aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.asan-blacklist6
-rw-r--r--src/.clang-format18
-rw-r--r--src/.valgrind.supp2
-rwxr-xr-xsrc/clint.py167
-rw-r--r--src/coverity-model.c70
-rw-r--r--src/nvim/CMakeLists.txt535
-rw-r--r--src/nvim/README.md190
-rw-r--r--src/nvim/api/buffer.c905
-rw-r--r--src/nvim/api/dispatch_deprecated.lua69
-rw-r--r--src/nvim/api/private/defs.h47
-rw-r--r--src/nvim/api/private/dispatch.c52
-rw-r--r--src/nvim/api/private/dispatch.h23
-rw-r--r--src/nvim/api/private/handle.c19
-rw-r--r--src/nvim/api/private/handle.h6
-rw-r--r--src/nvim/api/private/helpers.c688
-rw-r--r--src/nvim/api/private/helpers.h32
-rw-r--r--src/nvim/api/tabpage.c132
-rw-r--r--src/nvim/api/ui.c617
-rw-r--r--src/nvim/api/ui_events.in.h130
-rw-r--r--src/nvim/api/vim.c1702
-rw-r--r--src/nvim/api/vim.h4
-rw-r--r--src/nvim/api/window.c276
-rw-r--r--src/nvim/arabic.c1083
-rw-r--r--src/nvim/ascii.h30
-rw-r--r--src/nvim/assert.h30
-rw-r--r--src/nvim/aucmd.c40
-rw-r--r--src/nvim/aucmd.h9
-rw-r--r--src/nvim/auevents.lua20
-rw-r--r--src/nvim/buffer.c1828
-rw-r--r--src/nvim/buffer.h89
-rw-r--r--src/nvim/buffer_defs.h329
-rw-r--r--src/nvim/buffer_updates.c211
-rw-r--r--src/nvim/buffer_updates.h10
-rw-r--r--src/nvim/bufhl_defs.h30
-rw-r--r--src/nvim/channel.c831
-rw-r--r--src/nvim/channel.h134
-rw-r--r--src/nvim/charset.c1088
-rw-r--r--src/nvim/charset.h48
-rw-r--r--src/nvim/cursor.c106
-rw-r--r--src/nvim/cursor.h1
-rw-r--r--src/nvim/cursor_shape.c232
-rw-r--r--src/nvim/cursor_shape.h79
-rw-r--r--src/nvim/diff.c1279
-rw-r--r--src/nvim/diff.h3
-rw-r--r--src/nvim/digraph.c137
-rw-r--r--src/nvim/digraph.h3
-rw-r--r--src/nvim/edit.c1651
-rw-r--r--src/nvim/edit.h11
-rw-r--r--src/nvim/eval.c17917
-rw-r--r--src/nvim/eval.h63
-rw-r--r--src/nvim/eval.lua356
-rw-r--r--src/nvim/eval/decode.c348
-rw-r--r--src/nvim/eval/decode.h3
-rw-r--r--src/nvim/eval/encode.c442
-rw-r--r--src/nvim/eval/encode.h13
-rw-r--r--src/nvim/eval/executor.c118
-rw-r--r--src/nvim/eval/executor.h11
-rw-r--r--src/nvim/eval/gc.c14
-rw-r--r--src/nvim/eval/gc.h12
-rw-r--r--src/nvim/eval/typval.c2912
-rw-r--r--src/nvim/eval/typval.h842
-rw-r--r--src/nvim/eval/typval_encode.c.h846
-rw-r--r--src/nvim/eval/typval_encode.h588
-rw-r--r--src/nvim/eval_defs.h165
-rw-r--r--src/nvim/event/defs.h10
-rw-r--r--src/nvim/event/libuv_process.c51
-rw-r--r--src/nvim/event/libuv_process.h5
-rw-r--r--src/nvim/event/loop.c120
-rw-r--r--src/nvim/event/loop.h42
-rw-r--r--src/nvim/event/multiqueue.c247
-rw-r--r--src/nvim/event/multiqueue.h19
-rw-r--r--src/nvim/event/process.c260
-rw-r--r--src/nvim/event/process.h26
-rw-r--r--src/nvim/event/queue.c208
-rw-r--r--src/nvim/event/queue.h19
-rw-r--r--src/nvim/event/rstream.c60
-rw-r--r--src/nvim/event/signal.c3
-rw-r--r--src/nvim/event/signal.h2
-rw-r--r--src/nvim/event/socket.c214
-rw-r--r--src/nvim/event/socket.h4
-rw-r--r--src/nvim/event/stream.c29
-rw-r--r--src/nvim/event/stream.h13
-rw-r--r--src/nvim/event/time.c14
-rw-r--r--src/nvim/event/time.h2
-rw-r--r--src/nvim/event/wstream.c25
-rw-r--r--src/nvim/ex_cmds.c3573
-rw-r--r--src/nvim/ex_cmds.h20
-rw-r--r--src/nvim/ex_cmds.lua196
-rw-r--r--src/nvim/ex_cmds2.c900
-rw-r--r--src/nvim/ex_cmds_defs.h101
-rw-r--r--src/nvim/ex_docmd.c2780
-rw-r--r--src/nvim/ex_docmd.h30
-rw-r--r--src/nvim/ex_eval.c466
-rw-r--r--src/nvim/ex_eval.h49
-rw-r--r--src/nvim/ex_getln.c2323
-rw-r--r--src/nvim/ex_getln.h5
-rw-r--r--src/nvim/farsi.c416
-rw-r--r--src/nvim/file_search.c287
-rw-r--r--src/nvim/file_search.h5
-rw-r--r--src/nvim/fileio.c2293
-rw-r--r--src/nvim/fileio.h29
-rw-r--r--src/nvim/fold.c894
-rw-r--r--src/nvim/fold.h5
-rw-r--r--src/nvim/func_attr.h72
-rw-r--r--src/nvim/garray.c4
-rw-r--r--src/nvim/garray.h2
-rw-r--r--src/nvim/generators/c_grammar.lua50
-rw-r--r--src/nvim/generators/dump_bin_array.lua17
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua468
-rw-r--r--src/nvim/generators/gen_api_ui_events.lua177
-rw-r--r--src/nvim/generators/gen_char_blob.lua48
-rwxr-xr-xsrc/nvim/generators/gen_declarations.lua321
-rw-r--r--src/nvim/generators/gen_eval.lua67
-rw-r--r--src/nvim/generators/gen_events.lua62
-rw-r--r--src/nvim/generators/gen_ex_cmds.lua88
-rw-r--r--src/nvim/generators/gen_options.lua192
-rw-r--r--src/nvim/generators/gen_unicode_tables.lua327
-rw-r--r--src/nvim/getchar.c1241
-rw-r--r--src/nvim/getchar.h33
-rw-r--r--src/nvim/gettext.h23
-rw-r--r--src/nvim/globals.h744
-rw-r--r--src/nvim/grid_defs.h59
-rw-r--r--src/nvim/hardcopy.c282
-rw-r--r--src/nvim/hardcopy.h11
-rw-r--r--src/nvim/hashtab.c99
-rw-r--r--src/nvim/hashtab.h28
-rw-r--r--src/nvim/highlight.c416
-rw-r--r--src/nvim/highlight.h13
-rw-r--r--src/nvim/highlight_defs.h172
-rw-r--r--src/nvim/iconv.h6
-rw-r--r--src/nvim/if_cscope.c533
-rw-r--r--src/nvim/if_cscope.h3
-rw-r--r--src/nvim/if_cscope_defs.h14
-rw-r--r--src/nvim/indent.c56
-rw-r--r--src/nvim/indent_c.c276
-rw-r--r--src/nvim/keymap.c568
-rw-r--r--src/nvim/keymap.h271
-rw-r--r--src/nvim/lib/kbtree.h431
-rw-r--r--src/nvim/lib/kvec.h22
-rw-r--r--src/nvim/lib/queue.h18
-rw-r--r--src/nvim/lib/ringbuf.h27
-rw-r--r--src/nvim/log.c238
-rw-r--r--src/nvim/log.h79
-rw-r--r--src/nvim/lua/converter.c1206
-rw-r--r--src/nvim/lua/converter.h15
-rw-r--r--src/nvim/lua/executor.c549
-rw-r--r--src/nvim/lua/executor.h25
-rw-r--r--src/nvim/lua/vim.lua212
-rw-r--r--src/nvim/macros.h176
-rw-r--r--src/nvim/main.c1266
-rw-r--r--src/nvim/map.c35
-rw-r--r--src/nvim/map.h13
-rw-r--r--src/nvim/mark.c170
-rw-r--r--src/nvim/mark.h44
-rw-r--r--src/nvim/mark_defs.h2
-rw-r--r--src/nvim/mbyte.c1680
-rw-r--r--src/nvim/mbyte.h63
-rw-r--r--src/nvim/memfile.c195
-rw-r--r--src/nvim/memfile_defs.h5
-rw-r--r--src/nvim/memline.c511
-rw-r--r--src/nvim/memline.h2
-rw-r--r--src/nvim/memory.c232
-rw-r--r--src/nvim/memory.h33
-rw-r--r--src/nvim/menu.c377
-rw-r--r--src/nvim/menu.h52
-rw-r--r--src/nvim/message.c2105
-rw-r--r--src/nvim/message.h22
-rw-r--r--src/nvim/misc1.c509
-rw-r--r--src/nvim/misc2.c486
-rw-r--r--src/nvim/misc2.h12
-rw-r--r--src/nvim/mouse.c148
-rw-r--r--src/nvim/move.c365
-rw-r--r--src/nvim/move.h1
-rw-r--r--src/nvim/msgpack_rpc/channel.c605
-rw-r--r--src/nvim/msgpack_rpc/channel.h8
-rw-r--r--src/nvim/msgpack_rpc/channel_defs.h37
-rw-r--r--src/nvim/msgpack_rpc/defs.h28
-rw-r--r--src/nvim/msgpack_rpc/helpers.c125
-rw-r--r--src/nvim/msgpack_rpc/helpers.h7
-rw-r--r--src/nvim/msgpack_rpc/server.c94
-rw-r--r--src/nvim/msgpack_rpc/server.h2
-rw-r--r--src/nvim/normal.c1437
-rw-r--r--src/nvim/ops.c1237
-rw-r--r--src/nvim/ops.h4
-rw-r--r--src/nvim/option.c2390
-rw-r--r--src/nvim/option.h25
-rw-r--r--src/nvim/option_defs.h278
-rw-r--r--src/nvim/options.lua236
-rw-r--r--src/nvim/os/dl.c3
-rw-r--r--src/nvim/os/env.c430
-rw-r--r--src/nvim/os/fileio.c175
-rw-r--r--src/nvim/os/fileio.h5
-rw-r--r--src/nvim/os/fs.c662
-rw-r--r--src/nvim/os/fs_defs.h2
-rw-r--r--src/nvim/os/input.c121
-rw-r--r--src/nvim/os/lang.c65
-rw-r--r--src/nvim/os/lang.h7
-rw-r--r--src/nvim/os/mem.c3
-rw-r--r--src/nvim/os/os_defs.h11
-rw-r--r--src/nvim/os/process.c267
-rw-r--r--src/nvim/os/process.h11
-rw-r--r--src/nvim/os/pty_process_unix.c135
-rw-r--r--src/nvim/os/pty_process_win.c418
-rw-r--r--src/nvim/os/pty_process_win.h27
-rw-r--r--src/nvim/os/shell.c440
-rw-r--r--src/nvim/os/shell.h2
-rw-r--r--src/nvim/os/signal.c22
-rw-r--r--src/nvim/os/stdpaths.c61
-rw-r--r--src/nvim/os/time.c56
-rw-r--r--src/nvim/os/tty.c60
-rw-r--r--src/nvim/os/tty.h7
-rw-r--r--src/nvim/os/unix_defs.h8
-rw-r--r--src/nvim/os/users.c9
-rw-r--r--src/nvim/os/win_defs.h30
-rw-r--r--src/nvim/os_unix.c437
-rw-r--r--src/nvim/path.c548
-rw-r--r--src/nvim/po/CMakeLists.txt84
-rw-r--r--src/nvim/po/af.po7129
-rw-r--r--src/nvim/po/ca.po115
-rw-r--r--src/nvim/po/check.vim164
-rw-r--r--src/nvim/po/cleanup.vim8
-rw-r--r--src/nvim/po/cs.cp1250.po15
-rw-r--r--src/nvim/po/cs.po15
-rw-r--r--src/nvim/po/da.po7088
-rw-r--r--src/nvim/po/de.po53
-rw-r--r--src/nvim/po/en_GB.po9
-rw-r--r--src/nvim/po/eo.po6581
-rw-r--r--src/nvim/po/es.po66
-rw-r--r--src/nvim/po/fi.po7581
-rw-r--r--src/nvim/po/fr.po6771
-rw-r--r--src/nvim/po/ga.po6336
-rw-r--r--src/nvim/po/it.po118
-rw-r--r--src/nvim/po/ja.euc-jp.po6524
-rw-r--r--src/nvim/po/ja.po6525
-rw-r--r--src/nvim/po/ja.sjis.po8223
-rw-r--r--src/nvim/po/ko.UTF-8.po93
-rw-r--r--src/nvim/po/ko.po7858
-rw-r--r--src/nvim/po/nb.po36
-rw-r--r--src/nvim/po/nl.po19
-rw-r--r--src/nvim/po/no.po36
-rw-r--r--src/nvim/po/pl.UTF-8.po42
-rw-r--r--src/nvim/po/pl.cp1250.po8264
-rw-r--r--src/nvim/po/pl.po8264
-rw-r--r--src/nvim/po/pt_BR.po27
-rw-r--r--src/nvim/po/ru.cp1251.po8282
-rw-r--r--src/nvim/po/ru.po45
-rw-r--r--src/nvim/po/sjiscorr.c45
-rw-r--r--src/nvim/po/sk.cp1250.po32
-rw-r--r--src/nvim/po/sk.po32
-rw-r--r--src/nvim/po/sr.po7115
-rw-r--r--src/nvim/po/sv.po31
-rw-r--r--src/nvim/po/uk.cp1251.po8388
-rw-r--r--src/nvim/po/uk.po5860
-rw-r--r--src/nvim/po/vi.po16
-rw-r--r--src/nvim/po/zh_CN.UTF-8.po25
-rw-r--r--src/nvim/po/zh_CN.cp936.po7932
-rw-r--r--src/nvim/po/zh_CN.po7932
-rw-r--r--src/nvim/po/zh_TW.UTF-8.po21
-rw-r--r--src/nvim/po/zh_TW.po7910
-rw-r--r--src/nvim/popupmnu.c487
-rw-r--r--src/nvim/popupmnu.h2
-rw-r--r--src/nvim/pos.h8
-rw-r--r--src/nvim/profile.c3
-rw-r--r--src/nvim/quickfix.c3355
-rw-r--r--src/nvim/quickfix.h3
-rw-r--r--src/nvim/rbuffer.c9
-rw-r--r--src/nvim/rbuffer.h2
-rw-r--r--src/nvim/regexp.c1819
-rw-r--r--src/nvim/regexp.h25
-rw-r--r--src/nvim/regexp_defs.h46
-rw-r--r--src/nvim/regexp_nfa.c957
-rw-r--r--src/nvim/screen.c4953
-rw-r--r--src/nvim/screen.h17
-rw-r--r--src/nvim/search.c854
-rw-r--r--src/nvim/search.h6
-rw-r--r--src/nvim/sha256.c17
-rw-r--r--src/nvim/sha256.h1
-rw-r--r--src/nvim/shada.c1005
-rw-r--r--src/nvim/sign_defs.h23
-rw-r--r--src/nvim/spell.c6961
-rw-r--r--src/nvim/spell.h4
-rw-r--r--src/nvim/spell_defs.h291
-rw-r--r--src/nvim/spellfile.c5727
-rw-r--r--src/nvim/spellfile.h13
-rw-r--r--src/nvim/state.c120
-rw-r--r--src/nvim/strings.c1159
-rw-r--r--src/nvim/strings.h22
-rw-r--r--src/nvim/syntax.c3988
-rw-r--r--src/nvim/syntax.h17
-rw-r--r--src/nvim/syntax_defs.h48
-rw-r--r--src/nvim/tag.c682
-rw-r--r--src/nvim/tag.h3
-rw-r--r--src/nvim/terminal.c546
-rw-r--r--src/nvim/terminal.h2
-rw-r--r--src/nvim/testdir/Makefile162
-rw-r--r--src/nvim/testdir/pyxfile/py2_magic.py4
-rw-r--r--src/nvim/testdir/pyxfile/py2_shebang.py4
-rw-r--r--src/nvim/testdir/pyxfile/py3_magic.py4
-rw-r--r--src/nvim/testdir/pyxfile/py3_shebang.py4
-rw-r--r--src/nvim/testdir/pyxfile/pyx.py2
-rwxr-xr-xsrc/nvim/testdir/runnvim.sh82
-rw-r--r--src/nvim/testdir/runnvim.vim55
-rw-r--r--src/nvim/testdir/runtest.vim308
-rw-r--r--src/nvim/testdir/samples/memfile_test.c146
-rw-r--r--src/nvim/testdir/samples/quickfix.txt4
-rw-r--r--src/nvim/testdir/sautest/autoload/foo.vim7
-rw-r--r--src/nvim/testdir/sautest/autoload/footest.vim2
-rw-r--r--src/nvim/testdir/sautest/autoload/globone.vim1
-rw-r--r--src/nvim/testdir/sautest/autoload/globtwo.vim1
-rw-r--r--src/nvim/testdir/sautest/autoload/sourced.vim3
-rw-r--r--src/nvim/testdir/setup.vim40
-rw-r--r--src/nvim/testdir/shared.vim248
-rw-r--r--src/nvim/testdir/test12.in50
-rw-r--r--src/nvim/testdir/test12.ok10
-rw-r--r--src/nvim/testdir/test13.in63
-rw-r--r--src/nvim/testdir/test13.ok31
-rw-r--r--src/nvim/testdir/test17.in14
-rw-r--r--src/nvim/testdir/test24.inbin1265 -> 0 bytes
-rw-r--r--src/nvim/testdir/test24.ok32
-rw-r--r--src/nvim/testdir/test30.in230
-rw-r--r--src/nvim/testdir/test30.ok130
-rw-r--r--src/nvim/testdir/test32.in60
-rw-r--r--src/nvim/testdir/test32.ok15
-rw-r--r--src/nvim/testdir/test40.in63
-rw-r--r--src/nvim/testdir/test40.ok11
-rw-r--r--src/nvim/testdir/test47.in102
-rw-r--r--src/nvim/testdir/test47.ok44
-rw-r--r--src/nvim/testdir/test49.vim4
-rw-r--r--src/nvim/testdir/test53.in133
-rw-r--r--src/nvim/testdir/test53.ok71
-rw-r--r--src/nvim/testdir/test64.in4
-rw-r--r--src/nvim/testdir/test64.ok3
-rw-r--r--src/nvim/testdir/test69.in191
-rw-r--r--src/nvim/testdir/test69.ok166
-rw-r--r--src/nvim/testdir/test73.in175
-rw-r--r--src/nvim/testdir/test73.ok21
-rw-r--r--src/nvim/testdir/test79.inbin3335 -> 0 bytes
-rw-r--r--src/nvim/testdir/test79.okbin570 -> 0 bytes
-rw-r--r--src/nvim/testdir/test8.in43
-rw-r--r--src/nvim/testdir/test8.ok7
-rw-r--r--src/nvim/testdir/test_alot.vim50
-rw-r--r--src/nvim/testdir/test_alot_latin.vim10
-rw-r--r--src/nvim/testdir/test_alot_utf8.vim17
-rw-r--r--src/nvim/testdir/test_arabic.vim613
-rw-r--r--src/nvim/testdir/test_arglist.vim376
-rw-r--r--src/nvim/testdir/test_assign.vim47
-rw-r--r--src/nvim/testdir/test_autochdir.vim19
-rw-r--r--src/nvim/testdir/test_autocmd.vim1308
-rw-r--r--src/nvim/testdir/test_autoload.vim17
-rw-r--r--src/nvim/testdir/test_behave.vim29
-rw-r--r--src/nvim/testdir/test_blockedit.vim33
-rw-r--r--src/nvim/testdir/test_breakindent.vim298
-rw-r--r--src/nvim/testdir/test_bufwintabinfo.vim133
-rw-r--r--src/nvim/testdir/test_cd.vim67
-rw-r--r--src/nvim/testdir/test_changedtick.vim57
-rw-r--r--src/nvim/testdir/test_charsearch.vim62
-rw-r--r--src/nvim/testdir/test_charsearch_utf8.vim22
-rw-r--r--src/nvim/testdir/test_cindent.vim105
-rw-r--r--src/nvim/testdir/test_clientserver.vim107
-rw-r--r--src/nvim/testdir/test_close_count.vim174
-rw-r--r--src/nvim/testdir/test_cmdline.vim525
-rw-r--r--src/nvim/testdir/test_command_count.vim195
-rw-r--r--src/nvim/testdir/test_comparators.vim9
-rw-r--r--src/nvim/testdir/test_compiler.vim54
-rw-r--r--src/nvim/testdir/test_cscope.vim279
-rw-r--r--src/nvim/testdir/test_cursor_func.vim8
-rw-r--r--src/nvim/testdir/test_curswant.vim23
-rw-r--r--src/nvim/testdir/test_diffmode.vim740
-rw-r--r--src/nvim/testdir/test_digraph.vim468
-rw-r--r--src/nvim/testdir/test_display.vim71
-rw-r--r--src/nvim/testdir/test_edit.vim1445
-rw-r--r--src/nvim/testdir/test_erasebackword.vim25
-rw-r--r--src/nvim/testdir/test_escaped_glob.vim34
-rw-r--r--src/nvim/testdir/test_eval_stuff.vim23
-rw-r--r--src/nvim/testdir/test_ex_undo.vim19
-rw-r--r--src/nvim/testdir/test_ex_z.vim78
-rw-r--r--src/nvim/testdir/test_exec_while_if.vim53
-rw-r--r--src/nvim/testdir/test_execute_func.vim55
-rw-r--r--src/nvim/testdir/test_exists.vim321
-rw-r--r--src/nvim/testdir/test_exists_autocmd.vim26
-rw-r--r--src/nvim/testdir/test_exit.vim57
-rw-r--r--src/nvim/testdir/test_expr.vim480
-rw-r--r--src/nvim/testdir/test_expr_utf8.vim37
-rw-r--r--src/nvim/testdir/test_farsi.vim133
-rw-r--r--src/nvim/testdir/test_feedkeys.vim14
-rw-r--r--src/nvim/testdir/test_file_size.vim58
-rw-r--r--src/nvim/testdir/test_fileformat.vim33
-rw-r--r--src/nvim/testdir/test_filetype.vim602
-rw-r--r--src/nvim/testdir/test_filter_cmd.vim89
-rw-r--r--src/nvim/testdir/test_filter_map.vim81
-rw-r--r--src/nvim/testdir/test_find_complete.vim166
-rw-r--r--src/nvim/testdir/test_findfile.vim25
-rw-r--r--src/nvim/testdir/test_fixeol.vim48
-rw-r--r--src/nvim/testdir/test_float_func.vim332
-rw-r--r--src/nvim/testdir/test_fnameescape.vim21
-rw-r--r--src/nvim/testdir/test_fold.vim742
-rw-r--r--src/nvim/testdir/test_functions.vim1039
-rw-r--r--src/nvim/testdir/test_ga.vim37
-rw-r--r--src/nvim/testdir/test_getcwd.vim112
-rw-r--r--src/nvim/testdir/test_getvar.vim104
-rw-r--r--src/nvim/testdir/test_gf.vim61
-rw-r--r--src/nvim/testdir/test_glob2regpat.vim30
-rw-r--r--src/nvim/testdir/test_global.vim20
-rw-r--r--src/nvim/testdir/test_gn.vim136
-rw-r--r--src/nvim/testdir/test_goto.vim373
-rw-r--r--src/nvim/testdir/test_hardcopy.vim31
-rw-r--r--src/nvim/testdir/test_help.vim52
-rw-r--r--src/nvim/testdir/test_help_tagjump.vim232
-rw-r--r--src/nvim/testdir/test_hide.vim97
-rw-r--r--src/nvim/testdir/test_highlight.vim535
-rw-r--r--src/nvim/testdir/test_history.vim111
-rw-r--r--src/nvim/testdir/test_hlsearch.vim46
-rw-r--r--src/nvim/testdir/test_increment.vim782
-rw-r--r--src/nvim/testdir/test_increment_dbcs.vim29
-rw-r--r--src/nvim/testdir/test_ins_complete.vim251
-rw-r--r--src/nvim/testdir/test_join.vim35
-rw-r--r--src/nvim/testdir/test_jumps.vim11
-rw-r--r--src/nvim/testdir/test_lambda.vim287
-rw-r--r--src/nvim/testdir/test_largefile.vim34
-rw-r--r--src/nvim/testdir/test_let.vim27
-rw-r--r--src/nvim/testdir/test_lineending.vim19
-rw-r--r--src/nvim/testdir/test_lispwords.vim82
-rw-r--r--src/nvim/testdir/test_listchars.vim63
-rw-r--r--src/nvim/testdir/test_listdict.vim651
-rw-r--r--src/nvim/testdir/test_listlbr.vim238
-rw-r--r--src/nvim/testdir/test_listlbr_utf8.vim271
-rw-r--r--src/nvim/testdir/test_makeencoding.py67
-rw-r--r--src/nvim/testdir/test_makeencoding.vim113
-rw-r--r--src/nvim/testdir/test_maparg.vim56
-rw-r--r--src/nvim/testdir/test_mapping.vim286
-rw-r--r--src/nvim/testdir/test_marks.vim138
-rw-r--r--src/nvim/testdir/test_match.vim232
-rw-r--r--src/nvim/testdir/test_matchadd_conceal.vim275
-rw-r--r--src/nvim/testdir/test_matchadd_conceal_utf8.vim39
-rw-r--r--src/nvim/testdir/test_menu.vim2
-rw-r--r--src/nvim/testdir/test_messages.vim45
-rw-r--r--src/nvim/testdir/test_mksession.vim241
-rw-r--r--src/nvim/testdir/test_mksession_utf8.vim105
-rw-r--r--src/nvim/testdir/test_move.vim40
-rw-r--r--src/nvim/testdir/test_nested_function.vim63
-rw-r--r--src/nvim/testdir/test_normal.vim2542
-rw-r--r--src/nvim/testdir/test_number.vim254
-rw-r--r--src/nvim/testdir/test_options.vim412
-rw-r--r--src/nvim/testdir/test_partial.vim351
-rw-r--r--src/nvim/testdir/test_plus_arg_edit.vim10
-rw-r--r--src/nvim/testdir/test_popup.vim715
-rw-r--r--src/nvim/testdir/test_preview.vim13
-rw-r--r--src/nvim/testdir/test_profile.vim183
-rw-r--r--src/nvim/testdir/test_put.vim49
-rw-r--r--src/nvim/testdir/test_python2.vim54
-rw-r--r--src/nvim/testdir/test_python3.vim54
-rw-r--r--src/nvim/testdir/test_pyx2.vim74
-rw-r--r--src/nvim/testdir/test_pyx3.vim74
-rw-r--r--src/nvim/testdir/test_quickfix.vim2666
-rw-r--r--src/nvim/testdir/test_quotestar.vim157
-rw-r--r--src/nvim/testdir/test_recover.vim58
-rw-r--r--src/nvim/testdir/test_regex_char_classes.vim58
-rw-r--r--src/nvim/testdir/test_regexp_latin.vim32
-rw-r--r--src/nvim/testdir/test_regexp_utf8.vim185
-rw-r--r--src/nvim/testdir/test_registers.vim65
-rw-r--r--src/nvim/testdir/test_retab.vim77
-rw-r--r--src/nvim/testdir/test_scriptnames.vim26
-rw-r--r--src/nvim/testdir/test_scroll_opt.vim36
-rw-r--r--src/nvim/testdir/test_scrollbind.vim32
-rw-r--r--src/nvim/testdir/test_search.vim491
-rw-r--r--src/nvim/testdir/test_sha256.vim22
-rw-r--r--src/nvim/testdir/test_signs.vim226
-rw-r--r--src/nvim/testdir/test_smartindent.vim41
-rw-r--r--src/nvim/testdir/test_sort.vim1253
-rw-r--r--src/nvim/testdir/test_source_utf8.vim63
-rw-r--r--src/nvim/testdir/test_spell.vim851
-rw-r--r--src/nvim/testdir/test_startup.vim367
-rw-r--r--src/nvim/testdir/test_startup_utf8.vim64
-rw-r--r--src/nvim/testdir/test_stat.vim185
-rw-r--r--src/nvim/testdir/test_statusline.vim274
-rw-r--r--src/nvim/testdir/test_substitute.vim503
-rw-r--r--src/nvim/testdir/test_suspend.vim51
-rw-r--r--src/nvim/testdir/test_swap.vim63
-rw-r--r--src/nvim/testdir/test_syn_attr.vim28
-rw-r--r--src/nvim/testdir/test_syntax.vim444
-rw-r--r--src/nvim/testdir/test_system.vim90
-rw-r--r--src/nvim/testdir/test_tab.vim45
-rw-r--r--src/nvim/testdir/test_tabline.vim43
-rw-r--r--src/nvim/testdir/test_tabpage.vim550
-rw-r--r--src/nvim/testdir/test_tagcase.vim73
-rw-r--r--src/nvim/testdir/test_tagjump.vim261
-rw-r--r--src/nvim/testdir/test_taglist.vim63
-rw-r--r--src/nvim/testdir/test_textformat.vim168
-rw-r--r--src/nvim/testdir/test_textobjects.vim259
-rw-r--r--src/nvim/testdir/test_timers.vim222
-rw-r--r--src/nvim/testdir/test_true_false.vim150
-rw-r--r--src/nvim/testdir/test_undo.vim436
-rw-r--r--src/nvim/testdir/test_unlet.vim40
-rw-r--r--src/nvim/testdir/test_user_func.vim96
-rw-r--r--src/nvim/testdir/test_usercommands.vim220
-rw-r--r--src/nvim/testdir/test_utf8.vim65
-rw-r--r--src/nvim/testdir/test_utf8_comparisons.vim95
-rw-r--r--src/nvim/testdir/test_vimscript.vim (renamed from src/nvim/testdir/test_viml.vim)340
-rw-r--r--src/nvim/testdir/test_virtualedit.vim61
-rw-r--r--src/nvim/testdir/test_visual.vim320
-rw-r--r--src/nvim/testdir/test_winbuf_close.vim160
-rw-r--r--src/nvim/testdir/test_window_cmd.vim521
-rw-r--r--src/nvim/testdir/test_window_id.vim103
-rw-r--r--src/nvim/testdir/test_windows_home.vim121
-rw-r--r--src/nvim/testdir/test_wordcount.vim108
-rw-r--r--src/nvim/testdir/test_writefile.vim133
-rw-r--r--src/nvim/testdir/unix.vim6
-rw-r--r--src/nvim/testdir/view_util.vim51
-rw-r--r--src/nvim/tui/input.c126
-rw-r--r--src/nvim/tui/input.h6
-rw-r--r--src/nvim/tui/terminfo.c225
-rw-r--r--src/nvim/tui/terminfo.h10
-rw-r--r--src/nvim/tui/terminfo_defs.h2276
-rw-r--r--src/nvim/tui/tui.c1859
-rw-r--r--src/nvim/tui/tui.h3
-rw-r--r--src/nvim/types.h5
-rw-r--r--src/nvim/ugrid.c81
-rw-r--r--src/nvim/ugrid.h25
-rw-r--r--src/nvim/ui.c521
-rw-r--r--src/nvim/ui.h68
-rw-r--r--src/nvim/ui_bridge.c323
-rw-r--r--src/nvim/ui_bridge.h5
-rw-r--r--src/nvim/undo.c588
-rw-r--r--src/nvim/undo.h1
-rw-r--r--src/nvim/undo_defs.h6
-rw-r--r--src/nvim/version.c2342
-rw-r--r--src/nvim/version.h10
-rw-r--r--src/nvim/vim.h287
-rw-r--r--src/nvim/viml/parser/expressions.c3095
-rw-r--r--src/nvim/viml/parser/expressions.h389
-rw-r--r--src/nvim/viml/parser/parser.c16
-rw-r--r--src/nvim/viml/parser/parser.h244
-rw-r--r--src/nvim/window.c1138
-rw-r--r--src/nvim/window.h2
-rw-r--r--src/nvim/xdiff/COPYING504
-rw-r--r--src/nvim/xdiff/README.txt16
-rw-r--r--src/nvim/xdiff/xdiff.h143
-rw-r--r--src/nvim/xdiff/xdiffi.c1043
-rw-r--r--src/nvim/xdiff/xdiffi.h64
-rw-r--r--src/nvim/xdiff/xemit.c332
-rw-r--r--src/nvim/xdiff/xemit.h36
-rw-r--r--src/nvim/xdiff/xhistogram.c386
-rw-r--r--src/nvim/xdiff/xinclude.h61
-rw-r--r--src/nvim/xdiff/xmacros.h54
-rw-r--r--src/nvim/xdiff/xpatience.c393
-rw-r--r--src/nvim/xdiff/xprepare.c483
-rw-r--r--src/nvim/xdiff/xprepare.h34
-rw-r--r--src/nvim/xdiff/xtypes.h67
-rw-r--r--src/nvim/xdiff/xutils.c425
-rw-r--r--src/nvim/xdiff/xutils.h47
550 files changed, 160355 insertions, 155334 deletions
diff --git a/src/.asan-blacklist b/src/.asan-blacklist
index 63558170b3..928d81bd5a 100644
--- a/src/.asan-blacklist
+++ b/src/.asan-blacklist
@@ -1,3 +1,3 @@
-# libuv queue.h pointer arithmetic is not accepted by asan
-fun:queue_node_data
-fun:dictwatcher_node_data
+# multiqueue.h pointer arithmetic is not accepted by asan
+fun:multiqueue_node_data
+fun:tv_dict_watcher_node_data
diff --git a/src/.clang-format b/src/.clang-format
deleted file mode 100644
index 5a910ff34b..0000000000
--- a/src/.clang-format
+++ /dev/null
@@ -1,18 +0,0 @@
-BasedOnStyle: Google
-Language: Cpp
-ColumnLimit: 80
-IndentWidth: 2
-TabWidth: 2
-UseTab: Never
-IndentCaseLabels: true
-BreakBeforeBraces: Linux
-AlignEscapedNewlinesLeft: false
-AllowShortFunctionsOnASingleLine: false
-SpacesBeforeTrailingComments: 2
-PenaltyReturnTypeOnItsOwnLine: 200
-AllowAllParametersOfDeclarationOnNextLine: false
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
-BinPackParameters: false
-BreakBeforeBinaryOperators: true
-ContinuationIndentWidth: 4
diff --git a/src/.valgrind.supp b/src/.valgrind.supp
index 8b630fcaaf..cce22bd632 100644
--- a/src/.valgrind.supp
+++ b/src/.valgrind.supp
@@ -10,7 +10,7 @@
Memcheck:Leak
fun:malloc
fun:uv_spawn
- fun:pipe_process_spawn
+ fun:libuv_process_spawn
fun:process_spawn
fun:job_start
}
diff --git a/src/clint.py b/src/clint.py
index efc5f18378..34af5d15fd 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -49,6 +49,7 @@ from __future__ import unicode_literals
import codecs
import copy
+import fileinput
import getopt
import math # for log
import os
@@ -65,7 +66,7 @@ _USAGE = """
Syntax: clint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
[--counting=total|toplevel|detailed] [--root=subdir]
[--linelength=digits] [--record-errors=file]
- [--suppress-errors=file]
+ [--suppress-errors=file] [--stdin-filename=filename]
<file> [file] ...
The style guidelines this tries to follow are those in
@@ -167,6 +168,9 @@ Syntax: clint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
suppress-errors=file
Errors listed in the given file will not be reported.
+
+ stdin-filename=filename
+ Use specified filename when reading from stdin (file "-").
"""
# We categorize each error message we print. Here are the categories.
@@ -182,6 +186,7 @@ _ERROR_CATEGORIES = [
'build/include_order',
'build/printf_format',
'build/storage_class',
+ 'build/useless_fattr',
'readability/alt_tokens',
'readability/bool',
'readability/braces',
@@ -200,6 +205,7 @@ _ERROR_CATEGORIES = [
'runtime/printf',
'runtime/printf_format',
'runtime/threadsafe_fn',
+ 'runtime/deprecated',
'syntax/parenthesis',
'whitespace/alignment',
'whitespace/blank_line',
@@ -569,9 +575,10 @@ class _CppLintState(object):
def PrintErrorCounts(self):
"""Print a summary of errors by category, and the total."""
for category, count in self.errors_by_category.items():
- sys.stderr.write('Category \'%s\' errors found: %d\n' %
+ sys.stdout.write('Category \'%s\' errors found: %d\n' %
(category, count))
- sys.stderr.write('Total errors found: %d\n' % self.error_count)
+ if self.error_count:
+ sys.stdout.write('Total errors found: %d\n' % self.error_count)
def SuppressErrorsFrom(self, fname):
"""Open file and read a list of suppressed errors from it"""
@@ -818,13 +825,13 @@ def Error(filename, linenum, category, confidence, message):
if _ShouldPrintError(category, confidence, linenum):
_cpplint_state.IncrementErrorCount(category)
if _cpplint_state.output_format == 'vs7':
- sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
+ sys.stdout.write('%s(%s): %s [%s] [%d]\n' % (
filename, linenum, message, category, confidence))
elif _cpplint_state.output_format == 'eclipse':
- sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
+ sys.stdout.write('%s:%s: warning: %s [%s] [%d]\n' % (
filename, linenum, message, category, confidence))
else:
- sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
+ sys.stdout.write('%s:%s: %s [%s] [%d]\n' % (
filename, linenum, message, category, confidence))
@@ -1224,6 +1231,10 @@ def CheckForHeaderGuard(filename, lines, error):
lines: An array of strings, each representing a line of the file.
error: The function to call with any errors found.
"""
+ if filename.endswith('.c.h') or FileInfo(filename).RelativePath() in set((
+ 'func_attr.h',
+ )):
+ return
cppvar = GetHeaderGuardCPPVariable(filename)
@@ -2117,8 +2128,10 @@ def CheckExpressionAlignment(filename, clean_lines, linenum, error, startpos=0):
+ (level_starts[depth][2] == '{')):
if depth not in ignore_error_levels:
error(filename, linenum, 'whitespace/alignment', 2,
- 'Inner expression should be aligned '
- 'as opening brace + 1 (+ 2 in case of {)')
+ ('Inner expression should be aligned '
+ 'as opening brace + 1 (+ 2 in case of {{). '
+ 'Relevant opening is on line {0!r}').format(
+ level_starts[depth][3]))
prev_line_start = pos
elif brace == 'e':
pass
@@ -2135,7 +2148,8 @@ def CheckExpressionAlignment(filename, clean_lines, linenum, error, startpos=0):
ignore_error_levels.add(depth)
line_ended_with_opening = (
pos == len(line) - 2 * (line.endswith(' \\')) - 1)
- level_starts[depth] = (pos, line_ended_with_opening, brace)
+ level_starts[depth] = (pos, line_ended_with_opening, brace,
+ linenum)
if line_ended_with_opening:
depth_line_starts[depth] = (prev_line_start, brace)
else:
@@ -2268,11 +2282,14 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
# //!< Header comment
# or they begin with multiple slashes followed by a space:
# //////// Header comment
+ # or they are Vim {{{ fold markers
match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
Search(r'^/$', line[commentend:]) or
Search(r'^!< ', line[commentend:]) or
Search(r'^/< ', line[commentend:]) or
- Search(r'^/+ ', line[commentend:]))
+ Search(r'^/+ ', line[commentend:]) or
+ Search(r'^(?:\{{3}|\}{3})\d*(?: |$)',
+ line[commentend:]))
if not match:
error(filename, linenum, 'whitespace/comments', 4,
'Should have a space between // and comment')
@@ -2516,6 +2533,13 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
cast_line = re.sub(r'^# *define +\w+\([^)]*\)', '', line)
match = Search(r'(?<!\bkvec_t)'
+ r'(?<!\bkvec_withinit_t)'
+ r'(?<!\bklist_t)'
+ r'(?<!\bkliter_t)'
+ r'(?<!\bkhash_t)'
+ r'(?<!\bkbtree_t)'
+ r'(?<!\bkbitr_t)'
+ r'(?<!\bPMap)'
r'\((?:const )?(?:struct )?[a-zA-Z_]\w*(?: *\*(?:const)?)*\)'
r' +'
r'-?(?:\*+|&)?(?:\w+|\+\+|--|\()', cast_line)
@@ -2560,22 +2584,51 @@ def CheckBraces(filename, clean_lines, linenum, error):
line = clean_lines.elided[linenum] # get rid of comments and strings
- if not (filename.endswith('.c') or filename.endswith('.h')):
- if Match(r'\s*{\s*$', line):
- # We allow an open brace to start a line in the case where someone
- # is using braces in a block to explicitly create a new scope, which
- # is commonly used to control the lifetime of stack-allocated
- # variables. Braces are also used for brace initializers inside
- # function calls. We don't detect this perfectly: we just don't
- # complain if the last non-whitespace character on the previous
- # non-blank line is ',', ';', ':', '(', '{', or '}', or if the
- # previous line starts a preprocessor block.
- prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
- if (not Search(r'[,;:}{(]\s*$', prevline) and
- not Match(r'\s*#', prevline)):
- error(filename, linenum, 'whitespace/braces', 4,
- '{ should almost always be at the end'
- ' of the previous line')
+ if Match(r'\s+{\s*$', line):
+ # We allow an open brace to start a line in the case where someone
+ # is using braces in a block to explicitly create a new scope, which
+ # is commonly used to control the lifetime of stack-allocated
+ # variables. Braces are also used for brace initializers inside
+ # function calls. We don't detect this perfectly: we just don't
+ # complain if the last non-whitespace character on the previous
+ # non-blank line is ',', ';', ':', '(', '{', or '}', or if the
+ # previous line starts a preprocessor block.
+ prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
+ if (not Search(r'[,;:}{(]\s*$', prevline) and
+ not Match(r'\s*#', prevline)):
+ error(filename, linenum, 'whitespace/braces', 4,
+ '{ should almost always be at the end'
+ ' of the previous line')
+
+ # Brace must appear after function signature, but on the *next* line
+ if Match(r'^(?:\w+(?: ?\*+)? )+\w+\(', line):
+ pos = line.find('(')
+ (endline, end_linenum, endpos) = CloseExpression(
+ clean_lines, linenum, pos)
+ if endline.endswith('{'):
+ error(filename, end_linenum, 'readability/braces', 5,
+ 'Brace starting function body must be placed on its own line')
+ else:
+ func_start_linenum = end_linenum + 1
+ while not clean_lines.lines[func_start_linenum] == '{':
+ attrline = Match(r'^((?!# *define).*?)(?:FUNC_ATTR|FUNC_API|REAL_FATTR)_\w+(?:\(\d+(, \d+)*\))?',
+ clean_lines.lines[func_start_linenum])
+ if attrline:
+ if len(attrline.group(1)) != 2:
+ error(filename, func_start_linenum,
+ 'whitespace/indent', 5,
+ 'Function attribute line should have 2-space '
+ 'indent')
+
+ func_start_linenum += 1
+ else:
+ func_start = clean_lines.lines[func_start_linenum]
+ if not func_start.startswith('enum ') and func_start.endswith('{'):
+ error(filename, func_start_linenum,
+ 'readability/braces', 5,
+ 'Brace starting function body must be placed '
+ 'after the function signature')
+ break
# An else clause should be on the same line as the preceding closing brace.
# If there is no preceding closing brace, there should be one.
@@ -3001,9 +3054,10 @@ def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
include = match.group(2)
is_system = (match.group(1) == '<')
if include in include_state:
- error(filename, linenum, 'build/include', 4,
- '"%s" already included at %s:%s' %
- (include, filename, include_state[include]))
+ if is_system or not include.endswith('.c.h'):
+ error(filename, linenum, 'build/include', 4,
+ '"%s" already included at %s:%s' %
+ (include, filename, include_state[include]))
else:
include_state[include] = linenum
@@ -3140,11 +3194,28 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
# Check if some verboten C functions are being used.
if Search(r'\bsprintf\b', line):
error(filename, linenum, 'runtime/printf', 5,
- 'Never use sprintf. Use snprintf instead.')
- match = Search(r'\b(strcpy|strcat)\b', line)
+ 'Use snprintf instead of sprintf.')
+ match = Search(r'\b(strncpy|STRNCPY)\b', line)
+ if match:
+ error(filename, linenum, 'runtime/printf', 4,
+ 'Use xstrlcpy or snprintf instead of %s (unless this is from Vim)'
+ % match.group(1))
+ match = Search(r'\b(strcpy)\b', line)
+ if match:
+ error(filename, linenum, 'runtime/printf', 4,
+ 'Use xstrlcpy or snprintf instead of %s' % match.group(1))
+ match = Search(r'\b(STRNCAT|strncat|strcat|vim_strcat)\b', line)
if match:
error(filename, linenum, 'runtime/printf', 4,
- 'Almost always, snprintf is better than %s' % match.group(1))
+ 'Use xstrlcat or snprintf instead of %s' % match.group(1))
+ if not Search(r'eval/typval\.[ch]$', filename):
+ match = Search(r'(?:\.|->)'
+ r'(?:lv_(?:first|last|refcount|len|watch|idx(?:_item)?'
+ r'|copylist|lock)'
+ r'|li_(?:next|prev|tv))\b', line)
+ if match:
+ error(filename, linenum, 'runtime/deprecated', 4,
+ 'Accessing list_T internals directly is prohibited')
# Check for suspicious usage of "if" like
# } if (a == b) {
@@ -3232,6 +3303,13 @@ def CheckLanguage(filename, clean_lines, linenum, file_extension,
error(filename, linenum, 'readability/bool', 4,
'Use %s instead of %s.' % (token.lower(), token))
+ # Detect MAYBE
+ match = Search(r'\b(MAYBE)\b', line)
+ if match:
+ token = match.group(1)
+ error(filename, linenum, 'readability/bool', 4,
+ 'Use kNONE from TriState instead of %s.' % token)
+
# Detect preincrement/predecrement
match = Match(r'^\s*(?:\+\+|--)', line)
if match:
@@ -3382,10 +3460,12 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
# is processed.
if filename == '-':
- lines = codecs.StreamReaderWriter(sys.stdin,
- codecs.getreader('utf8'),
- codecs.getwriter('utf8'),
- 'replace').read().split('\n')
+ stdin = sys.stdin.read()
+ if sys.version_info < (3, 0):
+ stdin = stdin.decode('utf8')
+ lines = stdin.split('\n')
+ if _cpplint_state.stdin_filename is not None:
+ filename = _cpplint_state.stdin_filename
else:
lines = codecs.open(
filename, 'r', 'utf8', 'replace').read().split('\n')
@@ -3408,8 +3488,9 @@ def ProcessFile(filename, vlevel, extra_check_functions=[]):
# When reading from stdin, the extension is unknown, so no cpplint tests
# should rely on the extension.
if filename != '-' and file_extension not in _valid_extensions:
- sys.stderr.write('Ignoring %s; not a valid file name '
- '(%s)\n' % (filename, ', '.join(_valid_extensions)))
+ sys.stderr.write('Ignoring {}; only linting {} files\n'.format(
+ filename,
+ ', '.join('.{}'.format(ext) for ext in _valid_extensions)))
else:
ProcessFileData(filename, file_extension, lines, Error,
extra_check_functions)
@@ -3465,7 +3546,9 @@ def ParseArguments(args):
'linelength=',
'extensions=',
'record-errors=',
- 'suppress-errors='])
+ 'suppress-errors=',
+ 'stdin-filename=',
+ ])
except getopt.GetoptError:
PrintUsage('Invalid arguments.')
@@ -3475,6 +3558,7 @@ def ParseArguments(args):
counting_style = ''
record_errors_file = None
suppress_errors_file = None
+ stdin_filename = None
for (opt, val) in opts:
if opt == '--help':
@@ -3511,6 +3595,8 @@ def ParseArguments(args):
record_errors_file = val
elif opt == '--suppress-errors':
suppress_errors_file = val
+ elif opt == '--stdin-filename':
+ stdin_filename = val
if not filenames:
PrintUsage('No files were specified.')
@@ -3521,6 +3607,7 @@ def ParseArguments(args):
_SetCountingStyle(counting_style)
_SuppressErrorsFrom(suppress_errors_file)
_RecordErrorsTo(record_errors_file)
+ _cpplint_state.stdin_filename = stdin_filename
return filenames
@@ -3539,7 +3626,7 @@ def main():
if __name__ == '__main__':
main()
-# vim: ts=4 sts=4 sw=4
+# vim: ts=4 sts=4 sw=4 foldmarker=â–¶,â–²
# Ignore "too complex" warnings when using pymode.
# pylama:ignore=C901
diff --git a/src/coverity-model.c b/src/coverity-model.c
new file mode 100644
index 0000000000..3c38e4ae4d
--- /dev/null
+++ b/src/coverity-model.c
@@ -0,0 +1,70 @@
+// Coverity Scan model
+//
+// This is a modeling file for Coverity Scan. Modeling helps to avoid false
+// positives.
+//
+// - A model file can't import any header files.
+// - Therefore only some built-in primitives like int, char and void are
+// available but not wchar_t, NULL etc.
+// - Modeling doesn't need full structs and typedefs. Rudimentary structs
+// and similar types are sufficient.
+// - An uninitialized local pointer is not an error. It signifies that the
+// variable could be either NULL or have some data.
+//
+// Coverity Scan doesn't pick up modifications automatically. The model file
+// must be uploaded by an admin in the analysis settings of
+// http://scan.coverity.com/projects/neovim-neovim
+//
+
+// Issue 105985
+//
+// Teach coverity that uv_pipe_open saves fd on success (0 return value)
+// and doesn't save it on failure (return value != 0).
+
+struct uv_pipe_s {
+ int something;
+};
+
+int uv_pipe_open(struct uv_pipe_s *handle, int fd)
+{
+ int result;
+ if (result == 0) {
+ __coverity_escape__(fd);
+ }
+ return result;
+}
+
+// Issue 2422
+//
+// Teach coverity about jemalloc functions, so that it understands
+// they are equivalent to malloc ones.
+
+void *je_malloc(size_t size)
+{
+ return __coverity_alloc__(size);
+}
+
+void je_free(void *ptr)
+{
+ __coverity_free__(ptr);
+}
+
+void *je_calloc(size_t count, size_t size)
+{
+ return je_malloc(count * size);
+}
+
+void *je_realloc(void *ptr, size_t size)
+{
+ je_free(ptr);
+ return je_malloc(size);
+}
+
+// Hint Coverity that adding item to d avoids losing track
+// of the memory allocated for item.
+typedef struct {} dictitem_T;
+typedef struct {} dict_T;
+int tv_dict_add(dict_T *const d, dictitem_T *const item)
+{
+ __coverity_escape__(item);
+}
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index d80add2835..a2c4e677d4 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -10,38 +10,77 @@ if(USE_GCOV)
endif()
endif()
+if(WIN32)
+ # tell MinGW compiler to enable wmain
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -municode")
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework CoreFoundation")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -framework CoreFoundation")
+endif()
+
+set(TOUCHES_DIR ${PROJECT_BINARY_DIR}/touches)
+set(GENERATOR_DIR ${CMAKE_CURRENT_LIST_DIR}/generators)
set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto)
-set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/msgpack-gen.lua)
-file(GLOB API_HEADERS api/*.h)
-file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
-set(MSGPACK_DISPATCH ${GENERATED_DIR}/msgpack_dispatch.c)
-set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)
+set(API_DISPATCH_GENERATOR ${GENERATOR_DIR}/gen_api_dispatch.lua)
+set(API_UI_EVENTS_GENERATOR ${GENERATOR_DIR}/gen_api_ui_events.lua)
+set(API_METADATA ${PROJECT_BINARY_DIR}/api_metadata.mpack)
+set(FUNCS_DATA ${PROJECT_BINARY_DIR}/funcs_data.mpack)
+set(MSGPACK_LUA_C_BINDINGS ${GENERATED_DIR}/msgpack_lua_c_bindings.generated.c)
+set(HEADER_GENERATOR ${GENERATOR_DIR}/gen_declarations.lua)
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include)
+set(GENERATED_API_DISPATCH ${GENERATED_DIR}/api/private/dispatch_wrappers.generated.h)
+set(GENERATED_FUNCS_METADATA ${GENERATED_DIR}/api/private/funcs_metadata.generated.h)
+set(GENERATED_UI_EVENTS ${GENERATED_DIR}/ui_events.generated.h)
+set(GENERATED_UI_EVENTS_CALL ${GENERATED_DIR}/ui_events_call.generated.h)
+set(GENERATED_UI_EVENTS_REMOTE ${GENERATED_DIR}/ui_events_remote.generated.h)
+set(GENERATED_UI_EVENTS_BRIDGE ${GENERATED_DIR}/ui_events_bridge.generated.h)
+set(GENERATED_UI_EVENTS_METADATA ${GENERATED_DIR}/api/private/ui_events_metadata.generated.h)
set(GENERATED_EX_CMDS_ENUM ${GENERATED_INCLUDES_DIR}/ex_cmds_enum.generated.h)
set(GENERATED_EX_CMDS_DEFS ${GENERATED_DIR}/ex_cmds_defs.generated.h)
+set(GENERATED_FUNCS ${GENERATED_DIR}/funcs.generated.h)
set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h)
set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h)
set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h)
-set(EX_CMDS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genex_cmds.lua)
-set(EVENTS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gen_events.lua)
-set(OPTIONS_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genoptions.lua)
-set(EVENTS_LIST_FILE ${PROJECT_SOURCE_DIR}/src/nvim/auevents.lua)
-set(EX_CMDS_DEFS_FILE ${PROJECT_SOURCE_DIR}/src/nvim/ex_cmds.lua)
-set(OPTIONS_LIST_FILE ${PROJECT_SOURCE_DIR}/src/nvim/options.lua)
-set(UNICODE_TABLES_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/genunicodetables.lua)
+set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua)
+set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua)
+set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua)
+set(OPTIONS_GENERATOR ${GENERATOR_DIR}/gen_options.lua)
+set(UNICODE_TABLES_GENERATOR ${GENERATOR_DIR}/gen_unicode_tables.lua)
set(UNICODE_DIR ${PROJECT_SOURCE_DIR}/unicode)
-set(UNICODEDATA_FILE ${UNICODE_DIR}/UnicodeData.txt)
-set(CASEFOLDING_FILE ${UNICODE_DIR}/CaseFolding.txt)
-set(EASTASIANWIDTH_FILE ${UNICODE_DIR}/EastAsianWidth.txt)
set(GENERATED_UNICODE_TABLES ${GENERATED_DIR}/unicode_tables.generated.h)
+set(VIM_MODULE_FILE ${GENERATED_DIR}/lua/vim_module.generated.h)
+set(VIM_MODULE_SOURCE ${PROJECT_SOURCE_DIR}/src/nvim/lua/vim.lua)
+set(CHAR_BLOB_GENERATOR ${GENERATOR_DIR}/gen_char_blob.lua)
+set(LINT_SUPPRESS_FILE ${PROJECT_BINARY_DIR}/errors.json)
+set(LINT_SUPPRESS_URL_BASE "https://raw.githubusercontent.com/neovim/doc/gh-pages/reports/clint")
+set(LINT_SUPPRESS_URL "${LINT_SUPPRESS_URL_BASE}/errors.json")
+set(LINT_PRG ${PROJECT_SOURCE_DIR}/src/clint.py)
+set(DOWNLOAD_SCRIPT ${PROJECT_SOURCE_DIR}/cmake/Download.cmake)
+set(LINT_SUPPRESSES_ROOT ${PROJECT_BINARY_DIR}/errors)
+set(LINT_SUPPRESSES_URL "${LINT_SUPPRESS_URL_BASE}/errors.tar.gz")
+set(LINT_SUPPRESSES_ARCHIVE ${LINT_SUPPRESSES_ROOT}/errors.tar.gz)
+set(LINT_SUPPRESSES_TOUCH_FILE "${TOUCHES_DIR}/unpacked-clint-errors-archive")
+set(LINT_SUPPRESSES_INSTALL_SCRIPT "${PROJECT_SOURCE_DIR}/cmake/InstallClintErrors.cmake")
+
+file(GLOB UNICODE_FILES ${UNICODE_DIR}/*.txt)
+file(GLOB API_HEADERS api/*.h)
+list(REMOVE_ITEM API_HEADERS ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h)
+file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h)
include_directories(${GENERATED_DIR})
+include_directories(${CACHED_GENERATED_DIR})
include_directories(${GENERATED_INCLUDES_DIR})
+file(MAKE_DIRECTORY ${TOUCHES_DIR})
file(MAKE_DIRECTORY ${GENERATED_DIR})
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR})
+file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT})
+file(MAKE_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src)
-file(GLOB NEOVIM_SOURCES *.c)
+file(GLOB NVIM_SOURCES *.c)
+file(GLOB NVIM_HEADERS *.h)
+file(GLOB XDIFF_SOURCES xdiff/*.c)
+file(GLOB XDIFF_HEADERS xdiff/*.h)
foreach(subdir
os
@@ -51,6 +90,9 @@ foreach(subdir
tui
event
eval
+ lua
+ viml
+ viml/parser
)
if(${subdir} MATCHES "tui" AND NOT FEAT_TUI)
continue()
@@ -59,18 +101,21 @@ foreach(subdir
file(MAKE_DIRECTORY ${GENERATED_DIR}/${subdir})
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/${subdir})
file(GLOB sources ${subdir}/*.c)
- list(APPEND NEOVIM_SOURCES ${sources})
+ file(GLOB headers ${subdir}/*.h)
+ list(APPEND NVIM_SOURCES ${sources})
+ list(APPEND NVIM_HEADERS ${headers})
endforeach()
-file(GLOB_RECURSE NEOVIM_HEADERS *.h)
file(GLOB UNIT_TEST_FIXTURES ${PROJECT_SOURCE_DIR}/test/unit/fixtures/*.c)
# Sort file lists to ensure generated files are created in the same order from
# build to build.
-list(SORT NEOVIM_SOURCES)
-list(SORT NEOVIM_HEADERS)
+list(SORT NVIM_SOURCES)
+list(SORT NVIM_HEADERS)
-foreach(sfile ${NEOVIM_SOURCES})
+list(APPEND LINT_NVIM_SOURCES ${NVIM_SOURCES} ${NVIM_HEADERS})
+
+foreach(sfile ${NVIM_SOURCES})
get_filename_component(f ${sfile} NAME)
if(${f} MATCHES "^(regexp_nfa.c)$")
list(APPEND to_remove ${sfile})
@@ -78,13 +123,15 @@ foreach(sfile ${NEOVIM_SOURCES})
if(WIN32 AND ${f} MATCHES "^(pty_process_unix.c)$")
list(APPEND to_remove ${sfile})
endif()
+ if(NOT WIN32 AND ${f} MATCHES "^(pty_process_win.c)$")
+ list(APPEND to_remove ${sfile})
+ endif()
endforeach()
-list(REMOVE_ITEM NEOVIM_SOURCES ${to_remove})
+list(REMOVE_ITEM NVIM_SOURCES ${to_remove})
-# Handle legacy files that don't yet pass -Wconversion.
+# Legacy files that do not yet pass -Wconversion.
set(CONV_SOURCES
- buffer.c
diff.c
edit.c
eval.c
@@ -99,28 +146,39 @@ set(CONV_SOURCES
screen.c
search.c
spell.c
+ spellfile.c
syntax.c
tag.c
window.c)
-
foreach(sfile ${CONV_SOURCES})
- if(NOT EXISTS "${PROJECT_SOURCE_DIR}/src/nvim/${sfile}")
+ if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${sfile}")
message(FATAL_ERROR "${sfile} doesn't exist (it was added to CONV_SOURCES)")
endif()
endforeach()
+# xdiff: inlined external project, we don't maintain it. #9306
+list(APPEND CONV_SOURCES ${XDIFF_SOURCES})
if(NOT MSVC)
set_source_files_properties(
${CONV_SOURCES} PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-conversion")
+ # gperf generates ANSI-C with incorrect linkage, ignore it.
+ check_c_compiler_flag(-Wno-static-in-inline HAS_WNO_STATIC_IN_INLINE_FLAG)
+ if(HAS_WNO_STATIC_IN_INLINE_FLAG)
+ set_source_files_properties(
+ eval.c PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-static-in-inline -Wno-conversion")
+ else()
+ set_source_files_properties(
+ eval.c PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-conversion")
+ endif()
endif()
-if(DEFINED MIN_LOG_LEVEL)
+if(NOT "${MIN_LOG_LEVEL}" MATCHES "^$")
add_definitions(-DMIN_LOG_LEVEL=${MIN_LOG_LEVEL})
endif()
get_directory_property(gen_cdefs COMPILE_DEFINITIONS)
foreach(gen_cdef ${gen_cdefs} DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
- if(NOT "${gen_cdef}" MATCHES "INCLUDE_GENERATED_DECLARATIONS")
+ if(NOT ${gen_cdef} MATCHES "INCLUDE_GENERATED_DECLARATIONS")
list(APPEND gen_cflags "-D${gen_cdef}")
endif()
endforeach()
@@ -129,99 +187,185 @@ if(CLANG_ASAN_UBSAN OR CLANG_MSAN OR CLANG_TSAN)
endif()
get_directory_property(gen_includes INCLUDE_DIRECTORIES)
-foreach(gen_include ${gen_includes})
+foreach(gen_include ${gen_includes} ${LUA_PREFERRED_INCLUDE_DIRS})
list(APPEND gen_cflags "-I${gen_include}")
endforeach()
+if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_SYSROOT)
+ list(APPEND gen_cflags "-isysroot")
+ list(APPEND gen_cflags "${CMAKE_OSX_SYSROOT}")
+endif()
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
separate_arguments(C_FLAGS_ARRAY UNIX_COMMAND ${CMAKE_C_FLAGS})
separate_arguments(C_FLAGS_${build_type}_ARRAY UNIX_COMMAND ${CMAKE_C_FLAGS_${build_type}})
set(gen_cflags ${gen_cflags} ${C_FLAGS_${build_type}_ARRAY} ${C_FLAGS_ARRAY})
-foreach(sfile ${NEOVIM_SOURCES}
- "${PROJECT_SOURCE_DIR}/src/nvim/regexp_nfa.c")
+function(get_preproc_output varname iname)
+ if(MSVC)
+ set(${varname} /P /Fi${iname} PARENT_SCOPE)
+ else()
+ set(${varname} -E -o ${iname} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# NVIM_GENERATED_FOR_HEADERS: generated headers to be included in headers
+# NVIM_GENERATED_FOR_SOURCES: generated headers to be included in sources
+# NVIM_GENERATED_SOURCES: generated source files
+# These lists must be mutually exclusive.
+foreach(sfile ${NVIM_SOURCES}
+ "${CMAKE_CURRENT_LIST_DIR}/regexp_nfa.c"
+ ${GENERATED_API_DISPATCH}
+ "${GENERATED_UI_EVENTS_CALL}"
+ "${GENERATED_UI_EVENTS_REMOTE}"
+ "${GENERATED_UI_EVENTS_BRIDGE}"
+ )
get_filename_component(full_d ${sfile} PATH)
- file(RELATIVE_PATH d "${PROJECT_SOURCE_DIR}/src/nvim" "${full_d}")
+ file(RELATIVE_PATH d "${CMAKE_CURRENT_LIST_DIR}" "${full_d}")
+ if(${d} MATCHES "^[.][.]|auto/")
+ file(RELATIVE_PATH d "${GENERATED_DIR}" "${full_d}")
+ endif()
get_filename_component(f ${sfile} NAME)
get_filename_component(r ${sfile} NAME_WE)
if(NOT ${d} EQUAL ".")
set(f "${d}/${f}")
set(r "${d}/${r}")
endif()
- set(gf1 "${GENERATED_DIR}/${r}.c.generated.h")
- set(gf2 "${GENERATED_INCLUDES_DIR}/${r}.h.generated.h")
- set(gf3 "${GENERATED_DIR}/${r}.i")
+ set(gf_c_h "${GENERATED_DIR}/${r}.c.generated.h")
+ set(gf_h_h "${GENERATED_INCLUDES_DIR}/${r}.h.generated.h")
+ set(gf_i "${GENERATED_DIR}/${r}.i")
- if(MSVC)
- set(PREPROC_OUTPUT /P /Fi${gf3})
- else()
- set(PREPROC_OUTPUT -E -o ${gf3})
- endif()
+ get_preproc_output(PREPROC_OUTPUT ${gf_i})
add_custom_command(
- OUTPUT "${gf1}" "${gf2}"
+ OUTPUT "${gf_c_h}" "${gf_h_h}"
COMMAND ${CMAKE_C_COMPILER} ${sfile} ${PREPROC_OUTPUT} ${gen_cflags} ${C_FLAGS_ARRAY}
- COMMAND "${LUA_PRG}" "${HEADER_GENERATOR}" "${sfile}" "${gf1}" "${gf2}" "${gf3}"
+ COMMAND "${LUA_PRG}" "${HEADER_GENERATOR}" "${sfile}" "${gf_c_h}" "${gf_h_h}" "${gf_i}"
DEPENDS "${HEADER_GENERATOR}" "${sfile}"
)
- list(APPEND NEOVIM_GENERATED_SOURCES "${gf1}")
- list(APPEND NEOVIM_GENERATED_SOURCES "${gf2}")
+ list(APPEND NVIM_GENERATED_FOR_SOURCES "${gf_c_h}")
+ list(APPEND NVIM_GENERATED_FOR_HEADERS "${gf_h_h}")
if(${d} MATCHES "^api$" AND NOT ${f} MATCHES "^api/helpers.c$")
- list(APPEND API_HEADERS ${gf2})
+ list(APPEND API_HEADERS ${gf_h_h})
endif()
endforeach()
add_custom_command(OUTPUT ${GENERATED_UNICODE_TABLES}
COMMAND ${LUA_PRG} ${UNICODE_TABLES_GENERATOR}
- ${UNICODEDATA_FILE}
- ${CASEFOLDING_FILE}
- ${EASTASIANWIDTH_FILE}
+ ${UNICODE_DIR}
${GENERATED_UNICODE_TABLES}
DEPENDS
${UNICODE_TABLES_GENERATOR}
- ${UNICODEDATA_FILE}
- ${CASEFOLDING_FILE}
- ${EASTASIANWIDTH_FILE}
+ ${UNICODE_FILES}
)
-add_custom_command(OUTPUT ${MSGPACK_DISPATCH}
- COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${API_HEADERS} ${MSGPACK_DISPATCH}
+add_custom_command(
+ OUTPUT ${GENERATED_API_DISPATCH} ${GENERATED_FUNCS_METADATA}
+ ${API_METADATA} ${MSGPACK_LUA_C_BINDINGS}
+ COMMAND ${LUA_PRG} ${API_DISPATCH_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
+ ${GENERATED_API_DISPATCH}
+ ${GENERATED_FUNCS_METADATA} ${API_METADATA}
+ ${MSGPACK_LUA_C_BINDINGS}
+ ${API_HEADERS}
DEPENDS
${API_HEADERS}
${MSGPACK_RPC_HEADERS}
- ${DISPATCH_GENERATOR}
+ ${API_DISPATCH_GENERATOR}
+ ${CMAKE_CURRENT_LIST_DIR}/api/dispatch_deprecated.lua
)
-list(APPEND NEOVIM_GENERATED_SOURCES
- "${PROJECT_BINARY_DIR}/config/auto/pathdef.c"
- "${MSGPACK_DISPATCH}"
+add_custom_command(
+ OUTPUT ${VIM_MODULE_FILE}
+ COMMAND ${LUA_PRG} ${CHAR_BLOB_GENERATOR} ${VIM_MODULE_SOURCE}
+ ${VIM_MODULE_FILE} vim_module
+ DEPENDS
+ ${CHAR_BLOB_GENERATOR}
+ ${VIM_MODULE_SOURCE}
+)
+
+list(APPEND NVIM_GENERATED_SOURCES
+ "${MSGPACK_LUA_C_BINDINGS}"
+)
+
+add_custom_command(
+ OUTPUT ${GENERATED_UI_EVENTS}
+ ${GENERATED_UI_EVENTS_CALL}
+ ${GENERATED_UI_EVENTS_REMOTE}
+ ${GENERATED_UI_EVENTS_BRIDGE}
+ ${GENERATED_UI_EVENTS_METADATA}
+ COMMAND ${LUA_PRG} ${API_UI_EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}
+ ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h
+ ${GENERATED_UI_EVENTS}
+ ${GENERATED_UI_EVENTS_CALL}
+ ${GENERATED_UI_EVENTS_REMOTE}
+ ${GENERATED_UI_EVENTS_BRIDGE}
+ ${GENERATED_UI_EVENTS_METADATA}
+ DEPENDS
+ ${API_UI_EVENTS_GENERATOR}
+ ${CMAKE_CURRENT_LIST_DIR}/api/ui_events.in.h
+)
+
+list(APPEND NVIM_GENERATED_FOR_HEADERS
"${GENERATED_EX_CMDS_ENUM}"
- "${GENERATED_EX_CMDS_DEFS}"
"${GENERATED_EVENTS_ENUM}"
+)
+
+list(APPEND NVIM_GENERATED_FOR_SOURCES
+ "${GENERATED_API_DISPATCH}"
+ "${GENERATED_EX_CMDS_DEFS}"
"${GENERATED_EVENTS_NAMES_MAP}"
"${GENERATED_OPTIONS}"
"${GENERATED_UNICODE_TABLES}"
+ "${VIM_MODULE_FILE}"
+)
+
+list(APPEND NVIM_GENERATED_SOURCES
+ "${PROJECT_BINARY_DIR}/config/auto/pathdef.c"
)
add_custom_command(OUTPUT ${GENERATED_EX_CMDS_ENUM} ${GENERATED_EX_CMDS_DEFS}
COMMAND ${LUA_PRG} ${EX_CMDS_GENERATOR}
- ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_INCLUDES_DIR} ${GENERATED_DIR}
- DEPENDS ${EX_CMDS_GENERATOR} ${EX_CMDS_DEFS_FILE}
+ ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_INCLUDES_DIR} ${GENERATED_DIR}
+ DEPENDS ${EX_CMDS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/ex_cmds.lua
+)
+
+if(NOT GPERF_PRG)
+ message(FATAL_ERROR "gperf was not found.")
+endif()
+add_custom_command(OUTPUT ${GENERATED_FUNCS} ${FUNCS_DATA}
+ COMMAND ${LUA_PRG} ${FUNCS_GENERATOR}
+ ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_DIR} ${API_METADATA} ${FUNCS_DATA}
+ COMMAND ${GPERF_PRG}
+ ${GENERATED_DIR}/funcs.generated.h.gperf --output-file=${GENERATED_FUNCS}
+ DEPENDS ${FUNCS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/eval.lua ${API_METADATA}
)
+list(APPEND NVIM_GENERATED_FOR_SOURCES
+ "${GENERATED_FUNCS}")
add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
COMMAND ${LUA_PRG} ${EVENTS_GENERATOR}
- ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
- DEPENDS ${EVENTS_GENERATOR} ${EVENTS_LIST_FILE}
+ ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP}
+ DEPENDS ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua
)
add_custom_command(OUTPUT ${GENERATED_OPTIONS}
COMMAND ${LUA_PRG} ${OPTIONS_GENERATOR}
- ${PROJECT_SOURCE_DIR}/src/nvim ${GENERATED_OPTIONS}
- DEPENDS ${OPTIONS_GENERATOR} ${OPTIONS_LIST_FILE}
+ ${CMAKE_CURRENT_LIST_DIR} ${GENERATED_OPTIONS}
+ DEPENDS ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua
)
+# NVIM_GENERATED_FOR_SOURCES and NVIM_GENERATED_FOR_HEADERS must be mutually exclusive.
+foreach(hfile ${NVIM_GENERATED_FOR_HEADERS})
+ list(FIND NVIM_GENERATED_FOR_SOURCES ${hfile} hfile_idx)
+ if(NOT ${hfile_idx} EQUAL -1)
+ message(FATAL_ERROR "File included in both NVIM_GENERATED_FOR_HEADERS and NVIM_GENERATED_FOR_SOURCES")
+ endif()
+endforeach()
+
# Our dependencies come first.
+if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
+ list(APPEND NVIM_LINK_LIBRARIES pthread c++abi)
+endif()
+
if (LibIntl_FOUND)
list(APPEND NVIM_LINK_LIBRARIES ${LibIntl_LIBRARY})
endif()
@@ -230,6 +374,10 @@ if(Iconv_LIBRARIES)
list(APPEND NVIM_LINK_LIBRARIES ${Iconv_LIBRARIES})
endif()
+if(WIN32)
+ list(APPEND NVIM_LINK_LIBRARIES ${WINPTY_LIBRARIES})
+endif()
+
# Put these last on the link line, since multiple things may depend on them.
list(APPEND NVIM_LINK_LIBRARIES
${LIBUV_LIBRARIES}
@@ -247,18 +395,150 @@ if(UNIX)
)
endif()
-set(NVIM_EXEC_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES})
+set(NVIM_EXEC_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES} ${LUA_PREFERRED_LIBRARIES})
# Don't use jemalloc in the unit test library.
if(JEMALLOC_FOUND)
list(APPEND NVIM_EXEC_LINK_LIBRARIES ${JEMALLOC_LIBRARIES})
endif()
-add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES}
- ${NEOVIM_HEADERS})
+if(POLICY CMP0069)
+ cmake_policy(SET CMP0069 NEW)
+endif()
+
+add_executable(nvim ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
+ ${NVIM_GENERATED_SOURCES} ${NVIM_SOURCES} ${NVIM_HEADERS}
+ ${XDIFF_SOURCES} ${XDIFF_HEADERS})
target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES})
install_helper(TARGETS nvim)
+set_property(TARGET nvim APPEND PROPERTY
+ INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS})
+
+if(ENABLE_LTO AND (POLICY CMP0069))
+ include(CheckIPOSupported)
+ check_ipo_supported(RESULT IPO_SUPPORTED)
+ if(IPO_SUPPORTED AND (NOT CMAKE_BUILD_TYPE MATCHES Debug))
+ set_property(TARGET nvim PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
+ endif()
+endif()
+
+if(WIN32)
+ # Copy DLLs and third-party tools to bin/ and install them along with nvim
+ add_custom_target(nvim_runtime_deps ALL
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+ install(DIRECTORY ${PROJECT_BINARY_DIR}/windows_runtime_deps/
+ DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ add_custom_target(nvim_dll_deps DEPENDS nvim
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/windows_runtime_deps
+ COMMAND ${CMAKE_COMMAND}
+ "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}"
+ -DBINARY="${PROJECT_BINARY_DIR}/bin/nvim${CMAKE_EXECUTABLE_SUFFIX}"
+ -DDST=${PROJECT_BINARY_DIR}/windows_runtime_deps
+ -P ${PROJECT_SOURCE_DIR}/cmake/WindowsDllCopy.cmake)
+ add_dependencies(nvim_runtime_deps nvim_dll_deps)
+
+ # A CMake script is used for copying the files to avoid the
+ # "command line is too long" error that occurs when Ninja tries running
+ # a command that exceeds the length limit (8191 characters) on Windows.
+ # See https://developercommunity.visualstudio.com/content/problem/212207/file-open-cmake-the-command-line-is-too-long.html
+ set(EXTERNAL_BLOBS_SCRIPT
+ "file(MAKE_DIRECTORY \"${PROJECT_BINARY_DIR}/windows_runtime_deps/platforms\")")
+ foreach(DEP_FILE IN ITEMS
+ ca-bundle.crt
+ cat.exe
+ curl.exe
+ diff.exe
+ tee.exe
+ tidy.exe
+ win32yank.exe
+ winpty-agent.exe
+ xxd.exe
+
+ D3Dcompiler_47.dll
+ libEGL.dll
+ libgcc_s_dw2-1.dll
+ libGLESV2.dll
+ libstdc++-6.dll
+ libwinpthread-1.dll
+ nvim-qt.exe
+ Qt5Core.dll
+ Qt5Gui.dll
+ Qt5Network.dll
+ Qt5Svg.dll
+ Qt5Widgets.dll
+ winpty.dll
+
+ platforms/qwindows.dll
+ )
+ get_filename_component(DEP_FILE_DIR ${DEP_FILE} DIRECTORY)
+ set(EXTERNAL_BLOBS_SCRIPT "${EXTERNAL_BLOBS_SCRIPT}\n"
+ "file(COPY \"${DEPS_PREFIX}/bin/${DEP_FILE}\"
+ DESTINATION \"${PROJECT_BINARY_DIR}/windows_runtime_deps/${DEP_FILE_DIR}\")")
+ endforeach()
+ file(WRITE ${PROJECT_BINARY_DIR}/external_blobs.cmake ${EXTERNAL_BLOBS_SCRIPT})
+ add_custom_target(external_blobs
+ COMMAND ${CMAKE_COMMAND} -P ${PROJECT_BINARY_DIR}/external_blobs.cmake)
+ set_target_properties(external_blobs PROPERTIES FOLDER deps)
+ add_dependencies(nvim_runtime_deps external_blobs)
+else()
+ add_custom_target(nvim_runtime_deps) # Stub target to avoid CMP0046.
+endif()
+set_target_properties(nvim_runtime_deps PROPERTIES FOLDER deps)
+
+add_library(
+ libnvim
+ STATIC
+ EXCLUDE_FROM_ALL
+ ${NVIM_SOURCES} ${NVIM_GENERATED_SOURCES}
+ ${NVIM_HEADERS} ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
+ ${XDIFF_SOURCES} ${XDIFF_HEADERS}
+)
+set_property(TARGET libnvim APPEND PROPERTY
+ INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS})
+set_target_properties(
+ libnvim
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON
+ OUTPUT_NAME nvim
+)
+set_property(
+ TARGET libnvim
+ APPEND_STRING PROPERTY COMPILE_FLAGS " -DMAKE_LIB "
+)
+
+if(NOT LUAJIT_FOUND)
+ message(STATUS "luajit not found, skipping nvim-test (unit tests) target")
+else()
+ set(NVIM_TEST_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES} ${LUAJIT_LIBRARIES})
+ add_library(
+ nvim-test
+ MODULE
+ EXCLUDE_FROM_ALL
+ ${NVIM_SOURCES} ${NVIM_GENERATED_SOURCES}
+ ${NVIM_HEADERS} ${NVIM_GENERATED_FOR_SOURCES} ${NVIM_GENERATED_FOR_HEADERS}
+ ${XDIFF_SOURCES} ${XDIFF_HEADERS}
+ ${UNIT_TEST_FIXTURES}
+ )
+ target_link_libraries(nvim-test ${NVIM_TEST_LINK_LIBRARIES})
+ target_link_libraries(libnvim ${NVIM_TEST_LINK_LIBRARIES})
+ set_property(
+ TARGET nvim-test
+ APPEND PROPERTY INCLUDE_DIRECTORIES ${LUAJIT_INCLUDE_DIRS}
+ )
+ set_target_properties(
+ nvim-test
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON
+ )
+ set_property(
+ TARGET nvim-test
+ APPEND_STRING PROPERTY COMPILE_FLAGS " -DUNIT_TESTING "
+ )
+endif()
+
if(CLANG_ASAN_UBSAN)
message(STATUS "Enabling Clang address sanitizer and undefined behavior sanitizer for nvim.")
check_c_compiler_flag(-fno-sanitize-recover=all SANITIZE_RECOVER_ALL)
@@ -279,20 +559,117 @@ elseif(CLANG_TSAN)
message(STATUS "Enabling Clang thread sanitizer for nvim.")
set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-DEXITFREE ")
set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fsanitize=thread ")
+ set_property(TARGET nvim APPEND_STRING PROPERTY COMPILE_FLAGS "-fPIE ")
set_property(TARGET nvim APPEND_STRING PROPERTY LINK_FLAGS "-fsanitize=thread ")
endif()
-add_library(libnvim STATIC EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES}
- ${NEOVIM_SOURCES} ${NEOVIM_HEADERS})
-target_link_libraries(libnvim ${NVIM_LINK_LIBRARIES})
-set_target_properties(libnvim PROPERTIES
- POSITION_INDEPENDENT_CODE ON
- OUTPUT_NAME nvim)
-set_property(TARGET libnvim APPEND_STRING PROPERTY COMPILE_FLAGS " -DMAKE_LIB ")
-
-add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES}
- ${NEOVIM_SOURCES} ${UNIT_TEST_FIXTURES} ${NEOVIM_HEADERS})
-target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES})
-set_property(TARGET nvim-test APPEND_STRING PROPERTY COMPILE_FLAGS -DUNIT_TESTING)
+function(get_test_target prefix sfile relative_path_var target_var)
+ get_filename_component(full_d "${sfile}" PATH)
+ file(RELATIVE_PATH d "${PROJECT_SOURCE_DIR}/src/nvim" "${full_d}")
+ if(d MATCHES "^[.][.]")
+ file(RELATIVE_PATH d "${GENERATED_DIR}" "${full_d}")
+ endif()
+ get_filename_component(r "${sfile}" NAME)
+ if(NOT d MATCHES "^[.]?$")
+ set(r "${d}/${r}")
+ endif()
+ string(REGEX REPLACE "[/.]" "-" suffix "${r}")
+ set(${relative_path_var} ${r} PARENT_SCOPE)
+ if(prefix STREQUAL "")
+ set(${target_var} "${suffix}" PARENT_SCOPE)
+ else()
+ set(${target_var} "${prefix}-${suffix}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+set(NO_SINGLE_CHECK_HEADERS
+ os/win_defs.h
+ os/pty_process_win.h
+)
+foreach(hfile ${NVIM_HEADERS})
+ get_test_target(test-includes "${hfile}" relative_path texe)
+
+ if(NOT ${hfile} MATCHES "[.](c|in)[.]h$")
+ set(tsource "${GENERATED_DIR}/${relative_path}.test-include.c")
+ write_file("${tsource}" "#include \"${hfile}\"\nint main(int argc, char **argv) { return 0; }")
+ add_executable(
+ ${texe}
+ EXCLUDE_FROM_ALL
+ ${tsource} ${NVIM_HEADERS} ${NVIM_GENERATED_FOR_HEADERS})
+ set_property(
+ TARGET ${texe}
+ APPEND PROPERTY INCLUDE_DIRECTORIES ${LUA_PREFERRED_INCLUDE_DIRS}
+ )
+ set_target_properties(${texe} PROPERTIES FOLDER test)
+
+ list(FIND NO_SINGLE_CHECK_HEADERS "${relative_path}" hfile_exclude_idx)
+ if(${hfile_exclude_idx} EQUAL -1)
+ list(APPEND HEADER_CHECK_TARGETS ${texe})
+ endif()
+ endif()
+endforeach()
+add_custom_target(check-single-includes DEPENDS ${HEADER_CHECK_TARGETS})
+
+function(add_download output url allow_failure)
+ add_custom_command(
+ OUTPUT "${output}"
+ COMMAND
+ ${CMAKE_COMMAND}
+ -DURL=${url} -DFILE=${output}
+ -DALLOW_FAILURE=${allow_failure}
+ -P ${DOWNLOAD_SCRIPT}
+ DEPENDS ${DOWNLOAD_SCRIPT}
+ )
+endfunction()
+
+add_download(${LINT_SUPPRESSES_ARCHIVE} ${LINT_SUPPRESSES_URL} off)
+
+add_custom_command(
+ OUTPUT ${LINT_SUPPRESSES_TOUCH_FILE}
+ WORKING_DIRECTORY ${LINT_SUPPRESSES_ROOT}/src
+ COMMAND ${CMAKE_COMMAND} -E tar xfz ${LINT_SUPPRESSES_ARCHIVE}
+ COMMAND
+ ${CMAKE_COMMAND}
+ -DTARGET=${LINT_SUPPRESSES_ROOT}
+ -P ${LINT_SUPPRESSES_INSTALL_SCRIPT}
+ COMMAND ${CMAKE_COMMAND} -E touch ${LINT_SUPPRESSES_TOUCH_FILE}
+ DEPENDS
+ ${LINT_SUPPRESSES_ARCHIVE} ${LINT_SUPPRESSES_INSTALL_SCRIPT}
+)
+
+add_download(${LINT_SUPPRESS_FILE} ${LINT_SUPPRESS_URL} off)
+
+set(LINT_NVIM_REL_SOURCES)
+foreach(sfile ${LINT_NVIM_SOURCES})
+ get_test_target("" "${sfile}" r suffix)
+ set(suppress_file ${LINT_SUPPRESSES_ROOT}/${suffix}.json)
+ set(suppress_url "${LINT_SUPPRESS_URL_BASE}/${suffix}.json")
+ set(rsfile src/nvim/${r})
+ set(touch_file "${TOUCHES_DIR}/ran-clint-${suffix}")
+ add_custom_command(
+ OUTPUT ${touch_file}
+ COMMAND ${LINT_PRG} --suppress-errors=${suppress_file} ${rsfile}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ COMMAND ${CMAKE_COMMAND} -E touch ${touch_file}
+ DEPENDS ${LINT_PRG} ${sfile} ${LINT_SUPPRESSES_TOUCH_FILE}
+ )
+ list(APPEND LINT_TARGETS ${touch_file})
+ list(APPEND LINT_NVIM_REL_SOURCES ${rsfile})
+endforeach()
+add_custom_target(clint DEPENDS ${LINT_TARGETS})
+
+add_custom_target(
+ clint-full
+ COMMAND
+ ${LINT_PRG} --suppress-errors=${LINT_SUPPRESS_FILE} ${LINT_NVIM_REL_SOURCES}
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ DEPENDS ${LINT_PRG} ${LINT_NVIM_SOURCES} ${LINT_SUPPRESS_FILE}
+)
+
+add_custom_target(generated-sources DEPENDS
+ ${NVIM_GENERATED_FOR_SOURCES}
+ ${NVIM_GENERATED_FOR_HEADERS}
+ ${NVIM_GENERATED_SOURCES}
+)
add_subdirectory(po)
diff --git a/src/nvim/README.md b/src/nvim/README.md
index f16c6de12f..02464c2500 100644
--- a/src/nvim/README.md
+++ b/src/nvim/README.md
@@ -1,25 +1,119 @@
-## Source code overview
+Nvim core
+=========
-Since Neovim has inherited most code from Vim, some information in [its
-README](https://raw.githubusercontent.com/vim/vim/master/src/README.txt) still
-applies.
+Module-specific details are documented at the top of each module (`terminal.c`,
+`screen.c`, …).
-This document aims to give a high level overview of how Neovim works internally,
-focusing on parts that are different from Vim. Currently this is still a work in
-progress, especially because I have avoided adding too many details about parts
-that are constantly changing. As the code becomes more organized and stable,
-this document will be updated to reflect the changes.
+See `:help dev` for guidelines.
-If you are looking for module-specific details, it is best to read the source
-code. Some files are extensively commented at the top (e.g. terminal.c,
-screen.c).
+Filename conventions
+--------------------
-### Top-level program loops
+The source files use extensions to hint about their purpose.
-First let's understand what a Vim-like program does by analyzing the workflow of
-a typical editing session:
+- `*.c`, `*.generated.c` - full C files, with all includes, etc.
+- `*.c.h` - parametrized C files, contain all necessary includes, but require
+ defining macros before actually using. Example: `typval_encode.c.h`
+- `*.h` - full headers, with all includes. Does *not* apply to `*.generated.h`.
+- `*.h.generated.h` - exported functions’ declarations.
+- `*.c.generated.h` - static functions’ declarations.
-01. Vim dispays the welcome screen
+Logs
+----
+
+Low-level log messages sink to `$NVIM_LOG_FILE`.
+
+Use `LOG_CALLSTACK()` (Linux only) to log the current stacktrace. To log to an
+alternate file (e.g. stderr) use `LOG_CALLSTACK_TO_FILE(FILE*)`.
+
+UI events are logged at DEBUG level (`DEBUG_LOG_LEVEL`).
+
+ rm -rf build/
+ make CMAKE_EXTRA_FLAGS="-DMIN_LOG_LEVEL=0"
+
+Many log messages have a shared prefix, such as "UI" or "RPC". Use the shell to
+filter the log, e.g. at DEBUG level you might want to exclude UI messages:
+
+ tail -F ~/.local/share/nvim/log | cat -v | stdbuf -o0 grep -v UI | stdbuf -o0 tee -a log
+
+Build with ASAN
+---------------
+
+Building Nvim with Clang sanitizers (Address Sanitizer: ASan, Undefined
+Behavior Sanitizer: UBSan, Memory Sanitizer: MSan, Thread Sanitizer: TSan) is
+a good way to catch undefined behavior, leaks and other errors as soon as they
+happen. It's significantly faster than Valgrind.
+
+Requires clang 3.4 or later:
+
+ clang --version
+
+Build Nvim with sanitizer instrumentation:
+
+ CC=clang make CMAKE_EXTRA_FLAGS="-DCLANG_ASAN_UBSAN=ON"
+
+Create a directory to store logs:
+
+ mkdir -p "$HOME/logs"
+
+Enable the sanitizer(s) via these environment variables:
+
+ # Change to detect_leaks=1 to detect memory leaks (slower).
+ export ASAN_OPTIONS="detect_leaks=0:log_path=$HOME/logs/asan"
+ export ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-5.0/bin/llvm-symbolizer
+
+ export MSAN_SYMBOLIZER_PATH=/usr/lib/llvm-5.0/bin/llvm-symbolizer
+ export TSAN_OPTIONS="external_symbolizer_path=/usr/lib/llvm-5.0/bin/llvm-symbolizer log_path=${HOME}/logs/tsan"
+
+Logs will be written to `${HOME}/logs/*san.PID`.
+
+TUI debugging
+-------------
+
+### TUI troubleshoot
+
+Nvim logs its internal terminfo state at 'verbose' level 3. This makes it
+possible to see exactly what terminfo values Nvim is using on any system.
+
+ nvim -V3log
+
+### TUI trace
+
+The ancient `script` command is still the "state of the art" for tracing
+terminal behavior. The libvterm `vterm-dump` utility formats the result for
+human-readability.
+
+Record a Nvim terminal session and format it with `vterm-dump`:
+
+ script foo
+ ./build/bin/nvim -u NONE
+ # Exit the script session with CTRL-d
+
+ # Use `vterm-dump` utility to format the result.
+ ./.deps/usr/bin/vterm-dump foo > bar
+
+Then you can compare `bar` with another session, to debug TUI behavior.
+
+### TUI redraw
+
+Set the 'writedelay' option to see where and when the UI is painted.
+
+ :set writedelay=1
+
+### Terminal reference
+
+- `man terminfo`
+- http://bazaar.launchpad.net/~libvterm/libvterm/trunk/view/head:/doc/seqs.txt
+- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
+
+Nvim lifecycle
+--------------
+
+Following describes how Nvim processes input.
+
+Consider a typical Vim-like editing session:
+
+01. Vim displays the welcome screen
02. User types: `:`
03. Vim enters command-line mode
04. User types: `edit README.txt<CR>`
@@ -41,16 +135,14 @@ a typical editing session:
21. User types: `word<ESC>`
22. Vim inserts "word" at the beginning and returns to normal mode
-Note that we have split user actions into sequences of inputs that change the
-state of the editor. While there's no documentation about a "g command
-mode" (step 16), internally it is implemented similarly to "operator-pending
-mode".
+Note that we split user actions into sequences of inputs that change the state
+of the editor. While there's no documentation about a "g command mode" (step
+16), internally it is implemented similarly to "operator-pending mode".
-From this we can see that Vim has the behavior of a input-driven state
-machine (more specifically, a pushdown automaton since it requires a stack for
+From this we can see that Vim has the behavior of an input-driven state machine
+(more specifically, a pushdown automaton since it requires a stack for
transitioning back from states). Assuming each state has a callback responsible
-for handling keys, this pseudocode (a python-like language) shows a good
-representation of the main program loop:
+for handling keys, this pseudocode represents the main program loop:
```py
def state_enter(state_callback, data):
@@ -126,12 +218,11 @@ def insert_state(data, key):
return true
```
-While the actual code is much more complicated, the above gives an idea of how
-Neovim is organized internally. Some states like the `g_command_state` or
-`get_operator_count_state` do not have a dedicated `state_enter` callback, but
-are implicitly embedded into other states (this will change later as we continue
-the refactoring effort). To start reading the actual code, here's the
-recommended order:
+The above gives an idea of how Nvim is organized internally. Some states like
+the `g_command_state` or `get_operator_count_state` do not have a dedicated
+`state_enter` callback, but are implicitly embedded into other states (this
+will change later as we continue the refactoring effort). To start reading the
+actual code, here's the recommended order:
1. `state_enter()` function (state.c). This is the actual program loop,
note that a `VimState` structure is used, which contains function pointers
@@ -152,16 +243,17 @@ modes managed by the `state_enter` loop:
- insert mode: `insert_{enter,check,execute}()`(`edit.c`)
- terminal mode: `terminal_{enter,execute}()`(`terminal.c`)
-### Async event support
+Async event support
+-------------------
-One of the features Neovim added is the support for handling arbitrary
+One of the features Nvim added is the support for handling arbitrary
asynchronous events, which can include:
-- msgpack-rpc requests
+- RPC requests
- job control callbacks
-- timers (not implemented yet but the support code is already there)
+- timers
-Neovim implements this functionality by entering another event loop while
+Nvim implements this functionality by entering another event loop while
waiting for characters, so instead of:
```py
@@ -171,7 +263,7 @@ def state_enter(state_callback, data):
while state_callback(data, key) # invoke the callback for the current state
```
-Neovim program loop is more like:
+Nvim program loop is more like:
```py
def state_enter(state_callback, data):
@@ -182,9 +274,31 @@ def state_enter(state_callback, data):
where `event` is something the operating system delivers to us, including (but
not limited to) user input. The `read_next_event()` part is internally
-implemented by libuv, the platform layer used by Neovim.
+implemented by libuv, the platform layer used by Nvim.
-Since Neovim inherited its code from Vim, the states are not prepared to receive
+Since Nvim inherited its code from Vim, the states are not prepared to receive
"arbitrary events", so we use a special key to represent those (When a state
receives an "arbitrary event", it normally doesn't do anything other update the
screen).
+
+Main loop
+---------
+
+The `Loop` structure (which describes `main_loop`) abstracts multiple queues
+into one loop:
+
+ uv_loop_t uv;
+ MultiQueue *events;
+ MultiQueue *thread_events;
+ MultiQueue *fast_events;
+
+`loop_poll_events` checks `Loop.uv` and `Loop.fast_events` whenever Nvim is
+idle, and also at `os_breakcheck` intervals.
+
+MultiQueue is cool because you can attach throw-away "child queues" trivially.
+For example `do_os_system()` does this (for every spawned process!) to
+automatically route events onto the `main_loop`:
+
+ Process *proc = &uvproc.process;
+ MultiQueue *events = multiqueue_new_child(main_loop.events);
+ proc->events = events;
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 55b535c78c..5df0f0bb47 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.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
+
// Much of this code was adapted from 'if_py_both.h' from the original
// vim source
#include <stdbool.h>
@@ -10,11 +13,11 @@
#include "nvim/api/private/defs.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
+#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/ex_cmds.h"
#include "nvim/mark.h"
#include "nvim/fileio.h"
@@ -22,17 +25,35 @@
#include "nvim/syntax.h"
#include "nvim/window.h"
#include "nvim/undo.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/buffer_updates.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/buffer.c.generated.h"
#endif
+
+/// \defgroup api-buffer
+///
+/// Unloaded Buffers:~
+///
+/// Buffers may be unloaded by the |:bunload| command or the buffer's
+/// |'bufhidden'| option. When a buffer is unloaded its file contents are freed
+/// from memory and vim cannot operate on the buffer lines until it is reloaded
+/// (usually by opening the buffer again in a new window). API methods such as
+/// |nvim_buf_get_lines()| and |nvim_buf_line_count()| will be affected.
+///
+/// You can use |nvim_buf_is_loaded()| or |nvim_buf_line_count()| to check
+/// whether a buffer is loaded.
+
+
/// Gets the buffer line count
///
-/// @param buffer The buffer handle
-/// @param[out] err Details of an error that may have occurred
-/// @return The line count
-Integer buffer_line_count(Buffer buffer, Error *err)
+/// @param buffer Buffer handle
+/// @param[out] err Error details, if any
+/// @return Line count, or 0 for unloaded buffer. |api-buffer|
+Integer nvim_buf_line_count(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -40,29 +61,34 @@ Integer buffer_line_count(Buffer buffer, Error *err)
return 0;
}
+ // return sentinel value if the buffer isn't loaded
+ if (buf->b_ml.ml_mfp == NULL) {
+ return 0;
+ }
+
return buf->b_ml.ml_line_count;
}
/// Gets a buffer line
///
-/// @deprecated use buffer_get_lines instead.
+/// @deprecated use nvim_buf_get_lines instead.
/// for positive indices (including 0) use
-/// "buffer_get_lines(buffer, index, index+1, true)"
+/// "nvim_buf_get_lines(buffer, index, index+1, true)"
/// for negative indices use
-/// "buffer_get_lines(buffer, index-1, index, true)"
+/// "nvim_buf_get_lines(buffer, index-1, index, true)"
///
-/// @param buffer The buffer handle
-/// @param index The line index
-/// @param[out] err Details of an error that may have occurred
-/// @return The line string
+/// @param buffer Buffer handle
+/// @param index Line index
+/// @param[out] err Error details, if any
+/// @return Line string
String buffer_get_line(Buffer buffer, Integer index, Error *err)
{
String rv = { .size = 0 };
index = convert_index(index);
- Array slice = buffer_get_lines(buffer, index, index+1, true, err);
+ Array slice = nvim_buf_get_lines(0, buffer, index, index+1, true, err);
- if (!err->set && slice.size) {
+ if (!ERROR_SET(err) && slice.size) {
rv = slice.items[0].data.string;
}
@@ -71,89 +97,143 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err)
return rv;
}
+/// Activate updates from this buffer to the current channel.
+///
+/// @param buffer The buffer handle
+/// @param send_buffer Set to true if the initial notification should contain
+/// the whole buffer. If so, the first notification will be a
+/// `nvim_buf_lines_event`. Otherwise, the first notification will be
+/// a `nvim_buf_changedtick_event`
+/// @param opts Optional parameters. Currently not used.
+/// @param[out] err Details of an error that may have occurred
+/// @return False when updates couldn't be enabled because the buffer isn't
+/// loaded or `opts` contained an invalid key; otherwise True.
+Boolean nvim_buf_attach(uint64_t channel_id,
+ Buffer buffer,
+ Boolean send_buffer,
+ Dictionary opts,
+ Error *err)
+ FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
+{
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "dict isn't empty");
+ return false;
+ }
+
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return false;
+ }
+
+ return buf_updates_register(buf, channel_id, send_buffer);
+}
+//
+/// Deactivate updates from this buffer to the current channel.
+///
+/// @param buffer The buffer handle
+/// @param[out] err Details of an error that may have occurred
+/// @return False when updates couldn't be disabled because the buffer
+/// isn't loaded; otherwise True.
+Boolean nvim_buf_detach(uint64_t channel_id,
+ Buffer buffer,
+ Error *err)
+ FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return false;
+ }
+
+ buf_updates_unregister(buf, channel_id);
+ return true;
+}
+
/// Sets a buffer line
///
-/// @deprecated use buffer_set_lines instead.
+/// @deprecated use nvim_buf_set_lines instead.
/// for positive indices use
-/// "buffer_set_lines(buffer, index, index+1, true, [line])"
+/// "nvim_buf_set_lines(buffer, index, index+1, true, [line])"
/// for negative indices use
-/// "buffer_set_lines(buffer, index-1, index, true, [line])"
+/// "nvim_buf_set_lines(buffer, index-1, index, true, [line])"
///
-/// @param buffer The buffer handle
-/// @param index The line index
-/// @param line The new line.
-/// @param[out] err Details of an error that may have occurred
+/// @param buffer Buffer handle
+/// @param index Line index
+/// @param line Contents of the new line
+/// @param[out] err Error details, if any
void buffer_set_line(Buffer buffer, Integer index, String line, Error *err)
{
Object l = STRING_OBJ(line);
Array array = { .items = &l, .size = 1 };
index = convert_index(index);
- buffer_set_lines(buffer, index, index+1, true, array, err);
+ nvim_buf_set_lines(0, buffer, index, index+1, true, array, err);
}
/// Deletes a buffer line
///
-/// @deprecated use buffer_set_lines instead.
+/// @deprecated use nvim_buf_set_lines instead.
/// for positive indices use
-/// "buffer_set_lines(buffer, index, index+1, true, [])"
+/// "nvim_buf_set_lines(buffer, index, index+1, true, [])"
/// for negative indices use
-/// "buffer_set_lines(buffer, index-1, index, true, [])"
-/// @param buffer The buffer handle
-/// @param index The line index
-/// @param[out] err Details of an error that may have occurred
+/// "nvim_buf_set_lines(buffer, index-1, index, true, [])"
+/// @param buffer buffer handle
+/// @param index line index
+/// @param[out] err Error details, if any
void buffer_del_line(Buffer buffer, Integer index, Error *err)
{
Array array = ARRAY_DICT_INIT;
index = convert_index(index);
- buffer_set_lines(buffer, index, index+1, true, array, err);
+ nvim_buf_set_lines(0, buffer, index, index+1, true, array, err);
}
/// Retrieves a line range from the buffer
///
-/// @deprecated use buffer_get_lines(buffer, newstart, newend, false)
+/// @deprecated use nvim_buf_get_lines(buffer, newstart, newend, false)
/// where newstart = start + int(not include_start) - int(start < 0)
/// newend = end + int(include_end) - int(end < 0)
/// int(bool) = 1 if bool is true else 0
-/// @param buffer The buffer handle
-/// @param start The first line index
-/// @param end The last line index
-/// @param include_start True if the slice includes the `start` parameter
-/// @param include_end True if the slice includes the `end` parameter
-/// @param[out] err Details of an error that may have occurred
-/// @return An array of lines
+/// @param buffer Buffer handle
+/// @param start First line index
+/// @param end Last line index
+/// @param include_start True if the slice includes the `start` parameter
+/// @param include_end True if the slice includes the `end` parameter
+/// @param[out] err Error details, if any
+/// @return Array of lines
ArrayOf(String) buffer_get_line_slice(Buffer buffer,
- Integer start,
- Integer end,
- Boolean include_start,
- Boolean include_end,
- Error *err)
+ Integer start,
+ Integer end,
+ Boolean include_start,
+ Boolean include_end,
+ Error *err)
{
start = convert_index(start) + !include_start;
end = convert_index(end) + include_end;
- return buffer_get_lines(buffer, start , end, false, err);
+ return nvim_buf_get_lines(0, buffer, start , end, false, err);
}
-
-/// Retrieves a line range from the buffer
+/// Gets a line-range from the buffer.
///
/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
-/// as length+1+index, i e -1 refers to the index past the end. So to get the
-/// last element set start=-2 and end=-1.
+/// as length+1+index: -1 refers to the index past the end. So to get the
+/// last element use start=-2 and end=-1.
///
/// Out-of-bounds indices are clamped to the nearest valid value, unless
/// `strict_indexing` is set.
///
-/// @param buffer The buffer handle
-/// @param start The first line index
-/// @param end The last line index (exclusive)
-/// @param strict_indexing whether out-of-bounds should be an error.
-/// @param[out] err Details of an error that may have occurred
-/// @return An array of lines
-ArrayOf(String) buffer_get_lines(Buffer buffer,
- Integer start,
- Integer end,
- Boolean strict_indexing,
- Error *err)
+/// @param buffer Buffer handle
+/// @param start First line index
+/// @param end Last line index (exclusive)
+/// @param strict_indexing Whether out-of-bounds should be an error.
+/// @param[out] err Error details, if any
+/// @return Array of lines, or empty array for unloaded buffer.
+ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
+ Buffer buffer,
+ Integer start,
+ Integer end,
+ Boolean strict_indexing,
+ Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -162,12 +242,17 @@ ArrayOf(String) buffer_get_lines(Buffer buffer,
return rv;
}
+ // return sentinel value if the buffer isn't loaded
+ if (buf->b_ml.ml_mfp == NULL) {
+ return rv;
+ }
+
bool oob = false;
start = normalize_index(buf, start, &oob);
end = normalize_index(buf, end, &oob);
if (strict_indexing && oob) {
- api_set_error(err, Validation, _("Index out of bounds"));
+ api_set_error(err, kErrorTypeValidation, "Index out of bounds");
return rv;
}
@@ -179,25 +264,13 @@ ArrayOf(String) buffer_get_lines(Buffer buffer,
rv.size = (size_t)(end - start);
rv.items = xcalloc(sizeof(Object), rv.size);
- for (size_t i = 0; i < rv.size; i++) {
- int64_t lnum = start + (int64_t)i;
-
- if (lnum > LONG_MAX) {
- api_set_error(err, Validation, _("Line index is too high"));
- goto end;
- }
-
- const char *bufstr = (char *) ml_get_buf(buf, (linenr_T) lnum, false);
- Object str = STRING_OBJ(cstr_to_string(bufstr));
-
- // Vim represents NULs as NLs, but this may confuse clients.
- strchrsub(str.data.string.data, '\n', '\0');
-
- rv.items[i] = str;
+ if (!buf_collect_lines(buf, rv.size, start,
+ (channel_id != VIML_INTERNAL_CALL), &rv, err)) {
+ goto end;
}
end:
- if (err->set) {
+ if (ERROR_SET(err)) {
for (size_t i = 0; i < rv.size; i++) {
xfree(rv.items[i].data.string.data);
}
@@ -212,57 +285,59 @@ end:
/// Replaces a line range on the buffer
///
-/// @deprecated use buffer_set_lines(buffer, newstart, newend, false, lines)
+/// @deprecated use nvim_buf_set_lines(buffer, newstart, newend, false, lines)
/// where newstart = start + int(not include_start) + int(start < 0)
/// newend = end + int(include_end) + int(end < 0)
/// int(bool) = 1 if bool is true else 0
///
-/// @param buffer The buffer handle
-/// @param start The first line index
-/// @param end The last line index
-/// @param include_start True if the slice includes the `start` parameter
-/// @param include_end True if the slice includes the `end` parameter
-/// @param replacement An array of lines to use as replacement(A 0-length
-// array will simply delete the line range)
-/// @param[out] err Details of an error that may have occurred
+/// @param buffer Buffer handle
+/// @param start First line index
+/// @param end Last line index
+/// @param include_start True if the slice includes the `start` parameter
+/// @param include_end True if the slice includes the `end` parameter
+/// @param replacement Array of lines to use as replacement (0-length
+// array will delete the line range)
+/// @param[out] err Error details, if any
void buffer_set_line_slice(Buffer buffer,
- Integer start,
- Integer end,
- Boolean include_start,
- Boolean include_end,
- ArrayOf(String) replacement,
- Error *err)
+ Integer start,
+ Integer end,
+ Boolean include_start,
+ Boolean include_end,
+ ArrayOf(String) replacement, // NOLINT
+ Error *err)
{
start = convert_index(start) + !include_start;
end = convert_index(end) + include_end;
- buffer_set_lines(buffer, start, end, false, replacement, err);
+ nvim_buf_set_lines(0, buffer, start, end, false, replacement, err);
}
-/// Replaces line range on the buffer
+/// Sets (replaces) a line-range in the buffer.
///
/// Indexing is zero-based, end-exclusive. Negative indices are interpreted
-/// as length+1+index, i e -1 refers to the index past the end. So to change
-/// or delete the last element set start=-2 and end=-1.
+/// as length+1+index: -1 refers to the index past the end. So to change
+/// or delete the last element use start=-2 and end=-1.
///
-/// To insert lines at a given index, set both start and end to the same index.
-/// To delete a range of lines, set replacement to an empty array.
+/// To insert lines at a given index, set `start` and `end` to the same index.
+/// To delete a range of lines, set `replacement` to an empty array.
///
/// Out-of-bounds indices are clamped to the nearest valid value, unless
/// `strict_indexing` is set.
///
-/// @param buffer The buffer handle
-/// @param start The first line index
-/// @param end The last line index (exclusive)
-/// @param strict_indexing whether out-of-bounds should be an error.
-/// @param replacement An array of lines to use as replacement
-/// @param[out] err Details of an error that may have occurred
-void buffer_set_lines(Buffer buffer,
- Integer start,
- Integer end,
- Boolean strict_indexing,
- ArrayOf(String) replacement,
- Error *err)
+/// @param buffer Buffer handle
+/// @param start First line index
+/// @param end Last line index (exclusive)
+/// @param strict_indexing Whether out-of-bounds should be an error.
+/// @param replacement Array of lines to use as replacement
+/// @param[out] err Error details, if any
+void nvim_buf_set_lines(uint64_t channel_id,
+ Buffer buffer,
+ Integer start,
+ Integer end,
+ Boolean strict_indexing,
+ ArrayOf(String) replacement, // NOLINT
+ Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -275,54 +350,58 @@ void buffer_set_lines(Buffer buffer,
end = normalize_index(buf, end, &oob);
if (strict_indexing && oob) {
- api_set_error(err, Validation, _("Index out of bounds"));
+ api_set_error(err, kErrorTypeValidation, "Index out of bounds");
return;
}
if (start > end) {
api_set_error(err,
- Validation,
- _("Argument \"start\" is higher than \"end\""));
+ kErrorTypeValidation,
+ "Argument \"start\" is higher than \"end\"");
return;
}
- buf_T *save_curbuf = NULL;
+ for (size_t i = 0; i < replacement.size; i++) {
+ if (replacement.items[i].type != kObjectTypeString) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "All items in the replacement array must be strings");
+ return;
+ }
+ // Disallow newlines in the middle of the line.
+ if (channel_id != VIML_INTERNAL_CALL) {
+ const String l = replacement.items[i].data.string;
+ if (memchr(l.data, NL, l.size)) {
+ api_set_error(err, kErrorTypeValidation,
+ "String cannot contain newlines");
+ return;
+ }
+ }
+ }
+
win_T *save_curwin = NULL;
tabpage_T *save_curtab = NULL;
size_t new_len = replacement.size;
size_t old_len = (size_t)(end - start);
- ssize_t extra = 0; // lines added to text, can be negative
+ ptrdiff_t extra = 0; // lines added to text, can be negative
char **lines = (new_len != 0) ? xcalloc(new_len, sizeof(char *)) : NULL;
for (size_t i = 0; i < new_len; i++) {
- if (replacement.items[i].type != kObjectTypeString) {
- api_set_error(err,
- Validation,
- _("All items in the replacement array must be strings"));
- goto end;
- }
+ const String l = replacement.items[i].data.string;
- String l = replacement.items[i].data.string;
-
- // Fill lines[i] with l's contents. Disallow newlines in the middle of a
- // line and convert NULs to newlines to avoid truncation.
- lines[i] = xmallocz(l.size);
- for (size_t j = 0; j < l.size; j++) {
- if (l.data[j] == '\n') {
- api_set_error(err, Exception, _("string cannot contain newlines"));
- new_len = i + 1;
- goto end;
- }
- lines[i][j] = (char) (l.data[j] == '\0' ? '\n' : l.data[j]);
- }
+ // Fill lines[i] with l's contents. Convert NULs to newlines as required by
+ // NL-used-for-NUL.
+ lines[i] = xmemdupz(l.data, l.size);
+ memchrsub(lines[i], NUL, NL, l.size);
}
try_start();
+ bufref_T save_curbuf = { NULL, 0, 0 };
switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) {
- api_set_error(err, Exception, _("Failed to save undo information"));
+ api_set_error(err, kErrorTypeException, "Failed to save undo information");
goto end;
}
@@ -332,13 +411,13 @@ void buffer_set_lines(Buffer buffer,
size_t to_delete = (new_len < old_len) ? (size_t)(old_len - new_len) : 0;
for (size_t i = 0; i < to_delete; i++) {
if (ml_delete((linenr_T)start, false) == FAIL) {
- api_set_error(err, Exception, _("Failed to delete line"));
+ api_set_error(err, kErrorTypeException, "Failed to delete line");
goto end;
}
}
- if ((ssize_t)to_delete > 0) {
- extra -= (ssize_t)to_delete;
+ if (to_delete > 0) {
+ extra -= (ptrdiff_t)to_delete;
}
// For as long as possible, replace the existing old_len with the
@@ -348,13 +427,13 @@ void buffer_set_lines(Buffer buffer,
for (size_t i = 0; i < to_replace; i++) {
int64_t lnum = start + (int64_t)i;
- if (lnum > LONG_MAX) {
- api_set_error(err, Validation, _("Index value is too high"));
+ if (lnum >= MAXLNUM) {
+ api_set_error(err, kErrorTypeValidation, "Index value is too high");
goto end;
}
if (ml_replace((linenr_T)lnum, (char_u *)lines[i], false) == FAIL) {
- api_set_error(err, Exception, _("Failed to replace line"));
+ api_set_error(err, kErrorTypeException, "Failed to replace line");
goto end;
}
// Mark lines that haven't been passed to the buffer as they need
@@ -366,13 +445,13 @@ void buffer_set_lines(Buffer buffer,
for (size_t i = to_replace; i < new_len; i++) {
int64_t lnum = start + (int64_t)i - 1;
- if (lnum > LONG_MAX) {
- api_set_error(err, Validation, _("Index value is too high"));
+ if (lnum >= MAXLNUM) {
+ api_set_error(err, kErrorTypeValidation, "Index value is too high");
goto end;
}
if (ml_append((linenr_T)lnum, (char_u *)lines[i], 0, false) == FAIL) {
- api_set_error(err, Exception, _("Failed to insert line"));
+ api_set_error(err, kErrorTypeException, "Failed to insert line");
goto end;
}
@@ -386,14 +465,18 @@ void buffer_set_lines(Buffer buffer,
// changed range, and move any in the remainder of the buffer.
// Only adjust marks if we managed to switch to a window that holds
// the buffer, otherwise line numbers will be invalid.
- if (save_curbuf == NULL) {
- mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra);
+ if (save_curbuf.br_buf == NULL) {
+ mark_adjust((linenr_T)start,
+ (linenr_T)(end - 1),
+ MAXLNUM,
+ (long)extra,
+ false);
}
- changed_lines((linenr_T)start, 0, (linenr_T)end, extra);
+ changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra, true);
- if (buf == curbuf) {
- fix_cursor((linenr_T)start, (linenr_T)end, extra);
+ if (save_curbuf.br_buf == NULL) {
+ fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra);
}
end:
@@ -402,17 +485,53 @@ end:
}
xfree(lines);
- restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
+ restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
try_end(err);
}
+/// Returns the byte offset for a line.
+///
+/// Line 1 (index=0) has offset 0. UTF-8 bytes are counted. EOL is one byte.
+/// 'fileformat' and 'fileencoding' are ignored. The line index just after the
+/// last line gives the total byte-count of the buffer. A final EOL byte is
+/// counted if it would be written, see 'eol'.
+///
+/// Unlike |line2byte()|, throws error for out-of-bounds indexing.
+/// Returns -1 for unloaded buffer.
+///
+/// @param buffer Buffer handle
+/// @param index Line index
+/// @param[out] err Error details, if any
+/// @return Integer byte offset, or -1 for unloaded buffer.
+Integer nvim_buf_get_offset(Buffer buffer, Integer index, Error *err)
+ FUNC_API_SINCE(5)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (!buf) {
+ return 0;
+ }
+
+ // return sentinel value if the buffer isn't loaded
+ if (buf->b_ml.ml_mfp == NULL) {
+ return -1;
+ }
+
+ if (index < 0 || index > buf->b_ml.ml_line_count) {
+ api_set_error(err, kErrorTypeValidation, "Index out of bounds");
+ return 0;
+ }
+
+ return ml_find_line_or_offset(buf, (int)index+1, NULL, true);
+}
+
/// Gets a buffer-scoped (b:) variable.
///
-/// @param buffer The buffer handle
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The variable value
-Object buffer_get_var(Buffer buffer, String name, Error *err)
+/// @param buffer Buffer handle
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Variable value
+Object nvim_buf_get_var(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -423,13 +542,127 @@ Object buffer_get_var(Buffer buffer, String name, Error *err)
return dict_get_value(buf->b_vars, name, err);
}
+/// Gets a changed tick of a buffer
+///
+/// @param[in] buffer Buffer handle.
+/// @param[out] err Error details, if any
+///
+/// @return `b:changedtick` value.
+Integer nvim_buf_get_changedtick(Buffer buffer, Error *err)
+ FUNC_API_SINCE(2)
+{
+ const buf_T *const buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return -1;
+ }
+
+ return buf_get_changedtick(buf);
+}
+
+/// Gets a list of buffer-local |mapping| definitions.
+///
+/// @param mode Mode short-name ("n", "i", "v", ...)
+/// @param buffer Buffer handle
+/// @param[out] err Error details, if any
+/// @returns Array of maparg()-like dictionaries describing mappings.
+/// The "buffer" key holds the associated buffer handle.
+ArrayOf(Dictionary) nvim_buf_get_keymap(Buffer buffer, String mode, Error *err)
+ FUNC_API_SINCE(3)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return (Array)ARRAY_DICT_INIT;
+ }
+
+ return keymap_array(mode, buf);
+}
+
+/// Gets a map of buffer-local |user-commands|.
+///
+/// @param buffer Buffer handle.
+/// @param opts Optional parameters. Currently not used.
+/// @param[out] err Error details, if any.
+///
+/// @returns Map of maps describing commands.
+Dictionary nvim_buf_get_commands(Buffer buffer, Dictionary opts, Error *err)
+ FUNC_API_SINCE(4)
+{
+ bool global = (buffer == -1);
+ bool builtin = false;
+
+ for (size_t i = 0; i < opts.size; i++) {
+ String k = opts.items[i].key;
+ Object v = opts.items[i].value;
+ if (!strequal("builtin", k.data)) {
+ api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
+ return (Dictionary)ARRAY_DICT_INIT;
+ }
+ if (strequal("builtin", k.data)) {
+ builtin = v.data.boolean;
+ }
+ }
+
+ if (global) {
+ if (builtin) {
+ api_set_error(err, kErrorTypeValidation, "builtin=true not implemented");
+ return (Dictionary)ARRAY_DICT_INIT;
+ }
+ return commands_array(NULL);
+ }
+
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (builtin || !buf) {
+ return (Dictionary)ARRAY_DICT_INIT;
+ }
+ return commands_array(buf);
+}
+
/// Sets a buffer-scoped (b:) variable
///
-/// @param buffer The buffer handle
-/// @param name The variable name
-/// @param value The variable value
-/// @param[out] err Details of an error that may have occurred
-/// @return The old value or nil if there was no previous value.
+/// @param buffer Buffer handle
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+void nvim_buf_set_var(Buffer buffer, String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return;
+ }
+
+ dict_set_var(buf->b_vars, name, value, false, false, err);
+}
+
+/// Removes a buffer-scoped (b:) variable
+///
+/// @param buffer Buffer handle
+/// @param name Variable name
+/// @param[out] err Error details, if any
+void nvim_buf_del_var(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+
+ if (!buf) {
+ return;
+ }
+
+ dict_set_var(buf->b_vars, name, NIL, true, false, err);
+}
+
+/// Sets a buffer-scoped (b:) variable
+///
+/// @deprecated
+///
+/// @param buffer Buffer handle
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+/// @return Old value or nil if there was no previous value.
///
/// @warning It may return nil if there was no previous value
/// or if previous value was `v:null`.
@@ -441,18 +674,17 @@ Object buffer_set_var(Buffer buffer, String name, Object value, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(buf->b_vars, name, value, false, err);
+ return dict_set_var(buf->b_vars, name, value, false, true, err);
}
/// Removes a buffer-scoped (b:) variable
///
-/// @param buffer The buffer handle
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The old value or nil if there was no previous value.
+/// @deprecated
///
-/// @warning It may return nil if there was no previous value
-/// or if previous value was `v:null`.
+/// @param buffer Buffer handle
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Old value
Object buffer_del_var(Buffer buffer, String name, Error *err)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -461,16 +693,18 @@ Object buffer_del_var(Buffer buffer, String name, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(buf->b_vars, name, NIL, true, err);
+ return dict_set_var(buf->b_vars, name, NIL, true, true, err);
}
+
/// Gets a buffer option value
///
-/// @param buffer The buffer handle
-/// @param name The option name
-/// @param[out] err Details of an error that may have occurred
-/// @return The option value
-Object buffer_get_option(Buffer buffer, String name, Error *err)
+/// @param buffer Buffer handle
+/// @param name Option name
+/// @param[out] err Error details, if any
+/// @return Option value
+Object nvim_buf_get_option(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -481,14 +715,16 @@ Object buffer_get_option(Buffer buffer, String name, Error *err)
return get_option_from(buf, SREQ_BUF, name, err);
}
-/// Sets a buffer option value. Passing 'nil' as value deletes the option(only
+/// Sets a buffer option value. Passing 'nil' as value deletes the option (only
/// works if there's a global fallback)
///
-/// @param buffer The buffer handle
-/// @param name The option name
-/// @param value The option value
-/// @param[out] err Details of an error that may have occurred
-void buffer_set_option(Buffer buffer, String name, Object value, Error *err)
+/// @param buffer Buffer handle
+/// @param name Option name
+/// @param value Option value
+/// @param[out] err Error details, if any
+void nvim_buf_set_option(uint64_t channel_id, Buffer buffer,
+ String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -496,15 +732,20 @@ void buffer_set_option(Buffer buffer, String name, Object value, Error *err)
return;
}
- set_option_to(buf, SREQ_BUF, name, value, err);
+ set_option_to(channel_id, buf, SREQ_BUF, name, value, err);
}
/// Gets the buffer number
///
-/// @param buffer The buffer handle
-/// @param[out] err Details of an error that may have occurred
-/// @return The buffer number
-Integer buffer_get_number(Buffer buffer, Error *err)
+/// @deprecated The buffer number now is equal to the object id,
+/// so there is no need to use this function.
+///
+/// @param buffer Buffer handle
+/// @param[out] err Error details, if any
+/// @return Buffer number
+Integer nvim_buf_get_number(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
+ FUNC_API_DEPRECATED_SINCE(2)
{
Integer rv = 0;
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -518,10 +759,11 @@ Integer buffer_get_number(Buffer buffer, Error *err)
/// Gets the full file name for the buffer
///
-/// @param buffer The buffer handle
-/// @param[out] err Details of an error that may have occurred
-/// @return The buffer name
-String buffer_get_name(Buffer buffer, Error *err)
+/// @param buffer Buffer handle
+/// @param[out] err Error details, if any
+/// @return Buffer name
+String nvim_buf_get_name(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
{
String rv = STRING_INIT;
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -535,10 +777,11 @@ String buffer_get_name(Buffer buffer, Error *err)
/// Sets the full file name for a buffer
///
-/// @param buffer The buffer handle
-/// @param name The buffer name
-/// @param[out] err Details of an error that may have occurred
-void buffer_set_name(Buffer buffer, String name, Error *err)
+/// @param buffer Buffer handle
+/// @param name Buffer name
+/// @param[out] err Error details, if any
+void nvim_buf_set_name(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -559,29 +802,49 @@ void buffer_set_name(Buffer buffer, String name, Error *err)
}
if (ren_ret == FAIL) {
- api_set_error(err, Exception, _("Failed to rename buffer"));
+ api_set_error(err, kErrorTypeException, "Failed to rename buffer");
}
}
-/// Checks if a buffer is valid
+/// Checks if a buffer is valid and loaded. See |api-buffer| for more info
+/// about unloaded buffers.
///
-/// @param buffer The buffer handle
-/// @return true if the buffer is valid, false otherwise
-Boolean buffer_is_valid(Buffer buffer)
+/// @param buffer Buffer handle
+/// @return true if the buffer is valid and loaded, false otherwise.
+Boolean nvim_buf_is_loaded(Buffer buffer)
+ FUNC_API_SINCE(5)
+{
+ Error stub = ERROR_INIT;
+ buf_T *buf = find_buffer_by_handle(buffer, &stub);
+ api_clear_error(&stub);
+ return buf && buf->b_ml.ml_mfp != NULL;
+}
+
+/// Checks if a buffer is valid.
+///
+/// @note Even if a buffer is valid it may have been unloaded. See |api-buffer|
+/// for more info about unloaded buffers.
+///
+/// @param buffer Buffer handle
+/// @return true if the buffer is valid, false otherwise.
+Boolean nvim_buf_is_valid(Buffer buffer)
+ FUNC_API_SINCE(1)
{
Error stub = ERROR_INIT;
- return find_buffer_by_handle(buffer, &stub) != NULL;
+ Boolean ret = find_buffer_by_handle(buffer, &stub) != NULL;
+ api_clear_error(&stub);
+ return ret;
}
/// Inserts a sequence of lines to a buffer at a certain index
///
-/// @deprecated use buffer_set_lines(buffer, lnum, lnum, true, lines)
+/// @deprecated use nvim_buf_set_lines(buffer, lnum, lnum, true, lines)
///
-/// @param buffer The buffer handle
-/// @param lnum Insert the lines after `lnum`. If negative, it will append
-/// to the end of the buffer.
-/// @param lines An array of lines
-/// @param[out] err Details of an error that may have occurred
+/// @param buffer Buffer handle
+/// @param lnum Insert the lines after `lnum`. If negative, appends to
+/// the end of the buffer.
+/// @param lines Array of lines
+/// @param[out] err Error details, if any
void buffer_insert(Buffer buffer,
Integer lnum,
ArrayOf(String) lines,
@@ -589,16 +852,17 @@ void buffer_insert(Buffer buffer,
{
// "lnum" will be the index of the line after inserting,
// no matter if it is negative or not
- buffer_set_lines(buffer, lnum, lnum, true, lines, err);
+ nvim_buf_set_lines(0, buffer, lnum, lnum, true, lines, err);
}
/// Return a tuple (row,col) representing the position of the named mark
///
-/// @param buffer The buffer handle
-/// @param name The mark's name
-/// @param[out] err Details of an error that may have occurred
-/// @return The (row, col) tuple
-ArrayOf(Integer, 2) buffer_get_mark(Buffer buffer, String name, Error *err)
+/// @param buffer Buffer handle
+/// @param name Mark name
+/// @param[out] err Error details, if any
+/// @return (row, col) tuple
+ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -608,25 +872,26 @@ ArrayOf(Integer, 2) buffer_get_mark(Buffer buffer, String name, Error *err)
}
if (name.size != 1) {
- api_set_error(err, Validation, _("Mark name must be a single character"));
+ api_set_error(err, kErrorTypeValidation,
+ "Mark name must be a single character");
return rv;
}
pos_T *posp;
- buf_T *savebuf;
char mark = *name.data;
try_start();
- switch_buffer(&savebuf, buf);
+ bufref_T save_buf;
+ switch_buffer(&save_buf, buf);
posp = getmark(mark, false);
- restore_buffer(savebuf);
+ restore_buffer(&save_buf);
if (try_end(err)) {
return rv;
}
if (posp == NULL) {
- api_set_error(err, Validation, _("Invalid mark name"));
+ api_set_error(err, kErrorTypeValidation, "Invalid mark name");
return rv;
}
@@ -638,41 +903,42 @@ ArrayOf(Integer, 2) buffer_get_mark(Buffer buffer, String name, Error *err)
/// Adds a highlight to buffer.
///
-/// This can be used for plugins which dynamically generate highlights to a
-/// buffer (like a semantic highlighter or linter). The function adds a single
-/// highlight to a buffer. Unlike matchaddpos() highlights follow changes to
+/// Useful for plugins that dynamically generate highlights to a buffer
+/// (like a semantic highlighter or linter). The function adds a single
+/// highlight to a buffer. Unlike |matchaddpos()| highlights follow changes to
/// line numbering (as lines are inserted/removed above the highlighted line),
/// like signs and marks do.
///
-/// "src_id" is useful for batch deletion/updating of a set of highlights. When
-/// called with src_id = 0, an unique source id is generated and returned.
-/// Succesive calls can pass in it as "src_id" to add new highlights to the same
-/// source group. All highlights in the same group can then be cleared with
-/// buffer_clear_highlight. If the highlight never will be manually deleted
-/// pass in -1 for "src_id".
+/// Namespaces are used for batch deletion/updating of a set of highlights. To
+/// create a namespace, use |nvim_create_namespace| which returns a namespace
+/// id. Pass it in to this function as `ns_id` to add highlights to the
+/// namespace. All highlights in the same namespace can then be cleared with
+/// single call to |nvim_buf_clear_namespace|. If the highlight never will be
+/// deleted by an API call, pass `ns_id = -1`.
///
-/// If "hl_group" is the empty string no highlight is added, but a new src_id
-/// is still returned. This is useful for an external plugin to synchrounously
-/// request an unique src_id at initialization, and later asynchronously add and
-/// clear highlights in response to buffer changes.
+/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the
+/// highlight, the allocated id is then returned. If `hl_group` is the empty
+/// string no highlight is added, but a new `ns_id` is still returned. This is
+/// supported for backwards compatibility, new code should use
+/// |nvim_create_namespace| to create a new empty namespace.
///
-/// @param buffer The buffer handle
-/// @param src_id Source group to use or 0 to use a new group,
-/// or -1 for ungrouped highlight
-/// @param hl_group Name of the highlight group to use
-/// @param line The line to highlight
-/// @param col_start Start of range of columns to highlight
-/// @param col_end End of range of columns to highlight,
-/// or -1 to highlight to end of line
-/// @param[out] err Details of an error that may have occurred
-/// @return The src_id that was used
-Integer buffer_add_highlight(Buffer buffer,
- Integer src_id,
- String hl_group,
- Integer line,
- Integer col_start,
- Integer col_end,
- Error *err)
+/// @param buffer Buffer handle
+/// @param ns_id namespace to use or -1 for ungrouped highlight
+/// @param hl_group Name of the highlight group to use
+/// @param line Line to highlight (zero-indexed)
+/// @param col_start Start of (byte-indexed) column range to highlight
+/// @param col_end End of (byte-indexed) column range to highlight,
+/// or -1 to highlight to end of line
+/// @param[out] err Error details, if any
+/// @return The ns_id that was used
+Integer nvim_buf_add_highlight(Buffer buffer,
+ Integer ns_id,
+ String hl_group,
+ Integer line,
+ Integer col_start,
+ Integer col_end,
+ Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
@@ -680,39 +946,44 @@ Integer buffer_add_highlight(Buffer buffer,
}
if (line < 0 || line >= MAXLNUM) {
- api_set_error(err, Validation, _("Line number outside range"));
+ api_set_error(err, kErrorTypeValidation, "Line number outside range");
return 0;
}
if (col_start < 0 || col_start > MAXCOL) {
- api_set_error(err, Validation, _("Column value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Column value outside range");
return 0;
}
if (col_end < 0 || col_end > MAXCOL) {
col_end = MAXCOL;
}
- int hlg_id = syn_name2id((char_u*)hl_group.data);
- src_id = bufhl_add_hl(buf, (int)src_id, hlg_id, (linenr_T)line+1,
- (colnr_T)col_start+1, (colnr_T)col_end);
- return src_id;
+ int hlg_id = 0;
+ if (hl_group.size > 0) {
+ hlg_id = syn_check_group((char_u *)hl_group.data, (int)hl_group.size);
+ }
+
+ ns_id = bufhl_add_hl(buf, (int)ns_id, hlg_id, (linenr_T)line+1,
+ (colnr_T)col_start+1, (colnr_T)col_end);
+ return ns_id;
}
-/// Clears highlights from a given source group and a range of lines
+/// Clears namespaced objects, highlights and virtual text, from a line range
///
-/// To clear a source group in the entire buffer, pass in 1 and -1 to
+/// To clear the namespace in the entire buffer, pass in 0 and -1 to
/// line_start and line_end respectively.
///
-/// @param buffer The buffer handle
-/// @param src_id Highlight source group to clear, or -1 to clear all groups.
+/// @param buffer Buffer handle
+/// @param ns_id Namespace to clear, or -1 to clear all namespaces.
/// @param line_start Start of range of lines to clear
-/// @param line_end End of range of lines to clear (exclusive)
-/// or -1 to clear to end of file.
-/// @param[out] err Details of an error that may have occurred
-void buffer_clear_highlight(Buffer buffer,
- Integer src_id,
- Integer line_start,
- Integer line_end,
- Error *err)
+/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
+/// to end of buffer.
+/// @param[out] err Error details, if any
+void nvim_buf_clear_namespace(Buffer buffer,
+ Integer ns_id,
+ Integer line_start,
+ Integer line_end,
+ Error *err)
+ FUNC_API_SINCE(5)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
@@ -720,14 +991,122 @@ void buffer_clear_highlight(Buffer buffer,
}
if (line_start < 0 || line_start >= MAXLNUM) {
- api_set_error(err, Validation, _("Line number outside range"));
+ api_set_error(err, kErrorTypeValidation, "Line number outside range");
return;
}
if (line_end < 0 || line_end > MAXLNUM) {
line_end = MAXLNUM;
}
- bufhl_clear_line_range(buf, (int)src_id, (int)line_start+1, (int)line_end);
+ bufhl_clear_line_range(buf, (int)ns_id, (int)line_start+1, (int)line_end);
+}
+
+/// Clears highlights and virtual text from namespace and range of lines
+///
+/// @deprecated use |nvim_buf_clear_namespace|.
+///
+/// @param buffer Buffer handle
+/// @param ns_id Namespace to clear, or -1 to clear all.
+/// @param line_start Start of range of lines to clear
+/// @param line_end End of range of lines to clear (exclusive) or -1 to clear
+/// to end of file.
+/// @param[out] err Error details, if any
+void nvim_buf_clear_highlight(Buffer buffer,
+ Integer ns_id,
+ Integer line_start,
+ Integer line_end,
+ Error *err)
+ FUNC_API_SINCE(1)
+{
+ nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end, err);
+}
+
+
+/// Set the virtual text (annotation) for a buffer line.
+///
+/// By default (and currently the only option) the text will be placed after
+/// the buffer text. Virtual text will never cause reflow, rather virtual
+/// text will be truncated at the end of the screen line. The virtual text will
+/// begin one cell (|lcs-eol| or space) after the ordinary text.
+///
+/// Namespaces are used to support batch deletion/updating of virtual text.
+/// To create a namespace, use |nvim_create_namespace|. Virtual text is
+/// cleared using |nvim_buf_clear_namespace|. The same `ns_id` can be used for
+/// both virtual text and highlights added by |nvim_buf_add_highlight|, both
+/// can then be cleared with a single call to |nvim_buf_clear_namespace|. If the
+/// virtual text never will be cleared by an API call, pass `ns_id = -1`.
+///
+/// As a shorthand, `ns_id = 0` can be used to create a new namespace for the
+/// virtual text, the allocated id is then returned.
+///
+/// @param buffer Buffer handle
+/// @param ns_id Namespace to use or 0 to create a namespace,
+/// or -1 for a ungrouped annotation
+/// @param line Line to annotate with virtual text (zero-indexed)
+/// @param chunks A list of [text, hl_group] arrays, each representing a
+/// text chunk with specified highlight. `hl_group` element
+/// can be omitted for no highlight.
+/// @param opts Optional parameters. Currently not used.
+/// @param[out] err Error details, if any
+/// @return The ns_id that was used
+Integer nvim_buf_set_virtual_text(Buffer buffer,
+ Integer ns_id,
+ Integer line,
+ Array chunks,
+ Dictionary opts,
+ Error *err)
+ FUNC_API_SINCE(5)
+{
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ if (!buf) {
+ return 0;
+ }
+
+ if (line < 0 || line >= MAXLNUM) {
+ api_set_error(err, kErrorTypeValidation, "Line number outside range");
+ return 0;
+ }
+
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
+ return 0;
+ }
+
+ VirtText virt_text = KV_INITIAL_VALUE;
+ for (size_t i = 0; i < chunks.size; i++) {
+ if (chunks.items[i].type != kObjectTypeArray) {
+ api_set_error(err, kErrorTypeValidation, "Chunk is not an array");
+ goto free_exit;
+ }
+ Array chunk = chunks.items[i].data.array;
+ if (chunk.size == 0 || chunk.size > 2
+ || chunk.items[0].type != kObjectTypeString
+ || (chunk.size == 2 && chunk.items[1].type != kObjectTypeString)) {
+ api_set_error(err, kErrorTypeValidation,
+ "Chunk is not an array with one or two strings");
+ goto free_exit;
+ }
+
+ String str = chunk.items[0].data.string;
+ char *text = transstr(str.size > 0 ? str.data : ""); // allocates
+
+ int hl_id = 0;
+ if (chunk.size == 2) {
+ String hl = chunk.items[1].data.string;
+ if (hl.size > 0) {
+ hl_id = syn_check_group((char_u *)hl.data, (int)hl.size);
+ }
+ }
+ kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id }));
+ }
+
+ ns_id = bufhl_add_virt_text(buf, (int)ns_id, (linenr_T)line+1,
+ virt_text);
+ return ns_id;
+
+free_exit:
+ kv_destroy(virt_text);
+ return 0;
}
// Check if deleting lines made the cursor position invalid.
diff --git a/src/nvim/api/dispatch_deprecated.lua b/src/nvim/api/dispatch_deprecated.lua
new file mode 100644
index 0000000000..5650a77ac0
--- /dev/null
+++ b/src/nvim/api/dispatch_deprecated.lua
@@ -0,0 +1,69 @@
+local deprecated_aliases = {
+ nvim_buf_add_highlight="buffer_add_highlight",
+ nvim_buf_clear_highlight="buffer_clear_highlight",
+ nvim_buf_get_lines="buffer_get_lines",
+ nvim_buf_get_mark="buffer_get_mark",
+ nvim_buf_get_name="buffer_get_name",
+ nvim_buf_get_number="buffer_get_number",
+ nvim_buf_get_option="buffer_get_option",
+ nvim_buf_get_var="buffer_get_var",
+ nvim_buf_is_valid="buffer_is_valid",
+ nvim_buf_line_count="buffer_line_count",
+ nvim_buf_set_lines="buffer_set_lines",
+ nvim_buf_set_name="buffer_set_name",
+ nvim_buf_set_option="buffer_set_option",
+ nvim_call_function="vim_call_function",
+ nvim_command="vim_command",
+ nvim_command_output="vim_command_output",
+ nvim_del_current_line="vim_del_current_line",
+ nvim_err_write="vim_err_write",
+ nvim_err_writeln="vim_report_error",
+ nvim_eval="vim_eval",
+ nvim_feedkeys="vim_feedkeys",
+ nvim_get_api_info="vim_get_api_info",
+ nvim_get_color_by_name="vim_name_to_color",
+ nvim_get_color_map="vim_get_color_map",
+ nvim_get_current_buf="vim_get_current_buffer",
+ nvim_get_current_line="vim_get_current_line",
+ nvim_get_current_tabpage="vim_get_current_tabpage",
+ nvim_get_current_win="vim_get_current_window",
+ nvim_get_option="vim_get_option",
+ nvim_get_var="vim_get_var",
+ nvim_get_vvar="vim_get_vvar",
+ nvim_input="vim_input",
+ nvim_list_bufs="vim_get_buffers",
+ nvim_list_runtime_paths="vim_list_runtime_paths",
+ nvim_list_tabpages="vim_get_tabpages",
+ nvim_list_wins="vim_get_windows",
+ nvim_out_write="vim_out_write",
+ nvim_replace_termcodes="vim_replace_termcodes",
+ nvim_set_current_buf="vim_set_current_buffer",
+ nvim_set_current_dir="vim_change_directory",
+ nvim_set_current_line="vim_set_current_line",
+ nvim_set_current_tabpage="vim_set_current_tabpage",
+ nvim_set_current_win="vim_set_current_window",
+ nvim_set_option="vim_set_option",
+ nvim_strwidth="vim_strwidth",
+ nvim_subscribe="vim_subscribe",
+ nvim_tabpage_get_var="tabpage_get_var",
+ nvim_tabpage_get_win="tabpage_get_window",
+ nvim_tabpage_is_valid="tabpage_is_valid",
+ nvim_tabpage_list_wins="tabpage_get_windows",
+ nvim_ui_detach="ui_detach",
+ nvim_ui_try_resize="ui_try_resize",
+ nvim_unsubscribe="vim_unsubscribe",
+ nvim_win_get_buf="window_get_buffer",
+ nvim_win_get_cursor="window_get_cursor",
+ nvim_win_get_height="window_get_height",
+ nvim_win_get_option="window_get_option",
+ nvim_win_get_position="window_get_position",
+ nvim_win_get_tabpage="window_get_tabpage",
+ nvim_win_get_var="window_get_var",
+ nvim_win_get_width="window_get_width",
+ nvim_win_is_valid="window_is_valid",
+ nvim_win_set_cursor="window_set_cursor",
+ nvim_win_set_height="window_set_height",
+ nvim_win_set_option="window_set_option",
+ nvim_win_set_width="window_set_width",
+}
+return deprecated_aliases
diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h
index 5fb95a163f..feca140547 100644
--- a/src/nvim/api/private/defs.h
+++ b/src/nvim/api/private/defs.h
@@ -5,11 +5,16 @@
#include <stdbool.h>
#include <string.h>
+#include "nvim/func_attr.h"
+#include "nvim/types.h"
+
#define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL}
#define STRING_INIT {.data = NULL, .size = 0}
#define OBJECT_INIT { .type = kObjectTypeNil }
-#define ERROR_INIT { .set = false }
-#define REMOTE_TYPE(type) typedef uint64_t type
+#define ERROR_INIT { .type = kErrorTypeNone, .msg = NULL }
+#define REMOTE_TYPE(type) typedef handle_T type
+
+#define ERROR_SET(e) ((e)->type != kErrorTypeNone)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# define ArrayOf(...) Array
@@ -18,6 +23,7 @@
// Basic types
typedef enum {
+ kErrorTypeNone = -1,
kErrorTypeException,
kErrorTypeValidation
} ErrorType;
@@ -31,10 +37,31 @@ typedef enum {
/// Used as the message ID of notifications.
#define NO_RESPONSE UINT64_MAX
+/// Mask for all internal calls
+#define INTERNAL_CALL_MASK (((uint64_t)1) << (sizeof(uint64_t) * 8 - 1))
+
+/// Internal call from VimL code
+#define VIML_INTERNAL_CALL INTERNAL_CALL_MASK
+
+/// Internal call from lua code
+#define LUA_INTERNAL_CALL (VIML_INTERNAL_CALL + 1)
+
+static inline bool is_internal_call(const uint64_t channel_id)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST;
+
+/// Check whether call is internal
+///
+/// @param[in] channel_id Channel id.
+///
+/// @return true if channel_id refers to internal channel.
+static inline bool is_internal_call(const uint64_t channel_id)
+{
+ return !!(channel_id & INTERNAL_CALL_MASK);
+}
+
typedef struct {
ErrorType type;
- char msg[1024];
- bool set;
+ char *msg;
} Error;
typedef bool Boolean;
@@ -71,24 +98,22 @@ typedef struct {
} Dictionary;
typedef enum {
- kObjectTypeBuffer,
- kObjectTypeWindow,
- kObjectTypeTabpage,
- kObjectTypeNil,
+ kObjectTypeNil = 0,
kObjectTypeBoolean,
kObjectTypeInteger,
kObjectTypeFloat,
kObjectTypeString,
kObjectTypeArray,
kObjectTypeDictionary,
+ // EXT types, cannot be split or reordered, see #EXT_OBJECT_TYPE_SHIFT
+ kObjectTypeBuffer,
+ kObjectTypeWindow,
+ kObjectTypeTabpage,
} ObjectType;
struct object {
ObjectType type;
union {
- Buffer buffer;
- Window window;
- Tabpage tabpage;
Boolean boolean;
Integer integer;
Float floating;
diff --git a/src/nvim/api/private/dispatch.c b/src/nvim/api/private/dispatch.c
new file mode 100644
index 0000000000..8492225a69
--- /dev/null
+++ b/src/nvim/api/private/dispatch.c
@@ -0,0 +1,52 @@
+// 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 <inttypes.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <assert.h>
+#include <msgpack.h>
+
+#include "nvim/map.h"
+#include "nvim/log.h"
+#include "nvim/vim.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/api/private/dispatch.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/private/defs.h"
+
+#include "nvim/api/buffer.h"
+#include "nvim/api/tabpage.h"
+#include "nvim/api/ui.h"
+#include "nvim/api/vim.h"
+#include "nvim/api/window.h"
+
+static Map(String, MsgpackRpcRequestHandler) *methods = NULL;
+
+static void msgpack_rpc_add_method_handler(String method,
+ MsgpackRpcRequestHandler handler)
+{
+ map_put(String, MsgpackRpcRequestHandler)(methods, method, handler);
+}
+
+/// @param name API method name
+/// @param name_len name size (includes terminating NUL)
+MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
+ size_t name_len,
+ Error *error)
+{
+ String m = { .data = (char *)name, .size = name_len };
+ MsgpackRpcRequestHandler rv =
+ map_get(String, MsgpackRpcRequestHandler)(methods, m);
+
+ if (!rv.fn) {
+ api_set_error(error, kErrorTypeException, "Invalid method: %.*s",
+ m.size > 0 ? (int)m.size : (int)sizeof("<empty>"),
+ m.size > 0 ? m.data : "<empty>");
+ }
+ return rv;
+}
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+#include "api/private/dispatch_wrappers.generated.h"
+#endif
diff --git a/src/nvim/api/private/dispatch.h b/src/nvim/api/private/dispatch.h
new file mode 100644
index 0000000000..39aabd708a
--- /dev/null
+++ b/src/nvim/api/private/dispatch.h
@@ -0,0 +1,23 @@
+#ifndef NVIM_API_PRIVATE_DISPATCH_H
+#define NVIM_API_PRIVATE_DISPATCH_H
+
+#include "nvim/api/private/defs.h"
+
+typedef Object (*ApiDispatchWrapper)(uint64_t channel_id,
+ Array args,
+ Error *error);
+
+/// The rpc_method_handlers table, used in msgpack_rpc_dispatch(), stores
+/// functions of this type.
+typedef struct {
+ ApiDispatchWrapper fn;
+ bool async; // function is always safe to run immediately instead of being
+ // put in a request queue for handling when nvim waits for input.
+} MsgpackRpcRequestHandler;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "api/private/dispatch.h.generated.h"
+# include "api/private/dispatch_wrappers.h.generated.h"
+#endif
+
+#endif // NVIM_API_PRIVATE_DISPATCH_H
diff --git a/src/nvim/api/private/handle.c b/src/nvim/api/private/handle.c
index 69df7294ad..eb96192af2 100644
--- a/src/nvim/api/private/handle.c
+++ b/src/nvim/api/private/handle.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 <stdint.h>
@@ -5,30 +8,26 @@
#include "nvim/map.h"
#include "nvim/api/private/handle.h"
-#define HANDLE_INIT(name) name##_handles = pmap_new(uint64_t)()
+#define HANDLE_INIT(name) name##_handles = pmap_new(handle_T)()
#define HANDLE_IMPL(type, name) \
- static PMap(uint64_t) *name##_handles = NULL; \
+ static PMap(handle_T) *name##_handles = NULL; /* NOLINT */ \
\
- type *handle_get_##name(uint64_t handle) \
+ type *handle_get_##name(handle_T handle) \
{ \
- return pmap_get(uint64_t)(name##_handles, handle); \
+ return pmap_get(handle_T)(name##_handles, handle); \
} \
\
void handle_register_##name(type *name) \
{ \
- assert(!name->handle); \
- name->handle = next_handle++; \
- pmap_put(uint64_t)(name##_handles, name->handle, name); \
+ pmap_put(handle_T)(name##_handles, name->handle, name); \
} \
\
void handle_unregister_##name(type *name) \
{ \
- pmap_del(uint64_t)(name##_handles, name->handle); \
+ pmap_del(handle_T)(name##_handles, name->handle); \
}
-static uint64_t next_handle = 1;
-
HANDLE_IMPL(buf_T, buffer)
HANDLE_IMPL(win_T, window)
HANDLE_IMPL(tabpage_T, tabpage)
diff --git a/src/nvim/api/private/handle.h b/src/nvim/api/private/handle.h
index 804e266dc3..26e9dc3314 100644
--- a/src/nvim/api/private/handle.h
+++ b/src/nvim/api/private/handle.h
@@ -3,14 +3,18 @@
#include "nvim/vim.h"
#include "nvim/buffer_defs.h"
+#include "nvim/api/private/defs.h"
#define HANDLE_DECLS(type, name) \
- type *handle_get_##name(uint64_t handle); \
+ type *handle_get_##name(handle_T handle); \
void handle_register_##name(type *name); \
void handle_unregister_##name(type *name);
+// handle_get_buffer handle_register_buffer, handle_unregister_buffer
HANDLE_DECLS(buf_T, buffer)
+// handle_get_window handle_register_window, handle_unregister_window
HANDLE_DECLS(win_T, window)
+// handle_get_tabpage handle_register_tabpage, handle_unregister_tabpage
HANDLE_DECLS(tabpage_T, tabpage)
void handle_init(void);
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index c88bf2127a..82c9a1da67 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.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 <inttypes.h>
#include <stdbool.h>
@@ -7,18 +10,24 @@
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/handle.h"
+#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/ascii.h"
+#include "nvim/assert.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
#include "nvim/window.h"
+#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/map_defs.h"
#include "nvim/map.h"
#include "nvim/option.h"
#include "nvim/option_defs.h"
-#include "nvim/eval/typval_encode.h"
+#include "nvim/version.h"
#include "nvim/lib/kvec.h"
+#include "nvim/getchar.h"
+#include "nvim/ui.h"
/// Helper structure for vim_to_object
typedef struct {
@@ -27,9 +36,75 @@ typedef struct {
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/private/helpers.c.generated.h"
+# include "api/private/funcs_metadata.generated.h"
+# include "api/private/ui_events_metadata.generated.h"
#endif
+/// Start block that may cause VimL exceptions while evaluating another code
+///
+/// Used when caller is supposed to be operating when other VimL code is being
+/// processed and that “other VimL code†must not be affected.
+///
+/// @param[out] tstate Location where try state should be saved.
+void try_enter(TryState *const tstate)
+{
+ // TODO(ZyX-I): Check whether try_enter()/try_leave() may use
+ // enter_cleanup()/leave_cleanup(). Or
+ // save_dbg_stuff()/restore_dbg_stuff().
+ *tstate = (TryState) {
+ .current_exception = current_exception,
+ .msg_list = (const struct msglist *const *)msg_list,
+ .private_msg_list = NULL,
+ .trylevel = trylevel,
+ .got_int = got_int,
+ .need_rethrow = need_rethrow,
+ .did_emsg = did_emsg,
+ };
+ msg_list = &tstate->private_msg_list;
+ current_exception = NULL;
+ trylevel = 1;
+ got_int = false;
+ need_rethrow = false;
+ did_emsg = false;
+}
+
+/// End try block, set the error message if any and restore previous state
+///
+/// @warning Return is consistent with most functions (false on error), not with
+/// try_end (true on error).
+///
+/// @param[in] tstate Previous state to restore.
+/// @param[out] err Location where error should be saved.
+///
+/// @return false if error occurred, true otherwise.
+bool try_leave(const TryState *const tstate, Error *const err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const bool ret = !try_end(err);
+ assert(trylevel == 0);
+ assert(!need_rethrow);
+ assert(!got_int);
+ assert(!did_emsg);
+ assert(msg_list == &tstate->private_msg_list);
+ assert(*msg_list == NULL);
+ assert(current_exception == NULL);
+ msg_list = (struct msglist **)tstate->msg_list;
+ current_exception = tstate->current_exception;
+ trylevel = tstate->trylevel;
+ got_int = tstate->got_int;
+ need_rethrow = tstate->need_rethrow;
+ did_emsg = tstate->did_emsg;
+ return ret;
+}
+
/// Start block that may cause vimscript exceptions
+///
+/// Each try_start() call should be mirrored by try_end() call.
+///
+/// To be used as a replacement of `:try … catch … endtry` in C code, in cases
+/// when error flag could not already be set. If there may be pending error
+/// state at the time try_start() is executed which needs to be preserved,
+/// try_enter()/try_leave() pair should be used instead.
void try_start(void)
{
++trylevel;
@@ -42,20 +117,20 @@ void try_start(void)
/// @return true if an error occurred
bool try_end(Error *err)
{
- --trylevel;
+ // Note: all globals manipulated here should be saved/restored in
+ // try_enter/try_leave.
+ trylevel--;
- // Without this it stops processing all subsequent VimL commands and
- // generates strange error messages if I e.g. try calling Test() in a
- // cycle
+ // Set by emsg(), affects aborting(). See also enter_cleanup().
did_emsg = false;
if (got_int) {
- if (did_throw) {
+ if (current_exception) {
// If we got an interrupt, discard the current exception
discard_current_exception();
}
- api_set_error(err, Exception, _("Keyboard interrupt"));
+ api_set_error(err, kErrorTypeException, "Keyboard interrupt");
got_int = false;
} else if (msg_list != NULL && *msg_list != NULL) {
int should_free;
@@ -63,19 +138,18 @@ bool try_end(Error *err)
ET_ERROR,
NULL,
&should_free);
- xstrlcpy(err->msg, msg, sizeof(err->msg));
- err->set = true;
+ api_set_error(err, kErrorTypeException, "%s", msg);
free_global_msglist();
if (should_free) {
xfree(msg);
}
- } else if (did_throw) {
- api_set_error(err, Exception, "%s", current_exception->value);
+ } else if (current_exception) {
+ api_set_error(err, kErrorTypeException, "%s", current_exception->value);
discard_current_exception();
}
- return err->set;
+ return ERROR_SET(err);
}
/// Recursively expands a vimscript value in a dict
@@ -85,18 +159,17 @@ bool try_end(Error *err)
/// @param[out] err Details of an error that may have occurred
Object dict_get_value(dict_T *dict, String key, Error *err)
{
- hashitem_T *hi = hash_find(&dict->dv_hashtab, (uint8_t *) key.data);
+ dictitem_T *const di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size);
- if (HASHITEM_EMPTY(hi)) {
- api_set_error(err, Validation, _("Key not found"));
- return (Object) OBJECT_INIT;
+ if (di == NULL) {
+ api_set_error(err, kErrorTypeValidation, "Key not found: %s", key.data);
+ return (Object)OBJECT_INIT;
}
- dictitem_T *di = dict_lookup(hi);
return vim_to_object(&di->di_tv);
}
-/// Set a value in a dict. Objects are recursively expanded into their
+/// Set a value in a scope dict. Objects are recursively expanded into their
/// vimscript equivalents.
///
/// @param dict The vimscript dict
@@ -104,42 +177,50 @@ Object dict_get_value(dict_T *dict, String key, Error *err)
/// @param value The new value
/// @param del Delete key in place of setting it. Argument `value` is ignored in
/// this case.
+/// @param retval If true the old value will be converted and returned.
/// @param[out] err Details of an error that may have occurred
-/// @return the old value, if any
-Object dict_set_value(dict_T *dict, String key, Object value, bool del,
- Error *err)
+/// @return The old value if `retval` is true and the key was present, else NIL
+Object dict_set_var(dict_T *dict, String key, Object value, bool del,
+ bool retval, Error *err)
{
Object rv = OBJECT_INIT;
+ dictitem_T *di = tv_dict_find(dict, key.data, (ptrdiff_t)key.size);
- if (dict->dv_lock) {
- api_set_error(err, Exception, _("Dictionary is locked"));
+ if (di != NULL) {
+ if (di->di_flags & DI_FLAGS_RO) {
+ api_set_error(err, kErrorTypeException, "Key is read-only: %s", key.data);
+ return rv;
+ } else if (di->di_flags & DI_FLAGS_LOCK) {
+ api_set_error(err, kErrorTypeException, "Key is locked: %s", key.data);
+ return rv;
+ } else if (del && (di->di_flags & DI_FLAGS_FIX)) {
+ api_set_error(err, kErrorTypeException, "Key is fixed: %s", key.data);
+ return rv;
+ }
+ } else if (dict->dv_lock) {
+ api_set_error(err, kErrorTypeException, "Dictionary is locked");
return rv;
- }
-
- if (key.size == 0) {
- api_set_error(err, Validation, _("Empty dictionary keys aren't allowed"));
+ } else if (key.size == 0) {
+ api_set_error(err, kErrorTypeValidation, "Key name is empty");
return rv;
- }
-
- if (key.size > INT_MAX) {
- api_set_error(err, Validation, _("Key length is too high"));
+ } else if (key.size > INT_MAX) {
+ api_set_error(err, kErrorTypeValidation, "Key name is too long");
return rv;
}
- dictitem_T *di = dict_find(dict, (uint8_t *)key.data, (int)key.size);
-
if (del) {
// Delete the key
if (di == NULL) {
// Doesn't exist, fail
- api_set_error(err, Validation, _("Key \"%s\" doesn't exist"), key.data);
+ api_set_error(err, kErrorTypeValidation, "Key not found: %s",
+ key.data);
} else {
// Return the old value
- rv = vim_to_object(&di->di_tv);
+ if (retval) {
+ rv = vim_to_object(&di->di_tv);
+ }
// Delete the entry
- hashitem_T *hi = hash_find(&dict->dv_hashtab, di->di_key);
- hash_remove(&dict->dv_hashtab, hi);
- dictitem_free(di);
+ tv_dict_item_remove(dict, di);
}
} else {
// Update the key
@@ -152,18 +233,20 @@ Object dict_set_value(dict_T *dict, String key, Object value, bool del,
if (di == NULL) {
// Need to create an entry
- di = dictitem_alloc((uint8_t *) key.data);
- dict_add(dict, di);
+ di = tv_dict_item_alloc_len(key.data, key.size);
+ tv_dict_add(dict, di);
} else {
// Return the old value
- rv = vim_to_object(&di->di_tv);
- clear_tv(&di->di_tv);
+ if (retval) {
+ rv = vim_to_object(&di->di_tv);
+ }
+ tv_clear(&di->di_tv);
}
// Update the value
- copy_tv(&tv, &di->di_tv);
+ tv_copy(&tv, &di->di_tv);
// Clear the temporary variable
- clear_tv(&tv);
+ tv_clear(&tv);
}
return rv;
@@ -182,7 +265,7 @@ Object get_option_from(void *from, int type, String name, Error *err)
Object rv = OBJECT_INIT;
if (name.size == 0) {
- api_set_error(err, Validation, _("Empty option name"));
+ api_set_error(err, kErrorTypeValidation, "Empty option name");
return rv;
}
@@ -193,9 +276,7 @@ Object get_option_from(void *from, int type, String name, Error *err)
type, from);
if (!flags) {
- api_set_error(err,
- Validation,
- _("Invalid option name \"%s\""),
+ api_set_error(err, kErrorTypeValidation, "Invalid option name: '%s'",
name.data);
return rv;
}
@@ -212,15 +293,14 @@ Object get_option_from(void *from, int type, String name, Error *err)
rv.data.string.data = stringval;
rv.data.string.size = strlen(stringval);
} else {
- api_set_error(err,
- Exception,
- _("Unable to get value for option \"%s\""),
+ api_set_error(err, kErrorTypeException,
+ "Failed to get value for option '%s'",
name.data);
}
} else {
api_set_error(err,
- Exception,
- _("Unknown type for option \"%s\""),
+ kErrorTypeException,
+ "Unknown type for option '%s'",
name.data);
}
@@ -234,35 +314,32 @@ Object get_option_from(void *from, int type, String name, Error *err)
/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF`
/// @param name The option name
/// @param[out] err Details of an error that may have occurred
-void set_option_to(void *to, int type, String name, Object value, Error *err)
+void set_option_to(uint64_t channel_id, void *to, int type,
+ String name, Object value, Error *err)
{
if (name.size == 0) {
- api_set_error(err, Validation, _("Empty option name"));
+ api_set_error(err, kErrorTypeValidation, "Empty option name");
return;
}
int flags = get_option_value_strict(name.data, NULL, NULL, type, to);
if (flags == 0) {
- api_set_error(err,
- Validation,
- _("Invalid option name \"%s\""),
+ api_set_error(err, kErrorTypeValidation, "Invalid option name '%s'",
name.data);
return;
}
if (value.type == kObjectTypeNil) {
if (type == SREQ_GLOBAL) {
- api_set_error(err,
- Exception,
- _("Unable to unset option \"%s\""),
+ api_set_error(err, kErrorTypeException, "Cannot unset option '%s'",
name.data);
return;
} else if (!(flags & SOPT_GLOBAL)) {
api_set_error(err,
- Exception,
- _("Cannot unset option \"%s\" "
- "because it doesn't have a global value"),
+ kErrorTypeException,
+ "Cannot unset option '%s' "
+ "because it doesn't have a global value",
name.data);
return;
} else {
@@ -271,69 +348,74 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
}
}
- int opt_flags = (type ? OPT_LOCAL : OPT_GLOBAL);
+ int numval = 0;
+ char *stringval = NULL;
if (flags & SOPT_BOOL) {
if (value.type != kObjectTypeBoolean) {
api_set_error(err,
- Validation,
- _("Option \"%s\" requires a boolean value"),
+ kErrorTypeValidation,
+ "Option '%s' requires a Boolean value",
name.data);
return;
}
- bool val = value.data.boolean;
- set_option_value_for(name.data, val, NULL, opt_flags, type, to, err);
+ numval = value.data.boolean;
} else if (flags & SOPT_NUM) {
if (value.type != kObjectTypeInteger) {
- api_set_error(err,
- Validation,
- _("Option \"%s\" requires an integer value"),
+ api_set_error(err, kErrorTypeValidation,
+ "Option '%s' requires an integer value",
name.data);
return;
}
if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) {
- api_set_error(err,
- Validation,
- _("Value for option \"%s\" is outside range"),
+ api_set_error(err, kErrorTypeValidation,
+ "Value for option '%s' is out of range",
name.data);
return;
}
- int val = (int) value.data.integer;
- set_option_value_for(name.data, val, NULL, opt_flags, type, to, err);
+ numval = (int)value.data.integer;
} else {
if (value.type != kObjectTypeString) {
- api_set_error(err,
- Validation,
- _("Option \"%s\" requires a string value"),
+ api_set_error(err, kErrorTypeValidation,
+ "Option '%s' requires a string value",
name.data);
return;
}
- set_option_value_for(name.data, 0, value.data.string.data,
- opt_flags, type, to, err);
+ stringval = (char *)value.data.string.data;
}
+
+ const scid_T save_current_SID = current_SID;
+ current_SID = channel_id == LUA_INTERNAL_CALL ? SID_LUA : SID_API_CLIENT;
+ current_channel_id = channel_id;
+
+ const int opt_flags = (type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL;
+ set_option_value_for(name.data, numval, stringval,
+ opt_flags, type, to, err);
+
+ current_SID = save_current_SID;
}
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
-#define TYPVAL_ENCODE_CONV_NIL() \
+#define TYPVAL_ENCODE_CONV_NIL(tv) \
kv_push(edata->stack, NIL)
-#define TYPVAL_ENCODE_CONV_BOOL(num) \
+#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
kv_push(edata->stack, BOOLEAN_OBJ((Boolean)(num)))
-#define TYPVAL_ENCODE_CONV_NUMBER(num) \
+#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
kv_push(edata->stack, INTEGER_OBJ((Integer)(num)))
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
-#define TYPVAL_ENCODE_CONV_FLOAT(flt) \
- kv_push(edata->stack, FLOATING_OBJ((Float)(flt)))
+#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
+ kv_push(edata->stack, FLOAT_OBJ((Float)(flt)))
-#define TYPVAL_ENCODE_CONV_STRING(str, len) \
+#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
do { \
const size_t len_ = (size_t)(len); \
const char *const str_ = (const char *)(str); \
@@ -346,16 +428,23 @@ void set_option_to(void *to, int type, String name, Object value, Error *err)
#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
-#define TYPVAL_ENCODE_CONV_EXT_STRING(str, len, type) \
- TYPVAL_ENCODE_CONV_NIL()
+#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
+ TYPVAL_ENCODE_CONV_NIL(tv)
+
+#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
+ do { \
+ TYPVAL_ENCODE_CONV_NIL(tv); \
+ goto typval_encode_stop_converting_one_item; \
+ } while (0)
-#define TYPVAL_ENCODE_CONV_FUNC(fun) \
- TYPVAL_ENCODE_CONV_NIL()
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
-#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
+#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
kv_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
-#define TYPVAL_ENCODE_CONV_EMPTY_DICT() \
+#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
kv_push(edata->stack, \
DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
@@ -363,17 +452,18 @@ static inline void typval_encode_list_start(EncodedData *const edata,
const size_t len)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
- const Object obj = OBJECT_INIT;
kv_push(edata->stack, ARRAY_OBJ(((Array) {
.capacity = len,
.size = 0,
- .items = xmalloc(len * sizeof(*obj.data.array.items)),
+ .items = xmalloc(len * sizeof(*((Object)OBJECT_INIT).data.array.items)),
})));
}
-#define TYPVAL_ENCODE_CONV_LIST_START(len) \
+#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
typval_encode_list_start(edata, (size_t)(len))
+#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
+
static inline void typval_encode_between_list_items(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
@@ -384,7 +474,7 @@ static inline void typval_encode_between_list_items(EncodedData *const edata)
list->data.array.items[list->data.array.size++] = item;
}
-#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS() \
+#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
typval_encode_between_list_items(edata)
static inline void typval_encode_list_end(EncodedData *const edata)
@@ -397,25 +487,27 @@ static inline void typval_encode_list_end(EncodedData *const edata)
#endif
}
-#define TYPVAL_ENCODE_CONV_LIST_END() \
+#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
typval_encode_list_end(edata)
static inline void typval_encode_dict_start(EncodedData *const edata,
const size_t len)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
- const Object obj = OBJECT_INIT;
kv_push(edata->stack, DICTIONARY_OBJ(((Dictionary) {
.capacity = len,
.size = 0,
- .items = xmalloc(len * sizeof(*obj.data.dictionary.items)),
+ .items = xmalloc(len * sizeof(
+ *((Object)OBJECT_INIT).data.dictionary.items)),
})));
}
-#define TYPVAL_ENCODE_CONV_DICT_START(len) \
+#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
typval_encode_dict_start(edata, (size_t)(len))
-#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(label, kv_pair)
+#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
+
+#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, kv_pair)
static inline void typval_encode_after_key(EncodedData *const edata)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -434,7 +526,7 @@ static inline void typval_encode_after_key(EncodedData *const edata)
}
}
-#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY() \
+#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
typval_encode_after_key(edata)
static inline void typval_encode_between_dict_items(EncodedData *const edata)
@@ -447,7 +539,7 @@ static inline void typval_encode_between_dict_items(EncodedData *const edata)
dict->data.dictionary.items[dict->data.dictionary.size++].value = val;
}
-#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS() \
+#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
typval_encode_between_dict_items(edata)
static inline void typval_encode_dict_end(EncodedData *const edata)
@@ -460,31 +552,44 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
#endif
}
-#define TYPVAL_ENCODE_CONV_DICT_END() \
+#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
typval_encode_dict_end(edata)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- TYPVAL_ENCODE_CONV_NIL()
-
-TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, object, EncodedData *const, edata)
+ TYPVAL_ENCODE_CONV_NIL(val)
+
+#define TYPVAL_ENCODE_SCOPE static
+#define TYPVAL_ENCODE_NAME object
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE EncodedData *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME edata
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
#undef TYPVAL_ENCODE_CONV_NUMBER
#undef TYPVAL_ENCODE_CONV_FLOAT
-#undef TYPVAL_ENCODE_CONV_FUNC
+#undef TYPVAL_ENCODE_CONV_FUNC_START
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
+#undef TYPVAL_ENCODE_CONV_FUNC_END
#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
#undef TYPVAL_ENCODE_CONV_LIST_START
+#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
#undef TYPVAL_ENCODE_CONV_DICT_START
+#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
#undef TYPVAL_ENCODE_CONV_DICT_END
#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
+#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_CONV_LIST_END
#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_RECURSE
@@ -498,7 +603,10 @@ TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, object, EncodedData *const, edata)
Object vim_to_object(typval_T *obj)
{
EncodedData edata = { .stack = KV_INITIAL_VALUE };
- encode_vim_to_object(&edata, obj, "vim_to_object argument");
+ const int evo_ret = encode_vim_to_object(&edata, obj,
+ "vim_to_object argument");
+ (void)evo_ret;
+ assert(evo_ret == OK);
Object ret = kv_A(edata.stack, 0);
assert(kv_size(edata.stack) == 1);
kv_destroy(edata.stack);
@@ -507,37 +615,65 @@ Object vim_to_object(typval_T *obj)
buf_T *find_buffer_by_handle(Buffer buffer, Error *err)
{
+ if (buffer == 0) {
+ return curbuf;
+ }
+
buf_T *rv = handle_get_buffer(buffer);
if (!rv) {
- api_set_error(err, Validation, _("Invalid buffer id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid buffer id");
}
return rv;
}
-win_T * find_window_by_handle(Window window, Error *err)
+win_T *find_window_by_handle(Window window, Error *err)
{
+ if (window == 0) {
+ return curwin;
+ }
+
win_T *rv = handle_get_window(window);
if (!rv) {
- api_set_error(err, Validation, _("Invalid window id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid window id");
}
return rv;
}
-tabpage_T * find_tab_by_handle(Tabpage tabpage, Error *err)
+tabpage_T *find_tab_by_handle(Tabpage tabpage, Error *err)
{
+ if (tabpage == 0) {
+ return curtab;
+ }
+
tabpage_T *rv = handle_get_tabpage(tabpage);
if (!rv) {
- api_set_error(err, Validation, _("Invalid tabpage id"));
+ api_set_error(err, kErrorTypeValidation, "Invalid tabpage id");
}
return rv;
}
+/// Allocates a String consisting of a single char. Does not support multibyte
+/// characters. The resulting string is also NUL-terminated, to facilitate
+/// interoperating with code using C strings.
+///
+/// @param char the char to convert
+/// @return the resulting String, if the input char was NUL, an
+/// empty String is returned
+String cchar_to_string(char c)
+{
+ char buf[] = { c, NUL };
+ return (String){
+ .data = xmemdupz(buf, 1),
+ .size = (c != NUL) ? 1 : 0
+ };
+}
+
/// Copies a C string into a String (binary safe string, characters + length).
/// The resulting string is also NUL-terminated, to facilitate interoperating
/// with code using C strings.
@@ -548,16 +684,33 @@ tabpage_T * find_tab_by_handle(Tabpage tabpage, Error *err)
String cstr_to_string(const char *str)
{
if (str == NULL) {
- return (String) STRING_INIT;
+ return (String)STRING_INIT;
}
size_t len = strlen(str);
- return (String) {
- .data = xmemdupz(str, len),
- .size = len
+ return (String){
+ .data = xmemdupz(str, len),
+ .size = len,
};
}
+/// Copies buffer to an allocated String.
+/// The resulting string is also NUL-terminated, to facilitate interoperating
+/// with code using C strings.
+///
+/// @param buf the buffer to copy
+/// @param size length of the buffer
+/// @return the resulting String, if the input string was NULL, an
+/// empty String is returned
+String cbuf_to_string(const char *buf, size_t size)
+ FUNC_ATTR_NONNULL_ALL
+{
+ return (String){
+ .data = xmemdupz(buf, size),
+ .size = size
+ };
+}
+
/// Creates a String using the given C string. Unlike
/// cstr_to_string this function DOES NOT copy the C string.
///
@@ -567,15 +720,58 @@ String cstr_to_string(const char *str)
String cstr_as_string(char *str) FUNC_ATTR_PURE
{
if (str == NULL) {
- return (String) STRING_INIT;
+ return (String)STRING_INIT;
}
- return (String) {.data = str, .size = strlen(str)};
+ return (String){ .data = str, .size = strlen(str) };
}
+/// Collects `n` buffer lines into array `l`, optionally replacing newlines
+/// with NUL.
+///
+/// @param buf Buffer to get lines from
+/// @param n Number of lines to collect
+/// @param replace_nl Replace newlines ("\n") with NUL
+/// @param start Line number to start from
+/// @param[out] l Lines are copied here
+/// @param err[out] Error, if any
+/// @return true unless `err` was set
+bool buf_collect_lines(buf_T *buf, size_t n, int64_t start, bool replace_nl,
+ Array *l, Error *err)
+{
+ for (size_t i = 0; i < n; i++) {
+ int64_t lnum = start + (int64_t)i;
+
+ if (lnum >= MAXLNUM) {
+ if (err != NULL) {
+ api_set_error(err, kErrorTypeValidation, "Line index is too high");
+ }
+ return false;
+ }
+
+ const char *bufstr = (char *)ml_get_buf(buf, (linenr_T)lnum, false);
+ Object str = STRING_OBJ(cstr_to_string(bufstr));
+
+ if (replace_nl) {
+ // Vim represents NULs as NLs, but this may confuse clients.
+ strchrsub(str.data.string.data, '\n', '\0');
+ }
+
+ l->items[i] = str;
+ }
+
+ return true;
+}
+
+/// Converts from type Object to a VimL value.
+///
+/// @param obj Object to convert from.
+/// @param tv Conversion result is placed here. On failure member v_type is
+/// set to VAR_UNKNOWN (no allocation was made for this variable).
+/// returns true if conversion is successful, otherwise false.
bool object_to_vim(Object obj, typval_T *tv, Error *err)
{
tv->v_type = VAR_UNKNOWN;
- tv->v_lock = 0;
+ tv->v_lock = VAR_UNLOCKED;
switch (obj.type) {
case kObjectTypeNil:
@@ -592,13 +788,10 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
case kObjectTypeWindow:
case kObjectTypeTabpage:
case kObjectTypeInteger:
- if (obj.data.integer > INT_MAX || obj.data.integer < INT_MIN) {
- api_set_error(err, Validation, _("Integer value outside range"));
- return false;
- }
-
+ STATIC_ASSERT(sizeof(obj.data.integer) <= sizeof(varnumber_T),
+ "Integer size must be <= VimL number size");
tv->v_type = VAR_NUMBER;
- tv->vval.v_number = (int)obj.data.integer;
+ tv->vval.v_number = (varnumber_T)obj.data.integer;
break;
case kObjectTypeFloat:
@@ -616,56 +809,59 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
}
break;
- case kObjectTypeArray:
- tv->v_type = VAR_LIST;
- tv->vval.v_list = list_alloc();
+ case kObjectTypeArray: {
+ list_T *const list = tv_list_alloc((ptrdiff_t)obj.data.array.size);
for (uint32_t i = 0; i < obj.data.array.size; i++) {
Object item = obj.data.array.items[i];
- listitem_T *li = listitem_alloc();
+ typval_T li_tv;
- if (!object_to_vim(item, &li->li_tv, err)) {
- // cleanup
- listitem_free(li);
- list_free(tv->vval.v_list, true);
+ if (!object_to_vim(item, &li_tv, err)) {
+ tv_list_free(list);
return false;
}
- list_append(tv->vval.v_list, li);
+ tv_list_append_owned_tv(list, li_tv);
}
- tv->vval.v_list->lv_refcount++;
+ tv_list_ref(list);
+
+ tv->v_type = VAR_LIST;
+ tv->vval.v_list = list;
break;
+ }
- case kObjectTypeDictionary:
- tv->v_type = VAR_DICT;
- tv->vval.v_dict = dict_alloc();
+ case kObjectTypeDictionary: {
+ dict_T *const dict = tv_dict_alloc();
for (uint32_t i = 0; i < obj.data.dictionary.size; i++) {
KeyValuePair item = obj.data.dictionary.items[i];
String key = item.key;
if (key.size == 0) {
- api_set_error(err,
- Validation,
- _("Empty dictionary keys aren't allowed"));
+ api_set_error(err, kErrorTypeValidation,
+ "Empty dictionary keys aren't allowed");
// cleanup
- dict_free(tv->vval.v_dict, true);
+ tv_dict_free(dict);
return false;
}
- dictitem_T *di = dictitem_alloc((uint8_t *) key.data);
+ dictitem_T *const di = tv_dict_item_alloc(key.data);
if (!object_to_vim(item.value, &di->di_tv, err)) {
// cleanup
- dictitem_free(di);
- dict_free(tv->vval.v_dict, true);
+ tv_dict_item_free(di);
+ tv_dict_free(dict);
return false;
}
- dict_add(tv->vval.v_dict, di);
+ tv_dict_add(dict, di);
}
- tv->vval.v_dict->dv_refcount++;
+ dict->dv_refcount++;
+
+ tv->v_type = VAR_DICT;
+ tv->vval.v_dict = dict;
break;
+ }
default:
abort();
}
@@ -730,12 +926,25 @@ void api_free_dictionary(Dictionary value)
xfree(value.items);
}
+void api_clear_error(Error *value)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!ERROR_SET(value)) {
+ return;
+ }
+ xfree(value->msg);
+ value->msg = NULL;
+ value->type = kErrorTypeNone;
+}
+
Dictionary api_metadata(void)
{
static Dictionary metadata = ARRAY_DICT_INIT;
if (!metadata.size) {
- msgpack_rpc_init_function_metadata(&metadata);
+ PUT(metadata, "version", DICTIONARY_OBJ(version_dict()));
+ init_function_metadata(&metadata);
+ init_ui_event_metadata(&metadata);
init_error_type_metadata(&metadata);
init_type_metadata(&metadata);
}
@@ -743,6 +952,44 @@ Dictionary api_metadata(void)
return copy_object(DICTIONARY_OBJ(metadata)).data.dictionary;
}
+static void init_function_metadata(Dictionary *metadata)
+{
+ msgpack_unpacked unpacked;
+ msgpack_unpacked_init(&unpacked);
+ if (msgpack_unpack_next(&unpacked,
+ (const char *)funcs_metadata,
+ sizeof(funcs_metadata),
+ NULL) != MSGPACK_UNPACK_SUCCESS) {
+ abort();
+ }
+ Object functions;
+ msgpack_rpc_to_object(&unpacked.data, &functions);
+ msgpack_unpacked_destroy(&unpacked);
+ PUT(*metadata, "functions", functions);
+}
+
+static void init_ui_event_metadata(Dictionary *metadata)
+{
+ msgpack_unpacked unpacked;
+ msgpack_unpacked_init(&unpacked);
+ if (msgpack_unpack_next(&unpacked,
+ (const char *)ui_events_metadata,
+ sizeof(ui_events_metadata),
+ NULL) != MSGPACK_UNPACK_SUCCESS) {
+ abort();
+ }
+ Object ui_events;
+ msgpack_rpc_to_object(&unpacked.data, &ui_events);
+ msgpack_unpacked_destroy(&unpacked);
+ PUT(*metadata, "ui_events", ui_events);
+ Array ui_options = ARRAY_DICT_INIT;
+ ADD(ui_options, STRING_OBJ(cstr_to_string("rgb")));
+ for (UIExtension i = 0; i < kUIExtCount; i++) {
+ ADD(ui_options, STRING_OBJ(cstr_to_string(ui_ext_names[i])));
+ }
+ PUT(*metadata, "ui_options", ARRAY_OBJ(ui_options));
+}
+
static void init_error_type_metadata(Dictionary *metadata)
{
Dictionary types = ARRAY_DICT_INIT;
@@ -758,18 +1005,25 @@ static void init_error_type_metadata(Dictionary *metadata)
PUT(*metadata, "error_types", DICTIONARY_OBJ(types));
}
+
static void init_type_metadata(Dictionary *metadata)
{
Dictionary types = ARRAY_DICT_INIT;
Dictionary buffer_metadata = ARRAY_DICT_INIT;
- PUT(buffer_metadata, "id", INTEGER_OBJ(kObjectTypeBuffer));
+ PUT(buffer_metadata, "id",
+ INTEGER_OBJ(kObjectTypeBuffer - EXT_OBJECT_TYPE_SHIFT));
+ PUT(buffer_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_buf_")));
Dictionary window_metadata = ARRAY_DICT_INIT;
- PUT(window_metadata, "id", INTEGER_OBJ(kObjectTypeWindow));
+ PUT(window_metadata, "id",
+ INTEGER_OBJ(kObjectTypeWindow - EXT_OBJECT_TYPE_SHIFT));
+ PUT(window_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_win_")));
Dictionary tabpage_metadata = ARRAY_DICT_INIT;
- PUT(tabpage_metadata, "id", INTEGER_OBJ(kObjectTypeTabpage));
+ PUT(tabpage_metadata, "id",
+ INTEGER_OBJ(kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT));
+ PUT(tabpage_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_tabpage_")));
PUT(types, "Buffer", DICTIONARY_OBJ(buffer_metadata));
PUT(types, "Window", DICTIONARY_OBJ(window_metadata));
@@ -778,6 +1032,34 @@ static void init_type_metadata(Dictionary *metadata)
PUT(*metadata, "types", DICTIONARY_OBJ(types));
}
+String copy_string(String str)
+{
+ if (str.data != NULL) {
+ return (String){ .data = xmemdupz(str.data, str.size), .size = str.size };
+ } else {
+ return (String)STRING_INIT;
+ }
+}
+
+Array copy_array(Array array)
+{
+ Array rv = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < array.size; i++) {
+ ADD(rv, copy_object(array.items[i]));
+ }
+ return rv;
+}
+
+Dictionary copy_dictionary(Dictionary dict)
+{
+ Dictionary rv = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < dict.size; i++) {
+ KeyValuePair item = dict.items[i];
+ PUT(rv, item.key.data, copy_object(item.value));
+ }
+ return rv;
+}
+
/// Creates a deep clone of an object
Object copy_object(Object obj)
{
@@ -789,23 +1071,13 @@ Object copy_object(Object obj)
return obj;
case kObjectTypeString:
- return STRING_OBJ(cstr_to_string(obj.data.string.data));
+ return STRING_OBJ(copy_string(obj.data.string));
- case kObjectTypeArray: {
- Array rv = ARRAY_DICT_INIT;
- for (size_t i = 0; i < obj.data.array.size; i++) {
- ADD(rv, copy_object(obj.data.array.items[i]));
- }
- return ARRAY_OBJ(rv);
- }
+ case kObjectTypeArray:
+ return ARRAY_OBJ(copy_array(obj.data.array));
case kObjectTypeDictionary: {
- Dictionary rv = ARRAY_DICT_INIT;
- for (size_t i = 0; i < obj.data.dictionary.size; i++) {
- KeyValuePair item = obj.data.dictionary.items[i];
- PUT(rv, item.key.data, copy_object(item.value));
- }
- return DICTIONARY_OBJ(rv);
+ return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary));
}
default:
abort();
@@ -822,7 +1094,7 @@ static void set_option_value_for(char *key,
{
win_T *save_curwin = NULL;
tabpage_T *save_curtab = NULL;
- buf_T *save_curbuf = NULL;
+ bufref_T save_curbuf = { NULL, 0, 0 };
try_start();
switch (opt_type)
@@ -835,8 +1107,8 @@ static void set_option_value_for(char *key,
return;
}
api_set_error(err,
- Exception,
- _("Problem while switching windows"));
+ kErrorTypeException,
+ "Problem while switching windows");
return;
}
set_option_value_err(key, numval, stringval, opt_flags, err);
@@ -845,14 +1117,14 @@ static void set_option_value_for(char *key,
case SREQ_BUF:
switch_buffer(&save_curbuf, (buf_T *)from);
set_option_value_err(key, numval, stringval, opt_flags, err);
- restore_buffer(save_curbuf);
+ restore_buffer(&save_curbuf);
break;
case SREQ_GLOBAL:
set_option_value_err(key, numval, stringval, opt_flags, err);
break;
}
- if (err->set) {
+ if (ERROR_SET(err)) {
return;
}
@@ -868,15 +1140,69 @@ static void set_option_value_err(char *key,
{
char *errmsg;
- if ((errmsg = (char *)set_option_value((uint8_t *)key,
- numval,
- (uint8_t *)stringval,
- opt_flags)))
- {
+ if ((errmsg = set_option_value(key, numval, stringval, opt_flags))) {
if (try_end(err)) {
return;
}
- api_set_error(err, Exception, "%s", errmsg);
+ api_set_error(err, kErrorTypeException, "%s", errmsg);
}
}
+
+void api_set_error(Error *err, ErrorType errType, const char *format, ...)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PRINTF(3, 4)
+{
+ assert(kErrorTypeNone != errType);
+ va_list args1;
+ va_list args2;
+ va_start(args1, format);
+ va_copy(args2, args1);
+ int len = vsnprintf(NULL, 0, format, args1);
+ va_end(args1);
+ assert(len >= 0);
+ // Limit error message to 1 MB.
+ size_t bufsize = MIN((size_t)len + 1, 1024 * 1024);
+ err->msg = xmalloc(bufsize);
+ vsnprintf(err->msg, bufsize, format, args2);
+ va_end(args2);
+
+ err->type = errType;
+}
+
+/// Get an array containing dictionaries describing mappings
+/// based on mode and buffer id
+///
+/// @param mode The abbreviation for the mode
+/// @param buf The buffer to get the mapping array. NULL for global
+/// @returns Array of maparg()-like dictionaries describing mappings
+ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf)
+{
+ Array mappings = ARRAY_DICT_INIT;
+ dict_T *const dict = tv_dict_alloc();
+
+ // Convert the string mode to the integer mode
+ // that is stored within each mapblock
+ char_u *p = (char_u *)mode.data;
+ int int_mode = get_map_mode(&p, 0);
+
+ // Determine the desired buffer value
+ long buffer_value = (buf == NULL) ? 0 : buf->handle;
+
+ for (int i = 0; i < MAX_MAPHASH; i++) {
+ for (const mapblock_T *current_maphash = get_maphash(i, buf);
+ current_maphash;
+ current_maphash = current_maphash->m_next) {
+ // Check for correct mode
+ if (int_mode & current_maphash->m_mode) {
+ mapblock_fill_dict(dict, current_maphash, buffer_value, false);
+ ADD(mappings, vim_to_object(
+ (typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } }));
+
+ tv_dict_clear(dict);
+ }
+ }
+ }
+ tv_dict_free(dict);
+
+ return mappings;
+}
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index a946e35149..0634764f13 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -6,17 +6,9 @@
#include "nvim/api/private/defs.h"
#include "nvim/vim.h"
#include "nvim/memory.h"
+#include "nvim/ex_eval.h"
#include "nvim/lib/kvec.h"
-#define api_set_error(err, errtype, ...) \
- do { \
- snprintf((err)->msg, \
- sizeof((err)->msg), \
- __VA_ARGS__); \
- (err)->set = true; \
- (err)->type = kErrorType##errtype; \
- } while (0)
-
#define OBJECT_OBJ(o) o
#define BOOLEAN_OBJ(b) ((Object) { \
@@ -27,7 +19,7 @@
.type = kObjectTypeInteger, \
.data.integer = i })
-#define FLOATING_OBJ(f) ((Object) { \
+#define FLOAT_OBJ(f) ((Object) { \
.type = kObjectTypeFloat, \
.data.floating = f })
@@ -37,15 +29,15 @@
#define BUFFER_OBJ(s) ((Object) { \
.type = kObjectTypeBuffer, \
- .data.buffer = s })
+ .data.integer = s })
#define WINDOW_OBJ(s) ((Object) { \
.type = kObjectTypeWindow, \
- .data.window = s })
+ .data.integer = s })
#define TABPAGE_OBJ(s) ((Object) { \
.type = kObjectTypeTabpage, \
- .data.tabpage = s })
+ .data.integer = s })
#define ARRAY_OBJ(a) ((Object) { \
.type = kObjectTypeArray, \
@@ -91,6 +83,20 @@
#define api_free_window(value)
#define api_free_tabpage(value)
+/// Structure used for saving state for :try
+///
+/// Used when caller is supposed to be operating when other VimL code is being
+/// processed and that “other VimL code†must not be affected.
+typedef struct {
+ except_T *current_exception;
+ struct msglist *private_msg_list;
+ const struct msglist *const *msg_list;
+ int trylevel;
+ int got_int;
+ int need_rethrow;
+ int did_emsg;
+} TryState;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/private/helpers.h.generated.h"
#endif
diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c
index c8311b0aa0..b6830d9fcf 100644
--- a/src/nvim/api/tabpage.c
+++ b/src/nvim/api/tabpage.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 <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -11,10 +14,11 @@
/// Gets the windows in a tabpage
///
-/// @param tabpage The tabpage
-/// @param[out] err Details of an error that may have occurred
-/// @return The windows in `tabpage`
-ArrayOf(Window) tabpage_get_windows(Tabpage tabpage, Error *err)
+/// @param tabpage Tabpage
+/// @param[out] err Error details, if any
+/// @return List of windows in `tabpage`
+ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -39,11 +43,12 @@ ArrayOf(Window) tabpage_get_windows(Tabpage tabpage, Error *err)
/// Gets a tab-scoped (t:) variable
///
-/// @param tabpage The tab page handle
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The variable value
-Object tabpage_get_var(Tabpage tabpage, String name, Error *err)
+/// @param tabpage Tabpage handle
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Variable value
+Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err)
+ FUNC_API_SINCE(1)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -56,11 +61,51 @@ Object tabpage_get_var(Tabpage tabpage, String name, Error *err)
/// Sets a tab-scoped (t:) variable
///
-/// @param tabpage handle
-/// @param name The variable name
-/// @param value The variable value
-/// @param[out] err Details of an error that may have occurred
-/// @return The old value or nil if there was no previous value.
+/// @param tabpage Tabpage handle
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+void nvim_tabpage_set_var(Tabpage tabpage,
+ String name,
+ Object value,
+ Error *err)
+ FUNC_API_SINCE(1)
+{
+ tabpage_T *tab = find_tab_by_handle(tabpage, err);
+
+ if (!tab) {
+ return;
+ }
+
+ dict_set_var(tab->tp_vars, name, value, false, false, err);
+}
+
+/// Removes a tab-scoped (t:) variable
+///
+/// @param tabpage Tabpage handle
+/// @param name Variable name
+/// @param[out] err Error details, if any
+void nvim_tabpage_del_var(Tabpage tabpage, String name, Error *err)
+ FUNC_API_SINCE(1)
+{
+ tabpage_T *tab = find_tab_by_handle(tabpage, err);
+
+ if (!tab) {
+ return;
+ }
+
+ dict_set_var(tab->tp_vars, name, NIL, true, false, err);
+}
+
+/// Sets a tab-scoped (t:) variable
+///
+/// @deprecated
+///
+/// @param tabpage Tabpage handle
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+/// @return Old value or nil if there was no previous value.
///
/// @warning It may return nil if there was no previous value
/// or if previous value was `v:null`.
@@ -72,18 +117,17 @@ Object tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(tab->tp_vars, name, value, false, err);
+ return dict_set_var(tab->tp_vars, name, value, false, true, err);
}
/// Removes a tab-scoped (t:) variable
///
-/// @param tabpage handle
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The old value or nil if there was no previous value.
+/// @deprecated
///
-/// @warning It may return nil if there was no previous value
-/// or if previous value was `v:null`.
+/// @param tabpage Tabpage handle
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Old value
Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
{
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -92,15 +136,16 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(tab->tp_vars, name, NIL, true, err);
+ return dict_set_var(tab->tp_vars, name, NIL, true, true, err);
}
-/// Gets the current window in a tab page
+/// Gets the current window in a tabpage
///
-/// @param tabpage The tab page handle
-/// @param[out] err Details of an error that may have occurred
-/// @return The Window handle
-Window tabpage_get_window(Tabpage tabpage, Error *err)
+/// @param tabpage Tabpage handle
+/// @param[out] err Error details, if any
+/// @return Window handle
+Window nvim_tabpage_get_win(Tabpage tabpage, Error *err)
+ FUNC_API_SINCE(1)
{
Window rv = 0;
tabpage_T *tab = find_tab_by_handle(tabpage, err);
@@ -110,7 +155,7 @@ Window tabpage_get_window(Tabpage tabpage, Error *err)
}
if (tab == curtab) {
- return vim_get_current_window();
+ return nvim_get_current_win();
} else {
FOR_ALL_WINDOWS_IN_TAB(wp, tab) {
if (wp == tab->tp_curwin) {
@@ -122,13 +167,34 @@ Window tabpage_get_window(Tabpage tabpage, Error *err)
}
}
-/// Checks if a tab page is valid
+/// Gets the tabpage number
+///
+/// @param tabpage Tabpage handle
+/// @param[out] err Error details, if any
+/// @return Tabpage number
+Integer nvim_tabpage_get_number(Tabpage tabpage, Error *err)
+ FUNC_API_SINCE(1)
+{
+ Integer rv = 0;
+ tabpage_T *tab = find_tab_by_handle(tabpage, err);
+
+ if (!tab) {
+ return rv;
+ }
+
+ return tabpage_index(tab);
+}
+
+/// Checks if a tabpage is valid
///
-/// @param tabpage The tab page handle
-/// @return true if the tab page is valid, false otherwise
-Boolean tabpage_is_valid(Tabpage tabpage)
+/// @param tabpage Tabpage handle
+/// @return true if the tabpage is valid, false otherwise
+Boolean nvim_tabpage_is_valid(Tabpage tabpage)
+ FUNC_API_SINCE(1)
{
Error stub = ERROR_INIT;
- return find_tab_by_handle(tabpage, &stub) != NULL;
+ Boolean ret = find_tab_by_handle(tabpage, &stub) != NULL;
+ api_clear_error(&stub);
+ return ret;
}
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 1703d49296..7ba5251c60 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.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 <stddef.h>
#include <stdint.h>
@@ -8,120 +11,264 @@
#include "nvim/memory.h"
#include "nvim/map.h"
#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/api/ui.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/popupmnu.h"
+#include "nvim/cursor_shape.h"
+#include "nvim/highlight.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/ui.c.generated.h"
+# include "ui_events_remote.generated.h"
#endif
typedef struct {
uint64_t channel_id;
Array buffer;
+
+ int hl_id; // current higlight for legacy put event
+ Integer cursor_row, cursor_col; // Intended visibule cursor position
+
+ // Position of legacy cursor, used both for drawing and visible user cursor.
+ Integer client_row, client_col;
} UIData;
static PMap(uint64_t) *connected_uis = NULL;
void remote_ui_init(void)
- FUNC_API_NOEXPORT
+ FUNC_API_NOEXPORT
{
connected_uis = pmap_new(uint64_t)();
}
void remote_ui_disconnect(uint64_t channel_id)
- FUNC_API_NOEXPORT
+ FUNC_API_NOEXPORT
{
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
if (!ui) {
return;
}
UIData *data = ui->data;
- // destroy pending screen updates
- api_free_array(data->buffer);
+ api_free_array(data->buffer); // Destroy pending screen updates.
pmap_del(uint64_t)(connected_uis, channel_id);
xfree(ui->data);
+ ui->data = NULL; // Flag UI as "stopped".
ui_detach_impl(ui);
xfree(ui);
}
-void ui_attach(uint64_t channel_id, Integer width, Integer height,
- Boolean enable_rgb, Error *err)
+/// Wait until ui has connected on stdio channel.
+void remote_ui_wait_for_attach(void)
+ FUNC_API_NOEXPORT
+{
+ Channel *channel = find_channel(CHAN_STDIO);
+ if (!channel) {
+ // this function should only be called in --embed mode, stdio channel
+ // can be assumed.
+ abort();
+ }
+
+ LOOP_PROCESS_EVENTS_UNTIL(&main_loop, channel->events, -1,
+ pmap_has(uint64_t)(connected_uis, CHAN_STDIO));
+}
+
+void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height,
+ Dictionary options, Error *err)
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (pmap_has(uint64_t)(connected_uis, channel_id)) {
- api_set_error(err, Exception, _("UI already attached for channel"));
+ api_set_error(err, kErrorTypeException,
+ "UI already attached to channel: %" PRId64, channel_id);
return;
}
if (width <= 0 || height <= 0) {
- api_set_error(err, Validation,
- _("Expected width > 0 and height > 0"));
+ api_set_error(err, kErrorTypeValidation,
+ "Expected width > 0 and height > 0");
return;
}
- UIData *data = xmalloc(sizeof(UIData));
- data->channel_id = channel_id;
- data->buffer = (Array)ARRAY_DICT_INIT;
UI *ui = xcalloc(1, sizeof(UI));
ui->width = (int)width;
ui->height = (int)height;
- ui->rgb = enable_rgb;
- ui->data = data;
- ui->resize = remote_ui_resize;
- ui->clear = remote_ui_clear;
- ui->eol_clear = remote_ui_eol_clear;
- ui->cursor_goto = remote_ui_cursor_goto;
+ ui->rgb = true;
+ ui->grid_resize = remote_ui_grid_resize;
+ ui->grid_clear = remote_ui_grid_clear;
+ ui->grid_cursor_goto = remote_ui_grid_cursor_goto;
+ ui->mode_info_set = remote_ui_mode_info_set;
ui->update_menu = remote_ui_update_menu;
ui->busy_start = remote_ui_busy_start;
ui->busy_stop = remote_ui_busy_stop;
ui->mouse_on = remote_ui_mouse_on;
ui->mouse_off = remote_ui_mouse_off;
ui->mode_change = remote_ui_mode_change;
- ui->set_scroll_region = remote_ui_set_scroll_region;
- ui->scroll = remote_ui_scroll;
- ui->highlight_set = remote_ui_highlight_set;
- ui->put = remote_ui_put;
+ ui->grid_scroll = remote_ui_grid_scroll;
+ ui->hl_attr_define = remote_ui_hl_attr_define;
+ ui->raw_line = remote_ui_raw_line;
ui->bell = remote_ui_bell;
ui->visual_bell = remote_ui_visual_bell;
- ui->update_fg = remote_ui_update_fg;
- ui->update_bg = remote_ui_update_bg;
- ui->update_sp = remote_ui_update_sp;
+ ui->default_colors_set = remote_ui_default_colors_set;
ui->flush = remote_ui_flush;
ui->suspend = remote_ui_suspend;
ui->set_title = remote_ui_set_title;
ui->set_icon = remote_ui_set_icon;
+ ui->option_set = remote_ui_option_set;
+ ui->event = remote_ui_event;
+ ui->inspect = remote_ui_inspect;
+
+ memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
+
+ for (size_t i = 0; i < options.size; i++) {
+ ui_set_option(ui, true, options.items[i].key, options.items[i].value, err);
+ if (ERROR_SET(err)) {
+ xfree(ui);
+ return;
+ }
+ }
+
+ if (ui->ui_ext[kUIHlState] || ui->ui_ext[kUIMultigrid]) {
+ ui->ui_ext[kUILinegrid] = true;
+ }
+
+ UIData *data = xmalloc(sizeof(UIData));
+ data->channel_id = channel_id;
+ data->buffer = (Array)ARRAY_DICT_INIT;
+ data->hl_id = 0;
+ data->client_col = -1;
+ ui->data = data;
+
pmap_put(uint64_t)(connected_uis, channel_id, ui);
ui_attach_impl(ui);
- return;
}
-void ui_detach(uint64_t channel_id, Error *err)
+/// @deprecated
+void ui_attach(uint64_t channel_id, Integer width, Integer height,
+ Boolean enable_rgb, Error *err)
+{
+ Dictionary opts = ARRAY_DICT_INIT;
+ PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb));
+ nvim_ui_attach(channel_id, width, height, opts, err);
+ api_free_dictionary(opts);
+}
+
+void nvim_ui_detach(uint64_t channel_id, Error *err)
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
- api_set_error(err, Exception, _("UI is not attached for channel"));
+ api_set_error(err, kErrorTypeException,
+ "UI not attached to channel: %" PRId64, channel_id);
+ return;
}
remote_ui_disconnect(channel_id);
}
-Object ui_try_resize(uint64_t channel_id, Integer width,
- Integer height, Error *err)
+
+void nvim_ui_try_resize(uint64_t channel_id, Integer width,
+ Integer height, Error *err)
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
- api_set_error(err, Exception, _("UI is not attached for channel"));
+ api_set_error(err, kErrorTypeException,
+ "UI not attached to channel: %" PRId64, channel_id);
+ return;
}
if (width <= 0 || height <= 0) {
- api_set_error(err, Validation,
- _("Expected width > 0 and height > 0"));
- return NIL;
+ api_set_error(err, kErrorTypeValidation,
+ "Expected width > 0 and height > 0");
+ return;
}
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
ui->width = (int)width;
ui->height = (int)height;
ui_refresh();
- return NIL;
}
-static void push_call(UI *ui, char *name, Array args)
+void nvim_ui_set_option(uint64_t channel_id, String name,
+ Object value, Error *error)
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
+{
+ if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
+ api_set_error(error, kErrorTypeException,
+ "UI not attached to channel: %" PRId64, channel_id);
+ return;
+ }
+ UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
+
+ ui_set_option(ui, false, name, value, error);
+}
+
+static void ui_set_option(UI *ui, bool init, String name, Object value,
+ Error *error)
+{
+ if (strequal(name.data, "rgb")) {
+ if (value.type != kObjectTypeBoolean) {
+ api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean");
+ return;
+ }
+ ui->rgb = value.data.boolean;
+ // A little drastic, but only legacy uis need to use this option
+ if (!init) {
+ ui_refresh();
+ }
+ return;
+ }
+
+ // LEGACY: Deprecated option, use `ext_cmdline` instead.
+ bool is_popupmenu = strequal(name.data, "popupmenu_external");
+
+ for (UIExtension i = 0; i < kUIExtCount; i++) {
+ if (strequal(name.data, ui_ext_names[i])
+ || (i == kUIPopupmenu && is_popupmenu)) {
+ if (value.type != kObjectTypeBoolean) {
+ api_set_error(error, kErrorTypeValidation, "%s must be a Boolean",
+ name.data);
+ return;
+ }
+ bool boolval = value.data.boolean;
+ if (!init && i == kUILinegrid && boolval != ui->ui_ext[i]) {
+ // There shouldn't be a reason for an UI to do this ever
+ // so explicitly don't support this.
+ api_set_error(error, kErrorTypeValidation,
+ "ext_linegrid option cannot be changed");
+ }
+ ui->ui_ext[i] = boolval;
+ if (!init) {
+ ui_set_ext_option(ui, i, boolval);
+ }
+ return;
+ }
+ }
+
+ api_set_error(error, kErrorTypeValidation, "No such UI option: %s",
+ name.data);
+}
+
+/// Tell nvim to resize a grid. Nvim sends grid_resize event with the
+/// requested grid size is within size limits and with maximum allowed size
+/// otherwise.
+///
+/// On invalid grid handle, fails with error.
+///
+/// @param grid The handle of the grid to be changed.
+/// @param width The new requested width.
+/// @param height The new requested height.
+void nvim_ui_try_resize_grid(uint64_t channel_id, Integer grid, Integer width,
+ Integer height, Error *error)
+ FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY
+{
+ if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
+ api_set_error(error, kErrorTypeException,
+ "UI not attached to channel: %" PRId64, channel_id);
+ return;
+ }
+
+ ui_grid_resize((handle_T)grid, (int)width, (int)height, error);
+}
+
+/// Pushes data into UI.UIData, to be consumed later by remote_ui_flush().
+static void push_call(UI *ui, const char *name, Array args)
{
Array call = ARRAY_DICT_INIT;
UIData *data = ui->data;
@@ -143,201 +290,329 @@ static void push_call(UI *ui, char *name, Array args)
kv_A(data->buffer, kv_size(data->buffer) - 1).data.array = call;
}
-static void remote_ui_resize(UI *ui, int width, int height)
+static void remote_ui_grid_clear(UI *ui, Integer grid)
{
Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(width));
- ADD(args, INTEGER_OBJ(height));
- push_call(ui, "resize", args);
-}
-
-static void remote_ui_clear(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "clear", args);
-}
-
-static void remote_ui_eol_clear(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "eol_clear", args);
-}
-
-static void remote_ui_cursor_goto(UI *ui, int row, int col)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(row));
- ADD(args, INTEGER_OBJ(col));
- push_call(ui, "cursor_goto", args);
+ if (ui->ui_ext[kUILinegrid]) {
+ ADD(args, INTEGER_OBJ(grid));
+ }
+ const char *name = ui->ui_ext[kUILinegrid] ? "grid_clear" : "clear";
+ push_call(ui, name, args);
}
-static void remote_ui_update_menu(UI *ui)
+static void remote_ui_grid_resize(UI *ui, Integer grid,
+ Integer width, Integer height)
{
Array args = ARRAY_DICT_INIT;
- push_call(ui, "update_menu", args);
+ if (ui->ui_ext[kUILinegrid]) {
+ ADD(args, INTEGER_OBJ(grid));
+ }
+ ADD(args, INTEGER_OBJ(width));
+ ADD(args, INTEGER_OBJ(height));
+ const char *name = ui->ui_ext[kUILinegrid] ? "grid_resize" : "resize";
+ push_call(ui, name, args);
}
-static void remote_ui_busy_start(UI *ui)
+static void remote_ui_grid_scroll(UI *ui, Integer grid, Integer top,
+ Integer bot, Integer left, Integer right,
+ Integer rows, Integer cols)
{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "busy_start", args);
+ if (ui->ui_ext[kUILinegrid]) {
+ Array args = ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(grid));
+ ADD(args, INTEGER_OBJ(top));
+ ADD(args, INTEGER_OBJ(bot));
+ ADD(args, INTEGER_OBJ(left));
+ ADD(args, INTEGER_OBJ(right));
+ ADD(args, INTEGER_OBJ(rows));
+ ADD(args, INTEGER_OBJ(cols));
+ push_call(ui, "grid_scroll", args);
+ } else {
+ Array args = ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(top));
+ ADD(args, INTEGER_OBJ(bot-1));
+ ADD(args, INTEGER_OBJ(left));
+ ADD(args, INTEGER_OBJ(right-1));
+ push_call(ui, "set_scroll_region", args);
+
+ args = (Array)ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(rows));
+ push_call(ui, "scroll", args);
+
+ // some clients have "clear" being affected by scroll region,
+ // so reset it.
+ args = (Array)ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(0));
+ ADD(args, INTEGER_OBJ(ui->height-1));
+ ADD(args, INTEGER_OBJ(0));
+ ADD(args, INTEGER_OBJ(ui->width-1));
+ push_call(ui, "set_scroll_region", args);
+ }
}
-static void remote_ui_busy_stop(UI *ui)
+static void remote_ui_default_colors_set(UI *ui, Integer rgb_fg,
+ Integer rgb_bg, Integer rgb_sp,
+ Integer cterm_fg, Integer cterm_bg)
{
Array args = ARRAY_DICT_INIT;
- push_call(ui, "busy_stop", args);
+ ADD(args, INTEGER_OBJ(rgb_fg));
+ ADD(args, INTEGER_OBJ(rgb_bg));
+ ADD(args, INTEGER_OBJ(rgb_sp));
+ ADD(args, INTEGER_OBJ(cterm_fg));
+ ADD(args, INTEGER_OBJ(cterm_bg));
+ push_call(ui, "default_colors_set", args);
+
+ // Deprecated
+ if (!ui->ui_ext[kUILinegrid]) {
+ args = (Array)ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(ui->rgb ? rgb_fg : cterm_fg - 1));
+ push_call(ui, "update_fg", args);
+
+ args = (Array)ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(ui->rgb ? rgb_bg : cterm_bg - 1));
+ push_call(ui, "update_bg", args);
+
+ args = (Array)ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(ui->rgb ? rgb_sp : -1));
+ push_call(ui, "update_sp", args);
+ }
}
-static void remote_ui_mouse_on(UI *ui)
+static void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs,
+ HlAttrs cterm_attrs, Array info)
{
+ if (!ui->ui_ext[kUILinegrid]) {
+ return;
+ }
Array args = ARRAY_DICT_INIT;
- push_call(ui, "mouse_on", args);
-}
-static void remote_ui_mouse_off(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "mouse_off", args);
-}
+ ADD(args, INTEGER_OBJ(id));
+ ADD(args, DICTIONARY_OBJ(hlattrs2dict(rgb_attrs, true)));
+ ADD(args, DICTIONARY_OBJ(hlattrs2dict(cterm_attrs, false)));
-static void remote_ui_mode_change(UI *ui, int mode)
-{
- Array args = ARRAY_DICT_INIT;
- if (mode == INSERT) {
- ADD(args, STRING_OBJ(cstr_to_string("insert")));
- } else if (mode == REPLACE) {
- ADD(args, STRING_OBJ(cstr_to_string("replace")));
+ if (ui->ui_ext[kUIHlState]) {
+ ADD(args, ARRAY_OBJ(copy_array(info)));
} else {
- assert(mode == NORMAL);
- ADD(args, STRING_OBJ(cstr_to_string("normal")));
+ ADD(args, ARRAY_OBJ((Array)ARRAY_DICT_INIT));
}
- push_call(ui, "mode_change", args);
-}
-static void remote_ui_set_scroll_region(UI *ui, int top, int bot, int left,
- int right)
-{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(top));
- ADD(args, INTEGER_OBJ(bot));
- ADD(args, INTEGER_OBJ(left));
- ADD(args, INTEGER_OBJ(right));
- push_call(ui, "set_scroll_region", args);
+ push_call(ui, "hl_attr_define", args);
}
-static void remote_ui_scroll(UI *ui, int count)
+static void remote_ui_highlight_set(UI *ui, int id)
{
Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(count));
- push_call(ui, "scroll", args);
-}
-
-static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
-{
- Array args = ARRAY_DICT_INIT;
- Dictionary hl = ARRAY_DICT_INIT;
-
- if (attrs.bold) {
- PUT(hl, "bold", BOOLEAN_OBJ(true));
- }
-
- if (attrs.underline) {
- PUT(hl, "underline", BOOLEAN_OBJ(true));
- }
-
- if (attrs.undercurl) {
- PUT(hl, "undercurl", BOOLEAN_OBJ(true));
- }
-
- if (attrs.italic) {
- PUT(hl, "italic", BOOLEAN_OBJ(true));
- }
-
- if (attrs.reverse) {
- PUT(hl, "reverse", BOOLEAN_OBJ(true));
- }
-
- if (attrs.foreground != -1) {
- PUT(hl, "foreground", INTEGER_OBJ(attrs.foreground));
- }
+ UIData *data = ui->data;
- if (attrs.background != -1) {
- PUT(hl, "background", INTEGER_OBJ(attrs.background));
- }
- if (attrs.special != -1) {
- PUT(hl, "special", INTEGER_OBJ(attrs.special));
+ if (data->hl_id == id) {
+ return;
}
+ data->hl_id = id;
+ Dictionary hl = hlattrs2dict(syn_attr2entry(id), ui->rgb);
ADD(args, DICTIONARY_OBJ(hl));
push_call(ui, "highlight_set", args);
}
-static void remote_ui_put(UI *ui, uint8_t *data, size_t size)
+/// "true" cursor used only for input focus
+static void remote_ui_grid_cursor_goto(UI *ui, Integer grid, Integer row,
+ Integer col)
{
- Array args = ARRAY_DICT_INIT;
- String str = { .data = xmemdupz(data, size), .size = size };
- ADD(args, STRING_OBJ(str));
- push_call(ui, "put", args);
+ if (ui->ui_ext[kUILinegrid]) {
+ Array args = ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(grid));
+ ADD(args, INTEGER_OBJ(row));
+ ADD(args, INTEGER_OBJ(col));
+ push_call(ui, "grid_cursor_goto", args);
+ } else {
+ UIData *data = ui->data;
+ data->cursor_row = row;
+ data->cursor_col = col;
+ remote_ui_cursor_goto(ui, row, col);
+ }
}
-static void remote_ui_bell(UI *ui)
+/// emulated cursor used both for drawing and for input focus
+static void remote_ui_cursor_goto(UI *ui, Integer row, Integer col)
{
+ UIData *data = ui->data;
+ if (data->client_row == row && data->client_col == col) {
+ return;
+ }
+ data->client_row = row;
+ data->client_col = col;
Array args = ARRAY_DICT_INIT;
- push_call(ui, "bell", args);
+ ADD(args, INTEGER_OBJ(row));
+ ADD(args, INTEGER_OBJ(col));
+ push_call(ui, "cursor_goto", args);
}
-static void remote_ui_visual_bell(UI *ui)
+static void remote_ui_put(UI *ui, const char *cell)
{
+ UIData *data = ui->data;
+ data->client_col++;
Array args = ARRAY_DICT_INIT;
- push_call(ui, "visual_bell", args);
+ ADD(args, STRING_OBJ(cstr_to_string(cell)));
+ push_call(ui, "put", args);
}
-static void remote_ui_update_fg(UI *ui, int fg)
+static void remote_ui_raw_line(UI *ui, Integer grid, Integer row,
+ Integer startcol, Integer endcol,
+ Integer clearcol, Integer clearattr,
+ Boolean wrap, const schar_T *chunk,
+ const sattr_T *attrs)
{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(fg));
- push_call(ui, "update_fg", args);
+ UIData *data = ui->data;
+ if (ui->ui_ext[kUILinegrid]) {
+ Array args = ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(grid));
+ ADD(args, INTEGER_OBJ(row));
+ ADD(args, INTEGER_OBJ(startcol));
+ Array cells = ARRAY_DICT_INIT;
+ int repeat = 0;
+ size_t ncells = (size_t)(endcol-startcol);
+ int last_hl = -1;
+ for (size_t i = 0; i < ncells; i++) {
+ repeat++;
+ if (i == ncells-1 || attrs[i] != attrs[i+1]
+ || STRCMP(chunk[i], chunk[i+1])) {
+ Array cell = ARRAY_DICT_INIT;
+ ADD(cell, STRING_OBJ(cstr_to_string((const char *)chunk[i])));
+ if (attrs[i] != last_hl || repeat > 1) {
+ ADD(cell, INTEGER_OBJ(attrs[i]));
+ last_hl = attrs[i];
+ }
+ if (repeat > 1) {
+ ADD(cell, INTEGER_OBJ(repeat));
+ }
+ ADD(cells, ARRAY_OBJ(cell));
+ repeat = 0;
+ }
+ }
+ if (endcol < clearcol) {
+ Array cell = ARRAY_DICT_INIT;
+ ADD(cell, STRING_OBJ(cstr_to_string(" ")));
+ ADD(cell, INTEGER_OBJ(clearattr));
+ ADD(cell, INTEGER_OBJ(clearcol-endcol));
+ ADD(cells, ARRAY_OBJ(cell));
+ }
+ ADD(args, ARRAY_OBJ(cells));
+
+ push_call(ui, "grid_line", args);
+ } else {
+ for (int i = 0; i < endcol-startcol; i++) {
+ remote_ui_cursor_goto(ui, row, startcol+i);
+ remote_ui_highlight_set(ui, attrs[i]);
+ remote_ui_put(ui, (const char *)chunk[i]);
+ if (utf_ambiguous_width(utf_ptr2char(chunk[i]))) {
+ data->client_col = -1; // force cursor update
+ }
+ }
+ if (endcol < clearcol) {
+ remote_ui_cursor_goto(ui, row, endcol);
+ remote_ui_highlight_set(ui, (int)clearattr);
+ // legacy eol_clear was only ever used with cleared attributes
+ // so be on the safe side
+ if (clearattr == 0 && clearcol == Columns) {
+ Array args = ARRAY_DICT_INIT;
+ push_call(ui, "eol_clear", args);
+ } else {
+ for (Integer c = endcol; c < clearcol; c++) {
+ remote_ui_put(ui, " ");
+ }
+ }
+ }
+ }
}
-static void remote_ui_update_bg(UI *ui, int bg)
+static void remote_ui_flush(UI *ui)
{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(bg));
- push_call(ui, "update_bg", args);
+ UIData *data = ui->data;
+ if (data->buffer.size > 0) {
+ if (!ui->ui_ext[kUILinegrid]) {
+ remote_ui_cursor_goto(ui, data->cursor_row, data->cursor_col);
+ }
+ push_call(ui, "flush", (Array)ARRAY_DICT_INIT);
+ rpc_send_event(data->channel_id, "redraw", data->buffer);
+ data->buffer = (Array)ARRAY_DICT_INIT;
+ }
}
-static void remote_ui_update_sp(UI *ui, int sp)
+static Array translate_contents(UI *ui, Array contents)
{
- Array args = ARRAY_DICT_INIT;
- ADD(args, INTEGER_OBJ(sp));
- push_call(ui, "update_sp", args);
+ Array new_contents = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < contents.size; i++) {
+ Array item = contents.items[i].data.array;
+ Array new_item = ARRAY_DICT_INIT;
+ int attr = (int)item.items[0].data.integer;
+ if (attr) {
+ Dictionary rgb_attrs = hlattrs2dict(syn_attr2entry(attr), ui->rgb);
+ ADD(new_item, DICTIONARY_OBJ(rgb_attrs));
+ } else {
+ ADD(new_item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT));
+ }
+ ADD(new_item, copy_object(item.items[1]));
+ ADD(new_contents, ARRAY_OBJ(new_item));
+ }
+ return new_contents;
}
-static void remote_ui_flush(UI *ui)
+static Array translate_firstarg(UI *ui, Array args)
{
- UIData *data = ui->data;
- channel_send_event(data->channel_id, "redraw", data->buffer);
- data->buffer = (Array)ARRAY_DICT_INIT;
-}
+ Array new_args = ARRAY_DICT_INIT;
+ Array contents = args.items[0].data.array;
-static void remote_ui_suspend(UI *ui)
-{
- Array args = ARRAY_DICT_INIT;
- push_call(ui, "suspend", args);
+ ADD(new_args, ARRAY_OBJ(translate_contents(ui, contents)));
+ for (size_t i = 1; i < args.size; i++) {
+ ADD(new_args, copy_object(args.items[i]));
+ }
+ return new_args;
}
-static void remote_ui_set_title(UI *ui, char *title)
+static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed)
{
- Array args = ARRAY_DICT_INIT;
- ADD(args, STRING_OBJ(cstr_to_string(title)));
- push_call(ui, "set_title", args);
+ if (!ui->ui_ext[kUILinegrid]) {
+ // the representation of highlights in cmdline changed, translate back
+ // never consumes args
+ if (strequal(name, "cmdline_show")) {
+ Array new_args = translate_firstarg(ui, args);
+ push_call(ui, name, new_args);
+ return;
+ } else if (strequal(name, "cmdline_block_show")) {
+ Array new_args = ARRAY_DICT_INIT;
+ Array block = args.items[0].data.array;
+ Array new_block = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < block.size; i++) {
+ ADD(new_block,
+ ARRAY_OBJ(translate_contents(ui, block.items[i].data.array)));
+ }
+ ADD(new_args, ARRAY_OBJ(new_block));
+ push_call(ui, name, new_args);
+ return;
+ } else if (strequal(name, "cmdline_block_append")) {
+ Array new_args = translate_firstarg(ui, args);
+ push_call(ui, name, new_args);
+ return;
+ }
+ }
+
+ Array my_args = ARRAY_DICT_INIT;
+ // Objects are currently single-reference
+ // make a copy, but only if necessary
+ if (*args_consumed) {
+ for (size_t i = 0; i < args.size; i++) {
+ ADD(my_args, copy_object(args.items[i]));
+ }
+ } else {
+ my_args = args;
+ *args_consumed = true;
+ }
+ push_call(ui, name, my_args);
}
-static void remote_ui_set_icon(UI *ui, char *icon)
+static void remote_ui_inspect(UI *ui, Dictionary *info)
{
- Array args = ARRAY_DICT_INIT;
- ADD(args, STRING_OBJ(cstr_to_string(icon)));
- push_call(ui, "set_icon", args);
+ UIData *data = ui->data;
+ PUT(*info, "chan", INTEGER_OBJ((Integer)data->channel_id));
}
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
new file mode 100644
index 0000000000..59a7780651
--- /dev/null
+++ b/src/nvim/api/ui_events.in.h
@@ -0,0 +1,130 @@
+#ifndef NVIM_API_UI_EVENTS_IN_H
+#define NVIM_API_UI_EVENTS_IN_H
+
+// This file is not compiled, just parsed for definitons
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# error "don't include this file, include nvim/ui.h"
+#endif
+
+#include "nvim/api/private/defs.h"
+#include "nvim/func_attr.h"
+#include "nvim/ui.h"
+
+void mode_info_set(Boolean enabled, Array cursor_styles)
+ FUNC_API_SINCE(3);
+void update_menu(void)
+ FUNC_API_SINCE(3);
+void busy_start(void)
+ FUNC_API_SINCE(3);
+void busy_stop(void)
+ FUNC_API_SINCE(3);
+void mouse_on(void)
+ FUNC_API_SINCE(3);
+void mouse_off(void)
+ FUNC_API_SINCE(3);
+void mode_change(String mode, Integer mode_idx)
+ FUNC_API_SINCE(3);
+void bell(void)
+ FUNC_API_SINCE(3);
+void visual_bell(void)
+ FUNC_API_SINCE(3);
+void flush(void)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL;
+void suspend(void)
+ FUNC_API_SINCE(3) FUNC_API_BRIDGE_IMPL;
+void set_title(String title)
+ FUNC_API_SINCE(3);
+void set_icon(String icon)
+ FUNC_API_SINCE(3);
+void option_set(String name, Object value)
+ FUNC_API_SINCE(4) FUNC_API_BRIDGE_IMPL;
+
+// First revison of the grid protocol, used by default
+void update_fg(Integer fg)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void update_bg(Integer bg)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void update_sp(Integer sp)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void resize(Integer width, Integer height)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void clear(void)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void eol_clear(void)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void cursor_goto(Integer row, Integer col)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void highlight_set(HlAttrs attrs)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY FUNC_API_REMOTE_IMPL;
+void put(String str)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void set_scroll_region(Integer top, Integer bot, Integer left, Integer right)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void scroll(Integer count)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+
+// Second revison of the grid protocol, used with ext_linegrid ui option
+void default_colors_set(Integer rgb_fg, Integer rgb_bg, Integer rgb_sp,
+ Integer cterm_fg, Integer cterm_bg)
+ FUNC_API_SINCE(4) FUNC_API_REMOTE_IMPL;
+void hl_attr_define(Integer id, HlAttrs rgb_attrs, HlAttrs cterm_attrs,
+ Array info)
+ FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL;
+void grid_resize(Integer grid, Integer width, Integer height)
+ FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL;
+void grid_clear(Integer grid)
+ FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL;
+void grid_cursor_goto(Integer grid, Integer row, Integer col)
+ FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL;
+void grid_line(Integer grid, Integer row, Integer col_start, Array data)
+ FUNC_API_SINCE(5) FUNC_API_REMOTE_ONLY;
+void grid_scroll(Integer grid, Integer top, Integer bot,
+ Integer left, Integer right, Integer rows, Integer cols)
+ FUNC_API_SINCE(5) FUNC_API_REMOTE_IMPL;
+void grid_destroy(Integer grid)
+ FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
+
+void win_pos(Integer grid, Integer win, Integer startrow,
+ Integer startcol, Integer width, Integer height)
+ FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
+void win_hide(Integer grid)
+ FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
+void win_scroll_over_start(void)
+ FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
+void win_scroll_over_reset(void)
+ FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY;
+
+void popupmenu_show(Array items, Integer selected,
+ Integer row, Integer col, Integer grid)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void popupmenu_hide(void)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void popupmenu_select(Integer selected)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+
+void tabline_update(Tabpage current, Array tabs)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+
+void cmdline_show(Array content, Integer pos, String firstc, String prompt,
+ Integer indent, Integer level)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void cmdline_pos(Integer pos, Integer level)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void cmdline_special_char(String c, Boolean shift, Integer level)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void cmdline_hide(Integer level)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void cmdline_block_show(Array lines)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void cmdline_block_append(Array lines)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void cmdline_block_hide(void)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+
+void wildmenu_show(Array items)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void wildmenu_select(Integer selected)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+void wildmenu_hide(void)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
+#endif // NVIM_API_UI_EVENTS_IN_H
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index ac7cc65ee4..ce7ef681ef 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.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 <stdint.h>
#include <inttypes.h>
@@ -10,21 +13,33 @@
#include "nvim/ascii.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h"
+#include "nvim/api/private/dispatch.h"
#include "nvim/api/buffer.h"
#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/helpers.h"
+#include "nvim/lua/executor.h"
#include "nvim/vim.h"
#include "nvim/buffer.h"
+#include "nvim/file_search.h"
+#include "nvim/highlight.h"
#include "nvim/window.h"
#include "nvim/types.h"
#include "nvim/ex_docmd.h"
#include "nvim/screen.h"
#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/edit.h"
#include "nvim/eval.h"
-#include "nvim/misc2.h"
+#include "nvim/eval/typval.h"
+#include "nvim/option.h"
+#include "nvim/state.h"
#include "nvim/syntax.h"
#include "nvim/getchar.h"
#include "nvim/os/input.h"
+#include "nvim/os/process.h"
+#include "nvim/viml/parser/expressions.h"
+#include "nvim/viml/parser/parser.h"
+#include "nvim/ui.h"
#define LINE_BUFFER_SIZE 4096
@@ -32,36 +47,98 @@
# include "api/vim.c.generated.h"
#endif
-/// Executes an ex-mode command str
+void api_vim_init(void)
+ FUNC_API_NOEXPORT
+{
+ namespace_ids = map_new(String, handle_T)();
+}
+
+void api_vim_free_all_mem(void)
+ FUNC_API_NOEXPORT
+{
+ String name;
+ handle_T id;
+ map_foreach(namespace_ids, name, id, {
+ (void)id;
+ xfree(name.data);
+ })
+ map_free(String, handle_T)(namespace_ids);
+}
+
+/// Executes an ex-command.
///
-/// @param str The command str
-/// @param[out] err Details of an error that may have occurred
-void vim_command(String str, Error *err)
+/// On execution error: fails with VimL error, does not update v:errmsg.
+///
+/// @param command Ex-command string
+/// @param[out] err Error details (Vim error), if any
+void nvim_command(String command, Error *err)
+ FUNC_API_SINCE(1)
{
- // Run the command
try_start();
- do_cmdline_cmd(str.data);
- update_screen(VALID);
+ do_cmdline_cmd(command.data);
try_end(err);
}
-/// Passes input keys to Neovim
+/// Gets a highlight definition by name.
///
-/// @param keys to be typed
-/// @param mode specifies the mapping options
-/// @param escape_csi the string needs escaping for K_SPECIAL/CSI bytes
+/// @param name Highlight group name
+/// @param rgb Export RGB colors
+/// @param[out] err Error details, if any
+/// @return Highlight definition map
+/// @see nvim_get_hl_by_id
+Dictionary nvim_get_hl_by_name(String name, Boolean rgb, Error *err)
+ FUNC_API_SINCE(3)
+{
+ Dictionary result = ARRAY_DICT_INIT;
+ int id = syn_name2id((const char_u *)name.data);
+
+ if (id == 0) {
+ api_set_error(err, kErrorTypeException, "Invalid highlight name: %s",
+ name.data);
+ return result;
+ }
+ result = nvim_get_hl_by_id(id, rgb, err);
+ return result;
+}
+
+/// Gets a highlight definition by id. |hlID()|
+///
+/// @param hl_id Highlight id as returned by |hlID()|
+/// @param rgb Export RGB colors
+/// @param[out] err Error details, if any
+/// @return Highlight definition map
+/// @see nvim_get_hl_by_name
+Dictionary nvim_get_hl_by_id(Integer hl_id, Boolean rgb, Error *err)
+ FUNC_API_SINCE(3)
+{
+ Dictionary dic = ARRAY_DICT_INIT;
+ if (syn_get_final_id((int)hl_id) == 0) {
+ api_set_error(err, kErrorTypeException,
+ "Invalid highlight id: %" PRId64, hl_id);
+ return dic;
+ }
+ int attrcode = syn_id2attr((int)hl_id);
+ return hl_get_attr_by_id(attrcode, rgb, err);
+}
+
+/// Sends input-keys to Nvim, subject to various quirks controlled by `mode`
+/// flags. This is a blocking call, unlike |nvim_input()|.
+///
+/// On execution error: does not fail, but updates v:errmsg.
+///
+/// @param keys to be typed
+/// @param mode behavior flags, see |feedkeys()|
+/// @param escape_csi If true, escape K_SPECIAL/CSI bytes in `keys`
/// @see feedkeys()
/// @see vim_strsave_escape_csi
-void vim_feedkeys(String keys, String mode, Boolean escape_csi)
+void nvim_feedkeys(String keys, String mode, Boolean escape_csi)
+ FUNC_API_SINCE(1)
{
bool remap = true;
bool insert = false;
bool typed = false;
bool execute = false;
-
- if (keys.size == 0) {
- return;
- }
+ bool dangerous = false;
for (size_t i = 0; i < mode.size; ++i) {
switch (mode.data[i]) {
@@ -70,9 +147,14 @@ void vim_feedkeys(String keys, String mode, Boolean escape_csi)
case 't': typed = true; break;
case 'i': insert = true; break;
case 'x': execute = true; break;
+ case '!': dangerous = true; break;
}
}
+ if (keys.size == 0 && !execute) {
+ return;
+ }
+
char *keys_esc;
if (escape_csi) {
// Need to escape K_SPECIAL and CSI before putting the string in the
@@ -92,100 +174,193 @@ void vim_feedkeys(String keys, String mode, Boolean escape_csi)
typebuf_was_filled = true;
}
if (execute) {
+ int save_msg_scroll = msg_scroll;
+
+ /* Avoid a 1 second delay when the keys start Insert mode. */
+ msg_scroll = false;
+ if (!dangerous) {
+ ex_normal_busy++;
+ }
exec_normal(true);
+ if (!dangerous) {
+ ex_normal_busy--;
+ }
+ msg_scroll |= save_msg_scroll;
}
}
-/// Passes input keys to Neovim. Unlike `vim_feedkeys`, this will use a
-/// lower-level input buffer and the call is not deferred.
-/// This is the most reliable way to emulate real user input.
+/// Queues raw user-input. Unlike |nvim_feedkeys()|, this uses a low-level
+/// input buffer and the call is non-blocking (input is processed
+/// asynchronously by the eventloop).
+///
+/// On execution error: does not fail, but updates v:errmsg.
+///
+/// @note |keycodes| like <CR> are translated, so "<" is special.
+/// To input a literal "<", send <LT>.
///
/// @param keys to be typed
-/// @return The number of bytes actually written, which can be lower than
-/// requested if the buffer becomes full.
-Integer vim_input(String keys)
- FUNC_API_ASYNC
+/// @return Number of bytes actually written (can be fewer than
+/// requested if the buffer becomes full).
+Integer nvim_input(String keys)
+ FUNC_API_SINCE(1) FUNC_API_ASYNC
{
return (Integer)input_enqueue(keys);
}
-/// Replaces any terminal codes with the internal representation
+/// Replaces terminal codes and |keycodes| (<CR>, <Esc>, ...) in a string with
+/// the internal representation.
///
+/// @param str String to be converted.
+/// @param from_part Legacy Vim parameter. Usually true.
+/// @param do_lt Also translate <lt>. Ignored if `special` is false.
+/// @param special Replace |keycodes|, e.g. <CR> becomes a "\n" char.
/// @see replace_termcodes
/// @see cpoptions
-String vim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
+String nvim_replace_termcodes(String str, Boolean from_part, Boolean do_lt,
Boolean special)
+ FUNC_API_SINCE(1)
{
if (str.size == 0) {
// Empty string
- return str;
+ return (String) { .data = NULL, .size = 0 };
}
char *ptr = NULL;
- // Set 'cpoptions' the way we want it.
- // FLAG_CPO_BSLASH set - backslashes are *not* treated specially
- // FLAG_CPO_KEYCODE set - keycodes are *not* reverse-engineered
- // FLAG_CPO_SPECI unset - <Key> sequences *are* interpreted
- // The third from end parameter of replace_termcodes() is true so that the
- // <lt> sequence is recognised - needed for a real backslash.
replace_termcodes((char_u *)str.data, str.size, (char_u **)&ptr,
from_part, do_lt, special, CPO_TO_CPO_FLAGS);
return cstr_as_string(ptr);
}
-String vim_command_output(String str, Error *err)
+/// Executes an ex-command and returns its (non-error) output.
+/// Shell |:!| output is not captured.
+///
+/// On execution error: fails with VimL error, does not update v:errmsg.
+///
+/// @param command Ex-command string
+/// @param[out] err Error details (Vim error), if any
+String nvim_command_output(String command, Error *err)
+ FUNC_API_SINCE(1)
{
- do_cmdline_cmd("redir => v:command_output");
- vim_command(str, err);
- do_cmdline_cmd("redir END");
+ const int save_msg_silent = msg_silent;
+ garray_T *const save_capture_ga = capture_ga;
+ garray_T capture_local;
+ ga_init(&capture_local, 1, 80);
+
+ try_start();
+ msg_silent++;
+ capture_ga = &capture_local;
+ do_cmdline_cmd(command.data);
+ capture_ga = save_capture_ga;
+ msg_silent = save_msg_silent;
+ try_end(err);
- if (err->set) {
- return (String) STRING_INIT;
+ if (ERROR_SET(err)) {
+ goto theend;
+ }
+
+ if (capture_local.ga_len > 1) {
+ String s = (String){
+ .data = capture_local.ga_data,
+ .size = (size_t)capture_local.ga_len,
+ };
+ // redir usually (except :echon) prepends a newline.
+ if (s.data[0] == '\n') {
+ memmove(s.data, s.data + 1, s.size);
+ s.data[s.size - 1] = '\0';
+ s.size = s.size - 1;
+ }
+ return s; // Caller will free the memory.
}
- return cstr_to_string((char *)get_vim_var_str(VV_COMMAND_OUTPUT));
+theend:
+ ga_clear(&capture_local);
+ return (String)STRING_INIT;
}
-/// Evaluates the expression str using the Vim internal expression
-/// evaluator (see |expression|).
-/// Dictionaries and lists are recursively expanded.
+/// Evaluates a VimL expression (:help expression).
+/// Dictionaries and Lists are recursively expanded.
///
-/// @param str The expression str
-/// @param[out] err Details of an error that may have occurred
-/// @return The expanded object
-Object vim_eval(String str, Error *err)
+/// On execution error: fails with VimL error, does not update v:errmsg.
+///
+/// @param expr VimL expression string
+/// @param[out] err Error details, if any
+/// @return Evaluation result or expanded object
+Object nvim_eval(String expr, Error *err)
+ FUNC_API_SINCE(1)
{
+ static int recursive = 0; // recursion depth
Object rv = OBJECT_INIT;
- // Evaluate the expression
- try_start();
- typval_T *expr_result = eval_expr((char_u *) str.data, NULL);
- if (!expr_result) {
- api_set_error(err, Exception, _("Failed to evaluate expression"));
+ // `msg_list` controls the collection of abort-causing non-exception errors,
+ // which would otherwise be ignored. This pattern is from do_cmdline().
+ struct msglist **saved_msg_list = msg_list;
+ struct msglist *private_msg_list;
+ msg_list = &private_msg_list;
+ private_msg_list = NULL;
+
+ // Initialize `force_abort` and `suppress_errthrow` at the top level.
+ if (!recursive) {
+ force_abort = false;
+ suppress_errthrow = false;
+ current_exception = NULL;
+ // `did_emsg` is set by emsg(), which cancels execution.
+ did_emsg = false;
}
+ recursive++;
+ try_start();
+
+ typval_T rettv;
+ int ok = eval0((char_u *)expr.data, &rettv, NULL, true);
if (!try_end(err)) {
- // No errors, convert the result
- rv = vim_to_object(expr_result);
+ if (ok == FAIL) {
+ // Should never happen, try_end() should get the error. #8371
+ api_set_error(err, kErrorTypeException, "Failed to evaluate expression");
+ } else {
+ rv = vim_to_object(&rettv);
+ }
}
- // Free the vim object
- free_tv(expr_result);
+ tv_clear(&rettv);
+ msg_list = saved_msg_list; // Restore the exception context.
+ recursive--;
+
return rv;
}
-/// Call the given function with the given arguments stored in an array.
+/// Execute lua code. Parameters (if any) are available as `...` inside the
+/// chunk. The chunk can return a value.
+///
+/// Only statements are executed. To evaluate an expression, prefix it
+/// with `return`: return my_function(...)
///
-/// @param fname Function to call
-/// @param args Functions arguments packed in an Array
-/// @param[out] err Details of an error that may have occurred
+/// @param code lua code to execute
+/// @param args Arguments to the code
+/// @param[out] err Details of an error encountered while parsing
+/// or executing the lua code.
+///
+/// @return Return value of lua code if present or NIL.
+Object nvim_execute_lua(String code, Array args, Error *err)
+ FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY
+{
+ return executor_exec_lua_api(code, args, err);
+}
+
+/// Calls a VimL function.
+///
+/// @param fn Function name
+/// @param args Function arguments
+/// @param self `self` dict, or NULL for non-dict functions
+/// @param[out] err Error details, if any
/// @return Result of the function call
-Object vim_call_function(String fname, Array args, Error *err)
+static Object _call_function(String fn, Array args, dict_T *self, Error *err)
{
+ static int recursive = 0; // recursion depth
Object rv = OBJECT_INIT;
+
if (args.size > MAX_FUNC_ARGS) {
- api_set_error(err, Validation,
- _("Function called with too many arguments."));
+ api_set_error(err, kErrorTypeValidation,
+ "Function called with too many arguments");
return rv;
}
@@ -198,54 +373,168 @@ Object vim_call_function(String fname, Array args, Error *err)
}
}
+ // `msg_list` controls the collection of abort-causing non-exception errors,
+ // which would otherwise be ignored. This pattern is from do_cmdline().
+ struct msglist **saved_msg_list = msg_list;
+ struct msglist *private_msg_list;
+ msg_list = &private_msg_list;
+ private_msg_list = NULL;
+
+ // Initialize `force_abort` and `suppress_errthrow` at the top level.
+ if (!recursive) {
+ force_abort = false;
+ suppress_errthrow = false;
+ current_exception = NULL;
+ // `did_emsg` is set by emsg(), which cancels execution.
+ did_emsg = false;
+ }
+ recursive++;
try_start();
- // Call the function
typval_T rettv;
int dummy;
- int r = call_func((char_u *) fname.data, (int) fname.size,
- &rettv, (int) args.size, vim_args,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy,
- true,
- NULL);
- if (r == FAIL) {
- api_set_error(err, Exception, _("Error calling function."));
- }
+ // call_func() retval is deceptive, ignore it. Instead we set `msg_list`
+ // (see above) to capture abort-causing non-exception errors.
+ (void)call_func((char_u *)fn.data, (int)fn.size, &rettv, (int)args.size,
+ vim_args, NULL, curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &dummy, true, NULL, self);
if (!try_end(err)) {
rv = vim_to_object(&rettv);
}
- clear_tv(&rettv);
+ tv_clear(&rettv);
+ msg_list = saved_msg_list; // Restore the exception context.
+ recursive--;
free_vim_args:
while (i > 0) {
- clear_tv(&vim_args[--i]);
+ tv_clear(&vim_args[--i]);
+ }
+
+ return rv;
+}
+
+/// Calls a VimL function with the given arguments.
+///
+/// On execution error: fails with VimL error, does not update v:errmsg.
+///
+/// @param fn Function to call
+/// @param args Function arguments packed in an Array
+/// @param[out] err Error details, if any
+/// @return Result of the function call
+Object nvim_call_function(String fn, Array args, Error *err)
+ FUNC_API_SINCE(1)
+{
+ return _call_function(fn, args, NULL, err);
+}
+
+/// Calls a VimL |Dictionary-function| with the given arguments.
+///
+/// On execution error: fails with VimL error, does not update v:errmsg.
+///
+/// @param dict Dictionary, or String evaluating to a VimL |self| dict
+/// @param fn Name of the function defined on the VimL dict
+/// @param args Function arguments packed in an Array
+/// @param[out] err Error details, if any
+/// @return Result of the function call
+Object nvim_call_dict_function(Object dict, String fn, Array args, Error *err)
+ FUNC_API_SINCE(4)
+{
+ Object rv = OBJECT_INIT;
+
+ typval_T rettv;
+ bool mustfree = false;
+ switch (dict.type) {
+ case kObjectTypeString: {
+ try_start();
+ if (eval0((char_u *)dict.data.string.data, &rettv, NULL, true) == FAIL) {
+ api_set_error(err, kErrorTypeException,
+ "Failed to evaluate dict expression");
+ }
+ if (try_end(err)) {
+ return rv;
+ }
+ // Evaluation of the string arg created a new dict or increased the
+ // refcount of a dict. Not necessary for a RPC dict.
+ mustfree = true;
+ break;
+ }
+ case kObjectTypeDictionary: {
+ if (!object_to_vim(dict, &rettv, err)) {
+ goto end;
+ }
+ break;
+ }
+ default: {
+ api_set_error(err, kErrorTypeValidation,
+ "dict argument type must be String or Dictionary");
+ return rv;
+ }
+ }
+ dict_T *self_dict = rettv.vval.v_dict;
+ if (rettv.v_type != VAR_DICT || !self_dict) {
+ api_set_error(err, kErrorTypeValidation, "dict not found");
+ goto end;
+ }
+
+ if (fn.data && fn.size > 0 && dict.type != kObjectTypeDictionary) {
+ dictitem_T *const di = tv_dict_find(self_dict, fn.data, (ptrdiff_t)fn.size);
+ if (di == NULL) {
+ api_set_error(err, kErrorTypeValidation, "Not found: %s", fn.data);
+ goto end;
+ }
+ if (di->di_tv.v_type == VAR_PARTIAL) {
+ api_set_error(err, kErrorTypeValidation,
+ "partial function not supported");
+ goto end;
+ }
+ if (di->di_tv.v_type != VAR_FUNC) {
+ api_set_error(err, kErrorTypeValidation, "Not a function: %s", fn.data);
+ goto end;
+ }
+ fn = (String) {
+ .data = (char *)di->di_tv.vval.v_string,
+ .size = strlen((char *)di->di_tv.vval.v_string),
+ };
+ }
+
+ if (!fn.data || fn.size < 1) {
+ api_set_error(err, kErrorTypeValidation, "Invalid (empty) function name");
+ goto end;
+ }
+
+ rv = _call_function(fn, args, self_dict, err);
+end:
+ if (mustfree) {
+ tv_clear(&rettv);
}
return rv;
}
-/// Calculates the number of display cells `str` occupies, tab is counted as
-/// one cell.
+/// Calculates the number of display cells occupied by `text`.
+/// <Tab> counts as one cell.
///
-/// @param str Some text
-/// @param[out] err Details of an error that may have occurred
-/// @return The number of cells
-Integer vim_strwidth(String str, Error *err)
+/// @param text Some text
+/// @param[out] err Error details, if any
+/// @return Number of cells
+Integer nvim_strwidth(String text, Error *err)
+ FUNC_API_SINCE(1)
{
- if (str.size > INT_MAX) {
- api_set_error(err, Validation, _("String length is too high"));
+ if (text.size > INT_MAX) {
+ api_set_error(err, kErrorTypeValidation, "String is too long");
return 0;
}
- return (Integer) mb_string2cells((char_u *) str.data);
+ return (Integer)mb_string2cells((char_u *)text.data);
}
-/// Gets a list of paths contained in 'runtimepath'
+/// Gets the paths contained in 'runtimepath'.
///
-/// @return The list of paths
-ArrayOf(String) vim_list_runtime_paths(void)
+/// @return List of paths
+ArrayOf(String) nvim_list_runtime_paths(void)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
- uint8_t *rtp = p_rtp;
+ char_u *rtp = p_rtp;
if (*rtp == NUL) {
// No paths
@@ -259,13 +548,14 @@ ArrayOf(String) vim_list_runtime_paths(void)
}
rtp++;
}
+ rv.size++;
// Allocate memory for the copies
- rv.items = xmalloc(sizeof(Object) * rv.size);
+ rv.items = xmalloc(sizeof(*rv.items) * rv.size);
// Reset the position
rtp = p_rtp;
// Start copying
- for (size_t i = 0; i < rv.size && *rtp != NUL; i++) {
+ for (size_t i = 0; i < rv.size; i++) {
rv.items[i].type = kObjectTypeString;
rv.items[i].data.string.data = xmalloc(MAXPATHL);
// Copy the path from 'runtimepath' to rv.items[i]
@@ -279,26 +569,27 @@ ArrayOf(String) vim_list_runtime_paths(void)
return rv;
}
-/// Changes Vim working directory
+/// Changes the global working directory.
///
-/// @param dir The new working directory
-/// @param[out] err Details of an error that may have occurred
-void vim_change_directory(String dir, Error *err)
+/// @param dir Directory path
+/// @param[out] err Error details, if any
+void nvim_set_current_dir(String dir, Error *err)
+ FUNC_API_SINCE(1)
{
if (dir.size >= MAXPATHL) {
- api_set_error(err, Validation, _("Directory string is too long"));
+ api_set_error(err, kErrorTypeValidation, "Directory name is too long");
return;
}
char string[MAXPATHL];
- strncpy(string, dir.data, dir.size);
+ memcpy(string, dir.data, dir.size);
string[dir.size] = NUL;
try_start();
- if (vim_chdir((char_u *)string)) {
+ if (vim_chdir((char_u *)string, kCdScopeGlobal)) {
if (!try_end(err)) {
- api_set_error(err, Exception, _("Failed to change directory"));
+ api_set_error(err, kErrorTypeException, "Failed to change directory");
}
return;
}
@@ -309,127 +600,166 @@ void vim_change_directory(String dir, Error *err)
/// Gets the current line
///
-/// @param[out] err Details of an error that may have occurred
-/// @return The current line string
-String vim_get_current_line(Error *err)
+/// @param[out] err Error details, if any
+/// @return Current line string
+String nvim_get_current_line(Error *err)
+ FUNC_API_SINCE(1)
{
return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err);
}
/// Sets the current line
///
-/// @param line The line contents
-/// @param[out] err Details of an error that may have occurred
-void vim_set_current_line(String line, Error *err)
+/// @param line Line contents
+/// @param[out] err Error details, if any
+void nvim_set_current_line(String line, Error *err)
+ FUNC_API_SINCE(1)
{
buffer_set_line(curbuf->handle, curwin->w_cursor.lnum - 1, line, err);
}
/// Deletes the current line
///
-/// @param[out] err Details of an error that may have occurred
-void vim_del_current_line(Error *err)
+/// @param[out] err Error details, if any
+void nvim_del_current_line(Error *err)
+ FUNC_API_SINCE(1)
{
buffer_del_line(curbuf->handle, curwin->w_cursor.lnum - 1, err);
}
-/// Gets a global variable
+/// Gets a global (g:) variable
///
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The variable value
-Object vim_get_var(String name, Error *err)
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Variable value
+Object nvim_get_var(String name, Error *err)
+ FUNC_API_SINCE(1)
{
return dict_get_value(&globvardict, name, err);
}
-/// Sets a global variable
+/// Sets a global (g:) variable
///
-/// @param name The variable name
-/// @param value The variable value
-/// @param[out] err Details of an error that may have occurred
-/// @return The old value or nil if there was no previous value.
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+void nvim_set_var(String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
+{
+ dict_set_var(&globvardict, name, value, false, false, err);
+}
+
+/// Removes a global (g:) variable
///
-/// @warning It may return nil if there was no previous value
-/// or if previous value was `v:null`.
+/// @param name Variable name
+/// @param[out] err Error details, if any
+void nvim_del_var(String name, Error *err)
+ FUNC_API_SINCE(1)
+{
+ dict_set_var(&globvardict, name, NIL, true, false, err);
+}
+
+/// @deprecated
+/// @see nvim_set_var
+/// @return Old value or nil if there was no previous value.
+/// @warning May return nil if there was no previous value
+/// OR if previous value was `v:null`.
Object vim_set_var(String name, Object value, Error *err)
{
- return dict_set_value(&globvardict, name, value, false, err);
+ return dict_set_var(&globvardict, name, value, false, true, err);
}
-/// Removes a global variable
-///
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The old value or nil if there was no previous value.
-///
-/// @warning It may return nil if there was no previous value
-/// or if previous value was `v:null`.
+/// @deprecated
+/// @see nvim_del_var
Object vim_del_var(String name, Error *err)
{
- return dict_set_value(&globvardict, name, NIL, true, err);
+ return dict_set_var(&globvardict, name, NIL, true, true, err);
}
-/// Gets a vim variable
+/// Gets a v: variable
///
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The variable value
-Object vim_get_vvar(String name, Error *err)
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Variable value
+Object nvim_get_vvar(String name, Error *err)
+ FUNC_API_SINCE(1)
{
return dict_get_value(&vimvardict, name, err);
}
+/// Sets a v: variable, if it is not readonly
+///
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+void nvim_set_vvar(String name, Object value, Error *err)
+ FUNC_API_SINCE(6)
+{
+ dict_set_var(&vimvardict, name, value, false, false, err);
+}
+
/// Gets an option value string
///
-/// @param name The option name
-/// @param[out] err Details of an error that may have occurred
-/// @return The option value
-Object vim_get_option(String name, Error *err)
+/// @param name Option name
+/// @param[out] err Error details, if any
+/// @return Option value (global)
+Object nvim_get_option(String name, Error *err)
+ FUNC_API_SINCE(1)
{
return get_option_from(NULL, SREQ_GLOBAL, name, err);
}
/// Sets an option value
///
-/// @param name The option name
-/// @param value The new option value
-/// @param[out] err Details of an error that may have occurred
-void vim_set_option(String name, Object value, Error *err)
+/// @param name Option name
+/// @param value New option value
+/// @param[out] err Error details, if any
+void nvim_set_option(uint64_t channel_id, String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
- set_option_to(NULL, SREQ_GLOBAL, name, value, err);
+ set_option_to(channel_id, NULL, SREQ_GLOBAL, name, value, err);
}
-/// Writes a message to vim output buffer
+/// Writes a message to the Vim output buffer. Does not append "\n", the
+/// message is buffered (won't display) until a linefeed is written.
///
-/// @param str The message
-void vim_out_write(String str)
+/// @param str Message
+void nvim_out_write(String str)
+ FUNC_API_SINCE(1)
{
write_msg(str, false);
}
-/// Writes a message to vim error buffer
+/// Writes a message to the Vim error buffer. Does not append "\n", the
+/// message is buffered (won't display) until a linefeed is written.
///
-/// @param str The message
-void vim_err_write(String str)
+/// @param str Message
+void nvim_err_write(String str)
+ FUNC_API_SINCE(1)
{
write_msg(str, true);
}
-/// Higher level error reporting function that ensures all str contents
-/// are written by sending a trailing linefeed to `vim_err_write`
+/// Writes a message to the Vim error buffer. Appends "\n", so the buffer is
+/// flushed (and displayed).
///
-/// @param str The message
-void vim_report_error(String str)
+/// @param str Message
+/// @see nvim_err_write()
+void nvim_err_writeln(String str)
+ FUNC_API_SINCE(1)
{
- vim_err_write(str);
- vim_err_write((String) {.data = "\n", .size = 1});
+ nvim_err_write(str);
+ nvim_err_write((String) { .data = "\n", .size = 1 });
}
/// Gets the current list of buffer handles
///
-/// @return The number of buffers
-ArrayOf(Buffer) vim_get_buffers(void)
+/// Includes unlisted (unloaded/deleted) buffers, like `:ls!`.
+/// Use |nvim_buf_is_loaded()| to check if a buffer is loaded.
+///
+/// @return List of buffer handles
+ArrayOf(Buffer) nvim_list_bufs(void)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
@@ -449,17 +779,19 @@ ArrayOf(Buffer) vim_get_buffers(void)
/// Gets the current buffer
///
-/// @reqturn The buffer handle
-Buffer vim_get_current_buffer(void)
+/// @return Buffer handle
+Buffer nvim_get_current_buf(void)
+ FUNC_API_SINCE(1)
{
return curbuf->handle;
}
/// Sets the current buffer
///
-/// @param id The buffer handle
-/// @param[out] err Details of an error that may have occurred
-void vim_set_current_buffer(Buffer buffer, Error *err)
+/// @param buffer Buffer handle
+/// @param[out] err Error details, if any
+void nvim_set_current_buf(Buffer buffer, Error *err)
+ FUNC_API_SINCE(1)
{
buf_T *buf = find_buffer_by_handle(buffer, err);
@@ -471,16 +803,17 @@ void vim_set_current_buffer(Buffer buffer, Error *err)
int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
if (!try_end(err) && result == FAIL) {
api_set_error(err,
- Exception,
- _("Failed to switch to buffer %" PRIu64),
+ kErrorTypeException,
+ "Failed to switch to buffer %d",
buffer);
}
}
/// Gets the current list of window handles
///
-/// @return The number of windows
-ArrayOf(Window) vim_get_windows(void)
+/// @return List of window handles
+ArrayOf(Window) nvim_list_wins(void)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
@@ -500,16 +833,18 @@ ArrayOf(Window) vim_get_windows(void)
/// Gets the current window
///
-/// @return The window handle
-Window vim_get_current_window(void)
+/// @return Window handle
+Window nvim_get_current_win(void)
+ FUNC_API_SINCE(1)
{
return curwin->handle;
}
/// Sets the current window
///
-/// @param handle The window handle
-void vim_set_current_window(Window window, Error *err)
+/// @param window Window handle
+void nvim_set_current_win(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -521,16 +856,17 @@ void vim_set_current_window(Window window, Error *err)
goto_tabpage_win(win_find_tabpage(win), win);
if (!try_end(err) && win != curwin) {
api_set_error(err,
- Exception,
- _("Failed to switch to window %" PRIu64),
+ kErrorTypeException,
+ "Failed to switch to window %d",
window);
}
}
/// Gets the current list of tabpage handles
///
-/// @return The number of tab pages
-ArrayOf(Tabpage) vim_get_tabpages(void)
+/// @return List of tabpage handles
+ArrayOf(Tabpage) nvim_list_tabpages(void)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
@@ -548,19 +884,21 @@ ArrayOf(Tabpage) vim_get_tabpages(void)
return rv;
}
-/// Gets the current tab page
+/// Gets the current tabpage
///
-/// @return The tab page handle
-Tabpage vim_get_current_tabpage(void)
+/// @return Tabpage handle
+Tabpage nvim_get_current_tabpage(void)
+ FUNC_API_SINCE(1)
{
return curtab->handle;
}
-/// Sets the current tab page
+/// Sets the current tabpage
///
-/// @param handle The tab page handle
-/// @param[out] err Details of an error that may have occurred
-void vim_set_current_tabpage(Tabpage tabpage, Error *err)
+/// @param tabpage Tabpage handle
+/// @param[out] err Error details, if any
+void nvim_set_current_tabpage(Tabpage tabpage, Error *err)
+ FUNC_API_SINCE(1)
{
tabpage_T *tp = find_tab_by_handle(tabpage, err);
@@ -572,30 +910,75 @@ void vim_set_current_tabpage(Tabpage tabpage, Error *err)
goto_tabpage_tp(tp, true, true);
if (!try_end(err) && tp != curtab) {
api_set_error(err,
- Exception,
- _("Failed to switch to tabpage %" PRIu64),
+ kErrorTypeException,
+ "Failed to switch to tabpage %d",
tabpage);
}
}
+/// Creates a new namespace, or gets an existing one
+///
+/// Namespaces are used for buffer highlights and virtual text, see
+/// |nvim_buf_add_highlight()| and |nvim_buf_set_virtual_text()|.
+///
+/// Namespaces can be named or anonymous. If `name` matches an existing
+/// namespace, the associated id is returned. If `name` is an empty string
+/// a new, anonymous namespace is created.
+///
+/// @param name Namespace name or empty string
+/// @return Namespace id
+Integer nvim_create_namespace(String name)
+ FUNC_API_SINCE(5)
+{
+ handle_T id = map_get(String, handle_T)(namespace_ids, name);
+ if (id > 0) {
+ return id;
+ }
+ id = next_namespace_id++;
+ if (name.size > 0) {
+ String name_alloc = copy_string(name);
+ map_put(String, handle_T)(namespace_ids, name_alloc, id);
+ }
+ return (Integer)id;
+}
+
+/// Gets existing, non-anonymous namespaces
+///
+/// @return dict that maps from names to namespace ids.
+Dictionary nvim_get_namespaces(void)
+ FUNC_API_SINCE(5)
+{
+ Dictionary retval = ARRAY_DICT_INIT;
+ String name;
+ handle_T id;
+
+ map_foreach(namespace_ids, name, id, {
+ PUT(retval, name.data, INTEGER_OBJ(id));
+ })
+
+ return retval;
+}
+
/// Subscribes to event broadcasts
///
-/// @param channel_id The channel id (passed automatically by the dispatcher)
-/// @param event The event type string
-void vim_subscribe(uint64_t channel_id, String event)
+/// @param channel_id Channel id (passed automatically by the dispatcher)
+/// @param event Event type string
+void nvim_subscribe(uint64_t channel_id, String event)
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
size_t length = (event.size < METHOD_MAXLEN ? event.size : METHOD_MAXLEN);
char e[METHOD_MAXLEN + 1];
memcpy(e, event.data, length);
e[length] = NUL;
- channel_subscribe(channel_id, e);
+ rpc_subscribe(channel_id, e);
}
/// Unsubscribes to event broadcasts
///
-/// @param channel_id The channel id (passed automatically by the dispatcher)
-/// @param event The event type string
-void vim_unsubscribe(uint64_t channel_id, String event)
+/// @param channel_id Channel id (passed automatically by the dispatcher)
+/// @param event Event type string
+void nvim_unsubscribe(uint64_t channel_id, String event)
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
{
size_t length = (event.size < METHOD_MAXLEN ?
event.size :
@@ -603,15 +986,17 @@ void vim_unsubscribe(uint64_t channel_id, String event)
char e[METHOD_MAXLEN + 1];
memcpy(e, event.data, length);
e[length] = NUL;
- channel_unsubscribe(channel_id, e);
+ rpc_unsubscribe(channel_id, e);
}
-Integer vim_name_to_color(String name)
+Integer nvim_get_color_by_name(String name)
+ FUNC_API_SINCE(1)
{
- return name_to_color((uint8_t *)name.data);
+ return name_to_color((char_u *)name.data);
}
-Dictionary vim_get_color_map(void)
+Dictionary nvim_get_color_map(void)
+ FUNC_API_SINCE(1)
{
Dictionary colors = ARRAY_DICT_INIT;
@@ -623,8 +1008,55 @@ Dictionary vim_get_color_map(void)
}
-Array vim_get_api_info(uint64_t channel_id)
- FUNC_API_ASYNC
+/// Gets the current mode. |mode()|
+/// "blocking" is true if Nvim is waiting for input.
+///
+/// @returns Dictionary { "mode": String, "blocking": Boolean }
+Dictionary nvim_get_mode(void)
+ FUNC_API_SINCE(2) FUNC_API_ASYNC
+{
+ Dictionary rv = ARRAY_DICT_INIT;
+ char *modestr = get_mode();
+ bool blocked = input_blocking();
+
+ PUT(rv, "mode", STRING_OBJ(cstr_as_string(modestr)));
+ PUT(rv, "blocking", BOOLEAN_OBJ(blocked));
+
+ return rv;
+}
+
+/// Gets a list of global (non-buffer-local) |mapping| definitions.
+///
+/// @param mode Mode short-name ("n", "i", "v", ...)
+/// @returns Array of maparg()-like dictionaries describing mappings.
+/// The "buffer" key is always zero.
+ArrayOf(Dictionary) nvim_get_keymap(String mode)
+ FUNC_API_SINCE(3)
+{
+ return keymap_array(mode, NULL);
+}
+
+/// Gets a map of global (non-buffer-local) Ex commands.
+///
+/// Currently only |user-commands| are supported, not builtin Ex commands.
+///
+/// @param opts Optional parameters. Currently only supports
+/// {"builtin":false}
+/// @param[out] err Error details, if any.
+///
+/// @returns Map of maps describing commands.
+Dictionary nvim_get_commands(Dictionary opts, Error *err)
+ FUNC_API_SINCE(4)
+{
+ return nvim_buf_get_commands(-1, opts, err);
+}
+
+/// Returns a 2-tuple (Array), where item 0 is the current channel id and item
+/// 1 is the |api-metadata| map (Dictionary).
+///
+/// @returns 2-tuple [{channel-id}, {api-metadata}]
+Array nvim_get_api_info(uint64_t channel_id)
+ FUNC_API_SINCE(1) FUNC_API_ASYNC FUNC_API_REMOTE_ONLY
{
Array rv = ARRAY_DICT_INIT;
@@ -635,13 +1067,674 @@ Array vim_get_api_info(uint64_t channel_id)
return rv;
}
+/// Identify the client for nvim. Can be called more than once, but subsequent
+/// calls will remove earlier info, which should be resent if it is still
+/// valid. (This could happen if a library first identifies the channel, and a
+/// plugin using that library later overrides that info)
+///
+/// @param name short name for the connected client
+/// @param version Dictionary describing the version, with the following
+/// possible keys (all optional)
+/// - "major" major version (defaults to 0 if not set, for no release yet)
+/// - "minor" minor version
+/// - "patch" patch number
+/// - "prerelease" string describing a prerelease, like "dev" or "beta1"
+/// - "commit" hash or similar identifier of commit
+/// @param type Must be one of the following values. A client library should
+/// use "remote" if the library user hasn't specified other value.
+/// - "remote" remote client that connected to nvim.
+/// - "ui" gui frontend
+/// - "embedder" application using nvim as a component, for instance
+/// IDE/editor implementing a vim mode.
+/// - "host" plugin host, typically started by nvim
+/// - "plugin" single plugin, started by nvim
+/// @param methods Builtin methods in the client. For a host, this does not
+/// include plugin methods which will be discovered later.
+/// The key should be the method name, the values are dicts with
+/// the following (optional) keys:
+/// - "async" if true, send as a notification. If false or unspecified,
+/// use a blocking request
+/// - "nargs" Number of arguments. Could be a single integer or an array
+/// two integers, minimum and maximum inclusive.
+/// Further keys might be added in later versions of nvim and unknown keys
+/// are thus ignored. Clients must only use keys defined in this or later
+/// versions of nvim!
+///
+/// @param attributes Informal attributes describing the client. Clients might
+/// define their own keys, but the following are suggested:
+/// - "website" Website of client (for instance github repository)
+/// - "license" Informal description of the license, such as "Apache 2",
+/// "GPLv3" or "MIT"
+/// - "logo" URI or path to image, preferably small logo or icon.
+/// .png or .svg format is preferred.
+///
+void nvim_set_client_info(uint64_t channel_id, String name,
+ Dictionary version, String type,
+ Dictionary methods, Dictionary attributes,
+ Error *err)
+ FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
+{
+ Dictionary info = ARRAY_DICT_INIT;
+ PUT(info, "name", copy_object(STRING_OBJ(name)));
+
+ version = copy_dictionary(version);
+ bool has_major = false;
+ for (size_t i = 0; i < version.size; i++) {
+ if (strequal(version.items[i].key.data, "major")) {
+ has_major = true;
+ break;
+ }
+ }
+ if (!has_major) {
+ PUT(version, "major", INTEGER_OBJ(0));
+ }
+ PUT(info, "version", DICTIONARY_OBJ(version));
+
+ PUT(info, "type", copy_object(STRING_OBJ(type)));
+ PUT(info, "methods", DICTIONARY_OBJ(copy_dictionary(methods)));
+ PUT(info, "attributes", DICTIONARY_OBJ(copy_dictionary(attributes)));
+
+ rpc_set_client_info(channel_id, info);
+}
+
+/// Get information about a channel.
+///
+/// @returns a Dictionary, describing a channel with the
+/// following keys:
+/// - "stream" the stream underlying the channel
+/// - "stdio" stdin and stdout of this Nvim instance
+/// - "stderr" stderr of this Nvim instance
+/// - "socket" TCP/IP socket or named pipe
+/// - "job" job with communication over its stdio
+/// - "mode" how data received on the channel is interpreted
+/// - "bytes" send and recieve raw bytes
+/// - "terminal" a |terminal| instance interprets ASCII sequences
+/// - "rpc" |RPC| communication on the channel is active
+/// - "pty" Name of pseudoterminal, if one is used (optional).
+/// On a POSIX system, this will be a device path like
+/// /dev/pts/1. Even if the name is unknown, the key will
+/// still be present to indicate a pty is used. This is
+/// currently the case when using winpty on windows.
+/// - "buffer" buffer with connected |terminal| instance (optional)
+/// - "client" information about the client on the other end of the
+/// RPC channel, if it has added it using
+/// |nvim_set_client_info()|. (optional)
+///
+Dictionary nvim_get_chan_info(Integer chan, Error *err)
+ FUNC_API_SINCE(4)
+{
+ if (chan < 0) {
+ return (Dictionary)ARRAY_DICT_INIT;
+ }
+ return channel_info((uint64_t)chan);
+}
+
+/// Get information about all open channels.
+///
+/// @returns Array of Dictionaries, each describing a channel with
+/// the format specified at |nvim_get_chan_info()|.
+Array nvim_list_chans(void)
+ FUNC_API_SINCE(4)
+{
+ return channel_all_info();
+}
+
+/// Calls many API methods atomically.
+///
+/// This has two main usages:
+/// 1. To perform several requests from an async context atomically, i.e.
+/// without interleaving redraws, RPC requests from other clients, or user
+/// interactions (however API methods may trigger autocommands or event
+/// processing which have such side-effects, e.g. |:sleep| may wake timers).
+/// 2. To minimize RPC overhead (roundtrips) of a sequence of many requests.
+///
+/// @param calls an array of calls, where each call is described by an array
+/// with two elements: the request name, and an array of arguments.
+/// @param[out] err Details of a validation error of the nvim_multi_request call
+/// itself, i.e. malformed `calls` parameter. Errors from called methods will
+/// be indicated in the return value, see below.
+///
+/// @return an array with two elements. The first is an array of return
+/// values. The second is NIL if all calls succeeded. If a call resulted in
+/// an error, it is a three-element array with the zero-based index of the call
+/// which resulted in an error, the error type and the error message. If an
+/// error occurred, the values from all preceding calls will still be returned.
+Array nvim_call_atomic(uint64_t channel_id, Array calls, Error *err)
+ FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY
+{
+ Array rv = ARRAY_DICT_INIT;
+ Array results = ARRAY_DICT_INIT;
+ Error nested_error = ERROR_INIT;
+
+ size_t i; // also used for freeing the variables
+ for (i = 0; i < calls.size; i++) {
+ if (calls.items[i].type != kObjectTypeArray) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "Items in calls array must be arrays");
+ goto validation_error;
+ }
+ Array call = calls.items[i].data.array;
+ if (call.size != 2) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "Items in calls array must be arrays of size 2");
+ goto validation_error;
+ }
+
+ if (call.items[0].type != kObjectTypeString) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "Name must be String");
+ goto validation_error;
+ }
+ String name = call.items[0].data.string;
+
+ if (call.items[1].type != kObjectTypeArray) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "Args must be Array");
+ goto validation_error;
+ }
+ Array args = call.items[1].data.array;
+
+ MsgpackRpcRequestHandler handler =
+ msgpack_rpc_get_handler_for(name.data,
+ name.size,
+ &nested_error);
+
+ if (ERROR_SET(&nested_error)) {
+ break;
+ }
+ Object result = handler.fn(channel_id, args, &nested_error);
+ if (ERROR_SET(&nested_error)) {
+ // error handled after loop
+ break;
+ }
+
+ ADD(results, result);
+ }
+
+ ADD(rv, ARRAY_OBJ(results));
+ if (ERROR_SET(&nested_error)) {
+ Array errval = ARRAY_DICT_INIT;
+ ADD(errval, INTEGER_OBJ((Integer)i));
+ ADD(errval, INTEGER_OBJ(nested_error.type));
+ ADD(errval, STRING_OBJ(cstr_to_string(nested_error.msg)));
+ ADD(rv, ARRAY_OBJ(errval));
+ } else {
+ ADD(rv, NIL);
+ }
+ goto theend;
+
+validation_error:
+ api_free_array(results);
+theend:
+ api_clear_error(&nested_error);
+ return rv;
+}
+
+typedef struct {
+ ExprASTNode **node_p;
+ Object *ret_node_p;
+} ExprASTConvStackItem;
+
+/// @cond DOXYGEN_NOT_A_FUNCTION
+typedef kvec_withinit_t(ExprASTConvStackItem, 16) ExprASTConvStack;
+/// @endcond
+
+/// Parse a VimL expression
+///
+/// @param[in] expr Expression to parse. Is always treated as a single line.
+/// @param[in] flags Flags:
+///
+/// - "m" if multiple expressions in a row are allowed (only
+/// the first one will be parsed),
+/// - "E" if EOC tokens are not allowed (determines whether
+/// they will stop parsing process or be recognized as an
+/// operator/space, though also yielding an error).
+/// - "l" when needing to start parsing with lvalues for
+/// ":let" or ":for".
+///
+/// Common flag sets:
+/// - "m" to parse like for ":echo".
+/// - "E" to parse like for "<C-r>=".
+/// - empty string for ":call".
+/// - "lm" to parse for ":let".
+/// @param[in] highlight If true, return value will also include "highlight"
+/// key containing array of 4-tuples (arrays) (Integer,
+/// Integer, Integer, String), where first three numbers
+/// define the highlighted region and represent line,
+/// starting column and ending column (latter exclusive:
+/// one should highlight region [start_col, end_col)).
+///
+/// @return AST: top-level dictionary with these keys:
+///
+/// "error": Dictionary with error, present only if parser saw some
+/// error. Contains the following keys:
+///
+/// "message": String, error message in printf format, translated.
+/// Must contain exactly one "%.*s".
+/// "arg": String, error message argument.
+///
+/// "len": Amount of bytes successfully parsed. With flags equal to ""
+/// that should be equal to the length of expr string.
+///
+/// @note: “Sucessfully parsed†here means “participated in AST
+/// creationâ€, not “till the first errorâ€.
+///
+/// "ast": AST, either nil or a dictionary with these keys:
+///
+/// "type": node type, one of the value names from ExprASTNodeType
+/// stringified without "kExprNode" prefix.
+/// "start": a pair [line, column] describing where node is “startedâ€
+/// where "line" is always 0 (will not be 0 if you will be
+/// using nvim_parse_viml() on e.g. ":let", but that is not
+/// present yet). Both elements are Integers.
+/// "len": “length†of the node. This and "start" are there for
+/// debugging purposes primary (debugging parser and providing
+/// debug information).
+/// "children": a list of nodes described in top/"ast". There always
+/// is zero, one or two children, key will not be present
+/// if node has no children. Maximum number of children
+/// may be found in node_maxchildren array.
+///
+/// Local values (present only for certain nodes):
+///
+/// "scope": a single Integer, specifies scope for "Option" and
+/// "PlainIdentifier" nodes. For "Option" it is one of
+/// ExprOptScope values, for "PlainIdentifier" it is one of
+/// ExprVarScope values.
+/// "ident": identifier (without scope, if any), present for "Option",
+/// "PlainIdentifier", "PlainKey" and "Environment" nodes.
+/// "name": Integer, register name (one character) or -1. Only present
+/// for "Register" nodes.
+/// "cmp_type": String, comparison type, one of the value names from
+/// ExprComparisonType, stringified without "kExprCmp"
+/// prefix. Only present for "Comparison" nodes.
+/// "ccs_strategy": String, case comparison strategy, one of the
+/// value names from ExprCaseCompareStrategy,
+/// stringified without "kCCStrategy" prefix. Only
+/// present for "Comparison" nodes.
+/// "augmentation": String, augmentation type for "Assignment" nodes.
+/// Is either an empty string, "Add", "Subtract" or
+/// "Concat" for "=", "+=", "-=" or ".=" respectively.
+/// "invert": Boolean, true if result of comparison needs to be
+/// inverted. Only present for "Comparison" nodes.
+/// "ivalue": Integer, integer value for "Integer" nodes.
+/// "fvalue": Float, floating-point value for "Float" nodes.
+/// "svalue": String, value for "SingleQuotedString" and
+/// "DoubleQuotedString" nodes.
+Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
+ Error *err)
+ FUNC_API_SINCE(4) FUNC_API_ASYNC
+{
+ int pflags = 0;
+ for (size_t i = 0 ; i < flags.size ; i++) {
+ switch (flags.data[i]) {
+ case 'm': { pflags |= kExprFlagsMulti; break; }
+ case 'E': { pflags |= kExprFlagsDisallowEOC; break; }
+ case 'l': { pflags |= kExprFlagsParseLet; break; }
+ case NUL: {
+ api_set_error(err, kErrorTypeValidation, "Invalid flag: '\\0' (%u)",
+ (unsigned)flags.data[i]);
+ return (Dictionary)ARRAY_DICT_INIT;
+ }
+ default: {
+ api_set_error(err, kErrorTypeValidation, "Invalid flag: '%c' (%u)",
+ flags.data[i], (unsigned)flags.data[i]);
+ return (Dictionary)ARRAY_DICT_INIT;
+ }
+ }
+ }
+ ParserLine plines[] = {
+ {
+ .data = expr.data,
+ .size = expr.size,
+ .allocated = false,
+ },
+ { NULL, 0, false },
+ };
+ ParserLine *plines_p = plines;
+ ParserHighlight colors;
+ kvi_init(colors);
+ ParserHighlight *const colors_p = (highlight ? &colors : NULL);
+ ParserState pstate;
+ viml_parser_init(
+ &pstate, parser_simple_get_line, &plines_p, colors_p);
+ ExprAST east = viml_pexpr_parse(&pstate, pflags);
+
+ const size_t ret_size = (
+ 2 // "ast", "len"
+ + (size_t)(east.err.msg != NULL) // "error"
+ + (size_t)highlight // "highlight"
+ + 0);
+ Dictionary ret = {
+ .items = xmalloc(ret_size * sizeof(ret.items[0])),
+ .size = 0,
+ .capacity = ret_size,
+ };
+ ret.items[ret.size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ast"),
+ .value = NIL,
+ };
+ ret.items[ret.size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("len"),
+ .value = INTEGER_OBJ((Integer)(pstate.pos.line == 1
+ ? plines[0].size
+ : pstate.pos.col)),
+ };
+ if (east.err.msg != NULL) {
+ Dictionary err_dict = {
+ .items = xmalloc(2 * sizeof(err_dict.items[0])),
+ .size = 2,
+ .capacity = 2,
+ };
+ err_dict.items[0] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("message"),
+ .value = STRING_OBJ(cstr_to_string(east.err.msg)),
+ };
+ if (east.err.arg == NULL) {
+ err_dict.items[1] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("arg"),
+ .value = STRING_OBJ(STRING_INIT),
+ };
+ } else {
+ err_dict.items[1] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("arg"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(east.err.arg, (size_t)east.err.arg_len),
+ .size = (size_t)east.err.arg_len,
+ })),
+ };
+ }
+ ret.items[ret.size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("error"),
+ .value = DICTIONARY_OBJ(err_dict),
+ };
+ }
+ if (highlight) {
+ Array hl = (Array) {
+ .items = xmalloc(kv_size(colors) * sizeof(hl.items[0])),
+ .capacity = kv_size(colors),
+ .size = kv_size(colors),
+ };
+ for (size_t i = 0 ; i < kv_size(colors) ; i++) {
+ const ParserHighlightChunk chunk = kv_A(colors, i);
+ Array chunk_arr = (Array) {
+ .items = xmalloc(4 * sizeof(chunk_arr.items[0])),
+ .capacity = 4,
+ .size = 4,
+ };
+ chunk_arr.items[0] = INTEGER_OBJ((Integer)chunk.start.line);
+ chunk_arr.items[1] = INTEGER_OBJ((Integer)chunk.start.col);
+ chunk_arr.items[2] = INTEGER_OBJ((Integer)chunk.end_col);
+ chunk_arr.items[3] = STRING_OBJ(cstr_to_string(chunk.group));
+ hl.items[i] = ARRAY_OBJ(chunk_arr);
+ }
+ ret.items[ret.size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("highlight"),
+ .value = ARRAY_OBJ(hl),
+ };
+ }
+ kvi_destroy(colors);
+
+ // Walk over the AST, freeing nodes in process.
+ ExprASTConvStack ast_conv_stack;
+ kvi_init(ast_conv_stack);
+ kvi_push(ast_conv_stack, ((ExprASTConvStackItem) {
+ .node_p = &east.root,
+ .ret_node_p = &ret.items[0].value,
+ }));
+ while (kv_size(ast_conv_stack)) {
+ ExprASTConvStackItem cur_item = kv_last(ast_conv_stack);
+ ExprASTNode *const node = *cur_item.node_p;
+ if (node == NULL) {
+ assert(kv_size(ast_conv_stack) == 1);
+ kv_drop(ast_conv_stack, 1);
+ } else {
+ if (cur_item.ret_node_p->type == kObjectTypeNil) {
+ const size_t ret_node_items_size = (size_t)(
+ 3 // "type", "start" and "len"
+ + (node->children != NULL) // "children"
+ + (node->type == kExprNodeOption
+ || node->type == kExprNodePlainIdentifier) // "scope"
+ + (node->type == kExprNodeOption
+ || node->type == kExprNodePlainIdentifier
+ || node->type == kExprNodePlainKey
+ || node->type == kExprNodeEnvironment) // "ident"
+ + (node->type == kExprNodeRegister) // "name"
+ + (3 // "cmp_type", "ccs_strategy", "invert"
+ * (node->type == kExprNodeComparison))
+ + (node->type == kExprNodeInteger) // "ivalue"
+ + (node->type == kExprNodeFloat) // "fvalue"
+ + (node->type == kExprNodeDoubleQuotedString
+ || node->type == kExprNodeSingleQuotedString) // "svalue"
+ + (node->type == kExprNodeAssignment) // "augmentation"
+ + 0);
+ Dictionary ret_node = {
+ .items = xmalloc(ret_node_items_size * sizeof(ret_node.items[0])),
+ .capacity = ret_node_items_size,
+ .size = 0,
+ };
+ *cur_item.ret_node_p = DICTIONARY_OBJ(ret_node);
+ }
+ Dictionary *ret_node = &cur_item.ret_node_p->data.dictionary;
+ if (node->children != NULL) {
+ const size_t num_children = 1 + (node->children->next != NULL);
+ Array children_array = {
+ .items = xmalloc(num_children * sizeof(children_array.items[0])),
+ .capacity = num_children,
+ .size = num_children,
+ };
+ for (size_t i = 0; i < num_children; i++) {
+ children_array.items[i] = NIL;
+ }
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("children"),
+ .value = ARRAY_OBJ(children_array),
+ };
+ kvi_push(ast_conv_stack, ((ExprASTConvStackItem) {
+ .node_p = &node->children,
+ .ret_node_p = &children_array.items[0],
+ }));
+ } else if (node->next != NULL) {
+ kvi_push(ast_conv_stack, ((ExprASTConvStackItem) {
+ .node_p = &node->next,
+ .ret_node_p = cur_item.ret_node_p + 1,
+ }));
+ } else {
+ kv_drop(ast_conv_stack, 1);
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("type"),
+ .value = STRING_OBJ(cstr_to_string(east_node_type_tab[node->type])),
+ };
+ Array start_array = {
+ .items = xmalloc(2 * sizeof(start_array.items[0])),
+ .capacity = 2,
+ .size = 2,
+ };
+ start_array.items[0] = INTEGER_OBJ((Integer)node->start.line);
+ start_array.items[1] = INTEGER_OBJ((Integer)node->start.col);
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("start"),
+ .value = ARRAY_OBJ(start_array),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("len"),
+ .value = INTEGER_OBJ((Integer)node->len),
+ };
+ switch (node->type) {
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeSingleQuotedString: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("svalue"),
+ .value = STRING_OBJ(((String) {
+ .data = node->data.str.value,
+ .size = node->data.str.size,
+ })),
+ };
+ break;
+ }
+ case kExprNodeOption: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("scope"),
+ .value = INTEGER_OBJ(node->data.opt.scope),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.opt.ident,
+ node->data.opt.ident_len),
+ .size = node->data.opt.ident_len,
+ })),
+ };
+ break;
+ }
+ case kExprNodePlainIdentifier: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("scope"),
+ .value = INTEGER_OBJ(node->data.var.scope),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.var.ident,
+ node->data.var.ident_len),
+ .size = node->data.var.ident_len,
+ })),
+ };
+ break;
+ }
+ case kExprNodePlainKey: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.var.ident,
+ node->data.var.ident_len),
+ .size = node->data.var.ident_len,
+ })),
+ };
+ break;
+ }
+ case kExprNodeEnvironment: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ident"),
+ .value = STRING_OBJ(((String) {
+ .data = xmemdupz(node->data.env.ident,
+ node->data.env.ident_len),
+ .size = node->data.env.ident_len,
+ })),
+ };
+ break;
+ }
+ case kExprNodeRegister: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("name"),
+ .value = INTEGER_OBJ(node->data.reg.name),
+ };
+ break;
+ }
+ case kExprNodeComparison: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("cmp_type"),
+ .value = STRING_OBJ(cstr_to_string(
+ eltkn_cmp_type_tab[node->data.cmp.type])),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ccs_strategy"),
+ .value = STRING_OBJ(cstr_to_string(
+ ccs_tab[node->data.cmp.ccs])),
+ };
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("invert"),
+ .value = BOOLEAN_OBJ(node->data.cmp.inv),
+ };
+ break;
+ }
+ case kExprNodeFloat: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("fvalue"),
+ .value = FLOAT_OBJ(node->data.flt.value),
+ };
+ break;
+ }
+ case kExprNodeInteger: {
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("ivalue"),
+ .value = INTEGER_OBJ((Integer)(
+ node->data.num.value > API_INTEGER_MAX
+ ? API_INTEGER_MAX
+ : (Integer)node->data.num.value)),
+ };
+ break;
+ }
+ case kExprNodeAssignment: {
+ const ExprAssignmentType asgn_type = node->data.ass.type;
+ ret_node->items[ret_node->size++] = (KeyValuePair) {
+ .key = STATIC_CSTR_TO_STRING("augmentation"),
+ .value = STRING_OBJ(
+ asgn_type == kExprAsgnPlain
+ ? (String)STRING_INIT
+ : cstr_to_string(expr_asgn_type_tab[asgn_type])),
+ };
+ break;
+ }
+ case kExprNodeMissing:
+ case kExprNodeOpMissing:
+ case kExprNodeTernary:
+ case kExprNodeTernaryValue:
+ case kExprNodeSubscript:
+ case kExprNodeListLiteral:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryPlus:
+ case kExprNodeNested:
+ case kExprNodeCall:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeUnknownFigure:
+ case kExprNodeLambda:
+ case kExprNodeDictLiteral:
+ case kExprNodeCurlyBracesIdentifier:
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ case kExprNodeConcat:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeOr:
+ case kExprNodeAnd:
+ case kExprNodeUnaryMinus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeNot:
+ case kExprNodeMultiplication:
+ case kExprNodeDivision:
+ case kExprNodeMod: {
+ break;
+ }
+ }
+ assert(cur_item.ret_node_p->data.dictionary.size
+ == cur_item.ret_node_p->data.dictionary.capacity);
+ xfree(*cur_item.node_p);
+ *cur_item.node_p = NULL;
+ }
+ }
+ }
+ kvi_destroy(ast_conv_stack);
+
+ assert(ret.size == ret.capacity);
+ // Should be a no-op actually, leaving it in case non-nodes will need to be
+ // freed later.
+ viml_pexpr_free_ast(east);
+ viml_parser_destroy(&pstate);
+ return ret;
+}
+
+
/// Writes a message to vim output or error buffer. The string is split
/// and flushed after each newline. Incomplete lines are kept for writing
/// later.
///
-/// @param message The message to write
-/// @param to_err true if it should be treated as an error message (use
-/// `emsg` instead of `msg` to print each line)
+/// @param message Message to write
+/// @param to_err true: message is an error (uses `emsg` instead of `msg`)
static void write_msg(String message, bool to_err)
{
static size_t out_pos = 0, err_pos = 0;
@@ -650,7 +1743,7 @@ static void write_msg(String message, bool to_err)
#define PUSH_CHAR(i, pos, line_buf, msg) \
if (message.data[i] == NL || pos == LINE_BUFFER_SIZE - 1) { \
line_buf[pos] = NUL; \
- msg((uint8_t *)line_buf); \
+ msg((char_u *)line_buf); \
pos = 0; \
continue; \
} \
@@ -668,3 +1761,216 @@ static void write_msg(String message, bool to_err)
--no_wait_return;
msg_end();
}
+
+// Functions used for testing purposes
+
+/// Returns object given as argument
+///
+/// This API function is used for testing. One should not rely on its presence
+/// in plugins.
+///
+/// @param[in] obj Object to return.
+///
+/// @return its argument.
+Object nvim__id(Object obj)
+{
+ return copy_object(obj);
+}
+
+/// Returns array given as argument
+///
+/// This API function is used for testing. One should not rely on its presence
+/// in plugins.
+///
+/// @param[in] arr Array to return.
+///
+/// @return its argument.
+Array nvim__id_array(Array arr)
+{
+ return copy_object(ARRAY_OBJ(arr)).data.array;
+}
+
+/// Returns dictionary given as argument
+///
+/// This API function is used for testing. One should not rely on its presence
+/// in plugins.
+///
+/// @param[in] dct Dictionary to return.
+///
+/// @return its argument.
+Dictionary nvim__id_dictionary(Dictionary dct)
+{
+ return copy_object(DICTIONARY_OBJ(dct)).data.dictionary;
+}
+
+/// Returns floating-point value given as argument
+///
+/// This API function is used for testing. One should not rely on its presence
+/// in plugins.
+///
+/// @param[in] flt Value to return.
+///
+/// @return its argument.
+Float nvim__id_float(Float flt)
+{
+ return flt;
+}
+
+/// Gets internal stats.
+///
+/// @return Map of various internal stats.
+Dictionary nvim__stats(void)
+{
+ Dictionary rv = ARRAY_DICT_INIT;
+ PUT(rv, "fsync", INTEGER_OBJ(g_stats.fsync));
+ PUT(rv, "redraw", INTEGER_OBJ(g_stats.redraw));
+ return rv;
+}
+
+/// Gets a list of dictionaries representing attached UIs.
+///
+/// @return Array of UI dictionaries
+///
+/// Each dictionary has the following keys:
+/// - "height" requested height of the UI
+/// - "width" requested width of the UI
+/// - "rgb" whether the UI uses rgb colors (false implies cterm colors)
+/// - "ext_..." Requested UI extensions, see |ui-options|
+/// - "chan" Channel id of remote UI (not present for TUI)
+///
+Array nvim_list_uis(void)
+ FUNC_API_SINCE(4)
+{
+ return ui_array();
+}
+
+/// Gets the immediate children of process `pid`.
+///
+/// @return Array of child process ids, empty if process not found.
+Array nvim_get_proc_children(Integer pid, Error *err)
+ FUNC_API_SINCE(4)
+{
+ Array rvobj = ARRAY_DICT_INIT;
+ int *proc_list = NULL;
+
+ if (pid <= 0 || pid > INT_MAX) {
+ api_set_error(err, kErrorTypeException, "Invalid pid: %" PRId64, pid);
+ goto end;
+ }
+
+ size_t proc_count;
+ int rv = os_proc_children((int)pid, &proc_list, &proc_count);
+ if (rv != 0) {
+ // syscall failed (possibly because of kernel options), try shelling out.
+ DLOG("fallback to vim._os_proc_children()");
+ Array a = ARRAY_DICT_INIT;
+ ADD(a, INTEGER_OBJ(pid));
+ String s = cstr_to_string("return vim._os_proc_children(select(1, ...))");
+ Object o = nvim_execute_lua(s, a, err);
+ api_free_string(s);
+ api_free_array(a);
+ if (o.type == kObjectTypeArray) {
+ rvobj = o.data.array;
+ } else if (!ERROR_SET(err)) {
+ api_set_error(err, kErrorTypeException,
+ "Failed to get process children. pid=%" PRId64 " error=%d",
+ pid, rv);
+ }
+ goto end;
+ }
+
+ for (size_t i = 0; i < proc_count; i++) {
+ ADD(rvobj, INTEGER_OBJ(proc_list[i]));
+ }
+
+end:
+ xfree(proc_list);
+ return rvobj;
+}
+
+/// Gets info describing process `pid`.
+///
+/// @return Map of process properties, or NIL if process not found.
+Object nvim_get_proc(Integer pid, Error *err)
+ FUNC_API_SINCE(4)
+{
+ Object rvobj = OBJECT_INIT;
+ rvobj.data.dictionary = (Dictionary)ARRAY_DICT_INIT;
+ rvobj.type = kObjectTypeDictionary;
+
+ if (pid <= 0 || pid > INT_MAX) {
+ api_set_error(err, kErrorTypeException, "Invalid pid: %" PRId64, pid);
+ return NIL;
+ }
+#ifdef WIN32
+ rvobj.data.dictionary = os_proc_info((int)pid);
+ if (rvobj.data.dictionary.size == 0) { // Process not found.
+ return NIL;
+ }
+#else
+ // Cross-platform process info APIs are miserable, so use `ps` instead.
+ Array a = ARRAY_DICT_INIT;
+ ADD(a, INTEGER_OBJ(pid));
+ String s = cstr_to_string("return vim._os_proc_info(select(1, ...))");
+ Object o = nvim_execute_lua(s, a, err);
+ api_free_string(s);
+ api_free_array(a);
+ if (o.type == kObjectTypeArray && o.data.array.size == 0) {
+ return NIL; // Process not found.
+ } else if (o.type == kObjectTypeDictionary) {
+ rvobj.data.dictionary = o.data.dictionary;
+ } else if (!ERROR_SET(err)) {
+ api_set_error(err, kErrorTypeException,
+ "Failed to get process info. pid=%" PRId64, pid);
+ }
+#endif
+ return rvobj;
+}
+
+/// Selects an item in the completion popupmenu
+///
+/// When insert completion is not active, this API call is silently ignored.
+/// It is mostly useful for an external UI using |ui-popupmenu| for instance
+/// to control the popupmenu with the mouse. But it can also be used in an
+/// insert mode mapping, use <cmd> mapping |:map-cmd| to ensure the mapping
+/// doesn't end completion mode.
+///
+/// @param item Index of the item to select, starting with zero. Pass in "-1"
+/// to select no item (restore original text).
+/// @param insert Whether the selection should be inserted in the buffer.
+/// @param finish If true, completion will be finished with this item, and the
+/// popupmenu dissmissed. Implies `insert`.
+void nvim_select_popupmenu_item(Integer item, Boolean insert, Boolean finish,
+ Dictionary opts, Error *err)
+ FUNC_API_SINCE(6)
+{
+ if (opts.size > 0) {
+ api_set_error(err, kErrorTypeValidation, "opts dict isn't empty");
+ return;
+ }
+
+ if (finish) {
+ insert = true;
+ }
+
+ pum_ext_select_item((int)item, insert, finish);
+}
+
+/// NB: if your UI doesn't use hlstate, this will not return hlstate first time
+Array nvim__inspect_cell(Integer row, Integer col, Error *err)
+{
+ Array ret = ARRAY_DICT_INIT;
+ if (row < 0 || row >= default_grid.Rows
+ || col < 0 || col >= default_grid.Columns) {
+ return ret;
+ }
+ size_t off = default_grid.line_offset[(size_t)row] + (size_t)col;
+ ADD(ret, STRING_OBJ(cstr_to_string((char *)default_grid.chars[off])));
+ int attr = default_grid.attrs[off];
+ ADD(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, err)));
+ // will not work first time
+ if (!highlight_use_hlstate()) {
+ ADD(ret, ARRAY_OBJ(hl_inspect(attr)));
+ }
+ return ret;
+}
diff --git a/src/nvim/api/vim.h b/src/nvim/api/vim.h
index 5e0b35b562..d6873da6d2 100644
--- a/src/nvim/api/vim.h
+++ b/src/nvim/api/vim.h
@@ -4,6 +4,10 @@
#include <stdint.h>
#include "nvim/api/private/defs.h"
+#include "nvim/map.h"
+
+EXTERN Map(String, handle_T) *namespace_ids INIT(= NULL);
+EXTERN handle_T next_namespace_id INIT(= 1);
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/vim.h.generated.h"
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index f644453358..33857f95b7 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.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 <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -7,19 +10,20 @@
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/vim.h"
+#include "nvim/buffer.h"
#include "nvim/cursor.h"
#include "nvim/window.h"
#include "nvim/screen.h"
#include "nvim/move.h"
-#include "nvim/misc2.h"
/// Gets the current buffer in a window
///
-/// @param window The window handle
-/// @param[out] err Details of an error that may have occurred
-/// @return The buffer handle
-Buffer window_get_buffer(Window window, Error *err)
+/// @param window Window handle
+/// @param[out] err Error details, if any
+/// @return Buffer handle
+Buffer nvim_win_get_buf(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -30,12 +34,48 @@ Buffer window_get_buffer(Window window, Error *err)
return win->w_buffer->handle;
}
+/// Sets the current buffer in a window, without side-effects
+///
+/// @param window Window handle
+/// @param buffer Buffer handle
+/// @param[out] err Error details, if any
+void nvim_win_set_buf(Window window, Buffer buffer, Error *err)
+ FUNC_API_SINCE(5)
+{
+ win_T *win = find_window_by_handle(window, err), *save_curwin = curwin;
+ buf_T *buf = find_buffer_by_handle(buffer, err);
+ tabpage_T *tab = win_find_tabpage(win), *save_curtab = curtab;
+
+ if (!win || !buf) {
+ return;
+ }
+
+ if (switch_win(&save_curwin, &save_curtab, win, tab, false) == FAIL) {
+ api_set_error(err,
+ kErrorTypeException,
+ "Failed to switch to window %d",
+ window);
+ }
+
+ try_start();
+ int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0);
+ if (!try_end(err) && result == FAIL) {
+ api_set_error(err,
+ kErrorTypeException,
+ "Failed to set buffer %d",
+ buffer);
+ }
+
+ restore_win(save_curwin, save_curtab, false);
+}
+
/// Gets the cursor position in the window
///
-/// @param window The window handle
-/// @param[out] err Details of an error that may have occurred
-/// @return the (row, col) tuple
-ArrayOf(Integer, 2) window_get_cursor(Window window, Error *err)
+/// @param window Window handle
+/// @param[out] err Error details, if any
+/// @return (row, col) tuple
+ArrayOf(Integer, 2) nvim_win_get_cursor(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
win_T *win = find_window_by_handle(window, err);
@@ -50,22 +90,23 @@ ArrayOf(Integer, 2) window_get_cursor(Window window, Error *err)
/// Sets the cursor position in the window
///
-/// @param window The window handle
-/// @param pos the (row, col) tuple representing the new position
-/// @param[out] err Details of an error that may have occurred
-void window_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
+/// @param window Window handle
+/// @param pos (row, col) tuple representing the new position
+/// @param[out] err Error details, if any
+void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
- if (pos.size != 2 || pos.items[0].type != kObjectTypeInteger
- || pos.items[1].type != kObjectTypeInteger) {
- api_set_error(err,
- Validation,
- _("Argument \"pos\" must be a [row, col] array"));
+ if (!win) {
return;
}
- if (!win) {
+ if (pos.size != 2 || pos.items[0].type != kObjectTypeInteger
+ || pos.items[1].type != kObjectTypeInteger) {
+ api_set_error(err,
+ kErrorTypeValidation,
+ "Argument \"pos\" must be a [row, col] array");
return;
}
@@ -73,12 +114,12 @@ void window_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
int64_t col = pos.items[1].data.integer;
if (row <= 0 || row > win->w_buffer->b_ml.ml_line_count) {
- api_set_error(err, Validation, _("Cursor position outside buffer"));
+ api_set_error(err, kErrorTypeValidation, "Cursor position outside buffer");
return;
}
if (col > MAXCOL || col < 0) {
- api_set_error(err, Validation, _("Column value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Column value outside range");
return;
}
@@ -88,18 +129,22 @@ void window_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
// When column is out of range silently correct it.
check_cursor_col_win(win);
+ // 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);
- update_screen(VALID);
+ redraw_win_later(win, VALID);
}
/// Gets the window height
///
-/// @param window The window handle
-/// @param[out] err Details of an error that may have occurred
-/// @return the height in rows
-Integer window_get_height(Window window, Error *err)
+/// @param window Window handle
+/// @param[out] err Error details, if any
+/// @return Height as a count of rows
+Integer nvim_win_get_height(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -113,10 +158,11 @@ Integer window_get_height(Window window, Error *err)
/// Sets the window height. This will only succeed if the screen is split
/// horizontally.
///
-/// @param window The window handle
-/// @param height the new height in rows
-/// @param[out] err Details of an error that may have occurred
-void window_set_height(Window window, Integer height, Error *err)
+/// @param window Window handle
+/// @param height Height as a count of rows
+/// @param[out] err Error details, if any
+void nvim_win_set_height(Window window, Integer height, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -125,7 +171,7 @@ void window_set_height(Window window, Integer height, Error *err)
}
if (height > INT_MAX || height < INT_MIN) {
- api_set_error(err, Validation, _("Height value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Height value outside range");
return;
}
@@ -139,10 +185,11 @@ void window_set_height(Window window, Integer height, Error *err)
/// Gets the window width
///
-/// @param window The window handle
-/// @param[out] err Details of an error that may have occurred
-/// @return the width in columns
-Integer window_get_width(Window window, Error *err)
+/// @param window Window handle
+/// @param[out] err Error details, if any
+/// @return Width as a count of columns
+Integer nvim_win_get_width(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -156,10 +203,11 @@ Integer window_get_width(Window window, Error *err)
/// Sets the window width. This will only succeed if the screen is split
/// vertically.
///
-/// @param window The window handle
-/// @param width the new width in columns
-/// @param[out] err Details of an error that may have occurred
-void window_set_width(Window window, Integer width, Error *err)
+/// @param window Window handle
+/// @param width Width as a count of columns
+/// @param[out] err Error details, if any
+void nvim_win_set_width(Window window, Integer width, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -168,7 +216,7 @@ void window_set_width(Window window, Integer width, Error *err)
}
if (width > INT_MAX || width < INT_MIN) {
- api_set_error(err, Validation, _("Width value outside range"));
+ api_set_error(err, kErrorTypeValidation, "Width value outside range");
return;
}
@@ -182,11 +230,12 @@ void window_set_width(Window window, Integer width, Error *err)
/// Gets a window-scoped (w:) variable
///
-/// @param window The window handle
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The variable value
-Object window_get_var(Window window, String name, Error *err)
+/// @param window Window handle
+/// @param name Variable name
+/// @param[out] err Error details, if any
+/// @return Variable value
+Object nvim_win_get_var(Window window, String name, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -199,11 +248,48 @@ Object window_get_var(Window window, String name, Error *err)
/// Sets a window-scoped (w:) variable
///
-/// @param window The window handle
-/// @param name The variable name
-/// @param value The variable value
-/// @param[out] err Details of an error that may have occurred
-/// @return The old value or nil if there was no previous value.
+/// @param window Window handle
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+void nvim_win_set_var(Window window, String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
+{
+ win_T *win = find_window_by_handle(window, err);
+
+ if (!win) {
+ return;
+ }
+
+ dict_set_var(win->w_vars, name, value, false, false, err);
+}
+
+/// Removes a window-scoped (w:) variable
+///
+/// @param window Window handle
+/// @param name Variable name
+/// @param[out] err Error details, if any
+void nvim_win_del_var(Window window, String name, Error *err)
+ FUNC_API_SINCE(1)
+{
+ win_T *win = find_window_by_handle(window, err);
+
+ if (!win) {
+ return;
+ }
+
+ dict_set_var(win->w_vars, name, NIL, true, false, err);
+}
+
+/// Sets a window-scoped (w:) variable
+///
+/// @deprecated
+///
+/// @param window Window handle
+/// @param name Variable name
+/// @param value Variable value
+/// @param[out] err Error details, if any
+/// @return Old value or nil if there was no previous value.
///
/// @warning It may return nil if there was no previous value
/// or if previous value was `v:null`.
@@ -215,18 +301,17 @@ Object window_set_var(Window window, String name, Object value, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(win->w_vars, name, value, false, err);
+ return dict_set_var(win->w_vars, name, value, false, true, err);
}
/// Removes a window-scoped (w:) variable
///
-/// @param window The window handle
-/// @param name The variable name
-/// @param[out] err Details of an error that may have occurred
-/// @return The old value or nil if there was no previous value.
+/// @deprecated
///
-/// @warning It may return nil if there was no previous value
-/// or if previous value was `v:null`.
+/// @param window Window handle
+/// @param name variable name
+/// @param[out] err Error details, if any
+/// @return Old value
Object window_del_var(Window window, String name, Error *err)
{
win_T *win = find_window_by_handle(window, err);
@@ -235,16 +320,17 @@ Object window_del_var(Window window, String name, Error *err)
return (Object) OBJECT_INIT;
}
- return dict_set_value(win->w_vars, name, NIL, true, err);
+ return dict_set_var(win->w_vars, name, NIL, true, true, err);
}
/// Gets a window option value
///
-/// @param window The window handle
-/// @param name The option name
-/// @param[out] err Details of an error that may have occurred
-/// @return The option value
-Object window_get_option(Window window, String name, Error *err)
+/// @param window Window handle
+/// @param name Option name
+/// @param[out] err Error details, if any
+/// @return Option value
+Object nvim_win_get_option(Window window, String name, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -258,11 +344,13 @@ Object window_get_option(Window window, String name, Error *err)
/// Sets a window option value. Passing 'nil' as value deletes the option(only
/// works if there's a global fallback)
///
-/// @param window The window handle
-/// @param name The option name
-/// @param value The option value
-/// @param[out] err Details of an error that may have occurred
-void window_set_option(Window window, String name, Object value, Error *err)
+/// @param window Window handle
+/// @param name Option name
+/// @param value Option value
+/// @param[out] err Error details, if any
+void nvim_win_set_option(uint64_t channel_id, Window window,
+ String name, Object value, Error *err)
+ FUNC_API_SINCE(1)
{
win_T *win = find_window_by_handle(window, err);
@@ -270,15 +358,16 @@ void window_set_option(Window window, String name, Object value, Error *err)
return;
}
- set_option_to(win, SREQ_WIN, name, value, err);
+ set_option_to(channel_id, win, SREQ_WIN, name, value, err);
}
/// Gets the window position in display cells. First position is zero.
///
-/// @param window The window handle
-/// @param[out] err Details of an error that may have occurred
-/// @return The (row, col) tuple with the window position
-ArrayOf(Integer, 2) window_get_position(Window window, Error *err)
+/// @param window Window handle
+/// @param[out] err Error details, if any
+/// @return (row, col) tuple with the window position
+ArrayOf(Integer, 2) nvim_win_get_position(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
win_T *win = find_window_by_handle(window, err);
@@ -291,12 +380,13 @@ ArrayOf(Integer, 2) window_get_position(Window window, Error *err)
return rv;
}
-/// Gets the window tab page
+/// Gets the window tabpage
///
-/// @param window The window handle
-/// @param[out] err Details of an error that may have occurred
-/// @return The tab page that contains the window
-Tabpage window_get_tabpage(Window window, Error *err)
+/// @param window Window handle
+/// @param[out] err Error details, if any
+/// @return Tabpage that contains the window
+Tabpage nvim_win_get_tabpage(Window window, Error *err)
+ FUNC_API_SINCE(1)
{
Tabpage rv = 0;
win_T *win = find_window_by_handle(window, err);
@@ -308,13 +398,37 @@ Tabpage window_get_tabpage(Window window, Error *err)
return rv;
}
+/// Gets the window number
+///
+/// @param window Window handle
+/// @param[out] err Error details, if any
+/// @return Window number
+Integer nvim_win_get_number(Window window, Error *err)
+ FUNC_API_SINCE(1)
+{
+ int rv = 0;
+ win_T *win = find_window_by_handle(window, err);
+
+ if (!win) {
+ return rv;
+ }
+
+ int tabnr;
+ win_get_tabwin(window, &tabnr, &rv);
+
+ return rv;
+}
+
/// Checks if a window is valid
///
-/// @param window The window handle
+/// @param window Window handle
/// @return true if the window is valid, false otherwise
-Boolean window_is_valid(Window window)
+Boolean nvim_win_is_valid(Window window)
+ FUNC_API_SINCE(1)
{
Error stub = ERROR_INIT;
- return find_window_by_handle(window, &stub) != NULL;
+ Boolean ret = find_window_by_handle(window, &stub) != NULL;
+ api_clear_error(&stub);
+ return ret;
}
diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c
index db97bd9dc4..7f12c0c798 100644
--- a/src/nvim/arabic.c
+++ b/src/nvim/arabic.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
+
/// @file arabic.c
///
/// Functions for Arabic language.
@@ -390,491 +393,141 @@ static bool A_is_f(int cur_c)
// Change shape - from ISO-8859-6/Isolated to Form-B Isolated
static int chg_c_a2s(int cur_c)
{
- int tempc;
-
switch (cur_c) {
- case a_HAMZA:
- tempc = a_s_HAMZA;
- break;
-
- case a_ALEF_MADDA:
- tempc = a_s_ALEF_MADDA;
- break;
-
- case a_ALEF_HAMZA_ABOVE:
- tempc = a_s_ALEF_HAMZA_ABOVE;
- break;
-
- case a_WAW_HAMZA:
- tempc = a_s_WAW_HAMZA;
- break;
-
- case a_ALEF_HAMZA_BELOW:
- tempc = a_s_ALEF_HAMZA_BELOW;
- break;
-
- case a_YEH_HAMZA:
- tempc = a_s_YEH_HAMZA;
- break;
-
- case a_ALEF:
- tempc = a_s_ALEF;
- break;
-
- case a_TEH_MARBUTA:
- tempc = a_s_TEH_MARBUTA;
- break;
-
- case a_DAL:
- tempc = a_s_DAL;
- break;
-
- case a_THAL:
- tempc = a_s_THAL;
- break;
-
- case a_REH:
- tempc = a_s_REH;
- break;
-
- case a_ZAIN:
- tempc = a_s_ZAIN;
- break;
-
- case a_TATWEEL: // exceptions
- tempc = cur_c;
- break;
-
- case a_WAW:
- tempc = a_s_WAW;
- break;
-
- case a_ALEF_MAKSURA:
- tempc = a_s_ALEF_MAKSURA;
- break;
-
- case a_BEH:
- tempc = a_s_BEH;
- break;
-
- case a_TEH:
- tempc = a_s_TEH;
- break;
-
- case a_THEH:
- tempc = a_s_THEH;
- break;
-
- case a_JEEM:
- tempc = a_s_JEEM;
- break;
-
- case a_HAH:
- tempc = a_s_HAH;
- break;
-
- case a_KHAH:
- tempc = a_s_KHAH;
- break;
-
- case a_SEEN:
- tempc = a_s_SEEN;
- break;
-
- case a_SHEEN:
- tempc = a_s_SHEEN;
- break;
-
- case a_SAD:
- tempc = a_s_SAD;
- break;
-
- case a_DAD:
- tempc = a_s_DAD;
- break;
-
- case a_TAH:
- tempc = a_s_TAH;
- break;
-
- case a_ZAH:
- tempc = a_s_ZAH;
- break;
-
- case a_AIN:
- tempc = a_s_AIN;
- break;
-
- case a_GHAIN:
- tempc = a_s_GHAIN;
- break;
-
- case a_FEH:
- tempc = a_s_FEH;
- break;
-
- case a_QAF:
- tempc = a_s_QAF;
- break;
-
- case a_KAF:
- tempc = a_s_KAF;
- break;
-
- case a_LAM:
- tempc = a_s_LAM;
- break;
-
- case a_MEEM:
- tempc = a_s_MEEM;
- break;
-
- case a_NOON:
- tempc = a_s_NOON;
- break;
-
- case a_HEH:
- tempc = a_s_HEH;
- break;
-
- case a_YEH:
- tempc = a_s_YEH;
- break;
-
- default:
- tempc = 0;
+ case a_HAMZA: return a_s_HAMZA;
+ case a_ALEF_MADDA: return a_s_ALEF_MADDA;
+ case a_ALEF_HAMZA_ABOVE: return a_s_ALEF_HAMZA_ABOVE;
+ case a_WAW_HAMZA: return a_s_WAW_HAMZA;
+ case a_ALEF_HAMZA_BELOW: return a_s_ALEF_HAMZA_BELOW;
+ case a_YEH_HAMZA: return a_s_YEH_HAMZA;
+ case a_ALEF: return a_s_ALEF;
+ case a_TEH_MARBUTA: return a_s_TEH_MARBUTA;
+ case a_DAL: return a_s_DAL;
+ case a_THAL: return a_s_THAL;
+ case a_REH: return a_s_REH;
+ case a_ZAIN: return a_s_ZAIN;
+ case a_TATWEEL: return cur_c; // exceptions
+ case a_WAW: return a_s_WAW;
+ case a_ALEF_MAKSURA: return a_s_ALEF_MAKSURA;
+ case a_BEH: return a_s_BEH;
+ case a_TEH: return a_s_TEH;
+ case a_THEH: return a_s_THEH;
+ case a_JEEM: return a_s_JEEM;
+ case a_HAH: return a_s_HAH;
+ case a_KHAH: return a_s_KHAH;
+ case a_SEEN: return a_s_SEEN;
+ case a_SHEEN: return a_s_SHEEN;
+ case a_SAD: return a_s_SAD;
+ case a_DAD: return a_s_DAD;
+ case a_TAH: return a_s_TAH;
+ case a_ZAH: return a_s_ZAH;
+ case a_AIN: return a_s_AIN;
+ case a_GHAIN: return a_s_GHAIN;
+ case a_FEH: return a_s_FEH;
+ case a_QAF: return a_s_QAF;
+ case a_KAF: return a_s_KAF;
+ case a_LAM: return a_s_LAM;
+ case a_MEEM: return a_s_MEEM;
+ case a_NOON: return a_s_NOON;
+ case a_HEH: return a_s_HEH;
+ case a_YEH: return a_s_YEH;
}
-
- return tempc;
+ return 0;
}
// Change shape - from ISO-8859-6/Isolated to Initial
static int chg_c_a2i(int cur_c)
{
- int tempc;
-
switch (cur_c) {
- case a_YEH_HAMZA:
- tempc = a_i_YEH_HAMZA;
- break;
-
- case a_HAMZA: // exceptions
- tempc = a_s_HAMZA;
- break;
-
- case a_ALEF_MADDA: // exceptions
- tempc = a_s_ALEF_MADDA;
- break;
-
- case a_ALEF_HAMZA_ABOVE: // exceptions
- tempc = a_s_ALEF_HAMZA_ABOVE;
- break;
-
- case a_WAW_HAMZA: // exceptions
- tempc = a_s_WAW_HAMZA;
- break;
-
- case a_ALEF_HAMZA_BELOW: // exceptions
- tempc = a_s_ALEF_HAMZA_BELOW;
- break;
-
- case a_ALEF: // exceptions
- tempc = a_s_ALEF;
- break;
-
- case a_TEH_MARBUTA: // exceptions
- tempc = a_s_TEH_MARBUTA;
- break;
-
- case a_DAL: // exceptions
- tempc = a_s_DAL;
- break;
-
- case a_THAL: // exceptions
- tempc = a_s_THAL;
- break;
-
- case a_REH: // exceptions
- tempc = a_s_REH;
- break;
-
- case a_ZAIN: // exceptions
- tempc = a_s_ZAIN;
- break;
-
- case a_TATWEEL: // exceptions
- tempc = cur_c;
- break;
-
- case a_WAW: // exceptions
- tempc = a_s_WAW;
- break;
-
- case a_ALEF_MAKSURA: // exceptions
- tempc = a_s_ALEF_MAKSURA;
- break;
-
- case a_BEH:
- tempc = a_i_BEH;
- break;
-
- case a_TEH:
- tempc = a_i_TEH;
- break;
-
- case a_THEH:
- tempc = a_i_THEH;
- break;
-
- case a_JEEM:
- tempc = a_i_JEEM;
- break;
-
- case a_HAH:
- tempc = a_i_HAH;
- break;
-
- case a_KHAH:
- tempc = a_i_KHAH;
- break;
-
- case a_SEEN:
- tempc = a_i_SEEN;
- break;
-
- case a_SHEEN:
- tempc = a_i_SHEEN;
- break;
-
- case a_SAD:
- tempc = a_i_SAD;
- break;
-
- case a_DAD:
- tempc = a_i_DAD;
- break;
-
- case a_TAH:
- tempc = a_i_TAH;
- break;
-
- case a_ZAH:
- tempc = a_i_ZAH;
- break;
-
- case a_AIN:
- tempc = a_i_AIN;
- break;
-
- case a_GHAIN:
- tempc = a_i_GHAIN;
- break;
-
- case a_FEH:
- tempc = a_i_FEH;
- break;
-
- case a_QAF:
- tempc = a_i_QAF;
- break;
-
- case a_KAF:
- tempc = a_i_KAF;
- break;
-
- case a_LAM:
- tempc = a_i_LAM;
- break;
-
- case a_MEEM:
- tempc = a_i_MEEM;
- break;
-
- case a_NOON:
- tempc = a_i_NOON;
- break;
-
- case a_HEH:
- tempc = a_i_HEH;
- break;
-
- case a_YEH:
- tempc = a_i_YEH;
- break;
-
- default:
- tempc = 0;
+ case a_YEH_HAMZA: return a_i_YEH_HAMZA;
+ case a_HAMZA: return a_s_HAMZA; // exceptions
+ case a_ALEF_MADDA: return a_s_ALEF_MADDA; // exceptions
+ case a_ALEF_HAMZA_ABOVE: return a_s_ALEF_HAMZA_ABOVE; // exceptions
+ case a_WAW_HAMZA: return a_s_WAW_HAMZA; // exceptions
+ case a_ALEF_HAMZA_BELOW: return a_s_ALEF_HAMZA_BELOW; // exceptions
+ case a_ALEF: return a_s_ALEF; // exceptions
+ case a_TEH_MARBUTA: return a_s_TEH_MARBUTA; // exceptions
+ case a_DAL: return a_s_DAL; // exceptions
+ case a_THAL: return a_s_THAL; // exceptions
+ case a_REH: return a_s_REH; // exceptions
+ case a_ZAIN: return a_s_ZAIN; // exceptions
+ case a_TATWEEL: return cur_c; // exceptions
+ case a_WAW: return a_s_WAW; // exceptions
+ case a_ALEF_MAKSURA: return a_s_ALEF_MAKSURA; // exceptions
+ case a_BEH: return a_i_BEH;
+ case a_TEH: return a_i_TEH;
+ case a_THEH: return a_i_THEH;
+ case a_JEEM: return a_i_JEEM;
+ case a_HAH: return a_i_HAH;
+ case a_KHAH: return a_i_KHAH;
+ case a_SEEN: return a_i_SEEN;
+ case a_SHEEN: return a_i_SHEEN;
+ case a_SAD: return a_i_SAD;
+ case a_DAD: return a_i_DAD;
+ case a_TAH: return a_i_TAH;
+ case a_ZAH: return a_i_ZAH;
+ case a_AIN: return a_i_AIN;
+ case a_GHAIN: return a_i_GHAIN;
+ case a_FEH: return a_i_FEH;
+ case a_QAF: return a_i_QAF;
+ case a_KAF: return a_i_KAF;
+ case a_LAM: return a_i_LAM;
+ case a_MEEM: return a_i_MEEM;
+ case a_NOON: return a_i_NOON;
+ case a_HEH: return a_i_HEH;
+ case a_YEH: return a_i_YEH;
}
-
- return tempc;
+ return 0;
}
// Change shape - from ISO-8859-6/Isolated to Medial
static int chg_c_a2m(int cur_c)
{
- int tempc;
-
switch (cur_c) {
- case a_HAMZA: // exception
- tempc = a_s_HAMZA;
- break;
-
- case a_ALEF_MADDA: // exception
- tempc = a_f_ALEF_MADDA;
- break;
-
- case a_ALEF_HAMZA_ABOVE: // exception
- tempc = a_f_ALEF_HAMZA_ABOVE;
- break;
-
- case a_WAW_HAMZA: // exception
- tempc = a_f_WAW_HAMZA;
- break;
-
- case a_ALEF_HAMZA_BELOW: // exception
- tempc = a_f_ALEF_HAMZA_BELOW;
- break;
-
- case a_YEH_HAMZA:
- tempc = a_m_YEH_HAMZA;
- break;
-
- case a_ALEF: // exception
- tempc = a_f_ALEF;
- break;
-
- case a_BEH:
- tempc = a_m_BEH;
- break;
-
- case a_TEH_MARBUTA: // exception
- tempc = a_f_TEH_MARBUTA;
- break;
-
- case a_TEH:
- tempc = a_m_TEH;
- break;
-
- case a_THEH:
- tempc = a_m_THEH;
- break;
-
- case a_JEEM:
- tempc = a_m_JEEM;
- break;
-
- case a_HAH:
- tempc = a_m_HAH;
- break;
-
- case a_KHAH:
- tempc = a_m_KHAH;
- break;
-
- case a_DAL: // exception
- tempc = a_f_DAL;
- break;
-
- case a_THAL: // exception
- tempc = a_f_THAL;
- break;
-
- case a_REH: // exception
- tempc = a_f_REH;
- break;
-
- case a_ZAIN: // exception
- tempc = a_f_ZAIN;
- break;
-
- case a_SEEN:
- tempc = a_m_SEEN;
- break;
-
- case a_SHEEN:
- tempc = a_m_SHEEN;
- break;
-
- case a_SAD:
- tempc = a_m_SAD;
- break;
-
- case a_DAD:
- tempc = a_m_DAD;
- break;
-
- case a_TAH:
- tempc = a_m_TAH;
- break;
-
- case a_ZAH:
- tempc = a_m_ZAH;
- break;
-
- case a_AIN:
- tempc = a_m_AIN;
- break;
-
- case a_GHAIN:
- tempc = a_m_GHAIN;
- break;
-
- case a_TATWEEL: // exception
- tempc = cur_c;
- break;
-
- case a_FEH:
- tempc = a_m_FEH;
- break;
-
- case a_QAF:
- tempc = a_m_QAF;
- break;
-
- case a_KAF:
- tempc = a_m_KAF;
- break;
-
- case a_LAM:
- tempc = a_m_LAM;
- break;
-
- case a_MEEM:
- tempc = a_m_MEEM;
- break;
-
- case a_NOON:
- tempc = a_m_NOON;
- break;
-
- case a_HEH:
- tempc = a_m_HEH;
- break;
-
- case a_WAW: // exception
- tempc = a_f_WAW;
- break;
-
- case a_ALEF_MAKSURA: // exception
- tempc = a_f_ALEF_MAKSURA;
- break;
-
- case a_YEH:
- tempc = a_m_YEH;
- break;
-
- default:
- tempc = 0;
+ case a_HAMZA: return a_s_HAMZA; // exception
+ case a_ALEF_MADDA: return a_f_ALEF_MADDA; // exception
+ case a_ALEF_HAMZA_ABOVE: return a_f_ALEF_HAMZA_ABOVE; // exception
+ case a_WAW_HAMZA: return a_f_WAW_HAMZA; // exception
+ case a_ALEF_HAMZA_BELOW: return a_f_ALEF_HAMZA_BELOW; // exception
+ case a_YEH_HAMZA: return a_m_YEH_HAMZA;
+ case a_ALEF: return a_f_ALEF; // exception
+ case a_BEH: return a_m_BEH;
+ case a_TEH_MARBUTA: return a_f_TEH_MARBUTA; // exception
+ case a_TEH: return a_m_TEH;
+ case a_THEH: return a_m_THEH;
+ case a_JEEM: return a_m_JEEM;
+ case a_HAH: return a_m_HAH;
+ case a_KHAH: return a_m_KHAH;
+ case a_DAL: return a_f_DAL; // exception
+ case a_THAL: return a_f_THAL; // exception
+ case a_REH: return a_f_REH; // exception
+ case a_ZAIN: return a_f_ZAIN; // exception
+ case a_SEEN: return a_m_SEEN;
+ case a_SHEEN: return a_m_SHEEN;
+ case a_SAD: return a_m_SAD;
+ case a_DAD: return a_m_DAD;
+ case a_TAH: return a_m_TAH;
+ case a_ZAH: return a_m_ZAH;
+ case a_AIN: return a_m_AIN;
+ case a_GHAIN: return a_m_GHAIN;
+ case a_TATWEEL: return cur_c; // exception
+ case a_FEH: return a_m_FEH;
+ case a_QAF: return a_m_QAF;
+ case a_KAF: return a_m_KAF;
+ case a_LAM: return a_m_LAM;
+ case a_MEEM: return a_m_MEEM;
+ case a_NOON: return a_m_NOON;
+ case a_HEH: return a_m_HEH;
+ case a_WAW: return a_f_WAW; // exception
+ case a_ALEF_MAKSURA: return a_f_ALEF_MAKSURA; // exception
+ case a_YEH: return a_m_YEH;
}
-
- return tempc;
+ return 0;
}
// Change shape - from ISO-8859-6/Isolated to final
static int chg_c_a2f(int cur_c)
{
- int tempc;
-
// NOTE: these encodings need to be accounted for
//
// a_f_ALEF_MADDA;
@@ -885,280 +538,91 @@ static int chg_c_a2f(int cur_c)
// a_f_LAM_ALEF_HAMZA_BELOW;
switch (cur_c) {
- case a_HAMZA: // exception
- tempc = a_s_HAMZA;
- break;
-
- case a_ALEF_MADDA:
- tempc = a_f_ALEF_MADDA;
- break;
-
- case a_ALEF_HAMZA_ABOVE:
- tempc = a_f_ALEF_HAMZA_ABOVE;
- break;
-
- case a_WAW_HAMZA:
- tempc = a_f_WAW_HAMZA;
- break;
-
- case a_ALEF_HAMZA_BELOW:
- tempc = a_f_ALEF_HAMZA_BELOW;
- break;
-
- case a_YEH_HAMZA:
- tempc = a_f_YEH_HAMZA;
- break;
-
- case a_ALEF:
- tempc = a_f_ALEF;
- break;
-
- case a_BEH:
- tempc = a_f_BEH;
- break;
-
- case a_TEH_MARBUTA:
- tempc = a_f_TEH_MARBUTA;
- break;
-
- case a_TEH:
- tempc = a_f_TEH;
- break;
-
- case a_THEH:
- tempc = a_f_THEH;
- break;
-
- case a_JEEM:
- tempc = a_f_JEEM;
- break;
-
- case a_HAH:
- tempc = a_f_HAH;
- break;
-
- case a_KHAH:
- tempc = a_f_KHAH;
- break;
-
- case a_DAL:
- tempc = a_f_DAL;
- break;
-
- case a_THAL:
- tempc = a_f_THAL;
- break;
-
- case a_REH:
- tempc = a_f_REH;
- break;
-
- case a_ZAIN:
- tempc = a_f_ZAIN;
- break;
-
- case a_SEEN:
- tempc = a_f_SEEN;
- break;
-
- case a_SHEEN:
- tempc = a_f_SHEEN;
- break;
-
- case a_SAD:
- tempc = a_f_SAD;
- break;
-
- case a_DAD:
- tempc = a_f_DAD;
- break;
-
- case a_TAH:
- tempc = a_f_TAH;
- break;
-
- case a_ZAH:
- tempc = a_f_ZAH;
- break;
-
- case a_AIN:
- tempc = a_f_AIN;
- break;
-
- case a_GHAIN:
- tempc = a_f_GHAIN;
- break;
-
- case a_TATWEEL: // exception
- tempc = cur_c;
- break;
-
- case a_FEH:
- tempc = a_f_FEH;
- break;
-
- case a_QAF:
- tempc = a_f_QAF;
- break;
-
- case a_KAF:
- tempc = a_f_KAF;
- break;
-
- case a_LAM:
- tempc = a_f_LAM;
- break;
-
- case a_MEEM:
- tempc = a_f_MEEM;
- break;
-
- case a_NOON:
- tempc = a_f_NOON;
- break;
-
- case a_HEH:
- tempc = a_f_HEH;
- break;
-
- case a_WAW:
- tempc = a_f_WAW;
- break;
-
- case a_ALEF_MAKSURA:
- tempc = a_f_ALEF_MAKSURA;
- break;
-
- case a_YEH:
- tempc = a_f_YEH;
- break;
-
- default:
- tempc = 0;
+ case a_HAMZA: return a_s_HAMZA; // exception
+ case a_ALEF_MADDA: return a_f_ALEF_MADDA;
+ case a_ALEF_HAMZA_ABOVE: return a_f_ALEF_HAMZA_ABOVE;
+ case a_WAW_HAMZA: return a_f_WAW_HAMZA;
+ case a_ALEF_HAMZA_BELOW: return a_f_ALEF_HAMZA_BELOW;
+ case a_YEH_HAMZA: return a_f_YEH_HAMZA;
+ case a_ALEF: return a_f_ALEF;
+ case a_BEH: return a_f_BEH;
+ case a_TEH_MARBUTA: return a_f_TEH_MARBUTA;
+ case a_TEH: return a_f_TEH;
+ case a_THEH: return a_f_THEH;
+ case a_JEEM: return a_f_JEEM;
+ case a_HAH: return a_f_HAH;
+ case a_KHAH: return a_f_KHAH;
+ case a_DAL: return a_f_DAL;
+ case a_THAL: return a_f_THAL;
+ case a_REH: return a_f_REH;
+ case a_ZAIN: return a_f_ZAIN;
+ case a_SEEN: return a_f_SEEN;
+ case a_SHEEN: return a_f_SHEEN;
+ case a_SAD: return a_f_SAD;
+ case a_DAD: return a_f_DAD;
+ case a_TAH: return a_f_TAH;
+ case a_ZAH: return a_f_ZAH;
+ case a_AIN: return a_f_AIN;
+ case a_GHAIN: return a_f_GHAIN;
+ case a_TATWEEL: return cur_c; // exception
+ case a_FEH: return a_f_FEH;
+ case a_QAF: return a_f_QAF;
+ case a_KAF: return a_f_KAF;
+ case a_LAM: return a_f_LAM;
+ case a_MEEM: return a_f_MEEM;
+ case a_NOON: return a_f_NOON;
+ case a_HEH: return a_f_HEH;
+ case a_WAW: return a_f_WAW;
+ case a_ALEF_MAKSURA: return a_f_ALEF_MAKSURA;
+ case a_YEH: return a_f_YEH;
}
-
- return tempc;
+ return 0;
}
// Change shape - from Initial to Medial
+// This code is unreachable, because for the relevant characters ARABIC_CHAR()
+// is FALSE;
+#if 0
static int chg_c_i2m(int cur_c)
{
- int tempc;
-
switch (cur_c) {
- case a_i_YEH_HAMZA:
- tempc = a_m_YEH_HAMZA;
- break;
-
- case a_i_BEH:
- tempc = a_m_BEH;
- break;
-
- case a_i_TEH:
- tempc = a_m_TEH;
- break;
-
- case a_i_THEH:
- tempc = a_m_THEH;
- break;
-
- case a_i_JEEM:
- tempc = a_m_JEEM;
- break;
-
- case a_i_HAH:
- tempc = a_m_HAH;
- break;
-
- case a_i_KHAH:
- tempc = a_m_KHAH;
- break;
-
- case a_i_SEEN:
- tempc = a_m_SEEN;
- break;
-
- case a_i_SHEEN:
- tempc = a_m_SHEEN;
- break;
-
- case a_i_SAD:
- tempc = a_m_SAD;
- break;
-
- case a_i_DAD:
- tempc = a_m_DAD;
- break;
-
- case a_i_TAH:
- tempc = a_m_TAH;
- break;
-
- case a_i_ZAH:
- tempc = a_m_ZAH;
- break;
-
- case a_i_AIN:
- tempc = a_m_AIN;
- break;
-
- case a_i_GHAIN:
- tempc = a_m_GHAIN;
- break;
-
- case a_i_FEH:
- tempc = a_m_FEH;
- break;
-
- case a_i_QAF:
- tempc = a_m_QAF;
- break;
-
- case a_i_KAF:
- tempc = a_m_KAF;
- break;
-
- case a_i_LAM:
- tempc = a_m_LAM;
- break;
-
- case a_i_MEEM:
- tempc = a_m_MEEM;
- break;
-
- case a_i_NOON:
- tempc = a_m_NOON;
- break;
-
- case a_i_HEH:
- tempc = a_m_HEH;
- break;
-
- case a_i_YEH:
- tempc = a_m_YEH;
- break;
-
- default:
- tempc = 0;
+ case a_i_YEH_HAMZA: return a_m_YEH_HAMZA;
+ case a_i_BEH: return a_m_BEH;
+ case a_i_TEH: return a_m_TEH;
+ case a_i_THEH: return a_m_THEH;
+ case a_i_JEEM: return a_m_JEEM;
+ case a_i_HAH: return a_m_HAH;
+ case a_i_KHAH: return a_m_KHAH;
+ case a_i_SEEN: return a_m_SEEN;
+ case a_i_SHEEN: return a_m_SHEEN;
+ case a_i_SAD: return a_m_SAD;
+ case a_i_DAD: return a_m_DAD;
+ case a_i_TAH: return a_m_TAH;
+ case a_i_ZAH: return a_m_ZAH;
+ case a_i_AIN: return a_m_AIN;
+ case a_i_GHAIN: return a_m_GHAIN;
+ case a_i_FEH: return a_m_FEH;
+ case a_i_QAF: return a_m_QAF;
+ case a_i_KAF: return a_m_KAF;
+ case a_i_LAM: return a_m_LAM;
+ case a_i_MEEM: return a_m_MEEM;
+ case a_i_NOON: return a_m_NOON;
+ case a_i_HEH: return a_m_HEH;
+ case a_i_YEH: return a_m_YEH;
}
-
- return tempc;
+ return 0;
}
+#endif
// Change shape - from Final to Medial
static int chg_c_f2m(int cur_c)
{
- int tempc;
-
switch (cur_c) {
// NOTE: these encodings are multi-positional, no ?
// case a_f_ALEF_MADDA:
// case a_f_ALEF_HAMZA_ABOVE:
// case a_f_ALEF_HAMZA_BELOW:
- case a_f_YEH_HAMZA:
- tempc = a_m_YEH_HAMZA;
- break;
-
+ case a_f_YEH_HAMZA: return a_m_YEH_HAMZA;
case a_f_WAW_HAMZA: // exceptions
case a_f_ALEF:
case a_f_TEH_MARBUTA:
@@ -1168,165 +632,60 @@ static int chg_c_f2m(int cur_c)
case a_f_ZAIN:
case a_f_WAW:
case a_f_ALEF_MAKSURA:
- tempc = cur_c;
- break;
-
- case a_f_BEH:
- tempc = a_m_BEH;
- break;
-
- case a_f_TEH:
- tempc = a_m_TEH;
- break;
-
- case a_f_THEH:
- tempc = a_m_THEH;
- break;
-
- case a_f_JEEM:
- tempc = a_m_JEEM;
- break;
-
- case a_f_HAH:
- tempc = a_m_HAH;
- break;
-
- case a_f_KHAH:
- tempc = a_m_KHAH;
- break;
-
- case a_f_SEEN:
- tempc = a_m_SEEN;
- break;
-
- case a_f_SHEEN:
- tempc = a_m_SHEEN;
- break;
-
- case a_f_SAD:
- tempc = a_m_SAD;
- break;
-
- case a_f_DAD:
- tempc = a_m_DAD;
- break;
-
- case a_f_TAH:
- tempc = a_m_TAH;
- break;
-
- case a_f_ZAH:
- tempc = a_m_ZAH;
- break;
-
- case a_f_AIN:
- tempc = a_m_AIN;
- break;
-
- case a_f_GHAIN:
- tempc = a_m_GHAIN;
- break;
-
- case a_f_FEH:
- tempc = a_m_FEH;
- break;
-
- case a_f_QAF:
- tempc = a_m_QAF;
- break;
-
- case a_f_KAF:
- tempc = a_m_KAF;
- break;
-
- case a_f_LAM:
- tempc = a_m_LAM;
- break;
-
- case a_f_MEEM:
- tempc = a_m_MEEM;
- break;
-
- case a_f_NOON:
- tempc = a_m_NOON;
- break;
-
- case a_f_HEH:
- tempc = a_m_HEH;
- break;
-
- case a_f_YEH:
- tempc = a_m_YEH;
- break;
-
+ return cur_c;
+ case a_f_BEH: return a_m_BEH;
+ case a_f_TEH: return a_m_TEH;
+ case a_f_THEH: return a_m_THEH;
+ case a_f_JEEM: return a_m_JEEM;
+ case a_f_HAH: return a_m_HAH;
+ case a_f_KHAH: return a_m_KHAH;
+ case a_f_SEEN: return a_m_SEEN;
+ case a_f_SHEEN: return a_m_SHEEN;
+ case a_f_SAD: return a_m_SAD;
+ case a_f_DAD: return a_m_DAD;
+ case a_f_TAH: return a_m_TAH;
+ case a_f_ZAH: return a_m_ZAH;
+ case a_f_AIN: return a_m_AIN;
+ case a_f_GHAIN: return a_m_GHAIN;
+ case a_f_FEH: return a_m_FEH;
+ case a_f_QAF: return a_m_QAF;
+ case a_f_KAF: return a_m_KAF;
+ case a_f_LAM: return a_m_LAM;
+ case a_f_MEEM: return a_m_MEEM;
+ case a_f_NOON: return a_m_NOON;
+ case a_f_HEH: return a_m_HEH;
+ case a_f_YEH: return a_m_YEH;
// NOTE: these encodings are multi-positional, no ?
// case a_f_LAM_ALEF_MADDA_ABOVE:
// case a_f_LAM_ALEF_HAMZA_ABOVE:
// case a_f_LAM_ALEF_HAMZA_BELOW:
// case a_f_LAM_ALEF:
- default:
- tempc = 0;
}
-
- return tempc;
+ return 0;
}
// Change shape - from Combination (2 char) to an Isolated.
static int chg_c_laa2i(int hid_c)
{
- int tempc;
-
switch (hid_c) {
- case a_ALEF_MADDA:
- tempc = a_s_LAM_ALEF_MADDA_ABOVE;
- break;
-
- case a_ALEF_HAMZA_ABOVE:
- tempc = a_s_LAM_ALEF_HAMZA_ABOVE;
- break;
-
- case a_ALEF_HAMZA_BELOW:
- tempc = a_s_LAM_ALEF_HAMZA_BELOW;
- break;
-
- case a_ALEF:
- tempc = a_s_LAM_ALEF;
- break;
-
- default:
- tempc = 0;
+ case a_ALEF_MADDA: return a_s_LAM_ALEF_MADDA_ABOVE;
+ case a_ALEF_HAMZA_ABOVE: return a_s_LAM_ALEF_HAMZA_ABOVE;
+ case a_ALEF_HAMZA_BELOW: return a_s_LAM_ALEF_HAMZA_BELOW;
+ case a_ALEF: return a_s_LAM_ALEF;
}
-
- return tempc;
+ return 0;
}
// Change shape - from Combination-Isolated to Final.
static int chg_c_laa2f(int hid_c)
{
- int tempc;
-
switch (hid_c) {
- case a_ALEF_MADDA:
- tempc = a_f_LAM_ALEF_MADDA_ABOVE;
- break;
-
- case a_ALEF_HAMZA_ABOVE:
- tempc = a_f_LAM_ALEF_HAMZA_ABOVE;
- break;
-
- case a_ALEF_HAMZA_BELOW:
- tempc = a_f_LAM_ALEF_HAMZA_BELOW;
- break;
-
- case a_ALEF:
- tempc = a_f_LAM_ALEF;
- break;
-
- default:
- tempc = 0;
+ case a_ALEF_MADDA: return a_f_LAM_ALEF_MADDA_ABOVE;
+ case a_ALEF_HAMZA_ABOVE: return a_f_LAM_ALEF_HAMZA_ABOVE;
+ case a_ALEF_HAMZA_BELOW: return a_f_LAM_ALEF_HAMZA_BELOW;
+ case a_ALEF: return a_f_LAM_ALEF;
}
-
- return tempc;
+ return 0;
}
// Do "half-shaping" on character "c". Return zero if no shaping.
@@ -1381,7 +740,11 @@ int arabic_shape(int c, int *ccp, int *c1p, int prev_c, int prev_c1,
} else if (!shape_c || A_is_f(shape_c) || A_is_s(shape_c) || prev_laa) {
curr_c = A_is_valid(next_c) ? chg_c_a2i(c) : chg_c_a2s(c);
} else if (A_is_valid(next_c)) {
+#if 0
curr_c = A_is_iso(c) ? chg_c_a2m(c) : chg_c_i2m(c);
+#else
+ curr_c = A_is_iso(c) ? chg_c_a2m(c) : 0;
+#endif
} else if (A_is_valid(prev_c)) {
curr_c = chg_c_a2f(c);
} else {
@@ -1398,7 +761,7 @@ int arabic_shape(int c, int *ccp, int *c1p, int prev_c, int prev_c1,
char_u buf[MB_MAXBYTES + 1];
// Update the first byte of the character
- (*mb_char2bytes)(curr_c, buf);
+ utf_char2bytes(curr_c, buf);
*ccp = buf[0];
}
diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h
index 44ff540b40..ff6840d690 100644
--- a/src/nvim/ascii.h
+++ b/src/nvim/ascii.h
@@ -3,14 +3,17 @@
#include <stdbool.h>
+#include "nvim/macros.h"
#include "nvim/func_attr.h"
#include "nvim/os/os_defs.h"
// Definitions of various common control characters.
-#define CharOrd(x) ((x) < 'a' ? (x) - 'A' : (x) - 'a')
-#define CharOrdLow(x) ((x) - 'a')
-#define CharOrdUp(x) ((x) - 'A')
+#define CharOrd(x) ((uint8_t)(x) < 'a' \
+ ? (uint8_t)(x) - 'A'\
+ : (uint8_t)(x) - 'a')
+#define CharOrdLow(x) ((uint8_t)(x) - 'a')
+#define CharOrdUp(x) ((uint8_t)(x) - 'A')
#define ROT13(c, a) (((((c) - (a)) + 13) % 26) + (a))
#define NUL '\000'
@@ -18,15 +21,14 @@
#define BS '\010'
#define TAB '\011'
#define NL '\012'
-#define NL_STR (char_u *)"\012"
+#define NL_STR "\012"
#define FF '\014'
#define CAR '\015' /* CR is used by Mac OS X */
#define ESC '\033'
-#define ESC_STR (char_u *)"\033"
-#define ESC_STR_nc "\033"
+#define ESC_STR "\033"
#define DEL 0x7f
-#define DEL_STR (char_u *)"\177"
-#define CSI 0x9b /* Control Sequence Introducer */
+#define DEL_STR "\177"
+#define CSI 0x9b // Control Sequence Introducer
#define CSI_STR "\233"
#define DCS 0x90 /* Device Control String */
#define STERM 0x9c /* String Terminator */
@@ -97,6 +99,10 @@ static inline bool ascii_isxdigit(int)
REAL_FATTR_CONST
REAL_FATTR_ALWAYS_INLINE;
+static inline bool ascii_isident(int)
+ REAL_FATTR_CONST
+ REAL_FATTR_ALWAYS_INLINE;
+
static inline bool ascii_isbdigit(int)
REAL_FATTR_CONST
REAL_FATTR_ALWAYS_INLINE;
@@ -137,6 +143,14 @@ static inline bool ascii_isxdigit(int c)
|| (c >= 'A' && c <= 'F');
}
+/// Checks if `c` is an “identifier†character
+///
+/// That is, whether it is alphanumeric character or underscore.
+static inline bool ascii_isident(int c)
+{
+ return ASCII_ISALNUM(c) || c == '_';
+}
+
/// Checks if `c` is a binary digit, that is, 0-1.
///
/// @see {ascii_isdigit}
diff --git a/src/nvim/assert.h b/src/nvim/assert.h
index 761636305e..29195a49dc 100644
--- a/src/nvim/assert.h
+++ b/src/nvim/assert.h
@@ -121,4 +121,34 @@
((enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }) 0)
#endif
+/// @def STRICT_ADD
+/// @brief Adds (a + b) and stores result in `c`. Aborts on overflow.
+///
+/// Requires GCC 5+ and Clang 3.8+
+/// https://clang.llvm.org/docs/LanguageExtensions.html
+/// https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
+///
+/// Alternative for compilers without __builtin_xx_overflow ?
+/// https://stackoverflow.com/a/44830670/152142
+///
+/// @param MAX Maximum value of the narrowest type of operand.
+/// Not used if compiler supports __builtin_add_overflow.
+#if HAVE_BUILTIN_ADD_OVERFLOW
+# define STRICT_ADD(a, b, c, t) \
+ do { if (__builtin_add_overflow(a, b, c)) { abort(); } } while (0)
+#else
+# define STRICT_ADD(a, b, c, t) \
+ do { *(c) = (t)(a + b); } while (0)
+#endif
+
+/// @def STRICT_SUB
+/// @brief Subtracts (a - b) and stores result in `c`. Aborts on overflow.
+#if HAVE_BUILTIN_ADD_OVERFLOW
+# define STRICT_SUB(a, b, c, t) \
+ do { if (__builtin_sub_overflow(a, b, c)) { abort(); } } while (0)
+#else
+# define STRICT_SUB(a, b, c, t) \
+ do { *(c) = (t)(a - b); } while (0)
+#endif
+
#endif // NVIM_ASSERT_H
diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c
new file mode 100644
index 0000000000..9ad3414b79
--- /dev/null
+++ b/src/nvim/aucmd.c
@@ -0,0 +1,40 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/os/os.h"
+#include "nvim/fileio.h"
+#include "nvim/vim.h"
+#include "nvim/main.h"
+#include "nvim/ui.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "aucmd.c.generated.h"
+#endif
+
+static void focusgained_event(void **argv)
+{
+ bool *gainedp = argv[0];
+ do_autocmd_focusgained(*gainedp);
+ xfree(gainedp);
+}
+void aucmd_schedule_focusgained(bool gained)
+{
+ bool *gainedp = xmalloc(sizeof(*gainedp));
+ *gainedp = gained;
+ loop_schedule_deferred(&main_loop,
+ event_create(focusgained_event, 1, gainedp));
+}
+
+static void do_autocmd_focusgained(bool gained)
+{
+ static bool recursive = false;
+
+ if (recursive) {
+ return; // disallow recursion
+ }
+ recursive = true;
+ apply_autocmds((gained ? EVENT_FOCUSGAINED : EVENT_FOCUSLOST),
+ NULL, NULL, false, curbuf);
+ recursive = false;
+}
+
diff --git a/src/nvim/aucmd.h b/src/nvim/aucmd.h
new file mode 100644
index 0000000000..6570ba7a92
--- /dev/null
+++ b/src/nvim/aucmd.h
@@ -0,0 +1,9 @@
+#ifndef NVIM_AUCMD_H
+#define NVIM_AUCMD_H
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "aucmd.h.generated.h"
+#endif
+
+#endif // NVIM_AUCMD_H
+
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 8d891effae..3cffd66dee 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -19,16 +19,25 @@ return {
'BufWriteCmd', -- write buffer using command
'BufWritePost', -- after writing a buffer
'BufWritePre', -- before writing a buffer
+ 'ChanInfo', -- info was received about channel
+ 'ChanOpen', -- channel was opened
+ 'CmdLineChanged', -- command line was modified
+ 'CmdLineEnter', -- after entering cmdline mode
+ 'CmdLineLeave', -- before leaving cmdline mode
'CmdUndefined', -- command undefined
'CmdWinEnter', -- after entering the cmdline window
'CmdWinLeave', -- before leaving the cmdline window
'ColorScheme', -- after loading a colorscheme
+ 'ColorSchemePre', -- before loading a colorscheme
'CompleteDone', -- after finishing insert complete
'CursorHold', -- cursor in same position for a while
'CursorHoldI', -- idem, in Insert mode
'CursorMoved', -- cursor was moved
'CursorMovedI', -- cursor was moved in Insert mode
+ 'DiffUpdated', -- diffs have been updated
+ 'DirChanged', -- directory changed
'EncodingChanged', -- after changing the 'encoding' option
+ 'ExitPre', -- before exiting
'FileAppendCmd', -- append to a file using command
'FileAppendPost', -- after appending to a file
'FileAppendPre', -- before appending to a file
@@ -82,15 +91,19 @@ return {
'TermOpen', -- after opening a terminal buffer
'TermResponse', -- after setting "v:termresponse"
'TextChanged', -- text was modified
- 'TextChangedI', -- text was modified in Insert mode
+ 'TextChangedI', -- text was modified in Insert mode(no popup)
+ 'TextChangedP', -- text was modified in Insert mode(popup)
'TextYankPost', -- after a yank or delete was done (y, d, c)
'User', -- user defined autocommand
'VimEnter', -- after starting Vim
'VimLeave', -- before exiting Vim
'VimLeavePre', -- before exiting Vim and writing ShaDa file
'VimResized', -- after Vim window was resized
+ 'VimResume', -- after Nvim is resumed
+ 'VimSuspend', -- before Nvim is suspended
'WinEnter', -- after entering a window
'WinLeave', -- before leaving a window
+ 'WinNew', -- when entering a new window
},
aliases = {
BufCreate = 'BufAdd',
@@ -98,9 +111,10 @@ return {
BufWrite = 'BufWritePre',
FileEncoding = 'EncodingChanged',
},
- -- List of neovim-specific events or aliases for the purpose of generating
+ -- List of nvim-specific events or aliases for the purpose of generating
-- syntax file
- neovim_specific = {
+ nvim_specific = {
+ DirChanged=true,
TabClosed=true,
TabNew=true,
TabNewEntered=true,
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 438a85dd5d..c15a6f1330 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.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
+
/*
* buffer.c: functions for dealing with the buffer structure
*/
@@ -19,8 +22,11 @@
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
+#include <assert.h>
#include "nvim/api/private/handle.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/ascii.h"
#include "nvim/assert.h"
#include "nvim/vim.h"
@@ -36,9 +42,11 @@
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
+#include "nvim/file_search.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
+#include "nvim/highlight.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/main.h"
@@ -48,7 +56,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/option.h"
@@ -60,7 +67,6 @@
#include "nvim/spell.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/terminal.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/version.h"
@@ -69,6 +75,13 @@
#include "nvim/os/os.h"
#include "nvim/os/time.h"
#include "nvim/os/input.h"
+#include "nvim/buffer_updates.h"
+
+typedef enum {
+ kBLSUnchanged = 0,
+ kBLSChanged = 1,
+ kBLSDeleted = 2,
+} BufhlLineStatus;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "buffer.c.generated.h"
@@ -78,6 +91,60 @@ static char *msg_loclist = N_("[Location List]");
static char *msg_qflist = N_("[Quickfix List]");
static char *e_auabort = N_("E855: Autocommands caused command to abort");
+// Number of times free_buffer() was called.
+static int buf_free_count = 0;
+
+// Read data from buffer for retrying.
+static int
+read_buffer(
+ int read_stdin, // read file from stdin, otherwise fifo
+ exarg_T *eap, // for forced 'ff' and 'fenc' or NULL
+ int flags) // extra flags for readfile()
+{
+ int retval = OK;
+ linenr_T line_count;
+
+ //
+ // Read from the buffer which the text is already filled in and append at
+ // the end. This makes it possible to retry when 'fileformat' or
+ // 'fileencoding' was guessed wrong.
+ //
+ line_count = curbuf->b_ml.ml_line_count;
+ retval = readfile(
+ read_stdin ? NULL : curbuf->b_ffname,
+ read_stdin ? NULL : curbuf->b_fname,
+ (linenr_T)line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+ flags | READ_BUFFER);
+ if (retval == OK) {
+ // Delete the binary lines.
+ while (--line_count >= 0) {
+ ml_delete((linenr_T)1, false);
+ }
+ } else {
+ // Delete the converted lines.
+ while (curbuf->b_ml.ml_line_count > line_count) {
+ ml_delete(line_count, false);
+ }
+ }
+ // Put the cursor on the first line.
+ curwin->w_cursor.lnum = 1;
+ curwin->w_cursor.col = 0;
+
+ if (read_stdin) {
+ // Set or reset 'modified' before executing autocommands, so that
+ // it can be changed there.
+ if (!readonlymode && !BUFEMPTY()) {
+ changed();
+ } else if (retval != FAIL) {
+ unchanged(curbuf, false);
+ }
+
+ apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, false,
+ curbuf, &retval);
+ }
+ return retval;
+}
+
/*
* Open current buffer, that is: open the memfile and read the file into
* memory.
@@ -91,8 +158,9 @@ open_buffer (
)
{
int retval = OK;
- buf_T *old_curbuf;
+ bufref_T old_curbuf;
long old_tw = curbuf->b_p_tw;
+ int read_fifo = false;
/*
* The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
@@ -133,32 +201,63 @@ open_buffer (
return FAIL;
}
- /* The autocommands in readfile() may change the buffer, but only AFTER
- * reading the file. */
- old_curbuf = curbuf;
- modified_was_set = FALSE;
+ // The autocommands in readfile() may change the buffer, but only AFTER
+ // reading the file.
+ set_bufref(&old_curbuf, curbuf);
+ modified_was_set = false;
/* mark cursor position as being invalid */
curwin->w_valid = 0;
if (curbuf->b_ffname != NULL) {
int old_msg_silent = msg_silent;
+#ifdef UNIX
+ int save_bin = curbuf->b_p_bin;
+ int perm;
+
+ perm = os_getperm((const char *)curbuf->b_ffname);
+ if (perm >= 0 && (0
+# ifdef S_ISFIFO
+ || S_ISFIFO(perm)
+# endif
+# ifdef S_ISSOCK
+ || S_ISSOCK(perm)
+# endif
+# ifdef OPEN_CHR_FILES
+ || (S_ISCHR(perm)
+ && is_dev_fd_file(curbuf->b_ffname))
+# endif
+ )
+ ) {
+ read_fifo = true;
+ }
+ if (read_fifo) {
+ curbuf->b_p_bin = true;
+ }
+#endif
if (shortmess(SHM_FILEINFO)) {
msg_silent = 1;
}
retval = readfile(curbuf->b_ffname, curbuf->b_fname,
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
- flags | READ_NEW);
+ flags | READ_NEW | (read_fifo ? READ_FIFO : 0));
+#ifdef UNIX
+ if (read_fifo) {
+ curbuf->b_p_bin = save_bin;
+ if (retval == OK) {
+ retval = read_buffer(false, eap, flags);
+ }
+ }
+#endif
msg_silent = old_msg_silent;
// Help buffer is filtered.
- if (curbuf->b_help) {
+ if (bt_help(curbuf)) {
fix_help_buffer();
}
} else if (read_stdin) {
int save_bin = curbuf->b_p_bin;
- linenr_T line_count;
/*
* First read the text in binary mode into the buffer.
@@ -172,56 +271,36 @@ open_buffer (
flags | (READ_NEW + READ_STDIN));
curbuf->b_p_bin = save_bin;
if (retval == OK) {
- line_count = curbuf->b_ml.ml_line_count;
- retval = readfile(NULL, NULL, (linenr_T)line_count,
- (linenr_T)0, (linenr_T)MAXLNUM, eap,
- flags | READ_BUFFER);
- if (retval == OK) {
- /* Delete the binary lines. */
- while (--line_count >= 0)
- ml_delete((linenr_T)1, FALSE);
- } else {
- /* Delete the converted lines. */
- while (curbuf->b_ml.ml_line_count > line_count)
- ml_delete(line_count, FALSE);
- }
- /* Put the cursor on the first line. */
- curwin->w_cursor.lnum = 1;
- curwin->w_cursor.col = 0;
-
- /* Set or reset 'modified' before executing autocommands, so that
- * it can be changed there. */
- if (!readonlymode && !bufempty())
- changed();
- else if (retval != FAIL)
- unchanged(curbuf, FALSE);
- apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
- curbuf, &retval);
+ retval = read_buffer(true, eap, flags);
}
}
/* if first time loading this buffer, init b_chartab[] */
if (curbuf->b_flags & BF_NEVERLOADED) {
- (void)buf_init_chartab(curbuf, FALSE);
+ (void)buf_init_chartab(curbuf, false);
parse_cino(curbuf);
}
- /*
- * Set/reset the Changed flag first, autocmds may change the buffer.
- * Apply the automatic commands, before processing the modelines.
- * So the modelines have priority over auto commands.
- */
- /* When reading stdin, the buffer contents always needs writing, so set
- * the changed flag. Unless in readonly mode: "ls | nvim -R -".
- * When interrupted and 'cpoptions' contains 'i' set changed flag. */
+ // Set/reset the Changed flag first, autocmds may change the buffer.
+ // Apply the automatic commands, before processing the modelines.
+ // So the modelines have priority over auto commands.
+
+ // When reading stdin, the buffer contents always needs writing, so set
+ // the changed flag. Unless in readonly mode: "ls | nvim -R -".
+ // When interrupted and 'cpoptions' contains 'i' set changed flag.
if ((got_int && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
- || modified_was_set /* ":set modified" used in autocmd */
- || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)
- )
+ || modified_was_set // ":set modified" used in autocmd
+ || (aborting() && vim_strchr(p_cpo, CPO_INTMOD) != NULL)) {
changed();
- else if (retval != FAIL && !read_stdin)
- unchanged(curbuf, FALSE);
- save_file_ff(curbuf); /* keep this fileformat */
+ } else if (retval != FAIL && !read_stdin && !read_fifo) {
+ unchanged(curbuf, false);
+ }
+ save_file_ff(curbuf); // keep this fileformat
+
+ // Set last_changedtick to avoid triggering a TextChanged autocommand right
+ // after it was added.
+ curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
+ curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf);
/* require "!" to overwrite the file, because it wasn't read completely */
if (aborting())
@@ -246,11 +325,11 @@ open_buffer (
* The autocommands may have changed the current buffer. Apply the
* modelines to the correct buffer, if it still exists and is loaded.
*/
- if (buf_valid(old_curbuf) && old_curbuf->b_ml.ml_mfp != NULL) {
+ if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->b_ml.ml_mfp != NULL) {
aco_save_T aco;
- /* Go to the buffer that was opened. */
- aucmd_prepbuf(&aco, old_curbuf);
+ // Go to the buffer that was opened.
+ aucmd_prepbuf(&aco, old_curbuf.br_buf);
do_modelines(0);
curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED);
@@ -264,11 +343,45 @@ open_buffer (
return retval;
}
-/// Check that "buf" points to a valid buffer (in the buffer list).
+/// Store "buf" in "bufref" and set the free count.
+///
+/// @param bufref Reference to be used for the buffer.
+/// @param buf The buffer to reference.
+void set_bufref(bufref_T *bufref, buf_T *buf)
+{
+ bufref->br_buf = buf;
+ bufref->br_fnum = buf == NULL ? 0 : buf->b_fnum;
+ bufref->br_buf_free_count = buf_free_count;
+}
+
+/// Return true if "bufref->br_buf" points to the same buffer as when
+/// set_bufref() was called and it is a valid buffer.
+/// Only goes through the buffer list if buf_free_count changed.
+/// Also checks if b_fnum is still the same, a :bwipe followed by :new might get
+/// the same allocated memory, but it's a different buffer.
+///
+/// @param bufref Buffer reference to check for.
+bool bufref_valid(bufref_T *bufref)
+{
+ return bufref->br_buf_free_count == buf_free_count
+ ? true
+ : buf_valid(bufref->br_buf) && bufref->br_fnum == bufref->br_buf->b_fnum;
+}
+
+/// Check that "buf" points to a valid buffer in the buffer list.
+///
+/// Can be slow if there are many buffers, prefer using bufref_valid().
+///
+/// @param buf The buffer to check for.
bool buf_valid(buf_T *buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- FOR_ALL_BUFFERS(bp) {
+ if (buf == NULL) {
+ return false;
+ }
+ // Assume that we more often have a recent buffer,
+ // start with the last one.
+ for (buf_T *bp = lastbuf; bp != NULL; bp = bp->b_prev) {
if (bp == buf) {
return true;
}
@@ -276,35 +389,34 @@ bool buf_valid(buf_T *buf)
return false;
}
-/*
- * Close the link to a buffer.
- * "action" is used when there is no longer a window for the buffer.
- * It can be:
- * 0 buffer becomes hidden
- * DOBUF_UNLOAD buffer is unloaded
- * DOBUF_DELETE buffer is unloaded and removed from buffer list
- * DOBUF_WIPE buffer is unloaded and really deleted
- * When doing all but the first one on the current buffer, the caller should
- * get a new buffer very soon!
- *
- * The 'bufhidden' option can force freeing and deleting.
- *
- * When "abort_if_last" is TRUE then do not close the buffer if autocommands
- * cause there to be only one window with this buffer. e.g. when ":quit" is
- * supposed to close the window but autocommands close all other windows.
- */
-void
-close_buffer (
- win_T *win, /* if not NULL, set b_last_cursor */
- buf_T *buf,
- int action,
- int abort_if_last
-)
+/// Close the link to a buffer.
+///
+/// @param win If not NULL, set b_last_cursor.
+/// @param buf
+/// @param action Used when there is no longer a window for the buffer.
+/// Possible values:
+/// 0 buffer becomes hidden
+/// DOBUF_UNLOAD buffer is unloaded
+/// DOBUF_DELETE buffer is unloaded and removed from buffer list
+/// DOBUF_WIPE buffer is unloaded and really deleted
+/// When doing all but the first one on the current buffer, the
+/// caller should get a new buffer very soon!
+/// The 'bufhidden' option can force freeing and deleting.
+/// @param abort_if_last
+/// If TRUE, do not close the buffer if autocommands cause
+/// there to be only one window with this buffer. e.g. when
+/// ":quit" is supposed to close the window but autocommands
+/// close all other windows.
+void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last)
{
bool unload_buf = (action != 0);
bool del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE);
bool wipe_buf = (action == DOBUF_WIPE);
+ bool is_curwin = (curwin != NULL && curwin->w_buffer == buf);
+ win_T *the_curwin = curwin;
+ tabpage_T *the_curtab = curtab;
+
// Force unloading or deleting when 'bufhidden' says so, but not for terminal
// buffers.
// The caller must take care of NOT deleting/freeing when 'bufhidden' is
@@ -328,47 +440,57 @@ close_buffer (
wipe_buf = true;
}
- if (win_valid(win)) {
- /* Set b_last_cursor when closing the last window for the buffer.
- * Remember the last cursor position and window options of the buffer.
- * This used to be only for the current window, but then options like
- * 'foldmethod' may be lost with a ":only" command. */
- if (buf->b_nwindows == 1)
+ // Disallow deleting the buffer when it is locked (already being closed or
+ // halfway a command that relies on it). Unloading is allowed.
+ if (buf->b_locked > 0 && (del_buf || wipe_buf)) {
+ EMSG(_("E937: Attempt to delete a buffer that is in use"));
+ return;
+ }
+
+ if (win != NULL // Avoid bogus clang warning.
+ && win_valid_any_tab(win)) {
+ // Set b_last_cursor when closing the last window for the buffer.
+ // Remember the last cursor position and window options of the buffer.
+ // This used to be only for the current window, but then options like
+ // 'foldmethod' may be lost with a ":only" command.
+ if (buf->b_nwindows == 1) {
set_last_cursor(win);
+ }
buflist_setfpos(buf, win,
win->w_cursor.lnum == 1 ? 0 : win->w_cursor.lnum,
win->w_cursor.col, TRUE);
}
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
/* When the buffer is no longer in a window, trigger BufWinLeave */
if (buf->b_nwindows == 1) {
- buf->b_closing = true;
- apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) {
- /* Autocommands deleted the buffer. */
+ buf->b_locked++;
+ if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, false,
+ buf) && !bufref_valid(&bufref)) {
+ // Autocommands deleted the buffer.
EMSG(_(e_auabort));
return;
}
- buf->b_closing = false;
+ buf->b_locked--;
if (abort_if_last && one_window()) {
/* Autocommands made this the only window. */
EMSG(_(e_auabort));
return;
}
- /* When the buffer becomes hidden, but is not unloaded, trigger
- * BufHidden */
+ // When the buffer becomes hidden, but is not unloaded, trigger
+ // BufHidden
if (!unload_buf) {
- buf->b_closing = true;
- apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) {
- /* Autocommands deleted the buffer. */
+ buf->b_locked++;
+ if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, false,
+ buf) && !bufref_valid(&bufref)) {
+ // Autocommands deleted the buffer.
EMSG(_(e_auabort));
return;
}
- buf->b_closing = false;
+ buf->b_locked--;
if (abort_if_last && one_window()) {
/* Autocommands made this the only window. */
EMSG(_(e_auabort));
@@ -378,20 +500,36 @@ close_buffer (
if (aborting()) /* autocmds may abort script processing */
return;
}
+
+ // If the buffer was in curwin and the window has changed, go back to that
+ // window, if it still exists. This avoids that ":edit x" triggering a
+ // "tabnext" BufUnload autocmd leaves a window behind without a buffer.
+ if (is_curwin && curwin != the_curwin && win_valid_any_tab(the_curwin)) {
+ block_autocmds();
+ goto_tabpage_win(the_curtab, the_curwin);
+ unblock_autocmds();
+ }
+
int nwindows = buf->b_nwindows;
- /* decrease the link count from windows (unless not in any window) */
- if (buf->b_nwindows > 0)
- --buf->b_nwindows;
+ // decrease the link count from windows (unless not in any window)
+ if (buf->b_nwindows > 0) {
+ buf->b_nwindows--;
+ }
+
+ if (diffopt_hiddenoff() && !unload_buf && buf->b_nwindows == 0) {
+ diff_buf_delete(buf); // Clear 'diff' for hidden buffer.
+ }
/* Return when a window is displaying the buffer or when it's not
* unloaded. */
- if (buf->b_nwindows > 0 || !unload_buf)
+ if (buf->b_nwindows > 0 || !unload_buf) {
return;
+ }
if (buf->terminal) {
terminal_close(buf->terminal, NULL);
- }
+ }
/* Always remove the buffer when there is no file name. */
if (buf->b_ffname == NULL)
@@ -404,23 +542,29 @@ close_buffer (
/* Remember if we are closing the current buffer. Restore the number of
* windows, so that autocommands in buf_freeall() don't get confused. */
bool is_curbuf = (buf == curbuf);
+
+ // When closing the current buffer stop Visual mode before freeing
+ // anything.
+ if (is_curbuf && VIsual_active
+#if defined(EXITFREE)
+ && !entered_free_all_mem
+#endif
+ ) {
+ end_visual_mode();
+ }
+
buf->b_nwindows = nwindows;
buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0));
- if (win_valid(win) && win->w_buffer == buf) {
- win->w_buffer = NULL; // make sure we don't use the buffer now
- }
- /* Autocommands may have deleted the buffer. */
- if (!buf_valid(buf))
+ if (!bufref_valid(&bufref)) {
+ // Autocommands may have deleted the buffer.
return;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) {
+ // Autocmds may abort script processing.
return;
-
- /* Autocommands may have opened or closed windows for this buffer.
- * Decrement the count for the close we do here. */
- if (buf->b_nwindows > 0)
- --buf->b_nwindows;
+ }
/*
* It's possible that autocommands change curbuf to the one being deleted.
@@ -432,9 +576,24 @@ close_buffer (
if (buf == curbuf && !is_curbuf)
return;
+ if (win != NULL // Avoid bogus clang warning.
+ && win_valid_any_tab(win)
+ && win->w_buffer == buf) {
+ win->w_buffer = NULL; // make sure we don't use the buffer now
+ }
+
+ // Autocommands may have opened or closed windows for this buffer.
+ // Decrement the count for the close we do here.
+ if (buf->b_nwindows > 0) {
+ buf->b_nwindows--;
+ }
+
/* Change directories when the 'acd' option is set. */
do_autochdir();
+ // disable buffer updates for the current buffer
+ buf_updates_unregister_all(buf);
+
/*
* Remove the buffer from the list.
*/
@@ -483,35 +642,70 @@ void buf_clear_file(buf_T *buf)
buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */
}
-/*
- * buf_freeall() - free all things allocated for a buffer that are related to
- * the file. flags:
- * BFA_DEL buffer is going to be deleted
- * BFA_WIPE buffer is going to be wiped out
- * BFA_KEEP_UNDO do not free undo information
- */
+/// Clears the current buffer contents.
+void buf_clear(void)
+{
+ linenr_T line_count = curbuf->b_ml.ml_line_count;
+ while (!(curbuf->b_ml.ml_flags & ML_EMPTY)) {
+ ml_delete((linenr_T)1, false);
+ }
+ deleted_lines_mark(1, line_count); // prepare for display
+ ml_close(curbuf, true); // free memline_T
+ buf_clear_file(curbuf);
+}
+
+/// buf_freeall() - free all things allocated for a buffer that are related to
+/// the file. Careful: get here with "curwin" NULL when exiting.
+///
+/// @param flags BFA_DEL buffer is going to be deleted
+/// BFA_WIPE buffer is going to be wiped out
+/// BFA_KEEP_UNDO do not free undo information
void buf_freeall(buf_T *buf, int flags)
{
bool is_curbuf = (buf == curbuf);
+ int is_curwin = (curwin != NULL && curwin->w_buffer == buf);
+ win_T *the_curwin = curwin;
+ tabpage_T *the_curtab = curtab;
- buf->b_closing = true;
- apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
+ // Make sure the buffer isn't closed by autocommands.
+ buf->b_locked++;
+
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
+ if ((buf->b_ml.ml_mfp != NULL)
+ && apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf)
+ && !bufref_valid(&bufref)) {
+ // Autocommands deleted the buffer.
return;
- if ((flags & BFA_DEL) && buf->b_p_bl) {
- apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
- return;
}
- if (flags & BFA_WIPE) {
- apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
- return;
+ if ((flags & BFA_DEL)
+ && buf->b_p_bl
+ && apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, false, buf)
+ && !bufref_valid(&bufref)) {
+ // Autocommands may delete the buffer.
+ return;
}
- buf->b_closing = false;
- if (aborting()) /* autocmds may abort script processing */
+ if ((flags & BFA_WIPE)
+ && apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname, false,
+ buf)
+ && !bufref_valid(&bufref)) {
+ // Autocommands may delete the buffer.
return;
+ }
+ buf->b_locked--;
+
+ // If the buffer was in curwin and the window has changed, go back to that
+ // window, if it still exists. This avoids that ":edit x" triggering a
+ // "tabnext" BufUnload autocmd leaves a window behind without a buffer.
+ if (is_curwin && curwin != the_curwin && win_valid_any_tab(the_curwin)) {
+ block_autocmds();
+ goto_tabpage_win(the_curtab, the_curwin);
+ unblock_autocmds();
+ }
+ if (aborting()) { // autocmds may abort script processing
+ return;
+ }
/*
* It's possible that autocommands change curbuf to the one being deleted.
@@ -521,10 +715,11 @@ void buf_freeall(buf_T *buf, int flags)
*/
if (buf == curbuf && !is_curbuf)
return;
- diff_buf_delete(buf); /* Can't use 'diff' for unloaded buffer. */
- /* Remove any ownsyntax, unless exiting. */
- if (firstwin != NULL && curwin->w_buffer == buf)
+ diff_buf_delete(buf); // Can't use 'diff' for unloaded buffer.
+ // Remove any ownsyntax, unless exiting.
+ if (curwin != NULL && curwin->w_buffer == buf) {
reset_synblock(curwin);
+ }
/* No folds in an empty buffer. */
FOR_ALL_TAB_WINDOWS(tp, win) {
@@ -550,10 +745,11 @@ void buf_freeall(buf_T *buf, int flags)
static void free_buffer(buf_T *buf)
{
handle_unregister_buffer(buf);
- free_buffer_stuff(buf, TRUE);
+ buf_free_count++;
+ free_buffer_stuff(buf, true);
unref_var_dict(buf->b_vars);
aubuflocal_remove(buf);
- dict_unref(buf->additional_data);
+ tv_dict_unref(buf->additional_data);
clear_fmark(&buf->b_last_cursor);
clear_fmark(&buf->b_last_insert);
clear_fmark(&buf->b_last_change);
@@ -589,8 +785,18 @@ free_buffer_stuff (
free_buf_options(buf, true);
ga_clear(&buf->b_s.b_langp);
}
+ {
+ // Avoid loosing b:changedtick when deleting buffer: clearing variables
+ // implies using clear_tv() on b:changedtick and that sets changedtick to
+ // zero.
+ hashitem_T *const changedtick_hi = hash_find(
+ &buf->b_vars->dv_hashtab, (const char_u *)"changedtick");
+ assert(changedtick_hi != NULL);
+ hash_remove(&buf->b_vars->dv_hashtab, changedtick_hi);
+ }
vars_clear(&buf->b_vars->dv_hashtab); // free all internal variables
hash_init(&buf->b_vars->dv_hashtab);
+ buf_init_changedtick(buf);
uc_clear(&buf->b_ucmds); // clear local user commands
buf_delete_signs(buf); // delete any signs
bufhl_clear_all(buf); // delete any highligts
@@ -598,6 +804,8 @@ free_buffer_stuff (
map_clear_int(buf, MAP_ALL_MODES, true, true); // clear local abbrevs
xfree(buf->b_start_fenc);
buf->b_start_fenc = NULL;
+
+ buf_updates_unregister_all(buf);
}
/*
@@ -623,11 +831,13 @@ static void clear_wininfo(buf_T *buf)
*/
void goto_buffer(exarg_T *eap, int start, int dir, int count)
{
- (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
- start, dir, count, eap->forceit);
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
+ set_bufref(&old_curbuf, curbuf);
swap_exists_action = SEA_DIALOG;
+ (void)do_buffer(*eap->cmd == 's' ? DOBUF_SPLIT : DOBUF_GOTO,
+ start, dir, count, eap->forceit);
+
if (swap_exists_action == SEA_QUIT && *eap->cmd == 's') {
cleanup_T cs;
@@ -635,8 +845,8 @@ void goto_buffer(exarg_T *eap, int start, int dir, int count)
* aborting() returns FALSE when closing a window. */
enter_cleanup(&cs);
- /* Quitting means closing the split window, nothing else. */
- win_close(curwin, TRUE);
+ // Quitting means closing the split window, nothing else.
+ win_close(curwin, true);
swap_exists_action = SEA_NONE;
swap_exists_did_quit = TRUE;
@@ -644,36 +854,52 @@ void goto_buffer(exarg_T *eap, int start, int dir, int count)
* new aborting error, interrupt, or uncaught exception. */
leave_cleanup(&cs);
} else {
- handle_swap_exists(old_curbuf);
+ handle_swap_exists(&old_curbuf);
}
}
-/*
- * Handle the situation of swap_exists_action being set.
- * It is allowed for "old_curbuf" to be NULL or invalid.
- */
-void handle_swap_exists(buf_T *old_curbuf)
+/// Handle the situation of swap_exists_action being set.
+///
+/// It is allowed for "old_curbuf" to be NULL or invalid.
+///
+/// @param old_curbuf The buffer to check for.
+void handle_swap_exists(bufref_T *old_curbuf)
{
cleanup_T cs;
long old_tw = curbuf->b_p_tw;
+ buf_T *buf;
if (swap_exists_action == SEA_QUIT) {
/* Reset the error/interrupt/exception state here so that
* aborting() returns FALSE when closing a buffer. */
enter_cleanup(&cs);
- /* User selected Quit at ATTENTION prompt. Go back to previous
- * buffer. If that buffer is gone or the same as the current one,
- * open a new, empty buffer. */
- swap_exists_action = SEA_NONE; /* don't want it again */
- swap_exists_did_quit = TRUE;
- close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE);
- if (!buf_valid(old_curbuf) || old_curbuf == curbuf)
- old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
- if (old_curbuf != NULL) {
- enter_buffer(old_curbuf);
- if (old_tw != curbuf->b_p_tw)
+ // User selected Quit at ATTENTION prompt. Go back to previous
+ // buffer. If that buffer is gone or the same as the current one,
+ // open a new, empty buffer.
+ swap_exists_action = SEA_NONE; // don't want it again
+ swap_exists_did_quit = true;
+ close_buffer(curwin, curbuf, DOBUF_UNLOAD, false);
+ if (old_curbuf == NULL
+ || !bufref_valid(old_curbuf)
+ || old_curbuf->br_buf == curbuf) {
+ buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED);
+ } else {
+ buf = old_curbuf->br_buf;
+ }
+ if (buf != NULL) {
+ int old_msg_silent = msg_silent;
+
+ if (shortmess(SHM_FILEINFO)) {
+ msg_silent = 1; // prevent fileinfo message
+ }
+ enter_buffer(buf);
+ // restore msg_silent, so that the command line will be shown
+ msg_silent = old_msg_silent;
+
+ if (old_tw != curbuf->b_p_tw) {
check_colorcolumn(curwin);
+ }
}
/* If "old_curbuf" is NULL we are in big trouble here... */
@@ -696,7 +922,7 @@ void handle_swap_exists(buf_T *old_curbuf)
* new aborting error, interrupt, or uncaught exception. */
leave_cleanup(&cs);
}
- swap_exists_action = SEA_NONE;
+ swap_exists_action = SEA_NONE; // -V519
}
/*
@@ -824,6 +1050,9 @@ static int empty_curbuf(int close_others, int forceit, int action)
return FAIL;
}
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
if (close_others) {
/* Close any other windows on this buffer, then make it empty. */
close_windows(buf, TRUE);
@@ -833,15 +1062,17 @@ static int empty_curbuf(int close_others, int forceit, int action)
retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
forceit ? ECMD_FORCEIT : 0, curwin);
- /*
- * do_ecmd() may create a new buffer, then we have to delete
- * the old one. But do_ecmd() may have done that already, check
- * if the buffer still exists.
- */
- if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
- close_buffer(NULL, buf, action, FALSE);
- if (!close_others)
- need_fileinfo = FALSE;
+ // do_ecmd() may create a new buffer, then we have to delete
+ // the old one. But do_ecmd() may have done that already, check
+ // if the buffer still exists.
+ if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) {
+ close_buffer(NULL, buf, action, false);
+ }
+
+ if (!close_others) {
+ need_fileinfo = false;
+ }
+
return retval;
}
/*
@@ -943,6 +1174,8 @@ do_buffer (
*/
if (unload) {
int forward;
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
/* When unloading or deleting a buffer that's already unloaded and
* unlisted: fail silently. */
@@ -951,28 +1184,41 @@ do_buffer (
if (!forceit && (buf->terminal || bufIsChanged(buf))) {
if ((p_confirm || cmdmod.confirm) && p_write && !buf->terminal) {
- dialog_changed(buf, FALSE);
- if (!buf_valid(buf))
- /* Autocommand deleted buffer, oops! It's not changed
- * now. */
+ dialog_changed(buf, false);
+ if (!bufref_valid(&bufref)) {
+ // Autocommand deleted buffer, oops! It's not changed now.
return FAIL;
- /* If it's still changed fail silently, the dialog already
- * mentioned why it fails. */
- if (bufIsChanged(buf))
+ }
+ // If it's still changed fail silently, the dialog already
+ // mentioned why it fails.
+ if (bufIsChanged(buf)) {
return FAIL;
+ }
} else {
if (buf->terminal) {
- EMSG2(_("E89: %s will be killed(add ! to override)"),
- (char *)buf->b_fname);
+ if (p_confirm || cmdmod.confirm) {
+ if (!dialog_close_terminal(buf)) {
+ return FAIL;
+ }
+ } else {
+ EMSG2(_("E89: %s will be killed(add ! to override)"),
+ (char *)buf->b_fname);
+ return FAIL;
+ }
} else {
EMSGN(_("E89: No write since last change for buffer %" PRId64
" (add ! to override)"),
buf->b_fnum);
+ return FAIL;
}
- return FAIL;
}
}
+ // When closing the current buffer stop Visual mode.
+ if (buf == curbuf && VIsual_active) {
+ end_visual_mode();
+ }
+
/*
* If deleting the last (listed) buffer, make it empty.
* The last (listed) buffer cannot be unloaded.
@@ -993,9 +1239,9 @@ do_buffer (
* a window with this buffer.
*/
while (buf == curbuf
- && !(curwin->w_closing || curwin->w_buffer->b_closing)
- && (firstwin != lastwin || first_tabpage->tp_next != NULL)) {
- if (win_close(curwin, FALSE) == FAIL)
+ && !(curwin->w_closing || curwin->w_buffer->b_locked > 0)
+ && (!ONE_WINDOW || first_tabpage->tp_next != NULL)) {
+ if (win_close(curwin, false) == FAIL)
break;
}
@@ -1003,27 +1249,26 @@ do_buffer (
* If the buffer to be deleted is not the current one, delete it here.
*/
if (buf != curbuf) {
- close_windows(buf, FALSE);
- if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0)
- close_buffer(NULL, buf, action, FALSE);
+ close_windows(buf, false);
+ if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) {
+ close_buffer(NULL, buf, action, false);
+ }
return OK;
}
- /*
- * Deleting the current buffer: Need to find another buffer to go to.
- * There should be another, otherwise it would have been handled
- * above. However, autocommands may have deleted all buffers.
- * First use au_new_curbuf, if it is valid.
- * Then prefer the buffer we most recently visited.
- * Else try to find one that is loaded, after the current buffer,
- * then before the current buffer.
- * Finally use any buffer.
- */
- buf = NULL; /* selected buffer */
- bp = NULL; /* used when no loaded buffer found */
- if (au_new_curbuf != NULL && buf_valid(au_new_curbuf))
- buf = au_new_curbuf;
- else if (curwin->w_jumplistlen > 0) {
+ // Deleting the current buffer: Need to find another buffer to go to.
+ // There should be another, otherwise it would have been handled
+ // above. However, autocommands may have deleted all buffers.
+ // First use au_new_curbuf.br_buf, if it is valid.
+ // Then prefer the buffer we most recently visited.
+ // Else try to find one that is loaded, after the current buffer,
+ // then before the current buffer.
+ // Finally use any buffer.
+ buf = NULL; // Selected buffer.
+ bp = NULL; // Used when no loaded buffer found.
+ if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)) {
+ buf = au_new_curbuf.br_buf;
+ } else if (curwin->w_jumplistlen > 0) {
int jumpidx;
jumpidx = curwin->w_jumplistidx - 1;
@@ -1128,10 +1373,13 @@ do_buffer (
*/
if (action == DOBUF_GOTO && !can_abandon(curbuf, forceit)) {
if ((p_confirm || cmdmod.confirm) && p_write) {
- dialog_changed(curbuf, FALSE);
- if (!buf_valid(buf))
- /* Autocommand deleted buffer, oops! */
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ dialog_changed(curbuf, false);
+ if (!bufref_valid(&bufref)) {
+ // Autocommand deleted buffer, oops!
return FAIL;
+ }
}
if (bufIsChanged(curbuf)) {
EMSG(_(e_nowrtmsg));
@@ -1177,27 +1425,40 @@ void set_curbuf(buf_T *buf, int action)
/* Don't restart Select mode after switching to another buffer. */
VIsual_reselect = FALSE;
- /* close_windows() or apply_autocmds() may change curbuf */
+ // close_windows() or apply_autocmds() may change curbuf and wipe out "buf"
prevbuf = curbuf;
-
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- if (buf_valid(prevbuf) && !aborting()) {
- if (prevbuf == curwin->w_buffer)
+ bufref_T newbufref;
+ bufref_T prevbufref;
+ set_bufref(&prevbufref, prevbuf);
+ set_bufref(&newbufref, buf);
+
+ // Autocommands may delete the curren buffer and/or the buffer we wan to go
+ // to. In those cases don't close the buffer.
+ if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf)
+ || (bufref_valid(&prevbufref) && bufref_valid(&newbufref)
+ && !aborting())) {
+ if (prevbuf == curwin->w_buffer) {
reset_synblock(curwin);
- if (unload)
- close_windows(prevbuf, FALSE);
- if (buf_valid(prevbuf) && !aborting()) {
+ }
+ if (unload) {
+ close_windows(prevbuf, false);
+ }
+ if (bufref_valid(&prevbufref) && !aborting()) {
win_T *previouswin = curwin;
- if (prevbuf == curbuf)
- u_sync(FALSE);
- close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf,
- unload ? action : (action == DOBUF_GOTO
- && !P_HID(prevbuf)
- && !bufIsChanged(
- prevbuf)) ? DOBUF_UNLOAD : 0, FALSE);
- if (curwin != previouswin && win_valid(previouswin))
- /* autocommands changed curwin, Grr! */
+ if (prevbuf == curbuf) {
+ u_sync(false);
+ }
+ close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL,
+ prevbuf,
+ unload
+ ? action
+ : (action == DOBUF_GOTO && !buf_hide(prevbuf)
+ && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0,
+ false);
+ if (curwin != previouswin && win_valid(previouswin)) {
+ // autocommands changed curwin, Grr!
curwin = previouswin;
+ }
}
}
/* An autocommand may have deleted "buf", already entered it (e.g., when
@@ -1249,10 +1510,6 @@ void enter_buffer(buf_T *buf)
/* mark cursor position as being invalid */
curwin->w_valid = 0;
- if (buf->terminal) {
- terminal_resize(buf->terminal, curwin->w_width, curwin->w_height);
- }
-
/* Make sure the buffer is loaded. */
if (curbuf->b_ml.ml_mfp == NULL) { /* need to load the file */
/* If there is no filetype, allow for detecting one. Esp. useful for
@@ -1310,32 +1567,55 @@ void do_autochdir(void)
}
}
-/*
- * functions for dealing with the buffer list
- */
+//
+// functions for dealing with the buffer list
+//
-/*
- * Add a file name to the buffer list. Return a pointer to the buffer.
- * If the same file name already exists return a pointer to that buffer.
- * If it does not exist, or if fname == NULL, a new entry is created.
- * If (flags & BLN_CURBUF) is TRUE, may use current buffer.
- * If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
- * If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
- * This is the ONLY way to create a new buffer.
- */
-static int top_file_num = 1; /* highest file number */
-
-buf_T *
-buflist_new (
- char_u *ffname, /* full path of fname or relative */
- char_u *sfname, /* short fname or NULL */
- linenr_T lnum, /* preferred cursor line */
- int flags /* BLN_ defines */
-)
+static int top_file_num = 1; ///< highest file number
+
+/// Initialize b:changedtick and changedtick_val attribute
+///
+/// @param[out] buf Buffer to intialize for.
+static inline void buf_init_changedtick(buf_T *const buf)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
+{
+ STATIC_ASSERT(sizeof("changedtick") <= sizeof(buf->changedtick_di.di_key),
+ "buf->changedtick_di cannot hold large enough keys");
+ buf->changedtick_di = (ChangedtickDictItem) {
+ .di_flags = DI_FLAGS_RO|DI_FLAGS_FIX, // Must not include DI_FLAGS_ALLOC.
+ .di_tv = (typval_T) {
+ .v_type = VAR_NUMBER,
+ .v_lock = VAR_FIXED,
+ .vval.v_number = buf_get_changedtick(buf),
+ },
+ .di_key = "changedtick",
+ };
+ tv_dict_add(buf->b_vars, (dictitem_T *)&buf->changedtick_di);
+}
+
+/// Add a file name to the buffer list.
+/// If the same file name already exists return a pointer to that buffer.
+/// If it does not exist, or if fname == NULL, a new entry is created.
+/// If (flags & BLN_CURBUF) is TRUE, may use current buffer.
+/// If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list.
+/// If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer.
+/// If (flags & BLN_NEW) is TRUE, don't use an existing buffer.
+/// If (flags & BLN_NOOPT) is TRUE, don't copy options from the current buffer
+/// if the buffer already exists.
+/// This is the ONLY way to create a new buffer.
+///
+/// @param ffname full path of fname or relative
+/// @param sfname short fname or NULL
+/// @param lnum preferred cursor line
+/// @param flags BLN_ defines
+/// @param bufnr
+///
+/// @return pointer to the buffer
+buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags)
{
buf_T *buf;
- fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */
+ fname_expand(curbuf, &ffname, &sfname); // will allocate ffname
/*
* If file name already exists in the list, update the entry.
@@ -1349,16 +1629,20 @@ buflist_new (
&& (buf = buflist_findname_file_id(ffname, &file_id,
file_id_valid)) != NULL) {
xfree(ffname);
- if (lnum != 0)
- buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE);
- /* copy the options now, if 'cpo' doesn't have 's' and not done
- * already */
- buf_copy_options(buf, 0);
+ if (lnum != 0) {
+ buflist_setfpos(buf, curwin, lnum, (colnr_T)0, false);
+ }
+ if ((flags & BLN_NOOPT) == 0) {
+ // Copy the options now, if 'cpo' doesn't have 's' and not done already.
+ buf_copy_options(buf, 0);
+ }
if ((flags & BLN_LISTED) && !buf->b_p_bl) {
- buf->b_p_bl = TRUE;
+ buf->b_p_bl = true;
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
if (!(flags & BLN_DUMMY)) {
- apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf)) {
+ if (apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
+ && !bufref_valid(&bufref)) {
return NULL;
}
}
@@ -1379,7 +1663,7 @@ buflist_new (
&& curbuf != NULL
&& curbuf->b_ffname == NULL
&& curbuf->b_nwindows <= 1
- && (curbuf->b_ml.ml_mfp == NULL || bufempty())) {
+ && (curbuf->b_ml.ml_mfp == NULL || BUFEMPTY())) {
buf = curbuf;
/* It's like this buffer is deleted. Watch out for autocommands that
* change curbuf! If that happens, allocate a new buffer anyway. */
@@ -1397,10 +1681,10 @@ buflist_new (
}
if (buf != curbuf || curbuf == NULL) {
buf = xcalloc(1, sizeof(buf_T));
- handle_register_buffer(buf);
- /* init b: variables */
- buf->b_vars = dict_alloc();
+ // init b: variables
+ buf->b_vars = tv_dict_alloc();
init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
+ buf_init_changedtick(buf);
}
if (ffname != NULL) {
@@ -1451,11 +1735,12 @@ buflist_new (
lastbuf = buf;
buf->b_fnum = top_file_num++;
- if (top_file_num < 0) { /* wrap around (may cause duplicates) */
+ handle_register_buffer(buf);
+ if (top_file_num < 0) { // wrap around (may cause duplicates)
EMSG(_("W14: Warning: List of file names overflow"));
if (emsg_silent == 0) {
ui_flush();
- os_delay(3000L, true); /* make sure it is noticed */
+ os_delay(3000L, true); // make sure it is noticed
}
top_file_num = 1;
}
@@ -1484,25 +1769,30 @@ buflist_new (
if (flags & BLN_DUMMY)
buf->b_flags |= BF_DUMMY;
buf_clear_file(buf);
- clrallmarks(buf); /* clear marks */
- fmarks_check_names(buf); /* check file marks for this file */
- buf->b_p_bl = (flags & BLN_LISTED) ? TRUE : FALSE; /* init 'buflisted' */
+ clrallmarks(buf); // clear marks
+ fmarks_check_names(buf); // check file marks for this file
+ buf->b_p_bl = (flags & BLN_LISTED) ? true : false; // init 'buflisted'
+ kv_destroy(buf->update_channels);
+ kv_init(buf->update_channels);
if (!(flags & BLN_DUMMY)) {
// Tricky: these autocommands may change the buffer list. They could also
// split the window with re-using the one empty buffer. This may result in
// unexpectedly losing the empty buffer.
- apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf)) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, false, buf)
+ && !bufref_valid(&bufref)) {
return NULL;
}
- if (flags & BLN_LISTED) {
- apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf);
- if (!buf_valid(buf)) {
- return NULL;
- }
+ if ((flags & BLN_LISTED)
+ && apply_autocmds(EVENT_BUFADD, NULL, NULL, false, buf)
+ && !bufref_valid(&bufref)) {
+ return NULL;
}
- if (aborting()) /* autocmds may abort script processing */
+ if (aborting()) {
+ // Autocmds may abort script processing.
return NULL;
+ }
}
return buf;
@@ -1526,6 +1816,7 @@ void free_buf_options(buf_T *buf, int free_p_ff)
clear_string_option(&buf->b_p_inex);
clear_string_option(&buf->b_p_inde);
clear_string_option(&buf->b_p_indk);
+ clear_string_option(&buf->b_p_fp);
clear_string_option(&buf->b_p_fex);
clear_string_option(&buf->b_p_kp);
clear_string_option(&buf->b_p_mps);
@@ -1533,6 +1824,7 @@ void free_buf_options(buf_T *buf, int free_p_ff)
clear_string_option(&buf->b_p_flp);
clear_string_option(&buf->b_p_isk);
clear_string_option(&buf->b_p_keymap);
+ keymap_ga_clear(&buf->b_kmap_ga);
ga_clear(&buf->b_kmap_ga);
clear_string_option(&buf->b_p_com);
clear_string_option(&buf->b_p_cms);
@@ -1566,18 +1858,18 @@ void free_buf_options(buf_T *buf, int free_p_ff)
buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
clear_string_option(&buf->b_p_lw);
clear_string_option(&buf->b_p_bkc);
+ clear_string_option(&buf->b_p_menc);
}
-/*
- * get alternate file n
- * set linenr to lnum or altfpos.lnum if lnum == 0
- * also set cursor column to altfpos.col if 'startofline' is not set.
- * if (options & GETF_SETMARK) call setpcmark()
- * if (options & GETF_ALT) we are jumping to an alternate file.
- * if (options & GETF_SWITCH) respect 'switchbuf' settings when jumping
- *
- * return FAIL for failure, OK for success
- */
+
+/// Get alternate file "n".
+/// Set linenr to "lnum" or altfpos.lnum if "lnum" == 0.
+/// Also set cursor column to altfpos.col if 'startofline' is not set.
+/// if (options & GETF_SETMARK) call setpcmark()
+/// if (options & GETF_ALT) we are jumping to an alternate file.
+/// if (options & GETF_SWITCH) respect 'switchbuf' settings when jumping
+///
+/// Return FAIL for failure, OK for success.
int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
{
buf_T *buf;
@@ -1629,7 +1921,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
// If 'switchbuf' contains "split", "vsplit" or "newtab" and the
// current buffer isn't empty: open new tab or window
if (wp == NULL && (swb_flags & (SWB_VSPLIT | SWB_SPLIT | SWB_NEWTAB))
- && !bufempty()) {
+ && !BUFEMPTY()) {
if (swb_flags & SWB_NEWTAB) {
tabpage_new();
} else if (win_split(0, (swb_flags & SWB_VSPLIT) ? WSP_VERT : 0)
@@ -1640,10 +1932,10 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
}
}
- ++RedrawingDisabled;
- if (getfile(buf->b_fnum, NULL, NULL, (options & GETF_SETMARK),
- lnum, forceit) <= 0) {
- --RedrawingDisabled;
+ RedrawingDisabled++;
+ if (GETFILE_SUCCESS(getfile(buf->b_fnum, NULL, NULL,
+ (options & GETF_SETMARK), lnum, forceit))) {
+ RedrawingDisabled--;
/* cursor is at to BOL and w_cursor.lnum is checked due to getfile() */
if (!p_sol && col != 0) {
@@ -1654,13 +1946,11 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit)
}
return OK;
}
- --RedrawingDisabled;
+ RedrawingDisabled--;
return FAIL;
}
-/*
- * go to the last know line number for the current buffer
- */
+// Go to the last known line number for the current buffer.
void buflist_getfpos(void)
{
pos_T *fpos;
@@ -1725,7 +2015,8 @@ buf_T *buflist_findname(char_u *ffname)
static buf_T *buflist_findname_file_id(char_u *ffname, FileID *file_id,
bool file_id_valid)
{
- FOR_ALL_BUFFERS(buf) {
+ // Start at the last buffer, expect to find a match sooner.
+ FOR_ALL_BUFFERS_BACKWARDS(buf) {
if ((buf->b_flags & BF_DUMMY) == 0
&& !otherfile_buf(buf, ffname, file_id, file_id_valid)) {
return buf;
@@ -1799,7 +2090,7 @@ int buflist_findpat(
return -1;
}
- FOR_ALL_BUFFERS(buf) {
+ FOR_ALL_BUFFERS_BACKWARDS(buf) {
if (buf->b_p_bl == find_listed
&& (!diffmode || diff_mode_buf(buf))
&& buflist_match(&regmatch, buf, false) != NULL) {
@@ -1913,7 +2204,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options)
if (count == 0) /* no match found, break here */
break;
if (round == 1) {
- *file = xmalloc(count * sizeof(**file));
+ *file = xmalloc((size_t)count * sizeof(**file));
}
}
vim_regfree(regmatch.regprog);
@@ -1968,21 +2259,14 @@ static char_u *fname_match(regmatch_T *rmp, char_u *name, bool ignore_case)
return match;
}
-/*
- * find file in buffer list by number
- */
+/// Find a file in the buffer list by buffer number.
buf_T *buflist_findnr(int nr)
{
if (nr == 0) {
nr = curwin->w_alt_fnum;
}
- FOR_ALL_BUFFERS(buf) {
- if (buf->b_fnum == nr) {
- return buf;
- }
- }
- return NULL;
+ return handle_get_buffer((handle_T)nr);
}
/*
@@ -2128,8 +2412,15 @@ void get_winopts(buf_T *buf)
clear_winopt(&curwin->w_onebuf_opt);
clearFolding(curwin);
- wip = find_wininfo(buf, TRUE);
- if (wip != NULL && wip->wi_optset) {
+ wip = find_wininfo(buf, true);
+ if (wip != NULL && wip->wi_win != curwin && wip->wi_win != NULL
+ && wip->wi_win->w_buffer == buf) {
+ win_T *wp = wip->wi_win;
+ copy_winopt(&wp->w_onebuf_opt, &curwin->w_onebuf_opt);
+ curwin->w_fold_manual = wp->w_fold_manual;
+ curwin->w_foldinvalid = true;
+ cloneFoldGrowArray(&wp->w_folds, &curwin->w_folds);
+ } else if (wip != NULL && wip->wi_optset) {
copy_winopt(&wip->wi_opt, &curwin->w_onebuf_opt);
curwin->w_fold_manual = wip->wi_fold_manual;
curwin->w_foldinvalid = true;
@@ -2140,7 +2431,7 @@ void get_winopts(buf_T *buf)
/* Set 'foldlevel' to 'foldlevelstart' if it's not negative. */
if (p_fdls >= 0)
curwin->w_p_fdl = p_fdls;
- check_colorcolumn(curwin);
+ didset_window_options(curwin);
}
/*
@@ -2164,9 +2455,7 @@ linenr_T buflist_findlnum(buf_T *buf)
return buflist_findfpos(buf)->lnum;
}
-/*
- * List all know file names (for :files and :buffers command).
- */
+// List all known file names (for :files and :buffers command).
void buflist_list(exarg_T *eap)
{
buf_T *buf;
@@ -2191,12 +2480,17 @@ void buflist_list(exarg_T *eap)
&& (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) {
continue;
}
- msg_putchar('\n');
- if (buf_spname(buf) != NULL)
+ if (buf_spname(buf) != NULL) {
STRLCPY(NameBuff, buf_spname(buf), MAXPATHL);
- else
- home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE);
+ } else {
+ home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, true);
+ }
+ if (message_filtered(NameBuff)) {
+ continue;
+ }
+
+ msg_putchar('\n');
len = vim_snprintf((char *)IObuff, IOSIZE - 20, "%3d%c%c%c%c%c \"%s\"",
buf->b_fnum,
buf->b_p_bl ? ' ' : 'u',
@@ -2365,10 +2659,11 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum)
{
buf_T *buf;
- /* Create a buffer. 'buflisted' is not set if it's a new buffer */
+ // Create a buffer. 'buflisted' is not set if it's a new buffer
buf = buflist_new(ffname, sfname, lnum, 0);
- if (buf != NULL && !cmdmod.keepalt)
+ if (buf != NULL && !cmdmod.keepalt) {
curwin->w_alt_fnum = buf->b_fnum;
+ }
return buf;
}
@@ -2376,9 +2671,8 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum)
* Get alternate file name for current window.
* Return NULL if there isn't any, and give error message if requested.
*/
-char_u *
-getaltfname (
- int errmsg /* give error message */
+char_u * getaltfname(
+ bool errmsg // give error message
)
{
char_u *fname;
@@ -2403,8 +2697,9 @@ int buflist_add(char_u *fname, int flags)
buf_T *buf;
buf = buflist_new(fname, NULL, (linenr_T)0, flags);
- if (buf != NULL)
+ if (buf != NULL) {
return buf->b_fnum;
+ }
return 0;
}
@@ -2434,7 +2729,7 @@ void buflist_altfpos(win_T *win)
}
/// Check that "ffname" is not the same file as current file.
-/// Fname must have a full path (expanded by path_get_absolute_path()).
+/// Fname must have a full path (expanded by path_to_absolute()).
///
/// @param ffname full path name to check
bool otherfile(char_u *ffname)
@@ -2444,7 +2739,7 @@ bool otherfile(char_u *ffname)
}
/// Check that "ffname" is not the same file as the file loaded in "buf".
-/// Fname must have a full path (expanded by path_get_absolute_path()).
+/// Fname must have a full path (expanded by path_to_absolute()).
///
/// @param buf buffer to check
/// @param ffname full path name to check
@@ -2548,7 +2843,7 @@ fileinfo (
else
name = curbuf->b_ffname;
home_replace(shorthelp ? curbuf : NULL, name, p,
- (int)(IOSIZE - (p - buffer)), TRUE);
+ (size_t)(IOSIZE - (p - buffer)), true);
}
vim_snprintf_add((char *)buffer, IOSIZE, "\"%s%s%s%s%s%s",
@@ -2636,15 +2931,13 @@ static char_u *lasticon = NULL;
void maketitle(void)
{
- char_u *p;
char_u *t_str = NULL;
char_u *i_name;
char_u *i_str = NULL;
int maxlen = 0;
int len;
int mustset;
- char_u buf[IOSIZE];
- int off;
+ char buf[IOSIZE];
if (!redrawing()) {
/* Postpone updating the title when 'lazyredraw' is set. */
@@ -2658,102 +2951,123 @@ void maketitle(void)
if (p_title) {
if (p_titlelen > 0) {
- maxlen = p_titlelen * Columns / 100;
- if (maxlen < 10)
+ maxlen = (int)(p_titlelen * Columns / 100);
+ if (maxlen < 10) {
maxlen = 10;
+ }
}
- t_str = buf;
if (*p_titlestring != NUL) {
if (stl_syntax & STL_IN_TITLE) {
int use_sandbox = FALSE;
int save_called_emsg = called_emsg;
use_sandbox = was_set_insecurely((char_u *)"titlestring", 0);
- called_emsg = FALSE;
- build_stl_str_hl(curwin, t_str, sizeof(buf),
- p_titlestring, use_sandbox,
- 0, maxlen, NULL, NULL);
- if (called_emsg)
- set_string_option_direct((char_u *)"titlestring", -1,
- (char_u *)"", OPT_FREE, SID_ERROR);
+ called_emsg = false;
+ build_stl_str_hl(curwin, (char_u *)buf, sizeof(buf),
+ p_titlestring, use_sandbox,
+ 0, maxlen, NULL, NULL);
+ t_str = (char_u *)buf;
+ if (called_emsg) {
+ set_string_option_direct((char_u *)"titlestring", -1, (char_u *)"",
+ OPT_FREE, SID_ERROR);
+ }
called_emsg |= save_called_emsg;
- } else
+ } else {
t_str = p_titlestring;
+ }
} else {
- /* format: "fname + (path) (1 of 2) - VIM" */
-
-#define SPACE_FOR_FNAME (IOSIZE - 100)
-#define SPACE_FOR_DIR (IOSIZE - 20)
-#define SPACE_FOR_ARGNR (IOSIZE - 10) /* at least room for " - VIM" */
- if (curbuf->b_fname == NULL)
- STRLCPY(buf, _("[No Name]"), SPACE_FOR_FNAME + 1);
- else {
- p = transstr(path_tail(curbuf->b_fname));
- STRLCPY(buf, p, SPACE_FOR_FNAME + 1);
- xfree(p);
+ // Format: "fname + (path) (1 of 2) - VIM".
+
+#define SPACE_FOR_FNAME (sizeof(buf) - 100)
+#define SPACE_FOR_DIR (sizeof(buf) - 20)
+#define SPACE_FOR_ARGNR (sizeof(buf) - 10) // At least room for " - NVIM".
+ char *buf_p = buf;
+ if (curbuf->b_fname == NULL) {
+ const size_t size = xstrlcpy(buf_p, _("[No Name]"),
+ SPACE_FOR_FNAME + 1);
+ buf_p += MIN(size, SPACE_FOR_FNAME);
+ } else {
+ buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname),
+ buf_p, SPACE_FOR_FNAME + 1);
}
switch (bufIsChanged(curbuf)
- + (curbuf->b_p_ro * 2)
- + (!MODIFIABLE(curbuf) * 4)) {
- case 1: STRCAT(buf, " +"); break;
- case 2: STRCAT(buf, " ="); break;
- case 3: STRCAT(buf, " =+"); break;
- case 4:
- case 6: STRCAT(buf, " -"); break;
- case 5:
- case 7: STRCAT(buf, " -+"); break;
+ | (curbuf->b_p_ro << 1)
+ | (!MODIFIABLE(curbuf) << 2)) {
+ case 0: break;
+ case 1: buf_p = strappend(buf_p, " +"); break;
+ case 2: buf_p = strappend(buf_p, " ="); break;
+ case 3: buf_p = strappend(buf_p, " =+"); break;
+ case 4:
+ case 6: buf_p = strappend(buf_p, " -"); break;
+ case 5:
+ case 7: buf_p = strappend(buf_p, " -+"); break;
+ default: assert(false);
}
if (curbuf->b_fname != NULL) {
- /* Get path of file, replace home dir with ~ */
- off = (int)STRLEN(buf);
- buf[off++] = ' ';
- buf[off++] = '(';
- home_replace(curbuf, curbuf->b_ffname,
- buf + off, SPACE_FOR_DIR - off, TRUE);
+ // Get path of file, replace home dir with ~.
+ *buf_p++ = ' ';
+ *buf_p++ = '(';
+ home_replace(curbuf, curbuf->b_ffname, (char_u *)buf_p,
+ (SPACE_FOR_DIR - (size_t)(buf_p - buf)), true);
#ifdef BACKSLASH_IN_FILENAME
- /* avoid "c:/name" to be reduced to "c" */
- if (isalpha(buf[off]) && buf[off + 1] == ':')
- off += 2;
+ // Avoid "c:/name" to be reduced to "c".
+ if (isalpha((uint8_t)buf_p) && *(buf_p + 1) == ':') {
+ buf_p += 2;
+ }
#endif
- /* remove the file name */
- p = path_tail_with_sep(buf + off);
- if (p == buf + off)
- /* must be a help buffer */
- STRLCPY(buf + off, _("help"), SPACE_FOR_DIR - off);
- else
+ // Remove the file name.
+ char *p = (char *)path_tail_with_sep((char_u *)buf_p);
+ if (p == buf_p) {
+ // Must be a help buffer.
+ xstrlcpy(buf_p, _("help"), SPACE_FOR_DIR - (size_t)(buf_p - buf));
+ } else {
*p = NUL;
+ }
- /* Translate unprintable chars and concatenate. Keep some
- * room for the server name. When there is no room (very long
- * file name) use (...). */
- if (off < SPACE_FOR_DIR) {
- p = transstr(buf + off);
- STRLCPY(buf + off, p, SPACE_FOR_DIR - off + 1);
- xfree(p);
+ // Translate unprintable chars and concatenate. Keep some
+ // room for the server name. When there is no room (very long
+ // file name) use (...).
+ if ((size_t)(buf_p - buf) < SPACE_FOR_DIR) {
+ char *const tbuf = transstr(buf_p);
+ const size_t free_space = SPACE_FOR_DIR - (size_t)(buf_p - buf) + 1;
+ const size_t dir_len = xstrlcpy(buf_p, tbuf, free_space);
+ buf_p += MIN(dir_len, free_space - 1);
+ xfree(tbuf);
} else {
- STRLCPY(buf + off, "...", SPACE_FOR_ARGNR - off + 1);
+ const size_t free_space = SPACE_FOR_ARGNR - (size_t)(buf_p - buf) + 1;
+ const size_t dots_len = xstrlcpy(buf_p, "...", free_space);
+ buf_p += MIN(dots_len, free_space - 1);
}
- STRCAT(buf, ")");
+ *buf_p++ = ')';
+ *buf_p = NUL;
+ } else {
+ *buf_p = NUL;
}
- append_arg_number(curwin, buf, SPACE_FOR_ARGNR, FALSE);
+ append_arg_number(curwin, (char_u *)buf_p,
+ (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf)), false);
- STRCAT(buf, " - NVIM");
+ xstrlcat(buf_p, " - NVIM", (sizeof(buf) - (size_t)(buf_p - buf)));
if (maxlen > 0) {
- /* make it shorter by removing a bit in the middle */
- if (vim_strsize(buf) > maxlen)
- trunc_string(buf, buf, maxlen, IOSIZE);
+ // Make it shorter by removing a bit in the middle.
+ if (vim_strsize((char_u *)buf) > maxlen) {
+ trunc_string((char_u *)buf, (char_u *)buf, maxlen, sizeof(buf));
+ }
}
+ t_str = (char_u *)buf;
+#undef SPACE_FOR_FNAME
+#undef SPACE_FOR_DIR
+#undef SPACE_FOR_ARGNR
}
}
mustset = ti_change(t_str, &lasttitle);
if (p_icon) {
- i_str = buf;
+ i_str = (char_u *)buf;
if (*p_iconstring != NUL) {
if (stl_syntax & STL_IN_ICON) {
int use_sandbox = FALSE;
@@ -2819,13 +3133,13 @@ static bool ti_change(char_u *str, char_u **last)
return false;
}
-/*
- * Put current window title back (used after calling a shell)
- */
+
+/// Set current window title
void resettitle(void)
{
- ui_set_title((char *)lasttitle);
- ui_set_icon((char *)lasticon);
+ ui_call_set_icon(cstr_as_string((char *)lasticon));
+ ui_call_set_title(cstr_as_string((char *)lasttitle));
+ ui_flush();
}
# if defined(EXITFREE)
@@ -2841,7 +3155,6 @@ void free_titles(void)
/// be used when printing numbers in the status line.
typedef enum {
kNumBaseDecimal = 10,
- kNumBaseOctal = 8,
kNumBaseHexadecimal = 16
} NumberBase;
@@ -2877,13 +3190,13 @@ int build_stl_str_hl(
size_t outlen,
char_u *fmt,
int use_sandbox,
- int fillchar,
+ char_u fillchar,
int maxwidth,
struct stl_hlrec *hltab,
StlClickRecord *tabtab
)
{
- int groupitem[STL_MAX_ITEM];
+ int groupitems[STL_MAX_ITEM];
struct stl_item {
// Where the item starts in the status line output buffer
char_u *start;
@@ -2903,7 +3216,7 @@ int build_stl_str_hl(
ClickFunc,
Trunc
} type;
- } item[STL_MAX_ITEM];
+ } items[STL_MAX_ITEM];
#define TMPLEN 70
char_u tmp[TMPLEN];
char_u *usefmt = fmt;
@@ -2929,10 +3242,11 @@ int build_stl_str_hl(
// Get the byte value now, in case we need it below. This is more
// efficient than making a copy of the line.
int byteval;
- if (wp->w_cursor.col > (colnr_T)STRLEN(line_ptr))
+ if (wp->w_cursor.col > (colnr_T)STRLEN(line_ptr)) {
byteval = 0;
- else
- byteval = (*mb_ptr2char)(line_ptr + wp->w_cursor.col);
+ } else {
+ byteval = utf_ptr2char(line_ptr + wp->w_cursor.col);
+ }
int groupdepth = 0;
@@ -2990,9 +3304,6 @@ int build_stl_str_hl(
// Two `%` in a row is the escape sequence to print a
// single `%` in the output buffer.
if (*fmt_p == '%') {
- // Ignore the character if we're out of room in the output buffer.
- if (out_p >= out_end_p)
- break;
*out_p++ = *fmt_p++;
prevchar_isflag = prevchar_isitem = false;
continue;
@@ -3005,16 +3316,16 @@ int build_stl_str_hl(
if (groupdepth > 0) {
continue;
}
- item[curitem].type = Separate;
- item[curitem++].start = out_p;
+ items[curitem].type = Separate;
+ items[curitem++].start = out_p;
continue;
}
// STL_TRUNCMARK: Where to begin truncating if the statusline is too long.
if (*fmt_p == STL_TRUNCMARK) {
fmt_p++;
- item[curitem].type = Trunc;
- item[curitem++].start = out_p;
+ items[curitem].type = Trunc;
+ items[curitem++].start = out_p;
continue;
}
@@ -3030,7 +3341,7 @@ int build_stl_str_hl(
// Determine how long the group is.
// Note: We set the current output position to null
// so `vim_strsize` will work.
- char_u *t = item[groupitem[groupdepth]].start;
+ char_u *t = items[groupitems[groupdepth]].start;
*out_p = NUL;
long group_len = vim_strsize(t);
@@ -3040,11 +3351,11 @@ int build_stl_str_hl(
// move the output pointer back to where the group started.
// Note: This erases any non-item characters that were in the group.
// Otherwise there would be no reason to do this step.
- if (curitem > groupitem[groupdepth] + 1
- && item[groupitem[groupdepth]].minwid == 0) {
+ if (curitem > groupitems[groupdepth] + 1
+ && items[groupitems[groupdepth]].minwid == 0) {
bool has_normal_items = false;
- for (long n = groupitem[groupdepth] + 1; n < curitem; n++) {
- if (item[n].type == Normal || item[n].type == Highlight) {
+ for (long n = groupitems[groupdepth] + 1; n < curitem; n++) {
+ if (items[n].type == Normal || items[n].type == Highlight) {
has_normal_items = true;
break;
}
@@ -3058,18 +3369,18 @@ int build_stl_str_hl(
// If the group is longer than it is allowed to be
// truncate by removing bytes from the start of the group text.
- if (group_len > item[groupitem[groupdepth]].maxwid) {
+ if (group_len > items[groupitems[groupdepth]].maxwid) {
// { Determine the number of bytes to remove
long n;
if (has_mbyte) {
/* Find the first character that should be included. */
n = 0;
- while (group_len >= item[groupitem[groupdepth]].maxwid) {
+ while (group_len >= items[groupitems[groupdepth]].maxwid) {
group_len -= ptr2cells(t + n);
n += (*mb_ptr2len)(t + n);
}
} else {
- n = (long)(out_p - t) - item[groupitem[groupdepth]].maxwid + 1;
+ n = (long)(out_p - t) - items[groupitems[groupdepth]].maxwid + 1;
}
// }
@@ -3079,25 +3390,26 @@ int build_stl_str_hl(
// { Move the truncated output
memmove(t + 1, t + n, (size_t)(out_p - (t + n)));
out_p = out_p - n + 1;
- /* Fill up space left over by half a double-wide char. */
- while (++group_len < item[groupitem[groupdepth]].minwid)
+ // Fill up space left over by half a double-wide char.
+ while (++group_len < items[groupitems[groupdepth]].minwid) {
*out_p++ = fillchar;
+ }
// }
- /* correct the start of the items for the truncation */
- for (int idx = groupitem[groupdepth] + 1; idx < curitem; idx++) {
+ // correct the start of the items for the truncation
+ for (int idx = groupitems[groupdepth] + 1; idx < curitem; idx++) {
// Shift everything back by the number of removed bytes
- item[idx].start -= n;
+ items[idx].start -= n;
// If the item was partially or completely truncated, set its
// start to the start of the group
- if (item[idx].start < t) {
- item[idx].start = t;
+ if (items[idx].start < t) {
+ items[idx].start = t;
}
}
// If the group is shorter than the minimum width, add padding characters.
- } else if (abs(item[groupitem[groupdepth]].minwid) > group_len) {
- long min_group_width = item[groupitem[groupdepth]].minwid;
+ } else if (abs(items[groupitems[groupdepth]].minwid) > group_len) {
+ long min_group_width = items[groupitems[groupdepth]].minwid;
// If the group is left-aligned, add characters to the right.
if (min_group_width < 0) {
min_group_width = 0 - min_group_width;
@@ -3116,8 +3428,8 @@ int build_stl_str_hl(
// }
// Adjust item start positions
- for (int n = groupitem[groupdepth] + 1; n < curitem; n++) {
- item[n].start += group_len;
+ for (int n = groupitems[groupdepth] + 1; n < curitem; n++) {
+ items[n].start += group_len;
}
// Prepend the fill characters
@@ -3155,9 +3467,9 @@ int build_stl_str_hl(
// User highlight groups override the min width field
// to denote the styling to use.
if (*fmt_p == STL_USER_HL) {
- item[curitem].type = Highlight;
- item[curitem].start = out_p;
- item[curitem].minwid = minwid > 9 ? 1 : minwid;
+ items[curitem].type = Highlight;
+ items[curitem].start = out_p;
+ items[curitem].minwid = minwid > 9 ? 1 : minwid;
fmt_p++;
curitem++;
continue;
@@ -3189,20 +3501,21 @@ int build_stl_str_hl(
if (*fmt_p == STL_TABPAGENR || *fmt_p == STL_TABCLOSENR) {
if (*fmt_p == STL_TABCLOSENR) {
if (minwid == 0) {
- /* %X ends the close label, go back to the previously
- * define tab label nr. */
- for (long n = curitem - 1; n >= 0; --n)
- if (item[n].type == TabPage && item[n].minwid >= 0) {
- minwid = item[n].minwid;
+ // %X ends the close label, go back to the previous tab label nr.
+ for (long n = curitem - 1; n >= 0; n--) {
+ if (items[n].type == TabPage && items[n].minwid >= 0) {
+ minwid = items[n].minwid;
break;
}
- } else
- /* close nrs are stored as negative values */
+ }
+ } else {
+ // close nrs are stored as negative values
minwid = -minwid;
+ }
}
- item[curitem].type = TabPage;
- item[curitem].start = out_p;
- item[curitem].minwid = minwid;
+ items[curitem].type = TabPage;
+ items[curitem].start = out_p;
+ items[curitem].minwid = minwid;
fmt_p++;
curitem++;
continue;
@@ -3217,10 +3530,10 @@ int build_stl_str_hl(
if (*fmt_p != STL_CLICK_FUNC) {
break;
}
- item[curitem].type = ClickFunc;
- item[curitem].start = out_p;
- item[curitem].cmd = xmemdupz(t, (size_t) (((char *) fmt_p - t)));
- item[curitem].minwid = minwid;
+ items[curitem].type = ClickFunc;
+ items[curitem].start = out_p;
+ items[curitem].cmd = xmemdupz(t, (size_t)(((char *)fmt_p - t)));
+ items[curitem].minwid = minwid;
fmt_p++;
curitem++;
continue;
@@ -3243,11 +3556,11 @@ int build_stl_str_hl(
// Denotes the start of a new group
if (*fmt_p == '(') {
- groupitem[groupdepth++] = curitem;
- item[curitem].type = Group;
- item[curitem].start = out_p;
- item[curitem].minwid = minwid;
- item[curitem].maxwid = maxwid;
+ groupitems[groupdepth++] = curitem;
+ items[curitem].type = Group;
+ items[curitem].start = out_p;
+ items[curitem].minwid = minwid;
+ items[curitem].maxwid = maxwid;
fmt_p++;
curitem++;
continue;
@@ -3274,7 +3587,7 @@ int build_stl_str_hl(
case STL_FULLPATH:
case STL_FILENAME:
{
- // Set fillable to false to that ' ' in the filename will not
+ // Set fillable to false so that ' ' in the filename will not
// get replaced with the fillchar
fillable = false;
if (buf_spname(wp->w_buffer) != NULL) {
@@ -3313,7 +3626,7 @@ int build_stl_str_hl(
// Store the current buffer number as a string variable
vim_snprintf((char *)tmp, sizeof(tmp), "%d", curbuf->b_fnum);
- set_internal_string_var((char_u *)"actual_curbuf", tmp);
+ set_internal_string_var((char_u *)"g:actual_curbuf", tmp);
buf_T *o_curbuf = curbuf;
win_T *o_curwin = curwin;
@@ -3327,7 +3640,7 @@ int build_stl_str_hl(
curbuf = o_curbuf;
// Remove the variable we just stored
- do_unlet((char_u *)"g:actual_curbuf", true);
+ do_unlet(S_LEN("g:actual_curbuf"), true);
// }
@@ -3409,7 +3722,7 @@ int build_stl_str_hl(
case STL_KEYMAP:
fillable = false;
- if (get_keymap_str(wp, tmp, TMPLEN))
+ if (get_keymap_str(wp, (char_u *)"<%s>", tmp, TMPLEN))
str = tmp;
break;
case STL_PAGENUM:
@@ -3422,9 +3735,11 @@ int build_stl_str_hl(
case STL_OFFSET_X:
base = kNumBaseHexadecimal;
+ FALLTHROUGH;
case STL_OFFSET:
{
- long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL);
+ long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL,
+ false);
num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0 ?
0L : l + 1 + (!(State & INSERT) && empty_line ?
0 : (int)wp->w_cursor.col);
@@ -3432,6 +3747,7 @@ int build_stl_str_hl(
}
case STL_BYTEVAL_X:
base = kNumBaseHexadecimal;
+ FALLTHROUGH;
case STL_BYTEVAL:
num = byteval;
if (num == NL)
@@ -3479,7 +3795,7 @@ int build_stl_str_hl(
wp->w_buffer->b_p_ft);
// Uppercase the file extension
for (char_u *t = tmp; *t != 0; t++) {
- *t = TOUPPER_LOC(*t);
+ *t = (char_u)TOUPPER_LOC(*t);
}
str = tmp;
}
@@ -3526,9 +3842,9 @@ int build_stl_str_hl(
// Create a highlight item based on the name
if (*fmt_p == '#') {
- item[curitem].type = Highlight;
- item[curitem].start = out_p;
- item[curitem].minwid = -syn_namen2id(t, (int)(fmt_p - t));
+ items[curitem].type = Highlight;
+ items[curitem].start = out_p;
+ items[curitem].minwid = -syn_namen2id(t, (int)(fmt_p - t));
curitem++;
fmt_p++;
}
@@ -3539,8 +3855,8 @@ int build_stl_str_hl(
// If we made it this far, the item is normal and starts at
// our current position in the output buffer.
// Non-normal items would have `continued`.
- item[curitem].start = out_p;
- item[curitem].type = Normal;
+ items[curitem].start = out_p;
+ items[curitem].type = Normal;
// Copy the item string into the output buffer
if (str != NULL && *str) {
@@ -3635,9 +3951,7 @@ int build_stl_str_hl(
// Note: The `*` means we take the width as one of the arguments
*t++ = '*';
- *t++ = (char_u) (base == kNumBaseHexadecimal ? 'X'
- : (base == kNumBaseOctal ? 'o'
- : 'd'));
+ *t++ = (char_u)(base == kNumBaseHexadecimal ? 'X' : 'd');
*t = 0;
// }
@@ -3656,7 +3970,8 @@ int build_stl_str_hl(
}
// }
- size_t remaining_buf_len = (out_end_p - out_p) + 1;
+ assert(out_end_p >= out_p);
+ size_t remaining_buf_len = (size_t)(out_end_p - out_p) + 1;
// If the number is going to take up too much room
// Figure out the approximate number in "scientific" type notation.
@@ -3671,7 +3986,7 @@ int build_stl_str_hl(
// { Reduce the number by base^n
while (num_chars-- > maxwid) {
- num /= base;
+ num /= (long)base;
}
// }
@@ -3696,7 +4011,7 @@ int build_stl_str_hl(
// Otherwise, there was nothing to print so mark the item as empty
} else {
- item[curitem].type = Empty;
+ items[curitem].type = Empty;
}
// Only free the string buffer if we allocated it.
@@ -3721,8 +4036,7 @@ int build_stl_str_hl(
}
// We have now processed the entire statusline format string.
- // What follows is post-processing to handle alignment and
- // highlighting factors.
+ // What follows is post-processing to handle alignment and highlighting.
int width = vim_strsize(out);
if (maxwidth > 0 && width > maxwidth) {
@@ -3737,16 +4051,17 @@ int build_stl_str_hl(
// Otherwise, look for the truncation item
} else {
// Default to truncating at the first item
- trunc_p = item[0].start;
+ trunc_p = items[0].start;
item_idx = 0;
- for (int i = 0; i < itemcnt; i++)
- if (item[i].type == Trunc) {
- // Truncate at %< item.
- trunc_p = item[i].start;
+ for (int i = 0; i < itemcnt; i++) {
+ if (items[i].type == Trunc) {
+ // Truncate at %< items.
+ trunc_p = items[i].start;
item_idx = i;
break;
}
+ }
}
// If the truncation point we found is beyond the maximum
@@ -3776,7 +4091,7 @@ int build_stl_str_hl(
// Ignore any items in the statusline that occur after
// the truncation point
for (int i = 0; i < itemcnt; i++) {
- if (item[i].start > trunc_p) {
+ if (items[i].start > trunc_p) {
itemcnt = i;
break;
}
@@ -3831,12 +4146,12 @@ int build_stl_str_hl(
for (int i = item_idx; i < itemcnt; i++) {
// Items starting at or after the end of the truncated section need
// to be moved backwards.
- if (item[i].start >= trunc_end_p) {
- item[i].start -= item_offset;
+ if (items[i].start >= trunc_end_p) {
+ items[i].start -= item_offset;
// Anything inside the truncated area is set to start
// at the `<` truncation character.
} else {
- item[i].start = trunc_p;
+ items[i].start = trunc_p;
}
}
// }
@@ -3847,12 +4162,12 @@ int build_stl_str_hl(
// add characters at the separate marker (if there is one) to
// fill up the available space.
} else if (width < maxwidth
- && STRLEN(out) + maxwidth - width + 1 < outlen) {
+ && STRLEN(out) + (size_t)(maxwidth - width) + 1 < outlen) {
// Find how many separators there are, which we will use when
// figuring out how many groups there are.
int num_separators = 0;
for (int i = 0; i < itemcnt; i++) {
- if (item[i].type == Separate) {
+ if (items[i].type == Separate) {
num_separators++;
}
}
@@ -3864,7 +4179,7 @@ int build_stl_str_hl(
int separator_locations[STL_MAX_ITEM];
int index = 0;
for (int i = 0; i < itemcnt; i++) {
- if (item[i].type == Separate) {
+ if (items[i].type == Separate) {
separator_locations[index] = i;
index++;
}
@@ -3875,18 +4190,18 @@ int build_stl_str_hl(
standard_spaces * (num_separators - 1);
for (int i = 0; i < num_separators; i++) {
- int dislocation = (i == (num_separators - 1)) ?
- final_spaces : standard_spaces;
- char_u *sep_loc = item[separator_locations[i]].start + dislocation;
- STRMOVE(sep_loc, item[separator_locations[i]].start);
- for (char_u *s = item[separator_locations[i]].start; s < sep_loc; s++) {
+ int dislocation = (i == (num_separators - 1))
+ ? final_spaces : standard_spaces;
+ char_u *seploc = items[separator_locations[i]].start + dislocation;
+ STRMOVE(seploc, items[separator_locations[i]].start);
+ for (char_u *s = items[separator_locations[i]].start; s < seploc; s++) {
*s = fillchar;
}
for (int item_idx = separator_locations[i] + 1;
item_idx < itemcnt;
item_idx++) {
- item[item_idx].start += dislocation;
+ items[item_idx].start += dislocation;
}
}
@@ -3898,9 +4213,9 @@ int build_stl_str_hl(
if (hltab != NULL) {
struct stl_hlrec *sp = hltab;
for (long l = 0; l < itemcnt; l++) {
- if (item[l].type == Highlight) {
- sp->start = item[l].start;
- sp->userhl = item[l].minwid;
+ if (items[l].type == Highlight) {
+ sp->start = items[l].start;
+ sp->userhl = items[l].minwid;
sp++;
}
}
@@ -3912,14 +4227,14 @@ int build_stl_str_hl(
if (tabtab != NULL) {
StlClickRecord *cur_tab_rec = tabtab;
for (long l = 0; l < itemcnt; l++) {
- if (item[l].type == TabPage) {
- cur_tab_rec->start = (char *) item[l].start;
- if (item[l].minwid == 0) {
+ if (items[l].type == TabPage) {
+ cur_tab_rec->start = (char *)items[l].start;
+ if (items[l].minwid == 0) {
cur_tab_rec->def.type = kStlClickDisabled;
cur_tab_rec->def.tabnr = 0;
} else {
- int tabnr = item[l].minwid;
- if (item[l].minwid > 0) {
+ int tabnr = items[l].minwid;
+ if (items[l].minwid > 0) {
cur_tab_rec->def.type = kStlClickTabSwitch;
} else {
cur_tab_rec->def.type = kStlClickTabClose;
@@ -3929,11 +4244,11 @@ int build_stl_str_hl(
}
cur_tab_rec->def.func = NULL;
cur_tab_rec++;
- } else if (item[l].type == ClickFunc) {
- cur_tab_rec->start = (char *) item[l].start;
+ } else if (items[l].type == ClickFunc) {
+ cur_tab_rec->start = (char *)items[l].start;
cur_tab_rec->def.type = kStlClickFuncRun;
- cur_tab_rec->def.tabnr = item[l].minwid;
- cur_tab_rec->def.func = item[l].cmd;
+ cur_tab_rec->def.tabnr = items[l].minwid;
+ cur_tab_rec->def.func = items[l].cmd;
cur_tab_rec++;
}
}
@@ -4028,14 +4343,12 @@ void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname)
#ifdef WIN32
if (!buf->b_p_bin) {
- char_u *rfname;
-
- /* If the file name is a shortcut file, use the file it links to. */
- rfname = mch_resolve_shortcut(*ffname);
+ // If the file name is a shortcut file, use the file it links to.
+ char *rfname = os_resolve_shortcut((const char *)(*ffname));
if (rfname != NULL) {
xfree(*ffname);
- *ffname = rfname;
- *sfname = rfname;
+ *ffname = (char_u *)rfname;
+ *sfname = (char_u *)rfname;
}
}
#endif
@@ -4085,6 +4398,8 @@ do_arg_all (
win_T *new_curwin = NULL;
tabpage_T *new_curtab = NULL;
+ assert(firstwin != NULL); // satisfy coverity
+
if (ARGCOUNT <= 0) {
/* Don't give an error message. We don't want it when the ":all"
* command is in the .vimrc. */
@@ -4093,7 +4408,7 @@ do_arg_all (
setpcmark();
opened_len = ARGCOUNT;
- opened = xcalloc(opened_len, 1);
+ opened = xcalloc((size_t)opened_len, 1);
/* Autocommands may do anything to the argument list. Make sure it's not
* freed while we are working here by "locking" it. We still have to
@@ -4121,17 +4436,15 @@ do_arg_all (
wpnext = wp->w_next;
buf = wp->w_buffer;
if (buf->b_ffname == NULL
- || (!keep_tabs && buf->b_nwindows > 1)
- || wp->w_width != Columns
- )
+ || (!keep_tabs && (buf->b_nwindows > 1 || wp->w_width != Columns))) {
i = opened_len;
- else {
- /* check if the buffer in this window is in the arglist */
+ } else {
+ // check if the buffer in this window is in the arglist
for (i = 0; i < opened_len; ++i) {
if (i < alist->al_ga.ga_len
&& (AARGLIST(alist)[i].ae_fnum == buf->b_fnum
|| path_full_compare(alist_name(&AARGLIST(alist)[i]),
- buf->b_ffname, TRUE) & kEqualFiles)) {
+ buf->b_ffname, true) & kEqualFiles)) {
int weight = 1;
if (old_curtab == curtab) {
@@ -4164,29 +4477,32 @@ do_arg_all (
}
wp->w_arg_idx = i;
- if (i == opened_len && !keep_tabs) { /* close this window */
- if (P_HID(buf) || forceit || buf->b_nwindows > 1
+ if (i == opened_len && !keep_tabs) { // close this window
+ if (buf_hide(buf) || forceit || buf->b_nwindows > 1
|| !bufIsChanged(buf)) {
/* If the buffer was changed, and we would like to hide it,
* try autowriting. */
- if (!P_HID(buf) && buf->b_nwindows <= 1
- && bufIsChanged(buf)) {
- (void)autowrite(buf, FALSE);
- /* check if autocommands removed the window */
- if (!win_valid(wp) || !buf_valid(buf)) {
- wpnext = firstwin; /* start all over... */
+ if (!buf_hide(buf) && buf->b_nwindows <= 1 && bufIsChanged(buf)) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ (void)autowrite(buf, false);
+ // Check if autocommands removed the window.
+ if (!win_valid(wp) || !bufref_valid(&bufref)) {
+ wpnext = firstwin; // Start all over...
continue;
}
}
- /* don't close last window */
- if (firstwin == lastwin
- && (first_tabpage->tp_next == NULL || !had_tab))
- use_firstwin = TRUE;
- else {
- win_close(wp, !P_HID(buf) && !bufIsChanged(buf));
- /* check if autocommands removed the next window */
- if (!win_valid(wpnext))
- wpnext = firstwin; /* start all over... */
+ // don't close last window
+ if (ONE_WINDOW
+ && (first_tabpage->tp_next == NULL || !had_tab)) {
+ use_firstwin = true;
+ } else {
+ win_close(wp, !buf_hide(buf) && !bufIsChanged(buf));
+ // check if autocommands removed the next window
+ if (!win_valid(wpnext)) {
+ // start all over...
+ wpnext = firstwin;
+ }
}
}
}
@@ -4215,15 +4531,17 @@ do_arg_all (
last_curwin = curwin;
last_curtab = curtab;
win_enter(lastwin, false);
- /* ":drop all" should re-use an empty window to avoid "--remote-tab"
- * leaving an empty tab page when executed locally. */
- if (keep_tabs && bufempty() && curbuf->b_nwindows == 1
- && curbuf->b_ffname == NULL && !curbuf->b_changed)
- use_firstwin = TRUE;
-
- for (i = 0; i < count && i < opened_len && !got_int; ++i) {
- if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1)
- arg_had_last = TRUE;
+ // ":drop all" should re-use an empty window to avoid "--remote-tab"
+ // leaving an empty tab page when executed locally.
+ if (keep_tabs && BUFEMPTY() && curbuf->b_nwindows == 1
+ && curbuf->b_ffname == NULL && !curbuf->b_changed) {
+ use_firstwin = true;
+ }
+
+ for (i = 0; i < count && i < opened_len && !got_int; i++) {
+ if (alist == &global_alist && i == global_alist.al_ga.ga_len - 1) {
+ arg_had_last = true;
+ }
if (opened[i] > 0) {
/* Move the already present window to below the current window */
if (curwin->w_arg_idx != i) {
@@ -4258,14 +4576,15 @@ do_arg_all (
new_curwin = curwin;
new_curtab = curtab;
}
- (void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL,
- ECMD_ONE,
- ((P_HID(curwin->w_buffer)
- || bufIsChanged(curwin->w_buffer)) ? ECMD_HIDE : 0)
- + ECMD_OLDBUF, curwin);
- if (use_firstwin)
- ++autocmd_no_leave;
- use_firstwin = FALSE;
+ (void)do_ecmd(0, alist_name(&AARGLIST(alist)[i]), NULL, NULL, ECMD_ONE,
+ ((buf_hide(curwin->w_buffer)
+ || bufIsChanged(curwin->w_buffer))
+ ? ECMD_HIDE : 0) + ECMD_OLDBUF,
+ curwin);
+ if (use_firstwin) {
+ autocmd_no_leave++;
+ }
+ use_firstwin = false;
}
os_breakcheck();
@@ -4277,19 +4596,23 @@ do_arg_all (
/* Remove the "lock" on the argument list. */
alist_unlink(alist);
- --autocmd_no_enter;
- /* restore last referenced tabpage's curwin */
+ autocmd_no_enter--;
+ // restore last referenced tabpage's curwin
if (last_curtab != new_curtab) {
- if (valid_tabpage(last_curtab))
- goto_tabpage_tp(last_curtab, TRUE, TRUE);
- if (win_valid(last_curwin))
+ if (valid_tabpage(last_curtab)) {
+ goto_tabpage_tp(last_curtab, true, true);
+ }
+ if (win_valid(last_curwin)) {
win_enter(last_curwin, false);
+ }
+ }
+ // to window with first arg
+ if (valid_tabpage(new_curtab)) {
+ goto_tabpage_tp(new_curtab, true, true);
}
- /* to window with first arg */
- if (valid_tabpage(new_curtab))
- goto_tabpage_tp(new_curtab, TRUE, TRUE);
- if (win_valid(new_curwin))
+ if (win_valid(new_curwin)) {
win_enter(new_curwin, false);
+ }
--autocmd_no_leave;
xfree(opened);
@@ -4306,8 +4629,8 @@ void ex_buffer_all(exarg_T *eap)
bool p_ea_save;
int open_wins = 0;
int r;
- int count; /* Maximum number of windows to open. */
- int all; /* When TRUE also load inactive buffers. */
+ long count; // Maximum number of windows to open.
+ int all; // When TRUE also load inactive buffers.
int had_tab = cmdmod.tab;
tabpage_T *tpnext;
@@ -4338,14 +4661,14 @@ void ex_buffer_all(exarg_T *eap)
? wp->w_height + wp->w_status_height < Rows - p_ch
- tabline_height()
: wp->w_width != Columns)
- || (had_tab > 0 && wp != firstwin)
- ) && firstwin != lastwin
- && !(wp->w_closing || wp->w_buffer->b_closing)
+ || (had_tab > 0 && wp != firstwin))
+ && !ONE_WINDOW
+ && !(wp->w_closing || wp->w_buffer->b_locked > 0)
) {
- win_close(wp, FALSE);
- wpnext = firstwin; /* just in case an autocommand does
- something strange with windows */
- tpnext = first_tabpage; /* start all over...*/
+ win_close(wp, false);
+ wpnext = firstwin; // just in case an autocommand does
+ // something strange with windows
+ tpnext = first_tabpage; // start all over...
open_wins = 0;
} else
++open_wins;
@@ -4388,7 +4711,9 @@ void ex_buffer_all(exarg_T *eap)
}
if (wp == NULL && split_ret == OK) {
- /* Split the window and put the buffer in it */
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ // Split the window and put the buffer in it.
p_ea_save = p_ea;
p_ea = true; /* use space from all windows */
split_ret = win_split(0, WSP_ROOM | WSP_BELOW);
@@ -4400,7 +4725,8 @@ void ex_buffer_all(exarg_T *eap)
/* Open the buffer in this window. */
swap_exists_action = SEA_DIALOG;
set_curbuf(buf, DOBUF_GOTO);
- if (!buf_valid(buf)) { /* autocommands deleted the buffer!!! */
+ if (!bufref_valid(&bufref)) {
+ // Autocommands deleted the buffer.
swap_exists_action = SEA_NONE;
break;
}
@@ -4411,9 +4737,9 @@ void ex_buffer_all(exarg_T *eap)
* aborting() returns FALSE when closing a window. */
enter_cleanup(&cs);
- /* User selected Quit at ATTENTION prompt; close this window. */
- win_close(curwin, TRUE);
- --open_wins;
+ // User selected Quit at ATTENTION prompt; close this window.
+ win_close(curwin, true);
+ open_wins--;
swap_exists_action = SEA_NONE;
swap_exists_did_quit = TRUE;
@@ -4445,14 +4771,14 @@ void ex_buffer_all(exarg_T *eap)
* Close superfluous windows.
*/
for (wp = lastwin; open_wins > count; ) {
- r = (P_HID(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
- || autowrite(wp->w_buffer, FALSE) == OK);
+ r = (buf_hide(wp->w_buffer) || !bufIsChanged(wp->w_buffer)
+ || autowrite(wp->w_buffer, false) == OK);
if (!win_valid(wp)) {
/* BufWrite Autocommands made the window invalid, start over */
wp = lastwin;
} else if (r) {
- win_close(wp, !P_HID(wp->w_buffer));
- --open_wins;
+ win_close(wp, !buf_hide(wp->w_buffer));
+ open_wins--;
wp = lastwin;
} else {
wp = wp->w_prev;
@@ -4514,7 +4840,7 @@ chk_modeline (
char_u *e;
char_u *linecopy; /* local copy of any modeline found */
int prev;
- int vers;
+ intmax_t vers;
int end;
int retval = OK;
char_u *save_sourcing_name;
@@ -4533,7 +4859,10 @@ chk_modeline (
e = s + 4;
else
e = s + 3;
- vers = getdigits_int(&e);
+ if (getdigits_safe(&e, &vers) != OK) {
+ continue;
+ }
+
if (*e == ':'
&& (s[0] != 'V'
|| STRNCMP(skipwhite(e + 1), "set", 3) == 0)
@@ -4541,8 +4870,9 @@ chk_modeline (
|| (VIM_VERSION_100 >= vers && isdigit(s[3]))
|| (VIM_VERSION_100 < vers && s[3] == '<')
|| (VIM_VERSION_100 > vers && s[3] == '>')
- || (VIM_VERSION_100 == vers && s[3] == '=')))
+ || (VIM_VERSION_100 == vers && s[3] == '='))) {
break;
+ }
}
}
prev = *s;
@@ -4614,6 +4944,12 @@ chk_modeline (
return retval;
}
+// Return true if "buf" is a help buffer.
+bool bt_help(const buf_T *const buf)
+{
+ return buf != NULL && buf->b_help;
+}
+
/*
* Return special buffer name.
* Returns NULL when the buffer has a normal file name.
@@ -4753,13 +5089,16 @@ linenr_T buf_change_sign_type(
return (linenr_T)0;
}
-int buf_getsigntype(
- buf_T *buf,
- linenr_T lnum,
- int type /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */
- )
+/// Gets a sign from a given line.
+/// In case of multiple signs, returns the most recently placed one.
+///
+/// @param buf Buffer in which to search
+/// @param lnum Line in which to search
+/// @param type Type of sign to look for
+/// @return Identifier of the first matching sign, or 0
+int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type)
{
- signlist_T *sign; /* a sign in a b_signlist */
+ signlist_T *sign; // a sign in a b_signlist
for (sign = buf->b_signlist; sign != NULL; sign = sign->next) {
if (sign->lnum == lnum
@@ -4767,7 +5106,9 @@ int buf_getsigntype(
|| (type == SIGN_TEXT
&& sign_get_text(sign->typenr) != NULL)
|| (type == SIGN_LINEHL
- && sign_get_attr(sign->typenr, TRUE) != 0))) {
+ && sign_get_attr(sign->typenr, SIGN_LINEHL) != 0)
+ || (type == SIGN_NUMHL
+ && sign_get_attr(sign->typenr, SIGN_NUMHL) != 0))) {
return sign->typenr;
}
}
@@ -4824,7 +5165,7 @@ int buf_findsign(
for (sign = buf->b_signlist; sign != NULL; sign = sign->next) {
if (sign->id == id) {
- return sign->lnum;
+ return (int)sign->lnum;
}
}
@@ -4900,7 +5241,7 @@ void sign_list_placed(buf_T *rbuf)
while (buf != NULL && !got_int) {
if (buf->b_signlist != NULL) {
vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname);
- MSG_PUTS_ATTR(lbuf, hl_attr(HLF_D));
+ MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D));
msg_putchar('\n');
}
for (p = buf->b_signlist; p != NULL && !got_int; p = p->next) {
@@ -4938,6 +5279,30 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a
// bufhl: plugin highlights associated with a buffer
+/// Get reference to line in kbtree_t
+///
+/// @param b the three
+/// @param line the linenumber to lookup
+/// @param put if true, put a new line when not found
+/// if false, return NULL when not found
+BufhlLine *bufhl_tree_ref(BufhlInfo *b, linenr_T line, bool put)
+{
+ BufhlLine t = BUFHLLINE_INIT(line);
+
+ // kp_put() only works if key is absent, try get first
+ BufhlLine **pp = kb_get(bufhl, b, &t);
+ if (pp) {
+ return *pp;
+ } else if (!put) {
+ return NULL;
+ }
+
+ BufhlLine *p = xmalloc(sizeof(*p));
+ *p = (BufhlLine)BUFHLLINE_INIT(line);
+ kb_put(bufhl, b, p);
+ return p;
+}
+
/// Adds a highlight to buffer.
///
/// Unlike matchaddpos() highlights follow changes to line numbering (as lines
@@ -4966,34 +5331,105 @@ int bufhl_add_hl(buf_T *buf,
int hl_id,
linenr_T lnum,
colnr_T col_start,
- colnr_T col_end) {
- static int next_src_id = 1;
+ colnr_T col_end)
+{
if (src_id == 0) {
- src_id = next_src_id++;
+ src_id = (int)nvim_create_namespace((String)STRING_INIT);
}
if (hl_id <= 0) {
// no highlight group or invalid line, just return src_id
return src_id;
}
- if (!buf->b_bufhl_info) {
- buf->b_bufhl_info = map_new(linenr_T, bufhl_vec_T)();
- }
- bufhl_vec_T* lineinfo = map_ref(linenr_T, bufhl_vec_T)(buf->b_bufhl_info,
- lnum, true);
- bufhl_hl_item_T *hlentry = kv_pushp(*lineinfo);
+ BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, true);
+
+ BufhlItem *hlentry = kv_pushp(lineinfo->items);
hlentry->src_id = src_id;
hlentry->hl_id = hl_id;
hlentry->start = col_start;
hlentry->stop = col_end;
if (0 < lnum && lnum <= buf->b_ml.ml_line_count) {
- changed_lines_buf(buf, lnum, lnum+1, 0);
- redraw_buf_later(buf, VALID);
+ redraw_buf_line_later(buf, lnum);
+ }
+ return src_id;
+}
+
+/// Add highlighting to a buffer, bounded by two cursor positions,
+/// with an offset.
+///
+/// @param buf Buffer to add highlights to
+/// @param src_id src_id to use or 0 to use a new src_id group,
+/// or -1 for ungrouped highlight.
+/// @param hl_id Highlight group id
+/// @param pos_start Cursor position to start the hightlighting at
+/// @param pos_end Cursor position to end the highlighting at
+/// @param offset Move the whole highlighting this many columns to the right
+void bufhl_add_hl_pos_offset(buf_T *buf,
+ int src_id,
+ int hl_id,
+ lpos_T pos_start,
+ lpos_T pos_end,
+ colnr_T offset)
+{
+ colnr_T hl_start = 0;
+ colnr_T hl_end = 0;
+
+ for (linenr_T lnum = pos_start.lnum; lnum <= pos_end.lnum; lnum ++) {
+ if (pos_start.lnum < lnum && lnum < pos_end.lnum) {
+ hl_start = offset;
+ hl_end = MAXCOL;
+ } else if (lnum == pos_start.lnum && lnum < pos_end.lnum) {
+ hl_start = pos_start.col + offset + 1;
+ hl_end = MAXCOL;
+ } else if (pos_start.lnum < lnum && lnum == pos_end.lnum) {
+ hl_start = offset;
+ hl_end = pos_end.col + offset;
+ } else if (pos_start.lnum == lnum && pos_end.lnum == lnum) {
+ hl_start = pos_start.col + offset + 1;
+ hl_end = pos_end.col + offset;
+ }
+ (void)bufhl_add_hl(buf, src_id, hl_id, lnum, hl_start, hl_end);
+ }
+}
+
+int bufhl_add_virt_text(buf_T *buf,
+ int src_id,
+ linenr_T lnum,
+ VirtText virt_text)
+{
+ if (src_id == 0) {
+ src_id = (int)nvim_create_namespace((String)STRING_INIT);
+ }
+
+ BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, true);
+
+ bufhl_clear_virttext(&lineinfo->virt_text);
+ if (kv_size(virt_text) > 0) {
+ lineinfo->virt_text_src = src_id;
+ lineinfo->virt_text = virt_text;
+ } else {
+ lineinfo->virt_text_src = 0;
+ // currently not needed, but allow a future caller with
+ // 0 size and non-zero capacity
+ kv_destroy(virt_text);
+ }
+
+ if (0 < lnum && lnum <= buf->b_ml.ml_line_count) {
+ redraw_buf_line_later(buf, lnum);
}
return src_id;
}
+static void bufhl_clear_virttext(VirtText *text)
+{
+ for (size_t i = 0; i < kv_size(*text); i++) {
+ xfree(kv_A(*text, i).text);
+ }
+ kv_destroy(*text);
+ *text = (VirtText)KV_INITIAL_VALUE;
+}
+
/// Clear bufhl highlights from a given source group and range of lines.
///
/// @param buf The buffer to remove highlights from
@@ -5003,33 +5439,29 @@ int bufhl_add_hl(buf_T *buf,
void bufhl_clear_line_range(buf_T *buf,
int src_id,
linenr_T line_start,
- linenr_T line_end) {
- if (!buf->b_bufhl_info) {
- return;
- }
- linenr_T line;
- linenr_T first_changed = MAXLNUM, last_changed = -1;
- // In the case line_start - line_end << bufhl_info->size
- // it might be better to reverse this, i e loop over the lines
- // to clear on.
- bufhl_vec_T unused;
- map_foreach(buf->b_bufhl_info, line, unused, {
- (void)unused;
- if (line_start <= line && line <= line_end) {
- if (bufhl_clear_line(buf->b_bufhl_info, src_id, line)) {
- if (line > last_changed) {
- last_changed = line;
- }
- if (line < first_changed) {
- first_changed = line;
- }
+ linenr_T line_end)
+{
+ kbitr_t(bufhl) itr;
+ BufhlLine *l, t = BUFHLLINE_INIT(line_start);
+ if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) {
+ kb_itr_next(bufhl, &buf->b_bufhl_info, &itr);
+ }
+ for (; kb_itr_valid(&itr); kb_itr_next(bufhl, &buf->b_bufhl_info, &itr)) {
+ l = kb_itr_key(&itr);
+ linenr_T line = l->line;
+ if (line > line_end) {
+ break;
+ }
+ if (line_start <= line) {
+ BufhlLineStatus status = bufhl_clear_line(l, src_id, line);
+ if (status != kBLSUnchanged) {
+ redraw_buf_line_later(buf, line);
+ }
+ if (status == kBLSDeleted) {
+ kb_del_itr(bufhl, &buf->b_bufhl_info, &itr);
+ xfree(l);
}
}
- })
-
- if (last_changed != -1) {
- changed_lines_buf(buf, first_changed, last_changed+1, 0);
- redraw_buf_later(buf, VALID);
}
}
@@ -5038,40 +5470,52 @@ void bufhl_clear_line_range(buf_T *buf,
/// @param bufhl_info The highlight info for the buffer
/// @param src_id Highlight source group to clear, or -1 to clear all groups.
/// @param lnum Linenr where the highlight should be cleared
-static bool bufhl_clear_line(bufhl_info_T *bufhl_info, int src_id, int lnum) {
- bufhl_vec_T* lineinfo = map_ref(linenr_T, bufhl_vec_T)(bufhl_info,
- lnum, false);
- size_t oldsize = kv_size(*lineinfo);
+static BufhlLineStatus bufhl_clear_line(BufhlLine *lineinfo, int src_id,
+ linenr_T lnum)
+{
+ BufhlLineStatus changed = kBLSUnchanged;
+ size_t oldsize = kv_size(lineinfo->items);
if (src_id < 0) {
- kv_size(*lineinfo) = 0;
+ kv_size(lineinfo->items) = 0;
} else {
- size_t newind = 0;
- for (size_t i = 0; i < kv_size(*lineinfo); i++) {
- if (kv_A(*lineinfo, i).src_id != src_id) {
- if (i != newind) {
- kv_A(*lineinfo, newind) = kv_A(*lineinfo, i);
+ size_t newidx = 0;
+ for (size_t i = 0; i < kv_size(lineinfo->items); i++) {
+ if (kv_A(lineinfo->items, i).src_id != src_id) {
+ if (i != newidx) {
+ kv_A(lineinfo->items, newidx) = kv_A(lineinfo->items, i);
}
- newind++;
+ newidx++;
}
}
- kv_size(*lineinfo) = newind;
+ kv_size(lineinfo->items) = newidx;
+ }
+ if (kv_size(lineinfo->items) != oldsize) {
+ changed = kBLSChanged;
+ }
+
+ if (kv_size(lineinfo->virt_text) != 0
+ && (src_id < 0 || src_id == lineinfo->virt_text_src)) {
+ bufhl_clear_virttext(&lineinfo->virt_text);
+ lineinfo->virt_text_src = 0;
+ changed = kBLSChanged;
}
- if (kv_size(*lineinfo) == 0) {
- kv_destroy(*lineinfo);
- map_del(linenr_T, bufhl_vec_T)(bufhl_info, lnum);
+ if (kv_size(lineinfo->items) == 0 && kv_size(lineinfo->virt_text) == 0) {
+ kv_destroy(lineinfo->items);
+ return kBLSDeleted;
}
- return kv_size(*lineinfo) != oldsize;
+ return changed;
}
+
/// Remove all highlights and free the highlight data
-void bufhl_clear_all(buf_T* buf) {
- if (!buf->b_bufhl_info) {
- return;
- }
+void bufhl_clear_all(buf_T *buf)
+{
bufhl_clear_line_range(buf, -1, 1, MAXLNUM);
- map_free(linenr_T, bufhl_vec_T)(buf->b_bufhl_info);
- buf->b_bufhl_info = NULL;
+ kb_destroy(bufhl, (&buf->b_bufhl_info));
+ kb_init(&buf->b_bufhl_info);
+ kv_destroy(buf->b_bufhl_move_space);
+ kv_init(buf->b_bufhl_move_space);
}
/// Adjust a placed highlight for inserted/deleted lines.
@@ -5079,29 +5523,49 @@ void bufhl_mark_adjust(buf_T* buf,
linenr_T line1,
linenr_T line2,
long amount,
- long amount_after) {
- if (!buf->b_bufhl_info) {
+ long amount_after,
+ bool end_temp)
+{
+ kbitr_t(bufhl) itr;
+ BufhlLine *l, t = BUFHLLINE_INIT(line1);
+ if (end_temp && amount < 0) {
+ // Move all items from b_bufhl_move_space to the btree.
+ for (size_t i = 0; i < kv_size(buf->b_bufhl_move_space); i++) {
+ l = kv_A(buf->b_bufhl_move_space, i);
+ l->line += amount;
+ kb_put(bufhl, &buf->b_bufhl_info, l);
+ }
+ kv_size(buf->b_bufhl_move_space) = 0;
return;
}
- bufhl_info_T *newmap = map_new(linenr_T, bufhl_vec_T)();
- linenr_T line;
- bufhl_vec_T lineinfo;
- map_foreach(buf->b_bufhl_info, line, lineinfo, {
- if (line >= line1 && line <= line2) {
+ if (!kb_itr_get(bufhl, &buf->b_bufhl_info, &t, &itr)) {
+ kb_itr_next(bufhl, &buf->b_bufhl_info, &itr);
+ }
+ for (; kb_itr_valid(&itr); kb_itr_next(bufhl, &buf->b_bufhl_info, &itr)) {
+ l = kb_itr_key(&itr);
+ if (l->line >= line1 && l->line <= line2) {
+ if (end_temp && amount > 0) {
+ kb_del_itr(bufhl, &buf->b_bufhl_info, &itr);
+ kv_push(buf->b_bufhl_move_space, l);
+ }
if (amount == MAXLNUM) {
- bufhl_clear_line(buf->b_bufhl_info, -1, line);
- continue;
+ if (bufhl_clear_line(l, -1, l->line) == kBLSDeleted) {
+ kb_del_itr(bufhl, &buf->b_bufhl_info, &itr);
+ xfree(l);
+ } else {
+ assert(false);
+ }
} else {
- line += amount;
+ l->line += amount;
}
- } else if (line > line2) {
- line += amount_after;
+ } else if (l->line > line2) {
+ if (amount_after == 0) {
+ break;
+ }
+ l->line += amount_after;
}
- map_put(linenr_T, bufhl_vec_T)(newmap, line, lineinfo);
- });
- map_free(linenr_T, bufhl_vec_T)(buf->b_bufhl_info);
- buf->b_bufhl_info = newmap;
+ }
}
@@ -5111,14 +5575,15 @@ void bufhl_mark_adjust(buf_T* buf,
/// @param lnum The line number
/// @param[out] info The highligts for the line
/// @return true if there was highlights to display
-bool bufhl_start_line(buf_T *buf, linenr_T lnum, bufhl_lineinfo_T *info) {
- if (!buf->b_bufhl_info) {
+bool bufhl_start_line(buf_T *buf, linenr_T lnum, BufhlLineInfo *info)
+{
+ BufhlLine *lineinfo = bufhl_tree_ref(&buf->b_bufhl_info, lnum, false);
+ if (!lineinfo) {
return false;
}
-
info->valid_to = -1;
- info->entries = map_get(linenr_T, bufhl_vec_T)(buf->b_bufhl_info, lnum);
- return kv_size(info->entries) > 0;
+ info->line = lineinfo;
+ return true;
}
/// get highlighting at column col
@@ -5131,14 +5596,15 @@ bool bufhl_start_line(buf_T *buf, linenr_T lnum, bufhl_lineinfo_T *info) {
/// @param info The info returned by bufhl_start_line
/// @param col The column to get the attr for
/// @return The highilight attr to display at the column
-int bufhl_get_attr(bufhl_lineinfo_T *info, colnr_T col) {
+int bufhl_get_attr(BufhlLineInfo *info, colnr_T col)
+{
if (col <= info->valid_to) {
return info->current;
}
int attr = 0;
info->valid_to = MAXCOL;
- for (size_t i = 0; i < kv_size(info->entries); i++) {
- bufhl_hl_item_T entry = kv_A(info->entries, i);
+ for (size_t i = 0; i < kv_size(info->line->items); i++) {
+ BufhlItem entry = kv_A(info->line->items, i);
if (entry.start <= col && col <= entry.stop) {
int entry_attr = syn_id2attr(entry.hl_id);
attr = hl_combine_attr(attr, entry_attr);
@@ -5231,12 +5697,30 @@ wipe_buffer (
int aucmd /* When TRUE trigger autocommands. */
)
{
- if (buf->b_fnum == top_file_num - 1)
- --top_file_num;
-
- if (!aucmd) /* Don't trigger BufDelete autocommands here. */
+ if (!aucmd) {
+ // Don't trigger BufDelete autocommands here.
block_autocmds();
- close_buffer(NULL, buf, DOBUF_WIPE, FALSE);
- if (!aucmd)
+ }
+ close_buffer(NULL, buf, DOBUF_WIPE, false);
+ if (!aucmd) {
unblock_autocmds();
+ }
+}
+
+/// Creates or switches to a scratch buffer. :h special-buffers
+/// Scratch buffer is:
+/// - buftype=nofile bufhidden=hide noswapfile
+/// - Always considered 'nomodified'
+///
+/// @param bufnr Buffer to switch to, or 0 to create a new buffer.
+///
+/// @see curbufIsChanged()
+void buf_open_scratch(handle_T bufnr, char *bufname)
+{
+ (void)do_ecmd((int)bufnr, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
+ (void)setfname(curbuf, (char_u *)bufname, NULL, true);
+ set_option_value("bh", 0L, "hide", OPT_LOCAL);
+ set_option_value("bt", 0L, "nofile", OPT_LOCAL);
+ set_option_value("swf", 0L, NULL, OPT_LOCAL);
+ RESET_BINDING(curwin);
}
diff --git a/src/nvim/buffer.h b/src/nvim/buffer.h
index 36cbec7e60..e61c312fb1 100644
--- a/src/nvim/buffer.h
+++ b/src/nvim/buffer.h
@@ -1,10 +1,14 @@
#ifndef NVIM_BUFFER_H
#define NVIM_BUFFER_H
+#include "nvim/vim.h"
#include "nvim/window.h"
#include "nvim/pos.h" // for linenr_T
#include "nvim/ex_cmds_defs.h" // for exarg_T
#include "nvim/screen.h" // for StlClickRecord
+#include "nvim/func_attr.h"
+#include "nvim/eval.h"
+#include "nvim/macros.h"
// Values for buflist_getfile()
enum getf_values {
@@ -13,11 +17,22 @@ enum getf_values {
GETF_SWITCH = 0x04, // respect 'switchbuf' settings when jumping
};
+// Return values of getfile()
+enum getf_retvalues {
+ GETFILE_ERROR = 1, // normal error
+ GETFILE_NOT_WRITTEN = 2, // "not written" error
+ GETFILE_SAME_FILE = 0, // success, same file
+ GETFILE_OPEN_OTHER = -1, // success, opened another file
+ GETFILE_UNUSED = 8
+};
+
// Values for buflist_new() flags
enum bln_values {
- BLN_CURBUF = 1, // May re-use curbuf for new buffer
- BLN_LISTED = 2, // Put new buffer in buffer list
- BLN_DUMMY = 4, // Allocating dummy buffer
+ BLN_CURBUF = 1, // May re-use curbuf for new buffer
+ BLN_LISTED = 2, // Put new buffer in buffer list
+ BLN_DUMMY = 4, // Allocating dummy buffer
+ // TODO(mhinz): merge patch that introduces BLN_NEW
+ BLN_NOOPT = 16, // Don't copy options to existing buffer
};
// Values for action argument for do_buffer()
@@ -55,35 +70,89 @@ enum bfa_values {
static inline void switch_to_win_for_buf(buf_T *buf,
win_T **save_curwinp,
tabpage_T **save_curtabp,
- buf_T **save_curbufp)
+ bufref_T *save_curbuf)
{
win_T *wp;
tabpage_T *tp;
if (!find_win_for_buf(buf, &wp, &tp)
- || switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL)
- switch_buffer(save_curbufp, buf);
+ || switch_win(save_curwinp, save_curtabp, wp, tp, true) == FAIL) {
+ switch_buffer(save_curbuf, buf);
+ }
}
static inline void restore_win_for_buf(win_T *save_curwin,
tabpage_T *save_curtab,
- buf_T *save_curbuf)
+ bufref_T *save_curbuf)
{
- if (save_curbuf == NULL) {
+ if (save_curbuf->br_buf == NULL) {
restore_win(save_curwin, save_curtab, true);
} else {
restore_buffer(save_curbuf);
}
}
+static inline void buf_set_changedtick(buf_T *const buf,
+ const varnumber_T changedtick)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_ALWAYS_INLINE;
+
+/// Set b:changedtick, also checking b: for consistency in debug build
+///
+/// @param[out] buf Buffer to set changedtick in.
+/// @param[in] changedtick New value.
+static inline void buf_set_changedtick(buf_T *const buf,
+ const varnumber_T changedtick)
+{
+#ifndef NDEBUG
+ dictitem_T *const changedtick_di = tv_dict_find(
+ buf->b_vars, S_LEN("changedtick"));
+ assert(changedtick_di != NULL);
+ assert(changedtick_di->di_tv.v_type == VAR_NUMBER);
+ assert(changedtick_di->di_tv.v_lock == VAR_FIXED);
+ // For some reason formatc does not like the below.
+# ifndef UNIT_TESTING_LUA_PREPROCESSING
+ assert(changedtick_di->di_flags == (DI_FLAGS_RO|DI_FLAGS_FIX));
+# endif
+ assert(changedtick_di == (dictitem_T *)&buf->changedtick_di);
+#endif
+ buf->changedtick_di.di_tv.vval.v_number = changedtick;
+}
+
+static inline varnumber_T buf_get_changedtick(const buf_T *const buf)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_ALWAYS_INLINE REAL_FATTR_PURE
+ REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get b:changedtick value
+///
+/// Faster then querying b:.
+///
+/// @param[in] buf Buffer to get b:changedtick from.
+static inline varnumber_T buf_get_changedtick(const buf_T *const buf)
+{
+ return buf->changedtick_di.di_tv.vval.v_number;
+}
+
+static inline void buf_inc_changedtick(buf_T *const buf)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_ALWAYS_INLINE;
+
+/// Increment b:changedtick value
+///
+/// Also checks b: for consistency in case of debug build.
+///
+/// @param[in,out] buf Buffer to increment value in.
+static inline void buf_inc_changedtick(buf_T *const buf)
+{
+ buf_set_changedtick(buf, buf_get_changedtick(buf) + 1);
+}
+
#define WITH_BUFFER(b, code) \
do { \
- buf_T *save_curbuf = NULL; \
win_T *save_curwin = NULL; \
tabpage_T *save_curtab = NULL; \
+ bufref_T save_curbuf = { NULL, 0, 0 }; \
switch_to_win_for_buf(b, &save_curwin, &save_curtab, &save_curbuf); \
code; \
- restore_win_for_buf(save_curwin, save_curtab, save_curbuf); \
+ restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); \
} while (0)
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index b515c4e1e4..05688790c2 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -8,14 +8,24 @@
typedef struct file_buffer buf_T; // Forward declaration
+// Reference to a buffer that stores the value of buf_free_count.
+// bufref_valid() only needs to check "buf" when the count differs.
+typedef struct {
+ buf_T *br_buf;
+ int br_fnum;
+ int br_buf_free_count;
+} bufref_T;
+
// for garray_T
#include "nvim/garray.h"
+// for ScreenGrid
+#include "nvim/grid_defs.h"
+// for HLF_COUNT
+#include "nvim/highlight_defs.h"
// for pos_T, lpos_T and linenr_T
#include "nvim/pos.h"
// for the number window-local and buffer-local options
#include "nvim/option_defs.h"
-// for optional iconv support
-#include "nvim/iconv.h"
// for jump list and tag stack sizes in a buffer and mark types
#include "nvim/mark_defs.h"
// for u_header_T; needs buf_T.
@@ -23,15 +33,18 @@ typedef struct file_buffer buf_T; // Forward declaration
// for hashtab_T
#include "nvim/hashtab.h"
// for dict_T
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
// for proftime_T
#include "nvim/profile.h"
// for String
#include "nvim/api/private/defs.h"
// for Map(K, V)
#include "nvim/map.h"
+// for kvec
+#include "nvim/lib/kvec.h"
-#define MODIFIABLE(buf) (!buf->terminal && buf->b_p_ma)
+#define GETFILE_SUCCESS(x) ((x) <= 0)
+#define MODIFIABLE(buf) (buf->b_p_ma)
/*
* Flags for w_valid.
@@ -47,10 +60,10 @@ typedef struct file_buffer buf_T; // Forward declaration
* functions that set or reset the flags.
*
* VALID_BOTLINE VALID_BOTLINE_AP
- * on on w_botline valid
- * off on w_botline approximated
- * off off w_botline not valid
- * on off not possible
+ * on on w_botline valid
+ * off on w_botline approximated
+ * off off w_botline not valid
+ * on off not possible
*/
#define VALID_WROW 0x01 /* w_wrow (window row) is valid */
#define VALID_WCOL 0x02 /* w_wcol (window col) is valid */
@@ -83,36 +96,24 @@ typedef struct file_buffer buf_T; // Forward declaration
typedef struct window_S win_T;
typedef struct wininfo_S wininfo_T;
typedef struct frame_S frame_T;
-typedef int scid_T; /* script ID */
+typedef uint16_t disptick_T; // display tick type
// for struct memline (it needs memfile_T)
#include "nvim/memline_defs.h"
-
// for struct memfile, bhdr_T, blocknr_T... (it needs buf_T)
#include "nvim/memfile_defs.h"
-/*
- * This is here because regexp_defs.h needs win_T and buf_T. regprog_T is
- * used below.
- */
+// for regprog_T. Needs win_T and buf_T.
#include "nvim/regexp_defs.h"
-
-// for synstate_T (needs reg_extmatch_T, win_T and buf_T)
+// for synstate_T (needs reg_extmatch_T, win_T, buf_T)
#include "nvim/syntax_defs.h"
-
// for signlist_T
#include "nvim/sign_defs.h"
-
// for bufhl_*_T
#include "nvim/bufhl_defs.h"
-typedef Map(linenr_T, bufhl_vec_T) bufhl_info_T;
-
-// for FileID
-#include "nvim/os/fs_defs.h"
-
-// for Terminal
-#include "nvim/terminal.h"
+#include "nvim/os/fs_defs.h" // for FileID
+#include "nvim/terminal.h" // for Terminal
/*
* The taggy struct is used to store the information about a :tag command.
@@ -145,6 +146,12 @@ struct buffheader {
size_t bh_space; // space in bh_curr for appending
};
+typedef struct
+{
+ buffheader_T sr_redobuff;
+ buffheader_T sr_old_redobuff;
+} save_redo_T;
+
/*
* Structure that contains all options that are local to a window.
* Used twice in a window: for the current buffer and for all buffers.
@@ -154,7 +161,7 @@ typedef struct {
int wo_arab;
# define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */
int wo_bri;
-# define w_p_bri w_onebuf_opt.wo_bri /* 'breakindent' */
+# define w_p_bri w_onebuf_opt.wo_bri // 'breakindent'
char_u *wo_briopt;
# define w_p_briopt w_onebuf_opt.wo_briopt /* 'breakindentopt' */
int wo_diff;
@@ -237,8 +244,12 @@ typedef struct {
# define w_p_crb w_onebuf_opt.wo_crb /* 'cursorbind' */
int wo_crb_save; /* 'cursorbind' state saved for diff mode*/
# define w_p_crb_save w_onebuf_opt.wo_crb_save
+ char_u *wo_scl;
+# define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
+ char_u *wo_winhl;
+# define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight'
- int wo_scriptID[WV_COUNT]; /* SIDs for window-local options */
+ LastSet wo_scriptID[WV_COUNT]; // SIDs for window-local options
# define w_p_scriptID w_onebuf_opt.wo_scriptID
} winopt_T;
@@ -323,25 +334,6 @@ typedef struct {
} tasave_T;
/*
- * Used for conversion of terminal I/O and script files.
- */
-typedef struct {
- int vc_type; /* zero or one of the CONV_ values */
- int vc_factor; /* max. expansion factor */
-# ifdef USE_ICONV
- iconv_t vc_fd; /* for CONV_ICONV */
-# endif
- bool vc_fail; /* fail for invalid char, don't use '?' */
-} vimconv_T;
-
-#define CONV_NONE 0
-#define CONV_TO_UTF8 1
-#define CONV_9_TO_UTF8 2
-#define CONV_TO_LATIN1 3
-#define CONV_TO_LATIN9 4
-#define CONV_ICONV 5
-
-/*
* Structure used for mappings and abbreviations.
*/
typedef struct mapblock mapblock_T;
@@ -422,13 +414,13 @@ typedef struct {
* syntax state too often.
* b_sst_array[] is allocated to hold the state for all displayed lines,
* and states for 1 out of about 20 other lines.
- * b_sst_array pointer to an array of synstate_T
- * b_sst_len number of entries in b_sst_array[]
- * b_sst_first pointer to first used entry in b_sst_array[] or NULL
- * b_sst_firstfree pointer to first free entry in b_sst_array[] or NULL
- * b_sst_freecount number of free entries in b_sst_array[]
- * b_sst_check_lnum entries after this lnum need to be checked for
- * validity (MAXLNUM means no check needed)
+ * b_sst_array pointer to an array of synstate_T
+ * b_sst_len number of entries in b_sst_array[]
+ * b_sst_first pointer to first used entry in b_sst_array[] or NULL
+ * b_sst_firstfree pointer to first free entry in b_sst_array[] or NULL
+ * b_sst_freecount number of free entries in b_sst_array[]
+ * b_sst_check_lnum entries after this lnum need to be checked for
+ * validity (MAXLNUM means no check needed)
*/
synstate_T *b_sst_array;
int b_sst_len;
@@ -436,7 +428,7 @@ typedef struct {
synstate_T *b_sst_firstfree;
int b_sst_freecount;
linenr_T b_sst_check_lnum;
- uint16_t b_sst_lasttick; /* last display tick */
+ disptick_T b_sst_lasttick; // last display tick
// for spell checking
garray_T b_langp; // list of pointers to slang_T, see spell.c
@@ -451,6 +443,16 @@ typedef struct {
char_u *b_syn_isk; // iskeyword option
} synblock_T;
+/// Type used for changedtick_di member in buf_T
+///
+/// Primary exists so that literals of relevant type can be made.
+typedef TV_DICTITEM_STRUCT(sizeof("changedtick")) ChangedtickDictItem;
+
+#define BUF_HAS_QF_ENTRY 1
+#define BUF_HAS_LL_ENTRY 2
+
+// Maximum number of maphash blocks we will have
+#define MAX_MAPHASH 256
/*
* buffer: structure that holds information about one file
@@ -461,37 +463,45 @@ typedef struct {
*/
struct file_buffer {
- uint64_t handle; // unique identifier for the buffer
- memline_T b_ml; /* associated memline (also contains line
- count) */
+ handle_T handle; // unique id for the buffer (buffer number)
+#define b_fnum handle
+
+ memline_T b_ml; // associated memline (also contains line count
buf_T *b_next; /* links in list of buffers */
buf_T *b_prev;
int b_nwindows; /* nr of windows open on this buffer */
- int b_flags; /* various BF_ flags */
- bool b_closing; /* buffer is being closed, don't let
- autocommands close it too. */
+ int b_flags; // various BF_ flags
+ int b_locked; // Buffer is being closed or referenced, don't
+ // let autocommands wipe it out.
- /*
- * b_ffname has the full path of the file (NULL for no name).
- * b_sfname is the name as the user typed it (or NULL).
- * b_fname is the same as b_sfname, unless ":cd" has been done,
- * then it is the same as b_ffname (NULL for no name).
- */
- char_u *b_ffname; /* full path file name */
- char_u *b_sfname; /* short file name */
- char_u *b_fname; /* current file name */
+ //
+ // b_ffname has the full path of the file (NULL for no name).
+ // b_sfname is the name as the user typed it (or NULL).
+ // b_fname is the same as b_sfname, unless ":cd" has been done,
+ // then it is the same as b_ffname (NULL for no name).
+ //
+ char_u *b_ffname; // full path file name
+ char_u *b_sfname; // short file name
+ char_u *b_fname; // current file name
bool file_id_valid;
FileID file_id;
- int b_fnum; /* buffer number for this file. */
+ int b_changed; // 'modified': Set to true if something in the
+ // file has been changed and not written out.
- bool b_changed; /* 'modified': Set to true if something in the
- file has been changed and not written out. */
- int b_changedtick; /* incremented for each change, also for undo */
+ /// Change identifier incremented for each change, including undo
+ ///
+ /// This is a dictionary item used to store in b:changedtick.
+ ChangedtickDictItem changedtick_di;
+
+ varnumber_T b_last_changedtick; // b:changedtick when TextChanged or
+ // TextChangedI was last triggered.
+ varnumber_T b_last_changedtick_pum; // b:changedtick when TextChangedP was
+ // last triggered.
bool b_saving; /* Set to true if we are in the middle of
saving the buffer. */
@@ -539,8 +549,8 @@ struct file_buffer {
*/
uint64_t b_chartab[4];
- /* Table used for mappings local to a buffer. */
- mapblock_T *(b_maphash[256]);
+ // Table used for mappings local to a buffer.
+ mapblock_T *(b_maphash[MAX_MAPHASH]);
/* First abbreviation local to a buffer. */
mapblock_T *b_first_abbr;
@@ -579,12 +589,12 @@ struct file_buffer {
bool b_scanned; /* ^N/^P have scanned this buffer */
- /* flags for use of ":lmap" and IM control */
- long b_p_iminsert; /* input mode for insert */
- long b_p_imsearch; /* input mode for search */
-#define B_IMODE_USE_INSERT -1 /* Use b_p_iminsert value for search */
-#define B_IMODE_NONE 0 /* Input via none */
-#define B_IMODE_LMAP 1 /* Input via langmap */
+ // flags for use of ":lmap" and IM control
+ long b_p_iminsert; // input mode for insert
+ long b_p_imsearch; // input mode for search
+#define B_IMODE_USE_INSERT -1 // Use b_p_iminsert value for search
+#define B_IMODE_NONE 0 // Input via none
+#define B_IMODE_LMAP 1 // Input via langmap
# define B_IMODE_LAST 1
short b_kmap_state; /* using "lmap" mappings */
@@ -599,7 +609,7 @@ struct file_buffer {
*/
bool b_p_initialized; /* set when options initialized */
- int b_p_scriptID[BV_COUNT]; /* SIDs for buffer-local options */
+ LastSet b_p_scriptID[BV_COUNT]; // SIDs for buffer-local options
int b_p_ai; ///< 'autoindent'
int b_p_ai_nopaste; ///< b_p_ai saved for paste mode
@@ -610,7 +620,9 @@ struct file_buffer {
int b_p_bomb; ///< 'bomb'
char_u *b_p_bh; ///< 'bufhidden'
char_u *b_p_bt; ///< 'buftype'
+ int b_has_qf_entry; ///< quickfix exists for buffer
int b_p_bl; ///< 'buflisted'
+ long b_p_channel; ///< 'channel'
int b_p_cin; ///< 'cindent'
char_u *b_p_cino; ///< 'cinoptions'
char_u *b_p_cink; ///< 'cinkeys'
@@ -639,10 +651,12 @@ struct file_buffer {
char_u *b_p_inde; ///< 'indentexpr'
uint32_t b_p_inde_flags; ///< flags for 'indentexpr'
char_u *b_p_indk; ///< 'indentkeys'
+ char_u *b_p_fp; ///< 'formatprg'
char_u *b_p_fex; ///< 'formatexpr'
uint32_t b_p_fex_flags; ///< flags for 'formatexpr'
char_u *b_p_kp; ///< 'keywordprg'
int b_p_lisp; ///< 'lisp'
+ char_u *b_p_menc; ///< 'makeencoding'
char_u *b_p_mps; ///< 'matchpairs'
int b_p_ml; ///< 'modeline'
int b_p_ml_nobin; ///< b_p_ml saved for binary mode
@@ -652,11 +666,12 @@ struct file_buffer {
char_u *b_p_qe; ///< 'quoteescape'
int b_p_ro; ///< 'readonly'
long b_p_sw; ///< 'shiftwidth'
+ long b_p_scbk; ///< 'scrollback'
int b_p_si; ///< 'smartindent'
long b_p_sts; ///< 'softtabstop'
long b_p_sts_nopaste; ///< b_p_sts saved for paste mode
char_u *b_p_sua; ///< 'suffixesadd'
- bool b_p_swf; ///< 'swapfile'
+ int b_p_swf; ///< 'swapfile'
long b_p_smc; ///< 'synmaxcol'
char_u *b_p_syn; ///< 'syntax'
long b_p_ts; ///< 'tabstop'
@@ -722,6 +737,7 @@ struct file_buffer {
int b_ind_hash_comment;
int b_ind_cpp_namespace;
int b_ind_if_for_while;
+ int b_ind_cpp_extern_c;
linenr_T b_no_eol_lnum; /* non-zero lnum when last line of next binary
* write should not have an end-of-line */
@@ -732,8 +748,8 @@ struct file_buffer {
int b_bad_char; /* "++bad=" argument when edit started or 0 */
int b_start_bomb; /* 'bomb' when it was read */
- dictitem_T b_bufvar; /* variable for "b:" Dictionary */
- dict_T *b_vars; /* internal variables, local to buffer */
+ ScopeDictDictItem b_bufvar; ///< Variable for "b:" Dictionary.
+ dict_T *b_vars; ///< b: scope dictionary.
/* When a buffer is created, it starts without a swap file. b_may_swap is
* then set to indicate that a swap file may be opened later. It is reset
@@ -746,7 +762,7 @@ struct file_buffer {
/* Two special kinds of buffers:
* help buffer - used for help files, won't use a swap file.
* spell buffer - used for spell info, never displayed and doesn't have a
- * file name.
+ * file name.
*/
bool b_help; /* TRUE for help file buffer (when set b_p_bt
is "help") */
@@ -766,13 +782,21 @@ struct file_buffer {
int b_mapped_ctrl_c; // modes where CTRL-C is mapped
- bufhl_info_T *b_bufhl_info; // buffer stored highlights
+ BufhlInfo b_bufhl_info; // buffer stored highlights
+
+ kvec_t(BufhlLine *) b_bufhl_move_space; // temporary space for highlights
+
+ // array of channelids which have asked to receive updates for this
+ // buffer.
+ kvec_t(uint64_t) update_channels;
+
+ int b_diff_failed; // internal diff failed for this buffer
};
/*
* Stuff for diff mode.
*/
-# define DB_COUNT 4 /* up to four buffers can be diff'ed */
+# define DB_COUNT 8 // up to four buffers can be diff'ed
/*
* Each diffblock defines where a block of lines starts in each of the buffers
@@ -799,33 +823,32 @@ struct diffblock_S {
# define SNAP_AUCMD_IDX 1
# define SNAP_COUNT 2
-/*
- * Tab pages point to the top frame of each tab page.
- * Note: Most values are NOT valid for the current tab page! Use "curwin",
- * "firstwin", etc. for that. "tp_topframe" is always valid and can be
- * compared against "topframe" to find the current tab page.
- */
+/// Tab pages point to the top frame of each tab page.
+/// Note: Most values are NOT valid for the current tab page! Use "curwin",
+/// "firstwin", etc. for that. "tp_topframe" is always valid and can be
+/// compared against "topframe" to find the current tab page.
typedef struct tabpage_S tabpage_T;
struct tabpage_S {
- uint64_t handle;
- tabpage_T *tp_next; /* next tabpage or NULL */
- frame_T *tp_topframe; /* topframe for the windows */
- win_T *tp_curwin; /* current window in this Tab page */
- win_T *tp_prevwin; /* previous window in this Tab page */
- win_T *tp_firstwin; /* first window in this Tab page */
- win_T *tp_lastwin; /* last window in this Tab page */
- long tp_old_Rows; /* Rows when Tab page was left */
- long tp_old_Columns; /* Columns when Tab page was left */
- long tp_ch_used; /* value of 'cmdheight' when frame size
- was set */
+ handle_T handle;
+ tabpage_T *tp_next; ///< next tabpage or NULL
+ frame_T *tp_topframe; ///< topframe for the windows
+ win_T *tp_curwin; ///< current window in this Tab page
+ win_T *tp_prevwin; ///< previous window in this Tab page
+ win_T *tp_firstwin; ///< first window in this Tab page
+ win_T *tp_lastwin; ///< last window in this Tab page
+ long tp_old_Rows; ///< Rows when Tab page was left
+ long tp_old_Columns; ///< Columns when Tab page was left
+ long tp_ch_used; ///< value of 'cmdheight' when frame size
+ ///< was set
+
diff_T *tp_first_diff;
buf_T *(tp_diffbuf[DB_COUNT]);
- int tp_diff_invalid; ///< list of diffs is outdated */
+ int tp_diff_invalid; ///< list of diffs is outdated
+ int tp_diff_update; ///< update diffs before redrawing
frame_T *(tp_snapshot[SNAP_COUNT]); ///< window layout snapshots
- dictitem_T tp_winvar; ///< variable for "t:" Dictionary
- dict_T *tp_vars; ///< internal variables, local to tab page
- char_u *localdir; ///< Absolute path of local directory or
- ///< NULL
+ ScopeDictDictItem tp_winvar; ///< Variable for "t:" Dictionary.
+ dict_T *tp_vars; ///< Internal variables, local to tab page.
+ char_u *tp_localdir; ///< Absolute path of local cwd or NULL.
};
/*
@@ -879,16 +902,17 @@ struct frame_S {
* match functions there is a different pattern for each window.
*/
typedef struct {
- regmmatch_T rm; /* points to the regexp program; contains last found
- match (may continue in next line) */
- buf_T *buf; /* the buffer to search for a match */
- linenr_T lnum; /* the line to search for a match */
- int attr; /* attributes to be used for a match */
- int attr_cur; /* attributes currently active in win_line() */
- linenr_T first_lnum; /* first lnum to search for multi-line pat */
- colnr_T startcol; /* in win_line() points to char where HL starts */
- colnr_T endcol; /* in win_line() points to char where HL ends */
- proftime_T tm; /* for a time limit */
+ regmmatch_T rm; // points to the regexp program; contains last found
+ // match (may continue in next line)
+ buf_T *buf; // the buffer to search for a match
+ linenr_T lnum; // the line to search for a match
+ int attr; // attributes to be used for a match
+ int attr_cur; // attributes currently active in win_line()
+ linenr_T first_lnum; // first lnum to search for multi-line pat
+ colnr_T startcol; // in win_line() points to char where HL starts
+ colnr_T endcol; // in win_line() points to char where HL ends
+ bool is_addpos; // position specified directly by matchaddpos()
+ proftime_T tm; // for a time limit
} match_T;
/// number of positions supported by matchaddpos()
@@ -897,9 +921,9 @@ typedef struct {
/// Same as lpos_T, but with additional field len.
typedef struct
{
- linenr_T lnum; ///< line number
- colnr_T col; ///< column number
- int len; ///< length: 0 - to the end of line
+ linenr_T lnum; ///< line number
+ colnr_T col; ///< column number
+ int len; ///< length: 0 - to the end of line
} llpos_T;
/// posmatch_T provides an array for storing match items for matchaddpos()
@@ -907,10 +931,10 @@ typedef struct
typedef struct posmatch posmatch_T;
struct posmatch
{
- llpos_T pos[MAXPOSMATCH]; ///< array of positions
- int cur; ///< internal position counter
- linenr_T toplnum; ///< top buffer line
- linenr_T botlnum; ///< bottom buffer line
+ llpos_T pos[MAXPOSMATCH]; ///< array of positions
+ int cur; ///< internal position counter
+ linenr_T toplnum; ///< top buffer line
+ linenr_T botlnum; ///< bottom buffer line
};
/*
@@ -936,12 +960,21 @@ struct matchitem {
* All row numbers are relative to the start of the window, except w_winrow.
*/
struct window_S {
- uint64_t handle;
- buf_T *w_buffer; /* buffer we are a window into (used
- often, keep it the first item!) */
+ handle_T handle; ///< unique identifier for the window
+
+ buf_T *w_buffer; ///< buffer we are a window into (used
+ ///< often, keep it the first item!)
synblock_T *w_s; /* for :ownsyntax */
+ int w_hl_id_normal; ///< 'winhighlight' normal id
+ int w_hl_attr_normal; ///< 'winhighlight' normal final attrs
+
+ int w_hl_ids[HLF_COUNT]; ///< 'winhighlight' id
+ int w_hl_attrs[HLF_COUNT]; ///< 'winhighlight' final attrs
+
+ int w_hl_needs_update; ///< attrs need to be recalculated
+
win_T *w_prev; /* link to previous window */
win_T *w_next; /* link to next window */
bool w_closing; /* window is being closed, don't let
@@ -955,9 +988,11 @@ struct window_S {
used to try to stay in the same column
for up/down cursor motions. */
- int w_set_curswant; /* If set, then update w_curswant the next
- time through cursupdate() to the
- current virtual column */
+ int w_set_curswant; // If set, then update w_curswant the next
+ // time through cursupdate() to the
+ // current virtual column
+
+ linenr_T w_last_cursorline; ///< where last 'cursorline' was drawn
// the next seven are used to update the visual part
char w_old_visual_mode; ///< last known VIsual_mode
@@ -1006,7 +1041,7 @@ struct window_S {
* Recomputing is minimized by storing the result of computations.
* Use functions in screen.c to check if they are valid and to update.
* w_valid is a bitfield of flags, which indicate if specific values are
- * valid or need to be recomputed.
+ * valid or need to be recomputed.
*/
int w_valid;
pos_T w_valid_cursor; /* last known position of w_cursor, used
@@ -1036,11 +1071,11 @@ struct window_S {
*/
int w_wrow, w_wcol; /* cursor position in window */
- linenr_T w_botline; /* number of the line below the bottom of
- the screen */
- int w_empty_rows; /* number of ~ rows in window */
- int w_filler_rows; /* number of filler rows at the end of the
- window */
+ linenr_T w_botline; // number of the line below the bottom of
+ // the window
+ int w_empty_rows; // number of ~ rows in window
+ int w_filler_rows; // number of filler rows at the end of the
+ // window
/*
* Info about the lines currently in the window is remembered to avoid
@@ -1115,8 +1150,8 @@ struct window_S {
long w_scbind_pos;
- dictitem_T w_winvar; /* variable for "w:" Dictionary */
- dict_T *w_vars; /* internal variables, local to window */
+ ScopeDictDictItem w_winvar; ///< Variable for "w:" dictionary.
+ dict_T *w_vars; ///< Dictionary with w: variables.
int w_farsi; /* for the window dependent Farsi functions */
@@ -1150,6 +1185,9 @@ struct window_S {
int w_tagstackidx; /* idx just below active entry */
int w_tagstacklen; /* number of tags on stack */
+ ScreenGrid w_grid; // the grid specific to the window
+ bool w_pos_changed; // true if window position changed
+
/*
* w_fraction is the fractional row of the cursor within the window, from
* 0 at the top row to FRACTION_MULT at the last row.
@@ -1171,4 +1209,13 @@ struct window_S {
qf_info_T *w_llist_ref;
};
+static inline int win_hl_attr(win_T *wp, int hlf)
+{
+ return wp->w_hl_attrs[hlf];
+}
+
+/// Macros defined in Vim, but not in Neovim
+#define CHANGEDTICK(buf) \
+ (=== Include buffer.h & use buf_(get|set|inc)_changedtick ===)
+
#endif // NVIM_BUFFER_DEFS_H
diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c
new file mode 100644
index 0000000000..9d9c998a68
--- /dev/null
+++ b/src/nvim/buffer_updates.c
@@ -0,0 +1,211 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/buffer_updates.h"
+#include "nvim/memline.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/assert.h"
+#include "nvim/buffer.h"
+
+// Register a channel. Return True if the channel was added, or already added.
+// Return False if the channel couldn't be added because the buffer is
+// unloaded.
+bool buf_updates_register(buf_T *buf, uint64_t channel_id, bool send_buffer)
+{
+ // must fail if the buffer isn't loaded
+ if (buf->b_ml.ml_mfp == NULL) {
+ return false;
+ }
+
+ // count how many channels are currently watching the buffer
+ size_t size = kv_size(buf->update_channels);
+ if (size) {
+ for (size_t i = 0; i < size; i++) {
+ if (kv_A(buf->update_channels, i) == channel_id) {
+ // buffer is already registered ... nothing to do
+ return true;
+ }
+ }
+ }
+
+ // append the channelid to the list
+ kv_push(buf->update_channels, channel_id);
+
+ if (send_buffer) {
+ Array args = ARRAY_DICT_INIT;
+ args.size = 6;
+ args.items = xcalloc(sizeof(Object), args.size);
+
+ // the first argument is always the buffer handle
+ args.items[0] = BUFFER_OBJ(buf->handle);
+ args.items[1] = INTEGER_OBJ(buf_get_changedtick(buf));
+ // the first line that changed (zero-indexed)
+ args.items[2] = INTEGER_OBJ(0);
+ // the last line that was changed
+ args.items[3] = INTEGER_OBJ(-1);
+ Array linedata = ARRAY_DICT_INIT;
+
+ // collect buffer contents
+
+ STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
+ size_t line_count = (size_t)buf->b_ml.ml_line_count;
+
+ if (line_count >= 1) {
+ linedata.size = line_count;
+ linedata.items = xcalloc(sizeof(Object), line_count);
+
+ buf_collect_lines(buf, line_count, 1, true, &linedata, NULL);
+ }
+
+ args.items[4] = ARRAY_OBJ(linedata);
+ args.items[5] = BOOLEAN_OBJ(false);
+
+ rpc_send_event(channel_id, "nvim_buf_lines_event", args);
+ } else {
+ buf_updates_changedtick_single(buf, channel_id);
+ }
+
+ return true;
+}
+
+void buf_updates_send_end(buf_T *buf, uint64_t channelid)
+{
+ Array args = ARRAY_DICT_INIT;
+ args.size = 1;
+ args.items = xcalloc(sizeof(Object), args.size);
+ args.items[0] = BUFFER_OBJ(buf->handle);
+ rpc_send_event(channelid, "nvim_buf_detach_event", args);
+}
+
+void buf_updates_unregister(buf_T *buf, uint64_t channelid)
+{
+ size_t size = kv_size(buf->update_channels);
+ if (!size) {
+ return;
+ }
+
+ // go through list backwards and remove the channel id each time it appears
+ // (it should never appear more than once)
+ size_t j = 0;
+ size_t found = 0;
+ for (size_t i = 0; i < size; i++) {
+ if (kv_A(buf->update_channels, i) == channelid) {
+ found++;
+ } else {
+ // copy item backwards into prior slot if needed
+ if (i != j) {
+ kv_A(buf->update_channels, j) = kv_A(buf->update_channels, i);
+ }
+ j++;
+ }
+ }
+
+ if (found) {
+ // remove X items from the end of the array
+ buf->update_channels.size -= found;
+
+ // make a new copy of the active array without the channelid in it
+ buf_updates_send_end(buf, channelid);
+
+ if (found == size) {
+ kv_destroy(buf->update_channels);
+ kv_init(buf->update_channels);
+ }
+ }
+}
+
+void buf_updates_unregister_all(buf_T *buf)
+{
+ size_t size = kv_size(buf->update_channels);
+ if (size) {
+ for (size_t i = 0; i < size; i++) {
+ buf_updates_send_end(buf, kv_A(buf->update_channels, i));
+ }
+ kv_destroy(buf->update_channels);
+ kv_init(buf->update_channels);
+ }
+}
+
+void buf_updates_send_changes(buf_T *buf,
+ linenr_T firstline,
+ int64_t num_added,
+ int64_t num_removed,
+ bool send_tick)
+{
+ // if one the channels doesn't work, put its ID here so we can remove it later
+ uint64_t badchannelid = 0;
+
+ // notify each of the active channels
+ for (size_t i = 0; i < kv_size(buf->update_channels); i++) {
+ uint64_t channelid = kv_A(buf->update_channels, i);
+
+ // send through the changes now channel contents now
+ Array args = ARRAY_DICT_INIT;
+ args.size = 6;
+ args.items = xcalloc(sizeof(Object), args.size);
+
+ // the first argument is always the buffer handle
+ args.items[0] = BUFFER_OBJ(buf->handle);
+
+ // next argument is b:changedtick
+ args.items[1] = send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL;
+
+ // the first line that changed (zero-indexed)
+ args.items[2] = INTEGER_OBJ(firstline - 1);
+
+ // the last line that was changed
+ args.items[3] = INTEGER_OBJ(firstline - 1 + num_removed);
+
+ // linedata of lines being swapped in
+ Array linedata = ARRAY_DICT_INIT;
+ if (num_added > 0) {
+ STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
+ linedata.size = (size_t)num_added;
+ linedata.items = xcalloc(sizeof(Object), (size_t)num_added);
+ buf_collect_lines(buf, (size_t)num_added, firstline, true, &linedata,
+ NULL);
+ }
+ args.items[4] = ARRAY_OBJ(linedata);
+ args.items[5] = BOOLEAN_OBJ(false);
+ if (!rpc_send_event(channelid, "nvim_buf_lines_event", args)) {
+ // We can't unregister the channel while we're iterating over the
+ // update_channels array, so we remember its ID to unregister it at
+ // the end.
+ badchannelid = channelid;
+ }
+ }
+
+ // We can only ever remove one dead channel at a time. This is OK because the
+ // change notifications are so frequent that many dead channels will be
+ // cleared up quickly.
+ if (badchannelid != 0) {
+ ELOG("Disabling buffer updates for dead channel %"PRIu64, badchannelid);
+ buf_updates_unregister(buf, badchannelid);
+ }
+}
+
+void buf_updates_changedtick(buf_T *buf)
+{
+ // notify each of the active channels
+ for (size_t i = 0; i < kv_size(buf->update_channels); i++) {
+ uint64_t channel_id = kv_A(buf->update_channels, i);
+ buf_updates_changedtick_single(buf, channel_id);
+ }
+}
+
+void buf_updates_changedtick_single(buf_T *buf, uint64_t channel_id)
+{
+ Array args = ARRAY_DICT_INIT;
+ args.size = 2;
+ args.items = xcalloc(sizeof(Object), args.size);
+
+ // the first argument is always the buffer handle
+ args.items[0] = BUFFER_OBJ(buf->handle);
+
+ // next argument is b:changedtick
+ args.items[1] = INTEGER_OBJ(buf_get_changedtick(buf));
+
+ // don't try and clean up dead channels here
+ rpc_send_event(channel_id, "nvim_buf_changedtick_event", args);
+}
diff --git a/src/nvim/buffer_updates.h b/src/nvim/buffer_updates.h
new file mode 100644
index 0000000000..b2d0a62270
--- /dev/null
+++ b/src/nvim/buffer_updates.h
@@ -0,0 +1,10 @@
+#ifndef NVIM_BUFFER_UPDATES_H
+#define NVIM_BUFFER_UPDATES_H
+
+#include "nvim/buffer_defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "buffer_updates.h.generated.h"
+#endif
+
+#endif // NVIM_BUFFER_UPDATES_H
diff --git a/src/nvim/bufhl_defs.h b/src/nvim/bufhl_defs.h
index e47bb2a238..d0fb40ab88 100644
--- a/src/nvim/bufhl_defs.h
+++ b/src/nvim/bufhl_defs.h
@@ -3,23 +3,39 @@
#include "nvim/pos.h"
#include "nvim/lib/kvec.h"
+#include "nvim/lib/kbtree.h"
+
// bufhl: buffer specific highlighting
-struct bufhl_hl_item
-{
+typedef struct {
int src_id;
int hl_id; // highlight group
colnr_T start; // first column to highlight
colnr_T stop; // last column to highlight
-};
-typedef struct bufhl_hl_item bufhl_hl_item_T;
+} BufhlItem;
+
+typedef struct {
+ char *text;
+ int hl_id;
+} VirtTextChunk;
+
+typedef kvec_t(VirtTextChunk) VirtText;
-typedef kvec_t(struct bufhl_hl_item) bufhl_vec_T;
+typedef struct {
+ linenr_T line;
+ kvec_t(BufhlItem) items;
+ int virt_text_src;
+ VirtText virt_text;
+} BufhlLine;
+#define BUFHLLINE_INIT(l) { l, KV_INITIAL_VALUE, 0, KV_INITIAL_VALUE }
typedef struct {
- bufhl_vec_T entries;
+ BufhlLine *line;
int current;
colnr_T valid_to;
-} bufhl_lineinfo_T;
+} BufhlLineInfo;
+#define BUFHL_CMP(a, b) ((int)(((a)->line - (b)->line)))
+KBTREE_INIT(bufhl, BufhlLine *, BUFHL_CMP, 10) // -V512
+typedef kbtree_t(bufhl) BufhlInfo;
#endif // NVIM_BUFHL_DEFS_H
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
new file mode 100644
index 0000000000..8b8d27affd
--- /dev/null
+++ b/src/nvim/channel.c
@@ -0,0 +1,831 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/ui.h"
+#include "nvim/channel.h"
+#include "nvim/eval.h"
+#include "nvim/eval/encode.h"
+#include "nvim/event/socket.h"
+#include "nvim/fileio.h"
+#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/msgpack_rpc/server.h"
+#include "nvim/os/shell.h"
+#include "nvim/path.h"
+#include "nvim/ascii.h"
+
+static bool did_stdio = false;
+PMap(uint64_t) *channels = NULL;
+
+/// next free id for a job or rpc channel
+/// 1 is reserved for stdio channel
+/// 2 is reserved for stderr channel
+static uint64_t next_chan_id = CHAN_STDERR+1;
+
+
+typedef struct {
+ Channel *chan;
+ Callback *callback;
+ const char *type;
+ // if reader is set, status is ignored.
+ CallbackReader *reader;
+ int status;
+} ChannelEvent;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "channel.c.generated.h"
+#endif
+/// Teardown the module
+void channel_teardown(void)
+{
+ if (!channels) {
+ return;
+ }
+
+ Channel *channel;
+
+ map_foreach_value(channels, channel, {
+ channel_close(channel->id, kChannelPartAll, NULL);
+ });
+}
+
+/// Closes a channel
+///
+/// @param id The channel id
+/// @return true if successful, false otherwise
+bool channel_close(uint64_t id, ChannelPart part, const char **error)
+{
+ Channel *chan;
+ Process *proc;
+
+ const char *dummy;
+ if (!error) {
+ error = &dummy;
+ }
+
+ if (!(chan = find_channel(id))) {
+ if (id < next_chan_id) {
+ // allow double close, even though we can't say what parts was valid.
+ return true;
+ }
+ *error = (const char *)e_invchan;
+ return false;
+ }
+
+ bool close_main = false;
+ if (part == kChannelPartRpc || part == kChannelPartAll) {
+ close_main = true;
+ if (chan->is_rpc) {
+ rpc_close(chan);
+ } else if (part == kChannelPartRpc) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ } else if ((part == kChannelPartStdin || part == kChannelPartStdout)
+ && chan->is_rpc) {
+ *error = (const char *)e_invstreamrpc;
+ return false;
+ }
+
+ switch (chan->streamtype) {
+ case kChannelStreamSocket:
+ if (!close_main) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ stream_may_close(&chan->stream.socket);
+ break;
+
+ case kChannelStreamProc:
+ proc = (Process *)&chan->stream.proc;
+ if (part == kChannelPartStdin || close_main) {
+ stream_may_close(&proc->in);
+ }
+ if (part == kChannelPartStdout || close_main) {
+ stream_may_close(&proc->out);
+ }
+ if (part == kChannelPartStderr || part == kChannelPartAll) {
+ stream_may_close(&proc->err);
+ }
+ if (proc->type == kProcessTypePty && part == kChannelPartAll) {
+ pty_process_close_master(&chan->stream.pty);
+ }
+
+ break;
+
+ case kChannelStreamStdio:
+ if (part == kChannelPartStdin || close_main) {
+ stream_may_close(&chan->stream.stdio.in);
+ }
+ if (part == kChannelPartStdout || close_main) {
+ stream_may_close(&chan->stream.stdio.out);
+ }
+ if (part == kChannelPartStderr) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ break;
+
+ case kChannelStreamStderr:
+ if (part != kChannelPartAll && part != kChannelPartStderr) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ if (!chan->stream.err.closed) {
+ chan->stream.err.closed = true;
+ // Don't close on exit, in case late error messages
+ if (!exiting) {
+ fclose(stderr);
+ }
+ channel_decref(chan);
+ }
+ break;
+
+ case kChannelStreamInternal:
+ if (!close_main) {
+ *error = (const char *)e_invstream;
+ return false;
+ }
+ break;
+
+ default:
+ abort();
+ }
+
+ return true;
+}
+
+/// Initializes the module
+void channel_init(void)
+{
+ channels = pmap_new(uint64_t)();
+ channel_alloc(kChannelStreamStderr);
+ rpc_init();
+}
+
+/// Allocates a channel.
+///
+/// Channel is allocated with refcount 1, which should be decreased
+/// when the underlying stream closes.
+static Channel *channel_alloc(ChannelStreamType type)
+{
+ Channel *chan = xcalloc(1, sizeof(*chan));
+ if (type == kChannelStreamStdio) {
+ chan->id = CHAN_STDIO;
+ } else if (type == kChannelStreamStderr) {
+ chan->id = CHAN_STDERR;
+ } else {
+ chan->id = next_chan_id++;
+ }
+ chan->events = multiqueue_new_child(main_loop.events);
+ chan->refcount = 1;
+ chan->streamtype = type;
+ pmap_put(uint64_t)(channels, chan->id, chan);
+ return chan;
+}
+
+void channel_create_event(Channel *chan, const char *ext_source)
+{
+#if MIN_LOG_LEVEL <= INFO_LOG_LEVEL
+ const char *source;
+
+ if (ext_source) {
+ // TODO(bfredl): in a future improved traceback solution,
+ // external events should be included.
+ source = ext_source;
+ } else {
+ eval_fmt_source_name_line((char *)IObuff, sizeof(IObuff));
+ source = (const char *)IObuff;
+ }
+
+ Dictionary info = channel_info(chan->id);
+ typval_T tv = TV_INITIAL_VALUE;
+ // TODO(bfredl): do the conversion in one step. Also would be nice
+ // to pretty print top level dict in defined order
+ (void)object_to_vim(DICTIONARY_OBJ(info), &tv, NULL);
+ char *str = encode_tv2json(&tv, NULL);
+ ILOG("new channel %" PRIu64 " (%s) : %s", chan->id, source, str);
+ xfree(str);
+ api_free_dictionary(info);
+
+#else
+ (void)ext_source;
+#endif
+
+ channel_info_changed(chan, true);
+}
+
+void channel_incref(Channel *chan)
+{
+ chan->refcount++;
+}
+
+void channel_decref(Channel *chan)
+{
+ if (!(--chan->refcount)) {
+ // delay free, so that libuv is done with the handles
+ multiqueue_put(main_loop.events, free_channel_event, 1, chan);
+ }
+}
+
+void callback_reader_free(CallbackReader *reader)
+{
+ callback_free(&reader->cb);
+ ga_clear(&reader->buffer);
+}
+
+void callback_reader_start(CallbackReader *reader)
+{
+ ga_init(&reader->buffer, sizeof(char *), 32);
+}
+
+static void free_channel_event(void **argv)
+{
+ Channel *chan = argv[0];
+ if (chan->is_rpc) {
+ rpc_free(chan);
+ }
+
+ callback_reader_free(&chan->on_stdout);
+ callback_reader_free(&chan->on_stderr);
+ callback_free(&chan->on_exit);
+
+ pmap_del(uint64_t)(channels, chan->id);
+ multiqueue_free(chan->events);
+ xfree(chan);
+}
+
+static void channel_destroy_early(Channel *chan)
+{
+ if ((chan->id != --next_chan_id)) {
+ abort();
+ }
+ pmap_del(uint64_t)(channels, chan->id);
+ chan->id = 0;
+
+ if ((--chan->refcount != 0)) {
+ abort();
+ }
+
+ // uv will keep a reference to handles until next loop tick, so delay free
+ multiqueue_put(main_loop.events, free_channel_event, 1, chan);
+}
+
+
+static void close_cb(Stream *stream, void *data)
+{
+ channel_decref(data);
+}
+
+Channel *channel_job_start(char **argv, CallbackReader on_stdout,
+ CallbackReader on_stderr, Callback on_exit,
+ bool pty, bool rpc, bool detach, const char *cwd,
+ uint16_t pty_width, uint16_t pty_height,
+ char *term_name, varnumber_T *status_out)
+{
+ assert(cwd == NULL || os_isdir_executable(cwd));
+
+ Channel *chan = channel_alloc(kChannelStreamProc);
+ chan->on_stdout = on_stdout;
+ chan->on_stderr = on_stderr;
+ chan->on_exit = on_exit;
+
+ if (pty) {
+ if (detach) {
+ EMSG2(_(e_invarg2), "terminal/pty job cannot be detached");
+ shell_free_argv(argv);
+ xfree(term_name);
+ channel_destroy_early(chan);
+ *status_out = 0;
+ return NULL;
+ }
+ chan->stream.pty = pty_process_init(&main_loop, chan);
+ if (pty_width > 0) {
+ chan->stream.pty.width = pty_width;
+ }
+ if (pty_height > 0) {
+ chan->stream.pty.height = pty_height;
+ }
+ if (term_name) {
+ chan->stream.pty.term_name = term_name;
+ }
+ } else {
+ chan->stream.uv = libuv_process_init(&main_loop, chan);
+ }
+
+ Process *proc = (Process *)&chan->stream.proc;
+ proc->argv = argv;
+ proc->cb = channel_process_exit_cb;
+ proc->events = chan->events;
+ proc->detach = detach;
+ proc->cwd = cwd;
+
+ char *cmd = xstrdup(proc->argv[0]);
+ bool has_out, has_err;
+ if (proc->type == kProcessTypePty) {
+ has_out = true;
+ has_err = false;
+ } else {
+ has_out = rpc || callback_reader_set(chan->on_stdout);
+ has_err = callback_reader_set(chan->on_stderr);
+ }
+ int status = process_spawn(proc, true, has_out, has_err);
+ if (status) {
+ EMSG3(_(e_jobspawn), os_strerror(status), cmd);
+ xfree(cmd);
+ if (proc->type == kProcessTypePty) {
+ xfree(chan->stream.pty.term_name);
+ }
+ channel_destroy_early(chan);
+ *status_out = proc->status;
+ return NULL;
+ }
+ xfree(cmd);
+
+ wstream_init(&proc->in, 0);
+ if (has_out) {
+ rstream_init(&proc->out, 0);
+ }
+
+ if (rpc) {
+ // the rpc takes over the in and out streams
+ rpc_start(chan);
+ } else {
+ if (has_out) {
+ callback_reader_start(&chan->on_stdout);
+ rstream_start(&proc->out, on_job_stdout, chan);
+ }
+ }
+
+ if (has_err) {
+ callback_reader_start(&chan->on_stderr);
+ rstream_init(&proc->err, 0);
+ rstream_start(&proc->err, on_job_stderr, chan);
+ }
+
+ *status_out = (varnumber_T)chan->id;
+ return chan;
+}
+
+
+uint64_t channel_connect(bool tcp, const char *address,
+ bool rpc, CallbackReader on_output,
+ int timeout, const char **error)
+{
+ Channel *channel;
+
+ if (!tcp && rpc) {
+ char *path = fix_fname(address);
+ bool loopback = server_owns_pipe_address(path);
+ xfree(path);
+ if (loopback) {
+ // Create a loopback channel. This avoids deadlock if nvim connects to
+ // its own named pipe.
+ channel = channel_alloc(kChannelStreamInternal);
+ rpc_start(channel);
+ goto end;
+ }
+ }
+
+ channel = channel_alloc(kChannelStreamSocket);
+ if (!socket_connect(&main_loop, &channel->stream.socket,
+ tcp, address, timeout, error)) {
+ channel_destroy_early(channel);
+ return 0;
+ }
+
+ channel->stream.socket.internal_close_cb = close_cb;
+ channel->stream.socket.internal_data = channel;
+ wstream_init(&channel->stream.socket, 0);
+ rstream_init(&channel->stream.socket, 0);
+
+ if (rpc) {
+ rpc_start(channel);
+ } else {
+ channel->on_stdout = on_output;
+ callback_reader_start(&channel->on_stdout);
+ rstream_start(&channel->stream.socket, on_socket_output, channel);
+ }
+
+end:
+ channel_create_event(channel, address);
+ return channel->id;
+}
+
+/// Creates an RPC channel from a tcp/pipe socket connection
+///
+/// @param watcher The SocketWatcher ready to accept the connection
+void channel_from_connection(SocketWatcher *watcher)
+{
+ Channel *channel = channel_alloc(kChannelStreamSocket);
+ socket_watcher_accept(watcher, &channel->stream.socket);
+ channel->stream.socket.internal_close_cb = close_cb;
+ channel->stream.socket.internal_data = channel;
+ wstream_init(&channel->stream.socket, 0);
+ rstream_init(&channel->stream.socket, 0);
+ rpc_start(channel);
+ channel_create_event(channel, watcher->addr);
+}
+
+/// Creates an API channel from stdin/stdout. This is used when embedding
+/// Neovim
+uint64_t channel_from_stdio(bool rpc, CallbackReader on_output,
+ const char **error)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!headless_mode && !embedded_mode) {
+ *error = _("can only be opened in headless mode");
+ return 0;
+ }
+
+ if (did_stdio) {
+ *error = _("channel was already open");
+ return 0;
+ }
+ did_stdio = true;
+
+ Channel *channel = channel_alloc(kChannelStreamStdio);
+
+ rstream_init_fd(&main_loop, &channel->stream.stdio.in, 0, 0);
+ wstream_init_fd(&main_loop, &channel->stream.stdio.out, 1, 0);
+
+ if (rpc) {
+ rpc_start(channel);
+ } else {
+ channel->on_stdout = on_output;
+ callback_reader_start(&channel->on_stdout);
+ rstream_start(&channel->stream.stdio.in, on_stdio_input, channel);
+ }
+
+ return channel->id;
+}
+
+/// @param data will be consumed
+size_t channel_send(uint64_t id, char *data, size_t len, const char **error)
+{
+ Channel *chan = find_channel(id);
+ if (!chan) {
+ EMSG(_(e_invchan));
+ goto err;
+ }
+
+ if (chan->streamtype == kChannelStreamStderr) {
+ if (chan->stream.err.closed) {
+ *error = _("Can't send data to closed stream");
+ goto err;
+ }
+ // unbuffered write
+ size_t written = fwrite(data, len, 1, stderr);
+ xfree(data);
+ return len * written;
+ }
+
+
+ Stream *in = channel_instream(chan);
+ if (in->closed) {
+ *error = _("Can't send data to closed stream");
+ goto err;
+ }
+
+ if (chan->is_rpc) {
+ *error = _("Can't send raw data to rpc channel");
+ goto err;
+ }
+
+ WBuffer *buf = wstream_new_buffer(data, len, 1, xfree);
+ return wstream_write(in, buf) ? len : 0;
+
+err:
+ xfree(data);
+ return 0;
+}
+
+/// Convert binary byte array to a readfile()-style list
+///
+/// @param[in] buf Array to convert.
+/// @param[in] len Array length.
+///
+/// @return [allocated] Converted list.
+static inline list_T *buffer_to_tv_list(const char *const buf, const size_t len)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
+{
+ list_T *const l = tv_list_alloc(kListLenMayKnow);
+ // Empty buffer should be represented by [''], encode_list_write() thinks
+ // empty list is fine for the case.
+ tv_list_append_string(l, "", 0);
+ if (len > 0) {
+ encode_list_write(l, buf, len);
+ }
+ return l;
+}
+
+// vimscript job callbacks must be executed on Nvim main loop
+static inline void process_channel_event(Channel *chan, Callback *callback,
+ const char *type,
+ CallbackReader *reader, int status)
+{
+ assert(callback);
+ ChannelEvent *event_data = xmalloc(sizeof(*event_data));
+ event_data->reader = reader;
+ event_data->status = status;
+ channel_incref(chan); // Hold on ref to callback
+ event_data->chan = chan;
+ event_data->callback = callback;
+ event_data->type = type;
+
+ multiqueue_put(chan->events, on_channel_event, 1, event_data);
+}
+
+void on_job_stdout(Stream *stream, RBuffer *buf, size_t count,
+ void *data, bool eof)
+{
+ Channel *chan = data;
+ on_channel_output(stream, chan, buf, count, eof, &chan->on_stdout, "stdout");
+}
+
+void on_job_stderr(Stream *stream, RBuffer *buf, size_t count,
+ void *data, bool eof)
+{
+ Channel *chan = data;
+ on_channel_output(stream, chan, buf, count, eof, &chan->on_stderr, "stderr");
+}
+
+static void on_socket_output(Stream *stream, RBuffer *buf, size_t count,
+ void *data, bool eof)
+{
+ Channel *chan = data;
+ on_channel_output(stream, chan, buf, count, eof, &chan->on_stdout, "data");
+}
+
+static void on_stdio_input(Stream *stream, RBuffer *buf, size_t count,
+ void *data, bool eof)
+{
+ Channel *chan = data;
+ on_channel_output(stream, chan, buf, count, eof, &chan->on_stdout, "stdin");
+}
+
+/// @param type must have static lifetime
+static void on_channel_output(Stream *stream, Channel *chan, RBuffer *buf,
+ size_t count, bool eof, CallbackReader *reader,
+ const char *type)
+{
+ // stub variable, to keep reading consistent with the order of events, only
+ // consider the count parameter.
+ size_t r;
+ char *ptr = rbuffer_read_ptr(buf, &r);
+
+ if (eof) {
+ if (reader->buffered) {
+ if (reader->cb.type != kCallbackNone) {
+ process_channel_event(chan, &reader->cb, type, reader, 0);
+ } else if (reader->self) {
+ if (tv_dict_find(reader->self, type, -1) == NULL) {
+ list_T *data = buffer_to_tv_list(reader->buffer.ga_data,
+ (size_t)reader->buffer.ga_len);
+ tv_dict_add_list(reader->self, type, strlen(type), data);
+ } else {
+ // can't display error message now, defer it.
+ channel_incref(chan);
+ multiqueue_put(chan->events, on_buffered_error, 2, chan, type);
+ }
+ ga_clear(&reader->buffer);
+ } else {
+ abort();
+ }
+ } else if (reader->cb.type != kCallbackNone) {
+ process_channel_event(chan, &reader->cb, type, reader, 0);
+ }
+ return;
+ }
+
+ // The order here matters, the terminal must receive the data first because
+ // process_channel_event will modify the read buffer(convert NULs into NLs)
+ if (chan->term) {
+ terminal_receive(chan->term, ptr, count);
+ terminal_flush_output(chan->term);
+ }
+
+ rbuffer_consumed(buf, count);
+
+ if (callback_reader_set(*reader) || reader->buffered) {
+ // if buffer wasn't consumed, a pending callback is stalled. Aggregate the
+ // received data and avoid a "burst" of multiple callbacks.
+ bool buffer_set = reader->buffer.ga_len > 0;
+ ga_concat_len(&reader->buffer, ptr, count);
+ if (callback_reader_set(*reader) && !reader->buffered && !buffer_set) {
+ process_channel_event(chan, &reader->cb, type, reader, 0);
+ }
+ }
+}
+
+static void on_buffered_error(void **args)
+{
+ Channel *chan = (Channel *)args[0];
+ const char *stream = (const char *)args[1];
+ EMSG3(_(e_streamkey), stream, chan->id);
+ channel_decref(chan);
+}
+
+static void channel_process_exit_cb(Process *proc, int status, void *data)
+{
+ Channel *chan = data;
+ if (chan->term) {
+ char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
+ snprintf(msg, sizeof msg, "\r\n[Process exited %d]", proc->status);
+ terminal_close(chan->term, msg);
+ }
+
+ // If process did not exit, we only closed the handle of a detached process.
+ bool exited = (status >= 0);
+ if (exited) {
+ process_channel_event(chan, &chan->on_exit, "exit", NULL, status);
+ }
+
+ channel_decref(chan);
+}
+
+static void on_channel_event(void **args)
+{
+ ChannelEvent *ev = (ChannelEvent *)args[0];
+
+ typval_T argv[4];
+
+ argv[0].v_type = VAR_NUMBER;
+ argv[0].v_lock = VAR_UNLOCKED;
+ argv[0].vval.v_number = (varnumber_T)ev->chan->id;
+
+ if (ev->reader) {
+ argv[1].v_type = VAR_LIST;
+ argv[1].v_lock = VAR_UNLOCKED;
+ argv[1].vval.v_list = buffer_to_tv_list(ev->reader->buffer.ga_data,
+ (size_t)ev->reader->buffer.ga_len);
+ tv_list_ref(argv[1].vval.v_list);
+ ga_clear(&ev->reader->buffer);
+ } else {
+ argv[1].v_type = VAR_NUMBER;
+ argv[1].v_lock = VAR_UNLOCKED;
+ argv[1].vval.v_number = ev->status;
+ }
+
+ argv[2].v_type = VAR_STRING;
+ argv[2].v_lock = VAR_UNLOCKED;
+ argv[2].vval.v_string = (uint8_t *)ev->type;
+
+ typval_T rettv = TV_INITIAL_VALUE;
+ callback_call(ev->callback, 3, argv, &rettv);
+ tv_clear(&rettv);
+ channel_decref(ev->chan);
+ xfree(ev);
+}
+
+
+/// Open terminal for channel
+///
+/// Channel `chan` is assumed to be an open pty channel,
+/// and curbuf is assumed to be a new, unmodified buffer.
+void channel_terminal_open(Channel *chan)
+{
+ TerminalOptions topts;
+ topts.data = chan;
+ topts.width = chan->stream.pty.width;
+ topts.height = chan->stream.pty.height;
+ topts.write_cb = term_write;
+ topts.resize_cb = term_resize;
+ topts.close_cb = term_close;
+ curbuf->b_p_channel = (long)chan->id; // 'channel' option
+ Terminal *term = terminal_open(topts);
+ chan->term = term;
+ channel_incref(chan);
+}
+
+static void term_write(char *buf, size_t size, void *data)
+{
+ Channel *chan = data;
+ if (chan->stream.proc.in.closed) {
+ // If the backing stream was closed abruptly, there may be write events
+ // ahead of the terminal close event. Just ignore the writes.
+ ILOG("write failed: stream is closed");
+ return;
+ }
+ WBuffer *wbuf = wstream_new_buffer(xmemdup(buf, size), size, 1, xfree);
+ wstream_write(&chan->stream.proc.in, wbuf);
+}
+
+static void term_resize(uint16_t width, uint16_t height, void *data)
+{
+ Channel *chan = data;
+ pty_process_resize(&chan->stream.pty, width, height);
+}
+
+static inline void term_delayed_free(void **argv)
+{
+ Channel *chan = argv[0];
+ if (chan->stream.proc.in.pending_reqs || chan->stream.proc.out.pending_reqs) {
+ multiqueue_put(chan->events, term_delayed_free, 1, chan);
+ return;
+ }
+
+ terminal_destroy(chan->term);
+ chan->term = NULL;
+ channel_decref(chan);
+}
+
+static void term_close(void *data)
+{
+ Channel *chan = data;
+ process_stop(&chan->stream.proc);
+ multiqueue_put(chan->events, term_delayed_free, 1, data);
+}
+
+void channel_info_changed(Channel *chan, bool new)
+{
+ event_T event = new ? EVENT_CHANOPEN : EVENT_CHANINFO;
+ if (has_event(event)) {
+ channel_incref(chan);
+ multiqueue_put(main_loop.events, set_info_event,
+ 2, chan, event);
+ }
+}
+
+static void set_info_event(void **argv)
+{
+ Channel *chan = argv[0];
+ event_T event = (event_T)(ptrdiff_t)argv[1];
+
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+ Dictionary info = channel_info(chan->id);
+ typval_T retval;
+ (void)object_to_vim(DICTIONARY_OBJ(info), &retval, NULL);
+ tv_dict_add_dict(dict, S_LEN("info"), retval.vval.v_dict);
+
+ apply_autocmds(event, NULL, NULL, false, curbuf);
+
+ tv_dict_clear(dict);
+ api_free_dictionary(info);
+ channel_decref(chan);
+}
+
+Dictionary channel_info(uint64_t id)
+{
+ Channel *chan = find_channel(id);
+ if (!chan) {
+ return (Dictionary)ARRAY_DICT_INIT;
+ }
+
+ Dictionary info = ARRAY_DICT_INIT;
+ PUT(info, "id", INTEGER_OBJ((Integer)chan->id));
+
+ const char *stream_desc, *mode_desc;
+ switch (chan->streamtype) {
+ case kChannelStreamProc:
+ stream_desc = "job";
+ if (chan->stream.proc.type == kProcessTypePty) {
+ const char *name = pty_process_tty_name(&chan->stream.pty);
+ PUT(info, "pty", STRING_OBJ(cstr_to_string(name)));
+ }
+ break;
+
+ case kChannelStreamStdio:
+ stream_desc = "stdio";
+ break;
+
+ case kChannelStreamStderr:
+ stream_desc = "stderr";
+ break;
+
+ case kChannelStreamInternal:
+ PUT(info, "internal", BOOLEAN_OBJ(true));
+ FALLTHROUGH;
+
+ case kChannelStreamSocket:
+ stream_desc = "socket";
+ break;
+
+ default:
+ abort();
+ }
+ PUT(info, "stream", STRING_OBJ(cstr_to_string(stream_desc)));
+
+ if (chan->is_rpc) {
+ mode_desc = "rpc";
+ PUT(info, "client", DICTIONARY_OBJ(rpc_client_info(chan)));
+ } else if (chan->term) {
+ mode_desc = "terminal";
+ PUT(info, "buffer", BUFFER_OBJ(terminal_buf(chan->term)));
+ } else {
+ mode_desc = "bytes";
+ }
+ PUT(info, "mode", STRING_OBJ(cstr_to_string(mode_desc)));
+
+ return info;
+}
+
+Array channel_all_info(void)
+{
+ Channel *channel;
+ Array ret = ARRAY_DICT_INIT;
+ map_foreach_value(channels, channel, {
+ ADD(ret, DICTIONARY_OBJ(channel_info(channel->id)));
+ });
+ return ret;
+}
diff --git a/src/nvim/channel.h b/src/nvim/channel.h
new file mode 100644
index 0000000000..b856d197f1
--- /dev/null
+++ b/src/nvim/channel.h
@@ -0,0 +1,134 @@
+#ifndef NVIM_CHANNEL_H
+#define NVIM_CHANNEL_H
+
+#include "nvim/main.h"
+#include "nvim/event/socket.h"
+#include "nvim/event/process.h"
+#include "nvim/os/pty_process.h"
+#include "nvim/event/libuv_process.h"
+#include "nvim/eval/typval.h"
+#include "nvim/msgpack_rpc/channel_defs.h"
+
+#define CHAN_STDIO 1
+#define CHAN_STDERR 2
+
+typedef enum {
+ kChannelStreamProc,
+ kChannelStreamSocket,
+ kChannelStreamStdio,
+ kChannelStreamStderr,
+ kChannelStreamInternal
+} ChannelStreamType;
+
+typedef enum {
+ kChannelPartStdin,
+ kChannelPartStdout,
+ kChannelPartStderr,
+ kChannelPartRpc,
+ kChannelPartAll
+} ChannelPart;
+
+
+typedef struct {
+ Stream in;
+ Stream out;
+} StdioPair;
+
+typedef struct {
+ bool closed;
+} StderrState;
+
+typedef struct {
+ Callback cb;
+ dict_T *self;
+ garray_T buffer;
+ bool buffered;
+} CallbackReader;
+
+#define CALLBACK_READER_INIT ((CallbackReader){ .cb = CALLBACK_NONE, \
+ .self = NULL, \
+ .buffer = GA_EMPTY_INIT_VALUE, \
+ .buffered = false })
+static inline bool callback_reader_set(CallbackReader reader)
+{
+ return reader.cb.type != kCallbackNone || reader.self;
+}
+
+struct Channel {
+ uint64_t id;
+ size_t refcount;
+ MultiQueue *events;
+
+ ChannelStreamType streamtype;
+ union {
+ Process proc;
+ LibuvProcess uv;
+ PtyProcess pty;
+ Stream socket;
+ StdioPair stdio;
+ StderrState err;
+ } stream;
+
+ bool is_rpc;
+ RpcState rpc;
+ Terminal *term;
+
+ CallbackReader on_stdout;
+ CallbackReader on_stderr;
+ Callback on_exit;
+};
+
+EXTERN PMap(uint64_t) *channels;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "channel.h.generated.h"
+#endif
+
+/// @returns Channel with the id or NULL if not found
+static inline Channel *find_channel(uint64_t id)
+{
+ return pmap_get(uint64_t)(channels, id);
+}
+
+static inline Stream *channel_instream(Channel *chan)
+ FUNC_ATTR_NONNULL_ALL
+{
+ switch (chan->streamtype) {
+ case kChannelStreamProc:
+ return &chan->stream.proc.in;
+
+ case kChannelStreamSocket:
+ return &chan->stream.socket;
+
+ case kChannelStreamStdio:
+ return &chan->stream.stdio.out;
+
+ case kChannelStreamInternal:
+ case kChannelStreamStderr:
+ abort();
+ }
+ abort();
+}
+
+static inline Stream *channel_outstream(Channel *chan)
+ FUNC_ATTR_NONNULL_ALL
+{
+ switch (chan->streamtype) {
+ case kChannelStreamProc:
+ return &chan->stream.proc.out;
+
+ case kChannelStreamSocket:
+ return &chan->stream.socket;
+
+ case kChannelStreamStdio:
+ return &chan->stream.stdio.in;
+
+ case kChannelStreamInternal:
+ case kChannelStreamStderr:
+ abort();
+ }
+ abort();
+}
+
+
+#endif // NVIM_CHANNEL_H
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 5ae4416052..c220c4e347 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.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
+
/// @file charset.c
///
/// Code related to character sets.
@@ -15,17 +18,19 @@
#include "nvim/func_attr.h"
#include "nvim/indent.h"
#include "nvim/main.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/move.h"
+#include "nvim/option.h"
#include "nvim/os_unix.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/path.h"
-
+#include "nvim/cursor.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "charset.c.generated.h"
@@ -40,23 +45,30 @@ static bool chartab_initialized = false;
(buf)->b_chartab[(unsigned)(c) >> 6] |= (1ull << ((c) & 0x3f))
#define RESET_CHARTAB(buf, c) \
(buf)->b_chartab[(unsigned)(c) >> 6] &= ~(1ull << ((c) & 0x3f))
+#define GET_CHARTAB_TAB(chartab, c) \
+ ((chartab)[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
#define GET_CHARTAB(buf, c) \
- ((buf)->b_chartab[(unsigned)(c) >> 6] & (1ull << ((c) & 0x3f)))
+ GET_CHARTAB_TAB((buf)->b_chartab, c)
+
+// Table used below, see init_chartab() for an explanation
+static char_u g_chartab[256];
+
+// Flags for g_chartab[].
+#define CT_CELL_MASK 0x07 ///< mask: nr of display cells (1, 2 or 4)
+#define CT_PRINT_CHAR 0x10 ///< flag: set for printable chars
+#define CT_ID_CHAR 0x20 ///< flag: set for ID chars
+#define CT_FNAME_CHAR 0x40 ///< flag: set for file name chars
-/// Fill chartab[]. Also fills curbuf->b_chartab[] with flags for keyword
+/// Fill g_chartab[]. Also fills curbuf->b_chartab[] with flags for keyword
/// characters for current buffer.
///
/// Depends on the option settings 'iskeyword', 'isident', 'isfname',
/// 'isprint' and 'encoding'.
///
-/// The index in chartab[] depends on 'encoding':
-/// - For non-multi-byte index with the byte (same as the character).
-/// - For DBCS index with the first byte.
-/// - For UTF-8 index with the character (when first byte is up to 0x80 it is
-/// the same as the character, if the first byte is 0x80 and above it depends
-/// on further bytes).
+/// The index in g_chartab[] is the character when first byte is up to 0x80,
+/// if the first byte is 0x80 and above it depends on further bytes.
///
-/// The contents of chartab[]:
+/// The contents of g_chartab[]:
/// - The lower two bits, masked by CT_CELL_MASK, give the number of display
/// cells the character occupies (1 or 2). Not valid for UTF-8 above 0x80.
/// - CT_PRINT_CHAR bit is set when the character is printable (no need to
@@ -82,7 +94,6 @@ int buf_init_chartab(buf_T *buf, int global)
{
int c;
int c2;
- char_u *p;
int i;
bool tilde;
bool do_isalpha;
@@ -94,41 +105,33 @@ int buf_init_chartab(buf_T *buf, int global)
c = 0;
while (c < ' ') {
- chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
+ g_chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
}
while (c <= '~') {
- chartab[c++] = 1 + CT_PRINT_CHAR;
+ g_chartab[c++] = 1 + CT_PRINT_CHAR;
}
if (p_altkeymap) {
while (c < YE) {
- chartab[c++] = 1 + CT_PRINT_CHAR;
+ g_chartab[c++] = 1 + CT_PRINT_CHAR;
}
}
while (c < 256) {
- if (enc_utf8 && (c >= 0xa0)) {
+ if (c >= 0xa0) {
// UTF-8: bytes 0xa0 - 0xff are printable (latin1)
- chartab[c++] = CT_PRINT_CHAR + 1;
- } else if ((enc_dbcs == DBCS_JPNU) && (c == 0x8e)) {
- // euc-jp characters starting with 0x8e are single width
- chartab[c++] = CT_PRINT_CHAR + 1;
- } else if ((enc_dbcs != 0) && (MB_BYTE2LEN(c) == 2)) {
- // other double-byte chars can be printable AND double-width
- chartab[c++] = CT_PRINT_CHAR + 2;
+ g_chartab[c++] = CT_PRINT_CHAR + 1;
} else {
// the rest is unprintable by default
- chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
+ g_chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2;
}
}
// Assume that every multi-byte char is a filename character.
- for (c = 1; c < 256; ++c) {
- if (((enc_dbcs != 0) && (MB_BYTE2LEN(c) > 1))
- || ((enc_dbcs == DBCS_JPNU) && (c == 0x8e))
- || (enc_utf8 && (c >= 0xa0))) {
- chartab[c] |= CT_FNAME_CHAR;
+ for (c = 1; c < 256; c++) {
+ if (c >= 0xa0) {
+ g_chartab[c] |= CT_FNAME_CHAR;
}
}
}
@@ -136,15 +139,6 @@ int buf_init_chartab(buf_T *buf, int global)
// Init word char flags all to false
memset(buf->b_chartab, 0, (size_t)32);
- if (enc_dbcs != 0) {
- for (c = 0; c < 256; ++c) {
- // double-byte characters are probably word characters
- if (MB_BYTE2LEN(c) == 2) {
- SET_CHARTAB(buf, c);
- }
- }
- }
-
// In lisp mode the '-' character is included in keywords.
if (buf->b_p_lisp) {
SET_CHARTAB(buf, '-');
@@ -153,7 +147,8 @@ int buf_init_chartab(buf_T *buf, int global)
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
// options Each option is a list of characters, character numbers or
// ranges, separated by commas, e.g.: "200-210,x,#-178,-"
- for (i = global ? 0 : 3; i <= 3; ++i) {
+ for (i = global ? 0 : 3; i <= 3; i++) {
+ const char_u *p;
if (i == 0) {
// first round: 'isident'
p = p_isi;
@@ -178,11 +173,9 @@ int buf_init_chartab(buf_T *buf, int global)
}
if (ascii_isdigit(*p)) {
- c = getdigits_int(&p);
- } else if (has_mbyte) {
- c = mb_ptr2char_adv(&p);
+ c = getdigits_int((char_u **)&p);
} else {
- c = *p++;
+ c = mb_ptr2char_adv(&p);
}
c2 = -1;
@@ -190,11 +183,9 @@ int buf_init_chartab(buf_T *buf, int global)
++p;
if (ascii_isdigit(*p)) {
- c2 = getdigits_int(&p);
- } else if (has_mbyte) {
- c2 = mb_ptr2char_adv(&p);
+ c2 = getdigits_int((char_u **)&p);
} else {
- c2 = *p++;
+ c2 = mb_ptr2char_adv(&p);
}
}
@@ -225,15 +216,15 @@ int buf_init_chartab(buf_T *buf, int global)
// work properly when 'encoding' is "latin1" and the locale is
// "C".
if (!do_isalpha
- || vim_islower(c)
- || vim_isupper(c)
+ || mb_islower(c)
+ || mb_isupper(c)
|| (p_altkeymap && (F_isalpha(c) || F_isdigit(c)))) {
if (i == 0) {
// (re)set ID flag
if (tilde) {
- chartab[c] &= (uint8_t)~CT_ID_CHAR;
+ g_chartab[c] &= (uint8_t)~CT_ID_CHAR;
} else {
- chartab[c] |= CT_ID_CHAR;
+ g_chartab[c] |= CT_ID_CHAR;
}
} else if (i == 1) {
// (re)set printable
@@ -241,23 +232,22 @@ int buf_init_chartab(buf_T *buf, int global)
// that we can detect it from the first byte.
if (((c < ' ')
|| (c > '~')
- || (p_altkeymap && (F_isalpha(c) || F_isdigit(c))))
- && !(enc_dbcs && (MB_BYTE2LEN(c) == 2))) {
+ || (p_altkeymap && (F_isalpha(c) || F_isdigit(c))))) {
if (tilde) {
- chartab[c] = (uint8_t)((chartab[c] & ~CT_CELL_MASK)
- + ((dy_flags & DY_UHEX) ? 4 : 2));
- chartab[c] &= (uint8_t)~CT_PRINT_CHAR;
+ g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK)
+ + ((dy_flags & DY_UHEX) ? 4 : 2));
+ g_chartab[c] &= (uint8_t)~CT_PRINT_CHAR;
} else {
- chartab[c] = (uint8_t)((chartab[c] & ~CT_CELL_MASK) + 1);
- chartab[c] |= CT_PRINT_CHAR;
+ g_chartab[c] = (uint8_t)((g_chartab[c] & ~CT_CELL_MASK) + 1);
+ g_chartab[c] |= CT_PRINT_CHAR;
}
}
} else if (i == 2) {
// (re)set fname flag
if (tilde) {
- chartab[c] &= (uint8_t)~CT_FNAME_CHAR;
+ g_chartab[c] &= (uint8_t)~CT_FNAME_CHAR;
} else {
- chartab[c] |= CT_FNAME_CHAR;
+ g_chartab[c] |= CT_FNAME_CHAR;
}
} else { // i == 3
// (re)set keyword flag
@@ -303,7 +293,7 @@ void trans_characters(char_u *buf, int bufsize)
while (*buf != 0) {
// Assume a multi-byte character doesn't need translation.
- if (has_mbyte && ((trs_len = (*mb_ptr2len)(buf)) > 1)) {
+ if ((trs_len = (*mb_ptr2len)(buf)) > 1) {
len -= trs_len;
} else {
trs = transchar_byte(*buf);
@@ -323,73 +313,115 @@ void trans_characters(char_u *buf, int bufsize)
}
}
-/// Translate a string into allocated memory, replacing special chars with
-/// printable chars.
+/// Find length of a string capable of holding s with all specials replaced
///
-/// @param s
+/// Assumes replacing special characters with printable ones just like
+/// strtrans() does.
+///
+/// @param[in] s String to check.
///
-/// @return translated string
-char_u *transstr(char_u *s) FUNC_ATTR_NONNULL_RET
+/// @return number of bytes needed to hold a translation of `s`, NUL byte not
+/// included.
+size_t transstr_len(const char *const s)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
- char_u *res;
- char_u *p;
- int c;
- size_t l;
- char_u hexbuf[11];
-
- if (has_mbyte) {
- // Compute the length of the result, taking account of unprintable
- // multi-byte characters.
- size_t len = 0;
- p = s;
-
- while (*p != NUL) {
- if ((l = (size_t)(*mb_ptr2len)(p)) > 1) {
- c = (*mb_ptr2char)(p);
- p += l;
-
- if (vim_isprintc(c)) {
- len += l;
- } else {
- transchar_hex(hexbuf, c);
- len += STRLEN(hexbuf);
- }
- } else {
- l = (size_t)byte2cells(*p++);
+ const char *p = s;
+ size_t len = 0;
- if (l > 0) {
- len += l;
- } else {
- // illegal byte sequence
- len += 4;
+ while (*p) {
+ const size_t l = (size_t)utfc_ptr2len((const char_u *)p);
+ if (l > 1) {
+ int pcc[MAX_MCO + 1];
+ pcc[0] = utfc_ptr2char((const char_u *)p, &pcc[1]);
+
+ if (vim_isprintc(pcc[0])) {
+ len += l;
+ } else {
+ for (size_t i = 0; i < ARRAY_SIZE(pcc) && pcc[i]; i++) {
+ char hexbuf[9];
+ len += transchar_hex(hexbuf, pcc[i]);
}
}
+ p += l;
+ } else {
+ const int b2c_l = byte2cells((uint8_t)(*p++));
+ // Illegal byte sequence may occupy up to 4 characters.
+ len += (size_t)(b2c_l > 0 ? b2c_l : 4);
}
- res = xmallocz(len);
- } else {
- res = xmallocz((size_t)vim_strsize(s));
}
+ return len;
+}
- *res = NUL;
- p = s;
-
- while (*p != NUL) {
- if (has_mbyte && ((l = (size_t)(*mb_ptr2len)(p)) > 1)) {
- c = (*mb_ptr2char)(p);
+/// Replace special characters with printable ones
+///
+/// @param[in] s String to replace characters from.
+/// @param[out] buf Buffer to which result should be saved.
+/// @param[in] len Buffer length. Resulting string may not occupy more then
+/// len - 1 bytes (one for trailing NUL byte).
+///
+/// @return length of the resulting string, without the NUL byte.
+size_t transstr_buf(const char *const s, char *const buf, const size_t len)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const char *p = s;
+ char *buf_p = buf;
+ char *const buf_e = buf_p + len - 1;
+
+ while (*p != NUL && buf_p < buf_e) {
+ const size_t l = (size_t)utfc_ptr2len((const char_u *)p);
+ if (l > 1) {
+ if (buf_p + l > buf_e) {
+ break; // Exceeded `buf` size.
+ }
+ int pcc[MAX_MCO + 1];
+ pcc[0] = utfc_ptr2char((const char_u *)p, &pcc[1]);
- if (vim_isprintc(c)) {
- // append printable multi-byte char
- STRNCAT(res, p, l);
+ if (vim_isprintc(pcc[0])) {
+ memmove(buf_p, p, l);
+ buf_p += l;
} else {
- transchar_hex(res + STRLEN(res), c);
+ for (size_t i = 0; i < ARRAY_SIZE(pcc) && pcc[i]; i++) {
+ char hexbuf[9]; // <up to 6 bytes>NUL
+ const size_t hexlen = transchar_hex(hexbuf, pcc[i]);
+ if (buf_p + hexlen > buf_e) {
+ break;
+ }
+ memmove(buf_p, hexbuf, hexlen);
+ buf_p += hexlen;
+ }
}
p += l;
} else {
- STRCAT(res, transchar_byte(*p++));
+ const char *const tb = (const char *)transchar_byte((uint8_t)(*p++));
+ const size_t tb_len = strlen(tb);
+ if (buf_p + tb_len > buf_e) {
+ break; // Exceeded `buf` size.
+ }
+ memmove(buf_p, tb, tb_len);
+ buf_p += tb_len;
}
}
+ *buf_p = NUL;
+ assert(buf_p <= buf_e);
+ return (size_t)(buf_p - buf);
+}
- return res;
+/// Copy string and replace special characters with printable characters
+///
+/// Works like `strtrans()` does, used for that and in some other places.
+///
+/// @param[in] s String to replace characters from.
+///
+/// @return [allocated] translated string
+char *transstr(const char *const s)
+ FUNC_ATTR_NONNULL_RET
+{
+ // Compute the length of the result, taking account of unprintable
+ // multi-byte characters.
+ const size_t len = transstr_len((const char *)s) + 1;
+ char *const buf = xmalloc(len);
+ transstr_buf(s, buf, len);
+ return buf;
}
/// Convert the string "str[orglen]" to do ignore-case comparing.
@@ -433,79 +465,71 @@ char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
// Make each character lower case.
i = 0;
while (STR_CHAR(i) != NUL) {
- if (enc_utf8 || (has_mbyte && (MB_BYTE2LEN(STR_CHAR(i)) > 1))) {
- if (enc_utf8) {
- int c = utf_ptr2char(STR_PTR(i));
- int olen = utf_ptr2len(STR_PTR(i));
- int lc = utf_tolower(c);
-
- // Only replace the character when it is not an invalid
- // sequence (ASCII character or more than one byte) and
- // utf_tolower() doesn't return the original character.
- if (((c < 0x80) || (olen > 1)) && (c != lc)) {
- int nlen = utf_char2len(lc);
-
- // If the byte length changes need to shift the following
- // characters forward or backward.
- if (olen != nlen) {
- if (nlen > olen) {
- if (buf == NULL) {
- ga_grow(&ga, nlen - olen + 1);
- } else {
- if (len + nlen - olen >= buflen) {
- // out of memory, keep old char
- lc = c;
- nlen = olen;
- }
- }
- }
-
- if (olen != nlen) {
- if (buf == NULL) {
- STRMOVE(GA_PTR(i) + nlen, GA_PTR(i) + olen);
- ga.ga_len += nlen - olen;
- } else {
- STRMOVE(buf + i + nlen, buf + i + olen);
- len += nlen - olen;
- }
+ int c = utf_ptr2char(STR_PTR(i));
+ int olen = utf_ptr2len(STR_PTR(i));
+ int lc = mb_tolower(c);
+
+ // Only replace the character when it is not an invalid
+ // sequence (ASCII character or more than one byte) and
+ // mb_tolower() doesn't return the original character.
+ if (((c < 0x80) || (olen > 1)) && (c != lc)) {
+ int nlen = utf_char2len(lc);
+
+ // If the byte length changes need to shift the following
+ // characters forward or backward.
+ if (olen != nlen) {
+ if (nlen > olen) {
+ if (buf == NULL) {
+ ga_grow(&ga, nlen - olen + 1);
+ } else {
+ if (len + nlen - olen >= buflen) {
+ // out of memory, keep old char
+ lc = c;
+ nlen = olen;
}
}
- (void)utf_char2bytes(lc, STR_PTR(i));
}
- }
- // skip to next multi-byte char
- i += (*mb_ptr2len)(STR_PTR(i));
- } else {
- if (buf == NULL) {
- GA_CHAR(i) = (char_u)TOLOWER_LOC(GA_CHAR(i));
- } else {
- buf[i] = (char_u)TOLOWER_LOC(buf[i]);
+ if (olen != nlen) {
+ if (buf == NULL) {
+ STRMOVE(GA_PTR(i) + nlen, GA_PTR(i) + olen);
+ ga.ga_len += nlen - olen;
+ } else {
+ STRMOVE(buf + i + nlen, buf + i + olen);
+ len += nlen - olen;
+ }
+ }
}
- ++i;
+ (void)utf_char2bytes(lc, STR_PTR(i));
}
+
+ // skip to next multi-byte char
+ i += (*mb_ptr2len)(STR_PTR(i));
}
+
if (buf == NULL) {
return (char_u *)ga.ga_data;
}
return buf;
}
-// Catch 22: chartab[] can't be initialized before the options are
+// Catch 22: g_chartab[] can't be initialized before the options are
// initialized, and initializing options may cause transchar() to be called!
-// When chartab_initialized == false don't use chartab[].
+// When chartab_initialized == false don't use g_chartab[].
// Does NOT work for multi-byte characters, c must be <= 255.
// Also doesn't work for the first byte of a multi-byte, "c" must be a
// character!
-static char_u transchar_buf[7];
+static char_u transchar_buf[11];
-/// Translates a character
+/// Translate a character into a printable one, leaving printable ASCII intact
///
-/// @param c
+/// All unicode characters are considered non-printable in this function.
///
-/// @return translated character.
-char_u* transchar(int c)
+/// @param[in] c Character to translate.
+///
+/// @return translated character into a static buffer.
+char_u *transchar(int c)
{
int i = 0;
if (IS_SPECIAL(c)) {
@@ -516,38 +540,45 @@ char_u* transchar(int c)
c = K_SECOND(c);
}
- if ((!chartab_initialized && (((c >= ' ') && (c <= '~')) || F_ischar(c)))
- || ((c < 256) && vim_isprintc_strict(c))) {
+ if ((!chartab_initialized && (((c >= ' ') && (c <= '~'))
+ || (p_altkeymap && F_ischar(c))))
+ || ((c <= 0xFF) && vim_isprintc_strict(c))) {
// printable character
transchar_buf[i] = (char_u)c;
transchar_buf[i + 1] = NUL;
- } else {
+ } else if (c <= 0xFF) {
transchar_nonprint(transchar_buf + i, c);
+ } else {
+ transchar_hex((char *)transchar_buf + i, c);
}
return transchar_buf;
}
-/// Like transchar(), but called with a byte instead of a character. Checks
-/// for an illegal UTF-8 byte.
+/// Like transchar(), but called with a byte instead of a character
///
-/// @param c
+/// Checks for an illegal UTF-8 byte.
+///
+/// @param[in] c Byte to translate.
///
/// @return pointer to translated character in transchar_buf.
-char_u* transchar_byte(int c)
+char_u *transchar_byte(const int c)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (enc_utf8 && (c >= 0x80)) {
+ if (c >= 0x80) {
transchar_nonprint(transchar_buf, c);
return transchar_buf;
}
return transchar(c);
}
-/// Convert non-printable character to two or more printable characters in
-/// "buf[]". "buf" needs to be able to hold five bytes.
-/// Does NOT work for multi-byte characters, c must be <= 255.
+/// Convert non-printable characters to 2..4 printable ones
///
-/// @param buf
-/// @param c
+/// @warning Does not work for multi-byte characters, c must be <= 255.
+///
+/// @param[out] buf Buffer to store result in, must be able to hold at least
+/// 5 bytes (conversion result + NUL).
+/// @param[in] c Character to convert. NUL is assumed to be NL according to
+/// `:h NL-used-for-NUL`.
void transchar_nonprint(char_u *buf, int c)
{
if (c == NL) {
@@ -557,64 +588,63 @@ void transchar_nonprint(char_u *buf, int c)
// we use CR in place of NL in this case
c = NL;
}
+ assert(c <= 0xff);
- if (dy_flags & DY_UHEX) {
+ if (dy_flags & DY_UHEX || c > 0x7f) {
// 'display' has "uhex"
- transchar_hex(buf, c);
- } else if (c <= 0x7f) {
+ transchar_hex((char *)buf, c);
+ } else {
// 0x00 - 0x1f and 0x7f
buf[0] = '^';
// DEL displayed as ^?
buf[1] = (char_u)(c ^ 0x40);
buf[2] = NUL;
- } else if (enc_utf8 && (c >= 0x80)) {
- transchar_hex(buf, c);
- } else if ((c >= ' ' + 0x80) && (c <= '~' + 0x80)) {
- // 0xa0 - 0xfe
- buf[0] = '|';
- buf[1] = (char_u)(c - 0x80);
- buf[2] = NUL;
- } else {
- // 0x80 - 0x9f and 0xff
- buf[0] = '~';
- buf[1] = (char_u)((c - 0x80) ^ 0x40);
- buf[2] = NUL;
}
}
-/// Convert a non-printable character to hex.
+/// Convert a non-printable character to hex C string like "<FFFF>"
///
-/// @param buf
-/// @param c
-void transchar_hex(char_u *buf, int c)
+/// @param[out] buf Buffer to store result in.
+/// @param[in] c Character to convert.
+///
+/// @return Number of bytes stored in buffer, excluding trailing NUL byte.
+size_t transchar_hex(char *const buf, const int c)
+ FUNC_ATTR_NONNULL_ALL
{
- int i = 0;
+ size_t i = 0;
- buf[0] = '<';
+ buf[i++] = '<';
if (c > 255) {
- buf[++i] = (char_u)nr2hex((unsigned)c >> 12);
- buf[++i] = (char_u)nr2hex((unsigned)c >> 8);
- }
- buf[++i] = (char_u)(nr2hex((unsigned)c >> 4));
- buf[++i] = (char_u)(nr2hex((unsigned)c));
- buf[++i] = '>';
- buf[++i] = NUL;
+ if (c > 255 * 256) {
+ buf[i++] = (char)nr2hex((unsigned)c >> 20);
+ buf[i++] = (char)nr2hex((unsigned)c >> 16);
+ }
+ buf[i++] = (char)nr2hex((unsigned)c >> 12);
+ buf[i++] = (char)nr2hex((unsigned)c >> 8);
+ }
+ buf[i++] = (char)(nr2hex((unsigned)c >> 4));
+ buf[i++] = (char)(nr2hex((unsigned)c));
+ buf[i++] = '>';
+ buf[i] = NUL;
+ return i;
}
-/// Convert the lower 4 bits of byte "c" to its hex character.
+/// Convert the lower 4 bits of byte "c" to its hex character
+///
/// Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
/// function key 1.
///
-/// @param c
+/// @param[in] n Number to convert.
///
/// @return the hex character.
-static unsigned nr2hex(unsigned c)
+static inline unsigned nr2hex(unsigned n)
+ FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
- if ((c & 0xf) <= 9) {
- return (c & 0xf) + '0';
+ if ((n & 0xf) <= 9) {
+ return (n & 0xf) + '0';
}
- return (c & 0xf) - 10 + 'a';
+ return (n & 0xf) - 10 + 'a';
}
/// Return number of display cells occupied by byte "b".
@@ -622,18 +652,18 @@ static unsigned nr2hex(unsigned c)
/// Caller must make sure 0 <= b <= 255.
/// For multi-byte mode "b" must be the first byte of a character.
/// A TAB is counted as two cells: "^I".
-/// For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of
-/// cells depends on further bytes.
+/// This will return 0 for bytes >= 0x80, because the number of
+/// cells depends on further bytes in UTF-8.
///
/// @param b
///
/// @reeturn Number of display cells.
int byte2cells(int b)
{
- if (enc_utf8 && (b >= 0x80)) {
+ if (b >= 0x80) {
return 0;
}
- return chartab[b] & CT_CELL_MASK;
+ return g_chartab[b] & CT_CELL_MASK;
}
/// Return number of display cells occupied by character "c".
@@ -652,20 +682,9 @@ int char2cells(int c)
if (c >= 0x80) {
// UTF-8: above 0x80 need to check the value
- if (enc_utf8) {
- return utf_char2cells(c);
- }
-
- // DBCS: double-byte means double-width, except for euc-jp with first
- // byte 0x8e
- if ((enc_dbcs != 0) && (c >= 0x100)) {
- if ((enc_dbcs == DBCS_JPNU) && (((unsigned)c >> 8) == 0x8e)) {
- return 1;
- }
- return 2;
- }
+ return utf_char2cells(c);
}
- return chartab[c & 0xff] & CT_CELL_MASK;
+ return g_chartab[c & 0xff] & CT_CELL_MASK;
}
/// Return number of display cells occupied by character at "*p".
@@ -674,15 +693,15 @@ int char2cells(int c)
/// @param p
///
/// @return number of display cells.
-int ptr2cells(char_u *p)
+int ptr2cells(const char_u *p)
{
// For UTF-8 we need to look at more bytes if the first byte is >= 0x80.
- if (enc_utf8 && (*p >= 0x80)) {
+ if (*p >= 0x80) {
return utf_ptr2cells(p);
}
// For DBCS we can tell the cell count from the first byte.
- return chartab[*p] & CT_CELL_MASK;
+ return g_chartab[*p] & CT_CELL_MASK;
}
/// Return the number of character cells string "s" will take on the screen,
@@ -712,14 +731,10 @@ int vim_strnsize(char_u *s, int len)
assert(s != NULL);
int size = 0;
while (*s != NUL && --len >= 0) {
- if (has_mbyte) {
- int l = (*mb_ptr2len)(s);
- size += ptr2cells(s);
- s += l;
- len -= l - 1;
- } else {
- size += byte2cells(*s++);
- }
+ int l = (*mb_ptr2len)(s);
+ size += ptr2cells(s);
+ s += l;
+ len -= l - 1;
}
return size;
}
@@ -792,7 +807,7 @@ unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len)
for (char_u *s = line;
*s != NUL && (len == MAXCOL || s < line + len);
- mb_ptr_adv(s)) {
+ MB_PTR_ADV(s)) {
col += win_lbr_chartabsize(wp, line, s, col, NULL);
}
@@ -806,39 +821,44 @@ unsigned int win_linetabsize(win_T *wp, char_u *line, colnr_T len)
bool vim_isIDc(int c)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR);
+ return c > 0 && c < 0x100 && (g_chartab[c] & CT_ID_CHAR);
}
/// Check that "c" is a keyword character:
-/// Letters and characters from 'iskeyword' option for current buffer.
+/// Letters and characters from 'iskeyword' option for the current buffer.
/// For multi-byte characters mb_get_class() is used (builtin rules).
///
/// @param c character to check
-bool vim_iswordc(int c)
+bool vim_iswordc(const int c)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
return vim_iswordc_buf(c, curbuf);
}
+/// Check that "c" is a keyword character
+/// Letters and characters from 'iskeyword' option for given buffer.
+/// For multi-byte characters mb_get_class() is used (builtin rules).
+///
+/// @param[in] c Character to check.
+/// @param[in] chartab Buffer chartab.
+bool vim_iswordc_tab(const int c, const uint64_t *const chartab)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ return (c >= 0x100
+ ? (utf_class_tab(c, chartab) >= 2)
+ : (c > 0 && GET_CHARTAB_TAB(chartab, c) != 0));
+}
+
/// Check that "c" is a keyword character:
/// Letters and characters from 'iskeyword' option for given buffer.
/// For multi-byte characters mb_get_class() is used (builtin rules).
///
/// @param c character to check
/// @param buf buffer whose keywords to use
-bool vim_iswordc_buf(int c, buf_T *buf)
+bool vim_iswordc_buf(const int c, buf_T *const buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(2)
{
- if (c >= 0x100) {
- if (enc_dbcs != 0) {
- return dbcs_class((unsigned)c >> 8, (unsigned)(c & 0xff)) >= 2;
- }
-
- if (enc_utf8) {
- return utf_class(c) >= 2;
- }
- }
- return c > 0 && c < 0x100 && GET_CHARTAB(buf, c) != 0;
+ return vim_iswordc_tab(c, buf->b_chartab);
}
/// Just like vim_iswordc() but uses a pointer to the (multi-byte) character.
@@ -846,13 +866,10 @@ bool vim_iswordc_buf(int c, buf_T *buf)
/// @param p pointer to the multi-byte character
///
/// @return true if "p" points to a keyword character.
-bool vim_iswordp(char_u *p)
+bool vim_iswordp(const char_u *const p)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- if (has_mbyte && (MB_BYTE2LEN(*p) > 1)) {
- return mb_get_class(p) >= 2;
- }
- return GET_CHARTAB(curbuf, *p) != 0;
+ return vim_iswordp_buf(p, curbuf);
}
/// Just like vim_iswordc_buf() but uses a pointer to the (multi-byte)
@@ -862,13 +879,15 @@ bool vim_iswordp(char_u *p)
/// @param buf buffer whose keywords to use
///
/// @return true if "p" points to a keyword character.
-bool vim_iswordp_buf(char_u *p, buf_T *buf)
+bool vim_iswordp_buf(const char_u *const p, buf_T *const buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- if (has_mbyte && (MB_BYTE2LEN(*p) > 1)) {
- return mb_get_class(p) >= 2;
+ int c = *p;
+
+ if (MB_BYTE2LEN(c) > 1) {
+ c = utf_ptr2char(p);
}
- return GET_CHARTAB(buf, *p) != 0;
+ return vim_iswordc_buf(c, buf);
}
/// Check that "c" is a valid file-name character.
@@ -878,7 +897,7 @@ bool vim_iswordp_buf(char_u *p, buf_T *buf)
bool vim_isfilec(int c)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR));
+ return c >= 0x100 || (c > 0 && (g_chartab[c] & CT_FNAME_CHAR));
}
/// Check that "c" is a valid file-name character or a wildcard character
@@ -903,10 +922,10 @@ bool vim_isfilec_or_wc(int c)
bool vim_isprintc(int c)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (enc_utf8 && (c >= 0x100)) {
+ if (c >= 0x100) {
return utf_printable(c);
}
- return c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR));
+ return c > 0 && (g_chartab[c] & CT_PRINT_CHAR);
}
/// Strict version of vim_isprintc(c), don't return true if "c" is the head
@@ -918,14 +937,10 @@ bool vim_isprintc(int c)
bool vim_isprintc_strict(int c)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- if ((enc_dbcs != 0) && (c < 0x100) && (MB_BYTE2LEN(c) > 1)) {
- return false;
- }
-
- if (enc_utf8 && (c >= 0x100)) {
+ if (c >= 0x100) {
return utf_printable(c);
}
- return c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR));
+ return c > 0 && (g_chartab[c] & CT_PRINT_CHAR);
}
/// like chartabsize(), but also check for line breaks on the screen
@@ -958,7 +973,7 @@ int lbr_chartabsize_adv(char_u *line, char_u **s, colnr_T col)
int retval;
retval = lbr_chartabsize(line, *s, col);
- mb_ptr_adv(*s);
+ MB_PTR_ADV(*s);
return retval;
}
@@ -1005,14 +1020,14 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
// needs a break here
if (wp->w_p_lbr
&& vim_isbreak(c)
- && !vim_isbreak(s[1])
+ && !vim_isbreak((int)s[1])
&& wp->w_p_wrap
- && (wp->w_width != 0)) {
+ && (wp->w_grid.Columns != 0)) {
// Count all characters from first non-blank after a blank up to next
// non-blank after a blank.
numberextra = win_col_off(wp);
col2 = col;
- colmax = (colnr_T)(wp->w_width - numberextra - col_adj);
+ colmax = (colnr_T)(wp->w_grid.Columns - numberextra - col_adj);
if (col >= colmax) {
colmax += col_adj;
@@ -1025,13 +1040,11 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
for (;;) {
ps = s;
- mb_ptr_adv(s);
+ MB_PTR_ADV(s);
c = *s;
- if (!((c != NUL)
- && (vim_isbreak(c)
- || (!vim_isbreak(c)
- && ((col2 == col) || !vim_isbreak(*ps)))))) {
+ if (!(c != NUL
+ && (vim_isbreak(c) || col2 == col || !vim_isbreak((int)(*ps))))) {
break;
}
@@ -1042,8 +1055,7 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
break;
}
}
- } else if (has_mbyte
- && (size == 2)
+ } else if ((size == 2)
&& (MB_BYTE2LEN(*s) > 1)
&& wp->w_p_wrap
&& in_win_border(wp, col)) {
@@ -1064,9 +1076,9 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
numberextra = numberwidth;
col += numberextra + mb_added;
- if (col >= (colnr_T)wp->w_width) {
- col -= wp->w_width;
- numberextra = wp->w_width - (numberextra - win_col_off2(wp));
+ if (col >= (colnr_T)wp->w_grid.Columns) {
+ col -= wp->w_grid.Columns;
+ numberextra = wp->w_grid.Columns - (numberextra - win_col_off2(wp));
if (col >= numberextra && numberextra > 0) {
col %= numberextra;
}
@@ -1085,16 +1097,17 @@ int win_lbr_chartabsize(win_T *wp, char_u *line, char_u *s, colnr_T col, int *he
numberwidth -= win_col_off2(wp);
}
- if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_width)) {
+ if (col == 0 || (col + size + sbrlen > (colnr_T)wp->w_grid.Columns)) {
added = 0;
if (*p_sbr != NUL) {
- if (size + sbrlen + numberwidth > (colnr_T)wp->w_width) {
+ if (size + sbrlen + numberwidth > (colnr_T)wp->w_grid.Columns) {
// Calculate effective window width.
- int width = (colnr_T)wp->w_width - sbrlen - numberwidth;
- int prev_width = col ? ((colnr_T)wp->w_width - (sbrlen + col)) : 0;
+ int width = (colnr_T)wp->w_grid.Columns - sbrlen - numberwidth;
+ int prev_width = col ? ((colnr_T)wp->w_grid.Columns - (sbrlen + col))
+ : 0;
if (width == 0) {
- width = (colnr_T)wp->w_width;
+ width = (colnr_T)wp->w_grid.Columns;
}
added += ((size - prev_width) / width) * vim_strsize(p_sbr);
if ((size - prev_width) % width) {
@@ -1163,11 +1176,11 @@ bool in_win_border(win_T *wp, colnr_T vcol)
int width1; // width of first line (after line number)
int width2; // width of further lines
- if (wp->w_width == 0) {
+ if (wp->w_grid.Columns == 0) {
// there is no border
return false;
}
- width1 = wp->w_width - win_col_off(wp);
+ width1 = wp->w_grid.Columns - win_col_off(wp);
if ((int)vcol < width1 - 1) {
return false;
@@ -1215,7 +1228,13 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
// continue until the NUL
posptr = NULL;
} else {
+ // Special check for an empty line, which can happen on exit, when
+ // ml_get_buf() always returns an empty string.
+ if (*ptr == NUL) {
+ pos->col = 0;
+ }
posptr = ptr + pos->col;
+ posptr -= utf_head_off(line, posptr);
}
// This function is used very often, do some speed optimizations.
@@ -1241,27 +1260,23 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
if (c == TAB) {
incr = ts - (vcol % ts);
} else {
- if (has_mbyte) {
- // For utf-8, if the byte is >= 0x80, need to look at
- // further bytes to find the cell width.
- if (enc_utf8 && (c >= 0x80)) {
- incr = utf_ptr2cells(ptr);
- } else {
- incr = CHARSIZE(c);
- }
-
- // If a double-cell char doesn't fit at the end of a line
- // it wraps to the next line, it's like this char is three
- // cells wide.
- if ((incr == 2)
- && wp->w_p_wrap
- && (MB_BYTE2LEN(*ptr) > 1)
- && in_win_border(wp, vcol)) {
- ++incr;
- head = 1;
- }
+ // For utf-8, if the byte is >= 0x80, need to look at
+ // further bytes to find the cell width.
+ if (c >= 0x80) {
+ incr = utf_ptr2cells(ptr);
} else {
- incr = CHARSIZE(c);
+ incr = g_chartab[c] & CT_CELL_MASK;
+ }
+
+ // If a double-cell char doesn't fit at the end of a line
+ // it wraps to the next line, it's like this char is three
+ // cells wide.
+ if ((incr == 2)
+ && wp->w_p_wrap
+ && (MB_BYTE2LEN(*ptr) > 1)
+ && in_win_border(wp, vcol)) {
+ incr++;
+ head = 1;
}
}
@@ -1271,7 +1286,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
}
vcol += incr;
- mb_ptr_adv(ptr);
+ MB_PTR_ADV(ptr);
}
} else {
for (;;) {
@@ -1292,7 +1307,7 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
}
vcol += incr;
- mb_ptr_adv(ptr);
+ MB_PTR_ADV(ptr);
}
}
@@ -1330,7 +1345,11 @@ colnr_T getvcol_nolist(pos_T *posp)
colnr_T vcol;
curwin->w_p_list = false;
- getvcol(curwin, posp, NULL, &vcol, NULL);
+ if (posp->coladd) {
+ getvvcol(curwin, posp, NULL, &vcol, NULL);
+ } else {
+ getvcol(curwin, posp, NULL, &vcol, NULL);
+ }
curwin->w_p_list = list_save;
return vcol;
}
@@ -1361,7 +1380,7 @@ void getvvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor,
ptr = ml_get_buf(wp->w_buffer, pos->lnum, false);
if (pos->col < (colnr_T)STRLEN(ptr)) {
- int c = (*mb_ptr2char)(ptr + pos->col);
+ int c = utf_ptr2char(ptr + pos->col);
if ((c != TAB) && vim_isprintc(c)) {
endadd = (colnr_T)(char2cells(c) - 1);
if (coladd > endadd) {
@@ -1406,7 +1425,7 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left,
colnr_T to1;
colnr_T to2;
- if (ltp(pos1, pos2)) {
+ if (lt(*pos1, *pos2)) {
getvvcol(wp, pos1, &from1, NULL, &to1);
getvvcol(wp, pos2, &from2, NULL, &to2);
} else {
@@ -1433,32 +1452,47 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left,
/// skipwhite: skip over ' ' and '\t'.
///
-/// @param q
+/// @param[in] q String to skip in.
///
/// @return Pointer to character after the skipped whitespace.
-char_u* skipwhite(char_u *q)
+char_u *skipwhite(const char_u *q)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
{
- char_u *p = q;
+ const char_u *p = q;
while (ascii_iswhite(*p)) {
- // skip to next non-white
p++;
}
- return p;
+ return (char_u *)p;
+}
+
+// getwhitecols: return the number of whitespace
+// columns (bytes) at the start of a given line
+intptr_t getwhitecols_curline(void)
+{
+ return getwhitecols(get_cursor_line_ptr());
+}
+
+intptr_t getwhitecols(const char_u *p)
+{
+ return skipwhite(p) - p;
}
-/// skip over digits
+/// Skip over digits
///
-/// @param q
+/// @param[in] q String to skip digits in.
///
/// @return Pointer to the character after the skipped digits.
-char_u* skipdigits(char_u *q)
+char_u *skipdigits(const char_u *q)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_RET
{
- char_u *p = q;
+ const char_u *p = q;
while (ascii_isdigit(*p)) {
// skip to next non-digit
p++;
}
- return p;
+ return (char_u *)p;
}
/// skip over binary digits
@@ -1543,168 +1577,17 @@ char_u* skiptohex(char_u *q)
return p;
}
-// Vim's own character class functions. These exist because many library
-// islower()/toupper() etc. do not work properly: they crash when used with
-// invalid values or can't handle latin1 when the locale is C.
-// Speed is most important here.
-#define LATIN1LOWER 'l'
-#define LATIN1UPPER 'U'
-
-static char_u latin1flags[257] =
- " "
- " UUUUUUUUUUUUUUUUUUUUUUUUUU llllllllllllllllllllllllll "
- " "
- "UUUUUUUUUUUUUUUUUUUUUUU UUUUUUUllllllllllllllllllllllll llllllll";
-static char_u latin1upper[257] =
- " !\"#$%&'()*+,-./0123456789:;<=>"
- "?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~"
- "\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e"
- "\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e"
- "\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae"
- "\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe"
- "\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce"
- "\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde"
- "\xdf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce"
- "\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xf7\xd8\xd9\xda\xdb\xdc\xdd\xde\xff";
-static char_u latin1lower[257] =
- " !\"#$%&'()*+,-./0123456789:;<=>"
- "?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
- "\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e"
- "\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e"
- "\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae"
- "\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe"
- "\xbf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"
- "\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xd7\xf8\xf9\xfa\xfb\xfc\xfd\xfe"
- "\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee"
- "\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
-
-/// Check that the character is lower-case
-///
-/// @param c character to check
-bool vim_islower(int c)
- FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (c <= '@') {
- return false;
- }
-
- if (c >= 0x80) {
- if (enc_utf8) {
- return utf_islower(c);
- }
-
- if (c >= 0x100) {
- if (has_mbyte) {
- return iswlower((wint_t)c);
- }
-
- // islower() can't handle these chars and may crash
- return false;
- }
-
- if (enc_latin1like) {
- return (latin1flags[c] & LATIN1LOWER) == LATIN1LOWER;
- }
- }
- return islower(c);
-}
-
-/// Check that the character is upper-case
-///
-/// @param c character to check
-bool vim_isupper(int c)
- FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (c <= '@') {
- return false;
- }
-
- if (c >= 0x80) {
- if (enc_utf8) {
- return utf_isupper(c);
- }
-
- if (c >= 0x100) {
- if (has_mbyte) {
- return iswupper((wint_t)c);
- }
-
- // isupper() can't handle these chars and may crash
- return false;
- }
-
- if (enc_latin1like) {
- return (latin1flags[c] & LATIN1UPPER) == LATIN1UPPER;
- }
- }
- return isupper(c);
-}
-
-int vim_toupper(int c)
-{
- if (c <= '@') {
- return c;
- }
-
- if (c >= 0x80) {
- if (enc_utf8) {
- return utf_toupper(c);
- }
-
- if (c >= 0x100) {
- if (has_mbyte) {
- return (int)towupper((wint_t)c);
- }
-
- // toupper() can't handle these chars and may crash
- return c;
- }
-
- if (enc_latin1like) {
- return latin1upper[c];
- }
- }
- return TOUPPER_LOC(c);
-}
-
-int vim_tolower(int c)
-{
- if (c <= '@') {
- return c;
- }
-
- if (c >= 0x80) {
- if (enc_utf8) {
- return utf_tolower(c);
- }
-
- if (c >= 0x100) {
- if (has_mbyte) {
- return (int)towlower((wint_t)c);
- }
-
- // tolower() can't handle these chars and may crash
- return c;
- }
-
- if (enc_latin1like) {
- return latin1lower[c];
- }
- }
- return TOLOWER_LOC(c);
-}
-
-/// skiptowhite: skip over text until ' ' or '\t' or NUL.
+/// Skip over text until ' ' or '\t' or NUL
///
-/// @param p
+/// @param[in] p Text to skip over.
///
/// @return Pointer to the next whitespace or NUL character.
-char_u* skiptowhite(char_u *p)
+char_u *skiptowhite(const char_u *p)
{
while (*p != ' ' && *p != '\t' && *p != NUL) {
p++;
}
- return p;
+ return (char_u *)p;
}
/// skiptowhite_esc: Like skiptowhite(), but also skip escaped chars
@@ -1722,6 +1605,26 @@ char_u* skiptowhite_esc(char_u *p) {
return p;
}
+/// Get a number from a string and skip over it, signalling overflows
+///
+/// @param[out] pp A pointer to a pointer to char_u.
+/// It will be advanced past the read number.
+/// @param[out] nr Number read from the string.
+///
+/// @return OK on success, FAIL on error/overflow
+int getdigits_safe(char_u **pp, intmax_t *nr)
+{
+ errno = 0;
+ *nr = strtoimax((char *)(*pp), (char **)pp, 10);
+
+ if ((*nr == INTMAX_MIN || *nr == INTMAX_MAX)
+ && errno == ERANGE) {
+ return FAIL;
+ }
+
+ return OK;
+}
+
/// Get a number from a string and skip over it.
///
/// @param[out] pp A pointer to a pointer to char_u.
@@ -1730,14 +1633,16 @@ char_u* skiptowhite_esc(char_u *p) {
/// @return Number read from the string.
intmax_t getdigits(char_u **pp)
{
- intmax_t number = strtoimax((char *)*pp, (char **)pp, 10);
- assert(errno != ERANGE);
+ intmax_t number;
+ int ret = getdigits_safe(pp, &number);
+
+ (void)ret; // Avoid "unused variable" warning in Release build
+ assert(ret == OK);
+
return number;
}
-/// Get an int number from a string.
-///
-/// A getdigits wrapper restricted to int values.
+/// Get an int number from a string. Like getdigits(), but restricted to `int`.
int getdigits_int(char_u **pp)
{
intmax_t number = getdigits(pp);
@@ -1747,9 +1652,7 @@ int getdigits_int(char_u **pp)
return (int)number;
}
-/// Get a long number from a string.
-///
-/// A getdigits wrapper restricted to long values.
+/// Get a long number from a string. Like getdigits(), but restricted to `long`.
long getdigits_long(char_u **pp)
{
intmax_t number = getdigits(pp);
@@ -1787,135 +1690,156 @@ bool vim_isblankline(char_u *lbuf)
/// If maxlen > 0, check at a maximum maxlen chars.
///
/// @param start
-/// @param prep Returns type of number 0 = decimal, 'x' or 'X' is hex,
-/// '0' = octal, 'b' or 'B' is bin
+/// @param prep Returns guessed type of number 0 = decimal, 'x' or 'X' is
+/// hexadecimal, '0' = octal, 'b' or 'B' is binary. When using
+/// STR2NR_FORCE is always zero.
/// @param len Returns the detected length of number.
-/// @param what Recognizes what number passed.
+/// @param what Recognizes what number passed, @see ChStr2NrFlags.
/// @param nptr Returns the signed result.
/// @param unptr Returns the unsigned result.
/// @param maxlen Max length of string to check.
void vim_str2nr(const char_u *const start, int *const prep, int *const len,
- const int what, long *const nptr, unsigned long *const unptr,
- const int maxlen)
+ const int what, varnumber_T *const nptr,
+ uvarnumber_T *const unptr, const int maxlen)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- const char_u *ptr = start;
+ const char *ptr = (const char *)start;
+#define STRING_ENDED(ptr) \
+ (!(maxlen == 0 || (int)((ptr) - (const char *)start) < maxlen))
int pre = 0; // default is decimal
- bool negative = false;
- unsigned long un = 0;
+ const bool negative = (ptr[0] == '-');
+ uvarnumber_T un = 0;
- if (ptr[0] == '-') {
- negative = true;
+ if (negative) {
ptr++;
}
- // Recognize hex, octal and bin.
- if ((ptr[0] == '0') && (ptr[1] != '8') && (ptr[1] != '9')
- && (maxlen == 0 || maxlen > 1)) {
- pre = ptr[1];
-
- if ((what & STR2NR_HEX)
- && ((pre == 'X') || (pre == 'x'))
- && ascii_isxdigit(ptr[2])
- && (maxlen == 0 || maxlen > 2)) {
- // hexadecimal
- ptr += 2;
- } else if ((what & STR2NR_BIN)
- && ((pre == 'B') || (pre == 'b'))
- && ascii_isbdigit(ptr[2])
- && (maxlen == 0 || maxlen > 2)) {
- // binary
- ptr += 2;
- } else {
- // decimal or octal, default is decimal
- pre = 0;
-
- if (what & STR2NR_OCT) {
- // Don't interpret "0", "08" or "0129" as octal.
- for (int n = 1; ascii_isdigit(ptr[n]); ++n) {
- if (ptr[n] > '7') {
- // can't be octal
- pre = 0;
- break;
- }
- if (ptr[n] >= '0') {
- // assume octal
- pre = '0';
- }
- if (n == maxlen) {
- break;
- }
+ if (what & STR2NR_FORCE) {
+ // When forcing main consideration is skipping the prefix. Octal and decimal
+ // numbers have no prefixes to skip. pre is not set.
+ switch ((unsigned)what & (~(unsigned)STR2NR_FORCE)) {
+ case STR2NR_HEX: {
+ if (!STRING_ENDED(ptr + 2)
+ && ptr[0] == '0'
+ && (ptr[1] == 'x' || ptr[1] == 'X')
+ && ascii_isxdigit(ptr[2])) {
+ ptr += 2;
}
+ goto vim_str2nr_hex;
}
- }
- }
-
- // Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
- int n = 1;
- if ((pre == 'B') || (pre == 'b') || what == STR2NR_BIN + STR2NR_FORCE) {
- // bin
- if (pre != 0) {
- n += 2; // skip over "0b"
- }
- while ('0' <= *ptr && *ptr <= '1') {
- un = 2 * un + (unsigned long)(*ptr - '0');
- ptr++;
- if (n++ == maxlen) {
- break;
+ case STR2NR_BIN: {
+ if (!STRING_ENDED(ptr + 2)
+ && ptr[0] == '0'
+ && (ptr[1] == 'b' || ptr[1] == 'B')
+ && ascii_isbdigit(ptr[2])) {
+ ptr += 2;
+ }
+ goto vim_str2nr_bin;
}
- }
- } else if ((pre == '0') || what == STR2NR_OCT + STR2NR_FORCE) {
- // octal
- while ('0' <= *ptr && *ptr <= '7') {
- un = 8 * un + (unsigned long)(*ptr - '0');
- ptr++;
- if (n++ == maxlen) {
- break;
+ case STR2NR_OCT: {
+ goto vim_str2nr_oct;
+ }
+ case 0: {
+ goto vim_str2nr_dec;
+ }
+ default: {
+ assert(false);
}
}
- } else if ((pre == 'X') || (pre == 'x')
- || what == STR2NR_HEX + STR2NR_FORCE) {
- // hex
- if (pre != 0) {
- n += 2; // skip over "0x"
+ } else if ((what & (STR2NR_HEX|STR2NR_OCT|STR2NR_BIN))
+ && !STRING_ENDED(ptr + 1)
+ && ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9') {
+ pre = ptr[1];
+ // Detect hexadecimal: 0x or 0X followed by hex digit.
+ if ((what & STR2NR_HEX)
+ && !STRING_ENDED(ptr + 2)
+ && (pre == 'X' || pre == 'x')
+ && ascii_isxdigit(ptr[2])) {
+ ptr += 2;
+ goto vim_str2nr_hex;
}
- while (ascii_isxdigit(*ptr)) {
- un = 16 * un + (unsigned long)hex2nr(*ptr);
- ptr++;
- if (n++ == maxlen) {
- break;
- }
+ // Detect binary: 0b or 0B followed by 0 or 1.
+ if ((what & STR2NR_BIN)
+ && !STRING_ENDED(ptr + 2)
+ && (pre == 'B' || pre == 'b')
+ && ascii_isbdigit(ptr[2])) {
+ ptr += 2;
+ goto vim_str2nr_bin;
}
- } else {
- // decimal
- while (ascii_isdigit(*ptr)) {
- un = 10 * un + (unsigned long)(*ptr - '0');
- ptr++;
- if (n++ == maxlen) {
- break;
+ // Detect octal number: zero followed by octal digits without '8' or '9'.
+ pre = 0;
+ if (!(what & STR2NR_OCT)
+ || !('0' <= ptr[1] && ptr[1] <= '7')) {
+ goto vim_str2nr_dec;
+ }
+ for (int i = 2; !STRING_ENDED(ptr + i) && ascii_isdigit(ptr[i]); i++) {
+ if (ptr[i] > '7') {
+ goto vim_str2nr_dec;
}
}
+ pre = '0';
+ goto vim_str2nr_oct;
+ } else {
+ goto vim_str2nr_dec;
}
+ // Do the string-to-numeric conversion "manually" to avoid sscanf quirks.
+ assert(false); // Should’ve used goto earlier.
+#define PARSE_NUMBER(base, cond, conv) \
+ do { \
+ while (!STRING_ENDED(ptr) && (cond)) { \
+ /* avoid ubsan error for overflow */ \
+ if (un < UVARNUMBER_MAX / base) { \
+ un = base * un + (uvarnumber_T)(conv); \
+ } else { \
+ un = UVARNUMBER_MAX; \
+ } \
+ ptr++; \
+ } \
+ } while (0)
+vim_str2nr_bin:
+ PARSE_NUMBER(2, (*ptr == '0' || *ptr == '1'), (*ptr - '0'));
+ goto vim_str2nr_proceed;
+vim_str2nr_oct:
+ PARSE_NUMBER(8, ('0' <= *ptr && *ptr <= '7'), (*ptr - '0'));
+ goto vim_str2nr_proceed;
+vim_str2nr_dec:
+ PARSE_NUMBER(10, (ascii_isdigit(*ptr)), (*ptr - '0'));
+ goto vim_str2nr_proceed;
+vim_str2nr_hex:
+ PARSE_NUMBER(16, (ascii_isxdigit(*ptr)), (hex2nr(*ptr)));
+ goto vim_str2nr_proceed;
+#undef PARSE_NUMBER
+
+vim_str2nr_proceed:
if (prep != NULL) {
*prep = pre;
}
if (len != NULL) {
- *len = (int)(ptr - start);
+ *len = (int)(ptr - (const char *)start);
}
if (nptr != NULL) {
- if (negative) {
- // account for leading '-' for decimal numbers
- *nptr = -(long)un;
+ if (negative) { // account for leading '-' for decimal numbers
+ // avoid ubsan error for overflow
+ if (un > VARNUMBER_MAX) {
+ *nptr = VARNUMBER_MIN;
+ } else {
+ *nptr = -(varnumber_T)un;
+ }
} else {
- *nptr = (long)un;
+ if (un > VARNUMBER_MAX) {
+ un = VARNUMBER_MAX;
+ }
+ *nptr = (varnumber_T)un;
}
}
if (unptr != NULL) {
*unptr = un;
}
+#undef STRING_ENDED
}
/// Return the value of a single hex character.
diff --git a/src/nvim/charset.h b/src/nvim/charset.h
index 995ad123ae..e657ce19b6 100644
--- a/src/nvim/charset.h
+++ b/src/nvim/charset.h
@@ -1,15 +1,49 @@
#ifndef NVIM_CHARSET_H
#define NVIM_CHARSET_H
-/*
- * Flags for chartab[].
- */
-#define CT_CELL_MASK 0x07 /* mask: nr of display cells (1, 2 or 4) */
-#define CT_PRINT_CHAR 0x10 /* flag: set for printable chars */
-#define CT_ID_CHAR 0x20 /* flag: set for ID chars */
-#define CT_FNAME_CHAR 0x40 /* flag: set for file name chars */
+#include "nvim/types.h"
+#include "nvim/pos.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/eval/typval.h"
+#include "nvim/option_defs.h"
+
+/// Return the folded-case equivalent of the given character
+///
+/// @param[in] c Character to transform.
+///
+/// @return Folded variant.
+#define CH_FOLD(c) \
+ utf_fold((sizeof(c) == sizeof(char)) \
+ ?((int)(uint8_t)(c)) \
+ :((int)(c)))
+
+/// Flags for vim_str2nr()
+typedef enum {
+ STR2NR_DEC = 0,
+ STR2NR_BIN = (1 << 0), ///< Allow binary numbers.
+ STR2NR_OCT = (1 << 1), ///< Allow octal numbers.
+ STR2NR_HEX = (1 << 2), ///< Allow hexadecimal numbers.
+ /// Force one of the above variants.
+ ///
+ /// STR2NR_FORCE|STR2NR_DEC is actually not different from supplying zero
+ /// as flags, but still present for completeness.
+ STR2NR_FORCE = (1 << 3),
+ /// Recognize all formats vim_str2nr() can recognize.
+ STR2NR_ALL = STR2NR_BIN | STR2NR_OCT | STR2NR_HEX,
+} ChStr2NrFlags;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "charset.h.generated.h"
#endif
+
+static inline bool vim_isbreak(int c)
+ REAL_FATTR_CONST
+ REAL_FATTR_ALWAYS_INLINE;
+
+/// Check if `c` is one of the characters in 'breakat'.
+/// Used very often if 'linebreak' is set
+static inline bool vim_isbreak(int c)
+{
+ return breakat_flags[(char_u)c];
+}
#endif // NVIM_CHARSET_H
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index afaa6022c9..6c1bd01ff5 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -1,6 +1,10 @@
+// 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 <stdbool.h>
#include <inttypes.h>
+#include "nvim/assert.h"
#include "nvim/cursor.h"
#include "nvim/charset.h"
#include "nvim/fold.h"
@@ -9,8 +13,10 @@
#include "nvim/misc1.h"
#include "nvim/move.h"
#include "nvim/screen.h"
+#include "nvim/state.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/mark.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor.c.generated.h"
@@ -115,11 +121,11 @@ static int coladvance2(
--curwin->w_curswant;
}
} else {
- int width = curwin->w_width - win_col_off(curwin);
+ int width = curwin->w_grid.Columns - win_col_off(curwin);
if (finetune
&& curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
&& wcol >= (colnr_T)width) {
csize = linetabsize(line);
if (csize > 0)
@@ -139,7 +145,7 @@ static int coladvance2(
while (col <= wcol && *ptr != NUL) {
/* Count a tab for what it's worth (if list mode not on) */
csize = win_lbr_chartabsize(curwin, line, ptr, col, &head);
- mb_ptr_adv(ptr);
+ MB_PTR_ADV(ptr);
col += csize;
}
idx = (int)(ptr - line);
@@ -165,7 +171,9 @@ static int coladvance2(
if (line[idx] == NUL) {
/* Append spaces */
int correct = wcol - col;
- char_u *newline = xmallocz((size_t)(idx + correct));
+ size_t newline_size;
+ STRICT_ADD(idx, correct, &newline_size, size_t);
+ char_u *newline = xmallocz(newline_size);
memcpy(newline, line, (size_t)idx);
memset(newline + idx, ' ', (size_t)correct);
@@ -182,14 +190,17 @@ static int coladvance2(
if (-correct > csize)
return FAIL;
- newline = xmallocz((size_t)(linelen - 1 + csize));
+ size_t n;
+ STRICT_ADD(linelen - 1, csize, &n, size_t);
+ newline = xmallocz(n);
// Copy first idx chars
memcpy(newline, line, (size_t)idx);
// Replace idx'th char with csize spaces
memset(newline + idx, ' ', (size_t)csize);
// Copy the rest of the line
- memcpy(newline + idx + csize, line + idx + 1,
- (size_t)(linelen - idx - 1));
+ STRICT_SUB(linelen, idx, &n, size_t);
+ STRICT_SUB(n, 1, &n, size_t);
+ memcpy(newline + idx + csize, line + idx + 1, n);
ml_replace(pos->lnum, newline, false);
changed_bytes(pos->lnum, idx);
@@ -218,17 +229,19 @@ static int coladvance2(
} else {
int b = (int)wcol - (int)col;
- /* The difference between wcol and col is used to set coladd. */
- if (b > 0 && b < (MAXCOL - 2 * curwin->w_width))
+ // The difference between wcol and col is used to set coladd.
+ if (b > 0 && b < (MAXCOL - 2 * curwin->w_grid.Columns)) {
pos->coladd = b;
+ }
col += b;
}
}
- /* prevent from moving onto a trail byte */
- if (has_mbyte)
- mb_adjustpos(curbuf, pos);
+ // Prevent from moving onto a trail byte.
+ if (has_mbyte) {
+ mark_mb_adjustpos(curbuf, pos);
+ }
if (col < wcol)
return FAIL;
@@ -293,6 +306,26 @@ linenr_T get_cursor_rel_lnum(win_T *wp, linenr_T lnum)
return (lnum < cursor) ? -retval : retval;
}
+// Make sure "pos.lnum" and "pos.col" are valid in "buf".
+// This allows for the col to be on the NUL byte.
+void check_pos(buf_T *buf, pos_T *pos)
+{
+ char_u *line;
+ colnr_T len;
+
+ if (pos->lnum > buf->b_ml.ml_line_count) {
+ pos->lnum = buf->b_ml.ml_line_count;
+ }
+
+ if (pos->col > 0) {
+ line = ml_get_buf(buf, pos->lnum, false);
+ len = (colnr_T)STRLEN(line);
+ if (pos->col > len) {
+ pos->col = len;
+ }
+ }
+}
+
/*
* Make sure curwin->w_cursor.lnum is valid.
*/
@@ -317,9 +350,8 @@ void check_cursor_col(void)
check_cursor_col_win(curwin);
}
-/*
- * Make sure win->w_cursor.col is valid.
- */
+/// Make sure win->w_cursor.col is valid. Special handling of insert-mode.
+/// @see mb_check_adjust_col
void check_cursor_col_win(win_T *win)
{
colnr_T len;
@@ -341,25 +373,40 @@ void check_cursor_col_win(win_T *win)
win->w_cursor.col = len;
} else {
win->w_cursor.col = len - 1;
- /* Move the cursor to the head byte. */
- if (has_mbyte)
- mb_adjustpos(win->w_buffer, &win->w_cursor);
+ // Move the cursor to the head byte.
+ if (has_mbyte) {
+ mark_mb_adjustpos(win->w_buffer, &win->w_cursor);
+ }
}
} else if (win->w_cursor.col < 0) {
win->w_cursor.col = 0;
}
- /* If virtual editing is on, we can leave the cursor on the old position,
- * only we must set it to virtual. But don't do it when at the end of the
- * line. */
- if (oldcol == MAXCOL)
+ // If virtual editing is on, we can leave the cursor on the old position,
+ // only we must set it to virtual. But don't do it when at the end of the
+ // line.
+ if (oldcol == MAXCOL) {
win->w_cursor.coladd = 0;
- else if (ve_flags == VE_ALL) {
- if (oldcoladd > win->w_cursor.col)
+ } else if (ve_flags == VE_ALL) {
+ if (oldcoladd > win->w_cursor.col) {
win->w_cursor.coladd = oldcoladd - win->w_cursor.col;
- else
- /* avoid weird number when there is a miscalculation or overflow */
+
+ // Make sure that coladd is not more than the char width.
+ // Not for the last character, coladd is then used when the cursor
+ // is actually after the last character.
+ if (win->w_cursor.col + 1 < len) {
+ assert(win->w_cursor.coladd > 0);
+ int cs, ce;
+
+ getvcol(win, &win->w_cursor, &cs, NULL, &ce);
+ if (win->w_cursor.coladd > ce - cs) {
+ win->w_cursor.coladd = ce - cs;
+ }
+ }
+ } else {
+ // avoid weird number when there is a miscalculation or overflow
win->w_cursor.coladd = 0;
+ }
}
}
@@ -397,7 +444,7 @@ bool leftcol_changed(void)
bool retval = false;
changed_cline_bef_curs();
- lastcol = curwin->w_leftcol + curwin->w_width - curwin_col_off() - 1;
+ lastcol = curwin->w_leftcol + curwin->w_grid.Columns - curwin_col_off() - 1;
validate_virtcol();
/*
@@ -437,9 +484,7 @@ bool leftcol_changed(void)
int gchar_cursor(void)
{
- if (has_mbyte)
- return (*mb_ptr2char)(get_cursor_pos_ptr());
- return (int)*get_cursor_pos_ptr();
+ return utf_ptr2char(get_cursor_pos_ptr());
}
/*
@@ -468,4 +513,3 @@ char_u *get_cursor_pos_ptr(void)
return ml_get_buf(curbuf, curwin->w_cursor.lnum, false) +
curwin->w_cursor.col;
}
-
diff --git a/src/nvim/cursor.h b/src/nvim/cursor.h
index 09cc5a813c..1cbe8a609e 100644
--- a/src/nvim/cursor.h
+++ b/src/nvim/cursor.h
@@ -4,7 +4,6 @@
#include <stdbool.h>
#include "nvim/vim.h"
-#include "nvim/misc2.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor.h.generated.h"
diff --git a/src/nvim/cursor_shape.c b/src/nvim/cursor_shape.c
index 87425ca567..0377cb97e5 100644
--- a/src/nvim/cursor_shape.c
+++ b/src/nvim/cursor_shape.c
@@ -1,90 +1,132 @@
+// 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 <stdint.h>
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/cursor_shape.h"
-#include "nvim/misc2.h"
#include "nvim/ex_getln.h"
#include "nvim/charset.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/ui.h"
-/*
- * Handling of cursor and mouse pointer shapes in various modes.
- */
-
-static cursorentry_T shape_table[SHAPE_IDX_COUNT] =
+/// Handling of cursor and mouse pointer shapes in various modes.
+cursorentry_T shape_table[SHAPE_IDX_COUNT] =
{
- /* The values will be filled in from the 'guicursor' and 'mouseshape'
- * defaults when Vim starts.
- * Adjust the SHAPE_IDX_ defines when making changes! */
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "e", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "s", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "sd", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "vs", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "vd", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "m", SHAPE_MOUSE},
- {0, 0, 0, 0L, 0L, 0L, 0, 0, "ml", SHAPE_MOUSE},
- {0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR},
+ // Values are set by 'guicursor' and 'mouseshape'.
+ // Adjust the SHAPE_IDX_ defines when changing this!
+ { "normal", 0, 0, 0, 700L, 400L, 250L, 0, 0, "n", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "visual", 0, 0, 0, 700L, 400L, 250L, 0, 0, "v", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "insert", 0, 0, 0, 700L, 400L, 250L, 0, 0, "i", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "replace", 0, 0, 0, 700L, 400L, 250L, 0, 0, "r", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "cmdline_normal", 0, 0, 0, 700L, 400L, 250L, 0, 0, "c", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "cmdline_insert", 0, 0, 0, 700L, 400L, 250L, 0, 0, "ci", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "cmdline_replace", 0, 0, 0, 700L, 400L, 250L, 0, 0, "cr", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "operator", 0, 0, 0, 700L, 400L, 250L, 0, 0, "o", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "visual_select", 0, 0, 0, 700L, 400L, 250L, 0, 0, "ve", SHAPE_CURSOR+SHAPE_MOUSE },
+ { "cmdline_hover", 0, 0, 0, 0L, 0L, 0L, 0, 0, "e", SHAPE_MOUSE },
+ { "statusline_hover", 0, 0, 0, 0L, 0L, 0L, 0, 0, "s", SHAPE_MOUSE },
+ { "statusline_drag", 0, 0, 0, 0L, 0L, 0L, 0, 0, "sd", SHAPE_MOUSE },
+ { "vsep_hover", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vs", SHAPE_MOUSE },
+ { "vsep_drag", 0, 0, 0, 0L, 0L, 0L, 0, 0, "vd", SHAPE_MOUSE },
+ { "more", 0, 0, 0, 0L, 0L, 0L, 0, 0, "m", SHAPE_MOUSE },
+ { "more_lastline", 0, 0, 0, 0L, 0L, 0L, 0, 0, "ml", SHAPE_MOUSE },
+ { "showmatch", 0, 0, 0, 100L, 100L, 100L, 0, 0, "sm", SHAPE_CURSOR },
};
-/*
- * Parse the 'guicursor' option ("what" is SHAPE_CURSOR) or 'mouseshape'
- * ("what" is SHAPE_MOUSE).
- * Returns error message for an illegal option, NULL otherwise.
- */
+/// Converts cursor_shapes into an Array of Dictionaries
+/// @return Array of the form {[ "cursor_shape": ... ], ...}
+Array mode_style_array(void)
+{
+ Array all = ARRAY_DICT_INIT;
+
+ for (int i = 0; i < SHAPE_IDX_COUNT; i++) {
+ Dictionary dic = ARRAY_DICT_INIT;
+ cursorentry_T *cur = &shape_table[i];
+ if (cur->used_for & SHAPE_MOUSE) {
+ PUT(dic, "mouse_shape", INTEGER_OBJ(cur->mshape));
+ }
+ if (cur->used_for & SHAPE_CURSOR) {
+ String shape_str;
+ switch (cur->shape) {
+ case SHAPE_BLOCK: shape_str = cstr_to_string("block"); break;
+ case SHAPE_VER: shape_str = cstr_to_string("vertical"); break;
+ case SHAPE_HOR: shape_str = cstr_to_string("horizontal"); break;
+ default: shape_str = cstr_to_string("unknown");
+ }
+ PUT(dic, "cursor_shape", STRING_OBJ(shape_str));
+ PUT(dic, "cell_percentage", INTEGER_OBJ(cur->percentage));
+ PUT(dic, "blinkwait", INTEGER_OBJ(cur->blinkwait));
+ PUT(dic, "blinkon", INTEGER_OBJ(cur->blinkon));
+ PUT(dic, "blinkoff", INTEGER_OBJ(cur->blinkoff));
+ PUT(dic, "hl_id", INTEGER_OBJ(cur->id));
+ PUT(dic, "id_lm", INTEGER_OBJ(cur->id_lm));
+ PUT(dic, "attr_id", INTEGER_OBJ(cur->id ? syn_id2attr(cur->id) : 0));
+ PUT(dic, "attr_id_lm", INTEGER_OBJ(cur->id_lm ? syn_id2attr(cur->id_lm)
+ : 0));
+ }
+ PUT(dic, "name", STRING_OBJ(cstr_to_string(cur->full_name)));
+ PUT(dic, "short_name", STRING_OBJ(cstr_to_string(cur->name)));
+
+ ADD(all, DICTIONARY_OBJ(dic));
+ }
+
+ return all;
+}
+
+/// Parse the 'guicursor' option
+///
+/// @param what SHAPE_CURSOR or SHAPE_MOUSE ('mouseshape')
+///
+/// @returns error message for an illegal option, NULL otherwise.
char_u *parse_shape_opt(int what)
{
char_u *modep;
char_u *colonp;
char_u *commap;
char_u *slashp;
- char_u *p, *endp;
- int idx = 0; /* init for GCC */
+ char_u *p = NULL;
+ char_u *endp;
+ int idx = 0; // init for GCC
int all_idx;
int len;
int i;
- int found_ve = false; /* found "ve" flag */
+ int found_ve = false; // found "ve" flag
int round;
- /*
- * First round: check for errors; second round: do it for real.
- */
- for (round = 1; round <= 2; ++round) {
- /*
- * Repeat for all comma separated parts.
- */
+ // First round: check for errors; second round: do it for real.
+ for (round = 1; round <= 2; round++) {
+ // Repeat for all comma separated parts.
modep = p_guicursor;
+ if (*p_guicursor == NUL) {
+ modep = (char_u *)"a:block-blinkon0";
+ }
while (*modep != NUL) {
colonp = vim_strchr(modep, ':');
- if (colonp == NULL)
+ commap = vim_strchr(modep, ',');
+
+ if (colonp == NULL || (commap != NULL && commap < colonp)) {
return (char_u *)N_("E545: Missing colon");
- if (colonp == modep)
+ }
+ if (colonp == modep) {
return (char_u *)N_("E546: Illegal mode");
- commap = vim_strchr(modep, ',');
+ }
- /*
- * Repeat for all mode's before the colon.
- * For the 'a' mode, we loop to handle all the modes.
- */
+ // Repeat for all modes before the colon.
+ // For the 'a' mode, we loop to handle all the modes.
all_idx = -1;
assert(modep < colonp);
while (modep < colonp || all_idx >= 0) {
if (all_idx < 0) {
- /* Find the mode. */
- if (modep[1] == '-' || modep[1] == ':')
+ // Find the mode
+ if (modep[1] == '-' || modep[1] == ':') {
len = 1;
- else
+ } else {
len = 2;
+ }
if (len == 1 && TOLOWER_ASC(modep[0]) == 'a') {
all_idx = SHAPE_IDX_COUNT - 1;
@@ -101,15 +143,15 @@ char_u *parse_shape_opt(int what)
modep += len + 1;
}
- if (all_idx >= 0)
+ if (all_idx >= 0) {
idx = all_idx--;
- else if (round == 2) {
+ } else if (round == 2) {
{
- /* Set the defaults, for the missing parts */
+ // Set the defaults, for the missing parts
shape_table[idx].shape = SHAPE_BLOCK;
- shape_table[idx].blinkwait = 700L;
- shape_table[idx].blinkon = 400L;
- shape_table[idx].blinkoff = 250L;
+ shape_table[idx].blinkwait = 0L;
+ shape_table[idx].blinkon = 0L;
+ shape_table[idx].blinkoff = 0L;
}
}
@@ -209,6 +251,80 @@ char_u *parse_shape_opt(int what)
shape_table[SHAPE_IDX_VE].id_lm = shape_table[SHAPE_IDX_V].id_lm;
}
}
-
+ ui_mode_info_set();
return NULL;
}
+
+/// Returns true if the cursor is non-blinking "block" shape during
+/// visual selection.
+///
+/// @param exclusive If 'selection' option is "exclusive".
+bool cursor_is_block_during_visual(bool exclusive)
+{
+ int mode_idx = exclusive ? SHAPE_IDX_VE : SHAPE_IDX_V;
+ return (SHAPE_BLOCK == shape_table[mode_idx].shape
+ && 0 == shape_table[mode_idx].blinkon);
+}
+
+/// Map cursor mode from string to integer
+///
+/// @param mode Fullname of the mode whose id we are looking for
+/// @return -1 in case of failure, else the matching SHAPE_ID* integer
+int cursor_mode_str2int(const char *mode)
+{
+ for (int mode_idx = 0; mode_idx < SHAPE_IDX_COUNT; mode_idx++) {
+ if (strcmp(shape_table[mode_idx].full_name, mode) == 0) {
+ return mode_idx;
+ }
+ }
+ WLOG("Unknown mode %s", mode);
+ return -1;
+}
+
+/// Check if a syntax id is used as a cursor style.
+bool cursor_mode_uses_syn_id(int syn_id)
+{
+ if (*p_guicursor == NUL) {
+ return false;
+ }
+ for (int mode_idx = 0; mode_idx < SHAPE_IDX_COUNT; mode_idx++) {
+ if (shape_table[mode_idx].id == syn_id
+ || shape_table[mode_idx].id_lm == syn_id) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/// Return the index into shape_table[] for the current mode.
+int cursor_get_mode_idx(void)
+{
+ if (State == SHOWMATCH) {
+ return SHAPE_IDX_SM;
+ } else if (State & VREPLACE_FLAG) {
+ return SHAPE_IDX_R;
+ } else if (State & REPLACE_FLAG) {
+ return SHAPE_IDX_R;
+ } else if (State & INSERT) {
+ return SHAPE_IDX_I;
+ } else if (State & CMDLINE) {
+ if (cmdline_at_end()) {
+ return SHAPE_IDX_C;
+ } else if (cmdline_overstrike()) {
+ return SHAPE_IDX_CR;
+ } else {
+ return SHAPE_IDX_CI;
+ }
+ } else if (finish_op) {
+ return SHAPE_IDX_O;
+ } else if (VIsual_active) {
+ if (*p_sel == 'e') {
+ return SHAPE_IDX_VE;
+ } else {
+ return SHAPE_IDX_V;
+ }
+ } else {
+ return SHAPE_IDX_N;
+ }
+}
diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h
index 9ce1b6e0a0..2c466603f0 100644
--- a/src/nvim/cursor_shape.h
+++ b/src/nvim/cursor_shape.h
@@ -1,32 +1,37 @@
#ifndef NVIM_CURSOR_SHAPE_H
#define NVIM_CURSOR_SHAPE_H
-/*
- * struct to store values from 'guicursor' and 'mouseshape'
- */
-/* Indexes in shape_table[] */
-#define SHAPE_IDX_N 0 /* Normal mode */
-#define SHAPE_IDX_V 1 /* Visual mode */
-#define SHAPE_IDX_I 2 /* Insert mode */
-#define SHAPE_IDX_R 3 /* Replace mode */
-#define SHAPE_IDX_C 4 /* Command line Normal mode */
-#define SHAPE_IDX_CI 5 /* Command line Insert mode */
-#define SHAPE_IDX_CR 6 /* Command line Replace mode */
-#define SHAPE_IDX_O 7 /* Operator-pending mode */
-#define SHAPE_IDX_VE 8 /* Visual mode with 'selection' exclusive */
-#define SHAPE_IDX_CLINE 9 /* On command line */
-#define SHAPE_IDX_STATUS 10 /* A status line */
-#define SHAPE_IDX_SDRAG 11 /* dragging a status line */
-#define SHAPE_IDX_VSEP 12 /* A vertical separator line */
-#define SHAPE_IDX_VDRAG 13 /* dragging a vertical separator line */
-#define SHAPE_IDX_MORE 14 /* Hit-return or More */
-#define SHAPE_IDX_MOREL 15 /* Hit-return or More in last line */
-#define SHAPE_IDX_SM 16 /* showing matching paren */
-#define SHAPE_IDX_COUNT 17
-
-#define SHAPE_BLOCK 0 /* block cursor */
-#define SHAPE_HOR 1 /* horizontal bar cursor */
-#define SHAPE_VER 2 /* vertical bar cursor */
+#include "nvim/types.h"
+#include "nvim/api/private/defs.h"
+
+/// struct to store values from 'guicursor' and 'mouseshape'
+/// Indexes in shape_table[]
+typedef enum {
+SHAPE_IDX_N = 0, ///< Normal mode
+SHAPE_IDX_V = 1, ///< Visual mode
+SHAPE_IDX_I = 2, ///< Insert mode
+SHAPE_IDX_R = 3, ///< Replace mode
+SHAPE_IDX_C = 4, ///< Command line Normal mode
+SHAPE_IDX_CI = 5, ///< Command line Insert mode
+SHAPE_IDX_CR = 6, ///< Command line Replace mode
+SHAPE_IDX_O = 7, ///< Operator-pending mode
+SHAPE_IDX_VE = 8, ///< Visual mode with 'selection' exclusive
+SHAPE_IDX_CLINE = 9, ///< On command line
+SHAPE_IDX_STATUS = 10, ///< On status line
+SHAPE_IDX_SDRAG = 11, ///< dragging a status line
+SHAPE_IDX_VSEP = 12, ///< On vertical separator line
+SHAPE_IDX_VDRAG = 13, ///< dragging a vertical separator line
+SHAPE_IDX_MORE = 14, ///< Hit-return or More
+SHAPE_IDX_MOREL = 15, ///< Hit-return or More in last line
+SHAPE_IDX_SM = 16, ///< showing matching paren
+SHAPE_IDX_COUNT = 17
+} ModeShape;
+
+typedef enum {
+SHAPE_BLOCK = 0, ///< block cursor
+SHAPE_HOR = 1, ///< horizontal bar cursor
+SHAPE_VER = 2 ///< vertical bar cursor
+} CursorShape;
#define MSHAPE_NUMBERED 1000 /* offset for shapes identified by number */
#define MSHAPE_HIDE 1 /* hide mouse pointer */
@@ -35,18 +40,20 @@
#define SHAPE_CURSOR 2 /* used for text cursor shape */
typedef struct cursor_entry {
- int shape; /* one of the SHAPE_ defines */
- int mshape; /* one of the MSHAPE defines */
- int percentage; /* percentage of cell for bar */
- long blinkwait; /* blinking, wait time before blinking starts */
- long blinkon; /* blinking, on time */
- long blinkoff; /* blinking, off time */
- int id; /* highlight group ID */
- int id_lm; /* highlight group ID for :lmap mode */
- char *name; /* mode name (fixed) */
- char used_for; /* SHAPE_MOUSE and/or SHAPE_CURSOR */
+ char *full_name; ///< mode description
+ CursorShape shape; ///< cursor shape: one of the SHAPE_ defines
+ int mshape; ///< mouse shape: one of the MSHAPE defines
+ int percentage; ///< percentage of cell for bar
+ long blinkwait; ///< blinking, wait time before blinking starts
+ long blinkon; ///< blinking, on time
+ long blinkoff; ///< blinking, off time
+ int id; ///< highlight group ID
+ int id_lm; ///< highlight group ID for :lmap mode
+ char *name; ///< mode short name
+ char used_for; ///< SHAPE_MOUSE and/or SHAPE_CURSOR
} cursorentry_T;
+extern cursorentry_T shape_table[SHAPE_IDX_COUNT];
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "cursor_shape.h.generated.h"
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 4826e70727..866161e5cf 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1,11 +1,20 @@
+// 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
+
/// @file diff.c
///
/// Code for diff'ing two, three or four buffers.
+///
+/// There are three ways to diff:
+/// - Shell out to an external diff program, using files.
+/// - Use the compiled-in xdiff library.
+/// - Let 'diffexpr' do the work, using files.
#include <inttypes.h>
#include <stdbool.h>
#include "nvim/vim.h"
+#include "xdiff/xdiff.h"
#include "nvim/ascii.h"
#include "nvim/diff.h"
#include "nvim/buffer.h"
@@ -21,7 +30,6 @@
#include "nvim/memline.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/normal.h"
@@ -34,22 +42,50 @@
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
-static int diff_busy = FALSE; // ex_diffgetput() is busy
+static int diff_busy = false; // using diff structs, don't change them
+static int diff_need_update = false; // ex_diffupdate needs to be called
// Flags obtained from the 'diffopt' option
-#define DIFF_FILLER 1 // display filler lines
-#define DIFF_ICASE 2 // ignore case
-#define DIFF_IWHITE 4 // ignore change in white space
-#define DIFF_HORIZONTAL 8 // horizontal splits
-#define DIFF_VERTICAL 16 // vertical splits
-static int diff_flags = DIFF_FILLER;
+#define DIFF_FILLER 0x001 // display filler lines
+#define DIFF_IBLANK 0x002 // ignore empty lines
+#define DIFF_ICASE 0x004 // ignore case
+#define DIFF_IWHITE 0x008 // ignore change in white space
+#define DIFF_IWHITEALL 0x010 // ignore all white space changes
+#define DIFF_IWHITEEOL 0x020 // ignore change in white space at EOL
+#define DIFF_HORIZONTAL 0x040 // horizontal splits
+#define DIFF_VERTICAL 0x080 // vertical splits
+#define DIFF_HIDDEN_OFF 0x100 // diffoff when hidden
+#define DIFF_INTERNAL 0x200 // use internal xdiff algorithm
+#define ALL_WHITE_DIFF (DIFF_IWHITE | DIFF_IWHITEALL | DIFF_IWHITEEOL)
+static int diff_flags = DIFF_INTERNAL | DIFF_FILLER;
+
+static long diff_algorithm = 0;
#define LBUFLEN 50 // length of line in diff file
-// TRUE when "diff -a" works, FALSE when it doesn't work, MAYBE when not
-// checked yet
-static int diff_a_works = MAYBE;
-
+// kTrue when "diff -a" works, kFalse when it doesn't work,
+// kNone when not checked yet
+static TriState diff_a_works = kNone;
+
+// used for diff input
+typedef struct {
+ char_u *din_fname; // used for external diff
+ mmfile_t din_mmfile; // used for internal diff
+} diffin_T;
+
+// used for diff result
+typedef struct {
+ char_u *dout_fname; // used for external diff
+ garray_T dout_ga; // used for internal diff
+} diffout_T;
+
+// two diff inputs and one result
+typedef struct {
+ diffin_T dio_orig; // original file input
+ diffin_T dio_new; // new file input
+ diffout_T dio_diff; // diff result
+ int dio_internal; // using internal diff
+} diffio_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "diff.c.generated.h"
@@ -65,10 +101,10 @@ void diff_buf_delete(buf_T *buf)
if (i != DB_COUNT) {
tp->tp_diffbuf[i] = NULL;
- tp->tp_diff_invalid = TRUE;
+ tp->tp_diff_invalid = true;
if (tp == curtab) {
- diff_redraw(TRUE);
+ diff_redraw(true);
}
}
}
@@ -95,8 +131,8 @@ void diff_buf_adjust(win_T *win)
int i = diff_buf_idx(win->w_buffer);
if (i != DB_COUNT) {
curtab->tp_diffbuf[i] = NULL;
- curtab->tp_diff_invalid = TRUE;
- diff_redraw(TRUE);
+ curtab->tp_diff_invalid = true;
+ diff_redraw(true);
}
}
} else {
@@ -124,13 +160,27 @@ void diff_buf_add(buf_T *buf)
for (i = 0; i < DB_COUNT; ++i) {
if (curtab->tp_diffbuf[i] == NULL) {
curtab->tp_diffbuf[i] = buf;
- curtab->tp_diff_invalid = TRUE;
- diff_redraw(TRUE);
+ curtab->tp_diff_invalid = true;
+ diff_redraw(true);
return;
}
}
- EMSGN(_("E96: Can not diff more than %" PRId64 " buffers"), DB_COUNT);
+ EMSGN(_("E96: Cannot diff more than %" PRId64 " buffers"), DB_COUNT);
+}
+
+///
+/// Remove all buffers to make diffs for.
+///
+static void diff_buf_clear(void)
+{
+ for (int i = 0; i < DB_COUNT; i++) {
+ if (curtab->tp_diffbuf[i] != NULL) {
+ curtab->tp_diffbuf[i] = NULL;
+ curtab->tp_diff_invalid = true;
+ diff_redraw(true);
+ }
+ }
}
/// Find buffer "buf" in the list of diff buffers for the current tab page.
@@ -175,9 +225,9 @@ void diff_invalidate(buf_T *buf)
FOR_ALL_TABS(tp) {
int i = diff_buf_idx_tp(buf, tp);
if (i != DB_COUNT) {
- tp->tp_diff_invalid = TRUE;
+ tp->tp_diff_invalid = true;
if (tp == curtab) {
- diff_redraw(TRUE);
+ diff_redraw(true);
}
}
}
@@ -217,6 +267,15 @@ void diff_mark_adjust(linenr_T line1, linenr_T line2, long amount,
static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
linenr_T line2, long amount, long amount_after)
{
+ if (diff_internal()) {
+ // Will update diffs before redrawing. Set _invalid to update the
+ // diffs themselves, set _update to also update folds properly just
+ // before redrawing.
+ // Do update marks here, it is needed for :%diffput.
+ tp->tp_diff_invalid = true;
+ tp->tp_diff_update = true;
+ }
+
int inserted;
int deleted;
if (line2 == MAXLNUM) {
@@ -276,14 +335,14 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
//
// Check for these situations:
- // 1 2 3
- // 1 2 3
- // line1 2 3 4 5
- // 2 3 4 5
- // 2 3 4 5
- // line2 2 3 4 5
- // 3 5 6
- // 3 5 6
+ // 1 2 3
+ // 1 2 3
+ // line1 2 3 4 5
+ // 2 3 4 5
+ // 2 3 4 5
+ // line2 2 3 4 5
+ // 3 5 6
+ // 3 5 6
// compute last line of this change
last = dp->df_lnum[idx] + dp->df_count[idx] - 1;
@@ -299,7 +358,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
}
dp->df_lnum[idx] += amount_after;
} else {
- int check_unchanged = FALSE;
+ int check_unchanged = false;
// 2. 3. 4. 5.: inserted/deleted lines touching this diff.
if (deleted > 0) {
@@ -324,7 +383,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
// 5. delete lines at or just before top of diff
n = off;
dp->df_count[idx] -= line2 - dp->df_lnum[idx] + 1;
- check_unchanged = TRUE;
+ check_unchanged = true;
}
dp->df_lnum[idx] = line1;
} else {
@@ -344,7 +403,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
} else {
n = line2 - last;
}
- check_unchanged = TRUE;
+ check_unchanged = true;
} else {
// 3. delete lines inside the diff
n = 0;
@@ -363,7 +422,7 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
if (dp->df_lnum[idx] <= line1) {
// inserted lines somewhere in this diff
dp->df_count[idx] += inserted;
- check_unchanged = TRUE;
+ check_unchanged = true;
} else {
// inserted lines somewhere above this diff
dp->df_lnum[idx] += inserted;
@@ -430,12 +489,12 @@ static void diff_mark_adjust_tp(tabpage_T *tp, int idx, linenr_T line1,
}
if (tp == curtab) {
- diff_redraw(TRUE);
+ diff_redraw(true);
// Need to recompute the scroll binding, may remove or add filler
// lines (e.g., when adding lines above w_topline). But it's slow when
// making many changes, postpone until redrawing.
- diff_need_scrollbind = TRUE;
+ diff_need_scrollbind = true;
}
}
@@ -502,7 +561,7 @@ static void diff_check_unchanged(tabpage_T *tp, diff_T *dp)
}
char_u *line_org = vim_strsave(ml_get_buf(tp->tp_diffbuf[i_org],
dp->df_lnum[i_org] + off_org,
- FALSE));
+ false));
int i_new;
for (i_new = i_org + 1; i_new < DB_COUNT; ++i_new) {
@@ -521,7 +580,7 @@ static void diff_check_unchanged(tabpage_T *tp, diff_T *dp)
if (diff_cmp(line_org, ml_get_buf(tp->tp_diffbuf[i_new],
dp->df_lnum[i_new] + off_new,
- FALSE)) != 0) {
+ false)) != 0) {
break;
}
}
@@ -595,42 +654,243 @@ static void diff_redraw(int dofold)
} else if ((n > 0) && (n > wp->w_topfill)) {
wp->w_topfill = n;
}
- check_topfill(wp, FALSE);
+ check_topfill(wp, false);
+ }
+ }
+}
+
+static void clear_diffin(diffin_T *din)
+{
+ if (din->din_fname == NULL) {
+ xfree(din->din_mmfile.ptr);
+ din->din_mmfile.ptr = NULL;
+ } else {
+ os_remove((char *)din->din_fname);
+ }
+}
+
+static void clear_diffout(diffout_T *dout)
+{
+ if (dout->dout_fname == NULL) {
+ ga_clear_strings(&dout->dout_ga);
+ } else {
+ os_remove((char *)dout->dout_fname);
+ }
+}
+
+/// Write buffer "buf" to a memory buffer.
+///
+/// @param buf
+/// @param din
+///
+/// @return FAIL for failure.
+static int diff_write_buffer(buf_T *buf, diffin_T *din)
+{
+ linenr_T lnum;
+ char_u *s;
+ long len = 0;
+ char_u *ptr;
+
+ // xdiff requires one big block of memory with all the text.
+ for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
+ len += (long)STRLEN(ml_get_buf(buf, lnum, false)) + 1;
+ }
+ ptr = try_malloc(len);
+ if (ptr == NULL) {
+ // Allocating memory failed. This can happen, because we try to read
+ // the whole buffer text into memory. Set the failed flag, the diff
+ // will be retried with external diff. The flag is never reset.
+ buf->b_diff_failed = true;
+ if (p_verbose > 0) {
+ verbose_enter();
+ smsg(_("Not enough memory to use internal diff for buffer \"%s\""),
+ buf->b_fname);
+ verbose_leave();
+ }
+ return FAIL;
+ }
+ din->din_mmfile.ptr = (char *)ptr;
+ din->din_mmfile.size = len;
+
+ len = 0;
+ for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
+ for (s = ml_get_buf(buf, lnum, false); *s != NUL; ) {
+ if (diff_flags & DIFF_ICASE) {
+ int c;
+
+ // xdiff doesn't support ignoring case, fold-case the text.
+ int orig_len;
+ char_u cbuf[MB_MAXBYTES + 1];
+
+ c = PTR2CHAR(s);
+ c = enc_utf8 ? utf_fold(c) : TOLOWER_LOC(c);
+ orig_len = MB_PTR2LEN(s);
+ if (utf_char2bytes(c, cbuf) != orig_len) {
+ // TODO(Bram): handle byte length difference
+ memmove(ptr + len, s, orig_len);
+ } else {
+ memmove(ptr + len, cbuf, orig_len);
+ }
+
+ s += orig_len;
+ len += orig_len;
+ } else {
+ ptr[len++] = *s++;
+ }
}
+ ptr[len++] = NL;
}
+ return OK;
}
-/// Write buffer "buf" to file "name".
+/// Write buffer "buf" to file or memory buffer.
///
/// Always use 'fileformat' set to "unix".
///
/// @param buf
-/// @param fname
+/// @param din
///
/// @return FAIL for failure
-static int diff_write(buf_T *buf, char_u *fname)
+static int diff_write(buf_T *buf, diffin_T *din)
{
+ if (din->din_fname == NULL) {
+ return diff_write_buffer(buf, din);
+ }
+
+ // Always use 'fileformat' set to "unix".
char_u *save_ff = buf->b_p_ff;
buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
- int r = buf_write(buf, fname, NULL, (linenr_T)1, buf->b_ml.ml_line_count,
- NULL, FALSE, FALSE, FALSE, TRUE);
+ int r = buf_write(buf, din->din_fname, NULL,
+ (linenr_T)1, buf->b_ml.ml_line_count,
+ NULL, false, false, false, true);
free_string_option(buf->b_p_ff);
buf->b_p_ff = save_ff;
return r;
}
+///
+/// Update the diffs for all buffers involved.
+///
+/// @param dio
+/// @param idx_orig
+/// @param eap can be NULL
+static void diff_try_update(diffio_T *dio,
+ int idx_orig,
+ exarg_T *eap)
+{
+ buf_T *buf;
+ int idx_new;
+
+ if (dio->dio_internal) {
+ ga_init(&dio->dio_diff.dout_ga, sizeof(char *), 1000);
+ } else {
+ // We need three temp file names.
+ dio->dio_orig.din_fname = vim_tempname();
+ dio->dio_new.din_fname = vim_tempname();
+ dio->dio_diff.dout_fname = vim_tempname();
+ if (dio->dio_orig.din_fname == NULL
+ || dio->dio_new.din_fname == NULL
+ || dio->dio_diff.dout_fname == NULL) {
+ goto theend;
+ }
+ }
+
+ // Check external diff is actually working.
+ if (!dio->dio_internal && check_external_diff(dio) == FAIL) {
+ goto theend;
+ }
+
+ // :diffupdate!
+ if (eap != NULL && eap->forceit) {
+ for (idx_new = idx_orig; idx_new < DB_COUNT; idx_new++) {
+ buf = curtab->tp_diffbuf[idx_new];
+ if (buf_valid(buf)) {
+ buf_check_timestamp(buf, false);
+ }
+ }
+ }
+
+ // Write the first buffer to a tempfile or mmfile_t.
+ buf = curtab->tp_diffbuf[idx_orig];
+ if (diff_write(buf, &dio->dio_orig) == FAIL) {
+ goto theend;
+ }
+
+ // Make a difference between the first buffer and every other.
+ for (idx_new = idx_orig + 1; idx_new < DB_COUNT; idx_new++) {
+ buf = curtab->tp_diffbuf[idx_new];
+ if (buf == NULL || buf->b_ml.ml_mfp == NULL) {
+ continue; // skip buffer that isn't loaded
+ }
+
+ // Write the other buffer and diff with the first one.
+ if (diff_write(buf, &dio->dio_new) == FAIL) {
+ continue;
+ }
+ if (diff_file(dio) == FAIL) {
+ continue;
+ }
+
+ // Read the diff output and add each entry to the diff list.
+ diff_read(idx_orig, idx_new, &dio->dio_diff);
+
+ clear_diffin(&dio->dio_new);
+ clear_diffout(&dio->dio_diff);
+ }
+ clear_diffin(&dio->dio_orig);
+
+theend:
+ xfree(dio->dio_orig.din_fname);
+ xfree(dio->dio_new.din_fname);
+ xfree(dio->dio_diff.dout_fname);
+}
+
+///
+/// Return true if the options are set to use the internal diff library.
+/// Note that if the internal diff failed for one of the buffers, the external
+/// diff will be used anyway.
+///
+int diff_internal(void)
+{
+ return (diff_flags & DIFF_INTERNAL) != 0 && *p_dex == NUL;
+}
+
+///
+/// Return true if the internal diff failed for one of the diff buffers.
+///
+static int diff_internal_failed(void)
+{
+ int idx;
+
+ // Only need to do something when there is another buffer.
+ for (idx = 0; idx < DB_COUNT; idx++) {
+ if (curtab->tp_diffbuf[idx] != NULL
+ && curtab->tp_diffbuf[idx]->b_diff_failed) {
+ return true;
+ }
+ }
+ return false;
+}
+
/// Completely update the diffs for the buffers involved.
///
-/// This uses the ordinary "diff" command.
-/// The buffers are written to a file, also for unmodified buffers (the file
-/// could have been produced by autocommands, e.g. the netrw plugin).
+/// When using the external "diff" command the buffers are written to a file,
+/// also for unmodified buffers (the file could have been produced by
+/// autocommands, e.g. the netrw plugin).
///
/// @param eap can be NULL
void ex_diffupdate(exarg_T *eap)
{
+ if (diff_busy) {
+ diff_need_update = true;
+ return;
+ }
+
+ int had_diffs = curtab->tp_first_diff != NULL;
+
// Delete all diffblocks.
diff_clear(curtab);
- curtab->tp_diff_invalid = FALSE;
+ curtab->tp_diff_invalid = false;
// Use the first buffer as the original text.
int idx_orig;
@@ -641,7 +901,7 @@ void ex_diffupdate(exarg_T *eap)
}
if (idx_orig == DB_COUNT) {
- return;
+ goto theend;
}
// Only need to do something when there is another buffer.
@@ -653,49 +913,70 @@ void ex_diffupdate(exarg_T *eap)
}
if (idx_new == DB_COUNT) {
- return;
+ goto theend;
}
- // We need three temp file names.
- char *tmp_orig = (char *) vim_tempname();
- char *tmp_new = (char *) vim_tempname();
- char *tmp_diff = (char *) vim_tempname();
+ // Only use the internal method if it did not fail for one of the buffers.
+ diffio_T diffio;
+ memset(&diffio, 0, sizeof(diffio));
+ diffio.dio_internal = diff_internal() && !diff_internal_failed();
- if ((tmp_orig == NULL) || (tmp_new == NULL) || (tmp_diff == NULL)) {
- goto theend;
+ diff_try_update(&diffio, idx_orig, eap);
+ if (diffio.dio_internal && diff_internal_failed()) {
+ // Internal diff failed, use external diff instead.
+ memset(&diffio, 0, sizeof(diffio));
+ diff_try_update(&diffio, idx_orig, eap);
+ }
+
+ // force updating cursor position on screen
+ curwin->w_valid_cursor.lnum = 0;
+
+theend:
+ // A redraw is needed if there were diffs and they were cleared, or there
+ // are diffs now, which means they got updated.
+ if (had_diffs || curtab->tp_first_diff != NULL) {
+ diff_redraw(true);
+ apply_autocmds(EVENT_DIFFUPDATED, NULL, NULL, false, curbuf);
}
+}
- // Do a quick test if "diff" really works. Otherwise it looks like there
- // are no differences. Can't use the return value, it's non-zero when
- // there are differences.
+///
+/// Do a quick test if "diff" really works. Otherwise it looks like there
+/// are no differences. Can't use the return value, it's non-zero when
+/// there are differences.
+///
+static int check_external_diff(diffio_T *diffio)
+{
// May try twice, first with "-a" and then without.
int io_error = false;
- bool ok = false;
+ TriState ok = kFalse;
for (;;) {
- ok = false;
- FILE *fd = mch_fopen(tmp_orig, "w");
+ ok = kFalse;
+ FILE *fd = mch_fopen((char *)diffio->dio_orig.din_fname, "w");
if (fd == NULL) {
- io_error = TRUE;
+ io_error = true;
} else {
if (fwrite("line1\n", (size_t)6, (size_t)1, fd) != 1) {
- io_error = TRUE;
+ io_error = true;
}
fclose(fd);
- fd = mch_fopen(tmp_new, "w");
+ fd = mch_fopen((char *)diffio->dio_new.din_fname, "w");
if (fd == NULL) {
- io_error = TRUE;
+ io_error = true;
} else {
if (fwrite("line2\n", (size_t)6, (size_t)1, fd) != 1) {
- io_error = TRUE;
+ io_error = true;
}
fclose(fd);
- diff_file(tmp_orig, tmp_new, tmp_diff);
- fd = mch_fopen(tmp_diff, "r");
+ fd = NULL;
+ if (diff_file(diffio) == OK) {
+ fd = mch_fopen((char *)diffio->dio_diff.dout_fname, "r");
+ }
if (fd == NULL) {
- io_error = TRUE;
+ io_error = true;
} else {
char_u linebuf[LBUFLEN];
@@ -706,15 +987,15 @@ void ex_diffupdate(exarg_T *eap)
}
if (STRNCMP(linebuf, "1c1", 3) == 0) {
- ok = TRUE;
+ ok = kTrue;
}
}
fclose(fd);
}
- os_remove(tmp_diff);
- os_remove(tmp_new);
+ os_remove((char *)diffio->dio_diff.dout_fname);
+ os_remove((char *)diffio->dio_new.din_fname);
}
- os_remove(tmp_orig);
+ os_remove((char *)diffio->dio_orig.din_fname);
}
// When using 'diffexpr' break here.
@@ -723,7 +1004,7 @@ void ex_diffupdate(exarg_T *eap)
}
// If we checked if "-a" works already, break here.
- if (diff_a_works != MAYBE) {
+ if (diff_a_works != kNone) {
break;
}
diff_a_works = ok;
@@ -739,84 +1020,90 @@ void ex_diffupdate(exarg_T *eap)
EMSG(_("E810: Cannot read or write temp files"));
}
EMSG(_("E97: Cannot create diffs"));
- diff_a_works = MAYBE;
- goto theend;
- }
-
- // :diffupdate!
- if ((eap != NULL) && eap->forceit) {
- for (idx_new = idx_orig; idx_new < DB_COUNT; ++idx_new) {
- buf_T *buf = curtab->tp_diffbuf[idx_new];
- if (buf_valid(buf)) {
- buf_check_timestamp(buf, FALSE);
- }
- }
+ diff_a_works = kNone;
+ return FAIL;
}
+ return OK;
+}
- // Write the first buffer to a tempfile.
- buf_T *buf = curtab->tp_diffbuf[idx_orig];
- if (diff_write(buf, (char_u *) tmp_orig) == FAIL) {
- goto theend;
- }
+///
+/// Invoke the xdiff function.
+///
+static int diff_file_internal(diffio_T *diffio)
+{
+ xpparam_t param;
+ xdemitconf_t emit_cfg;
+ xdemitcb_t emit_cb;
- // Make a difference between the first buffer and every other.
- for (idx_new = idx_orig + 1; idx_new < DB_COUNT; ++idx_new) {
- buf_T *buf = curtab->tp_diffbuf[idx_new];
- if (buf == NULL || buf->b_ml.ml_mfp == NULL) {
- continue; // skip buffer that isn't loaded
- }
+ memset(&param, 0, sizeof(param));
+ memset(&emit_cfg, 0, sizeof(emit_cfg));
+ memset(&emit_cb, 0, sizeof(emit_cb));
- if (diff_write(buf, (char_u *) tmp_new) == FAIL) {
- continue;
- }
- diff_file(tmp_orig, tmp_new, tmp_diff);
+ param.flags = diff_algorithm;
- // Read the diff output and add each entry to the diff list.
- diff_read(idx_orig, idx_new, (char_u *) tmp_diff);
- os_remove(tmp_diff);
- os_remove(tmp_new);
+ if (diff_flags & DIFF_IWHITE) {
+ param.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
+ }
+ if (diff_flags & DIFF_IWHITEALL) {
+ param.flags |= XDF_IGNORE_WHITESPACE;
+ }
+ if (diff_flags & DIFF_IWHITEEOL) {
+ param.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
+ }
+ if (diff_flags & DIFF_IBLANK) {
+ param.flags |= XDF_IGNORE_BLANK_LINES;
}
- os_remove(tmp_orig);
-
- // force updating cursor position on screen
- curwin->w_valid_cursor.lnum = 0;
-
- diff_redraw(TRUE);
-theend:
- xfree(tmp_orig);
- xfree(tmp_new);
- xfree(tmp_diff);
+ emit_cfg.ctxlen = 0; // don't need any diff_context here
+ emit_cb.priv = &diffio->dio_diff;
+ emit_cb.outf = xdiff_out;
+ if (xdl_diff(&diffio->dio_orig.din_mmfile,
+ &diffio->dio_new.din_mmfile,
+ &param, &emit_cfg, &emit_cb) < 0) {
+ EMSG(_("E960: Problem creating the internal diff"));
+ return FAIL;
+ }
+ return OK;
}
/// Make a diff between files "tmp_orig" and "tmp_new", results in "tmp_diff".
///
-/// @param tmp_orig
-/// @param tmp_new
-/// @param tmp_diff
-static void diff_file(const char *const tmp_orig, const char *const tmp_new,
- const char *const tmp_diff)
+/// @param dio
+///
+/// @return OK or FAIL
+static int diff_file(diffio_T *dio)
{
+ char *tmp_orig = (char *)dio->dio_orig.din_fname;
+ char *tmp_new = (char *)dio->dio_new.din_fname;
+ char *tmp_diff = (char *)dio->dio_diff.dout_fname;
if (*p_dex != NUL) {
// Use 'diffexpr' to generate the diff file.
eval_diff(tmp_orig, tmp_new, tmp_diff);
+ return OK;
+ }
+ // Use xdiff for generating the diff.
+ if (dio->dio_internal) {
+ return diff_file_internal(dio);
} else {
const size_t len = (strlen(tmp_orig) + strlen(tmp_new) + strlen(tmp_diff)
+ STRLEN(p_srr) + 27);
char *const cmd = xmalloc(len);
- /* We don't want $DIFF_OPTIONS to get in the way. */
+ // We don't want $DIFF_OPTIONS to get in the way.
if (os_getenv("DIFF_OPTIONS")) {
os_unsetenv("DIFF_OPTIONS");
}
- /* Build the diff command and execute it. Always use -a, binary
- * differences are of no use. Ignore errors, diff returns
- * non-zero when differences have been found. */
- vim_snprintf(cmd, len, "diff %s%s%s%s%s %s",
- diff_a_works ? "-a " : "",
+ // Build the diff command and execute it. Always use -a, binary
+ // differences are of no use. Ignore errors, diff returns
+ // non-zero when differences have been found.
+ vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s%s%s%s %s",
+ diff_a_works == kFalse ? "" : "-a ",
"",
(diff_flags & DIFF_IWHITE) ? "-b " : "",
+ (diff_flags & DIFF_IWHITEALL) ? "-w " : "",
+ (diff_flags & DIFF_IWHITEEOL) ? "-Z " : "",
+ (diff_flags & DIFF_IBLANK) ? "-B " : "",
(diff_flags & DIFF_ICASE) ? "-i " : "",
tmp_orig, tmp_new);
append_redir(cmd, len, (char *) p_srr, tmp_diff);
@@ -826,6 +1113,7 @@ static void diff_file(const char *const tmp_orig, const char *const tmp_new,
NULL);
unblock_autocmds();
xfree(cmd);
+ return OK;
}
}
@@ -839,12 +1127,13 @@ void ex_diffpatch(exarg_T *eap)
{
char_u *buf = NULL;
win_T *old_curwin = curwin;
- char_u *newname = NULL; // name of patched file buffer
+ char_u *newname = NULL; // name of patched file buffer
+ char_u *esc_name = NULL;
#ifdef UNIX
- char_u dirbuf[MAXPATHL];
- char_u *fullname = NULL;
-#endif // ifdef UNIX
+ char *fullname = NULL;
+#endif
+
// We need two temp file names.
// Name of original temp file.
char_u *tmp_orig = vim_tempname();
@@ -858,27 +1147,23 @@ void ex_diffpatch(exarg_T *eap)
// Write the current buffer to "tmp_orig".
if (buf_write(curbuf, tmp_orig, NULL,
(linenr_T)1, curbuf->b_ml.ml_line_count,
- NULL, FALSE, FALSE, FALSE, TRUE) == FAIL) {
+ NULL, false, false, false, true) == FAIL) {
goto theend;
}
#ifdef UNIX
// Get the absolute path of the patchfile, changing directory below.
- fullname = (char_u *)FullName_save((char *)eap->arg, FALSE);
-#endif // ifdef UNIX
-
-#ifdef UNIX
- size_t buflen = STRLEN(tmp_orig)
- + (fullname != NULL ? STRLEN(fullname) : STRLEN(eap->arg))
- + STRLEN(tmp_new) + 16;
+ fullname = FullName_save((char *)eap->arg, false);
+ esc_name = vim_strsave_shellescape(
+ (fullname != NULL ? (char_u *)fullname : eap->arg), true, true);
#else
- size_t buflen = STRLEN(tmp_orig) + (STRLEN(eap->arg)) + STRLEN(tmp_new) + 16;
-#endif // ifdef UNIX
-
+ esc_name = vim_strsave_shellescape(eap->arg, true, true);
+#endif
+ size_t buflen = STRLEN(tmp_orig) + STRLEN(esc_name) + STRLEN(tmp_new) + 16;
buf = xmalloc(buflen);
#ifdef UNIX
-
+ char_u dirbuf[MAXPATHL];
// Temporarily chdir to /tmp, to avoid patching files in the current
// directory when the patch file contains more than one patch. When we
// have our own temp dir use that instead, it will be cleaned up when we
@@ -893,31 +1178,24 @@ void ex_diffpatch(exarg_T *eap)
tempdir = "/tmp";
}
os_chdir(tempdir);
- shorten_fnames(TRUE);
+ shorten_fnames(true);
}
-#endif // ifdef UNIX
+#endif
if (*p_pex != NUL) {
// Use 'patchexpr' to generate the new file.
#ifdef UNIX
- eval_patch((char *) tmp_orig,
- (char *) (fullname != NULL ? fullname : eap->arg),
- (char *) tmp_new);
+ eval_patch((char *)tmp_orig,
+ (fullname != NULL ? fullname : (char *)eap->arg),
+ (char *)tmp_new);
#else
- eval_patch((char *) tmp_orig, (char *) eap->arg, (char *) tmp_new);
-#endif // ifdef UNIX
+ eval_patch((char *)tmp_orig, (char *)eap->arg, (char *)tmp_new);
+#endif
} else {
- // Build the patch command and execute it. Ignore errors. Switch to
- // cooked mode to allow the user to respond to prompts.
-#ifdef UNIX
- vim_snprintf((char *)buf, buflen, "patch -o %s %s < \"%s\"",
- tmp_new, tmp_orig, fullname != NULL ? fullname : eap->arg);
-#else
- vim_snprintf((char *)buf, buflen, "patch -o %s %s < \"%s\"",
- tmp_new, tmp_orig, eap->arg);
-#endif // ifdef UNIX
- // Avoid ShellCmdPost stuff
- block_autocmds();
+ // Build the patch command and execute it. Ignore errors.
+ vim_snprintf((char *)buf, buflen, "patch -o %s %s < %s",
+ tmp_new, tmp_orig, esc_name);
+ block_autocmds(); // Avoid ShellCmdPost stuff
(void)call_shell(buf, kShellOptFilter, NULL);
unblock_autocmds();
}
@@ -927,12 +1205,9 @@ void ex_diffpatch(exarg_T *eap)
if (os_chdir((char *)dirbuf) != 0) {
EMSG(_(e_prev_dir));
}
- shorten_fnames(TRUE);
+ shorten_fnames(true);
}
-#endif // ifdef UNIX
-
- // patch probably has written over the screen
- redraw_later(CLEAR);
+#endif
// Delete any .orig or .rej file created.
STRCPY(buf, tmp_new);
@@ -967,8 +1242,8 @@ void ex_diffpatch(exarg_T *eap)
// check that split worked and editing tmp_new
if ((curwin != old_curwin) && win_valid(old_curwin)) {
// Set 'diff', 'scrollbind' on and 'wrap' off.
- diff_win_options(curwin, TRUE);
- diff_win_options(old_curwin, TRUE);
+ diff_win_options(curwin, true);
+ diff_win_options(old_curwin, true);
if (newname != NULL) {
// do a ":file filename.new" on the patched buffer
@@ -998,7 +1273,8 @@ theend:
xfree(buf);
#ifdef UNIX
xfree(fullname);
-#endif // ifdef UNIX
+#endif
+ xfree(esc_name);
}
/// Split the window and edit another file, setting options to show the diffs.
@@ -1007,7 +1283,12 @@ theend:
void ex_diffsplit(exarg_T *eap)
{
win_T *old_curwin = curwin;
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
+ set_bufref(&old_curbuf, curbuf);
+
+ // Need to compute w_fraction when no redraw happened yet.
+ validate_cursor();
+ set_fraction(curwin);
// don't use a new tab page, each tab page has its own diffs
cmdmod.tab = 0;
@@ -1015,7 +1296,7 @@ void ex_diffsplit(exarg_T *eap)
if (win_split(0, (diff_flags & DIFF_VERTICAL) ? WSP_VERT : 0) != FAIL) {
// Pretend it was a ":split fname" command
eap->cmdidx = CMD_split;
- curwin->w_p_diff = TRUE;
+ curwin->w_p_diff = true;
do_exedit(eap, old_curwin);
// split must have worked
@@ -1025,15 +1306,15 @@ void ex_diffsplit(exarg_T *eap)
if (win_valid(old_curwin)) {
diff_win_options(old_curwin, true);
- if (buf_valid(old_curbuf)) {
+ if (bufref_valid(&old_curbuf)) {
// Move the cursor position to that of the old window.
curwin->w_cursor.lnum = diff_get_corresponding_line(
- old_curbuf,
- old_curwin->w_cursor.lnum,
- curbuf,
- curwin->w_cursor.lnum);
+ old_curbuf.br_buf, old_curwin->w_cursor.lnum);
}
}
+ // Now that lines are folded scroll to show the cursor at the same
+ // relative position.
+ scroll_to_fraction(curwin, curwin->w_height);
}
}
}
@@ -1042,9 +1323,23 @@ void ex_diffsplit(exarg_T *eap)
void ex_diffthis(exarg_T *eap)
{
// Set 'diff', 'scrollbind' on and 'wrap' off.
- diff_win_options(curwin, TRUE);
+ diff_win_options(curwin, true);
}
+static void set_diff_option(win_T *wp, int value)
+{
+ win_T *old_curwin = curwin;
+
+ curwin = wp;
+ curbuf = curwin->w_buffer;
+ curbuf_lock++;
+ set_option_value("diff", (long)value, NULL, OPT_LOCAL);
+ curbuf_lock--;
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
+}
+
+
/// Set options in window "wp" for diff mode.
///
/// @param addbuf Add buffer to diff.
@@ -1061,18 +1356,18 @@ void diff_win_options(win_T *wp, int addbuf)
if (!wp->w_p_diff) {
wp->w_p_scb_save = wp->w_p_scb;
}
- wp->w_p_scb = TRUE;
+ wp->w_p_scb = true;
if (!wp->w_p_diff) {
wp->w_p_crb_save = wp->w_p_crb;
}
- wp->w_p_crb = TRUE;
+ wp->w_p_crb = true;
if (!wp->w_p_diff) {
wp->w_p_wrap_save = wp->w_p_wrap;
}
- wp->w_p_wrap = FALSE;
- curwin = wp;
+ wp->w_p_wrap = false;
+ curwin = wp; // -V519
curbuf = curwin->w_buffer;
if (!wp->w_p_diff) {
@@ -1092,7 +1387,7 @@ void diff_win_options(win_T *wp, int addbuf)
wp->w_p_fdl_save = wp->w_p_fdl;
}
wp->w_p_fdc = diff_foldcolumn;
- wp->w_p_fen = TRUE;
+ wp->w_p_fen = true;
wp->w_p_fdl = 0;
foldUpdateAll(wp);
@@ -1102,10 +1397,10 @@ void diff_win_options(win_T *wp, int addbuf)
do_cmdline_cmd("set sbo+=hor");
}
- // Saved the current values, to be restored in ex_diffoff().
- wp->w_p_diff_saved = TRUE;
+ // Save the current values, to be restored in ex_diffoff().
+ wp->w_p_diff_saved = true;
- wp->w_p_diff = true;
+ set_diff_option(wp, true);
if (addbuf) {
diff_buf_add(wp->w_buffer);
@@ -1126,7 +1421,7 @@ void ex_diffoff(exarg_T *eap)
// Set 'diff' off. If option values were saved in
// diff_win_options(), restore the ones whose settings seem to have
// been left over from diff mode.
- wp->w_p_diff = false;
+ set_diff_option(wp, false);
if (wp->w_p_diff_saved) {
if (wp->w_p_scb) {
@@ -1142,7 +1437,9 @@ void ex_diffoff(exarg_T *eap)
}
free_string_option(wp->w_p_fdm);
- wp->w_p_fdm = vim_strsave(wp->w_p_fdm_save);
+ wp->w_p_fdm = vim_strsave(*wp->w_p_fdm_save
+ ? wp->w_p_fdm_save
+ : (char_u *)"manual");
if (wp->w_p_fdc == diff_foldcolumn) {
wp->w_p_fdc = wp->w_p_fdc_save;
}
@@ -1156,10 +1453,13 @@ void ex_diffoff(exarg_T *eap)
}
foldUpdateAll(wp);
-
- // make sure topline is not halfway through a fold
- changed_window_setting_win(wp);
}
+ // remove filler lines
+ wp->w_topfill = 0;
+
+ // make sure topline is not halfway a fold and cursor is
+ // invalidated
+ changed_window_setting_win(wp);
// Note: 'sbo' is not restored, it's a global option.
diff_buf_adjust(wp);
@@ -1167,6 +1467,11 @@ void ex_diffoff(exarg_T *eap)
diffwin |= wp->w_p_diff;
}
+ // Also remove hidden buffers from the list.
+ if (eap->forceit) {
+ diff_buf_clear();
+ }
+
// Remove "hor" from from 'scrollopt' if there are no diff windows left.
if (!diffwin && (vim_strchr(p_sbo, 'h') != NULL)) {
do_cmdline_cmd("set sbo-=hor");
@@ -1177,88 +1482,95 @@ void ex_diffoff(exarg_T *eap)
///
/// @param idx_orig idx of original file
/// @param idx_new idx of new file
-/// @param fname name of diff output file
-static void diff_read(int idx_orig, int idx_new, char_u *fname)
+/// @dout diff output
+static void diff_read(int idx_orig, int idx_new, diffout_T *dout)
{
- FILE *fd;
+ FILE *fd = NULL;
+ int line_idx = 0;
diff_T *dprev = NULL;
diff_T *dp = curtab->tp_first_diff;
diff_T *dn, *dpl;
- long f1, l1, f2, l2;
- char_u linebuf[LBUFLEN]; // only need to hold the diff line
- int difftype;
- char_u *p;
+ char_u linebuf[LBUFLEN]; // only need to hold the diff line
+ char_u *line;
long off;
int i;
linenr_T lnum_orig, lnum_new;
long count_orig, count_new;
- int notset = TRUE; // block "*dp" not set yet
-
- fd = mch_fopen((char *)fname, "r");
-
- if (fd == NULL) {
- EMSG(_("E98: Cannot read diff output"));
- return;
+ int notset = true; // block "*dp" not set yet
+ enum {
+ DIFF_ED,
+ DIFF_UNIFIED,
+ DIFF_NONE
+ } diffstyle = DIFF_NONE;
+
+ if (dout->dout_fname == NULL) {
+ diffstyle = DIFF_UNIFIED;
+ } else {
+ fd = mch_fopen((char *)dout->dout_fname, "r");
+ if (fd == NULL) {
+ EMSG(_("E98: Cannot read diff output"));
+ return;
+ }
}
for (;;) {
- if (vim_fgets(linebuf, LBUFLEN, fd)) {
- // end of file
- break;
- }
-
- if (!isdigit(*linebuf)) {
- // not the start of a diff block
- continue;
- }
-
- // This line must be one of three formats:
- // {first}[,{last}]c{first}[,{last}]
- // {first}a{first}[,{last}]
- // {first}[,{last}]d{first}
- p = linebuf;
- f1 = getdigits_long(&p);
-
- if (*p == ',') {
- ++p;
- l1 = getdigits_long(&p);
- } else {
- l1 = f1;
- }
-
- if ((*p != 'a') && (*p != 'c') && (*p != 'd')) {
- // invalid diff format
- continue;
- }
- difftype = *p++;
- f2 = getdigits_long(&p);
-
- if (*p == ',') {
- ++p;
- l2 = getdigits_long(&p);
- } else {
- l2 = f2;
- }
-
- if ((l1 < f1) || (l2 < f2)) {
- // invalid line range
- continue;
- }
-
- if (difftype == 'a') {
- lnum_orig = f1 + 1;
- count_orig = 0;
+ if (fd == NULL) {
+ if (line_idx >= dout->dout_ga.ga_len) {
+ break; // did last line
+ }
+ line = ((char_u **)dout->dout_ga.ga_data)[line_idx++];
} else {
- lnum_orig = f1;
- count_orig = l1 - f1 + 1;
+ if (vim_fgets(linebuf, LBUFLEN, fd)) {
+ break; // end of file
+ }
+ line = linebuf;
+ }
+
+ if (diffstyle == DIFF_NONE) {
+ // Determine diff style.
+ // ed like diff looks like this:
+ // {first}[,{last}]c{first}[,{last}]
+ // {first}a{first}[,{last}]
+ // {first}[,{last}]d{first}
+ //
+ // unified diff looks like this:
+ // --- file1 2018-03-20 13:23:35.783153140 +0100
+ // +++ file2 2018-03-20 13:23:41.183156066 +0100
+ // @@ -1,3 +1,5 @@
+ if (isdigit(*line)) {
+ diffstyle = DIFF_ED;
+ } else if ((STRNCMP(line, "@@ ", 3) == 0)) {
+ diffstyle = DIFF_UNIFIED;
+ } else if ((STRNCMP(line, "--- ", 4) == 0)
+ && (vim_fgets(linebuf, LBUFLEN, fd) == 0) // -V501
+ && (STRNCMP(line, "+++ ", 4) == 0)
+ && (vim_fgets(linebuf, LBUFLEN, fd) == 0) // -V501
+ && (STRNCMP(line, "@@ ", 3) == 0)) {
+ diffstyle = DIFF_UNIFIED;
+ } else {
+ // Format not recognized yet, skip over this line. Cygwin diff
+ // may put a warning at the start of the file.
+ continue;
+ }
}
- if (difftype == 'd') {
- lnum_new = f2 + 1;
- count_new = 0;
+ if (diffstyle == DIFF_ED) {
+ if (!isdigit(*line)) {
+ continue; // not the start of a diff block
+ }
+ if (parse_diff_ed(line, &lnum_orig, &count_orig,
+ &lnum_new, &count_new) == FAIL) {
+ continue;
+ }
} else {
- lnum_new = f2;
- count_new = l2 - f2 + 1;
+ assert(diffstyle == DIFF_UNIFIED);
+ if (STRNCMP(line, "@@ ", 3) != 0) {
+ continue; // not the start of a diff block
+ }
+ if (parse_diff_unified(line, &lnum_orig, &count_orig,
+ &lnum_new, &count_new) == FAIL) {
+ continue;
+ }
}
// Go over blocks before the change, for which orig and new are equal.
@@ -1270,7 +1582,7 @@ static void diff_read(int idx_orig, int idx_new, char_u *fname)
}
dprev = dp;
dp = dp->df_next;
- notset = TRUE;
+ notset = true;
}
if ((dp != NULL)
@@ -1357,7 +1669,7 @@ static void diff_read(int idx_orig, int idx_new, char_u *fname)
}
}
}
- notset = FALSE; // "*dp" has been set
+ notset = false; // "*dp" has been set
}
// for remaining diff blocks orig and new are equal
@@ -1367,10 +1679,12 @@ static void diff_read(int idx_orig, int idx_new, char_u *fname)
}
dprev = dp;
dp = dp->df_next;
- notset = TRUE;
+ notset = true;
}
- fclose(fd);
+ if (fd != NULL) {
+ fclose(fd);
+ }
}
/// Copy an entry at "dp" from "idx_orig" to "idx_new".
@@ -1453,7 +1767,7 @@ int diff_check(win_T *wp, linenr_T lnum)
}
// A closed fold never has filler lines.
- if (hasFoldingWin(wp, lnum, NULL, NULL, TRUE, NULL)) {
+ if (hasFoldingWin(wp, lnum, NULL, NULL, true, NULL)) {
return 0;
}
@@ -1469,23 +1783,23 @@ int diff_check(win_T *wp, linenr_T lnum)
}
if (lnum < dp->df_lnum[idx] + dp->df_count[idx]) {
- int zero = FALSE;
+ int zero = false;
// Changed or inserted line. If the other buffers have a count of
// zero, the lines were inserted. If the other buffers have the same
// count, check if the lines are identical.
- cmp = FALSE;
+ cmp = false;
for (i = 0; i < DB_COUNT; ++i) {
if ((i != idx) && (curtab->tp_diffbuf[i] != NULL)) {
if (dp->df_count[i] == 0) {
- zero = TRUE;
+ zero = true;
} else {
if (dp->df_count[i] != dp->df_count[idx]) {
// nr of lines changed.
return -1;
}
- cmp = TRUE;
+ cmp = true;
}
}
}
@@ -1509,7 +1823,7 @@ int diff_check(win_T *wp, linenr_T lnum)
// the difference. Can't remove the entry here, we might be halfway
// through updating the window. Just report the text as unchanged.
// Other windows might still show the change though.
- if (zero == FALSE) {
+ if (zero == false) {
return 0;
}
return -2;
@@ -1564,6 +1878,34 @@ static bool diff_equal_entry(diff_T *dp, int idx1, int idx2)
return true;
}
+// Compare the characters at "p1" and "p2". If they are equal (possibly
+// ignoring case) return true and set "len" to the number of bytes.
+static bool diff_equal_char(const char_u *const p1, const char_u *const p2,
+ int *const len)
+{
+ const int l = utfc_ptr2len(p1);
+
+ if (l != utfc_ptr2len(p2)) {
+ return false;
+ }
+ if (l > 1) {
+ if (STRNCMP(p1, p2, l) != 0
+ && (!(diff_flags & DIFF_ICASE)
+ || utf_fold(utf_ptr2char(p1)) != utf_fold(utf_ptr2char(p2)))) {
+ return false;
+ }
+ *len = l;
+ } else {
+ if ((*p1 != *p2)
+ && (!(diff_flags & DIFF_ICASE)
+ || TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2))) {
+ return false;
+ }
+ *len = 1;
+ }
+ return true;
+}
+
/// Compare strings "s1" and "s2" according to 'diffopt'.
/// Return non-zero when they are different.
///
@@ -1573,47 +1915,37 @@ static bool diff_equal_entry(diff_T *dp, int idx1, int idx2)
/// @return on-zero if the two strings are different.
static int diff_cmp(char_u *s1, char_u *s2)
{
- if ((diff_flags & (DIFF_ICASE | DIFF_IWHITE)) == 0) {
+ if ((diff_flags & DIFF_IBLANK)
+ && (*skipwhite(s1) == NUL || *skipwhite(s2) == NUL)) {
+ return 0;
+ }
+
+ if ((diff_flags & (DIFF_ICASE | ALL_WHITE_DIFF)) == 0) {
return STRCMP(s1, s2);
}
- if ((diff_flags & DIFF_ICASE) && !(diff_flags & DIFF_IWHITE)) {
- return mb_stricmp(s1, s2);
+ if ((diff_flags & DIFF_ICASE) && !(diff_flags & ALL_WHITE_DIFF)) {
+ return mb_stricmp((const char *)s1, (const char *)s2);
}
- // Ignore white space changes and possibly ignore case.
char_u *p1 = s1;
char_u *p2 = s2;
+ // Ignore white space changes and possibly ignore case.
while (*p1 != NUL && *p2 != NUL) {
- if (ascii_iswhite(*p1) && ascii_iswhite(*p2)) {
+ if (((diff_flags & DIFF_IWHITE)
+ && ascii_iswhite(*p1) && ascii_iswhite(*p2))
+ || ((diff_flags & DIFF_IWHITEALL)
+ && (ascii_iswhite(*p1) || ascii_iswhite(*p2)))) {
p1 = skipwhite(p1);
p2 = skipwhite(p2);
} else {
- int l = (*mb_ptr2len)(p1);
- if (l != (*mb_ptr2len)(p2)) {
+ int l;
+ if (!diff_equal_char(p1, p2, &l)) {
break;
}
-
- if (l > 1) {
- if ((STRNCMP(p1, p2, l) != 0)
- && (!enc_utf8
- || !(diff_flags & DIFF_ICASE)
- || (utf_fold(utf_ptr2char(p1))
- != utf_fold(utf_ptr2char(p2))))) {
- break;
- }
- p1 += l;
- p2 += l;
- } else {
- if ((*p1 != *p2)
- && (!(diff_flags & DIFF_ICASE)
- || (TOLOWER_LOC(*p1) != TOLOWER_LOC(*p2)))) {
- break;
- }
- ++p1;
- ++p2;
- }
+ p1 += l;
+ p2 += l;
}
}
@@ -1760,7 +2092,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin)
check_topfill(towin, false);
(void)hasFoldingWin(towin, towin->w_topline, &towin->w_topline,
- NULL, TRUE, NULL);
+ NULL, true, NULL);
}
/// This is called when 'diffopt' is changed.
@@ -1771,6 +2103,8 @@ int diffopt_changed(void)
int diff_context_new = 6;
int diff_flags_new = 0;
int diff_foldcolumn_new = 2;
+ long diff_algorithm_new = 0;
+ long diff_indent_heuristic = 0;
char_u *p = p_dip;
while (*p != NUL) {
@@ -1780,9 +2114,18 @@ int diffopt_changed(void)
} else if ((STRNCMP(p, "context:", 8) == 0) && ascii_isdigit(p[8])) {
p += 8;
diff_context_new = getdigits_int(&p);
+ } else if (STRNCMP(p, "iblank", 6) == 0) {
+ p += 6;
+ diff_flags_new |= DIFF_IBLANK;
} else if (STRNCMP(p, "icase", 5) == 0) {
p += 5;
diff_flags_new |= DIFF_ICASE;
+ } else if (STRNCMP(p, "iwhiteall", 9) == 0) {
+ p += 9;
+ diff_flags_new |= DIFF_IWHITEALL;
+ } else if (STRNCMP(p, "iwhiteeol", 9) == 0) {
+ p += 9;
+ diff_flags_new |= DIFF_IWHITEEOL;
} else if (STRNCMP(p, "iwhite", 6) == 0) {
p += 6;
diff_flags_new |= DIFF_IWHITE;
@@ -1795,6 +2138,32 @@ int diffopt_changed(void)
} else if ((STRNCMP(p, "foldcolumn:", 11) == 0) && ascii_isdigit(p[11])) {
p += 11;
diff_foldcolumn_new = getdigits_int(&p);
+ } else if (STRNCMP(p, "hiddenoff", 9) == 0) {
+ p += 9;
+ diff_flags_new |= DIFF_HIDDEN_OFF;
+ } else if (STRNCMP(p, "indent-heuristic", 16) == 0) {
+ p += 16;
+ diff_indent_heuristic = XDF_INDENT_HEURISTIC;
+ } else if (STRNCMP(p, "internal", 8) == 0) {
+ p += 8;
+ diff_flags_new |= DIFF_INTERNAL;
+ } else if (STRNCMP(p, "algorithm:", 10) == 0) {
+ p += 10;
+ if (STRNCMP(p, "myers", 5) == 0) {
+ p += 5;
+ diff_algorithm_new = 0;
+ } else if (STRNCMP(p, "minimal", 7) == 0) {
+ p += 7;
+ diff_algorithm_new = XDF_NEED_MINIMAL;
+ } else if (STRNCMP(p, "patience", 8) == 0) {
+ p += 8;
+ diff_algorithm_new = XDF_PATIENCE_DIFF;
+ } else if (STRNCMP(p, "histogram", 9) == 0) {
+ p += 9;
+ diff_algorithm_new = XDF_HISTOGRAM_DIFF;
+ } else {
+ return FAIL;
+ }
}
if ((*p != ',') && (*p != NUL)) {
@@ -1806,23 +2175,27 @@ int diffopt_changed(void)
}
}
+ diff_algorithm_new |= diff_indent_heuristic;
+
// Can't have both "horizontal" and "vertical".
if ((diff_flags_new & DIFF_HORIZONTAL) && (diff_flags_new & DIFF_VERTICAL)) {
return FAIL;
}
- // If "icase" or "iwhite" was added or removed, need to update the diff.
- if (diff_flags != diff_flags_new) {
+ // If flags were added or removed, or the algorithm was changed, need to
+ // update the diff.
+ if (diff_flags != diff_flags_new || diff_algorithm != diff_algorithm_new) {
FOR_ALL_TABS(tp) {
- tp->tp_diff_invalid = TRUE;
+ tp->tp_diff_invalid = true;
}
}
diff_flags = diff_flags_new;
diff_context = diff_context_new;
diff_foldcolumn = diff_foldcolumn_new;
+ diff_algorithm = diff_algorithm_new;
- diff_redraw(TRUE);
+ diff_redraw(true);
// recompute the scroll binding with the new option value, may
// remove or add filler lines
@@ -1837,6 +2210,12 @@ bool diffopt_horizontal(void)
return (diff_flags & DIFF_HORIZONTAL) != 0;
}
+// Return true if 'diffopt' contains "hiddenoff".
+bool diffopt_hiddenoff(void)
+{
+ return (diff_flags & DIFF_HIDDEN_OFF) != 0;
+}
+
/// Find the difference within a changed line.
///
/// @param wp window whose current buffer to check
@@ -1854,9 +2233,10 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp)
int ei_org;
int ei_new;
bool added = true;
+ int l;
// Make a copy of the line, the next ml_get() will invalidate it.
- char_u *line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, FALSE));
+ char_u *line_org = vim_strsave(ml_get_buf(wp->w_buffer, lnum, false));
int idx = diff_buf_idx(wp->w_buffer);
if (idx == DB_COUNT) {
@@ -1888,32 +2268,33 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp)
}
added = false;
line_new = ml_get_buf(curtab->tp_diffbuf[i],
- dp->df_lnum[i] + off, FALSE);
+ dp->df_lnum[i] + off, false);
// Search for start of difference
si_org = si_new = 0;
while (line_org[si_org] != NUL) {
- if ((diff_flags & DIFF_IWHITE)
- && ascii_iswhite(line_org[si_org])
- && ascii_iswhite(line_new[si_new])) {
+ if (((diff_flags & DIFF_IWHITE)
+ && ascii_iswhite(line_org[si_org])
+ && ascii_iswhite(line_new[si_new]))
+ || ((diff_flags & DIFF_IWHITEALL)
+ && (ascii_iswhite(line_org[si_org])
+ || ascii_iswhite(line_new[si_new])))) {
si_org = (int)(skipwhite(line_org + si_org) - line_org);
si_new = (int)(skipwhite(line_new + si_new) - line_new);
} else {
- if (line_org[si_org] != line_new[si_new]) {
+ if (!diff_equal_char(line_org + si_org, line_new + si_new, &l)) {
break;
}
- ++si_org;
- ++si_new;
+ si_org += l;
+ si_new += l;
}
}
- if (has_mbyte) {
- // Move back to first byte of character in both lines (may
- // have "nn^" in line_org and "n^ in line_new).
- si_org -= (*mb_head_off)(line_org, line_org + si_org);
- si_new -= (*mb_head_off)(line_new, line_new + si_new);
- }
+ // Move back to first byte of character in both lines (may
+ // have "nn^" in line_org and "n^ in line_new).
+ si_org -= utf_head_off(line_org, line_org + si_org);
+ si_new -= utf_head_off(line_new, line_new + si_new);
if (*startp > si_org) {
*startp = si_org;
@@ -1928,9 +2309,12 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp)
&& ei_new >= si_new
&& ei_org >= 0
&& ei_new >= 0) {
- if ((diff_flags & DIFF_IWHITE)
- && ascii_iswhite(line_org[ei_org])
- && ascii_iswhite(line_new[ei_new])) {
+ if (((diff_flags & DIFF_IWHITE)
+ && ascii_iswhite(line_org[ei_org])
+ && ascii_iswhite(line_new[ei_new]))
+ || ((diff_flags & DIFF_IWHITEALL)
+ && (ascii_iswhite(line_org[ei_org])
+ || ascii_iswhite(line_new[ei_new])))) {
while (ei_org >= *startp && ascii_iswhite(line_org[ei_org])) {
ei_org--;
}
@@ -1939,11 +2323,17 @@ bool diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp)
ei_new--;
}
} else {
- if (line_org[ei_org] != line_new[ei_new]) {
+ const char_u *p1 = line_org + ei_org;
+ const char_u *p2 = line_new + ei_new;
+
+ p1 -= utf_head_off(line_org, p1);
+ p2 -= utf_head_off(line_new, p2);
+
+ if (!diff_equal_char(p1, p2, &l)) {
break;
}
- ei_org--;
- ei_new--;
+ ei_org -= l;
+ ei_new -= l;
}
}
@@ -2059,7 +2449,7 @@ void ex_diffgetput(exarg_T *eap)
int start_skip, end_skip;
int new_count;
int buf_empty;
- int found_not_ma = FALSE;
+ int found_not_ma = false;
int idx_other;
int idx_from;
int idx_to;
@@ -2080,7 +2470,7 @@ void ex_diffgetput(exarg_T *eap)
|| MODIFIABLE(curtab->tp_diffbuf[idx_other])) {
break;
}
- found_not_ma = TRUE;
+ found_not_ma = true;
}
}
@@ -2118,7 +2508,7 @@ void ex_diffgetput(exarg_T *eap)
// digits only
i = atol((char *)eap->arg);
} else {
- i = buflist_findpat(eap->arg, p, FALSE, TRUE, FALSE);
+ i = buflist_findpat(eap->arg, p, false, true, false);
if (i < 0) {
// error message already given
@@ -2144,7 +2534,7 @@ void ex_diffgetput(exarg_T *eap)
}
}
- diff_busy = TRUE;
+ diff_busy = true;
// When no range given include the line above or below the cursor.
if (eap->addr_count == 0) {
@@ -2181,7 +2571,7 @@ void ex_diffgetput(exarg_T *eap)
change_warning(0);
if (diff_buf_idx(curbuf) != idx_to) {
EMSG(_("E787: Buffer changed unexpectedly"));
- return;
+ goto theend;
}
}
@@ -2244,13 +2634,13 @@ void ex_diffgetput(exarg_T *eap)
}
}
- buf_empty = bufempty();
+ buf_empty = BUFEMPTY();
added = 0;
for (i = 0; i < count; ++i) {
// remember deleting the last line of the buffer
buf_empty = curbuf->b_ml.ml_line_count == 1;
- ml_delete(lnum, FALSE);
+ ml_delete(lnum, false);
added--;
}
@@ -2259,15 +2649,15 @@ void ex_diffgetput(exarg_T *eap)
if (nr > curtab->tp_diffbuf[idx_from]->b_ml.ml_line_count) {
break;
}
- p = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx_from], nr, FALSE));
- ml_append(lnum + i - 1, p, 0, FALSE);
+ p = vim_strsave(ml_get_buf(curtab->tp_diffbuf[idx_from], nr, false));
+ ml_append(lnum + i - 1, p, 0, false);
xfree(p);
added++;
if (buf_empty && (curbuf->b_ml.ml_line_count == 2)) {
// Added the first line into an empty buffer, need to
// delete the dummy empty line.
- buf_empty = FALSE;
- ml_delete((linenr_T)2, FALSE);
+ buf_empty = false;
+ ml_delete((linenr_T)2, false);
}
}
new_count = dp->df_count[idx_to] + added;
@@ -2300,7 +2690,7 @@ void ex_diffgetput(exarg_T *eap)
// Adjust marks. This will change the following entries!
if (added != 0) {
- mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added);
+ mark_adjust(lnum, lnum + count - 1, (long)MAXLNUM, (long)added, false);
if (curwin->w_cursor.lnum >= lnum) {
// Adjust the cursor position if it's in/after the changed
// lines.
@@ -2311,7 +2701,7 @@ void ex_diffgetput(exarg_T *eap)
}
}
}
- changed_lines(lnum, 0, lnum + count, (long)added);
+ changed_lines(lnum, 0, lnum + count, (long)added, true);
if (dfree != NULL) {
// Diff is deleted, update folds in other windows.
@@ -2341,20 +2731,31 @@ void ex_diffgetput(exarg_T *eap)
// another buffer. Sync undo if the command was typed. This isn't
// 100% right when ":diffput" is used in a function or mapping.
if (KeyTyped) {
- u_sync(FALSE);
+ u_sync(false);
}
aucmd_restbuf(&aco);
}
- diff_busy = FALSE;
+theend:
+ diff_busy = false;
+ if (diff_need_update) {
+ ex_diffupdate(NULL);
+ }
- // Check that the cursor is on a valid character and update it's position.
- // When there were filler lines the topline has become invalid.
+ // Check that the cursor is on a valid character and update its
+ // position. When there were filler lines the topline has become
+ // invalid.
check_cursor();
changed_line_abv_curs();
- // Also need to redraw the other buffers.
- diff_redraw(FALSE);
+ if (diff_need_update) {
+ // redraw already done by ex_diffupdate()
+ diff_need_update = false;
+ } else {
+ // Also need to redraw the other buffers.
+ diff_redraw(false);
+ apply_autocmds(EVENT_DIFFUPDATED, NULL, NULL, false, curbuf);
+ }
}
/// Update folds for all diff buffers for entry "dp".
@@ -2452,25 +2853,17 @@ int diff_move_to(int dir, long count)
return OK;
}
-/// Finds the corresponding line in a diff.
-///
-/// @param buf1
-/// @param lnum1
-/// @param buf2
-/// @param lnum3
-///
-/// @return The corresponding line.
-linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2,
- linenr_T lnum3)
+/// Return the line number in the current window that is closest to "lnum1" in
+/// "buf1" in diff mode.
+static linenr_T diff_get_corresponding_line_int(buf_T *buf1, linenr_T lnum1)
{
int idx1;
int idx2;
diff_T *dp;
int baseline = 0;
- linenr_T lnum2;
idx1 = diff_buf_idx(buf1);
- idx2 = diff_buf_idx(buf2);
+ idx2 = diff_buf_idx(curbuf);
if ((idx1 == DB_COUNT)
|| (idx2 == DB_COUNT)
@@ -2490,15 +2883,9 @@ linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2,
for (dp = curtab->tp_first_diff; dp != NULL; dp = dp->df_next) {
if (dp->df_lnum[idx1] > lnum1) {
- lnum2 = lnum1 - baseline;
-
- // don't end up past the end of the file
- if (lnum2 > buf2->b_ml.ml_line_count) {
- lnum2 = buf2->b_ml.ml_line_count;
- }
-
- return lnum2;
- } else if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1) {
+ return lnum1 - baseline;
+ }
+ if ((dp->df_lnum[idx1] + dp->df_count[idx1]) > lnum1) {
// Inside the diffblock
baseline = lnum1 - dp->df_lnum[idx1];
@@ -2507,30 +2894,42 @@ linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1, buf_T *buf2,
}
return dp->df_lnum[idx2] + baseline;
- } else if ((dp->df_lnum[idx1] == lnum1)
- && (dp->df_count[idx1] == 0)
- && (dp->df_lnum[idx2] <= lnum3)
- && ((dp->df_lnum[idx2] + dp->df_count[idx2]) > lnum3)) {
+ }
+ if ((dp->df_lnum[idx1] == lnum1)
+ && (dp->df_count[idx1] == 0)
+ && (dp->df_lnum[idx2] <= curwin->w_cursor.lnum)
+ && ((dp->df_lnum[idx2] + dp->df_count[idx2])
+ > curwin->w_cursor.lnum)) {
// Special case: if the cursor is just after a zero-count
// block (i.e. all filler) and the target cursor is already
// inside the corresponding block, leave the target cursor
// unmoved. This makes repeated CTRL-W W operations work
// as expected.
- return lnum3;
+ return curwin->w_cursor.lnum;
}
baseline = (dp->df_lnum[idx1] + dp->df_count[idx1])
- - (dp->df_lnum[idx2] + dp->df_count[idx2]);
+ - (dp->df_lnum[idx2] + dp->df_count[idx2]);
}
// If we get here then the cursor is after the last diff
- lnum2 = lnum1 - baseline;
+ return lnum1 - baseline;
+}
+
+/// Finds the corresponding line in a diff.
+///
+/// @param buf1
+/// @param lnum1
+///
+/// @return The corresponding line.
+linenr_T diff_get_corresponding_line(buf_T *buf1, linenr_T lnum1)
+{
+ linenr_T lnum = diff_get_corresponding_line_int(buf1, lnum1);
// don't end up past the end of the file
- if (lnum2 > buf2->b_ml.ml_line_count) {
- lnum2 = buf2->b_ml.ml_line_count;
+ if (lnum > curbuf->b_ml.ml_line_count) {
+ return curbuf->b_ml.ml_line_count;
}
-
- return lnum2;
+ return lnum;
}
/// For line "lnum" in the current window find the equivalent lnum in window
@@ -2581,3 +2980,145 @@ linenr_T diff_lnum_win(linenr_T lnum, win_T *wp)
}
return n;
}
+
+///
+/// Handle an ED style diff line.
+/// Return FAIL if the line does not contain diff info.
+///
+static int parse_diff_ed(char_u *line,
+ linenr_T *lnum_orig,
+ long *count_orig,
+ linenr_T *lnum_new,
+ long *count_new)
+{
+ char_u *p;
+ long f1, l1, f2, l2;
+ int difftype;
+
+ // The line must be one of three formats:
+ // change: {first}[,{last}]c{first}[,{last}]
+ // append: {first}a{first}[,{last}]
+ // delete: {first}[,{last}]d{first}
+ p = line;
+ f1 = getdigits(&p);
+ if (*p == ',') {
+ p++;
+ l1 = getdigits(&p);
+ } else {
+ l1 = f1;
+ }
+ if (*p != 'a' && *p != 'c' && *p != 'd') {
+ return FAIL; // invalid diff format
+ }
+ difftype = *p++;
+ f2 = getdigits(&p);
+ if (*p == ',') {
+ p++;
+ l2 = getdigits(&p);
+ } else {
+ l2 = f2;
+ }
+ if (l1 < f1 || l2 < f2) {
+ return FAIL;
+ }
+
+ if (difftype == 'a') {
+ *lnum_orig = f1 + 1;
+ *count_orig = 0;
+ } else {
+ *lnum_orig = f1;
+ *count_orig = l1 - f1 + 1;
+ }
+ if (difftype == 'd') {
+ *lnum_new = f2 + 1;
+ *count_new = 0;
+ } else {
+ *lnum_new = f2;
+ *count_new = l2 - f2 + 1;
+ }
+ return OK;
+}
+
+///
+/// Parses unified diff with zero(!) context lines.
+/// Return FAIL if there is no diff information in "line".
+///
+static int parse_diff_unified(char_u *line,
+ linenr_T *lnum_orig,
+ long *count_orig,
+ linenr_T *lnum_new,
+ long *count_new)
+{
+ char_u *p;
+ long oldline, oldcount, newline, newcount;
+
+ // Parse unified diff hunk header:
+ // @@ -oldline,oldcount +newline,newcount @@
+ p = line;
+ if (*p++ == '@' && *p++ == '@' && *p++ == ' ' && *p++ == '-') {
+ oldline = getdigits(&p);
+ if (*p == ',') {
+ p++;
+ oldcount = getdigits(&p);
+ } else {
+ oldcount = 1;
+ }
+ if (*p++ == ' ' && *p++ == '+') {
+ newline = getdigits(&p);
+ if (*p == ',') {
+ p++;
+ newcount = getdigits(&p);
+ } else {
+ newcount = 1;
+ }
+ } else {
+ return FAIL; // invalid diff format
+ }
+
+ if (oldcount == 0) {
+ oldline += 1;
+ }
+ if (newcount == 0) {
+ newline += 1;
+ }
+ if (newline == 0) {
+ newline = 1;
+ }
+
+ *lnum_orig = oldline;
+ *count_orig = oldcount;
+ *lnum_new = newline;
+ *count_new = newcount;
+
+ return OK;
+ }
+
+ return FAIL;
+}
+
+///
+/// Callback function for the xdl_diff() function.
+/// Stores the diff output in a grow array.
+///
+static int xdiff_out(void *priv, mmbuffer_t *mb, int nbuf)
+{
+ diffout_T *dout = (diffout_T *)priv;
+ char_u *p;
+
+ // The header line always comes by itself, text lines in at least two
+ // parts. We drop the text part.
+ if (nbuf > 1) {
+ return 0;
+ }
+
+ // sanity check
+ if (STRNCMP(mb[0].ptr, "@@ ", 3) != 0) {
+ return 0;
+ }
+
+ ga_grow(&dout->dout_ga, 1);
+
+ p = vim_strnsave((char_u *)mb[0].ptr, mb[0].size);
+ ((char_u **)dout->dout_ga.ga_data)[dout->dout_ga.ga_len++] = p;
+ return 0;
+}
diff --git a/src/nvim/diff.h b/src/nvim/diff.h
index f6cef1cafd..3624ce29bb 100644
--- a/src/nvim/diff.h
+++ b/src/nvim/diff.h
@@ -1,6 +1,9 @@
#ifndef NVIM_DIFF_H
#define NVIM_DIFF_H
+#include "nvim/pos.h"
+#include "nvim/ex_cmds_defs.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "diff.h.generated.h"
#endif
diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c
index aad145b3e5..3329290634 100644
--- a/src/nvim/digraph.c
+++ b/src/nvim/digraph.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
+
/// @file digraph.c
///
/// code for digraphs
@@ -17,7 +20,6 @@
#include "nvim/getchar.h"
#include "nvim/mbyte.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/garray.h"
#include "nvim/normal.h"
@@ -791,6 +793,7 @@ static digr_T digraphdefault[] =
{ '/', '-', 0x2020 },
{ '/', '=', 0x2021 },
{ '.', '.', 0x2025 },
+ { ',', '.', 0x2026 },
{ '%', '0', 0x2030 },
{ '1', '\'', 0x2032 },
{ '2', '\'', 0x2033 },
@@ -1356,6 +1359,12 @@ static digr_T digraphdefault[] =
{ 'f', 't', 0xfb05 },
{ 's', 't', 0xfb06 },
+ // extra alternatives, easier to remember
+ { 'W', '`', 0x1e80 },
+ { 'w', '`', 0x1e81 },
+ { 'Y', '`', 0x1ef2 },
+ { 'y', '`', 0x1ef3 },
+
// Vim 5.x compatible digraphs that don't conflict with the above
{ '~', '!', 161 }, // ¡
{ 'c', '|', 162 }, // ¢
@@ -1388,7 +1397,7 @@ static digr_T digraphdefault[] =
{ 'O', '`', 210 }, // Ò
{ 'O', '^', 212 }, // Ô
{ 'O', '~', 213 }, // Õ
- { '/', '\\', 215 }, // × - multiplication symbol in ISO 8859-1
+ { '/', '\\', 215 }, // × - multiplication symbol in ISO 8859-1
{ 'U', '`', 217 }, // Ù
{ 'U', '^', 219 }, // Û
{ 'I', 'p', 222 }, // Þ
@@ -1439,6 +1448,33 @@ int do_digraph(int c)
return c;
}
+/// Find a digraph for "val". If found return the string to display it.
+/// If not found return NULL.
+char_u *get_digraph_for_char(int val)
+{
+ digr_T *dp;
+ static char_u r[3];
+
+ for (int use_defaults = 0; use_defaults <= 1; use_defaults++) {
+ if (use_defaults == 0) {
+ dp = (digr_T *)user_digraphs.ga_data;
+ } else {
+ dp = digraphdefault;
+ }
+ for (int i = 0;
+ use_defaults ? dp->char1 != NUL : i < user_digraphs.ga_len; i++) {
+ if (dp->result == val) {
+ r[0] = dp->char1;
+ r[1] = dp->char2;
+ r[2] = NUL;
+ return r;
+ }
+ dp++;
+ }
+ }
+ return NULL;
+}
+
/// Get a digraph. Used after typing CTRL-K on the command line or in normal
/// mode.
///
@@ -1449,10 +1485,8 @@ int get_digraph(int cmdline)
{
int cc;
no_mapping++;
- allow_keys++;
int c = plain_vgetc();
no_mapping--;
- allow_keys--;
if (c != ESC) {
// ESC cancels CTRL-K
@@ -1469,10 +1503,8 @@ int get_digraph(int cmdline)
add_to_showcmd(c);
}
no_mapping++;
- allow_keys++;
cc = plain_vgetc();
no_mapping--;
- allow_keys--;
if (cc != ESC) {
// ESC cancels CTRL-K
@@ -1521,34 +1553,6 @@ static int getexactdigraph(int char1, int char2, int meta_char)
}
}
- if ((retval != 0) && !enc_utf8) {
- char_u buf[6], *to;
- vimconv_T vc;
-
- // Convert the Unicode digraph to 'encoding'.
- int i = utf_char2bytes(retval, buf);
- retval = 0;
- vc.vc_type = CONV_NONE;
-
- if (convert_setup(&vc, (char_u *)"utf-8", p_enc) == OK) {
- vc.vc_fail = true;
- assert(i >= 0);
- size_t len = (size_t)i;
- to = string_convert(&vc, buf, &len);
-
- if (to != NULL) {
- retval = (*mb_ptr2char)(to);
- xfree(to);
- }
- (void)convert_setup(&vc, NULL, NULL);
- }
- }
-
- // Ignore multi-byte characters when not in multi-byte mode.
- if (!has_mbyte && (retval > 0xff)) {
- retval = 0;
- }
-
if (retval == 0) {
// digraph deleted or not found
if ((char1 == ' ') && meta_char) {
@@ -1574,7 +1578,8 @@ int getdigraph(int char1, int char2, int meta_char)
if (((retval = getexactdigraph(char1, char2, meta_char)) == char2)
&& (char1 != char2)
- && ((retval = getexactdigraph(char2, char1, meta_char)) == char1)) {
+ && ((retval = getexactdigraph(char2, char1, meta_char)) // -V764
+ == char1)) {
return char2;
}
return retval;
@@ -1654,8 +1659,7 @@ void listdigraphs(void)
tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE);
if ((tmp.result != 0)
- && (tmp.result != tmp.char2)
- && (has_mbyte || (tmp.result <= 255))) {
+ && (tmp.result != tmp.char2)) {
printdigraph(&tmp);
}
dp++;
@@ -1668,9 +1672,6 @@ void listdigraphs(void)
os_breakcheck();
dp++;
}
- // clear screen, because some digraphs may be wrong, in which case we messed
- // up ScreenLines
- must_redraw = CLEAR;
}
static void printdigraph(digr_T *dp)
@@ -1680,38 +1681,39 @@ static void printdigraph(digr_T *dp)
int list_width;
- if ((dy_flags & DY_UHEX) || has_mbyte) {
- list_width = 13;
- } else {
- list_width = 11;
- }
+ list_width = 13;
if (dp->result != 0) {
if (msg_col > Columns - list_width) {
msg_putchar('\n');
}
- if (msg_col) {
- while (msg_col % list_width != 0) {
+
+ // Make msg_col a multiple of list_width by using spaces.
+ if (msg_col % list_width != 0) {
+ int spaces = (msg_col / list_width + 1) * list_width - msg_col;
+ while (spaces--) {
msg_putchar(' ');
}
}
- p = buf;
+ p = &buf[0];
*p++ = dp->char1;
*p++ = dp->char2;
*p++ = ' ';
+ *p = NUL;
+ msg_outtrans(buf);
+ p = buf;
- if (has_mbyte) {
- // add a space to draw a composing char on
- if (enc_utf8 && utf_iscomposing(dp->result)) {
- *p++ = ' ';
- }
- p += (*mb_char2bytes)(dp->result, p);
- } else {
- *p++ = (char_u)dp->result;
+ // add a space to draw a composing char on
+ if (utf_iscomposing(dp->result)) {
+ *p++ = ' ';
}
+ p += utf_char2bytes(dp->result, p);
+ *p = NUL;
+ msg_outtrans_attr(buf, HL_ATTR(HLF_8));
+ p = buf;
if (char2cells(dp->result) == 1) {
*p++ = ' ';
}
@@ -1832,12 +1834,12 @@ void ex_loadkeymap(exarg_T *eap)
xfree(line);
}
- // setup ":lnoremap" to map the keys
- for (int i = 0; i < curbuf->b_kmap_ga.ga_len; ++i) {
+ // setup ":lmap" to map the keys
+ for (int i = 0; i < curbuf->b_kmap_ga.ga_len; i++) {
vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s %s",
((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].from,
((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].to);
- (void)do_map(2, buf, LANGMAP, FALSE);
+ (void)do_map(0, buf, LANGMAP, false);
}
p_cpo = save_cpo;
@@ -1846,6 +1848,16 @@ void ex_loadkeymap(exarg_T *eap)
status_redraw_curbuf();
}
+/// Frees the buf_T.b_kmap_ga field of a buffer.
+void keymap_ga_clear(garray_T *kmap_ga)
+{
+ kmap_T *kp = (kmap_T *)kmap_ga->ga_data;
+ for (int i = 0; i < kmap_ga->ga_len; i++) {
+ xfree(kp[i].from);
+ xfree(kp[i].to);
+ }
+}
+
/// Stop using 'keymap'.
static void keymap_unload(void)
{
@@ -1863,12 +1875,11 @@ static void keymap_unload(void)
// clear the ":lmap"s
kp = (kmap_T *)curbuf->b_kmap_ga.ga_data;
- for (int i = 0; i < curbuf->b_kmap_ga.ga_len; ++i) {
+ for (int i = 0; i < curbuf->b_kmap_ga.ga_len; i++) {
vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s", kp[i].from);
- (void)do_map(1, buf, LANGMAP, FALSE);
- xfree(kp[i].from);
- xfree(kp[i].to);
+ (void)do_map(1, buf, LANGMAP, false);
}
+ keymap_ga_clear(&curbuf->b_kmap_ga);
p_cpo = save_cpo;
diff --git a/src/nvim/digraph.h b/src/nvim/digraph.h
index b623969e08..1b73ccaf3f 100644
--- a/src/nvim/digraph.h
+++ b/src/nvim/digraph.h
@@ -1,6 +1,9 @@
#ifndef NVIM_DIGRAPH_H
#define NVIM_DIGRAPH_H
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "digraph.h.generated.h"
#endif
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 03ef41f849..bb3c0ec196 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.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
+
/*
* edit.c: functions for Insert mode
*/
@@ -15,6 +18,7 @@
#include "nvim/cursor.h"
#include "nvim/digraph.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/farsi.h"
@@ -29,7 +33,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/move.h"
#include "nvim/normal.h"
@@ -135,6 +138,7 @@ struct compl_S {
static compl_T *compl_first_match = NULL;
static compl_T *compl_curr_match = NULL;
static compl_T *compl_shown_match = NULL;
+static compl_T *compl_old_match = NULL;
/* After using a cursor key <Enter> selects a match in the popup menu,
* otherwise it inserts a line break. */
@@ -180,6 +184,16 @@ static expand_T compl_xp;
static int compl_opt_refresh_always = FALSE;
+static int pum_selected_item = -1;
+
+/// state for pum_ext_select_item.
+struct {
+ bool active;
+ int item;
+ bool insert;
+ bool finish;
+} pum_want;
+
typedef struct insert_state {
VimState state;
cmdarg_T *ca;
@@ -223,7 +237,7 @@ static int last_insert_skip; /* nr of chars in front of previous insert */
static int new_insert_skip; /* nr of chars in front of current insert */
static int did_restart_edit; /* "restart_edit" when calling edit() */
-static int can_cindent; /* may do cindenting on this line */
+static bool can_cindent; // may do cindenting on this line
static int old_indent = 0; /* for ^^D command in insert mode */
@@ -236,10 +250,10 @@ static int ins_need_undo; /* call u_save() before inserting a
char. Set when edit() is called.
after that arrow_used is used. */
-static int did_add_space = FALSE; /* auto_format() added an extra space
- under the cursor */
-static int dont_sync_undo = false; // CTRL-G U prevents syncing undo
- // for the next left/right cursor
+static bool did_add_space = false; // auto_format() added an extra space
+ // under the cursor
+static TriState dont_sync_undo = kFalse; // CTRL-G U prevents syncing undo
+ // for the next left/right cursor
static linenr_T o_lnum = 0;
@@ -272,7 +286,7 @@ static void insert_enter(InsertState *s)
set_vim_var_string(VV_INSERTMODE, (char *) s->ptr, 1);
set_vim_var_string(VV_CHAR, NULL, -1);
- apply_autocmds(EVENT_INSERTENTER, NULL, NULL, false, curbuf);
+ ins_apply_autocmds(EVENT_INSERTENTER);
// Make sure the cursor didn't move. Do call check_cursor_col() in
// case the text was modified. Since Insert mode was not started yet
@@ -292,10 +306,6 @@ static void insert_enter(InsertState *s)
}
}
- // Check if the cursor line needs redrawing before changing State. If
- // 'concealcursor' is "n" it needs to be redrawn without concealing.
- conceal_check_cursur_line();
-
// When doing a paste with the middle mouse button, Insstart is set to
// where the paste started.
if (where_paste_started.lnum != 0) {
@@ -459,12 +469,16 @@ static void insert_enter(InsertState *s)
// Always update o_lnum, so that a "CTRL-O ." that adds a line
// still puts the cursor back after the inserted text.
- if (ins_at_eol && gchar_cursor() == NUL) {
+ if (ins_at_eol) {
o_lnum = curwin->w_cursor.lnum;
}
- if (s->cmdchar != 'r' && s->cmdchar != 'v') {
- apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL, false, curbuf);
+ foldUpdateAfterInsert();
+ // When CTRL-C was typed got_int will be set, with the result
+ // that the autocommands won't be executed. When mapped got_int
+ // is not set, but let's keep the behavior the same.
+ if (s->cmdchar != 'r' && s->cmdchar != 'v' && s->c != Ctrl_C) {
+ ins_apply_autocmds(EVENT_INSERTLEAVE);
}
did_cursorhold = false;
}
@@ -474,7 +488,9 @@ static int insert_check(VimState *state)
InsertState *s = (InsertState *)state;
// If typed something may trigger CursorHoldI again.
- if (s->c != K_EVENT) {
+ if (s->c != K_EVENT
+ // but not in CTRL-X mode, a script can't restore the state
+ && ctrl_x_mode == 0) {
did_cursorhold = false;
}
@@ -501,7 +517,7 @@ static int insert_check(VimState *state)
Insstart_orig = Insstart;
}
- if (stop_insert_mode) {
+ if (stop_insert_mode && !pum_visible()) {
// ":stopinsert" used or 'insertmode' reset
s->count = 0;
return 0; // exit insert mode
@@ -550,7 +566,7 @@ static int insert_check(VimState *state)
if (curwin->w_wcol < s->mincol - curbuf->b_p_ts
&& curwin->w_wrow == curwin->w_winrow
- + curwin->w_height - 1 - p_so
+ + curwin->w_grid.Rows - 1 - p_so
&& (curwin->w_cursor.lnum != curwin->w_topline
|| curwin->w_topfill > 0)) {
if (curwin->w_topfill > 0) {
@@ -588,10 +604,10 @@ static int insert_check(VimState *state)
s->lastc = s->c; // remember previous char for CTRL-D
// After using CTRL-G U the next cursor key will not break undo.
- if (dont_sync_undo == MAYBE) {
- dont_sync_undo = true;
+ if (dont_sync_undo == kNone) {
+ dont_sync_undo = kTrue;
} else {
- dont_sync_undo = false;
+ dont_sync_undo = kFalse;
}
return 1;
@@ -652,7 +668,7 @@ static int insert_execute(VimState *state, int key)
char_u *p;
if (str != NULL) {
- for (p = str; *p != NUL; mb_ptr_adv(p)) {
+ for (p = str; *p != NUL; MB_PTR_ADV(p)) {
ins_compl_addleader(PTR2CHAR(p));
}
xfree(str);
@@ -664,11 +680,12 @@ static int insert_execute(VimState *state, int key)
// Pressing CTRL-Y selects the current match. When
// compl_enter_selects is set the Enter key does the same.
- if (s->c == Ctrl_Y
- || (compl_enter_selects
- && (s->c == CAR || s->c == K_KENTER || s->c == NL))) {
+ if ((s->c == Ctrl_Y
+ || (compl_enter_selects
+ && (s->c == CAR || s->c == K_KENTER || s->c == NL)))
+ && stop_arrow() == OK) {
ins_compl_delete();
- ins_compl_insert();
+ ins_compl_insert(false);
}
}
}
@@ -686,11 +703,9 @@ static int insert_execute(VimState *state, int key)
if (s->c == Ctrl_BSL) {
// may need to redraw when no more chars available now
ins_redraw(false);
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
s->c = plain_vgetc();
- --no_mapping;
- --allow_keys;
+ no_mapping--;
if (s->c != Ctrl_N && s->c != Ctrl_G && s->c != Ctrl_O) {
// it's something else
vungetc(s->c);
@@ -769,7 +784,7 @@ static int insert_handle_key(InsertState *s)
if (echeck_abbr(ESC + ABBR_OFF)) {
break;
}
- // FALLTHROUGH
+ FALLTHROUGH;
case Ctrl_C: // End input mode
if (s->c == Ctrl_C && cmdwin_type != 0) {
@@ -797,9 +812,9 @@ static int insert_handle_key(InsertState *s)
if (!p_im) {
goto normalchar; // insert CTRL-Z as normal char
}
- stuffReadbuff((char_u *)":st\r");
- s->c = Ctrl_O;
- // FALLTHROUGH
+ do_cmdline_cmd("stop");
+ ui_cursor_shape(); // may need to update cursor shape
+ break;
case Ctrl_O: // execute one command
if (ctrl_x_mode == CTRL_X_OMNI) {
@@ -841,6 +856,11 @@ static int insert_handle_key(InsertState *s)
return 0; // exit insert mode
+ case ' ':
+ if (mod_mask != MOD_MASK_CTRL) {
+ goto normalchar;
+ }
+ FALLTHROUGH;
case K_ZERO: // Insert the previously inserted text.
case NUL:
case Ctrl_A:
@@ -879,7 +899,7 @@ static int insert_handle_key(InsertState *s)
insert_do_complete(s);
break;
}
- // FALLTHROUGH
+ FALLTHROUGH;
case Ctrl_T: // Make indent one shiftwidth greater.
if (s->c == Ctrl_T && ctrl_x_mode == CTRL_X_THESAURUS) {
@@ -961,15 +981,26 @@ static int insert_handle_key(InsertState *s)
break;
case K_EVENT: // some event
- queue_process_events(main_loop.events);
- break;
-
- case K_FOCUSGAINED: // Neovim has been given focus
- apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
- break;
-
- case K_FOCUSLOST: // Neovim has lost focus
- apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
+ multiqueue_process_events(main_loop.events);
+ goto check_pum;
+
+ case K_COMMAND: // some command
+ do_cmdline(NULL, getcmdkeycmd, NULL, 0);
+
+check_pum:
+ // TODO(bfredl): Not entirely sure this indirection is necessary
+ // but doing like this ensures using nvim_select_popupmenu_item is
+ // equivalent to selecting the item with a typed key.
+ if (pum_want.active) {
+ if (pum_visible()) {
+ insert_do_complete(s);
+ if (pum_want.finish) {
+ // accept the item and stop completion
+ ins_compl_prep(Ctrl_Y);
+ }
+ }
+ pum_want.active = false;
+ }
break;
case K_HOME: // <Home>
@@ -990,7 +1021,7 @@ static int insert_handle_key(InsertState *s)
if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) {
ins_s_left();
} else {
- ins_left(dont_sync_undo == false);
+ ins_left(dont_sync_undo == kFalse);
}
break;
@@ -1003,7 +1034,7 @@ static int insert_handle_key(InsertState *s)
if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) {
ins_s_right();
} else {
- ins_right(dont_sync_undo == false);
+ ins_right(dont_sync_undo == kFalse);
}
break;
@@ -1055,7 +1086,7 @@ static int insert_handle_key(InsertState *s)
case K_S_TAB: // When not mapped, use like a normal TAB
s->c = TAB;
- // FALLTHROUGH
+ FALLTHROUGH;
case TAB: // TAB or Complete patterns along path
if (ctrl_x_mode == CTRL_X_PATH_PATTERNS) {
@@ -1071,7 +1102,7 @@ static int insert_handle_key(InsertState *s)
case K_KENTER: // <Enter>
s->c = CAR;
- // FALLTHROUGH
+ FALLTHROUGH;
case CAR:
case NL:
// In a quickfix window a <CR> jumps to the error under the
@@ -1089,7 +1120,7 @@ static int insert_handle_key(InsertState *s)
cmdwin_result = CAR;
return 0;
}
- if (ins_eol(s->c) && !p_im) {
+ if (!ins_eol(s->c) && !p_im) {
return 0; // out of memory
}
auto_format(false, false);
@@ -1150,7 +1181,7 @@ static int insert_handle_key(InsertState *s)
}
goto normalchar;
}
- // FALLTHROUGH
+ FALLTHROUGH;
case Ctrl_P: // Do previous/next pattern completion
case Ctrl_N:
@@ -1174,6 +1205,14 @@ static int insert_handle_key(InsertState *s)
normalchar:
// Insert a normal character.
+
+ if (mod_mask == MOD_MASK_ALT || mod_mask == MOD_MASK_META) {
+ // Unmapped ALT/META chord behaves like ESC+c. #8213
+ stuffcharReadbuff(ESC);
+ stuffcharReadbuff(s->c);
+ break;
+ }
+
if (!p_paste) {
// Trigger InsertCharPre.
char_u *str = do_insert_char_pre(s->c);
@@ -1182,7 +1221,7 @@ normalchar:
if (str != NULL) {
if (*str != NUL && stop_arrow() != FAIL) {
// Insert the new value of v:char literally.
- for (p = str; *p != NUL; mb_ptr_adv(p)) {
+ for (p = str; *p != NUL; MB_PTR_ADV(p)) {
s->c = PTR2CHAR(p);
if (s->c == CAR || s->c == K_KENTER || s->c == NL) {
ins_eol(s->c);
@@ -1285,10 +1324,9 @@ bool edit(int cmdchar, bool startln, long count)
{
if (curbuf->terminal) {
if (ex_normal_busy) {
- // don't enter terminal mode from `ex_normal`, which can result in all
- // kinds of havoc(such as terminal mode recursiveness). Instead, set a
- // flag that allow us to force-set the value of `restart_edit` before
- // `ex_normal` returns
+ // Do not enter terminal mode from ex_normal(), which would cause havoc
+ // (such as terminal-mode recursiveness). Instead set a flag to force-set
+ // the value of `restart_edit` before `ex_normal` returns.
restart_edit = 'i';
force_restart_edit = true;
} else {
@@ -1339,9 +1377,7 @@ ins_redraw (
int ready /* not busy with something */
)
{
- linenr_T conceal_old_cursor_line = 0;
- linenr_T conceal_new_cursor_line = 0;
- int conceal_update_lines = FALSE;
+ bool conceal_cursor_moved = false;
if (char_avail())
return;
@@ -1362,42 +1398,61 @@ ins_redraw (
// Make sure curswant is correct, an autocommand may call
// getcurpos()
update_curswant();
- apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, false, curbuf);
- }
- if (curwin->w_p_cole > 0) {
- conceal_old_cursor_line = last_cursormoved.lnum;
- conceal_new_cursor_line = curwin->w_cursor.lnum;
- conceal_update_lines = TRUE;
+ ins_apply_autocmds(EVENT_CURSORMOVEDI);
}
+ conceal_cursor_moved = true;
last_cursormoved = curwin->w_cursor;
}
- // Trigger TextChangedI if b_changedtick differs.
+ // Trigger TextChangedI if changedtick differs.
if (ready && has_event(EVENT_TEXTCHANGEDI)
- && last_changedtick != curbuf->b_changedtick
+ && curbuf->b_last_changedtick != buf_get_changedtick(curbuf)
&& !pum_visible()) {
- if (last_changedtick_buf == curbuf) {
- apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf);
+ aco_save_T aco;
+ varnumber_T tick = buf_get_changedtick(curbuf);
+
+ // save and restore curwin and curbuf, in case the autocmd changes them
+ aucmd_prepbuf(&aco, curbuf);
+ apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf);
+ aucmd_restbuf(&aco);
+ curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
+ if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds()
+ u_save(curwin->w_cursor.lnum,
+ (linenr_T)(curwin->w_cursor.lnum + 1));
+ }
+ }
+
+ // Trigger TextChangedP if changedtick differs. When the popupmenu closes
+ // TextChangedI will need to trigger for backwards compatibility, thus use
+ // different b_last_changedtick* variables.
+ if (ready && has_event(EVENT_TEXTCHANGEDP)
+ && curbuf->b_last_changedtick_pum != buf_get_changedtick(curbuf)
+ && pum_visible()) {
+ aco_save_T aco;
+ varnumber_T tick = buf_get_changedtick(curbuf);
+
+ // save and restore curwin and curbuf, in case the autocmd changes them
+ aucmd_prepbuf(&aco, curbuf);
+ apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, false, curbuf);
+ aucmd_restbuf(&aco);
+ curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf);
+ if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds()
+ u_save(curwin->w_cursor.lnum,
+ (linenr_T)(curwin->w_cursor.lnum + 1));
}
- last_changedtick_buf = curbuf;
- last_changedtick = curbuf->b_changedtick;
}
- if (must_redraw)
+ if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)
+ && conceal_cursor_moved) {
+ redrawWinline(curwin, curwin->w_cursor.lnum);
+ }
+
+ if (must_redraw) {
update_screen(0);
- else if (clear_cmdline || redraw_cmdline)
- showmode(); /* clear cmdline and show mode */
- if ((conceal_update_lines
- && (conceal_old_cursor_line != conceal_new_cursor_line
- || conceal_cursor_line(curwin)))
- || need_cursor_line_redraw) {
- if (conceal_old_cursor_line != conceal_new_cursor_line)
- update_single_line(curwin, conceal_old_cursor_line);
- update_single_line(curwin, conceal_new_cursor_line == 0
- ? curwin->w_cursor.lnum : conceal_new_cursor_line);
- curwin->w_valid &= ~VALID_CROW;
- }
- showruler(FALSE);
+ } else if (clear_cmdline || redraw_cmdline) {
+ showmode(); // clear cmdline and show mode
+ }
+ showruler(false);
setcursor();
emsg_on_display = FALSE; /* may remove error message now */
}
@@ -1417,7 +1472,7 @@ static void ins_ctrl_v(void)
edit_putchar('^', TRUE);
did_putchar = TRUE;
}
- AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */
+ AppendToRedobuff(CTRL_V_STR);
add_to_showcmd_c(Ctrl_V);
@@ -1427,7 +1482,7 @@ static void ins_ctrl_v(void)
* line and will not removed by the redraw */
edit_unputchar();
clear_showcmd();
- insert_special(c, FALSE, TRUE);
+ insert_special(c, true, true);
revins_chars++;
revins_legal++;
}
@@ -1450,39 +1505,41 @@ void edit_putchar(int c, int highlight)
{
int attr;
- if (ScreenLines != NULL) {
- update_topline(); /* just in case w_topline isn't valid */
+ if (curwin->w_grid.chars != NULL || default_grid.chars != NULL) {
+ update_topline(); // just in case w_topline isn't valid
validate_cursor();
- if (highlight)
- attr = hl_attr(HLF_8);
- else
+ if (highlight) {
+ attr = HL_ATTR(HLF_8);
+ } else {
attr = 0;
- pc_row = curwin->w_winrow + curwin->w_wrow;
- pc_col = curwin->w_wincol;
+ }
+ pc_row = curwin->w_wrow;
+ pc_col = 0;
pc_status = PC_STATUS_UNSET;
if (curwin->w_p_rl) {
- pc_col += curwin->w_width - 1 - curwin->w_wcol;
+ pc_col += curwin->w_grid.Columns - 1 - curwin->w_wcol;
if (has_mbyte) {
- int fix_col = mb_fix_col(pc_col, pc_row);
+ int fix_col = grid_fix_col(&curwin->w_grid, pc_col, pc_row);
if (fix_col != pc_col) {
- screen_putchar(' ', pc_row, fix_col, attr);
- --curwin->w_wcol;
+ grid_putchar(&curwin->w_grid, ' ', pc_row, fix_col, attr);
+ curwin->w_wcol--;
pc_status = PC_STATUS_RIGHT;
}
}
} else {
pc_col += curwin->w_wcol;
- if (mb_lefthalve(pc_row, pc_col))
+ if (grid_lefthalve(&curwin->w_grid, pc_row, pc_col)) {
pc_status = PC_STATUS_LEFT;
+ }
}
/* save the character to be able to put it back */
if (pc_status == PC_STATUS_UNSET) {
- screen_getbytes(pc_row, pc_col, pc_bytes, &pc_attr);
+ grid_getbytes(&curwin->w_grid, pc_row, pc_col, pc_bytes, &pc_attr);
pc_status = PC_STATUS_SET;
}
- screen_putchar(c, pc_row, pc_col, attr);
+ grid_putchar(&curwin->w_grid, c, pc_row, pc_col, attr);
}
}
@@ -1492,12 +1549,15 @@ void edit_putchar(int c, int highlight)
void edit_unputchar(void)
{
if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) {
- if (pc_status == PC_STATUS_RIGHT)
- ++curwin->w_wcol;
- if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT)
- redrawWinline(curwin->w_cursor.lnum, FALSE);
- else
- screen_puts(pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr);
+ if (pc_status == PC_STATUS_RIGHT) {
+ curwin->w_wcol++;
+ }
+ if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) {
+ redrawWinline(curwin, curwin->w_cursor.lnum);
+ } else {
+ grid_puts(&curwin->w_grid, pc_bytes, pc_row - msg_scrolled, pc_col,
+ pc_attr);
+ }
}
}
@@ -1514,16 +1574,13 @@ void display_dollar(colnr_T col)
save_col = curwin->w_cursor.col;
curwin->w_cursor.col = col;
- if (has_mbyte) {
- char_u *p;
- /* If on the last byte of a multi-byte move to the first byte. */
- p = get_cursor_line_ptr();
- curwin->w_cursor.col -= (*mb_head_off)(p, p + col);
- }
- curs_columns(FALSE); /* recompute w_wrow and w_wcol */
- if (curwin->w_wcol < curwin->w_width) {
- edit_putchar('$', FALSE);
+ // If on the last byte of a multi-byte move to the first byte.
+ char_u *p = get_cursor_line_ptr();
+ curwin->w_cursor.col -= utf_head_off(p, p + col);
+ curs_columns(false); // Recompute w_wrow and w_wcol
+ if (curwin->w_wcol < curwin->w_grid.Columns) {
+ edit_putchar('$', false);
dollar_vcol = curwin->w_virtcol;
}
curwin->w_cursor.col = save_col;
@@ -1537,7 +1594,7 @@ static void undisplay_dollar(void)
{
if (dollar_vcol >= 0) {
dollar_vcol = -1;
- redrawWinline(curwin->w_cursor.lnum, FALSE);
+ redrawWinline(curwin, curwin->w_cursor.lnum);
}
}
@@ -1744,8 +1801,8 @@ change_indent (
/* We only put back the new line up to the cursor */
new_line[curwin->w_cursor.col] = NUL;
- /* Put back original line */
- ml_replace(curwin->w_cursor.lnum, orig_line, FALSE);
+ // Put back original line
+ ml_replace(curwin->w_cursor.lnum, orig_line, false);
curwin->w_cursor.col = orig_col;
/* Backspace from cursor to start of line */
@@ -1857,8 +1914,9 @@ static bool check_compl_option(bool dict_opt)
: (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) {
ctrl_x_mode = 0;
edit_submode = NULL;
- msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty")
- : (char_u *)_("'thesaurus' option is empty"), hl_attr(HLF_E));
+ msg_attr((dict_opt
+ ? _("'dictionary' option is empty")
+ : _("'thesaurus' option is empty")), HL_ATTR(HLF_E));
if (emsg_silent == 0) {
vim_beep(BO_COMPL);
setcursor();
@@ -1925,7 +1983,7 @@ bool vim_is_ctrl_x_key(int c)
case CTRL_X_EVAL:
return (c == Ctrl_P || c == Ctrl_N);
}
- EMSG(_(e_internal));
+ internal_error("vim_is_ctrl_x_key()");
return false;
}
@@ -1970,7 +2028,6 @@ static bool ins_compl_accept_char(int c)
*/
int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags)
{
- char_u *p;
int i, c;
int actual_len; /* Take multi-byte characters */
int actual_compl_length; /* into account. */
@@ -1980,26 +2037,26 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
int was_letter = FALSE;
if (p_ic && curbuf->b_p_inf && len > 0) {
- /* Infer case of completed part. */
+ // Infer case of completed part.
- /* Find actual length of completion. */
+ // Find actual length of completion.
if (has_mbyte) {
- p = str;
+ const char_u *p = str;
actual_len = 0;
while (*p != NUL) {
- mb_ptr_adv(p);
- ++actual_len;
+ MB_PTR_ADV(p);
+ actual_len++;
}
} else
actual_len = len;
/* Find actual length of original text. */
if (has_mbyte) {
- p = compl_orig_text;
+ const char_u *p = compl_orig_text;
actual_compl_length = 0;
while (*p != NUL) {
- mb_ptr_adv(p);
- ++actual_compl_length;
+ MB_PTR_ADV(p);
+ actual_compl_length++;
}
} else
actual_compl_length = compl_length;
@@ -2011,27 +2068,35 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
/* Allocate wide character array for the completion and fill it. */
wca = xmalloc(actual_len * sizeof(*wca));
- p = str;
- for (i = 0; i < actual_len; ++i)
- if (has_mbyte)
- wca[i] = mb_ptr2char_adv(&p);
- else
- wca[i] = *(p++);
+ {
+ const char_u *p = str;
+ for (i = 0; i < actual_len; i++) {
+ if (has_mbyte) {
+ wca[i] = mb_ptr2char_adv(&p);
+ } else {
+ wca[i] = *(p++);
+ }
+ }
+ }
- /* Rule 1: Were any chars converted to lower? */
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i) {
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
- c = *(p++);
- if (vim_islower(c)) {
- has_lower = TRUE;
- if (vim_isupper(wca[i])) {
- /* Rule 1 is satisfied. */
- for (i = actual_compl_length; i < actual_len; ++i)
- wca[i] = vim_tolower(wca[i]);
- break;
+ // Rule 1: Were any chars converted to lower?
+ {
+ const char_u *p = compl_orig_text;
+ for (i = 0; i < min_len; i++) {
+ if (has_mbyte) {
+ c = mb_ptr2char_adv(&p);
+ } else {
+ c = *(p++);
+ }
+ if (mb_islower(c)) {
+ has_lower = true;
+ if (mb_isupper(wca[i])) {
+ // Rule 1 is satisfied.
+ for (i = actual_compl_length; i < actual_len; i++) {
+ wca[i] = mb_tolower(wca[i]);
+ }
+ break;
+ }
}
}
}
@@ -2041,84 +2106,106 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
* upper case.
*/
if (!has_lower) {
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i) {
- if (has_mbyte)
+ const char_u *p = compl_orig_text;
+ for (i = 0; i < min_len; i++) {
+ if (has_mbyte) {
c = mb_ptr2char_adv(&p);
- else
+ } else {
c = *(p++);
- if (was_letter && vim_isupper(c) && vim_islower(wca[i])) {
- /* Rule 2 is satisfied. */
- for (i = actual_compl_length; i < actual_len; ++i)
- wca[i] = vim_toupper(wca[i]);
+ }
+ if (was_letter && mb_isupper(c) && mb_islower(wca[i])) {
+ // Rule 2 is satisfied.
+ for (i = actual_compl_length; i < actual_len; i++) {
+ wca[i] = mb_toupper(wca[i]);
+ }
break;
}
- was_letter = vim_islower(c) || vim_isupper(c);
+ was_letter = mb_islower(c) || mb_isupper(c);
}
}
- /* Copy the original case of the part we typed. */
- p = compl_orig_text;
- for (i = 0; i < min_len; ++i) {
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
- c = *(p++);
- if (vim_islower(c))
- wca[i] = vim_tolower(wca[i]);
- else if (vim_isupper(c))
- wca[i] = vim_toupper(wca[i]);
+ // Copy the original case of the part we typed.
+ {
+ const char_u *p = compl_orig_text;
+ for (i = 0; i < min_len; i++) {
+ if (has_mbyte) {
+ c = mb_ptr2char_adv(&p);
+ } else {
+ c = *(p++);
+ }
+ if (mb_islower(c)) {
+ wca[i] = mb_tolower(wca[i]);
+ } else if (mb_isupper(c)) {
+ wca[i] = mb_toupper(wca[i]);
+ }
+ }
}
- /*
- * Generate encoding specific output from wide character array.
- * Multi-byte characters can occupy up to five bytes more than
- * ASCII characters, and we also need one byte for NUL, so stay
- * six bytes away from the edge of IObuff.
- */
- p = IObuff;
- i = 0;
- while (i < actual_len && (p - IObuff + 6) < IOSIZE)
- if (has_mbyte)
- p += (*mb_char2bytes)(wca[i++], p);
- else
- *(p++) = wca[i++];
- *p = NUL;
+ // Generate encoding specific output from wide character array.
+ // Multi-byte characters can occupy up to five bytes more than
+ // ASCII characters, and we also need one byte for NUL, so stay
+ // six bytes away from the edge of IObuff.
+ {
+ char_u *p = IObuff;
+ i = 0;
+ while (i < actual_len && (p - IObuff + 6) < IOSIZE) {
+ p += utf_char2bytes(wca[i++], p);
+ }
+ *p = NUL;
+ }
xfree(wca);
- return ins_compl_add(IObuff, len, icase, fname, NULL, dir,
- flags, FALSE);
+ return ins_compl_add(IObuff, len, icase, fname, NULL, false, dir, flags,
+ false);
}
- return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE);
+ return ins_compl_add(str, len, icase, fname, NULL, false, dir, flags, false);
}
-/*
- * Add a match to the list of matches.
- * If the given string is already in the list of completions, then return
- * NOTDONE, otherwise add it to the list and return OK. If there is an error
- * then FAIL is returned.
- */
-static int
-ins_compl_add (
- char_u *str,
- int len,
- int icase,
- char_u *fname,
- char_u **cptext, /* extra text for popup menu or NULL */
- int cdir,
- int flags,
- int adup /* accept duplicate match */
-)
+/// Add a match to the list of matches
+///
+/// @param[in] str Match to add.
+/// @param[in] len Match length, -1 to use #STRLEN.
+/// @param[in] icase Whether case is to be ignored.
+/// @param[in] fname File name match comes from. May be NULL.
+/// @param[in] cptext Extra text for popup menu. May be NULL. If not NULL,
+/// must have exactly #CPT_COUNT items.
+/// @param[in] cptext_allocated If true, will not copy cptext strings.
+///
+/// @note Will free strings in case of error.
+/// cptext itself will not be freed.
+/// @param[in] cdir Completion direction.
+/// @param[in] adup True if duplicate matches are to be accepted.
+///
+/// @return NOTDONE if the given string is already in the list of completions,
+/// otherwise it is added to the list and OK is returned. FAIL will be
+/// returned in case of error.
+static int ins_compl_add(char_u *const str, int len,
+ const bool icase, char_u *const fname,
+ char_u *const *const cptext,
+ const bool cptext_allocated,
+ const Direction cdir, int flags, const bool adup)
+ FUNC_ATTR_NONNULL_ARG(1)
{
compl_T *match;
- int dir = (cdir == 0 ? compl_direction : cdir);
+ int dir = (cdir == kDirectionNotSet ? compl_direction : cdir);
os_breakcheck();
- if (got_int)
+#define FREE_CPTEXT(cptext, cptext_allocated) \
+ do { \
+ if (cptext != NULL && cptext_allocated) { \
+ for (size_t i = 0; i < CPT_COUNT; i++) { \
+ xfree(cptext[i]); \
+ } \
+ } \
+ } while (0)
+ if (got_int) {
+ FREE_CPTEXT(cptext, cptext_allocated);
return FAIL;
- if (len < 0)
+ }
+ if (len < 0) {
len = (int)STRLEN(str);
+ }
/*
* If the same match is already present, don't add it.
@@ -2126,10 +2213,12 @@ ins_compl_add (
if (compl_first_match != NULL && !adup) {
match = compl_first_match;
do {
- if ( !(match->cp_flags & ORIGINAL_TEXT)
- && STRNCMP(match->cp_str, str, len) == 0
- && match->cp_str[len] == NUL)
+ if (!(match->cp_flags & ORIGINAL_TEXT)
+ && STRNCMP(match->cp_str, str, len) == 0
+ && match->cp_str[len] == NUL) {
+ FREE_CPTEXT(cptext, cptext_allocated);
return NOTDONE;
+ }
match = match->cp_next;
} while (match != NULL && match != compl_first_match);
}
@@ -2160,16 +2249,26 @@ ins_compl_add (
else if (fname != NULL) {
match->cp_fname = vim_strsave(fname);
flags |= FREE_FNAME;
- } else
+ } else {
match->cp_fname = NULL;
+ }
match->cp_flags = flags;
if (cptext != NULL) {
int i;
- for (i = 0; i < CPT_COUNT; ++i)
- if (cptext[i] != NULL && *cptext[i] != NUL)
- match->cp_text[i] = vim_strsave(cptext[i]);
+ for (i = 0; i < CPT_COUNT; i++) {
+ if (cptext[i] == NULL) {
+ continue;
+ }
+ if (*cptext[i] != NUL) {
+ match->cp_text[i] = (cptext_allocated
+ ? cptext[i]
+ : (char_u *)xstrdup((char *)cptext[i]));
+ } else if (cptext_allocated) {
+ xfree(cptext[i]);
+ }
+ }
}
/*
@@ -2243,23 +2342,14 @@ static void ins_compl_longest_match(compl_T *match)
p = compl_leader;
s = match->cp_str;
while (*p != NUL) {
- if (has_mbyte) {
- c1 = mb_ptr2char(p);
- c2 = mb_ptr2char(s);
- } else {
- c1 = *p;
- c2 = *s;
- }
- if (match->cp_icase ? (vim_tolower(c1) != vim_tolower(c2))
- : (c1 != c2))
+ c1 = utf_ptr2char(p);
+ c2 = utf_ptr2char(s);
+
+ if (match->cp_icase ? (mb_tolower(c1) != mb_tolower(c2)) : (c1 != c2)) {
break;
- if (has_mbyte) {
- mb_ptr_adv(p);
- mb_ptr_adv(s);
- } else {
- ++p;
- ++s;
}
+ MB_PTR_ADV(p);
+ MB_PTR_ADV(s);
}
if (*p != NUL) {
@@ -2292,9 +2382,10 @@ static void ins_compl_add_matches(int num_matches, char_u **matches, int icase)
for (i = 0; i < num_matches && add_r != FAIL; i++)
if ((add_r = ins_compl_add(matches[i], -1, icase,
- NULL, NULL, dir, 0, FALSE)) == OK)
- /* if dir was BACKWARD then honor it just once */
+ NULL, NULL, false, dir, 0, false)) == OK) {
+ // If dir was BACKWARD then honor it just once.
dir = FORWARD;
+ }
FreeWild(num_matches, matches);
}
@@ -2322,7 +2413,6 @@ static int ins_compl_make_cyclic(void)
return count;
}
-
// Set variables that store noselect and noinsert behavior from the
// 'completeopt' value.
void completeopt_was_set(void)
@@ -2350,9 +2440,7 @@ void set_completion(colnr_T startcol, list_T *list)
ins_compl_prep(' ');
}
ins_compl_clear();
-
- if (stop_arrow() == FAIL)
- return;
+ ins_compl_free();
compl_direction = FORWARD;
if (startcol > curwin->w_cursor.col)
@@ -2362,8 +2450,8 @@ void set_completion(colnr_T startcol, list_T *list)
/* compl_pattern doesn't need to be set */
compl_orig_text = vim_strnsave(get_cursor_line_ptr() + compl_col,
compl_length);
- if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, 0,
- ORIGINAL_TEXT, FALSE) != OK) {
+ if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, false, 0,
+ ORIGINAL_TEXT, false) != OK) {
return;
}
@@ -2375,6 +2463,7 @@ void set_completion(colnr_T startcol, list_T *list)
compl_used_match = TRUE;
compl_cont_status = 0;
int save_w_wrow = curwin->w_wrow;
+ int save_w_leftcol = curwin->w_leftcol;
compl_curr_match = compl_first_match;
if (compl_no_insert || compl_no_select) {
@@ -2385,10 +2474,11 @@ void set_completion(colnr_T startcol, list_T *list)
} else {
ins_complete(Ctrl_N, false);
}
+ compl_enter_selects = compl_no_insert;
// Lazily show the popup menu, unless we got interrupted.
if (!compl_interrupted) {
- show_pum(save_w_wrow);
+ show_pum(save_w_wrow, save_w_leftcol);
}
ui_flush();
@@ -2471,6 +2561,7 @@ void ins_compl_show_pum(void)
int cur = -1;
colnr_T col;
int lead_len = 0;
+ bool array_changed = false;
if (!pum_wanted() || !pum_enough_matches())
return;
@@ -2482,7 +2573,8 @@ void ins_compl_show_pum(void)
update_screen(0);
if (compl_match_array == NULL) {
- /* Need to build the popup menu list. */
+ array_changed = true;
+ // Need to build the popup menu list.
compl_match_arraysize = 0;
compl = compl_first_match;
/*
@@ -2585,7 +2677,8 @@ void ins_compl_show_pum(void)
// Use the cursor to get all wrapping and other settings right.
col = curwin->w_cursor.col;
curwin->w_cursor.col = compl_col;
- pum_display(compl_match_array, compl_match_arraysize, cur);
+ pum_selected_item = cur;
+ pum_display(compl_match_array, compl_match_arraysize, cur, array_changed);
curwin->w_cursor.col = col;
}
@@ -2703,8 +2796,8 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags,
fp = mch_fopen((char *)files[i], "r"); /* open dictionary file */
if (flags != DICT_EXACT) {
vim_snprintf((char *)IObuff, IOSIZE,
- _("Scanning dictionary: %s"), (char *)files[i]);
- (void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+ _("Scanning dictionary: %s"), (char *)files[i]);
+ (void)msg_trunc_attr(IObuff, true, HL_ATTR(HLF_R));
}
if (fp == NULL) {
@@ -2775,7 +2868,7 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags,
break;
}
line_breakcheck();
- ins_compl_check_keys(50);
+ ins_compl_check_keys(50, false);
}
fclose(fp);
}
@@ -2865,6 +2958,7 @@ static void ins_compl_free(void)
} while (compl_curr_match != NULL && compl_curr_match != compl_first_match);
compl_first_match = compl_curr_match = NULL;
compl_shown_match = NULL;
+ compl_old_match = NULL;
}
static void ins_compl_clear(void)
@@ -2881,7 +2975,7 @@ static void ins_compl_clear(void)
compl_orig_text = NULL;
compl_enter_selects = FALSE;
// clear v:completed_item
- set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+ set_vim_var_dict(VV_COMPLETED_ITEM, tv_dict_alloc());
}
/// Check that Insert completion is active.
@@ -2904,13 +2998,16 @@ static int ins_compl_bs(void)
line = get_cursor_line_ptr();
p = line + curwin->w_cursor.col;
- mb_ptr_back(line, p);
+ MB_PTR_BACK(line, p);
- /* Stop completion when the whole word was deleted. For Omni completion
- * allow the word to be deleted, we won't match everything. */
+ // Stop completion when the whole word was deleted. For Omni completion
+ // allow the word to be deleted, we won't match everything.
+ // Respect the 'backspace' option.
if ((int)(p - line) - (int)compl_col < 0
|| ((int)(p - line) - (int)compl_col == 0
- && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL) {
+ && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL
+ || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col
+ - compl_length < 0)) {
return K_BS;
}
@@ -2999,10 +3096,13 @@ static void ins_compl_addleader(int c)
{
int cc;
- if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) {
+ if (stop_arrow() == FAIL) {
+ return;
+ }
+ if ((cc = utf_char2len(c)) > 1) {
char_u buf[MB_MAXBYTES + 1];
- (*mb_char2bytes)(c, buf);
+ utf_char2bytes(c, buf);
buf[cc] = NUL;
ins_char_bytes(buf, cc);
} else {
@@ -3041,10 +3141,16 @@ static void ins_compl_restart(void)
*/
static void ins_compl_set_original_text(char_u *str)
{
- /* Replace the original text entry. */
- if (compl_first_match->cp_flags & ORIGINAL_TEXT) { /* safety check */
+ // Replace the original text entry.
+ // The ORIGINAL_TEXT flag is either at the first item or might possibly be
+ // at the last item for backward completion
+ if (compl_first_match->cp_flags & ORIGINAL_TEXT) { // safety check
xfree(compl_first_match->cp_str);
compl_first_match->cp_str = vim_strsave(str);
+ } else if (compl_first_match->cp_prev != NULL
+ && (compl_first_match->cp_prev->cp_flags & ORIGINAL_TEXT)) {
+ xfree(compl_first_match->cp_prev->cp_str);
+ compl_first_match->cp_prev->cp_str = vim_strsave(str);
}
}
@@ -3104,7 +3210,7 @@ static bool ins_compl_prep(int c)
/* Ignore end of Select mode mapping and mouse scroll buttons. */
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
|| c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT
- || c == K_FOCUSGAINED || c == K_FOCUSLOST) {
+ || c == K_COMMAND) {
return retval;
}
@@ -3187,7 +3293,7 @@ static bool ins_compl_prep(int c)
compl_cont_status |= CONT_LOCAL;
else if (compl_cont_mode != 0)
compl_cont_status &= ~CONT_LOCAL;
- /* FALLTHROUGH */
+ FALLTHROUGH;
default:
/* If we have typed at least 2 ^X's... for modes != 0, we set
* compl_cont_status = 0 (eg, as if we had just started ^X
@@ -3261,14 +3367,19 @@ static bool ins_compl_prep(int c)
} else {
int prev_col = curwin->w_cursor.col;
- /* put the cursor on the last char, for 'tw' formatting */
- if (prev_col > 0)
+ // put the cursor on the last char, for 'tw' formatting
+ if (prev_col > 0) {
dec_cursor();
- if (stop_arrow() == OK)
+ }
+
+ if (!arrow_used && !ins_need_undo && c != Ctrl_E) {
insertchar(NUL, 0, -1);
+ }
+
if (prev_col > 0
- && get_cursor_line_ptr()[curwin->w_cursor.col] != NUL)
+ && get_cursor_line_ptr()[curwin->w_cursor.col] != NUL) {
inc_cursor();
+ }
}
// If the popup menu is displayed pressing CTRL-Y means accepting
@@ -3280,7 +3391,8 @@ static bool ins_compl_prep(int c)
retval = true;
}
- /* CTRL-E means completion is Ended, go back to the typed text. */
+ // CTRL-E means completion is Ended, go back to the typed text.
+ // but only do this, if the Popup is still visible
if (c == Ctrl_E) {
ins_compl_delete();
if (compl_leader != NULL) {
@@ -3319,12 +3431,12 @@ static bool ins_compl_prep(int c)
do_c_expr_indent();
/* Trigger the CompleteDone event to give scripts a chance to act
* upon the completion. */
- apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_COMPLETEDONE);
}
} else if (ctrl_x_mode == CTRL_X_LOCAL_MSG)
/* Trigger the CompleteDone event to give scripts a chance to act
* upon the (possibly failed) completion. */
- apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf);
+ ins_apply_autocmds(EVENT_COMPLETEDONE);
/* reset continue_* if we left expansion-mode, if we stay they'll be
* (re)set properly in ins_complete() */
@@ -3355,16 +3467,17 @@ static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg)
}
if (compl_orig_text != NULL) {
p = compl_orig_text;
- for (len = 0; p[len] != NUL && p[len] == ptr[len]; ++len)
- ;
- if (len > 0)
- len -= (*mb_head_off)(p, p + len);
- for (p += len; *p != NUL; mb_ptr_adv(p))
+ for (len = 0; p[len] != NUL && p[len] == ptr[len]; len++) {}
+ if (len > 0) {
+ len -= utf_head_off(p, p + len);
+ }
+ for (p += len; *p != NUL; MB_PTR_ADV(p)) {
AppendCharToRedobuff(K_BS);
- } else
+ }
+ } else {
len = 0;
- if (ptr != NULL)
- AppendToRedobuffLit(ptr + len, -1);
+ }
+ AppendToRedobuffLit(ptr + len, -1);
}
/*
@@ -3414,20 +3527,19 @@ expand_by_function (
{
list_T *matchlist = NULL;
dict_T *matchdict = NULL;
- char_u *args[2];
char_u *funcname;
pos_T pos;
win_T *curwin_save;
buf_T *curbuf_save;
typval_T rettv;
+ const int save_State = State;
funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu;
if (*funcname == NUL)
return;
- /* Call 'completefunc' to obtain the list of matches. */
- args[0] = (char_u *)"0";
- args[1] = base;
+ // Call 'completefunc' to obtain the list of matches.
+ const char_u *const args[2] = { (char_u *)"0", base };
pos = curwin->w_cursor;
curwin_save = curwin;
@@ -3443,8 +3555,8 @@ expand_by_function (
matchdict = rettv.vval.v_dict;
break;
default:
- /* TODO: Give error message? */
- clear_tv(&rettv);
+ // TODO(brammool): Give error message?
+ tv_clear(&rettv);
break;
}
}
@@ -3466,28 +3578,33 @@ expand_by_function (
ins_compl_add_dict(matchdict);
theend:
- if (matchdict != NULL)
- dict_unref(matchdict);
- if (matchlist != NULL)
- list_unref(matchlist);
+ // Restore State, it might have been changed.
+ State = save_State;
+
+ if (matchdict != NULL) {
+ tv_dict_unref(matchdict);
+ }
+ if (matchlist != NULL) {
+ tv_list_unref(matchlist);
+ }
}
/*
* Add completions from a list.
*/
-static void ins_compl_add_list(list_T *list)
+static void ins_compl_add_list(list_T *const list)
{
- listitem_T *li;
int dir = compl_direction;
- /* Go through the List with matches and add each of them. */
- for (li = list->lv_first; li != NULL; li = li->li_next) {
- if (ins_compl_add_tv(&li->li_tv, dir) == OK)
- /* if dir was BACKWARD then honor it just once */
+ // Go through the List with matches and add each of them.
+ TV_LIST_ITER(list, li, {
+ if (ins_compl_add_tv(TV_LIST_ITEM_TV(li), dir) == OK) {
+ // If dir was BACKWARD then honor it just once.
dir = FORWARD;
- else if (did_emsg)
+ } else if (did_emsg) {
break;
- }
+ }
+ });
}
/*
@@ -3498,59 +3615,65 @@ static void ins_compl_add_dict(dict_T *dict)
dictitem_T *di_refresh;
dictitem_T *di_words;
- /* Check for optional "refresh" item. */
- compl_opt_refresh_always = FALSE;
- di_refresh = dict_find(dict, (char_u *)"refresh", 7);
+ // Check for optional "refresh" item.
+ compl_opt_refresh_always = false;
+ di_refresh = tv_dict_find(dict, S_LEN("refresh"));
if (di_refresh != NULL && di_refresh->di_tv.v_type == VAR_STRING) {
- char_u *v = di_refresh->di_tv.vval.v_string;
+ const char *v = (const char *)di_refresh->di_tv.vval.v_string;
- if (v != NULL && STRCMP(v, (char_u *)"always") == 0)
- compl_opt_refresh_always = TRUE;
+ if (v != NULL && strcmp(v, "always") == 0) {
+ compl_opt_refresh_always = true;
+ }
}
- /* Add completions from a "words" list. */
- di_words = dict_find(dict, (char_u *)"words", 5);
- if (di_words != NULL && di_words->di_tv.v_type == VAR_LIST)
+ // Add completions from a "words" list.
+ di_words = tv_dict_find(dict, S_LEN("words"));
+ if (di_words != NULL && di_words->di_tv.v_type == VAR_LIST) {
ins_compl_add_list(di_words->di_tv.vval.v_list);
+ }
}
-/*
- * Add a match to the list of matches from a typeval_T.
- * If the given string is already in the list of completions, then return
- * NOTDONE, otherwise add it to the list and return OK. If there is an error
- * then FAIL is returned.
- */
-int ins_compl_add_tv(typval_T *tv, int dir)
-{
- char_u *word;
- int icase = FALSE;
- int adup = FALSE;
- int aempty = FALSE;
- char_u *(cptext[CPT_COUNT]);
+/// Add a match to the list of matches from VimL object
+///
+/// @param[in] tv Object to get matches from.
+/// @param[in] dir Completion direction.
+///
+/// @return NOTDONE if the given string is already in the list of completions,
+/// otherwise it is added to the list and OK is returned. FAIL will be
+/// returned in case of error.
+int ins_compl_add_tv(typval_T *const tv, const Direction dir)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const char *word;
+ bool icase = false;
+ bool adup = false;
+ bool aempty = false;
+ char *(cptext[CPT_COUNT]);
if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) {
- word = get_dict_string(tv->vval.v_dict, (char_u *)"word", FALSE);
- cptext[CPT_ABBR] = get_dict_string(tv->vval.v_dict,
- (char_u *)"abbr", FALSE);
- cptext[CPT_MENU] = get_dict_string(tv->vval.v_dict,
- (char_u *)"menu", FALSE);
- cptext[CPT_KIND] = get_dict_string(tv->vval.v_dict,
- (char_u *)"kind", FALSE);
- cptext[CPT_INFO] = get_dict_string(tv->vval.v_dict,
- (char_u *)"info", FALSE);
- if (get_dict_string(tv->vval.v_dict, (char_u *)"icase", FALSE) != NULL)
- icase = get_dict_number(tv->vval.v_dict, (char_u *)"icase");
- if (get_dict_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL)
- adup = get_dict_number(tv->vval.v_dict, (char_u *)"dup");
- if (get_dict_string(tv->vval.v_dict, (char_u *)"empty", FALSE) != NULL)
- aempty = get_dict_number(tv->vval.v_dict, (char_u *)"empty");
+ word = tv_dict_get_string(tv->vval.v_dict, "word", false);
+ cptext[CPT_ABBR] = tv_dict_get_string(tv->vval.v_dict, "abbr", true);
+ cptext[CPT_MENU] = tv_dict_get_string(tv->vval.v_dict, "menu", true);
+ cptext[CPT_KIND] = tv_dict_get_string(tv->vval.v_dict, "kind", true);
+ cptext[CPT_INFO] = tv_dict_get_string(tv->vval.v_dict, "info", true);
+ cptext[CPT_USER_DATA] = tv_dict_get_string(tv->vval.v_dict,
+ "user_data", true);
+
+ icase = (bool)tv_dict_get_number(tv->vval.v_dict, "icase");
+ adup = (bool)tv_dict_get_number(tv->vval.v_dict, "dup");
+ aempty = (bool)tv_dict_get_number(tv->vval.v_dict, "empty");
} else {
- word = get_tv_string_chk(tv);
+ word = (const char *)tv_get_string_chk(tv);
memset(cptext, 0, sizeof(cptext));
}
- if (word == NULL || (!aempty && *word == NUL))
+ if (word == NULL || (!aempty && *word == NUL)) {
+ for (size_t i = 0; i < CPT_COUNT; i++) {
+ xfree(cptext[i]);
+ }
return FAIL;
- return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup);
+ }
+ return ins_compl_add((char_u *)word, -1, icase, NULL,
+ (char_u **)cptext, true, dir, 0, adup);
}
/*
@@ -3584,7 +3707,6 @@ static int ins_compl_get_exp(pos_T *ini)
char_u *ptr;
char_u *dict = NULL;
int dict_f = 0;
- compl_T *old_match;
int set_match_pos;
int l_ctrl_x_mode = ctrl_x_mode;
@@ -3599,7 +3721,7 @@ static int ins_compl_get_exp(pos_T *ini)
last_match_pos = first_match_pos = *ini;
}
- old_match = compl_curr_match; /* remember the last current match */
+ compl_old_match = compl_curr_match; // remember the last current match
pos = (compl_direction == FORWARD) ? &last_match_pos : &first_match_pos;
/* For ^N/^P loop over all the flags/windows/buffers in 'complete' */
for (;; ) {
@@ -3619,9 +3741,15 @@ static int ins_compl_get_exp(pos_T *ini)
if (*e_cpt == '.' && !curbuf->b_scanned) {
ins_buf = curbuf;
first_match_pos = *ini;
- /* So that ^N can match word immediately after cursor */
- if (l_ctrl_x_mode == 0)
- dec(&first_match_pos);
+ // Move the cursor back one character so that ^N can match the
+ // word immediately after the cursor.
+ if (ctrl_x_mode == 0 && dec(&first_match_pos) < 0) {
+ // Move the cursor to after the last character in the
+ // buffer, so that word at start of buffer is found
+ // correctly.
+ first_match_pos.lnum = ins_buf->b_ml.ml_line_count;
+ first_match_pos.col = (colnr_T)STRLEN(ml_get(first_match_pos.lnum));
+ }
last_match_pos = first_match_pos;
type = 0;
@@ -3647,15 +3775,15 @@ static int ins_compl_get_exp(pos_T *ini)
dict_f = DICT_EXACT;
}
vim_snprintf((char *)IObuff, IOSIZE, _("Scanning: %s"),
- ins_buf->b_fname == NULL
- ? buf_spname(ins_buf)
- : ins_buf->b_sfname == NULL
- ? ins_buf->b_fname
- : ins_buf->b_sfname);
- (void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
- } else if (*e_cpt == NUL)
+ ins_buf->b_fname == NULL
+ ? buf_spname(ins_buf)
+ : ins_buf->b_sfname == NULL
+ ? ins_buf->b_fname
+ : ins_buf->b_sfname);
+ (void)msg_trunc_attr(IObuff, true, HL_ATTR(HLF_R));
+ } else if (*e_cpt == NUL) {
break;
- else {
+ } else {
if (CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode)) {
type = -1;
} else if (*e_cpt == 'k' || *e_cpt == 's') {
@@ -3674,9 +3802,10 @@ static int ins_compl_get_exp(pos_T *ini)
else if (*e_cpt == ']' || *e_cpt == 't') {
type = CTRL_X_TAGS;
vim_snprintf((char *)IObuff, IOSIZE, _("Scanning tags."));
- (void)msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
- } else
+ (void)msg_trunc_attr(IObuff, true, HL_ATTR(HLF_R));
+ } else {
type = -1;
+ }
/* in any case e_cpt is advanced to the next entry */
(void)copy_option_part(&e_cpt, IObuff, IOSIZE, ",");
@@ -3687,6 +3816,12 @@ static int ins_compl_get_exp(pos_T *ini)
}
}
+ // If complete() was called then compl_pattern has been reset.
+ // The following won't work then, bail out.
+ if (compl_pattern == NULL) {
+ break;
+ }
+
switch (type) {
case -1:
break;
@@ -3846,13 +3981,11 @@ static int ins_compl_get_exp(pos_T *ini)
if ((compl_cont_status & CONT_ADDING)
&& len == compl_length) {
if (pos->lnum < ins_buf->b_ml.ml_line_count) {
- /* Try next line, if any. the new word will be
- * "join" as if the normal command "J" was used.
- * IOSIZE is always greater than
- * compl_length, so the next STRNCPY always
- * works -- Acevedo */
+ // Try next line, if any. the new word will be "join" as if the
+ // normal command "J" was used. IOSIZE is always greater than
+ // compl_length, so the next STRNCPY always works -- Acevedo
STRNCPY(IObuff, ptr, len);
- ptr = ml_get_buf(ins_buf, pos->lnum + 1, FALSE);
+ ptr = ml_get_buf(ins_buf, pos->lnum + 1, false);
tmp_ptr = ptr = skipwhite(ptr);
/* Find start of next word. */
tmp_ptr = find_word_start(tmp_ptr);
@@ -3895,10 +4028,11 @@ static int ins_compl_get_exp(pos_T *ini)
p_ws = save_p_ws;
}
- /* check if compl_curr_match has changed, (e.g. other type of
- * expansion added something) */
- if (type != 0 && compl_curr_match != old_match)
+ // check if compl_curr_match has changed, (e.g. other type of
+ // expansion added something)
+ if (type != 0 && compl_curr_match != compl_old_match) {
found_new_match = OK;
+ }
/* break the loop for specialized modes (use 'complete' just for the
* generic l_ctrl_x_mode == 0) or when we've found a new match */
@@ -3908,7 +4042,7 @@ static int ins_compl_get_exp(pos_T *ini)
break;
/* Fill the popup menu as soon as possible. */
if (type != -1)
- ins_compl_check_keys(0);
+ ins_compl_check_keys(0, false);
if ((l_ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(l_ctrl_x_mode))
|| compl_interrupted) {
@@ -3938,36 +4072,45 @@ static int ins_compl_get_exp(pos_T *ini)
i = ins_compl_make_cyclic();
}
- /* If several matches were added (FORWARD) or the search failed and has
- * just been made cyclic then we have to move compl_curr_match to the next
- * or previous entry (if any) -- Acevedo */
- compl_curr_match = compl_direction == FORWARD ? old_match->cp_next
- : old_match->cp_prev;
- if (compl_curr_match == NULL)
- compl_curr_match = old_match;
+ if (compl_old_match != NULL) {
+ // If several matches were added (FORWARD) or the search failed and has
+ // just been made cyclic then we have to move compl_curr_match to the
+ // next or previous entry (if any) -- Acevedo
+ compl_curr_match = compl_direction == FORWARD
+ ? compl_old_match->cp_next
+ : compl_old_match->cp_prev;
+ if (compl_curr_match == NULL) {
+ compl_curr_match = compl_old_match;
+ }
+ }
return i;
}
/* Delete the old text being completed. */
static void ins_compl_delete(void)
{
- int i;
+ int col;
- /*
- * In insert mode: Delete the typed part.
- * In replace mode: Put the old characters back, if any.
- */
- i = compl_col + (compl_cont_status & CONT_ADDING ? compl_length : 0);
- backspace_until_column(i);
- // TODO: is this sufficient for redrawing? Redrawing everything causes
- // flicker, thus we can't do that.
+ // In insert mode: Delete the typed part.
+ // In replace mode: Put the old characters back, if any.
+ col = compl_col + (compl_cont_status & CONT_ADDING ? compl_length : 0);
+ if ((int)curwin->w_cursor.col > col) {
+ if (stop_arrow() == FAIL) {
+ return;
+ }
+ backspace_until_column(col);
+ }
+
+ // TODO(vim): is this sufficient for redrawing? Redrawing everything
+ // causes flicker, thus we can't do that.
changed_cline_bef_curs();
// clear v:completed_item
- set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+ set_vim_var_dict(VV_COMPLETED_ITEM, tv_dict_alloc());
}
-/* Insert the new text being completed. */
-static void ins_compl_insert(void)
+// Insert the new text being completed.
+// "in_compl_func" is TRUE when called from complete_check().
+static void ins_compl_insert(int in_compl_func)
{
ins_bytes(compl_shown_match->cp_str + ins_compl_len());
if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
@@ -3977,18 +4120,29 @@ static void ins_compl_insert(void)
// Set completed item.
// { word, abbr, menu, kind, info }
- dict_T *dict = dict_alloc();
- dict_add_nr_str(dict, "word", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_str));
- dict_add_nr_str(dict, "abbr", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_ABBR]));
- dict_add_nr_str(dict, "menu", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_MENU]));
- dict_add_nr_str(dict, "kind", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_KIND]));
- dict_add_nr_str(dict, "info", 0L,
- EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_INFO]));
+ dict_T *dict = tv_dict_alloc();
+ tv_dict_add_str(
+ dict, S_LEN("word"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_str));
+ tv_dict_add_str(
+ dict, S_LEN("abbr"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_ABBR]));
+ tv_dict_add_str(
+ dict, S_LEN("menu"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_MENU]));
+ tv_dict_add_str(
+ dict, S_LEN("kind"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_KIND]));
+ tv_dict_add_str(
+ dict, S_LEN("info"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_INFO]));
+ tv_dict_add_str(
+ dict, S_LEN("user_data"),
+ (const char *)EMPTY_IF_NULL(compl_shown_match->cp_text[CPT_USER_DATA]));
set_vim_var_dict(VV_COMPLETED_ITEM, dict);
+ if (!in_compl_func) {
+ compl_curr_match = compl_shown_match;
+ }
}
/*
@@ -4010,13 +4164,13 @@ static void ins_compl_insert(void)
static int
ins_compl_next (
int allow_get_expansion,
- int count, /* repeat completion this many times; should
- be at least 1 */
- int insert_match /* Insert the newly selected match */
+ int count, // Repeat completion this many times; should
+ // be at least 1
+ int insert_match, // Insert the newly selected match
+ int in_compl_func // Called from complete_check()
)
{
int num_matches = -1;
- int i;
int todo = count;
compl_T *found_compl = NULL;
int found_end = FALSE;
@@ -4142,7 +4296,7 @@ ins_compl_next (
compl_used_match = FALSE;
} else if (insert_match) {
if (!compl_get_longest || compl_used_match) {
- ins_compl_insert();
+ ins_compl_insert(in_compl_func);
} else {
ins_bytes(compl_leader + ins_compl_len());
}
@@ -4178,28 +4332,51 @@ ins_compl_next (
* Truncate the file name to avoid a wait for return.
*/
if (compl_shown_match->cp_fname != NULL) {
- STRCPY(IObuff, "match in file ");
- i = (vim_strsize(compl_shown_match->cp_fname) + 16) - sc_col;
- if (i <= 0)
- i = 0;
- else
- STRCAT(IObuff, "<");
- STRCAT(IObuff, compl_shown_match->cp_fname + i);
- msg(IObuff);
- redraw_cmdline = FALSE; /* don't overwrite! */
+ char *lead = _("match in file");
+ int space = sc_col - vim_strsize((char_u *)lead) - 2;
+ char_u *s;
+ char_u *e;
+
+ if (space > 0) {
+ // We need the tail that fits. With double-byte encoding going
+ // back from the end is very slow, thus go from the start and keep
+ // the text that fits in "space" between "s" and "e".
+ for (s = e = compl_shown_match->cp_fname; *e != NUL; MB_PTR_ADV(e)) {
+ space -= ptr2cells(e);
+ while (space < 0) {
+ space += ptr2cells(s);
+ MB_PTR_ADV(s);
+ }
+ }
+ vim_snprintf((char *)IObuff, IOSIZE, "%s %s%s", lead,
+ s > compl_shown_match->cp_fname ? "<" : "", s);
+ msg(IObuff);
+ redraw_cmdline = false; // don't overwrite!
+ }
}
return num_matches;
}
-/*
- * Call this while finding completions, to check whether the user has hit a key
- * that should change the currently displayed completion, or exit completion
- * mode. Also, when compl_pending is not zero, show a completion as soon as
- * possible. -- webb
- * "frequency" specifies out of how many calls we actually check.
- */
-void ins_compl_check_keys(int frequency)
+void pum_ext_select_item(int item, bool insert, bool finish)
+{
+ if (!pum_visible() || item < -1 || item >= compl_match_arraysize) {
+ return;
+ }
+ pum_want.active = true;
+ pum_want.item = item;
+ pum_want.insert = insert;
+ pum_want.finish = finish;
+}
+
+// Call this while finding completions, to check whether the user has hit a key
+// that should change the currently displayed completion, or exit completion
+// mode. Also, when compl_pending is not zero, show a completion as soon as
+// possible. -- webb
+// "frequency" specifies out of how many calls we actually check.
+// "in_compl_func" is TRUE when called from complete_check(), don't set
+// compl_curr_match.
+void ins_compl_check_keys(int frequency, int in_compl_func)
{
static int count = 0;
@@ -4222,8 +4399,8 @@ void ins_compl_check_keys(int frequency)
if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R) {
c = safe_vgetc(); /* Eat the character */
compl_shows_dir = ins_compl_key2dir(c);
- (void)ins_compl_next(FALSE, ins_compl_key2count(c),
- c != K_UP && c != K_DOWN);
+ (void)ins_compl_next(false, ins_compl_key2count(c),
+ c != K_UP && c != K_DOWN, in_compl_func);
} else {
/* Need to get the character to have KeyTyped set. We'll put it
* back with vungetc() below. But skip K_IGNORE. */
@@ -4242,7 +4419,7 @@ void ins_compl_check_keys(int frequency)
int todo = compl_pending > 0 ? compl_pending : -compl_pending;
compl_pending = 0;
- (void)ins_compl_next(FALSE, todo, TRUE);
+ (void)ins_compl_next(false, todo, true, in_compl_func);
}
}
@@ -4252,6 +4429,9 @@ void ins_compl_check_keys(int frequency)
*/
static int ins_compl_key2dir(int c)
{
+ if (c == K_EVENT || c == K_COMMAND) {
+ return pum_want.item < pum_selected_item ? BACKWARD : FORWARD;
+ }
if (c == Ctrl_P || c == Ctrl_L
|| c == K_PAGEUP || c == K_KPAGEUP
|| c == K_S_UP || c == K_UP) {
@@ -4279,6 +4459,11 @@ static int ins_compl_key2count(int c)
{
int h;
+ if (c == K_EVENT || c == K_COMMAND) {
+ int offset = pum_want.item - pum_selected_item;
+ return abs(offset);
+ }
+
if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN) {
h = pum_get_height();
if (h > 3)
@@ -4305,6 +4490,9 @@ static bool ins_compl_use_match(int c)
case K_KPAGEUP:
case K_S_UP:
return false;
+ case K_EVENT:
+ case K_COMMAND:
+ return pum_want.active && pum_want.insert;
}
return true;
}
@@ -4321,17 +4509,23 @@ static int ins_complete(int c, bool enable_pum)
colnr_T curs_col; /* cursor column */
int n;
int save_w_wrow;
+ int save_w_leftcol;
+ int insert_match;
+ const bool save_did_ai = did_ai;
compl_direction = ins_compl_key2dir(c);
+ insert_match = ins_compl_use_match(c);
+
if (!compl_started) {
/* First time we hit ^N or ^P (in a row, I mean) */
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
- if (stop_arrow() == FAIL)
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
+ if (stop_arrow() == FAIL) {
return FAIL;
+ }
line = ml_get(curwin->w_cursor.lnum);
curs_col = curwin->w_cursor.col;
@@ -4357,7 +4551,7 @@ static int ins_complete(int c, bool enable_pum)
* first non_blank in the line, if it is not a wordchar
* include it to get a better pattern, but then we don't
* want the "\\<" prefix, check it bellow */
- compl_col = (colnr_T)(skipwhite(line) - line);
+ compl_col = (colnr_T)getwhitecols(line);
compl_startpos.col = compl_col;
compl_startpos.lnum = curwin->w_cursor.lnum;
compl_cont_status &= ~CONT_SOL; /* clear SOL if present */
@@ -4438,24 +4632,17 @@ static int ins_complete(int c, bool enable_pum)
compl_col += curs_col;
compl_length = 0;
} else {
- /* Search the point of change class of multibyte character
- * or not a word single byte character backward. */
- if (has_mbyte) {
- int base_class;
- int head_off;
-
- startcol -= (*mb_head_off)(line, line + startcol);
- base_class = mb_get_class(line + startcol);
- while (--startcol >= 0) {
- head_off = (*mb_head_off)(line, line + startcol);
- if (base_class != mb_get_class(line + startcol
- - head_off))
- break;
- startcol -= head_off;
+ // Search the point of change class of multibyte character
+ // or not a word single byte character backward.
+ startcol -= utf_head_off(line, line + startcol);
+ int base_class = mb_get_class(line + startcol);
+ while (--startcol >= 0) {
+ int head_off = utf_head_off(line, line + startcol);
+ if (base_class != mb_get_class(line + startcol - head_off)) {
+ break;
}
- } else
- while (--startcol >= 0 && vim_iswordc(line[startcol]))
- ;
+ startcol -= head_off;
+ }
compl_col += ++startcol;
compl_length = (int)curs_col - startcol;
if (compl_length == 1) {
@@ -4476,7 +4663,7 @@ static int ins_complete(int c, bool enable_pum)
}
}
} else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) {
- compl_col = (colnr_T)(skipwhite(line) - line);
+ compl_col = (colnr_T)getwhitecols(line);
compl_length = (int)curs_col - (int)compl_col;
if (compl_length < 0) /* cursor in indent: empty pattern */
compl_length = 0;
@@ -4489,13 +4676,15 @@ static int ins_complete(int c, bool enable_pum)
if (startcol > 0) {
char_u *p = line + startcol;
- mb_ptr_back(line, p);
- while (p > line && vim_isfilec(PTR2CHAR(p)))
- mb_ptr_back(line, p);
- if (p == line && vim_isfilec(PTR2CHAR(p)))
+ MB_PTR_BACK(line, p);
+ while (p > line && vim_isfilec(PTR2CHAR(p))) {
+ MB_PTR_BACK(line, p);
+ }
+ if (p == line && vim_isfilec(PTR2CHAR(p))) {
startcol = 0;
- else
+ } else {
startcol = (int)(p - line) + 1;
+ }
}
compl_col += startcol;
@@ -4504,14 +4693,15 @@ static int ins_complete(int c, bool enable_pum)
} else if (ctrl_x_mode == CTRL_X_CMDLINE) {
compl_pattern = vim_strnsave(line, curs_col);
set_cmd_context(&compl_xp, compl_pattern,
- (int)STRLEN(compl_pattern), curs_col);
+ (int)STRLEN(compl_pattern), curs_col, false);
if (compl_xp.xp_context == EXPAND_UNSUCCESSFUL
- || compl_xp.xp_context == EXPAND_NOTHING)
- /* No completion possible, use an empty pattern to get a
- * "pattern not found" message. */
+ || compl_xp.xp_context == EXPAND_NOTHING) {
+ // No completion possible, use an empty pattern to get a
+ // "pattern not found" message.
compl_col = curs_col;
- else
+ } else {
compl_col = (int)(compl_xp.xp_pattern - compl_pattern);
+ }
compl_length = curs_col - compl_col;
} else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode ==
CTRL_X_OMNI) {
@@ -4519,12 +4709,12 @@ static int ins_complete(int c, bool enable_pum)
* Call user defined function 'completefunc' with "a:findstart"
* set to 1 to obtain the length of text to use for completion.
*/
- char_u *args[2];
int col;
char_u *funcname;
pos_T pos;
win_T *curwin_save;
buf_T *curbuf_save;
+ const int save_State = State;
/* Call 'completefunc' or 'omnifunc' and get pattern length as a
* string */
@@ -4533,15 +4723,18 @@ static int ins_complete(int c, bool enable_pum)
if (*funcname == NUL) {
EMSG2(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION
? "completefunc" : "omnifunc");
+ // restore did_ai, so that adding comment leader works
+ did_ai = save_did_ai;
return FAIL;
}
- args[0] = (char_u *)"1";
- args[1] = NULL;
+ const char_u *const args[2] = { (char_u *)"1", NULL };
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
- col = call_func_retnr(funcname, 2, args, FALSE);
+ col = call_func_retnr(funcname, 2, args, false);
+
+ State = save_State;
if (curwin_save != curwin || curbuf_save != curbuf) {
EMSG(_(e_complwin));
return FAIL;
@@ -4602,7 +4795,7 @@ static int ins_complete(int c, bool enable_pum)
line = ml_get(curwin->w_cursor.lnum);
compl_pattern = vim_strnsave(line + compl_col, compl_length);
} else {
- EMSG2(_(e_intern2), "ins_complete()");
+ internal_error("ins_complete()");
return FAIL;
}
@@ -4637,8 +4830,8 @@ static int ins_complete(int c, bool enable_pum)
/* Always add completion for the original text. */
xfree(compl_orig_text);
compl_orig_text = vim_strnsave(line + compl_col, compl_length);
- if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, 0,
- ORIGINAL_TEXT, FALSE) != OK) {
+ if (ins_compl_add(compl_orig_text, -1, p_ic, NULL, NULL, false, 0,
+ ORIGINAL_TEXT, false) != OK) {
xfree(compl_pattern);
compl_pattern = NULL;
xfree(compl_orig_text);
@@ -4655,6 +4848,8 @@ static int ins_complete(int c, bool enable_pum)
showmode();
edit_submode_extra = NULL;
ui_flush();
+ } else if (insert_match && stop_arrow() == FAIL) {
+ return FAIL;
}
compl_shown_match = compl_curr_match;
@@ -4664,7 +4859,8 @@ static int ins_complete(int c, bool enable_pum)
* Find next match (and following matches).
*/
save_w_wrow = curwin->w_wrow;
- n = ins_compl_next(TRUE, ins_compl_key2count(c), ins_compl_use_match(c));
+ save_w_leftcol = curwin->w_leftcol;
+ n = ins_compl_next(true, ins_compl_key2count(c), insert_match, false);
/* may undisplay the popup menu */
ins_compl_upd_pum();
@@ -4787,9 +4983,9 @@ static int ins_complete(int c, bool enable_pum)
if (!shortmess(SHM_COMPLETIONMENU)) {
if (edit_submode_extra != NULL) {
if (!p_smd) {
- msg_attr(edit_submode_extra,
- edit_submode_highl < HLF_COUNT
- ? hl_attr(edit_submode_highl) : 0);
+ msg_attr((const char *)edit_submode_extra,
+ (edit_submode_highl < HLF_COUNT
+ ? HL_ATTR(edit_submode_highl) : 0));
}
} else {
msg_clr_cmdline(); // necessary for "noshowmode"
@@ -4798,7 +4994,7 @@ static int ins_complete(int c, bool enable_pum)
// Show the popup menu, unless we got interrupted.
if (enable_pum && !compl_interrupted) {
- show_pum(save_w_wrow);
+ show_pum(save_w_wrow, save_w_leftcol);
}
compl_was_interrupted = compl_interrupted;
compl_interrupted = FALSE;
@@ -4824,14 +5020,17 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len)
if (ctrl_x_mode == CTRL_X_DICTIONARY
|| ctrl_x_mode == CTRL_X_THESAURUS)
break;
+ FALLTHROUGH;
case '~':
if (!p_magic) /* quote these only if magic is set */
break;
+ FALLTHROUGH;
case '\\':
if (ctrl_x_mode == CTRL_X_DICTIONARY
|| ctrl_x_mode == CTRL_X_THESAURUS)
break;
- case '^': /* currently it's not needed. */
+ FALLTHROUGH;
+ case '^': // currently it's not needed.
case '$':
m++;
if (dest != NULL)
@@ -4959,13 +5158,11 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
char_u *p;
int len;
- /*
- * Special function key, translate into "<Key>". Up to the last '>' is
- * inserted with ins_str(), so as not to replace characters in replace
- * mode.
- * Only use mod_mask for special keys, to avoid things like <S-Space>,
- * unless 'allow_modmask' is TRUE.
- */
+ // Special function key, translate into "<Key>". Up to the last '>' is
+ // inserted with ins_str(), so as not to replace characters in replace
+ // mode.
+ // Only use mod_mask for special keys, to avoid things like <S-Space>,
+ // unless 'allow_modmask' is TRUE.
if (mod_mask & MOD_MASK_CMD) { // Command-key never produces a normal key.
allow_modmask = true;
}
@@ -5124,10 +5321,10 @@ insertchar (
}
end_comment_pending = NUL;
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
// If there's any pending input, grab up to INPUT_BUFLEN at once.
// This speeds up normal text input considerably.
@@ -5150,28 +5347,27 @@ insertchar (
buf[0] = c;
i = 1;
- if (textwidth > 0)
+ if (textwidth > 0) {
virtcol = get_nolist_virtcol();
- /*
- * Stop the string when:
- * - no more chars available
- * - finding a special character (command key)
- * - buffer is full
- * - running into the 'textwidth' boundary
- * - need to check for abbreviation: A non-word char after a word-char
- */
- while ( (c = vpeekc()) != NUL
- && !ISSPECIAL(c)
- && (!has_mbyte || MB_BYTE2LEN_CHECK(c) == 1)
- && i < INPUT_BUFLEN
- && (textwidth == 0
- || (virtcol += byte2cells(buf[i - 1])) < (colnr_T)textwidth)
- && !(!no_abbr && !vim_iswordc(c) && vim_iswordc(buf[i - 1]))) {
+ }
+ // Stop the string when:
+ // - no more chars available
+ // - finding a special character (command key)
+ // - buffer is full
+ // - running into the 'textwidth' boundary
+ // - need to check for abbreviation: A non-word char after a word-char
+ while ((c = vpeekc()) != NUL
+ && !ISSPECIAL(c)
+ && MB_BYTE2LEN(c) == 1
+ && i < INPUT_BUFLEN
+ && !(p_fkmap && KeyTyped) // Farsi mode mapping moves cursor
+ && (textwidth == 0
+ || (virtcol += byte2cells(buf[i - 1])) < (colnr_T)textwidth)
+ && !(!no_abbr && !vim_iswordc(c) && vim_iswordc(buf[i - 1]))) {
c = vgetc();
- if (p_hkmap && KeyTyped)
- c = hkmap(c); /* Hebrew mode mapping */
- if (p_fkmap && KeyTyped)
- c = fkmap(c); /* Farsi mode mapping */
+ if (p_hkmap && KeyTyped) {
+ c = hkmap(c); // Hebrew mode mapping
+ }
buf[i++] = c;
}
@@ -5189,10 +5385,10 @@ insertchar (
} else {
int cc;
- if (has_mbyte && (cc = (*mb_char2len)(c)) > 1) {
+ if ((cc = utf_char2len(c)) > 1) {
char_u buf[MB_MAXBYTES + 1];
- (*mb_char2bytes)(c, buf);
+ utf_char2bytes(c, buf);
buf[cc] = NUL;
ins_char_bytes(buf, cc);
AppendCharToRedobuff(c);
@@ -5223,7 +5419,7 @@ internal_format (
{
int cc;
int save_char = NUL;
- int haveto_redraw = FALSE;
+ bool haveto_redraw = false;
int fo_ins_blank = has_format_option(FO_INS_BLANK);
int fo_multibyte = has_format_option(FO_MBYTE_BREAK);
int fo_white_par = has_format_option(FO_WHITE_PAR);
@@ -5511,13 +5707,13 @@ internal_format (
curwin->w_cursor.col = len;
}
- haveto_redraw = TRUE;
- can_cindent = TRUE;
- /* moved the cursor, don't autoindent or cindent now */
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
+ haveto_redraw = true;
+ can_cindent = true;
+ // moved the cursor, don't autoindent or cindent now
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
line_breakcheck();
}
@@ -5558,8 +5754,8 @@ auto_format (
pos = curwin->w_cursor;
old = get_cursor_line_ptr();
- /* may remove added space */
- check_auto_format(FALSE);
+ // may remove added space
+ check_auto_format(false);
/* Don't format in Insert mode when the cursor is on a trailing blank, the
* user might insert normal text next. Also skip formatting when "1" is
@@ -5625,12 +5821,13 @@ auto_format (
pnew = vim_strnsave(new, len + 2);
pnew[len] = ' ';
pnew[len + 1] = NUL;
- ml_replace(curwin->w_cursor.lnum, pnew, FALSE);
- /* remove the space later */
- did_add_space = TRUE;
- } else
- /* may remove added space */
- check_auto_format(FALSE);
+ ml_replace(curwin->w_cursor.lnum, pnew, false);
+ // remove the space later
+ did_add_space = true;
+ } else {
+ // may remove added space
+ check_auto_format(false);
+ }
}
check_cursor();
@@ -5641,9 +5838,8 @@ auto_format (
* delete it now. The space must be under the cursor, just after the insert
* position.
*/
-static void
-check_auto_format (
- int end_insert /* TRUE when ending Insert mode */
+static void check_auto_format(
+ bool end_insert // true when ending Insert mode
)
{
int c = ' ';
@@ -5651,19 +5847,19 @@ check_auto_format (
if (did_add_space) {
cc = gchar_cursor();
- if (!WHITECHAR(cc))
- /* Somehow the space was removed already. */
- did_add_space = FALSE;
- else {
+ if (!WHITECHAR(cc)) {
+ // Somehow the space was removed already.
+ did_add_space = false;
+ } else {
if (!end_insert) {
inc_cursor();
c = gchar_cursor();
dec_cursor();
}
if (c != NUL) {
- /* The space is no longer at the end of the line, delete it. */
- del_char(FALSE);
- did_add_space = FALSE;
+ // The space is no longer at the end of the line, delete it.
+ del_char(false);
+ did_add_space = false;
}
}
}
@@ -5672,7 +5868,7 @@ check_auto_format (
/*
* Find out textwidth to be used for formatting:
* if 'textwidth' option is set, use it
- * else if 'wrapmargin' option is set, use curwin->w_width - 'wrapmargin'
+ * else if 'wrapmargin' option is set, use curwin->w_grid.Columns-'wrapmargin'
* if invalid value, use 0.
* Set default to window width (maximum 79) for "gq" operator.
*/
@@ -5687,12 +5883,13 @@ comp_textwidth (
if (textwidth == 0 && curbuf->b_p_wm) {
/* The width is the window width minus 'wrapmargin' minus all the
* things that add to the margin. */
- textwidth = curwin->w_width - curbuf->b_p_wm;
- if (cmdwin_type != 0)
+ textwidth = curwin->w_grid.Columns - curbuf->b_p_wm;
+ if (cmdwin_type != 0) {
textwidth -= 1;
+ }
textwidth -= curwin->w_p_fdc;
- if (curwin->w_buffer->b_signlist != NULL) {
+ if (signcolumn_on(curwin)) {
textwidth -= 1;
}
@@ -5702,9 +5899,10 @@ comp_textwidth (
if (textwidth < 0)
textwidth = 0;
if (ff && textwidth == 0) {
- textwidth = curwin->w_width - 1;
- if (textwidth > 79)
+ textwidth = curwin->w_grid.Columns - 1;
+ if (textwidth > 79) {
textwidth = 79;
+ }
}
return textwidth;
}
@@ -5714,15 +5912,16 @@ comp_textwidth (
*/
static void redo_literal(int c)
{
- char_u buf[10];
+ char buf[10];
- /* Only digits need special treatment. Translate them into a string of
- * three digits. */
+ // Only digits need special treatment. Translate them into a string of
+ // three digits.
if (ascii_isdigit(c)) {
- vim_snprintf((char *)buf, sizeof(buf), "%03d", c);
+ vim_snprintf(buf, sizeof(buf), "%03d", c);
AppendToRedobuff(buf);
- } else
+ } else {
AppendCharToRedobuff(c);
+ }
}
// start_arrow() is called when an arrow key is used in insert mode.
@@ -5751,8 +5950,8 @@ static void start_arrow_common(pos_T *end_insert_pos, bool end_change)
{
if (!arrow_used && end_change) { // something has been inserted
AppendToRedobuff(ESC_STR);
- stop_insert(end_insert_pos, FALSE, FALSE);
- arrow_used = TRUE; /* this means we stopped the current insert */
+ stop_insert(end_insert_pos, false, false);
+ arrow_used = true; // This means we stopped the current insert.
}
check_spell_redraw();
}
@@ -5767,7 +5966,7 @@ static void check_spell_redraw(void)
linenr_T lnum = spell_redraw_lnum;
spell_redraw_lnum = 0;
- redrawWinline(lnum, FALSE);
+ redrawWinline(curwin, lnum);
}
}
@@ -5809,7 +6008,7 @@ int stop_arrow(void)
vr_lines_changed = 1;
}
ResetRedobuff();
- AppendToRedobuff((char_u *)"1i"); /* pretend we start an insertion */
+ AppendToRedobuff("1i"); // Pretend we start an insertion.
new_insert_skip = 2;
} else if (ins_need_undo) {
if (u_save_cursor() == OK)
@@ -5887,8 +6086,8 @@ stop_insert (
}
}
- /* If a space was inserted for auto-formatting, remove it now. */
- check_auto_format(TRUE);
+ // If a space was inserted for auto-formatting, remove it now.
+ check_auto_format(true);
/* If we just did an auto-indent, remove the white space from the end
* of the line, and put the cursor back.
@@ -5907,10 +6106,12 @@ stop_insert (
if (gchar_cursor() == NUL && curwin->w_cursor.col > 0)
--curwin->w_cursor.col;
cc = gchar_cursor();
- if (!ascii_iswhite(cc))
+ if (!ascii_iswhite(cc)) {
break;
- if (del_char(TRUE) == FAIL)
- break; /* should not happen */
+ }
+ if (del_char(true) == FAIL) {
+ break; // should not happen
+ }
}
if (curwin->w_cursor.lnum != tpos.lnum)
curwin->w_cursor = tpos;
@@ -5935,10 +6136,10 @@ stop_insert (
}
}
}
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
/* Set '[ and '] to the inserted text. When end_insert_pos is NULL we are
* now in a different buffer. */
@@ -5980,27 +6181,30 @@ void free_last_insert(void)
#endif
-/*
- * Add character "c" to buffer "s". Escape the special meaning of K_SPECIAL
- * and CSI. Handle multi-byte characters.
- * Returns a pointer to after the added bytes.
- */
+/// Add character "c" to buffer "s"
+///
+/// Escapes the special meaning of K_SPECIAL and CSI, handles multi-byte
+/// characters.
+///
+/// @param[in] c Character to add.
+/// @param[out] s Buffer to add to. Must have at least MB_MAXBYTES + 1 bytes.
+///
+/// @return Pointer to after the added bytes.
char_u *add_char2buf(int c, char_u *s)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
char_u temp[MB_MAXBYTES + 1];
- int i;
- int len;
-
- len = (*mb_char2bytes)(c, temp);
- for (i = 0; i < len; ++i) {
+ const int len = utf_char2bytes(c, temp);
+ for (int i = 0; i < len; i++) {
c = temp[i];
- /* Need to escape K_SPECIAL and CSI like in the typeahead buffer. */
+ // Need to escape K_SPECIAL and CSI like in the typeahead buffer.
if (c == K_SPECIAL) {
*s++ = K_SPECIAL;
*s++ = KS_SPECIAL;
*s++ = KE_FILLER;
- } else
+ } else {
*s++ = c;
+ }
}
return s;
}
@@ -6049,12 +6253,10 @@ int oneright(void)
/* Adjust for multi-wide char (excluding TAB) */
ptr = get_cursor_pos_ptr();
- coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(
- (*mb_ptr2char)(ptr)
- ))
- ? ptr2cells(ptr) : 1));
- curwin->w_set_curswant = TRUE;
- /* Return OK if the cursor moved, FAIL otherwise (at window edge). */
+ coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) ?
+ ptr2cells(ptr) : 1));
+ curwin->w_set_curswant = true;
+ // Return OK if the cursor moved, FAIL otherwise (at window edge).
return (prevpos.col != curwin->w_cursor.col
|| prevpos.coladd != curwin->w_cursor.coladd) ? OK : FAIL;
}
@@ -6109,10 +6311,10 @@ int oneleft(void)
/* Adjust for multi-wide char (not a TAB) */
ptr = get_cursor_pos_ptr();
- if (*ptr != TAB && vim_isprintc(
- (*mb_ptr2char)(ptr)
- ) && ptr2cells(ptr) > 1)
+ if (*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))
+ && ptr2cells(ptr) > 1) {
curwin->w_cursor.coladd = 0;
+ }
}
curwin->w_set_curswant = TRUE;
@@ -6259,8 +6461,10 @@ stuff_inserted (
/* may want to stuff the command character, to start Insert mode */
if (c != NUL)
stuffcharReadbuff(c);
- if ((esc_ptr = (char_u *)vim_strrchr(ptr, ESC)) != NULL)
- *esc_ptr = NUL; /* remove the ESC */
+ if ((esc_ptr = STRRCHR(ptr, ESC)) != NULL) {
+ // remove the ESC.
+ *esc_ptr = NUL;
+ }
/* when the last char is either "0" or "^" it will be quoted if no ESC
* comes after it OR if it will inserted more than once and "ptr"
@@ -6274,12 +6478,13 @@ stuff_inserted (
}
do {
- stuffReadbuff(ptr);
- /* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */
- if (last)
- stuffReadbuff((char_u *)(last == '0'
- ? "\026\060\064\070"
- : "\026^"));
+ stuffReadbuff((const char *)ptr);
+ // A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^".
+ if (last) {
+ stuffReadbuff((last == '0'
+ ? "\026\060\064\070"
+ : "\026^"));
+ }
} while (--count > 0);
if (last)
@@ -6560,8 +6765,8 @@ static void replace_do_bs(int limit_col)
* text aligned. */
curwin->w_cursor.col += ins_len;
while (vcol > orig_vcols && gchar_cursor() == ' ') {
- del_char(FALSE);
- ++orig_vcols;
+ del_char(false);
+ orig_vcols++;
}
curwin->w_cursor.col -= ins_len;
}
@@ -6757,7 +6962,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
p = look + STRLEN(look);
if ((try_match || try_match_word)
&& curwin->w_cursor.col >= (colnr_T)(p - look)) {
- int match = FALSE;
+ bool match = false;
if (keytyped == KEY_COMPLETE) {
char_u *s;
@@ -6782,29 +6987,30 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
&& (icase
? mb_strnicmp(s, look, (size_t)(p - look))
: STRNCMP(s, look, p - look)) == 0)
- match = TRUE;
- } else
- /* TODO: multi-byte */
- if (keytyped == (int)p[-1] || (icase && keytyped < 256
- && TOLOWER_LOC(keytyped) ==
- TOLOWER_LOC((int)p[-1]))) {
- line = get_cursor_pos_ptr();
- assert(p >= look && (uintmax_t)(p - look) <= SIZE_MAX);
- if ((curwin->w_cursor.col == (colnr_T)(p - look)
- || !vim_iswordc(line[-(p - look) - 1]))
- && (icase
- ? mb_strnicmp(line - (p - look), look, (size_t)(p - look))
- : STRNCMP(line - (p - look), look, p - look))
- == 0)
- match = TRUE;
+ match = true;
+ } else {
+ // TODO(@brammool): multi-byte
+ if (keytyped == (int)p[-1]
+ || (icase && keytyped < 256
+ && TOLOWER_LOC(keytyped) == TOLOWER_LOC((int)p[-1]))) {
+ line = get_cursor_pos_ptr();
+ assert(p >= look && (uintmax_t)(p - look) <= SIZE_MAX);
+ if ((curwin->w_cursor.col == (colnr_T)(p - look)
+ || !vim_iswordc(line[-(p - look) - 1]))
+ && (icase
+ ? mb_strnicmp(line - (p - look), look, (size_t)(p - look))
+ : STRNCMP(line - (p - look), look, p - look)) == 0) {
+ match = true;
+ }
+ }
}
if (match && try_match_word && !try_match) {
/* "0=word": Check if there are only blanks before the
* word. */
- line = get_cursor_line_ptr();
- if ((int)(skipwhite(line) - line) !=
- (int)(curwin->w_cursor.col - (p - look)))
- match = FALSE;
+ if (getwhitecols_curline() !=
+ (int)(curwin->w_cursor.col - (p - look))) {
+ match = false;
+ }
}
if (match) {
return true;
@@ -6817,7 +7023,9 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
if (try_match && *look == keytyped) {
return true;
}
- look++;
+ if (*look != NUL) {
+ look++;
+ }
}
/*
@@ -7023,7 +7231,7 @@ static void ins_ctrl_g(void)
case 'U':
// Allow one left/right cursor movement with the next char,
// without breaking undo.
- dont_sync_undo = MAYBE;
+ dont_sync_undo = kNone;
break;
/* Unknown CTRL-G command, reserved for future expansion. */
@@ -7036,8 +7244,8 @@ static void ins_ctrl_g(void)
*/
static void ins_ctrl_hat(void)
{
- if (map_to_exists_mode((char_u *)"", LANGMAP, FALSE)) {
- /* ":lmap" mappings exists, Toggle use of ":lmap" mappings. */
+ if (map_to_exists_mode("", LANGMAP, false)) {
+ // ":lmap" mappings exists, Toggle use of ":lmap" mappings.
if (State & LANGMAP) {
curbuf->b_p_iminsert = B_IMODE_NONE;
State &= ~LANGMAP;
@@ -7072,13 +7280,12 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
disabled_redraw = false;
}
if (!arrow_used) {
- /*
- * Don't append the ESC for "r<CR>" and "grx".
- * When 'insertmode' is set only CTRL-L stops Insert mode. Needed for
- * when "count" is non-zero.
- */
- if (cmdchar != 'r' && cmdchar != 'v')
- AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR);
+ // Don't append the ESC for "r<CR>" and "grx".
+ // When 'insertmode' is set only CTRL-L stops Insert mode. Needed for
+ // when "count" is non-zero.
+ if (cmdchar != 'r' && cmdchar != 'v') {
+ AppendToRedobuff(p_im ? "\014" : ESC_STR);
+ }
/*
* Repeating insert may take a long time. Check for
@@ -7218,7 +7425,7 @@ static bool ins_start_select(int c)
case K_KPAGEDOWN:
if (!(mod_mask & MOD_MASK_SHIFT))
break;
- // FALLTHROUGH
+ FALLTHROUGH;
case K_S_LEFT:
case K_S_RIGHT:
case K_S_UP:
@@ -7232,7 +7439,8 @@ static bool ins_start_select(int c)
// Execute the key in (insert) Select mode.
stuffcharReadbuff(Ctrl_O);
if (mod_mask) {
- char_u buf[4] = { K_SPECIAL, KS_MODIFIER, mod_mask, NUL };
+ const char buf[] = { (char)K_SPECIAL, (char)KS_MODIFIER,
+ (char)(uint8_t)mod_mask, NUL };
stuffReadbuff(buf);
}
stuffcharReadbuff(c);
@@ -7255,7 +7463,7 @@ static void ins_insert(int replaceState)
set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) ? "i" :
replaceState == VREPLACE ? "v" :
"r"), 1);
- apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, false, curbuf);
+ ins_apply_autocmds(EVENT_INSERTCHANGE);
if (State & REPLACE_FLAG) {
State = INSERT | (State & LANGMAP);
} else {
@@ -7301,46 +7509,55 @@ static void ins_shift(int c, int lastc)
*/
if (c == Ctrl_D && (lastc == '0' || lastc == '^')
&& curwin->w_cursor.col > 0) {
- --curwin->w_cursor.col;
- (void)del_char(FALSE); /* delete the '^' or '0' */
- /* In Replace mode, restore the characters that '^' or '0' replaced. */
- if (State & REPLACE_FLAG)
+ curwin->w_cursor.col--;
+ (void)del_char(false); // delete the '^' or '0'
+ // In Replace mode, restore the characters that '^' or '0' replaced.
+ if (State & REPLACE_FLAG) {
replace_pop_ins();
- if (lastc == '^')
- old_indent = get_indent(); /* remember curr. indent */
+ }
+ if (lastc == '^') {
+ old_indent = get_indent(); // remember curr. indent
+ }
change_indent(INDENT_SET, 0, TRUE, 0, TRUE);
} else
change_indent(c == Ctrl_D ? INDENT_DEC : INDENT_INC, 0, TRUE, 0, TRUE);
- if (did_ai && *skipwhite(get_cursor_line_ptr()) != NUL)
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
- can_cindent = FALSE; /* no cindenting after ^D or ^T */
+ if (did_ai && *skipwhite(get_cursor_line_ptr()) != NUL) {
+ did_ai = false;
+ }
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
+ can_cindent = false; // no cindenting after ^D or ^T
}
static void ins_del(void)
{
- int temp;
-
- if (stop_arrow() == FAIL)
+ if (stop_arrow() == FAIL) {
return;
- if (gchar_cursor() == NUL) { /* delete newline */
- temp = curwin->w_cursor.col;
+ }
+ if (gchar_cursor() == NUL) { // delete newline
+ const int temp = curwin->w_cursor.col;
if (!can_bs(BS_EOL) // only if "eol" included
|| do_join(2, false, true, false, false) == FAIL) {
vim_beep(BO_BS);
} else {
curwin->w_cursor.col = temp;
+ // Adjust orig_line_count in case more lines have been deleted than
+ // have been added. That makes sure, that open_line() later
+ // can access all buffer lines correctly
+ if (State & VREPLACE_FLAG
+ && orig_line_count > curbuf->b_ml.ml_line_count) {
+ orig_line_count = curbuf->b_ml.ml_line_count;
+ }
}
} else if (del_char(false) == FAIL) { // delete char under cursor
vim_beep(BO_BS);
}
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
AppendCharToRedobuff(K_DEL);
}
@@ -7358,8 +7575,9 @@ static void ins_bs_one(colnr_T *vcolp)
if (curwin->w_cursor.lnum != Insstart.lnum
|| curwin->w_cursor.col >= Insstart.col)
replace_do_bs(-1);
- } else
- (void)del_char(FALSE);
+ } else {
+ (void)del_char(false);
+ }
}
/// Handle Backspace, delete-word and delete-line in Insert mode.
@@ -7383,13 +7601,11 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
int oldState;
int cpc[MAX_MCO]; /* composing characters */
- /*
- * can't delete anything in an empty file
- * can't backup past first character in buffer
- * can't backup past starting point unless 'backspace' > 1
- * can backup to a previous line if 'backspace' == 0
- */
- if (bufempty()
+ // can't delete anything in an empty file
+ // can't backup past first character in buffer
+ // can't backup past starting point unless 'backspace' > 1
+ // can backup to a previous line if 'backspace' == 0
+ if (BUFEMPTY()
|| (!revins_on
&& ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0)
|| (!can_bs(BS_START)
@@ -7430,9 +7646,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
curwin->w_cursor.coladd = 0;
}
- /*
- * delete newline!
- */
+ // Delete newline!
if (curwin->w_cursor.col == 0) {
lnum = Insstart.lnum;
if (curwin->w_cursor.lnum == lnum || revins_on) {
@@ -7441,7 +7655,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
return false;
}
Insstart.lnum--;
- Insstart.col = MAXCOL;
+ Insstart.col = (colnr_T)STRLEN(ml_get(Insstart.lnum));
}
/*
* In replace mode:
@@ -7511,7 +7725,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
State = oldState;
}
}
- did_ai = FALSE;
+ did_ai = false;
} else {
/*
* Delete character(s) before the cursor.
@@ -7627,16 +7841,16 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
else {
const bool l_enc_utf8 = enc_utf8;
const int l_p_deco = p_deco;
- if (l_enc_utf8 && l_p_deco)
+ if (l_enc_utf8 && l_p_deco) {
(void)utfc_ptr2char(get_cursor_pos_ptr(), cpc);
- (void)del_char(FALSE);
- /*
- * If there are combining characters and 'delcombine' is set
- * move the cursor back. Don't back up before the base
- * character.
- */
- if (l_enc_utf8 && l_p_deco && cpc[0] != NUL)
+ }
+ (void)del_char(false);
+ // If there are combining characters and 'delcombine' is set
+ // move the cursor back. Don't back up before the base
+ // character.
+ if (l_enc_utf8 && l_p_deco && cpc[0] != NUL) {
inc_cursor();
+ }
if (revins_chars) {
revins_chars--;
revins_legal++;
@@ -7715,7 +7929,7 @@ static void ins_mouse(int c)
curwin = new_curwin;
curbuf = curwin->w_buffer;
}
- can_cindent = TRUE;
+ can_cindent = true;
}
/* redraw status lines (in case another window became active) */
@@ -7724,20 +7938,20 @@ static void ins_mouse(int c)
static void ins_mousescroll(int dir)
{
- pos_T tpos;
- win_T *old_curwin = curwin;
- int did_scroll = FALSE;
-
- tpos = curwin->w_cursor;
+ win_T *const old_curwin = curwin;
+ bool did_scroll = false;
+ pos_T tpos = curwin->w_cursor;
if (mouse_row >= 0 && mouse_col >= 0) {
- int row, col;
+ int row = mouse_row;
+ int col = mouse_col;
- row = mouse_row;
- col = mouse_col;
-
- /* find the window at the pointer coordinates */
- curwin = mouse_find_win(&row, &col);
+ // find the window at the pointer coordinates
+ win_T *const wp = mouse_find_win(&row, &col);
+ if (wp == NULL) {
+ return;
+ }
+ curwin = wp;
curbuf = curwin->w_buffer;
}
if (curwin == old_curwin)
@@ -7756,7 +7970,7 @@ static void ins_mousescroll(int dir)
} else {
mouse_scroll_horiz(dir);
}
- did_scroll = TRUE;
+ did_scroll = true;
}
curwin->w_redr_status = TRUE;
@@ -7774,7 +7988,7 @@ static void ins_mousescroll(int dir)
if (!equalpos(curwin->w_cursor, tpos)) {
start_arrow(&tpos);
- can_cindent = TRUE;
+ can_cindent = true;
}
}
@@ -7807,7 +8021,7 @@ static void ins_left(bool end_change)
} else {
vim_beep(BO_CRSR);
}
- dont_sync_undo = false;
+ dont_sync_undo = kFalse;
}
static void ins_home(int c)
@@ -7892,7 +8106,7 @@ static void ins_right(bool end_change)
} else {
vim_beep(BO_CRSR);
}
- dont_sync_undo = false;
+ dont_sync_undo = kFalse;
}
static void ins_s_right(void)
@@ -8040,11 +8254,11 @@ static bool ins_tab(void)
return true;
}
- did_ai = FALSE;
- did_si = FALSE;
- can_si = FALSE;
- can_si_back = FALSE;
- AppendToRedobuff((char_u *)"\t");
+ did_ai = false;
+ did_si = false;
+ can_si = false;
+ can_si_back = false;
+ AppendToRedobuff("\t");
if (p_sta && ind) { // insert tab in indent, use "shiftwidth"
temp = get_sw_value(curbuf);
@@ -8197,14 +8411,14 @@ static bool ins_tab(void)
/// Handle CR or NL in insert mode.
///
-/// @return true when it can't undo.
+/// @return false when it can't undo.
static bool ins_eol(int c)
{
if (echeck_abbr(c + ABBR_OFF)) {
- return false;
+ return true;
}
if (stop_arrow() == FAIL) {
- return true;
+ return false;
}
undisplay_dollar();
@@ -8242,11 +8456,11 @@ static bool ins_eol(int c)
has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0,
old_indent);
old_indent = 0;
- can_cindent = TRUE;
- /* When inserting a line the cursor line must never be in a closed fold. */
+ can_cindent = true;
+ // When inserting a line the cursor line must never be in a closed fold.
foldOpenCursor();
- return !i;
+ return i;
}
/*
@@ -8271,17 +8485,16 @@ static int ins_digraph(void)
}
- /* don't map the digraph chars. This also prevents the
- * mode message to be deleted when ESC is hit */
- ++no_mapping;
- ++allow_keys;
+ // don't map the digraph chars. This also prevents the
+ // mode message to be deleted when ESC is hit
+ no_mapping++;
c = plain_vgetc();
- --no_mapping;
- --allow_keys;
- if (did_putchar)
- /* when the line fits in 'columns' the '?' is at the start of the next
- * line and will not be removed by the redraw */
+ no_mapping--;
+ if (did_putchar) {
+ // when the line fits in 'columns' the '?' is at the start of the next
+ // line and will not be removed by the redraw
edit_unputchar();
+ }
if (IS_SPECIAL(c) || mod_mask) { /* special key */
clear_showcmd();
@@ -8301,18 +8514,17 @@ static int ins_digraph(void)
}
add_to_showcmd_c(c);
}
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
cc = plain_vgetc();
- --no_mapping;
- --allow_keys;
- if (did_putchar)
- /* when the line fits in 'columns' the '?' is at the start of the
- * next line and will not be removed by a redraw */
+ no_mapping--;
+ if (did_putchar) {
+ // when the line fits in 'columns' the '?' is at the start of the
+ // next line and will not be removed by a redraw
edit_unputchar();
+ }
if (cc != ESC) {
- AppendToRedobuff((char_u *)CTRL_V_STR);
- c = getdigraph(c, cc, TRUE);
+ AppendToRedobuff(CTRL_V_STR);
+ c = getdigraph(c, cc, true);
clear_showcmd();
return c;
}
@@ -8349,7 +8561,7 @@ int ins_copychar(linenr_T lnum)
if ((colnr_T)temp > curwin->w_virtcol)
ptr = prev_ptr;
- c = (*mb_ptr2char)(ptr);
+ c = utf_ptr2char(ptr);
if (c == NUL) {
vim_beep(BO_COPY);
}
@@ -8374,12 +8586,13 @@ static int ins_ctrl_ey(int tc)
if (c != NUL) {
long tw_save;
- /* The character must be taken literally, insert like it
- * was typed after a CTRL-V, and pretend 'textwidth'
- * wasn't set. Digits, 'o' and 'x' are special after a
- * CTRL-V, don't use it for these. */
- if (c < 256 && !isalnum(c))
- AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */
+ // The character must be taken literally, insert like it
+ // was typed after a CTRL-V, and pretend 'textwidth'
+ // wasn't set. Digits, 'o' and 'x' are special after a
+ // CTRL-V, don't use it for these.
+ if (c < 256 && !isalnum(c)) {
+ AppendToRedobuff(CTRL_V_STR);
+ }
tw_save = curbuf->b_p_tw;
curbuf->b_p_tw = -1;
insert_special(c, TRUE, FALSE);
@@ -8495,46 +8708,64 @@ static colnr_T get_nolist_virtcol(void)
static char_u *do_insert_char_pre(int c)
{
char buf[MB_MAXBYTES + 1];
+ const int save_State = State;
// Return quickly when there is nothing to do.
if (!has_event(EVENT_INSERTCHARPRE)) {
return NULL;
}
- if (has_mbyte) {
- buf[(*mb_char2bytes)(c, (char_u *) buf)] = NUL;
- } else {
- buf[0] = c;
- buf[1] = NUL;
- }
+ buf[utf_char2bytes(c, (char_u *)buf)] = NUL;
// Lock the text to avoid weird things from happening.
textlock++;
set_vim_var_string(VV_CHAR, buf, -1);
char_u *res = NULL;
- if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf)) {
- /* Get the value of v:char. It may be empty or more than one
- * character. Only use it when changed, otherwise continue with the
- * original character to avoid breaking autoindent. */
- if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0)
+ if (ins_apply_autocmds(EVENT_INSERTCHARPRE)) {
+ // Get the value of v:char. It may be empty or more than one
+ // character. Only use it when changed, otherwise continue with the
+ // original character to avoid breaking autoindent.
+ if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) {
res = vim_strsave(get_vim_var_str(VV_CHAR));
+ }
}
set_vim_var_string(VV_CHAR, NULL, -1);
textlock--;
+ // Restore the State, it may have been changed.
+ State = save_State;
+
return res;
}
-static void show_pum(int save_w_wrow)
+/// Trigger "event" and take care of fixing undo.
+static int ins_apply_autocmds(event_T event)
+{
+ varnumber_T tick = buf_get_changedtick(curbuf);
+ int r;
+
+ r = apply_autocmds(event, NULL, NULL, false, curbuf);
+
+ // If u_savesub() was called then we are not prepared to start
+ // a new line. Call u_save() with no contents to fix that.
+ if (tick != buf_get_changedtick(curbuf)) {
+ u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1));
+ }
+
+ return r;
+}
+
+static void show_pum(int prev_w_wrow, int prev_w_leftcol)
{
// RedrawingDisabled may be set when invoked through complete().
int n = RedrawingDisabled;
RedrawingDisabled = 0;
- // If the cursor moved we need to remove the pum first.
+ // If the cursor moved or the display scrolled we need to remove the pum
+ // first.
setcursor();
- if (save_w_wrow != curwin->w_wrow) {
+ if (prev_w_wrow != curwin->w_wrow || prev_w_leftcol != curwin->w_leftcol) {
ins_compl_del_pum();
}
diff --git a/src/nvim/edit.h b/src/nvim/edit.h
index 0d61f26bcc..433a941295 100644
--- a/src/nvim/edit.h
+++ b/src/nvim/edit.h
@@ -6,11 +6,12 @@
/*
* Array indexes used for cptext argument of ins_compl_add().
*/
-#define CPT_ABBR 0 /* "abbr" */
-#define CPT_MENU 1 /* "menu" */
-#define CPT_KIND 2 /* "kind" */
-#define CPT_INFO 3 /* "info" */
-#define CPT_COUNT 4 /* Number of entries */
+#define CPT_ABBR 0 // "abbr"
+#define CPT_MENU 1 // "menu"
+#define CPT_KIND 2 // "kind"
+#define CPT_INFO 3 // "info"
+#define CPT_USER_DATA 4 // "user data"
+#define CPT_COUNT 5 // Number of entries
typedef int (*IndentGetter)(void);
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 591ed50cfd..4cf8a01ddb 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -1,8 +1,12 @@
+// 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
+
/*
* eval.c: Expression evaluation.
*/
#include <assert.h>
+#include <float.h>
#include <inttypes.h>
#include <stdarg.h>
#include <string.h>
@@ -20,6 +24,7 @@
#endif
#include "nvim/eval.h"
#include "nvim/buffer.h"
+#include "nvim/channel.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
@@ -30,6 +35,7 @@
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
+#include "nvim/os/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
@@ -42,9 +48,9 @@
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
+#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/map.h"
#include "nvim/file_search.h"
@@ -63,6 +69,7 @@
#include "nvim/search.h"
#include "nvim/sha256.h"
#include "nvim/spell.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
@@ -90,16 +97,21 @@
#include "nvim/os/dl.h"
#include "nvim/os/input.h"
#include "nvim/event/loop.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/lib/khash.h"
#include "nvim/lib/queue.h"
-#include "nvim/eval/typval_encode.h"
+#include "nvim/lua/executor.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval/gc.h"
+#include "nvim/macros.h"
-#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */
+// TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead
-#define DO_NOT_FREE_CNT 99999 /* refcount for dict or list that should not
- be freed. */
+#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */
-#define AUTOLOAD_CHAR '#' /* Character used as separator in autoload
- function/variable names. */
+// Character used as separator in autoload function/variable names.
+#define AUTOLOAD_CHAR '#'
/*
* Structure returned by get_lval() and used by set_var_lval().
@@ -129,34 +141,31 @@
* "newkey" is the key for the new item.
*/
typedef struct lval_S {
- char_u *ll_name; /* start of variable name (can be NULL) */
- char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */
- typval_T *ll_tv; /* Typeval of item being used. If "newkey"
- isn't NULL it's the Dict to which to add
- the item. */
- listitem_T *ll_li; /* The list item or NULL. */
- list_T *ll_list; /* The list or NULL. */
- int ll_range; /* TRUE when a [i:j] range was used */
- long ll_n1; /* First index for list */
- long ll_n2; /* Second index for list range */
- int ll_empty2; /* Second index is empty: [i:] */
- dict_T *ll_dict; /* The Dictionary or NULL */
- dictitem_T *ll_di; /* The dictitem or NULL */
- char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */
+ const char *ll_name; ///< Start of variable name (can be NULL).
+ size_t ll_name_len; ///< Length of the .ll_name.
+ char *ll_exp_name; ///< NULL or expanded name in allocated memory.
+ typval_T *ll_tv; ///< Typeval of item being used. If "newkey"
+ ///< isn't NULL it's the Dict to which to add the item.
+ listitem_T *ll_li; ///< The list item or NULL.
+ list_T *ll_list; ///< The list or NULL.
+ int ll_range; ///< TRUE when a [i:j] range was used.
+ long ll_n1; ///< First index for list.
+ long ll_n2; ///< Second index for list range.
+ int ll_empty2; ///< Second index is empty: [i:].
+ dict_T *ll_dict; ///< The Dictionary or NULL.
+ dictitem_T *ll_di; ///< The dictitem or NULL.
+ char_u *ll_newkey; ///< New key for Dict in allocated memory or NULL.
} lval_T;
static char *e_letunexp = N_("E18: Unexpected characters in :let");
-static char *e_listidx = N_("E684: list index out of range: %" PRId64);
-static char *e_undefvar = N_("E121: Undefined variable: %s");
static char *e_missbrac = N_("E111: Missing ']'");
static char *e_listarg = N_("E686: Argument of %s must be a List");
static char *e_listdictarg = N_(
"E712: Argument of %s must be a List or Dictionary");
-static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary");
static char *e_listreq = N_("E714: List required");
static char *e_dictreq = N_("E715: Dictionary required");
-static char *e_strreq = N_("E114: String required");
+static char *e_stringreq = N_("E928: String required");
static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
static char *e_funcexts = N_(
@@ -164,15 +173,20 @@ static char *e_funcexts = N_(
static char *e_funcdict = N_("E717: Dictionary entry already exists");
static char *e_funcref = N_("E718: Funcref required");
static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary");
-static char *e_letwrong = N_("E734: Wrong variable type for %s=");
static char *e_nofunc = N_("E130: Unknown function: %s");
static char *e_illvar = N_("E461: Illegal variable name: %s");
-static char *e_float_as_string = N_("E806: using Float as a String");
+static const char *e_readonlyvar = N_(
+ "E46: Cannot change read-only variable \"%.*s\"");
+
+// TODO(ZyX-I): move to eval/executor
+static char *e_letwrong = N_("E734: Wrong variable type for %s=");
-static char_u * const empty_string = (char_u *)"";
static char_u * const namespace_char = (char_u *)"abglstvw";
-static dictitem_T globvars_var; /* variable used for g: */
+/// Variable used for g:
+static ScopeDictDictItem globvars_var;
+
+/// g: value
#define globvarht globvardict.dv_hashtab
/*
@@ -183,12 +197,15 @@ static hashtab_T compat_hashtab;
hashtab_T func_hashtab;
+// Used for checking if local variables or arguments used in a lambda.
+static int *eval_lavars_used = NULL;
+
/*
* Array to hold the hashtab with variables local to each sourced script.
* Each item holds a variable (nameless) that points to the dict_T.
*/
typedef struct {
- dictitem_T sv_var;
+ ScopeDictDictItem sv_var;
dict_T sv_dict;
} scriptvar_T;
@@ -198,59 +215,81 @@ static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL};
static int echo_attr = 0; /* attributes used for ":echo" */
-/* Values for trans_function_name() argument: */
-#define TFN_INT 1 /* internal function name OK */
-#define TFN_QUIET 2 /* no error messages */
-#define TFN_NO_AUTOLOAD 4 /* do not use script autoloading */
-
-/* Values for get_lval() flags argument: */
-#define GLV_QUIET TFN_QUIET /* no error messages */
-#define GLV_NO_AUTOLOAD TFN_NO_AUTOLOAD /* do not use script autoloading */
-
-/* function flags */
-#define FC_ABORT 1 /* abort function on error */
-#define FC_RANGE 2 /* function accepts range */
-#define FC_DICT 4 /* Dict function, uses "self" */
-
-/* The names of packages that once were loaded are remembered. */
-static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
-
-/* list heads for garbage collection */
-static dict_T *first_dict = NULL; /* list of all dicts */
-static list_T *first_list = NULL; /* list of all lists */
+/// Describe data to return from find_some_match()
+typedef enum {
+ kSomeMatch, ///< Data for match().
+ kSomeMatchEnd, ///< Data for matchend().
+ kSomeMatchList, ///< Data for matchlist().
+ kSomeMatchStr, ///< Data for matchstr().
+ kSomeMatchStrPos, ///< Data for matchstrpos().
+} SomeMatchType;
+
+/// trans_function_name() flags
+typedef enum {
+ TFN_INT = 1, ///< May use internal function name
+ TFN_QUIET = 2, ///< Do not emit error messages.
+ TFN_NO_AUTOLOAD = 4, ///< Do not use script autoloading.
+ TFN_NO_DEREF = 8, ///< Do not dereference a Funcref.
+ TFN_READ_ONLY = 16, ///< Will not change the variable.
+} TransFunctionNameFlags;
+
+/// get_lval() flags
+typedef enum {
+ GLV_QUIET = TFN_QUIET, ///< Do not emit error messages.
+ GLV_NO_AUTOLOAD = TFN_NO_AUTOLOAD, ///< Do not use script autoloading.
+ GLV_READ_ONLY = TFN_READ_ONLY, ///< Indicates that caller will not change
+ ///< the value (prevents error message).
+} GetLvalFlags;
+
+// function flags
+#define FC_ABORT 0x01 // abort function on error
+#define FC_RANGE 0x02 // function accepts range
+#define FC_DICT 0x04 // Dict function, uses "self"
+#define FC_CLOSURE 0x08 // closure, uses outer scope variables
+#define FC_DELETED 0x10 // :delfunction used while uf_refcount > 0
+#define FC_REMOVED 0x20 // function redefined while uf_refcount > 0
+
+// The names of packages that once were loaded are remembered.
+static garray_T ga_loaded = { 0, 0, sizeof(char_u *), 4, NULL };
#define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j]
#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]
-#define VAR_SHORT_LEN 20 /* short variable name length */
-#define FIXVAR_CNT 12 /* number of fixed variables */
-
-/* structure to hold info for a function that is currently being executed. */
-typedef struct funccall_S funccall_T;
+/// Short variable name length
+#define VAR_SHORT_LEN 20
+/// Number of fixed variables used for arguments
+#define FIXVAR_CNT 12
struct funccall_S {
- ufunc_T *func; /* function being called */
- int linenr; /* next line to be executed */
- int returned; /* ":return" used */
- struct /* fixed variables for arguments */
- {
- dictitem_T var; /* variable (without room for name) */
- char_u room[VAR_SHORT_LEN]; /* room for the name */
- } fixvar[FIXVAR_CNT];
- dict_T l_vars; /* l: local function variables */
- dictitem_T l_vars_var; /* variable for l: scope */
- dict_T l_avars; /* a: argument variables */
- dictitem_T l_avars_var; /* variable for a: scope */
- list_T l_varlist; /* list for a:000 */
- listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */
- typval_T *rettv; /* return value */
- linenr_T breakpoint; /* next line with breakpoint or zero */
- int dbg_tick; /* debug_tick when breakpoint was set */
- int level; /* top nesting level of executed function */
- proftime_T prof_child; /* time spent in a child */
- funccall_T *caller; /* calling function or NULL */
+ ufunc_T *func; ///< Function being called.
+ int linenr; ///< Next line to be executed.
+ int returned; ///< ":return" used.
+ /// Fixed variables for arguments.
+ TV_DICTITEM_STRUCT(VAR_SHORT_LEN + 1) fixvar[FIXVAR_CNT];
+ dict_T l_vars; ///< l: local function variables.
+ ScopeDictDictItem l_vars_var; ///< Variable for l: scope.
+ dict_T l_avars; ///< a: argument variables.
+ ScopeDictDictItem l_avars_var; ///< Variable for a: scope.
+ list_T l_varlist; ///< List for a:000.
+ listitem_T l_listitems[MAX_FUNC_ARGS]; ///< List items for a:000.
+ typval_T *rettv; ///< Return value.
+ linenr_T breakpoint; ///< Next line with breakpoint or zero.
+ int dbg_tick; ///< Debug_tick when breakpoint was set.
+ int level; ///< Top nesting level of executed function.
+ proftime_T prof_child; ///< Time spent in a child.
+ funccall_T *caller; ///< Calling function or NULL.
+ int fc_refcount; ///< Number of user functions that reference this funccall.
+ int fc_copyID; ///< CopyID used for garbage collection.
+ garray_T fc_funcs; ///< List of ufunc_T* which keep a reference to "func".
};
+///< Structure used by trans_function_name()
+typedef struct {
+ dict_T *fd_dict; ///< Dictionary used.
+ char_u *fd_newkey; ///< New key in "dict" in allocated memory.
+ dictitem_T *fd_di; ///< Dictionary item used.
+} funcdict_T;
+
/*
* Info used by a ":for" loop.
*/
@@ -262,15 +301,6 @@ typedef struct {
} forinfo_T;
/*
- * Struct used by trans_function_name()
- */
-typedef struct {
- dict_T *fd_dict; /* Dictionary used */
- char_u *fd_newkey; /* new key in "dict" in allocated memory */
- dictitem_T *fd_di; /* Dictionary item used */
-} funcdict_T;
-
-/*
* enum used by var_flavour()
*/
typedef enum {
@@ -290,8 +320,8 @@ typedef enum {
.vv_di = { \
.di_tv = { .v_type = type }, \
.di_flags = 0, \
+ .di_key = { 0 }, \
}, \
- .vv_filler = { 0 }, \
.vv_flags = flags, \
}
@@ -301,9 +331,8 @@ typedef enum {
// variables with the VV_ defines.
static struct vimvar {
char *vv_name; ///< Name of the variable, without v:.
- dictitem_T vv_di; ///< Value of the variable, with name.
- char vv_filler[16]; ///< Space for longest name from below.
- char vv_flags; ///< Flags: #VV_COMPAT, #VV_RO, #VV_RO_SBX.
+ TV_DICTITEM_STRUCT(17) vv_di; ///< Value and name for key (max 16 chars).
+ char vv_flags; ///< Flags: #VV_COMPAT, #VV_RO, #VV_RO_SBX.
} vimvars[] =
{
// VV_ tails differing from upcased string literals:
@@ -312,14 +341,14 @@ static struct vimvar {
// VV_SEND_SERVER "servername"
// VV_REG "register"
// VV_OP "operator"
- VV(VV_COUNT, "count", VAR_NUMBER, VV_COMPAT+VV_RO),
+ VV(VV_COUNT, "count", VAR_NUMBER, VV_RO),
VV(VV_COUNT1, "count1", VAR_NUMBER, VV_RO),
VV(VV_PREVCOUNT, "prevcount", VAR_NUMBER, VV_RO),
- VV(VV_ERRMSG, "errmsg", VAR_STRING, VV_COMPAT),
+ VV(VV_ERRMSG, "errmsg", VAR_STRING, 0),
VV(VV_WARNINGMSG, "warningmsg", VAR_STRING, 0),
VV(VV_STATUSMSG, "statusmsg", VAR_STRING, 0),
- VV(VV_SHELL_ERROR, "shell_error", VAR_NUMBER, VV_COMPAT+VV_RO),
- VV(VV_THIS_SESSION, "this_session", VAR_STRING, VV_COMPAT),
+ VV(VV_SHELL_ERROR, "shell_error", VAR_NUMBER, VV_RO),
+ VV(VV_THIS_SESSION, "this_session", VAR_STRING, 0),
VV(VV_VERSION, "version", VAR_NUMBER, VV_COMPAT+VV_RO),
VV(VV_LNUM, "lnum", VAR_NUMBER, VV_RO_SBX),
VV(VV_TERMRESPONSE, "termresponse", VAR_STRING, VV_RO),
@@ -343,6 +372,7 @@ static struct vimvar {
VV(VV_DYING, "dying", VAR_NUMBER, VV_RO),
VV(VV_EXCEPTION, "exception", VAR_STRING, VV_RO),
VV(VV_THROWPOINT, "throwpoint", VAR_STRING, VV_RO),
+ VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO),
VV(VV_REG, "register", VAR_STRING, VV_RO),
VV(VV_CMDBANG, "cmdbang", VAR_NUMBER, VV_RO),
VV(VV_INSERTMODE, "insertmode", VAR_STRING, VV_RO),
@@ -353,6 +383,7 @@ static struct vimvar {
VV(VV_FCS_CHOICE, "fcs_choice", VAR_STRING, 0),
VV(VV_BEVAL_BUFNR, "beval_bufnr", VAR_NUMBER, VV_RO),
VV(VV_BEVAL_WINNR, "beval_winnr", VAR_NUMBER, VV_RO),
+ VV(VV_BEVAL_WINID, "beval_winid", VAR_NUMBER, VV_RO),
VV(VV_BEVAL_LNUM, "beval_lnum", VAR_NUMBER, VV_RO),
VV(VV_BEVAL_COL, "beval_col", VAR_NUMBER, VV_RO),
VV(VV_BEVAL_TEXT, "beval_text", VAR_STRING, VV_RO),
@@ -362,6 +393,7 @@ static struct vimvar {
VV(VV_SWAPCOMMAND, "swapcommand", VAR_STRING, VV_RO),
VV(VV_CHAR, "char", VAR_STRING, 0),
VV(VV_MOUSE_WIN, "mouse_win", VAR_NUMBER, 0),
+ VV(VV_MOUSE_WINID, "mouse_winid", VAR_NUMBER, 0),
VV(VV_MOUSE_LNUM, "mouse_lnum", VAR_NUMBER, 0),
VV(VV_MOUSE_COL, "mouse_col", VAR_NUMBER, 0),
VV(VV_OP, "operator", VAR_STRING, VV_RO),
@@ -370,7 +402,6 @@ static struct vimvar {
VV(VV_OLDFILES, "oldfiles", VAR_LIST, 0),
VV(VV_WINDOWID, "windowid", VAR_NUMBER, VV_RO_SBX),
VV(VV_PROGPATH, "progpath", VAR_STRING, VV_RO),
- VV(VV_COMMAND_OUTPUT, "command_output", VAR_STRING, 0),
VV(VV_COMPLETED_ITEM, "completed_item", VAR_DICT, VV_RO),
VV(VV_OPTION_NEW, "option_new", VAR_STRING, VV_RO),
VV(VV_OPTION_OLD, "option_old", VAR_STRING, VV_RO),
@@ -383,6 +414,16 @@ static struct vimvar {
VV(VV_NULL, "null", VAR_SPECIAL, VV_RO),
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
+ VV(VV_VIM_DID_ENTER, "vim_did_enter", VAR_NUMBER, VV_RO),
+ VV(VV_TESTING, "testing", VAR_NUMBER, 0),
+ VV(VV_TYPE_NUMBER, "t_number", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_STRING, "t_string", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_FUNC, "t_func", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_LIST, "t_list", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_DICT, "t_dict", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_FLOAT, "t_float", VAR_NUMBER, VV_RO),
+ VV(VV_TYPE_BOOL, "t_bool", VAR_NUMBER, VV_RO),
+ VV(VV_EXITING, "exiting", VAR_NUMBER, VV_RO),
};
#undef VV
@@ -396,50 +437,57 @@ static struct vimvar {
#define vv_dict vv_di.di_tv.vval.v_dict
#define vv_tv vv_di.di_tv
-static dictitem_T vimvars_var; /* variable used for v: */
-#define vimvarht vimvardict.dv_hashtab
-
-typedef struct {
- union {
- LibuvProcess uv;
- PtyProcess pty;
- } proc;
- Stream in, out, err;
- Terminal *term;
- bool stopped;
- bool exited;
- int refcount;
- ufunc_T *on_stdout, *on_stderr, *on_exit;
- dict_T *self;
- int *status_ptr;
- uint64_t id;
- Queue *events;
-} TerminalJobData;
-
-typedef struct dict_watcher {
- ufunc_T *callback;
- char *key_pattern;
- QUEUE node;
- bool busy; // prevent recursion if the dict is changed in the callback
-} DictWatcher;
+/// Variable used for v:
+static ScopeDictDictItem vimvars_var;
-typedef struct {
- TerminalJobData *data;
- ufunc_T *callback;
- const char *type;
- list_T *received;
- int status;
-} JobEvent;
+/// v: hashtab
+#define vimvarht vimvardict.dv_hashtab
typedef struct {
TimeWatcher tw;
int timer_id;
int repeat_count;
+ int refcount;
long timeout;
bool stopped;
- ufunc_T *callback;
+ bool paused;
+ Callback callback;
} timer_T;
+typedef void (*FunPtr)(void);
+
+/// Prototype of C function that implements VimL function
+typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, FunPtr data);
+
+/// Structure holding VimL function definition
+typedef struct fst {
+ char *name; ///< Name of the function.
+ uint8_t min_argc; ///< Minimal number of arguments.
+ uint8_t max_argc; ///< Maximal number of arguments.
+ VimLFunc func; ///< Function implementation.
+ FunPtr data; ///< Userdata for function implementation.
+} VimLFuncDef;
+
+KHASH_MAP_INIT_STR(functions, VimLFuncDef)
+
+/// Type of assert_* check being performed
+typedef enum
+{
+ ASSERT_EQUAL,
+ ASSERT_NOTEQUAL,
+ ASSERT_MATCH,
+ ASSERT_NOTMATCH,
+ ASSERT_INRANGE,
+ ASSERT_OTHER,
+} assert_type_T;
+
+/// Type for dict_list function
+typedef enum {
+ kDictListKeys, ///< List dictionary keys.
+ kDictListValues, ///< List dictionary values.
+ kDictListItems, ///< List dictionary contents: [keys, values].
+} DictListType;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval.c.generated.h"
#endif
@@ -447,12 +495,18 @@ typedef struct {
#define FNE_INCL_BR 1 /* find_name_end(): include [] in name */
#define FNE_CHECK_START 2 /* find_name_end(): check name starts with
valid character */
-static uint64_t current_job_id = 1;
-static PMap(uint64_t) *jobs = NULL;
-static uint64_t last_timer_id = 0;
+static uint64_t last_timer_id = 1;
static PMap(uint64_t) *timers = NULL;
+/// Dummy va_list for passing to vim_snprintf
+///
+/// Used because:
+/// - passing a NULL pointer doesn't work when va_list isn't a pointer
+/// - locally in the function results in a "used before set" warning
+/// - using va_start() to initialize it gives "function with fixed args" error
+static va_list dummy_ap;
+
static const char *const msgpack_type_names[] = {
[kMPNil] = "nil",
[kMPBoolean] = "boolean",
@@ -483,7 +537,6 @@ void eval_init(void)
{
vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
- jobs = pmap_new(uint64_t)();
timers = pmap_new(uint64_t)();
struct vimvar *p;
@@ -495,6 +548,7 @@ void eval_init(void)
for (size_t i = 0; i < ARRAY_SIZE(vimvars); i++) {
p = &vimvars[i];
+ assert(STRLEN(p->vv_name) <= 16);
STRCPY(p->vv_di.di_key, p->vv_name);
if (p->vv_flags & VV_RO)
p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
@@ -512,19 +566,19 @@ void eval_init(void)
}
vimvars[VV_VERSION].vv_nr = VIM_VERSION_100;
- dict_T *const msgpack_types_dict = dict_alloc();
+ dict_T *const msgpack_types_dict = tv_dict_alloc();
for (size_t i = 0; i < ARRAY_SIZE(msgpack_type_names); i++) {
- list_T *const type_list = list_alloc();
- type_list->lv_lock = VAR_FIXED;
- type_list->lv_refcount = 1;
- dictitem_T *const di = dictitem_alloc((char_u *) msgpack_type_names[i]);
- di->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
+ list_T *const type_list = tv_list_alloc(0);
+ tv_list_set_lock(type_list, VAR_FIXED);
+ tv_list_ref(type_list);
+ dictitem_T *const di = tv_dict_item_alloc(msgpack_type_names[i]);
+ di->di_flags |= DI_FLAGS_RO|DI_FLAGS_FIX;
di->di_tv = (typval_T) {
.v_type = VAR_LIST,
.vval = { .v_list = type_list, },
};
eval_msgpack_type_lists[i] = type_list;
- if (dict_add(msgpack_types_dict, di) == FAIL) {
+ if (tv_dict_add(msgpack_types_dict, di) == FAIL) {
// There must not be duplicate items in this dictionary by definition.
assert(false);
}
@@ -532,18 +586,28 @@ void eval_init(void)
msgpack_types_dict->dv_lock = VAR_FIXED;
set_vim_var_dict(VV_MSGPACK_TYPES, msgpack_types_dict);
- set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
+ set_vim_var_dict(VV_COMPLETED_ITEM, tv_dict_alloc());
- dict_T *v_event = dict_alloc();
+ dict_T *v_event = tv_dict_alloc();
v_event->dv_lock = VAR_FIXED;
set_vim_var_dict(VV_EVENT, v_event);
- set_vim_var_list(VV_ERRORS, list_alloc());
+ set_vim_var_list(VV_ERRORS, tv_list_alloc(kListLenUnknown));
+ set_vim_var_nr(VV_STDERR, CHAN_STDERR);
set_vim_var_nr(VV_SEARCHFORWARD, 1L);
set_vim_var_nr(VV_HLSEARCH, 1L);
+ set_vim_var_nr(VV_COUNT1, 1);
+ set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER);
+ set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING);
+ set_vim_var_nr(VV_TYPE_FUNC, VAR_TYPE_FUNC);
+ set_vim_var_nr(VV_TYPE_LIST, VAR_TYPE_LIST);
+ set_vim_var_nr(VV_TYPE_DICT, VAR_TYPE_DICT);
+ set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT);
+ set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL);
set_vim_var_special(VV_FALSE, kSpecialVarFalse);
set_vim_var_special(VV_TRUE, kSpecialVarTrue);
set_vim_var_special(VV_NULL, kSpecialVarNull);
+ set_vim_var_special(VV_EXITING, kSpecialVarNull);
set_reg_var(0); // default for v:register is not 0 but '"'
}
@@ -559,7 +623,7 @@ void eval_clear(void)
xfree(p->vv_str);
p->vv_str = NULL;
} else if (p->vv_di.di_tv.v_type == VAR_LIST) {
- list_unref(p->vv_list);
+ tv_list_unref(p->vv_list);
p->vv_list = NULL;
}
}
@@ -585,12 +649,11 @@ void eval_clear(void)
xfree(SCRIPT_SV(i));
ga_clear(&ga_scripts);
- /* unreferenced lists and dicts */
- (void)garbage_collect();
+ // unreferenced lists and dicts
+ (void)garbage_collect(false);
- /* functions */
+ // functions
free_all_functions();
- hash_clear(&func_hashtab);
}
#endif
@@ -630,8 +693,8 @@ int func_level(void *cookie)
/* pointer to funccal for currently active function */
funccall_T *current_funccal = NULL;
-/* pointer to list of previously used funccal, still around because some
- * item in it is still being used. */
+// Pointer to list of previously used funccal, still around because some
+// item in it is still being used.
funccall_T *previous_funccal = NULL;
/*
@@ -648,26 +711,25 @@ int current_func_returned(void)
*/
void set_internal_string_var(char_u *name, char_u *value)
{
- char_u *val = vim_strsave(value);
- typval_T *tvp = xcalloc(1, sizeof(typval_T));
+ const typval_T tv = {
+ .v_type = VAR_STRING,
+ .vval.v_string = value,
+ };
- tvp->v_type = VAR_STRING;
- tvp->vval.v_string = val;
- set_var(name, tvp, FALSE);
- free_tv(tvp);
+ set_var((const char *)name, STRLEN(name), (typval_T *)&tv, true);
}
static lval_T *redir_lval = NULL;
-static garray_T redir_ga; /* only valid when redir_lval is not NULL */
-static char_u *redir_endp = NULL;
+static garray_T redir_ga; // Only valid when redir_lval is not NULL.
+static char_u *redir_endp = NULL;
static char_u *redir_varname = NULL;
/*
* Start recording command output to a variable
* Returns OK if successfully completed the setup. FAIL otherwise.
*/
-int
-var_redir_start (
+int
+var_redir_start(
char_u *name,
int append /* append to an existing variable */
)
@@ -690,11 +752,11 @@ var_redir_start (
/* The output is stored in growarray "redir_ga" until redirection ends. */
ga_init(&redir_ga, (int)sizeof(char), 500);
- /* Parse the variable name (can be a dict or list entry). */
- redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, 0,
- FNE_CHECK_START);
- if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp !=
- NUL) {
+ // Parse the variable name (can be a dict or list entry).
+ redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval, false, false,
+ 0, FNE_CHECK_START);
+ if (redir_endp == NULL || redir_lval->ll_name == NULL
+ || *redir_endp != NUL) {
clear_lval(redir_lval);
if (redir_endp != NULL && *redir_endp != NUL)
/* Trailing characters are present after the variable name */
@@ -768,12 +830,13 @@ void var_redir_stop(void)
ga_append(&redir_ga, NUL); /* Append the trailing NUL. */
tv.v_type = VAR_STRING;
tv.vval.v_string = redir_ga.ga_data;
- /* Call get_lval() again, if it's inside a Dict or List it may
- * have changed. */
- redir_endp = get_lval(redir_varname, NULL, redir_lval,
- FALSE, FALSE, 0, FNE_CHECK_START);
- if (redir_endp != NULL && redir_lval->ll_name != NULL)
- set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
+ // Call get_lval() again, if it's inside a Dict or List it may
+ // have changed.
+ redir_endp = (char_u *)get_lval(redir_varname, NULL, redir_lval,
+ false, false, 0, FNE_CHECK_START);
+ if (redir_endp != NULL && redir_lval->ll_name != NULL) {
+ set_var_lval(redir_lval, redir_endp, &tv, false, (char_u *)".");
+ }
clear_lval(redir_lval);
}
@@ -791,7 +854,7 @@ void var_redir_stop(void)
int eval_charconvert(const char *const enc_from, const char *const enc_to,
const char *const fname_from, const char *const fname_to)
{
- int err = false;
+ bool err = false;
set_vim_var_string(VV_CC_FROM, enc_from, -1);
set_vim_var_string(VV_CC_TO, enc_to, -1);
@@ -813,7 +876,7 @@ int eval_charconvert(const char *const enc_from, const char *const enc_to,
int eval_printexpr(const char *const fname, const char *const args)
{
- int err = false;
+ bool err = false;
set_vim_var_string(VV_FNAME_IN, fname, -1);
set_vim_var_string(VV_CMDARG, args, -1);
@@ -833,7 +896,7 @@ int eval_printexpr(const char *const fname, const char *const args)
void eval_diff(const char *const origfile, const char *const newfile,
const char *const outfile)
{
- int err = FALSE;
+ bool err = false;
set_vim_var_string(VV_FNAME_IN, origfile, -1);
set_vim_var_string(VV_FNAME_NEW, newfile, -1);
@@ -847,7 +910,7 @@ void eval_diff(const char *const origfile, const char *const newfile,
void eval_patch(const char *const origfile, const char *const difffile,
const char *const outfile)
{
- int err;
+ bool err = false;
set_vim_var_string(VV_FNAME_IN, origfile, -1);
set_vim_var_string(VV_FNAME_DIFF, difffile, -1);
@@ -863,59 +926,64 @@ void eval_patch(const char *const origfile, const char *const difffile,
* Sets "error" to TRUE if there was an error.
* Return TRUE or FALSE.
*/
-int
-eval_to_bool (
+int
+eval_to_bool(
char_u *arg,
- int *error,
+ bool *error,
char_u **nextcmd,
int skip /* only parse, don't execute */
)
{
typval_T tv;
- int retval = FALSE;
+ bool retval = false;
- if (skip)
- ++emsg_skip;
- if (eval0(arg, &tv, nextcmd, !skip) == FAIL)
- *error = TRUE;
- else {
- *error = FALSE;
+ if (skip) {
+ emsg_skip++;
+ }
+ if (eval0(arg, &tv, nextcmd, !skip) == FAIL) {
+ *error = true;
+ } else {
+ *error = false;
if (!skip) {
- retval = (get_tv_number_chk(&tv, error) != 0);
- clear_tv(&tv);
+ retval = (tv_get_number_chk(&tv, error) != 0);
+ tv_clear(&tv);
}
}
- if (skip)
- --emsg_skip;
+ if (skip) {
+ emsg_skip--;
+ }
return retval;
}
-/*
- * Top level evaluation function, returning a string. If "skip" is TRUE,
- * only parsing to "nextcmd" is done, without reporting errors. Return
- * pointer to allocated memory, or NULL for failure or when "skip" is TRUE.
- */
-char_u *
-eval_to_string_skip (
- char_u *arg,
- char_u **nextcmd,
- int skip /* only parse, don't execute */
-)
+/// Top level evaluation function, returning a string
+///
+/// @param[in] arg String to evaluate.
+/// @param nextcmd Pointer to the start of the next Ex command.
+/// @param[in] skip If true, only do parsing to nextcmd without reporting
+/// errors or actually evaluating anything.
+///
+/// @return [allocated] string result of evaluation or NULL in case of error or
+/// when skipping.
+char *eval_to_string_skip(const char *arg, const char **nextcmd,
+ const bool skip)
+ FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
{
typval_T tv;
- char_u *retval;
+ char *retval;
- if (skip)
- ++emsg_skip;
- if (eval0(arg, &tv, nextcmd, !skip) == FAIL || skip)
+ if (skip) {
+ emsg_skip++;
+ }
+ if (eval0((char_u *)arg, &tv, (char_u **)nextcmd, !skip) == FAIL || skip) {
retval = NULL;
- else {
- retval = vim_strsave(get_tv_string(&tv));
- clear_tv(&tv);
+ } else {
+ retval = xstrdup(tv_get_string(&tv));
+ tv_clear(&tv);
+ }
+ if (skip) {
+ emsg_skip--;
}
- if (skip)
- --emsg_skip;
return retval;
}
@@ -941,31 +1009,33 @@ int skip_expr(char_u **pp)
char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert)
{
typval_T tv;
- char_u *retval;
+ char *retval;
garray_T ga;
- char_u numbuf[NUMBUFLEN];
- if (eval0(arg, &tv, nextcmd, TRUE) == FAIL)
+ if (eval0(arg, &tv, nextcmd, true) == FAIL) {
retval = NULL;
- else {
+ } else {
if (convert && tv.v_type == VAR_LIST) {
ga_init(&ga, (int)sizeof(char), 80);
if (tv.vval.v_list != NULL) {
- list_join(&ga, tv.vval.v_list, "\n");
- if (tv.vval.v_list->lv_len > 0)
+ tv_list_join(&ga, tv.vval.v_list, "\n");
+ if (tv_list_len(tv.vval.v_list) > 0) {
ga_append(&ga, NL);
+ }
}
ga_append(&ga, NUL);
- retval = (char_u *)ga.ga_data;
+ retval = (char *)ga.ga_data;
} else if (convert && tv.v_type == VAR_FLOAT) {
- vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
- retval = vim_strsave(numbuf);
- } else
- retval = vim_strsave(get_tv_string(&tv));
- clear_tv(&tv);
+ char numbuf[NUMBUFLEN];
+ vim_snprintf(numbuf, NUMBUFLEN, "%g", tv.vval.v_float);
+ retval = xstrdup(numbuf);
+ } else {
+ retval = xstrdup(tv_get_string(&tv));
+ }
+ tv_clear(&tv);
}
- return retval;
+ return (char_u *)retval;
}
/*
@@ -994,19 +1064,19 @@ char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox)
* Evaluates "expr" silently.
* Returns -1 for an error.
*/
-int eval_to_number(char_u *expr)
+varnumber_T eval_to_number(char_u *expr)
{
typval_T rettv;
- int retval;
+ varnumber_T retval;
char_u *p = skipwhite(expr);
++emsg_off;
- if (eval1(&p, &rettv, TRUE) == FAIL)
+ if (eval1(&p, &rettv, true) == FAIL) {
retval = -1;
- else {
- retval = get_tv_number_chk(&rettv, NULL);
- clear_tv(&rettv);
+ } else {
+ retval = tv_get_number_chk(&rettv, NULL);
+ tv_clear(&rettv);
}
--emsg_off;
@@ -1037,10 +1107,11 @@ static void restore_vimvar(int idx, typval_T *save_tv)
vimvars[idx].vv_tv = *save_tv;
if (vimvars[idx].vv_type == VAR_UNKNOWN) {
hi = hash_find(&vimvarht, vimvars[idx].vv_di.di_key);
- if (HASHITEM_EMPTY(hi))
- EMSG2(_(e_intern2), "restore_vimvar()");
- else
+ if (HASHITEM_EMPTY(hi)) {
+ internal_error("restore_vimvar()");
+ } else {
hash_remove(&vimvarht, hi);
+ }
}
}
@@ -1063,11 +1134,12 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr)
if (p_verbose == 0)
++emsg_off;
- if (eval1(&p, &rettv, TRUE) == OK) {
- if (rettv.v_type != VAR_LIST)
- clear_tv(&rettv);
- else
+ if (eval1(&p, &rettv, true) == OK) {
+ if (rettv.v_type != VAR_LIST) {
+ tv_clear(&rettv);
+ } else {
list = rettv.vval.v_list;
+ }
}
if (p_verbose == 0)
@@ -1077,60 +1149,49 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr)
return list;
}
-/*
- * "list" is supposed to contain two items: a word and a number. Return the
- * word in "pp" and the number as the return value.
- * Return -1 if anything isn't right.
- * Used to get the good word and score from the eval_spell_expr() result.
- */
-int get_spellword(list_T *list, char_u **pp)
+/// Get spell word from an entry from spellsuggest=expr:
+///
+/// Entry in question is supposed to be a list (to be checked by the caller)
+/// with two items: a word and a score represented as an unsigned number
+/// (whether it actually is unsigned is not checked).
+///
+/// Used to get the good word and score from the eval_spell_expr() result.
+///
+/// @param[in] list List to get values from.
+/// @param[out] ret_word Suggested word. Not initialized if return value is
+/// -1.
+///
+/// @return -1 in case of error, score otherwise.
+int get_spellword(list_T *const list, const char **ret_word)
{
- listitem_T *li;
-
- li = list->lv_first;
- if (li == NULL)
+ if (tv_list_len(list) != 2) {
+ EMSG(_("E5700: Expression from 'spellsuggest' must yield lists with "
+ "exactly two values"));
return -1;
- *pp = get_tv_string(&li->li_tv);
-
- li = li->li_next;
- if (li == NULL)
+ }
+ *ret_word = tv_list_find_str(list, 0);
+ if (*ret_word == NULL) {
return -1;
- return get_tv_number(&li->li_tv);
-}
-
-/*
- * Top level evaluation function.
- * Returns an allocated typval_T with the result.
- * Returns NULL when there is an error.
- */
-typval_T *eval_expr(char_u *arg, char_u **nextcmd)
-{
- typval_T *tv = xmalloc(sizeof(typval_T));
-
- if (eval0(arg, tv, nextcmd, TRUE) == FAIL) {
- xfree(tv);
- return NULL;
}
-
- return tv;
+ return tv_list_find_nr(list, -1, NULL);
}
-// Call some vimL function and return the result in "*rettv".
+// Call some vim script function and return the result in "*rettv".
// Uses argv[argc] for the function arguments. Only Number and String
// arguments are currently supported.
//
// Return OK or FAIL.
int call_vim_function(
- char_u *func,
+ const char_u *func,
int argc,
- char_u **argv,
- int safe, // use the sandbox
+ const char_u *const *const argv,
+ bool safe, // use the sandbox
int str_arg_only, // all arguments are strings
typval_T *rettv
)
{
- long n;
+ varnumber_T n;
int len;
int doesrange;
void *save_funccalp = NULL;
@@ -1149,15 +1210,19 @@ int call_vim_function(
if (str_arg_only) {
len = 0;
} else {
- // Recognize a number argument, the others must be strings.
+ // Recognize a number argument, the others must be strings. A dash
+ // is a string too.
vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0);
+ if (len == 1 && *argv[i] == '-') {
+ len = 0;
+ }
}
if (len != 0 && len == (int)STRLEN(argv[i])) {
argvars[i].v_type = VAR_NUMBER;
argvars[i].vval.v_number = n;
} else {
argvars[i].v_type = VAR_STRING;
- argvars[i].vval.v_string = argv[i];
+ argvars[i].vval.v_string = (char_u *)argv[i];
}
}
@@ -1166,10 +1231,10 @@ int call_vim_function(
++sandbox;
}
- rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
- ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars,
+ rettv->v_type = VAR_UNKNOWN; // tv_clear() uses this.
+ ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &doesrange, true, NULL);
+ &doesrange, true, NULL, NULL);
if (safe) {
--sandbox;
restore_funccal(save_funccalp);
@@ -1177,74 +1242,72 @@ int call_vim_function(
xfree(argvars);
if (ret == FAIL) {
- clear_tv(rettv);
+ tv_clear(rettv);
}
return ret;
}
-/*
- * Call vimL function "func" and return the result as a number.
- * Returns -1 when calling the function fails.
- * Uses argv[argc] for the function arguments.
- */
-long
-call_func_retnr (
- char_u *func,
- int argc,
- char_u **argv,
- int safe /* use the sandbox */
-)
+/// Call Vim script function and return the result as a number
+///
+/// @param[in] func Function name.
+/// @param[in] argc Number of arguments.
+/// @param[in] argv Array with string arguments.
+/// @param[in] safe Use with sandbox.
+///
+/// @return -1 when calling function fails, result of function otherwise.
+varnumber_T call_func_retnr(char_u *func, int argc,
+ const char_u *const *const argv, int safe)
{
typval_T rettv;
- long retval;
+ varnumber_T retval;
/* All arguments are passed as strings, no conversion to number. */
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
return -1;
- retval = get_tv_number_chk(&rettv, NULL);
- clear_tv(&rettv);
+ retval = tv_get_number_chk(&rettv, NULL);
+ tv_clear(&rettv);
return retval;
}
-/*
- * Call vimL function "func" and return the result as a string.
- * Returns NULL when calling the function fails.
- * Uses argv[argc] for the function arguments.
- */
-void *
-call_func_retstr (
- char_u *func,
- int argc,
- char_u **argv,
- int safe /* use the sandbox */
-)
+/// Call Vim script function and return the result as a string
+///
+/// @param[in] func Function name.
+/// @param[in] argc Number of arguments.
+/// @param[in] argv Array with string arguments.
+/// @param[in] safe Use the sandbox.
+///
+/// @return [allocated] NULL when calling function fails, allocated string
+/// otherwise.
+char *call_func_retstr(const char *const func, int argc,
+ const char_u *const *argv,
+ bool safe)
+ FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
typval_T rettv;
- char_u *retval;
-
- /* All arguments are passed as strings, no conversion to number. */
- if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
+ // All arguments are passed as strings, no conversion to number.
+ if (call_vim_function((const char_u *)func, argc, argv, safe, true, &rettv)
+ == FAIL) {
return NULL;
+ }
- retval = vim_strsave(get_tv_string(&rettv));
- clear_tv(&rettv);
+ char *const retval = xstrdup(tv_get_string(&rettv));
+ tv_clear(&rettv);
return retval;
}
-/*
- * Call vimL function "func" and return the result as a List.
- * Uses argv[argc] for the function arguments.
- * Returns NULL when there is something wrong.
- */
-void *
-call_func_retlist (
- char_u *func,
- int argc,
- char_u **argv,
- int safe /* use the sandbox */
-)
+/// Call Vim script function and return the result as a List
+///
+/// @param[in] func Function name.
+/// @param[in] argc Number of arguments.
+/// @param[in] argv Array with string arguments.
+/// @param[in] safe Use the sandbox.
+///
+/// @return [allocated] NULL when calling function fails or return tv is not a
+/// List, allocated List otherwise.
+void *call_func_retlist(char_u *func, int argc, const char_u *const *argv,
+ bool safe)
{
typval_T rettv;
@@ -1253,7 +1316,7 @@ call_func_retlist (
return NULL;
if (rettv.v_type != VAR_LIST) {
- clear_tv(&rettv);
+ tv_clear(&rettv);
return NULL;
}
@@ -1325,7 +1388,7 @@ void prof_child_exit(proftime_T *tm /* where waittime was stored */
int eval_foldexpr(char_u *arg, int *cp)
{
typval_T tv;
- int retval;
+ varnumber_T retval;
char_u *s;
int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
OPT_LOCAL);
@@ -1351,14 +1414,14 @@ int eval_foldexpr(char_u *arg, int *cp)
*cp = *s++;
retval = atol((char *)s);
}
- clear_tv(&tv);
+ tv_clear(&tv);
}
--emsg_off;
if (use_sandbox)
--sandbox;
--textlock;
- return retval;
+ return (int)retval;
}
/*
@@ -1382,22 +1445,24 @@ void ex_let(exarg_T *eap)
char_u *argend;
int first = TRUE;
- argend = skip_var_list(arg, &var_count, &semicolon);
- if (argend == NULL)
+ argend = (char_u *)skip_var_list(arg, &var_count, &semicolon);
+ if (argend == NULL) {
return;
- if (argend > arg && argend[-1] == '.') /* for var.='str' */
- --argend;
+ }
+ if (argend > arg && argend[-1] == '.') { // For var.='str'.
+ argend--;
+ }
expr = skipwhite(argend);
if (*expr != '=' && !(vim_strchr((char_u *)"+-.", *expr) != NULL
&& expr[1] == '=')) {
// ":let" without "=": list variables
- if (*arg == '[')
+ if (*arg == '[') {
EMSG(_(e_invarg));
- else if (!ends_excmd(*arg))
- /* ":let var1 var2" */
- arg = list_arg_vars(eap, arg, &first);
- else if (!eap->skip) {
- /* ":let" */
+ } else if (!ends_excmd(*arg)) {
+ // ":let var1 var2"
+ arg = (char_u *)list_arg_vars(eap, (const char *)arg, &first);
+ } else if (!eap->skip) {
+ // ":let"
list_glob_vars(&first);
list_buf_vars(&first);
list_win_vars(&first);
@@ -1423,13 +1488,13 @@ void ex_let(exarg_T *eap)
++emsg_skip;
i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip);
if (eap->skip) {
- if (i != FAIL)
- clear_tv(&rettv);
- --emsg_skip;
+ if (i != FAIL) {
+ tv_clear(&rettv);
+ }
+ emsg_skip--;
} else if (i != FAIL) {
- (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count,
- op);
- clear_tv(&rettv);
+ (void)ex_let_vars(eap->arg, &rettv, false, semicolon, var_count, op);
+ tv_clear(&rettv);
}
}
}
@@ -1442,8 +1507,8 @@ void ex_let(exarg_T *eap)
* or concatenate.
* Returns OK or FAIL;
*/
-static int
-ex_let_vars (
+static int
+ex_let_vars(
char_u *arg_start,
typval_T *tv,
int copy, /* copy values from "tv", don't move */
@@ -1452,10 +1517,7 @@ ex_let_vars (
char_u *nextchars
)
{
- char_u *arg = arg_start;
- list_T *l;
- int i;
- listitem_T *item;
+ char_u *arg = arg_start;
typval_T ltv;
if (*arg != '[') {
@@ -1467,55 +1529,62 @@ ex_let_vars (
return OK;
}
- /*
- * ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
- */
- if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) {
+ // ":let [v1, v2] = list" or ":for [v1, v2] in listlist"
+ if (tv->v_type != VAR_LIST) {
EMSG(_(e_listreq));
return FAIL;
}
+ list_T *const l = tv->vval.v_list;
- i = list_len(l);
- if (semicolon == 0 && var_count < i) {
+ const int len = tv_list_len(l);
+ if (semicolon == 0 && var_count < len) {
EMSG(_("E687: Less targets than List items"));
return FAIL;
}
- if (var_count - semicolon > i) {
+ if (var_count - semicolon > len) {
EMSG(_("E688: More targets than List items"));
return FAIL;
}
+ // List l may actually be NULL, but it should fail with E688 or even earlier
+ // if you try to do ":let [] = v:_null_list".
+ assert(l != NULL);
- item = l->lv_first;
+ listitem_T *item = tv_list_first(l);
+ size_t rest_len = tv_list_len(l);
while (*arg != ']') {
arg = skipwhite(arg + 1);
- arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars);
- item = item->li_next;
- if (arg == NULL)
+ arg = ex_let_one(arg, TV_LIST_ITEM_TV(item), true, (const char_u *)",;]",
+ nextchars);
+ if (arg == NULL) {
return FAIL;
+ }
+ rest_len--;
+ item = TV_LIST_ITEM_NEXT(l, item);
arg = skipwhite(arg);
if (*arg == ';') {
/* Put the rest of the list (may be empty) in the var after ';'.
* Create a new list for this. */
- l = list_alloc();
+ list_T *const rest_list = tv_list_alloc(rest_len);
while (item != NULL) {
- list_append_tv(l, &item->li_tv);
- item = item->li_next;
+ tv_list_append_tv(rest_list, TV_LIST_ITEM_TV(item));
+ item = TV_LIST_ITEM_NEXT(l, item);
}
ltv.v_type = VAR_LIST;
- ltv.v_lock = 0;
- ltv.vval.v_list = l;
- l->lv_refcount = 1;
-
- arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE,
- (char_u *)"]", nextchars);
- clear_tv(&ltv);
- if (arg == NULL)
+ ltv.v_lock = VAR_UNLOCKED;
+ ltv.vval.v_list = rest_list;
+ tv_list_ref(rest_list);
+
+ arg = ex_let_one(skipwhite(arg + 1), &ltv, false,
+ (char_u *)"]", nextchars);
+ tv_clear(&ltv);
+ if (arg == NULL) {
return FAIL;
+ }
break;
} else if (*arg != ',' && *arg != ']') {
- EMSG2(_(e_intern2), "ex_let_vars()");
+ internal_error("ex_let_vars()");
return FAIL;
}
}
@@ -1530,9 +1599,11 @@ ex_let_vars (
* for "[var, var; var]" set "semicolon".
* Return NULL for an error.
*/
-static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon)
+static const char_u *skip_var_list(const char_u *arg, int *var_count,
+ int *semicolon)
{
- char_u *p, *s;
+ const char_u *p;
+ const char_u *s;
if (*arg == '[') {
/* "[var, var]": find the matching ']'. */
@@ -1569,7 +1640,7 @@ static char_u *skip_var_list(char_u *arg, int *var_count, int *semicolon)
* Skip one (assignable) variable name, including @r, $VAR, &option, d.key,
* l[idx].
*/
-static char_u *skip_var_one(char_u *arg)
+static const char_u *skip_var_one(const char_u *arg)
{
if (*arg == '@' && arg[1] != NUL)
return arg + 2;
@@ -1581,7 +1652,8 @@ static char_u *skip_var_one(char_u *arg)
* List variables for hashtab "ht" with prefix "prefix".
* If "empty" is TRUE also list NULL strings as empty strings.
*/
-static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first)
+static void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty,
+ int *first)
{
hashitem_T *hi;
dictitem_T *di;
@@ -1590,11 +1662,12 @@ static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *f
todo = (int)ht->ht_used;
for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) {
if (!HASHITEM_EMPTY(hi)) {
- --todo;
- di = HI2DI(hi);
+ todo--;
+ di = TV_DICT_HI2DI(hi);
if (empty || di->di_tv.v_type != VAR_STRING
- || di->di_tv.vval.v_string != NULL)
+ || di->di_tv.vval.v_string != NULL) {
list_one_var(di, prefix, first);
+ }
}
}
}
@@ -1604,7 +1677,7 @@ static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *f
*/
static void list_glob_vars(int *first)
{
- list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first);
+ list_hashtable_vars(&globvarht, "", true, first);
}
/*
@@ -1612,14 +1685,7 @@ static void list_glob_vars(int *first)
*/
static void list_buf_vars(int *first)
{
- char_u numbuf[NUMBUFLEN];
-
- list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
- TRUE, first);
-
- sprintf((char *)numbuf, "%" PRId64, (int64_t)curbuf->b_changedtick);
- list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER,
- numbuf, first);
+ list_hashtable_vars(&curbuf->b_vars->dv_hashtab, "b:", true, first);
}
/*
@@ -1627,8 +1693,7 @@ static void list_buf_vars(int *first)
*/
static void list_win_vars(int *first)
{
- list_hashtable_vars(&curwin->w_vars->dv_hashtab,
- (char_u *)"w:", TRUE, first);
+ list_hashtable_vars(&curwin->w_vars->dv_hashtab, "w:", true, first);
}
/*
@@ -1636,8 +1701,7 @@ static void list_win_vars(int *first)
*/
static void list_tab_vars(int *first)
{
- list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
- (char_u *)"t:", TRUE, first);
+ list_hashtable_vars(&curtab->tp_vars->dv_hashtab, "t:", true, first);
}
/*
@@ -1645,7 +1709,7 @@ static void list_tab_vars(int *first)
*/
static void list_vim_vars(int *first)
{
- list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first);
+ list_hashtable_vars(&vimvarht, "v:", false, first);
}
/*
@@ -1653,9 +1717,9 @@ static void list_vim_vars(int *first)
*/
static void list_script_vars(int *first)
{
- if (current_SID > 0 && current_SID <= ga_scripts.ga_len)
- list_hashtable_vars(&SCRIPT_VARS(current_SID),
- (char_u *)"s:", FALSE, first);
+ if (current_SID > 0 && current_SID <= ga_scripts.ga_len) {
+ list_hashtable_vars(&SCRIPT_VARS(current_SID), "s:", false, first);
+ }
}
/*
@@ -1663,36 +1727,37 @@ static void list_script_vars(int *first)
*/
static void list_func_vars(int *first)
{
- if (current_funccal != NULL)
- list_hashtable_vars(&current_funccal->l_vars.dv_hashtab,
- (char_u *)"l:", FALSE, first);
+ if (current_funccal != NULL) {
+ list_hashtable_vars(&current_funccal->l_vars.dv_hashtab, "l:", false,
+ first);
+ }
}
/*
* List variables in "arg".
*/
-static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
+static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first)
{
int error = FALSE;
int len;
- char_u *name;
- char_u *name_start;
- char_u *arg_subsc;
- char_u *tofree;
+ const char *name;
+ const char *name_start;
typval_T tv;
while (!ends_excmd(*arg) && !got_int) {
if (error || eap->skip) {
- arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
+ arg = (const char *)find_name_end((char_u *)arg, NULL, NULL,
+ FNE_INCL_BR | FNE_CHECK_START);
if (!ascii_iswhite(*arg) && !ends_excmd(*arg)) {
emsg_severe = TRUE;
EMSG(_(e_trailing));
break;
}
} else {
- /* get_name_len() takes care of expanding curly braces */
+ // get_name_len() takes care of expanding curly braces
name_start = name = arg;
- len = get_name_len(&arg, &tofree, TRUE, TRUE);
+ char *tofree;
+ len = get_name_len(&arg, &tofree, true, true);
if (len <= 0) {
/* This is mainly to keep test 49 working: when expanding
* curly braces fails overrule the exception error message. */
@@ -1706,14 +1771,15 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
if (tofree != NULL) {
name = tofree;
}
- if (get_var_tv(name, len, &tv, NULL, true, false) == FAIL) {
+ if (get_var_tv((const char *)name, len, &tv, NULL, true, false)
+ == FAIL) {
error = true;
} else {
// handle d.key, l[idx], f(expr)
- arg_subsc = arg;
- if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL)
- error = TRUE;
- else {
+ const char *const arg_subsc = arg;
+ if (handle_subscript(&arg, &tv, true, true) == FAIL) {
+ error = true;
+ } else {
if (arg == arg_subsc && len == 2 && name[1] == ':') {
switch (*name) {
case 'g': list_glob_vars(first); break;
@@ -1727,20 +1793,18 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
EMSG2(_("E738: Can't list variables for %s"), name);
}
} else {
- int c;
-
- char_u *s = (char_u *) encode_tv2echo(&tv, NULL);
- c = *arg;
- *arg = NUL;
- list_one_var_a((char_u *)"",
- arg == arg_subsc ? name : name_start,
- tv.v_type,
- s == NULL ? (char_u *)"" : s,
- first);
- *arg = c;
+ char *const s = encode_tv2echo(&tv, NULL);
+ const char *const used_name = (arg == arg_subsc
+ ? name
+ : name_start);
+ const ptrdiff_t name_size = (used_name == tofree
+ ? (ptrdiff_t)strlen(used_name)
+ : (arg - used_name));
+ list_one_var_a("", used_name, name_size,
+ tv.v_type, s == NULL ? "" : s, first);
xfree(s);
}
- clear_tv(&tv);
+ tv_clear(&tv);
}
}
}
@@ -1748,152 +1812,154 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first)
xfree(tofree);
}
- arg = skipwhite(arg);
+ arg = (const char *)skipwhite((const char_u *)arg);
}
return arg;
}
-/*
- * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value.
- * Returns a pointer to the char just after the var name.
- * Returns NULL if there is an error.
- */
-static char_u *
-ex_let_one (
- char_u *arg, /* points to variable name */
- typval_T *tv, /* value to assign to variable */
- int copy, /* copy value from "tv" */
- char_u *endchars, /* valid chars after variable name or NULL */
- char_u *op /* "+", "-", "." or NULL*/
-)
-{
- int c1;
- char_u *name;
- char_u *p;
- char_u *arg_end = NULL;
+// 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.
+/// @param[in] tv Value to assign to the variable.
+/// @param[in] copy If true, copy value from `tv`.
+/// @param[in] endchars Valid characters after variable name or NULL.
+/// @param[in] op Operation performed: *op is `+`, `-`, `.` for `+=`, etc.
+/// NULL for `=`.
+///
+/// @return a pointer to the char just after the var name or NULL in case of
+/// error.
+static char_u *ex_let_one(char_u *arg, typval_T *const tv,
+ const bool copy, const char_u *const endchars,
+ const char_u *const op)
+ FUNC_ATTR_NONNULL_ARG(1, 2) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ char_u *arg_end = NULL;
int len;
int opt_flags;
- char_u *tofree = NULL;
+ char_u *tofree = NULL;
/*
* ":let $VAR = expr": Set environment variable.
*/
if (*arg == '$') {
- /* Find the end of the name. */
- ++arg;
- name = arg;
- len = get_env_len(&arg);
- if (len == 0)
+ // Find the end of the name.
+ arg++;
+ char *name = (char *)arg;
+ len = get_env_len((const char_u **)&arg);
+ if (len == 0) {
EMSG2(_(e_invarg2), name - 1);
- else {
- if (op != NULL && (*op == '+' || *op == '-'))
+ } else {
+ if (op != NULL && (*op == '+' || *op == '-')) {
EMSG2(_(e_letwrong), op);
- else if (endchars != NULL
- && vim_strchr(endchars, *skipwhite(arg)) == NULL)
+ } else if (endchars != NULL
+ && vim_strchr(endchars, *skipwhite(arg)) == NULL) {
EMSG(_(e_letunexp));
- else if (!check_secure()) {
- c1 = name[len];
+ } else if (!check_secure()) {
+ const char c1 = name[len];
name[len] = NUL;
- p = get_tv_string_chk(tv);
+ const char *p = tv_get_string_chk(tv);
if (p != NULL && op != NULL && *op == '.') {
- char *s = vim_getenv((char *)name);
+ char *s = vim_getenv(name);
if (s != NULL) {
- p = tofree = concat_str((char_u *)s, p);
+ tofree = concat_str((const char_u *)s, (const char_u *)p);
+ p = (const char *)tofree;
xfree(s);
}
}
if (p != NULL) {
- vim_setenv((char *)name, (char *)p);
- if (STRICMP(name, "HOME") == 0)
+ vim_setenv(name, p);
+ if (STRICMP(name, "HOME") == 0) {
init_homedir();
- else if (didset_vim && STRICMP(name, "VIM") == 0)
- didset_vim = FALSE;
- else if (didset_vimruntime
- && STRICMP(name, "VIMRUNTIME") == 0)
- didset_vimruntime = FALSE;
+ } else if (didset_vim && STRICMP(name, "VIM") == 0) {
+ didset_vim = false;
+ } else if (didset_vimruntime
+ && STRICMP(name, "VIMRUNTIME") == 0) {
+ didset_vimruntime = false;
+ }
arg_end = arg;
}
name[len] = c1;
xfree(tofree);
}
}
- }
- /*
- * ":let &option = expr": Set option value.
- * ":let &l:option = expr": Set local option value.
- * ":let &g:option = expr": Set global option value.
- */
- else if (*arg == '&') {
- /* Find the end of the name. */
- p = find_option_end(&arg, &opt_flags);
- if (p == NULL || (endchars != NULL
- && vim_strchr(endchars, *skipwhite(p)) == NULL))
+ // ":let &option = expr": Set option value.
+ // ":let &l:option = expr": Set local option value.
+ // ":let &g:option = expr": Set global option value.
+ } else if (*arg == '&') {
+ // Find the end of the name.
+ char *const p = (char *)find_option_end((const char **)&arg, &opt_flags);
+ if (p == NULL
+ || (endchars != NULL
+ && vim_strchr(endchars, *skipwhite((const char_u *)p)) == NULL)) {
EMSG(_(e_letunexp));
- else {
- long n;
+ } else {
int opt_type;
long numval;
- char_u *stringval = NULL;
- char_u *s;
+ char *stringval = NULL;
- c1 = *p;
+ const char c1 = *p;
*p = NUL;
- n = get_tv_number(tv);
- s = get_tv_string_chk(tv); /* != NULL if number or string */
+ varnumber_T n = tv_get_number(tv);
+ const char *s = tv_get_string_chk(tv); // != NULL if number or string.
if (s != NULL && op != NULL && *op != '=') {
- opt_type = get_option_value(arg, &numval,
- &stringval, opt_flags);
+ opt_type = get_option_value(arg, &numval, (char_u **)&stringval,
+ opt_flags);
if ((opt_type == 1 && *op == '.')
- || (opt_type == 0 && *op != '.'))
+ || (opt_type == 0 && *op != '.')) {
EMSG2(_(e_letwrong), op);
- else {
- if (opt_type == 1) { /* number */
- if (*op == '+')
+ s = NULL; // don't set the value
+ } else {
+ if (opt_type == 1) { // number
+ if (*op == '+') {
n = numval + n;
- else
+ } else {
n = numval - n;
- } else if (opt_type == 0 && stringval != NULL) { /* string */
- s = concat_str(stringval, s);
- xfree(stringval);
- stringval = s;
+ }
+ } else if (opt_type == 0 && stringval != NULL) { // string
+ char *const oldstringval = stringval;
+ stringval = (char *)concat_str((const char_u *)stringval,
+ (const char_u *)s);
+ xfree(oldstringval);
+ s = stringval;
}
}
}
if (s != NULL) {
- set_option_value(arg, n, s, opt_flags);
- arg_end = p;
+ set_option_value((const char *)arg, n, s, opt_flags);
+ arg_end = (char_u *)p;
}
*p = c1;
xfree(stringval);
}
- }
- /*
- * ":let @r = expr": Set register contents.
- */
- else if (*arg == '@') {
- ++arg;
- if (op != NULL && (*op == '+' || *op == '-'))
- EMSG2(_(e_letwrong), op);
- else if (endchars != NULL
- && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL)
+ // ":let @r = expr": Set register contents.
+ } else if (*arg == '@') {
+ arg++;
+ if (op != NULL && (*op == '+' || *op == '-')) {
+ emsgf(_(e_letwrong), op);
+ } else if (endchars != NULL
+ && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) {
EMSG(_(e_letunexp));
- else {
- char_u *ptofree = NULL;
+ } else {
char_u *s;
- p = get_tv_string_chk(tv);
+ char_u *ptofree = NULL;
+ const char *p = tv_get_string_chk(tv);
if (p != NULL && op != NULL && *op == '.') {
s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc);
if (s != NULL) {
- p = ptofree = concat_str(s, p);
+ ptofree = concat_str(s, (const char_u *)p);
+ p = (const char *)ptofree;
xfree(s);
}
}
if (p != NULL) {
- write_reg_contents(*arg == '@' ? '"' : *arg, p, STRLEN(p), false);
+ write_reg_contents(*arg == '@' ? '"' : *arg,
+ (const char_u *)p, STRLEN(p), false);
arg_end = arg + 1;
}
xfree(ptofree);
@@ -1906,11 +1972,11 @@ ex_let_one (
else if (eval_isnamec1(*arg) || *arg == '{') {
lval_T lv;
- p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START);
+ char_u *const p = get_lval(arg, tv, &lv, false, false, 0, FNE_CHECK_START);
if (p != NULL && lv.ll_name != NULL) {
- if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL)
+ if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) {
EMSG(_(e_letunexp));
- else {
+ } else {
set_var_lval(&lv, p, tv, copy, op);
arg_end = p;
}
@@ -1922,57 +1988,41 @@ ex_let_one (
return arg_end;
}
-/*
- * If "arg" is equal to "b:changedtick" give an error and return TRUE.
- */
-static int check_changedtick(char_u *arg)
-{
- if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) {
- EMSG2(_(e_readonlyvar), arg);
- return TRUE;
- }
- return FALSE;
-}
+// TODO(ZyX-I): move to eval/executor
-/*
- * Get an lval: variable, Dict item or List item that can be assigned a value
- * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]",
- * "name.key", "name.key[expr]" etc.
- * Indexing only works if "name" is an existing List or Dictionary.
- * "name" points to the start of the name.
- * If "rettv" is not NULL it points to the value to be assigned.
- * "unlet" is TRUE for ":unlet": slightly different behavior when something is
- * wrong; must end in space or cmd separator.
- *
- * flags:
- * GLV_QUIET: do not give error messages
- * GLV_NO_AUTOLOAD: do not use script autoloading
- *
- * Returns a pointer to just after the name, including indexes.
- * When an evaluation error occurs "lp->ll_name" is NULL;
- * Returns NULL for a parsing error. Still need to free items in "lp"!
- */
-static char_u *
-get_lval (
- char_u *name,
- typval_T *rettv,
- lval_T *lp,
- int unlet,
- int skip,
- int flags, /* GLV_ values */
- int fne_flags /* flags for find_name_end() */
-)
+/// Get an lvalue
+///
+/// Lvalue may be
+/// - variable: "name", "na{me}"
+/// - dictionary item: "dict.key", "dict['key']"
+/// - list item: "list[expr]"
+/// - list slice: "list[expr:expr]"
+///
+/// Indexing only works if trying to use it with an existing List or Dictionary.
+///
+/// @param[in] name Name to parse.
+/// @param rettv Pointer to the value to be assigned or NULL.
+/// @param[out] lp Lvalue definition. When evaluation errors occur `->ll_name`
+/// is NULL.
+/// @param[in] unlet True if using `:unlet`. This results in slightly
+/// different behaviour when something is wrong; must end in
+/// space or cmd separator.
+/// @param[in] skip True when skipping.
+/// @param[in] flags @see GetLvalFlags.
+/// @param[in] fne_flags Flags for find_name_end().
+///
+/// @return A pointer to just after the name, including indexes. Returns NULL
+/// for a parsing error, but it is still needed to free items in lp.
+static char_u *get_lval(char_u *const name, typval_T *const rettv,
+ lval_T *const lp, const bool unlet, const bool skip,
+ const int flags, const int fne_flags)
+ FUNC_ATTR_NONNULL_ARG(1, 3)
{
- char_u *p;
- char_u *expr_start, *expr_end;
- int cc;
dictitem_T *v;
typval_T var1;
typval_T var2;
int empty1 = FALSE;
listitem_T *ni;
- char_u *key = NULL;
- int len;
hashtab_T *ht;
int quiet = flags & GLV_QUIET;
@@ -1980,13 +2030,19 @@ get_lval (
memset(lp, 0, sizeof(lval_T));
if (skip) {
- /* When skipping just find the end of the name. */
- lp->ll_name = name;
- return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags);
+ // When skipping just find the end of the name.
+ lp->ll_name = (const char *)name;
+ return (char_u *)find_name_end((const char_u *)name, NULL, NULL,
+ FNE_INCL_BR | fne_flags);
}
- /* Find the end of the name. */
- p = find_name_end(name, &expr_start, &expr_end, fne_flags);
+ // Find the end of the name.
+ char_u *expr_start;
+ char_u *expr_end;
+ char_u *p = (char_u *)find_name_end(name,
+ (const char_u **)&expr_start,
+ (const char_u **)&expr_end,
+ fne_flags);
if (expr_start != NULL) {
/* Don't expand the name when we already know there is an error. */
if (unlet && !ascii_iswhite(*p) && !ends_excmd(*p)
@@ -1995,7 +2051,9 @@ get_lval (
return NULL;
}
- lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p);
+ lp->ll_exp_name = (char *)make_expanded_name(name, expr_start, expr_end,
+ (char_u *)p);
+ lp->ll_name = lp->ll_exp_name;
if (lp->ll_exp_name == NULL) {
/* Report an invalid expression in braces, unless the
* expression evaluation has been cancelled due to an
@@ -2005,28 +2063,39 @@ get_lval (
EMSG2(_(e_invarg2), name);
return NULL;
}
+ lp->ll_name_len = 0;
+ } else {
+ lp->ll_name_len = strlen(lp->ll_name);
}
- lp->ll_name = lp->ll_exp_name;
- } else
- lp->ll_name = name;
+ } else {
+ lp->ll_name = (const char *)name;
+ lp->ll_name_len = (size_t)((const char *)p - lp->ll_name);
+ }
- /* Without [idx] or .key we are done. */
- if ((*p != '[' && *p != '.') || lp->ll_name == NULL)
+ // Without [idx] or .key we are done.
+ if ((*p != '[' && *p != '.') || lp->ll_name == NULL) {
return p;
+ }
- cc = *p;
- *p = NUL;
- v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD);
- if (v == NULL && !quiet)
- EMSG2(_(e_undefvar), lp->ll_name);
- *p = cc;
- if (v == NULL)
+ // Only pass &ht when we would write to the variable, it prevents autoload
+ // as well.
+ v = find_var(lp->ll_name, lp->ll_name_len,
+ (flags & GLV_READ_ONLY) ? NULL : &ht,
+ flags & GLV_NO_AUTOLOAD);
+ if (v == NULL && !quiet) {
+ emsgf(_("E121: Undefined variable: %.*s"),
+ (int)lp->ll_name_len, lp->ll_name);
+ }
+ if (v == NULL) {
return NULL;
+ }
/*
* Loop until no more [idx] or .key is following.
*/
lp->ll_tv = &v->di_tv;
+ var1.v_type = VAR_UNKNOWN;
+ var2.v_type = VAR_UNKNOWN;
while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) {
if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
&& !(lp->ll_tv->v_type == VAR_DICT
@@ -2041,29 +2110,32 @@ get_lval (
return NULL;
}
- len = -1;
+ int len = -1;
+ char_u *key = NULL;
if (*p == '.') {
key = p + 1;
- for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len)
- ;
+ for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; len++) {
+ }
if (len == 0) {
- if (!quiet)
- EMSG(_(e_emptykey));
+ if (!quiet) {
+ EMSG(_("E713: Cannot use empty key after ."));
+ }
return NULL;
}
p = key + len;
} else {
/* Get the index [expr] or the first index [expr: ]. */
p = skipwhite(p + 1);
- if (*p == ':')
- empty1 = TRUE;
- else {
- empty1 = FALSE;
- if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */
+ if (*p == ':') {
+ empty1 = true;
+ } else {
+ empty1 = false;
+ if (eval1(&p, &var1, true) == FAIL) { // Recursive!
return NULL;
- if (get_tv_string_chk(&var1) == NULL) {
- /* not a number or string */
- clear_tv(&var1);
+ }
+ if (!tv_check_str(&var1)) {
+ // Not a number or string.
+ tv_clear(&var1);
return NULL;
}
}
@@ -2071,35 +2143,33 @@ get_lval (
/* Optionally get the second index [ :expr]. */
if (*p == ':') {
if (lp->ll_tv->v_type == VAR_DICT) {
- if (!quiet)
+ if (!quiet) {
EMSG(_(e_dictrange));
- if (!empty1)
- clear_tv(&var1);
+ }
+ tv_clear(&var1);
return NULL;
}
if (rettv != NULL && (rettv->v_type != VAR_LIST
|| rettv->vval.v_list == NULL)) {
- if (!quiet)
+ if (!quiet) {
EMSG(_("E709: [:] requires a List value"));
- if (!empty1)
- clear_tv(&var1);
+ }
+ tv_clear(&var1);
return NULL;
}
p = skipwhite(p + 1);
- if (*p == ']')
- lp->ll_empty2 = TRUE;
- else {
- lp->ll_empty2 = FALSE;
- if (eval1(&p, &var2, TRUE) == FAIL) { /* recursive! */
- if (!empty1)
- clear_tv(&var1);
+ if (*p == ']') {
+ lp->ll_empty2 = true;
+ } else {
+ lp->ll_empty2 = false;
+ if (eval1(&p, &var2, true) == FAIL) { // Recursive!
+ tv_clear(&var1);
return NULL;
}
- if (get_tv_string_chk(&var2) == NULL) {
- /* not a number or string */
- if (!empty1)
- clear_tv(&var1);
- clear_tv(&var2);
+ if (!tv_check_str(&var2)) {
+ // Not a number or string.
+ tv_clear(&var1);
+ tv_clear(&var2);
return NULL;
}
}
@@ -2108,12 +2178,11 @@ get_lval (
lp->ll_range = FALSE;
if (*p != ']') {
- if (!quiet)
+ if (!quiet) {
EMSG(_(e_missbrac));
- if (!empty1)
- clear_tv(&var1);
- if (lp->ll_range && !lp->ll_empty2)
- clear_tv(&var2);
+ }
+ tv_clear(&var1);
+ tv_clear(&var2);
return NULL;
}
@@ -2123,18 +2192,12 @@ get_lval (
if (lp->ll_tv->v_type == VAR_DICT) {
if (len == -1) {
- /* "[key]": get key from "var1" */
- key = get_tv_string(&var1); /* is number or string */
- if (*key == NUL) {
- if (!quiet)
- EMSG(_(e_emptykey));
- clear_tv(&var1);
- return NULL;
- }
+ // "[key]": get key from "var1"
+ key = (char_u *)tv_get_string(&var1); // is number or string
}
lp->ll_list = NULL;
lp->ll_dict = lp->ll_tv->vval.v_dict;
- lp->ll_di = dict_find(lp->ll_dict, key, len);
+ lp->ll_di = tv_dict_find(lp->ll_dict, (const char *)key, len);
/* When assigning to a scope dictionary check that a function and
* variable name is valid (only variable name unless it is l: or
@@ -2146,16 +2209,19 @@ get_lval (
if (len != -1) {
prevval = key[len];
key[len] = NUL;
- } else
- prevval = 0; /* avoid compiler warning */
- wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE
- && rettv->v_type == VAR_FUNC
- && var_check_func_name(key, lp->ll_di == NULL))
- || !valid_varname(key);
- if (len != -1)
+ } else {
+ prevval = 0; // Avoid compiler warning.
+ }
+ wrong = ((lp->ll_dict->dv_scope == VAR_DEF_SCOPE
+ && tv_is_func(*rettv)
+ && !var_check_func_name((const char *)key, lp->ll_di == NULL))
+ || !valid_varname((const char *)key));
+ if (len != -1) {
key[len] = prevval;
- if (wrong)
+ }
+ if (wrong) {
return NULL;
+ }
}
if (lp->ll_di == NULL) {
@@ -2167,51 +2233,53 @@ get_lval (
/* Key does not exist in dict: may need to add it. */
if (*p == '[' || *p == '.' || unlet) {
- if (!quiet)
- EMSG2(_(e_dictkey), key);
- if (len == -1)
- clear_tv(&var1);
+ if (!quiet) {
+ emsgf(_(e_dictkey), key);
+ }
+ tv_clear(&var1);
return NULL;
}
- if (len == -1)
+ if (len == -1) {
lp->ll_newkey = vim_strsave(key);
- else
+ } else {
lp->ll_newkey = vim_strnsave(key, len);
- if (len == -1)
- clear_tv(&var1);
+ }
+ tv_clear(&var1);
break;
- } else if (var_check_ro(lp->ll_di->di_flags, name, false)) {
- // existing variable, need to check if it can be changed
+ // existing variable, need to check if it can be changed
+ } else if (!(flags & GLV_READ_ONLY) && var_check_ro(lp->ll_di->di_flags,
+ (const char *)name,
+ (size_t)(p - name))) {
+ tv_clear(&var1);
return NULL;
}
- if (len == -1)
- clear_tv(&var1);
+ tv_clear(&var1);
lp->ll_tv = &lp->ll_di->di_tv;
} else {
- /*
- * Get the number and item for the only or first index of the List.
- */
- if (empty1)
+ // Get the number and item for the only or first index of the List.
+ if (empty1) {
lp->ll_n1 = 0;
- else {
- lp->ll_n1 = get_tv_number(&var1); /* is number or string */
- clear_tv(&var1);
+ } else {
+ // Is number or string.
+ lp->ll_n1 = (long)tv_get_number(&var1);
}
+ tv_clear(&var1);
+
lp->ll_dict = NULL;
lp->ll_list = lp->ll_tv->vval.v_list;
- lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
+ lp->ll_li = tv_list_find(lp->ll_list, lp->ll_n1);
if (lp->ll_li == NULL) {
if (lp->ll_n1 < 0) {
lp->ll_n1 = 0;
- lp->ll_li = list_find(lp->ll_list, lp->ll_n1);
+ lp->ll_li = tv_list_find(lp->ll_list, lp->ll_n1);
}
}
if (lp->ll_li == NULL) {
- if (lp->ll_range && !lp->ll_empty2)
- clear_tv(&var2);
- if (!quiet)
+ tv_clear(&var2);
+ if (!quiet) {
EMSGN(_(e_listidx), lp->ll_n1);
+ }
return NULL;
}
@@ -2222,35 +2290,40 @@ get_lval (
* Otherwise "lp->ll_n2" is set to the second index.
*/
if (lp->ll_range && !lp->ll_empty2) {
- lp->ll_n2 = get_tv_number(&var2); /* is number or string */
- clear_tv(&var2);
+ lp->ll_n2 = (long)tv_get_number(&var2); // Is number or string.
+ tv_clear(&var2);
if (lp->ll_n2 < 0) {
- ni = list_find(lp->ll_list, lp->ll_n2);
+ ni = tv_list_find(lp->ll_list, lp->ll_n2);
if (ni == NULL) {
if (!quiet)
EMSGN(_(e_listidx), lp->ll_n2);
return NULL;
}
- lp->ll_n2 = list_idx_of_item(lp->ll_list, ni);
+ lp->ll_n2 = tv_list_idx_of_item(lp->ll_list, ni);
}
- /* Check that lp->ll_n2 isn't before lp->ll_n1. */
- if (lp->ll_n1 < 0)
- lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li);
+ // Check that lp->ll_n2 isn't before lp->ll_n1.
+ if (lp->ll_n1 < 0) {
+ lp->ll_n1 = tv_list_idx_of_item(lp->ll_list, lp->ll_li);
+ }
if (lp->ll_n2 < lp->ll_n1) {
- if (!quiet)
+ if (!quiet) {
EMSGN(_(e_listidx), lp->ll_n2);
+ }
return NULL;
}
}
- lp->ll_tv = &lp->ll_li->li_tv;
+ lp->ll_tv = TV_LIST_ITEM_TV(lp->ll_li);
}
}
+ tv_clear(&var1);
return p;
}
+// TODO(ZyX-I): move to eval/executor
+
/*
* Clear lval "lp" that was filled by get_lval().
*/
@@ -2260,281 +2333,159 @@ static 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".
* "endp" points to just after the parsed name.
* "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=".
*/
-static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)
+static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv,
+ int copy, const char_u *op)
{
int cc;
listitem_T *ri;
dictitem_T *di;
if (lp->ll_tv == NULL) {
- if (!check_changedtick(lp->ll_name)) {
- cc = *endp;
- *endp = NUL;
- if (op != NULL && *op != '=') {
- typval_T tv;
-
- // handle +=, -= and .=
- di = NULL;
- if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name),
- &tv, &di, true, false) == OK) {
- if ((di == NULL
- || (!var_check_ro(di->di_flags, lp->ll_name, false)
- && !tv_check_lock(di->di_tv.v_lock, lp->ll_name, false)))
- && tv_op(&tv, rettv, op) == OK) {
- set_var(lp->ll_name, &tv, false);
- }
- clear_tv(&tv);
+ cc = *endp;
+ *endp = NUL;
+ if (op != NULL && *op != '=') {
+ typval_T tv;
+
+ // handle +=, -= and .=
+ di = NULL;
+ if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name),
+ &tv, &di, true, false) == OK) {
+ if ((di == NULL
+ || (!var_check_ro(di->di_flags, (const char *)lp->ll_name,
+ TV_CSTRING)
+ && !tv_check_lock(di->di_tv.v_lock, (const char *)lp->ll_name,
+ TV_CSTRING)))
+ && eexe_mod_op(&tv, rettv, (const char *)op) == OK) {
+ set_var(lp->ll_name, lp->ll_name_len, &tv, false);
}
- } else
- set_var(lp->ll_name, rettv, copy);
- *endp = cc;
+ tv_clear(&tv);
+ }
+ } else {
+ set_var(lp->ll_name, lp->ll_name_len, rettv, copy);
}
+ *endp = cc;
} else if (tv_check_lock(lp->ll_newkey == NULL
? lp->ll_tv->v_lock
: lp->ll_tv->vval.v_dict->dv_lock,
- lp->ll_name, false)) {
+ (const char *)lp->ll_name, TV_CSTRING)) {
} else if (lp->ll_range) {
listitem_T *ll_li = lp->ll_li;
int ll_n1 = lp->ll_n1;
// Check whether any of the list items is locked
- for (listitem_T *ri = rettv->vval.v_list->lv_first;
+ for (ri = tv_list_first(rettv->vval.v_list);
ri != NULL && ll_li != NULL; ) {
- if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, false)) {
+ if (tv_check_lock(TV_LIST_ITEM_TV(ll_li)->v_lock,
+ (const char *)lp->ll_name,
+ TV_CSTRING)) {
return;
}
- ri = ri->li_next;
+ ri = TV_LIST_ITEM_NEXT(rettv->vval.v_list, ri);
if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1)) {
break;
}
- ll_li = ll_li->li_next;
+ ll_li = TV_LIST_ITEM_NEXT(lp->ll_list, ll_li);
ll_n1++;
}
/*
* Assign the List values to the list items.
*/
- for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) {
- if (op != NULL && *op != '=')
- tv_op(&lp->ll_li->li_tv, &ri->li_tv, op);
- else {
- clear_tv(&lp->ll_li->li_tv);
- copy_tv(&ri->li_tv, &lp->ll_li->li_tv);
+ for (ri = tv_list_first(rettv->vval.v_list); ri != NULL; ) {
+ if (op != NULL && *op != '=') {
+ eexe_mod_op(TV_LIST_ITEM_TV(lp->ll_li), TV_LIST_ITEM_TV(ri),
+ (const char *)op);
+ } else {
+ tv_clear(TV_LIST_ITEM_TV(lp->ll_li));
+ tv_copy(TV_LIST_ITEM_TV(ri), TV_LIST_ITEM_TV(lp->ll_li));
}
- ri = ri->li_next;
- if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1))
+ ri = TV_LIST_ITEM_NEXT(rettv->vval.v_list, ri);
+ if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) {
break;
- if (lp->ll_li->li_next == NULL) {
- /* Need to add an empty item. */
- list_append_number(lp->ll_list, 0);
- assert(lp->ll_li->li_next);
}
- lp->ll_li = lp->ll_li->li_next;
- ++lp->ll_n1;
+ assert(lp->ll_li != NULL);
+ if (TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li) == NULL) {
+ // Need to add an empty item.
+ tv_list_append_number(lp->ll_list, 0);
+ // ll_li may have become invalid after append, don’t use it.
+ lp->ll_li = tv_list_last(lp->ll_list); // Valid again.
+ } else {
+ lp->ll_li = TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li);
+ }
+ lp->ll_n1++;
}
- if (ri != NULL)
+ if (ri != NULL) {
EMSG(_("E710: List value has more items than target"));
- else if (lp->ll_empty2
- ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL)
- : lp->ll_n1 != lp->ll_n2)
+ } else if (lp->ll_empty2
+ ? (lp->ll_li != NULL
+ && TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li) != NULL)
+ : lp->ll_n1 != lp->ll_n2) {
EMSG(_("E711: List value has not enough items"));
+ }
} else {
- typval_T oldtv;
+ typval_T oldtv = TV_INITIAL_VALUE;
dict_T *dict = lp->ll_dict;
- bool watched = is_watched(dict);
+ bool watched = tv_dict_is_watched(dict);
- if (watched) {
- init_tv(&oldtv);
- }
-
- /*
- * Assign to a List or Dictionary item.
- */
+ // Assign to a List or Dictionary item.
if (lp->ll_newkey != NULL) {
if (op != NULL && *op != '=') {
EMSG2(_(e_letwrong), op);
return;
}
- /* Need to add an item to the Dictionary. */
- di = dictitem_alloc(lp->ll_newkey);
- if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) {
+ // Need to add an item to the Dictionary.
+ di = tv_dict_item_alloc((const char *)lp->ll_newkey);
+ if (tv_dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) {
xfree(di);
return;
}
lp->ll_tv = &di->di_tv;
} else {
if (watched) {
- copy_tv(lp->ll_tv, &oldtv);
+ tv_copy(lp->ll_tv, &oldtv);
}
if (op != NULL && *op != '=') {
- tv_op(lp->ll_tv, rettv, op);
+ eexe_mod_op(lp->ll_tv, rettv, (const char *)op);
goto notify;
} else {
- clear_tv(lp->ll_tv);
+ tv_clear(lp->ll_tv);
}
}
// Assign the value to the variable or list item.
if (copy) {
- copy_tv(rettv, lp->ll_tv);
+ tv_copy(rettv, lp->ll_tv);
} else {
*lp->ll_tv = *rettv;
lp->ll_tv->v_lock = 0;
- init_tv(rettv);
+ tv_init(rettv);
}
notify:
if (watched) {
if (oldtv.v_type == VAR_UNKNOWN) {
- dictwatcher_notify(dict, (char *)lp->ll_newkey, lp->ll_tv, NULL);
+ assert(lp->ll_newkey != NULL);
+ tv_dict_watcher_notify(dict, (char *)lp->ll_newkey, lp->ll_tv, NULL);
} else {
- dictitem_T *di = lp->ll_di;
- dictwatcher_notify(dict, (char *)di->di_key, lp->ll_tv, &oldtv);
- clear_tv(&oldtv);
+ dictitem_T *di_ = lp->ll_di;
+ assert(di_->di_key != NULL);
+ tv_dict_watcher_notify(dict, (char *)di_->di_key, lp->ll_tv, &oldtv);
+ tv_clear(&oldtv);
}
}
}
}
-/*
- * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2"
- * Returns OK or FAIL.
- */
-static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
-{
- long n;
- char_u numbuf[NUMBUFLEN];
- char_u *s;
-
- // Can't do anything with a Funcref, a Dict or special value on the right.
- if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) {
- switch (tv1->v_type) {
- case VAR_DICT:
- case VAR_FUNC:
- case VAR_SPECIAL:
- break;
-
- case VAR_LIST:
- if (*op != '+' || tv2->v_type != VAR_LIST)
- break;
- /* List += List */
- if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL)
- list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
- return OK;
-
- case VAR_NUMBER:
- case VAR_STRING:
- if (tv2->v_type == VAR_LIST)
- break;
- if (*op == '+' || *op == '-') {
- /* nr += nr or nr -= nr*/
- n = get_tv_number(tv1);
- if (tv2->v_type == VAR_FLOAT) {
- float_T f = n;
-
- if (*op == '+')
- f += tv2->vval.v_float;
- else
- f -= tv2->vval.v_float;
- clear_tv(tv1);
- tv1->v_type = VAR_FLOAT;
- tv1->vval.v_float = f;
- } else {
- if (*op == '+')
- n += get_tv_number(tv2);
- else
- n -= get_tv_number(tv2);
- clear_tv(tv1);
- tv1->v_type = VAR_NUMBER;
- tv1->vval.v_number = n;
- }
- } else {
- if (tv2->v_type == VAR_FLOAT)
- break;
-
- /* str .= str */
- s = get_tv_string(tv1);
- s = concat_str(s, get_tv_string_buf(tv2, numbuf));
- clear_tv(tv1);
- tv1->v_type = VAR_STRING;
- tv1->vval.v_string = s;
- }
- return OK;
-
- case VAR_FLOAT:
- {
- float_T f;
-
- if (*op == '.' || (tv2->v_type != VAR_FLOAT
- && tv2->v_type != VAR_NUMBER
- && tv2->v_type != VAR_STRING))
- break;
- if (tv2->v_type == VAR_FLOAT)
- f = tv2->vval.v_float;
- else
- f = get_tv_number(tv2);
- if (*op == '+')
- tv1->vval.v_float += f;
- else
- tv1->vval.v_float -= f;
- }
- return OK;
-
- case VAR_UNKNOWN:
- assert(false);
- }
- }
-
- EMSG2(_(e_letwrong), op);
- return FAIL;
-}
-
-/*
- * Add a watcher to a list.
- */
-void list_add_watch(list_T *l, listwatch_T *lw)
-{
- lw->lw_next = l->lv_watch;
- l->lv_watch = lw;
-}
-
-/*
- * Remove a watcher from a list.
- * No warning when it isn't found...
- */
-void list_rem_watch(list_T *l, listwatch_T *lwrem)
-{
- listwatch_T *lw, **lwp;
-
- lwp = &l->lv_watch;
- for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) {
- if (lw == lwrem) {
- *lwp = lw->lw_next;
- break;
- }
- lwp = &lw->lw_next;
- }
-}
-
-/*
- * Just before removing an item from a list: advance watchers to the next
- * item.
- */
-static void list_fix_watch(list_T *l, listitem_T *item)
-{
- listwatch_T *lw;
-
- for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
- if (lw->lw_item == item)
- lw->lw_item = item->li_next;
-}
+// TODO(ZyX-I): move to eval/ex_cmds
/*
* Evaluate the expression used in a ":for var in expr" command.
@@ -2542,14 +2493,14 @@ static void list_fix_watch(list_T *l, listitem_T *item)
* Set "*errp" to TRUE for an error, FALSE otherwise;
* Return a pointer that holds the info. Null when there is an error.
*/
-void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip)
+void *eval_for_line(const char_u *arg, bool *errp, char_u **nextcmdp, int skip)
{
forinfo_T *fi = xcalloc(1, sizeof(forinfo_T));
- char_u *expr;
+ const char_u *expr;
typval_T tv;
list_T *l;
- *errp = TRUE; /* default: there is an error */
+ *errp = true; // Default: there is an error.
expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon);
if (expr == NULL)
@@ -2564,18 +2515,21 @@ void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip)
if (skip)
++emsg_skip;
if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) {
- *errp = FALSE;
+ *errp = false;
if (!skip) {
l = tv.vval.v_list;
- if (tv.v_type != VAR_LIST || l == NULL) {
+ if (tv.v_type != VAR_LIST) {
EMSG(_(e_listreq));
- clear_tv(&tv);
+ tv_clear(&tv);
+ } else if (l == NULL) {
+ // a null list is like an empty list: do nothing
+ tv_clear(&tv);
} else {
/* No need to increment the refcount, it's already set for the
* list being used in "tv". */
fi->fi_list = l;
- list_add_watch(l, &fi->fi_lw);
- fi->fi_lw.lw_item = l->lv_first;
+ tv_list_watch_add(l, &fi->fi_lw);
+ fi->fi_lw.lw_item = tv_list_first(l);
}
}
}
@@ -2585,29 +2539,30 @@ void *eval_for_line(char_u *arg, int *errp, char_u **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.
* Return TRUE when a valid item was found, FALSE when at end of list or
* something wrong.
*/
-int next_for_item(void *fi_void, char_u *arg)
+bool next_for_item(void *fi_void, char_u *arg)
{
- forinfo_T *fi = (forinfo_T *)fi_void;
- int result;
- listitem_T *item;
+ forinfo_T *fi = (forinfo_T *)fi_void;
- item = fi->fi_lw.lw_item;
- if (item == NULL)
- result = FALSE;
- else {
- fi->fi_lw.lw_item = item->li_next;
- result = (ex_let_vars(arg, &item->li_tv, TRUE,
- fi->fi_semicolon, fi->fi_varcount, NULL) == OK);
+ listitem_T *item = fi->fi_lw.lw_item;
+ if (item == NULL) {
+ return false;
+ } else {
+ fi->fi_lw.lw_item = TV_LIST_ITEM_NEXT(fi->fi_list, item);
+ return (ex_let_vars(arg, TV_LIST_ITEM_TV(item), true,
+ fi->fi_semicolon, fi->fi_varcount, NULL) == OK);
}
- return result;
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* Free the structure used to store info used by ":for".
*/
@@ -2616,8 +2571,8 @@ void free_for_info(void *fi_void)
forinfo_T *fi = (forinfo_T *)fi_void;
if (fi != NULL && fi->fi_list != NULL) {
- list_rem_watch(fi->fi_list, &fi->fi_lw);
- list_unref(fi->fi_list);
+ tv_list_watch_remove(fi->fi_list, &fi->fi_lw);
+ tv_list_unref(fi->fi_list);
}
xfree(fi);
}
@@ -2635,9 +2590,10 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
/* ":let var1 var2 ...": find last space. */
for (p = arg + STRLEN(arg); p >= arg; ) {
xp->xp_pattern = p;
- mb_ptr_back(arg, p);
- if (ascii_iswhite(*p))
+ MB_PTR_BACK(arg, p);
+ if (ascii_iswhite(*p)) {
break;
+ }
}
return;
}
@@ -2665,6 +2621,10 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
} else if (c == '=') {
got_eq = TRUE;
xp->xp_context = EXPAND_EXPRESSION;
+ } else if (c == '#'
+ && xp->xp_context == EXPAND_EXPRESSION) {
+ // Autoload function/variable contains '#'
+ break;
} else if ((c == '<' || c == '#')
&& xp->xp_context == EXPAND_FUNCTIONS
&& vim_strchr(xp->xp_pattern, '(') == NULL) {
@@ -2701,6 +2661,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
xp->xp_pattern = arg;
}
+// TODO(ZyX-I): move to eval/ex_cmds
/*
* ":1,25call func(arg1, arg2)" function call.
@@ -2715,107 +2676,114 @@ void ex_call(exarg_T *eap)
typval_T rettv;
linenr_T lnum;
int doesrange;
- int failed = FALSE;
+ bool failed = false;
funcdict_T fudi;
+ partial_T *partial = NULL;
if (eap->skip) {
- /* trans_function_name() doesn't work well when skipping, use eval0()
- * instead to skip to any following command, e.g. for:
- * :if 0 | call dict.foo().bar() | endif */
- ++emsg_skip;
- if (eval0(eap->arg, &rettv, &eap->nextcmd, FALSE) != FAIL)
- clear_tv(&rettv);
- --emsg_skip;
+ // trans_function_name() doesn't work well when skipping, use eval0()
+ // instead to skip to any following command, e.g. for:
+ // :if 0 | call dict.foo().bar() | endif.
+ emsg_skip++;
+ if (eval0(eap->arg, &rettv, &eap->nextcmd, false) != FAIL) {
+ tv_clear(&rettv);
+ }
+ emsg_skip--;
return;
}
- tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi);
+ tofree = trans_function_name(&arg, false, TFN_INT, &fudi, &partial);
if (fudi.fd_newkey != NULL) {
- /* Still need to give an error message for missing key. */
+ // Still need to give an error message for missing key.
EMSG2(_(e_dictkey), fudi.fd_newkey);
xfree(fudi.fd_newkey);
}
- if (tofree == NULL)
+ if (tofree == NULL) {
return;
+ }
- /* Increase refcount on dictionary, it could get deleted when evaluating
- * the arguments. */
- if (fudi.fd_dict != NULL)
- ++fudi.fd_dict->dv_refcount;
+ // Increase refcount on dictionary, it could get deleted when evaluating
+ // the arguments.
+ if (fudi.fd_dict != NULL) {
+ fudi.fd_dict->dv_refcount++;
+ }
- /* If it is the name of a variable of type VAR_FUNC use its contents. */
+ // If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its
+ // contents. For VAR_PARTIAL get its partial, unless we already have one
+ // from trans_function_name().
len = (int)STRLEN(tofree);
- name = deref_func_name(tofree, &len, FALSE);
+ name = deref_func_name((const char *)tofree, &len,
+ partial != NULL ? NULL : &partial, false);
- /* Skip white space to allow ":call func ()". Not good, but required for
- * backward compatibility. */
+ // Skip white space to allow ":call func ()". Not good, but required for
+ // backward compatibility.
startarg = skipwhite(arg);
- rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */
+ rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this.
if (*startarg != '(') {
EMSG2(_("E107: Missing parentheses: %s"), eap->arg);
goto end;
}
- /*
- * When skipping, evaluate the function once, to find the end of the
- * arguments.
- * When the function takes a range, this is discovered after the first
- * call, and the loop is broken.
- */
- if (eap->skip) {
- ++emsg_skip;
- lnum = eap->line2; /* do it once, also with an invalid range */
- } else
- lnum = eap->line1;
- for (; lnum <= eap->line2; ++lnum) {
- if (!eap->skip && eap->addr_count > 0) {
+ lnum = eap->line1;
+ for (; lnum <= eap->line2; lnum++) {
+ if (eap->addr_count > 0) { // -V560
+ if (lnum > curbuf->b_ml.ml_line_count) {
+ // If the function deleted lines or switched to another buffer
+ // the line number may become invalid.
+ EMSG(_(e_invrange));
+ break;
+ }
curwin->w_cursor.lnum = lnum;
curwin->w_cursor.col = 0;
curwin->w_cursor.coladd = 0;
}
arg = startarg;
if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg,
- eap->line1, eap->line2, &doesrange,
- !eap->skip, fudi.fd_dict) == FAIL) {
- failed = TRUE;
+ eap->line1, eap->line2, &doesrange,
+ true, partial, fudi.fd_dict) == FAIL) {
+ failed = true;
break;
}
- /* Handle a function returning a Funcref, Dictionary or List. */
- if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) {
- failed = TRUE;
+ // Handle a function returning a Funcref, Dictionary or List.
+ if (handle_subscript((const char **)&arg, &rettv, true, true)
+ == FAIL) {
+ failed = true;
break;
}
- clear_tv(&rettv);
- if (doesrange || eap->skip)
+ tv_clear(&rettv);
+ if (doesrange) {
break;
+ }
- /* Stop when immediately aborting on error, or when an interrupt
- * occurred or an exception was thrown but not caught.
- * get_func_tv() returned OK, so that the check for trailing
- * characters below is executed. */
- if (aborting())
+ // Stop when immediately aborting on error, or when an interrupt
+ // occurred or an exception was thrown but not caught.
+ // get_func_tv() returned OK, so that the check for trailing
+ // characters below is executed.
+ if (aborting()) {
break;
+ }
}
- if (eap->skip)
- --emsg_skip;
if (!failed) {
- /* Check for trailing illegal characters and a following command. */
+ // Check for trailing illegal characters and a following command.
if (!ends_excmd(*arg)) {
emsg_severe = TRUE;
EMSG(_(e_trailing));
- } else
+ } else {
eap->nextcmd = check_nextcmd(arg);
+ }
}
end:
- dict_unref(fudi.fd_dict);
+ tv_dict_unref(fudi.fd_dict);
xfree(tofree);
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* ":unlet[!] var1 ... " command.
*/
@@ -2824,6 +2792,8 @@ void ex_unlet(exarg_T *eap)
ex_unletlock(eap, eap->arg, 0);
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* ":lockvar" and ":unlockvar" commands
*/
@@ -2842,22 +2812,37 @@ void ex_lockvar(exarg_T *eap)
ex_unletlock(eap, arg, deep);
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* ":unlet", ":lockvar" and ":unlockvar" are quite similar.
*/
static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
{
char_u *arg = argstart;
- char_u *name_end;
- int error = FALSE;
+ bool error = false;
lval_T lv;
do {
- /* Parse the name and find the end. */
- name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, 0,
- FNE_CHECK_START);
- if (lv.ll_name == NULL)
- error = TRUE; /* error but continue parsing */
+ if (*arg == '$') {
+ const char *name = (char *)++arg;
+
+ if (get_env_len((const char_u **)&arg) == 0) {
+ EMSG2(_(e_invarg2), name - 1);
+ return;
+ }
+ os_unsetenv(name);
+ arg = skipwhite(arg);
+ continue;
+ }
+
+ // Parse the name and find the end.
+ char_u *const name_end = (char_u *)get_lval(arg, NULL, &lv, true,
+ eap->skip || error,
+ 0, FNE_CHECK_START);
+ if (lv.ll_name == NULL) {
+ error = true; // error, but continue parsing.
+ }
if (name_end == NULL || (!ascii_iswhite(*name_end)
&& !ends_excmd(*name_end))) {
if (name_end != NULL) {
@@ -2875,8 +2860,9 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
error = TRUE;
} else {
if (do_lock_var(&lv, name_end, deep,
- eap->cmdidx == CMD_lockvar) == FAIL)
- error = TRUE;
+ eap->cmdidx == CMD_lockvar) == FAIL) {
+ error = true;
+ }
}
}
@@ -2889,7 +2875,9 @@ static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep)
eap->nextcmd = check_nextcmd(arg);
}
-static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
+// TODO(ZyX-I): move to eval/ex_cmds
+
+static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit)
{
int ret = OK;
int cc;
@@ -2898,61 +2886,67 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
cc = *name_end;
*name_end = NUL;
- /* Normal name or expanded name. */
- if (check_changedtick(lp->ll_name))
- ret = FAIL;
- else if (do_unlet(lp->ll_name, forceit) == FAIL)
+ // Normal name or expanded name.
+ if (do_unlet(lp->ll_name, lp->ll_name_len, forceit) == FAIL) {
ret = FAIL;
+ }
*name_end = cc;
} else if ((lp->ll_list != NULL
- && tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, false))
+ // ll_list is not NULL when lvalue is not in a list, NULL lists
+ // yield E689.
+ && tv_check_lock(tv_list_locked(lp->ll_list),
+ (const char *)lp->ll_name,
+ lp->ll_name_len))
|| (lp->ll_dict != NULL
- && tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, false))) {
+ && tv_check_lock(lp->ll_dict->dv_lock,
+ (const char *)lp->ll_name,
+ lp->ll_name_len))) {
return FAIL;
} else if (lp->ll_range) {
- listitem_T *li;
- listitem_T *ll_li = lp->ll_li;
- int ll_n1 = lp->ll_n1;
-
- while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) {
- li = ll_li->li_next;
- if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, false)) {
+ assert(lp->ll_list != NULL);
+ // Delete a range of List items.
+ listitem_T *const first_li = lp->ll_li;
+ listitem_T *last_li = first_li;
+ for (;;) {
+ listitem_T *const li = TV_LIST_ITEM_NEXT(lp->ll_list, lp->ll_li);
+ if (tv_check_lock(TV_LIST_ITEM_TV(lp->ll_li)->v_lock,
+ (const char *)lp->ll_name,
+ lp->ll_name_len)) {
return false;
}
- ll_li = li;
- ll_n1++;
- }
-
- /* Delete a range of List items. */
- while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) {
- li = lp->ll_li->li_next;
- listitem_remove(lp->ll_list, lp->ll_li);
lp->ll_li = li;
- ++lp->ll_n1;
+ lp->ll_n1++;
+ if (lp->ll_li == NULL || (!lp->ll_empty2 && lp->ll_n2 < lp->ll_n1)) {
+ break;
+ } else {
+ last_li = lp->ll_li;
+ }
}
+ tv_list_remove_items(lp->ll_list, first_li, last_li);
} else {
if (lp->ll_list != NULL) {
// unlet a List item.
- listitem_remove(lp->ll_list, lp->ll_li);
+ tv_list_item_remove(lp->ll_list, lp->ll_li);
} else {
// unlet a Dictionary item.
dict_T *d = lp->ll_dict;
+ assert(d != NULL);
dictitem_T *di = lp->ll_di;
- bool watched = is_watched(d);
+ bool watched = tv_dict_is_watched(d);
char *key = NULL;
typval_T oldtv;
if (watched) {
- copy_tv(&di->di_tv, &oldtv);
+ tv_copy(&di->di_tv, &oldtv);
// need to save key because dictitem_remove will free it
key = xstrdup((char *)di->di_key);
}
- dictitem_remove(d, di);
+ tv_dict_item_remove(d, di);
if (watched) {
- dictwatcher_notify(d, key, NULL, &oldtv);
- clear_tv(&oldtv);
+ tv_dict_watcher_notify(d, key, NULL, &oldtv);
+ tv_clear(&oldtv);
xfree(key);
}
}
@@ -2961,21 +2955,24 @@ static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit)
return ret;
}
-/*
- * "unlet" a variable. Return OK if it existed, FAIL if not.
- * When "forceit" is TRUE don't complain if the variable doesn't exist.
- */
-int do_unlet(char_u *name, int forceit)
+// TODO(ZyX-I): move to eval/ex_cmds
+
+/// unlet a variable
+///
+/// @param[in] name Variable name to unlet.
+/// @param[in] name_len Variable name length.
+/// @param[in] fonceit If true, do not complain if variable doesn’t exist.
+///
+/// @return OK if it existed, FAIL otherwise.
+int do_unlet(const char *const name, const size_t name_len, const int forceit)
+ FUNC_ATTR_NONNULL_ALL
{
- hashtab_T *ht;
- hashitem_T *hi;
- char_u *varname;
- dict_T *d;
- dictitem_T *di;
+ const char *varname;
dict_T *dict;
- ht = find_var_ht_dict(name, &varname, &dict);
+ hashtab_T *ht = find_var_ht_dict(name, name_len, &varname, &dict);
if (ht != NULL && *varname != NUL) {
+ dict_T *d;
if (ht == &globvarht) {
d = &globvardict;
} else if (current_funccal != NULL
@@ -2984,38 +2981,41 @@ int do_unlet(char_u *name, int forceit)
} else if (ht == &compat_hashtab) {
d = &vimvardict;
} else {
- di = find_var_in_ht(ht, *name, (char_u *)"", false);
+ dictitem_T *const di = find_var_in_ht(ht, *name, "", 0, false);
d = di->di_tv.vval.v_dict;
}
if (d == NULL) {
- EMSG2(_(e_intern2), "do_unlet()");
+ internal_error("do_unlet()");
return FAIL;
}
- hi = hash_find(ht, varname);
- if (!HASHITEM_EMPTY(hi)) {
- di = HI2DI(hi);
- if (var_check_fixed(di->di_flags, name, false)
- || var_check_ro(di->di_flags, name, false)
- || tv_check_lock(d->dv_lock, name, false)) {
+ hashitem_T *hi = hash_find(ht, (const char_u *)varname);
+ if (HASHITEM_EMPTY(hi)) {
+ hi = find_hi_in_scoped_ht((const char *)name, &ht);
+ }
+ if (hi != NULL && !HASHITEM_EMPTY(hi)) {
+ dictitem_T *const di = TV_DICT_HI2DI(hi);
+ if (var_check_fixed(di->di_flags, (const char *)name, TV_CSTRING)
+ || var_check_ro(di->di_flags, (const char *)name, TV_CSTRING)
+ || tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) {
return FAIL;
}
- if (d == NULL || tv_check_lock(d->dv_lock, name, false)) {
+ if (tv_check_lock(d->dv_lock, (const char *)name, TV_CSTRING)) {
return FAIL;
}
typval_T oldtv;
- bool watched = is_watched(dict);
+ bool watched = tv_dict_is_watched(dict);
if (watched) {
- copy_tv(&di->di_tv, &oldtv);
+ tv_copy(&di->di_tv, &oldtv);
}
delete_var(ht, hi);
if (watched) {
- dictwatcher_notify(dict, (char *)varname, NULL, &oldtv);
- clear_tv(&oldtv);
+ tv_dict_watcher_notify(dict, varname, NULL, &oldtv);
+ tv_clear(&oldtv);
}
return OK;
}
@@ -3026,161 +3026,74 @@ int do_unlet(char_u *name, int forceit)
return FAIL;
}
+// TODO(ZyX-I): move to eval/ex_cmds
+
/*
* Lock or unlock variable indicated by "lp".
* "deep" is the levels to go (-1 for unlimited);
* "lock" is TRUE for ":lockvar", FALSE for ":unlockvar".
*/
-static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock)
+static int do_lock_var(lval_T *lp, char_u *const name_end, const int deep,
+ const bool lock)
{
int ret = OK;
- int cc;
- dictitem_T *di;
- if (deep == 0) /* nothing to do */
+ if (deep == 0) { // Nothing to do.
return OK;
+ }
if (lp->ll_tv == NULL) {
- cc = *name_end;
- *name_end = NUL;
-
- /* Normal name or expanded name. */
- if (check_changedtick(lp->ll_name))
+ // Normal name or expanded name.
+ dictitem_T *const di = find_var(
+ (const char *)lp->ll_name, lp->ll_name_len, NULL,
+ true);
+ if (di == NULL) {
ret = FAIL;
- else {
- di = find_var(lp->ll_name, NULL, TRUE);
- if (di == NULL)
- ret = FAIL;
- else {
- if (lock)
- di->di_flags |= DI_FLAGS_LOCK;
- else
- di->di_flags &= ~DI_FLAGS_LOCK;
- item_lock(&di->di_tv, deep, lock);
+ } else if ((di->di_flags & DI_FLAGS_FIX)
+ && di->di_tv.v_type != VAR_DICT
+ && di->di_tv.v_type != VAR_LIST) {
+ // For historical reasons this error is not given for Lists and
+ // Dictionaries. E.g. b: dictionary may be locked/unlocked.
+ emsgf(_("E940: Cannot lock or unlock variable %s"), lp->ll_name);
+ } else {
+ if (lock) {
+ di->di_flags |= DI_FLAGS_LOCK;
+ } else {
+ di->di_flags &= ~DI_FLAGS_LOCK;
}
+ tv_item_lock(&di->di_tv, deep, lock);
}
- *name_end = cc;
} else if (lp->ll_range) {
listitem_T *li = lp->ll_li;
/* (un)lock a range of List items. */
while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) {
- item_lock(&li->li_tv, deep, lock);
- li = li->li_next;
- ++lp->ll_n1;
+ tv_item_lock(TV_LIST_ITEM_TV(li), deep, lock);
+ li = TV_LIST_ITEM_NEXT(lp->ll_list, li);
+ lp->ll_n1++;
}
} else if (lp->ll_list != NULL) {
// (un)lock a List item.
- item_lock(&lp->ll_li->li_tv, deep, lock);
+ tv_item_lock(TV_LIST_ITEM_TV(lp->ll_li), deep, lock);
} else {
// (un)lock a Dictionary item.
- item_lock(&lp->ll_di->di_tv, deep, lock);
+ tv_item_lock(&lp->ll_di->di_tv, deep, lock);
}
return ret;
}
/*
- * Lock or unlock an item. "deep" is nr of levels to go.
- */
-static void item_lock(typval_T *tv, int deep, int lock)
-{
- static int recurse = 0;
- list_T *l;
- listitem_T *li;
- dict_T *d;
- hashitem_T *hi;
- int todo;
-
- if (recurse >= DICT_MAXNEST) {
- EMSG(_("E743: variable nested too deep for (un)lock"));
- return;
- }
- if (deep == 0)
- return;
- ++recurse;
-
- /* lock/unlock the item itself */
- if (lock)
- tv->v_lock |= VAR_LOCKED;
- else
- tv->v_lock &= ~VAR_LOCKED;
-
- switch (tv->v_type) {
- case VAR_LIST:
- if ((l = tv->vval.v_list) != NULL) {
- if (lock)
- l->lv_lock |= VAR_LOCKED;
- else
- l->lv_lock &= ~VAR_LOCKED;
- if (deep < 0 || deep > 1)
- /* recursive: lock/unlock the items the List contains */
- for (li = l->lv_first; li != NULL; li = li->li_next)
- item_lock(&li->li_tv, deep - 1, lock);
- }
- break;
- case VAR_DICT:
- if ((d = tv->vval.v_dict) != NULL) {
- if (lock)
- d->dv_lock |= VAR_LOCKED;
- else
- d->dv_lock &= ~VAR_LOCKED;
- if (deep < 0 || deep > 1) {
- /* recursive: lock/unlock the items the List contains */
- todo = (int)d->dv_hashtab.ht_used;
- for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- item_lock(&HI2DI(hi)->di_tv, deep - 1, lock);
- }
- }
- }
- }
- break;
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_STRING:
- case VAR_FUNC:
- case VAR_SPECIAL:
- break;
- case VAR_UNKNOWN:
- assert(false);
- }
- --recurse;
-}
-
-/*
- * Return TRUE if typeval "tv" is locked: Either that value is locked itself
- * or it refers to a List or Dictionary that is locked.
- */
-static int tv_islocked(typval_T *tv)
-{
- return (tv->v_lock & VAR_LOCKED)
- || (tv->v_type == VAR_LIST
- && tv->vval.v_list != NULL
- && (tv->vval.v_list->lv_lock & VAR_LOCKED))
- || (tv->v_type == VAR_DICT
- && tv->vval.v_dict != NULL
- && (tv->vval.v_dict->dv_lock & VAR_LOCKED));
-}
-
-/*
* Delete all "menutrans_" variables.
*/
void del_menutrans_vars(void)
{
- hashitem_T *hi;
- int todo;
-
hash_lock(&globvarht);
- todo = (int)globvarht.ht_used;
- for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0)
- delete_var(&globvarht, hi);
+ HASHTAB_ITER(&globvarht, hi, {
+ if (STRNCMP(hi->hi_key, "menutrans_", 10) == 0) {
+ delete_var(&globvarht, hi);
}
- }
+ });
hash_unlock(&globvarht);
}
@@ -3256,10 +3169,6 @@ char_u *get_user_var_name(expand_T *xp, int idx)
++hi;
return cat_prefix_varname('b', hi->hi_key);
}
- if (bdone == ht->ht_used) {
- ++bdone;
- return (char_u *)"b:changedtick";
- }
/* w: variables */
ht = &curwin->w_vars->dv_hashtab;
@@ -3296,6 +3205,27 @@ char_u *get_user_var_name(expand_T *xp, int idx)
return NULL;
}
+// TODO(ZyX-I): move to eval/expressions
+
+/// Return TRUE if "pat" matches "text".
+/// Does not use 'cpo' and always uses 'magic'.
+static int pattern_match(char_u *pat, char_u *text, int ic)
+{
+ int matches = 0;
+ regmatch_T regmatch;
+
+ // avoid 'l' flag in 'cpoptions'
+ char_u *save_cpo = p_cpo;
+ p_cpo = (char_u *)"";
+ regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ if (regmatch.regprog != NULL) {
+ regmatch.rm_ic = ic;
+ matches = vim_regexec_nl(&regmatch, text, (colnr_T)0);
+ vim_regfree(regmatch.regprog);
+ }
+ p_cpo = save_cpo;
+ return matches;
+}
/*
* types for expressions.
@@ -3312,6 +3242,8 @@ typedef enum {
, TYPE_NOMATCH /* !~ */
} exptype_T;
+// 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
@@ -3325,7 +3257,7 @@ typedef enum {
* Note: "rettv.v_lock" is not set.
* Return OK or FAIL.
*/
-static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
+int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
{
int ret;
char_u *p;
@@ -3333,15 +3265,15 @@ static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
p = skipwhite(arg);
ret = eval1(&p, rettv, evaluate);
if (ret == FAIL || !ends_excmd(*p)) {
- if (ret != FAIL)
- clear_tv(rettv);
- /*
- * Report the invalid expression unless the expression evaluation has
- * been cancelled due to an aborting error, an interrupt, or an
- * exception.
- */
- if (!aborting())
- EMSG2(_(e_invexpr2), arg);
+ if (ret != FAIL) {
+ tv_clear(rettv);
+ }
+ // Report the invalid expression unless the expression evaluation has
+ // been cancelled due to an aborting error, an interrupt, or an
+ // exception.
+ if (!aborting()) {
+ emsgf(_(e_invexpr2), arg);
+ }
ret = FAIL;
}
if (nextcmd != NULL)
@@ -3350,6 +3282,8 @@ static int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)
return ret;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle top level expression:
* expr2 ? expr1 : expr1
@@ -3375,13 +3309,15 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate)
if ((*arg)[0] == '?') {
result = FALSE;
if (evaluate) {
- int error = FALSE;
+ bool error = false;
- if (get_tv_number_chk(rettv, &error) != 0)
- result = TRUE;
- clear_tv(rettv);
- if (error)
+ if (tv_get_number_chk(rettv, &error) != 0) {
+ result = true;
+ }
+ tv_clear(rettv);
+ if (error) {
return FAIL;
+ }
}
/*
@@ -3396,8 +3332,9 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate)
*/
if ((*arg)[0] != ':') {
EMSG(_("E109: Missing ':' after '?'"));
- if (evaluate && result)
- clear_tv(rettv);
+ if (evaluate && result) {
+ tv_clear(rettv);
+ }
return FAIL;
}
@@ -3405,9 +3342,10 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate)
* Get the third variable.
*/
*arg = skipwhite(*arg + 1);
- if (eval1(arg, &var2, evaluate && !result) == FAIL) { /* recursive! */
- if (evaluate && result)
- clear_tv(rettv);
+ if (eval1(arg, &var2, evaluate && !result) == FAIL) { // Recursive!
+ if (evaluate && result) {
+ tv_clear(rettv);
+ }
return FAIL;
}
if (evaluate && !result)
@@ -3417,6 +3355,8 @@ static int eval1(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle first level expression:
* expr2 || expr2 || expr2 logical OR
@@ -3431,7 +3371,7 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
typval_T var2;
long result;
int first;
- int error = FALSE;
+ bool error = false;
/*
* Get the first variable.
@@ -3446,12 +3386,14 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
result = FALSE;
while ((*arg)[0] == '|' && (*arg)[1] == '|') {
if (evaluate && first) {
- if (get_tv_number_chk(rettv, &error) != 0)
- result = TRUE;
- clear_tv(rettv);
- if (error)
+ if (tv_get_number_chk(rettv, &error) != 0) {
+ result = true;
+ }
+ tv_clear(rettv);
+ if (error) {
return FAIL;
- first = FALSE;
+ }
+ first = false;
}
/*
@@ -3465,11 +3407,13 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
* Compute the result.
*/
if (evaluate && !result) {
- if (get_tv_number_chk(&var2, &error) != 0)
- result = TRUE;
- clear_tv(&var2);
- if (error)
+ if (tv_get_number_chk(&var2, &error) != 0) {
+ result = true;
+ }
+ tv_clear(&var2);
+ if (error) {
return FAIL;
+ }
}
if (evaluate) {
rettv->v_type = VAR_NUMBER;
@@ -3480,6 +3424,8 @@ static int eval2(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle second level expression:
* expr3 && expr3 && expr3 logical AND
@@ -3494,7 +3440,7 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
typval_T var2;
long result;
int first;
- int error = FALSE;
+ bool error = false;
/*
* Get the first variable.
@@ -3509,12 +3455,14 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
result = TRUE;
while ((*arg)[0] == '&' && (*arg)[1] == '&') {
if (evaluate && first) {
- if (get_tv_number_chk(rettv, &error) == 0)
- result = FALSE;
- clear_tv(rettv);
- if (error)
+ if (tv_get_number_chk(rettv, &error) == 0) {
+ result = false;
+ }
+ tv_clear(rettv);
+ if (error) {
return FAIL;
- first = FALSE;
+ }
+ first = false;
}
/*
@@ -3528,11 +3476,13 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
* Compute the result.
*/
if (evaluate && result) {
- if (get_tv_number_chk(&var2, &error) == 0)
- result = FALSE;
- clear_tv(&var2);
- if (error)
+ if (tv_get_number_chk(&var2, &error) == 0) {
+ result = false;
+ }
+ tv_clear(&var2);
+ if (error) {
return FAIL;
+ }
}
if (evaluate) {
rettv->v_type = VAR_NUMBER;
@@ -3543,6 +3493,8 @@ static int eval3(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle third level expression:
* var1 == var2
@@ -3569,12 +3521,8 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
exptype_T type = TYPE_UNKNOWN;
int type_is = FALSE; /* TRUE for "is" and "isnot" */
int len = 2;
- long n1, n2;
- char_u *s1, *s2;
- char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
- regmatch_T regmatch;
+ varnumber_T n1, n2;
int ic;
- char_u *save_cpo;
/*
* Get the first variable.
@@ -3641,7 +3589,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
*/
*arg = skipwhite(p + len);
if (eval5(arg, &var2, evaluate) == FAIL) {
- clear_tv(rettv);
+ tv_clear(rettv);
return FAIL;
}
@@ -3663,15 +3611,15 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
} else {
EMSG(_("E692: Invalid operation for List"));
}
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
} else {
- /* Compare two Lists for being equal or unequal. */
- n1 = list_equal(rettv->vval.v_list, var2.vval.v_list,
- ic, FALSE);
- if (type == TYPE_NEQUAL)
+ // Compare two Lists for being equal or unequal.
+ n1 = tv_list_equal(rettv->vval.v_list, var2.vval.v_list, ic, false);
+ if (type == TYPE_NEQUAL) {
n1 = !n1;
+ }
}
} else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) {
if (type_is) {
@@ -3685,36 +3633,46 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
EMSG(_("E735: Can only compare Dictionary with Dictionary"));
else
EMSG(_("E736: Invalid operation for Dictionary"));
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
} else {
- /* Compare two Dictionaries for being equal or unequal. */
- n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict,
- ic, FALSE);
- if (type == TYPE_NEQUAL)
+ // Compare two Dictionaries for being equal or unequal.
+ n1 = tv_dict_equal(rettv->vval.v_dict, var2.vval.v_dict,
+ ic, false);
+ if (type == TYPE_NEQUAL) {
n1 = !n1;
+ }
}
- } else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) {
- if (rettv->v_type != var2.v_type
- || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) {
- if (rettv->v_type != var2.v_type)
- EMSG(_("E693: Can only compare Funcref with Funcref"));
- else
- EMSG(_("E694: Invalid operation for Funcrefs"));
- clear_tv(rettv);
- clear_tv(&var2);
+ } else if (tv_is_func(*rettv) || tv_is_func(var2)) {
+ if (type != TYPE_EQUAL && type != TYPE_NEQUAL) {
+ EMSG(_("E694: Invalid operation for Funcrefs"));
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
+ }
+ if ((rettv->v_type == VAR_PARTIAL
+ && rettv->vval.v_partial == NULL)
+ || (var2.v_type == VAR_PARTIAL
+ && var2.vval.v_partial == NULL)) {
+ // when a partial is NULL assume not equal
+ n1 = false;
+ } else if (type_is) {
+ if (rettv->v_type == VAR_FUNC && var2.v_type == VAR_FUNC) {
+ // strings are considered the same if their value is
+ // the same
+ n1 = tv_equal(rettv, &var2, ic, false);
+ } else if (rettv->v_type == VAR_PARTIAL
+ && var2.v_type == VAR_PARTIAL) {
+ n1 = (rettv->vval.v_partial == var2.vval.v_partial);
+ } else {
+ n1 = false;
+ }
} else {
- /* Compare two Funcrefs for being equal or unequal. */
- if (rettv->vval.v_string == NULL
- || var2.vval.v_string == NULL)
- n1 = FALSE;
- else
- n1 = STRCMP(rettv->vval.v_string,
- var2.vval.v_string) == 0;
- if (type == TYPE_NEQUAL)
- n1 = !n1;
+ n1 = tv_equal(rettv, &var2, ic, false);
+ }
+ if (type == TYPE_NEQUAL) {
+ n1 = !n1;
}
}
/*
@@ -3725,25 +3683,27 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
&& type != TYPE_MATCH && type != TYPE_NOMATCH) {
float_T f1, f2;
- if (rettv->v_type == VAR_FLOAT)
+ if (rettv->v_type == VAR_FLOAT) {
f1 = rettv->vval.v_float;
- else
- f1 = get_tv_number(rettv);
- if (var2.v_type == VAR_FLOAT)
+ } else {
+ f1 = tv_get_number(rettv);
+ }
+ if (var2.v_type == VAR_FLOAT) {
f2 = var2.vval.v_float;
- else
- f2 = get_tv_number(&var2);
- n1 = FALSE;
+ } else {
+ f2 = tv_get_number(&var2);
+ }
+ n1 = false;
switch (type) {
- case TYPE_EQUAL: n1 = (f1 == f2); break;
- case TYPE_NEQUAL: n1 = (f1 != f2); break;
- case TYPE_GREATER: n1 = (f1 > f2); break;
- case TYPE_GEQUAL: n1 = (f1 >= f2); break;
- case TYPE_SMALLER: n1 = (f1 < f2); break;
- case TYPE_SEQUAL: n1 = (f1 <= f2); break;
- case TYPE_UNKNOWN:
- case TYPE_MATCH:
- case TYPE_NOMATCH: break; /* avoid gcc warning */
+ case TYPE_EQUAL: n1 = (f1 == f2); break;
+ case TYPE_NEQUAL: n1 = (f1 != f2); break;
+ case TYPE_GREATER: n1 = (f1 > f2); break;
+ case TYPE_GEQUAL: n1 = (f1 >= f2); break;
+ case TYPE_SMALLER: n1 = (f1 < f2); break;
+ case TYPE_SEQUAL: n1 = (f1 <= f2); break;
+ case TYPE_UNKNOWN:
+ case TYPE_MATCH:
+ case TYPE_NOMATCH: break;
}
}
/*
@@ -3752,57 +3712,51 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
*/
else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER)
&& type != TYPE_MATCH && type != TYPE_NOMATCH) {
- n1 = get_tv_number(rettv);
- n2 = get_tv_number(&var2);
+ n1 = tv_get_number(rettv);
+ n2 = tv_get_number(&var2);
switch (type) {
- case TYPE_EQUAL: n1 = (n1 == n2); break;
- case TYPE_NEQUAL: n1 = (n1 != n2); break;
- case TYPE_GREATER: n1 = (n1 > n2); break;
- case TYPE_GEQUAL: n1 = (n1 >= n2); break;
- case TYPE_SMALLER: n1 = (n1 < n2); break;
- case TYPE_SEQUAL: n1 = (n1 <= n2); break;
- case TYPE_UNKNOWN:
- case TYPE_MATCH:
- case TYPE_NOMATCH: break; /* avoid gcc warning */
+ case TYPE_EQUAL: n1 = (n1 == n2); break;
+ case TYPE_NEQUAL: n1 = (n1 != n2); break;
+ case TYPE_GREATER: n1 = (n1 > n2); break;
+ case TYPE_GEQUAL: n1 = (n1 >= n2); break;
+ case TYPE_SMALLER: n1 = (n1 < n2); break;
+ case TYPE_SEQUAL: n1 = (n1 <= n2); break;
+ case TYPE_UNKNOWN:
+ case TYPE_MATCH:
+ case TYPE_NOMATCH: break;
}
} else {
- s1 = get_tv_string_buf(rettv, buf1);
- s2 = get_tv_string_buf(&var2, buf2);
- if (type != TYPE_MATCH && type != TYPE_NOMATCH)
- i = ic ? mb_stricmp(s1, s2) : STRCMP(s1, s2);
- else
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *const s1 = tv_get_string_buf(rettv, buf1);
+ const char *const s2 = tv_get_string_buf(&var2, buf2);
+ if (type != TYPE_MATCH && type != TYPE_NOMATCH) {
+ i = mb_strcmp_ic((bool)ic, s1, s2);
+ } else {
i = 0;
- n1 = FALSE;
+ }
+ n1 = false;
switch (type) {
- case TYPE_EQUAL: n1 = (i == 0); break;
- case TYPE_NEQUAL: n1 = (i != 0); break;
- case TYPE_GREATER: n1 = (i > 0); break;
- case TYPE_GEQUAL: n1 = (i >= 0); break;
- case TYPE_SMALLER: n1 = (i < 0); break;
- case TYPE_SEQUAL: n1 = (i <= 0); break;
-
- case TYPE_MATCH:
- case TYPE_NOMATCH:
- /* avoid 'l' flag in 'cpoptions' */
- save_cpo = p_cpo;
- p_cpo = (char_u *)"";
- regmatch.regprog = vim_regcomp(s2,
- RE_MAGIC + RE_STRING);
- regmatch.rm_ic = ic;
- if (regmatch.regprog != NULL) {
- n1 = vim_regexec_nl(&regmatch, s1, (colnr_T)0);
- vim_regfree(regmatch.regprog);
- if (type == TYPE_NOMATCH)
+ case TYPE_EQUAL: n1 = (i == 0); break;
+ case TYPE_NEQUAL: n1 = (i != 0); break;
+ case TYPE_GREATER: n1 = (i > 0); break;
+ case TYPE_GEQUAL: n1 = (i >= 0); break;
+ case TYPE_SMALLER: n1 = (i < 0); break;
+ case TYPE_SEQUAL: n1 = (i <= 0); break;
+
+ case TYPE_MATCH:
+ case TYPE_NOMATCH: {
+ n1 = pattern_match((char_u *)s2, (char_u *)s1, ic);
+ if (type == TYPE_NOMATCH) {
n1 = !n1;
+ }
+ break;
}
- p_cpo = save_cpo;
- break;
-
- case TYPE_UNKNOWN: break; /* avoid gcc warning */
+ case TYPE_UNKNOWN: break; // Avoid gcc warning.
}
}
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = n1;
}
@@ -3811,6 +3765,8 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Handle fourth level expression:
* + number addition
@@ -3827,10 +3783,8 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
typval_T var2;
typval_T var3;
int op;
- long n1, n2;
+ varnumber_T n1, n2;
float_T f1 = 0, f2 = 0;
- char_u *s1, *s2;
- char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
char_u *p;
/*
@@ -3848,17 +3802,16 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
break;
if ((op != '+' || rettv->v_type != VAR_LIST)
- && (op == '.' || rettv->v_type != VAR_FLOAT)
- ) {
- /* For "list + ...", an illegal use of the first operand as
- * a number cannot be determined before evaluating the 2nd
- * operand: if this is also a list, all is ok.
- * For "something . ...", "something - ..." or "non-list + ...",
- * we know that the first operand needs to be a string or number
- * without evaluating the 2nd operand. So check before to avoid
- * side effects after an error. */
- if (evaluate && get_tv_string_chk(rettv) == NULL) {
- clear_tv(rettv);
+ && (op == '.' || rettv->v_type != VAR_FLOAT)) {
+ // For "list + ...", an illegal use of the first operand as
+ // a number cannot be determined before evaluating the 2nd
+ // operand: if this is also a list, all is ok.
+ // For "something . ...", "something - ..." or "non-list + ...",
+ // we know that the first operand needs to be a string or number
+ // without evaluating the 2nd operand. So check before to avoid
+ // side effects after an error.
+ if (evaluate && !tv_check_str(rettv)) {
+ tv_clear(rettv);
return FAIL;
}
}
@@ -3868,7 +3821,7 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
*/
*arg = skipwhite(*arg + 1);
if (eval6(arg, &var2, evaluate, op == '.') == FAIL) {
- clear_tv(rettv);
+ tv_clear(rettv);
return FAIL;
}
@@ -3877,41 +3830,44 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
* Compute the result.
*/
if (op == '.') {
- s1 = get_tv_string_buf(rettv, buf1); /* already checked */
- s2 = get_tv_string_buf_chk(&var2, buf2);
- if (s2 == NULL) { /* type error ? */
- clear_tv(rettv);
- clear_tv(&var2);
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ // s1 already checked
+ const char *const s1 = tv_get_string_buf(rettv, buf1);
+ const char *const s2 = tv_get_string_buf_chk(&var2, buf2);
+ if (s2 == NULL) { // Type error?
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
}
- p = concat_str(s1, s2);
- clear_tv(rettv);
+ p = concat_str((const char_u *)s1, (const char_u *)s2);
+ tv_clear(rettv);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = p;
} else if (op == '+' && rettv->v_type == VAR_LIST
&& var2.v_type == VAR_LIST) {
- /* concatenate Lists */
- if (list_concat(rettv->vval.v_list, var2.vval.v_list,
- &var3) == FAIL) {
- clear_tv(rettv);
- clear_tv(&var2);
+ // Concatenate Lists.
+ if (tv_list_concat(rettv->vval.v_list, var2.vval.v_list, &var3)
+ == FAIL) {
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
}
- clear_tv(rettv);
+ tv_clear(rettv);
*rettv = var3;
} else {
- int error = FALSE;
+ bool error = false;
if (rettv->v_type == VAR_FLOAT) {
f1 = rettv->vval.v_float;
n1 = 0;
} else {
- n1 = get_tv_number_chk(rettv, &error);
+ n1 = tv_get_number_chk(rettv, &error);
if (error) {
/* This can only happen for "list + non-list". For
* "non-list + ..." or "something - ...", we returned
* before evaluating the 2nd operand. */
- clear_tv(rettv);
+ tv_clear(rettv);
return FAIL;
}
if (var2.v_type == VAR_FLOAT)
@@ -3921,16 +3877,16 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
f2 = var2.vval.v_float;
n2 = 0;
} else {
- n2 = get_tv_number_chk(&var2, &error);
+ n2 = tv_get_number_chk(&var2, &error);
if (error) {
- clear_tv(rettv);
- clear_tv(&var2);
+ tv_clear(rettv);
+ tv_clear(&var2);
return FAIL;
}
if (rettv->v_type == VAR_FLOAT)
f2 = n2;
}
- clear_tv(rettv);
+ tv_clear(rettv);
/* If there is a float on either side the result is a float. */
if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) {
@@ -3949,37 +3905,36 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate)
rettv->vval.v_number = n1;
}
}
- clear_tv(&var2);
+ tv_clear(&var2);
}
}
return OK;
}
-/*
- * Handle fifth level expression:
- * * number multiplication
- * / number division
- * % number modulo
- *
- * "arg" must point to the first non-white of the expression.
- * "arg" is advanced to the next non-white after the recognized expression.
- *
- * Return OK or FAIL.
- */
-static int
-eval6 (
- char_u **arg,
- typval_T *rettv,
- int evaluate,
- int want_string /* after "." operator */
-)
+// TODO(ZyX-I): move to eval/expressions
+
+/// Handle fifth level expression:
+/// - * number multiplication
+/// - / number division
+/// - % number modulo
+///
+/// @param[in,out] arg Points to the first non-whitespace character of the
+/// expression. Is advanced to the next non-whitespace
+/// character after the recognized expression.
+/// @param[out] rettv Location where result is saved.
+/// @param[in] evaluate If not true, rettv is not populated.
+/// @param[in] want_string True if "." is string_concatenation, otherwise
+/// float
+/// @return OK or FAIL.
+static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
+ FUNC_ATTR_NO_SANITIZE_UNDEFINED
{
typval_T var2;
int op;
- long n1, n2;
- int use_float = FALSE;
+ varnumber_T n1, n2;
+ bool use_float = false;
float_T f1 = 0, f2;
- int error = FALSE;
+ bool error = false;
/*
* Get the first variable.
@@ -3998,15 +3953,18 @@ eval6 (
if (evaluate) {
if (rettv->v_type == VAR_FLOAT) {
f1 = rettv->vval.v_float;
- use_float = TRUE;
+ use_float = true;
n1 = 0;
- } else
- n1 = get_tv_number_chk(rettv, &error);
- clear_tv(rettv);
- if (error)
+ } else {
+ n1 = tv_get_number_chk(rettv, &error);
+ }
+ tv_clear(rettv);
+ if (error) {
return FAIL;
- } else
+ }
+ } else {
n1 = 0;
+ }
/*
* Get the second variable.
@@ -4019,17 +3977,19 @@ eval6 (
if (var2.v_type == VAR_FLOAT) {
if (!use_float) {
f1 = n1;
- use_float = TRUE;
+ use_float = true;
}
f2 = var2.vval.v_float;
n2 = 0;
} else {
- n2 = get_tv_number_chk(&var2, &error);
- clear_tv(&var2);
- if (error)
+ n2 = tv_get_number_chk(&var2, &error);
+ tv_clear(&var2);
+ if (error) {
return FAIL;
- if (use_float)
+ }
+ if (use_float) {
f2 = n2;
+ }
}
/*
@@ -4060,18 +4020,20 @@ eval6 (
rettv->v_type = VAR_FLOAT;
rettv->vval.v_float = f1;
} else {
- if (op == '*')
+ if (op == '*') {
n1 = n1 * n2;
- else if (op == '/') {
- if (n2 == 0) { /* give an error message? */
- if (n1 == 0)
- n1 = -0x7fffffffL - 1L; /* similar to NaN */
- else if (n1 < 0)
- n1 = -0x7fffffffL;
- else
- n1 = 0x7fffffffL;
- } else
+ } else if (op == '/') {
+ if (n2 == 0) { // give an error message?
+ if (n1 == 0) {
+ n1 = VARNUMBER_MIN; // similar to NaN
+ } else if (n1 < 0) {
+ n1 = -VARNUMBER_MAX;
+ } else {
+ n1 = VARNUMBER_MAX;
+ }
+ } else {
n1 = n1 / n2;
+ }
} else {
if (n2 == 0) /* give an error message? */
n1 = 0;
@@ -4087,6 +4049,8 @@ eval6 (
return OK;
}
+// TODO(ZyX-I): move to eval/expressions
+
// Handle sixth level expression:
// number number constant
// "string" string constant
@@ -4118,18 +4082,18 @@ static int eval7(
int want_string // after "." operator
)
{
- long n;
+ varnumber_T n;
int len;
char_u *s;
char_u *start_leader, *end_leader;
int ret = OK;
char_u *alias;
- // Initialise variable so that clear_tv() can't mistake this for a
+ // Initialise variable so that tv_clear() can't mistake this for a
// string and free a string that isn't there.
rettv->v_type = VAR_UNKNOWN;
- // Skip '!' and '-' characters. They are handled later.
+ // Skip '!', '-' and '+' characters. They are handled later.
start_leader = *arg;
while (**arg == '!' || **arg == '-' || **arg == '+') {
*arg = skipwhite(*arg + 1);
@@ -4206,14 +4170,19 @@ static int eval7(
case '[': ret = get_list_tv(arg, rettv, evaluate);
break;
+ // Lambda: {arg, arg -> expr}
// Dictionary: {key: val, key: val}
- case '{': ret = get_dict_tv(arg, rettv, evaluate);
+ case '{': ret = get_lambda_tv(arg, rettv, evaluate);
+ if (ret == NOTDONE) {
+ ret = get_dict_tv(arg, rettv, evaluate);
+ }
break;
// Option value: &name
- case '&': ret = get_option_tv(arg, rettv, evaluate);
+ case '&': {
+ ret = get_option_tv((const char **)arg, rettv, evaluate);
break;
-
+ }
// Environment variable: $VAR.
case '$': ret = get_env_tv(arg, rettv, evaluate);
break;
@@ -4236,7 +4205,7 @@ static int eval7(
++*arg;
} else if (ret == OK) {
EMSG(_("E110: Missing ')'"));
- clear_tv(rettv);
+ tv_clear(rettv);
ret = FAIL;
}
break;
@@ -4249,7 +4218,7 @@ static int eval7(
// Must be a variable or function name.
// Can also be a curly-braces kind of name: {expr}.
s = *arg;
- len = get_name_len(arg, &alias, evaluate, true);
+ len = get_name_len((const char **)arg, (char **)&alias, evaluate, true);
if (alias != NULL) {
s = alias;
}
@@ -4258,20 +4227,32 @@ static int eval7(
ret = FAIL;
} else {
if (**arg == '(') { // recursive!
+ partial_T *partial;
+
+ if (!evaluate) {
+ check_vars((const char *)s, len);
+ }
+
// If "s" is the name of a variable of type VAR_FUNC
// use its contents.
- s = deref_func_name(s, &len, !evaluate);
+ s = deref_func_name((const char *)s, &len, &partial, !evaluate);
+
+ // Need to make a copy, in case evaluating the arguments makes
+ // the name invalid.
+ s = xmemdupz(s, len);
// Invoke the function.
ret = get_func_tv(s, len, rettv, arg,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &len, evaluate, NULL);
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &len, evaluate, partial, NULL);
+
+ xfree(s);
// If evaluate is false rettv->v_type was not set in
// get_func_tv, but it's needed in handle_subscript() to parse
// what follows. So set it here.
if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') {
- rettv->vval.v_string = empty_string;
+ rettv->vval.v_string = (char_u *)tv_empty_string;
rettv->v_type = VAR_FUNC;
}
@@ -4280,13 +4261,14 @@ static int eval7(
// an exception was thrown but not caught.
if (aborting()) {
if (ret == OK) {
- clear_tv(rettv);
+ tv_clear(rettv);
}
ret = FAIL;
}
} else if (evaluate) {
- ret = get_var_tv(s, len, rettv, NULL, true, false);
+ ret = get_var_tv((const char *)s, len, rettv, NULL, true, false);
} else {
+ check_vars((const char *)s, len);
ret = OK;
}
}
@@ -4298,22 +4280,22 @@ static int eval7(
// Handle following '[', '(' and '.' for expr[expr], expr.name,
// expr(expr).
if (ret == OK) {
- ret = handle_subscript(arg, rettv, evaluate, true);
+ ret = handle_subscript((const char **)arg, rettv, evaluate, true);
}
// Apply logical NOT and unary '-', from right to left, ignore '+'.
if (ret == OK && evaluate && end_leader > start_leader) {
- int error = false;
- int val = 0;
+ bool error = false;
+ varnumber_T val = 0;
float_T f = 0.0;
if (rettv->v_type == VAR_FLOAT) {
f = rettv->vval.v_float;
} else {
- val = get_tv_number_chk(rettv, &error);
+ val = tv_get_number_chk(rettv, &error);
}
if (error) {
- clear_tv(rettv);
+ tv_clear(rettv);
ret = FAIL;
} else {
while (end_leader > start_leader) {
@@ -4333,10 +4315,10 @@ static int eval7(
}
}
if (rettv->v_type == VAR_FLOAT) {
- clear_tv(rettv);
+ tv_clear(rettv);
rettv->vval.v_float = f;
} else {
- clear_tv(rettv);
+ tv_clear(rettv);
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = val;
}
@@ -4346,29 +4328,31 @@ static int eval7(
return ret;
}
+// TODO(ZyX-I): move to eval/expressions
+
/*
* Evaluate an "[expr]" or "[expr:expr]" index. Also "dict.key".
* "*arg" points to the '[' or '.'.
* Returns FAIL or OK. "*arg" is advanced to after the ']'.
*/
-static int
-eval_index (
+static int
+eval_index(
char_u **arg,
typval_T *rettv,
int evaluate,
int verbose /* give error messages */
)
{
- int empty1 = FALSE, empty2 = FALSE;
- typval_T var1, var2;
+ bool empty1 = false;
+ bool empty2 = false;
long n1, n2 = 0;
- long len = -1;
- int range = FALSE;
- char_u *s;
+ ptrdiff_t len = -1;
+ int range = false;
char_u *key = NULL;
switch (rettv->v_type) {
- case VAR_FUNC: {
+ case VAR_FUNC:
+ case VAR_PARTIAL: {
if (verbose) {
EMSG(_("E695: Cannot index a Funcref"));
}
@@ -4390,7 +4374,7 @@ eval_index (
if (evaluate) {
return FAIL;
}
- // fallthrough
+ FALLTHROUGH;
}
case VAR_STRING:
case VAR_NUMBER:
@@ -4400,8 +4384,8 @@ eval_index (
}
}
- init_tv(&var1);
- init_tv(&var2);
+ typval_T var1 = TV_INITIAL_VALUE;
+ typval_T var2 = TV_INITIAL_VALUE;
if (**arg == '.') {
/*
* dict.name
@@ -4419,13 +4403,13 @@ eval_index (
* Get the (first) variable from inside the [].
*/
*arg = skipwhite(*arg + 1);
- if (**arg == ':')
- empty1 = TRUE;
- else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */
+ if (**arg == ':') {
+ empty1 = true;
+ } else if (eval1(arg, &var1, evaluate) == FAIL) { // Recursive!
return FAIL;
- else if (evaluate && get_tv_string_chk(&var1) == NULL) {
- /* not a number or string */
- clear_tv(&var1);
+ } else if (evaluate && !tv_check_str(&var1)) {
+ // Not a number or string.
+ tv_clear(&var1);
return FAIL;
}
@@ -4435,28 +4419,32 @@ eval_index (
if (**arg == ':') {
range = TRUE;
*arg = skipwhite(*arg + 1);
- if (**arg == ']')
- empty2 = TRUE;
- else if (eval1(arg, &var2, evaluate) == FAIL) { /* recursive! */
- if (!empty1)
- clear_tv(&var1);
+ if (**arg == ']') {
+ empty2 = true;
+ } else if (eval1(arg, &var2, evaluate) == FAIL) { // Recursive!
+ if (!empty1) {
+ tv_clear(&var1);
+ }
return FAIL;
- } else if (evaluate && get_tv_string_chk(&var2) == NULL) {
- /* not a number or string */
- if (!empty1)
- clear_tv(&var1);
- clear_tv(&var2);
+ } else if (evaluate && !tv_check_str(&var2)) {
+ // Not a number or string.
+ if (!empty1) {
+ tv_clear(&var1);
+ }
+ tv_clear(&var2);
return FAIL;
}
}
/* Check for the ']'. */
if (**arg != ']') {
- if (verbose)
+ if (verbose) {
EMSG(_(e_missbrac));
- clear_tv(&var1);
- if (range)
- clear_tv(&var2);
+ }
+ tv_clear(&var1);
+ if (range) {
+ tv_clear(&var2);
+ }
return FAIL;
}
*arg = skipwhite(*arg + 1); /* skip the ']' */
@@ -4465,169 +4453,179 @@ eval_index (
if (evaluate) {
n1 = 0;
if (!empty1 && rettv->v_type != VAR_DICT) {
- n1 = get_tv_number(&var1);
- clear_tv(&var1);
+ n1 = tv_get_number(&var1);
+ tv_clear(&var1);
}
if (range) {
- if (empty2)
+ if (empty2) {
n2 = -1;
- else {
- n2 = get_tv_number(&var2);
- clear_tv(&var2);
+ } else {
+ n2 = tv_get_number(&var2);
+ tv_clear(&var2);
}
}
switch (rettv->v_type) {
- case VAR_NUMBER:
- case VAR_STRING:
- s = get_tv_string(rettv);
- len = (long)STRLEN(s);
- if (range) {
- /* The resulting variable is a substring. If the indexes
- * are out of range the result is empty. */
+ case VAR_NUMBER:
+ case VAR_STRING: {
+ const char *const s = tv_get_string(rettv);
+ char *v;
+ len = (ptrdiff_t)strlen(s);
+ if (range) {
+ // The resulting variable is a substring. If the indexes
+ // are out of range the result is empty.
+ if (n1 < 0) {
+ n1 = len + n1;
+ if (n1 < 0) {
+ n1 = 0;
+ }
+ }
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len;
+ }
+ if (n1 >= len || n2 < 0 || n1 > n2) {
+ v = NULL;
+ } else {
+ v = xmemdupz(s + n1, (size_t)(n2 - n1 + 1));
+ }
+ } else {
+ // The resulting variable is a string of a single
+ // character. If the index is too big or negative the
+ // result is empty.
+ if (n1 >= len || n1 < 0) {
+ v = NULL;
+ } else {
+ v = xmemdupz(s + n1, 1);
+ }
+ }
+ tv_clear(rettv);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = (char_u *)v;
+ break;
+ }
+ case VAR_LIST: {
+ len = tv_list_len(rettv->vval.v_list);
if (n1 < 0) {
n1 = len + n1;
- if (n1 < 0)
- n1 = 0;
}
- if (n2 < 0)
- n2 = len + n2;
- else if (n2 >= len)
- n2 = len;
- if (n1 >= len || n2 < 0 || n1 > n2)
- s = NULL;
- else
- s = vim_strnsave(s + n1, (int)(n2 - n1 + 1));
- } else {
- /* The resulting variable is a string of a single
- * character. If the index is too big or negative the
- * result is empty. */
- if (n1 >= len || n1 < 0)
- s = NULL;
- else
- s = vim_strnsave(s + n1, 1);
- }
- clear_tv(rettv);
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = s;
- break;
-
- case VAR_LIST:
- len = list_len(rettv->vval.v_list);
- if (n1 < 0)
- n1 = len + n1;
- if (!empty1 && (n1 < 0 || n1 >= len)) {
- /* For a range we allow invalid values and return an empty
- * list. A list index out of range is an error. */
- if (!range) {
- if (verbose)
- EMSGN(_(e_listidx), n1);
- return FAIL;
+ if (!empty1 && (n1 < 0 || n1 >= len)) {
+ // For a range we allow invalid values and return an empty
+ // list. A list index out of range is an error.
+ if (!range) {
+ if (verbose) {
+ EMSGN(_(e_listidx), n1);
+ }
+ return FAIL;
+ }
+ n1 = len;
}
- n1 = len;
- }
- if (range) {
- list_T *l;
- listitem_T *item;
-
- if (n2 < 0)
- n2 = len + n2;
- else if (n2 >= len)
- n2 = len - 1;
- if (!empty2 && (n2 < 0 || n2 + 1 < n1))
- n2 = -1;
- l = list_alloc();
- item = list_find(rettv->vval.v_list, n1);
- while (n1++ <= n2) {
- list_append_tv(l, &item->li_tv);
- item = item->li_next;
+ if (range) {
+ list_T *l;
+ listitem_T *item;
+
+ if (n2 < 0) {
+ n2 = len + n2;
+ } else if (n2 >= len) {
+ n2 = len - 1;
+ }
+ if (!empty2 && (n2 < 0 || n2 + 1 < n1)) {
+ n2 = -1;
+ }
+ l = tv_list_alloc(n2 - n1 + 1);
+ item = tv_list_find(rettv->vval.v_list, n1);
+ while (n1++ <= n2) {
+ tv_list_append_tv(l, TV_LIST_ITEM_TV(item));
+ item = TV_LIST_ITEM_NEXT(rettv->vval.v_list, item);
+ }
+ tv_clear(rettv);
+ tv_list_set_ret(rettv, l);
+ } else {
+ tv_copy(TV_LIST_ITEM_TV(tv_list_find(rettv->vval.v_list, n1)), &var1);
+ tv_clear(rettv);
+ *rettv = var1;
}
- clear_tv(rettv);
- rettv->v_type = VAR_LIST;
- rettv->vval.v_list = l;
- ++l->lv_refcount;
- } else {
- copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, &var1);
- clear_tv(rettv);
- *rettv = var1;
- }
- break;
-
- case VAR_DICT:
- if (range) {
- if (verbose)
- EMSG(_(e_dictrange));
- if (len == -1)
- clear_tv(&var1);
- return FAIL;
+ break;
}
- {
- dictitem_T *item;
+ case VAR_DICT: {
+ if (range) {
+ if (verbose) {
+ EMSG(_(e_dictrange));
+ }
+ if (len == -1) {
+ tv_clear(&var1);
+ }
+ return FAIL;
+ }
if (len == -1) {
- key = get_tv_string(&var1);
- if (*key == NUL) {
- if (verbose)
- EMSG(_(e_emptykey));
- clear_tv(&var1);
+ key = (char_u *)tv_get_string_chk(&var1);
+ if (key == NULL) {
+ tv_clear(&var1);
return FAIL;
}
}
- item = dict_find(rettv->vval.v_dict, key, (int)len);
+ dictitem_T *const item = tv_dict_find(rettv->vval.v_dict,
+ (const char *)key, len);
- if (item == NULL && verbose)
- EMSG2(_(e_dictkey), key);
- if (len == -1)
- clear_tv(&var1);
- if (item == NULL)
+ if (item == NULL && verbose) {
+ emsgf(_(e_dictkey), key);
+ }
+ if (len == -1) {
+ tv_clear(&var1);
+ }
+ if (item == NULL) {
return FAIL;
+ }
- copy_tv(&item->di_tv, &var1);
- clear_tv(rettv);
+ tv_copy(&item->di_tv, &var1);
+ tv_clear(rettv);
*rettv = var1;
+ break;
+ }
+ case VAR_SPECIAL:
+ case VAR_FUNC:
+ case VAR_FLOAT:
+ case VAR_PARTIAL:
+ case VAR_UNKNOWN: {
+ break; // Not evaluating, skipping over subscript
}
- break;
- case VAR_SPECIAL:
- case VAR_FUNC:
- case VAR_FLOAT:
- case VAR_UNKNOWN:
- break; // Not evaluating, skipping over subscript
}
}
return OK;
}
-/*
- * Get an option value.
- * "arg" points to the '&' or '+' before the option name.
- * "arg" is advanced to character after the option name.
- * Return OK or FAIL.
- */
-static int
-get_option_tv (
- char_u **arg,
- typval_T *rettv, /* when NULL, only check if option exists */
- int evaluate
-)
+// TODO(ZyX-I): move to eval/executor
+
+/// Get an option value
+///
+/// @param[in,out] arg Points to the '&' or '+' before the option name. Is
+/// advanced to the character after the option name.
+/// @param[out] rettv Location where result is saved.
+/// @param[in] evaluate If not true, rettv is not populated.
+///
+/// @return OK or FAIL.
+static int get_option_tv(const char **const arg, typval_T *const rettv,
+ const bool evaluate)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- char_u *option_end;
long numval;
char_u *stringval;
int opt_type;
int c;
- int working = (**arg == '+'); /* has("+option") */
+ bool working = (**arg == '+'); // has("+option")
int ret = OK;
int opt_flags;
- /*
- * Isolate the option name and find its value.
- */
- option_end = find_option_end(arg, &opt_flags);
+ // Isolate the option name and find its value.
+ char *option_end = (char *)find_option_end(arg, &opt_flags);
if (option_end == NULL) {
- if (rettv != NULL)
+ if (rettv != NULL) {
EMSG2(_("E112: Option name missing: %s"), *arg);
+ }
return FAIL;
}
@@ -4638,8 +4636,8 @@ get_option_tv (
c = *option_end;
*option_end = NUL;
- opt_type = get_option_value(*arg, &numval,
- rettv == NULL ? NULL : &stringval, opt_flags);
+ opt_type = get_option_value((char_u *)(*arg), &numval,
+ rettv == NULL ? NULL : &stringval, opt_flags);
if (opt_type == -3) { /* invalid name */
if (rettv != NULL)
@@ -4681,7 +4679,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
/*
* Find the end of the string, skipping backslashed characters.
*/
- for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) {
+ for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p)) {
if (*p == '\\' && p[1] != NUL) {
++p;
/* A "\<x>" form occupies at least 4 characters, and produces up
@@ -4743,10 +4741,11 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
++p;
/* For "\u" store the number according to
* 'encoding'. */
- if (c != 'X')
- name += (*mb_char2bytes)(nr, name);
- else
+ if (c != 'X') {
+ name += utf_char2bytes(nr, name);
+ } else {
*name++ = nr;
+ }
}
break;
@@ -4769,12 +4768,12 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
// Special key, e.g.: "\<C-W>"
case '<':
- extra = trans_special((const char_u **) &p, STRLEN(p), name, true);
+ extra = trans_special((const char_u **)&p, STRLEN(p), name, true, true);
if (extra != 0) {
name += extra;
break;
}
- // FALLTHROUGH
+ FALLTHROUGH;
default: MB_COPY_CHAR(p, name);
break;
@@ -4784,7 +4783,10 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate)
}
*name = NUL;
- *arg = p + 1;
+ if (*p != NUL) { // just in case
+ p++;
+ }
+ *arg = p;
return OK;
}
@@ -4802,7 +4804,7 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
/*
* Find the end of the string, skipping ''.
*/
- for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) {
+ for (p = *arg + 1; *p != NUL; MB_PTR_ADV(p)) {
if (*p == '\'') {
if (p[1] != '\'')
break;
@@ -4843,773 +4845,144 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
-/*
- * Allocate a variable for a List and fill it from "*arg".
- * Return OK or FAIL.
- */
+/// @return the function name of the partial.
+char_u *partial_name(partial_T *pt)
+{
+ if (pt->pt_name != NULL) {
+ return pt->pt_name;
+ }
+ return 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++) {
+ tv_clear(&pt->pt_argv[i]);
+ }
+ xfree(pt->pt_argv);
+ tv_dict_unref(pt->pt_dict);
+ if (pt->pt_name != NULL) {
+ func_unref(pt->pt_name);
+ xfree(pt->pt_name);
+ } else {
+ func_ptr_unref(pt->pt_func);
+ }
+ 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)
+{
+ if (pt != NULL && --pt->pt_refcount <= 0) {
+ partial_free(pt);
+ }
+}
+
+/// Allocate a variable for a List and fill it from "*arg".
+/// Return OK or FAIL.
static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate)
{
list_T *l = NULL;
- typval_T tv;
- listitem_T *item;
if (evaluate) {
- l = list_alloc();
+ l = tv_list_alloc(kListLenShouldKnow);
}
*arg = skipwhite(*arg + 1);
while (**arg != ']' && **arg != NUL) {
- if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */
+ typval_T tv;
+ if (eval1(arg, &tv, evaluate) == FAIL) { // Recursive!
goto failret;
+ }
if (evaluate) {
- item = listitem_alloc();
- item->li_tv = tv;
- item->li_tv.v_lock = 0;
- list_append(l, item);
+ tv.v_lock = VAR_UNLOCKED;
+ tv_list_append_owned_tv(l, tv);
}
- if (**arg == ']')
+ if (**arg == ']') {
break;
+ }
if (**arg != ',') {
- EMSG2(_("E696: Missing comma in List: %s"), *arg);
+ emsgf(_("E696: Missing comma in List: %s"), *arg);
goto failret;
}
*arg = skipwhite(*arg + 1);
}
if (**arg != ']') {
- EMSG2(_("E697: Missing end of List ']': %s"), *arg);
+ emsgf(_("E697: Missing end of List ']': %s"), *arg);
failret:
- if (evaluate)
- list_free(l, TRUE);
+ if (evaluate) {
+ tv_list_free(l);
+ }
return FAIL;
}
*arg = skipwhite(*arg + 1);
if (evaluate) {
- rettv->v_type = VAR_LIST;
- rettv->vval.v_list = l;
- ++l->lv_refcount;
+ tv_list_set_ret(rettv, l);
}
return OK;
}
-/*
- * Allocate an empty header for a list.
- * Caller should take care of the reference count.
- */
-list_T *list_alloc(void) FUNC_ATTR_NONNULL_RET
-{
- list_T *list = xcalloc(1, sizeof(list_T));
-
- /* Prepend the list to the list of lists for garbage collection. */
- if (first_list != NULL)
- first_list->lv_used_prev = list;
- list->lv_used_prev = NULL;
- list->lv_used_next = first_list;
- first_list = list;
- return list;
-}
-
-/*
- * Allocate an empty list for a return value.
- */
-static list_T *rettv_list_alloc(typval_T *rettv)
-{
- list_T *l = list_alloc();
- rettv->vval.v_list = l;
- rettv->v_type = VAR_LIST;
- ++l->lv_refcount;
- return l;
-}
-
-/*
- * Unreference a list: decrement the reference count and free it when it
- * becomes zero.
- */
-void list_unref(list_T *l)
-{
- if (l != NULL && --l->lv_refcount <= 0)
- list_free(l, TRUE);
-}
-
-/*
- * Free a list, including all items it points to.
- * Ignores the reference count.
- */
-void
-list_free (
- list_T *l,
- int recurse /* Free Lists and Dictionaries recursively. */
-)
-{
- listitem_T *item;
-
- /* Remove the list from the list of lists for garbage collection. */
- if (l->lv_used_prev == NULL)
- first_list = l->lv_used_next;
- else
- l->lv_used_prev->lv_used_next = l->lv_used_next;
- if (l->lv_used_next != NULL)
- l->lv_used_next->lv_used_prev = l->lv_used_prev;
-
- for (item = l->lv_first; item != NULL; item = l->lv_first) {
- /* Remove the item before deleting it. */
- l->lv_first = item->li_next;
- if (recurse || (item->li_tv.v_type != VAR_LIST
- && item->li_tv.v_type != VAR_DICT))
- clear_tv(&item->li_tv);
- xfree(item);
- }
- xfree(l);
-}
-
-/*
- * Allocate a list item.
- * It is not initialized, don't forget to set v_lock.
- */
-listitem_T *listitem_alloc(void) FUNC_ATTR_NONNULL_RET
-{
- return xmalloc(sizeof(listitem_T));
-}
-
-/*
- * Free a list item. Also clears the value. Does not notify watchers.
- */
-void listitem_free(listitem_T *item)
-{
- clear_tv(&item->li_tv);
- xfree(item);
-}
-
-/*
- * Remove a list item from a List and free it. Also clears the value.
- */
-void listitem_remove(list_T *l, listitem_T *item)
-{
- vim_list_remove(l, item, item);
- listitem_free(item);
-}
-
-/*
- * Get the number of items in a list.
- */
-static long list_len(list_T *l)
-{
- if (l == NULL)
- return 0L;
- return l->lv_len;
-}
-
-/*
- * Return TRUE when two lists have exactly the same values.
- */
-static int
-list_equal (
- list_T *l1,
- list_T *l2,
- int ic, /* ignore case for strings */
- int recursive /* TRUE when used recursively */
-)
-{
- listitem_T *item1, *item2;
-
- if (l1 == NULL || l2 == NULL)
- return FALSE;
- if (l1 == l2)
- return TRUE;
- if (list_len(l1) != list_len(l2))
- return FALSE;
-
- for (item1 = l1->lv_first, item2 = l2->lv_first;
- item1 != NULL && item2 != NULL;
- item1 = item1->li_next, item2 = item2->li_next)
- if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
- return FALSE;
- return item1 == NULL && item2 == NULL;
-}
-
-/*
- * Return the dictitem that an entry in a hashtable points to.
- */
-dictitem_T *dict_lookup(hashitem_T *hi)
-{
- return HI2DI(hi);
-}
-
-/*
- * Return TRUE when two dictionaries have exactly the same key/values.
- */
-static int
-dict_equal (
- dict_T *d1,
- dict_T *d2,
- int ic, /* ignore case for strings */
- int recursive /* TRUE when used recursively */
-)
-{
- hashitem_T *hi;
- dictitem_T *item2;
- int todo;
-
- if (d1 == NULL || d2 == NULL)
- return FALSE;
- if (d1 == d2)
- return TRUE;
- if (dict_len(d1) != dict_len(d2))
- return FALSE;
-
- todo = (int)d1->dv_hashtab.ht_used;
- for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- item2 = dict_find(d2, hi->hi_key, -1);
- if (item2 == NULL)
- return FALSE;
- if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic, recursive))
- return FALSE;
- --todo;
- }
- }
- return TRUE;
-}
-
-static int tv_equal_recurse_limit;
-
-/*
- * Return TRUE if "tv1" and "tv2" have the same value.
- * Compares the items just like "==" would compare them, but strings and
- * numbers are different. Floats and numbers are also different.
- */
-static int
-tv_equal (
+bool func_equal(
typval_T *tv1,
typval_T *tv2,
- int ic, /* ignore case */
- int recursive /* TRUE when used recursively */
-)
-{
- char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
- char_u *s1, *s2;
- static int recursive_cnt = 0; /* catch recursive loops */
- int r;
-
- if (tv1->v_type != tv2->v_type)
- return FALSE;
-
- /* Catch lists and dicts that have an endless loop by limiting
- * recursiveness to a limit. We guess they are equal then.
- * A fixed limit has the problem of still taking an awful long time.
- * Reduce the limit every time running into it. That should work fine for
- * deeply linked structures that are not recursively linked and catch
- * recursiveness quickly. */
- if (!recursive)
- tv_equal_recurse_limit = 1000;
- if (recursive_cnt >= tv_equal_recurse_limit) {
- --tv_equal_recurse_limit;
- return TRUE;
- }
-
- switch (tv1->v_type) {
- case VAR_LIST:
- ++recursive_cnt;
- r = list_equal(tv1->vval.v_list, tv2->vval.v_list, ic, TRUE);
- --recursive_cnt;
- return r;
-
- case VAR_DICT:
- ++recursive_cnt;
- r = dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic, TRUE);
- --recursive_cnt;
- return r;
-
- case VAR_FUNC:
- return tv1->vval.v_string != NULL
- && tv2->vval.v_string != NULL
- && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0;
-
- case VAR_NUMBER:
- return tv1->vval.v_number == tv2->vval.v_number;
-
- case VAR_FLOAT:
- return tv1->vval.v_float == tv2->vval.v_float;
-
- case VAR_STRING:
- s1 = get_tv_string_buf(tv1, buf1);
- s2 = get_tv_string_buf(tv2, buf2);
- return (ic ? mb_stricmp(s1, s2) : STRCMP(s1, s2)) == 0;
-
- case VAR_SPECIAL:
- return tv1->vval.v_special == tv2->vval.v_special;
-
- case VAR_UNKNOWN:
- // VAR_UNKNOWN can be the result of an invalid expression, let’s say it does
- // not equal anything, not even self.
+ bool ic // ignore case
+) {
+ char_u *s1, *s2;
+ dict_T *d1, *d2;
+ int a1, a2;
+
+ // empty and NULL function name considered the same
+ s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string
+ : partial_name(tv1->vval.v_partial);
+ if (s1 != NULL && *s1 == NUL) {
+ s1 = NULL;
+ }
+ s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string
+ : partial_name(tv2->vval.v_partial);
+ if (s2 != NULL && *s2 == NUL) {
+ s2 = NULL;
+ }
+ if (s1 == NULL || s2 == NULL) {
+ if (s1 != s2) {
+ return false;
+ }
+ } else if (STRCMP(s1, s2) != 0) {
return false;
}
- assert(false);
- return false;
-}
-
-/*
- * Locate item with index "n" in list "l" and return it.
- * A negative index is counted from the end; -1 is the last item.
- * Returns NULL when "n" is out of range.
- */
-listitem_T *list_find(list_T *l, long n)
-{
- listitem_T *item;
- long idx;
-
- if (l == NULL)
- return NULL;
-
- /* Negative index is relative to the end. */
- if (n < 0)
- n = l->lv_len + n;
-
- /* Check for index out of range. */
- if (n < 0 || n >= l->lv_len)
- return NULL;
-
- /* When there is a cached index may start search from there. */
- if (l->lv_idx_item != NULL) {
- if (n < l->lv_idx / 2) {
- /* closest to the start of the list */
- item = l->lv_first;
- idx = 0;
- } else if (n > (l->lv_idx + l->lv_len) / 2) {
- /* closest to the end of the list */
- item = l->lv_last;
- idx = l->lv_len - 1;
- } else {
- /* closest to the cached index */
- item = l->lv_idx_item;
- idx = l->lv_idx;
- }
- } else {
- if (n < l->lv_len / 2) {
- /* closest to the start of the list */
- item = l->lv_first;
- idx = 0;
- } else {
- /* closest to the end of the list */
- item = l->lv_last;
- idx = l->lv_len - 1;
- }
- }
-
- while (n > idx) {
- /* search forward */
- item = item->li_next;
- ++idx;
- }
- while (n < idx) {
- /* search backward */
- item = item->li_prev;
- --idx;
- }
-
- /* cache the used index */
- l->lv_idx = idx;
- l->lv_idx_item = item;
-
- return item;
-}
-
-/*
- * Get list item "l[idx]" as a number.
- */
-static long
-list_find_nr (
- list_T *l,
- long idx,
- int *errorp /* set to TRUE when something wrong */
-)
-{
- listitem_T *li;
-
- li = list_find(l, idx);
- if (li == NULL) {
- if (errorp != NULL)
- *errorp = TRUE;
- return -1L;
- }
- return get_tv_number_chk(&li->li_tv, errorp);
-}
-
-/*
- * Get list item "l[idx - 1]" as a string. Returns NULL for failure.
- */
-char_u *list_find_str(list_T *l, long idx)
-{
- listitem_T *li;
-
- li = list_find(l, idx - 1);
- if (li == NULL) {
- EMSGN(_(e_listidx), idx);
- return NULL;
- }
- return get_tv_string(&li->li_tv);
-}
-
-/*
- * Locate "item" list "l" and return its index.
- * Returns -1 when "item" is not in the list.
- */
-static long list_idx_of_item(list_T *l, listitem_T *item)
-{
- long idx = 0;
- listitem_T *li;
-
- if (l == NULL)
- return -1;
- idx = 0;
- for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
- ++idx;
- if (li == NULL)
- return -1;
- return idx;
-}
-
-/*
- * Append item "item" to the end of list "l".
- */
-void list_append(list_T *l, listitem_T *item)
-{
- if (l->lv_last == NULL) {
- /* empty list */
- l->lv_first = item;
- l->lv_last = item;
- item->li_prev = NULL;
- } else {
- l->lv_last->li_next = item;
- item->li_prev = l->lv_last;
- l->lv_last = item;
- }
- ++l->lv_len;
- item->li_next = NULL;
-}
-
-/*
- * Append typval_T "tv" to the end of list "l".
- */
-void list_append_tv(list_T *l, typval_T *tv)
-{
- listitem_T *li = listitem_alloc();
- copy_tv(tv, &li->li_tv);
- list_append(l, li);
-}
-
-/*
- * Add a list to a list.
- */
-void list_append_list(list_T *list, list_T *itemlist)
-{
- listitem_T *li = listitem_alloc();
-
- li->li_tv.v_type = VAR_LIST;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_list = itemlist;
- list_append(list, li);
- ++itemlist->lv_refcount;
-}
-
-/*
- * Add a dictionary to a list. Used by getqflist().
- */
-void list_append_dict(list_T *list, dict_T *dict)
-{
- listitem_T *li = listitem_alloc();
-
- li->li_tv.v_type = VAR_DICT;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_dict = dict;
- list_append(list, li);
- ++dict->dv_refcount;
-}
-
-/// Make a copy of "str" and append it as an item to list "l"
-///
-/// @param[out] l List to append to.
-/// @param[in] str String to append.
-/// @param[in] len Length of the appended string. May be negative, in this
-/// case string is considered to be usual zero-terminated
-/// string.
-void list_append_string(list_T *l, const char_u *str, int len)
- FUNC_ATTR_NONNULL_ARG(1)
-{
- if (str == NULL) {
- list_append_allocated_string(l, NULL);
- } else {
- list_append_allocated_string(l, (len >= 0
- ? xmemdupz((char *) str, len)
- : xstrdup((char *) str)));
- }
-}
-
-/// Append given string to the list
-///
-/// Unlike list_append_string this function does not copy the string.
-///
-/// @param[out] l List to append to.
-/// @param[in] str String to append.
-void list_append_allocated_string(list_T *l, char *const str)
- FUNC_ATTR_NONNULL_ARG(1)
-{
- listitem_T *li = listitem_alloc();
-
- list_append(l, li);
- li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = (char_u *) str;
-}
-
-/*
- * Append "n" to list "l".
- */
-void list_append_number(list_T *l, varnumber_T n)
-{
- listitem_T *li = listitem_alloc();
- li->li_tv.v_type = VAR_NUMBER;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_number = n;
- list_append(l, li);
-}
-
-/*
- * Insert typval_T "tv" in list "l" before "item".
- * If "item" is NULL append at the end.
- */
-void list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
-{
- listitem_T *ni = listitem_alloc();
-
- copy_tv(tv, &ni->li_tv);
- list_insert(l, ni, item);
-}
-
-void list_insert(list_T *l, listitem_T *ni, listitem_T *item)
-{
- if (item == NULL)
- /* Append new item at end of list. */
- list_append(l, ni);
- else {
- /* Insert new item before existing item. */
- ni->li_prev = item->li_prev;
- ni->li_next = item;
- if (item->li_prev == NULL) {
- l->lv_first = ni;
- ++l->lv_idx;
- } else {
- item->li_prev->li_next = ni;
- l->lv_idx_item = NULL;
+ // empty dict and NULL dict is different
+ d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict;
+ d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict;
+ if (d1 == NULL || d2 == NULL) {
+ if (d1 != d2) {
+ return false;
}
- item->li_prev = ni;
- ++l->lv_len;
- }
-}
-
-/*
- * Extend "l1" with "l2".
- * If "bef" is NULL append at the end, otherwise insert before this item.
- */
-static void list_extend(list_T *l1, list_T *l2, listitem_T *bef)
-{
- listitem_T *item;
- int todo = l2->lv_len;
-
- /* We also quit the loop when we have inserted the original item count of
- * the list, avoid a hang when we extend a list with itself. */
- for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) {
- list_insert_tv(l1, &item->li_tv, bef);
- }
-}
-
-/*
- * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
- * Return FAIL on failure to copy.
- */
-static int list_concat(list_T *l1, list_T *l2, typval_T *tv)
-{
- list_T *l;
-
- if (l1 == NULL || l2 == NULL)
- return FAIL;
-
- /* make a copy of the first list. */
- l = list_copy(NULL, l1, false, 0);
- if (l == NULL)
- return FAIL;
- tv->v_type = VAR_LIST;
- tv->vval.v_list = l;
-
- /* append all items from the second list */
- list_extend(l, l2, NULL);
- return OK;
-}
-
-/// Make a copy of list
-///
-/// @param[in] conv If non-NULL, then all internal strings will be converted.
-/// @param[in] orig Original list to copy.
-/// @param[in] deep If false, then shallow copy will be done.
-/// @param[in] copyID See var_item_copy().
-///
-/// @return Copied list. May be NULL in case original list is NULL or some
-/// failure happens. The refcount of the new list is set to 1.
-static list_T *list_copy(const vimconv_T *const conv,
- list_T *const orig,
- const bool deep,
- const int copyID)
- FUNC_ATTR_WARN_UNUSED_RESULT
-{
- listitem_T *item;
- listitem_T *ni;
-
- if (orig == NULL)
- return NULL;
-
- list_T *copy = list_alloc();
- if (copyID != 0) {
- /* Do this before adding the items, because one of the items may
- * refer back to this list. */
- orig->lv_copyID = copyID;
- orig->lv_copylist = copy;
- }
- for (item = orig->lv_first; item != NULL && !got_int;
- item = item->li_next) {
- ni = listitem_alloc();
- if (deep) {
- if (var_item_copy(conv, &item->li_tv, &ni->li_tv, deep, copyID) == FAIL) {
- xfree(ni);
- break;
- }
- } else
- copy_tv(&item->li_tv, &ni->li_tv);
- list_append(copy, ni);
- }
- ++copy->lv_refcount;
- if (item != NULL) {
- list_unref(copy);
- copy = NULL;
- }
-
- return copy;
-}
-
-/// Remove items "item" to "item2" from list "l".
-/// @warning Does not free the listitem or the value!
-void vim_list_remove(list_T *l, listitem_T *item, listitem_T *item2)
-{
- // notify watchers
- for (listitem_T *ip = item; ip != NULL; ip = ip->li_next) {
- --l->lv_len;
- list_fix_watch(l, ip);
- if (ip == item2) {
- break;
- }
- }
-
- if (item2->li_next == NULL) {
- l->lv_last = item->li_prev;
- } else {
- item2->li_next->li_prev = item->li_prev;
- }
- if (item->li_prev == NULL) {
- l->lv_first = item2->li_next;
- } else {
- item->li_prev->li_next = item2->li_next;
+ } else if (!tv_dict_equal(d1, d2, ic, true)) {
+ return false;
}
- l->lv_idx_item = NULL;
-}
-
-typedef struct join_S {
- char_u *s;
- char_u *tofree;
-} join_T;
-
-/// Join list into a string, helper function
-///
-/// @param[out] gap Garray where result will be saved.
-/// @param[in] l List to join.
-/// @param[in] sep Used separator.
-/// @param[in] join_gap Garray to keep each list item string.
-///
-/// @return OK in case of success, FAIL otherwise.
-static int list_join_inner(garray_T *const gap, list_T *const l,
- const char *const sep, garray_T *const join_gap)
- FUNC_ATTR_NONNULL_ALL
-{
- int sumlen = 0;
- bool first = true;
- listitem_T *item;
-
- /* Stringify each item in the list. */
- for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) {
- char *s;
- size_t len;
- s = encode_tv2echo(&item->li_tv, &len);
- if (s == NULL) {
- return FAIL;
- }
-
- sumlen += (int) len;
- join_T *const p = GA_APPEND_VIA_PTR(join_T, join_gap);
- p->tofree = p->s = (char_u *) s;
-
- line_breakcheck();
+ // empty list and no list considered the same
+ a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc;
+ a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc;
+ if (a1 != a2) {
+ return false;
}
-
- /* Allocate result buffer with its total size, avoid re-allocation and
- * multiple copy operations. Add 2 for a tailing ']' and NUL. */
- if (join_gap->ga_len >= 2)
- sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
- ga_grow(gap, sumlen + 2);
-
- for (int i = 0; i < join_gap->ga_len && !got_int; ++i) {
- if (first) {
- first = false;
- } else {
- ga_concat(gap, (const char_u *) sep);
+ for (int i = 0; i < a1; i++) {
+ if (!tv_equal(tv1->vval.v_partial->pt_argv + i,
+ tv2->vval.v_partial->pt_argv + i, ic, true)) {
+ return false;
}
- const join_T *const p = ((const join_T *)join_gap->ga_data) + i;
-
- if (p->s != NULL)
- ga_concat(gap, p->s);
- line_breakcheck();
- }
-
- return OK;
-}
-
-/// Join list into a string using given separator
-///
-/// @param[out] gap Garray where result will be saved.
-/// @param[in] l Joined list.
-/// @param[in] sep Separator.
-///
-/// @return OK in case of success, FAIL otherwise.
-static int list_join(garray_T *const gap, list_T *const l,
- const char *const sep)
- FUNC_ATTR_NONNULL_ALL
-{
- if (l->lv_len < 1) {
- return OK;
}
-
- garray_T join_ga;
- int retval;
-
- ga_init(&join_ga, (int)sizeof(join_T), l->lv_len);
- retval = list_join_inner(gap, l, sep, &join_ga);
-
-# define FREE_JOIN_TOFREE(join) xfree((join)->tofree)
- GA_DEEP_CLEAR(&join_ga, join_T, FREE_JOIN_TOFREE);
-
- return retval;
+ return true;
}
/// Get next (unique) copy ID
@@ -5628,6 +5001,9 @@ int get_copyID(void)
return current_copyID;
}
+// Used by get_func_tv()
+static garray_T funcargs = GA_EMPTY_INIT_VALUE;
+
/*
* Garbage collection for lists and dictionaries.
*
@@ -5650,19 +5026,22 @@ int get_copyID(void)
/// Do garbage collection for lists and dicts.
///
+/// @param testing true if called from test_garbagecollect_now().
/// @returns true if some memory was freed.
-bool garbage_collect(void)
+bool garbage_collect(bool testing)
{
bool abort = false;
#define ABORTING(func) abort = abort || func
- // Only do this once.
- want_garbage_collect = false;
- may_garbage_collect = false;
- garbage_collect_at_exit = false;
+ if (!testing) {
+ // Only do this once.
+ want_garbage_collect = false;
+ may_garbage_collect = false;
+ garbage_collect_at_exit = false;
+ }
- // We advance by two because we add one for items referenced through
- // previous_funccal.
+ // We advance by two (COPYID_INC) because we add one for items referenced
+ // through previous_funccal.
const int copyID = get_copyID();
// 1. Go through all accessible variables and mark all lists and dicts
@@ -5672,6 +5051,7 @@ bool garbage_collect(void)
// referenced through previous_funccal. This must be first, because if
// the item is referenced elsewhere the funccal must not be freed.
for (funccall_T *fc = previous_funccal; fc != NULL; fc = fc->caller) {
+ fc->fc_copyID = copyID + 1;
ABORTING(set_ref_in_ht)(&fc->l_vars.dv_hashtab, copyID + 1, NULL);
ABORTING(set_ref_in_ht)(&fc->l_avars.dv_hashtab, copyID + 1, NULL);
}
@@ -5717,7 +5097,8 @@ bool garbage_collect(void)
do {
yankreg_T reg;
char name = NUL;
- reg_iter = op_register_iter(reg_iter, &name, &reg);
+ bool is_unnamed = false;
+ reg_iter = op_register_iter(reg_iter, &name, &reg, &is_unnamed);
if (name != NUL) {
ABORTING(set_ref_dict)(reg.additional_data, copyID);
}
@@ -5747,18 +5128,38 @@ bool garbage_collect(void)
// function-local variables
for (funccall_T *fc = current_funccal; fc != NULL; fc = fc->caller) {
+ fc->fc_copyID = copyID;
ABORTING(set_ref_in_ht)(&fc->l_vars.dv_hashtab, copyID, NULL);
ABORTING(set_ref_in_ht)(&fc->l_avars.dv_hashtab, copyID, NULL);
}
- // Jobs
+ // named functions (matters for closures)
+ ABORTING(set_ref_in_functions(copyID));
+
+ // Channels
+ {
+ Channel *data;
+ map_foreach_value(channels, data, {
+ set_ref_in_callback_reader(&data->on_stdout, copyID, NULL, NULL);
+ set_ref_in_callback_reader(&data->on_stderr, copyID, NULL, NULL);
+ set_ref_in_callback(&data->on_exit, copyID, NULL, NULL);
+ })
+ }
+
+ // Timers
{
- TerminalJobData *data;
- map_foreach_value(jobs, data, {
- ABORTING(set_ref_dict)(data->self, copyID);
+ timer_T *timer;
+ map_foreach_value(timers, timer, {
+ set_ref_in_callback(&timer->callback, copyID, NULL, NULL);
})
}
+ // function call arguments, if v:testing is set.
+ for (int i = 0; i < funcargs.ga_len; i++) {
+ ABORTING(set_ref_in_item)(((typval_T **)funcargs.ga_data)[i],
+ copyID, NULL, NULL);
+ }
+
// v: vars
ABORTING(set_ref_in_ht)(&vimvarht, copyID, NULL);
@@ -5792,6 +5193,8 @@ bool garbage_collect(void)
ABORTING(set_ref_list)(sub.additional_elements, copyID);
}
+ ABORTING(set_ref_in_quickfix)(copyID);
+
bool did_free = false;
if (!abort) {
// 2. Free lists and dictionaries that are not referenced.
@@ -5813,7 +5216,7 @@ bool garbage_collect(void)
if (did_free_funccal) {
// When a funccal was freed some more items might be garbage
// collected, so run again.
- (void)garbage_collect();
+ (void)garbage_collect(testing);
}
} else if (p_verbose > 0) {
verb_msg((char_u *)_(
@@ -5825,7 +5228,7 @@ bool garbage_collect(void)
/// Free lists and dictionaries that are no longer referenced.
///
-/// Note: This function may only be called from garbage_collect().
+/// @note This function may only be called from garbage_collect().
///
/// @param copyID Free lists/dictionaries that don't have this ID.
/// @return true, if something was freed.
@@ -5833,40 +5236,61 @@ static int free_unref_items(int copyID)
{
bool did_free = false;
+ // Let all "free" functions know that we are here. This means no
+ // dictionaries, lists, or jobs are to be freed, because we will
+ // do that here.
+ tv_in_free_unref_items = true;
+
+ // PASS 1: free the contents of the items. We don't free the items
+ // themselves yet, so that it is possible to decrement refcount counters.
+
// Go through the list of dicts and free items without the copyID.
// Don't free dicts that are referenced internally.
- for (dict_T *dd = first_dict; dd != NULL; ) {
+ for (dict_T *dd = gc_first_dict; dd != NULL; dd = dd->dv_used_next) {
if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
// Free the Dictionary and ordinary items it contains, but don't
// recurse into Lists and Dictionaries, they will be in the list
- // of dicts or list of lists. */
- dict_T *dd_next = dd->dv_used_next;
- dict_free(dd, FALSE);
+ // of dicts or list of lists.
+ tv_dict_free_contents(dd);
did_free = true;
- dd = dd_next;
- } else {
- dd = dd->dv_used_next;
}
}
// Go through the list of lists and free items without the copyID.
// But don't free a list that has a watcher (used in a for loop), these
// are not referenced anywhere.
- for (list_T *ll = first_list; ll != NULL;) {
- if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
- && ll->lv_watch == NULL) {
+ for (list_T *ll = gc_first_list; ll != NULL; ll = ll->lv_used_next) {
+ if ((tv_list_copyid(ll) & COPYID_MASK) != (copyID & COPYID_MASK)
+ && !tv_list_has_watchers(ll)) {
// Free the List and ordinary items it contains, but don't recurse
// into Lists and Dictionaries, they will be in the list of dicts
// or list of lists.
- list_T* ll_next = ll->lv_used_next;
- list_free(ll, FALSE);
+ tv_list_free_contents(ll);
did_free = true;
- ll = ll_next;
- } else {
- ll = ll->lv_used_next;
}
}
+ // PASS 2: free the items themselves.
+ dict_T *dd_next;
+ for (dict_T *dd = gc_first_dict; dd != NULL; dd = dd_next) {
+ dd_next = dd->dv_used_next;
+ if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
+ tv_dict_free_dict(dd);
+ }
+ }
+
+ list_T *ll_next;
+ for (list_T *ll = gc_first_list; ll != NULL; ll = ll_next) {
+ ll_next = ll->lv_used_next;
+ if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
+ && !tv_list_has_watchers(ll)) {
+ // Free the List and ordinary items it contains, but don't recurse
+ // into Lists and Dictionaries, they will be in the list of dicts
+ // or list of lists.
+ tv_list_free_list(ll);
+ }
+ }
+ tv_in_free_unref_items = false;
return did_free;
}
@@ -5889,14 +5313,10 @@ bool set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack)
// Mark each item in the hashtab. If the item contains a hashtab
// it is added to ht_stack, if it contains a list it is added to
// list_stack.
- int todo = (int)cur_ht->ht_used;
- for (hashitem_T *hi = cur_ht->ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- abort = abort || set_ref_in_item(&HI2DI(hi)->di_tv, copyID, &ht_stack,
- list_stack);
- }
- }
+ HASHTAB_ITER(cur_ht, hi, {
+ abort = abort || set_ref_in_item(
+ &TV_DICT_HI2DI(hi)->di_tv, copyID, &ht_stack, list_stack);
+ });
}
if (ht_stack == NULL) {
@@ -5928,15 +5348,16 @@ bool set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack)
list_T *cur_l = l;
for (;;) {
- if (!abort) {
- // Mark each item in the list. If the item contains a hashtab
- // it is added to ht_stack, if it contains a list it is added to
- // list_stack.
- for (listitem_T *li = cur_l->lv_first; !abort && li != NULL;
- li = li->li_next) {
- abort = set_ref_in_item(&li->li_tv, copyID, ht_stack, &list_stack);
+ // Mark each item in the list. If the item contains a hashtab
+ // it is added to ht_stack, if it contains a list it is added to
+ // list_stack.
+ TV_LIST_ITER(cur_l, li, {
+ if (abort) {
+ break;
}
- }
+ abort = set_ref_in_item(TV_LIST_ITEM_TV(li), copyID, ht_stack,
+ &list_stack);
+ });
if (list_stack == NULL) {
break;
@@ -5984,6 +5405,13 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
*ht_stack = newitem;
}
}
+
+ QUEUE *w = NULL;
+ DictWatcher *watcher = NULL;
+ QUEUE_FOREACH(w, &dd->watchers) {
+ watcher = tv_dict_watcher_node_data(w);
+ set_ref_in_callback(&watcher->callback, copyID, ht_stack, list_stack);
+ }
}
break;
}
@@ -6009,7 +5437,30 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
break;
}
+ case VAR_PARTIAL: {
+ partial_T *pt = tv->vval.v_partial;
+
+ // A partial does not have a copyID, because it cannot contain itself.
+ if (pt != NULL) {
+ abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID);
+ if (pt->pt_dict != NULL) {
+ typval_T dtv;
+
+ dtv.v_type = VAR_DICT;
+ dtv.vval.v_dict = pt->pt_dict;
+ abort = abort || set_ref_in_item(&dtv, copyID, ht_stack, list_stack);
+ }
+
+ for (int i = 0; i < pt->pt_argc; i++) {
+ abort = abort || set_ref_in_item(&pt->pt_argv[i], copyID,
+ ht_stack, list_stack);
+ }
+ }
+ break;
+ }
case VAR_FUNC:
+ abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
+ break;
case VAR_UNKNOWN:
case VAR_SPECIAL:
case VAR_FLOAT:
@@ -6021,6 +5472,29 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
return abort;
}
+/// Set "copyID" in all functions available by name.
+bool set_ref_in_functions(int copyID)
+{
+ int todo;
+ hashitem_T *hi = NULL;
+ bool abort = false;
+ ufunc_T *fp;
+
+ todo = (int)func_hashtab.ht_used;
+ for (hi = func_hashtab.ht_array; todo > 0 && !got_int; hi++) {
+ if (!HASHITEM_EMPTY(hi)) {
+ todo--;
+ fp = HI2UF(hi);
+ if (!func_name_refcount(fp->uf_name)) {
+ abort = abort || set_ref_in_func(NULL, fp, copyID);
+ }
+ }
+ }
+ return abort;
+}
+
+
+
/// Mark all lists and dicts referenced in given mark
///
/// @returns true if setting references failed somehow.
@@ -6067,441 +5541,17 @@ static inline bool set_ref_dict(dict_T *dict, int copyID)
return false;
}
-/*
- * Allocate an empty header for a dictionary.
- */
-dict_T *dict_alloc(void) FUNC_ATTR_NONNULL_RET
-{
- dict_T *d = xmalloc(sizeof(dict_T));
-
- /* Add the dict to the list of dicts for garbage collection. */
- if (first_dict != NULL)
- first_dict->dv_used_prev = d;
- d->dv_used_next = first_dict;
- d->dv_used_prev = NULL;
- first_dict = d;
-
- hash_init(&d->dv_hashtab);
- d->dv_lock = 0;
- d->dv_scope = 0;
- d->dv_refcount = 0;
- d->dv_copyID = 0;
- QUEUE_INIT(&d->watchers);
-
- return d;
-}
-
-/*
- * Allocate an empty dict for a return value.
- */
-static void rettv_dict_alloc(typval_T *rettv)
-{
- dict_T *d = dict_alloc();
-
- rettv->vval.v_dict = d;
- rettv->v_type = VAR_DICT;
- ++d->dv_refcount;
-}
-
-/// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary.
-///
-/// @param d The Dictionary to clear
-void dict_clear(dict_T *d)
- FUNC_ATTR_NONNULL_ALL
-{
- hash_lock(&d->dv_hashtab);
- assert(d->dv_hashtab.ht_locked > 0);
-
- size_t todo = d->dv_hashtab.ht_used;
- for (hashitem_T *hi = d->dv_hashtab.ht_array; todo > 0; hi++) {
- if (!HASHITEM_EMPTY(hi)) {
- dictitem_free(HI2DI(hi));
- hash_remove(&d->dv_hashtab, hi);
- todo--;
- }
- }
-
- hash_unlock(&d->dv_hashtab);
-}
-
-
-/*
- * Unreference a Dictionary: decrement the reference count and free it when it
- * becomes zero.
- */
-void dict_unref(dict_T *d)
+static bool set_ref_in_funccal(funccall_T *fc, int copyID)
{
- if (d != NULL && --d->dv_refcount <= 0)
- dict_free(d, TRUE);
-}
-
-/*
- * Free a Dictionary, including all items it contains.
- * Ignores the reference count.
- */
-void
-dict_free (
- dict_T *d,
- int recurse /* Free Lists and Dictionaries recursively. */
-)
-{
- int todo;
- hashitem_T *hi;
- dictitem_T *di;
-
- /* Remove the dict from the list of dicts for garbage collection. */
- if (d->dv_used_prev == NULL)
- first_dict = d->dv_used_next;
- else
- d->dv_used_prev->dv_used_next = d->dv_used_next;
- if (d->dv_used_next != NULL)
- d->dv_used_next->dv_used_prev = d->dv_used_prev;
-
- /* Lock the hashtab, we don't want it to resize while freeing items. */
- hash_lock(&d->dv_hashtab);
- assert(d->dv_hashtab.ht_locked > 0);
- todo = (int)d->dv_hashtab.ht_used;
- for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- /* Remove the item before deleting it, just in case there is
- * something recursive causing trouble. */
- di = HI2DI(hi);
- hash_remove(&d->dv_hashtab, hi);
- if (recurse || (di->di_tv.v_type != VAR_LIST
- && di->di_tv.v_type != VAR_DICT))
- clear_tv(&di->di_tv);
- xfree(di);
- --todo;
- }
- }
-
- while (!QUEUE_EMPTY(&d->watchers)) {
- QUEUE *w = QUEUE_HEAD(&d->watchers);
- DictWatcher *watcher = dictwatcher_node_data(w);
- dictwatcher_free(watcher);
- QUEUE_REMOVE(w);
- }
-
- hash_clear(&d->dv_hashtab);
- xfree(d);
-}
-
-/*
- * Allocate a Dictionary item.
- * The "key" is copied to the new item.
- * Note that the value of the item "di_tv" still needs to be initialized!
- */
-dictitem_T *dictitem_alloc(char_u *key) FUNC_ATTR_NONNULL_RET
-{
- dictitem_T *di = xmalloc(sizeof(dictitem_T) + STRLEN(key));
-#ifndef __clang_analyzer__
- STRCPY(di->di_key, key);
-#endif
- di->di_flags = DI_FLAGS_ALLOC;
- return di;
-}
-
-/*
- * Make a copy of a Dictionary item.
- */
-static dictitem_T *dictitem_copy(dictitem_T *org) FUNC_ATTR_NONNULL_RET
-{
- dictitem_T *di = xmalloc(sizeof(dictitem_T) + STRLEN(org->di_key));
-
- STRCPY(di->di_key, org->di_key);
- di->di_flags = DI_FLAGS_ALLOC;
- copy_tv(&org->di_tv, &di->di_tv);
-
- return di;
-}
-
-/*
- * Remove item "item" from Dictionary "dict" and free it.
- */
-static void dictitem_remove(dict_T *dict, dictitem_T *item)
-{
- hashitem_T *hi;
-
- hi = hash_find(&dict->dv_hashtab, item->di_key);
- if (HASHITEM_EMPTY(hi)) {
- EMSG2(_(e_intern2), "dictitem_remove()");
- } else {
- hash_remove(&dict->dv_hashtab, hi);
- }
- dictitem_free(item);
-}
-
-/*
- * Free a dict item. Also clears the value.
- */
-void dictitem_free(dictitem_T *item)
-{
- clear_tv(&item->di_tv);
- if (item->di_flags & DI_FLAGS_ALLOC) {
- xfree(item);
- }
-}
-
-/// Make a copy of dictionary
-///
-/// @param[in] conv If non-NULL, then all internal strings will be converted.
-/// @param[in] orig Original dictionary to copy.
-/// @param[in] deep If false, then shallow copy will be done.
-/// @param[in] copyID See var_item_copy().
-///
-/// @return Copied dictionary. May be NULL in case original dictionary is NULL
-/// or some failure happens. The refcount of the new dictionary is set
-/// to 1.
-static dict_T *dict_copy(const vimconv_T *const conv,
- dict_T *const orig,
- const bool deep,
- const int copyID)
-{
- dictitem_T *di;
- int todo;
- hashitem_T *hi;
-
- if (orig == NULL)
- return NULL;
-
- dict_T *copy = dict_alloc();
- {
- if (copyID != 0) {
- orig->dv_copyID = copyID;
- orig->dv_copydict = copy;
- }
- todo = (int)orig->dv_hashtab.ht_used;
- for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
-
- if (conv == NULL || conv->vc_type == CONV_NONE) {
- di = dictitem_alloc(hi->hi_key);
- } else {
- char *const key = (char *) string_convert((vimconv_T *) conv,
- hi->hi_key, NULL);
- if (key == NULL) {
- di = dictitem_alloc(hi->hi_key);
- } else {
- di = dictitem_alloc((char_u *) key);
- xfree(key);
- }
- }
- if (deep) {
- if (var_item_copy(conv, &HI2DI(hi)->di_tv, &di->di_tv, deep,
- copyID) == FAIL) {
- xfree(di);
- break;
- }
- } else
- copy_tv(&HI2DI(hi)->di_tv, &di->di_tv);
- if (dict_add(copy, di) == FAIL) {
- dictitem_free(di);
- break;
- }
- }
- }
-
- ++copy->dv_refcount;
- if (todo > 0) {
- dict_unref(copy);
- copy = NULL;
- }
- }
-
- return copy;
-}
-
-/*
- * Add item "item" to Dictionary "d".
- * Returns FAIL when key already exists.
- */
-int dict_add(dict_T *d, dictitem_T *item)
-{
- return hash_add(&d->dv_hashtab, item->di_key);
-}
-
-/*
- * Add a number or string entry to dictionary "d".
- * When "str" is NULL use number "nr", otherwise use "str".
- * Returns FAIL when key already exists.
- */
-int dict_add_nr_str(dict_T *d, char *key, long nr, char_u *str)
-{
- dictitem_T *item;
-
- item = dictitem_alloc((char_u *)key);
- item->di_tv.v_lock = 0;
- if (str == NULL) {
- item->di_tv.v_type = VAR_NUMBER;
- item->di_tv.vval.v_number = nr;
- } else {
- item->di_tv.v_type = VAR_STRING;
- item->di_tv.vval.v_string = vim_strsave(str);
- }
- if (dict_add(d, item) == FAIL) {
- dictitem_free(item);
- return FAIL;
- }
- return OK;
-}
-
-/*
- * Add a list entry to dictionary "d".
- * Returns FAIL when key already exists.
- */
-int dict_add_list(dict_T *d, char *key, list_T *list)
-{
- dictitem_T *item = dictitem_alloc((char_u *)key);
-
- item->di_tv.v_lock = 0;
- item->di_tv.v_type = VAR_LIST;
- item->di_tv.vval.v_list = list;
- if (dict_add(d, item) == FAIL) {
- dictitem_free(item);
- return FAIL;
- }
- ++list->lv_refcount;
- return OK;
-}
-
-/// Set all existing keys in "dict" as read-only.
-///
-/// This does not protect against adding new keys to the Dictionary.
-///
-/// @param dict The dict whose keys should be frozen
-void dict_set_keys_readonly(dict_T *dict)
- FUNC_ATTR_NONNULL_ALL
-{
- size_t todo = dict->dv_hashtab.ht_used;
- for (hashitem_T *hi = dict->dv_hashtab.ht_array; todo > 0 ; hi++) {
- if (HASHITEM_EMPTY(hi)) {
- continue;
- }
- todo--;
- HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
- }
-}
-
-/*
- * Get the number of items in a Dictionary.
- */
-static long dict_len(dict_T *d)
-{
- if (d == NULL)
- return 0L;
- return (long)d->dv_hashtab.ht_used;
-}
-
-/*
- * Find item "key[len]" in Dictionary "d".
- * If "len" is negative use strlen(key).
- * Returns NULL when not found.
- */
-dictitem_T *dict_find(dict_T *d, char_u *key, int len)
-{
-#define AKEYLEN 200
- char_u buf[AKEYLEN];
- char_u *akey;
- char_u *tofree = NULL;
- hashitem_T *hi;
-
- if (len < 0)
- akey = key;
- else if (len >= AKEYLEN) {
- tofree = akey = vim_strnsave(key, len);
- } else {
- /* Avoid a malloc/free by using buf[]. */
- STRLCPY(buf, key, len + 1);
- akey = buf;
- }
-
- hi = hash_find(&d->dv_hashtab, akey);
- xfree(tofree);
- if (HASHITEM_EMPTY(hi))
- return NULL;
- return HI2DI(hi);
-}
-
-/// Get a function from a dictionary
-/// @param[out] result The address where a pointer to the wanted callback
-/// will be left.
-/// @return true/false on success/failure.
-static bool get_dict_callback(dict_T *d, char *key, ufunc_T **result)
-{
- dictitem_T *di = dict_find(d, (uint8_t *)key, -1);
-
- if (di == NULL) {
- *result = NULL;
- return true;
- }
-
- if (di->di_tv.v_type != VAR_FUNC && di->di_tv.v_type != VAR_STRING) {
- EMSG(_("Argument is not a function or function name"));
- *result = NULL;
- return false;
- }
-
- if ((*result = find_ufunc(di->di_tv.vval.v_string)) == NULL) {
- return false;
- }
-
- (*result)->uf_refcount++;
- return true;
-}
-
-static ufunc_T *find_ufunc(uint8_t *name)
-{
- uint8_t *n = name;
- ufunc_T *rv = NULL;
- if (*n > '9' || *n < '0') {
- if ((n = trans_function_name(&n, false, TFN_INT|TFN_QUIET, NULL))) {
- rv = find_func(n);
- xfree(n);
- }
- } else {
- // dict function, name is already translated
- rv = find_func(n);
- }
-
- if (!rv) {
- EMSG2(_("Function %s doesn't exist"), name);
- return NULL;
- }
-
- return rv;
-}
-
-/*
- * Get a string item from a dictionary.
- * When "save" is TRUE allocate memory for it.
- * Returns NULL if the entry doesn't exist.
- */
-char_u *get_dict_string(dict_T *d, char_u *key, int save)
-{
- dictitem_T *di;
- char_u *s;
+ bool abort = false;
- di = dict_find(d, key, -1);
- if (di == NULL)
- return NULL;
- s = get_tv_string(&di->di_tv);
- if (save) {
- s = vim_strsave(s);
+ if (fc->fc_copyID != copyID) {
+ fc->fc_copyID = copyID;
+ abort = abort || set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID, NULL);
+ abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL);
+ abort = abort || set_ref_in_func(NULL, fc->func, copyID);
}
- return s;
-}
-
-/*
- * Get a number item from a dictionary.
- * Returns 0 if the entry doesn't exist.
- */
-long get_dict_number(dict_T *d, char_u *key)
-{
- dictitem_T *di = dict_find(d, key, -1);
- if (di == NULL)
- return 0;
- return get_tv_number(&di->di_tv);
+ return abort;
}
/*
@@ -6516,7 +5566,7 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
char_u *key = NULL;
dictitem_T *item;
char_u *start = skipwhite(*arg + 1);
- char_u buf[NUMBUFLEN];
+ char buf[NUMBUFLEN];
/*
* First check if it's not a curly-braces thing: {expr}.
@@ -6533,7 +5583,7 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
}
if (evaluate) {
- d = dict_alloc();
+ d = tv_dict_alloc();
}
tvkey.v_type = VAR_UNKNOWN;
tv.v_type = VAR_UNKNOWN;
@@ -6544,40 +5594,39 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
goto failret;
if (**arg != ':') {
EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg);
- clear_tv(&tvkey);
+ tv_clear(&tvkey);
goto failret;
}
if (evaluate) {
- key = get_tv_string_buf_chk(&tvkey, buf);
- if (key == NULL || *key == NUL) {
- /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
- if (key != NULL)
- EMSG(_(e_emptykey));
- clear_tv(&tvkey);
+ key = (char_u *)tv_get_string_buf_chk(&tvkey, buf);
+ if (key == NULL) {
+ // "key" is NULL when tv_get_string_buf_chk() gave an errmsg
+ tv_clear(&tvkey);
goto failret;
}
}
*arg = skipwhite(*arg + 1);
- if (eval1(arg, &tv, evaluate) == FAIL) { /* recursive! */
- if (evaluate)
- clear_tv(&tvkey);
+ if (eval1(arg, &tv, evaluate) == FAIL) { // Recursive!
+ if (evaluate) {
+ tv_clear(&tvkey);
+ }
goto failret;
}
if (evaluate) {
- item = dict_find(d, key, -1);
+ item = tv_dict_find(d, (const char *)key, -1);
if (item != NULL) {
EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key);
- clear_tv(&tvkey);
- clear_tv(&tv);
+ tv_clear(&tvkey);
+ tv_clear(&tv);
goto failret;
}
- item = dictitem_alloc(key);
- clear_tv(&tvkey);
+ item = tv_dict_item_alloc((const char *)key);
+ tv_clear(&tvkey);
item->di_tv = tv;
item->di_tv.v_lock = 0;
- if (dict_add(d, item) == FAIL) {
- dictitem_free(item);
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
}
}
@@ -6593,21 +5642,238 @@ static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate)
if (**arg != '}') {
EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg);
failret:
- if (evaluate)
- dict_free(d, TRUE);
+ if (evaluate) {
+ tv_dict_free(d);
+ }
return FAIL;
}
*arg = skipwhite(*arg + 1);
if (evaluate) {
- rettv->v_type = VAR_DICT;
- rettv->vval.v_dict = d;
- ++d->dv_refcount;
+ tv_dict_set_ret(rettv, d);
}
return OK;
}
+/// Get function arguments.
+static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs,
+ int *varargs, bool skip)
+{
+ bool mustend = false;
+ char_u *arg = *argp;
+ char_u *p = arg;
+ int c;
+ int i;
+
+ if (newargs != NULL) {
+ ga_init(newargs, (int)sizeof(char_u *), 3);
+ }
+
+ if (varargs != NULL) {
+ *varargs = false;
+ }
+
+ // Isolate the arguments: "arg1, arg2, ...)"
+ while (*p != endchar) {
+ if (p[0] == '.' && p[1] == '.' && p[2] == '.') {
+ if (varargs != NULL) {
+ *varargs = true;
+ }
+ p += 3;
+ mustend = true;
+ } else {
+ arg = p;
+ while (ASCII_ISALNUM(*p) || *p == '_') {
+ p++;
+ }
+ if (arg == p || isdigit(*arg)
+ || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
+ || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) {
+ if (!skip) {
+ EMSG2(_("E125: Illegal argument: %s"), arg);
+ }
+ break;
+ }
+ if (newargs != NULL) {
+ ga_grow(newargs, 1);
+ c = *p;
+ *p = NUL;
+ arg = vim_strsave(arg);
+
+ // Check for duplicate argument name.
+ for (i = 0; i < newargs->ga_len; i++) {
+ if (STRCMP(((char_u **)(newargs->ga_data))[i], arg) == 0) {
+ EMSG2(_("E853: Duplicate argument name: %s"), arg);
+ xfree(arg);
+ goto err_ret;
+ }
+ }
+ ((char_u **)(newargs->ga_data))[newargs->ga_len] = arg;
+ newargs->ga_len++;
+
+ *p = c;
+ }
+ if (*p == ',') {
+ p++;
+ } else {
+ mustend = true;
+ }
+ }
+ p = skipwhite(p);
+ if (mustend && *p != endchar) {
+ if (!skip) {
+ EMSG2(_(e_invarg2), *argp);
+ }
+ break;
+ }
+ }
+ if (*p != endchar) {
+ goto err_ret;
+ }
+ p++; // skip "endchar"
+
+ *argp = p;
+ return OK;
+
+err_ret:
+ if (newargs != NULL) {
+ ga_clear_strings(newargs);
+ }
+ return FAIL;
+}
+
+/// Register function "fp" as using "current_funccal" as its scope.
+static void register_closure(ufunc_T *fp)
+{
+ if (fp->uf_scoped == current_funccal) {
+ // no change
+ return;
+ }
+ funccal_unref(fp->uf_scoped, fp, false);
+ fp->uf_scoped = current_funccal;
+ current_funccal->fc_refcount++;
+ ga_grow(&current_funccal->fc_funcs, 1);
+ ((ufunc_T **)current_funccal->fc_funcs.ga_data)
+ [current_funccal->fc_funcs.ga_len++] = fp;
+}
+
+/// Parse a lambda expression and get a Funcref from "*arg".
+///
+/// @return OK or FAIL. Returns NOTDONE for dict or {expr}.
+static int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
+{
+ garray_T newargs = GA_EMPTY_INIT_VALUE;
+ garray_T *pnewargs;
+ ufunc_T *fp = NULL;
+ int varargs;
+ int ret;
+ char_u *start = skipwhite(*arg + 1);
+ char_u *s, *e;
+ static int lambda_no = 0;
+ int *old_eval_lavars = eval_lavars_used;
+ int eval_lavars = false;
+
+ // First, check if this is a lambda expression. "->" must exists.
+ ret = get_function_args(&start, '-', NULL, NULL, true);
+ if (ret == FAIL || *start != '>') {
+ return NOTDONE;
+ }
+
+ // Parse the arguments again.
+ if (evaluate) {
+ pnewargs = &newargs;
+ } else {
+ pnewargs = NULL;
+ }
+ *arg = skipwhite(*arg + 1);
+ ret = get_function_args(arg, '-', pnewargs, &varargs, false);
+ if (ret == FAIL || **arg != '>') {
+ goto errret;
+ }
+
+ // Set up a flag for checking local variables and arguments.
+ if (evaluate) {
+ eval_lavars_used = &eval_lavars;
+ }
+
+ // Get the start and the end of the expression.
+ *arg = skipwhite(*arg + 1);
+ s = *arg;
+ ret = skip_expr(arg);
+ if (ret == FAIL) {
+ goto errret;
+ }
+ e = *arg;
+ *arg = skipwhite(*arg);
+ if (**arg != '}') {
+ goto errret;
+ }
+ (*arg)++;
+
+ if (evaluate) {
+ int len, flags = 0;
+ char_u *p;
+ char_u name[20];
+ partial_T *pt;
+ garray_T newlines;
+
+ lambda_no++;
+ snprintf((char *)name, sizeof(name), "<lambda>%d", lambda_no);
+
+ fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
+ pt = xcalloc(1, sizeof(partial_T));
+
+ ga_init(&newlines, (int)sizeof(char_u *), 1);
+ ga_grow(&newlines, 1);
+
+ // Add "return " before the expression.
+ len = 7 + e - s + 1;
+ p = (char_u *)xmalloc(len);
+ ((char_u **)(newlines.ga_data))[newlines.ga_len++] = p;
+ STRCPY(p, "return ");
+ STRLCPY(p + 7, s, e - s + 1);
+
+ fp->uf_refcount = 1;
+ STRCPY(fp->uf_name, name);
+ hash_add(&func_hashtab, UF2HIKEY(fp));
+ fp->uf_args = newargs;
+ fp->uf_lines = newlines;
+ if (current_funccal != NULL && eval_lavars) {
+ flags |= FC_CLOSURE;
+ register_closure(fp);
+ } else {
+ fp->uf_scoped = NULL;
+ }
+
+ fp->uf_tml_count = NULL;
+ fp->uf_tml_total = NULL;
+ fp->uf_tml_self = NULL;
+ fp->uf_profiling = false;
+ if (prof_def_func()) {
+ func_do_profile(fp);
+ }
+ fp->uf_varargs = true;
+ fp->uf_flags = flags;
+ fp->uf_calls = 0;
+ fp->uf_script_ID = current_SID;
+
+ pt->pt_func = fp;
+ pt->pt_refcount = 1;
+ rettv->vval.v_partial = pt;
+ rettv->v_type = VAR_PARTIAL;
+ }
+
+ eval_lavars_used = old_eval_lavars;
+ return OK;
+
+errret:
+ ga_clear_strings(&newargs);
+ xfree(fp);
+ eval_lavars_used = old_eval_lavars;
+ return FAIL;
+}
+
/// Convert the string to a floating point number
///
/// This uses strtod(). setlocale(LC_NUMERIC, "C") has been used earlier to
@@ -6622,6 +5888,19 @@ size_t string2float(const char *const text, float_T *const ret_value)
{
char *s = NULL;
+ // MS-Windows does not deal with "inf" and "nan" properly
+ if (STRNICMP(text, "inf", 3) == 0) {
+ *ret_value = INFINITY;
+ return 3;
+ }
+ if (STRNICMP(text, "-inf", 3) == 0) {
+ *ret_value = -INFINITY;
+ return 4;
+ }
+ if (STRNICMP(text, "nan", 3) == 0) {
+ *ret_value = NAN;
+ return 3;
+ }
*ret_value = strtod(text, &s);
return (size_t) (s - text);
}
@@ -6642,7 +5921,7 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
++*arg;
name = *arg;
- len = get_env_len(arg);
+ len = get_env_len((const char_u **)arg);
if (evaluate) {
if (len == 0) {
@@ -6670,324 +5949,17 @@ static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate)
return OK;
}
-/*
- * Array with names and number of arguments of all internal functions
- * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH!
- */
-static struct fst {
- char *f_name; /* function name */
- char f_min_argc; /* minimal number of arguments */
- char f_max_argc; /* maximal number of arguments */
- void (*f_func)(typval_T *args, typval_T *rvar);
- /* implementation of function */
-} functions[] =
-{
- { "abs", 1, 1, f_abs },
- { "acos", 1, 1, f_acos }, // WJMc
- { "add", 2, 2, f_add },
- { "and", 2, 2, f_and },
- { "api_info", 0, 0, f_api_info },
- { "append", 2, 2, f_append },
- { "argc", 0, 0, f_argc },
- { "argidx", 0, 0, f_argidx },
- { "arglistid", 0, 2, f_arglistid },
- { "argv", 0, 1, f_argv },
- { "asin", 1, 1, f_asin }, // WJMc
- { "assert_equal", 2, 3, f_assert_equal },
- { "assert_exception", 1, 2, f_assert_exception },
- { "assert_fails", 1, 2, f_assert_fails },
- { "assert_false", 1, 2, f_assert_false },
- { "assert_true", 1, 2, f_assert_true },
- { "atan", 1, 1, f_atan },
- { "atan2", 2, 2, f_atan2 },
- { "browse", 4, 4, f_browse },
- { "browsedir", 2, 2, f_browsedir },
- { "bufexists", 1, 1, f_bufexists },
- { "buffer_exists", 1, 1, f_bufexists }, // obsolete
- { "buffer_name", 1, 1, f_bufname }, // obsolete
- { "buffer_number", 1, 1, f_bufnr }, // obsolete
- { "buflisted", 1, 1, f_buflisted },
- { "bufloaded", 1, 1, f_bufloaded },
- { "bufname", 1, 1, f_bufname },
- { "bufnr", 1, 2, f_bufnr },
- { "bufwinnr", 1, 1, f_bufwinnr },
- { "byte2line", 1, 1, f_byte2line },
- { "byteidx", 2, 2, f_byteidx },
- { "byteidxcomp", 2, 2, f_byteidxcomp },
- { "call", 2, 3, f_call },
- { "capture", 1, 1, f_capture },
- { "ceil", 1, 1, f_ceil },
- { "changenr", 0, 0, f_changenr },
- { "char2nr", 1, 2, f_char2nr },
- { "cindent", 1, 1, f_cindent },
- { "clearmatches", 0, 0, f_clearmatches },
- { "col", 1, 1, f_col },
- { "complete", 2, 2, f_complete },
- { "complete_add", 1, 1, f_complete_add },
- { "complete_check", 0, 0, f_complete_check },
- { "confirm", 1, 4, f_confirm },
- { "copy", 1, 1, f_copy },
- { "cos", 1, 1, f_cos },
- { "cosh", 1, 1, f_cosh },
- { "count", 2, 4, f_count },
- { "cscope_connection", 0, 3, f_cscope_connection },
- { "cursor", 1, 3, f_cursor },
- { "deepcopy", 1, 2, f_deepcopy },
- { "delete", 1, 2, f_delete },
- { "dictwatcheradd", 3, 3, f_dictwatcheradd },
- { "dictwatcherdel", 3, 3, f_dictwatcherdel },
- { "did_filetype", 0, 0, f_did_filetype },
- { "diff_filler", 1, 1, f_diff_filler },
- { "diff_hlID", 2, 2, f_diff_hlID },
- { "empty", 1, 1, f_empty },
- { "escape", 2, 2, f_escape },
- { "eval", 1, 1, f_eval },
- { "eventhandler", 0, 0, f_eventhandler },
- { "executable", 1, 1, f_executable },
- { "exepath", 1, 1, f_exepath },
- { "exists", 1, 1, f_exists },
- { "exp", 1, 1, f_exp },
- { "expand", 1, 3, f_expand },
- { "extend", 2, 3, f_extend },
- { "feedkeys", 1, 2, f_feedkeys },
- { "file_readable", 1, 1, f_filereadable }, // obsolete
- { "filereadable", 1, 1, f_filereadable },
- { "filewritable", 1, 1, f_filewritable },
- { "filter", 2, 2, f_filter },
- { "finddir", 1, 3, f_finddir },
- { "findfile", 1, 3, f_findfile },
- { "float2nr", 1, 1, f_float2nr },
- { "floor", 1, 1, f_floor },
- { "fmod", 2, 2, f_fmod },
- { "fnameescape", 1, 1, f_fnameescape },
- { "fnamemodify", 2, 2, f_fnamemodify },
- { "foldclosed", 1, 1, f_foldclosed },
- { "foldclosedend", 1, 1, f_foldclosedend },
- { "foldlevel", 1, 1, f_foldlevel },
- { "foldtext", 0, 0, f_foldtext },
- { "foldtextresult", 1, 1, f_foldtextresult },
- { "foreground", 0, 0, f_foreground },
- { "function", 1, 1, f_function },
- { "garbagecollect", 0, 1, f_garbagecollect },
- { "get", 2, 3, f_get },
- { "getbufline", 2, 3, f_getbufline },
- { "getbufvar", 2, 3, f_getbufvar },
- { "getchar", 0, 1, f_getchar },
- { "getcharmod", 0, 0, f_getcharmod },
- { "getcharsearch", 0, 0, f_getcharsearch },
- { "getcmdline", 0, 0, f_getcmdline },
- { "getcmdpos", 0, 0, f_getcmdpos },
- { "getcmdtype", 0, 0, f_getcmdtype },
- { "getcmdwintype", 0, 0, f_getcmdwintype },
- { "getcurpos", 0, 0, f_getcurpos },
- { "getcwd", 0, 2, f_getcwd },
- { "getfontname", 0, 1, f_getfontname },
- { "getfperm", 1, 1, f_getfperm },
- { "getfsize", 1, 1, f_getfsize },
- { "getftime", 1, 1, f_getftime },
- { "getftype", 1, 1, f_getftype },
- { "getline", 1, 2, f_getline },
- { "getloclist", 1, 1, f_getqflist },
- { "getmatches", 0, 0, f_getmatches },
- { "getpid", 0, 0, f_getpid },
- { "getpos", 1, 1, f_getpos },
- { "getqflist", 0, 0, f_getqflist },
- { "getreg", 0, 3, f_getreg },
- { "getregtype", 0, 1, f_getregtype },
- { "gettabvar", 2, 3, f_gettabvar },
- { "gettabwinvar", 3, 4, f_gettabwinvar },
- { "getwinposx", 0, 0, f_getwinposx },
- { "getwinposy", 0, 0, f_getwinposy },
- { "getwinvar", 2, 3, f_getwinvar },
- { "glob", 1, 4, f_glob },
- { "glob2regpat", 1, 1, f_glob2regpat },
- { "globpath", 2, 5, f_globpath },
- { "has", 1, 1, f_has },
- { "has_key", 2, 2, f_has_key },
- { "haslocaldir", 0, 2, f_haslocaldir },
- { "hasmapto", 1, 3, f_hasmapto },
- { "highlightID", 1, 1, f_hlID }, // obsolete
- { "highlight_exists", 1, 1, f_hlexists }, // obsolete
- { "histadd", 2, 2, f_histadd },
- { "histdel", 1, 2, f_histdel },
- { "histget", 1, 2, f_histget },
- { "histnr", 1, 1, f_histnr },
- { "hlID", 1, 1, f_hlID },
- { "hlexists", 1, 1, f_hlexists },
- { "hostname", 0, 0, f_hostname },
- { "iconv", 3, 3, f_iconv },
- { "indent", 1, 1, f_indent },
- { "index", 2, 4, f_index },
- { "input", 1, 3, f_input },
- { "inputdialog", 1, 3, f_inputdialog },
- { "inputlist", 1, 1, f_inputlist },
- { "inputrestore", 0, 0, f_inputrestore },
- { "inputsave", 0, 0, f_inputsave },
- { "inputsecret", 1, 2, f_inputsecret },
- { "insert", 2, 3, f_insert },
- { "invert", 1, 1, f_invert },
- { "isdirectory", 1, 1, f_isdirectory },
- { "islocked", 1, 1, f_islocked },
- { "items", 1, 1, f_items },
- { "jobclose", 1, 2, f_jobclose },
- { "jobpid", 1, 1, f_jobpid },
- { "jobresize", 3, 3, f_jobresize },
- { "jobsend", 2, 2, f_jobsend },
- { "jobstart", 1, 2, f_jobstart },
- { "jobstop", 1, 1, f_jobstop },
- { "jobwait", 1, 2, f_jobwait },
- { "join", 1, 2, f_join },
- { "json_decode", 1, 1, f_json_decode },
- { "json_encode", 1, 1, f_json_encode },
- { "keys", 1, 1, f_keys },
- { "last_buffer_nr", 0, 0, f_last_buffer_nr }, // obsolete
- { "len", 1, 1, f_len },
- { "libcall", 3, 3, f_libcall },
- { "libcallnr", 3, 3, f_libcallnr },
- { "line", 1, 1, f_line },
- { "line2byte", 1, 1, f_line2byte },
- { "lispindent", 1, 1, f_lispindent },
- { "localtime", 0, 0, f_localtime },
- { "log", 1, 1, f_log },
- { "log10", 1, 1, f_log10 },
- { "map", 2, 2, f_map },
- { "maparg", 1, 4, f_maparg },
- { "mapcheck", 1, 3, f_mapcheck },
- { "match", 2, 4, f_match },
- { "matchadd", 2, 5, f_matchadd },
- { "matchaddpos", 2, 5, f_matchaddpos },
- { "matcharg", 1, 1, f_matcharg },
- { "matchdelete", 1, 1, f_matchdelete },
- { "matchend", 2, 4, f_matchend },
- { "matchlist", 2, 4, f_matchlist },
- { "matchstr", 2, 4, f_matchstr },
- { "max", 1, 1, f_max },
- { "min", 1, 1, f_min },
- { "mkdir", 1, 3, f_mkdir },
- { "mode", 0, 1, f_mode },
- { "msgpackdump", 1, 1, f_msgpackdump },
- { "msgpackparse", 1, 1, f_msgpackparse },
- { "nextnonblank", 1, 1, f_nextnonblank },
- { "nr2char", 1, 2, f_nr2char },
- { "or", 2, 2, f_or },
- { "pathshorten", 1, 1, f_pathshorten },
- { "pow", 2, 2, f_pow },
- { "prevnonblank", 1, 1, f_prevnonblank },
- { "printf", 2, MAX_FUNC_ARGS, f_printf },
- { "pumvisible", 0, 0, f_pumvisible },
- { "py3eval", 1, 1, f_py3eval },
- { "pyeval", 1, 1, f_pyeval },
- { "range", 1, 3, f_range },
- { "readfile", 1, 3, f_readfile },
- { "reltime", 0, 2, f_reltime },
- { "reltimefloat", 1, 1, f_reltimefloat },
- { "reltimestr", 1, 1, f_reltimestr },
- { "remove", 2, 3, f_remove },
- { "rename", 2, 2, f_rename },
- { "repeat", 2, 2, f_repeat },
- { "resolve", 1, 1, f_resolve },
- { "reverse", 1, 1, f_reverse },
- { "round", 1, 1, f_round },
- { "rpcnotify", 2, MAX_FUNC_ARGS, f_rpcnotify },
- { "rpcrequest", 2, MAX_FUNC_ARGS, f_rpcrequest },
- { "rpcstart", 1, 2, f_rpcstart },
- { "rpcstop", 1, 1, f_rpcstop },
- { "screenattr", 2, 2, f_screenattr },
- { "screenchar", 2, 2, f_screenchar },
- { "screencol", 0, 0, f_screencol },
- { "screenrow", 0, 0, f_screenrow },
- { "search", 1, 4, f_search },
- { "searchdecl", 1, 3, f_searchdecl },
- { "searchpair", 3, 7, f_searchpair },
- { "searchpairpos", 3, 7, f_searchpairpos },
- { "searchpos", 1, 4, f_searchpos },
- { "serverlist", 0, 0, f_serverlist },
- { "serverstart", 0, 1, f_serverstart },
- { "serverstop", 1, 1, f_serverstop },
- { "setbufvar", 3, 3, f_setbufvar },
- { "setcharsearch", 1, 1, f_setcharsearch },
- { "setcmdpos", 1, 1, f_setcmdpos },
- { "setfperm", 2, 2, f_setfperm },
- { "setline", 2, 2, f_setline },
- { "setloclist", 2, 4, f_setloclist },
- { "setmatches", 1, 1, f_setmatches },
- { "setpos", 2, 2, f_setpos },
- { "setqflist", 1, 3, f_setqflist },
- { "setreg", 2, 3, f_setreg },
- { "settabvar", 3, 3, f_settabvar },
- { "settabwinvar", 4, 4, f_settabwinvar },
- { "setwinvar", 3, 3, f_setwinvar },
- { "sha256", 1, 1, f_sha256 },
- { "shellescape", 1, 2, f_shellescape },
- { "shiftwidth", 0, 0, f_shiftwidth },
- { "simplify", 1, 1, f_simplify },
- { "sin", 1, 1, f_sin },
- { "sinh", 1, 1, f_sinh },
- { "sort", 1, 3, f_sort },
- { "soundfold", 1, 1, f_soundfold },
- { "spellbadword", 0, 1, f_spellbadword },
- { "spellsuggest", 1, 3, f_spellsuggest },
- { "split", 1, 3, f_split },
- { "sqrt", 1, 1, f_sqrt },
- { "str2float", 1, 1, f_str2float },
- { "str2nr", 1, 2, f_str2nr },
- { "strchars", 1, 2, f_strchars },
- { "strdisplaywidth", 1, 2, f_strdisplaywidth },
- { "strftime", 1, 2, f_strftime },
- { "stridx", 2, 3, f_stridx },
- { "string", 1, 1, f_string },
- { "strlen", 1, 1, f_strlen },
- { "strpart", 2, 3, f_strpart },
- { "strridx", 2, 3, f_strridx },
- { "strtrans", 1, 1, f_strtrans },
- { "strwidth", 1, 1, f_strwidth },
- { "submatch", 1, 2, f_submatch },
- { "substitute", 4, 4, f_substitute },
- { "synID", 3, 3, f_synID },
- { "synIDattr", 2, 3, f_synIDattr },
- { "synIDtrans", 1, 1, f_synIDtrans },
- { "synconcealed", 2, 2, f_synconcealed },
- { "synstack", 2, 2, f_synstack },
- { "system", 1, 2, f_system },
- { "systemlist", 1, 3, f_systemlist },
- { "tabpagebuflist", 0, 1, f_tabpagebuflist },
- { "tabpagenr", 0, 1, f_tabpagenr },
- { "tabpagewinnr", 1, 2, f_tabpagewinnr },
- { "tagfiles", 0, 0, f_tagfiles },
- { "taglist", 1, 1, f_taglist },
- { "tan", 1, 1, f_tan },
- { "tanh", 1, 1, f_tanh },
- { "tempname", 0, 0, f_tempname },
- { "termopen", 1, 2, f_termopen },
- { "test", 1, 1, f_test },
- { "timer_start", 2, 3, f_timer_start },
- { "timer_stop", 1, 1, f_timer_stop },
- { "tolower", 1, 1, f_tolower },
- { "toupper", 1, 1, f_toupper },
- { "tr", 3, 3, f_tr },
- { "trunc", 1, 1, f_trunc },
- { "type", 1, 1, f_type },
- { "undofile", 1, 1, f_undofile },
- { "undotree", 0, 0, f_undotree },
- { "uniq", 1, 3, f_uniq },
- { "values", 1, 1, f_values },
- { "virtcol", 1, 1, f_virtcol },
- { "visualmode", 0, 1, f_visualmode },
- { "wildmenumode", 0, 0, f_wildmenumode },
- { "winbufnr", 1, 1, f_winbufnr },
- { "wincol", 0, 0, f_wincol },
- { "winheight", 1, 1, f_winheight },
- { "winline", 0, 0, f_winline },
- { "winnr", 0, 1, f_winnr },
- { "winrestcmd", 0, 0, f_winrestcmd },
- { "winrestview", 1, 1, f_winrestview },
- { "winsaveview", 0, 0, f_winsaveview },
- { "winwidth", 1, 1, f_winwidth },
- { "wordcount", 0, 0, f_wordcount },
- { "writefile", 2, 3, f_writefile },
- { "xor", 2, 2, f_xor },
-};
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+
+#ifdef _MSC_VER
+// This prevents MSVC from replacing the functions with intrinsics,
+// and causing errors when trying to get their addresses in funcs.generated.h
+#pragma function (ceil)
+#pragma function (floor)
+#endif
+# include "funcs.generated.h"
+#endif
/*
* Function given to ExpandGeneric() to obtain the list of internal
@@ -7005,15 +5977,25 @@ char_u *get_function_name(expand_T *xp, int idx)
if (name != NULL)
return name;
}
- if (++intidx < (int)ARRAY_SIZE(functions)) {
- STRCPY(IObuff, functions[intidx].f_name);
- STRCAT(IObuff, "(");
- if (functions[intidx].f_max_argc == 0)
- STRCAT(IObuff, ")");
- return IObuff;
+ while ( (size_t)++intidx < ARRAY_SIZE(functions)
+ && functions[intidx].name[0] == '\0') {
}
- return NULL;
+ if ((size_t)intidx >= ARRAY_SIZE(functions)) {
+ return NULL;
+ }
+
+ const char *const key = functions[intidx].name;
+ const size_t key_len = strlen(key);
+ memcpy(IObuff, key, key_len);
+ IObuff[key_len] = '(';
+ if (functions[intidx].max_argc == 0) {
+ IObuff[key_len + 1] = ')';
+ IObuff[key_len + 2] = NUL;
+ } else {
+ IObuff[key_len + 1] = NUL;
+ }
+ return IObuff;
}
/*
@@ -7035,77 +6017,85 @@ char_u *get_expr_name(expand_T *xp, int idx)
return get_user_var_name(xp, ++intidx);
}
-
-
-
-/*
- * Find internal function in table above.
- * Return index, or -1 if not found
- */
-static int
-find_internal_func (
- char_u *name /* name of the function */
-)
+/// Find internal function in hash functions
+///
+/// @param[in] name Name of the function.
+///
+/// Returns pointer to the function definition or NULL if not found.
+static const VimLFuncDef *find_internal_func(const char *const name)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE FUNC_ATTR_NONNULL_ALL
{
- int first = 0;
- int last = (int)ARRAY_SIZE(functions) - 1;
-
- /*
- * Find the function name in the table. Binary search.
- */
- while (first <= last) {
- int x = first + ((unsigned)(last - first)) / 2;
- int cmp = STRCMP(name, functions[x].f_name);
- if (cmp < 0)
- last = x - 1;
- else if (cmp > 0)
- first = x + 1;
- else
- return x;
- }
- return -1;
+ size_t len = strlen(name);
+ return find_internal_func_gperf(name, len);
}
-/*
- * Check if "name" is a variable of type VAR_FUNC. If so, return the function
- * name it contains, otherwise return "name".
- */
-static char_u *deref_func_name(char_u *name, int *lenp, int no_autoload)
+/// Return name of the function corresponding to `name`
+///
+/// If `name` points to variable that is either a function or partial then
+/// corresponding function name is returned. Otherwise it returns `name` itself.
+///
+/// @param[in] name Function name to check.
+/// @param[in,out] lenp Location where length of the returned name is stored.
+/// Must be set to the length of the `name` argument.
+/// @param[out] partialp Location where partial will be stored if found
+/// function appears to be a partial. May be NULL if this
+/// is not needed.
+/// @param[in] no_autoload If true, do not source autoload scripts if function
+/// was not found.
+///
+/// @return name of the function.
+static char_u *deref_func_name(const char *name, int *lenp,
+ partial_T **const partialp, bool no_autoload)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
{
- dictitem_T *v;
- int cc;
+ if (partialp != NULL) {
+ *partialp = NULL;
+ }
- cc = name[*lenp];
- name[*lenp] = NUL;
- v = find_var(name, NULL, no_autoload);
- name[*lenp] = cc;
+ dictitem_T *const v = find_var(name, (size_t)(*lenp), NULL, no_autoload);
if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
- if (v->di_tv.vval.v_string == NULL) {
+ if (v->di_tv.vval.v_string == NULL) { // just in case
*lenp = 0;
- return (char_u *)""; /* just in case */
+ return (char_u *)"";
}
*lenp = (int)STRLEN(v->di_tv.vval.v_string);
return v->di_tv.vval.v_string;
}
- return name;
+ if (v != NULL && v->di_tv.v_type == VAR_PARTIAL) {
+ partial_T *const pt = v->di_tv.vval.v_partial;
+
+ if (pt == NULL) { // just in case
+ *lenp = 0;
+ return (char_u *)"";
+ }
+ if (partialp != NULL) {
+ *partialp = pt;
+ }
+ char_u *s = partial_name(pt);
+ *lenp = (int)STRLEN(s);
+ return s;
+ }
+
+ return (char_u *)name;
}
/*
* Allocate a variable for the result of a function.
* Return OK or FAIL.
*/
-static int
-get_func_tv (
- char_u *name, /* name of the function */
- int len, /* length of "name" */
+static int
+get_func_tv(
+ char_u *name, // name of the function
+ int len, // length of "name"
typval_T *rettv,
- char_u **arg, /* argument, pointing to the '(' */
- linenr_T firstline, /* first line of range */
- linenr_T lastline, /* last line of range */
- int *doesrange, /* return: function handled range */
+ char_u **arg, // argument, pointing to the '('
+ linenr_T firstline, // first line of range
+ linenr_T lastline, // last line of range
+ int *doesrange, // return: function handled range
int evaluate,
- dict_T *selfdict /* Dictionary for "self" */
+ partial_T *partial, // for extra arguments
+ dict_T *selfdict // Dictionary for "self"
)
{
char_u *argp;
@@ -7117,10 +6107,11 @@ get_func_tv (
* Get the arguments.
*/
argp = *arg;
- while (argcount < MAX_FUNC_ARGS) {
- argp = skipwhite(argp + 1); /* skip the '(' or ',' */
- if (*argp == ')' || *argp == ',' || *argp == NUL)
+ while (argcount < MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) {
+ argp = skipwhite(argp + 1); // skip the '(' or ','
+ if (*argp == ')' || *argp == ',' || *argp == NUL) {
break;
+ }
if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) {
ret = FAIL;
break;
@@ -7134,81 +6125,89 @@ get_func_tv (
else
ret = FAIL;
- if (ret == OK)
- ret = call_func(name, len, rettv, argcount, argvars,
- firstline, lastline, doesrange, evaluate, selfdict);
- else if (!aborting()) {
- if (argcount == MAX_FUNC_ARGS)
+ if (ret == OK) {
+ int i = 0;
+
+ if (get_vim_var_nr(VV_TESTING)) {
+ // Prepare for calling garbagecollect_for_testing(), need to know
+ // what variables are used on the call stack.
+ if (funcargs.ga_itemsize == 0) {
+ ga_init(&funcargs, (int)sizeof(typval_T *), 50);
+ }
+ for (i = 0; i < argcount; i++) {
+ ga_grow(&funcargs, 1);
+ ((typval_T **)funcargs.ga_data)[funcargs.ga_len++] = &argvars[i];
+ }
+ }
+ ret = call_func(name, len, rettv, argcount, argvars, NULL,
+ firstline, lastline, doesrange, evaluate,
+ partial, selfdict);
+
+ funcargs.ga_len -= i;
+ } else if (!aborting()) {
+ if (argcount == MAX_FUNC_ARGS) {
emsg_funcname(N_("E740: Too many arguments for function %s"), name);
- else
+ } else {
emsg_funcname(N_("E116: Invalid arguments for function %s"), name);
+ }
}
- while (--argcount >= 0)
- clear_tv(&argvars[argcount]);
+ while (--argcount >= 0) {
+ tv_clear(&argvars[argcount]);
+ }
*arg = skipwhite(argp);
return ret;
}
+typedef enum {
+ ERROR_UNKNOWN = 0,
+ ERROR_TOOMANY,
+ ERROR_TOOFEW,
+ ERROR_SCRIPT,
+ ERROR_DICT,
+ ERROR_NONE,
+ ERROR_OTHER,
+ ERROR_BOTH,
+ ERROR_DELETED,
+} FnameTransError;
-/*
- * Call a function with its resolved parameters
- * Return FAIL when the function can't be called, OK otherwise.
- * Also returns OK when an error was encountered while executing the function.
- */
-int
-call_func (
- char_u *funcname, /* name of the function */
- int len, /* length of "name" */
- typval_T *rettv, /* return value goes here */
- int argcount, /* number of "argvars" */
- typval_T *argvars, /* vars for arguments, must have "argcount"
- PLUS ONE elements! */
- linenr_T firstline, /* first line of range */
- linenr_T lastline, /* last line of range */
- int *doesrange, /* return: function handled range */
- int evaluate,
- dict_T *selfdict /* Dictionary for "self" */
-)
-{
- int ret = FAIL;
-#define ERROR_UNKNOWN 0
-#define ERROR_TOOMANY 1
-#define ERROR_TOOFEW 2
-#define ERROR_SCRIPT 3
-#define ERROR_DICT 4
-#define ERROR_NONE 5
-#define ERROR_OTHER 6
- int error = ERROR_NONE;
- int i;
- int llen;
- ufunc_T *fp;
#define FLEN_FIXED 40
- char_u fname_buf[FLEN_FIXED + 1];
- char_u *fname;
- char_u *name;
-
- /* Make a copy of the name, if it comes from a funcref variable it could
- * be changed or deleted in the called function. */
- name = vim_strnsave(funcname, len);
- /*
- * In a script change <SID>name() and s:name() to K_SNR 123_name().
- * Change <SNR>123_name() to K_SNR 123_name().
- * Use fname_buf[] when it fits, otherwise allocate memory (slow).
- */
- llen = eval_fname_script(name);
+/// In a script transform script-local names into actually used names
+///
+/// Transforms "<SID>" and "s:" prefixes to `K_SNR {N}` (e.g. K_SNR "123") and
+/// "<SNR>" prefix to `K_SNR`. Uses `fname_buf` buffer that is supposed to have
+/// #FLEN_FIXED + 1 length when it fits, otherwise it allocates memory.
+///
+/// @param[in] name Name to transform.
+/// @param fname_buf Buffer to save resulting function name to, if it fits.
+/// Must have at least #FLEN_FIXED + 1 length.
+/// @param[out] tofree Location where pointer to an allocated memory is saved
+/// in case result does not fit into fname_buf.
+/// @param[out] error Location where error type is saved, @see
+/// FnameTransError.
+///
+/// @return transformed name: either `fname_buf` or a pointer to an allocated
+/// memory.
+static char_u *fname_trans_sid(const char_u *const name,
+ char_u *const fname_buf,
+ char_u **const tofree, int *const error)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ char_u *fname;
+ const int llen = eval_fname_script((const char *)name);
if (llen > 0) {
fname_buf[0] = K_SPECIAL;
fname_buf[1] = KS_EXTRA;
fname_buf[2] = (int)KE_SNR;
- i = 3;
- if (eval_fname_sid(name)) { /* "<SID>" or "s:" */
- if (current_SID <= 0)
- error = ERROR_SCRIPT;
- else {
- sprintf((char *)fname_buf + 3, "%" PRId64 "_", (int64_t)current_SID);
+ int i = 3;
+ if (eval_fname_sid((const char *)name)) { // "<SID>" or "s:"
+ if (current_SID <= 0) {
+ *error = ERROR_SCRIPT;
+ } else {
+ snprintf((char *)fname_buf + 3, FLEN_FIXED + 1, "%" PRId64 "_",
+ (int64_t)current_SID);
i = (int)STRLEN(fname_buf);
}
}
@@ -7217,13 +6216,114 @@ call_func (
fname = fname_buf;
} else {
fname = xmalloc(i + STRLEN(name + llen) + 1);
+ *tofree = fname;
memmove(fname, fname_buf, (size_t)i);
STRCPY(fname + i, name + llen);
}
- } else
- fname = name;
+ } else {
+ fname = (char_u *)name;
+ }
+
+ return fname;
+}
+
+/// Mark all lists and dicts referenced through function "name" with "copyID".
+/// "list_stack" is used to add lists to be marked. Can be NULL.
+/// "ht_stack" is used to add hashtabs to be marked. Can be NULL.
+///
+/// @return true if setting references failed somehow.
+bool set_ref_in_func(char_u *name, ufunc_T *fp_in, int copyID)
+{
+ ufunc_T *fp = fp_in;
+ funccall_T *fc;
+ int error = ERROR_NONE;
+ char_u fname_buf[FLEN_FIXED + 1];
+ char_u *tofree = NULL;
+ char_u *fname;
+ bool abort = false;
+ if (name == NULL && fp_in == NULL) {
+ return false;
+ }
+
+ if (fp_in == NULL) {
+ fname = fname_trans_sid(name, fname_buf, &tofree, &error);
+ fp = find_func(fname);
+ }
+ if (fp != NULL) {
+ for (fc = fp->uf_scoped; fc != NULL; fc = fc->func->uf_scoped) {
+ abort = abort || set_ref_in_funccal(fc, copyID);
+ }
+ }
+ xfree(tofree);
+ return abort;
+}
- *doesrange = FALSE;
+/// Call a function with its resolved parameters
+///
+/// "argv_func", when not NULL, can be used to fill in arguments only when the
+/// invoked function uses them. It is called like this:
+/// new_argcount = argv_func(current_argcount, argv, called_func_argcount)
+///
+/// @return FAIL if function cannot be called, else OK (even if an error
+/// occurred while executing the function! Set `msg_list` to capture
+/// the error, see do_cmdline()).
+int
+call_func(
+ const char_u *funcname, // name of the function
+ int len, // length of "name"
+ typval_T *rettv, // [out] value goes here
+ int argcount_in, // number of "argvars"
+ typval_T *argvars_in, // vars for arguments, must have "argcount"
+ // PLUS ONE elements!
+ ArgvFunc argv_func, // function to fill in argvars
+ linenr_T firstline, // first line of range
+ linenr_T lastline, // last line of range
+ int *doesrange, // [out] function handled range
+ bool evaluate,
+ partial_T *partial, // optional, can be NULL
+ dict_T *selfdict_in // Dictionary for "self"
+)
+{
+ int ret = FAIL;
+ int error = ERROR_NONE;
+ ufunc_T *fp;
+ char_u fname_buf[FLEN_FIXED + 1];
+ char_u *tofree = NULL;
+ char_u *fname;
+ char_u *name;
+ int argcount = argcount_in;
+ typval_T *argvars = argvars_in;
+ dict_T *selfdict = selfdict_in;
+ typval_T argv[MAX_FUNC_ARGS + 1]; // used when "partial" is not NULL
+ int argv_clear = 0;
+
+ // Make a copy of the name, if it comes from a funcref variable it could
+ // be changed or deleted in the called function.
+ name = vim_strnsave(funcname, len);
+
+ fname = fname_trans_sid(name, fname_buf, &tofree, &error);
+
+ *doesrange = false;
+
+ if (partial != NULL) {
+ // When the function has a partial with a dict and there is a dict
+ // argument, use the dict argument. That is backwards compatible.
+ // When the dict was bound explicitly use the one from the partial.
+ if (partial->pt_dict != NULL
+ && (selfdict_in == NULL || !partial->pt_auto)) {
+ selfdict = partial->pt_dict;
+ }
+ if (error == ERROR_NONE && partial->pt_argc > 0) {
+ for (argv_clear = 0; argv_clear < partial->pt_argc; argv_clear++) {
+ tv_copy(&partial->pt_argv[argv_clear], &argv[argv_clear]);
+ }
+ for (int i = 0; i < argcount_in; i++) {
+ argv[i + argv_clear] = argvars_in[i];
+ }
+ argvars = argv;
+ argcount = partial->pt_argc + argcount_in;
+ }
+ }
/* execute the function if no errors detected and executing */
@@ -7239,54 +6339,61 @@ call_func (
rettv->vval.v_number = 0;
error = ERROR_UNKNOWN;
- if (!builtin_function(rfname, -1)) {
- /*
- * User defined function.
- */
- fp = find_func(rfname);
+ if (!builtin_function((const char *)rfname, -1)) {
+ // User defined function.
+ if (partial != NULL && partial->pt_func != NULL) {
+ fp = partial->pt_func;
+ } else {
+ fp = find_func(rfname);
+ }
- /* Trigger FuncUndefined event, may load the function. */
+ // Trigger FuncUndefined event, may load the function.
if (fp == NULL
&& apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, TRUE, NULL)
&& !aborting()) {
/* executed an autocommand, search for the function again */
fp = find_func(rfname);
}
- /* Try loading a package. */
- if (fp == NULL && script_autoload(rfname, TRUE) && !aborting()) {
- /* loaded a package, search for the function again */
+ // Try loading a package.
+ if (fp == NULL && script_autoload((const char *)rfname, STRLEN(rfname),
+ true) && !aborting()) {
+ // Loaded a package, search for the function again.
fp = find_func(rfname);
}
- if (fp != NULL) {
- if (fp->uf_flags & FC_RANGE)
- *doesrange = TRUE;
- if (argcount < fp->uf_args.ga_len)
+ if (fp != NULL && (fp->uf_flags & FC_DELETED)) {
+ error = ERROR_DELETED;
+ } else if (fp != NULL) {
+ if (argv_func != NULL) {
+ argcount = argv_func(argcount, argvars, fp->uf_args.ga_len);
+ }
+ if (fp->uf_flags & FC_RANGE) {
+ *doesrange = true;
+ }
+ if (argcount < fp->uf_args.ga_len) {
error = ERROR_TOOFEW;
- else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len)
+ } else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) {
error = ERROR_TOOMANY;
- else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
+ } else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) {
error = ERROR_DICT;
- else {
+ } else {
// Call the user function.
call_user_func(fp, argcount, argvars, rettv, firstline, lastline,
- (fp->uf_flags & FC_DICT) ? selfdict : NULL);
+ (fp->uf_flags & FC_DICT) ? selfdict : NULL);
error = ERROR_NONE;
}
}
} else {
- /*
- * Find the function name in the table, call its implementation.
- */
- i = find_internal_func(fname);
- if (i >= 0) {
- if (argcount < functions[i].f_min_argc)
+ // Find the function name in the table, call its implementation.
+ const VimLFuncDef *const fdef = find_internal_func((const char *)fname);
+ if (fdef != NULL) {
+ if (argcount < fdef->min_argc) {
error = ERROR_TOOFEW;
- else if (argcount > functions[i].f_max_argc)
+ } else if (argcount > fdef->max_argc) {
error = ERROR_TOOMANY;
- else {
+ } else {
argvars[argcount].v_type = VAR_UNKNOWN;
- functions[i].f_func(argvars, rettv);
+ fdef->func(argvars, rettv, fdef->data);
error = ERROR_NONE;
}
}
@@ -7315,6 +6422,9 @@ call_func (
case ERROR_UNKNOWN:
emsg_funcname(N_("E117: Unknown function: %s"), name);
break;
+ case ERROR_DELETED:
+ emsg_funcname(N_("E933: Function was deleted: %s"), name);
+ break;
case ERROR_TOOMANY:
emsg_funcname(e_toomanyarg, name);
break;
@@ -7333,28 +6443,34 @@ call_func (
}
}
- if (fname != name && fname != fname_buf)
- xfree(fname);
+ while (argv_clear > 0) {
+ tv_clear(&argv[--argv_clear]);
+ }
+ xfree(tofree);
xfree(name);
return ret;
}
-/*
- * Give an error message with a function name. Handle <SNR> things.
- * "ermsg" is to be passed without translation, use N_() instead of _().
- */
+/// Give an error message with a function name. Handle <SNR> things.
+///
+/// @param ermsg must be passed without translation (use N_() instead of _()).
+/// @param name function name
static void emsg_funcname(char *ermsg, char_u *name)
{
- char_u *p;
+ char_u *p;
- if (*name == K_SPECIAL)
+ if (*name == K_SPECIAL) {
p = concat_str((char_u *)"<SNR>", name + 3);
- else
+ } else {
p = name;
+ }
+
EMSG2(_(ermsg), p);
- if (p != name)
+
+ if (p != name) {
xfree(p);
+ }
}
/*
@@ -7362,11 +6478,13 @@ static void emsg_funcname(char *ermsg, char_u *name)
*/
static int non_zero_arg(typval_T *argvars)
{
- return (argvars[0].v_type == VAR_NUMBER
- && argvars[0].vval.v_number != 0)
- || (argvars[0].v_type == VAR_STRING
- && argvars[0].vval.v_string != NULL
- && *argvars[0].vval.v_string != NUL);
+ return ((argvars[0].v_type == VAR_NUMBER
+ && argvars[0].vval.v_number != 0)
+ || (argvars[0].v_type == VAR_SPECIAL
+ && argvars[0].vval.v_special == kSpecialVarTrue)
+ || (argvars[0].v_type == VAR_STRING
+ && argvars[0].vval.v_string != NULL
+ && *argvars[0].vval.v_string != NUL));
}
/*********************************************
@@ -7374,105 +6492,103 @@ static int non_zero_arg(typval_T *argvars)
*/
-/*
- * Get the float value of "argvars[0]" into "f".
- * Returns FAIL when the argument is not a Number or Float.
- */
-static inline int get_float_arg(typval_T *argvars, float_T *f)
-{
- if (argvars[0].v_type == VAR_FLOAT) {
- *f = argvars[0].vval.v_float;
- return OK;
- }
- if (argvars[0].v_type == VAR_NUMBER) {
- *f = (float_T)argvars[0].vval.v_number;
- return OK;
- }
- EMSG(_("E808: Number or Float required"));
- return FAIL;
-}
-
// Apply a floating point C function on a typval with one float_T.
//
// Some versions of glibc on i386 have an optimization that makes it harder to
// call math functions indirectly from inside an inlined function, causing
// compile-time errors. Avoid `inline` in that case. #3072
-#ifndef ARCH_32
-inline
-#endif
-static void float_op_wrapper(typval_T *argvars, typval_T *rettv,
- float_T (*function)(float_T))
+static void float_op_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T f;
+ float_T (*function)(float_T) = (float_T (*)(float_T))fptr;
rettv->v_type = VAR_FLOAT;
- if (get_float_arg(argvars, &f) == OK) {
+ if (tv_get_float_chk(argvars, &f)) {
rettv->vval.v_float = function(f);
} else {
rettv->vval.v_float = 0.0;
}
}
+static void api_wrapper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ ApiDispatchWrapper fn = (ApiDispatchWrapper)fptr;
+
+ Array args = ARRAY_DICT_INIT;
+
+ for (typval_T *tv = argvars; tv->v_type != VAR_UNKNOWN; tv++) {
+ ADD(args, vim_to_object(tv));
+ }
+
+ Error err = ERROR_INIT;
+ Object result = fn(VIML_INTERNAL_CALL, args, &err);
+
+ if (ERROR_SET(&err)) {
+ nvim_err_writeln(cstr_as_string(err.msg));
+ goto end;
+ }
+
+ if (!object_to_vim(result, rettv, &err)) {
+ EMSG2(_("Error converting the call result: %s"), err.msg);
+ }
+
+end:
+ api_free_array(args);
+ api_free_object(result);
+ api_clear_error(&err);
+}
+
/*
* "abs(expr)" function
*/
-static void f_abs(typval_T *argvars, typval_T *rettv)
+static void f_abs(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type == VAR_FLOAT) {
- float_op_wrapper(argvars, rettv, &fabs);
+ float_op_wrapper(argvars, rettv, (FunPtr)&fabs);
} else {
varnumber_T n;
- int error = FALSE;
+ bool error = false;
- n = get_tv_number_chk(&argvars[0], &error);
- if (error)
+ n = tv_get_number_chk(&argvars[0], &error);
+ if (error) {
rettv->vval.v_number = -1;
- else if (n > 0)
+ } else if (n > 0) {
rettv->vval.v_number = n;
- else
+ } else {
rettv->vval.v_number = -n;
+ }
}
}
/*
- * "acos()" function
- */
-static void f_acos(typval_T *argvars, typval_T *rettv)
-{
- float_op_wrapper(argvars, rettv, &acos);
-}
-
-/*
* "add(list, item)" function
*/
-static void f_add(typval_T *argvars, typval_T *rettv)
+static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- list_T *l;
-
- rettv->vval.v_number = 1; /* Default: Failed */
+ rettv->vval.v_number = 1; // Default: failed.
if (argvars[0].v_type == VAR_LIST) {
- if ((l = argvars[0].vval.v_list) != NULL
- && !tv_check_lock(l->lv_lock,
- (char_u *)N_("add() argument"), true)) {
- list_append_tv(l, &argvars[1]);
- copy_tv(&argvars[0], rettv);
+ list_T *const l = argvars[0].vval.v_list;
+ if (!tv_check_lock(tv_list_locked(l), N_("add() argument"), TV_TRANSLATE)) {
+ tv_list_append_tv(l, &argvars[1]);
+ tv_copy(&argvars[0], rettv);
}
- } else
+ } else {
EMSG(_(e_listreq));
+ }
}
/*
* "and(expr, expr)" function
*/
-static void f_and(typval_T *argvars, typval_T *rettv)
+static void f_and(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
- & get_tv_number_chk(&argvars[1], NULL);
+ rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
+ & tv_get_number_chk(&argvars[1], NULL);
}
/// "api_info()" function
-static void f_api_info(typval_T *argvars, typval_T *rettv)
+static void f_api_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
Dictionary metadata = api_metadata();
(void)object_to_vim(DICTIONARY_OBJ(metadata), rettv, NULL);
@@ -7482,10 +6598,9 @@ static void f_api_info(typval_T *argvars, typval_T *rettv)
/*
* "append(lnum, string/list)" function
*/
-static void f_append(typval_T *argvars, typval_T *rettv)
+static void f_append(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long lnum;
- char_u *line;
list_T *l = NULL;
listitem_T *li = NULL;
typval_T *tv;
@@ -7498,33 +6613,36 @@ static void f_append(typval_T *argvars, typval_T *rettv)
u_sync(TRUE);
}
- lnum = get_tv_lnum(argvars);
+ lnum = tv_get_lnum(argvars);
if (lnum >= 0
&& lnum <= curbuf->b_ml.ml_line_count
&& u_save(lnum, lnum + 1) == OK) {
if (argvars[1].v_type == VAR_LIST) {
l = argvars[1].vval.v_list;
- if (l == NULL)
+ if (l == NULL) {
return;
- li = l->lv_first;
+ }
+ li = tv_list_first(l);
}
for (;; ) {
- if (l == NULL)
- tv = &argvars[1]; /* append a string */
- else if (li == NULL)
- break; /* end of list */
- else
- tv = &li->li_tv; /* append item from list */
- line = get_tv_string_chk(tv);
- if (line == NULL) { /* type error */
- rettv->vval.v_number = 1; /* Failed */
+ if (l == NULL) {
+ tv = &argvars[1]; // Append a string.
+ } else if (li == NULL) {
+ break; // End of list.
+ } else {
+ tv = TV_LIST_ITEM_TV(li); // Append item from list.
+ }
+ const char *const line = tv_get_string_chk(tv);
+ if (line == NULL) { // Type error.
+ rettv->vval.v_number = 1; // Failed.
break;
}
- ml_append(lnum + added, line, (colnr_T)0, FALSE);
- ++added;
- if (l == NULL)
+ ml_append(lnum + added, (char_u *)line, (colnr_T)0, false);
+ added++;
+ if (l == NULL) {
break;
- li = li->li_next;
+ }
+ li = TV_LIST_ITEM_NEXT(l, li);
}
appended_lines_mark(lnum, added);
@@ -7537,7 +6655,7 @@ static void f_append(typval_T *argvars, typval_T *rettv)
/*
* "argc()" function
*/
-static void f_argc(typval_T *argvars, typval_T *rettv)
+static void f_argc(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ARGCOUNT;
}
@@ -7545,13 +6663,13 @@ static void f_argc(typval_T *argvars, typval_T *rettv)
/*
* "argidx()" function
*/
-static void f_argidx(typval_T *argvars, typval_T *rettv)
+static void f_argidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = curwin->w_arg_idx;
}
/// "arglistid" function
-static void f_arglistid(typval_T *argvars, typval_T *rettv)
+static void f_arglistid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
win_T *wp = find_tabwin(&argvars[0], &argvars[1]);
@@ -7563,21 +6681,24 @@ static void f_arglistid(typval_T *argvars, typval_T *rettv)
/*
* "argv(nr)" function
*/
-static void f_argv(typval_T *argvars, typval_T *rettv)
+static void f_argv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int idx;
if (argvars[0].v_type != VAR_UNKNOWN) {
- idx = get_tv_number_chk(&argvars[0], NULL);
- if (idx >= 0 && idx < ARGCOUNT)
- rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
- else
+ idx = (int)tv_get_number_chk(&argvars[0], NULL);
+ if (idx >= 0 && idx < ARGCOUNT) {
+ rettv->vval.v_string = (char_u *)xstrdup(
+ (const char *)alist_name(&ARGLIST[idx]));
+ } else {
rettv->vval.v_string = NULL;
+ }
rettv->v_type = VAR_STRING;
} else {
- rettv_list_alloc(rettv);
- for (idx = 0; idx < ARGCOUNT; ++idx) {
- list_append_string(rettv->vval.v_list, alist_name(&ARGLIST[idx]), -1);
+ tv_list_alloc_ret(rettv, ARGCOUNT);
+ for (idx = 0; idx < ARGCOUNT; idx++) {
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)alist_name(&ARGLIST[idx]), -1);
}
}
}
@@ -7603,29 +6724,79 @@ static void prepare_assert_error(garray_T *gap)
}
}
+// Append "str" to "gap", escaping unprintable characters.
+// Changes NL to \n, CR to \r, etc.
+static void ga_concat_esc(garray_T *gap, char_u *str)
+{
+ char_u *p;
+ char_u buf[NUMBUFLEN];
+
+ if (str == NULL) {
+ ga_concat(gap, (char_u *)"NULL");
+ return;
+ }
+
+ for (p = str; *p != NUL; p++) {
+ switch (*p) {
+ case BS: ga_concat(gap, (char_u *)"\\b"); break;
+ case ESC: ga_concat(gap, (char_u *)"\\e"); break;
+ case FF: ga_concat(gap, (char_u *)"\\f"); break;
+ case NL: ga_concat(gap, (char_u *)"\\n"); break;
+ case TAB: ga_concat(gap, (char_u *)"\\t"); break;
+ case CAR: ga_concat(gap, (char_u *)"\\r"); break;
+ case '\\': ga_concat(gap, (char_u *)"\\\\"); break;
+ default:
+ if (*p < ' ') {
+ vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p);
+ ga_concat(gap, buf);
+ } else {
+ ga_append(gap, *p);
+ }
+ break;
+ }
+ }
+}
+
// Fill "gap" with information about an assert error.
static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv,
char_u *exp_str, typval_T *exp_tv,
- typval_T *got_tv)
+ typval_T *got_tv, assert_type_T atype)
{
char_u *tofree;
if (opt_msg_tv->v_type != VAR_UNKNOWN) {
- tofree = (char_u *) encode_tv2string(opt_msg_tv, NULL);
+ tofree = (char_u *)encode_tv2echo(opt_msg_tv, NULL);
ga_concat(gap, tofree);
xfree(tofree);
+ ga_concat(gap, (char_u *)": ");
+ }
+
+ if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) {
+ ga_concat(gap, (char_u *)"Pattern ");
+ } else if (atype == ASSERT_NOTEQUAL) {
+ ga_concat(gap, (char_u *)"Expected not equal to ");
} else {
ga_concat(gap, (char_u *)"Expected ");
- if (exp_str == NULL) {
- tofree = (char_u *) encode_tv2string(exp_tv, NULL);
- ga_concat(gap, tofree);
- xfree(tofree);
+ }
+
+ if (exp_str == NULL) {
+ tofree = (char_u *)encode_tv2string(exp_tv, NULL);
+ ga_concat_esc(gap, tofree);
+ xfree(tofree);
+ } else {
+ ga_concat_esc(gap, exp_str);
+ }
+
+ if (atype != ASSERT_NOTEQUAL) {
+ if (atype == ASSERT_MATCH) {
+ ga_concat(gap, (char_u *)" does not match ");
+ } else if (atype == ASSERT_NOTMATCH) {
+ ga_concat(gap, (char_u *)" does match ");
} else {
- ga_concat(gap, exp_str);
+ ga_concat(gap, (char_u *)" but got ");
}
- tofree = (char_u *) encode_tv2string(got_tv, NULL);
- ga_concat(gap, (char_u *)" but got ");
- ga_concat(gap, tofree);
+ tofree = (char_u *)encode_tv2string(got_tv, NULL);
+ ga_concat_esc(gap, tofree);
xfree(tofree);
}
}
@@ -7637,32 +6808,55 @@ static void assert_error(garray_T *gap)
if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) {
// Make sure v:errors is a list.
- set_vim_var_list(VV_ERRORS, list_alloc());
+ set_vim_var_list(VV_ERRORS, tv_list_alloc(1));
}
- list_append_string(vimvars[VV_ERRORS].vv_list,
- gap->ga_data, gap->ga_len);
+ tv_list_append_string(vimvars[VV_ERRORS].vv_list,
+ (const char *)gap->ga_data, (ptrdiff_t)gap->ga_len);
}
-// "assert_equal(expected, actual[, msg])" function
-static void f_assert_equal(typval_T *argvars, typval_T *rettv)
+static void assert_equal_common(typval_T *argvars, assert_type_T atype)
{
garray_T ga;
- if (!tv_equal(&argvars[0], &argvars[1], false, false)) {
+ if (tv_equal(&argvars[0], &argvars[1], false, false)
+ != (atype == ASSERT_EQUAL)) {
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[2], NULL,
- &argvars[0], &argvars[1]);
+ &argvars[0], &argvars[1], atype);
assert_error(&ga);
ga_clear(&ga);
}
}
+// "assert_equal(expected, actual[, msg])" function
+static void f_assert_equal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ assert_equal_common(argvars, ASSERT_EQUAL);
+}
+
+// "assert_notequal(expected, actual[, msg])" function
+static void f_assert_notequal(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ assert_equal_common(argvars, ASSERT_NOTEQUAL);
+}
+
+/// "assert_report(msg)
+static void f_assert_report(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ garray_T ga;
+
+ prepare_assert_error(&ga);
+ ga_concat(&ga, (const char_u *)tv_get_string(&argvars[0]));
+ assert_error(&ga);
+ ga_clear(&ga);
+}
+
/// "assert_exception(string[, msg])" function
-static void f_assert_exception(typval_T *argvars, typval_T *rettv)
+static void f_assert_exception(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
garray_T ga;
- char *error = (char *)get_tv_string_chk(&argvars[0]);
+ const char *const error = tv_get_string_chk(&argvars[0]);
if (vimvars[VV_EXCEPTION].vv_str == NULL) {
prepare_assert_error(&ga);
ga_concat(&ga, (char_u *)"v:exception is not set");
@@ -7672,37 +6866,37 @@ static void f_assert_exception(typval_T *argvars, typval_T *rettv)
&& strstr((char *)vimvars[VV_EXCEPTION].vv_str, error) == NULL) {
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
- &vimvars[VV_EXCEPTION].vv_tv);
+ &vimvars[VV_EXCEPTION].vv_tv, ASSERT_OTHER);
assert_error(&ga);
ga_clear(&ga);
}
}
/// "assert_fails(cmd [, error])" function
-static void f_assert_fails(typval_T *argvars, typval_T *rettv)
+static void f_assert_fails(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *cmd = get_tv_string_chk(&argvars[0]);
+ const char *const cmd = tv_get_string_chk(&argvars[0]);
garray_T ga;
called_emsg = false;
suppress_errthrow = true;
emsg_silent = true;
- do_cmdline_cmd((char *)cmd);
+ do_cmdline_cmd(cmd);
if (!called_emsg) {
prepare_assert_error(&ga);
- ga_concat(&ga, (char_u *)"command did not fail: ");
- ga_concat(&ga, cmd);
+ ga_concat(&ga, (const char_u *)"command did not fail: ");
+ ga_concat(&ga, (const char_u *)cmd);
assert_error(&ga);
ga_clear(&ga);
} else if (argvars[1].v_type != VAR_UNKNOWN) {
- char_u buf[NUMBUFLEN];
- char *error = (char *)get_tv_string_buf_chk(&argvars[1], buf);
+ char buf[NUMBUFLEN];
+ const char *const error = tv_get_string_buf_chk(&argvars[1], buf);
if (error == NULL
|| strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL) {
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
- &vimvars[VV_ERRMSG].vv_tv);
+ &vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER);
assert_error(&ga);
ga_clear(&ga);
}
@@ -7715,14 +6909,39 @@ static void f_assert_fails(typval_T *argvars, typval_T *rettv)
set_vim_var_string(VV_ERRMSG, NULL, 0);
}
+void assert_inrange(typval_T *argvars)
+{
+ bool error = false;
+ const varnumber_T lower = tv_get_number_chk(&argvars[0], &error);
+ const varnumber_T upper = tv_get_number_chk(&argvars[1], &error);
+ const varnumber_T actual = tv_get_number_chk(&argvars[2], &error);
+
+ if (error) {
+ return;
+ }
+ if (actual < lower || actual > upper) {
+ garray_T ga;
+ prepare_assert_error(&ga);
+
+ char msg[55];
+ vim_snprintf(msg, sizeof(msg),
+ "range %" PRIdVARNUMBER " - %" PRIdVARNUMBER ",",
+ lower, upper);
+ fill_assert_error(&ga, &argvars[3], (char_u *)msg, NULL, &argvars[2],
+ ASSERT_INRANGE);
+ assert_error(&ga);
+ ga_clear(&ga);
+ }
+}
+
// Common for assert_true() and assert_false().
static void assert_bool(typval_T *argvars, bool is_true)
{
- int error = (int)false;
+ bool error = false;
garray_T ga;
if ((argvars[0].v_type != VAR_NUMBER
- || (get_tv_number_chk(&argvars[0], &error) == 0) == is_true
+ || (tv_get_number_chk(&argvars[0], &error) == 0) == is_true
|| error)
&& (argvars[0].v_type != VAR_SPECIAL
|| (argvars[0].vval.v_special
@@ -7732,59 +6951,81 @@ static void assert_bool(typval_T *argvars, bool is_true)
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[1],
(char_u *)(is_true ? "True" : "False"),
- NULL, &argvars[0]);
+ NULL, &argvars[0], ASSERT_OTHER);
assert_error(&ga);
ga_clear(&ga);
}
}
// "assert_false(actual[, msg])" function
-static void f_assert_false(typval_T *argvars, typval_T *rettv)
+static void f_assert_false(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
assert_bool(argvars, false);
}
-// "assert_true(actual[, msg])" function
-static void f_assert_true(typval_T *argvars, typval_T *rettv)
+static void assert_match_common(typval_T *argvars, assert_type_T atype)
{
- assert_bool(argvars, true);
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *const pat = tv_get_string_buf_chk(&argvars[0], buf1);
+ const char *const text = tv_get_string_buf_chk(&argvars[1], buf2);
+
+ if (pat == NULL || text == NULL) {
+ EMSG(_(e_invarg));
+ } else if (pattern_match((char_u *)pat, (char_u *)text, false)
+ != (atype == ASSERT_MATCH)) {
+ garray_T ga;
+ prepare_assert_error(&ga);
+ fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], atype);
+ assert_error(&ga);
+ ga_clear(&ga);
+ }
}
-/*
- * "asin()" function
- */
-static void f_asin(typval_T *argvars, typval_T *rettv)
+/// "assert_inrange(lower, upper[, msg])" function
+static void f_assert_inrange(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_op_wrapper(argvars, rettv, &asin);
+ assert_inrange(argvars);
}
-/*
- * "atan()" function
- */
-static void f_atan(typval_T *argvars, typval_T *rettv)
+/// "assert_match(pattern, actual[, msg])" function
+static void f_assert_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ assert_match_common(argvars, ASSERT_MATCH);
+}
+
+/// "assert_notmatch(pattern, actual[, msg])" function
+static void f_assert_notmatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_op_wrapper(argvars, rettv, &atan);
+ assert_match_common(argvars, ASSERT_NOTMATCH);
+}
+
+// "assert_true(actual[, msg])" function
+static void f_assert_true(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ assert_bool(argvars, true);
}
/*
* "atan2()" function
*/
-static void f_atan2(typval_T *argvars, typval_T *rettv)
+static void f_atan2(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_T fx, fy;
+ float_T fx;
+ float_T fy;
rettv->v_type = VAR_FLOAT;
- if (get_float_arg(argvars, &fx) == OK
- && get_float_arg(&argvars[1], &fy) == OK)
+ if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) {
rettv->vval.v_float = atan2(fx, fy);
- else
+ } else {
rettv->vval.v_float = 0.0;
+ }
}
/*
* "browse(save, title, initdir, default)" function
*/
-static void f_browse(typval_T *argvars, typval_T *rettv)
+static void f_browse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
@@ -7793,9 +7034,9 @@ static void f_browse(typval_T *argvars, typval_T *rettv)
/*
* "browsedir(title, initdir)" function
*/
-static void f_browsedir(typval_T *argvars, typval_T *rettv)
+static void f_browsedir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- f_browse(argvars, rettv);
+ f_browse(argvars, rettv, NULL);
}
@@ -7831,7 +7072,7 @@ static buf_T *find_buffer(typval_T *avar)
/*
* "bufexists(expr)" function
*/
-static void f_bufexists(typval_T *argvars, typval_T *rettv)
+static void f_bufexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL);
}
@@ -7839,7 +7080,7 @@ static void f_bufexists(typval_T *argvars, typval_T *rettv)
/*
* "buflisted(expr)" function
*/
-static void f_buflisted(typval_T *argvars, typval_T *rettv)
+static void f_buflisted(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -7850,7 +7091,7 @@ static void f_buflisted(typval_T *argvars, typval_T *rettv)
/*
* "bufloaded(expr)" function
*/
-static void f_bufloaded(typval_T *argvars, typval_T *rettv)
+static void f_bufloaded(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
buf_T *buf;
@@ -7862,7 +7103,7 @@ static void f_bufloaded(typval_T *argvars, typval_T *rettv)
/*
* Get buffer by number or pattern.
*/
-static buf_T *get_buf_tv(typval_T *tv, int curtab_only)
+static buf_T *tv_get_buf(typval_T *tv, int curtab_only)
{
char_u *name = tv->vval.v_string;
int save_magic;
@@ -7900,108 +7141,126 @@ static buf_T *get_buf_tv(typval_T *tv, int curtab_only)
/*
* "bufname(expr)" function
*/
-static void f_bufname(typval_T *argvars, typval_T *rettv)
+static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
-
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- ++emsg_off;
- buf = get_buf_tv(&argvars[0], FALSE);
rettv->v_type = VAR_STRING;
- if (buf != NULL && buf->b_fname != NULL)
- rettv->vval.v_string = vim_strsave(buf->b_fname);
- else
- rettv->vval.v_string = NULL;
- --emsg_off;
+ rettv->vval.v_string = NULL;
+ if (!tv_check_str_or_nr(&argvars[0])) {
+ return;
+ }
+ emsg_off++;
+ const buf_T *const buf = tv_get_buf(&argvars[0], false);
+ emsg_off--;
+ if (buf != NULL && buf->b_fname != NULL) {
+ rettv->vval.v_string = (char_u *)xstrdup((char *)buf->b_fname);
+ }
}
/*
* "bufnr(expr)" function
*/
-static void f_bufnr(typval_T *argvars, typval_T *rettv)
+static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- int error = FALSE;
- char_u *name;
+ bool error = false;
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- ++emsg_off;
- buf = get_buf_tv(&argvars[0], FALSE);
- --emsg_off;
+ rettv->vval.v_number = -1;
+ if (!tv_check_str_or_nr(&argvars[0])) {
+ return;
+ }
+ emsg_off++;
+ const buf_T *buf = tv_get_buf(&argvars[0], false);
+ emsg_off--;
- /* If the buffer isn't found and the second argument is not zero create a
- * new buffer. */
+ // If the buffer isn't found and the second argument is not zero create a
+ // new buffer.
+ const char *name;
if (buf == NULL
&& argvars[1].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[1], &error) != 0
+ && tv_get_number_chk(&argvars[1], &error) != 0
&& !error
- && (name = get_tv_string_chk(&argvars[0])) != NULL
- && !error)
- buf = buflist_new(name, NULL, (linenr_T)1, 0);
+ && (name = tv_get_string_chk(&argvars[0])) != NULL) {
+ buf = buflist_new((char_u *)name, NULL, 1, 0);
+ }
- if (buf != NULL)
+ if (buf != NULL) {
rettv->vval.v_number = buf->b_fnum;
- else
- rettv->vval.v_number = -1;
+ }
}
-/*
- * "bufwinnr(nr)" function
- */
-static void f_bufwinnr(typval_T *argvars, typval_T *rettv)
+static void buf_win_common(typval_T *argvars, typval_T *rettv, bool get_nr)
{
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- ++emsg_off;
+ if (!tv_check_str_or_nr(&argvars[0])) {
+ rettv->vval.v_number = -1;
+ return;
+ }
+
+ emsg_off++;
+ buf_T *buf = tv_get_buf(&argvars[0], true);
+ if (buf == NULL) { // no need to search if buffer was not found
+ rettv->vval.v_number = -1;
+ goto end;
+ }
- buf_T *buf = get_buf_tv(&argvars[0], TRUE);
int winnr = 0;
+ int winid;
bool found_buf = false;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- ++winnr;
+ winnr++;
if (wp->w_buffer == buf) {
found_buf = true;
+ winid = wp->handle;
break;
}
}
- rettv->vval.v_number = (found_buf ? winnr : -1);
- --emsg_off;
+ rettv->vval.v_number = (found_buf ? (get_nr ? winnr : winid) : -1);
+end:
+ emsg_off--;
+}
+
+/// "bufwinid(nr)" function
+static void f_bufwinid(typval_T *argvars, typval_T *rettv, FunPtr fptr) {
+ buf_win_common(argvars, rettv, false);
+}
+
+/// "bufwinnr(nr)" function
+static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ buf_win_common(argvars, rettv, true);
}
/*
* "byte2line(byte)" function
*/
-static void f_byte2line(typval_T *argvars, typval_T *rettv)
+static void f_byte2line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long boff = 0;
-
- boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */
- if (boff < 0)
+ long boff = tv_get_number(&argvars[0]) - 1;
+ if (boff < 0) {
rettv->vval.v_number = -1;
- else
- rettv->vval.v_number = ml_find_line_or_offset(curbuf,
- (linenr_T)0, &boff);
+ } else {
+ rettv->vval.v_number = (varnumber_T)ml_find_line_or_offset(curbuf, 0,
+ &boff, false);
+ }
}
static void byteidx(typval_T *argvars, typval_T *rettv, int comp)
{
- char_u *t;
- char_u *str;
- long idx;
-
- str = get_tv_string_chk(&argvars[0]);
- idx = get_tv_number_chk(&argvars[1], NULL);
+ const char *const str = tv_get_string_chk(&argvars[0]);
+ varnumber_T idx = tv_get_number_chk(&argvars[1], NULL);
rettv->vval.v_number = -1;
- if (str == NULL || idx < 0)
+ if (str == NULL || idx < 0) {
return;
+ }
- t = str;
+ const char *t = str;
for (; idx > 0; idx--) {
- if (*t == NUL) /* EOL reached */
+ if (*t == NUL) { // EOL reached.
return;
- if (enc_utf8 && comp)
- t += utf_ptr2len(t);
- else
- t += (*mb_ptr2len)(t);
+ }
+ if (enc_utf8 && comp) {
+ t += utf_ptr2len((const char_u *)t);
+ } else {
+ t += (*mb_ptr2len)((const char_u *)t);
+ }
}
rettv->vval.v_number = (varnumber_T)(t - str);
}
@@ -8009,7 +7268,7 @@ static void byteidx(typval_T *argvars, typval_T *rettv, int comp)
/*
* "byteidx()" function
*/
-static void f_byteidx(typval_T *argvars, typval_T *rettv)
+static void f_byteidx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
byteidx(argvars, rettv, FALSE);
}
@@ -8017,64 +7276,67 @@ static void f_byteidx(typval_T *argvars, typval_T *rettv)
/*
* "byteidxcomp()" function
*/
-static void f_byteidxcomp(typval_T *argvars, typval_T *rettv)
+static void f_byteidxcomp(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
byteidx(argvars, rettv, TRUE);
}
-int func_call(char_u *name, typval_T *args, dict_T *selfdict, typval_T *rettv)
+int func_call(char_u *name, typval_T *args, partial_T *partial,
+ dict_T *selfdict, typval_T *rettv)
{
- listitem_T *item;
typval_T argv[MAX_FUNC_ARGS + 1];
int argc = 0;
int dummy;
int r = 0;
- for (item = args->vval.v_list->lv_first; item != NULL;
- item = item->li_next) {
- if (argc == MAX_FUNC_ARGS) {
+ TV_LIST_ITER(args->vval.v_list, item, {
+ if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) {
EMSG(_("E699: Too many arguments"));
- break;
+ goto func_call_skip_call;
}
- /* Make a copy of each argument. This is needed to be able to set
- * v_lock to VAR_FIXED in the copy without changing the original list.
- */
- copy_tv(&item->li_tv, &argv[argc++]);
- }
+ // Make a copy of each argument. This is needed to be able to set
+ // v_lock to VAR_FIXED in the copy without changing the original list.
+ tv_copy(TV_LIST_ITEM_TV(item), &argv[argc++]);
+ });
- if (item == NULL)
- r = call_func(name, (int)STRLEN(name), rettv, argc, argv,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &dummy, TRUE, selfdict);
+ r = call_func(name, (int)STRLEN(name), rettv, argc, argv, NULL,
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &dummy, true, partial, selfdict);
- /* Free the arguments. */
- while (argc > 0)
- clear_tv(&argv[--argc]);
+func_call_skip_call:
+ // Free the arguments.
+ while (argc > 0) {
+ tv_clear(&argv[--argc]);
+ }
return r;
}
-/*
- * "call(func, arglist)" function
- */
-static void f_call(typval_T *argvars, typval_T *rettv)
+/// "call(func, arglist [, dict])" function
+static void f_call(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *func;
- dict_T *selfdict = NULL;
-
if (argvars[1].v_type != VAR_LIST) {
EMSG(_(e_listreq));
return;
}
- if (argvars[1].vval.v_list == NULL)
+ if (argvars[1].vval.v_list == NULL) {
return;
+ }
- if (argvars[0].v_type == VAR_FUNC)
+ char_u *func;
+ partial_T *partial = NULL;
+ dict_T *selfdict = NULL;
+ if (argvars[0].v_type == VAR_FUNC) {
func = argvars[0].vval.v_string;
- else
- func = get_tv_string(&argvars[0]);
- if (*func == NUL)
- return; /* type error or empty name */
+ } else if (argvars[0].v_type == VAR_PARTIAL) {
+ partial = argvars[0].vval.v_partial;
+ func = partial_name(partial);
+ } else {
+ func = (char_u *)tv_get_string(&argvars[0]);
+ }
+ if (*func == NUL) {
+ return; // type error or empty name
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
if (argvars[2].v_type != VAR_DICT) {
@@ -8084,86 +7346,112 @@ static void f_call(typval_T *argvars, typval_T *rettv)
selfdict = argvars[2].vval.v_dict;
}
- (void)func_call(func, &argvars[1], selfdict, rettv);
+ func_call(func, &argvars[1], partial, selfdict, rettv);
}
-// "capture(command)" function
-static void f_capture(typval_T *argvars, typval_T *rettv)
+/*
+ * "changenr()" function
+ */
+static void f_changenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int save_msg_silent = msg_silent;
- garray_T *save_capture_ga = capture_ga;
-
- if (check_secure()) {
- return;
- }
+ rettv->vval.v_number = curbuf->b_u_seq_cur;
+}
- garray_T capture_local;
- capture_ga = &capture_local;
- ga_init(capture_ga, (int)sizeof(char), 80);
+// "chanclose(id[, stream])" function
+static void f_chanclose(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = 0;
- msg_silent++;
- if (argvars[0].v_type != VAR_LIST) {
- do_cmdline_cmd((char *)get_tv_string(&argvars[0]));
- } else if (argvars[0].vval.v_list != NULL) {
- for (listitem_T *li = argvars[0].vval.v_list->lv_first;
- li != NULL; li = li->li_next) {
- do_cmdline_cmd((char *)get_tv_string(&li->li_tv));
- }
- }
- msg_silent = save_msg_silent;
+ if (check_restricted() || check_secure()) {
+ return;
+ }
- ga_append(capture_ga, NUL);
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = capture_ga->ga_data;
+ if (argvars[0].v_type != VAR_NUMBER || (argvars[1].v_type != VAR_STRING
+ && argvars[1].v_type != VAR_UNKNOWN)) {
+ EMSG(_(e_invarg));
+ return;
+ }
- capture_ga = save_capture_ga;
+ ChannelPart part = kChannelPartAll;
+ if (argvars[1].v_type == VAR_STRING) {
+ char *stream = (char *)argvars[1].vval.v_string;
+ if (!strcmp(stream, "stdin")) {
+ part = kChannelPartStdin;
+ } else if (!strcmp(stream, "stdout")) {
+ part = kChannelPartStdout;
+ } else if (!strcmp(stream, "stderr")) {
+ part = kChannelPartStderr;
+ } else if (!strcmp(stream, "rpc")) {
+ part = kChannelPartRpc;
+ } else {
+ EMSG2(_("Invalid channel stream \"%s\""), stream);
+ return;
+ }
+ }
+ const char *error;
+ rettv->vval.v_number = channel_close(argvars[0].vval.v_number, part, &error);
+ if (!rettv->vval.v_number) {
+ EMSG(error);
+ }
}
-/*
- * "ceil({float})" function
- */
-static void f_ceil(typval_T *argvars, typval_T *rettv)
+// "chansend(id, data)" function
+static void f_chansend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_op_wrapper(argvars, rettv, &ceil);
-}
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = 0;
-/*
- * "changenr()" function
- */
-static void f_changenr(typval_T *argvars, typval_T *rettv)
-{
- rettv->vval.v_number = curbuf->b_u_seq_cur;
+ if (check_restricted() || check_secure()) {
+ return;
+ }
+
+ if (argvars[0].v_type != VAR_NUMBER || argvars[1].v_type == VAR_UNKNOWN) {
+ // First argument is the channel id and second is the data to write
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ ptrdiff_t input_len = 0;
+ char *input = save_tv_as_string(&argvars[1], &input_len, false);
+ if (!input) {
+ // Either the error has been handled by save_tv_as_string(),
+ // or there is no input to send.
+ return;
+ }
+ uint64_t id = argvars[0].vval.v_number;
+ const char *error = NULL;
+ rettv->vval.v_number = channel_send(id, input, input_len, &error);
+ if (error) {
+ EMSG(error);
+ }
}
/*
* "char2nr(string)" function
*/
-static void f_char2nr(typval_T *argvars, typval_T *rettv)
+static void f_char2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- if (has_mbyte) {
- int utf8 = 0;
-
- if (argvars[1].v_type != VAR_UNKNOWN)
- utf8 = get_tv_number_chk(&argvars[1], NULL);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ if (!tv_check_num(&argvars[1])) {
+ return;
+ }
+ }
- if (utf8)
- rettv->vval.v_number = (*utf_ptr2char)(get_tv_string(&argvars[0]));
- else
- rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0]));
- } else
- rettv->vval.v_number = get_tv_string(&argvars[0])[0];
+ rettv->vval.v_number = utf_ptr2char(
+ (const char_u *)tv_get_string(&argvars[0]));
}
/*
* "cindent(lnum)" function
*/
-static void f_cindent(typval_T *argvars, typval_T *rettv)
+static void f_cindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T pos;
linenr_T lnum;
pos = curwin->w_cursor;
- lnum = get_tv_lnum(argvars);
+ lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = lnum;
rettv->vval.v_number = get_c_indent();
@@ -8175,7 +7463,7 @@ static void f_cindent(typval_T *argvars, typval_T *rettv)
/*
* "clearmatches()" function
*/
-static void f_clearmatches(typval_T *argvars, typval_T *rettv)
+static void f_clearmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
clear_matches(curwin);
}
@@ -8183,7 +7471,7 @@ static void f_clearmatches(typval_T *argvars, typval_T *rettv)
/*
* "col(string)" function
*/
-static void f_col(typval_T *argvars, typval_T *rettv)
+static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
colnr_T col = 0;
pos_T *fp;
@@ -8220,10 +7508,8 @@ static void f_col(typval_T *argvars, typval_T *rettv)
/*
* "complete()" function
*/
-static void f_complete(typval_T *argvars, typval_T *rettv)
+static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int startcol;
-
if ((State & INSERT) == 0) {
EMSG(_("E785: complete() can only be used in Insert mode"));
return;
@@ -8234,14 +7520,15 @@ static void f_complete(typval_T *argvars, typval_T *rettv)
if (!undo_allowed())
return;
- if (argvars[1].v_type != VAR_LIST || argvars[1].vval.v_list == NULL) {
+ if (argvars[1].v_type != VAR_LIST) {
EMSG(_(e_invarg));
return;
}
- startcol = get_tv_number_chk(&argvars[0], NULL);
- if (startcol <= 0)
+ const colnr_T startcol = tv_get_number_chk(&argvars[0], NULL);
+ if (startcol <= 0) {
return;
+ }
set_completion(startcol - 1, argvars[1].vval.v_list);
}
@@ -8249,7 +7536,7 @@ static void f_complete(typval_T *argvars, typval_T *rettv)
/*
* "complete_add()" function
*/
-static void f_complete_add(typval_T *argvars, typval_T *rettv)
+static void f_complete_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0);
}
@@ -8257,12 +7544,12 @@ static void f_complete_add(typval_T *argvars, typval_T *rettv)
/*
* "complete_check()" function
*/
-static void f_complete_check(typval_T *argvars, typval_T *rettv)
+static void f_complete_check(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int saved = RedrawingDisabled;
RedrawingDisabled = 0;
- ins_compl_check_keys(0);
+ ins_compl_check_keys(0, true);
rettv->vval.v_number = compl_interrupted;
RedrawingDisabled = saved;
}
@@ -8270,109 +7557,126 @@ static void f_complete_check(typval_T *argvars, typval_T *rettv)
/*
* "confirm(message, buttons[, default [, type]])" function
*/
-static void f_confirm(typval_T *argvars, typval_T *rettv)
+static void f_confirm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *message;
- char_u *buttons = NULL;
- char_u buf[NUMBUFLEN];
- char_u buf2[NUMBUFLEN];
+ char buf[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *message;
+ const char *buttons = NULL;
int def = 1;
int type = VIM_GENERIC;
- char_u *typestr;
- int error = FALSE;
+ const char *typestr;
+ bool error = false;
- message = get_tv_string_chk(&argvars[0]);
- if (message == NULL)
- error = TRUE;
+ message = tv_get_string_chk(&argvars[0]);
+ if (message == NULL) {
+ error = true;
+ }
if (argvars[1].v_type != VAR_UNKNOWN) {
- buttons = get_tv_string_buf_chk(&argvars[1], buf);
- if (buttons == NULL)
- error = TRUE;
+ buttons = tv_get_string_buf_chk(&argvars[1], buf);
+ if (buttons == NULL) {
+ error = true;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- def = get_tv_number_chk(&argvars[2], &error);
+ def = tv_get_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN) {
- typestr = get_tv_string_buf_chk(&argvars[3], buf2);
- if (typestr == NULL)
- error = TRUE;
- else {
+ typestr = tv_get_string_buf_chk(&argvars[3], buf2);
+ if (typestr == NULL) {
+ error = true;
+ } else {
switch (TOUPPER_ASC(*typestr)) {
- case 'E': type = VIM_ERROR; break;
- case 'Q': type = VIM_QUESTION; break;
- case 'I': type = VIM_INFO; break;
- case 'W': type = VIM_WARNING; break;
- case 'G': type = VIM_GENERIC; break;
+ case 'E': type = VIM_ERROR; break;
+ case 'Q': type = VIM_QUESTION; break;
+ case 'I': type = VIM_INFO; break;
+ case 'W': type = VIM_WARNING; break;
+ case 'G': type = VIM_GENERIC; break;
}
}
}
}
}
- if (buttons == NULL || *buttons == NUL)
- buttons = (char_u *)_("&Ok");
+ if (buttons == NULL || *buttons == NUL) {
+ buttons = _("&Ok");
+ }
- if (!error)
- rettv->vval.v_number = do_dialog(type, NULL, message, buttons,
- def, NULL, FALSE);
+ if (!error) {
+ rettv->vval.v_number = do_dialog(
+ type, NULL, (char_u *)message, (char_u *)buttons, def, NULL, false);
+ }
}
/*
* "copy()" function
*/
-static void f_copy(typval_T *argvars, typval_T *rettv)
+static void f_copy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
var_item_copy(NULL, &argvars[0], rettv, false, 0);
}
/*
- * "cos()" function
- */
-static void f_cos(typval_T *argvars, typval_T *rettv)
-{
- float_op_wrapper(argvars, rettv, &cos);
-}
-
-/*
- * "cosh()" function
- */
-static void f_cosh(typval_T *argvars, typval_T *rettv)
-{
- float_op_wrapper(argvars, rettv, &cosh);
-}
-
-/*
* "count()" function
*/
-static void f_count(typval_T *argvars, typval_T *rettv)
+static void f_count(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long n = 0;
- int ic = FALSE;
+ int ic = 0;
+ bool error = false;
- if (argvars[0].v_type == VAR_LIST) {
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ ic = tv_get_number_chk(&argvars[2], &error);
+ }
+
+ if (argvars[0].v_type == VAR_STRING) {
+ const char_u *expr = (char_u *)tv_get_string_chk(&argvars[1]);
+ const char_u *p = argvars[0].vval.v_string;
+
+ if (!error && expr != NULL && *expr != NUL && p != NULL) {
+ if (ic) {
+ const size_t len = STRLEN(expr);
+
+ while (*p != NUL) {
+ if (mb_strnicmp(p, expr, len) == 0) {
+ n++;
+ p += len;
+ } else {
+ MB_PTR_ADV(p);
+ }
+ }
+ } else {
+ char_u *next;
+ while ((next = (char_u *)strstr((char *)p, (char *)expr)) != NULL) {
+ n++;
+ p = next + STRLEN(expr);
+ }
+ }
+ }
+ } else if (argvars[0].v_type == VAR_LIST) {
listitem_T *li;
list_T *l;
long idx;
if ((l = argvars[0].vval.v_list) != NULL) {
- li = l->lv_first;
+ li = tv_list_first(l);
if (argvars[2].v_type != VAR_UNKNOWN) {
- int error = FALSE;
-
- ic = get_tv_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN) {
- idx = get_tv_number_chk(&argvars[3], &error);
+ idx = tv_get_number_chk(&argvars[3], &error);
if (!error) {
- li = list_find(l, idx);
- if (li == NULL)
+ li = tv_list_find(l, idx);
+ if (li == NULL) {
EMSGN(_(e_listidx), idx);
+ }
}
}
if (error)
li = NULL;
}
- for (; li != NULL; li = li->li_next)
- if (tv_equal(&li->li_tv, &argvars[1], ic, FALSE))
- ++n;
+ for (; li != NULL; li = TV_LIST_ITEM_NEXT(l, li)) {
+ if (tv_equal(TV_LIST_ITEM_TV(li), &argvars[1], ic, false)) {
+ n++;
+ }
+ }
}
} else if (argvars[0].v_type == VAR_DICT) {
int todo;
@@ -8380,25 +7684,25 @@ static void f_count(typval_T *argvars, typval_T *rettv)
hashitem_T *hi;
if ((d = argvars[0].vval.v_dict) != NULL) {
- int error = FALSE;
-
if (argvars[2].v_type != VAR_UNKNOWN) {
- ic = get_tv_number_chk(&argvars[2], &error);
- if (argvars[3].v_type != VAR_UNKNOWN)
+ if (argvars[3].v_type != VAR_UNKNOWN) {
EMSG(_(e_invarg));
+ }
}
todo = error ? 0 : (int)d->dv_hashtab.ht_used;
for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
if (!HASHITEM_EMPTY(hi)) {
- --todo;
- if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic, FALSE))
- ++n;
+ todo--;
+ if (tv_equal(&TV_DICT_HI2DI(hi)->di_tv, &argvars[1], ic, false)) {
+ n++;
+ }
}
}
}
- } else
+ } else {
EMSG2(_(e_listdictarg), "count()");
+ }
rettv->vval.v_number = n;
}
@@ -8407,22 +7711,24 @@ static void f_count(typval_T *argvars, typval_T *rettv)
*
* Checks the existence of a cscope connection.
*/
-static void f_cscope_connection(typval_T *argvars, typval_T *rettv)
+static void f_cscope_connection(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int num = 0;
- char_u *dbpath = NULL;
- char_u *prepend = NULL;
- char_u buf[NUMBUFLEN];
+ const char *dbpath = NULL;
+ const char *prepend = NULL;
+ char buf[NUMBUFLEN];
if (argvars[0].v_type != VAR_UNKNOWN
&& argvars[1].v_type != VAR_UNKNOWN) {
- num = (int)get_tv_number(&argvars[0]);
- dbpath = get_tv_string(&argvars[1]);
- if (argvars[2].v_type != VAR_UNKNOWN)
- prepend = get_tv_string_buf(&argvars[2], buf);
+ num = (int)tv_get_number(&argvars[0]);
+ dbpath = tv_get_string(&argvars[1]);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ prepend = tv_get_string_buf(&argvars[2], buf);
+ }
}
- rettv->vval.v_number = cs_connection(num, dbpath, prepend);
+ rettv->vval.v_number = cs_connection(num, (char_u *)dbpath,
+ (char_u *)prepend);
}
/// "cursor(lnum, col)" function, or
@@ -8431,7 +7737,7 @@ static void f_cscope_connection(typval_T *argvars, typval_T *rettv)
/// Moves the cursor to the specified line and column.
///
/// @returns 0 when the position could be set, -1 otherwise.
-static void f_cursor(typval_T *argvars, typval_T *rettv)
+static void f_cursor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
long line, col;
long coladd = 0;
@@ -8455,10 +7761,10 @@ static void f_cursor(typval_T *argvars, typval_T *rettv)
set_curswant = false;
}
} else {
- line = get_tv_lnum(argvars);
- col = get_tv_number_chk(&argvars[1], NULL);
+ line = tv_get_lnum(argvars);
+ col = (long)tv_get_number_chk(&argvars[1], NULL);
if (argvars[2].v_type != VAR_UNKNOWN) {
- coladd = get_tv_number_chk(&argvars[2], NULL);
+ coladd = (long)tv_get_number_chk(&argvars[2], NULL);
}
}
if (line < 0 || col < 0
@@ -8487,12 +7793,13 @@ static void f_cursor(typval_T *argvars, typval_T *rettv)
/*
* "deepcopy()" function
*/
-static void f_deepcopy(typval_T *argvars, typval_T *rettv)
+static void f_deepcopy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int noref = 0;
- if (argvars[1].v_type != VAR_UNKNOWN)
- noref = get_tv_number_chk(&argvars[1], NULL);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ noref = tv_get_number_chk(&argvars[1], NULL);
+ }
if (noref < 0 || noref > 1) {
EMSG(_(e_invarg));
} else {
@@ -8503,151 +7810,118 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv)
}
// "delete()" function
-static void f_delete(typval_T *argvars, typval_T *rettv)
+static void f_delete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u nbuf[NUMBUFLEN];
- char_u *name;
- char_u *flags;
-
rettv->vval.v_number = -1;
if (check_restricted() || check_secure()) {
return;
}
- name = get_tv_string(&argvars[0]);
- if (name == NULL || *name == NUL) {
+ const char *const name = tv_get_string(&argvars[0]);
+ if (*name == NUL) {
EMSG(_(e_invarg));
return;
}
+ char nbuf[NUMBUFLEN];
+ const char *flags;
if (argvars[1].v_type != VAR_UNKNOWN) {
- flags = get_tv_string_buf(&argvars[1], nbuf);
+ flags = tv_get_string_buf(&argvars[1], nbuf);
} else {
- flags = (char_u *)"";
+ flags = "";
}
if (*flags == NUL) {
// delete a file
- rettv->vval.v_number = os_remove((char *)name) == 0 ? 0 : -1;
- } else if (STRCMP(flags, "d") == 0) {
+ rettv->vval.v_number = os_remove(name) == 0 ? 0 : -1;
+ } else if (strcmp(flags, "d") == 0) {
// delete an empty directory
- rettv->vval.v_number = os_rmdir((char *)name) == 0 ? 0 : -1;
- } else if (STRCMP(flags, "rf") == 0) {
+ rettv->vval.v_number = os_rmdir(name) == 0 ? 0 : -1;
+ } else if (strcmp(flags, "rf") == 0) {
// delete a directory recursively
rettv->vval.v_number = delete_recursive(name);
} else {
- EMSG2(_(e_invexpr2), flags);
+ emsgf(_(e_invexpr2), flags);
}
}
// dictwatcheradd(dict, key, funcref) function
-static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv)
+static void f_dictwatcheradd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
return;
}
if (argvars[0].v_type != VAR_DICT) {
- EMSG2(e_invarg2, "dict");
+ emsgf(_(e_invarg2), "dict");
return;
- }
-
- if (argvars[1].v_type != VAR_STRING && argvars[1].v_type != VAR_NUMBER) {
- EMSG2(e_invarg2, "key");
+ } else if (argvars[0].vval.v_dict == NULL) {
+ const char *const arg_errmsg = _("dictwatcheradd() argument");
+ const size_t arg_errmsg_len = strlen(arg_errmsg);
+ emsgf(_(e_readonlyvar), (int)arg_errmsg_len, arg_errmsg);
return;
}
- if (argvars[2].v_type != VAR_FUNC && argvars[2].v_type != VAR_STRING) {
- EMSG2(e_invarg2, "funcref");
+ if (argvars[1].v_type != VAR_STRING && argvars[1].v_type != VAR_NUMBER) {
+ emsgf(_(e_invarg2), "key");
return;
}
- char *key_pattern = (char *)get_tv_string_chk(argvars + 1);
- assert(key_pattern);
- const size_t key_len = STRLEN(argvars[1].vval.v_string);
-
- if (key_len == 0) {
- EMSG(_(e_emptykey));
+ const char *const key_pattern = tv_get_string_chk(argvars + 1);
+ if (key_pattern == NULL) {
return;
}
+ const size_t key_pattern_len = strlen(key_pattern);
- ufunc_T *func = find_ufunc(argvars[2].vval.v_string);
- if (!func) {
- // Invalid function name. Error already reported by `find_ufunc`.
+ Callback callback;
+ if (!callback_from_typval(&callback, &argvars[2])) {
+ emsgf(_(e_invarg2), "funcref");
return;
}
- func->uf_refcount++;
- DictWatcher *watcher = xmalloc(sizeof(DictWatcher));
- watcher->key_pattern = xmemdupz(key_pattern, key_len);
- watcher->callback = func;
- watcher->busy = false;
- QUEUE_INSERT_TAIL(&argvars[0].vval.v_dict->watchers, &watcher->node);
+ tv_dict_watcher_add(argvars[0].vval.v_dict, key_pattern, key_pattern_len,
+ callback);
}
// dictwatcherdel(dict, key, funcref) function
-static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv)
+static void f_dictwatcherdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
return;
}
if (argvars[0].v_type != VAR_DICT) {
- EMSG2(e_invarg2, "dict");
- return;
- }
-
- if (argvars[1].v_type != VAR_STRING && argvars[1].v_type != VAR_NUMBER) {
- EMSG2(e_invarg2, "key");
+ emsgf(_(e_invarg2), "dict");
return;
}
if (argvars[2].v_type != VAR_FUNC && argvars[2].v_type != VAR_STRING) {
- EMSG2(e_invarg2, "funcref");
+ emsgf(_(e_invarg2), "funcref");
return;
}
- char *key_pattern = (char *)get_tv_string_chk(argvars + 1);
- assert(key_pattern);
- const size_t key_len = STRLEN(argvars[1].vval.v_string);
-
- if (key_len == 0) {
- EMSG(_(e_emptykey));
+ const char *const key_pattern = tv_get_string_chk(argvars + 1);
+ if (key_pattern == NULL) {
return;
}
- ufunc_T *func = find_ufunc(argvars[2].vval.v_string);
- if (!func) {
- // Invalid function name. Error already reported by `find_ufunc`.
+ Callback callback;
+ if (!callback_from_typval(&callback, &argvars[2])) {
return;
}
- dict_T *dict = argvars[0].vval.v_dict;
- QUEUE *w = NULL;
- DictWatcher *watcher = NULL;
- bool matched = false;
- QUEUE_FOREACH(w, &dict->watchers) {
- watcher = dictwatcher_node_data(w);
- if (func == watcher->callback
- && !strcmp(watcher->key_pattern, key_pattern)) {
- matched = true;
- break;
- }
- }
-
- if (!matched) {
+ if (!tv_dict_watcher_remove(argvars[0].vval.v_dict, key_pattern,
+ strlen(key_pattern), callback)) {
EMSG("Couldn't find a watcher matching key and callback");
- return;
}
- QUEUE_REMOVE(w);
- dictwatcher_free(watcher);
+ callback_free(&callback);
}
/*
* "did_filetype()" function
*/
-static void f_did_filetype(typval_T *argvars, typval_T *rettv)
+static void f_did_filetype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = did_filetype;
}
@@ -8655,17 +7929,17 @@ static void f_did_filetype(typval_T *argvars, typval_T *rettv)
/*
* "diff_filler()" function
*/
-static void f_diff_filler(typval_T *argvars, typval_T *rettv)
+static void f_diff_filler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars));
+ rettv->vval.v_number = diff_check_fill(curwin, tv_get_lnum(argvars));
}
/*
* "diff_hlID()" function
*/
-static void f_diff_hlID(typval_T *argvars, typval_T *rettv)
+static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum = get_tv_lnum(argvars);
+ linenr_T lnum = tv_get_lnum(argvars);
static linenr_T prev_lnum = 0;
static int changedtick = 0;
static int fnum = 0;
@@ -8678,7 +7952,7 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv)
if (lnum < 0) /* ignore type error in {lnum} arg */
lnum = 0;
if (lnum != prev_lnum
- || changedtick != curbuf->b_changedtick
+ || changedtick != buf_get_changedtick(curbuf)
|| fnum != curbuf->b_fnum) {
/* New line, buffer, change: need to get the values. */
filler_lines = diff_check(curwin, lnum);
@@ -8695,16 +7969,17 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv)
} else
hlID = (hlf_T)0;
prev_lnum = lnum;
- changedtick = curbuf->b_changedtick;
+ changedtick = buf_get_changedtick(curbuf);
fnum = curbuf->b_fnum;
}
if (hlID == HLF_CHD || hlID == HLF_TXD) {
- col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */
- if (col >= change_start && col <= change_end)
- hlID = HLF_TXD; /* changed text */
- else
- hlID = HLF_CHD; /* changed line */
+ col = tv_get_number(&argvars[1]) - 1; // Ignore type error in {col}.
+ if (col >= change_start && col <= change_end) {
+ hlID = HLF_TXD; // Changed text.
+ } else {
+ hlID = HLF_CHD; // Changed line.
+ }
}
rettv->vval.v_number = hlID == (hlf_T)0 ? 0 : (int)hlID;
}
@@ -8712,36 +7987,56 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv)
/*
* "empty({expr})" function
*/
-static void f_empty(typval_T *argvars, typval_T *rettv)
+static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
bool n = true;
switch (argvars[0].v_type) {
- case VAR_STRING:
- case VAR_FUNC:
- n = argvars[0].vval.v_string == NULL
- || *argvars[0].vval.v_string == NUL;
- break;
- case VAR_NUMBER:
- n = argvars[0].vval.v_number == 0;
- break;
- case VAR_FLOAT:
- n = argvars[0].vval.v_float == 0.0;
- break;
- case VAR_LIST:
- n = argvars[0].vval.v_list == NULL
- || argvars[0].vval.v_list->lv_first == NULL;
- break;
- case VAR_DICT:
- n = argvars[0].vval.v_dict == NULL
- || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0;
- break;
- case VAR_SPECIAL:
- n = argvars[0].vval.v_special != kSpecialVarTrue;
- break;
- case VAR_UNKNOWN:
- EMSG2(_(e_intern2), "f_empty(UNKNOWN)");
- break;
+ case VAR_STRING:
+ case VAR_FUNC: {
+ n = argvars[0].vval.v_string == NULL
+ || *argvars[0].vval.v_string == NUL;
+ break;
+ }
+ case VAR_PARTIAL: {
+ n = false;
+ break;
+ }
+ case VAR_NUMBER: {
+ n = argvars[0].vval.v_number == 0;
+ break;
+ }
+ case VAR_FLOAT: {
+ n = argvars[0].vval.v_float == 0.0;
+ break;
+ }
+ case VAR_LIST: {
+ n = (tv_list_len(argvars[0].vval.v_list) == 0);
+ break;
+ }
+ case VAR_DICT: {
+ n = (tv_dict_len(argvars[0].vval.v_dict) == 0);
+ break;
+ }
+ case VAR_SPECIAL: {
+ // Using switch to get warning if SpecialVarValue receives more values.
+ switch (argvars[0].vval.v_special) {
+ case kSpecialVarTrue: {
+ n = false;
+ break;
+ }
+ case kSpecialVarFalse:
+ case kSpecialVarNull: {
+ n = true;
+ break;
+ }
+ }
+ break;
+ }
+ case VAR_UNKNOWN: {
+ internal_error("f_empty(UNKNOWN)");
+ break;
+ }
}
rettv->vval.v_number = n;
@@ -8750,30 +8045,30 @@ static void f_empty(typval_T *argvars, typval_T *rettv)
/*
* "escape({string}, {chars})" function
*/
-static void f_escape(typval_T *argvars, typval_T *rettv)
+static void f_escape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
+ char buf[NUMBUFLEN];
- rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]),
- get_tv_string_buf(&argvars[1], buf));
+ rettv->vval.v_string = vim_strsave_escaped(
+ (const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1], buf));
rettv->v_type = VAR_STRING;
}
/*
* "eval()" function
*/
-static void f_eval(typval_T *argvars, typval_T *rettv)
+static void f_eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s;
-
- s = get_tv_string_chk(&argvars[0]);
- if (s != NULL)
- s = skipwhite(s);
+ const char *s = tv_get_string_chk(&argvars[0]);
+ if (s != NULL) {
+ s = (const char *)skipwhite((const char_u *)s);
+ }
- char_u *p = s;
- if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) {
- if (p != NULL && !aborting()) {
- EMSG2(_(e_invexpr2), p);
+ const char *const expr_start = s;
+ if (s == NULL || eval1((char_u **)&s, rettv, true) == FAIL) {
+ if (expr_start != NULL && !aborting()) {
+ EMSG2(_(e_invexpr2), expr_start);
}
need_clr_eos = FALSE;
rettv->v_type = VAR_NUMBER;
@@ -8786,7 +8081,7 @@ static void f_eval(typval_T *argvars, typval_T *rettv)
/*
* "eventhandler()" function
*/
-static void f_eventhandler(typval_T *argvars, typval_T *rettv)
+static void f_eventhandler(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = vgetc_busy;
}
@@ -8794,22 +8089,104 @@ static void f_eventhandler(typval_T *argvars, typval_T *rettv)
/*
* "executable()" function
*/
-static void f_executable(typval_T *argvars, typval_T *rettv)
+static void f_executable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *name = get_tv_string(&argvars[0]);
+ const char *name = tv_get_string(&argvars[0]);
// Check in $PATH and also check directly if there is a directory name
- rettv->vval.v_number = os_can_exe(name, NULL, true)
- || (gettail_dir(name) != name && os_can_exe(name, NULL, false));
+ rettv->vval.v_number = (
+ os_can_exe((const char_u *)name, NULL, true)
+ || (gettail_dir(name) != name
+ && os_can_exe((const char_u *)name, NULL, false)));
+}
+
+typedef struct {
+ const list_T *const l;
+ const listitem_T *li;
+} GetListLineCookie;
+
+static char_u *get_list_line(int c, void *cookie, int indent)
+{
+ GetListLineCookie *const p = (GetListLineCookie *)cookie;
+
+ const listitem_T *const item = p->li;
+ if (item == NULL) {
+ return NULL;
+ }
+ char buf[NUMBUFLEN];
+ const char *const s = tv_get_string_buf_chk(TV_LIST_ITEM_TV(item), buf);
+ p->li = TV_LIST_ITEM_NEXT(p->l, item);
+ return (char_u *)(s == NULL ? NULL : xstrdup(s));
+}
+
+// "execute(command)" function
+static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ const int save_msg_silent = msg_silent;
+ const int save_emsg_silent = emsg_silent;
+ const bool save_emsg_noredir = emsg_noredir;
+ const bool save_redir_off = redir_off;
+ garray_T *const save_capture_ga = capture_ga;
+
+ if (check_secure()) {
+ return;
+ }
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ char buf[NUMBUFLEN];
+ const char *const s = tv_get_string_buf_chk(&argvars[1], buf);
+
+ if (s == NULL) {
+ return;
+ }
+ if (strncmp(s, "silent", 6) == 0) {
+ msg_silent++;
+ }
+ if (strcmp(s, "silent!") == 0) {
+ emsg_silent = true;
+ emsg_noredir = true;
+ }
+ } else {
+ msg_silent++;
+ }
+
+ garray_T capture_local;
+ ga_init(&capture_local, (int)sizeof(char), 80);
+ capture_ga = &capture_local;
+ redir_off = false;
+
+ if (argvars[0].v_type != VAR_LIST) {
+ do_cmdline_cmd(tv_get_string(&argvars[0]));
+ } else if (argvars[0].vval.v_list != NULL) {
+ list_T *const list = argvars[0].vval.v_list;
+ tv_list_ref(list);
+ GetListLineCookie cookie = {
+ .l = list,
+ .li = tv_list_first(list),
+ };
+ do_cmdline(NULL, get_list_line, (void *)&cookie,
+ DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED);
+ tv_list_unref(list);
+ }
+ msg_silent = save_msg_silent;
+ emsg_silent = save_emsg_silent;
+ emsg_noredir = save_emsg_noredir;
+ redir_off = save_redir_off;
+
+ ga_append(capture_ga, NUL);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = capture_ga->ga_data;
+
+ capture_ga = save_capture_ga;
}
/// "exepath()" function
-static void f_exepath(typval_T *argvars, typval_T *rettv)
+static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *arg = get_tv_string(&argvars[0]);
+ const char *arg = tv_get_string(&argvars[0]);
char_u *path = NULL;
- (void)os_can_exe(arg, &path, true);
+ (void)os_can_exe((const char_u *)arg, &path, true);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = path;
@@ -8818,55 +8195,57 @@ static void f_exepath(typval_T *argvars, typval_T *rettv)
/*
* "exists()" function
*/
-static void f_exists(typval_T *argvars, typval_T *rettv)
+static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
- char_u *name;
- int n = FALSE;
+ int n = false;
int len = 0;
- p = get_tv_string(&argvars[0]);
- if (*p == '$') { /* environment variable */
- /* first try "normal" environment variables (fast) */
- if (os_getenv((char *)(p + 1)) != NULL)
- n = TRUE;
- else {
- /* try expanding things like $VIM and ${HOME} */
- p = expand_env_save(p);
- if (p != NULL && *p != '$')
- n = TRUE;
- xfree(p);
+ const char *p = tv_get_string(&argvars[0]);
+ if (*p == '$') { // Environment variable.
+ // First try "normal" environment variables (fast).
+ if (os_getenv(p + 1) != NULL) {
+ n = true;
+ } else {
+ // Try expanding things like $VIM and ${HOME}.
+ char_u *const exp = expand_env_save((char_u *)p);
+ if (exp != NULL && *exp != '$') {
+ n = true;
+ }
+ xfree(exp);
}
- } else if (*p == '&' || *p == '+') { /* option */
- n = (get_option_tv(&p, NULL, TRUE) == OK);
- if (*skipwhite(p) != NUL)
- n = FALSE; /* trailing garbage */
- } else if (*p == '*') { /* internal or user defined function */
- n = function_exists(p + 1);
+ } else if (*p == '&' || *p == '+') { // Option.
+ n = (get_option_tv(&p, NULL, true) == OK);
+ if (*skipwhite((const char_u *)p) != NUL) {
+ n = false; // Trailing garbage.
+ }
+ } else if (*p == '*') { // Internal or user defined function.
+ n = function_exists(p + 1, false);
} else if (*p == ':') {
n = cmd_exists(p + 1);
} else if (*p == '#') {
- if (p[1] == '#')
+ if (p[1] == '#') {
n = autocmd_supported(p + 2);
- else
+ } else {
n = au_exists(p + 1);
- } else { /* internal variable */
- char_u *tofree;
+ }
+ } else { // Internal variable.
typval_T tv;
- /* get_name_len() takes care of expanding curly braces */
- name = p;
- len = get_name_len(&p, &tofree, TRUE, FALSE);
+ // get_name_len() takes care of expanding curly braces
+ const char *name = p;
+ char *tofree;
+ len = get_name_len((const char **)&p, &tofree, true, false);
if (len > 0) {
if (tofree != NULL) {
name = tofree;
}
n = (get_var_tv(name, len, &tv, NULL, false, true) == OK);
if (n) {
- /* handle d.key, l[idx], f(expr) */
- n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK);
- if (n)
- clear_tv(&tv);
+ // Handle d.key, l[idx], f(expr).
+ n = (handle_subscript(&p, &tv, true, false) == OK);
+ if (n) {
+ tv_clear(&tv);
+ }
}
}
if (*p != NUL)
@@ -8879,44 +8258,34 @@ static void f_exists(typval_T *argvars, typval_T *rettv)
}
/*
- * "exp()" function
- */
-static void f_exp(typval_T *argvars, typval_T *rettv)
-{
- float_op_wrapper(argvars, rettv, &exp);
-}
-
-/*
* "expand()" function
*/
-static void f_expand(typval_T *argvars, typval_T *rettv)
+static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s;
size_t len;
char_u *errormsg;
int options = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND;
expand_T xpc;
- int error = FALSE;
- char_u *result;
+ bool error = false;
+ char_u *result;
rettv->v_type = VAR_STRING;
if (argvars[1].v_type != VAR_UNKNOWN
&& argvars[2].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[2], &error)
+ && tv_get_number_chk(&argvars[2], &error)
&& !error) {
- rettv->v_type = VAR_LIST;
- rettv->vval.v_list = NULL;
+ tv_list_set_ret(rettv, NULL);
}
- s = get_tv_string(&argvars[0]);
+ const char *s = tv_get_string(&argvars[0]);
if (*s == '%' || *s == '#' || *s == '<') {
- ++emsg_off;
- result = eval_vars(s, s, &len, NULL, &errormsg, NULL);
- --emsg_off;
+ emsg_off++;
+ result = eval_vars((char_u *)s, (char_u *)s, &len, NULL, &errormsg, NULL);
+ emsg_off--;
if (rettv->v_type == VAR_LIST) {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, (result != NULL));
if (result != NULL) {
- list_append_string(rettv->vval.v_list, result, -1);
+ tv_list_append_string(rettv->vval.v_list, (const char *)result, -1);
}
} else
rettv->vval.v_string = result;
@@ -8924,262 +8293,217 @@ static void f_expand(typval_T *argvars, typval_T *rettv)
/* When the optional second argument is non-zero, don't remove matches
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
if (argvars[1].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[1], &error))
+ && tv_get_number_chk(&argvars[1], &error)) {
options |= WILD_KEEP_ALL;
+ }
if (!error) {
ExpandInit(&xpc);
xpc.xp_context = EXPAND_FILES;
- if (p_wic)
+ if (p_wic) {
options += WILD_ICASE;
- if (rettv->v_type == VAR_STRING)
- rettv->vval.v_string = ExpandOne(&xpc, s, NULL,
- options, WILD_ALL);
- else {
- rettv_list_alloc(rettv);
- ExpandOne(&xpc, s, NULL, options, WILD_ALL_KEEP);
+ }
+ if (rettv->v_type == VAR_STRING) {
+ rettv->vval.v_string = ExpandOne(&xpc, (char_u *)s, NULL, options,
+ WILD_ALL);
+ } else {
+ ExpandOne(&xpc, (char_u *)s, NULL, options, WILD_ALL_KEEP);
+ tv_list_alloc_ret(rettv, xpc.xp_numfiles);
for (int i = 0; i < xpc.xp_numfiles; i++) {
- list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)xpc.xp_files[i], -1);
}
ExpandCleanup(&xpc);
}
- } else
+ } else {
rettv->vval.v_string = NULL;
+ }
}
}
-/*
- * Go over all entries in "d2" and add them to "d1".
- * When "action" is "error" then a duplicate key is an error.
- * When "action" is "force" then a duplicate key is overwritten.
- * Otherwise duplicate keys are ignored ("action" is "keep").
- */
-void dict_extend(dict_T *d1, dict_T *d2, char_u *action)
-{
- dictitem_T *di1;
- hashitem_T *hi2;
- int todo;
- bool watched = is_watched(d1);
- char_u *arg_errmsg = (char_u *)N_("extend() argument");
-
- todo = (int)d2->dv_hashtab.ht_used;
- for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) {
- if (!HASHITEM_EMPTY(hi2)) {
- --todo;
- di1 = dict_find(d1, hi2->hi_key, -1);
- if (d1->dv_scope != 0) {
- /* Disallow replacing a builtin function in l: and g:.
- * Check the key to be valid when adding to any
- * scope. */
- if (d1->dv_scope == VAR_DEF_SCOPE
- && HI2DI(hi2)->di_tv.v_type == VAR_FUNC
- && var_check_func_name(hi2->hi_key,
- di1 == NULL))
- break;
- if (!valid_varname(hi2->hi_key))
- break;
- }
- if (di1 == NULL) {
- di1 = dictitem_copy(HI2DI(hi2));
- if (dict_add(d1, di1) == FAIL) {
- dictitem_free(di1);
- }
-
- if (watched) {
- dictwatcher_notify(d1, (char *)di1->di_key, &di1->di_tv, NULL);
- }
- } else if (*action == 'e') {
- EMSG2(_("E737: Key already exists: %s"), hi2->hi_key);
- break;
- } else if (*action == 'f' && HI2DI(hi2) != di1) {
- typval_T oldtv;
-
- if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, true)
- || var_check_ro(di1->di_flags, arg_errmsg, true)) {
- break;
- }
- if (watched) {
- copy_tv(&di1->di_tv, &oldtv);
- }
-
- clear_tv(&di1->di_tv);
- copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv);
-
- if (watched) {
- dictwatcher_notify(d1, (char *)di1->di_key, &di1->di_tv, &oldtv);
- clear_tv(&oldtv);
- }
- }
- }
+/// "menu_get(path [, modes])" function
+static void f_menu_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+ int modes = MENU_ALL_MODES;
+ if (argvars[1].v_type == VAR_STRING) {
+ const char_u *const strmodes = (char_u *)tv_get_string(&argvars[1]);
+ modes = get_menu_cmd_modes(strmodes, false, NULL, NULL);
}
+ menu_get((char_u *)tv_get_string(&argvars[0]), modes, rettv->vval.v_list);
}
/*
* "extend(list, list [, idx])" function
* "extend(dict, dict [, action])" function
*/
-static void f_extend(typval_T *argvars, typval_T *rettv)
+static void f_extend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *arg_errmsg = (char_u *)N_("extend() argument");
+ const char *const arg_errmsg = N_("extend() argument");
if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) {
- list_T *l1, *l2;
- listitem_T *item;
long before;
- int error = FALSE;
+ bool error = false;
- l1 = argvars[0].vval.v_list;
- l2 = argvars[1].vval.v_list;
- if (l1 != NULL && !tv_check_lock(l1->lv_lock, arg_errmsg, true)
- && l2 != NULL) {
+ list_T *const l1 = argvars[0].vval.v_list;
+ list_T *const l2 = argvars[1].vval.v_list;
+ if (!tv_check_lock(tv_list_locked(l1), arg_errmsg, TV_TRANSLATE)) {
+ listitem_T *item;
if (argvars[2].v_type != VAR_UNKNOWN) {
- before = get_tv_number_chk(&argvars[2], &error);
- if (error)
- return; /* type error; errmsg already given */
+ before = (long)tv_get_number_chk(&argvars[2], &error);
+ if (error) {
+ return; // Type error; errmsg already given.
+ }
- if (before == l1->lv_len)
+ if (before == tv_list_len(l1)) {
item = NULL;
- else {
- item = list_find(l1, before);
+ } else {
+ item = tv_list_find(l1, before);
if (item == NULL) {
EMSGN(_(e_listidx), before);
return;
}
}
- } else
+ } else {
item = NULL;
- list_extend(l1, l2, item);
+ }
+ tv_list_extend(l1, l2, item);
- copy_tv(&argvars[0], rettv);
+ tv_copy(&argvars[0], rettv);
}
} else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type ==
VAR_DICT) {
- dict_T *d1, *d2;
- char_u *action;
- int i;
-
- d1 = argvars[0].vval.v_dict;
- d2 = argvars[1].vval.v_dict;
- if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, true)
- && d2 != NULL) {
- /* Check the third argument. */
+ dict_T *const d1 = argvars[0].vval.v_dict;
+ dict_T *const d2 = argvars[1].vval.v_dict;
+ if (d1 == NULL) {
+ const bool locked = tv_check_lock(VAR_FIXED, arg_errmsg, TV_TRANSLATE);
+ (void)locked;
+ assert(locked == true);
+ } else if (d2 == NULL) {
+ // Do nothing
+ tv_copy(&argvars[0], rettv);
+ } else if (!tv_check_lock(d1->dv_lock, arg_errmsg, TV_TRANSLATE)) {
+ const char *action = "force";
+ // Check the third argument.
if (argvars[2].v_type != VAR_UNKNOWN) {
- static char *(av[]) = {"keep", "force", "error"};
+ const char *const av[] = { "keep", "force", "error" };
- action = get_tv_string_chk(&argvars[2]);
- if (action == NULL)
- return; /* type error; errmsg already given */
- for (i = 0; i < 3; ++i)
- if (STRCMP(action, av[i]) == 0)
+ action = tv_get_string_chk(&argvars[2]);
+ if (action == NULL) {
+ return; // Type error; error message already given.
+ }
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(av); i++) {
+ if (strcmp(action, av[i]) == 0) {
break;
+ }
+ }
if (i == 3) {
EMSG2(_(e_invarg2), action);
return;
}
- } else
- action = (char_u *)"force";
+ }
- dict_extend(d1, d2, action);
+ tv_dict_extend(d1, d2, action);
- copy_tv(&argvars[0], rettv);
+ tv_copy(&argvars[0], rettv);
}
- } else
+ } else {
EMSG2(_(e_listdictarg), "extend()");
+ }
}
/*
* "feedkeys()" function
*/
-static void f_feedkeys(typval_T *argvars, typval_T *rettv)
+static void f_feedkeys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *keys, *flags = NULL;
- char_u nbuf[NUMBUFLEN];
-
- /* This is not allowed in the sandbox. If the commands would still be
- * executed in the sandbox it would be OK, but it probably happens later,
- * when "sandbox" is no longer set. */
- if (check_secure())
+ // This is not allowed in the sandbox. If the commands would still be
+ // executed in the sandbox it would be OK, but it probably happens later,
+ // when "sandbox" is no longer set.
+ if (check_secure()) {
return;
+ }
- keys = get_tv_string(&argvars[0]);
- if (*keys != NUL) {
- if (argvars[1].v_type != VAR_UNKNOWN) {
- flags = get_tv_string_buf(&argvars[1], nbuf);
- }
-
- vim_feedkeys(cstr_as_string((char *)keys),
- cstr_as_string((char *)flags), true);
+ const char *const keys = tv_get_string(&argvars[0]);
+ char nbuf[NUMBUFLEN];
+ const char *flags = NULL;
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ flags = tv_get_string_buf(&argvars[1], nbuf);
}
+
+ nvim_feedkeys(cstr_as_string((char *)keys),
+ cstr_as_string((char *)flags), true);
}
/// "filereadable()" function
-static void f_filereadable(typval_T *argvars, typval_T *rettv)
+static void f_filereadable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = get_tv_string(&argvars[0]);
+ const char *const p = tv_get_string(&argvars[0]);
rettv->vval.v_number =
- (*p && !os_isdir(p) && os_file_is_readable((char*)p));
+ (*p && !os_isdir((const char_u *)p) && os_file_is_readable(p));
}
/*
* Return 0 for not writable, 1 for writable file, 2 for a dir which we have
* rights to write into.
*/
-static void f_filewritable(typval_T *argvars, typval_T *rettv)
+static void f_filewritable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char *filename = (char *)get_tv_string(&argvars[0]);
+ const char *filename = tv_get_string(&argvars[0]);
rettv->vval.v_number = os_file_is_writable(filename);
}
static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
{
- char_u *fname;
- char_u *fresult = NULL;
- char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
- char_u *p;
- char_u pathbuf[NUMBUFLEN];
+ char_u *fresult = NULL;
+ char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path;
int count = 1;
- int first = TRUE;
- int error = FALSE;
+ bool first = true;
+ bool error = false;
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
- fname = get_tv_string(&argvars[0]);
+ const char *fname = tv_get_string(&argvars[0]);
+ char pathbuf[NUMBUFLEN];
if (argvars[1].v_type != VAR_UNKNOWN) {
- p = get_tv_string_buf_chk(&argvars[1], pathbuf);
- if (p == NULL)
- error = TRUE;
- else {
- if (*p != NUL)
- path = p;
+ const char *p = tv_get_string_buf_chk(&argvars[1], pathbuf);
+ if (p == NULL) {
+ error = true;
+ } else {
+ if (*p != NUL) {
+ path = (char_u *)p;
+ }
- if (argvars[2].v_type != VAR_UNKNOWN)
- count = get_tv_number_chk(&argvars[2], &error);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ count = tv_get_number_chk(&argvars[2], &error);
+ }
}
}
if (count < 0) {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, kListLenUnknown);
}
if (*fname != NUL && !error) {
do {
if (rettv->v_type == VAR_STRING || rettv->v_type == VAR_LIST)
xfree(fresult);
- fresult = find_file_in_path_option(first ? fname : NULL,
- first ? STRLEN(fname) : 0,
+ fresult = find_file_in_path_option(first ? (char_u *)fname : NULL,
+ first ? strlen(fname) : 0,
0, first, path,
find_what, curbuf->b_ffname,
(find_what == FINDFILE_DIR
? (char_u *)""
: curbuf->b_p_sua));
- first = FALSE;
-
- if (fresult != NULL && rettv->v_type == VAR_LIST)
- list_append_string(rettv->vval.v_list, fresult, -1);
+ first = false;
+ if (fresult != NULL && rettv->v_type == VAR_LIST) {
+ tv_list_append_string(rettv->vval.v_list, (const char *)fresult, -1);
+ }
} while ((rettv->v_type == VAR_LIST || --count > 0) && fresult != NULL);
}
@@ -9193,9 +8517,7 @@ static void findfilendir(typval_T *argvars, typval_T *rettv, int find_what)
*/
static void filter_map(typval_T *argvars, typval_T *rettv, int map)
{
- char_u buf[NUMBUFLEN];
- char_u *expr;
- listitem_T *li, *nli;
+ typval_T *expr;
list_T *l = NULL;
dictitem_T *di;
hashtab_T *ht;
@@ -9203,22 +8525,26 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
dict_T *d = NULL;
typval_T save_val;
typval_T save_key;
- int rem;
+ int rem = false;
int todo;
- char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
- char_u *arg_errmsg = (char_u *)(map ? N_("map() argument")
- : N_("filter() argument"));
+ char_u *ermsg = (char_u *)(map ? "map()" : "filter()");
+ const char *const arg_errmsg = (map
+ ? N_("map() argument")
+ : N_("filter() argument"));
int save_did_emsg;
int idx = 0;
if (argvars[0].v_type == VAR_LIST) {
+ tv_copy(&argvars[0], rettv);
if ((l = argvars[0].vval.v_list) == NULL
- || (!map && tv_check_lock(l->lv_lock, arg_errmsg, true))) {
+ || (!map && tv_check_lock(tv_list_locked(l), arg_errmsg,
+ TV_TRANSLATE))) {
return;
}
} else if (argvars[0].v_type == VAR_DICT) {
+ tv_copy(&argvars[0], rettv);
if ((d = argvars[0].vval.v_dict) == NULL
- || (!map && tv_check_lock(d->dv_lock, arg_errmsg, true))) {
+ || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE))) {
return;
}
} else {
@@ -9226,16 +8552,15 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
return;
}
- expr = get_tv_string_buf_chk(&argvars[1], buf);
- /* On type errors, the preceding call has already displayed an error
- * message. Avoid a misleading error message for an empty string that
- * was not passed as argument. */
- if (expr != NULL) {
+ expr = &argvars[1];
+ // On type errors, the preceding call has already displayed an error
+ // message. Avoid a misleading error message for an empty string that
+ // was not passed as argument.
+ if (expr->v_type != VAR_UNKNOWN) {
prepare_vimvar(VV_VAL, &save_val);
- expr = skipwhite(expr);
- /* We reset "did_emsg" to be able to detect whether an error
- * occurred during evaluation of the expression. */
+ // We reset "did_emsg" to be able to detect whether an error
+ // occurred during evaluation of the expression.
save_did_emsg = did_emsg;
did_emsg = FALSE;
@@ -9250,24 +8575,25 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
if (!HASHITEM_EMPTY(hi)) {
--todo;
- di = HI2DI(hi);
+ di = TV_DICT_HI2DI(hi);
if (map
- && (tv_check_lock(di->di_tv.v_lock, arg_errmsg, true)
- || var_check_ro(di->di_flags, arg_errmsg, true))) {
+ && (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TV_TRANSLATE)
+ || var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE))) {
break;
}
vimvars[VV_KEY].vv_str = vim_strsave(di->di_key);
int r = filter_map_one(&di->di_tv, expr, map, &rem);
- clear_tv(&vimvars[VV_KEY].vv_tv);
- if (r == FAIL || did_emsg)
+ tv_clear(&vimvars[VV_KEY].vv_tv);
+ if (r == FAIL || did_emsg) {
break;
+ }
if (!map && rem) {
- if (var_check_fixed(di->di_flags, arg_errmsg, true)
- || var_check_ro(di->di_flags, arg_errmsg, true)) {
+ if (var_check_fixed(di->di_flags, arg_errmsg, TV_TRANSLATE)
+ || var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE)) {
break;
}
- dictitem_remove(d, di);
+ tv_dict_item_remove(d, di);
}
}
}
@@ -9275,18 +8601,23 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
} else {
vimvars[VV_KEY].vv_type = VAR_NUMBER;
- for (li = l->lv_first; li != NULL; li = nli) {
- if (map && tv_check_lock(li->li_tv.v_lock, arg_errmsg, true)) {
+ for (listitem_T *li = tv_list_first(l); li != NULL;) {
+ if (map
+ && tv_check_lock(TV_LIST_ITEM_TV(li)->v_lock, arg_errmsg,
+ TV_TRANSLATE)) {
break;
}
- nli = li->li_next;
vimvars[VV_KEY].vv_nr = idx;
- if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL
- || did_emsg)
+ if (filter_map_one(TV_LIST_ITEM_TV(li), expr, map, &rem) == FAIL
+ || did_emsg) {
break;
- if (!map && rem)
- listitem_remove(l, li);
- ++idx;
+ }
+ if (!map && rem) {
+ li = tv_list_item_remove(l, li);
+ } else {
+ li = TV_LIST_ITEM_NEXT(l, li);
+ }
+ idx++;
}
}
@@ -9295,51 +8626,75 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
did_emsg |= save_did_emsg;
}
-
- copy_tv(&argvars[0], rettv);
}
-static int filter_map_one(typval_T *tv, char_u *expr, int map, int *remp)
+static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
{
typval_T rettv;
- char_u *s;
+ typval_T argv[3];
int retval = FAIL;
+ int dummy;
- copy_tv(tv, &vimvars[VV_VAL].vv_tv);
- s = expr;
- if (eval1(&s, &rettv, TRUE) == FAIL)
- goto theend;
- if (*s != NUL) { /* check for trailing chars after expr */
- EMSG2(_(e_invexpr2), s);
- clear_tv(&rettv);
- goto theend;
+ tv_copy(tv, &vimvars[VV_VAL].vv_tv);
+ argv[0] = vimvars[VV_KEY].vv_tv;
+ argv[1] = vimvars[VV_VAL].vv_tv;
+ if (expr->v_type == VAR_FUNC) {
+ const char_u *const s = expr->vval.v_string;
+ if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
+ 0L, 0L, &dummy, true, NULL, NULL) == FAIL) {
+ goto theend;
+ }
+ } else if (expr->v_type == VAR_PARTIAL) {
+ partial_T *partial = expr->vval.v_partial;
+
+ const char_u *const s = partial_name(partial);
+ if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL,
+ 0L, 0L, &dummy, true, partial, NULL) == FAIL) {
+ goto theend;
+ }
+ } else {
+ char buf[NUMBUFLEN];
+ const char *s = tv_get_string_buf_chk(expr, buf);
+ if (s == NULL) {
+ goto theend;
+ }
+ s = (const char *)skipwhite((const char_u *)s);
+ if (eval1((char_u **)&s, &rettv, true) == FAIL) {
+ goto theend;
+ }
+
+ if (*s != NUL) { // check for trailing chars after expr
+ emsgf(_(e_invexpr2), s);
+ goto theend;
+ }
}
if (map) {
- /* map(): replace the list item value */
- clear_tv(tv);
+ // map(): replace the list item value.
+ tv_clear(tv);
rettv.v_lock = 0;
*tv = rettv;
} else {
- int error = FALSE;
-
- /* filter(): when expr is zero remove the item */
- *remp = (get_tv_number_chk(&rettv, &error) == 0);
- clear_tv(&rettv);
- /* On type error, nothing has been removed; return FAIL to stop the
- * loop. The error message was given by get_tv_number_chk(). */
- if (error)
+ bool error = false;
+
+ // filter(): when expr is zero remove the item
+ *remp = (tv_get_number_chk(&rettv, &error) == 0);
+ tv_clear(&rettv);
+ // On type error, nothing has been removed; return FAIL to stop the
+ // loop. The error message was given by tv_get_number_chk().
+ if (error) {
goto theend;
+ }
}
retval = OK;
theend:
- clear_tv(&vimvars[VV_VAL].vv_tv);
+ tv_clear(&vimvars[VV_VAL].vv_tv);
return retval;
}
/*
* "filter()" function
*/
-static void f_filter(typval_T *argvars, typval_T *rettv)
+static void f_filter(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
filter_map(argvars, rettv, FALSE);
}
@@ -9347,7 +8702,7 @@ static void f_filter(typval_T *argvars, typval_T *rettv)
/*
* "finddir({fname}[, {path}[, {count}]])" function
*/
-static void f_finddir(typval_T *argvars, typval_T *rettv)
+static void f_finddir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
findfilendir(argvars, rettv, FINDFILE_DIR);
}
@@ -9355,7 +8710,7 @@ static void f_finddir(typval_T *argvars, typval_T *rettv)
/*
* "findfile({fname}[, {path}[, {count}]])" function
*/
-static void f_findfile(typval_T *argvars, typval_T *rettv)
+static void f_findfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
findfilendir(argvars, rettv, FINDFILE_FILE);
}
@@ -9363,79 +8718,72 @@ static void f_findfile(typval_T *argvars, typval_T *rettv)
/*
* "float2nr({float})" function
*/
-static void f_float2nr(typval_T *argvars, typval_T *rettv)
+static void f_float2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
float_T f;
- if (get_float_arg(argvars, &f) == OK) {
- if (f < -0x7fffffff)
- rettv->vval.v_number = -0x7fffffff;
- else if (f > 0x7fffffff)
- rettv->vval.v_number = 0x7fffffff;
- else
+ if (tv_get_float_chk(argvars, &f)) {
+ if (f <= -VARNUMBER_MAX + DBL_EPSILON) {
+ rettv->vval.v_number = -VARNUMBER_MAX;
+ } else if (f >= VARNUMBER_MAX - DBL_EPSILON) {
+ rettv->vval.v_number = VARNUMBER_MAX;
+ } else {
rettv->vval.v_number = (varnumber_T)f;
+ }
}
}
/*
- * "floor({float})" function
- */
-static void f_floor(typval_T *argvars, typval_T *rettv)
-{
- float_op_wrapper(argvars, rettv, &floor);
-}
-
-/*
* "fmod()" function
*/
-static void f_fmod(typval_T *argvars, typval_T *rettv)
+static void f_fmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_T fx, fy;
+ float_T fx;
+ float_T fy;
rettv->v_type = VAR_FLOAT;
- if (get_float_arg(argvars, &fx) == OK
- && get_float_arg(&argvars[1], &fy) == OK)
+ if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) {
rettv->vval.v_float = fmod(fx, fy);
- else
+ } else {
rettv->vval.v_float = 0.0;
+ }
}
/*
* "fnameescape({string})" function
*/
-static void f_fnameescape(typval_T *argvars, typval_T *rettv)
+static void f_fnameescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_string = vim_strsave_fnameescape(
- get_tv_string(&argvars[0]), FALSE);
+ rettv->vval.v_string = (char_u *)vim_strsave_fnameescape(
+ tv_get_string(&argvars[0]), false);
rettv->v_type = VAR_STRING;
}
/*
* "fnamemodify({fname}, {mods})" function
*/
-static void f_fnamemodify(typval_T *argvars, typval_T *rettv)
+static void f_fnamemodify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *fname;
- char_u *mods;
- size_t usedlen = 0;
+ char_u *fbuf = NULL;
size_t len;
- char_u *fbuf = NULL;
- char_u buf[NUMBUFLEN];
-
- fname = get_tv_string_chk(&argvars[0]);
- mods = get_tv_string_buf_chk(&argvars[1], buf);
- if (fname == NULL || mods == NULL)
+ char buf[NUMBUFLEN];
+ const char *fname = tv_get_string_chk(&argvars[0]);
+ const char *const mods = tv_get_string_buf_chk(&argvars[1], buf);
+ if (fname == NULL || mods == NULL) {
fname = NULL;
- else {
- len = STRLEN(fname);
- (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len);
+ } else {
+ len = strlen(fname);
+ size_t usedlen = 0;
+ (void)modify_fname((char_u *)mods, &usedlen, (char_u **)&fname, &fbuf,
+ &len);
}
rettv->v_type = VAR_STRING;
- if (fname == NULL)
+ if (fname == NULL) {
rettv->vval.v_string = NULL;
- else
- rettv->vval.v_string = vim_strnsave(fname, len);
+ } else {
+ rettv->vval.v_string = (char_u *)xmemdupz(fname, len);
+ }
xfree(fbuf);
}
@@ -9445,16 +8793,16 @@ static void f_fnamemodify(typval_T *argvars, typval_T *rettv)
*/
static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
{
- linenr_T lnum;
- linenr_T first, last;
-
- lnum = get_tv_lnum(argvars);
+ const linenr_T lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
- if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) {
- if (end)
+ linenr_T first;
+ linenr_T last;
+ if (hasFoldingWin(curwin, lnum, &first, &last, false, NULL)) {
+ if (end) {
rettv->vval.v_number = (varnumber_T)last;
- else
+ } else {
rettv->vval.v_number = (varnumber_T)first;
+ }
return;
}
}
@@ -9464,7 +8812,7 @@ static void foldclosed_both(typval_T *argvars, typval_T *rettv, int end)
/*
* "foldclosed()" function
*/
-static void f_foldclosed(typval_T *argvars, typval_T *rettv)
+static void f_foldclosed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, FALSE);
}
@@ -9472,7 +8820,7 @@ static void f_foldclosed(typval_T *argvars, typval_T *rettv)
/*
* "foldclosedend()" function
*/
-static void f_foldclosedend(typval_T *argvars, typval_T *rettv)
+static void f_foldclosedend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
foldclosed_both(argvars, rettv, TRUE);
}
@@ -9480,38 +8828,40 @@ static void f_foldclosedend(typval_T *argvars, typval_T *rettv)
/*
* "foldlevel()" function
*/
-static void f_foldlevel(typval_T *argvars, typval_T *rettv)
+static void f_foldlevel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
-
- lnum = get_tv_lnum(argvars);
- if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
rettv->vval.v_number = foldLevel(lnum);
+ }
}
/*
* "foldtext()" function
*/
-static void f_foldtext(typval_T *argvars, typval_T *rettv)
+static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
+ linenr_T foldstart;
+ linenr_T foldend;
+ char_u *dashes;
+ linenr_T lnum;
char_u *s;
char_u *r;
- int len;
+ int len;
char *txt;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0
- && (linenr_T)vimvars[VV_FOLDEND].vv_nr
- <= curbuf->b_ml.ml_line_count
- && vimvars[VV_FOLDDASHES].vv_str != NULL) {
- /* Find first non-empty line in the fold. */
- lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr;
- while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) {
- if (!linewhite(lnum))
+
+ foldstart = (linenr_T)get_vim_var_nr(VV_FOLDSTART);
+ foldend = (linenr_T)get_vim_var_nr(VV_FOLDEND);
+ dashes = get_vim_var_str(VV_FOLDDASHES);
+ if (foldstart > 0 && foldend <= curbuf->b_ml.ml_line_count) {
+ // Find first non-empty line in the fold.
+ for (lnum = foldstart; lnum < foldend; lnum++) {
+ if (!linewhite(lnum)) {
break;
- ++lnum;
+ }
}
/* Find interesting text in this line. */
@@ -9519,21 +8869,19 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv)
/* skip C comment-start */
if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) {
s = skipwhite(s + 2);
- if (*skipwhite(s) == NUL
- && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) {
+ if (*skipwhite(s) == NUL && lnum + 1 < foldend) {
s = skipwhite(ml_get(lnum + 1));
if (*s == '*')
s = skipwhite(s + 1);
}
}
- txt = _("+-%s%3ld lines: ");
+ unsigned long count = (unsigned long)(foldend - foldstart + 1);
+ txt = NGETTEXT("+-%s%3ld line: ", "+-%s%3ld lines: ", count);
r = xmalloc(STRLEN(txt)
- + STRLEN(vimvars[VV_FOLDDASHES].vv_str) // for %s
- + 20 // for %3ld
- + STRLEN(s)); // concatenated
- sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str,
- (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr
- - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1));
+ + STRLEN(dashes) // for %s
+ + 20 // for %3ld
+ + STRLEN(s)); // concatenated
+ sprintf((char *)r, txt, dashes, count);
len = (int)STRLEN(r);
STRCAT(r, s);
/* remove 'foldmarker' and 'commentstring' */
@@ -9545,86 +8893,232 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv)
/*
* "foldtextresult(lnum)" function
*/
-static void f_foldtextresult(typval_T *argvars, typval_T *rettv)
+static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
char_u *text;
- char_u buf[51];
+ char_u buf[FOLD_TEXT_LEN];
foldinfo_T foldinfo;
int fold_count;
+ static bool entered = false;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- lnum = get_tv_lnum(argvars);
- /* treat illegal types and illegal string values for {lnum} the same */
- if (lnum < 0)
+ if (entered) {
+ return; // reject recursive use
+ }
+ entered = true;
+ linenr_T lnum = tv_get_lnum(argvars);
+ // Treat illegal types and illegal string values for {lnum} the same.
+ if (lnum < 0) {
lnum = 0;
+ }
fold_count = foldedCount(curwin, lnum, &foldinfo);
if (fold_count > 0) {
- text = get_foldtext(curwin, lnum, lnum + fold_count - 1,
- &foldinfo, buf);
- if (text == buf)
+ text = get_foldtext(curwin, lnum, lnum + fold_count - 1, &foldinfo, buf);
+ if (text == buf) {
text = vim_strsave(text);
+ }
rettv->vval.v_string = text;
}
+
+ entered = false;
}
/*
* "foreground()" function
*/
-static void f_foreground(typval_T *argvars, typval_T *rettv)
+static void f_foreground(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
}
-/*
- * "function()" function
- */
-static void f_function(typval_T *argvars, typval_T *rettv)
+static void common_function(typval_T *argvars, typval_T *rettv,
+ bool is_funcref, FunPtr fptr)
{
char_u *s;
-
- s = get_tv_string(&argvars[0]);
- if (s == NULL || *s == NUL || ascii_isdigit(*s))
- EMSG2(_(e_invarg2), s);
- /* Don't check an autoload name for existence here. */
- else if (vim_strchr(s, AUTOLOAD_CHAR) == NULL && !function_exists(s))
- EMSG2(_("E700: Unknown function: %s"), s);
- else {
+ char_u *name;
+ bool use_string = false;
+ partial_T *arg_pt = NULL;
+ char_u *trans_name = NULL;
+
+ if (argvars[0].v_type == VAR_FUNC) {
+ // function(MyFunc, [arg], dict)
+ s = argvars[0].vval.v_string;
+ } else if (argvars[0].v_type == VAR_PARTIAL
+ && argvars[0].vval.v_partial != NULL) {
+ // function(dict.MyFunc, [arg])
+ arg_pt = argvars[0].vval.v_partial;
+ s = partial_name(arg_pt);
+ } else {
+ // function('MyFunc', [arg], dict)
+ s = (char_u *)tv_get_string(&argvars[0]);
+ use_string = true;
+ }
+
+ if ((use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL) || is_funcref) {
+ name = s;
+ trans_name = trans_function_name(&name, false,
+ TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD
+ | TFN_NO_DEREF, NULL, NULL);
+ if (*name != NUL) {
+ s = NULL;
+ }
+ }
+ if (s == NULL || *s == NUL || (use_string && ascii_isdigit(*s))
+ || (is_funcref && trans_name == NULL)) {
+ emsgf(_(e_invarg2), (use_string
+ ? tv_get_string(&argvars[0])
+ : (const char *)s));
+ // Don't check an autoload name for existence here.
+ } else if (trans_name != NULL
+ && (is_funcref ? find_func(trans_name) == NULL
+ : !translated_function_exists((const char *)trans_name))) {
+ emsgf(_("E700: Unknown function: %s"), s);
+ } else {
+ int dict_idx = 0;
+ int arg_idx = 0;
+ list_T *list = NULL;
if (STRNCMP(s, "s:", 2) == 0 || STRNCMP(s, "<SID>", 5) == 0) {
char sid_buf[25];
int off = *s == 's' ? 2 : 5;
- /* Expand s: and <SID> into <SNR>nr_, so that the function can
- * also be called from another script. Using trans_function_name()
- * would also work, but some plugins depend on the name being
- * printable text. */
- sprintf(sid_buf, "<SNR>%" PRId64 "_", (int64_t)current_SID);
- rettv->vval.v_string = xmalloc(STRLEN(sid_buf) + STRLEN(s + off) + 1);
- STRCPY(rettv->vval.v_string, sid_buf);
- STRCAT(rettv->vval.v_string, s + off);
- } else
- rettv->vval.v_string = vim_strsave(s);
- rettv->v_type = VAR_FUNC;
+ // Expand s: and <SID> into <SNR>nr_, so that the function can
+ // also be called from another script. Using trans_function_name()
+ // would also work, but some plugins depend on the name being
+ // printable text.
+ snprintf(sid_buf, sizeof(sid_buf), "<SNR>%" PRId64 "_",
+ (int64_t)current_SID);
+ name = xmalloc(STRLEN(sid_buf) + STRLEN(s + off) + 1);
+ STRCPY(name, sid_buf);
+ STRCAT(name, s + off);
+ } else {
+ name = vim_strsave(s);
+ }
+
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ // function(name, [args], dict)
+ arg_idx = 1;
+ dict_idx = 2;
+ } else if (argvars[1].v_type == VAR_DICT) {
+ // function(name, dict)
+ dict_idx = 1;
+ } else {
+ // function(name, [args])
+ arg_idx = 1;
+ }
+ if (dict_idx > 0) {
+ if (argvars[dict_idx].v_type != VAR_DICT) {
+ EMSG(_("E922: expected a dict"));
+ xfree(name);
+ goto theend;
+ }
+ if (argvars[dict_idx].vval.v_dict == NULL) {
+ dict_idx = 0;
+ }
+ }
+ if (arg_idx > 0) {
+ if (argvars[arg_idx].v_type != VAR_LIST) {
+ EMSG(_("E923: Second argument of function() must be "
+ "a list or a dict"));
+ xfree(name);
+ goto theend;
+ }
+ list = argvars[arg_idx].vval.v_list;
+ if (tv_list_len(list) == 0) {
+ arg_idx = 0;
+ }
+ }
+ }
+ if (dict_idx > 0 || arg_idx > 0 || arg_pt != NULL || is_funcref) {
+ partial_T *const pt = xcalloc(1, sizeof(*pt));
+
+ // result is a VAR_PARTIAL
+ if (arg_idx > 0 || (arg_pt != NULL && arg_pt->pt_argc > 0)) {
+ const int arg_len = (arg_pt == NULL ? 0 : arg_pt->pt_argc);
+ const int lv_len = tv_list_len(list);
+
+ pt->pt_argc = arg_len + lv_len;
+ pt->pt_argv = xmalloc(sizeof(pt->pt_argv[0]) * pt->pt_argc);
+ int i = 0;
+ for (; i < arg_len; i++) {
+ tv_copy(&arg_pt->pt_argv[i], &pt->pt_argv[i]);
+ }
+ if (lv_len > 0) {
+ TV_LIST_ITER(list, li, {
+ tv_copy(TV_LIST_ITEM_TV(li), &pt->pt_argv[i++]);
+ });
+ }
+ }
+
+ // For "function(dict.func, [], dict)" and "func" is a partial
+ // use "dict". That is backwards compatible.
+ if (dict_idx > 0) {
+ // The dict is bound explicitly, pt_auto is false
+ pt->pt_dict = argvars[dict_idx].vval.v_dict;
+ (pt->pt_dict->dv_refcount)++;
+ } else if (arg_pt != NULL) {
+ // If the dict was bound automatically the result is also
+ // bound automatically.
+ pt->pt_dict = arg_pt->pt_dict;
+ pt->pt_auto = arg_pt->pt_auto;
+ if (pt->pt_dict != NULL) {
+ (pt->pt_dict->dv_refcount)++;
+ }
+ }
+
+ pt->pt_refcount = 1;
+ if (arg_pt != NULL && arg_pt->pt_func != NULL) {
+ pt->pt_func = arg_pt->pt_func;
+ func_ptr_ref(pt->pt_func);
+ xfree(name);
+ } else if (is_funcref) {
+ pt->pt_func = find_func(trans_name);
+ func_ptr_ref(pt->pt_func);
+ xfree(name);
+ } else {
+ pt->pt_name = name;
+ func_ref(name);
+ }
+
+ rettv->v_type = VAR_PARTIAL;
+ rettv->vval.v_partial = pt;
+ } else {
+ // result is a VAR_FUNC
+ rettv->v_type = VAR_FUNC;
+ rettv->vval.v_string = name;
+ func_ref(name);
+ }
}
+theend:
+ xfree(trans_name);
}
-/*
- * "garbagecollect()" function
- */
-static void f_garbagecollect(typval_T *argvars, typval_T *rettv)
+static void f_funcref(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- /* This is postponed until we are back at the toplevel, because we may be
- * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */
- want_garbage_collect = TRUE;
+ common_function(argvars, rettv, true, fptr);
+}
- if (argvars[0].v_type != VAR_UNKNOWN && get_tv_number(&argvars[0]) == 1)
- garbage_collect_at_exit = TRUE;
+static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ common_function(argvars, rettv, false, fptr);
+}
+
+/// "garbagecollect()" function
+static void f_garbagecollect(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ // This is postponed until we are back at the toplevel, because we may be
+ // using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]".
+ want_garbage_collect = true;
+
+ if (argvars[0].v_type != VAR_UNKNOWN && tv_get_number(&argvars[0]) == 1) {
+ garbage_collect_at_exit = true;
+ }
}
/*
* "get()" function
*/
-static void f_get(typval_T *argvars, typval_T *rettv)
+static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
listitem_T *li;
list_T *l;
@@ -9634,28 +9128,183 @@ static void f_get(typval_T *argvars, typval_T *rettv)
if (argvars[0].v_type == VAR_LIST) {
if ((l = argvars[0].vval.v_list) != NULL) {
- int error = FALSE;
+ bool error = false;
- li = list_find(l, get_tv_number_chk(&argvars[1], &error));
- if (!error && li != NULL)
- tv = &li->li_tv;
+ li = tv_list_find(l, tv_get_number_chk(&argvars[1], &error));
+ if (!error && li != NULL) {
+ tv = TV_LIST_ITEM_TV(li);
+ }
}
} else if (argvars[0].v_type == VAR_DICT) {
if ((d = argvars[0].vval.v_dict) != NULL) {
- di = dict_find(d, get_tv_string(&argvars[1]), -1);
- if (di != NULL)
+ di = tv_dict_find(d, tv_get_string(&argvars[1]), -1);
+ if (di != NULL) {
tv = &di->di_tv;
+ }
}
- } else
+ } else if (tv_is_func(argvars[0])) {
+ partial_T *pt;
+ partial_T fref_pt;
+
+ if (argvars[0].v_type == VAR_PARTIAL) {
+ pt = argvars[0].vval.v_partial;
+ } else {
+ memset(&fref_pt, 0, sizeof(fref_pt));
+ fref_pt.pt_name = argvars[0].vval.v_string;
+ pt = &fref_pt;
+ }
+
+ if (pt != NULL) {
+ const char *const what = tv_get_string(&argvars[1]);
+
+ if (strcmp(what, "func") == 0 || strcmp(what, "name") == 0) {
+ 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 = (char_u *)xstrdup(n);
+ if (rettv->v_type == VAR_FUNC) {
+ func_ref(rettv->vval.v_string);
+ }
+ } else if (strcmp(what, "dict") == 0) {
+ tv_dict_set_ret(rettv, pt->pt_dict);
+ } else if (strcmp(what, "args") == 0) {
+ rettv->v_type = VAR_LIST;
+ if (tv_list_alloc_ret(rettv, pt->pt_argc) != NULL) {
+ for (int i = 0; i < pt->pt_argc; i++) {
+ tv_list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]);
+ }
+ }
+ } else {
+ EMSG2(_(e_invarg2), what);
+ }
+ return;
+ }
+ } else {
EMSG2(_(e_listdictarg), "get()");
+ }
if (tv == NULL) {
- if (argvars[2].v_type != VAR_UNKNOWN)
- copy_tv(&argvars[2], rettv);
- } else
- copy_tv(tv, rettv);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ tv_copy(&argvars[2], rettv);
+ }
+ } else {
+ tv_copy(tv, rettv);
+ }
+}
+
+/// Returns information about signs placed in a buffer as list of dicts.
+static list_T *get_buffer_signs(buf_T *buf)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ list_T *const l = tv_list_alloc(kListLenMayKnow);
+ for (signlist_T *sign = buf->b_signlist; sign; sign = sign->next) {
+ dict_T *const d = tv_dict_alloc();
+
+ tv_dict_add_nr(d, S_LEN("id"), sign->id);
+ tv_dict_add_nr(d, S_LEN("lnum"), sign->lnum);
+ tv_dict_add_str(d, S_LEN("name"),
+ (const char *)sign_typenr2name(sign->typenr));
+
+ tv_list_append_dict(l, d);
+ }
+ return l;
+}
+
+/// Returns buffer options, variables and other attributes in a dictionary.
+static dict_T *get_buffer_info(buf_T *buf)
+{
+ dict_T *const dict = tv_dict_alloc();
+
+ tv_dict_add_nr(dict, S_LEN("bufnr"), buf->b_fnum);
+ tv_dict_add_str(dict, S_LEN("name"),
+ buf->b_ffname != NULL ? (const char *)buf->b_ffname : "");
+ tv_dict_add_nr(dict, S_LEN("lnum"),
+ buf == curbuf ? curwin->w_cursor.lnum : buflist_findlnum(buf));
+ tv_dict_add_nr(dict, S_LEN("loaded"), buf->b_ml.ml_mfp != NULL);
+ tv_dict_add_nr(dict, S_LEN("listed"), buf->b_p_bl);
+ tv_dict_add_nr(dict, S_LEN("changed"), bufIsChanged(buf));
+ tv_dict_add_nr(dict, S_LEN("changedtick"), buf_get_changedtick(buf));
+ tv_dict_add_nr(dict, S_LEN("hidden"),
+ buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0);
+
+ // Get a reference to buffer variables
+ tv_dict_add_dict(dict, S_LEN("variables"), buf->b_vars);
+
+ // List of windows displaying this buffer
+ list_T *const windows = tv_list_alloc(kListLenMayKnow);
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ if (wp->w_buffer == buf) {
+ tv_list_append_number(windows, (varnumber_T)wp->handle);
+ }
+ }
+ tv_dict_add_list(dict, S_LEN("windows"), windows);
+
+ if (buf->b_signlist != NULL) {
+ // List of signs placed in this buffer
+ tv_dict_add_list(dict, S_LEN("signs"), get_buffer_signs(buf));
+ }
+
+ return dict;
}
+/// "getbufinfo()" function
+static void f_getbufinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ buf_T *argbuf = NULL;
+ bool filtered = false;
+ bool sel_buflisted = false;
+ bool sel_bufloaded = false;
+
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+
+ // List of all the buffers or selected buffers
+ if (argvars[0].v_type == VAR_DICT) {
+ dict_T *sel_d = argvars[0].vval.v_dict;
+
+ if (sel_d != NULL) {
+ dictitem_T *di;
+
+ filtered = true;
+
+ di = tv_dict_find(sel_d, S_LEN("buflisted"));
+ if (di != NULL && tv_get_number(&di->di_tv)) {
+ sel_buflisted = true;
+ }
+
+ di = tv_dict_find(sel_d, S_LEN("bufloaded"));
+ if (di != NULL && tv_get_number(&di->di_tv)) {
+ sel_bufloaded = true;
+ }
+ }
+ } else if (argvars[0].v_type != VAR_UNKNOWN) {
+ // Information about one buffer. Argument specifies the buffer
+ if (tv_check_num(&argvars[0])) { // issue errmsg if type error
+ emsg_off++;
+ argbuf = tv_get_buf(&argvars[0], false);
+ emsg_off--;
+ if (argbuf == NULL) {
+ return;
+ }
+ }
+ }
+
+ // Return information about all the buffers or a specified buffer
+ FOR_ALL_BUFFERS(buf) {
+ if (argbuf != NULL && argbuf != buf) {
+ continue;
+ }
+ if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL)
+ || (sel_buflisted && !buf->b_p_bl))) {
+ continue;
+ }
+
+ dict_T *const d = get_buffer_info(buf);
+ tv_list_append_dict(rettv->vval.v_list, d);
+ if (argbuf != NULL) {
+ return;
+ }
+ }
+}
/*
* Get line or list of lines from buffer "buf" into "rettv".
@@ -9665,149 +9314,185 @@ static void f_get(typval_T *argvars, typval_T *rettv)
*/
static void get_buffer_lines(buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)
{
- char_u *p;
-
- rettv->v_type = VAR_STRING;
+ rettv->v_type = (retlist ? VAR_LIST : VAR_STRING);
rettv->vval.v_string = NULL;
- if (retlist) {
- rettv_list_alloc(rettv);
- }
- if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0)
+ if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0 || end < start) {
+ if (retlist) {
+ tv_list_alloc_ret(rettv, 0);
+ }
return;
+ }
- if (!retlist) {
- if (start >= 1 && start <= buf->b_ml.ml_line_count)
- p = ml_get_buf(buf, start, FALSE);
- else
- p = (char_u *)"";
- rettv->vval.v_string = vim_strsave(p);
- } else {
- if (end < start)
- return;
-
- if (start < 1)
+ if (retlist) {
+ if (start < 1) {
start = 1;
- if (end > buf->b_ml.ml_line_count)
+ }
+ if (end > buf->b_ml.ml_line_count) {
end = buf->b_ml.ml_line_count;
+ }
+ tv_list_alloc_ret(rettv, end - start + 1);
while (start <= end) {
- list_append_string(
- rettv->vval.v_list, ml_get_buf(buf, start++, FALSE), -1);
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)ml_get_buf(buf, start++, false), -1);
}
+ } else {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = ((start >= 1 && start <= buf->b_ml.ml_line_count)
+ ? vim_strsave(ml_get_buf(buf, start, false))
+ : NULL);
}
}
+/// Get the line number from VimL object
+///
+/// @note Unlike tv_get_lnum(), this one supports only "$" special string.
+///
+/// @param[in] tv Object to get value from. Is expected to be a number or
+/// a special string "$".
+/// @param[in] buf Buffer to take last line number from in case tv is "$". May
+/// be NULL, in this case "$" results in zero return.
+///
+/// @return Line number or 0 in case of error.
+static linenr_T tv_get_lnum_buf(const typval_T *const tv,
+ const buf_T *const buf)
+ FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (tv->v_type == VAR_STRING
+ && tv->vval.v_string != NULL
+ && tv->vval.v_string[0] == '$'
+ && buf != NULL) {
+ return buf->b_ml.ml_line_count;
+ }
+ return tv_get_number_chk(tv, NULL);
+}
+
/*
* "getbufline()" function
*/
-static void f_getbufline(typval_T *argvars, typval_T *rettv)
+static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
- linenr_T end;
- buf_T *buf;
+ buf_T *buf = NULL;
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- ++emsg_off;
- buf = get_buf_tv(&argvars[0], FALSE);
- --emsg_off;
+ if (tv_check_str_or_nr(&argvars[0])) {
+ emsg_off++;
+ buf = tv_get_buf(&argvars[0], false);
+ emsg_off--;
+ }
- lnum = get_tv_lnum_buf(&argvars[1], buf);
- if (argvars[2].v_type == VAR_UNKNOWN)
- end = lnum;
- else
- end = get_tv_lnum_buf(&argvars[2], buf);
+ const linenr_T lnum = tv_get_lnum_buf(&argvars[1], buf);
+ const linenr_T end = (argvars[2].v_type == VAR_UNKNOWN
+ ? lnum
+ : tv_get_lnum_buf(&argvars[2], buf));
- get_buffer_lines(buf, lnum, end, TRUE, rettv);
+ get_buffer_lines(buf, lnum, end, true, rettv);
}
/*
* "getbufvar()" function
*/
-static void f_getbufvar(typval_T *argvars, typval_T *rettv)
+static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- buf_T *save_curbuf;
- char_u *varname;
- dictitem_T *v;
- int done = FALSE;
-
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- varname = get_tv_string_chk(&argvars[1]);
- ++emsg_off;
- buf = get_buf_tv(&argvars[0], FALSE);
+ bool done = false;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
+ if (!tv_check_str_or_nr(&argvars[0])) {
+ goto f_getbufvar_end;
+ }
+
+ const char *varname = tv_get_string_chk(&argvars[1]);
+ emsg_off++;
+ buf_T *const buf = tv_get_buf(&argvars[0], false);
+
if (buf != NULL && varname != NULL) {
- /* set curbuf to be our buf, temporarily */
- save_curbuf = curbuf;
+ // set curbuf to be our buf, temporarily
+ buf_T *const save_curbuf = curbuf;
curbuf = buf;
- if (*varname == '&') { /* buffer-local-option */
- if (get_option_tv(&varname, rettv, TRUE) == OK)
- done = TRUE;
- } else if (STRCMP(varname, "changedtick") == 0) {
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = curbuf->b_changedtick;
- done = TRUE;
+ if (*varname == '&') { // buffer-local-option
+ if (varname[1] == NUL) {
+ // get all buffer-local options in a dict
+ dict_T *opts = get_winbuf_options(true);
+
+ if (opts != NULL) {
+ tv_dict_set_ret(rettv, opts);
+ done = true;
+ }
+ } else if (get_option_tv(&varname, rettv, true) == OK) {
+ // buffer-local-option
+ done = true;
+ }
} else {
- /* Look up the variable. */
- /* Let getbufvar({nr}, "") return the "b:" dictionary. */
- v = find_var_in_ht(&curbuf->b_vars->dv_hashtab,
- 'b', varname, FALSE);
+ // Look up the variable.
+ // Let getbufvar({nr}, "") return the "b:" dictionary.
+ dictitem_T *const v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, 'b',
+ varname, strlen(varname), false);
if (v != NULL) {
- copy_tv(&v->di_tv, rettv);
- done = TRUE;
+ tv_copy(&v->di_tv, rettv);
+ done = true;
}
}
- /* restore previous notion of curbuf */
+ // restore previous notion of curbuf
curbuf = save_curbuf;
}
+ emsg_off--;
- if (!done && argvars[2].v_type != VAR_UNKNOWN)
- /* use the default value */
- copy_tv(&argvars[2], rettv);
-
- --emsg_off;
+f_getbufvar_end:
+ if (!done && argvars[2].v_type != VAR_UNKNOWN) {
+ // use the default value
+ tv_copy(&argvars[2], rettv);
+ }
}
/*
* "getchar()" function
*/
-static void f_getchar(typval_T *argvars, typval_T *rettv)
+static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
varnumber_T n;
- int error = FALSE;
-
- /* Position the cursor. Needed after a message that ends in a space. */
- ui_cursor_goto(msg_row, msg_col);
+ bool error = false;
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
for (;; ) {
- if (argvars[0].v_type == VAR_UNKNOWN)
- /* getchar(): blocking wait. */
+ // Position the cursor. Needed after a message that ends in a space,
+ // or if event processing caused a redraw.
+ ui_cursor_goto(msg_row, msg_col);
+
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ // getchar(): blocking wait.
+ if (!(char_avail() || using_script() || input_available())) {
+ input_enable_events();
+ (void)os_inchar(NULL, 0, -1, 0);
+ input_disable_events();
+ if (!multiqueue_empty(main_loop.events)) {
+ multiqueue_process_events(main_loop.events);
+ continue;
+ }
+ }
n = safe_vgetc();
- else if (get_tv_number_chk(&argvars[0], &error) == 1)
- /* getchar(1): only check if char avail */
+ } else if (tv_get_number_chk(&argvars[0], &error) == 1) {
+ // getchar(1): only check if char avail
n = vpeekc_any();
- else if (error || vpeekc_any() == NUL)
- /* illegal argument or getchar(0) and no char avail: return zero */
+ } else if (error || vpeekc_any() == NUL) {
+ // illegal argument or getchar(0) and no char avail: return zero
n = 0;
- else
- /* getchar(0) and char avail: return char */
+ } else {
+ // getchar(0) and char avail: return char
n = safe_vgetc();
+ }
- if (n == K_IGNORE)
+ if (n == K_IGNORE) {
continue;
+ }
break;
}
- --no_mapping;
- --allow_keys;
+ no_mapping--;
vimvars[VV_MOUSE_WIN].vv_nr = 0;
+ vimvars[VV_MOUSE_WINID].vv_nr = 0;
vimvars[VV_MOUSE_LNUM].vv_nr = 0;
vimvars[VV_MOUSE_COL].vv_nr = 0;
@@ -9826,10 +9511,9 @@ static void f_getchar(typval_T *argvars, typval_T *rettv)
temp[i++] = K_SPECIAL;
temp[i++] = K_SECOND(n);
temp[i++] = K_THIRD(n);
- } else if (has_mbyte)
- i += (*mb_char2bytes)(n, temp + i);
- else
- temp[i++] = n;
+ } else {
+ i += utf_char2bytes(n, temp + i);
+ }
temp[i++] = NUL;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strsave(temp);
@@ -9846,10 +9530,14 @@ static void f_getchar(typval_T *argvars, typval_T *rettv)
/* Find the window at the mouse coordinates and compute the
* text position. */
win = mouse_find_win(&row, &col);
+ if (win == NULL) {
+ return;
+ }
(void)mouse_comp_pos(win, &row, &col, &lnum);
for (wp = firstwin; wp != win; wp = wp->w_next)
++winnr;
vimvars[VV_MOUSE_WIN].vv_nr = winnr;
+ vimvars[VV_MOUSE_WINID].vv_nr = wp->handle;
vimvars[VV_MOUSE_LNUM].vv_nr = lnum;
vimvars[VV_MOUSE_COL].vv_nr = col + 1;
}
@@ -9860,7 +9548,7 @@ static void f_getchar(typval_T *argvars, typval_T *rettv)
/*
* "getcharmod()" function
*/
-static void f_getcharmod(typval_T *argvars, typval_T *rettv)
+static void f_getcharmod(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = mod_mask;
}
@@ -9868,21 +9556,21 @@ static void f_getcharmod(typval_T *argvars, typval_T *rettv)
/*
* "getcharsearch()" function
*/
-static void f_getcharsearch(typval_T *argvars, typval_T *rettv)
+static void f_getcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
dict_T *dict = rettv->vval.v_dict;
- dict_add_nr_str(dict, "char", 0L, last_csearch());
- dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL);
- dict_add_nr_str(dict, "until", last_csearch_until(), NULL);
+ tv_dict_add_str(dict, S_LEN("char"), last_csearch());
+ tv_dict_add_nr(dict, S_LEN("forward"), last_csearch_forward());
+ tv_dict_add_nr(dict, S_LEN("until"), last_csearch_until());
}
/*
* "getcmdline()" function
*/
-static void f_getcmdline(typval_T *argvars, typval_T *rettv)
+static void f_getcmdline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = get_cmdline_str();
@@ -9891,7 +9579,7 @@ static void f_getcmdline(typval_T *argvars, typval_T *rettv)
/*
* "getcmdpos()" function
*/
-static void f_getcmdpos(typval_T *argvars, typval_T *rettv)
+static void f_getcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = get_cmdline_pos() + 1;
}
@@ -9899,7 +9587,7 @@ static void f_getcmdpos(typval_T *argvars, typval_T *rettv)
/*
* "getcmdtype()" function
*/
-static void f_getcmdtype(typval_T *argvars, typval_T *rettv)
+static void f_getcmdtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = xmallocz(1);
@@ -9909,7 +9597,7 @@ static void f_getcmdtype(typval_T *argvars, typval_T *rettv)
/*
* "getcmdwintype()" function
*/
-static void f_getcmdwintype(typval_T *argvars, typval_T *rettv)
+static void f_getcmdwintype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -9917,6 +9605,77 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv)
rettv->vval.v_string[0] = cmdwin_type;
}
+// "getcompletion()" function
+static void f_getcompletion(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ char_u *pat;
+ expand_T xpc;
+ bool filtered = false;
+ int options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
+ | WILD_NO_BEEP;
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ filtered = (bool)tv_get_number_chk(&argvars[2], NULL);
+ }
+
+ if (p_wic) {
+ options |= WILD_ICASE;
+ }
+
+ // For filtered results, 'wildignore' is used
+ if (!filtered) {
+ options |= WILD_KEEP_ALL;
+ }
+
+ if (argvars[0].v_type != VAR_STRING || argvars[1].v_type != VAR_STRING) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ if (strcmp(tv_get_string(&argvars[1]), "cmdline") == 0) {
+ set_one_cmd_context(&xpc, tv_get_string(&argvars[0]));
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ goto theend;
+ }
+
+ ExpandInit(&xpc);
+ xpc.xp_pattern = (char_u *)tv_get_string(&argvars[0]);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ xpc.xp_context = cmdcomplete_str_to_type(
+ (char_u *)tv_get_string(&argvars[1]));
+ if (xpc.xp_context == EXPAND_NOTHING) {
+ EMSG2(_(e_invarg2), argvars[1].vval.v_string);
+ return;
+ }
+
+ if (xpc.xp_context == EXPAND_MENUS) {
+ set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, false);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ }
+
+ if (xpc.xp_context == EXPAND_CSCOPE) {
+ set_context_in_cscope_cmd(&xpc, (const char *)xpc.xp_pattern, CMD_cscope);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ }
+
+ if (xpc.xp_context == EXPAND_SIGN) {
+ set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
+ xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern);
+ }
+
+theend:
+ pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context);
+ ExpandOne(&xpc, pat, NULL, options, WILD_ALL_KEEP);
+ tv_list_alloc_ret(rettv, xpc.xp_numfiles);
+
+ for (int i = 0; i < xpc.xp_numfiles; i++) {
+ tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i],
+ -1);
+ }
+ xfree(pat);
+ ExpandCleanup(&xpc);
+}
+
/// `getcwd([{win}[, {tab}]])` function
///
/// Every scope not specified implies the currently selected scope object.
@@ -9926,7 +9685,7 @@ static void f_getcmdwintype(typval_T *argvars, typval_T *rettv)
/// @pre An argument may not be -1 if preceding arguments are not all -1.
///
/// @post The return value will be a string.
-static void f_getcwd(typval_T *argvars, typval_T *rettv)
+static void f_getcwd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
// Possible scope of working directory to return.
CdScope scope = kCdScopeInvalid;
@@ -10011,26 +9770,22 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv)
if (from) {
break;
}
- case kCdScopeTab: // FALLTHROUGH
+ FALLTHROUGH;
+ case kCdScopeTab:
assert(tp);
- from = tp->localdir;
+ from = tp->tp_localdir;
if (from) {
break;
}
- case kCdScopeGlobal: // FALLTHROUGH
- // The `globaldir` variable is not always set.
- if (globaldir) {
+ FALLTHROUGH;
+ case kCdScopeGlobal:
+ if (globaldir) { // `globaldir` is not always set.
from = globaldir;
- } else {
- // We have to copy the OS path directly into output string.
- if (os_dirname(cwd, MAXPATHL) == FAIL) {
- EMSG(_("E41: Could not display path."));
- goto end;
- }
+ } else if (os_dirname(cwd, MAXPATHL) == FAIL) { // Get the OS CWD.
+ from = (char_u *)""; // Return empty string on failure.
}
break;
- case kCdScopeInvalid:
- // We should never get here
+ case kCdScopeInvalid: // We should never get here
assert(false);
}
@@ -10042,14 +9797,14 @@ static void f_getcwd(typval_T *argvars, typval_T *rettv)
#ifdef BACKSLASH_IN_FILENAME
slash_adjust(rettv->vval.v_string);
#endif
-end:
+
xfree(cwd);
}
/*
* "getfontname()" function
*/
-static void f_getfontname(typval_T *argvars, typval_T *rettv)
+static void f_getfontname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -10058,39 +9813,40 @@ static void f_getfontname(typval_T *argvars, typval_T *rettv)
/*
* "getfperm({fname})" function
*/
-static void f_getfperm(typval_T *argvars, typval_T *rettv)
+static void f_getfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *perm = NULL;
+ char *perm = NULL;
char_u flags[] = "rwx";
- char_u *filename = get_tv_string(&argvars[0]);
+ const char *filename = tv_get_string(&argvars[0]);
int32_t file_perm = os_getperm(filename);
if (file_perm >= 0) {
- perm = vim_strsave((char_u *)"---------");
+ perm = xstrdup("---------");
for (int i = 0; i < 9; i++) {
- if (file_perm & (1 << (8 - i)))
+ if (file_perm & (1 << (8 - i))) {
perm[i] = flags[i % 3];
+ }
}
}
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = perm;
+ rettv->vval.v_string = (char_u *)perm;
}
/*
* "getfsize({fname})" function
*/
-static void f_getfsize(typval_T *argvars, typval_T *rettv)
+static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char *fname = (char *)get_tv_string(&argvars[0]);
+ const char *fname = tv_get_string(&argvars[0]);
rettv->v_type = VAR_NUMBER;
FileInfo file_info;
if (os_fileinfo(fname, &file_info)) {
uint64_t filesize = os_fileinfo_size(&file_info);
- if (os_isdir((char_u *)fname))
+ if (os_isdir((const char_u *)fname)) {
rettv->vval.v_number = 0;
- else {
+ } else {
rettv->vval.v_number = (varnumber_T)filesize;
/* non-perfect check for overflow */
@@ -10106,9 +9862,9 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv)
/*
* "getftime({fname})" function
*/
-static void f_getftime(typval_T *argvars, typval_T *rettv)
+static void f_getftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char *fname = (char *)get_tv_string(&argvars[0]);
+ const char *fname = tv_get_string(&argvars[0]);
FileInfo file_info;
if (os_fileinfo(fname, &file_info)) {
@@ -10121,17 +9877,16 @@ static void f_getftime(typval_T *argvars, typval_T *rettv)
/*
* "getftype({fname})" function
*/
-static void f_getftype(typval_T *argvars, typval_T *rettv)
+static void f_getftype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *fname;
char_u *type = NULL;
char *t;
- fname = get_tv_string(&argvars[0]);
+ const char *fname = tv_get_string(&argvars[0]);
rettv->v_type = VAR_STRING;
FileInfo file_info;
- if (os_fileinfo_link((char *)fname, &file_info)) {
+ if (os_fileinfo_link(fname, &file_info)) {
uint64_t mode = file_info.stat.st_mode;
#ifdef S_ISREG
if (S_ISREG(mode))
@@ -10156,7 +9911,7 @@ static void f_getftype(typval_T *argvars, typval_T *rettv)
# endif
# ifdef S_ISSOCK
else if (S_ISSOCK(mode))
- t = "fifo";
+ t = "socket";
# endif
else
t = "other";
@@ -10183,10 +9938,11 @@ static void f_getftype(typval_T *argvars, typval_T *rettv)
default: t = "other";
}
# else
- if (os_isdir(fname))
+ if (os_isdir((const char_u *)fname)) {
t = "dir";
- else
+ } else {
t = "file";
+ }
# endif
#endif
type = vim_strsave((char_u *)t);
@@ -10197,69 +9953,101 @@ static void f_getftype(typval_T *argvars, typval_T *rettv)
/*
* "getline(lnum, [end])" function
*/
-static void f_getline(typval_T *argvars, typval_T *rettv)
+static void f_getline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
linenr_T end;
- int retlist;
+ bool retlist;
- lnum = get_tv_lnum(argvars);
+ const linenr_T lnum = tv_get_lnum(argvars);
if (argvars[1].v_type == VAR_UNKNOWN) {
- end = 0;
- retlist = FALSE;
+ end = lnum;
+ retlist = false;
} else {
- end = get_tv_lnum(&argvars[1]);
- retlist = TRUE;
+ end = tv_get_lnum(&argvars[1]);
+ retlist = true;
}
get_buffer_lines(curbuf, lnum, end, retlist, rettv);
}
+static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg,
+ typval_T *rettv)
+{
+ if (what_arg->v_type == VAR_UNKNOWN) {
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+ if (is_qf || wp != NULL) {
+ (void)get_errorlist(NULL, wp, -1, rettv->vval.v_list);
+ }
+ } else {
+ tv_dict_alloc_ret(rettv);
+ if (is_qf || wp != NULL) {
+ if (what_arg->v_type == VAR_DICT) {
+ dict_T *d = what_arg->vval.v_dict;
+
+ if (d != NULL) {
+ get_errorlist_properties(wp, d, rettv->vval.v_dict);
+ }
+ } else {
+ EMSG(_(e_dictreq));
+ }
+ }
+ }
+}
+
+/// "getloclist()" function
+static void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ win_T *wp = find_win_by_nr(&argvars[0], NULL);
+ get_qf_loc_list(false, wp, &argvars[1], rettv);
+}
+
/*
* "getmatches()" function
*/
-static void f_getmatches(typval_T *argvars, typval_T *rettv)
+static void f_getmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
matchitem_T *cur = curwin->w_match_head;
int i;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
while (cur != NULL) {
- dict_T *dict = dict_alloc();
+ dict_T *dict = tv_dict_alloc();
if (cur->match.regprog == NULL) {
- // match added with matchaddpos()
- for (i = 0; i < MAXPOSMATCH; ++i) {
+ // match added with matchaddpos()
+ for (i = 0; i < MAXPOSMATCH; i++) {
llpos_T *llpos;
- char buf[6];
+ char buf[6];
llpos = &cur->pos.pos[i];
if (llpos->lnum == 0) {
break;
}
- list_T *l = list_alloc();
- list_append_number(l, (varnumber_T)llpos->lnum);
+ list_T *const l = tv_list_alloc(1 + (llpos->col > 0 ? 2 : 0));
+ tv_list_append_number(l, (varnumber_T)llpos->lnum);
if (llpos->col > 0) {
- list_append_number(l, (varnumber_T)llpos->col);
- list_append_number(l, (varnumber_T)llpos->len);
+ tv_list_append_number(l, (varnumber_T)llpos->col);
+ tv_list_append_number(l, (varnumber_T)llpos->len);
}
- sprintf(buf, "pos%d", i + 1);
- dict_add_list(dict, buf, l);
+ int len = snprintf(buf, sizeof(buf), "pos%d", i + 1);
+ assert((size_t)len < sizeof(buf));
+ tv_dict_add_list(dict, buf, (size_t)len, l);
}
} else {
- dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
+ tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cur->pattern);
}
- dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
- dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
- dict_add_nr_str(dict, "id", (long)cur->id, NULL);
+ tv_dict_add_str(dict, S_LEN("group"),
+ (const char *)syn_id2name(cur->hlg_id));
+ tv_dict_add_nr(dict, S_LEN("priority"), (varnumber_T)cur->priority);
+ tv_dict_add_nr(dict, S_LEN("id"), (varnumber_T)cur->id);
if (cur->conceal_char) {
- char_u buf[MB_MAXBYTES + 1];
+ char buf[MB_MAXBYTES + 1];
- buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
- dict_add_nr_str(dict, "conceal", 0L, (char_u *)&buf);
+ buf[utf_char2bytes((int)cur->conceal_char, (char_u *)buf)] = NUL;
+ tv_dict_add_str(dict, S_LEN("conceal"), buf);
}
- list_append_dict(rettv->vval.v_list, dict);
+ tv_list_append_dict(rettv->vval.v_list, dict);
cur = cur->next;
}
}
@@ -10267,7 +10055,7 @@ static void f_getmatches(typval_T *argvars, typval_T *rettv)
/*
* "getpid()" function
*/
-static void f_getpid(typval_T *argvars, typval_T *rettv)
+static void f_getpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = os_get_pid();
}
@@ -10283,27 +10071,29 @@ static void getpos_both(typval_T *argvars, typval_T *rettv, bool getcurpos)
fp = var2fpos(&argvars[0], true, &fnum);
}
- list_T *l = rettv_list_alloc(rettv);
- list_append_number(l, (fnum != -1) ? (varnumber_T)fnum : (varnumber_T)0);
- list_append_number(l, (fp != NULL) ? (varnumber_T)fp->lnum : (varnumber_T)0);
- list_append_number(l,
- (fp != NULL)
- ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
- : (varnumber_T)0);
- list_append_number(l,
- (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
+ list_T *const l = tv_list_alloc_ret(rettv, 4 + (!!getcurpos));
+ tv_list_append_number(l, (fnum != -1) ? (varnumber_T)fnum : (varnumber_T)0);
+ tv_list_append_number(l, ((fp != NULL)
+ ? (varnumber_T)fp->lnum
+ : (varnumber_T)0));
+ tv_list_append_number(
+ l, ((fp != NULL)
+ ? (varnumber_T)(fp->col == MAXCOL ? MAXCOL : fp->col + 1)
+ : (varnumber_T)0));
+ tv_list_append_number(
+ l, (fp != NULL) ? (varnumber_T)fp->coladd : (varnumber_T)0);
if (getcurpos) {
update_curswant();
- list_append_number(l, curwin->w_curswant == MAXCOL
+ tv_list_append_number(l, (curwin->w_curswant == MAXCOL
? (varnumber_T)MAXCOL
- : (varnumber_T)curwin->w_curswant + 1);
+ : (varnumber_T)curwin->w_curswant + 1));
}
}
/*
* "getcurpos(string)" function
*/
-static void f_getcurpos(typval_T *argvars, typval_T *rettv)
+static void f_getcurpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getpos_both(argvars, rettv, true);
}
@@ -10311,65 +10101,55 @@ static void f_getcurpos(typval_T *argvars, typval_T *rettv)
/*
* "getpos(string)" function
*/
-static void f_getpos(typval_T *argvars, typval_T *rettv)
+static void f_getpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getpos_both(argvars, rettv, false);
}
-/*
- * "getqflist()" and "getloclist()" functions
- */
-static void f_getqflist(typval_T *argvars, typval_T *rettv)
+/// "getqflist()" functions
+static void f_getqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_list_alloc(rettv);
- win_T *wp = NULL;
- if (argvars[0].v_type != VAR_UNKNOWN) { /* getloclist() */
- wp = find_win_by_nr(&argvars[0], NULL);
- if (wp == NULL) {
- return;
- }
- }
- (void)get_errorlist(wp, rettv->vval.v_list);
+ get_qf_loc_list(true, NULL, &argvars[0], rettv);
}
/// "getreg()" function
-static void f_getreg(typval_T *argvars, typval_T *rettv)
+static void f_getreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *strregname;
- int regname;
+ const char *strregname;
int arg2 = false;
bool return_list = false;
- int error = false;
+ bool error = false;
if (argvars[0].v_type != VAR_UNKNOWN) {
- strregname = get_tv_string_chk(&argvars[0]);
+ strregname = tv_get_string_chk(&argvars[0]);
error = strregname == NULL;
if (argvars[1].v_type != VAR_UNKNOWN) {
- arg2 = get_tv_number_chk(&argvars[1], &error);
+ arg2 = tv_get_number_chk(&argvars[1], &error);
if (!error && argvars[2].v_type != VAR_UNKNOWN) {
- return_list = get_tv_number_chk(&argvars[2], &error);
+ return_list = tv_get_number_chk(&argvars[2], &error);
}
}
} else {
- strregname = vimvars[VV_REG].vv_str;
+ strregname = (const char *)vimvars[VV_REG].vv_str;
}
if (error) {
return;
}
- regname = (strregname == NULL ? '"' : *strregname);
- if (regname == 0)
+ int regname = (uint8_t)(strregname == NULL ? '"' : *strregname);
+ if (regname == 0) {
regname = '"';
+ }
if (return_list) {
rettv->v_type = VAR_LIST;
- rettv->vval.v_list =
+ rettv->vval.v_list =
get_reg_contents(regname, (arg2 ? kGRegExprSrc : 0) | kGRegList);
if (rettv->vval.v_list == NULL) {
- rettv->vval.v_list = list_alloc();
+ rettv->vval.v_list = tv_list_alloc(0);
}
- rettv->vval.v_list->lv_refcount++;
+ tv_list_ref(rettv->vval.v_list);
} else {
rettv->v_type = VAR_STRING;
rettv->vval.v_string = get_reg_contents(regname, arg2 ? kGRegExprSrc : 0);
@@ -10379,25 +10159,26 @@ static void f_getreg(typval_T *argvars, typval_T *rettv)
/*
* "getregtype()" function
*/
-static void f_getregtype(typval_T *argvars, typval_T *rettv)
+static void f_getregtype(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *strregname;
- int regname;
+ const char *strregname;
if (argvars[0].v_type != VAR_UNKNOWN) {
- strregname = get_tv_string_chk(&argvars[0]);
- if (strregname == NULL) { /* type error; errmsg already given */
+ strregname = tv_get_string_chk(&argvars[0]);
+ if (strregname == NULL) { // Type error; errmsg already given.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
return;
}
- } else
- /* Default to v:register */
- strregname = vimvars[VV_REG].vv_str;
+ } else {
+ // Default to v:register.
+ strregname = (const char *)vimvars[VV_REG].vv_str;
+ }
- regname = (strregname == NULL ? '"' : *strregname);
- if (regname == 0)
+ int regname = (uint8_t)(strregname == NULL ? '"' : *strregname);
+ if (regname == 0) {
regname = '"';
+ }
colnr_T reglen = 0;
char buf[NUMBUFLEN + 2];
@@ -10408,57 +10189,179 @@ static void f_getregtype(typval_T *argvars, typval_T *rettv)
rettv->vval.v_string = (char_u *)xstrdup(buf);
}
+/// Returns information (variables, options, etc.) about a tab page
+/// as a dictionary.
+static dict_T *get_tabpage_info(tabpage_T *tp, int tp_idx)
+{
+ dict_T *const dict = tv_dict_alloc();
+
+ tv_dict_add_nr(dict, S_LEN("tabnr"), tp_idx);
+
+ list_T *const l = tv_list_alloc(kListLenMayKnow);
+ FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
+ tv_list_append_number(l, (varnumber_T)wp->handle);
+ }
+ tv_dict_add_list(dict, S_LEN("windows"), l);
+
+ // Make a reference to tabpage variables
+ tv_dict_add_dict(dict, S_LEN("variables"), tp->tp_vars);
+
+ return dict;
+}
+
+/// "gettabinfo()" function
+static void f_gettabinfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tabpage_T *tparg = NULL;
+
+ tv_list_alloc_ret(rettv, (argvars[0].v_type == VAR_UNKNOWN
+ ? 1
+ : kListLenMayKnow));
+
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ // Information about one tab page
+ tparg = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+ if (tparg == NULL) {
+ return;
+ }
+ }
+
+ // Get information about a specific tab page or all tab pages
+ int tpnr = 0;
+ FOR_ALL_TABS(tp) {
+ tpnr++;
+ if (tparg != NULL && tp != tparg) {
+ continue;
+ }
+ dict_T *const d = get_tabpage_info(tp, tpnr);
+ tv_list_append_dict(rettv->vval.v_list, d);
+ if (tparg != NULL) {
+ return;
+ }
+ }
+}
+
/*
* "gettabvar()" function
*/
-static void f_gettabvar(typval_T *argvars, typval_T *rettv)
+static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *oldcurwin;
- tabpage_T *tp, *oldtabpage;
- dictitem_T *v;
- char_u *varname;
+ tabpage_T *oldtabpage;
bool done = false;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- varname = get_tv_string_chk(&argvars[1]);
- tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
+ const char *const varname = tv_get_string_chk(&argvars[1]);
+ tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
if (tp != NULL && varname != NULL) {
// Set tp to be our tabpage, temporarily. Also set the window to the
// first window in the tabpage, otherwise the window is not valid.
- win_T *window = tp->tp_firstwin == NULL ? firstwin : tp->tp_firstwin;
+ win_T *const window = tp == curtab || tp->tp_firstwin == NULL
+ ? firstwin
+ : tp->tp_firstwin;
if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) {
// look up the variable
// Let gettabvar({nr}, "") return the "t:" dictionary.
- v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE);
+ const dictitem_T *const v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't',
+ varname, strlen(varname),
+ false);
if (v != NULL) {
- copy_tv(&v->di_tv, rettv);
+ tv_copy(&v->di_tv, rettv);
done = true;
}
}
- /* restore previous notion of curwin */
- restore_win(oldcurwin, oldtabpage, TRUE);
+ // restore previous notion of curwin
+ restore_win(oldcurwin, oldtabpage, true);
}
if (!done && argvars[2].v_type != VAR_UNKNOWN) {
- copy_tv(&argvars[2], rettv);
+ tv_copy(&argvars[2], rettv);
}
}
/*
* "gettabwinvar()" function
*/
-static void f_gettabwinvar(typval_T *argvars, typval_T *rettv)
+static void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getwinvar(argvars, rettv, 1);
}
+/// Returns information about a window as a dictionary.
+static dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr)
+{
+ dict_T *const dict = tv_dict_alloc();
+
+ tv_dict_add_nr(dict, S_LEN("tabnr"), tpnr);
+ tv_dict_add_nr(dict, S_LEN("winnr"), winnr);
+ tv_dict_add_nr(dict, S_LEN("winid"), wp->handle);
+ tv_dict_add_nr(dict, S_LEN("height"), wp->w_height);
+ tv_dict_add_nr(dict, S_LEN("winrow"), wp->w_winrow);
+ tv_dict_add_nr(dict, S_LEN("width"), wp->w_width);
+ tv_dict_add_nr(dict, S_LEN("bufnr"), wp->w_buffer->b_fnum);
+ tv_dict_add_nr(dict, S_LEN("wincol"), wp->w_wincol);
+
+ tv_dict_add_nr(dict, S_LEN("quickfix"), bt_quickfix(wp->w_buffer));
+ tv_dict_add_nr(dict, S_LEN("loclist"),
+ (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL));
+
+ // Add a reference to window variables
+ tv_dict_add_dict(dict, S_LEN("variables"), wp->w_vars);
+
+ return dict;
+}
+
+/// "getwininfo()" function
+static void f_getwininfo(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ win_T *wparg = NULL;
+
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ wparg = win_id2wp(argvars);
+ if (wparg == NULL) {
+ return;
+ }
+ }
+
+ // Collect information about either all the windows across all the tab
+ // pages or one particular window.
+ int16_t tabnr = 0;
+ FOR_ALL_TABS(tp) {
+ tabnr++;
+ int16_t winnr = 0;
+ FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
+ winnr++;
+ if (wparg != NULL && wp != wparg) {
+ continue;
+ }
+ dict_T *const d = get_win_info(wp, tabnr, winnr);
+ tv_list_append_dict(rettv->vval.v_list, d);
+ if (wparg != NULL) {
+ // found information about a specific window
+ return;
+ }
+ }
+ }
+}
+
+// "win_screenpos()" function
+static void f_win_screenpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tv_list_alloc_ret(rettv, 2);
+ const win_T *const wp = find_win_by_nr(&argvars[0], NULL);
+ tv_list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_winrow + 1);
+ tv_list_append_number(rettv->vval.v_list, wp == NULL ? 0 : wp->w_wincol + 1);
+}
+
/*
* "getwinposx()" function
*/
-static void f_getwinposx(typval_T *argvars, typval_T *rettv)
+static void f_getwinposx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
}
@@ -10466,7 +10369,7 @@ static void f_getwinposx(typval_T *argvars, typval_T *rettv)
/*
* "getwinposy()" function
*/
-static void f_getwinposy(typval_T *argvars, typval_T *rettv)
+static void f_getwinposy(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = -1;
}
@@ -10480,7 +10383,7 @@ find_win_by_nr (
tabpage_T *tp /* NULL for current tab page */
)
{
- int nr = get_tv_number_chk(vp, NULL);
+ int nr = (int)tv_get_number_chk(vp, NULL);
if (nr < 0) {
return NULL;
@@ -10496,7 +10399,11 @@ find_win_by_nr (
}
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
- if (--nr <= 0) {
+ if (nr >= LOWEST_WIN_ID) {
+ if (wp->handle == nr) {
+ return wp;
+ }
+ } else if (--nr <= 0) {
return wp;
}
}
@@ -10511,7 +10418,7 @@ static win_T *find_tabwin(typval_T *wvp, typval_T *tvp)
if (wvp->v_type != VAR_UNKNOWN) {
if (tvp->v_type != VAR_UNKNOWN) {
- long n = get_tv_number(tvp);
+ long n = tv_get_number(tvp);
if (n >= 0) {
tp = find_tabpage(n);
}
@@ -10530,7 +10437,7 @@ static win_T *find_tabwin(typval_T *wvp, typval_T *tvp)
}
/// "getwinvar()" function
-static void f_getwinvar(typval_T *argvars, typval_T *rettv)
+static void f_getwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
getwinvar(argvars, rettv, 0);
}
@@ -10538,31 +10445,31 @@ static void f_getwinvar(typval_T *argvars, typval_T *rettv)
/*
* getwinvar() and gettabwinvar()
*/
-static void
-getwinvar (
+static void
+getwinvar(
typval_T *argvars,
typval_T *rettv,
int off /* 1 for gettabwinvar() */
)
{
win_T *win, *oldcurwin;
- char_u *varname;
dictitem_T *v;
tabpage_T *tp = NULL;
tabpage_T *oldtabpage = NULL;
bool done = false;
- if (off == 1)
- tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
- else
+ if (off == 1) {
+ tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+ } else {
tp = curtab;
+ }
win = find_win_by_nr(&argvars[off], tp);
- varname = get_tv_string_chk(&argvars[off + 1]);
- ++emsg_off;
+ const char *varname = tv_get_string_chk(&argvars[off + 1]);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
+ emsg_off++;
if (win != NULL && varname != NULL) {
// Set curwin to be our win, temporarily. Also set the tabpage,
// otherwise the window is not valid. Only do this when needed,
@@ -10570,16 +10477,26 @@ getwinvar (
bool need_switch_win = tp != curtab || win != curwin;
if (!need_switch_win
|| switch_win(&oldcurwin, &oldtabpage, win, tp, true) == OK) {
- if (*varname == '&') { // window-local-option
- if (get_option_tv(&varname, rettv, 1) == OK) {
+ if (*varname == '&') {
+ if (varname[1] == NUL) {
+ // get all window-local options in a dict
+ dict_T *opts = get_winbuf_options(false);
+
+ if (opts != NULL) {
+ tv_dict_set_ret(rettv, opts);
+ done = true;
+ }
+ } else if (get_option_tv(&varname, rettv, 1) == OK) {
+ // window-local-option
done = true;
}
} else {
// Look up the variable.
// Let getwinvar({nr}, "") return the "w:" dictionary.
- v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE);
+ v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname,
+ strlen(varname), false);
if (v != NULL) {
- copy_tv(&v->di_tv, rettv);
+ tv_copy(&v->di_tv, rettv);
done = true;
}
}
@@ -10590,36 +10507,36 @@ getwinvar (
restore_win(oldcurwin, oldtabpage, true);
}
}
+ emsg_off--;
- if (!done && argvars[off + 2].v_type != VAR_UNKNOWN)
- /* use the default return value */
- copy_tv(&argvars[off + 2], rettv);
-
- --emsg_off;
+ if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) {
+ // use the default return value
+ tv_copy(&argvars[off + 2], rettv);
+ }
}
/*
* "glob()" function
*/
-static void f_glob(typval_T *argvars, typval_T *rettv)
+static void f_glob(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int options = WILD_SILENT|WILD_USE_NL;
expand_T xpc;
- int error = FALSE;
+ bool error = false;
/* When the optional second argument is non-zero, don't remove matches
* for 'wildignore' and don't put matches for 'suffixes' at the end. */
rettv->v_type = VAR_STRING;
if (argvars[1].v_type != VAR_UNKNOWN) {
- if (get_tv_number_chk(&argvars[1], &error))
+ if (tv_get_number_chk(&argvars[1], &error)) {
options |= WILD_KEEP_ALL;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- if (get_tv_number_chk(&argvars[2], &error)) {
- rettv->v_type = VAR_LIST;
- rettv->vval.v_list = NULL;
+ if (tv_get_number_chk(&argvars[2], &error)) {
+ tv_list_set_ret(rettv, NULL);
}
if (argvars[3].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[3], &error)) {
+ && tv_get_number_chk(&argvars[3], &error)) {
options |= WILD_ALLLINKS;
}
}
@@ -10629,14 +10546,16 @@ static void f_glob(typval_T *argvars, typval_T *rettv)
xpc.xp_context = EXPAND_FILES;
if (p_wic)
options += WILD_ICASE;
- if (rettv->v_type == VAR_STRING)
- rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]),
- NULL, options, WILD_ALL);
- else {
- rettv_list_alloc(rettv);
- ExpandOne(&xpc, get_tv_string(&argvars[0]), NULL, options, WILD_ALL_KEEP);
+ if (rettv->v_type == VAR_STRING) {
+ rettv->vval.v_string = ExpandOne(
+ &xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options, WILD_ALL);
+ } else {
+ ExpandOne(&xpc, (char_u *)tv_get_string(&argvars[0]), NULL, options,
+ WILD_ALL_KEEP);
+ tv_list_alloc_ret(rettv, xpc.xp_numfiles);
for (int i = 0; i < xpc.xp_numfiles; i++) {
- list_append_string(rettv->vval.v_list, xpc.xp_files[i], -1);
+ tv_list_append_string(rettv->vval.v_list, (const char *)xpc.xp_files[i],
+ -1);
}
ExpandCleanup(&xpc);
}
@@ -10645,10 +10564,10 @@ static void f_glob(typval_T *argvars, typval_T *rettv)
}
/// "globpath()" function
-static void f_globpath(typval_T *argvars, typval_T *rettv)
+static void f_globpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int flags = 0; // Flags for globpath.
- int error = false;
+ bool error = false;
// Return a string, or a list if the optional third argument is non-zero.
rettv->v_type = VAR_STRING;
@@ -10656,36 +10575,35 @@ static void f_globpath(typval_T *argvars, typval_T *rettv)
if (argvars[2].v_type != VAR_UNKNOWN) {
// When the optional second argument is non-zero, don't remove matches
// for 'wildignore' and don't put matches for 'suffixes' at the end.
- if (get_tv_number_chk(&argvars[2], &error)) {
+ if (tv_get_number_chk(&argvars[2], &error)) {
flags |= WILD_KEEP_ALL;
}
if (argvars[3].v_type != VAR_UNKNOWN) {
- if (get_tv_number_chk(&argvars[3], &error)) {
- rettv->v_type = VAR_LIST;
- rettv->vval.v_list = NULL;
+ if (tv_get_number_chk(&argvars[3], &error)) {
+ tv_list_set_ret(rettv, NULL);
}
if (argvars[4].v_type != VAR_UNKNOWN
- && get_tv_number_chk(&argvars[4], &error)) {
+ && tv_get_number_chk(&argvars[4], &error)) {
flags |= WILD_ALLLINKS;
}
}
}
- char_u buf1[NUMBUFLEN];
- char_u *file = get_tv_string_buf_chk(&argvars[1], buf1);
+ char buf1[NUMBUFLEN];
+ const char *const file = tv_get_string_buf_chk(&argvars[1], buf1);
if (file != NULL && !error) {
garray_T ga;
ga_init(&ga, (int)sizeof(char_u *), 10);
- globpath(get_tv_string(&argvars[0]), file, &ga, flags);
+ globpath((char_u *)tv_get_string(&argvars[0]), (char_u *)file, &ga, flags);
if (rettv->v_type == VAR_STRING) {
rettv->vval.v_string = ga_concat_strings_sep(&ga, "\n");
} else {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, ga.ga_len);
for (int i = 0; i < ga.ga_len; i++) {
- list_append_string(rettv->vval.v_list,
- ((char_u **)(ga.ga_data))[i], -1);
+ tv_list_append_string(rettv->vval.v_list,
+ ((const char **)(ga.ga_data))[i], -1);
}
}
@@ -10696,26 +10614,21 @@ static void f_globpath(typval_T *argvars, typval_T *rettv)
}
// "glob2regpat()" function
-static void f_glob2regpat(typval_T *argvars, typval_T *rettv)
+static void f_glob2regpat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *pat = get_tv_string_chk(&argvars[0]); // NULL on type error
+ const char *const pat = tv_get_string_chk(&argvars[0]); // NULL on type error
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = (pat == NULL)
- ? NULL
- : file_pat_to_reg_pat(pat, NULL, NULL, false);
+ rettv->vval.v_string = ((pat == NULL)
+ ? NULL
+ : file_pat_to_reg_pat((char_u *)pat, NULL, NULL,
+ false));
}
-/*
- * "has()" function
- */
-static void f_has(typval_T *argvars, typval_T *rettv)
+/// "has()" function
+static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int i;
- char_u *name;
- int n = FALSE;
- static char *(has_list[]) =
- {
+ static const char *const has_list[] = {
#ifdef UNIX
"unix",
#endif
@@ -10729,6 +10642,7 @@ static void f_has(typval_T *argvars, typval_T *rettv)
#ifdef HAVE_ACL
"acl",
#endif
+ "autochdir",
"arabic",
"autocmd",
"browsefilter",
@@ -10766,6 +10680,7 @@ static void f_has(typval_T *argvars, typval_T *rettv)
"insert_expand",
"jumplist",
"keymap",
+ "lambda",
"langmap",
"libcall",
"linebreak",
@@ -10782,12 +10697,14 @@ static void f_has(typval_T *argvars, typval_T *rettv)
"mouse",
"multi_byte",
"multi_lang",
+ "num64",
"packages",
"path_extra",
"persistent_undo",
"postscript",
"printer",
"profile",
+ "pythonx",
"reltime",
"quickfix",
"rightleft",
@@ -10824,51 +10741,66 @@ static void f_has(typval_T *argvars, typval_T *rettv)
"windows",
"winaltkeys",
"writebackup",
+#if defined(HAVE_WSL)
+ "wsl",
+#endif
"nvim",
- NULL
};
- name = get_tv_string(&argvars[0]);
- for (i = 0; has_list[i] != NULL; ++i)
+ bool n = false;
+ const char *const name = tv_get_string(&argvars[0]);
+ for (size_t i = 0; i < ARRAY_SIZE(has_list); i++) {
if (STRICMP(name, has_list[i]) == 0) {
- n = TRUE;
+ n = true;
break;
}
+ }
- if (n == FALSE) {
+ if (!n) {
if (STRNICMP(name, "patch", 5) == 0) {
if (name[5] == '-'
- && STRLEN(name) > 11
+ && strlen(name) >= 11
&& ascii_isdigit(name[6])
&& ascii_isdigit(name[8])
&& ascii_isdigit(name[10])) {
- int major = atoi((char *)name + 6);
- int minor = atoi((char *)name + 8);
+ int major = atoi(name + 6);
+ int minor = atoi(name + 8);
// Expect "patch-9.9.01234".
n = (major < VIM_VERSION_MAJOR
|| (major == VIM_VERSION_MAJOR
&& (minor < VIM_VERSION_MINOR
|| (minor == VIM_VERSION_MINOR
- && has_patch(atoi((char *)name + 10))))));
+ && has_vim_patch(atoi(name + 10))))));
} else {
- n = has_patch(atoi((char *)name + 5));
+ n = has_vim_patch(atoi(name + 5));
}
+ } else if (STRNICMP(name, "nvim-", 5) == 0) {
+ // Expect "nvim-x.y.z"
+ n = has_nvim_version(name + 5);
} else if (STRICMP(name, "vim_starting") == 0) {
n = (starting != 0);
+ } else if (STRICMP(name, "ttyin") == 0) {
+ n = stdin_isatty;
+ } else if (STRICMP(name, "ttyout") == 0) {
+ n = stdout_isatty;
} else if (STRICMP(name, "multi_byte_encoding") == 0) {
- n = has_mbyte;
+ n = has_mbyte != 0;
#if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
} else if (STRICMP(name, "iconv") == 0) {
n = iconv_enabled(false);
#endif
} else if (STRICMP(name, "syntax_items") == 0) {
n = syntax_present(curwin);
+#ifdef UNIX
+ } else if (STRICMP(name, "unnamedplus") == 0) {
+ n = eval_has_provider("clipboard");
+#endif
}
}
- if (n == FALSE && eval_has_provider((char *)name)) {
- n = TRUE;
+ if (!n && eval_has_provider(name)) {
+ n = true;
}
rettv->vval.v_number = n;
@@ -10877,7 +10809,7 @@ static void f_has(typval_T *argvars, typval_T *rettv)
/*
* "has_key()" function
*/
-static void f_has_key(typval_T *argvars, typval_T *rettv)
+static void f_has_key(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
@@ -10886,8 +10818,9 @@ static void f_has_key(typval_T *argvars, typval_T *rettv)
if (argvars[0].vval.v_dict == NULL)
return;
- rettv->vval.v_number = dict_find(argvars[0].vval.v_dict,
- get_tv_string(&argvars[1]), -1) != NULL;
+ rettv->vval.v_number = tv_dict_find(argvars[0].vval.v_dict,
+ tv_get_string(&argvars[1]),
+ -1) != NULL;
}
/// `haslocaldir([{win}[, {tab}]])` function
@@ -10901,7 +10834,7 @@ static void f_has_key(typval_T *argvars, typval_T *rettv)
/// @pre An argument may not be -1 if preceding arguments are not all -1.
///
/// @post The return value will be either the number `1` or `0`.
-static void f_haslocaldir(typval_T *argvars, typval_T *rettv)
+static void f_haslocaldir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
// Possible scope of working directory to return.
CdScope scope = kCdScopeInvalid;
@@ -10951,7 +10884,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv)
if (scope_number[kCdScopeTab] > 0) {
tp = find_tabpage(scope_number[kCdScopeTab]);
if (!tp) {
- EMSG(_("5000: Cannot find tab number."));
+ EMSG(_("E5000: Cannot find tab number."));
return;
}
}
@@ -10979,7 +10912,7 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv)
break;
case kCdScopeTab:
assert(tp);
- rettv->vval.v_number = tp->localdir ? 1 : 0;
+ rettv->vval.v_number = tp->tp_localdir ? 1 : 0;
break;
case kCdScopeGlobal:
// The global scope never has a local directory
@@ -10994,48 +10927,47 @@ static void f_haslocaldir(typval_T *argvars, typval_T *rettv)
/*
* "hasmapto()" function
*/
-static void f_hasmapto(typval_T *argvars, typval_T *rettv)
+static void f_hasmapto(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *name;
- char_u *mode;
- char_u buf[NUMBUFLEN];
- int abbr = FALSE;
-
- name = get_tv_string(&argvars[0]);
- if (argvars[1].v_type == VAR_UNKNOWN)
- mode = (char_u *)"nvo";
- else {
- mode = get_tv_string_buf(&argvars[1], buf);
- if (argvars[2].v_type != VAR_UNKNOWN)
- abbr = get_tv_number(&argvars[2]);
+ const char *mode;
+ const char *const name = tv_get_string(&argvars[0]);
+ bool abbr = false;
+ char buf[NUMBUFLEN];
+ if (argvars[1].v_type == VAR_UNKNOWN) {
+ mode = "nvo";
+ } else {
+ mode = tv_get_string_buf(&argvars[1], buf);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ abbr = tv_get_number(&argvars[2]);
+ }
}
- if (map_to_exists(name, mode, abbr))
- rettv->vval.v_number = TRUE;
- else
- rettv->vval.v_number = FALSE;
+ if (map_to_exists(name, mode, abbr)) {
+ rettv->vval.v_number = true;
+ } else {
+ rettv->vval.v_number = false;
+ }
}
/*
* "histadd()" function
*/
-static void f_histadd(typval_T *argvars, typval_T *rettv)
+static void f_histadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
HistoryType histype;
- char_u *str;
- char_u buf[NUMBUFLEN];
rettv->vval.v_number = false;
if (check_restricted() || check_secure()) {
return;
}
- str = get_tv_string_chk(&argvars[0]); // NULL on type error
- histype = str != NULL ? get_histtype(str, STRLEN(str), false) : HIST_INVALID;
+ const char *str = tv_get_string_chk(&argvars[0]); // NULL on type error
+ histype = str != NULL ? get_histtype(str, strlen(str), false) : HIST_INVALID;
if (histype != HIST_INVALID) {
- str = get_tv_string_buf(&argvars[1], buf);
+ char buf[NUMBUFLEN];
+ str = tv_get_string_buf(&argvars[1], buf);
if (*str != NUL) {
init_history();
- add_to_history(histype, str, false, NUL);
+ add_to_history(histype, (char_u *)str, false, NUL);
rettv->vval.v_number = true;
return;
}
@@ -11045,26 +10977,24 @@ static void f_histadd(typval_T *argvars, typval_T *rettv)
/*
* "histdel()" function
*/
-static void f_histdel(typval_T *argvars, typval_T *rettv)
+static void f_histdel(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n;
- char_u buf[NUMBUFLEN];
- char_u *str;
-
- str = get_tv_string_chk(&argvars[0]); // NULL on type error
+ const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error
if (str == NULL) {
n = 0;
} else if (argvars[1].v_type == VAR_UNKNOWN) {
// only one argument: clear entire history
- n = clr_history(get_histtype(str, STRLEN(str), false));
+ n = clr_history(get_histtype(str, strlen(str), false));
} else if (argvars[1].v_type == VAR_NUMBER) {
// index given: remove that entry
- n = del_history_idx(get_histtype(str, STRLEN(str), false),
- (int) get_tv_number(&argvars[1]));
+ n = del_history_idx(get_histtype(str, strlen(str), false),
+ (int)tv_get_number(&argvars[1]));
} else {
// string given: remove all matching entries
- n = del_history_entry(get_histtype(str, STRLEN(str), false),
- get_tv_string_buf(&argvars[1], buf));
+ char buf[NUMBUFLEN];
+ n = del_history_entry(get_histtype(str, strlen(str), false),
+ (char_u *)tv_get_string_buf(&argvars[1], buf));
}
rettv->vval.v_number = n;
}
@@ -11072,21 +11002,20 @@ static void f_histdel(typval_T *argvars, typval_T *rettv)
/*
* "histget()" function
*/
-static void f_histget(typval_T *argvars, typval_T *rettv)
+static void f_histget(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
HistoryType type;
int idx;
- char_u *str;
- str = get_tv_string_chk(&argvars[0]); // NULL on type error
+ const char *const str = tv_get_string_chk(&argvars[0]); // NULL on type error
if (str == NULL) {
rettv->vval.v_string = NULL;
} else {
- type = get_histtype(str, STRLEN(str), false);
+ type = get_histtype(str, strlen(str), false);
if (argvars[1].v_type == VAR_UNKNOWN) {
idx = get_history_idx(type);
} else {
- idx = (int)get_tv_number_chk(&argvars[1], NULL);
+ idx = (int)tv_get_number_chk(&argvars[1], NULL);
}
// -1 on type error
rettv->vval.v_string = vim_strsave(get_history_entry(type, idx));
@@ -11097,13 +11026,13 @@ static void f_histget(typval_T *argvars, typval_T *rettv)
/*
* "histnr()" function
*/
-static void f_histnr(typval_T *argvars, typval_T *rettv)
+static void f_histnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int i;
- char_u *history = get_tv_string_chk(&argvars[0]);
+ const char *const history = tv_get_string_chk(&argvars[0]);
- i = history == NULL ? HIST_CMD - 1 : get_histtype(history, STRLEN(history),
+ i = history == NULL ? HIST_CMD - 1 : get_histtype(history, strlen(history),
false);
if (i != HIST_INVALID) {
i = get_history_idx(i);
@@ -11116,23 +11045,25 @@ static void f_histnr(typval_T *argvars, typval_T *rettv)
/*
* "highlightID(name)" function
*/
-static void f_hlID(typval_T *argvars, typval_T *rettv)
+static void f_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
+ rettv->vval.v_number = syn_name2id(
+ (const char_u *)tv_get_string(&argvars[0]));
}
/*
* "highlight_exists()" function
*/
-static void f_hlexists(typval_T *argvars, typval_T *rettv)
+static void f_hlexists(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0]));
+ rettv->vval.v_number = highlight_exists(
+ (const char_u *)tv_get_string(&argvars[0]));
}
/*
* "hostname()" function
*/
-static void f_hostname(typval_T *argvars, typval_T *rettv)
+static void f_hostname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char hostname[256];
@@ -11144,27 +11075,29 @@ static void f_hostname(typval_T *argvars, typval_T *rettv)
/*
* iconv() function
*/
-static void f_iconv(typval_T *argvars, typval_T *rettv)
+static void f_iconv(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf1[NUMBUFLEN];
- char_u buf2[NUMBUFLEN];
- char_u *from, *to, *str;
vimconv_T vimconv;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- str = get_tv_string(&argvars[0]);
- from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1)));
- to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2)));
+ const char *const str = tv_get_string(&argvars[0]);
+ char buf1[NUMBUFLEN];
+ char_u *const from = enc_canonize(enc_skip(
+ (char_u *)tv_get_string_buf(&argvars[1], buf1)));
+ char buf2[NUMBUFLEN];
+ char_u *const to = enc_canonize(enc_skip(
+ (char_u *)tv_get_string_buf(&argvars[2], buf2)));
vimconv.vc_type = CONV_NONE;
convert_setup(&vimconv, from, to);
- /* If the encodings are equal, no conversion needed. */
- if (vimconv.vc_type == CONV_NONE)
- rettv->vval.v_string = vim_strsave(str);
- else
- rettv->vval.v_string = string_convert(&vimconv, str, NULL);
+ // If the encodings are equal, no conversion needed.
+ if (vimconv.vc_type == CONV_NONE) {
+ rettv->vval.v_string = (char_u *)xstrdup(str);
+ } else {
+ rettv->vval.v_string = string_convert(&vimconv, (char_u *)str, NULL);
+ }
convert_setup(&vimconv, NULL, NULL);
xfree(from);
@@ -11174,53 +11107,57 @@ static void f_iconv(typval_T *argvars, typval_T *rettv)
/*
* "indent()" function
*/
-static void f_indent(typval_T *argvars, typval_T *rettv)
+static void f_indent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
-
- lnum = get_tv_lnum(argvars);
- if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
rettv->vval.v_number = get_indent_lnum(lnum);
- else
+ } else {
rettv->vval.v_number = -1;
+ }
}
/*
* "index()" function
*/
-static void f_index(typval_T *argvars, typval_T *rettv)
+static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- list_T *l;
- listitem_T *item;
long idx = 0;
- int ic = FALSE;
+ bool ic = false;
rettv->vval.v_number = -1;
if (argvars[0].v_type != VAR_LIST) {
EMSG(_(e_listreq));
return;
}
- l = argvars[0].vval.v_list;
+ list_T *const l = argvars[0].vval.v_list;
if (l != NULL) {
- item = l->lv_first;
+ listitem_T *item = tv_list_first(l);
if (argvars[2].v_type != VAR_UNKNOWN) {
- int error = FALSE;
+ bool error = false;
- /* Start at specified item. Use the cached index that list_find()
- * sets, so that a negative number also works. */
- item = list_find(l, get_tv_number_chk(&argvars[2], &error));
- idx = l->lv_idx;
- if (argvars[3].v_type != VAR_UNKNOWN)
- ic = get_tv_number_chk(&argvars[3], &error);
- if (error)
+ // Start at specified item.
+ idx = tv_list_uidx(l, tv_get_number_chk(&argvars[2], &error));
+ if (error || idx == -1) {
item = NULL;
+ } else {
+ item = tv_list_find(l, idx);
+ assert(item != NULL);
+ }
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ ic = !!tv_get_number_chk(&argvars[3], &error);
+ if (error) {
+ item = NULL;
+ }
+ }
}
- for (; item != NULL; item = item->li_next, ++idx)
- if (tv_equal(&item->li_tv, &argvars[1], ic, FALSE)) {
+ for (; item != NULL; item = TV_LIST_ITEM_NEXT(l, item), idx++) {
+ if (tv_equal(TV_LIST_ITEM_TV(item), &argvars[1], ic, false)) {
rettv->vval.v_number = idx;
break;
}
+ }
}
}
@@ -11233,85 +11170,132 @@ static int inputsecret_flag = 0;
* prompt. The third argument to f_inputdialog() specifies the value to return
* when the user cancels the prompt.
*/
-static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog)
+void get_user_input(const typval_T *const argvars,
+ typval_T *const rettv, const bool inputdialog)
+ FUNC_ATTR_NONNULL_ALL
{
- char_u *prompt = get_tv_string_chk(&argvars[0]);
- char_u *p = NULL;
- int c;
- char_u buf[NUMBUFLEN];
- int cmd_silent_save = cmd_silent;
- char_u *defstr = (char_u *)"";
- int xp_type = EXPAND_NOTHING;
- char_u *xp_arg = NULL;
-
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- cmd_silent = FALSE; /* Want to see the prompt. */
- if (prompt != NULL) {
- /* Only the part of the message after the last NL is considered as
- * prompt for the command line */
- p = vim_strrchr(prompt, '\n');
- if (p == NULL)
- p = prompt;
- else {
- ++p;
- c = *p;
- *p = NUL;
- msg_start();
- msg_clr_eos();
- msg_puts_attr(prompt, echo_attr);
- msg_didout = FALSE;
- msg_starthere();
- *p = c;
+ const char *prompt = "";
+ const char *defstr = "";
+ const char *cancelreturn = NULL;
+ const char *xp_name = NULL;
+ Callback input_callback = { .type = kCallbackNone };
+ char prompt_buf[NUMBUFLEN];
+ char defstr_buf[NUMBUFLEN];
+ char cancelreturn_buf[NUMBUFLEN];
+ char xp_name_buf[NUMBUFLEN];
+ char def[1] = { 0 };
+ if (argvars[0].v_type == VAR_DICT) {
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ EMSG(_("E5050: {opts} must be the only argument"));
+ return;
+ }
+ dict_T *const dict = argvars[0].vval.v_dict;
+ prompt = tv_dict_get_string_buf_chk(dict, S_LEN("prompt"), prompt_buf, "");
+ if (prompt == NULL) {
+ return;
+ }
+ defstr = tv_dict_get_string_buf_chk(dict, S_LEN("default"), defstr_buf, "");
+ if (defstr == NULL) {
+ return;
+ }
+ cancelreturn = tv_dict_get_string_buf_chk(dict, S_LEN("cancelreturn"),
+ cancelreturn_buf, def);
+ if (cancelreturn == NULL) { // error
+ return;
+ }
+ if (*cancelreturn == NUL) {
+ cancelreturn = NULL;
+ }
+ xp_name = tv_dict_get_string_buf_chk(dict, S_LEN("completion"),
+ xp_name_buf, def);
+ if (xp_name == NULL) { // error
+ return;
+ }
+ if (xp_name == def) { // default to NULL
+ xp_name = NULL;
+ }
+ if (!tv_dict_get_callback(dict, S_LEN("highlight"), &input_callback)) {
+ return;
+ }
+ } else {
+ prompt = tv_get_string_buf_chk(&argvars[0], prompt_buf);
+ if (prompt == NULL) {
+ return;
}
- cmdline_row = msg_row;
-
if (argvars[1].v_type != VAR_UNKNOWN) {
- defstr = get_tv_string_buf_chk(&argvars[1], buf);
- if (defstr != NULL)
- stuffReadbuffSpec(defstr);
-
- if (!inputdialog && argvars[2].v_type != VAR_UNKNOWN) {
- char_u *xp_name;
- int xp_namelen;
- uint32_t argt;
-
- /* input() with a third argument: completion */
- rettv->vval.v_string = NULL;
-
- xp_name = get_tv_string_buf_chk(&argvars[2], buf);
- if (xp_name == NULL)
- return;
-
- xp_namelen = (int)STRLEN(xp_name);
-
- if (parse_compl_arg(xp_name, xp_namelen, &xp_type, &argt,
- &xp_arg) == FAIL)
+ defstr = tv_get_string_buf_chk(&argvars[1], defstr_buf);
+ if (defstr == NULL) {
+ return;
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ const char *const arg2 = tv_get_string_buf_chk(&argvars[2],
+ cancelreturn_buf);
+ if (arg2 == NULL) {
return;
+ }
+ if (inputdialog) {
+ cancelreturn = arg2;
+ } else {
+ xp_name = arg2;
+ }
}
}
+ }
- if (defstr != NULL) {
- int save_ex_normal_busy = ex_normal_busy;
- ex_normal_busy = 0;
- rettv->vval.v_string =
- getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr,
- xp_type, xp_arg);
- ex_normal_busy = save_ex_normal_busy;
+ int xp_type = EXPAND_NOTHING;
+ char *xp_arg = NULL;
+ if (xp_name != NULL) {
+ // input() with a third argument: completion
+ const int xp_namelen = (int)strlen(xp_name);
+
+ uint32_t argt;
+ if (parse_compl_arg((char_u *)xp_name, xp_namelen, &xp_type,
+ &argt, (char_u **)&xp_arg) == FAIL) {
+ return;
}
- if (inputdialog && rettv->vval.v_string == NULL
- && argvars[1].v_type != VAR_UNKNOWN
- && argvars[2].v_type != VAR_UNKNOWN)
- rettv->vval.v_string = vim_strsave(get_tv_string_buf(
- &argvars[2], buf));
+ }
- xfree(xp_arg);
+ const bool cmd_silent_save = cmd_silent;
- /* since the user typed this, no need to wait for return */
- need_wait_return = FALSE;
- msg_didout = FALSE;
+ cmd_silent = false; // Want to see the prompt.
+ // Only the part of the message after the last NL is considered as
+ // prompt for the command line, unlsess cmdline is externalized
+ const char *p = prompt;
+ if (!ui_is_external(kUICmdline)) {
+ const char *lastnl = strrchr(prompt, '\n');
+ if (lastnl != NULL) {
+ p = lastnl+1;
+ msg_start();
+ msg_clr_eos();
+ msg_puts_attr_len(prompt, p - prompt, echo_attr);
+ msg_didout = false;
+ msg_starthere();
+ }
+ }
+ cmdline_row = msg_row;
+
+ stuffReadbuffSpec(defstr);
+
+ const int save_ex_normal_busy = ex_normal_busy;
+ ex_normal_busy = 0;
+ rettv->vval.v_string =
+ (char_u *)getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr,
+ xp_type, xp_arg, input_callback);
+ ex_normal_busy = save_ex_normal_busy;
+ callback_free(&input_callback);
+
+ if (rettv->vval.v_string == NULL && cancelreturn != NULL) {
+ rettv->vval.v_string = (char_u *)xstrdup(cancelreturn);
}
+
+ xfree(xp_arg);
+
+ // Since the user typed this, no need to wait for return.
+ need_wait_return = false;
+ msg_didout = false;
cmd_silent = cmd_silent_save;
}
@@ -11319,7 +11303,7 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog)
* "input()" function
* Also handles inputsecret() when inputsecret is set.
*/
-static void f_input(typval_T *argvars, typval_T *rettv)
+static void f_input(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_user_input(argvars, rettv, FALSE);
}
@@ -11327,7 +11311,7 @@ static void f_input(typval_T *argvars, typval_T *rettv)
/*
* "inputdialog()" function
*/
-static void f_inputdialog(typval_T *argvars, typval_T *rettv)
+static void f_inputdialog(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_user_input(argvars, rettv, TRUE);
}
@@ -11335,13 +11319,12 @@ static void f_inputdialog(typval_T *argvars, typval_T *rettv)
/*
* "inputlist()" function
*/
-static void f_inputlist(typval_T *argvars, typval_T *rettv)
+static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- listitem_T *li;
int selected;
int mouse_used;
- if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL) {
+ if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "inputlist()");
return;
}
@@ -11352,15 +11335,16 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv)
msg_scroll = TRUE;
msg_clr_eos();
- for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) {
- msg_puts(get_tv_string(&li->li_tv));
+ TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, {
+ msg_puts(tv_get_string(TV_LIST_ITEM_TV(li)));
msg_putchar('\n');
- }
+ });
- /* Ask for choice. */
+ // Ask for choice.
selected = prompt_for_number(&mouse_used);
- if (mouse_used)
+ if (mouse_used) {
selected -= lines_left;
+ }
rettv->vval.v_number = selected;
}
@@ -11371,7 +11355,7 @@ static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
/*
* "inputrestore()" function
*/
-static void f_inputrestore(typval_T *argvars, typval_T *rettv)
+static void f_inputrestore(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (!GA_EMPTY(&ga_userinput)) {
--ga_userinput.ga_len;
@@ -11387,7 +11371,7 @@ static void f_inputrestore(typval_T *argvars, typval_T *rettv)
/*
* "inputsave()" function
*/
-static void f_inputsave(typval_T *argvars, typval_T *rettv)
+static void f_inputsave(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
// Add an entry to the stack of typeahead storage.
tasave_T *p = GA_APPEND_VIA_PTR(tasave_T, &ga_userinput);
@@ -11397,50 +11381,47 @@ static void f_inputsave(typval_T *argvars, typval_T *rettv)
/*
* "inputsecret()" function
*/
-static void f_inputsecret(typval_T *argvars, typval_T *rettv)
+static void f_inputsecret(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- ++cmdline_star;
- ++inputsecret_flag;
- f_input(argvars, rettv);
- --cmdline_star;
- --inputsecret_flag;
+ cmdline_star++;
+ inputsecret_flag++;
+ f_input(argvars, rettv, NULL);
+ cmdline_star--;
+ inputsecret_flag--;
}
/*
* "insert()" function
*/
-static void f_insert(typval_T *argvars, typval_T *rettv)
+static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long before = 0;
- listitem_T *item;
- list_T *l;
- int error = FALSE;
+ list_T *l;
+ bool error = false;
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "insert()");
- } else if ((l = argvars[0].vval.v_list) != NULL
- && !tv_check_lock(l->lv_lock,
- (char_u *)N_("insert() argument"), true)) {
+ } else if (!tv_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
+ N_("insert() argument"), TV_TRANSLATE)) {
+ long before = 0;
if (argvars[2].v_type != VAR_UNKNOWN) {
- before = get_tv_number_chk(&argvars[2], &error);
+ before = tv_get_number_chk(&argvars[2], &error);
}
if (error) {
// type error; errmsg already given
return;
}
- if (before == l->lv_len)
- item = NULL;
- else {
- item = list_find(l, before);
+ listitem_T *item = NULL;
+ if (before != tv_list_len(l)) {
+ item = tv_list_find(l, before);
if (item == NULL) {
EMSGN(_(e_listidx), before);
l = NULL;
}
}
if (l != NULL) {
- list_insert_tv(l, &argvars[1], item);
- copy_tv(&argvars[0], rettv);
+ tv_list_insert_tv(l, &argvars[1], item);
+ tv_copy(&argvars[0], rettv);
}
}
}
@@ -11448,60 +11429,58 @@ static void f_insert(typval_T *argvars, typval_T *rettv)
/*
* "invert(expr)" function
*/
-static void f_invert(typval_T *argvars, typval_T *rettv)
+static void f_invert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL);
+ rettv->vval.v_number = ~tv_get_number_chk(&argvars[0], NULL);
}
/*
* "isdirectory()" function
*/
-static void f_isdirectory(typval_T *argvars, typval_T *rettv)
+static void f_isdirectory(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = os_isdir(get_tv_string(&argvars[0]));
+ rettv->vval.v_number = os_isdir((const char_u *)tv_get_string(&argvars[0]));
}
/*
* "islocked()" function
*/
-static void f_islocked(typval_T *argvars, typval_T *rettv)
+static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
lval_T lv;
- char_u *end;
dictitem_T *di;
rettv->vval.v_number = -1;
- end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE,
- GLV_NO_AUTOLOAD, FNE_CHECK_START);
+ const char_u *const end = get_lval((char_u *)tv_get_string(&argvars[0]),
+ NULL,
+ &lv, false, false,
+ GLV_NO_AUTOLOAD|GLV_READ_ONLY,
+ FNE_CHECK_START);
if (end != NULL && lv.ll_name != NULL) {
- if (*end != NUL)
+ if (*end != NUL) {
EMSG(_(e_trailing));
- else {
+ } else {
if (lv.ll_tv == NULL) {
- if (check_changedtick(lv.ll_name))
- rettv->vval.v_number = 1; /* always locked */
- else {
- di = find_var(lv.ll_name, NULL, TRUE);
- if (di != NULL) {
- /* Consider a variable locked when:
- * 1. the variable itself is locked
- * 2. the value of the variable is locked.
- * 3. the List or Dict value is locked.
- */
- rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
- || tv_islocked(&di->di_tv));
- }
+ di = find_var((const char *)lv.ll_name, lv.ll_name_len, NULL, true);
+ if (di != NULL) {
+ // Consider a variable locked when:
+ // 1. the variable itself is locked
+ // 2. the value of the variable is locked.
+ // 3. the List or Dict value is locked.
+ rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK)
+ || tv_islocked(&di->di_tv));
}
- } else if (lv.ll_range)
+ } else if (lv.ll_range) {
EMSG(_("E786: Range not allowed"));
- else if (lv.ll_newkey != NULL)
+ } else if (lv.ll_newkey != NULL) {
EMSG2(_(e_dictkey), lv.ll_newkey);
- else if (lv.ll_list != NULL)
- /* List item. */
- rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv);
- else
- /* Dictionary item. */
+ } else if (lv.ll_list != NULL) {
+ // List item.
+ rettv->vval.v_number = tv_islocked(TV_LIST_ITEM_TV(lv.ll_li));
+ } else {
+ // Dictionary item.
rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv);
+ }
}
}
@@ -11509,120 +11488,81 @@ static void f_islocked(typval_T *argvars, typval_T *rettv)
}
-/*
- * Turn a dict into a list:
- * "what" == 0: list of keys
- * "what" == 1: list of values
- * "what" == 2: list of items
- */
-static void dict_list(typval_T *argvars, typval_T *rettv, int what)
-{
- list_T *l2;
- dictitem_T *di;
- hashitem_T *hi;
- listitem_T *li;
- listitem_T *li2;
- dict_T *d;
- int todo;
-
- if (argvars[0].v_type != VAR_DICT) {
+/// Turn a dictionary into a list
+///
+/// @param[in] tv Dictionary to convert. Is checked for actually being
+/// a dictionary, will give an error if not.
+/// @param[out] rettv Location where result will be saved.
+/// @param[in] what What to save in rettv.
+static void dict_list(typval_T *const tv, typval_T *const rettv,
+ const DictListType what)
+{
+ if (tv->v_type != VAR_DICT) {
EMSG(_(e_dictreq));
return;
}
- if ((d = argvars[0].vval.v_dict) == NULL)
+ if (tv->vval.v_dict == NULL) {
return;
+ }
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, tv_dict_len(tv->vval.v_dict));
- todo = (int)d->dv_hashtab.ht_used;
- for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- di = HI2DI(hi);
-
- li = listitem_alloc();
- list_append(rettv->vval.v_list, li);
-
- if (what == 0) {
- /* keys() */
- li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = vim_strsave(di->di_key);
- } else if (what == 1) {
- /* values() */
- copy_tv(&di->di_tv, &li->li_tv);
- } else {
- /* items() */
- l2 = list_alloc();
- li->li_tv.v_type = VAR_LIST;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_list = l2;
- ++l2->lv_refcount;
+ TV_DICT_ITER(tv->vval.v_dict, di, {
+ typval_T tv_item = { .v_lock = VAR_UNLOCKED };
- li2 = listitem_alloc();
- list_append(l2, li2);
- li2->li_tv.v_type = VAR_STRING;
- li2->li_tv.v_lock = 0;
- li2->li_tv.vval.v_string = vim_strsave(di->di_key);
+ switch (what) {
+ case kDictListKeys: {
+ tv_item.v_type = VAR_STRING;
+ tv_item.vval.v_string = vim_strsave(di->di_key);
+ break;
+ }
+ case kDictListValues: {
+ tv_copy(&di->di_tv, &tv_item);
+ break;
+ }
+ case kDictListItems: {
+ // items()
+ list_T *const sub_l = tv_list_alloc(2);
+ tv_item.v_type = VAR_LIST;
+ tv_item.vval.v_list = sub_l;
+ tv_list_ref(sub_l);
+
+ tv_list_append_owned_tv(sub_l, (typval_T) {
+ .v_type = VAR_STRING,
+ .v_lock = VAR_UNLOCKED,
+ .vval.v_string = (char_u *)xstrdup((const char *)di->di_key),
+ });
- li2 = listitem_alloc();
- list_append(l2, li2);
- copy_tv(&di->di_tv, &li2->li_tv);
+ tv_list_append_tv(sub_l, &di->di_tv);
+
+ break;
}
}
- }
+
+ tv_list_append_owned_tv(rettv->vval.v_list, tv_item);
+ });
+}
+
+/// "id()" function
+static void f_id(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const int len = vim_vsnprintf(NULL, 0, "%p", dummy_ap, argvars);
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = xmalloc(len + 1);
+ vim_vsnprintf((char *)rettv->vval.v_string, len + 1, "%p", dummy_ap, argvars);
}
/*
* "items(dict)" function
*/
-static void f_items(typval_T *argvars, typval_T *rettv)
+static void f_items(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 2);
}
-// "jobclose(id[, stream])" function
-static void f_jobclose(typval_T *argvars, typval_T *rettv)
-{
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = 0;
-
- if (check_restricted() || check_secure()) {
- return;
- }
-
- if (argvars[0].v_type != VAR_NUMBER || (argvars[1].v_type != VAR_STRING
- && argvars[1].v_type != VAR_UNKNOWN)) {
- EMSG(_(e_invarg));
- return;
- }
-
- TerminalJobData *data = find_job(argvars[0].vval.v_number);
- if (!data) {
- EMSG(_(e_invjob));
- return;
- }
-
- Process *proc = (Process *)&data->proc;
-
- if (argvars[1].v_type == VAR_STRING) {
- char *stream = (char *)argvars[1].vval.v_string;
- if (!strcmp(stream, "stdin")) {
- process_close_in(proc);
- } else if (!strcmp(stream, "stdout")) {
- process_close_out(proc);
- } else if (!strcmp(stream, "stderr")) {
- process_close_err(proc);
- } else {
- EMSG2(_("Invalid job stream \"%s\""), stream);
- }
- } else {
- process_close_streams(proc);
- }
-}
-
// "jobpid(id)" function
-static void f_jobpid(typval_T *argvars, typval_T *rettv)
+static void f_jobpid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -11636,58 +11576,17 @@ static void f_jobpid(typval_T *argvars, typval_T *rettv)
return;
}
- TerminalJobData *data = find_job(argvars[0].vval.v_number);
+ Channel *data = find_job(argvars[0].vval.v_number, true);
if (!data) {
- EMSG(_(e_invjob));
return;
}
- Process *proc = (Process *)&data->proc;
+ Process *proc = (Process *)&data->stream.proc;
rettv->vval.v_number = proc->pid;
}
-// "jobsend()" function
-static void f_jobsend(typval_T *argvars, typval_T *rettv)
-{
- rettv->v_type = VAR_NUMBER;
- rettv->vval.v_number = 0;
-
- if (check_restricted() || check_secure()) {
- return;
- }
-
- if (argvars[0].v_type != VAR_NUMBER || argvars[1].v_type == VAR_UNKNOWN) {
- // First argument is the job id and second is the string or list to write
- // to the job's stdin
- EMSG(_(e_invarg));
- return;
- }
-
- TerminalJobData *data = find_job(argvars[0].vval.v_number);
- if (!data) {
- EMSG(_(e_invjob));
- return;
- }
-
- if (((Process *)&data->proc)->in->closed) {
- EMSG(_("Can't send data to the job: stdin is closed"));
- return;
- }
-
- ssize_t input_len;
- char *input = (char *) save_tv_as_string(&argvars[1], &input_len, false);
- if (!input) {
- // Either the error has been handled by save_tv_as_string(), or there is no
- // input to send.
- return;
- }
-
- WBuffer *buf = wstream_new_buffer(input, input_len, 1, xfree);
- rettv->vval.v_number = wstream_write(data->proc.uv.process.in, buf);
-}
-
// "jobresize(job, width, height)" function
-static void f_jobresize(typval_T *argvars, typval_T *rettv)
+static void f_jobresize(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -11704,26 +11603,25 @@ static void f_jobresize(typval_T *argvars, typval_T *rettv)
}
- TerminalJobData *data = find_job(argvars[0].vval.v_number);
+ Channel *data = find_job(argvars[0].vval.v_number, true);
if (!data) {
- EMSG(_(e_invjob));
return;
}
- if (data->proc.uv.process.type != kProcessTypePty) {
- EMSG(_(e_jobnotpty));
+ if (data->stream.proc.type != kProcessTypePty) {
+ EMSG(_(e_channotpty));
return;
}
- pty_process_resize(&data->proc.pty, argvars[1].vval.v_number,
- argvars[2].vval.v_number);
+ pty_process_resize(&data->stream.pty, argvars[1].vval.v_number,
+ argvars[2].vval.v_number);
rettv->vval.v_number = 1;
}
-static char **tv_to_argv(typval_T *cmd_tv, char **cmd)
+static char **tv_to_argv(typval_T *cmd_tv, const char **cmd, bool *executable)
{
if (cmd_tv->v_type == VAR_STRING) {
- char *cmd_str = (char *)get_tv_string(cmd_tv);
+ const char *cmd_str = tv_get_string(cmd_tv);
if (cmd) {
*cmd = cmd_str;
}
@@ -11736,45 +11634,42 @@ static char **tv_to_argv(typval_T *cmd_tv, char **cmd)
}
list_T *argl = cmd_tv->vval.v_list;
- int argc = argl->lv_len;
+ int argc = tv_list_len(argl);
if (!argc) {
- EMSG(_("Argument vector must have at least one item"));
+ EMSG(_(e_invarg)); // List must have at least one item.
return NULL;
}
- assert(argl->lv_first);
-
- const char_u *exe = get_tv_string_chk(&argl->lv_first->li_tv);
- if (!exe || !os_can_exe(exe, NULL, true)) {
- // String is not executable
- if (exe) {
- EMSG2(e_jobexe, exe);
+ const char *exe = tv_get_string_chk(TV_LIST_ITEM_TV(tv_list_first(argl)));
+ if (!exe || !os_can_exe((const char_u *)exe, NULL, true)) {
+ if (exe && executable) {
+ *executable = false;
}
return NULL;
}
if (cmd) {
- *cmd = (char *)exe;
+ *cmd = exe;
}
-
+
// Build the argument vector
int i = 0;
char **argv = xcalloc(argc + 1, sizeof(char *));
- for (listitem_T *arg = argl->lv_first; arg != NULL; arg = arg->li_next) {
- char *a = (char *)get_tv_string_chk(&arg->li_tv);
+ TV_LIST_ITER_CONST(argl, arg, {
+ const char *a = tv_get_string_chk(TV_LIST_ITEM_TV(arg));
if (!a) {
- // Did emsg in get_tv_string; just deallocate argv.
+ // Did emsg in tv_get_string_chk; just deallocate argv.
shell_free_argv(argv);
return NULL;
}
argv[i++] = xstrdup(a);
- }
+ });
return argv;
}
// "jobstart()" function
-static void f_jobstart(typval_T *argvars, typval_T *rettv)
+static void f_jobstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -11783,8 +11678,10 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv)
return;
}
- char **argv = tv_to_argv(&argvars[0], NULL);
+ bool executable = true;
+ char **argv = tv_to_argv(&argvars[0], NULL, &executable);
if (!argv) {
+ rettv->vval.v_number = executable ? 0 : -1;
return; // Did error message in tv_to_argv.
}
@@ -11795,17 +11692,32 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv)
return;
}
+
dict_T *job_opts = NULL;
- ufunc_T *on_stdout = NULL, *on_stderr = NULL, *on_exit = NULL;
+ bool detach = false;
+ bool rpc = false;
+ bool pty = false;
+ CallbackReader on_stdout = CALLBACK_READER_INIT,
+ on_stderr = CALLBACK_READER_INIT;
+ Callback on_exit = CALLBACK_NONE;
char *cwd = NULL;
if (argvars[1].v_type == VAR_DICT) {
job_opts = argvars[1].vval.v_dict;
- char *new_cwd = (char *)get_dict_string(job_opts, (char_u *)"cwd", false);
+ detach = tv_dict_get_number(job_opts, "detach") != 0;
+ rpc = tv_dict_get_number(job_opts, "rpc") != 0;
+ pty = tv_dict_get_number(job_opts, "pty") != 0;
+ if (pty && rpc) {
+ EMSG2(_(e_invarg2), "job cannot have both 'pty' and 'rpc' options set");
+ shell_free_argv(argv);
+ return;
+ }
+
+ char *new_cwd = tv_dict_get_string(job_opts, "cwd", false);
if (new_cwd && strlen(new_cwd) > 0) {
cwd = new_cwd;
// The new cwd must be a directory.
- if (!os_isdir((char_u *)cwd)) {
+ if (!os_isdir_executable((const char *)cwd)) {
EMSG2(_(e_invarg2), "expected valid directory");
shell_free_argv(argv);
return;
@@ -11818,38 +11730,25 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv)
}
}
- bool pty = job_opts && get_dict_number(job_opts, (uint8_t *)"pty") != 0;
- bool detach = job_opts && get_dict_number(job_opts, (uint8_t *)"detach") != 0;
- TerminalJobData *data = common_job_init(argv, on_stdout, on_stderr, on_exit,
- job_opts, pty, detach, cwd);
- Process *proc = (Process *)&data->proc;
+ uint16_t width = 0, height = 0;
+ char *term_name = NULL;
if (pty) {
- uint16_t width = get_dict_number(job_opts, (uint8_t *)"width");
- if (width > 0) {
- data->proc.pty.width = width;
- }
- uint16_t height = get_dict_number(job_opts, (uint8_t *)"height");
- if (height > 0) {
- data->proc.pty.height = height;
- }
- char *term = (char *)get_dict_string(job_opts, (uint8_t *)"TERM", true);
- if (term) {
- data->proc.pty.term_name = term;
- }
+ width = (uint16_t)tv_dict_get_number(job_opts, "width");
+ height = (uint16_t)tv_dict_get_number(job_opts, "height");
+ term_name = tv_dict_get_string(job_opts, "TERM", true);
}
- if (!on_stdout) {
- proc->out = NULL;
+ Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit, pty,
+ rpc, detach, cwd, width, height, term_name,
+ &rettv->vval.v_number);
+ if (chan) {
+ channel_create_event(chan, NULL);
}
- if (!on_stderr) {
- proc->err = NULL;
- }
- common_job_start(data, rettv);
}
// "jobstop()" function
-static void f_jobstop(typval_T *argvars, typval_T *rettv)
+static void f_jobstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -11865,19 +11764,17 @@ static void f_jobstop(typval_T *argvars, typval_T *rettv)
}
- TerminalJobData *data = find_job(argvars[0].vval.v_number);
+ Channel *data = find_job(argvars[0].vval.v_number, true);
if (!data) {
- EMSG(_(e_invjob));
return;
}
- process_stop((Process *)&data->proc);
- data->stopped = true;
+ process_stop((Process *)&data->stream.proc);
rettv->vval.v_number = 1;
}
// "jobwait(ids[, timeout])" function
-static void f_jobwait(typval_T *argvars, typval_T *rettv)
+static void f_jobwait(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -11892,30 +11789,34 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv)
return;
}
+
list_T *args = argvars[0].vval.v_list;
- list_T *rv = list_alloc();
+ Channel **jobs = xcalloc(tv_list_len(args), sizeof(*jobs));
ui_busy_start();
- Queue *waiting_jobs = queue_new_parent(loop_on_put, &main_loop);
+ MultiQueue *waiting_jobs = multiqueue_new_parent(loop_on_put, &main_loop);
// For each item in the input list append an integer to the output list. -3
// is used to represent an invalid job id, -2 is for a interrupted job and
// -1 for jobs that were skipped or timed out.
- for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
- TerminalJobData *data = NULL;
- if (arg->li_tv.v_type != VAR_NUMBER
- || !(data = find_job(arg->li_tv.vval.v_number))) {
- list_append_number(rv, -3);
+
+ int i = 0;
+ TV_LIST_ITER_CONST(args, arg, {
+ Channel *chan = NULL;
+ if (TV_LIST_ITEM_TV(arg)->v_type != VAR_NUMBER
+ || !(chan = find_job(TV_LIST_ITEM_TV(arg)->vval.v_number, false))) {
+ jobs[i] = NULL;
} else {
- // append the list item and set the status pointer so we'll collect the
- // status code when the job exits
- list_append_number(rv, -1);
- data->status_ptr = &rv->lv_last->li_tv.vval.v_number;
- // Process any pending events for the job because we'll temporarily
- // replace the parent queue
- queue_process_events(data->events);
- queue_replace_parent(data->events, waiting_jobs);
+ jobs[i] = chan;
+ channel_incref(chan);
+ if (chan->stream.proc.status < 0) {
+ // Process any pending events for the job because we'll temporarily
+ // replace the parent queue
+ multiqueue_process_events(chan->events);
+ multiqueue_replace_parent(chan->events, waiting_jobs);
+ }
}
- }
+ i++;
+ });
int remaining = -1;
uint64_t before = 0;
@@ -11924,24 +11825,21 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv)
before = os_hrtime();
}
- for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
- TerminalJobData *data = NULL;
+ for (i = 0; i < tv_list_len(args); i++) {
if (remaining == 0) {
// timed out
break;
}
- if (arg->li_tv.v_type != VAR_NUMBER
- || !(data = find_job(arg->li_tv.vval.v_number))) {
+
+ // if the job already exited, but wasn't freed yet
+ if (jobs[i] == NULL || jobs[i]->stream.proc.status >= 0) {
continue;
}
- int status = process_wait((Process *)&data->proc, remaining, waiting_jobs);
+
+ int status = process_wait(&jobs[i]->stream.proc, remaining,
+ waiting_jobs);
if (status < 0) {
// interrupted or timed out, skip remaining jobs.
- if (status == -2) {
- // set the status so the user can distinguish between interrupted and
- // skipped/timeout jobs.
- *data->status_ptr = -2;
- }
break;
}
if (remaining > 0) {
@@ -11954,32 +11852,26 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv)
}
}
- for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
- TerminalJobData *data = NULL;
- if (arg->li_tv.v_type != VAR_NUMBER
- || !(data = find_job(arg->li_tv.vval.v_number))) {
- continue;
- }
- // remove the status pointer because the list may be freed before the
- // job exits
- data->status_ptr = NULL;
- }
+ list_T *const rv = tv_list_alloc(tv_list_len(args));
// restore the parent queue for any jobs still alive
- for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
- TerminalJobData *data = NULL;
- if (arg->li_tv.v_type != VAR_NUMBER
- || !(data = pmap_get(uint64_t)(jobs, arg->li_tv.vval.v_number))) {
+ for (i = 0; i < tv_list_len(args); i++) {
+ if (jobs[i] == NULL) {
+ tv_list_append_number(rv, -3);
continue;
}
// restore the parent queue for the job
- queue_process_events(data->events);
- queue_replace_parent(data->events, main_loop.events);
+ multiqueue_process_events(jobs[i]->events);
+ multiqueue_replace_parent(jobs[i]->events, main_loop.events);
+
+ tv_list_append_number(rv, jobs[i]->stream.proc.status);
+ channel_decref(jobs[i]);
}
- queue_free(waiting_jobs);
+ multiqueue_free(waiting_jobs);
+ xfree(jobs);
ui_busy_stop();
- rv->lv_refcount++;
+ tv_list_ref(rv);
rettv->v_type = VAR_LIST;
rettv->vval.v_list = rv;
}
@@ -11987,52 +11879,48 @@ static void f_jobwait(typval_T *argvars, typval_T *rettv)
/*
* "join()" function
*/
-static void f_join(typval_T *argvars, typval_T *rettv)
+static void f_join(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- garray_T ga;
- char_u *sep;
-
if (argvars[0].v_type != VAR_LIST) {
EMSG(_(e_listreq));
return;
}
- if (argvars[0].vval.v_list == NULL)
- return;
- if (argvars[1].v_type == VAR_UNKNOWN)
- sep = (char_u *)" ";
- else
- sep = get_tv_string_chk(&argvars[1]);
+ const char *const sep = (argvars[1].v_type == VAR_UNKNOWN
+ ? " "
+ : tv_get_string_chk(&argvars[1]));
rettv->v_type = VAR_STRING;
if (sep != NULL) {
+ garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
- list_join(&ga, argvars[0].vval.v_list, (char *) sep);
+ tv_list_join(&ga, argvars[0].vval.v_list, sep);
ga_append(&ga, NUL);
rettv->vval.v_string = (char_u *)ga.ga_data;
- } else
+ } else {
rettv->vval.v_string = NULL;
+ }
}
/// json_decode() function
-static void f_json_decode(typval_T *argvars, typval_T *rettv)
+static void f_json_decode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char numbuf[NUMBUFLEN];
- char *s = NULL;
+ const char *s = NULL;
char *tofree = NULL;
size_t len;
if (argvars[0].v_type == VAR_LIST) {
- if (!encode_vim_list_to_buf(argvars[0].vval.v_list, &len, &s)) {
+ if (!encode_vim_list_to_buf(argvars[0].vval.v_list, &len, &tofree)) {
EMSG(_("E474: Failed to convert list to string"));
return;
}
- tofree = s;
+ s = tofree;
if (s == NULL) {
assert(len == 0);
s = "";
}
} else {
- s = (char *) get_tv_string_buf_chk(&argvars[0], (char_u *) numbuf);
+ s = tv_get_string_buf_chk(&argvars[0], numbuf);
if (s) {
len = strlen(s);
} else {
@@ -12040,7 +11928,7 @@ static void f_json_decode(typval_T *argvars, typval_T *rettv)
}
}
if (json_decode_string(s, len, rettv) == FAIL) {
- emsgf(_("E474: Failed to parse %.*s"), (int) len, s);
+ emsgf(_("E474: Failed to parse %.*s"), (int)len, s);
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
}
@@ -12049,7 +11937,7 @@ static void f_json_decode(typval_T *argvars, typval_T *rettv)
}
/// json_encode() function
-static void f_json_encode(typval_T *argvars, typval_T *rettv)
+static void f_json_encode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = (char_u *) encode_tv2json(&argvars[0], NULL);
@@ -12058,7 +11946,7 @@ static void f_json_encode(typval_T *argvars, typval_T *rettv)
/*
* "keys()" function
*/
-static void f_keys(typval_T *argvars, typval_T *rettv)
+static void f_keys(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 0);
}
@@ -12066,7 +11954,7 @@ static void f_keys(typval_T *argvars, typval_T *rettv)
/*
* "last_buffer_nr()" function.
*/
-static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv)
+static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n = 0;
@@ -12082,26 +11970,31 @@ static void f_last_buffer_nr(typval_T *argvars, typval_T *rettv)
/*
* "len()" function
*/
-static void f_len(typval_T *argvars, typval_T *rettv)
+static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
switch (argvars[0].v_type) {
- case VAR_STRING:
- case VAR_NUMBER:
- rettv->vval.v_number = (varnumber_T)STRLEN(
- get_tv_string(&argvars[0]));
- break;
- case VAR_LIST:
- rettv->vval.v_number = list_len(argvars[0].vval.v_list);
- break;
- case VAR_DICT:
- rettv->vval.v_number = dict_len(argvars[0].vval.v_dict);
- break;
- case VAR_UNKNOWN:
- case VAR_SPECIAL:
- case VAR_FLOAT:
- case VAR_FUNC:
- EMSG(_("E701: Invalid type for len()"));
- break;
+ case VAR_STRING:
+ case VAR_NUMBER: {
+ rettv->vval.v_number = (varnumber_T)strlen(
+ tv_get_string(&argvars[0]));
+ break;
+ }
+ case VAR_LIST: {
+ rettv->vval.v_number = tv_list_len(argvars[0].vval.v_list);
+ break;
+ }
+ case VAR_DICT: {
+ rettv->vval.v_number = tv_dict_len(argvars[0].vval.v_dict);
+ break;
+ }
+ case VAR_UNKNOWN:
+ case VAR_SPECIAL:
+ case VAR_FLOAT:
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ EMSG(_("E701: Invalid type for len()"));
+ break;
+ }
}
}
@@ -12153,7 +12046,7 @@ static void libcall_common(typval_T *argvars, typval_T *rettv, int out_type)
/*
* "libcall()" function
*/
-static void f_libcall(typval_T *argvars, typval_T *rettv)
+static void f_libcall(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
libcall_common(argvars, rettv, VAR_STRING);
}
@@ -12161,7 +12054,7 @@ static void f_libcall(typval_T *argvars, typval_T *rettv)
/*
* "libcallnr()" function
*/
-static void f_libcallnr(typval_T *argvars, typval_T *rettv)
+static void f_libcallnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
libcall_common(argvars, rettv, VAR_NUMBER);
}
@@ -12169,7 +12062,7 @@ static void f_libcallnr(typval_T *argvars, typval_T *rettv)
/*
* "line(string)" function
*/
-static void f_line(typval_T *argvars, typval_T *rettv)
+static void f_line(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum = 0;
pos_T *fp;
@@ -12184,41 +12077,39 @@ static void f_line(typval_T *argvars, typval_T *rettv)
/*
* "line2byte(lnum)" function
*/
-static void f_line2byte(typval_T *argvars, typval_T *rettv)
+static void f_line2byte(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
-
- lnum = get_tv_lnum(argvars);
- if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) {
rettv->vval.v_number = -1;
- else
- rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL);
- if (rettv->vval.v_number >= 0)
- ++rettv->vval.v_number;
+ } else {
+ rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL, false);
+ }
+ if (rettv->vval.v_number >= 0) {
+ rettv->vval.v_number++;
+ }
}
/*
* "lispindent(lnum)" function
*/
-static void f_lispindent(typval_T *argvars, typval_T *rettv)
+static void f_lispindent(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- pos_T pos;
- linenr_T lnum;
-
- pos = curwin->w_cursor;
- lnum = get_tv_lnum(argvars);
+ const pos_T pos = curwin->w_cursor;
+ const linenr_T lnum = tv_get_lnum(argvars);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = lnum;
rettv->vval.v_number = get_lisp_indent();
curwin->w_cursor = pos;
- } else
+ } else {
rettv->vval.v_number = -1;
+ }
}
/*
* "localtime()" function
*/
-static void f_localtime(typval_T *argvars, typval_T *rettv)
+static void f_localtime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = (varnumber_T)time(NULL);
}
@@ -12226,94 +12117,127 @@ static void f_localtime(typval_T *argvars, typval_T *rettv)
static void get_maparg(typval_T *argvars, typval_T *rettv, int exact)
{
- char_u *keys;
- char_u *which;
- char_u buf[NUMBUFLEN];
- char_u *keys_buf = NULL;
- char_u *rhs;
+ char_u *keys_buf = NULL;
+ char_u *rhs;
int mode;
int abbr = FALSE;
int get_dict = FALSE;
mapblock_T *mp;
int buffer_local;
- /* return empty string for failure */
+ // Return empty string for failure.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- keys = get_tv_string(&argvars[0]);
- if (*keys == NUL)
+ char_u *keys = (char_u *)tv_get_string(&argvars[0]);
+ if (*keys == NUL) {
return;
+ }
+ char buf[NUMBUFLEN];
+ const char *which;
if (argvars[1].v_type != VAR_UNKNOWN) {
- which = get_tv_string_buf_chk(&argvars[1], buf);
+ which = tv_get_string_buf_chk(&argvars[1], buf);
if (argvars[2].v_type != VAR_UNKNOWN) {
- abbr = get_tv_number(&argvars[2]);
- if (argvars[3].v_type != VAR_UNKNOWN)
- get_dict = get_tv_number(&argvars[3]);
+ abbr = tv_get_number(&argvars[2]);
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ get_dict = tv_get_number(&argvars[3]);
+ }
}
- } else
- which = (char_u *)"";
- if (which == NULL)
+ } else {
+ which = "";
+ }
+ if (which == NULL) {
return;
+ }
- mode = get_map_mode(&which, 0);
+ mode = get_map_mode((char_u **)&which, 0);
- keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, false,
+ keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true,
CPO_TO_CPO_FLAGS);
rhs = check_map(keys, mode, exact, false, abbr, &mp, &buffer_local);
xfree(keys_buf);
if (!get_dict) {
- /* Return a string. */
- if (rhs != NULL)
- rettv->vval.v_string = str2special_save(rhs, FALSE);
+ // Return a string.
+ if (rhs != NULL) {
+ if (*rhs == NUL) {
+ rettv->vval.v_string = vim_strsave((char_u *)"<Nop>");
+ } else {
+ rettv->vval.v_string = (char_u *)str2special_save(
+ (char *)rhs, false, false);
+ }
+ }
} else {
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
if (rhs != NULL) {
// Return a dictionary.
- char_u *lhs = str2special_save(mp->m_keys, TRUE);
- char_u *mapmode = map_mode_to_chars(mp->m_mode);
- dict_T *dict = rettv->vval.v_dict;
-
- dict_add_nr_str(dict, "lhs", 0L, lhs);
- dict_add_nr_str(dict, "rhs", 0L, mp->m_orig_str);
- dict_add_nr_str(dict, "noremap", mp->m_noremap ? 1L : 0L, NULL);
- dict_add_nr_str(dict, "expr", mp->m_expr ? 1L : 0L, NULL);
- dict_add_nr_str(dict, "silent", mp->m_silent ? 1L : 0L, NULL);
- dict_add_nr_str(dict, "sid", (long)mp->m_script_ID, NULL);
- dict_add_nr_str(dict, "buffer", (long)buffer_local, NULL);
- dict_add_nr_str(dict, "nowait", mp->m_nowait ? 1L : 0L, NULL);
- dict_add_nr_str(dict, "mode", 0L, mapmode);
-
- xfree(lhs);
- xfree(mapmode);
+ mapblock_fill_dict(rettv->vval.v_dict, mp, buffer_local, true);
}
}
}
-/*
- * "log()" function
- */
-static void f_log(typval_T *argvars, typval_T *rettv)
+/// luaeval() function implementation
+static void f_luaeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+ FUNC_ATTR_NONNULL_ALL
{
- float_op_wrapper(argvars, rettv, &log);
+ const char *const str = (const char *)tv_get_string_chk(&argvars[0]);
+ if (str == NULL) {
+ return;
+ }
+
+ executor_eval_lua(cstr_as_string((char *)str), &argvars[1], rettv);
}
-/*
- * "log10()" function
- */
-static void f_log10(typval_T *argvars, typval_T *rettv)
+/// Fill a dictionary with all applicable maparg() like dictionaries
+///
+/// @param dict The dictionary to be filled
+/// @param mp The maphash that contains the mapping information
+/// @param buffer_value The "buffer" value
+/// @param compatible True for compatible with old maparg() dict
+void mapblock_fill_dict(dict_T *const dict,
+ const mapblock_T *const mp,
+ long buffer_value,
+ bool compatible)
+ FUNC_ATTR_NONNULL_ALL
{
- float_op_wrapper(argvars, rettv, &log10);
-}
+ char *const lhs = str2special_save((const char *)mp->m_keys,
+ compatible, !compatible);
+ char *const mapmode = map_mode_to_chars(mp->m_mode);
+ varnumber_T noremap_value;
+ if (compatible) {
+ // Keep old compatible behavior
+ // This is unable to determine whether a mapping is a <script> mapping
+ noremap_value = !!mp->m_noremap;
+ } else {
+ // Distinguish between <script> mapping
+ // If it's not a <script> mapping, check if it's a noremap
+ noremap_value = mp->m_noremap == REMAP_SCRIPT ? 2 : !!mp->m_noremap;
+ }
+
+ if (compatible) {
+ tv_dict_add_str(dict, S_LEN("rhs"), (const char *)mp->m_orig_str);
+ } else {
+ tv_dict_add_allocated_str(dict, S_LEN("rhs"),
+ str2special_save((const char *)mp->m_str, false,
+ true));
+ }
+ tv_dict_add_allocated_str(dict, S_LEN("lhs"), lhs);
+ tv_dict_add_nr(dict, S_LEN("noremap"), noremap_value);
+ tv_dict_add_nr(dict, S_LEN("expr"), mp->m_expr ? 1 : 0);
+ tv_dict_add_nr(dict, S_LEN("silent"), mp->m_silent ? 1 : 0);
+ tv_dict_add_nr(dict, S_LEN("sid"), (varnumber_T)mp->m_script_ID);
+ tv_dict_add_nr(dict, S_LEN("buffer"), (varnumber_T)buffer_value);
+ tv_dict_add_nr(dict, S_LEN("nowait"), mp->m_nowait ? 1 : 0);
+ tv_dict_add_allocated_str(dict, S_LEN("mode"), mapmode);
+}
/*
* "map()" function
*/
-static void f_map(typval_T *argvars, typval_T *rettv)
+static void f_map(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
filter_map(argvars, rettv, TRUE);
}
@@ -12321,7 +12245,7 @@ static void f_map(typval_T *argvars, typval_T *rettv)
/*
* "maparg()" function
*/
-static void f_maparg(typval_T *argvars, typval_T *rettv)
+static void f_maparg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_maparg(argvars, rettv, TRUE);
}
@@ -12329,25 +12253,24 @@ static void f_maparg(typval_T *argvars, typval_T *rettv)
/*
* "mapcheck()" function
*/
-static void f_mapcheck(typval_T *argvars, typval_T *rettv)
+static void f_mapcheck(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_maparg(argvars, rettv, FALSE);
}
-static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
+static void find_some_match(typval_T *const argvars, typval_T *const rettv,
+ const SomeMatchType type)
{
char_u *str = NULL;
long len = 0;
char_u *expr = NULL;
- char_u *pat;
regmatch_T regmatch;
- char_u patbuf[NUMBUFLEN];
char_u *save_cpo;
long start = 0;
long nth = 1;
colnr_T startcol = 0;
- int match = 0;
+ bool match = false;
list_T *l = NULL;
listitem_T *li = NULL;
long idx = 0;
@@ -12358,38 +12281,62 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
p_cpo = (char_u *)"";
rettv->vval.v_number = -1;
- if (type == 3) {
- /* return empty list when there are no matches */
- rettv_list_alloc(rettv);
- } else if (type == 2) {
- rettv->v_type = VAR_STRING;
- rettv->vval.v_string = NULL;
+ switch (type) {
+ // matchlist(): return empty list when there are no matches.
+ case kSomeMatchList: {
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+ break;
+ }
+ // matchstrpos(): return ["", -1, -1, -1]
+ case kSomeMatchStrPos: {
+ tv_list_alloc_ret(rettv, 4);
+ tv_list_append_string(rettv->vval.v_list, "", 0);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ tv_list_append_number(rettv->vval.v_list, -1);
+ break;
+ }
+ case kSomeMatchStr: {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+ break;
+ }
+ case kSomeMatch:
+ case kSomeMatchEnd: {
+ // Do nothing: zero is default.
+ break;
+ }
}
if (argvars[0].v_type == VAR_LIST) {
- if ((l = argvars[0].vval.v_list) == NULL)
+ if ((l = argvars[0].vval.v_list) == NULL) {
goto theend;
- li = l->lv_first;
+ }
+ li = tv_list_first(l);
} else {
- expr = str = get_tv_string(&argvars[0]);
+ expr = str = (char_u *)tv_get_string(&argvars[0]);
len = (long)STRLEN(str);
}
- pat = get_tv_string_buf_chk(&argvars[1], patbuf);
- if (pat == NULL)
+ char patbuf[NUMBUFLEN];
+ const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ if (pat == NULL) {
goto theend;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- int error = FALSE;
+ bool error = false;
- start = get_tv_number_chk(&argvars[2], &error);
- if (error)
+ start = tv_get_number_chk(&argvars[2], &error);
+ if (error) {
goto theend;
+ }
if (l != NULL) {
- li = list_find(l, start);
- if (li == NULL)
+ idx = tv_list_uidx(l, start);
+ if (idx == -1) {
goto theend;
- idx = l->lv_idx; /* use the cached index */
+ }
+ li = tv_list_find(l, idx);
} else {
if (start < 0)
start = 0;
@@ -12406,24 +12353,27 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
}
}
- if (argvars[3].v_type != VAR_UNKNOWN)
- nth = get_tv_number_chk(&argvars[3], &error);
- if (error)
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ nth = tv_get_number_chk(&argvars[3], &error);
+ }
+ if (error) {
goto theend;
+ }
}
- regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ regmatch.regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING);
if (regmatch.regprog != NULL) {
regmatch.rm_ic = p_ic;
for (;; ) {
if (l != NULL) {
if (li == NULL) {
- match = FALSE;
+ match = false;
break;
}
xfree(tofree);
- tofree = str = (char_u *) encode_tv2echo(&li->li_tv, NULL);
+ tofree = expr = str = (char_u *)encode_tv2echo(TV_LIST_ITEM_TV(li),
+ NULL);
if (str == NULL) {
break;
}
@@ -12438,55 +12388,92 @@ static void find_some_match(typval_T *argvars, typval_T *rettv, int type)
/* Advance to just after the match. */
if (l != NULL) {
- li = li->li_next;
- ++idx;
+ li = TV_LIST_ITEM_NEXT(l, li);
+ idx++;
} else {
startcol = (colnr_T)(regmatch.startp[0]
+ (*mb_ptr2len)(regmatch.startp[0]) - str);
if (startcol > (colnr_T)len || str + startcol <= regmatch.startp[0]) {
- match = FALSE;
+ match = false;
break;
}
}
}
if (match) {
- if (type == 3) {
- int i;
-
- /* return list with matched string and submatches */
- for (i = 0; i < NSUBEXP; ++i) {
- if (regmatch.endp[i] == NULL) {
- list_append_string(rettv->vval.v_list, (char_u *)"", 0);
+ switch (type) {
+ case kSomeMatchStrPos: {
+ list_T *const ret_l = rettv->vval.v_list;
+ listitem_T *li1 = tv_list_first(ret_l);
+ listitem_T *li2 = TV_LIST_ITEM_NEXT(ret_l, li1);
+ listitem_T *li3 = TV_LIST_ITEM_NEXT(ret_l, li2);
+ listitem_T *li4 = TV_LIST_ITEM_NEXT(ret_l, li3);
+ xfree(TV_LIST_ITEM_TV(li1)->vval.v_string);
+
+ const size_t rd = (size_t)(regmatch.endp[0] - regmatch.startp[0]);
+ TV_LIST_ITEM_TV(li1)->vval.v_string = xmemdupz(
+ (const char *)regmatch.startp[0], rd);
+ TV_LIST_ITEM_TV(li3)->vval.v_number = (varnumber_T)(
+ regmatch.startp[0] - expr);
+ TV_LIST_ITEM_TV(li4)->vval.v_number = (varnumber_T)(
+ regmatch.endp[0] - expr);
+ if (l != NULL) {
+ TV_LIST_ITEM_TV(li2)->vval.v_number = (varnumber_T)idx;
+ }
+ break;
+ }
+ case kSomeMatchList: {
+ // Return list with matched string and submatches.
+ for (int i = 0; i < NSUBEXP; i++) {
+ if (regmatch.endp[i] == NULL) {
+ tv_list_append_string(rettv->vval.v_list, NULL, 0);
+ } else {
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)regmatch.startp[i],
+ (regmatch.endp[i] - regmatch.startp[i]));
+ }
+ }
+ break;
+ }
+ case kSomeMatchStr: {
+ // Return matched string.
+ if (l != NULL) {
+ tv_copy(TV_LIST_ITEM_TV(li), rettv);
} else {
- list_append_string(rettv->vval.v_list,
- regmatch.startp[i],
- (int)(regmatch.endp[i] - regmatch.startp[i]));
+ rettv->vval.v_string = (char_u *)xmemdupz(
+ (const char *)regmatch.startp[0],
+ (size_t)(regmatch.endp[0] - regmatch.startp[0]));
}
+ break;
+ }
+ case kSomeMatch:
+ case kSomeMatchEnd: {
+ if (l != NULL) {
+ rettv->vval.v_number = idx;
+ } else {
+ if (type == kSomeMatch) {
+ rettv->vval.v_number =
+ (varnumber_T)(regmatch.startp[0] - str);
+ } else {
+ rettv->vval.v_number =
+ (varnumber_T)(regmatch.endp[0] - str);
+ }
+ rettv->vval.v_number += (varnumber_T)(str - expr);
+ }
+ break;
}
- } else if (type == 2) {
- /* return matched string */
- if (l != NULL)
- copy_tv(&li->li_tv, rettv);
- else
- rettv->vval.v_string = vim_strnsave(regmatch.startp[0],
- (int)(regmatch.endp[0] - regmatch.startp[0]));
- } else if (l != NULL)
- rettv->vval.v_number = idx;
- else {
- if (type != 0)
- rettv->vval.v_number =
- (varnumber_T)(regmatch.startp[0] - str);
- else
- rettv->vval.v_number =
- (varnumber_T)(regmatch.endp[0] - str);
- rettv->vval.v_number += (varnumber_T)(str - expr);
}
}
vim_regfree(regmatch.regprog);
}
theend:
+ if (type == kSomeMatchStrPos && l == NULL && rettv->vval.v_list != NULL) {
+ // matchstrpos() without a list: drop the second item
+ list_T *const ret_l = rettv->vval.v_list;
+ tv_list_item_remove(ret_l, TV_LIST_ITEM_NEXT(ret_l, tv_list_first(ret_l)));
+ }
+
xfree(tofree);
p_cpo = save_cpo;
}
@@ -12494,50 +12481,52 @@ theend:
/*
* "match()" function
*/
-static void f_match(typval_T *argvars, typval_T *rettv)
+static void f_match(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- find_some_match(argvars, rettv, 1);
+ find_some_match(argvars, rettv, kSomeMatch);
}
/*
* "matchadd()" function
*/
-static void f_matchadd(typval_T *argvars, typval_T *rettv)
+static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
- char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */
- char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */
- int prio = 10; /* default priority */
+ char grpbuf[NUMBUFLEN];
+ char patbuf[NUMBUFLEN];
+ const char *const grp = tv_get_string_buf_chk(&argvars[0], grpbuf);
+ const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ int prio = 10;
int id = -1;
- int error = false;
- char_u *conceal_char = NULL;
+ bool error = false;
+ const char *conceal_char = NULL;
rettv->vval.v_number = -1;
- if (grp == NULL || pat == NULL)
+ if (grp == NULL || pat == NULL) {
return;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- prio = get_tv_number_chk(&argvars[2], &error);
+ prio = tv_get_number_chk(&argvars[2], &error);
if (argvars[3].v_type != VAR_UNKNOWN) {
- id = get_tv_number_chk(&argvars[3], &error);
+ id = tv_get_number_chk(&argvars[3], &error);
if (argvars[4].v_type != VAR_UNKNOWN) {
if (argvars[4].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
return;
}
- if (dict_find(argvars[4].vval.v_dict,
- (char_u *)"conceal", -1) != NULL) {
- conceal_char = get_dict_string(argvars[4].vval.v_dict,
- (char_u *)"conceal", false);
+ dictitem_T *di;
+ if ((di = tv_dict_find(argvars[4].vval.v_dict, S_LEN("conceal")))
+ != NULL) {
+ conceal_char = tv_get_string(&di->di_tv);
}
}
}
}
- if (error == true) {
+ if (error) {
return;
}
if (id >= 1 && id <= 3) {
- EMSGN("E798: ID is reserved for \":match\": %" PRId64, id);
+ EMSGN(_("E798: ID is reserved for \":match\": %" PRId64), id);
return;
}
@@ -12545,59 +12534,58 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv)
conceal_char);
}
-static void f_matchaddpos(typval_T *argvars, typval_T *rettv) FUNC_ATTR_NONNULL_ALL
+static void f_matchaddpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = -1;
-
- char_u buf[NUMBUFLEN];
- char_u *group;
- group = get_tv_string_buf_chk(&argvars[0], buf);
- if (group == NULL) {
- return;
- }
+ rettv->vval.v_number = -1;
- if (argvars[1].v_type != VAR_LIST) {
- EMSG2(_(e_listarg), "matchaddpos()");
- return;
- }
+ char buf[NUMBUFLEN];
+ const char *const group = tv_get_string_buf_chk(&argvars[0], buf);
+ if (group == NULL) {
+ return;
+ }
- list_T *l;
- l = argvars[1].vval.v_list;
- if (l == NULL) {
- return;
- }
+ if (argvars[1].v_type != VAR_LIST) {
+ EMSG2(_(e_listarg), "matchaddpos()");
+ return;
+ }
- int error = false;
- int prio = 10;
- int id = -1;
- char_u *conceal_char = NULL;
+ list_T *l;
+ l = argvars[1].vval.v_list;
+ if (l == NULL) {
+ return;
+ }
- if (argvars[2].v_type != VAR_UNKNOWN) {
- prio = get_tv_number_chk(&argvars[2], &error);
- if (argvars[3].v_type != VAR_UNKNOWN) {
- id = get_tv_number_chk(&argvars[3], &error);
- if (argvars[4].v_type != VAR_UNKNOWN) {
- if (argvars[4].v_type != VAR_DICT) {
- EMSG(_(e_dictreq));
- return;
- }
- if (dict_find(argvars[4].vval.v_dict,
- (char_u *)"conceal", -1) != NULL) {
- conceal_char = get_dict_string(argvars[4].vval.v_dict,
- (char_u *)"conceal", false);
- }
+ bool error = false;
+ int prio = 10;
+ int id = -1;
+ const char *conceal_char = NULL;
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ prio = tv_get_number_chk(&argvars[2], &error);
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ id = tv_get_number_chk(&argvars[3], &error);
+ if (argvars[4].v_type != VAR_UNKNOWN) {
+ if (argvars[4].v_type != VAR_DICT) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+ dictitem_T *di;
+ if ((di = tv_dict_find(argvars[4].vval.v_dict, S_LEN("conceal")))
+ != NULL) {
+ conceal_char = tv_get_string(&di->di_tv);
}
}
}
- if (error == true) {
- return;
- }
+ }
+ if (error == true) {
+ return;
+ }
- // id == 3 is ok because matchaddpos() is supposed to substitute :3match
- if (id == 1 || id == 2) {
- EMSGN("E798: ID is reserved for \"match\": %" PRId64, id);
- return;
- }
+ // id == 3 is ok because matchaddpos() is supposed to substitute :3match
+ if (id == 1 || id == 2) {
+ EMSGN(_("E798: ID is reserved for \"match\": %" PRId64), id);
+ return;
+ }
rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l,
conceal_char);
@@ -12606,21 +12594,24 @@ static void f_matchaddpos(typval_T *argvars, typval_T *rettv) FUNC_ATTR_NONNULL_
/*
* "matcharg()" function
*/
-static void f_matcharg(typval_T *argvars, typval_T *rettv)
+static void f_matcharg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_list_alloc(rettv);
+ const int id = tv_get_number(&argvars[0]);
- int id = get_tv_number(&argvars[0]);
+ tv_list_alloc_ret(rettv, (id >= 1 && id <= 3
+ ? 2
+ : 0));
if (id >= 1 && id <= 3) {
- matchitem_T *m;
+ matchitem_T *const m = (matchitem_T *)get_match(curwin, id);
- if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) {
- list_append_string(rettv->vval.v_list, syn_id2name(m->hlg_id), -1);
- list_append_string(rettv->vval.v_list, m->pattern, -1);
+ if (m != NULL) {
+ tv_list_append_string(rettv->vval.v_list,
+ (const char *)syn_id2name(m->hlg_id), -1);
+ tv_list_append_string(rettv->vval.v_list, (const char *)m->pattern, -1);
} else {
- list_append_string(rettv->vval.v_list, NULL, -1);
- list_append_string(rettv->vval.v_list, NULL, -1);
+ tv_list_append_string(rettv->vval.v_list, NULL, 0);
+ tv_list_append_string(rettv->vval.v_list, NULL, 0);
}
}
}
@@ -12628,92 +12619,96 @@ static void f_matcharg(typval_T *argvars, typval_T *rettv)
/*
* "matchdelete()" function
*/
-static void f_matchdelete(typval_T *argvars, typval_T *rettv)
+static void f_matchdelete(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = match_delete(curwin,
- (int)get_tv_number(&argvars[0]), TRUE);
+ (int)tv_get_number(&argvars[0]), true);
}
/*
* "matchend()" function
*/
-static void f_matchend(typval_T *argvars, typval_T *rettv)
+static void f_matchend(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- find_some_match(argvars, rettv, 0);
+ find_some_match(argvars, rettv, kSomeMatchEnd);
}
/*
* "matchlist()" function
*/
-static void f_matchlist(typval_T *argvars, typval_T *rettv)
+static void f_matchlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- find_some_match(argvars, rettv, 3);
+ find_some_match(argvars, rettv, kSomeMatchList);
}
/*
* "matchstr()" function
*/
-static void f_matchstr(typval_T *argvars, typval_T *rettv)
+static void f_matchstr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- find_some_match(argvars, rettv, 2);
+ find_some_match(argvars, rettv, kSomeMatchStr);
}
-
-static void max_min(typval_T *argvars, typval_T *rettv, int domax)
+/// "matchstrpos()" function
+static void f_matchstrpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long n = 0;
- long i;
- int error = FALSE;
+ find_some_match(argvars, rettv, kSomeMatchStrPos);
+}
- if (argvars[0].v_type == VAR_LIST) {
- list_T *l;
- listitem_T *li;
+/// Get maximal/minimal number value in a list or dictionary
+///
+/// @param[in] tv List or dictionary to work with. If it contains something
+/// that is not an integer number (or cannot be coerced to
+/// it) error is given.
+/// @param[out] rettv Location where result will be saved. Only assigns
+/// vval.v_number, type is not touched. Returns zero for
+/// empty lists/dictionaries.
+/// @param[in] domax Determines whether maximal or minimal value is desired.
+static void max_min(const typval_T *const tv, typval_T *const rettv,
+ const bool domax)
+ FUNC_ATTR_NONNULL_ALL
+{
+ bool error = false;
- l = argvars[0].vval.v_list;
- if (l != NULL) {
- li = l->lv_first;
- if (li != NULL) {
- n = get_tv_number_chk(&li->li_tv, &error);
- for (;; ) {
- li = li->li_next;
- if (li == NULL)
- break;
- i = get_tv_number_chk(&li->li_tv, &error);
- if (domax ? i > n : i < n)
- n = i;
- }
- }
+ rettv->vval.v_number = 0;
+ varnumber_T n = (domax ? VARNUMBER_MIN : VARNUMBER_MAX);
+ if (tv->v_type == VAR_LIST) {
+ if (tv_list_len(tv->vval.v_list) == 0) {
+ return;
}
- } else if (argvars[0].v_type == VAR_DICT) {
- dict_T *d;
- int first = TRUE;
- hashitem_T *hi;
- int todo;
-
- d = argvars[0].vval.v_dict;
- if (d != NULL) {
- todo = (int)d->dv_hashtab.ht_used;
- for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error);
- if (first) {
- n = i;
- first = FALSE;
- } else if (domax ? i > n : i < n)
- n = i;
- }
+ TV_LIST_ITER_CONST(tv->vval.v_list, li, {
+ const varnumber_T i = tv_get_number_chk(TV_LIST_ITEM_TV(li), &error);
+ if (error) {
+ return;
+ }
+ if (domax ? i > n : i < n) {
+ n = i;
}
+ });
+ } else if (tv->v_type == VAR_DICT) {
+ if (tv_dict_len(tv->vval.v_dict) == 0) {
+ return;
}
- } else
- EMSG(_(e_listdictarg));
- rettv->vval.v_number = error ? 0 : n;
+ TV_DICT_ITER(tv->vval.v_dict, di, {
+ const varnumber_T i = tv_get_number_chk(&di->di_tv, &error);
+ if (error) {
+ return;
+ }
+ if (domax ? i > n : i < n) {
+ n = i;
+ }
+ });
+ } else {
+ EMSG2(_(e_listdictarg), domax ? "max()" : "min()");
+ return;
+ }
+ rettv->vval.v_number = n;
}
/*
* "max()" function
*/
-static void f_max(typval_T *argvars, typval_T *rettv)
+static void f_max(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
max_min(argvars, rettv, TRUE);
}
@@ -12721,7 +12716,7 @@ static void f_max(typval_T *argvars, typval_T *rettv)
/*
* "min()" function
*/
-static void f_min(typval_T *argvars, typval_T *rettv)
+static void f_min(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
max_min(argvars, rettv, FALSE);
}
@@ -12729,30 +12724,31 @@ static void f_min(typval_T *argvars, typval_T *rettv)
/*
* "mkdir()" function
*/
-static void f_mkdir(typval_T *argvars, typval_T *rettv)
+static void f_mkdir(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *dir;
- char_u buf[NUMBUFLEN];
- int prot = 0755;
+ int prot = 0755; // -V536
rettv->vval.v_number = FAIL;
if (check_restricted() || check_secure())
return;
- dir = get_tv_string_buf(&argvars[0], buf);
- if (*dir == NUL)
+ char buf[NUMBUFLEN];
+ const char *const dir = tv_get_string_buf(&argvars[0], buf);
+ if (*dir == NUL) {
rettv->vval.v_number = FAIL;
- else {
- if (*path_tail(dir) == NUL)
- /* remove trailing slashes */
- *path_tail_with_sep(dir) = NUL;
+ } else {
+ if (*path_tail((char_u *)dir) == NUL) {
+ // Remove trailing slashes.
+ *path_tail_with_sep((char_u *)dir) = NUL;
+ }
if (argvars[1].v_type != VAR_UNKNOWN) {
- if (argvars[2].v_type != VAR_UNKNOWN)
- prot = get_tv_number_chk(&argvars[2], NULL);
- if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) {
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ prot = tv_get_number_chk(&argvars[2], NULL);
+ }
+ if (prot != -1 && strcmp(tv_get_string(&argvars[1]), "p") == 0) {
char *failed_dir;
- int ret = os_mkdir_recurse((char *) dir, prot, &failed_dir);
+ int ret = os_mkdir_recurse(dir, prot, &failed_dir);
if (ret != 0) {
EMSG3(_(e_mkdir), failed_dir, os_strerror(ret));
xfree(failed_dir);
@@ -12768,104 +12764,60 @@ static void f_mkdir(typval_T *argvars, typval_T *rettv)
}
}
-/*
- * "mode()" function
- */
-static void f_mode(typval_T *argvars, typval_T *rettv)
+/// "mode()" function
+static void f_mode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[3];
-
- buf[1] = NUL;
- buf[2] = NUL;
+ char *mode = get_mode();
- if (VIsual_active) {
- if (VIsual_select)
- buf[0] = VIsual_mode + 's' - 'v';
- else
- buf[0] = VIsual_mode;
- } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
- || State == CONFIRM) {
- buf[0] = 'r';
- if (State == ASKMORE)
- buf[1] = 'm';
- else if (State == CONFIRM)
- buf[1] = '?';
- } else if (State == EXTERNCMD)
- buf[0] = '!';
- else if (State & INSERT) {
- if (State & VREPLACE_FLAG) {
- buf[0] = 'R';
- buf[1] = 'v';
- } else if (State & REPLACE_FLAG)
- buf[0] = 'R';
- else
- buf[0] = 'i';
- } else if (State & CMDLINE) {
- buf[0] = 'c';
- if (exmode_active)
- buf[1] = 'v';
- } else if (exmode_active) {
- buf[0] = 'c';
- buf[1] = 'e';
- } else if (State & TERM_FOCUS) {
- buf[0] = 't';
- } else {
- buf[0] = 'n';
- if (finish_op)
- buf[1] = 'o';
+ // Clear out the minor mode when the argument is not a non-zero number or
+ // non-empty string.
+ if (!non_zero_arg(&argvars[0])) {
+ mode[1] = NUL;
}
- /* Clear out the minor mode when the argument is not a non-zero number or
- * non-empty string. */
- if (!non_zero_arg(&argvars[0]))
- buf[1] = NUL;
-
- rettv->vval.v_string = vim_strsave(buf);
+ rettv->vval.v_string = (char_u *)mode;
rettv->v_type = VAR_STRING;
}
/// "msgpackdump()" function
-static void f_msgpackdump(typval_T *argvars, typval_T *rettv)
+static void f_msgpackdump(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "msgpackdump()");
return;
}
- list_T *ret_list = rettv_list_alloc(rettv);
- const list_T *list = argvars[0].vval.v_list;
- if (list == NULL) {
- return;
- }
+ list_T *const ret_list = tv_list_alloc_ret(rettv, kListLenMayKnow);
+ list_T *const list = argvars[0].vval.v_list;
msgpack_packer *lpacker = msgpack_packer_new(ret_list, &encode_list_write);
const char *const msg = _("msgpackdump() argument, index %i");
// Assume that translation will not take more then 4 times more space
char msgbuf[sizeof("msgpackdump() argument, index ") * 4 + NUMBUFLEN];
int idx = 0;
- for (listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
- vim_snprintf(msgbuf, sizeof(msgbuf), (char *) msg, idx);
+ TV_LIST_ITER(list, li, {
+ vim_snprintf(msgbuf, sizeof(msgbuf), (char *)msg, idx);
idx++;
- if (encode_vim_to_msgpack(lpacker, &li->li_tv, msgbuf) == FAIL) {
+ if (encode_vim_to_msgpack(lpacker, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) {
break;
}
- }
+ });
msgpack_packer_free(lpacker);
}
/// "msgpackparse" function
-static void f_msgpackparse(typval_T *argvars, typval_T *rettv)
+static void f_msgpackparse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "msgpackparse()");
return;
}
- list_T *ret_list = rettv_list_alloc(rettv);
- const list_T *list = argvars[0].vval.v_list;
- if (list == NULL || list->lv_first == NULL) {
+ list_T *const ret_list = tv_list_alloc_ret(rettv, kListLenMayKnow);
+ const list_T *const list = argvars[0].vval.v_list;
+ if (tv_list_len(list) == 0) {
return;
}
- if (list->lv_first->li_tv.v_type != VAR_STRING) {
+ if (TV_LIST_ITEM_TV(tv_list_first(list))->v_type != VAR_STRING) {
EMSG2(_(e_invarg2), "List item is not a string");
return;
}
@@ -12905,13 +12857,12 @@ static void f_msgpackparse(typval_T *argvars, typval_T *rettv)
goto f_msgpackparse_exit;
}
if (result == MSGPACK_UNPACK_SUCCESS) {
- listitem_T *li = listitem_alloc();
- li->li_tv.v_type = VAR_UNKNOWN;
- list_append(ret_list, li);
- if (msgpack_to_vim(unpacked.data, &li->li_tv) == FAIL) {
+ typval_T tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(unpacked.data, &tv) == FAIL) {
EMSG2(_(e_invarg2), "Failed to convert msgpack string");
goto f_msgpackparse_exit;
}
+ tv_list_append_owned_tv(ret_list, tv);
}
if (result == MSGPACK_UNPACK_CONTINUE) {
if (rlret == OK) {
@@ -12934,17 +12885,18 @@ f_msgpackparse_exit:
/*
* "nextnonblank()" function
*/
-static void f_nextnonblank(typval_T *argvars, typval_T *rettv)
+static void f_nextnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
linenr_T lnum;
- for (lnum = get_tv_lnum(argvars);; ++lnum) {
+ for (lnum = tv_get_lnum(argvars);; lnum++) {
if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) {
lnum = 0;
break;
}
- if (*skipwhite(ml_get(lnum)) != NUL)
+ if (*skipwhite(ml_get(lnum)) != NUL) {
break;
+ }
}
rettv->vval.v_number = lnum;
}
@@ -12952,107 +12904,110 @@ static void f_nextnonblank(typval_T *argvars, typval_T *rettv)
/*
* "nr2char()" function
*/
-static void f_nr2char(typval_T *argvars, typval_T *rettv)
+static void f_nr2char(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
-
- if (has_mbyte) {
- int utf8 = 0;
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ if (!tv_check_num(&argvars[1])) {
+ return;
+ }
+ }
- if (argvars[1].v_type != VAR_UNKNOWN)
- utf8 = get_tv_number_chk(&argvars[1], NULL);
- if (utf8)
- buf[(*utf_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
- else
- buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL;
- } else {
- buf[0] = (char_u)get_tv_number(&argvars[0]);
- buf[1] = NUL;
+ bool error = false;
+ const varnumber_T num = tv_get_number_chk(&argvars[0], &error);
+ if (error) {
+ return;
+ }
+ if (num < 0) {
+ EMSG(_("E5070: Character number must not be less than zero"));
+ return;
}
+ if (num > INT_MAX) {
+ emsgf(_("E5071: Character number must not be greater than INT_MAX (%i)"),
+ INT_MAX);
+ return;
+ }
+
+ char buf[MB_MAXBYTES];
+ const int len = utf_char2bytes((int)num, (char_u *)buf);
+
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strsave(buf);
+ rettv->vval.v_string = xmemdupz(buf, (size_t)len);
}
/*
* "or(expr, expr)" function
*/
-static void f_or(typval_T *argvars, typval_T *rettv)
+static void f_or(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
- | get_tv_number_chk(&argvars[1], NULL);
+ rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
+ | tv_get_number_chk(&argvars[1], NULL);
}
/*
* "pathshorten()" function
*/
-static void f_pathshorten(typval_T *argvars, typval_T *rettv)
+static void f_pathshorten(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = get_tv_string_chk(&argvars[0]);
- if (!rettv->vval.v_string) {
+ const char *const s = tv_get_string_chk(&argvars[0]);
+ if (!s) {
return;
}
- rettv->vval.v_string = shorten_dir(vim_strsave(rettv->vval.v_string));
+ rettv->vval.v_string = shorten_dir((char_u *)xstrdup(s));
}
/*
* "pow()" function
*/
-static void f_pow(typval_T *argvars, typval_T *rettv)
+static void f_pow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_T fx, fy;
+ float_T fx;
+ float_T fy;
rettv->v_type = VAR_FLOAT;
- if (get_float_arg(argvars, &fx) == OK
- && get_float_arg(&argvars[1], &fy) == OK)
+ if (tv_get_float_chk(argvars, &fx) && tv_get_float_chk(&argvars[1], &fy)) {
rettv->vval.v_float = pow(fx, fy);
- else
+ } else {
rettv->vval.v_float = 0.0;
+ }
}
/*
* "prevnonblank()" function
*/
-static void f_prevnonblank(typval_T *argvars, typval_T *rettv)
+static void f_prevnonblank(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
-
- lnum = get_tv_lnum(argvars);
- if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
+ linenr_T lnum = tv_get_lnum(argvars);
+ if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
lnum = 0;
- else
- while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
- --lnum;
+ } else {
+ while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) {
+ lnum--;
+ }
+ }
rettv->vval.v_number = lnum;
}
-/* This dummy va_list is here because:
- * - passing a NULL pointer doesn't work when va_list isn't a pointer
- * - locally in the function results in a "used before set" warning
- * - using va_start() to initialize it gives "function with fixed args" error */
-static va_list ap;
-
/*
* "printf()" function
*/
-static void f_printf(typval_T *argvars, typval_T *rettv)
+static void f_printf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
{
- char_u buf[NUMBUFLEN];
int len;
int saved_did_emsg = did_emsg;
- char *fmt;
- /* Get the required length, allocate the buffer and do it for real. */
- did_emsg = FALSE;
- fmt = (char *)get_tv_string_buf(&argvars[0], buf);
- len = vim_vsnprintf(NULL, 0, fmt, ap, argvars + 1);
+ // Get the required length, allocate the buffer and do it for real.
+ did_emsg = false;
+ char buf[NUMBUFLEN];
+ const char *fmt = tv_get_string_buf(&argvars[0], buf);
+ len = vim_vsnprintf(NULL, 0, fmt, dummy_ap, argvars + 1);
if (!did_emsg) {
char *s = xmalloc(len + 1);
rettv->vval.v_string = (char_u *)s;
- (void)vim_vsnprintf(s, len + 1, fmt, ap, argvars + 1);
+ (void)vim_vsnprintf(s, len + 1, fmt, dummy_ap, argvars + 1);
}
did_emsg |= saved_did_emsg;
}
@@ -13061,7 +13016,7 @@ static void f_printf(typval_T *argvars, typval_T *rettv)
/*
* "pumvisible()" function
*/
-static void f_pumvisible(typval_T *argvars, typval_T *rettv)
+static void f_pumvisible(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (pum_visible())
rettv->vval.v_number = 1;
@@ -13070,50 +13025,71 @@ static void f_pumvisible(typval_T *argvars, typval_T *rettv)
/*
* "pyeval()" function
*/
-static void f_pyeval(typval_T *argvars, typval_T *rettv)
+static void f_pyeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
+ if (p_pyx == 0) {
+ p_pyx = 2;
+ }
+
script_host_eval("python", argvars, rettv);
}
/*
* "py3eval()" function
*/
-static void f_py3eval(typval_T *argvars, typval_T *rettv)
+static void f_py3eval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
+ if (p_pyx == 0) {
+ p_pyx = 3;
+ }
+
script_host_eval("python3", argvars, rettv);
}
+// "pyxeval()" function
+static void f_pyxeval(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ init_pyxversion();
+ if (p_pyx == 2) {
+ f_pyeval(argvars, rettv, NULL);
+ } else {
+ f_py3eval(argvars, rettv, NULL);
+ }
+}
+
/*
* "range()" function
*/
-static void f_range(typval_T *argvars, typval_T *rettv)
+static void f_range(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long start;
- long end;
- long stride = 1;
- long i;
- int error = FALSE;
+ varnumber_T start;
+ varnumber_T end;
+ varnumber_T stride = 1;
+ varnumber_T i;
+ bool error = false;
- start = get_tv_number_chk(&argvars[0], &error);
+ start = tv_get_number_chk(&argvars[0], &error);
if (argvars[1].v_type == VAR_UNKNOWN) {
end = start - 1;
start = 0;
} else {
- end = get_tv_number_chk(&argvars[1], &error);
- if (argvars[2].v_type != VAR_UNKNOWN)
- stride = get_tv_number_chk(&argvars[2], &error);
+ end = tv_get_number_chk(&argvars[1], &error);
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ stride = tv_get_number_chk(&argvars[2], &error);
+ }
}
- if (error)
- return; /* type error; errmsg already given */
- if (stride == 0)
+ if (error) {
+ return; // Type error; errmsg already given.
+ }
+ if (stride == 0) {
EMSG(_("E726: Stride is zero"));
- else if (stride > 0 ? end + 1 < start : end - 1 > start)
+ } else if (stride > 0 ? end + 1 < start : end - 1 > start) {
EMSG(_("E727: Start past end"));
- else {
- rettv_list_alloc(rettv);
+ } else {
+ tv_list_alloc_ret(rettv, (end - start) / stride);
for (i = start; stride > 0 ? i <= end : i >= end; i += stride) {
- list_append_number(rettv->vval.v_list, (varnumber_T)i);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)i);
}
}
}
@@ -13121,10 +13097,9 @@ static void f_range(typval_T *argvars, typval_T *rettv)
/*
* "readfile()" function
*/
-static void f_readfile(typval_T *argvars, typval_T *rettv)
+static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int binary = FALSE;
- char_u *fname;
+ bool binary = false;
FILE *fd;
char_u buf[(IOSIZE/256)*256]; /* rounded to avoid odd + 1 */
int io_size = sizeof(buf);
@@ -13133,40 +13108,40 @@ static void f_readfile(typval_T *argvars, typval_T *rettv)
long prevlen = 0; /* length of data in prev */
long prevsize = 0; /* size of prev buffer */
long maxline = MAXLNUM;
- long cnt = 0;
- char_u *p; /* position in buf */
- char_u *start; /* start of current line */
if (argvars[1].v_type != VAR_UNKNOWN) {
- if (STRCMP(get_tv_string(&argvars[1]), "b") == 0)
- binary = TRUE;
- if (argvars[2].v_type != VAR_UNKNOWN)
- maxline = get_tv_number(&argvars[2]);
+ if (strcmp(tv_get_string(&argvars[1]), "b") == 0) {
+ binary = true;
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ maxline = tv_get_number(&argvars[2]);
+ }
}
- rettv_list_alloc(rettv);
+ list_T *const l = tv_list_alloc_ret(rettv, kListLenUnknown);
- /* Always open the file in binary mode, library functions have a mind of
- * their own about CR-LF conversion. */
- fname = get_tv_string(&argvars[0]);
- if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) {
- EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname);
+ // Always open the file in binary mode, library functions have a mind of
+ // their own about CR-LF conversion.
+ const char *const fname = tv_get_string(&argvars[0]);
+ if (*fname == NUL || (fd = mch_fopen(fname, READBIN)) == NULL) {
+ EMSG2(_(e_notopen), *fname == NUL ? _("<empty>") : fname);
return;
}
- while (cnt < maxline || maxline < 0) {
+ while (maxline < 0 || tv_list_len(l) < maxline) {
readlen = (int)fread(buf, 1, io_size, fd);
- /* This for loop processes what was read, but is also entered at end
- * of file so that either:
- * - an incomplete line gets written
- * - a "binary" file gets an empty line at the end if it ends in a
- * newline. */
+ // This for loop processes what was read, but is also entered at end
+ // of file so that either:
+ // - an incomplete line gets written
+ // - a "binary" file gets an empty line at the end if it ends in a
+ // newline.
+ char_u *p; // Position in buf.
+ char_u *start; // Start of current line.
for (p = buf, start = buf;
p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary));
- ++p) {
+ p++) {
if (*p == '\n' || readlen <= 0) {
- listitem_T *li;
char_u *s = NULL;
size_t len = p - start;
@@ -13193,22 +13168,32 @@ static void f_readfile(typval_T *argvars, typval_T *rettv)
prevlen = prevsize = 0;
}
- li = listitem_alloc();
- li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = s;
- list_append(rettv->vval.v_list, li);
-
- start = p + 1; /* step over newline */
- if ((++cnt >= maxline && maxline >= 0) || readlen <= 0)
+ tv_list_append_owned_tv(l, (typval_T) {
+ .v_type = VAR_STRING,
+ .v_lock = VAR_UNLOCKED,
+ .vval.v_string = s,
+ });
+
+ start = p + 1; // Step over newline.
+ if (maxline < 0) {
+ if (tv_list_len(l) > -maxline) {
+ assert(tv_list_len(l) == 1 + (-maxline));
+ tv_list_item_remove(l, tv_list_first(l));
+ }
+ } else if (tv_list_len(l) >= maxline) {
+ assert(tv_list_len(l) == maxline);
+ break;
+ }
+ if (readlen <= 0) {
break;
- } else if (*p == NUL)
+ }
+ } else if (*p == NUL) {
*p = '\n';
- /* Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this
- * when finding the BF and check the previous two bytes. */
- else if (*p == 0xbf && enc_utf8 && !binary) {
- /* Find the two bytes before the 0xbf. If p is at buf, or buf
- * + 1, these may be in the "prev" string. */
+ // Check for utf8 "bom"; U+FEFF is encoded as EF BB BF. Do this
+ // when finding the BF and check the previous two bytes.
+ } else if (*p == 0xbf && !binary) {
+ // Find the two bytes before the 0xbf. If p is at buf, or buf + 1,
+ // these may be in the "prev" string.
char_u back1 = p >= buf + 1 ? p[-1]
: prevlen >= 1 ? prev[prevlen - 1] : NUL;
char_u back2 = p >= buf + 2 ? p[-2]
@@ -13227,8 +13212,9 @@ static void f_readfile(typval_T *argvars, typval_T *rettv)
/* have to shuffle buf to close gap */
int adjust_prevlen = 0;
- if (dest < buf) {
- adjust_prevlen = (int)(buf - dest); /* must be 1 or 2 */
+ if (dest < buf) { // -V782
+ adjust_prevlen = (int)(buf - dest); // -V782
+ // adjust_prevlen must be 1 or 2.
dest = buf;
}
if (readlen > p - buf + 1)
@@ -13241,8 +13227,9 @@ static void f_readfile(typval_T *argvars, typval_T *rettv)
}
} /* for */
- if ((cnt >= maxline && maxline >= 0) || readlen <= 0)
+ if ((maxline >= 0 && tv_list_len(l) >= maxline) || readlen <= 0) {
break;
+ }
if (start < p) {
/* There's part of a line in buf, store it in "prev". */
if (p - start + prevlen >= prevsize) {
@@ -13266,16 +13253,6 @@ static void f_readfile(typval_T *argvars, typval_T *rettv)
}
} /* while */
- /*
- * For a negative line count use only the lines at the end of the file,
- * free the rest.
- */
- if (maxline < 0)
- while (cnt > -maxline) {
- listitem_remove(rettv->vval.v_list, rettv->vval.v_list->lv_first);
- --cnt;
- }
-
xfree(prev);
fclose(fd);
}
@@ -13289,15 +13266,13 @@ static void f_readfile(typval_T *argvars, typval_T *rettv)
/// @return OK In case of success, FAIL in case of error
static int list2proftime(typval_T *arg, proftime_T *tm) FUNC_ATTR_NONNULL_ALL
{
- if (arg->v_type != VAR_LIST
- || arg->vval.v_list == NULL
- || arg->vval.v_list->lv_len != 2) {
+ if (arg->v_type != VAR_LIST || tv_list_len(arg->vval.v_list) != 2) {
return FAIL;
}
- int error = false;
- varnumber_T n1 = list_find_nr(arg->vval.v_list, 0L, &error);
- varnumber_T n2 = list_find_nr(arg->vval.v_list, 1L, &error);
+ bool error = false;
+ varnumber_T n1 = tv_list_find_nr(arg->vval.v_list, 0L, &error);
+ varnumber_T n2 = tv_list_find_nr(arg->vval.v_list, 1L, &error);
if (error) {
return FAIL;
}
@@ -13305,7 +13280,7 @@ static int list2proftime(typval_T *arg, proftime_T *tm) FUNC_ATTR_NONNULL_ALL
// in f_reltime() we split up the 64-bit proftime_T into two 32-bit
// values, now we combine them again.
union {
- struct { varnumber_T low, high; } split;
+ struct { int32_t low, high; } split;
proftime_T prof;
} u = { .split.high = n1, .split.low = n2 };
@@ -13320,7 +13295,7 @@ static int list2proftime(typval_T *arg, proftime_T *tm) FUNC_ATTR_NONNULL_ALL
/// one argument it returns the time passed since the argument.
/// With two arguments it returns the time passed between
/// the two arguments.
-static void f_reltime(typval_T *argvars, typval_T *rettv) FUNC_ATTR_NONNULL_ALL
+static void f_reltime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
proftime_T res;
proftime_T start;
@@ -13346,7 +13321,7 @@ static void f_reltime(typval_T *argvars, typval_T *rettv) FUNC_ATTR_NONNULL_ALL
// (varnumber_T is defined as int). For all our supported platforms, int's
// are at least 32-bits wide. So we'll use two 32-bit values to store it.
union {
- struct { varnumber_T low, high; } split;
+ struct { int32_t low, high; } split;
proftime_T prof;
} u = { .prof = res };
@@ -13356,9 +13331,9 @@ static void f_reltime(typval_T *argvars, typval_T *rettv) FUNC_ATTR_NONNULL_ALL
STATIC_ASSERT(sizeof(u.prof) == sizeof(u) && sizeof(u.split) == sizeof(u),
"type punning will produce incorrect results on this platform");
- rettv_list_alloc(rettv);
- list_append_number(rettv->vval.v_list, u.split.high);
- list_append_number(rettv->vval.v_list, u.split.low);
+ tv_list_alloc_ret(rettv, 2);
+ tv_list_append_number(rettv->vval.v_list, u.split.high);
+ tv_list_append_number(rettv->vval.v_list, u.split.low);
}
/// f_reltimestr - return a string that represents the value of {time}
@@ -13366,7 +13341,7 @@ static void f_reltime(typval_T *argvars, typval_T *rettv) FUNC_ATTR_NONNULL_ALL
/// @return The string representation of the argument, the format is the
/// number of seconds followed by a dot, followed by the number
/// of microseconds.
-static void f_reltimestr(typval_T *argvars, typval_T *rettv)
+static void f_reltimestr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
proftime_T tm;
@@ -13381,81 +13356,76 @@ static void f_reltimestr(typval_T *argvars, typval_T *rettv)
/*
* "remove()" function
*/
-static void f_remove(typval_T *argvars, typval_T *rettv)
+static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
list_T *l;
listitem_T *item, *item2;
listitem_T *li;
long idx;
long end;
- char_u *key;
dict_T *d;
dictitem_T *di;
- char_u *arg_errmsg = (char_u *)N_("remove() argument");
+ const char *const arg_errmsg = N_("remove() argument");
if (argvars[0].v_type == VAR_DICT) {
if (argvars[2].v_type != VAR_UNKNOWN) {
EMSG2(_(e_toomanyarg), "remove()");
} else if ((d = argvars[0].vval.v_dict) != NULL
- && !tv_check_lock(d->dv_lock, arg_errmsg, true)) {
- key = get_tv_string_chk(&argvars[1]);
+ && !tv_check_lock(d->dv_lock, arg_errmsg, TV_TRANSLATE)) {
+ const char *key = tv_get_string_chk(&argvars[1]);
if (key != NULL) {
- di = dict_find(d, key, -1);
+ di = tv_dict_find(d, key, -1);
if (di == NULL) {
EMSG2(_(e_dictkey), key);
- } else if (!var_check_fixed(di->di_flags, arg_errmsg, true)
- && !var_check_ro(di->di_flags, arg_errmsg, true)) {
+ } else if (!var_check_fixed(di->di_flags, arg_errmsg, TV_TRANSLATE)
+ && !var_check_ro(di->di_flags, arg_errmsg, TV_TRANSLATE)) {
*rettv = di->di_tv;
- init_tv(&di->di_tv);
- dictitem_remove(d, di);
- if (is_watched(d)) {
- dictwatcher_notify(d, (char *)key, NULL, rettv);
+ di->di_tv = TV_INITIAL_VALUE;
+ tv_dict_item_remove(d, di);
+ if (tv_dict_is_watched(d)) {
+ tv_dict_watcher_notify(d, key, NULL, rettv);
}
}
}
}
} else if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listdictarg), "remove()");
- } else if ((l = argvars[0].vval.v_list) != NULL
- && !tv_check_lock(l->lv_lock, arg_errmsg, true)) {
- int error = (int)false;
-
- idx = get_tv_number_chk(&argvars[1], &error);
- if (error)
- ; /* type error: do nothing, errmsg already given */
- else if ((item = list_find(l, idx)) == NULL)
+ } else if (!tv_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
+ arg_errmsg, TV_TRANSLATE)) {
+ bool error = false;
+
+ idx = tv_get_number_chk(&argvars[1], &error);
+ if (error) {
+ // Type error: do nothing, errmsg already given.
+ } else if ((item = tv_list_find(l, idx)) == NULL) {
EMSGN(_(e_listidx), idx);
- else {
+ } else {
if (argvars[2].v_type == VAR_UNKNOWN) {
// Remove one item, return its value.
- vim_list_remove(l, item, item);
- *rettv = item->li_tv;
+ tv_list_drop_items(l, item, item);
+ *rettv = *TV_LIST_ITEM_TV(item);
xfree(item);
} else {
- /* Remove range of items, return list with values. */
- end = get_tv_number_chk(&argvars[2], &error);
- if (error)
- ; /* type error: do nothing */
- else if ((item2 = list_find(l, end)) == NULL)
+ // Remove range of items, return list with values.
+ end = tv_get_number_chk(&argvars[2], &error);
+ if (error) {
+ // Type error: do nothing.
+ } else if ((item2 = tv_list_find(l, end)) == NULL) {
EMSGN(_(e_listidx), end);
- else {
+ } else {
int cnt = 0;
- for (li = item; li != NULL; li = li->li_next) {
- ++cnt;
- if (li == item2)
+ for (li = item; li != NULL; li = TV_LIST_ITEM_NEXT(l, li)) {
+ cnt++;
+ if (li == item2) {
break;
+ }
}
- if (li == NULL) /* didn't find "item2" after "item" */
+ if (li == NULL) { // Didn't find "item2" after "item".
EMSG(_(e_invrange));
- else {
- vim_list_remove(l, item, item2);
- l = rettv_list_alloc(rettv);
- l->lv_first = item;
- l->lv_last = item2;
- item->li_prev = NULL;
- item2->li_next = NULL;
- l->lv_len = cnt;
+ } else {
+ tv_list_move_items(l, item, item2, tv_list_alloc_ret(rettv, cnt),
+ cnt);
}
}
}
@@ -13466,110 +13436,105 @@ static void f_remove(typval_T *argvars, typval_T *rettv)
/*
* "rename({from}, {to})" function
*/
-static void f_rename(typval_T *argvars, typval_T *rettv)
+static void f_rename(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
-
- if (check_restricted() || check_secure())
+ if (check_restricted() || check_secure()) {
rettv->vval.v_number = -1;
- else
- rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]),
- get_tv_string_buf(&argvars[1], buf));
+ } else {
+ char buf[NUMBUFLEN];
+ rettv->vval.v_number = vim_rename(
+ (const char_u *)tv_get_string(&argvars[0]),
+ (const char_u *)tv_get_string_buf(&argvars[1], buf));
+ }
}
/*
* "repeat()" function
*/
-static void f_repeat(typval_T *argvars, typval_T *rettv)
+static void f_repeat(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
- int n;
-
- n = get_tv_number(&argvars[1]);
+ varnumber_T n = tv_get_number(&argvars[1]);
if (argvars[0].v_type == VAR_LIST) {
- rettv_list_alloc(rettv);
- if (argvars[0].vval.v_list != NULL) {
- while (n-- > 0) {
- list_extend(rettv->vval.v_list, argvars[0].vval.v_list, NULL);
- }
+ tv_list_alloc_ret(rettv, (n > 0) * n * tv_list_len(argvars[0].vval.v_list));
+ while (n-- > 0) {
+ tv_list_extend(rettv->vval.v_list, argvars[0].vval.v_list, NULL);
}
} else {
- p = get_tv_string(&argvars[0]);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
+ if (n <= 0) {
+ return;
+ }
+
+ const char *const p = tv_get_string(&argvars[0]);
- int slen = (int)STRLEN(p);
- int len = slen * n;
- if (len <= 0)
+ const size_t slen = strlen(p);
+ if (slen == 0) {
+ return;
+ }
+ const size_t len = slen * n;
+ // Detect overflow.
+ if (len / n != slen) {
return;
+ }
- char_u *r = xmallocz(len);
- for (int i = 0; i < n; i++)
- memmove(r + i * slen, p, (size_t)slen);
+ char *const r = xmallocz(len);
+ for (varnumber_T i = 0; i < n; i++) {
+ memmove(r + i * slen, p, slen);
+ }
- rettv->vval.v_string = r;
+ rettv->vval.v_string = (char_u *)r;
}
}
/*
* "resolve()" function
*/
-static void f_resolve(typval_T *argvars, typval_T *rettv)
+static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
-#ifdef HAVE_READLINK
- char_u *buf = NULL;
-#endif
-
- p = get_tv_string(&argvars[0]);
+ rettv->v_type = VAR_STRING;
+ const char *fname = tv_get_string(&argvars[0]);
#ifdef WIN32
- {
- char_u *v = NULL;
-
- v = mch_resolve_shortcut(p);
- if (v != NULL)
- rettv->vval.v_string = v;
- else
- rettv->vval.v_string = vim_strsave(p);
- }
+ char *const v = os_resolve_shortcut(fname);
+ rettv->vval.v_string = (char_u *)(v == NULL ? xstrdup(fname) : v);
#else
# ifdef HAVE_READLINK
{
- char_u *cpy;
- int len;
- char_u *remain = NULL;
- char_u *q;
- int is_relative_to_current = FALSE;
- int has_trailing_pathsep = FALSE;
+ bool is_relative_to_current = false;
+ bool has_trailing_pathsep = false;
int limit = 100;
- p = vim_strsave(p);
+ char *p = xstrdup(fname);
if (p[0] == '.' && (vim_ispathsep(p[1])
- || (p[1] == '.' && (vim_ispathsep(p[2])))))
- is_relative_to_current = TRUE;
+ || (p[1] == '.' && (vim_ispathsep(p[2]))))) {
+ is_relative_to_current = true;
+ }
- len = STRLEN(p);
- if (len > 0 && after_pathsep((char *)p, (char *)p + len)) {
- has_trailing_pathsep = TRUE;
- p[len - 1] = NUL; /* the trailing slash breaks readlink() */
+ ptrdiff_t len = (ptrdiff_t)strlen(p);
+ if (len > 0 && after_pathsep(p, p + len)) {
+ has_trailing_pathsep = true;
+ p[len - 1] = NUL; // The trailing slash breaks readlink().
}
- q = path_next_component(p);
+ char *q = (char *)path_next_component(p);
+ char *remain = NULL;
if (*q != NUL) {
- /* Separate the first path component in "p", and keep the
- * remainder (beginning with the path separator). */
- remain = vim_strsave(q - 1);
+ // Separate the first path component in "p", and keep the
+ // remainder (beginning with the path separator).
+ remain = xstrdup(q - 1);
q[-1] = NUL;
}
- buf = xmallocz(MAXPATHL);
+ char *const buf = xmallocz(MAXPATHL);
+ char *cpy;
for (;; ) {
for (;; ) {
- len = readlink((char *)p, (char *)buf, MAXPATHL);
- if (len <= 0)
+ len = readlink(p, buf, MAXPATHL);
+ if (len <= 0) {
break;
+ }
buf[len] = NUL;
if (limit-- == 0) {
@@ -13577,66 +13542,72 @@ static void f_resolve(typval_T *argvars, typval_T *rettv)
xfree(remain);
EMSG(_("E655: Too many symbolic links (cycle?)"));
rettv->vval.v_string = NULL;
- goto fail;
+ xfree(buf);
+ return;
}
- /* Ensure that the result will have a trailing path separator
- * if the argument has one. */
- if (remain == NULL && has_trailing_pathsep)
- add_pathsep((char *)buf);
+ // Ensure that the result will have a trailing path separator
+ // if the argument has one. */
+ if (remain == NULL && has_trailing_pathsep) {
+ add_pathsep(buf);
+ }
- /* Separate the first path component in the link value and
- * concatenate the remainders. */
- q = path_next_component(vim_ispathsep(*buf) ? buf + 1 : buf);
+ // Separate the first path component in the link value and
+ // concatenate the remainders. */
+ q = (char *)path_next_component(vim_ispathsep(*buf) ? buf + 1 : buf);
if (*q != NUL) {
cpy = remain;
- remain = remain ?
- concat_str(q - 1, remain) : (char_u *) xstrdup((char *)q - 1);
+ remain = (remain
+ ? (char *)concat_str((char_u *)q - 1, (char_u *)remain)
+ : xstrdup(q - 1));
xfree(cpy);
q[-1] = NUL;
}
- q = path_tail(p);
+ q = (char *)path_tail((char_u *)p);
if (q > p && *q == NUL) {
- /* Ignore trailing path separator. */
+ // Ignore trailing path separator.
q[-1] = NUL;
- q = path_tail(p);
+ q = (char *)path_tail((char_u *)p);
}
- if (q > p && !path_is_absolute_path(buf)) {
- /* symlink is relative to directory of argument */
- cpy = xmalloc(STRLEN(p) + STRLEN(buf) + 1);
- STRCPY(cpy, p);
- STRCPY(path_tail(cpy), buf);
- xfree(p);
- p = cpy;
+ if (q > p && !path_is_absolute((const char_u *)buf)) {
+ // Symlink is relative to directory of argument. Replace the
+ // symlink with the resolved name in the same directory.
+ const size_t p_len = strlen(p);
+ const size_t buf_len = strlen(buf);
+ p = xrealloc(p, p_len + buf_len + 1);
+ memcpy(path_tail((char_u *)p), buf, buf_len + 1);
} else {
xfree(p);
- p = vim_strsave(buf);
+ p = xstrdup(buf);
}
}
- if (remain == NULL)
+ if (remain == NULL) {
break;
+ }
- /* Append the first path component of "remain" to "p". */
- q = path_next_component(remain + 1);
+ // Append the first path component of "remain" to "p".
+ q = (char *)path_next_component(remain + 1);
len = q - remain - (*q != NUL);
- cpy = vim_strnsave(p, STRLEN(p) + len);
- STRNCAT(cpy, remain, len);
+ const size_t p_len = strlen(p);
+ cpy = xmallocz(p_len + len);
+ memcpy(cpy, p, p_len + 1);
+ xstrlcat(cpy + p_len, remain, len + 1);
xfree(p);
p = cpy;
- /* Shorten "remain". */
- if (*q != NUL)
+ // Shorten "remain".
+ if (*q != NUL) {
STRMOVE(remain, q - 1);
- else {
+ } else {
xfree(remain);
remain = NULL;
}
}
- /* If the result is a relative path name, make it explicitly relative to
- * the current directory if and only if the argument had this form. */
+ // If the result is a relative path name, make it explicitly relative to
+ // the current directory if and only if the argument had this form.
if (!vim_ispathsep(*p)) {
if (is_relative_to_current
&& *p != NUL
@@ -13646,69 +13617,54 @@ static void f_resolve(typval_T *argvars, typval_T *rettv)
|| (p[1] == '.'
&& (p[2] == NUL
|| vim_ispathsep(p[2])))))) {
- /* Prepend "./". */
- cpy = concat_str((char_u *)"./", p);
+ // Prepend "./".
+ cpy = (char *)concat_str((const char_u *)"./", (const char_u *)p);
xfree(p);
p = cpy;
} else if (!is_relative_to_current) {
- /* Strip leading "./". */
+ // Strip leading "./".
q = p;
- while (q[0] == '.' && vim_ispathsep(q[1]))
+ while (q[0] == '.' && vim_ispathsep(q[1])) {
q += 2;
- if (q > p)
+ }
+ if (q > p) {
STRMOVE(p, p + 2);
+ }
}
}
- /* Ensure that the result will have no trailing path separator
- * if the argument had none. But keep "/" or "//". */
+ // Ensure that the result will have no trailing path separator
+ // if the argument had none. But keep "/" or "//".
if (!has_trailing_pathsep) {
- q = p + STRLEN(p);
- if (after_pathsep((char *)p, (char *)q))
- *path_tail_with_sep(p) = NUL;
+ q = p + strlen(p);
+ if (after_pathsep(p, q)) {
+ *path_tail_with_sep((char_u *)p) = NUL;
+ }
}
- rettv->vval.v_string = p;
+ rettv->vval.v_string = (char_u *)p;
+ xfree(buf);
}
# else
- rettv->vval.v_string = vim_strsave(p);
+ rettv->vval.v_string = (char_u *)xstrdup(p);
# endif
#endif
simplify_filename(rettv->vval.v_string);
-
-#ifdef HAVE_READLINK
-fail:
- xfree(buf);
-#endif
- rettv->v_type = VAR_STRING;
}
/*
* "reverse({list})" function
*/
-static void f_reverse(typval_T *argvars, typval_T *rettv)
+static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- list_T *l;
- listitem_T *li, *ni;
-
+ list_T *l;
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "reverse()");
- } else if ((l = argvars[0].vval.v_list) != NULL
- && !tv_check_lock(l->lv_lock,
- (char_u *)N_("reverse() argument"), true)) {
- li = l->lv_last;
- l->lv_first = l->lv_last = NULL;
- l->lv_len = 0;
- while (li != NULL) {
- ni = li->li_prev;
- list_append(l, li);
- li = ni;
- }
- rettv->vval.v_list = l;
- rettv->v_type = VAR_LIST;
- ++l->lv_refcount;
- l->lv_idx = l->lv_len - l->lv_idx - 1;
+ } else if (!tv_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
+ N_("reverse() argument"), TV_TRANSLATE)) {
+ tv_list_reverse(l);
+ tv_list_set_ret(rettv, l);
}
}
@@ -13729,40 +13685,45 @@ static void f_reverse(typval_T *argvars, typval_T *rettv)
static int get_search_arg(typval_T *varp, int *flagsp)
{
int dir = FORWARD;
- char_u *flags;
- char_u nbuf[NUMBUFLEN];
int mask;
if (varp->v_type != VAR_UNKNOWN) {
- flags = get_tv_string_buf_chk(varp, nbuf);
- if (flags == NULL)
- return 0; /* type error; errmsg already given */
+ char nbuf[NUMBUFLEN];
+ const char *flags = tv_get_string_buf_chk(varp, nbuf);
+ if (flags == NULL) {
+ return 0; // Type error; errmsg already given.
+ }
while (*flags != NUL) {
switch (*flags) {
- case 'b': dir = BACKWARD; break;
- case 'w': p_ws = true; break;
- case 'W': p_ws = false; break;
- default: mask = 0;
- if (flagsp != NULL)
- switch (*flags) {
- case 'c': mask = SP_START; break;
- case 'e': mask = SP_END; break;
- case 'm': mask = SP_RETCOUNT; break;
- case 'n': mask = SP_NOMOVE; break;
- case 'p': mask = SP_SUBPAT; break;
- case 'r': mask = SP_REPEAT; break;
- case 's': mask = SP_SETPCMARK; break;
- case 'z': mask = SP_COLUMN; break;
+ case 'b': dir = BACKWARD; break;
+ case 'w': p_ws = true; break;
+ case 'W': p_ws = false; break;
+ default: {
+ mask = 0;
+ if (flagsp != NULL) {
+ switch (*flags) {
+ case 'c': mask = SP_START; break;
+ case 'e': mask = SP_END; break;
+ case 'm': mask = SP_RETCOUNT; break;
+ case 'n': mask = SP_NOMOVE; break;
+ case 'p': mask = SP_SUBPAT; break;
+ case 'r': mask = SP_REPEAT; break;
+ case 's': mask = SP_SETPCMARK; break;
+ case 'z': mask = SP_COLUMN; break;
+ }
}
- if (mask == 0) {
- EMSG2(_(e_invarg2), flags);
- dir = 0;
- } else
- *flagsp |= mask;
+ if (mask == 0) {
+ emsgf(_(e_invarg2), flags);
+ dir = 0;
+ } else {
+ *flagsp |= mask;
+ }
+ }
}
- if (dir == 0)
+ if (dir == 0) {
break;
- ++flags;
+ }
+ flags++;
}
}
return dir;
@@ -13772,7 +13733,6 @@ static int get_search_arg(typval_T *varp, int *flagsp)
static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
{
int flags;
- char_u *pat;
pos_T pos;
pos_T save_cursor;
bool save_p_ws = p_ws;
@@ -13784,10 +13744,11 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
int options = SEARCH_KEEP;
int subpatnum;
- pat = get_tv_string(&argvars[0]);
- dir = get_search_arg(&argvars[1], flagsp); /* may set p_ws */
- if (dir == 0)
+ const char *const pat = tv_get_string(&argvars[0]);
+ dir = get_search_arg(&argvars[1], flagsp); // May set p_ws.
+ if (dir == 0) {
goto theend;
+ }
flags = *flagsp;
if (flags & SP_START) {
options |= SEARCH_START;
@@ -13801,13 +13762,15 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
/* Optional arguments: line number to stop searching and timeout. */
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
- lnum_stop = get_tv_number_chk(&argvars[2], NULL);
- if (lnum_stop < 0)
+ lnum_stop = tv_get_number_chk(&argvars[2], NULL);
+ if (lnum_stop < 0) {
goto theend;
+ }
if (argvars[3].v_type != VAR_UNKNOWN) {
- time_limit = get_tv_number_chk(&argvars[3], NULL);
- if (time_limit < 0)
+ time_limit = tv_get_number_chk(&argvars[3], NULL);
+ if (time_limit < 0) {
goto theend;
+ }
}
}
@@ -13822,13 +13785,13 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
*/
if (((flags & (SP_REPEAT | SP_RETCOUNT)) != 0)
|| ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) {
- EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
+ EMSG2(_(e_invarg2), tv_get_string(&argvars[1]));
goto theend;
}
pos = save_cursor = curwin->w_cursor;
- subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L,
- options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
+ subpatnum = searchit(curwin, curbuf, &pos, dir, (char_u *)pat, 1,
+ options, RE_SEARCH, (linenr_T)lnum_stop, &tm);
if (subpatnum != FAIL) {
if (flags & SP_SUBPAT)
retval = subpatnum;
@@ -13858,16 +13821,8 @@ theend:
return retval;
}
-/*
- * "round({float})" function
- */
-static void f_round(typval_T *argvars, typval_T *rettv)
-{
- float_op_wrapper(argvars, rettv, &round);
-}
-
// "rpcnotify()" function
-static void f_rpcnotify(typval_T *argvars, typval_T *rettv)
+static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -13892,9 +13847,8 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv)
ADD(args, vim_to_object(tv));
}
- if (!channel_send_event((uint64_t)argvars[0].vval.v_number,
- (char *)get_tv_string(&argvars[1]),
- args)) {
+ if (!rpc_send_event((uint64_t)argvars[0].vval.v_number,
+ tv_get_string(&argvars[1]), args)) {
EMSG2(_(e_invarg2), "Channel doesn't exist");
return;
}
@@ -13903,7 +13857,7 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv)
}
// "rpcrequest()" function
-static void f_rpcrequest(typval_T *argvars, typval_T *rettv)
+static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -13932,7 +13886,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv)
scid_T save_current_SID;
uint8_t *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
linenr_T save_sourcing_lnum;
- int save_autocmd_fname_full, save_autocmd_bufnr;
+ int save_autocmd_bufnr;
void *save_funccalp;
if (l_provider_call_nesting) {
@@ -13943,26 +13897,22 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv)
save_sourcing_lnum = sourcing_lnum;
save_autocmd_fname = autocmd_fname;
save_autocmd_match = autocmd_match;
- save_autocmd_fname_full = autocmd_fname_full;
save_autocmd_bufnr = autocmd_bufnr;
save_funccalp = save_funccal();
- //
+
current_SID = provider_caller_scope.SID;
sourcing_name = provider_caller_scope.sourcing_name;
sourcing_lnum = provider_caller_scope.sourcing_lnum;
autocmd_fname = provider_caller_scope.autocmd_fname;
autocmd_match = provider_caller_scope.autocmd_match;
- autocmd_fname_full = provider_caller_scope.autocmd_fname_full;
autocmd_bufnr = provider_caller_scope.autocmd_bufnr;
restore_funccal(provider_caller_scope.funccalp);
}
Error err = ERROR_INIT;
- Object result = channel_send_call((uint64_t)argvars[0].vval.v_number,
- (char *)get_tv_string(&argvars[1]),
- args,
- &err);
+ Object result = rpc_send_call((uint64_t)argvars[0].vval.v_number,
+ tv_get_string(&argvars[1]), args, &err);
if (l_provider_call_nesting) {
current_SID = save_current_SID;
@@ -13970,13 +13920,12 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv)
sourcing_lnum = save_sourcing_lnum;
autocmd_fname = save_autocmd_fname;
autocmd_match = save_autocmd_match;
- autocmd_fname_full = save_autocmd_fname_full;
autocmd_bufnr = save_autocmd_bufnr;
restore_funccal(save_funccalp);
}
- if (err.set) {
- vim_report_error(cstr_as_string(err.msg));
+ if (ERROR_SET(&err)) {
+ nvim_err_writeln(cstr_as_string(err.msg));
goto end;
}
@@ -13986,10 +13935,11 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv)
end:
api_free_object(result);
+ api_clear_error(&err);
}
-// "rpcstart()" function
-static void f_rpcstart(typval_T *argvars, typval_T *rettv)
+// "rpcstart()" function (DEPRECATED)
+static void f_rpcstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -14009,14 +13959,17 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv)
int argsl = 0;
if (argvars[1].v_type == VAR_LIST) {
args = argvars[1].vval.v_list;
- argsl = args->lv_len;
+ argsl = tv_list_len(args);
// Assert that all list items are strings
- for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
- if (arg->li_tv.v_type != VAR_STRING) {
- EMSG(_(e_invarg));
+ int i = 0;
+ TV_LIST_ITER_CONST(args, arg, {
+ if (TV_LIST_ITEM_TV(arg)->v_type != VAR_STRING) {
+ emsgf(_("E5010: List item %d of the second argument is not a string"),
+ i);
return;
}
- }
+ i++;
+ });
}
if (argvars[0].vval.v_string == NULL || argvars[0].vval.v_string[0] == NUL) {
@@ -14034,24 +13987,25 @@ static void f_rpcstart(typval_T *argvars, typval_T *rettv)
int i = 1;
// Copy arguments to the vector
if (argsl > 0) {
- for (listitem_T *arg = args->lv_first; arg != NULL; arg = arg->li_next) {
- argv[i++] = xstrdup((char *) get_tv_string(&arg->li_tv));
- }
+ TV_LIST_ITER_CONST(args, arg, {
+ argv[i++] = xstrdup(tv_get_string(TV_LIST_ITEM_TV(arg)));
+ });
}
// The last item of argv must be NULL
argv[i] = NULL;
- uint64_t channel_id = channel_from_process(argv);
- if (!channel_id) {
- EMSG(_(e_api_spawn_failed));
+ Channel *chan = channel_job_start(argv, CALLBACK_READER_INIT,
+ CALLBACK_READER_INIT, CALLBACK_NONE,
+ false, true, false, NULL, 0, 0, NULL,
+ &rettv->vval.v_number);
+ if (chan) {
+ channel_create_event(chan, NULL);
}
-
- rettv->vval.v_number = (varnumber_T)channel_id;
}
// "rpcstop()" function
-static void f_rpcstop(typval_T *argvars, typval_T *rettv)
+static void f_rpcstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = 0;
@@ -14066,49 +14020,54 @@ static void f_rpcstop(typval_T *argvars, typval_T *rettv)
return;
}
- rettv->vval.v_number = channel_close(argvars[0].vval.v_number);
+ // if called with a job, stop it, else closes the channel
+ uint64_t id = argvars[0].vval.v_number;
+ if (find_job(id, false)) {
+ f_jobstop(argvars, rettv, NULL);
+ } else {
+ const char *error;
+ rettv->vval.v_number = channel_close(argvars[0].vval.v_number,
+ kChannelPartRpc, &error);
+ if (!rettv->vval.v_number) {
+ EMSG(error);
+ }
+ }
}
/*
* "screenattr()" function
*/
-static void f_screenattr(typval_T *argvars, typval_T *rettv)
+static void f_screenattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int row;
- int col;
int c;
- row = get_tv_number_chk(&argvars[0], NULL) - 1;
- col = get_tv_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= screen_Rows
- || col < 0 || col >= screen_Columns)
+ const int row = (int)tv_get_number_chk(&argvars[0], NULL) - 1;
+ const int col = (int)tv_get_number_chk(&argvars[1], NULL) - 1;
+ if (row < 0 || row >= default_grid.Rows
+ || col < 0 || col >= default_grid.Columns) {
c = -1;
- else
- c = ScreenAttrs[LineOffset[row] + col];
+ } else {
+ c = default_grid.attrs[default_grid.line_offset[row] + col];
+ }
rettv->vval.v_number = c;
}
/*
* "screenchar()" function
*/
-static void f_screenchar(typval_T *argvars, typval_T *rettv)
+static void f_screenchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int row;
- int col;
int off;
int c;
- row = get_tv_number_chk(&argvars[0], NULL) - 1;
- col = get_tv_number_chk(&argvars[1], NULL) - 1;
- if (row < 0 || row >= screen_Rows
- || col < 0 || col >= screen_Columns)
+ const int row = tv_get_number_chk(&argvars[0], NULL) - 1;
+ const int col = tv_get_number_chk(&argvars[1], NULL) - 1;
+ if (row < 0 || row >= default_grid.Rows
+ || col < 0 || col >= default_grid.Columns) {
c = -1;
- else {
- off = LineOffset[row] + col;
- if (enc_utf8 && ScreenLinesUC[off] != 0)
- c = ScreenLinesUC[off];
- else
- c = ScreenLines[off];
+ } else {
+ off = default_grid.line_offset[row] + col;
+ c = utf_ptr2char(default_grid.chars[off]);
}
rettv->vval.v_number = c;
}
@@ -14118,7 +14077,7 @@ static void f_screenchar(typval_T *argvars, typval_T *rettv)
*
* First column is 1 to be consistent with virtcol().
*/
-static void f_screencol(typval_T *argvars, typval_T *rettv)
+static void f_screencol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ui_current_col() + 1;
}
@@ -14126,7 +14085,7 @@ static void f_screencol(typval_T *argvars, typval_T *rettv)
/*
* "screenrow()" function
*/
-static void f_screenrow(typval_T *argvars, typval_T *rettv)
+static void f_screenrow(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = ui_current_row() + 1;
}
@@ -14134,7 +14093,7 @@ static void f_screenrow(typval_T *argvars, typval_T *rettv)
/*
* "search()" function
*/
-static void f_search(typval_T *argvars, typval_T *rettv)
+static void f_search(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int flags = 0;
@@ -14144,23 +14103,25 @@ static void f_search(typval_T *argvars, typval_T *rettv)
/*
* "searchdecl()" function
*/
-static void f_searchdecl(typval_T *argvars, typval_T *rettv)
+static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int locally = 1;
int thisblock = 0;
- int error = FALSE;
+ bool error = false;
rettv->vval.v_number = 1; /* default: FAIL */
- char_u *name = get_tv_string_chk(&argvars[0]);
+ const char *const name = tv_get_string_chk(&argvars[0]);
if (argvars[1].v_type != VAR_UNKNOWN) {
- locally = get_tv_number_chk(&argvars[1], &error) == 0;
- if (!error && argvars[2].v_type != VAR_UNKNOWN)
- thisblock = get_tv_number_chk(&argvars[2], &error) != 0;
+ locally = tv_get_number_chk(&argvars[1], &error) == 0;
+ if (!error && argvars[2].v_type != VAR_UNKNOWN) {
+ thisblock = tv_get_number_chk(&argvars[2], &error) != 0;
+ }
}
- if (!error && name != NULL)
- rettv->vval.v_number = find_decl(name, STRLEN(name), locally,
+ if (!error && name != NULL) {
+ rettv->vval.v_number = find_decl((char_u *)name, strlen(name), locally,
thisblock, SEARCH_KEEP) == FAIL;
+ }
}
/*
@@ -14168,65 +14129,70 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv)
*/
static int searchpair_cmn(typval_T *argvars, pos_T *match_pos)
{
- char_u *spat, *mpat, *epat;
- char_u *skip;
bool save_p_ws = p_ws;
int dir;
int flags = 0;
- char_u nbuf1[NUMBUFLEN];
- char_u nbuf2[NUMBUFLEN];
- char_u nbuf3[NUMBUFLEN];
- int retval = 0; /* default: FAIL */
+ int retval = 0; // default: FAIL
long lnum_stop = 0;
long time_limit = 0;
- /* Get the three pattern arguments: start, middle, end. */
- spat = get_tv_string_chk(&argvars[0]);
- mpat = get_tv_string_buf_chk(&argvars[1], nbuf1);
- epat = get_tv_string_buf_chk(&argvars[2], nbuf2);
- if (spat == NULL || mpat == NULL || epat == NULL)
- goto theend; /* type error */
+ // Get the three pattern arguments: start, middle, end.
+ char nbuf1[NUMBUFLEN];
+ char nbuf2[NUMBUFLEN];
+ char nbuf3[NUMBUFLEN];
+ const char *spat = tv_get_string_chk(&argvars[0]);
+ const char *mpat = tv_get_string_buf_chk(&argvars[1], nbuf1);
+ const char *epat = tv_get_string_buf_chk(&argvars[2], nbuf2);
+ if (spat == NULL || mpat == NULL || epat == NULL) {
+ goto theend; // Type error.
+ }
- /* Handle the optional fourth argument: flags */
- dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
- if (dir == 0)
+ // Handle the optional fourth argument: flags.
+ dir = get_search_arg(&argvars[3], &flags); // may set p_ws.
+ if (dir == 0) {
goto theend;
+ }
- /* Don't accept SP_END or SP_SUBPAT.
- * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set.
- */
+ // Don't accept SP_END or SP_SUBPAT.
+ // Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set.
if ((flags & (SP_END | SP_SUBPAT)) != 0
|| ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) {
- EMSG2(_(e_invarg2), get_tv_string(&argvars[3]));
+ EMSG2(_(e_invarg2), tv_get_string(&argvars[3]));
goto theend;
}
- /* Using 'r' implies 'W', otherwise it doesn't work. */
- if (flags & SP_REPEAT)
+ // Using 'r' implies 'W', otherwise it doesn't work.
+ if (flags & SP_REPEAT) {
p_ws = false;
+ }
- /* Optional fifth argument: skip expression */
+ // Optional fifth argument: skip expression.
+ const char *skip;
if (argvars[3].v_type == VAR_UNKNOWN
- || argvars[4].v_type == VAR_UNKNOWN)
- skip = (char_u *)"";
- else {
- skip = get_tv_string_buf_chk(&argvars[4], nbuf3);
+ || argvars[4].v_type == VAR_UNKNOWN) {
+ skip = "";
+ } else {
+ skip = tv_get_string_buf_chk(&argvars[4], nbuf3);
+ if (skip == NULL) {
+ goto theend; // Type error.
+ }
if (argvars[5].v_type != VAR_UNKNOWN) {
- lnum_stop = get_tv_number_chk(&argvars[5], NULL);
- if (lnum_stop < 0)
+ lnum_stop = tv_get_number_chk(&argvars[5], NULL);
+ if (lnum_stop < 0) {
goto theend;
+ }
if (argvars[6].v_type != VAR_UNKNOWN) {
- time_limit = get_tv_number_chk(&argvars[6], NULL);
- if (time_limit < 0)
+ time_limit = tv_get_number_chk(&argvars[6], NULL);
+ if (time_limit < 0) {
goto theend;
+ }
}
}
}
- if (skip == NULL)
- goto theend; /* type error */
- retval = do_searchpair(spat, mpat, epat, dir, skip, flags,
- match_pos, lnum_stop, time_limit);
+ retval = do_searchpair(
+ (char_u *)spat, (char_u *)mpat, (char_u *)epat, dir, (char_u *)skip,
+ flags, match_pos, lnum_stop, time_limit);
theend:
p_ws = save_p_ws;
@@ -14237,7 +14203,7 @@ theend:
/*
* "searchpair()" function
*/
-static void f_searchpair(typval_T *argvars, typval_T *rettv)
+static void f_searchpair(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = searchpair_cmn(argvars, NULL);
}
@@ -14245,21 +14211,21 @@ static void f_searchpair(typval_T *argvars, typval_T *rettv)
/*
* "searchpairpos()" function
*/
-static void f_searchpairpos(typval_T *argvars, typval_T *rettv)
+static void f_searchpairpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T match_pos;
int lnum = 0;
int col = 0;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, 2);
if (searchpair_cmn(argvars, &match_pos) > 0) {
lnum = match_pos.lnum;
col = match_pos.col;
}
- list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
- list_append_number(rettv->vval.v_list, (varnumber_T)col);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)col);
}
/*
@@ -14267,17 +14233,17 @@ static void f_searchpairpos(typval_T *argvars, typval_T *rettv)
* Used by searchpair(), see its documentation for the details.
* Returns 0 or -1 for no match,
*/
-long
-do_searchpair (
- char_u *spat, /* start pattern */
- char_u *mpat, /* middle pattern */
- char_u *epat, /* end pattern */
- int dir, /* BACKWARD or FORWARD */
- char_u *skip, /* skip expression */
- int flags, /* SP_SETPCMARK and other SP_ values */
+long
+do_searchpair(
+ char_u *spat, // start pattern
+ char_u *mpat, // middle pattern
+ char_u *epat, // end pattern
+ int dir, // BACKWARD or FORWARD
+ char_u *skip, // skip expression
+ int flags, // SP_SETPCMARK and other SP_ values
pos_T *match_pos,
- linenr_T lnum_stop, /* stop at this line if not zero */
- long time_limit /* stop after this many msec */
+ linenr_T lnum_stop, // stop at this line if not zero
+ long time_limit // stop after this many msec
)
{
char_u *save_cpo;
@@ -14291,9 +14257,10 @@ do_searchpair (
int n;
int r;
int nest = 1;
- int err;
int options = SEARCH_KEEP;
proftime_T tm;
+ size_t pat2_len;
+ size_t pat3_len;
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
save_cpo = p_cpo;
@@ -14302,18 +14269,22 @@ do_searchpair (
/* Set the time limit, if there is one. */
tm = profile_setlimit(time_limit);
- /* Make two search patterns: start/end (pat2, for in nested pairs) and
- * start/middle/end (pat3, for the top pair). */
- pat2 = xmalloc(STRLEN(spat) + STRLEN(epat) + 15);
- pat3 = xmalloc(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23);
- sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
- if (*mpat == NUL)
+ // Make two search patterns: start/end (pat2, for in nested pairs) and
+ // start/middle/end (pat3, for the top pair).
+ pat2_len = STRLEN(spat) + STRLEN(epat) + 17;
+ pat2 = xmalloc(pat2_len);
+ pat3_len = STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 25;
+ pat3 = xmalloc(pat3_len);
+ snprintf((char *)pat2, pat2_len, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
+ if (*mpat == NUL) {
STRCPY(pat3, pat2);
- else
- sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
- spat, epat, mpat);
- if (flags & SP_START)
+ } else {
+ snprintf((char *)pat3, pat3_len,
+ "\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat, mpat);
+ }
+ if (flags & SP_START) {
options |= SEARCH_START;
+ }
save_cursor = curwin->w_cursor;
pos = curwin->w_cursor;
@@ -14347,7 +14318,8 @@ do_searchpair (
if (*skip != NUL) {
save_pos = curwin->w_cursor;
curwin->w_cursor = pos;
- r = eval_to_bool(skip, &err, NULL, FALSE);
+ bool err;
+ r = eval_to_bool(skip, &err, NULL, false);
curwin->w_cursor = save_pos;
if (err) {
/* Evaluating {skip} caused an error, break here. */
@@ -14410,48 +14382,41 @@ do_searchpair (
/*
* "searchpos()" function
*/
-static void f_searchpos(typval_T *argvars, typval_T *rettv)
+static void f_searchpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T match_pos;
- int lnum = 0;
- int col = 0;
- int n;
int flags = 0;
- rettv_list_alloc(rettv);
+ const int n = search_cmn(argvars, &match_pos, &flags);
- n = search_cmn(argvars, &match_pos, &flags);
- if (n > 0) {
- lnum = match_pos.lnum;
- col = match_pos.col;
- }
+ tv_list_alloc_ret(rettv, 2 + (!!(flags & SP_SUBPAT)));
+
+ const int lnum = (n > 0 ? match_pos.lnum : 0);
+ const int col = (n > 0 ? match_pos.col : 0);
- list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
- list_append_number(rettv->vval.v_list, (varnumber_T)col);
- if (flags & SP_SUBPAT)
- list_append_number(rettv->vval.v_list, (varnumber_T)n);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)lnum);
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)col);
+ if (flags & SP_SUBPAT) {
+ tv_list_append_number(rettv->vval.v_list, (varnumber_T)n);
+ }
}
/// "serverlist()" function
-static void f_serverlist(typval_T *argvars, typval_T *rettv)
+static void f_serverlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
size_t n;
char **addrs = server_address_list(&n);
// Copy addrs into a linked list.
- list_T *l = rettv_list_alloc(rettv);
+ list_T *const l = tv_list_alloc_ret(rettv, n);
for (size_t i = 0; i < n; i++) {
- listitem_T *li = listitem_alloc();
- li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = (char_u *) addrs[i];
- list_append(l, li);
+ tv_list_append_allocated_string(l, addrs[i]);
}
xfree(addrs);
}
/// "serverstart()" function
-static void f_serverstart(typval_T *argvars, typval_T *rettv)
+static void f_serverstart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL; // Address of the new server
@@ -14460,91 +14425,113 @@ static void f_serverstart(typval_T *argvars, typval_T *rettv)
return;
}
+ char *address;
// If the user supplied an address, use it, otherwise use a temp.
if (argvars[0].v_type != VAR_UNKNOWN) {
if (argvars[0].v_type != VAR_STRING) {
EMSG(_(e_invarg));
return;
} else {
- rettv->vval.v_string = vim_strsave(get_tv_string(argvars));
+ address = xstrdup(tv_get_string(argvars));
}
} else {
- rettv->vval.v_string = (char_u *)server_address_new();
+ address = server_address_new();
}
- int result = server_start((char *) rettv->vval.v_string);
+ int result = server_start(address);
+ xfree(address);
+
if (result != 0) {
- EMSG2("Failed to start server: %s", uv_strerror(result));
+ EMSG2("Failed to start server: %s",
+ result > 0 ? "Unknown system error" : uv_strerror(result));
+ return;
}
+
+ // Since it's possible server_start adjusted the given {address} (e.g.,
+ // "localhost:" will now have a port), return the final value to the user.
+ size_t n;
+ char **addrs = server_address_list(&n);
+ rettv->vval.v_string = (char_u *)addrs[n - 1];
+
+ n--;
+ for (size_t i = 0; i < n; i++) {
+ xfree(addrs[i]);
+ }
+ xfree(addrs);
}
/// "serverstop()" function
-static void f_serverstop(typval_T *argvars, typval_T *rettv)
+static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
return;
}
- if (argvars[0].v_type == VAR_UNKNOWN || argvars[0].v_type != VAR_STRING) {
+ if (argvars[0].v_type != VAR_STRING) {
EMSG(_(e_invarg));
return;
}
+ rettv->v_type = VAR_NUMBER;
+ rettv->vval.v_number = 0;
if (argvars[0].vval.v_string) {
- server_stop((char *) argvars[0].vval.v_string);
+ bool rv = server_stop((char *)argvars[0].vval.v_string);
+ rettv->vval.v_number = (rv ? 1 : 0);
}
}
/*
* "setbufvar()" function
*/
-static void f_setbufvar(typval_T *argvars, typval_T *rettv)
+static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- buf_T *buf;
- aco_save_T aco;
- char_u *varname, *bufvarname;
- typval_T *varp;
- char_u nbuf[NUMBUFLEN];
-
- if (check_restricted() || check_secure())
+ if (check_restricted()
+ || check_secure()
+ || !tv_check_str_or_nr(&argvars[0])) {
return;
- (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */
- varname = get_tv_string_chk(&argvars[1]);
- buf = get_buf_tv(&argvars[0], FALSE);
- varp = &argvars[2];
-
- if (buf != NULL && varname != NULL && varp != NULL) {
- /* set curbuf to be our buf, temporarily */
- aucmd_prepbuf(&aco, buf);
+ }
+ const char *varname = tv_get_string_chk(&argvars[1]);
+ buf_T *const buf = tv_get_buf(&argvars[0], false);
+ typval_T *varp = &argvars[2];
+ if (buf != NULL && varname != NULL) {
if (*varname == '&') {
long numval;
- char_u *strval;
- int error = FALSE;
+ bool error = false;
+ aco_save_T aco;
- ++varname;
- numval = get_tv_number_chk(varp, &error);
- strval = get_tv_string_buf_chk(varp, nbuf);
- if (!error && strval != NULL)
+ // set curbuf to be our buf, temporarily
+ aucmd_prepbuf(&aco, buf);
+
+ varname++;
+ numval = tv_get_number_chk(varp, &error);
+ char nbuf[NUMBUFLEN];
+ const char *const strval = tv_get_string_buf_chk(varp, nbuf);
+ if (!error && strval != NULL) {
set_option_value(varname, numval, strval, OPT_LOCAL);
+ }
+
+ // reset notion of buffer
+ aucmd_restbuf(&aco);
} else {
- bufvarname = xmalloc(STRLEN(varname) + 3);
- STRCPY(bufvarname, "b:");
- STRCPY(bufvarname + 2, varname);
- set_var(bufvarname, varp, TRUE);
+ buf_T *save_curbuf = curbuf;
+
+ const size_t varname_len = STRLEN(varname);
+ char *const bufvarname = xmalloc(varname_len + 3);
+ curbuf = buf;
+ memcpy(bufvarname, "b:", 2);
+ memcpy(bufvarname + 2, varname, varname_len + 1);
+ set_var(bufvarname, varname_len + 2, varp, true);
xfree(bufvarname);
+ curbuf = save_curbuf;
}
-
- /* reset notion of buffer */
- aucmd_restbuf(&aco);
}
}
-static void f_setcharsearch(typval_T *argvars, typval_T *rettv)
+static void f_setcharsearch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *d;
dictitem_T *di;
- char_u *csearch;
if (argvars[0].v_type != VAR_DICT) {
EMSG(_(e_dictreq));
@@ -14552,7 +14539,7 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv)
}
if ((d = argvars[0].vval.v_dict) != NULL) {
- csearch = get_dict_string(d, (char_u *)"char", FALSE);
+ char_u *const csearch = (char_u *)tv_dict_get_string(d, "char", false);
if (csearch != NULL) {
if (enc_utf8) {
int pcc[MAX_MCO];
@@ -14564,44 +14551,47 @@ static void f_setcharsearch(typval_T *argvars, typval_T *rettv)
csearch, MB_PTR2LEN(csearch));
}
- di = dict_find(d, (char_u *)"forward", -1);
- if (di != NULL)
- set_csearch_direction(get_tv_number(&di->di_tv) ? FORWARD : BACKWARD);
+ di = tv_dict_find(d, S_LEN("forward"));
+ if (di != NULL) {
+ set_csearch_direction(tv_get_number(&di->di_tv) ? FORWARD : BACKWARD);
+ }
- di = dict_find(d, (char_u *)"until", -1);
- if (di != NULL)
- set_csearch_until(!!get_tv_number(&di->di_tv));
+ di = tv_dict_find(d, S_LEN("until"));
+ if (di != NULL) {
+ set_csearch_until(!!tv_get_number(&di->di_tv));
+ }
}
}
/*
* "setcmdpos()" function
*/
-static void f_setcmdpos(typval_T *argvars, typval_T *rettv)
+static void f_setcmdpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int pos = (int)get_tv_number(&argvars[0]) - 1;
+ const int pos = (int)tv_get_number(&argvars[0]) - 1;
- if (pos >= 0)
+ if (pos >= 0) {
rettv->vval.v_number = set_cmdline_pos(pos);
+ }
}
/// "setfperm({fname}, {mode})" function
-static void f_setfperm(typval_T *argvars, typval_T *rettv)
+static void f_setfperm(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = 0;
- char_u *fname = get_tv_string_chk(&argvars[0]);
+ const char *const fname = tv_get_string_chk(&argvars[0]);
if (fname == NULL) {
return;
}
- char_u modebuf[NUMBUFLEN];
- char_u *mode_str = get_tv_string_buf_chk(&argvars[1], modebuf);
+ char modebuf[NUMBUFLEN];
+ const char *const mode_str = tv_get_string_buf_chk(&argvars[1], modebuf);
if (mode_str == NULL) {
return;
}
- if (STRLEN(mode_str) != 9) {
+ if (strlen(mode_str) != 9) {
EMSG2(_(e_invarg2), mode_str);
return;
}
@@ -14620,35 +14610,37 @@ static void f_setfperm(typval_T *argvars, typval_T *rettv)
/*
* "setline()" function
*/
-static void f_setline(typval_T *argvars, typval_T *rettv)
+static void f_setline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- linenr_T lnum;
- char_u *line = NULL;
list_T *l = NULL;
listitem_T *li = NULL;
long added = 0;
linenr_T lcount = curbuf->b_ml.ml_line_count;
- lnum = get_tv_lnum(&argvars[0]);
+ linenr_T lnum = tv_get_lnum(&argvars[0]);
+ const char *line = NULL;
if (argvars[1].v_type == VAR_LIST) {
l = argvars[1].vval.v_list;
- li = l->lv_first;
- } else
- line = get_tv_string_chk(&argvars[1]);
+ li = tv_list_first(l);
+ } else {
+ line = tv_get_string_chk(&argvars[1]);
+ }
- /* default result is zero == OK */
+ // Default result is zero == OK.
for (;; ) {
- if (l != NULL) {
- /* list argument, get next string */
- if (li == NULL)
+ if (argvars[1].v_type == VAR_LIST) {
+ // List argument, get next string.
+ if (li == NULL) {
break;
- line = get_tv_string_chk(&li->li_tv);
- li = li->li_next;
+ }
+ line = tv_get_string_chk(TV_LIST_ITEM_TV(li));
+ li = TV_LIST_ITEM_NEXT(l, li);
}
- rettv->vval.v_number = 1; /* FAIL */
- if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
+ rettv->vval.v_number = 1; // FAIL
+ if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) {
break;
+ }
/* When coming here from Insert mode, sync undo, so that this can be
* undone separately from what was previously inserted. */
@@ -14658,18 +14650,20 @@ static void f_setline(typval_T *argvars, typval_T *rettv)
}
if (lnum <= curbuf->b_ml.ml_line_count) {
- /* existing line, replace it */
- if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) {
+ // Existing line, replace it.
+ if (u_savesub(lnum) == OK
+ && ml_replace(lnum, (char_u *)line, true) == OK) {
changed_bytes(lnum, 0);
if (lnum == curwin->w_cursor.lnum)
check_cursor_col();
rettv->vval.v_number = 0; /* OK */
}
} else if (added > 0 || u_save(lnum - 1, lnum) == OK) {
- /* lnum is one past the last line, append the line */
- ++added;
- if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK)
- rettv->vval.v_number = 0; /* OK */
+ // lnum is one past the last line, append the line.
+ added++;
+ if (ml_append(lnum - 1, (char_u *)line, 0, false) == OK) {
+ rettv->vval.v_number = 0; // OK
+ }
}
if (l == NULL) /* only one string argument */
@@ -14684,7 +14678,7 @@ static void f_setline(typval_T *argvars, typval_T *rettv)
/// Create quickfix/location list from VimL values
///
/// Used by `setqflist()` and `setloclist()` functions. Accepts invalid
-/// list_arg, action_arg and title_arg arguments in which case errors out,
+/// list_arg, action_arg and what_arg arguments in which case errors out,
/// including VAR_UNKNOWN parameters.
///
/// @param[in,out] wp Window to create location list for. May be NULL in
@@ -14697,14 +14691,20 @@ static void f_setline(typval_T *argvars, typval_T *rettv)
static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(2, 3)
{
- char_u *title = NULL;
+ static char *e_invact = N_("E927: Invalid action: '%s'");
+ const char *title = NULL;
int action = ' ';
+ static int recursive = 0;
rettv->vval.v_number = -1;
+ dict_T *d = NULL;
typval_T *list_arg = &args[0];
if (list_arg->v_type != VAR_LIST) {
EMSG(_(e_listreq));
return;
+ } else if (recursive != 0) {
+ EMSG(_(e_au_recursive));
+ return;
}
typval_T *action_arg = &args[1];
@@ -14712,40 +14712,52 @@ static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv)
// Option argument was not given.
goto skip_args;
} else if (action_arg->v_type != VAR_STRING) {
- EMSG(_(e_strreq));
+ EMSG(_(e_stringreq));
return;
}
- char_u *act = get_tv_string_chk(action_arg);
- if (*act == 'a' || *act == 'r') {
+ const char *const act = tv_get_string_chk(action_arg);
+ if ((*act == 'a' || *act == 'r' || *act == ' ' || *act == 'f')
+ && act[1] == NUL) {
action = *act;
+ } else {
+ EMSG2(_(e_invact), act);
+ return;
}
typval_T *title_arg = &args[2];
if (title_arg->v_type == VAR_UNKNOWN) {
// Option argument was not given.
goto skip_args;
- }
- title = get_tv_string_chk(title_arg);
- if (!title) {
- // Type error. Error already printed by get_tv_string_chk().
+ } else if (title_arg->v_type == VAR_STRING) {
+ title = tv_get_string_chk(title_arg);
+ if (!title) {
+ // Type error. Error already printed by tv_get_string_chk().
+ return;
+ }
+ } else if (title_arg->v_type == VAR_DICT) {
+ d = title_arg->vval.v_dict;
+ } else {
+ EMSG(_(e_dictreq));
return;
}
skip_args:
if (!title) {
- title = (char_u*)(wp ? "setloclist()" : "setqflist()");
+ title = (wp ? "setloclist()" : "setqflist()");
}
- list_T *l = list_arg->vval.v_list;
- if (l && set_errorlist(wp, l, action, title) == OK) {
+ recursive++;
+ list_T *const l = list_arg->vval.v_list;
+ if (set_errorlist(wp, l, action, (char_u *)title, d) == OK) {
rettv->vval.v_number = 0;
}
+ recursive--;
}
/*
* "setloclist()" function
*/
-static void f_setloclist(typval_T *argvars, typval_T *rettv)
+static void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *win;
@@ -14760,10 +14772,8 @@ static void f_setloclist(typval_T *argvars, typval_T *rettv)
/*
* "setmatches()" function
*/
-static void f_setmatches(typval_T *argvars, typval_T *rettv)
+static void f_setmatches(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- list_T *l;
- listitem_T *li;
dict_T *d;
list_T *s = NULL;
@@ -14772,78 +14782,89 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv)
EMSG(_(e_listreq));
return;
}
- if ((l = argvars[0].vval.v_list) != NULL) {
-
- /* To some extent make sure that we are dealing with a list from
- * "getmatches()". */
- li = l->lv_first;
- while (li != NULL) {
- if (li->li_tv.v_type != VAR_DICT
- || (d = li->li_tv.vval.v_dict) == NULL) {
- EMSG(_(e_invarg));
- return;
- }
- if (!(dict_find(d, (char_u *)"group", -1) != NULL
- && (dict_find(d, (char_u *)"pattern", -1) != NULL
- || dict_find(d, (char_u *)"pos1", -1) != NULL)
- && dict_find(d, (char_u *)"priority", -1) != NULL
- && dict_find(d, (char_u *)"id", -1) != NULL)) {
- EMSG(_(e_invarg));
- return;
- }
- li = li->li_next;
+ list_T *const l = argvars[0].vval.v_list;
+ // To some extent make sure that we are dealing with a list from
+ // "getmatches()".
+ int li_idx = 0;
+ TV_LIST_ITER_CONST(l, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type != VAR_DICT
+ || (d = TV_LIST_ITEM_TV(li)->vval.v_dict) == NULL) {
+ emsgf(_("E474: List item %d is either not a dictionary "
+ "or an empty one"), li_idx);
+ return;
+ }
+ if (!(tv_dict_find(d, S_LEN("group")) != NULL
+ && (tv_dict_find(d, S_LEN("pattern")) != NULL
+ || tv_dict_find(d, S_LEN("pos1")) != NULL)
+ && tv_dict_find(d, S_LEN("priority")) != NULL
+ && tv_dict_find(d, S_LEN("id")) != NULL)) {
+ emsgf(_("E474: List item %d is missing one of the required keys"),
+ li_idx);
+ return;
}
+ li_idx++;
+ });
- clear_matches(curwin);
- li = l->lv_first;
- while (li != NULL) {
- int i = 0;
- char_u buf[5];
- dictitem_T *di;
+ clear_matches(curwin);
+ bool match_add_failed = false;
+ TV_LIST_ITER_CONST(l, li, {
+ int i = 0;
+
+ d = TV_LIST_ITEM_TV(li)->vval.v_dict;
+ dictitem_T *const di = tv_dict_find(d, S_LEN("pattern"));
+ if (di == NULL) {
+ if (s == NULL) {
+ s = tv_list_alloc(9);
+ }
- d = li->li_tv.vval.v_dict;
- if (dict_find(d, (char_u *)"pattern", -1) == NULL) {
- if (s == NULL) {
- s = list_alloc();
- if (s == NULL) {
+ // match from matchaddpos()
+ for (i = 1; i < 9; i++) {
+ char buf[5];
+ snprintf(buf, sizeof(buf), "pos%d", i);
+ dictitem_T *const pos_di = tv_dict_find(d, buf, -1);
+ if (pos_di != NULL) {
+ if (pos_di->di_tv.v_type != VAR_LIST) {
return;
}
- }
-
- // match from matchaddpos()
- for (i = 1; i < 9; ++i) {
- snprintf((char *)buf, sizeof(buf), (char *)"pos%d", i);
- if ((di = dict_find(d, (char_u *)buf, -1)) != NULL) {
- if (di->di_tv.v_type != VAR_LIST) {
- return;
- }
- list_append_tv(s, &di->di_tv);
- s->lv_refcount++;
- } else {
- break;
- }
+ tv_list_append_tv(s, &pos_di->di_tv);
+ tv_list_ref(s);
+ } else {
+ break;
}
}
+ }
- char_u *group = get_dict_string(d, (char_u *)"group", false);
- int priority = get_dict_number(d, (char_u *)"priority");
- int id = get_dict_number(d, (char_u *)"id");
- char_u *conceal = dict_find(d, (char_u *)"conceal", -1) != NULL
- ? get_dict_string(d, (char_u *)"conceal",
- false)
- : NULL;
- if (i == 0) {
- match_add(curwin, group,
- get_dict_string(d, (char_u *)"pattern", false),
- priority, id, NULL, conceal);
- } else {
- match_add(curwin, group, NULL, priority, id, s, conceal);
- list_unref(s);
- s = NULL;
+ // Note: there are three number buffers involved:
+ // - group_buf below.
+ // - numbuf in tv_dict_get_string().
+ // - mybuf in tv_get_string().
+ //
+ // If you change this code make sure that buffers will not get
+ // accidentally reused.
+ char group_buf[NUMBUFLEN];
+ const char *const group = tv_dict_get_string_buf(d, "group", group_buf);
+ const int priority = (int)tv_dict_get_number(d, "priority");
+ const int id = (int)tv_dict_get_number(d, "id");
+ dictitem_T *const conceal_di = tv_dict_find(d, S_LEN("conceal"));
+ const char *const conceal = (conceal_di != NULL
+ ? tv_get_string(&conceal_di->di_tv)
+ : NULL);
+ if (i == 0) {
+ if (match_add(curwin, group,
+ tv_dict_get_string(d, "pattern", false),
+ priority, id, NULL, conceal) != id) {
+ match_add_failed = true;
+ }
+ } else {
+ if (match_add(curwin, group, NULL, priority, id, s, conceal) != id) {
+ match_add_failed = true;
}
- li = li->li_next;
+ tv_list_unref(s);
+ s = NULL;
}
+ });
+ if (!match_add_failed) {
rettv->vval.v_number = 0;
}
}
@@ -14851,36 +14872,31 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv)
/*
* "setpos()" function
*/
-static void f_setpos(typval_T *argvars, typval_T *rettv)
+static void f_setpos(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
pos_T pos;
int fnum;
- char_u *name;
colnr_T curswant = -1;
rettv->vval.v_number = -1;
- name = get_tv_string_chk(argvars);
+ const char *const name = tv_get_string_chk(argvars);
if (name != NULL) {
if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK) {
if (--pos.col < 0) {
pos.col = 0;
}
if (name[0] == '.' && name[1] == NUL) {
- // set cursor
- if (fnum == curbuf->b_fnum) {
- curwin->w_cursor = pos;
- if (curswant >= 0) {
- curwin->w_curswant = curswant - 1;
- curwin->w_set_curswant = false;
- }
- check_cursor();
- rettv->vval.v_number = 0;
- } else {
- EMSG(_(e_invarg));
+ // set cursor; "fnum" is ignored
+ curwin->w_cursor = pos;
+ if (curswant >= 0) {
+ curwin->w_curswant = curswant - 1;
+ curwin->w_set_curswant = false;
}
+ check_cursor();
+ rettv->vval.v_number = 0;
} else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL) {
// set mark
- if (setmark_pos(name[1], &pos, fnum) == OK) {
+ if (setmark_pos((uint8_t)name[1], &pos, fnum) == OK) {
rettv->vval.v_number = 0;
}
} else {
@@ -14893,7 +14909,7 @@ static void f_setpos(typval_T *argvars, typval_T *rettv)
/*
* "setqflist()" function
*/
-static void f_setqflist(typval_T *argvars, typval_T *rettv)
+static void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
set_qf_ll_list(NULL, argvars, rettv);
}
@@ -14901,11 +14917,9 @@ static void f_setqflist(typval_T *argvars, typval_T *rettv)
/*
* "setreg()" function
*/
-static void f_setreg(typval_T *argvars, typval_T *rettv)
+static void f_setreg(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int regname;
- char_u *strregname;
- char_u *stropt;
bool append = false;
MotionType yank_type;
long block_len;
@@ -14913,127 +14927,144 @@ static void f_setreg(typval_T *argvars, typval_T *rettv)
block_len = -1;
yank_type = kMTUnknown;
- strregname = get_tv_string_chk(argvars);
- rettv->vval.v_number = 1; /* FAIL is default */
+ rettv->vval.v_number = 1; // FAIL is default.
- if (strregname == NULL)
- return; /* type error; errmsg already given */
- regname = *strregname;
- if (regname == 0 || regname == '@')
+ const char *const strregname = tv_get_string_chk(argvars);
+ if (strregname == NULL) {
+ return; // Type error; errmsg already given.
+ }
+ regname = (uint8_t)(*strregname);
+ if (regname == 0 || regname == '@') {
regname = '"';
+ }
+ bool set_unnamed = false;
if (argvars[2].v_type != VAR_UNKNOWN) {
- stropt = get_tv_string_chk(&argvars[2]);
- if (stropt == NULL)
- return; /* type error */
- for (; *stropt != NUL; ++stropt)
+ const char *stropt = tv_get_string_chk(&argvars[2]);
+ if (stropt == NULL) {
+ return; // Type error.
+ }
+ for (; *stropt != NUL; stropt++) {
switch (*stropt) {
- case 'a': case 'A': // append
- append = true;
- break;
- case 'v': case 'c': // character-wise selection
- yank_type = kMTCharWise;
- break;
- case 'V': case 'l': // line-wise selection
- yank_type = kMTLineWise;
- break;
- case 'b': case Ctrl_V: // block-wise selection
- yank_type = kMTBlockWise;
- if (ascii_isdigit(stropt[1])) {
- ++stropt;
- block_len = getdigits_long(&stropt) - 1;
- --stropt;
+ case 'a': case 'A': { // append
+ append = true;
+ break;
+ }
+ case 'v': case 'c': { // character-wise selection
+ yank_type = kMTCharWise;
+ break;
+ }
+ case 'V': case 'l': { // line-wise selection
+ yank_type = kMTLineWise;
+ break;
+ }
+ case 'b': case Ctrl_V: { // block-wise selection
+ yank_type = kMTBlockWise;
+ if (ascii_isdigit(stropt[1])) {
+ stropt++;
+ block_len = getdigits_long((char_u **)&stropt) - 1;
+ stropt--;
+ }
+ break;
+ }
+ case 'u': case '"': { // unnamed register
+ set_unnamed = true;
+ break;
}
- break;
}
+ }
}
if (argvars[1].v_type == VAR_LIST) {
- int len = argvars[1].vval.v_list->lv_len;
+ list_T *ll = argvars[1].vval.v_list;
+ // If the list is NULL handle like an empty list.
+ const int len = tv_list_len(ll);
+
// First half: use for pointers to result lines; second half: use for
// pointers to allocated copies.
- char_u **lstval = xmalloc(sizeof(char_u *) * ((len + 1) * 2));
- char_u **curval = lstval;
- char_u **allocval = lstval + len + 2;
- char_u **curallocval = allocval;
-
- char_u buf[NUMBUFLEN];
- for (listitem_T *li = argvars[1].vval.v_list->lv_first;
- li != NULL;
- li = li->li_next) {
- char_u *strval = get_tv_string_buf_chk(&li->li_tv, buf);
- if (strval == NULL) {
+ char **lstval = xmalloc(sizeof(char *) * ((len + 1) * 2));
+ const char **curval = (const char **)lstval;
+ char **allocval = lstval + len + 2;
+ char **curallocval = allocval;
+
+ TV_LIST_ITER_CONST(ll, li, {
+ char buf[NUMBUFLEN];
+ *curval = tv_get_string_buf_chk(TV_LIST_ITEM_TV(li), buf);
+ if (*curval == NULL) {
goto free_lstval;
}
- if (strval == buf) {
+ if (*curval == buf) {
// Need to make a copy,
- // next get_tv_string_buf_chk() will overwrite the string.
- strval = vim_strsave(buf);
- *curallocval++ = strval;
+ // next tv_get_string_buf_chk() will overwrite the string.
+ *curallocval = xstrdup(*curval);
+ *curval = *curallocval;
+ curallocval++;
}
- *curval++ = strval;
- }
+ curval++;
+ });
*curval++ = NULL;
- write_reg_contents_lst(regname, lstval, STRLEN(lstval),
- append, yank_type, block_len);
+ write_reg_contents_lst(regname, (char_u **)lstval, append, yank_type,
+ block_len);
free_lstval:
- while (curallocval > allocval)
- xfree(*--curallocval);
+ while (curallocval > allocval) {
+ xfree(*--curallocval);
+ }
xfree(lstval);
} else {
- char_u *strval = get_tv_string_chk(&argvars[1]);
+ const char *strval = tv_get_string_chk(&argvars[1]);
if (strval == NULL) {
return;
}
- write_reg_contents_ex(regname, strval, STRLEN(strval),
+ write_reg_contents_ex(regname, (const char_u *)strval, STRLEN(strval),
append, yank_type, block_len);
}
rettv->vval.v_number = 0;
+
+ if (set_unnamed) {
+ // Discard the result. We already handle the error case.
+ if (op_register_set_previous(regname)) { }
+ }
}
/*
* "settabvar()" function
*/
-static void f_settabvar(typval_T *argvars, typval_T *rettv)
+static void f_settabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- tabpage_T *save_curtab;
- tabpage_T *tp;
- char_u *varname, *tabvarname;
- typval_T *varp;
-
rettv->vval.v_number = 0;
- if (check_restricted() || check_secure())
+ if (check_restricted() || check_secure()) {
return;
+ }
- tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
- varname = get_tv_string_chk(&argvars[1]);
- varp = &argvars[2];
+ tabpage_T *const tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+ const char *const varname = tv_get_string_chk(&argvars[1]);
+ typval_T *const varp = &argvars[2];
- if (varname != NULL && varp != NULL
- && tp != NULL
- ) {
- save_curtab = curtab;
- goto_tabpage_tp(tp, FALSE, FALSE);
+ if (varname != NULL && tp != NULL) {
+ tabpage_T *const save_curtab = curtab;
+ goto_tabpage_tp(tp, false, false);
- tabvarname = xmalloc(STRLEN(varname) + 3);
- STRCPY(tabvarname, "t:");
- STRCPY(tabvarname + 2, varname);
- set_var(tabvarname, varp, TRUE);
+ const size_t varname_len = strlen(varname);
+ char *const tabvarname = xmalloc(varname_len + 3);
+ memcpy(tabvarname, "t:", 2);
+ memcpy(tabvarname + 2, varname, varname_len + 1);
+ set_var(tabvarname, varname_len + 2, varp, true);
xfree(tabvarname);
- /* Restore current tabpage */
- if (valid_tabpage(save_curtab))
- goto_tabpage_tp(save_curtab, FALSE, FALSE);
+ // Restore current tabpage.
+ if (valid_tabpage(save_curtab)) {
+ goto_tabpage_tp(save_curtab, false, false);
+ }
}
}
/*
* "settabwinvar()" function
*/
-static void f_settabwinvar(typval_T *argvars, typval_T *rettv)
+static void f_settabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
setwinvar(argvars, rettv, 1);
}
@@ -15041,7 +15072,7 @@ static void f_settabwinvar(typval_T *argvars, typval_T *rettv)
/*
* "setwinvar()" function
*/
-static void f_setwinvar(typval_T *argvars, typval_T *rettv)
+static void f_setwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
setwinvar(argvars, rettv, 0);
}
@@ -15052,45 +15083,43 @@ static void f_setwinvar(typval_T *argvars, typval_T *rettv)
static void setwinvar(typval_T *argvars, typval_T *rettv, int off)
{
- win_T *win;
- win_T *save_curwin;
- tabpage_T *save_curtab;
- char_u *varname, *winvarname;
- typval_T *varp;
- char_u nbuf[NUMBUFLEN];
- tabpage_T *tp = NULL;
-
- if (check_restricted() || check_secure())
+ if (check_restricted() || check_secure()) {
return;
+ }
- if (off == 1)
- tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
- else
+ tabpage_T *tp = NULL;
+ if (off == 1) {
+ tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
+ } else {
tp = curtab;
- win = find_win_by_nr(&argvars[off], tp);
- varname = get_tv_string_chk(&argvars[off + 1]);
- varp = &argvars[off + 2];
+ }
+ win_T *const win = find_win_by_nr(&argvars[off], tp);
+ const char *varname = tv_get_string_chk(&argvars[off + 1]);
+ typval_T *varp = &argvars[off + 2];
if (win != NULL && varname != NULL && varp != NULL) {
+ win_T *save_curwin;
+ tabpage_T *save_curtab;
bool need_switch_win = tp != curtab || win != curwin;
if (!need_switch_win
|| switch_win(&save_curwin, &save_curtab, win, tp, true) == OK) {
if (*varname == '&') {
long numval;
- char_u *strval;
- int error = false;
+ bool error = false;
- ++varname;
- numval = get_tv_number_chk(varp, &error);
- strval = get_tv_string_buf_chk(varp, nbuf);
+ varname++;
+ numval = tv_get_number_chk(varp, &error);
+ char nbuf[NUMBUFLEN];
+ const char *const strval = tv_get_string_buf_chk(varp, nbuf);
if (!error && strval != NULL) {
set_option_value(varname, numval, strval, OPT_LOCAL);
}
} else {
- winvarname = xmalloc(STRLEN(varname) + 3);
- STRCPY(winvarname, "w:");
- STRCPY(winvarname + 2, varname);
- set_var(winvarname, varp, true);
+ const size_t varname_len = strlen(varname);
+ char *const winvarname = xmalloc(varname_len + 3);
+ memcpy(winvarname, "w:", 2);
+ memcpy(winvarname + 2, varname, varname_len + 1);
+ set_var(winvarname, varname_len + 2, varp, true);
xfree(winvarname);
}
}
@@ -15101,30 +15130,32 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off)
}
/// f_sha256 - sha256({string}) function
-static void f_sha256(typval_T *argvars, typval_T *rettv)
+static void f_sha256(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = get_tv_string(&argvars[0]);
- const char_u *hash = sha256_bytes(p, (int) STRLEN(p) , NULL, 0);
+ const char *p = tv_get_string(&argvars[0]);
+ const char *hash = sha256_bytes((const uint8_t *)p, strlen(p) , NULL, 0);
// make a copy of the hash (sha256_bytes returns a static buffer)
- rettv->vval.v_string = (char_u *) xstrdup((char *) hash);
+ rettv->vval.v_string = (char_u *)xstrdup(hash);
rettv->v_type = VAR_STRING;
}
/*
* "shellescape({string})" function
*/
-static void f_shellescape(typval_T *argvars, typval_T *rettv)
+static void f_shellescape(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
+ const bool do_special = non_zero_arg(&argvars[1]);
+
rettv->vval.v_string = vim_strsave_shellescape(
- get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), true);
+ (const char_u *)tv_get_string(&argvars[0]), do_special, do_special);
rettv->v_type = VAR_STRING;
}
/*
* shiftwidth() function
*/
-static void f_shiftwidth(typval_T *argvars, typval_T *rettv)
+static void f_shiftwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->vval.v_number = get_sw_value(curbuf);
}
@@ -15132,37 +15163,65 @@ static void f_shiftwidth(typval_T *argvars, typval_T *rettv)
/*
* "simplify()" function
*/
-static void f_simplify(typval_T *argvars, typval_T *rettv)
+static void f_simplify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
-
- p = get_tv_string(&argvars[0]);
- rettv->vval.v_string = vim_strsave(p);
- simplify_filename(rettv->vval.v_string); /* simplify in place */
+ const char *const p = tv_get_string(&argvars[0]);
+ rettv->vval.v_string = (char_u *)xstrdup(p);
+ simplify_filename(rettv->vval.v_string); // Simplify in place.
rettv->v_type = VAR_STRING;
}
-/*
- * "sin()" function
- */
-static void f_sin(typval_T *argvars, typval_T *rettv)
+/// "sockconnect()" function
+static void f_sockconnect(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_op_wrapper(argvars, rettv, &sin);
-}
+ if (argvars[0].v_type != VAR_STRING || argvars[1].v_type != VAR_STRING) {
+ EMSG(_(e_invarg));
+ return;
+ }
+ if (argvars[2].v_type != VAR_DICT && argvars[2].v_type != VAR_UNKNOWN) {
+ // Wrong argument types
+ EMSG2(_(e_invarg2), "expected dictionary");
+ return;
+ }
-/*
- * "sinh()" function
- */
-static void f_sinh(typval_T *argvars, typval_T *rettv)
-{
- float_op_wrapper(argvars, rettv, &sinh);
-}
+ const char *mode = tv_get_string(&argvars[0]);
+ const char *address = tv_get_string(&argvars[1]);
-/// struct used in the array that's given to qsort()
-typedef struct {
- listitem_T *item;
- int idx;
-} sortItem_T;
+ bool tcp;
+ if (strcmp(mode, "tcp") == 0) {
+ tcp = true;
+ } else if (strcmp(mode, "pipe") == 0) {
+ tcp = false;
+ } else {
+ EMSG2(_(e_invarg2), "invalid mode");
+ return;
+ }
+
+ bool rpc = false;
+ CallbackReader on_data = CALLBACK_READER_INIT;
+ if (argvars[2].v_type == VAR_DICT) {
+ dict_T *opts = argvars[2].vval.v_dict;
+ rpc = tv_dict_get_number(opts, "rpc") != 0;
+
+ if (!tv_dict_get_callback(opts, S_LEN("on_data"), &on_data.cb)) {
+ return;
+ }
+ on_data.buffered = tv_dict_get_number(opts, "data_buffered");
+ if (on_data.buffered && on_data.cb.type == kCallbackNone) {
+ on_data.self = opts;
+ }
+ }
+
+ const char *error = NULL;
+ uint64_t id = channel_connect(tcp, address, rpc, on_data, 50, &error);
+
+ if (error) {
+ EMSG2(_("connection failed: %s"), error);
+ }
+
+ rettv->vval.v_number = (varnumber_T)id;
+ rettv->v_type = VAR_NUMBER;
+}
/// struct storing information about current sort
typedef struct {
@@ -15170,9 +15229,10 @@ typedef struct {
bool item_compare_numeric;
bool item_compare_numbers;
bool item_compare_float;
- char_u *item_compare_func;
+ const char *item_compare_func;
+ partial_T *item_compare_partial;
dict_T *item_compare_selfdict;
- int item_compare_func_err;
+ bool item_compare_func_err;
} sortinfo_T;
static sortinfo_T *sortinfo = NULL;
@@ -15183,58 +15243,61 @@ static sortinfo_T *sortinfo = NULL;
*/
static int item_compare(const void *s1, const void *s2, bool keep_zero)
{
- sortItem_T *si1, *si2;
- char_u *p1;
- char_u *p2;
- char_u *tofree1 = NULL;
- char_u *tofree2 = NULL;
- int res;
+ ListSortItem *const si1 = (ListSortItem *)s1;
+ ListSortItem *const si2 = (ListSortItem *)s2;
- si1 = (sortItem_T *)s1;
- si2 = (sortItem_T *)s2;
- typval_T *tv1 = &si1->item->li_tv;
- typval_T *tv2 = &si2->item->li_tv;
+ typval_T *const tv1 = TV_LIST_ITEM_TV(si1->item);
+ typval_T *const tv2 = TV_LIST_ITEM_TV(si2->item);
+
+ int res;
if (sortinfo->item_compare_numbers) {
- long v1 = get_tv_number(tv1);
- long v2 = get_tv_number(tv2);
+ const varnumber_T v1 = tv_get_number(tv1);
+ const varnumber_T v2 = tv_get_number(tv2);
- return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+ res = v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+ goto item_compare_end;
}
if (sortinfo->item_compare_float) {
- float_T v1 = get_tv_float(tv1);
- float_T v2 = get_tv_float(tv2);
+ const float_T v1 = tv_get_float(tv1);
+ const float_T v2 = tv_get_float(tv2);
- return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+ res = v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
+ goto item_compare_end;
}
+ char *tofree1 = NULL;
+ char *tofree2 = NULL;
+ char *p1;
+ char *p2;
+
// encode_tv2string() puts quotes around a string and allocates memory. Don't
// do that for string variables. Use a single quote when comparing with
// a non-string to do what the docs promise.
if (tv1->v_type == VAR_STRING) {
if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric) {
- p1 = (char_u *)"'";
+ p1 = "'";
} else {
- p1 = tv1->vval.v_string;
+ p1 = (char *)tv1->vval.v_string;
}
} else {
- tofree1 = p1 = (char_u *) encode_tv2string(tv1, NULL);
+ tofree1 = p1 = encode_tv2string(tv1, NULL);
}
if (tv2->v_type == VAR_STRING) {
if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric) {
- p2 = (char_u *)"'";
+ p2 = "'";
} else {
- p2 = tv2->vval.v_string;
+ p2 = (char *)tv2->vval.v_string;
}
} else {
- tofree2 = p2 = (char_u *) encode_tv2string(tv2, NULL);
+ tofree2 = p2 = encode_tv2string(tv2, NULL);
}
if (p1 == NULL) {
- p1 = (char_u *)"";
+ p1 = "";
}
if (p2 == NULL) {
- p2 = (char_u *)"";
+ p2 = "";
}
if (!sortinfo->item_compare_numeric) {
if (sortinfo->item_compare_ic) {
@@ -15244,19 +15307,22 @@ static int item_compare(const void *s1, const void *s2, bool keep_zero)
}
} else {
double n1, n2;
- n1 = strtod((char *)p1, (char **)&p1);
- n2 = strtod((char *)p2, (char **)&p2);
+ n1 = strtod(p1, &p1);
+ n2 = strtod(p2, &p2);
res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
}
+ xfree(tofree1);
+ xfree(tofree2);
+
+item_compare_end:
// When the result would be zero, compare the item indexes. Makes the
// sort stable.
if (res == 0 && !keep_zero) {
+ // WARNING: When using uniq si1 and si2 are actually listitem_T **, no
+ // indexes are there.
res = si1->idx > si2->idx ? 1 : -1;
}
-
- xfree(tofree1);
- xfree(tofree2);
return res;
}
@@ -15272,46 +15338,56 @@ static int item_compare_not_keeping_zero(const void *s1, const void *s2)
static int item_compare2(const void *s1, const void *s2, bool keep_zero)
{
- sortItem_T *si1, *si2;
+ ListSortItem *si1, *si2;
int res;
typval_T rettv;
typval_T argv[3];
int dummy;
+ const char *func_name;
+ partial_T *partial = sortinfo->item_compare_partial;
// shortcut after failure in previous call; compare all items equal
if (sortinfo->item_compare_func_err) {
return 0;
}
- si1 = (sortItem_T *)s1;
- si2 = (sortItem_T *)s2;
+ si1 = (ListSortItem *)s1;
+ si2 = (ListSortItem *)s2;
+
+ if (partial == NULL) {
+ func_name = sortinfo->item_compare_func;
+ } else {
+ func_name = (const char *)partial_name(partial);
+ }
// Copy the values. This is needed to be able to set v_lock to VAR_FIXED
// in the copy without changing the original list items.
- copy_tv(&si1->item->li_tv, &argv[0]);
- copy_tv(&si2->item->li_tv, &argv[1]);
+ tv_copy(TV_LIST_ITEM_TV(si1->item), &argv[0]);
+ tv_copy(TV_LIST_ITEM_TV(si2->item), &argv[1]);
- rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
- res = call_func(sortinfo->item_compare_func,
- (int)STRLEN(sortinfo->item_compare_func),
- &rettv, 2, argv, 0L, 0L, &dummy, true,
- sortinfo->item_compare_selfdict);
- clear_tv(&argv[0]);
- clear_tv(&argv[1]);
+ rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this
+ res = call_func((const char_u *)func_name,
+ (int)STRLEN(func_name),
+ &rettv, 2, argv, NULL, 0L, 0L, &dummy, true,
+ partial, sortinfo->item_compare_selfdict);
+ tv_clear(&argv[0]);
+ tv_clear(&argv[1]);
if (res == FAIL) {
res = ITEM_COMPARE_FAIL;
} else {
- res = get_tv_number_chk(&rettv, &sortinfo->item_compare_func_err);
+ res = tv_get_number_chk(&rettv, &sortinfo->item_compare_func_err);
}
if (sortinfo->item_compare_func_err) {
res = ITEM_COMPARE_FAIL; // return value has wrong type
}
- clear_tv(&rettv);
+ tv_clear(&rettv);
// When the result would be zero, compare the pointers themselves. Makes
// the sort stable.
if (res == 0 && !keep_zero) {
+ // WARNING: When using uniq si1 and si2 are actually listitem_T **, no
+ // indexes are there.
res = si1->idx > si2->idx ? 1 : -1;
}
@@ -15333,9 +15409,7 @@ static int item_compare2_not_keeping_zero(const void *s1, const void *s2)
*/
static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
{
- list_T *l;
- listitem_T *li;
- sortItem_T *ptrs;
+ ListSortItem *ptrs;
long len;
long i;
@@ -15345,23 +15419,20 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
sortinfo_T *old_sortinfo = sortinfo;
sortinfo = &info;
+ const char *const arg_errmsg = (sort
+ ? N_("sort() argument")
+ : N_("uniq() argument"));
+
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
} else {
- l = argvars[0].vval.v_list;
- if (l == NULL
- || tv_check_lock(l->lv_lock,
- (char_u *)(sort
- ? N_("sort() argument")
- : N_("uniq() argument")),
- true)) {
- goto theend;
+ list_T *const l = argvars[0].vval.v_list;
+ if (tv_check_lock(tv_list_locked(l), arg_errmsg, TV_TRANSLATE)) {
+ goto theend;
}
- rettv->vval.v_list = l;
- rettv->v_type = VAR_LIST;
- ++l->lv_refcount;
+ tv_list_set_ret(rettv, l);
- len = list_len(l);
+ len = tv_list_len(l);
if (len <= 1) {
goto theend; // short list sorts pretty quickly
}
@@ -15371,23 +15442,26 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
info.item_compare_numbers = false;
info.item_compare_float = false;
info.item_compare_func = NULL;
+ info.item_compare_partial = NULL;
info.item_compare_selfdict = NULL;
if (argvars[1].v_type != VAR_UNKNOWN) {
/* optional second argument: {func} */
if (argvars[1].v_type == VAR_FUNC) {
- info.item_compare_func = argvars[1].vval.v_string;
+ info.item_compare_func = (const char *)argvars[1].vval.v_string;
+ } else if (argvars[1].v_type == VAR_PARTIAL) {
+ info.item_compare_partial = argvars[1].vval.v_partial;
} else {
- int error = FALSE;
+ bool error = false;
- i = get_tv_number_chk(&argvars[1], &error);
+ i = tv_get_number_chk(&argvars[1], &error);
if (error) {
goto theend; // type error; errmsg already given
}
if (i == 1) {
info.item_compare_ic = true;
} else if (argvars[1].v_type != VAR_NUMBER) {
- info.item_compare_func = get_tv_string(&argvars[1]);
+ info.item_compare_func = tv_get_string(&argvars[1]);
} else if (i != 0) {
EMSG(_(e_invarg));
goto theend;
@@ -15396,16 +15470,16 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
if (*info.item_compare_func == NUL) {
// empty string means default sort
info.item_compare_func = NULL;
- } else if (STRCMP(info.item_compare_func, "n") == 0) {
+ } else if (strcmp(info.item_compare_func, "n") == 0) {
info.item_compare_func = NULL;
info.item_compare_numeric = true;
- } else if (STRCMP(info.item_compare_func, "N") == 0) {
+ } else if (strcmp(info.item_compare_func, "N") == 0) {
info.item_compare_func = NULL;
info.item_compare_numbers = true;
- } else if (STRCMP(info.item_compare_func, "f") == 0) {
+ } else if (strcmp(info.item_compare_func, "f") == 0) {
info.item_compare_func = NULL;
info.item_compare_float = true;
- } else if (STRCMP(info.item_compare_func, "i") == 0) {
+ } else if (strcmp(info.item_compare_func, "i") == 0) {
info.item_compare_func = NULL;
info.item_compare_ic = true;
}
@@ -15422,77 +15496,45 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
}
}
- /* Make an array with each entry pointing to an item in the List. */
- ptrs = xmalloc((size_t)(len * sizeof (sortItem_T)));
+ // Make an array with each entry pointing to an item in the List.
+ ptrs = xmalloc((size_t)(len * sizeof(ListSortItem)));
- i = 0;
if (sort) {
- // sort(): ptrs will be the list to sort.
- for (li = l->lv_first; li != NULL; li = li->li_next) {
- ptrs[i].item = li;
- ptrs[i].idx = i;
- i++;
- }
-
info.item_compare_func_err = false;
- // Test the compare function.
- if (info.item_compare_func != NULL
- && item_compare2_not_keeping_zero(&ptrs[0], &ptrs[1])
- == ITEM_COMPARE_FAIL) {
+ tv_list_item_sort(l, ptrs,
+ ((info.item_compare_func == NULL
+ && info.item_compare_partial == NULL)
+ ? item_compare_not_keeping_zero
+ : item_compare2_not_keeping_zero),
+ &info.item_compare_func_err);
+ if (info.item_compare_func_err) {
EMSG(_("E702: Sort compare function failed"));
- } else {
- // Sort the array with item pointers.
- qsort(ptrs, (size_t)len, sizeof (sortItem_T),
- (info.item_compare_func == NULL ?
- item_compare_not_keeping_zero :
- item_compare2_not_keeping_zero));
-
- if (!info.item_compare_func_err) {
- // Clear the list and append the items in the sorted order.
- l->lv_first = NULL;
- l->lv_last = NULL;
- l->lv_idx_item = NULL;
- l->lv_len = 0;
-
- for (i = 0; i < len; i++) {
- list_append(l, ptrs[i].item);
- }
- }
}
} else {
- int (*item_compare_func_ptr)(const void *, const void *);
+ ListSorter item_compare_func_ptr;
// f_uniq(): ptrs will be a stack of items to remove.
info.item_compare_func_err = false;
- if (info.item_compare_func != NULL) {
- item_compare_func_ptr = item_compare2_keeping_zero;
+ if (info.item_compare_func != NULL
+ || info.item_compare_partial != NULL) {
+ item_compare_func_ptr = item_compare2_keeping_zero;
} else {
- item_compare_func_ptr = item_compare_keeping_zero;
- }
-
- for (li = l->lv_first; li != NULL && li->li_next != NULL; li = li->li_next) {
- if (item_compare_func_ptr(&li, &li->li_next) == 0) {
- ptrs[i++].item = li;
- }
- if (info.item_compare_func_err) {
- EMSG(_("E882: Uniq compare function failed"));
- break;
- }
+ item_compare_func_ptr = item_compare_keeping_zero;
}
- if (!info.item_compare_func_err) {
- while (--i >= 0) {
- assert(ptrs[i].item->li_next);
- li = ptrs[i].item->li_next;
- ptrs[i].item->li_next = li->li_next;
- if (li->li_next != NULL) {
- li->li_next->li_prev = ptrs[i].item;
- } else {
- l->lv_last = ptrs[i].item;
+ int idx = 0;
+ for (listitem_T *li = TV_LIST_ITEM_NEXT(l, tv_list_first(l))
+ ; li != NULL;) {
+ listitem_T *const prev_li = TV_LIST_ITEM_PREV(l, li);
+ if (item_compare_func_ptr(&prev_li, &li) == 0) {
+ if (info.item_compare_func_err) { // -V547
+ EMSG(_("E882: Uniq compare function failed"));
+ break;
}
- list_fix_watch(l, li);
- listitem_free(li);
- l->lv_len--;
+ li = tv_list_item_remove(l, li);
+ } else {
+ idx++;
+ li = TV_LIST_ITEM_NEXT(l, li);
}
}
}
@@ -15505,13 +15547,46 @@ theend:
}
/// "sort"({list})" function
-static void f_sort(typval_T *argvars, typval_T *rettv)
+static void f_sort(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
do_sort_uniq(argvars, rettv, true);
}
+/// "stdioopen()" function
+static void f_stdioopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ if (argvars[0].v_type != VAR_DICT) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+
+ bool rpc = false;
+ CallbackReader on_stdin = CALLBACK_READER_INIT;
+ dict_T *opts = argvars[0].vval.v_dict;
+ rpc = tv_dict_get_number(opts, "rpc") != 0;
+
+ if (!tv_dict_get_callback(opts, S_LEN("on_stdin"), &on_stdin.cb)) {
+ return;
+ }
+ on_stdin.buffered = tv_dict_get_number(opts, "stdin_buffered");
+ if (on_stdin.buffered && on_stdin.cb.type == kCallbackNone) {
+ on_stdin.self = opts;
+ }
+
+ const char *error;
+ uint64_t id = channel_from_stdio(rpc, on_stdin, &error);
+ if (!id) {
+ EMSG2(e_stdiochan2, error);
+ }
+
+
+ rettv->vval.v_number = (varnumber_T)id;
+ rettv->v_type = VAR_NUMBER;
+}
+
/// "uniq({list})" function
-static void f_uniq(typval_T *argvars, typval_T *rettv)
+static void f_uniq(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
do_sort_uniq(argvars, rettv, false);
}
@@ -15519,7 +15594,7 @@ static void f_uniq(typval_T *argvars, typval_T *rettv)
//
// "reltimefloat()" function
//
-static void f_reltimefloat(typval_T *argvars , typval_T *rettv)
+static void f_reltimefloat(typval_T *argvars , typval_T *rettv, FunPtr fptr)
FUNC_ATTR_NONNULL_ALL
{
proftime_T tm;
@@ -15534,39 +15609,37 @@ static void f_reltimefloat(typval_T *argvars , typval_T *rettv)
/*
* "soundfold({word})" function
*/
-static void f_soundfold(typval_T *argvars, typval_T *rettv)
+static void f_soundfold(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s;
-
rettv->v_type = VAR_STRING;
- s = get_tv_string(&argvars[0]);
- rettv->vval.v_string = eval_soundfold(s);
+ const char *const s = tv_get_string(&argvars[0]);
+ rettv->vval.v_string = (char_u *)eval_soundfold(s);
}
/*
* "spellbadword()" function
*/
-static void f_spellbadword(typval_T *argvars, typval_T *rettv)
+static void f_spellbadword(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *word = (char_u *)"";
+ const char *word = "";
hlf_T attr = HLF_COUNT;
size_t len = 0;
- rettv_list_alloc(rettv);
-
if (argvars[0].v_type == VAR_UNKNOWN) {
- /* Find the start and length of the badly spelled word. */
- len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr);
- if (len != 0)
- word = get_cursor_pos_ptr();
+ // Find the start and length of the badly spelled word.
+ len = spell_move_to(curwin, FORWARD, true, true, &attr);
+ if (len != 0) {
+ word = (char *)get_cursor_pos_ptr();
+ curwin->w_set_curswant = true;
+ }
} else if (curwin->w_p_spell && *curbuf->b_s.b_p_spl != NUL) {
- char_u *str = get_tv_string_chk(&argvars[0]);
+ const char *str = tv_get_string_chk(&argvars[0]);
int capcol = -1;
if (str != NULL) {
- /* Check the argument for spelling. */
+ // Check the argument for spelling.
while (*str != NUL) {
- len = spell_check(curwin, str, &attr, &capcol, false);
+ len = spell_check(curwin, (char_u *)str, &attr, &capcol, false);
if (attr != HLF_COUNT) {
word = str;
break;
@@ -15577,119 +15650,125 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv)
}
assert(len <= INT_MAX);
- list_append_string(rettv->vval.v_list, word, (int)len);
- list_append_string(rettv->vval.v_list,
- (char_u *)(attr == HLF_SPB ? "bad" :
- attr == HLF_SPR ? "rare" :
- attr == HLF_SPL ? "local" :
- attr == HLF_SPC ? "caps" :
- ""),
- -1);
+ tv_list_alloc_ret(rettv, 2);
+ tv_list_append_string(rettv->vval.v_list, word, len);
+ tv_list_append_string(rettv->vval.v_list,
+ (attr == HLF_SPB ? "bad"
+ : attr == HLF_SPR ? "rare"
+ : attr == HLF_SPL ? "local"
+ : attr == HLF_SPC ? "caps"
+ : NULL), -1);
}
/*
* "spellsuggest()" function
*/
-static void f_spellsuggest(typval_T *argvars, typval_T *rettv)
+static void f_spellsuggest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *str;
- int typeerr = FALSE;
+ bool typeerr = false;
int maxcount;
- garray_T ga;
- listitem_T *li;
+ garray_T ga = GA_EMPTY_INIT_VALUE;
bool need_capital = false;
- rettv_list_alloc(rettv);
-
if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) {
- str = get_tv_string(&argvars[0]);
+ const char *const str = tv_get_string(&argvars[0]);
if (argvars[1].v_type != VAR_UNKNOWN) {
- maxcount = get_tv_number_chk(&argvars[1], &typeerr);
- if (maxcount <= 0)
- return;
+ maxcount = tv_get_number_chk(&argvars[1], &typeerr);
+ if (maxcount <= 0) {
+ goto f_spellsuggest_return;
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- need_capital = get_tv_number_chk(&argvars[2], &typeerr);
- if (typeerr)
- return;
+ need_capital = tv_get_number_chk(&argvars[2], &typeerr);
+ if (typeerr) {
+ goto f_spellsuggest_return;
+ }
}
- } else
+ } else {
maxcount = 25;
+ }
- spell_suggest_list(&ga, str, maxcount, need_capital, false);
-
- for (int i = 0; i < ga.ga_len; ++i) {
- str = ((char_u **)ga.ga_data)[i];
+ spell_suggest_list(&ga, (char_u *)str, maxcount, need_capital, false);
+ }
- li = listitem_alloc();
- li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = str;
- list_append(rettv->vval.v_list, li);
- }
- ga_clear(&ga);
+f_spellsuggest_return:
+ tv_list_alloc_ret(rettv, (ptrdiff_t)ga.ga_len);
+ for (int i = 0; i < ga.ga_len; i++) {
+ char *const p = ((char **)ga.ga_data)[i];
+ tv_list_append_allocated_string(rettv->vval.v_list, p);
}
+ ga_clear(&ga);
}
-static void f_split(typval_T *argvars, typval_T *rettv)
+static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *str;
- char_u *end;
- char_u *pat = NULL;
- regmatch_T regmatch;
- char_u patbuf[NUMBUFLEN];
char_u *save_cpo;
int match;
colnr_T col = 0;
- int keepempty = FALSE;
- int typeerr = FALSE;
+ bool keepempty = false;
+ bool typeerr = false;
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
save_cpo = p_cpo;
p_cpo = (char_u *)"";
- str = get_tv_string(&argvars[0]);
+ const char *str = tv_get_string(&argvars[0]);
+ const char *pat = NULL;
+ char patbuf[NUMBUFLEN];
if (argvars[1].v_type != VAR_UNKNOWN) {
- pat = get_tv_string_buf_chk(&argvars[1], patbuf);
- if (pat == NULL)
- typeerr = TRUE;
- if (argvars[2].v_type != VAR_UNKNOWN)
- keepempty = get_tv_number_chk(&argvars[2], &typeerr);
+ pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ if (pat == NULL) {
+ typeerr = true;
+ }
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ keepempty = (bool)tv_get_number_chk(&argvars[2], &typeerr);
+ }
+ }
+ if (pat == NULL || *pat == NUL) {
+ pat = "[\\x01- ]\\+";
}
- if (pat == NULL || *pat == NUL)
- pat = (char_u *)"[\\x01- ]\\+";
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
- if (typeerr)
+ if (typeerr) {
return;
+ }
- regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
+ regmatch_T regmatch = {
+ .regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING),
+ .startp = { NULL },
+ .endp = { NULL },
+ .rm_ic = false,
+ };
if (regmatch.regprog != NULL) {
- regmatch.rm_ic = FALSE;
while (*str != NUL || keepempty) {
- if (*str == NUL)
- match = FALSE; /* empty item at the end */
- else
- match = vim_regexec_nl(&regmatch, str, col);
- if (match)
- end = regmatch.startp[0];
- else
- end = str + STRLEN(str);
- if (keepempty || end > str || (rettv->vval.v_list->lv_len > 0
- && *str != NUL && match && end <
- regmatch.endp[0])) {
- list_append_string(rettv->vval.v_list, str, (int)(end - str));
+ if (*str == NUL) {
+ match = false; // Empty item at the end.
+ } else {
+ match = vim_regexec_nl(&regmatch, (char_u *)str, col);
+ }
+ const char *end;
+ if (match) {
+ end = (const char *)regmatch.startp[0];
+ } else {
+ end = str + strlen(str);
}
- if (!match)
+ if (keepempty || end > str || (tv_list_len(rettv->vval.v_list) > 0
+ && *str != NUL
+ && match
+ && end < (const char *)regmatch.endp[0])) {
+ tv_list_append_string(rettv->vval.v_list, str, end - str);
+ }
+ if (!match) {
break;
- /* Advance to just after the match. */
- if (regmatch.endp[0] > str)
+ }
+ // Advance to just after the match.
+ if (regmatch.endp[0] > (char_u *)str) {
col = 0;
- else {
- /* Don't get stuck at the same match. */
+ } else {
+ // Don't get stuck at the same match.
col = (*mb_ptr2len)(regmatch.endp[0]);
}
- str = regmatch.endp[0];
+ str = (const char *)regmatch.endp[0];
}
vim_regfree(regmatch.regprog);
@@ -15698,80 +15777,137 @@ static void f_split(typval_T *argvars, typval_T *rettv)
p_cpo = save_cpo;
}
-/*
- * "sqrt()" function
- */
-static void f_sqrt(typval_T *argvars, typval_T *rettv)
+/// "stdpath()" helper for list results
+static void get_xdg_var_list(const XDGVarType xdg, typval_T *rettv)
+ FUNC_ATTR_NONNULL_ALL
{
- float_op_wrapper(argvars, rettv, &sqrt);
+ const void *iter = NULL;
+ list_T *const list = tv_list_alloc(kListLenShouldKnow);
+ rettv->v_type = VAR_LIST;
+ rettv->vval.v_list = list;
+ tv_list_ref(list);
+ char *const dirs = stdpaths_get_xdg_var(xdg);
+ if (dirs == NULL) {
+ return;
+ }
+ do {
+ size_t dir_len;
+ const char *dir;
+ iter = vim_env_iter(':', dirs, iter, &dir, &dir_len);
+ if (dir != NULL && dir_len > 0) {
+ char *dir_with_nvim = xmemdupz(dir, dir_len);
+ dir_with_nvim = concat_fnames_realloc(dir_with_nvim, "nvim", true);
+ tv_list_append_string(list, dir_with_nvim, strlen(dir_with_nvim));
+ xfree(dir_with_nvim);
+ }
+ } while (iter != NULL);
+ xfree(dirs);
+}
+
+/// "stdpath(type)" function
+static void f_stdpath(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = NULL;
+
+ const char *const p = tv_get_string_chk(&argvars[0]);
+ if (p == NULL) {
+ return; // Type error; errmsg already given.
+ }
+
+ if (strequal(p, "config")) {
+ rettv->vval.v_string = (char_u *)get_xdg_home(kXDGConfigHome);
+ } else if (strequal(p, "data")) {
+ rettv->vval.v_string = (char_u *)get_xdg_home(kXDGDataHome);
+ } else if (strequal(p, "cache")) {
+ rettv->vval.v_string = (char_u *)get_xdg_home(kXDGCacheHome);
+ } else if (strequal(p, "config_dirs")) {
+ get_xdg_var_list(kXDGConfigDirs, rettv);
+ } else if (strequal(p, "data_dirs")) {
+ get_xdg_var_list(kXDGDataDirs, rettv);
+ } else {
+ EMSG2(_("E6100: \"%s\" is not a valid stdpath"), p);
+ }
}
/*
* "str2float()" function
*/
-static void f_str2float(typval_T *argvars, typval_T *rettv)
+static void f_str2float(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = skipwhite(get_tv_string(&argvars[0]));
+ char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
+ bool isneg = (*p == '-');
- if (*p == '+')
+ if (*p == '+' || *p == '-') {
p = skipwhite(p + 1);
- (void) string2float((char *) p, &rettv->vval.v_float);
+ }
+ (void)string2float((char *)p, &rettv->vval.v_float);
+ if (isneg) {
+ rettv->vval.v_float *= -1;
+ }
rettv->v_type = VAR_FLOAT;
}
// "str2nr()" function
-static void f_str2nr(typval_T *argvars, typval_T *rettv)
+static void f_str2nr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int base = 10;
- char_u *p;
- long n;
+ varnumber_T n;
int what;
if (argvars[1].v_type != VAR_UNKNOWN) {
- base = get_tv_number(&argvars[1]);
+ base = tv_get_number(&argvars[1]);
if (base != 2 && base != 8 && base != 10 && base != 16) {
EMSG(_(e_invarg));
return;
}
}
- p = skipwhite(get_tv_string(&argvars[0]));
- if (*p == '+') {
+ char_u *p = skipwhite((const char_u *)tv_get_string(&argvars[0]));
+ bool isneg = (*p == '-');
+ if (*p == '+' || *p == '-') {
p = skipwhite(p + 1);
}
switch (base) {
- case 2:
- what = STR2NR_BIN + STR2NR_FORCE;
+ case 2: {
+ what = STR2NR_BIN | STR2NR_FORCE;
break;
- case 8:
- what = STR2NR_OCT + STR2NR_FORCE;
+ }
+ case 8: {
+ what = STR2NR_OCT | STR2NR_FORCE;
break;
- case 16:
- what = STR2NR_HEX + STR2NR_FORCE;
+ }
+ case 16: {
+ what = STR2NR_HEX | STR2NR_FORCE;
break;
- default:
+ }
+ default: {
what = 0;
+ }
}
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
- rettv->vval.v_number = n;
+ if (isneg) {
+ rettv->vval.v_number = -n;
+ } else {
+ rettv->vval.v_number = n;
+ }
}
/*
* "strftime({format}[, {time}])" function
*/
-static void f_strftime(typval_T *argvars, typval_T *rettv)
+static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u result_buf[256];
time_t seconds;
- char_u *p;
rettv->v_type = VAR_STRING;
- p = get_tv_string(&argvars[0]);
- if (argvars[1].v_type == VAR_UNKNOWN)
+ char *p = (char *)tv_get_string(&argvars[0]);
+ if (argvars[1].v_type == VAR_UNKNOWN) {
seconds = time(NULL);
- else
- seconds = (time_t)get_tv_number(&argvars[1]);
+ } else {
+ seconds = (time_t)tv_get_number(&argvars[1]);
+ }
struct tm curtime;
struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime);
@@ -15785,65 +15921,98 @@ static void f_strftime(typval_T *argvars, typval_T *rettv)
conv.vc_type = CONV_NONE;
enc = enc_locale();
convert_setup(&conv, p_enc, enc);
- if (conv.vc_type != CONV_NONE)
- p = string_convert(&conv, p, NULL);
- if (p != NULL)
- (void)strftime((char *)result_buf, sizeof(result_buf),
- (char *)p, curtime_ptr);
- else
+ if (conv.vc_type != CONV_NONE) {
+ p = (char *)string_convert(&conv, (char_u *)p, NULL);
+ }
+ char result_buf[256];
+ if (p != NULL) {
+ (void)strftime(result_buf, sizeof(result_buf), p, curtime_ptr);
+ } else {
result_buf[0] = NUL;
+ }
- if (conv.vc_type != CONV_NONE)
+ if (conv.vc_type != CONV_NONE) {
xfree(p);
+ }
convert_setup(&conv, enc, p_enc);
- if (conv.vc_type != CONV_NONE)
- rettv->vval.v_string = string_convert(&conv, result_buf, NULL);
- else
- rettv->vval.v_string = vim_strsave(result_buf);
+ if (conv.vc_type != CONV_NONE) {
+ rettv->vval.v_string = string_convert(&conv, (char_u *)result_buf, NULL);
+ } else {
+ rettv->vval.v_string = (char_u *)xstrdup(result_buf);
+ }
- /* Release conversion descriptors */
+ // Release conversion descriptors.
convert_setup(&conv, NULL, NULL);
xfree(enc);
}
}
+// "strgetchar()" function
+static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->vval.v_number = -1;
+
+ const char *const str = tv_get_string_chk(&argvars[0]);
+ if (str == NULL) {
+ return;
+ }
+ bool error = false;
+ varnumber_T charidx = tv_get_number_chk(&argvars[1], &error);
+ if (error) {
+ return;
+ }
+
+ const size_t len = STRLEN(str);
+ size_t byteidx = 0;
+
+ while (charidx >= 0 && byteidx < len) {
+ if (charidx == 0) {
+ rettv->vval.v_number = utf_ptr2char((const char_u *)str + byteidx);
+ break;
+ }
+ charidx--;
+ byteidx += MB_CPTR2LEN((const char_u *)str + byteidx);
+ }
+}
+
/*
* "stridx()" function
*/
-static void f_stridx(typval_T *argvars, typval_T *rettv)
+static void f_stridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
- char_u *needle;
- char_u *haystack;
- char_u *save_haystack;
- char_u *pos;
- int start_idx;
-
- needle = get_tv_string_chk(&argvars[1]);
- save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf);
rettv->vval.v_number = -1;
- if (needle == NULL || haystack == NULL)
- return; /* type error; errmsg already given */
+
+ char buf[NUMBUFLEN];
+ const char *const needle = tv_get_string_chk(&argvars[1]);
+ const char *haystack = tv_get_string_buf_chk(&argvars[0], buf);
+ const char *const haystack_start = haystack;
+ if (needle == NULL || haystack == NULL) {
+ return; // Type error; errmsg already given.
+ }
if (argvars[2].v_type != VAR_UNKNOWN) {
- int error = FALSE;
+ bool error = false;
- start_idx = get_tv_number_chk(&argvars[2], &error);
- if (error || start_idx >= (int)STRLEN(haystack))
+ const ptrdiff_t start_idx = (ptrdiff_t)tv_get_number_chk(&argvars[2],
+ &error);
+ if (error || start_idx >= (ptrdiff_t)strlen(haystack)) {
return;
- if (start_idx >= 0)
+ }
+ if (start_idx >= 0) {
haystack += start_idx;
+ }
}
- pos = (char_u *)strstr((char *)haystack, (char *)needle);
- if (pos != NULL)
- rettv->vval.v_number = (varnumber_T)(pos - save_haystack);
+ const char *pos = strstr(haystack, needle);
+ if (pos != NULL) {
+ rettv->vval.v_number = (varnumber_T)(pos - haystack_start);
+ }
}
/*
* "string()" function
*/
-static void f_string(typval_T *argvars, typval_T *rettv)
+static void f_string(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = (char_u *) encode_tv2string(&argvars[0], NULL);
@@ -15852,32 +16021,31 @@ static void f_string(typval_T *argvars, typval_T *rettv)
/*
* "strlen()" function
*/
-static void f_strlen(typval_T *argvars, typval_T *rettv)
+static void f_strlen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = (varnumber_T)(STRLEN(
- get_tv_string(&argvars[0])));
+ rettv->vval.v_number = (varnumber_T)strlen(tv_get_string(&argvars[0]));
}
/*
* "strchars()" function
*/
-static void f_strchars(typval_T *argvars, typval_T *rettv)
+static void f_strchars(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s = get_tv_string(&argvars[0]);
+ const char *s = tv_get_string(&argvars[0]);
int skipcc = 0;
varnumber_T len = 0;
- int (*func_mb_ptr2char_adv)(char_u **pp);
+ int (*func_mb_ptr2char_adv)(const char_u **pp);
if (argvars[1].v_type != VAR_UNKNOWN) {
- skipcc = get_tv_number_chk(&argvars[1], NULL);
+ skipcc = tv_get_number_chk(&argvars[1], NULL);
}
if (skipcc < 0 || skipcc > 1) {
EMSG(_(e_invarg));
} else {
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
while (*s != NUL) {
- func_mb_ptr2char_adv(&s);
- ++len;
+ func_mb_ptr2char_adv((const char_u **)&s);
+ len++;
}
rettv->vval.v_number = len;
}
@@ -15886,139 +16054,197 @@ static void f_strchars(typval_T *argvars, typval_T *rettv)
/*
* "strdisplaywidth()" function
*/
-static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv)
+static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s = get_tv_string(&argvars[0]);
+ const char *const s = tv_get_string(&argvars[0]);
int col = 0;
- if (argvars[1].v_type != VAR_UNKNOWN)
- col = get_tv_number(&argvars[1]);
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ col = tv_get_number(&argvars[1]);
+ }
- rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, s) - col);
+ rettv->vval.v_number = (varnumber_T)(linetabsize_col(col, (char_u *)s) - col);
}
/*
* "strwidth()" function
*/
-static void f_strwidth(typval_T *argvars, typval_T *rettv)
+static void f_strwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *s = get_tv_string(&argvars[0]);
+ const char *const s = tv_get_string(&argvars[0]);
- rettv->vval.v_number = (varnumber_T) mb_string2cells(s);
+ rettv->vval.v_number = (varnumber_T)mb_string2cells((const char_u *)s);
+}
+
+// "strcharpart()" function
+static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ const char *const p = tv_get_string(&argvars[0]);
+ const size_t slen = STRLEN(p);
+
+ int nbyte = 0;
+ bool error = false;
+ varnumber_T nchar = tv_get_number_chk(&argvars[1], &error);
+ if (!error) {
+ if (nchar > 0) {
+ while (nchar > 0 && (size_t)nbyte < slen) {
+ nbyte += MB_CPTR2LEN((const char_u *)p + nbyte);
+ nchar--;
+ }
+ } else {
+ nbyte = nchar;
+ }
+ }
+ int len = 0;
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ int charlen = tv_get_number(&argvars[2]);
+ while (charlen > 0 && nbyte + len < (int)slen) {
+ int off = nbyte + len;
+
+ if (off < 0) {
+ len += 1;
+ } else {
+ len += (size_t)MB_CPTR2LEN((const char_u *)p + off);
+ }
+ charlen--;
+ }
+ } else {
+ len = slen - nbyte; // default: all bytes that are available.
+ }
+
+ // Only return the overlap between the specified part and the actual
+ // string.
+ if (nbyte < 0) {
+ len += nbyte;
+ nbyte = 0;
+ } else if ((size_t)nbyte > slen) {
+ nbyte = slen;
+ }
+ if (len < 0) {
+ len = 0;
+ } else if (nbyte + len > (int)slen) {
+ len = slen - nbyte;
+ }
+
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = (char_u *)xstrndup(p + nbyte, (size_t)len);
}
/*
* "strpart()" function
*/
-static void f_strpart(typval_T *argvars, typval_T *rettv)
+static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p;
- int n;
- int len;
- int slen;
- int error = FALSE;
+ bool error = false;
- p = get_tv_string(&argvars[0]);
- slen = (int)STRLEN(p);
+ const char *const p = tv_get_string(&argvars[0]);
+ const size_t slen = strlen(p);
- n = get_tv_number_chk(&argvars[1], &error);
- if (error)
+ varnumber_T n = tv_get_number_chk(&argvars[1], &error);
+ varnumber_T len;
+ if (error) {
len = 0;
- else if (argvars[2].v_type != VAR_UNKNOWN)
- len = get_tv_number(&argvars[2]);
- else
- len = slen - n; /* default len: all bytes that are available. */
+ } else if (argvars[2].v_type != VAR_UNKNOWN) {
+ len = tv_get_number(&argvars[2]);
+ } else {
+ len = slen - n; // Default len: all bytes that are available.
+ }
- /*
- * Only return the overlap between the specified part and the actual
- * string.
- */
+ // Only return the overlap between the specified part and the actual
+ // string.
if (n < 0) {
len += n;
n = 0;
- } else if (n > slen)
+ } else if (n > (varnumber_T)slen) {
n = slen;
- if (len < 0)
+ }
+ if (len < 0) {
len = 0;
- else if (n + len > slen)
+ } else if (n + len > (varnumber_T)slen) {
len = slen - n;
+ }
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = vim_strnsave(p + n, len);
+ rettv->vval.v_string = (char_u *)xmemdupz(p + n, (size_t)len);
}
/*
* "strridx()" function
*/
-static void f_strridx(typval_T *argvars, typval_T *rettv)
+static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u buf[NUMBUFLEN];
- char_u *needle;
- char_u *haystack;
- char_u *rest;
- char_u *lastmatch = NULL;
- int haystack_len, end_idx;
-
- needle = get_tv_string_chk(&argvars[1]);
- haystack = get_tv_string_buf_chk(&argvars[0], buf);
+ char buf[NUMBUFLEN];
+ const char *const needle = tv_get_string_chk(&argvars[1]);
+ const char *const haystack = tv_get_string_buf_chk(&argvars[0], buf);
rettv->vval.v_number = -1;
- if (needle == NULL || haystack == NULL)
- return; /* type error; errmsg already given */
+ if (needle == NULL || haystack == NULL) {
+ return; // Type error; errmsg already given.
+ }
- haystack_len = (int)STRLEN(haystack);
+ const size_t haystack_len = STRLEN(haystack);
+ ptrdiff_t end_idx;
if (argvars[2].v_type != VAR_UNKNOWN) {
- /* Third argument: upper limit for index */
- end_idx = get_tv_number_chk(&argvars[2], NULL);
- if (end_idx < 0)
- return; /* can never find a match */
- } else
- end_idx = haystack_len;
+ // Third argument: upper limit for index.
+ end_idx = (ptrdiff_t)tv_get_number_chk(&argvars[2], NULL);
+ if (end_idx < 0) {
+ return; // Can never find a match.
+ }
+ } else {
+ end_idx = (ptrdiff_t)haystack_len;
+ }
+ const char *lastmatch = NULL;
if (*needle == NUL) {
- /* Empty string matches past the end. */
+ // Empty string matches past the end.
lastmatch = haystack + end_idx;
} else {
- for (rest = haystack; *rest != NUL; ++rest) {
- rest = (char_u *)strstr((char *)rest, (char *)needle);
- if (rest == NULL || rest > haystack + end_idx)
+ for (const char *rest = haystack; *rest != NUL; rest++) {
+ rest = strstr(rest, needle);
+ if (rest == NULL || rest > haystack + end_idx) {
break;
+ }
lastmatch = rest;
}
}
- if (lastmatch == NULL)
+ if (lastmatch == NULL) {
rettv->vval.v_number = -1;
- else
+ } else {
rettv->vval.v_number = (varnumber_T)(lastmatch - haystack);
+ }
}
/*
* "strtrans()" function
*/
-static void f_strtrans(typval_T *argvars, typval_T *rettv)
+static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = transstr(get_tv_string(&argvars[0]));
+ rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]));
}
/*
* "submatch()" function
*/
-static void f_submatch(typval_T *argvars, typval_T *rettv)
+static void f_submatch(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int error = FALSE;
- int no = (int)get_tv_number_chk(&argvars[0], &error);
+ bool error = false;
+ int no = (int)tv_get_number_chk(&argvars[0], &error);
if (error) {
return;
}
+ if (no < 0 || no >= NSUBEXP) {
+ emsgf(_("E935: invalid submatch number: %d"), no);
+ return;
+ }
int retList = 0;
if (argvars[1].v_type != VAR_UNKNOWN) {
- retList = get_tv_number_chk(&argvars[1], &error);
+ retList = tv_get_number_chk(&argvars[1], &error);
if (error) {
- return;
+ return;
}
}
@@ -16034,42 +16260,49 @@ static void f_submatch(typval_T *argvars, typval_T *rettv)
/*
* "substitute()" function
*/
-static void f_substitute(typval_T *argvars, typval_T *rettv)
+static void f_substitute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u patbuf[NUMBUFLEN];
- char_u subbuf[NUMBUFLEN];
- char_u flagsbuf[NUMBUFLEN];
+ char patbuf[NUMBUFLEN];
+ char subbuf[NUMBUFLEN];
+ char flagsbuf[NUMBUFLEN];
+
+ const char *const str = tv_get_string_chk(&argvars[0]);
+ const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf);
+ const char *sub = NULL;
+ const char *const flg = tv_get_string_buf_chk(&argvars[3], flagsbuf);
- char_u *str = get_tv_string_chk(&argvars[0]);
- char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf);
- char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf);
- char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf);
+ typval_T *expr = NULL;
+ if (tv_is_func(argvars[2])) {
+ expr = &argvars[2];
+ } else {
+ sub = tv_get_string_buf_chk(&argvars[2], subbuf);
+ }
rettv->v_type = VAR_STRING;
- if (str == NULL || pat == NULL || sub == NULL || flg == NULL)
+ if (str == NULL || pat == NULL || (sub == NULL && expr == NULL)
+ || flg == NULL) {
rettv->vval.v_string = NULL;
- else
- rettv->vval.v_string = do_string_sub(str, pat, sub, flg);
+ } else {
+ rettv->vval.v_string = do_string_sub((char_u *)str, (char_u *)pat,
+ (char_u *)sub, expr, (char_u *)flg);
+ }
}
-/*
- * "synID(lnum, col, trans)" function
- */
-static void f_synID(typval_T *argvars, typval_T *rettv)
+/// "synID(lnum, col, trans)" function
+static void f_synID(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int id = 0;
- long lnum;
- long col;
- int trans;
- int transerr = FALSE;
+ // -1 on type error (both)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1;
- lnum = get_tv_lnum(argvars); /* -1 on type error */
- col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */
- trans = get_tv_number_chk(&argvars[2], &transerr);
+ bool transerr = false;
+ const int trans = tv_get_number_chk(&argvars[2], &transerr);
+ int id = 0;
if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count
- && col >= 0 && col < (long)STRLEN(ml_get(lnum)))
- id = syn_get_id(curwin, lnum, (colnr_T)col, trans, NULL, FALSE);
+ && col >= 0 && (size_t)col < STRLEN(ml_get(lnum))) {
+ id = syn_get_id(curwin, lnum, col, trans, NULL, false);
+ }
rettv->vval.v_number = id;
}
@@ -16077,22 +16310,18 @@ static void f_synID(typval_T *argvars, typval_T *rettv)
/*
* "synIDattr(id, what [, mode])" function
*/
-static void f_synIDattr(typval_T *argvars, typval_T *rettv)
+static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = NULL;
- int id;
- char_u *what;
- char_u *mode;
- char_u modebuf[NUMBUFLEN];
+ const int id = (int)tv_get_number(&argvars[0]);
+ const char *const what = tv_get_string(&argvars[1]);
int modec;
-
- id = get_tv_number(&argvars[0]);
- what = get_tv_string(&argvars[1]);
if (argvars[2].v_type != VAR_UNKNOWN) {
- mode = get_tv_string_buf(&argvars[2], modebuf);
+ char modebuf[NUMBUFLEN];
+ const char *const mode = tv_get_string_buf(&argvars[2], modebuf);
modec = TOLOWER_ASC(mode[0]);
- if (modec != 'c' && modec != 'g')
- modec = 0; /* replace invalid with current */
+ if (modec != 'c' && modec != 'g') {
+ modec = 0; // Replace invalid with current.
+ }
} else if (ui_rgb_attached()) {
modec = 'g';
} else {
@@ -16100,69 +16329,70 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv)
}
+ const char *p = NULL;
switch (TOLOWER_ASC(what[0])) {
- case 'b':
- if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */
+ case 'b': {
+ if (TOLOWER_ASC(what[1]) == 'g') { // bg[#]
+ p = highlight_color(id, what, modec);
+ } else { // bold
+ p = highlight_has_attr(id, HL_BOLD, modec);
+ }
+ break;
+ }
+ case 'f': { // fg[#] or font
p = highlight_color(id, what, modec);
- else /* bold */
- p = highlight_has_attr(id, HL_BOLD, modec);
- break;
-
- case 'f': /* fg[#] or font */
- p = highlight_color(id, what, modec);
- break;
-
- case 'i':
- if (TOLOWER_ASC(what[1]) == 'n') /* inverse */
+ break;
+ }
+ case 'i': {
+ if (TOLOWER_ASC(what[1]) == 'n') { // inverse
+ p = highlight_has_attr(id, HL_INVERSE, modec);
+ } else { // italic
+ p = highlight_has_attr(id, HL_ITALIC, modec);
+ }
+ break;
+ }
+ case 'n': { // name
+ p = get_highlight_name_ext(NULL, id - 1, false);
+ break;
+ }
+ case 'r': { // reverse
p = highlight_has_attr(id, HL_INVERSE, modec);
- else /* italic */
- p = highlight_has_attr(id, HL_ITALIC, modec);
- break;
-
- case 'n': /* name */
- p = get_highlight_name(NULL, id - 1);
- break;
-
- case 'r': /* reverse */
- p = highlight_has_attr(id, HL_INVERSE, modec);
- break;
-
- case 's':
- if (TOLOWER_ASC(what[1]) == 'p') /* sp[#] */
- p = highlight_color(id, what, modec);
- else /* standout */
- p = highlight_has_attr(id, HL_STANDOUT, modec);
- break;
-
- case 'u':
- if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c')
- /* underline */
- p = highlight_has_attr(id, HL_UNDERLINE, modec);
- else
- /* undercurl */
- p = highlight_has_attr(id, HL_UNDERCURL, modec);
- break;
+ break;
+ }
+ case 's': {
+ if (TOLOWER_ASC(what[1]) == 'p') { // sp[#]
+ p = highlight_color(id, what, modec);
+ } else { // standout
+ p = highlight_has_attr(id, HL_STANDOUT, modec);
+ }
+ break;
+ }
+ case 'u': {
+ if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
+ p = highlight_has_attr(id, HL_UNDERLINE, modec);
+ } else { // undercurl
+ p = highlight_has_attr(id, HL_UNDERCURL, modec);
+ }
+ break;
+ }
}
- if (p != NULL)
- p = vim_strsave(p);
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = p;
+ rettv->vval.v_string = (char_u *)(p == NULL ? p : xstrdup(p));
}
/*
* "synIDtrans(id)" function
*/
-static void f_synIDtrans(typval_T *argvars, typval_T *rettv)
+static void f_synIDtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- int id;
-
- id = get_tv_number(&argvars[0]);
+ int id = tv_get_number(&argvars[0]);
- if (id > 0)
+ if (id > 0) {
id = syn_get_final_id(id);
- else
+ } else {
id = 0;
+ }
rettv->vval.v_number = id;
}
@@ -16170,111 +16400,88 @@ static void f_synIDtrans(typval_T *argvars, typval_T *rettv)
/*
* "synconcealed(lnum, col)" function
*/
-static void f_synconcealed(typval_T *argvars, typval_T *rettv)
+static void f_synconcealed(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long lnum;
- long col;
int syntax_flags = 0;
int cchar;
int matchid = 0;
char_u str[NUMBUFLEN];
- rettv->v_type = VAR_LIST;
- rettv->vval.v_list = NULL;
+ tv_list_set_ret(rettv, NULL);
- lnum = get_tv_lnum(argvars); /* -1 on type error */
- col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */
+ // -1 on type error (both)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1;
memset(str, NUL, sizeof(str));
- rettv_list_alloc(rettv);
if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count && col >= 0
- && col <= (long)STRLEN(ml_get(lnum)) && curwin->w_p_cole > 0) {
- (void)syn_get_id(curwin, lnum, col, FALSE, NULL, FALSE);
+ && (size_t)col <= STRLEN(ml_get(lnum)) && curwin->w_p_cole > 0) {
+ (void)syn_get_id(curwin, lnum, col, false, NULL, false);
syntax_flags = get_syntax_info(&matchid);
// get the conceal character
if ((syntax_flags & HL_CONCEAL) && curwin->w_p_cole < 3) {
cchar = syn_get_sub_char();
- if (cchar == NUL && curwin->w_p_cole == 1 && lcs_conceal != NUL) {
- cchar = lcs_conceal;
+ if (cchar == NUL && curwin->w_p_cole == 1) {
+ cchar = (lcs_conceal == NUL) ? ' ' : lcs_conceal;
}
if (cchar != NUL) {
- if (has_mbyte)
- (*mb_char2bytes)(cchar, str);
- else
- str[0] = cchar;
+ utf_char2bytes(cchar, str);
}
}
}
- list_append_number(rettv->vval.v_list, (syntax_flags & HL_CONCEAL) != 0);
+ tv_list_alloc_ret(rettv, 3);
+ tv_list_append_number(rettv->vval.v_list, (syntax_flags & HL_CONCEAL) != 0);
// -1 to auto-determine strlen
- list_append_string(rettv->vval.v_list, str, -1);
- list_append_number(rettv->vval.v_list, matchid);
+ tv_list_append_string(rettv->vval.v_list, (const char *)str, -1);
+ tv_list_append_number(rettv->vval.v_list, matchid);
}
/*
* "synstack(lnum, col)" function
*/
-static void f_synstack(typval_T *argvars, typval_T *rettv)
+static void f_synstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long lnum;
- long col;
-
- rettv->v_type = VAR_LIST;
- rettv->vval.v_list = NULL;
+ tv_list_set_ret(rettv, NULL);
- lnum = get_tv_lnum(argvars); /* -1 on type error */
- col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */
+ // -1 on type error (both)
+ const linenr_T lnum = tv_get_lnum(argvars);
+ const colnr_T col = (colnr_T)tv_get_number(&argvars[1]) - 1;
if (lnum >= 1
&& lnum <= curbuf->b_ml.ml_line_count
&& col >= 0
- && col <= (long)STRLEN(ml_get(lnum))) {
- rettv_list_alloc(rettv);
- (void)syn_get_id(curwin, lnum, (colnr_T)col, FALSE, NULL, TRUE);
+ && (size_t)col <= STRLEN(ml_get(lnum))) {
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+ (void)syn_get_id(curwin, lnum, col, false, NULL, true);
int id;
int i = 0;
while ((id = syn_get_stack_item(i++)) >= 0) {
- list_append_number(rettv->vval.v_list, id);
+ tv_list_append_number(rettv->vval.v_list, id);
}
}
}
-static list_T* string_to_list(char_u *str, size_t len, bool keepempty)
+static list_T *string_to_list(const char *str, size_t len, const bool keepempty)
{
- list_T *list = list_alloc();
-
- // Copy each line to a list element using NL as the delimiter.
- for (size_t i = 0; i < len; i++) {
- char_u *start = str + i;
- size_t line_len = (char_u *) xmemscan(start, NL, len - i) - start;
- i += line_len;
-
- // Don't use a str function to copy res as it may contains NULs.
- char_u *s = xmemdupz(start, line_len);
- memchrsub(s, NUL, NL, line_len); // Replace NUL with NL to avoid truncation
-
- listitem_T *li = listitem_alloc();
- li->li_tv.v_type = VAR_STRING;
- li->li_tv.v_lock = 0;
- li->li_tv.vval.v_string = s;
- list_append(list, li);
- }
-
- // Optionally retain final newline, if present
- if (keepempty && str[len-1] == NL) {
- list_append_string(list, (char_u*)"", 0);
+ if (!keepempty && str[len - 1] == NL) {
+ len--;
}
-
+ list_T *const list = tv_list_alloc(kListLenMayKnow);
+ encode_list_write(list, str, len);
return list;
}
-static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
+// os_system wrapper. Handles 'verbose', :profile, and v:shell_error.
+static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
bool retlist)
{
+ proftime_T wait_time;
+ bool profiling = do_profiling == PROF_YES;
+
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
@@ -16283,25 +16490,46 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
}
// get input to the shell command (if any), and its length
- ssize_t input_len;
- char *input = (char *) save_tv_as_string(&argvars[1], &input_len, false);
+ ptrdiff_t input_len;
+ char *input = save_tv_as_string(&argvars[1], &input_len, false);
if (input_len < 0) {
assert(input == NULL);
return;
}
// get shell command to execute
- char **argv = tv_to_argv(&argvars[0], NULL);
+ bool executable = true;
+ char **argv = tv_to_argv(&argvars[0], NULL, &executable);
if (!argv) {
+ if (!executable) {
+ set_vim_var_nr(VV_SHELL_ERROR, (long)-1);
+ }
xfree(input);
return; // Already did emsg.
}
+ if (p_verbose > 3) {
+ char *cmdstr = shell_argv_to_str(argv);
+ verbose_enter_scroll();
+ smsg(_("Executing command: \"%s\""), cmdstr);
+ msg_puts("\n\n");
+ verbose_leave_scroll();
+ xfree(cmdstr);
+ }
+
+ if (profiling) {
+ prof_child_enter(&wait_time);
+ }
+
// execute the command
size_t nread = 0;
char *res = NULL;
int status = os_system(argv, input, input_len, &res, &nread);
+ if (profiling) {
+ prof_child_exit(&wait_time);
+ }
+
xfree(input);
set_vim_var_nr(VV_SHELL_ERROR, (long) status);
@@ -16309,7 +16537,7 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
if (res == NULL) {
if (retlist) {
// return an empty list when there's no output
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, 0);
} else {
rettv->vval.v_string = (char_u *) xstrdup("");
}
@@ -16319,10 +16547,10 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
if (retlist) {
int keepempty = 0;
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {
- keepempty = get_tv_number(&argvars[2]);
+ keepempty = tv_get_number(&argvars[2]);
}
- rettv->vval.v_list = string_to_list((char_u *) res, nread, keepempty != 0);
- rettv->vval.v_list->lv_refcount++;
+ rettv->vval.v_list = string_to_list(res, nread, (bool)keepempty);
+ tv_list_ref(rettv->vval.v_list);
rettv->v_type = VAR_LIST;
xfree(res);
@@ -16348,12 +16576,12 @@ static void get_system_output_as_rettv(typval_T *argvars, typval_T *rettv,
}
/// f_system - the VimL system() function
-static void f_system(typval_T *argvars, typval_T *rettv)
+static void f_system(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_system_output_as_rettv(argvars, rettv, false);
}
-static void f_systemlist(typval_T *argvars, typval_T *rettv)
+static void f_systemlist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
get_system_output_as_rettv(argvars, rettv, true);
}
@@ -16362,22 +16590,22 @@ static void f_systemlist(typval_T *argvars, typval_T *rettv)
/*
* "tabpagebuflist()" function
*/
-static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv)
+static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- tabpage_T *tp;
win_T *wp = NULL;
- if (argvars[0].v_type == VAR_UNKNOWN)
+ if (argvars[0].v_type == VAR_UNKNOWN) {
wp = firstwin;
- else {
- tp = find_tabpage((int)get_tv_number(&argvars[0]));
- if (tp != NULL)
+ } else {
+ tabpage_T *const tp = find_tabpage((int)tv_get_number(&argvars[0]));
+ if (tp != NULL) {
wp = (tp == curtab) ? firstwin : tp->tp_firstwin;
+ }
}
if (wp != NULL) {
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
while (wp != NULL) {
- list_append_number(rettv->vval.v_list, wp->w_buffer->b_fnum);
+ tv_list_append_number(rettv->vval.v_list, wp->w_buffer->b_fnum);
wp = wp->w_next;
}
}
@@ -16387,22 +16615,23 @@ static void f_tabpagebuflist(typval_T *argvars, typval_T *rettv)
/*
* "tabpagenr()" function
*/
-static void f_tabpagenr(typval_T *argvars, typval_T *rettv)
+static void f_tabpagenr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
- char_u *arg;
if (argvars[0].v_type != VAR_UNKNOWN) {
- arg = get_tv_string_chk(&argvars[0]);
+ const char *const arg = tv_get_string_chk(&argvars[0]);
nr = 0;
if (arg != NULL) {
- if (STRCMP(arg, "$") == 0)
+ if (strcmp(arg, "$") == 0) {
nr = tabpage_index(NULL) - 1;
- else
+ } else {
EMSG2(_(e_invexpr2), arg);
+ }
}
- } else
+ } else {
nr = tabpage_index(curtab);
+ }
rettv->vval.v_number = nr;
}
@@ -16416,19 +16645,19 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
win_T *twin;
int nr = 1;
win_T *wp;
- char_u *arg;
twin = (tp == curtab) ? curwin : tp->tp_curwin;
if (argvar->v_type != VAR_UNKNOWN) {
- arg = get_tv_string_chk(argvar);
- if (arg == NULL)
- nr = 0; /* type error; errmsg already given */
- else if (STRCMP(arg, "$") == 0)
+ const char *const arg = tv_get_string_chk(argvar);
+ if (arg == NULL) {
+ nr = 0; // Type error; errmsg already given.
+ } else if (strcmp(arg, "$") == 0) {
twin = (tp == curtab) ? lastwin : tp->tp_lastwin;
- else if (STRCMP(arg, "#") == 0) {
+ } else if (strcmp(arg, "#") == 0) {
twin = (tp == curtab) ? prevwin : tp->tp_prevwin;
- if (twin == NULL)
+ if (twin == NULL) {
nr = 0;
+ }
} else {
EMSG2(_(e_invexpr2), arg);
nr = 0;
@@ -16451,16 +16680,15 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar)
/*
* "tabpagewinnr()" function
*/
-static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv)
+static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
- tabpage_T *tp;
-
- tp = find_tabpage((int)get_tv_number(&argvars[0]));
- if (tp == NULL)
+ tabpage_T *const tp = find_tabpage((int)tv_get_number(&argvars[0]));
+ if (tp == NULL) {
nr = 0;
- else
+ } else {
nr = get_winnr(tp, &argvars[1]);
+ }
rettv->vval.v_number = nr;
}
@@ -16468,18 +16696,18 @@ static void f_tabpagewinnr(typval_T *argvars, typval_T *rettv)
/*
* "tagfiles()" function
*/
-static void f_tagfiles(typval_T *argvars, typval_T *rettv)
+static void f_tagfiles(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *fname;
+ char *fname;
tagname_T tn;
- rettv_list_alloc(rettv);
+ tv_list_alloc_ret(rettv, kListLenUnknown);
fname = xmalloc(MAXPATHL);
- int first = TRUE;
- while (get_tagfname(&tn, first, fname) == OK) {
- list_append_string(rettv->vval.v_list, fname, -1);
- first = FALSE;
+ bool first = true;
+ while (get_tagfname(&tn, first, (char_u *)fname) == OK) {
+ tv_list_append_string(rettv->vval.v_list, fname, -1);
+ first = false;
}
tagname_free(&tn);
@@ -16489,30 +16717,34 @@ static void f_tagfiles(typval_T *argvars, typval_T *rettv)
/*
* "taglist()" function
*/
-static void f_taglist(typval_T *argvars, typval_T *rettv)
+static void f_taglist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *tag_pattern;
+ const char *const tag_pattern = tv_get_string(&argvars[0]);
- tag_pattern = get_tv_string(&argvars[0]);
-
- rettv->vval.v_number = FALSE;
- if (*tag_pattern == NUL)
+ rettv->vval.v_number = false;
+ if (*tag_pattern == NUL) {
return;
+ }
- (void)get_tags(rettv_list_alloc(rettv), tag_pattern);
+ const char *fname = NULL;
+ if (argvars[1].v_type != VAR_UNKNOWN) {
+ fname = tv_get_string(&argvars[1]);
+ }
+ (void)get_tags(tv_list_alloc_ret(rettv, kListLenUnknown),
+ (char_u *)tag_pattern, (char_u *)fname);
}
/*
* "tempname()" function
*/
-static void f_tempname(typval_T *argvars, typval_T *rettv)
+static void f_tempname(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_tempname();
}
// "termopen(cmd[, cwd])" function
-static void f_termopen(typval_T *argvars, typval_T *rettv)
+static void f_termopen(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (check_restricted() || check_secure()) {
return;
@@ -16523,9 +16755,11 @@ static void f_termopen(typval_T *argvars, typval_T *rettv)
return;
}
- char *cmd;
- char **argv = tv_to_argv(&argvars[0], &cmd);
+ const char *cmd;
+ bool executable = true;
+ char **argv = tv_to_argv(&argvars[0], &cmd, &executable);
if (!argv) {
+ rettv->vval.v_number = executable ? 0 : -1;
return; // Did error message in tv_to_argv.
}
@@ -16536,17 +16770,19 @@ static void f_termopen(typval_T *argvars, typval_T *rettv)
return;
}
- ufunc_T *on_stdout = NULL, *on_stderr = NULL, *on_exit = NULL;
+ CallbackReader on_stdout = CALLBACK_READER_INIT,
+ on_stderr = CALLBACK_READER_INIT;
+ Callback on_exit = CALLBACK_NONE;
dict_T *job_opts = NULL;
- char *cwd = ".";
+ const char *cwd = ".";
if (argvars[1].v_type == VAR_DICT) {
job_opts = argvars[1].vval.v_dict;
- char *new_cwd = (char *)get_dict_string(job_opts, (char_u *)"cwd", false);
- if (new_cwd && strlen(new_cwd) > 0) {
+ const char *const new_cwd = tv_dict_get_string(job_opts, "cwd", false);
+ if (new_cwd && *new_cwd != NUL) {
cwd = new_cwd;
// The new cwd must be a directory.
- if (!os_isdir((char_u *)cwd)) {
+ if (!os_isdir_executable((const char *)cwd)) {
EMSG2(_(e_invarg2), "expected valid directory");
shell_free_argv(argv);
return;
@@ -16559,23 +16795,17 @@ static void f_termopen(typval_T *argvars, typval_T *rettv)
}
}
- TerminalJobData *data = common_job_init(argv, on_stdout, on_stderr, on_exit,
- job_opts, true, false, cwd);
- data->proc.pty.width = curwin->w_width;
- data->proc.pty.height = curwin->w_height;
- data->proc.pty.term_name = xstrdup("xterm-256color");
- if (!common_job_start(data, rettv)) {
+ uint16_t term_width = MAX(0, curwin->w_grid.Columns - win_col_off(curwin));
+ Channel *chan = channel_job_start(argv, on_stdout, on_stderr, on_exit,
+ true, false, false, cwd,
+ term_width, curwin->w_grid.Rows,
+ xstrdup("xterm-256color"),
+ &rettv->vval.v_number);
+ if (rettv->vval.v_number <= 0) {
return;
}
- TerminalOptions topts;
- topts.data = data;
- topts.width = curwin->w_width;
- topts.height = curwin->w_height;
- topts.write_cb = term_write;
- topts.resize_cb = term_resize;
- topts.close_cb = term_close;
- int pid = data->proc.pty.process.pid;
+ int pid = chan->stream.pty.process.pid;
char buf[1024];
// format the title with the pid to conform with the term:// URI
@@ -16583,50 +16813,218 @@ static void f_termopen(typval_T *argvars, typval_T *rettv)
// at this point the buffer has no terminal instance associated yet, so unset
// the 'swapfile' option to ensure no swap file will be created
curbuf->b_p_swf = false;
- (void)setfname(curbuf, (uint8_t *)buf, NULL, true);
+ (void)setfname(curbuf, (char_u *)buf, NULL, true);
// Save the job id and pid in b:terminal_job_{id,pid}
- Error err;
- dict_set_value(curbuf->b_vars, cstr_as_string("terminal_job_id"),
- INTEGER_OBJ(rettv->vval.v_number), false, &err);
- dict_set_value(curbuf->b_vars, cstr_as_string("terminal_job_pid"),
- INTEGER_OBJ(pid), false, &err);
+ Error err = ERROR_INIT;
+ // deprecated: use 'channel' buffer option
+ dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_id"),
+ INTEGER_OBJ(chan->id), false, false, &err);
+ api_clear_error(&err);
+ dict_set_var(curbuf->b_vars, cstr_as_string("terminal_job_pid"),
+ INTEGER_OBJ(pid), false, false, &err);
+ api_clear_error(&err);
- Terminal *term = terminal_open(topts);
- data->term = term;
- data->refcount++;
+ channel_terminal_open(chan);
+ channel_create_event(chan, NULL);
+}
- return;
+// "test_garbagecollect_now()" function
+static void f_test_garbagecollect_now(typval_T *argvars,
+ typval_T *rettv, FunPtr fptr)
+{
+ // This is dangerous, any Lists and Dicts used internally may be freed
+ // while still in use.
+ garbage_collect(true);
}
-/*
- * "test(list)" function: Just checking the walls...
- */
-static void f_test(typval_T *argvars, typval_T *rettv)
+// "test_write_list_log()" function
+static void f_test_write_list_log(typval_T *const argvars,
+ typval_T *const rettv,
+ FunPtr fptr)
{
- /* Used for unit testing. Change the code below to your liking. */
+ const char *const fname = tv_get_string_chk(&argvars[0]);
+ if (fname == NULL) {
+ return;
+ }
+ list_write_log(fname);
}
-/*
- * "tan()" function
- */
-static void f_tan(typval_T *argvars, typval_T *rettv)
+bool callback_from_typval(Callback *const callback, typval_T *const arg)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- float_op_wrapper(argvars, rettv, &tan);
+ if (arg->v_type == VAR_PARTIAL && arg->vval.v_partial != NULL) {
+ callback->data.partial = arg->vval.v_partial;
+ callback->data.partial->pt_refcount++;
+ callback->type = kCallbackPartial;
+ } else if (arg->v_type == VAR_FUNC || arg->v_type == VAR_STRING) {
+ char_u *name = arg->vval.v_string;
+ func_ref(name);
+ callback->data.funcref = vim_strsave(name);
+ callback->type = kCallbackFuncref;
+ } else if (arg->v_type == VAR_NUMBER && arg->vval.v_number == 0) {
+ callback->type = kCallbackNone;
+ } else {
+ EMSG(_("E921: Invalid callback argument"));
+ return false;
+ }
+ return true;
}
-/*
- * "tanh()" function
- */
-static void f_tanh(typval_T *argvars, typval_T *rettv)
+bool callback_call(Callback *const callback, const int argcount_in,
+ typval_T *const argvars_in, typval_T *const rettv)
+ FUNC_ATTR_NONNULL_ALL
{
- float_op_wrapper(argvars, rettv, &tanh);
+ partial_T *partial;
+ char_u *name;
+ switch (callback->type) {
+ case kCallbackFuncref:
+ name = callback->data.funcref;
+ partial = NULL;
+ break;
+
+ case kCallbackPartial:
+ partial = callback->data.partial;
+ name = partial_name(partial);
+ break;
+
+ case kCallbackNone:
+ return false;
+ break;
+
+ default:
+ abort();
+ }
+
+ int dummy;
+ return call_func(name, (int)STRLEN(name), rettv, argcount_in, argvars_in,
+ NULL, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy,
+ true, partial, NULL);
}
+static bool set_ref_in_callback(Callback *callback, int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ typval_T tv;
+ switch (callback->type) {
+ case kCallbackFuncref:
+ case kCallbackNone:
+ break;
+
+ case kCallbackPartial:
+ tv.v_type = VAR_PARTIAL;
+ tv.vval.v_partial = callback->data.partial;
+ return set_ref_in_item(&tv, copyID, ht_stack, list_stack);
+ break;
+
+
+ default:
+ abort();
+ }
+ return false;
+}
+
+static bool set_ref_in_callback_reader(CallbackReader *reader, int copyID,
+ ht_stack_T **ht_stack,
+ list_stack_T **list_stack)
+{
+ if (set_ref_in_callback(&reader->cb, copyID, ht_stack, list_stack)) {
+ return true;
+ }
+
+ if (reader->self) {
+ typval_T tv;
+ tv.v_type = VAR_DICT;
+ tv.vval.v_dict = reader->self;
+ return set_ref_in_item(&tv, copyID, ht_stack, list_stack);
+ }
+ return false;
+}
+
+static void add_timer_info(typval_T *rettv, timer_T *timer)
+{
+ list_T *list = rettv->vval.v_list;
+ dict_T *dict = tv_dict_alloc();
+
+ tv_list_append_dict(list, dict);
+ tv_dict_add_nr(dict, S_LEN("id"), timer->timer_id);
+ tv_dict_add_nr(dict, S_LEN("time"), timer->timeout);
+ tv_dict_add_nr(dict, S_LEN("paused"), timer->paused);
+
+ tv_dict_add_nr(dict, S_LEN("repeat"),
+ (timer->repeat_count < 0 ? -1 : timer->repeat_count));
+
+ dictitem_T *di = tv_dict_item_alloc("callback");
+ if (tv_dict_add(dict, di) == FAIL) {
+ xfree(di);
+ return;
+ }
+
+ if (timer->callback.type == kCallbackPartial) {
+ di->di_tv.v_type = VAR_PARTIAL;
+ di->di_tv.vval.v_partial = timer->callback.data.partial;
+ timer->callback.data.partial->pt_refcount++;
+ } else if (timer->callback.type == kCallbackFuncref) {
+ di->di_tv.v_type = VAR_FUNC;
+ di->di_tv.vval.v_string = vim_strsave(timer->callback.data.funcref);
+ }
+ di->di_tv.v_lock = 0;
+}
+
+static void add_timer_info_all(typval_T *rettv)
+{
+ timer_T *timer;
+ map_foreach_value(timers, timer, {
+ if (!timer->stopped) {
+ add_timer_info(rettv, timer);
+ }
+ })
+}
+
+/// "timer_info([timer])" function
+static void f_timer_info(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tv_list_alloc_ret(rettv, (argvars[0].v_type != VAR_UNKNOWN
+ ? 1
+ : timers->table->n_occupied));
+ if (argvars[0].v_type != VAR_UNKNOWN) {
+ if (argvars[0].v_type != VAR_NUMBER) {
+ EMSG(_(e_number_exp));
+ return;
+ }
+ timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0]));
+ if (timer != NULL && !timer->stopped) {
+ add_timer_info(rettv, timer);
+ }
+ } else {
+ add_timer_info_all(rettv);
+ }
+}
+
+/// "timer_pause(timer, paused)" function
+static void f_timer_pause(typval_T *argvars, typval_T *unused, FunPtr fptr)
+{
+ if (argvars[0].v_type != VAR_NUMBER) {
+ EMSG(_(e_number_exp));
+ return;
+ }
+ int paused = (bool)tv_get_number(&argvars[1]);
+ timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0]));
+ if (timer != NULL) {
+ if (!timer->paused && paused) {
+ time_watcher_stop(&timer->tw);
+ } else if (timer->paused && !paused) {
+ time_watcher_start(&timer->tw, timer_due_cb, timer->timeout,
+ timer->timeout);
+ }
+ timer->paused = paused;
+ }
+}
/// "timer_start(timeout, callback, opts)" function
-static void f_timer_start(typval_T *argvars, typval_T *rettv)
+static void f_timer_start(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- long timeout = get_tv_number(&argvars[0]);
+ const long timeout = tv_get_number(&argvars[0]);
timer_T *timer;
int repeat = 1;
dict_T *dict;
@@ -16636,41 +17034,37 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv)
if (argvars[2].v_type != VAR_UNKNOWN) {
if (argvars[2].v_type != VAR_DICT
|| (dict = argvars[2].vval.v_dict) == NULL) {
- EMSG2(_(e_invarg2), get_tv_string(&argvars[2]));
+ EMSG2(_(e_invarg2), tv_get_string(&argvars[2]));
return;
}
- if (dict_find(dict, (char_u *)"repeat", -1) != NULL) {
- repeat = get_dict_number(dict, (char_u *)"repeat");
+ dictitem_T *const di = tv_dict_find(dict, S_LEN("repeat"));
+ if (di != NULL) {
+ repeat = tv_get_number(&di->di_tv);
if (repeat == 0) {
repeat = 1;
}
}
}
- if (argvars[1].v_type != VAR_FUNC && argvars[1].v_type != VAR_STRING) {
- EMSG2(e_invarg2, "funcref");
- return;
- }
- ufunc_T *func = find_ufunc(argvars[1].vval.v_string);
- if (!func) {
- // Invalid function name. Error already reported by `find_ufunc`.
+ Callback callback;
+ if (!callback_from_typval(&callback, &argvars[1])) {
return;
}
- func->uf_refcount++;
timer = xmalloc(sizeof *timer);
+ timer->refcount = 1;
timer->stopped = false;
+ timer->paused = false;
timer->repeat_count = repeat;
timer->timeout = timeout;
timer->timer_id = last_timer_id++;
- timer->callback = func;
+ timer->callback = callback;
time_watcher_init(&main_loop, &timer->tw, timer);
- timer->tw.events = queue_new_child(main_loop.events);
+ timer->tw.events = multiqueue_new_child(main_loop.events);
// if main loop is blocked, don't queue up multiple events
timer->tw.blockable = true;
- time_watcher_start(&timer->tw, timer_due_cb, timeout,
- timeout * (repeat != 1));
+ time_watcher_start(&timer->tw, timer_due_cb, timeout, timeout);
pmap_put(uint64_t)(timers, timer->timer_id, timer);
rettv->vval.v_number = timer->timer_id;
@@ -16678,14 +17072,14 @@ static void f_timer_start(typval_T *argvars, typval_T *rettv)
// "timer_stop(timerid)" function
-static void f_timer_stop(typval_T *argvars, typval_T *rettv)
+static void f_timer_stop(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (argvars[0].v_type != VAR_NUMBER) {
EMSG(_(e_number_exp));
return;
}
- timer_T *timer = pmap_get(uint64_t)(timers, get_tv_number(&argvars[0]));
+ timer_T *timer = pmap_get(uint64_t)(timers, tv_get_number(&argvars[0]));
if (timer == NULL) {
return;
@@ -16694,28 +17088,32 @@ static void f_timer_stop(typval_T *argvars, typval_T *rettv)
timer_stop(timer);
}
+static void f_timer_stopall(typval_T *argvars, typval_T *unused, FunPtr fptr)
+{
+ timer_stop_all();
+}
+
// invoked on the main loop
static void timer_due_cb(TimeWatcher *tw, void *data)
{
timer_T *timer = (timer_T *)data;
- if (timer->stopped) {
+ if (timer->stopped || timer->paused) {
return;
}
+
+ timer->refcount++;
// if repeat was negative repeat forever
if (timer->repeat_count >= 0 && --timer->repeat_count == 0) {
timer_stop(timer);
}
- typval_T argv[1];
- init_tv(argv);
+ typval_T argv[2] = { TV_INITIAL_VALUE, TV_INITIAL_VALUE };
argv[0].v_type = VAR_NUMBER;
argv[0].vval.v_number = timer->timer_id;
- typval_T rettv;
+ typval_T rettv = TV_INITIAL_VALUE;
- init_tv(&rettv);
- call_user_func(timer->callback, ARRAY_SIZE(argv), argv, &rettv,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum, NULL);
- clear_tv(&rettv);
+ callback_call(&timer->callback, 1, argv, &rettv);
+ tv_clear(&rettv);
if (!timer->stopped && timer->timeout == 0) {
// special case: timeout=0 means the callback will be
@@ -16724,6 +17122,7 @@ static void timer_due_cb(TimeWatcher *tw, void *data)
// when the main loop is blocked.
time_watcher_start(&timer->tw, timer_due_cb, 0, 0);
}
+ timer_decref(timer);
}
static void timer_stop(timer_T *timer)
@@ -16734,20 +17133,28 @@ static void timer_stop(timer_T *timer)
}
timer->stopped = true;
time_watcher_stop(&timer->tw);
- time_watcher_close(&timer->tw, timer_free_cb);
+ time_watcher_close(&timer->tw, timer_close_cb);
}
-// invoked on next event loop tick, so queue is empty
-static void timer_free_cb(TimeWatcher *tw, void *data)
+// This will be run on the main loop after the last timer_due_cb, so at this
+// point it is safe to free the callback.
+static void timer_close_cb(TimeWatcher *tw, void *data)
{
timer_T *timer = (timer_T *)data;
- queue_free(timer->tw.events);
- user_func_unref(timer->callback);
+ multiqueue_free(timer->tw.events);
+ callback_free(&timer->callback);
pmap_del(uint64_t)(timers, timer->timer_id);
- xfree(timer);
+ timer_decref(timer);
}
-void timer_teardown(void)
+static void timer_decref(timer_T *timer)
+{
+ if (--timer->refcount == 0) {
+ xfree(timer);
+ }
+}
+
+static void timer_stop_all(void)
{
timer_T *timer;
map_foreach_value(timers, timer, {
@@ -16755,122 +17162,101 @@ void timer_teardown(void)
})
}
+void timer_teardown(void)
+{
+ timer_stop_all();
+}
+
/*
* "tolower(string)" function
*/
-static void f_tolower(typval_T *argvars, typval_T *rettv)
+static void f_tolower(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *p = vim_strsave(get_tv_string(&argvars[0]));
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = p;
-
- while (*p != NUL) {
- int l;
-
- if (enc_utf8) {
- int c, lc;
-
- c = utf_ptr2char(p);
- lc = utf_tolower(c);
- l = utf_ptr2len(p);
- /* TODO: reallocate string when byte count changes. */
- if (utf_char2len(lc) == l)
- utf_char2bytes(lc, p);
- p += l;
- } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
- p += l; /* skip multi-byte character */
- else {
- *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
- ++p;
- }
- }
+ rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
+ false);
}
/*
* "toupper(string)" function
*/
-static void f_toupper(typval_T *argvars, typval_T *rettv)
+static void f_toupper(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = strup_save(get_tv_string(&argvars[0]));
+ rettv->vval.v_string = (char_u *)strcase_save(tv_get_string(&argvars[0]),
+ true);
}
/*
* "tr(string, fromstr, tostr)" function
*/
-static void f_tr(typval_T *argvars, typval_T *rettv)
+static void f_tr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- char_u *in_str;
- char_u *fromstr;
- char_u *tostr;
- char_u *p;
- int inlen;
- int fromlen;
- int tolen;
- int idx;
- char_u *cpstr;
- int cplen;
- int first = TRUE;
- char_u buf[NUMBUFLEN];
- char_u buf2[NUMBUFLEN];
- garray_T ga;
+ char buf[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
- in_str = get_tv_string(&argvars[0]);
- fromstr = get_tv_string_buf_chk(&argvars[1], buf);
- tostr = get_tv_string_buf_chk(&argvars[2], buf2);
+ const char *in_str = tv_get_string(&argvars[0]);
+ const char *fromstr = tv_get_string_buf_chk(&argvars[1], buf);
+ const char *tostr = tv_get_string_buf_chk(&argvars[2], buf2);
- /* Default return value: empty string. */
+ // Default return value: empty string.
rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL;
- if (fromstr == NULL || tostr == NULL)
- return; /* type error; errmsg already given */
+ if (fromstr == NULL || tostr == NULL) {
+ return; // Type error; errmsg already given.
+ }
+ garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
- if (!has_mbyte)
- /* not multi-byte: fromstr and tostr must be the same length */
- if (STRLEN(fromstr) != STRLEN(tostr)) {
-error:
- EMSG2(_(e_invarg2), fromstr);
- ga_clear(&ga);
- return;
+ if (!has_mbyte) {
+ // Not multi-byte: fromstr and tostr must be the same length.
+ if (strlen(fromstr) != strlen(tostr)) {
+ goto error;
}
+ }
- /* fromstr and tostr have to contain the same number of chars */
+ // fromstr and tostr have to contain the same number of chars.
+ bool first = true;
while (*in_str != NUL) {
if (has_mbyte) {
- inlen = (*mb_ptr2len)(in_str);
- cpstr = in_str;
- cplen = inlen;
- idx = 0;
- for (p = fromstr; *p != NUL; p += fromlen) {
- fromlen = (*mb_ptr2len)(p);
+ const char *cpstr = in_str;
+ const int inlen = (*mb_ptr2len)((const char_u *)in_str);
+ int cplen = inlen;
+ int idx = 0;
+ int fromlen;
+ for (const char *p = fromstr; *p != NUL; p += fromlen) {
+ fromlen = (*mb_ptr2len)((const char_u *)p);
if (fromlen == inlen && STRNCMP(in_str, p, inlen) == 0) {
+ int tolen;
for (p = tostr; *p != NUL; p += tolen) {
- tolen = (*mb_ptr2len)(p);
+ tolen = (*mb_ptr2len)((const char_u *)p);
if (idx-- == 0) {
cplen = tolen;
- cpstr = p;
+ cpstr = (char *)p;
break;
}
}
- if (*p == NUL) /* tostr is shorter than fromstr */
+ if (*p == NUL) { // tostr is shorter than fromstr.
goto error;
+ }
break;
}
- ++idx;
+ idx++;
}
if (first && cpstr == in_str) {
- /* Check that fromstr and tostr have the same number of
- * (multi-byte) characters. Done only once when a character
- * of in_str doesn't appear in fromstr. */
- first = FALSE;
- for (p = tostr; *p != NUL; p += tolen) {
- tolen = (*mb_ptr2len)(p);
- --idx;
+ // Check that fromstr and tostr have the same number of
+ // (multi-byte) characters. Done only once when a character
+ // of in_str doesn't appear in fromstr.
+ first = false;
+ int tolen;
+ for (const char *p = tostr; *p != NUL; p += tolen) {
+ tolen = (*mb_ptr2len)((const char_u *)p);
+ idx--;
}
- if (idx != 0)
+ if (idx != 0) {
goto error;
+ }
}
ga_grow(&ga, cplen);
@@ -16879,13 +17265,14 @@ error:
in_str += inlen;
} else {
- /* When not using multi-byte chars we can do it faster. */
- p = vim_strchr(fromstr, *in_str);
- if (p != NULL)
+ // When not using multi-byte chars we can do it faster.
+ const char *const p = strchr(fromstr, *in_str);
+ if (p != NULL) {
ga_append(&ga, tostr[p - fromstr]);
- else
+ } else {
ga_append(&ga, *in_str);
- ++in_str;
+ }
+ in_str++;
}
}
@@ -16893,35 +17280,96 @@ error:
ga_append(&ga, NUL);
rettv->vval.v_string = ga.ga_data;
+ return;
+error:
+ EMSG2(_(e_invarg2), fromstr);
+ ga_clear(&ga);
+ return;
}
-/*
- * "trunc({float})" function
- */
-static void f_trunc(typval_T *argvars, typval_T *rettv)
+// "trim({expr})" function
+static void f_trim(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- float_op_wrapper(argvars, rettv, &trunc);
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char_u *head = (const char_u *)tv_get_string_buf_chk(&argvars[0], buf1);
+ const char_u *mask = NULL;
+ const char_u *tail;
+ const char_u *prev;
+ const char_u *p;
+ int c1;
+
+ rettv->v_type = VAR_STRING;
+ if (head == NULL) {
+ rettv->vval.v_string = NULL;
+ return;
+ }
+
+ if (argvars[1].v_type == VAR_STRING) {
+ mask = (const char_u *)tv_get_string_buf_chk(&argvars[1], buf2);
+ }
+
+ while (*head != NUL) {
+ c1 = PTR2CHAR(head);
+ if (mask == NULL) {
+ if (c1 > ' ' && c1 != 0xa0) {
+ break;
+ }
+ } else {
+ for (p = mask; *p != NUL; MB_PTR_ADV(p)) {
+ if (c1 == PTR2CHAR(p)) {
+ break;
+ }
+ }
+ if (*p == NUL) {
+ break;
+ }
+ }
+ MB_PTR_ADV(head);
+ }
+
+ for (tail = head + STRLEN(head); tail > head; tail = prev) {
+ prev = tail;
+ MB_PTR_BACK(head, prev);
+ c1 = PTR2CHAR(prev);
+ if (mask == NULL) {
+ if (c1 > ' ' && c1 != 0xa0) {
+ break;
+ }
+ } else {
+ for (p = mask; *p != NUL; MB_PTR_ADV(p)) {
+ if (c1 == PTR2CHAR(p)) {
+ break;
+ }
+ }
+ if (*p == NUL) {
+ break;
+ }
+ }
+ }
+ rettv->vval.v_string = vim_strnsave(head, (int)(tail - head));
}
/*
* "type(expr)" function
*/
-static void f_type(typval_T *argvars, typval_T *rettv)
+static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int n = -1;
switch (argvars[0].v_type) {
- case VAR_NUMBER: n = 0; break;
- case VAR_STRING: n = 1; break;
- case VAR_FUNC: n = 2; break;
- case VAR_LIST: n = 3; break;
- case VAR_DICT: n = 4; break;
- case VAR_FLOAT: n = 5; break;
+ case VAR_NUMBER: n = VAR_TYPE_NUMBER; break;
+ case VAR_STRING: n = VAR_TYPE_STRING; break;
+ case VAR_PARTIAL:
+ case VAR_FUNC: n = VAR_TYPE_FUNC; break;
+ case VAR_LIST: n = VAR_TYPE_LIST; break;
+ case VAR_DICT: n = VAR_TYPE_DICT; break;
+ case VAR_FLOAT: n = VAR_TYPE_FLOAT; break;
case VAR_SPECIAL: {
switch (argvars[0].vval.v_special) {
case kSpecialVarTrue:
case kSpecialVarFalse: {
- n = 6;
+ n = VAR_TYPE_BOOL;
break;
}
case kSpecialVarNull: {
@@ -16932,7 +17380,7 @@ static void f_type(typval_T *argvars, typval_T *rettv)
break;
}
case VAR_UNKNOWN: {
- EMSG2(_(e_intern2), "f_type(UNKNOWN)");
+ internal_error("f_type(UNKNOWN)");
break;
}
}
@@ -16942,53 +17390,48 @@ static void f_type(typval_T *argvars, typval_T *rettv)
/*
* "undofile(name)" function
*/
-static void f_undofile(typval_T *argvars, typval_T *rettv)
+static void f_undofile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- {
- char_u *fname = get_tv_string(&argvars[0]);
+ const char *const fname = tv_get_string(&argvars[0]);
- if (*fname == NUL) {
- /* If there is no file name there will be no undo file. */
- rettv->vval.v_string = NULL;
- } else {
- char *ffname = FullName_save((char *)fname, false);
+ if (*fname == NUL) {
+ // If there is no file name there will be no undo file.
+ rettv->vval.v_string = NULL;
+ } else {
+ char *ffname = FullName_save(fname, false);
- if (ffname != NULL) {
- rettv->vval.v_string = (char_u *)u_get_undo_file_name(ffname, false);
- }
- xfree(ffname);
+ if (ffname != NULL) {
+ rettv->vval.v_string = (char_u *)u_get_undo_file_name(ffname, false);
}
+ xfree(ffname);
}
}
/*
* "undotree()" function
*/
-static void f_undotree(typval_T *argvars, typval_T *rettv)
+static void f_undotree(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
dict_T *dict = rettv->vval.v_dict;
- list_T *list;
- dict_add_nr_str(dict, "synced", (long)curbuf->b_u_synced, NULL);
- dict_add_nr_str(dict, "seq_last", curbuf->b_u_seq_last, NULL);
- dict_add_nr_str(dict, "save_last",
- (long)curbuf->b_u_save_nr_last, NULL);
- dict_add_nr_str(dict, "seq_cur", curbuf->b_u_seq_cur, NULL);
- dict_add_nr_str(dict, "time_cur", (long)curbuf->b_u_time_cur, NULL);
- dict_add_nr_str(dict, "save_cur", (long)curbuf->b_u_save_nr_cur, NULL);
+ tv_dict_add_nr(dict, S_LEN("synced"), (varnumber_T)curbuf->b_u_synced);
+ tv_dict_add_nr(dict, S_LEN("seq_last"), (varnumber_T)curbuf->b_u_seq_last);
+ tv_dict_add_nr(dict, S_LEN("save_last"),
+ (varnumber_T)curbuf->b_u_save_nr_last);
+ tv_dict_add_nr(dict, S_LEN("seq_cur"), (varnumber_T)curbuf->b_u_seq_cur);
+ tv_dict_add_nr(dict, S_LEN("time_cur"), (varnumber_T)curbuf->b_u_time_cur);
+ tv_dict_add_nr(dict, S_LEN("save_cur"), (varnumber_T)curbuf->b_u_save_nr_cur);
- list = list_alloc();
- u_eval_tree(curbuf->b_u_oldhead, list);
- dict_add_list(dict, "entries", list);
+ tv_dict_add_list(dict, S_LEN("entries"), u_eval_tree(curbuf->b_u_oldhead));
}
/*
* "values(dict)" function
*/
-static void f_values(typval_T *argvars, typval_T *rettv)
+static void f_values(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_list(argvars, rettv, 1);
}
@@ -16996,7 +17439,7 @@ static void f_values(typval_T *argvars, typval_T *rettv)
/*
* "virtcol(string)" function
*/
-static void f_virtcol(typval_T *argvars, typval_T *rettv)
+static void f_virtcol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
colnr_T vcol = 0;
pos_T *fp;
@@ -17015,7 +17458,7 @@ static void f_virtcol(typval_T *argvars, typval_T *rettv)
/*
* "visualmode()" function
*/
-static void f_visualmode(typval_T *argvars, typval_T *rettv)
+static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
char_u str[2];
@@ -17032,16 +17475,47 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv)
/*
* "wildmenumode()" function
*/
-static void f_wildmenumode(typval_T *argvars, typval_T *rettv)
+static void f_wildmenumode(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
if (wild_menu_showing)
rettv->vval.v_number = 1;
}
+/// "win_findbuf()" function
+static void f_win_findbuf(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ tv_list_alloc_ret(rettv, kListLenMayKnow);
+ win_findbuf(argvars, rettv->vval.v_list);
+}
+
+/// "win_getid()" function
+static void f_win_getid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->vval.v_number = win_getid(argvars);
+}
+
+/// "win_gotoid()" function
+static void f_win_gotoid(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->vval.v_number = win_gotoid(argvars);
+}
+
+/// "win_id2tabwin()" function
+static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ win_id2tabwin(argvars, rettv);
+}
+
+/// "win_id2win()" function
+static void f_win_id2win(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+{
+ rettv->vval.v_number = win_id2win(argvars);
+}
+
/*
* "winbufnr(nr)" function
*/
-static void f_winbufnr(typval_T *argvars, typval_T *rettv)
+static void f_winbufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp;
@@ -17055,7 +17529,7 @@ static void f_winbufnr(typval_T *argvars, typval_T *rettv)
/*
* "wincol()" function
*/
-static void f_wincol(typval_T *argvars, typval_T *rettv)
+static void f_wincol(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
validate_cursor();
rettv->vval.v_number = curwin->w_wcol + 1;
@@ -17064,7 +17538,7 @@ static void f_wincol(typval_T *argvars, typval_T *rettv)
/*
* "winheight(nr)" function
*/
-static void f_winheight(typval_T *argvars, typval_T *rettv)
+static void f_winheight(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp;
@@ -17078,7 +17552,7 @@ static void f_winheight(typval_T *argvars, typval_T *rettv)
/*
* "winline()" function
*/
-static void f_winline(typval_T *argvars, typval_T *rettv)
+static void f_winline(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
validate_cursor();
rettv->vval.v_number = curwin->w_wrow + 1;
@@ -17087,7 +17561,7 @@ static void f_winline(typval_T *argvars, typval_T *rettv)
/*
* "winnr()" function
*/
-static void f_winnr(typval_T *argvars, typval_T *rettv)
+static void f_winnr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int nr = 1;
@@ -17098,7 +17572,7 @@ static void f_winnr(typval_T *argvars, typval_T *rettv)
/*
* "winrestcmd()" function
*/
-static void f_winrestcmd(typval_T *argvars, typval_T *rettv)
+static void f_winrestcmd(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int winnr = 1;
garray_T ga;
@@ -17121,38 +17595,39 @@ static void f_winrestcmd(typval_T *argvars, typval_T *rettv)
/*
* "winrestview()" function
*/
-static void f_winrestview(typval_T *argvars, typval_T *rettv)
+static void f_winrestview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- dict_T *dict;
+ dict_T *dict;
if (argvars[0].v_type != VAR_DICT
- || (dict = argvars[0].vval.v_dict) == NULL)
+ || (dict = argvars[0].vval.v_dict) == NULL) {
EMSG(_(e_invarg));
- else {
- if (dict_find(dict, (char_u *)"lnum", -1) != NULL) {
- curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum");
+ } else {
+ dictitem_T *di;
+ if ((di = tv_dict_find(dict, S_LEN("lnum"))) != NULL) {
+ curwin->w_cursor.lnum = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"col", -1) != NULL) {
- curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col");
+ if ((di = tv_dict_find(dict, S_LEN("col"))) != NULL) {
+ curwin->w_cursor.col = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"coladd", -1) != NULL) {
- curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd");
+ if ((di = tv_dict_find(dict, S_LEN("coladd"))) != NULL) {
+ curwin->w_cursor.coladd = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"curswant", -1) != NULL) {
- curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
- curwin->w_set_curswant = FALSE;
+ if ((di = tv_dict_find(dict, S_LEN("curswant"))) != NULL) {
+ curwin->w_curswant = tv_get_number(&di->di_tv);
+ curwin->w_set_curswant = false;
}
- if (dict_find(dict, (char_u *)"topline", -1) != NULL) {
- set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
+ if ((di = tv_dict_find(dict, S_LEN("topline"))) != NULL) {
+ set_topline(curwin, tv_get_number(&di->di_tv));
}
- if (dict_find(dict, (char_u *)"topfill", -1) != NULL) {
- curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
+ if ((di = tv_dict_find(dict, S_LEN("topfill"))) != NULL) {
+ curwin->w_topfill = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"leftcol", -1) != NULL) {
- curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol");
+ if ((di = tv_dict_find(dict, S_LEN("leftcol"))) != NULL) {
+ curwin->w_leftcol = tv_get_number(&di->di_tv);
}
- if (dict_find(dict, (char_u *)"skipcol", -1) != NULL) {
- curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol");
+ if ((di = tv_dict_find(dict, S_LEN("skipcol"))) != NULL) {
+ curwin->w_skipcol = tv_get_number(&di->di_tv);
}
check_cursor();
@@ -17171,102 +17646,165 @@ static void f_winrestview(typval_T *argvars, typval_T *rettv)
/*
* "winsaveview()" function
*/
-static void f_winsaveview(typval_T *argvars, typval_T *rettv)
+static void f_winsaveview(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
dict_T *dict;
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
dict = rettv->vval.v_dict;
- dict_add_nr_str(dict, "lnum", (long)curwin->w_cursor.lnum, NULL);
- dict_add_nr_str(dict, "col", (long)curwin->w_cursor.col, NULL);
- dict_add_nr_str(dict, "coladd", (long)curwin->w_cursor.coladd, NULL);
+ tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)curwin->w_cursor.lnum);
+ tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)curwin->w_cursor.col);
+ tv_dict_add_nr(dict, S_LEN("coladd"), (varnumber_T)curwin->w_cursor.coladd);
update_curswant();
- dict_add_nr_str(dict, "curswant", (long)curwin->w_curswant, NULL);
+ tv_dict_add_nr(dict, S_LEN("curswant"), (varnumber_T)curwin->w_curswant);
- dict_add_nr_str(dict, "topline", (long)curwin->w_topline, NULL);
- dict_add_nr_str(dict, "topfill", (long)curwin->w_topfill, NULL);
- dict_add_nr_str(dict, "leftcol", (long)curwin->w_leftcol, NULL);
- dict_add_nr_str(dict, "skipcol", (long)curwin->w_skipcol, NULL);
+ tv_dict_add_nr(dict, S_LEN("topline"), (varnumber_T)curwin->w_topline);
+ tv_dict_add_nr(dict, S_LEN("topfill"), (varnumber_T)curwin->w_topfill);
+ tv_dict_add_nr(dict, S_LEN("leftcol"), (varnumber_T)curwin->w_leftcol);
+ tv_dict_add_nr(dict, S_LEN("skipcol"), (varnumber_T)curwin->w_skipcol);
}
-/// Writes list of strings to file
-static bool write_list(FILE *fd, list_T *list, bool binary)
+/// Write "list" of strings to file "fd".
+///
+/// @param fp File to write to.
+/// @param[in] list List to write.
+/// @param[in] binary Whether to write in binary mode.
+///
+/// @return true in case of success, false otherwise.
+static bool write_list(FileDescriptor *const fp, const list_T *const list,
+ const bool binary)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- int ret = true;
-
- for (listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
- for (char_u *s = get_tv_string(&li->li_tv); *s != NUL; ++s) {
- if (putc(*s == '\n' ? NUL : *s, fd) == EOF) {
- ret = false;
- break;
+ int error = 0;
+ TV_LIST_ITER_CONST(list, li, {
+ const char *const s = tv_get_string_chk(TV_LIST_ITEM_TV(li));
+ if (s == NULL) {
+ return false;
+ }
+ const char *hunk_start = s;
+ for (const char *p = hunk_start;; p++) {
+ if (*p == NUL || *p == NL) {
+ if (p != hunk_start) {
+ const ptrdiff_t written = file_write(fp, hunk_start,
+ (size_t)(p - hunk_start));
+ if (written < 0) {
+ error = (int)written;
+ goto write_list_error;
+ }
+ }
+ if (*p == NUL) {
+ break;
+ } else {
+ hunk_start = p + 1;
+ const ptrdiff_t written = file_write(fp, (char[]){ NUL }, 1);
+ if (written < 0) {
+ error = (int)written;
+ break;
+ }
+ }
}
}
- if (!binary || li->li_next != NULL) {
- if (putc('\n', fd) == EOF) {
- ret = false;
- break;
+ if (!binary || TV_LIST_ITEM_NEXT(list, li) != NULL) {
+ const ptrdiff_t written = file_write(fp, "\n", 1);
+ if (written < 0) {
+ error = (int)written;
+ goto write_list_error;
}
}
- if (ret == false) {
- EMSG(_(e_write));
- break;
- }
+ });
+ if ((error = file_flush(fp)) != 0) {
+ goto write_list_error;
}
- return ret;
+ return true;
+write_list_error:
+ emsgf(_("E80: Error while writing: %s"), os_strerror(error));
+ return false;
}
/// Saves a typval_T as a string.
///
-/// For lists, replaces NLs with NUL and separates items with NLs.
+/// For lists or buffers, replaces NLs with NUL and separates items with NLs.
///
-/// @param[in] tv A value to store as a string.
-/// @param[out] len The length of the resulting string or -1 on error.
+/// @param[in] tv Value to store as a string.
+/// @param[out] len Length of the resulting string or -1 on error.
/// @param[in] endnl If true, the output will end in a newline (if a list).
/// @returns an allocated string if `tv` represents a VimL string, list, or
/// number; NULL otherwise.
-static char_u *save_tv_as_string(typval_T *tv, ssize_t *len, bool endnl)
+static char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl)
FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
+ *len = 0;
if (tv->v_type == VAR_UNKNOWN) {
- *len = 0;
return NULL;
}
- // For types other than list, let get_tv_string_buf_chk() get the value or
+ // For other types, let tv_get_string_buf_chk() get the value or
// print an error.
- if (tv->v_type != VAR_LIST) {
- char_u *ret = get_tv_string_chk(tv);
- if (ret && (*len = STRLEN(ret))) {
- ret = vim_strsave(ret);
+ if (tv->v_type != VAR_LIST && tv->v_type != VAR_NUMBER) {
+ const char *ret = tv_get_string_chk(tv);
+ if (ret) {
+ *len = strlen(ret);
+ return xmemdupz(ret, (size_t)(*len));
} else {
- ret = NULL;
*len = -1;
+ return NULL;
}
+ }
+
+ if (tv->v_type == VAR_NUMBER) { // Treat number as a buffer-id.
+ buf_T *buf = buflist_findnr(tv->vval.v_number);
+ if (buf) {
+ for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
+ for (char_u *p = ml_get_buf(buf, lnum, false); *p != NUL; p++) {
+ *len += 1;
+ }
+ *len += 1;
+ }
+ } else {
+ EMSGN(_(e_nobufnr), tv->vval.v_number);
+ *len = -1;
+ return NULL;
+ }
+
+ if (*len == 0) {
+ return NULL;
+ }
+
+ char *ret = xmalloc(*len + 1);
+ char *end = ret;
+ for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
+ for (char_u *p = ml_get_buf(buf, lnum, false); *p != NUL; p++) {
+ *end++ = (*p == '\n') ? NUL : *p;
+ }
+ *end++ = '\n';
+ }
+ *end = NUL;
+ *len = end - ret;
return ret;
}
+ assert(tv->v_type == VAR_LIST);
// Pre-calculate the resulting length.
- *len = 0;
list_T *list = tv->vval.v_list;
- for (listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
- *len += STRLEN(get_tv_string(&li->li_tv)) + 1;
- }
+ TV_LIST_ITER_CONST(list, li, {
+ *len += strlen(tv_get_string(TV_LIST_ITEM_TV(li))) + 1;
+ });
if (*len == 0) {
return NULL;
}
- char_u *ret = xmalloc(*len + endnl);
- char_u *end = ret;
- for (listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
- for (char_u *s = get_tv_string(&li->li_tv); *s != NUL; s++) {
+ char *ret = xmalloc(*len + endnl);
+ char *end = ret;
+ TV_LIST_ITER_CONST(list, li, {
+ for (const char *s = tv_get_string(TV_LIST_ITEM_TV(li)); *s != NUL; s++) {
*end++ = (*s == '\n') ? NUL : *s;
}
- if (endnl || li->li_next != NULL) {
+ if (endnl || TV_LIST_ITEM_NEXT(list, li) != NULL) {
*end++ = '\n';
}
- }
+ });
*end = NUL;
*len = end - ret;
return ret;
@@ -17275,7 +17813,7 @@ static char_u *save_tv_as_string(typval_T *tv, ssize_t *len, bool endnl)
/*
* "winwidth(nr)" function
*/
-static void f_winwidth(typval_T *argvars, typval_T *rettv)
+static void f_winwidth(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
win_T *wp;
@@ -17287,16 +17825,16 @@ static void f_winwidth(typval_T *argvars, typval_T *rettv)
}
/// "wordcount()" function
-static void f_wordcount(typval_T *argvars, typval_T *rettv)
+static void f_wordcount(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv_dict_alloc(rettv);
+ tv_dict_alloc_ret(rettv);
cursor_pos_info(rettv->vval.v_dict);
}
/// "writefile()" function
-static void f_writefile(typval_T *argvars, typval_T *rettv)
+static void f_writefile(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = 0; // Assuming success.
+ rettv->vval.v_number = -1;
if (check_restricted() || check_secure()) {
return;
@@ -17306,117 +17844,155 @@ static void f_writefile(typval_T *argvars, typval_T *rettv)
EMSG2(_(e_listarg), "writefile()");
return;
}
- if (argvars[0].vval.v_list == NULL) {
- return;
- }
+ const list_T *const list = argvars[0].vval.v_list;
+ TV_LIST_ITER_CONST(list, li, {
+ if (!tv_check_str_or_nr(TV_LIST_ITEM_TV(li))) {
+ return;
+ }
+ });
bool binary = false;
bool append = false;
+ bool do_fsync = !!p_fs;
if (argvars[2].v_type != VAR_UNKNOWN) {
- if (vim_strchr(get_tv_string(&argvars[2]), 'b')) {
- binary = true;
+ const char *const flags = tv_get_string_chk(&argvars[2]);
+ if (flags == NULL) {
+ return;
}
- if (vim_strchr(get_tv_string(&argvars[2]), 'a')) {
- append = true;
+ for (const char *p = flags; *p; p++) {
+ switch (*p) {
+ case 'b': { binary = true; break; }
+ case 'a': { append = true; break; }
+ case 's': { do_fsync = true; break; }
+ case 'S': { do_fsync = false; break; }
+ default: {
+ // Using %s, p and not %c, *p to preserve multibyte characters
+ emsgf(_("E5060: Unknown flag: %s"), p);
+ return;
+ }
+ }
}
}
- // Always open the file in binary mode, library functions have a mind of
- // their own about CR-LF conversion.
- char_u *fname = get_tv_string(&argvars[1]);
- FILE *fd;
- if (*fname == NUL || (fd = mch_fopen((char *)fname,
- append ? APPENDBIN : WRITEBIN)) == NULL) {
- EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname);
- rettv->vval.v_number = -1;
+ char buf[NUMBUFLEN];
+ const char *const fname = tv_get_string_buf_chk(&argvars[1], buf);
+ if (fname == NULL) {
+ return;
+ }
+ FileDescriptor fp;
+ int error;
+ if (*fname == NUL) {
+ EMSG(_("E482: Can't open file with an empty name"));
+ } else if ((error = file_open(&fp, fname,
+ ((append ? kFileAppend : kFileTruncate)
+ | kFileCreate), 0666)) != 0) {
+ emsgf(_("E482: Can't open file %s for writing: %s"),
+ fname, os_strerror(error));
} else {
- if (write_list(fd, argvars[0].vval.v_list, binary) == false) {
- rettv->vval.v_number = -1;
+ if (write_list(&fp, list, binary)) {
+ rettv->vval.v_number = 0;
+ }
+ if ((error = file_close(&fp, do_fsync)) != 0) {
+ emsgf(_("E80: Error when closing file %s: %s"),
+ fname, os_strerror(error));
}
- fclose(fd);
}
}
/*
* "xor(expr, expr)" function
*/
-static void f_xor(typval_T *argvars, typval_T *rettv)
+static void f_xor(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL)
- ^ get_tv_number_chk(&argvars[1], NULL);
+ rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
+ ^ tv_get_number_chk(&argvars[1], NULL);
}
-/*
- * Translate a String variable into a position.
- * Returns NULL when there is an error.
- */
-static pos_T *
-var2fpos (
- typval_T *varp,
- int dollar_lnum, /* TRUE when $ is last line */
- int *fnum /* set to fnum for '0, 'A, etc. */
-)
+/// Translate a VimL object into a position
+///
+/// Accepts VAR_LIST and VAR_STRING objects. Does not give an error for invalid
+/// type.
+///
+/// @param[in] tv Object to translate.
+/// @param[in] dollar_lnum True when "$" is last line.
+/// @param[out] ret_fnum Set to fnum for marks.
+///
+/// @return Pointer to position or NULL in case of error (e.g. invalid type).
+pos_T *var2fpos(const typval_T *const tv, const int dollar_lnum,
+ int *const ret_fnum)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- char_u *name;
static pos_T pos;
pos_T *pp;
- /* Argument can be [lnum, col, coladd]. */
- if (varp->v_type == VAR_LIST) {
+ // Argument can be [lnum, col, coladd].
+ if (tv->v_type == VAR_LIST) {
list_T *l;
int len;
- int error = FALSE;
- listitem_T *li;
+ bool error = false;
+ listitem_T *li;
- l = varp->vval.v_list;
- if (l == NULL)
+ l = tv->vval.v_list;
+ if (l == NULL) {
return NULL;
+ }
- /* Get the line number */
- pos.lnum = list_find_nr(l, 0L, &error);
- if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count)
- return NULL; /* invalid line number */
+ // Get the line number.
+ pos.lnum = tv_list_find_nr(l, 0L, &error);
+ if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) {
+ // Invalid line number.
+ return NULL;
+ }
- /* Get the column number */
- pos.col = list_find_nr(l, 1L, &error);
- if (error)
+ // Get the column number.
+ pos.col = tv_list_find_nr(l, 1L, &error);
+ if (error) {
return NULL;
+ }
len = (long)STRLEN(ml_get(pos.lnum));
- /* We accept "$" for the column number: last column. */
- li = list_find(l, 1L);
- if (li != NULL && li->li_tv.v_type == VAR_STRING
- && li->li_tv.vval.v_string != NULL
- && STRCMP(li->li_tv.vval.v_string, "$") == 0)
+ // We accept "$" for the column number: last column.
+ li = tv_list_find(l, 1L);
+ if (li != NULL && TV_LIST_ITEM_TV(li)->v_type == VAR_STRING
+ && TV_LIST_ITEM_TV(li)->vval.v_string != NULL
+ && STRCMP(TV_LIST_ITEM_TV(li)->vval.v_string, "$") == 0) {
pos.col = len + 1;
+ }
- /* Accept a position up to the NUL after the line. */
- if (pos.col == 0 || (int)pos.col > len + 1)
- return NULL; /* invalid column number */
- --pos.col;
+ // Accept a position up to the NUL after the line.
+ if (pos.col == 0 || (int)pos.col > len + 1) {
+ // Invalid column number.
+ return NULL;
+ }
+ pos.col--;
- /* Get the virtual offset. Defaults to zero. */
- pos.coladd = list_find_nr(l, 2L, &error);
- if (error)
+ // Get the virtual offset. Defaults to zero.
+ pos.coladd = tv_list_find_nr(l, 2L, &error);
+ if (error) {
pos.coladd = 0;
+ }
return &pos;
}
- name = get_tv_string_chk(varp);
- if (name == NULL)
+ const char *const name = tv_get_string_chk(tv);
+ if (name == NULL) {
return NULL;
- if (name[0] == '.') /* cursor */
+ }
+ if (name[0] == '.') { // Cursor.
return &curwin->w_cursor;
- if (name[0] == 'v' && name[1] == NUL) { /* Visual start */
- if (VIsual_active)
+ }
+ if (name[0] == 'v' && name[1] == NUL) { // Visual start.
+ if (VIsual_active) {
return &VIsual;
+ }
return &curwin->w_cursor;
}
- if (name[0] == '\'') { /* mark */
- pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum);
- if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
+ if (name[0] == '\'') { // Mark.
+ pp = getmark_buf_fnum(curbuf, (uint8_t)name[1], false, ret_fnum);
+ if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) {
return NULL;
+ }
return pp;
}
@@ -17426,11 +18002,14 @@ var2fpos (
pos.col = 0;
if (name[1] == '0') { /* "w0": first visible line */
update_topline();
- pos.lnum = curwin->w_topline;
+ // In silent Ex mode topline is zero, but that's not a valid line
+ // number; use one instead.
+ pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1;
return &pos;
} else if (name[1] == '$') { /* "w$": last visible line */
validate_botline();
- pos.lnum = curwin->w_botline - 1;
+ // In silent Ex mode botline is zero, return zero then.
+ pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0;
return &pos;
}
} else if (name[0] == '$') { /* last column or line */
@@ -17456,45 +18035,51 @@ var2fpos (
*/
static int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp)
{
- list_T *l = arg->vval.v_list;
+ list_T *l;
long i = 0;
long n;
- /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only
- * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */
+ // List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only
+ // there when "fnump" isn't NULL; "coladd" and "curswant" are optional.
if (arg->v_type != VAR_LIST
- || l == NULL
- || l->lv_len < (fnump == NULL ? 2 : 3)
- || l->lv_len > (fnump == NULL ? 4 : 5))
+ || (l = arg->vval.v_list) == NULL
+ || tv_list_len(l) < (fnump == NULL ? 2 : 3)
+ || tv_list_len(l) > (fnump == NULL ? 4 : 5)) {
return FAIL;
+ }
if (fnump != NULL) {
- n = list_find_nr(l, i++, NULL); /* fnum */
- if (n < 0)
+ n = tv_list_find_nr(l, i++, NULL); // fnum
+ if (n < 0) {
return FAIL;
- if (n == 0)
- n = curbuf->b_fnum; /* current buffer */
+ }
+ if (n == 0) {
+ n = curbuf->b_fnum; // Current buffer.
+ }
*fnump = n;
}
- n = list_find_nr(l, i++, NULL); /* lnum */
- if (n < 0)
+ n = tv_list_find_nr(l, i++, NULL); // lnum
+ if (n < 0) {
return FAIL;
+ }
posp->lnum = n;
- n = list_find_nr(l, i++, NULL); /* col */
- if (n < 0)
+ n = tv_list_find_nr(l, i++, NULL); // col
+ if (n < 0) {
return FAIL;
+ }
posp->col = n;
- n = list_find_nr(l, i, NULL); // off
- if (n < 0)
+ n = tv_list_find_nr(l, i, NULL); // off
+ if (n < 0) {
posp->coladd = 0;
- else
+ } else {
posp->coladd = n;
+ }
if (curswantp != NULL) {
- *curswantp = list_find_nr(l, i + 1, NULL); // curswant
+ *curswantp = tv_list_find_nr(l, i + 1, NULL); // curswant
}
return OK;
@@ -17505,15 +18090,16 @@ static int list2fpos(typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp)
* Advance "arg" to the first character after the name.
* Return 0 for error.
*/
-static int get_env_len(char_u **arg)
+static int get_env_len(const char_u **arg)
{
- char_u *p;
int len;
- for (p = *arg; vim_isIDc(*p); ++p)
- ;
- if (p == *arg) /* no name found */
+ const char_u *p;
+ for (p = *arg; vim_isIDc(*p); p++) {
+ }
+ if (p == *arg) { // No name found.
return 0;
+ }
len = (int)(p - *arg);
*arg = p;
@@ -17523,11 +18109,12 @@ static int get_env_len(char_u **arg)
// Get the length of the name of a function or internal variable.
// "arg" is advanced to the first non-white character after the name.
// Return 0 if something is wrong.
-static int get_id_len(char_u **arg) {
- char_u *p;
+static int get_id_len(const char **const arg)
+{
int len;
// Find the end of the name.
+ const char *p;
for (p = *arg; eval_isnamec(*p); p++) {
if (*p == ':') {
// "s:" is start of "s:var", but "n:" is not and can be used in
@@ -17544,7 +18131,7 @@ static int get_id_len(char_u **arg) {
}
len = (int)(p - *arg);
- *arg = skipwhite(p);
+ *arg = (const char *)skipwhite((const char_u *)p);
return len;
}
@@ -17558,18 +18145,18 @@ static int get_id_len(char_u **arg) {
* If the name contains 'magic' {}'s, expand them and return the
* expanded name in an allocated string via 'alias' - caller must free.
*/
-static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
+static int get_name_len(const char **const arg,
+ char **alias,
+ int evaluate,
+ int verbose)
{
int len;
- char_u *p;
- char_u *expr_start;
- char_u *expr_end;
*alias = NULL; /* default to no alias */
- if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA
- && (*arg)[2] == (int)KE_SNR) {
- /* hard coded <SNR>, already translated */
+ if ((*arg)[0] == (char)K_SPECIAL && (*arg)[1] == (char)KS_EXTRA
+ && (*arg)[2] == (char)KE_SNR) {
+ // Hard coded <SNR>, already translated.
*arg += 3;
return get_id_len(arg) + 3;
}
@@ -17579,17 +18166,17 @@ static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
*arg += len;
}
- /*
- * Find the end of the name; check for {} construction.
- */
- p = find_name_end(*arg, &expr_start, &expr_end,
- len > 0 ? 0 : FNE_CHECK_START);
+ // Find the end of the name; check for {} construction.
+ char_u *expr_start;
+ char_u *expr_end;
+ const char *p = (const char *)find_name_end((char_u *)(*arg),
+ (const char_u **)&expr_start,
+ (const char_u **)&expr_end,
+ len > 0 ? 0 : FNE_CHECK_START);
if (expr_start != NULL) {
- char_u *temp_string;
-
if (!evaluate) {
len += (int)(p - *arg);
- *arg = skipwhite(p);
+ *arg = (const char *)skipwhite((const char_u *)p);
return len;
}
@@ -17597,11 +18184,13 @@ static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
* Include any <SID> etc in the expanded string:
* Thus the -len here.
*/
- temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p);
- if (temp_string == NULL)
+ char_u *temp_string = make_expanded_name((char_u *)(*arg) - len, expr_start,
+ expr_end, (char_u *)p);
+ if (temp_string == NULL) {
return -1;
- *alias = temp_string;
- *arg = skipwhite(p);
+ }
+ *alias = (char *)temp_string;
+ *arg = (const char *)skipwhite((const char_u *)p);
return (int)STRLEN(temp_string);
}
@@ -17618,12 +18207,11 @@ static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose)
// "flags" can have FNE_INCL_BR and FNE_CHECK_START.
// Return a pointer to just after the name. Equal to "arg" if there is no
// valid name.
-static char_u *find_name_end(char_u *arg, char_u **expr_start,
- char_u **expr_end, int flags)
+static const char_u *find_name_end(const char_u *arg, const char_u **expr_start,
+ const char_u **expr_end, int flags)
{
int mb_nest = 0;
int br_nest = 0;
- char_u *p;
int len;
if (expr_start != NULL) {
@@ -17636,21 +18224,23 @@ static char_u *find_name_end(char_u *arg, char_u **expr_start,
return arg;
}
+ const char_u *p;
for (p = arg; *p != NUL
&& (eval_isnamec(*p)
|| *p == '{'
|| ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.'))
|| mb_nest != 0
- || br_nest != 0); mb_ptr_adv(p)) {
+ || br_nest != 0); MB_PTR_ADV(p)) {
if (*p == '\'') {
- /* skip over 'string' to avoid counting [ and ] inside it. */
- for (p = p + 1; *p != NUL && *p != '\''; mb_ptr_adv(p))
- ;
- if (*p == NUL)
+ // skip over 'string' to avoid counting [ and ] inside it.
+ for (p = p + 1; *p != NUL && *p != '\''; MB_PTR_ADV(p)) {
+ }
+ if (*p == NUL) {
break;
+ }
} else if (*p == '"') {
// skip over "str\"ing" to avoid counting [ and ] inside it.
- for (p = p + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) {
+ for (p = p + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p)) {
if (*p == '\\' && p[1] != NUL) {
++p;
}
@@ -17707,7 +18297,8 @@ static char_u *find_name_end(char_u *arg, char_u **expr_start,
* Returns a new allocated string, which the caller must free.
* Returns NULL for failure.
*/
-static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)
+static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start,
+ char_u *expr_end, char_u *in_end)
{
char_u c1;
char_u *retval = NULL;
@@ -17736,7 +18327,9 @@ static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *
*expr_end = '}';
if (retval != NULL) {
- temp_result = find_name_end(retval, &expr_start, &expr_end, 0);
+ temp_result = (char_u *)find_name_end(retval,
+ (const char_u **)&expr_start,
+ (const char_u **)&expr_end, 0);
if (expr_start != NULL) {
/* Further expansion! */
temp_result = make_expanded_name(retval, expr_start,
@@ -17770,17 +18363,17 @@ static int eval_isnamec1(int c)
/*
* Get number v: variable value.
*/
-long get_vim_var_nr(int idx) FUNC_ATTR_PURE
+varnumber_T get_vim_var_nr(int idx) FUNC_ATTR_PURE
{
return vimvars[idx].vv_nr;
}
-/*
- * Get string v: variable value. Uses a static buffer, can only be used once.
- */
+// Get string v: variable value. Uses a static buffer, can only be used once.
+// If the String variable has never been set, return an empty string.
+// Never returns NULL;
char_u *get_vim_var_str(int idx) FUNC_ATTR_PURE FUNC_ATTR_NONNULL_RET
{
- return get_tv_string(&vimvars[idx].vv_tv);
+ return (char_u *)tv_get_string(&vimvars[idx].vv_tv);
}
/*
@@ -17806,12 +18399,7 @@ void set_vim_var_char(int c)
{
char buf[MB_MAXBYTES + 1];
- if (has_mbyte) {
- buf[(*mb_char2bytes)(c, (char_u *) buf)] = NUL;
- } else {
- buf[0] = c;
- buf[1] = NUL;
- }
+ buf[utf_char2bytes(c, (char_u *)buf)] = NUL;
set_vim_var_string(VV_CHAR, buf, -1);
}
@@ -17833,6 +18421,8 @@ void set_vcount(long count, long count1, int set_prevcount)
/// @param[in] val Value to set to.
void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val)
{
+ tv_clear(&vimvars[idx].vv_tv);
+ vimvars[idx].vv_type = VAR_NUMBER;
vimvars[idx].vv_nr = val;
}
@@ -17842,6 +18432,8 @@ void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val)
/// @param[in] val Value to set to.
void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val)
{
+ tv_clear(&vimvars[idx].vv_tv);
+ vimvars[idx].vv_type = VAR_SPECIAL;
vimvars[idx].vv_special = val;
}
@@ -17854,7 +18446,7 @@ void set_vim_var_special(const VimVarIndex idx, const SpecialVarValue val)
void set_vim_var_string(const VimVarIndex idx, const char *const val,
const ptrdiff_t len)
{
- clear_tv(&vimvars[idx].vv_di.di_tv);
+ tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_STRING;
if (val == NULL) {
vimvars[idx].vv_str = NULL;
@@ -17871,11 +18463,11 @@ void set_vim_var_string(const VimVarIndex idx, const char *const val,
/// @param[in,out] val Value to set to. Reference count will be incremented.
void set_vim_var_list(const VimVarIndex idx, list_T *const val)
{
- clear_tv(&vimvars[idx].vv_di.di_tv);
+ tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_LIST;
vimvars[idx].vv_list = val;
if (val != NULL) {
- val->lv_refcount++;
+ tv_list_ref(val);
}
}
@@ -17886,14 +18478,14 @@ void set_vim_var_list(const VimVarIndex idx, list_T *const val)
/// Also keys of the dictionary will be made read-only.
void set_vim_var_dict(const VimVarIndex idx, dict_T *const val)
{
- clear_tv(&vimvars[idx].vv_di.di_tv);
+ tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_DICT;
vimvars[idx].vv_dict = val;
if (val != NULL) {
val->dv_refcount++;
// Set readonly
- dict_set_keys_readonly(val);
+ tv_dict_set_keys_readonly(val);
}
}
@@ -18011,9 +18603,8 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg)
* Get the value of internal variable "name".
* Return OK or FAIL.
*/
-static int
-get_var_tv (
- char_u *name,
+static int get_var_tv(
+ const char *name,
int len, // length of "name"
typval_T *rettv, // NULL when only checking existence
dictitem_T **dip, // non-NULL when typval's dict item is needed
@@ -18023,55 +18614,52 @@ get_var_tv (
{
int ret = OK;
typval_T *tv = NULL;
- typval_T atv;
dictitem_T *v;
- int cc;
- /* truncate the name, so that we can use strcmp() */
- cc = name[len];
- name[len] = NUL;
-
- /*
- * Check for "b:changedtick".
- */
- if (STRCMP(name, "b:changedtick") == 0) {
- atv.v_type = VAR_NUMBER;
- atv.vval.v_number = curbuf->b_changedtick;
- tv = &atv;
- }
- /*
- * Check for user-defined variables.
- */
- else {
- v = find_var(name, NULL, no_autoload);
- if (v != NULL) {
- tv = &v->di_tv;
- if (dip != NULL) {
- *dip = v;
- }
+ v = find_var(name, (size_t)len, NULL, no_autoload);
+ if (v != NULL) {
+ tv = &v->di_tv;
+ if (dip != NULL) {
+ *dip = v;
}
}
if (tv == NULL) {
- if (rettv != NULL && verbose)
- EMSG2(_(e_undefvar), name);
+ if (rettv != NULL && verbose) {
+ emsgf(_("E121: Undefined variable: %.*s"), len, name);
+ }
ret = FAIL;
- } else if (rettv != NULL)
- copy_tv(tv, rettv);
-
- name[len] = cc;
+ } else if (rettv != NULL) {
+ tv_copy(tv, rettv);
+ }
return ret;
}
-/*
- * Handle expr[expr], expr[expr:expr] subscript and .name lookup.
- * Also handle function call with Funcref variable: func(expr)
- * Can all be combined: dict.func(expr)[idx]['func'](expr)
- */
-static int
-handle_subscript (
- char_u **arg,
+/// Check if variable "name[len]" is a local variable or an argument.
+/// If so, "*eval_lavars_used" is set to TRUE.
+static void check_vars(const char *name, size_t len)
+{
+ if (eval_lavars_used == NULL) {
+ return;
+ }
+
+ const char *varname;
+ hashtab_T *ht = find_var_ht(name, len, &varname);
+
+ if (ht == get_funccal_local_ht() || ht == get_funccal_args_ht()) {
+ if (find_var(name, len, NULL, true) != NULL) {
+ *eval_lavars_used = true;
+ }
+ }
+}
+
+/// Handle expr[expr], expr[expr:expr] subscript and .name lookup.
+/// Also handle function call with Funcref variable: func(expr)
+/// Can all be combined: dict.func(expr)[idx]['func'](expr)
+static int
+handle_subscript(
+ const char **const arg,
typval_T *rettv,
int evaluate, /* do more than finding the end */
int verbose /* give error messages */
@@ -18086,493 +18674,219 @@ handle_subscript (
while (ret == OK
&& (**arg == '['
|| (**arg == '.' && rettv->v_type == VAR_DICT)
- || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC)))
+ || (**arg == '(' && (!evaluate || tv_is_func(*rettv))))
&& !ascii_iswhite(*(*arg - 1))) {
if (**arg == '(') {
- /* need to copy the funcref so that we can clear rettv */
+ partial_T *pt = NULL;
+ // need to copy the funcref so that we can clear rettv
if (evaluate) {
functv = *rettv;
rettv->v_type = VAR_UNKNOWN;
- /* Invoke the function. Recursive! */
- s = functv.vval.v_string;
- } else
+ // Invoke the function. Recursive!
+ if (functv.v_type == VAR_PARTIAL) {
+ pt = functv.vval.v_partial;
+ s = partial_name(pt);
+ } else {
+ s = functv.vval.v_string;
+ }
+ } else {
s = (char_u *)"";
- ret = get_func_tv(s, (int)STRLEN(s), rettv, arg,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &len, evaluate, selfdict);
+ }
+ ret = get_func_tv(s, (int)STRLEN(s), rettv, (char_u **)arg,
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &len, evaluate, pt, selfdict);
- /* Clear the funcref afterwards, so that deleting it while
- * evaluating the arguments is possible (see test55). */
- if (evaluate)
- clear_tv(&functv);
+ // Clear the funcref afterwards, so that deleting it while
+ // evaluating the arguments is possible (see test55).
+ if (evaluate) {
+ tv_clear(&functv);
+ }
/* Stop the expression evaluation when immediately aborting on
* error, or when an interrupt occurred or an exception was thrown
* but not caught. */
if (aborting()) {
- if (ret == OK)
- clear_tv(rettv);
+ if (ret == OK) {
+ tv_clear(rettv);
+ }
ret = FAIL;
}
- dict_unref(selfdict);
+ tv_dict_unref(selfdict);
selfdict = NULL;
- } else { /* **arg == '[' || **arg == '.' */
- dict_unref(selfdict);
+ } else { // **arg == '[' || **arg == '.'
+ tv_dict_unref(selfdict);
if (rettv->v_type == VAR_DICT) {
selfdict = rettv->vval.v_dict;
if (selfdict != NULL)
++selfdict->dv_refcount;
} else
selfdict = NULL;
- if (eval_index(arg, rettv, evaluate, verbose) == FAIL) {
- clear_tv(rettv);
+ if (eval_index((char_u **)arg, rettv, evaluate, verbose) == FAIL) {
+ tv_clear(rettv);
ret = FAIL;
}
}
}
- dict_unref(selfdict);
- return ret;
-}
-/*
- * Free the memory for a variable type-value.
- */
-void free_tv(typval_T *varp)
-{
- if (varp != NULL) {
- switch (varp->v_type) {
- case VAR_FUNC:
- func_unref(varp->vval.v_string);
- // FALLTHROUGH
- case VAR_STRING:
- xfree(varp->vval.v_string);
- break;
- case VAR_LIST:
- list_unref(varp->vval.v_list);
- break;
- case VAR_DICT:
- dict_unref(varp->vval.v_dict);
- break;
- case VAR_SPECIAL:
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_UNKNOWN:
- break;
- }
- xfree(varp);
- }
-}
-
-#define TYPVAL_ENCODE_ALLOW_SPECIALS false
-
-#define TYPVAL_ENCODE_CONV_NIL() \
- do { \
- tv->vval.v_special = kSpecialVarFalse; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_BOOL(ignored) \
- TYPVAL_ENCODE_CONV_NIL()
-
-#define TYPVAL_ENCODE_CONV_NUMBER(ignored) \
- do { \
- (void)ignored; \
- tv->vval.v_number = 0; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(ignored) \
- assert(false)
-
-#define TYPVAL_ENCODE_CONV_FLOAT(ignored) \
- do { \
- tv->vval.v_float = 0; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_STRING(str, ignored) \
- do { \
- xfree(str); \
- tv->vval.v_string = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_STR_STRING(ignored1, ignored2)
-
-#define TYPVAL_ENCODE_CONV_EXT_STRING(ignored1, ignored2, ignored3)
-
-#define TYPVAL_ENCODE_CONV_FUNC(fun) \
- do { \
- func_unref(fun); \
- if (fun != empty_string) { \
- xfree(fun); \
- } \
- tv->vval.v_string = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
- do { \
- list_unref(tv->vval.v_list); \
- tv->vval.v_list = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_EMPTY_DICT() \
- do { \
- dict_unref(tv->vval.v_dict); \
- tv->vval.v_dict = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_LIST_START(ignored) \
- do { \
- if (tv->vval.v_list->lv_refcount > 1) { \
- tv->vval.v_list->lv_refcount--; \
- tv->vval.v_list = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- return OK; \
- } \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS()
-
-#define TYPVAL_ENCODE_CONV_LIST_END() \
- do { \
- typval_T *const cur_tv = cur_mpsv->tv; \
- assert(cur_tv->v_type == VAR_LIST); \
- list_unref(cur_tv->vval.v_list); \
- cur_tv->vval.v_list = NULL; \
- cur_tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_DICT_START(ignored) \
- do { \
- if (tv->vval.v_dict->dv_refcount > 1) { \
- tv->vval.v_dict->dv_refcount--; \
- tv->vval.v_dict = NULL; \
- tv->v_lock = VAR_UNLOCKED; \
- return OK; \
- } \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(ignored1, ignored2)
-
-#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY()
-
-#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS()
-
-#define TYPVAL_ENCODE_CONV_DICT_END() \
- do { \
- typval_T *const cur_tv = cur_mpsv->tv; \
- assert(cur_tv->v_type == VAR_DICT); \
- dict_unref(cur_tv->vval.v_dict); \
- cur_tv->vval.v_dict = NULL; \
- cur_tv->v_lock = VAR_UNLOCKED; \
- } while (0)
-
-#define TYPVAL_ENCODE_CONV_RECURSE(ignored1, ignored2)
-
-TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, nothing, void *, ignored)
-
-#undef TYPVAL_ENCODE_ALLOW_SPECIALS
-#undef TYPVAL_ENCODE_CONV_NIL
-#undef TYPVAL_ENCODE_CONV_BOOL
-#undef TYPVAL_ENCODE_CONV_NUMBER
-#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
-#undef TYPVAL_ENCODE_CONV_FLOAT
-#undef TYPVAL_ENCODE_CONV_STRING
-#undef TYPVAL_ENCODE_CONV_STR_STRING
-#undef TYPVAL_ENCODE_CONV_EXT_STRING
-#undef TYPVAL_ENCODE_CONV_FUNC
-#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
-#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
-#undef TYPVAL_ENCODE_CONV_LIST_START
-#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_CONV_LIST_END
-#undef TYPVAL_ENCODE_CONV_DICT_START
-#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
-#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
-#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_CONV_DICT_END
-#undef TYPVAL_ENCODE_CONV_RECURSE
-
-/// Free memory for a variable value and set the value to NULL or 0
-///
-/// @param[in,out] varp Value to free.
-void clear_tv(typval_T *varp)
-{
- if (varp != NULL && varp->v_type != VAR_UNKNOWN) {
- encode_vim_to_nothing(varp, varp, "clear_tv argument");
+ // Turn "dict.Func" into a partial for "Func" bound to "dict".
+ if (selfdict != NULL && tv_is_func(*rettv)) {
+ set_selfdict(rettv, selfdict);
}
-}
-/*
- * Set the value of a variable to NULL without freeing items.
- */
-static void init_tv(typval_T *varp)
-{
- if (varp != NULL)
- memset(varp, 0, sizeof(typval_T));
+ tv_dict_unref(selfdict);
+ return ret;
}
-/*
- * Get the number value of a variable.
- * If it is a String variable, uses vim_str2nr().
- * For incompatible types, return 0.
- * get_tv_number_chk() is similar to get_tv_number(), but informs the
- * caller of incompatible types: it sets *denote to TRUE if "denote"
- * is not NULL or returns -1 otherwise.
- */
-static long get_tv_number(typval_T *varp)
+void set_selfdict(typval_T *rettv, dict_T *selfdict)
{
- int error = FALSE;
-
- return get_tv_number_chk(varp, &error); /* return 0L on error */
-}
+ // Don't do this when "dict.Func" is already a partial that was bound
+ // explicitly (pt_auto is false).
+ if (rettv->v_type == VAR_PARTIAL && !rettv->vval.v_partial->pt_auto
+ && rettv->vval.v_partial->pt_dict != NULL) {
+ return;
+ }
+ char_u *fname;
+ char_u *tofree = NULL;
+ ufunc_T *fp;
+ char_u fname_buf[FLEN_FIXED + 1];
+ int error;
-long get_tv_number_chk(typval_T *varp, int *denote)
-{
- long n = 0L;
+ if (rettv->v_type == VAR_PARTIAL && rettv->vval.v_partial->pt_func != NULL) {
+ fp = rettv->vval.v_partial->pt_func;
+ } else {
+ fname = rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING
+ ? rettv->vval.v_string
+ : rettv->vval.v_partial->pt_name;
+ // Translate "s:func" to the stored function name.
+ fname = fname_trans_sid(fname, fname_buf, &tofree, &error);
+ fp = find_func(fname);
+ xfree(tofree);
+ }
- switch (varp->v_type) {
- case VAR_NUMBER:
- return (long)(varp->vval.v_number);
- case VAR_FLOAT:
- EMSG(_("E805: Using a Float as a Number"));
- break;
- case VAR_FUNC:
- EMSG(_("E703: Using a Funcref as a Number"));
- break;
- case VAR_STRING:
- if (varp->vval.v_string != NULL) {
- vim_str2nr(varp->vval.v_string, NULL, NULL,
- STR2NR_ALL, &n, NULL, 0);
- }
- return n;
- case VAR_LIST:
- EMSG(_("E745: Using a List as a Number"));
- break;
- case VAR_DICT:
- EMSG(_("E728: Using a Dictionary as a Number"));
- break;
- case VAR_SPECIAL:
- switch (varp->vval.v_special) {
- case kSpecialVarTrue: {
- return 1;
+ // Turn "dict.Func" into a partial for "Func" with "dict".
+ if (fp != NULL && (fp->uf_flags & FC_DICT)) {
+ partial_T *pt = (partial_T *)xcalloc(1, sizeof(partial_T));
+ pt->pt_refcount = 1;
+ pt->pt_dict = selfdict;
+ (selfdict->dv_refcount)++;
+ pt->pt_auto = true;
+ if (rettv->v_type == VAR_FUNC || rettv->v_type == VAR_STRING) {
+ // Just a function: Take over the function name and use selfdict.
+ pt->pt_name = rettv->vval.v_string;
+ } else {
+ partial_T *ret_pt = rettv->vval.v_partial;
+ int i;
+
+ // Partial: copy the function name, use selfdict and copy
+ // args. Can't take over name or args, the partial might
+ // be referenced elsewhere.
+ if (ret_pt->pt_name != NULL) {
+ pt->pt_name = vim_strsave(ret_pt->pt_name);
+ func_ref(pt->pt_name);
+ } else {
+ pt->pt_func = ret_pt->pt_func;
+ func_ptr_ref(pt->pt_func);
}
- case kSpecialVarFalse:
- case kSpecialVarNull: {
- return 0;
+ if (ret_pt->pt_argc > 0) {
+ size_t arg_size = sizeof(typval_T) * ret_pt->pt_argc;
+ pt->pt_argv = (typval_T *)xmalloc(arg_size);
+ pt->pt_argc = ret_pt->pt_argc;
+ for (i = 0; i < pt->pt_argc; i++) {
+ tv_copy(&ret_pt->pt_argv[i], &pt->pt_argv[i]);
+ }
}
+ partial_unref(ret_pt);
}
- break;
- case VAR_UNKNOWN:
- EMSG2(_(e_intern2), "get_tv_number(UNKNOWN)");
- break;
+ rettv->v_type = VAR_PARTIAL;
+ rettv->vval.v_partial = pt;
}
- if (denote == NULL) {
- // useful for values that must be unsigned
- n = -1;
- } else {
- *denote = true;
- }
- return n;
}
-static float_T get_tv_float(typval_T *varp)
+// Find variable "name" in the list of variables.
+// Return a pointer to it if found, NULL if not found.
+// Careful: "a:0" variables don't have a name.
+// When "htp" is not NULL we are writing to the variable, set "htp" to the
+// hashtab_T used.
+static dictitem_T *find_var(const char *const name, const size_t name_len,
+ hashtab_T **htp, int no_autoload)
{
- switch (varp->v_type) {
- case VAR_NUMBER:
- return (float_T)(varp->vval.v_number);
- case VAR_FLOAT:
- return varp->vval.v_float;
- break;
- case VAR_FUNC:
- EMSG(_("E891: Using a Funcref as a Float"));
- break;
- case VAR_STRING:
- EMSG(_("E892: Using a String as a Float"));
- break;
- case VAR_LIST:
- EMSG(_("E893: Using a List as a Float"));
- break;
- case VAR_DICT:
- EMSG(_("E894: Using a Dictionary as a Float"));
- break;
- default:
- EMSG2(_(e_intern2), "get_tv_float()");
- break;
+ const char *varname;
+ hashtab_T *const ht = find_var_ht(name, name_len, &varname);
+ if (htp != NULL) {
+ *htp = ht;
}
- return 0;
-}
-
-/*
- * Get the lnum from the first argument.
- * Also accepts ".", "$", etc., but that only works for the current buffer.
- * Returns -1 on error.
- */
-static linenr_T get_tv_lnum(typval_T *argvars)
-{
- typval_T rettv;
- linenr_T lnum;
-
- lnum = get_tv_number_chk(&argvars[0], NULL);
- if (lnum == 0) { /* no valid number, try using line() */
- rettv.v_type = VAR_NUMBER;
- f_line(argvars, &rettv);
- lnum = rettv.vval.v_number;
- clear_tv(&rettv);
+ if (ht == NULL) {
+ return NULL;
}
- return lnum;
-}
-
-/*
- * Get the lnum from the first argument.
- * Also accepts "$", then "buf" is used.
- * Returns 0 on error.
- */
-static linenr_T get_tv_lnum_buf(typval_T *argvars, buf_T *buf)
-{
- if (argvars[0].v_type == VAR_STRING
- && argvars[0].vval.v_string != NULL
- && argvars[0].vval.v_string[0] == '$'
- && buf != NULL)
- return buf->b_ml.ml_line_count;
- return get_tv_number_chk(&argvars[0], NULL);
-}
-
-/*
- * Get the string value of a variable.
- * If it is a Number variable, the number is converted into a string.
- * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
- * get_tv_string_buf() uses a given buffer.
- * If the String variable has never been set, return an empty string.
- * Never returns NULL;
- * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return
- * NULL on error.
- */
-static char_u *get_tv_string(const typval_T *varp)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
-{
- static char_u mybuf[NUMBUFLEN];
-
- return get_tv_string_buf(varp, mybuf);
-}
-
-static char_u *get_tv_string_buf(const typval_T *varp, char_u *buf)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
-{
- char_u *res = get_tv_string_buf_chk(varp, buf);
-
- return res != NULL ? res : (char_u *)"";
-}
-
-/// Careful: This uses a single, static buffer. YOU CAN ONLY USE IT ONCE!
-char_u *get_tv_string_chk(const typval_T *varp)
- FUNC_ATTR_NONNULL_ALL
-{
- static char_u mybuf[NUMBUFLEN];
-
- return get_tv_string_buf_chk(varp, mybuf);
-}
-
-static char_u *get_tv_string_buf_chk(const typval_T *varp, char_u *buf)
- FUNC_ATTR_NONNULL_ALL
-{
- switch (varp->v_type) {
- case VAR_NUMBER:
- sprintf((char *)buf, "%" PRId64, (int64_t)varp->vval.v_number);
- return buf;
- case VAR_FUNC:
- EMSG(_("E729: using Funcref as a String"));
- break;
- case VAR_LIST:
- EMSG(_("E730: using List as a String"));
- break;
- case VAR_DICT:
- EMSG(_("E731: using Dictionary as a String"));
- break;
- case VAR_FLOAT:
- EMSG(_(e_float_as_string));
- break;
- case VAR_STRING:
- if (varp->vval.v_string != NULL)
- return varp->vval.v_string;
- return (char_u *)"";
- case VAR_SPECIAL:
- STRCPY(buf, encode_special_var_names[varp->vval.v_special]);
- return buf;
- case VAR_UNKNOWN:
- EMSG(_("E908: using an invalid value as a String"));
- break;
+ dictitem_T *const ret = find_var_in_ht(ht, *name,
+ varname,
+ name_len - (size_t)(varname - name),
+ no_autoload || htp != NULL);
+ if (ret != NULL) {
+ return ret;
}
- return NULL;
-}
-/*
- * Find variable "name" in the list of variables.
- * Return a pointer to it if found, NULL if not found.
- * Careful: "a:0" variables don't have a name.
- * When "htp" is not NULL we are writing to the variable, set "htp" to the
- * hashtab_T used.
- */
-static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload)
-{
- char_u *varname;
- hashtab_T *ht;
-
- ht = find_var_ht(name, &varname);
- if (htp != NULL)
- *htp = ht;
- if (ht == NULL)
- return NULL;
- return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL);
+ // Search in parent scope for lambda
+ return find_var_in_scoped_ht(name, name_len, no_autoload || htp != NULL);
}
-/*
- * Find variable "varname" in hashtab "ht" with name "htname".
- * Returns NULL if not found.
- */
-static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload)
+/// Find variable in hashtab
+///
+/// @param[in] ht Hashtab to find variable in.
+/// @param[in] htname Hashtab name (first character).
+/// @param[in] varname Variable name.
+/// @param[in] varname_len Variable name length.
+/// @param[in] no_autoload If true then autoload scripts will not be sourced
+/// if autoload variable was not found.
+///
+/// @return pointer to the dictionary item with the found variable or NULL if it
+/// was not found.
+static dictitem_T *find_var_in_ht(hashtab_T *const ht,
+ int htname,
+ const char *const varname,
+ const size_t varname_len,
+ int no_autoload)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
hashitem_T *hi;
- if (*varname == NUL) {
- /* Must be something like "s:", otherwise "ht" would be NULL. */
+ if (varname_len == 0) {
+ // Must be something like "s:", otherwise "ht" would be NULL.
switch (htname) {
- case 's': return &SCRIPT_SV(current_SID)->sv_var;
- case 'g': return &globvars_var;
- case 'v': return &vimvars_var;
- case 'b': return &curbuf->b_bufvar;
- case 'w': return &curwin->w_winvar;
- case 't': return &curtab->tp_winvar;
- case 'l': return current_funccal == NULL
- ? NULL : &current_funccal->l_vars_var;
- case 'a': return current_funccal == NULL
- ? NULL : &current_funccal->l_avars_var;
+ case 's': return (dictitem_T *)&SCRIPT_SV(current_SID)->sv_var;
+ case 'g': return (dictitem_T *)&globvars_var;
+ case 'v': return (dictitem_T *)&vimvars_var;
+ case 'b': return (dictitem_T *)&curbuf->b_bufvar;
+ case 'w': return (dictitem_T *)&curwin->w_winvar;
+ case 't': return (dictitem_T *)&curtab->tp_winvar;
+ case 'l': return (current_funccal == NULL
+ ? NULL : (dictitem_T *)&current_funccal->l_vars_var);
+ case 'a': return (current_funccal == NULL
+ ? NULL : (dictitem_T *)&get_funccal()->l_avars_var);
}
return NULL;
}
- hi = hash_find(ht, varname);
+ hi = hash_find_len(ht, varname, varname_len);
if (HASHITEM_EMPTY(hi)) {
- /* For global variables we may try auto-loading the script. If it
- * worked find the variable again. Don't auto-load a script if it was
- * loaded already, otherwise it would be loaded every time when
- * checking if a function name is a Funcref variable. */
+ // For global variables we may try auto-loading the script. If it
+ // worked find the variable again. Don't auto-load a script if it was
+ // loaded already, otherwise it would be loaded every time when
+ // checking if a function name is a Funcref variable.
if (ht == &globvarht && !no_autoload) {
- /* Note: script_autoload() may make "hi" invalid. It must either
- * be obtained again or not used. */
- if (!script_autoload(varname, FALSE) || aborting())
+ // Note: script_autoload() may make "hi" invalid. It must either
+ // be obtained again or not used.
+ if (!script_autoload(varname, varname_len, false) || aborting()) {
return NULL;
- hi = hash_find(ht, varname);
+ }
+ hi = hash_find_len(ht, varname, varname_len);
}
- if (HASHITEM_EMPTY(hi))
+ if (HASHITEM_EMPTY(hi)) {
return NULL;
+ }
}
- return HI2DI(hi);
+ return TV_DICT_HI2DI(hi);
}
// Get function call environment based on backtrace debug level
@@ -18594,17 +18908,45 @@ static funccall_T *get_funccal(void)
return funccal;
}
-// Find the dict and hashtable used for a variable name. Set "varname" to the
-// start of name without ':'.
-static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d)
+/// Return the hashtable used for argument in the current funccal.
+/// Return NULL if there is no current funccal.
+static hashtab_T *get_funccal_args_ht(void)
{
- hashitem_T *hi;
+ if (current_funccal == NULL) {
+ return NULL;
+ }
+ return &get_funccal()->l_avars.dv_hashtab;
+}
+
+/// Return the hashtable used for local variables in the current funccal.
+/// Return NULL if there is no current funccal.
+static hashtab_T *get_funccal_local_ht(void)
+{
+ if (current_funccal == NULL) {
+ return NULL;
+ }
+ return &get_funccal()->l_vars.dv_hashtab;
+}
+
+/// Find the dict and hashtable used for a variable
+///
+/// @param[in] name Variable name, possibly with scope prefix.
+/// @param[in] name_len Variable name length.
+/// @param[out] varname Will be set to the start of the name without scope
+/// prefix.
+/// @param[out] d Scope dictionary.
+///
+/// @return Scope hashtab, NULL if name is not valid.
+static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len,
+ const char **varname, dict_T **d)
+{
+ hashitem_T *hi;
*d = NULL;
- if (name[0] == NUL) {
+ if (name_len == 0) {
return NULL;
}
- if (name[1] != ':') {
+ if (name_len == 1 || name[1] != ':') {
// name has implicit scope
if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) {
// The name must not start with a colon or #.
@@ -18613,7 +18955,7 @@ static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d)
*varname = name;
// "version" is "v:version" in all scopes
- hi = hash_find(&compat_hashtab, name);
+ hi = hash_find_len(&compat_hashtab, name, name_len);
if (!HASHITEM_EMPTY(hi)) {
return &compat_hashtab;
}
@@ -18629,26 +18971,27 @@ static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d)
*varname = name + 2;
if (*name == 'g') { // global variable
*d = &globvardict;
- } else if (vim_strchr(name + 2, ':') != NULL
- || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) {
+ } else if (name_len > 2
+ && (memchr(name + 2, ':', name_len - 2) != NULL
+ || memchr(name + 2, AUTOLOAD_CHAR, name_len - 2) != NULL)) {
// There must be no ':' or '#' in the rest of the name if g: was not used
return NULL;
}
- if (*name == 'b') { // buffer variable
+ if (*name == 'b') { // buffer variable
*d = curbuf->b_vars;
- } else if (*name == 'w') { // window variable
+ } else if (*name == 'w') { // window variable
*d = curwin->w_vars;
- } else if (*name == 't') { // tab page variable
+ } else if (*name == 't') { // tab page variable
*d = curtab->tp_vars;
- } else if (*name == 'v') { // v: variable
+ } else if (*name == 'v') { // v: variable
*d = &vimvardict;
} else if (*name == 'a' && current_funccal != NULL) { // function argument
*d = &get_funccal()->l_avars;
} else if (*name == 'l' && current_funccal != NULL) { // local variable
*d = &get_funccal()->l_vars;
- } else if (*name == 's' // script variable
- && current_SID > 0 && current_SID <= ga_scripts.ga_len) {
+ } else if (*name == 's' // script variable
+ && current_SID > 0 && current_SID <= ga_scripts.ga_len) {
*d = &SCRIPT_SV(current_SID)->sv_dict;
}
@@ -18656,28 +18999,35 @@ end:
return *d ? &(*d)->dv_hashtab : NULL;
}
-// Find the hashtab used for a variable name.
-// Return NULL if the name is not valid.
-// Set "varname" to the start of name without ':'.
-static hashtab_T *find_var_ht(uint8_t *name, uint8_t **varname)
+/// Find the hashtable used for a variable
+///
+/// @param[in] name Variable name, possibly with scope prefix.
+/// @param[in] name_len Variable name length.
+/// @param[out] varname Will be set to the start of the name without scope
+/// prefix.
+///
+/// @return Scope hashtab, NULL if name is not valid.
+static hashtab_T *find_var_ht(const char *name, const size_t name_len,
+ const char **varname)
{
dict_T *d;
- return find_var_ht_dict(name, varname, &d);
+ return find_var_ht_dict(name, name_len, varname, &d);
}
/*
* Get the string value of a (global/local) variable.
- * Note: see get_tv_string() for how long the pointer remains valid.
+ * Note: see tv_get_string() for how long the pointer remains valid.
* Returns NULL when it doesn't exist.
*/
-char_u *get_var_value(char_u *name)
+char_u *get_var_value(const char *const name)
{
dictitem_T *v;
- v = find_var(name, NULL, FALSE);
- if (v == NULL)
+ v = find_var(name, strlen(name), NULL, false);
+ if (v == NULL) {
return NULL;
- return get_tv_string(&v->di_tv);
+ }
+ return (char_u *)tv_get_string(&v->di_tv);
}
/*
@@ -18714,10 +19064,10 @@ void new_script_vars(scid_T id)
* Initialize dictionary "dict" as a scope and set variable "dict_var" to
* point to it.
*/
-void init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope)
+void init_var_dict(dict_T *dict, ScopeDictDictItem *dict_var, int scope)
{
hash_init(&dict->dv_hashtab);
- dict->dv_lock = 0;
+ dict->dv_lock = VAR_UNLOCKED;
dict->dv_scope = scope;
dict->dv_refcount = DO_NOT_FREE_CNT;
dict->dv_copyID = 0;
@@ -18737,7 +19087,7 @@ void unref_var_dict(dict_T *dict)
/* Now the dict needs to be freed if no one else is using it, go back to
* normal reference counting. */
dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
- dict_unref(dict);
+ tv_dict_unref(dict);
}
/*
@@ -18768,9 +19118,9 @@ static void vars_clear_ext(hashtab_T *ht, int free_val)
// Free the variable. Don't remove it from the hashtab,
// ht_array might change then. hash_clear() takes care of it
// later.
- v = HI2DI(hi);
+ v = TV_DICT_HI2DI(hi);
if (free_val) {
- clear_tv(&v->di_tv);
+ tv_clear(&v->di_tv);
}
if (v->di_flags & DI_FLAGS_ALLOC) {
xfree(v);
@@ -18787,45 +19137,44 @@ static void vars_clear_ext(hashtab_T *ht, int free_val)
*/
static void delete_var(hashtab_T *ht, hashitem_T *hi)
{
- dictitem_T *di = HI2DI(hi);
+ dictitem_T *di = TV_DICT_HI2DI(hi);
hash_remove(ht, hi);
- clear_tv(&di->di_tv);
+ tv_clear(&di->di_tv);
xfree(di);
}
/*
* List the value of one internal variable.
*/
-static void list_one_var(dictitem_T *v, char_u *prefix, int *first)
+static void list_one_var(dictitem_T *v, const char *prefix, int *first)
{
- char_u *s = (char_u *) encode_tv2echo(&v->di_tv, NULL);
- list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
- s == NULL ? (char_u *)"" : s, first);
+ char *const s = encode_tv2echo(&v->di_tv, NULL);
+ list_one_var_a(prefix, (const char *)v->di_key, STRLEN(v->di_key),
+ v->di_tv.v_type, (s == NULL ? "" : s), first);
xfree(s);
}
-static void
-list_one_var_a (
- char_u *prefix,
- char_u *name,
- int type,
- char_u *string,
- int *first /* when TRUE clear rest of screen and set to FALSE */
-)
+/// @param[in] name_len Length of the name. May be -1, in this case strlen()
+/// will be used.
+/// @param[in,out] first When true clear rest of screen and set to false.
+static void list_one_var_a(const char *prefix, const char *name,
+ const ptrdiff_t name_len, const int type,
+ const char *string, int *first)
{
- /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */
+ // don't use msg() or msg_attr() to avoid overwriting "v:statusmsg"
msg_start();
msg_puts(prefix);
- if (name != NULL) /* "a:" vars don't have a name stored */
- msg_puts(name);
+ if (name != NULL) { // "a:" vars don't have a name stored
+ msg_puts_attr_len(name, name_len, 0);
+ }
msg_putchar(' ');
msg_advance(22);
- if (type == VAR_NUMBER)
+ if (type == VAR_NUMBER) {
msg_putchar('#');
- else if (type == VAR_FUNC)
+ } else if (type == VAR_FUNC || type == VAR_PARTIAL) {
msg_putchar('*');
- else if (type == VAR_LIST) {
+ } else if (type == VAR_LIST) {
msg_putchar('[');
if (*string == '[')
++string;
@@ -18836,67 +19185,58 @@ list_one_var_a (
} else
msg_putchar(' ');
- msg_outtrans(string);
+ msg_outtrans((char_u *)string);
- if (type == VAR_FUNC)
- msg_puts((char_u *)"()");
+ if (type == VAR_FUNC || type == VAR_PARTIAL) {
+ msg_puts("()");
+ }
if (*first) {
msg_clr_eos();
*first = FALSE;
}
}
-/*
- * Set variable "name" to value in "tv".
- * If the variable already exists, the value is updated.
- * Otherwise the variable is created.
- */
-static void
-set_var (
- char_u *name,
- typval_T *tv,
- int copy /* make copy of value in "tv" */
-)
+/// Set variable to the given value
+///
+/// If the variable already exists, the value is updated. Otherwise the variable
+/// is created.
+///
+/// @param[in] name Variable name to set.
+/// @param[in] name_len Length of the variable name.
+/// @param tv Variable value.
+/// @param[in] copy True if value in tv is to be copied.
+static void set_var(const char *name, const size_t name_len, typval_T *const tv,
+ const bool copy)
+ FUNC_ATTR_NONNULL_ALL
{
dictitem_T *v;
- char_u *varname;
hashtab_T *ht;
- typval_T oldtv;
dict_T *dict;
- ht = find_var_ht_dict(name, &varname, &dict);
- bool watched = is_watched(dict);
-
- if (watched) {
- init_tv(&oldtv);
- }
+ const char *varname;
+ ht = find_var_ht_dict(name, name_len, &varname, &dict);
+ const bool watched = tv_dict_is_watched(dict);
if (ht == NULL || *varname == NUL) {
EMSG2(_(e_illvar), name);
return;
}
- v = find_var_in_ht(ht, 0, varname, TRUE);
+ v = find_var_in_ht(ht, 0, varname, name_len - (size_t)(varname - name), true);
- if (tv->v_type == VAR_FUNC && var_check_func_name(name, v == NULL))
+ // Search in parent scope which is possible to reference from lambda
+ if (v == NULL) {
+ v = find_var_in_scoped_ht((const char *)name, name_len, true);
+ }
+
+ if (tv_is_func(*tv) && !var_check_func_name(name, v == NULL)) {
return;
+ }
+ typval_T oldtv = TV_INITIAL_VALUE;
if (v != NULL) {
// existing variable, need to clear the value
- if (var_check_ro(v->di_flags, name, false)
- || tv_check_lock(v->di_tv.v_lock, name, false)) {
- return;
- }
- if (v->di_tv.v_type != tv->v_type
- && !((v->di_tv.v_type == VAR_STRING
- || v->di_tv.v_type == VAR_NUMBER)
- && (tv->v_type == VAR_STRING
- || tv->v_type == VAR_NUMBER))
- && !((v->di_tv.v_type == VAR_NUMBER
- || v->di_tv.v_type == VAR_FLOAT)
- && (tv->v_type == VAR_NUMBER
- || tv->v_type == VAR_FLOAT))
- ) {
- EMSG2(_("E706: Variable type mismatch for: %s"), name);
+ if (var_check_ro(v->di_flags, name, name_len)
+ || tv_check_lock(v->di_tv.v_lock, name, name_len)) {
return;
}
@@ -18905,46 +19245,51 @@ set_var (
if (ht == &vimvarht) {
if (v->di_tv.v_type == VAR_STRING) {
xfree(v->di_tv.vval.v_string);
- if (copy || tv->v_type != VAR_STRING)
- v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv));
- else {
- /* Take over the string to avoid an extra alloc/free. */
+ if (copy || tv->v_type != VAR_STRING) {
+ v->di_tv.vval.v_string = (char_u *)xstrdup(tv_get_string(tv));
+ } else {
+ // Take over the string to avoid an extra alloc/free.
v->di_tv.vval.v_string = tv->vval.v_string;
tv->vval.v_string = NULL;
}
return;
} else if (v->di_tv.v_type == VAR_NUMBER) {
- v->di_tv.vval.v_number = get_tv_number(tv);
- if (STRCMP(varname, "searchforward") == 0)
+ v->di_tv.vval.v_number = tv_get_number(tv);
+ if (strcmp(varname, "searchforward") == 0) {
set_search_direction(v->di_tv.vval.v_number ? '/' : '?');
- else if (STRCMP(varname, "hlsearch") == 0) {
+ } else if (strcmp(varname, "hlsearch") == 0) {
no_hlsearch = !v->di_tv.vval.v_number;
redraw_all_later(SOME_VALID);
}
return;
} else if (v->di_tv.v_type != tv->v_type) {
- EMSG2(_(e_intern2), "set_var()");
+ EMSG2(_("E963: setting %s to value with wrong type"), name);
+ return;
}
}
if (watched) {
- copy_tv(&v->di_tv, &oldtv);
+ tv_copy(&v->di_tv, &oldtv);
}
- clear_tv(&v->di_tv);
- } else { /* add a new variable */
- /* Can't add "v:" variable. */
+ tv_clear(&v->di_tv);
+ } else { // Add a new variable.
+ // Can't add "v:" variable.
if (ht == &vimvarht) {
- EMSG2(_(e_illvar), name);
+ emsgf(_(e_illvar), name);
return;
}
- /* Make sure the variable name is valid. */
- if (!valid_varname(varname))
+ // Make sure the variable name is valid.
+ if (!valid_varname(varname)) {
return;
+ }
- v = xmalloc(sizeof(dictitem_T) + STRLEN(varname));
+ // Make sure dict is valid
+ assert(dict != NULL);
+
+ v = xmalloc(sizeof(dictitem_T) + strlen(varname));
STRCPY(v->di_key, varname);
- if (hash_add(ht, DI2HIKEY(v)) == FAIL) {
+ if (tv_dict_add(dict, v) == FAIL) {
xfree(v);
return;
}
@@ -18952,159 +19297,153 @@ set_var (
}
if (copy || tv->v_type == VAR_NUMBER || tv->v_type == VAR_FLOAT) {
- copy_tv(tv, &v->di_tv);
+ tv_copy(tv, &v->di_tv);
} else {
v->di_tv = *tv;
v->di_tv.v_lock = 0;
- init_tv(tv);
+ tv_init(tv);
}
if (watched) {
if (oldtv.v_type == VAR_UNKNOWN) {
- dictwatcher_notify(dict, (char *)v->di_key, &v->di_tv, NULL);
+ tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, NULL);
} else {
- dictwatcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv);
- clear_tv(&oldtv);
+ tv_dict_watcher_notify(dict, (char *)v->di_key, &v->di_tv, &oldtv);
+ tv_clear(&oldtv);
}
}
}
-// Return true if di_flags "flags" indicates variable "name" is read-only.
-// Also give an error message.
-static bool var_check_ro(int flags, char_u *name, bool use_gettext)
+/// Check whether variable is read-only (DI_FLAGS_RO, DI_FLAGS_RO_SBX)
+///
+/// Also gives an error message.
+///
+/// @param[in] flags di_flags attribute value.
+/// @param[in] name Variable name, for use in error message.
+/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
+/// variable name and compute the length. Use #TV_CSTRING
+/// to compute the length with strlen() without
+/// translating.
+///
+/// Both #TV_… values are used for optimization purposes:
+/// variable name with its length is needed only in case
+/// of error, when no error occurs computing them is
+/// a waste of CPU resources. This especially applies to
+/// gettext.
+///
+/// @return True if variable is read-only: either always or in sandbox when
+/// sandbox is enabled, false otherwise.
+bool var_check_ro(const int flags, const char *name,
+ size_t name_len)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
+ const char *error_message = NULL;
if (flags & DI_FLAGS_RO) {
- EMSG2(_(e_readonlyvar), use_gettext ? (char_u *)_(name) : name);
- return true;
+ error_message = N_(e_readonlyvar);
+ } else if ((flags & DI_FLAGS_RO_SBX) && sandbox) {
+ error_message = N_("E794: Cannot set variable in the sandbox: \"%.*s\"");
}
- if ((flags & DI_FLAGS_RO_SBX) && sandbox) {
- EMSG2(_(e_readonlysbx), use_gettext ? (char_u *)_(name) : name);
- return true;
+
+ if (error_message == NULL) {
+ return false;
}
- return false;
+ if (name_len == TV_TRANSLATE) {
+ name = _(name);
+ name_len = strlen(name);
+ } else if (name_len == TV_CSTRING) {
+ name_len = strlen(name);
+ }
+
+ emsgf(_(error_message), (int)name_len, name);
+
+ return true;
}
-// Return true if di_flags "flags" indicates variable "name" is fixed.
-// Also give an error message.
-static bool var_check_fixed(int flags, char_u *name, bool use_gettext)
+/// Check whether variable is fixed (DI_FLAGS_FIX)
+///
+/// Also gives an error message.
+///
+/// @param[in] flags di_flags attribute value.
+/// @param[in] name Variable name, for use in error message.
+/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
+/// variable name and compute the length. Use #TV_CSTRING
+/// to compute the length with strlen() without
+/// translating.
+///
+/// Both #TV_… values are used for optimization purposes:
+/// variable name with its length is needed only in case
+/// of error, when no error occurs computing them is
+/// a waste of CPU resources. This especially applies to
+/// gettext.
+///
+/// @return True if variable is fixed, false otherwise.
+static bool var_check_fixed(const int flags, const char *name,
+ size_t name_len)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
if (flags & DI_FLAGS_FIX) {
- EMSG2(_("E795: Cannot delete variable %s"),
- use_gettext ? (char_u *)_(name) : name);
+ if (name_len == TV_TRANSLATE) {
+ name = _(name);
+ name_len = strlen(name);
+ } else if (name_len == TV_CSTRING) {
+ name_len = strlen(name);
+ }
+ EMSG3(_("E795: Cannot delete variable %.*s"), (int)name_len, name);
return true;
}
return false;
}
-/*
- * Check if a funcref is assigned to a valid variable name.
- * Return TRUE and give an error if not.
- */
-static int
-var_check_func_name (
- char_u *name, /* points to start of variable name */
- int new_var /* TRUE when creating the variable */
-)
+// 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.
+/// @param[in] new_var True if it is a name for a variable.
+///
+/// @return false in case of error, true in case of success. Also gives an
+/// error message if appropriate.
+bool var_check_func_name(const char *const name, const bool new_var)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
// Allow for w: b: s: and t:.
if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':')
&& !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') ? name[2]
: name[0])) {
EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name);
- return TRUE;
+ return false;
}
- /* Don't allow hiding a function. When "v" is not NULL we might be
- * assigning another function to the same var, the type is checked
- * below. */
- if (new_var && function_exists(name)) {
+ // Don't allow hiding a function. When "v" is not NULL we might be
+ // assigning another function to the same var, the type is checked
+ // below.
+ if (new_var && function_exists((const char *)name, false)) {
EMSG2(_("E705: Variable name conflicts with existing function: %s"),
- name);
- return TRUE;
+ name);
+ return false;
}
- return FALSE;
+ return true;
}
-/*
- * Check if a variable name is valid.
- * Return FALSE and give an error if not.
- */
-static int valid_varname(char_u *varname)
-{
- char_u *p;
+// TODO(ZyX-I): move to eval/expressions
- for (p = varname; *p != NUL; ++p)
- if (!eval_isnamec1(*p) && (p == varname || !ascii_isdigit(*p))
+/// Check if a variable name is valid
+///
+/// @param[in] varname Variable name to check.
+///
+/// @return false when variable name is not valid, true when it is. Also gives
+/// an error message if appropriate.
+bool valid_varname(const char *varname)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ for (const char *p = varname; *p != NUL; p++) {
+ if (!eval_isnamec1((int)(uint8_t)(*p))
+ && (p == varname || !ascii_isdigit(*p))
&& *p != AUTOLOAD_CHAR) {
- EMSG2(_(e_illvar), varname);
- return FALSE;
+ emsgf(_(e_illvar), varname);
+ return false;
}
- return TRUE;
-}
-
-// Return true if typeval "tv" is set to be locked (immutable).
-// Also give an error message, using "name" or _("name") when use_gettext is
-// true.
-static bool tv_check_lock(int lock, char_u *name, bool use_gettext)
-{
- if (lock & VAR_LOCKED) {
- EMSG2(_("E741: Value is locked: %s"),
- name == NULL
- ? (char_u *)_("Unknown")
- : use_gettext ? (char_u *)_(name)
- : name);
- return true;
- }
- if (lock & VAR_FIXED) {
- EMSG2(_("E742: Cannot change value of %s"),
- name == NULL
- ? (char_u *)_("Unknown")
- : use_gettext ? (char_u *)_(name)
- : name);
- return true;
- }
- return false;
-}
-
-/*
- * Copy the values from typval_T "from" to typval_T "to".
- * When needed allocates string or increases reference count.
- * Does not make a copy of a list or dict but copies the reference!
- * It is OK for "from" and "to" to point to the same item. This is used to
- * make a copy later.
- */
-void copy_tv(typval_T *from, typval_T *to)
-{
- to->v_type = from->v_type;
- to->v_lock = 0;
- memmove(&to->vval, &from->vval, sizeof(to->vval));
- switch (from->v_type) {
- case VAR_NUMBER:
- case VAR_FLOAT:
- case VAR_SPECIAL:
- break;
- case VAR_STRING:
- case VAR_FUNC:
- if (from->vval.v_string != NULL) {
- to->vval.v_string = vim_strsave(from->vval.v_string);
- if (from->v_type == VAR_FUNC) {
- func_ref(to->vval.v_string);
- }
- }
- break;
- case VAR_LIST:
- if (from->vval.v_list != NULL) {
- to->vval.v_list->lv_refcount++;
- }
- break;
- case VAR_DICT:
- if (from->vval.v_dict != NULL) {
- to->vval.v_dict->dv_refcount++;
- }
- break;
- case VAR_UNKNOWN:
- EMSG2(_(e_intern2), "copy_tv(UNKNOWN)");
- break;
}
+ return true;
}
/// Make a copy of an item
@@ -19122,7 +19461,7 @@ void copy_tv(typval_T *from, typval_T *to)
/// list[1]`) var_item_copy with zero copyID will emit
/// a copy with (`copy[0] isnot copy[1]`), with non-zero it
/// will emit a copy with (`copy[0] is copy[1]`) like in the
-/// original list. Not use when deep is false.
+/// original list. Not used when deep is false.
int var_item_copy(const vimconv_T *const conv,
typval_T *const from,
typval_T *const to,
@@ -19143,12 +19482,14 @@ int var_item_copy(const vimconv_T *const conv,
case VAR_NUMBER:
case VAR_FLOAT:
case VAR_FUNC:
+ case VAR_PARTIAL:
case VAR_SPECIAL:
- copy_tv(from, to);
+ tv_copy(from, to);
break;
case VAR_STRING:
- if (conv == NULL || conv->vc_type == CONV_NONE) {
- copy_tv(from, to);
+ if (conv == NULL || conv->vc_type == CONV_NONE
+ || from->vval.v_string == NULL) {
+ tv_copy(from, to);
} else {
to->v_type = VAR_STRING;
to->v_lock = 0;
@@ -19163,17 +19504,18 @@ int var_item_copy(const vimconv_T *const conv,
case VAR_LIST:
to->v_type = VAR_LIST;
to->v_lock = 0;
- if (from->vval.v_list == NULL)
+ if (from->vval.v_list == NULL) {
to->vval.v_list = NULL;
- else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) {
- /* use the copy made earlier */
- to->vval.v_list = from->vval.v_list->lv_copylist;
- ++to->vval.v_list->lv_refcount;
+ } else if (copyID != 0 && tv_list_copyid(from->vval.v_list) == copyID) {
+ // Use the copy made earlier.
+ to->vval.v_list = tv_list_latest_copy(from->vval.v_list);
+ tv_list_ref(to->vval.v_list);
} else {
- to->vval.v_list = list_copy(conv, from->vval.v_list, deep, copyID);
+ to->vval.v_list = tv_list_copy(conv, from->vval.v_list, deep, copyID);
}
- if (to->vval.v_list == NULL)
+ if (to->vval.v_list == NULL && from->vval.v_list != NULL) {
ret = FAIL;
+ }
break;
case VAR_DICT:
to->v_type = VAR_DICT;
@@ -19185,13 +19527,14 @@ int var_item_copy(const vimconv_T *const conv,
to->vval.v_dict = from->vval.v_dict->dv_copydict;
++to->vval.v_dict->dv_refcount;
} else {
- to->vval.v_dict = dict_copy(conv, from->vval.v_dict, deep, copyID);
+ to->vval.v_dict = tv_dict_copy(conv, from->vval.v_dict, deep, copyID);
}
- if (to->vval.v_dict == NULL)
+ if (to->vval.v_dict == NULL && from->vval.v_dict != NULL) {
ret = FAIL;
+ }
break;
case VAR_UNKNOWN:
- EMSG2(_(e_intern2), "var_item_copy(UNKNOWN)");
+ internal_error("var_item_copy(UNKNOWN)");
ret = FAIL;
}
--recurse;
@@ -19207,9 +19550,9 @@ void ex_echo(exarg_T *eap)
{
char_u *arg = eap->arg;
typval_T rettv;
- char_u *p;
bool needclr = true;
bool atstart = true;
+ const int did_emsg_before = did_emsg;
if (eap->skip)
++emsg_skip;
@@ -19218,19 +19561,20 @@ void ex_echo(exarg_T *eap)
* still need to be cleared. E.g., "echo 22,44". */
need_clr_eos = needclr;
- p = arg;
- if (eval1(&arg, &rettv, !eap->skip) == FAIL) {
- /*
- * Report the invalid expression unless the expression evaluation
- * has been cancelled due to an aborting error, an interrupt, or an
- * exception.
- */
- if (!aborting())
- EMSG2(_(e_invexpr2), p);
- need_clr_eos = FALSE;
- break;
+ {
+ char_u *p = arg;
+ if (eval1(&arg, &rettv, !eap->skip) == FAIL) {
+ // Report the invalid expression unless the expression evaluation
+ // has been cancelled due to an aborting error, an interrupt, or an
+ // exception.
+ if (!aborting() && did_emsg == did_emsg_before) {
+ EMSG2(_(e_invexpr2), p);
+ }
+ need_clr_eos = false;
+ break;
+ }
+ need_clr_eos = false;
}
- need_clr_eos = FALSE;
if (!eap->skip) {
if (atstart) {
@@ -19244,9 +19588,11 @@ void ex_echo(exarg_T *eap)
msg_sb_eol();
msg_start();
}
- } else if (eap->cmdidx == CMD_echo)
- msg_puts_attr((char_u *)" ", echo_attr);
- char_u *tofree = p = (char_u *) encode_tv2echo(&rettv, NULL);
+ } else if (eap->cmdidx == CMD_echo) {
+ msg_puts_attr(" ", echo_attr);
+ }
+ char *tofree = encode_tv2echo(&rettv, NULL);
+ const char *p = tofree;
if (p != NULL) {
for (; *p != NUL && !got_int; ++p) {
if (*p == '\n' || *p == '\r' || *p == TAB) {
@@ -19255,21 +19601,18 @@ void ex_echo(exarg_T *eap)
msg_clr_eos();
needclr = false;
}
- msg_putchar_attr(*p, echo_attr);
+ msg_putchar_attr((uint8_t)(*p), echo_attr);
} else {
- if (has_mbyte) {
- int i = (*mb_ptr2len)(p);
+ int i = (*mb_ptr2len)((const char_u *)p);
- (void)msg_outtrans_len_attr(p, i, echo_attr);
- p += i - 1;
- } else
- (void)msg_outtrans_len_attr(p, 1, echo_attr);
+ (void)msg_outtrans_len_attr((char_u *)p, i, echo_attr);
+ p += i - 1;
}
}
}
xfree(tofree);
}
- clear_tv(&rettv);
+ tv_clear(&rettv);
arg = skipwhite(arg);
}
eap->nextcmd = check_nextcmd(arg);
@@ -19313,8 +19656,7 @@ void ex_execute(exarg_T *eap)
int ret = OK;
char_u *p;
garray_T ga;
- int len;
- int save_did_emsg;
+ int save_did_emsg = did_emsg;
ga_init(&ga, 1, 80);
@@ -19328,27 +19670,36 @@ void ex_execute(exarg_T *eap)
* has been cancelled due to an aborting error, an interrupt, or an
* exception.
*/
- if (!aborting())
+ if (!aborting() && did_emsg == save_did_emsg) {
EMSG2(_(e_invexpr2), p);
+ }
ret = FAIL;
break;
}
if (!eap->skip) {
- p = get_tv_string(&rettv);
- len = (int)STRLEN(p);
+ const char *const argstr = tv_get_string(&rettv);
+ const size_t len = strlen(argstr);
ga_grow(&ga, len + 2);
- if (!GA_EMPTY(&ga))
+ if (!GA_EMPTY(&ga)) {
((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
- STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
+ }
+ memcpy((char_u *)(ga.ga_data) + ga.ga_len, argstr, len + 1);
ga.ga_len += len;
}
- clear_tv(&rettv);
+ tv_clear(&rettv);
arg = skipwhite(arg);
}
if (ret != FAIL && ga.ga_data != NULL) {
+ if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr) {
+ // Mark the already saved text as finishing the line, so that what
+ // follows is displayed on a new line when scrolling back at the
+ // more prompt.
+ msg_sb_eol();
+ }
+
if (eap->cmdidx == CMD_echomsg) {
MSG_ATTR(ga.ga_data, echo_attr);
ui_flush();
@@ -19377,9 +19728,9 @@ void ex_execute(exarg_T *eap)
* Returns NULL when no option name found. Otherwise pointer to the char
* after the option name.
*/
-static char_u *find_option_end(char_u **arg, int *opt_flags)
+static const char *find_option_end(const char **const arg, int *const opt_flags)
{
- char_u *p = *arg;
+ const char *p = *arg;
++p;
if (*p == 'g' && p[1] == ':') {
@@ -19388,18 +19739,22 @@ static char_u *find_option_end(char_u **arg, int *opt_flags)
} else if (*p == 'l' && p[1] == ':') {
*opt_flags = OPT_LOCAL;
p += 2;
- } else
+ } else {
*opt_flags = 0;
+ }
- if (!ASCII_ISALPHA(*p))
+ if (!ASCII_ISALPHA(*p)) {
return NULL;
+ }
*arg = p;
- if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL)
- p += 4; /* termcap option */
- else
- while (ASCII_ISALPHA(*p))
- ++p;
+ if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) {
+ p += 4; // t_xx/termcap option
+ } else {
+ while (ASCII_ISALPHA(*p)) {
+ p++;
+ }
+ }
return p;
}
@@ -19409,6 +19764,7 @@ static char_u *find_option_end(char_u **arg, int *opt_flags)
void ex_function(exarg_T *eap)
{
char_u *theline;
+ char_u *line_to_free = NULL;
int c;
int saved_did_emsg;
int saved_wait_return = need_wait_return;
@@ -19418,10 +19774,10 @@ void ex_function(exarg_T *eap)
char_u *line_arg = NULL;
garray_T newargs;
garray_T newlines;
- int varargs = FALSE;
- int mustend = FALSE;
+ int varargs = false;
int flags = 0;
ufunc_T *fp;
+ bool overwrite = false;
int indent;
int nesting;
char_u *skip_until = NULL;
@@ -19433,6 +19789,7 @@ void ex_function(exarg_T *eap)
int todo;
hashitem_T *hi;
int sourcing_lnum_off;
+ bool show_block = false;
/*
* ":function" without argument: list functions.
@@ -19444,8 +19801,9 @@ void ex_function(exarg_T *eap)
if (!HASHITEM_EMPTY(hi)) {
--todo;
fp = HI2UF(hi);
- if (!isdigit(*fp->uf_name))
- list_func_head(fp, FALSE);
+ if (!func_name_refcount(fp->uf_name)) {
+ list_func_head(fp, false);
+ }
}
}
}
@@ -19502,7 +19860,7 @@ void ex_function(exarg_T *eap)
// s:func script-local function name
// g:func global function name, same as "func"
p = eap->arg;
- name = trans_function_name(&p, eap->skip, 0, &fudi);
+ name = trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL);
paren = (vim_strchr(p, '(') != NULL);
if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) {
/*
@@ -19511,8 +19869,9 @@ void ex_function(exarg_T *eap)
* interrupt, or an exception.
*/
if (!aborting()) {
- if (!eap->skip && fudi.fd_newkey != NULL)
+ if (fudi.fd_newkey != NULL) {
EMSG2(_(e_dictkey), fudi.fd_newkey);
+ }
xfree(fudi.fd_newkey);
return;
} else
@@ -19554,7 +19913,7 @@ void ex_function(exarg_T *eap)
}
if (!got_int) {
msg_putchar('\n');
- msg_puts((char_u *)" endfunction");
+ msg_puts(" endfunction");
}
} else
emsg_funcname(N_("E123: Undefined function: %s"), name);
@@ -19587,8 +19946,7 @@ void ex_function(exarg_T *eap)
arg = name;
else
arg = fudi.fd_newkey;
- if (arg != NULL && (fudi.fd_di == NULL
- || fudi.fd_di->di_tv.v_type != VAR_FUNC)) {
+ if (arg != NULL && (fudi.fd_di == NULL || !tv_is_func(fudi.fd_di->di_tv))) {
int j = (*arg == K_SPECIAL) ? 3 : 0;
while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
: eval_isnamec(arg[j])))
@@ -19601,59 +19959,16 @@ void ex_function(exarg_T *eap)
EMSG(_("E862: Cannot use g: here"));
}
- /*
- * Isolate the arguments: "arg1, arg2, ...)"
- */
- while (*p != ')') {
- if (p[0] == '.' && p[1] == '.' && p[2] == '.') {
- varargs = TRUE;
- p += 3;
- mustend = TRUE;
- } else {
- arg = p;
- while (ASCII_ISALNUM(*p) || *p == '_')
- ++p;
- if (arg == p || isdigit(*arg)
- || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0)
- || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) {
- if (!eap->skip)
- EMSG2(_("E125: Illegal argument: %s"), arg);
- break;
- }
- ga_grow(&newargs, 1);
- c = *p;
- *p = NUL;
- arg = vim_strsave(arg);
-
- /* Check for duplicate argument name. */
- for (int i = 0; i < newargs.ga_len; ++i)
- if (STRCMP(((char_u **)(newargs.ga_data))[i], arg) == 0) {
- EMSG2(_("E853: Duplicate argument name: %s"), arg);
- xfree(arg);
- goto erret;
- }
-
- ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg;
- *p = c;
- newargs.ga_len++;
- if (*p == ',')
- ++p;
- else
- mustend = TRUE;
- }
- p = skipwhite(p);
- if (mustend && *p != ')') {
- if (!eap->skip)
- EMSG2(_(e_invarg2), eap->arg);
- break;
- }
+ if (get_function_args(&p, ')', &newargs, &varargs, eap->skip) == FAIL) {
+ goto errret_2;
}
- if (*p != ')') {
- goto erret;
+
+ if (KeyTyped && ui_is_external(kUICmdline)) {
+ show_block = true;
+ ui_ext_cmdline_block_append(0, (const char *)eap->cmd);
}
- ++p; // skip the ')'
- /* find extra arguments "range", "dict" and "abort" */
+ // find extra arguments "range", "dict", "abort" and "closure"
for (;; ) {
p = skipwhite(p);
if (STRNCMP(p, "range", 5) == 0) {
@@ -19665,16 +19980,27 @@ void ex_function(exarg_T *eap)
} else if (STRNCMP(p, "abort", 5) == 0) {
flags |= FC_ABORT;
p += 5;
- } else
+ } else if (STRNCMP(p, "closure", 7) == 0) {
+ flags |= FC_CLOSURE;
+ p += 7;
+ if (current_funccal == NULL) {
+ emsg_funcname(N_
+ ("E932: Closure function should not be at top level: %s"),
+ name == NULL ? (char_u *)"" : name);
+ goto erret;
+ }
+ } else {
break;
+ }
}
/* When there is a line break use what follows for the function body.
* Makes 'exe "func Test()\n...\nendfunc"' work. */
- if (*p == '\n')
+ if (*p == '\n') {
line_arg = p + 1;
- else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg)
+ } else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) {
EMSG(_(e_trailing));
+ }
/*
* Read the body of the function, until ":endfunction" is found.
@@ -19693,7 +20019,9 @@ void ex_function(exarg_T *eap)
if (!eap->skip && did_emsg)
goto erret;
- msg_putchar('\n'); /* don't overwrite the function name */
+ if (!ui_is_external(kUICmdline)) {
+ msg_putchar('\n'); // don't overwrite the function name
+ }
cmdline_row = msg_row;
}
@@ -19717,16 +20045,25 @@ void ex_function(exarg_T *eap)
*p = NUL;
line_arg = p + 1;
}
- } else if (eap->getline == NULL)
- theline = getcmdline(':', 0L, indent);
- else
- theline = eap->getline(':', eap->cookie, indent);
- if (KeyTyped)
+ } else {
+ xfree(line_to_free);
+ if (eap->getline == NULL) {
+ theline = getcmdline(':', 0L, indent);
+ } else {
+ theline = eap->getline(':', eap->cookie, indent);
+ }
+ line_to_free = theline;
+ }
+ if (KeyTyped) {
lines_left = Rows - 1;
+ }
if (theline == NULL) {
EMSG(_("E126: Missing :endfunction"));
goto erret;
}
+ if (show_block) {
+ ui_ext_cmdline_block_append(indent, (const char *)theline);
+ }
/* Detect line continuation: sourcing_lnum increased more than one. */
if (sourcing_lnum > sourcing_lnum_off + 1)
@@ -19748,8 +20085,29 @@ void ex_function(exarg_T *eap)
/* Check for "endfunction". */
if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) {
- if (line_arg == NULL)
- xfree(theline);
+ if (*p == '!') {
+ p++;
+ }
+ char_u *nextcmd = NULL;
+ if (*p == '|') {
+ nextcmd = p + 1;
+ } else if (line_arg != NULL && *skipwhite(line_arg) != NUL) {
+ nextcmd = line_arg;
+ } else if (*p != NUL && *p != '"' && p_verbose > 0) {
+ give_warning2((char_u *)_("W22: Text found after :endfunction: %s"),
+ p, true);
+ }
+ if (nextcmd != NULL) {
+ // Another command follows. If the line came from "eap" we
+ // can simply point into it, otherwise we need to change
+ // "eap->cmdlinep".
+ eap->nextcmd = nextcmd;
+ if (line_to_free != NULL) {
+ xfree(*eap->cmdlinep);
+ *eap->cmdlinep = line_to_free;
+ line_to_free = NULL;
+ }
+ }
break;
}
@@ -19768,17 +20126,23 @@ void ex_function(exarg_T *eap)
if (*p == '!') {
p = skipwhite(p + 1);
}
- p += eval_fname_script(p);
- xfree(trans_function_name(&p, TRUE, 0, NULL));
+ p += eval_fname_script((const char *)p);
+ xfree(trans_function_name(&p, true, 0, NULL, NULL));
if (*skipwhite(p) == '(') {
nesting++;
indent += 2;
}
}
- /* Check for ":append" or ":insert". */
+ // Check for ":append", ":change", ":insert".
p = skip_range(p, NULL);
if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p'))
+ || (p[0] == 'c'
+ && (!ASCII_ISALPHA(p[1])
+ || (p[1] == 'h' && (!ASCII_ISALPHA(p[2])
+ || (p[2] == 'a'
+ && (STRNCMP(&p[3], "nge", 3) != 0
+ || !ASCII_ISALPHA(p[6])))))))
|| (p[0] == 'i'
&& (!ASCII_ISALPHA(p[1]) || (p[1] == 'n'
&& (!ASCII_ISALPHA(p[2])
@@ -19790,7 +20154,9 @@ void ex_function(exarg_T *eap)
arg = skipwhite(skiptowhite(p));
if (arg[0] == '<' && arg[1] =='<'
&& ((p[0] == 'p' && p[1] == 'y'
- && (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
+ && (!ASCII_ISALNUM(p[2]) || p[2] == 't'
+ || ((p[2] == '3' || p[2] == 'x')
+ && !ASCII_ISALPHA(p[3]))))
|| (p[0] == 'p' && p[1] == 'e'
&& (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
|| (p[0] == 't' && p[1] == 'c'
@@ -19818,11 +20184,7 @@ void ex_function(exarg_T *eap)
* allocates 250 bytes per line, this saves 80% on average. The cost
* is an extra alloc/free. */
p = vim_strsave(theline);
- if (line_arg == NULL)
- xfree(theline);
- theline = p;
-
- ((char_u **)(newlines.ga_data))[newlines.ga_len++] = theline;
+ ((char_u **)(newlines.ga_data))[newlines.ga_len++] = p;
/* Add NULL lines for continuation lines, so that the line count is
* equal to the index in the growarray. */
@@ -19843,7 +20205,7 @@ void ex_function(exarg_T *eap)
* If there are no errors, add the function
*/
if (fudi.fd_dict == NULL) {
- v = find_var(name, &ht, FALSE);
+ v = find_var((const char *)name, STRLEN(name), &ht, false);
if (v != NULL && v->di_tv.v_type == VAR_FUNC) {
emsg_funcname(N_("E707: Function name conflicts with variable: %s"),
name);
@@ -19856,16 +20218,25 @@ void ex_function(exarg_T *eap)
emsg_funcname(e_funcexts, name);
goto erret;
}
- if (fp->uf_refcount > 1 || fp->uf_calls > 0) {
+ if (fp->uf_calls > 0) {
emsg_funcname(N_("E127: Cannot redefine function %s: It is in use"),
name);
goto erret;
}
- /* redefine existing function */
- ga_clear_strings(&(fp->uf_args));
- ga_clear_strings(&(fp->uf_lines));
- xfree(name);
- name = NULL;
+ if (fp->uf_refcount > 1) {
+ // This function is referenced somewhere, don't redefine it but
+ // create a new one.
+ (fp->uf_refcount)--;
+ fp->uf_flags |= FC_REMOVED;
+ fp = NULL;
+ overwrite = true;
+ } else {
+ // redefine existing function
+ ga_clear_strings(&(fp->uf_args));
+ ga_clear_strings(&(fp->uf_lines));
+ xfree(name);
+ name = NULL;
+ }
}
} else {
char numbuf[20];
@@ -19876,11 +20247,13 @@ void ex_function(exarg_T *eap)
goto erret;
}
if (fudi.fd_di == NULL) {
- if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg, false)) {
+ if (tv_check_lock(fudi.fd_dict->dv_lock, (const char *)eap->arg,
+ TV_CSTRING)) {
// Can't add a function to a locked dictionary
goto erret;
}
- } else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg, false)) {
+ } else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, (const char *)eap->arg,
+ TV_CSTRING)) {
// Can't change an existing function if it is locked
goto erret;
}
@@ -19900,7 +20273,7 @@ void ex_function(exarg_T *eap)
/* Check that the autoload name matches the script name. */
int j = FAIL;
if (sourcing_name != NULL) {
- scriptname = autoload_name(name);
+ scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name));
p = vim_strchr(scriptname, '/');
plen = (int)STRLEN(p);
slen = (int)STRLEN(sourcing_name);
@@ -19917,20 +20290,21 @@ void ex_function(exarg_T *eap)
}
}
- fp = xmalloc(sizeof(ufunc_T) + STRLEN(name));
+ fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
if (fudi.fd_dict != NULL) {
if (fudi.fd_di == NULL) {
- /* add new dict entry */
- fudi.fd_di = dictitem_alloc(fudi.fd_newkey);
- if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) {
+ // Add new dict entry
+ fudi.fd_di = tv_dict_item_alloc((const char *)fudi.fd_newkey);
+ if (tv_dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) {
xfree(fudi.fd_di);
xfree(fp);
goto erret;
}
- } else
- /* overwrite existing dict entry */
- clear_tv(&fudi.fd_di->di_tv);
+ } else {
+ // Overwrite existing dict entry.
+ tv_clear(&fudi.fd_di->di_tv);
+ }
fudi.fd_di->di_tv.v_type = VAR_FUNC;
fudi.fd_di->di_tv.v_lock = 0;
fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
@@ -19941,14 +20315,22 @@ void ex_function(exarg_T *eap)
/* insert the new function in the function list */
STRCPY(fp->uf_name, name);
- if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) {
- xfree(fp);
- goto erret;
+ if (overwrite) {
+ hi = hash_find(&func_hashtab, name);
+ hi->hi_key = UF2HIKEY(fp);
+ } else if (hash_add(&func_hashtab, UF2HIKEY(fp)) == FAIL) {
+ xfree(fp);
+ goto erret;
}
+ fp->uf_refcount = 1;
}
- fp->uf_refcount = 1;
fp->uf_args = newargs;
fp->uf_lines = newlines;
+ if ((flags & FC_CLOSURE) != 0) {
+ register_closure(fp);
+ } else {
+ fp->uf_scoped = NULL;
+ }
fp->uf_tml_count = NULL;
fp->uf_tml_total = NULL;
fp->uf_tml_self = NULL;
@@ -19963,38 +20345,43 @@ void ex_function(exarg_T *eap)
erret:
ga_clear_strings(&newargs);
+errret_2:
ga_clear_strings(&newlines);
ret_free:
xfree(skip_until);
+ xfree(line_to_free);
xfree(fudi.fd_newkey);
xfree(name);
did_emsg |= saved_did_emsg;
need_wait_return |= saved_wait_return;
+ if (show_block) {
+ ui_ext_cmdline_block_leave();
+ }
}
-/*
- * Get a function name, translating "<SID>" and "<SNR>".
- * Also handles a Funcref in a List or Dictionary.
- * Returns the function name in allocated memory, or NULL for failure.
- * flags:
- * TFN_INT: internal function name OK
- * TFN_QUIET: be quiet
- * TFN_NO_AUTOLOAD: do not use script autoloading
- * Advances "pp" to just after the function name (if no error).
- */
+/// Get a function name, translating "<SID>" and "<SNR>".
+/// Also handles a Funcref in a List or Dictionary.
+/// flags:
+/// TFN_INT: internal function name OK
+/// TFN_QUIET: be quiet
+/// TFN_NO_AUTOLOAD: do not use script autoloading
+/// TFN_NO_DEREF: do not dereference a Funcref
+/// Advances "pp" to just after the function name (if no error).
+///
+/// @return the function name in allocated memory, or NULL for failure.
static char_u *
-trans_function_name (
+trans_function_name(
char_u **pp,
- int skip, /* only find the end, don't evaluate */
+ int skip, // only find the end, don't evaluate
int flags,
- funcdict_T *fdp /* return: info about dictionary used */
+ funcdict_T *fdp, // return: info about dictionary used
+ partial_T **partial // return: partial of a FuncRef
)
{
char_u *name = NULL;
- char_u *start;
- char_u *end;
+ const char_u *start;
+ const char_u *end;
int lead;
- char_u sid_buf[20];
int len;
lval_T lv;
@@ -20007,19 +20394,20 @@ trans_function_name (
if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA
&& (*pp)[2] == (int)KE_SNR) {
*pp += 3;
- len = get_id_len(pp) + 3;
- return vim_strnsave(start, len);
+ len = get_id_len((const char **)pp) + 3;
+ return (char_u *)xmemdupz(start, len);
}
/* A name starting with "<SID>" or "<SNR>" is local to a script. But
* don't skip over "s:", get_lval() needs it for "s:dict.func". */
- lead = eval_fname_script(start);
- if (lead > 2)
+ lead = eval_fname_script((const char *)start);
+ if (lead > 2) {
start += lead;
+ }
- /* Note that TFN_ flags use the same values as GLV_ flags. */
- end = get_lval(start, NULL, &lv, FALSE, skip, flags,
- lead > 2 ? 0 : FNE_CHECK_START);
+ // Note that TFN_ flags use the same values as GLV_ flags.
+ end = get_lval((char_u *)start, NULL, &lv, false, skip, flags | GLV_READ_ONLY,
+ lead > 2 ? 0 : FNE_CHECK_START);
if (end == start) {
if (!skip)
EMSG(_("E129: Function name required"));
@@ -20032,10 +20420,12 @@ trans_function_name (
* interrupt, or an exception.
*/
if (!aborting()) {
- if (end != NULL)
- EMSG2(_(e_invarg2), start);
- } else
- *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR);
+ if (end != NULL) {
+ emsgf(_(e_invarg2), start);
+ }
+ } else {
+ *pp = (char_u *)find_name_end(start, NULL, NULL, FNE_INCL_BR);
+ }
goto theend;
}
@@ -20048,14 +20438,21 @@ trans_function_name (
}
if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) {
name = vim_strsave(lv.ll_tv->vval.v_string);
- *pp = end;
+ *pp = (char_u *)end;
+ } else if (lv.ll_tv->v_type == VAR_PARTIAL
+ && lv.ll_tv->vval.v_partial != NULL) {
+ name = vim_strsave(partial_name(lv.ll_tv->vval.v_partial));
+ *pp = (char_u *)end;
+ if (partial != NULL) {
+ *partial = lv.ll_tv->vval.v_partial;
+ }
} else {
if (!skip && !(flags & TFN_QUIET) && (fdp == NULL
|| lv.ll_dict == NULL
|| fdp->fd_newkey == NULL)) {
EMSG(_(e_funcref));
} else {
- *pp = end;
+ *pp = (char_u *)end;
}
name = NULL;
}
@@ -20063,26 +20460,30 @@ trans_function_name (
}
if (lv.ll_name == NULL) {
- /* Error found, but continue after the function name. */
- *pp = end;
+ // Error found, but continue after the function name.
+ *pp = (char_u *)end;
goto theend;
}
/* Check if the name is a Funcref. If so, use the value. */
if (lv.ll_exp_name != NULL) {
- len = (int)STRLEN(lv.ll_exp_name);
- name = deref_func_name(lv.ll_exp_name, &len, flags & TFN_NO_AUTOLOAD);
- if (name == lv.ll_exp_name)
+ len = (int)strlen(lv.ll_exp_name);
+ name = deref_func_name(lv.ll_exp_name, &len, partial,
+ flags & TFN_NO_AUTOLOAD);
+ if ((const char *)name == lv.ll_exp_name) {
name = NULL;
- } else {
+ }
+ } else if (!(flags & TFN_NO_DEREF)) {
len = (int)(end - *pp);
- name = deref_func_name(*pp, &len, flags & TFN_NO_AUTOLOAD);
- if (name == *pp)
+ name = deref_func_name((const char *)(*pp), &len, partial,
+ flags & TFN_NO_AUTOLOAD);
+ if (name == *pp) {
name = NULL;
+ }
}
if (name != NULL) {
name = vim_strsave(name);
- *pp = end;
+ *pp = (char_u *)end;
if (strncmp((char *)name, "<SNR>", 5) == 0) {
// Change "<SNR>" to the byte sequence.
name[0] = K_SPECIAL;
@@ -20094,12 +20495,13 @@ trans_function_name (
}
if (lv.ll_exp_name != NULL) {
- len = (int)STRLEN(lv.ll_exp_name);
+ len = (int)strlen(lv.ll_exp_name);
if (lead <= 2 && lv.ll_name == lv.ll_exp_name
- && STRNCMP(lv.ll_name, "s:", 2) == 0) {
- /* When there was "s:" already or the name expanded to get a
- * leading "s:" then remove it. */
+ && lv.ll_name_len >= 2 && memcmp(lv.ll_name, "s:", 2) == 0) {
+ // When there was "s:" already or the name expanded to get a
+ // leading "s:" then remove it.
lv.ll_name += 2;
+ lv.ll_name_len -= 2;
len -= 2;
lead = 2;
}
@@ -20107,37 +20509,41 @@ trans_function_name (
// Skip over "s:" and "g:".
if (lead == 2 || (lv.ll_name[0] == 'g' && lv.ll_name[1] == ':')) {
lv.ll_name += 2;
+ lv.ll_name_len -= 2;
}
- len = (int)(end - lv.ll_name);
+ len = (int)((const char *)end - lv.ll_name);
}
- /*
- * Copy the function name to allocated memory.
- * Accept <SID>name() inside a script, translate into <SNR>123_name().
- * Accept <SNR>123_name() outside a script.
- */
- if (skip)
- lead = 0; /* do nothing */
- else if (lead > 0) {
+ size_t sid_buf_len = 0;
+ char sid_buf[20];
+
+ // Copy the function name to allocated memory.
+ // Accept <SID>name() inside a script, translate into <SNR>123_name().
+ // Accept <SNR>123_name() outside a script.
+ if (skip) {
+ lead = 0; // do nothing
+ } else if (lead > 0) {
lead = 3;
if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name))
- || eval_fname_sid(*pp)) {
- /* It's "s:" or "<SID>" */
+ || eval_fname_sid((const char *)(*pp))) {
+ // It's "s:" or "<SID>".
if (current_SID <= 0) {
EMSG(_(e_usingsid));
goto theend;
}
- sprintf((char *)sid_buf, "%" PRId64 "_", (int64_t)current_SID);
- lead += (int)STRLEN(sid_buf);
+ sid_buf_len = snprintf(sid_buf, sizeof(sid_buf),
+ "%" PRIdSCID "_", current_SID);
+ lead += sid_buf_len;
}
- } else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len)) {
+ } else if (!(flags & TFN_INT)
+ && builtin_function(lv.ll_name, lv.ll_name_len)) {
EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"),
start);
goto theend;
}
- if (!skip && !(flags & TFN_QUIET)) {
- char_u *cp = vim_strchr(lv.ll_name, ':');
+ if (!skip && !(flags & TFN_QUIET) && !(flags & TFN_NO_DEREF)) {
+ char_u *cp = xmemrchr(lv.ll_name, ':', lv.ll_name_len);
if (cp != NULL && cp < end) {
EMSG2(_("E884: Function name cannot contain a colon: %s"), start);
@@ -20150,12 +20556,13 @@ trans_function_name (
name[0] = K_SPECIAL;
name[1] = KS_EXTRA;
name[2] = (int)KE_SNR;
- if (lead > 3) /* If it's "<SID>" */
- STRCPY(name + 3, sid_buf);
+ if (sid_buf_len > 0) { // If it's "<SID>"
+ memcpy(name + 3, sid_buf, sid_buf_len);
+ }
}
- memmove(name + lead, lv.ll_name, (size_t)len);
+ memmove(name + lead, lv.ll_name, len);
name[lead + len] = NUL;
- *pp = end;
+ *pp = (char_u *)end;
theend:
clear_lval(&lv);
@@ -20167,23 +20574,34 @@ theend:
* Return 2 if "p" starts with "s:".
* Return 0 otherwise.
*/
-static int eval_fname_script(char_u *p)
+static int eval_fname_script(const char *const p)
{
- if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0
- || STRNICMP(p + 1, "SNR>", 4) == 0))
+ // Use mb_strnicmp() because in Turkish comparing the "I" may not work with
+ // the standard library function.
+ if (p[0] == '<'
+ && (mb_strnicmp((char_u *)p + 1, (char_u *)"SID>", 4) == 0
+ || mb_strnicmp((char_u *)p + 1, (char_u *)"SNR>", 4) == 0)) {
return 5;
- if (p[0] == 's' && p[1] == ':')
+ }
+ if (p[0] == 's' && p[1] == ':') {
return 2;
+ }
return 0;
}
-/*
- * Return TRUE if "p" starts with "<SID>" or "s:".
- * Only works if eval_fname_script() returned non-zero for "p"!
- */
-static int eval_fname_sid(char_u *p)
+/// Check whether function name starts with <SID> or s:
+///
+/// @warning Only works for names previously checked by eval_fname_script(), if
+/// it returned non-zero.
+///
+/// @param[in] name Name to check.
+///
+/// @return true if it starts with <SID> or s:, false otherwise.
+static inline bool eval_fname_sid(const char *const name)
+ FUNC_ATTR_PURE FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_ALL
{
- return *p == 's' || TOUPPER_ASC(p[2]) == 'I';
+ return *name == 's' || TOUPPER_ASC(name[2]) == 'I';
}
/*
@@ -20196,39 +20614,46 @@ static void list_func_head(ufunc_T *fp, int indent)
MSG_PUTS(" ");
MSG_PUTS("function ");
if (fp->uf_name[0] == K_SPECIAL) {
- MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
- msg_puts(fp->uf_name + 3);
- } else
- msg_puts(fp->uf_name);
+ MSG_PUTS_ATTR("<SNR>", HL_ATTR(HLF_8));
+ msg_puts((const char *)fp->uf_name + 3);
+ } else {
+ msg_puts((const char *)fp->uf_name);
+ }
msg_putchar('(');
int j;
- for (j = 0; j < fp->uf_args.ga_len; ++j) {
- if (j)
- MSG_PUTS(", ");
- msg_puts(FUNCARG(fp, j));
+ for (j = 0; j < fp->uf_args.ga_len; j++) {
+ if (j) {
+ msg_puts(", ");
+ }
+ msg_puts((const char *)FUNCARG(fp, j));
}
if (fp->uf_varargs) {
- if (j)
- MSG_PUTS(", ");
- MSG_PUTS("...");
+ if (j) {
+ msg_puts(", ");
+ }
+ msg_puts("...");
}
msg_putchar(')');
- if (fp->uf_flags & FC_ABORT)
- MSG_PUTS(" abort");
- if (fp->uf_flags & FC_RANGE)
- MSG_PUTS(" range");
- if (fp->uf_flags & FC_DICT)
- MSG_PUTS(" dict");
+ if (fp->uf_flags & FC_ABORT) {
+ msg_puts(" abort");
+ }
+ if (fp->uf_flags & FC_RANGE) {
+ msg_puts(" range");
+ }
+ if (fp->uf_flags & FC_DICT) {
+ msg_puts(" dict");
+ }
+ if (fp->uf_flags & FC_CLOSURE) {
+ msg_puts(" closure");
+ }
msg_clr_eos();
if (p_verbose > 0)
last_set_msg(fp->uf_script_ID);
}
-/*
- * Find a function by name, return pointer to it in ufuncs.
- * Return NULL for unknown function.
- */
-static ufunc_T *find_func(char_u *name)
+/// Find a function by name, return pointer to it in ufuncs.
+/// @return NULL for unknown function.
+static ufunc_T *find_func(const char_u *name)
{
hashitem_T *hi;
@@ -20242,61 +20667,124 @@ static ufunc_T *find_func(char_u *name)
void free_all_functions(void)
{
hashitem_T *hi;
+ ufunc_T *fp;
+ uint64_t skipped = 0;
+ uint64_t todo = 1;
+ uint64_t used;
+
+ // Clean up the call stack.
+ while (current_funccal != NULL) {
+ tv_clear(current_funccal->rettv);
+ cleanup_function_call(current_funccal);
+ }
+
+ // First clear what the functions contain. Since this may lower the
+ // reference count of a function, it may also free a function and change
+ // the hash table. Restart if that happens.
+ while (todo > 0) {
+ todo = func_hashtab.ht_used;
+ for (hi = func_hashtab.ht_array; todo > 0; hi++) {
+ if (!HASHITEM_EMPTY(hi)) {
+ // Only free functions that are not refcounted, those are
+ // supposed to be freed when no longer referenced.
+ fp = HI2UF(hi);
+ if (func_name_refcount(fp->uf_name)) {
+ skipped++;
+ } else {
+ used = func_hashtab.ht_used;
+ func_clear(fp, true);
+ if (used != func_hashtab.ht_used) {
+ skipped = 0;
+ break;
+ }
+ }
+ todo--;
+ }
+ }
+ }
- /* Need to start all over every time, because func_free() may change the
- * hash table. */
- while (func_hashtab.ht_used > 0)
- for (hi = func_hashtab.ht_array;; ++hi)
+ // Now actually free the functions. Need to start all over every time,
+ // because func_free() may change the hash table.
+ skipped = 0;
+ while (func_hashtab.ht_used > skipped) {
+ todo = func_hashtab.ht_used;
+ for (hi = func_hashtab.ht_array; todo > 0; hi++) {
if (!HASHITEM_EMPTY(hi)) {
- func_free(HI2UF(hi));
- break;
+ todo--;
+ // Only free functions that are not refcounted, those are
+ // supposed to be freed when no longer referenced.
+ fp = HI2UF(hi);
+ if (func_name_refcount(fp->uf_name)) {
+ skipped++;
+ } else {
+ func_free(fp);
+ skipped = 0;
+ break;
+ }
}
+ }
+ }
+ if (skipped == 0) {
+ hash_clear(&func_hashtab);
+ }
}
#endif
-int translated_function_exists(char_u *name)
+bool translated_function_exists(const char *name)
{
if (builtin_function(name, -1)) {
- return find_internal_func(name) >= 0;
+ return find_internal_func((char *)name) != NULL;
}
- return find_func(name) != NULL;
+ return find_func((const char_u *)name) != NULL;
}
-/*
- * Return TRUE if a function "name" exists.
- */
-static int function_exists(char_u *name)
+/// Check whether function with the given name exists
+///
+/// @param[in] name Function name.
+/// @param[in] no_deref Whether to dereference a Funcref.
+///
+/// @return True if it exists, false otherwise.
+static bool function_exists(const char *const name, bool no_deref)
{
- char_u *nm = name;
- char_u *p;
- int n = FALSE;
+ const char_u *nm = (const char_u *)name;
+ bool n = false;
+ int flag = TFN_INT | TFN_QUIET | TFN_NO_AUTOLOAD;
- p = trans_function_name(&nm, FALSE, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD,
- NULL);
+ if (no_deref) {
+ flag |= TFN_NO_DEREF;
+ }
+ char *const p = (char *)trans_function_name((char_u **)&nm, false, flag, NULL,
+ NULL);
nm = skipwhite(nm);
/* Only accept "funcname", "funcname ", "funcname (..." and
* "funcname(...", not "funcname!...". */
- if (p != NULL && (*nm == NUL || *nm == '('))
+ if (p != NULL && (*nm == NUL || *nm == '(')) {
n = translated_function_exists(p);
+ }
xfree(p);
return n;
}
-/// Return TRUE if "name" looks like a builtin function name: starts with a
+/// Checks if a builtin function with the given name exists.
+///
+/// @param[in] name name of the builtin function to check.
+/// @param[in] len length of "name", or -1 for NUL terminated.
+///
+/// @return true if "name" looks like a builtin function name: starts with a
/// lower case letter and doesn't contain AUTOLOAD_CHAR.
-/// "len" is the length of "name", or -1 for NUL terminated.
-static bool builtin_function(char_u *name, int len)
+static bool builtin_function(const char *name, int len)
{
if (!ASCII_ISLOWER(name[0])) {
- return FALSE;
+ return false;
}
- char_u *p = vim_strchr(name, AUTOLOAD_CHAR);
+ const char *p = (len == -1
+ ? strchr(name, AUTOLOAD_CHAR)
+ : memchr(name, AUTOLOAD_CHAR, (size_t)len));
- return p == NULL
- || (len > 0 && p > name + len);
+ return p == NULL;
}
/*
@@ -20390,8 +20878,8 @@ void func_dump_profile(FILE *fd)
xfree(sorttab);
}
-static void
-prof_sort_list (
+static void
+prof_sort_list(
FILE *fd,
ufunc_T **sorttab,
int st_len,
@@ -20462,44 +20950,45 @@ static int prof_self_cmp(const void *s1, const void *s2)
}
-/*
- * If "name" has a package name try autoloading the script for it.
- * Return TRUE if a package was loaded.
- */
-static int
-script_autoload (
- char_u *name,
- int reload /* load script again when already loaded */
-)
+/// If name has a package name try autoloading the script for it
+///
+/// @param[in] name Variable/function name.
+/// @param[in] name_len Name length.
+/// @param[in] reload If true, load script again when already loaded.
+///
+/// @return true if a package was loaded.
+static bool script_autoload(const char *const name, const size_t name_len,
+ const bool reload)
{
- char_u *p;
- char_u *scriptname, *tofree;
- int ret = FALSE;
- int i;
-
- /* If there is no '#' after name[0] there is no package name. */
- p = vim_strchr(name, AUTOLOAD_CHAR);
- if (p == NULL || p == name)
- return FALSE;
+ // If there is no '#' after name[0] there is no package name.
+ const char *p = memchr(name, AUTOLOAD_CHAR, name_len);
+ if (p == NULL || p == name) {
+ return false;
+ }
- tofree = scriptname = autoload_name(name);
+ bool ret = false;
+ char *tofree = autoload_name(name, name_len);
+ char *scriptname = tofree;
- /* Find the name in the list of previously loaded package names. Skip
- * "autoload/", it's always the same. */
- for (i = 0; i < ga_loaded.ga_len; ++i)
- if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
+ // Find the name in the list of previously loaded package names. Skip
+ // "autoload/", it's always the same.
+ int i = 0;
+ for (; i < ga_loaded.ga_len; i++) {
+ if (STRCMP(((char **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) {
break;
- if (!reload && i < ga_loaded.ga_len)
- ret = FALSE; /* was loaded already */
- else {
- /* Remember the name if it wasn't loaded already. */
+ }
+ }
+ if (!reload && i < ga_loaded.ga_len) {
+ ret = false; // Was loaded already.
+ } else {
+ // Remember the name if it wasn't loaded already.
if (i == ga_loaded.ga_len) {
- GA_APPEND(char_u *, &ga_loaded, scriptname);
+ GA_APPEND(char *, &ga_loaded, scriptname);
tofree = NULL;
}
// Try loading the package from $VIMRUNTIME/autoload/<name>.vim
- if (source_runtime(scriptname, 0) == OK) {
+ if (source_runtime((char_u *)scriptname, 0) == OK) {
ret = true;
}
}
@@ -20508,21 +20997,29 @@ script_autoload (
return ret;
}
-/*
- * Return the autoload script name for a function or variable name.
- */
-static char_u *autoload_name(char_u *name)
+/// Return the autoload script name for a function or variable name
+///
+/// @param[in] name Variable/function name.
+/// @param[in] name_len Name length.
+///
+/// @return [allocated] autoload script name.
+static char *autoload_name(const char *const name, const size_t name_len)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
- /* Get the script file name: replace '#' with '/', append ".vim". */
- char_u *scriptname = xmalloc(STRLEN(name) + 14);
- STRCPY(scriptname, "autoload/");
- STRCAT(scriptname, name);
- *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL;
- STRCAT(scriptname, ".vim");
-
- char_u *p;
- while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL)
- *p = '/';
+ // Get the script file name: replace '#' with '/', append ".vim".
+ char *const scriptname = xmalloc(name_len + sizeof("autoload/.vim"));
+ memcpy(scriptname, "autoload/", sizeof("autoload/") - 1);
+ memcpy(scriptname + sizeof("autoload/") - 1, name, name_len);
+ size_t auchar_idx = 0;
+ for (size_t i = sizeof("autoload/") - 1;
+ i - sizeof("autoload/") + 1 < name_len;
+ i++) {
+ if (scriptname[i] == AUTOLOAD_CHAR) {
+ scriptname[i] = '/';
+ auchar_idx = i;
+ }
+ }
+ memcpy(scriptname + auchar_idx, ".vim", sizeof(".vim"));
return scriptname;
}
@@ -20550,11 +21047,14 @@ char_u *get_user_func_name(expand_T *xp, int idx)
++hi;
fp = HI2UF(hi);
- if (fp->uf_flags & FC_DICT)
- return (char_u *)""; /* don't show dict functions */
+ if ((fp->uf_flags & FC_DICT)
+ || STRNCMP(fp->uf_name, "<lambda>", 8) == 0) {
+ return (char_u *)""; // don't show dict and lambda functions
+ }
- if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
- return fp->uf_name; /* prevents overflow */
+ if (STRLEN(fp->uf_name) + 4 >= IOSIZE) {
+ return fp->uf_name; // Prevent overflow.
+ }
cat_func_name(IObuff, fp);
if (xp->xp_context != EXPAND_USER_FUNC) {
@@ -20582,9 +21082,18 @@ static void cat_func_name(char_u *buf, ufunc_T *fp)
STRCPY(buf, fp->uf_name);
}
-/*
- * ":delfunction {name}"
- */
+/// There are two kinds of function names:
+/// 1. ordinary names, function defined with :function
+/// 2. numbered functions and lambdas
+/// For the first we only count the name stored in func_hashtab as a reference,
+/// using function() does not count as a reference, because the function is
+/// looked up by name.
+static bool func_name_refcount(char_u *name)
+{
+ return isdigit(*name) || *name == '<';
+}
+
+/// ":delfunction {name}"
void ex_delfunction(exarg_T *eap)
{
ufunc_T *fp = NULL;
@@ -20593,7 +21102,7 @@ void ex_delfunction(exarg_T *eap)
funcdict_T fudi;
p = eap->arg;
- name = trans_function_name(&p, eap->skip, 0, &fudi);
+ name = trans_function_name(&p, eap->skip, 0, &fudi, NULL);
xfree(fudi.fd_newkey);
if (name == NULL) {
if (fudi.fd_dict != NULL && !eap->skip)
@@ -20615,7 +21124,9 @@ void ex_delfunction(exarg_T *eap)
if (!eap->skip) {
if (fp == NULL) {
- EMSG2(_(e_nofunc), eap->arg);
+ if (!eap->forceit) {
+ EMSG2(_(e_nofunc), eap->arg);
+ }
return;
}
if (fp->uf_calls > 0) {
@@ -20631,96 +21142,188 @@ void ex_delfunction(exarg_T *eap)
}
if (fudi.fd_dict != NULL) {
- /* Delete the dict item that refers to the function, it will
- * invoke func_unref() and possibly delete the function. */
- dictitem_remove(fudi.fd_dict, fudi.fd_di);
- } else
- func_free(fp);
+ // Delete the dict item that refers to the function, it will
+ // invoke func_unref() and possibly delete the function.
+ tv_dict_item_remove(fudi.fd_dict, fudi.fd_di);
+ } else {
+ // A normal function (not a numbered function or lambda) has a
+ // refcount of 1 for the entry in the hashtable. When deleting
+ // it and the refcount is more than one, it should be kept.
+ // A numbered function or lambda should be kept if the refcount is
+ // one or more.
+ if (fp->uf_refcount > (func_name_refcount(fp->uf_name) ? 0 : 1)) {
+ // Function is still referenced somewhere. Don't free it but
+ // do remove it from the hashtable.
+ if (func_remove(fp)) {
+ fp->uf_refcount--;
+ }
+ fp->uf_flags |= FC_DELETED;
+ } else {
+ func_clear_free(fp, false);
+ }
+ }
}
}
-/*
- * Free a function and remove it from the list of functions.
- */
-static void func_free(ufunc_T *fp)
+/// Remove the function from the function hashtable. If the function was
+/// deleted while it still has references this was already done.
+///
+/// @return true if the entry was deleted, false if it wasn't found.
+static bool func_remove(ufunc_T *fp)
{
- hashitem_T *hi;
+ hashitem_T *hi = hash_find(&func_hashtab, UF2HIKEY(fp));
- /* clear this function */
+ if (!HASHITEM_EMPTY(hi)) {
+ hash_remove(&func_hashtab, hi);
+ return true;
+ }
+
+ return false;
+}
+
+/// Free all things that a function contains. Does not free the function
+/// itself, use func_free() for that.
+///
+/// param[in] force When true, we are exiting.
+static void func_clear(ufunc_T *fp, bool force)
+{
+ if (fp->uf_cleared) {
+ return;
+ }
+ fp->uf_cleared = true;
+
+ // clear this function
ga_clear_strings(&(fp->uf_args));
ga_clear_strings(&(fp->uf_lines));
xfree(fp->uf_tml_count);
xfree(fp->uf_tml_total);
xfree(fp->uf_tml_self);
+ funccal_unref(fp->uf_scoped, fp, force);
+}
- /* remove the function from the function hashtable */
- hi = hash_find(&func_hashtab, UF2HIKEY(fp));
- if (HASHITEM_EMPTY(hi))
- EMSG2(_(e_intern2), "func_free()");
- else
- hash_remove(&func_hashtab, hi);
-
+/// Free a function and remove it from the list of functions. Does not free
+/// what a function contains, call func_clear() first.
+///
+/// param[in] fp The function to free.
+static void func_free(ufunc_T *fp)
+{
+ // only remove it when not done already, otherwise we would remove a newer
+ // version of the function
+ if ((fp->uf_flags & (FC_DELETED | FC_REMOVED)) == 0) {
+ func_remove(fp);
+ }
xfree(fp);
}
+/// Free all things that a function contains and free the function itself.
+///
+/// param[in] force When true, we are exiting.
+static void func_clear_free(ufunc_T *fp, bool force)
+{
+ func_clear(fp, force);
+ func_free(fp);
+}
+
/*
* Unreference a Function: decrement the reference count and free it when it
- * becomes zero. Only for numbered functions.
+ * becomes zero.
*/
void func_unref(char_u *name)
{
- ufunc_T *fp;
+ ufunc_T *fp = NULL;
- if (name != NULL && isdigit(*name)) {
- fp = find_func(name);
- if (fp == NULL) {
- EMSG2(_(e_intern2), "func_unref()");
- } else {
- user_func_unref(fp);
+ if (name == NULL || !func_name_refcount(name)) {
+ return;
+ }
+
+ fp = find_func(name);
+ if (fp == NULL && isdigit(*name)) {
+#ifdef EXITFREE
+ if (!entered_free_all_mem) {
+ internal_error("func_unref()");
+ abort();
}
+#else
+ internal_error("func_unref()");
+ abort();
+#endif
}
+ func_ptr_unref(fp);
}
-static void user_func_unref(ufunc_T *fp)
+/// Unreference a Function: decrement the reference count and free it when it
+/// becomes zero.
+/// Unreference user function, freeing it if needed
+///
+/// Decrements the reference count and frees when it becomes zero.
+///
+/// @param fp Function to unreference.
+void func_ptr_unref(ufunc_T *fp)
{
- if (--fp->uf_refcount <= 0) {
- // Only delete it when it's not being used. Otherwise it's done
+ if (fp != NULL && --fp->uf_refcount <= 0) {
+ // Only delete it when it's not being used. Otherwise it's done
// when "uf_calls" becomes zero.
if (fp->uf_calls == 0) {
- func_free(fp);
+ func_clear_free(fp, false);
}
}
}
-/*
- * Count a reference to a Function.
- */
+/// Count a reference to a Function.
void func_ref(char_u *name)
{
ufunc_T *fp;
- if (name != NULL && isdigit(*name)) {
- fp = find_func(name);
- if (fp == NULL)
- EMSG2(_(e_intern2), "func_ref()");
- else
- ++fp->uf_refcount;
+ if (name == NULL || !func_name_refcount(name)) {
+ return;
+ }
+ fp = find_func(name);
+ if (fp != NULL) {
+ (fp->uf_refcount)++;
+ } else if (isdigit(*name)) {
+ // Only give an error for a numbered function.
+ // Fail silently, when named or lambda function isn't found.
+ internal_error("func_ref()");
}
}
-/*
- * Call a user function.
- */
-static void
-call_user_func (
- ufunc_T *fp, /* pointer to function */
- int argcount, /* nr of args */
- typval_T *argvars, /* arguments */
- typval_T *rettv, /* return value */
- linenr_T firstline, /* first line of range */
- linenr_T lastline, /* last line of range */
- dict_T *selfdict /* Dictionary for "self" */
-)
+/// Count a reference to a Function.
+void func_ptr_ref(ufunc_T *fp)
+{
+ if (fp != NULL) {
+ (fp->uf_refcount)++;
+ }
+}
+
+/// Check whether funccall is still referenced outside
+///
+/// It is supposed to be referenced if either it is referenced itself or if l:,
+/// a: or a:000 are referenced as all these are statically allocated within
+/// funccall structure.
+static inline bool fc_referenced(const funccall_T *const fc)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_ALL
+{
+ return ((fc->l_varlist.lv_refcount // NOLINT(runtime/deprecated)
+ != DO_NOT_FREE_CNT)
+ || fc->l_vars.dv_refcount != DO_NOT_FREE_CNT
+ || fc->l_avars.dv_refcount != DO_NOT_FREE_CNT
+ || fc->fc_refcount > 0);
+}
+
+/// Call a user function
+///
+/// @param fp Function to call.
+/// @param[in] argcount Number of arguments.
+/// @param argvars Arguments.
+/// @param[out] rettv Return value.
+/// @param[in] firstline First line of range.
+/// @param[in] lastline Last line of range.
+/// @param selfdict Dictionary for "self" for dictionary functions.
+void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
+ typval_T *rettv, linenr_T firstline, linenr_T lastline,
+ dict_T *selfdict)
+ FUNC_ATTR_NONNULL_ARG(1, 3, 4)
{
char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
@@ -20731,11 +21334,13 @@ call_user_func (
dictitem_T *v;
int fixvar_idx = 0; /* index in fixvar[] */
int ai;
+ bool islambda = false;
char_u numbuf[NUMBUFLEN];
char_u *name;
proftime_T wait_start;
proftime_T call_start;
bool did_save_redo = false;
+ save_redo_T save_redo;
/* If depth of calling is getting too high, don't execute the function */
if (depth >= p_mfd) {
@@ -20748,7 +21353,7 @@ call_user_func (
// Save search patterns and redo buffer.
save_search_patterns();
if (!ins_compl_active()) {
- saveRedobuff();
+ saveRedobuff(&save_redo);
did_save_redo = true;
}
++fp->uf_calls;
@@ -20768,25 +21373,32 @@ call_user_func (
fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
fc->dbg_tick = debug_tick;
- /*
- * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
- * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free
- * each argument variable and saves a lot of time.
- */
- /*
- * Init l: variables.
- */
+ // Set up fields for closure.
+ fc->fc_refcount = 0;
+ fc->fc_copyID = 0;
+ ga_init(&fc->fc_funcs, sizeof(ufunc_T *), 1);
+ func_ptr_ref(fp);
+
+ if (STRNCMP(fp->uf_name, "<lambda>", 8) == 0) {
+ islambda = true;
+ }
+
+ // Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
+ // with names up to VAR_SHORT_LEN long. This avoids having to alloc/free
+ // each argument variable and saves a lot of time.
+ //
+ // Init l: variables.
init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE);
if (selfdict != NULL) {
- /* Set l:self to "selfdict". Use "name" to avoid a warning from
- * some compiler that checks the destination size. */
- v = &fc->fixvar[fixvar_idx++].var;
+ // Set l:self to "selfdict". Use "name" to avoid a warning from
+ // some compiler that checks the destination size.
+ v = (dictitem_T *)&fc->fixvar[fixvar_idx++];
#ifndef __clang_analyzer__
name = v->di_key;
STRCPY(name, "self");
#endif
v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX;
- hash_add(&fc->l_vars.dv_hashtab, DI2HIKEY(v));
+ tv_dict_add(&fc->l_vars, v);
v->di_tv.v_type = VAR_DICT;
v->di_tv.v_lock = 0;
v->di_tv.vval.v_dict = selfdict;
@@ -20799,62 +21411,72 @@ call_user_func (
* Set a:000 to a list with room for the "..." arguments.
*/
init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE);
- add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0",
- (varnumber_T)(argcount - fp->uf_args.ga_len));
- /* Use "name" to avoid a warning from some compiler that checks the
- * destination size. */
- v = &fc->fixvar[fixvar_idx++].var;
+ add_nr_var(&fc->l_avars, (dictitem_T *)&fc->fixvar[fixvar_idx++], "0",
+ (varnumber_T)(argcount - fp->uf_args.ga_len));
+ // Use "name" to avoid a warning from some compiler that checks the
+ // destination size.
+ v = (dictitem_T *)&fc->fixvar[fixvar_idx++];
#ifndef __clang_analyzer__
name = v->di_key;
STRCPY(name, "000");
#endif
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
- hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
+ tv_dict_add(&fc->l_avars, v);
v->di_tv.v_type = VAR_LIST;
v->di_tv.v_lock = VAR_FIXED;
v->di_tv.vval.v_list = &fc->l_varlist;
- memset(&fc->l_varlist, 0, sizeof(list_T));
- fc->l_varlist.lv_refcount = DO_NOT_FREE_CNT;
- fc->l_varlist.lv_lock = VAR_FIXED;
+ tv_list_init_static(&fc->l_varlist);
+ tv_list_set_lock(&fc->l_varlist, VAR_FIXED);
+
+ // Set a:firstline to "firstline" and a:lastline to "lastline".
+ // Set a:name to named arguments.
+ // Set a:N to the "..." arguments.
+ add_nr_var(&fc->l_avars, (dictitem_T *)&fc->fixvar[fixvar_idx++],
+ "firstline", (varnumber_T)firstline);
+ add_nr_var(&fc->l_avars, (dictitem_T *)&fc->fixvar[fixvar_idx++],
+ "lastline", (varnumber_T)lastline);
+ for (int i = 0; i < argcount; i++) {
+ bool addlocal = false;
- /*
- * Set a:firstline to "firstline" and a:lastline to "lastline".
- * Set a:name to named arguments.
- * Set a:N to the "..." arguments.
- */
- add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "firstline",
- (varnumber_T)firstline);
- add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "lastline",
- (varnumber_T)lastline);
- for (int i = 0; i < argcount; ++i) {
ai = i - fp->uf_args.ga_len;
- if (ai < 0)
- /* named argument a:name */
+ if (ai < 0) {
+ // named argument a:name
name = FUNCARG(fp, i);
- else {
- /* "..." argument a:1, a:2, etc. */
- sprintf((char *)numbuf, "%d", ai + 1);
+ if (islambda) {
+ addlocal = true;
+ }
+ } else {
+ // "..." argument a:1, a:2, etc.
+ snprintf((char *)numbuf, sizeof(numbuf), "%d", ai + 1);
name = numbuf;
}
if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) {
- v = &fc->fixvar[fixvar_idx++].var;
+ v = (dictitem_T *)&fc->fixvar[fixvar_idx++];
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
} else {
v = xmalloc(sizeof(dictitem_T) + STRLEN(name));
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC;
}
STRCPY(v->di_key, name);
- hash_add(&fc->l_avars.dv_hashtab, DI2HIKEY(v));
- /* Note: the values are copied directly to avoid alloc/free.
- * "argvars" must have VAR_FIXED for v_lock. */
+ // Note: the values are copied directly to avoid alloc/free.
+ // "argvars" must have VAR_FIXED for v_lock.
v->di_tv = argvars[i];
v->di_tv.v_lock = VAR_FIXED;
+ if (addlocal) {
+ // Named arguments can be accessed without the "a:" prefix in lambda
+ // expressions. Add to the l: dict.
+ tv_copy(&v->di_tv, &v->di_tv);
+ tv_dict_add(&fc->l_vars, v);
+ } else {
+ tv_dict_add(&fc->l_avars, v);
+ }
+
if (ai >= 0 && ai < MAX_FUNC_ARGS) {
- list_append(&fc->l_varlist, &fc->l_listitems[ai]);
- fc->l_listitems[ai].li_tv = argvars[i];
- fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED;
+ tv_list_append(&fc->l_varlist, &fc->l_listitems[ai]);
+ *TV_LIST_ITEM_TV(&fc->l_listitems[ai]) = argvars[i];
+ TV_LIST_ITEM_TV(&fc->l_listitems[ai])->v_lock = VAR_FIXED;
}
}
@@ -20890,24 +21512,24 @@ call_user_func (
smsg(_("calling %s"), sourcing_name);
if (p_verbose >= 14) {
- char_u buf[MSG_BUF_LEN];
-
- msg_puts((char_u *)"(");
- for (int i = 0; i < argcount; ++i) {
+ msg_puts("(");
+ for (int i = 0; i < argcount; i++) {
if (i > 0) {
- msg_puts((char_u *)", ");
+ msg_puts(", ");
}
if (argvars[i].v_type == VAR_NUMBER) {
msg_outnum((long)argvars[i].vval.v_number);
} else {
// Do not want errors such as E724 here.
emsg_off++;
- char_u *s = (char_u *) encode_tv2string(&argvars[i], NULL);
- char_u *tofree = s;
+ char *tofree = encode_tv2string(&argvars[i], NULL);
emsg_off--;
- if (s != NULL) {
- if (vim_strsize(s) > MSG_BUF_CLEN) {
- trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
+ if (tofree != NULL) {
+ char *s = tofree;
+ char buf[MSG_BUF_LEN];
+ if (vim_strsize((char_u *)s) > MSG_BUF_CLEN) {
+ trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN,
+ sizeof(buf));
s = buf;
}
msg_puts(s);
@@ -20915,24 +21537,26 @@ call_user_func (
}
}
}
- msg_puts((char_u *)")");
+ msg_puts(")");
}
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
--no_wait_return;
}
}
+ const bool do_profiling_yes = do_profiling == PROF_YES;
+
bool func_not_yet_profiling_but_should =
- do_profiling == PROF_YES
- && !fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL);
+ do_profiling_yes
+ && !fp->uf_profiling && has_profiling(false, fp->uf_name, NULL);
if (func_not_yet_profiling_but_should)
func_do_profile(fp);
bool func_or_func_caller_profiling =
- do_profiling == PROF_YES
+ do_profiling_yes
&& (fp->uf_profiling
|| (fc->caller != NULL && fc->caller->func->uf_profiling));
@@ -20942,7 +21566,7 @@ call_user_func (
fp->uf_tm_children = profile_zero();
}
- if (do_profiling == PROF_YES) {
+ if (do_profiling_yes) {
script_prof_save(&wait_start);
}
@@ -20960,14 +21584,14 @@ call_user_func (
// when the function was aborted because of an error, return -1
if ((did_emsg
&& (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) {
- clear_tv(rettv);
+ tv_clear(rettv);
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = -1;
}
if (func_or_func_caller_profiling) {
call_start = profile_end(call_start);
- call_start = profile_sub_wait(wait_start, call_start);
+ call_start = profile_sub_wait(wait_start, call_start); // -V614
fp->uf_tm_total = profile_add(fp->uf_tm_total, call_start);
fp->uf_tm_self = profile_self(fp->uf_tm_self, call_start,
fp->uf_tm_children);
@@ -21008,7 +21632,7 @@ call_user_func (
xfree(tofree);
}
}
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
--no_wait_return;
@@ -21018,104 +21642,146 @@ call_user_func (
sourcing_name = save_sourcing_name;
sourcing_lnum = save_sourcing_lnum;
current_SID = save_current_SID;
- if (do_profiling == PROF_YES)
+ if (do_profiling_yes) {
script_prof_restore(&wait_start);
+ }
if (p_verbose >= 12 && sourcing_name != NULL) {
++no_wait_return;
verbose_enter_scroll();
smsg(_("continuing in %s"), sourcing_name);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
--no_wait_return;
}
did_emsg |= save_did_emsg;
- current_funccal = fc->caller;
- --depth;
-
- /* If the a:000 list and the l: and a: dicts are not referenced we can
- * free the funccall_T and what's in it. */
- if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
- && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
- && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT) {
- free_funccal(fc, FALSE);
- } else {
- hashitem_T *hi;
- listitem_T *li;
- int todo;
+ depth--;
- /* "fc" is still in use. This can happen when returning "a:000" or
- * assigning "l:" to a global variable.
- * Link "fc" in the list for garbage collection later. */
- fc->caller = previous_funccal;
- previous_funccal = fc;
+ cleanup_function_call(fc);
- /* Make a copy of the a: variables, since we didn't do that above. */
- todo = (int)fc->l_avars.dv_hashtab.ht_used;
- for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- v = HI2DI(hi);
- copy_tv(&v->di_tv, &v->di_tv);
- }
- }
-
- /* Make a copy of the a:000 items, since we didn't do that above. */
- for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
- copy_tv(&li->li_tv, &li->li_tv);
- }
-
- if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) && fp->uf_refcount <= 0) {
+ if (--fp->uf_calls <= 0 && fp->uf_refcount <= 0) {
// Function was unreferenced while being used, free it now.
- func_free(fp);
+ func_clear_free(fp, false);
}
// restore search patterns and redo buffer
if (did_save_redo) {
- restoreRedobuff();
+ restoreRedobuff(&save_redo);
}
restore_search_patterns();
}
-/*
- * Return TRUE if items in "fc" do not have "copyID". That means they are not
- * referenced from anywhere that is in use.
- */
+/// Unreference "fc": decrement the reference count and free it when it
+/// becomes zero. "fp" is detached from "fc".
+///
+/// @param[in] force When true, we are exiting.
+static void funccal_unref(funccall_T *fc, ufunc_T *fp, bool force)
+{
+ funccall_T **pfc;
+ int i;
+
+ if (fc == NULL) {
+ return;
+ }
+
+ fc->fc_refcount--;
+ if (force ? fc->fc_refcount <= 0 : !fc_referenced(fc)) {
+ for (pfc = &previous_funccal; *pfc != NULL; pfc = &(*pfc)->caller) {
+ if (fc == *pfc) {
+ *pfc = fc->caller;
+ free_funccal(fc, true);
+ return;
+ }
+ }
+ }
+ for (i = 0; i < fc->fc_funcs.ga_len; i++) {
+ if (((ufunc_T **)(fc->fc_funcs.ga_data))[i] == fp) {
+ ((ufunc_T **)(fc->fc_funcs.ga_data))[i] = NULL;
+ }
+ }
+}
+
+/// @return true if items in "fc" do not have "copyID". That means they are not
+/// referenced from anywhere that is in use.
static int can_free_funccal(funccall_T *fc, int copyID)
{
return fc->l_varlist.lv_copyID != copyID
&& fc->l_vars.dv_copyID != copyID
- && fc->l_avars.dv_copyID != copyID;
+ && fc->l_avars.dv_copyID != copyID
+ && fc->fc_copyID != copyID;
}
/*
* Free "fc" and what it contains.
*/
-static void
-free_funccal (
+static void
+free_funccal(
funccall_T *fc,
int free_val /* a: vars were allocated */
)
{
- listitem_T *li;
+ for (int i = 0; i < fc->fc_funcs.ga_len; i++) {
+ ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[i];
+
+ // When garbage collecting a funccall_T may be freed before the
+ // function that references it, clear its uf_scoped field.
+ // The function may have been redefined and point to another
+ // funccal_T, don't clear it then.
+ if (fp != NULL && fp->uf_scoped == fc) {
+ fp->uf_scoped = NULL;
+ }
+ }
+ ga_clear(&fc->fc_funcs);
- /* The a: variables typevals may not have been allocated, only free the
- * allocated variables. */
+ // The a: variables typevals may not have been allocated, only free the
+ // allocated variables.
vars_clear_ext(&fc->l_avars.dv_hashtab, free_val);
- /* free all l: variables */
+ // Free all l: variables.
vars_clear(&fc->l_vars.dv_hashtab);
- /* Free the a:000 variables if they were allocated. */
- if (free_val)
- for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
- clear_tv(&li->li_tv);
+ // Free the a:000 variables if they were allocated.
+ if (free_val) {
+ TV_LIST_ITER(&fc->l_varlist, li, {
+ tv_clear(TV_LIST_ITEM_TV(li));
+ });
+ }
+ func_ptr_unref(fc->func);
xfree(fc);
}
+/// Handle the last part of returning from a function: free the local hashtable.
+/// Unless it is still in use by a closure.
+static void cleanup_function_call(funccall_T *fc)
+{
+ current_funccal = fc->caller;
+
+ // If the a:000 list and the l: and a: dicts are not referenced and there
+ // is no closure using it, we can free the funccall_T and what's in it.
+ if (!fc_referenced(fc)) {
+ free_funccal(fc, false);
+ } else {
+ // "fc" is still in use. This can happen when returning "a:000",
+ // assigning "l:" to a global variable or defining a closure.
+ // Link "fc" in the list for garbage collection later.
+ fc->caller = previous_funccal;
+ previous_funccal = fc;
+
+ // Make a copy of the a: variables, since we didn't do that above.
+ TV_DICT_ITER(&fc->l_avars, di, {
+ tv_copy(&di->di_tv, &di->di_tv);
+ });
+
+ // Make a copy of the a:000 items, since we didn't do that above.
+ TV_LIST_ITER(&fc->l_varlist, li, {
+ tv_copy(TV_LIST_ITEM_TV(li), TV_LIST_ITEM_TV(li));
+ });
+ }
+}
+
/*
* Add a number variable "name" to dict "dp" with value "nr".
*/
@@ -21125,7 +21791,7 @@ static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)
STRCPY(v->di_key, name);
#endif
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
- hash_add(&dp->dv_hashtab, DI2HIKEY(v));
+ tv_dict_add(dp, v);
v->di_tv.v_type = VAR_NUMBER;
v->di_tv.v_lock = VAR_FIXED;
v->di_tv.vval.v_number = nr;
@@ -21151,19 +21817,20 @@ void ex_return(exarg_T *eap)
eap->nextcmd = NULL;
if ((*arg != NUL && *arg != '|' && *arg != '\n')
&& eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) {
- if (!eap->skip)
- returning = do_return(eap, FALSE, TRUE, &rettv);
- else
- clear_tv(&rettv);
- }
- /* It's safer to return also on error. */
- else if (!eap->skip) {
- /*
- * Return unless the expression evaluation has been cancelled due to an
- * aborting error, an interrupt, or an exception.
- */
- if (!aborting())
- returning = do_return(eap, FALSE, TRUE, NULL);
+ if (!eap->skip) {
+ returning = do_return(eap, false, true, &rettv);
+ } else {
+ tv_clear(&rettv);
+ }
+ } else if (!eap->skip) { // It's safer to return also on error.
+ // In return statement, cause_abort should be force_abort.
+ update_force_abort();
+
+ // Return unless the expression evaluation has been cancelled due to an
+ // aborting error, an interrupt, or an exception.
+ if (!aborting()) {
+ returning = do_return(eap, false, true, NULL);
+ }
}
/* When skipping or the return gets pending, advance to the next command
@@ -21241,7 +21908,7 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
* a return immediately after reanimation, the value is already
* there. */
if (!reanimate && rettv != NULL) {
- clear_tv(current_funccal->rettv);
+ tv_clear(current_funccal->rettv);
*current_funccal->rettv = *(typval_T *)rettv;
if (!is_cmd)
xfree(rettv);
@@ -21252,14 +21919,6 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
}
/*
- * Free the variable with a pending return value.
- */
-void discard_pending_return(void *rettv)
-{
- free_tv((typval_T *)rettv);
-}
-
-/*
* Generate a return command for producing the value of "rettv". The result
* is an allocated string. Used by report_pending() for verbose messages.
*/
@@ -21276,7 +21935,7 @@ char_u *get_return_cmd(void *rettv)
}
STRCPY(IObuff, ":return ");
- STRNCPY(IObuff + 8, s, IOSIZE - 8);
+ STRLCPY(IObuff + 8, s, IOSIZE - 8);
if (STRLEN(s) + 8 >= IOSIZE)
STRCPY(IObuff + IOSIZE - 4, "...");
xfree(tofree);
@@ -21431,6 +22090,72 @@ static var_flavour_T var_flavour(char_u *varname)
}
}
+/// Search hashitem in parent scope.
+hashitem_T *find_hi_in_scoped_ht(const char *name, hashtab_T **pht)
+{
+ if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) {
+ return NULL;
+ }
+
+ funccall_T *old_current_funccal = current_funccal;
+ hashitem_T *hi = NULL;
+ const size_t namelen = strlen(name);
+ const char *varname;
+
+ // Search in parent scope which is possible to reference from lambda
+ current_funccal = current_funccal->func->uf_scoped;
+ while (current_funccal != NULL) {
+ hashtab_T *ht = find_var_ht(name, namelen, &varname);
+ if (ht != NULL && *varname != NUL) {
+ hi = hash_find_len(ht, varname, namelen - (varname - name));
+ if (!HASHITEM_EMPTY(hi)) {
+ *pht = ht;
+ break;
+ }
+ }
+ if (current_funccal == current_funccal->func->uf_scoped) {
+ break;
+ }
+ current_funccal = current_funccal->func->uf_scoped;
+ }
+ current_funccal = old_current_funccal;
+
+ return hi;
+}
+
+/// Search variable in parent scope.
+dictitem_T *find_var_in_scoped_ht(const char *name, const size_t namelen,
+ int no_autoload)
+{
+ if (current_funccal == NULL || current_funccal->func->uf_scoped == NULL) {
+ return NULL;
+ }
+
+ dictitem_T *v = NULL;
+ funccall_T *old_current_funccal = current_funccal;
+ const char *varname;
+
+ // Search in parent scope which is possible to reference from lambda
+ current_funccal = current_funccal->func->uf_scoped;
+ while (current_funccal) {
+ hashtab_T *ht = find_var_ht(name, namelen, &varname);
+ if (ht != NULL && *varname != NUL) {
+ v = find_var_in_ht(ht, *name, varname,
+ namelen - (size_t)(varname - name), no_autoload);
+ if (v != NULL) {
+ break;
+ }
+ }
+ if (current_funccal == current_funccal->func->uf_scoped) {
+ break;
+ }
+ current_funccal = current_funccal->func->uf_scoped;
+ }
+ current_funccal = old_current_funccal;
+
+ return v;
+}
+
/// Iterate over global variables
///
/// @warning No modifications to global variable dictionary must be performed
@@ -21454,7 +22179,7 @@ const void *var_shada_iter(const void *const iter, const char **const name,
hi = globvarht.ht_array;
while ((size_t) (hi - hifirst) < hinum
&& (HASHITEM_EMPTY(hi)
- || var_flavour(HI2DI(hi)->di_key) != VAR_FLAVOUR_SHADA)) {
+ || var_flavour(hi->hi_key) != VAR_FLAVOUR_SHADA)) {
hi++;
}
if ((size_t) (hi - hifirst) == hinum) {
@@ -21463,11 +22188,10 @@ const void *var_shada_iter(const void *const iter, const char **const name,
} else {
hi = (const hashitem_T *) iter;
}
- *name = (char *) HI2DI(hi)->di_key;
- copy_tv(&(HI2DI(hi)->di_tv), rettv);
- while ((size_t) (++hi - hifirst) < hinum) {
- if (!HASHITEM_EMPTY(hi)
- && var_flavour(HI2DI(hi)->di_key) == VAR_FLAVOUR_SHADA) {
+ *name = (char *)TV_DICT_HI2DI(hi)->di_key;
+ tv_copy(&TV_DICT_HI2DI(hi)->di_tv, rettv);
+ while ((size_t)(++hi - hifirst) < hinum) {
+ if (!HASHITEM_EMPTY(hi) && var_flavour(hi->hi_key) == VAR_FLAVOUR_SHADA) {
return hi;
}
}
@@ -21478,62 +22202,55 @@ void var_set_global(const char *const name, typval_T vartv)
{
funccall_T *const saved_current_funccal = current_funccal;
current_funccal = NULL;
- set_var((char_u *) name, &vartv, false);
+ set_var(name, strlen(name), &vartv, false);
current_funccal = saved_current_funccal;
}
int store_session_globals(FILE *fd)
{
- hashitem_T *hi;
- dictitem_T *this_var;
- int todo;
- char_u *p, *t;
-
- todo = (int)globvarht.ht_used;
- for (hi = globvarht.ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- this_var = HI2DI(hi);
- if ((this_var->di_tv.v_type == VAR_NUMBER
- || this_var->di_tv.v_type == VAR_STRING)
- && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
- /* Escape special characters with a backslash. Turn a LF and
- * CR into \n and \r. */
- p = vim_strsave_escaped(get_tv_string(&this_var->di_tv),
- (char_u *)"\\\"\n\r");
- for (t = p; *t != NUL; ++t)
- if (*t == '\n')
- *t = 'n';
- else if (*t == '\r')
- *t = 'r';
- if ((fprintf(fd, "let %s = %c%s%c",
- this_var->di_key,
- (this_var->di_tv.v_type == VAR_STRING) ? '"'
- : ' ',
- p,
- (this_var->di_tv.v_type == VAR_STRING) ? '"'
- : ' ') < 0)
- || put_eol(fd) == FAIL) {
- xfree(p);
- return FAIL;
+ TV_DICT_ITER(&globvardict, this_var, {
+ if ((this_var->di_tv.v_type == VAR_NUMBER
+ || this_var->di_tv.v_type == VAR_STRING)
+ && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
+ // Escape special characters with a backslash. Turn a LF and
+ // CR into \n and \r.
+ char_u *const p = vim_strsave_escaped(
+ (const char_u *)tv_get_string(&this_var->di_tv),
+ (const char_u *)"\\\"\n\r");
+ for (char_u *t = p; *t != NUL; t++) {
+ if (*t == '\n') {
+ *t = 'n';
+ } else if (*t == '\r') {
+ *t = 'r';
}
+ }
+ if ((fprintf(fd, "let %s = %c%s%c",
+ this_var->di_key,
+ ((this_var->di_tv.v_type == VAR_STRING) ? '"'
+ : ' '),
+ p,
+ ((this_var->di_tv.v_type == VAR_STRING) ? '"'
+ : ' ')) < 0)
+ || put_eol(fd) == FAIL) {
xfree(p);
- } else if (this_var->di_tv.v_type == VAR_FLOAT
- && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
- float_T f = this_var->di_tv.vval.v_float;
- int sign = ' ';
-
- if (f < 0) {
- f = -f;
- sign = '-';
- }
- if ((fprintf(fd, "let %s = %c%f",
- this_var->di_key, sign, f) < 0)
- || put_eol(fd) == FAIL)
- return FAIL;
+ return FAIL;
+ }
+ xfree(p);
+ } else if (this_var->di_tv.v_type == VAR_FLOAT
+ && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) {
+ float_T f = this_var->di_tv.vval.v_float;
+ int sign = ' ';
+
+ if (f < 0) {
+ f = -f;
+ sign = '-';
+ }
+ if ((fprintf(fd, "let %s = %c%f", this_var->di_key, sign, f) < 0)
+ || put_eol(fd) == FAIL) {
+ return FAIL;
}
}
- }
+ });
return OK;
}
@@ -21543,58 +22260,28 @@ int store_session_globals(FILE *fd)
*/
void last_set_msg(scid_T scriptID)
{
- if (scriptID != 0) {
- char_u *p = home_replace_save(NULL, get_scriptname(scriptID));
- verbose_enter();
- MSG_PUTS(_("\n\tLast set from "));
- MSG_PUTS(p);
- xfree(p);
- verbose_leave();
- }
+ const LastSet last_set = (LastSet){
+ .script_id = scriptID,
+ .channel_id = 0,
+ };
+ option_last_set_msg(last_set);
}
-/*
- * List v:oldfiles in a nice way.
- */
-void ex_oldfiles(exarg_T *eap)
+/// Displays where an option was last set.
+///
+/// Should only be invoked when 'verbose' is non-zero.
+void option_last_set_msg(LastSet last_set)
{
- list_T *l = get_vim_var_list(VV_OLDFILES);
- listitem_T *li;
- long nr = 0;
-
- if (l == NULL)
- msg((char_u *)_("No old files"));
- else {
- msg_start();
- msg_scroll = TRUE;
- for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) {
- msg_outnum(++nr);
- MSG_PUTS(": ");
- msg_outtrans(get_tv_string(&li->li_tv));
- msg_putchar('\n');
- ui_flush(); /* output one line at a time */
- os_breakcheck();
- }
- /* Assume "got_int" was set to truncate the listing. */
- got_int = FALSE;
-
- // File selection prompt on ":oldfiles!"
- if (eap->forceit) {
- quit_more = false;
- nr = prompt_for_number(false);
- msg_starthere();
- if (nr > 0 && nr <= l->lv_len) {
- char_u *p = list_find_str(l, nr);
- if (p == NULL) {
- return;
- }
- p = expand_env_save(p);
- eap->arg = p;
- eap->cmdidx = CMD_edit;
- do_exedit(eap, NULL);
- xfree(p);
- }
+ if (last_set.script_id != 0) {
+ bool should_free;
+ char_u *p = get_scriptname(last_set, &should_free);
+ verbose_enter();
+ MSG_PUTS(_("\n\tLast set from "));
+ MSG_PUTS(p);
+ if (should_free) {
+ xfree(p);
}
+ verbose_leave();
}
}
@@ -21613,13 +22300,13 @@ void reset_v_option_vars(void)
* Returns VALID_ flags or -1 for failure.
* When there is an error, *fnamep is set to NULL.
*/
-int
-modify_fname (
- char_u *src, /* string with modifiers */
- size_t *usedlen, /* characters after src that are used */
- char_u **fnamep, /* file name so far */
- char_u **bufp, /* buffer for allocated file name or NULL */
- size_t *fnamelen /* length of fnamep */
+int
+modify_fname(
+ char_u *src, // string with modifiers
+ size_t *usedlen, // characters after src that are used
+ char_u **fnamep, // file name so far
+ char_u **bufp, // buffer for allocated file name or NULL
+ size_t *fnamelen // length of fnamep
)
{
int valid = 0;
@@ -21655,15 +22342,16 @@ repeat:
return -1;
}
- /* When "/." or "/.." is used: force expansion to get rid of it. */
- for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) {
+ // When "/." or "/.." is used: force expansion to get rid of it.
+ for (p = *fnamep; *p != NUL; MB_PTR_ADV(p)) {
if (vim_ispathsep(*p)
&& p[1] == '.'
&& (p[2] == NUL
|| vim_ispathsep(p[2])
|| (p[2] == '.'
- && (p[3] == NUL || vim_ispathsep(p[3])))))
+ && (p[3] == NUL || vim_ispathsep(p[3]))))) {
break;
+ }
}
/* FullName_save() is slow, don't use it when not needed. */
@@ -21743,8 +22431,9 @@ repeat:
valid |= VALID_HEAD;
*usedlen += 2;
s = get_past_head(*fnamep);
- while (tail > s && after_pathsep((char *)s, (char *)tail))
- mb_ptr_back(*fnamep, tail);
+ while (tail > s && after_pathsep((char *)s, (char *)tail)) {
+ MB_PTR_BACK(*fnamep, tail);
+ }
*fnamelen = (size_t)(tail - *fnamep);
if (*fnamelen == 0) {
/* Result is empty. Turn it into "." to make ":cd %:h" work. */
@@ -21752,8 +22441,9 @@ repeat:
*bufp = *fnamep = tail = vim_strsave((char_u *)".");
*fnamelen = 1;
} else {
- while (tail > s && !after_pathsep((char *)s, (char *)tail))
- mb_ptr_back(*fnamep, tail);
+ while (tail > s && !after_pathsep((char *)s, (char *)tail)) {
+ MB_PTR_BACK(*fnamep, tail);
+ }
}
}
@@ -21830,7 +22520,7 @@ repeat:
sub = vim_strnsave(s, (int)(p - s));
str = vim_strnsave(*fnamep, *fnamelen);
*usedlen = (size_t)(p + 1 - src);
- s = do_string_sub(str, pat, sub, flags);
+ s = do_string_sub(str, pat, sub, NULL, flags);
*fnamep = s;
*fnamelen = STRLEN(s);
xfree(*bufp);
@@ -21866,12 +22556,12 @@ repeat:
return valid;
}
-/*
- * Perform a substitution on "str" with pattern "pat" and substitute "sub".
- * "flags" can be "g" to do a global substitute.
- * Returns an allocated string, NULL for error.
- */
-char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags)
+/// Perform a substitution on "str" with pattern "pat" and substitute "sub".
+/// When "sub" is NULL "expr" is used, must be a VAR_FUNC or VAR_PARTIAL.
+/// "flags" can be "g" to do a global substitute.
+/// Returns an allocated string, NULL for error.
+char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub,
+ typval_T *expr, char_u *flags)
{
int sublen;
regmatch_T regmatch;
@@ -21909,23 +22599,21 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags)
zero_width = regmatch.startp[0];
}
- /*
- * Get some space for a temporary buffer to do the substitution
- * into. It will contain:
- * - The text up to where the match is.
- * - The substituted text.
- * - The text after the match.
- */
- sublen = vim_regsub(&regmatch, sub, tail, FALSE, TRUE, FALSE);
+ // Get some space for a temporary buffer to do the substitution
+ // into. It will contain:
+ // - The text up to where the match is.
+ // - The substituted text.
+ // - The text after the match.
+ sublen = vim_regsub(&regmatch, sub, expr, tail, false, true, false);
ga_grow(&ga, (int)((end - tail) + sublen -
(regmatch.endp[0] - regmatch.startp[0])));
/* copy the text up to where the match is */
int i = (int)(regmatch.startp[0] - tail);
memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i);
- /* add the substituted text */
- (void)vim_regsub(&regmatch, sub, (char_u *)ga.ga_data
- + ga.ga_len + i, TRUE, TRUE, FALSE);
+ // add the substituted text
+ (void)vim_regsub(&regmatch, sub, expr, (char_u *)ga.ga_data
+ + ga.ga_len + i, true, true, false);
ga.ga_len += i + sublen - 1;
tail = regmatch.endp[0];
if (*tail == NUL)
@@ -21942,329 +22630,64 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags)
char_u *ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
ga_clear(&ga);
- if (p_cpo == empty_option)
+ if (p_cpo == empty_option) {
p_cpo = save_cpo;
- else
- /* Darn, evaluating {sub} expression changed the value. */
+ } else {
+ // Darn, evaluating {sub} expression or {expr} changed the value.
free_string_option(save_cpo);
+ }
return ret;
}
-static inline TerminalJobData *common_job_init(char **argv,
- ufunc_T *on_stdout,
- ufunc_T *on_stderr,
- ufunc_T *on_exit,
- dict_T *self,
- bool pty,
- bool detach,
- char *cwd)
-{
- TerminalJobData *data = xcalloc(1, sizeof(TerminalJobData));
- data->stopped = false;
- data->on_stdout = on_stdout;
- data->on_stderr = on_stderr;
- data->on_exit = on_exit;
- data->self = self;
- data->events = queue_new_child(main_loop.events);
- if (pty) {
- data->proc.pty = pty_process_init(&main_loop, data);
- } else {
- data->proc.uv = libuv_process_init(&main_loop, data);
- }
- Process *proc = (Process *)&data->proc;
- proc->argv = argv;
- proc->in = &data->in;
- proc->out = &data->out;
- if (!pty) {
- proc->err = &data->err;
- }
- proc->cb = on_process_exit;
- proc->events = data->events;
- proc->detach = detach;
- proc->cwd = cwd;
- return data;
-}
-
-/// Return true/false on success/failure.
-static inline bool common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout,
- ufunc_T **on_stderr, ufunc_T **on_exit)
-{
- if (get_dict_callback(vopts, "on_stdout", on_stdout)
- && get_dict_callback(vopts, "on_stderr", on_stderr)
- && get_dict_callback(vopts, "on_exit", on_exit)) {
+/// common code for getting job callbacks for jobstart, termopen and rpcstart
+///
+/// @return true/false on success/failure.
+static inline bool common_job_callbacks(dict_T *vopts,
+ CallbackReader *on_stdout,
+ CallbackReader *on_stderr,
+ Callback *on_exit)
+{
+ if (tv_dict_get_callback(vopts, S_LEN("on_stdout"), &on_stdout->cb)
+ &&tv_dict_get_callback(vopts, S_LEN("on_stderr"), &on_stderr->cb)
+ && tv_dict_get_callback(vopts, S_LEN("on_exit"), on_exit)) {
+ on_stdout->buffered = tv_dict_get_number(vopts, "stdout_buffered");
+ on_stderr->buffered = tv_dict_get_number(vopts, "stderr_buffered");
+ if (on_stdout->buffered && on_stdout->cb.type == kCallbackNone) {
+ on_stdout->self = vopts;
+ }
+ if (on_stderr->buffered && on_stderr->cb.type == kCallbackNone) {
+ on_stderr->self = vopts;
+ }
vopts->dv_refcount++;
return true;
}
- if (*on_stdout) {
- user_func_unref(*on_stdout);
- }
- if (*on_stderr) {
- user_func_unref(*on_stderr);
- }
- if (*on_exit) {
- user_func_unref(*on_exit);
- }
- return false;
-}
-
-static inline bool common_job_start(TerminalJobData *data, typval_T *rettv)
-{
- Process *proc = (Process *)&data->proc;
- if (proc->type == kProcessTypePty && proc->detach) {
- EMSG2(_(e_invarg2), "terminal/pty job cannot be detached");
- return false;
- }
- data->refcount++;
- char *cmd = xstrdup(proc->argv[0]);
- if (!process_spawn(proc)) {
- EMSG2(_(e_jobspawn), cmd);
- xfree(cmd);
- if (proc->type == kProcessTypePty) {
- xfree(data->proc.pty.term_name);
- }
- rettv->vval.v_number = proc->status;
- term_job_data_decref(data);
- return false;
- }
- xfree(cmd);
-
- data->id = current_job_id++;
- wstream_init(proc->in, 0);
- if (proc->out) {
- rstream_init(proc->out, 0);
- rstream_start(proc->out, on_job_stdout);
- }
- if (proc->err) {
- rstream_init(proc->err, 0);
- rstream_start(proc->err, on_job_stderr);
- }
- pmap_put(uint64_t)(jobs, data->id, data);
- rettv->vval.v_number = data->id;
- return true;
-}
-
-static inline void free_term_job_data_event(void **argv)
-{
- TerminalJobData *data = argv[0];
- if (data->on_stdout) {
- user_func_unref(data->on_stdout);
- }
- if (data->on_stderr) {
- user_func_unref(data->on_stderr);
- }
- if (data->on_exit) {
- user_func_unref(data->on_exit);
- }
-
- if (data->self) {
- dict_unref(data->self);
- }
- queue_free(data->events);
- xfree(data);
+ callback_reader_free(on_stdout);
+ callback_reader_free(on_stderr);
+ callback_free(on_exit);
+ return false;
}
-static inline void free_term_job_data(TerminalJobData *data)
-{
- // data->queue may still be used after this function returns(process_wait), so
- // only free in the next event loop iteration
- queue_put(main_loop.fast_events, free_term_job_data_event, 1, data);
-}
-// vimscript job callbacks must be executed on Nvim main loop
-static inline void process_job_event(TerminalJobData *data, ufunc_T *callback,
- const char *type, char *buf, size_t count, int status)
+static Channel *find_job(uint64_t id, bool show_error)
{
- JobEvent event_data;
- event_data.received = NULL;
- if (buf) {
- event_data.received = list_alloc();
- char *ptr = buf;
- size_t remaining = count;
- size_t off = 0;
-
- while (off < remaining) {
- // append the line
- if (ptr[off] == NL) {
- list_append_string(event_data.received, (uint8_t *)ptr, off);
- size_t skip = off + 1;
- ptr += skip;
- remaining -= skip;
- off = 0;
- continue;
- }
- if (ptr[off] == NUL) {
- // Translate NUL to NL
- ptr[off] = NL;
+ Channel *data = find_channel(id);
+ if (!data || data->streamtype != kChannelStreamProc
+ || process_is_stopped(&data->stream.proc)) {
+ if (show_error) {
+ if (data && data->streamtype != kChannelStreamProc) {
+ EMSG(_(e_invchanjob));
+ } else {
+ EMSG(_(e_invchan));
}
- off++;
- }
- list_append_string(event_data.received, (uint8_t *)ptr, off);
- } else {
- event_data.status = status;
- }
- event_data.data = data;
- event_data.callback = callback;
- event_data.type = type;
- on_job_event(&event_data);
-}
-
-static void on_job_stdout(Stream *stream, RBuffer *buf, size_t count,
- void *job, bool eof)
-{
- TerminalJobData *data = job;
- on_job_output(stream, job, buf, count, eof, data->on_stdout, "stdout");
-}
-
-static void on_job_stderr(Stream *stream, RBuffer *buf, size_t count,
- void *job, bool eof)
-{
- TerminalJobData *data = job;
- on_job_output(stream, job, buf, count, eof, data->on_stderr, "stderr");
-}
-
-static void on_job_output(Stream *stream, TerminalJobData *data, RBuffer *buf,
- size_t count, bool eof, ufunc_T *callback, const char *type)
-{
- if (eof) {
- return;
- }
-
- // stub variable, to keep reading consistent with the order of events, only
- // consider the count parameter.
- size_t r;
- char *ptr = rbuffer_read_ptr(buf, &r);
-
- // The order here matters, the terminal must receive the data first because
- // process_job_event will modify the read buffer(convert NULs into NLs)
- if (data->term) {
- terminal_receive(data->term, ptr, count);
- }
-
- if (callback) {
- process_job_event(data, callback, type, ptr, count, 0);
- }
-
- rbuffer_consumed(buf, count);
-}
-
-static void on_process_exit(Process *proc, int status, void *d)
-{
- TerminalJobData *data = d;
- if (data->term && !data->exited) {
- data->exited = true;
- char msg[sizeof("\r\n[Process exited ]") + NUMBUFLEN];
- snprintf(msg, sizeof msg, "\r\n[Process exited %d]", proc->status);
- terminal_close(data->term, msg);
- }
-
- if (data->status_ptr) {
- *data->status_ptr = status;
- }
-
- process_job_event(data, data->on_exit, "exit", NULL, 0, status);
-}
-
-static void term_write(char *buf, size_t size, void *d)
-{
- TerminalJobData *data = d;
- WBuffer *wbuf = wstream_new_buffer(xmemdup(buf, size), size, 1, xfree);
- wstream_write(&data->in, wbuf);
-}
-
-static void term_resize(uint16_t width, uint16_t height, void *d)
-{
- TerminalJobData *data = d;
- pty_process_resize(&data->proc.pty, width, height);
-}
-
-static inline void term_delayed_free(void **argv)
-{
- TerminalJobData *j = argv[0];
- if (j->in.pending_reqs || j->out.pending_reqs || j->err.pending_reqs) {
- queue_put(j->events, term_delayed_free, 1, j);
- return;
- }
-
- terminal_destroy(j->term);
- term_job_data_decref(j);
-}
-
-static void term_close(void *d)
-{
- TerminalJobData *data = d;
- if (!data->exited) {
- data->exited = true;
- process_stop((Process *)&data->proc);
- }
- queue_put(data->events, term_delayed_free, 1, data);
-}
-
-static void term_job_data_decref(TerminalJobData *data)
-{
- if (!(--data->refcount)) {
- free_term_job_data(data);
- }
-}
-
-static void on_job_event(JobEvent *ev)
-{
- if (!ev->callback) {
- goto end;
- }
-
- typval_T argv[3];
- int argc = ev->callback->uf_args.ga_len;
-
- if (argc > 0) {
- argv[0].v_type = VAR_NUMBER;
- argv[0].v_lock = 0;
- argv[0].vval.v_number = ev->data->id;
- }
-
- if (argc > 1) {
- if (ev->received) {
- argv[1].v_type = VAR_LIST;
- argv[1].v_lock = 0;
- argv[1].vval.v_list = ev->received;
- argv[1].vval.v_list->lv_refcount++;
- } else {
- argv[1].v_type = VAR_NUMBER;
- argv[1].v_lock = 0;
- argv[1].vval.v_number = ev->status;
}
- }
-
- if (argc > 2) {
- argv[2].v_type = VAR_STRING;
- argv[2].v_lock = 0;
- argv[2].vval.v_string = (uint8_t *)ev->type;
- }
-
- typval_T rettv;
- init_tv(&rettv);
- call_user_func(ev->callback, argc, argv, &rettv, curwin->w_cursor.lnum,
- curwin->w_cursor.lnum, ev->data->self);
- clear_tv(&rettv);
-
-end:
- if (!ev->received) {
- // exit event, safe to free job data now
- pmap_del(uint64_t)(jobs, ev->data->id);
- term_job_data_decref(ev->data);
- }
-}
-
-static TerminalJobData *find_job(uint64_t id)
-{
- TerminalJobData *data = pmap_get(uint64_t)(jobs, id);
- if (!data || data->stopped) {
return NULL;
}
return data;
}
+
static void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
{
if (check_restricted() || check_secure()) {
@@ -22276,13 +22699,23 @@ static void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
return;
}
- list_T *args = list_alloc();
- list_append_string(args, argvars[0].vval.v_string, -1);
+ list_T *args = tv_list_alloc(1);
+ tv_list_append_string(args, (const char *)argvars[0].vval.v_string, -1);
*rettv = eval_call_provider(name, "eval", args);
}
typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
{
+ if (!eval_has_provider(provider)) {
+ emsgf("E319: No \"%s\" provider found. Run \":checkhealth provider\"",
+ provider);
+ return (typval_T){
+ .v_type = VAR_NUMBER,
+ .v_lock = VAR_UNLOCKED,
+ .vval.v_number = (varnumber_T)0
+ };
+ }
+
char func[256];
int name_len = snprintf(func, sizeof(func), "provider#%s#Call", provider);
@@ -22294,7 +22727,6 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
.sourcing_lnum = sourcing_lnum,
.autocmd_fname = autocmd_fname,
.autocmd_match = autocmd_match,
- .autocmd_fname_full = autocmd_fname_full,
.autocmd_bufnr = autocmd_bufnr,
.funccalp = save_funccal()
};
@@ -22305,142 +22737,117 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
{.v_type = VAR_LIST, .vval.v_list = arguments, .v_lock = 0},
{.v_type = VAR_UNKNOWN}
};
- typval_T rettv = {.v_type = VAR_UNKNOWN, .v_lock = 0};
- arguments->lv_refcount++;
+ typval_T rettv = { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED };
+ tv_list_ref(arguments);
int dummy;
- (void)call_func((uint8_t *)func,
+ (void)call_func((const char_u *)func,
name_len,
&rettv,
2,
argvars,
+ NULL,
curwin->w_cursor.lnum,
curwin->w_cursor.lnum,
&dummy,
true,
+ NULL,
NULL);
- list_unref(arguments);
+ tv_list_unref(arguments);
// Restore caller scope information
restore_funccal(provider_caller_scope.funccalp);
provider_caller_scope = saved_provider_caller_scope;
provider_call_nesting--;
-
+ assert(provider_call_nesting >= 0);
+
return rettv;
}
-bool eval_has_provider(char *name)
+bool eval_has_provider(const char *name)
{
-#define check_provider(name) \
+#define CHECK_PROVIDER(name) \
if (has_##name == -1) { \
- has_##name = !!find_func((uint8_t *)"provider#" #name "#Call"); \
+ has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \
if (!has_##name) { \
- script_autoload((uint8_t *)"provider#" #name "#Call", false); \
- has_##name = !!find_func((uint8_t *)"provider#" #name "#Call"); \
+ script_autoload("provider#" #name "#Call", \
+ sizeof("provider#" #name "#Call") - 1, \
+ false); \
+ has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \
} \
}
- static int has_clipboard = -1, has_python = -1, has_python3 = -1;
+ static int has_clipboard = -1;
+ static int has_python = -1;
+ static int has_python3 = -1;
+ static int has_ruby = -1;
- if (!strcmp(name, "clipboard")) {
- check_provider(clipboard);
+ if (strequal(name, "clipboard")) {
+ CHECK_PROVIDER(clipboard);
return has_clipboard;
- } else if (!strcmp(name, "python3")) {
- check_provider(python3);
+ } else if (strequal(name, "python3")) {
+ CHECK_PROVIDER(python3);
return has_python3;
- } else if (!strcmp(name, "python")) {
- check_provider(python);
+ } else if (strequal(name, "python")) {
+ CHECK_PROVIDER(python);
return has_python;
+ } else if (strequal(name, "ruby")) {
+ bool need_check_ruby = (has_ruby == -1);
+ CHECK_PROVIDER(ruby);
+ if (need_check_ruby && has_ruby == 1) {
+ char *rubyhost = call_func_retstr("provider#ruby#Detect", 0, NULL, true);
+ if (rubyhost) {
+ if (*rubyhost == NUL) {
+ // Invalid rubyhost executable. Gem is probably not installed.
+ has_ruby = 0;
+ }
+ xfree(rubyhost);
+ }
+ }
+ return has_ruby;
}
return false;
}
-// Compute the `DictWatcher` address from a QUEUE node. This only exists for
-// .asan-blacklist (ASAN doesn't handle QUEUE_DATA pointer arithmetic).
-static DictWatcher *dictwatcher_node_data(QUEUE *q)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
+/// Writes "<sourcing_name>:<sourcing_lnum>" to `buf[bufsize]`.
+void eval_fmt_source_name_line(char *buf, size_t bufsize)
{
- return QUEUE_DATA(q, DictWatcher, node);
+ if (sourcing_name) {
+ snprintf(buf, bufsize, "%s:%" PRIdLINENR, sourcing_name, sourcing_lnum);
+ } else {
+ snprintf(buf, bufsize, "?");
+ }
}
-// Send a change notification to all `dict` watchers that match `key`.
-static void dictwatcher_notify(dict_T *dict, const char *key, typval_T *newtv,
- typval_T *oldtv)
- FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2)
+/// ":checkhealth [plugins]"
+void ex_checkhealth(exarg_T *eap)
{
- typval_T argv[3];
- for (size_t i = 0; i < ARRAY_SIZE(argv); i++) {
- init_tv(argv + i);
- }
-
- argv[0].v_type = VAR_DICT;
- argv[0].vval.v_dict = dict;
- argv[1].v_type = VAR_STRING;
- argv[1].vval.v_string = (char_u *)xstrdup(key);
- argv[2].v_type = VAR_DICT;
- argv[2].vval.v_dict = dict_alloc();
- argv[2].vval.v_dict->dv_refcount++;
-
- if (newtv) {
- dictitem_T *v = dictitem_alloc((char_u *)"new");
- copy_tv(newtv, &v->di_tv);
- dict_add(argv[2].vval.v_dict, v);
+ bool found = !!find_func((char_u *)"health#check");
+ if (!found
+ && script_autoload("health#check", sizeof("health#check") - 1, false)) {
+ found = !!find_func((char_u *)"health#check");
}
-
- if (oldtv) {
- dictitem_T *v = dictitem_alloc((char_u *)"old");
- copy_tv(oldtv, &v->di_tv);
- dict_add(argv[2].vval.v_dict, v);
- }
-
- typval_T rettv;
-
- QUEUE *w;
- QUEUE_FOREACH(w, &dict->watchers) {
- DictWatcher *watcher = dictwatcher_node_data(w);
- if (!watcher->busy && dictwatcher_matches(watcher, key)) {
- init_tv(&rettv);
- watcher->busy = true;
- call_user_func(watcher->callback, ARRAY_SIZE(argv), argv, &rettv,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum, NULL);
- watcher->busy = false;
- clear_tv(&rettv);
+ if (!found) {
+ const char *vimruntime_env = os_getenv("VIMRUNTIME");
+ if (vimruntime_env == NULL) {
+ EMSG(_("E5009: $VIMRUNTIME is empty or unset"));
+ } else {
+ bool rtp_ok = NULL != strstr((char *)p_rtp, vimruntime_env);
+ if (rtp_ok) {
+ EMSG2(_("E5009: Invalid $VIMRUNTIME: %s"), vimruntime_env);
+ } else {
+ EMSG(_("E5009: Invalid 'runtimepath'"));
+ }
}
+ return;
}
- for (size_t i = 1; i < ARRAY_SIZE(argv); i++) {
- clear_tv(argv + i);
- }
-}
-
-// Test if `key` matches with with `watcher->key_pattern`
-static bool dictwatcher_matches(DictWatcher *watcher, const char *key)
- FUNC_ATTR_NONNULL_ALL
-{
- // For now only allow very simple globbing in key patterns: a '*' at the end
- // of the string means it should match everything up to the '*' instead of the
- // whole string.
- char *nul = strchr(watcher->key_pattern, NUL);
- size_t len = nul - watcher->key_pattern;
- if (*(nul - 1) == '*') {
- return !strncmp(key, watcher->key_pattern, len - 1);
- } else {
- return !strcmp(key, watcher->key_pattern);
- }
-}
+ size_t bufsize = STRLEN(eap->arg) + sizeof("call health#check('')");
+ char *buf = xmalloc(bufsize);
+ snprintf(buf, bufsize, "call health#check('%s')", eap->arg);
-// Perform all necessary cleanup for a `DictWatcher` instance.
-static void dictwatcher_free(DictWatcher *watcher)
- FUNC_ATTR_NONNULL_ALL
-{
- user_func_unref(watcher->callback);
- xfree(watcher->key_pattern);
- xfree(watcher);
-}
+ do_cmdline_cmd(buf);
-// Check if `d` has at least one watcher.
-static bool is_watched(dict_T *d)
-{
- return d && !QUEUE_EMPTY(&d->watchers);
+ xfree(buf);
}
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index d6800afd52..149dae688e 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -1,11 +1,16 @@
#ifndef NVIM_EVAL_H
#define NVIM_EVAL_H
-#include "nvim/profile.h"
#include "nvim/hashtab.h" // For hashtab_T
-#include "nvim/garray.h" // For garray_T
-#include "nvim/buffer_defs.h" // For scid_T
+#include "nvim/buffer_defs.h"
#include "nvim/ex_cmds_defs.h" // For exarg_T
+#include "nvim/eval/typval.h"
+#include "nvim/profile.h"
+#include "nvim/garray.h"
+#include "nvim/event/rstream.h"
+#include "nvim/event/wstream.h"
+#include "nvim/channel.h"
+#include "nvim/os/stdpaths_defs.h"
#define COPYID_INC 2
#define COPYID_MASK (~0x1)
@@ -13,42 +18,10 @@
// All user-defined functions are found in this hashtable.
extern hashtab_T func_hashtab;
-// Structure to hold info for a user function.
-typedef struct ufunc ufunc_T;
-
-struct ufunc {
- int uf_varargs; ///< variable nr of arguments
- int uf_flags;
- int uf_calls; ///< nr of active calls
- garray_T uf_args; ///< arguments
- garray_T uf_lines; ///< function lines
- int uf_profiling; ///< true when func is being profiled
- // Profiling the function as a whole.
- int uf_tm_count; ///< nr of calls
- proftime_T uf_tm_total; ///< time spent in function + children
- proftime_T uf_tm_self; ///< time spent in function itself
- proftime_T uf_tm_children; ///< time spent in children this call
- // Profiling the function per line.
- int *uf_tml_count; ///< nr of times line was executed
- proftime_T *uf_tml_total; ///< time spent in a line + children
- proftime_T *uf_tml_self; ///< time spent in a line itself
- proftime_T uf_tml_start; ///< start time for current line
- proftime_T uf_tml_children; ///< time spent in children for this line
- proftime_T uf_tml_wait; ///< start wait time for current line
- int uf_tml_idx; ///< index of line being timed; -1 if none
- int uf_tml_execed; ///< line being timed was executed
- scid_T uf_script_ID; ///< ID of script where function was defined,
- // used for s: variables
- int uf_refcount; ///< for numbered function: reference count
- char_u uf_name[1]; ///< name of function (actually longer); can
- // start with <SNR>123_ (<SNR> is K_SPECIAL
- // KS_EXTRA KE_SNR)
-};
-
// From user function to hashitem and back.
EXTERN ufunc_T dumuf;
#define UF2HIKEY(fp) ((fp)->uf_name)
-#define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
+#define HIKEY2UF(p) ((ufunc_T *)(p - offsetof(ufunc_T, uf_name)))
#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
/// Defines for Vim variables
@@ -84,6 +57,7 @@ typedef enum {
VV_DYING,
VV_EXCEPTION,
VV_THROWPOINT,
+ VV_STDERR,
VV_REG,
VV_CMDBANG,
VV_INSERTMODE,
@@ -94,6 +68,7 @@ typedef enum {
VV_FCS_CHOICE,
VV_BEVAL_BUFNR,
VV_BEVAL_WINNR,
+ VV_BEVAL_WINID,
VV_BEVAL_LNUM,
VV_BEVAL_COL,
VV_BEVAL_TEXT,
@@ -103,6 +78,7 @@ typedef enum {
VV_SWAPCOMMAND,
VV_CHAR,
VV_MOUSE_WIN,
+ VV_MOUSE_WINID,
VV_MOUSE_LNUM,
VV_MOUSE_COL,
VV_OP,
@@ -111,7 +87,6 @@ typedef enum {
VV_OLDFILES,
VV_WINDOWID,
VV_PROGPATH,
- VV_COMMAND_OUTPUT,
VV_COMPLETED_ITEM,
VV_OPTION_NEW,
VV_OPTION_OLD,
@@ -124,6 +99,16 @@ typedef enum {
VV_NULL,
VV__NULL_LIST, // List with NULL value. For test purposes only.
VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
+ VV_VIM_DID_ENTER,
+ VV_TESTING,
+ VV_TYPE_NUMBER,
+ VV_TYPE_STRING,
+ VV_TYPE_FUNC,
+ VV_TYPE_LIST,
+ VV_TYPE_DICT,
+ VV_TYPE_FLOAT,
+ VV_TYPE_BOOL,
+ VV_EXITING,
} VimVarIndex;
/// All recognized msgpack types
@@ -145,8 +130,8 @@ extern const list_T *eval_msgpack_type_lists[LAST_MSGPACK_TYPE + 1];
#undef LAST_MSGPACK_TYPE
-/// Maximum number of function arguments
-#define MAX_FUNC_ARGS 20
+typedef int (*ArgvFunc)(int current_argcount, typval_T *argv,
+ int called_func_argcount);
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval.h.generated.h"
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
new file mode 100644
index 0000000000..78cac4878d
--- /dev/null
+++ b/src/nvim/eval.lua
@@ -0,0 +1,356 @@
+-- File containing table with all functions.
+--
+-- Keys:
+--
+-- args Number of arguments, list with maximum and minimum number of arguments
+-- or list with a minimum number of arguments only. Defaults to zero
+-- arguments.
+-- func Name of the C function which implements the VimL function. Defaults to
+-- `f_{funcname}`.
+
+local varargs = function(nr)
+ return {nr}
+end
+
+return {
+ funcs={
+ abs={args=1},
+ acos={args=1, func="float_op_wrapper", data="&acos"}, -- WJMc
+ add={args=2},
+ ['and']={args=2},
+ api_info={},
+ append={args=2},
+ argc={},
+ argidx={},
+ arglistid={args={0, 2}},
+ argv={args={0, 1}},
+ asin={args=1, func="float_op_wrapper", data="&asin"}, -- WJMc
+ assert_equal={args={2, 3}},
+ assert_exception={args={1, 2}},
+ assert_fails={args={1, 2}},
+ assert_false={args={1, 2}},
+ assert_inrange={args={3, 4}},
+ assert_match={args={2, 3}},
+ assert_notequal={args={2, 3}},
+ assert_notmatch={args={2, 3}},
+ assert_report={args=1},
+ assert_true={args={1, 2}},
+ atan={args=1, func="float_op_wrapper", data="&atan"},
+ atan2={args=2},
+ browse={args=4},
+ browsedir={args=2},
+ bufexists={args=1},
+ buffer_exists={args=1, func='f_bufexists'}, -- obsolete
+ buffer_name={args=1, func='f_bufname'}, -- obsolete
+ buffer_number={args=1, func='f_bufnr'}, -- obsolete
+ buflisted={args=1},
+ bufloaded={args=1},
+ bufname={args=1},
+ bufnr={args={1, 2}},
+ bufwinid={args=1},
+ bufwinnr={args=1},
+ byte2line={args=1},
+ byteidx={args=2},
+ byteidxcomp={args=2},
+ call={args={2, 3}},
+ ceil={args=1, func="float_op_wrapper", data="&ceil"},
+ changenr={},
+ chanclose={args={1, 2}},
+ chansend={args=2},
+ char2nr={args={1, 2}},
+ cindent={args=1},
+ clearmatches={},
+ col={args=1},
+ complete={args=2},
+ complete_add={args=1},
+ complete_check={},
+ confirm={args={1, 4}},
+ copy={args=1},
+ cos={args=1, func="float_op_wrapper", data="&cos"},
+ cosh={args=1, func="float_op_wrapper", data="&cosh"},
+ count={args={2, 4}},
+ cscope_connection={args={0, 3}},
+ cursor={args={1, 3}},
+ deepcopy={args={1, 2}},
+ delete={args={1,2}},
+ dictwatcheradd={args=3},
+ dictwatcherdel={args=3},
+ did_filetype={},
+ diff_filler={args=1},
+ diff_hlID={args=2},
+ empty={args=1},
+ escape={args=2},
+ eval={args=1},
+ eventhandler={},
+ executable={args=1},
+ execute={args={1, 2}},
+ exepath={args=1},
+ exists={args=1},
+ exp={args=1, func="float_op_wrapper", data="&exp"},
+ expand={args={1, 3}},
+ extend={args={2, 3}},
+ feedkeys={args={1, 2}},
+ file_readable={args=1, func='f_filereadable'}, -- obsolete
+ filereadable={args=1},
+ filewritable={args=1},
+ filter={args=2},
+ finddir={args={1, 3}},
+ findfile={args={1, 3}},
+ float2nr={args=1},
+ floor={args=1, func="float_op_wrapper", data="&floor"},
+ fmod={args=2},
+ fnameescape={args=1},
+ fnamemodify={args=2},
+ foldclosed={args=1},
+ foldclosedend={args=1},
+ foldlevel={args=1},
+ foldtext={},
+ foldtextresult={args=1},
+ foreground={},
+ funcref={args={1, 3}},
+ ['function']={args={1, 3}},
+ garbagecollect={args={0, 1}},
+ get={args={2, 3}},
+ getbufinfo={args={0, 1}},
+ getbufline={args={2, 3}},
+ getbufvar={args={2, 3}},
+ getchar={args={0, 1}},
+ getcharmod={},
+ getcharsearch={},
+ getcmdline={},
+ getcmdpos={},
+ getcmdtype={},
+ getcmdwintype={},
+ getcompletion={args={2, 3}},
+ getcurpos={},
+ getcwd={args={0,2}},
+ getfontname={args={0, 1}},
+ getfperm={args=1},
+ getfsize={args=1},
+ getftime={args=1},
+ getftype={args=1},
+ getline={args={1, 2}},
+ getloclist={args={1, 2}},
+ getmatches={},
+ getpid={},
+ getpos={args=1},
+ getqflist={args={0, 1}},
+ getreg={args={0, 3}},
+ getregtype={args={0, 1}},
+ gettabinfo={args={0, 1}},
+ gettabvar={args={2, 3}},
+ gettabwinvar={args={3, 4}},
+ getwininfo={args={0, 1}},
+ getwinposx={},
+ getwinposy={},
+ getwinvar={args={2, 3}},
+ glob={args={1, 4}},
+ glob2regpat={args=1},
+ globpath={args={2, 5}},
+ has={args=1},
+ has_key={args=2},
+ haslocaldir={args={0,2}},
+ hasmapto={args={1, 3}},
+ highlightID={args=1, func='f_hlID'}, -- obsolete
+ highlight_exists={args=1, func='f_hlexists'}, -- obsolete
+ histadd={args=2},
+ histdel={args={1, 2}},
+ histget={args={1, 2}},
+ histnr={args=1},
+ hlID={args=1},
+ hlexists={args=1},
+ hostname={},
+ iconv={args=3},
+ indent={args=1},
+ index={args={2, 4}},
+ input={args={1, 3}},
+ inputdialog={args={1, 3}},
+ inputlist={args=1},
+ inputrestore={},
+ inputsave={},
+ inputsecret={args={1, 2}},
+ insert={args={2, 3}},
+ invert={args=1},
+ isdirectory={args=1},
+ islocked={args=1},
+ id={args=1},
+ items={args=1},
+ jobclose={args={1, 2}, func="f_chanclose"},
+ jobpid={args=1},
+ jobresize={args=3},
+ jobsend={args=2, func="f_chansend"},
+ jobstart={args={1, 2}},
+ jobstop={args=1},
+ jobwait={args={1, 2}},
+ join={args={1, 2}},
+ json_decode={args=1},
+ json_encode={args=1},
+ keys={args=1},
+ last_buffer_nr={}, -- obsolete
+ len={args=1},
+ libcall={args=3},
+ libcallnr={args=3},
+ line={args=1},
+ line2byte={args=1},
+ lispindent={args=1},
+ localtime={},
+ log={args=1, func="float_op_wrapper", data="&log"},
+ log10={args=1, func="float_op_wrapper", data="&log10"},
+ luaeval={args={1, 2}},
+ map={args=2},
+ maparg={args={1, 4}},
+ mapcheck={args={1, 3}},
+ match={args={2, 4}},
+ matchadd={args={2, 5}},
+ matchaddpos={args={2, 5}},
+ matcharg={args=1},
+ matchdelete={args=1},
+ matchend={args={2, 4}},
+ matchlist={args={2, 4}},
+ matchstr={args={2, 4}},
+ matchstrpos={args={2,4}},
+ max={args=1},
+ menu_get={args={1, 2}},
+ min={args=1},
+ mkdir={args={1, 3}},
+ mode={args={0, 1}},
+ msgpackdump={args=1},
+ msgpackparse={args=1},
+ nextnonblank={args=1},
+ nr2char={args={1, 2}},
+ ['or']={args=2},
+ pathshorten={args=1},
+ pow={args=2},
+ prevnonblank={args=1},
+ printf={args=varargs(1)},
+ pumvisible={},
+ py3eval={args=1},
+ pyeval={args=1},
+ pyxeval={args=1},
+ range={args={1, 3}},
+ readfile={args={1, 3}},
+ reltime={args={0, 2}},
+ reltimefloat={args=1},
+ reltimestr={args=1},
+ remove={args={2, 3}},
+ rename={args=2},
+ ['repeat']={args=2},
+ resolve={args=1},
+ reverse={args=1},
+ round={args=1, func="float_op_wrapper", data="&round"},
+ rpcnotify={args=varargs(2)},
+ rpcrequest={args=varargs(2)},
+ rpcstart={args={1, 2}},
+ rpcstop={args=1},
+ screenattr={args=2},
+ screenchar={args=2},
+ screencol={},
+ screenrow={},
+ search={args={1, 4}},
+ searchdecl={args={1, 3}},
+ searchpair={args={3, 7}},
+ searchpairpos={args={3, 7}},
+ searchpos={args={1, 4}},
+ serverlist={},
+ serverstart={args={0, 1}},
+ serverstop={args=1},
+ setbufvar={args=3},
+ setcharsearch={args=1},
+ setcmdpos={args=1},
+ setfperm={args=2},
+ setline={args=2},
+ setloclist={args={2, 4}},
+ setmatches={args=1},
+ setpos={args=2},
+ setqflist={args={1, 3}},
+ setreg={args={2, 3}},
+ settabvar={args=3},
+ settabwinvar={args=4},
+ setwinvar={args=3},
+ sha256={args=1},
+ shellescape={args={1, 2}},
+ shiftwidth={},
+ simplify={args=1},
+ sin={args=1, func="float_op_wrapper", data="&sin"},
+ sinh={args=1, func="float_op_wrapper", data="&sinh"},
+ sockconnect={args={2,3}},
+ sort={args={1, 3}},
+ soundfold={args=1},
+ stdioopen={args=1},
+ spellbadword={args={0, 1}},
+ spellsuggest={args={1, 3}},
+ split={args={1, 3}},
+ sqrt={args=1, func="float_op_wrapper", data="&sqrt"},
+ stdpath={args=1},
+ str2float={args=1},
+ str2nr={args={1, 2}},
+ strcharpart={args={2, 3}},
+ strchars={args={1,2}},
+ strdisplaywidth={args={1, 2}},
+ strftime={args={1, 2}},
+ strgetchar={args={2, 2}},
+ stridx={args={2, 3}},
+ string={args=1},
+ strlen={args=1},
+ strpart={args={2, 3}},
+ strridx={args={2, 3}},
+ strtrans={args=1},
+ strwidth={args=1},
+ submatch={args={1, 2}},
+ substitute={args=4},
+ synID={args=3},
+ synIDattr={args={2, 3}},
+ synIDtrans={args=1},
+ synconcealed={args=2},
+ synstack={args=2},
+ system={args={1, 2}},
+ systemlist={args={1, 3}},
+ tabpagebuflist={args={0, 1}},
+ tabpagenr={args={0, 1}},
+ tabpagewinnr={args={1, 2}},
+ tagfiles={},
+ taglist={args={1, 2}},
+ tan={args=1, func="float_op_wrapper", data="&tan"},
+ tanh={args=1, func="float_op_wrapper", data="&tanh"},
+ tempname={},
+ termopen={args={1, 2}},
+ test_garbagecollect_now={},
+ test_write_list_log={args=1},
+ timer_info={args={0,1}},
+ timer_pause={args=2},
+ timer_start={args={2,3}},
+ timer_stop={args=1},
+ timer_stopall={args=0},
+ tolower={args=1},
+ toupper={args=1},
+ tr={args=3},
+ trim={args={1,2}},
+ trunc={args=1, func="float_op_wrapper", data="&trunc"},
+ type={args=1},
+ undofile={args=1},
+ undotree={},
+ uniq={args={1, 3}},
+ values={args=1},
+ virtcol={args=1},
+ visualmode={args={0, 1}},
+ wildmenumode={},
+ win_findbuf={args=1},
+ win_getid={args={0,2}},
+ win_gotoid={args=1},
+ win_id2tabwin={args=1},
+ win_id2win={args=1},
+ win_screenpos={args=1},
+ winbufnr={args=1},
+ wincol={},
+ winheight={args=1},
+ winline={},
+ winnr={args={0, 1}},
+ winrestcmd={},
+ winrestview={args=1},
+ winsaveview={},
+ winwidth={args=1},
+ wordcount={},
+ writefile={args={2, 3}},
+ xor={args=2},
+ },
+}
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 43e9f76c0f..4d75c7bda1 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -1,12 +1,17 @@
+// 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 <stddef.h>
#include <msgpack.h>
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/eval.h"
#include "nvim/eval/encode.h"
#include "nvim/ascii.h"
+#include "nvim/macros.h"
#include "nvim/message.h"
+#include "nvim/globals.h"
#include "nvim/charset.h" // vim_str2nr
#include "nvim/lib/kvec.h"
#include "nvim/vim.h" // OK, FAIL
@@ -51,16 +56,16 @@ static inline void create_special_dict(typval_T *const rettv,
typval_T val)
FUNC_ATTR_NONNULL_ALL
{
- dict_T *const dict = dict_alloc();
- dictitem_T *const type_di = dictitem_alloc((char_u *) "_TYPE");
+ dict_T *const dict = tv_dict_alloc();
+ dictitem_T *const type_di = tv_dict_item_alloc_len(S_LEN("_TYPE"));
type_di->di_tv.v_type = VAR_LIST;
type_di->di_tv.v_lock = VAR_UNLOCKED;
- type_di->di_tv.vval.v_list = (list_T *) eval_msgpack_type_lists[type];
- type_di->di_tv.vval.v_list->lv_refcount++;
- dict_add(dict, type_di);
- dictitem_T *const val_di = dictitem_alloc((char_u *) "_VAL");
+ type_di->di_tv.vval.v_list = (list_T *)eval_msgpack_type_lists[type];
+ tv_list_ref(type_di->di_tv.vval.v_list);
+ tv_dict_add(dict, type_di);
+ dictitem_T *const val_di = tv_dict_item_alloc_len(S_LEN("_VAL"));
val_di->di_tv = val;
- dict_add(dict, val_di);
+ tv_dict_add(dict, val_di);
dict->dv_refcount++;
*rettv = (typval_T) {
.v_type = VAR_DICT,
@@ -115,21 +120,19 @@ static inline int json_decoder_pop(ValuesStackItem obj,
last_container = kv_last(*container_stack);
}
if (last_container.container.v_type == VAR_LIST) {
- if (last_container.container.vval.v_list->lv_len != 0
+ if (tv_list_len(last_container.container.vval.v_list) != 0
&& !obj.didcomma) {
EMSG2(_("E474: Expected comma before list item: %s"), val_location);
- clear_tv(&obj.val);
+ tv_clear(&obj.val);
return FAIL;
}
assert(last_container.special_val == NULL);
- listitem_T *obj_li = listitem_alloc();
- obj_li->li_tv = obj.val;
- list_append(last_container.container.vval.v_list, obj_li);
+ tv_list_append_owned_tv(last_container.container.vval.v_list, obj.val);
} else if (last_container.stack_index == kv_size(*stack) - 2) {
if (!obj.didcolon) {
EMSG2(_("E474: Expected colon before dictionary value: %s"),
val_location);
- clear_tv(&obj.val);
+ tv_clear(&obj.val);
return FAIL;
}
ValuesStackItem key = kv_pop(*stack);
@@ -138,34 +141,31 @@ static inline int json_decoder_pop(ValuesStackItem obj,
assert(!(key.is_special_string
|| key.val.vval.v_string == NULL
|| *key.val.vval.v_string == NUL));
- dictitem_T *obj_di = dictitem_alloc(key.val.vval.v_string);
- clear_tv(&key.val);
- if (dict_add(last_container.container.vval.v_dict, obj_di)
+ dictitem_T *const obj_di = tv_dict_item_alloc(
+ (const char *)key.val.vval.v_string);
+ tv_clear(&key.val);
+ if (tv_dict_add(last_container.container.vval.v_dict, obj_di)
== FAIL) {
assert(false);
}
obj_di->di_tv = obj.val;
} else {
- list_T *const kv_pair = list_alloc();
- list_append_list(last_container.special_val, kv_pair);
- listitem_T *const key_li = listitem_alloc();
- key_li->li_tv = key.val;
- list_append(kv_pair, key_li);
- listitem_T *const val_li = listitem_alloc();
- val_li->li_tv = obj.val;
- list_append(kv_pair, val_li);
+ list_T *const kv_pair = tv_list_alloc(2);
+ tv_list_append_list(last_container.special_val, kv_pair);
+ tv_list_append_owned_tv(kv_pair, key.val);
+ tv_list_append_owned_tv(kv_pair, obj.val);
}
} else {
// Object with key only
if (!obj.is_special_string && obj.val.v_type != VAR_STRING) {
EMSG2(_("E474: Expected string key: %s"), *pp);
- clear_tv(&obj.val);
+ tv_clear(&obj.val);
return FAIL;
} else if (!obj.didcomma
&& (last_container.special_val == NULL
&& (DICT_LEN(last_container.container.vval.v_dict) != 0))) {
EMSG2(_("E474: Expected comma before dictionary key: %s"), val_location);
- clear_tv(&obj.val);
+ tv_clear(&obj.val);
return FAIL;
}
// Handle empty key and key represented as special dictionary
@@ -173,16 +173,16 @@ static inline int json_decoder_pop(ValuesStackItem obj,
&& (obj.is_special_string
|| obj.val.vval.v_string == NULL
|| *obj.val.vval.v_string == NUL
- || dict_find(last_container.container.vval.v_dict,
- obj.val.vval.v_string, -1))) {
- clear_tv(&obj.val);
+ || tv_dict_find(last_container.container.vval.v_dict,
+ (const char *)obj.val.vval.v_string, -1))) {
+ tv_clear(&obj.val);
// Restart
(void) kv_pop(*container_stack);
ValuesStackItem last_container_val =
kv_A(*stack, last_container.stack_index);
while (kv_size(*stack) > last_container.stack_index) {
- clear_tv(&(kv_pop(*stack).val));
+ tv_clear(&(kv_pop(*stack).val));
}
*pp = last_container.s;
*didcomma = last_container_val.didcomma;
@@ -218,10 +218,85 @@ static inline int json_decoder_pop(ValuesStackItem obj,
} \
} while (0)
+/// Create a new special dictionary that ought to represent a MAP
+///
+/// @param[out] ret_tv Address where new special dictionary is saved.
+/// @param[in] len Expected number of items to be populated before list
+/// becomes accessible from VimL. It is still valid to
+/// underpopulate a list, value only controls how many elements
+/// will be allocated in advance. @see ListLenSpecials.
+///
+/// @return [allocated] list which should contain key-value pairs. Return value
+/// may be safely ignored.
+list_T *decode_create_map_special_dict(typval_T *const ret_tv,
+ const ptrdiff_t len)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_T *const list = tv_list_alloc(len);
+ tv_list_ref(list);
+ create_special_dict(ret_tv, kMPMap, ((typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ return list;
+}
+
+/// Convert char* string to typval_T
+///
+/// Depending on whether string has (no) NUL bytes, it may use a special
+/// dictionary or decode string to VAR_STRING.
+///
+/// @param[in] s String to decode.
+/// @param[in] len String length.
+/// @param[in] hasnul Whether string has NUL byte, not or it was not yet
+/// determined.
+/// @param[in] binary If true, save special string type as kMPBinary,
+/// otherwise kMPString.
+/// @param[in] s_allocated If true, then `s` was allocated and can be saved in
+/// a returned structure. If it is not saved there, it
+/// will be freed.
+///
+/// @return Decoded string.
+typval_T decode_string(const char *const s, const size_t len,
+ const TriState hasnul, const bool binary,
+ const bool s_allocated)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ assert(s != NULL || len == 0);
+ const bool really_hasnul = (hasnul == kNone
+ ? ((s != NULL) && (memchr(s, NUL, len) != NULL))
+ : (bool)hasnul);
+ if (really_hasnul) {
+ list_T *const list = tv_list_alloc(kListLenMayKnow);
+ tv_list_ref(list);
+ typval_T tv;
+ create_special_dict(&tv, binary ? kMPBinary : kMPString, ((typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_list = list },
+ }));
+ const int elw_ret = encode_list_write((void *)list, s, len);
+ if (s_allocated) {
+ xfree((void *)s);
+ }
+ if (elw_ret == -1) {
+ tv_clear(&tv);
+ return (typval_T) { .v_type = VAR_UNKNOWN, .v_lock = VAR_UNLOCKED };
+ }
+ return tv;
+ } else {
+ return (typval_T) {
+ .v_type = VAR_STRING,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_string = (char_u *)(
+ (s == NULL || s_allocated) ? (char *)s : xmemdupz(s, len)) },
+ };
+ }
+}
+
/// Parse JSON double-quoted string
///
-/// @param[in] conv Defines conversion necessary to convert UTF-8 string to
-/// &encoding.
/// @param[in] buf Buffer being converted.
/// @param[in] buf_len Length of the buffer.
/// @param[in,out] pp Pointer to the start of the string. Must point to '"'.
@@ -238,8 +313,7 @@ static inline int json_decoder_pop(ValuesStackItem obj,
/// value when decoder is restarted, otherwise unused.
///
/// @return OK in case of success, FAIL in case of error.
-static inline int parse_json_string(vimconv_T *const conv,
- const char *const buf, const size_t buf_len,
+static inline int parse_json_string(const char *const buf, const size_t buf_len,
const char **const pp,
ValuesStack *const stack,
ContainerStack *const container_stack,
@@ -360,8 +434,8 @@ static inline int parse_json_string(vimconv_T *const conv,
case 'u': {
const char ubuf[] = { t[1], t[2], t[3], t[4] };
t += 4;
- unsigned long ch;
- vim_str2nr((char_u *) ubuf, NULL, NULL,
+ uvarnumber_T ch;
+ vim_str2nr((char_u *)ubuf, NULL, NULL,
STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4);
if (ch == 0) {
hasnul = true;
@@ -414,43 +488,13 @@ static inline int parse_json_string(vimconv_T *const conv,
}
PUT_FST_IN_PAIR(fst_in_pair, str_end);
#undef PUT_FST_IN_PAIR
- if (conv->vc_type != CONV_NONE) {
- size_t str_len = (size_t) (str_end - str);
- char *const new_str = (char *) string_convert(conv, (char_u *) str,
- &str_len);
- if (new_str == NULL) {
- emsgf(_("E474: Failed to convert string \"%.*s\" from UTF-8"),
- (int) str_len, str);
- xfree(str);
- goto parse_json_string_fail;
- }
- xfree(str);
- str = new_str;
- str_end = new_str + str_len;
- }
- if (hasnul) {
- typval_T obj;
- list_T *const list = list_alloc();
- list->lv_refcount++;
- create_special_dict(&obj, kMPString, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- if (encode_list_write((void *) list, str, (size_t) (str_end - str))
- == -1) {
- clear_tv(&obj);
- goto parse_json_string_fail;
- }
- xfree(str);
- POP(obj, true);
- } else {
- *str_end = NUL;
- POP(((typval_T) {
- .v_type = VAR_STRING,
- .vval = { .v_string = (char_u *) str },
- }), false);
+ *str_end = NUL;
+ typval_T obj = decode_string(
+ str, (size_t)(str_end - str), hasnul ? kTrue : kFalse, false, true);
+ if (obj.v_type == VAR_UNKNOWN) {
+ goto parse_json_string_fail;
}
+ POP(obj, obj.v_type != VAR_STRING);
goto parse_json_string_ret;
parse_json_string_fail:
ret = FAIL;
@@ -564,7 +608,7 @@ parse_json_number_check:
tv.v_type = VAR_FLOAT;
} else {
// Convert integer
- long nr;
+ varnumber_T nr;
int num_len;
vim_str2nr((char_u *) s, NULL, &num_len, 0, &nr, NULL, (int) (p - s));
if ((int) exp_num_len != num_len) {
@@ -572,7 +616,7 @@ parse_json_number_check:
"to integer vim_str2nr consumed %i bytes in place of %zu"),
(int) exp_num_len, s, num_len, exp_num_len);
}
- tv.vval.v_number = (varnumber_T) nr;
+ tv.vval.v_number = nr;
}
if (json_decoder_pop(OBJ(tv, false, *didcomma, *didcolon),
stack, container_stack,
@@ -624,9 +668,6 @@ int json_decode_string(const char *const buf, const size_t buf_len,
EMSG(_("E474: Attempt to decode a blank string"));
return FAIL;
}
- vimconv_T conv = { .vc_type = CONV_NONE };
- convert_setup(&conv, (char_u *) "utf-8", p_enc);
- conv.vc_fail = true;
int ret = OK;
ValuesStack stack = KV_INITIAL_VALUE;
ContainerStack container_stack = KV_INITIAL_VALUE;
@@ -696,8 +737,9 @@ json_decode_string_cycle_start:
} else if (last_container.special_val == NULL
? (last_container.container.v_type == VAR_DICT
? (DICT_LEN(last_container.container.vval.v_dict) == 0)
- : (last_container.container.vval.v_list->lv_len == 0))
- : (last_container.special_val->lv_len == 0)) {
+ : (tv_list_len(last_container.container.vval.v_list)
+ == 0))
+ : (tv_list_len(last_container.special_val) == 0)) {
emsgf(_("E474: Leading comma: %.*s"), LENP(p, e));
goto json_decode_string_fail;
}
@@ -772,7 +814,7 @@ json_decode_string_cycle_start:
break;
}
case '"': {
- if (parse_json_string(&conv, buf, buf_len, &p, &stack, &container_stack,
+ if (parse_json_string(buf, buf_len, &p, &stack, &container_stack,
&next_map_special, &didcomma, &didcolon)
== FAIL) {
// Error message was already given
@@ -806,8 +848,8 @@ json_decode_string_cycle_start:
break;
}
case '[': {
- list_T *list = list_alloc();
- list->lv_refcount++;
+ list_T *list = tv_list_alloc(kListLenMayKnow);
+ tv_list_ref(list);
typval_T tv = {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
@@ -827,15 +869,9 @@ json_decode_string_cycle_start:
list_T *val_list = NULL;
if (next_map_special) {
next_map_special = false;
- val_list = list_alloc();
- val_list->lv_refcount++;
- create_special_dict(&tv, kMPMap, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = val_list },
- }));
+ val_list = decode_create_map_special_dict(&tv, kListLenMayKnow);
} else {
- dict_T *dict = dict_alloc();
+ dict_T *dict = tv_dict_alloc();
dict->dv_refcount++;
tv = (typval_T) {
.v_type = VAR_DICT,
@@ -887,7 +923,7 @@ json_decode_string_after_cycle:
json_decode_string_fail:
ret = FAIL;
while (kv_size(stack)) {
- clear_tv(&(kv_pop(stack).val));
+ tv_clear(&(kv_pop(stack).val));
}
json_decode_string_ret:
kv_destroy(stack);
@@ -933,45 +969,51 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
.vval = { .v_number = (varnumber_T) mobj.via.u64 },
};
} else {
- list_T *const list = list_alloc();
- list->lv_refcount++;
+ list_T *const list = tv_list_alloc(4);
+ tv_list_ref(list);
create_special_dict(rettv, kMPInteger, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
.vval = { .v_list = list },
}));
uint64_t n = mobj.via.u64;
- list_append_number(list, 1);
- list_append_number(list, (varnumber_T) ((n >> 62) & 0x3));
- list_append_number(list, (varnumber_T) ((n >> 31) & 0x7FFFFFFF));
- list_append_number(list, (varnumber_T) (n & 0x7FFFFFFF));
+ tv_list_append_number(list, 1);
+ tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
+ tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
+ tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
break;
}
case MSGPACK_OBJECT_NEGATIVE_INTEGER: {
- if (mobj.via.i64 >= VARNUMBER_MIN) {
+ if (mobj.via.i64 >= VARNUMBER_MIN) { // -V547
*rettv = (typval_T) {
.v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
.vval = { .v_number = (varnumber_T) mobj.via.i64 },
};
} else {
- list_T *const list = list_alloc();
- list->lv_refcount++;
+ list_T *const list = tv_list_alloc(4);
+ tv_list_ref(list);
create_special_dict(rettv, kMPInteger, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
.vval = { .v_list = list },
}));
- uint64_t n = -((uint64_t) mobj.via.i64);
- list_append_number(list, -1);
- list_append_number(list, (varnumber_T) ((n >> 62) & 0x3));
- list_append_number(list, (varnumber_T) ((n >> 31) & 0x7FFFFFFF));
- list_append_number(list, (varnumber_T) (n & 0x7FFFFFFF));
+ uint64_t n = -((uint64_t)mobj.via.i64);
+ tv_list_append_number(list, -1);
+ tv_list_append_number(list, (varnumber_T)((n >> 62) & 0x3));
+ tv_list_append_number(list, (varnumber_T)((n >> 31) & 0x7FFFFFFF));
+ tv_list_append_number(list, (varnumber_T)(n & 0x7FFFFFFF));
}
break;
}
- case MSGPACK_OBJECT_FLOAT: {
+#ifdef NVIM_MSGPACK_HAS_FLOAT32
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
+#else
+ case MSGPACK_OBJECT_FLOAT:
+#endif
+ {
*rettv = (typval_T) {
.v_type = VAR_FLOAT,
.v_lock = VAR_UNLOCKED,
@@ -980,54 +1022,35 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
break;
}
case MSGPACK_OBJECT_STR: {
- list_T *const list = list_alloc();
- list->lv_refcount++;
- create_special_dict(rettv, kMPString, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- if (encode_list_write((void *) list, mobj.via.str.ptr, mobj.via.str.size)
- == -1) {
+ *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kTrue, false,
+ false);
+ if (rettv->v_type == VAR_UNKNOWN) {
return FAIL;
}
break;
}
case MSGPACK_OBJECT_BIN: {
- if (memchr(mobj.via.bin.ptr, NUL, mobj.via.bin.size) == NULL) {
- *rettv = (typval_T) {
- .v_type = VAR_STRING,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_string = xmemdupz(mobj.via.bin.ptr, mobj.via.bin.size) },
- };
- break;
- }
- list_T *const list = list_alloc();
- list->lv_refcount++;
- create_special_dict(rettv, kMPBinary, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
- if (encode_list_write((void *) list, mobj.via.bin.ptr, mobj.via.bin.size)
- == -1) {
+ *rettv = decode_string(mobj.via.bin.ptr, mobj.via.bin.size, kNone, true,
+ false);
+ if (rettv->v_type == VAR_UNKNOWN) {
return FAIL;
}
break;
}
case MSGPACK_OBJECT_ARRAY: {
- list_T *const list = list_alloc();
- list->lv_refcount++;
+ list_T *const list = tv_list_alloc((ptrdiff_t)mobj.via.array.size);
+ tv_list_ref(list);
*rettv = (typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
.vval = { .v_list = list },
};
for (size_t i = 0; i < mobj.via.array.size; i++) {
- listitem_T *const li = listitem_alloc();
- li->li_tv.v_type = VAR_UNKNOWN;
- list_append(list, li);
- if (msgpack_to_vim(mobj.via.array.ptr[i], &li->li_tv) == FAIL) {
+ // Not populated yet, need to create list item to push.
+ tv_list_append_owned_tv(list, (typval_T) { .v_type = VAR_UNKNOWN });
+ if (msgpack_to_vim(mobj.via.array.ptr[i],
+ TV_LIST_ITEM_TV(tv_list_last(list)))
+ == FAIL) {
return FAIL;
}
}
@@ -1042,7 +1065,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
goto msgpack_to_vim_generic_map;
}
}
- dict_T *const dict = dict_alloc();
+ dict_T *const dict = tv_dict_alloc();
dict->dv_refcount++;
*rettv = (typval_T) {
.v_type = VAR_DICT,
@@ -1055,9 +1078,9 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
memcpy(&di->di_key[0], mobj.via.map.ptr[i].key.via.str.ptr,
mobj.via.map.ptr[i].key.via.str.size);
di->di_tv.v_type = VAR_UNKNOWN;
- if (dict_add(dict, di) == FAIL) {
+ if (tv_dict_add(dict, di) == FAIL) {
// Duplicate key: fallback to generic map
- clear_tv(rettv);
+ tv_clear(rettv);
xfree(di);
goto msgpack_to_vim_generic_map;
}
@@ -1067,37 +1090,34 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
}
break;
msgpack_to_vim_generic_map: {}
- list_T *const list = list_alloc();
- list->lv_refcount++;
- create_special_dict(rettv, kMPMap, ((typval_T) {
- .v_type = VAR_LIST,
- .v_lock = VAR_UNLOCKED,
- .vval = { .v_list = list },
- }));
+ list_T *const list = decode_create_map_special_dict(
+ rettv, (ptrdiff_t)mobj.via.map.size);
for (size_t i = 0; i < mobj.via.map.size; i++) {
- list_T *const kv_pair = list_alloc();
- list_append_list(list, kv_pair);
- listitem_T *const key_li = listitem_alloc();
- key_li->li_tv.v_type = VAR_UNKNOWN;
- list_append(kv_pair, key_li);
- listitem_T *const val_li = listitem_alloc();
- val_li->li_tv.v_type = VAR_UNKNOWN;
- list_append(kv_pair, val_li);
- if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_li->li_tv) == FAIL) {
+ list_T *const kv_pair = tv_list_alloc(2);
+ tv_list_append_list(list, kv_pair);
+
+ typval_T key_tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(mobj.via.map.ptr[i].key, &key_tv) == FAIL) {
+ tv_clear(&key_tv);
return FAIL;
}
- if (msgpack_to_vim(mobj.via.map.ptr[i].val, &val_li->li_tv) == FAIL) {
+ tv_list_append_owned_tv(kv_pair, key_tv);
+
+ typval_T val_tv = { .v_type = VAR_UNKNOWN };
+ if (msgpack_to_vim(mobj.via.map.ptr[i].val, &val_tv) == FAIL) {
+ tv_clear(&val_tv);
return FAIL;
}
+ tv_list_append_owned_tv(kv_pair, val_tv);
}
break;
}
case MSGPACK_OBJECT_EXT: {
- list_T *const list = list_alloc();
- list->lv_refcount++;
- list_append_number(list, mobj.via.ext.type);
- list_T *const ext_val_list = list_alloc();
- list_append_list(list, ext_val_list);
+ list_T *const list = tv_list_alloc(2);
+ tv_list_ref(list);
+ tv_list_append_number(list, mobj.via.ext.type);
+ list_T *const ext_val_list = tv_list_alloc(kListLenMayKnow);
+ tv_list_append_list(list, ext_val_list);
create_special_dict(rettv, kMPExt, ((typval_T) {
.v_type = VAR_LIST,
.v_lock = VAR_UNLOCKED,
diff --git a/src/nvim/eval/decode.h b/src/nvim/eval/decode.h
index 5c25a64f7a..77fc4c78c2 100644
--- a/src/nvim/eval/decode.h
+++ b/src/nvim/eval/decode.h
@@ -5,7 +5,8 @@
#include <msgpack.h>
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
+#include "nvim/globals.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/decode.h.generated.h"
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 670437ceda..64658b52d9 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.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
+
/// @file encode.c
///
/// File containing functions for encoding and decoding VimL values.
@@ -11,9 +14,9 @@
#include <math.h>
#include "nvim/eval/encode.h"
-#include "nvim/buffer_defs.h" // vimconv_T
+#include "nvim/buffer_defs.h"
#include "nvim/eval.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/garray.h"
#include "nvim/mbyte.h"
#include "nvim/message.h"
@@ -25,14 +28,15 @@
#include "nvim/lib/kvec.h"
#include "nvim/eval/typval_encode.h"
+#ifdef __MINGW32__
+# undef fpclassify
+# define fpclassify __fpclassify
+#endif
+
#define ga_concat(a, b) ga_concat(a, (char_u *)b)
#define utf_ptr2char(b) utf_ptr2char((char_u *)b)
#define utf_ptr2len(b) ((size_t)utf_ptr2len((char_u *)b))
#define utf_char2len(b) ((size_t)utf_char2len(b))
-#define string_convert(a, b, c) \
- ((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
-#define convert_setup(vcp, from, to) \
- (convert_setup(vcp, (char_u *)from, (char_u *)to))
const char *const encode_special_var_names[] = {
[kSpecialVarNull] = "null",
@@ -45,7 +49,8 @@ const char *const encode_special_var_names[] = {
#endif
/// Msgpack callback for writing to readfile()-style list
-int encode_list_write(void *data, const char *buf, size_t len)
+int encode_list_write(void *const data, const char *const buf, const size_t len)
+ FUNC_ATTR_NONNULL_ARG(1)
{
if (len == 0) {
return 0;
@@ -53,17 +58,18 @@ int encode_list_write(void *data, const char *buf, size_t len)
list_T *const list = (list_T *) data;
const char *const end = buf + len;
const char *line_end = buf;
- listitem_T *li = list->lv_last;
+ listitem_T *li = tv_list_last(list);
// Continue the last list element
if (li != NULL) {
line_end = xmemscan(buf, NL, len);
if (line_end != buf) {
const size_t line_length = (size_t)(line_end - buf);
- char *str = (char *)li->li_tv.vval.v_string;
+ char *str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string;
const size_t li_len = (str == NULL ? 0 : strlen(str));
- li->li_tv.vval.v_string = xrealloc(str, li_len + line_length + 1);
- str = (char *)li->li_tv.vval.v_string + li_len;
+ TV_LIST_ITEM_TV(li)->vval.v_string = xrealloc(
+ str, li_len + line_length + 1);
+ str = (char *)TV_LIST_ITEM_TV(li)->vval.v_string + li_len;
memcpy(str, buf, line_length);
str[line_length] = 0;
memchrsub(str, NUL, NL, line_length);
@@ -80,11 +86,11 @@ int encode_list_write(void *data, const char *buf, size_t len)
str = xmemdupz(line_start, line_length);
memchrsub(str, NUL, NL, line_length);
}
- list_append_allocated_string(list, str);
+ tv_list_append_allocated_string(list, str);
line_end++;
}
if (line_end == end) {
- list_append_allocated_string(list, NULL);
+ tv_list_append_allocated_string(list, NULL);
}
return 0;
}
@@ -108,9 +114,12 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
{
garray_T msg_ga;
ga_init(&msg_ga, (int)sizeof(char), 80);
- char *const key_msg = _("key %s");
- char *const key_pair_msg = _("key %s at index %i from special map");
- char *const idx_msg = _("index %i");
+ const char *const key_msg = _("key %s");
+ const char *const key_pair_msg = _("key %s at index %i from special map");
+ const char *const idx_msg = _("index %i");
+ const char *const partial_arg_msg = _("partial");
+ const char *const partial_arg_i_msg = _("argument %i");
+ const char *const partial_self_msg = _("partial self dictionary");
for (size_t i = 0; i < kv_size(*mpstack); i++) {
if (i != 0) {
ga_concat(&msg_ga, ", ");
@@ -132,21 +141,27 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
}
case kMPConvPairs:
case kMPConvList: {
- int idx = 0;
- const listitem_T *li;
- for (li = v.data.l.list->lv_first;
- li != NULL && li->li_next != v.data.l.li;
- li = li->li_next) {
- idx++;
- }
+ const int idx = (v.data.l.li == tv_list_first(v.data.l.list)
+ ? 0
+ : (v.data.l.li == NULL
+ ? tv_list_len(v.data.l.list) - 1
+ : (int)tv_list_idx_of_item(
+ v.data.l.list,
+ TV_LIST_ITEM_PREV(v.data.l.list,
+ v.data.l.li))));
+ const listitem_T *const li = (v.data.l.li == NULL
+ ? tv_list_last(v.data.l.list)
+ : TV_LIST_ITEM_PREV(v.data.l.list,
+ v.data.l.li));
if (v.type == kMPConvList
|| li == NULL
- || (li->li_tv.v_type != VAR_LIST
- && li->li_tv.vval.v_list->lv_len <= 0)) {
- vim_snprintf((char *) IObuff, IOSIZE, idx_msg, idx);
+ || (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST
+ && tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) <= 0)) {
+ vim_snprintf((char *)IObuff, IOSIZE, idx_msg, idx);
ga_concat(&msg_ga, IObuff);
} else {
- typval_T key_tv = li->li_tv.vval.v_list->lv_first->li_tv;
+ typval_T key_tv = *TV_LIST_ITEM_TV(
+ tv_list_first(TV_LIST_ITEM_TV(li)->vval.v_list));
char *const key = encode_tv2echo(&key_tv, NULL);
vim_snprintf((char *) IObuff, IOSIZE, key_pair_msg, key, idx);
xfree(key);
@@ -154,11 +169,34 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
}
break;
}
+ case kMPConvPartial: {
+ switch (v.data.p.stage) {
+ case kMPConvPartialArgs: {
+ assert(false);
+ break;
+ }
+ case kMPConvPartialSelf: {
+ ga_concat(&msg_ga, partial_arg_msg);
+ break;
+ }
+ case kMPConvPartialEnd: {
+ ga_concat(&msg_ga, partial_self_msg);
+ break;
+ }
+ }
+ break;
+ }
+ case kMPConvPartialList: {
+ const int idx = (int)(v.data.a.arg - v.data.a.argv) - 1;
+ vim_snprintf((char *)IObuff, IOSIZE, partial_arg_i_msg, idx);
+ ga_concat(&msg_ga, IObuff);
+ break;
+ }
}
}
- EMSG3(msg, objname, (kv_size(*mpstack) == 0
- ? _("itself")
- : (char *) msg_ga.ga_data));
+ emsgf(msg, _(objname), (kv_size(*mpstack) == 0
+ ? _("itself")
+ : (char *)msg_ga.ga_data));
ga_clear(&msg_ga);
return FAIL;
}
@@ -176,21 +214,17 @@ bool encode_vim_list_to_buf(const list_T *const list, size_t *const ret_len,
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
size_t len = 0;
- if (list != NULL) {
- for (const listitem_T *li = list->lv_first;
- li != NULL;
- li = li->li_next) {
- if (li->li_tv.v_type != VAR_STRING) {
- return false;
- }
- len++;
- if (li->li_tv.vval.v_string != 0) {
- len += STRLEN(li->li_tv.vval.v_string);
- }
+ TV_LIST_ITER_CONST(list, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) {
+ return false;
}
- if (len) {
- len--;
+ len++;
+ if (TV_LIST_ITEM_TV(li)->vval.v_string != NULL) {
+ len += STRLEN(TV_LIST_ITEM_TV(li)->vval.v_string);
}
+ });
+ if (len) {
+ len--;
}
*ret_len = len;
if (len == 0) {
@@ -227,34 +261,39 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
char *const buf_end = buf + nbuf;
char *p = buf;
while (p < buf_end) {
+ assert(state->li_length == 0
+ || TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) {
- const char ch = (char) state->li->li_tv.vval.v_string[state->offset++];
- *p++ = (char) ((char) ch == (char) NL ? (char) NUL : (char) ch);
+ assert(TV_LIST_ITEM_TV(state->li)->vval.v_string != NULL);
+ const char ch = (char)(
+ TV_LIST_ITEM_TV(state->li)->vval.v_string[state->offset++]);
+ *p++ = (char)((char)ch == (char)NL ? (char)NUL : (char)ch);
}
if (p < buf_end) {
- state->li = state->li->li_next;
+ state->li = TV_LIST_ITEM_NEXT(state->list, state->li);
if (state->li == NULL) {
*read_bytes = (size_t) (p - buf);
return OK;
}
*p++ = NL;
- if (state->li->li_tv.v_type != VAR_STRING) {
- *read_bytes = (size_t) (p - buf);
+ if (TV_LIST_ITEM_TV(state->li)->v_type != VAR_STRING) {
+ *read_bytes = (size_t)(p - buf);
return FAIL;
}
state->offset = 0;
- state->li_length = (state->li->li_tv.vval.v_string == NULL
+ state->li_length = (TV_LIST_ITEM_TV(state->li)->vval.v_string == NULL
? 0
- : STRLEN(state->li->li_tv.vval.v_string));
+ : STRLEN(TV_LIST_ITEM_TV(state->li)->vval.v_string));
}
}
*read_bytes = nbuf;
- return (state->offset < state->li_length || state->li->li_next != NULL
+ return ((state->offset < state->li_length
+ || TV_LIST_ITEM_NEXT(state->list, state->li) != NULL)
? NOTDONE
: OK);
}
-#define TYPVAL_ENCODE_CONV_STRING(buf, len) \
+#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
const char *const buf_ = (const char *) buf; \
if (buf == NULL) { \
@@ -263,29 +302,29 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
const size_t len_ = (len); \
ga_grow(gap, (int) (2 + len_ + memcnt(buf_, '\'', len_))); \
ga_append(gap, '\''); \
- for (size_t i = 0; i < len_; i++) { \
- if (buf_[i] == '\'') { \
+ for (size_t i_ = 0; i_ < len_; i_++) { \
+ if (buf_[i_] == '\'') { \
ga_append(gap, '\''); \
} \
- ga_append(gap, buf_[i]); \
+ ga_append(gap, buf_[i_]); \
} \
ga_append(gap, '\''); \
} \
} while (0)
-#define TYPVAL_ENCODE_CONV_STR_STRING(buf, len) \
- TYPVAL_ENCODE_CONV_STRING(buf, len)
+#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
+ TYPVAL_ENCODE_CONV_STRING(tv, buf, len)
-#define TYPVAL_ENCODE_CONV_EXT_STRING(buf, len, type)
+#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
-#define TYPVAL_ENCODE_CONV_NUMBER(num) \
+#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
do { \
char numbuf[NUMBUFLEN]; \
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRId64, (int64_t) (num)); \
ga_concat(gap, numbuf); \
} while (0)
-#define TYPVAL_ENCODE_CONV_FLOAT(flt) \
+#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
do { \
const float_T flt_ = (flt); \
switch (fpclassify(flt_)) { \
@@ -308,49 +347,75 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
} \
} while (0)
-#define TYPVAL_ENCODE_CONV_FUNC(fun) \
+#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
+ do { \
+ const char *const fun_ = (const char *)(fun); \
+ if (fun_ == NULL) { \
+ internal_error("string(): NULL function name"); \
+ ga_concat(gap, "function(NULL"); \
+ } else { \
+ ga_concat(gap, "function("); \
+ TYPVAL_ENCODE_CONV_STRING(tv, fun_, strlen(fun_)); \
+ }\
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len) \
+ do { \
+ if (len != 0) { \
+ ga_concat(gap, ", "); \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len) \
do { \
- ga_concat(gap, "function("); \
- TYPVAL_ENCODE_CONV_STRING(fun, STRLEN(fun)); \
- ga_append(gap, ')'); \
+ if ((ptrdiff_t)len != -1) { \
+ ga_concat(gap, ", "); \
+ } \
} while (0)
-#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
+#define TYPVAL_ENCODE_CONV_FUNC_END(tv) \
+ ga_append(gap, ')')
+
+#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
ga_concat(gap, "[]")
-#define TYPVAL_ENCODE_CONV_LIST_START(len) \
+#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
ga_append(gap, '[')
-#define TYPVAL_ENCODE_CONV_EMPTY_DICT() \
+#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
ga_concat(gap, "{}")
-#define TYPVAL_ENCODE_CONV_NIL() \
+#define TYPVAL_ENCODE_CONV_NIL(tv) \
ga_concat(gap, "v:null")
-#define TYPVAL_ENCODE_CONV_BOOL(num) \
+#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
ga_concat(gap, ((num)? "v:true": "v:false"))
-#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(num)
+#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
-#define TYPVAL_ENCODE_CONV_DICT_START(len) \
+#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
ga_append(gap, '{')
-#define TYPVAL_ENCODE_CONV_DICT_END() \
+#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
+
+#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
ga_append(gap, '}')
-#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY() \
+#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict) \
ga_concat(gap, ": ")
-#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS() \
+#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
ga_concat(gap, ", ")
-#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(label, key)
+#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key)
-#define TYPVAL_ENCODE_CONV_LIST_END() \
+#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
ga_append(gap, ']')
-#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS() \
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS()
+#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, NULL)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
do { \
@@ -383,7 +448,15 @@ int encode_read_from_list(ListReaderState *const state, char *const buf,
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
-TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, string, garray_T *const, gap)
+#define TYPVAL_ENCODE_SCOPE static
+#define TYPVAL_ENCODE_NAME string
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE garray_T *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME gap
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
#undef TYPVAL_ENCODE_CONV_RECURSE
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
@@ -413,7 +486,15 @@ TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, string, garray_T *const, gap)
return OK; \
} while (0)
-TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(, echo, garray_T *const, gap)
+#define TYPVAL_ENCODE_SCOPE
+#define TYPVAL_ENCODE_NAME echo
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE garray_T *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME gap
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
#undef TYPVAL_ENCODE_CONV_RECURSE
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
@@ -431,15 +512,15 @@ TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(, echo, garray_T *const, gap)
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
#undef TYPVAL_ENCODE_CONV_NIL
-#define TYPVAL_ENCODE_CONV_NIL() \
+#define TYPVAL_ENCODE_CONV_NIL(tv) \
ga_concat(gap, "null")
#undef TYPVAL_ENCODE_CONV_BOOL
-#define TYPVAL_ENCODE_CONV_BOOL(num) \
+#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
ga_concat(gap, ((num)? "true": "false"))
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
-#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(num) \
+#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
do { \
char numbuf[NUMBUFLEN]; \
vim_snprintf(numbuf, ARRAY_SIZE(numbuf), "%" PRIu64, (num)); \
@@ -447,7 +528,7 @@ TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(, echo, garray_T *const, gap)
} while (0)
#undef TYPVAL_ENCODE_CONV_FLOAT
-#define TYPVAL_ENCODE_CONV_FLOAT(flt) \
+#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
do { \
const float_T flt_ = (flt); \
switch (fpclassify(flt_)) { \
@@ -468,17 +549,6 @@ TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(, echo, garray_T *const, gap)
} \
} while (0)
-/// Last used p_enc value
-///
-/// Generic pointer: it is not used as a string, only pointer comparisons are
-/// performed. Must not be freed.
-static const void *last_p_enc = NULL;
-
-/// Conversion setup for converting from last_p_enc to UTF-8
-static vimconv_T p_enc_conv = {
- .vc_type = CONV_NONE,
-};
-
/// Escape sequences used in JSON
static const char escapes[][3] = {
[BS] = "\\b",
@@ -510,33 +580,15 @@ static inline int convert_to_json_string(garray_T *const gap,
} else {
size_t utf_len = len;
char *tofree = NULL;
- if (last_p_enc != (const void *) p_enc) {
- p_enc_conv.vc_type = CONV_NONE;
- convert_setup(&p_enc_conv, p_enc, "utf-8");
- p_enc_conv.vc_fail = true;
- last_p_enc = p_enc;
- }
- if (p_enc_conv.vc_type != CONV_NONE) {
- tofree = string_convert(&p_enc_conv, buf, &utf_len);
- if (tofree == NULL) {
- emsgf(_("E474: Failed to convert string \"%.*s\" to UTF-8"),
- utf_len, utf_buf);
- return FAIL;
- }
- utf_buf = tofree;
- }
size_t str_len = 0;
- // Encode character as \u0000 if
- // 1. It is an ASCII control character (0x0 .. 0x1F, 0x7F).
- // 2. &encoding is not UTF-8 and code point is above 0x7F.
- // 3. &encoding is UTF-8 and code point is not printable according to
- // utf_printable().
- // This is done to make it possible to :echo values when &encoding is not
- // UTF-8.
-#define ENCODE_RAW(p_enc_conv, ch) \
- (ch >= 0x20 && (p_enc_conv.vc_type == CONV_NONE \
- ? utf_printable(ch) \
- : ch < 0x7F))
+ // Encode character as \uNNNN if
+ // 1. It is an ASCII control character (0x0 .. 0x1F; 0x7F not
+ // utf_printable and thus not checked specially).
+ // 2. Code point is not printable according to utf_printable().
+ // This is done to make resulting values displayable on screen also not from
+ // Neovim.
+#define ENCODE_RAW(ch) \
+ (ch >= 0x20 && utf_printable(ch))
for (size_t i = 0; i < utf_len;) {
const int ch = utf_ptr2char(utf_buf + i);
const size_t shift = (ch == 0? 1: utf_ptr2len(utf_buf + i));
@@ -557,17 +609,17 @@ static inline int convert_to_json_string(garray_T *const gap,
if (ch > 0x7F && shift == 1) {
emsgf(_("E474: String \"%.*s\" contains byte that does not start "
"any UTF-8 character"),
- utf_len - (i - shift), utf_buf + i - shift);
+ (int)(utf_len - (i - shift)), utf_buf + i - shift);
xfree(tofree);
return FAIL;
} else if ((SURROGATE_HI_START <= ch && ch <= SURROGATE_HI_END)
|| (SURROGATE_LO_START <= ch && ch <= SURROGATE_LO_END)) {
emsgf(_("E474: UTF-8 string contains code point which belongs "
"to a surrogate pair: %.*s"),
- utf_len - (i - shift), utf_buf + i - shift);
+ (int)(utf_len - (i - shift)), utf_buf + i - shift);
xfree(tofree);
return FAIL;
- } else if (ENCODE_RAW(p_enc_conv, ch)) {
+ } else if (ENCODE_RAW(ch)) {
str_len += shift;
} else {
str_len += ((sizeof("\\u1234") - 1)
@@ -597,7 +649,7 @@ static inline int convert_to_json_string(garray_T *const gap,
break;
}
default: {
- if (ENCODE_RAW(p_enc_conv, ch)) {
+ if (ENCODE_RAW(ch)) {
ga_concat_len(gap, utf_buf + i, shift);
} else if (ch < SURROGATE_FIRST_CHAR) {
ga_concat_len(gap, ((const char[]) {
@@ -636,7 +688,7 @@ static inline int convert_to_json_string(garray_T *const gap,
}
#undef TYPVAL_ENCODE_CONV_STRING
-#define TYPVAL_ENCODE_CONV_STRING(buf, len) \
+#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
if (convert_to_json_string(gap, (const char *) (buf), (len)) != OK) { \
return FAIL; \
@@ -644,15 +696,15 @@ static inline int convert_to_json_string(garray_T *const gap,
} while (0)
#undef TYPVAL_ENCODE_CONV_EXT_STRING
-#define TYPVAL_ENCODE_CONV_EXT_STRING(buf, len, type) \
+#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
do { \
xfree(buf); \
EMSG(_("E474: Unable to convert EXT string to JSON")); \
return FAIL; \
} while (0)
-#undef TYPVAL_ENCODE_CONV_FUNC
-#define TYPVAL_ENCODE_CONV_FUNC(fun) \
+#undef TYPVAL_ENCODE_CONV_FUNC_START
+#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
return conv_error(_("E474: Error while dumping %s, %s: " \
"attempt to dump function reference"), \
mpstack, objname)
@@ -675,28 +727,27 @@ bool encode_check_json_key(const typval_T *const tv)
}
const dictitem_T *type_di;
const dictitem_T *val_di;
- if ((type_di = dict_find((dict_T *) spdict, (char_u *) "_TYPE", -1)) == NULL
+ if ((type_di = tv_dict_find(spdict, S_LEN("_TYPE"))) == NULL
|| type_di->di_tv.v_type != VAR_LIST
|| (type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPString]
&& type_di->di_tv.vval.v_list != eval_msgpack_type_lists[kMPBinary])
- || (val_di = dict_find((dict_T *) spdict, (char_u *) "_VAL", -1)) == NULL
+ || (val_di = tv_dict_find(spdict, S_LEN("_VAL"))) == NULL
|| val_di->di_tv.v_type != VAR_LIST) {
return false;
}
if (val_di->di_tv.vval.v_list == NULL) {
return true;
}
- for (const listitem_T *li = val_di->di_tv.vval.v_list->lv_first;
- li != NULL; li = li->li_next) {
- if (li->li_tv.v_type != VAR_STRING) {
+ TV_LIST_ITER_CONST(val_di->di_tv.vval.v_list, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) {
return false;
}
- }
+ });
return true;
}
-#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
-#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(label, key) \
+#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
+#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key) \
do { \
if (!encode_check_json_key(&key)) { \
EMSG(_("E474: Invalid key in special dictionary")); \
@@ -704,25 +755,38 @@ bool encode_check_json_key(const typval_T *const tv)
} \
} while (0)
-TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(static, json, garray_T *const, gap)
+#define TYPVAL_ENCODE_SCOPE static
+#define TYPVAL_ENCODE_NAME json
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE garray_T *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME gap
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
#undef TYPVAL_ENCODE_CONV_NUMBER
#undef TYPVAL_ENCODE_CONV_FLOAT
-#undef TYPVAL_ENCODE_CONV_FUNC
+#undef TYPVAL_ENCODE_CONV_FUNC_START
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
+#undef TYPVAL_ENCODE_CONV_FUNC_END
#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
#undef TYPVAL_ENCODE_CONV_LIST_START
+#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
#undef TYPVAL_ENCODE_CONV_DICT_START
+#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
#undef TYPVAL_ENCODE_CONV_DICT_END
#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
+#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_CONV_LIST_END
#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_RECURSE
@@ -740,7 +804,10 @@ char *encode_tv2string(typval_T *tv, size_t *len)
{
garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
- encode_vim_to_string(&ga, tv, "encode_tv2string() argument");
+ const int evs_ret = encode_vim_to_string(&ga, tv,
+ N_("encode_tv2string() argument"));
+ (void)evs_ret;
+ assert(evs_ret == OK);
did_echo_string_emsg = false;
if (len != NULL) {
*len = (size_t) ga.ga_len;
@@ -766,7 +833,9 @@ char *encode_tv2echo(typval_T *tv, size_t *len)
ga_concat(&ga, tv->vval.v_string);
}
} else {
- encode_vim_to_echo(&ga, tv, ":echo argument");
+ const int eve_ret = encode_vim_to_echo(&ga, tv, N_(":echo argument"));
+ (void)eve_ret;
+ assert(eve_ret == OK);
}
if (len != NULL) {
*len = (size_t) ga.ga_len;
@@ -787,16 +856,20 @@ char *encode_tv2json(typval_T *tv, size_t *len)
{
garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
- encode_vim_to_json(&ga, tv, "encode_tv2json() argument");
+ const int evj_ret = encode_vim_to_json(&ga, tv,
+ N_("encode_tv2json() argument"));
+ if (!evj_ret) {
+ ga_clear(&ga);
+ }
did_echo_string_emsg = false;
if (len != NULL) {
- *len = (size_t) ga.ga_len;
+ *len = (size_t)ga.ga_len;
}
ga_append(&ga, '\0');
- return (char *) ga.ga_data;
+ return (char *)ga.ga_data;
}
-#define TYPVAL_ENCODE_CONV_STRING(buf, len) \
+#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
do { \
if (buf == NULL) { \
msgpack_pack_bin(packer, 0); \
@@ -807,7 +880,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
} \
} while (0)
-#define TYPVAL_ENCODE_CONV_STR_STRING(buf, len) \
+#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
do { \
if (buf == NULL) { \
msgpack_pack_str(packer, 0); \
@@ -818,7 +891,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
} \
} while (0)
-#define TYPVAL_ENCODE_CONV_EXT_STRING(buf, len, type) \
+#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
do { \
if (buf == NULL) { \
msgpack_pack_ext(packer, 0, (int8_t) type); \
@@ -829,82 +902,103 @@ char *encode_tv2json(typval_T *tv, size_t *len)
} \
} while (0)
-#define TYPVAL_ENCODE_CONV_NUMBER(num) \
- msgpack_pack_int64(packer, (int64_t) (num))
+#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
+ msgpack_pack_int64(packer, (int64_t)(num))
-#define TYPVAL_ENCODE_CONV_FLOAT(flt) \
- msgpack_pack_double(packer, (double) (flt))
+#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
+ msgpack_pack_double(packer, (double)(flt))
-#define TYPVAL_ENCODE_CONV_FUNC(fun) \
- return conv_error(_("E951: Error while dumping %s, %s: " \
+#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
+ return conv_error(_("E5004: Error while dumping %s, %s: " \
"attempt to dump function reference"), \
mpstack, objname)
-#define TYPVAL_ENCODE_CONV_EMPTY_LIST() \
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
msgpack_pack_array(packer, 0)
-#define TYPVAL_ENCODE_CONV_LIST_START(len) \
- msgpack_pack_array(packer, (size_t) (len))
+#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
+ msgpack_pack_array(packer, (size_t)(len))
-#define TYPVAL_ENCODE_CONV_EMPTY_DICT() \
+#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
msgpack_pack_map(packer, 0)
-#define TYPVAL_ENCODE_CONV_NIL() \
+#define TYPVAL_ENCODE_CONV_NIL(tv) \
msgpack_pack_nil(packer)
-#define TYPVAL_ENCODE_CONV_BOOL(num) \
+#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
do { \
- if ((num)) { \
+ if (num) { \
msgpack_pack_true(packer); \
} else { \
msgpack_pack_false(packer); \
} \
} while (0)
-#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(num) \
+#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
msgpack_pack_uint64(packer, (num))
-#define TYPVAL_ENCODE_CONV_DICT_START(len) \
- msgpack_pack_map(packer, (size_t) (len))
+#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
+ msgpack_pack_map(packer, (size_t)(len))
+
+#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
-#define TYPVAL_ENCODE_CONV_DICT_END()
+#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict)
-#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY()
+#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
-#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS()
+#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
-#define TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK(label, key)
+#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, key)
-#define TYPVAL_ENCODE_CONV_LIST_END()
+#define TYPVAL_ENCODE_CONV_LIST_END(tv)
-#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS()
+#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
- return conv_error(_("E952: Unable to dump %s: " \
+ return conv_error(_("E5005: Unable to dump %s: " \
"container references itself in %s"), \
mpstack, objname)
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
-TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(, msgpack, msgpack_packer *const, packer)
+#define TYPVAL_ENCODE_SCOPE
+#define TYPVAL_ENCODE_NAME msgpack
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE msgpack_packer *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME packer
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
#undef TYPVAL_ENCODE_CONV_STRING
#undef TYPVAL_ENCODE_CONV_STR_STRING
#undef TYPVAL_ENCODE_CONV_EXT_STRING
#undef TYPVAL_ENCODE_CONV_NUMBER
#undef TYPVAL_ENCODE_CONV_FLOAT
-#undef TYPVAL_ENCODE_CONV_FUNC
+#undef TYPVAL_ENCODE_CONV_FUNC_START
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
+#undef TYPVAL_ENCODE_CONV_FUNC_END
#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
#undef TYPVAL_ENCODE_CONV_LIST_START
+#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
#undef TYPVAL_ENCODE_CONV_DICT_START
+#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
#undef TYPVAL_ENCODE_CONV_DICT_END
#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
-#undef TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
+#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
#undef TYPVAL_ENCODE_CONV_LIST_END
#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
#undef TYPVAL_ENCODE_CONV_RECURSE
diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h
index 9bc665253b..ccea245ab3 100644
--- a/src/nvim/eval/encode.h
+++ b/src/nvim/eval/encode.h
@@ -33,9 +33,10 @@ int encode_vim_to_echo(garray_T *const packer,
/// Structure defining state for read_from_list()
typedef struct {
+ const list_T *const list; ///< List being currently read.
const listitem_T *li; ///< Item currently read.
- size_t offset; ///< Byte offset inside the read item.
- size_t li_length; ///< Length of the string inside the read item.
+ size_t offset; ///< Byte offset inside the read item.
+ size_t li_length; ///< Length of the string inside the read item.
} ListReaderState;
/// Initialize ListReaderState structure
@@ -43,11 +44,13 @@ static inline ListReaderState encode_init_lrstate(const list_T *const list)
FUNC_ATTR_NONNULL_ALL
{
return (ListReaderState) {
- .li = list->lv_first,
+ .list = list,
+ .li = tv_list_first(list),
.offset = 0,
- .li_length = (list->lv_first->li_tv.vval.v_string == NULL
+ .li_length = (TV_LIST_ITEM_TV(tv_list_first(list))->vval.v_string == NULL
? 0
- : STRLEN(list->lv_first->li_tv.vval.v_string)),
+ : STRLEN(TV_LIST_ITEM_TV(
+ tv_list_first(list))->vval.v_string)),
};
}
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
new file mode 100644
index 0000000000..99298cbbcf
--- /dev/null
+++ b/src/nvim/eval/executor.c
@@ -0,0 +1,118 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/eval/typval.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval.h"
+#include "nvim/message.h"
+#include "nvim/vim.h"
+#include "nvim/globals.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/executor.c.generated.h"
+#endif
+
+static char *e_letwrong = N_("E734: Wrong variable type for %s=");
+
+char *e_listidx = N_("E684: list index out of range: %" PRId64);
+
+/// Hanle tv1 += tv2, -=, .=
+///
+/// @param[in,out] tv1 First operand, modified typval.
+/// @param[in] tv2 Second operand.
+/// @param[in] op Used operator.
+///
+/// @return OK or FAIL.
+int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
+ const char *const op)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
+{
+ // Can't do anything with a Funcref, a Dict or special value on the right.
+ if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) {
+ switch (tv1->v_type) {
+ case VAR_DICT:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_SPECIAL: {
+ break;
+ }
+ case VAR_LIST: {
+ if (*op != '+' || tv2->v_type != VAR_LIST) {
+ break;
+ }
+ // List += List
+ if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) {
+ tv_list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+ }
+ return OK;
+ }
+ case VAR_NUMBER:
+ case VAR_STRING: {
+ if (tv2->v_type == VAR_LIST) {
+ break;
+ }
+ if (*op == '+' || *op == '-') {
+ // nr += nr or nr -= nr
+ varnumber_T n = tv_get_number(tv1);
+ if (tv2->v_type == VAR_FLOAT) {
+ float_T f = (float_T)n;
+
+ if (*op == '+') {
+ f += tv2->vval.v_float;
+ } else {
+ f -= tv2->vval.v_float;
+ }
+ tv_clear(tv1);
+ tv1->v_type = VAR_FLOAT;
+ tv1->vval.v_float = f;
+ } else {
+ if (*op == '+') {
+ n += tv_get_number(tv2);
+ } else {
+ n -= tv_get_number(tv2);
+ }
+ tv_clear(tv1);
+ tv1->v_type = VAR_NUMBER;
+ tv1->vval.v_number = n;
+ }
+ } else {
+ // str .= str
+ if (tv2->v_type == VAR_FLOAT) {
+ break;
+ }
+ const char *tvs = tv_get_string(tv1);
+ char numbuf[NUMBUFLEN];
+ char *const s = (char *)concat_str(
+ (const char_u *)tvs, (const char_u *)tv_get_string_buf(tv2,
+ numbuf));
+ tv_clear(tv1);
+ tv1->v_type = VAR_STRING;
+ tv1->vval.v_string = (char_u *)s;
+ }
+ return OK;
+ }
+ case VAR_FLOAT: {
+ if (*op == '.' || (tv2->v_type != VAR_FLOAT
+ && tv2->v_type != VAR_NUMBER
+ && tv2->v_type != VAR_STRING)) {
+ break;
+ }
+ const float_T f = (tv2->v_type == VAR_FLOAT
+ ? tv2->vval.v_float
+ : (float_T)tv_get_number(tv2));
+ if (*op == '+') {
+ tv1->vval.v_float += f;
+ } else {
+ tv1->vval.v_float -= f;
+ }
+ return OK;
+ }
+ case VAR_UNKNOWN: {
+ assert(false);
+ }
+ }
+ }
+
+ EMSG2(_(e_letwrong), op);
+ return FAIL;
+}
diff --git a/src/nvim/eval/executor.h b/src/nvim/eval/executor.h
new file mode 100644
index 0000000000..3d789f76a5
--- /dev/null
+++ b/src/nvim/eval/executor.h
@@ -0,0 +1,11 @@
+#ifndef NVIM_EVAL_EXECUTOR_H
+#define NVIM_EVAL_EXECUTOR_H
+
+#include "nvim/eval/typval.h"
+
+extern char *e_listidx;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/executor.h.generated.h"
+#endif
+#endif // NVIM_EVAL_EXECUTOR_H
diff --git a/src/nvim/eval/gc.c b/src/nvim/eval/gc.c
new file mode 100644
index 0000000000..2bbf78d827
--- /dev/null
+++ b/src/nvim/eval/gc.c
@@ -0,0 +1,14 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/eval/typval.h"
+#include "nvim/eval/gc.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/gc.c.generated.h"
+#endif
+
+/// Head of list of all dictionaries
+dict_T *gc_first_dict = NULL;
+/// Head of list of all lists
+list_T *gc_first_list = NULL;
diff --git a/src/nvim/eval/gc.h b/src/nvim/eval/gc.h
new file mode 100644
index 0000000000..c2e862e469
--- /dev/null
+++ b/src/nvim/eval/gc.h
@@ -0,0 +1,12 @@
+#ifndef NVIM_EVAL_GC_H
+#define NVIM_EVAL_GC_H
+
+#include "nvim/eval/typval.h"
+
+extern dict_T *gc_first_dict;
+extern list_T *gc_first_list;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/gc.h.generated.h"
+#endif
+#endif // NVIM_EVAL_GC_H
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
new file mode 100644
index 0000000000..912aecafec
--- /dev/null
+++ b/src/nvim/eval/typval.c
@@ -0,0 +1,2912 @@
+// 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 <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdbool.h>
+
+#include "nvim/lib/queue.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/gc.h"
+#include "nvim/eval/executor.h"
+#include "nvim/eval/encode.h"
+#include "nvim/eval/typval_encode.h"
+#include "nvim/eval.h"
+#include "nvim/types.h"
+#include "nvim/assert.h"
+#include "nvim/memory.h"
+#include "nvim/globals.h"
+#include "nvim/hashtab.h"
+#include "nvim/vim.h"
+#include "nvim/ascii.h"
+#include "nvim/pos.h"
+#include "nvim/charset.h"
+#include "nvim/garray.h"
+#include "nvim/gettext.h"
+#include "nvim/macros.h"
+#include "nvim/mbyte.h"
+#include "nvim/message.h"
+// TODO(ZyX-I): Move line_breakcheck out of misc1
+#include "nvim/misc1.h" // For line_breakcheck
+#include "nvim/os/fileio.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/typval.c.generated.h"
+#endif
+
+bool tv_in_free_unref_items = false;
+
+// TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead
+
+#define DICT_MAXNEST 100
+
+const char *const tv_empty_string = "";
+
+//{{{1 Lists
+//{{{2 List log
+#ifdef LOG_LIST_ACTIONS
+ListLog *list_log_first = NULL;
+ListLog *list_log_last = NULL;
+
+/// Write list log to the given file
+///
+/// @param[in] fname File to write log to. Will be appended to if already
+/// present.
+void list_write_log(const char *const fname)
+ FUNC_ATTR_NONNULL_ALL
+{
+ FileDescriptor fp;
+ const int fo_ret = file_open(&fp, fname, kFileCreate|kFileAppend, 0600);
+ if (fo_ret != 0) {
+ emsgf(_("E5142: Failed to open file %s: %s"), fname, os_strerror(fo_ret));
+ return;
+ }
+ for (ListLog *chunk = list_log_first; chunk != NULL;) {
+ for (size_t i = 0; i < chunk->size; i++) {
+ char buf[10 + 1 + ((16 + 3) * 3) + (8 + 2) + 2];
+ // act : hex " c:" len "[]" "\n\0"
+ const ListLogEntry entry = chunk->entries[i];
+ const size_t snp_len = (size_t)snprintf(
+ buf, sizeof(buf),
+ "%-10.10s: l:%016" PRIxPTR "[%08d] 1:%016" PRIxPTR " 2:%016" PRIxPTR
+ "\n",
+ entry.action, entry.l, entry.len, entry.li1, entry.li2);
+ assert(snp_len + 1 == sizeof(buf));
+ const ptrdiff_t fw_ret = file_write(&fp, buf, snp_len);
+ if (fw_ret != (ptrdiff_t)snp_len) {
+ assert(fw_ret < 0);
+ if (i) {
+ memmove(chunk->entries, chunk->entries + i,
+ sizeof(chunk->entries[0]) * (chunk->size - i));
+ chunk->size -= i;
+ }
+ emsgf(_("E5143: Failed to write to file %s: %s"),
+ fname, os_strerror((int)fw_ret));
+ return;
+ }
+ }
+ list_log_first = chunk->next;
+ xfree(chunk);
+ chunk = list_log_first;
+ }
+ const int fc_ret = file_close(&fp, true);
+ if (fc_ret != 0) {
+ emsgf(_("E5144: Failed to close file %s: %s"), fname, os_strerror(fc_ret));
+ }
+}
+
+#ifdef EXITFREE
+/// Free list log
+void list_free_log(void)
+{
+ for (ListLog *chunk = list_log_first; chunk != NULL;) {
+ list_log_first = chunk->next;
+ xfree(chunk);
+ chunk = list_log_first;
+ }
+}
+#endif
+#endif
+//{{{2 List item
+
+/// Allocate a list item
+///
+/// @warning Allocated item is not initialized, do not forget to initialize it
+/// and specifically set lv_lock.
+///
+/// @return [allocated] new list item.
+static listitem_T *tv_list_item_alloc(void)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC
+{
+ return xmalloc(sizeof(listitem_T));
+}
+
+/// Remove a list item from a List and free it
+///
+/// Also clears the value.
+///
+/// @param[out] l List to remove item from.
+/// @param[in,out] item Item to remove.
+///
+/// @return Pointer to the list item just after removed one, NULL if removed
+/// item was the last one.
+listitem_T *tv_list_item_remove(list_T *const l, listitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ listitem_T *const next_item = TV_LIST_ITEM_NEXT(l, item);
+ tv_list_drop_items(l, item, item);
+ tv_clear(TV_LIST_ITEM_TV(item));
+ xfree(item);
+ return next_item;
+}
+
+//{{{2 List watchers
+
+/// Add a watcher to a list
+///
+/// @param[out] l List to add watcher to.
+/// @param[in] lw Watcher to add.
+void tv_list_watch_add(list_T *const l, listwatch_T *const lw)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lw->lw_next = l->lv_watch;
+ l->lv_watch = lw;
+}
+
+/// Remove a watcher from a list
+///
+/// Does not give a warning if watcher was not found.
+///
+/// @param[out] l List to remove watcher from.
+/// @param[in] lwrem Watcher to remove.
+void tv_list_watch_remove(list_T *const l, listwatch_T *const lwrem)
+ FUNC_ATTR_NONNULL_ALL
+{
+ listwatch_T **lwp = &l->lv_watch;
+ for (listwatch_T *lw = l->lv_watch; lw != NULL; lw = lw->lw_next) {
+ if (lw == lwrem) {
+ *lwp = lw->lw_next;
+ break;
+ }
+ lwp = &lw->lw_next;
+ }
+}
+
+/// Advance watchers to the next item
+///
+/// Used just before removing an item from a list.
+///
+/// @param[out] l List from which item is removed.
+/// @param[in] item List item being removed.
+void tv_list_watch_fix(list_T *const l, const listitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ for (listwatch_T *lw = l->lv_watch; lw != NULL; lw = lw->lw_next) {
+ if (lw->lw_item == item) {
+ lw->lw_item = item->li_next;
+ }
+ }
+}
+
+//{{{2 Alloc/free
+
+/// Allocate an empty list
+///
+/// Caller should take care of the reference count.
+///
+/// @param[in] len Expected number of items to be populated before list
+/// becomes accessible from VimL. It is still valid to
+/// underpopulate a list, value only controls how many elements
+/// will be allocated in advance. Currently does nothing.
+/// @see ListLenSpecials.
+///
+/// @return [allocated] new list.
+list_T *tv_list_alloc(const ptrdiff_t len)
+ FUNC_ATTR_NONNULL_RET
+{
+ list_T *const list = xcalloc(1, sizeof(list_T));
+
+ // Prepend the list to the list of lists for garbage collection.
+ if (gc_first_list != NULL) {
+ gc_first_list->lv_used_prev = list;
+ }
+ list->lv_used_prev = NULL;
+ list->lv_used_next = gc_first_list;
+ gc_first_list = list;
+ list_log(list, NULL, (void *)(uintptr_t)len, "alloc");
+ return list;
+}
+
+/// Initialize a static list with 10 items
+///
+/// @param[out] sl Static list to initialize.
+void tv_list_init_static10(staticList10_T *const sl)
+ FUNC_ATTR_NONNULL_ALL
+{
+#define SL_SIZE ARRAY_SIZE(sl->sl_items)
+ list_T *const l = &sl->sl_list;
+
+ memset(sl, 0, sizeof(staticList10_T));
+ l->lv_first = &sl->sl_items[0];
+ l->lv_last = &sl->sl_items[SL_SIZE - 1];
+ l->lv_refcount = DO_NOT_FREE_CNT;
+ tv_list_set_lock(l, VAR_FIXED);
+ sl->sl_list.lv_len = 10;
+
+ sl->sl_items[0].li_prev = NULL;
+ sl->sl_items[0].li_next = &sl->sl_items[1];
+ sl->sl_items[SL_SIZE - 1].li_prev = &sl->sl_items[SL_SIZE - 2];
+ sl->sl_items[SL_SIZE - 1].li_next = NULL;
+
+ for (size_t i = 1; i < SL_SIZE - 1; i++) {
+ listitem_T *const li = &sl->sl_items[i];
+ li->li_prev = li - 1;
+ li->li_next = li + 1;
+ }
+ list_log((const list_T *)sl, &sl->sl_items[0], &sl->sl_items[SL_SIZE - 1],
+ "s10init");
+#undef SL_SIZE
+}
+
+/// Initialize static list with undefined number of elements
+///
+/// @param[out] l List to initialize.
+void tv_list_init_static(list_T *const l)
+ FUNC_ATTR_NONNULL_ALL
+{
+ memset(l, 0, sizeof(*l));
+ l->lv_refcount = DO_NOT_FREE_CNT;
+ list_log(l, NULL, NULL, "sinit");
+}
+
+/// Free items contained in a list
+///
+/// @param[in,out] l List to clear.
+void tv_list_free_contents(list_T *const l)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_log(l, NULL, NULL, "freecont");
+ for (listitem_T *item = l->lv_first; item != NULL; item = l->lv_first) {
+ // Remove the item before deleting it.
+ l->lv_first = item->li_next;
+ tv_clear(&item->li_tv);
+ xfree(item);
+ }
+ l->lv_len = 0;
+ l->lv_idx_item = NULL;
+ l->lv_last = NULL;
+ assert(l->lv_watch == NULL);
+}
+
+/// Free a list itself, ignoring items it contains
+///
+/// Ignores the reference count.
+///
+/// @param[in,out] l List to free.
+void tv_list_free_list(list_T *const l)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Remove the list from the list of lists for garbage collection.
+ if (l->lv_used_prev == NULL) {
+ gc_first_list = l->lv_used_next;
+ } else {
+ l->lv_used_prev->lv_used_next = l->lv_used_next;
+ }
+ if (l->lv_used_next != NULL) {
+ l->lv_used_next->lv_used_prev = l->lv_used_prev;
+ }
+ list_log(l, NULL, NULL, "freelist");
+
+ xfree(l);
+}
+
+/// Free a list, including all items it points to
+///
+/// Ignores the reference count. Does not do anything if
+/// tv_in_free_unref_items is true.
+///
+/// @param[in,out] l List to free.
+void tv_list_free(list_T *const l)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!tv_in_free_unref_items) {
+ tv_list_free_contents(l);
+ tv_list_free_list(l);
+ }
+}
+
+/// Unreference a list
+///
+/// Decrements the reference count and frees when it becomes zero or less.
+///
+/// @param[in,out] l List to unreference.
+void tv_list_unref(list_T *const l)
+{
+ if (l != NULL && --l->lv_refcount <= 0) {
+ tv_list_free(l);
+ }
+}
+
+//{{{2 Add/remove
+
+/// Remove items "item" to "item2" from list "l"
+///
+/// @warning Does not free the listitem or the value!
+///
+/// @param[out] l List to remove from.
+/// @param[in] item First item to remove.
+/// @param[in] item2 Last item to remove.
+void tv_list_drop_items(list_T *const l, listitem_T *const item,
+ listitem_T *const item2)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_log(l, item, item2, "drop");
+ // Notify watchers.
+ for (listitem_T *ip = item; ip != item2->li_next; ip = ip->li_next) {
+ l->lv_len--;
+ tv_list_watch_fix(l, ip);
+ }
+
+ if (item2->li_next == NULL) {
+ l->lv_last = item->li_prev;
+ } else {
+ item2->li_next->li_prev = item->li_prev;
+ }
+ if (item->li_prev == NULL) {
+ l->lv_first = item2->li_next;
+ } else {
+ item->li_prev->li_next = item2->li_next;
+ }
+ l->lv_idx_item = NULL;
+ list_log(l, l->lv_first, l->lv_last, "afterdrop");
+}
+
+/// Like tv_list_drop_items, but also frees all removed items
+void tv_list_remove_items(list_T *const l, listitem_T *const item,
+ listitem_T *const item2)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_log(l, item, item2, "remove");
+ tv_list_drop_items(l, item, item2);
+ for (listitem_T *li = item;;) {
+ tv_clear(TV_LIST_ITEM_TV(li));
+ listitem_T *const nli = li->li_next;
+ xfree(li);
+ if (li == item2) {
+ break;
+ }
+ li = nli;
+ }
+}
+
+/// Move items "item" to "item2" from list "l" to the end of the list "tgt_l"
+///
+/// @param[out] l List to move from.
+/// @param[in] item First item to move.
+/// @param[in] item2 Last item to move.
+/// @param[out] tgt_l List to move to.
+/// @param[in] cnt Number of items moved.
+void tv_list_move_items(list_T *const l, listitem_T *const item,
+ listitem_T *const item2, list_T *const tgt_l,
+ const int cnt)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_log(l, item, item2, "move");
+ tv_list_drop_items(l, item, item2);
+ item->li_prev = tgt_l->lv_last;
+ item2->li_next = NULL;
+ if (tgt_l->lv_last == NULL) {
+ tgt_l->lv_first = item;
+ } else {
+ tgt_l->lv_last->li_next = item;
+ }
+ tgt_l->lv_last = item2;
+ tgt_l->lv_len += cnt;
+ list_log(tgt_l, tgt_l->lv_first, tgt_l->lv_last, "movetgt");
+}
+
+/// Insert list item
+///
+/// @param[out] l List to insert to.
+/// @param[in,out] ni Item to insert.
+/// @param[in] item Item to insert before. If NULL, inserts at the end of the
+/// list.
+void tv_list_insert(list_T *const l, listitem_T *const ni,
+ listitem_T *const item)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
+{
+ if (item == NULL) {
+ // Append new item at end of list.
+ tv_list_append(l, ni);
+ } else {
+ // Insert new item before existing item.
+ ni->li_prev = item->li_prev;
+ ni->li_next = item;
+ if (item->li_prev == NULL) {
+ l->lv_first = ni;
+ l->lv_idx++;
+ } else {
+ item->li_prev->li_next = ni;
+ l->lv_idx_item = NULL;
+ }
+ item->li_prev = ni;
+ l->lv_len++;
+ list_log(l, ni, item, "insert");
+ }
+}
+
+/// Insert VimL value into a list
+///
+/// @param[out] l List to insert to.
+/// @param[in,out] tv Value to insert. Is copied (@see tv_copy()) to an
+/// allocated listitem_T and inserted.
+/// @param[in] item Item to insert before. If NULL, inserts at the end of the
+/// list.
+void tv_list_insert_tv(list_T *const l, typval_T *const tv,
+ listitem_T *const item)
+{
+ listitem_T *const ni = tv_list_item_alloc();
+
+ tv_copy(tv, &ni->li_tv);
+ tv_list_insert(l, ni, item);
+}
+
+/// Append item to the end of list
+///
+/// @param[out] l List to append to.
+/// @param[in,out] item Item to append.
+void tv_list_append(list_T *const l, listitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_log(l, item, NULL, "append");
+ if (l->lv_last == NULL) {
+ // empty list
+ l->lv_first = item;
+ l->lv_last = item;
+ item->li_prev = NULL;
+ } else {
+ l->lv_last->li_next = item;
+ item->li_prev = l->lv_last;
+ l->lv_last = item;
+ }
+ l->lv_len++;
+ item->li_next = NULL;
+}
+
+/// Append VimL value to the end of list
+///
+/// @param[out] l List to append to.
+/// @param[in,out] tv Value to append. Is copied (@see tv_copy()) to an
+/// allocated listitem_T.
+void tv_list_append_tv(list_T *const l, typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ listitem_T *const li = tv_list_item_alloc();
+ tv_copy(tv, TV_LIST_ITEM_TV(li));
+ tv_list_append(l, li);
+}
+
+/// Like tv_list_append_tv(), but tv is moved to a list
+///
+/// This means that it is no longer valid to use contents of the typval_T after
+/// function exits.
+void tv_list_append_owned_tv(list_T *const l, typval_T tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ listitem_T *const li = tv_list_item_alloc();
+ *TV_LIST_ITEM_TV(li) = tv;
+ tv_list_append(l, li);
+}
+
+/// Append a list to a list as one item
+///
+/// @param[out] l List to append to.
+/// @param[in,out] itemlist List to append. Reference count is increased.
+void tv_list_append_list(list_T *const l, list_T *const itemlist)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ tv_list_append_owned_tv(l, (typval_T) {
+ .v_type = VAR_LIST,
+ .v_lock = VAR_UNLOCKED,
+ .vval.v_list = itemlist,
+ });
+ tv_list_ref(itemlist);
+}
+
+/// Append a dictionary to a list
+///
+/// @param[out] l List to append to.
+/// @param[in,out] dict Dictionary to append. Reference count is increased.
+void tv_list_append_dict(list_T *const l, dict_T *const dict)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ tv_list_append_owned_tv(l, (typval_T) {
+ .v_type = VAR_DICT,
+ .v_lock = VAR_UNLOCKED,
+ .vval.v_dict = dict,
+ });
+ if (dict != NULL) {
+ dict->dv_refcount++;
+ }
+}
+
+/// Make a copy of "str" and append it as an item to list "l"
+///
+/// @param[out] l List to append to.
+/// @param[in] str String to append.
+/// @param[in] len Length of the appended string. May be -1, in this
+/// case string is considered to be usual zero-terminated
+/// string or NULL “empty†string.
+void tv_list_append_string(list_T *const l, const char *const str,
+ const ssize_t len)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ tv_list_append_owned_tv(l, (typval_T) {
+ .v_type = VAR_STRING,
+ .v_lock = VAR_UNLOCKED,
+ .vval.v_string = (str == NULL
+ ? NULL
+ : (len >= 0
+ ? xmemdupz(str, (size_t)len)
+ : xstrdup(str))),
+ });
+}
+
+/// Append given string to the list
+///
+/// Unlike list_append_string this function does not copy the string.
+///
+/// @param[out] l List to append to.
+/// @param[in] str String to append.
+void tv_list_append_allocated_string(list_T *const l, char *const str)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ tv_list_append_owned_tv(l, (typval_T) {
+ .v_type = VAR_STRING,
+ .v_lock = VAR_UNLOCKED,
+ .vval.v_string = (char_u *)str,
+ });
+}
+
+/// Append number to the list
+///
+/// @param[out] l List to append to.
+/// @param[in] n Number to append. Will be recorded in the allocated
+/// listitem_T.
+void tv_list_append_number(list_T *const l, const varnumber_T n)
+{
+ tv_list_append_owned_tv(l, (typval_T) {
+ .v_type = VAR_NUMBER,
+ .v_lock = VAR_UNLOCKED,
+ .vval.v_number = n,
+ });
+}
+
+//{{{2 Operations on the whole list
+
+/// Make a copy of list
+///
+/// @param[in] conv If non-NULL, then all internal strings will be converted.
+/// Only used when `deep` is true.
+/// @param[in] orig Original list to copy.
+/// @param[in] deep If false, then shallow copy will be done.
+/// @param[in] copyID See var_item_copy().
+///
+/// @return Copied list. May be NULL in case original list is NULL or some
+/// failure happens. The refcount of the new list is set to 1.
+list_T *tv_list_copy(const vimconv_T *const conv, list_T *const orig,
+ const bool deep, const int copyID)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (orig == NULL) {
+ return NULL;
+ }
+
+ list_T *copy = tv_list_alloc(tv_list_len(orig));
+ tv_list_ref(copy);
+ if (copyID != 0) {
+ // Do this before adding the items, because one of the items may
+ // refer back to this list.
+ orig->lv_copyID = copyID;
+ orig->lv_copylist = copy;
+ }
+ TV_LIST_ITER(orig, item, {
+ if (got_int) {
+ break;
+ }
+ listitem_T *const ni = tv_list_item_alloc();
+ if (deep) {
+ if (var_item_copy(conv, TV_LIST_ITEM_TV(item), TV_LIST_ITEM_TV(ni),
+ deep, copyID) == FAIL) {
+ xfree(ni);
+ goto tv_list_copy_error;
+ }
+ } else {
+ tv_copy(TV_LIST_ITEM_TV(item), TV_LIST_ITEM_TV(ni));
+ }
+ tv_list_append(copy, ni);
+ });
+
+ return copy;
+
+tv_list_copy_error:
+ tv_list_unref(copy);
+ return NULL;
+}
+
+/// Extend first list with the second
+///
+/// @param[out] l1 List to extend.
+/// @param[in] l2 List to extend with.
+/// @param[in] bef If not NULL, extends before this item.
+void tv_list_extend(list_T *const l1, list_T *const l2,
+ listitem_T *const bef)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ int todo = tv_list_len(l2);
+ listitem_T *const befbef = (bef == NULL ? NULL : bef->li_prev);
+ listitem_T *const saved_next = (befbef == NULL ? NULL : befbef->li_next);
+ // We also quit the loop when we have inserted the original item count of
+ // the list, avoid a hang when we extend a list with itself.
+ for (listitem_T *item = tv_list_first(l2)
+ ; item != NULL && todo--
+ ; item = (item == befbef ? saved_next : item->li_next)) {
+ tv_list_insert_tv(l1, TV_LIST_ITEM_TV(item), bef);
+ }
+}
+
+/// Concatenate lists into a new list
+///
+/// @param[in] l1 First list.
+/// @param[in] l2 Second list.
+/// @param[out] ret_tv Location where new list is saved.
+///
+/// @return OK or FAIL.
+int tv_list_concat(list_T *const l1, list_T *const l2, typval_T *const tv)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ list_T *l;
+
+ tv->v_type = VAR_LIST;
+
+ if (l1 == NULL && l2 == NULL) {
+ l = NULL;
+ } else if (l1 == NULL) {
+ l = tv_list_copy(NULL, l2, false, 0);
+ } else {
+ l = tv_list_copy(NULL, l1, false, 0);
+ if (l != NULL && l2 != NULL) {
+ tv_list_extend(l, l2, NULL);
+ }
+ }
+ if (l == NULL && !(l1 == NULL && l2 == NULL)) {
+ return FAIL;
+ }
+
+ tv->vval.v_list = l;
+ return OK;
+}
+
+typedef struct {
+ char_u *s;
+ char_u *tofree;
+} Join;
+
+/// Join list into a string, helper function
+///
+/// @param[out] gap Garray where result will be saved.
+/// @param[in] l List to join.
+/// @param[in] sep Used separator.
+/// @param[in] join_gap Garray to keep each list item string.
+///
+/// @return OK in case of success, FAIL otherwise.
+static int list_join_inner(garray_T *const gap, list_T *const l,
+ const char *const sep, garray_T *const join_gap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t sumlen = 0;
+ bool first = true;
+
+ // Stringify each item in the list.
+ TV_LIST_ITER(l, item, {
+ if (got_int) {
+ break;
+ }
+ char *s;
+ size_t len;
+ s = encode_tv2echo(TV_LIST_ITEM_TV(item), &len);
+ if (s == NULL) {
+ return FAIL;
+ }
+
+ sumlen += len;
+
+ Join *const p = GA_APPEND_VIA_PTR(Join, join_gap);
+ p->tofree = p->s = (char_u *)s;
+
+ line_breakcheck();
+ });
+
+ // Allocate result buffer with its total size, avoid re-allocation and
+ // multiple copy operations. Add 2 for a tailing ']' and NUL.
+ if (join_gap->ga_len >= 2) {
+ sumlen += strlen(sep) * (size_t)(join_gap->ga_len - 1);
+ }
+ ga_grow(gap, (int)sumlen + 2);
+
+ for (int i = 0; i < join_gap->ga_len && !got_int; i++) {
+ if (first) {
+ first = false;
+ } else {
+ ga_concat(gap, (const char_u *)sep);
+ }
+ const Join *const p = ((const Join *)join_gap->ga_data) + i;
+
+ if (p->s != NULL) {
+ ga_concat(gap, p->s);
+ }
+ line_breakcheck();
+ }
+
+ return OK;
+}
+
+/// Join list into a string using given separator
+///
+/// @param[out] gap Garray where result will be saved.
+/// @param[in] l Joined list.
+/// @param[in] sep Separator.
+///
+/// @return OK in case of success, FAIL otherwise.
+int tv_list_join(garray_T *const gap, list_T *const l, const char *const sep)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ if (!tv_list_len(l)) {
+ return OK;
+ }
+
+ garray_T join_ga;
+ int retval;
+
+ ga_init(&join_ga, (int)sizeof(Join), tv_list_len(l));
+ retval = list_join_inner(gap, l, sep, &join_ga);
+
+#define FREE_JOIN_TOFREE(join) xfree((join)->tofree)
+ GA_DEEP_CLEAR(&join_ga, Join, FREE_JOIN_TOFREE);
+#undef FREE_JOIN_TOFREE
+
+ return retval;
+}
+
+/// Chech whether two lists are equal
+///
+/// @param[in] l1 First list to compare.
+/// @param[in] l2 Second list to compare.
+/// @param[in] ic True if case is to be ignored.
+/// @param[in] recursive True when used recursively.
+///
+/// @return True if lists are equal, false otherwise.
+bool tv_list_equal(list_T *const l1, list_T *const l2, const bool ic,
+ const bool recursive)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (l1 == l2) {
+ return true;
+ }
+ if (l1 == NULL || l2 == NULL) {
+ return false;
+ }
+ if (tv_list_len(l1) != tv_list_len(l2)) {
+ return false;
+ }
+
+ listitem_T *item1 = tv_list_first(l1);
+ listitem_T *item2 = tv_list_first(l2);
+ for (; item1 != NULL && item2 != NULL
+ ; (item1 = TV_LIST_ITEM_NEXT(l1, item1),
+ item2 = TV_LIST_ITEM_NEXT(l2, item2))) {
+ if (!tv_equal(TV_LIST_ITEM_TV(item1), TV_LIST_ITEM_TV(item2), ic,
+ recursive)) {
+ return false;
+ }
+ }
+ assert(item1 == NULL && item2 == NULL);
+ return true;
+}
+
+/// Reverse list in-place
+///
+/// @param[in,out] l List to reverse.
+void tv_list_reverse(list_T *const l)
+{
+ if (tv_list_len(l) <= 1) {
+ return;
+ }
+ list_log(l, NULL, NULL, "reverse");
+#define SWAP(a, b) \
+ do { \
+ tmp = a; \
+ a = b; \
+ b = tmp; \
+ } while (0)
+ listitem_T *tmp;
+
+ SWAP(l->lv_first, l->lv_last);
+ for (listitem_T *li = l->lv_first; li != NULL; li = li->li_next) {
+ SWAP(li->li_next, li->li_prev);
+ }
+#undef SWAP
+
+ l->lv_idx = l->lv_len - l->lv_idx - 1;
+}
+
+// FIXME Add unit tests for tv_list_item_sort().
+
+/// Sort list using libc qsort
+///
+/// @param[in,out] l List to sort, will be sorted in-place.
+/// @param ptrs Preallocated array of items to sort, must have at least
+/// tv_list_len(l) entries. Should not be initialized.
+/// @param[in] item_compare_func Function used to compare list items.
+/// @param errp Location where information about whether error occurred is
+/// saved by item_compare_func. If boolean there appears to be
+/// true list will not be modified. Must be initialized to false
+/// by the caller.
+void tv_list_item_sort(list_T *const l, ListSortItem *const ptrs,
+ const ListSorter item_compare_func,
+ bool *errp)
+ FUNC_ATTR_NONNULL_ARG(3, 4)
+{
+ const int len = tv_list_len(l);
+ if (len <= 1) {
+ return;
+ }
+ list_log(l, NULL, NULL, "sort");
+ int i = 0;
+ TV_LIST_ITER(l, li, {
+ ptrs[i].item = li;
+ ptrs[i].idx = i;
+ i++;
+ });
+ // Sort the array with item pointers.
+ qsort(ptrs, (size_t)len, sizeof(ListSortItem), item_compare_func);
+ if (!(*errp)) {
+ // Clear the list and append the items in the sorted order.
+ l->lv_first = NULL;
+ l->lv_last = NULL;
+ l->lv_idx_item = NULL;
+ l->lv_len = 0;
+ for (i = 0; i < len; i++) {
+ tv_list_append(l, ptrs[i].item);
+ }
+ }
+}
+
+//{{{2 Indexing/searching
+
+/// Locate item with a given index in a list and return it
+///
+/// @param[in] l List to index.
+/// @param[in] n Index. Negative index is counted from the end, -1 is the last
+/// item.
+///
+/// @return Item at the given index or NULL if `n` is out of range.
+listitem_T *tv_list_find(list_T *const l, int n)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ STATIC_ASSERT(sizeof(n) == sizeof(l->lv_idx),
+ "n and lv_idx sizes do not match");
+ if (l == NULL) {
+ return NULL;
+ }
+
+ n = tv_list_uidx(l, n);
+ if (n == -1) {
+ return NULL;
+ }
+
+ int idx;
+ listitem_T *item;
+
+ // When there is a cached index may start search from there.
+ if (l->lv_idx_item != NULL) {
+ if (n < l->lv_idx / 2) {
+ // Closest to the start of the list.
+ item = l->lv_first;
+ idx = 0;
+ } else if (n > (l->lv_idx + l->lv_len) / 2) {
+ // Closest to the end of the list.
+ item = l->lv_last;
+ idx = l->lv_len - 1;
+ } else {
+ // Closest to the cached index.
+ item = l->lv_idx_item;
+ idx = l->lv_idx;
+ }
+ } else {
+ if (n < l->lv_len / 2) {
+ // Closest to the start of the list.
+ item = l->lv_first;
+ idx = 0;
+ } else {
+ // Closest to the end of the list.
+ item = l->lv_last;
+ idx = l->lv_len - 1;
+ }
+ }
+
+ while (n > idx) {
+ // Search forward.
+ item = item->li_next;
+ idx++;
+ }
+ while (n < idx) {
+ // Search backward.
+ item = item->li_prev;
+ idx--;
+ }
+
+ assert(idx == n);
+ // Cache the used index.
+ l->lv_idx = idx;
+ l->lv_idx_item = item;
+ list_log(l, l->lv_idx_item, (void *)(uintptr_t)l->lv_idx, "find");
+
+ return item;
+}
+
+/// Get list item l[n] as a number
+///
+/// @param[in] l List to index.
+/// @param[in] n Index in a list.
+/// @param[out] ret_error Location where 1 will be saved if index was not
+/// found. May be NULL. If everything is OK,
+/// `*ret_error` is not touched.
+///
+/// @return Integer value at the given index or -1.
+varnumber_T tv_list_find_nr(list_T *const l, const int n, bool *const ret_error)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const listitem_T *const li = tv_list_find(l, n);
+ if (li == NULL) {
+ if (ret_error != NULL) {
+ *ret_error = true;
+ }
+ return -1;
+ }
+ return tv_get_number_chk(TV_LIST_ITEM_TV(li), ret_error);
+}
+
+/// Get list item l[n] as a string
+///
+/// @param[in] l List to index.
+/// @param[in] n Index in a list.
+///
+/// @return List item string value or NULL in case of error.
+const char *tv_list_find_str(list_T *const l, const int n)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const listitem_T *const li = tv_list_find(l, n);
+ if (li == NULL) {
+ EMSG2(_(e_listidx), (int64_t)n);
+ return NULL;
+ }
+ return tv_get_string(TV_LIST_ITEM_TV(li));
+}
+
+/// Locate item in a list and return its index
+///
+/// @param[in] l List to search.
+/// @param[in] item Item to search for.
+///
+/// @return Index of an item or -1 if item is not in the list.
+long tv_list_idx_of_item(const list_T *const l, const listitem_T *const item)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
+{
+ if (l == NULL) {
+ return -1;
+ }
+ int idx = 0;
+ TV_LIST_ITER_CONST(l, li, {
+ if (li == item) {
+ return idx;
+ }
+ idx++;
+ });
+ return -1;
+}
+
+//{{{1 Dictionaries
+//{{{2 Dictionary watchers
+
+/// Perform all necessary cleanup for a `DictWatcher` instance
+///
+/// @param watcher Watcher to free.
+static void tv_dict_watcher_free(DictWatcher *watcher)
+ FUNC_ATTR_NONNULL_ALL
+{
+ callback_free(&watcher->callback);
+ xfree(watcher->key_pattern);
+ xfree(watcher);
+}
+
+/// Add watcher to a dictionary
+///
+/// @param[in] dict Dictionary to add watcher to.
+/// @param[in] key_pattern Pattern to watch for.
+/// @param[in] key_pattern_len Key pattern length.
+/// @param callback Function to be called on events.
+void tv_dict_watcher_add(dict_T *const dict, const char *const key_pattern,
+ const size_t key_pattern_len, Callback callback)
+ FUNC_ATTR_NONNULL_ARG(2)
+{
+ if (dict == NULL) {
+ return;
+ }
+ DictWatcher *const watcher = xmalloc(sizeof(DictWatcher));
+ watcher->key_pattern = xmemdupz(key_pattern, key_pattern_len);
+ watcher->key_pattern_len = key_pattern_len;
+ watcher->callback = callback;
+ watcher->busy = false;
+ QUEUE_INSERT_TAIL(&dict->watchers, &watcher->node);
+}
+
+/// Check whether two callbacks are equal
+///
+/// @param[in] cb1 First callback to check.
+/// @param[in] cb2 Second callback to check.
+///
+/// @return True if they are equal, false otherwise.
+bool tv_callback_equal(const Callback *cb1, const Callback *cb2)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (cb1->type != cb2->type) {
+ return false;
+ }
+ switch (cb1->type) {
+ case kCallbackFuncref: {
+ return STRCMP(cb1->data.funcref, cb2->data.funcref) == 0;
+ }
+ case kCallbackPartial: {
+ // FIXME: this is inconsistent with tv_equal but is needed for precision
+ // maybe change dictwatcheradd to return a watcher id instead?
+ return cb1->data.partial == cb2->data.partial;
+ }
+ case kCallbackNone: {
+ return true;
+ }
+ }
+ abort();
+ return false;
+}
+
+/// Unref/free callback
+void callback_free(Callback *callback)
+ FUNC_ATTR_NONNULL_ALL
+{
+ switch (callback->type) {
+ case kCallbackFuncref: {
+ func_unref(callback->data.funcref);
+ xfree(callback->data.funcref);
+ break;
+ }
+ case kCallbackPartial: {
+ partial_unref(callback->data.partial);
+ break;
+ }
+ case kCallbackNone: {
+ break;
+ }
+ }
+ callback->type = kCallbackNone;
+}
+
+/// Remove watcher from a dictionary
+///
+/// @param dict Dictionary to remove watcher from.
+/// @param[in] key_pattern Pattern to remove watcher for.
+/// @param[in] key_pattern_len Pattern length.
+/// @param callback Callback to remove watcher for.
+///
+/// @return True on success, false if relevant watcher was not found.
+bool tv_dict_watcher_remove(dict_T *const dict, const char *const key_pattern,
+ const size_t key_pattern_len,
+ Callback callback)
+ FUNC_ATTR_NONNULL_ARG(2)
+{
+ if (dict == NULL) {
+ return false;
+ }
+
+ QUEUE *w = NULL;
+ DictWatcher *watcher = NULL;
+ bool matched = false;
+ QUEUE_FOREACH(w, &dict->watchers) {
+ watcher = tv_dict_watcher_node_data(w);
+ if (tv_callback_equal(&watcher->callback, &callback)
+ && watcher->key_pattern_len == key_pattern_len
+ && memcmp(watcher->key_pattern, key_pattern, key_pattern_len) == 0) {
+ matched = true;
+ break;
+ }
+ }
+
+ if (!matched) {
+ return false;
+ }
+
+ QUEUE_REMOVE(w);
+ tv_dict_watcher_free(watcher);
+ return true;
+}
+
+/// Test if `key` matches with with `watcher->key_pattern`
+///
+/// @param[in] watcher Watcher to check key pattern from.
+/// @param[in] key Key to check.
+///
+/// @return true if key matches, false otherwise.
+static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
+{
+ // For now only allow very simple globbing in key patterns: a '*' at the end
+ // of the string means it should match everything up to the '*' instead of the
+ // whole string.
+ const size_t len = watcher->key_pattern_len;
+ if (len && watcher->key_pattern[len - 1] == '*') {
+ return strncmp(key, watcher->key_pattern, len - 1) == 0;
+ } else {
+ return strcmp(key, watcher->key_pattern) == 0;
+ }
+}
+
+/// Send a change notification to all dictionary watchers that match given key
+///
+/// @param[in] dict Dictionary which was modified.
+/// @param[in] key Key which was modified.
+/// @param[in] newtv New key value.
+/// @param[in] oldtv Old key value.
+void tv_dict_watcher_notify(dict_T *const dict, const char *const key,
+ typval_T *const newtv, typval_T *const oldtv)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
+{
+ typval_T argv[3];
+
+ argv[0].v_type = VAR_DICT;
+ argv[0].v_lock = VAR_UNLOCKED;
+ argv[0].vval.v_dict = dict;
+ argv[1].v_type = VAR_STRING;
+ argv[1].v_lock = VAR_UNLOCKED;
+ argv[1].vval.v_string = (char_u *)xstrdup(key);
+ argv[2].v_type = VAR_DICT;
+ argv[2].v_lock = VAR_UNLOCKED;
+ argv[2].vval.v_dict = tv_dict_alloc();
+ argv[2].vval.v_dict->dv_refcount++;
+
+ if (newtv) {
+ dictitem_T *const v = tv_dict_item_alloc_len(S_LEN("new"));
+ tv_copy(newtv, &v->di_tv);
+ tv_dict_add(argv[2].vval.v_dict, v);
+ }
+
+ if (oldtv) {
+ dictitem_T *const v = tv_dict_item_alloc_len(S_LEN("old"));
+ tv_copy(oldtv, &v->di_tv);
+ tv_dict_add(argv[2].vval.v_dict, v);
+ }
+
+ typval_T rettv;
+
+ QUEUE *w;
+ QUEUE_FOREACH(w, &dict->watchers) {
+ DictWatcher *watcher = tv_dict_watcher_node_data(w);
+ if (!watcher->busy && tv_dict_watcher_matches(watcher, key)) {
+ rettv = TV_INITIAL_VALUE;
+ watcher->busy = true;
+ callback_call(&watcher->callback, 3, argv, &rettv);
+ watcher->busy = false;
+ tv_clear(&rettv);
+ }
+ }
+
+ for (size_t i = 1; i < ARRAY_SIZE(argv); i++) {
+ tv_clear(argv + i);
+ }
+}
+
+//{{{2 Dictionary item
+
+/// Allocate a dictionary item
+///
+/// @note that the value of the item (->di_tv) still needs to be initialized.
+///
+/// @param[in] key Key, is copied to the new item.
+/// @param[in] key_len Key length.
+///
+/// @return [allocated] new dictionary item.
+dictitem_T *tv_dict_item_alloc_len(const char *const key, const size_t key_len)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_MALLOC
+{
+ dictitem_T *const di = xmalloc(offsetof(dictitem_T, di_key) + key_len + 1);
+ memcpy(di->di_key, key, key_len);
+ di->di_key[key_len] = NUL;
+ di->di_flags = DI_FLAGS_ALLOC;
+ return di;
+}
+
+/// Allocate a dictionary item
+///
+/// @note that the value of the item (->di_tv) still needs to be initialized.
+///
+/// @param[in] key Key, is copied to the new item.
+///
+/// @return [allocated] new dictionary item.
+dictitem_T *tv_dict_item_alloc(const char *const key)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_MALLOC
+{
+ return tv_dict_item_alloc_len(key, strlen(key));
+}
+
+/// Free a dictionary item, also clearing the value
+///
+/// @param item Item to free.
+void tv_dict_item_free(dictitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ tv_clear(&item->di_tv);
+ if (item->di_flags & DI_FLAGS_ALLOC) {
+ xfree(item);
+ }
+}
+
+/// Make a copy of a dictionary item
+///
+/// @param[in] di Item to copy.
+///
+/// @return [allocated] new dictionary item.
+static dictitem_T *tv_dict_item_copy(dictitem_T *const di)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ dictitem_T *const new_di = tv_dict_item_alloc((const char *)di->di_key);
+ tv_copy(&di->di_tv, &new_di->di_tv);
+ return new_di;
+}
+
+/// Remove item from dictionary and free it
+///
+/// @param dict Dictionary to remove item from.
+/// @param item Item to remove.
+void tv_dict_item_remove(dict_T *const dict, dictitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ hashitem_T *const hi = hash_find(&dict->dv_hashtab, item->di_key);
+ if (HASHITEM_EMPTY(hi)) {
+ emsgf(_(e_intern2), "tv_dict_item_remove()");
+ } else {
+ hash_remove(&dict->dv_hashtab, hi);
+ }
+ tv_dict_item_free(item);
+}
+
+//{{{2 Alloc/free
+
+/// Allocate an empty dictionary
+///
+/// @return [allocated] new dictionary.
+dict_T *tv_dict_alloc(void)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ dict_T *const d = xmalloc(sizeof(dict_T));
+
+ // Add the dict to the list of dicts for garbage collection.
+ if (gc_first_dict != NULL) {
+ gc_first_dict->dv_used_prev = d;
+ }
+ d->dv_used_next = gc_first_dict;
+ d->dv_used_prev = NULL;
+ gc_first_dict = d;
+
+ hash_init(&d->dv_hashtab);
+ d->dv_lock = VAR_UNLOCKED;
+ d->dv_scope = VAR_NO_SCOPE;
+ d->dv_refcount = 0;
+ d->dv_copyID = 0;
+ QUEUE_INIT(&d->watchers);
+
+ return d;
+}
+
+/// Free items contained in a dictionary
+///
+/// @param[in,out] d Dictionary to clear.
+void tv_dict_free_contents(dict_T *const d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Lock the hashtab, we don't want it to resize while freeing items.
+ hash_lock(&d->dv_hashtab);
+ assert(d->dv_hashtab.ht_locked > 0);
+ HASHTAB_ITER(&d->dv_hashtab, hi, {
+ // Remove the item before deleting it, just in case there is
+ // something recursive causing trouble.
+ dictitem_T *const di = TV_DICT_HI2DI(hi);
+ hash_remove(&d->dv_hashtab, hi);
+ tv_dict_item_free(di);
+ });
+
+ while (!QUEUE_EMPTY(&d->watchers)) {
+ QUEUE *w = QUEUE_HEAD(&d->watchers);
+ QUEUE_REMOVE(w);
+ DictWatcher *watcher = tv_dict_watcher_node_data(w);
+ tv_dict_watcher_free(watcher);
+ }
+
+ hash_clear(&d->dv_hashtab);
+ d->dv_hashtab.ht_locked--;
+ hash_init(&d->dv_hashtab);
+}
+
+/// Free a dictionary itself, ignoring items it contains
+///
+/// Ignores the reference count.
+///
+/// @param[in,out] d Dictionary to free.
+void tv_dict_free_dict(dict_T *const d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Remove the dict from the list of dicts for garbage collection.
+ if (d->dv_used_prev == NULL) {
+ gc_first_dict = d->dv_used_next;
+ } else {
+ d->dv_used_prev->dv_used_next = d->dv_used_next;
+ }
+ if (d->dv_used_next != NULL) {
+ d->dv_used_next->dv_used_prev = d->dv_used_prev;
+ }
+
+ xfree(d);
+}
+
+/// Free a dictionary, including all items it contains
+///
+/// Ignores the reference count.
+///
+/// @param d Dictionary to free.
+void tv_dict_free(dict_T *const d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!tv_in_free_unref_items) {
+ tv_dict_free_contents(d);
+ tv_dict_free_dict(d);
+ }
+}
+
+
+/// Unreference a dictionary
+///
+/// Decrements the reference count and frees dictionary when it becomes zero.
+///
+/// @param[in] d Dictionary to operate on.
+void tv_dict_unref(dict_T *const d)
+{
+ if (d != NULL && --d->dv_refcount <= 0) {
+ tv_dict_free(d);
+ }
+}
+
+//{{{2 Indexing/searching
+
+/// Find item in dictionary
+///
+/// @param[in] d Dictionary to check.
+/// @param[in] key Dictionary key.
+/// @param[in] len Key length. If negative, then strlen(key) is used.
+///
+/// @return found item or NULL if nothing was found.
+dictitem_T *tv_dict_find(const dict_T *const d, const char *const key,
+ const ptrdiff_t len)
+ FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (d == NULL) {
+ return NULL;
+ }
+ hashitem_T *const hi = (len < 0
+ ? hash_find(&d->dv_hashtab, (const char_u *)key)
+ : hash_find_len(&d->dv_hashtab, key, (size_t)len));
+ if (HASHITEM_EMPTY(hi)) {
+ return NULL;
+ }
+ return TV_DICT_HI2DI(hi);
+}
+
+/// Get a number item from a dictionary
+///
+/// Returns 0 if the entry does not exist.
+///
+/// @param[in] d Dictionary to get item from.
+/// @param[in] key Key to find in dictionary.
+///
+/// @return Dictionary item.
+varnumber_T tv_dict_get_number(const dict_T *const d, const char *const key)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ dictitem_T *const di = tv_dict_find(d, key, -1);
+ if (di == NULL) {
+ return 0;
+ }
+ return tv_get_number(&di->di_tv);
+}
+
+/// Get a string item from a dictionary
+///
+/// @param[in] d Dictionary to get item from.
+/// @param[in] key Dictionary key.
+/// @param[in] save If true, returned string will be placed in the allocated
+/// memory.
+///
+/// @return NULL if key does not exist, empty string in case of type error,
+/// string item value otherwise. If returned value is not NULL, it may
+/// be allocated depending on `save` argument.
+char *tv_dict_get_string(const dict_T *const d, const char *const key,
+ const bool save)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static char numbuf[NUMBUFLEN];
+ const char *const s = tv_dict_get_string_buf(d, key, numbuf);
+ if (save && s != NULL) {
+ return xstrdup(s);
+ }
+ return (char *)s;
+}
+
+/// Get a string item from a dictionary
+///
+/// @param[in] d Dictionary to get item from.
+/// @param[in] key Dictionary key.
+/// @param[in] numbuf Buffer for non-string items converted to strings, at
+/// least of #NUMBUFLEN length.
+///
+/// @return NULL if key does not exist, empty string in case of type error,
+/// string item value otherwise.
+const char *tv_dict_get_string_buf(const dict_T *const d, const char *const key,
+ char *const numbuf)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const dictitem_T *const di = tv_dict_find(d, key, -1);
+ if (di == NULL) {
+ return NULL;
+ }
+ return tv_get_string_buf(&di->di_tv, numbuf);
+}
+
+/// Get a string item from a dictionary
+///
+/// @param[in] d Dictionary to get item from.
+/// @param[in] key Dictionary key.
+/// @param[in] key_len Key length.
+/// @param[in] numbuf Buffer for non-string items converted to strings, at
+/// least of #NUMBUFLEN length.
+/// @param[in] def Default return when key does not exist.
+///
+/// @return `def` when key does not exist,
+/// NULL in case of type error,
+/// string item value in case of success.
+const char *tv_dict_get_string_buf_chk(const dict_T *const d,
+ const char *const key,
+ const ptrdiff_t key_len,
+ char *const numbuf,
+ const char *const def)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const dictitem_T *const di = tv_dict_find(d, key, key_len);
+ if (di == NULL) {
+ return def;
+ }
+ return tv_get_string_buf_chk(&di->di_tv, numbuf);
+}
+
+/// Get a function from a dictionary
+///
+/// @param[in] d Dictionary to get callback from.
+/// @param[in] key Dictionary key.
+/// @param[in] key_len Key length, may be -1 to use strlen().
+/// @param[out] result The address where a pointer to the wanted callback
+/// will be left.
+///
+/// @return true/false on success/failure.
+bool tv_dict_get_callback(dict_T *const d,
+ const char *const key, const ptrdiff_t key_len,
+ Callback *const result)
+ FUNC_ATTR_NONNULL_ARG(2, 4) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ result->type = kCallbackNone;
+
+ dictitem_T *const di = tv_dict_find(d, key, key_len);
+
+ if (di == NULL) {
+ return true;
+ }
+
+ if (!tv_is_func(di->di_tv) && di->di_tv.v_type != VAR_STRING) {
+ EMSG(_("E6000: Argument is not a function or function name"));
+ return false;
+ }
+
+ typval_T tv;
+ tv_copy(&di->di_tv, &tv);
+ set_selfdict(&tv, d);
+ const bool res = callback_from_typval(result, &tv);
+ tv_clear(&tv);
+ return res;
+}
+
+//{{{2 dict_add*
+
+/// Add item to dictionary
+///
+/// @param[out] d Dictionary to add to.
+/// @param[in] item Item to add.
+///
+/// @return FAIL if key already exists.
+int tv_dict_add(dict_T *const d, dictitem_T *const item)
+ FUNC_ATTR_NONNULL_ALL
+{
+ return hash_add(&d->dv_hashtab, item->di_key);
+}
+
+/// Add a list entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param list List to add. Will have reference count incremented.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_list(dict_T *const d, const char *const key,
+ const size_t key_len, list_T *const list)
+ FUNC_ATTR_NONNULL_ALL
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_LIST;
+ item->di_tv.vval.v_list = list;
+ tv_list_ref(list);
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Add a dictionary entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param dict Dictionary to add. Will have reference count incremented.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_dict(dict_T *const d, const char *const key,
+ const size_t key_len, dict_T *const dict)
+ FUNC_ATTR_NONNULL_ALL
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_DICT;
+ item->di_tv.vval.v_dict = dict;
+ dict->dv_refcount++;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Add a number entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] nr Number to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_nr(dict_T *const d, const char *const key,
+ const size_t key_len, const varnumber_T nr)
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_NUMBER;
+ item->di_tv.vval.v_number = nr;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Add a special entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] val SpecialVarValue to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_special(dict_T *const d, const char *const key,
+ const size_t key_len, SpecialVarValue val)
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_SPECIAL;
+ item->di_tv.vval.v_special = val;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Add a string entry to dictionary
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] val String to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_str(dict_T *const d,
+ const char *const key, const size_t key_len,
+ const char *const val)
+ FUNC_ATTR_NONNULL_ALL
+{
+ return tv_dict_add_allocated_str(d, key, key_len, xstrdup(val));
+}
+
+/// Add a string entry to dictionary
+///
+/// Unlike tv_dict_add_str() saves val to the new dictionary item in place of
+/// creating a new copy.
+///
+/// @warning String will be freed even in case addition fails.
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] val String to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_allocated_str(dict_T *const d,
+ const char *const key, const size_t key_len,
+ char *const val)
+ FUNC_ATTR_NONNULL_ALL
+{
+ dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
+
+ item->di_tv.v_lock = VAR_UNLOCKED;
+ item->di_tv.v_type = VAR_STRING;
+ item->di_tv.vval.v_string = (char_u *)val;
+ if (tv_dict_add(d, item) == FAIL) {
+ tv_dict_item_free(item);
+ return FAIL;
+ }
+ return OK;
+}
+
+//{{{2 Operations on the whole dict
+
+/// Clear all the keys of a Dictionary. "d" remains a valid empty Dictionary.
+///
+/// @param d The Dictionary to clear
+void tv_dict_clear(dict_T *const d)
+ FUNC_ATTR_NONNULL_ALL
+{
+ hash_lock(&d->dv_hashtab);
+ assert(d->dv_hashtab.ht_locked > 0);
+
+ HASHTAB_ITER(&d->dv_hashtab, hi, {
+ tv_dict_item_free(TV_DICT_HI2DI(hi));
+ hash_remove(&d->dv_hashtab, hi);
+ });
+
+ hash_unlock(&d->dv_hashtab);
+}
+
+/// Extend dictionary with items from another dictionary
+///
+/// @param d1 Dictionary to extend.
+/// @param[in] d2 Dictionary to extend with.
+/// @param[in] action "error", "force", "keep":
+///
+/// e*, including "error": duplicate key gives an error.
+/// f*, including "force": duplicate d2 keys override d1.
+/// 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
+{
+ const bool watched = tv_dict_is_watched(d1);
+ const char *const arg_errmsg = _("extend() argument");
+ const size_t arg_errmsg_len = strlen(arg_errmsg);
+
+ TV_DICT_ITER(d2, di2, {
+ dictitem_T *const di1 = tv_dict_find(d1, (const char *)di2->di_key, -1);
+ if (d1->dv_scope != VAR_NO_SCOPE) {
+ // Disallow replacing a builtin function in l: and g:.
+ // Check the key to be valid when adding to any scope.
+ if (d1->dv_scope == VAR_DEF_SCOPE
+ && tv_is_func(di2->di_tv)
+ && !var_check_func_name((const char *)di2->di_key, di1 == NULL)) {
+ break;
+ }
+ if (!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);
+ }
+ } else if (*action == 'e') {
+ emsgf(_("E737: Key already exists: %s"), di2->di_key);
+ break;
+ } else if (*action == 'f' && di2 != di1) {
+ typval_T oldtv;
+
+ if (tv_check_lock(di1->di_tv.v_lock, arg_errmsg, arg_errmsg_len)
+ || var_check_ro(di1->di_flags, arg_errmsg, arg_errmsg_len)) {
+ break;
+ }
+
+ if (watched) {
+ tv_copy(&di1->di_tv, &oldtv);
+ }
+
+ tv_clear(&di1->di_tv);
+ tv_copy(&di2->di_tv, &di1->di_tv);
+
+ if (watched) {
+ tv_dict_watcher_notify(d1, (const char *)di1->di_key, &di1->di_tv,
+ &oldtv);
+ tv_clear(&oldtv);
+ }
+ }
+ });
+}
+
+/// Compare two dictionaries
+///
+/// @param[in] d1 First dictionary.
+/// @param[in] d2 Second dictionary.
+/// @param[in] ic True if case is to be ignored.
+/// @param[in] recursive True when used recursively.
+bool tv_dict_equal(dict_T *const d1, dict_T *const d2,
+ const bool ic, const bool recursive)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (d1 == d2) {
+ return true;
+ }
+ if (d1 == NULL || d2 == NULL) {
+ return false;
+ }
+ if (tv_dict_len(d1) != tv_dict_len(d2)) {
+ return false;
+ }
+
+ TV_DICT_ITER(d1, di1, {
+ dictitem_T *const di2 = tv_dict_find(d2, (const char *)di1->di_key, -1);
+ if (di2 == NULL) {
+ return false;
+ }
+ if (!tv_equal(&di1->di_tv, &di2->di_tv, ic, recursive)) {
+ return false;
+ }
+ });
+ return true;
+}
+
+/// Make a copy of dictionary
+///
+/// @param[in] conv If non-NULL, then all internal strings will be converted.
+/// @param[in] orig Original dictionary to copy.
+/// @param[in] deep If false, then shallow copy will be done.
+/// @param[in] copyID See var_item_copy().
+///
+/// @return Copied dictionary. May be NULL in case original dictionary is NULL
+/// or some failure happens. The refcount of the new dictionary is set
+/// to 1.
+dict_T *tv_dict_copy(const vimconv_T *const conv,
+ dict_T *const orig,
+ const bool deep,
+ const int copyID)
+{
+ if (orig == NULL) {
+ return NULL;
+ }
+
+ dict_T *copy = tv_dict_alloc();
+ if (copyID != 0) {
+ orig->dv_copyID = copyID;
+ orig->dv_copydict = copy;
+ }
+ TV_DICT_ITER(orig, di, {
+ if (got_int) {
+ break;
+ }
+ dictitem_T *new_di;
+ if (conv == NULL || conv->vc_type == CONV_NONE) {
+ new_di = tv_dict_item_alloc((const char *)di->di_key);
+ } else {
+ size_t len = STRLEN(di->di_key);
+ char *const key = (char *)string_convert(conv, di->di_key, &len);
+ if (key == NULL) {
+ new_di = tv_dict_item_alloc_len((const char *)di->di_key, len);
+ } else {
+ new_di = tv_dict_item_alloc_len(key, len);
+ xfree(key);
+ }
+ }
+ if (deep) {
+ if (var_item_copy(conv, &di->di_tv, &new_di->di_tv, deep,
+ copyID) == FAIL) {
+ xfree(new_di);
+ break;
+ }
+ } else {
+ tv_copy(&di->di_tv, &new_di->di_tv);
+ }
+ if (tv_dict_add(copy, new_di) == FAIL) {
+ tv_dict_item_free(new_di);
+ break;
+ }
+ });
+
+ copy->dv_refcount++;
+ if (got_int) {
+ tv_dict_unref(copy);
+ copy = NULL;
+ }
+
+ return copy;
+}
+
+/// Set all existing keys in "dict" as read-only.
+///
+/// This does not protect against adding new keys to the Dictionary.
+///
+/// @param dict The dict whose keys should be frozen.
+void tv_dict_set_keys_readonly(dict_T *const dict)
+ FUNC_ATTR_NONNULL_ALL
+{
+ TV_DICT_ITER(dict, di, {
+ di->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
+ });
+}
+
+//{{{1 Generic typval operations
+//{{{2 Init/alloc/clear
+//{{{3 Alloc
+
+/// Allocate an empty list for a return value
+///
+/// Also sets reference count.
+///
+/// @param[out] ret_tv Structure where list is saved.
+/// @param[in] len Expected number of items to be populated before list
+/// becomes accessible from VimL. It is still valid to
+/// underpopulate a list, value only controls how many elements
+/// will be allocated in advance. @see ListLenSpecials.
+///
+/// @return [allocated] pointer to the created list.
+list_T *tv_list_alloc_ret(typval_T *const ret_tv, const ptrdiff_t len)
+ FUNC_ATTR_NONNULL_ALL
+{
+ list_T *const l = tv_list_alloc(len);
+ tv_list_set_ret(ret_tv, l);
+ ret_tv->v_lock = VAR_UNLOCKED;
+ return l;
+}
+
+/// Allocate an empty dictionary for a return value
+///
+/// Also sets reference count.
+///
+/// @param[out] ret_tv Structure where dictionary is saved.
+void tv_dict_alloc_ret(typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ dict_T *const d = tv_dict_alloc();
+ tv_dict_set_ret(ret_tv, d);
+ ret_tv->v_lock = VAR_UNLOCKED;
+}
+
+//{{{3 Clear
+#define TYPVAL_ENCODE_ALLOW_SPECIALS false
+
+#define TYPVAL_ENCODE_CONV_NIL(tv) \
+ do { \
+ tv->vval.v_special = kSpecialVarFalse; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
+ TYPVAL_ENCODE_CONV_NIL(tv)
+
+#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
+ do { \
+ (void)num; \
+ tv->vval.v_number = 0; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num)
+
+#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
+ do { \
+ tv->vval.v_float = 0; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
+ do { \
+ xfree(buf); \
+ tv->vval.v_string = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len)
+
+#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type)
+
+static inline int _nothing_conv_func_start(typval_T *const tv,
+ char_u *const fun)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1)
+{
+ tv->v_lock = VAR_UNLOCKED;
+ if (tv->v_type == VAR_PARTIAL) {
+ partial_T *const pt_ = tv->vval.v_partial;
+ if (pt_ != NULL && pt_->pt_refcount > 1) {
+ pt_->pt_refcount--;
+ tv->vval.v_partial = NULL;
+ return OK;
+ }
+ } else {
+ func_unref(fun);
+ if ((const char *)fun != tv_empty_string) {
+ xfree(fun);
+ }
+ tv->vval.v_string = NULL;
+ }
+ return NOTDONE;
+}
+#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
+ do { \
+ if (_nothing_conv_func_start(tv, fun) != NOTDONE) { \
+ return OK; \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
+
+static inline void _nothing_conv_func_end(typval_T *const tv, const int copyID)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
+{
+ if (tv->v_type == VAR_PARTIAL) {
+ partial_T *const pt = tv->vval.v_partial;
+ if (pt == NULL) {
+ return;
+ }
+ // Dictionary should already be freed by the time.
+ // If it was not freed then it is a part of the reference cycle.
+ assert(pt->pt_dict == NULL || pt->pt_dict->dv_copyID == copyID);
+ pt->pt_dict = NULL;
+ // As well as all arguments.
+ pt->pt_argc = 0;
+ assert(pt->pt_refcount <= 1);
+ partial_unref(pt);
+ tv->vval.v_partial = NULL;
+ assert(tv->v_lock == VAR_UNLOCKED);
+ }
+}
+#define TYPVAL_ENCODE_CONV_FUNC_END(tv) _nothing_conv_func_end(tv, copyID)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
+ do { \
+ tv_list_unref(tv->vval.v_list); \
+ tv->vval.v_list = NULL; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
+
+static inline void _nothing_conv_empty_dict(typval_T *const tv,
+ dict_T **const dictp)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(2)
+{
+ tv_dict_unref(*dictp);
+ *dictp = NULL;
+ if (tv != NULL) {
+ tv->v_lock = VAR_UNLOCKED;
+ }
+}
+#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
+ do { \
+ assert((void *)&dict != (void *)&TYPVAL_ENCODE_NODICT_VAR); \
+ _nothing_conv_empty_dict(tv, ((dict_T **)&dict)); \
+ } while (0)
+
+static inline int _nothing_conv_real_list_after_start(
+ typval_T *const tv, MPConvStackVal *const mpsv)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ assert(tv != NULL);
+ tv->v_lock = VAR_UNLOCKED;
+ if (tv->vval.v_list->lv_refcount > 1) {
+ tv->vval.v_list->lv_refcount--;
+ tv->vval.v_list = NULL;
+ mpsv->data.l.li = NULL;
+ return OK;
+ }
+ return NOTDONE;
+}
+#define TYPVAL_ENCODE_CONV_LIST_START(tv, len)
+
+#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv) \
+ do { \
+ if (_nothing_conv_real_list_after_start(tv, &mpsv) != NOTDONE) { \
+ goto typval_encode_stop_converting_one_item; \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv)
+
+static inline void _nothing_conv_list_end(typval_T *const tv)
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ if (tv == NULL) {
+ return;
+ }
+ assert(tv->v_type == VAR_LIST);
+ list_T *const list = tv->vval.v_list;
+ tv_list_unref(list);
+ tv->vval.v_list = NULL;
+}
+#define TYPVAL_ENCODE_CONV_LIST_END(tv) _nothing_conv_list_end(tv)
+
+static inline int _nothing_conv_real_dict_after_start(
+ typval_T *const tv, dict_T **const dictp, const void *const nodictvar,
+ MPConvStackVal *const mpsv)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (tv != NULL) {
+ tv->v_lock = VAR_UNLOCKED;
+ }
+ if ((const void *)dictp != nodictvar && (*dictp)->dv_refcount > 1) {
+ (*dictp)->dv_refcount--;
+ *dictp = NULL;
+ mpsv->data.d.todo = 0;
+ return OK;
+ }
+ return NOTDONE;
+}
+#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len)
+
+#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv) \
+ do { \
+ if (_nothing_conv_real_dict_after_start( \
+ tv, (dict_T **)&dict, (void *)&TYPVAL_ENCODE_NODICT_VAR, \
+ &mpsv) != NOTDONE) { \
+ goto typval_encode_stop_converting_one_item; \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(tv, dict)
+#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
+#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
+
+static inline void _nothing_conv_dict_end(typval_T *const tv,
+ dict_T **const dictp,
+ const void *const nodictvar)
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ if ((const void *)dictp != nodictvar) {
+ tv_dict_unref(*dictp);
+ *dictp = NULL;
+ }
+}
+#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
+ _nothing_conv_dict_end(tv, (dict_T **)&dict, \
+ (void *)&TYPVAL_ENCODE_NODICT_VAR)
+
+#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type)
+
+#define TYPVAL_ENCODE_SCOPE static
+#define TYPVAL_ENCODE_NAME nothing
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE const void *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME ignored
+#define TYPVAL_ENCODE_TRANSLATE_OBJECT_NAME
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
+#undef TYPVAL_ENCODE_TRANSLATE_OBJECT_NAME
+
+#undef TYPVAL_ENCODE_ALLOW_SPECIALS
+#undef TYPVAL_ENCODE_CONV_NIL
+#undef TYPVAL_ENCODE_CONV_BOOL
+#undef TYPVAL_ENCODE_CONV_NUMBER
+#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
+#undef TYPVAL_ENCODE_CONV_FLOAT
+#undef TYPVAL_ENCODE_CONV_STRING
+#undef TYPVAL_ENCODE_CONV_STR_STRING
+#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_FUNC_START
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
+#undef TYPVAL_ENCODE_CONV_FUNC_END
+#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
+#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
+#undef TYPVAL_ENCODE_CONV_LIST_START
+#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
+#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
+#undef TYPVAL_ENCODE_CONV_LIST_END
+#undef TYPVAL_ENCODE_CONV_DICT_START
+#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
+#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
+#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
+#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
+#undef TYPVAL_ENCODE_CONV_DICT_END
+#undef TYPVAL_ENCODE_CONV_RECURSE
+
+/// Free memory for a variable value and set the value to NULL or 0
+///
+/// @param[in,out] tv Value to free.
+void tv_clear(typval_T *const tv)
+{
+ if (tv != NULL && tv->v_type != VAR_UNKNOWN) {
+ // WARNING: do not translate the string here, gettext is slow and function
+ // is used *very* often. At the current state encode_vim_to_nothing() does
+ // not error out and does not use the argument anywhere.
+ //
+ // If situation changes and this argument will be used, translate it in the
+ // place where it is used.
+ const int evn_ret = encode_vim_to_nothing(NULL, tv, "tv_clear() argument");
+ (void)evn_ret;
+ assert(evn_ret == OK);
+ }
+}
+
+//{{{3 Free
+
+/// Free allocated VimL object and value stored inside
+///
+/// @param tv Object to free.
+void tv_free(typval_T *tv)
+{
+ if (tv != NULL) {
+ switch (tv->v_type) {
+ case VAR_PARTIAL: {
+ partial_unref(tv->vval.v_partial);
+ break;
+ }
+ case VAR_FUNC: {
+ func_unref(tv->vval.v_string);
+ FALLTHROUGH;
+ }
+ case VAR_STRING: {
+ xfree(tv->vval.v_string);
+ break;
+ }
+ case VAR_LIST: {
+ tv_list_unref(tv->vval.v_list);
+ break;
+ }
+ case VAR_DICT: {
+ tv_dict_unref(tv->vval.v_dict);
+ break;
+ }
+ case VAR_SPECIAL:
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN: {
+ break;
+ }
+ }
+ xfree(tv);
+ }
+}
+
+//{{{3 Copy
+
+/// Copy typval from one location to another
+///
+/// When needed allocates string or increases reference count. Does not make
+/// a copy of a container, but copies its reference!
+///
+/// It is OK for `from` and `to` to point to the same location; this is used to
+/// make a copy later.
+///
+/// @param[in] from Location to copy from.
+/// @param[out] to Location to copy to.
+void tv_copy(const typval_T *const from, typval_T *const to)
+{
+ to->v_type = from->v_type;
+ to->v_lock = VAR_UNLOCKED;
+ memmove(&to->vval, &from->vval, sizeof(to->vval));
+ switch (from->v_type) {
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_SPECIAL: {
+ break;
+ }
+ case VAR_STRING:
+ case VAR_FUNC: {
+ if (from->vval.v_string != NULL) {
+ to->vval.v_string = vim_strsave(from->vval.v_string);
+ if (from->v_type == VAR_FUNC) {
+ func_ref(to->vval.v_string);
+ }
+ }
+ break;
+ }
+ case VAR_PARTIAL: {
+ if (to->vval.v_partial != NULL) {
+ to->vval.v_partial->pt_refcount++;
+ }
+ break;
+ }
+ case VAR_LIST: {
+ tv_list_ref(to->vval.v_list);
+ break;
+ }
+ case VAR_DICT: {
+ if (from->vval.v_dict != NULL) {
+ to->vval.v_dict->dv_refcount++;
+ }
+ break;
+ }
+ case VAR_UNKNOWN: {
+ emsgf(_(e_intern2), "tv_copy(UNKNOWN)");
+ break;
+ }
+ }
+}
+
+//{{{2 Locks
+
+/// Lock or unlock an item
+///
+/// @param[out] tv Item to (un)lock.
+/// @param[in] deep Levels to (un)lock, -1 to (un)lock everything.
+/// @param[in] lock True if it is needed to lock an item, false to unlock.
+void tv_item_lock(typval_T *const tv, const int deep, const bool lock)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // TODO(ZyX-I): Make this not recursive
+ static int recurse = 0;
+
+ if (recurse >= DICT_MAXNEST) {
+ EMSG(_("E743: variable nested too deep for (un)lock"));
+ return;
+ }
+ if (deep == 0) {
+ return;
+ }
+ recurse++;
+
+ // lock/unlock the item itself
+#define CHANGE_LOCK(lock, var) \
+ do { \
+ var = ((VarLockStatus[]) { \
+ [VAR_UNLOCKED] = (lock ? VAR_LOCKED : VAR_UNLOCKED), \
+ [VAR_LOCKED] = (lock ? VAR_LOCKED : VAR_UNLOCKED), \
+ [VAR_FIXED] = VAR_FIXED, \
+ })[var]; \
+ } while (0)
+ CHANGE_LOCK(lock, tv->v_lock);
+
+ switch (tv->v_type) {
+ case VAR_LIST: {
+ list_T *const l = tv->vval.v_list;
+ if (l != NULL) {
+ CHANGE_LOCK(lock, l->lv_lock);
+ if (deep < 0 || deep > 1) {
+ // Recursive: lock/unlock the items the List contains.
+ TV_LIST_ITER(l, li, {
+ tv_item_lock(TV_LIST_ITEM_TV(li), deep - 1, lock);
+ });
+ }
+ }
+ break;
+ }
+ case VAR_DICT: {
+ dict_T *const d = tv->vval.v_dict;
+ if (d != NULL) {
+ CHANGE_LOCK(lock, d->dv_lock);
+ if (deep < 0 || deep > 1) {
+ // recursive: lock/unlock the items the List contains
+ TV_DICT_ITER(d, di, {
+ tv_item_lock(&di->di_tv, deep - 1, lock);
+ });
+ }
+ }
+ break;
+ }
+ case VAR_NUMBER:
+ case VAR_FLOAT:
+ case VAR_STRING:
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_SPECIAL: {
+ break;
+ }
+ case VAR_UNKNOWN: {
+ assert(false);
+ }
+ }
+#undef CHANGE_LOCK
+ recurse--;
+}
+
+/// Check whether VimL value is locked itself or refers to a locked container
+///
+/// @warning Fixed container is not the same as locked.
+///
+/// @param[in] tv Value to check.
+///
+/// @return True if value is locked, false otherwise.
+bool tv_islocked(const typval_T *const tv)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ return ((tv->v_lock == VAR_LOCKED)
+ || (tv->v_type == VAR_LIST
+ && (tv_list_locked(tv->vval.v_list) == VAR_LOCKED))
+ || (tv->v_type == VAR_DICT
+ && tv->vval.v_dict != NULL
+ && (tv->vval.v_dict->dv_lock == VAR_LOCKED)));
+}
+
+/// Return true if typval is locked
+///
+/// Also gives an error message when typval is locked.
+///
+/// @param[in] lock Lock status.
+/// @param[in] name Variable name, used in the error message.
+/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
+/// variable name and compute the length. Use #TV_CSTRING
+/// to compute the length with strlen() without
+/// translating.
+///
+/// Both #TV_… values are used for optimization purposes:
+/// variable name with its length is needed only in case
+/// of error, when no error occurs computing them is
+/// a waste of CPU resources. This especially applies to
+/// gettext.
+///
+/// @return true if variable is locked, false otherwise.
+bool tv_check_lock(const VarLockStatus lock, const char *name,
+ size_t name_len)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const char *error_message = NULL;
+ switch (lock) {
+ case VAR_UNLOCKED: {
+ return false;
+ }
+ case VAR_LOCKED: {
+ error_message = N_("E741: Value is locked: %.*s");
+ break;
+ }
+ case VAR_FIXED: {
+ error_message = N_("E742: Cannot change value of %.*s");
+ break;
+ }
+ }
+ assert(error_message != NULL);
+
+ if (name == NULL) {
+ name = _("Unknown");
+ name_len = strlen(name);
+ } else if (name_len == TV_TRANSLATE) {
+ name = _(name);
+ name_len = strlen(name);
+ } else if (name_len == TV_CSTRING) {
+ name_len = strlen(name);
+ }
+
+ emsgf(_(error_message), (int)name_len, name);
+
+ return true;
+}
+
+//{{{2 Comparison
+
+static int tv_equal_recurse_limit;
+
+/// Compare two VimL values
+///
+/// Like "==", but strings and numbers are different, as well as floats and
+/// numbers.
+///
+/// @warning Too nested structures may be considered equal even if they are not.
+///
+/// @param[in] tv1 First value to compare.
+/// @param[in] tv2 Second value to compare.
+/// @param[in] ic True if case is to be ignored.
+/// @param[in] recursive True when used recursively.
+///
+/// @return true if values are equal.
+bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
+ const bool recursive)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ // TODO(ZyX-I): Make this not recursive
+ static int recursive_cnt = 0; // Catch recursive loops.
+
+ if (!(tv_is_func(*tv1) && tv_is_func(*tv2)) && tv1->v_type != tv2->v_type) {
+ return false;
+ }
+
+ // Catch lists and dicts that have an endless loop by limiting
+ // recursiveness to a limit. We guess they are equal then.
+ // A fixed limit has the problem of still taking an awful long time.
+ // Reduce the limit every time running into it. That should work fine for
+ // deeply linked structures that are not recursively linked and catch
+ // recursiveness quickly.
+ if (!recursive) {
+ tv_equal_recurse_limit = 1000;
+ }
+ if (recursive_cnt >= tv_equal_recurse_limit) {
+ tv_equal_recurse_limit--;
+ return true;
+ }
+
+ switch (tv1->v_type) {
+ case VAR_LIST: {
+ recursive_cnt++;
+ const bool r = tv_list_equal(tv1->vval.v_list, tv2->vval.v_list, ic,
+ true);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_DICT: {
+ recursive_cnt++;
+ const bool r = tv_dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic,
+ true);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ if ((tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial == NULL)
+ || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial == NULL)) {
+ return false;
+ }
+ recursive_cnt++;
+ const bool r = func_equal(tv1, tv2, ic);
+ recursive_cnt--;
+ return r;
+ }
+ case VAR_NUMBER: {
+ return tv1->vval.v_number == tv2->vval.v_number;
+ }
+ case VAR_FLOAT: {
+ return tv1->vval.v_float == tv2->vval.v_float;
+ }
+ case VAR_STRING: {
+ char buf1[NUMBUFLEN];
+ char buf2[NUMBUFLEN];
+ const char *s1 = tv_get_string_buf(tv1, buf1);
+ const char *s2 = tv_get_string_buf(tv2, buf2);
+ return mb_strcmp_ic((bool)ic, s1, s2) == 0;
+ }
+ case VAR_SPECIAL: {
+ return tv1->vval.v_special == tv2->vval.v_special;
+ }
+ case VAR_UNKNOWN: {
+ // VAR_UNKNOWN can be the result of an invalid expression, let’s say it
+ // does not equal anything, not even self.
+ return false;
+ }
+ }
+
+ assert(false);
+ return false;
+}
+
+//{{{2 Type checks
+
+/// Check that given value is a number or string
+///
+/// Error messages are compatible with tv_get_number() previously used for the
+/// same purpose in buf*() functions. Special values are not accepted (previous
+/// behaviour: silently fail to find buffer).
+///
+/// @param[in] tv Value to check.
+///
+/// @return true if everything is OK, false otherwise.
+bool tv_check_str_or_nr(const typval_T *const tv)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER:
+ case VAR_STRING: {
+ return true;
+ }
+ case VAR_FLOAT: {
+ EMSG(_("E805: Expected a Number or a String, Float found"));
+ return false;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ EMSG(_("E703: Expected a Number or a String, Funcref found"));
+ return false;
+ }
+ case VAR_LIST: {
+ EMSG(_("E745: Expected a Number or a String, List found"));
+ return false;
+ }
+ case VAR_DICT: {
+ EMSG(_("E728: Expected a Number or a String, Dictionary found"));
+ return false;
+ }
+ case VAR_SPECIAL: {
+ EMSG(_("E5300: Expected a Number or a String"));
+ return false;
+ }
+ case VAR_UNKNOWN: {
+ EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)");
+ return false;
+ }
+ }
+ assert(false);
+ return false;
+}
+
+#define FUNC_ERROR "E703: Using a Funcref as a Number"
+
+static const char *const num_errors[] = {
+ [VAR_PARTIAL]=N_(FUNC_ERROR),
+ [VAR_FUNC]=N_(FUNC_ERROR),
+ [VAR_LIST]=N_("E745: Using a List as a Number"),
+ [VAR_DICT]=N_("E728: Using a Dictionary as a Number"),
+ [VAR_FLOAT]=N_("E805: Using a Float as a Number"),
+ [VAR_UNKNOWN]=N_("E685: using an invalid value as a Number"),
+};
+
+#undef FUNC_ERROR
+
+/// Check that given value is a number or can be converted to it
+///
+/// Error messages are compatible with tv_get_number_chk() previously used for
+/// the same purpose.
+///
+/// @param[in] tv Value to check.
+///
+/// @return true if everything is OK, false otherwise.
+bool tv_check_num(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER:
+ case VAR_SPECIAL:
+ case VAR_STRING: {
+ return true;
+ }
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN: {
+ EMSG(_(num_errors[tv->v_type]));
+ return false;
+ }
+ }
+ assert(false);
+ return false;
+}
+
+#define FUNC_ERROR "E729: using Funcref as a String"
+
+static const char *const str_errors[] = {
+ [VAR_PARTIAL]=N_(FUNC_ERROR),
+ [VAR_FUNC]=N_(FUNC_ERROR),
+ [VAR_LIST]=N_("E730: using List as a String"),
+ [VAR_DICT]=N_("E731: using Dictionary as a String"),
+ [VAR_FLOAT]=((const char *)e_float_as_string),
+ [VAR_UNKNOWN]=N_("E908: using an invalid value as a String"),
+};
+
+#undef FUNC_ERROR
+
+/// Check that given value is a VimL String or can be "cast" to it.
+///
+/// Error messages are compatible with tv_get_string_chk() previously used for
+/// the same purpose.
+///
+/// @param[in] tv Value to check.
+///
+/// @return true if everything is OK, false otherwise.
+bool tv_check_str(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER:
+ case VAR_SPECIAL:
+ case VAR_STRING: {
+ return true;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN: {
+ EMSG(_(str_errors[tv->v_type]));
+ return false;
+ }
+ }
+ assert(false);
+ return false;
+}
+
+//{{{2 Get
+
+/// Get the number value of a VimL object
+///
+/// @note Use tv_get_number_chk() if you need to determine whether there was an
+/// error.
+///
+/// @param[in] tv Object to get value from.
+///
+/// @return Number value: vim_str2nr() output for VAR_STRING objects, value
+/// for VAR_NUMBER objects, -1 for other types.
+varnumber_T tv_get_number(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ bool error = false;
+ return tv_get_number_chk(tv, &error);
+}
+
+/// Get the number value of a VimL object
+///
+/// @param[in] tv Object to get value from.
+/// @param[out] ret_error If type error occurred then `true` will be written
+/// to this location. Otherwise it is not touched.
+///
+/// @note Needs to be initialized to `false` to be
+/// useful.
+///
+/// @return Number value: vim_str2nr() output for VAR_STRING objects, value
+/// for VAR_NUMBER objects, -1 (ret_error == NULL) or 0 (otherwise) for
+/// other types.
+varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ARG(1)
+{
+ switch (tv->v_type) {
+ case VAR_FUNC:
+ case VAR_PARTIAL:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT: {
+ EMSG(_(num_errors[tv->v_type]));
+ break;
+ }
+ case VAR_NUMBER: {
+ return tv->vval.v_number;
+ }
+ case VAR_STRING: {
+ varnumber_T n = 0;
+ if (tv->vval.v_string != NULL) {
+ vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0);
+ }
+ return n;
+ }
+ case VAR_SPECIAL: {
+ switch (tv->vval.v_special) {
+ case kSpecialVarTrue: {
+ return 1;
+ }
+ case kSpecialVarFalse:
+ case kSpecialVarNull: {
+ return 0;
+ }
+ }
+ break;
+ }
+ case VAR_UNKNOWN: {
+ emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
+ break;
+ }
+ }
+ if (ret_error != NULL) {
+ *ret_error = true;
+ }
+ return (ret_error == NULL ? -1 : 0);
+}
+
+/// Get the line number from VimL object
+///
+/// @param[in] tv Object to get value from. Is expected to be a number or
+/// a special string like ".", "$", … (works with current buffer
+/// only).
+///
+/// @return Line number or -1 or 0.
+linenr_T tv_get_lnum(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ linenr_T lnum = (linenr_T)tv_get_number_chk(tv, NULL);
+ if (lnum == 0) { // No valid number, try using same function as line() does.
+ int fnum;
+ pos_T *const fp = var2fpos(tv, true, &fnum);
+ if (fp != NULL) {
+ lnum = fp->lnum;
+ }
+ }
+ return lnum;
+}
+
+/// Get the floating-point value of a VimL object
+///
+/// Raises an error if object is not number or floating-point.
+///
+/// @param[in] tv Object to get value of.
+///
+/// @return Floating-point value of the variable or zero.
+float_T tv_get_float(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER: {
+ return (float_T)(tv->vval.v_number);
+ }
+ case VAR_FLOAT: {
+ return tv->vval.v_float;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC: {
+ EMSG(_("E891: Using a Funcref as a Float"));
+ break;
+ }
+ case VAR_STRING: {
+ EMSG(_("E892: Using a String as a Float"));
+ break;
+ }
+ case VAR_LIST: {
+ EMSG(_("E893: Using a List as a Float"));
+ break;
+ }
+ case VAR_DICT: {
+ EMSG(_("E894: Using a Dictionary as a Float"));
+ break;
+ }
+ case VAR_SPECIAL: {
+ EMSG(_("E907: Using a special value as a Float"));
+ break;
+ }
+ case VAR_UNKNOWN: {
+ emsgf(_(e_intern2), "tv_get_float(UNKNOWN)");
+ break;
+ }
+ }
+ return 0;
+}
+
+/// Get the string value of a "stringish" VimL object.
+///
+/// @param[in] tv Object to get value of.
+/// @param buf Buffer used to hold numbers and special variables converted to
+/// string. When function encounters one of these stringified value
+/// will be written to buf and buf will be returned.
+///
+/// Buffer must have NUMBUFLEN size.
+///
+/// @return Object value if it is VAR_STRING object, number converted to
+/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL.
+const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ switch (tv->v_type) {
+ case VAR_NUMBER: {
+ snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); // -V576
+ return buf;
+ }
+ case VAR_STRING: {
+ if (tv->vval.v_string != NULL) {
+ return (const char *)tv->vval.v_string;
+ }
+ return "";
+ }
+ case VAR_SPECIAL: {
+ STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
+ return buf;
+ }
+ case VAR_PARTIAL:
+ case VAR_FUNC:
+ case VAR_LIST:
+ case VAR_DICT:
+ case VAR_FLOAT:
+ case VAR_UNKNOWN: {
+ EMSG(_(str_errors[tv->v_type]));
+ return false;
+ }
+ }
+ return NULL;
+}
+
+/// Get the string value of a "stringish" VimL object.
+///
+/// @warning For number and special values it uses a single, static buffer. It
+/// may be used only once, next call to tv_get_string may reuse it. Use
+/// tv_get_string_buf() if you need to use tv_get_string() output after
+/// calling it again.
+///
+/// @param[in] tv Object to get value of.
+///
+/// @return Object value if it is VAR_STRING object, number converted to
+/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL.
+const char *tv_get_string_chk(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static char mybuf[NUMBUFLEN];
+
+ return tv_get_string_buf_chk(tv, mybuf);
+}
+
+/// Get the string value of a "stringish" VimL object.
+///
+/// @warning For number and special values it uses a single, static buffer. It
+/// may be used only once, next call to tv_get_string may reuse it. Use
+/// tv_get_string_buf() if you need to use tv_get_string() output after
+/// calling it again.
+///
+/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but
+/// return NULL on error.
+///
+/// @param[in] tv Object to get value of.
+///
+/// @return Object value if it is VAR_STRING object, number converted to
+/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or empty
+/// string.
+const char *tv_get_string(const typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static char mybuf[NUMBUFLEN];
+ return tv_get_string_buf((typval_T *)tv, mybuf);
+}
+
+/// Get the string value of a "stringish" VimL object.
+///
+/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but
+/// return NULL on error.
+///
+/// @param[in] tv Object to get value of.
+/// @param buf Buffer used to hold numbers and special variables converted to
+/// string. When function encounters one of these stringified value
+/// will be written to buf and buf will be returned.
+///
+/// Buffer must have NUMBUFLEN size.
+///
+/// @return Object value if it is VAR_STRING object, number converted to
+/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or empty
+/// string.
+const char *tv_get_string_buf(const typval_T *const tv, char *const buf)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const char *const res = (const char *)tv_get_string_buf_chk(tv, buf);
+
+ return res != NULL ? res : "";
+}
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
new file mode 100644
index 0000000000..e99289c430
--- /dev/null
+++ b/src/nvim/eval/typval.h
@@ -0,0 +1,842 @@
+#ifndef NVIM_EVAL_TYPVAL_H
+#define NVIM_EVAL_TYPVAL_H
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <limits.h>
+
+#include "nvim/types.h"
+#include "nvim/hashtab.h"
+#include "nvim/garray.h"
+#include "nvim/mbyte.h"
+#include "nvim/func_attr.h"
+#include "nvim/lib/queue.h"
+#include "nvim/profile.h" // for proftime_T
+#include "nvim/pos.h" // for linenr_T
+#include "nvim/gettext.h"
+#include "nvim/message.h"
+#include "nvim/macros.h"
+#ifdef LOG_LIST_ACTIONS
+# include "nvim/memory.h"
+#endif
+
+/// Type used for VimL VAR_NUMBER values
+typedef int64_t varnumber_T;
+typedef uint64_t uvarnumber_T;
+
+/// Type used for VimL VAR_FLOAT values
+typedef double float_T;
+
+/// Refcount for dict or list that should not be freed
+enum { DO_NOT_FREE_CNT = (INT_MAX / 2) };
+
+/// Additional values for tv_list_alloc() len argument
+enum {
+ /// List length is not known in advance
+ ///
+ /// To be used when there is neither a way to know how many elements will be
+ /// needed nor are any educated guesses.
+ kListLenUnknown = -1,
+ /// List length *should* be known, but is actually not
+ ///
+ /// All occurrences of this value should be eventually removed. This is for
+ /// the case when the only reason why list length is not known is that it
+ /// would be hard to code without refactoring, but refactoring is needed.
+ kListLenShouldKnow = -2,
+ /// List length may be known in advance, but it requires too much effort
+ ///
+ /// To be used when it looks impractical to determine list length.
+ kListLenMayKnow = -3,
+} ListLenSpecials;
+
+/// Maximal possible value of varnumber_T variable
+#define VARNUMBER_MAX INT64_MAX
+#define UVARNUMBER_MAX UINT64_MAX
+
+/// Mimimal possible value of varnumber_T variable
+#define VARNUMBER_MIN INT64_MIN
+
+/// %d printf format specifier for varnumber_T
+#define PRIdVARNUMBER PRId64
+
+typedef struct listvar_S list_T;
+typedef struct dictvar_S dict_T;
+typedef struct partial_S partial_T;
+
+typedef struct ufunc ufunc_T;
+
+typedef enum {
+ kCallbackNone = 0,
+ kCallbackFuncref,
+ kCallbackPartial,
+} CallbackType;
+
+typedef struct {
+ union {
+ char_u *funcref;
+ partial_T *partial;
+ } data;
+ CallbackType type;
+} Callback;
+#define CALLBACK_NONE ((Callback){ .type = kCallbackNone })
+
+/// Structure holding dictionary watcher
+typedef struct dict_watcher {
+ Callback callback;
+ char *key_pattern;
+ size_t key_pattern_len;
+ QUEUE node;
+ bool busy; // prevent recursion if the dict is changed in the callback
+} DictWatcher;
+
+/// Special variable values
+typedef enum {
+ kSpecialVarFalse, ///< v:false
+ kSpecialVarTrue, ///< v:true
+ kSpecialVarNull, ///< v:null
+} SpecialVarValue;
+
+/// Variable lock status for typval_T.v_lock
+typedef enum {
+ VAR_UNLOCKED = 0, ///< Not locked.
+ VAR_LOCKED = 1, ///< User lock, can be unlocked.
+ VAR_FIXED = 2, ///< Locked forever.
+} VarLockStatus;
+
+/// VimL variable types, for use in typval_T.v_type
+typedef enum {
+ VAR_UNKNOWN = 0, ///< Unknown (unspecified) value.
+ VAR_NUMBER, ///< Number, .v_number is used.
+ VAR_STRING, ///< String, .v_string is used.
+ VAR_FUNC, ///< Function reference, .v_string is used as function name.
+ VAR_LIST, ///< List, .v_list is used.
+ VAR_DICT, ///< Dictionary, .v_dict is used.
+ VAR_FLOAT, ///< Floating-point value, .v_float is used.
+ VAR_SPECIAL, ///< Special value (true, false, null), .v_special
+ ///< is used.
+ VAR_PARTIAL, ///< Partial, .v_partial is used.
+} VarType;
+
+/// Structure that holds an internal variable value
+typedef struct {
+ VarType v_type; ///< Variable type.
+ VarLockStatus v_lock; ///< Variable lock status.
+ union typval_vval_union {
+ varnumber_T v_number; ///< Number, for VAR_NUMBER.
+ SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL.
+ float_T v_float; ///< Floating-point number, for VAR_FLOAT.
+ char_u *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL.
+ list_T *v_list; ///< List for VAR_LIST, can be NULL.
+ dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL.
+ partial_T *v_partial; ///< Closure: function with args.
+ } vval; ///< Actual value.
+} typval_T;
+
+/// Values for (struct dictvar_S).dv_scope
+typedef enum {
+ VAR_NO_SCOPE = 0, ///< Not a scope dictionary.
+ VAR_SCOPE = 1, ///< Scope dictionary which requires prefix (a:, v:, …).
+ VAR_DEF_SCOPE = 2, ///< Scope dictionary which may be accessed without prefix
+ ///< (l:, g:).
+} ScopeType;
+
+/// Structure to hold an item of a list
+typedef struct listitem_S listitem_T;
+
+struct listitem_S {
+ listitem_T *li_next; ///< Next item in list.
+ listitem_T *li_prev; ///< Previous item in list.
+ typval_T li_tv; ///< Item value.
+};
+
+/// Structure used by those that are using an item in a list
+typedef struct listwatch_S listwatch_T;
+
+struct listwatch_S {
+ listitem_T *lw_item; ///< Item being watched.
+ listwatch_T *lw_next; ///< Next watcher.
+};
+
+/// Structure to hold info about a list
+/// Order of members is optimized to reduce padding.
+struct listvar_S {
+ listitem_T *lv_first; ///< First item, NULL if none.
+ listitem_T *lv_last; ///< Last item, NULL if none.
+ listwatch_T *lv_watch; ///< First watcher, NULL if none.
+ listitem_T *lv_idx_item; ///< When not NULL item at index "lv_idx".
+ list_T *lv_copylist; ///< Copied list used by deepcopy().
+ list_T *lv_used_next; ///< next list in used lists list.
+ list_T *lv_used_prev; ///< Previous list in used lists list.
+ int lv_refcount; ///< Reference count.
+ int lv_len; ///< Number of items.
+ int lv_idx; ///< Index of a cached item, used for optimising repeated l[idx].
+ int lv_copyID; ///< ID used by deepcopy().
+ VarLockStatus lv_lock; ///< Zero, VAR_LOCKED, VAR_FIXED.
+};
+
+// Static list with 10 items. Use tv_list_init_static10() to initialize.
+typedef struct {
+ list_T sl_list; // must be first
+ listitem_T sl_items[10];
+} staticList10_T;
+
+#define TV_LIST_STATIC10_INIT { \
+ .sl_list = { \
+ .lv_first = NULL, \
+ .lv_last = NULL, \
+ .lv_refcount = 0, \
+ .lv_len = 0, \
+ .lv_watch = NULL, \
+ .lv_idx_item = NULL, \
+ .lv_lock = VAR_FIXED, \
+ .lv_used_next = NULL, \
+ .lv_used_prev = NULL, \
+ }, \
+ }
+
+#define TV_DICTITEM_STRUCT(...) \
+ struct { \
+ typval_T di_tv; /* Structure that holds scope dictionary itself. */ \
+ uint8_t di_flags; /* Flags. */ \
+ char_u di_key[__VA_ARGS__]; /* Key value. */ \
+ }
+
+/// Structure to hold a scope dictionary
+///
+/// @warning Must be compatible with dictitem_T.
+///
+/// For use in find_var_in_ht to pretend that it found dictionary item when it
+/// finds scope dictionary.
+typedef TV_DICTITEM_STRUCT(1) ScopeDictDictItem;
+
+/// Structure to hold an item of a Dictionary
+///
+/// @warning Must be compatible with ScopeDictDictItem.
+///
+/// Also used for a variable.
+typedef TV_DICTITEM_STRUCT() dictitem_T;
+
+/// Flags for dictitem_T.di_flags
+typedef enum {
+ DI_FLAGS_RO = 1, ///< Read-only value
+ DI_FLAGS_RO_SBX = 2, ///< Value, read-only in the sandbox
+ DI_FLAGS_FIX = 4, ///< Fixed value: cannot be :unlet or remove()d.
+ DI_FLAGS_LOCK = 8, ///< Locked value.
+ DI_FLAGS_ALLOC = 16, ///< Separately allocated.
+} DictItemFlags;
+
+/// Structure representing a Dictionary
+struct dictvar_S {
+ VarLockStatus dv_lock; ///< Whole dictionary lock status.
+ ScopeType dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if
+ ///< dictionary represents a scope (i.e. g:, l: …).
+ int dv_refcount; ///< Reference count.
+ int dv_copyID; ///< ID used when recursivery traversing a value.
+ hashtab_T dv_hashtab; ///< Hashtab containing all items.
+ dict_T *dv_copydict; ///< Copied dict used by deepcopy().
+ dict_T *dv_used_next; ///< Next dictionary in used dictionaries list.
+ dict_T *dv_used_prev; ///< Previous dictionary in used dictionaries list.
+ QUEUE watchers; ///< Dictionary key watchers set by user code.
+};
+
+/// Type used for script ID
+typedef int scid_T;
+/// Format argument for scid_T
+#define PRIdSCID "d"
+
+// Structure to hold info for a function that is currently being executed.
+typedef struct funccall_S funccall_T;
+
+/// Structure to hold info for a user function.
+struct ufunc {
+ int uf_varargs; ///< variable nr of arguments
+ int uf_flags;
+ int uf_calls; ///< nr of active calls
+ bool uf_cleared; ///< func_clear() was already called
+ garray_T uf_args; ///< arguments
+ garray_T uf_lines; ///< function lines
+ int uf_profiling; ///< true when func is being profiled
+ // Profiling the function as a whole.
+ int uf_tm_count; ///< nr of calls
+ proftime_T uf_tm_total; ///< time spent in function + children
+ proftime_T uf_tm_self; ///< time spent in function itself
+ proftime_T uf_tm_children; ///< time spent in children this call
+ // Profiling the function per line.
+ int *uf_tml_count; ///< nr of times line was executed
+ proftime_T *uf_tml_total; ///< time spent in a line + children
+ proftime_T *uf_tml_self; ///< time spent in a line itself
+ proftime_T uf_tml_start; ///< start time for current line
+ proftime_T uf_tml_children; ///< time spent in children for this line
+ proftime_T uf_tml_wait; ///< start wait time for current line
+ int uf_tml_idx; ///< index of line being timed; -1 if none
+ int uf_tml_execed; ///< line being timed was executed
+ scid_T uf_script_ID; ///< ID of script where function was defined,
+ ///< used for s: variables
+ int uf_refcount; ///< reference count, see func_name_refcount()
+ funccall_T *uf_scoped; ///< l: local variables for closure
+ char_u uf_name[]; ///< Name of function; can start with <SNR>123_
+ ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR)
+};
+
+/// Maximum number of function arguments
+#define MAX_FUNC_ARGS 20
+
+struct partial_S {
+ int pt_refcount; ///< Reference count.
+ char_u *pt_name; ///< Function name; when NULL use pt_func->name.
+ ufunc_T *pt_func; ///< Function pointer; when NULL lookup function with
+ ///< pt_name.
+ bool pt_auto; ///< When true the partial was created by using dict.member
+ ///< in handle_subscript().
+ int pt_argc; ///< Number of arguments.
+ typval_T *pt_argv; ///< Arguments in allocated array.
+ dict_T *pt_dict; ///< Dict for "self".
+};
+
+/// Structure used for explicit stack while garbage collecting hash tables
+typedef struct ht_stack_S {
+ hashtab_T *ht;
+ struct ht_stack_S *prev;
+} ht_stack_T;
+
+/// Structure used for explicit stack while garbage collecting lists
+typedef struct list_stack_S {
+ list_T *list;
+ struct list_stack_S *prev;
+} list_stack_T;
+
+/// Structure representing one list item, used for sort array.
+typedef struct {
+ listitem_T *item; ///< Sorted list item.
+ int idx; ///< Sorted list item index.
+} ListSortItem;
+
+typedef int (*ListSorter)(const void *, const void *);
+
+#ifdef LOG_LIST_ACTIONS
+
+/// List actions log entry
+typedef struct {
+ uintptr_t l; ///< List log entry belongs to.
+ uintptr_t li1; ///< First list item log entry belongs to, if applicable.
+ uintptr_t li2; ///< Second list item log entry belongs to, if applicable.
+ int len; ///< List length when log entry was created.
+ const char *action; ///< Logged action.
+} ListLogEntry;
+
+typedef struct list_log ListLog;
+
+/// List actions log
+struct list_log {
+ ListLog *next; ///< Next chunk or NULL.
+ size_t capacity; ///< Number of entries in current chunk.
+ size_t size; ///< Current chunk size.
+ ListLogEntry entries[]; ///< Actual log entries.
+};
+
+extern ListLog *list_log_first; ///< First list log chunk, NULL if missing
+extern ListLog *list_log_last; ///< Last list log chunk
+
+static inline ListLog *list_log_alloc(const size_t size)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Allocate a new log chunk and update globals
+///
+/// @param[in] size Number of entries in a new chunk.
+///
+/// @return [allocated] Newly allocated chunk.
+static inline ListLog *list_log_new(const size_t size)
+{
+ ListLog *ret = xmalloc(offsetof(ListLog, entries)
+ + size * sizeof(ret->entries[0]));
+ ret->size = 0;
+ ret->capacity = size;
+ ret->next = NULL;
+ if (list_log_first == NULL) {
+ list_log_first = ret;
+ } else {
+ list_log_last->next = ret;
+ }
+ list_log_last = ret;
+ return ret;
+}
+
+static inline void list_log(const list_T *const l,
+ const listitem_T *const li1,
+ const listitem_T *const li2,
+ const char *const action)
+ REAL_FATTR_ALWAYS_INLINE;
+
+/// Add new entry to log
+///
+/// If last chunk was filled it uses twice as much memory to allocate the next
+/// chunk.
+///
+/// @param[in] l List to which entry belongs.
+/// @param[in] li1 List item 1.
+/// @param[in] li2 List item 2, often used for integers and not list items.
+/// @param[in] action Logged action.
+static inline void list_log(const list_T *const l,
+ const listitem_T *const li1,
+ const listitem_T *const li2,
+ const char *const action)
+{
+ ListLog *tgt;
+ if (list_log_first == NULL) {
+ tgt = list_log_new(128);
+ } else if (list_log_last->size == list_log_last->capacity) {
+ tgt = list_log_new(list_log_last->capacity * 2);
+ } else {
+ tgt = list_log_last;
+ }
+ tgt->entries[tgt->size++] = (ListLogEntry) {
+ .l = (uintptr_t)l,
+ .li1 = (uintptr_t)li1,
+ .li2 = (uintptr_t)li2,
+ .len = (l == NULL ? 0 : l->lv_len),
+ .action = action,
+ };
+}
+#else
+# define list_log(...)
+# define list_write_log(...)
+# define list_free_log()
+#endif
+
+// In a hashtab item "hi_key" points to "di_key" in a dictitem.
+// This avoids adding a pointer to the hashtab item.
+
+/// Convert a hashitem pointer to a dictitem pointer
+#define TV_DICT_HI2DI(hi) \
+ ((dictitem_T *)((hi)->hi_key - offsetof(dictitem_T, di_key)))
+
+static inline void tv_list_ref(list_T *const l)
+ REAL_FATTR_ALWAYS_INLINE;
+
+/// Increase reference count for a given list
+///
+/// Does nothing for NULL lists.
+///
+/// @param[in,out] l List to modify.
+static inline void tv_list_ref(list_T *const l)
+{
+ if (l == NULL) {
+ return;
+ }
+ l->lv_refcount++;
+}
+
+static inline void tv_list_set_ret(typval_T *const tv, list_T *const l)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1);
+
+/// Set a list as the return value
+///
+/// @param[out] tv Object to receive the list
+/// @param[in,out] l List to pass to the object
+static inline void tv_list_set_ret(typval_T *const tv, list_T *const l)
+{
+ tv->v_type = VAR_LIST;
+ tv->vval.v_list = l;
+ tv_list_ref(l);
+}
+
+static inline VarLockStatus tv_list_locked(const list_T *const l)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get list lock status
+///
+/// Returns VAR_FIXED for NULL lists.
+///
+/// @param[in] l List to check.
+static inline VarLockStatus tv_list_locked(const list_T *const l)
+{
+ if (l == NULL) {
+ return VAR_FIXED;
+ }
+ return l->lv_lock;
+}
+
+/// Set list lock status
+///
+/// May only “set†VAR_FIXED for NULL lists.
+///
+/// @param[out] l List to modify.
+/// @param[in] lock New lock status.
+static inline void tv_list_set_lock(list_T *const l,
+ const VarLockStatus lock)
+{
+ if (l == NULL) {
+ assert(lock == VAR_FIXED);
+ return;
+ }
+ l->lv_lock = lock;
+}
+
+/// Set list copyID
+///
+/// Does not expect NULL list, be careful.
+///
+/// @param[out] l List to modify.
+/// @param[in] copyid New copyID.
+static inline void tv_list_set_copyid(list_T *const l,
+ const int copyid)
+ FUNC_ATTR_NONNULL_ALL
+{
+ l->lv_copyID = copyid;
+}
+
+static inline int tv_list_len(const list_T *const l)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get the number of items in a list
+///
+/// @param[in] l List to check.
+static inline int tv_list_len(const list_T *const l)
+{
+ list_log(l, NULL, NULL, "len");
+ if (l == NULL) {
+ return 0;
+ }
+ return l->lv_len;
+}
+
+static inline int tv_list_copyid(const list_T *const l)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_NONNULL_ALL;
+
+/// Get list copyID
+///
+/// Does not expect NULL list, be careful.
+///
+/// @param[in] l List to check.
+static inline int tv_list_copyid(const list_T *const l)
+{
+ return l->lv_copyID;
+}
+
+static inline list_T *tv_list_latest_copy(const list_T *const l)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_NONNULL_ALL;
+
+/// Get latest list copy
+///
+/// Gets lv_copylist field assigned by tv_list_copy() earlier.
+///
+/// Does not expect NULL list, be careful.
+///
+/// @param[in] l List to check.
+static inline list_T *tv_list_latest_copy(const list_T *const l)
+{
+ return l->lv_copylist;
+}
+
+static inline int tv_list_uidx(const list_T *const l, int n)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Normalize index: that is, return either -1 or non-negative index
+///
+/// @param[in] l List to index. Used to get length.
+/// @param[in] n List index, possibly negative.
+///
+/// @return -1 or list index in range [0, tv_list_len(l)).
+static inline int tv_list_uidx(const list_T *const l, int n)
+{
+ // Negative index is relative to the end.
+ if (n < 0) {
+ n += tv_list_len(l);
+ }
+
+ // Check for index out of range.
+ if (n < 0 || n >= tv_list_len(l)) {
+ return -1;
+ }
+ return n;
+}
+
+static inline bool tv_list_has_watchers(const list_T *const l)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Check whether list has watchers
+///
+/// E.g. is referenced by a :for loop.
+///
+/// @param[in] l List to check.
+///
+/// @return true if there are watchers, false otherwise.
+static inline bool tv_list_has_watchers(const list_T *const l)
+{
+ return l && l->lv_watch;
+}
+
+static inline listitem_T *tv_list_first(const list_T *const l)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get first list item
+///
+/// @param[in] l List to get item from.
+///
+/// @return List item or NULL in case of an empty list.
+static inline listitem_T *tv_list_first(const list_T *const l)
+{
+ if (l == NULL) {
+ list_log(l, NULL, NULL, "first");
+ return NULL;
+ }
+ list_log(l, l->lv_first, NULL, "first");
+ return l->lv_first;
+}
+
+static inline listitem_T *tv_list_last(const list_T *const l)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get last list item
+///
+/// @param[in] l List to get item from.
+///
+/// @return List item or NULL in case of an empty list.
+static inline listitem_T *tv_list_last(const list_T *const l)
+{
+ if (l == NULL) {
+ list_log(l, NULL, NULL, "last");
+ return NULL;
+ }
+ list_log(l, l->lv_last, NULL, "last");
+ return l->lv_last;
+}
+
+static inline void tv_dict_set_ret(typval_T *const tv, dict_T *const d)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1);
+
+/// Set a dictionary as the return value
+///
+/// @param[out] tv Object to receive the dictionary
+/// @param[in,out] d Dictionary to pass to the object
+static inline void tv_dict_set_ret(typval_T *const tv, dict_T *const d)
+{
+ tv->v_type = VAR_DICT;
+ tv->vval.v_dict = d;
+ if (d != NULL) {
+ d->dv_refcount++;
+ }
+}
+
+static inline long tv_dict_len(const dict_T *const d)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Get the number of items in a Dictionary
+///
+/// @param[in] d Dictionary to check.
+static inline long tv_dict_len(const dict_T *const d)
+{
+ if (d == NULL) {
+ return 0L;
+ }
+ return (long)d->dv_hashtab.ht_used;
+}
+
+static inline bool tv_dict_is_watched(const dict_T *const d)
+ REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Check if dictionary is watched
+///
+/// @param[in] d Dictionary to check.
+///
+/// @return true if there is at least one watcher.
+static inline bool tv_dict_is_watched(const dict_T *const d)
+{
+ return d && !QUEUE_EMPTY(&d->watchers);
+}
+
+/// Initialize VimL object
+///
+/// Initializes to unlocked VAR_UNKNOWN object.
+///
+/// @param[out] tv Object to initialize.
+static inline void tv_init(typval_T *const tv)
+{
+ if (tv != NULL) {
+ memset(tv, 0, sizeof(*tv));
+ }
+}
+
+#define TV_INITIAL_VALUE \
+ ((typval_T) { \
+ .v_type = VAR_UNKNOWN, \
+ .v_lock = VAR_UNLOCKED, \
+ })
+
+/// Empty string
+///
+/// Needed for hack which allows not allocating empty string and still not
+/// crashing when freeing it.
+extern const char *const tv_empty_string;
+
+/// Specifies that free_unref_items() function has (not) been entered
+extern bool tv_in_free_unref_items;
+
+/// Iterate over a list
+///
+/// @param modifier Modifier: expected to be const or nothing, volatile should
+/// also work if you have any uses for the volatile list.
+/// @param[in] l List to iterate over.
+/// @param li Name of the variable with current listitem_T entry.
+/// @param code Cycle body.
+#define _TV_LIST_ITER_MOD(modifier, l, li, code) \
+ do { \
+ modifier list_T *const l_ = (l); \
+ list_log(l_, NULL, NULL, "iter" #modifier); \
+ if (l_ != NULL) { \
+ for (modifier listitem_T *li = l_->lv_first; \
+ li != NULL; li = li->li_next) { \
+ code \
+ } \
+ } \
+ } while (0)
+
+/// Iterate over a list
+///
+/// To be used when you need to modify list or values you iterate over, use
+/// #TV_LIST_ITER_CONST if you don’t.
+///
+/// @param[in] l List to iterate over.
+/// @param li Name of the variable with current listitem_T entry.
+/// @param code Cycle body.
+#define TV_LIST_ITER(l, li, code) \
+ _TV_LIST_ITER_MOD(, l, li, code)
+
+/// Iterate over a list
+///
+/// To be used when you don’t need to modify list or values you iterate over,
+/// use #TV_LIST_ITER if you do.
+///
+/// @param[in] l List to iterate over.
+/// @param li Name of the variable with current listitem_T entry.
+/// @param code Cycle body.
+#define TV_LIST_ITER_CONST(l, li, code) \
+ _TV_LIST_ITER_MOD(const, l, li, code)
+
+// Below macros are macros to avoid duplicating code for functionally identical
+// const and non-const function variants.
+
+/// Get typval_T out of list item
+///
+/// @param[in] li List item to get typval_T from, must not be NULL.
+///
+/// @return Pointer to typval_T.
+#define TV_LIST_ITEM_TV(li) (&(li)->li_tv)
+
+/// Get next list item given the current one
+///
+/// @param[in] l List to get item from.
+/// @param[in] li List item to get typval_T from.
+///
+/// @return Pointer to the next item or NULL.
+#define TV_LIST_ITEM_NEXT(l, li) ((li)->li_next)
+
+/// Get previous list item given the current one
+///
+/// @param[in] l List to get item from.
+/// @param[in] li List item to get typval_T from.
+///
+/// @return Pointer to the previous item or NULL.
+#define TV_LIST_ITEM_PREV(l, li) ((li)->li_prev)
+// List argument is not used currently, but it is a must for lists implemented
+// as a pair (size(in list), array) without terminator - basically for lists on
+// top of kvec.
+
+/// Iterate over a dictionary
+///
+/// @param[in] d Dictionary to iterate over.
+/// @param di Name of the variable with current dictitem_T entry.
+/// @param code Cycle body.
+#define TV_DICT_ITER(d, di, code) \
+ HASHTAB_ITER(&(d)->dv_hashtab, di##hi_, { \
+ { \
+ dictitem_T *const di = TV_DICT_HI2DI(di##hi_); \
+ { \
+ code \
+ } \
+ } \
+ })
+
+static inline bool tv_get_float_chk(const typval_T *const tv,
+ float_T *const ret_f)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT;
+
+// FIXME circular dependency, cannot import message.h.
+bool emsgf(const char *const fmt, ...);
+
+/// Get the float value
+///
+/// Raises an error if object is not number or floating-point.
+///
+/// @param[in] tv VimL object to get value from.
+/// @param[out] ret_f Location where resulting float is stored.
+///
+/// @return true in case of success, false if tv is not a number or float.
+static inline bool tv_get_float_chk(const typval_T *const tv,
+ float_T *const ret_f)
+{
+ if (tv->v_type == VAR_FLOAT) {
+ *ret_f = tv->vval.v_float;
+ return true;
+ }
+ if (tv->v_type == VAR_NUMBER) {
+ *ret_f = (float_T)tv->vval.v_number;
+ return true;
+ }
+ emsgf(_("E808: Number or Float required"));
+ return false;
+}
+
+static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_NONNULL_RET REAL_FATTR_PURE
+ REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE;
+
+/// Compute the `DictWatcher` address from a QUEUE node.
+///
+/// This only exists for .asan-blacklist (ASAN doesn't handle QUEUE_DATA pointer
+/// arithmetic).
+static inline DictWatcher *tv_dict_watcher_node_data(QUEUE *q)
+{
+ return QUEUE_DATA(q, DictWatcher, node);
+}
+
+static inline bool tv_is_func(const typval_T tv)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_CONST;
+
+/// Check whether given typval_T contains a function
+///
+/// That is, whether it contains VAR_FUNC or VAR_PARTIAL.
+///
+/// @param[in] tv Typval to check.
+///
+/// @return True if it is a function or a partial, false otherwise.
+static inline bool tv_is_func(const typval_T tv)
+{
+ return tv.v_type == VAR_FUNC || tv.v_type == VAR_PARTIAL;
+}
+
+/// Specify that argument needs to be translated
+///
+/// Used for size_t length arguments to avoid calling gettext() and strlen()
+/// unless needed.
+#define TV_TRANSLATE (SIZE_MAX)
+
+/// Specify that argument is a NUL-terminated C string
+///
+/// Used for size_t length arguments to avoid calling strlen() unless needed.
+#define TV_CSTRING (SIZE_MAX - 1)
+
+#ifdef UNIT_TESTING
+// Do not use enum constants, see commit message.
+EXTERN const size_t kTVCstring INIT(= TV_CSTRING);
+EXTERN const size_t kTVTranslate INIT(= TV_TRANSLATE);
+#endif
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "eval/typval.h.generated.h"
+#endif
+#endif // NVIM_EVAL_TYPVAL_H
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
new file mode 100644
index 0000000000..623bdfc93b
--- /dev/null
+++ b/src/nvim/eval/typval_encode.c.h
@@ -0,0 +1,846 @@
+/// @file eval/typval_encode.c.h
+///
+/// Contains set of macros used to convert (possibly recursive) typval_T into
+/// something else. For these macros to work the following macros must be
+/// defined:
+
+/// @def TYPVAL_ENCODE_CONV_NIL
+/// @brief Macros used to convert NIL value
+///
+/// Is called both for special dictionary (unless #TYPVAL_ENCODE_ALLOW_SPECIALS
+/// is false) and `v:null`.
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL. May
+/// point to special dictionary.
+
+/// @def TYPVAL_ENCODE_CONV_BOOL
+/// @brief Macros used to convert boolean value
+///
+/// Is called both for special dictionary (unless #TYPVAL_ENCODE_ALLOW_SPECIALS
+/// is false) and `v:true`/`v:false`.
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL. May
+/// point to a special dictionary.
+/// @param num Boolean value to convert. Value is an expression which
+/// evaluates to some integer.
+
+/// @def TYPVAL_ENCODE_CONV_NUMBER
+/// @brief Macros used to convert integer
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL. May
+/// point to a special dictionary.
+/// @param num Integer to convert, must accept both varnumber_T and int64_t.
+
+/// @def TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
+/// @brief Macros used to convert unsigned integer
+///
+/// Not used if #TYPVAL_ENCODE_ALLOW_SPECIALS is false, but still must be
+/// defined.
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL. Points
+/// to a special dictionary.
+/// @param num Integer to convert, must accept uint64_t.
+
+/// @def TYPVAL_ENCODE_CONV_FLOAT
+/// @brief Macros used to convert floating-point number
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL. May
+/// point to a special dictionary.
+/// @param flt Number to convert, must accept float_T.
+
+/// @def TYPVAL_ENCODE_CONV_STRING
+/// @brief Macros used to convert plain string
+///
+/// Is used to convert VAR_STRING objects as well as BIN strings represented as
+/// special dictionary.
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL. May
+/// point to a special dictionary.
+/// @param buf String to convert. Is a char[] buffer, not NUL-terminated.
+/// @param len String length.
+
+/// @def TYPVAL_ENCODE_CONV_STR_STRING
+/// @brief Like #TYPVAL_ENCODE_CONV_STRING, but for STR strings
+///
+/// Is used to convert dictionary keys and STR strings represented as special
+/// dictionaries.
+///
+/// @param tv Pointer to typval where value is stored. May be NULL. May
+/// point to a special dictionary.
+/// @param buf String to convert. Is a char[] buffer, not NUL-terminated.
+/// @param len String length.
+
+/// @def TYPVAL_ENCODE_CONV_EXT_STRING
+/// @brief Macros used to convert EXT string
+///
+/// Is used to convert EXT strings represented as special dictionaries. Never
+/// actually used if #TYPVAL_ENCODE_ALLOW_SPECIALS is false, but still must be
+/// defined.
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL. Points
+/// to a special dictionary.
+/// @param buf String to convert. Is a char[] buffer, not NUL-terminated.
+/// @param len String length.
+/// @param type EXT type.
+
+/// @def TYPVAL_ENCODE_CONV_FUNC_START
+/// @brief Macros used when starting to convert a funcref or a partial
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL.
+/// @param fun Function name. May be NULL.
+
+/// @def TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
+/// @brief Macros used before starting to convert partial arguments
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL.
+/// @param len Number of arguments. Zero for absent arguments or when
+/// converting a funcref.
+
+/// @def TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
+/// @brief Macros used before starting to convert self dictionary
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL.
+/// @param len Number of arguments. May be zero for empty dictionary or -1 for
+/// missing self dictionary, also when converting function
+/// reference.
+
+/// @def TYPVAL_ENCODE_CONV_FUNC_END
+/// @brief Macros used after converting a funcref or a partial
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL.
+
+/// @def TYPVAL_ENCODE_CONV_EMPTY_LIST
+/// @brief Macros used to convert an empty list
+///
+/// @param tv Pointer to typval where value is stored. May not be NULL.
+
+/// @def TYPVAL_ENCODE_CONV_EMPTY_DICT
+/// @brief Macros used to convert an empty dictionary
+///
+/// @param tv Pointer to typval where value is stored. May be NULL. May
+/// point to a special dictionary.
+/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR
+/// (for dictionaries represented as special lists).
+
+/// @def TYPVAL_ENCODE_CONV_LIST_START
+/// @brief Macros used before starting to convert non-empty list
+///
+/// @param tv Pointer to typval where value is stored. May be NULL. May
+/// point to a special dictionary.
+/// @param len List length. Is an expression which evaluates to an integer.
+
+/// @def TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
+/// @brief Macros used after pushing list onto the stack
+///
+/// Only used for real list_T* lists, not for special dictionaries or partial
+/// arguments.
+///
+/// @param tv Pointer to typval where value is stored. May be NULL. May
+/// point to a special dictionary.
+/// @param mpsv Pushed MPConvStackVal value.
+
+/// @def TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
+/// @brief Macros used after finishing converting non-last list item
+///
+/// @param tv Pointer to typval where list is stored. May be NULL.
+
+/// @def TYPVAL_ENCODE_CONV_LIST_END
+/// @brief Macros used after converting non-empty list
+///
+/// @param tv Pointer to typval where list is stored. May be NULL.
+
+/// @def TYPVAL_ENCODE_CONV_DICT_START
+/// @brief Macros used before starting to convert non-empty dictionary
+///
+/// Only used for real dict_T* dictionaries, not for special dictionaries. Also
+/// used for partial self dictionary.
+///
+/// @param tv Pointer to typval where dictionary is stored. May be NULL. May
+/// point to a special dictionary.
+/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR
+/// (for dictionaries represented as special lists).
+/// @param len Dictionary length. Is an expression which evaluates to an
+/// integer.
+
+/// @def TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
+/// @brief Macros used after pushing dictionary onto the stack
+///
+/// @param tv Pointer to typval where dictionary is stored. May be NULL.
+/// May not point to a special dictionary.
+/// @param dict Converted dictionary, lvalue.
+/// @param mpsv Pushed MPConvStackVal value.
+
+/// @def TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
+/// @brief Macros used to check special dictionary key
+///
+/// @param label Label for goto in case check was not successfull.
+/// @param key typval_T key to check.
+
+/// @def TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
+/// @brief Macros used after finishing converting dictionary key
+///
+/// @param tv Pointer to typval where dictionary is stored. May be NULL. May
+/// point to a special dictionary.
+/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR
+/// (for dictionaries represented as special lists).
+
+/// @def TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
+/// @brief Macros used after finishing converting non-last dictionary value
+///
+/// @param tv Pointer to typval where dictionary is stored. May be NULL. May
+/// point to a special dictionary.
+/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR
+/// (for dictionaries represented as special lists).
+
+/// @def TYPVAL_ENCODE_CONV_DICT_END
+/// @brief Macros used after converting non-empty dictionary
+///
+/// @param tv Pointer to typval where dictionary is stored. May be NULL. May
+/// point to a special dictionary.
+/// @param dict Converted dictionary, lvalue or #TYPVAL_ENCODE_NODICT_VAR
+/// (for dictionaries represented as special lists).
+
+/// @def TYPVAL_ENCODE_CONV_RECURSE
+/// @brief Macros used when self-containing container is detected
+///
+/// @param val Container for which this situation was detected.
+/// @param conv_type Type of the stack entry, @see MPConvStackValType.
+
+/// @def TYPVAL_ENCODE_ALLOW_SPECIALS
+/// @brief Macros that specifies whether special dictionaries are special
+///
+/// Must be something that evaluates to boolean, most likely `true` or `false`.
+/// If it is false then special dictionaries are not treated specially.
+
+/// @def TYPVAL_ENCODE_SCOPE
+/// @brief Scope of the main function: either nothing or `static`
+
+/// @def TYPVAL_ENCODE_NAME
+/// @brief Name of the target converter
+///
+/// After including this file it will define function
+/// `encode_vim_to_{TYPVAL_ENCODE_NAME}` with scope #TYPVAL_ENCODE_SCOPE and
+/// static functions `_typval_encode_{TYPVAL_ENCODE_NAME}_convert_one_value` and
+/// `_typval_encode_{TYPVAL_ENCODE_NAME}_check_self_reference`.
+
+/// @def TYPVAL_ENCODE_FIRST_ARG_TYPE
+/// @brief Type of the first argument, which will be used to return the results
+///
+/// Is expected to be a pointer type.
+
+/// @def TYPVAL_ENCODE_FIRST_ARG_NAME
+/// @brief Name of the first argument
+///
+/// This name will only be used by one of the above macros which are defined by
+/// the caller. Functions defined here do not use first argument directly.
+#include <stddef.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#include "nvim/lib/kvec.h"
+#include "nvim/eval/typval.h"
+#include "nvim/eval/encode.h"
+#include "nvim/func_attr.h"
+#include "nvim/eval/typval_encode.h"
+
+/// Dummy variable used because some macros need lvalue
+///
+/// Must not be written to, if needed one must check that address of the
+/// macros argument is (not) equal to `&TYPVAL_ENCODE_NODICT_VAR`.
+const dict_T *const TYPVAL_ENCODE_NODICT_VAR = NULL;
+
+static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ void *const val, int *const val_copyID,
+ const MPConvStack *const mpstack, const int copyID,
+ const MPConvStackValType conv_type,
+ const char *const objname)
+ REAL_FATTR_NONNULL_ARG(2, 3, 4, 7) REAL_FATTR_WARN_UNUSED_RESULT
+ REAL_FATTR_ALWAYS_INLINE;
+
+/// Function for checking whether container references itself
+///
+/// @param TYPVAL_ENCODE_FIRST_ARG_NAME First argument.
+/// @param[in,out] val Container to check.
+/// @param val_copyID Pointer to the container attribute that holds copyID.
+/// After checking whether value of this attribute is
+/// copyID (variable) it is set to copyID.
+/// @param[in] mpstack Stack with values to convert. Read-only, used for error
+/// reporting.
+/// @param[in] copyID CopyID used by the caller.
+/// @param[in] conv_type Type of the conversion, @see MPConvStackValType.
+/// @param[in] objname Object name, used for error reporting.
+///
+/// @return NOTDONE in case of success, what to return in case of failure.
+static inline int _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ void *const val, int *const val_copyID,
+ const MPConvStack *const mpstack, const int copyID,
+ const MPConvStackValType conv_type,
+ const char *const objname)
+{
+ if (*val_copyID == copyID) {
+ TYPVAL_ENCODE_CONV_RECURSE(val, conv_type);
+ return OK;
+ }
+ *val_copyID = copyID;
+ return NOTDONE;
+}
+
+static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv,
+ typval_T *const tv, const int copyID,
+ const char *const objname)
+ REAL_FATTR_NONNULL_ARG(2, 4, 6) REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Convert single value
+///
+/// Only scalar values are converted immediately, everything else is pushed onto
+/// the stack.
+///
+/// @param TYPVAL_ENCODE_FIRST_ARG_NAME First argument, defined by the
+/// includer. Only meaningful to macros
+/// defined by the includer.
+/// @param mpstack Stack with values to convert. Values which are not
+/// converted completely by this function (i.e.
+/// non-scalars) are pushed here.
+/// @param cur_mpsv Currently converted value from stack.
+/// @param tv Converted value.
+/// @param[in] copyID CopyID.
+/// @param[in] objname Object name, used for error reporting.
+///
+/// @return OK in case of success, FAIL in case of failure.
+static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ MPConvStack *const mpstack, MPConvStackVal *const cur_mpsv,
+ typval_T *const tv, const int copyID,
+ const char *const objname)
+{
+ switch (tv->v_type) {
+ case VAR_STRING: {
+ TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv));
+ break;
+ }
+ case VAR_NUMBER: {
+ TYPVAL_ENCODE_CONV_NUMBER(tv, tv->vval.v_number);
+ break;
+ }
+ case VAR_FLOAT: {
+ TYPVAL_ENCODE_CONV_FLOAT(tv, tv->vval.v_float);
+ break;
+ }
+ case VAR_FUNC: {
+ TYPVAL_ENCODE_CONV_FUNC_START(tv, tv->vval.v_string);
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, 0);
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
+ TYPVAL_ENCODE_CONV_FUNC_END(tv);
+ break;
+ }
+ case VAR_PARTIAL: {
+ partial_T *const pt = tv->vval.v_partial;
+ (void)pt;
+ TYPVAL_ENCODE_CONV_FUNC_START( // -V547
+ tv, (pt == NULL ? NULL : partial_name(pt)));
+ _mp_push(*mpstack, ((MPConvStackVal) { // -V779
+ .type = kMPConvPartial,
+ .tv = tv,
+ .saved_copyID = copyID - 1,
+ .data = {
+ .p = {
+ .stage = kMPConvPartialArgs,
+ .pt = tv->vval.v_partial,
+ },
+ },
+ }));
+ break;
+ }
+ case VAR_LIST: {
+ if (tv->vval.v_list == NULL || tv_list_len(tv->vval.v_list) == 0) {
+ TYPVAL_ENCODE_CONV_EMPTY_LIST(tv);
+ break;
+ }
+ const int saved_copyID = tv_list_copyid(tv->vval.v_list);
+ _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, copyID,
+ kMPConvList);
+ TYPVAL_ENCODE_CONV_LIST_START(tv, tv_list_len(tv->vval.v_list));
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
+ _mp_push(*mpstack, ((MPConvStackVal) {
+ .type = kMPConvList,
+ .tv = tv,
+ .saved_copyID = saved_copyID,
+ .data = {
+ .l = {
+ .list = tv->vval.v_list,
+ .li = tv_list_first(tv->vval.v_list),
+ },
+ },
+ }));
+ TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack));
+ break;
+ }
+ case VAR_SPECIAL: {
+ switch (tv->vval.v_special) {
+ case kSpecialVarNull: {
+ TYPVAL_ENCODE_CONV_NIL(tv);
+ break;
+ }
+ case kSpecialVarTrue:
+ case kSpecialVarFalse: {
+ TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_special == kSpecialVarTrue);
+ break;
+ }
+ }
+ break;
+ }
+ case VAR_DICT: {
+ if (tv->vval.v_dict == NULL
+ || tv->vval.v_dict->dv_hashtab.ht_used == 0) {
+ TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, tv->vval.v_dict);
+ break;
+ }
+ const dictitem_T *type_di;
+ const dictitem_T *val_di;
+ if (TYPVAL_ENCODE_ALLOW_SPECIALS
+ && tv->vval.v_dict->dv_hashtab.ht_used == 2
+ && (type_di = tv_dict_find((dict_T *)tv->vval.v_dict,
+ S_LEN("_TYPE"))) != NULL
+ && type_di->di_tv.v_type == VAR_LIST
+ && (val_di = tv_dict_find((dict_T *)tv->vval.v_dict,
+ S_LEN("_VAL"))) != NULL) {
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) {
+ if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) {
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(eval_msgpack_type_lists)) {
+ goto _convert_one_value_regular_dict;
+ }
+ switch ((MessagePackType)i) {
+ case kMPNil: {
+ TYPVAL_ENCODE_CONV_NIL(tv);
+ break;
+ }
+ case kMPBoolean: {
+ if (val_di->di_tv.v_type != VAR_NUMBER) {
+ goto _convert_one_value_regular_dict;
+ }
+ TYPVAL_ENCODE_CONV_BOOL(tv, val_di->di_tv.vval.v_number);
+ break;
+ }
+ case kMPInteger: {
+ const list_T *val_list;
+ varnumber_T sign;
+ varnumber_T highest_bits;
+ varnumber_T high_bits;
+ varnumber_T low_bits;
+ // List of 4 integers; first is signed (should be 1 or -1, but
+ // this is not checked), second is unsigned and have at most
+ // one (sign is -1) or two (sign is 1) non-zero bits (number of
+ // bits is not checked), other unsigned and have at most 31
+ // non-zero bits (number of bits is not checked).
+ if (val_di->di_tv.v_type != VAR_LIST
+ || tv_list_len(val_list = val_di->di_tv.vval.v_list) != 4) {
+ goto _convert_one_value_regular_dict;
+ }
+
+ const listitem_T *const sign_li = tv_list_first(val_list);
+ if (TV_LIST_ITEM_TV(sign_li)->v_type != VAR_NUMBER
+ || (sign = TV_LIST_ITEM_TV(sign_li)->vval.v_number) == 0) {
+ goto _convert_one_value_regular_dict;
+ }
+
+ const listitem_T *const highest_bits_li = (
+ TV_LIST_ITEM_NEXT(val_list, sign_li));
+ if (TV_LIST_ITEM_TV(highest_bits_li)->v_type != VAR_NUMBER
+ || ((highest_bits
+ = TV_LIST_ITEM_TV(highest_bits_li)->vval.v_number)
+ < 0)) {
+ goto _convert_one_value_regular_dict;
+ }
+
+ const listitem_T *const high_bits_li = (
+ TV_LIST_ITEM_NEXT(val_list, highest_bits_li));
+ if (TV_LIST_ITEM_TV(high_bits_li)->v_type != VAR_NUMBER
+ || ((high_bits = TV_LIST_ITEM_TV(high_bits_li)->vval.v_number)
+ < 0)) {
+ goto _convert_one_value_regular_dict;
+ }
+
+ const listitem_T *const low_bits_li = tv_list_last(val_list);
+ if (TV_LIST_ITEM_TV(low_bits_li)->v_type != VAR_NUMBER
+ || ((low_bits = TV_LIST_ITEM_TV(low_bits_li)->vval.v_number)
+ < 0)) {
+ goto _convert_one_value_regular_dict;
+ }
+
+ const uint64_t number = ((uint64_t)(((uint64_t)highest_bits) << 62)
+ | (uint64_t)(((uint64_t)high_bits) << 31)
+ | (uint64_t)low_bits);
+ if (sign > 0) {
+ TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, number);
+ } else {
+ TYPVAL_ENCODE_CONV_NUMBER(tv, -number);
+ }
+ break;
+ }
+ case kMPFloat: {
+ if (val_di->di_tv.v_type != VAR_FLOAT) {
+ goto _convert_one_value_regular_dict;
+ }
+ TYPVAL_ENCODE_CONV_FLOAT(tv, val_di->di_tv.vval.v_float);
+ break;
+ }
+ case kMPString:
+ case kMPBinary: {
+ const bool is_string = ((MessagePackType)i == kMPString);
+ if (val_di->di_tv.v_type != VAR_LIST) {
+ goto _convert_one_value_regular_dict;
+ }
+ size_t len;
+ char *buf;
+ if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len,
+ &buf)) {
+ goto _convert_one_value_regular_dict;
+ }
+ if (is_string) {
+ TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len);
+ } else { // -V523
+ TYPVAL_ENCODE_CONV_STRING(tv, buf, len);
+ }
+ xfree(buf);
+ break;
+ }
+ case kMPArray: {
+ if (val_di->di_tv.v_type != VAR_LIST) {
+ goto _convert_one_value_regular_dict;
+ }
+ const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list);
+ _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list,
+ lv_copyID, copyID,
+ kMPConvList);
+ TYPVAL_ENCODE_CONV_LIST_START(
+ tv, tv_list_len(val_di->di_tv.vval.v_list));
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
+ _mp_push(*mpstack, ((MPConvStackVal) {
+ .tv = tv,
+ .type = kMPConvList,
+ .saved_copyID = saved_copyID,
+ .data = {
+ .l = {
+ .list = val_di->di_tv.vval.v_list,
+ .li = tv_list_first(val_di->di_tv.vval.v_list),
+ },
+ },
+ }));
+ break;
+ }
+ case kMPMap: {
+ if (val_di->di_tv.v_type != VAR_LIST) {
+ goto _convert_one_value_regular_dict;
+ }
+ list_T *const val_list = val_di->di_tv.vval.v_list;
+ if (val_list == NULL || tv_list_len(val_list) == 0) {
+ TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501
+ tv, TYPVAL_ENCODE_NODICT_VAR);
+ break;
+ }
+ TV_LIST_ITER_CONST(val_list, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST
+ || tv_list_len(TV_LIST_ITEM_TV(li)->vval.v_list) != 2) {
+ goto _convert_one_value_regular_dict;
+ }
+ });
+ const int saved_copyID = tv_list_copyid(val_di->di_tv.vval.v_list);
+ _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val_list, lv_copyID, copyID,
+ kMPConvPairs);
+ TYPVAL_ENCODE_CONV_DICT_START(tv, TYPVAL_ENCODE_NODICT_VAR,
+ tv_list_len(val_list));
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
+ _mp_push(*mpstack, ((MPConvStackVal) {
+ .tv = tv,
+ .type = kMPConvPairs,
+ .saved_copyID = saved_copyID,
+ .data = {
+ .l = {
+ .list = val_list,
+ .li = tv_list_first(val_list),
+ },
+ },
+ }));
+ break;
+ }
+ case kMPExt: {
+ const list_T *val_list;
+ varnumber_T type;
+ if (val_di->di_tv.v_type != VAR_LIST
+ || tv_list_len((val_list = val_di->di_tv.vval.v_list)) != 2
+ || (TV_LIST_ITEM_TV(tv_list_first(val_list))->v_type
+ != VAR_NUMBER)
+ || ((type
+ = TV_LIST_ITEM_TV(tv_list_first(val_list))->vval.v_number)
+ > INT8_MAX)
+ || type < INT8_MIN
+ || (TV_LIST_ITEM_TV(tv_list_last(val_list))->v_type
+ != VAR_LIST)) {
+ goto _convert_one_value_regular_dict;
+ }
+ size_t len;
+ char *buf;
+ if (!(
+ encode_vim_list_to_buf(
+ TV_LIST_ITEM_TV(tv_list_last(val_list))->vval.v_list, &len,
+ &buf))) {
+ goto _convert_one_value_regular_dict;
+ }
+ TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type);
+ xfree(buf);
+ break;
+ }
+ }
+ break;
+ }
+_convert_one_value_regular_dict: {}
+ const int saved_copyID = tv->vval.v_dict->dv_copyID;
+ _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, copyID,
+ kMPConvDict);
+ TYPVAL_ENCODE_CONV_DICT_START(tv, tv->vval.v_dict,
+ tv->vval.v_dict->dv_hashtab.ht_used);
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
+ _mp_push(*mpstack, ((MPConvStackVal) {
+ .tv = tv,
+ .type = kMPConvDict,
+ .saved_copyID = saved_copyID,
+ .data = {
+ .d = {
+ .dict = tv->vval.v_dict,
+ .dictp = &tv->vval.v_dict,
+ .hi = tv->vval.v_dict->dv_hashtab.ht_array,
+ .todo = tv->vval.v_dict->dv_hashtab.ht_used,
+ },
+ },
+ }));
+ TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, tv->vval.v_dict,
+ _mp_last(*mpstack));
+ break;
+ }
+ case VAR_UNKNOWN: {
+ internal_error(STR(_TYPVAL_ENCODE_CONVERT_ONE_VALUE) "()");
+ return FAIL;
+ }
+ }
+typval_encode_stop_converting_one_item:
+ return OK;
+ // Prevent “unused label†warnings.
+ goto typval_encode_stop_converting_one_item; // -V779
+}
+
+TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ typval_T *const tv, const char *const objname)
+ REAL_FATTR_NONNULL_ARG(2, 3) REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Convert the whole typval
+///
+/// @param TYPVAL_ENCODE_FIRST_ARG_NAME First argument, defined by the
+/// includer. Only meaningful to macros
+/// defined by the includer.
+/// @param top_tv Converted value.
+/// @param[in] objname Object name, used for error reporting.
+///
+/// @return OK in case of success, FAIL in case of failure.
+TYPVAL_ENCODE_SCOPE int _TYPVAL_ENCODE_ENCODE(
+ TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME,
+ typval_T *const top_tv, const char *const objname)
+{
+ const int copyID = get_copyID();
+ MPConvStack mpstack;
+ _mp_init(mpstack);
+ if (_TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack,
+ NULL,
+ top_tv, copyID, objname)
+ == FAIL) {
+ goto encode_vim_to__error_ret;
+ }
+/// Label common for this and convert_one_value functions, used for escaping
+/// from macros like TYPVAL_ENCODE_CONV_DICT_START.
+typval_encode_stop_converting_one_item:
+ while (_mp_size(mpstack)) {
+ MPConvStackVal *cur_mpsv = &_mp_last(mpstack);
+ typval_T *tv = NULL;
+ switch (cur_mpsv->type) {
+ case kMPConvDict: {
+ if (!cur_mpsv->data.d.todo) {
+ (void)_mp_pop(mpstack);
+ cur_mpsv->data.d.dict->dv_copyID = cur_mpsv->saved_copyID;
+ TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, *cur_mpsv->data.d.dictp);
+ continue;
+ } else if (cur_mpsv->data.d.todo
+ != cur_mpsv->data.d.dict->dv_hashtab.ht_used) {
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(cur_mpsv->tv,
+ *cur_mpsv->data.d.dictp);
+ }
+ while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) {
+ cur_mpsv->data.d.hi++;
+ }
+ dictitem_T *const di = TV_DICT_HI2DI(cur_mpsv->data.d.hi);
+ cur_mpsv->data.d.todo--;
+ cur_mpsv->data.d.hi++;
+ TYPVAL_ENCODE_CONV_STR_STRING(NULL, &di->di_key[0],
+ strlen((char *)&di->di_key[0]));
+ TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv,
+ *cur_mpsv->data.d.dictp);
+ tv = &di->di_tv;
+ break;
+ }
+ case kMPConvList: {
+ if (cur_mpsv->data.l.li == NULL) {
+ (void)_mp_pop(mpstack);
+ tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID);
+ TYPVAL_ENCODE_CONV_LIST_END(cur_mpsv->tv);
+ continue;
+ } else if (cur_mpsv->data.l.li
+ != tv_list_first(cur_mpsv->data.l.list)) {
+ TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(cur_mpsv->tv);
+ }
+ tv = TV_LIST_ITEM_TV(cur_mpsv->data.l.li);
+ cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list,
+ cur_mpsv->data.l.li);
+ break;
+ }
+ case kMPConvPairs: {
+ if (cur_mpsv->data.l.li == NULL) {
+ (void)_mp_pop(mpstack);
+ tv_list_set_copyid(cur_mpsv->data.l.list, cur_mpsv->saved_copyID);
+ TYPVAL_ENCODE_CONV_DICT_END(cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
+ continue;
+ } else if (cur_mpsv->data.l.li
+ != tv_list_first(cur_mpsv->data.l.list)) {
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(
+ cur_mpsv->tv, TYPVAL_ENCODE_NODICT_VAR);
+ }
+ const list_T *const kv_pair = (
+ TV_LIST_ITEM_TV(cur_mpsv->data.l.li)->vval.v_list);
+ TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(
+ encode_vim_to__error_ret, *TV_LIST_ITEM_TV(tv_list_first(kv_pair)));
+ if (
+ _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
+ TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack, cur_mpsv,
+ TV_LIST_ITEM_TV(tv_list_first(kv_pair)), copyID, objname)
+ == FAIL) {
+ goto encode_vim_to__error_ret;
+ }
+ TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(cur_mpsv->tv,
+ TYPVAL_ENCODE_NODICT_VAR);
+ tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair));
+ cur_mpsv->data.l.li = TV_LIST_ITEM_NEXT(cur_mpsv->data.l.list,
+ cur_mpsv->data.l.li);
+ break;
+ }
+ case kMPConvPartial: {
+ partial_T *const pt = cur_mpsv->data.p.pt;
+ tv = cur_mpsv->tv;
+ (void)tv;
+ switch (cur_mpsv->data.p.stage) {
+ case kMPConvPartialArgs: {
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv,
+ pt == NULL ? 0 : pt->pt_argc);
+ cur_mpsv->data.p.stage = kMPConvPartialSelf;
+ if (pt != NULL && pt->pt_argc > 0) {
+ TYPVAL_ENCODE_CONV_LIST_START(NULL, pt->pt_argc);
+ _mp_push(mpstack, ((MPConvStackVal) {
+ .type = kMPConvPartialList,
+ .tv = NULL,
+ .saved_copyID = copyID - 1,
+ .data = {
+ .a = {
+ .arg = pt->pt_argv,
+ .argv = pt->pt_argv,
+ .todo = (size_t)pt->pt_argc,
+ },
+ },
+ }));
+ }
+ break;
+ }
+ case kMPConvPartialSelf: {
+ cur_mpsv->data.p.stage = kMPConvPartialEnd;
+ dict_T *const dict = pt == NULL ? NULL : pt->pt_dict;
+ if (dict != NULL) {
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, dict->dv_hashtab.ht_used);
+ if (dict->dv_hashtab.ht_used == 0) {
+ TYPVAL_ENCODE_CONV_EMPTY_DICT(NULL, pt->pt_dict);
+ continue;
+ }
+ const int saved_copyID = dict->dv_copyID;
+ const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(
+ TYPVAL_ENCODE_FIRST_ARG_NAME,
+ dict, &dict->dv_copyID, &mpstack, copyID, kMPConvDict,
+ objname);
+ if (te_csr_ret != NOTDONE) {
+ if (te_csr_ret == FAIL) {
+ goto encode_vim_to__error_ret;
+ } else {
+ continue;
+ }
+ }
+ TYPVAL_ENCODE_CONV_DICT_START(NULL, pt->pt_dict,
+ dict->dv_hashtab.ht_used);
+ assert(saved_copyID != copyID && saved_copyID != copyID - 1);
+ _mp_push(mpstack, ((MPConvStackVal) {
+ .type = kMPConvDict,
+ .tv = NULL,
+ .saved_copyID = saved_copyID,
+ .data = {
+ .d = {
+ .dict = dict,
+ .dictp = &pt->pt_dict,
+ .hi = dict->dv_hashtab.ht_array,
+ .todo = dict->dv_hashtab.ht_used,
+ },
+ },
+ }));
+ TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(NULL, pt->pt_dict,
+ _mp_last(mpstack));
+ } else {
+ TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, -1);
+ }
+ break;
+ }
+ case kMPConvPartialEnd: {
+ TYPVAL_ENCODE_CONV_FUNC_END(tv);
+ (void)_mp_pop(mpstack);
+ break;
+ }
+ }
+ continue;
+ }
+ case kMPConvPartialList: {
+ if (!cur_mpsv->data.a.todo) {
+ (void)_mp_pop(mpstack);
+ TYPVAL_ENCODE_CONV_LIST_END(NULL);
+ continue;
+ } else if (cur_mpsv->data.a.argv != cur_mpsv->data.a.arg) {
+ TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(NULL);
+ }
+ tv = cur_mpsv->data.a.arg++;
+ cur_mpsv->data.a.todo--;
+ break;
+ }
+ }
+ assert(tv != NULL);
+ if (_TYPVAL_ENCODE_CONVERT_ONE_VALUE(TYPVAL_ENCODE_FIRST_ARG_NAME, &mpstack,
+ cur_mpsv, tv, copyID, objname)
+ == FAIL) {
+ goto encode_vim_to__error_ret;
+ }
+ }
+ _mp_destroy(mpstack);
+ return OK;
+encode_vim_to__error_ret:
+ _mp_destroy(mpstack);
+ return FAIL;
+ // Prevent “unused label†warnings.
+ goto typval_encode_stop_converting_one_item; // -V779
+}
diff --git a/src/nvim/eval/typval_encode.h b/src/nvim/eval/typval_encode.h
index 98fa7b26c6..3475f6d8b3 100644
--- a/src/nvim/eval/typval_encode.h
+++ b/src/nvim/eval/typval_encode.h
@@ -1,163 +1,46 @@
-/// @file eval/typval_convert.h
+/// @file eval/typval_encode.h
///
-/// Contains set of macros used to convert (possibly recursive) typval_T into
-/// something else. For these macros to work the following macros must be
-/// defined:
-
-/// @def TYPVAL_ENCODE_CONV_NIL
-/// @brief Macros used to convert NIL value
-///
-/// Is called both for special dictionary (unless #TYPVAL_ENCODE_ALLOW_SPECIALS
-/// is false) and `v:null`. Accepts no arguments, but still must be
-/// a function-like macros.
-
-/// @def TYPVAL_ENCODE_CONV_BOOL
-/// @brief Macros used to convert boolean value
-///
-/// Is called both for special dictionary (unless #TYPVAL_ENCODE_ALLOW_SPECIALS
-/// is false) and `v:true`/`v:false`.
-///
-/// @param num Boolean value to convert. Value is an expression which
-/// evaluates to some integer.
-
-/// @def TYPVAL_ENCODE_CONV_NUMBER
-/// @brief Macros used to convert integer
-///
-/// @param num Integer to convert, must accept both varnumber_T and int64_t.
-
-/// @def TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
-/// @brief Macros used to convert unsigned integer
-///
-/// Not used if #TYPVAL_ENCODE_ALLOW_SPECIALS is false, but still must be
-/// defined.
-///
-/// @param num Integer to convert, must accept uint64_t.
-
-/// @def TYPVAL_ENCODE_CONV_FLOAT
-/// @brief Macros used to convert floating-point number
-///
-/// @param flt Number to convert, must accept float_T.
-
-/// @def TYPVAL_ENCODE_CONV_STRING
-/// @brief Macros used to convert plain string
-///
-/// Is used to convert VAR_STRING objects as well as BIN strings represented as
-/// special dictionary.
-///
-/// @param buf String to convert. Is a char[] buffer, not NUL-terminated.
-/// @param len String length.
-
-/// @def TYPVAL_ENCODE_CONV_STR_STRING
-/// @brief Like #TYPVAL_ENCODE_CONV_STRING, but for STR strings
-///
-/// Is used to convert dictionary keys and STR strings represented as special
-/// dictionaries.
-
-/// @def TYPVAL_ENCODE_CONV_EXT_STRING
-/// @brief Macros used to convert EXT string
-///
-/// Is used to convert EXT strings represented as special dictionaries. Never
-/// actually used if #TYPVAL_ENCODE_ALLOW_SPECIALS is false, but still must be
-/// defined.
-///
-/// @param buf String to convert. Is a char[] buffer, not NUL-terminated.
-/// @param len String length.
-/// @param type EXT type.
-
-/// @def TYPVAL_ENCODE_CONV_FUNC
-/// @brief Macros used to convert a function reference
-///
-/// @param fun Function name.
-
-/// @def TYPVAL_ENCODE_CONV_EMPTY_LIST
-/// @brief Macros used to convert an empty list
-///
-/// Accepts no arguments, but still must be a function-like macros.
-
-/// @def TYPVAL_ENCODE_CONV_EMPTY_DICT
-/// @brief Macros used to convert an empty dictionary
-///
-/// Accepts no arguments, but still must be a function-like macros.
-
-/// @def TYPVAL_ENCODE_CONV_LIST_START
-/// @brief Macros used before starting to convert non-empty list
-///
-/// @param len List length. Is an expression which evaluates to an integer.
-
-/// @def TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
-/// @brief Macros used after finishing converting non-last list item
-///
-/// Accepts no arguments, but still must be a function-like macros.
-
-/// @def TYPVAL_ENCODE_CONV_LIST_END
-/// @brief Macros used after converting non-empty list
-///
-/// Accepts no arguments, but still must be a function-like macros.
-
-/// @def TYPVAL_ENCODE_CONV_DICT_START
-/// @brief Macros used before starting to convert non-empty dictionary
-///
-/// @param len Dictionary length. Is an expression which evaluates to an
-/// integer.
-
-/// @def TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK
-/// @brief Macros used to check special dictionary key
-///
-/// @param label Label for goto in case check was not successfull.
-/// @param key typval_T key to check.
-
-/// @def TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
-/// @brief Macros used after finishing converting dictionary key
-///
-/// Accepts no arguments, but still must be a function-like macros.
-
-/// @def TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
-/// @brief Macros used after finishing converting non-last dictionary value
-///
-/// Accepts no arguments, but still must be a function-like macros.
-
-/// @def TYPVAL_ENCODE_CONV_DICT_END
-/// @brief Macros used after converting non-empty dictionary
-///
-/// Accepts no arguments, but still must be a function-like macros.
-
-/// @def TYPVAL_ENCODE_CONV_RECURSE
-/// @brief Macros used when self-containing container is detected
-///
-/// @param val Container for which this situation was detected.
-/// @param conv_type Type of the stack entry, @see MPConvStackValType.
-
-/// @def TYPVAL_ENCODE_ALLOW_SPECIALS
-/// @brief Macros that specifies whether special dictionaries are special
-///
-/// Must be something that evaluates to boolean, most likely `true` or `false`.
-/// If it is false then special dictionaries are not treated specially.
+/// Contains common definitions for eval/typval_encode.c.h. Most of time should
+/// not be included directly.
#ifndef NVIM_EVAL_TYPVAL_ENCODE_H
#define NVIM_EVAL_TYPVAL_ENCODE_H
#include <stddef.h>
#include <inttypes.h>
+#include <string.h>
#include <assert.h>
#include "nvim/lib/kvec.h"
-#include "nvim/eval_defs.h"
-#include "nvim/eval/encode.h"
+#include "nvim/eval/typval.h"
#include "nvim/func_attr.h"
/// Type of the stack entry
typedef enum {
- kMPConvDict, ///< Convert dict_T *dictionary.
- kMPConvList, ///< Convert list_T *list.
+ kMPConvDict, ///< Convert dict_T *dictionary.
+ kMPConvList, ///< Convert list_T *list.
kMPConvPairs, ///< Convert mapping represented as a list_T* of pairs.
+ kMPConvPartial, ///< Convert partial_T* partial.
+ kMPConvPartialList, ///< Convert argc/argv pair coming from a partial.
} MPConvStackValType;
+/// Stage at which partial is being converted
+typedef enum {
+ kMPConvPartialArgs, ///< About to convert arguments.
+ kMPConvPartialSelf, ///< About to convert self dictionary.
+ kMPConvPartialEnd, ///< Already converted everything.
+} MPConvPartialStage;
+
/// Structure representing current VimL to messagepack conversion state
typedef struct {
MPConvStackValType type; ///< Type of the stack entry.
typval_T *tv; ///< Currently converted typval_T.
+ int saved_copyID; ///< copyID item used to have.
union {
struct {
dict_T *dict; ///< Currently converted dictionary.
+ dict_T **dictp; ///< Location where that dictionary is stored.
+ ///< Normally it is &.tv->vval.v_dict, but not when
+ ///< converting partials.
hashitem_T *hi; ///< Currently converted dictionary item.
size_t todo; ///< Amount of items left to process.
} d; ///< State of dictionary conversion.
@@ -165,6 +48,15 @@ typedef struct {
list_T *list; ///< Currently converted list.
listitem_T *li; ///< Currently converted list item.
} l; ///< State of list or generic mapping conversion.
+ struct {
+ MPConvPartialStage stage; ///< Stage at which partial is being converted.
+ partial_T *pt; ///< Currently converted partial.
+ } p; ///< State of partial conversion.
+ struct {
+ typval_T *arg; ///< Currently converted argument.
+ typval_T *argv; ///< Start of the argument list.
+ size_t todo; ///< Number of items left to process.
+ } a; ///< State of list or generic mapping conversion.
} data; ///< Data to convert.
} MPConvStackVal;
@@ -179,21 +71,9 @@ typedef kvec_withinit_t(MPConvStackVal, 8) MPConvStack;
#define _mp_pop kv_pop
#define _mp_last kv_last
-/// Code for checking whether container references itself
-///
-/// @param[in,out] val Container to check.
-/// @param copyID_attr Name of the container attribute that holds copyID.
-/// After checking whether value of this attribute is
-/// copyID (variable) it is set to copyID.
-/// @param conv_type Type of the conversion, @see MPConvStackValType.
-#define _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(val, copyID_attr, conv_type) \
- do { \
- if ((val)->copyID_attr == copyID) { \
- TYPVAL_ENCODE_CONV_RECURSE((val), conv_type); \
- return OK; \
- } \
- (val)->copyID_attr = copyID; \
- } while (0)
+static inline size_t tv_strlen(const typval_T *const tv)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT
+ REAL_FATTR_NONNULL_ALL;
/// Length of the string stored in typval_T
///
@@ -203,8 +83,6 @@ typedef kvec_withinit_t(MPConvStackVal, 8) MPConvStack;
/// @return Length of the string stored in typval_T, including 0 for NULL
/// string.
static inline size_t tv_strlen(const typval_T *const tv)
- FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
- FUNC_ATTR_NONNULL_ALL
{
assert(tv->v_type == VAR_STRING);
return (tv->vval.v_string == NULL
@@ -212,359 +90,57 @@ static inline size_t tv_strlen(const typval_T *const tv)
: strlen((char *) tv->vval.v_string));
}
-/// Define functions which convert VimL value to something else
-///
-/// Creates function `vim_to_{name}(firstargtype firstargname, typval_T *const
-/// tv)` which returns OK or FAIL and helper functions.
+/// Code for checking whether container references itself
///
-/// @param scope Scope of the main function: either nothing or `static`.
-/// @param name Name of the target converter.
-/// @param firstargtype Type of the first argument. It will be used to return
-/// the results.
-/// @param firstargname Name of the first argument.
-#define TYPVAL_ENCODE_DEFINE_CONV_FUNCTIONS(scope, name, firstargtype, \
- firstargname) \
-static int name##_convert_one_value(firstargtype firstargname, \
- MPConvStack *const mpstack, \
- typval_T *const tv, \
- const int copyID, \
- const char *const objname) \
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
-{ \
- switch (tv->v_type) { \
- case VAR_STRING: { \
- TYPVAL_ENCODE_CONV_STRING(tv->vval.v_string, tv_strlen(tv)); \
- break; \
- } \
- case VAR_NUMBER: { \
- TYPVAL_ENCODE_CONV_NUMBER(tv->vval.v_number); \
- break; \
- } \
- case VAR_FLOAT: { \
- TYPVAL_ENCODE_CONV_FLOAT(tv->vval.v_float); \
- break; \
- } \
- case VAR_FUNC: { \
- TYPVAL_ENCODE_CONV_FUNC(tv->vval.v_string); \
- break; \
- } \
- case VAR_LIST: { \
- if (tv->vval.v_list == NULL || tv->vval.v_list->lv_len == 0) { \
- TYPVAL_ENCODE_CONV_EMPTY_LIST(); \
- break; \
- } \
- _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(tv->vval.v_list, lv_copyID, \
- kMPConvList); \
- TYPVAL_ENCODE_CONV_LIST_START(tv->vval.v_list->lv_len); \
- _mp_push(*mpstack, ((MPConvStackVal) { \
- .type = kMPConvList, \
- .tv = tv, \
- .data = { \
- .l = { \
- .list = tv->vval.v_list, \
- .li = tv->vval.v_list->lv_first, \
- }, \
- }, \
- })); \
- break; \
- } \
- case VAR_SPECIAL: { \
- switch (tv->vval.v_special) { \
- case kSpecialVarNull: { \
- TYPVAL_ENCODE_CONV_NIL(); \
- break; \
- } \
- case kSpecialVarTrue: \
- case kSpecialVarFalse: { \
- TYPVAL_ENCODE_CONV_BOOL(tv->vval.v_special == kSpecialVarTrue); \
- break; \
- } \
- } \
- break; \
- } \
- case VAR_DICT: { \
- if (tv->vval.v_dict == NULL \
- || tv->vval.v_dict->dv_hashtab.ht_used == 0) { \
- TYPVAL_ENCODE_CONV_EMPTY_DICT(); \
- break; \
- } \
- const dictitem_T *type_di; \
- const dictitem_T *val_di; \
- if (TYPVAL_ENCODE_ALLOW_SPECIALS \
- && tv->vval.v_dict->dv_hashtab.ht_used == 2 \
- && (type_di = dict_find((dict_T *) tv->vval.v_dict, \
- (char_u *) "_TYPE", -1)) != NULL \
- && type_di->di_tv.v_type == VAR_LIST \
- && (val_di = dict_find((dict_T *) tv->vval.v_dict, \
- (char_u *) "_VAL", -1)) != NULL) { \
- size_t i; \
- for (i = 0; i < ARRAY_SIZE(eval_msgpack_type_lists); i++) { \
- if (type_di->di_tv.vval.v_list == eval_msgpack_type_lists[i]) { \
- break; \
- } \
- } \
- if (i == ARRAY_SIZE(eval_msgpack_type_lists)) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- switch ((MessagePackType) i) { \
- case kMPNil: { \
- TYPVAL_ENCODE_CONV_NIL(); \
- break; \
- } \
- case kMPBoolean: { \
- if (val_di->di_tv.v_type != VAR_NUMBER) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- TYPVAL_ENCODE_CONV_BOOL(val_di->di_tv.vval.v_number); \
- break; \
- } \
- case kMPInteger: { \
- const list_T *val_list; \
- varnumber_T sign; \
- varnumber_T highest_bits; \
- varnumber_T high_bits; \
- varnumber_T low_bits; \
- /* List of 4 integers; first is signed (should be 1 or -1, but */ \
- /* this is not checked), second is unsigned and have at most */ \
- /* one (sign is -1) or two (sign is 1) non-zero bits (number of */ \
- /* bits is not checked), other unsigned and have at most 31 */ \
- /* non-zero bits (number of bits is not checked).*/ \
- if (val_di->di_tv.v_type != VAR_LIST \
- || (val_list = val_di->di_tv.vval.v_list) == NULL \
- || val_list->lv_len != 4 \
- || val_list->lv_first->li_tv.v_type != VAR_NUMBER \
- || (sign = val_list->lv_first->li_tv.vval.v_number) == 0 \
- || val_list->lv_first->li_next->li_tv.v_type != VAR_NUMBER \
- || (highest_bits = \
- val_list->lv_first->li_next->li_tv.vval.v_number) < 0 \
- || val_list->lv_last->li_prev->li_tv.v_type != VAR_NUMBER \
- || (high_bits = \
- val_list->lv_last->li_prev->li_tv.vval.v_number) < 0 \
- || val_list->lv_last->li_tv.v_type != VAR_NUMBER \
- || (low_bits = val_list->lv_last->li_tv.vval.v_number) < 0) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- uint64_t number = ((uint64_t) (((uint64_t) highest_bits) << 62) \
- | (uint64_t) (((uint64_t) high_bits) << 31) \
- | (uint64_t) low_bits); \
- if (sign > 0) { \
- TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(number); \
- } else { \
- TYPVAL_ENCODE_CONV_NUMBER(-number); \
- } \
- break; \
- } \
- case kMPFloat: { \
- if (val_di->di_tv.v_type != VAR_FLOAT) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- TYPVAL_ENCODE_CONV_FLOAT(val_di->di_tv.vval.v_float); \
- break; \
- } \
- case kMPString: \
- case kMPBinary: { \
- const bool is_string = ((MessagePackType) i == kMPString); \
- if (val_di->di_tv.v_type != VAR_LIST) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- size_t len; \
- char *buf; \
- if (!encode_vim_list_to_buf(val_di->di_tv.vval.v_list, &len, \
- &buf)) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- if (is_string) { \
- TYPVAL_ENCODE_CONV_STR_STRING(buf, len); \
- } else { \
- TYPVAL_ENCODE_CONV_STRING(buf, len); \
- } \
- xfree(buf); \
- break; \
- } \
- case kMPArray: { \
- if (val_di->di_tv.v_type != VAR_LIST) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(val_di->di_tv.vval.v_list, \
- lv_copyID, kMPConvList); \
- TYPVAL_ENCODE_CONV_LIST_START(val_di->di_tv.vval.v_list->lv_len); \
- _mp_push(*mpstack, ((MPConvStackVal) { \
- .tv = tv, \
- .type = kMPConvList, \
- .data = { \
- .l = { \
- .list = val_di->di_tv.vval.v_list, \
- .li = val_di->di_tv.vval.v_list->lv_first, \
- }, \
- }, \
- })); \
- break; \
- } \
- case kMPMap: { \
- if (val_di->di_tv.v_type != VAR_LIST) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- list_T *const val_list = val_di->di_tv.vval.v_list; \
- if (val_list == NULL || val_list->lv_len == 0) { \
- TYPVAL_ENCODE_CONV_EMPTY_DICT(); \
- break; \
- } \
- for (const listitem_T *li = val_list->lv_first; li != NULL; \
- li = li->li_next) { \
- if (li->li_tv.v_type != VAR_LIST \
- || li->li_tv.vval.v_list->lv_len != 2) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- } \
- _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(val_list, lv_copyID, \
- kMPConvPairs); \
- TYPVAL_ENCODE_CONV_DICT_START(val_list->lv_len); \
- _mp_push(*mpstack, ((MPConvStackVal) { \
- .tv = tv, \
- .type = kMPConvPairs, \
- .data = { \
- .l = { \
- .list = val_list, \
- .li = val_list->lv_first, \
- }, \
- }, \
- })); \
- break; \
- } \
- case kMPExt: { \
- const list_T *val_list; \
- varnumber_T type; \
- if (val_di->di_tv.v_type != VAR_LIST \
- || (val_list = val_di->di_tv.vval.v_list) == NULL \
- || val_list->lv_len != 2 \
- || (val_list->lv_first->li_tv.v_type != VAR_NUMBER) \
- || (type = val_list->lv_first->li_tv.vval.v_number) > INT8_MAX \
- || type < INT8_MIN \
- || (val_list->lv_last->li_tv.v_type != VAR_LIST)) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- size_t len; \
- char *buf; \
- if (!encode_vim_list_to_buf(val_list->lv_last->li_tv.vval.v_list, \
- &len, &buf)) { \
- goto name##_convert_one_value_regular_dict; \
- } \
- TYPVAL_ENCODE_CONV_EXT_STRING(buf, len, type); \
- xfree(buf); \
- break; \
- } \
- } \
- break; \
- } \
-name##_convert_one_value_regular_dict: \
- _TYPVAL_ENCODE_CHECK_SELF_REFERENCE(tv->vval.v_dict, dv_copyID, \
- kMPConvDict); \
- TYPVAL_ENCODE_CONV_DICT_START(tv->vval.v_dict->dv_hashtab.ht_used); \
- _mp_push(*mpstack, ((MPConvStackVal) { \
- .tv = tv, \
- .type = kMPConvDict, \
- .data = { \
- .d = { \
- .dict = tv->vval.v_dict, \
- .hi = tv->vval.v_dict->dv_hashtab.ht_array, \
- .todo = tv->vval.v_dict->dv_hashtab.ht_used, \
- }, \
- }, \
- })); \
- break; \
- } \
- case VAR_UNKNOWN: { \
- EMSG2(_(e_intern2), #name "_convert_one_value()"); \
- return FAIL; \
- } \
- } \
- return OK; \
-} \
-\
-scope int encode_vim_to_##name(firstargtype firstargname, typval_T *const tv, \
- const char *const objname) \
- FUNC_ATTR_WARN_UNUSED_RESULT \
-{ \
- const int copyID = get_copyID(); \
- MPConvStack mpstack; \
- _mp_init(mpstack); \
- if (name##_convert_one_value(firstargname, &mpstack, tv, copyID, objname) \
- == FAIL) { \
- goto encode_vim_to_##name##_error_ret; \
- } \
- while (_mp_size(mpstack)) { \
- MPConvStackVal *cur_mpsv = &_mp_last(mpstack); \
- typval_T *cur_tv = NULL; \
- switch (cur_mpsv->type) { \
- case kMPConvDict: { \
- if (!cur_mpsv->data.d.todo) { \
- (void) _mp_pop(mpstack); \
- cur_mpsv->data.d.dict->dv_copyID = copyID - 1; \
- TYPVAL_ENCODE_CONV_DICT_END(); \
- continue; \
- } else if (cur_mpsv->data.d.todo \
- != cur_mpsv->data.d.dict->dv_hashtab.ht_used) { \
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(); \
- } \
- while (HASHITEM_EMPTY(cur_mpsv->data.d.hi)) { \
- cur_mpsv->data.d.hi++; \
- } \
- dictitem_T *const di = HI2DI(cur_mpsv->data.d.hi); \
- cur_mpsv->data.d.todo--; \
- cur_mpsv->data.d.hi++; \
- TYPVAL_ENCODE_CONV_STR_STRING(&di->di_key[0], \
- strlen((char *) &di->di_key[0])); \
- TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(); \
- cur_tv = &di->di_tv; \
- break; \
- } \
- case kMPConvList: { \
- if (cur_mpsv->data.l.li == NULL) { \
- (void) _mp_pop(mpstack); \
- cur_mpsv->data.l.list->lv_copyID = copyID - 1; \
- TYPVAL_ENCODE_CONV_LIST_END(); \
- continue; \
- } else if (cur_mpsv->data.l.li != cur_mpsv->data.l.list->lv_first) { \
- TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(); \
- } \
- cur_tv = &cur_mpsv->data.l.li->li_tv; \
- cur_mpsv->data.l.li = cur_mpsv->data.l.li->li_next; \
- break; \
- } \
- case kMPConvPairs: { \
- if (cur_mpsv->data.l.li == NULL) { \
- (void) _mp_pop(mpstack); \
- cur_mpsv->data.l.list->lv_copyID = copyID - 1; \
- TYPVAL_ENCODE_CONV_DICT_END(); \
- continue; \
- } else if (cur_mpsv->data.l.li != cur_mpsv->data.l.list->lv_first) { \
- TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(); \
- } \
- const list_T *const kv_pair = cur_mpsv->data.l.li->li_tv.vval.v_list; \
- TYPVAL_ENCODE_CONV_SPECIAL_DICT_KEY_CHECK( \
- encode_vim_to_##name##_error_ret, kv_pair->lv_first->li_tv); \
- if (name##_convert_one_value(firstargname, &mpstack, \
- &kv_pair->lv_first->li_tv, copyID, \
- objname) == FAIL) { \
- goto encode_vim_to_##name##_error_ret; \
- } \
- TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(); \
- cur_tv = &kv_pair->lv_last->li_tv; \
- cur_mpsv->data.l.li = cur_mpsv->data.l.li->li_next; \
- break; \
+/// @param[in,out] val Container to check.
+/// @param copyID_attr Name of the container attribute that holds copyID.
+/// After checking whether value of this attribute is
+/// copyID (variable) it is set to copyID.
+/// @param[in] copyID CopyID used by the caller.
+/// @param conv_type Type of the conversion, @see MPConvStackValType.
+#define _TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val, copyID_attr, copyID, \
+ conv_type) \
+ do { \
+ const int te_csr_ret = _TYPVAL_ENCODE_CHECK_SELF_REFERENCE( \
+ TYPVAL_ENCODE_FIRST_ARG_NAME, \
+ (val), &(val)->copyID_attr, mpstack, copyID, conv_type, objname); \
+ if (te_csr_ret != NOTDONE) { \
+ return te_csr_ret; \
} \
- } \
- assert(cur_tv != NULL); \
- if (name##_convert_one_value(firstargname, &mpstack, cur_tv, copyID, \
- objname) == FAIL) { \
- goto encode_vim_to_##name##_error_ret; \
- } \
- } \
- _mp_destroy(mpstack); \
- return OK; \
-encode_vim_to_##name##_error_ret: \
- _mp_destroy(mpstack); \
- return FAIL; \
-}
+ } while (0)
+
+#define _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) \
+ pref##name##suf
+#define _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, name, suf) \
+ _TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf)
+
+/// Construct function name, possibly using macros
+///
+/// Is used to expand macros that may appear in arguments.
+///
+/// @note Expands all arguments, even if only one is needed.
+///
+/// @param[in] pref Prefix.
+/// @param[in] suf Suffix.
+///
+/// @return Concat: pref + #TYPVAL_ENCODE_NAME + suf.
+#define _TYPVAL_ENCODE_FUNC_NAME(pref, suf) \
+ _TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf)
+
+/// Self reference checker function name
+#define _TYPVAL_ENCODE_CHECK_SELF_REFERENCE \
+ _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference)
+
+/// Entry point function name
+#define _TYPVAL_ENCODE_ENCODE \
+ _TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, )
+
+/// Name of the …convert_one_value function
+#define _TYPVAL_ENCODE_CONVERT_ONE_VALUE \
+ _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value)
+
+/// Name of the dummy const dict_T *const variable
+#define TYPVAL_ENCODE_NODICT_VAR \
+ _TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var)
#endif // NVIM_EVAL_TYPVAL_ENCODE_H
diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h
deleted file mode 100644
index d5c9b2c1ec..0000000000
--- a/src/nvim/eval_defs.h
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef NVIM_EVAL_DEFS_H
-#define NVIM_EVAL_DEFS_H
-
-#include <limits.h>
-#include <stddef.h>
-
-#include "nvim/hashtab.h"
-#include "nvim/lib/queue.h"
-
-typedef int varnumber_T;
-typedef double float_T;
-
-#define VARNUMBER_MAX INT_MAX
-#define VARNUMBER_MIN INT_MIN
-
-typedef struct listvar_S list_T;
-typedef struct dictvar_S dict_T;
-
-/// Special variable values
-typedef enum {
- kSpecialVarFalse, ///< v:false
- kSpecialVarTrue, ///< v:true
- kSpecialVarNull, ///< v:null
-} SpecialVarValue;
-
-/// Variable lock status for typval_T.v_lock
-typedef enum {
- VAR_UNLOCKED = 0, ///< Not locked.
- VAR_LOCKED, ///< User lock, can be unlocked.
- VAR_FIXED, ///< Locked forever.
-} VarLockStatus;
-
-/// VimL variable types, for use in typval_T.v_type
-typedef enum {
- VAR_UNKNOWN = 0, ///< Unknown (unspecified) value.
- VAR_NUMBER, ///< Number, .v_number is used.
- VAR_STRING, ///< String, .v_string is used.
- VAR_FUNC, ///< Function referene, .v_string is used for function name.
- VAR_LIST, ///< List, .v_list is used.
- VAR_DICT, ///< Dictionary, .v_dict is used.
- VAR_FLOAT, ///< Floating-point value, .v_float is used.
- VAR_SPECIAL, ///< Special value (true, false, null), .v_special
- ///< is used.
-} VarType;
-
-/// Structure that holds an internal variable value
-typedef struct {
- VarType v_type; ///< Variable type.
- VarLockStatus v_lock; ///< Variable lock status.
- union {
- varnumber_T v_number; ///< Number, for VAR_NUMBER.
- SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL.
- float_T v_float; ///< Floating-point number, for VAR_FLOAT.
- char_u *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL.
- list_T *v_list; ///< List for VAR_LIST, can be NULL.
- dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL.
- } vval; ///< Actual value.
-} typval_T;
-
-/* Values for "dv_scope". */
-#define VAR_SCOPE 1 /* a:, v:, s:, etc. scope dictionaries */
-#define VAR_DEF_SCOPE 2 /* l:, g: scope dictionaries: here funcrefs are not
- allowed to mask existing functions */
-
-/*
- * Structure to hold an item of a list: an internal variable without a name.
- */
-typedef struct listitem_S listitem_T;
-
-struct listitem_S {
- listitem_T *li_next; /* next item in list */
- listitem_T *li_prev; /* previous item in list */
- typval_T li_tv; /* type and value of the variable */
-};
-
-/*
- * Struct used by those that are using an item in a list.
- */
-typedef struct listwatch_S listwatch_T;
-
-struct listwatch_S {
- listitem_T *lw_item; /* item being watched */
- listwatch_T *lw_next; /* next watcher */
-};
-
-/*
- * Structure to hold info about a list.
- */
-struct listvar_S {
- listitem_T *lv_first; /* first item, NULL if none */
- listitem_T *lv_last; /* last item, NULL if none */
- int lv_refcount; /* reference count */
- int lv_len; /* number of items */
- listwatch_T *lv_watch; /* first watcher, NULL if none */
- int lv_idx; /* cached index of an item */
- listitem_T *lv_idx_item; /* when not NULL item at index "lv_idx" */
- int lv_copyID; /* ID used by deepcopy() */
- list_T *lv_copylist; /* copied list used by deepcopy() */
- char lv_lock; /* zero, VAR_LOCKED, VAR_FIXED */
- list_T *lv_used_next; /* next list in used lists list */
- list_T *lv_used_prev; /* previous list in used lists list */
-};
-
-/*
- * Structure to hold an item of a Dictionary.
- * Also used for a variable.
- * The key is copied into "di_key" to avoid an extra alloc/free for it.
- */
-struct dictitem_S {
- typval_T di_tv; /* type and value of the variable */
- char_u di_flags; /* flags (only used for variable) */
- char_u di_key[1]; /* key (actually longer!) */
-};
-
-typedef struct dictitem_S dictitem_T;
-
-#define DI_FLAGS_RO 1 // "di_flags" value: read-only variable
-#define DI_FLAGS_RO_SBX 2 // "di_flags" value: read-only in the sandbox
-#define DI_FLAGS_FIX 4 // "di_flags" value: fixed: no :unlet or remove()
-#define DI_FLAGS_LOCK 8 // "di_flags" value: locked variable
-#define DI_FLAGS_ALLOC 16 // "di_flags" value: separately allocated
-
-/// Structure representing a Dictionary
-struct dictvar_S {
- VarLockStatus dv_lock; ///< Whole dictionary lock status.
- char dv_scope; ///< Non-zero (#VAR_SCOPE, #VAR_DEF_SCOPE) if
- ///< dictionary represents a scope (i.e. g:, l: …).
- int dv_refcount; ///< Reference count.
- int dv_copyID; ///< ID used when recursivery traversing a value.
- hashtab_T dv_hashtab; ///< Hashtab containing all items.
- dict_T *dv_copydict; ///< Copied dict used by deepcopy().
- dict_T *dv_used_next; ///< Next dictionary in used dictionaries list.
- dict_T *dv_used_prev; ///< Previous dictionary in used dictionaries list.
- QUEUE watchers; ///< Dictionary key watchers set by user code.
-};
-
-// structure used for explicit stack while garbage collecting hash tables
-typedef struct ht_stack_S {
- hashtab_T *ht;
- struct ht_stack_S *prev;
-} ht_stack_T;
-
-// structure used for explicit stack while garbage collecting lists
-typedef struct list_stack_S {
- list_T *list;
- struct list_stack_S *prev;
-} list_stack_T;
-
-// In a hashtab item "hi_key" points to "di_key" in a dictitem.
-// This avoids adding a pointer to the hashtab item.
-
-/// Convert a dictitem pointer to a hashitem key pointer
-#define DI2HIKEY(di) ((di)->di_key)
-
-/// Convert a hashitem key pointer to a dictitem pointer
-#define HIKEY2DI(p) ((dictitem_T *)(p - offsetof(dictitem_T, di_key)))
-
-/// Convert a hashitem value pointer to a dictitem pointer
-#define HIVAL2DI(p) \
- ((dictitem_T *)(((char *)p) - offsetof(dictitem_T, di_tv)))
-
-/// Convert a hashitem pointer to a dictitem pointer
-#define HI2DI(hi) HIKEY2DI((hi)->hi_key)
-
-#endif // NVIM_EVAL_DEFS_H
diff --git a/src/nvim/event/defs.h b/src/nvim/event/defs.h
index e5335d9f25..fdd4f17d5c 100644
--- a/src/nvim/event/defs.h
+++ b/src/nvim/event/defs.h
@@ -4,20 +4,18 @@
#include <assert.h>
#include <stdarg.h>
-#define EVENT_HANDLER_MAX_ARGC 6
+#define EVENT_HANDLER_MAX_ARGC 10
typedef void (*argv_callback)(void **argv);
typedef struct message {
- int priority;
argv_callback handler;
void *argv[EVENT_HANDLER_MAX_ARGC];
} Event;
typedef void(*event_scheduler)(Event event, void *data);
-#define VA_EVENT_INIT(event, p, h, a) \
+#define VA_EVENT_INIT(event, h, a) \
do { \
assert(a <= EVENT_HANDLER_MAX_ARGC); \
- (event)->priority = p; \
(event)->handler = h; \
if (a) { \
va_list args; \
@@ -29,11 +27,11 @@ typedef void(*event_scheduler)(Event event, void *data);
} \
} while (0)
-static inline Event event_create(int priority, argv_callback cb, int argc, ...)
+static inline Event event_create(argv_callback cb, int argc, ...)
{
assert(argc <= EVENT_HANDLER_MAX_ARGC);
Event event;
- VA_EVENT_INIT(&event, priority, cb, argc);
+ VA_EVENT_INIT(&event, cb, argc);
return event;
}
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c
index a68badcc8f..ffe2db9b76 100644
--- a/src/nvim/event/libuv_process.c
+++ b/src/nvim/event/libuv_process.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 <uv.h>
@@ -8,25 +11,37 @@
#include "nvim/event/process.h"
#include "nvim/event/libuv_process.h"
#include "nvim/log.h"
+#include "nvim/macros.h"
+#include "nvim/os/os.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/libuv_process.c.generated.h"
#endif
-bool libuv_process_spawn(LibuvProcess *uvproc)
+/// @returns zero on success, or negative error code
+int libuv_process_spawn(LibuvProcess *uvproc)
FUNC_ATTR_NONNULL_ALL
{
Process *proc = (Process *)uvproc;
uvproc->uvopts.file = proc->argv[0];
uvproc->uvopts.args = proc->argv;
- uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE
- | UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
+ uvproc->uvopts.flags = UV_PROCESS_WINDOWS_HIDE;
+#ifdef WIN32
+ // libuv collapses the argv to a CommandLineToArgvW()-style string. cmd.exe
+ // expects a different syntax (must be prepared by the caller before now).
+ if (os_shell_is_cmdexe(proc->argv[0])) {
+ uvproc->uvopts.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
+ }
if (proc->detach) {
- uvproc->uvopts.flags |= UV_PROCESS_DETACHED;
+ uvproc->uvopts.flags |= UV_PROCESS_DETACHED;
}
+#else
+ // Always setsid() on unix-likes. #8107
+ uvproc->uvopts.flags |= UV_PROCESS_DETACHED;
+#endif
uvproc->uvopts.exit_cb = exit_cb;
uvproc->uvopts.cwd = proc->cwd;
- uvproc->uvopts.env = NULL;
+ uvproc->uvopts.env = NULL; // Inherits the parent (nvim) env.
uvproc->uvopts.stdio = uvproc->uvstdio;
uvproc->uvopts.stdio_count = 3;
uvproc->uvstdio[0].flags = UV_IGNORE;
@@ -34,29 +49,39 @@ bool libuv_process_spawn(LibuvProcess *uvproc)
uvproc->uvstdio[2].flags = UV_IGNORE;
uvproc->uv.data = proc;
- if (proc->in) {
+ if (!proc->in.closed) {
uvproc->uvstdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
- uvproc->uvstdio[0].data.stream = (uv_stream_t *)&proc->in->uv.pipe;
+#ifdef WIN32
+ uvproc->uvstdio[0].flags |= UV_OVERLAPPED_PIPE;
+#endif
+ uvproc->uvstdio[0].data.stream = STRUCT_CAST(uv_stream_t,
+ &proc->in.uv.pipe);
}
- if (proc->out) {
+ if (!proc->out.closed) {
uvproc->uvstdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
- uvproc->uvstdio[1].data.stream = (uv_stream_t *)&proc->out->uv.pipe;
+#ifdef WIN32
+ // pipe must be readable for IOCP to work.
+ uvproc->uvstdio[1].flags |= UV_READABLE_PIPE | UV_OVERLAPPED_PIPE;
+#endif
+ uvproc->uvstdio[1].data.stream = STRUCT_CAST(uv_stream_t,
+ &proc->out.uv.pipe);
}
- if (proc->err) {
+ if (!proc->err.closed) {
uvproc->uvstdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
- uvproc->uvstdio[2].data.stream = (uv_stream_t *)&proc->err->uv.pipe;
+ uvproc->uvstdio[2].data.stream = STRUCT_CAST(uv_stream_t,
+ &proc->err.uv.pipe);
}
int status;
if ((status = uv_spawn(&proc->loop->uv, &uvproc->uv, &uvproc->uvopts))) {
ELOG("uv_spawn failed: %s", uv_strerror(status));
- return false;
+ return status;
}
proc->pid = uvproc->uv.pid;
- return true;
+ return status;
}
void libuv_process_close(LibuvProcess *uvproc)
diff --git a/src/nvim/event/libuv_process.h b/src/nvim/event/libuv_process.h
index aaaa896e10..1132ce79ca 100644
--- a/src/nvim/event/libuv_process.h
+++ b/src/nvim/event/libuv_process.h
@@ -14,8 +14,9 @@ typedef struct libuv_process {
static inline LibuvProcess libuv_process_init(Loop *loop, void *data)
{
- LibuvProcess rv;
- rv.process = process_init(loop, kProcessTypeUv, data);
+ LibuvProcess rv = {
+ .process = process_init(loop, kProcessTypeUv, data)
+ };
return rv;
}
diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c
index 6f3e6b9253..609c723c57 100644
--- a/src/nvim/event/loop.c
+++ b/src/nvim/event/loop.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 <stdarg.h>
#include <stdint.h>
@@ -5,6 +8,7 @@
#include "nvim/event/loop.h"
#include "nvim/event/process.h"
+#include "nvim/log.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/loop.c.generated.h"
@@ -17,55 +21,87 @@ void loop_init(Loop *loop, void *data)
loop->recursive = 0;
loop->uv.data = loop;
loop->children = kl_init(WatcherPtr);
- loop->children_stop_requests = 0;
- loop->events = queue_new_parent(loop_on_put, loop);
- loop->fast_events = queue_new_child(loop->events);
- loop->thread_events = queue_new_parent(NULL, NULL);
+ loop->events = multiqueue_new_parent(loop_on_put, loop);
+ loop->fast_events = multiqueue_new_child(loop->events);
+ loop->thread_events = multiqueue_new_parent(NULL, NULL);
uv_mutex_init(&loop->mutex);
uv_async_init(&loop->uv, &loop->async, async_cb);
uv_signal_init(&loop->uv, &loop->children_watcher);
uv_timer_init(&loop->uv, &loop->children_kill_timer);
uv_timer_init(&loop->uv, &loop->poll_timer);
+ loop->poll_timer.data = xmalloc(sizeof(bool)); // "timeout expired" flag
}
-void loop_poll_events(Loop *loop, int ms)
+/// Processes one `Loop.uv` event (at most).
+/// Processes all `Loop.fast_events` events.
+/// Does NOT process `Loop.events`, that is an application-specific decision.
+///
+/// @returns true if `ms` timeout was reached
+bool loop_poll_events(Loop *loop, int ms)
{
if (loop->recursive++) {
abort(); // Should not re-enter uv_run
}
uv_run_mode mode = UV_RUN_ONCE;
+ bool timeout_expired = false;
if (ms > 0) {
- // Use a repeating timeout of ms milliseconds to make sure
- // we do not block indefinitely for I/O.
+ *((bool *)loop->poll_timer.data) = false; // reset "timeout expired" flag
+ // Dummy timer to ensure UV_RUN_ONCE does not block indefinitely for I/O.
uv_timer_start(&loop->poll_timer, timer_cb, (uint64_t)ms, (uint64_t)ms);
} else if (ms == 0) {
- // For ms == 0, we need to do a non-blocking event poll by
- // setting the run mode to UV_RUN_NOWAIT.
+ // For ms == 0, do a non-blocking event poll.
mode = UV_RUN_NOWAIT;
}
uv_run(&loop->uv, mode);
if (ms > 0) {
+ timeout_expired = *((bool *)loop->poll_timer.data);
uv_timer_stop(&loop->poll_timer);
}
loop->recursive--; // Can re-enter uv_run now
- queue_process_events(loop->fast_events);
+ multiqueue_process_events(loop->fast_events);
+ return timeout_expired;
}
-// Schedule an event from another thread
+/// Schedules an event from another thread.
+///
+/// @note Event is queued into `fast_events`, which is processed outside of the
+/// primary `events` queue by loop_poll_events(). For `main_loop`, that
+/// means `fast_events` is NOT processed in an "editor mode"
+/// (VimState.execute), so redraw and other side-effects are likely to be
+/// skipped.
+/// @see loop_schedule_deferred
void loop_schedule(Loop *loop, Event event)
{
uv_mutex_lock(&loop->mutex);
- queue_put_event(loop->thread_events, event);
+ multiqueue_put_event(loop->thread_events, event);
uv_async_send(&loop->async);
uv_mutex_unlock(&loop->mutex);
}
-void loop_on_put(Queue *queue, void *data)
+/// Schedules an event from another thread. Unlike loop_schedule(), the event
+/// is forwarded to `Loop.events`, instead of being processed immediately.
+///
+/// @see loop_schedule
+void loop_schedule_deferred(Loop *loop, Event event)
+{
+ Event *eventp = xmalloc(sizeof(*eventp));
+ *eventp = event;
+ loop_schedule(loop, event_create(loop_deferred_event, 2, loop, eventp));
+}
+static void loop_deferred_event(void **argv)
+{
+ Loop *loop = argv[0];
+ Event *eventp = argv[1];
+ multiqueue_put_event(loop->events, *eventp);
+ xfree(eventp);
+}
+
+void loop_on_put(MultiQueue *queue, void *data)
{
Loop *loop = data;
// Sometimes libuv will run pending callbacks(timer for example) before
@@ -76,34 +112,70 @@ void loop_on_put(Queue *queue, void *data)
uv_stop(&loop->uv);
}
-void loop_close(Loop *loop)
+/// @returns false if the loop could not be closed gracefully
+bool loop_close(Loop *loop, bool wait)
{
+ bool rv = true;
uv_mutex_destroy(&loop->mutex);
uv_close((uv_handle_t *)&loop->children_watcher, NULL);
uv_close((uv_handle_t *)&loop->children_kill_timer, NULL);
- uv_close((uv_handle_t *)&loop->poll_timer, NULL);
+ uv_close((uv_handle_t *)&loop->poll_timer, timer_close_cb);
uv_close((uv_handle_t *)&loop->async, NULL);
- do {
- uv_run(&loop->uv, UV_RUN_DEFAULT);
- } while (uv_loop_close(&loop->uv));
- queue_free(loop->fast_events);
- queue_free(loop->thread_events);
- queue_free(loop->events);
+ uint64_t start = wait ? os_hrtime() : 0;
+ while (true) {
+ uv_run(&loop->uv, wait ? UV_RUN_DEFAULT : UV_RUN_NOWAIT);
+ if (!uv_loop_close(&loop->uv) || !wait) {
+ break;
+ }
+ if (os_hrtime() - start >= 2 * 1000000000) {
+ // Some libuv resource was not correctly deref'd. Log and bail.
+ rv = false;
+ ELOG("uv_loop_close() hang?");
+ log_uv_handles(&loop->uv);
+ break;
+ }
+ }
+ multiqueue_free(loop->fast_events);
+ multiqueue_free(loop->thread_events);
+ multiqueue_free(loop->events);
kl_destroy(WatcherPtr, loop->children);
+ return rv;
+}
+
+void loop_purge(Loop *loop)
+{
+ uv_mutex_lock(&loop->mutex);
+ multiqueue_purge_events(loop->thread_events);
+ multiqueue_purge_events(loop->fast_events);
+ uv_mutex_unlock(&loop->mutex);
+}
+
+size_t loop_size(Loop *loop)
+{
+ uv_mutex_lock(&loop->mutex);
+ size_t rv = multiqueue_size(loop->thread_events);
+ uv_mutex_unlock(&loop->mutex);
+ return rv;
}
static void async_cb(uv_async_t *handle)
{
Loop *l = handle->loop->data;
uv_mutex_lock(&l->mutex);
- while (!queue_empty(l->thread_events)) {
- Event ev = queue_get(l->thread_events);
- queue_put_event(l->fast_events, ev);
+ while (!multiqueue_empty(l->thread_events)) {
+ Event ev = multiqueue_get(l->thread_events);
+ multiqueue_put_event(l->fast_events, ev);
}
uv_mutex_unlock(&l->mutex);
}
static void timer_cb(uv_timer_t *handle)
{
+ bool *timeout_expired = handle->data;
+ *timeout_expired = true;
}
+static void timer_close_cb(uv_handle_t *handle)
+{
+ xfree(handle->data);
+}
diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h
index 407aa4245f..f5dd23ac8b 100644
--- a/src/nvim/event/loop.h
+++ b/src/nvim/event/loop.h
@@ -7,7 +7,7 @@
#include "nvim/lib/klist.h"
#include "nvim/os/time.h"
-#include "nvim/event/queue.h"
+#include "nvim/event/multiqueue.h"
typedef void * WatcherPtr;
@@ -16,33 +16,51 @@ KLIST_INIT(WatcherPtr, WatcherPtr, _noop)
typedef struct loop {
uv_loop_t uv;
- Queue *events, *fast_events, *thread_events;
+ MultiQueue *events;
+ MultiQueue *thread_events;
+ // Immediate events:
+ // "Processed after exiting uv_run() (to avoid recursion), but before
+ // returning from loop_poll_events()." 502aee690c98
+ // Practical consequence (for main_loop): these events are processed by
+ // state_enter()..os_inchar()
+ // whereas "regular" events (main_loop.events) are processed by
+ // state_enter()..VimState.execute()
+ // But state_enter()..os_inchar() can be "too early" if you want the event
+ // to trigger UI updates and other user-activity-related side-effects.
+ MultiQueue *fast_events;
+
+ // used by process/job-control subsystem
klist_t(WatcherPtr) *children;
uv_signal_t children_watcher;
- uv_timer_t children_kill_timer, poll_timer;
- size_t children_stop_requests;
+ uv_timer_t children_kill_timer;
+
+ // generic timer, used by loop_poll_events()
+ uv_timer_t poll_timer;
+
uv_async_t async;
uv_mutex_t mutex;
int recursive;
} Loop;
-#define CREATE_EVENT(queue, handler, argc, ...) \
+#define CREATE_EVENT(multiqueue, handler, argc, ...) \
do { \
- if (queue) { \
- queue_put((queue), (handler), argc, __VA_ARGS__); \
+ if (multiqueue) { \
+ multiqueue_put((multiqueue), (handler), argc, __VA_ARGS__); \
} else { \
void *argv[argc] = { __VA_ARGS__ }; \
(handler)(argv); \
} \
} while (0)
+// -V:LOOP_PROCESS_EVENTS_UNTIL:547
+
// Poll for events until a condition or timeout
-#define LOOP_PROCESS_EVENTS_UNTIL(loop, queue, timeout, condition) \
+#define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \
do { \
int remaining = timeout; \
uint64_t before = (remaining > 0) ? os_hrtime() : 0; \
while (!(condition)) { \
- LOOP_PROCESS_EVENTS(loop, queue, remaining); \
+ LOOP_PROCESS_EVENTS(loop, multiqueue, remaining); \
if (remaining == 0) { \
break; \
} else if (remaining > 0) { \
@@ -56,10 +74,10 @@ typedef struct loop {
} \
} while (0)
-#define LOOP_PROCESS_EVENTS(loop, queue, timeout) \
+#define LOOP_PROCESS_EVENTS(loop, multiqueue, timeout) \
do { \
- if (queue && !queue_empty(queue)) { \
- queue_process_events(queue); \
+ if (multiqueue && !multiqueue_empty(multiqueue)) { \
+ multiqueue_process_events(multiqueue); \
} else { \
loop_poll_events(loop, timeout); \
} \
diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c
new file mode 100644
index 0000000000..ef9f3f1870
--- /dev/null
+++ b/src/nvim/event/multiqueue.c
@@ -0,0 +1,247 @@
+// 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
+
+// Multi-level queue for selective async event processing.
+// Not threadsafe; access must be synchronized externally.
+//
+// Multiqueue supports a parent-child relationship with these properties:
+// - pushing a node to a child queue will push a corresponding link node to the
+// parent queue
+// - removing a link node from a parent queue will remove the next node
+// in the linked child queue
+// - removing a node from a child queue will remove the corresponding link node
+// in the parent queue
+//
+// These properties allow Nvim to organize and process events from different
+// sources with a certain degree of control. How the multiqueue is used:
+//
+// +----------------+
+// | Main loop |
+// +----------------+
+//
+// +----------------+
+// +-------------->| Event loop |<------------+
+// | +--+-------------+ |
+// | ^ ^ |
+// | | | |
+// +-----------+ +-----------+ +---------+ +---------+
+// | Channel 1 | | Channel 2 | | Job 1 | | Job 2 |
+// +-----------+ +-----------+ +---------+ +---------+
+//
+//
+// The lower boxes represent event emitters, each with its own private queue
+// having the event loop queue as the parent.
+//
+// When idle, the main loop spins the event loop which queues events from many
+// sources (channels, jobs, user...). Each event emitter pushes events to its
+// private queue which is propagated to the event loop queue. When the main loop
+// consumes an event, the corresponding event is removed from the emitter's
+// queue.
+//
+// The main reason for this queue hierarchy is to allow focusing on a single
+// event emitter while blocking the main loop. For example, if the `jobwait`
+// VimL function is called on job1, the main loop will temporarily stop polling
+// the event loop queue and poll job1 queue instead. Same with channels, when
+// calling `rpcrequest` we want to temporarily stop processing events from
+// other sources and focus on a specific channel.
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+
+#include <uv.h>
+
+#include "nvim/event/multiqueue.h"
+#include "nvim/memory.h"
+#include "nvim/os/time.h"
+
+typedef struct multiqueue_item MultiQueueItem;
+struct multiqueue_item {
+ union {
+ MultiQueue *queue;
+ struct {
+ Event event;
+ MultiQueueItem *parent_item;
+ } item;
+ } data;
+ bool link; // true: current item is just a link to a node in a child queue
+ QUEUE node;
+};
+
+struct multiqueue {
+ MultiQueue *parent;
+ QUEUE headtail; // circularly-linked
+ put_callback put_cb;
+ void *data;
+ size_t size;
+};
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "event/multiqueue.c.generated.h"
+#endif
+
+static Event NILEVENT = { .handler = NULL, .argv = {NULL} };
+
+MultiQueue *multiqueue_new_parent(put_callback put_cb, void *data)
+{
+ return multiqueue_new(NULL, put_cb, data);
+}
+
+MultiQueue *multiqueue_new_child(MultiQueue *parent)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(!parent->parent); // parent cannot have a parent, more like a "root"
+ parent->size++;
+ return multiqueue_new(parent, NULL, NULL);
+}
+
+static MultiQueue *multiqueue_new(MultiQueue *parent, put_callback put_cb,
+ void *data)
+{
+ MultiQueue *rv = xmalloc(sizeof(MultiQueue));
+ QUEUE_INIT(&rv->headtail);
+ rv->size = 0;
+ rv->parent = parent;
+ rv->put_cb = put_cb;
+ rv->data = data;
+ return rv;
+}
+
+void multiqueue_free(MultiQueue *this)
+{
+ assert(this);
+ while (!QUEUE_EMPTY(&this->headtail)) {
+ QUEUE *q = QUEUE_HEAD(&this->headtail);
+ MultiQueueItem *item = multiqueue_node_data(q);
+ if (this->parent) {
+ QUEUE_REMOVE(&item->data.item.parent_item->node);
+ xfree(item->data.item.parent_item);
+ }
+ QUEUE_REMOVE(q);
+ xfree(item);
+ }
+
+ xfree(this);
+}
+
+/// Removes the next item and returns its Event.
+Event multiqueue_get(MultiQueue *this)
+{
+ return multiqueue_empty(this) ? NILEVENT : multiqueue_remove(this);
+}
+
+void multiqueue_put_event(MultiQueue *this, Event event)
+{
+ assert(this);
+ multiqueue_push(this, event);
+ if (this->parent && this->parent->put_cb) {
+ this->parent->put_cb(this->parent, this->parent->data);
+ }
+}
+
+void multiqueue_process_events(MultiQueue *this)
+{
+ assert(this);
+ while (!multiqueue_empty(this)) {
+ Event event = multiqueue_remove(this);
+ if (event.handler) {
+ event.handler(event.argv);
+ }
+ }
+}
+
+/// Removes all events without processing them.
+void multiqueue_purge_events(MultiQueue *this)
+{
+ assert(this);
+ while (!multiqueue_empty(this)) {
+ (void)multiqueue_remove(this);
+ }
+}
+
+bool multiqueue_empty(MultiQueue *this)
+{
+ assert(this);
+ return QUEUE_EMPTY(&this->headtail);
+}
+
+void multiqueue_replace_parent(MultiQueue *this, MultiQueue *new_parent)
+{
+ assert(multiqueue_empty(this));
+ this->parent = new_parent;
+}
+
+/// Gets the count of all events currently in the queue.
+size_t multiqueue_size(MultiQueue *this)
+{
+ return this->size;
+}
+
+/// Gets an Event from an item.
+///
+/// @param remove Remove the node from its queue, and free it.
+static Event multiqueueitem_get_event(MultiQueueItem *item, bool remove)
+{
+ assert(item != NULL);
+ Event ev;
+ if (item->link) {
+ // get the next node in the linked queue
+ MultiQueue *linked = item->data.queue;
+ assert(!multiqueue_empty(linked));
+ MultiQueueItem *child =
+ multiqueue_node_data(QUEUE_HEAD(&linked->headtail));
+ ev = child->data.item.event;
+ // remove the child node
+ if (remove) {
+ QUEUE_REMOVE(&child->node);
+ xfree(child);
+ }
+ } else {
+ // remove the corresponding link node in the parent queue
+ if (remove && item->data.item.parent_item) {
+ QUEUE_REMOVE(&item->data.item.parent_item->node);
+ xfree(item->data.item.parent_item);
+ item->data.item.parent_item = NULL;
+ }
+ ev = item->data.item.event;
+ }
+ return ev;
+}
+
+static Event multiqueue_remove(MultiQueue *this)
+{
+ assert(!multiqueue_empty(this));
+ QUEUE *h = QUEUE_HEAD(&this->headtail);
+ QUEUE_REMOVE(h);
+ MultiQueueItem *item = multiqueue_node_data(h);
+ assert(!item->link || !this->parent); // Only a parent queue has link-nodes
+ Event ev = multiqueueitem_get_event(item, true);
+ this->size--;
+ xfree(item);
+ return ev;
+}
+
+static void multiqueue_push(MultiQueue *this, Event event)
+{
+ MultiQueueItem *item = xmalloc(sizeof(MultiQueueItem));
+ item->link = false;
+ item->data.item.event = event;
+ item->data.item.parent_item = NULL;
+ QUEUE_INSERT_TAIL(&this->headtail, &item->node);
+ if (this->parent) {
+ // push link node to the parent queue
+ item->data.item.parent_item = xmalloc(sizeof(MultiQueueItem));
+ item->data.item.parent_item->link = true;
+ item->data.item.parent_item->data.queue = this;
+ QUEUE_INSERT_TAIL(&this->parent->headtail,
+ &item->data.item.parent_item->node);
+ }
+ this->size++;
+}
+
+static MultiQueueItem *multiqueue_node_data(QUEUE *q)
+{
+ return QUEUE_DATA(q, MultiQueueItem, node);
+}
diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h
new file mode 100644
index 0000000000..a688107665
--- /dev/null
+++ b/src/nvim/event/multiqueue.h
@@ -0,0 +1,19 @@
+#ifndef NVIM_EVENT_MULTIQUEUE_H
+#define NVIM_EVENT_MULTIQUEUE_H
+
+#include <uv.h>
+
+#include "nvim/event/defs.h"
+#include "nvim/lib/queue.h"
+
+typedef struct multiqueue MultiQueue;
+typedef void (*put_callback)(MultiQueue *multiq, void *data);
+
+#define multiqueue_put(q, h, ...) \
+ multiqueue_put_event(q, event_create(h, __VA_ARGS__));
+
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "event/multiqueue.h.generated.h"
+#endif
+#endif // NVIM_EVENT_MULTIQUEUE_H
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 1c4c9737c3..7a8a39dbcf 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.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 <stdlib.h>
@@ -9,63 +12,65 @@
#include "nvim/event/wstream.h"
#include "nvim/event/process.h"
#include "nvim/event/libuv_process.h"
+#include "nvim/os/process.h"
#include "nvim/os/pty_process.h"
#include "nvim/globals.h"
+#include "nvim/macros.h"
#include "nvim/log.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/process.c.generated.h"
#endif
-// {SIGNAL}_TIMEOUT is the time (in nanoseconds) that a process has to cleanly
-// exit before we send SIGNAL to it
-#define TERM_TIMEOUT 1000000000
-#define KILL_TIMEOUT (TERM_TIMEOUT * 2)
-
-#define CLOSE_PROC_STREAM(proc, stream) \
- do { \
- if (proc->stream && !proc->stream->closed) { \
- stream_close(proc->stream, NULL); \
- } \
- } while (0)
+// Time for a process to exit cleanly before we send KILL.
+// For PTY processes SIGTERM is sent first (in case SIGHUP was not enough).
+#define KILL_TIMEOUT_MS 2000
static bool process_is_tearing_down = false;
-bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
+/// @returns zero on success, or negative error code
+int process_spawn(Process *proc, bool in, bool out, bool err)
+ FUNC_ATTR_NONNULL_ALL
{
- if (proc->in) {
- uv_pipe_init(&proc->loop->uv, &proc->in->uv.pipe, 0);
+ if (in) {
+ uv_pipe_init(&proc->loop->uv, &proc->in.uv.pipe, 0);
+ } else {
+ proc->in.closed = true;
}
- if (proc->out) {
- uv_pipe_init(&proc->loop->uv, &proc->out->uv.pipe, 0);
+ if (out) {
+ uv_pipe_init(&proc->loop->uv, &proc->out.uv.pipe, 0);
+ } else {
+ proc->out.closed = true;
}
- if (proc->err) {
- uv_pipe_init(&proc->loop->uv, &proc->err->uv.pipe, 0);
+ if (err) {
+ uv_pipe_init(&proc->loop->uv, &proc->err.uv.pipe, 0);
+ } else {
+ proc->err.closed = true;
}
- bool success;
+ int status;
switch (proc->type) {
case kProcessTypeUv:
- success = libuv_process_spawn((LibuvProcess *)proc);
+ status = libuv_process_spawn((LibuvProcess *)proc);
break;
case kProcessTypePty:
- success = pty_process_spawn((PtyProcess *)proc);
+ status = pty_process_spawn((PtyProcess *)proc);
break;
default:
abort();
}
- if (!success) {
- if (proc->in) {
- uv_close((uv_handle_t *)&proc->in->uv.pipe, NULL);
+ if (status) {
+ if (in) {
+ uv_close((uv_handle_t *)&proc->in.uv.pipe, NULL);
}
- if (proc->out) {
- uv_close((uv_handle_t *)&proc->out->uv.pipe, NULL);
+ if (out) {
+ uv_close((uv_handle_t *)&proc->out.uv.pipe, NULL);
}
- if (proc->err) {
- uv_close((uv_handle_t *)&proc->err->uv.pipe, NULL);
+ if (err) {
+ uv_close((uv_handle_t *)&proc->err.uv.pipe, NULL);
}
if (proc->type == kProcessTypeUv) {
@@ -75,32 +80,30 @@ bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
}
shell_free_argv(proc->argv);
proc->status = -1;
- return false;
+ return status;
}
- void *data = proc->data;
-
- if (proc->in) {
- stream_init(NULL, proc->in, -1, (uv_stream_t *)&proc->in->uv.pipe, data);
- proc->in->events = proc->events;
- proc->in->internal_data = proc;
- proc->in->internal_close_cb = on_process_stream_close;
+ if (in) {
+ stream_init(NULL, &proc->in, -1,
+ STRUCT_CAST(uv_stream_t, &proc->in.uv.pipe));
+ proc->in.internal_data = proc;
+ proc->in.internal_close_cb = on_process_stream_close;
proc->refcount++;
}
- if (proc->out) {
- stream_init(NULL, proc->out, -1, (uv_stream_t *)&proc->out->uv.pipe, data);
- proc->out->events = proc->events;
- proc->out->internal_data = proc;
- proc->out->internal_close_cb = on_process_stream_close;
+ if (out) {
+ stream_init(NULL, &proc->out, -1,
+ STRUCT_CAST(uv_stream_t, &proc->out.uv.pipe));
+ proc->out.internal_data = proc;
+ proc->out.internal_close_cb = on_process_stream_close;
proc->refcount++;
}
- if (proc->err) {
- stream_init(NULL, proc->err, -1, (uv_stream_t *)&proc->err->uv.pipe, data);
- proc->err->events = proc->events;
- proc->err->internal_data = proc;
- proc->err->internal_close_cb = on_process_stream_close;
+ if (err) {
+ stream_init(NULL, &proc->err, -1,
+ STRUCT_CAST(uv_stream_t, &proc->err.uv.pipe));
+ proc->err.internal_data = proc;
+ proc->err.internal_close_cb = on_process_stream_close;
proc->refcount++;
}
@@ -108,7 +111,8 @@ bool process_spawn(Process *proc) FUNC_ATTR_NONNULL_ALL
proc->internal_close_cb = decref;
proc->refcount++;
kl_push(WatcherPtr, proc->loop->children, proc);
- return true;
+ DLOG("new: pid=%d argv=[%s]", proc->pid, *proc->argv);
+ return 0;
}
void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
@@ -116,75 +120,51 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL
process_is_tearing_down = true;
kl_iter(WatcherPtr, loop->children, current) {
Process *proc = (*current)->data;
- if (proc->detach) {
+ if (proc->detach || proc->type == kProcessTypePty) {
// Close handles to process without killing it.
CREATE_EVENT(loop->events, process_close_handles, 1, proc);
} else {
- if (proc->type == kProcessTypeUv) {
- uv_kill(proc->pid, SIGTERM);
- proc->term_sent = true;
- process_stop(proc);
- } else { // kProcessTypePty
- process_close_streams(proc);
- pty_process_close_master((PtyProcess *)proc);
- }
+ process_stop(proc);
}
}
- // Wait until all children exit
- LOOP_PROCESS_EVENTS_UNTIL(loop, loop->events, -1, kl_empty(loop->children));
+ // Wait until all children exit and all close events are processed.
+ LOOP_PROCESS_EVENTS_UNTIL(
+ loop, loop->events, -1,
+ kl_empty(loop->children) && multiqueue_empty(loop->events));
pty_process_teardown(loop);
}
-// Wrappers around `stream_close` that protect against double-closing.
void process_close_streams(Process *proc) FUNC_ATTR_NONNULL_ALL
{
- process_close_in(proc);
- process_close_out(proc);
- process_close_err(proc);
-}
-
-void process_close_in(Process *proc) FUNC_ATTR_NONNULL_ALL
-{
- CLOSE_PROC_STREAM(proc, in);
-}
-
-void process_close_out(Process *proc) FUNC_ATTR_NONNULL_ALL
-{
- CLOSE_PROC_STREAM(proc, out);
-}
-
-void process_close_err(Process *proc) FUNC_ATTR_NONNULL_ALL
-{
- CLOSE_PROC_STREAM(proc, err);
+ stream_may_close(&proc->in);
+ stream_may_close(&proc->out);
+ stream_may_close(&proc->err);
}
/// Synchronously wait for a process to finish
///
-/// @param process The Process instance
-/// @param ms Number of milliseconds to wait, 0 for not waiting, -1 for
-/// waiting until the process quits.
-/// @return returns the status code of the exited process. -1 if the process is
-/// still running and the `timeout` has expired. Note that this is
-/// indistinguishable from the process returning -1 by itself. Which
-/// is possible on some OS. Returns -2 if an user has interruped the
-/// wait.
-int process_wait(Process *proc, int ms, Queue *events) FUNC_ATTR_NONNULL_ARG(1)
+/// @param process Process instance
+/// @param ms Time in milliseconds to wait for the process.
+/// 0 for no wait. -1 to wait until the process quits.
+/// @return Exit code of the process. proc->status will have the same value.
+/// -1 if the timeout expired while the process is still running.
+/// -2 if the user interruped the wait.
+int process_wait(Process *proc, int ms, MultiQueue *events)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- // The default status is -1, which represents a timeout
- int status = -1;
- bool interrupted = false;
if (!proc->refcount) {
+ int status = proc->status;
LOOP_PROCESS_EVENTS(proc->loop, proc->events, 0);
- return proc->status;
+ return status;
}
if (!events) {
events = proc->events;
}
- // Increase refcount to stop the exit callback from being called(and possibly
- // being freed) before we have a chance to get the status.
+ // Increase refcount to stop the exit callback from being called (and possibly
+ // freed) before we have a chance to get the status.
proc->refcount++;
LOOP_PROCESS_EVENTS_UNTIL(proc->loop, events, ms,
// Until...
@@ -194,7 +174,6 @@ int process_wait(Process *proc, int ms, Queue *events) FUNC_ATTR_NONNULL_ARG(1)
// we'll assume that a user frantically hitting interrupt doesn't like
// the current job. Signal that it has to be killed.
if (got_int) {
- interrupted = true;
got_int = false;
process_stop(proc);
if (ms == -1) {
@@ -205,38 +184,40 @@ int process_wait(Process *proc, int ms, Queue *events) FUNC_ATTR_NONNULL_ARG(1)
} else {
LOOP_PROCESS_EVENTS(proc->loop, events, 0);
}
+
+ proc->status = -2;
}
if (proc->refcount == 1) {
- // Job exited, collect status and manually invoke close_cb to free the job
- // resources
- status = interrupted ? -2 : proc->status;
+ // Job exited, free its resources.
decref(proc);
if (events) {
// the decref call created an exit event, process it now
- queue_process_events(events);
+ multiqueue_process_events(events);
}
} else {
proc->refcount--;
}
- return status;
+ return proc->status;
}
/// Ask a process to terminate and eventually kill if it doesn't respond
void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
{
- if (proc->stopped_time) {
+ bool exited = (proc->status >= 0);
+ if (exited || proc->stopped_time) {
return;
}
-
proc->stopped_time = os_hrtime();
+
switch (proc->type) {
case kProcessTypeUv:
// Close the process's stdin. If the process doesn't close its own
// stdout/stderr, they will be closed when it exits(possibly due to being
// terminated after a timeout)
- process_close_in(proc);
+ stream_may_close(&proc->in);
+ os_proc_tree_kill(proc->pid, SIGTERM);
break;
case kProcessTypePty:
// close all streams for pty processes to send SIGHUP to the process
@@ -247,36 +228,32 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL
abort();
}
- Loop *loop = proc->loop;
- if (!loop->children_stop_requests++) {
- // When there's at least one stop request pending, start a timer that
- // will periodically check if a signal should be send to a to the job
- DLOG("Starting job kill timer");
- uv_timer_start(&loop->children_kill_timer, children_kill_cb, 100, 100);
- }
+ // (Re)start timer to verify that stopped process(es) died.
+ uv_timer_start(&proc->loop->children_kill_timer, children_kill_cb,
+ KILL_TIMEOUT_MS, 0);
}
-/// Iterates the process list sending SIGTERM to stopped processes and SIGKILL
-/// to those that didn't die from SIGTERM after a while(exit_timeout is 0).
+/// Sends SIGKILL (or SIGTERM..SIGKILL for PTY jobs) to processes that did
+/// not terminate after process_stop().
static void children_kill_cb(uv_timer_t *handle)
{
Loop *loop = handle->loop->data;
- uint64_t now = os_hrtime();
kl_iter(WatcherPtr, loop->children, current) {
Process *proc = (*current)->data;
- if (!proc->stopped_time) {
+ bool exited = (proc->status >= 0);
+ if (exited || !proc->stopped_time) {
continue;
}
- uint64_t elapsed = now - proc->stopped_time;
-
- if (!proc->term_sent && elapsed >= TERM_TIMEOUT) {
- ILOG("Sending SIGTERM to pid %d", proc->pid);
- uv_kill(proc->pid, SIGTERM);
- proc->term_sent = true;
- } else if (elapsed >= KILL_TIMEOUT) {
- ILOG("Sending SIGKILL to pid %d", proc->pid);
- uv_kill(proc->pid, SIGKILL);
+ uint64_t term_sent = UINT64_MAX == proc->stopped_time;
+ if (kProcessTypePty != proc->type || term_sent) {
+ os_proc_tree_kill(proc->pid, SIGKILL);
+ } else {
+ os_proc_tree_kill(proc->pid, SIGTERM);
+ proc->stopped_time = UINT64_MAX; // Flag: SIGTERM was sent.
+ // Restart timer.
+ uv_timer_start(&proc->loop->children_kill_timer, children_kill_cb,
+ KILL_TIMEOUT_MS, 0);
}
}
}
@@ -288,7 +265,7 @@ static void process_close_event(void **argv)
if (proc->type == kProcessTypePty) {
xfree(((PtyProcess *)proc)->term_name);
}
- if (proc->cb) {
+ if (proc->cb) { // "on_exit" for jobstart(). See channel_job_start().
proc->cb(proc, proc->status, proc->data);
}
}
@@ -315,12 +292,21 @@ static void decref(Process *proc)
static void process_close(Process *proc)
FUNC_ATTR_NONNULL_ARG(1)
{
- if (process_is_tearing_down && proc->detach && proc->closed) {
- // If a detached process dies while tearing down it might get closed twice.
+ if (process_is_tearing_down && (proc->detach || proc->type == kProcessTypePty)
+ && proc->closed) {
+ // If a detached/pty process dies while tearing down it might get closed
+ // twice.
return;
}
assert(!proc->closed);
proc->closed = true;
+
+ if (proc->detach) {
+ if (proc->type == kProcessTypeUv) {
+ uv_unref((uv_handle_t *)&(((LibuvProcess *)proc)->uv));
+ }
+ }
+
switch (proc->type) {
case kProcessTypeUv:
libuv_process_close((LibuvProcess *)proc);
@@ -365,16 +351,16 @@ static void flush_stream(Process *proc, Stream *stream)
// Poll for data and process the generated events.
loop_poll_events(proc->loop, 0);
- if (proc->events) {
- queue_process_events(proc->events);
+ if (stream->events) {
+ multiqueue_process_events(stream->events);
}
// Stream can be closed if it is empty.
- if (num_bytes == stream->num_bytes) {
- if (stream->read_cb) {
+ if (num_bytes == stream->num_bytes) { // -V547
+ if (stream->read_cb && !stream->did_eof) {
// Stream callback could miss EOF handling if a child keeps the stream
- // open.
- stream->read_cb(stream, stream->buffer, 0, stream->data, true);
+ // open. But only send EOF if we haven't already.
+ stream->read_cb(stream, stream->buffer, 0, stream->cb_data, true);
}
break;
}
@@ -385,8 +371,8 @@ static void process_close_handles(void **argv)
{
Process *proc = argv[0];
- flush_stream(proc, proc->out);
- flush_stream(proc, proc->err);
+ flush_stream(proc, &proc->out);
+ flush_stream(proc, &proc->err);
process_close_streams(proc);
process_close(proc);
@@ -395,18 +381,14 @@ static void process_close_handles(void **argv)
static void on_process_exit(Process *proc)
{
Loop *loop = proc->loop;
- if (proc->stopped_time && loop->children_stop_requests
- && !--loop->children_stop_requests) {
- // Stop the timer if no more stop requests are pending
- DLOG("Stopping process kill timer");
- uv_timer_stop(&loop->children_kill_timer);
- }
+ ILOG("exited: pid=%d status=%d stoptime=%" PRIu64, proc->pid, proc->status,
+ proc->stopped_time);
// Process has terminated, but there could still be data to be read from the
// OS. We are still in the libuv loop, so we cannot call code that polls for
// more data directly. Instead delay the reading after the libuv loop by
// queueing process_close_handles() as an event.
- Queue *queue = proc->events ? proc->events : loop->events;
+ MultiQueue *queue = proc->events ? proc->events : loop->events;
CREATE_EVENT(queue, process_close_handles, 1, proc);
}
diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h
index a4c6e7eeb2..ba2c2a6a11 100644
--- a/src/nvim/event/process.h
+++ b/src/nvim/event/process.h
@@ -19,17 +19,17 @@ struct process {
Loop *loop;
void *data;
int pid, status, refcount;
- // set to the hrtime of when process_stop was called for the process.
- uint64_t stopped_time;
- char *cwd;
+ uint64_t stopped_time; // process_stop() timestamp
+ const char *cwd;
char **argv;
- Stream *in, *out, *err;
+ Stream in, out, err;
process_exit_cb cb;
internal_process_cb internal_exit_cb, internal_close_cb;
- bool closed, term_sent, detach;
- Queue *events;
+ bool closed, detach;
+ MultiQueue *events;
};
+
static inline Process process_init(Loop *loop, ProcessType type, void *data)
{
return (Process) {
@@ -38,23 +38,27 @@ static inline Process process_init(Loop *loop, ProcessType type, void *data)
.loop = loop,
.events = NULL,
.pid = 0,
- .status = 0,
+ .status = -1,
.refcount = 0,
.stopped_time = 0,
.cwd = NULL,
.argv = NULL,
- .in = NULL,
- .out = NULL,
- .err = NULL,
+ .in = { .closed = false },
+ .out = { .closed = false },
+ .err = { .closed = false },
.cb = NULL,
.closed = false,
- .term_sent = false,
.internal_close_cb = NULL,
.internal_exit_cb = NULL,
.detach = false
};
}
+static inline bool process_is_stopped(Process *proc)
+{
+ return proc->stopped_time != 0;
+}
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/process.h.generated.h"
#endif
diff --git a/src/nvim/event/queue.c b/src/nvim/event/queue.c
deleted file mode 100644
index c5ef22d426..0000000000
--- a/src/nvim/event/queue.c
+++ /dev/null
@@ -1,208 +0,0 @@
-// Queue for selective async event processing. Instances of this queue support a
-// parent/child relationship with the following properties:
-//
-// - pushing a node to a child queue will push a corresponding link node to the
-// parent queue
-// - removing a link node from a parent queue will remove the next node
-// in the linked child queue
-// - removing a node from a child queue will remove the corresponding link node
-// in the parent queue
-//
-// These properties allow neovim to organize and process events from different
-// sources with a certain degree of control. Here's how the queue is used:
-//
-// +----------------+
-// | Main loop |
-// +----------------+
-// ^
-// |
-// +----------------+
-// +-------------->| Event loop |<------------+
-// | +--+-------------+ |
-// | ^ ^ |
-// | | | |
-// +-----------+ +-----------+ +---------+ +---------+
-// | Channel 1 | | Channel 2 | | Job 1 | | Job 2 |
-// +-----------+ +-----------+ +---------+ +---------+
-//
-//
-// In the above diagram, the lower boxes represents event emitters, each with
-// it's own private queue that have the event loop queue as the parent.
-//
-// When idle, the main loop spins the event loop which queues events from many
-// sources(channels, jobs, user...). Each event emitter pushes events to its own
-// private queue which is propagated to the event loop queue. When the main loop
-// consumes an event, the corresponding event is removed from the emitter's
-// queue.
-//
-// The main reason for this queue hierarchy is to allow focusing on a single
-// event emitter while blocking the main loop. For example, if the `jobwait`
-// vimscript function is called on job1, the main loop will temporarily stop
-// polling the event loop queue and poll job1 queue instead. Same with channels,
-// when calling `rpcrequest`, we want to temporarily stop processing events from
-// other sources and focus on a specific channel.
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-
-#include <uv.h>
-
-#include "nvim/event/queue.h"
-#include "nvim/memory.h"
-#include "nvim/os/time.h"
-
-typedef struct queue_item QueueItem;
-struct queue_item {
- union {
- Queue *queue;
- struct {
- Event event;
- QueueItem *parent;
- } item;
- } data;
- bool link; // this is just a link to a node in a child queue
- QUEUE node;
-};
-
-struct queue {
- Queue *parent;
- QUEUE headtail;
- put_callback put_cb;
- void *data;
-};
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "event/queue.c.generated.h"
-#endif
-
-static Event NILEVENT = {.handler = NULL, .argv = {NULL}};
-
-Queue *queue_new_parent(put_callback put_cb, void *data)
-{
- return queue_new(NULL, put_cb, data);
-}
-
-Queue *queue_new_child(Queue *parent)
- FUNC_ATTR_NONNULL_ALL
-{
- assert(!parent->parent);
- return queue_new(parent, NULL, NULL);
-}
-
-static Queue *queue_new(Queue *parent, put_callback put_cb, void *data)
-{
- Queue *rv = xmalloc(sizeof(Queue));
- QUEUE_INIT(&rv->headtail);
- rv->parent = parent;
- rv->put_cb = put_cb;
- rv->data = data;
- return rv;
-}
-
-void queue_free(Queue *queue)
-{
- assert(queue);
- while (!QUEUE_EMPTY(&queue->headtail)) {
- QUEUE *q = QUEUE_HEAD(&queue->headtail);
- QueueItem *item = queue_node_data(q);
- if (queue->parent) {
- QUEUE_REMOVE(&item->data.item.parent->node);
- xfree(item->data.item.parent);
- }
- QUEUE_REMOVE(q);
- xfree(item);
- }
-
- xfree(queue);
-}
-
-Event queue_get(Queue *queue)
-{
- return queue_empty(queue) ? NILEVENT : queue_remove(queue);
-}
-
-void queue_put_event(Queue *queue, Event event)
-{
- assert(queue);
- queue_push(queue, event);
- if (queue->parent && queue->parent->put_cb) {
- queue->parent->put_cb(queue->parent, queue->parent->data);
- }
-}
-
-void queue_process_events(Queue *queue)
-{
- assert(queue);
- while (!queue_empty(queue)) {
- Event event = queue_get(queue);
- if (event.handler) {
- event.handler(event.argv);
- }
- }
-}
-
-bool queue_empty(Queue *queue)
-{
- assert(queue);
- return QUEUE_EMPTY(&queue->headtail);
-}
-
-void queue_replace_parent(Queue *queue, Queue *new_parent)
-{
- assert(queue_empty(queue));
- queue->parent = new_parent;
-}
-
-static Event queue_remove(Queue *queue)
-{
- assert(!queue_empty(queue));
- QUEUE *h = QUEUE_HEAD(&queue->headtail);
- QUEUE_REMOVE(h);
- QueueItem *item = queue_node_data(h);
- Event rv;
-
- if (item->link) {
- assert(!queue->parent);
- // remove the next node in the linked queue
- Queue *linked = item->data.queue;
- assert(!queue_empty(linked));
- QueueItem *child =
- queue_node_data(QUEUE_HEAD(&linked->headtail));
- QUEUE_REMOVE(&child->node);
- rv = child->data.item.event;
- xfree(child);
- } else {
- if (queue->parent) {
- // remove the corresponding link node in the parent queue
- QUEUE_REMOVE(&item->data.item.parent->node);
- xfree(item->data.item.parent);
- }
- rv = item->data.item.event;
- }
-
- xfree(item);
- return rv;
-}
-
-static void queue_push(Queue *queue, Event event)
-{
- QueueItem *item = xmalloc(sizeof(QueueItem));
- item->link = false;
- item->data.item.event = event;
- QUEUE_INSERT_TAIL(&queue->headtail, &item->node);
- if (queue->parent) {
- // push link node to the parent queue
- item->data.item.parent = xmalloc(sizeof(QueueItem));
- item->data.item.parent->link = true;
- item->data.item.parent->data.queue = queue;
- QUEUE_INSERT_TAIL(&queue->parent->headtail, &item->data.item.parent->node);
- }
-}
-
-static QueueItem *queue_node_data(QUEUE *q)
-{
- return QUEUE_DATA(q, QueueItem, node);
-}
diff --git a/src/nvim/event/queue.h b/src/nvim/event/queue.h
deleted file mode 100644
index 85fc59f8b2..0000000000
--- a/src/nvim/event/queue.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef NVIM_EVENT_QUEUE_H
-#define NVIM_EVENT_QUEUE_H
-
-#include <uv.h>
-
-#include "nvim/event/defs.h"
-#include "nvim/lib/queue.h"
-
-typedef struct queue Queue;
-typedef void (*put_callback)(Queue *queue, void *data);
-
-#define queue_put(q, h, ...) \
- queue_put_event(q, event_create(1, h, __VA_ARGS__));
-
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "event/queue.h.generated.h"
-#endif
-#endif // NVIM_EVENT_QUEUE_H
diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c
index a520143064..6812b342bf 100644
--- a/src/nvim/event/rstream.c
+++ b/src/nvim/event/rstream.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 <stdint.h>
#include <stdbool.h>
@@ -17,21 +20,19 @@
# include "event/rstream.c.generated.h"
#endif
-void rstream_init_fd(Loop *loop, Stream *stream, int fd, size_t bufsize,
- void *data)
+void rstream_init_fd(Loop *loop, Stream *stream, int fd, size_t bufsize)
FUNC_ATTR_NONNULL_ARG(1)
FUNC_ATTR_NONNULL_ARG(2)
{
- stream_init(loop, stream, fd, NULL, data);
+ stream_init(loop, stream, fd, NULL);
rstream_init(stream, bufsize);
}
-void rstream_init_stream(Stream *stream, uv_stream_t *uvstream, size_t bufsize,
- void *data)
+void rstream_init_stream(Stream *stream, uv_stream_t *uvstream, size_t bufsize)
FUNC_ATTR_NONNULL_ARG(1)
FUNC_ATTR_NONNULL_ARG(2)
{
- stream_init(NULL, stream, -1, uvstream, data);
+ stream_init(NULL, stream, -1, uvstream);
rstream_init(stream, bufsize);
}
@@ -48,10 +49,11 @@ void rstream_init(Stream *stream, size_t bufsize)
/// Starts watching for events from a `Stream` instance.
///
/// @param stream The `Stream` instance
-void rstream_start(Stream *stream, stream_read_cb cb)
+void rstream_start(Stream *stream, stream_read_cb cb, void *data)
FUNC_ATTR_NONNULL_ARG(1)
{
stream->read_cb = cb;
+ stream->cb_data = data;
if (stream->uvstream) {
uv_read_start(stream->uvstream, alloc_cb, read_cb);
} else {
@@ -81,7 +83,7 @@ static void on_rbuffer_nonfull(RBuffer *buf, void *data)
{
Stream *stream = data;
assert(stream->read_cb);
- rstream_start(stream, stream->read_cb);
+ rstream_start(stream, stream->read_cb, stream->cb_data);
}
// Callbacks used by libuv
@@ -90,7 +92,10 @@ static void on_rbuffer_nonfull(RBuffer *buf, void *data)
static void alloc_cb(uv_handle_t *handle, size_t suggested, uv_buf_t *buf)
{
Stream *stream = handle->data;
- buf->base = rbuffer_write_ptr(stream->buffer, &buf->len);
+ // `uv_buf_t.len` happens to have different size on Windows.
+ size_t write_count;
+ buf->base = rbuffer_write_ptr(stream->buffer, &write_count);
+ buf->len = UV_BUF_LEN(write_count);
}
// Callback invoked by libuv after it copies the data into the buffer provided
@@ -100,21 +105,21 @@ static void read_cb(uv_stream_t *uvstream, ssize_t cnt, const uv_buf_t *buf)
{
Stream *stream = uvstream->data;
- if (cnt > 0) {
- stream->num_bytes += (size_t)cnt;
- }
-
if (cnt <= 0) {
- if (cnt != UV_ENOBUFS
- // cnt == 0 means libuv asked for a buffer and decided it wasn't needed:
- // http://docs.libuv.org/en/latest/stream.html#c.uv_read_start.
- //
- // We don't need to do anything with the RBuffer because the next call
- // to `alloc_cb` will return the same unused pointer(`rbuffer_produced`
- // won't be called)
- && cnt != 0) {
- DLOG("Closing Stream(%p) because of %s(%zd)", stream,
- uv_strerror((int)cnt), cnt);
+ // cnt == 0 means libuv asked for a buffer and decided it wasn't needed:
+ // http://docs.libuv.org/en/latest/stream.html#c.uv_read_start.
+ //
+ // We don't need to do anything with the RBuffer because the next call
+ // to `alloc_cb` will return the same unused pointer(`rbuffer_produced`
+ // won't be called)
+ if (cnt == UV_ENOBUFS || cnt == 0) {
+ return;
+ } else if (cnt == UV_EOF && uvstream->type == UV_TTY) {
+ // The TTY driver might signal EOF without closing the stream
+ invoke_read_cb(stream, 0, true);
+ } else {
+ DLOG("Closing Stream (%p): %s (%s)", stream,
+ uv_err_name((int)cnt), os_strerror((int)cnt));
// Read error or EOF, either way stop the stream and invoke the callback
// with eof == true
uv_read_stop(uvstream);
@@ -125,6 +130,7 @@ static void read_cb(uv_stream_t *uvstream, ssize_t cnt, const uv_buf_t *buf)
// at this point we're sure that cnt is positive, no error occurred
size_t nread = (size_t)cnt;
+ stream->num_bytes += nread;
// Data was already written, so all we need is to update 'wpos' to reflect
// the space actually used in the buffer.
rbuffer_produced(stream->buffer, nread);
@@ -137,7 +143,10 @@ static void fread_idle_cb(uv_idle_t *handle)
uv_fs_t req;
Stream *stream = handle->data;
- stream->uvbuf.base = rbuffer_write_ptr(stream->buffer, &stream->uvbuf.len);
+ // `uv_buf_t.len` happens to have different size on Windows.
+ size_t write_count;
+ stream->uvbuf.base = rbuffer_write_ptr(stream->buffer, &write_count);
+ stream->uvbuf.len = UV_BUF_LEN(write_count);
// the offset argument to uv_fs_read is int64_t, could someone really try
// to read more than 9 quintillion (9e18) bytes?
@@ -179,7 +188,8 @@ static void read_event(void **argv)
if (stream->read_cb) {
size_t count = (uintptr_t)argv[1];
bool eof = (uintptr_t)argv[2];
- stream->read_cb(stream, stream->buffer, count, stream->data, eof);
+ stream->did_eof = eof;
+ stream->read_cb(stream, stream->buffer, count, stream->cb_data, eof);
}
stream->pending_reqs--;
if (stream->closed && !stream->pending_reqs) {
diff --git a/src/nvim/event/signal.c b/src/nvim/event/signal.c
index 11ce15a882..fec46da4ff 100644
--- a/src/nvim/event/signal.c
+++ b/src/nvim/event/signal.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 <uv.h>
#include "nvim/event/loop.h"
diff --git a/src/nvim/event/signal.h b/src/nvim/event/signal.h
index e32608acc0..7fe352edef 100644
--- a/src/nvim/event/signal.h
+++ b/src/nvim/event/signal.h
@@ -14,7 +14,7 @@ struct signal_watcher {
void *data;
signal_cb cb;
signal_close_cb close_cb;
- Queue *events;
+ MultiQueue *events;
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c
index cdaf40849b..6fcb9f7e7a 100644
--- a/src/nvim/event/socket.c
+++ b/src/nvim/event/socket.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 <stdint.h>
@@ -12,99 +15,123 @@
#include "nvim/vim.h"
#include "nvim/strings.h"
#include "nvim/path.h"
+#include "nvim/main.h"
#include "nvim/memory.h"
+#include "nvim/macros.h"
+#include "nvim/charset.h"
+#include "nvim/log.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "event/socket.c.generated.h"
#endif
-#define NVIM_DEFAULT_TCP_PORT 7450
-
-void socket_watcher_init(Loop *loop, SocketWatcher *watcher,
- const char *endpoint, void *data)
- FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(3)
+int socket_watcher_init(Loop *loop, SocketWatcher *watcher,
+ const char *endpoint)
+ FUNC_ATTR_NONNULL_ALL
{
- // Trim to `ADDRESS_MAX_SIZE`
- if (xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr))
- >= sizeof(watcher->addr)) {
- // TODO(aktau): since this is not what the user wanted, perhaps we
- // should return an error here
- WLOG("Address was too long, truncated to %s", watcher->addr);
- }
-
- bool tcp = true;
- char ip[16], *ip_end = xstrchrnul(watcher->addr, ':');
+ xstrlcpy(watcher->addr, endpoint, sizeof(watcher->addr));
+ char *addr = watcher->addr;
+ char *host_end = strrchr(addr, ':');
- // (ip_end - addr) is always > 0, so convert to size_t
- size_t addr_len = (size_t)(ip_end - watcher->addr);
+ if (host_end && addr != host_end) {
+ // Split user specified address into two strings, addr(hostname) and port.
+ // The port part in watcher->addr will be updated later.
+ *host_end = '\0';
+ char *port = host_end + 1;
+ intmax_t iport;
- if (addr_len > sizeof(ip) - 1) {
- // Maximum length of an IPv4 address buffer is 15 (eg: 255.255.255.255)
- addr_len = sizeof(ip) - 1;
- }
+ int ret = getdigits_safe(&(char_u *){ (char_u *)port }, &iport);
+ if (ret == FAIL || iport < 0 || iport > UINT16_MAX) {
+ ELOG("Invalid port: %s", port);
+ return UV_EINVAL;
+ }
- // Extract the address part
- xstrlcpy(ip, watcher->addr, addr_len + 1);
- int port = NVIM_DEFAULT_TCP_PORT;
-
- if (*ip_end == ':') {
- // Extract the port
- long lport = strtol(ip_end + 1, NULL, 10); // NOLINT
- if (lport <= 0 || lport > 0xffff) {
- // Invalid port, treat as named pipe or unix socket
- tcp = false;
- } else {
- port = (int) lport;
+ if (*port == NUL) {
+ // When no port is given, (uv_)getaddrinfo expects NULL otherwise the
+ // implementation may attempt to lookup the service by name (and fail)
+ port = NULL;
}
- }
- if (tcp) {
- // Try to parse ip address
- if (uv_ip4_addr(ip, port, &watcher->uv.tcp.addr)) {
- // Invalid address, treat as named pipe or unix socket
- tcp = false;
+ uv_getaddrinfo_t request;
+
+ int retval = uv_getaddrinfo(&loop->uv, &request, NULL, addr, port,
+ &(struct addrinfo){
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ });
+ if (retval != 0) {
+ ELOG("Host lookup failed: %s", endpoint);
+ return retval;
}
- }
+ watcher->uv.tcp.addrinfo = request.addrinfo;
- if (tcp) {
uv_tcp_init(&loop->uv, &watcher->uv.tcp.handle);
- watcher->stream = (uv_stream_t *)&watcher->uv.tcp.handle;
+ uv_tcp_nodelay(&watcher->uv.tcp.handle, true);
+ watcher->stream = STRUCT_CAST(uv_stream_t, &watcher->uv.tcp.handle);
} else {
uv_pipe_init(&loop->uv, &watcher->uv.pipe.handle, 0);
- watcher->stream = (uv_stream_t *)&watcher->uv.pipe.handle;
+ watcher->stream = STRUCT_CAST(uv_stream_t, &watcher->uv.pipe.handle);
}
watcher->stream->data = watcher;
watcher->cb = NULL;
watcher->close_cb = NULL;
watcher->events = NULL;
+ watcher->data = NULL;
+
+ return 0;
}
int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb)
FUNC_ATTR_NONNULL_ALL
{
watcher->cb = cb;
- int result;
+ int result = UV_EINVAL;
if (watcher->stream->type == UV_TCP) {
- result = uv_tcp_bind(&watcher->uv.tcp.handle,
- (const struct sockaddr *)&watcher->uv.tcp.addr, 0);
+ struct addrinfo *ai = watcher->uv.tcp.addrinfo;
+
+ for (; ai; ai = ai->ai_next) {
+ result = uv_tcp_bind(&watcher->uv.tcp.handle, ai->ai_addr, 0);
+ if (result != 0) {
+ continue;
+ }
+ result = uv_listen(watcher->stream, backlog, connection_cb);
+ if (result == 0) {
+ struct sockaddr_storage sas;
+
+ // When the endpoint in socket_watcher_init() didn't specify a port
+ // number, a free random port number will be assigned. sin_port will
+ // contain 0 in this case, unless uv_tcp_getsockname() is used first.
+ uv_tcp_getsockname(&watcher->uv.tcp.handle, (struct sockaddr *)&sas,
+ &(int){ sizeof(sas) });
+ uint16_t port = (uint16_t)(
+ (sas.ss_family == AF_INET)
+ ? (STRUCT_CAST(struct sockaddr_in, &sas))->sin_port
+ : (STRUCT_CAST(struct sockaddr_in6, &sas))->sin6_port);
+ // v:servername uses the string from watcher->addr
+ size_t len = strlen(watcher->addr);
+ snprintf(watcher->addr+len, sizeof(watcher->addr)-len, ":%" PRIu16,
+ ntohs(port));
+ break;
+ }
+ }
+ uv_freeaddrinfo(watcher->uv.tcp.addrinfo);
} else {
result = uv_pipe_bind(&watcher->uv.pipe.handle, watcher->addr);
- }
-
- if (result == 0) {
- result = uv_listen(watcher->stream, backlog, connection_cb);
+ if (result == 0) {
+ result = uv_listen(watcher->stream, backlog, connection_cb);
+ }
}
assert(result <= 0); // libuv should return negative error code or zero.
if (result < 0) {
- if (result == -EACCES) {
+ if (result == UV_EACCES) {
// Libuv converts ENOENT to EACCES for Windows compatibility, but if
// the parent directory does not exist, ENOENT would be more accurate.
*path_tail((char_u *)watcher->addr) = NUL;
if (!os_path_exists((char_u *)watcher->addr)) {
- result = -ENOENT;
+ result = UV_ENOENT;
}
}
return result;
@@ -113,16 +140,17 @@ int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb)
return 0;
}
-int socket_watcher_accept(SocketWatcher *watcher, Stream *stream, void *data)
+int socket_watcher_accept(SocketWatcher *watcher, Stream *stream)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2)
{
uv_stream_t *client;
if (watcher->stream->type == UV_TCP) {
- client = (uv_stream_t *)&stream->uv.tcp;
+ client = STRUCT_CAST(uv_stream_t, &stream->uv.tcp);
uv_tcp_init(watcher->uv.tcp.handle.loop, (uv_tcp_t *)client);
+ uv_tcp_nodelay((uv_tcp_t *)client, true);
} else {
- client = (uv_stream_t *)&stream->uv.pipe;
+ client = STRUCT_CAST(uv_stream_t, &stream->uv.pipe);
uv_pipe_init(watcher->uv.pipe.handle.loop, (uv_pipe_t *)client, 0);
}
@@ -133,7 +161,7 @@ int socket_watcher_accept(SocketWatcher *watcher, Stream *stream, void *data)
return result;
}
- stream_init(NULL, stream, -1, client, data);
+ stream_init(NULL, stream, -1, client);
return 0;
}
@@ -165,3 +193,77 @@ static void close_cb(uv_handle_t *handle)
watcher->close_cb(watcher, watcher->data);
}
}
+
+static void connect_cb(uv_connect_t *req, int status)
+{
+ int *ret_status = req->data;
+ *ret_status = status;
+ if (status != 0) {
+ uv_close((uv_handle_t *)req->handle, NULL);
+ }
+}
+
+bool socket_connect(Loop *loop, Stream *stream,
+ bool is_tcp, const char *address,
+ int timeout, const char **error)
+{
+ bool success = false;
+ int status;
+ uv_connect_t req;
+ req.data = &status;
+ uv_stream_t *uv_stream;
+
+ uv_tcp_t *tcp = &stream->uv.tcp;
+ uv_getaddrinfo_t addr_req;
+ addr_req.addrinfo = NULL;
+ const struct addrinfo *addrinfo = NULL;
+ char *addr = NULL;
+ if (is_tcp) {
+ addr = xstrdup(address);
+ char *host_end = strrchr(addr, ':');
+ if (!host_end) {
+ *error = _("tcp address must be host:port");
+ goto cleanup;
+ }
+ *host_end = NUL;
+
+ const struct addrinfo hints = { .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM,
+ .ai_flags = AI_NUMERICSERV };
+ int retval = uv_getaddrinfo(&loop->uv, &addr_req, NULL,
+ addr, host_end+1, &hints);
+ if (retval != 0) {
+ *error = _("failed to lookup host or port");
+ goto cleanup;
+ }
+ addrinfo = addr_req.addrinfo;
+
+tcp_retry:
+ uv_tcp_init(&loop->uv, tcp);
+ uv_tcp_nodelay(tcp, true);
+ uv_tcp_connect(&req, tcp, addrinfo->ai_addr, connect_cb);
+ uv_stream = (uv_stream_t *)tcp;
+
+ } else {
+ uv_pipe_t *pipe = &stream->uv.pipe;
+ uv_pipe_init(&loop->uv, pipe, 0);
+ uv_pipe_connect(&req, pipe, address, connect_cb);
+ uv_stream = STRUCT_CAST(uv_stream_t, pipe);
+ }
+ status = 1;
+ LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, timeout, status != 1);
+ if (status == 0) { // -V547
+ stream_init(NULL, stream, -1, uv_stream);
+ success = true;
+ } else if (is_tcp && addrinfo->ai_next) {
+ addrinfo = addrinfo->ai_next;
+ goto tcp_retry;
+ } else {
+ *error = _("connection refused");
+ }
+
+cleanup:
+ xfree(addr);
+ uv_freeaddrinfo(addr_req.addrinfo);
+ return success;
+}
diff --git a/src/nvim/event/socket.h b/src/nvim/event/socket.h
index ad59fdbe3a..d30ae45502 100644
--- a/src/nvim/event/socket.h
+++ b/src/nvim/event/socket.h
@@ -20,7 +20,7 @@ struct socket_watcher {
union {
struct {
uv_tcp_t handle;
- struct sockaddr_in addr;
+ struct addrinfo *addrinfo;
} tcp;
struct {
uv_pipe_t handle;
@@ -30,7 +30,7 @@ struct socket_watcher {
void *data;
socket_cb cb;
socket_close_cb close_cb;
- Queue *events;
+ MultiQueue *events;
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
index 33404158cf..ba25b76ec7 100644
--- a/src/nvim/event/stream.c
+++ b/src/nvim/event/stream.c
@@ -1,10 +1,15 @@
+// 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 <stdio.h>
#include <stdbool.h>
#include <uv.h>
+#include "nvim/log.h"
#include "nvim/rbuffer.h"
+#include "nvim/macros.h"
#include "nvim/event/stream.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -23,15 +28,15 @@ int stream_set_blocking(int fd, bool blocking)
uv_loop_init(&loop);
uv_pipe_init(&loop, &stream, 0);
uv_pipe_open(&stream, fd);
- int retval = uv_stream_set_blocking((uv_stream_t *)&stream, blocking);
- uv_close((uv_handle_t *)&stream, NULL);
+ int retval = uv_stream_set_blocking(STRUCT_CAST(uv_stream_t, &stream),
+ blocking);
+ uv_close(STRUCT_CAST(uv_handle_t, &stream), NULL);
uv_run(&loop, UV_RUN_NOWAIT); // not necessary, but couldn't hurt.
uv_loop_close(&loop);
return retval;
}
-void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream,
- void *data)
+void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream)
FUNC_ATTR_NONNULL_ARG(2)
{
stream->uvstream = uvstream;
@@ -50,7 +55,7 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream,
assert(type == UV_NAMED_PIPE || type == UV_TTY);
uv_pipe_init(&loop->uv, &stream->uv.pipe, 0);
uv_pipe_open(&stream->uv.pipe, fd);
- stream->uvstream = (uv_stream_t *)&stream->uv.pipe;
+ stream->uvstream = STRUCT_CAST(uv_stream_t, &stream->uv.pipe);
}
}
@@ -58,7 +63,6 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream,
stream->uvstream->data = stream;
}
- stream->data = data;
stream->internal_data = NULL;
stream->fpos = 0;
stream->curmem = 0;
@@ -74,18 +78,27 @@ void stream_init(Loop *loop, Stream *stream, int fd, uv_stream_t *uvstream,
stream->num_bytes = 0;
}
-void stream_close(Stream *stream, stream_close_cb on_stream_close)
+void stream_close(Stream *stream, stream_close_cb on_stream_close, void *data)
FUNC_ATTR_NONNULL_ARG(1)
{
assert(!stream->closed);
+ DLOG("closing Stream: %p", stream);
stream->closed = true;
stream->close_cb = on_stream_close;
+ stream->close_cb_data = data;
if (!stream->pending_reqs) {
stream_close_handle(stream);
}
}
+void stream_may_close(Stream *stream)
+{
+ if (!stream->closed) {
+ stream_close(stream, NULL, NULL);
+ }
+}
+
void stream_close_handle(Stream *stream)
FUNC_ATTR_NONNULL_ALL
{
@@ -103,7 +116,7 @@ static void close_cb(uv_handle_t *handle)
rbuffer_free(stream->buffer);
}
if (stream->close_cb) {
- stream->close_cb(stream, stream->data);
+ stream->close_cb(stream, stream->close_cb_data);
}
if (stream->internal_close_cb) {
stream->internal_close_cb(stream, stream->internal_data);
diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h
index ad4e24775b..e713323f5c 100644
--- a/src/nvim/event/stream.h
+++ b/src/nvim/event/stream.h
@@ -14,10 +14,7 @@ typedef struct stream Stream;
///
/// @param stream The Stream instance
/// @param rbuffer The associated RBuffer instance
-/// @param count Number of bytes to read. This must be respected if keeping
-/// the order of events is a requirement. This is because events
-/// may be queued and only processed later when more data is copied
-/// into to the buffer, so one read may starve another.
+/// @param count Number of bytes that was read.
/// @param data User-defined data
/// @param eof If the stream reached EOF.
typedef void (*stream_read_cb)(Stream *stream, RBuffer *buf, size_t count,
@@ -33,6 +30,8 @@ typedef void (*stream_write_cb)(Stream *stream, void *data, int status);
typedef void (*stream_close_cb)(Stream *stream, void *data);
struct stream {
+ bool closed;
+ bool did_eof;
union {
uv_pipe_t pipe;
uv_tcp_t tcp;
@@ -44,15 +43,15 @@ struct stream {
uv_file fd;
stream_read_cb read_cb;
stream_write_cb write_cb;
+ void *cb_data;
stream_close_cb close_cb, internal_close_cb;
+ void *close_cb_data, *internal_data;
size_t fpos;
size_t curmem;
size_t maxmem;
size_t pending_reqs;
size_t num_bytes;
- void *data, *internal_data;
- bool closed;
- Queue *events;
+ MultiQueue *events;
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c
index f68a66345f..b7e30e392b 100644
--- a/src/nvim/event/time.c
+++ b/src/nvim/event/time.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 <stdint.h>
#include <uv.h>
@@ -51,17 +54,24 @@ static void time_watcher_cb(uv_timer_t *handle)
FUNC_ATTR_NONNULL_ALL
{
TimeWatcher *watcher = handle->data;
- if (watcher->blockable && !queue_empty(watcher->events)) {
+ if (watcher->blockable && !multiqueue_empty(watcher->events)) {
// the timer blocked and there already is an unprocessed event waiting
return;
}
CREATE_EVENT(watcher->events, time_event, 1, watcher);
}
+static void close_event(void **argv)
+{
+ TimeWatcher *watcher = argv[0];
+ watcher->close_cb(watcher, watcher->data);
+}
+
static void close_cb(uv_handle_t *handle)
+ FUNC_ATTR_NONNULL_ALL
{
TimeWatcher *watcher = handle->data;
if (watcher->close_cb) {
- watcher->close_cb(watcher, watcher->data);
+ CREATE_EVENT(watcher->events, close_event, 1, watcher);
}
}
diff --git a/src/nvim/event/time.h b/src/nvim/event/time.h
index 14df176ea3..a6de89ad6e 100644
--- a/src/nvim/event/time.h
+++ b/src/nvim/event/time.h
@@ -12,7 +12,7 @@ struct time_watcher {
uv_timer_t uv;
void *data;
time_cb cb, close_cb;
- Queue *events;
+ MultiQueue *events;
bool blockable;
};
diff --git a/src/nvim/event/wstream.c b/src/nvim/event/wstream.c
index 8028e35e6b..2baa667e7d 100644
--- a/src/nvim/event/wstream.c
+++ b/src/nvim/event/wstream.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 <stdint.h>
#include <stdbool.h>
@@ -5,12 +8,13 @@
#include <uv.h>
+#include "nvim/log.h"
#include "nvim/event/loop.h"
#include "nvim/event/wstream.h"
#include "nvim/vim.h"
#include "nvim/memory.h"
-#define DEFAULT_MAXMEM 1024 * 1024 * 10
+#define DEFAULT_MAXMEM 1024 * 1024 * 2000
typedef struct {
Stream *stream;
@@ -22,19 +26,17 @@ typedef struct {
# include "event/wstream.c.generated.h"
#endif
-void wstream_init_fd(Loop *loop, Stream *stream, int fd, size_t maxmem,
- void *data)
+void wstream_init_fd(Loop *loop, Stream *stream, int fd, size_t maxmem)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2)
{
- stream_init(loop, stream, fd, NULL, data);
+ stream_init(loop, stream, fd, NULL);
wstream_init(stream, maxmem);
}
-void wstream_init_stream(Stream *stream, uv_stream_t *uvstream, size_t maxmem,
- void *data)
+void wstream_init_stream(Stream *stream, uv_stream_t *uvstream, size_t maxmem)
FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2)
{
- stream_init(NULL, stream, -1, uvstream, data);
+ stream_init(NULL, stream, -1, uvstream);
wstream_init(stream, maxmem);
}
@@ -54,10 +56,11 @@ void wstream_init(Stream *stream, size_t maxmem)
///
/// @param stream The `Stream` instance
/// @param cb The callback
-void wstream_set_write_cb(Stream *stream, stream_write_cb cb)
- FUNC_ATTR_NONNULL_ALL
+void wstream_set_write_cb(Stream *stream, stream_write_cb cb, void *data)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
{
stream->write_cb = cb;
+ stream->cb_data = data;
}
/// Queues data for writing to the backing file descriptor of a `Stream`
@@ -87,7 +90,7 @@ bool wstream_write(Stream *stream, WBuffer *buffer)
uv_buf_t uvbuf;
uvbuf.base = buffer->data;
- uvbuf.len = buffer->size;
+ uvbuf.len = UV_BUF_LEN(buffer->size);
if (uv_write(&data->uv_req, stream->uvstream, &uvbuf, 1, write_cb)) {
xfree(data);
@@ -138,7 +141,7 @@ static void write_cb(uv_write_t *req, int status)
wstream_release_wbuffer(data->buffer);
if (data->stream->write_cb) {
- data->stream->write_cb(data->stream, data->stream->data, status);
+ data->stream->write_cb(data->stream, data->stream->cb_data, status);
}
data->stream->pending_reqs--;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index da64533708..85844c37bd 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.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
+
/*
* ex_cmds.c: some functions for command line commands
*/
@@ -8,7 +11,11 @@
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
+#include <math.h>
+#include "nvim/api/private/defs.h"
+#include "nvim/api/buffer.h"
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/ex_cmds.h"
@@ -27,7 +34,9 @@
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
+#include "nvim/highlight.h"
#include "nvim/indent.h"
+#include "nvim/buffer_updates.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
@@ -64,87 +73,151 @@
*/
typedef struct sign sign_T;
+/// Case matching style to use for :substitute
+typedef enum {
+ kSubHonorOptions = 0, ///< Honor the user's 'ignorecase'/'smartcase' options
+ kSubIgnoreCase, ///< Ignore case of the search
+ kSubMatchCase, ///< Match case of the search
+} SubIgnoreType;
+
+/// Flags kept between calls to :substitute.
+typedef struct {
+ bool do_all; ///< do multiple substitutions per line
+ bool do_ask; ///< ask for confirmation
+ bool do_count; ///< count only
+ bool do_error; ///< if false, ignore errors
+ bool do_print; ///< print last line with subs
+ bool do_list; ///< list last line with subs
+ bool do_number; ///< list last line with line nr
+ SubIgnoreType do_ic; ///< ignore case flag
+} subflags_T;
+
+/// Partial result of a substitution during :substitute.
+/// Numbers refer to the buffer _after_ substitution
+typedef struct {
+ lpos_T start; // start of the match
+ lpos_T end; // end of the match
+ linenr_T pre_match; // where to begin showing lines before the match
+} SubResult;
+
+// Collected results of a substitution for showing them in
+// the preview window
+typedef struct {
+ kvec_t(SubResult) subresults;
+ linenr_T lines_needed; // lines neede in the preview window
+} PreviewLines;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds.c.generated.h"
#endif
-/*
- * ":ascii" and "ga".
- */
-void do_ascii(exarg_T *eap)
+/// ":ascii" and "ga" implementation
+void do_ascii(const exarg_T *const eap)
{
- int c;
- int cval;
- char buf1[20];
- char buf2[20];
- char_u buf3[7];
+ char_u *dig;
int cc[MAX_MCO];
- int ci = 0;
- int len;
- const bool l_enc_utf8 = enc_utf8;
-
- if (l_enc_utf8)
- c = utfc_ptr2char(get_cursor_pos_ptr(), cc);
- else
- c = gchar_cursor();
+ int c = utfc_ptr2char(get_cursor_pos_ptr(), cc);
if (c == NUL) {
MSG("NUL");
return;
}
- IObuff[0] = NUL;
- if (!has_mbyte || (enc_dbcs != 0 && c < 0x100) || c < 0x80) {
- if (c == NL) /* NUL is stored as NL */
+ size_t iobuff_len = 0;
+
+ int ci = 0;
+ if (c < 0x80) {
+ if (c == NL) { // NUL is stored as NL.
c = NUL;
- if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
- cval = NL; /* NL is stored as CR */
- else
- cval = c;
- if (vim_isprintc_strict(c) && (c < ' '
- || c > '~'
- )) {
+ }
+ const int cval = (c == CAR && get_fileformat(curbuf) == EOL_MAC
+ ? NL // NL is stored as CR.
+ : c);
+ char buf1[20];
+ if (vim_isprintc_strict(c) && (c < ' ' || c > '~')) {
+ char_u buf3[7];
transchar_nonprint(buf3, c);
vim_snprintf(buf1, sizeof(buf1), " <%s>", (char *)buf3);
- } else
+ } else {
buf1[0] = NUL;
- if (c >= 0x80)
- vim_snprintf(buf2, sizeof(buf2), " <M-%s>",
- (char *)transchar(c & 0x7f));
- else
- buf2[0] = NUL;
- vim_snprintf((char *)IObuff, IOSIZE,
- _("<%s>%s%s %d, Hex %02x, Octal %03o"),
- transchar(c), buf1, buf2, cval, cval, cval);
- if (l_enc_utf8)
- c = cc[ci++];
- else
- c = 0;
- }
-
- /* Repeat for combining characters. */
- while (has_mbyte && (c >= 0x100 || (l_enc_utf8 && c >= 0x80))) {
- len = (int)STRLEN(IObuff);
- /* This assumes every multi-byte char is printable... */
- if (len > 0)
- IObuff[len++] = ' ';
- IObuff[len++] = '<';
- if (l_enc_utf8 && utf_iscomposing(c)
-# ifdef USE_GUI
- && !gui.in_use
-# endif
- )
- IObuff[len++] = ' '; /* draw composing char on top of a space */
- len += (*mb_char2bytes)(c, IObuff + len);
- vim_snprintf((char *)IObuff + len, IOSIZE - len,
- c < 0x10000 ? _("> %d, Hex %04x, Octal %o")
- : _("> %d, Hex %08x, Octal %o"), c, c, c);
- if (ci == MAX_MCO)
+ }
+ char buf2[20];
+ buf2[0] = NUL;
+
+ dig = get_digraph_for_char(cval);
+ if (dig != NULL) {
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len,
+ sizeof(IObuff) - iobuff_len,
+ _("<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"),
+ transchar(c), buf1, buf2, cval, cval, cval, dig));
+ } else {
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len,
+ sizeof(IObuff) - iobuff_len,
+ _("<%s>%s%s %d, Hex %02x, Octal %03o"),
+ transchar(c), buf1, buf2, cval, cval, cval));
+ }
+
+ c = cc[ci++];
+ }
+
+#define SPACE_FOR_DESC (1 + 1 + 1 + MB_MAXBYTES + 16 + 4 + 3 + 3 + 1)
+ // Space for description:
+ // - 1 byte for separator (starting from second entry)
+ // - 1 byte for "<"
+ // - 1 byte for space to draw composing character on (optional, but really
+ // mostly required)
+ // - up to MB_MAXBYTES bytes for character itself
+ // - 16 bytes for raw text ("> , Hex , Octal ").
+ // - at least 4 bytes for hexadecimal representation
+ // - at least 3 bytes for decimal representation
+ // - at least 3 bytes for octal representation
+ // - 1 byte for NUL
+ //
+ // Taking into account MAX_MCO and characters which need 8 bytes for
+ // hexadecimal representation, but not taking translation into account:
+ // resulting string will occupy less then 400 bytes (conservative estimate).
+ //
+ // Less then 1000 bytes if translation multiplies number of bytes needed for
+ // raw text by 6, so it should always fit into 1025 bytes reserved for IObuff.
+
+ // Repeat for combining characters, also handle multiby here.
+ while (c >= 0x80 && iobuff_len < sizeof(IObuff) - SPACE_FOR_DESC) {
+ // This assumes every multi-byte char is printable...
+ if (iobuff_len > 0) {
+ IObuff[iobuff_len++] = ' ';
+ }
+ IObuff[iobuff_len++] = '<';
+ if (utf_iscomposing(c)) {
+ IObuff[iobuff_len++] = ' '; // Draw composing char on top of a space.
+ }
+ iobuff_len += utf_char2bytes(c, IObuff + iobuff_len);
+
+ dig = get_digraph_for_char(c);
+ if (dig != NULL) {
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len,
+ sizeof(IObuff) - iobuff_len,
+ (c < 0x10000
+ ? _("> %d, Hex %04x, Oct %o, Digr %s")
+ : _("> %d, Hex %08x, Oct %o, Digr %s")),
+ c, c, c, dig));
+ } else {
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len,
+ sizeof(IObuff) - iobuff_len,
+ (c < 0x10000
+ ? _("> %d, Hex %04x, Octal %o")
+ : _("> %d, Hex %08x, Octal %o")),
+ c, c, c));
+ }
+ if (ci == MAX_MCO) {
break;
- if (l_enc_utf8)
- c = cc[ci++];
- else
- c = 0;
+ }
+ c = cc[ci++];
+ }
+ if (ci != MAX_MCO && c != 0) {
+ xstrlcpy((char *)IObuff + iobuff_len, " ...", sizeof(IObuff) - iobuff_len);
}
msg(IObuff);
@@ -183,10 +256,12 @@ void ex_align(exarg_T *eap)
*/
if (width <= 0)
width = curbuf->b_p_tw;
- if (width == 0 && curbuf->b_p_wm > 0)
- width = curwin->w_width - curbuf->b_p_wm;
- if (width <= 0)
+ if (width == 0 && curbuf->b_p_wm > 0) {
+ width = curwin->w_grid.Columns - curbuf->b_p_wm;
+ }
+ if (width <= 0) {
width = 80;
+ }
}
if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
@@ -235,7 +310,7 @@ void ex_align(exarg_T *eap)
new_indent = 0;
(void)set_indent(new_indent, 0); /* set indent */
}
- changed_lines(eap->line1, 0, eap->line2 + 1, 0L);
+ changed_lines(eap->line1, 0, eap->line2 + 1, 0L, true);
curwin->w_cursor = save_curpos;
beginline(BL_WHITE | BL_FIX);
}
@@ -261,9 +336,12 @@ static int linelen(int *has_tab)
;
save = *last;
*last = NUL;
- len = linetabsize(line); /* get line length */
- if (has_tab != NULL) /* check for embedded TAB */
- *has_tab = (vim_strrchr(first, TAB) != NULL);
+ // Get line length.
+ len = linetabsize(line);
+ // Check for embedded TAB.
+ if (has_tab != NULL) {
+ *has_tab = STRRCHR(first, TAB) != NULL;
+ }
*last = save;
return len;
@@ -284,14 +362,12 @@ static int sort_abort; ///< flag to indicate if sorting has been interrupted
/// Struct to store info to be sorted.
typedef struct {
linenr_T lnum; ///< line number
- long start_col_nr; ///< starting column number or number
- long end_col_nr; ///< ending column number
union {
struct {
- long start_col_nr; ///< starting column number
- long end_col_nr; ///< ending column number
+ varnumber_T start_col_nr; ///< starting column number
+ varnumber_T end_col_nr; ///< ending column number
} line;
- long value; ///< value if sorting by integer
+ varnumber_T value; ///< value if sorting by integer
float_T value_flt; ///< value if sorting by float
} st_u;
} sorti_T;
@@ -326,12 +402,12 @@ static int sort_compare(const void *s1, const void *s2)
// We need to copy one line into "sortbuf1", because there is no
// guarantee that the first pointer becomes invalid when obtaining the
// second one.
- STRNCPY(sortbuf1, ml_get(l1.lnum) + l1.st_u.line.start_col_nr,
- l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr + 1);
- sortbuf1[l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr] = 0;
- STRNCPY(sortbuf2, ml_get(l2.lnum) + l2.st_u.line.start_col_nr,
- l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1);
- sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = 0;
+ memcpy(sortbuf1, ml_get(l1.lnum) + l1.st_u.line.start_col_nr,
+ l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr + 1);
+ sortbuf1[l1.st_u.line.end_col_nr - l1.st_u.line.start_col_nr] = NUL;
+ memcpy(sortbuf2, ml_get(l2.lnum) + l2.st_u.line.start_col_nr,
+ l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr + 1);
+ sortbuf2[l2.st_u.line.end_col_nr - l2.st_u.line.start_col_nr] = NUL;
result = sort_ic ? STRICMP(sortbuf1, sortbuf2)
: STRCMP(sortbuf1, sortbuf2);
@@ -377,6 +453,7 @@ void ex_sort(exarg_T *eap)
sort_abort = sort_ic = sort_rx = sort_nr = sort_flt = 0;
size_t format_found = 0;
+ bool change_occurred = false; // Buffer contents changed.
for (p = eap->arg; *p != NUL; ++p) {
if (ascii_iswhite(*p)) {
@@ -537,8 +614,16 @@ void ex_sort(exarg_T *eap)
// Insert the lines in the sorted order below the last one.
lnum = eap->line2;
- for (i = 0; i < count; ++i) {
- s = ml_get(nrs[eap->forceit ? count - i - 1 : i].lnum);
+ for (i = 0; i < count; i++) {
+ const linenr_T get_lnum = nrs[eap->forceit ? count - i - 1 : i].lnum;
+
+ // If the original line number of the line being placed is not the same
+ // as "lnum" (accounting for offset), we know that the buffer changed.
+ if (get_lnum + ((linenr_T)count - 1) != lnum) {
+ change_occurred = true;
+ }
+
+ s = ml_get(get_lnum);
if (!unique || i == 0
|| (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0) {
// Copy the line into a buffer, it may become invalid in
@@ -565,11 +650,15 @@ void ex_sort(exarg_T *eap)
// Adjust marks for deleted (or added) lines and prepare for displaying.
deleted = (long)(count - (lnum - eap->line2));
if (deleted > 0) {
- mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted);
+ mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted,
+ false);
+ msgmore(-deleted);
} else if (deleted < 0) {
- mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
+ mark_adjust(eap->line2, MAXLNUM, -deleted, 0L, false);
+ }
+ if (change_occurred || deleted != 0) {
+ changed_lines(eap->line1, 0, eap->line2 + 1, -deleted, true);
}
- changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
curwin->w_cursor.lnum = eap->line1;
beginline(BL_WHITE | BL_FIX);
@@ -671,11 +760,13 @@ void ex_retab(exarg_T *eap)
memmove(new_line + start_col + len,
ptr + col, (size_t)(old_len - col + 1));
ptr = new_line + start_col;
- for (col = 0; col < len; col++)
+ for (col = 0; col < len; col++) {
ptr[col] = (col < num_tabs) ? '\t' : ' ';
- ml_replace(lnum, new_line, FALSE);
- if (first_line == 0)
+ }
+ ml_replace(lnum, new_line, false);
+ if (first_line == 0) {
first_line = lnum;
+ }
last_line = lnum;
ptr = new_line;
col = start_col + len;
@@ -701,8 +792,9 @@ void ex_retab(exarg_T *eap)
if (curbuf->b_p_ts != new_ts)
redraw_curbuf_later(NOT_VALID);
- if (first_line != 0)
- changed_lines(first_line, 0, last_line + 1, 0L);
+ if (first_line != 0) {
+ changed_lines(first_line, 0, last_line + 1, 0L, true);
+ }
curwin->w_p_list = save_list; /* restore 'list' */
@@ -725,19 +817,24 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
linenr_T num_lines; // Num lines moved
linenr_T last_line; // Last line in file after adding new text
- // Moving lines seems to corrupt the folds, delete folding info now
- // and recreate it when finished. Don't do this for manual folding, it
- // would delete all folds.
- bool isFolded = hasAnyFolding(curwin) && !foldmethodIsManual(curwin);
- if (isFolded) {
- deleteFoldRecurse(&curwin->w_folds);
- }
-
if (dest >= line1 && dest < line2) {
- EMSG(_("E134: Move lines into themselves"));
+ EMSG(_("E134: Cannot move a range of lines into itself"));
return FAIL;
}
+ // Do nothing if we are not actually moving any lines. This will prevent
+ // the 'modified' flag from being set without cause.
+ if (dest == line1 - 1 || dest == line2) {
+ // Move the cursor as if lines were moved (see below) to be backwards
+ // compatible.
+ if (dest >= line1) {
+ curwin->w_cursor.lnum = dest;
+ } else {
+ curwin->w_cursor.lnum = dest + (line2 - line1) + 1;
+ }
+ return OK;
+ }
+
num_lines = line2 - line1 + 1;
/*
@@ -770,21 +867,36 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
* their final destination at the new text position -- webb
*/
last_line = curbuf->b_ml.ml_line_count;
- mark_adjust(line1, line2, last_line - line2, 0L);
- changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines);
+ mark_adjust_nofold(line1, line2, last_line - line2, 0L, true);
+ changed_lines(last_line - num_lines + 1, 0, last_line + 1, num_lines, false);
if (dest >= line2) {
- mark_adjust(line2 + 1, dest, -num_lines, 0L);
+ mark_adjust_nofold(line2 + 1, dest, -num_lines, 0L, false);
+ FOR_ALL_TAB_WINDOWS(tab, win) {
+ if (win->w_buffer == curbuf) {
+ foldMoveRange(&win->w_folds, line1, line2, dest);
+ }
+ }
curbuf->b_op_start.lnum = dest - num_lines + 1;
curbuf->b_op_end.lnum = dest;
} else {
- mark_adjust(dest + 1, line1 - 1, num_lines, 0L);
+ mark_adjust_nofold(dest + 1, line1 - 1, num_lines, 0L, false);
+ FOR_ALL_TAB_WINDOWS(tab, win) {
+ if (win->w_buffer == curbuf) {
+ foldMoveRange(&win->w_folds, dest + 1, line1 - 1, line2);
+ }
+ }
curbuf->b_op_start.lnum = dest + 1;
curbuf->b_op_end.lnum = dest + num_lines;
}
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
- mark_adjust(last_line - num_lines + 1, last_line,
- -(last_line - dest - extra), 0L);
- changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra);
+ mark_adjust_nofold(last_line - num_lines + 1, last_line,
+ -(last_line - dest - extra), 0L, true);
+ changed_lines(last_line - num_lines + 1, 0, last_line + 1, -extra, false);
+
+ // send update regarding the new lines that were added
+ if (kv_size(curbuf->update_channels)) {
+ buf_updates_send_changes(curbuf, dest + 1, num_lines, 0, true);
+ }
/*
* Now we delete the original text -- webb
@@ -815,14 +927,14 @@ int do_move(linenr_T line1, linenr_T line2, linenr_T dest)
last_line = curbuf->b_ml.ml_line_count;
if (dest > last_line + 1)
dest = last_line + 1;
- changed_lines(line1, 0, dest, 0L);
+ changed_lines(line1, 0, dest, 0L, false);
} else {
- changed_lines(dest + 1, 0, line1 + num_lines, 0L);
+ changed_lines(dest + 1, 0, line1 + num_lines, 0L, false);
}
- // recreate folds
- if (isFolded) {
- foldUpdateAll(curwin);
+ // send nvim_buf_lines_event regarding lines that were deleted
+ if (kv_size(curbuf->update_channels)) {
+ buf_updates_send_changes(curbuf, line1 + extra, 0, num_lines, true);
}
return OK;
@@ -982,8 +1094,8 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
AppendToRedobuffLit(cmd, -1);
xfree(cmd);
- AppendToRedobuff((char_u *)"\n");
- bangredo = FALSE;
+ AppendToRedobuff("\n");
+ bangredo = false;
}
/*
* Add quotes around the command, for shells that need them.
@@ -1100,11 +1212,12 @@ static void do_filter(
*/
++no_wait_return; /* don't call wait_return() while busy */
if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
- FALSE, FALSE, FALSE, TRUE) == FAIL) {
- msg_putchar('\n'); /* keep message from buf_write() */
- --no_wait_return;
- if (!aborting())
- (void)EMSG2(_(e_notcreate), itmp); /* will call wait_return */
+ false, false, false, true) == FAIL) {
+ msg_putchar('\n'); // Keep message from buf_write().
+ no_wait_return--;
+ if (!aborting()) {
+ EMSG2(_("E482: Can't create file %s"), itmp); // Will call wait_return.
+ }
goto filterend;
}
if (curbuf != old_curbuf)
@@ -1117,16 +1230,6 @@ static void do_filter(
cmd_buf = make_filter_cmd(cmd, itmp, otmp);
ui_cursor_goto((int)Rows - 1, 0);
- /*
- * When not redirecting the output the command can write anything to the
- * screen. If 'shellredir' is equal to ">", screen may be messed up by
- * stderr output of external command. Clear the screen later.
- * If do_in is FALSE, this could be something like ":r !cat", which may
- * also mess up the screen, clear it later.
- */
- if (!do_out || STRCMP(p_srr, ">") == 0 || !do_in)
- redraw_later_clear();
-
if (do_out) {
if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL) {
xfree(cmd_buf);
@@ -1136,23 +1239,8 @@ static void do_filter(
}
read_linecount = curbuf->b_ml.ml_line_count;
- /*
- * When call_shell() fails wait_return() is called to give the user a
- * chance to read the error messages. Otherwise errors are ignored, so you
- * can see the error messages from the command that appear on stdout; use
- * 'u' to fix the text
- * Switch to cooked mode when not redirecting stdin, avoids that something
- * like ":r !cat" hangs.
- * Pass on the kShellDoOut flag when the output is being redirected.
- */
- if (call_shell(
- cmd_buf,
- kShellOptFilter | shell_flags,
- NULL
- )) {
- redraw_later_clear();
- wait_return(FALSE);
- }
+ // Pass on the kShellOptDoOut flag when the output is being redirected.
+ call_shell(cmd_buf, kShellOptFilter | shell_flags, NULL);
xfree(cmd_buf);
did_check_timestamps = FALSE;
@@ -1166,8 +1254,8 @@ static void do_filter(
if (do_out) {
if (otmp != NULL) {
- if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM,
- eap, READ_FILTER) == FAIL) {
+ if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+ READ_FILTER) != OK) {
if (!aborting()) {
msg_putchar('\n');
EMSG2(_(e_notread), otmp);
@@ -1188,15 +1276,14 @@ static void do_filter(
if (do_in) {
if (cmdmod.keepmarks || vim_strchr(p_cpo, CPO_REMMARK) == NULL) {
- if (read_linecount >= linecount)
- /* move all marks from old lines to new lines */
- mark_adjust(line1, line2, linecount, 0L);
- else {
- /* move marks from old lines to new lines, delete marks
- * that are in deleted lines */
- mark_adjust(line1, line1 + read_linecount - 1,
- linecount, 0L);
- mark_adjust(line1 + read_linecount, line2, MAXLNUM, 0L);
+ if (read_linecount >= linecount) {
+ // move all marks from old lines to new lines
+ mark_adjust(line1, line2, linecount, 0L, false);
+ } else {
+ // move marks from old lines to new lines, delete marks
+ // that are in deleted lines
+ mark_adjust(line1, line1 + read_linecount - 1, linecount, 0L, false);
+ mark_adjust(line1 + read_linecount, line2, MAXLNUM, 0L, false);
}
}
@@ -1254,23 +1341,17 @@ filterend:
xfree(otmp);
}
-/*
- * Call a shell to execute a command.
- * When "cmd" is NULL start an interactive shell.
- */
-void
-do_shell (
+// Call a shell to execute a command.
+// When "cmd" is NULL start an interactive shell.
+void
+do_shell(
char_u *cmd,
- int flags /* may be SHELL_DOOUT when output is redirected */
+ int flags // may be SHELL_DOOUT when output is redirected
)
{
- int save_nwr;
-
- /*
- * Disallow shell commands in restricted mode (-Z)
- * Disallow shell commands from .exrc and .vimrc in current directory for
- * security reasons.
- */
+ // Disallow shell commands in restricted mode (-Z)
+ // Disallow shell commands from .exrc and .vimrc in current directory for
+ // security reasons.
if (check_restricted() || check_secure()) {
msg_end();
return;
@@ -1308,38 +1389,31 @@ do_shell (
msg_row = Rows - 1;
msg_col = 0;
- if (autocmd_busy) {
- if (msg_silent == 0)
- redraw_later_clear();
- } else {
- /*
- * For ":sh" there is no need to call wait_return(), just redraw.
- * Also for the Win32 GUI (the output is in a console window).
- * Otherwise there is probably text on the screen that the user wants
- * to read before redrawing, so call wait_return().
- */
- if (cmd == NULL
- ) {
- if (msg_silent == 0)
- redraw_later_clear();
- need_wait_return = FALSE;
- } else {
- /*
- * If we switch screens when starttermcap() is called, we really
- * want to wait for "hit return to continue".
- */
- save_nwr = no_wait_return;
- wait_return(msg_silent == 0);
- no_wait_return = save_nwr;
- }
- }
-
- /* display any error messages now */
+ // display any error messages now
display_errors();
apply_autocmds(EVENT_SHELLCMDPOST, NULL, NULL, FALSE, curbuf);
}
+#if !defined(UNIX)
+static char *find_pipe(const char *cmd)
+{
+ bool inquote = false;
+
+ for (const char *p = cmd; *p != NUL; p++) {
+ if (!inquote && *p == '|') {
+ return p;
+ }
+ if (*p == '"') {
+ inquote = !inquote;
+ } else if (rem_backslash((const char_u *)p)) {
+ p++;
+ }
+ }
+ return NULL;
+}
+#endif
+
/// Create a shell command from a command string, input redirection file and
/// output redirection file.
///
@@ -1377,36 +1451,34 @@ char_u *make_filter_cmd(char_u *cmd, char_u *itmp, char_u *otmp)
: "(%s)";
vim_snprintf(buf, len, fmt, (char *)cmd);
} else {
- strncpy(buf, (char *) cmd, len);
+ xstrlcpy(buf, (char *)cmd, len);
}
if (itmp != NULL) {
- strncat(buf, " < ", len);
- strncat(buf, (char *) itmp, len);
+ xstrlcat(buf, " < ", len - 1);
+ xstrlcat(buf, (const char *)itmp, len - 1);
}
#else
// For shells that don't understand braces around commands, at least allow
// the use of commands in a pipe.
- strncpy(buf, cmd, len);
+ xstrlcpy(buf, (char *)cmd, len);
if (itmp != NULL) {
- char_u *p;
-
// If there is a pipe, we have to put the '<' in front of it.
// Don't do this when 'shellquote' is not empty, otherwise the
// redirection would be inside the quotes.
if (*p_shq == NUL) {
- p = strchr(buf, '|');
+ char *const p = find_pipe(buf);
if (p != NULL) {
*p = NUL;
}
}
- strncat(buf, " < ", len);
- strncat(buf, (char *) itmp, len);
+ xstrlcat(buf, " < ", len);
+ xstrlcat(buf, (const char *)itmp, len);
if (*p_shq == NUL) {
- p = strchr(cmd, '|');
+ const char *const p = find_pipe((const char *)cmd);
if (p != NULL) {
- strncat(buf, " ", len); // Insert a space before the '|' for DOS
- strncat(buf, p, len);
+ xstrlcat(buf, " ", len - 1); // Insert a space before the '|' for DOS
+ xstrlcat(buf, p, len - 1);
}
}
}
@@ -1449,12 +1521,12 @@ void append_redir(char *const buf, const size_t buflen,
void print_line_no_prefix(linenr_T lnum, int use_number, int list)
{
- char_u numbuf[30];
+ char numbuf[30];
if (curwin->w_p_nu || use_number) {
- vim_snprintf((char *)numbuf, sizeof(numbuf),
- "%*ld ", number_width(curwin), (long)lnum);
- msg_puts_attr(numbuf, hl_attr(HLF_N)); /* Highlight line nrs */
+ vim_snprintf(numbuf, sizeof(numbuf), "%*" PRIdLINENR " ",
+ number_width(curwin), lnum);
+ msg_puts_attr(numbuf, HL_ATTR(HLF_N)); // Highlight line nrs.
}
msg_prt_line(ml_get(lnum), list);
}
@@ -1466,6 +1538,11 @@ void print_line(linenr_T lnum, int use_number, int list)
{
int save_silent = silent_mode;
+ // apply :filter /pat/
+ if (message_filtered(ml_get(lnum))) {
+ return;
+ }
+
msg_start();
silent_mode = FALSE;
info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
@@ -1510,8 +1587,9 @@ int rename_buffer(char_u *new_fname)
curbuf->b_flags |= BF_NOTEDITED;
if (xfname != NULL && *xfname != NUL) {
buf = buflist_new(fname, xfname, curwin->w_cursor.lnum, 0);
- if (buf != NULL && !cmdmod.keepalt)
+ if (buf != NULL && !cmdmod.keepalt) {
curwin->w_alt_fnum = buf->b_fnum;
+ }
}
xfree(fname);
xfree(sfname);
@@ -1537,12 +1615,14 @@ void ex_file(exarg_T *eap)
}
if (*eap->arg != NUL || eap->addr_count == 1) {
- if (rename_buffer(eap->arg) == FAIL)
+ if (rename_buffer(eap->arg) == FAIL) {
return;
+ }
+ redraw_tabline = true;
}
- if (!shortmess(SHM_FILEINFO)) {
- // print full file name if :cd used
+ // print file name if no argument or 'F' is not in 'shortmess'
+ if (*eap->arg == NUL || !shortmess(SHM_FILEINFO)) {
fileinfo(false, false, eap->forceit);
}
}
@@ -1583,6 +1663,7 @@ int do_write(exarg_T *eap)
int retval = FAIL;
char_u *free_fname = NULL;
buf_T *alt_buf = NULL;
+ int name_was_missing;
if (not_writing()) /* check 'write' option */
return FAIL;
@@ -1693,11 +1774,11 @@ int do_write(exarg_T *eap)
goto theend;
}
- /* If 'filetype' was empty try detecting it now. */
+ // If 'filetype' was empty try detecting it now.
if (*curbuf->b_p_ft == NUL) {
- if (au_has_group((char_u *)"filetypedetect"))
- (void)do_doautocmd((char_u *)"filetypedetect BufRead",
- TRUE);
+ if (au_has_group((char_u *)"filetypedetect")) {
+ (void)do_doautocmd((char_u *)"filetypedetect BufRead", true, NULL);
+ }
do_modelines(0);
}
@@ -1706,6 +1787,7 @@ int do_write(exarg_T *eap)
fname = curbuf->b_sfname;
}
+ name_was_missing = curbuf->b_ffname == NULL;
retval = buf_write(curbuf, ffname, fname, eap->line1, eap->line2,
eap, eap->append, eap->forceit, TRUE, FALSE);
@@ -1715,7 +1797,11 @@ int do_write(exarg_T *eap)
curbuf->b_p_ro = FALSE;
redraw_tabline = TRUE;
}
- /* Change directories when the 'acd' option is set. */
+ }
+
+ // Change directories when the 'acd' option is set and the file name
+ // got changed or set.
+ if (eap->cmdidx == CMD_saveas || name_was_missing) {
do_autochdir();
}
}
@@ -1731,14 +1817,14 @@ theend:
* May set eap->forceit if a dialog says it's OK to overwrite.
* Return OK if it's OK, FAIL if it is not.
*/
-int
-check_overwrite (
+int
+check_overwrite(
exarg_T *eap,
buf_T *buf,
- char_u *fname, /* file name to be used (can differ from
- buf->ffname) */
- char_u *ffname, /* full path version of fname */
- int other /* writing under other name */
+ char_u *fname, // file name to be used (can differ from
+ // buf->ffname)
+ char_u *ffname, // full path version of fname
+ int other // writing under other name
)
{
/*
@@ -1872,11 +1958,15 @@ void do_wqall(exarg_T *eap)
FALSE) == FAIL) {
++error;
} else {
- if (buf_write_all(buf, eap->forceit) == FAIL)
- ++error;
- /* an autocommand may have deleted the buffer */
- if (!buf_valid(buf))
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ if (buf_write_all(buf, eap->forceit) == FAIL) {
+ error++;
+ }
+ // An autocommand may have deleted the buffer.
+ if (!bufref_valid(&bufref)) {
buf = firstbuf;
+ }
}
eap->forceit = save_forceit; /* check_overwrite() may set it */
}
@@ -1944,11 +2034,14 @@ static int check_readonly(int *forceit, buf_T *buf)
/*
* Try to abandon current file and edit a new or existing file.
- * 'fnum' is the number of the file, if zero use ffname/sfname.
+ * "fnum" is the number of the file, if zero use ffname/sfname.
+ * "lnum" is the line number for the cursor in the new file (if non-zero).
*
- * Return 1 for "normal" error, 2 for "not written" error, 0 for success
- * -1 for successfully opening another file.
- * 'lnum' is the line number for the cursor in the new file (if non-zero).
+ * Return:
+ * GETFILE_ERROR for "normal" error,
+ * GETFILE_NOT_WRITTEN for "not written" error,
+ * GETFILE_SAME_FILE for success
+ * GETFILE_OPEN_OTHER for successfully opening another file.
*/
int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum, int forceit)
{
@@ -1956,10 +2049,12 @@ int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum,
int retval;
char_u *free_me = NULL;
- if (text_locked())
- return 1;
- if (curbuf_locked())
- return 1;
+ if (text_locked()) {
+ return GETFILE_ERROR;
+ }
+ if (curbuf_locked()) {
+ return GETFILE_ERROR;
+ }
if (fnum == 0) {
/* make ffname full path, set sfname */
@@ -1969,17 +2064,18 @@ int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum,
} else
other = (fnum != curbuf->b_fnum);
- if (other)
- ++no_wait_return; /* don't wait for autowrite message */
- if (other && !forceit && curbuf->b_nwindows == 1 && !P_HID(curbuf)
+ if (other) {
+ no_wait_return++; // don't wait for autowrite message
+ }
+ if (other && !forceit && curbuf->b_nwindows == 1 && !buf_hide(curbuf)
&& curbufIsChanged() && autowrite(curbuf, forceit) == FAIL) {
- if (p_confirm && p_write)
- dialog_changed(curbuf, FALSE);
+ if (p_confirm && p_write) {
+ dialog_changed(curbuf, false);
+ }
if (curbufIsChanged()) {
- if (other)
- --no_wait_return;
+ no_wait_return--;
EMSG(_(e_nowrtmsg));
- retval = 2; /* file has been changed */
+ retval = GETFILE_NOT_WRITTEN; // File has been changed.
goto theend;
}
}
@@ -1988,54 +2084,53 @@ int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum,
if (setpm)
setpcmark();
if (!other) {
- if (lnum != 0)
+ if (lnum != 0) {
curwin->w_cursor.lnum = lnum;
+ }
check_cursor_lnum();
beginline(BL_SOL | BL_FIX);
- retval = 0; /* it's in the same file */
+ retval = GETFILE_SAME_FILE; // it's in the same file
} else if (do_ecmd(fnum, ffname, sfname, NULL, lnum,
- (P_HID(curbuf) ? ECMD_HIDE : 0) + (forceit ? ECMD_FORCEIT : 0),
- curwin) == OK)
- retval = -1; /* opened another file */
- else
- retval = 1; /* error encountered */
+ (buf_hide(curbuf) ? ECMD_HIDE : 0)
+ + (forceit ? ECMD_FORCEIT : 0), curwin) == OK) {
+ retval = GETFILE_OPEN_OTHER; // opened another file
+ } else {
+ retval = GETFILE_ERROR; // error encountered
+ }
theend:
xfree(free_me);
return retval;
}
-/*
- * start editing a new file
- *
- * fnum: file number; if zero use ffname/sfname
- * ffname: the file name
- * - full path if sfname used,
- * - any file name if sfname is NULL
- * - empty string to re-edit with the same file name (but may be
- * in a different directory)
- * - NULL to start an empty buffer
- * sfname: the short file name (or NULL)
- * eap: contains the command to be executed after loading the file and
- * forced 'ff' and 'fenc'
- * newlnum: if > 0: put cursor on this line number (if possible)
- * if ECMD_LASTL: use last position in loaded file
- * if ECMD_LAST: use last position in all files
- * if ECMD_ONE: use first line
- * flags:
- * ECMD_HIDE: if TRUE don't free the current buffer
- * ECMD_SET_HELP: set b_help flag of (new) buffer before opening file
- * ECMD_OLDBUF: use existing buffer if it exists
- * ECMD_FORCEIT: ! used for Ex command
- * ECMD_ADDBUF: don't edit, just add to buffer list
- * oldwin: Should be "curwin" when editing a new buffer in the current
- * window, NULL when splitting the window first. When not NULL info
- * of the previous buffer for "oldwin" is stored.
- *
- * return FAIL for failure, OK otherwise
- */
-int
-do_ecmd (
+/// start editing a new file
+///
+/// @param fnum file number; if zero use ffname/sfname
+/// @param ffname the file name
+/// - full path if sfname used,
+/// - any file name if sfname is NULL
+/// - empty string to re-edit with the same file name (but may
+/// be in a different directory)
+/// - NULL to start an empty buffer
+/// @param sfname the short file name (or NULL)
+/// @param eap contains the command to be executed after loading the file
+/// and forced 'ff' and 'fenc'
+/// @param newlnum if > 0: put cursor on this line number (if possible)
+/// ECMD_LASTL: use last position in loaded file
+/// ECMD_LAST: use last position in all files
+/// ECMD_ONE: use first line
+/// @param flags ECMD_HIDE: if TRUE don't free the current buffer
+/// ECMD_SET_HELP: set b_help flag of (new) buffer before
+/// opening file
+/// ECMD_OLDBUF: use existing buffer if it exists
+/// ECMD_FORCEIT: ! used for Ex command
+/// ECMD_ADDBUF: don't edit, just add to buffer list
+/// @param oldwin Should be "curwin" when editing a new buffer in the current
+/// window, NULL when splitting the window first. When not NULL
+/// info of the previous buffer for "oldwin" is stored.
+///
+/// @return FAIL for failure, OK otherwise
+int do_ecmd(
int fnum,
char_u *ffname,
char_u *sfname,
@@ -2052,7 +2147,8 @@ do_ecmd (
char_u *new_name = NULL;
int did_set_swapcommand = FALSE;
buf_T *buf;
- buf_T *old_curbuf = curbuf;
+ bufref_T bufref;
+ bufref_T old_curbuf;
char_u *free_fname = NULL;
int retval = FAIL;
long n;
@@ -2064,10 +2160,13 @@ do_ecmd (
char_u *command = NULL;
int did_get_winopts = FALSE;
int readfile_flags = 0;
+ bool did_inc_redrawing_disabled = false;
if (eap != NULL)
command = eap->do_ecmd_cmd;
+ set_bufref(&old_curbuf, curbuf);
+
if (fnum != 0) {
if (fnum == curbuf->b_fnum) /* file is already being edited */
return OK; /* nothing to do */
@@ -2101,6 +2200,14 @@ do_ecmd (
}
}
+ // Re-editing a terminal buffer: skip most buffer re-initialization.
+ if (!other_file && curbuf->terminal) {
+ check_arg_idx(curwin); // Needed when called from do_argfile().
+ maketitle(); // Title may show the arg index, e.g. "(2 of 5)".
+ retval = OK;
+ goto theend;
+ }
+
/*
* if the file was changed we may not be allowed to abandon it
* - if we are going to re-edit the same file
@@ -2151,9 +2258,9 @@ do_ecmd (
buflist_altfpos(oldwin);
}
- if (fnum)
+ if (fnum) {
buf = buflist_findnr(fnum);
- else {
+ } else {
if (flags & ECMD_ADDBUF) {
linenr_T tlnum = 1L;
@@ -2166,28 +2273,32 @@ do_ecmd (
goto theend;
}
buf = buflist_new(ffname, sfname, 0L,
- BLN_CURBUF | ((flags & ECMD_SET_HELP) ? 0 : BLN_LISTED));
+ BLN_CURBUF | (flags & ECMD_SET_HELP ? 0 : BLN_LISTED));
// Autocmds may change curwin and curbuf.
if (oldwin != NULL) {
oldwin = curwin;
}
- old_curbuf = curbuf;
+ set_bufref(&old_curbuf, curbuf);
}
if (buf == NULL)
goto theend;
- if (buf->b_ml.ml_mfp == NULL) { /* no memfile yet */
- oldbuf = FALSE;
- } else { /* existing memfile */
- oldbuf = TRUE;
- (void)buf_check_timestamp(buf, FALSE);
- /* Check if autocommands made buffer invalid or changed the current
- * buffer. */
- if (!buf_valid(buf)
- || curbuf != old_curbuf
- )
+ if (buf->b_ml.ml_mfp == NULL) {
+ // No memfile yet.
+ oldbuf = false;
+ } else {
+ // Existing memfile.
+ oldbuf = true;
+ set_bufref(&bufref, buf);
+ (void)buf_check_timestamp(buf, false);
+ // Check if autocommands made buffer invalid or changed the current
+ // buffer.
+ if (!bufref_valid(&bufref) || curbuf != old_curbuf.br_buf) {
goto theend;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) {
+ // Autocmds may abort script processing.
goto theend;
+ }
}
/* May jump to last used line number for a loaded buffer or when asked
@@ -2215,46 +2326,53 @@ do_ecmd (
* - If we ended up in the new buffer already, need to skip a few
* things, set auto_buf.
*/
- if (buf->b_fname != NULL)
+ if (buf->b_fname != NULL) {
new_name = vim_strsave(buf->b_fname);
- au_new_curbuf = buf;
- apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
- if (!buf_valid(buf)) { /* new buffer has been deleted */
- delbuf_msg(new_name); /* frees new_name */
+ }
+ set_bufref(&au_new_curbuf, buf);
+ apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, false, curbuf);
+ if (!bufref_valid(&au_new_curbuf)) {
+ // New buffer has been deleted.
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
if (aborting()) { /* autocmds may abort script processing */
xfree(new_name);
goto theend;
}
- if (buf == curbuf) /* already in new buffer */
- auto_buf = TRUE;
- else {
- if (curbuf == old_curbuf)
+ if (buf == curbuf) { // already in new buffer
+ auto_buf = true;
+ } else {
+ win_T *the_curwin = curwin;
+
+ // Set w_closing to avoid that autocommands close the window.
+ // Set b_locked for the same reason.
+ the_curwin->w_closing = true;
+ buf->b_locked++;
+
+ if (curbuf == old_curbuf.br_buf) {
buf_copy_options(buf, BCO_ENTER);
+ }
- /* close the link to the current buffer */
- u_sync(FALSE);
+ // Close the link to the current buffer. This will set
+ // oldwin->w_buffer to NULL.
+ u_sync(false);
close_buffer(oldwin, curbuf,
- (flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD, FALSE);
-
- /* Autocommands may open a new window and leave oldwin open
- * which leads to crashes since the above call sets
- * oldwin->w_buffer to NULL. */
- if (curwin != oldwin && oldwin != aucmd_win && win_valid(oldwin)) {
- assert(oldwin);
- if (oldwin->w_buffer == NULL) {
- win_close(oldwin, FALSE);
- }
- }
+ (flags & ECMD_HIDE) || curbuf->terminal ? 0 : DOBUF_UNLOAD,
+ false);
+
+ the_curwin->w_closing = false;
+ buf->b_locked--;
- if (aborting()) { /* autocmds may abort script processing */
+ // autocmds may abort script processing
+ if (aborting() && curwin->w_buffer != NULL) {
xfree(new_name);
goto theend;
}
- /* Be careful again, like above. */
- if (!buf_valid(buf)) { /* new buffer has been deleted */
- delbuf_msg(new_name); /* frees new_name */
+ // Be careful again, like above.
+ if (!bufref_valid(&au_new_curbuf)) {
+ // New buffer has been deleted.
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
if (buf == curbuf) { // already in new buffer
@@ -2262,8 +2380,8 @@ do_ecmd (
} else {
// <VN> We could instead free the synblock
// and re-attach to buffer, perhaps.
- if (curwin->w_buffer != NULL
- && curwin->w_s == &(curwin->w_buffer->b_s)) {
+ if (curwin->w_buffer == NULL
+ || curwin->w_s == &(curwin->w_buffer->b_s)) {
curwin->w_s = &(buf->b_s);
}
@@ -2287,7 +2405,8 @@ do_ecmd (
}
xfree(new_name);
- au_new_curbuf = NULL;
+ au_new_curbuf.br_buf = NULL;
+ au_new_curbuf.br_buf_free_count = 0;
}
curwin->w_pcmark.lnum = 1;
@@ -2300,6 +2419,11 @@ do_ecmd (
oldbuf = (flags & ECMD_OLDBUF);
}
+ // Don't redraw until the cursor is in the right line, otherwise
+ // autocommands may cause ml_get errors.
+ RedrawingDisabled++;
+ did_inc_redrawing_disabled = true;
+
buf = curbuf;
if ((flags & ECMD_SET_HELP) || keep_help_flag) {
prepare_help_buffer();
@@ -2335,28 +2459,34 @@ do_ecmd (
solcol = curwin->w_cursor.col;
}
buf = curbuf;
- if (buf->b_fname != NULL)
+ if (buf->b_fname != NULL) {
new_name = vim_strsave(buf->b_fname);
- else
+ } else {
new_name = NULL;
+ }
+ set_bufref(&bufref, buf);
if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) {
/* Save all the text, so that the reload can be undone.
* Sync first so that this is a separate undo-able action. */
- u_sync(FALSE);
- if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, TRUE)
- == FAIL)
+ u_sync(false);
+ if (u_savecommon(0, curbuf->b_ml.ml_line_count + 1, 0, true)
+ == FAIL) {
+ xfree(new_name);
goto theend;
+ }
u_unchanged(curbuf);
+ buf_updates_unregister_all(curbuf);
buf_freeall(curbuf, BFA_KEEP_UNDO);
- /* tell readfile() not to clear or reload undo info */
+ // Tell readfile() not to clear or reload undo info.
readfile_flags = READ_KEEP_UNDO;
- } else
- buf_freeall(curbuf, 0); /* free all things for buffer */
- /* If autocommands deleted the buffer we were going to re-edit, give
- * up and jump to the end. */
- if (!buf_valid(buf)) {
- delbuf_msg(new_name); /* frees new_name */
+ } else {
+ buf_freeall(curbuf, 0); // Free all things for buffer.
+ }
+ // If autocommands deleted the buffer we were going to re-edit, give
+ // up and jump to the end.
+ if (!bufref_valid(&bufref)) {
+ delbuf_msg(new_name); // Frees new_name.
goto theend;
}
xfree(new_name);
@@ -2376,18 +2506,11 @@ do_ecmd (
/*
* If we get here we are sure to start editing
*/
- /* don't redraw until the cursor is in the right line */
- ++RedrawingDisabled;
/* Assume success now */
retval = OK;
/*
- * Reset cursor position, could be used by autocommands.
- */
- check_cursor();
-
- /*
* Check if we are editing the w_arg_idx file in the argument list.
*/
check_arg_idx(curwin);
@@ -2429,7 +2552,7 @@ do_ecmd (
if (swap_exists_action == SEA_QUIT)
retval = FAIL;
- handle_swap_exists(old_curbuf);
+ handle_swap_exists(&old_curbuf);
} else {
/* Read the modelines, but only to set window-local options. Any
* buffer-local options have already been set and may have been
@@ -2443,11 +2566,17 @@ do_ecmd (
}
check_arg_idx(curwin);
- // If autocommands change the cursor position or topline, we should keep
- // it. Also when it moves within a line.
+ // If autocommands change the cursor position or topline, we should
+ // keep it. Also when it moves within a line. But not when it moves
+ // to the first non-blank.
if (!equalpos(curwin->w_cursor, orig_pos)) {
- newlnum = curwin->w_cursor.lnum;
- newcol = curwin->w_cursor.col;
+ const char_u *text = get_cursor_line_ptr();
+
+ if (curwin->w_cursor.lnum != orig_pos.lnum
+ || curwin->w_cursor.col != (int)(skipwhite(text) - text)) {
+ newlnum = curwin->w_cursor.lnum;
+ newcol = curwin->w_cursor.col;
+ }
}
if (curwin->w_topline == topline)
topline = 0;
@@ -2529,7 +2658,8 @@ do_ecmd (
if (curbuf->b_kmap_state & KEYMAP_INIT)
(void)keymap_init();
- --RedrawingDisabled;
+ RedrawingDisabled--;
+ did_inc_redrawing_disabled = false;
if (!skip_redraw) {
n = p_so;
if (topline == 0 && command == NULL)
@@ -2548,8 +2678,12 @@ do_ecmd (
theend:
- if (did_set_swapcommand)
+ if (did_inc_redrawing_disabled) {
+ RedrawingDisabled--;
+ }
+ if (did_set_swapcommand) {
set_vim_var_string(VV_SWAPCOMMAND, NULL, -1);
+ }
xfree(free_fname);
return retval;
}
@@ -2559,7 +2693,8 @@ static void delbuf_msg(char_u *name)
EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"),
name == NULL ? (char_u *)"" : name);
xfree(name);
- au_new_curbuf = NULL;
+ au_new_curbuf.br_buf = NULL;
+ au_new_curbuf.br_buf_free_count = 0;
}
static int append_indent = 0; /* autoindent for first line */
@@ -2588,7 +2723,7 @@ void ex_append(exarg_T *eap)
if (eap->cmdidx != CMD_append)
--lnum;
- /* when the buffer is empty append to line 0 and delete the dummy line */
+ // when the buffer is empty need to delete the dummy line
if (empty && lnum == 1)
lnum = 0;
@@ -2660,7 +2795,7 @@ void ex_append(exarg_T *eap)
did_undo = TRUE;
ml_append(lnum, theline, (colnr_T)0, FALSE);
- appended_lines_mark(lnum, 1L);
+ appended_lines_mark(lnum + (empty ? 1 : 0), 1L);
xfree(theline);
++lnum;
@@ -2727,23 +2862,25 @@ void ex_change(exarg_T *eap)
void ex_z(exarg_T *eap)
{
char_u *x;
- int bigness;
+ int64_t bigness;
char_u *kind;
int minus = 0;
linenr_T start, end, curs, i;
int j;
linenr_T lnum = eap->line2;
- /* Vi compatible: ":z!" uses display height, without a count uses
- * 'scroll' */
- if (eap->forceit)
- bigness = curwin->w_height;
- else if (firstwin == lastwin)
+ // Vi compatible: ":z!" uses display height, without a count uses
+ // 'scroll'
+ if (eap->forceit) {
+ bigness = curwin->w_grid.Rows;
+ } else if (ONE_WINDOW) {
bigness = curwin->w_p_scr * 2;
- else
- bigness = curwin->w_height - 3;
- if (bigness < 1)
+ } else {
+ bigness = curwin->w_grid.Rows - 3;
+ }
+ if (bigness < 1) {
bigness = 1;
+ }
x = eap->arg;
kind = x;
@@ -2758,10 +2895,17 @@ void ex_z(exarg_T *eap)
EMSG(_("E144: non-numeric argument to :z"));
return;
}
- bigness = atoi((char *)x);
+ bigness = atol((char *)x);
+
+ // bigness could be < 0 if atol(x) overflows.
+ if (bigness > 2 * curbuf->b_ml.ml_line_count || bigness < 0) {
+ bigness = 2 * curbuf->b_ml.ml_line_count;
+ }
+
p_window = bigness;
- if (*kind == '=')
+ if (*kind == '=') {
bigness += 2;
+ }
}
/* the number of '-' and '+' multiplies the distance */
@@ -2812,8 +2956,11 @@ void ex_z(exarg_T *eap)
if (end > curbuf->b_ml.ml_line_count)
end = curbuf->b_ml.ml_line_count;
- if (curs > curbuf->b_ml.ml_line_count)
+ if (curs > curbuf->b_ml.ml_line_count) {
curs = curbuf->b_ml.ml_line_count;
+ } else if (curs < 1) {
+ curs = 1;
+ }
for (i = start; i <= end; i++) {
if (minus && i == lnum) {
@@ -2833,8 +2980,11 @@ void ex_z(exarg_T *eap)
}
}
- curwin->w_cursor.lnum = curs;
- ex_no_reprint = TRUE;
+ if (curwin->w_cursor.lnum != curs) {
+ curwin->w_cursor.lnum = curs;
+ curwin->w_cursor.col = 0;
+ }
+ ex_no_reprint = true;
}
/*
@@ -2896,57 +3046,214 @@ void sub_set_replacement(SubReplacementString sub)
{
xfree(old_sub.sub);
if (sub.additional_elements != old_sub.additional_elements) {
- list_unref(old_sub.additional_elements);
+ tv_list_unref(old_sub.additional_elements);
}
old_sub = sub;
}
-/* do_sub()
- *
- * Perform a substitution from line eap->line1 to line eap->line2 using the
- * command pointed to by eap->arg which should be of the form:
- *
- * /pattern/substitution/{flags}
- *
- * The usual escapes are supported as described in the regexp docs.
- */
-void do_sub(exarg_T *eap)
+/// Recognize ":%s/\n//" and turn it into a join command, which is much
+/// more efficient.
+///
+/// @param[in] eap Ex arguments
+/// @param[in] pat Search pattern
+/// @param[in] sub Replacement string
+/// @param[in] cmd Command from :s_flags
+/// @param[in] save Save pattern to options, history
+///
+/// @returns true if :substitute can be replaced with a join command
+static bool sub_joining_lines(exarg_T *eap, char_u *pat, char_u *sub,
+ char_u *cmd, bool save)
+ FUNC_ATTR_NONNULL_ARG(1, 3, 4)
+{
+ // TODO(vim): find a generic solution to make line-joining operations more
+ // efficient, avoid allocating a string that grows in size.
+ if (pat != NULL
+ && strcmp((const char *)pat, "\\n") == 0
+ && *sub == NUL
+ && (*cmd == NUL || (cmd[1] == NUL
+ && (*cmd == 'g'
+ || *cmd == 'l'
+ || *cmd == 'p'
+ || *cmd == '#')))) {
+ curwin->w_cursor.lnum = eap->line1;
+ if (*cmd == 'l') {
+ eap->flags = EXFLAG_LIST;
+ } else if (*cmd == '#') {
+ eap->flags = EXFLAG_NR;
+ } else if (*cmd == 'p') {
+ eap->flags = EXFLAG_PRINT;
+ }
+
+ // The number of lines joined is the number of lines in the range
+ linenr_T joined_lines_count = eap->line2 - eap->line1 + 1
+ // plus one extra line if not at the end of file.
+ + (eap->line2 < curbuf->b_ml.ml_line_count ? 1 : 0);
+ if (joined_lines_count > 1) {
+ do_join(joined_lines_count, FALSE, TRUE, FALSE, true);
+ sub_nsubs = joined_lines_count - 1;
+ sub_nlines = 1;
+ do_sub_msg(false);
+ ex_may_print(eap);
+ }
+
+ if (save) {
+ if (!cmdmod.keeppatterns) {
+ save_re_pat(RE_SUBST, pat, p_magic);
+ }
+ add_to_history(HIST_SEARCH, pat, true, NUL);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+/// Allocate memory to store the replacement text for :substitute.
+///
+/// Slightly more memory that is strictly necessary is allocated to reduce the
+/// frequency of memory (re)allocation.
+///
+/// @param[in,out] new_start pointer to the memory for the replacement text
+/// @param[in] needed_len amount of memory needed
+///
+/// @returns pointer to the end of the allocated memory
+static char_u *sub_grow_buf(char_u **new_start, int needed_len)
+ FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_RET
+{
+ int new_start_len = 0;
+ char_u *new_end;
+ if (*new_start == NULL) {
+ // Get some space for a temporary buffer to do the
+ // substitution into (and some extra space to avoid
+ // too many calls to xmalloc()/free()).
+ new_start_len = needed_len + 50;
+ *new_start = xmalloc(new_start_len);
+ **new_start = NUL;
+ new_end = *new_start;
+ } else {
+ // Check if the temporary buffer is long enough to do the
+ // substitution into. If not, make it larger (with a bit
+ // extra to avoid too many calls to xmalloc()/free()).
+ size_t len = STRLEN(*new_start);
+ needed_len += len;
+ if (needed_len > new_start_len) {
+ new_start_len = needed_len + 50;
+ *new_start = xrealloc(*new_start, new_start_len);
+ }
+ new_end = *new_start + len;
+ }
+
+ return new_end;
+}
+
+/// Parse cmd string for :substitute's {flags} and update subflags accordingly
+///
+/// @param[in] cmd command string
+/// @param[in,out] subflags current flags defined for the :substitute command
+/// @param[in,out] which_pat pattern type from which to get default search
+///
+/// @returns pointer to the end of the flags, which may be the end of the string
+static char_u *sub_parse_flags(char_u *cmd, subflags_T *subflags,
+ int *which_pat)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
+{
+ // Find trailing options. When '&' is used, keep old options.
+ if (*cmd == '&') {
+ cmd++;
+ } else {
+ subflags->do_all = p_gd;
+ subflags->do_ask = false;
+ subflags->do_error = true;
+ subflags->do_print = false;
+ subflags->do_count = false;
+ subflags->do_number = false;
+ subflags->do_ic = kSubHonorOptions;
+ }
+ while (*cmd) {
+ // Note that 'g' and 'c' are always inverted.
+ // 'r' is never inverted.
+ if (*cmd == 'g') {
+ subflags->do_all = !subflags->do_all;
+ } else if (*cmd == 'c') {
+ subflags->do_ask = !subflags->do_ask;
+ } else if (*cmd == 'n') {
+ subflags->do_count = true;
+ } else if (*cmd == 'e') {
+ subflags->do_error = !subflags->do_error;
+ } else if (*cmd == 'r') { // use last used regexp
+ *which_pat = RE_LAST;
+ } else if (*cmd == 'p') {
+ subflags->do_print = true;
+ } else if (*cmd == '#') {
+ subflags->do_print = true;
+ subflags->do_number = true;
+ } else if (*cmd == 'l') {
+ subflags->do_print = true;
+ subflags->do_list = true;
+ } else if (*cmd == 'i') { // ignore case
+ subflags->do_ic = kSubIgnoreCase;
+ } else if (*cmd == 'I') { // don't ignore case
+ subflags->do_ic = kSubMatchCase;
+ } else {
+ break;
+ }
+ cmd++;
+ }
+ if (subflags->do_count) {
+ subflags->do_ask = false;
+ }
+
+ return cmd;
+}
+
+/// Perform a substitution from line eap->line1 to line eap->line2 using the
+/// command pointed to by eap->arg which should be of the form:
+///
+/// /pattern/substitution/{flags}
+///
+/// The usual escapes are supported as described in the regexp docs.
+///
+/// @param do_buf_event If `true`, send buffer updates.
+/// @return buffer used for 'inccommand' preview
+static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
+ bool do_buf_event)
{
- linenr_T lnum;
long i = 0;
regmmatch_T regmatch;
- static int do_all = FALSE; /* do multiple substitutions per line */
- static int do_ask = FALSE; /* ask for confirmation */
- static bool do_count = false; /* count only */
- static int do_error = TRUE; /* if false, ignore errors */
- static int do_print = FALSE; /* print last line with subs. */
- static int do_list = FALSE; /* list last line with subs. */
- static int do_number = FALSE; /* list last line with line nr*/
- static int do_ic = 0; /* ignore case flag */
- int save_do_all; // remember user specified 'g' flag
- int save_do_ask; // remember user specified 'c' flag
- char_u *pat = NULL, *sub = NULL; /* init for GCC */
+ static subflags_T subflags = {
+ .do_all = false,
+ .do_ask = false,
+ .do_count = false,
+ .do_error = true,
+ .do_print = false,
+ .do_list = false,
+ .do_number = false,
+ .do_ic = kSubHonorOptions
+ };
+ char_u *pat = NULL, *sub = NULL; // init for GCC
int delimiter;
+ bool has_second_delim = false;
int sublen;
- int got_quit = FALSE;
- int got_match = FALSE;
- int temp;
+ int got_quit = false;
+ int got_match = false;
int which_pat;
- char_u *cmd;
- int save_State;
- linenr_T first_line = 0; /* first changed line */
- linenr_T last_line= 0; /* below last changed line AFTER the
- * change */
+ char_u *cmd = eap->arg;
+ linenr_T first_line = 0; // first changed line
+ linenr_T last_line= 0; // below last changed line AFTER the change
linenr_T old_line_count = curbuf->b_ml.ml_line_count;
- linenr_T line2;
- long nmatch; /* number of lines in match */
- char_u *sub_firstline; /* allocated copy of first sub line */
- int endcolumn = FALSE; /* cursor in last column when done */
+ char_u *sub_firstline; // allocated copy of first sub line
+ bool endcolumn = false; // cursor in last column when done
+ PreviewLines preview_lines = { KV_INITIAL_VALUE, 0 };
+ static int pre_src_id = 0; // Source id for the preview highlight
+ static int pre_hl_id = 0;
+ buf_T *orig_buf = curbuf; // save to reset highlighting
pos_T old_cursor = curwin->w_cursor;
int start_nsubs;
int save_ma = 0;
+ int save_b_changed = curbuf->b_changed;
+ bool preview = (State & CMDPREVIEW);
- cmd = eap->arg;
if (!global_busy) {
sub_nsubs = 0;
sub_nlines = 0;
@@ -2964,7 +3271,7 @@ void do_sub(exarg_T *eap)
/* don't accept alphanumeric for separator */
if (isalpha(*cmd)) {
EMSG(_("E146: Regular expressions can't be delimited by letters"));
- return;
+ return NULL;
}
/*
* undocumented vi feature:
@@ -2975,21 +3282,26 @@ void do_sub(exarg_T *eap)
++cmd;
if (vim_strchr((char_u *)"/?&", *cmd) == NULL) {
EMSG(_(e_backslash));
- return;
+ return NULL;
+ }
+ if (*cmd != '&') {
+ which_pat = RE_SEARCH; // use last '/' pattern
}
- if (*cmd != '&')
- which_pat = RE_SEARCH; /* use last '/' pattern */
- pat = (char_u *)""; /* empty search pattern */
- delimiter = *cmd++; /* remember delimiter character */
- } else { /* find the end of the regexp */
- if (p_altkeymap && curwin->w_p_rl)
+ pat = (char_u *)""; // empty search pattern
+ delimiter = *cmd++; // remember delimiter character
+ has_second_delim = true;
+ } else { // find the end of the regexp
+ if (p_altkeymap && curwin->w_p_rl) {
lrF_sub(cmd);
- which_pat = RE_LAST; /* use last used regexp */
- delimiter = *cmd++; /* remember delimiter character */
- pat = cmd; /* remember start of search pat */
+ }
+ which_pat = RE_LAST; // use last used regexp
+ delimiter = *cmd++; // remember delimiter character
+ pat = cmd; // remember start of search pat
cmd = skip_regexp(cmd, delimiter, p_magic, &eap->arg);
- if (cmd[0] == delimiter) /* end delimiter found */
- *cmd++ = NUL; /* replace it with a NUL */
+ if (cmd[0] == delimiter) { // end delimiter found
+ *cmd++ = NUL; // replace it with a NUL
+ has_second_delim = true;
+ }
}
/*
@@ -3003,12 +3315,13 @@ void do_sub(exarg_T *eap)
*cmd++ = NUL; /* replace it with a NUL */
break;
}
- if (cmd[0] == '\\' && cmd[1] != 0) /* skip escaped characters */
- ++cmd;
- mb_ptr_adv(cmd);
+ if (cmd[0] == '\\' && cmd[1] != 0) { // skip escaped characters
+ cmd++;
+ }
+ MB_PTR_ADV(cmd);
}
- if (!eap->skip) {
+ if (!eap->skip && !preview) {
sub_set_replacement((SubReplacementString) {
.sub = xstrdup((char *) sub),
.timestamp = os_time(),
@@ -3018,7 +3331,7 @@ void do_sub(exarg_T *eap)
} else if (!eap->skip) { /* use previous pattern and substitution */
if (old_sub.sub == NULL) { /* there is no previous command */
EMSG(_(e_nopresub));
- return;
+ return NULL;
}
pat = NULL; /* search_regcomp() will use previous pattern */
sub = (char_u *) old_sub.sub;
@@ -3028,106 +3341,22 @@ void do_sub(exarg_T *eap)
endcolumn = (curwin->w_curswant == MAXCOL);
}
- // Recognize ":%s/\n//" and turn it into a join command, which is much
- // more efficient.
- // TODO: find a generic solution to make line-joining operations more
- // efficient, avoid allocating a string that grows in size.
- if (pat != NULL
- && strcmp((const char *)pat, "\\n") == 0
- && *sub == NUL
- && (*cmd == NUL || (cmd[1] == NUL
- && (*cmd == 'g'
- || *cmd == 'l'
- || *cmd == 'p'
- || *cmd == '#')))) {
- curwin->w_cursor.lnum = eap->line1;
- if (*cmd == 'l') {
- eap->flags = EXFLAG_LIST;
- } else if (*cmd == '#') {
- eap->flags = EXFLAG_NR;
- } else if (*cmd == 'p') {
- eap->flags = EXFLAG_PRINT;
- }
-
- // The number of lines joined is the number of lines in the range
- linenr_T joined_lines_count = eap->line2 - eap->line1 + 1
- // plus one extra line if not at the end of file.
- + (eap->line2 < curbuf->b_ml.ml_line_count ? 1 : 0);
- if (joined_lines_count > 1) {
- do_join(joined_lines_count, FALSE, TRUE, FALSE, true);
- sub_nsubs = joined_lines_count - 1;
- sub_nlines = 1;
- do_sub_msg(false);
- ex_may_print(eap);
- }
-
- if (!cmdmod.keeppatterns) {
- save_re_pat(RE_SUBST, pat, p_magic);
- }
- add_to_history(HIST_SEARCH, pat, TRUE, NUL);
-
- return;
+ if (sub != NULL && sub_joining_lines(eap, pat, sub, cmd, !preview)) {
+ return NULL;
}
- /*
- * Find trailing options. When '&' is used, keep old options.
- */
- if (*cmd == '&') {
- ++cmd;
- } else {
- // default is global on
- do_all = p_gd ? TRUE : FALSE;
-
- do_ask = FALSE;
- do_error = TRUE;
- do_print = FALSE;
- do_count = false;
- do_number = FALSE;
- do_ic = 0;
- }
- while (*cmd) {
- // Note that 'g' and 'c' are always inverted.
- // 'r' is never inverted.
- if (*cmd == 'g')
- do_all = !do_all;
- else if (*cmd == 'c')
- do_ask = !do_ask;
- else if (*cmd == 'n')
- do_count = true;
- else if (*cmd == 'e')
- do_error = !do_error;
- else if (*cmd == 'r') /* use last used regexp */
- which_pat = RE_LAST;
- else if (*cmd == 'p')
- do_print = TRUE;
- else if (*cmd == '#') {
- do_print = TRUE;
- do_number = TRUE;
- } else if (*cmd == 'l') {
- do_print = TRUE;
- do_list = TRUE;
- } else if (*cmd == 'i') /* ignore case */
- do_ic = 'i';
- else if (*cmd == 'I') /* don't ignore case */
- do_ic = 'I';
- else
- break;
- ++cmd;
- }
- if (do_count) {
- do_ask = FALSE;
- }
+ cmd = sub_parse_flags(cmd, &subflags, &which_pat);
- save_do_all = do_all;
- save_do_ask = do_ask;
+ bool save_do_all = subflags.do_all; // remember user specified 'g' flag
+ bool save_do_ask = subflags.do_ask; // remember user specified 'c' flag
// check for a trailing count
cmd = skipwhite(cmd);
if (ascii_isdigit(*cmd)) {
i = getdigits_long(&cmd);
- if (i <= 0 && !eap->skip && do_error) {
+ if (i <= 0 && !eap->skip && subflags.do_error) {
EMSG(_(e_zerocount));
- return;
+ return NULL;
}
eap->line1 = eap->line2;
eap->line2 += i - 1;
@@ -3143,31 +3372,34 @@ void do_sub(exarg_T *eap)
eap->nextcmd = check_nextcmd(cmd);
if (eap->nextcmd == NULL) {
EMSG(_(e_trailing));
- return;
+ return NULL;
}
}
- if (eap->skip) /* not executing commands, only parsing */
- return;
+ if (eap->skip) { // not executing commands, only parsing
+ return NULL;
+ }
- if (!do_count && !MODIFIABLE(curbuf)) {
- /* Substitution is not allowed in non-'modifiable' buffer */
+ if (!subflags.do_count && !MODIFIABLE(curbuf)) {
+ // Substitution is not allowed in non-'modifiable' buffer
EMSG(_(e_modifiable));
- return;
+ return NULL;
}
- if (search_regcomp(pat, RE_SUBST, which_pat, SEARCH_HIS,
- &regmatch) == FAIL) {
- if (do_error)
+ if (search_regcomp(pat, RE_SUBST, which_pat, (preview ? 0 : SEARCH_HIS),
+ &regmatch) == FAIL) {
+ if (subflags.do_error) {
EMSG(_(e_invcmd));
- return;
+ }
+ return NULL;
}
- /* the 'i' or 'I' flag overrules 'ignorecase' and 'smartcase' */
- if (do_ic == 'i')
- regmatch.rmm_ic = TRUE;
- else if (do_ic == 'I')
- regmatch.rmm_ic = FALSE;
+ // the 'i' or 'I' flag overrules 'ignorecase' and 'smartcase'
+ if (subflags.do_ic == kSubIgnoreCase) {
+ regmatch.rmm_ic = true;
+ } else if (subflags.do_ic == kSubMatchCase) {
+ regmatch.rmm_ic = false;
+ }
sub_firstline = NULL;
@@ -3179,29 +3411,28 @@ void do_sub(exarg_T *eap)
if (!(sub[0] == '\\' && sub[1] == '='))
sub = regtilde(sub, p_magic);
- /*
- * Check for a match on each line.
- */
- line2 = eap->line2;
- for (lnum = eap->line1; lnum <= line2 && !(got_quit
- || aborting()
- ); ++lnum) {
- nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
- (colnr_T)0, NULL);
+ // Check for a match on each line.
+ // If preview: limit to max('cmdwinheight', viewport).
+ linenr_T line2 = eap->line2;
+ for (linenr_T lnum = eap->line1;
+ lnum <= line2 && !got_quit && !aborting()
+ && (!preview || preview_lines.lines_needed <= (linenr_T)p_cwh
+ || lnum <= curwin->w_botline);
+ lnum++) {
+ long nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
+ (colnr_T)0, NULL);
if (nmatch) {
colnr_T copycol;
colnr_T matchcol;
colnr_T prev_matchcol = MAXCOL;
char_u *new_end, *new_start = NULL;
- unsigned new_start_len = 0;
char_u *p1;
int did_sub = FALSE;
int lastone;
- int len, copy_len, needed_len;
- long nmatch_tl = 0; /* nr of lines matched below lnum */
- int do_again; /* do it again after joining lines */
- int skip_match = FALSE;
- linenr_T sub_firstlnum; /* nr of first sub line */
+ long nmatch_tl = 0; // nr of lines matched below lnum
+ int do_again; // do it again after joining lines
+ int skip_match = false;
+ linenr_T sub_firstlnum; // nr of first sub line
/*
* The new text is build up step by step, to avoid too much
@@ -3241,8 +3472,7 @@ void do_sub(exarg_T *eap)
* accordingly.
*
* The new text is built up in new_start[]. It has some extra
- * room to avoid using xmalloc()/free() too often. new_start_len is
- * the length of the allocated memory at new_start.
+ * room to avoid using xmalloc()/free() too often.
*
* Make a copy of the old line, so it won't be taken away when
* updating the screen or handling a multi-line match. The "old_"
@@ -3261,16 +3491,25 @@ void do_sub(exarg_T *eap)
/*
* Loop until nothing more to replace in this line.
* 1. Handle match with empty string.
- * 2. If do_ask is set, ask for confirmation.
+ * 2. If subflags.do_ask is set, ask for confirmation.
* 3. substitute the string.
- * 4. if do_all is set, find next match
+ * 4. if subflags.do_all is set, find next match
* 5. break if there isn't another match in this line
*/
for (;; ) {
- /* Advance "lnum" to the line where the match starts. The
- * match does not start in the first line when there is a line
- * break before \zs. */
+ SubResult current_match = {
+ .start = { 0, 0 },
+ .end = { 0, 0 },
+ .pre_match = 0,
+ };
+ // lnum is where the match start, but maybe not the pattern match,
+ // since we can have \n before \zs in the pattern
+
+ // Advance "lnum" to the line where the match starts. The
+ // match does not start in the first line when there is a line
+ // break before \zs.
if (regmatch.startpos[0].lnum > 0) {
+ current_match.pre_match = lnum;
lnum += regmatch.startpos[0].lnum;
sub_firstlnum += regmatch.startpos[0].lnum;
nmatch -= regmatch.startpos[0].lnum;
@@ -3278,6 +3517,10 @@ void do_sub(exarg_T *eap)
sub_firstline = NULL;
}
+ // Now we're at the line where the pattern match starts
+ // Note: If not first match on a line, column can't be known here
+ current_match.start.lnum = sub_firstlnum;
+
if (sub_firstline == NULL) {
sub_firstline = vim_strsave(ml_get(sub_firstlnum));
}
@@ -3306,6 +3549,10 @@ void do_sub(exarg_T *eap)
else
++matchcol;
}
+ // match will be pushed to preview_lines, bring it into a proper state
+ current_match.start.col = matchcol;
+ current_match.end.lnum = sub_firstlnum;
+ current_match.end.col = matchcol;
goto skip;
}
@@ -3314,15 +3561,13 @@ void do_sub(exarg_T *eap)
matchcol = regmatch.endpos[0].col;
prev_matchcol = matchcol;
- /*
- * 2. If do_count is set only increase the counter.
- * If do_ask is set, ask for confirmation.
- */
- if (do_count) {
- /* For a multi-line match, put matchcol at the NUL at
- * the end of the line and set nmatch to one, so that
- * we continue looking for a match on the next line.
- * Avoids that ":s/\nB\@=//gc" get stuck. */
+ // 2. If subflags.do_count is set only increase the counter.
+ // If do_ask is set, ask for confirmation.
+ if (subflags.do_count) {
+ // For a multi-line match, put matchcol at the NUL at
+ // the end of the line and set nmatch to one, so that
+ // we continue looking for a match on the next line.
+ // Avoids that ":s/\nB\@=//gc" get stuck.
if (nmatch > 1) {
matchcol = (colnr_T)STRLEN(sub_firstline);
nmatch = 1;
@@ -3336,16 +3581,20 @@ void do_sub(exarg_T *eap)
goto skip;
}
- if (do_ask) {
+ if (subflags.do_ask && !preview) {
int typed = 0;
/* change State to CONFIRM, so that the mouse works
* properly */
- save_State = State;
+ int save_State = State;
State = CONFIRM;
setmouse(); /* disable mouse in xterm */
curwin->w_cursor.col = regmatch.startpos[0].col;
+ if (curwin->w_p_crb) {
+ do_check_cursorbind();
+ }
+
/* When 'cpoptions' contains "u" don't sync undo when
* asking for confirmation. */
if (vim_strchr(p_cpo, CPO_UNDO) != NULL)
@@ -3354,17 +3603,20 @@ void do_sub(exarg_T *eap)
/*
* Loop until 'y', 'n', 'q', CTRL-E or CTRL-Y typed.
*/
- while (do_ask) {
+ while (subflags.do_ask) {
if (exmode_active) {
char_u *resp;
colnr_T sc, ec;
- print_line_no_prefix(lnum, do_number, do_list);
+ print_line_no_prefix(lnum, subflags.do_number, subflags.do_list);
getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
curwin->w_cursor.col = regmatch.endpos[0].col - 1;
+ if (curwin->w_cursor.col < 0) {
+ curwin->w_cursor.col = 0;
+ }
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
- if (do_number || curwin->w_p_nu) {
+ if (subflags.do_number || curwin->w_p_nu) {
int numw = number_width(curwin) + 1;
sc += numw;
ec += numw;
@@ -3388,7 +3640,7 @@ void do_sub(exarg_T *eap)
curwin->w_p_fen = FALSE;
/* Invert the matched string.
* Remove the inversion afterwards. */
- temp = RedrawingDisabled;
+ int temp = RedrawingDisabled;
RedrawingDisabled = 0;
if (new_start != NULL) {
@@ -3405,7 +3657,7 @@ void do_sub(exarg_T *eap)
// before the cursor.
len_change = (int)STRLEN(new_line) - (int)STRLEN(orig_line);
curwin->w_cursor.col += len_change;
- ml_replace(lnum, new_line, FALSE);
+ ml_replace(lnum, new_line, false);
}
search_match_lines = regmatch.endpos[0].lnum
@@ -3430,7 +3682,7 @@ void do_sub(exarg_T *eap)
msg_no_more = TRUE;
/* write message same highlighting as for
* wait_return */
- smsg_attr(hl_attr(HLF_R),
+ smsg_attr(HL_ATTR(HLF_R),
_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
msg_no_more = FALSE;
msg_scroll = i;
@@ -3438,29 +3690,24 @@ void do_sub(exarg_T *eap)
ui_cursor_goto(msg_row, msg_col);
RedrawingDisabled = temp;
- ++no_mapping; /* don't map this key */
- ++allow_keys; /* allow special keys */
+ no_mapping++; // don't map this key
typed = plain_vgetc();
- --allow_keys;
- --no_mapping;
+ no_mapping--;
/* clear the question */
msg_didout = FALSE; /* don't scroll up */
msg_col = 0;
gotocmdline(TRUE);
- /* restore the line */
- if (orig_line != NULL)
- ml_replace(lnum, orig_line, FALSE);
+ // restore the line
+ if (orig_line != NULL) {
+ ml_replace(lnum, orig_line, false);
+ }
}
- need_wait_return = FALSE; /* no hit-return prompt */
- if (typed == 'q' || typed == ESC || typed == Ctrl_C
-#ifdef UNIX
- || typed == intr_char
-#endif
- ) {
- got_quit = TRUE;
+ need_wait_return = false; // no hit-return prompt
+ if (typed == 'q' || typed == ESC || typed == Ctrl_C) {
+ got_quit = true;
break;
}
if (typed == 'n')
@@ -3468,13 +3715,13 @@ void do_sub(exarg_T *eap)
if (typed == 'y')
break;
if (typed == 'l') {
- /* last: replace and then stop */
- do_all = FALSE;
+ // last: replace and then stop
+ subflags.do_all = false;
line2 = lnum;
break;
}
if (typed == 'a') {
- do_ask = FALSE;
+ subflags.do_ask = false;
break;
}
if (typed == Ctrl_E)
@@ -3507,156 +3754,164 @@ void do_sub(exarg_T *eap)
* use "\=col("."). */
curwin->w_cursor.col = regmatch.startpos[0].col;
- /*
- * 3. substitute the string.
- */
- if (do_count) {
- /* prevent accidentally changing the buffer by a function */
- save_ma = curbuf->b_p_ma;
- curbuf->b_p_ma = FALSE;
- sandbox++;
- }
- /* get length of substitution part */
- sublen = vim_regsub_multi(&regmatch,
- sub_firstlnum - regmatch.startpos[0].lnum,
- sub, sub_firstline, FALSE, p_magic, TRUE);
- if (do_count) {
- curbuf->b_p_ma = save_ma;
- sandbox--;
- goto skip;
- }
-
- /* When the match included the "$" of the last line it may
- * go beyond the last line of the buffer. */
+ // When the match included the "$" of the last line it may
+ // go beyond the last line of the buffer.
if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1) {
nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1;
- skip_match = TRUE;
+ current_match.end.lnum = sub_firstlnum + nmatch;
+ skip_match = true;
}
- /* Need room for:
- * - result so far in new_start (not for first sub in line)
- * - original text up to match
- * - length of substituted part
- * - original text after match
- */
- if (nmatch == 1)
- p1 = sub_firstline;
- else {
- p1 = ml_get(sub_firstlnum + nmatch - 1);
- nmatch_tl += nmatch - 1;
- }
- copy_len = regmatch.startpos[0].col - copycol;
- needed_len = copy_len + ((unsigned)STRLEN(p1)
- - regmatch.endpos[0].col) + sublen + 1;
- if (new_start == NULL) {
- /*
- * Get some space for a temporary buffer to do the
- * substitution into (and some extra space to avoid
- * too many calls to xmalloc()/free()).
- */
- new_start_len = needed_len + 50;
- new_start = xmalloc(new_start_len);
- *new_start = NUL;
- new_end = new_start;
- } else {
- /*
- * Check if the temporary buffer is long enough to do the
- * substitution into. If not, make it larger (with a bit
- * extra to avoid too many calls to xmalloc()/free()).
- */
- len = (unsigned)STRLEN(new_start);
- needed_len += len;
- if (needed_len > (int)new_start_len) {
- new_start_len = needed_len + 50;
- new_start = xrealloc(new_start, new_start_len);
+#define ADJUST_SUB_FIRSTLNUM() \
+ do { \
+ /* For a multi-line match, make a copy of the last matched */ \
+ /* line and continue in that one. */ \
+ if (nmatch > 1) { \
+ sub_firstlnum += nmatch - 1; \
+ xfree(sub_firstline); \
+ sub_firstline = vim_strsave(ml_get(sub_firstlnum)); \
+ /* When going beyond the last line, stop substituting. */ \
+ if (sub_firstlnum <= line2) { \
+ do_again = true; \
+ } else { \
+ subflags.do_all = false; \
+ } \
+ } \
+ if (skip_match) { \
+ /* Already hit end of the buffer, sub_firstlnum is one */ \
+ /* less than what it ought to be. */ \
+ xfree(sub_firstline); \
+ sub_firstline = vim_strsave((char_u *)""); \
+ copycol = 0; \
+ } \
+ } while (0)
+
+ // Save the line numbers for the preview buffer
+ // NOTE: If the pattern matches a final newline, the next line will
+ // be shown also, but should not be highlighted. Intentional for now.
+ if (preview && !has_second_delim) {
+ current_match.start.col = regmatch.startpos[0].col;
+ if (current_match.end.lnum == 0) {
+ current_match.end.lnum = sub_firstlnum + nmatch - 1;
}
- new_end = new_start + len;
- }
+ current_match.end.col = regmatch.endpos[0].col;
- /*
- * copy the text up to the part that matched
- */
- memmove(new_end, sub_firstline + copycol, (size_t)copy_len);
- new_end += copy_len;
-
- (void)vim_regsub_multi(&regmatch,
- sub_firstlnum - regmatch.startpos[0].lnum,
- sub, new_end, TRUE, p_magic, TRUE);
- sub_nsubs++;
- did_sub = TRUE;
-
- /* Move the cursor to the start of the line, to avoid that it
- * is beyond the end of the line after the substitution. */
- curwin->w_cursor.col = 0;
-
- /* For a multi-line match, make a copy of the last matched
- * line and continue in that one. */
- if (nmatch > 1) {
- sub_firstlnum += nmatch - 1;
- xfree(sub_firstline);
- sub_firstline = vim_strsave(ml_get(sub_firstlnum));
- /* When going beyond the last line, stop substituting. */
- if (sub_firstlnum <= line2)
- do_again = TRUE;
- else
- do_all = FALSE;
- }
+ ADJUST_SUB_FIRSTLNUM();
+ lnum += nmatch - 1;
- /* Remember next character to be copied. */
- copycol = regmatch.endpos[0].col;
-
- if (skip_match) {
- /* Already hit end of the buffer, sub_firstlnum is one
- * less than what it ought to be. */
- xfree(sub_firstline);
- sub_firstline = vim_strsave((char_u *)"");
- copycol = 0;
+ goto skip;
}
- /*
- * Now the trick is to replace CTRL-M chars with a real line
- * break. This would make it impossible to insert a CTRL-M in
- * the text. The line break can be avoided by preceding the
- * CTRL-M with a backslash. To be able to insert a backslash,
- * they must be doubled in the string and are halved here.
- * That is Vi compatible.
- */
- for (p1 = new_end; *p1; ++p1) {
- if (p1[0] == '\\' && p1[1] != NUL) /* remove backslash */
- STRMOVE(p1, p1 + 1);
- else if (*p1 == CAR) {
- if (u_inssub(lnum) == OK) { /* prepare for undo */
- *p1 = NUL; /* truncate up to the CR */
- ml_append(lnum - 1, new_start,
- (colnr_T)(p1 - new_start + 1), FALSE);
- mark_adjust(lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
- if (do_ask)
- appended_lines(lnum - 1, 1L);
- else {
- if (first_line == 0)
- first_line = lnum;
- last_line = lnum + 1;
+ // 3. Substitute the string. During 'inccommand' preview only do this if
+ // there is a replace pattern.
+ if (!preview || has_second_delim) {
+ if (subflags.do_count) {
+ // prevent accidentally changing the buffer by a function
+ save_ma = curbuf->b_p_ma;
+ curbuf->b_p_ma = false;
+ sandbox++;
+ }
+ // Save flags for recursion. They can change for e.g.
+ // :s/^/\=execute("s#^##gn")
+ subflags_T subflags_save = subflags;
+ // get length of substitution part
+ sublen = vim_regsub_multi(&regmatch,
+ sub_firstlnum - regmatch.startpos[0].lnum,
+ sub, sub_firstline, false, p_magic, true);
+ // Don't keep flags set by a recursive call
+ subflags = subflags_save;
+ if (subflags.do_count) {
+ curbuf->b_p_ma = save_ma;
+ if (sandbox > 0) {
+ sandbox--;
+ }
+ goto skip;
+ }
+
+ // Need room for:
+ // - result so far in new_start (not for first sub in line)
+ // - original text up to match
+ // - length of substituted part
+ // - original text after match
+ if (nmatch == 1) {
+ p1 = sub_firstline;
+ } else {
+ p1 = ml_get(sub_firstlnum + nmatch - 1);
+ nmatch_tl += nmatch - 1;
+ }
+ size_t copy_len = regmatch.startpos[0].col - copycol;
+ new_end = sub_grow_buf(&new_start,
+ (STRLEN(p1) - regmatch.endpos[0].col)
+ + copy_len + sublen + 1);
+
+ // copy the text up to the part that matched
+ memmove(new_end, sub_firstline + copycol, (size_t)copy_len);
+ new_end += copy_len;
+
+ // Finally, at this point we can know where the match actually will
+ // start in the new text
+ current_match.start.col = new_end - new_start;
+
+ (void)vim_regsub_multi(&regmatch,
+ sub_firstlnum - regmatch.startpos[0].lnum,
+ sub, new_end, true, p_magic, true);
+ sub_nsubs++;
+ did_sub = true;
+
+ // Move the cursor to the start of the line, to avoid that it
+ // is beyond the end of the line after the substitution.
+ curwin->w_cursor.col = 0;
+
+ // Remember next character to be copied.
+ copycol = regmatch.endpos[0].col;
+
+ ADJUST_SUB_FIRSTLNUM();
+
+ // Now the trick is to replace CTRL-M chars with a real line
+ // break. This would make it impossible to insert a CTRL-M in
+ // the text. The line break can be avoided by preceding the
+ // CTRL-M with a backslash. To be able to insert a backslash,
+ // they must be doubled in the string and are halved here.
+ // That is Vi compatible.
+ for (p1 = new_end; *p1; p1++) {
+ if (p1[0] == '\\' && p1[1] != NUL) { // remove backslash
+ STRMOVE(p1, p1 + 1);
+ } else if (*p1 == CAR) {
+ if (u_inssub(lnum) == OK) { // prepare for undo
+ *p1 = NUL; // truncate up to the CR
+ ml_append(lnum - 1, new_start,
+ (colnr_T)(p1 - new_start + 1), false);
+ mark_adjust(lnum + 1, (linenr_T)MAXLNUM, 1L, 0L, false);
+ if (subflags.do_ask) {
+ appended_lines(lnum - 1, 1L);
+ } else {
+ if (first_line == 0) {
+ first_line = lnum;
+ }
+ last_line = lnum + 1;
+ }
+ // All line numbers increase.
+ sub_firstlnum++;
+ lnum++;
+ line2++;
+ // move the cursor to the new line, like Vi
+ curwin->w_cursor.lnum++;
+ // copy the rest
+ STRMOVE(new_start, p1 + 1);
+ p1 = new_start - 1;
}
- /* All line numbers increase. */
- ++sub_firstlnum;
- ++lnum;
- ++line2;
- /* move the cursor to the new line, like Vi */
- ++curwin->w_cursor.lnum;
- /* copy the rest */
- STRMOVE(new_start, p1 + 1);
- p1 = new_start - 1;
+ } else if (has_mbyte) {
+ p1 += (*mb_ptr2len)(p1) - 1;
}
- } else if (has_mbyte)
- p1 += (*mb_ptr2len)(p1) - 1;
+ }
+ current_match.end.col = STRLEN(new_start);
+ current_match.end.lnum = lnum;
}
- /*
- * 4. If do_all is set, find next match.
- * Prevent endless loop with patterns that match empty
- * strings, e.g. :s/$/pat/g or :s/[a-z]* /(&)/g.
- * But ":s/\n/#/" is OK.
- */
+ // 4. If subflags.do_all is set, find next match.
+ // Prevent endless loop with patterns that match empty
+ // strings, e.g. :s/$/pat/g or :s/[a-z]* /(&)/g.
+ // But ":s/\n/#/" is OK.
skip:
/* We already know that we did the last subst when we are at
* the end of the line, except that a pattern like
@@ -3667,7 +3922,7 @@ skip:
|| got_int
|| got_quit
|| lnum > line2
- || !(do_all || do_again)
+ || !(subflags.do_all || do_again)
|| (sub_firstline[matchcol] == NUL && nmatch <= 1
&& !re_multiline(regmatch.regprog)));
nmatch = -1;
@@ -3700,9 +3955,10 @@ skip:
prev_matchcol = (colnr_T)STRLEN(sub_firstline)
- prev_matchcol;
- if (u_savesub(lnum) != OK)
+ if (u_savesub(lnum) != OK) {
break;
- ml_replace(lnum, new_start, TRUE);
+ }
+ ml_replace(lnum, new_start, true);
if (nmatch_tl > 0) {
/*
@@ -3717,21 +3973,23 @@ skip:
for (i = 0; i < nmatch_tl; ++i)
ml_delete(lnum, (int)FALSE);
mark_adjust(lnum, lnum + nmatch_tl - 1,
- (long)MAXLNUM, -nmatch_tl);
- if (do_ask)
+ (long)MAXLNUM, -nmatch_tl, false);
+ if (subflags.do_ask) {
deleted_lines(lnum, nmatch_tl);
- --lnum;
- line2 -= nmatch_tl; /* nr of lines decreases */
+ }
+ lnum--;
+ line2 -= nmatch_tl; // nr of lines decreases
nmatch_tl = 0;
}
/* When asking, undo is saved each time, must also set
* changed flag each time. */
- if (do_ask)
+ if (subflags.do_ask) {
changed_bytes(lnum, 0);
- else {
- if (first_line == 0)
+ } else {
+ if (first_line == 0) {
first_line = lnum;
+ }
last_line = lnum + 1;
}
@@ -3757,9 +4015,30 @@ skip:
* found the match. */
if (nmatch == -1)
lnum -= regmatch.startpos[0].lnum;
+
+#define PUSH_PREVIEW_LINES() \
+ do { \
+ linenr_T match_lines = current_match.end.lnum \
+ - current_match.start.lnum +1; \
+ if (preview_lines.subresults.size > 0) { \
+ linenr_T last = kv_last(preview_lines.subresults).end.lnum; \
+ if (last == current_match.start.lnum) { \
+ preview_lines.lines_needed += match_lines - 1; \
+ } \
+ } else { \
+ preview_lines.lines_needed += match_lines; \
+ } \
+ kv_push(preview_lines.subresults, current_match); \
+ } while (0)
+
+ // Push the match to preview_lines.
+ PUSH_PREVIEW_LINES();
+
break;
}
}
+ // Push the match to preview_lines.
+ PUSH_PREVIEW_LINES();
line_breakcheck();
}
@@ -3772,6 +4051,10 @@ skip:
}
line_breakcheck();
+
+ if (profile_passed_limit(timeout)) {
+ got_quit = true;
+ }
}
if (first_line != 0) {
@@ -3779,14 +4062,22 @@ skip:
* the line number before the change (same as adding the number of
* deleted lines). */
i = curbuf->b_ml.ml_line_count - old_line_count;
- changed_lines(first_line, 0, last_line - i, i);
+ changed_lines(first_line, 0, last_line - i, i, false);
+
+ if (kv_size(curbuf->update_channels)) {
+ int64_t num_added = last_line - first_line;
+ int64_t num_removed = num_added - i;
+ buf_updates_send_changes(curbuf, first_line, num_added, num_removed,
+ do_buf_event);
+ }
}
xfree(sub_firstline); /* may have to free allocated copy of the line */
- /* ":s/pat//n" doesn't move the cursor */
- if (do_count)
+ // ":s/pat//n" doesn't move the cursor
+ if (subflags.do_count) {
curwin->w_cursor = old_cursor;
+ }
if (sub_nsubs > start_nsubs) {
/* Set the '[ and '] marks. */
@@ -3795,28 +4086,37 @@ skip:
curbuf->b_op_start.col = curbuf->b_op_end.col = 0;
if (!global_busy) {
- if (!do_ask) { /* when interactive leave cursor on the match */
- if (endcolumn)
+ // when interactive leave cursor on the match
+ if (!subflags.do_ask) {
+ if (endcolumn) {
coladvance((colnr_T)MAXCOL);
- else
+ } else {
beginline(BL_WHITE | BL_FIX);
+ }
}
- if (!do_sub_msg(do_count) && do_ask)
+ if (!preview && !do_sub_msg(subflags.do_count) && subflags.do_ask) {
MSG("");
- } else
- global_need_beginline = TRUE;
- if (do_print)
- print_line(curwin->w_cursor.lnum, do_number, do_list);
+ }
+ } else {
+ global_need_beginline = true;
+ }
+ if (subflags.do_print) {
+ print_line(curwin->w_cursor.lnum, subflags.do_number, subflags.do_list);
+ }
} else if (!global_busy) {
- if (got_int) /* interrupted */
+ if (got_int) {
+ // interrupted
EMSG(_(e_interr));
- else if (got_match) /* did find something but nothing substituted */
+ } else if (got_match) {
+ // did find something but nothing substituted
MSG("");
- else if (do_error) /* nothing found */
+ } else if (subflags.do_error) {
+ // nothing found
EMSG2(_(e_patnotf2), get_search_pat());
+ }
}
- if (do_ask && hasAnyFolding(curwin)) {
+ if (subflags.do_ask && hasAnyFolding(curwin)) {
// Cursor position may require updating
changed_window_setting();
}
@@ -3824,9 +4124,40 @@ skip:
vim_regfree(regmatch.regprog);
// Restore the flag values, they can be used for ":&&".
- do_all = save_do_all;
- do_ask = save_do_ask;
-}
+ subflags.do_all = save_do_all;
+ subflags.do_ask = save_do_ask;
+
+ // Show 'inccommand' preview if there are matched lines.
+ buf_T *preview_buf = NULL;
+ size_t subsize = preview_lines.subresults.size;
+ if (preview && !aborting()) {
+ if (got_quit) { // Substitution is too slow, disable 'inccommand'.
+ set_string_option_direct((char_u *)"icm", -1, (char_u *)"", OPT_FREE,
+ SID_NONE);
+ } else if (*p_icm != NUL && pat != NULL) {
+ if (pre_src_id == 0) {
+ // Get a unique new src_id, saved in a static
+ pre_src_id = bufhl_add_hl(NULL, 0, -1, 0, 0, 0);
+ }
+ if (pre_hl_id == 0) {
+ pre_hl_id = syn_check_group((char_u *)S_LEN("Substitute"));
+ }
+ curbuf->b_changed = save_b_changed; // preserve 'modified' during preview
+ preview_buf = show_sub(eap, old_cursor, &preview_lines,
+ pre_hl_id, pre_src_id);
+ if (subsize > 0) {
+ bufhl_clear_line_range(orig_buf, pre_src_id, eap->line1,
+ kv_last(preview_lines.subresults).end.lnum);
+ }
+ }
+ }
+
+ kv_destroy(preview_lines.subresults);
+
+ return preview_buf;
+#undef ADJUST_SUB_FIRSTLNUM
+#undef PUSH_PREVIEW_LINES
+} // NOLINT(readability/fn_size)
/*
* Give message for number of substitutions.
@@ -3877,6 +4208,17 @@ do_sub_msg (
return false;
}
+static void global_exe_one(char_u *const cmd, const linenr_T lnum)
+{
+ curwin->w_cursor.lnum = lnum;
+ curwin->w_cursor.col = 0;
+ if (*cmd == NUL || *cmd == '\n') {
+ do_cmdline((char_u *)"p", NULL, NULL, DOCMD_NOWAIT);
+ } else {
+ do_cmdline(cmd, NULL, NULL, DOCMD_NOWAIT);
+ }
+}
+
/*
* Execute a global command of the form:
*
@@ -3906,8 +4248,12 @@ void ex_global(exarg_T *eap)
int match;
int which_pat;
- if (global_busy) {
- EMSG(_("E147: Cannot do :global recursive")); /* will increment global_busy */
+ // When nesting the command works on one line. This allows for
+ // ":g/found/v/notfound/command".
+ if (global_busy && (eap->line1 != 1
+ || eap->line2 != curbuf->b_ml.ml_line_count)) {
+ // will increment global_busy to break out of the loop
+ EMSG(_("E147: Cannot do :global recursive with a range"));
return;
}
@@ -3956,95 +4302,97 @@ void ex_global(exarg_T *eap)
return;
}
- /*
- * pass 1: set marks for each (not) matching line
- */
- for (lnum = eap->line1; lnum <= eap->line2 && !got_int; ++lnum) {
- /* a match on this line? */
+ if (global_busy) {
+ lnum = curwin->w_cursor.lnum;
match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
- (colnr_T)0, NULL);
+ (colnr_T)0, NULL);
if ((type == 'g' && match) || (type == 'v' && !match)) {
- ml_setmarked(lnum);
- ndone++;
+ global_exe_one(cmd, lnum);
+ }
+ } else {
+ // pass 1: set marks for each (not) matching line
+ for (lnum = eap->line1; lnum <= eap->line2 && !got_int; lnum++) {
+ // a match on this line?
+ match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
+ (colnr_T)0, NULL);
+ if ((type == 'g' && match) || (type == 'v' && !match)) {
+ ml_setmarked(lnum);
+ ndone++;
+ }
+ line_breakcheck();
}
- line_breakcheck();
- }
- /*
- * pass 2: execute the command for each line that has been marked
- */
- if (got_int)
- MSG(_(e_interr));
- else if (ndone == 0) {
- if (type == 'v') {
- smsg(_("Pattern found in every line: %s"), pat);
+ // pass 2: execute the command for each line that has been marked
+ if (got_int) {
+ MSG(_(e_interr));
+ } else if (ndone == 0) {
+ if (type == 'v') {
+ smsg(_("Pattern found in every line: %s"), pat);
+ } else {
+ smsg(_("Pattern not found: %s"), pat);
+ }
} else {
- smsg(_("Pattern not found: %s"), pat);
+ global_exe(cmd);
}
- } else {
- start_global_changes();
- global_exe(cmd);
- end_global_changes();
+ ml_clearmarked(); // clear rest of the marks
}
- ml_clearmarked(); /* clear rest of the marks */
vim_regfree(regmatch.regprog);
}
-/*
- * Execute "cmd" on lines marked with ml_setmarked().
- */
+/// Execute `cmd` on lines marked with ml_setmarked().
void global_exe(char_u *cmd)
{
- linenr_T old_lcount; /* b_ml.ml_line_count before the command */
- buf_T *old_buf = curbuf; /* remember what buffer we started in */
- linenr_T lnum; /* line number according to old situation */
-
- /*
- * Set current position only once for a global command.
- * If global_busy is set, setpcmark() will not do anything.
- * If there is an error, global_busy will be incremented.
- */
+ linenr_T old_lcount; // b_ml.ml_line_count before the command
+ buf_T *old_buf = curbuf; // remember what buffer we started in
+ linenr_T lnum; // line number according to old situation
+ int save_mapped_ctrl_c = mapped_ctrl_c;
+
+ // Set current position only once for a global command.
+ // If global_busy is set, setpcmark() will not do anything.
+ // If there is an error, global_busy will be incremented.
setpcmark();
- /* When the command writes a message, don't overwrite the command. */
- msg_didout = TRUE;
+ // When the command writes a message, don't overwrite the command.
+ msg_didout = true;
+ // Disable CTRL-C mapping, let it interrupt (potentially long output).
+ mapped_ctrl_c = 0;
sub_nsubs = 0;
sub_nlines = 0;
- global_need_beginline = FALSE;
+ global_need_beginline = false;
global_busy = 1;
old_lcount = curbuf->b_ml.ml_line_count;
+
while (!got_int && (lnum = ml_firstmarked()) != 0 && global_busy == 1) {
- curwin->w_cursor.lnum = lnum;
- curwin->w_cursor.col = 0;
- if (*cmd == NUL || *cmd == '\n')
- do_cmdline((char_u *)"p", NULL, NULL, DOCMD_NOWAIT);
- else
- do_cmdline(cmd, NULL, NULL, DOCMD_NOWAIT);
+ global_exe_one(cmd, lnum);
os_breakcheck();
}
+ mapped_ctrl_c = save_mapped_ctrl_c;
global_busy = 0;
- if (global_need_beginline)
+ if (global_need_beginline) {
beginline(BL_WHITE | BL_FIX);
- else
- check_cursor(); /* cursor may be beyond the end of the line */
+ } else {
+ check_cursor(); // cursor may be beyond the end of the line
+ }
- /* the cursor may not have moved in the text but a change in a previous
- * line may move it on the screen */
+ // the cursor may not have moved in the text but a change in a previous
+ // line may move it on the screen
changed_line_abv_curs();
- /* If it looks like no message was written, allow overwriting the
- * command with the report for number of changes. */
- if (msg_col == 0 && msg_scrolled == 0)
- msg_didout = FALSE;
+ // If it looks like no message was written, allow overwriting the
+ // command with the report for number of changes.
+ if (msg_col == 0 && msg_scrolled == 0) {
+ msg_didout = false;
+ }
- /* If substitutes done, report number of substitutes, otherwise report
- * number of extra or deleted lines.
- * Don't report extra or deleted lines in the edge case where the buffer
- * we are in after execution is different from the buffer we started in. */
- if (!do_sub_msg(false) && curbuf == old_buf)
+ // If substitutes done, report number of substitutes, otherwise report
+ // number of extra or deleted lines.
+ // Don't report extra or deleted lines in the edge case where the buffer
+ // we are in after execution is different from the buffer we started in.
+ if (!do_sub_msg(false) && curbuf == old_buf) {
msgmore(curbuf->b_ml.ml_line_count - old_lcount);
+ }
}
#if defined(EXITFREE)
@@ -4116,7 +4464,7 @@ void ex_help(exarg_T *eap)
buf_T *buf;
int len;
char_u *lang;
- int old_KeyTyped = KeyTyped;
+ const bool old_KeyTyped = KeyTyped;
if (eap != NULL) {
/*
@@ -4188,22 +4536,25 @@ void ex_help(exarg_T *eap)
* Re-use an existing help window or open a new one.
* Always open a new one for ":tab help".
*/
- if (!curwin->w_buffer->b_help
+ if (!bt_help(curwin->w_buffer)
|| cmdmod.tab != 0
) {
- if (cmdmod.tab != 0)
+ if (cmdmod.tab != 0) {
wp = NULL;
- else
- for (wp = firstwin; wp != NULL; wp = wp->w_next)
- if (wp->w_buffer != NULL && wp->w_buffer->b_help)
+ } else {
+ wp = NULL;
+ FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
+ if (bt_help(wp2->w_buffer)) {
+ wp = wp2;
break;
- if (wp != NULL && wp->w_buffer->b_nwindows > 0)
+ }
+ }
+ }
+ if (wp != NULL && wp->w_buffer->b_nwindows > 0) {
win_enter(wp, true);
- else {
- /*
- * There is no help window yet.
- * Try to open the file specified by the "helpfile" option.
- */
+ } else {
+ // There is no help window yet.
+ // Try to open the file specified by the "helpfile" option.
if ((helpfd = mch_fopen((char *)p_hf, READBIN)) == NULL) {
smsg(_("Sorry, help file \"%s\" not found"), p_hf);
goto erret;
@@ -4294,11 +4645,11 @@ char_u *check_help_lang(char_u *arg)
* Assumption is made that the matched_string passed has already been found to
* match some string for which help is requested. webb.
*/
-int
-help_heuristic (
+int
+help_heuristic(
char_u *matched_string,
- int offset, /* offset for match */
- int wrong_case /* no matching case */
+ int offset, // offset for match
+ int wrong_case // no matching case
)
{
int num_letters;
@@ -4346,47 +4697,66 @@ static int help_compare(const void *s1, const void *s2)
return strcmp(p1, p2);
}
-/*
- * Find all help tags matching "arg", sort them and return in matches[], with
- * the number of matches in num_matches.
- * The matches will be sorted with a "best" match algorithm.
- * When "keep_lang" is TRUE try keeping the language of the current buffer.
- */
-int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_lang)
+// Find all help tags matching "arg", sort them and return in matches[], with
+// the number of matches in num_matches.
+// The matches will be sorted with a "best" match algorithm.
+// When "keep_lang" is true try keeping the language of the current buffer.
+int find_help_tags(const char_u *arg, int *num_matches, char_u ***matches,
+ bool keep_lang)
{
- char_u *s, *d;
int i;
- static char *(mtable[]) = {"*", "g*", "[*", "]*",
- "/*", "/\\*", "\"*", "**",
- "/\\(\\)", "/\\%(\\)",
- "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
- "/\\?", "/\\z(\\)", "\\=", ":s\\=",
- "[count]", "[quotex]", "[range]",
- "[pattern]", "\\|", "\\%$",
- "s/\\~", "s/\\U", "s/\\L",
- "s/\\1", "s/\\2", "s/\\3", "s/\\9"};
- static char *(rtable[]) = {"star", "gstar", "[star", "]star",
- "/star", "/\\\\star", "quotestar", "starstar",
- "/\\\\(\\\\)", "/\\\\%(\\\\)",
- "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?",
- "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
- "\\[count]", "\\[quotex]", "\\[range]",
- "\\[pattern]", "\\\\bar", "/\\\\%\\$",
- "s/\\\\\\~", "s/\\\\U", "s/\\\\L",
- "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"};
- int flags;
-
- d = IObuff; /* assume IObuff is long enough! */
-
- /*
- * Recognize a few exceptions to the rule. Some strings that contain '*'
- * with "star". Otherwise '*' is recognized as a wildcard.
- */
- for (i = (int)ARRAY_SIZE(mtable); --i >= 0; )
- if (STRCMP(arg, mtable[i]) == 0) {
- STRCPY(d, rtable[i]);
- break;
+ static const char *(mtable[]) = {
+ "*", "g*", "[*", "]*",
+ "/*", "/\\*", "\"*", "**",
+ "/\\(\\)", "/\\%(\\)",
+ "?", ":?", "?<CR>", "g?", "g?g?", "g??",
+ "-?", "q?", "v_g?",
+ "/\\?", "/\\z(\\)", "\\=", ":s\\=",
+ "[count]", "[quotex]",
+ "[range]", ":[range]",
+ "[pattern]", "\\|", "\\%$",
+ "s/\\~", "s/\\U", "s/\\L",
+ "s/\\1", "s/\\2", "s/\\3", "s/\\9"
+ };
+ static const char *(rtable[]) = {
+ "star", "gstar", "[star", "]star",
+ "/star", "/\\\\star", "quotestar", "starstar",
+ "/\\\\(\\\\)", "/\\\\%(\\\\)",
+ "?", ":?", "?<CR>", "g?", "g?g?", "g??",
+ "-?", "q?", "v_g?",
+ "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=",
+ "\\[count]", "\\[quotex]",
+ "\\[range]", ":\\[range]",
+ "\\[pattern]", "\\\\bar", "/\\\\%\\$",
+ "s/\\\\\\~", "s/\\\\U", "s/\\\\L",
+ "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"
+ };
+ static const char *(expr_table[]) = {
+ "!=?", "!~?", "<=?", "<?", "==?", "=~?",
+ ">=?", ">?", "is?", "isnot?"
+ };
+ char_u *d = IObuff; // assume IObuff is long enough!
+
+ if (STRNICMP(arg, "expr-", 5) == 0) {
+ // When the string starting with "expr-" and containing '?' and matches
+ // the table, it is taken literally. Otherwise '?' is recognized as a
+ // wildcard.
+ for (i = (int)ARRAY_SIZE(expr_table); --i >= 0; ) {
+ if (STRCMP(arg + 5, expr_table[i]) == 0) {
+ STRCPY(d, arg);
+ break;
+ }
+ }
+ } else {
+ // Recognize a few exceptions to the rule. Some strings that contain
+ // '*' with "star". Otherwise '*' is recognized as a wildcard.
+ for (i = (int)ARRAY_SIZE(mtable); --i >= 0; ) {
+ if (STRCMP(arg, mtable[i]) == 0) {
+ STRCPY(d, rtable[i]);
+ break;
+ }
}
+ }
if (i < 0) { /* no match in table */
/* Replace "\S" with "/\\S", etc. Otherwise every tag is matched.
@@ -4418,7 +4788,7 @@ int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_la
if (*arg == '(' && arg[1] == '\'') {
arg++;
}
- for (s = arg; *s; s++) {
+ for (const char_u *s = arg; *s; s++) {
// Replace "|" with "bar" and '"' with "quote" to match the name of
// the tags for these commands.
// Replace "*" with ".*" and "?" with "." to match command line
@@ -4494,12 +4864,15 @@ int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_la
break;
}
- /*
- * If tag starts with ', toss everything after a second '. Fixes
- * CTRL-] on 'option'. (would include the trailing '.').
- */
- if (*s == '\'' && s > arg && *arg == '\'')
+ // If tag starts with ', toss everything after a second '. Fixes
+ // CTRL-] on 'option'. (would include the trailing '.').
+ if (*s == '\'' && s > arg && *arg == '\'') {
break;
+ }
+ // Also '{' and '}'. Fixes CTRL-] on '{address}'.
+ if (*s == '}' && s > arg && *arg == '{') {
+ break;
+ }
}
*d = NUL;
@@ -4524,9 +4897,10 @@ int find_help_tags(char_u *arg, int *num_matches, char_u ***matches, int keep_la
*matches = (char_u **)"";
*num_matches = 0;
- flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE;
- if (keep_lang)
+ int flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE;
+ if (keep_lang) {
flags |= TAG_KEEP_LANG;
+ }
if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL, NULL) == OK
&& *num_matches > 0) {
/* Sort the matches found on the heuristic number that is after the
@@ -4588,19 +4962,19 @@ void fix_help_buffer(void)
{
linenr_T lnum;
char_u *line;
- int in_example = FALSE;
- int len;
- char_u *fname;
- char_u *p;
- char_u *rt;
+ bool in_example = false;
- /* set filetype to "help". */
- set_option_value((char_u *)"ft", 0L, (char_u *)"help", OPT_LOCAL);
+ // Set filetype to "help".
+ if (STRCMP(curbuf->b_p_ft, "help") != 0) {
+ curbuf_lock++;
+ set_option_value("ft", 0L, "help", OPT_LOCAL);
+ curbuf_lock--;
+ }
if (!syntax_present(curwin)) {
- for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
- line = ml_get_buf(curbuf, lnum, FALSE);
- len = (int)STRLEN(line);
+ for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) {
+ line = ml_get_buf(curbuf, lnum, false);
+ const size_t len = STRLEN(line);
if (in_example && len > 0 && !ascii_iswhite(line[0])) {
/* End of example: non-white or '<' in first column. */
if (line[0] == '<') {
@@ -4608,14 +4982,14 @@ void fix_help_buffer(void)
line = ml_get_buf(curbuf, lnum, TRUE);
line[0] = ' ';
}
- in_example = FALSE;
+ in_example = false;
}
if (!in_example && len > 0) {
if (line[len - 1] == '>' && (len == 1 || line[len - 2] == ' ')) {
/* blank-out a '>' in the last column (start of example) */
line = ml_get_buf(curbuf, lnum, TRUE);
line[len - 1] = ' ';
- in_example = TRUE;
+ in_example = true;
} else if (line[len - 1] == '~') {
/* blank-out a '~' at the end of line (header marker) */
line = ml_get_buf(curbuf, lnum, TRUE);
@@ -4629,7 +5003,7 @@ void fix_help_buffer(void)
* In the "help.txt" and "help.abx" file, add the locally added help
* files. This uses the very first line in the help file.
*/
- fname = path_tail(curbuf->b_fname);
+ char_u *const fname = path_tail(curbuf->b_fname);
if (fnamecmp(fname, "help.txt") == 0
|| (fnamencmp(fname, "help.", 5) == 0
&& ASCII_ISALPHA(fname[5])
@@ -4644,22 +5018,25 @@ void fix_help_buffer(void)
/* Go through all directories in 'runtimepath', skipping
* $VIMRUNTIME. */
- p = p_rtp;
+ char_u *p = p_rtp;
while (*p != NUL) {
copy_option_part(&p, NameBuff, MAXPATHL, ",");
- rt = (char_u *)vim_getenv("VIMRUNTIME");
- if (path_full_compare(rt, NameBuff, FALSE) != kEqualFiles) {
+ char_u *const rt = (char_u *)vim_getenv("VIMRUNTIME");
+ if (rt != NULL
+ && path_full_compare(rt, NameBuff, false) != kEqualFiles) {
int fcount;
char_u **fnames;
- FILE *fd;
char_u *s;
- int fi;
vimconv_T vc;
char_u *cp;
- /* Find all "doc/ *.txt" files in this directory. */
- add_pathsep((char *)NameBuff);
- STRCAT(NameBuff, "doc/*.??[tx]");
+ // Find all "doc/ *.txt" files in this directory.
+ if (!add_pathsep((char *)NameBuff)
+ || STRLCAT(NameBuff, "doc/*.??[tx]",
+ sizeof(NameBuff)) >= MAXPATHL) {
+ EMSG(_(e_fnametoolong));
+ continue;
+ }
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
@@ -4667,31 +5044,25 @@ void fix_help_buffer(void)
if (gen_expand_wildcards(1, buff_list, &fcount,
&fnames, EW_FILE|EW_SILENT) == OK
&& fcount > 0) {
- int i1;
- int i2;
- char_u *f1;
- char_u *f2;
- char_u *t1;
- char_u *e1;
- char_u *e2;
-
- /* If foo.abx is found use it instead of foo.txt in
- * the same directory. */
- for (i1 = 0; i1 < fcount; ++i1) {
- for (i2 = 0; i2 < fcount; ++i2) {
- if (i1 == i2)
+ // If foo.abx is found use it instead of foo.txt in
+ // the same directory.
+ for (int i1 = 0; i1 < fcount; i1++) {
+ for (int i2 = 0; i2 < fcount; i2++) {
+ if (i1 == i2) {
continue;
- if (fnames[i1] == NULL || fnames[i2] == NULL)
- continue;
- f1 = fnames[i1];
- f2 = fnames[i2];
- t1 = path_tail(f1);
- if (fnamencmp(f1, f2, t1 - f1) != 0)
+ }
+ if (fnames[i1] == NULL || fnames[i2] == NULL) {
continue;
- e1 = vim_strrchr(t1, '.');
- e2 = vim_strrchr(path_tail(f2), '.');
- if (e1 == NUL || e2 == NUL)
+ }
+ const char_u *const f1 = fnames[i1];
+ const char_u *const f2 = fnames[i2];
+ const char_u *const t1 = path_tail(f1);
+ const char_u *const t2 = path_tail(f2);
+ const char_u *const e1 = STRRCHR(t1, '.');
+ const char_u *const e2 = STRRCHR(t2, '.');
+ if (e1 == NULL || e2 == NULL) {
continue;
+ }
if (fnamecmp(e1, ".txt") != 0
&& fnamecmp(e1, fname + 4) != 0) {
/* Not .txt and not .abx, remove it. */
@@ -4699,8 +5070,10 @@ void fix_help_buffer(void)
fnames[i1] = NULL;
continue;
}
- if (fnamencmp(f1, f2, e1 - f1) != 0)
+ if (e1 - f1 != e2 - f2
+ || fnamencmp(f1, f2, e1 - f1) != 0) {
continue;
+ }
if (fnamecmp(e1, ".txt") == 0
&& fnamecmp(e2, fname + 4) == 0) {
/* use .abx instead of .txt */
@@ -4709,10 +5082,12 @@ void fix_help_buffer(void)
}
}
}
- for (fi = 0; fi < fcount; ++fi) {
- if (fnames[fi] == NULL)
+ for (int fi = 0; fi < fcount; fi++) {
+ if (fnames[fi] == NULL) {
continue;
- fd = mch_fopen((char *)fnames[fi], "r");
+ }
+
+ FILE *const fd = mch_fopen((char *)fnames[fi], "r");
if (fd == NULL) {
continue;
}
@@ -4720,9 +5095,9 @@ void fix_help_buffer(void)
if (IObuff[0] == '*'
&& (s = vim_strchr(IObuff + 1, '*'))
!= NULL) {
- int this_utf = MAYBE;
- /* Change tag definition to a
- * reference and remove <CR>/<NL>. */
+ TriState this_utf = kNone;
+ // Change tag definition to a
+ // reference and remove <CR>/<NL>.
IObuff[0] = '|';
*s = '|';
while (*s != NUL) {
@@ -4732,13 +5107,12 @@ void fix_help_buffer(void)
* above 127 is found and no
* illegal byte sequence is found.
*/
- if (*s >= 0x80 && this_utf != FALSE) {
- int l;
-
- this_utf = TRUE;
- l = utf_ptr2len(s);
- if (l == 1)
- this_utf = FALSE;
+ if (*s >= 0x80 && this_utf != kFalse) {
+ this_utf = kTrue;
+ const int l = utf_ptr2len(s);
+ if (l == 1) {
+ this_utf = kFalse;
+ }
s += l - 1;
}
++s;
@@ -4747,18 +5121,20 @@ void fix_help_buffer(void)
* conversion to the current
* 'encoding' may be required. */
vc.vc_type = CONV_NONE;
- convert_setup(&vc, (char_u *)(
- this_utf == TRUE ? "utf-8"
- : "latin1"), p_enc);
- if (vc.vc_type == CONV_NONE)
- /* No conversion needed. */
+ convert_setup(
+ &vc,
+ (char_u *)(this_utf == kTrue ? "utf-8" : "latin1"),
+ p_enc);
+ if (vc.vc_type == CONV_NONE) {
+ // No conversion needed.
cp = IObuff;
- else {
- /* Do the conversion. If it fails
- * use the unconverted text. */
+ } else {
+ // Do the conversion. If it fails
+ // use the unconverted text.
cp = string_convert(&vc, IObuff, NULL);
- if (cp == NULL)
+ if (cp == NULL) {
cp = IObuff;
+ }
}
convert_setup(&vc, NULL, NULL);
@@ -4803,28 +5179,25 @@ void ex_viusage(exarg_T *eap)
/// @param tagname Name of the tags file ("tags" for English, "tags-fr" for
/// French)
/// @param add_help_tags Whether to add the "help-tags" tag
-static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
- bool add_help_tags)
+static void helptags_one(char_u *const dir, const char_u *const ext,
+ const char_u *const tagfname, const bool add_help_tags)
{
- FILE *fd_tags;
- FILE *fd;
garray_T ga;
int filecount;
char_u **files;
char_u *p1, *p2;
- int fi;
char_u *s;
- char_u *fname;
- int utf8 = MAYBE;
- int this_utf8;
- int firstline;
- int mix = FALSE; /* detected mixed encodings */
+ TriState utf8 = kNone;
+ bool mix = false; // detected mixed encodings
// Find all *.txt files.
- size_t dirlen = STRLEN(dir);
- STRCPY(NameBuff, dir);
- STRCAT(NameBuff, "/**/*");
- STRCAT(NameBuff, ext);
+ size_t dirlen = STRLCPY(NameBuff, dir, sizeof(NameBuff));
+ if (dirlen >= MAXPATHL
+ || STRLCAT(NameBuff, "/**/*", sizeof(NameBuff)) >= MAXPATHL // NOLINT
+ || STRLCAT(NameBuff, ext, sizeof(NameBuff)) >= MAXPATHL) {
+ EMSG(_(e_fnametoolong));
+ return;
+ }
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
@@ -4832,19 +5205,24 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
if (gen_expand_wildcards(1, buff_list, &filecount, &files,
EW_FILE|EW_SILENT) == FAIL
|| filecount == 0) {
- if (!got_int)
- EMSG2("E151: No match: %s", NameBuff);
+ if (!got_int) {
+ EMSG2(_("E151: No match: %s"), NameBuff);
+ }
return;
}
- /*
- * Open the tags file for writing.
- * Do this before scanning through all the files.
- */
- STRCPY(NameBuff, dir);
- add_pathsep((char *)NameBuff);
- STRNCAT(NameBuff, tagfname, sizeof(NameBuff) - dirlen - 2);
- fd_tags = mch_fopen((char *)NameBuff, "w");
+ //
+ // Open the tags file for writing.
+ // Do this before scanning through all the files.
+ //
+ memcpy(NameBuff, dir, dirlen + 1);
+ if (!add_pathsep((char *)NameBuff)
+ || STRLCAT(NameBuff, tagfname, sizeof(NameBuff)) >= MAXPATHL) {
+ EMSG(_(e_fnametoolong));
+ return;
+ }
+
+ FILE *const fd_tags = mch_fopen((char *)NameBuff, "w");
if (fd_tags == NULL) {
EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
FreeWild(filecount, files);
@@ -4856,8 +5234,9 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
* add the "help-tags" tag.
*/
ga_init(&ga, (int)sizeof(char_u *), 100);
- if (add_help_tags || path_full_compare((char_u *)"$VIMRUNTIME/doc",
- dir, FALSE) == kEqualFiles) {
+ if (add_help_tags
+ || path_full_compare((char_u *)"$VIMRUNTIME/doc",
+ dir, false) == kEqualFiles) {
s = xmalloc(18 + STRLEN(tagfname));
sprintf((char *)s, "help-tags\t%s\t1\n", tagfname);
GA_APPEND(char_u *, &ga, s);
@@ -4866,55 +5245,54 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
/*
* Go over all the files and extract the tags.
*/
- for (fi = 0; fi < filecount && !got_int; ++fi) {
- fd = mch_fopen((char *)files[fi], "r");
+ for (int fi = 0; fi < filecount && !got_int; fi++) {
+ FILE *const fd = mch_fopen((char *)files[fi], "r");
if (fd == NULL) {
EMSG2(_("E153: Unable to open %s for reading"), files[fi]);
continue;
}
- fname = files[fi] + dirlen + 1;
+ const char_u *const fname = files[fi] + dirlen + 1;
- firstline = TRUE;
+ bool firstline = true;
while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {
if (firstline) {
- /* Detect utf-8 file by a non-ASCII char in the first line. */
- this_utf8 = MAYBE;
- for (s = IObuff; *s != NUL; ++s)
+ // Detect utf-8 file by a non-ASCII char in the first line.
+ TriState this_utf8 = kNone;
+ for (s = IObuff; *s != NUL; s++) {
if (*s >= 0x80) {
- int l;
-
- this_utf8 = TRUE;
- l = utf_ptr2len(s);
+ this_utf8 = kTrue;
+ const int l = utf_ptr2len(s);
if (l == 1) {
- /* Illegal UTF-8 byte sequence. */
- this_utf8 = FALSE;
+ // Illegal UTF-8 byte sequence.
+ this_utf8 = kFalse;
break;
}
s += l - 1;
}
- if (this_utf8 == MAYBE) /* only ASCII characters found */
- this_utf8 = FALSE;
- if (utf8 == MAYBE) /* first file */
+ }
+ if (this_utf8 == kNone) { // only ASCII characters found
+ this_utf8 = kFalse;
+ }
+ if (utf8 == kNone) { // first file
utf8 = this_utf8;
- else if (utf8 != this_utf8) {
+ } else if (utf8 != this_utf8) {
EMSG2(_(
"E670: Mix of help file encodings within a language: %s"),
files[fi]);
mix = !got_int;
got_int = TRUE;
}
- firstline = FALSE;
+ firstline = false;
}
p1 = vim_strchr(IObuff, '*'); /* find first '*' */
while (p1 != NULL) {
- /* Use vim_strbyte() instead of vim_strchr() so that when
- * 'encoding' is dbcs it still works, don't find '*' in the
- * second byte. */
- p2 = vim_strbyte(p1 + 1, '*'); /* find second '*' */
- if (p2 != NULL && p2 > p1 + 1) { /* skip "*" and "**" */
- for (s = p1 + 1; s < p2; ++s)
- if (*s == ' ' || *s == '\t' || *s == '|')
+ p2 = (char_u *)strchr((const char *)p1 + 1, '*'); // Find second '*'.
+ if (p2 != NULL && p2 > p1 + 1) { // Skip "*" and "**".
+ for (s = p1 + 1; s < p2; s++) {
+ if (*s == ' ' || *s == '\t' || *s == '|') {
break;
+ }
+ }
/*
* Only accept a *tag* when it consists of valid
@@ -4974,8 +5352,9 @@ static void helptags_one(char_u *dir, char_u *ext, char_u *tagfname,
}
}
- if (utf8 == TRUE)
+ if (utf8 == kTrue) {
fprintf(fd_tags, "!_TAG_FILE_ENCODING\tutf-8\t//\n");
+ }
/*
* Write the tags into the file.
@@ -5016,9 +5395,12 @@ static void do_helptags(char_u *dirname, bool add_help_tags)
char_u **files;
// Get a list of all files in the help directory and in subdirectories.
- STRCPY(NameBuff, dirname);
- add_pathsep((char *)NameBuff);
- STRCAT(NameBuff, "**");
+ STRLCPY(NameBuff, dirname, sizeof(NameBuff));
+ if (!add_pathsep((char *)NameBuff)
+ || STRLCAT(NameBuff, "**", sizeof(NameBuff)) >= MAXPATHL) {
+ EMSG(_(e_fnametoolong));
+ return;
+ }
// Note: We cannot just do `&NameBuff` because it is a statically sized array
// so `NameBuff == &NameBuff` according to C semantics.
@@ -5026,8 +5408,7 @@ static void do_helptags(char_u *dirname, bool add_help_tags)
if (gen_expand_wildcards(1, buff_list, &filecount, &files,
EW_FILE|EW_SILENT) == FAIL
|| filecount == 0) {
- EMSG2("E151: No match: %s", NameBuff);
- xfree(dirname);
+ EMSG2(_("E151: No match: %s"), NameBuff);
return;
}
@@ -5132,13 +5513,14 @@ void ex_helptags(exarg_T *eap)
struct sign
{
- sign_T *sn_next; /* next sign in list */
- int sn_typenr; /* type number of sign */
- char_u *sn_name; /* name of sign */
- char_u *sn_icon; /* name of pixmap */
- char_u *sn_text; /* text used instead of pixmap */
- int sn_line_hl; /* highlight ID for line */
- int sn_text_hl; /* highlight ID for text */
+ sign_T *sn_next; // next sign in list
+ int sn_typenr; // type number of sign
+ char_u *sn_name; // name of sign
+ char_u *sn_icon; // name of pixmap
+ char_u *sn_text; // text used instead of pixmap
+ int sn_line_hl; // highlight ID for line
+ int sn_text_hl; // highlight ID for text
+ int sn_num_hl; // highlight ID for line number
};
static sign_T *first_sign = NULL;
@@ -5150,8 +5532,8 @@ static int next_sign_typenr = 1;
void ex_helpclose(exarg_T *eap)
{
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
- if (win->w_buffer->b_help) {
- win_close(win, FALSE);
+ if (bt_help(win->w_buffer)) {
+ win_close(win, false);
return;
}
}
@@ -5201,385 +5583,341 @@ static int sign_cmd_idx(
*/
void ex_sign(exarg_T *eap)
{
- char_u *arg = eap->arg;
- char_u *p;
- int idx;
- sign_T *sp;
- sign_T *sp_prev;
-
- /* Parse the subcommand. */
- p = skiptowhite(arg);
- idx = sign_cmd_idx(arg, p);
- if (idx == SIGNCMD_LAST)
- {
- EMSG2(_("E160: Unknown sign command: %s"), arg);
- return;
+ char_u *arg = eap->arg;
+ char_u *p;
+ int idx;
+ sign_T *sp;
+ sign_T *sp_prev;
+
+ // Parse the subcommand.
+ p = skiptowhite(arg);
+ idx = sign_cmd_idx(arg, p);
+ if (idx == SIGNCMD_LAST) {
+ EMSG2(_("E160: Unknown sign command: %s"), arg);
+ return;
+ }
+ arg = skipwhite(p);
+
+ if (idx <= SIGNCMD_LIST) {
+ // Define, undefine or list signs.
+ if (idx == SIGNCMD_LIST && *arg == NUL) {
+ // ":sign list": list all defined signs
+ for (sp = first_sign; sp != NULL && !got_int; sp = sp->sn_next) {
+ sign_list_defined(sp);
+ }
+ } else if (*arg == NUL) {
+ EMSG(_("E156: Missing sign name"));
+ } else {
+ // Isolate the sign name. If it's a number skip leading zeroes,
+ // so that "099" and "99" are the same sign. But keep "0".
+ p = skiptowhite(arg);
+ if (*p != NUL) {
+ *p++ = NUL;
+ }
+ while (arg[0] == '0' && arg[1] != NUL) {
+ arg++;
+ }
+
+ sp_prev = NULL;
+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
+ if (STRCMP(sp->sn_name, arg) == 0) {
+ break;
+ }
+ sp_prev = sp;
+ }
+ if (idx == SIGNCMD_DEFINE) {
+ // ":sign define {name} ...": define a sign
+ if (sp == NULL) {
+ sign_T *lp;
+ int start = next_sign_typenr;
+
+ // Allocate a new sign.
+ sp = xcalloc(1, sizeof(sign_T));
+
+ // Check that next_sign_typenr is not already being used.
+ // This only happens after wrapping around. Hopefully
+ // another one got deleted and we can use its number.
+ for (lp = first_sign; lp != NULL; ) {
+ if (lp->sn_typenr == next_sign_typenr) {
+ next_sign_typenr++;
+ if (next_sign_typenr == MAX_TYPENR) {
+ next_sign_typenr = 1;
+ }
+ if (next_sign_typenr == start) {
+ xfree(sp);
+ EMSG(_("E612: Too many signs defined"));
+ return;
+ }
+ lp = first_sign; // start all over
+ continue;
+ }
+ lp = lp->sn_next;
+ }
+
+ sp->sn_typenr = next_sign_typenr;
+ if (++next_sign_typenr == MAX_TYPENR) {
+ next_sign_typenr = 1; // wrap around
+ }
+
+ sp->sn_name = vim_strsave(arg);
+
+ // add the new sign to the list of signs
+ if (sp_prev == NULL) {
+ first_sign = sp;
+ } else {
+ sp_prev->sn_next = sp;
+ }
+ }
+
+ // set values for a defined sign.
+ for (;;) {
+ arg = skipwhite(p);
+ if (*arg == NUL) {
+ break;
+ }
+ p = skiptowhite_esc(arg);
+ if (STRNCMP(arg, "icon=", 5) == 0) {
+ arg += 5;
+ xfree(sp->sn_icon);
+ sp->sn_icon = vim_strnsave(arg, (int)(p - arg));
+ backslash_halve(sp->sn_icon);
+ } else if (STRNCMP(arg, "text=", 5) == 0) {
+ char_u *s;
+ int cells;
+ int len;
+
+ arg += 5;
+ for (s = arg; s + 1 < p; s++) {
+ if (*s == '\\') {
+ // Remove a backslash, so that it is possible
+ // to use a space.
+ STRMOVE(s, s + 1);
+ p--;
+ }
+ }
+
+ // Count cells and check for non-printable chars
+ cells = 0;
+ for (s = arg; s < p; s += utfc_ptr2len(s)) {
+ if (!vim_isprintc(utf_ptr2char(s))) {
+ break;
+ }
+ cells += utf_ptr2cells(s);
+ }
+ // Currently must be one or two display cells
+ if (s != p || cells < 1 || cells > 2) {
+ *p = NUL;
+ EMSG2(_("E239: Invalid sign text: %s"), arg);
+ return;
+ }
+
+ xfree(sp->sn_text);
+ // Allocate one byte more if we need to pad up
+ // with a space.
+ len = (int)(p - arg + ((cells == 1) ? 1 : 0));
+ sp->sn_text = vim_strnsave(arg, len);
+
+ if (cells == 1) {
+ STRCPY(sp->sn_text + len - 1, " ");
+ }
+ } else if (STRNCMP(arg, "linehl=", 7) == 0) {
+ arg += 7;
+ sp->sn_line_hl = syn_check_group(arg, (int)(p - arg));
+ } else if (STRNCMP(arg, "texthl=", 7) == 0) {
+ arg += 7;
+ sp->sn_text_hl = syn_check_group(arg, (int)(p - arg));
+ } else if (STRNCMP(arg, "numhl=", 6) == 0) {
+ arg += 6;
+ sp->sn_num_hl = syn_check_group(arg, (int)(p - arg));
+ } else {
+ EMSG2(_(e_invarg2), arg);
+ return;
+ }
+ }
+ } else if (sp == NULL) {
+ EMSG2(_("E155: Unknown sign: %s"), arg);
+ } else if (idx == SIGNCMD_LIST) {
+ // ":sign list {name}"
+ sign_list_defined(sp);
+ } else {
+ // ":sign undefine {name}"
+ sign_undefine(sp, sp_prev);
+ }
+ }
+ } else {
+ int id = -1;
+ linenr_T lnum = -1;
+ char_u *sign_name = NULL;
+ char_u *arg1;
+
+ if (*arg == NUL) {
+ if (idx == SIGNCMD_PLACE) {
+ // ":sign place": list placed signs in all buffers
+ sign_list_placed(NULL);
+ } else if (idx == SIGNCMD_UNPLACE) {
+ // ":sign unplace": remove placed sign at cursor
+ id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum);
+ if (id > 0) {
+ buf_delsign(curwin->w_buffer, id);
+ redraw_buf_line_later(curwin->w_buffer, curwin->w_cursor.lnum);
+ } else {
+ EMSG(_("E159: Missing sign number"));
+ }
+ } else {
+ EMSG(_(e_argreq));
+ }
+ return;
}
- arg = skipwhite(p);
- if (idx <= SIGNCMD_LIST)
- {
- /*
- * Define, undefine or list signs.
- */
- if (idx == SIGNCMD_LIST && *arg == NUL)
- {
- /* ":sign list": list all defined signs */
- for (sp = first_sign; sp != NULL && !got_int; sp = sp->sn_next)
- sign_list_defined(sp);
- }
- else if (*arg == NUL)
- EMSG(_("E156: Missing sign name"));
- else
- {
- /* Isolate the sign name. If it's a number skip leading zeroes,
- * so that "099" and "99" are the same sign. But keep "0". */
- p = skiptowhite(arg);
- if (*p != NUL)
- *p++ = NUL;
- while (arg[0] == '0' && arg[1] != NUL)
- ++arg;
-
- sp_prev = NULL;
- for (sp = first_sign; sp != NULL; sp = sp->sn_next)
- {
- if (STRCMP(sp->sn_name, arg) == 0)
- break;
- sp_prev = sp;
- }
- if (idx == SIGNCMD_DEFINE)
- {
- /* ":sign define {name} ...": define a sign */
- if (sp == NULL)
- {
- sign_T *lp;
- int start = next_sign_typenr;
-
- /* Allocate a new sign. */
- sp = xcalloc(1, sizeof(sign_T));
-
- /* Check that next_sign_typenr is not already being used.
- * This only happens after wrapping around. Hopefully
- * another one got deleted and we can use its number. */
- for (lp = first_sign; lp != NULL; )
- {
- if (lp->sn_typenr == next_sign_typenr)
- {
- ++next_sign_typenr;
- if (next_sign_typenr == MAX_TYPENR)
- next_sign_typenr = 1;
- if (next_sign_typenr == start)
- {
- xfree(sp);
- EMSG(_("E612: Too many signs defined"));
- return;
- }
- lp = first_sign; /* start all over */
- continue;
- }
- lp = lp->sn_next;
- }
-
- sp->sn_typenr = next_sign_typenr;
- if (++next_sign_typenr == MAX_TYPENR)
- next_sign_typenr = 1; /* wrap around */
-
- sp->sn_name = vim_strsave(arg);
-
- /* add the new sign to the list of signs */
- if (sp_prev == NULL)
- first_sign = sp;
- else
- sp_prev->sn_next = sp;
- }
-
- /* set values for a defined sign. */
- for (;;)
- {
- arg = skipwhite(p);
- if (*arg == NUL)
- break;
- p = skiptowhite_esc(arg);
- if (STRNCMP(arg, "icon=", 5) == 0)
- {
- arg += 5;
- xfree(sp->sn_icon);
- sp->sn_icon = vim_strnsave(arg, (int)(p - arg));
- backslash_halve(sp->sn_icon);
- }
- else if (STRNCMP(arg, "text=", 5) == 0)
- {
- char_u *s;
- int cells;
- int len;
-
- arg += 5;
-
- /* Count cells and check for non-printable chars */
- if (has_mbyte)
- {
- cells = 0;
- for (s = arg; s < p; s += (*mb_ptr2len)(s))
- {
- if (!vim_isprintc((*mb_ptr2char)(s)))
- break;
- cells += (*mb_ptr2cells)(s);
- }
- }
- else
-
- {
- for (s = arg; s < p; ++s)
- if (!vim_isprintc(*s))
- break;
- cells = (int)(s - arg);
- }
- /* Currently must be one or two display cells */
- if (s != p || cells < 1 || cells > 2)
- {
- *p = NUL;
- EMSG2(_("E239: Invalid sign text: %s"), arg);
- return;
- }
-
- xfree(sp->sn_text);
- /* Allocate one byte more if we need to pad up
- * with a space. */
- len = (int)(p - arg + ((cells == 1) ? 1 : 0));
- sp->sn_text = vim_strnsave(arg, len);
-
- if (cells == 1)
- STRCPY(sp->sn_text + len - 1, " ");
- }
- else if (STRNCMP(arg, "linehl=", 7) == 0)
- {
- arg += 7;
- sp->sn_line_hl = syn_check_group(arg, (int)(p - arg));
- }
- else if (STRNCMP(arg, "texthl=", 7) == 0)
- {
- arg += 7;
- sp->sn_text_hl = syn_check_group(arg, (int)(p - arg));
- }
- else
- {
- EMSG2(_(e_invarg2), arg);
- return;
- }
- }
- }
- else if (sp == NULL)
- EMSG2(_("E155: Unknown sign: %s"), arg);
- else if (idx == SIGNCMD_LIST)
- /* ":sign list {name}" */
- sign_list_defined(sp);
- else
- /* ":sign undefine {name}" */
- sign_undefine(sp, sp_prev);
- }
+ if (idx == SIGNCMD_UNPLACE && arg[0] == '*' && arg[1] == NUL) {
+ // ":sign unplace *": remove all placed signs
+ buf_delete_all_signs();
+ return;
}
- else
- {
- int id = -1;
- linenr_T lnum = -1;
- char_u *sign_name = NULL;
- char_u *arg1;
-
- if (*arg == NUL)
- {
- if (idx == SIGNCMD_PLACE)
- {
- /* ":sign place": list placed signs in all buffers */
- sign_list_placed(NULL);
- }
- else if (idx == SIGNCMD_UNPLACE)
- {
- /* ":sign unplace": remove placed sign at cursor */
- id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum);
- if (id > 0)
- {
- buf_delsign(curwin->w_buffer, id);
- update_debug_sign(curwin->w_buffer, curwin->w_cursor.lnum);
- }
- else
- EMSG(_("E159: Missing sign number"));
- }
- else
- EMSG(_(e_argreq));
- return;
- }
-
- if (idx == SIGNCMD_UNPLACE && arg[0] == '*' && arg[1] == NUL)
- {
- /* ":sign unplace *": remove all placed signs */
- buf_delete_all_signs();
- return;
- }
-
- /* first arg could be placed sign id */
- arg1 = arg;
- if (ascii_isdigit(*arg))
- {
- id = getdigits_int(&arg);
- if (!ascii_iswhite(*arg) && *arg != NUL)
- {
- id = -1;
- arg = arg1;
- }
- else
- {
- arg = skipwhite(arg);
- if (idx == SIGNCMD_UNPLACE && *arg == NUL)
- {
- // ":sign unplace {id}": remove placed sign by number
- FOR_ALL_BUFFERS(buf) {
- if ((lnum = buf_delsign(buf, id)) != 0) {
- update_debug_sign(buf, lnum);
- }
- }
- return;
- }
- }
- }
-
- /*
- * Check for line={lnum} name={name} and file={fname} or buffer={nr}.
- * Leave "arg" pointing to {fname}.
- */
-
- buf_T *buf = NULL;
- for (;;)
- {
- if (STRNCMP(arg, "line=", 5) == 0)
- {
- arg += 5;
- lnum = atoi((char *)arg);
- arg = skiptowhite(arg);
- }
- else if (STRNCMP(arg, "*", 1) == 0 && idx == SIGNCMD_UNPLACE)
- {
- if (id != -1)
- {
- EMSG(_(e_invarg));
- return;
- }
- id = -2;
- arg = skiptowhite(arg + 1);
- }
- else if (STRNCMP(arg, "name=", 5) == 0)
- {
- arg += 5;
- sign_name = arg;
- arg = skiptowhite(arg);
- if (*arg != NUL)
- *arg++ = NUL;
- while (sign_name[0] == '0' && sign_name[1] != NUL)
- ++sign_name;
- }
- else if (STRNCMP(arg, "file=", 5) == 0)
- {
- arg += 5;
- buf = buflist_findname(arg);
- break;
- }
- else if (STRNCMP(arg, "buffer=", 7) == 0)
- {
- arg += 7;
- buf = buflist_findnr(getdigits_int(&arg));
- if (*skipwhite(arg) != NUL)
- EMSG(_(e_trailing));
- break;
- }
- else
- {
- EMSG(_(e_invarg));
- return;
- }
- arg = skipwhite(arg);
- }
-
- if (buf == NULL)
- {
- EMSG2(_("E158: Invalid buffer name: %s"), arg);
- }
- else if (id <= 0 && !(idx == SIGNCMD_UNPLACE && id == -2))
- {
- if (lnum >= 0 || sign_name != NULL)
- EMSG(_(e_invarg));
- else
- /* ":sign place file={fname}": list placed signs in one file */
- sign_list_placed(buf);
- }
- else if (idx == SIGNCMD_JUMP)
- {
- /* ":sign jump {id} file={fname}" */
- if (lnum >= 0 || sign_name != NULL)
- EMSG(_(e_invarg));
- else if ((lnum = buf_findsign(buf, id)) > 0)
- { /* goto a sign ... */
- if (buf_jump_open_win(buf) != NULL)
- { /* ... in a current window */
- curwin->w_cursor.lnum = lnum;
- check_cursor_lnum();
- beginline(BL_WHITE);
- }
- else
- { // ... not currently in a window
- char *cmd = xmalloc(STRLEN(buf->b_fname) + 25);
- sprintf(cmd, "e +%" PRId64 " %s",
- (int64_t)lnum, buf->b_fname);
- do_cmdline_cmd(cmd);
- xfree(cmd);
- }
-
- foldOpenCursor();
- }
- else
- EMSGN(_("E157: Invalid sign ID: %" PRId64), id);
- }
- else if (idx == SIGNCMD_UNPLACE)
- {
- if (lnum >= 0 || sign_name != NULL)
- EMSG(_(e_invarg));
- else if (id == -2)
- {
- /* ":sign unplace * file={fname}" */
- redraw_buf_later(buf, NOT_VALID);
- buf_delete_signs(buf);
- }
- else
- {
- /* ":sign unplace {id} file={fname}" */
- lnum = buf_delsign(buf, id);
- update_debug_sign(buf, lnum);
- }
- }
- /* idx == SIGNCMD_PLACE */
- else if (sign_name != NULL)
- {
- for (sp = first_sign; sp != NULL; sp = sp->sn_next)
- if (STRCMP(sp->sn_name, sign_name) == 0)
- break;
- if (sp == NULL)
- {
- EMSG2(_("E155: Unknown sign: %s"), sign_name);
- return;
- }
- if (lnum > 0)
- /* ":sign place {id} line={lnum} name={name} file={fname}":
- * place a sign */
- buf_addsign(buf, id, lnum, sp->sn_typenr);
- else
- /* ":sign place {id} file={fname}": change sign type */
- lnum = buf_change_sign_type(buf, id, sp->sn_typenr);
- if (lnum > 0)
- update_debug_sign(buf, lnum);
- else
- EMSG2(_("E885: Not possible to change sign %s"), sign_name);
- }
- else
- EMSG(_(e_invarg));
+
+ // first arg could be placed sign id
+ arg1 = arg;
+ if (ascii_isdigit(*arg)) {
+ id = getdigits_int(&arg);
+ if (!ascii_iswhite(*arg) && *arg != NUL) {
+ id = -1;
+ arg = arg1;
+ } else {
+ arg = skipwhite(arg);
+ if (idx == SIGNCMD_UNPLACE && *arg == NUL) {
+ // ":sign unplace {id}": remove placed sign by number
+ FOR_ALL_BUFFERS(buf) {
+ if ((lnum = buf_delsign(buf, id)) != 0) {
+ redraw_buf_line_later(buf, lnum);
+ }
+ }
+ return;
+ }
+ }
+ }
+
+ // Check for line={lnum} name={name} and file={fname} or buffer={nr}.
+ // Leave "arg" pointing to {fname}.
+
+ buf_T *buf = NULL;
+ for (;;) {
+ if (STRNCMP(arg, "line=", 5) == 0) {
+ arg += 5;
+ lnum = atoi((char *)arg);
+ arg = skiptowhite(arg);
+ } else if (STRNCMP(arg, "*", 1) == 0 && idx == SIGNCMD_UNPLACE) {
+ if (id != -1) {
+ EMSG(_(e_invarg));
+ return;
+ }
+ id = -2;
+ arg = skiptowhite(arg + 1);
+ } else if (STRNCMP(arg, "name=", 5) == 0) {
+ arg += 5;
+ sign_name = arg;
+ arg = skiptowhite(arg);
+ if (*arg != NUL) {
+ *arg++ = NUL;
+ }
+ while (sign_name[0] == '0' && sign_name[1] != NUL) {
+ sign_name++;
+ }
+ } else if (STRNCMP(arg, "file=", 5) == 0) {
+ arg += 5;
+ buf = buflist_findname(arg);
+ break;
+ } else if (STRNCMP(arg, "buffer=", 7) == 0) {
+ arg += 7;
+ buf = buflist_findnr(getdigits_int(&arg));
+ if (*skipwhite(arg) != NUL) {
+ EMSG(_(e_trailing));
+ }
+ break;
+ } else {
+ EMSG(_(e_invarg));
+ return;
+ }
+ arg = skipwhite(arg);
+ }
+
+ if (buf == NULL) {
+ EMSG2(_("E158: Invalid buffer name: %s"), arg);
+ } else if (id <= 0 && !(idx == SIGNCMD_UNPLACE && id == -2)) {
+ if (lnum >= 0 || sign_name != NULL) {
+ EMSG(_(e_invarg));
+ } else {
+ // ":sign place file={fname}": list placed signs in one file
+ sign_list_placed(buf);
+ }
+ } else if (idx == SIGNCMD_JUMP) {
+ // ":sign jump {id} file={fname}"
+ if (lnum >= 0 || sign_name != NULL) {
+ EMSG(_(e_invarg));
+ } else if ((lnum = buf_findsign(buf, id)) > 0) {
+ // goto a sign ...
+ if (buf_jump_open_win(buf) != NULL) {
+ // ... in a current window
+ curwin->w_cursor.lnum = lnum;
+ check_cursor_lnum();
+ beginline(BL_WHITE);
+ } else {
+ // ... not currently in a window
+ if (buf->b_fname == NULL) {
+ EMSG(_("E934: Cannot jump to a buffer that does not have a name"));
+ return;
+ }
+ size_t cmdlen = STRLEN(buf->b_fname) + 24;
+ char *cmd = xmallocz(cmdlen);
+ snprintf(cmd, cmdlen, "e +%" PRId64 " %s",
+ (int64_t)lnum, buf->b_fname);
+ do_cmdline_cmd(cmd);
+ xfree(cmd);
+ }
+
+ foldOpenCursor();
+ } else {
+ EMSGN(_("E157: Invalid sign ID: %" PRId64), id);
+ }
+ } else if (idx == SIGNCMD_UNPLACE) {
+ if (lnum >= 0 || sign_name != NULL) {
+ EMSG(_(e_invarg));
+ } else if (id == -2) {
+ // ":sign unplace * file={fname}"
+ redraw_buf_later(buf, NOT_VALID);
+ buf_delete_signs(buf);
+ } else {
+ // ":sign unplace {id} file={fname}"
+ lnum = buf_delsign(buf, id);
+ redraw_buf_line_later(buf, lnum);
+ }
+ } else if (sign_name != NULL) {
+ // idx == SIGNCMD_PLACE
+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
+ if (STRCMP(sp->sn_name, sign_name) == 0) {
+ break;
+ }
+ }
+ if (sp == NULL) {
+ EMSG2(_("E155: Unknown sign: %s"), sign_name);
+ return;
+ }
+ if (lnum > 0) {
+ // ":sign place {id} line={lnum} name={name} file={fname}":
+ // place a sign
+ buf_addsign(buf, id, lnum, sp->sn_typenr);
+ } else {
+ // ":sign place {id} file={fname}": change sign type
+ lnum = buf_change_sign_type(buf, id, sp->sn_typenr);
+ }
+ if (lnum > 0) {
+ redraw_buf_line_later(buf, lnum);
+ } else {
+ EMSG2(_("E885: Not possible to change sign %s"), sign_name);
+ }
+ } else {
+ EMSG(_(e_invarg));
}
+ }
}
/*
@@ -5587,33 +5925,45 @@ void ex_sign(exarg_T *eap)
*/
static void sign_list_defined(sign_T *sp)
{
- char_u *p;
-
smsg("sign %s", sp->sn_name);
if (sp->sn_icon != NULL) {
- MSG_PUTS(" icon=");
+ msg_puts(" icon=");
msg_outtrans(sp->sn_icon);
- MSG_PUTS(_(" (not supported)"));
+ msg_puts(_(" (not supported)"));
}
if (sp->sn_text != NULL) {
- MSG_PUTS(" text=");
+ msg_puts(" text=");
msg_outtrans(sp->sn_text);
}
if (sp->sn_line_hl > 0) {
- MSG_PUTS(" linehl=");
- p = get_highlight_name(NULL, sp->sn_line_hl - 1);
- if (p == NULL)
- MSG_PUTS("NONE");
- else
+ msg_puts(" linehl=");
+ const char *const p = get_highlight_name_ext(NULL,
+ sp->sn_line_hl - 1, false);
+ if (p == NULL) {
+ msg_puts("NONE");
+ } else {
msg_puts(p);
+ }
}
if (sp->sn_text_hl > 0) {
- MSG_PUTS(" texthl=");
- p = get_highlight_name(NULL, sp->sn_text_hl - 1);
- if (p == NULL)
- MSG_PUTS("NONE");
- else
+ msg_puts(" texthl=");
+ const char *const p = get_highlight_name_ext(NULL,
+ sp->sn_text_hl - 1, false);
+ if (p == NULL) {
+ msg_puts("NONE");
+ } else {
+ msg_puts(p);
+ }
+ }
+ if (sp->sn_num_hl > 0) {
+ msg_puts(" numhl=");
+ const char *const p = get_highlight_name_ext(NULL,
+ sp->sn_num_hl - 1, false);
+ if (p == NULL) {
+ msg_puts("NONE");
+ } else {
msg_puts(p);
+ }
}
}
@@ -5632,25 +5982,33 @@ static void sign_undefine(sign_T *sp, sign_T *sp_prev)
xfree(sp);
}
-/*
- * Get highlighting attribute for sign "typenr".
- * If "line" is TRUE: line highl, if FALSE: text highl.
- */
-int sign_get_attr(int typenr, int line)
+/// Gets highlighting attribute for sign "typenr" corresponding to "type".
+int sign_get_attr(int typenr, SignType type)
{
sign_T *sp;
+ int sign_hl = 0;
- for (sp = first_sign; sp != NULL; sp = sp->sn_next)
+ for (sp = first_sign; sp != NULL; sp = sp->sn_next) {
if (sp->sn_typenr == typenr) {
- if (line) {
- if (sp->sn_line_hl > 0)
- return syn_id2attr(sp->sn_line_hl);
- } else {
- if (sp->sn_text_hl > 0)
- return syn_id2attr(sp->sn_text_hl);
+ switch (type) {
+ case SIGN_TEXT:
+ sign_hl = sp->sn_text_hl;
+ break;
+ case SIGN_LINEHL:
+ sign_hl = sp->sn_line_hl;
+ break;
+ case SIGN_NUMHL:
+ sign_hl = sp->sn_num_hl;
+ break;
+ default:
+ abort();
+ }
+ if (sign_hl > 0) {
+ return syn_id2attr(sign_hl);
}
break;
}
+ }
return 0;
}
@@ -5702,50 +6060,40 @@ static enum
EXP_SIGN_NAMES /* expand with name of placed signs */
} expand_what;
-/*
- * Function given to ExpandGeneric() to obtain the sign command
- * expansion.
- */
+/// Function given to ExpandGeneric() to obtain the sign command
+/// expansion.
char_u * get_sign_name(expand_T *xp, int idx)
{
- sign_T *sp;
- int current_idx;
-
- switch (expand_what)
- {
+ switch (expand_what)
+ {
case EXP_SUBCMD:
- return (char_u *)cmds[idx];
- case EXP_DEFINE:
- {
- char *define_arg[] =
- {
- "icon=", "linehl=", "text=", "texthl=", NULL
- };
- return (char_u *)define_arg[idx];
- }
- case EXP_PLACE:
- {
- char *place_arg[] =
- {
- "line=", "name=", "file=", "buffer=", NULL
- };
- return (char_u *)place_arg[idx];
- }
- case EXP_UNPLACE:
- {
- char *unplace_arg[] = { "file=", "buffer=", NULL };
- return (char_u *)unplace_arg[idx];
- }
- case EXP_SIGN_NAMES:
- /* Complete with name of signs already defined */
- current_idx = 0;
- for (sp = first_sign; sp != NULL; sp = sp->sn_next)
- if (current_idx++ == idx)
- return sp->sn_name;
- return NULL;
+ return (char_u *)cmds[idx];
+ case EXP_DEFINE: {
+ char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=",
+ NULL };
+ return (char_u *)define_arg[idx];
+ }
+ case EXP_PLACE: {
+ char *place_arg[] = { "line=", "name=", "file=", "buffer=", NULL };
+ return (char_u *)place_arg[idx];
+ }
+ case EXP_UNPLACE: {
+ char *unplace_arg[] = { "file=", "buffer=", NULL };
+ return (char_u *)unplace_arg[idx];
+ }
+ case EXP_SIGN_NAMES: {
+ // Complete with name of signs already defined
+ int current_idx = 0;
+ for (sign_T *sp = first_sign; sp != NULL; sp = sp->sn_next) {
+ if (current_idx++ == idx) {
+ return sp->sn_name;
+ }
+ }
+ }
+ return NULL;
default:
- return NULL;
- }
+ return NULL;
+ }
}
/*
@@ -5818,9 +6166,8 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
// :sign define {name} {args}... {last}=
// | |
// last p
- if (p == NUL)
- {
- /* Expand last argument name (before equal sign). */
+ if (p == NULL) {
+ // Expand last argument name (before equal sign).
xp->xp_pattern = last;
switch (cmd_idx)
{
@@ -5846,7 +6193,8 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
{
case SIGNCMD_DEFINE:
if (STRNCMP(last, "texthl", p - last) == 0
- || STRNCMP(last, "linehl", p - last) == 0) {
+ || STRNCMP(last, "linehl", p - last) == 0
+ || STRNCMP(last, "numhl", p - last) == 0) {
xp->xp_context = EXPAND_HIGHLIGHT;
} else if (STRNCMP(last, "icon", p - last) == 0) {
xp->xp_context = EXPAND_FILES;
@@ -5865,3 +6213,312 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
}
}
}
+
+/// Shows the effects of the :substitute command being typed ('inccommand').
+/// If inccommand=split, shows a preview window and later restores the layout.
+static buf_T *show_sub(exarg_T *eap, pos_T old_cusr,
+ PreviewLines *preview_lines, int hl_id, int src_id)
+ FUNC_ATTR_NONNULL_ALL
+{
+ static handle_T bufnr = 0; // special buffer, re-used on each visit
+
+ win_T *save_curwin = curwin;
+ cmdmod_T save_cmdmod = cmdmod;
+ char_u *save_shm_p = vim_strsave(p_shm);
+ PreviewLines lines = *preview_lines;
+ buf_T *orig_buf = curbuf;
+
+ // We keep a special-purpose buffer around, but don't assume it exists.
+ buf_T *preview_buf = bufnr ? buflist_findnr(bufnr) : 0;
+ cmdmod.tab = 0; // disable :tab modifier
+ cmdmod.noswapfile = true; // disable swap for preview buffer
+ // disable file info message
+ set_string_option_direct((char_u *)"shm", -1, (char_u *)"F", OPT_FREE,
+ SID_NONE);
+
+ bool outside_curline = (eap->line1 != old_cusr.lnum
+ || eap->line2 != old_cusr.lnum);
+ bool split = outside_curline && (*p_icm != 'n');
+ if (preview_buf == curbuf) { // Preview buffer cannot preview itself!
+ split = false;
+ preview_buf = NULL;
+ }
+
+ // Place cursor on nearest matching line, to undo do_sub() cursor placement.
+ for (size_t i = 0; i < lines.subresults.size; i++) {
+ SubResult curres = lines.subresults.items[i];
+ if (curres.start.lnum >= old_cusr.lnum) {
+ curwin->w_cursor.lnum = curres.start.lnum;
+ curwin->w_cursor.col = curres.start.col;
+ break;
+ } // Else: All matches are above, do_sub() already placed cursor.
+ }
+
+ // Width of the "| lnum|..." column which displays the line numbers.
+ linenr_T highest_num_line = 0;
+ int col_width = 0;
+
+ if (split && win_split((int)p_cwh, WSP_BOT) != FAIL) {
+ buf_open_scratch(preview_buf ? bufnr : 0, "[Preview]");
+ buf_clear();
+ preview_buf = curbuf;
+ bufnr = preview_buf->handle;
+ curbuf->b_p_bl = false;
+ curbuf->b_p_ma = true;
+ curbuf->b_p_ul = -1;
+ curbuf->b_p_tw = 0; // Reset 'textwidth' (was set by ftplugin)
+ curwin->w_p_cul = false;
+ curwin->w_p_cuc = false;
+ curwin->w_p_spell = false;
+ curwin->w_p_fen = false;
+
+ if (lines.subresults.size > 0) {
+ highest_num_line = kv_last(lines.subresults).end.lnum;
+ col_width = log10(highest_num_line) + 1 + 3;
+ }
+ }
+
+ char *str = NULL; // construct the line to show in here
+ size_t old_line_size = 0;
+ size_t line_size = 0;
+ linenr_T linenr_preview = 0; // last line added to preview buffer
+ linenr_T linenr_origbuf = 0; // last line added to original buffer
+ linenr_T next_linenr = 0; // next line to show for the match
+
+ for (size_t matchidx = 0; matchidx < lines.subresults.size; matchidx++) {
+ SubResult match = lines.subresults.items[matchidx];
+
+ if (split && preview_buf) {
+ lpos_T p_start = { 0, match.start.col }; // match starts here in preview
+ lpos_T p_end = { 0, match.end.col }; // ... and ends here
+
+ if (match.pre_match == 0) {
+ next_linenr = match.start.lnum;
+ } else {
+ next_linenr = match.pre_match;
+ }
+ // Don't add a line twice
+ if (next_linenr == linenr_origbuf) {
+ next_linenr++;
+ p_start.lnum = linenr_preview; // might be redefined below
+ p_end.lnum = linenr_preview; // might be redefined below
+ }
+
+ for (; next_linenr <= match.end.lnum; next_linenr++) {
+ if (next_linenr == match.start.lnum) {
+ p_start.lnum = linenr_preview + 1;
+ }
+ if (next_linenr == match.end.lnum) {
+ p_end.lnum = linenr_preview + 1;
+ }
+ char *line;
+ if (next_linenr == orig_buf->b_ml.ml_line_count + 1) {
+ line = "";
+ } else {
+ line = (char *)ml_get_buf(orig_buf, next_linenr, false);
+ line_size = strlen(line) + col_width + 1;
+
+ // Reallocate if line not long enough
+ if (line_size > old_line_size) {
+ str = xrealloc(str, line_size * sizeof(char));
+ old_line_size = line_size;
+ }
+ }
+ // Put "|lnum| line" into `str` and append it to the preview buffer.
+ snprintf(str, line_size, "|%*ld| %s", col_width - 3,
+ next_linenr, line);
+ if (linenr_preview == 0) {
+ ml_replace(1, (char_u *)str, true);
+ } else {
+ ml_append(linenr_preview, (char_u *)str, (colnr_T)line_size, false);
+ }
+ linenr_preview += 1;
+ }
+ linenr_origbuf = match.end.lnum;
+
+ bufhl_add_hl_pos_offset(preview_buf, src_id, hl_id, p_start,
+ p_end, col_width);
+ }
+ bufhl_add_hl_pos_offset(orig_buf, src_id, hl_id, match.start,
+ match.end, 0);
+ }
+ xfree(str);
+
+ redraw_later(SOME_VALID);
+ win_enter(save_curwin, false); // Return to original window
+ update_topline();
+
+ // Update screen now. Must do this _before_ close_windows().
+ int save_rd = RedrawingDisabled;
+ RedrawingDisabled = 0;
+ update_screen(SOME_VALID);
+ RedrawingDisabled = save_rd;
+
+ set_string_option_direct((char_u *)"shm", -1, save_shm_p, OPT_FREE, SID_NONE);
+ xfree(save_shm_p);
+
+ cmdmod = save_cmdmod;
+
+ return preview_buf;
+}
+
+/// :substitute command
+///
+/// If 'inccommand' is empty: calls do_sub().
+/// If 'inccommand' is set: shows a "live" preview then removes the changes.
+/// from undo history.
+void ex_substitute(exarg_T *eap)
+{
+ bool preview = (State & CMDPREVIEW);
+ if (*p_icm == NUL || !preview) { // 'inccommand' is disabled
+ (void)do_sub(eap, profile_zero(), true);
+ return;
+ }
+
+ block_autocmds(); // Disable events during command preview.
+
+ char_u *save_eap = eap->arg;
+ garray_T save_view;
+ win_size_save(&save_view); // Save current window sizes.
+ save_search_patterns();
+ int save_changedtick = buf_get_changedtick(curbuf);
+ time_t save_b_u_time_cur = curbuf->b_u_time_cur;
+ u_header_T *save_b_u_newhead = curbuf->b_u_newhead;
+ long save_b_p_ul = curbuf->b_p_ul;
+ int save_w_p_cul = curwin->w_p_cul;
+ int save_w_p_cuc = curwin->w_p_cuc;
+
+ curbuf->b_p_ul = LONG_MAX; // make sure we can undo all changes
+ curwin->w_p_cul = false; // Disable 'cursorline'
+ curwin->w_p_cuc = false; // Disable 'cursorcolumn'
+
+ // Don't show search highlighting during live substitution
+ bool save_hls = p_hls;
+ p_hls = false;
+ buf_T *preview_buf = do_sub(eap, profile_setlimit(p_rdt), false);
+ p_hls = save_hls;
+
+ if (save_changedtick != buf_get_changedtick(curbuf)) {
+ // Undo invisibly. This also moves the cursor!
+ if (!u_undo_and_forget(1)) { abort(); }
+ // Restore newhead. It is meaningless when curhead is valid, but we must
+ // restore it so that undotree() is identical before/after the preview.
+ curbuf->b_u_newhead = save_b_u_newhead;
+ curbuf->b_u_time_cur = save_b_u_time_cur;
+ buf_set_changedtick(curbuf, save_changedtick);
+ }
+ if (buf_valid(preview_buf)) {
+ // XXX: Must do this *after* u_undo_and_forget(), why?
+ close_windows(preview_buf, false);
+ }
+ curbuf->b_p_ul = save_b_p_ul;
+ curwin->w_p_cul = save_w_p_cul; // Restore 'cursorline'
+ curwin->w_p_cuc = save_w_p_cuc; // Restore 'cursorcolumn'
+ eap->arg = save_eap;
+ restore_search_patterns();
+ win_size_restore(&save_view);
+ ga_clear(&save_view);
+ unblock_autocmds();
+}
+
+/// Skip over the pattern argument of ":vimgrep /pat/[g][j]".
+/// Put the start of the pattern in "*s", unless "s" is NULL.
+/// If "flags" is not NULL put the flags in it: VGR_GLOBAL, VGR_NOJUMP.
+/// If "s" is not NULL terminate the pattern with a NUL.
+/// Return a pointer to the char just past the pattern plus flags.
+char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
+{
+ int c;
+
+ if (vim_isIDc(*p)) {
+ // ":vimgrep pattern fname"
+ if (s != NULL) {
+ *s = p;
+ }
+ p = skiptowhite(p);
+ if (s != NULL && *p != NUL) {
+ *p++ = NUL;
+ }
+ } else {
+ // ":vimgrep /pattern/[g][j] fname"
+ if (s != NULL) {
+ *s = p + 1;
+ }
+ c = *p;
+ p = skip_regexp(p + 1, c, true, NULL);
+ if (*p != c) {
+ return NULL;
+ }
+
+ // Truncate the pattern.
+ if (s != NULL) {
+ *p = NUL;
+ }
+ p++;
+
+ // Find the flags
+ while (*p == 'g' || *p == 'j') {
+ if (flags != NULL) {
+ if (*p == 'g') {
+ *flags |= VGR_GLOBAL;
+ } else {
+ *flags |= VGR_NOJUMP;
+ }
+ }
+ p++;
+ }
+ }
+ return p;
+}
+
+/// List v:oldfiles in a nice way.
+void ex_oldfiles(exarg_T *eap)
+{
+ list_T *l = get_vim_var_list(VV_OLDFILES);
+ long nr = 0;
+
+ if (l == NULL) {
+ msg((char_u *)_("No old files"));
+ } else {
+ msg_start();
+ msg_scroll = true;
+ TV_LIST_ITER(l, li, {
+ if (got_int) {
+ break;
+ }
+ nr++;
+ const char *fname = tv_get_string(TV_LIST_ITEM_TV(li));
+ if (!message_filtered((char_u *)fname)) {
+ msg_outnum(nr);
+ MSG_PUTS(": ");
+ msg_outtrans((char_u *)tv_get_string(TV_LIST_ITEM_TV(li)));
+ msg_clr_eos();
+ msg_putchar('\n');
+ ui_flush(); // output one line at a time
+ os_breakcheck();
+ }
+ });
+
+ // Assume "got_int" was set to truncate the listing.
+ got_int = false;
+
+ // File selection prompt on ":browse oldfiles"
+ if (cmdmod.browse) {
+ quit_more = false;
+ nr = prompt_for_number(false);
+ msg_starthere();
+ if (nr > 0 && nr <= tv_list_len(l)) {
+ const char *const p = tv_list_find_str(l, nr - 1);
+ if (p == NULL) {
+ return;
+ }
+ char *const s = (char *)expand_env_save((char_u *)p);
+ eap->arg = (char_u *)s;
+ eap->cmdidx = CMD_edit;
+ cmdmod.browse = false;
+ do_exedit(eap, NULL);
+ xfree(s);
+ }
+ }
+ }
+}
diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h
index 721145efd8..b564cde56c 100644
--- a/src/nvim/ex_cmds.h
+++ b/src/nvim/ex_cmds.h
@@ -4,15 +4,19 @@
#include <stdbool.h>
#include "nvim/os/time.h"
-#include "nvim/eval_defs.h"
+#include "nvim/pos.h"
+#include "nvim/eval/typval.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/ex_cmds_defs.h"
+
+// flags for do_ecmd()
+#define ECMD_HIDE 0x01 // don't free the current buffer
+#define ECMD_SET_HELP 0x02 // set b_help flag of (new) buffer before
+ // opening file
+#define ECMD_OLDBUF 0x04 // use existing buffer if it exists
+#define ECMD_FORCEIT 0x08 // ! used in Ex command
+#define ECMD_ADDBUF 0x10 // don't edit, just add to buffer list
-/* flags for do_ecmd() */
-#define ECMD_HIDE 0x01 /* don't free the current buffer */
-#define ECMD_SET_HELP 0x02 /* set b_help flag of (new) buffer before
- opening file */
-#define ECMD_OLDBUF 0x04 /* use existing buffer if it exists */
-#define ECMD_FORCEIT 0x08 /* ! used in Ex command */
-#define ECMD_ADDBUF 0x10 /* don't edit, just add to buffer list */
/* for lnum argument in do_ecmd() */
#define ECMD_LASTL (linenr_T)0 /* use last position in loaded file */
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 76191d5a56..4806eff1b4 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -1,4 +1,4 @@
-bit = require 'bit'
+local bit = require 'bit'
-- Description of the values below is contained in ex_cmds_defs.h file.
local RANGE = 0x001
@@ -28,13 +28,15 @@ local FILES = bit.bor(XFILE, EXTRA)
local WORD1 = bit.bor(EXTRA, NOSPC)
local FILE1 = bit.bor(FILES, NOSPC)
-local ADDR_LINES = 0
-local ADDR_WINDOWS = 1
-local ADDR_ARGUMENTS = 2
-local ADDR_LOADED_BUFFERS = 3
-local ADDR_BUFFERS = 4
-local ADDR_TABS = 5
-local ADDR_QUICKFIX = 6
+local ADDR_LINES = 0 -- buffer line numbers
+local ADDR_WINDOWS = 1 -- window number
+local ADDR_ARGUMENTS = 2 -- argument number
+local ADDR_LOADED_BUFFERS = 3 -- buffer number of loaded buffer
+local ADDR_BUFFERS = 4 -- buffer number
+local ADDR_TABS = 5 -- tab page number
+local ADDR_TABS_RELATIVE = 6 -- Tab page that only relative
+local ADDR_QUICKFIX = 7 -- quickfix list entry number
+local ADDR_OTHER = 99 -- something else
-- The following table is described in ex_cmds_defs.h file.
return {
@@ -106,7 +108,7 @@ return {
},
{
command='argedit',
- flags=bit.bor(BANG, NEEDARG, RANGE, NOTADR, ZEROR, FILE1, EDITCMD, ARGOPT, TRLBAR),
+ flags=bit.bor(BANG, NEEDARG, RANGE, NOTADR, ZEROR, FILES, EDITCMD, ARGOPT, TRLBAR),
addr_type=ADDR_ARGUMENTS,
func='ex_argedit',
},
@@ -357,6 +359,12 @@ return {
func='ex_cbuffer',
},
{
+ command='cbottom',
+ flags=bit.bor(TRLBAR),
+ addr_type=ADDR_LINES,
+ func='ex_cbottom',
+ },
+ {
command='cc',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG),
addr_type=ADDR_LINES,
@@ -443,6 +451,12 @@ return {
func='ex_changes',
},
{
+ command='checkhealth',
+ flags=bit.bor(EXTRA, TRLBAR),
+ addr_type=ADDR_LINES,
+ func='ex_checkhealth',
+ },
+ {
command='checkpath',
flags=bit.bor(TRLBAR, BANG, CMDWIN),
addr_type=ADDR_LINES,
@@ -455,6 +469,12 @@ return {
func='ex_checktime',
},
{
+ command='chistory',
+ flags=bit.bor(TRLBAR),
+ addr_type=ADDR_LINES,
+ func='qf_history',
+ },
+ {
command='clist',
flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
@@ -473,6 +493,12 @@ return {
func='ex_close',
},
{
+ command='clearjumps',
+ flags=bit.bor(TRLBAR, CMDWIN),
+ addr_type=ADDR_LINES,
+ func='ex_clearjumps',
+ },
+ {
command='cmap',
flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, USECTRLV, CMDWIN),
addr_type=ADDR_LINES,
@@ -594,7 +620,7 @@ return {
},
{
command='cquit',
- flags=bit.bor(TRLBAR, BANG),
+ flags=bit.bor(RANGE, NOTADR, COUNT, ZEROR, TRLBAR, BANG),
addr_type=ADDR_LINES,
func='ex_cquit',
},
@@ -608,13 +634,13 @@ return {
command='cscope',
flags=bit.bor(EXTRA, NOTRLCOM, XFILE),
addr_type=ADDR_LINES,
- func='do_cscope',
+ func='ex_cscope',
},
{
command='cstag',
flags=bit.bor(BANG, TRLBAR, WORD1),
addr_type=ADDR_LINES,
- func='do_cstag',
+ func='ex_cstag',
},
{
command='cunmap',
@@ -666,13 +692,13 @@ return {
},
{
command='delcommand',
- flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN),
+ flags=bit.bor(BANG, NEEDARG, WORD1, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
func='ex_delcommand',
},
{
command='delfunction',
- flags=bit.bor(NEEDARG, WORD1, CMDWIN),
+ flags=bit.bor(BANG, NEEDARG, WORD1, CMDWIN),
addr_type=ADDR_LINES,
func='ex_delfunction',
},
@@ -911,6 +937,12 @@ return {
func='ex_filetype',
},
{
+ command='filter',
+ flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM),
+ addr_type=ADDR_LINES,
+ func='ex_wrongmodifier',
+ },
+ {
command='find',
flags=bit.bor(RANGE, NOTADR, BANG, FILE1, EDITCMD, ARGOPT, TRLBAR),
addr_type=ADDR_LINES,
@@ -1050,7 +1082,7 @@ return {
},
{
command='hide',
- flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EXTRA, NOTRLCOM),
+ flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EXTRA, TRLBAR),
addr_type=ADDR_WINDOWS,
func='ex_hide',
},
@@ -1271,6 +1303,12 @@ return {
func='ex_cbuffer',
},
{
+ command='lbottom',
+ flags=bit.bor(TRLBAR),
+ addr_type=ADDR_LINES,
+ func='ex_cbottom',
+ },
+ {
command='lcd',
flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
@@ -1292,7 +1330,7 @@ return {
command='lcscope',
flags=bit.bor(EXTRA, NOTRLCOM, XFILE),
addr_type=ADDR_LINES,
- func='do_cscope',
+ func='ex_cscope',
},
{
command='ldo',
@@ -1381,6 +1419,12 @@ return {
func='ex_helpgrep',
},
{
+ command='lhistory',
+ flags=bit.bor(TRLBAR),
+ addr_type=ADDR_LINES,
+ func='qf_history',
+ },
+ {
command='ll',
flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR, BANG),
addr_type=ADDR_LINES,
@@ -1510,19 +1554,19 @@ return {
command='lua',
flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_script_ni',
+ func='ex_lua',
},
{
command='luado',
flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_ni',
+ func='ex_luado',
},
{
command='luafile',
flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_ni',
+ func='ex_luafile',
},
{
command='lvimgrep',
@@ -1604,8 +1648,8 @@ return {
},
{
command='messages',
- flags=bit.bor(TRLBAR, CMDWIN),
- addr_type=ADDR_LINES,
+ flags=bit.bor(EXTRA, TRLBAR, RANGE, CMDWIN),
+ addr_type=ADDR_OTHER,
func='ex_messages',
},
{
@@ -1663,24 +1707,6 @@ return {
func='ex_next',
},
{
- command='nbkey',
- flags=bit.bor(EXTRA, NOTADR, NEEDARG),
- addr_type=ADDR_LINES,
- func='ex_ni',
- },
- {
- command='nbclose',
- flags=bit.bor(TRLBAR, CMDWIN),
- addr_type=ADDR_LINES,
- func='ex_ni',
- },
- {
- command='nbstart',
- flags=bit.bor(WORD1, TRLBAR, CMDWIN),
- addr_type=ADDR_LINES,
- func='ex_ni',
- },
- {
command='new',
flags=bit.bor(BANG, FILE1, RANGE, NOTADR, EDITCMD, ARGOPT, TRLBAR),
addr_type=ADDR_LINES,
@@ -1915,18 +1941,6 @@ return {
func='ex_previous',
},
{
- command='promptfind',
- flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN),
- addr_type=ADDR_LINES,
- func='ex_ni',
- },
- {
- command='promptrepl',
- flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN),
- addr_type=ADDR_LINES,
- func='ex_ni',
- },
- {
command='profile',
flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
@@ -2053,6 +2067,30 @@ return {
func='ex_py3file',
},
{
+ command='pyx',
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ addr_type=ADDR_LINES,
+ func='ex_pyx',
+ },
+ {
+ command='pyxdo',
+ flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
+ addr_type=ADDR_LINES,
+ func='ex_pyxdo',
+ },
+ {
+ command='pythonx',
+ flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
+ addr_type=ADDR_LINES,
+ func='ex_pyx',
+ },
+ {
+ command='pyxfile',
+ flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
+ addr_type=ADDR_LINES,
+ func='ex_pyxfile',
+ },
+ {
command='quit',
flags=bit.bor(BANG, RANGE, COUNT, NOTADR, TRLBAR, CMDWIN),
addr_type=ADDR_WINDOWS,
@@ -2114,7 +2152,7 @@ return {
},
{
command='resize',
- flags=bit.bor(RANGE, NOTADR, TRLBAR, WORD1),
+ flags=bit.bor(RANGE, NOTADR, TRLBAR, WORD1, CMDWIN),
addr_type=ADDR_LINES,
func='ex_resize',
},
@@ -2170,19 +2208,19 @@ return {
command='ruby',
flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_script_ni',
+ func='ex_ruby',
},
{
command='rubydo',
flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_ni',
+ func='ex_rubydo',
},
{
command='rubyfile',
flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_ni',
+ func='ex_rubyfile',
},
{
command='rviminfo',
@@ -2194,7 +2232,7 @@ return {
command='substitute',
flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN),
addr_type=ADDR_LINES,
- func='do_sub',
+ func='ex_substitute',
},
{
command='sNext',
@@ -2282,8 +2320,8 @@ return {
},
{
command='scriptnames',
- flags=bit.bor(TRLBAR, CMDWIN),
- addr_type=ADDR_LINES,
+ flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR, CMDWIN),
+ addr_type=ADDR_OTHER,
func='ex_scriptnames',
},
{
@@ -2296,7 +2334,7 @@ return {
command='scscope',
flags=bit.bor(EXTRA, NOTRLCOM),
addr_type=ADDR_LINES,
- func='do_scscope',
+ func='ex_scscope',
},
{
command='set',
@@ -2619,12 +2657,12 @@ return {
{
command='tab',
flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_wrongmodifier',
},
{
command='tabclose',
- flags=bit.bor(RANGE, NOTADR, COUNT, BANG, TRLBAR, CMDWIN),
+ flags=bit.bor(BANG, RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN),
addr_type=ADDR_TABS,
func='ex_tabclose',
},
@@ -2649,7 +2687,7 @@ return {
{
command='tabfirst',
flags=bit.bor(TRLBAR),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
@@ -2661,13 +2699,13 @@ return {
{
command='tablast',
flags=bit.bor(TRLBAR),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
command='tabnext',
- flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
- addr_type=ADDR_LINES,
+ flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
+ addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
@@ -2678,32 +2716,32 @@ return {
},
{
command='tabonly',
- flags=bit.bor(BANG, RANGE, NOTADR, TRLBAR, CMDWIN),
+ flags=bit.bor(BANG, RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN),
addr_type=ADDR_TABS,
func='ex_tabonly',
},
{
command='tabprevious',
- flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
- addr_type=ADDR_LINES,
+ flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
+ addr_type=ADDR_TABS_RELATIVE,
func='ex_tabnext',
},
{
command='tabNext',
- flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR),
- addr_type=ADDR_LINES,
+ flags=bit.bor(RANGE, NOTADR, ZEROR, EXTRA, NOSPC, TRLBAR),
+ addr_type=ADDR_TABS_RELATIVE,
func='ex_tabnext',
},
{
command='tabrewind',
flags=bit.bor(TRLBAR),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_tabnext',
},
{
command='tabs',
flags=bit.bor(TRLBAR, CMDWIN),
- addr_type=ADDR_LINES,
+ addr_type=ADDR_TABS,
func='ex_tabs',
},
{
@@ -3032,13 +3070,13 @@ return {
},
{
command='wincmd',
- flags=bit.bor(NEEDARG, WORD1, RANGE, NOTADR),
+ flags=bit.bor(NEEDARG, WORD1, RANGE, NOTADR, CMDWIN),
addr_type=ADDR_WINDOWS,
func='ex_wincmd',
},
{
command='windo',
- flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL),
+ flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, RANGE, NOTADR, DFLALL),
addr_type=ADDR_WINDOWS,
func='ex_listdo',
},
@@ -3073,12 +3111,6 @@ return {
func='do_wqall',
},
{
- command='wsverb',
- flags=bit.bor(EXTRA, NOTADR, NEEDARG),
- addr_type=ADDR_LINES,
- func='ex_ni',
- },
- {
command='wshada',
flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
@@ -3181,7 +3213,7 @@ return {
enum='CMD_and',
flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY),
addr_type=ADDR_LINES,
- func='do_sub',
+ func='ex_substitute',
},
{
command='<',
@@ -3222,6 +3254,6 @@ return {
enum='CMD_tilde',
flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY),
addr_type=ADDR_LINES,
- func='do_sub',
+ func='ex_substitute',
},
}
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index b56b1cf013..0ecc389699 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.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
+
/// @file ex_cmds2.c
///
/// Some more functions for command line commands
@@ -27,7 +30,6 @@
#include "nvim/mbyte.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/memory.h"
#include "nvim/move.h"
@@ -121,7 +123,7 @@ void do_debug(char_u *cmd)
int save_msg_scroll = msg_scroll;
int save_State = State;
int save_did_emsg = did_emsg;
- int save_cmd_silent = cmd_silent;
+ const bool save_cmd_silent = cmd_silent;
int save_msg_silent = msg_silent;
int save_emsg_silent = emsg_silent;
int save_redir_off = redir_off;
@@ -187,7 +189,8 @@ void do_debug(char_u *cmd)
}
xfree(cmdline);
- cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL);
+ cmdline = (char_u *)getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL,
+ CALLBACK_NONE);
if (typeahead_saved) {
restore_typeahead(&typeaheadbuf);
@@ -897,6 +900,21 @@ void ex_pydo(exarg_T *eap)
script_host_do_range("python", eap);
}
+void ex_ruby(exarg_T *eap)
+{
+ script_host_execute("ruby", eap);
+}
+
+void ex_rubyfile(exarg_T *eap)
+{
+ script_host_execute_file("ruby", eap);
+}
+
+void ex_rubydo(exarg_T *eap)
+{
+ script_host_do_range("ruby", eap);
+}
+
void ex_python3(exarg_T *eap)
{
script_host_execute("python3", eap);
@@ -943,23 +961,21 @@ char_u *get_profile_name(expand_T *xp, int idx)
}
/// Handle command line completion for :profile command.
-void set_context_in_profile_cmd(expand_T *xp, char_u *arg)
+void set_context_in_profile_cmd(expand_T *xp, const char *arg)
{
- char_u *end_subcmd;
-
// Default: expand subcommands.
xp->xp_context = EXPAND_PROFILE;
pexpand_what = PEXP_SUBCMD;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
- end_subcmd = skiptowhite(arg);
+ char_u *const end_subcmd = skiptowhite((const char_u *)arg);
if (*end_subcmd == NUL) {
return;
}
- if (end_subcmd - arg == 5 && STRNCMP(arg, "start", 5) == 0) {
+ if ((const char *)end_subcmd - arg == 5 && strncmp(arg, "start", 5) == 0) {
xp->xp_context = EXPAND_FILES;
- xp->xp_pattern = skipwhite(end_subcmd);
+ xp->xp_pattern = skipwhite((const char_u *)end_subcmd);
return;
}
@@ -1023,9 +1039,14 @@ static void profile_reset(void)
uf->uf_tm_total = profile_zero();
uf->uf_tm_self = profile_zero();
uf->uf_tm_children = profile_zero();
+
+ xfree(uf->uf_tml_count);
+ xfree(uf->uf_tml_total);
+ xfree(uf->uf_tml_self);
uf->uf_tml_count = NULL;
uf->uf_tml_total = NULL;
uf->uf_tml_self = NULL;
+
uf->uf_tml_start = profile_zero();
uf->uf_tml_children = profile_zero();
uf->uf_tml_wait = profile_zero();
@@ -1052,7 +1073,7 @@ static void profile_init(scriptitem_T *si)
si->sn_pr_nest = 0;
}
-/// save time when starting to invoke another script or function.
+/// Save time when starting to invoke another script or function.
void script_prof_save(
proftime_T *tm // place to store wait time
)
@@ -1125,12 +1146,14 @@ static void script_dump_profile(FILE *fd)
if (sfd == NULL) {
fprintf(fd, "Cannot open file!\n");
} else {
- for (int i = 0; i < si->sn_prl_ga.ga_len; i++) {
+ // Keep going till the end of file, so that trailing
+ // continuation lines are listed.
+ for (int i = 0; ; i++) {
if (vim_fgets(IObuff, IOSIZE, sfd)) {
break;
}
- pp = &PRL_ITEM(si, i);
- if (pp->snp_count > 0) {
+ if (i < si->sn_prl_ga.ga_len
+ && (pp = &PRL_ITEM(si, i))->snp_count > 0) {
fprintf(fd, "%5d ", pp->snp_count);
if (profile_equal(pp->sn_prl_total, pp->sn_prl_self)) {
fprintf(fd, " ");
@@ -1167,6 +1190,7 @@ bool prof_def_func(void)
int autowrite(buf_T *buf, int forceit)
{
int r;
+ bufref_T bufref;
if (!(p_aw || p_awa) || !p_write
// never autowrite a "nofile" or "nowrite" buffer
@@ -1174,17 +1198,18 @@ int autowrite(buf_T *buf, int forceit)
|| (!forceit && buf->b_p_ro) || buf->b_ffname == NULL) {
return FAIL;
}
+ set_bufref(&bufref, buf);
r = buf_write_all(buf, forceit);
// Writing may succeed but the buffer still changed, e.g., when there is a
// conversion error. We do want to return FAIL then.
- if (buf_valid(buf) && bufIsChanged(buf)) {
+ if (bufref_valid(&bufref) && bufIsChanged(buf)) {
r = FAIL;
}
return r;
}
-/// flush all buffers, except the ones that are readonly
+/// Flush all buffers, except the ones that are readonly or are never written.
void autowrite_all(void)
{
if (!(p_aw || p_awa) || !p_write) {
@@ -1192,10 +1217,12 @@ void autowrite_all(void)
}
FOR_ALL_BUFFERS(buf) {
- if (bufIsChanged(buf) && !buf->b_p_ro) {
+ if (bufIsChanged(buf) && !buf->b_p_ro && !bt_dontwrite(buf)) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
(void)buf_write_all(buf, false);
// an autocommand may have deleted the buffer
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
buf = firstbuf;
}
}
@@ -1207,6 +1234,8 @@ void autowrite_all(void)
bool check_changed(buf_T *buf, int flags)
{
int forceit = (flags & CCGD_FORCEIT);
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
if (!forceit
&& bufIsChanged(buf)
@@ -1222,12 +1251,12 @@ bool check_changed(buf_T *buf, int flags)
}
}
}
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
// Autocommand deleted buffer, oops! It's not changed now.
return false;
}
dialog_changed(buf, count > 1);
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
// Autocommand deleted buffer, oops! It's not changed now.
return false;
}
@@ -1250,15 +1279,13 @@ bool check_changed(buf_T *buf, int flags)
///
/// @param buf
/// @param checkall may abandon all changed buffers
-void dialog_changed(buf_T *buf, int checkall)
+void dialog_changed(buf_T *buf, bool checkall)
{
char_u buff[DIALOG_MSG_SIZE];
int ret;
exarg_T ea;
- dialog_msg(buff, _("Save changes to \"%s\"?"),
- (buf->b_fname != NULL) ?
- buf->b_fname : (char_u *)_("Untitled"));
+ dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname);
if (checkall) {
ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
} else {
@@ -1286,9 +1313,10 @@ void dialog_changed(buf_T *buf, int checkall)
// Skip readonly buffers, these need to be confirmed
// individually.
FOR_ALL_BUFFERS(buf2) {
- if (bufIsChanged(buf2)
- && (buf2->b_ffname != NULL)
- && !buf2->b_p_ro) {
+ if (bufIsChanged(buf2) && (buf2->b_ffname != NULL) && !buf2->b_p_ro) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf2);
+
if (buf2->b_fname != NULL
&& check_overwrite(&ea, buf2, buf2->b_fname,
buf2->b_ffname, false) == OK) {
@@ -1296,7 +1324,7 @@ void dialog_changed(buf_T *buf, int checkall)
(void)buf_write_all(buf2, false);
}
// an autocommand may have deleted the buffer
- if (!buf_valid(buf2)) {
+ if (!bufref_valid(&bufref)) {
buf2 = firstbuf;
}
}
@@ -1309,11 +1337,27 @@ void dialog_changed(buf_T *buf, int checkall)
}
}
+/// Ask the user whether to close the terminal buffer or not.
+///
+/// @param buf The terminal buffer.
+/// @return bool Whether to close the buffer or not.
+bool dialog_close_terminal(buf_T *buf)
+{
+ char_u buff[DIALOG_MSG_SIZE];
+
+ dialog_msg(buff, _("Close \"%s\"?"),
+ (buf->b_fname != NULL) ? buf->b_fname : (char_u *)"?");
+
+ int ret = vim_dialog_yesnocancel(VIM_QUESTION, NULL, buff, 1);
+
+ return (ret == VIM_YES) ? true : false;
+}
+
/// Return true if the buffer "buf" can be abandoned, either by making it
/// hidden, autowriting it or unloading it.
bool can_abandon(buf_T *buf, int forceit)
{
- return P_HID(buf)
+ return buf_hide(buf)
|| !bufIsChanged(buf)
|| buf->b_nwindows > 1
|| autowrite(buf, forceit) == OK
@@ -1393,11 +1437,14 @@ bool check_changed_any(bool hidden, bool unload)
continue;
}
if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf)) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
// Try auto-writing the buffer. If this fails but the buffer no
// longer exists it's not changed, that's OK.
if (check_changed(buf, (p_awa ? CCGD_AW : 0)
| CCGD_MULTWIN
- | CCGD_ALLBUF) && buf_valid(buf)) {
+ | CCGD_ALLBUF) && bufref_valid(&bufref)) {
break; // didn't save - still changes
}
}
@@ -1433,9 +1480,11 @@ bool check_changed_any(bool hidden, bool unload)
if (buf != curbuf) {
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp->w_buffer == buf) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
goto_tabpage_win(tp, wp);
// Paranoia: did autocmds wipe out the buffer with changes?
- if (!buf_valid(buf)) {
+ if (!bufref_valid(&bufref)) {
goto theend;
}
goto buf_found;
@@ -1477,7 +1526,7 @@ int buf_write_all(buf_T *buf, int forceit)
(linenr_T)1, buf->b_ml.ml_line_count, NULL,
false, forceit, true, false));
if (curbuf != old_curbuf) {
- msg_source(hl_attr(HLF_W));
+ msg_source(HL_ATTR(HLF_W));
MSG(_("Warning: Entered other buffer unexpectedly (check autocommands)"));
}
return retval;
@@ -1523,12 +1572,17 @@ static char_u *do_one_arg(char_u *str)
/// Separate the arguments in "str" and return a list of pointers in the
/// growarray "gap".
-void get_arglist(garray_T *gap, char_u *str)
+static void get_arglist(garray_T *gap, char_u *str, int escaped)
{
ga_init(gap, (int)sizeof(char_u *), 20);
while (*str != NUL) {
GA_APPEND(char_u *, gap, str);
+ // If str is escaped, don't handle backslashes or spaces
+ if (!escaped) {
+ return;
+ }
+
// Isolate one argument, change it in-place, put a NUL after it.
str = do_one_arg(str);
}
@@ -1543,7 +1597,7 @@ int get_arglist_exp(char_u *str, int *fcountp, char_u ***fnamesp, bool wig)
garray_T ga;
int i;
- get_arglist(&ga, str);
+ get_arglist(&ga, str, true);
if (wig) {
i = expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
@@ -1574,6 +1628,7 @@ static int do_arglist(char_u *str, int what, int after)
char_u **exp_files;
char_u *p;
int match;
+ int arg_escaped = true;
// Set default argument for ":argadd" command.
if (what == AL_ADD && *str == NUL) {
@@ -1581,10 +1636,11 @@ static int do_arglist(char_u *str, int what, int after)
return FAIL;
}
str = curbuf->b_fname;
+ arg_escaped = false;
}
// Collect all file name arguments in "new_ga".
- get_arglist(&new_ga, str);
+ get_arglist(&new_ga, str, arg_escaped);
if (what == AL_DEL) {
regmatch_T regmatch;
@@ -1716,7 +1772,7 @@ void ex_args(exarg_T *eap)
}
}
- if (!ends_excmd(*eap->arg)) {
+ if (*eap->arg != NUL) {
// ":args file ..": define new argument list, handle like ":next"
// Also for ":argslocal file .." and ":argsglobal file ..".
ex_next(eap);
@@ -1818,12 +1874,12 @@ void do_argfile(exarg_T *eap, int argn)
// if 'hidden' set, only check for changed file when re-editing
// the same buffer
other = true;
- if (P_HID(curbuf)) {
+ if (buf_hide(curbuf)) {
p = (char_u *)fix_fname((char *)alist_name(&ARGLIST[argn]));
other = otherfile(p);
xfree(p);
}
- if ((!P_HID(curbuf) || !other)
+ if ((!buf_hide(curbuf) || !other)
&& check_changed(curbuf, CCGD_AW
| (other ? 0 : CCGD_MULTWIN)
| (eap->forceit ? CCGD_FORCEIT : 0)
@@ -1843,7 +1899,7 @@ void do_argfile(exarg_T *eap, int argn)
// argument index.
if (do_ecmd(0, alist_name(&ARGLIST[curwin->w_arg_idx]), NULL,
eap, ECMD_LAST,
- (P_HID(curwin->w_buffer) ? ECMD_HIDE : 0)
+ (buf_hide(curwin->w_buffer) ? ECMD_HIDE : 0)
+ (eap->forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) {
curwin->w_arg_idx = old_arg_idx;
} else if (eap->cmdidx != CMD_argdo) {
@@ -1860,7 +1916,7 @@ void ex_next(exarg_T *eap)
// check for changed buffer now, if this fails the argument list is not
// redefined.
- if (P_HID(curbuf)
+ if (buf_hide(curbuf)
|| eap->cmdidx == CMD_snext
|| !check_changed(curbuf, CCGD_AW
| (eap->forceit ? CCGD_FORCEIT : 0)
@@ -1880,31 +1936,21 @@ void ex_next(exarg_T *eap)
/// ":argedit"
void ex_argedit(exarg_T *eap)
{
- int fnum;
- int i;
- char_u *s;
+ int i = eap->addr_count ? (int)eap->line2 : curwin->w_arg_idx + 1;
- // Add the argument to the buffer list and get the buffer number.
- fnum = buflist_add(eap->arg, BLN_LISTED);
-
- // Check if this argument is already in the argument list.
- for (i = 0; i < ARGCOUNT; i++) {
- if (ARGLIST[i].ae_fnum == fnum) {
- break;
- }
- }
- if (i == ARGCOUNT) {
- // Can't find it, add it to the argument list.
- s = vim_strsave(eap->arg);
- int after = eap->addr_count > 0 ? (int)eap->line2 : curwin->w_arg_idx + 1;
- i = alist_add_list(1, &s, after);
- curwin->w_arg_idx = i;
+ if (do_arglist(eap->arg, AL_ADD, i) == FAIL) {
+ return;
}
+ maketitle();
- alist_check_arg_idx();
-
+ if (curwin->w_arg_idx == 0 && (curbuf->b_ml.ml_flags & ML_EMPTY)
+ && curbuf->b_ffname == NULL) {
+ i = 0;
+ }
// Edit the argument.
- do_argfile(eap, i);
+ if (i < ARGCOUNT) {
+ do_argfile(eap, i);
+ }
}
/// ":argadd"
@@ -1924,8 +1970,14 @@ void ex_argdelete(exarg_T *eap)
eap->line2 = ARGCOUNT;
}
linenr_T n = eap->line2 - eap->line1 + 1;
- if (*eap->arg != NUL || n <= 0) {
+ if (*eap->arg != NUL) {
+ // Can't have both a range and an argument.
EMSG(_(e_invarg));
+ } else if (n <= 0) {
+ // Don't give an error for ":%argdel" if the list is empty.
+ if (eap->line1 != 1 || eap->line2 != 0) {
+ EMSG(_(e_invrange));
+ }
} else {
for (linenr_T i = eap->line1; i <= eap->line2; i++) {
xfree(ARGLIST[i - 1].ae_fname);
@@ -1968,11 +2020,9 @@ void ex_listdo(exarg_T *eap)
save_ei = au_event_disable(",Syntax");
}
- start_global_changes();
-
if (eap->cmdidx == CMD_windo
|| eap->cmdidx == CMD_tabdo
- || P_HID(curbuf)
+ || buf_hide(curbuf)
|| !check_changed(curbuf, CCGD_AW
| (eap->forceit ? CCGD_FORCEIT : 0)
| CCGD_EXCMD)) {
@@ -2049,9 +2099,9 @@ void ex_listdo(exarg_T *eap)
// Clear 'shm' to avoid that the file message overwrites
// any output from the command.
p_shm_save = vim_strsave(p_shm);
- set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
+ set_option_value("shm", 0L, "", 0);
do_argfile(eap, i);
- set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+ set_option_value("shm", 0L, (char *)p_shm_save, 0);
xfree(p_shm_save);
}
if (curwin->w_arg_idx != i) {
@@ -2080,9 +2130,9 @@ void ex_listdo(exarg_T *eap)
// Remember the number of the next listed buffer, in case
// ":bwipe" is used or autocommands do something strange.
next_fnum = -1;
- for (buf_T *buf = curbuf->b_next; buf != NULL; buf = buf->b_next) {
- if (buf->b_p_bl) {
- next_fnum = buf->b_fnum;
+ for (buf_T *bp = curbuf->b_next; bp != NULL; bp = bp->b_next) {
+ if (bp->b_p_bl) {
+ next_fnum = bp->b_fnum;
break;
}
}
@@ -2114,9 +2164,9 @@ void ex_listdo(exarg_T *eap)
// Go to the next buffer. Clear 'shm' to avoid that the file
// message overwrites any output from the command.
p_shm_save = vim_strsave(p_shm);
- set_option_value((char_u *)"shm", 0L, (char_u *)"", 0);
+ set_option_value("shm", 0L, "", 0);
goto_buffer(eap, DOBUF_FIRST, FORWARD, next_fnum);
- set_option_value((char_u *)"shm", 0L, p_shm_save, 0);
+ set_option_value("shm", 0L, (char *)p_shm_save, 0);
xfree(p_shm_save);
// If autocommands took us elsewhere, quit here.
@@ -2166,7 +2216,6 @@ void ex_listdo(exarg_T *eap)
apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
curbuf->b_fname, true, curbuf);
}
- end_global_changes();
}
/// Add files[count] to the arglist of the current window after arg "after".
@@ -2203,6 +2252,15 @@ static int alist_add_list(int count, char_u **files, int after)
}
}
+// Function given to ExpandGeneric() to obtain the possible arguments of the
+// argedit and argdelete commands.
+char_u *get_arglist_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+{
+ if (idx >= ARGCOUNT) {
+ return NULL;
+ }
+ return alist_name(&ARGLIST[idx]);
+}
/// ":compiler[!] {name}"
void ex_compiler(exarg_T *eap)
@@ -2227,14 +2285,14 @@ void ex_compiler(exarg_T *eap)
// plugin will then skip the settings. Afterwards set
// "b:current_compiler" and restore "current_compiler".
// Explicitly prepend "g:" to make it work in a function.
- old_cur_comp = get_var_value((char_u *)"g:current_compiler");
+ old_cur_comp = get_var_value("g:current_compiler");
if (old_cur_comp != NULL) {
old_cur_comp = vim_strsave(old_cur_comp);
}
do_cmdline_cmd("command -nargs=* CompilerSet setlocal <args>");
}
- do_unlet((char_u *)"g:current_compiler", true);
- do_unlet((char_u *)"b:current_compiler", true);
+ do_unlet(S_LEN("g:current_compiler"), true);
+ do_unlet(S_LEN("b:current_compiler"), true);
snprintf((char *)buf, bufsize, "compiler/%s.vim", eap->arg);
if (source_runtime(buf, DIP_ALL) == FAIL) {
@@ -2245,7 +2303,7 @@ void ex_compiler(exarg_T *eap)
do_cmdline_cmd(":delcommand CompilerSet");
// Set "b:current_compiler" from "current_compiler".
- p = get_var_value((char_u *)"g:current_compiler");
+ p = get_var_value("g:current_compiler");
if (p != NULL) {
set_internal_string_var((char_u *)"b:current_compiler", p);
}
@@ -2257,7 +2315,7 @@ void ex_compiler(exarg_T *eap)
old_cur_comp);
xfree(old_cur_comp);
} else {
- do_unlet((char_u *)"g:current_compiler", true);
+ do_unlet(S_LEN("g:current_compiler"), true);
}
}
}
@@ -2294,16 +2352,6 @@ static void source_callback(char_u *fname, void *cookie)
(void)do_source(fname, false, DOSO_NONE);
}
-/// Source the file "name" from all directories in 'runtimepath'.
-/// "name" can contain wildcards.
-/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
-///
-/// return FAIL when no file could be sourced, OK otherwise.
-int source_runtime(char_u *name, int flags)
-{
- return do_in_runtimepath(name, flags, source_callback, NULL);
-}
-
/// Find the file "name" in all directories in "path" and invoke
/// "callback(fname, cookie)".
/// "name" can contain wildcards.
@@ -2338,12 +2386,25 @@ int do_in_path(char_u *path, char_u *name, int flags,
while (*rtp != NUL && ((flags & DIP_ALL) || !did_one)) {
// Copy the path from 'runtimepath' to buf[].
copy_option_part(&rtp, buf, MAXPATHL, ",");
+ size_t buflen = STRLEN(buf);
+
+ // Skip after or non-after directories.
+ if (flags & (DIP_NOAFTER | DIP_AFTER)) {
+ bool is_after = buflen >= 5
+ && STRCMP(buf + buflen - 5, "after") == 0;
+
+ if ((is_after && (flags & DIP_NOAFTER))
+ || (!is_after && (flags & DIP_AFTER))) {
+ continue;
+ }
+ }
+
if (name == NULL) {
(*callback)(buf, (void *)&cookie);
if (!did_one) {
did_one = (cookie == NULL);
}
- } else if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL) {
+ } else if (buflen + STRLEN(name) + 2 < MAXPATHL) {
add_pathsep((char *)buf);
tail = buf + STRLEN(buf);
@@ -2396,21 +2457,21 @@ int do_in_path(char_u *path, char_u *name, int flags,
return did_one ? OK : FAIL;
}
-/// Find "name" in 'runtimepath'. When found, invoke the callback function for
+/// Find "name" in "path". When found, invoke the callback function for
/// it: callback(fname, "cookie")
/// When "flags" has DIP_ALL repeat for all matches, otherwise only the first
/// one is used.
/// Returns OK when at least one match found, FAIL otherwise.
-/// If "name" is NULL calls callback for each entry in runtimepath. Cookie is
+/// If "name" is NULL calls callback for each entry in "path". Cookie is
/// passed by reference in this case, setting it to NULL indicates that callback
/// has done its job.
-int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
- void *cookie)
+int do_in_path_and_pp(char_u *path, char_u *name, int flags,
+ DoInRuntimepathCB callback, void *cookie)
{
int done = FAIL;
if ((flags & DIP_NORTP) == 0) {
- done = do_in_path(p_rtp, name, flags, callback, cookie);
+ done = do_in_path(path, name, flags, callback, cookie);
}
if ((done == FAIL || (flags & DIP_ALL)) && (flags & DIP_START)) {
@@ -2438,6 +2499,29 @@ int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
return done;
}
+/// Just like do_in_path_and_pp(), using 'runtimepath' for "path".
+int do_in_runtimepath(char_u *name, int flags, DoInRuntimepathCB callback,
+ void *cookie)
+{
+ return do_in_path_and_pp(p_rtp, name, flags, callback, cookie);
+}
+
+/// Source the file "name" from all directories in 'runtimepath'.
+/// "name" can contain wildcards.
+/// When "flags" has DIP_ALL: source all files, otherwise only the first one.
+///
+/// return FAIL when no file could be sourced, OK otherwise.
+int source_runtime(char_u *name, int flags)
+{
+ return source_in_path(p_rtp, name, flags);
+}
+
+/// Just like source_runtime(), but use "path" instead of 'runtimepath'.
+int source_in_path(char_u *path, char_u *name, int flags)
+{
+ return do_in_path_and_pp(path, name, flags, source_callback, NULL);
+}
+
// Expand wildcards in "pat" and invoke do_source() for each match.
static void source_all_matches(char_u *pat)
{
@@ -2452,162 +2536,399 @@ static void source_all_matches(char_u *pat)
}
}
-// used for "cookie" of add_pack_plugin()
-static int APP_ADD_DIR;
-static int APP_LOAD;
-static int APP_BOTH;
-
-static void add_pack_plugin(char_u *fname, void *cookie)
+/// Add the package directory to 'runtimepath'
+static int add_pack_dir_to_rtp(char_u *fname)
{
char_u *p4, *p3, *p2, *p1, *p;
- char_u *new_rtp;
- char_u *ffname = (char_u *)fix_fname((char *)fname);
+ char_u *buf = NULL;
+ char *afterdir = NULL;
+ int retval = FAIL;
- if (ffname == NULL) {
- return;
+ p4 = p3 = p2 = p1 = get_past_head(fname);
+ for (p = p1; *p; MB_PTR_ADV(p)) {
+ if (vim_ispathsep_nocolon(*p)) {
+ p4 = p3; p3 = p2; p2 = p1; p1 = p;
+ }
}
- if (cookie != &APP_LOAD && strstr((char *)p_rtp, (char *)ffname) == NULL) {
- // directory is not yet in 'runtimepath', add it
- p4 = p3 = p2 = p1 = get_past_head(ffname);
- for (p = p1; *p; mb_ptr_adv(p)) {
- if (vim_ispathsep_nocolon(*p)) {
- p4 = p3; p3 = p2; p2 = p1; p1 = p;
- }
- }
+ // now we have:
+ // rtp/pack/name/start/name
+ // p4 p3 p2 p1
+ //
+ // find the part up to "pack" in 'runtimepath'
+ p4++; // append pathsep in order to expand symlink
+ char_u c = *p4;
+ *p4 = NUL;
+ char *const ffname = fix_fname((char *)fname);
+ *p4 = c;
- // now we have:
- // rtp/pack/name/start/name
- // p4 p3 p2 p1
- //
- // find the part up to "pack" in 'runtimepath'
- char_u c = *p4;
- *p4 = NUL;
+ if (ffname == NULL) {
+ return FAIL;
+ }
- // Find "ffname" in "p_rtp", ignoring '/' vs '\' differences
- size_t fname_len = STRLEN(ffname);
- char_u *insp = p_rtp;
- for (;;) {
- if (vim_fnamencmp(insp, ffname, fname_len) == 0) {
- break;
+ // Find "ffname" in "p_rtp", ignoring '/' vs '\' differences
+ // Also stop at the first "after" directory
+ size_t fname_len = strlen(ffname);
+ buf = try_malloc(MAXPATHL);
+ if (buf == NULL) {
+ goto theend;
+ }
+ const char *insp = NULL;
+ const char *after_insp = NULL;
+ for (const char *entry = (const char *)p_rtp; *entry != NUL; ) {
+ const char *cur_entry = entry;
+
+ copy_option_part((char_u **)&entry, buf, MAXPATHL, ",");
+ if (insp == NULL) {
+ add_pathsep((char *)buf);
+ char *const rtp_ffname = fix_fname((char *)buf);
+ if (rtp_ffname == NULL) {
+ goto theend;
}
- insp = vim_strchr(insp, ',');
- if (insp == NULL) {
- break;
+ bool match = path_fnamencmp(rtp_ffname, ffname, fname_len) == 0;
+ xfree(rtp_ffname);
+ if (match) {
+ // Insert "ffname" after this entry (and comma).
+ insp = entry;
}
- insp++;
}
- if (insp == NULL) {
- // not found, append at the end
- insp = p_rtp + STRLEN(p_rtp);
- } else {
- // append after the matching directory.
- insp += STRLEN(ffname);
- while (*insp != NUL && *insp != ',') {
- insp++;
+ if ((p = (char_u *)strstr((char *)buf, "after")) != NULL
+ && p > buf
+ && vim_ispathsep(p[-1])
+ && (vim_ispathsep(p[5]) || p[5] == NUL || p[5] == ',')) {
+ if (insp == NULL) {
+ // Did not find "ffname" before the first "after" directory,
+ // insert it before this entry.
+ insp = cur_entry;
}
+ after_insp = cur_entry;
+ break;
}
- *p4 = c;
+ }
- // check if rtp/pack/name/start/name/after exists
- char *afterdir = concat_fnames((char *)ffname, "after", true);
- size_t afterlen = 0;
- if (os_isdir((char_u *)afterdir)) {
- afterlen = STRLEN(afterdir) + 1; // add one for comma
- }
+ if (insp == NULL) {
+ // Both "fname" and "after" not found, append at the end.
+ insp = (const char *)p_rtp + STRLEN(p_rtp);
+ }
- size_t oldlen = STRLEN(p_rtp);
- size_t addlen = STRLEN(ffname) + 1; // add one for comma
- new_rtp = try_malloc(oldlen + addlen + afterlen + 1); // add one for NUL
- if (new_rtp == NULL) {
- goto theend;
- }
- uintptr_t keep = (uintptr_t)(insp - p_rtp);
- memmove(new_rtp, p_rtp, keep);
- new_rtp[keep] = ',';
- memmove(new_rtp + keep + 1, ffname, addlen);
- if (p_rtp[keep] != NUL) {
- memmove(new_rtp + keep + addlen, p_rtp + keep,
- oldlen - keep + 1);
- }
- if (afterlen > 0) {
- STRCAT(new_rtp, ",");
- STRCAT(new_rtp, afterdir);
- }
- set_option_value((char_u *)"rtp", 0L, new_rtp, 0);
- xfree(new_rtp);
- xfree(afterdir);
+ // check if rtp/pack/name/start/name/after exists
+ afterdir = concat_fnames((char *)fname, "after", true);
+ size_t afterlen = 0;
+ if (os_isdir((char_u *)afterdir)) {
+ afterlen = strlen(afterdir) + 1; // add one for comma
}
- if (cookie != &APP_ADD_DIR) {
- static const char *plugpat = "%s/plugin/*.vim"; // NOLINT
- static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT
+ const size_t oldlen = STRLEN(p_rtp);
+ const size_t addlen = STRLEN(fname) + 1; // add one for comma
+ const size_t new_rtp_capacity = oldlen + addlen + afterlen + 1;
+ // add one for NUL ------------------------------------------^
+ char *const new_rtp = try_malloc(new_rtp_capacity);
+ if (new_rtp == NULL) {
+ goto theend;
+ }
- size_t len = STRLEN(ffname) + STRLEN(ftpat);
- char_u *pat = try_malloc(len + 1);
- if (pat == NULL) {
- goto theend;
- }
- vim_snprintf((char *)pat, len, plugpat, ffname);
- source_all_matches(pat);
+ // We now have 'rtp' parts: {keep}{keep_after}{rest}.
+ // Create new_rtp, first: {keep},{fname}
+ size_t keep = (size_t)(insp - (const char *)p_rtp);
+ memmove(new_rtp, p_rtp, keep);
+ size_t new_rtp_len = keep;
+ if (*insp == NUL) {
+ new_rtp[new_rtp_len++] = ','; // add comma before
+ }
+ memmove(new_rtp + new_rtp_len, fname, addlen - 1);
+ new_rtp_len += addlen - 1;
+ if (*insp != NUL) {
+ new_rtp[new_rtp_len++] = ','; // add comma after
+ }
- char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes");
+ if (afterlen > 0 && after_insp != NULL) {
+ size_t keep_after = (size_t)(after_insp - (const char *)p_rtp);
- // If runtime/filetype.vim wasn't loaded yet, the scripts will be
- // found when it loads.
- if (eval_to_number(cmd) > 0) {
- do_cmdline_cmd("augroup filetypedetect");
- vim_snprintf((char *)pat, len, ftpat, ffname);
- source_all_matches(pat);
- do_cmdline_cmd("augroup END");
- }
- xfree(cmd);
- xfree(pat);
+ // Add to new_rtp: {keep},{fname}{keep_after},{afterdir}
+ memmove(new_rtp + new_rtp_len, p_rtp + keep, keep_after - keep);
+ new_rtp_len += keep_after - keep;
+ memmove(new_rtp + new_rtp_len, afterdir, afterlen - 1);
+ new_rtp_len += afterlen - 1;
+ new_rtp[new_rtp_len++] = ',';
+ keep = keep_after;
+ }
+
+ if (p_rtp[keep] != NUL) {
+ // Append rest: {keep},{fname}{keep_after},{afterdir}{rest}
+ memmove(new_rtp + new_rtp_len, p_rtp + keep, oldlen - keep + 1);
+ } else {
+ new_rtp[new_rtp_len] = NUL;
+ }
+
+ if (afterlen > 0 && after_insp == NULL) {
+ // Append afterdir when "after" was not found:
+ // {keep},{fname}{rest},{afterdir}
+ xstrlcat(new_rtp, ",", new_rtp_capacity);
+ xstrlcat(new_rtp, afterdir, new_rtp_capacity);
+ }
+
+ set_option_value("rtp", 0L, new_rtp, 0);
+ xfree(new_rtp);
+ retval = OK;
+
+theend:
+ xfree(buf);
+ xfree(ffname);
+ xfree(afterdir);
+ return retval;
+}
+
+/// Load scripts in "plugin" and "ftdetect" directories of the package.
+static int load_pack_plugin(char_u *fname)
+{
+ static const char *plugpat = "%s/plugin/**/*.vim"; // NOLINT
+ static const char *ftpat = "%s/ftdetect/*.vim"; // NOLINT
+
+ int retval = FAIL;
+ char *const ffname = fix_fname((char *)fname);
+ size_t len = strlen(ffname) + STRLEN(ftpat);
+ char_u *pat = try_malloc(len + 1);
+ if (pat == NULL) {
+ goto theend;
}
+ vim_snprintf((char *)pat, len, plugpat, ffname);
+ source_all_matches(pat);
+
+ char_u *cmd = vim_strsave((char_u *)"g:did_load_filetypes");
+
+ // If runtime/filetype.vim wasn't loaded yet, the scripts will be
+ // found when it loads.
+ if (eval_to_number(cmd) > 0) {
+ do_cmdline_cmd("augroup filetypedetect");
+ vim_snprintf((char *)pat, len, ftpat, ffname);
+ source_all_matches(pat);
+ do_cmdline_cmd("augroup END");
+ }
+ xfree(cmd);
+ xfree(pat);
+ retval = OK;
theend:
xfree(ffname);
+
+ return retval;
+}
+
+// used for "cookie" of add_pack_plugin()
+static int APP_ADD_DIR;
+static int APP_LOAD;
+static int APP_BOTH;
+
+static void add_pack_plugin(char_u *fname, void *cookie)
+{
+ if (cookie != &APP_LOAD) {
+ char *buf = xmalloc(MAXPATHL);
+ bool found = false;
+
+ const char *p = (const char *)p_rtp;
+ while (*p != NUL) {
+ copy_option_part((char_u **)&p, (char_u *)buf, MAXPATHL, ",");
+ if (path_fnamecmp(buf, (char *)fname) == 0) {
+ found = true;
+ break;
+ }
+ }
+ xfree(buf);
+ if (!found) {
+ // directory is not yet in 'runtimepath', add it
+ if (add_pack_dir_to_rtp(fname) == FAIL) {
+ return;
+ }
+ }
+ }
+
+ if (cookie != &APP_ADD_DIR) {
+ load_pack_plugin(fname);
+ }
+}
+
+/// Add all packages in the "start" directory to 'runtimepath'.
+void add_pack_start_dirs(void)
+{
+ do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
+ add_pack_plugin, &APP_ADD_DIR);
}
-static bool did_source_packages = false;
+/// Load plugins from all packages in the "start" directory.
+void load_start_packages(void)
+{
+ did_source_packages = true;
+ do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
+ add_pack_plugin, &APP_LOAD);
+}
// ":packloadall"
// Find plugins in the package directories and source them.
void ex_packloadall(exarg_T *eap)
{
- if (!did_source_packages || (eap != NULL && eap->forceit)) {
- did_source_packages = true;
-
+ if (!did_source_packages || eap->forceit) {
// First do a round to add all directories to 'runtimepath', then load
// the plugins. This allows for plugins to use an autoload directory
// of another plugin.
- do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_ADD_DIR);
- do_in_path(p_pp, (char_u *)"pack/*/start/*", DIP_ALL + DIP_DIR, // NOLINT
- add_pack_plugin, &APP_LOAD);
+ add_pack_start_dirs();
+ load_start_packages();
}
}
/// ":packadd[!] {name}"
void ex_packadd(exarg_T *eap)
{
- static const char *plugpat = "pack/*/opt/%s"; // NOLINT
+ static const char *plugpat = "pack/*/%s/%s"; // NOLINT
+ int res = OK;
- size_t len = STRLEN(plugpat) + STRLEN(eap->arg);
- char *pat = (char *)xmallocz(len);
- vim_snprintf(pat, len, plugpat, eap->arg);
- do_in_path(p_pp, (char_u *)pat, DIP_ALL + DIP_DIR + DIP_ERR, add_pack_plugin,
- eap->forceit ? &APP_ADD_DIR : &APP_BOTH);
- xfree(pat);
+ // Round 1: use "start", round 2: use "opt".
+ for (int round = 1; round <= 2; round++) {
+ // Only look under "start" when loading packages wasn't done yet.
+ if (round == 1 && did_source_packages) {
+ continue;
+ }
+
+ const size_t len = STRLEN(plugpat) + STRLEN(eap->arg) + 5;
+ char *pat = xmallocz(len);
+ vim_snprintf(pat, len, plugpat, round == 1 ? "start" : "opt", eap->arg);
+ // The first round don't give a "not found" error, in the second round
+ // only when nothing was found in the first round.
+ res = do_in_path(p_pp, (char_u *)pat,
+ DIP_ALL + DIP_DIR
+ + (round == 2 && res == FAIL ? DIP_ERR : 0),
+ add_pack_plugin, eap->forceit ? &APP_ADD_DIR : &APP_BOTH);
+ xfree(pat);
+ }
}
/// ":options"
void ex_options(exarg_T *eap)
{
+ vim_setenv("OPTWIN_CMD", cmdmod.tab ? "tab" : "");
cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
}
+// Detect Python 3 or 2, and initialize 'pyxversion'.
+void init_pyxversion(void)
+{
+ if (p_pyx == 0) {
+ if (!eval_has_provider("python3")) {
+ p_pyx = 3;
+ } else if (!eval_has_provider("python")) {
+ p_pyx = 2;
+ }
+ }
+}
+
+// Does a file contain one of the following strings at the beginning of any
+// line?
+// "#!(any string)python2" => returns 2
+// "#!(any string)python3" => returns 3
+// "# requires python 2.x" => returns 2
+// "# requires python 3.x" => returns 3
+// otherwise return 0.
+static int requires_py_version(char_u *filename)
+{
+ FILE *file;
+ int requires_py_version = 0;
+ int i, lines;
+
+ lines = (int)p_mls;
+ if (lines < 0) {
+ lines = 5;
+ }
+
+ file = mch_fopen((char *)filename, "r");
+ if (file != NULL) {
+ for (i = 0; i < lines; i++) {
+ if (vim_fgets(IObuff, IOSIZE, file)) {
+ break;
+ }
+ if (i == 0 && IObuff[0] == '#' && IObuff[1] == '!') {
+ // Check shebang.
+ if (strstr((char *)IObuff + 2, "python2") != NULL) {
+ requires_py_version = 2;
+ break;
+ }
+ if (strstr((char *)IObuff + 2, "python3") != NULL) {
+ requires_py_version = 3;
+ break;
+ }
+ }
+ IObuff[21] = '\0';
+ if (STRCMP("# requires python 2.x", IObuff) == 0) {
+ requires_py_version = 2;
+ break;
+ }
+ if (STRCMP("# requires python 3.x", IObuff) == 0) {
+ requires_py_version = 3;
+ break;
+ }
+ }
+ fclose(file);
+ }
+ return requires_py_version;
+}
+
+
+// Source a python file using the requested python version.
+static void source_pyx_file(exarg_T *eap, char_u *fname)
+{
+ exarg_T ex;
+ long int v = requires_py_version(fname);
+
+ init_pyxversion();
+ if (v == 0) {
+ // user didn't choose a preference, 'pyx' is used
+ v = p_pyx;
+ }
+
+ // now source, if required python version is not supported show
+ // unobtrusive message.
+ if (eap == NULL) {
+ memset(&ex, 0, sizeof(ex));
+ } else {
+ ex = *eap;
+ }
+ ex.arg = fname;
+ ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3");
+
+ if (v == 2) {
+ ex_pyfile(&ex);
+ } else {
+ ex_py3file(&ex);
+ }
+}
+
+// ":pyxfile {fname}"
+void ex_pyxfile(exarg_T *eap)
+{
+ source_pyx_file(eap, eap->arg);
+}
+
+// ":pyx"
+void ex_pyx(exarg_T *eap)
+{
+ init_pyxversion();
+ if (p_pyx == 2) {
+ ex_python(eap);
+ } else {
+ ex_python3(eap);
+ }
+}
+
+// ":pyxdo"
+void ex_pyxdo(exarg_T *eap)
+{
+ init_pyxversion();
+ if (p_pyx == 2) {
+ ex_pydo(eap);
+ } else {
+ ex_pydo3(eap);
+ }
+}
+
/// ":source {fname}"
void ex_source(exarg_T *eap)
{
@@ -2669,14 +2990,7 @@ static FILE *fopen_noinh_readbin(char *filename)
return NULL;
}
-#ifdef HAVE_FD_CLOEXEC
- {
- int fdflags = fcntl(fd_tmp, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
- (void)fcntl(fd_tmp, F_SETFD, fdflags | FD_CLOEXEC);
- }
- }
-#endif
+ (void)os_set_cloexec(fd_tmp);
return fdopen(fd_tmp, READBIN);
}
@@ -2803,22 +3117,6 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 0;
- cookie.conv.vc_type = CONV_NONE; // no conversion
-
- // Read the first line so we can check for a UTF-8 BOM.
- firstline = getsourceline(0, (void *)&cookie, 0);
- if (firstline != NULL && STRLEN(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, (char_u *)"utf-8", p_enc);
- p = string_convert(&cookie.conv, firstline + 3, NULL);
- if (p == NULL) {
- p = vim_strsave(firstline + 3);
- }
- xfree(firstline);
- firstline = p;
- }
-
// start measuring script load time if --startuptime was passed and
// time_fd was successfully opened afterwards.
proftime_T rel_time;
@@ -2891,6 +3189,22 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
}
}
+ cookie.conv.vc_type = CONV_NONE; // no conversion
+
+ // Read the first line so we can check for a UTF-8 BOM.
+ firstline = getsourceline(0, (void *)&cookie, 0);
+ if (firstline != NULL && STRLEN(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, (char_u *)"utf-8", p_enc);
+ p = string_convert(&cookie.conv, firstline + 3, NULL);
+ if (p == NULL) {
+ p = vim_strsave(firstline + 3);
+ }
+ xfree(firstline);
+ firstline = p;
+ }
+
// Call do_cmdline, which will call getsourceline() to get the lines.
do_cmdline(firstline, getsourceline, (void *)&cookie,
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
@@ -2954,6 +3268,17 @@ theend:
/// ":scriptnames"
void ex_scriptnames(exarg_T *eap)
{
+ if (eap->addr_count > 0) {
+ // :script {scriptId}: edit the script
+ if (eap->line2 < 1 || eap->line2 > script_items.ga_len) {
+ EMSG(_(e_invarg));
+ } else {
+ eap->arg = SCRIPT_ITEM(eap->line2).sn_name;
+ do_exedit(eap, NULL);
+ }
+ return;
+ }
+
for (int i = 1; i <= script_items.ga_len && !got_int; i++) {
if (SCRIPT_ITEM(i).sn_name != NULL) {
home_replace(NULL, SCRIPT_ITEM(i).sn_name,
@@ -2977,29 +3302,39 @@ void scriptnames_slash_adjust(void)
# endif
/// Get a pointer to a script name. Used for ":verbose set".
-char_u *get_scriptname(scid_T id)
+char_u *get_scriptname(LastSet last_set, bool *should_free)
{
- if (id == SID_MODELINE) {
- return (char_u *)_("modeline");
- }
- if (id == SID_CMDARG) {
- return (char_u *)_("--cmd argument");
- }
- if (id == SID_CARG) {
- return (char_u *)_("-c argument");
- }
- if (id == SID_ENV) {
- return (char_u *)_("environment variable");
- }
- if (id == SID_ERROR) {
- return (char_u *)_("error handler");
+ *should_free = false;
+
+ switch (last_set.script_id) {
+ case SID_MODELINE:
+ return (char_u *)_("modeline");
+ case SID_CMDARG:
+ return (char_u *)_("--cmd argument");
+ case SID_CARG:
+ return (char_u *)_("-c argument");
+ case SID_ENV:
+ return (char_u *)_("environment variable");
+ case SID_ERROR:
+ return (char_u *)_("error handler");
+ case SID_LUA:
+ return (char_u *)_("Lua");
+ case SID_API_CLIENT:
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("API client (channel id %" PRIu64 ")"),
+ last_set.channel_id);
+ return IObuff;
+ default:
+ *should_free = true;
+ return home_replace_save(NULL, SCRIPT_ITEM(last_set.script_id).sn_name);
}
- return SCRIPT_ITEM(id).sn_name;
}
# if defined(EXITFREE)
void free_scriptnames(void)
{
+ profile_reset();
+
# define FREE_SCRIPTNAME(item) xfree((item)->sn_name)
GA_DEEP_CLEAR(&script_items, scriptitem_T, FREE_SCRIPTNAME);
}
@@ -3122,8 +3457,14 @@ static char_u *get_one_sourceline(struct source_cookie *sp)
ga_grow(&ga, 120);
buf = (char_u *)ga.ga_data;
+retry:
+ errno = 0;
if (fgets((char *)buf + ga.ga_len, ga.ga_maxlen - ga.ga_len,
sp->fp) == NULL) {
+ if (errno == EINTR) {
+ goto retry;
+ }
+
break;
}
len = ga.ga_len + (int)STRLEN(buf + ga.ga_len);
@@ -3164,7 +3505,7 @@ static char_u *get_one_sourceline(struct source_cookie *sp)
ga.ga_len--;
} else { // lines like ":map xx yy^M" will have failed
if (!sp->error) {
- msg_source(hl_attr(HLF_W));
+ msg_source(HL_ATTR(HLF_W));
EMSG(_("W15: Warning: Wrong line separator, ^M may be missing"));
}
sp->error = true;
@@ -3213,7 +3554,8 @@ void script_line_start(void)
if (si->sn_prof_on && sourcing_lnum >= 1) {
// Grow the array before starting the timer, so that the time spent
// here isn't counted.
- ga_grow(&si->sn_prl_ga, (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
+ (void)ga_grow(&si->sn_prl_ga,
+ (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
si->sn_prl_idx = sourcing_lnum - 1;
while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen) {
@@ -3374,7 +3716,12 @@ static char *get_locale_val(int what)
}
#endif
-
+// Return true when "lang" starts with a valid language name.
+// Rejects NULL, empty string, "C", "C.UTF-8" and others.
+static bool is_valid_mess_lang(char *lang)
+{
+ return lang != NULL && ASCII_ISALPHA(lang[0]) && ASCII_ISALPHA(lang[1]);
+}
/// Obtain the current messages language. Used to set the default for
/// 'helplang'. May return NULL or an empty string.
@@ -3394,14 +3741,14 @@ char *get_mess_lang(void)
# endif
# else
p = os_getenv("LC_ALL");
- if (p == NULL) {
+ if (!is_valid_mess_lang(p)) {
p = os_getenv("LC_MESSAGES");
- if (p == NULL) {
+ if (!is_valid_mess_lang(p)) {
p = os_getenv("LANG");
}
}
# endif
- return p;
+ return is_valid_mess_lang(p) ? p : NULL;
}
// Complicated #if; matches with where get_mess_env() is used below.
@@ -3570,18 +3917,11 @@ void ex_language(exarg_T *eap)
static char_u **locales = NULL; // Array of all available locales
-static bool did_init_locales = false;
-/// Lazy initialization of all available locales.
-static void init_locales(void)
-{
- if (!did_init_locales) {
- did_init_locales = true;
- locales = find_locales();
- }
-}
+#ifndef WIN32
+static bool did_init_locales = false;
-// Return an array of strings for all available locales + NULL for the
+/// Return an array of strings for all available locales + NULL for the
/// last element. Return NULL in case of error.
static char_u **find_locales(void)
{
@@ -3613,6 +3953,18 @@ static char_u **find_locales(void)
((char_u **)locales_ga.ga_data)[locales_ga.ga_len] = NULL;
return (char_u **)locales_ga.ga_data;
}
+#endif
+
+/// Lazy initialization of all available locales.
+static void init_locales(void)
+{
+#ifndef WIN32
+ if (!did_init_locales) {
+ did_init_locales = true;
+ locales = find_locales();
+ }
+#endif
+}
# if defined(EXITFREE)
void free_locales(void)
@@ -3665,19 +4017,19 @@ char_u *get_locales(expand_T *xp, int idx)
static void script_host_execute(char *name, exarg_T *eap)
{
- uint8_t *script = script_get(eap, eap->arg);
+ size_t len;
+ char *const script = script_get(eap, &len);
- if (!eap->skip) {
- list_T *args = list_alloc();
+ if (script != NULL) {
+ list_T *const args = tv_list_alloc(3);
// script
- list_append_string(args, script ? script : eap->arg, -1);
+ tv_list_append_allocated_string(args, script);
// current range
- list_append_number(args, (int)eap->line1);
- list_append_number(args, (int)eap->line2);
+ tv_list_append_number(args, (int)eap->line1);
+ tv_list_append_number(args, (int)eap->line2);
+
(void)eval_call_provider(name, "execute", args);
}
-
- xfree(script);
}
static void script_host_execute_file(char *name, exarg_T *eap)
@@ -3685,21 +4037,21 @@ static void script_host_execute_file(char *name, exarg_T *eap)
uint8_t buffer[MAXPATHL];
vim_FullName((char *)eap->arg, (char *)buffer, sizeof(buffer), false);
- list_T *args = list_alloc();
+ list_T *args = tv_list_alloc(3);
// filename
- list_append_string(args, buffer, -1);
+ tv_list_append_string(args, (const char *)buffer, -1);
// current range
- list_append_number(args, (int)eap->line1);
- list_append_number(args, (int)eap->line2);
+ tv_list_append_number(args, (int)eap->line1);
+ tv_list_append_number(args, (int)eap->line2);
(void)eval_call_provider(name, "execute_file", args);
}
static void script_host_do_range(char *name, exarg_T *eap)
{
- list_T *args = list_alloc();
- list_append_number(args, (int)eap->line1);
- list_append_number(args, (int)eap->line2);
- list_append_string(args, eap->arg, -1);
+ list_T *args = tv_list_alloc(3);
+ tv_list_append_number(args, (int)eap->line1);
+ tv_list_append_number(args, (int)eap->line2);
+ tv_list_append_string(args, (const char *)eap->arg, -1);
(void)eval_call_provider(name, "do_range", args);
}
@@ -3749,7 +4101,7 @@ void ex_drop(exarg_T *eap)
// to split the current window or data could be lost.
// Skip the check if the 'hidden' option is set, as in this case the
// buffer won't be lost.
- if (!P_HID(curbuf)) {
+ if (!buf_hide(curbuf)) {
emsg_off++;
split = check_changed(curbuf, CCGD_AW | CCGD_EXCMD);
emsg_off--;
diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h
index f46d1e6d47..6c36922c09 100644
--- a/src/nvim/ex_cmds_defs.h
+++ b/src/nvim/ex_cmds_defs.h
@@ -6,6 +6,7 @@
#include "nvim/pos.h" // for linenr_T
#include "nvim/normal.h"
+#include "nvim/regexp_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_cmds_enum.generated.h"
@@ -58,7 +59,9 @@
#define BUFUNL 0x20000 /* accepts unlisted buffer too */
#define ARGOPT 0x40000 /* allow "++opt=val" argument */
#define SBOXOK 0x80000 /* allowed in the sandbox */
-#define CMDWIN 0x100000 /* allowed in cmdline window */
+#define CMDWIN 0x100000 /* allowed in cmdline window; when missing
+ * disallows editing another buffer when
+ * curbuf_lock is set */
#define MODIFY 0x200000 /* forbidden in non-'modifiable' buffer */
#define EXFLAGS 0x400000 /* allow flags after count in argument */
#define FILES (XFILE | EXTRA) /* multiple extra files allowed */
@@ -72,7 +75,9 @@
#define ADDR_LOADED_BUFFERS 3
#define ADDR_BUFFERS 4
#define ADDR_TABS 5
-#define ADDR_QUICKFIX 6
+#define ADDR_TABS_RELATIVE 6 // Tab page that only relative
+#define ADDR_QUICKFIX 7
+#define ADDR_OTHER 99
typedef struct exarg exarg_T;
@@ -126,57 +131,55 @@ struct exarg {
struct condstack *cstack; ///< condition stack for ":if" etc.
};
-#define FORCE_BIN 1 /* ":edit ++bin file" */
-#define FORCE_NOBIN 2 /* ":edit ++nobin file" */
-
-/* Values for "flags" */
-#define EXFLAG_LIST 0x01 /* 'l': list */
-#define EXFLAG_NR 0x02 /* '#': number */
-#define EXFLAG_PRINT 0x04 /* 'p': print */
-
-/*
- * used for completion on the command line
- */
-typedef struct expand {
- int xp_context; /* type of expansion */
- char_u *xp_pattern; /* start of item to expand */
- int xp_pattern_len; /* bytes in xp_pattern before cursor */
- char_u *xp_arg; /* completion function */
- int xp_scriptID; /* SID for completion function */
- int xp_backslash; /* one of the XP_BS_ values */
+#define FORCE_BIN 1 // ":edit ++bin file"
+#define FORCE_NOBIN 2 // ":edit ++nobin file"
+
+// Values for "flags"
+#define EXFLAG_LIST 0x01 // 'l': list
+#define EXFLAG_NR 0x02 // '#': number
+#define EXFLAG_PRINT 0x04 // 'p': print
+
+// used for completion on the command line
+struct expand {
+ int xp_context; // type of expansion
+ char_u *xp_pattern; // start of item to expand
+ int xp_pattern_len; // bytes in xp_pattern before cursor
+ char_u *xp_arg; // completion function
+ int xp_scriptID; // SID for completion function
+ int xp_backslash; // one of the XP_BS_ values
#ifndef BACKSLASH_IN_FILENAME
- int xp_shell; /* TRUE for a shell command, more
- characters need to be escaped */
+ int xp_shell; // TRUE for a shell command, more
+ // characters need to be escaped
#endif
- int xp_numfiles; /* number of files found by
- file name completion */
- char_u **xp_files; /* list of files */
- char_u *xp_line; /* text being completed */
- int xp_col; /* cursor position in line */
-} expand_T;
-
-/* values for xp_backslash */
-#define XP_BS_NONE 0 /* nothing special for backslashes */
-#define XP_BS_ONE 1 /* uses one backslash before a space */
-#define XP_BS_THREE 2 /* uses three backslashes before a space */
+ int xp_numfiles; // number of files found by file name completion
+ char_u **xp_files; // list of files
+ char_u *xp_line; // text being completed
+ int xp_col; // cursor position in line
+};
-/*
- * Command modifiers ":vertical", ":browse", ":confirm" and ":hide" set a flag.
- * This needs to be saved for recursive commands, put them in a structure for
- * easy manipulation.
- */
+// values for xp_backslash
+#define XP_BS_NONE 0 // nothing special for backslashes
+#define XP_BS_ONE 1 // uses one backslash before a space
+#define XP_BS_THREE 2 // uses three backslashes before a space
+
+/// Command modifiers ":vertical", ":browse", ":confirm", ":hide", etc. set a
+/// flag. This needs to be saved for recursive commands, put them in a
+/// structure for easy manipulation.
typedef struct {
- int hide; /* TRUE when ":hide" was used */
- int split; /* flags for win_split() */
- int tab; /* > 0 when ":tab" was used */
- int confirm; /* TRUE to invoke yes/no dialog */
- int keepalt; /* TRUE when ":keepalt" was used */
- int keepmarks; /* TRUE when ":keepmarks" was used */
- int keepjumps; /* TRUE when ":keepjumps" was used */
- int lockmarks; /* TRUE when ":lockmarks" was used */
- int keeppatterns; /* TRUE when ":keeppatterns" was used */
- bool noswapfile; /* true when ":noswapfile" was used */
- char_u *save_ei; /* saved value of 'eventignore' */
+ int split; ///< flags for win_split()
+ int tab; ///< > 0 when ":tab" was used
+ bool browse; ///< true to invoke file dialog
+ bool confirm; ///< true to invoke yes/no dialog
+ bool hide; ///< true when ":hide" was used
+ bool keepalt; ///< true when ":keepalt" was used
+ bool keepjumps; ///< true when ":keepjumps" was used
+ bool keepmarks; ///< true when ":keepmarks" was used
+ bool keeppatterns; ///< true when ":keeppatterns" was used
+ bool lockmarks; ///< true when ":lockmarks" was used
+ bool noswapfile; ///< true when ":noswapfile" was used
+ char_u *save_ei; ///< saved value of 'eventignore'
+ regmatch_T filter_regmatch; ///< set by :filter /pat/
+ bool filter_force; ///< set for :filter!
} cmdmod_T;
#endif // NVIM_EX_CMDS_DEFS_H
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 9bc7ec39da..f5c16d883a 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.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
+
/*
* ex_docmd.c: functions for executing an Ex command line.
*/
@@ -6,6 +9,7 @@
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
+#include <stdlib.h>
#include <inttypes.h>
#include "nvim/vim.h"
@@ -36,7 +40,6 @@
#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/file_search.h"
#include "nvim/garray.h"
@@ -51,6 +54,7 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
+#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
@@ -67,6 +71,9 @@
#include "nvim/event/rstream.h"
#include "nvim/event/wstream.h"
#include "nvim/shada.h"
+#include "nvim/lua/executor.h"
+#include "nvim/globals.h"
+#include "nvim/api/private/helpers.h"
static int quitmore = 0;
static int ex_pressedreturn = FALSE;
@@ -127,7 +134,6 @@ struct dbg_stuff {
char_u *vv_throwpoint;
int did_emsg;
int got_int;
- int did_throw;
int need_rethrow;
int check_cstack;
except_T *current_exception;
@@ -159,12 +165,11 @@ static void save_dbg_stuff(struct dbg_stuff *dsp)
dsp->vv_exception = v_exception(NULL);
dsp->vv_throwpoint = v_throwpoint(NULL);
- /* Necessary for debugging an inactive ":catch", ":finally", ":endtry" */
- dsp->did_emsg = did_emsg; did_emsg = FALSE;
- dsp->got_int = got_int; got_int = FALSE;
- dsp->did_throw = did_throw; did_throw = FALSE;
- dsp->need_rethrow = need_rethrow; need_rethrow = FALSE;
- dsp->check_cstack = check_cstack; check_cstack = FALSE;
+ // Necessary for debugging an inactive ":catch", ":finally", ":endtry".
+ dsp->did_emsg = did_emsg; did_emsg = false;
+ dsp->got_int = got_int; got_int = false;
+ dsp->need_rethrow = need_rethrow; need_rethrow = false;
+ dsp->check_cstack = check_cstack; check_cstack = false;
dsp->current_exception = current_exception; current_exception = NULL;
}
@@ -178,21 +183,13 @@ static void restore_dbg_stuff(struct dbg_stuff *dsp)
(void)v_throwpoint(dsp->vv_throwpoint);
did_emsg = dsp->did_emsg;
got_int = dsp->got_int;
- did_throw = dsp->did_throw;
need_rethrow = dsp->need_rethrow;
check_cstack = dsp->check_cstack;
current_exception = dsp->current_exception;
}
-
-/*
- * do_exmode(): Repeatedly get commands for the "Ex" mode, until the ":vi"
- * command is given.
- */
-void
-do_exmode (
- int improved /* TRUE for "improved Ex" mode */
-)
+/// Repeatedly get commands for Ex mode, until the ":vi" command is given.
+void do_exmode(int improved)
{
int save_msg_scroll;
int prev_msg_row;
@@ -211,8 +208,8 @@ do_exmode (
return;
save_msg_scroll = msg_scroll;
- ++RedrawingDisabled; /* don't redisplay the window */
- ++no_wait_return; /* don't wait for return */
+ RedrawingDisabled++; // don't redisplay the window
+ no_wait_return++; // don't wait for return
MSG(_("Entering Ex mode. Type \"visual\" to go to Normal mode."));
while (exmode_active) {
@@ -221,25 +218,22 @@ do_exmode (
exmode_active = FALSE;
break;
}
- msg_scroll = TRUE;
- need_wait_return = FALSE;
- ex_pressedreturn = FALSE;
- ex_no_reprint = FALSE;
- changedtick = curbuf->b_changedtick;
+ msg_scroll = true;
+ need_wait_return = false;
+ ex_pressedreturn = false;
+ ex_no_reprint = false;
+ changedtick = buf_get_changedtick(curbuf);
prev_msg_row = msg_row;
prev_line = curwin->w_cursor.lnum;
- if (improved) {
- cmdline_row = msg_row;
- do_cmdline(NULL, getexline, NULL, 0);
- } else
- do_cmdline(NULL, getexmodeline, NULL, DOCMD_NOWAIT);
+ cmdline_row = msg_row;
+ do_cmdline(NULL, getexline, NULL, 0);
lines_left = Rows - 1;
if ((prev_line != curwin->w_cursor.lnum
- || changedtick != curbuf->b_changedtick) && !ex_no_reprint) {
- if (curbuf->b_ml.ml_flags & ML_EMPTY)
+ || changedtick != buf_get_changedtick(curbuf)) && !ex_no_reprint) {
+ if (curbuf->b_ml.ml_flags & ML_EMPTY) {
EMSG(_(e_emptybuf));
- else {
+ } else {
if (ex_pressedreturn) {
/* go up one line, to overwrite the ":<CR>" line, so the
* output doesn't contain empty lines. */
@@ -259,20 +253,21 @@ do_exmode (
}
}
- --RedrawingDisabled;
- --no_wait_return;
- update_screen(CLEAR);
- need_wait_return = FALSE;
+ RedrawingDisabled--;
+ no_wait_return--;
+ redraw_all_later(NOT_VALID);
+ update_screen(NOT_VALID);
+ need_wait_return = false;
msg_scroll = save_msg_scroll;
}
/*
* Execute a simple command line. Used for translated commands like "*".
*/
-int do_cmdline_cmd(char *cmd)
+int do_cmdline_cmd(const char *cmd)
{
return do_cmdline((char_u *)cmd, NULL, NULL,
- DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED);
+ DOCMD_NOWAIT|DOCMD_KEYTYPED);
}
/*
@@ -335,17 +330,19 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
msg_list = &private_msg_list;
private_msg_list = NULL;
- /* It's possible to create an endless loop with ":execute", catch that
- * here. The value of 200 allows nested function calls, ":source", etc. */
- if (call_depth == 200) {
+ // It's possible to create an endless loop with ":execute", catch that
+ // here. The value of 200 allows nested function calls, ":source", etc.
+ // Allow 200 or 'maxfuncdepth', whatever is larger.
+ if (call_depth >= 200 && call_depth >= p_mfd) {
EMSG(_("E169: Command too recursive"));
- /* When converting to an exception, we do not include the command name
- * since this is not an error of the specific command. */
+ // When converting to an exception, we do not include the command name
+ // since this is not an error of the specific command.
do_errthrow((struct condstack *)NULL, (char_u *)NULL);
msg_list = saved_msg_list;
return FAIL;
}
- ++call_depth;
+ call_depth++;
+ start_batch_changes();
cstack.cs_idx = -1;
cstack.cs_looplevel = 0;
@@ -392,16 +389,11 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
initial_trylevel = trylevel;
- /*
- * "did_throw" will be set to TRUE when an exception is being thrown.
- */
- did_throw = FALSE;
- /*
- * "did_emsg" will be set to TRUE when emsg() is used, in which case we
- * cancel the whole command line, and any if/endif or loop.
- * If force_abort is set, we cancel everything.
- */
- did_emsg = FALSE;
+ current_exception = NULL;
+ // "did_emsg" will be set to TRUE when emsg() is used, in which case we
+ // cancel the whole command line, and any if/endif or loop.
+ // If force_abort is set, we cancel everything.
+ did_emsg = false;
/*
* KeyTyped is only set when calling vgetc(). Reset it here when not
@@ -409,7 +401,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
*/
if (!(flags & DOCMD_KEYTYPED)
&& !getline_equal(fgetline, cookie, getexline))
- KeyTyped = FALSE;
+ KeyTyped = false;
/*
* Continue executing command lines:
@@ -583,10 +575,10 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
++no_wait_return;
verbose_enter_scroll();
- smsg(_("line %" PRId64 ": %s"),
- (int64_t)sourcing_lnum, cmdline_copy);
- if (msg_silent == 0)
- msg_puts((char_u *)"\n"); /* don't overwrite this */
+ smsg(_("line %" PRIdLINENR ": %s"), sourcing_lnum, cmdline_copy);
+ if (msg_silent == 0) {
+ msg_puts("\n"); // don't overwrite this either
+ }
verbose_leave_scroll();
--no_wait_return;
@@ -597,11 +589,16 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* do_one_cmd() will return NULL if there is no trailing '|'.
* "cmdline_copy" can change, e.g. for '%' and '#' expansion.
*/
- ++recursive;
- next_cmdline = do_one_cmd(&cmdline_copy, flags & DOCMD_VERBOSE,
- &cstack,
- cmd_getline, cmd_cookie);
- --recursive;
+ recursive++;
+ next_cmdline = do_one_cmd(&cmdline_copy, flags,
+ &cstack,
+ cmd_getline, cmd_cookie);
+ recursive--;
+
+ // Ignore trailing '|'-separated commands in preview-mode ('inccommand').
+ if (State & CMDPREVIEW) {
+ next_cmdline = NULL;
+ }
if (cmd_cookie == (void *)&cmd_loop_cookie)
/* Use "current_line" from "cmd_loop_cookie", it may have been
@@ -651,7 +648,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* not to use a cs_line[] from an entry that isn't a ":while"
* or ":for": It would make "current_line" invalid and can
* cause a crash. */
- if (!did_emsg && !got_int && !did_throw
+ if (!did_emsg && !got_int && !current_exception
&& cstack.cs_idx >= 0
&& (cstack.cs_flags[cstack.cs_idx]
& (CSF_WHILE | CSF_FOR))
@@ -699,7 +696,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
}
/*
- * A ":finally" makes did_emsg, got_int, and did_throw pending for
+ * A ":finally" makes did_emsg, got_int and current_exception pending for
* being restored at the ":endtry". Reset them here and set the
* ACTIVE and FINALLY flags, so that the finally clause gets executed.
* This includes the case where a missing ":endif", ":endwhile" or
@@ -707,10 +704,11 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
*/
if (cstack.cs_lflags & CSL_HAD_FINA) {
cstack.cs_lflags &= ~CSL_HAD_FINA;
- report_make_pending(cstack.cs_pending[cstack.cs_idx]
- & (CSTP_ERROR | CSTP_INTERRUPT | CSTP_THROW),
- did_throw ? (void *)current_exception : NULL);
- did_emsg = got_int = did_throw = FALSE;
+ report_make_pending((cstack.cs_pending[cstack.cs_idx]
+ & (CSTP_ERROR | CSTP_INTERRUPT | CSTP_THROW)),
+ current_exception);
+ did_emsg = got_int = false;
+ current_exception = NULL;
cstack.cs_flags[cstack.cs_idx] |= CSF_ACTIVE | CSF_FINALLY;
}
@@ -718,15 +716,14 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* within this loop. */
trylevel = initial_trylevel + cstack.cs_trylevel;
- /*
- * If the outermost try conditional (across function calls and sourced
- * files) is aborted because of an error, an interrupt, or an uncaught
- * exception, cancel everything. If it is left normally, reset
- * force_abort to get the non-EH compatible abortion behavior for
- * the rest of the script.
- */
- if (trylevel == 0 && !did_emsg && !got_int && !did_throw)
- force_abort = FALSE;
+ // If the outermost try conditional (across function calls and sourced
+ // files) is aborted because of an error, an interrupt, or an uncaught
+ // exception, cancel everything. If it is left normally, reset
+ // force_abort to get the non-EH compatible abortion behavior for
+ // the rest of the script.
+ if (trylevel == 0 && !did_emsg && !got_int && !current_exception) {
+ force_abort = false;
+ }
/* Convert an interrupt to an exception if appropriate. */
(void)do_intthrow(&cstack);
@@ -741,11 +738,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* - there is a command after '|', inside a :if, :while, :for or :try, or
* looping for ":source" command or function call.
*/
- while (!((got_int
- || (did_emsg && force_abort) || did_throw
- )
- && cstack.cs_trylevel == 0
- )
+ while (!((got_int || (did_emsg && force_abort) || current_exception)
+ && cstack.cs_trylevel == 0)
&& !(did_emsg
/* Keep going when inside try/catch, so that the error can be
* deal with, except when it is a syntax error, it may cause
@@ -767,7 +761,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* If a sourced file or executed function ran to its end, report the
* unclosed conditional.
*/
- if (!got_int && !did_throw
+ if (!got_int && !current_exception
&& ((getline_equal(fgetline, cookie, getsourceline)
&& !source_finished(fgetline, cookie))
|| (getline_equal(fgetline, cookie, get_func_line)
@@ -807,17 +801,16 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
? (char_u *)"endfunction" : (char_u *)NULL);
if (trylevel == 0) {
- /*
- * When an exception is being thrown out of the outermost try
- * conditional, discard the uncaught exception, disable the conversion
- * of interrupts or errors to exceptions, and ensure that no more
- * commands are executed.
- */
- if (did_throw) {
- void *p = NULL;
- char_u *saved_sourcing_name;
+ // When an exception is being thrown out of the outermost try
+ // conditional, discard the uncaught exception, disable the conversion
+ // of interrupts or errors to exceptions, and ensure that no more
+ // commands are executed.
+ if (current_exception) {
+ void *p = NULL;
+ char_u *saved_sourcing_name;
int saved_sourcing_lnum;
- struct msglist *messages = NULL, *next;
+ struct msglist *messages = NULL;
+ struct msglist *next;
/*
* If the uncaught exception is a user exception, report it as an
@@ -838,8 +831,6 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
break;
case ET_INTERRUPT:
break;
- default:
- p = vim_strsave((char_u *)_(e_internal));
}
saved_sourcing_name = sourcing_name;
@@ -879,22 +870,22 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
suppress_errthrow = TRUE;
}
- /*
- * The current cstack will be freed when do_cmdline() returns. An uncaught
- * exception will have to be rethrown in the previous cstack. If a function
- * has just returned or a script file was just finished and the previous
- * cstack belongs to the same function or, respectively, script file, it
- * will have to be checked for finally clauses to be executed due to the
- * ":return" or ":finish". This is done in do_one_cmd().
- */
- if (did_throw)
- need_rethrow = TRUE;
+ // The current cstack will be freed when do_cmdline() returns. An uncaught
+ // exception will have to be rethrown in the previous cstack. If a function
+ // has just returned or a script file was just finished and the previous
+ // cstack belongs to the same function or, respectively, script file, it
+ // will have to be checked for finally clauses to be executed due to the
+ // ":return" or ":finish". This is done in do_one_cmd().
+ if (current_exception) {
+ need_rethrow = true;
+ }
if ((getline_equal(fgetline, cookie, getsourceline)
&& ex_nesting_level > source_level(real_cookie))
|| (getline_equal(fgetline, cookie, get_func_line)
&& ex_nesting_level > func_level(real_cookie) + 1)) {
- if (!did_throw)
- check_cstack = TRUE;
+ if (!current_exception) {
+ check_cstack = true;
+ }
} else {
/* When leaving a function, reduce nesting level. */
if (getline_equal(fgetline, cookie, get_func_line))
@@ -952,7 +943,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
did_endif = FALSE; /* in case do_cmdline used recursively */
- --call_depth;
+ call_depth--;
+ end_batch_changes();
return retval;
}
@@ -982,8 +974,8 @@ static char_u *get_loop_line(int c, void *cookie, int indent)
return line;
}
- KeyTyped = FALSE;
- ++cp->current_line;
+ KeyTyped = false;
+ cp->current_line++;
wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line;
sourcing_lnum = wp->lnum;
return vim_strsave(wp->line);
@@ -1224,7 +1216,7 @@ static void get_wincmd_addr_type(char_u *arg, exarg_T *eap)
* This function may be called recursively!
*/
static char_u * do_one_cmd(char_u **cmdlinep,
- int sourcing,
+ int flags,
struct condstack *cstack,
LineGetter fgetline,
void *cookie /* argument for fgetline() */
@@ -1243,11 +1235,12 @@ static char_u * do_one_cmd(char_u **cmdlinep,
cmdmod_T save_cmdmod;
int ni; /* set when Not Implemented */
char_u *cmd;
+ int address_count = 1;
memset(&ea, 0, sizeof(ea));
ea.line1 = 1;
ea.line2 = 1;
- ++ex_nesting_level;
+ ex_nesting_level++;
/* When the last file has not been edited :q has to be typed twice. */
if (quitmore
@@ -1300,9 +1293,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
/*
* 2. Handle command modifiers.
*/
- p = ea.cmd;
- if (ascii_isdigit(*ea.cmd))
- p = skipwhite(skipdigits(ea.cmd));
+ p = skip_range(ea.cmd, NULL);
switch (*p) {
/* When adding an entry, also modify cmd_exists(). */
case 'a': if (!checkforcmd(&ea.cmd, "aboveleft", 3))
@@ -1313,8 +1304,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
case 'b': if (checkforcmd(&ea.cmd, "belowright", 3)) {
cmdmod.split |= WSP_BELOW;
continue;
- }
+ }
if (checkforcmd(&ea.cmd, "browse", 3)) {
+ cmdmod.browse = true;
continue;
}
if (!checkforcmd(&ea.cmd, "botright", 2))
@@ -1324,36 +1316,61 @@ static char_u * do_one_cmd(char_u **cmdlinep,
case 'c': if (!checkforcmd(&ea.cmd, "confirm", 4))
break;
- cmdmod.confirm = TRUE;
+ cmdmod.confirm = true;
continue;
case 'k': if (checkforcmd(&ea.cmd, "keepmarks", 3)) {
- cmdmod.keepmarks = TRUE;
+ cmdmod.keepmarks = true;
continue;
}
if (checkforcmd(&ea.cmd, "keepalt", 5)) {
- cmdmod.keepalt = TRUE;
+ cmdmod.keepalt = true;
continue;
}
if (checkforcmd(&ea.cmd, "keeppatterns", 5)) {
- cmdmod.keeppatterns = TRUE;
+ cmdmod.keeppatterns = true;
continue;
}
if (!checkforcmd(&ea.cmd, "keepjumps", 5))
break;
- cmdmod.keepjumps = TRUE;
+ cmdmod.keepjumps = true;
+ continue;
+
+ case 'f': { // only accept ":filter {pat} cmd"
+ char_u *reg_pat;
+
+ if (!checkforcmd(&p, "filter", 4) || *p == NUL || ends_excmd(*p)) {
+ break;
+ }
+ if (*p == '!') {
+ cmdmod.filter_force = true;
+ p = skipwhite(p + 1);
+ if (*p == NUL || ends_excmd(*p)) {
+ break;
+ }
+ }
+ p = skip_vimgrep_pat(p, &reg_pat, NULL);
+ if (p == NULL || *p == NUL) {
+ break;
+ }
+ cmdmod.filter_regmatch.regprog = vim_regcomp(reg_pat, RE_MAGIC);
+ if (cmdmod.filter_regmatch.regprog == NULL) {
+ break;
+ }
+ ea.cmd = p;
continue;
+ }
/* ":hide" and ":hide | cmd" are not modifiers */
case 'h': if (p != ea.cmd || !checkforcmd(&p, "hide", 3)
|| *p == NUL || ends_excmd(*p))
break;
ea.cmd = p;
- cmdmod.hide = TRUE;
+ cmdmod.hide = true;
continue;
case 'l': if (checkforcmd(&ea.cmd, "lockmarks", 3)) {
- cmdmod.lockmarks = TRUE;
+ cmdmod.lockmarks = true;
continue;
}
@@ -1373,7 +1390,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
continue;
}
- if (!checkforcmd(&ea.cmd, "noswapfile", 6)) {
+ if (!checkforcmd(&ea.cmd, "noswapfile", 3)) {
break;
}
cmdmod.noswapfile = true;
@@ -1404,12 +1421,18 @@ static char_u * do_one_cmd(char_u **cmdlinep,
continue;
case 't': if (checkforcmd(&p, "tab", 3)) {
- if (ascii_isdigit(*ea.cmd))
- cmdmod.tab = atoi((char *)ea.cmd) + 1;
- else
- cmdmod.tab = tabpage_index(curtab) + 1;
- ea.cmd = p;
- continue;
+ long tabnr = get_address(&ea, &ea.cmd, ADDR_TABS, ea.skip, false, 1);
+ if (tabnr == MAXLNUM) {
+ cmdmod.tab = tabpage_index(curtab) + 1;
+ } else {
+ if (tabnr < 0 || tabnr > LAST_TAB_NR) {
+ errormsg = (char_u *)_(e_invrange);
+ goto doend;
+ }
+ cmdmod.tab = tabnr + 1;
+ }
+ ea.cmd = p;
+ continue;
}
if (!checkforcmd(&ea.cmd, "topleft", 2))
break;
@@ -1440,11 +1463,13 @@ static char_u * do_one_cmd(char_u **cmdlinep,
}
break;
}
+ char_u *after_modifier = ea.cmd;
- ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0
- && !(cstack->cs_flags[cstack->
- cs_idx]
- & CSF_ACTIVE));
+ ea.skip = (did_emsg
+ || got_int
+ || current_exception
+ || (cstack->cs_idx >= 0
+ && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)));
/* Count this line for profiling if ea.skip is FALSE. */
if (do_profiling == PROF_YES && !ea.skip) {
@@ -1513,8 +1538,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = curwin->w_cursor.lnum;
break;
case ADDR_WINDOWS:
- lnum = CURRENT_WIN_NR;
- ea.line2 = lnum;
+ ea.line2 = CURRENT_WIN_NR;
break;
case ADDR_ARGUMENTS:
ea.line2 = curwin->w_arg_idx + 1;
@@ -1527,15 +1551,18 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line2 = curbuf->b_fnum;
break;
case ADDR_TABS:
- lnum = CURRENT_TAB_NR;
- ea.line2 = lnum;
+ ea.line2 = CURRENT_TAB_NR;
+ break;
+ case ADDR_TABS_RELATIVE:
+ ea.line2 = 1;
break;
case ADDR_QUICKFIX:
ea.line2 = qf_get_cur_valid_idx(&ea);
break;
}
ea.cmd = skipwhite(ea.cmd);
- lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip, ea.addr_count == 0);
+ lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip,
+ ea.addr_count == 0, address_count++);
if (ea.cmd == NULL) { // error detected
goto doend;
}
@@ -1577,6 +1604,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
goto doend;
}
break;
+ case ADDR_TABS_RELATIVE:
+ errormsg = (char_u *)_(e_invrange);
+ goto doend;
+ break;
case ADDR_ARGUMENTS:
if (ARGCOUNT == 0) {
ea.line1 = ea.line2 = 0;
@@ -1622,11 +1653,15 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.addr_count++;
if (*ea.cmd == ';') {
- if (!ea.skip)
+ if (!ea.skip) {
curwin->w_cursor.lnum = ea.line2;
- } else if (*ea.cmd != ',')
+ // don't leave the cursor on an illegal line or column
+ check_cursor();
+ }
+ } else if (*ea.cmd != ',') {
break;
- ++ea.cmd;
+ }
+ ea.cmd++;
}
/* One address given: set start and end lines */
@@ -1637,9 +1672,6 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.addr_count = 0;
}
- /* Don't leave the cursor on an illegal line (caused by ';') */
- check_cursor_lnum();
-
/*
* 5. Parse the command.
*/
@@ -1703,7 +1735,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
xfree(p);
// If the autocommands did something and didn't cause an error, try
// finding the command again.
- p = (ret && !aborting()) ? find_command(&ea, NULL) : NULL;
+ p = (ret && !aborting()) ? find_command(&ea, NULL) : ea.cmd;
}
if (p == NULL) {
@@ -1711,16 +1743,19 @@ static char_u * do_one_cmd(char_u **cmdlinep,
errormsg = (char_u *)_("E464: Ambiguous use of user-defined command");
goto doend;
}
- /* Check for wrong commands. */
- if (*p == '!' && ea.cmd[1] == 0151 && ea.cmd[0] == 78) {
- errormsg = uc_fun_cmd();
- goto doend;
- }
+ // Check for wrong commands.
if (ea.cmdidx == CMD_SIZE) {
if (!ea.skip) {
STRCPY(IObuff, _("E492: Not an editor command"));
- if (!sourcing)
- append_command(*cmdlinep);
+ if (!(flags & DOCMD_VERBOSE)) {
+ // If the modifier was parsed OK the error must be in the following
+ // command
+ if (after_modifier != NULL) {
+ append_command(after_modifier);
+ } else {
+ append_command(*cmdlinep);
+ }
+ }
errormsg = IObuff;
did_emsg_syntax = TRUE;
}
@@ -1733,13 +1768,14 @@ static char_u * do_one_cmd(char_u **cmdlinep,
));
- /* forced commands */
+ // Forced commands.
if (*p == '!' && ea.cmdidx != CMD_substitute
&& ea.cmdidx != CMD_smagic && ea.cmdidx != CMD_snomagic) {
- ++p;
- ea.forceit = TRUE;
- } else
- ea.forceit = FALSE;
+ p++;
+ ea.forceit = true;
+ } else {
+ ea.forceit = false;
+ }
/*
* 6. Parse arguments.
@@ -1764,22 +1800,23 @@ static char_u * do_one_cmd(char_u **cmdlinep,
if (text_locked() && !(ea.argt & CMDWIN)
&& !IS_USER_CMDIDX(ea.cmdidx)) {
- /* Command not allowed when editing the command line. */
- if (cmdwin_type != 0)
- errormsg = (char_u *)_(e_cmdwin);
- else
- errormsg = (char_u *)_(e_secure);
+ // Command not allowed when editing the command line.
+ errormsg = (char_u *)_(get_text_locked_msg());
goto doend;
}
- /* Disallow editing another buffer when "curbuf_lock" is set.
- * Do allow ":edit" (check for argument later).
- * Do allow ":checktime" (it's postponed). */
+
+ // Disallow editing another buffer when "curbuf_lock" is set.
+ // Do allow ":checktime" (it is postponed).
+ // Do allow ":edit" (check for an argument later).
+ // Do allow ":file" with no arguments (check for an argument later).
if (!(ea.argt & CMDWIN)
- && ea.cmdidx != CMD_edit
&& ea.cmdidx != CMD_checktime
+ && ea.cmdidx != CMD_edit
+ && ea.cmdidx != CMD_file
&& !IS_USER_CMDIDX(ea.cmdidx)
- && curbuf_locked())
+ && curbuf_locked()) {
goto doend;
+ }
if (!ni && !(ea.argt & RANGE) && ea.addr_count > 0) {
/* no range allowed */
@@ -1805,13 +1842,13 @@ static char_u * do_one_cmd(char_u **cmdlinep,
*/
if (!global_busy && ea.line1 > ea.line2) {
if (msg_silent == 0) {
- if (sourcing || exmode_active) {
+ if ((flags & DOCMD_VERBOSE) || exmode_active) {
errormsg = (char_u *)_("E493: Backwards range given");
goto doend;
}
- if (ask_yesno((char_u *)
- _("Backwards range given, OK to swap"), FALSE) != 'y')
+ if (ask_yesno(_("Backwards range given, OK to swap"), false) != 'y') {
goto doend;
+ }
}
lnum = ea.line1;
ea.line1 = ea.line2;
@@ -1851,6 +1888,11 @@ static char_u * do_one_cmd(char_u **cmdlinep,
else
ea.arg = skipwhite(p);
+ // ":file" cannot be run with an argument when "curbuf_lock" is set
+ if (ea.cmdidx == CMD_file && *ea.arg != NUL && curbuf_locked()) {
+ goto doend;
+ }
+
/*
* Check for "++opt=val" argument.
* Must be first, allow ":w ++enc=utf8 !cmd"
@@ -1965,6 +2007,9 @@ static char_u * do_one_cmd(char_u **cmdlinep,
case ADDR_TABS:
ea.line2 = LAST_TAB_NR;
break;
+ case ADDR_TABS_RELATIVE:
+ ea.line2 = 1;
+ break;
case ADDR_ARGUMENTS:
if (ARGCOUNT == 0) {
ea.line1 = ea.line2 = 0;
@@ -2020,11 +2065,11 @@ static char_u * do_one_cmd(char_u **cmdlinep,
ea.line1 = ea.line2;
ea.line2 += n - 1;
++ea.addr_count;
- /*
- * Be vi compatible: no error message for out of range.
- */
- if (ea.line2 > curbuf->b_ml.ml_line_count)
+ // Be vi compatible: no error message for out of range.
+ if (ea.addr_type == ADDR_LINES
+ && ea.line2 > curbuf->b_ml.ml_line_count) {
ea.line2 = curbuf->b_ml.ml_line_count;
+ }
}
}
@@ -2089,6 +2134,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
case CMD_echomsg:
case CMD_echon:
case CMD_execute:
+ case CMD_filter:
case CMD_help:
case CMD_hide:
case CMD_ijump:
@@ -2112,6 +2158,10 @@ static char_u * do_one_cmd(char_u **cmdlinep,
case CMD_python:
case CMD_py3:
case CMD_python3:
+ case CMD_pythonx:
+ case CMD_pyx:
+ case CMD_pyxdo:
+ case CMD_pyxfile:
case CMD_return:
case CMD_rightbelow:
case CMD_ruby:
@@ -2217,7 +2267,7 @@ doend:
curwin->w_cursor.lnum = 1;
if (errormsg != NULL && *errormsg != NUL && !did_emsg) {
- if (sourcing) {
+ if (flags & DOCMD_VERBOSE) {
if (errormsg != IObuff) {
STRCPY(IObuff, errormsg);
errormsg = IObuff;
@@ -2240,6 +2290,10 @@ doend:
free_string_option(cmdmod.save_ei);
}
+ if (cmdmod.filter_regmatch.regprog != NULL) {
+ vim_regfree(cmdmod.filter_regmatch.regprog);
+ }
+
cmdmod = save_cmdmod;
if (save_msg_silent != -1) {
@@ -2275,11 +2329,11 @@ doend:
* Check for an Ex command with optional tail.
* If there is a match advance "pp" to the argument and return TRUE.
*/
-int
-checkforcmd (
- char_u **pp, /* start of command */
- char *cmd, /* name of command */
- int len /* required length */
+int
+checkforcmd(
+ char_u **pp, // start of command
+ char *cmd, // name of command
+ int len // required length
)
{
int i;
@@ -2525,28 +2579,29 @@ static struct cmdmod {
int minlen;
int has_count; /* :123verbose :3tab */
} cmdmods[] = {
- {"aboveleft", 3, FALSE},
- {"belowright", 3, FALSE},
- {"botright", 2, FALSE},
- {"browse", 3, FALSE},
- {"confirm", 4, FALSE},
- {"hide", 3, FALSE},
- {"keepalt", 5, FALSE},
- {"keepjumps", 5, FALSE},
- {"keepmarks", 3, FALSE},
- {"keeppatterns", 5, FALSE},
- {"leftabove", 5, FALSE},
- {"lockmarks", 3, FALSE},
- {"noautocmd", 3, FALSE},
- {"noswapfile", 3, FALSE},
- {"rightbelow", 6, FALSE},
- {"sandbox", 3, FALSE},
- {"silent", 3, FALSE},
- {"tab", 3, TRUE},
- {"topleft", 2, FALSE},
- {"unsilent", 3, FALSE},
- {"verbose", 4, TRUE},
- {"vertical", 4, FALSE},
+ { "aboveleft", 3, false },
+ { "belowright", 3, false },
+ { "botright", 2, false },
+ { "browse", 3, false },
+ { "confirm", 4, false },
+ { "filter", 4, false },
+ { "hide", 3, false },
+ { "keepalt", 5, false },
+ { "keepjumps", 5, false },
+ { "keepmarks", 3, false },
+ { "keeppatterns", 5, false },
+ { "leftabove", 5, false },
+ { "lockmarks", 3, false },
+ { "noautocmd", 3, false },
+ { "noswapfile", 3, false },
+ { "rightbelow", 6, false },
+ { "sandbox", 3, false },
+ { "silent", 3, false },
+ { "tab", 3, true },
+ { "topleft", 2, false },
+ { "unsilent", 3, false },
+ { "verbose", 4, true },
+ { "vertical", 4, false },
};
/*
@@ -2576,27 +2631,29 @@ int modifier_len(char_u *cmd)
* Return 2 if there is an exact match.
* Return 3 if there is an ambiguous match.
*/
-int cmd_exists(char_u *name)
+int cmd_exists(const char *const name)
{
exarg_T ea;
- int full = FALSE;
- int i;
- int j;
char_u *p;
- /* Check command modifiers. */
- for (i = 0; i < (int)ARRAY_SIZE(cmdmods); ++i) {
- for (j = 0; name[j] != NUL; ++j)
- if (name[j] != cmdmods[i].name[j])
+ // Check command modifiers.
+ for (int i = 0; i < (int)ARRAY_SIZE(cmdmods); i++) {
+ int j;
+ for (j = 0; name[j] != NUL; j++) {
+ if (name[j] != (char)cmdmods[i].name[j]) {
break;
- if (name[j] == NUL && j >= cmdmods[i].minlen)
+ }
+ }
+ if (name[j] == NUL && j >= cmdmods[i].minlen) {
return cmdmods[i].name[j] == NUL ? 2 : 1;
+ }
}
/* Check built-in commands and user defined commands.
* For ":2match" and ":3match" we need to skip the number. */
- ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name;
+ ea.cmd = (char_u *)((*name == '2' || *name == '3') ? name + 1 : name);
ea.cmdidx = (cmdidx_T)0;
+ int full = false;
p = find_command(&ea, &full);
if (p == NULL)
return 3;
@@ -2614,32 +2671,27 @@ int cmd_exists(char_u *name)
* perfectly compatible with each other, but then the command line syntax
* probably won't change that much -- webb.
*/
-char_u *
-set_one_cmd_context (
+const char * set_one_cmd_context(
expand_T *xp,
- char_u *buff /* buffer for command string */
+ const char *buff // buffer for command string
)
{
- char_u *p;
- char_u *cmd, *arg;
- int len = 0;
+ size_t len = 0;
exarg_T ea;
- int compl = EXPAND_NOTHING;
- int delim;
- int forceit = FALSE;
- int usefilter = FALSE; /* filter instead of file name */
+ int context = EXPAND_NOTHING;
+ bool forceit = false;
+ bool usefilter = false; // Filter instead of file name.
ExpandInit(xp);
- xp->xp_pattern = buff;
- xp->xp_context = EXPAND_COMMANDS; /* Default until we get past command */
+ xp->xp_pattern = (char_u *)buff;
+ xp->xp_context = EXPAND_COMMANDS; // Default until we get past command
ea.argt = 0;
- /*
- * 2. skip comment lines and leading space, colons or bars
- */
- for (cmd = buff; vim_strchr((char_u *)" \t:|", *cmd) != NULL; cmd++)
- ;
- xp->xp_pattern = cmd;
+ // 2. skip comment lines and leading space, colons or bars
+ const char *cmd;
+ for (cmd = buff; vim_strchr((const char_u *)" \t:|", *cmd) != NULL; cmd++) {
+ }
+ xp->xp_pattern = (char_u *)cmd;
if (*cmd == NUL)
return NULL;
@@ -2651,14 +2703,15 @@ set_one_cmd_context (
/*
* 3. parse a range specifier of the form: addr [,addr] [;addr] ..
*/
- cmd = skip_range(cmd, &xp->xp_context);
+ cmd = (const char *)skip_range((const char_u *)cmd, &xp->xp_context);
/*
* 4. parse command
*/
- xp->xp_pattern = cmd;
- if (*cmd == NUL)
+ xp->xp_pattern = (char_u *)cmd;
+ if (*cmd == NUL) {
return NULL;
+ }
if (*cmd == '"') {
xp->xp_context = EXPAND_NOTHING;
return NULL;
@@ -2674,6 +2727,7 @@ set_one_cmd_context (
* do accept "keepmarks", "keepalt" and "keepjumps".
* - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
*/
+ const char *p;
if (*cmd == 'k' && cmd[1] != 'e') {
ea.cmdidx = CMD_k;
p = cmd + 1;
@@ -2696,20 +2750,21 @@ set_one_cmd_context (
}
}
// check for non-alpha command
- if (p == cmd && vim_strchr((char_u *)"@*!=><&~#", *p) != NULL) {
+ if (p == cmd && vim_strchr((const char_u *)"@*!=><&~#", *p) != NULL) {
p++;
}
- len = (int)(p - cmd);
+ len = (size_t)(p - cmd);
if (len == 0) {
xp->xp_context = EXPAND_UNSUCCESSFUL;
return NULL;
}
for (ea.cmdidx = (cmdidx_T)0; (int)ea.cmdidx < (int)CMD_SIZE;
- ea.cmdidx = (cmdidx_T)((int)ea.cmdidx + 1))
- if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, cmd,
- (size_t)len) == 0)
+ ea.cmdidx = (cmdidx_T)((int)ea.cmdidx + 1)) {
+ if (STRNCMP(cmdnames[(int)ea.cmdidx].cmd_name, cmd, len) == 0) {
break;
+ }
+ }
if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
while (ASCII_ISALNUM(*p) || *p == '*') { // Allow * wild card
@@ -2726,16 +2781,15 @@ set_one_cmd_context (
return NULL;
if (ea.cmdidx == CMD_SIZE) {
- if (*cmd == 's' && vim_strchr((char_u *)"cgriI", cmd[1]) != NULL) {
+ if (*cmd == 's' && vim_strchr((const char_u *)"cgriI", cmd[1]) != NULL) {
ea.cmdidx = CMD_substitute;
p = cmd + 1;
} else if (cmd[0] >= 'A' && cmd[0] <= 'Z') {
- ea.cmd = cmd;
- p = find_ucmd(&ea, p, NULL, xp,
- &compl
- );
- if (p == NULL)
- ea.cmdidx = CMD_SIZE; /* ambiguous user command */
+ ea.cmd = (char_u *)cmd;
+ p = (const char *)find_ucmd(&ea, (char_u *)p, NULL, xp, &context);
+ if (p == NULL) {
+ ea.cmdidx = CMD_SIZE; // Ambiguous user command.
+ }
}
}
if (ea.cmdidx == CMD_SIZE) {
@@ -2746,9 +2800,9 @@ set_one_cmd_context (
xp->xp_context = EXPAND_NOTHING; /* Default now that we're past command */
- if (*p == '!') { /* forced commands */
- forceit = TRUE;
- ++p;
+ if (*p == '!') { // forced commands
+ forceit = true;
+ p++;
}
/*
@@ -2758,45 +2812,47 @@ set_one_cmd_context (
ea.argt = cmdnames[(int)ea.cmdidx].cmd_argt;
}
- arg = skipwhite(p);
+ const char *arg = (const char *)skipwhite((const char_u *)p);
if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update) {
- if (*arg == '>') { /* append */
- if (*++arg == '>')
- ++arg;
- arg = skipwhite(arg);
- } else if (*arg == '!' && ea.cmdidx == CMD_write) { /* :w !filter */
- ++arg;
- usefilter = TRUE;
+ if (*arg == '>') { // Append.
+ if (*++arg == '>') {
+ arg++;
+ }
+ arg = (const char *)skipwhite((const char_u *)arg);
+ } else if (*arg == '!' && ea.cmdidx == CMD_write) { // :w !filter
+ arg++;
+ usefilter = true;
}
}
if (ea.cmdidx == CMD_read) {
- usefilter = forceit; /* :r! filter if forced */
- if (*arg == '!') { /* :r !filter */
- ++arg;
- usefilter = TRUE;
+ usefilter = forceit; // :r! filter if forced
+ if (*arg == '!') { // :r !filter
+ arg++;
+ usefilter = true;
}
}
if (ea.cmdidx == CMD_lshift || ea.cmdidx == CMD_rshift) {
- while (*arg == *cmd) /* allow any number of '>' or '<' */
- ++arg;
- arg = skipwhite(arg);
+ while (*arg == *cmd) { // allow any number of '>' or '<'
+ arg++;
+ }
+ arg = (const char *)skipwhite((const char_u *)arg);
}
/* Does command allow "+command"? */
if ((ea.argt & EDITCMD) && !usefilter && *arg == '+') {
/* Check if we're in the +command */
p = arg + 1;
- arg = skip_cmd_arg(arg, FALSE);
+ arg = (const char *)skip_cmd_arg((char_u *)arg, false);
/* Still touching the command after '+'? */
if (*arg == NUL)
return p;
- /* Skip space(s) after +command to get to the real argument */
- arg = skipwhite(arg);
+ // Skip space(s) after +command to get to the real argument.
+ arg = (const char *)skipwhite((const char_u *)arg);
}
/*
@@ -2820,52 +2876,49 @@ set_one_cmd_context (
return NULL; /* It's a comment */
}
}
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
}
// no arguments allowed
- if (!(ea.argt & EXTRA) && *arg != NUL
- && vim_strchr((char_u *)"|\"", *arg) == NULL) {
+ if (!(ea.argt & EXTRA) && *arg != NUL && strchr("|\"", *arg) == NULL) {
return NULL;
}
/* Find start of last argument (argument just before cursor): */
p = buff;
- xp->xp_pattern = p;
- len = (int)STRLEN(buff);
+ xp->xp_pattern = (char_u *)p;
+ len = strlen(buff);
while (*p && p < buff + len) {
if (*p == ' ' || *p == TAB) {
- /* argument starts after a space */
- xp->xp_pattern = ++p;
+ // Argument starts after a space.
+ xp->xp_pattern = (char_u *)++p;
} else {
- if (*p == '\\' && *(p + 1) != NUL)
- ++p; /* skip over escaped character */
- mb_ptr_adv(p);
+ if (*p == '\\' && *(p + 1) != NUL) {
+ p++; // skip over escaped character
+ }
+ MB_PTR_ADV(p);
}
}
if (ea.argt & XFILE) {
int c;
- int in_quote = FALSE;
- char_u *bow = NULL; /* Beginning of word */
+ int in_quote = false;
+ const char *bow = NULL; // Beginning of word.
/*
* Allow spaces within back-quotes to count as part of the argument
* being expanded.
*/
- xp->xp_pattern = skipwhite(arg);
- p = xp->xp_pattern;
+ xp->xp_pattern = skipwhite((const char_u *)arg);
+ p = (const char *)xp->xp_pattern;
while (*p != NUL) {
- if (has_mbyte)
- c = mb_ptr2char(p);
- else
- c = *p;
- if (c == '\\' && p[1] != NUL)
- ++p;
- else if (c == '`') {
+ c = utf_ptr2char((const char_u *)p);
+ if (c == '\\' && p[1] != NUL) {
+ p++;
+ } else if (c == '`') {
if (!in_quote) {
- xp->xp_pattern = p;
+ xp->xp_pattern = (char_u *)p;
bow = p + 1;
}
in_quote = !in_quote;
@@ -2878,33 +2931,30 @@ set_one_cmd_context (
|| ascii_iswhite(c)) {
len = 0; /* avoid getting stuck when space is in 'isfname' */
while (*p != NUL) {
- if (has_mbyte)
- c = mb_ptr2char(p);
- else
- c = *p;
- if (c == '`' || vim_isfilec_or_wc(c))
+ c = utf_ptr2char((const char_u *)p);
+ if (c == '`' || vim_isfilec_or_wc(c)) {
break;
- if (has_mbyte)
- len = (*mb_ptr2len)(p);
- else
- len = 1;
- mb_ptr_adv(p);
+ }
+ len = (size_t)utfc_ptr2len((const char_u *)p);
+ MB_PTR_ADV(p);
}
- if (in_quote)
+ if (in_quote) {
bow = p;
- else
- xp->xp_pattern = p;
+ } else {
+ xp->xp_pattern = (char_u *)p;
+ }
p -= len;
}
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
/*
* If we are still inside the quotes, and we passed a space, just
* expand from there.
*/
- if (bow != NULL && in_quote)
- xp->xp_pattern = bow;
+ if (bow != NULL && in_quote) {
+ xp->xp_pattern = (char_u *)bow;
+ }
xp->xp_context = EXPAND_FILES;
/* For a shell command more chars need to be escaped. */
@@ -2912,34 +2962,37 @@ set_one_cmd_context (
#ifndef BACKSLASH_IN_FILENAME
xp->xp_shell = TRUE;
#endif
- /* When still after the command name expand executables. */
- if (xp->xp_pattern == skipwhite(arg))
+ // When still after the command name expand executables.
+ if (xp->xp_pattern == skipwhite((const char_u *)arg)) {
xp->xp_context = EXPAND_SHELLCMD;
+ }
}
- /* Check for environment variable */
- if (*xp->xp_pattern == '$'
- ) {
- for (p = xp->xp_pattern + 1; *p != NUL; ++p)
- if (!vim_isIDc(*p))
+ // Check for environment variable.
+ if (*xp->xp_pattern == '$') {
+ for (p = (const char *)xp->xp_pattern + 1; *p != NUL; p++) {
+ if (!vim_isIDc((uint8_t)(*p))) {
break;
+ }
+ }
if (*p == NUL) {
xp->xp_context = EXPAND_ENV_VARS;
- ++xp->xp_pattern;
- /* Avoid that the assignment uses EXPAND_FILES again. */
- if (compl != EXPAND_USER_DEFINED && compl != EXPAND_USER_LIST)
- compl = EXPAND_ENV_VARS;
+ xp->xp_pattern++;
+ // Avoid that the assignment uses EXPAND_FILES again.
+ if (context != EXPAND_USER_DEFINED && context != EXPAND_USER_LIST) {
+ context = EXPAND_ENV_VARS;
+ }
}
}
/* Check for user names */
if (*xp->xp_pattern == '~') {
- for (p = xp->xp_pattern + 1; *p != NUL && *p != '/'; ++p)
- ;
- /* Complete ~user only if it partially matches a user name.
- * A full match ~user<Tab> will be replaced by user's home
- * directory i.e. something like ~user<Tab> -> /home/user/ */
- if (*p == NUL && p > xp->xp_pattern + 1
- && match_user(xp->xp_pattern + 1) == 1) {
+ for (p = (const char *)xp->xp_pattern + 1; *p != NUL && *p != '/'; p++) {
+ }
+ // Complete ~user only if it partially matches a user name.
+ // A full match ~user<Tab> will be replaced by user's home
+ // directory i.e. something like ~user<Tab> -> /home/user/
+ if (*p == NUL && p > (const char *)xp->xp_pattern + 1
+ && match_user(xp->xp_pattern + 1) >= 1) {
xp->xp_context = EXPAND_USER;
++xp->xp_pattern;
}
@@ -2968,7 +3021,7 @@ set_one_cmd_context (
break;
case CMD_help:
xp->xp_context = EXPAND_HELP;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
/* Command modifiers: return the argument.
@@ -3007,17 +3060,28 @@ set_one_cmd_context (
case CMD_windo:
return arg;
+ case CMD_filter:
+ if (*arg != NUL) {
+ arg = (const char *)skip_vimgrep_pat((char_u *)arg, NULL, NULL);
+ }
+ if (arg == NULL || *arg == NUL) {
+ xp->xp_context = EXPAND_NOTHING;
+ return NULL;
+ }
+ return (const char *)skipwhite((const char_u *)arg);
+
case CMD_match:
if (*arg == NUL || !ends_excmd(*arg)) {
/* also complete "None" */
set_context_in_echohl_cmd(xp, arg);
- arg = skipwhite(skiptowhite(arg));
+ arg = (const char *)skipwhite(skiptowhite((const char_u *)arg));
if (*arg != NUL) {
xp->xp_context = EXPAND_NOTHING;
- arg = skip_regexp(arg + 1, *arg, p_magic, NULL);
+ arg = (const char *)skip_regexp((char_u *)arg + 1, (uint8_t)(*arg),
+ p_magic, NULL);
}
}
- return find_nextcmd(arg);
+ return (const char *)find_nextcmd((char_u *)arg);
/*
* All completion for the +cmdline_compl feature goes here.
@@ -3026,15 +3090,15 @@ set_one_cmd_context (
case CMD_command:
/* Check for attributes */
while (*arg == '-') {
- arg++; /* Skip "-" */
- p = skiptowhite(arg);
+ arg++; // Skip "-".
+ p = (const char *)skiptowhite((const char_u *)arg);
if (*p == NUL) {
- /* Cursor is still in the attribute */
- p = vim_strchr(arg, '=');
+ // Cursor is still in the attribute.
+ p = strchr(arg, '=');
if (p == NULL) {
- /* No "=", so complete attribute names */
+ // No "=", so complete attribute names.
xp->xp_context = EXPAND_USER_CMD_FLAGS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
return NULL;
}
@@ -3042,73 +3106,81 @@ set_one_cmd_context (
// their arguments as well.
if (STRNICMP(arg, "complete", p - arg) == 0) {
xp->xp_context = EXPAND_USER_COMPLETE;
- xp->xp_pattern = p + 1;
+ xp->xp_pattern = (char_u *)p + 1;
return NULL;
} else if (STRNICMP(arg, "nargs", p - arg) == 0) {
xp->xp_context = EXPAND_USER_NARGS;
- xp->xp_pattern = p + 1;
+ xp->xp_pattern = (char_u *)p + 1;
return NULL;
} else if (STRNICMP(arg, "addr", p - arg) == 0) {
xp->xp_context = EXPAND_USER_ADDR_TYPE;
- xp->xp_pattern = p + 1;
+ xp->xp_pattern = (char_u *)p + 1;
return NULL;
}
return NULL;
}
- arg = skipwhite(p);
+ arg = (const char *)skipwhite((char_u *)p);
}
- /* After the attributes comes the new command name */
- p = skiptowhite(arg);
+ // After the attributes comes the new command name.
+ p = (const char *)skiptowhite((const char_u *)arg);
if (*p == NUL) {
xp->xp_context = EXPAND_USER_COMMANDS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
}
- /* And finally comes a normal command */
- return skipwhite(p);
+ // And finally comes a normal command.
+ return (const char *)skipwhite((const char_u *)p);
case CMD_delcommand:
xp->xp_context = EXPAND_USER_COMMANDS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_global:
- case CMD_vglobal:
- delim = *arg; /* get the delimiter */
- if (delim)
- ++arg; /* skip delimiter if there is one */
+ case CMD_vglobal: {
+ const int delim = (uint8_t)(*arg); // Get the delimiter.
+ if (delim) {
+ arg++; // Skip delimiter if there is one.
+ }
- while (arg[0] != NUL && arg[0] != delim) {
- if (arg[0] == '\\' && arg[1] != NUL)
- ++arg;
- ++arg;
+ while (arg[0] != NUL && (uint8_t)arg[0] != delim) {
+ if (arg[0] == '\\' && arg[1] != NUL) {
+ arg++;
+ }
+ arg++;
}
if (arg[0] != NUL)
return arg + 1;
break;
+ }
case CMD_and:
- case CMD_substitute:
- delim = *arg;
+ case CMD_substitute: {
+ const int delim = (uint8_t)(*arg);
if (delim) {
- /* skip "from" part */
- ++arg;
- arg = skip_regexp(arg, delim, p_magic, NULL);
+ // Skip "from" part.
+ arg++;
+ arg = (const char *)skip_regexp((char_u *)arg, delim, p_magic, NULL);
}
- /* skip "to" part */
- while (arg[0] != NUL && arg[0] != delim) {
- if (arg[0] == '\\' && arg[1] != NUL)
- ++arg;
- ++arg;
+ // Skip "to" part.
+ while (arg[0] != NUL && (uint8_t)arg[0] != delim) {
+ if (arg[0] == '\\' && arg[1] != NUL) {
+ arg++;
+ }
+ arg++;
}
- if (arg[0] != NUL) /* skip delimiter */
- ++arg;
- while (arg[0] && vim_strchr((char_u *)"|\"#", arg[0]) == NULL)
- ++arg;
- if (arg[0] != NUL)
+ if (arg[0] != NUL) { // Skip delimiter.
+ arg++;
+ }
+ while (arg[0] && strchr("|\"#", arg[0]) == NULL) {
+ arg++;
+ }
+ if (arg[0] != NUL) {
return arg;
+ }
break;
+ }
case CMD_isearch:
case CMD_dsearch:
case CMD_ilist:
@@ -3118,36 +3190,40 @@ set_one_cmd_context (
case CMD_djump:
case CMD_isplit:
case CMD_dsplit:
- arg = skipwhite(skipdigits(arg)); /* skip count */
- if (*arg == '/') { /* Match regexp, not just whole words */
- for (++arg; *arg && *arg != '/'; arg++)
- if (*arg == '\\' && arg[1] != NUL)
+ // Skip count.
+ arg = (const char *)skipwhite(skipdigits((const char_u *)arg));
+ if (*arg == '/') { // Match regexp, not just whole words.
+ for (++arg; *arg && *arg != '/'; arg++) {
+ if (*arg == '\\' && arg[1] != NUL) {
arg++;
+ }
+ }
if (*arg) {
- arg = skipwhite(arg + 1);
+ arg = (const char *)skipwhite((const char_u *)arg + 1);
- /* Check for trailing illegal characters */
- if (*arg && vim_strchr((char_u *)"|\"\n", *arg) == NULL)
+ // Check for trailing illegal characters.
+ if (*arg && strchr("|\"\n", *arg) == NULL) {
xp->xp_context = EXPAND_NOTHING;
- else
+ } else {
return arg;
+ }
}
}
break;
case CMD_autocmd:
- return set_context_in_autocmd(xp, arg, FALSE);
+ return (const char *)set_context_in_autocmd(xp, (char_u *)arg, false);
case CMD_doautocmd:
case CMD_doautoall:
- return set_context_in_autocmd(xp, arg, TRUE);
+ return (const char *)set_context_in_autocmd(xp, (char_u *)arg, true);
case CMD_set:
- set_context_in_set_cmd(xp, arg, 0);
+ set_context_in_set_cmd(xp, (char_u *)arg, 0);
break;
case CMD_setglobal:
- set_context_in_set_cmd(xp, arg, OPT_GLOBAL);
+ set_context_in_set_cmd(xp, (char_u *)arg, OPT_GLOBAL);
break;
case CMD_setlocal:
- set_context_in_set_cmd(xp, arg, OPT_LOCAL);
+ set_context_in_set_cmd(xp, (char_u *)arg, OPT_LOCAL);
break;
case CMD_tag:
case CMD_stag:
@@ -3159,15 +3235,16 @@ set_one_cmd_context (
case CMD_tjump:
case CMD_stjump:
case CMD_ptjump:
- if (*p_wop != NUL)
+ if (*p_wop != NUL) {
xp->xp_context = EXPAND_TAGS_LISTFILES;
- else
+ } else {
xp->xp_context = EXPAND_TAGS;
- xp->xp_pattern = arg;
+ }
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_augroup:
xp->xp_context = EXPAND_AUGROUP;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_syntax:
set_context_in_syntax_cmd(xp, arg);
@@ -3184,20 +3261,34 @@ set_one_cmd_context (
case CMD_echoerr:
case CMD_call:
case CMD_return:
- set_context_for_expression(xp, arg, ea.cmdidx);
+ case CMD_cexpr:
+ case CMD_caddexpr:
+ case CMD_cgetexpr:
+ case CMD_lexpr:
+ case CMD_laddexpr:
+ case CMD_lgetexpr:
+ set_context_for_expression(xp, (char_u *)arg, ea.cmdidx);
break;
case CMD_unlet:
- while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
- arg = xp->xp_pattern + 1;
+ while ((xp->xp_pattern = (char_u *)strchr(arg, ' ')) != NULL) {
+ arg = (const char *)xp->xp_pattern + 1;
+ }
+
xp->xp_context = EXPAND_USER_VARS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
+
+ if (*xp->xp_pattern == '$') {
+ xp->xp_context = EXPAND_ENV_VARS;
+ xp->xp_pattern++;
+ }
+
break;
case CMD_function:
case CMD_delfunction:
xp->xp_context = EXPAND_USER_FUNC;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_echohl:
@@ -3212,45 +3303,50 @@ set_one_cmd_context (
set_context_in_cscope_cmd(xp, arg, ea.cmdidx);
break;
case CMD_sign:
- set_context_in_sign_cmd(xp, arg);
+ set_context_in_sign_cmd(xp, (char_u *)arg);
break;
case CMD_bdelete:
case CMD_bwipeout:
case CMD_bunload:
- while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
- arg = xp->xp_pattern + 1;
- /*FALLTHROUGH*/
+ while ((xp->xp_pattern = (char_u *)strchr(arg, ' ')) != NULL) {
+ arg = (const char *)xp->xp_pattern + 1;
+ }
+ FALLTHROUGH;
case CMD_buffer:
case CMD_sbuffer:
case CMD_checktime:
xp->xp_context = EXPAND_BUFFERS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_USER:
case CMD_USER_BUF:
- if (compl != EXPAND_NOTHING) {
- /* XFILE: file names are handled above */
+ if (context != EXPAND_NOTHING) {
+ // XFILE: file names are handled above.
if (!(ea.argt & XFILE)) {
- if (compl == EXPAND_MENUS)
- return set_context_in_menu_cmd(xp, cmd, arg, forceit);
- if (compl == EXPAND_COMMANDS)
+ if (context == EXPAND_MENUS) {
+ return (const char *)set_context_in_menu_cmd(xp, (char_u *)cmd,
+ (char_u *)arg, forceit);
+ } else if (context == EXPAND_COMMANDS) {
return arg;
- if (compl == EXPAND_MAPPINGS)
- return set_context_in_map_cmd(xp, (char_u *)"map",
- arg, forceit, FALSE, FALSE, CMD_map);
- /* Find start of last argument. */
+ } else if (context == EXPAND_MAPPINGS) {
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)"map", (char_u *)arg, forceit, false, false,
+ CMD_map);
+ }
+ // Find start of last argument.
p = arg;
while (*p) {
- if (*p == ' ')
- /* argument starts after a space */
+ if (*p == ' ') {
+ // argument starts after a space
arg = p + 1;
- else if (*p == '\\' && *(p + 1) != NUL)
- ++p; /* skip over escaped character */
- mb_ptr_adv(p);
+ } else if (*p == '\\' && *(p + 1) != NUL) {
+ p++; // skip over escaped character
+ }
+ MB_PTR_ADV(p);
}
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
}
- xp->xp_context = compl;
+ xp->xp_context = context;
}
break;
case CMD_map: case CMD_noremap:
@@ -3262,8 +3358,8 @@ set_one_cmd_context (
case CMD_lmap: case CMD_lnoremap:
case CMD_smap: case CMD_snoremap:
case CMD_xmap: case CMD_xnoremap:
- return set_context_in_map_cmd(xp, cmd, arg, forceit,
- FALSE, FALSE, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit, false, false, ea.cmdidx);
case CMD_unmap:
case CMD_nunmap:
case CMD_vunmap:
@@ -3273,18 +3369,31 @@ set_one_cmd_context (
case CMD_lunmap:
case CMD_sunmap:
case CMD_xunmap:
- return set_context_in_map_cmd(xp, cmd, arg, forceit,
- FALSE, TRUE, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit, false, true, ea.cmdidx);
+ case CMD_mapclear:
+ case CMD_nmapclear:
+ case CMD_vmapclear:
+ case CMD_omapclear:
+ case CMD_imapclear:
+ case CMD_cmapclear:
+ case CMD_lmapclear:
+ case CMD_smapclear:
+ case CMD_xmapclear:
+ xp->xp_context = EXPAND_MAPCLEAR;
+ xp->xp_pattern = (char_u *)arg;
+ break;
+
case CMD_abbreviate: case CMD_noreabbrev:
case CMD_cabbrev: case CMD_cnoreabbrev:
case CMD_iabbrev: case CMD_inoreabbrev:
- return set_context_in_map_cmd(xp, cmd, arg, forceit,
- TRUE, FALSE, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit, true, false, ea.cmdidx);
case CMD_unabbreviate:
case CMD_cunabbrev:
case CMD_iunabbrev:
- return set_context_in_map_cmd(xp, cmd, arg, forceit,
- TRUE, TRUE, ea.cmdidx);
+ return (const char *)set_context_in_map_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit, true, true, ea.cmdidx);
case CMD_menu: case CMD_noremenu: case CMD_unmenu:
case CMD_amenu: case CMD_anoremenu: case CMD_aunmenu:
case CMD_nmenu: case CMD_nnoremenu: case CMD_nunmenu:
@@ -3294,67 +3403,85 @@ set_one_cmd_context (
case CMD_cmenu: case CMD_cnoremenu: case CMD_cunmenu:
case CMD_tmenu: case CMD_tunmenu:
case CMD_popup: case CMD_emenu:
- return set_context_in_menu_cmd(xp, cmd, arg, forceit);
+ return (const char *)set_context_in_menu_cmd(
+ xp, (char_u *)cmd, (char_u *)arg, forceit);
case CMD_colorscheme:
xp->xp_context = EXPAND_COLORS;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_compiler:
xp->xp_context = EXPAND_COMPILER;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_ownsyntax:
xp->xp_context = EXPAND_OWNSYNTAX;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_setfiletype:
xp->xp_context = EXPAND_FILETYPE;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_packadd:
xp->xp_context = EXPAND_PACKADD;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
#ifdef HAVE_WORKING_LIBINTL
case CMD_language:
- p = skiptowhite(arg);
+ p = (const char *)skiptowhite((const char_u *)arg);
if (*p == NUL) {
xp->xp_context = EXPAND_LANGUAGE;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
} else {
- if ( STRNCMP(arg, "messages", p - arg) == 0
- || STRNCMP(arg, "ctype", p - arg) == 0
- || STRNCMP(arg, "time", p - arg) == 0) {
+ if (strncmp(arg, "messages", p - arg) == 0
+ || strncmp(arg, "ctype", p - arg) == 0
+ || strncmp(arg, "time", p - arg) == 0) {
xp->xp_context = EXPAND_LOCALES;
- xp->xp_pattern = skipwhite(p);
- } else
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ } else {
xp->xp_context = EXPAND_NOTHING;
+ }
}
break;
#endif
case CMD_profile:
set_context_in_profile_cmd(xp, arg);
break;
+ case CMD_checkhealth:
+ xp->xp_context = EXPAND_CHECKHEALTH;
+ xp->xp_pattern = (char_u *)arg;
+ break;
case CMD_behave:
xp->xp_context = EXPAND_BEHAVE;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
+ break;
+
+ case CMD_messages:
+ xp->xp_context = EXPAND_MESSAGES;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_history:
xp->xp_context = EXPAND_HISTORY;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
case CMD_syntime:
xp->xp_context = EXPAND_SYNTIME;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
break;
+ case CMD_argdelete:
+ while ((xp->xp_pattern = vim_strchr((const char_u *)arg, ' ')) != NULL) {
+ arg = (const char *)(xp->xp_pattern + 1);
+ }
+ xp->xp_context = EXPAND_ARGLIST;
+ xp->xp_pattern = (char_u *)arg;
+ break;
default:
break;
@@ -3371,18 +3498,24 @@ set_one_cmd_context (
* Also skip white space and ":" characters.
* Returns the "cmd" pointer advanced to beyond the range.
*/
-char_u *
-skip_range (
- char_u *cmd,
- int *ctx /* pointer to xp_context or NULL */
+char_u *skip_range(
+ const char_u *cmd,
+ int *ctx // pointer to xp_context or NULL
)
{
unsigned delim;
- while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;", *cmd) != NULL) {
- if (*cmd == '\'') {
- if (*++cmd == NUL && ctx != NULL)
+ while (vim_strchr((char_u *)" \t0123456789.$%'/?-+,;\\", *cmd) != NULL) {
+ if (*cmd == '\\') {
+ if (cmd[1] == '?' || cmd[1] == '/' || cmd[1] == '&') {
+ cmd++;
+ } else {
+ break;
+ }
+ } else if (*cmd == '\'') {
+ if (*++cmd == NUL && ctx != NULL) {
*ctx = EXPAND_NOTHING;
+ }
} else if (*cmd == '/' || *cmd == '?') {
delim = *cmd++;
while (*cmd != NUL && *cmd != delim)
@@ -3399,7 +3532,7 @@ skip_range (
while (*cmd == ':')
cmd = skipwhite(cmd + 1);
- return cmd;
+ return (char_u *)cmd;
}
/*
@@ -3414,8 +3547,8 @@ static linenr_T get_address(exarg_T *eap,
char_u **ptr,
int addr_type, // flag: one of ADDR_LINES, ...
int skip, // only skip the address, don't use it
- int to_other_file // flag: may jump to other file
- )
+ int to_other_file, // flag: may jump to other file
+ int address_count) // 1 for first, >1 after comma
{
int c;
int i;
@@ -3449,6 +3582,11 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
+ case ADDR_TABS_RELATIVE:
+ EMSG(_(e_invrange));
+ cmd = NULL;
+ goto error;
+ break;
case ADDR_QUICKFIX:
lnum = qf_get_cur_valid_idx(eap);
break;
@@ -3483,6 +3621,11 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS:
lnum = LAST_TAB_NR;
break;
+ case ADDR_TABS_RELATIVE:
+ EMSG(_(e_invrange));
+ cmd = NULL;
+ goto error;
+ break;
case ADDR_QUICKFIX:
lnum = qf_get_size(eap);
if (lnum == 0) {
@@ -3542,17 +3685,18 @@ static linenr_T get_address(exarg_T *eap,
*/
if (lnum != MAXLNUM)
curwin->w_cursor.lnum = lnum;
- /*
- * Start a forward search at the end of the line.
- * Start a backward search at the start of the line.
- * This makes sure we never match in the current
- * line, and can match anywhere in the
- * next/previous line.
- */
- if (c == '/')
+
+ // Start a forward search at the end of the line (unless
+ // before the first line).
+ // Start a backward search at the start of the line.
+ // This makes sure we never match in the current
+ // line, and can match anywhere in the
+ // next/previous line.
+ if (c == '/' && curwin->w_cursor.lnum > 0) {
curwin->w_cursor.col = MAXCOL;
- else
+ } else {
curwin->w_cursor.col = 0;
+ }
searchcmdlen = 0;
if (!do_search(NULL, c, cmd, 1L,
SEARCH_HIS | SEARCH_MSG, NULL)) {
@@ -3631,6 +3775,9 @@ static linenr_T get_address(exarg_T *eap,
case ADDR_TABS:
lnum = CURRENT_TAB_NR;
break;
+ case ADDR_TABS_RELATIVE:
+ lnum = 1;
+ break;
case ADDR_QUICKFIX:
lnum = qf_get_cur_valid_idx(eap);
break;
@@ -3645,13 +3792,27 @@ static linenr_T get_address(exarg_T *eap,
n = 1;
else
n = getdigits(&cmd);
- if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS)
+
+ if (addr_type == ADDR_TABS_RELATIVE) {
+ EMSG(_(e_invrange));
+ cmd = NULL;
+ goto error;
+ } else if (addr_type == ADDR_LOADED_BUFFERS || addr_type == ADDR_BUFFERS) {
lnum = compute_buffer_local_count(
addr_type, lnum, (i == '-') ? -1 * n : n);
- else if (i == '-')
- lnum -= n;
- else
- lnum += n;
+ } else {
+ // Relative line addressing, need to adjust for folded lines
+ // now, but only do it after the first address.
+ if (addr_type == ADDR_LINES && (i == '-' || i == '+')
+ && address_count >= 2) {
+ (void)hasFolding(lnum, NULL, &lnum);
+ }
+ if (i == '-') {
+ lnum -= n;
+ } else {
+ lnum += n;
+ }
+ }
}
} while (*cmd == '/' || *cmd == '?');
@@ -3688,10 +3849,12 @@ void ex_ni(exarg_T *eap)
/// Skips over ":perl <<EOF" constructs.
static void ex_script_ni(exarg_T *eap)
{
- if (!eap->skip)
+ if (!eap->skip) {
ex_ni(eap);
- else
- xfree(script_get(eap, eap->arg));
+ } else {
+ size_t len;
+ xfree(script_get(eap, &len));
+ }
}
/*
@@ -3758,6 +3921,9 @@ static char_u *invalid_range(exarg_T *eap)
return (char_u *)_(e_invrange);
}
break;
+ case ADDR_TABS_RELATIVE:
+ // Do nothing
+ break;
case ADDR_QUICKFIX:
assert(eap->line2 >= 0);
if (eap->line2 != 1 && (size_t)eap->line2 > qf_get_size(eap)) {
@@ -3848,7 +4014,7 @@ static char_u *replace_makeprg(exarg_T *eap, char_u *p, char_u **cmdlinep)
ptr = new_cmdline;
while ((pos = (char_u *)strstr((char *)program, "$*")) != NULL) {
i = (int)(pos - program);
- STRNCPY(ptr, program, i);
+ memcpy(ptr, program, i);
STRCPY(ptr += i, p);
ptr += len;
program = pos + 2;
@@ -3934,8 +4100,6 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
* Don't do this for:
* - replacement that already has been escaped: "##"
* - shell commands (may have to use quotes instead).
- * - non-unix systems when there is a single argument (spaces don't
- * separate arguments then).
*/
if (!eap->usefilter
&& !escaped
@@ -3946,9 +4110,8 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
&& eap->cmdidx != CMD_lgrep
&& eap->cmdidx != CMD_grepadd
&& eap->cmdidx != CMD_lgrepadd
-#ifndef UNIX
+ && eap->cmdidx != CMD_hardcopy
&& !(eap->argt & NOSPC)
-#endif
) {
char_u *l;
#ifdef BACKSLASH_IN_FILENAME
@@ -4010,28 +4173,6 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
}
}
- // Replace any other wildcards, remove backslashes.
-#ifdef UNIX
- /*
- * Only for Unix we check for more than one file name.
- * For other systems spaces are considered to be part
- * of the file name.
- * Only check here if there is no wildcard, otherwise
- * ExpandOne() will check for errors. This allows
- * ":e `ls ve*.c`" on Unix.
- */
- if (!has_wildcards)
- for (p = eap->arg; *p; ++p) {
- /* skip escaped characters */
- if (p[1] && (*p == '\\' || *p == Ctrl_V))
- ++p;
- else if (ascii_iswhite(*p)) {
- *errormsgp = (char_u *)_("E172: Only one file name allowed");
- return FAIL;
- }
- }
-#endif
-
/*
* Halve the number of backslashes (this is Vi compatible).
* For Unix, when wildcards are expanded, this is
@@ -4050,14 +4191,12 @@ int expand_filename(exarg_T *eap, char_u **cmdlinep, char_u **errormsgp)
xpc.xp_context = EXPAND_FILES;
if (p_wic)
options += WILD_ICASE;
- p = ExpandOne(&xpc, eap->arg, NULL,
- options, WILD_EXPAND_FREE);
- if (p == NULL)
+ p = ExpandOne(&xpc, eap->arg, NULL, options, WILD_EXPAND_FREE);
+ if (p == NULL) {
return FAIL;
- if (p != NULL) {
- (void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg), p, cmdlinep);
- xfree(p);
}
+ (void)repl_cmdline(eap, eap->arg, STRLEN(eap->arg), p, cmdlinep);
+ xfree(p);
}
}
return OK;
@@ -4122,7 +4261,7 @@ void separate_nextcmd(exarg_T *eap)
p = skip_grep_pat(eap);
- for (; *p; mb_ptr_adv(p)) {
+ for (; *p; MB_PTR_ADV(p)) {
if (*p == Ctrl_V) {
if (eap->argt & (USECTRLV | XFILE))
++p; /* skip CTRL-V and next char */
@@ -4206,7 +4345,7 @@ skip_cmd_arg (
else
++p;
}
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
return p;
}
@@ -4292,6 +4431,89 @@ static int getargopt(exarg_T *eap)
return OK;
}
+/// Handle the argument for a tabpage related ex command.
+/// Returns a tabpage number.
+/// When an error is encountered then eap->errmsg is set.
+static int get_tabpage_arg(exarg_T *eap)
+{
+ int tab_number = 0;
+ int unaccept_arg0 = (eap->cmdidx == CMD_tabmove) ? 0 : 1;
+
+ if (eap->arg && *eap->arg != NUL) {
+ char_u *p = eap->arg;
+ char_u *p_save;
+ int relative = 0; // argument +N/-N means: go to N places to the
+ // right/left relative to the current position.
+
+ if (*p == '-') {
+ relative = -1;
+ p++;
+ } else if (*p == '+') {
+ relative = 1;
+ p++;
+ }
+
+ p_save = p;
+ tab_number = getdigits(&p);
+
+ if (relative == 0) {
+ if (STRCMP(p, "$") == 0) {
+ tab_number = LAST_TAB_NR;
+ } else if (p == p_save || *p_save == '-' || *p != NUL
+ || tab_number > LAST_TAB_NR) {
+ // No numbers as argument.
+ eap->errmsg = e_invarg;
+ goto theend;
+ }
+ } else {
+ if (*p_save == NUL) {
+ tab_number = 1;
+ }
+ else if (p == p_save || *p_save == '-' || *p != NUL || tab_number == 0) {
+ // No numbers as argument.
+ eap->errmsg = e_invarg;
+ goto theend;
+ }
+ tab_number = tab_number * relative + tabpage_index(curtab);
+ if (!unaccept_arg0 && relative == -1) {
+ --tab_number;
+ }
+ }
+ if (tab_number < unaccept_arg0 || tab_number > LAST_TAB_NR) {
+ eap->errmsg = e_invarg;
+ }
+ } else if (eap->addr_count > 0) {
+ if (unaccept_arg0 && eap->line2 == 0) {
+ eap->errmsg = e_invrange;
+ tab_number = 0;
+ } else {
+ tab_number = eap->line2;
+ if (!unaccept_arg0 && **eap->cmdlinep == '-') {
+ --tab_number;
+ if (tab_number < unaccept_arg0) {
+ eap->errmsg = e_invarg;
+ }
+ }
+ }
+ } else {
+ switch (eap->cmdidx) {
+ case CMD_tabnext:
+ tab_number = tabpage_index(curtab) + 1;
+ if (tab_number > LAST_TAB_NR)
+ tab_number = 1;
+ break;
+ case CMD_tabmove:
+ tab_number = LAST_TAB_NR;
+ break;
+ default:
+ tab_number = tabpage_index(curtab);
+ }
+ }
+
+theend:
+ return tab_number;
+}
+
/*
* ":abbreviate" and friends.
*/
@@ -4361,12 +4583,15 @@ static void ex_autocmd(exarg_T *eap)
*/
static void ex_doautocmd(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = eap->arg;
int call_do_modelines = check_nomodeline(&arg);
+ bool did_aucmd;
- (void)do_doautocmd(arg, TRUE);
- if (call_do_modelines) /* Only when there is no <nomodeline>. */
+ (void)do_doautocmd(arg, true, &did_aucmd);
+ // Only when there is no <nomodeline>.
+ if (call_do_modelines && did_aucmd) {
do_modelines(0);
+ }
}
/*
@@ -4476,27 +4701,28 @@ int ends_excmd(int c) FUNC_ATTR_CONST
* Return the next command, after the first '|' or '\n'.
* Return NULL if not found.
*/
-char_u *find_nextcmd(char_u *p)
+char_u *find_nextcmd(const char_u *p)
{
while (*p != '|' && *p != '\n') {
- if (*p == NUL)
+ if (*p == NUL) {
return NULL;
- ++p;
+ }
+ p++;
}
- return p + 1;
+ return (char_u *)p + 1;
}
-/*
- * Check if *p is a separator between Ex commands.
- * Return NULL if it isn't, (p + 1) if it is.
- */
+/// Check if *p is a separator between Ex commands, skipping over white space.
+/// Return NULL if it isn't, the following character if it is.
char_u *check_nextcmd(char_u *p)
{
- p = skipwhite(p);
- if (*p == '|' || *p == '\n')
- return p + 1;
- else
- return NULL;
+ char_u *s = skipwhite(p);
+
+ if (*s == '|' || *s == '\n') {
+ return (s + 1);
+ } else {
+ return NULL;
+ }
}
/*
@@ -4507,9 +4733,9 @@ char_u *check_nextcmd(char_u *p)
* return FAIL and give error message if 'message' TRUE
* return OK otherwise
*/
-static int
-check_more (
- int message, /* when FALSE check only, no messages */
+static int
+check_more(
+ int message, // when FALSE check only, no messages
int forceit
)
{
@@ -4563,7 +4789,7 @@ static int uc_add_command(char_u *name, size_t name_len, char_u *rep,
char_u *rep_buf = NULL;
garray_T *gap;
- replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, false,
+ replace_termcodes(rep, STRLEN(rep), &rep_buf, false, false, true,
CPO_TO_CPO_FLAGS);
if (rep_buf == NULL) {
/* Can't replace termcodes - try using the string as is */
@@ -4660,49 +4886,58 @@ static struct {
* List of names for completion for ":command" with the EXPAND_ flag.
* Must be alphabetical for completion.
*/
-static struct {
- int expand;
- char *name;
-} command_complete[] =
-{
- { EXPAND_AUGROUP, "augroup" },
- { EXPAND_BEHAVE, "behave" },
- { EXPAND_BUFFERS, "buffer" },
- { EXPAND_COLORS, "color" },
- { EXPAND_COMMANDS, "command" },
- { EXPAND_COMPILER, "compiler" },
- { EXPAND_CSCOPE, "cscope" },
- { EXPAND_USER_DEFINED, "custom" },
- { EXPAND_USER_LIST, "customlist" },
- { EXPAND_DIRECTORIES, "dir" },
- { EXPAND_ENV_VARS, "environment" },
- { EXPAND_EVENTS, "event" },
- { EXPAND_EXPRESSION, "expression" },
- { EXPAND_FILES, "file" },
- { EXPAND_FILES_IN_PATH, "file_in_path" },
- { EXPAND_FILETYPE, "filetype" },
- { EXPAND_FUNCTIONS, "function" },
- { EXPAND_HELP, "help" },
- { EXPAND_HIGHLIGHT, "highlight" },
- { EXPAND_HISTORY, "history" },
+static const char *command_complete[] =
+{
+ [EXPAND_ARGLIST] = "arglist",
+ [EXPAND_AUGROUP] = "augroup",
+ [EXPAND_BEHAVE] = "behave",
+ [EXPAND_BUFFERS] = "buffer",
+ [EXPAND_CHECKHEALTH] = "checkhealth",
+ [EXPAND_COLORS] = "color",
+ [EXPAND_COMMANDS] = "command",
+ [EXPAND_COMPILER] = "compiler",
+ [EXPAND_CSCOPE] = "cscope",
+ [EXPAND_USER_DEFINED] = "custom",
+ [EXPAND_USER_LIST] = "customlist",
+ [EXPAND_DIRECTORIES] = "dir",
+ [EXPAND_ENV_VARS] = "environment",
+ [EXPAND_EVENTS] = "event",
+ [EXPAND_EXPRESSION] = "expression",
+ [EXPAND_FILES] = "file",
+ [EXPAND_FILES_IN_PATH] = "file_in_path",
+ [EXPAND_FILETYPE] = "filetype",
+ [EXPAND_FUNCTIONS] = "function",
+ [EXPAND_HELP] = "help",
+ [EXPAND_HIGHLIGHT] = "highlight",
+ [EXPAND_HISTORY] = "history",
#ifdef HAVE_WORKING_LIBINTL
- { EXPAND_LOCALES, "locale" },
+ [EXPAND_LOCALES] = "locale",
#endif
- { EXPAND_MAPPINGS, "mapping" },
- { EXPAND_MENUS, "menu" },
- { EXPAND_OWNSYNTAX, "syntax" },
- { EXPAND_SYNTIME, "syntime" },
- { EXPAND_SETTINGS, "option" },
- { EXPAND_PACKADD, "packadd" },
- { EXPAND_SHELLCMD, "shellcmd" },
- { EXPAND_SIGN, "sign" },
- { EXPAND_TAGS, "tag" },
- { EXPAND_TAGS_LISTFILES, "tag_listfiles" },
- { EXPAND_USER, "user" },
- { EXPAND_USER_VARS, "var" },
- { 0, NULL }
+ [EXPAND_MAPCLEAR] = "mapclear",
+ [EXPAND_MAPPINGS] = "mapping",
+ [EXPAND_MENUS] = "menu",
+ [EXPAND_MESSAGES] = "messages",
+ [EXPAND_OWNSYNTAX] = "syntax",
+ [EXPAND_SYNTIME] = "syntime",
+ [EXPAND_SETTINGS] = "option",
+ [EXPAND_PACKADD] = "packadd",
+ [EXPAND_SHELLCMD] = "shellcmd",
+ [EXPAND_SIGN] = "sign",
+ [EXPAND_TAGS] = "tag",
+ [EXPAND_TAGS_LISTFILES] = "tag_listfiles",
+ [EXPAND_USER] = "user",
+ [EXPAND_USER_VARS] = "var",
};
+static char *get_command_complete(int arg)
+{
+ if (arg >= (int)(ARRAY_SIZE(command_complete))) {
+ return NULL;
+ } else {
+ return (char *)command_complete[arg];
+ }
+}
+
static void uc_list(char_u *name, size_t name_len)
{
int i, j;
@@ -4718,9 +4953,12 @@ static void uc_list(char_u *name, size_t name_len)
cmd = USER_CMD_GA(gap, i);
a = cmd->uc_argt;
- /* Skip commands which don't match the requested prefix */
- if (STRNCMP(name, cmd->uc_name, name_len) != 0)
+ // Skip commands which don't match the requested prefix and
+ // commands filtered out.
+ if (STRNCMP(name, cmd->uc_name, name_len) != 0
+ || message_filtered(cmd->uc_name)) {
continue;
+ }
/* Put out the title first time */
if (!found)
@@ -4736,7 +4974,7 @@ static void uc_list(char_u *name, size_t name_len)
msg_putchar(gap != &ucmds ? 'b' : ' ');
msg_putchar(' ');
- msg_outtrans_attr(cmd->uc_name, hl_attr(HLF_D));
+ msg_outtrans_attr(cmd->uc_name, HL_ATTR(HLF_D));
len = (int)STRLEN(cmd->uc_name) + 4;
do {
@@ -4793,13 +5031,12 @@ static void uc_list(char_u *name, size_t name_len)
IObuff[len++] = ' ';
} while (len < 21);
- /* Completion */
- for (j = 0; command_complete[j].expand != 0; ++j)
- if (command_complete[j].expand == cmd->uc_compl) {
- STRCPY(IObuff + len, command_complete[j].name);
- len += (int)STRLEN(IObuff + len);
- break;
- }
+ // Completion
+ char *cmd_compl = get_command_complete(cmd->uc_compl);
+ if (cmd_compl != NULL) {
+ STRCPY(IObuff + len, get_command_complete(cmd->uc_compl));
+ len += (int)STRLEN(IObuff + len);
+ }
do {
IObuff[len++] = ' ';
@@ -4825,20 +5062,6 @@ static void uc_list(char_u *name, size_t name_len)
MSG(_("No user-defined commands found"));
}
-static char_u *uc_fun_cmd(void)
-{
- static char_u fcmd[] = {0x84, 0xaf, 0x60, 0xb9, 0xaf, 0xb5, 0x60, 0xa4,
- 0xa5, 0xad, 0xa1, 0xae, 0xa4, 0x60, 0xa1, 0x60,
- 0xb3, 0xa8, 0xb2, 0xb5, 0xa2, 0xa2, 0xa5, 0xb2,
- 0xb9, 0x7f, 0};
- int i;
-
- for (i = 0; fcmd[i]; ++i)
- IObuff[i] = fcmd[i] - 0x40;
- IObuff[i] = 0;
- return IObuff;
-}
-
static int uc_scan_attr(char_u *attr, size_t len, uint32_t *argt, long *def,
int *flags, int * compl, char_u **compl_arg,
int *addr_type_arg)
@@ -4987,17 +5210,20 @@ static void ex_command(exarg_T *eap)
while (*p == '-') {
++p;
end = skiptowhite(p);
- if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg, &addr_type_arg)
- == FAIL)
+ if (uc_scan_attr(p, end - p, &argt, &def, &flags, &compl, &compl_arg,
+ &addr_type_arg) == FAIL) {
return;
+ }
p = skipwhite(end);
}
- /* Get the name (if any) and skip to the following argument */
+ // Get the name (if any) and skip to the following argument.
name = p;
- if (ASCII_ISALPHA(*p))
- while (ASCII_ISALNUM(*p))
- ++p;
+ if (ASCII_ISALPHA(*p)) {
+ while (ASCII_ISALNUM(*p)) {
+ p++;
+ }
+ }
if (!ends_excmd(*p) && !ascii_iswhite(*p)) {
EMSG(_("E182: Invalid command name"));
return;
@@ -5015,13 +5241,13 @@ static void ex_command(exarg_T *eap)
EMSG(_("E183: User defined commands must start with an uppercase letter"));
return;
} else if ((name_len == 1 && *name == 'X')
- || (name_len <= 4
- && STRNCMP(name, "Next", name_len > 4 ? 4 : name_len) == 0)) {
+ || (name_len <= 4 && STRNCMP(name, "Next", name_len) == 0)) {
EMSG(_("E841: Reserved name, cannot be used for user defined command"));
return;
- } else
+ } else {
uc_add_command(name, end - name, p, argt, def, flags, compl, compl_arg,
addr_type_arg, eap->forceit);
+ }
}
/*
@@ -5153,6 +5379,24 @@ static char_u *uc_split_args(char_u *arg, size_t *lenp)
return buf;
}
+static size_t add_cmd_modifier(char_u *buf, char *mod_str, bool *multi_mods)
+{
+ size_t result = STRLEN(mod_str);
+ if (*multi_mods) {
+ result++;
+ }
+
+ if (buf != NULL) {
+ if (*multi_mods) {
+ STRCAT(buf, " ");
+ }
+ STRCAT(buf, mod_str);
+ }
+
+ *multi_mods = true;
+ return result;
+}
+
/*
* Check for a <> code in a user command.
* "code" points to the '<'. "len" the length of the <> (inclusive).
@@ -5162,8 +5406,8 @@ static char_u *uc_split_args(char_u *arg, size_t *lenp)
* Returns the length of the replacement, which has been added to "buf".
* Returns -1 if there was no match, and only the "<" has been copied.
*/
-static size_t
-uc_check_code (
+static size_t
+uc_check_code(
char_u *code,
size_t len,
char_u *buf,
@@ -5177,8 +5421,18 @@ uc_check_code (
char_u *p = code + 1;
size_t l = len - 2;
int quote = 0;
- enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_REGISTER,
- ct_LT, ct_NONE } type = ct_NONE;
+ enum {
+ ct_ARGS,
+ ct_BANG,
+ ct_COUNT,
+ ct_LINE1,
+ ct_LINE2,
+ ct_RANGE,
+ ct_MODS,
+ ct_REGISTER,
+ ct_LT,
+ ct_NONE
+ } type = ct_NONE;
if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-') {
quote = (*p == 'q' || *p == 'Q') ? 1 : 2;
@@ -5186,23 +5440,28 @@ uc_check_code (
l -= 2;
}
- ++l;
- if (l <= 1)
+ l++;
+ if (l <= 1) {
type = ct_NONE;
- else if (STRNICMP(p, "args>", l) == 0)
+ } else if (STRNICMP(p, "args>", l) == 0) {
type = ct_ARGS;
- else if (STRNICMP(p, "bang>", l) == 0)
+ } else if (STRNICMP(p, "bang>", l) == 0) {
type = ct_BANG;
- else if (STRNICMP(p, "count>", l) == 0)
+ } else if (STRNICMP(p, "count>", l) == 0) {
type = ct_COUNT;
- else if (STRNICMP(p, "line1>", l) == 0)
+ } else if (STRNICMP(p, "line1>", l) == 0) {
type = ct_LINE1;
- else if (STRNICMP(p, "line2>", l) == 0)
+ } else if (STRNICMP(p, "line2>", l) == 0) {
type = ct_LINE2;
- else if (STRNICMP(p, "lt>", l) == 0)
+ } else if (STRNICMP(p, "range>", l) == 0) {
+ type = ct_RANGE;
+ } else if (STRNICMP(p, "lt>", l) == 0) {
type = ct_LT;
- else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0)
+ } else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0) {
type = ct_REGISTER;
+ } else if (STRNICMP(p, "mods>", l) == 0) {
+ type = ct_MODS;
+ }
switch (type) {
case ct_ARGS:
@@ -5283,11 +5542,13 @@ uc_check_code (
case ct_LINE1:
case ct_LINE2:
+ case ct_RANGE:
case ct_COUNT:
{
char num_buf[20];
long num = (type == ct_LINE1) ? eap->line1 :
(type == ct_LINE2) ? eap->line2 :
+ (type == ct_RANGE) ? eap->addr_count :
(eap->addr_count > 0) ? eap->line2 : cmd->uc_def;
size_t num_len;
@@ -5310,6 +5571,87 @@ uc_check_code (
break;
}
+ case ct_MODS:
+ {
+ result = quote ? 2 : 0;
+ if (buf != NULL) {
+ if (quote) {
+ *buf++ = '"';
+ }
+ *buf = '\0';
+ }
+
+ bool multi_mods = false;
+
+ // :aboveleft and :leftabove
+ if (cmdmod.split & WSP_ABOVE) {
+ result += add_cmd_modifier(buf, "aboveleft", &multi_mods);
+ }
+ // :belowright and :rightbelow
+ if (cmdmod.split & WSP_BELOW) {
+ result += add_cmd_modifier(buf, "belowright", &multi_mods);
+ }
+ // :botright
+ if (cmdmod.split & WSP_BOT) {
+ result += add_cmd_modifier(buf, "botright", &multi_mods);
+ }
+
+ typedef struct {
+ bool *set;
+ char *name;
+ } mod_entry_T;
+ static mod_entry_T mod_entries[] = {
+ { &cmdmod.browse, "browse" },
+ { &cmdmod.confirm, "confirm" },
+ { &cmdmod.hide, "hide" },
+ { &cmdmod.keepalt, "keepalt" },
+ { &cmdmod.keepjumps, "keepjumps" },
+ { &cmdmod.keepmarks, "keepmarks" },
+ { &cmdmod.keeppatterns, "keeppatterns" },
+ { &cmdmod.lockmarks, "lockmarks" },
+ { &cmdmod.noswapfile, "noswapfile" }
+ };
+ // the modifiers that are simple flags
+ for (size_t i = 0; i < ARRAY_SIZE(mod_entries); i++) {
+ if (*mod_entries[i].set) {
+ result += add_cmd_modifier(buf, mod_entries[i].name, &multi_mods);
+ }
+ }
+
+ // TODO(vim): How to support :noautocmd?
+ // TODO(vim): How to support :sandbox?
+
+ // :silent
+ if (msg_silent > 0) {
+ result += add_cmd_modifier(buf, emsg_silent > 0 ? "silent!" : "silent",
+ &multi_mods);
+ }
+ // :tab
+ if (cmdmod.tab > 0) {
+ result += add_cmd_modifier(buf, "tab", &multi_mods);
+ }
+ // :topleft
+ if (cmdmod.split & WSP_TOP) {
+ result += add_cmd_modifier(buf, "topleft", &multi_mods);
+ }
+
+ // TODO(vim): How to support :unsilent?
+
+ // :verbose
+ if (p_verbose > 0) {
+ result += add_cmd_modifier(buf, "verbose", &multi_mods);
+ }
+ // :vertical
+ if (cmdmod.split & WSP_VERT) {
+ result += add_cmd_modifier(buf, "vertical", &multi_mods);
+ }
+ if (quote && buf != NULL) {
+ buf += result - 2;
+ *buf = '"';
+ }
+ break;
+ }
+
case ct_REGISTER:
result = eap->regname ? 1 : 0;
if (quote)
@@ -5378,22 +5720,21 @@ static void do_ucmd(exarg_T *eap)
if (start != NULL)
end = vim_strchr(start + 1, '>');
if (buf != NULL) {
- for (ksp = p; *ksp != NUL && *ksp != K_SPECIAL; ++ksp)
- ;
+ for (ksp = p; *ksp != NUL && *ksp != K_SPECIAL; ksp++) {
+ }
if (*ksp == K_SPECIAL
&& (start == NULL || ksp < start || end == NULL)
- && ((ksp[1] == KS_SPECIAL && ksp[2] == KE_FILLER)
- )) {
- /* K_SPECIAL has been put in the buffer as K_SPECIAL
- * KS_SPECIAL KE_FILLER, like for mappings, but
- * do_cmdline() doesn't handle that, so convert it back.
- * Also change K_SPECIAL KS_EXTRA KE_CSI into CSI. */
+ && (ksp[1] == KS_SPECIAL && ksp[2] == KE_FILLER)) {
+ // K_SPECIAL has been put in the buffer as K_SPECIAL
+ // KS_SPECIAL KE_FILLER, like for mappings, but
+ // do_cmdline() doesn't handle that, so convert it back.
+ // Also change K_SPECIAL KS_EXTRA KE_CSI into CSI.
len = ksp - p;
if (len > 0) {
memmove(q, p, len);
q += len;
}
- *q++ = ksp[1] == KS_SPECIAL ? K_SPECIAL : CSI;
+ *q++ = K_SPECIAL;
p = ksp + 3;
continue;
}
@@ -5502,7 +5843,15 @@ char_u *get_user_cmd_nargs(expand_T *xp, int idx)
*/
char_u *get_user_cmd_complete(expand_T *xp, int idx)
{
- return (char_u *)command_complete[idx].name;
+ if (idx >= (int)ARRAY_SIZE(command_complete)) {
+ return NULL;
+ }
+ char *cmd_compl = get_command_complete(idx);
+ if (cmd_compl == NULL) {
+ return (char_u *)"";
+ } else {
+ return (char_u *)cmd_compl;
+ }
}
/*
@@ -5544,10 +5893,10 @@ int parse_addr_type_arg(char_u *value, int vallen, uint32_t *argt,
* copied to allocated memory and stored in "*compl_arg".
* Returns FAIL if something is wrong.
*/
-int parse_compl_arg(char_u *value, int vallen, int *complp,
+int parse_compl_arg(const char_u *value, int vallen, int *complp,
uint32_t *argt, char_u **compl_arg)
{
- char_u *arg = NULL;
+ const char_u *arg = NULL;
size_t arglen = 0;
int i;
int valend = vallen;
@@ -5562,20 +5911,23 @@ int parse_compl_arg(char_u *value, int vallen, int *complp,
}
}
- for (i = 0; command_complete[i].expand != 0; ++i) {
- if ((int)STRLEN(command_complete[i].name) == valend
- && STRNCMP(value, command_complete[i].name, valend) == 0) {
- *complp = command_complete[i].expand;
- if (command_complete[i].expand == EXPAND_BUFFERS)
+ for (i = 0; i < (int)ARRAY_SIZE(command_complete); i++) {
+ if (get_command_complete(i) == NULL) {
+ continue;
+ }
+ if ((int)STRLEN(command_complete[i]) == valend
+ && STRNCMP(value, command_complete[i], valend) == 0) {
+ *complp = i;
+ if (i == EXPAND_BUFFERS) {
*argt |= BUFNAME;
- else if (command_complete[i].expand == EXPAND_DIRECTORIES
- || command_complete[i].expand == EXPAND_FILES)
+ } else if (i == EXPAND_DIRECTORIES || i == EXPAND_FILES) {
*argt |= XFILE;
+ }
break;
}
}
- if (command_complete[i].expand == 0) {
+ if (i == (int)ARRAY_SIZE(command_complete)) {
EMSG2(_("E180: Invalid complete value: %s"), value);
return FAIL;
}
@@ -5597,6 +5949,21 @@ int parse_compl_arg(char_u *value, int vallen, int *complp,
return OK;
}
+int cmdcomplete_str_to_type(char_u *complete_str)
+{
+ for (int i = 0; i < (int)(ARRAY_SIZE(command_complete)); i++) {
+ char *cmd_compl = get_command_complete(i);
+ if (cmd_compl == NULL) {
+ continue;
+ }
+ if (STRCMP(complete_str, command_complete[i]) == 0) {
+ return i;
+ }
+ }
+
+ return EXPAND_NOTHING;
+}
+
static void ex_colorscheme(exarg_T *eap)
{
if (*eap->arg == NUL) {
@@ -5619,9 +5986,10 @@ static void ex_colorscheme(exarg_T *eap)
static void ex_highlight(exarg_T *eap)
{
- if (*eap->arg == NUL && eap->cmd[2] == '!')
+ if (*eap->arg == NUL && eap->cmd[2] == '!') {
MSG(_("Greetings, Vim user!"));
- do_highlight(eap->arg, eap->forceit, FALSE);
+ }
+ do_highlight((const char *)eap->arg, eap->forceit, false);
}
@@ -5634,9 +6002,35 @@ void not_exiting(void)
exiting = FALSE;
}
-/*
- * ":quit": quit current window, quit Vim if the last window is closed.
- */
+static bool before_quit_autocmds(win_T *wp, bool quit_all, int forceit)
+{
+ apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, wp->w_buffer);
+
+ // Bail out when autocommands closed the window.
+ // Refuse to quit when the buffer in the last window is being closed (can
+ // only happen in autocommands).
+ if (!win_valid(wp)
+ || curbuf_locked()
+ || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_locked > 0)) {
+ return true;
+ }
+
+ if (quit_all
+ || (check_more(false, forceit) == OK && only_one_window())) {
+ apply_autocmds(EVENT_EXITPRE, NULL, NULL, false, curbuf);
+ // Refuse to quit when locked or when the buffer in the last window is
+ // being closed (can only happen in autocommands).
+ if (curbuf_locked()
+ || (curbuf->b_nwindows == 1 && curbuf->b_locked > 0)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// ":quit": quit current window, quit Vim if the last window is closed.
+// ":{nr}quit": quit window {nr}
static void ex_quit(exarg_T *eap)
{
if (cmdwin_type != 0) {
@@ -5662,22 +6056,22 @@ static void ex_quit(exarg_T *eap)
wp = curwin;
}
- apply_autocmds(EVENT_QUITPRE, NULL, NULL, false, curbuf);
- // Refuse to quit when locked or when the buffer in the last window is
- // being closed (can only happen in autocommands).
- if (curbuf_locked()
- || (wp->w_buffer->b_nwindows == 1 && wp->w_buffer->b_closing)) {
+ // Refuse to quit when locked.
+ if (curbuf_locked()) {
return;
}
+ // Trigger QuitPre and maybe ExitPre
+ if (before_quit_autocmds(wp, false, eap->forceit)) {
+ return;
+ }
- /*
- * If there are more files or windows we won't exit.
- */
- if (check_more(FALSE, eap->forceit) == OK && only_one_window())
- exiting = TRUE;
- if ((!P_HID(curbuf)
- && check_changed(curbuf, (p_awa ? CCGD_AW : 0)
+ // If there are more files or windows we won't exit.
+ if (check_more(false, eap->forceit) == OK && only_one_window()) {
+ exiting = true;
+ }
+ if ((!buf_hide(wp->w_buffer)
+ && check_changed(wp->w_buffer, (p_awa ? CCGD_AW : 0)
| (eap->forceit ? CCGD_FORCEIT : 0)
| CCGD_EXCMD))
|| check_more(true, eap->forceit) == FAIL
@@ -5690,11 +6084,12 @@ static void ex_quit(exarg_T *eap)
// specified. Example:
// :h|wincmd w|1q - don't quit
// :h|wincmd w|q - quit
- if (only_one_window() && (firstwin == lastwin || eap->addr_count == 0)) {
+ if (only_one_window() && (ONE_WINDOW || eap->addr_count == 0)) {
getout(0);
}
- /* close window; may free buffer */
- win_close(wp, !P_HID(wp->w_buffer) || eap->forceit);
+ not_exiting();
+ // close window; may free buffer
+ win_close(wp, !buf_hide(wp->w_buffer) || eap->forceit);
}
}
@@ -5703,7 +6098,7 @@ static void ex_quit(exarg_T *eap)
*/
static void ex_cquit(exarg_T *eap)
{
- getout(1);
+ getout(eap->addr_count > 0 ? (int)eap->line2 : EXIT_FAILURE);
}
/*
@@ -5712,10 +6107,11 @@ static void ex_cquit(exarg_T *eap)
static void ex_quit_all(exarg_T *eap)
{
if (cmdwin_type != 0) {
- if (eap->forceit)
- cmdwin_result = K_XF1; /* ex_window() takes care of this */
- else
+ if (eap->forceit) {
+ cmdwin_result = K_XF1; // open_cmdwin() takes care of this
+ } else {
cmdwin_result = K_XF2;
+ }
return;
}
@@ -5724,11 +6120,10 @@ static void ex_quit_all(exarg_T *eap)
text_locked_msg();
return;
}
- apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
- /* Refuse to quit when locked or when the buffer in the last window is
- * being closed (can only happen in autocommands). */
- if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing))
+
+ if (before_quit_autocmds(curwin, true, eap->forceit)) {
return;
+ }
exiting = true;
if (eap->forceit || !check_changed_any(false, false)) {
@@ -5742,18 +6137,20 @@ static void ex_quit_all(exarg_T *eap)
*/
static void ex_close(exarg_T *eap)
{
- win_T *win;
+ win_T *win = NULL;
int winnr = 0;
- if (cmdwin_type != 0)
+ if (cmdwin_type != 0) {
cmdwin_result = Ctrl_C;
- else if (!text_locked() && !curbuf_locked()) {
- if (eap->addr_count == 0)
+ } else if (!text_locked() && !curbuf_locked()) {
+ if (eap->addr_count == 0) {
ex_win_close(eap->forceit, curwin, NULL);
- else {
- for (win = firstwin; win != NULL; win = win->w_next) {
+ } else {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
winnr++;
- if (winnr == eap->line2)
+ if (winnr == eap->line2) {
+ win = wp;
break;
+ }
}
if (win == NULL)
win = lastwin;
@@ -5779,8 +6176,8 @@ static void ex_pclose(exarg_T *eap)
* Close window "win" and take care of handling closing the last window for a
* modified buffer.
*/
-static void
-ex_win_close (
+static void
+ex_win_close(
int forceit,
win_T *win,
tabpage_T *tp /* NULL or the tab page "win" is in */
@@ -5790,12 +6187,15 @@ ex_win_close (
buf_T *buf = win->w_buffer;
need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
- if (need_hide && !P_HID(buf) && !forceit) {
+ if (need_hide && !buf_hide(buf) && !forceit) {
if ((p_confirm || cmdmod.confirm) && p_write) {
- dialog_changed(buf, FALSE);
- if (buf_valid(buf) && bufIsChanged(buf))
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ dialog_changed(buf, false);
+ if (bufref_valid(&bufref) && bufIsChanged(buf)) {
return;
- need_hide = FALSE;
+ }
+ need_hide = false;
} else {
EMSG(_(e_nowrtmsg));
return;
@@ -5803,11 +6203,12 @@ ex_win_close (
}
- /* free buffer when not hiding it or when it's a scratch buffer */
- if (tp == NULL)
- win_close(win, !need_hide && !P_HID(buf));
- else
- win_close_othertab(win, !need_hide && !P_HID(buf), tp);
+ // free buffer when not hiding it or when it's a scratch buffer
+ if (tp == NULL) {
+ win_close(win, !need_hide && !buf_hide(buf));
+ } else {
+ win_close_othertab(win, !need_hide && !buf_hide(buf), tp);
+ }
}
/*
@@ -5823,8 +6224,9 @@ static void ex_tabclose(exarg_T *eap)
else if (first_tabpage->tp_next == NULL)
EMSG(_("E784: Cannot close last tab page"));
else {
- if (eap->addr_count > 0) {
- tp = find_tabpage((int)eap->line2);
+ int tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg == NULL) {
+ tp = find_tabpage(tab_number);
if (tp == NULL) {
beep_flush();
return;
@@ -5832,44 +6234,46 @@ static void ex_tabclose(exarg_T *eap)
if (tp != curtab) {
tabpage_close_other(tp, eap->forceit);
return;
+ } else if (!text_locked() && !curbuf_locked()) {
+ tabpage_close(eap->forceit);
}
}
- if (!text_locked()
- && !curbuf_locked()
- )
- tabpage_close(eap->forceit);
}
}
-/*
- * ":tabonly": close all tab pages except the current one
- */
+/// ":tabonly": close all tab pages except the current one
static void ex_tabonly(exarg_T *eap)
{
- if (cmdwin_type != 0)
+ if (cmdwin_type != 0) {
cmdwin_result = K_IGNORE;
- else if (first_tabpage->tp_next == NULL)
- MSG(_("Already only one tab page"));
- else {
- if (eap->addr_count > 0)
- goto_tabpage(eap->line2);
- /* Repeat this up to a 1000 times, because autocommands may mess
- * up the lists. */
- for (int done = 0; done < 1000; ++done) {
- FOR_ALL_TABS(tp) {
- if (tp->tp_topframe != topframe) {
- tabpage_close_other(tp, eap->forceit);
- /* if we failed to close it quit */
- if (valid_tabpage(tp))
- done = 1000;
- /* start over, "tp" is now invalid */
+ } else if (first_tabpage->tp_next == NULL) {
+ MSG(_("Already only one tab page"));
+ } else {
+ int tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg == NULL) {
+ goto_tabpage(tab_number);
+ // Repeat this up to a 1000 times, because autocommands may
+ // mess up the lists.
+ for (int done = 0; done < 1000; done++) {
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ assert(wp != aucmd_win);
+ }
+ FOR_ALL_TABS(tp) {
+ if (tp->tp_topframe != topframe) {
+ tabpage_close_other(tp, eap->forceit);
+ // if we failed to close it quit
+ if (valid_tabpage(tp)) {
+ done = 1000;
+ }
+ // start over, "tp" is now invalid
+ break;
+ }
+ }
+ assert(first_tabpage);
+ if (first_tabpage->tp_next == NULL) {
break;
}
}
- assert(first_tabpage);
- if (first_tabpage->tp_next == NULL) {
- break;
- }
}
}
}
@@ -5879,12 +6283,14 @@ static void ex_tabonly(exarg_T *eap)
*/
void tabpage_close(int forceit)
{
- /* First close all the windows but the current one. If that worked then
- * close the last window in this tab, that will close it. */
- if (lastwin != firstwin)
- close_others(TRUE, forceit);
- if (lastwin == firstwin)
+ // First close all the windows but the current one. If that worked then
+ // close the last window in this tab, that will close it.
+ if (!ONE_WINDOW) {
+ close_others(true, forceit);
+ }
+ if (ONE_WINDOW) {
ex_win_close(forceit, curwin, NULL);
+ }
}
/*
@@ -5912,7 +6318,6 @@ void tabpage_close_other(tabpage_T *tp, int forceit)
if (!valid_tabpage(tp) || tp->tp_firstwin == wp)
break;
}
- apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, FALSE, curbuf);
redraw_tabline = TRUE;
if (h != tabline_height())
@@ -5952,34 +6357,30 @@ void ex_all(exarg_T *eap)
static void ex_hide(exarg_T *eap)
{
- if (*eap->arg != NUL && check_nextcmd(eap->arg) == NULL)
- eap->errmsg = e_invarg;
- else {
- /* ":hide" or ":hide | cmd": hide current window */
- eap->nextcmd = check_nextcmd(eap->arg);
+ // ":hide" or ":hide | cmd": hide current window
if (!eap->skip) {
- if (eap->addr_count == 0)
- win_close(curwin, FALSE); /* don't free buffer */
- else {
- int winnr = 0;
- win_T *win;
-
- for (win = firstwin; win != NULL; win = win->w_next) {
- winnr++;
- if (winnr == eap->line2)
- break;
+ if (eap->addr_count == 0) {
+ win_close(curwin, false); // don't free buffer
+ } else {
+ int winnr = 0;
+ win_T *win = NULL;
+
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ winnr++;
+ if (winnr == eap->line2) {
+ win = wp;
+ break;
+ }
+ }
+ if (win == NULL) {
+ win = lastwin;
+ }
+ win_close(win, false);
}
- if (win == NULL)
- win = lastwin;
- win_close(win, FALSE);
- }
}
- }
}
-/*
- * ":stop" and ":suspend": Suspend Vim.
- */
+/// ":stop" and ":suspend": Suspend Vim.
static void ex_stop(exarg_T *eap)
{
// Disallow suspending in restricted mode (-Z)
@@ -5987,20 +6388,23 @@ static void ex_stop(exarg_T *eap)
if (!eap->forceit) {
autowrite_all();
}
+ apply_autocmds(EVENT_VIMSUSPEND, NULL, NULL, false, NULL);
+
+ // TODO(bfredl): the TUI should do this on suspend
ui_cursor_goto((int)Rows - 1, 0);
- ui_putc('\n');
+ ui_call_grid_scroll(1, 0, Rows, 0, Columns, 1, 0);
+ ui_flush();
+ ui_call_suspend(); // call machine specific function
+
ui_flush();
- ui_suspend(); /* call machine specific function */
maketitle();
- resettitle(); /* force updating the title */
- redraw_later_clear();
- ui_refresh(); /* may have resized window */
+ resettitle(); // force updating the title
+ ui_refresh(); // may have resized window
+ apply_autocmds(EVENT_VIMRESUME, NULL, NULL, false, NULL);
}
}
-/*
- * ":exit", ":xit" and ":wq": Write file and exit Vim.
- */
+// ":exit", ":xit" and ":wq": Write file and quite the current window.
static void ex_exit(exarg_T *eap)
{
if (cmdwin_type != 0) {
@@ -6012,11 +6416,10 @@ static void ex_exit(exarg_T *eap)
text_locked_msg();
return;
}
- apply_autocmds(EVENT_QUITPRE, NULL, NULL, FALSE, curbuf);
- /* Refuse to quit when locked or when the buffer in the last window is
- * being closed (can only happen in autocommands). */
- if (curbuf_locked() || (curbuf->b_nwindows == 1 && curbuf->b_closing))
+
+ if (before_quit_autocmds(curwin, false, eap->forceit)) {
return;
+ }
// if more files or windows we won't exit
if (check_more(false, eap->forceit) == OK && only_one_window()) {
@@ -6033,8 +6436,9 @@ static void ex_exit(exarg_T *eap)
// quit last window, exit Vim
getout(0);
}
+ not_exiting();
// Quit current window, may free the buffer.
- win_close(curwin, !P_HID(curwin->w_buffer));
+ win_close(curwin, !buf_hide(curwin->w_buffer));
}
}
@@ -6153,6 +6557,13 @@ void alist_expand(int *fnum_list, int fnum_len)
void alist_set(alist_T *al, int count, char_u **files, int use_curbuf, int *fnum_list, int fnum_len)
{
int i;
+ static int recursive = 0;
+
+ if (recursive) {
+ EMSG(_(e_au_recursive));
+ return;
+ }
+ recursive++;
alist_clear(al);
ga_grow(&al->al_ga, count);
@@ -6177,16 +6588,18 @@ void alist_set(alist_T *al, int count, char_u **files, int use_curbuf, int *fnum
xfree(files);
}
- if (al == &global_alist)
- arg_had_last = FALSE;
+ if (al == &global_alist) {
+ arg_had_last = false;
+ }
+ recursive--;
}
/*
* Add file "fname" to argument list "al".
* "fname" must have been allocated and "al" must have been checked for room.
*/
-void
-alist_add (
+void
+alist_add(
alist_T *al,
char_u *fname,
int set_fnum /* 1: set buffer number; 2: re-use curbuf */
@@ -6229,18 +6642,14 @@ void alist_slash_adjust(void)
#endif
-/*
- * ":preserve".
- */
+/// ":preserve".
static void ex_preserve(exarg_T *eap)
{
curbuf->b_flags |= BF_PRESERVED;
- ml_preserve(curbuf, TRUE);
+ ml_preserve(curbuf, true, true);
}
-/*
- * ":recover".
- */
+/// ":recover".
static void ex_recover(exarg_T *eap)
{
/* Set recoverymode right away to avoid the ATTENTION prompt. */
@@ -6355,6 +6764,8 @@ void tabpage_new(void)
*/
static void ex_tabnext(exarg_T *eap)
{
+ int tab_number;
+
switch (eap->cmdidx) {
case CMD_tabfirst:
case CMD_tabrewind:
@@ -6365,66 +6776,48 @@ static void ex_tabnext(exarg_T *eap)
break;
case CMD_tabprevious:
case CMD_tabNext:
- goto_tabpage(eap->addr_count == 0 ? -1 : -(int)eap->line2);
- break;
- default: /* CMD_tabnext */
- goto_tabpage(eap->addr_count == 0 ? 0 : (int)eap->line2);
- break;
- }
-}
-
-/*
- * :tabmove command
- */
-static void ex_tabmove(exarg_T *eap)
-{
- int tab_number;
+ if (eap->arg && *eap->arg != NUL) {
+ char_u *p = eap->arg;
+ char_u *p_save = p;
- if (eap->arg && *eap->arg != NUL) {
- char_u *p = eap->arg;
- int relative = 0; /* argument +N/-N means: move N places to the
- * right/left relative to the current position. */
-
- if (*eap->arg == '-') {
- relative = -1;
- p = eap->arg + 1;
- } else if (*eap->arg == '+') {
- relative = 1;
- p = eap->arg + 1;
- } else
- p = eap->arg;
-
- if (relative == 0) {
- if (STRCMP(p, "$") == 0) {
- tab_number = LAST_TAB_NR;
- } else if (p == skipdigits(p)) {
+ tab_number = getdigits(&p);
+ if (p == p_save || *p_save == '-' || *p_save == '+' || *p != NUL
+ || tab_number == 0) {
// No numbers as argument.
eap->errmsg = e_invarg;
return;
- } else {
- tab_number = getdigits(&p);
}
} else {
- if (*p != NUL) {
- tab_number = getdigits(&p);
- } else {
+ if (eap->addr_count == 0) {
tab_number = 1;
- }
- tab_number = tab_number * relative + tabpage_index(curtab);
- if (relative == -1) {
- --tab_number;
+ } else {
+ tab_number = eap->line2;
+ if (tab_number < 1) {
+ eap->errmsg = e_invrange;
+ return;
+ }
}
}
- } else if (eap->addr_count != 0) {
- tab_number = eap->line2;
- if (**eap->cmdlinep == '-') {
- --tab_number;
+ goto_tabpage(-tab_number);
+ break;
+ default: // CMD_tabnext
+ tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg == NULL) {
+ goto_tabpage(tab_number);
}
- } else {
- tab_number = LAST_TAB_NR;
+ break;
}
+}
- tabpage_move(tab_number);
+/*
+ * :tabmove command
+ */
+static void ex_tabmove(exarg_T *eap)
+{
+ int tab_number = get_tabpage_arg(eap);
+ if (eap->errmsg == NULL) {
+ tabpage_move(tab_number);
+ }
}
/*
@@ -6444,8 +6837,8 @@ static void ex_tabs(exarg_T *eap)
msg_putchar('\n');
vim_snprintf((char *)IObuff, IOSIZE, _("Tab page %d"), tabcount++);
- msg_outtrans_attr(IObuff, hl_attr(HLF_T));
- ui_flush(); /* output one line at a time */
+ msg_outtrans_attr(IObuff, HL_ATTR(HLF_T));
+ ui_flush(); // output one line at a time
os_breakcheck();
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
@@ -6478,7 +6871,8 @@ static void ex_tabs(exarg_T *eap)
static void ex_mode(exarg_T *eap)
{
if (*eap->arg == NUL) {
- ui_refresh();
+ must_redraw = CLEAR;
+ ex_redraw(eap);
} else {
EMSG(_(e_screenmode));
}
@@ -6553,8 +6947,8 @@ static void ex_edit(exarg_T *eap)
/*
* ":edit <file>" command and alikes.
*/
-void
-do_exedit (
+void
+do_exedit(
exarg_T *eap,
win_T *old_curwin /* curwin before doing a split or NULL */
)
@@ -6576,7 +6970,7 @@ do_exedit (
int ms = msg_scroll;
if (eap->nextcmd != NULL) {
- stuffReadbuff(eap->nextcmd);
+ stuffReadbuff((const char *)eap->nextcmd);
eap->nextcmd = NULL;
}
@@ -6584,7 +6978,7 @@ do_exedit (
no_wait_return = 0;
need_wait_return = FALSE;
msg_scroll = 0;
- must_redraw = CLEAR;
+ redraw_all_later(NOT_VALID);
normal_enter(false, true);
@@ -6608,11 +7002,6 @@ do_exedit (
old_curwin == NULL ? curwin : NULL);
} else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit)
|| *eap->arg != NUL) {
- // ":edit <blank>" is a no-op in terminal buffers. #2822
- if (curbuf->terminal != NULL && eap->cmdidx == CMD_edit && *eap->arg == NUL) {
- return;
- }
-
/* Can't edit another file when "curbuf_lock" is set. Only ":edit"
* can bring us here, others are stopped earlier. */
if (*eap->arg != NUL && curbuf_locked())
@@ -6625,24 +7014,23 @@ do_exedit (
empty buffer */
setpcmark();
if (do_ecmd(0, (eap->cmdidx == CMD_enew ? NULL : eap->arg),
- NULL, eap,
- eap->do_ecmd_lnum,
- (P_HID(curbuf) ? ECMD_HIDE : 0)
- + (eap->forceit ? ECMD_FORCEIT : 0)
- // After a split we can use an existing buffer.
- + (old_curwin != NULL ? ECMD_OLDBUF : 0)
- + (eap->cmdidx == CMD_badd ? ECMD_ADDBUF : 0 )
- , old_curwin == NULL ? curwin : NULL) == FAIL) {
- /* Editing the file failed. If the window was split, close it. */
+ NULL, eap, eap->do_ecmd_lnum,
+ (buf_hide(curbuf) ? ECMD_HIDE : 0)
+ + (eap->forceit ? ECMD_FORCEIT : 0)
+ // After a split we can use an existing buffer.
+ + (old_curwin != NULL ? ECMD_OLDBUF : 0)
+ + (eap->cmdidx == CMD_badd ? ECMD_ADDBUF : 0)
+ , old_curwin == NULL ? curwin : NULL) == FAIL) {
+ // Editing the file failed. If the window was split, close it.
if (old_curwin != NULL) {
need_hide = (curbufIsChanged() && curbuf->b_nwindows <= 1);
- if (!need_hide || P_HID(curbuf)) {
+ if (!need_hide || buf_hide(curbuf)) {
cleanup_T cs;
/* Reset the error/interrupt/exception state here so that
* aborting() returns FALSE when closing a window. */
enter_cleanup(&cs);
- win_close(curwin, !need_hide && !P_HID(curbuf));
+ win_close(curwin, !need_hide && !buf_hide(curbuf));
/* Restore the error/interrupt/exception state if not
* discarded by a new aborting error, interrupt, or
@@ -6682,12 +7070,10 @@ do_exedit (
ex_no_reprint = TRUE;
}
-/*
- * ":gui" and ":gvim" when there is no GUI.
- */
+/// ":gui" and ":gvim" when there is no GUI.
static void ex_nogui(exarg_T *eap)
{
- eap->errmsg = e_nogvim;
+ eap->errmsg = (char_u *)N_("E25: Nvim does not have a built-in GUI");
}
@@ -6739,7 +7125,8 @@ static void ex_syncbind(exarg_T *eap)
/*
* Set all scrollbind windows to the same topline.
*/
- for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ curwin = wp;
if (curwin->w_p_scb) {
curbuf = curwin->w_buffer;
y = topline - curwin->w_topline;
@@ -6793,9 +7180,10 @@ static void ex_read(exarg_T *eap)
eap->line2, (linenr_T)0, (linenr_T)MAXLNUM, eap, 0);
}
- if (i == FAIL) {
- if (!aborting())
+ if (i != OK) {
+ if (!aborting()) {
EMSG2(_(e_notopen), eap->arg);
+ }
} else {
if (empty && exmode_active) {
/* Delete the empty line that remains. Historically ex does
@@ -6836,24 +7224,27 @@ void free_cd_dir(void)
/// @param scope Scope of the function call (global, tab or window).
void post_chdir(CdScope scope)
{
- // The local directory of the current window is always overwritten.
+ // Always overwrite the window-local CWD.
xfree(curwin->w_localdir);
curwin->w_localdir = NULL;
- // Overwrite the local directory of the current tab page for `cd` and `tcd`
+ // Overwrite the tab-local CWD for :cd, :tcd.
if (scope >= kCdScopeTab) {
- xfree(curtab->localdir);
- curtab->localdir = NULL;
+ xfree(curtab->tp_localdir);
+ curtab->tp_localdir = NULL;
}
if (scope < kCdScopeGlobal) {
- // If still in global directory, need to remember current directory as
- // global directory.
+ // If still in global directory, set CWD as the global directory.
if (globaldir == NULL && prev_dir != NULL) {
globaldir = vim_strsave(prev_dir);
}
}
+ char cwd[MAXPATHL];
+ if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
+ return;
+ }
switch (scope) {
case kCdScopeGlobal:
// We are now in the global directory, no need to remember its name.
@@ -6861,27 +7252,19 @@ void post_chdir(CdScope scope)
globaldir = NULL;
break;
case kCdScopeTab:
- // Remember this local directory for the tab page.
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- curtab->localdir = vim_strsave(NameBuff);
- }
+ curtab->tp_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeWindow:
- // Remember this local directory for the window.
- if (os_dirname(NameBuff, MAXPATHL) == OK) {
- curwin->w_localdir = vim_strsave(NameBuff);
- }
+ curwin->w_localdir = (char_u *)xstrdup(cwd);
break;
case kCdScopeInvalid:
- // We should never get here
assert(false);
}
- shorten_fnames(TRUE);
+ shorten_fnames(true);
+ do_autocmd_dirchanged(cwd, scope);
}
-
-
/// `:cd`, `:tcd`, `:lcd`, `:chdir`, `:tchdir` and `:lchdir`.
void ex_cd(exarg_T *eap)
{
@@ -6923,30 +7306,31 @@ void ex_cd(exarg_T *eap)
new_dir = NameBuff;
}
#endif
- if (vim_chdir(new_dir)) {
- EMSG(_(e_failed));
- } else {
- CdScope scope = kCdScopeGlobal; // Depends on command invoked
+ CdScope scope = kCdScopeGlobal; // Depends on command invoked
- switch (eap->cmdidx) {
- case CMD_tcd:
- case CMD_tchdir:
- scope = kCdScopeTab;
- break;
- case CMD_lcd:
- case CMD_lchdir:
- scope = kCdScopeWindow;
- break;
- default:
- break;
- }
+ switch (eap->cmdidx) {
+ case CMD_tcd:
+ case CMD_tchdir:
+ scope = kCdScopeTab;
+ break;
+ case CMD_lcd:
+ case CMD_lchdir:
+ scope = kCdScopeWindow;
+ break;
+ default:
+ break;
+ }
+ if (vim_chdir(new_dir, scope)) {
+ EMSG(_(e_failed));
+ } else {
post_chdir(scope);
-
- /* Echo the new current directory if the command was typed. */
- if (KeyTyped || p_verbose >= 5)
+ // Echo the new current directory if the command was typed.
+ if (KeyTyped || p_verbose >= 5) {
ex_pwd(eap);
+ }
}
+
xfree(tofree);
}
}
@@ -7086,7 +7470,7 @@ static void ex_operators(exarg_T *eap)
oa.end.lnum = eap->line2;
oa.line_count = eap->line2 - eap->line1 + 1;
oa.motion_type = kMTLineWise;
- virtual_op = false;
+ virtual_op = kFalse;
if (eap->cmdidx != CMD_yank) { // position cursor for undo
setpcmark();
curwin->w_cursor.lnum = eap->line1;
@@ -7117,7 +7501,7 @@ static void ex_operators(exarg_T *eap)
op_shift(&oa, FALSE, eap->amount);
break;
}
- virtual_op = MAYBE;
+ virtual_op = kNone;
ex_may_print(eap);
}
@@ -7141,7 +7525,7 @@ static void ex_put(exarg_T *eap)
*/
static void ex_copymove(exarg_T *eap)
{
- long n = get_address(eap, &eap->arg, eap->addr_type, false, false);
+ long n = get_address(eap, &eap->arg, eap->addr_type, false, false, 1);
if (eap->arg == NULL) { // error detected
eap->nextcmd = NULL;
return;
@@ -7178,15 +7562,13 @@ void ex_may_print(exarg_T *eap)
}
}
-/*
- * ":smagic" and ":snomagic".
- */
+/// ":smagic" and ":snomagic".
static void ex_submagic(exarg_T *eap)
{
int magic_save = p_magic;
p_magic = (eap->cmdidx == CMD_smagic);
- do_sub(eap);
+ ex_substitute(eap);
p_magic = magic_save;
}
@@ -7218,6 +7600,7 @@ static void ex_at(exarg_T *eap)
int prev_len = typebuf.tb_len;
curwin->w_cursor.lnum = eap->line2;
+ check_cursor_col();
// Get the register name. No name means use the previous one.
int c = *eap->arg;
@@ -7259,10 +7642,11 @@ static void ex_bang(exarg_T *eap)
*/
static void ex_undo(exarg_T *eap)
{
- if (eap->addr_count == 1) /* :undo 123 */
- undo_time(eap->line2, FALSE, FALSE, TRUE);
- else
+ if (eap->addr_count == 1) { // :undo 123
+ undo_time(eap->line2, false, false, true);
+ } else {
u_undo(1);
+ }
}
static void ex_wundo(exarg_T *eap)
@@ -7295,8 +7679,8 @@ static void ex_redo(exarg_T *eap)
static void ex_later(exarg_T *eap)
{
long count = 0;
- int sec = FALSE;
- int file = FALSE;
+ bool sec = false;
+ bool file = false;
char_u *p = eap->arg;
if (*p == NUL)
@@ -7304,11 +7688,11 @@ static void ex_later(exarg_T *eap)
else if (isdigit(*p)) {
count = getdigits_long(&p);
switch (*p) {
- case 's': ++p; sec = TRUE; break;
- case 'm': ++p; sec = TRUE; count *= 60; break;
- case 'h': ++p; sec = TRUE; count *= 60 * 60; break;
- case 'd': ++p; sec = TRUE; count *= 24 * 60 * 60; break;
- case 'f': ++p; file = TRUE; break;
+ case 's': ++p; sec = true; break;
+ case 'm': ++p; sec = true; count *= 60; break;
+ case 'h': ++p; sec = true; count *= 60 * 60; break;
+ case 'd': ++p; sec = true; count *= 24 * 60 * 60; break;
+ case 'f': ++p; file = true; break;
}
}
@@ -7316,7 +7700,7 @@ static void ex_later(exarg_T *eap)
EMSG2(_(e_invarg2), eap->arg);
else
undo_time(eap->cmdidx == CMD_earlier ? -count : count,
- sec, file, FALSE);
+ sec, file, false);
}
/*
@@ -7411,12 +7795,16 @@ static void ex_redraw(exarg_T *eap)
RedrawingDisabled = 0;
p_lz = FALSE;
+ validate_cursor();
update_topline();
- update_screen(eap->forceit ? CLEAR :
- VIsual_active ? INVERTED :
- 0);
- if (need_maketitle)
+ if (eap->forceit) {
+ redraw_all_later(NOT_VALID);
+ }
+ update_screen(eap->forceit ? NOT_VALID
+ : VIsual_active ? INVERTED : 0);
+ if (need_maketitle) {
maketitle();
+ }
RedrawingDisabled = r;
p_lz = p;
@@ -7514,7 +7902,7 @@ static void ex_mkrc(exarg_T *eap)
/* When using 'viewdir' may have to create the directory. */
if (using_vdir && !os_isdir(p_vdir)) {
- vim_mkdir_emsg(p_vdir, 0755);
+ vim_mkdir_emsg((const char *)p_vdir, 0755);
}
fd = open_exfile((char_u *) fname, eap->forceit, WRITEBIN);
@@ -7611,7 +7999,7 @@ static void ex_mkrc(exarg_T *eap)
if (failed) {
EMSG(_(e_write));
} else if (eap->cmdidx == CMD_mksession) {
- // successful session write - set this_session var
+ // successful session write - set v:this_session
char *const tbuf = xmalloc(MAXPATHL);
if (vim_FullName(fname, tbuf, MAXPATHL, false) == OK) {
set_vim_var_string(VV_THIS_SESSION, tbuf, -1);
@@ -7626,10 +8014,17 @@ static void ex_mkrc(exarg_T *eap)
xfree(viewFile);
}
-int vim_mkdir_emsg(char_u *name, int prot)
+/// Try creating a directory, give error message on failure
+///
+/// @param[in] name Directory to create.
+/// @param[in] prot Directory permissions.
+///
+/// @return OK in case of success, FAIL otherwise.
+int vim_mkdir_emsg(const char *const name, const int prot)
+ FUNC_ATTR_NONNULL_ALL
{
int ret;
- if ((ret = os_mkdir((char *)name, prot)) != 0) {
+ if ((ret = os_mkdir(name, prot)) != 0) {
EMSG3(_(e_mkdir), name, os_strerror(ret));
return FAIL;
}
@@ -7784,6 +8179,7 @@ static void ex_normal(exarg_T *eap)
if (eap->addr_count != 0) {
curwin->w_cursor.lnum = eap->line1++;
curwin->w_cursor.col = 0;
+ check_cursor_moved(curwin);
}
exec_normal_cmd(
@@ -7803,9 +8199,8 @@ static void ex_normal(exarg_T *eap)
if (force_restart_edit) {
force_restart_edit = false;
} else {
- // some function called was aware of ex_normal and decided to override the
- // value of restart_edit anyway. So far only used in terminal mode(see
- // terminal_enter() in edit.c)
+ // Some function (terminal_enter()) was aware of ex_normal and decided to
+ // override the value of restart_edit anyway.
restart_edit = save_restart_edit;
}
p_im = save_insertmode;
@@ -7827,6 +8222,10 @@ static void ex_normal(exarg_T *eap)
static void ex_startinsert(exarg_T *eap)
{
if (eap->forceit) {
+ // cursor line can be zero on startup
+ if (!curwin->w_cursor.lnum) {
+ curwin->w_cursor.lnum = 1;
+ }
coladvance((colnr_T)MAXCOL);
curwin->w_curswant = MAXCOL;
curwin->w_set_curswant = FALSE;
@@ -7849,6 +8248,10 @@ static void ex_startinsert(exarg_T *eap)
restart_edit = 'i';
curwin->w_curswant = 0; /* avoid MAXCOL */
}
+
+ if (VIsual_active) {
+ showmode();
+ }
}
/*
@@ -7857,7 +8260,8 @@ static void ex_startinsert(exarg_T *eap)
static void ex_stopinsert(exarg_T *eap)
{
restart_edit = 0;
- stop_insert_mode = TRUE;
+ stop_insert_mode = true;
+ clearmode();
}
/*
@@ -8033,7 +8437,7 @@ static void ex_tag_cmd(exarg_T *eap, char_u *name)
break;
default: /* ":tag" */
if (p_cst && *eap->arg != NUL) {
- do_cstag(eap);
+ ex_cstag(eap);
return;
}
cmd = DT_TAG;
@@ -8061,23 +8465,25 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
"%",
#define SPEC_PERC 0
"#",
-#define SPEC_HASH 1
- "<cword>", /* cursor word */
-#define SPEC_CWORD 2
- "<cWORD>", /* cursor WORD */
-#define SPEC_CCWORD 3
- "<cfile>", /* cursor path name */
-#define SPEC_CFILE 4
- "<sfile>", /* ":so" file name */
-#define SPEC_SFILE 5
- "<slnum>", /* ":so" file line number */
-#define SPEC_SLNUM 6
- "<afile>", /* autocommand file name */
-# define SPEC_AFILE 7
- "<abuf>", /* autocommand buffer number */
-# define SPEC_ABUF 8
- "<amatch>", /* autocommand match name */
-# define SPEC_AMATCH 9
+#define SPEC_HASH (SPEC_PERC + 1)
+ "<cword>", // cursor word
+#define SPEC_CWORD (SPEC_HASH + 1)
+ "<cWORD>", // cursor WORD
+#define SPEC_CCWORD (SPEC_CWORD + 1)
+ "<cexpr>", // expr under cursor
+#define SPEC_CEXPR (SPEC_CCWORD + 1)
+ "<cfile>", // cursor path name
+#define SPEC_CFILE (SPEC_CEXPR + 1)
+ "<sfile>", // ":so" file name
+#define SPEC_SFILE (SPEC_CFILE + 1)
+ "<slnum>", // ":so" file line number
+#define SPEC_SLNUM (SPEC_SFILE + 1)
+ "<afile>", // autocommand file name
+#define SPEC_AFILE (SPEC_SLNUM + 1)
+ "<abuf>", // autocommand buffer number
+#define SPEC_ABUF (SPEC_AFILE + 1)
+ "<amatch>", // autocommand match name
+#define SPEC_AMATCH (SPEC_ABUF + 1)
};
for (size_t i = 0; i < ARRAY_SIZE(spec_str); ++i) {
@@ -8128,9 +8534,9 @@ eval_vars (
char_u *resultbuf = NULL;
size_t resultlen;
buf_T *buf;
- int valid = VALID_HEAD + VALID_PATH; /* assume valid result */
- int skip_mod = FALSE;
- char_u strbuf[30];
+ int valid = VALID_HEAD | VALID_PATH; // Assume valid result.
+ int skip_mod = false;
+ char strbuf[30];
*errormsg = NULL;
if (escaped != NULL)
@@ -8158,10 +8564,16 @@ eval_vars (
/*
* word or WORD under cursor
*/
- if (spec_idx == SPEC_CWORD || spec_idx == SPEC_CCWORD) {
- resultlen = find_ident_under_cursor(&result, (spec_idx == SPEC_CWORD
- ? (FIND_IDENT|FIND_STRING)
- : FIND_STRING));
+ if (spec_idx == SPEC_CWORD
+ || spec_idx == SPEC_CCWORD
+ || spec_idx == SPEC_CEXPR) {
+ resultlen = find_ident_under_cursor(
+ &result,
+ spec_idx == SPEC_CWORD
+ ? (FIND_IDENT | FIND_STRING)
+ : (spec_idx == SPEC_CEXPR
+ ? (FIND_IDENT | FIND_STRING | FIND_EVAL)
+ : FIND_STRING));
if (resultlen == 0) {
*errormsg = (char_u *)"";
return NULL;
@@ -8198,21 +8610,28 @@ eval_vars (
if (*s == '<') /* "#<99" uses v:oldfiles */
++s;
i = getdigits_int(&s);
- *usedlen = (size_t)(s - src); /* length of what we expand */
+ if (s == src + 2 && src[1] == '-') {
+ // just a minus sign, don't skip over it
+ s--;
+ }
+ *usedlen = (size_t)(s - src); // length of what we expand
- if (src[1] == '<') {
+ if (src[1] == '<' && i != 0) {
if (*usedlen < 2) {
/* Should we give an error message for #<text? */
*usedlen = 1;
return NULL;
}
- result = list_find_str(get_vim_var_list(VV_OLDFILES),
- (long)i);
+ result = (char_u *)tv_list_find_str(get_vim_var_list(VV_OLDFILES),
+ i - 1);
if (result == NULL) {
*errormsg = (char_u *)"";
return NULL;
}
} else {
+ if (i == 0 && src[1] == '<' && *usedlen > 1) {
+ *usedlen = 1;
+ }
buf = buflist_findnr(i);
if (buf == NULL) {
*errormsg = (char_u *)_(
@@ -8238,22 +8657,25 @@ eval_vars (
resultbuf = result; /* remember allocated string */
break;
- case SPEC_AFILE: /* file name for autocommand */
- result = autocmd_fname;
- if (result != NULL && !autocmd_fname_full) {
- /* Still need to turn the fname into a full path. It is
- * postponed to avoid a delay when <afile> is not used. */
- autocmd_fname_full = TRUE;
- result = (char_u *)FullName_save((char *)autocmd_fname, FALSE);
- xfree(autocmd_fname);
- autocmd_fname = result;
+ case SPEC_AFILE: // file name for autocommand
+ if (autocmd_fname != NULL
+ && !path_is_absolute(autocmd_fname)
+ // For CmdlineEnter and related events, <afile> is not a path! #9348
+ && !strequal("/", (char *)autocmd_fname)) {
+ // Still need to turn the fname into a full path. It was
+ // postponed to avoid a delay when <afile> is not used.
+ result = (char_u *)FullName_save((char *)autocmd_fname, false);
+ // Copy into `autocmd_fname`, don't reassign it. #8165
+ xstrlcpy((char *)autocmd_fname, (char *)result, MAXPATHL);
+ xfree(result);
}
+ result = autocmd_fname;
if (result == NULL) {
*errormsg = (char_u *)_(
"E495: no autocommand file name to substitute for \"<afile>\"");
return NULL;
}
- result = path_shorten_fname_if_possible(result);
+ result = path_try_shorten_fname(result);
break;
case SPEC_ABUF: /* buffer number for autocommand */
@@ -8262,8 +8684,8 @@ eval_vars (
"E496: no autocommand buffer number to substitute for \"<abuf>\"");
return NULL;
}
- sprintf((char *)strbuf, "%d", autocmd_bufnr);
- result = strbuf;
+ snprintf(strbuf, sizeof(strbuf), "%d", autocmd_bufnr);
+ result = (char_u *)strbuf;
break;
case SPEC_AMATCH: /* match name for autocommand */
@@ -8288,20 +8710,24 @@ eval_vars (
*errormsg = (char_u *)_("E842: no line number to use for \"<slnum>\"");
return NULL;
}
- sprintf((char *)strbuf, "%" PRId64, (int64_t)sourcing_lnum);
- result = strbuf;
+ snprintf(strbuf, sizeof(strbuf), "%" PRIdLINENR, sourcing_lnum);
+ result = (char_u *)strbuf;
break;
default:
// should not happen
*errormsg = (char_u *)"";
- return NULL;
+ result = (char_u *)""; // avoid gcc warning
+ break;
}
- resultlen = STRLEN(result); /* length of new string */
- if (src[*usedlen] == '<') { /* remove the file name extension */
- ++*usedlen;
- if ((s = vim_strrchr(result, '.')) != NULL && s >= path_tail(result))
+ // Length of new string.
+ resultlen = STRLEN(result);
+ // Remove the file name extension.
+ if (src[*usedlen] == '<') {
+ (*usedlen)++;
+ if ((s = STRRCHR(result, '.')) != NULL && s >= path_tail(result)) {
resultlen = (size_t)(s - result);
+ }
} else if (!skip_mod) {
valid |= modify_fname(src, usedlen, &result, &resultbuf, &resultlen);
if (result == NULL) {
@@ -8360,7 +8786,7 @@ static char_u *arg_all(void)
#ifndef BACKSLASH_IN_FILENAME
|| *p == '\\'
#endif
- ) {
+ || *p == '`') {
// insert a backslash
if (retval != NULL) {
retval[len] = '\\';
@@ -8441,8 +8867,8 @@ char_u *expand_sfile(char_u *arg)
* Write openfile commands for the current buffers to an .exrc file.
* Return FAIL on error, OK otherwise.
*/
-static int
-makeopens (
+static int
+makeopens(
FILE *fd,
char_u *dirnow /* Current directory name */
)
@@ -8462,15 +8888,15 @@ makeopens (
if (ssop_flags & SSOP_BUFFERS)
only_save_windows = FALSE; /* Save ALL buffers */
- /*
- * Begin by setting the this_session variable, and then other
- * sessionable variables.
- */
- if (put_line(fd, "let v:this_session=expand(\"<sfile>:p\")") == FAIL)
+ // Begin by setting v:this_session, and then other sessionable variables.
+ if (put_line(fd, "let v:this_session=expand(\"<sfile>:p\")") == FAIL) {
return FAIL;
- if (ssop_flags & SSOP_GLOBALS)
- if (store_session_globals(fd) == FAIL)
+ }
+ if (ssop_flags & SSOP_GLOBALS) {
+ if (store_session_globals(fd) == FAIL) {
return FAIL;
+ }
+ }
/*
* Close all windows but one.
@@ -8523,11 +8949,12 @@ makeopens (
&& buf->b_fname != NULL
&& buf->b_p_bl) {
if (fprintf(fd, "badd +%" PRId64 " ",
- buf->b_wininfo == NULL ?
- (int64_t)1L :
- (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0
- || ses_fname(fd, buf, &ssop_flags) == FAIL)
+ buf->b_wininfo == NULL
+ ? (int64_t)1L
+ : (int64_t)buf->b_wininfo->wi_fpos.lnum) < 0
+ || ses_fname(fd, buf, &ssop_flags, true) == FAIL) {
return FAIL;
+ }
}
}
@@ -8565,15 +8992,16 @@ makeopens (
*/
tab_firstwin = firstwin; /* first window in tab page "tabnr" */
tab_topframe = topframe;
- for (tabnr = 1;; ++tabnr) {
+ for (tabnr = 1;; tabnr++) {
+ tabpage_T *tp = find_tabpage(tabnr);
+ if (tp == NULL) {
+ break; // done all tab pages
+ }
+
int need_tabnew = false;
int cnr = 1;
if ((ssop_flags & SSOP_TABPAGES)) {
- tabpage_T *tp = find_tabpage(tabnr);
-
- if (tp == NULL)
- break; /* done all tab pages */
if (tp == curtab) {
tab_firstwin = firstwin;
tab_topframe = topframe;
@@ -8597,11 +9025,13 @@ makeopens (
&& !bt_nofile(wp->w_buffer)
) {
if (fputs(need_tabnew ? "tabedit " : "edit ", fd) < 0
- || ses_fname(fd, wp->w_buffer, &ssop_flags) == FAIL)
+ || ses_fname(fd, wp->w_buffer, &ssop_flags, true) == FAIL) {
return FAIL;
- need_tabnew = FALSE;
- if (!wp->w_arg_idx_invalid)
+ }
+ need_tabnew = false;
+ if (!wp->w_arg_idx_invalid) {
edited_win = wp;
+ }
break;
}
}
@@ -8640,17 +9070,22 @@ makeopens (
if (put_line(fd, "wincmd t") == FAIL)
return FAIL;
- /*
- * If more than one window, see if sizes can be restored.
- * First set 'winheight' and 'winwidth' to 1 to avoid the windows being
- * resized when moving between windows.
- * Do this before restoring the view, so that the topline and the
- * cursor can be set. This is done again below.
- */
- if (put_line(fd, "set winheight=1 winwidth=1") == FAIL)
+ // If more than one window, see if sizes can be restored.
+ // First set 'winheight' and 'winwidth' to 1 to avoid the windows being
+ // resized when moving between windows.
+ // Do this before restoring the view, so that the topline and the
+ // cursor can be set. This is done again below.
+ // winminheight and winminwidth need to be set to avoid an error if the
+ // user has set winheight or winwidth.
+ if (put_line(fd, "set winminheight=0") == FAIL
+ || put_line(fd, "set winheight=1") == FAIL
+ || put_line(fd, "set winminwidth=0") == FAIL
+ || put_line(fd, "set winwidth=1") == FAIL) {
return FAIL;
- if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
+ }
+ if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL) {
return FAIL;
+ }
/*
* Restore the view of the window (options, file, cursor, etc.).
@@ -8685,6 +9120,16 @@ makeopens (
if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
return FAIL;
+ // Take care of tab-local working directories if applicable
+ if (tp->tp_localdir) {
+ if (fputs("if has('nvim') | tcd ", fd) < 0
+ || ses_put_fname(fd, tp->tp_localdir, &ssop_flags) == FAIL
+ || fputs(" | endif", fd) < 0
+ || put_eol(fd) == FAIL) {
+ return FAIL;
+ }
+ }
+
/* Don't continue in another tab page when doing only the current one
* or when at the last tab page. */
if (!(ssop_flags & SSOP_TABPAGES))
@@ -8714,11 +9159,18 @@ makeopens (
if (put_line(fd, "unlet! s:wipebuf") == FAIL)
return FAIL;
- /* Re-apply 'winheight', 'winwidth' and 'shortmess'. */
- if (fprintf(fd, "set winheight=%" PRId64 " winwidth=%" PRId64 " shortmess=%s",
- (int64_t)p_wh, (int64_t)p_wiw, p_shm) < 0
- || put_eol(fd) == FAIL)
+ // Re-apply options.
+ if (fprintf(fd, "set winheight=%" PRId64 " winwidth=%" PRId64
+ " winminheight=%" PRId64 " winminwidth=%" PRId64
+ " shortmess=%s",
+ (int64_t)p_wh,
+ (int64_t)p_wiw,
+ (int64_t)p_wmh,
+ (int64_t)p_wmw,
+ p_shm) < 0
+ || put_eol(fd) == FAIL) {
return FAIL;
+ }
/*
* Lastly, execute the x.vim file if it exists.
@@ -8746,10 +9198,10 @@ static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin)
/* restore height when not full height */
if (wp->w_height + wp->w_status_height < topframe->fr_height
&& (fprintf(fd,
- "exe '%dresize ' . ((&lines * %" PRId64
- " + %" PRId64 ") / %" PRId64 ")",
- n, (int64_t)wp->w_height,
- (int64_t)(Rows / 2), (int64_t)Rows) < 0
+ "exe '%dresize ' . ((&lines * %" PRId64
+ " + %" PRId64 ") / %" PRId64 ")",
+ n, (int64_t)wp->w_grid.Rows,
+ (int64_t)(Rows / 2), (int64_t)Rows) < 0
|| put_eol(fd) == FAIL))
return FAIL;
@@ -8860,12 +9312,24 @@ static int ses_do_win(win_T *wp)
return true;
}
+static int put_view_curpos(FILE *fd, const win_T *wp, char *spaces)
+{
+ int r;
+
+ if (wp->w_curswant == MAXCOL) {
+ r = fprintf(fd, "%snormal! $", spaces);
+ } else {
+ r = fprintf(fd, "%snormal! 0%d|", spaces, wp->w_virtcol + 1);
+ }
+ return r < 0 || put_eol(fd) == FAIL ? FAIL : OK;
+}
+
/*
* Write commands to "fd" to restore the view of a window.
* Caller must make sure 'scrolloff' is zero.
*/
-static int
-put_view (
+static int
+put_view(
FILE *fd,
win_T *wp,
int add_edit, /* add ":edit" command to view */
@@ -8915,24 +9379,35 @@ put_view (
if (wp->w_buffer->b_ffname != NULL
&& (!bt_nofile(wp->w_buffer) || wp->w_buffer->terminal)
) {
- /*
- * Editing a file in this buffer: use ":edit file".
- * This may have side effects! (e.g., compressed or network file).
- */
- if (fputs("edit ", fd) < 0
- || ses_fname(fd, wp->w_buffer, flagp) == FAIL)
+ // Editing a file in this buffer: use ":edit file".
+ // This may have side effects! (e.g., compressed or network file).
+ //
+ // Note, if a buffer for that file already exists, use :badd to
+ // edit that buffer, to not lose folding information (:edit resets
+ // folds in other buffers)
+ if (fputs("if bufexists('", fd) < 0
+ || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL
+ || fputs("') | buffer ", fd) < 0
+ || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL
+ || fputs(" | else | edit ", fd) < 0
+ || ses_fname(fd, wp->w_buffer, flagp, false) == FAIL
+ || fputs(" | endif", fd) < 0
+ || put_eol(fd) == FAIL) {
return FAIL;
+ }
} else {
- /* No file in this buffer, just make it empty. */
- if (put_line(fd, "enew") == FAIL)
+ // No file in this buffer, just make it empty.
+ if (put_line(fd, "enew") == FAIL) {
return FAIL;
+ }
if (wp->w_buffer->b_ffname != NULL) {
- /* The buffer does have a name, but it's not a file name. */
+ // The buffer does have a name, but it's not a file name.
if (fputs("file ", fd) < 0
- || ses_fname(fd, wp->w_buffer, flagp) == FAIL)
+ || ses_fname(fd, wp->w_buffer, flagp, true) == FAIL) {
return FAIL;
+ }
}
- do_cursor = FALSE;
+ do_cursor = false;
}
}
@@ -8988,8 +9463,8 @@ put_view (
" * winheight(0) + %" PRId64 ") / %" PRId64 ")",
(int64_t)wp->w_cursor.lnum,
(int64_t)(wp->w_cursor.lnum - wp->w_topline),
- (int64_t)(wp->w_height / 2),
- (int64_t)wp->w_height) < 0
+ (int64_t)(wp->w_grid.Rows / 2),
+ (int64_t)wp->w_grid.Rows) < 0
|| put_eol(fd) == FAIL
|| put_line(fd, "if s:l < 1 | let s:l = 1 | endif") == FAIL
|| put_line(fd, "exe s:l") == FAIL
@@ -9015,27 +9490,27 @@ put_view (
(int64_t)(wp->w_virtcol + 1)) < 0
|| put_eol(fd) == FAIL
|| put_line(fd, "else") == FAIL
- || fprintf(fd, " normal! 0%d|", wp->w_virtcol + 1) < 0
- || put_eol(fd) == FAIL
+ || put_view_curpos(fd, wp, " ") == FAIL
|| put_line(fd, "endif") == FAIL)
return FAIL;
- } else {
- if (fprintf(fd, "normal! 0%d|", wp->w_virtcol + 1) < 0
- || put_eol(fd) == FAIL)
- return FAIL;
+ } else if (put_view_curpos(fd, wp, "") == FAIL) {
+ return FAIL;
}
}
}
- /*
- * Local directory.
- */
- if (wp->w_localdir != NULL) {
+ //
+ // Local directory, if the current flag is not view options or the "curdir"
+ // option is included.
+ //
+ if (wp->w_localdir != NULL
+ && (flagp != &vop_flags || (*flagp & SSOP_CURDIR))) {
if (fputs("lcd ", fd) < 0
|| ses_put_fname(fd, wp->w_localdir, flagp) == FAIL
- || put_eol(fd) == FAIL)
+ || put_eol(fd) == FAIL) {
return FAIL;
- did_lcd = TRUE;
+ }
+ did_lcd = true;
}
return OK;
@@ -9045,8 +9520,8 @@ put_view (
* Write an argument list to the session file.
* Returns FAIL if writing fails.
*/
-static int
-ses_arglist (
+static int
+ses_arglist(
FILE *fd,
char *cmd,
garray_T *gap,
@@ -9072,7 +9547,7 @@ ses_arglist (
(void)vim_FullName((char *)s, (char *)buf, MAXPATHL, FALSE);
s = buf;
}
- if (fputs("argadd ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL
+ if (fputs("$argadd ", fd) < 0 || ses_put_fname(fd, s, flagp) == FAIL
|| put_eol(fd) == FAIL) {
xfree(buf);
return FAIL;
@@ -9083,12 +9558,10 @@ ses_arglist (
return OK;
}
-/*
- * Write a buffer name to the session file.
- * Also ends the line.
- * Returns FAIL if writing fails.
- */
-static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp)
+/// Write a buffer name to the session file.
+/// Also ends the line, if "add_eol" is true.
+/// Returns FAIL if writing fails.
+static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp, bool add_eol)
{
char_u *name;
@@ -9105,8 +9578,10 @@ static int ses_fname(FILE *fd, buf_T *buf, unsigned *flagp)
name = buf->b_sfname;
else
name = buf->b_ffname;
- if (ses_put_fname(fd, name, flagp) == FAIL || put_eol(fd) == FAIL)
+ if (ses_put_fname(fd, name, flagp) == FAIL
+ || (add_eol && put_eol(fd) == FAIL)) {
return FAIL;
+ }
return OK;
}
@@ -9123,14 +9598,16 @@ static int ses_put_fname(FILE *fd, char_u *name, unsigned *flagp)
char_u *sname = home_replace_save(NULL, name);
if (*flagp & SSOP_SLASH) {
- /* change all backslashes to forward slashes */
- for (p = sname; *p != NUL; mb_ptr_adv(p))
- if (*p == '\\')
+ // change all backslashes to forward slashes
+ for (p = sname; *p != NUL; MB_PTR_ADV(p)) {
+ if (*p == '\\') {
*p = '/';
+ }
+ }
}
- /* escape special characters */
- p = vim_strsave_fnameescape(sname, FALSE);
+ // Escape special characters.
+ p = (char_u *)vim_strsave_fnameescape((const char *)sname, false);
xfree(sname);
/* write the result */
@@ -9265,18 +9742,18 @@ void dialog_msg(char_u *buff, char *format, char_u *fname)
static void ex_behave(exarg_T *eap)
{
if (STRCMP(eap->arg, "mswin") == 0) {
- set_option_value((char_u *)"selection", 0L, (char_u *)"exclusive", 0);
- set_option_value((char_u *)"selectmode", 0L, (char_u *)"mouse,key", 0);
- set_option_value((char_u *)"mousemodel", 0L, (char_u *)"popup", 0);
- set_option_value((char_u *)"keymodel", 0L,
- (char_u *)"startsel,stopsel", 0);
+ set_option_value("selection", 0L, "exclusive", 0);
+ set_option_value("selectmode", 0L, "mouse,key", 0);
+ set_option_value("mousemodel", 0L, "popup", 0);
+ set_option_value("keymodel", 0L, "startsel,stopsel", 0);
} else if (STRCMP(eap->arg, "xterm") == 0) {
- set_option_value((char_u *)"selection", 0L, (char_u *)"inclusive", 0);
- set_option_value((char_u *)"selectmode", 0L, (char_u *)"", 0);
- set_option_value((char_u *)"mousemodel", 0L, (char_u *)"extend", 0);
- set_option_value((char_u *)"keymodel", 0L, (char_u *)"", 0);
- } else
+ set_option_value("selection", 0L, "inclusive", 0);
+ set_option_value("selectmode", 0L, "", 0);
+ set_option_value("mousemodel", 0L, "extend", 0);
+ set_option_value("keymodel", 0L, "", 0);
+ } else {
EMSG2(_(e_invarg2), eap->arg);
+ }
}
/*
@@ -9292,6 +9769,24 @@ char_u *get_behave_arg(expand_T *xp, int idx)
return NULL;
}
+// Function given to ExpandGeneric() to obtain the possible arguments of the
+// ":messages {clear}" command.
+char_u *get_messages_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+{
+ if (idx == 0) {
+ return (char_u *)"clear";
+ }
+ return NULL;
+}
+
+char_u *get_mapclear_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
+{
+ if (idx == 0) {
+ return (char_u *)"<buffer>";
+ }
+ return NULL;
+}
+
static TriState filetype_detect = kNone;
static TriState filetype_plugin = kNone;
static TriState filetype_indent = kNone;
@@ -9348,7 +9843,7 @@ static void ex_filetype(exarg_T *eap)
}
}
if (*arg == 'd') {
- (void)do_doautocmd((char_u *)"filetypedetect BufRead", TRUE);
+ (void)do_doautocmd((char_u *)"filetypedetect BufRead", true, NULL);
do_modelines(0);
}
} else if (STRCMP(arg, "off") == 0) {
@@ -9369,29 +9864,38 @@ static void ex_filetype(exarg_T *eap)
EMSG2(_(e_invarg2), arg);
}
-/// Do ":filetype plugin indent on" if user did not already do some
-/// permutation thereof.
+/// Set all :filetype options ON if user did not explicitly set any to OFF.
void filetype_maybe_enable(void)
{
- if (filetype_detect == kNone
- && filetype_plugin == kNone
- && filetype_indent == kNone) {
+ if (filetype_detect == kNone) {
source_runtime((char_u *)FILETYPE_FILE, true);
filetype_detect = kTrue;
+ }
+ if (filetype_plugin == kNone) {
source_runtime((char_u *)FTPLUGIN_FILE, true);
filetype_plugin = kTrue;
+ }
+ if (filetype_indent == kNone) {
source_runtime((char_u *)INDENT_FILE, true);
filetype_indent = kTrue;
}
}
-/*
- * ":setfiletype {name}"
- */
+/// ":setfiletype [FALLBACK] {name}"
static void ex_setfiletype(exarg_T *eap)
{
- if (!did_filetype)
- set_option_value((char_u *)"filetype", 0L, eap->arg, OPT_LOCAL);
+ if (!did_filetype) {
+ char_u *arg = eap->arg;
+
+ if (STRNCMP(arg, "FALLBACK ", 9) == 0) {
+ arg += 9;
+ }
+
+ set_option_value("filetype", 0L, (char *)arg, OPT_LOCAL);
+ if (arg != eap->arg) {
+ did_filetype = false;
+ }
+ }
}
static void ex_digraphs(exarg_T *eap)
@@ -9477,7 +9981,8 @@ static void ex_match(exarg_T *eap)
c = *end;
*end = NUL;
- match_add(curwin, g, p + 1, 10, id, NULL, NULL);
+ match_add(curwin, (const char *)g, (const char *)p + 1, 10, id,
+ NULL, NULL);
xfree(g);
*end = c;
}
@@ -9499,42 +10004,171 @@ static void ex_foldopen(exarg_T *eap)
static void ex_folddo(exarg_T *eap)
{
- linenr_T lnum;
-
- start_global_changes();
-
- /* First set the marks for all lines closed/open. */
- for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
- if (hasFolding(lnum, NULL, NULL) == (eap->cmdidx == CMD_folddoclosed))
+ // First set the marks for all lines closed/open.
+ for (linenr_T lnum = eap->line1; lnum <= eap->line2; ++lnum) {
+ if (hasFolding(lnum, NULL, NULL) == (eap->cmdidx == CMD_folddoclosed)) {
ml_setmarked(lnum);
+ }
+ }
- /* Execute the command on the marked lines. */
- global_exe(eap->arg);
- ml_clearmarked(); /* clear rest of the marks */
-
- end_global_changes();
+ global_exe(eap->arg); // Execute the command on the marked lines.
+ ml_clearmarked(); // clear rest of the marks
}
static void ex_terminal(exarg_T *eap)
{
- char *name = (char *)p_sh; // Default to 'shell' if {cmd} is not given.
- bool mustfree = false;
- char *lquote = "['";
- char *rquote = "']";
+ char ex_cmd[1024];
+
+ if (*eap->arg != NUL) { // Run {cmd} in 'shell'.
+ char *name = (char *)vim_strsave_escaped(eap->arg, (char_u *)"\"\\");
+ snprintf(ex_cmd, sizeof(ex_cmd),
+ ":enew%s | call termopen(\"%s\")",
+ eap->forceit ? "!" : "", name);
+ xfree(name);
+ } else { // No {cmd}: run the job with tokenized 'shell'.
+ if (*p_sh == NUL) {
+ EMSG(_(e_shellempty));
+ return;
+ }
+
+ char **argv = shell_build_argv(NULL, NULL);
+ char **p = argv;
+ char tempstring[512];
+ char shell_argv[512] = { 0 };
+
+ while (*p != NULL) {
+ snprintf(tempstring, sizeof(tempstring), ",\"%s\"", *p);
+ xstrlcat(shell_argv, tempstring, sizeof(shell_argv));
+ p++;
+ }
+ shell_free_argv(argv);
- if (*eap->arg != NUL) {
- name = (char *)vim_strsave_escaped(eap->arg, (char_u *)"\"\\");
- mustfree = true;
- lquote = rquote = "\"";
+ snprintf(ex_cmd, sizeof(ex_cmd),
+ ":enew%s | call termopen([%s])",
+ eap->forceit ? "!" : "", shell_argv + 1);
}
- char ex_cmd[512];
- snprintf(ex_cmd, sizeof(ex_cmd),
- ":enew%s | call termopen(%s%s%s) | startinsert",
- eap->forceit==TRUE ? "!" : "", lquote, name, rquote);
do_cmdline_cmd(ex_cmd);
+}
- if (mustfree) {
- xfree(name);
+/// Checks if `cmd` is "previewable" (i.e. supported by 'inccommand').
+///
+/// @param[in] cmd Commandline to check. May start with a range or modifier.
+///
+/// @return true if `cmd` is previewable
+bool cmd_can_preview(char_u *cmd)
+{
+ if (cmd == NULL) {
+ return false;
+ }
+
+ // Ignore any leading modifiers (:keeppatterns, :verbose, etc.)
+ for (int len = modifier_len(cmd); len != 0; len = modifier_len(cmd)) {
+ cmd += len;
+ cmd = skipwhite(cmd);
+ }
+
+ exarg_T ea;
+ memset(&ea, 0, sizeof(ea));
+ // parse the command line
+ ea.cmd = skip_range(cmd, NULL);
+ if (*ea.cmd == '*') {
+ ea.cmd = skipwhite(ea.cmd + 1);
+ }
+ char_u *end = find_command(&ea, NULL);
+
+ switch (ea.cmdidx) {
+ case CMD_substitute:
+ case CMD_smagic:
+ case CMD_snomagic:
+ // Only preview once the pattern delimiter has been typed
+ if (*end && !ASCII_ISALNUM(*end)) {
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+/// Gets a map of maps describing user-commands defined for buffer `buf` or
+/// defined globally if `buf` is NULL.
+///
+/// @param buf Buffer to inspect, or NULL to get global commands.
+///
+/// @return Map of maps describing commands
+Dictionary commands_array(buf_T *buf)
+{
+ Dictionary rv = ARRAY_DICT_INIT;
+ Object obj = NIL;
+ (void)obj; // Avoid "dead assignment" warning.
+ char str[10];
+ garray_T *gap = (buf == NULL) ? &ucmds : &buf->b_ucmds;
+
+ for (int i = 0; i < gap->ga_len; i++) {
+ char arg[2] = { 0, 0 };
+ Dictionary d = ARRAY_DICT_INIT;
+ ucmd_T *cmd = USER_CMD_GA(gap, i);
+
+ PUT(d, "name", STRING_OBJ(cstr_to_string((char *)cmd->uc_name)));
+ PUT(d, "definition", STRING_OBJ(cstr_to_string((char *)cmd->uc_rep)));
+ PUT(d, "script_id", INTEGER_OBJ(cmd->uc_scriptID));
+ PUT(d, "bang", BOOLEAN_OBJ(!!(cmd->uc_argt & BANG)));
+ PUT(d, "bar", BOOLEAN_OBJ(!!(cmd->uc_argt & TRLBAR)));
+ PUT(d, "register", BOOLEAN_OBJ(!!(cmd->uc_argt & REGSTR)));
+
+ switch (cmd->uc_argt & (EXTRA|NOSPC|NEEDARG)) {
+ case 0: arg[0] = '0'; break;
+ case(EXTRA): arg[0] = '*'; break;
+ case(EXTRA|NOSPC): arg[0] = '?'; break;
+ case(EXTRA|NEEDARG): arg[0] = '+'; break;
+ case(EXTRA|NOSPC|NEEDARG): arg[0] = '1'; break;
+ }
+ PUT(d, "nargs", STRING_OBJ(cstr_to_string(arg)));
+
+ char *cmd_compl = get_command_complete(cmd->uc_compl);
+ PUT(d, "complete", (cmd_compl == NULL
+ ? NIL : STRING_OBJ(cstr_to_string(cmd_compl))));
+ PUT(d, "complete_arg", cmd->uc_compl_arg == NULL
+ ? NIL : STRING_OBJ(cstr_to_string((char *)cmd->uc_compl_arg)));
+
+ obj = NIL;
+ if (cmd->uc_argt & COUNT) {
+ if (cmd->uc_def >= 0) {
+ snprintf(str, sizeof(str), "%" PRId64, (int64_t)cmd->uc_def);
+ obj = STRING_OBJ(cstr_to_string(str)); // -count=N
+ } else {
+ obj = STRING_OBJ(cstr_to_string("0")); // -count
+ }
+ }
+ PUT(d, "count", obj);
+
+ obj = NIL;
+ if (cmd->uc_argt & RANGE) {
+ if (cmd->uc_argt & DFLALL) {
+ obj = STRING_OBJ(cstr_to_string("%")); // -range=%
+ } else if (cmd->uc_def >= 0) {
+ snprintf(str, sizeof(str), "%" PRId64, (int64_t)cmd->uc_def);
+ obj = STRING_OBJ(cstr_to_string(str)); // -range=N
+ } else {
+ obj = STRING_OBJ(cstr_to_string(".")); // -range
+ }
+ }
+ PUT(d, "range", obj);
+
+ obj = NIL;
+ for (int j = 0; addr_type_complete[j].expand != -1; j++) {
+ if (addr_type_complete[j].expand != ADDR_LINES
+ && addr_type_complete[j].expand == cmd->uc_addr_type) {
+ obj = STRING_OBJ(cstr_to_string(addr_type_complete[j].name));
+ break;
+ }
+ }
+ PUT(d, "addr", obj);
+
+ PUT(rv, (char *)cmd->uc_name, DICTIONARY_OBJ(d));
}
+ return rv;
}
diff --git a/src/nvim/ex_docmd.h b/src/nvim/ex_docmd.h
index bafad20169..cff350de08 100644
--- a/src/nvim/ex_docmd.h
+++ b/src/nvim/ex_docmd.h
@@ -2,14 +2,15 @@
#define NVIM_EX_DOCMD_H
#include "nvim/ex_cmds_defs.h"
+#include "nvim/globals.h"
-/* flags for do_cmdline() */
-#define DOCMD_VERBOSE 0x01 /* included command in error message */
-#define DOCMD_NOWAIT 0x02 /* don't call wait_return() and friends */
-#define DOCMD_REPEAT 0x04 /* repeat exec. until getline() returns NULL */
-#define DOCMD_KEYTYPED 0x08 /* don't reset KeyTyped */
-#define DOCMD_EXCRESET 0x10 /* reset exception environment (for debugging)*/
-#define DOCMD_KEEPLINE 0x20 /* keep typed line for repeating with "." */
+// flags for do_cmdline()
+#define DOCMD_VERBOSE 0x01 // included command in error message
+#define DOCMD_NOWAIT 0x02 // don't call wait_return() and friends
+#define DOCMD_REPEAT 0x04 // repeat exec. until getline() returns NULL
+#define DOCMD_KEYTYPED 0x08 // don't reset KeyTyped
+#define DOCMD_EXCRESET 0x10 // reset exception environment (for debugging
+#define DOCMD_KEEPLINE 0x20 // keep typed line for repeating with "."
/* defines for eval_vars() */
#define VALID_PATH 1
@@ -19,21 +20,6 @@
#define EXMODE_NORMAL 1
#define EXMODE_VIM 2
-/// The scope of a working-directory command like `:cd`.
-///
-/// Scopes are enumerated from lowest to highest. When adding a scope make sure
-/// to update all functions using scopes as well, such as the implementation of
-/// `getcwd()`. When using scopes as limits (e.g. in loops) don't use the scopes
-/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead.
-typedef enum {
- kCdScopeInvalid = -1,
- kCdScopeWindow, ///< Affects one window.
- kCdScopeTab, ///< Affects one tab page.
- kCdScopeGlobal, ///< Affects the entire instance of Neovim.
-} CdScope;
-#define MIN_CD_SCOPE kCdScopeWindow
-#define MAX_CD_SCOPE kCdScopeGlobal
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_docmd.h.generated.h"
#endif
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 82d4c2b2d5..7f7851f078 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -1,6 +1,11 @@
-/*
- * ex_eval.c: functions for Ex command line for the +eval feature.
- */
+// 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.
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
@@ -12,58 +17,65 @@
#include "nvim/ex_eval.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/regexp.h"
#include "nvim/strings.h"
-
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_eval.c.generated.h"
#endif
-/*
- * Exception handling terms:
- *
- * :try ":try" command \
- * ... try block |
- * :catch RE ":catch" command |
- * ... catch clause |- try conditional
- * :finally ":finally" command |
- * ... finally clause |
- * :endtry ":endtry" command /
- *
- * The try conditional may have any number of catch clauses and at most one
- * finally clause. A ":throw" command can be inside the try block, a catch
- * clause, the finally clause, or in a function called or script sourced from
- * there or even outside the try conditional. Try conditionals may be nested.
- */
-
-/*
- * Configuration whether an exception is thrown on error or interrupt. When
- * the preprocessor macros below evaluate to FALSE, an error (did_emsg) or
- * interrupt (got_int) under an active try conditional terminates the script
- * after the non-active finally clauses of all active try conditionals have been
- * executed. Otherwise, errors and/or interrupts are converted into catchable
- * exceptions (did_throw additionally set), which terminate the script only if
- * not caught. For user exceptions, only did_throw is set. (Note: got_int can
- * be set asynchronously afterwards by a SIGINT, so did_throw && got_int is not
- * a reliant test that the exception currently being thrown is an interrupt
- * exception. Similarly, did_emsg can be set afterwards on an error in an
- * (unskipped) conditional command inside an inactive conditional, so did_throw
- * && did_emsg is not a reliant test that the exception currently being thrown
- * is an error exception.) - The macros can be defined as expressions checking
- * for a variable that is allowed to be changed during execution of a script.
- */
-/* Values used for the Vim release. */
-# define THROW_ON_ERROR TRUE
-# define THROW_ON_ERROR_TRUE
-# define THROW_ON_INTERRUPT TRUE
-# define THROW_ON_INTERRUPT_TRUE
+// Exception handling terms:
+//
+// :try ":try" command ─â”
+// ... try block │
+// :catch RE ":catch" command │
+// ... catch clause ├─ try conditional
+// :finally ":finally" command │
+// ... finally clause │
+// :endtry ":endtry" command ─┘
+//
+// The try conditional may have any number of catch clauses and at most one
+// finally clause. A ":throw" command can be inside the try block, a catch
+// clause, the finally clause, or in a function called or script sourced from
+// there or even outside the try conditional. Try conditionals may be nested.
+
+// Configuration whether an exception is thrown on error or interrupt. When
+// the preprocessor macros below evaluate to FALSE, an error (did_emsg) or
+// interrupt (got_int) under an active try conditional terminates the script
+// after the non-active finally clauses of all active try conditionals have been
+// executed. Otherwise, errors and/or interrupts are converted into catchable
+// exceptions, which terminate the script only if not caught. For user
+// exceptions, only current_exception is set. (Note: got_int can be set
+// asynchronously afterwards by a SIGINT, so current_exception && got_int is not
+// a reliant test that the exception currently being thrown is an interrupt
+// exception. Similarly, did_emsg can be set afterwards on an error in an
+// (unskipped) conditional command inside an inactive conditional, so
+// current_exception && did_emsg is not a reliant test that the exception
+// currently being thrown is an error exception.) - The macros can be defined
+// as expressions checking for a variable that is allowed to be changed during
+// execution of a script.
+
+// Values used for the Vim release.
+#define THROW_ON_ERROR true
+#define THROW_ON_ERROR_TRUE
+#define THROW_ON_INTERRUPT true
+#define THROW_ON_INTERRUPT_TRUE
+
+// Don't do something after an error, interrupt, or throw, or when
+// there is a surrounding conditional and it was not active.
+#define CHECK_SKIP \
+ (did_emsg \
+ || got_int \
+ || current_exception \
+ || (cstack->cs_idx > 0 \
+ && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)))
+
+#define discard_pending_return(p) tv_free((typval_T *)(p))
/*
* When several errors appear in a row, setting "force_abort" is delayed until
@@ -89,7 +101,7 @@ static int cause_abort = FALSE;
*/
int aborting(void)
{
- return (did_emsg && force_abort) || got_int || did_throw;
+ return (did_emsg && force_abort) || got_int || current_exception;
}
/*
@@ -173,8 +185,9 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore)
* currently throwing an exception, do nothing. The message text will
* then be stored to v:errmsg by emsg() without displaying it.
*/
- if (((trylevel == 0 && !cause_abort) || emsg_silent) && !did_throw)
- return FALSE;
+ if (((trylevel == 0 && !cause_abort) || emsg_silent) && !current_exception) {
+ return false;
+ }
/*
* Ignore an interrupt message when inside a try conditional or when an
@@ -203,12 +216,13 @@ int cause_errthrow(char_u *mesg, int severe, int *ignore)
* exception currently being thrown to prevent it from being caught. Just
* execute finally clauses and terminate.
*/
- if (did_throw) {
- /* When discarding an interrupt exception, reset got_int to prevent the
- * same interrupt being converted to an exception again and discarding
- * the error exception we are about to throw here. */
- if (current_exception->type == ET_INTERRUPT)
- got_int = FALSE;
+ if (current_exception) {
+ // When discarding an interrupt exception, reset got_int to prevent the
+ // same interrupt being converted to an exception again and discarding
+ // the error exception we are about to throw here.
+ if (current_exception->type == ET_INTERRUPT) {
+ got_int = false;
+ }
discard_current_exception();
}
@@ -328,51 +342,49 @@ void do_errthrow(struct condstack *cstack, char_u *cmdname)
*/
int do_intthrow(struct condstack *cstack)
{
- /*
- * If no interrupt occurred or no try conditional is active and no exception
- * is being thrown, do nothing (for compatibility of non-EH scripts).
- */
- if (!got_int || (trylevel == 0 && !did_throw))
- return FALSE;
+ // If no interrupt occurred or no try conditional is active and no exception
+ // is being thrown, do nothing (for compatibility of non-EH scripts).
+ if (!got_int || (trylevel == 0 && !current_exception)) {
+ return false;
+ }
-#ifdef THROW_TEST /* avoid warning for condition always true */
+#ifdef THROW_TEST // avoid warning for condition always true
if (!THROW_ON_INTERRUPT) {
- /*
- * The interrupt aborts everything except for executing finally clauses.
- * Discard any user or error or interrupt exception currently being
- * thrown.
- */
- if (did_throw)
+ // The interrupt aborts everything except for executing finally clauses.
+ // Discard any user or error or interrupt exception currently being
+ // thrown.
+ if (current_exception) {
discard_current_exception();
- } else
+ }
+ } else {
#endif
- {
- /*
- * Throw an interrupt exception, so that everything will be aborted
- * (except for executing finally clauses), until the interrupt exception
- * is caught; if still uncaught at the top level, the script processing
- * will be terminated then. - If an interrupt exception is already
- * being thrown, do nothing.
- *
- */
- if (did_throw) {
- if (current_exception->type == ET_INTERRUPT)
- return FALSE;
+ // Throw an interrupt exception, so that everything will be aborted
+ // (except for executing finally clauses), until the interrupt exception
+ // is caught; if still uncaught at the top level, the script processing
+ // will be terminated then. - If an interrupt exception is already
+ // being thrown, do nothing.
+
+ if (current_exception) {
+ if (current_exception->type == ET_INTERRUPT) {
+ return false;
+ }
- /* An interrupt exception replaces any user or error exception. */
+ // An interrupt exception replaces any user or error exception.
discard_current_exception();
}
- if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL)
+ if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL) {
do_throw(cstack);
+ }
+#ifdef THROW_TEST
}
+#endif
- return TRUE;
+ return true;
}
-/*
- * Get an exception message that is to be stored in current_exception->value.
- */
-char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should_free)
+// Get an exception message that is to be stored in current_exception->value.
+char_u *get_exception_string(void *value, except_type_T type, char_u *cmdname,
+ int *should_free)
{
char_u *ret, *mesg;
char_u *p, *val;
@@ -430,13 +442,11 @@ char_u *get_exception_string(void *value, int type, char_u *cmdname, int *should
}
-/*
- * Throw a new exception. Return FAIL when out of memory or it was tried to
- * throw an illegal user exception. "value" is the exception string for a
- * user or interrupt exception, or points to a message list in case of an
- * error exception.
- */
-static int throw_exception(void *value, int type, char_u *cmdname)
+// Throw a new exception. Return FAIL when out of memory or it was tried to
+// throw an illegal user exception. "value" is the exception string for a
+// user or interrupt exception, or points to a message list in case of an
+// error exception.
+static int throw_exception(void *value, except_type_T type, char_u *cmdname)
{
except_T *excp;
int should_free;
@@ -483,7 +493,7 @@ static int throw_exception(void *value, int type, char_u *cmdname)
msg_scroll = TRUE; /* always scroll up, don't overwrite */
smsg(_("Exception thrown: %s"), excp->value);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
if (debug_break_level > 0 || *p_vfile == NUL)
cmdline_row = msg_row;
@@ -515,7 +525,7 @@ static void discard_exception(except_T *excp, int was_finished)
char_u *saved_IObuff;
if (excp == NULL) {
- EMSG(_(e_internal));
+ internal_error("discard_exception()");
return;
}
@@ -533,15 +543,17 @@ static void discard_exception(except_T *excp, int was_finished)
smsg(was_finished ? _("Exception finished: %s")
: _("Exception discarded: %s"),
excp->value);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
- if (debug_break_level > 0 || *p_vfile == NUL)
+ msg_puts("\n"); // don't overwrite this either
+ if (debug_break_level > 0 || *p_vfile == NUL) {
cmdline_row = msg_row;
- --no_wait_return;
- if (debug_break_level > 0)
+ }
+ no_wait_return--;
+ if (debug_break_level > 0) {
msg_silent = save_msg_silent;
- else
+ } else {
verbose_leave();
- STRCPY(IObuff, saved_IObuff);
+ }
+ xstrlcpy((char *)IObuff, (const char *)saved_IObuff, IOSIZE);
xfree(saved_IObuff);
}
if (excp->type != ET_INTERRUPT)
@@ -557,10 +569,11 @@ static void discard_exception(except_T *excp, int was_finished)
*/
void discard_current_exception(void)
{
- discard_exception(current_exception, FALSE);
+ discard_exception(current_exception, false);
+ // Note: all globals manipulated here should be saved/restored in
+ // try_enter/try_leave.
current_exception = NULL;
- did_throw = FALSE;
- need_rethrow = FALSE;
+ need_rethrow = false;
}
/*
@@ -596,7 +609,7 @@ static void catch_exception(except_T *excp)
msg_scroll = TRUE; /* always scroll up, don't overwrite */
smsg(_("Exception caught: %s"), excp->value);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
if (debug_break_level > 0 || *p_vfile == NUL)
cmdline_row = msg_row;
@@ -613,8 +626,9 @@ static void catch_exception(except_T *excp)
*/
static void finish_exception(except_T *excp)
{
- if (excp != caught_stack)
- EMSG(_(e_internal));
+ if (excp != caught_stack) {
+ internal_error("finish_exception()");
+ }
caught_stack = caught_stack->caught;
if (caught_stack != NULL) {
set_vim_var_string(VV_EXCEPTION, (char *) caught_stack->value, -1);
@@ -715,7 +729,7 @@ static void report_pending(int action, int pending, void *value)
++no_wait_return;
msg_scroll = TRUE; /* always scroll up, don't overwrite */
smsg(mesg, s);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
cmdline_row = msg_row;
--no_wait_return;
if (debug_break_level > 0)
@@ -778,7 +792,6 @@ void report_discard_pending(int pending, void *value)
*/
void ex_if(exarg_T *eap)
{
- int error;
int skip;
int result;
struct condstack *cstack = eap->cstack;
@@ -789,16 +802,9 @@ void ex_if(exarg_T *eap)
++cstack->cs_idx;
cstack->cs_flags[cstack->cs_idx] = 0;
- /*
- * Don't do something after an error, interrupt, or throw, or when there
- * is a surrounding conditional and it was not active.
- */
- skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
- && !(cstack->cs_flags[cstack->
- cs_idx -
- 1] &
- CSF_ACTIVE));
+ skip = CHECK_SKIP;
+ bool error;
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
if (!skip && !error) {
@@ -843,20 +849,11 @@ void ex_endif(exarg_T *eap)
*/
void ex_else(exarg_T *eap)
{
- int error;
int skip;
int result;
struct condstack *cstack = eap->cstack;
- /*
- * Don't do something after an error, interrupt, or throw, or when there is
- * a surrounding conditional and it was not active.
- */
- skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
- && !(cstack->cs_flags[cstack->
- cs_idx -
- 1] &
- CSF_ACTIVE));
+ skip = CHECK_SKIP;
if (cstack->cs_idx < 0
|| (cstack->cs_flags[cstack->cs_idx]
@@ -900,6 +897,7 @@ void ex_else(exarg_T *eap)
}
if (eap->cmdidx == CMD_elseif) {
+ bool error;
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
/* When throwing error exceptions, we want to throw always the first
* of several errors in a row. This is what actually happens when
@@ -924,7 +922,7 @@ void ex_else(exarg_T *eap)
*/
void ex_while(exarg_T *eap)
{
- int error;
+ bool error;
int skip;
int result;
struct condstack *cstack = eap->cstack;
@@ -945,15 +943,7 @@ void ex_while(exarg_T *eap)
cstack->cs_flags[cstack->cs_idx] =
eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR;
- /*
- * Don't do something after an error, interrupt, or throw, or when
- * there is a surrounding conditional and it was not active.
- */
- skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
- && !(cstack->cs_flags[cstack->
- cs_idx -
- 1] &
- CSF_ACTIVE));
+ skip = CHECK_SKIP;
if (eap->cmdidx == CMD_while) {
/*
* ":while bool-expr"
@@ -1146,23 +1136,25 @@ void ex_endwhile(exarg_T *eap)
*/
void ex_throw(exarg_T *eap)
{
- char_u *arg = eap->arg;
- char_u *value;
+ const char *arg = (const char *)eap->arg;
+ char *value;
- if (*arg != NUL && *arg != '|' && *arg != '\n')
- value = eval_to_string_skip(arg, &eap->nextcmd, eap->skip);
- else {
+ if (*arg != NUL && *arg != '|' && *arg != '\n') {
+ value = eval_to_string_skip(arg, (const char **)&eap->nextcmd,
+ (bool)eap->skip);
+ } else {
EMSG(_(e_argreq));
value = NULL;
}
- /* On error or when an exception is thrown during argument evaluation, do
- * not throw. */
+ // On error or when an exception is thrown during argument evaluation, do
+ // not throw.
if (!eap->skip && value != NULL) {
- if (throw_exception(value, ET_USER, NULL) == FAIL)
+ if (throw_exception((char_u *)value, ET_USER, NULL) == FAIL) {
xfree(value);
- else
+ } else {
do_throw(eap->cstack);
+ }
}
}
@@ -1224,8 +1216,6 @@ void do_throw(struct condstack *cstack)
cstack->cs_flags[idx] &= ~CSF_ACTIVE;
cstack->cs_exception[idx] = current_exception;
}
-
- did_throw = TRUE;
}
/*
@@ -1244,15 +1234,7 @@ void ex_try(exarg_T *eap)
cstack->cs_flags[cstack->cs_idx] = CSF_TRY;
cstack->cs_pending[cstack->cs_idx] = CSTP_NONE;
- /*
- * Don't do something after an error, interrupt, or throw, or when there
- * is a surrounding conditional and it was not active.
- */
- skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
- && !(cstack->cs_flags[cstack->
- cs_idx -
- 1] &
- CSF_ACTIVE));
+ skip = CHECK_SKIP;
if (!skip) {
/* Set ACTIVE and TRUE. TRUE means that the corresponding ":catch"
@@ -1344,8 +1326,9 @@ void ex_catch(exarg_T *eap)
* corresponding try block never got active (because of an inactive
* surrounding conditional or after an error or interrupt or throw).
*/
- if (!did_throw || !(cstack->cs_flags[idx] & CSF_TRUE))
- skip = TRUE;
+ if (!current_exception || !(cstack->cs_flags[idx] & CSF_TRUE)) {
+ skip = true;
+ }
/*
* Check for a match only if an exception is thrown but not caught by
@@ -1404,18 +1387,23 @@ void ex_catch(exarg_T *eap)
}
if (caught) {
- /* Make this ":catch" clause active and reset did_emsg, got_int,
- * and did_throw. Put the exception on the caught stack. */
+ /* Make this ":catch" clause active and reset did_emsg and got_int.
+ * Put the exception on the caught stack. */
cstack->cs_flags[idx] |= CSF_ACTIVE | CSF_CAUGHT;
- did_emsg = got_int = did_throw = FALSE;
+ did_emsg = got_int = false;
catch_exception((except_T *)cstack->cs_exception[idx]);
/* It's mandatory that the current exception is stored in the cstack
* so that it can be discarded at the next ":catch", ":finally", or
* ":endtry" or when the catch clause is left by a ":continue",
* ":break", ":return", ":finish", error, interrupt, or another
* exception. */
- if (cstack->cs_exception[cstack->cs_idx] != current_exception)
- EMSG(_(e_internal));
+ if (cstack->cs_exception[cstack->cs_idx] != current_exception) {
+ internal_error("ex_catch()");
+ }
+ // Discarding current_exceptions happens based on what is stored in
+ // cstack->cs_exception, *all* calls to discard_current_exception() are
+ // (and must be) guarded by current_exception check.
+ current_exception = NULL;
} else {
/*
* If there is a preceding catch clause and it caught the exception,
@@ -1474,7 +1462,7 @@ void ex_finally(exarg_T *eap)
* interrupt or throw) or for a ":finally" without ":try" or a multiple
* ":finally". After every other error (did_emsg or the conditional
* errors detected above) or after an interrupt (got_int) or an
- * exception (did_throw), the finally clause must be executed.
+ * exception (current_exception), the finally clause must be executed.
*/
skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
@@ -1501,30 +1489,31 @@ void ex_finally(exarg_T *eap)
cleanup_conditionals(cstack, CSF_TRY, FALSE);
/*
- * Make did_emsg, got_int, did_throw pending. If set, they overrule
- * a pending ":continue", ":break", ":return", or ":finish". Then
- * we have particularly to discard a pending return value (as done
+ * Make did_emsg, got_int, current_exception pending. If set, they
+ * overrule a pending ":continue", ":break", ":return", or ":finish".
+ * Then we have particularly to discard a pending return value (as done
* by the call to cleanup_conditionals() above when did_emsg or
* got_int is set). The pending values are restored by the
* ":endtry", except if there is a new error, interrupt, exception,
* ":continue", ":break", ":return", or ":finish" in the following
* finally clause. A missing ":endwhile", ":endfor" or ":endif"
- * detected here is treated as if did_emsg and did_throw had
+ * detected here is treated as if did_emsg and current_exception had
* already been set, respectively in case that the error is not
- * converted to an exception, did_throw had already been unset.
+ * converted to an exception, current_exception had already been unset.
* We must not set did_emsg here since that would suppress the
* error message.
*/
- if (pending == CSTP_ERROR || did_emsg || got_int || did_throw) {
+ if (pending == CSTP_ERROR || did_emsg || got_int || current_exception) {
if (cstack->cs_pending[cstack->cs_idx] == CSTP_RETURN) {
report_discard_pending(CSTP_RETURN,
cstack->cs_rettv[cstack->cs_idx]);
discard_pending_return(cstack->cs_rettv[cstack->cs_idx]);
}
- if (pending == CSTP_ERROR && !did_emsg)
- pending |= (THROW_ON_ERROR) ? CSTP_THROW : 0;
- else
- pending |= did_throw ? CSTP_THROW : 0;
+ if (pending == CSTP_ERROR && !did_emsg) {
+ pending |= (THROW_ON_ERROR ? CSTP_THROW : 0);
+ } else {
+ pending |= (current_exception ? CSTP_THROW : 0);
+ }
pending |= did_emsg ? CSTP_ERROR : 0;
pending |= got_int ? CSTP_INTERRUPT : 0;
assert(pending >= CHAR_MIN && pending <= CHAR_MAX);
@@ -1537,14 +1526,15 @@ void ex_finally(exarg_T *eap)
* exception. When emsg() is called for a missing ":endif" or
* a missing ":endwhile"/":endfor" detected here, the
* exception will be discarded. */
- if (did_throw && cstack->cs_exception[cstack->cs_idx]
- != current_exception)
- EMSG(_(e_internal));
+ if (current_exception
+ && cstack->cs_exception[cstack->cs_idx] != current_exception) {
+ internal_error("ex_finally()");
+ }
}
/*
* Set CSL_HAD_FINA, so do_cmdline() will reset did_emsg,
- * got_int, and did_throw and make the finally clause active.
+ * got_int, and current_exception and make the finally clause active.
* This will happen after emsg() has been called for a missing
* ":endif" or a missing ":endwhile"/":endfor" detected here, so
* that the following finally clause will be executed even then.
@@ -1579,7 +1569,7 @@ void ex_endtry(exarg_T *eap)
// made inactive by a ":continue", ":break", ":return", or ":finish" in
// the finally clause. The latter case need not be tested since then
// anything pending has already been discarded.
- skip = (did_emsg || got_int || did_throw
+ skip = (did_emsg || got_int || current_exception
|| !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE));
if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) {
@@ -1596,12 +1586,13 @@ void ex_endtry(exarg_T *eap)
/*
* If an exception is being thrown, discard it to prevent it from
* being rethrown at the end of this function. It would be
- * discarded by the error message, anyway. Resets did_throw.
+ * discarded by the error message, anyway. Resets current_exception.
* This does not affect the script termination due to the error
* since "trylevel" is decremented after emsg() has been called.
*/
- if (did_throw)
+ if (current_exception) {
discard_current_exception();
+ }
} else {
idx = cstack->cs_idx;
@@ -1611,9 +1602,11 @@ void ex_endtry(exarg_T *eap)
* a finally clause, we need to rethrow it after closing the try
* conditional.
*/
- if (did_throw && (cstack->cs_flags[idx] & CSF_TRUE)
- && !(cstack->cs_flags[idx] & CSF_FINALLY))
- rethrow = TRUE;
+ if (current_exception
+ && (cstack->cs_flags[idx] & CSF_TRUE)
+ && !(cstack->cs_flags[idx] & CSF_FINALLY)) {
+ rethrow = true;
+ }
}
/* If there was no finally clause, show the user when debugging or
@@ -1634,11 +1627,12 @@ void ex_endtry(exarg_T *eap)
if (got_int) {
skip = TRUE;
(void)do_intthrow(cstack);
- /* The do_intthrow() call may have reset did_throw or
- * cstack->cs_pending[idx].*/
- rethrow = FALSE;
- if (did_throw && !(cstack->cs_flags[idx] & CSF_FINALLY))
- rethrow = TRUE;
+ // The do_intthrow() call may have reset current_exception or
+ // cstack->cs_pending[idx].
+ rethrow = false;
+ if (current_exception && !(cstack->cs_flags[idx] & CSF_FINALLY)) {
+ rethrow = true;
+ }
}
}
@@ -1700,26 +1694,30 @@ void ex_endtry(exarg_T *eap)
do_finish(eap, FALSE);
break;
- /* When the finally clause was entered due to an error,
- * interrupt or throw (as opposed to a ":continue", ":break",
- * ":return", or ":finish"), restore the pending values of
- * did_emsg, got_int, and did_throw. This is skipped, if there
- * was a new error, interrupt, throw, ":continue", ":break",
- * ":return", or ":finish". in the finally clause. */
+ // When the finally clause was entered due to an error,
+ // interrupt or throw (as opposed to a ":continue", ":break",
+ // ":return", or ":finish"), restore the pending values of
+ // did_emsg, got_int, and current_exception. This is skipped, if there
+ // was a new error, interrupt, throw, ":continue", ":break",
+ // ":return", or ":finish". in the finally clause.
default:
- if (pending & CSTP_ERROR)
- did_emsg = TRUE;
- if (pending & CSTP_INTERRUPT)
- got_int = TRUE;
- if (pending & CSTP_THROW)
- rethrow = TRUE;
+ if (pending & CSTP_ERROR) {
+ did_emsg = true;
+ }
+ if (pending & CSTP_INTERRUPT) {
+ got_int = true;
+ }
+ if (pending & CSTP_THROW) {
+ rethrow = true;
+ }
break;
}
}
- if (rethrow)
- /* Rethrow the current exception (within this cstack). */
+ if (rethrow) {
+ // Rethrow the current exception (within this cstack).
do_throw(cstack);
+ }
}
}
@@ -1749,33 +1747,34 @@ void enter_cleanup(cleanup_T *csp)
int pending = CSTP_NONE;
/*
- * Postpone did_emsg, got_int, did_throw. The pending values will be
+ * Postpone did_emsg, got_int, current_exception. The pending values will be
* restored by leave_cleanup() except if there was an aborting error,
* interrupt, or uncaught exception after this function ends.
*/
- if (did_emsg || got_int || did_throw || need_rethrow) {
- csp->pending = (did_emsg ? CSTP_ERROR : 0)
- | (got_int ? CSTP_INTERRUPT : 0)
- | (did_throw ? CSTP_THROW : 0)
- | (need_rethrow ? CSTP_THROW : 0);
-
- /* If we are currently throwing an exception (did_throw), save it as
- * well. On an error not yet converted to an exception, update
- * "force_abort" and reset "cause_abort" (as do_errthrow() would do).
- * This is needed for the do_cmdline() call that is going to be made
- * for autocommand execution. We need not save *msg_list because
- * there is an extra instance for every call of do_cmdline(), anyway.
+ if (did_emsg || got_int || current_exception || need_rethrow) {
+ csp->pending = (did_emsg ? CSTP_ERROR : 0)
+ | (got_int ? CSTP_INTERRUPT : 0)
+ | (current_exception ? CSTP_THROW : 0)
+ | (need_rethrow ? CSTP_THROW : 0);
+
+ /* If we are currently throwing an exception, save it as well. On an error
+ * not yet converted to an exception, update "force_abort" and reset
+ * "cause_abort" (as do_errthrow() would do). This is needed for the
+ * do_cmdline() call that is going to be made for autocommand execution. We
+ * need not save *msg_list because there is an extra instance for every call
+ * of do_cmdline(), anyway.
*/
- if (did_throw || need_rethrow)
+ if (current_exception || need_rethrow) {
csp->exception = current_exception;
- else {
+ } else {
csp->exception = NULL;
if (did_emsg) {
force_abort |= cause_abort;
cause_abort = FALSE;
}
}
- did_emsg = got_int = did_throw = need_rethrow = FALSE;
+ did_emsg = got_int = need_rethrow = false;
+ current_exception = NULL;
/* Report if required by the 'verbose' option or when debugging. */
report_make_pending(pending, csp->exception);
@@ -1847,19 +1846,20 @@ void leave_cleanup(cleanup_T *csp)
force_abort = FALSE;
}
- /*
- * Restore the pending values of did_emsg, got_int, and did_throw.
- */
- if (pending & CSTP_ERROR)
- did_emsg = TRUE;
- if (pending & CSTP_INTERRUPT)
- got_int = TRUE;
- if (pending & CSTP_THROW)
- need_rethrow = TRUE; /* did_throw will be set by do_one_cmd() */
+ // Restore the pending values of did_emsg, got_int, and current_exception.
+ if (pending & CSTP_ERROR) {
+ did_emsg = true;
+ }
+ if (pending & CSTP_INTERRUPT) {
+ got_int = true;
+ }
+ if (pending & CSTP_THROW) {
+ need_rethrow = true; // current_exception will be set by do_one_cmd()
+ }
- /* Report if required by the 'verbose' option or when debugging. */
- report_resume_pending(pending,
- (pending & CSTP_THROW) ? (void *)current_exception : NULL);
+ // Report if required by the 'verbose' option or when debugging.
+ report_resume_pending(
+ pending, ((pending & CSTP_THROW) ? (void *)current_exception : NULL));
}
}
diff --git a/src/nvim/ex_eval.h b/src/nvim/ex_eval.h
index 30871c7711..d5f8737bf3 100644
--- a/src/nvim/ex_eval.h
+++ b/src/nvim/ex_eval.h
@@ -23,19 +23,19 @@ struct eslist_elem {
#define CSTACK_LEN 50
struct condstack {
- short cs_flags[CSTACK_LEN]; /* CSF_ flags */
- char cs_pending[CSTACK_LEN]; /* CSTP_: what's pending in ":finally"*/
+ int cs_flags[CSTACK_LEN]; // CSF_ flags
+ char cs_pending[CSTACK_LEN]; // CSTP_: what's pending in ":finally"
union {
- void *csp_rv[CSTACK_LEN]; /* return typeval for pending return */
- void *csp_ex[CSTACK_LEN]; /* exception for pending throw */
+ void *csp_rv[CSTACK_LEN]; // return typeval for pending return
+ void *csp_ex[CSTACK_LEN]; // exception for pending throw
} cs_pend;
- void *cs_forinfo[CSTACK_LEN]; /* info used by ":for" */
- int cs_line[CSTACK_LEN]; /* line nr of ":while"/":for" line */
- int cs_idx; /* current entry, or -1 if none */
- int cs_looplevel; /* nr of nested ":while"s and ":for"s */
- int cs_trylevel; /* nr of nested ":try"s */
- eslist_T *cs_emsg_silent_list; /* saved values of "emsg_silent" */
- char cs_lflags; /* loop flags: CSL_ flags */
+ void *cs_forinfo[CSTACK_LEN]; // info used by ":for"
+ int cs_line[CSTACK_LEN]; // line nr of ":while"/":for" line
+ int cs_idx; // current entry, or -1 if none
+ int cs_looplevel; // nr of nested ":while"s and ":for"s
+ int cs_trylevel; // nr of nested ":try"s
+ eslist_T *cs_emsg_silent_list; // saved values of "emsg_silent"
+ int cs_lflags; // loop flags: CSL_ flags
};
# define cs_rettv cs_pend.csp_rv
# define cs_exception cs_pend.csp_ex
@@ -89,28 +89,29 @@ struct msglist {
struct msglist *next; /* next of several messages in a row */
};
+// The exception types.
+typedef enum
+{
+ ET_USER, // exception caused by ":throw" command
+ ET_ERROR, // error exception
+ ET_INTERRUPT // interrupt exception triggered by Ctrl-C
+} except_type_T;
+
/*
* Structure describing an exception.
* (don't use "struct exception", it's used by the math library).
*/
typedef struct vim_exception except_T;
struct vim_exception {
- int type; /* exception type */
- char_u *value; /* exception value */
- struct msglist *messages; /* message(s) causing error exception */
- char_u *throw_name; /* name of the throw point */
- linenr_T throw_lnum; /* line number of the throw point */
- except_T *caught; /* next exception on the caught stack */
+ except_type_T type; // exception type
+ char_u *value; // exception value
+ struct msglist *messages; // message(s) causing error exception
+ char_u *throw_name; // name of the throw point
+ linenr_T throw_lnum; // line number of the throw point
+ except_T *caught; // next exception on the caught stack
};
/*
- * The exception types.
- */
-#define ET_USER 0 /* exception caused by ":throw" command */
-#define ET_ERROR 1 /* error exception */
-#define ET_INTERRUPT 2 /* interrupt exception triggered by Ctrl-C */
-
-/*
* Structure to save the error/interrupt/exception state between calls to
* enter_cleanup() and leave_cleanup(). Must be allocated as an automatic
* variable by the (common) caller of these functions.
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index cd28554970..8efb027575 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.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
+
/*
* ex_getln.c: Functions for entering and editing an Ex command line.
*/
@@ -8,6 +11,8 @@
#include <stdlib.h>
#include <inttypes.h>
+#include "nvim/assert.h"
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/arabic.h"
@@ -26,15 +31,16 @@
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/getchar.h"
+#include "nvim/highlight.h"
#include "nvim/if_cscope.h"
#include "nvim/indent.h"
#include "nvim/main.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/cursor_shape.h"
#include "nvim/keymap.h"
@@ -58,6 +64,42 @@
#include "nvim/os/os.h"
#include "nvim/event/loop.h"
#include "nvim/os/time.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/highlight_defs.h"
+#include "nvim/viml/parser/parser.h"
+#include "nvim/viml/parser/expressions.h"
+
+/// Command-line colors: one chunk
+///
+/// Defines a region which has the same highlighting.
+typedef struct {
+ int start; ///< Colored chunk start.
+ int end; ///< Colored chunk end (exclusive, > start).
+ int attr; ///< Highlight attr.
+} CmdlineColorChunk;
+
+/// Command-line colors
+///
+/// Holds data about all colors.
+typedef kvec_t(CmdlineColorChunk) CmdlineColors;
+
+/// Command-line coloring
+///
+/// Holds both what are the colors and what have been colored. Latter is used to
+/// suppress unnecessary calls to coloring callbacks.
+typedef struct {
+ unsigned prompt_id; ///< ID of the prompt which was colored last.
+ char *cmdbuff; ///< What exactly was colored last time or NULL.
+ CmdlineColors colors; ///< Last colors.
+} ColoredCmdline;
+
+/// Keeps track how much state must be sent to external ui.
+typedef enum {
+ kCmdRedrawNone,
+ kCmdRedrawPos,
+ kCmdRedrawAll,
+} CmdRedraw;
/*
* Variables shared between getcmdline(), redrawcmdline() and others.
@@ -65,23 +107,33 @@
* structure.
*/
struct cmdline_info {
- char_u *cmdbuff; /* pointer to command line buffer */
- int cmdbufflen; /* length of cmdbuff */
- int cmdlen; /* number of chars in command line */
- int cmdpos; /* current cursor position */
- int cmdspos; /* cursor column on screen */
- int cmdfirstc; /* ':', '/', '?', '=', '>' or NUL */
- int cmdindent; /* number of spaces before cmdline */
- char_u *cmdprompt; /* message in front of cmdline */
- int cmdattr; /* attributes for prompt */
- int overstrike; /* Typing mode on the command line. Shared by
- getcmdline() and put_on_cmdline(). */
- expand_T *xpc; /* struct being used for expansion, xp_pattern
- may point into cmdbuff */
- int xp_context; /* type of expansion */
- char_u *xp_arg; /* user-defined expansion arg */
- int input_fn; /* when TRUE Invoked for input() function */
+ char_u *cmdbuff; // pointer to command line buffer
+ int cmdbufflen; // length of cmdbuff
+ int cmdlen; // number of chars in command line
+ int cmdpos; // current cursor position
+ int cmdspos; // cursor column on screen
+ int cmdfirstc; // ':', '/', '?', '=', '>' or NUL
+ int cmdindent; // number of spaces before cmdline
+ char_u *cmdprompt; // message in front of cmdline
+ int cmdattr; // attributes for prompt
+ int overstrike; // Typing mode on the command line. Shared by
+ // getcmdline() and put_on_cmdline().
+ expand_T *xpc; // struct being used for expansion, xp_pattern
+ // may point into cmdbuff
+ int xp_context; // type of expansion
+ char_u *xp_arg; // user-defined expansion arg
+ int input_fn; // when TRUE Invoked for input() function
+ unsigned prompt_id; ///< Prompt number, used to disable coloring on errors.
+ Callback highlight_callback; ///< Callback used for coloring user input.
+ ColoredCmdline last_colors; ///< Last cmdline colors
+ int level; // current cmdline level
+ struct cmdline_info *prev_ccline; ///< pointer to saved cmdline state
+ char special_char; ///< last putcmdline char (used for redraws)
+ bool special_shift; ///< shift of last putcmdline char
+ CmdRedraw redraw_state; ///< needed redraw for external cmdline
};
+/// Last value of prompt_id, incremented when doing new prompt
+static unsigned last_prompt_id = 0;
typedef struct command_line_state {
VimState state;
@@ -96,19 +148,28 @@ typedef struct command_line_state {
char_u *lookfor; // string to match
int hiscnt; // current history line in use
int histype; // history type to be used
- pos_T old_cursor;
- colnr_T old_curswant;
- colnr_T old_leftcol;
- linenr_T old_topline;
- int old_topfill;
- linenr_T old_botline;
+ pos_T search_start; // where 'incsearch' starts searching
+ pos_T save_cursor;
+ colnr_T old_curswant;
+ colnr_T init_curswant;
+ colnr_T old_leftcol;
+ colnr_T init_leftcol;
+ linenr_T old_topline;
+ linenr_T init_topline;
+ int old_topfill;
+ int init_topfill;
+ linenr_T old_botline;
+ linenr_T init_botline;
+ pos_T match_start;
+ pos_T match_end;
int did_incsearch;
int incsearch_postponed;
int did_wild_list; // did wild_list() recently
int wim_index; // index in wim_flags[]
int res;
- int save_msg_scroll;
- int save_State; // remember State when called
+ int save_msg_scroll;
+ int save_State; // remember State when called
+ char_u *save_p_icm;
int some_key_typed; // one of the keys was typed
// mouse drag and release events are ignored, unless they are
// preceded with a mouse down event
@@ -116,12 +177,10 @@ typedef struct command_line_state {
int break_ctrl_c;
expand_T xpc;
long *b_im_ptr;
- // Everything that may work recursively should save and restore the
- // current command line in save_ccline. That includes update_screen(), a
- // custom status line may invoke ":normal".
- struct cmdline_info save_ccline;
} CommandLineState;
+typedef struct cmdline_info CmdlineInfo;
+
/* The current cmdline_info. It is initialized in getcmdline() and after that
* used by other functions. When invoking getcmdline() recursively it needs
* to be saved with save_cmdline() and restored with restore_cmdline().
@@ -132,10 +191,16 @@ static int cmd_showtail; /* Only show path tail in lists ? */
static int new_cmdpos; /* position set by set_cmdline_pos() */
+/// currently displayed block of context
+static Array cmdline_block = ARRAY_DICT_INIT;
+
/*
* Type used by call_user_expand_func
*/
-typedef void *(*user_expand_func_T)(char_u *, int, char_u **, int);
+typedef void *(*user_expand_func_T)(const char_u *,
+ int,
+ const char_u * const *,
+ bool);
static histentry_T *(history[HIST_COUNT]) = {NULL, NULL, NULL, NULL, NULL};
static int hisidx[HIST_COUNT] = {-1, -1, -1, -1, -1}; /* lastused entry */
@@ -143,16 +208,30 @@ static int hisnum[HIST_COUNT] = {0, 0, 0, 0, 0};
/* identifying (unique) number of newest history entry */
static int hislen = 0; /* actual length of history tables */
+/// Flag for command_line_handle_key to ignore <C-c>
+///
+/// Used if it was received while processing highlight function in order for
+/// user interrupting highlight function to not interrupt command-line.
+static bool getln_interrupted_highlight = false;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_getln.c.generated.h"
#endif
-static int cmd_hkmap = 0; /* Hebrew mapping during command line */
+static int cmd_hkmap = 0; // Hebrew mapping during command line
+static int cmd_fkmap = 0; // Farsi mapping during command line
-static int cmd_fkmap = 0; /* Farsi mapping during command line */
+/// Internal entry point for cmdline mode.
+///
+/// caller must use save_cmdline and restore_cmdline. Best is to use
+/// getcmdline or getcmdline_prompt, instead of calling this directly.
static uint8_t *command_line_enter(int firstc, long count, int indent)
{
+ // can be invoked recursively, identify each level
+ static int cmdline_level = 0;
+ cmdline_level++;
+
CommandLineState state, *s = &state;
memset(s, 0, sizeof(CommandLineState));
s->firstc = firstc;
@@ -160,7 +239,14 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
s->indent = indent;
s->save_msg_scroll = msg_scroll;
s->save_State = State;
+ s->save_p_icm = vim_strsave(p_icm);
s->ignore_drag_release = true;
+ s->match_start = curwin->w_cursor;
+ s->init_curswant = curwin->w_curswant;
+ s->init_leftcol = curwin->w_leftcol;
+ s->init_topline = curwin->w_topline;
+ s->init_topfill = curwin->w_topfill;
+ s->init_botline = curwin->w_botline;
if (s->firstc == -1) {
s->firstc = NUL;
@@ -172,8 +258,12 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
cmd_hkmap = 0;
}
+ ccline.prompt_id = last_prompt_id++;
+ ccline.level = cmdline_level;
ccline.overstrike = false; // always start in insert mode
- s->old_cursor = curwin->w_cursor; // needs to be restored later
+ clearpos(&s->match_end);
+ s->save_cursor = curwin->w_cursor; // may be restored later
+ s->search_start = curwin->w_cursor;
s->old_curswant = curwin->w_curswant;
s->old_leftcol = curwin->w_leftcol;
s->old_topline = curwin->w_topline;
@@ -189,6 +279,10 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
ccline.cmdlen = ccline.cmdpos = 0;
ccline.cmdbuff[0] = NUL;
+ ccline.last_colors = (ColoredCmdline){ .cmdbuff = NULL,
+ .colors = KV_INITIAL_VALUE };
+ sb_text_start_cmdline();
+
// autoindent for :insert and :append
if (s->firstc <= 0) {
memset(ccline.cmdbuff, ' ', s->indent);
@@ -210,10 +304,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
redir_off = true; // don't redirect the typed command
if (!cmd_silent) {
- s->i = msg_scrolled;
- msg_scrolled = 0; // avoid wait_return message
gotocmdline(true);
- msg_scrolled += s->i;
redrawcmdprompt(); // draw prompt or indent
set_cmdspos();
}
@@ -262,12 +353,68 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
redrawcmd();
}
+ // redraw the statusline for statuslines that display the current mode
+ // using the mode() function.
+ if (KeyTyped && msg_scrolled == 0) {
+ curwin->w_redr_status = true;
+ redraw_statuslines();
+ }
+
did_emsg = false;
got_int = false;
s->state.check = command_line_check;
s->state.execute = command_line_execute;
+
+ TryState tstate;
+ Error err = ERROR_INIT;
+ bool tl_ret = true;
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+ char firstcbuf[2];
+ firstcbuf[0] = firstc > 0 ? firstc : '-';
+ firstcbuf[1] = 0;
+
+ if (has_event(EVENT_CMDLINEENTER)) {
+ // set v:event to a dictionary with information about the commandline
+ tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
+ tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
+ tv_dict_set_keys_readonly(dict);
+ try_enter(&tstate);
+
+ apply_autocmds(EVENT_CMDLINEENTER, (char_u *)firstcbuf, (char_u *)firstcbuf,
+ false, curbuf);
+ tv_dict_clear(dict);
+
+
+ tl_ret = try_leave(&tstate, &err);
+ if (!tl_ret && ERROR_SET(&err)) {
+ msg_putchar('\n');
+ msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
+ api_clear_error(&err);
+ redrawcmd();
+ }
+ tl_ret = true;
+ }
+
state_enter(&s->state);
+ if (has_event(EVENT_CMDLINELEAVE)) {
+ tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
+ tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
+ tv_dict_set_keys_readonly(dict);
+ // not readonly:
+ tv_dict_add_special(dict, S_LEN("abort"),
+ s->gotesc ? kSpecialVarTrue : kSpecialVarFalse);
+ try_enter(&tstate);
+ apply_autocmds(EVENT_CMDLINELEAVE, (char_u *)firstcbuf, (char_u *)firstcbuf,
+ false, curbuf);
+ // error printed below, to avoid redraw issues
+ tl_ret = try_leave(&tstate, &err);
+ if (tv_dict_get_number(dict, "abort") != 0) {
+ s->gotesc = 1;
+ }
+ tv_dict_clear(dict);
+ }
+
cmdmsg_rl = false;
cmd_fkmap = 0;
@@ -276,7 +423,16 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
ccline.xpc = NULL;
if (s->did_incsearch) {
- curwin->w_cursor = s->old_cursor;
+ if (s->gotesc) {
+ curwin->w_cursor = s->save_cursor;
+ } else {
+ if (!equalpos(s->save_cursor, s->search_start)) {
+ // put the '" mark at the original position
+ curwin->w_cursor = s->save_cursor;
+ setpcmark();
+ }
+ curwin->w_cursor = s->search_start; // -V519
+ }
curwin->w_curswant = s->old_curswant;
curwin->w_leftcol = s->old_leftcol;
curwin->w_topline = s->old_topline;
@@ -284,7 +440,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
curwin->w_botline = s->old_botline;
highlight_match = false;
validate_cursor(); // needed for TAB
- redraw_later(SOME_VALID);
+ redraw_all_later(SOME_VALID);
}
if (ccline.cmdbuff != NULL) {
@@ -301,14 +457,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
}
}
- if (s->gotesc) { // abandon command line
- xfree(ccline.cmdbuff);
- ccline.cmdbuff = NULL;
- if (msg_scrolled == 0) {
- compute_cmdrow();
- }
- MSG("");
- redraw_cmdline = true;
+ if (s->gotesc) {
+ abandon_cmdline();
}
}
@@ -319,22 +469,36 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
msg_scroll = s->save_msg_scroll;
redir_off = false;
+ if (!tl_ret && ERROR_SET(&err)) {
+ msg_putchar('\n');
+ msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
+ api_clear_error(&err);
+ }
+
// When the command line was typed, no need for a wait-return prompt.
- if (s->some_key_typed) {
+ if (s->some_key_typed && tl_ret) {
need_wait_return = false;
}
+ set_string_option_direct((char_u *)"icm", -1, s->save_p_icm, OPT_FREE,
+ SID_NONE);
State = s->save_State;
setmouse();
ui_cursor_shape(); // may show different cursor shape
+ xfree(s->save_p_icm);
+ xfree(ccline.last_colors.cmdbuff);
+ kv_destroy(ccline.last_colors.colors);
- {
- char_u *p = ccline.cmdbuff;
+ sb_text_end_cmdline();
+
+ char_u *p = ccline.cmdbuff;
- // Make ccline empty, getcmdline() may try to use it.
- ccline.cmdbuff = NULL;
- return p;
+ if (ui_is_external(kUICmdline)) {
+ ui_call_cmdline_hide(ccline.level);
}
+
+ cmdline_level--;
+ return p;
}
static int command_line_check(VimState *state)
@@ -344,7 +508,12 @@ static int command_line_check(VimState *state)
// completion may switch it on.
quit_more = false; // reset after CTRL-D which had a more-prompt
+ did_emsg = false; // There can't really be a reason why an error
+ // that occurs while typing a command should
+ // cause the command not to be executed.
+
cursorcmd(); // set the cursor on the right spot
+ ui_cursor_shape();
return 1;
}
@@ -357,8 +526,12 @@ static int command_line_execute(VimState *state, int key)
CommandLineState *s = (CommandLineState *)state;
s->c = key;
- if (s->c == K_EVENT) {
- queue_process_events(main_loop.events);
+ if (s->c == K_EVENT || s->c == K_COMMAND) {
+ if (s->c == K_EVENT) {
+ multiqueue_process_events(main_loop.events);
+ } else {
+ do_cmdline(NULL, getcmdkeycmd, NULL, DOCMD_NOWAIT);
+ }
redrawcmdline();
return 1;
}
@@ -437,18 +610,22 @@ static int command_line_execute(VimState *state, int key)
}
// free expanded names when finished walking through matches
- if (s->xpc.xp_numfiles != -1
- && !(s->c == p_wc && KeyTyped) && s->c != p_wcm
+ if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm
&& s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A
&& s->c != Ctrl_L) {
- (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
+ if (ui_is_external(kUIWildmenu)) {
+ ui_call_wildmenu_hide();
+ }
+ if (s->xpc.xp_numfiles != -1) {
+ (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE);
+ }
s->did_wild_list = false;
if (!p_wmnu || (s->c != K_UP && s->c != K_DOWN)) {
s->xpc.xp_context = EXPAND_NOTHING;
}
s->wim_index = 0;
if (p_wmnu && wild_menu_showing != 0) {
- int skt = KeyTyped;
+ const bool skt = KeyTyped;
int old_RedrawingDisabled = RedrawingDisabled;
if (ccline.input_fn) {
@@ -459,22 +636,22 @@ static int command_line_execute(VimState *state, int key)
// Entered command line, move it up
cmdline_row--;
redrawcmd();
+ wild_menu_showing = 0;
} else if (save_p_ls != -1) {
// restore 'laststatus' and 'winminheight'
p_ls = save_p_ls;
p_wmh = save_p_wmh;
last_status(false);
- save_cmdline(&s->save_ccline);
update_screen(VALID); // redraw the screen NOW
- restore_cmdline(&s->save_ccline);
redrawcmd();
save_p_ls = -1;
+ wild_menu_showing = 0;
} else {
win_redraw_last_status(topframe);
+ wild_menu_showing = 0; // must be before redraw_statuslines #8385
redraw_statuslines();
}
KeyTyped = skt;
- wild_menu_showing = 0;
if (ccline.input_fn) {
RedrawingDisabled = old_RedrawingDisabled;
}
@@ -547,9 +724,7 @@ static int command_line_execute(VimState *state, int key)
s->j = ccline.cmdpos;
s->i = (int)(s->xpc.xp_pattern - ccline.cmdbuff);
while (--s->j > s->i) {
- if (has_mbyte) {
- s->j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + s->j);
- }
+ s->j -= utf_head_off(ccline.cmdbuff, ccline.cmdbuff + s->j);
if (vim_ispathsep(ccline.cmdbuff[s->j])) {
found = true;
break;
@@ -569,12 +744,10 @@ static int command_line_execute(VimState *state, int key)
s->j = ccline.cmdpos - 1;
s->i = (int)(s->xpc.xp_pattern - ccline.cmdbuff);
while (--s->j > s->i) {
- if (has_mbyte) {
- s->j -= (*mb_head_off)(ccline.cmdbuff, ccline.cmdbuff + s->j);
- }
+ s->j -= utf_head_off(ccline.cmdbuff, ccline.cmdbuff + s->j);
if (vim_ispathsep(ccline.cmdbuff[s->j])
#ifdef BACKSLASH_IN_FILENAME
- && vim_strchr(" *?[{`$%#", ccline.cmdbuff[s->j + 1])
+ && vim_strchr((const char_u *)" *?[{`$%#", ccline.cmdbuff[s->j + 1])
== NULL
#endif
) {
@@ -617,16 +790,16 @@ static int command_line_execute(VimState *state, int key)
// CTRL-\ CTRL-N goes to Normal mode, CTRL-\ CTRL-G goes to Insert
// mode when 'insertmode' is set, CTRL-\ e prompts for an expression.
if (s->c == Ctrl_BSL) {
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
s->c = plain_vgetc();
- --no_mapping;
- --allow_keys;
+ no_mapping--;
// CTRL-\ e doesn't work when obtaining an expression, unless it
// is in a mapping.
- if (s->c != Ctrl_N && s->c != Ctrl_G && (s->c != 'e'
- || (ccline.cmdfirstc == '='
- && KeyTyped))) {
+ if (s->c != Ctrl_N
+ && s->c != Ctrl_G
+ && (s->c != 'e'
+ || (ccline.cmdfirstc == '=' && KeyTyped)
+ || cmdline_star > 0)) {
vungetc(s->c);
s->c = Ctrl_BSL;
} else if (s->c == 'e') {
@@ -642,18 +815,17 @@ static int command_line_execute(VimState *state, int key)
new_cmdpos = ccline.cmdpos;
}
- save_cmdline(&s->save_ccline);
s->c = get_expr_register();
- restore_cmdline(&s->save_ccline);
if (s->c == '=') {
// Need to save and restore ccline. And set "textlock"
// to avoid nasty things like going to another buffer when
// evaluating an expression.
- save_cmdline(&s->save_ccline);
- ++textlock;
+ CmdlineInfo save_ccline;
+ save_cmdline(&save_ccline);
+ textlock++;
p = get_expr_line();
- --textlock;
- restore_cmdline(&s->save_ccline);
+ textlock--;
+ restore_cmdline(&save_ccline);
if (p != NULL) {
len = (int)STRLEN(p);
@@ -694,7 +866,7 @@ static int command_line_execute(VimState *state, int key)
if (s->c == cedit_key || s->c == K_CMDWIN) {
if (ex_normal_busy == 0 && got_int == false) {
// Open a window to edit the command line (and history).
- s->c = ex_window();
+ s->c = open_cmdwin();
s->some_key_typed = true;
}
} else {
@@ -723,7 +895,9 @@ static int command_line_execute(VimState *state, int key)
}
if (!cmd_silent) {
- ui_cursor_goto(msg_row, 0);
+ if (!ui_is_external(kUICmdline)) {
+ ui_cursor_goto(msg_row, 0);
+ }
ui_flush();
}
return 0;
@@ -849,6 +1023,144 @@ static int command_line_execute(VimState *state, int key)
return command_line_handle_key(s);
}
+static void command_line_next_incsearch(CommandLineState *s, bool next_match)
+{
+ ui_busy_start();
+ ui_flush();
+
+ pos_T t;
+ char_u *pat;
+ int search_flags = SEARCH_NOOF;
+
+
+ if (s->firstc == ccline.cmdbuff[0]) {
+ pat = last_search_pattern();
+ } else {
+ pat = ccline.cmdbuff;
+ }
+
+ save_last_search_pattern();
+
+ if (next_match) {
+ t = s->match_end;
+ if (lt(s->match_start, s->match_end)) {
+ // start searching at the end of the match
+ // not at the beginning of the next column
+ (void)decl(&t);
+ }
+ search_flags += SEARCH_COL;
+ } else {
+ t = s->match_start;
+ }
+ if (!p_hls) {
+ search_flags += SEARCH_KEEP;
+ }
+ emsg_off++;
+ s->i = searchit(curwin, curbuf, &t,
+ next_match ? FORWARD : BACKWARD,
+ pat, s->count, search_flags,
+ RE_SEARCH, 0, NULL);
+ emsg_off--;
+ ui_busy_stop();
+ if (s->i) {
+ s->search_start = s->match_start;
+ s->match_end = t;
+ s->match_start = t;
+ if (!next_match && s->firstc == '/') {
+ // move just before the current match, so that
+ // when nv_search finishes the cursor will be
+ // put back on the match
+ s->search_start = t;
+ (void)decl(&s->search_start);
+ } else if (next_match && s->firstc == '?') {
+ // move just after the current match, so that
+ // when nv_search finishes the cursor will be
+ // put back on the match
+ s->search_start = t;
+ (void)incl(&s->search_start);
+ }
+ if (lt(t, s->search_start) && next_match) {
+ // wrap around
+ s->search_start = t;
+ if (s->firstc == '?') {
+ (void)incl(&s->search_start);
+ } else {
+ (void)decl(&s->search_start);
+ }
+ }
+
+ set_search_match(&s->match_end);
+ curwin->w_cursor = s->match_start;
+ changed_cline_bef_curs();
+ update_topline();
+ validate_cursor();
+ highlight_match = true;
+ s->old_curswant = curwin->w_curswant;
+ s->old_leftcol = curwin->w_leftcol;
+ s->old_topline = curwin->w_topline;
+ s->old_topfill = curwin->w_topfill;
+ s->old_botline = curwin->w_botline;
+ update_screen(NOT_VALID);
+ redrawcmdline();
+ } else {
+ vim_beep(BO_ERROR);
+ }
+ restore_last_search_pattern();
+ return;
+}
+
+static void command_line_next_histidx(CommandLineState *s, bool next_match)
+{
+ s->j = (int)STRLEN(s->lookfor);
+ for (;; ) {
+ // one step backwards
+ if (!next_match) {
+ if (s->hiscnt == hislen) {
+ // first time
+ s->hiscnt = hisidx[s->histype];
+ } else if (s->hiscnt == 0 && hisidx[s->histype] != hislen - 1) {
+ s->hiscnt = hislen - 1;
+ } else if (s->hiscnt != hisidx[s->histype] + 1) {
+ s->hiscnt--;
+ } else {
+ // at top of list
+ s->hiscnt = s->i;
+ break;
+ }
+ } else { // one step forwards
+ // on last entry, clear the line
+ if (s->hiscnt == hisidx[s->histype]) {
+ s->hiscnt = hislen;
+ break;
+ }
+
+ // not on a history line, nothing to do
+ if (s->hiscnt == hislen) {
+ break;
+ }
+
+ if (s->hiscnt == hislen - 1) {
+ // wrap around
+ s->hiscnt = 0;
+ } else {
+ s->hiscnt++;
+ }
+ }
+
+ if (s->hiscnt < 0 || history[s->histype][s->hiscnt].hisstr == NULL) {
+ s->hiscnt = s->i;
+ break;
+ }
+
+ if ((s->c != K_UP && s->c != K_DOWN)
+ || s->hiscnt == s->i
+ || STRNCMP(history[s->histype][s->hiscnt].hisstr,
+ s->lookfor, (size_t)s->j) == 0) {
+ break;
+ }
+ }
+}
+
static int command_line_handle_key(CommandLineState *s)
{
// Big switch for a typed command line character.
@@ -921,6 +1233,16 @@ static int command_line_handle_key(CommandLineState *s)
// Truncate at the end, required for multi-byte chars.
ccline.cmdbuff[ccline.cmdlen] = NUL;
+ if (ccline.cmdlen == 0) {
+ s->search_start = s->save_cursor;
+ // save view settings, so that the screen won't be restored at the
+ // wrong position
+ s->old_curswant = s->init_curswant;
+ s->old_leftcol = s->init_leftcol;
+ s->old_topline = s->init_topline;
+ s->old_topfill = s->init_topfill;
+ s->old_botline = s->init_botline;
+ }
redrawcmd();
} else if (ccline.cmdlen == 0 && s->c != Ctrl_W
&& ccline.cmdprompt == NULL && s->indent == 0) {
@@ -931,7 +1253,7 @@ static int command_line_handle_key(CommandLineState *s)
xfree(ccline.cmdbuff); // no commandline to return
ccline.cmdbuff = NULL;
- if (!cmd_silent) {
+ if (!cmd_silent && !ui_is_external(kUICmdline)) {
if (cmdmsg_rl) {
msg_col = Columns;
} else {
@@ -939,6 +1261,7 @@ static int command_line_handle_key(CommandLineState *s)
}
msg_putchar(' '); // delete ':'
}
+ s->search_start = s->save_cursor;
redraw_cmdline = true;
return 0; // back to cmd mode
}
@@ -958,7 +1281,7 @@ static int command_line_handle_key(CommandLineState *s)
return command_line_not_changed(s);
case Ctrl_HAT:
- if (map_to_exists_mode((char_u *)"", LANGMAP, false)) {
+ if (map_to_exists_mode("", LANGMAP, false)) {
// ":lmap" mappings exists, toggle use of mappings.
State ^= LANGMAP;
if (s->b_im_ptr != NULL) {
@@ -982,7 +1305,6 @@ static int command_line_handle_key(CommandLineState *s)
status_redraw_curbuf();
return command_line_not_changed(s);
- // case '@': only in very old vi
case Ctrl_U:
// delete all characters left of the cursor
s->j = ccline.cmdpos;
@@ -994,15 +1316,20 @@ static int command_line_handle_key(CommandLineState *s)
// Truncate at the end, required for multi-byte chars.
ccline.cmdbuff[ccline.cmdlen] = NUL;
+ if (ccline.cmdlen == 0) {
+ s->search_start = s->save_cursor;
+ }
redrawcmd();
return command_line_changed(s);
-
case ESC: // get here if p_wc != ESC or when ESC typed twice
case Ctrl_C:
// In exmode it doesn't make sense to return. Except when
- // ":normal" runs out of characters.
- if (exmode_active && (ex_normal_busy == 0 || typebuf.tb_len > 0)) {
+ // ":normal" runs out of characters. Also when highlight callback is active
+ // <C-c> should interrupt only it.
+ if ((exmode_active && (ex_normal_busy == 0 || typebuf.tb_len > 0))
+ || (getln_interrupted_highlight && s->c == Ctrl_C)) {
+ getln_interrupted_highlight = false;
return command_line_not_changed(s);
}
@@ -1027,13 +1354,15 @@ static int command_line_handle_key(CommandLineState *s)
// a new one...
new_cmdpos = -1;
if (s->c == '=') {
- if (ccline.cmdfirstc == '=') { // can't do this recursively
+ if (ccline.cmdfirstc == '=' // can't do this recursively
+ || cmdline_star > 0) { // or when typing a password
beep_flush();
s->c = ESC;
} else {
- save_cmdline(&s->save_ccline);
+ CmdlineInfo save_ccline;
+ save_cmdline(&save_ccline);
s->c = get_expr_register();
- restore_cmdline(&s->save_ccline);
+ restore_cmdline(&save_ccline);
}
}
@@ -1065,6 +1394,7 @@ static int command_line_handle_key(CommandLineState *s)
break; // Use ^D as normal char instead
}
+ wild_menu_showing = WM_LIST;
redrawcmd();
return 1; // don't do incremental search now
@@ -1103,25 +1433,22 @@ static int command_line_handle_key(CommandLineState *s)
return command_line_not_changed(s);
}
do {
- --ccline.cmdpos;
- if (has_mbyte) { // move to first byte of char
- ccline.cmdpos -= (*mb_head_off)(ccline.cmdbuff,
- ccline.cmdbuff + ccline.cmdpos);
- }
+ ccline.cmdpos--;
+ // Move to first byte of possibly multibyte char.
+ ccline.cmdpos -= utf_head_off(ccline.cmdbuff,
+ ccline.cmdbuff + ccline.cmdpos);
ccline.cmdspos -= cmdline_charsize(ccline.cmdpos);
} while (ccline.cmdpos > 0
&& (s->c == K_S_LEFT || s->c == K_C_LEFT
|| (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)))
&& ccline.cmdbuff[ccline.cmdpos - 1] != ' ');
- if (has_mbyte) {
- set_cmdspos_cursor();
- }
+ set_cmdspos_cursor();
return command_line_not_changed(s);
case K_IGNORE:
- // Ignore mouse event or ex_window() result.
+ // Ignore mouse event or open_cmdwin() result.
return command_line_not_changed(s);
@@ -1147,7 +1474,7 @@ static int command_line_handle_key(CommandLineState *s)
if (s->ignore_drag_release) {
return command_line_not_changed(s);
}
- // FALLTHROUGH
+ FALLTHROUGH;
case K_LEFTMOUSE:
case K_RIGHTMOUSE:
if (s->c == K_LEFTRELEASE || s->c == K_RIGHTRELEASE) {
@@ -1224,24 +1551,27 @@ static int command_line_handle_key(CommandLineState *s)
case Ctrl_L:
if (p_is && !cmd_silent && (s->firstc == '/' || s->firstc == '?')) {
// Add a character from under the cursor for 'incsearch'
- if (s->did_incsearch && !equalpos(curwin->w_cursor, s->old_cursor)) {
- s->c = gchar_cursor();
- // If 'ignorecase' and 'smartcase' are set and the
- // command line has no uppercase characters, convert
- // the character to lowercase
- if (p_ic && p_scs && !pat_has_uppercase(ccline.cmdbuff)) {
- s->c = vim_tolower(s->c);
- }
-
- if (s->c != NUL) {
- if (s->c == s->firstc
- || vim_strchr((char_u *)(p_magic ? "\\^$.*[" : "\\^$"), s->c)
- != NULL) {
- // put a backslash before special characters
- stuffcharReadbuff(s->c);
- s->c = '\\';
+ if (s->did_incsearch) {
+ curwin->w_cursor = s->match_end;
+ if (!equalpos(curwin->w_cursor, s->search_start)) {
+ s->c = gchar_cursor();
+ // If 'ignorecase' and 'smartcase' are set and the
+ // command line has no uppercase characters, convert
+ // the character to lowercase
+ if (p_ic && p_scs
+ && !pat_has_uppercase(ccline.cmdbuff)) {
+ s->c = mb_tolower(s->c);
+ }
+ if (s->c != NUL) {
+ if (s->c == s->firstc
+ || vim_strchr((char_u *)(p_magic ? "\\~^$.*[" : "\\^$"), s->c)
+ != NULL) {
+ // put a backslash before special characters
+ stuffcharReadbuff(s->c);
+ s->c = '\\';
+ }
+ break;
}
- break;
}
}
return command_line_not_changed(s);
@@ -1260,8 +1590,9 @@ static int command_line_handle_key(CommandLineState *s)
0, s->firstc != '@') == FAIL) {
break;
}
- return command_line_changed(s);
+ return command_line_not_changed(s);
}
+ FALLTHROUGH;
case K_UP:
case K_DOWN:
@@ -1284,60 +1615,14 @@ static int command_line_handle_key(CommandLineState *s)
s->lookfor[ccline.cmdpos] = NUL;
}
- s->j = (int)STRLEN(s->lookfor);
- for (;; ) {
- // one step backwards
- if (s->c == K_UP|| s->c == K_S_UP || s->c == Ctrl_P
- || s->c == K_PAGEUP || s->c == K_KPAGEUP) {
- if (s->hiscnt == hislen) {
- // first time
- s->hiscnt = hisidx[s->histype];
- } else if (s->hiscnt == 0 && hisidx[s->histype] != hislen - 1) {
- s->hiscnt = hislen - 1;
- } else if (s->hiscnt != hisidx[s->histype] + 1) {
- --s->hiscnt;
- } else {
- // at top of list
- s->hiscnt = s->i;
- break;
- }
- } else { // one step forwards
- // on last entry, clear the line
- if (s->hiscnt == hisidx[s->histype]) {
- s->hiscnt = hislen;
- break;
- }
-
- // not on a history line, nothing to do
- if (s->hiscnt == hislen) {
- break;
- }
-
- if (s->hiscnt == hislen - 1) {
- // wrap around
- s->hiscnt = 0;
- } else {
- ++s->hiscnt;
- }
- }
-
- if (s->hiscnt < 0 || history[s->histype][s->hiscnt].hisstr == NULL) {
- s->hiscnt = s->i;
- break;
- }
-
- if ((s->c != K_UP && s->c != K_DOWN)
- || s->hiscnt == s->i
- || STRNCMP(history[s->histype][s->hiscnt].hisstr,
- s->lookfor, (size_t)s->j) == 0) {
- break;
- }
- }
+ bool next_match = (s->c == K_DOWN || s->c == K_S_DOWN || s->c == Ctrl_N
+ || s->c == K_PAGEDOWN || s->c == K_KPAGEDOWN);
+ command_line_next_histidx(s, next_match);
if (s->hiscnt != s->i) {
// jumped to other entry
char_u *p;
- int len;
+ int len = 0;
int old_firstc;
xfree(ccline.cmdbuff);
@@ -1400,6 +1685,16 @@ static int command_line_handle_key(CommandLineState *s)
beep_flush();
return command_line_not_changed(s);
+ case Ctrl_G: // next match
+ case Ctrl_T: // previous match
+ if (p_is && !cmd_silent && (s->firstc == '/' || s->firstc == '?')) {
+ if (ccline.cmdlen != 0) {
+ command_line_next_incsearch(s, s->c == Ctrl_G);
+ }
+ return command_line_not_changed(s);
+ }
+ break;
+
case Ctrl_V:
case Ctrl_Q:
s->ignore_drag_release = true;
@@ -1408,9 +1703,14 @@ static int command_line_handle_key(CommandLineState *s)
s->do_abbr = false; // don't do abbreviation now
// may need to remove ^ when composing char was typed
if (enc_utf8 && utf_iscomposing(s->c) && !cmd_silent) {
- draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
- msg_putchar(' ');
- cursorcmd();
+ if (ui_is_external(kUICmdline)) {
+ // TODO(bfredl): why not make unputcmdline also work with true?
+ unputcmdline();
+ } else {
+ draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
+ msg_putchar(' ');
+ cursorcmd();
+ }
}
break;
@@ -1442,14 +1742,6 @@ static int command_line_handle_key(CommandLineState *s)
}
return command_line_not_changed(s);
- case K_FOCUSGAINED: // Neovim has been given focus
- apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
- return command_line_not_changed(s);
-
- case K_FOCUSLOST: // Neovim has lost focus
- apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
- return command_line_not_changed(s);
-
default:
// Normal character with no special meaning. Just set mod_mask
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
@@ -1475,14 +1767,9 @@ static int command_line_handle_key(CommandLineState *s)
if (IS_SPECIAL(s->c) || mod_mask != 0) {
put_on_cmdline(get_special_key_name(s->c, mod_mask), -1, true);
} else {
- if (has_mbyte) {
- s->j = (*mb_char2bytes)(s->c, IObuff);
- IObuff[s->j] = NUL; // exclude composing chars
- put_on_cmdline(IObuff, s->j, true);
- } else {
- IObuff[0] = s->c;
- put_on_cmdline(IObuff, 1, true);
- }
+ s->j = utf_char2bytes(s->c, IObuff);
+ IObuff[s->j] = NUL; // exclude composing chars
+ put_on_cmdline(IObuff, s->j, true);
}
return command_line_changed(s);
}
@@ -1490,19 +1777,62 @@ static int command_line_handle_key(CommandLineState *s)
static int command_line_not_changed(CommandLineState *s)
{
- // This part implements incremental searches for "/" and "?" Jump to
- // cmdline_not_changed when a character has been read but the command line
- // did not change. Then we only search and redraw if something changed in
- // the past. Jump to cmdline_changed when the command line did change.
- // (Sorry for the goto's, I know it is ugly).
+ // Incremental searches for "/" and "?":
+ // Enter command_line_not_changed() when a character has been read but the
+ // command line did not change. Then we only search and redraw if something
+ // changed in the past.
+ // Enter command_line_changed() when the command line did change.
if (!s->incsearch_postponed) {
return 1;
}
return command_line_changed(s);
}
+/// Guess that the pattern matches everything. Only finds specific cases, such
+/// as a trailing \|, which can happen while typing a pattern.
+static int empty_pattern(char_u *p)
+{
+ size_t n = STRLEN(p);
+
+ // remove trailing \v and the like
+ while (n >= 2 && p[n - 2] == '\\'
+ && vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL) {
+ n -= 2;
+ }
+ return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
+}
+
static int command_line_changed(CommandLineState *s)
{
+ // Trigger CmdlineChanged autocommands.
+ if (has_event(EVENT_CMDLINECHANGED)) {
+ TryState tstate;
+ Error err = ERROR_INIT;
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+
+ char firstcbuf[2];
+ firstcbuf[0] = s->firstc > 0 ? s->firstc : '-';
+ firstcbuf[1] = 0;
+
+ // set v:event to a dictionary with information about the commandline
+ tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf);
+ tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
+ tv_dict_set_keys_readonly(dict);
+ try_enter(&tstate);
+
+ apply_autocmds(EVENT_CMDLINECHANGED, (char_u *)firstcbuf,
+ (char_u *)firstcbuf, false, curbuf);
+ tv_dict_clear(dict);
+
+ bool tl_ret = try_leave(&tstate, &err);
+ if (!tl_ret && ERROR_SET(&err)) {
+ msg_putchar('\n');
+ msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, (char *)e_autocmd_err, err.msg);
+ api_clear_error(&err);
+ redrawcmd();
+ }
+ }
+
// 'incsearch' highlighting.
if (p_is && !cmd_silent && (s->firstc == '/' || s->firstc == '?')) {
pos_T end_pos;
@@ -1514,21 +1844,28 @@ static int command_line_changed(CommandLineState *s)
return 1;
}
s->incsearch_postponed = false;
- curwin->w_cursor = s->old_cursor; // start at old position
+ curwin->w_cursor = s->search_start; // start at old position
+ save_last_search_pattern();
// If there is no command line, don't do anything
if (ccline.cmdlen == 0) {
s->i = 0;
+ SET_NO_HLSEARCH(true); // turn off previous highlight
+ redraw_all_later(SOME_VALID);
} else {
+ int search_flags = SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK;
ui_busy_start();
ui_flush();
++emsg_off; // So it doesn't beep if bad expr
// Set the time limit to half a second.
tm = profile_setlimit(500L);
+ if (!p_hls) {
+ search_flags += SEARCH_KEEP;
+ }
s->i = do_search(NULL, s->firstc, ccline.cmdbuff, s->count,
- SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
- &tm);
- --emsg_off;
+ search_flags,
+ &tm);
+ emsg_off--;
// if interrupted while searching, behave like it failed
if (got_int) {
(void)vpeekc(); // remove <C-C> from input stream
@@ -1559,30 +1896,30 @@ static int command_line_changed(CommandLineState *s)
if (s->i != 0) {
pos_T save_pos = curwin->w_cursor;
- // First move cursor to end of match, then to the start. This
- // moves the whole match onto the screen when 'nowrap' is set.
- curwin->w_cursor.lnum += search_match_lines;
- curwin->w_cursor.col = search_match_endcol;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
- curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
- coladvance((colnr_T)MAXCOL);
- }
+ s->match_start = curwin->w_cursor;
+ set_search_match(&curwin->w_cursor);
validate_cursor();
end_pos = curwin->w_cursor;
+ s->match_end = end_pos;
curwin->w_cursor = save_pos;
} else {
end_pos = curwin->w_cursor; // shutup gcc 4
}
+ // Disable 'hlsearch' highlighting if the pattern matches
+ // everything. Avoids a flash when typing "foo\|".
+ if (empty_pattern(ccline.cmdbuff)) {
+ SET_NO_HLSEARCH(true);
+ }
+
validate_cursor();
// May redraw the status line to show the cursor position.
if (p_ru && curwin->w_status_height > 0) {
curwin->w_redr_status = true;
}
- save_cmdline(&s->save_ccline);
update_screen(SOME_VALID);
- restore_cmdline(&s->save_ccline);
+ restore_last_search_pattern();
// Leave it at the end to make CTRL-R CTRL-W work.
if (s->i != 0) {
@@ -1592,6 +1929,36 @@ static int command_line_changed(CommandLineState *s)
msg_starthere();
redrawcmdline();
s->did_incsearch = true;
+ } else if (s->firstc == ':'
+ && current_SID == 0 // only if interactive
+ && *p_icm != NUL // 'inccommand' is set
+ && curbuf->b_p_ma // buffer is modifiable
+ && cmdline_star == 0 // not typing a password
+ && cmd_can_preview(ccline.cmdbuff)
+ && !vpeekc_any()) {
+ // Show 'inccommand' preview. It works like this:
+ // 1. Do the command.
+ // 2. Command implementation detects CMDPREVIEW state, then:
+ // - Update the screen while the effects are in place.
+ // - Immediately undo the effects.
+ State |= CMDPREVIEW;
+ emsg_silent++; // Block error reporting as the command may be incomplete
+ do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT);
+ emsg_silent--; // Unblock error reporting
+
+ // Restore the window "view".
+ curwin->w_cursor = s->save_cursor;
+ curwin->w_curswant = s->old_curswant;
+ curwin->w_leftcol = s->old_leftcol;
+ curwin->w_topline = s->old_topline;
+ curwin->w_topfill = s->old_topfill;
+ curwin->w_botline = s->old_botline;
+ update_topline();
+
+ redrawcmdline();
+ } else if (State & CMDPREVIEW) {
+ State = (State & ~CMDPREVIEW);
+ update_screen(SOME_VALID); // Clear 'inccommand' preview.
}
if (cmdmsg_rl || (p_arshape && !p_tbidi && enc_utf8)) {
@@ -1599,7 +1966,8 @@ static int command_line_changed(CommandLineState *s)
// right-left typing. Not efficient, but it works.
// Do it only when there are no characters left to read
// to avoid useless intermediate redraws.
- if (vpeekc() == NUL) {
+ // if cmdline is external the ui handles shaping, no redraw needed.
+ if (!ui_is_external(kUICmdline) && vpeekc() == NUL) {
redrawcmd();
}
}
@@ -1607,6 +1975,18 @@ static int command_line_changed(CommandLineState *s)
return 1;
}
+/// Abandon the command line.
+static void abandon_cmdline(void)
+{
+ xfree(ccline.cmdbuff);
+ ccline.cmdbuff = NULL;
+ if (msg_scrolled == 0) {
+ compute_cmdrow();
+ }
+ MSG("");
+ redraw_cmdline = true;
+}
+
/*
* getcmdline() - accept a command line starting with firstc.
*
@@ -1633,44 +2013,64 @@ getcmdline (
int indent // indent for inside conditionals
)
{
- return command_line_enter(firstc, count, indent);
+ // Be prepared for situations where cmdline can be invoked recursively.
+ // That includes cmd mappings, event handlers, as well as update_screen()
+ // (custom status line eval), which all may invoke ":normal :".
+ CmdlineInfo save_ccline;
+ save_cmdline(&save_ccline);
+ char_u *retval = command_line_enter(firstc, count, indent);
+ restore_cmdline(&save_ccline);
+ return retval;
}
-/*
- * Get a command line with a prompt.
- * This is prepared to be called recursively from getcmdline() (e.g. by
- * f_input() when evaluating an expression from CTRL-R =).
- * Returns the command line in allocated memory, or NULL.
- */
-char_u *
-getcmdline_prompt (
- int firstc,
- char_u *prompt, /* command line prompt */
- int attr, /* attributes for prompt */
- int xp_context, /* type of expansion */
- char_u *xp_arg /* user-defined expansion argument */
-)
+/// Get a command line with a prompt
+///
+/// This is prepared to be called recursively from getcmdline() (e.g. by
+/// f_input() when evaluating an expression from `<C-r>=`).
+///
+/// @param[in] firstc Prompt type: e.g. '@' for input(), '>' for debug.
+/// @param[in] prompt Prompt string: what is displayed before the user text.
+/// @param[in] attr Prompt highlighting.
+/// @param[in] xp_context Type of expansion.
+/// @param[in] xp_arg User-defined expansion argument.
+/// @param[in] highlight_callback Callback used for highlighting user input.
+///
+/// @return [allocated] Command line or NULL.
+char *getcmdline_prompt(const char firstc, const char *const prompt,
+ const int attr, const int xp_context,
+ const char *const xp_arg,
+ const Callback highlight_callback)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
- char_u *s;
- struct cmdline_info save_ccline;
- int msg_col_save = msg_col;
+ const int msg_col_save = msg_col;
+ CmdlineInfo save_ccline;
save_cmdline(&save_ccline);
- ccline.cmdprompt = prompt;
+
+ ccline.prompt_id = last_prompt_id++;
+ ccline.cmdprompt = (char_u *)prompt;
ccline.cmdattr = attr;
ccline.xp_context = xp_context;
- ccline.xp_arg = xp_arg;
+ ccline.xp_arg = (char_u *)xp_arg;
ccline.input_fn = (firstc == '@');
- s = getcmdline(firstc, 1L, 0);
+ ccline.highlight_callback = highlight_callback;
+
+ int msg_silent_saved = msg_silent;
+ msg_silent = 0;
+
+ char *const ret = (char *)command_line_enter(firstc, 1L, 0);
+
restore_cmdline(&save_ccline);
- /* Restore msg_col, the prompt from input() may have changed it.
- * But only if called recursively and the commandline is therefore being
- * restored to an old one; if not, the input() prompt stays on the screen,
- * so we need its modified msg_col left intact. */
- if (ccline.cmdbuff != NULL)
+ msg_silent = msg_silent_saved;
+ // Restore msg_col, the prompt from input() may have changed it.
+ // But only if called recursively and the commandline is therefore being
+ // restored to an old one; if not, the input() prompt stays on the screen,
+ // so we need its modified msg_col left intact.
+ if (ccline.cmdbuff != NULL) {
msg_col = msg_col_save;
+ }
- return s;
+ return ret;
}
/*
@@ -1689,10 +2089,15 @@ int text_locked(void) {
*/
void text_locked_msg(void)
{
- if (cmdwin_type != 0)
- EMSG(_(e_cmdwin));
- else
- EMSG(_(e_secure));
+ EMSG(_(get_text_locked_msg()));
+}
+
+char_u * get_text_locked_msg(void) {
+ if (cmdwin_type != 0) {
+ return e_cmdwin;
+ } else {
+ return e_secure;
+ }
}
/*
@@ -1776,10 +2181,11 @@ static void set_cmdspos_cursor(void)
*/
static void correct_cmdspos(int idx, int cells)
{
- if ((*mb_ptr2len)(ccline.cmdbuff + idx) > 1
- && (*mb_ptr2cells)(ccline.cmdbuff + idx) > 1
- && ccline.cmdspos % Columns + cells > Columns)
+ if (utfc_ptr2len(ccline.cmdbuff + idx) > 1
+ && utf_ptr2cells(ccline.cmdbuff + idx) > 1
+ && ccline.cmdspos % Columns + cells > Columns) {
ccline.cmdspos++;
+ }
}
/*
@@ -1795,6 +2201,7 @@ getexline (
/* When executing a register, remove ':' that's in front of each line. */
if (exec_from_reg && vpeekc() == ':')
(void)vgetc();
+
return getcmdline(c, 1L, indent);
}
@@ -1842,7 +2249,7 @@ getexmodeline (
vcol = indent;
while (indent >= 8) {
ga_append(&line_ga, TAB);
- msg_puts((char_u *)" ");
+ msg_puts(" ");
indent -= 8;
}
while (indent-- > 0) {
@@ -1850,8 +2257,7 @@ getexmodeline (
msg_putchar(' ');
}
}
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
/*
* Get the line, one character at a time.
@@ -1863,7 +2269,13 @@ getexmodeline (
/* Get one character at a time. Don't use inchar(), it can't handle
* special characters. */
prev_char = c1;
- c1 = vgetc();
+
+ // Check for a ":normal" command and no more characters left.
+ if (ex_normal_busy > 0 && typebuf.tb_len == 0) {
+ c1 = '\n';
+ } else {
+ c1 = vgetc();
+ }
/*
* Handle line editing.
@@ -1882,14 +2294,10 @@ getexmodeline (
if (c1 == BS || c1 == K_BS || c1 == DEL || c1 == K_DEL || c1 == K_KDEL) {
if (!GA_EMPTY(&line_ga)) {
- if (has_mbyte) {
- p = (char_u *)line_ga.ga_data;
- p[line_ga.ga_len] = NUL;
- len = (*mb_head_off)(p, p + line_ga.ga_len - 1) + 1;
- line_ga.ga_len -= len;
- } else {
- line_ga.ga_len--;
- }
+ p = (char_u *)line_ga.ga_data;
+ p[line_ga.ga_len] = NUL;
+ len = utf_head_off(p, p + line_ga.ga_len - 1) + 1;
+ line_ga.ga_len -= len;
goto redraw;
}
continue;
@@ -1993,16 +2401,11 @@ redraw:
if (IS_SPECIAL(c1)) {
c1 = '?';
}
- if (has_mbyte) {
- len = (*mb_char2bytes)(c1, (char_u *)line_ga.ga_data + line_ga.ga_len);
- } else {
- len = 1;
- ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
- }
- if (c1 == '\n')
+ len = utf_char2bytes(c1, (char_u *)line_ga.ga_data + line_ga.ga_len);
+ if (c1 == '\n') {
msg_putchar('\n');
- else if (c1 == TAB) {
- /* Don't use chartabsize(), 'ts' can be different */
+ } else if (c1 == TAB) {
+ // Don't use chartabsize(), 'ts' can be different.
do {
msg_putchar(' ');
} while (++vcol % 8);
@@ -2041,8 +2444,7 @@ redraw:
}
}
- --no_mapping;
- --allow_keys;
+ no_mapping--;
/* make following messages go to the next line */
msg_didout = FALSE;
@@ -2057,6 +2459,18 @@ redraw:
return (char_u *)line_ga.ga_data;
}
+bool cmdline_overstrike(void)
+{
+ return ccline.overstrike;
+}
+
+
+/// Return true if the cursor is at the end of the cmdline.
+bool cmdline_at_end(void)
+{
+ return (ccline.cmdpos >= ccline.cmdlen);
+}
+
/*
* Allocate a new command line buffer.
* Assigns the new buffer to ccline.cmdbuff and ccline.cmdbufflen.
@@ -2116,75 +2530,389 @@ void free_cmdline_buf(void)
# endif
+enum { MAX_CB_ERRORS = 1 };
+
+/// Color expression cmdline using built-in expressions parser
+///
+/// @param[in] colored_ccline Command-line to color.
+/// @param[out] ret_ccline_colors What should be colored.
+///
+/// Always colors the whole cmdline.
+static void color_expr_cmdline(const CmdlineInfo *const colored_ccline,
+ ColoredCmdline *const ret_ccline_colors)
+ FUNC_ATTR_NONNULL_ALL
+{
+ ParserLine plines[] = {
+ {
+ .data = (const char *)colored_ccline->cmdbuff,
+ .size = STRLEN(colored_ccline->cmdbuff),
+ .allocated = false,
+ },
+ { NULL, 0, false },
+ };
+ ParserLine *plines_p = plines;
+ ParserHighlight colors;
+ kvi_init(colors);
+ ParserState pstate;
+ viml_parser_init(
+ &pstate, parser_simple_get_line, &plines_p, &colors);
+ ExprAST east = viml_pexpr_parse(&pstate, kExprFlagsDisallowEOC);
+ viml_pexpr_free_ast(east);
+ viml_parser_destroy(&pstate);
+ kv_resize(ret_ccline_colors->colors, kv_size(colors));
+ size_t prev_end = 0;
+ for (size_t i = 0 ; i < kv_size(colors) ; i++) {
+ const ParserHighlightChunk chunk = kv_A(colors, i);
+ if (chunk.start.col != prev_end) {
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = prev_end,
+ .end = chunk.start.col,
+ .attr = 0,
+ }));
+ }
+ const int id = syn_name2id((const char_u *)chunk.group);
+ const int attr = (id == 0 ? 0 : syn_id2attr(id));
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = chunk.start.col,
+ .end = chunk.end_col,
+ .attr = attr,
+ }));
+ prev_end = chunk.end_col;
+ }
+ if (prev_end < (size_t)colored_ccline->cmdlen) {
+ kv_push(ret_ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = prev_end,
+ .end = (size_t)colored_ccline->cmdlen,
+ .attr = 0,
+ }));
+ }
+ kvi_destroy(colors);
+}
+
+/// Color command-line
+///
+/// Should use built-in command parser or user-specified one. Currently only the
+/// latter is supported.
+///
+/// @param[in,out] colored_ccline Command-line to color. Also holds a cache:
+/// if ->prompt_id and ->cmdbuff values happen
+/// to be equal to those from colored_cmdline it
+/// will just do nothing, assuming that ->colors
+/// already contains needed data.
+///
+/// Always colors the whole cmdline.
+///
+/// @return true if draw_cmdline may proceed, false if it does not need anything
+/// to do.
+static bool color_cmdline(CmdlineInfo *colored_ccline)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ bool printed_errmsg = false;
+
+#define PRINT_ERRMSG(...) \
+ do { \
+ msg_putchar('\n'); \
+ msg_printf_attr(HL_ATTR(HLF_E)|MSG_HIST, __VA_ARGS__); \
+ printed_errmsg = true; \
+ } while (0)
+ bool ret = true;
+
+ ColoredCmdline *ccline_colors = &colored_ccline->last_colors;
+
+ // Check whether result of the previous call is still valid.
+ if (ccline_colors->prompt_id == colored_ccline->prompt_id
+ && ccline_colors->cmdbuff != NULL
+ && STRCMP(ccline_colors->cmdbuff, colored_ccline->cmdbuff) == 0) {
+ return ret;
+ }
+
+ kv_size(ccline_colors->colors) = 0;
+
+ if (colored_ccline->cmdbuff == NULL || *colored_ccline->cmdbuff == NUL) {
+ // Nothing to do, exiting.
+ xfree(ccline_colors->cmdbuff);
+ ccline_colors->cmdbuff = NULL;
+ return ret;
+ }
+
+ bool arg_allocated = false;
+ typval_T arg = {
+ .v_type = VAR_STRING,
+ .vval.v_string = colored_ccline->cmdbuff,
+ };
+ typval_T tv = { .v_type = VAR_UNKNOWN };
+
+ static unsigned prev_prompt_id = UINT_MAX;
+ static int prev_prompt_errors = 0;
+ Callback color_cb = CALLBACK_NONE;
+ bool can_free_cb = false;
+ TryState tstate;
+ Error err = ERROR_INIT;
+ const char *err_errmsg = (const char *)e_intern2;
+ bool dgc_ret = true;
+ bool tl_ret = true;
+
+ if (colored_ccline->prompt_id != prev_prompt_id) {
+ prev_prompt_errors = 0;
+ prev_prompt_id = colored_ccline->prompt_id;
+ } else if (prev_prompt_errors >= MAX_CB_ERRORS) {
+ goto color_cmdline_end;
+ }
+ if (colored_ccline->highlight_callback.type != kCallbackNone) {
+ // Currently this should only happen while processing input() prompts.
+ assert(colored_ccline->input_fn);
+ color_cb = colored_ccline->highlight_callback;
+ } else if (colored_ccline->cmdfirstc == ':') {
+ try_enter(&tstate);
+ err_errmsg = N_(
+ "E5408: Unable to get g:Nvim_color_cmdline callback: %s");
+ dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"),
+ &color_cb);
+ tl_ret = try_leave(&tstate, &err);
+ can_free_cb = true;
+ } else if (colored_ccline->cmdfirstc == '=') {
+ color_expr_cmdline(colored_ccline, ccline_colors);
+ }
+ if (!tl_ret || !dgc_ret) {
+ goto color_cmdline_error;
+ }
+
+ if (color_cb.type == kCallbackNone) {
+ goto color_cmdline_end;
+ }
+ if (colored_ccline->cmdbuff[colored_ccline->cmdlen] != NUL) {
+ arg_allocated = true;
+ arg.vval.v_string = xmemdupz((const char *)colored_ccline->cmdbuff,
+ (size_t)colored_ccline->cmdlen);
+ }
+ // msg_start() called by e.g. :echo may shift command-line to the first column
+ // even though msg_silent is here. Two ways to workaround this problem without
+ // altering message.c: use full_screen or save and restore msg_col.
+ //
+ // Saving and restoring full_screen does not work well with :redraw!. Saving
+ // and restoring msg_col is neither ideal, but while with full_screen it
+ // appears shifted one character to the right and cursor position is no longer
+ // correct, with msg_col it just misses leading `:`. Since `redraw!` in
+ // callback lags this is least of the user problems.
+ //
+ // Also using try_enter() because error messages may overwrite typed
+ // command-line which is not expected.
+ getln_interrupted_highlight = false;
+ try_enter(&tstate);
+ err_errmsg = N_("E5407: Callback has thrown an exception: %s");
+ const int saved_msg_col = msg_col;
+ msg_silent++;
+ const bool cbcall_ret = callback_call(&color_cb, 1, &arg, &tv);
+ msg_silent--;
+ msg_col = saved_msg_col;
+ if (got_int) {
+ getln_interrupted_highlight = true;
+ }
+ if (!try_leave(&tstate, &err) || !cbcall_ret) {
+ goto color_cmdline_error;
+ }
+ if (tv.v_type != VAR_LIST) {
+ PRINT_ERRMSG(_("E5400: Callback should return list"));
+ goto color_cmdline_error;
+ }
+ if (tv.vval.v_list == NULL) {
+ goto color_cmdline_end;
+ }
+ varnumber_T prev_end = 0;
+ int i = 0;
+ TV_LIST_ITER_CONST(tv.vval.v_list, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type != VAR_LIST) {
+ PRINT_ERRMSG(_("E5401: List item %i is not a List"), i);
+ goto color_cmdline_error;
+ }
+ const list_T *const l = TV_LIST_ITEM_TV(li)->vval.v_list;
+ if (tv_list_len(l) != 3) {
+ PRINT_ERRMSG(_("E5402: List item %i has incorrect length: %d /= 3"),
+ i, tv_list_len(l));
+ goto color_cmdline_error;
+ }
+ bool error = false;
+ const varnumber_T start = (
+ tv_get_number_chk(TV_LIST_ITEM_TV(tv_list_first(l)), &error));
+ if (error) {
+ goto color_cmdline_error;
+ } else if (!(prev_end <= start && start < colored_ccline->cmdlen)) {
+ PRINT_ERRMSG(_("E5403: Chunk %i start %" PRIdVARNUMBER " not in range "
+ "[%" PRIdVARNUMBER ", %i)"),
+ i, start, prev_end, colored_ccline->cmdlen);
+ goto color_cmdline_error;
+ } else if (utf8len_tab_zero[(uint8_t)colored_ccline->cmdbuff[start]] == 0) {
+ PRINT_ERRMSG(_("E5405: Chunk %i start %" PRIdVARNUMBER " splits "
+ "multibyte character"), i, start);
+ goto color_cmdline_error;
+ }
+ if (start != prev_end) {
+ kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = prev_end,
+ .end = start,
+ .attr = 0,
+ }));
+ }
+ const varnumber_T end = tv_get_number_chk(
+ TV_LIST_ITEM_TV(TV_LIST_ITEM_NEXT(l, tv_list_first(l))), &error);
+ if (error) {
+ goto color_cmdline_error;
+ } else if (!(start < end && end <= colored_ccline->cmdlen)) {
+ PRINT_ERRMSG(_("E5404: Chunk %i end %" PRIdVARNUMBER " not in range "
+ "(%" PRIdVARNUMBER ", %i]"),
+ i, end, start, colored_ccline->cmdlen);
+ goto color_cmdline_error;
+ } else if (end < colored_ccline->cmdlen
+ && (utf8len_tab_zero[(uint8_t)colored_ccline->cmdbuff[end]]
+ == 0)) {
+ PRINT_ERRMSG(_("E5406: Chunk %i end %" PRIdVARNUMBER " splits multibyte "
+ "character"), i, end);
+ goto color_cmdline_error;
+ }
+ prev_end = end;
+ const char *const group = tv_get_string_chk(
+ TV_LIST_ITEM_TV(tv_list_last(l)));
+ if (group == NULL) {
+ goto color_cmdline_error;
+ }
+ const int id = syn_name2id((char_u *)group);
+ const int attr = (id == 0 ? 0 : syn_id2attr(id));
+ kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = start,
+ .end = end,
+ .attr = attr,
+ }));
+ i++;
+ });
+ if (prev_end < colored_ccline->cmdlen) {
+ kv_push(ccline_colors->colors, ((CmdlineColorChunk) {
+ .start = prev_end,
+ .end = colored_ccline->cmdlen,
+ .attr = 0,
+ }));
+ }
+ prev_prompt_errors = 0;
+color_cmdline_end:
+ assert(!ERROR_SET(&err));
+ if (can_free_cb) {
+ callback_free(&color_cb);
+ }
+ xfree(ccline_colors->cmdbuff);
+ // Note: errors “output†is cached just as well as regular results.
+ ccline_colors->prompt_id = colored_ccline->prompt_id;
+ if (arg_allocated) {
+ ccline_colors->cmdbuff = (char *)arg.vval.v_string;
+ } else {
+ ccline_colors->cmdbuff = xmemdupz((const char *)colored_ccline->cmdbuff,
+ (size_t)colored_ccline->cmdlen);
+ }
+ tv_clear(&tv);
+ return ret;
+color_cmdline_error:
+ if (ERROR_SET(&err)) {
+ PRINT_ERRMSG(_(err_errmsg), err.msg);
+ api_clear_error(&err);
+ }
+ assert(printed_errmsg);
+ (void)printed_errmsg;
+
+ prev_prompt_errors++;
+ kv_size(ccline_colors->colors) = 0;
+ redrawcmdline();
+ ret = false;
+ goto color_cmdline_end;
+#undef PRINT_ERRMSG
+}
+
/*
* Draw part of the cmdline at the current cursor position. But draw stars
* when cmdline_star is TRUE.
*/
static void draw_cmdline(int start, int len)
{
- int i;
+ if (!color_cmdline(&ccline)) {
+ return;
+ }
- if (cmdline_star > 0)
- for (i = 0; i < len; ++i) {
+ if (ui_is_external(kUICmdline)) {
+ ccline.special_char = NUL;
+ ccline.redraw_state = kCmdRedrawAll;
+ return;
+ }
+
+ if (cmdline_star > 0) {
+ for (int i = 0; i < len; i++) {
msg_putchar('*');
- if (has_mbyte)
+ if (has_mbyte) {
i += (*mb_ptr2len)(ccline.cmdbuff + start + i) - 1;
+ }
}
- else if (p_arshape && !p_tbidi && enc_utf8 && len > 0) {
- static int buflen = 0;
- char_u *p;
- int j;
- int newlen = 0;
+ } else if (p_arshape && !p_tbidi && enc_utf8 && len > 0) {
+ bool do_arabicshape = false;
int mb_l;
- int pc, pc1 = 0;
- int prev_c = 0;
- int prev_c1 = 0;
- int u8c;
- int u8cc[MAX_MCO];
- int nc = 0;
+ for (int i = start; i < start + len; i += mb_l) {
+ char_u *p = ccline.cmdbuff + i;
+ int u8cc[MAX_MCO];
+ int u8c = utfc_ptr2char_len(p, u8cc, start + len - i);
+ mb_l = utfc_ptr2len_len(p, start + len - i);
+ if (arabic_char(u8c)) {
+ do_arabicshape = true;
+ break;
+ }
+ }
+ if (!do_arabicshape) {
+ goto draw_cmdline_no_arabicshape;
+ }
- /*
- * Do arabic shaping into a temporary buffer. This is very
- * inefficient!
- */
+ static int buflen = 0;
+
+ // Do arabic shaping into a temporary buffer. This is very
+ // inefficient!
if (len * 2 + 2 > buflen) {
- /* Re-allocate the buffer. We keep it around to avoid a lot of
- * alloc()/free() calls. */
+ // Re-allocate the buffer. We keep it around to avoid a lot of
+ // alloc()/free() calls.
xfree(arshape_buf);
buflen = len * 2 + 2;
arshape_buf = xmalloc(buflen);
}
+ int newlen = 0;
if (utf_iscomposing(utf_ptr2char(ccline.cmdbuff + start))) {
- /* Prepend a space to draw the leading composing char on. */
+ // Prepend a space to draw the leading composing char on.
arshape_buf[0] = ' ';
newlen = 1;
}
- for (j = start; j < start + len; j += mb_l) {
- p = ccline.cmdbuff + j;
- u8c = utfc_ptr2char_len(p, u8cc, start + len - j);
- mb_l = utfc_ptr2len_len(p, start + len - j);
+ int prev_c = 0;
+ int prev_c1 = 0;
+ for (int i = start; i < start + len; i += mb_l) {
+ char_u *p = ccline.cmdbuff + i;
+ int u8cc[MAX_MCO];
+ int u8c = utfc_ptr2char_len(p, u8cc, start + len - i);
+ mb_l = utfc_ptr2len_len(p, start + len - i);
if (arabic_char(u8c)) {
- /* Do Arabic shaping. */
+ int pc;
+ int pc1 = 0;
+ int nc = 0;
+ // Do Arabic shaping.
if (cmdmsg_rl) {
- /* displaying from right to left */
+ // Displaying from right to left.
pc = prev_c;
pc1 = prev_c1;
prev_c1 = u8cc[0];
- if (j + mb_l >= start + len)
+ if (i + mb_l >= start + len) {
nc = NUL;
- else
+ } else {
nc = utf_ptr2char(p + mb_l);
+ }
} else {
- /* displaying from left to right */
- if (j + mb_l >= start + len)
+ // Displaying from left to right.
+ if (i + mb_l >= start + len) {
pc = NUL;
- else {
+ } else {
int pcc[MAX_MCO];
- pc = utfc_ptr2char_len(p + mb_l, pcc,
- start + len - j - mb_l);
+ pc = utfc_ptr2char_len(p + mb_l, pcc, start + len - i - mb_l);
pc1 = pcc[0];
}
nc = prev_c;
@@ -2193,12 +2921,12 @@ static void draw_cmdline(int start, int len)
u8c = arabic_shape(u8c, NULL, &u8cc[0], pc, pc1, nc);
- newlen += (*mb_char2bytes)(u8c, arshape_buf + newlen);
+ newlen += utf_char2bytes(u8c, arshape_buf + newlen);
if (u8cc[0] != 0) {
- newlen += (*mb_char2bytes)(u8cc[0], arshape_buf + newlen);
- if (u8cc[1] != 0)
- newlen += (*mb_char2bytes)(u8cc[1],
- arshape_buf + newlen);
+ newlen += utf_char2bytes(u8cc[0], arshape_buf + newlen);
+ if (u8cc[1] != 0) {
+ newlen += utf_char2bytes(u8cc[1], arshape_buf + newlen);
+ }
}
} else {
prev_c = u8c;
@@ -2208,8 +2936,139 @@ static void draw_cmdline(int start, int len)
}
msg_outtrans_len(arshape_buf, newlen);
- } else
- msg_outtrans_len(ccline.cmdbuff + start, len);
+ } else {
+draw_cmdline_no_arabicshape:
+ if (kv_size(ccline.last_colors.colors)) {
+ for (size_t i = 0; i < kv_size(ccline.last_colors.colors); i++) {
+ CmdlineColorChunk chunk = kv_A(ccline.last_colors.colors, i);
+ if (chunk.end <= start) {
+ continue;
+ }
+ const int chunk_start = MAX(chunk.start, start);
+ msg_outtrans_len_attr(ccline.cmdbuff + chunk_start,
+ chunk.end - chunk_start,
+ chunk.attr);
+ }
+ } else {
+ msg_outtrans_len(ccline.cmdbuff + start, len);
+ }
+ }
+}
+
+static void ui_ext_cmdline_show(CmdlineInfo *line)
+{
+ Array content = ARRAY_DICT_INIT;
+ if (cmdline_star) {
+ size_t len = 0;
+ for (char_u *p = ccline.cmdbuff; *p; MB_PTR_ADV(p)) {
+ len++;
+ }
+ char *buf = xmallocz(len);
+ memset(buf, '*', len);
+ Array item = ARRAY_DICT_INIT;
+ ADD(item, INTEGER_OBJ(0));
+ ADD(item, STRING_OBJ(((String) { .data = buf, .size = len })));
+ ADD(content, ARRAY_OBJ(item));
+ } else if (kv_size(line->last_colors.colors)) {
+ for (size_t i = 0; i < kv_size(line->last_colors.colors); i++) {
+ CmdlineColorChunk chunk = kv_A(line->last_colors.colors, i);
+ Array item = ARRAY_DICT_INIT;
+ ADD(item, INTEGER_OBJ(chunk.attr));
+
+ ADD(item, STRING_OBJ(cbuf_to_string((char *)line->cmdbuff + chunk.start,
+ chunk.end-chunk.start)));
+ ADD(content, ARRAY_OBJ(item));
+ }
+ } else {
+ Array item = ARRAY_DICT_INIT;
+ ADD(item, INTEGER_OBJ(0));
+ ADD(item, STRING_OBJ(cstr_to_string((char *)(line->cmdbuff))));
+ ADD(content, ARRAY_OBJ(item));
+ }
+ ui_call_cmdline_show(content, line->cmdpos,
+ cchar_to_string((char)line->cmdfirstc),
+ cstr_to_string((char *)(line->cmdprompt)),
+ line->cmdindent,
+ line->level);
+ if (line->special_char) {
+ ui_call_cmdline_special_char(cchar_to_string((char)(line->special_char)),
+ line->special_shift,
+ line->level);
+ }
+}
+
+void ui_ext_cmdline_block_append(int indent, const char *line)
+{
+ char *buf = xmallocz(indent + strlen(line));
+ memset(buf, ' ', indent);
+ memcpy(buf + indent, line, strlen(line)); // -V575
+
+ Array item = ARRAY_DICT_INIT;
+ ADD(item, INTEGER_OBJ(0));
+ ADD(item, STRING_OBJ(cstr_as_string(buf)));
+ Array content = ARRAY_DICT_INIT;
+ ADD(content, ARRAY_OBJ(item));
+ ADD(cmdline_block, ARRAY_OBJ(content));
+ if (cmdline_block.size > 1) {
+ ui_call_cmdline_block_append(copy_array(content));
+ } else {
+ ui_call_cmdline_block_show(copy_array(cmdline_block));
+ }
+}
+
+void ui_ext_cmdline_block_leave(void)
+{
+ api_free_array(cmdline_block);
+ cmdline_block = (Array)ARRAY_DICT_INIT;
+ ui_call_cmdline_block_hide();
+}
+
+/// Extra redrawing needed for redraw! and on ui_attach
+/// assumes "redrawcmdline()" will already be invoked
+void cmdline_screen_cleared(void)
+{
+ if (!ui_is_external(kUICmdline)) {
+ return;
+ }
+
+ if (cmdline_block.size) {
+ ui_call_cmdline_block_show(copy_array(cmdline_block));
+ }
+
+ int prev_level = ccline.level-1;
+ CmdlineInfo *line = ccline.prev_ccline;
+ while (prev_level > 0 && line) {
+ if (line->level == prev_level) {
+ // don't redraw a cmdline already shown in the cmdline window
+ if (prev_level != cmdwin_level) {
+ line->redraw_state = kCmdRedrawAll;
+ }
+ prev_level--;
+ }
+ line = line->prev_ccline;
+ }
+}
+
+/// called by ui_flush, do what redraws neccessary to keep cmdline updated.
+void cmdline_ui_flush(void)
+{
+ if (!ui_is_external(kUICmdline)) {
+ return;
+ }
+ int level = ccline.level;
+ CmdlineInfo *line = &ccline;
+ while (level > 0 && line) {
+ if (line->level == level) {
+ if (line->redraw_state == kCmdRedrawAll) {
+ ui_ext_cmdline_show(line);
+ } else if (line->redraw_state == kCmdRedrawPos) {
+ ui_call_cmdline_pos(line->cmdpos, line->level);
+ }
+ line->redraw_state = kCmdRedrawNone;
+ level--;
+ }
+ line = line->prev_ccline;
+ }
}
/*
@@ -2219,33 +3078,43 @@ static void draw_cmdline(int start, int len)
*/
void putcmdline(int c, int shift)
{
- if (cmd_silent)
+ if (cmd_silent) {
return;
- msg_no_more = TRUE;
- msg_putchar(c);
- if (shift)
- draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
- msg_no_more = FALSE;
+ }
+ if (!ui_is_external(kUICmdline)) {
+ msg_no_more = true;
+ msg_putchar(c);
+ if (shift) {
+ draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
+ }
+ msg_no_more = false;
+ } else {
+ ccline.special_char = c;
+ ccline.special_shift = shift;
+ if (ccline.redraw_state != kCmdRedrawAll) {
+ ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift,
+ ccline.level);
+ }
+ }
cursorcmd();
+ ui_cursor_shape();
}
-/*
- * Undo a putcmdline(c, FALSE).
- */
+/// Undo a putcmdline(c, FALSE).
void unputcmdline(void)
{
- if (cmd_silent)
+ if (cmd_silent) {
return;
- msg_no_more = TRUE;
- if (ccline.cmdlen == ccline.cmdpos)
+ }
+ msg_no_more = true;
+ if (ccline.cmdlen == ccline.cmdpos && !ui_is_external(kUICmdline)) {
msg_putchar(' ');
- else if (has_mbyte)
- draw_cmdline(ccline.cmdpos,
- (*mb_ptr2len)(ccline.cmdbuff + ccline.cmdpos));
- else
- draw_cmdline(ccline.cmdpos, 1);
- msg_no_more = FALSE;
+ } else {
+ draw_cmdline(ccline.cmdpos, mb_ptr2len(ccline.cmdbuff + ccline.cmdpos));
+ }
+ msg_no_more = false;
cursorcmd();
+ ui_cursor_shape();
}
/*
@@ -2302,18 +3171,15 @@ void put_on_cmdline(char_u *str, int len, int redraw)
i = 0;
c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
while (ccline.cmdpos > 0 && utf_iscomposing(c)) {
- i = (*mb_head_off)(ccline.cmdbuff,
- ccline.cmdbuff + ccline.cmdpos - 1) + 1;
+ i = utf_head_off(ccline.cmdbuff, ccline.cmdbuff + ccline.cmdpos - 1) + 1;
ccline.cmdpos -= i;
len += i;
c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
}
if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c)) {
- /* Check the previous character for Arabic combining pair. */
- i = (*mb_head_off)(ccline.cmdbuff,
- ccline.cmdbuff + ccline.cmdpos - 1) + 1;
- if (arabic_combine(utf_ptr2char(ccline.cmdbuff
- + ccline.cmdpos - i), c)) {
+ // Check the previous character for Arabic combining pair.
+ i = utf_head_off(ccline.cmdbuff, ccline.cmdbuff + ccline.cmdpos - 1) + 1;
+ if (arabic_combine(utf_ptr2char(ccline.cmdbuff + ccline.cmdpos - i), c)) {
ccline.cmdpos -= i;
len += i;
} else
@@ -2377,9 +3243,6 @@ void put_on_cmdline(char_u *str, int len, int redraw)
msg_check();
}
-static struct cmdline_info prev_ccline;
-static int prev_ccline_used = FALSE;
-
/*
* Save ccline, because obtaining the "=" register may execute "normal :cmd"
* and overwrite it. But get_cmdline_str() may need it, thus make it
@@ -2387,15 +3250,13 @@ static int prev_ccline_used = FALSE;
*/
static void save_cmdline(struct cmdline_info *ccp)
{
- if (!prev_ccline_used) {
- memset(&prev_ccline, 0, sizeof(struct cmdline_info));
- prev_ccline_used = TRUE;
- }
- *ccp = prev_ccline;
- prev_ccline = ccline;
+ *ccp = ccline;
+ ccline.prev_ccline = ccp;
ccline.cmdbuff = NULL;
ccline.cmdprompt = NULL;
ccline.xpc = NULL;
+ ccline.special_char = NUL;
+ ccline.level = 0;
}
/*
@@ -2403,8 +3264,7 @@ static void save_cmdline(struct cmdline_info *ccp)
*/
static void restore_cmdline(struct cmdline_info *ccp)
{
- ccline = prev_ccline;
- prev_ccline = *ccp;
+ ccline = *ccp;
}
/*
@@ -2439,17 +3299,18 @@ void restore_cmdline_alloc(char_u *p)
/// @returns FAIL for failure, OK otherwise
static bool cmdline_paste(int regname, bool literally, bool remcr)
{
- long i;
char_u *arg;
char_u *p;
- int allocated;
+ bool allocated;
struct cmdline_info save_ccline;
/* check for valid regname; also accept special characters for CTRL-R in
* the command line */
if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W
- && regname != Ctrl_A && !valid_yank_reg(regname, false))
+ && regname != Ctrl_A && regname != Ctrl_L
+ && !valid_yank_reg(regname, false)) {
return FAIL;
+ }
/* A register containing CTRL-R can cause an endless loop. Allow using
* CTRL-C to break the loop. */
@@ -2461,9 +3322,9 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
/* Need to save and restore ccline. And set "textlock" to avoid nasty
* things like going to another buffer when evaluating an expression. */
save_cmdline(&save_ccline);
- ++textlock;
- i = get_spec_reg(regname, &arg, &allocated, TRUE);
- --textlock;
+ textlock++;
+ const bool i = get_spec_reg(regname, &arg, &allocated, true);
+ textlock--;
restore_cmdline(&save_ccline);
if (i) {
@@ -2480,16 +3341,11 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
/* Locate start of last word in the cmd buffer. */
for (w = ccline.cmdbuff + ccline.cmdpos; w > ccline.cmdbuff; ) {
- if (has_mbyte) {
- len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1;
- if (!vim_iswordc(mb_ptr2char(w - len)))
- break;
- w -= len;
- } else {
- if (!vim_iswordc(w[-1]))
- break;
- --w;
+ len = utf_head_off(ccline.cmdbuff, w - 1) + 1;
+ if (!vim_iswordc(utf_ptr2char(w - len))) {
+ break;
}
+ w -= len;
}
len = (int)((ccline.cmdbuff + ccline.cmdpos) - w);
if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
@@ -2520,19 +3376,19 @@ void cmdline_paste_str(char_u *s, int literally)
else
while (*s != NUL) {
cv = *s;
- if (cv == Ctrl_V && s[1])
- ++s;
- if (has_mbyte)
- c = mb_cptr2char_adv(&s);
- else
+ if (cv == Ctrl_V && s[1]) {
+ s++;
+ }
+ if (has_mbyte) {
+ c = mb_cptr2char_adv((const char_u **)&s);
+ } else {
c = *s++;
+ }
if (cv == Ctrl_V || c == ESC || c == Ctrl_C
|| c == CAR || c == NL || c == Ctrl_L
-#ifdef UNIX
- || c == intr_char
-#endif
- || (c == Ctrl_BSL && *s == Ctrl_N))
+ || (c == Ctrl_BSL && *s == Ctrl_N)) {
stuffcharReadbuff(Ctrl_V);
+ }
stuffcharReadbuff(c);
}
}
@@ -2549,10 +3405,9 @@ static void cmdline_del(int from)
ccline.cmdpos = from;
}
-/*
- * this function is called when the screen size changes and with incremental
- * search
- */
+// This function is called when the screen size changes and with incremental
+// search and in other situations where the command line may have been
+// overwritten.
void redrawcmdline(void)
{
if (cmd_silent)
@@ -2561,6 +3416,7 @@ void redrawcmdline(void)
compute_cmdrow();
redrawcmd();
cursorcmd();
+ ui_cursor_shape();
}
static void redrawcmdprompt(void)
@@ -2569,17 +3425,25 @@ static void redrawcmdprompt(void)
if (cmd_silent)
return;
- if (ccline.cmdfirstc != NUL)
+ if (ui_is_external(kUICmdline)) {
+ ccline.redraw_state = kCmdRedrawAll;
+ return;
+ }
+ if (ccline.cmdfirstc != NUL) {
msg_putchar(ccline.cmdfirstc);
+ }
if (ccline.cmdprompt != NULL) {
- msg_puts_attr(ccline.cmdprompt, ccline.cmdattr);
+ msg_puts_attr((const char *)ccline.cmdprompt, ccline.cmdattr);
ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns;
- /* do the reverse of set_cmdspos() */
- if (ccline.cmdfirstc != NUL)
- --ccline.cmdindent;
- } else
- for (i = ccline.cmdindent; i > 0; --i)
+ // do the reverse of set_cmdspos()
+ if (ccline.cmdfirstc != NUL) {
+ ccline.cmdindent--;
+ }
+ } else {
+ for (i = ccline.cmdindent; i > 0; i--) {
msg_putchar(' ');
+ }
+ }
}
/*
@@ -2590,6 +3454,11 @@ void redrawcmd(void)
if (cmd_silent)
return;
+ if (ui_is_external(kUICmdline)) {
+ draw_cmdline(0, ccline.cmdlen);
+ return;
+ }
+
/* when 'incsearch' is set there may be no command line while redrawing */
if (ccline.cmdbuff == NULL) {
ui_cursor_goto(cmdline_row, 0);
@@ -2633,6 +3502,14 @@ static void cursorcmd(void)
if (cmd_silent)
return;
+ if (ui_is_external(kUICmdline)) {
+ if (ccline.redraw_state < kCmdRedrawPos) {
+ ccline.redraw_state = kCmdRedrawPos;
+ }
+ setcursor();
+ return;
+ }
+
if (cmdmsg_rl) {
msg_row = cmdline_row + (ccline.cmdspos / (int)(Columns - 1));
msg_col = (int)Columns - (ccline.cmdspos % (int)(Columns - 1)) - 1;
@@ -2650,6 +3527,9 @@ static void cursorcmd(void)
void gotocmdline(int clr)
{
+ if (ui_is_external(kUICmdline)) {
+ return;
+ }
msg_start();
if (cmdmsg_rl)
msg_col = Columns - 1;
@@ -2668,10 +3548,28 @@ void gotocmdline(int clr)
*/
static int ccheck_abbr(int c)
{
- if (p_paste || no_abbr) /* no abbreviations or in paste mode */
- return FALSE;
+ int spos = 0;
- return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, 0);
+ if (p_paste || no_abbr) { // no abbreviations or in paste mode
+ return false;
+ }
+
+ // Do not consider '<,'> be part of the mapping, skip leading whitespace.
+ // Actually accepts any mark.
+ while (ascii_iswhite(ccline.cmdbuff[spos]) && spos < ccline.cmdlen) {
+ spos++;
+ }
+ if (ccline.cmdlen - spos > 5
+ && ccline.cmdbuff[spos] == '\''
+ && ccline.cmdbuff[spos + 2] == ','
+ && ccline.cmdbuff[spos + 3] == '\'') {
+ spos += 5;
+ } else {
+ // check abbreviation from the beginning of the commandline
+ spos = 0;
+ }
+
+ return check_abbr(c, ccline.cmdbuff, ccline.cmdpos, spos);
}
static int sort_func_compare(const void *s1, const void *s2)
@@ -2717,47 +3615,42 @@ nextwild (
return FAIL;
}
- MSG_PUTS("..."); /* show that we are busy */
- ui_flush();
+ if (!ui_is_external(kUIWildmenu)) {
+ MSG_PUTS("..."); // show that we are busy
+ ui_flush();
+ }
i = (int)(xp->xp_pattern - ccline.cmdbuff);
xp->xp_pattern_len = ccline.cmdpos - i;
if (type == WILD_NEXT || type == WILD_PREV) {
- /*
- * Get next/previous match for a previous expanded pattern.
- */
+ // Get next/previous match for a previous expanded pattern.
p2 = ExpandOne(xp, NULL, NULL, 0, type);
} else {
- /*
- * Translate string into pattern and expand it.
- */
- if ((p1 = addstar(xp->xp_pattern, xp->xp_pattern_len,
- xp->xp_context)) == NULL)
- p2 = NULL;
- else {
- int use_options = options |
- WILD_HOME_REPLACE|WILD_ADD_SLASH|WILD_SILENT;
- if (escape)
- use_options |= WILD_ESCAPE;
-
- if (p_wic)
- use_options += WILD_ICASE;
- p2 = ExpandOne(xp, p1,
- vim_strnsave(&ccline.cmdbuff[i], xp->xp_pattern_len),
- use_options, type);
- xfree(p1);
- /* longest match: make sure it is not shorter, happens with :help */
- if (p2 != NULL && type == WILD_LONGEST) {
- for (j = 0; j < xp->xp_pattern_len; ++j)
- if (ccline.cmdbuff[i + j] == '*'
- || ccline.cmdbuff[i + j] == '?')
- break;
- if ((int)STRLEN(p2) < j) {
- xfree(p2);
- p2 = NULL;
+ // Translate string into pattern and expand it.
+ p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
+ const int use_options = (
+ options
+ | WILD_HOME_REPLACE
+ | WILD_ADD_SLASH
+ | WILD_SILENT
+ | (escape ? WILD_ESCAPE : 0)
+ | (p_wic ? WILD_ICASE : 0));
+ p2 = ExpandOne(xp, p1, vim_strnsave(&ccline.cmdbuff[i], xp->xp_pattern_len),
+ use_options, type);
+ xfree(p1);
+ // Longest match: make sure it is not shorter, happens with :help.
+ if (p2 != NULL && type == WILD_LONGEST) {
+ for (j = 0; j < xp->xp_pattern_len; j++) {
+ if (ccline.cmdbuff[i + j] == '*'
+ || ccline.cmdbuff[i + j] == '?') {
+ break;
}
}
+ if ((int)STRLEN(p2) < j) {
+ xfree(p2);
+ p2 = NULL;
+ }
}
}
@@ -2871,11 +3764,17 @@ ExpandOne (
else
findex = -1;
}
- if (p_wmnu)
- win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files,
- findex, cmd_showtail);
- if (findex == -1)
+ if (p_wmnu) {
+ if (ui_is_external(kUIWildmenu)) {
+ ui_call_wildmenu_select(findex);
+ } else {
+ win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files,
+ findex, cmd_showtail);
+ }
+ }
+ if (findex == -1) {
return vim_strsave(orig_save);
+ }
return vim_strsave(xp->xp_files[findex]);
} else
return NULL;
@@ -2959,30 +3858,19 @@ ExpandOne (
// Find longest common part
if (mode == WILD_LONGEST && xp->xp_numfiles > 0) {
- size_t len;
- size_t mb_len = 1;
- int c0;
- int ci;
+ size_t len = 0;
- for (len = 0; xp->xp_files[0][len]; len += mb_len) {
- if (has_mbyte) {
- mb_len = (* mb_ptr2len)(&xp->xp_files[0][len]);
- c0 = (* mb_ptr2char)(&xp->xp_files[0][len]);
- } else {
- c0 = xp->xp_files[0][len];
- }
- for (i = 1; i < xp->xp_numfiles; ++i) {
- if (has_mbyte) {
- ci =(* mb_ptr2char)(&xp->xp_files[i][len]);
- } else {
- ci = xp->xp_files[i][len];
- }
+ for (size_t mb_len; xp->xp_files[0][len]; len += mb_len) {
+ mb_len = utfc_ptr2len(&xp->xp_files[0][len]);
+ int c0 = utf_ptr2char(&xp->xp_files[0][len]);
+ for (i = 1; i < xp->xp_numfiles; i++) {
+ int ci = utf_ptr2char(&xp->xp_files[i][len]);
if (p_fic && (xp->xp_context == EXPAND_DIRECTORIES
|| xp->xp_context == EXPAND_FILES
|| xp->xp_context == EXPAND_SHELLCMD
|| xp->xp_context == EXPAND_BUFFERS)) {
- if (vim_tolower(c0) != vim_tolower(ci)) {
+ if (mb_tolower(c0) != mb_tolower(ci)) {
break;
}
} else if (c0 != ci) {
@@ -3088,9 +3976,10 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
#endif
}
#ifdef BACKSLASH_IN_FILENAME
- p = vim_strsave_fnameescape(files[i], FALSE);
+ p = (char_u *)vim_strsave_fnameescape((const char *)files[i], false);
#else
- p = vim_strsave_fnameescape(files[i], xp->xp_shell);
+ p = (char_u *)vim_strsave_fnameescape((const char *)files[i],
+ xp->xp_shell);
#endif
xfree(files[i]);
files[i] = p;
@@ -3120,42 +4009,49 @@ void ExpandEscape(expand_T *xp, char_u *str, int numfiles, char_u **files, int o
}
}
-/*
- * Escape special characters in "fname" for when used as a file name argument
- * after a Vim command, or, when "shell" is non-zero, a shell command.
- * Returns the result in allocated memory.
- */
-char_u *vim_strsave_fnameescape(char_u *fname, int shell) FUNC_ATTR_NONNULL_RET
+/// Escape special characters in a file name for use as a command argument
+///
+/// @param[in] fname File name to escape.
+/// @param[in] shell What to escape for: if false, escapes for VimL command,
+/// if true then it escapes for a shell command.
+///
+/// @return [allocated] escaped file name.
+char *vim_strsave_fnameescape(const char *const fname, const bool shell)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- char_u *p;
#ifdef BACKSLASH_IN_FILENAME
-#define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`%#'\"|!<")
- char_u buf[20];
+#define PATH_ESC_CHARS " \t\n*?[{`%#'\"|!<"
+ char_u buf[sizeof(PATH_ESC_CHARS)];
int j = 0;
- /* Don't escape '[', '{' and '!' if they are in 'isfname'. */
- for (p = PATH_ESC_CHARS; *p != NUL; ++p)
- if ((*p != '[' && *p != '{' && *p != '!') || !vim_isfilec(*p))
- buf[j++] = *p;
+ // Don't escape '[', '{' and '!' if they are in 'isfname'.
+ for (const char *s = PATH_ESC_CHARS; *s != NUL; s++) {
+ if ((*s != '[' && *s != '{' && *s != '!') || !vim_isfilec(*s)) {
+ buf[j++] = *s;
+ }
+ }
buf[j] = NUL;
- p = vim_strsave_escaped(fname, buf);
+ char *p = (char *)vim_strsave_escaped((const char_u *)fname,
+ (const char_u *)buf);
#else
#define PATH_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<")
#define SHELL_ESC_CHARS ((char_u *)" \t\n*?[{`$\\%#'\"|!<>();&")
- p = vim_strsave_escaped(fname, shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS);
+ char *p = (char *)vim_strsave_escaped(
+ (const char_u *)fname, (shell ? SHELL_ESC_CHARS : PATH_ESC_CHARS));
if (shell && csh_like_shell()) {
- /* For csh and similar shells need to put two backslashes before '!'.
- * One is taken by Vim, one by the shell. */
- char_u *s = vim_strsave_escaped(p, (char_u *)"!");
+ // For csh and similar shells need to put two backslashes before '!'.
+ // One is taken by Vim, one by the shell.
+ char *s = (char *)vim_strsave_escaped((const char_u *)p,
+ (const char_u *)"!");
xfree(p);
p = s;
}
#endif
- /* '>' and '+' are special at the start of some commands, e.g. ":edit" and
- * ":write". "cd -" has a special meaning. */
+ // '>' and '+' are special at the start of some commands, e.g. ":edit" and
+ // ":write". "cd -" has a special meaning.
if (*p == '>' || *p == '+' || (*p == '-' && p[1] == NUL)) {
- escape_fname(&p);
+ escape_fname((char_u **)&p);
}
return p;
@@ -3224,6 +4120,15 @@ static int showmatches(expand_T *xp, int wildmenu)
showtail = cmd_showtail;
}
+ if (ui_is_external(kUIWildmenu)) {
+ Array args = ARRAY_DICT_INIT;
+ for (i = 0; i < num_files; i++) {
+ ADD(args, STRING_OBJ(cstr_to_string((char *)files_found[i])));
+ }
+ ui_call_wildmenu_show(args);
+ return EXPAND_OK;
+ }
+
if (!wildmenu) {
msg_didany = FALSE; /* lines_left will be set */
msg_start(); /* prepare for paging */
@@ -3234,12 +4139,12 @@ static int showmatches(expand_T *xp, int wildmenu)
msg_start(); /* prepare for paging */
}
- if (got_int)
- got_int = FALSE; /* only int. the completion, not the cmd line */
- else if (wildmenu)
- win_redr_status_matches(xp, num_files, files_found, 0, showtail);
- else {
- /* find the length of the longest file name */
+ if (got_int) {
+ got_int = false; // only int. the completion, not the cmd line
+ } else if (wildmenu) {
+ win_redr_status_matches(xp, num_files, files_found, -1, showtail);
+ } else {
+ // find the length of the longest file name
maxlen = 0;
for (i = 0; i < num_files; ++i) {
if (!showtail && (xp->xp_context == EXPAND_FILES
@@ -3264,13 +4169,13 @@ static int showmatches(expand_T *xp, int wildmenu)
lines = (num_files + columns - 1) / columns;
}
- attr = hl_attr(HLF_D); /* find out highlighting for directories */
+ attr = HL_ATTR(HLF_D); // find out highlighting for directories
if (xp->xp_context == EXPAND_TAGS_LISTFILES) {
- MSG_PUTS_ATTR(_("tagname"), hl_attr(HLF_T));
+ MSG_PUTS_ATTR(_("tagname"), HL_ATTR(HLF_T));
msg_clr_eos();
msg_advance(maxlen - 3);
- MSG_PUTS_ATTR(_(" kind file\n"), hl_attr(HLF_T));
+ MSG_PUTS_ATTR(_(" kind file\n"), HL_ATTR(HLF_T));
}
/* list the files line by line */
@@ -3278,12 +4183,12 @@ static int showmatches(expand_T *xp, int wildmenu)
lastlen = 999;
for (k = i; k < num_files; k += lines) {
if (xp->xp_context == EXPAND_TAGS_LISTFILES) {
- msg_outtrans_attr(files_found[k], hl_attr(HLF_D));
+ msg_outtrans_attr(files_found[k], HL_ATTR(HLF_D));
p = files_found[k] + STRLEN(files_found[k]) + 1;
msg_advance(maxlen + 1);
- msg_puts(p);
+ msg_puts((const char *)p);
msg_advance(maxlen + 3);
- msg_puts_long_attr(p + 2, hl_attr(HLF_D));
+ msg_puts_long_attr(p + 2, HL_ATTR(HLF_D));
break;
}
for (j = maxlen - lastlen; --j >= 0; )
@@ -3366,7 +4271,7 @@ char_u *sm_gettail(char_u *s)
t = p;
had_sep = FALSE;
}
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
return t;
}
@@ -3433,18 +4338,20 @@ addstar (
* use with vim_regcomp(). First work out how long it will be:
*/
- /* For help tags the translation is done in find_help_tags().
- * For a tag pattern starting with "/" no translation is needed. */
+ // For help tags the translation is done in find_help_tags().
+ // For a tag pattern starting with "/" no translation is needed.
if (context == EXPAND_HELP
+ || context == EXPAND_CHECKHEALTH
|| context == EXPAND_COLORS
|| context == EXPAND_COMPILER
|| context == EXPAND_OWNSYNTAX
|| context == EXPAND_FILETYPE
|| context == EXPAND_PACKADD
- || (context == EXPAND_TAGS && fname[0] == '/'))
+ || ((context == EXPAND_TAGS_LISTFILES || context == EXPAND_TAGS)
+ && fname[0] == '/')) {
retval = vim_strnsave(fname, len);
- else {
- new_len = len + 2; /* +2 for '^' at start, NUL at end */
+ } else {
+ new_len = len + 2; // +2 for '^' at start, NUL at end
for (i = 0; i < len; i++) {
if (fname[i] == '*' || fname[i] == '~')
new_len++; /* '*' needs to be replaced by ".*"
@@ -3579,19 +4486,19 @@ static void set_expand_context(expand_T *xp)
xp->xp_context = EXPAND_NOTHING;
return;
}
- set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos);
+ set_cmd_context(xp, ccline.cmdbuff, ccline.cmdlen, ccline.cmdpos, true);
}
void
set_cmd_context (
expand_T *xp,
- char_u *str, /* start of command line */
- int len, /* length of command line (excl. NUL) */
- int col /* position of cursor */
+ char_u *str, // start of command line
+ int len, // length of command line (excl. NUL)
+ int col, // position of cursor
+ int use_ccline // use ccline for info
)
{
int old_char = NUL;
- char_u *nextcomm;
/*
* Avoid a UMR warning from Purify, only save the character if it has been
@@ -3600,18 +4507,20 @@ set_cmd_context (
if (col < len)
old_char = str[col];
str[col] = NUL;
- nextcomm = str;
+ const char *nextcomm = (const char *)str;
- if (ccline.cmdfirstc == '=') {
- /* pass CMD_SIZE because there is no real command */
+ if (use_ccline && ccline.cmdfirstc == '=') {
+ // pass CMD_SIZE because there is no real command
set_context_for_expression(xp, str, CMD_SIZE);
- } else if (ccline.input_fn) {
+ } else if (use_ccline && ccline.input_fn) {
xp->xp_context = ccline.xp_context;
xp->xp_pattern = ccline.cmdbuff;
xp->xp_arg = ccline.xp_arg;
- } else
- while (nextcomm != NULL)
+ } else {
+ while (nextcomm != NULL) {
nextcomm = set_one_cmd_context(xp, nextcomm);
+ }
+ }
/* Store the string here so that call_user_expand_func() can get to them
* easily. */
@@ -3670,31 +4579,60 @@ expand_cmdline (
return EXPAND_OK;
}
-/*
- * Cleanup matches for help tags: remove "@en" if "en" is the only language.
- */
-
+// Cleanup matches for help tags:
+// Remove "@ab" if the top of 'helplang' is "ab" and the language of the first
+// tag matches it. Otherwise remove "@en" if "en" is the only language.
static void cleanup_help_tags(int num_file, char_u **file)
{
- int i, j;
- int len;
+ char_u buf[4];
+ char_u *p = buf;
+
+ if (p_hlg[0] != NUL && (p_hlg[0] != 'e' || p_hlg[1] != 'n')) {
+ *p++ = '@';
+ *p++ = p_hlg[0];
+ *p++ = p_hlg[1];
+ }
+ *p = NUL;
- for (i = 0; i < num_file; ++i) {
- len = (int)STRLEN(file[i]) - 3;
- if (len > 0 && STRCMP(file[i] + len, "@en") == 0) {
- /* Sorting on priority means the same item in another language may
- * be anywhere. Search all items for a match up to the "@en". */
- for (j = 0; j < num_file; ++j)
+ for (int i = 0; i < num_file; i++) {
+ int len = (int)STRLEN(file[i]) - 3;
+ if (len <= 0) {
+ continue;
+ }
+ if (STRCMP(file[i] + len, "@en") == 0) {
+ // Sorting on priority means the same item in another language may
+ // be anywhere. Search all items for a match up to the "@en".
+ int j;
+ for (j = 0; j < num_file; j++) {
if (j != i
&& (int)STRLEN(file[j]) == len + 3
- && STRNCMP(file[i], file[j], len + 1) == 0)
+ && STRNCMP(file[i], file[j], len + 1) == 0) {
break;
- if (j == num_file)
+ }
+ }
+ if (j == num_file) {
+ // item only exists with @en, remove it
file[i][len] = NUL;
+ }
+ }
+ }
+
+ if (*buf != NUL) {
+ for (int i = 0; i < num_file; i++) {
+ int len = (int)STRLEN(file[i]) - 3;
+ if (len <= 0) {
+ continue;
+ }
+ if (STRCMP(file[i] + len, buf) == 0) {
+ // remove the default language
+ file[i][len] = NUL;
+ }
}
}
}
+typedef char_u *(*ExpandFunc)(expand_T *, int);
+
/*
* Do the expansion based on xp->xp_context and "pat".
*/
@@ -3773,7 +4711,7 @@ ExpandFromContext (
/* 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 ? (char_u *)"help" : pat,
- num_file, file, FALSE) == OK) {
+ num_file, file, false) == OK) {
cleanup_help_tags(*num_file, *file);
return OK;
}
@@ -3810,6 +4748,10 @@ ExpandFromContext (
char *directories[] = { "syntax", "indent", "ftplugin", NULL };
return ExpandRTDir(pat, 0, num_file, file, directories);
}
+ if (xp->xp_context == EXPAND_CHECKHEALTH) {
+ char *directories[] = { "autoload/health", NULL };
+ return ExpandRTDir(pat, 0, num_file, file, directories);
+ }
if (xp->xp_context == EXPAND_USER_LIST) {
return ExpandUserList(xp, num_file, file);
}
@@ -3834,39 +4776,41 @@ ExpandFromContext (
else {
static struct expgen {
int context;
- char_u *((*func)(expand_T *, int));
+ ExpandFunc func;
int ic;
int escaped;
- } tab[] =
- {
- {EXPAND_COMMANDS, get_command_name, FALSE, TRUE},
- {EXPAND_BEHAVE, get_behave_arg, TRUE, TRUE},
- {EXPAND_HISTORY, get_history_arg, TRUE, TRUE},
- {EXPAND_USER_COMMANDS, get_user_commands, FALSE, TRUE},
- {EXPAND_USER_ADDR_TYPE, get_user_cmd_addr_type, FALSE, TRUE},
- {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE},
- {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE},
- {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE},
- {EXPAND_USER_VARS, get_user_var_name, FALSE, TRUE},
- {EXPAND_FUNCTIONS, get_function_name, FALSE, TRUE},
- {EXPAND_USER_FUNC, get_user_func_name, FALSE, TRUE},
- {EXPAND_EXPRESSION, get_expr_name, FALSE, TRUE},
- {EXPAND_MENUS, get_menu_name, FALSE, TRUE},
- {EXPAND_MENUNAMES, get_menu_names, FALSE, TRUE},
- {EXPAND_SYNTAX, get_syntax_name, TRUE, TRUE},
- {EXPAND_SYNTIME, get_syntime_arg, TRUE, TRUE},
- {EXPAND_HIGHLIGHT, get_highlight_name, TRUE, TRUE},
- {EXPAND_EVENTS, get_event_name, TRUE, TRUE},
- {EXPAND_AUGROUP, get_augroup_name, TRUE, TRUE},
- {EXPAND_CSCOPE, get_cscope_name, TRUE, TRUE},
- {EXPAND_SIGN, get_sign_name, TRUE, TRUE},
- {EXPAND_PROFILE, get_profile_name, TRUE, TRUE},
+ } tab[] = {
+ { EXPAND_COMMANDS, get_command_name, false, true },
+ { EXPAND_BEHAVE, get_behave_arg, true, true },
+ { EXPAND_MAPCLEAR, get_mapclear_arg, true, true },
+ { EXPAND_MESSAGES, get_messages_arg, true, true },
+ { EXPAND_HISTORY, get_history_arg, true, true },
+ { EXPAND_USER_COMMANDS, get_user_commands, false, true },
+ { EXPAND_USER_ADDR_TYPE, get_user_cmd_addr_type, false, true },
+ { EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, false, true },
+ { EXPAND_USER_NARGS, get_user_cmd_nargs, false, true },
+ { EXPAND_USER_COMPLETE, get_user_cmd_complete, false, true },
+ { EXPAND_USER_VARS, get_user_var_name, false, true },
+ { EXPAND_FUNCTIONS, get_function_name, false, true },
+ { EXPAND_USER_FUNC, get_user_func_name, false, true },
+ { EXPAND_EXPRESSION, get_expr_name, false, true },
+ { EXPAND_MENUS, get_menu_name, false, true },
+ { EXPAND_MENUNAMES, get_menu_names, false, true },
+ { EXPAND_SYNTAX, get_syntax_name, true, true },
+ { EXPAND_SYNTIME, get_syntime_arg, true, true },
+ { EXPAND_HIGHLIGHT, (ExpandFunc)get_highlight_name, true, true },
+ { EXPAND_EVENTS, get_event_name, true, true },
+ { EXPAND_AUGROUP, get_augroup_name, true, true },
+ { EXPAND_CSCOPE, get_cscope_name, true, true },
+ { EXPAND_SIGN, get_sign_name, true, true },
+ { EXPAND_PROFILE, get_profile_name, true, true },
#ifdef HAVE_WORKING_LIBINTL
- {EXPAND_LANGUAGE, get_lang_arg, TRUE, FALSE},
- {EXPAND_LOCALES, get_locales, TRUE, FALSE},
+ { EXPAND_LANGUAGE, get_lang_arg, true, false },
+ { EXPAND_LOCALES, get_locales, true, false },
#endif
- {EXPAND_ENV_VARS, get_env_name, TRUE, TRUE},
- {EXPAND_USER, get_users, TRUE, FALSE},
+ { EXPAND_ENV_VARS, get_env_name, true, true },
+ { EXPAND_USER, get_users, true, false },
+ { EXPAND_ARGLIST, get_arglist_name, true, false },
};
int i;
@@ -3930,23 +4874,27 @@ void ExpandGeneric(
// copy the matching names into allocated memory
count = 0;
- for (i = 0;; ++i) {
+ for (i = 0;; i++) {
str = (*func)(xp, i);
- if (str == NULL) // end of list
+ if (str == NULL) { // End of list.
break;
- if (*str == NUL) // skip empty strings
+ }
+ if (*str == NUL) { // Skip empty strings.
continue;
+ }
if (vim_regexec(regmatch, str, (colnr_T)0)) {
- if (escaped)
+ if (escaped) {
str = vim_strsave_escaped(str, (char_u *)" \t\\.");
- else
+ } else {
str = vim_strsave(str);
+ }
(*file)[count++] = str;
- if (func == get_menu_names && str != NULL) {
- /* test for separator added by get_menu_names() */
+ if (func == get_menu_names) {
+ // Test for separator added by get_menu_names().
str += STRLEN(str) - 1;
- if (*str == '\001')
+ if (*str == '\001') {
*str = '.';
+ }
}
}
}
@@ -3978,7 +4926,7 @@ void ExpandGeneric(
/// @param flagsarg is a combination of EW_* flags.
static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
int flagsarg)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ALL
{
char_u *pat;
int i;
@@ -4001,13 +4949,14 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
flags |= EW_FILE | EW_EXEC | EW_SHELLCMD;
bool mustfree = false; // Track memory allocation for *path.
- /* For an absolute name we don't use $PATH. */
- if (path_is_absolute_path(pat))
+ // For an absolute name we don't use $PATH.
+ if (path_is_absolute(pat)) {
path = (char_u *)" ";
- else if ((pat[0] == '.' && (vim_ispathsep(pat[1])
- || (pat[1] == '.' && vim_ispathsep(pat[2])))))
+ } else if (pat[0] == '.' && (vim_ispathsep(pat[1])
+ || (pat[1] == '.'
+ && vim_ispathsep(pat[2])))) {
path = (char_u *)".";
- else {
+ } else {
path = (char_u *)vim_getenv("PATH");
if (path == NULL) {
path = (char_u *)"";
@@ -4079,10 +5028,8 @@ static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
}
}
-/*
- * Call "user_expand_func()" to invoke a user defined VimL function and return
- * the result (either a string or a List).
- */
+/// Call "user_expand_func()" to invoke a user defined Vim script function and
+/// return the result (either a string or a List).
static void * call_user_expand_func(user_expand_func_T user_expand_func,
expand_T *xp, int *num_file, char_u ***file)
{
@@ -4114,7 +5061,10 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
ccline.cmdprompt = NULL;
current_SID = xp->xp_scriptID;
- ret = user_expand_func(xp->xp_arg, 3, args, FALSE);
+ ret = user_expand_func(xp->xp_arg,
+ 3,
+ (const char_u * const *)args,
+ false);
ccline = save_ccline;
current_SID = save_current_SID;
@@ -4130,36 +5080,34 @@ static void * call_user_expand_func(user_expand_func_T user_expand_func,
*/
static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)
{
- char_u *retstr;
- char_u *s;
- char_u *e;
- char_u keep;
- garray_T ga;
+ char_u *e;
+ garray_T ga;
+
+ char_u *const retstr = call_user_expand_func(
+ (user_expand_func_T)call_func_retstr, xp, num_file, file);
- retstr = call_user_expand_func(call_func_retstr, xp, num_file, file);
- if (retstr == NULL)
+ if (retstr == NULL) {
return FAIL;
+ }
ga_init(&ga, (int)sizeof(char *), 3);
- for (s = retstr; *s != NUL; s = e) {
+ for (char_u *s = retstr; *s != NUL; s = e) {
e = vim_strchr(s, '\n');
if (e == NULL)
e = s + STRLEN(s);
- keep = *e;
- *e = 0;
+ const int keep = *e;
+ *e = NUL;
- if (xp->xp_pattern[0] && vim_regexec(regmatch, s, (colnr_T)0) == 0) {
- *e = keep;
- if (*e != NUL)
- ++e;
- continue;
+ const bool skip = xp->xp_pattern[0]
+ && vim_regexec(regmatch, s, (colnr_T)0) == 0;
+ *e = keep;
+ if (!skip) {
+ GA_APPEND(char_u *, &ga, vim_strnsave(s, (int)(e - s)));
}
- GA_APPEND(char_u *, &ga, vim_strnsave(s, (int)(e - s)));
-
- *e = keep;
- if (*e != NUL)
- ++e;
+ if (*e != NUL) {
+ e++;
+ }
}
xfree(retstr);
*file = ga.ga_data;
@@ -4172,23 +5120,25 @@ static int ExpandUserDefined(expand_T *xp, regmatch_T *regmatch, int *num_file,
*/
static int ExpandUserList(expand_T *xp, int *num_file, char_u ***file)
{
- list_T *retlist;
- listitem_T *li;
- garray_T ga;
-
- retlist = call_user_expand_func(call_func_retlist, xp, num_file, file);
- if (retlist == NULL)
+ list_T *const retlist = call_user_expand_func(
+ (user_expand_func_T)call_func_retlist, xp, num_file, file);
+ if (retlist == NULL) {
return FAIL;
+ }
+ garray_T ga;
ga_init(&ga, (int)sizeof(char *), 3);
- /* Loop over the items in the list. */
- for (li = retlist->lv_first; li != NULL; li = li->li_next) {
- if (li->li_tv.v_type != VAR_STRING || li->li_tv.vval.v_string == NULL)
- continue; /* Skip non-string items and empty strings */
+ // Loop over the items in the list.
+ TV_LIST_ITER_CONST(retlist, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING
+ || TV_LIST_ITEM_TV(li)->vval.v_string == NULL) {
+ continue; // Skip non-string items and empty strings.
+ }
- GA_APPEND(char_u *, &ga, vim_strsave(li->li_tv.vval.v_string));
- }
- list_unref(retlist);
+ GA_APPEND(char *, &ga, xstrdup(
+ (const char *)TV_LIST_ITEM_TV(li)->vval.v_string));
+ });
+ tv_list_unref(retlist);
*file = ga.ga_data;
*num_file = ga.ga_len;
@@ -4247,7 +5197,7 @@ static int ExpandRTDir(char_u *pat, int flags, int *num_file, char_u ***file,
char_u *e = s + STRLEN(s);
if (e - s > 4 && STRNICMP(e - 4, ".vim", 4) == 0) {
e -= 4;
- for (s = e; s > match; mb_ptr_back(match, s)) {
+ for (s = e; s > match; MB_PTR_BACK(match, s)) {
if (vim_ispathsep(*s)) {
break;
}
@@ -4371,6 +5321,7 @@ static HistoryType hist_char2type(const int c)
case '>': {
return HIST_DEBUG;
}
+ case NUL:
case '/':
case '?': {
return HIST_SEARCH;
@@ -4483,7 +5434,7 @@ static inline void hist_free_entry(histentry_T *hisptr)
FUNC_ATTR_NONNULL_ALL
{
xfree(hisptr->hisstr);
- list_unref(hisptr->additional_elements);
+ tv_list_unref(hisptr->additional_elements);
clear_hist_entry(hisptr);
}
@@ -4539,7 +5490,7 @@ in_history (
history[type][last_i] = history[type][i];
last_i = i;
}
- list_unref(list);
+ tv_list_unref(list);
history[type][i].hisnum = ++hisnum[type];
history[type][i].hisstr = str;
history[type][i].timestamp = os_time();
@@ -4561,7 +5512,7 @@ in_history (
///
/// @return Any value from HistoryType enum, including HIST_INVALID. May not
/// return HIST_DEFAULT unless return_default is true.
-HistoryType get_histtype(const char_u *const name, const size_t len,
+HistoryType get_histtype(const char *const name, const size_t len,
const bool return_default)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
@@ -4615,8 +5566,8 @@ add_to_history (
* down, only lines that were added.
*/
if (histype == HIST_SEARCH && in_map) {
- if (maptick == last_maptick) {
- /* Current line is from the same mapping, remove it */
+ if (maptick == last_maptick && hisidx[HIST_SEARCH] >= 0) {
+ // Current line is from the same mapping, remove it
hisptr = &history[HIST_SEARCH][hisidx[HIST_SEARCH]];
hist_free_entry(hisptr);
--hisnum[histype];
@@ -4665,13 +5616,15 @@ int get_history_idx(int histype)
*/
static struct cmdline_info *get_ccline_ptr(void)
{
- if ((State & CMDLINE) == 0)
+ if ((State & CMDLINE) == 0) {
return NULL;
- if (ccline.cmdbuff != NULL)
+ } else if (ccline.cmdbuff != NULL) {
return &ccline;
- if (prev_ccline_used && prev_ccline.cmdbuff != NULL)
- return &prev_ccline;
- return NULL;
+ } else if (ccline.prev_ccline && ccline.prev_ccline->cmdbuff != NULL) {
+ return ccline.prev_ccline;
+ } else {
+ return NULL;
+ }
}
/*
@@ -4681,6 +5634,9 @@ static struct cmdline_info *get_ccline_ptr(void)
*/
char_u *get_cmdline_str(void)
{
+ if (cmdline_star > 0) {
+ return NULL;
+ }
struct cmdline_info *p = get_ccline_ptr();
if (p == NULL)
@@ -4904,7 +5860,7 @@ int get_list_range(char_u **str, int *num1, int *num2)
{
int len;
int first = false;
- long num;
+ varnumber_T num;
*str = skipwhite(*str);
if (**str == '-' || ascii_isdigit(**str)) { // parse "from" part of range
@@ -4954,7 +5910,7 @@ void ex_history(exarg_T *eap)
while (ASCII_ISALPHA(*end)
|| vim_strchr((char_u *)":=@>/?", *end) != NULL)
end++;
- histype1 = get_histtype(arg, end - arg, false);
+ histype1 = get_histtype((const char *)arg, end - arg, false);
if (histype1 == HIST_INVALID) {
if (STRNICMP(arg, "all", end - arg) == 0) {
histype1 = 0;
@@ -4975,6 +5931,7 @@ void ex_history(exarg_T *eap)
for (; !got_int && histype1 <= histype2; ++histype1) {
STRCPY(IObuff, "\n # ");
+ assert(history_names[histype1] != NULL);
STRCAT(STRCAT(IObuff, history_names[histype1]), " history");
MSG_PUTS_TITLE(IObuff);
idx = hisidx[histype1];
@@ -5066,12 +6023,12 @@ int cmd_gchar(int offset)
* Ctrl_C if it is to be abandoned
* K_IGNORE if editing continues
*/
-static int ex_window(void)
+static int open_cmdwin(void)
{
struct cmdline_info save_ccline;
- buf_T *old_curbuf = curbuf;
+ bufref_T old_curbuf;
+ bufref_T bufref;
win_T *old_curwin = curwin;
- buf_T *bp;
win_T *wp;
int i;
linenr_T lnum;
@@ -5090,6 +6047,8 @@ static int ex_window(void)
return K_IGNORE;
}
+ set_bufref(&old_curbuf, curbuf);
+
/* Save current window sizes. */
win_size_save(&winsizes);
@@ -5097,6 +6056,7 @@ static int ex_window(void)
block_autocmds();
/* don't use a new tab page */
cmdmod.tab = 0;
+ cmdmod.noswapfile = 1;
/* Create a window for the command-line buffer. */
if (win_split((int)p_cwh, WSP_BOT) == FAIL) {
@@ -5105,20 +6065,21 @@ static int ex_window(void)
return K_IGNORE;
}
cmdwin_type = get_cmdline_type();
+ cmdwin_level = ccline.level;
- /* Create the command-line buffer empty. */
- (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
- (void)setfname(curbuf, (char_u *)"[Command Line]", NULL, TRUE);
- set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
- set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
- curbuf->b_p_ma = TRUE;
- curwin->w_p_fen = FALSE;
+ // Create empty command-line buffer.
+ buf_open_scratch(0, "[Command Line]");
+ // Command-line buffer has bufhidden=wipe, unlike a true "scratch" buffer.
+ set_option_value("bh", 0L, "wipe", OPT_LOCAL);
curwin->w_p_rl = cmdmsg_rl;
- cmdmsg_rl = FALSE;
- RESET_BINDING(curwin);
+ cmdmsg_rl = false;
+ curbuf->b_p_ma = true;
+ curwin->w_p_fen = false;
- /* Do execute autocommands for setting the filetype (load syntax). */
+ // Do execute autocommands for setting the filetype (load syntax).
unblock_autocmds();
+ // But don't allow switching to another buffer.
+ curbuf_lock++;
/* Showing the prompt may have set need_wait_return, reset it. */
need_wait_return = FALSE;
@@ -5129,8 +6090,9 @@ static int ex_window(void)
add_map((char_u *)"<buffer> <Tab> <C-X><C-V>", INSERT);
add_map((char_u *)"<buffer> <Tab> a<C-X><C-V>", NORMAL);
}
- set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL);
+ set_option_value("ft", 0L, "vim", OPT_LOCAL);
}
+ curbuf_lock--;
/* Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
* sets 'textwidth' to 78). */
@@ -5154,17 +6116,19 @@ static int ex_window(void)
/* Replace the empty last line with the current command-line and put the
* cursor there. */
- ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, TRUE);
+ ml_replace(curbuf->b_ml.ml_line_count, ccline.cmdbuff, true);
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
curwin->w_cursor.col = ccline.cmdpos;
changed_line_abv_curs();
invalidate_botline();
+ if (ui_is_external(kUICmdline)) {
+ ccline.redraw_state = kCmdRedrawNone;
+ ui_call_cmdline_hide(ccline.level);
+ }
redraw_later(SOME_VALID);
- /* Save the command line info, can be used recursively. */
- save_ccline = ccline;
- ccline.cmdbuff = NULL;
- ccline.cmdprompt = NULL;
+ // Save the command line info, can be used recursively.
+ save_cmdline(&save_ccline);
/* No Ex mode here! */
exmode_active = 0;
@@ -5181,6 +6145,7 @@ static int ex_window(void)
i = RedrawingDisabled;
RedrawingDisabled = 0;
+ int save_count = save_batch_count();
/*
* Call the main loop until <CR> or CTRL-C is typed.
@@ -5189,8 +6154,9 @@ static int ex_window(void)
normal_enter(true, false);
RedrawingDisabled = i;
+ restore_batch_count(save_count);
- int save_KeyTyped = KeyTyped;
+ const bool save_KeyTyped = KeyTyped;
/* Trigger CmdwinLeave autocommands. */
apply_autocmds(EVENT_CMDWINLEAVE, typestr, typestr, FALSE, curbuf);
@@ -5198,15 +6164,16 @@ static int ex_window(void)
/* Restore KeyTyped in case it is modified by autocommands */
KeyTyped = save_KeyTyped;
- /* Restore the command line info. */
- ccline = save_ccline;
+ // Restore the command line info.
+ restore_cmdline(&save_ccline);
cmdwin_type = 0;
+ cmdwin_level = 0;
exmode_active = save_exmode;
/* Safety check: The old window or buffer was deleted: It's a bug when
* this happens! */
- if (!win_valid(old_curwin) || !buf_valid(old_curbuf)) {
+ if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) {
cmdwin_result = Ctrl_C;
EMSG(_("E199: Active window or buffer deleted"));
} else {
@@ -5215,32 +6182,33 @@ static int ex_window(void)
cmdwin_result = Ctrl_C;
/* Set the new command line from the cmdline buffer. */
xfree(ccline.cmdbuff);
- if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { /* :qa[!] typed */
- char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
+ if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed
+ const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
if (histtype == HIST_CMD) {
- /* Execute the command directly. */
- ccline.cmdbuff = vim_strsave((char_u *)p);
+ // Execute the command directly.
+ ccline.cmdbuff = (char_u *)xstrdup(p);
cmdwin_result = CAR;
} else {
- /* First need to cancel what we were doing. */
+ // First need to cancel what we were doing.
ccline.cmdbuff = NULL;
stuffcharReadbuff(':');
- stuffReadbuff((char_u *)p);
+ stuffReadbuff(p);
stuffcharReadbuff(CAR);
}
- } else if (cmdwin_result == K_XF2) { /* :qa typed */
- ccline.cmdbuff = vim_strsave((char_u *)"qa");
- cmdwin_result = CAR;
} else if (cmdwin_result == Ctrl_C) {
/* :q or :close, don't execute any command
* and don't modify the cmd window. */
ccline.cmdbuff = NULL;
} else
ccline.cmdbuff = vim_strsave(get_cursor_line_ptr());
- if (ccline.cmdbuff == NULL)
+ if (ccline.cmdbuff == NULL) {
+ ccline.cmdbuff = vim_strsave((char_u *)"");
+ ccline.cmdlen = 0;
+ ccline.cmdbufflen = 1;
+ ccline.cmdpos = 0;
cmdwin_result = Ctrl_C;
- else {
+ } else {
ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
ccline.cmdbufflen = ccline.cmdlen + 1;
ccline.cmdpos = curwin->w_cursor.col;
@@ -5257,14 +6225,15 @@ static int ex_window(void)
// Avoid command-line window first character being concealed
curwin->w_p_cole = 0;
wp = curwin;
- bp = curbuf;
+ set_bufref(&bufref, curbuf);
win_goto(old_curwin);
- win_close(wp, TRUE);
+ win_close(wp, true);
- /* win_close() may have already wiped the buffer when 'bh' is
- * set to 'wipe' */
- if (buf_valid(bp))
- close_buffer(NULL, bp, DOBUF_WIPE, FALSE);
+ // win_close() may have already wiped the buffer when 'bh' is
+ // set to 'wipe'.
+ if (bufref_valid(&bufref)) {
+ close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, false);
+ }
/* Restore window sizes. */
win_size_restore(&winsizes);
@@ -5282,47 +6251,61 @@ static int ex_window(void)
return cmdwin_result;
}
-/*
- * Used for commands that either take a simple command string argument, or:
- * cmd << endmarker
- * {script}
- * endmarker
- * Returns a pointer to allocated memory with {script} or NULL.
- */
-char_u *script_get(exarg_T *eap, char_u *cmd)
+/// Get script string
+///
+/// Used for commands which accept either `:command script` or
+///
+/// :command << endmarker
+/// script
+/// endmarker
+///
+/// @param eap Command being run.
+/// @param[out] lenp Location where length of resulting string is saved. Will
+/// be set to zero when skipping.
+///
+/// @return [allocated] NULL or script. Does not show any error messages.
+/// NULL is returned when skipping and on error.
+char *script_get(exarg_T *const eap, size_t *const lenp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
- char_u *theline;
- char *end_pattern = NULL;
- char dot[] = ".";
- garray_T ga;
+ const char *const cmd = (const char *)eap->arg;
- if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL)
- return NULL;
-
- ga_init(&ga, 1, 0x400);
+ if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) {
+ *lenp = STRLEN(eap->arg);
+ return eap->skip ? NULL : xmemdupz(eap->arg, *lenp);
+ }
- if (cmd[2] != NUL)
- end_pattern = (char *)skipwhite(cmd + 2);
- else
- end_pattern = dot;
+ garray_T ga = { .ga_data = NULL, .ga_len = 0 };
+ if (!eap->skip) {
+ ga_init(&ga, 1, 0x400);
+ }
- for (;; ) {
- theline = eap->getline(
+ const char *const end_pattern = (
+ cmd[2] != NUL
+ ? (const char *)skipwhite((const char_u *)cmd + 2)
+ : ".");
+ for (;;) {
+ char *const theline = (char *)eap->getline(
eap->cstack->cs_looplevel > 0 ? -1 :
NUL, eap->cookie, 0);
- if (theline == NULL || STRCMP(end_pattern, theline) == 0) {
+ if (theline == NULL || strcmp(end_pattern, theline) == 0) {
xfree(theline);
break;
}
- ga_concat(&ga, theline);
- ga_append(&ga, '\n');
+ if (!eap->skip) {
+ ga_concat(&ga, (const char_u *)theline);
+ ga_append(&ga, '\n');
+ }
xfree(theline);
}
- ga_append(&ga, NUL);
+ *lenp = (size_t)ga.ga_len; // Set length without trailing NUL.
+ if (!eap->skip) {
+ ga_append(&ga, NUL);
+ }
- return (char_u *)ga.ga_data;
+ return (char *)ga.ga_data;
}
/// Iterate over history items
@@ -5408,3 +6391,15 @@ histentry_T *hist_get_array(const uint8_t history_type, int **const new_hisidx,
*new_hisnum = &(hisnum[history_type]);
return history[history_type];
}
+
+static void set_search_match(pos_T *t)
+{
+ // First move cursor to end of match, then to the start. This
+ // moves the whole match onto the screen when 'nowrap' is set.
+ t->lnum += search_match_lines;
+ t->col = search_match_endcol;
+ if (t->lnum > curbuf->b_ml.ml_line_count) {
+ t->lnum = curbuf->b_ml.ml_line_count;
+ coladvance((colnr_T)MAXCOL);
+ }
+}
diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h
index 24eebdc303..051564fbe1 100644
--- a/src/nvim/ex_getln.h
+++ b/src/nvim/ex_getln.h
@@ -1,8 +1,11 @@
#ifndef NVIM_EX_GETLN_H
#define NVIM_EX_GETLN_H
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
+#include "nvim/ex_cmds_defs.h"
+#include "nvim/os/time.h"
+#include "nvim/regexp_defs.h"
/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */
#define WILD_FREE 1
diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c
index 61e17128ea..3d714f0fa6 100644
--- a/src/nvim/farsi.c
+++ b/src/nvim/farsi.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
+
/// @file farsi.c
///
/// Functions for Farsi language
@@ -15,7 +18,6 @@
#include "nvim/memline.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/vim.h"
@@ -132,7 +134,7 @@ static char_u toF_Xor_X_(int c)
/// @param c The character to convert.
///
/// @return Character converted to the Farsi capital leter.
-char_u toF_TyA(char_u c)
+static char_u toF_TyA(char_u c)
{
char_u tempc;
@@ -322,7 +324,7 @@ static void put_curr_and_l_to_X(char_u c)
}
if ((curwin->w_cursor.col < (colnr_T)STRLEN(get_cursor_line_ptr()))) {
- if ((p_ri && curwin->w_cursor.col) || !p_ri) {
+ if (!p_ri || curwin->w_cursor.col) {
if (p_ri) {
dec_cursor();
} else {
@@ -594,78 +596,83 @@ static void chg_r_to_Xor_X_(void)
int fkmap(int c)
{
int tempc;
- static int revins;
+ int insert_mode = (State & INSERT);
+ static int revins = 0;
if (IS_SPECIAL(c)) {
return c;
}
- if (ascii_isdigit(c)
- || ((c == '.'
- || c == '+'
- || c == '-'
- || c == '^'
- || c == '%'
- || c == '#'
- || c == '=')
- && revins)) {
- if (!revins) {
- if (curwin->w_cursor.col) {
- if (!p_ri) {
- dec_cursor();
- }
+ if (insert_mode) {
+ if (ascii_isdigit(c)
+ || ((c == '.'
+ || c == '+'
+ || c == '-'
+ || c == '^'
+ || c == '%'
+ || c == '#'
+ || c == '=')
+ && revins)) {
+ // Numbers are entered left-to-right.
+ if (!revins) {
+ if (curwin->w_cursor.col) {
+ if (!p_ri) {
+ dec_cursor();
+ }
- chg_c_toX_orX();
- chg_l_toXor_X();
- if (!p_ri) {
- inc_cursor();
+ chg_c_toX_orX();
+ chg_l_toXor_X();
+ if (!p_ri) {
+ inc_cursor();
+ }
}
}
- }
- arrow_used = TRUE;
- (void)stop_arrow();
-
- if (!curwin->w_p_rl && revins) {
- inc_cursor();
- }
-
- revins++;
- p_ri = 1;
- } else {
- if (revins) {
- arrow_used = TRUE;
+ arrow_used = true;
(void)stop_arrow();
- revins = 0;
- if (curwin->w_p_rl) {
- while ((F_isdigit(gchar_cursor())
- || (gchar_cursor() == F_PERIOD
- || gchar_cursor() == F_PLUS
- || gchar_cursor() == F_MINUS
- || gchar_cursor() == F_MUL
- || gchar_cursor() == F_DIVIDE
- || gchar_cursor() == F_PERCENT
- || gchar_cursor() == F_EQUALS))
- && gchar_cursor() != NUL) {
- curwin->w_cursor.col++;
- }
- } else {
- if (curwin->w_cursor.col) {
+ if (!curwin->w_p_rl && revins) {
+ inc_cursor();
+ }
+
+ revins++;
+ p_ri = 1;
+ } else {
+ if (revins) {
+ // Stop entering number.
+ arrow_used = true;
+ (void)stop_arrow();
+
+ revins = 0;
+ if (curwin->w_p_rl) {
while ((F_isdigit(gchar_cursor())
- || (gchar_cursor() == F_PERIOD
- || gchar_cursor() == F_PLUS
- || gchar_cursor() == F_MINUS
- || gchar_cursor() == F_MUL
- || gchar_cursor() == F_DIVIDE
- || gchar_cursor() == F_PERCENT
- || gchar_cursor() == F_EQUALS))
- && --curwin->w_cursor.col) {
+ || (gchar_cursor() == F_PERIOD
+ || gchar_cursor() == F_PLUS
+ || gchar_cursor() == F_MINUS
+ || gchar_cursor() == F_MUL
+ || gchar_cursor() == F_DIVIDE
+ || gchar_cursor() == F_PERCENT
+ || gchar_cursor() == F_EQUALS))
+ && gchar_cursor() != NUL) {
+ curwin->w_cursor.col++;
+ }
+ } else {
+ if (curwin->w_cursor.col) {
+ while ((F_isdigit(gchar_cursor())
+ || (gchar_cursor() == F_PERIOD
+ || gchar_cursor() == F_PLUS
+ || gchar_cursor() == F_MINUS
+ || gchar_cursor() == F_MUL
+ || gchar_cursor() == F_DIVIDE
+ || gchar_cursor() == F_PERCENT
+ || gchar_cursor() == F_EQUALS))
+ && --curwin->w_cursor.col) {
+ }
}
- }
- if (!F_isdigit(gchar_cursor())) {
- ++curwin->w_cursor.col;
+ if (!F_isdigit(gchar_cursor())) {
+ curwin->w_cursor.col++;
+ }
}
}
}
@@ -753,7 +760,7 @@ int fkmap(int c)
case 'Y':
case NL:
case TAB:
- if (p_ri && (c == NL) && curwin->w_cursor.col) {
+ if (p_ri && (c == NL) && curwin->w_cursor.col && insert_mode) {
// If the char before the cursor is _X_ or X_ do not change
// the one under the cursor with X type.
@@ -824,135 +831,137 @@ int fkmap(int c)
}
}
- if (!p_ri) {
- dec_cursor();
- }
+ if (insert_mode) {
+ if (!p_ri) {
+ dec_cursor();
+ }
- switch ((tempc = gchar_cursor())) {
- case _BE:
- case _PE:
- case _TE:
- case _SE:
- case _JIM:
- case _CHE:
- case _HE_J:
- case _XE:
- case _SIN:
- case _SHIN:
- case _SAD:
- case _ZAD:
- case _FE:
- case _GHAF:
- case _KAF:
- case _KAF_H:
- case _GAF:
- case _LAM:
- case _MIM:
- case _NOON:
- case _HE:
- case _HE_:
- case _TA:
- case _ZA:
- put_curr_and_l_to_X(toF_TyA((char_u)tempc));
- break;
+ switch ((tempc = gchar_cursor())) {
+ case _BE:
+ case _PE:
+ case _TE:
+ case _SE:
+ case _JIM:
+ case _CHE:
+ case _HE_J:
+ case _XE:
+ case _SIN:
+ case _SHIN:
+ case _SAD:
+ case _ZAD:
+ case _FE:
+ case _GHAF:
+ case _KAF:
+ case _KAF_H:
+ case _GAF:
+ case _LAM:
+ case _MIM:
+ case _NOON:
+ case _HE:
+ case _HE_:
+ case _TA:
+ case _ZA:
+ put_curr_and_l_to_X(toF_TyA((char_u)tempc));
+ break;
- case _AYN:
- case _AYN_:
- if (!p_ri) {
- if (!curwin->w_cursor.col) {
- put_curr_and_l_to_X(AYN);
- break;
+ case _AYN:
+ case _AYN_:
+ if (!p_ri) {
+ if (!curwin->w_cursor.col) {
+ put_curr_and_l_to_X(AYN);
+ break;
+ }
}
- }
- if (p_ri) {
- inc_cursor();
- } else {
- dec_cursor();
- }
+ if (p_ri) {
+ inc_cursor();
+ } else {
+ dec_cursor();
+ }
- if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
- tempc = AYN_;
- } else {
- tempc = AYN;
- }
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
+ tempc = AYN_;
+ } else {
+ tempc = AYN;
+ }
- if (p_ri) {
- dec_cursor();
- } else {
- inc_cursor();
- }
+ if (p_ri) {
+ dec_cursor();
+ } else {
+ inc_cursor();
+ }
- put_curr_and_l_to_X((char_u)tempc);
- break;
+ put_curr_and_l_to_X((char_u)tempc);
+ break;
- case _GHAYN:
- case _GHAYN_:
+ case _GHAYN:
+ case _GHAYN_:
- if (!p_ri) {
- if (!curwin->w_cursor.col) {
- put_curr_and_l_to_X(GHAYN);
- break;
+ if (!p_ri) {
+ if (!curwin->w_cursor.col) {
+ put_curr_and_l_to_X(GHAYN);
+ break;
+ }
}
- }
- if (p_ri) {
- inc_cursor();
- } else {
- dec_cursor();
- }
+ if (p_ri) {
+ inc_cursor();
+ } else {
+ dec_cursor();
+ }
- if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
- tempc = GHAYN_;
- } else {
- tempc = GHAYN;
- }
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
+ tempc = GHAYN_;
+ } else {
+ tempc = GHAYN;
+ }
- if (p_ri) {
- dec_cursor();
- } else {
- inc_cursor();
- }
+ if (p_ri) {
+ dec_cursor();
+ } else {
+ inc_cursor();
+ }
- put_curr_and_l_to_X((char_u)tempc);
- break;
+ put_curr_and_l_to_X((char_u)tempc);
+ break;
- case _YE:
- case _IE:
- case _YEE:
+ case _YE:
+ case _IE:
+ case _YEE:
- if (!p_ri) {
- if (!curwin->w_cursor.col) {
- put_curr_and_l_to_X(
- (tempc == _YE ? YE : tempc == _IE ? IE : YEE));
- break;
+ if (!p_ri) {
+ if (!curwin->w_cursor.col) {
+ put_curr_and_l_to_X(
+ (tempc == _YE ? YE : tempc == _IE ? IE : YEE));
+ break;
+ }
}
- }
- if (p_ri) {
- inc_cursor();
- } else {
- dec_cursor();
- }
+ if (p_ri) {
+ inc_cursor();
+ } else {
+ dec_cursor();
+ }
- if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
- tempc = (tempc == _YE ? YE_ : tempc == _IE ? IE_ : YEE_);
- } else {
- tempc = (tempc == _YE ? YE : tempc == _IE ? IE : YEE);
- }
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
+ tempc = (tempc == _YE ? YE_ : tempc == _IE ? IE_ : YEE_);
+ } else {
+ tempc = (tempc == _YE ? YE : tempc == _IE ? IE : YEE);
+ }
- if (p_ri) {
- dec_cursor();
- } else {
- inc_cursor();
- }
+ if (p_ri) {
+ dec_cursor();
+ } else {
+ inc_cursor();
+ }
- put_curr_and_l_to_X((char_u)tempc);
- break;
- }
+ put_curr_and_l_to_X((char_u)tempc);
+ break;
+ }
- if (!p_ri) {
- inc_cursor();
+ if (!p_ri) {
+ inc_cursor();
+ }
}
tempc = 0;
@@ -1072,7 +1081,7 @@ int fkmap(int c)
if (gchar_cursor() == _LAM) {
chg_l_toXor_X();
- del_char(FALSE);
+ del_char(false);
AppendCharToRedobuff(K_BS);
if (!p_ri) {
@@ -1558,7 +1567,7 @@ static char_u toF_ending(char_u c)
}
/// Convert the Farsi 3342 standard into Farsi VIM.
-void conv_to_pvim(void)
+static void conv_to_pvim(void)
{
char_u *ptr;
int lnum, llen, i;
@@ -1571,7 +1580,7 @@ void conv_to_pvim(void)
ptr[i] = toF_leading(ptr[i]);
i++;
- while (canF_Rjoin(ptr[i]) && i < llen) {
+ while (i < llen && canF_Rjoin(ptr[i])) {
ptr[i] = toF_Rjoin(ptr[i]);
if (F_isterm(ptr[i]) || !F_isalpha(ptr[i])) {
break;
@@ -1589,23 +1598,23 @@ void conv_to_pvim(void)
}
// Following lines contains Farsi encoded character.
- do_cmdline_cmd("%s/\202\231/\232/g");
- do_cmdline_cmd("%s/\201\231/\370\334/g");
+ do_cmdline_cmd("%s/\202\231/\232/ge");
+ do_cmdline_cmd("%s/\201\231/\370\334/ge");
// Assume the screen has been messed up: clear it and redraw.
- redraw_later(CLEAR);
- MSG_ATTR(farsi_text_1, hl_attr(HLF_S));
+ redraw_later(NOT_VALID);
+ MSG_ATTR((const char *)farsi_text_1, HL_ATTR(HLF_S));
}
/// Convert the Farsi VIM into Farsi 3342 standard.
-void conv_to_pstd(void)
+static void conv_to_pstd(void)
{
char_u *ptr;
int lnum, llen, i;
// Following line contains Farsi encoded character.
- do_cmdline_cmd("%s/\232/\202\231/g");
- for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) {
+ do_cmdline_cmd("%s/\232/\202\231/ge");
+ for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; lnum++) {
ptr = ml_get((linenr_T)lnum);
llen = (int)STRLEN(ptr);
for (i = 0; i < llen; i++) {
@@ -1614,8 +1623,8 @@ void conv_to_pstd(void)
}
// Assume the screen has been messed up: clear it and redraw.
- redraw_later(CLEAR);
- MSG_ATTR(farsi_text_2, hl_attr(HLF_S));
+ redraw_later(NOT_VALID);
+ msg_attr((const char *)farsi_text_2, HL_ATTR(HLF_S));
}
/// left-right swap the characters in buf[len].
@@ -2037,34 +2046,31 @@ bool F_ischar(int c)
return c >= TEE_ && c <= YE_;
}
-void farsi_fkey(cmdarg_T *cap)
+void farsi_f8(cmdarg_T *cap FUNC_ATTR_UNUSED)
{
- int c = cap->cmdchar;
-
- if (c == K_F8) {
- if (p_altkeymap) {
- if (curwin->w_farsi & W_R_L) {
- p_fkmap = 0;
- do_cmdline_cmd("set norl");
- MSG("");
- } else {
- p_fkmap = 1;
- do_cmdline_cmd("set rl");
- MSG("");
- }
-
- curwin->w_farsi = curwin->w_farsi ^ W_R_L;
+ if (p_altkeymap) {
+ if (curwin->w_farsi & W_R_L) {
+ p_fkmap = 0;
+ do_cmdline_cmd("set norl");
+ MSG("");
+ } else {
+ p_fkmap = 1;
+ do_cmdline_cmd("set rl");
+ MSG("");
}
+
+ curwin->w_farsi = curwin->w_farsi ^ W_R_L;
}
+}
- if (c == K_F9) {
- if (p_altkeymap && curwin->w_p_rl) {
- curwin->w_farsi = curwin->w_farsi ^ W_CONV;
- if (curwin->w_farsi & W_CONV) {
- conv_to_pvim();
- } else {
- conv_to_pstd();
- }
+void farsi_f9(cmdarg_T *cap FUNC_ATTR_UNUSED)
+{
+ if (p_altkeymap && curwin->w_p_rl) {
+ curwin->w_farsi = curwin->w_farsi ^ W_CONV;
+ if (curwin->w_farsi & W_CONV) {
+ conv_to_pvim();
+ } else {
+ conv_to_pstd();
}
}
}
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 78b224f04c..ee775bab4a 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -1,48 +1,47 @@
-/* TODO: make some #ifdef for this */
-/*--------[ file searching ]-------------------------------------------------*/
-/*
- * File searching functions for 'path', 'tags' and 'cdpath' options.
- * External visible functions:
- * vim_findfile_init() creates/initialises the search context
- * vim_findfile_free_visited() free list of visited files/dirs of search
- * context
- * vim_findfile() find a file in the search context
- * vim_findfile_cleanup() cleanup/free search context created by
- * vim_findfile_init()
- *
- * All static functions and variables start with 'ff_'
- *
- * In general it works like this:
- * First you create yourself a search context by calling vim_findfile_init().
- * It is possible to give a search context from a previous call to
- * vim_findfile_init(), so it can be reused. After this you call vim_findfile()
- * until you are satisfied with the result or it returns NULL. On every call it
- * returns the next file which matches the conditions given to
- * vim_findfile_init(). If it doesn't find a next file it returns NULL.
- *
- * It is possible to call vim_findfile_init() again to reinitialise your search
- * with some new parameters. Don't forget to pass your old search context to
- * it, so it can reuse it and especially reuse the list of already visited
- * directories. If you want to delete the list of already visited directories
- * simply call vim_findfile_free_visited().
- *
- * When you are done call vim_findfile_cleanup() to free the search context.
- *
- * The function vim_findfile_init() has a long comment, which describes the
- * needed parameters.
- *
- *
- *
- * ATTENTION:
- * ==========
- * Also we use an allocated search context here, this functions are NOT
- * thread-safe!!!!!
- *
- * To minimize parameter passing (or because I'm to lazy), only the
- * external visible functions get a search context as a parameter. This is
- * then assigned to a static global, which is used throughout the local
- * functions.
- */
+// 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
+
+// File searching functions for 'path', 'tags' and 'cdpath' options.
+//
+// External visible functions:
+// vim_findfile_init() creates/initialises the search context
+// vim_findfile_free_visited() free list of visited files/dirs of search
+// context
+// vim_findfile() find a file in the search context
+// vim_findfile_cleanup() cleanup/free search context created by
+// vim_findfile_init()
+//
+// All static functions and variables start with 'ff_'
+//
+// In general it works like this:
+// First you create yourself a search context by calling vim_findfile_init().
+// It is possible to give a search context from a previous call to
+// vim_findfile_init(), so it can be reused. After this you call vim_findfile()
+// until you are satisfied with the result or it returns NULL. On every call it
+// returns the next file which matches the conditions given to
+// vim_findfile_init(). If it doesn't find a next file it returns NULL.
+//
+// It is possible to call vim_findfile_init() again to reinitialise your search
+// with some new parameters. Don't forget to pass your old search context to
+// it, so it can reuse it and especially reuse the list of already visited
+// directories. If you want to delete the list of already visited directories
+// simply call vim_findfile_free_visited().
+//
+// When you are done call vim_findfile_cleanup() to free the search context.
+//
+// The function vim_findfile_init() has a long comment, which describes the
+// needed parameters.
+//
+//
+//
+// ATTENTION:
+// ==========
+// We use an allocated search context, these functions are NOT thread-safe!!!!!
+//
+// To minimize parameter passing (or because I'm too lazy), only the
+// external visible functions get a search context as a parameter. This is
+// then assigned to a static global, which is used throughout the local
+// functions.
#include <assert.h>
#include <string.h>
@@ -52,6 +51,7 @@
#include <limits.h>
#include "nvim/vim.h"
+#include "nvim/eval.h"
#include "nvim/ascii.h"
#include "nvim/file_search.h"
#include "nvim/charset.h"
@@ -59,7 +59,7 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
+#include "nvim/option.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
#include "nvim/strings.h"
@@ -196,7 +196,6 @@ typedef struct ff_search_ctx_T {
static char_u e_pathtoolong[] = N_("E854: path too long for completion");
-
/*
* Initialization routine for vim_findfile().
*
@@ -326,8 +325,11 @@ vim_findfile_init (
drive[0] = path[0];
drive[1] = ':';
drive[2] = NUL;
- if (vim_FullName(drive, ff_expand_buffer, MAXPATHL, TRUE) == FAIL)
+ if (vim_FullName((const char *)drive, (char *)ff_expand_buffer, MAXPATHL,
+ true)
+ == FAIL) {
goto error_return;
+ }
path += 2;
} else
#endif
@@ -575,7 +577,7 @@ char_u *vim_findfile(void *search_ctx_arg)
char_u *file_path;
char_u *rest_of_wildcards;
char_u *path_end = NULL;
- ff_stack_T *stackp;
+ ff_stack_T *stackp = NULL;
size_t len;
char_u *p;
char_u *suf;
@@ -640,9 +642,8 @@ char_u *vim_findfile(void *search_ctx_arg)
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("Already Searched: %s (%s)",
- stackp->ffs_fix_path, stackp->ffs_wc_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ stackp->ffs_fix_path, stackp->ffs_wc_path);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -654,8 +655,7 @@ char_u *vim_findfile(void *search_ctx_arg)
verbose_enter_scroll();
smsg("Searching: %s (%s)",
stackp->ffs_fix_path, stackp->ffs_wc_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -683,28 +683,40 @@ char_u *vim_findfile(void *search_ctx_arg)
dirptrs[0] = file_path;
dirptrs[1] = NULL;
- /* if we have a start dir copy it in */
+ // if we have a start dir copy it in
if (!vim_isAbsName(stackp->ffs_fix_path)
&& search_ctx->ffsc_start_dir) {
+ if (STRLEN(search_ctx->ffsc_start_dir) + 1 >= MAXPATHL) {
+ goto fail;
+ }
STRCPY(file_path, search_ctx->ffsc_start_dir);
- add_pathsep((char *)file_path);
+ if (!add_pathsep((char *)file_path)) {
+ goto fail;
+ }
}
- /* append the fix part of the search path */
+ // append the fix part of the search path
+ if (STRLEN(file_path) + STRLEN(stackp->ffs_fix_path) + 1 >= MAXPATHL) {
+ goto fail;
+ }
STRCAT(file_path, stackp->ffs_fix_path);
- add_pathsep((char *)file_path);
+ if (!add_pathsep((char *)file_path)) {
+ goto fail;
+ }
rest_of_wildcards = stackp->ffs_wc_path;
if (*rest_of_wildcards != NUL) {
len = STRLEN(file_path);
if (STRNCMP(rest_of_wildcards, "**", 2) == 0) {
- /* pointer to the restrict byte
- * The restrict byte is not a character!
- */
+ // pointer to the restrict byte
+ // The restrict byte is not a character!
p = rest_of_wildcards + 2;
if (*p > 0) {
(*p)--;
+ if (len + 1 >= MAXPATHL) {
+ goto fail;
+ }
file_path[len++] = '*';
}
@@ -729,8 +741,12 @@ char_u *vim_findfile(void *search_ctx_arg)
* on the stack again for further search.
*/
while (*rest_of_wildcards
- && !vim_ispathsep(*rest_of_wildcards))
+ && !vim_ispathsep(*rest_of_wildcards)) {
+ if (len + 1 >= MAXPATHL) {
+ goto fail;
+ }
file_path[len++] = *rest_of_wildcards++;
+ }
file_path[len] = NUL;
if (vim_ispathsep(*rest_of_wildcards))
@@ -773,10 +789,15 @@ char_u *vim_findfile(void *search_ctx_arg)
&& !os_isdir(stackp->ffs_filearray[i]))
continue; /* not a directory */
- /* prepare the filename to be checked for existence
- * below */
+ // prepare the filename to be checked for existence below
+ if (STRLEN(stackp->ffs_filearray[i]) + 1
+ + STRLEN(search_ctx->ffsc_file_to_search) >= MAXPATHL) {
+ goto fail;
+ }
STRCPY(file_path, stackp->ffs_filearray[i]);
- add_pathsep((char *)file_path);
+ if (!add_pathsep((char *)file_path)) {
+ goto fail;
+ }
STRCAT(file_path, search_ctx->ffsc_file_to_search);
/*
@@ -813,10 +834,8 @@ char_u *vim_findfile(void *search_ctx_arg)
) == FAIL) {
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("Already: %s",
- file_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ smsg("Already: %s", file_path);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
continue;
@@ -841,8 +860,7 @@ char_u *vim_findfile(void *search_ctx_arg)
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("HIT: %s", file_path);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -927,8 +945,14 @@ char_u *vim_findfile(void *search_ctx_arg)
if (*search_ctx->ffsc_start_dir == 0)
break;
+ if (STRLEN(search_ctx->ffsc_start_dir) + 1
+ + STRLEN(search_ctx->ffsc_fix_path) >= MAXPATHL) {
+ goto fail;
+ }
STRCPY(file_path, search_ctx->ffsc_start_dir);
- add_pathsep((char *)file_path);
+ if (!add_pathsep((char *)file_path)) {
+ goto fail;
+ }
STRCAT(file_path, search_ctx->ffsc_fix_path);
/* create a new stack entry */
@@ -939,6 +963,8 @@ char_u *vim_findfile(void *search_ctx_arg)
break;
}
+fail:
+ ff_free_stack_element(stackp);
xfree(file_path);
return NULL;
}
@@ -1003,10 +1029,8 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l
#ifdef FF_VERBOSE
if (p_verbose >= 5) {
verbose_enter_scroll();
- smsg("ff_get_visited_list: FOUND list for %s",
- filename);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ smsg("ff_get_visited_list: FOUND list for %s", filename);
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -1020,8 +1044,7 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l
if (p_verbose >= 5) {
verbose_enter_scroll();
smsg("ff_get_visited_list: new list for %s", filename);
- /* don't overwrite this either */
- msg_puts((char_u *)"\n");
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
#endif
@@ -1066,7 +1089,7 @@ static bool ff_wc_equal(char_u *s1, char_u *s2)
c1 = PTR2CHAR(s1 + i);
c2 = PTR2CHAR(s2 + j);
- if ((p_fic ? vim_tolower(c1) != vim_tolower(c2) : c1 != c2)
+ if ((p_fic ? mb_tolower(c1) != mb_tolower(c2) : c1 != c2)
&& (prev1 != '*' || prev2 != '*')) {
return false;
}
@@ -1153,7 +1176,7 @@ static ff_stack_T *ff_create_stack_element(char_u *fix_part, char_u *wc_part, in
new->ffs_filearray_cur = 0;
new->ffs_stage = 0;
new->ffs_level = level;
- new->ffs_star_star_empty = star_star_empty;;
+ new->ffs_star_star_empty = star_star_empty;
/* the following saves NULL pointer checks in vim_findfile */
if (fix_part == NULL)
@@ -1198,14 +1221,19 @@ static ff_stack_T *ff_pop(ff_search_ctx_T *search_ctx)
/*
* free the given stack element
*/
-static void ff_free_stack_element(ff_stack_T *stack_ptr)
+static void ff_free_stack_element(ff_stack_T *const stack_ptr)
{
- /* free handles possible NULL pointers */
+ if (stack_ptr == NULL) {
+ return;
+ }
+
+ // free handles possible NULL pointers
xfree(stack_ptr->ffs_fix_path);
xfree(stack_ptr->ffs_wc_path);
- if (stack_ptr->ffs_filearray != NULL)
+ if (stack_ptr->ffs_filearray != NULL) {
FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray);
+ }
xfree(stack_ptr);
}
@@ -1374,6 +1402,11 @@ find_file_in_path_option (
char_u *buf = NULL;
int rel_to_curdir;
+ if (rel_fname != NULL && path_with_url((const char *)rel_fname)) {
+ // Do not attempt to search "relative" to a URL. #6009
+ rel_fname = NULL;
+ }
+
if (first == TRUE) {
/* copy file name into NameBuff, expanding environment variables */
save_char = ptr[len];
@@ -1526,3 +1559,91 @@ theend:
return file_name;
}
+void do_autocmd_dirchanged(char *new_dir, CdScope scope)
+{
+ static bool recursive = false;
+
+ if (recursive || !has_event(EVENT_DIRCHANGED)) {
+ // No autocommand was defined or we changed
+ // the directory from this autocommand.
+ return;
+ }
+
+ recursive = true;
+
+ dict_T *dict = get_vim_var_dict(VV_EVENT);
+ char buf[8];
+
+ switch (scope) {
+ case kCdScopeGlobal: {
+ snprintf(buf, sizeof(buf), "global");
+ break;
+ }
+ case kCdScopeTab: {
+ snprintf(buf, sizeof(buf), "tab");
+ break;
+ }
+ case kCdScopeWindow: {
+ snprintf(buf, sizeof(buf), "window");
+ break;
+ }
+ case kCdScopeInvalid: {
+ // Should never happen.
+ assert(false);
+ }
+ }
+
+ tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614
+ tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
+ tv_dict_set_keys_readonly(dict);
+
+ apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false,
+ curbuf);
+
+ tv_dict_clear(dict);
+
+ recursive = false;
+}
+
+/// Change to a file's directory.
+/// Caller must call shorten_fnames()!
+/// @return OK or FAIL
+int vim_chdirfile(char_u *fname)
+{
+ char dir[MAXPATHL];
+
+ STRLCPY(dir, fname, MAXPATHL);
+ *path_tail_with_sep((char_u *)dir) = NUL;
+
+ if (os_dirname(NameBuff, sizeof(NameBuff)) != OK) {
+ NameBuff[0] = NUL;
+ }
+
+ if (os_chdir(dir) != 0) {
+ return FAIL;
+ }
+
+#ifdef BACKSLASH_IN_FILENAME
+ slash_adjust((char_u *)dir);
+#endif
+ if (!strequal(dir, (char *)NameBuff)) {
+ do_autocmd_dirchanged(dir, kCdScopeWindow);
+ }
+
+ return OK;
+}
+
+/// Change directory to "new_dir". Search 'cdpath' for relative directory names.
+int vim_chdir(char_u *new_dir, CdScope scope)
+{
+ char_u *dir_name = find_directory_in_path(new_dir, STRLEN(new_dir),
+ FNAME_MESS, curbuf->b_ffname);
+ if (dir_name == NULL) {
+ return -1;
+ }
+
+ int r = os_chdir((char *)dir_name);
+ xfree(dir_name);
+ return r;
+}
+
diff --git a/src/nvim/file_search.h b/src/nvim/file_search.h
index 833a1a05ff..b128029123 100644
--- a/src/nvim/file_search.h
+++ b/src/nvim/file_search.h
@@ -1,6 +1,11 @@
#ifndef NVIM_FILE_SEARCH_H
#define NVIM_FILE_SEARCH_H
+#include <stdlib.h> // for size_t
+
+#include "nvim/types.h" // for char_u
+#include "nvim/globals.h" // for CdScope
+
/* Flags for find_file_*() functions. */
#define FINDFILE_FILE 0 /* only files */
#define FINDFILE_DIR 1 /* only directories */
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 154558b332..ba154ea36a 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1,6 +1,7 @@
-/*
- * fileio.c: read from and write to a file
- */
+// 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
+
+// fileio.c: read from and write to a file
#include <assert.h>
#include <errno.h>
@@ -32,7 +33,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/normal.h"
@@ -44,6 +44,7 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/sha256.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/types.h"
@@ -51,6 +52,7 @@
#include "nvim/window.h"
#include "nvim/shada.h"
#include "nvim/os/os.h"
+#include "nvim/os/os_defs.h"
#include "nvim/os/time.h"
#include "nvim/os/input.h"
@@ -61,57 +63,62 @@
#define BUFSIZE 8192 /* size of normal write buffer */
#define SMBUFSIZE 256 /* size of emergency write buffer */
-/*
- * The autocommands are stored in a list for each event.
- * Autocommands for the same pattern, that are consecutive, are joined
- * together, to avoid having to match the pattern too often.
- * The result is an array of Autopat lists, which point to AutoCmd lists:
- *
- * first_autopat[0] --> Autopat.next --> Autopat.next --> NULL
- * Autopat.cmds Autopat.cmds
- * | |
- * V V
- * AutoCmd.next AutoCmd.next
- * | |
- * V V
- * AutoCmd.next NULL
- * |
- * V
- * NULL
- *
- * first_autopat[1] --> Autopat.next --> NULL
- * Autopat.cmds
- * |
- * V
- * AutoCmd.next
- * |
- * V
- * NULL
- * etc.
- *
- * The order of AutoCmds is important, this is the order in which they were
- * defined and will have to be executed.
- */
+//
+// The autocommands are stored in a list for each event.
+// Autocommands for the same pattern, that are consecutive, are joined
+// together, to avoid having to match the pattern too often.
+// The result is an array of Autopat lists, which point to AutoCmd lists:
+//
+// last_autopat[0] -----------------------------+
+// V
+// first_autopat[0] --> Autopat.next --> Autopat.next --> NULL
+// Autopat.cmds Autopat.cmds
+// | |
+// V V
+// AutoCmd.next AutoCmd.next
+// | |
+// V V
+// AutoCmd.next NULL
+// |
+// V
+// NULL
+//
+// last_autopat[1] --------+
+// V
+// first_autopat[1] --> Autopat.next --> NULL
+// Autopat.cmds
+// |
+// V
+// AutoCmd.next
+// |
+// V
+// NULL
+// etc.
+//
+// The order of AutoCmds is important, this is the order in which they were
+// defined and will have to be executed.
+//
typedef struct AutoCmd {
- char_u *cmd; /* The command to be executed (NULL
- when command has been removed) */
- char nested; /* If autocommands nest here */
- char last; /* last command in list */
- scid_T scriptID; /* script ID where defined */
- struct AutoCmd *next; /* Next AutoCmd in list */
+ char_u *cmd; // The command to be executed (NULL
+ // when command has been removed)
+ char nested; // If autocommands nest here
+ char last; // last command in list
+ scid_T scriptID; // script ID where defined
+ struct AutoCmd *next; // Next AutoCmd in list
} AutoCmd;
typedef struct AutoPat {
- char_u *pat; /* pattern as typed (NULL when pattern
- has been removed) */
- regprog_T *reg_prog; /* compiled regprog for pattern */
- AutoCmd *cmds; /* list of commands to do */
- struct AutoPat *next; /* next AutoPat in AutoPat list */
- int group; /* group ID */
- int patlen; /* strlen() of pat */
- int buflocal_nr; /* !=0 for buffer-local AutoPat */
- char allow_dirs; /* Pattern may match whole path */
- char last; /* last pattern for apply_autocmds() */
+ struct AutoPat *next; // next AutoPat in AutoPat list; MUST
+ // be the first entry
+ char_u *pat; // pattern as typed (NULL when pattern
+ // has been removed)
+ regprog_T *reg_prog; // compiled regprog for pattern
+ AutoCmd *cmds; // list of commands to do
+ int group; // group ID
+ int patlen; // strlen() of pat
+ int buflocal_nr; // !=0 for buffer-local AutoPat
+ char allow_dirs; // Pattern may match whole path
+ char last; // last pattern for apply_autocmds()
} AutoPat;
/*
@@ -187,22 +194,26 @@ struct bw_info {
static char *e_auchangedbuf = N_(
"E812: Autocommands changed buffer or buffer name");
+// Set by the apply_autocmds_group function if the given event is equal to
+// EVENT_FILETYPE. Used by the readfile function in order to determine if
+// EVENT_BUFREADPOST triggered the EVENT_FILETYPE.
+//
+// Relying on this value requires one to reset it prior calling
+// apply_autocmds_group.
+static bool au_did_filetype INIT(= false);
+
void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
{
int msg_scroll_save;
- if (msg_silent != 0)
+ if (msg_silent != 0) {
return;
- msg_add_fname(buf, name); /* put file name in IObuff with quotes */
- /* If it's extremely long, truncate it. */
- if (STRLEN(IObuff) > IOSIZE - 80)
- IObuff[IOSIZE - 80] = NUL;
- STRCAT(IObuff, s);
- /*
- * For the first message may have to start a new line.
- * For further ones overwrite the previous one, reset msg_scroll before
- * calling filemess().
- */
+ }
+ add_quoted_fname((char *)IObuff, IOSIZE - 80, buf, (const char *)name);
+ xstrlcat((char *)IObuff, (const char *)s, IOSIZE);
+ // For the first message may have to start a new line.
+ // For further ones overwrite the previous one, reset msg_scroll before
+ // calling filemess().
msg_scroll_save = msg_scroll;
if (shortmess(SHM_OVERALL) && !exiting && p_verbose == 0)
msg_scroll = FALSE;
@@ -218,6 +229,15 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
msg_scrolled_ign = FALSE;
}
+static AutoPat *last_autopat[NUM_EVENTS] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
/*
* Read lines from file "fname" into the buffer after line "from".
*
@@ -239,8 +259,9 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
* stdin)
* READ_DUMMY read into a dummy buffer (to check if file contents changed)
* READ_KEEP_UNDO don't clear undo info or read it from a file
+ * READ_FIFO read from fifo/socket instead of a file
*
- * return FAIL for failure, OK otherwise
+ * return FAIL for failure, NOTDONE for directory (failure), or OK
*/
int
readfile (
@@ -249,7 +270,7 @@ readfile (
linenr_T from,
linenr_T lines_to_skip,
linenr_T lines_to_read,
- exarg_T *eap, /* can be NULL! */
+ exarg_T *eap, // can be NULL!
int flags
)
{
@@ -259,6 +280,7 @@ readfile (
int filtering = (flags & READ_FILTER);
int read_stdin = (flags & READ_STDIN);
int read_buffer = (flags & READ_BUFFER);
+ int read_fifo = (flags & READ_FIFO);
int set_options = newfile || read_buffer
|| (eap != NULL && eap->read_edit);
linenr_T read_buf_lnum = 1; /* next line to read from curbuf */
@@ -272,21 +294,18 @@ readfile (
int wasempty; /* buffer was empty before reading */
colnr_T len;
long size = 0;
- char_u *p;
- off_t filesize = 0;
- int skip_read = FALSE;
+ char_u *p = NULL;
+ off_T filesize = 0;
+ int skip_read = false;
context_sha256_T sha_ctx;
- int read_undo_file = FALSE;
- int split = 0; /* number of split lines */
+ int read_undo_file = false;
linenr_T linecnt;
int error = FALSE; /* errors encountered */
int ff_error = EOL_UNKNOWN; /* file format with errors */
long linerest = 0; /* remaining chars in line */
-#ifdef UNIX
int perm = 0;
+#ifdef UNIX
int swap_mode = -1; /* protection bits for swap file */
-#else
- int perm;
#endif
int fileformat = 0; /* end-of-line format */
int keep_fileformat = FALSE;
@@ -294,12 +313,9 @@ readfile (
linenr_T skip_count = 0;
linenr_T read_count = 0;
int msg_save = msg_scroll;
- linenr_T read_no_eol_lnum = 0; /* non-zero lnum when last line of
- * last read was missing the eol */
- int try_mac = (vim_strchr(p_ffs, 'm') != NULL);
- int try_dos = (vim_strchr(p_ffs, 'd') != NULL);
- int try_unix = (vim_strchr(p_ffs, 'x') != NULL);
- int file_rewind = FALSE;
+ linenr_T read_no_eol_lnum = 0; // non-zero lnum when last line of
+ // last read was missing the eol
+ int file_rewind = false;
int can_retry;
linenr_T conv_error = 0; /* line nr with conversion error */
linenr_T illegal_byte = 0; /* line nr with illegal byte */
@@ -331,6 +347,8 @@ readfile (
int using_b_ffname;
int using_b_fname;
+ au_did_filetype = false; // reset before triggering any autocommands
+
curbuf->b_no_eol_lnum = 0; /* in case it was set by the previous read */
/*
@@ -418,32 +436,31 @@ readfile (
}
}
- if (!read_stdin && !read_buffer) {
+ if (!read_buffer && !read_stdin && !read_fifo) {
+ perm = os_getperm((const char *)fname);
#ifdef UNIX
- /*
- * On Unix it is possible to read a directory, so we have to
- * check for it before os_open().
- */
- perm = os_getperm(fname);
- if (perm >= 0 && !S_ISREG(perm) /* not a regular file ... */
+ // On Unix it is possible to read a directory, so we have to
+ // check for it before os_open().
+ if (perm >= 0 && !S_ISREG(perm) // not a regular file ...
# ifdef S_ISFIFO
- && !S_ISFIFO(perm) /* ... or fifo */
+ && !S_ISFIFO(perm) // ... or fifo
# endif
# ifdef S_ISSOCK
- && !S_ISSOCK(perm) /* ... or socket */
+ && !S_ISSOCK(perm) // ... or socket
# endif
# ifdef OPEN_CHR_FILES
&& !(S_ISCHR(perm) && is_dev_fd_file(fname))
- /* ... or a character special file named /dev/fd/<n> */
+ // ... or a character special file named /dev/fd/<n>
# endif
) {
- if (S_ISDIR(perm))
+ if (S_ISDIR(perm)) {
filemess(curbuf, fname, (char_u *)_("is a directory"), 0);
- else
+ } else {
filemess(curbuf, fname, (char_u *)_("is not a file"), 0);
+ }
msg_end();
msg_scroll = msg_save;
- return FAIL;
+ return S_ISDIR(perm) ? NOTDONE : FAIL;
}
#endif
}
@@ -461,8 +478,8 @@ readfile (
if (check_readonly && !readonlymode)
curbuf->b_p_ro = FALSE;
- if (newfile && !read_stdin && !read_buffer) {
- /* Remember time of file. */
+ if (newfile && !read_stdin && !read_buffer && !read_fifo) {
+ // Remember time of file.
FileInfo file_info;
if (os_fileinfo((char *)fname, &file_info)) {
buf_store_file_info(curbuf, &file_info);
@@ -493,44 +510,31 @@ readfile (
curbuf->b_flags &= ~(BF_NEW | BF_NEW_W);
}
- /*
- * Check readonly by trying to open the file for writing.
- * If this fails, we know that the file is readonly.
- */
- file_readonly = FALSE;
+ // Check readonly.
+ file_readonly = false;
if (!read_buffer && !read_stdin) {
- if (!newfile || readonlymode) {
- file_readonly = TRUE;
- } else if ((fd = os_open((char *)fname, O_RDWR, 0)) < 0) {
- // opening in readwrite mode failed => file is readonly
- file_readonly = TRUE;
- }
- if (file_readonly == TRUE) {
- // try to open readonly
- fd = os_open((char *)fname, O_RDONLY, 0);
+ if (!newfile || readonlymode || !(perm & 0222)
+ || !os_file_is_writable((char *)fname)) {
+ file_readonly = true;
}
+ fd = os_open((char *)fname, O_RDONLY, 0);
}
- if (fd < 0) { /* cannot open at all */
+ if (fd < 0) { // cannot open at all
msg_scroll = msg_save;
#ifndef UNIX
- /*
- * On non-unix systems we can't open a directory, check here.
- */
- perm = os_getperm(fname); /* check if the file exists */
+ // On non-unix systems we can't open a directory, check here.
if (os_isdir(fname)) {
filemess(curbuf, sfname, (char_u *)_("is a directory"), 0);
- curbuf->b_p_ro = TRUE; /* must use "w!" now */
- } else
+ curbuf->b_p_ro = true; // must use "w!" now
+ } else {
#endif
if (!newfile) {
return FAIL;
}
- if (perm == UV_ENOENT) {
- /*
- * Set the 'new-file' flag, so that when the file has
- * been created by someone else, a ":w" will complain.
- */
+ if (perm == UV_ENOENT) { // check if the file exists
+ // Set the 'new-file' flag, so that when the file has
+ // been created by someone else, a ":w" will complain.
curbuf->b_flags |= BF_NEW;
/* Create a swap file now, so that other Vims are warned
@@ -581,6 +585,9 @@ readfile (
return FAIL;
}
+#ifndef UNIX
+ }
+#endif
/*
* Only set the 'ro' flag for readonly files the first time they are
@@ -616,10 +623,12 @@ readfile (
return FAIL;
}
#ifdef UNIX
- /* Set swap file protection bits after creating it. */
+ // Set swap file protection bits after creating it.
if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL
- && curbuf->b_ml.ml_mfp->mf_fname != NULL)
- (void)os_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode);
+ && curbuf->b_ml.ml_mfp->mf_fname != NULL) {
+ (void)os_setperm((const char *)curbuf->b_ml.ml_mfp->mf_fname,
+ (long)swap_mode);
+ }
#endif
}
@@ -638,37 +647,46 @@ readfile (
curbuf->b_op_start.lnum = ((from == 0) ? 1 : from);
curbuf->b_op_start.col = 0;
+ int try_mac = (vim_strchr(p_ffs, 'm') != NULL);
+ int try_dos = (vim_strchr(p_ffs, 'd') != NULL);
+ int try_unix = (vim_strchr(p_ffs, 'x') != NULL);
+
if (!read_buffer) {
int m = msg_scroll;
int n = msg_scrolled;
- /*
- * The file must be closed again, the autocommands may want to change
- * the file before reading it.
- */
- if (!read_stdin)
- close(fd); /* ignore errors */
+ // The file must be closed again, the autocommands may want to change
+ // the file before reading it.
+ if (!read_stdin) {
+ close(fd); // ignore errors
+ }
- /*
- * The output from the autocommands should not overwrite anything and
- * should not be overwritten: Set msg_scroll, restore its value if no
- * output was done.
- */
- msg_scroll = TRUE;
- if (filtering)
+ // The output from the autocommands should not overwrite anything and
+ // should not be overwritten: Set msg_scroll, restore its value if no
+ // output was done.
+ msg_scroll = true;
+ if (filtering) {
apply_autocmds_exarg(EVENT_FILTERREADPRE, NULL, sfname,
- FALSE, curbuf, eap);
- else if (read_stdin)
+ false, curbuf, eap);
+ } else if (read_stdin) {
apply_autocmds_exarg(EVENT_STDINREADPRE, NULL, sfname,
- FALSE, curbuf, eap);
- else if (newfile)
+ false, curbuf, eap);
+ } else if (newfile) {
apply_autocmds_exarg(EVENT_BUFREADPRE, NULL, sfname,
- FALSE, curbuf, eap);
- else
+ false, curbuf, eap);
+ } else {
apply_autocmds_exarg(EVENT_FILEREADPRE, sfname, sfname,
- FALSE, NULL, eap);
- if (msg_scrolled == n)
+ false, NULL, eap);
+ }
+
+ // autocommands may have changed it
+ try_mac = (vim_strchr(p_ffs, 'm') != NULL);
+ try_dos = (vim_strchr(p_ffs, 'd') != NULL);
+ try_unix = (vim_strchr(p_ffs, 'x') != NULL);
+
+ if (msg_scrolled == n) {
msg_scroll = m;
+ }
if (aborting()) { /* autocmds may abort script processing */
--no_wait_return;
@@ -702,16 +720,9 @@ readfile (
wasempty = (curbuf->b_ml.ml_flags & ML_EMPTY);
if (!recoverymode && !filtering && !(flags & READ_DUMMY)) {
- /*
- * Show the user that we are busy reading the input. Sometimes this
- * may take a while. When reading from stdin another program may
- * still be running, don't move the cursor to the last line, unless
- * always using the GUI.
- */
- if (read_stdin) {
- mch_msg(_("Nvim: Reading from stdin...\n"));
- } else if (!read_buffer)
+ if (!read_stdin && !read_buffer) {
filemess(curbuf, sfname, (char_u *)"", 0);
+ }
}
msg_scroll = FALSE; /* overwrite the file message */
@@ -741,43 +752,14 @@ readfile (
fenc = (char_u *)""; /* binary: don't convert */
fenc_alloced = FALSE;
} else if (curbuf->b_help) {
- char_u firstline[80];
- int fc;
-
- /* Help files are either utf-8 or latin1. Try utf-8 first, if this
- * fails it must be latin1.
- * Always do this when 'encoding' is "utf-8". Otherwise only do
- * this when needed to avoid [converted] remarks all the time.
- * It is needed when the first line contains non-ASCII characters.
- * That is only in *.??x files. */
- fenc = (char_u *)"latin1";
- c = enc_utf8;
- if (!c && !read_stdin) {
- fc = fname[STRLEN(fname) - 1];
- if (TOLOWER_ASC(fc) == 'x') {
- /* Read the first line (and a bit more). Immediately rewind to
- * the start of the file. If the read() fails "len" is -1. */
- len = read_eintr(fd, firstline, 80);
- lseek(fd, (off_t)0L, SEEK_SET);
- for (p = firstline; p < firstline + len; ++p)
- if (*p >= 0x80) {
- c = TRUE;
- break;
- }
- }
- }
-
- if (c) {
- fenc_next = fenc;
- fenc = (char_u *)"utf-8";
-
- /* When the file is utf-8 but a character doesn't fit in
- * 'encoding' don't retry. In help text editing utf-8 bytes
- * doesn't make sense. */
- if (!enc_utf8)
- keep_dest_enc = TRUE;
- }
- fenc_alloced = FALSE;
+ // Help files are either utf-8 or latin1. Try utf-8 first, if this
+ // fails it must be latin1.
+ // It is needed when the first line contains non-ASCII characters.
+ // That is only in *.??x files.
+ fenc_next = (char_u *)"latin1";
+ fenc = (char_u *)"utf-8";
+
+ fenc_alloced = false;
} else if (*p_fencs == NUL) {
fenc = curbuf->b_p_fenc; /* use format from buffer */
fenc_alloced = FALSE;
@@ -812,9 +794,9 @@ retry:
if (read_buffer) {
read_buf_lnum = 1;
read_buf_col = 0;
- } else if (read_stdin || lseek(fd, (off_t)0L, SEEK_SET) != 0) {
- /* Can't rewind the file, give up. */
- error = TRUE;
+ } else if (read_stdin || vim_lseek(fd, (off_T)0L, SEEK_SET) != 0) {
+ // Can't rewind the file, give up.
+ error = true;
goto failed;
}
/* Delete the previously read lines. */
@@ -930,6 +912,7 @@ retry:
* and we can't do it internally or with iconv().
*/
if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
+ && !read_fifo
# ifdef USE_ICONV
&& iconv_fd == (iconv_t)-1
# endif
@@ -970,7 +953,7 @@ retry:
/* Set "can_retry" when it's possible to rewind the file and try with
* another "fenc" value. It's FALSE when no other "fenc" to try, reading
* stdin or fixed at a specific encoding. */
- can_retry = (*fenc != NUL && !read_stdin && !keep_dest_enc);
+ can_retry = (*fenc != NUL && !read_stdin && !keep_dest_enc && !read_fifo);
if (!skip_read) {
linerest = 0;
@@ -982,6 +965,7 @@ retry:
&& curbuf->b_ffname != NULL
&& curbuf->b_p_udf
&& !filtering
+ && !read_fifo
&& !read_stdin
&& !read_buffer);
if (read_undo_file)
@@ -1042,8 +1026,8 @@ retry:
size = size / ICONV_MULT; /* worst case */
if (conv_restlen > 0) {
- /* Insert unconverted bytes from previous line. */
- memmove(ptr, conv_rest, conv_restlen);
+ // Insert unconverted bytes from previous line.
+ memmove(ptr, conv_rest, conv_restlen); // -V614
ptr += conv_restlen;
size -= conv_restlen;
}
@@ -1394,15 +1378,15 @@ retry:
}
} else if (fio_flags & FIO_UCS4) {
if (fio_flags & FIO_ENDIAN_L) {
- u8c = (*--p << 24);
- u8c += (*--p << 16);
- u8c += (*--p << 8);
+ u8c = (unsigned)(*--p) << 24;
+ u8c += (unsigned)(*--p) << 16;
+ u8c += (unsigned)(*--p) << 8;
u8c += *--p;
} else { /* big endian */
u8c = *--p;
- u8c += (*--p << 8);
- u8c += (*--p << 16);
- u8c += (*--p << 24);
+ u8c += (unsigned)(*--p) << 8;
+ u8c += (unsigned)(*--p) << 16;
+ u8c += (unsigned)(*--p) << 24;
}
} else { /* UTF-8 */
if (*--p < 0x80)
@@ -1647,21 +1631,19 @@ rewind_retry:
*ptr = NUL; /* end of line */
len = (colnr_T)(ptr - line_start + 1);
if (fileformat == EOL_DOS) {
- if (ptr[-1] == CAR) { /* remove CR */
+ if (ptr > line_start && ptr[-1] == CAR) {
+ // remove CR before NL
ptr[-1] = NUL;
- --len;
- }
- /*
- * Reading in Dos format, but no CR-LF found!
- * When 'fileformats' includes "unix", delete all
- * the lines read so far and start all over again.
- * Otherwise give an error message later.
- */
- else if (ff_error != EOL_DOS) {
- if ( try_unix
- && !read_stdin
- && (read_buffer
- || lseek(fd, (off_t)0L, SEEK_SET) == 0)) {
+ len--;
+ } else if (ff_error != EOL_DOS) {
+ // Reading in Dos format, but no CR-LF found!
+ // When 'fileformats' includes "unix", delete all
+ // the lines read so far and start all over again.
+ // Otherwise give an error message later.
+ if (try_unix
+ && !read_stdin
+ && (read_buffer
+ || vim_lseek(fd, (off_T)0L, SEEK_SET) == 0)) {
fileformat = EOL_UNIX;
if (set_options)
set_fileformat(EOL_UNIX, OPT_LOCAL);
@@ -1744,22 +1726,25 @@ failed:
}
# endif
- if (!read_buffer && !read_stdin)
- close(fd); /* errors are ignored */
-#ifdef HAVE_FD_CLOEXEC
- else {
- int fdflags = fcntl(fd, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
- (void)fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC);
- }
+ if (!read_buffer && !read_stdin) {
+ close(fd); // errors are ignored
+ } else {
+ (void)os_set_cloexec(fd);
}
-#endif
xfree(buffer);
if (read_stdin) {
- /* Use stderr for stdin, makes shell commands work. */
close(0);
- ignored = dup(2);
+#ifndef WIN32
+ // On Unix, use stderr for stdin, makes shell commands work.
+ vim_ignored = dup(2);
+#else
+ // On Windows, use the console input handle for stdin.
+ HANDLE conin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING, 0, (HANDLE)NULL);
+ vim_ignored = _open_osfhandle(conin, _O_RDONLY);
+#endif
}
if (tmpname != NULL) {
@@ -1812,8 +1797,8 @@ failed:
}
if (!filtering && !(flags & READ_DUMMY)) {
- msg_add_fname(curbuf, sfname); /* fname in IObuff with quotes */
- c = FALSE;
+ add_quoted_fname((char *)IObuff, IOSIZE, curbuf, (const char *)sfname);
+ c = false;
#ifdef UNIX
# ifdef S_ISFIFO
@@ -1854,10 +1839,6 @@ failed:
STRCAT(IObuff, _("[CR missing]"));
c = TRUE;
}
- if (split) {
- STRCAT(IObuff, _("[long lines split]"));
- c = TRUE;
- }
if (notconverted) {
STRCAT(IObuff, _("[NOT converted]"));
c = TRUE;
@@ -1884,17 +1865,22 @@ failed:
xfree(keep_msg);
keep_msg = NULL;
+ p = NULL;
msg_scrolled_ign = TRUE;
- p = msg_trunc_attr(IObuff, FALSE, 0);
+
+ if (!read_stdin && !read_buffer) {
+ p = msg_trunc_attr(IObuff, FALSE, 0);
+ }
+
if (read_stdin || read_buffer || restart_edit != 0
- || (msg_scrolled != 0 && !need_wait_return))
- /* Need to repeat the message after redrawing when:
- * - When reading from stdin (the screen will be cleared next).
- * - When restart_edit is set (otherwise there will be a delay
- * before redrawing).
- * - When the screen was scrolled but there is no wait-return
- * prompt. */
+ || (msg_scrolled != 0 && !need_wait_return)) {
+ // Need to repeat the message after redrawing when:
+ // - When reading from stdin (the screen will be cleared next).
+ // - When restart_edit is set (otherwise there will be a delay before
+ // redrawing).
+ // - When the screen was scrolled but there is no wait-return prompt.
set_keep_msg(p, 0);
+ }
msg_scrolled_ign = FALSE;
}
@@ -1957,7 +1943,7 @@ failed:
u_read_undo(NULL, hash, fname);
}
- if (!read_stdin && !read_buffer) {
+ if (!read_stdin && !read_fifo && (!read_buffer || sfname != NULL)) {
int m = msg_scroll;
int n = msg_scrolled;
@@ -1971,20 +1957,29 @@ failed:
* should not be overwritten: Set msg_scroll, restore its value if no
* output was done.
*/
- msg_scroll = TRUE;
- if (filtering)
+ msg_scroll = true;
+ if (filtering) {
apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
- FALSE, curbuf, eap);
- else if (newfile)
+ false, curbuf, eap);
+ } else if (newfile || (read_buffer && sfname != NULL)) {
apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
- FALSE, curbuf, eap);
- else
+ false, curbuf, eap);
+ if (!au_did_filetype && *curbuf->b_p_ft != NUL) {
+ // EVENT_FILETYPE was not triggered but the buffer already has a
+ // filetype. Trigger EVENT_FILETYPE using the existing filetype.
+ apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, curbuf->b_fname,
+ true, curbuf);
+ }
+ } else {
apply_autocmds_exarg(EVENT_FILEREADPOST, sfname, sfname,
- FALSE, NULL, eap);
- if (msg_scrolled == n)
+ false, NULL, eap);
+ }
+ if (msg_scrolled == n) {
msg_scroll = m;
- if (aborting()) /* autocmds may abort script processing */
+ }
+ if (aborting()) { // autocmds may abort script processing
return FAIL;
+ }
}
if (recoverymode && error)
@@ -1999,7 +1994,7 @@ failed:
/// Do not accept "/dev/fd/[012]", opening these may hang Vim.
///
/// @param fname file name to check
-static bool is_dev_fd_file(char_u *fname)
+bool is_dev_fd_file(char_u *fname)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
return STRNCMP(fname, "/dev/fd/", 8) == 0
@@ -2256,22 +2251,30 @@ buf_write (
int len;
linenr_T lnum;
long nchars;
- char_u *errmsg = NULL;
- int errmsg_allocated = FALSE;
- char_u *errnum = NULL;
+#define SET_ERRMSG_NUM(num, msg) \
+ errnum = num, errmsg = msg, errmsgarg = 0
+#define SET_ERRMSG_ARG(msg, error) \
+ errnum = NULL, errmsg = msg, errmsgarg = error
+#define SET_ERRMSG(msg) \
+ errnum = NULL, errmsg = msg, errmsgarg = 0
+ const char *errnum = NULL;
+ char *errmsg = NULL;
+ int errmsgarg = 0;
+ bool errmsg_allocated = false;
char_u *buffer;
char_u smallbuf[SMBUFSIZE];
char_u *backup_ext;
int bufsize;
- long perm; /* file permissions */
+ long perm; // file permissions
int retval = OK;
- int newfile = FALSE; /* TRUE if file doesn't exist yet */
+ int newfile = false; // TRUE if file doesn't exist yet
int msg_save = msg_scroll;
- int overwriting; /* TRUE if writing over original */
- int no_eol = FALSE; /* no end-of-line written */
- int device = FALSE; /* writing to a device */
+ int overwriting; // TRUE if writing over original
+ int no_eol = false; // no end-of-line written
+ int device = false; // writing to a device
int prev_got_int = got_int;
- bool file_readonly = false; /* overwritten file is read-only */
+ int checking_conversion;
+ bool file_readonly = false; // overwritten file is read-only
static char *err_readonly =
"is read-only (cannot override: \"W\" in 'cpoptions')";
#if defined(UNIX)
@@ -2280,7 +2283,6 @@ buf_write (
/* writing everything */
int whole = (start == 1 && end == buf->b_ml.ml_line_count);
linenr_T old_line_count = buf->b_ml.ml_line_count;
- int attr;
int fileformat;
int write_bin;
struct bw_info write_info; /* info for buf_write_bytes() */
@@ -2390,6 +2392,7 @@ buf_write (
int did_cmd = FALSE;
int nofile_err = FALSE;
int empty_memline = (buf->b_ml.ml_mfp == NULL);
+ bufref_T bufref;
/*
* Apply PRE autocommands.
@@ -2405,8 +2408,9 @@ buf_write (
if (fname == buf->b_sfname)
buf_fname_s = TRUE;
- /* set curwin/curbuf to buf and save a few things */
+ // Set curwin/curbuf to buf and save a few things.
aucmd_prepbuf(&aco, buf);
+ set_bufref(&bufref, buf);
if (append) {
if (!(did_cmd = apply_autocmds_exarg(EVENT_FILEAPPENDCMD,
@@ -2454,14 +2458,13 @@ buf_write (
/* restore curwin/curbuf and a few other things */
aucmd_restbuf(&aco);
- /*
- * In three situations we return here and don't write the file:
- * 1. the autocommands deleted or unloaded the buffer.
- * 2. The autocommands abort script processing.
- * 3. If one of the "Cmd" autocommands was executed.
- */
- if (!buf_valid(buf))
+ // In three situations we return here and don't write the file:
+ // 1. the autocommands deleted or unloaded the buffer.
+ // 2. The autocommands abort script processing.
+ // 3. If one of the "Cmd" autocommands was executed.
+ if (!bufref_valid(&bufref)) {
buf = NULL;
+ }
if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline)
|| did_cmd || nofile_err
|| aborting()
@@ -2574,13 +2577,11 @@ buf_write (
perm = file_info_old.stat.st_mode;
if (!S_ISREG(file_info_old.stat.st_mode)) { /* not a file */
if (S_ISDIR(file_info_old.stat.st_mode)) {
- errnum = (char_u *)"E502: ";
- errmsg = (char_u *)_("is a directory");
+ SET_ERRMSG_NUM("E502", _("is a directory"));
goto fail;
}
if (os_nodetype((char *)fname) != NODE_WRITABLE) {
- errnum = (char_u *)"E503: ";
- errmsg = (char_u *)_("is not a file or writable device");
+ SET_ERRMSG_NUM("E503", _("is not a file or writable device"));
goto fail;
}
/* It's a device of some kind (or a fifo) which we can write to
@@ -2590,14 +2591,11 @@ buf_write (
perm = -1;
}
}
-#else /* win32 */
- /*
- * Check for a writable device name.
- */
- c = os_nodetype((char *)fname);
+#else // win32
+ // Check for a writable device name.
+ c = fname == NULL ? NODE_OTHER : os_nodetype((char *)fname);
if (c == NODE_OTHER) {
- errnum = (char_u *)"E503: ";
- errmsg = (char_u *)_("is not a file or writable device");
+ SET_ERRMSG_NUM("E503", _("is not a file or writable device"));
goto fail;
}
if (c == NODE_WRITABLE) {
@@ -2605,20 +2603,18 @@ buf_write (
newfile = TRUE;
perm = -1;
} else {
- perm = os_getperm(fname);
- if (perm < 0)
- newfile = TRUE;
- else if (os_isdir(fname)) {
- errnum = (char_u *)"E502: ";
- errmsg = (char_u *)_("is a directory");
+ perm = os_getperm((const char *)fname);
+ if (perm < 0) {
+ newfile = true;
+ } else if (os_isdir(fname)) {
+ SET_ERRMSG_NUM("E502", _("is a directory"));
goto fail;
}
if (overwriting) {
os_fileinfo((char *)fname, &file_info_old);
}
-
}
-#endif /* !UNIX */
+#endif // !UNIX
if (!device && !newfile) {
/*
@@ -2629,11 +2625,9 @@ buf_write (
if (!forceit && file_readonly) {
if (vim_strchr(p_cpo, CPO_FWRITE) != NULL) {
- errnum = (char_u *)"E504: ";
- errmsg = (char_u *)_(err_readonly);
+ SET_ERRMSG_NUM("E504", _(err_readonly));
} else {
- errnum = (char_u *)"E505: ";
- errmsg = (char_u *)_("is read-only (add ! to override)");
+ SET_ERRMSG_NUM("E505", _("is read-only (add ! to override)"));
}
goto fail;
}
@@ -2869,9 +2863,9 @@ buf_write (
xfree(backup);
backup = NULL;
} else {
- /* set file protection same as original file, but
- * strip s-bit */
- (void)os_setperm(backup, perm & 0777);
+ // set file protection same as original file, but
+ // strip s-bit.
+ (void)os_setperm((const char *)backup, perm & 0777);
#ifdef UNIX
/*
@@ -2882,7 +2876,8 @@ buf_write (
*/
if (file_info_new.stat.st_gid != file_info_old.stat.st_gid
&& os_fchown(bfd, -1, file_info_old.stat.st_gid) != 0) {
- os_setperm(backup, (perm & 0707) | ((perm & 07) << 3));
+ os_setperm((const char *)backup,
+ (perm & 0707) | ((perm & 07) << 3));
}
# ifdef HAVE_SELINUX
mch_copy_sec(fname, backup);
@@ -2900,23 +2895,27 @@ buf_write (
while ((write_info.bw_len = read_eintr(fd, copybuf,
BUFSIZE)) > 0) {
if (buf_write_bytes(&write_info) == FAIL) {
- errmsg = (char_u *)_(
- "E506: Can't write to backup file (add ! to override)");
+ SET_ERRMSG(_(
+ "E506: Can't write to backup file (add ! to override)"));
break;
}
os_breakcheck();
if (got_int) {
- errmsg = (char_u *)_(e_interr);
+ SET_ERRMSG(_(e_interr));
break;
}
}
- if (close(bfd) < 0 && errmsg == NULL)
- errmsg = (char_u *)_(
- "E507: Close error for backup file (add ! to override)");
- if (write_info.bw_len < 0)
- errmsg = (char_u *)_(
- "E508: Can't read file for backup (add ! to override)");
+ int error;
+ if ((error = os_close(bfd)) != 0 && errmsg == NULL) {
+ SET_ERRMSG_ARG(_("E507: Close error for backup file "
+ "(add ! to override): %s"),
+ error);
+ }
+ if (write_info.bw_len < 0) {
+ SET_ERRMSG(_(
+ "E508: Can't read file for backup (add ! to override)"));
+ }
#ifdef UNIX
set_file_time(backup,
file_info_old.stat.st_atim.tv_sec,
@@ -2933,18 +2932,19 @@ buf_write (
}
}
nobackup:
- close(fd); /* ignore errors for closing read file */
+ os_close(fd); // Ignore errors for closing read file.
xfree(copybuf);
- if (backup == NULL && errmsg == NULL)
- errmsg = (char_u *)_(
- "E509: Cannot create backup file (add ! to override)");
- /* ignore errors when forceit is TRUE */
+ if (backup == NULL && errmsg == NULL) {
+ SET_ERRMSG(_(
+ "E509: Cannot create backup file (add ! to override)"));
+ }
+ // Ignore errors when forceit is TRUE.
if ((some_error || errmsg != NULL) && !forceit) {
retval = FAIL;
goto fail;
}
- errmsg = NULL;
+ SET_ERRMSG(NULL);
} else {
char_u *dirp;
char_u *p;
@@ -2959,8 +2959,7 @@ nobackup:
* anyway, thus we need an extra check here.
*/
if (file_readonly && vim_strchr(p_cpo, CPO_FWRITE) != NULL) {
- errnum = (char_u *)"E504: ";
- errmsg = (char_u *)_(err_readonly);
+ SET_ERRMSG_NUM("E504", _(err_readonly));
goto fail;
}
@@ -3024,7 +3023,7 @@ nobackup:
}
}
if (backup == NULL && !forceit) {
- errmsg = (char_u *)_("E510: Can't make backup file (add ! to override)");
+ SET_ERRMSG(_("E510: Can't make backup file (add ! to override)"));
goto fail;
}
}
@@ -3036,8 +3035,8 @@ nobackup:
&& file_info_old.stat.st_uid == getuid()
&& vim_strchr(p_cpo, CPO_FWRITE) == NULL) {
perm |= 0200;
- (void)os_setperm(fname, perm);
- made_writable = TRUE;
+ (void)os_setperm((const char *)fname, perm);
+ made_writable = true;
}
#endif
@@ -3063,9 +3062,9 @@ nobackup:
*/
if (reset_changed && !newfile && overwriting
&& !(exiting && backup != NULL)) {
- ml_preserve(buf, FALSE);
+ ml_preserve(buf, false, !!p_fs);
if (got_int) {
- errmsg = (char_u *)_(e_interr);
+ SET_ERRMSG(_(e_interr));
goto restore_backup;
}
}
@@ -3136,8 +3135,8 @@ nobackup:
*/
if (*p_ccv != NUL) {
wfname = vim_tempname();
- if (wfname == NULL) { /* Can't write without a tempfile! */
- errmsg = (char_u *)_("E214: Can't find temp file for writing");
+ if (wfname == NULL) { // Can't write without a tempfile!
+ SET_ERRMSG(_("E214: Can't find temp file for writing"));
goto restore_backup;
}
}
@@ -3149,362 +3148,399 @@ nobackup:
&& wfname == fname
) {
if (!forceit) {
- errmsg = (char_u *)_(
- "E213: Cannot convert (add ! to write without conversion)");
+ SET_ERRMSG(_(
+ "E213: Cannot convert (add ! to write without conversion)"));
goto restore_backup;
}
notconverted = TRUE;
}
- /*
- * Open the file "wfname" for writing.
- * We may try to open the file twice: If we can't write to the
- * file and forceit is TRUE we delete the existing file and try to create
- * a new one. If this still fails we may have lost the original file!
- * (this may happen when the user reached his quotum for number of files).
- * Appending will fail if the file does not exist and forceit is FALSE.
- */
- while ((fd = os_open((char *)wfname, O_WRONLY | (append
- ? (forceit ? (
- O_APPEND |
- O_CREAT) :
- O_APPEND)
- : (O_CREAT |
- O_TRUNC))
- , perm < 0 ? 0666 : (perm & 0777))) < 0) {
- /*
- * A forced write will try to create a new file if the old one is
- * still readonly. This may also happen when the directory is
- * read-only. In that case the os_remove() will fail.
- */
- if (errmsg == NULL) {
+ // If conversion is taking place, we may first pretend to write and check
+ // for conversion errors. Then loop again to write for real.
+ // When not doing conversion this writes for real right away.
+ for (checking_conversion = true; ; checking_conversion = false) {
+ // There is no need to check conversion when:
+ // - there is no conversion
+ // - we make a backup file, that can be restored in case of conversion
+ // failure.
+ if (!converted || dobackup) {
+ checking_conversion = false;
+ }
+
+ if (checking_conversion) {
+ // Make sure we don't write anything.
+ fd = -1;
+ write_info.bw_fd = fd;
+ } else {
+ // Open the file "wfname" for writing.
+ // We may try to open the file twice: If we can't write to the file
+ // and forceit is TRUE we delete the existing file and try to
+ // create a new one. If this still fails we may have lost the
+ // original file! (this may happen when the user reached his
+ // quotum for number of files).
+ // Appending will fail if the file does not exist and forceit is
+ // FALSE.
+ while ((fd = os_open((char *)wfname,
+ O_WRONLY |
+ (append ?
+ (forceit ? (O_APPEND | O_CREAT) : O_APPEND)
+ : (O_CREAT | O_TRUNC))
+ , perm < 0 ? 0666 : (perm & 0777))) < 0) {
+ // A forced write will try to create a new file if the old one
+ // is still readonly. This may also happen when the directory
+ // is read-only. In that case the mch_remove() will fail.
+ if (errmsg == NULL) {
#ifdef UNIX
- FileInfo file_info;
+ FileInfo file_info;
- /* Don't delete the file when it's a hard or symbolic link. */
- if ((!newfile && os_fileinfo_hardlinks(&file_info) > 1)
- || (os_fileinfo_link((char *)fname, &file_info)
- && !os_fileinfo_id_equal(&file_info, &file_info_old))) {
- errmsg = (char_u *)_("E166: Can't open linked file for writing");
- } else
+ // Don't delete the file when it's a hard or symbolic link.
+ if ((!newfile && os_fileinfo_hardlinks(&file_info_old) > 1)
+ || (os_fileinfo_link((char *)fname, &file_info)
+ && !os_fileinfo_id_equal(&file_info, &file_info_old))) {
+ SET_ERRMSG(_("E166: Can't open linked file for writing"));
+ } else {
#endif
- {
- errmsg = (char_u *)_("E212: Can't open file for writing");
- if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL
- && perm >= 0) {
+ SET_ERRMSG_ARG(_("E212: Can't open file for writing: %s"), fd);
+ if (forceit && vim_strchr(p_cpo, CPO_FWRITE) == NULL
+ && perm >= 0) {
+#ifdef UNIX
+ // we write to the file, thus it should be marked
+ // writable after all
+ if (!(perm & 0200)) {
+ made_writable = true;
+ }
+ perm |= 0200;
+ if (file_info_old.stat.st_uid != getuid()
+ || file_info_old.stat.st_gid != getgid()) {
+ perm &= 0777;
+ }
+#endif
+ if (!append) { // don't remove when appending
+ os_remove((char *)wfname);
+ }
+ continue;
+ }
#ifdef UNIX
- /* we write to the file, thus it should be marked
- writable after all */
- if (!(perm & 0200))
- made_writable = TRUE;
- perm |= 0200;
- if (file_info_old.stat.st_uid != getuid()
- || file_info_old.stat.st_gid != getgid()) {
- perm &= 0777;
}
#endif
- if (!append) /* don't remove when appending */
- os_remove((char *)wfname);
- continue;
}
- }
- }
restore_backup:
- {
- /*
- * If we failed to open the file, we don't need a backup. Throw it
- * away. If we moved or removed the original file try to put the
- * backup in its place.
- */
- if (backup != NULL && wfname == fname) {
- if (backup_copy) {
- /*
- * There is a small chance that we removed the original,
- * try to move the copy in its place.
- * This may not work if the vim_rename() fails.
- * In that case we leave the copy around.
- */
- // If file does not exist, put the copy in its place
- if (!os_path_exists(fname)) {
- vim_rename(backup, fname);
+ {
+ // If we failed to open the file, we don't need a backup. Throw it
+ // away. If we moved or removed the original file try to put the
+ // backup in its place.
+ if (backup != NULL && wfname == fname) {
+ if (backup_copy) {
+ // There is a small chance that we removed the original,
+ // try to move the copy in its place.
+ // This may not work if the vim_rename() fails.
+ // In that case we leave the copy around.
+ // If file does not exist, put the copy in its place
+ if (!os_path_exists(fname)) {
+ vim_rename(backup, fname);
+ }
+ // if original file does exist throw away the copy
+ if (os_path_exists(fname)) {
+ os_remove((char *)backup);
+ }
+ } else {
+ // try to put the original file back
+ vim_rename(backup, fname);
+ }
}
- // if original file does exist throw away the copy
- if (os_path_exists(fname)) {
- os_remove((char *)backup);
+
+ // if original file no longer exists give an extra warning
+ if (!newfile && !os_path_exists(fname)) {
+ end = 0;
}
- } else {
- /* try to put the original file back */
- vim_rename(backup, fname);
}
- }
- // if original file no longer exists give an extra warning
- if (!newfile && !os_path_exists(fname)) {
- end = 0;
+ if (wfname != fname) {
+ xfree(wfname);
+ }
+ goto fail;
}
+ write_info.bw_fd = fd;
}
+ SET_ERRMSG(NULL);
- if (wfname != fname)
- xfree(wfname);
- goto fail;
- }
- errmsg = NULL;
-
+ write_info.bw_buf = buffer;
+ nchars = 0;
- write_info.bw_fd = fd;
- write_info.bw_buf = buffer;
- nchars = 0;
-
- /* use "++bin", "++nobin" or 'binary' */
- if (eap != NULL && eap->force_bin != 0)
- write_bin = (eap->force_bin == FORCE_BIN);
- else
- write_bin = buf->b_p_bin;
-
- /*
- * Skip the BOM when appending and the file already existed, the BOM
- * only makes sense at the start of the file.
- */
- if (buf->b_p_bomb && !write_bin && (!append || perm < 0)) {
- write_info.bw_len = make_bom(buffer, fenc);
- if (write_info.bw_len > 0) {
- /* don't convert */
- write_info.bw_flags = FIO_NOCONVERT | wb_flags;
- if (buf_write_bytes(&write_info) == FAIL)
- end = 0;
- else
- nchars += write_info.bw_len;
+ // use "++bin", "++nobin" or 'binary'
+ if (eap != NULL && eap->force_bin != 0) {
+ write_bin = (eap->force_bin == FORCE_BIN);
+ } else {
+ write_bin = buf->b_p_bin;
+ }
+
+ // Skip the BOM when appending and the file already existed, the BOM
+ // only makes sense at the start of the file.
+ if (buf->b_p_bomb && !write_bin && (!append || perm < 0)) {
+ write_info.bw_len = make_bom(buffer, fenc);
+ if (write_info.bw_len > 0) {
+ // don't convert
+ write_info.bw_flags = FIO_NOCONVERT | wb_flags;
+ if (buf_write_bytes(&write_info) == FAIL) {
+ end = 0;
+ } else {
+ nchars += write_info.bw_len;
+ }
+ }
}
- }
- write_info.bw_start_lnum = start;
+ write_info.bw_start_lnum = start;
- write_undo_file = (buf->b_p_udf && overwriting && !append
- && !filtering && reset_changed);
- if (write_undo_file)
- /* Prepare for computing the hash value of the text. */
- sha256_start(&sha_ctx);
+ write_undo_file = (buf->b_p_udf && overwriting && !append
+ && !filtering && reset_changed && !checking_conversion);
+ if (write_undo_file) {
+ // Prepare for computing the hash value of the text.
+ sha256_start(&sha_ctx);
+ }
- write_info.bw_len = bufsize;
+ write_info.bw_len = bufsize;
#ifdef HAS_BW_FLAGS
- write_info.bw_flags = wb_flags;
+ write_info.bw_flags = wb_flags;
#endif
- fileformat = get_fileformat_force(buf, eap);
- s = buffer;
- len = 0;
- for (lnum = start; lnum <= end; ++lnum) {
- /*
- * The next while loop is done once for each character written.
- * Keep it fast!
- */
- ptr = ml_get_buf(buf, lnum, FALSE) - 1;
- if (write_undo_file)
- sha256_update(&sha_ctx, ptr + 1, (uint32_t)(STRLEN(ptr + 1) + 1));
- while ((c = *++ptr) != NUL) {
- if (c == NL)
- *s = NUL; /* replace newlines with NULs */
- else if (c == CAR && fileformat == EOL_MAC)
- *s = NL; /* Mac: replace CRs with NLs */
- else
- *s = c;
- ++s;
- if (++len != bufsize)
- continue;
- if (buf_write_bytes(&write_info) == FAIL) {
- end = 0; /* write error: break loop */
+ fileformat = get_fileformat_force(buf, eap);
+ s = buffer;
+ len = 0;
+ for (lnum = start; lnum <= end; lnum++) {
+ // The next while loop is done once for each character written.
+ // Keep it fast!
+ ptr = ml_get_buf(buf, lnum, false) - 1;
+ if (write_undo_file) {
+ sha256_update(&sha_ctx, ptr + 1, (uint32_t)(STRLEN(ptr + 1) + 1));
+ }
+ while ((c = *++ptr) != NUL) {
+ if (c == NL) {
+ *s = NUL; // replace newlines with NULs
+ } else if (c == CAR && fileformat == EOL_MAC) {
+ *s = NL; // Mac: replace CRs with NLs
+ } else {
+ *s = c;
+ }
+ s++;
+ if (++len != bufsize) {
+ continue;
+ }
+ if (buf_write_bytes(&write_info) == FAIL) {
+ end = 0; // write error: break loop
+ break;
+ }
+ nchars += bufsize;
+ s = buffer;
+ len = 0;
+ write_info.bw_start_lnum = lnum;
+ }
+ // write failed or last line has no EOL: stop here
+ if (end == 0
+ || (lnum == end
+ && (write_bin || !buf->b_p_fixeol)
+ && (lnum == buf->b_no_eol_lnum
+ || (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol)))) {
+ lnum++; // written the line, count it
+ no_eol = true;
break;
}
- nchars += bufsize;
- s = buffer;
- len = 0;
- write_info.bw_start_lnum = lnum;
- }
- /* write failed or last line has no EOL: stop here */
- if (end == 0
- || (lnum == end
- && (write_bin || !buf->b_p_fixeol)
- && (lnum == buf->b_no_eol_lnum
- || (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol)))) {
- ++lnum; /* written the line, count it */
- no_eol = TRUE;
- break;
- }
- if (fileformat == EOL_UNIX)
- *s++ = NL;
- else {
- *s++ = CAR; /* EOL_MAC or EOL_DOS: write CR */
- if (fileformat == EOL_DOS) { /* write CR-NL */
- if (++len == bufsize) {
- if (buf_write_bytes(&write_info) == FAIL) {
- end = 0; /* write error: break loop */
- break;
+ if (fileformat == EOL_UNIX) {
+ *s++ = NL;
+ } else {
+ *s++ = CAR; // EOL_MAC or EOL_DOS: write CR
+ if (fileformat == EOL_DOS) { // write CR-NL
+ if (++len == bufsize) {
+ if (buf_write_bytes(&write_info) == FAIL) {
+ end = 0; // write error: break loop
+ break;
+ }
+ nchars += bufsize;
+ s = buffer;
+ len = 0;
}
- nchars += bufsize;
- s = buffer;
- len = 0;
+ *s++ = NL;
+ }
+ }
+ if (++len == bufsize) {
+ if (buf_write_bytes(&write_info) == FAIL) {
+ end = 0; // Write error: break loop.
+ break;
+ }
+ nchars += bufsize;
+ s = buffer;
+ len = 0;
+
+ os_breakcheck();
+ if (got_int) {
+ end = 0; // Interrupted, break loop.
+ break;
}
- *s++ = NL;
}
}
- if (++len == bufsize && end) {
+ if (len > 0 && end > 0) {
+ write_info.bw_len = len;
if (buf_write_bytes(&write_info) == FAIL) {
- end = 0; /* write error: break loop */
- break;
+ end = 0; // write error
}
- nchars += bufsize;
- s = buffer;
- len = 0;
+ nchars += len;
+ }
- os_breakcheck();
- if (got_int) {
- end = 0; /* Interrupted, break loop */
+ // Stop when writing done or an error was encountered.
+ if (!checking_conversion || end == 0) {
break;
- }
}
- }
- if (len > 0 && end > 0) {
- write_info.bw_len = len;
- if (buf_write_bytes(&write_info) == FAIL)
- end = 0; /* write error */
- nchars += len;
- }
-#if defined(UNIX)
- // On many journalling file systems there is a bug that causes both the
- // original and the backup file to be lost when halting the system right
- // after writing the file. That's because only the meta-data is
- // journalled. Syncing the file slows down the system, but assures it has
- // been written to disk and we don't lose it.
- // For a device do try the fsync() but don't complain if it does not work
- // (could be a pipe).
- // If the 'fsync' option is FALSE, don't fsync(). Useful for laptops.
- if (p_fs && os_fsync(fd) != 0 && !device) {
- errmsg = (char_u *)_("E667: Fsync failed");
- end = 0;
+ // If no error happened until now, writing should be ok, so loop to
+ // really write the buffer.
}
-#endif
+
+ // If we started writing, finish writing. Also when an error was
+ // encountered.
+ if (!checking_conversion) {
+ // On many journalling file systems there is a bug that causes both the
+ // original and the backup file to be lost when halting the system right
+ // after writing the file. That's because only the meta-data is
+ // journalled. Syncing the file slows down the system, but assures it has
+ // been written to disk and we don't lose it.
+ // For a device do try the fsync() but don't complain if it does not work
+ // (could be a pipe).
+ // If the 'fsync' option is FALSE, don't fsync(). Useful for laptops.
+ int error;
+ if (p_fs && (error = os_fsync(fd)) != 0 && !device) {
+ SET_ERRMSG_ARG(_("E667: Fsync failed: %s"), error);
+ end = 0;
+ }
#ifdef HAVE_SELINUX
- /* Probably need to set the security context. */
- if (!backup_copy)
- mch_copy_sec(backup, wfname);
+ // Probably need to set the security context.
+ if (!backup_copy) {
+ mch_copy_sec(backup, wfname);
+ }
#endif
#ifdef UNIX
- /* When creating a new file, set its owner/group to that of the original
- * file. Get the new device and inode number. */
- if (backup != NULL && !backup_copy) {
- /* don't change the owner when it's already OK, some systems remove
- * permission or ACL stuff */
- FileInfo file_info;
- if (!os_fileinfo((char *)wfname, &file_info)
- || file_info.stat.st_uid != file_info_old.stat.st_uid
- || file_info.stat.st_gid != file_info_old.stat.st_gid) {
- os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
- if (perm >= 0) /* set permission again, may have changed */
- (void)os_setperm(wfname, perm);
- }
- buf_set_file_id(buf);
- } else if (!buf->file_id_valid) {
- // Set the file_id when creating a new file.
- buf_set_file_id(buf);
- }
+ // When creating a new file, set its owner/group to that of the original
+ // file. Get the new device and inode number.
+ if (backup != NULL && !backup_copy) {
+ // don't change the owner when it's already OK, some systems remove
+ // permission or ACL stuff
+ FileInfo file_info;
+ if (!os_fileinfo((char *)wfname, &file_info)
+ || file_info.stat.st_uid != file_info_old.stat.st_uid
+ || file_info.stat.st_gid != file_info_old.stat.st_gid) {
+ os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
+ if (perm >= 0) { // Set permission again, may have changed.
+ (void)os_setperm((const char *)wfname, perm);
+ }
+ }
+ buf_set_file_id(buf);
+ } else if (!buf->file_id_valid) {
+ // Set the file_id when creating a new file.
+ buf_set_file_id(buf);
+ }
#endif
- if (close(fd) != 0) {
- errmsg = (char_u *)_("E512: Close failed");
- end = 0;
- }
+ if ((error = os_close(fd)) != 0) {
+ SET_ERRMSG_ARG(_("E512: Close failed: %s"), error);
+ end = 0;
+ }
#ifdef UNIX
- if (made_writable)
- perm &= ~0200; /* reset 'w' bit for security reasons */
+ if (made_writable) {
+ perm &= ~0200; // reset 'w' bit for security reasons
+ }
#endif
- if (perm >= 0) /* set perm. of new file same as old file */
- (void)os_setperm(wfname, perm);
+ if (perm >= 0) { // Set perm. of new file same as old file.
+ (void)os_setperm((const char *)wfname, perm);
+ }
#ifdef HAVE_ACL
- /* Probably need to set the ACL before changing the user (can't set the
- * ACL on a file the user doesn't own). */
- if (!backup_copy)
- mch_set_acl(wfname, acl);
+ // Probably need to set the ACL before changing the user (can't set the
+ // ACL on a file the user doesn't own).
+ if (!backup_copy) {
+ mch_set_acl(wfname, acl);
+ }
#endif
- if (wfname != fname) {
- /*
- * The file was written to a temp file, now it needs to be converted
- * with 'charconvert' to (overwrite) the output file.
- */
- if (end != 0) {
- if (eval_charconvert(enc_utf8 ? "utf-8" : (char *) p_enc, (char *) fenc,
- (char *) wfname, (char *) fname) == FAIL) {
- write_info.bw_conv_error = true;
- end = 0;
+ if (wfname != fname) {
+ // The file was written to a temp file, now it needs to be converted
+ // with 'charconvert' to (overwrite) the output file.
+ if (end != 0) {
+ if (eval_charconvert(enc_utf8 ? "utf-8" : (char *)p_enc, (char *)fenc,
+ (char *)wfname, (char *)fname) == FAIL) {
+ write_info.bw_conv_error = true;
+ end = 0;
+ }
}
+ os_remove((char *)wfname);
+ xfree(wfname);
}
- os_remove((char *)wfname);
- xfree(wfname);
}
if (end == 0) {
+ // Error encountered.
if (errmsg == NULL) {
if (write_info.bw_conv_error) {
- if (write_info.bw_conv_error_lnum == 0)
- errmsg = (char_u *)_(
- "E513: write error, conversion failed (make 'fenc' empty to override)");
- else {
- errmsg_allocated = TRUE;
- errmsg = xmalloc(300);
- vim_snprintf((char *)errmsg, 300,
- _("E513: write error, conversion failed in line %" PRId64
+ if (write_info.bw_conv_error_lnum == 0) {
+ SET_ERRMSG(_(
+ "E513: write error, conversion failed "
+ "(make 'fenc' empty to override)"));
+ } else {
+ errmsg_allocated = true;
+ SET_ERRMSG(xmalloc(300));
+ vim_snprintf(
+ errmsg, 300,
+ _("E513: write error, conversion failed in line %" PRIdLINENR
" (make 'fenc' empty to override)"),
- (int64_t)write_info.bw_conv_error_lnum);
+ write_info.bw_conv_error_lnum);
}
- } else if (got_int)
- errmsg = (char_u *)_(e_interr);
- else
- errmsg = (char_u *)_("E514: write error (file system full?)");
+ } else if (got_int) {
+ SET_ERRMSG(_(e_interr));
+ } else {
+ SET_ERRMSG(_("E514: write error (file system full?)"));
+ }
}
- /*
- * If we have a backup file, try to put it in place of the new file,
- * because the new file is probably corrupt. This avoids losing the
- * original file when trying to make a backup when writing the file a
- * second time.
- * When "backup_copy" is set we need to copy the backup over the new
- * file. Otherwise rename the backup file.
- * If this is OK, don't give the extra warning message.
- */
+ // If we have a backup file, try to put it in place of the new file,
+ // because the new file is probably corrupt. This avoids losing the
+ // original file when trying to make a backup when writing the file a
+ // second time.
+ // When "backup_copy" is set we need to copy the backup over the new
+ // file. Otherwise rename the backup file.
+ // If this is OK, don't give the extra warning message.
if (backup != NULL) {
if (backup_copy) {
- /* This may take a while, if we were interrupted let the user
- * know we got the message. */
+ // This may take a while, if we were interrupted let the user
+ // know we got the message.
if (got_int) {
MSG(_(e_interr));
ui_flush();
}
if ((fd = os_open((char *)backup, O_RDONLY, 0)) >= 0) {
if ((write_info.bw_fd = os_open((char *)fname,
- O_WRONLY | O_CREAT | O_TRUNC,
- perm & 0777)) >= 0) {
- /* copy the file. */
+ O_WRONLY | O_CREAT | O_TRUNC,
+ perm & 0777)) >= 0) {
+ // copy the file.
write_info.bw_buf = smallbuf;
#ifdef HAS_BW_FLAGS
write_info.bw_flags = FIO_NOCONVERT;
#endif
while ((write_info.bw_len = read_eintr(fd, smallbuf,
- SMBUFSIZE)) > 0)
- if (buf_write_bytes(&write_info) == FAIL)
+ SMBUFSIZE)) > 0) {
+ if (buf_write_bytes(&write_info) == FAIL) {
break;
+ }
+ }
if (close(write_info.bw_fd) >= 0
- && write_info.bw_len == 0)
- end = 1; /* success */
+ && write_info.bw_len == 0) {
+ end = 1; // success
+ }
}
- close(fd); /* ignore errors for closing read file */
+ close(fd); // ignore errors for closing read file
}
} else {
- if (vim_rename(backup, fname) == 0)
+ if (vim_rename(backup, fname) == 0) {
end = 1;
+ }
}
}
goto fail;
@@ -3517,8 +3553,8 @@ restore_backup:
fname = sfname; /* use shortname now, for the messages */
#endif
if (!filtering) {
- msg_add_fname(buf, fname); /* put fname in IObuff with quotes */
- c = FALSE;
+ add_quoted_fname((char *)IObuff, IOSIZE, buf, (const char *)fname);
+ c = false;
if (write_info.bw_conv_error) {
STRCAT(IObuff, _(" CONVERSION ERROR"));
c = TRUE;
@@ -3561,14 +3597,13 @@ restore_backup:
* writing to the original file and '+' is not in 'cpoptions'. */
if (reset_changed && whole && !append
&& !write_info.bw_conv_error
- && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)
- ) {
- unchanged(buf, TRUE);
- /* buf->b_changedtick is always incremented in unchanged() but that
- * should not trigger a TextChanged event. */
- if (last_changedtick + 1 == buf->b_changedtick
- && last_changedtick_buf == buf) {
- last_changedtick = buf->b_changedtick;
+ && (overwriting || vim_strchr(p_cpo, CPO_PLUS) != NULL)) {
+ unchanged(buf, true);
+ const varnumber_T changedtick = buf_get_changedtick(buf);
+ if (buf->b_last_changedtick + 1 == changedtick) {
+ // changedtick is always incremented in unchanged() but that
+ // should not trigger a TextChanged event.
+ buf->b_last_changedtick = changedtick;
}
u_unchanged(buf);
u_update_save_nr(buf);
@@ -3627,7 +3662,7 @@ restore_backup:
close(empty_fd);
}
if (org != NULL) {
- os_setperm((char_u *)org, os_getperm(fname) & 0777);
+ os_setperm(org, os_getperm((const char *)fname) & 0777);
xfree(org);
}
}
@@ -3667,33 +3702,32 @@ nofail:
#endif
if (errmsg != NULL) {
- int numlen = errnum != NULL ? (int)STRLEN(errnum) : 0;
-
- attr = hl_attr(HLF_E); /* set highlight for error messages */
- msg_add_fname(buf,
+ // - 100 to save some space for further error message
#ifndef UNIX
- sfname
+ add_quoted_fname((char *)IObuff, IOSIZE - 100, buf, (const char *)sfname);
#else
- fname
+ add_quoted_fname((char *)IObuff, IOSIZE - 100, buf, (const char *)fname);
#endif
- ); /* put file name in IObuff with quotes */
- if (STRLEN(IObuff) + STRLEN(errmsg) + numlen >= IOSIZE)
- IObuff[IOSIZE - STRLEN(errmsg) - numlen - 1] = NUL;
- /* If the error message has the form "is ...", put the error number in
- * front of the file name. */
if (errnum != NULL) {
- STRMOVE(IObuff + numlen, IObuff);
- memmove(IObuff, errnum, (size_t)numlen);
+ if (errmsgarg != 0) {
+ emsgf("%s: %s%s: %s", errnum, IObuff, errmsg, os_strerror(errmsgarg));
+ } else {
+ emsgf("%s: %s%s", errnum, IObuff, errmsg);
+ }
+ } else if (errmsgarg != 0) {
+ emsgf(errmsg, os_strerror(errmsgarg));
+ } else {
+ EMSG(errmsg);
}
- STRCAT(IObuff, errmsg);
- emsg(IObuff);
- if (errmsg_allocated)
+ if (errmsg_allocated) {
xfree(errmsg);
+ }
retval = FAIL;
if (end == 0) {
+ const int attr = HL_ATTR(HLF_E); // Set highlight for error messages.
MSG_PUTS_ATTR(_("\nWARNING: Original file may be lost or damaged\n"),
- attr | MSG_HIST);
+ attr | MSG_HIST);
MSG_PUTS_ATTR(_(
"don't quit the editor until the file is successfully written!"),
attr | MSG_HIST);
@@ -3753,6 +3787,9 @@ nofail:
got_int |= prev_got_int;
return retval;
+#undef SET_ERRMSG
+#undef SET_ERRMSG_ARG
+#undef SET_ERRMSG_NUM
}
/*
@@ -3787,24 +3824,34 @@ static int set_rw_fname(char_u *fname, char_u *sfname)
/* Do filetype detection now if 'filetype' is empty. */
if (*curbuf->b_p_ft == NUL) {
- if (au_has_group((char_u *)"filetypedetect"))
- (void)do_doautocmd((char_u *)"filetypedetect BufRead", FALSE);
+ if (au_has_group((char_u *)"filetypedetect")) {
+ (void)do_doautocmd((char_u *)"filetypedetect BufRead", false, NULL);
+ }
do_modelines(0);
}
return OK;
}
-/*
- * Put file name into IObuff with quotes.
- */
-void msg_add_fname(buf_T *buf, char_u *fname)
+/// Put file name into the specified buffer with quotes
+///
+/// Replaces home directory at the start with `~`.
+///
+/// @param[out] ret_buf Buffer to save results to.
+/// @param[in] buf_len ret_buf length.
+/// @param[in] buf buf_T file name is coming from.
+/// @param[in] fname File name to write.
+static void add_quoted_fname(char *const ret_buf, const size_t buf_len,
+ const buf_T *const buf, const char *fname)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- if (fname == NULL)
- fname = (char_u *)"-stdin-";
- home_replace(buf, fname, IObuff + 1, IOSIZE - 4, TRUE);
- IObuff[0] = '"';
- STRCAT(IObuff, "\" ");
+ if (fname == NULL) {
+ fname = "-stdin-";
+ }
+ ret_buf[0] = '"';
+ home_replace(buf, (const char_u *)fname, (char_u *)ret_buf + 1,
+ (int)buf_len - 4, true);
+ xstrlcat(ret_buf, "\" ", buf_len);
}
/// Append message for text mode to IObuff.
@@ -3836,7 +3883,7 @@ 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)
+void msg_add_lines(int insert_space, long lnum, off_T nchars)
{
char_u *p;
@@ -3881,15 +3928,15 @@ static int check_mtime(buf_T *buf, FileInfo *file_info)
if (buf->b_mtime_read != 0
&& time_differs(file_info->stat.st_mtim.tv_sec,
buf->b_mtime_read)) {
- msg_scroll = TRUE; /* don't overwrite messages here */
- msg_silent = 0; /* must give this prompt */
- /* don't use emsg() here, don't want to flush the buffers */
- MSG_ATTR(_("WARNING: The file has been changed since reading it!!!"),
- hl_attr(HLF_E));
- if (ask_yesno((char_u *)_("Do you really want to write to it"),
- TRUE) == 'n')
+ msg_scroll = true; // Don't overwrite messages here.
+ msg_silent = 0; // Must give this prompt.
+ // Don't use emsg() here, don't want to flush the buffers.
+ msg_attr(_("WARNING: The file has been changed since reading it!!!"),
+ HL_ATTR(HLF_E));
+ if (ask_yesno(_("Do you really want to write to it"), true) == 'n') {
return FAIL;
- msg_scroll = FALSE; /* always overwrite the file message now */
+ }
+ msg_scroll = false; // Always overwrite the file message now.
}
return OK;
}
@@ -4083,6 +4130,10 @@ static int buf_write_bytes(struct bw_info *ip)
# endif
}
+ if (ip->bw_fd < 0) {
+ // Only checking conversion, which is OK if we get here.
+ return OK;
+ }
wlen = write_eintr(ip->bw_fd, buf, len);
return (wlen < len) ? FAIL : OK;
}
@@ -4178,9 +4229,8 @@ static bool need_conversion(const char_u *fenc)
same_encoding = (enc_flags != 0 && fenc_flags == enc_flags);
}
if (same_encoding) {
- /* Specified encoding matches with 'encoding'. This requires
- * conversion when 'encoding' is Unicode but not UTF-8. */
- return enc_unicode != 0;
+ // Specified file encoding matches UTF-8.
+ return false;
}
/* Encodings differ. However, conversion is not needed when 'enc' is any
@@ -4296,38 +4346,46 @@ static int make_bom(char_u *buf, char_u *name)
return (int)(p - buf);
}
+/// Shorten filename of a buffer.
+/// When "force" is TRUE: Use full path from now on for files currently being
+/// edited, both for file name and swap file name. Try to shorten the file
+/// names a bit, if safe to do so.
+/// When "force" is FALSE: Only try to shorten absolute file names.
+/// For buffers that have buftype "nofile" or "scratch": never change the file
+/// name.
+void shorten_buf_fname(buf_T *buf, char_u *dirname, int force)
+{
+ char_u *p;
+
+ if (buf->b_fname != NULL
+ && !bt_nofile(buf)
+ && !path_with_url((char *)buf->b_fname)
+ && (force
+ || buf->b_sfname == NULL
+ || path_is_absolute(buf->b_sfname))) {
+ xfree(buf->b_sfname);
+ buf->b_sfname = NULL;
+ p = path_shorten_fname(buf->b_ffname, dirname);
+ if (p != NULL) {
+ buf->b_sfname = vim_strsave(p);
+ buf->b_fname = buf->b_sfname;
+ }
+ if (p == NULL || buf->b_fname == NULL) {
+ buf->b_fname = buf->b_ffname;
+ }
+ }
+}
+
/*
* Shorten filenames for all buffers.
- * When "force" is TRUE: Use full path from now on for files currently being
- * edited, both for file name and swap file name. Try to shorten the file
- * names a bit, if safe to do so.
- * When "force" is FALSE: Only try to shorten absolute file names.
- * For buffers that have buftype "nofile" or "scratch": never change the file
- * name.
*/
void shorten_fnames(int force)
{
char_u dirname[MAXPATHL];
- char_u *p;
os_dirname(dirname, MAXPATHL);
FOR_ALL_BUFFERS(buf) {
- if (buf->b_fname != NULL
- && !bt_nofile(buf)
- && !path_with_url((char *)buf->b_fname)
- && (force
- || buf->b_sfname == NULL
- || path_is_absolute_path(buf->b_sfname))) {
- xfree(buf->b_sfname);
- buf->b_sfname = NULL;
- p = path_shorten_fname(buf->b_ffname, dirname);
- if (p != NULL) {
- buf->b_sfname = vim_strsave(p);
- buf->b_fname = buf->b_sfname;
- }
- if (p == NULL || buf->b_fname == NULL)
- buf->b_fname = buf->b_ffname;
- }
+ shorten_buf_fname(buf, dirname, force);
/* Always make the swap file name a full path, a "nofile" buffer may
* also have a swap file. */
@@ -4389,7 +4447,7 @@ char *modname(const char *fname, const char *ext, bool prepend_dot)
// Search backwards until we hit a '/', '\' or ':'.
// Then truncate what is after the '/', '\' or ':' to BASENAMELEN characters.
char *ptr = NULL;
- for (ptr = retval + fnamelen; ptr > retval; mb_ptr_back(retval, ptr)) {
+ for (ptr = retval + fnamelen; ptr > retval; MB_PTR_BACK(retval, ptr)) {
if (vim_ispathsep(*ptr)) {
ptr++;
break;
@@ -4439,33 +4497,163 @@ char *modname(const char *fname, const char *ext, bool prepend_dot)
/// @param size size of the buffer
/// @param fp file to read from
///
-/// @return true for end-of-file.
+/// @return true for EOF or error
bool vim_fgets(char_u *buf, int size, FILE *fp) FUNC_ATTR_NONNULL_ALL
{
- char *eof;
-#define FGETS_SIZE 200
- char tbuf[FGETS_SIZE];
+ char *retval;
+ assert(size > 0);
buf[size - 2] = NUL;
- eof = fgets((char *)buf, size, fp);
+
+ do {
+ errno = 0;
+ retval = fgets((char *)buf, size, fp);
+ } while (retval == NULL && errno == EINTR && ferror(fp));
+
if (buf[size - 2] != NUL && buf[size - 2] != '\n') {
- buf[size - 1] = NUL; /* Truncate the line */
+ char tbuf[200];
- /* Now throw away the rest of the line: */
+ buf[size - 1] = NUL; // Truncate the line.
+
+ // Now throw away the rest of the line:
do {
- tbuf[FGETS_SIZE - 2] = NUL;
- ignoredp = fgets((char *)tbuf, FGETS_SIZE, fp);
- } while (tbuf[FGETS_SIZE - 2] != NUL && tbuf[FGETS_SIZE - 2] != '\n');
+ tbuf[sizeof(tbuf) - 2] = NUL;
+ errno = 0;
+ retval = fgets((char *)tbuf, sizeof(tbuf), fp);
+ if (retval == NULL && (feof(fp) || errno != EINTR)) {
+ break;
+ }
+ } while (tbuf[sizeof(tbuf) - 2] != NUL && tbuf[sizeof(tbuf) - 2] != '\n');
}
- return eof == NULL;
+ return retval == NULL;
}
-/*
- * os_rename() only works if both files are on the same file system, this
- * function will (attempts to?) copy the file across if rename fails -- webb
- * Return -1 for failure, 0 for success.
- */
-int vim_rename(char_u *from, char_u *to)
+/// Read 2 bytes from "fd" and turn them into an int, MSB first.
+/// Returns -1 when encountering EOF.
+int get2c(FILE *fd)
+{
+ const int n = getc(fd);
+ if (n == EOF) {
+ return -1;
+ }
+ const int c = getc(fd);
+ if (c == EOF) {
+ return -1;
+ }
+ return (n << 8) + c;
+}
+
+/// Read 3 bytes from "fd" and turn them into an int, MSB first.
+/// Returns -1 when encountering EOF.
+int get3c(FILE *fd)
+{
+ int n = getc(fd);
+ if (n == EOF) {
+ return -1;
+ }
+ int c = getc(fd);
+ if (c == EOF) {
+ return -1;
+ }
+ n = (n << 8) + c;
+ c = getc(fd);
+ if (c == EOF) {
+ return -1;
+ }
+ return (n << 8) + c;
+}
+
+/// Read 4 bytes from "fd" and turn them into an int, MSB first.
+/// Returns -1 when encountering EOF.
+int get4c(FILE *fd)
+{
+ // Use unsigned rather than int otherwise result is undefined
+ // when left-shift sets the MSB.
+ unsigned n;
+
+ int c = getc(fd);
+ if (c == EOF) {
+ return -1;
+ }
+ n = (unsigned)c;
+ c = getc(fd);
+ if (c == EOF) {
+ return -1;
+ }
+ n = (n << 8) + (unsigned)c;
+ c = getc(fd);
+ if (c == EOF) {
+ return -1;
+ }
+ n = (n << 8) + (unsigned)c;
+ c = getc(fd);
+ if (c == EOF) {
+ return -1;
+ }
+ n = (n << 8) + (unsigned)c;
+ return (int)n;
+}
+
+/// Read 8 bytes from `fd` and turn them into a time_t, MSB first.
+/// Returns -1 when encountering EOF.
+time_t get8ctime(FILE *fd)
+{
+ time_t n = 0;
+
+ for (int i = 0; i < 8; i++) {
+ const int c = getc(fd);
+ if (c == EOF) {
+ return -1;
+ }
+ n = (n << 8) + c;
+ }
+ return n;
+}
+
+/// Reads a string of length "cnt" from "fd" into allocated memory.
+/// @return pointer to the string or NULL when unable to read that many bytes.
+char *read_string(FILE *fd, size_t cnt)
+{
+ char *str = xmallocz(cnt);
+ for (size_t i = 0; i < cnt; i++) {
+ int c = getc(fd);
+ if (c == EOF) {
+ xfree(str);
+ return NULL;
+ }
+ str[i] = (char)c;
+ }
+ return str;
+}
+
+/// Writes a number to file "fd", most significant bit first, in "len" bytes.
+/// @returns false in case of an error.
+bool put_bytes(FILE *fd, uintmax_t number, size_t len)
+{
+ assert(len > 0);
+ for (size_t i = len - 1; i < len; i--) {
+ if (putc((int)(number >> (i * 8)), fd) == EOF) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/// Writes time_t to file "fd" in 8 bytes.
+/// @returns FAIL when the write failed.
+int put_time(FILE *fd, time_t time_)
+{
+ uint8_t buf[8];
+ time_to_bytes(time_, buf);
+ return fwrite(buf, sizeof(uint8_t), ARRAY_SIZE(buf), fd) == 1 ? OK : FAIL;
+}
+
+/// os_rename() only works if both files are on the same file system, this
+/// function will (attempts to?) copy the file across if rename fails -- webb
+///
+/// @return -1 for failure, 0 for success
+int vim_rename(const char_u *from, const char_u *to)
+ FUNC_ATTR_NONNULL_ALL
{
int fd_in;
int fd_out;
@@ -4484,10 +4672,12 @@ int vim_rename(char_u *from, char_u *to)
* the file name differs we need to go through a temp file.
*/
if (fnamecmp(from, to) == 0) {
- if (p_fic && STRCMP(path_tail(from), path_tail(to)) != 0)
+ if (p_fic && (STRCMP(path_tail((char_u *)from), path_tail((char_u *)to))
+ != 0)) {
use_tmp_file = true;
- else
+ } else {
return 0;
+ }
}
// Fail if the "from" file doesn't exist. Avoids that "to" is deleted.
@@ -4553,9 +4743,9 @@ int vim_rename(char_u *from, char_u *to)
/*
* Rename() failed, try copying the file.
*/
- perm = os_getperm(from);
+ perm = os_getperm((const char *)from);
#ifdef HAVE_ACL
- /* For systems that support ACL: get the ACL from the original file. */
+ // For systems that support ACL: get the ACL from the original file.
acl = mch_get_acl(from);
#endif
fd_in = os_open((char *)from, O_RDONLY, 0);
@@ -4577,7 +4767,7 @@ int vim_rename(char_u *from, char_u *to)
return -1;
}
- // Avoid xmalloc() here as vim_rename() is called by buf_write() when neovim
+ // Avoid xmalloc() here as vim_rename() is called by buf_write() when nvim
// is `preserve_exit()`ing.
buffer = try_malloc(BUFSIZE);
if (buffer == NULL) {
@@ -4603,8 +4793,8 @@ int vim_rename(char_u *from, char_u *to)
errmsg = _("E210: Error reading \"%s\"");
to = from;
}
-#ifndef UNIX /* for Unix os_open() already set the permission */
- os_setperm(to, perm);
+#ifndef UNIX // For Unix os_open() already set the permission.
+ os_setperm((const char *)to, perm);
#endif
#ifdef HAVE_ACL
mch_set_acl(to, acl);
@@ -4636,7 +4826,6 @@ check_timestamps (
int focus /* called for GUI focus event */
)
{
- buf_T *buf;
int didit = 0;
int n;
@@ -4655,32 +4844,33 @@ check_timestamps (
if (!stuff_empty() || global_busy || !typebuf_typed()
|| autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
- )
- need_check_timestamps = TRUE; /* check later */
- else {
- ++no_wait_return;
- did_check_timestamps = TRUE;
- already_warned = FALSE;
- for (buf = firstbuf; buf != NULL; ) {
- /* Only check buffers in a window. */
+ ) {
+ need_check_timestamps = true; // check later
+ } else {
+ no_wait_return++;
+ did_check_timestamps = true;
+ already_warned = false;
+ FOR_ALL_BUFFERS(buf) {
+ // Only check buffers in a window.
if (buf->b_nwindows > 0) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
n = buf_check_timestamp(buf, focus);
- if (didit < n)
+ if (didit < n) {
didit = n;
- if (n > 0 && !buf_valid(buf)) {
- /* Autocommands have removed the buffer, start at the
- * first one again. */
+ }
+ if (n > 0 && !bufref_valid(&bufref)) {
+ // Autocommands have removed the buffer, start at the first one again.
buf = firstbuf;
continue;
}
}
- buf = buf->b_next;
}
--no_wait_return;
need_check_timestamps = FALSE;
if (need_wait_return && didit == 2) {
- /* make sure msg isn't overwritten */
- msg_puts((char_u *)"\n");
+ // make sure msg isn't overwritten
+ msg_puts("\n");
ui_flush();
}
}
@@ -4739,6 +4929,7 @@ buf_check_timestamp (
buf_T *buf,
int focus /* called for GUI focus event */
)
+ FUNC_ATTR_NONNULL_ALL
{
int retval = 0;
char_u *path;
@@ -4754,6 +4945,9 @@ buf_check_timestamp (
char_u *s;
char *reason;
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+
// If its a terminal, there is no file name, the buffer is not loaded,
// 'buftype' is set, we are in the middle of a save or being called
// recursively: ignore this buffer.
@@ -4776,10 +4970,12 @@ buf_check_timestamp (
)) {
retval = 1;
- /* set b_mtime to stop further warnings (e.g., when executing
- * FileChangedShell autocmd) */
+ // set b_mtime to stop further warnings (e.g., when executing
+ // FileChangedShell autocmd)
if (!file_info_ok) {
- buf->b_mtime = 0;
+ // When 'autoread' is set we'll check the file again to see if it
+ // re-appears.
+ buf->b_mtime = buf->b_p_ar;
buf->b_orig_size = 0;
buf->b_orig_mode = 0;
} else {
@@ -4823,8 +5019,9 @@ buf_check_timestamp (
allbuf_lock--;
busy = false;
if (n) {
- if (!buf_valid(buf))
+ if (!bufref_valid(&bufref)) {
EMSG(_("E246: FileChangedShell autocommand deleted buffer"));
+ }
s = get_vim_var_str(VV_FCS_CHOICE);
if (STRCMP(s, "reload") == 0 && *reason != 'd')
reload = TRUE;
@@ -4886,8 +5083,8 @@ buf_check_timestamp (
set_vim_var_string(VV_WARNINGMSG, tbuf, -1);
if (can_reload) {
if (*mesg2 != NUL) {
- strncat(tbuf, "\n", tbuf_len);
- strncat(tbuf, mesg2, tbuf_len);
+ xstrlcat(tbuf, "\n", tbuf_len - 1);
+ xstrlcat(tbuf, mesg2, tbuf_len - 1);
}
if (do_dialog(VIM_WARNING, (char_u *) _("Warning"), (char_u *) tbuf,
(char_u *) _("&OK\n&Load File"), 1, NULL, true) == 2) {
@@ -4895,18 +5092,17 @@ buf_check_timestamp (
}
} else if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned) {
if (*mesg2 != NUL) {
- strncat(tbuf, "; ", tbuf_len);
- strncat(tbuf, mesg2, tbuf_len);
+ xstrlcat(tbuf, "; ", tbuf_len - 1);
+ xstrlcat(tbuf, mesg2, tbuf_len - 1);
}
EMSG(tbuf);
retval = 2;
} else {
if (!autocmd_busy) {
msg_start();
- msg_puts_attr((char_u *) tbuf, hl_attr(HLF_E) + MSG_HIST);
+ msg_puts_attr(tbuf, HL_ATTR(HLF_E) + MSG_HIST);
if (*mesg2 != NUL) {
- msg_puts_attr((char_u *)mesg2,
- hl_attr(HLF_W) + MSG_HIST);
+ msg_puts_attr(mesg2, HL_ATTR(HLF_W) + MSG_HIST);
}
msg_clr_eos();
(void)msg_end();
@@ -4941,11 +5137,11 @@ buf_check_timestamp (
}
}
- /* Trigger FileChangedShell when the file was changed in any way. */
- if (buf_valid(buf) && retval != 0)
- (void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST,
- buf->b_fname, buf->b_fname, FALSE, buf);
-
+ // Trigger FileChangedShell when the file was changed in any way.
+ if (bufref_valid(&bufref) && retval != 0) {
+ (void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST, buf->b_fname, buf->b_fname,
+ false, buf);
+ }
return retval;
}
@@ -4962,6 +5158,7 @@ void buf_reload(buf_T *buf, int orig_mode)
linenr_T old_topline;
int old_ro = buf->b_p_ro;
buf_T *savebuf;
+ bufref_T bufref;
int saved = OK;
aco_save_T aco;
int flags = READ_NEW;
@@ -4985,18 +5182,17 @@ void buf_reload(buf_T *buf, int orig_mode)
flags |= READ_KEEP_UNDO;
}
- /*
- * To behave like when a new file is edited (matters for
- * BufReadPost autocommands) we first need to delete the current
- * buffer contents. But if reading the file fails we should keep
- * the old contents. Can't use memory only, the file might be
- * too big. Use a hidden buffer to move the buffer contents to.
- */
- if (bufempty() || saved == FAIL)
+ // To behave like when a new file is edited (matters for
+ // BufReadPost autocommands) we first need to delete the current
+ // buffer contents. But if reading the file fails we should keep
+ // the old contents. Can't use memory only, the file might be
+ // too big. Use a hidden buffer to move the buffer contents to.
+ if (BUFEMPTY() || saved == FAIL) {
savebuf = NULL;
- else {
- /* Allocate a buffer without putting it in the buffer list. */
+ } else {
+ // Allocate a buffer without putting it in the buffer list.
savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
+ set_bufref(&bufref, savebuf);
if (savebuf != NULL && buf == curbuf) {
/* Open the memline. */
curbuf = savebuf;
@@ -5014,19 +5210,21 @@ void buf_reload(buf_T *buf, int orig_mode)
}
if (saved == OK) {
- curbuf->b_flags |= BF_CHECK_RO; /* check for RO again */
- keep_filetype = TRUE; /* don't detect 'filetype' */
- if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0,
- (linenr_T)0,
- (linenr_T)MAXLNUM, &ea, flags) == FAIL) {
- if (!aborting())
+ curbuf->b_flags |= BF_CHECK_RO; // check for RO again
+ keep_filetype = true; // don't detect 'filetype'
+ if (readfile(buf->b_ffname, buf->b_fname, (linenr_T)0, (linenr_T)0,
+ (linenr_T)MAXLNUM, &ea, flags) != OK) {
+ if (!aborting()) {
EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname);
- if (savebuf != NULL && buf_valid(savebuf) && buf == curbuf) {
- /* Put the text back from the save buffer. First
- * delete any lines that readfile() added. */
- while (!bufempty())
- if (ml_delete(buf->b_ml.ml_line_count, FALSE) == FAIL)
+ }
+ if (savebuf != NULL && bufref_valid(&bufref) && buf == curbuf) {
+ // Put the text back from the save buffer. First
+ // delete any lines that readfile() added.
+ while (!BUFEMPTY()) {
+ if (ml_delete(buf->b_ml.ml_line_count, false) == FAIL) {
break;
+ }
+ }
(void)move_lines(savebuf, buf);
}
} else if (buf == curbuf) { /* "buf" still valid */
@@ -5043,8 +5241,9 @@ void buf_reload(buf_T *buf, int orig_mode)
}
xfree(ea.cmd);
- if (savebuf != NULL && buf_valid(savebuf))
- wipe_buffer(savebuf, FALSE);
+ if (savebuf != NULL && bufref_valid(&bufref)) {
+ wipe_buffer(savebuf, false);
+ }
/* Invalidate diff info if necessary. */
diff_invalidate(curbuf);
@@ -5107,7 +5306,7 @@ void forward_slash(char_u *fname)
{
char_u *p;
- if (path_with_url(fname)) {
+ if (path_with_url((const char *)fname)) {
return;
}
for (p = fname; *p != NUL; p++) {
@@ -5135,6 +5334,10 @@ static void vim_maketempdir(void)
// Try the entries in `TEMP_DIR_NAMES` to create the temp directory.
char_u template[TEMP_FILE_PATH_MAXLEN];
char_u path[TEMP_FILE_PATH_MAXLEN];
+
+ // Make sure the umask doesn't remove the executable bit.
+ // "repl" has been reported to use "0177".
+ mode_t umask_save = umask(0077);
for (size_t i = 0; i < ARRAY_SIZE(temp_dirs); i++) {
// Expand environment variables, leave room for "/nvimXXXXXX/999999999"
expand_env((char_u *)temp_dirs[i], template, TEMP_FILE_PATH_MAXLEN - 22);
@@ -5158,12 +5361,13 @@ static void vim_maketempdir(void)
os_rmdir((char *)path);
}
}
+ (void)umask(umask_save);
}
/// Delete "name" and everything in it, recursively.
/// @param name The path which should be deleted.
/// @return 0 for success, -1 if some file was not deleted.
-int delete_recursive(char_u *name)
+int delete_recursive(const char *name)
{
int result = 0;
@@ -5177,7 +5381,7 @@ int delete_recursive(char_u *name)
EW_DIR | EW_FILE | EW_SILENT | EW_ALLLINKS
| EW_DODOT | EW_EMPTYOK) == OK) {
for (int i = 0; i < file_count; i++) {
- if (delete_recursive(files[i]) != 0) {
+ if (delete_recursive((const char *)files[i]) != 0) {
result = -1;
}
}
@@ -5187,9 +5391,9 @@ int delete_recursive(char_u *name)
}
xfree(exp);
- os_rmdir((char *)name);
+ os_rmdir(name);
} else {
- result = os_remove((char *)name) == 0 ? 0 : -1;
+ result = os_remove(name) == 0 ? 0 : -1;
}
return result;
@@ -5201,7 +5405,7 @@ void vim_deltempdir(void)
if (vim_tempdir != NULL) {
// remove the trailing path separator
path_tail(vim_tempdir)[-1] = NUL;
- delete_recursive(vim_tempdir);
+ delete_recursive((const char *)vim_tempdir);
xfree(vim_tempdir);
vim_tempdir = NULL;
}
@@ -5272,11 +5476,9 @@ char_u *vim_tempname(void)
static AutoPatCmd *active_apc_list = NULL; /* stack of active autocommands */
-/*
- * augroups stores a list of autocmd group names.
- */
-static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL};
-#define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i])
+/// List of autocmd group names
+static garray_T augroups = { 0, 0, sizeof(char_u *), 10, NULL };
+#define AUGROUP_NAME(i) (((char **)augroups.ga_data)[i])
/*
* The ID of the current group. Group 0 is the default one.
@@ -5291,6 +5493,18 @@ static event_T last_event;
static int last_group;
static int autocmd_blocked = 0; /* block all autocmds */
+// use get_deleted_augroup() to get this
+static const char *deleted_augroup = NULL;
+
+static inline const char *get_deleted_augroup(void)
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ if (deleted_augroup == NULL) {
+ deleted_augroup = _("--Deleted--");
+ }
+ return deleted_augroup;
+}
+
/*
* Show the autocommands for one AutoPat.
*/
@@ -5310,13 +5524,14 @@ static void show_autocmd(AutoPat *ap, event_T event)
return;
if (event != last_event || ap->group != last_group) {
if (ap->group != AUGROUP_DEFAULT) {
- if (AUGROUP_NAME(ap->group) == NULL)
- msg_puts_attr((char_u *)_("--Deleted--"), hl_attr(HLF_E));
- else
- msg_puts_attr(AUGROUP_NAME(ap->group), hl_attr(HLF_T));
- msg_puts((char_u *)" ");
+ if (AUGROUP_NAME(ap->group) == NULL) {
+ msg_puts_attr(get_deleted_augroup(), HL_ATTR(HLF_E));
+ } else {
+ msg_puts_attr(AUGROUP_NAME(ap->group), HL_ATTR(HLF_T));
+ }
+ msg_puts(" ");
}
- msg_puts_attr(event_nr2name(event), hl_attr(HLF_T));
+ msg_puts_attr(event_nr2name(event), HL_ATTR(HLF_T));
last_event = event;
last_group = ap->group;
msg_putchar('\n');
@@ -5407,6 +5622,15 @@ static void au_cleanup(void)
/* remove the pattern if it has been marked for deletion */
if (ap->pat == NULL) {
+ if (ap->next == NULL) {
+ if (prev_ap == &(first_autopat[(int)event])) {
+ last_autopat[(int)event] = NULL;
+ } else {
+ // this depends on the "next" field being the first in
+ // the struct
+ last_autopat[(int)event] = (AutoPat *)prev_ap;
+ }
+ }
*prev_ap = ap->next;
vim_regfree(ap->reg_prog);
xfree(ap);
@@ -5443,7 +5667,7 @@ void aubuflocal_remove(buf_T *buf)
if (p_verbose >= 6) {
verbose_enter();
smsg(_("auto-removing autocommand: %s <buffer=%d>"),
- event_nr2name(event), buf->b_fnum);
+ event_nr2name(event), buf->b_fnum);
verbose_leave();
}
}
@@ -5466,9 +5690,10 @@ static int au_new_group(char_u *name)
ga_grow(&augroups, 1);
}
- AUGROUP_NAME(i) = vim_strsave(name);
- if (i == augroups.ga_len)
- ++augroups.ga_len;
+ AUGROUP_NAME(i) = xstrdup((char *)name);
+ if (i == augroups.ga_len) {
+ augroups.ga_len++;
+ }
}
return i;
@@ -5479,11 +5704,33 @@ static void au_del_group(char_u *name)
int i;
i = au_find_group(name);
- if (i == AUGROUP_ERROR) /* the group doesn't exist */
+ if (i == AUGROUP_ERROR) { // the group doesn't exist
EMSG2(_("E367: No such group: \"%s\""), name);
- else {
+ } else if (i == current_augroup) {
+ EMSG(_("E936: Cannot delete the current group"));
+ } else {
+ event_T event;
+ AutoPat *ap;
+ int in_use = false;
+
+ for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ event = (event_T)((int)event + 1)) {
+ for (ap = first_autopat[(int)event]; ap != NULL; ap = ap->next) {
+ if (ap->group == i && ap->pat != NULL) {
+ give_warning((char_u *)
+ _("W19: Deleting augroup that is still in use"), true);
+ in_use = true;
+ event = NUM_EVENTS;
+ break;
+ }
+ }
+ }
xfree(AUGROUP_NAME(i));
- AUGROUP_NAME(i) = NULL;
+ if (in_use) {
+ AUGROUP_NAME(i) = (char *)get_deleted_augroup();
+ } else {
+ AUGROUP_NAME(i) = NULL;
+ }
}
}
@@ -5495,8 +5742,9 @@ static void au_del_group(char_u *name)
static int au_find_group(const char_u *name)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- for (int i = 0; i < augroups.ga_len; ++i) {
- if (AUGROUP_NAME(i) != NULL && STRCMP(AUGROUP_NAME(i), name) == 0) {
+ for (int i = 0; i < augroups.ga_len; i++) {
+ if (AUGROUP_NAME(i) != NULL && AUGROUP_NAME(i) != get_deleted_augroup()
+ && STRCMP(AUGROUP_NAME(i), name) == 0) {
return i;
}
}
@@ -5533,7 +5781,7 @@ void do_augroup(char_u *arg, int del_group)
for (int i = 0; i < augroups.ga_len; ++i) {
if (AUGROUP_NAME(i) != NULL) {
msg_puts(AUGROUP_NAME(i));
- msg_puts((char_u *)" ");
+ msg_puts(" ");
}
}
msg_clr_eos();
@@ -5545,11 +5793,18 @@ void do_augroup(char_u *arg, int del_group)
void free_all_autocmds(void)
{
for (current_augroup = -1; current_augroup < augroups.ga_len;
- ++current_augroup)
- do_autocmd((char_u *)"", TRUE);
- ga_clear_strings(&augroups);
-}
+ current_augroup++) {
+ do_autocmd((char_u *)"", true);
+ }
+ for (int i = 0; i < augroups.ga_len; i++) {
+ char *const s = ((char **)(augroups.ga_data))[i];
+ if ((const char *)s != get_deleted_augroup()) {
+ xfree(s);
+ }
+ }
+ ga_clear(&augroups);
+}
#endif
/*
@@ -5557,39 +5812,47 @@ void free_all_autocmds(void)
* Return NUM_EVENTS if the event name was not found.
* Return a pointer to the next event name in "end".
*/
-static event_T event_name2nr(char_u *start, char_u **end)
+static event_T event_name2nr(const char_u *start, char_u **end)
{
- char_u *p;
+ const char_u *p;
int i;
int len;
- /* the event name ends with end of line, a blank or a comma */
- for (p = start; *p && !ascii_iswhite(*p) && *p != ','; ++p)
- ;
- for (i = 0; event_names[i].name != NULL; ++i) {
- len = (int) event_names[i].len;
- if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0)
+ // the event name ends with end of line, '|', a blank or a comma
+ for (p = start; *p && !ascii_iswhite(*p) && *p != ',' && *p != '|'; p++) {
+ }
+ for (i = 0; event_names[i].name != NULL; i++) {
+ len = (int)event_names[i].len;
+ if (len == p - start && STRNICMP(event_names[i].name, start, len) == 0) {
break;
+ }
+ }
+ if (*p == ',') {
+ p++;
}
- if (*p == ',')
- ++p;
- *end = p;
- if (event_names[i].name == NULL)
+ *end = (char_u *)p;
+ if (event_names[i].name == NULL) {
return NUM_EVENTS;
+ }
return event_names[i].event;
}
-/*
- * Return the name for event "event".
- */
-static char_u *event_nr2name(event_T event)
+/// Return the name for event
+///
+/// @param[in] event Event to return name for.
+///
+/// @return Event name, static string. Returns "Unknown" for unknown events.
+static const char *event_nr2name(event_T event)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST
{
int i;
- for (i = 0; event_names[i].name != NULL; ++i)
- if (event_names[i].event == event)
- return (char_u *)event_names[i].name;
- return (char_u *)"Unknown";
+ for (i = 0; event_names[i].name != NULL; i++) {
+ if (event_names[i].event == event) {
+ return event_names[i].name;
+ }
+ }
+ return "Unknown";
}
/*
@@ -5611,7 +5874,7 @@ find_end_event (
}
pat = arg + 1;
} else {
- for (pat = arg; *pat && !ascii_iswhite(*pat); pat = p) {
+ for (pat = arg; *pat && *pat != '|' && !ascii_iswhite(*pat); pat = p) {
if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) {
if (have_group)
EMSG2(_("E216: No such event: %s"), pat);
@@ -5702,19 +5965,19 @@ void au_event_restore(char_u *old_ei)
* will be automatically executed for <event>
* when editing a file matching <pat>, in
* the current group.
- * :autocmd <event> <pat> Show the auto-commands associated with
+ * :autocmd <event> <pat> Show the autocommands associated with
* <event> and <pat>.
- * :autocmd <event> Show the auto-commands associated with
+ * :autocmd <event> Show the autocommands associated with
* <event>.
- * :autocmd Show all auto-commands.
- * :autocmd! <event> <pat> <cmd> Remove all auto-commands associated with
+ * :autocmd Show all autocommands.
+ * :autocmd! <event> <pat> <cmd> Remove all autocommands associated with
* <event> and <pat>, and add the command
* <cmd>, for the current group.
- * :autocmd! <event> <pat> Remove all auto-commands associated with
+ * :autocmd! <event> <pat> Remove all autocommands associated with
* <event> and <pat> for the current group.
- * :autocmd! <event> Remove all auto-commands associated with
+ * :autocmd! <event> Remove all autocommands associated with
* <event> for the current group.
- * :autocmd! Remove ALL auto-commands for the current
+ * :autocmd! Remove ALL autocommands for the current
* group.
*
* Multiple events and patterns may be given separated by commas. Here are
@@ -5726,20 +5989,23 @@ void au_event_restore(char_u *old_ei)
*
* Mostly a {group} argument can optionally appear before <event>.
*/
-void do_autocmd(char_u *arg, int forceit)
+void do_autocmd(char_u *arg_in, int forceit)
{
+ char_u *arg = arg_in;
char_u *pat;
char_u *envpat = NULL;
char_u *cmd;
- event_T event;
- int need_free = FALSE;
- int nested = FALSE;
+ int need_free = false;
+ int nested = false;
int group;
- /*
- * Check for a legal group name. If not, use AUGROUP_ALL.
- */
- group = au_get_grouparg(&arg);
+ if (*arg == '|') {
+ arg = (char_u *)"";
+ group = AUGROUP_ALL; // no argument, use all groups
+ } else {
+ // Check for a legal group name. If not, use AUGROUP_ALL.
+ group = au_get_grouparg(&arg);
+ }
/*
* Scan over the events.
@@ -5749,73 +6015,78 @@ void do_autocmd(char_u *arg, int forceit)
if (pat == NULL)
return;
- /*
- * Scan over the pattern. Put a NUL at the end.
- */
pat = skipwhite(pat);
- cmd = pat;
- while (*cmd && (!ascii_iswhite(*cmd) || cmd[-1] == '\\'))
- cmd++;
- if (*cmd)
- *cmd++ = NUL;
-
- /* Expand environment variables in the pattern. Set 'shellslash', we want
- * forward slashes here. */
- if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) {
+ if (*pat == '|') {
+ pat = (char_u *)"";
+ cmd = (char_u *)"";
+ } else {
+ // Scan over the pattern. Put a NUL at the end.
+ cmd = pat;
+ while (*cmd && (!ascii_iswhite(*cmd) || cmd[-1] == '\\')) {
+ cmd++;
+ }
+ if (*cmd) {
+ *cmd++ = NUL;
+ }
+
+ // Expand environment variables in the pattern. Set 'shellslash', we want
+ // forward slashes here.
+ if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) {
#ifdef BACKSLASH_IN_FILENAME
- int p_ssl_save = p_ssl;
+ int p_ssl_save = p_ssl;
- p_ssl = TRUE;
+ p_ssl = true;
#endif
- envpat = expand_env_save(pat);
+ envpat = expand_env_save(pat);
#ifdef BACKSLASH_IN_FILENAME
- p_ssl = p_ssl_save;
+ p_ssl = p_ssl_save;
#endif
- if (envpat != NULL)
- pat = envpat;
- }
+ if (envpat != NULL) {
+ pat = envpat;
+ }
+ }
- /*
- * Check for "nested" flag.
- */
- cmd = skipwhite(cmd);
- if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && ascii_iswhite(cmd[6])) {
- nested = TRUE;
- cmd = skipwhite(cmd + 6);
- }
+ // Check for "nested" flag.
+ cmd = skipwhite(cmd);
+ if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0
+ && ascii_iswhite(cmd[6])) {
+ nested = true;
+ cmd = skipwhite(cmd + 6);
+ }
- /*
- * Find the start of the commands.
- * Expand <sfile> in it.
- */
- if (*cmd != NUL) {
- cmd = expand_sfile(cmd);
- if (cmd == NULL) /* some error */
- return;
- need_free = TRUE;
+ // Find the start of the commands.
+ // Expand <sfile> in it.
+ if (*cmd != NUL) {
+ cmd = expand_sfile(cmd);
+ if (cmd == NULL) { // some error
+ return;
+ }
+ need_free = true;
+ }
}
/*
* Print header when showing autocommands.
*/
if (!forceit && *cmd == NUL) {
- /* Highlight title */
- MSG_PUTS_TITLE(_("\n--- Auto-Commands ---"));
+ // Highlight title
+ MSG_PUTS_TITLE(_("\n--- Autocommands ---"));
}
/*
* Loop over the events.
*/
- last_event = (event_T)-1; /* for listing the event name */
- last_group = AUGROUP_ERROR; /* for listing the group name */
- if (*arg == '*' || *arg == NUL) {
- for (event = (event_T)0; (int)event < (int)NUM_EVENTS;
- event = (event_T)((int)event + 1))
- if (do_autocmd_event(event, pat,
- nested, cmd, forceit, group) == FAIL)
+ last_event = (event_T)-1; // for listing the event name
+ last_group = AUGROUP_ERROR; // for listing the group name
+ if (*arg == '*' || *arg == NUL || *arg == '|') {
+ for (event_T event = (event_T)0; (int)event < (int)NUM_EVENTS;
+ event = (event_T)((int)event + 1)) {
+ if (do_autocmd_event(event, pat, nested, cmd, forceit, group) == FAIL) {
break;
+ }
+ }
} else {
- while (*arg && !ascii_iswhite(*arg)) {
+ while (*arg && *arg != '|' && !ascii_iswhite(*arg)) {
event_T event = event_name2nr(arg, &arg);
assert(event < NUM_EVENTS);
if (do_autocmd_event(event, pat, nested, cmd, forceit, group) == FAIL) {
@@ -5842,7 +6113,8 @@ static int au_get_grouparg(char_u **argp)
char_u *arg = *argp;
int group = AUGROUP_ALL;
- p = skiptowhite(arg);
+ for (p = arg; *p && !ascii_iswhite(*p) && *p != '|'; p++) {
+ }
if (p > arg) {
group_name = vim_strnsave(arg, (int)(p - arg));
group = au_find_group(group_name);
@@ -5950,10 +6222,13 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd,
patlen = (int)STRLEN(buflocal_pat); /* but not endpat */
}
- /*
- * Find AutoPat entries with this pattern.
- */
- prev_ap = &first_autopat[(int)event];
+ // Find AutoPat entries with this pattern. When adding a command it
+ // always goes at or after the last one, so start at the end.
+ if (!forceit && *cmd != NUL && last_autopat[(int)event] != NULL) {
+ prev_ap = &last_autopat[(int)event];
+ } else {
+ prev_ap = &first_autopat[(int)event];
+ }
while ((ap = *prev_ap) != NULL) {
if (ap->pat != NULL) {
/* Accept a pattern when:
@@ -6010,8 +6285,8 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd,
/* refuse to add buffer-local ap if buffer number is invalid */
if (is_buflocal && (buflocal_nr == 0
|| buflist_findnr(buflocal_nr) == NULL)) {
- EMSGN(_("E680: <buffer=%d>: invalid buffer number "),
- buflocal_nr);
+ emsgf(_("E680: <buffer=%d>: invalid buffer number "),
+ buflocal_nr);
return FAIL;
}
@@ -6039,6 +6314,7 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd,
}
ap->cmds = NULL;
*prev_ap = ap;
+ last_autopat[(int)event] = ap;
ap->next = NULL;
if (group == AUGROUP_ALL)
ap->group = current_augroup;
@@ -6072,13 +6348,18 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd,
int
do_doautocmd (
char_u *arg,
- int do_msg /* give message for no matching autocmds? */
+ int do_msg, // give message for no matching autocmds?
+ bool *did_something
)
{
char_u *fname;
int nothing_done = TRUE;
int group;
+ if (did_something != NULL) {
+ *did_something = false;
+ }
+
/*
* Check for a legal group name. If not, use AUGROUP_ALL.
*/
@@ -6099,16 +6380,20 @@ do_doautocmd (
fname = skipwhite(fname);
- /*
- * Loop over the events.
- */
- while (*arg && !ascii_iswhite(*arg))
- if (apply_autocmds_group(event_name2nr(arg, &arg),
- fname, NULL, TRUE, group, curbuf, NULL))
- nothing_done = FALSE;
+ // Loop over the events.
+ while (*arg && !ends_excmd(*arg) && !ascii_iswhite(*arg)) {
+ if (apply_autocmds_group(event_name2nr(arg, &arg), fname, NULL, true,
+ group, curbuf, NULL)) {
+ nothing_done = false;
+ }
+ }
- if (nothing_done && do_msg)
+ if (nothing_done && do_msg) {
MSG(_("No matching autocommands"));
+ }
+ if (did_something != NULL) {
+ *did_something = !nothing_done;
+ }
return aborting() ? FAIL : OK;
}
@@ -6122,6 +6407,7 @@ void ex_doautoall(exarg_T *eap)
aco_save_T aco;
char_u *arg = eap->arg;
int call_do_modelines = check_nomodeline(&arg);
+ bufref_T bufref;
/*
* This is a bit tricky: For some commands curwin->w_buffer needs to be
@@ -6134,25 +6420,28 @@ void ex_doautoall(exarg_T *eap)
if (buf->b_ml.ml_mfp == NULL) {
continue;
}
- /* find a window for this buffer and save some values */
+ // Find a window for this buffer and save some values.
aucmd_prepbuf(&aco, buf);
+ set_bufref(&bufref, buf);
- /* execute the autocommands for this buffer */
- retval = do_doautocmd(arg, FALSE);
+ bool did_aucmd;
+ // execute the autocommands for this buffer
+ retval = do_doautocmd(arg, false, &did_aucmd);
- if (call_do_modelines) {
- /* Execute the modeline settings, but don't set window-local
- * options if we are using the current window for another
- * buffer. */
+ if (call_do_modelines && did_aucmd) {
+ // Execute the modeline settings, but don't set window-local
+ // options if we are using the current window for another
+ // buffer.
do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0);
}
/* restore the current window */
aucmd_restbuf(&aco);
- /* stop if there is some error or buffer was deleted */
- if (retval == FAIL || !buf_valid(buf))
+ // Stop if there is some error or buffer was deleted.
+ if (retval == FAIL || !bufref_valid(&bufref)) {
break;
+ }
}
check_cursor(); /* just in case lines got deleted */
@@ -6259,30 +6548,27 @@ aucmd_prepbuf (
}
curbuf = buf;
aco->new_curwin = curwin;
- aco->new_curbuf = curbuf;
+ set_bufref(&aco->new_curbuf, curbuf);
}
-/*
- * Cleanup after executing autocommands for a (hidden) buffer.
- * Restore the window as it was (if possible).
- */
-void
-aucmd_restbuf (
- aco_save_T *aco /* structure holding saved values */
-)
+/// Cleanup after executing autocommands for a (hidden) buffer.
+/// Restore the window as it was (if possible).
+///
+/// @param aco structure holding saved values
+void aucmd_restbuf(aco_save_T *aco)
{
int dummy;
if (aco->use_aucmd_win) {
- --curbuf->b_nwindows;
- /* Find "aucmd_win", it can't be closed, but it may be in another tab
- * page. Do not trigger autocommands here. */
+ curbuf->b_nwindows--;
+ // Find "aucmd_win", it can't be closed, but it may be in another tab page.
+ // Do not trigger autocommands here.
block_autocmds();
if (curwin != aucmd_win) {
FOR_ALL_TAB_WINDOWS(tp, wp) {
if (wp == aucmd_win) {
if (tp != curtab) {
- goto_tabpage_tp(tp, TRUE, TRUE);
+ goto_tabpage_tp(tp, true, true);
}
win_goto(aucmd_win);
goto win_found;
@@ -6291,49 +6577,56 @@ aucmd_restbuf (
}
win_found:
- /* Remove the window and frame from the tree of frames. */
+ // Remove the window and frame from the tree of frames.
(void)winframe_remove(curwin, &dummy, NULL);
win_remove(curwin, NULL);
- aucmd_win_used = FALSE;
- last_status(FALSE); /* may need to remove last status line */
- restore_snapshot(SNAP_AUCMD_IDX, FALSE);
- (void)win_comp_pos(); /* recompute window positions */
+ aucmd_win_used = false;
+ last_status(false); // may need to remove last status line
+
+ if (!valid_tabpage_win(curtab)) {
+ // no valid window in current tabpage
+ close_tabpage(curtab);
+ }
+
+ restore_snapshot(SNAP_AUCMD_IDX, false);
+ (void)win_comp_pos(); // recompute window positions
unblock_autocmds();
- if (win_valid(aco->save_curwin))
+ if (win_valid(aco->save_curwin)) {
curwin = aco->save_curwin;
- else
- /* Hmm, original window disappeared. Just use the first one. */
+ } else {
+ // Hmm, original window disappeared. Just use the first one.
curwin = firstwin;
- vars_clear(&aucmd_win->w_vars->dv_hashtab); /* free all w: variables */
- hash_init(&aucmd_win->w_vars->dv_hashtab); /* re-use the hashtab */
+ }
+ vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
+ hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
curbuf = curwin->w_buffer;
xfree(globaldir);
globaldir = aco->globaldir;
- /* the buffer contents may have changed */
+ // the buffer contents may have changed
check_cursor();
if (curwin->w_topline > curbuf->b_ml.ml_line_count) {
curwin->w_topline = curbuf->b_ml.ml_line_count;
curwin->w_topfill = 0;
}
} else {
- /* restore curwin */
+ // restore curwin
if (win_valid(aco->save_curwin)) {
- /* Restore the buffer which was previously edited by curwin, if
- * it was changed, we are still the same window and the buffer is
- * valid. */
+ // Restore the buffer which was previously edited by curwin, if it was
+ // changed, we are still the same window and the buffer is valid.
if (curwin == aco->new_curwin
- && curbuf != aco->new_curbuf
- && buf_valid(aco->new_curbuf)
- && aco->new_curbuf->b_ml.ml_mfp != NULL) {
- if (curwin->w_s == &curbuf->b_s)
- curwin->w_s = &aco->new_curbuf->b_s;
- --curbuf->b_nwindows;
- curbuf = aco->new_curbuf;
+ && curbuf != aco->new_curbuf.br_buf
+ && bufref_valid(&aco->new_curbuf)
+ && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) {
+ if (curwin->w_s == &curbuf->b_s) {
+ curwin->w_s = &aco->new_curbuf.br_buf->b_s;
+ }
+ curbuf->b_nwindows--;
+ curbuf = aco->new_curbuf.br_buf;
curwin->w_buffer = curbuf;
- ++curbuf->b_nwindows;
+ curbuf->b_nwindows++;
}
curwin = aco->save_curwin;
@@ -6439,7 +6732,7 @@ bool trigger_cursorhold(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
/// Return true if "event" autocommand is defined.
///
/// @param event the autocommand to check
-bool has_event(int event) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+bool has_event(event_T event) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
return first_autopat[event] != NULL;
}
@@ -6468,7 +6761,6 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
char_u *save_sourcing_name;
linenr_T save_sourcing_lnum;
char_u *save_autocmd_fname;
- int save_autocmd_fname_full;
int save_autocmd_bufnr;
char_u *save_autocmd_match;
int save_autocmd_busy;
@@ -6483,13 +6775,15 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
static int filechangeshell_busy = FALSE;
proftime_T wait_time;
bool did_save_redobuff = false;
+ save_redo_T save_redo;
+ const bool save_KeyTyped = KeyTyped;
- /*
- * Quickly return if there are no autocommands for this event or
- * autocommands are blocked.
- */
- if (first_autopat[(int)event] == NULL || autocmd_blocked > 0)
+ // Quickly return if there are no autocommands for this event or
+ // autocommands are blocked.
+ if (event == NUM_EVENTS || first_autopat[(int)event] == NULL
+ || autocmd_blocked > 0) {
goto BYPASS_AU;
+ }
/*
* When autocommands are busy, new autocommands are only executed when
@@ -6541,7 +6835,6 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
* Save the autocmd_* variables and info about the current buffer.
*/
save_autocmd_fname = autocmd_fname;
- save_autocmd_fname_full = autocmd_fname_full;
save_autocmd_bufnr = autocmd_bufnr;
save_autocmd_match = autocmd_match;
save_autocmd_busy = autocmd_busy;
@@ -6555,19 +6848,24 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
* invalid.
*/
if (fname_io == NULL) {
- if (event == EVENT_COLORSCHEME || event == EVENT_OPTIONSET)
+ if (event == EVENT_COLORSCHEME
+ || event == EVENT_COLORSCHEMEPRE
+ || event == EVENT_OPTIONSET) {
autocmd_fname = NULL;
- else if (fname != NULL && *fname != NUL)
+ } else if (fname != NULL && !ends_excmd(*fname)) {
autocmd_fname = fname;
- else if (buf != NULL)
+ } else if (buf != NULL) {
autocmd_fname = buf->b_ffname;
- else
+ } else {
autocmd_fname = NULL;
- } else
+ }
+ } else {
autocmd_fname = fname_io;
- if (autocmd_fname != NULL)
- autocmd_fname = vim_strsave(autocmd_fname);
- autocmd_fname_full = FALSE; /* call FullName_save() later */
+ }
+ if (autocmd_fname != NULL) {
+ // Allocate MAXPATHL for when eval_vars() resolves the fullpath.
+ autocmd_fname = vim_strnsave(autocmd_fname, MAXPATHL);
+ }
/*
* Set the buffer number to be used for <abuf>.
@@ -6601,8 +6899,16 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
fname = vim_strsave(fname); /* make a copy, so we can change it */
} else {
sfname = vim_strsave(fname);
- // don't try expanding the following events
- if (event == EVENT_COLORSCHEME
+ // Don't try expanding the following events.
+ if (event == EVENT_CMDLINECHANGED
+ || event == EVENT_CMDLINEENTER
+ || event == EVENT_CMDLINELEAVE
+ || event == EVENT_CMDWINENTER
+ || event == EVENT_CMDWINLEAVE
+ || event == EVENT_CMDUNDEFINED
+ || event == EVENT_COLORSCHEME
+ || event == EVENT_COLORSCHEMEPRE
+ || event == EVENT_DIRCHANGED
|| event == EVENT_FILETYPE
|| event == EVENT_FUNCUNDEFINED
|| event == EVENT_OPTIONSET
@@ -6611,10 +6917,11 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
|| event == EVENT_REMOTEREPLY
|| event == EVENT_SPELLFILEMISSING
|| event == EVENT_SYNTAX
- || event == EVENT_TABCLOSED)
+ || event == EVENT_TABCLOSED) {
fname = vim_strsave(fname);
- else
- fname = (char_u *)FullName_save((char *)fname, FALSE);
+ } else {
+ fname = (char_u *)FullName_save((char *)fname, false);
+ }
}
if (fname == NULL) { /* out of memory */
xfree(sfname);
@@ -6638,8 +6945,8 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
autocmd_match = fname;
- /* Don't redraw while doing auto commands. */
- ++RedrawingDisabled;
+ // Don't redraw while doing autocommands.
+ RedrawingDisabled++;
save_sourcing_name = sourcing_name;
sourcing_name = NULL; /* don't free this one */
save_sourcing_lnum = sourcing_lnum;
@@ -6659,7 +6966,7 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
if (!autocmd_busy) {
save_search_patterns();
if (!ins_compl_active()) {
- saveRedobuff();
+ saveRedobuff(&save_redo);
did_save_redobuff = true;
}
did_filetype = keep_filetype;
@@ -6696,8 +7003,8 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
patcmd.next = active_apc_list;
active_apc_list = &patcmd;
- /* set v:cmdarg (only when there is a matching pattern) */
- save_cmdbang = get_vim_var_nr(VV_CMDBANG);
+ // set v:cmdarg (only when there is a matching pattern)
+ save_cmdbang = (long)get_vim_var_nr(VV_CMDBANG);
if (eap != NULL) {
save_cmdarg = set_cmdarg(eap, NULL);
set_vim_var_nr(VV_CMDBANG, (long)eap->forceit);
@@ -6732,13 +7039,13 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
sourcing_lnum = save_sourcing_lnum;
xfree(autocmd_fname);
autocmd_fname = save_autocmd_fname;
- autocmd_fname_full = save_autocmd_fname_full;
autocmd_bufnr = save_autocmd_bufnr;
autocmd_match = save_autocmd_match;
current_SID = save_current_SID;
restore_funccal(save_funccalp);
if (do_profiling == PROF_YES)
prof_child_exit(&wait_time);
+ KeyTyped = save_KeyTyped;
xfree(fname);
xfree(sfname);
--nesting; /* see matching increment above */
@@ -6749,7 +7056,7 @@ static bool apply_autocmds_group(event_T event, char_u *fname, char_u *fname_io,
if (!autocmd_busy) {
restore_search_patterns();
if (did_save_redobuff) {
- restoreRedobuff();
+ restoreRedobuff(&save_redo);
}
did_filetype = FALSE;
while (au_pending_free_buf != NULL) {
@@ -6787,6 +7094,10 @@ BYPASS_AU:
if (event == EVENT_BUFWIPEOUT && buf != NULL)
aubuflocal_remove(buf);
+ if (retval == OK && event == EVENT_FILETYPE) {
+ au_did_filetype = true;
+ }
+
return retval;
}
@@ -6827,7 +7138,6 @@ auto_next_pat (
{
AutoPat *ap;
AutoCmd *cp;
- char_u *name;
char *s;
xfree(sourcing_name);
@@ -6846,11 +7156,13 @@ auto_next_pat (
? match_file_pat(NULL, &ap->reg_prog, apc->fname, apc->sfname,
apc->tail, ap->allow_dirs)
: ap->buflocal_nr == apc->arg_bufnr) {
- name = event_nr2name(apc->event);
- s = _("%s Auto commands for \"%s\"");
- sourcing_name = xmalloc(STRLEN(s) + STRLEN(name) + ap->patlen + 1);
- sprintf((char *)sourcing_name, s,
- (char *)name, (char *)ap->pat);
+ const char *const name = event_nr2name(apc->event);
+ s = _("%s Autocommands for \"%s\"");
+ const size_t sourcing_name_len = (STRLEN(s) + strlen(name) + ap->patlen
+ + 1);
+ sourcing_name = xmalloc(sourcing_name_len);
+ snprintf((char *)sourcing_name, sourcing_name_len, s, name,
+ (char *)ap->pat);
if (p_verbose >= 8) {
verbose_enter();
smsg(_("Executing %s"), sourcing_name);
@@ -6916,7 +7228,7 @@ char_u *getnextac(int c, void *cookie, int indent)
if (p_verbose >= 9) {
verbose_enter_scroll();
smsg(_("autocommand %s"), ac->cmd);
- msg_puts((char_u *)"\n"); /* don't overwrite this either */
+ msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
}
retval = vim_strsave(ac->cmd);
@@ -6982,13 +7294,17 @@ bool has_autocmd(event_T event, char_u *sfname, buf_T *buf)
*/
char_u *get_augroup_name(expand_T *xp, int idx)
{
- if (idx == augroups.ga_len) /* add "END" add the end */
+ if (idx == augroups.ga_len) { // add "END" add the end
return (char_u *)"END";
- if (idx >= augroups.ga_len) /* end of list */
+ }
+ if (idx >= augroups.ga_len) { // end of list
return NULL;
- if (AUGROUP_NAME(idx) == NULL) /* skip deleted entries */
+ }
+ if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == get_deleted_augroup()) {
+ // skip deleted entries
return (char_u *)"";
- return AUGROUP_NAME(idx); /* return a name */
+ }
+ return (char_u *)AUGROUP_NAME(idx);
}
static int include_groups = FALSE;
@@ -7045,21 +7361,27 @@ set_context_in_autocmd (
*/
char_u *get_event_name(expand_T *xp, int idx)
{
- if (idx < augroups.ga_len) { /* First list group names, if wanted */
- if (!include_groups || AUGROUP_NAME(idx) == NULL)
- return (char_u *)""; /* skip deleted entries */
- return AUGROUP_NAME(idx); /* return a name */
+ if (idx < augroups.ga_len) { // First list group names, if wanted
+ if (!include_groups || AUGROUP_NAME(idx) == NULL
+ || AUGROUP_NAME(idx) == get_deleted_augroup()) {
+ return (char_u *)""; // skip deleted entries
+ }
+ return (char_u *)AUGROUP_NAME(idx);
}
return (char_u *)event_names[idx - augroups.ga_len].name;
}
-/// Return true if autocmd "event" is supported.
-bool autocmd_supported(char_u *event)
+/// Check whether given autocommand is supported
+///
+/// @param[in] event Event to check.
+///
+/// @return True if it is, false otherwise.
+bool autocmd_supported(const char *const event)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
char_u *p;
-
- return event_name2nr(event, &p) != NUM_EVENTS;
+ return event_name2nr((const char_u *)event, &p) != NUM_EVENTS;
}
/// Return true if an autocommand is defined for a group, event and
@@ -7074,26 +7396,24 @@ bool autocmd_supported(char_u *event)
/// exists("#Event#pat")
///
/// @param arg autocommand string
-bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT
+bool au_exists(const char *const arg) FUNC_ATTR_WARN_UNUSED_RESULT
{
- char_u *arg_save;
- char_u *pattern = NULL;
- char_u *event_name;
- char_u *p;
event_T event;
AutoPat *ap;
buf_T *buflocal_buf = NULL;
int group;
bool retval = false;
- /* Make a copy so that we can change the '#' chars to a NUL. */
- arg_save = vim_strsave(arg);
- p = vim_strchr(arg_save, '#');
- if (p != NULL)
+ // Make a copy so that we can change the '#' chars to a NUL.
+ char *const arg_save = xstrdup(arg);
+ char *p = strchr(arg_save, '#');
+ if (p != NULL) {
*p++ = NUL;
+ }
- /* First, look for an autocmd group name */
- group = au_find_group(arg_save);
+ // First, look for an autocmd group name.
+ group = au_find_group((char_u *)arg_save);
+ char *event_name;
if (group == AUGROUP_ERROR) {
/* Didn't match a group name, assume the first argument is an event. */
group = AUGROUP_ALL;
@@ -7105,17 +7425,18 @@ bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT
goto theend;
}
- /* Must be "Group#Event" or "Group#Event#pat". */
+ // Must be "Group#Event" or "Group#Event#pat".
event_name = p;
- p = vim_strchr(event_name, '#');
- if (p != NULL)
- *p++ = NUL; /* "Group#Event#pat" */
+ p = strchr(event_name, '#');
+ if (p != NULL) {
+ *p++ = NUL; // "Group#Event#pat"
+ }
}
- pattern = p; /* "pattern" is NULL when there is no pattern */
+ char *pattern = p; // "pattern" is NULL when there is no pattern.
- /* find the index (enum) for the event name */
- event = event_name2nr(event_name, &p);
+ // Find the index (enum) for the event name.
+ event = event_name2nr((char_u *)event_name, (char_u **)&p);
/* return FALSE if the event name is not recognized */
if (event == NUM_EVENTS)
@@ -7141,7 +7462,7 @@ bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT
&& (group == AUGROUP_ALL || ap->group == group)
&& (pattern == NULL
|| (buflocal_buf == NULL
- ? fnamecmp(ap->pat, pattern) == 0
+ ? fnamecmp(ap->pat, (char_u *)pattern) == 0
: ap->buflocal_nr == buflocal_buf->b_fnum))) {
retval = true;
break;
diff --git a/src/nvim/fileio.h b/src/nvim/fileio.h
index d93f3f3eb3..8db4b89806 100644
--- a/src/nvim/fileio.h
+++ b/src/nvim/fileio.h
@@ -4,25 +4,28 @@
#include "nvim/buffer_defs.h"
#include "nvim/os/os.h"
-/* Values for readfile() flags */
-#define READ_NEW 0x01 /* read a file into a new buffer */
-#define READ_FILTER 0x02 /* read filter output */
-#define READ_STDIN 0x04 /* read from stdin */
-#define READ_BUFFER 0x08 /* read from curbuf (converting stdin) */
-#define READ_DUMMY 0x10 /* reading into a dummy buffer */
-#define READ_KEEP_UNDO 0x20 /* keep undo info*/
+// Values for readfile() flags
+#define READ_NEW 0x01 // read a file into a new buffer
+#define READ_FILTER 0x02 // read filter output
+#define READ_STDIN 0x04 // read from stdin
+#define READ_BUFFER 0x08 // read from curbuf (converting stdin)
+#define READ_DUMMY 0x10 // reading into a dummy buffer
+#define READ_KEEP_UNDO 0x20 // keep undo info
+#define READ_FIFO 0x40 // read from fifo or socket
+
+#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))
/*
* Struct to save values in before executing autocommands for a buffer that is
* not the current buffer.
*/
typedef struct {
- buf_T *save_curbuf; /* saved curbuf */
- int use_aucmd_win; /* using aucmd_win */
- win_T *save_curwin; /* saved curwin */
- win_T *new_curwin; /* new curwin */
- buf_T *new_curbuf; /* new curbuf */
- char_u *globaldir; /* saved value of globaldir */
+ buf_T *save_curbuf; ///< saved curbuf
+ int use_aucmd_win; ///< using aucmd_win
+ win_T *save_curwin; ///< saved curwin
+ win_T *new_curwin; ///< new curwin
+ bufref_T new_curbuf; ///< new curbuf
+ char_u *globaldir; ///< saved value of globaldir
} aco_save_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index ac3cf959c8..39975308d7 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.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
+
// vim: set fdm=marker fdl=1 fdc=3
/*
@@ -17,12 +20,12 @@
#include "nvim/ex_docmd.h"
#include "nvim/func_attr.h"
#include "nvim/indent.h"
+#include "nvim/buffer_updates.h"
#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/option.h"
@@ -30,6 +33,7 @@
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/undo.h"
+#include "nvim/ops.h"
/* local declarations. {{{1 */
/* typedef fold_T {{{2 */
@@ -40,14 +44,14 @@
* The info stored in both growarrays is the same: An array of fold_T.
*/
typedef struct {
- linenr_T fd_top; /* first line of fold; for nested fold
- * relative to parent */
- linenr_T fd_len; /* number of lines in the fold */
- garray_T fd_nested; /* array of nested folds */
- char fd_flags; /* see below */
- char fd_small; /* TRUE, FALSE or MAYBE: fold smaller than
- 'foldminlines'; MAYBE applies to nested
- folds too */
+ linenr_T fd_top; // first line of fold; for nested fold
+ // relative to parent
+ linenr_T fd_len; // number of lines in the fold
+ garray_T fd_nested; // array of nested folds
+ char fd_flags; // see below
+ TriState fd_small; // kTrue, kFalse, or kNone: fold smaller than
+ // 'foldminlines'; kNone applies to nested
+ // folds too
} fold_T;
#define FD_OPEN 0 /* fold is open (nested ones can be closed) */
@@ -72,8 +76,8 @@ typedef struct {
this line (copy of "end" of prev. line) */
} fline_T;
-/* Flag is set when redrawing is needed. */
-static int fold_changed;
+// Flag is set when redrawing is needed.
+static bool fold_changed;
/* Function used by foldUpdateIEMSRecurse */
typedef void (*LevelGetter)(fline_T *);
@@ -143,35 +147,32 @@ int hasAnyFolding(win_T *win)
*/
bool hasFolding(linenr_T lnum, linenr_T *firstp, linenr_T *lastp)
{
- return hasFoldingWin(curwin, lnum, firstp, lastp, TRUE, NULL);
+ return hasFoldingWin(curwin, lnum, firstp, lastp, true, NULL);
}
/* hasFoldingWin() {{{2 */
bool hasFoldingWin(
- win_T *win,
- linenr_T lnum,
- linenr_T *firstp,
- linenr_T *lastp,
- int cache, /* when TRUE: use cached values of window */
- foldinfo_T *infop /* where to store fold info */
+ win_T *const win,
+ const linenr_T lnum,
+ linenr_T *const firstp,
+ linenr_T *const lastp,
+ const bool cache, // when true: use cached values of window
+ foldinfo_T *const infop // where to store fold info
)
{
- int had_folded = FALSE;
+ bool had_folded = false;
linenr_T first = 0;
linenr_T last = 0;
linenr_T lnum_rel = lnum;
- int x;
fold_T *fp;
int level = 0;
- int use_level = FALSE;
- int maybe_small = FALSE;
- garray_T *gap;
- int low_level = 0;;
+ bool use_level = false;
+ bool maybe_small = false;
+ int low_level = 0;
checkupdate(win);
- /*
- * Return quickly when there is no folding at all in this window.
- */
+
+ // Return quickly when there is no folding at all in this window.
if (!hasAnyFolding(win)) {
if (infop != NULL)
infop->fi_level = 0;
@@ -183,7 +184,7 @@ bool hasFoldingWin(
* First look in cached info for displayed lines. This is probably
* the fastest, but it can only be used if the entry is still valid.
*/
- x = find_wl_entry(win, lnum);
+ const int x = find_wl_entry(win, lnum);
if (x >= 0) {
first = win->w_lines[x].wl_lnum;
last = win->w_lines[x].wl_lastlnum;
@@ -195,7 +196,7 @@ bool hasFoldingWin(
/*
* Recursively search for a fold that contains "lnum".
*/
- gap = &win->w_folds;
+ garray_T *gap = &win->w_folds;
for (;; ) {
if (!foldFind(gap, lnum_rel, &fp))
break;
@@ -270,14 +271,11 @@ int foldLevel(linenr_T lnum)
return foldLevelWin(curwin, lnum);
}
-/* lineFolded() {{{2 */
-/*
- * Low level function to check if a line is folded. Doesn't use any caching.
- * Return TRUE if line is folded.
- * Return FALSE if line is not folded.
- * Return MAYBE if the line is folded when next to a folded line.
- */
-int lineFolded(win_T *win, linenr_T lnum)
+// lineFolded() {{{2
+// Low level function to check if a line is folded. Doesn't use any caching.
+// Return true if line is folded.
+// Return false if line is not folded.
+bool lineFolded(win_T *const win, const linenr_T lnum)
{
return foldedCount(win, lnum, NULL) != 0;
}
@@ -295,8 +293,9 @@ long foldedCount(win_T *win, linenr_T lnum, foldinfo_T *infop)
{
linenr_T last;
- if (hasFoldingWin(win, lnum, NULL, &last, FALSE, infop))
+ if (hasFoldingWin(win, lnum, NULL, &last, false, infop)) {
return (long)(last - lnum + 1);
+ }
return 0;
}
@@ -378,13 +377,13 @@ void closeFoldRecurse(linenr_T lnum)
* Open or Close folds for current window in lines "first" to "last".
* Used for "zo", "zO", "zc" and "zC" in Visual mode.
*/
-void
-opFoldRange (
+void
+opFoldRange(
linenr_T first,
linenr_T last,
- int opening, /* TRUE to open, FALSE to close */
- int recurse, /* TRUE to do it recursively */
- int had_visual /* TRUE when Visual selection used */
+ int opening, // TRUE to open, FALSE to close
+ int recurse, // TRUE to do it recursively
+ int had_visual // TRUE when Visual selection used
)
{
int done = DONE_NOTHING; /* avoid error messages */
@@ -645,7 +644,7 @@ void foldCreate(linenr_T start, linenr_T end)
if (!use_level)
curwin->w_fold_manual = true;
fp->fd_flags = FD_CLOSED;
- fp->fd_small = MAYBE;
+ fp->fd_small = kNone;
/* redraw */
changed_window_setting();
@@ -659,36 +658,31 @@ void foldCreate(linenr_T start, linenr_T end)
* When "end" is not 0, delete all folds from "start" to "end".
* When "recursive" is TRUE delete recursively.
*/
-void
-deleteFold (
- linenr_T start,
- linenr_T end,
- int recursive,
- int had_visual /* TRUE when Visual selection used */
+void deleteFold(
+ const linenr_T start,
+ const linenr_T end,
+ const int recursive,
+ const bool had_visual // true when Visual selection used
)
{
- garray_T *gap;
fold_T *fp;
- garray_T *found_ga;
fold_T *found_fp = NULL;
linenr_T found_off = 0;
- int use_level;
- int maybe_small = FALSE;
+ bool maybe_small = false;
int level = 0;
linenr_T lnum = start;
- linenr_T lnum_off;
- int did_one = FALSE;
+ bool did_one = false;
linenr_T first_lnum = MAXLNUM;
linenr_T last_lnum = 0;
checkupdate(curwin);
while (lnum <= end) {
- /* Find the deepest fold for "start". */
- gap = &curwin->w_folds;
- found_ga = NULL;
- lnum_off = 0;
- use_level = FALSE;
+ // Find the deepest fold for "start".
+ garray_T *gap = &curwin->w_folds;
+ garray_T *found_ga = NULL;
+ linenr_T lnum_off = 0;
+ bool use_level = false;
for (;; ) {
if (!foldFind(gap, lnum - lnum_off, &fp))
break;
@@ -724,7 +718,7 @@ deleteFold (
parseMarker(curwin);
deleteFoldMarkers(found_fp, recursive, found_off);
}
- did_one = TRUE;
+ did_one = true;
/* redraw window */
changed_window_setting();
@@ -739,8 +733,20 @@ deleteFold (
/* Deleting markers may make cursor column invalid. */
check_cursor_col();
- if (last_lnum > 0)
- changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L);
+ if (last_lnum > 0) {
+ changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L, false);
+
+ // send one nvim_buf_lines_event at the end
+ if (kv_size(curbuf->update_channels)) {
+ // last_lnum is the line *after* the last line of the outermost fold
+ // that was modified. Note also that deleting a fold might only require
+ // the modification of the *first* line of the fold, but we send through a
+ // notification that includes every line that was part of the fold
+ int64_t num_changed = last_lnum - first_lnum;
+ buf_updates_send_changes(curbuf, first_lnum, num_changed,
+ num_changed, true);
+ }
+ }
}
/* clearFolding() {{{2 */
@@ -762,21 +768,17 @@ void clearFolding(win_T *win)
*/
void foldUpdate(win_T *wp, linenr_T top, linenr_T bot)
{
- if (compl_busy) {
- return;
- }
-
- fold_T *fp;
- if (wp->w_buffer->terminal) {
+ if (compl_busy || State & INSERT) {
return;
}
// Mark all folds from top to bot as maybe-small.
+ fold_T *fp;
(void)foldFind(&wp->w_folds, top, &fp);
while (fp < (fold_T *)wp->w_folds.ga_data + wp->w_folds.ga_len
&& fp->fd_top < bot) {
- fp->fd_small = MAYBE;
- ++fp;
+ fp->fd_small = kNone;
+ fp++;
}
if (foldmethodIsIndent(wp)
@@ -793,6 +795,19 @@ void foldUpdate(win_T *wp, linenr_T top, linenr_T bot)
}
}
+/// Updates folds when leaving insert-mode.
+void foldUpdateAfterInsert(void)
+{
+ if (foldmethodIsManual(curwin) // foldmethod=manual: No need to update.
+ // These foldmethods are too slow, do not auto-update on insert-leave.
+ || foldmethodIsSyntax(curwin) || foldmethodIsExpr(curwin)) {
+ return;
+ }
+
+ foldUpdateAll(curwin);
+ foldOpenCursor();
+}
+
/* foldUpdateAll() {{{2 */
/*
* Update all lines in a window for folding.
@@ -806,44 +821,34 @@ void foldUpdateAll(win_T *win)
redraw_win_later(win, NOT_VALID);
}
-/* foldMoveTo() {{{2 */
-/*
- * If "updown" is FALSE: Move to the start or end of the fold.
- * If "updown" is TRUE: move to fold at the same level.
- * If not moved return FAIL.
- */
-int
-foldMoveTo (
- int updown,
- int dir, /* FORWARD or BACKWARD */
- long count
+// foldMoveTo() {{{2
+//
+// If "updown" is false: Move to the start or end of the fold.
+// If "updown" is true: move to fold at the same level.
+// If not moved return FAIL.
+int foldMoveTo(
+ const bool updown,
+ const int dir, // FORWARD or BACKWARD
+ const long count
)
{
- long n;
int retval = FAIL;
- linenr_T lnum_off;
- linenr_T lnum_found;
linenr_T lnum;
- int use_level;
- int maybe_small;
- garray_T *gap;
fold_T *fp;
- int level;
- int last;
checkupdate(curwin);
- /* Repeat "count" times. */
- for (n = 0; n < count; ++n) {
- /* Find nested folds. Stop when a fold is closed. The deepest fold
- * that moves the cursor is used. */
- lnum_off = 0;
- gap = &curwin->w_folds;
- use_level = FALSE;
- maybe_small = FALSE;
- lnum_found = curwin->w_cursor.lnum;
- level = 0;
- last = FALSE;
+ // Repeat "count" times.
+ for (long n = 0; n < count; n++) {
+ // Find nested folds. Stop when a fold is closed. The deepest fold
+ // that moves the cursor is used.
+ linenr_T lnum_off = 0;
+ garray_T *gap = &curwin->w_folds;
+ bool use_level = false;
+ bool maybe_small = false;
+ linenr_T lnum_found = curwin->w_cursor.lnum;
+ int level = 0;
+ bool last = false;
for (;; ) {
if (!foldFind(gap, curwin->w_cursor.lnum - lnum_off, &fp)) {
if (!updown)
@@ -861,14 +866,15 @@ foldMoveTo (
}
/* don't look for contained folds, they will always move
* the cursor too far. */
- last = TRUE;
+ last = true;
}
if (!last) {
/* Check if this fold is closed. */
if (check_closed(curwin, fp, &use_level, level,
- &maybe_small, lnum_off))
- last = TRUE;
+ &maybe_small, lnum_off)) {
+ last = true;
+ }
/* "[z" and "]z" stop at closed fold */
if (last && !updown)
@@ -1131,11 +1137,11 @@ static void setFoldRepeat(linenr_T lnum, long count, int do_open)
* Open or close the fold in the current window which contains "lnum".
* Also does this for other windows in diff mode when needed.
*/
-static linenr_T
-setManualFold (
+static linenr_T
+setManualFold(
linenr_T lnum,
- int opening, /* TRUE when opening, FALSE when closing */
- int recurse, /* TRUE when closing/opening recursive */
+ int opening, // TRUE when opening, FALSE when closing
+ int recurse, // TRUE when closing/opening recursive
int *donep
)
{
@@ -1169,12 +1175,12 @@ setManualFold (
* Return the line number of the next line that could be closed.
* It's only valid when "opening" is TRUE!
*/
-static linenr_T
-setManualFoldWin (
+static linenr_T
+setManualFoldWin(
win_T *wp,
linenr_T lnum,
- int opening, /* TRUE when opening, FALSE when closing */
- int recurse, /* TRUE when closing/opening recursive */
+ int opening, // TRUE when opening, FALSE when closing
+ int recurse, // TRUE when closing/opening recursive
int *donep
)
{
@@ -1281,25 +1287,21 @@ static void foldOpenNested(fold_T *fpr)
}
}
-/* deleteFoldEntry() {{{2 */
-/*
- * Delete fold "idx" from growarray "gap".
- * When "recursive" is TRUE also delete all the folds contained in it.
- * When "recursive" is FALSE contained folds are moved one level up.
- */
-static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
+// deleteFoldEntry() {{{2
+// Delete fold "idx" from growarray "gap".
+// When "recursive" is true also delete all the folds contained in it.
+// When "recursive" is false contained folds are moved one level up.
+static void deleteFoldEntry(garray_T *const gap, const int idx,
+ const bool recursive)
{
- fold_T *fp;
- int i;
- fold_T *nfp;
-
- fp = (fold_T *)gap->ga_data + idx;
+ fold_T *fp = (fold_T *)gap->ga_data + idx;
if (recursive || GA_EMPTY(&fp->fd_nested)) {
- /* recursively delete the contained folds */
+ // recursively delete the contained folds
deleteFoldRecurse(&fp->fd_nested);
- --gap->ga_len;
- if (idx < gap->ga_len)
- memmove(fp, fp + 1, sizeof(fold_T) * (size_t)(gap->ga_len - idx));
+ gap->ga_len--;
+ if (idx < gap->ga_len) {
+ memmove(fp, fp + 1, sizeof(*fp) * (size_t)(gap->ga_len - idx));
+ }
} else {
/* Move nested folds one level up, to overwrite the fold that is
* deleted. */
@@ -1309,22 +1311,24 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
/* Get "fp" again, the array may have been reallocated. */
fp = (fold_T *)gap->ga_data + idx;
- /* adjust fd_top and fd_flags for the moved folds */
- nfp = (fold_T *)fp->fd_nested.ga_data;
- for (i = 0; i < moved; ++i) {
+ // adjust fd_top and fd_flags for the moved folds
+ fold_T *nfp = (fold_T *)fp->fd_nested.ga_data;
+ for (int i = 0; i < moved; i++) {
nfp[i].fd_top += fp->fd_top;
if (fp->fd_flags == FD_LEVEL)
nfp[i].fd_flags = FD_LEVEL;
- if (fp->fd_small == MAYBE)
- nfp[i].fd_small = MAYBE;
+ if (fp->fd_small == kNone) {
+ nfp[i].fd_small = kNone;
+ }
}
- /* move the existing folds down to make room */
- if (idx + 1 < gap->ga_len)
+ // move the existing folds down to make room
+ if (idx + 1 < gap->ga_len) {
memmove(fp + moved, fp + 1,
- sizeof(fold_T) * (size_t)(gap->ga_len - (idx + 1)));
- /* move the contained folds one level up */
- memmove(fp, nfp, sizeof(fold_T) * (size_t)moved);
+ sizeof(*fp) * (size_t)(gap->ga_len - (idx + 1)));
+ }
+ // move the contained folds one level up
+ memmove(fp, nfp, sizeof(*fp) * (size_t)moved);
xfree(nfp);
gap->ga_len += moved - 1;
}
@@ -1404,14 +1408,15 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2,
fp->fd_top += amount_after;
} else {
if (fp->fd_top >= top && last <= line2) {
- /* 4. fold completely contained in range */
+ // 4. fold completely contained in range
if (amount == MAXLNUM) {
- /* Deleting lines: delete the fold completely */
- deleteFoldEntry(gap, i, TRUE);
- --i; /* adjust index for deletion */
- --fp;
- } else
+ // Deleting lines: delete the fold completely
+ deleteFoldEntry(gap, i, true);
+ i--; // adjust index for deletion
+ fp--;
+ } else {
fp->fd_top += amount;
+ }
} else {
if (fp->fd_top < top) {
/* 2 or 3: need to correct nested folds too */
@@ -1430,13 +1435,16 @@ static void foldMarkAdjustRecurse(garray_T *gap, linenr_T line1, linenr_T line2,
} else {
/* 5. fold is below line1 and contains line2; need to
* correct nested folds too */
- foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
- line2 - fp->fd_top, amount,
- amount_after + (fp->fd_top - top));
if (amount == MAXLNUM) {
+ foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ line2 - fp->fd_top, amount,
+ amount_after + (fp->fd_top - top));
fp->fd_len -= line2 - fp->fd_top + 1;
fp->fd_top = line1;
} else {
+ foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ line2 - fp->fd_top, amount,
+ amount_after - amount);
fp->fd_len += amount_after - amount;
fp->fd_top += amount;
}
@@ -1477,36 +1485,40 @@ static int getDeepestNestingRecurse(garray_T *gap)
/*
* Check if a fold is closed and update the info needed to check nested folds.
*/
-static int
-check_closed (
- win_T *win,
- fold_T *fp,
- int *use_levelp, /* TRUE: outer fold had FD_LEVEL */
- int level, /* folding depth */
- int *maybe_smallp, /* TRUE: outer this had fd_small == MAYBE */
- linenr_T lnum_off /* line number offset for fp->fd_top */
+static bool check_closed(
+ win_T *const win,
+ fold_T *const fp,
+ bool *const use_levelp, // true: outer fold had FD_LEVEL
+ const int level, // folding depth
+ bool *const maybe_smallp, // true: outer this had fd_small == kNone
+ const linenr_T lnum_off // line number offset for fp->fd_top
)
{
- int closed = FALSE;
+ bool closed = false;
/* Check if this fold is closed. If the flag is FD_LEVEL this
* fold and all folds it contains depend on 'foldlevel'. */
if (*use_levelp || fp->fd_flags == FD_LEVEL) {
- *use_levelp = TRUE;
- if (level >= win->w_p_fdl)
- closed = TRUE;
- } else if (fp->fd_flags == FD_CLOSED)
- closed = TRUE;
-
- /* Small fold isn't closed anyway. */
- if (fp->fd_small == MAYBE)
- *maybe_smallp = TRUE;
+ *use_levelp = true;
+ if (level >= win->w_p_fdl) {
+ closed = true;
+ }
+ } else if (fp->fd_flags == FD_CLOSED) {
+ closed = true;
+ }
+
+ // Small fold isn't closed anyway.
+ if (fp->fd_small == kNone) {
+ *maybe_smallp = true;
+ }
if (closed) {
- if (*maybe_smallp)
- fp->fd_small = MAYBE;
+ if (*maybe_smallp) {
+ fp->fd_small = kNone;
+ }
checkSmall(win, fp, lnum_off);
- if (fp->fd_small == TRUE)
- closed = FALSE;
+ if (fp->fd_small == kTrue) {
+ closed = false;
+ }
}
return closed;
}
@@ -1515,45 +1527,40 @@ check_closed (
/*
* Update fd_small field of fold "fp".
*/
-static void
-checkSmall (
- win_T *wp,
- fold_T *fp,
- linenr_T lnum_off /* offset for fp->fd_top */
+static void
+checkSmall(
+ win_T *const wp,
+ fold_T *const fp,
+ const linenr_T lnum_off // offset for fp->fd_top
)
{
- int count;
- int n;
-
- if (fp->fd_small == MAYBE) {
- /* Mark any nested folds to maybe-small */
+ if (fp->fd_small == kNone) {
+ // Mark any nested folds to maybe-small
setSmallMaybe(&fp->fd_nested);
- if (fp->fd_len > curwin->w_p_fml)
- fp->fd_small = FALSE;
- else {
- count = 0;
- for (n = 0; n < fp->fd_len; ++n) {
+ if (fp->fd_len > curwin->w_p_fml) {
+ fp->fd_small = kFalse;
+ } else {
+ int count = 0;
+ for (int n = 0; n < fp->fd_len; n++) {
count += plines_win_nofold(wp, fp->fd_top + lnum_off + n);
if (count > curwin->w_p_fml) {
- fp->fd_small = FALSE;
+ fp->fd_small = kFalse;
return;
}
}
- fp->fd_small = TRUE;
+ fp->fd_small = kTrue;
}
}
}
-/* setSmallMaybe() {{{2 */
-/*
- * Set small flags in "gap" to MAYBE.
- */
+// setSmallMaybe() {{{2
+// Set small flags in "gap" to kNone.
static void setSmallMaybe(garray_T *gap)
{
fold_T *fp = (fold_T *)gap->ga_data;
- for (int i = 0; i < gap->ga_len; ++i) {
- fp[i].fd_small = MAYBE;
+ for (int i = 0; i < gap->ga_len; i++) {
+ fp[i].fd_small = kNone;
}
}
@@ -1575,36 +1582,47 @@ static void foldCreateMarkers(linenr_T start, linenr_T end)
/* Update both changes here, to avoid all folds after the start are
* changed when the start marker is inserted and the end isn't. */
- changed_lines(start, (colnr_T)0, end, 0L);
+ changed_lines(start, (colnr_T)0, end, 0L, false);
+
+ if (kv_size(curbuf->update_channels)) {
+ // Note: foldAddMarker() may not actually change start and/or end if
+ // u_save() is unable to save the buffer line, but we send the
+ // nvim_buf_lines_event anyway since it won't do any harm.
+ int64_t num_changed = 1 + end - start;
+ buf_updates_send_changes(curbuf, start, num_changed, num_changed, true);
+ }
}
/* foldAddMarker() {{{2 */
/*
* Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/
-static void foldAddMarker(linenr_T lnum, char_u *marker, size_t markerlen)
+static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen)
{
char_u *cms = curbuf->b_p_cms;
char_u *line;
char_u *newline;
char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
+ bool line_is_comment = false;
- /* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */
+ // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
line = ml_get(lnum);
size_t line_len = STRLEN(line);
if (u_save(lnum - 1, lnum + 1) == OK) {
+ // Check if the line ends with an unclosed comment
+ skip_comment(line, false, false, &line_is_comment);
newline = xmalloc(line_len + markerlen + STRLEN(cms) + 1);
STRCPY(newline, line);
- if (p == NULL)
+ // Append the marker to the end of the line
+ if (p == NULL || line_is_comment) {
STRLCPY(newline + line_len, marker, markerlen + 1);
- else {
+ } else {
STRCPY(newline + line_len, cms);
- STRNCPY(newline + line_len + (p - cms), marker, markerlen);
+ memcpy(newline + line_len + (p - cms), marker, markerlen);
STRCPY(newline + line_len + (p - cms) + markerlen, p + 2);
}
-
- ml_replace(lnum, newline, FALSE);
+ ml_replace(lnum, newline, false);
}
}
@@ -1612,11 +1630,11 @@ static void foldAddMarker(linenr_T lnum, char_u *marker, size_t markerlen)
/*
* Delete the markers for a fold, causing it to be deleted.
*/
-static void
-deleteFoldMarkers (
+static void
+deleteFoldMarkers(
fold_T *fp,
int recursive,
- linenr_T lnum_off /* offset for fp->fd_top */
+ linenr_T lnum_off // offset for fp->fd_top
)
{
if (recursive) {
@@ -1665,20 +1683,19 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
if (u_save(lnum - 1, lnum + 1) == OK) {
/* Make new line: text-before-marker + text-after-marker */
newline = xmalloc(STRLEN(line) - len + 1);
- STRNCPY(newline, line, p - line);
+ assert(p >= line);
+ memcpy(newline, line, (size_t)(p - line));
STRCPY(newline + (p - line), p + len);
- ml_replace(lnum, newline, FALSE);
+ ml_replace(lnum, newline, false);
}
break;
}
}
-/* get_foldtext() {{{2 */
-/*
- * Return the text for a closed fold at line "lnum", with last line "lnume".
- * When 'foldtext' isn't set puts the result in "buf[51]". Otherwise the
- * result is in allocated memory.
- */
+// get_foldtext() {{{2
+/// Return the text for a closed fold at line "lnum", with last line "lnume".
+/// When 'foldtext' isn't set puts the result in "buf[FOLD_TEXT_LEN]".
+/// Otherwise the result is in allocated memory.
char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
foldinfo_T *foldinfo, char_u *buf)
FUNC_ATTR_NONNULL_ARG(1)
@@ -1745,12 +1762,13 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
if (text != NULL) {
/* Replace unprintable characters, if there are any. But
* replace a TAB with a space. */
- for (p = text; *p != NUL; ++p) {
- int len;
+ for (p = text; *p != NUL; p++) {
+ int len = utfc_ptr2len(p);
- if (has_mbyte && (len = (*mb_ptr2len)(p)) > 1) {
- if (!vim_isprintc((*mb_ptr2char)(p)))
+ if (len > 1) {
+ if (!vim_isprintc(utf_ptr2char(p))) {
break;
+ }
p += len - 1;
} else if (*p == TAB)
*p = ' ';
@@ -1758,15 +1776,19 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
break;
}
if (*p != NUL) {
- p = transstr(text);
+ p = (char_u *)transstr((const char *)text);
xfree(text);
text = p;
}
}
}
if (text == NULL) {
- sprintf((char *)buf, _("+--%3ld lines folded "),
- (long)(lnume - lnum + 1));
+ unsigned long count = (unsigned long)(lnume - lnum + 1);
+
+ vim_snprintf((char *)buf, FOLD_TEXT_LEN,
+ NGETTEXT("+--%3ld line folded",
+ "+--%3ld lines folded ", count),
+ count);
text = buf;
}
return text;
@@ -1841,7 +1863,7 @@ void foldtext_cleanup(char_u *str)
++len;
STRMOVE(s, s + len);
} else {
- mb_ptr_adv(s);
+ MB_PTR_ADV(s);
}
}
}
@@ -1854,13 +1876,10 @@ void foldtext_cleanup(char_u *str)
* Update the folding for window "wp", at least from lines "top" to "bot".
* Return TRUE if any folds did change.
*/
-static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
+static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot)
{
- linenr_T start;
- linenr_T end;
fline_T fline;
void (*getlevel)(fline_T *);
- int level;
fold_T *fp;
/* Avoid problems when being called recursively. */
@@ -1886,12 +1905,13 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
bot += diff_context;
}
- /* When deleting lines at the end of the buffer "top" can be past the end
- * of the buffer. */
- if (top > wp->w_buffer->b_ml.ml_line_count)
+ // When deleting lines at the end of the buffer "top" can be past the end
+ // of the buffer.
+ if (top > wp->w_buffer->b_ml.ml_line_count) {
top = wp->w_buffer->b_ml.ml_line_count;
+ }
- fold_changed = FALSE;
+ fold_changed = false;
fline.wp = wp;
fline.off = 0;
fline.lvl = 0;
@@ -1912,8 +1932,8 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
/* Need to get the level of the line above top, it is used if there is
* no marker at the top. */
if (top > 1) {
- /* Get the fold level at top - 1. */
- level = foldLevelWin(wp, top - 1);
+ // Get the fold level at top - 1.
+ const int level = foldLevelWin(wp, top - 1);
/* The fold may end just above the top, check for that. */
fline.lnum = top - 1;
@@ -1989,11 +2009,12 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
}
}
- start = fline.lnum;
- end = bot;
- /* Do at least one line. */
- if (start > end && end < wp->w_buffer->b_ml.ml_line_count)
+ linenr_T start = fline.lnum;
+ linenr_T end = bot;
+ // Do at least one line.
+ if (start > end && end < wp->w_buffer->b_ml.ml_line_count) {
end = start;
+ }
while (!got_int) {
/* Always stop at the end of the file ("end" can be past the end of
* the file). */
@@ -2084,22 +2105,21 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
* Returns bot, which may have been increased for lines that also need to be
* updated as a result of a detected change in the fold.
*/
-static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
- linenr_T startlnum, fline_T *flp,
- LevelGetter getlevel,
- linenr_T bot,
- char topflags /* containing fold flags */
- )
+static linenr_T foldUpdateIEMSRecurse(
+ garray_T *const gap, const int level, const linenr_T startlnum,
+ fline_T *const flp, LevelGetter getlevel, linenr_T bot,
+ const char topflags // containing fold flags
+)
{
linenr_T ll;
fold_T *fp = NULL;
fold_T *fp2;
int lvl = level;
linenr_T startlnum2 = startlnum;
- linenr_T firstlnum = flp->lnum; /* first lnum we got */
+ const linenr_T firstlnum = flp->lnum; // first lnum we got
int i;
- int finish = FALSE;
- linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off;
+ bool finish = false;
+ const linenr_T linecount = flp->wp->w_buffer->b_ml.ml_line_count - flp->off;
int concat;
/*
@@ -2216,57 +2236,86 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
* before where we started looking, extend it. If it
* starts at another line, update nested folds to keep
* their position, compensating for the new fd_top. */
- if (fp->fd_top >= startlnum && fp->fd_top != firstlnum) {
- if (fp->fd_top > firstlnum)
- /* like lines are inserted */
+ if (fp->fd_top == firstlnum) {
+ // We have found a fold beginning exactly where we want one.
+ } else if (fp->fd_top >= startlnum) {
+ if (fp->fd_top > firstlnum) {
+ // We will move the start of this fold up, hence we move all
+ // nested folds (with relative line numbers) down.
foldMarkAdjustRecurse(&fp->fd_nested,
- (linenr_T)0, (linenr_T)MAXLNUM,
- (long)(fp->fd_top - firstlnum), 0L);
- else
- /* like lines are deleted */
+ (linenr_T)0, (linenr_T)MAXLNUM,
+ (long)(fp->fd_top - firstlnum), 0L);
+ } else {
+ // Will move fold down, move nested folds relatively up.
foldMarkAdjustRecurse(&fp->fd_nested,
- (linenr_T)0,
- (long)(firstlnum - fp->fd_top - 1),
- (linenr_T)MAXLNUM,
- (long)(fp->fd_top - firstlnum));
+ (linenr_T)0,
+ (long)(firstlnum - fp->fd_top - 1),
+ (linenr_T)MAXLNUM,
+ (long)(fp->fd_top - firstlnum));
+ }
fp->fd_len += fp->fd_top - firstlnum;
fp->fd_top = firstlnum;
- fold_changed = TRUE;
- } else if (flp->start != 0 && lvl == level
- && fp->fd_top != firstlnum) {
- /* Existing fold that includes startlnum must stop
- * if we find the start of a new fold at the same
- * level. Split it. Delete contained folds at
- * this point to split them too. */
- foldRemove(&fp->fd_nested, flp->lnum - fp->fd_top,
- flp->lnum - fp->fd_top);
+ fold_changed = true;
+ } else if ((flp->start != 0 && lvl == level)
+ || (firstlnum != startlnum)) {
+ // Before there was a fold spanning from above startlnum to below
+ // firstlnum. This fold is valid above startlnum (because we are
+ // not updating that range), but there is now a break in it.
+ // If the break is because we are now forced to start a new fold
+ // at the level "level" at line fline->lnum, then we need to
+ // split the fold at fline->lnum.
+ // If the break is because the range [startlnum, firstlnum) is
+ // now at a lower indent than "level", we need to split the fold
+ // in this range.
+ // Any splits have to be done recursively.
+ linenr_T breakstart;
+ linenr_T breakend;
+ if (firstlnum != startlnum) {
+ breakstart = startlnum;
+ breakend = firstlnum;
+ } else {
+ breakstart = flp->lnum;
+ breakend = flp->lnum;
+ }
+ foldRemove(&fp->fd_nested, breakstart - fp->fd_top,
+ breakend - fp->fd_top);
i = (int)(fp - (fold_T *)gap->ga_data);
- foldSplit(gap, i, flp->lnum, flp->lnum - 1);
+ foldSplit(gap, i, breakstart, breakend - 1);
fp = (fold_T *)gap->ga_data + i + 1;
/* If using the "marker" or "syntax" method, we
* need to continue until the end of the fold is
* found. */
if (getlevel == foldlevelMarker
|| getlevel == foldlevelExpr
- || getlevel == foldlevelSyntax)
- finish = TRUE;
+ || getlevel == foldlevelSyntax) {
+ finish = true;
+ }
+ }
+ if (fp->fd_top == startlnum && concat) {
+ i = (int)(fp - (fold_T *)gap->ga_data);
+ if (i != 0) {
+ fp2 = fp - 1;
+ if (fp2->fd_top + fp2->fd_len == fp->fd_top) {
+ foldMerge(fp2, gap, fp);
+ fp = fp2;
+ }
+ }
}
break;
}
if (fp->fd_top >= startlnum) {
- /* A fold that starts at or after startlnum and stops
- * before the new fold must be deleted. Continue
- * looking for the next one. */
- deleteFoldEntry(gap,
- (int)(fp - (fold_T *)gap->ga_data), TRUE);
+ // A fold that starts at or after startlnum and stops
+ // before the new fold must be deleted. Continue
+ // looking for the next one.
+ deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), true);
} else {
/* A fold has some lines above startlnum, truncate it
* to stop just above startlnum. */
fp->fd_len = startlnum - fp->fd_top;
foldMarkAdjustRecurse(&fp->fd_nested,
- (linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
- (linenr_T)MAXLNUM, 0L);
- fold_changed = TRUE;
+ (linenr_T)fp->fd_len, (linenr_T)MAXLNUM,
+ (linenr_T)MAXLNUM, 0L);
+ fold_changed = true;
}
} else {
/* Insert new fold. Careful: ga_data may be NULL and it
@@ -2290,14 +2339,15 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
flp->wp->w_fold_manual = true;
} else
fp->fd_flags = (fp - 1)->fd_flags;
- fp->fd_small = MAYBE;
- /* If using the "marker", "expr" or "syntax" method, we
- * need to continue until the end of the fold is found. */
+ fp->fd_small = kNone;
+ // If using the "marker", "expr" or "syntax" method, we
+ // need to continue until the end of the fold is found.
if (getlevel == foldlevelMarker
|| getlevel == foldlevelExpr
- || getlevel == foldlevelSyntax)
- finish = TRUE;
- fold_changed = TRUE;
+ || getlevel == foldlevelSyntax) {
+ finish = true;
+ }
+ fold_changed = true;
break;
}
}
@@ -2316,12 +2366,11 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
* Check "fp" for safety.
*/
if (lvl > level && fp != NULL) {
- /*
- * There is a nested fold, handle it recursively.
- */
- /* At least do one line (can happen when finish is TRUE). */
- if (bot < flp->lnum)
+ // There is a nested fold, handle it recursively.
+ // At least do one line (can happen when finish is true).
+ if (bot < flp->lnum) {
bot = flp->lnum;
+ }
/* Line numbers in the nested fold are relative to the start of
* this fold. */
@@ -2383,8 +2432,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
/* Current fold at least extends until lnum. */
if (fp->fd_len < flp->lnum - fp->fd_top) {
fp->fd_len = flp->lnum - fp->fd_top;
- fp->fd_small = MAYBE;
- fold_changed = TRUE;
+ fp->fd_small = kNone;
+ fold_changed = true;
}
/* Delete contained folds from the end of the last one found until where
@@ -2393,27 +2442,28 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
flp->lnum - 1 - fp->fd_top);
if (lvl < level) {
- /* End of fold found, update the length when it got shorter. */
+ // End of fold found, update the length when it got shorter.
if (fp->fd_len != flp->lnum - fp->fd_top) {
- if (fp->fd_top + fp->fd_len > bot + 1) {
- /* fold continued below bot */
+ if (fp->fd_top + fp->fd_len - 1 > bot) {
+ // fold continued below bot
if (getlevel == foldlevelMarker
|| getlevel == foldlevelExpr
|| getlevel == foldlevelSyntax) {
- /* marker method: truncate the fold and make sure the
- * previously included lines are processed again */
+ // marker method: truncate the fold and make sure the
+ // previously included lines are processed again
bot = fp->fd_top + fp->fd_len - 1;
fp->fd_len = flp->lnum - fp->fd_top;
} else {
- /* indent or expr method: split fold to create a new one
- * below bot */
+ // indent or expr method: split fold to create a new one
+ // below bot
i = (int)(fp - (fold_T *)gap->ga_data);
foldSplit(gap, i, flp->lnum, bot);
fp = (fold_T *)gap->ga_data + i;
}
- } else
+ } else {
fp->fd_len = flp->lnum - fp->fd_top;
- fold_changed = TRUE;
+ }
+ fold_changed = true;
}
}
@@ -2431,7 +2481,7 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
(linenr_T)MAXLNUM, (long)(fp2->fd_top - flp->lnum));
fp2->fd_len -= flp->lnum - fp2->fd_top;
fp2->fd_top = flp->lnum;
- fold_changed = TRUE;
+ fold_changed = true;
}
if (lvl >= level) {
@@ -2440,8 +2490,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
}
break;
}
- fold_changed = TRUE;
- deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
+ fold_changed = true;
+ deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
}
/* Need to redraw the lines we inspected, which might be further down than
@@ -2477,34 +2527,32 @@ static void foldInsert(garray_T *gap, int i)
* The caller must first have taken care of any nested folds from "top" to
* "bot"!
*/
-static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
+static void foldSplit(garray_T *const gap, const int i, const linenr_T top,
+ const linenr_T bot)
{
- fold_T *fp;
fold_T *fp2;
- garray_T *gap1;
- garray_T *gap2;
- int idx;
- int len;
/* The fold continues below bot, need to split it. */
foldInsert(gap, i + 1);
- fp = (fold_T *)gap->ga_data + i;
+ fold_T *const fp = (fold_T *)gap->ga_data + i;
fp[1].fd_top = bot + 1;
+ // check for wrap around (MAXLNUM, and 32bit)
+ assert(fp[1].fd_top > bot);
fp[1].fd_len = fp->fd_len - (fp[1].fd_top - fp->fd_top);
fp[1].fd_flags = fp->fd_flags;
- fp[1].fd_small = MAYBE;
- fp->fd_small = MAYBE;
+ fp[1].fd_small = kNone;
+ fp->fd_small = kNone;
/* Move nested folds below bot to new fold. There can't be
* any between top and bot, they have been removed by the caller. */
- gap1 = &fp->fd_nested;
- gap2 = &fp[1].fd_nested;
+ garray_T *const gap1 = &fp->fd_nested;
+ garray_T *const gap2 = &fp[1].fd_nested;
(void)(foldFind(gap1, bot + 1 - fp->fd_top, &fp2));
- len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
+ const int len = (int)((fold_T *)gap1->ga_data + gap1->ga_len - fp2);
if (len > 0) {
ga_grow(gap2, len);
- for (idx = 0; idx < len; ++idx) {
+ for (int idx = 0; idx < len; idx++) {
((fold_T *)gap2->ga_data)[idx] = fp2[idx];
((fold_T *)gap2->ga_data)[idx].fd_top
-= fp[1].fd_top - fp->fd_top;
@@ -2513,7 +2561,7 @@ static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
gap1->ga_len -= len;
}
fp->fd_len = top - fp->fd_top;
- fold_changed = TRUE;
+ fold_changed = true;
}
/* foldRemove() {{{2 */
@@ -2523,10 +2571,10 @@ static void foldSplit(garray_T *gap, int i, linenr_T top, linenr_T bot)
* 1 2 3
* 1 2 3
* top 2 3 4 5
- * 2 3 4 5
- * bot 2 3 4 5
- * 3 5 6
- * 3 5 6
+ * 2 3 4 5
+ * bot 2 3 4 5
+ * 3 5 6
+ * 3 5 6
*
* 1: not changed
* 2: truncate to stop above "top"
@@ -2539,34 +2587,35 @@ static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
{
fold_T *fp = NULL;
- if (bot < top)
- return; /* nothing to do */
+ if (bot < top) {
+ return; // nothing to do
+ }
for (;; ) {
- /* Find fold that includes top or a following one. */
+ // Find fold that includes top or a following one.
if (foldFind(gap, top, &fp) && fp->fd_top < top) {
- /* 2: or 3: need to delete nested folds */
+ // 2: or 3: need to delete nested folds
foldRemove(&fp->fd_nested, top - fp->fd_top, bot - fp->fd_top);
- if (fp->fd_top + fp->fd_len > bot + 1) {
- /* 3: need to split it. */
+ if (fp->fd_top + fp->fd_len - 1 > bot) {
+ // 3: need to split it.
foldSplit(gap, (int)(fp - (fold_T *)gap->ga_data), top, bot);
} else {
- /* 2: truncate fold at "top". */
+ // 2: truncate fold at "top".
fp->fd_len = top - fp->fd_top;
}
- fold_changed = TRUE;
+ fold_changed = true;
continue;
}
if (fp >= (fold_T *)(gap->ga_data) + gap->ga_len
|| fp->fd_top > bot) {
- /* 6: Found a fold below bot, can stop looking. */
+ // 6: Found a fold below bot, can stop looking.
break;
}
if (fp->fd_top >= top) {
- /* Found an entry below top. */
- fold_changed = TRUE;
+ // Found an entry below top.
+ fold_changed = true;
if (fp->fd_top + fp->fd_len - 1 > bot) {
- /* 5: Make fold that includes bot start below bot. */
+ // 5: Make fold that includes bot start below bot.
foldMarkAdjustRecurse(&fp->fd_nested,
(linenr_T)0, (long)(bot - fp->fd_top),
(linenr_T)MAXLNUM, (long)(fp->fd_top - bot - 1));
@@ -2575,11 +2624,170 @@ static void foldRemove(garray_T *gap, linenr_T top, linenr_T bot)
break;
}
- /* 4: Delete completely contained fold. */
- deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), TRUE);
+ // 4: Delete completely contained fold.
+ deleteFoldEntry(gap, (int)(fp - (fold_T *)gap->ga_data), true);
+ }
+ }
+}
+
+// foldReverseOrder() {{{2
+static void foldReverseOrder(
+ garray_T *gap,
+ const linenr_T start_arg,
+ const linenr_T end_arg)
+{
+ linenr_T start = start_arg;
+ linenr_T end = end_arg;
+ for (; start < end; start++, end--) {
+ fold_T *left = (fold_T *)gap->ga_data + start;
+ fold_T *right = (fold_T *)gap->ga_data + end;
+ fold_T tmp = *left;
+ *left = *right;
+ *right = tmp;
+ }
+}
+
+// foldMoveRange() {{{2
+// Move folds within the inclusive range "line1" to "line2" to after "dest"
+// require "line1" <= "line2" <= "dest"
+//
+// There are the following situations for the first fold at or below line1 - 1.
+// 1 2 3 4
+// 1 2 3 4
+// line1 2 3 4
+// 2 3 4 5 6 7
+// line2 3 4 5 6 7
+// 3 4 6 7 8 9
+// dest 4 7 8 9
+// 4 7 8 10
+// 4 7 8 10
+//
+// In the following descriptions, "moved" means moving in the buffer, *and* in
+// the fold array.
+// Meanwhile, "shifted" just means moving in the buffer.
+// 1. not changed
+// 2. truncated above line1
+// 3. length reduced by line2 - line1, folds starting between the end of 3 and
+// dest are truncated and shifted up
+// 4. internal folds moved (from [line1, line2] to dest)
+// 5. moved to dest.
+// 6. truncated below line2 and moved.
+// 7. length reduced by line2 - dest, folds starting between line2 and dest are
+// removed, top is moved down by move_len.
+// 8. truncated below dest and shifted up.
+// 9. shifted up
+// 10. not changed
+static void truncate_fold(fold_T *fp, linenr_T end)
+{
+ // I want to stop *at here*, foldRemove() stops *above* top
+ end += 1;
+ foldRemove(&fp->fd_nested, end - fp->fd_top, MAXLNUM);
+ fp->fd_len = end - fp->fd_top;
+}
+
+#define FOLD_END(fp) ((fp)->fd_top + (fp)->fd_len - 1)
+#define VALID_FOLD(fp, gap) ((fp) < ((fold_T *)(gap)->ga_data + (gap)->ga_len))
+#define FOLD_INDEX(fp, gap) ((size_t)(fp - ((fold_T *)(gap)->ga_data)))
+void foldMoveRange(garray_T *gap, const linenr_T line1, const linenr_T line2,
+ const linenr_T dest)
+{
+ fold_T *fp;
+ const linenr_T range_len = line2 - line1 + 1;
+ const linenr_T move_len = dest - line2;
+ const bool at_start = foldFind(gap, line1 - 1, &fp);
+
+ if (at_start) {
+ if (FOLD_END(fp) > dest) {
+ // Case 4 -- don't have to change this fold, but have to move nested
+ // folds.
+ foldMoveRange(&fp->fd_nested, line1 - fp->fd_top, line2 -
+ fp->fd_top, dest - fp->fd_top);
+ return;
+ } else if (FOLD_END(fp) > line2) {
+ // Case 3 -- Remove nested folds between line1 and line2 & reduce the
+ // length of fold by "range_len".
+ // Folds after this one must be dealt with.
+ foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
+ line2 - fp->fd_top, MAXLNUM, -range_len);
+ fp->fd_len -= range_len;
+ } else {
+ // Case 2 -- truncate fold *above* line1.
+ // Folds after this one must be dealt with.
+ truncate_fold(fp, line1 - 1);
+ }
+ // Look at the next fold, and treat that one as if it were the first after
+ // "line1" (because now it is).
+ fp = fp + 1;
+ }
+
+ if (!VALID_FOLD(fp, gap) || fp->fd_top > dest) {
+ // No folds after "line1" and before "dest"
+ // Case 10.
+ return;
+ } else if (fp->fd_top > line2) {
+ for (; VALID_FOLD(fp, gap) && FOLD_END(fp) <= dest; fp++) {
+ // Case 9. (for all case 9's) -- shift up.
+ fp->fd_top -= range_len;
+ }
+ if (VALID_FOLD(fp, gap) && fp->fd_top <= dest) {
+ // Case 8. -- ensure truncated at dest, shift up
+ truncate_fold(fp, dest);
+ fp->fd_top -= range_len;
+ }
+ return;
+ } else if (FOLD_END(fp) > dest) {
+ // Case 7 -- remove nested folds and shrink
+ foldMarkAdjustRecurse(&fp->fd_nested, line2 + 1 - fp->fd_top,
+ dest - fp->fd_top, MAXLNUM, -move_len);
+ fp->fd_len -= move_len;
+ fp->fd_top += move_len;
+ return;
+ }
+
+ // Case 5 or 6: changes rely on whether there are folds between the end of
+ // this fold and "dest".
+ size_t move_start = FOLD_INDEX(fp, gap);
+ size_t move_end = 0, dest_index = 0;
+ for (; VALID_FOLD(fp, gap) && fp->fd_top <= dest; fp++) {
+ if (fp->fd_top <= line2) {
+ // 5, or 6
+ if (FOLD_END(fp) > line2) {
+ // 6, truncate before moving
+ truncate_fold(fp, line2);
+ }
+ fp->fd_top += move_len;
+ continue;
+ }
+
+ // Record index of the first fold after the moved range.
+ if (move_end == 0) {
+ move_end = FOLD_INDEX(fp, gap);
}
+
+ if (FOLD_END(fp) > dest) {
+ truncate_fold(fp, dest);
+ }
+
+ fp->fd_top -= range_len;
+ }
+ dest_index = FOLD_INDEX(fp, gap);
+
+ // All folds are now correct, but not necessarily in the correct order.
+ // We must swap folds in the range [move_end, dest_index) with those in the
+ // range [move_start, move_end).
+ if (move_end == 0) {
+ // There are no folds after those moved, so none were moved out of order.
+ return;
}
+ foldReverseOrder(gap, (linenr_T)move_start, (linenr_T)(dest_index - 1));
+ foldReverseOrder(gap, (linenr_T)move_start,
+ (linenr_T)(move_start + dest_index - move_end - 1));
+ foldReverseOrder(gap, (linenr_T)(move_start + dest_index - move_end),
+ (linenr_T)(dest_index - 1));
}
+#undef FOLD_END
+#undef VALID_FOLD
+#undef FOLD_INDEX
/* foldMerge() {{{2 */
/*
@@ -2615,8 +2823,8 @@ static void foldMerge(fold_T *fp1, garray_T *gap, fold_T *fp2)
}
fp1->fd_len += fp2->fd_len;
- deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), TRUE);
- fold_changed = TRUE;
+ deleteFoldEntry(gap, (int)(fp2 - (fold_T *)gap->ga_data), true);
+ fold_changed = true;
}
/* foldlevelIndent() {{{2 */
@@ -2642,8 +2850,9 @@ static void foldlevelIndent(fline_T *flp)
flp->lvl = 0;
else
flp->lvl = -1;
- } else
- flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(curbuf);
+ } else {
+ flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(buf);
+ }
if (flp->lvl > flp->wp->w_p_fdn) {
flp->lvl = (int) MAX(0, flp->wp->w_p_fdn);
}
@@ -2674,7 +2883,6 @@ static void foldlevelExpr(fline_T *flp)
int n;
int c;
linenr_T lnum = flp->lnum + flp->off;
- int save_keytyped;
win = curwin;
curwin = flp->wp;
@@ -2689,8 +2897,8 @@ static void foldlevelExpr(fline_T *flp)
/* KeyTyped may be reset to 0 when calling a function which invokes
* do_cmdline(). To make 'foldopen' work correctly restore KeyTyped. */
- save_keytyped = KeyTyped;
- n = eval_foldexpr(flp->wp->w_p_fde, &c);
+ const bool save_keytyped = KeyTyped;
+ n = (int)eval_foldexpr(flp->wp->w_p_fde, &c);
KeyTyped = save_keytyped;
switch (c) {
@@ -2829,10 +3037,12 @@ static void foldlevelMarker(fline_T *flp)
if (flp->lvl_next > start_lvl)
flp->lvl_next = start_lvl;
}
- } else
- --flp->lvl_next;
- } else
- mb_ptr_adv(s);
+ } else {
+ flp->lvl_next--;
+ }
+ } else {
+ MB_PTR_ADV(s);
+ }
}
/* The level can't go negative, must be missing a start marker. */
diff --git a/src/nvim/fold.h b/src/nvim/fold.h
index 2ff10c0e91..f35b328fb1 100644
--- a/src/nvim/fold.h
+++ b/src/nvim/fold.h
@@ -1,7 +1,12 @@
#ifndef NVIM_FOLD_H
#define NVIM_FOLD_H
+#include <stdio.h>
+
#include "nvim/pos.h"
+#include "nvim/garray.h"
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
/*
* Info used to pass info about a fold from the fold-detection code to the
diff --git a/src/nvim/func_attr.h b/src/nvim/func_attr.h
index ea017ab0c8..6e5e47c060 100644
--- a/src/nvim/func_attr.h
+++ b/src/nvim/func_attr.h
@@ -41,9 +41,7 @@
// $ gcc -E -dM - </dev/null
// $ echo | clang -dM -E -
-#ifndef NVIM_FUNC_ATTR_H
-#define NVIM_FUNC_ATTR_H
-#undef NVIM_FUNC_ATTR_H
+#include "nvim/macros.h"
#ifdef FUNC_ATTR_MALLOC
# undef FUNC_ATTR_MALLOC
@@ -93,11 +91,22 @@
# undef FUNC_ATTR_NONNULL_RET
#endif
+#ifdef FUNC_ATTR_NORETURN
+# undef FUNC_ATTR_NORETURN
+#endif
+
+#ifdef FUNC_ATTR_NO_SANITIZE_UNDEFINED
+# undef FUNC_ATTR_NO_SANITIZE_UNDEFINED
+#endif
+
+#ifdef FUNC_ATTR_PRINTF
+# undef FUNC_ATTR_PRINTF
+#endif
+
#ifndef DID_REAL_ATTR
# define DID_REAL_ATTR
# ifdef __GNUC__
-// place defines for all gnulikes here, for now that's gcc, clang and
-// intel.
+// For all gnulikes: gcc, clang, intel.
// place these after the argument list of the function declaration
// (not definition), like so:
@@ -111,27 +120,28 @@
# define REAL_FATTR_UNUSED __attribute__((unused))
# define REAL_FATTR_NONNULL_ALL __attribute__((nonnull))
# define REAL_FATTR_NONNULL_ARG(...) __attribute__((nonnull(__VA_ARGS__)))
+# define REAL_FATTR_NORETURN __attribute__((noreturn))
+# define REAL_FATTR_PRINTF(x, y) __attribute__((format (printf, x, y)))
+
+# if NVIM_HAS_ATTRIBUTE(returns_nonnull)
+# define REAL_FATTR_NONNULL_RET __attribute__((returns_nonnull))
+# endif
-# ifdef __clang__
-// clang only
-# elif defined(__INTEL_COMPILER)
-// intel only
-# else
-# define GCC_VERSION \
- (__GNUC__ * 10000 + \
- __GNUC_MINOR__ * 100 + \
- __GNUC_PATCHLEVEL__)
-// gcc only
+# if NVIM_HAS_ATTRIBUTE(alloc_size)
# define REAL_FATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
# define REAL_FATTR_ALLOC_SIZE_PROD(x, y) __attribute__((alloc_size(x, y)))
-# if GCC_VERSION >= 40900
-# define REAL_FATTR_NONNULL_RET __attribute__((returns_nonnull))
-# endif
+# endif
+
+# if NVIM_HAS_ATTRIBUTE(no_sanitize_undefined)
+# define REAL_FATTR_NO_SANITIZE_UNDEFINED \
+ __attribute__((no_sanitize_undefined))
+# elif NVIM_HAS_ATTRIBUTE(no_sanitize)
+# define REAL_FATTR_NO_SANITIZE_UNDEFINED \
+ __attribute__((no_sanitize("undefined")))
# endif
# endif
-// define function attributes that haven't been defined for this specific
-// compiler.
+// Define attributes that are not defined for this compiler.
# ifndef REAL_FATTR_MALLOC
# define REAL_FATTR_MALLOC
@@ -180,11 +190,26 @@
# ifndef REAL_FATTR_NONNULL_RET
# define REAL_FATTR_NONNULL_RET
# endif
+
+# ifndef REAL_FATTR_NORETURN
+# define REAL_FATTR_NORETURN
+# endif
+
+# ifndef REAL_FATTR_NO_SANITIZE_UNDEFINED
+# define REAL_FATTR_NO_SANITIZE_UNDEFINED
+# endif
+
+# ifndef REAL_FATTR_PRINTF
+# define REAL_FATTR_PRINTF(x, y)
+# endif
#endif
#ifdef DEFINE_FUNC_ATTRIBUTES
# define FUNC_API_ASYNC
# define FUNC_API_NOEXPORT
+# define FUNC_API_REMOTE_ONLY
+# define FUNC_API_SINCE(X)
+# define FUNC_API_DEPRECATED_SINCE(X)
# define FUNC_ATTR_MALLOC REAL_FATTR_MALLOC
# define FUNC_ATTR_ALLOC_SIZE(x) REAL_FATTR_ALLOC_SIZE(x)
# define FUNC_ATTR_ALLOC_SIZE_PROD(x, y) REAL_FATTR_ALLOC_SIZE_PROD(x, y)
@@ -197,6 +222,9 @@
# define FUNC_ATTR_NONNULL_ALL REAL_FATTR_NONNULL_ALL
# define FUNC_ATTR_NONNULL_ARG(...) REAL_FATTR_NONNULL_ARG(__VA_ARGS__)
# define FUNC_ATTR_NONNULL_RET REAL_FATTR_NONNULL_RET
+# define FUNC_ATTR_NORETURN REAL_FATTR_NORETURN
+# define FUNC_ATTR_NO_SANITIZE_UNDEFINED REAL_FATTR_NO_SANITIZE_UNDEFINED
+# define FUNC_ATTR_PRINTF(x, y) REAL_FATTR_PRINTF(x, y)
#elif !defined(DO_NOT_DEFINE_EMPTY_ATTRIBUTES)
# define FUNC_ATTR_MALLOC
# define FUNC_ATTR_ALLOC_SIZE(x)
@@ -210,5 +238,7 @@
# define FUNC_ATTR_NONNULL_ALL
# define FUNC_ATTR_NONNULL_ARG(...)
# define FUNC_ATTR_NONNULL_RET
+# define FUNC_ATTR_NORETURN
+# define FUNC_ATTR_NO_SANITIZE_UNDEFINED
+# define FUNC_ATTR_PRINTF(x, y)
#endif
-#endif // NVIM_FUNC_ATTR_H
diff --git a/src/nvim/garray.c b/src/nvim/garray.c
index 98cec69b54..2d2af54c95 100644
--- a/src/nvim/garray.c
+++ b/src/nvim/garray.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
+
/// @file garray.c
///
/// Functions for handling growing arrays.
@@ -8,7 +11,6 @@
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/log.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/path.h"
#include "nvim/garray.h"
diff --git a/src/nvim/garray.h b/src/nvim/garray.h
index 5d7806bbfa..58738df691 100644
--- a/src/nvim/garray.h
+++ b/src/nvim/garray.h
@@ -37,7 +37,7 @@ typedef struct growarray {
static inline void *ga_append_via_ptr(garray_T *gap, size_t item_size)
{
if ((int)item_size != gap->ga_itemsize) {
- ELOG("wrong item size in garray(%d), should be %d", item_size);
+ WLOG("wrong item size (%zu), should be %d", item_size, gap->ga_itemsize);
}
ga_grow(gap, 1);
return ((char *)gap->ga_data) + (item_size * (size_t)gap->ga_len++);
diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua
new file mode 100644
index 0000000000..d3047e1a9c
--- /dev/null
+++ b/src/nvim/generators/c_grammar.lua
@@ -0,0 +1,50 @@
+lpeg = require('lpeg')
+
+-- lpeg grammar for building api metadata from a set of header files. It
+-- ignores comments and preprocessor commands and parses a very small subset
+-- of C prototypes with a limited set of types
+local P, R, S = lpeg.P, lpeg.R, lpeg.S
+local C, Ct, Cc, Cg = lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg
+
+local any = P(1) -- (consume one character)
+local letter = R('az', 'AZ') + S('_$')
+local num = R('09')
+local alpha = letter + num
+local nl = P('\r\n') + P('\n')
+local not_nl = any - nl
+local ws = S(' \t') + nl
+local fill = ws ^ 0
+local c_comment = P('//') * (not_nl ^ 0)
+local c_preproc = P('#') * (not_nl ^ 0)
+local typed_container =
+ (P('ArrayOf(') + P('DictionaryOf(')) * ((any - P(')')) ^ 1) * P(')')
+local c_id = (
+ typed_container +
+ (letter * (alpha ^ 0))
+)
+local c_void = P('void')
+local c_param_type = (
+ ((P('Error') * fill * P('*') * fill) * Cc('error')) +
+ (C(c_id) * (ws ^ 1))
+ )
+local c_type = (C(c_void) * (ws ^ 1)) + c_param_type
+local c_param = Ct(c_param_type * C(c_id))
+local c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0)
+local c_params = Ct(c_void + c_param_list)
+local c_proto = Ct(
+ Cg(c_type, 'return_type') * Cg(c_id, 'name') *
+ fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') *
+ Cg(Cc(false), 'async') *
+ (fill * Cg((P('FUNC_API_SINCE(') * C(num ^ 1)) * P(')'), 'since') ^ -1) *
+ (fill * Cg((P('FUNC_API_DEPRECATED_SINCE(') * C(num ^ 1)) * P(')'),
+ 'deprecated_since') ^ -1) *
+ (fill * Cg((P('FUNC_API_ASYNC') * Cc(true)), 'async') ^ -1) *
+ (fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1) *
+ (fill * Cg((P('FUNC_API_REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1) *
+ (fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) *
+ (fill * Cg((P('FUNC_API_BRIDGE_IMPL') * Cc(true)), 'bridge_impl') ^ -1) *
+ fill * P(';')
+ )
+
+local grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1)
+return {grammar=grammar, typed_container=typed_container}
diff --git a/src/nvim/generators/dump_bin_array.lua b/src/nvim/generators/dump_bin_array.lua
new file mode 100644
index 0000000000..bee5aba73f
--- /dev/null
+++ b/src/nvim/generators/dump_bin_array.lua
@@ -0,0 +1,17 @@
+local function dump_bin_array(output, name, data)
+ output:write([[
+ static const uint8_t ]]..name..[[[] = {
+]])
+
+ for i = 1, #data do
+ output:write(string.byte(data, i)..', ')
+ if i % 10 == 0 then
+ output:write('\n ')
+ end
+ end
+ output:write([[
+};
+]])
+end
+
+return dump_bin_array
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
new file mode 100644
index 0000000000..bd9650e4d1
--- /dev/null
+++ b/src/nvim/generators/gen_api_dispatch.lua
@@ -0,0 +1,468 @@
+mpack = require('mpack')
+
+-- we need at least 4 arguments since the last two are output files
+if arg[1] == '--help' then
+ print('Usage: genmsgpack.lua args')
+ print('Args: 1: source directory')
+ print(' 2: dispatch output file (dispatch_wrappers.generated.h)')
+ print(' 3: functions metadata output file (funcs_metadata.generated.h)')
+ print(' 4: API metadata output file (api_metadata.mpack)')
+ print(' 5: lua C bindings output file (msgpack_lua_c_bindings.generated.c)')
+ print(' rest: C files where API functions are defined')
+end
+assert(#arg >= 4)
+functions = {}
+
+local nvimdir = arg[1]
+package.path = nvimdir .. '/?.lua;' .. package.path
+
+-- names of all headers relative to the source root (for inclusion in the
+-- generated file)
+headers = {}
+
+-- output h file with generated dispatch functions
+dispatch_outputf = arg[2]
+-- output h file with packed metadata
+funcs_metadata_outputf = arg[3]
+-- output metadata mpack file, for use by other build scripts
+mpack_outputf = arg[4]
+lua_c_bindings_outputf = arg[5]
+
+-- set of function names, used to detect duplicates
+function_names = {}
+
+c_grammar = require('generators.c_grammar')
+
+-- read each input file, parse and append to the api metadata
+for i = 6, #arg do
+ local full_path = arg[i]
+ local parts = {}
+ for part in string.gmatch(full_path, '[^/]+') do
+ parts[#parts + 1] = part
+ end
+ headers[#headers + 1] = parts[#parts - 1]..'/'..parts[#parts]
+
+ local input = io.open(full_path, 'rb')
+
+ local tmp = c_grammar.grammar:match(input:read('*all'))
+ for i = 1, #tmp do
+ local fn = tmp[i]
+ if not fn.noexport then
+ functions[#functions + 1] = tmp[i]
+ function_names[fn.name] = true
+ if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then
+ -- this function should receive the channel id
+ fn.receives_channel_id = true
+ -- remove the parameter since it won't be passed by the api client
+ table.remove(fn.parameters, 1)
+ end
+ if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'error' then
+ -- function can fail if the last parameter type is 'Error'
+ fn.can_fail = true
+ -- remove the error parameter, msgpack has it's own special field
+ -- for specifying errors
+ fn.parameters[#fn.parameters] = nil
+ end
+ end
+ end
+ input:close()
+end
+
+local function shallowcopy(orig)
+ local copy = {}
+ for orig_key, orig_value in pairs(orig) do
+ copy[orig_key] = orig_value
+ end
+ return copy
+end
+
+local function startswith(String,Start)
+ return string.sub(String,1,string.len(Start))==Start
+end
+
+-- Export functions under older deprecated names.
+-- These will be removed eventually.
+local deprecated_aliases = require("api.dispatch_deprecated")
+for i,f in ipairs(shallowcopy(functions)) do
+ local ismethod = false
+ if startswith(f.name, "nvim_") then
+ if startswith(f.name, "nvim__") then
+ f.since = -1
+ elseif f.since == nil then
+ print("Function "..f.name.." lacks since field.\n")
+ os.exit(1)
+ end
+ f.since = tonumber(f.since)
+ if f.deprecated_since ~= nil then
+ f.deprecated_since = tonumber(f.deprecated_since)
+ end
+
+ if startswith(f.name, "nvim_buf_") then
+ ismethod = true
+ elseif startswith(f.name, "nvim_win_") then
+ ismethod = true
+ elseif startswith(f.name, "nvim_tabpage_") then
+ ismethod = true
+ end
+ else
+ f.remote_only = true
+ f.since = 0
+ f.deprecated_since = 1
+ end
+ f.method = ismethod
+ local newname = deprecated_aliases[f.name]
+ if newname ~= nil then
+ if function_names[newname] then
+ -- duplicate
+ print("Function "..f.name.." has deprecated alias\n"
+ ..newname.." which has a separate implementation.\n"..
+ "Please remove it from src/nvim/api/dispatch_deprecated.lua")
+ os.exit(1)
+ end
+ local newf = shallowcopy(f)
+ newf.name = newname
+ if newname == "ui_try_resize" then
+ -- The return type was incorrectly set to Object in 0.1.5.
+ -- Keep it that way for clients that rely on this.
+ newf.return_type = "Object"
+ end
+ newf.impl_name = f.name
+ newf.remote_only = true
+ newf.since = 0
+ newf.deprecated_since = 1
+ functions[#functions+1] = newf
+ end
+end
+
+-- don't expose internal attributes like "impl_name" in public metadata
+exported_attributes = {'name', 'parameters', 'return_type', 'method',
+ 'since', 'deprecated_since'}
+exported_functions = {}
+for _,f in ipairs(functions) do
+ if not startswith(f.name, "nvim__") then
+ local f_exported = {}
+ for _,attr in ipairs(exported_attributes) do
+ f_exported[attr] = f[attr]
+ end
+ exported_functions[#exported_functions+1] = f_exported
+ end
+end
+
+
+-- serialize the API metadata using msgpack and embed into the resulting
+-- binary for easy querying by clients
+funcs_metadata_output = io.open(funcs_metadata_outputf, 'wb')
+packed = mpack.pack(exported_functions)
+dump_bin_array = require("generators.dump_bin_array")
+dump_bin_array(funcs_metadata_output, 'funcs_metadata', packed)
+funcs_metadata_output:close()
+
+-- start building the dispatch wrapper output
+output = io.open(dispatch_outputf, 'wb')
+
+local function real_type(type)
+ local rv = type
+ if c_grammar.typed_container:match(rv) then
+ if rv:match('Array') then
+ rv = 'Array'
+ else
+ rv = 'Dictionary'
+ end
+ end
+ return rv
+end
+
+local function attr_name(rt)
+ if rt == 'Float' then
+ return 'floating'
+ else
+ return rt:lower()
+ end
+end
+
+-- start the handler functions. Visit each function metadata to build the
+-- handler function with code generated for validating arguments and calling to
+-- the real API.
+for i = 1, #functions do
+ local fn = functions[i]
+ if fn.impl_name == nil then
+ local args = {}
+
+ output:write('Object handle_'..fn.name..'(uint64_t channel_id, Array args, Error *error)')
+ output:write('\n{')
+ output:write('\n#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL')
+ output:write('\n logmsg(DEBUG_LOG_LEVEL, "RPC: ", NULL, -1, true, "invoke '..fn.name..'");')
+ output:write('\n#endif')
+ output:write('\n Object ret = NIL;')
+ -- Declare/initialize variables that will hold converted arguments
+ for j = 1, #fn.parameters do
+ local param = fn.parameters[j]
+ local converted = 'arg_'..j
+ output:write('\n '..param[1]..' '..converted..';')
+ end
+ output:write('\n')
+ output:write('\n if (args.size != '..#fn.parameters..') {')
+ output:write('\n api_set_error(error, kErrorTypeException, "Wrong number of arguments: expecting '..#fn.parameters..' but got %zu", args.size);')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
+
+ -- Validation/conversion for each argument
+ for j = 1, #fn.parameters do
+ local converted, convert_arg, param, arg
+ param = fn.parameters[j]
+ converted = 'arg_'..j
+ local rt = real_type(param[1])
+ if rt ~= 'Object' then
+ if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') then
+ -- Buffer, Window, and Tabpage have a specific type, but are stored in integer
+ output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..' && args.items['..(j - 1)..'].data.integer >= 0) {')
+ output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;')
+ else
+ output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..') {')
+ output:write('\n '..converted..' = args.items['..(j - 1)..'].data.'..attr_name(rt)..';')
+ end
+ if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') or rt:match('^Boolean$') then
+ -- accept nonnegative integers for Booleans, Buffers, Windows and Tabpages
+ output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeInteger && args.items['..(j - 1)..'].data.integer >= 0) {')
+ output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;')
+ end
+ -- accept empty lua tables as empty dictionarys
+ if rt:match('^Dictionary') then
+ output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeArray && args.items['..(j - 1)..'].data.array.size == 0) {')
+ output:write('\n '..converted..' = (Dictionary)ARRAY_DICT_INIT;')
+ end
+ output:write('\n } else {')
+ output:write('\n api_set_error(error, kErrorTypeException, "Wrong type for argument '..j..', expecting '..param[1]..'");')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
+ else
+ output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
+ end
+
+ args[#args + 1] = converted
+ end
+
+ -- function call
+ local call_args = table.concat(args, ', ')
+ output:write('\n ')
+ if fn.return_type ~= 'void' then
+ -- has a return value, prefix the call with a declaration
+ output:write(fn.return_type..' rv = ')
+ end
+
+ -- write the function name and the opening parenthesis
+ output:write(fn.name..'(')
+
+ if fn.receives_channel_id then
+ -- if the function receives the channel id, pass it as first argument
+ if #args > 0 or fn.can_fail then
+ output:write('channel_id, '..call_args)
+ else
+ output:write('channel_id')
+ end
+ else
+ output:write(call_args)
+ end
+
+ if fn.can_fail then
+ -- if the function can fail, also pass a pointer to the local error object
+ if #args > 0 then
+ output:write(', error);\n')
+ else
+ output:write('error);\n')
+ end
+ -- and check for the error
+ output:write('\n if (ERROR_SET(error)) {')
+ output:write('\n goto cleanup;')
+ output:write('\n }\n')
+ else
+ output:write(');\n')
+ end
+
+ if fn.return_type ~= 'void' then
+ output:write('\n ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);')
+ end
+ output:write('\n\ncleanup:');
+
+ output:write('\n return ret;\n}\n\n');
+ end
+end
+
+-- Generate a function that initializes method names with handler functions
+output:write([[
+void msgpack_rpc_init_method_table(void)
+{
+ methods = map_new(String, MsgpackRpcRequestHandler)();
+
+]])
+
+for i = 1, #functions do
+ local fn = functions[i]
+ output:write(' msgpack_rpc_add_method_handler('..
+ '(String) {.data = "'..fn.name..'", '..
+ '.size = sizeof("'..fn.name..'") - 1}, '..
+ '(MsgpackRpcRequestHandler) {.fn = handle_'.. (fn.impl_name or fn.name)..
+ ', .async = '..tostring(fn.async)..'});\n')
+
+end
+
+output:write('\n}\n\n')
+output:close()
+
+mpack_output = io.open(mpack_outputf, 'wb')
+mpack_output:write(mpack.pack(functions))
+mpack_output:close()
+
+local function include_headers(output, headers)
+ for i = 1, #headers do
+ if headers[i]:sub(-12) ~= '.generated.h' then
+ output:write('\n#include "nvim/'..headers[i]..'"')
+ end
+ end
+end
+
+local function write_shifted_output(output, str)
+ str = str:gsub('\n ', '\n')
+ str = str:gsub('^ ', '')
+ str = str:gsub(' +$', '')
+ output:write(str)
+end
+
+-- start building lua output
+output = io.open(lua_c_bindings_outputf, 'wb')
+
+output:write([[
+// 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 <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "nvim/func_attr.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/lua/converter.h"
+]])
+include_headers(output, headers)
+output:write('\n')
+
+lua_c_functions = {}
+
+local function process_function(fn)
+ lua_c_function_name = ('nlua_msgpack_%s'):format(fn.name)
+ write_shifted_output(output, string.format([[
+
+ static int %s(lua_State *lstate)
+ {
+ Error err = ERROR_INIT;
+ if (lua_gettop(lstate) != %i) {
+ api_set_error(&err, kErrorTypeValidation, "Expected %i argument%s");
+ goto exit_0;
+ }
+ ]], lua_c_function_name, #fn.parameters, #fn.parameters,
+ (#fn.parameters == 1) and '' or 's'))
+ lua_c_functions[#lua_c_functions + 1] = {
+ binding=lua_c_function_name,
+ api=fn.name
+ }
+ local cparams = ''
+ local free_code = {}
+ for j = #fn.parameters,1,-1 do
+ param = fn.parameters[j]
+ cparam = string.format('arg%u', j)
+ param_type = real_type(param[1])
+ lc_param_type = param_type:lower()
+ write_shifted_output(output, string.format([[
+ const %s %s = nlua_pop_%s(lstate, &err);
+
+ if (ERROR_SET(&err)) {
+ goto exit_%u;
+ }
+ ]], param[1], cparam, param_type, #fn.parameters - j))
+ free_code[#free_code + 1] = ('api_free_%s(%s);'):format(
+ lc_param_type, cparam)
+ cparams = cparam .. ', ' .. cparams
+ end
+ if fn.receives_channel_id then
+ cparams = 'LUA_INTERNAL_CALL, ' .. cparams
+ end
+ if fn.can_fail then
+ cparams = cparams .. '&err'
+ else
+ cparams = cparams:gsub(', $', '')
+ end
+ local free_at_exit_code = ''
+ for i = 1, #free_code do
+ local rev_i = #free_code - i + 1
+ local code = free_code[rev_i]
+ if i == 1 then
+ free_at_exit_code = free_at_exit_code .. ('\n %s'):format(code)
+ else
+ free_at_exit_code = free_at_exit_code .. ('\n exit_%u:\n %s'):format(
+ rev_i, code)
+ end
+ end
+ local err_throw_code = [[
+
+ exit_0:
+ if (ERROR_SET(&err)) {
+ luaL_where(lstate, 1);
+ lua_pushstring(lstate, err.msg);
+ api_clear_error(&err);
+ lua_concat(lstate, 2);
+ return lua_error(lstate);
+ }
+ ]]
+ if fn.return_type ~= 'void' then
+ if fn.return_type:match('^ArrayOf') then
+ return_type = 'Array'
+ else
+ return_type = fn.return_type
+ end
+ write_shifted_output(output, string.format([[
+ const %s ret = %s(%s);
+ nlua_push_%s(lstate, ret);
+ api_free_%s(ret);
+ %s
+ %s
+ return 1;
+ ]], fn.return_type, fn.name, cparams, return_type, return_type:lower(),
+ free_at_exit_code, err_throw_code))
+ else
+ write_shifted_output(output, string.format([[
+ %s(%s);
+ %s
+ %s
+ return 0;
+ ]], fn.name, cparams, free_at_exit_code, err_throw_code))
+ end
+ write_shifted_output(output, [[
+ }
+ ]])
+end
+
+for _, fn in ipairs(functions) do
+ if not fn.remote_only or fn.name:sub(1, 4) == '_vim' then
+ process_function(fn)
+ end
+end
+
+output:write(string.format([[
+void nlua_add_api_functions(lua_State *lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_createtable(lstate, 0, %u);
+]], #lua_c_functions))
+for _, func in ipairs(lua_c_functions) do
+ output:write(string.format([[
+
+ lua_pushcfunction(lstate, &%s);
+ lua_setfield(lstate, -2, "%s");]], func.binding, func.api))
+end
+output:write([[
+
+ lua_setfield(lstate, -2, "api");
+}
+]])
+
+output:close()
diff --git a/src/nvim/generators/gen_api_ui_events.lua b/src/nvim/generators/gen_api_ui_events.lua
new file mode 100644
index 0000000000..e76b601d8a
--- /dev/null
+++ b/src/nvim/generators/gen_api_ui_events.lua
@@ -0,0 +1,177 @@
+mpack = require('mpack')
+
+local nvimdir = arg[1]
+package.path = nvimdir .. '/?.lua;' .. package.path
+
+assert(#arg == 7)
+input = io.open(arg[2], 'rb')
+proto_output = io.open(arg[3], 'wb')
+call_output = io.open(arg[4], 'wb')
+remote_output = io.open(arg[5], 'wb')
+bridge_output = io.open(arg[6], 'wb')
+metadata_output = io.open(arg[7], 'wb')
+
+c_grammar = require('generators.c_grammar')
+local events = c_grammar.grammar:match(input:read('*all'))
+
+function write_signature(output, ev, prefix, notype)
+ output:write('('..prefix)
+ if prefix == "" and #ev.parameters == 0 then
+ output:write('void')
+ end
+ for j = 1, #ev.parameters do
+ if j > 1 or prefix ~= '' then
+ output:write(', ')
+ end
+ local param = ev.parameters[j]
+ if not notype then
+ output:write(param[1]..' ')
+ end
+ output:write(param[2])
+ end
+ output:write(')')
+end
+
+function write_arglist(output, ev, need_copy)
+ output:write(' Array args = ARRAY_DICT_INIT;\n')
+ for j = 1, #ev.parameters do
+ local param = ev.parameters[j]
+ local kind = string.upper(param[1])
+ local do_copy = need_copy and (kind == "ARRAY" or kind == "DICTIONARY" or kind == "STRING" or kind == "OBJECT")
+ output:write(' ADD(args, ')
+ if do_copy then
+ output:write('copy_object(')
+ end
+ output:write(kind..'_OBJ('..param[2]..')')
+ if do_copy then
+ output:write(')')
+ end
+ output:write(');\n')
+ end
+end
+
+for i = 1, #events do
+ ev = events[i]
+ assert(ev.return_type == 'void')
+
+ if ev.since == nil then
+ print("Ui event "..ev.name.." lacks since field.\n")
+ os.exit(1)
+ end
+ ev.since = tonumber(ev.since)
+
+ if not ev.remote_only then
+ proto_output:write(' void (*'..ev.name..')')
+ write_signature(proto_output, ev, 'UI *ui')
+ proto_output:write(';\n')
+
+ if not ev.remote_impl then
+ remote_output:write('static void remote_ui_'..ev.name)
+ write_signature(remote_output, ev, 'UI *ui')
+ remote_output:write('\n{\n')
+ write_arglist(remote_output, ev, true)
+ remote_output:write(' push_call(ui, "'..ev.name..'", args);\n')
+ remote_output:write('}\n\n')
+ end
+
+ if not ev.bridge_impl then
+
+ send, argv, recv, recv_argv, recv_cleanup = '', '', '', '', ''
+ argc = 1
+ for j = 1, #ev.parameters do
+ local param = ev.parameters[j]
+ copy = 'copy_'..param[2]
+ if param[1] == 'String' then
+ send = send..' String copy_'..param[2]..' = copy_string('..param[2]..');\n'
+ argv = argv..', '..copy..'.data, INT2PTR('..copy..'.size)'
+ recv = (recv..' String '..param[2]..
+ ' = (String){.data = argv['..argc..'],'..
+ '.size = (size_t)argv['..(argc+1)..']};\n')
+ recv_argv = recv_argv..', '..param[2]
+ recv_cleanup = recv_cleanup..' api_free_string('..param[2]..');\n'
+ argc = argc+2
+ elseif param[1] == 'Array' then
+ send = send..' Array '..copy..' = copy_array('..param[2]..');\n'
+ argv = argv..', '..copy..'.items, INT2PTR('..copy..'.size)'
+ recv = (recv..' Array '..param[2]..
+ ' = (Array){.items = argv['..argc..'],'..
+ '.size = (size_t)argv['..(argc+1)..']};\n')
+ recv_argv = recv_argv..', '..param[2]
+ recv_cleanup = recv_cleanup..' api_free_array('..param[2]..');\n'
+ argc = argc+2
+ elseif param[1] == 'Object' then
+ send = send..' Object *'..copy..' = xmalloc(sizeof(Object));\n'
+ send = send..' *'..copy..' = copy_object('..param[2]..');\n'
+ argv = argv..', '..copy
+ recv = recv..' Object '..param[2]..' = *(Object *)argv['..argc..'];\n'
+ recv_argv = recv_argv..', '..param[2]
+ recv_cleanup = (recv_cleanup..' api_free_object('..param[2]..');\n'..
+ ' xfree(argv['..argc..']);\n')
+ argc = argc+1
+ elseif param[1] == 'Integer' or param[1] == 'Boolean' then
+ argv = argv..', INT2PTR('..param[2]..')'
+ recv_argv = recv_argv..', PTR2INT(argv['..argc..'])'
+ argc = argc+1
+ else
+ assert(false)
+ end
+ end
+ bridge_output:write('static void ui_bridge_'..ev.name..
+ '_event(void **argv)\n{\n')
+ bridge_output:write(' UI *ui = UI(argv[0]);\n')
+ bridge_output:write(recv)
+ bridge_output:write(' ui->'..ev.name..'(ui'..recv_argv..');\n')
+ bridge_output:write(recv_cleanup)
+ bridge_output:write('}\n\n')
+
+ bridge_output:write('static void ui_bridge_'..ev.name)
+ write_signature(bridge_output, ev, 'UI *ui')
+ bridge_output:write('\n{\n')
+ bridge_output:write(send)
+ bridge_output:write(' UI_BRIDGE_CALL(ui, '..ev.name..', '..argc..', ui'..argv..');\n}\n\n')
+ end
+ end
+
+ if not (ev.remote_only and ev.remote_impl) then
+ call_output:write('void ui_call_'..ev.name)
+ write_signature(call_output, ev, '')
+ call_output:write('\n{\n')
+ if ev.remote_only then
+ write_arglist(call_output, ev, false)
+ call_output:write(' UI_LOG('..ev.name..', 0);\n')
+ call_output:write(' ui_event("'..ev.name..'", args);\n')
+ else
+ call_output:write(' UI_CALL')
+ write_signature(call_output, ev, ev.name, true)
+ call_output:write(";\n")
+ end
+ call_output:write("}\n\n")
+ end
+
+end
+
+proto_output:close()
+call_output:close()
+remote_output:close()
+
+-- don't expose internal attributes like "impl_name" in public metadata
+exported_attributes = {'name', 'parameters',
+ 'since', 'deprecated_since'}
+exported_events = {}
+for _,ev in ipairs(events) do
+ local ev_exported = {}
+ for _,attr in ipairs(exported_attributes) do
+ ev_exported[attr] = ev[attr]
+ end
+ for _,p in ipairs(ev_exported.parameters) do
+ if p[1] == 'HlAttrs' then
+ p[1] = 'Dictionary'
+ end
+ end
+ exported_events[#exported_events+1] = ev_exported
+end
+
+packed = mpack.pack(exported_events)
+dump_bin_array = require("generators.dump_bin_array")
+dump_bin_array(metadata_output, 'ui_events_metadata', packed)
+metadata_output:close()
diff --git a/src/nvim/generators/gen_char_blob.lua b/src/nvim/generators/gen_char_blob.lua
new file mode 100644
index 0000000000..d860375e26
--- /dev/null
+++ b/src/nvim/generators/gen_char_blob.lua
@@ -0,0 +1,48 @@
+if arg[1] == '--help' then
+ print('Usage:')
+ print(' gencharblob.lua source target varname')
+ print('')
+ print('Generates C file with big uint8_t blob.')
+ print('Blob will be stored in a static const array named varname.')
+ os.exit()
+end
+
+assert(#arg == 3)
+
+local source_file = arg[1]
+local target_file = arg[2]
+local varname = arg[3]
+
+source = io.open(source_file, 'r')
+target = io.open(target_file, 'w')
+
+target:write('#include <stdint.h>\n\n')
+target:write(('static const uint8_t %s[] = {\n'):format(varname))
+
+num_bytes = 0
+MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line
+target:write(' ')
+
+increase_num_bytes = function()
+ num_bytes = num_bytes + 1
+ if num_bytes == MAX_NUM_BYTES then
+ num_bytes = 0
+ target:write('\n ')
+ end
+end
+
+for line in source:lines() do
+ for i = 1,string.len(line) do
+ byte = string.byte(line, i)
+ assert(byte ~= 0)
+ target:write(string.format(' %3u,', byte))
+ increase_num_bytes()
+ end
+ target:write(string.format(' %3u,', string.byte('\n', 1)))
+ increase_num_bytes()
+end
+
+target:write(' 0};\n')
+
+source:close()
+target:close()
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
new file mode 100755
index 0000000000..c40c37bb3e
--- /dev/null
+++ b/src/nvim/generators/gen_declarations.lua
@@ -0,0 +1,321 @@
+#!/usr/bin/lua
+
+local fname = arg[1]
+local static_fname = arg[2]
+local non_static_fname = arg[3]
+local preproc_fname = arg[4]
+
+
+local lpeg = require('lpeg')
+
+local fold = function (func, ...)
+ local result = nil
+ for i, v in ipairs({...}) do
+ if result == nil then
+ result = v
+ else
+ result = func(result, v)
+ end
+ end
+ return result
+end
+
+local folder = function (func)
+ return function (...)
+ return fold(func, ...)
+ end
+end
+
+local lit = lpeg.P
+local set = function(...)
+ return lpeg.S(fold(function (a, b) return a .. b end, ...))
+end
+local any_character = lpeg.P(1)
+local rng = function(s, e) return lpeg.R(s .. e) end
+local concat = folder(function (a, b) return a * b end)
+local branch = folder(function (a, b) return a + b end)
+local one_or_more = function(v) return v ^ 1 end
+local two_or_more = function(v) return v ^ 2 end
+local any_amount = function(v) return v ^ 0 end
+local one_or_no = function(v) return v ^ -1 end
+local look_behind = lpeg.B
+local look_ahead = function(v) return #v end
+local neg_look_ahead = function(v) return -v end
+local neg_look_behind = function(v) return -look_behind(v) end
+
+local w = branch(
+ rng('a', 'z'),
+ rng('A', 'Z'),
+ lit('_')
+)
+local aw = branch(
+ w,
+ rng('0', '9')
+)
+local s = set(' ', '\n', '\t')
+local raw_word = concat(w, any_amount(aw))
+local right_word = concat(
+ raw_word,
+ neg_look_ahead(aw)
+)
+local word = branch(
+ concat(
+ branch(lit('ArrayOf('), lit('DictionaryOf(')), -- typed container macro
+ one_or_more(any_character - lit(')')),
+ lit(')')
+ ),
+ concat(
+ neg_look_behind(aw),
+ right_word
+ )
+)
+local inline_comment = concat(
+ lit('/*'),
+ any_amount(concat(
+ neg_look_ahead(lit('*/')),
+ any_character
+ )),
+ lit('*/')
+)
+local spaces = any_amount(branch(
+ s,
+ -- Comments are really handled by preprocessor, so the following is not needed
+ inline_comment,
+ concat(
+ lit('//'),
+ any_amount(concat(
+ neg_look_ahead(lit('\n')),
+ any_character
+ )),
+ lit('\n')
+ ),
+ -- Linemarker inserted by preprocessor
+ concat(
+ lit('# '),
+ any_amount(concat(
+ neg_look_ahead(lit('\n')),
+ any_character
+ )),
+ lit('\n')
+ )
+))
+local typ_part = concat(
+ word,
+ any_amount(concat(
+ spaces,
+ lit('*')
+ )),
+ spaces
+)
+local typ = one_or_more(typ_part)
+local typ_id = two_or_more(typ_part)
+local arg = typ_id -- argument name is swallowed by typ
+local pattern = concat(
+ any_amount(branch(set(' ', '\t'), inline_comment)),
+ typ_id, -- return type with function name
+ spaces,
+ lit('('),
+ spaces,
+ one_or_no(branch( -- function arguments
+ concat(
+ arg, -- first argument, does not require comma
+ any_amount(concat( -- following arguments, start with a comma
+ spaces,
+ lit(','),
+ spaces,
+ arg,
+ any_amount(concat(
+ lit('['),
+ spaces,
+ any_amount(aw),
+ spaces,
+ lit(']')
+ ))
+ )),
+ one_or_no(concat(
+ spaces,
+ lit(','),
+ spaces,
+ lit('...')
+ ))
+ ),
+ lit('void') -- also accepts just void
+ )),
+ spaces,
+ lit(')'),
+ any_amount(concat( -- optional attributes
+ spaces,
+ lit('FUNC_'),
+ any_amount(aw),
+ one_or_no(concat( -- attribute argument
+ spaces,
+ lit('('),
+ any_amount(concat(
+ neg_look_ahead(lit(')')),
+ any_character
+ )),
+ lit(')')
+ ))
+ )),
+ look_ahead(concat( -- definition must be followed by "{"
+ spaces,
+ lit('{')
+ ))
+)
+
+if fname == '--help' then
+ print([[
+Usage:
+
+ gendeclarations.lua definitions.c static.h non-static.h definitions.i
+
+Generates declarations for a C file definitions.c, putting declarations for
+static functions into static.h and declarations for non-static functions into
+non-static.h. File `definitions.i' should contain an already preprocessed
+version of definitions.c and it is the only one which is actually parsed,
+definitions.c is needed only to determine functions from which file out of all
+functions found in definitions.i are needed.
+
+Additionally uses the following environment variables:
+
+ NVIM_GEN_DECLARATIONS_LINE_NUMBERS:
+ If set to 1 then all generated declarations receive a comment with file
+ name and line number after the declaration. This may be useful for
+ debugging gen_declarations script, but not much beyond that with
+ configured development environment (i.e. with ctags/cscope/finding
+ definitions with clang/etc).
+
+ WARNING: setting this to 1 will cause extensive rebuilds: declarations
+ generator script will not regenerate non-static.h file if its
+ contents did not change, but including line numbers will make
+ contents actually change.
+
+ With contents changed timestamp of the file is regenerated even
+ when no real changes were made (e.g. a few lines were added to
+ a function which is not at the bottom of the file).
+
+ With changed timestamp build system will assume that header
+ changed, triggering rebuilds of all C files which depend on the
+ "changed" header.
+]])
+ os.exit()
+end
+
+local preproc_f = io.open(preproc_fname)
+local text = preproc_f:read("*all")
+preproc_f:close()
+
+
+local header = [[
+#ifndef DEFINE_FUNC_ATTRIBUTES
+# define DEFINE_FUNC_ATTRIBUTES
+#endif
+#include "nvim/func_attr.h"
+#undef DEFINE_FUNC_ATTRIBUTES
+]]
+
+local footer = [[
+#include "nvim/func_attr.h"
+]]
+
+local non_static = header
+local static = header
+
+local filepattern = '^#%a* (%d+) "([^"]-)/?([^"/]+)"'
+local curfile
+
+local init = 1
+local curfile = nil
+local neededfile = fname:match('[^/]+$')
+local declline = 0
+local declendpos = 0
+local curdir = nil
+local is_needed_file = false
+local init_is_nl = true
+while init ~= nil do
+ if init_is_nl and text:sub(init, init) == '#' then
+ local line, dir, file = text:match(filepattern, init)
+ if file ~= nil then
+ curfile = file
+ is_needed_file = (curfile == neededfile)
+ declline = tonumber(line) - 1
+ local curdir_start = dir:find('src/nvim/')
+ if curdir_start ~= nil then
+ curdir = dir:sub(curdir_start + #('src/nvim/'))
+ else
+ curdir = dir
+ end
+ else
+ declline = declline - 1
+ end
+ elseif init < declendpos then
+ -- Skipping over declaration
+ elseif is_needed_file then
+ s = init
+ e = pattern:match(text, init)
+ if e ~= nil then
+ local declaration = text:sub(s, e - 1)
+ -- Comments are really handled by preprocessor, so the following is not
+ -- needed
+ declaration = declaration:gsub('/%*.-%*/', '')
+ declaration = declaration:gsub('//.-\n', '\n')
+
+ declaration = declaration:gsub('# .-\n', '')
+
+ declaration = declaration:gsub('\n', ' ')
+ declaration = declaration:gsub('%s+', ' ')
+ declaration = declaration:gsub(' ?%( ?', '(')
+ -- declaration = declaration:gsub(' ?%) ?', ')')
+ declaration = declaration:gsub(' ?, ?', ', ')
+ declaration = declaration:gsub(' ?(%*+) ?', ' %1')
+ declaration = declaration:gsub(' ?(FUNC_ATTR_)', ' %1')
+ declaration = declaration:gsub(' $', '')
+ declaration = declaration:gsub('^ ', '')
+ declaration = declaration .. ';'
+ if os.getenv('NVIM_GEN_DECLARATIONS_LINE_NUMBERS') == '1' then
+ declaration = declaration .. (' // %s/%s:%u'):format(
+ curdir, curfile, declline)
+ end
+ declaration = declaration .. '\n'
+ if declaration:sub(1, 6) == 'static' then
+ static = static .. declaration
+ else
+ non_static = non_static .. declaration
+ end
+ declendpos = e
+ end
+ end
+ init = text:find('[\n;}]', init)
+ if init == nil then
+ break
+ end
+ init_is_nl = text:sub(init, init) == '\n'
+ init = init + 1
+ if init_is_nl and is_needed_file then
+ declline = declline + 1
+ end
+end
+
+non_static = non_static .. footer
+static = static .. footer
+
+local F
+F = io.open(static_fname, 'w')
+F:write(static)
+F:close()
+
+-- Before generating the non-static headers, check if the current file(if
+-- exists) is different from the new one. If they are the same, we won't touch
+-- the current version to avoid triggering an unnecessary rebuilds of modules
+-- that depend on this one
+F = io.open(non_static_fname, 'r')
+if F ~= nil then
+ if F:read('*a') == non_static then
+ os.exit(0)
+ end
+ io.close(F)
+end
+
+F = io.open(non_static_fname, 'w')
+F:write(non_static)
+F:close()
diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua
new file mode 100644
index 0000000000..23435a1d0b
--- /dev/null
+++ b/src/nvim/generators/gen_eval.lua
@@ -0,0 +1,67 @@
+mpack = require('mpack')
+
+local nvimsrcdir = arg[1]
+local autodir = arg[2]
+local metadata_file = arg[3]
+local funcs_file = arg[4]
+
+if nvimsrcdir == '--help' then
+ print([[
+Usage:
+ lua geneval.lua src/nvim build/src/nvim/auto
+
+Will generate build/src/nvim/auto/funcs.generated.h with definition of functions
+static const array.
+]])
+ os.exit(0)
+end
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local funcsfname = autodir .. '/funcs.generated.h'
+
+local gperfpipe = io.open(funcsfname .. '.gperf', 'wb')
+
+local funcs = require('eval').funcs
+local metadata = mpack.unpack(io.open(arg[3], 'rb'):read("*all"))
+for i,fun in ipairs(metadata) do
+ if not fun.remote_only then
+ funcs[fun.name] = {
+ args=#fun.parameters,
+ func='api_wrapper',
+ data='&handle_'..fun.name,
+ }
+ end
+end
+
+local funcsdata = io.open(funcs_file, 'w')
+funcsdata:write(mpack.pack(funcs))
+funcsdata:close()
+
+gperfpipe:write([[
+%language=ANSI-C
+%global-table
+%readonly-tables
+%define initializer-suffix ,0,0,NULL,NULL
+%define word-array-name functions
+%define hash-function-name hash_internal_func_gperf
+%define lookup-function-name find_internal_func_gperf
+%omit-struct-type
+%struct-type
+VimLFuncDef;
+%%
+]])
+
+for name, def in pairs(funcs) do
+ args = def.args or 0
+ if type(args) == 'number' then
+ args = {args, args}
+ elseif #args == 1 then
+ args[2] = 'MAX_FUNC_ARGS'
+ end
+ func = def.func or ('f_' .. name)
+ data = def.data or "NULL"
+ gperfpipe:write(('%s, %s, %s, &%s, (FunPtr)%s\n')
+ :format(name, args[1], args[2], func, data))
+end
+gperfpipe:close()
diff --git a/src/nvim/generators/gen_events.lua b/src/nvim/generators/gen_events.lua
new file mode 100644
index 0000000000..d03c787b2b
--- /dev/null
+++ b/src/nvim/generators/gen_events.lua
@@ -0,0 +1,62 @@
+if arg[1] == '--help' then
+ print('Usage: gen_events.lua src/nvim enum_file event_names_file')
+ os.exit(0)
+end
+
+local nvimsrcdir = arg[1]
+local fileio_enum_file = arg[2]
+local names_file = arg[3]
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local auevents = require('auevents')
+local events = auevents.events
+local aliases = auevents.aliases
+
+enum_tgt = io.open(fileio_enum_file, 'w')
+names_tgt = io.open(names_file, 'w')
+
+enum_tgt:write('typedef enum auto_event {')
+names_tgt:write([[
+static const struct event_name {
+ size_t len;
+ char *name;
+ event_T event;
+} event_names[] = {]])
+
+for i, event in ipairs(events) do
+ enum_tgt:write(('\n EVENT_%s = %u,'):format(event:upper(), i - 1))
+ names_tgt:write(('\n {%u, "%s", EVENT_%s},'):format(#event, event, event:upper()))
+ if i == #events then -- Last item.
+ enum_tgt:write(('\n NUM_EVENTS = %u,'):format(i))
+ end
+end
+
+for alias, event in pairs(aliases) do
+ names_tgt:write(('\n {%u, "%s", EVENT_%s},'):format(#alias, alias, event:upper()))
+end
+
+names_tgt:write('\n {0, NULL, (event_T)0},')
+
+enum_tgt:write('\n} event_T;\n')
+names_tgt:write('\n};\n')
+
+names_tgt:write('\nstatic AutoPat *first_autopat[NUM_EVENTS] = {\n ')
+line_len = 1
+for i = 1,((#events) - 1) do
+ line_len = line_len + #(' NULL,')
+ if line_len > 80 then
+ names_tgt:write('\n ')
+ line_len = 1 + #(' NULL,')
+ end
+ names_tgt:write(' NULL,')
+end
+if line_len + #(' NULL') > 80 then
+ names_tgt:write('\n NULL')
+else
+ names_tgt:write(' NULL')
+end
+names_tgt:write('\n};\n')
+
+enum_tgt:close()
+names_tgt:close()
diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua
new file mode 100644
index 0000000000..cb566d46ca
--- /dev/null
+++ b/src/nvim/generators/gen_ex_cmds.lua
@@ -0,0 +1,88 @@
+local nvimsrcdir = arg[1]
+local includedir = arg[2]
+local autodir = arg[3]
+
+if nvimsrcdir == '--help' then
+ print ([[
+Usage:
+ lua genex_cmds.lua src/nvim build/include build/src/nvim/auto
+
+Will generate files build/include/ex_cmds_enum.generated.h with cmdidx_T
+enum and build/src/nvim/auto/ex_cmds_defs.generated.h with main Ex commands
+definitions.
+]])
+ os.exit(0)
+end
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local enumfname = includedir .. '/ex_cmds_enum.generated.h'
+local defsfname = autodir .. '/ex_cmds_defs.generated.h'
+
+local enumfile = io.open(enumfname, 'w')
+local defsfile = io.open(defsfname, 'w')
+
+local defs = require('ex_cmds')
+local lastchar = nil
+
+local i
+local cmd
+local first = true
+local prevfirstchar = nil
+
+local byte_a = string.byte('a')
+local byte_z = string.byte('z')
+
+local cmdidxs = string.format([[
+static const cmdidx_T cmdidxs[%u] = {
+]], byte_z - byte_a + 2)
+
+enumfile:write([[
+typedef enum CMD_index {
+]])
+defsfile:write(string.format([[
+static CommandDefinition cmdnames[%u] = {
+]], #defs))
+for i, cmd in ipairs(defs) do
+ local enumname = cmd.enum or ('CMD_' .. cmd.command)
+ firstchar = string.byte(cmd.command)
+ if firstchar ~= prevfirstchar then
+ if (not prevfirstchar
+ or (byte_a <= firstchar and firstchar <= byte_z)
+ or (byte_a <= prevfirstchar and prevfirstchar <= byte_z)) then
+ if not first then
+ cmdidxs = cmdidxs .. ',\n'
+ end
+ cmdidxs = cmdidxs .. ' ' .. enumname
+ end
+ prevfirstchar = firstchar
+ end
+ if first then
+ first = false
+ else
+ defsfile:write(',\n')
+ end
+ enumfile:write(' ' .. enumname .. ',\n')
+ defsfile:write(string.format([[
+ [%s] = {
+ .cmd_name = (char_u *) "%s",
+ .cmd_func = (ex_func_T)&%s,
+ .cmd_argt = %uL,
+ .cmd_addr_type = %i
+ }]], enumname, cmd.command, cmd.func, cmd.flags, cmd.addr_type))
+end
+defsfile:write([[
+
+};
+]])
+enumfile:write([[
+ CMD_SIZE,
+ CMD_USER = -1,
+ CMD_USER_BUF = -2
+} cmdidx_T;
+]])
+cmdidxs = cmdidxs .. [[
+
+};
+]]
+defsfile:write(cmdidxs)
diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua
new file mode 100644
index 0000000000..fdc00d5dc0
--- /dev/null
+++ b/src/nvim/generators/gen_options.lua
@@ -0,0 +1,192 @@
+if arg[1] == '--help' then
+ print('Usage: genoptions.lua src/nvim options_file')
+ os.exit(0)
+end
+
+local nvimsrcdir = arg[1]
+local options_file = arg[2]
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local opt_fd = io.open(options_file, 'w')
+
+local w = function(s)
+ if s:match('^ %.') then
+ opt_fd:write(s .. ',\n')
+ else
+ opt_fd:write(s .. '\n')
+ end
+end
+
+local options = require('options')
+
+cstr = options.cstr
+
+local type_flags={
+ bool='P_BOOL',
+ number='P_NUM',
+ string='P_STRING',
+}
+
+local redraw_flags={
+ statuslines='P_RSTAT',
+ current_window='P_RWIN',
+ current_window_only='P_RWINONLY',
+ current_buffer='P_RBUF',
+ all_windows='P_RALL',
+ everything='P_RCLR',
+ curswant='P_CURSWANT',
+ ui_option='P_UI_OPTION',
+}
+
+local list_flags={
+ comma='P_COMMA',
+ onecomma='P_ONECOMMA',
+ flags='P_FLAGLIST',
+ flagscomma='P_COMMA|P_FLAGLIST',
+}
+
+local get_flags = function(o)
+ local ret = {type_flags[o.type]}
+ local add_flag = function(f)
+ ret[1] = ret[1] .. '|' .. f
+ end
+ if o.list then
+ add_flag(list_flags[o.list])
+ end
+ if o.redraw then
+ for _, r_flag in ipairs(o.redraw) do
+ add_flag(redraw_flags[r_flag])
+ end
+ end
+ if o.expand then
+ add_flag('P_EXPAND')
+ if o.expand == 'nodefault' then
+ add_flag('P_NO_DEF_EXP')
+ end
+ end
+ for _, flag_desc in ipairs({
+ {'alloced'},
+ {'nodefault'},
+ {'no_mkrc'},
+ {'vi_def'},
+ {'vim'},
+ {'secure'},
+ {'gettext'},
+ {'noglob'},
+ {'normal_fname_chars', 'P_NFNAME'},
+ {'normal_dname_chars', 'P_NDNAME'},
+ {'pri_mkrc'},
+ {'deny_in_modelines', 'P_NO_ML'},
+ {'deny_duplicates', 'P_NODUP'},
+ }) do
+ local key_name = flag_desc[1]
+ local def_name = flag_desc[2] or ('P_' .. key_name:upper())
+ if o[key_name] then
+ add_flag(def_name)
+ end
+ end
+ return ret[1]
+end
+
+local get_cond
+get_cond = function(c, base_string)
+ local cond_string = base_string or '#if '
+ if type(c) == 'table' then
+ cond_string = cond_string .. get_cond(c[1], '')
+ for i, subc in ipairs(c) do
+ if i > 1 then
+ cond_string = cond_string .. ' && ' .. get_cond(subc, '')
+ end
+ end
+ elseif c:sub(1, 1) == '!' then
+ cond_string = cond_string .. '!defined(' .. c:sub(2) .. ')'
+ else
+ cond_string = cond_string .. 'defined(' .. c .. ')'
+ end
+ return cond_string
+end
+
+value_dumpers = {
+ ['function']=function(v) return v() end,
+ string=cstr,
+ boolean=function(v) return v and 'true' or 'false' end,
+ number=function(v) return ('%iL'):format(v) end,
+ ['nil']=function(v) return '0L' end,
+}
+
+local get_value = function(v)
+ return '(char_u *) ' .. value_dumpers[type(v)](v)
+end
+
+local get_defaults = function(d)
+ return ('{' .. get_value(d.vi) .. ', ' .. get_value(d.vim) .. '}')
+end
+
+local defines = {}
+
+local dump_option = function(i, o)
+ w(' [' .. ('%u'):format(i - 1) .. ']={')
+ w(' .fullname=' .. cstr(o.full_name))
+ if o.abbreviation then
+ w(' .shortname=' .. cstr(o.abbreviation))
+ end
+ w(' .flags=' .. get_flags(o))
+ if o.enable_if then
+ w(get_cond(o.enable_if))
+ end
+ if o.varname then
+ w(' .var=(char_u *)&' .. o.varname)
+ elseif #o.scope == 1 and o.scope[1] == 'window' then
+ w(' .var=VAR_WIN')
+ end
+ if o.enable_if then
+ w('#endif')
+ end
+ if #o.scope == 1 and o.scope[1] == 'global' then
+ w(' .indir=PV_NONE')
+ else
+ assert (#o.scope == 1 or #o.scope == 2)
+ assert (#o.scope == 1 or o.scope[1] == 'global')
+ local min_scope = o.scope[#o.scope]
+ local varname = o.pv_name or o.varname or (
+ 'p_' .. (o.abbreviation or o.full_name))
+ local pv_name = (
+ 'OPT_' .. min_scope:sub(1, 3):upper() .. '(' .. (
+ min_scope:sub(1, 1):upper() .. 'V_' .. varname:sub(3):upper()
+ ) .. ')'
+ )
+ if #o.scope == 2 then
+ pv_name = 'OPT_BOTH(' .. pv_name .. ')'
+ end
+ defines['PV_' .. varname:sub(3):upper()] = pv_name
+ w(' .indir=' .. pv_name)
+ end
+ if o.defaults then
+ if o.defaults.condition then
+ w(get_cond(o.defaults.condition))
+ end
+ w(' .def_val=' .. get_defaults(o.defaults.if_true))
+ if o.defaults.condition then
+ if o.defaults.if_false then
+ w('#else')
+ w(' .def_val=' .. get_defaults(o.defaults.if_false))
+ end
+ w('#endif')
+ end
+ end
+ w(' },')
+end
+
+w('static vimoption_T options[] = {')
+for i, o in ipairs(options.options) do
+ dump_option(i, o)
+end
+w(' [' .. ('%u'):format(#options.options) .. ']={.fullname=NULL}')
+w('};')
+w('')
+
+for k, v in pairs(defines) do
+ w('#define ' .. k .. ' ' .. v)
+end
+opt_fd:close()
diff --git a/src/nvim/generators/gen_unicode_tables.lua b/src/nvim/generators/gen_unicode_tables.lua
new file mode 100644
index 0000000000..66430ba26e
--- /dev/null
+++ b/src/nvim/generators/gen_unicode_tables.lua
@@ -0,0 +1,327 @@
+-- Script creates the following tables in unicode_tables.generated.h:
+--
+-- 1. doublewidth and ambiguous tables: sorted list of non-overlapping closed
+-- intervals. Codepoints in these intervals have double (W or F) or ambiguous
+-- (A) east asian width respectively.
+-- 2. combining table: same as the above, but characters inside are combining
+-- characters (i.e. have general categories equal to Mn, Mc or Me).
+-- 3. foldCase, toLower and toUpper tables used to convert characters to
+-- folded/lower/upper variants. In these tables first two values are
+-- character ranges: like in previous tables they are sorted and must be
+-- non-overlapping. Third value means step inside the range: e.g. if it is
+-- 2 then interval applies only to first, third, fifth, … character in range.
+-- Fourth value is number that should be added to the codepoint to yield
+-- folded/lower/upper codepoint.
+-- 4. emoji_width and emoji_all tables: sorted lists of non-overlapping closed
+-- intervals of Emoji characters. emoji_width contains all the characters
+-- which don't have ambiguous or double width, and emoji_all has all Emojis.
+if arg[1] == '--help' then
+ print('Usage:')
+ print(' genunicodetables.lua unicode/ unicode_tables.generated.h')
+ os.exit(0)
+end
+
+local basedir = arg[1]
+local pathsep = package.config:sub(1, 1)
+local get_path = function(fname)
+ return basedir .. pathsep .. fname
+end
+
+local unicodedata_fname = get_path('UnicodeData.txt')
+local casefolding_fname = get_path('CaseFolding.txt')
+local eastasianwidth_fname = get_path('EastAsianWidth.txt')
+local emoji_fname = get_path('emoji-data.txt')
+
+local utf_tables_fname = arg[2]
+
+local split_on_semicolons = function(s)
+ local ret = {}
+ local idx = 1
+ while idx <= #s + 1 do
+ item = s:match('^[^;]*', idx)
+ idx = idx + #item + 1
+ if idx <= #s + 1 then
+ assert(s:sub(idx - 1, idx - 1) == ';')
+ end
+ item = item:gsub('^%s*', '')
+ item = item:gsub('%s*$', '')
+ table.insert(ret, item)
+ end
+ return ret
+end
+
+local fp_lines_to_lists = function(fp, n, has_comments)
+ local ret = {}
+ local line
+ local i = 0
+ while true do
+ i = i + 1
+ line = fp:read('*l')
+ if not line then
+ break
+ end
+ if (not has_comments
+ or (line:sub(1, 1) ~= '#' and not line:match('^%s*$'))) then
+ local l = split_on_semicolons(line)
+ if #l ~= n then
+ io.stderr:write(('Found %s items in line %u, expected %u\n'):format(
+ #l, i, n))
+ io.stderr:write('Line: ' .. line .. '\n')
+ return nil
+ end
+ table.insert(ret, l)
+ end
+ end
+ return ret
+end
+
+local parse_data_to_props = function(ud_fp)
+ return fp_lines_to_lists(ud_fp, 15, false)
+end
+
+local parse_fold_props = function(cf_fp)
+ return fp_lines_to_lists(cf_fp, 4, true)
+end
+
+local parse_width_props = function(eaw_fp)
+ return fp_lines_to_lists(eaw_fp, 2, true)
+end
+
+local parse_emoji_props = function(emoji_fp)
+ return fp_lines_to_lists(emoji_fp, 2, true)
+end
+
+local make_range = function(start, end_, step, add)
+ if step and add then
+ return (' {0x%x, 0x%x, %d, %d},\n'):format(
+ start, end_, step == 0 and -1 or step, add)
+ else
+ return (' {0x%04x, 0x%04x},\n'):format(start, end_)
+ end
+end
+
+local build_convert_table = function(ut_fp, props, cond_func, nl_index,
+ table_name)
+ ut_fp:write('static const convertStruct ' .. table_name .. '[] = {\n')
+ local start = -1
+ local end_ = -1
+ local step = 0
+ local add = -1
+ for _, p in ipairs(props) do
+ if cond_func(p) then
+ local n = tonumber(p[1], 16)
+ local nl = tonumber(p[nl_index], 16)
+ if start >= 0 and add == (nl - n) and (step == 0 or n - end_ == step) then
+ -- Continue with the same range.
+ step = n - end_
+ end_ = n
+ else
+ if start >= 0 then
+ -- Produce previous range.
+ ut_fp:write(make_range(start, end_, step, add))
+ end
+ start = n
+ end_ = n
+ step = 0
+ add = nl - n
+ end
+ end
+ end
+ if start >= 0 then
+ ut_fp:write(make_range(start, end_, step, add))
+ end
+ ut_fp:write('};\n')
+end
+
+local build_case_table = function(ut_fp, dataprops, table_name, index)
+ local cond_func = function(p)
+ return p[index] ~= ''
+ end
+ return build_convert_table(ut_fp, dataprops, cond_func, index,
+ 'to' .. table_name)
+end
+
+local build_fold_table = function(ut_fp, foldprops)
+ local cond_func = function(p)
+ return (p[2] == 'C' or p[2] == 'S')
+ end
+ return build_convert_table(ut_fp, foldprops, cond_func, 3, 'foldCase')
+end
+
+local build_combining_table = function(ut_fp, dataprops)
+ ut_fp:write('static const struct interval combining[] = {\n')
+ local start = -1
+ local end_ = -1
+ for _, p in ipairs(dataprops) do
+ if (({Mn=true, Mc=true, Me=true})[p[3]]) then
+ local n = tonumber(p[1], 16)
+ if start >= 0 and end_ + 1 == n then
+ -- Continue with the same range.
+ end_ = n
+ else
+ if start >= 0 then
+ -- Produce previous range.
+ ut_fp:write(make_range(start, end_))
+ end
+ start = n
+ end_ = n
+ end
+ end
+ end
+ if start >= 0 then
+ ut_fp:write(make_range(start, end_))
+ end
+ ut_fp:write('};\n')
+end
+
+local build_width_table = function(ut_fp, dataprops, widthprops, widths,
+ table_name)
+ ut_fp:write('static const struct interval ' .. table_name .. '[] = {\n')
+ local start = -1
+ local end_ = -1
+ local dataidx = 1
+ local ret = {}
+ for _, p in ipairs(widthprops) do
+ if widths[p[2]:sub(1, 1)] then
+ local rng_start, rng_end = p[1]:find('%.%.')
+ local n, n_last
+ if rng_start then
+ -- It is a range. We don’t check for composing char then.
+ n = tonumber(p[1]:sub(1, rng_start - 1), 16)
+ n_last = tonumber(p[1]:sub(rng_end + 1), 16)
+ else
+ n = tonumber(p[1], 16)
+ n_last = n
+ end
+ local dn
+ while true do
+ dn = tonumber(dataprops[dataidx][1], 16)
+ if dn >= n then
+ break
+ end
+ dataidx = dataidx + 1
+ end
+ if dn ~= n and n_last == n then
+ io.stderr:write('Cannot find character ' .. n .. ' in data table.\n')
+ end
+ -- Only use the char when it’s not a composing char.
+ -- But use all chars from a range.
+ local dp = dataprops[dataidx]
+ if (n_last > n) or (not (({Mn=true, Mc=true, Me=true})[dp[3]])) then
+ if start >= 0 and end_ + 1 == n then
+ -- Continue with the same range.
+ else
+ if start >= 0 then
+ ut_fp:write(make_range(start, end_))
+ table.insert(ret, {start, end_})
+ end
+ start = n
+ end
+ end_ = n_last
+ end
+ end
+ end
+ if start >= 0 then
+ ut_fp:write(make_range(start, end_))
+ table.insert(ret, {start, end_})
+ end
+ ut_fp:write('};\n')
+ return ret
+end
+
+local build_emoji_table = function(ut_fp, emojiprops, doublewidth, ambiwidth)
+ local emojiwidth = {}
+ local emoji = {}
+ for _, p in ipairs(emojiprops) do
+ if p[2]:match('Emoji%s+#') then
+ local rng_start, rng_end = p[1]:find('%.%.')
+ if rng_start then
+ n = tonumber(p[1]:sub(1, rng_start - 1), 16)
+ n_last = tonumber(p[1]:sub(rng_end + 1), 16)
+ else
+ n = tonumber(p[1], 16)
+ n_last = n
+ end
+ if #emoji > 0 and n - 1 == emoji[#emoji][2] then
+ emoji[#emoji][2] = n_last
+ else
+ table.insert(emoji, { n, n_last })
+ end
+
+ -- Characters below 1F000 may be considered single width traditionally,
+ -- making them double width causes problems.
+ if n >= 0x1f000 then
+ -- exclude characters that are in the ambiguous/doublewidth table
+ for _, ambi in ipairs(ambiwidth) do
+ if n >= ambi[1] and n <= ambi[2] then
+ n = ambi[2] + 1
+ end
+ if n_last >= ambi[1] and n_last <= ambi[2] then
+ n_last = ambi[1] - 1
+ end
+ end
+ for _, double in ipairs(doublewidth) do
+ if n >= double[1] and n <= double[2] then
+ n = double[2] + 1
+ end
+ if n_last >= double[1] and n_last <= double[2] then
+ n_last = double[1] - 1
+ end
+ end
+
+ if n <= n_last then
+ if #emojiwidth > 0 and n - 1 == emojiwidth[#emojiwidth][2] then
+ emojiwidth[#emojiwidth][2] = n_last
+ else
+ table.insert(emojiwidth, { n, n_last })
+ end
+ end
+ end
+ end
+ end
+
+ ut_fp:write('static const struct interval emoji_all[] = {\n')
+ for _, p in ipairs(emoji) do
+ ut_fp:write(make_range(p[1], p[2]))
+ end
+ ut_fp:write('};\n')
+
+ ut_fp:write('static const struct interval emoji_width[] = {\n')
+ for _, p in ipairs(emojiwidth) do
+ ut_fp:write(make_range(p[1], p[2]))
+ end
+ ut_fp:write('};\n')
+end
+
+local ud_fp = io.open(unicodedata_fname, 'r')
+local dataprops = parse_data_to_props(ud_fp)
+ud_fp:close()
+
+local ut_fp = io.open(utf_tables_fname, 'w')
+
+build_case_table(ut_fp, dataprops, 'Lower', 14)
+build_case_table(ut_fp, dataprops, 'Upper', 13)
+build_combining_table(ut_fp, dataprops)
+
+local cf_fp = io.open(casefolding_fname, 'r')
+local foldprops = parse_fold_props(cf_fp)
+cf_fp:close()
+
+build_fold_table(ut_fp, foldprops)
+
+local eaw_fp = io.open(eastasianwidth_fname, 'r')
+local widthprops = parse_width_props(eaw_fp)
+eaw_fp:close()
+
+local doublewidth = build_width_table(ut_fp, dataprops, widthprops,
+ {W=true, F=true}, 'doublewidth')
+local ambiwidth = build_width_table(ut_fp, dataprops, widthprops,
+ {A=true}, 'ambiguous')
+
+local emoji_fp = io.open(emoji_fname, 'r')
+local emojiprops = parse_emoji_props(emoji_fp)
+emoji_fp:close()
+
+build_emoji_table(ut_fp, emojiprops, doublewidth, ambiwidth)
+
+ut_fp:close()
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index ae1857f318..53e9846c2d 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.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
+
/*
* getchar.c
*
@@ -15,6 +18,7 @@
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/getchar.h"
+#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
@@ -29,7 +33,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/garray.h"
#include "nvim/move.h"
@@ -38,12 +41,20 @@
#include "nvim/option.h"
#include "nvim/regexp.h"
#include "nvim/screen.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/event/loop.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
+#include "nvim/os/fileio.h"
+#include "nvim/api/private/handle.h"
+
+
+/// Index in scriptin
+static int curscript = 0;
+FileDescriptor *scriptin[NSCRIPT] = { NULL };
/*
* These buffers are used for storing:
@@ -67,11 +78,9 @@
#define MINIMAL_SIZE 20 /* minimal size for b_str */
-static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-static buffheader_T save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-static buffheader_T save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
-static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
+static buffheader_T redobuff = { { NULL, { NUL } }, NULL, 0, 0 };
+static buffheader_T old_redobuff = { { NULL, { NUL } }, NULL, 0, 0 };
+static buffheader_T recordbuff = { { NULL, { NUL } }, NULL, 0, 0 };
// First read ahead buffer. Used for translated commands.
static buffheader_T readbuf1 = {{NULL, {NUL}}, NULL, 0, 0};
@@ -87,23 +96,20 @@ static int typeahead_char = 0; /* typeahead char that's not flushed */
*/
static int block_redo = FALSE;
-/*
- * Make a hash value for a mapping.
- * "mode" is the lower 4 bits of the State for the mapping.
- * "c1" is the first character of the "lhs".
- * Returns a value between 0 and 255, index in maphash.
- * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
- */
+// Make a hash value for a mapping.
+// "mode" is the lower 4 bits of the State for the mapping.
+// "c1" is the first character of the "lhs".
+// Returns a value between 0 and 255, index in maphash.
+// Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
#define MAP_HASH(mode, \
c1) (((mode) & \
(NORMAL + VISUAL + SELECTMODE + \
- OP_PENDING)) ? (c1) : ((c1) ^ 0x80))
+ OP_PENDING + TERM_FOCUS)) ? (c1) : ((c1) ^ 0x80))
-/*
- * Each mapping is put in one of the 256 hash lists, to speed up finding it.
- */
-static mapblock_T *(maphash[256]);
-static int maphash_valid = FALSE;
+// Each mapping is put in one of the MAX_MAPHASH hash lists,
+// to speed up finding it.
+static mapblock_T *(maphash[MAX_MAPHASH]);
+static bool maphash_valid = false;
/*
* List used for abbreviations.
@@ -113,7 +119,7 @@ static mapblock_T *first_abbr = NULL; /* first entry in abbrlist */
static int KeyNoremap = 0; /* remapping flags */
/*
- * variables used by vgetorpeek() and flush_buffers()
+ * Variables used by vgetorpeek() and flush_buffers()
*
* typebuf.tb_buf[] contains all characters that are not consumed yet.
* typebuf.tb_buf[typebuf.tb_off] is the first valid character.
@@ -235,34 +241,34 @@ char_u *get_inserted(void)
return get_buffcont(&redobuff, FALSE);
}
-/*
- * Add string "s" after the current block of buffer "buf".
- * K_SPECIAL and CSI should have been escaped already.
- */
-static void
-add_buff (
- buffheader_T *buf,
- char_u *s,
- ssize_t slen // length of "s" or -1
-)
+/// Add string after the current block of the given buffer
+///
+/// K_SPECIAL and CSI should have been escaped already.
+///
+/// @param[out] buf Buffer to add to.
+/// @param[in] s String to add.
+/// @param[in] slen String length or -1 for NUL-terminated string.
+static void add_buff(buffheader_T *const buf, const char *const s,
+ ptrdiff_t slen)
{
if (slen < 0) {
- slen = (ssize_t)STRLEN(s);
+ slen = (ptrdiff_t)strlen(s);
}
if (slen == 0) { // don't add empty strings
return;
}
- if (buf->bh_first.b_next == NULL) { /* first add to list */
+ if (buf->bh_first.b_next == NULL) { // first add to list
buf->bh_space = 0;
buf->bh_curr = &(buf->bh_first);
- } else if (buf->bh_curr == NULL) { /* buffer has already been read */
- EMSG(_("E222: Add to read buffer"));
+ } else if (buf->bh_curr == NULL) { // buffer has already been read
+ IEMSG(_("E222: Add to read buffer"));
return;
- } else if (buf->bh_index != 0)
+ } else if (buf->bh_index != 0) {
memmove(buf->bh_first.b_next->b_str,
- buf->bh_first.b_next->b_str + buf->bh_index,
- STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1);
+ buf->bh_first.b_next->b_str + buf->bh_index,
+ STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1);
+ }
buf->bh_index = 0;
size_t len;
@@ -292,9 +298,8 @@ add_buff (
*/
static void add_num_buff(buffheader_T *buf, long n)
{
- char_u number[32];
-
- sprintf((char *)number, "%" PRId64, (int64_t)n);
+ char number[32];
+ snprintf(number, sizeof(number), "%ld", n);
add_buff(buf, number, -1L);
}
@@ -304,27 +309,29 @@ static void add_num_buff(buffheader_T *buf, long n)
*/
static void add_char_buff(buffheader_T *buf, int c)
{
- char_u bytes[MB_MAXBYTES + 1];
- int len;
- int i;
- char_u temp[4];
+ uint8_t bytes[MB_MAXBYTES + 1];
- if (IS_SPECIAL(c))
+ int len;
+ if (IS_SPECIAL(c)) {
len = 1;
- else
- len = (*mb_char2bytes)(c, bytes);
- for (i = 0; i < len; ++i) {
- if (!IS_SPECIAL(c))
+ } else {
+ len = utf_char2bytes(c, bytes);
+ }
+
+ for (int i = 0; i < len; i++) {
+ if (!IS_SPECIAL(c)) {
c = bytes[i];
+ }
+ char temp[4];
if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL) {
- /* translate special key code into three byte sequence */
- temp[0] = K_SPECIAL;
- temp[1] = (char_u)K_SECOND(c);
- temp[2] = (char_u)K_THIRD(c);
+ // Translate special key code into three byte sequence.
+ temp[0] = (char)K_SPECIAL;
+ temp[1] = (char)K_SECOND(c);
+ temp[2] = (char)K_THIRD(c);
temp[3] = NUL;
} else {
- temp[0] = (char_u)c;
+ temp[0] = (char)c;
temp[1] = NUL;
}
add_buff(buf, temp, -1L);
@@ -413,7 +420,7 @@ void typeahead_noflush(int c)
* typeahead buffer (used in case of an error). If "flush_typeahead" is true,
* flush all typeahead characters (used when interrupted by a CTRL-C).
*/
-void flush_buffers(int flush_typeahead)
+void flush_buffers(flush_buffers_T flush_typeahead)
{
init_typebuf();
@@ -421,24 +428,28 @@ void flush_buffers(int flush_typeahead)
while (read_readbuffers(TRUE) != NUL) {
}
- if (flush_typeahead) { /* remove all typeahead */
- /*
- * We have to get all characters, because we may delete the first part
- * of an escape sequence.
- * In an xterm we get one char at a time and we have to get them all.
- */
- while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L,
- typebuf.tb_change_cnt) != 0)
- ;
- typebuf.tb_off = MAXMAPLEN;
- typebuf.tb_len = 0;
- } else { /* remove mapped characters at the start only */
+ if (flush_typeahead == FLUSH_MINIMAL) {
+ // remove mapped characters at the start only
typebuf.tb_off += typebuf.tb_maplen;
typebuf.tb_len -= typebuf.tb_maplen;
+ } else {
+ // remove typeahead
+ if (flush_typeahead == FLUSH_INPUT) {
+ // We have to get all characters, because we may delete the first
+ // part of an escape sequence. In an xterm we get one char at a
+ // time and we have to get them all.
+ while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L) != 0) {
+ }
+ }
+ typebuf.tb_off = MAXMAPLEN;
+ typebuf.tb_len = 0;
+ // Reset the flag that text received from a client or from feedkeys()
+ // was inserted in the typeahead buffer.
+ typebuf_was_filled = false;
}
typebuf.tb_maplen = 0;
typebuf.tb_silent = 0;
- cmd_silent = FALSE;
+ cmd_silent = false;
typebuf.tb_no_abbr_cnt = 0;
}
@@ -471,53 +482,42 @@ void CancelRedo(void)
}
}
-/*
- * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
- * Used before executing autocommands and user functions.
- */
-static int save_level = 0;
-
-void saveRedobuff(void)
+/// Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
+/// Used before executing autocommands and user functions.
+void saveRedobuff(save_redo_T *save_redo)
{
- char_u *s;
-
- if (save_level++ == 0) {
- save_redobuff = redobuff;
- redobuff.bh_first.b_next = NULL;
- save_old_redobuff = old_redobuff;
- old_redobuff.bh_first.b_next = NULL;
-
- /* Make a copy, so that ":normal ." in a function works. */
- s = get_buffcont(&save_redobuff, FALSE);
- if (s != NULL) {
- add_buff(&redobuff, s, -1L);
- xfree(s);
- }
+ save_redo->sr_redobuff = redobuff;
+ redobuff.bh_first.b_next = NULL;
+ save_redo->sr_old_redobuff = old_redobuff;
+ old_redobuff.bh_first.b_next = NULL;
+
+ // Make a copy, so that ":normal ." in a function works.
+ char *const s = (char *)get_buffcont(&save_redo->sr_redobuff, false);
+ if (s != NULL) {
+ add_buff(&redobuff, s, -1L);
+ xfree(s);
}
}
-/*
- * Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff.
- * Used after executing autocommands and user functions.
- */
-void restoreRedobuff(void)
+/// Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff.
+/// Used after executing autocommands and user functions.
+void restoreRedobuff(save_redo_T *save_redo)
{
- if (--save_level == 0) {
- free_buff(&redobuff);
- redobuff = save_redobuff;
- free_buff(&old_redobuff);
- old_redobuff = save_old_redobuff;
- }
+ free_buff(&redobuff);
+ redobuff = save_redo->sr_redobuff;
+ free_buff(&old_redobuff);
+ old_redobuff = save_redo->sr_old_redobuff;
}
/*
* Append "s" to the redo buffer.
* K_SPECIAL and CSI should already have been escaped.
*/
-void AppendToRedobuff(char_u *s)
+void AppendToRedobuff(const char *s)
{
- if (!block_redo)
- add_buff(&redobuff, s, -1L);
+ if (!block_redo) {
+ add_buff(&redobuff, (const char *)s, -1L);
+ }
}
/*
@@ -530,44 +530,47 @@ AppendToRedobuffLit (
int len /* length of "str" or -1 for up to the NUL */
)
{
- char_u *s = str;
- int c;
- char_u *start;
-
- if (block_redo)
+ if (block_redo) {
return;
+ }
+
+ const char *s = (const char *)str;
+ while (len < 0 ? *s != NUL : s - (const char *)str < len) {
+ // Put a string of normal characters in the redo buffer (that's
+ // faster).
+ const char *start = s;
+ while (*s >= ' ' && *s < DEL && (len < 0 || s - (const char *)str < len)) {
+ s++;
+ }
- while (len < 0 ? *s != NUL : s - str < len) {
- /* Put a string of normal characters in the redo buffer (that's
- * faster). */
- start = s;
- while (*s >= ' ' && *s < DEL && (len < 0 || s - str < len))
- ++s;
-
- /* Don't put '0' or '^' as last character, just in case a CTRL-D is
- * typed next. */
- if (*s == NUL && (s[-1] == '0' || s[-1] == '^'))
- --s;
- if (s > start)
+ // Don't put '0' or '^' as last character, just in case a CTRL-D is
+ // typed next.
+ if (*s == NUL && (s[-1] == '0' || s[-1] == '^')) {
+ s--;
+ }
+ if (s > start) {
add_buff(&redobuff, start, (long)(s - start));
+ }
- if (*s == NUL || (len >= 0 && s - str >= len))
+ if (*s == NUL || (len >= 0 && s - (const char *)str >= len)) {
break;
+ }
- /* Handle a special or multibyte character. */
- if (has_mbyte)
- /* Handle composing chars separately. */
- c = mb_cptr2char_adv(&s);
- else
- c = *s++;
- if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^')))
+ // Handle a special or multibyte character.
+ // Composing chars separately are handled separately.
+ const int c = (has_mbyte
+ ? mb_cptr2char_adv((const char_u **)&s)
+ : (uint8_t)(*s++));
+ if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^'))) {
add_char_buff(&redobuff, Ctrl_V);
+ }
- /* CTRL-V '0' must be inserted as CTRL-V 048 */
- if (*s == NUL && c == '0')
- add_buff(&redobuff, (char_u *)"048", 3L);
- else
+ // CTRL-V '0' must be inserted as CTRL-V 048.
+ if (*s == NUL && c == '0') {
+ add_buff(&redobuff, "048", 3L);
+ } else {
add_char_buff(&redobuff, c);
+ }
}
}
@@ -594,19 +597,19 @@ void AppendNumberToRedobuff(long n)
* Append string "s" to the stuff buffer.
* CSI and K_SPECIAL must already have been escaped.
*/
-void stuffReadbuff(char_u *s)
+void stuffReadbuff(const char *s)
{
add_buff(&readbuf1, s, -1L);
}
/// Append string "s" to the redo stuff buffer.
/// @remark CSI and K_SPECIAL must already have been escaped.
-void stuffRedoReadbuff(char_u *s)
+void stuffRedoReadbuff(const char *s)
{
add_buff(&readbuf2, s, -1L);
}
-void stuffReadbuffLen(char_u *s, long len)
+void stuffReadbuffLen(const char *s, long len)
{
add_buff(&readbuf1, s, len);
}
@@ -616,19 +619,18 @@ void stuffReadbuffLen(char_u *s, long len)
* escaping other K_SPECIAL and CSI bytes.
* Change CR, LF and ESC into a space.
*/
-void stuffReadbuffSpec(char_u *s)
+void stuffReadbuffSpec(const char *s)
{
- int c;
-
while (*s != NUL) {
- if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
- /* Insert special key literally. */
- stuffReadbuffLen(s, 3L);
+ if ((uint8_t)(*s) == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
+ // Insert special key literally.
+ stuffReadbuffLen(s, 3);
s += 3;
} else {
- c = mb_ptr2char_adv(&s);
- if (c == CAR || c == NL || c == ESC)
+ int c = mb_ptr2char_adv((const char_u **)&s);
+ if (c == CAR || c == NL || c == ESC) {
c = ' ';
+ }
stuffcharReadbuff(c);
}
}
@@ -651,15 +653,13 @@ void stuffnumReadbuff(long n)
add_num_buff(&readbuf1, n);
}
-/*
- * Read a character from the redo buffer. Translates K_SPECIAL, CSI and
- * multibyte characters.
- * The redo buffer is left as it is.
- * If init is TRUE, prepare for redo, return FAIL if nothing to redo, OK
- * otherwise.
- * If old is TRUE, use old_redobuff instead of redobuff.
- */
-static int read_redo(int init, int old_redo)
+// Read a character from the redo buffer. Translates K_SPECIAL, CSI and
+// multibyte characters.
+// The redo buffer is left as it is.
+// If init is true, prepare for redo, return FAIL if nothing to redo, OK
+// otherwise.
+// If old_redo is true, use old_redobuff instead of redobuff.
+static int read_redo(bool init, bool old_redo)
{
static buffblock_T *bp;
static char_u *p;
@@ -700,7 +700,7 @@ static int read_redo(int init, int old_redo)
buf[i] = (char_u)c;
if (i == n - 1) { // last byte of a character
if (n != 1) {
- c = (*mb_ptr2char)(buf);
+ c = utf_ptr2char(buf);
}
break;
}
@@ -712,64 +712,69 @@ static int read_redo(int init, int old_redo)
return c;
}
-/*
- * Copy the rest of the redo buffer into the stuff buffer (in a slow way).
- * If old_redo is TRUE, use old_redobuff instead of redobuff.
- * The escaped K_SPECIAL and CSI are copied without translation.
- */
-static void copy_redo(int old_redo)
+// Copy the rest of the redo buffer into the stuff buffer (in a slow way).
+// If old_redo is true, use old_redobuff instead of redobuff.
+// The escaped K_SPECIAL and CSI are copied without translation.
+static void copy_redo(bool old_redo)
{
int c;
- while ((c = read_redo(FALSE, old_redo)) != NUL) {
+ while ((c = read_redo(false, old_redo)) != NUL) {
add_char_buff(&readbuf2, c);
}
}
-/*
- * Stuff the redo buffer into readbuf2.
- * Insert the redo count into the command.
- * If "old_redo" is TRUE, the last but one command is repeated
- * instead of the last command (inserting text). This is used for
- * CTRL-O <.> in insert mode
- *
- * return FAIL for failure, OK otherwise
- */
-int start_redo(long count, int old_redo)
+// Stuff the redo buffer into readbuf2.
+// Insert the redo count into the command.
+// If "old_redo" is true, the last but one command is repeated
+// instead of the last command (inserting text). This is used for
+// CTRL-O <.> in insert mode
+//
+// return FAIL for failure, OK otherwise
+int start_redo(long count, bool old_redo)
{
int c;
- /* init the pointers; return if nothing to redo */
- if (read_redo(TRUE, old_redo) == FAIL)
+ // init the pointers; return if nothing to redo
+ if (read_redo(true, old_redo) == FAIL) {
return FAIL;
+ }
- c = read_redo(FALSE, old_redo);
+ c = read_redo(false, old_redo);
/* copy the buffer name, if present */
if (c == '"') {
- add_buff(&readbuf2, (char_u *)"\"", 1L);
- c = read_redo(FALSE, old_redo);
+ add_buff(&readbuf2, "\"", 1L);
+ c = read_redo(false, old_redo);
/* if a numbered buffer is used, increment the number */
if (c >= '1' && c < '9')
++c;
add_char_buff(&readbuf2, c);
- c = read_redo(FALSE, old_redo);
+
+ // the expression register should be re-evaluated
+ if (c == '=') {
+ add_char_buff(&readbuf2, CAR);
+ cmd_silent = true;
+ }
+
+ c = read_redo(false, old_redo);
}
if (c == 'v') { /* redo Visual */
VIsual = curwin->w_cursor;
- VIsual_active = TRUE;
- VIsual_select = FALSE;
- VIsual_reselect = TRUE;
- redo_VIsual_busy = TRUE;
- c = read_redo(FALSE, old_redo);
+ VIsual_active = true;
+ VIsual_select = false;
+ VIsual_reselect = true;
+ redo_VIsual_busy = true;
+ c = read_redo(false, old_redo);
}
- /* try to enter the count (in place of a previous count) */
+ // try to enter the count (in place of a previous count)
if (count) {
- while (ascii_isdigit(c)) /* skip "old" count */
- c = read_redo(FALSE, old_redo);
+ while (ascii_isdigit(c)) { // skip "old" count
+ c = read_redo(false, old_redo);
+ }
add_num_buff(&readbuf2, count);
}
@@ -788,12 +793,13 @@ int start_redo_ins(void)
{
int c;
- if (read_redo(TRUE, FALSE) == FAIL)
+ if (read_redo(true, false) == FAIL) {
return FAIL;
+ }
start_stuff();
- /* skip the count and the command character */
- while ((c = read_redo(FALSE, FALSE)) != NUL) {
+ // skip the count and the command character
+ while ((c = read_redo(false, false)) != NUL) {
if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL) {
if (c == 'O' || c == 'o') {
add_buff(&readbuf2, NL_STR, -1L);
@@ -802,9 +808,9 @@ int start_redo_ins(void)
}
}
- /* copy the typed text from the redo buffer into the stuff buffer */
- copy_redo(FALSE);
- block_redo = TRUE;
+ // copy the typed text from the redo buffer into the stuff buffer
+ copy_redo(false);
+ block_redo = true;
return OK;
}
@@ -825,7 +831,7 @@ static void init_typebuf(void)
typebuf.tb_noremap = noremapbuf_init;
typebuf.tb_buflen = TYPELEN_INIT;
typebuf.tb_len = 0;
- typebuf.tb_off = 0;
+ typebuf.tb_off = MAXMAPLEN + 4;
typebuf.tb_change_cnt = 1;
}
}
@@ -865,20 +871,21 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, bool silent)
addlen = (int)STRLEN(str);
- /*
- * Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
- */
if (offset == 0 && addlen <= typebuf.tb_off) {
+ // Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
typebuf.tb_off -= addlen;
memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
- }
- /*
- * Need to allocate a new buffer.
- * In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
- * characters. We add some extra room to avoid having to allocate too
- * often.
- */
- else {
+ } else if (typebuf.tb_len == 0
+ && typebuf.tb_buflen >= addlen + 3 * (MAXMAPLEN + 4)) {
+ // Buffer is empty and string fits in the existing buffer.
+ // Leave some space before and after, if possible.
+ typebuf.tb_off = (typebuf.tb_buflen - addlen - 3 * (MAXMAPLEN + 4)) / 2;
+ memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
+ } else {
+ // Need to allocate a new buffer.
+ // In typebuf.tb_buf there must always be room for 3 * (MAXMAPLEN + 4)
+ // characters. We add some extra room to avoid having to allocate too
+ // often.
newoff = MAXMAPLEN + 4;
newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
if (newlen < 0) { /* string is getting too long */
@@ -950,7 +957,7 @@ int ins_typebuf(char_u *str, int noremap, int offset, int nottyped, bool silent)
typebuf.tb_maplen += addlen;
if (silent || typebuf.tb_silent > offset) {
typebuf.tb_silent += addlen;
- cmd_silent = TRUE;
+ cmd_silent = true;
}
if (typebuf.tb_no_abbr_cnt && offset == 0) /* and not used for abbrev.s */
typebuf.tb_no_abbr_cnt += addlen;
@@ -973,7 +980,7 @@ void ins_char_typebuf(int c)
buf[2] = (char_u)K_THIRD(c);
buf[3] = NUL;
} else {
- buf[(*mb_char2bytes)(c, buf)] = NUL;
+ buf[utf_char2bytes(c, buf)] = NUL;
}
(void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
}
@@ -1078,9 +1085,10 @@ void del_typebuf(int len, int offset)
/* Reset the flag that text received from a client or from feedkeys()
* was inserted in the typeahead buffer. */
- typebuf_was_filled = FALSE;
- if (++typebuf.tb_change_cnt == 0)
+ typebuf_was_filled = false;
+ if (++typebuf.tb_change_cnt == 0) {
typebuf.tb_change_cnt = 1;
+ }
}
/*
@@ -1091,21 +1099,19 @@ static void gotchars(char_u *chars, size_t len)
{
char_u *s = chars;
int c;
- char_u buf[2];
// remember how many chars were last recorded
if (Recording) {
last_recorded_len += len;
}
- buf[1] = NUL;
while (len--) {
// Handle one byte at a time; no translation to be done.
c = *s++;
updatescript(c);
if (Recording) {
- buf[0] = (char_u)c;
+ char buf[2] = { (char)c, NUL };
add_buff(&recordbuff, buf, 1L);
}
}
@@ -1142,7 +1148,7 @@ void alloc_typebuf(void)
typebuf.tb_buf = xmalloc(TYPELEN_INIT);
typebuf.tb_noremap = xmalloc(TYPELEN_INIT);
typebuf.tb_buflen = TYPELEN_INIT;
- typebuf.tb_off = 0;
+ typebuf.tb_off = MAXMAPLEN + 4; // can insert without realloc
typebuf.tb_len = 0;
typebuf.tb_maplen = 0;
typebuf.tb_silent = 0;
@@ -1156,14 +1162,16 @@ void alloc_typebuf(void)
*/
void free_typebuf(void)
{
- if (typebuf.tb_buf == typebuf_init)
- EMSG2(_(e_intern2), "Free typebuf 1");
- else
+ if (typebuf.tb_buf == typebuf_init) {
+ internal_error("Free typebuf 1");
+ } else {
xfree(typebuf.tb_buf);
- if (typebuf.tb_noremap == noremapbuf_init)
- EMSG2(_(e_intern2), "Free typebuf 2");
- else
+ }
+ if (typebuf.tb_noremap == noremapbuf_init) {
+ internal_error("Free typebuf 2");
+ } else {
xfree(typebuf.tb_noremap);
+ }
}
/*
@@ -1244,10 +1252,13 @@ openscript (
++curscript;
/* use NameBuff for expanded name */
expand_env(name, NameBuff, MAXPATHL);
- if ((scriptin[curscript] = mch_fopen((char *)NameBuff, READBIN)) == NULL) {
- EMSG2(_(e_notopen), name);
- if (curscript)
- --curscript;
+ int error;
+ if ((scriptin[curscript] = file_open_new(&error, (char *)NameBuff,
+ kFileReadOnly, 0)) == NULL) {
+ emsgf(_(e_notopen_2), name, os_strerror(error));
+ if (curscript) {
+ curscript--;
+ }
return;
}
save_typebuf();
@@ -1297,7 +1308,7 @@ static void closescript(void)
free_typebuf();
typebuf = saved_typebuf[curscript];
- fclose(scriptin[curscript]);
+ file_free(scriptin[curscript], false);
scriptin[curscript] = NULL;
if (curscript > 0)
--curscript;
@@ -1320,32 +1331,32 @@ int using_script(void)
return scriptin[curscript] != NULL;
}
-/*
- * This function is called just before doing a blocking wait. Thus after
- * waiting 'updatetime' for a character to arrive.
- */
+/// This function is called just before doing a blocking wait. Thus after
+/// waiting 'updatetime' for a character to arrive.
void before_blocking(void)
{
updatescript(0);
- if (may_garbage_collect)
- garbage_collect();
+ if (may_garbage_collect) {
+ garbage_collect(false);
+ }
}
-/*
- * updatescipt() is called when a character can be written into the script file
- * or when we have waited some time for a character (c == 0)
- *
- * All the changed memfiles are synced if c == 0 or when the number of typed
- * characters reaches 'updatecount' and 'updatecount' is non-zero.
- */
-void updatescript(int c)
+/// updatescript() is called when a character can be written to the script file
+/// or when we have waited some time for a character (c == 0).
+///
+/// All the changed memfiles are synced if c == 0 or when the number of typed
+/// characters reaches 'updatecount' and 'updatecount' is non-zero.
+static void updatescript(int c)
{
static int count = 0;
- if (c && scriptout)
+ if (c && scriptout) {
putc(c, scriptout);
- if (c == 0 || (p_uc > 0 && ++count >= p_uc)) {
- ml_sync_all(c == 0, TRUE);
+ }
+ bool idle = (c == 0);
+ if (idle || (p_uc > 0 && ++count >= p_uc)) {
+ ml_sync_all(idle, true,
+ (!!p_fs || idle)); // Always fsync at idle (CursorHold).
count = 0;
}
}
@@ -1366,10 +1377,11 @@ int vgetc(void)
char_u buf[MB_MAXBYTES + 1];
int i;
- /* Do garbage collection when garbagecollect() was called previously and
- * we are now at the toplevel. */
- if (may_garbage_collect && want_garbage_collect)
- garbage_collect();
+ // Do garbage collection when garbagecollect() was called previously and
+ // we are now at the toplevel.
+ if (may_garbage_collect && want_garbage_collect) {
+ garbage_collect(false);
+ }
/*
* If a character was put back with vungetc, it was already processed.
@@ -1387,27 +1399,20 @@ int vgetc(void)
for (;; ) { // this is done twice if there are modifiers
bool did_inc = false;
if (mod_mask) { // no mapping after modifier has been read
- ++no_mapping;
- ++allow_keys;
+ no_mapping++;
did_inc = true; // mod_mask may change value
}
c = vgetorpeek(true);
if (did_inc) {
- --no_mapping;
- --allow_keys;
+ no_mapping--;
}
- /* Get two extra bytes for special keys */
- if (c == K_SPECIAL
- ) {
- int save_allow_keys = allow_keys;
-
- ++no_mapping;
- allow_keys = 0; /* make sure BS is not found */
- c2 = vgetorpeek(TRUE); /* no mapping for these chars */
- c = vgetorpeek(TRUE);
- --no_mapping;
- allow_keys = save_allow_keys;
+ // Get two extra bytes for special keys
+ if (c == K_SPECIAL) {
+ no_mapping++;
+ c2 = vgetorpeek(true); // no mapping for these chars
+ c = vgetorpeek(true);
+ no_mapping--;
if (c2 == KS_MODIFIER) {
mod_mask = c;
continue;
@@ -1485,8 +1490,8 @@ int vgetc(void)
buf[i] = CSI;
}
}
- --no_mapping;
- c = (*mb_ptr2char)(buf);
+ no_mapping--;
+ c = utf_ptr2char(buf);
}
break;
@@ -1535,6 +1540,7 @@ int plain_vgetc(void)
* Check if a character is available, such that vgetc() will not block.
* If the next character is a special character or multi-byte, the returned
* character is not valid!.
+ * Returns NUL if no character is available.
*/
int vpeekc(void)
{
@@ -1568,7 +1574,7 @@ int char_avail(void)
no_mapping++;
retval = vpeekc();
- --no_mapping;
+ no_mapping--;
return retval != NUL;
}
@@ -1583,29 +1589,28 @@ vungetc ( /* unget one character (can only be done once!) */
old_mouse_col = mouse_col;
}
-/*
- * get a character:
- * 1. from the stuffbuffer
- * This is used for abbreviated commands like "D" -> "d$".
- * Also used to redo a command for ".".
- * 2. from the typeahead buffer
- * Stores text obtained previously but not used yet.
- * Also stores the result of mappings.
- * Also used for the ":normal" command.
- * 3. from the user
- * This may do a blocking wait if "advance" is TRUE.
- *
- * if "advance" is TRUE (vgetc()):
- * really get the character.
- * KeyTyped is set to TRUE in the case the user typed the key.
- * KeyStuffed is TRUE if the character comes from the stuff buffer.
- * if "advance" is FALSE (vpeekc()):
- * just look whether there is a character available.
- *
- * When "no_mapping" is zero, checks for mappings in the current mode.
- * Only returns one byte (of a multi-byte character).
- * K_SPECIAL and CSI may be escaped, need to get two more bytes then.
- */
+/// Gets a character:
+/// 1. from the stuffbuffer
+/// This is used for abbreviated commands like "D" -> "d$".
+/// Also used to redo a command for ".".
+/// 2. from the typeahead buffer
+/// Stores text obtained previously but not used yet.
+/// Also stores the result of mappings.
+/// Also used for the ":normal" command.
+/// 3. from the user
+/// This may do a blocking wait if "advance" is TRUE.
+///
+/// if "advance" is TRUE (vgetc()):
+/// Really get the character.
+/// KeyTyped is set to TRUE in the case the user typed the key.
+/// KeyStuffed is TRUE if the character comes from the stuff buffer.
+/// if "advance" is FALSE (vpeekc()):
+/// Just look whether there is a character available.
+/// Return NUL if not.
+///
+/// When `no_mapping` (global) is zero, checks for mappings in the current mode.
+/// Only returns one byte (of a multi-byte character).
+/// K_SPECIAL and CSI may be escaped, need to get two more bytes then.
static int vgetorpeek(int advance)
{
int c, c1;
@@ -1669,10 +1674,10 @@ static int vgetorpeek(int advance)
}
if (c != NUL && !got_int) {
if (advance) {
- /* KeyTyped = FALSE; When the command that stuffed something
- * was typed, behave like the stuffed command was typed.
- * needed for CTRL-W CTRl-] to open a fold, for example. */
- KeyStuffed = TRUE;
+ // KeyTyped = false; When the command that stuffed something
+ // was typed, behave like the stuffed command was typed.
+ // needed for CTRL-W CTRL-] to open a fold, for example.
+ KeyStuffed = true;
}
if (typebuf.tb_no_abbr_cnt == 0)
typebuf.tb_no_abbr_cnt = 1; /* no abbreviations now */
@@ -1695,22 +1700,20 @@ static int vgetorpeek(int advance)
os_breakcheck(); /* check for CTRL-C */
keylen = 0;
if (got_int) {
- /* flush all input */
- c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L,
- typebuf.tb_change_cnt);
- /*
- * If inchar() returns TRUE (script file was active) or we
- * are inside a mapping, get out of insert mode.
- * Otherwise we behave like having gotten a CTRL-C.
- * As a result typing CTRL-C in insert mode will
- * really insert a CTRL-C.
- */
+ // flush all input
+ c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L);
+ // If inchar() returns TRUE (script file was active) or we
+ // are inside a mapping, get out of insert mode.
+ // Otherwise we behave like having gotten a CTRL-C.
+ // As a result typing CTRL-C in insert mode will
+ // really insert a CTRL-C.
if ((c || typebuf.tb_maplen)
- && (State & (INSERT + CMDLINE)))
+ && (State & (INSERT + CMDLINE))) {
c = ESC;
- else
+ } else {
c = Ctrl_C;
- flush_buffers(TRUE); /* flush all typeahead */
+ }
+ flush_buffers(FLUSH_INPUT); // flush all typeahead
if (advance) {
/* Also record this character, it might be needed to
@@ -1718,7 +1721,7 @@ static int vgetorpeek(int advance)
*typebuf.tb_buf = (char_u)c;
gotchars(typebuf.tb_buf, 1);
}
- cmd_silent = FALSE;
+ cmd_silent = false;
break;
} else if (typebuf.tb_len > 0) {
@@ -1810,7 +1813,7 @@ static int vgetorpeek(int advance)
* <M-a> and then changing 'encoding'. Beware
* that 0x80 is escaped. */
char_u *p1 = mp->m_keys;
- char_u *p2 = mb_unescape(&p1);
+ char_u *p2 = (char_u *)mb_unescape((const char **)&p1);
if (has_mbyte && p2 != NULL && MB_BYTE2LEN(c1) > MB_PTR2LEN(p2))
mlen = 0;
@@ -1852,16 +1855,21 @@ static int vgetorpeek(int advance)
keylen = KEYLEN_PART_MAP;
break;
}
- } else if (keylen > mp_match_len) {
- /* found a longer match */
+ } else if (keylen > mp_match_len
+ || (keylen == mp_match_len
+ && mp_match != NULL
+ && (mp_match->m_mode & LANGMAP) == 0
+ && (mp->m_mode & LANGMAP) != 0)) {
+ // found a longer match
mp_match = mp;
mp_match_len = keylen;
}
- } else
- /* No match; may have to check for
- * termcode at next character. */
- if (max_mlen < mlen)
- max_mlen = mlen;
+ } else {
+ // No match; may have to check for termcode at next character.
+ if (max_mlen < mlen) {
+ max_mlen = mlen;
+ }
+ }
}
}
@@ -1888,9 +1896,8 @@ static int vgetorpeek(int advance)
(size_t)(mlen - typebuf.tb_maplen));
}
- del_typebuf(mlen, 0); /* remove the chars */
- set_option_value((char_u *)"paste",
- (long)!p_paste, NULL, 0);
+ del_typebuf(mlen, 0); // Remove the chars.
+ set_option_value("paste", !p_paste, NULL, 0);
if (!(State & INSERT)) {
msg_col = 0;
msg_row = (int)Rows - 1;
@@ -1913,63 +1920,30 @@ static int vgetorpeek(int advance)
if ((mp == NULL || max_mlen >= mp_match_len)
&& keylen != KEYLEN_PART_MAP) {
- /*
- * When no matching mapping found or found a
- * non-matching mapping that matches at least what the
- * matching mapping matched:
- * Check if we have a terminal code, when:
- * mapping is allowed,
- * keys have not been mapped,
- * and not an ESC sequence, not in insert mode or
- * p_ek is on,
- * and when not timed out,
- */
- if ((no_mapping == 0 || allow_keys != 0)
- && (typebuf.tb_maplen == 0
- || (p_remap && typebuf.tb_noremap[
- typebuf.tb_off] == RM_YES))
- && !timedout) {
- keylen = 0;
- } else
- keylen = 0;
- if (keylen == 0) { /* no matching terminal code */
- /* When there was a matching mapping and no
- * termcode could be replaced after another one,
- * use that mapping (loop around). If there was
- * no mapping use the character from the
- * typeahead buffer right here. */
- if (mp == NULL) {
- /*
- * get a character: 2. from the typeahead buffer
- */
- c = typebuf.tb_buf[typebuf.tb_off] & 255;
- if (advance) { /* remove chars from tb_buf */
- cmd_silent = (typebuf.tb_silent > 0);
- if (typebuf.tb_maplen > 0)
- KeyTyped = FALSE;
- else {
- KeyTyped = TRUE;
- /* write char to script file(s) */
- gotchars(typebuf.tb_buf
- + typebuf.tb_off, 1);
- }
- KeyNoremap = typebuf.tb_noremap[
- typebuf.tb_off];
- del_typebuf(1, 0);
+ // No matching mapping found or found a non-matching mapping that
+ // matches at least what the matching mapping matched
+ keylen = 0;
+ // If there was no mapping, use the character from the typeahead
+ // buffer right here. Otherwise, use the mapping (loop around).
+ if (mp == NULL) {
+ // get a character: 2. from the typeahead buffer
+ c = typebuf.tb_buf[typebuf.tb_off] & 255;
+ if (advance) { // remove chars from tb_buf
+ cmd_silent = (typebuf.tb_silent > 0);
+ if (typebuf.tb_maplen > 0) {
+ KeyTyped = false;
+ } else {
+ KeyTyped = true;
+ // write char to script file(s)
+ gotchars(typebuf.tb_buf + typebuf.tb_off, 1);
}
- break; /* got character, break for loop */
+ KeyNoremap = typebuf.tb_noremap[typebuf.tb_off];
+ del_typebuf(1, 0);
}
- }
- if (keylen > 0) { /* full matching terminal code */
- continue; /* try mapping again */
- }
-
- /* Partial match: get some more characters. When a
- * matching mapping was found use that one. */
- if (mp == NULL || keylen < 0)
- keylen = KEYLEN_PART_KEY;
- else
+ break; // got character, break for loop
+ } else {
keylen = mp_match_len;
+ }
}
/* complete match */
@@ -1980,8 +1954,9 @@ static int vgetorpeek(int advance)
char_u *save_m_keys;
char_u *save_m_str;
- // write chars to script file(s)
- if (keylen > typebuf.tb_maplen) {
+ // Write chars to script file(s)
+ // Note: :lmap mappings are written *after* being applied. #5658
+ if (keylen > typebuf.tb_maplen && (mp->m_mode & LANGMAP) == 0) {
gotchars(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_maplen,
(size_t)(keylen - typebuf.tb_maplen));
}
@@ -1999,8 +1974,8 @@ static int vgetorpeek(int advance)
redrawcmdline();
else
setcursor();
- flush_buffers(FALSE);
- mapdepth = 0; /* for next one */
+ flush_buffers(FLUSH_MINIMAL);
+ mapdepth = 0; // for next one
c = -1;
break;
}
@@ -2056,6 +2031,12 @@ static int vgetorpeek(int advance)
else {
int noremap;
+ // If this is a LANGMAP mapping, then we didn't record the keys
+ // at the start of the function and have to record them now.
+ if (keylen > typebuf.tb_maplen && (mp->m_mode & LANGMAP) != 0) {
+ gotchars(s, STRLEN(s));
+ }
+
if (save_m_noremap != REMAP_YES)
noremap = save_m_noremap;
else if (
@@ -2095,18 +2076,17 @@ static int vgetorpeek(int advance)
c = 0;
new_wcol = curwin->w_wcol;
new_wrow = curwin->w_wrow;
- if ( advance
- && typebuf.tb_len == 1
- && typebuf.tb_buf[typebuf.tb_off] == ESC
- && !no_mapping
- && ex_normal_busy == 0
- && typebuf.tb_maplen == 0
- && (State & INSERT)
- && (p_timeout
- || (keylen == KEYLEN_PART_KEY && p_ttimeout))
- && (c = inchar(typebuf.tb_buf + typebuf.tb_off
- + typebuf.tb_len, 3, 25L,
- typebuf.tb_change_cnt)) == 0) {
+ if (advance
+ && typebuf.tb_len == 1
+ && typebuf.tb_buf[typebuf.tb_off] == ESC
+ && !no_mapping
+ && ex_normal_busy == 0
+ && typebuf.tb_maplen == 0
+ && (State & INSERT)
+ && (p_timeout
+ || (keylen == KEYLEN_PART_KEY && p_ttimeout))
+ && (c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
+ 3, 25L)) == 0) {
colnr_T col = 0, vcol;
char_u *ptr;
@@ -2140,8 +2120,8 @@ static int vgetorpeek(int advance)
++col;
}
curwin->w_wrow = curwin->w_cline_row
- + curwin->w_wcol / curwin->w_width;
- curwin->w_wcol %= curwin->w_width;
+ + curwin->w_wcol / curwin->w_grid.Columns;
+ curwin->w_wcol %= curwin->w_grid.Columns;
curwin->w_wcol += curwin_col_off();
col = 0; /* no correction needed */
} else {
@@ -2149,17 +2129,18 @@ static int vgetorpeek(int advance)
col = curwin->w_cursor.col - 1;
}
} else if (curwin->w_p_wrap && curwin->w_wrow) {
- --curwin->w_wrow;
- curwin->w_wcol = curwin->w_width - 1;
+ curwin->w_wrow--;
+ curwin->w_wcol = curwin->w_grid.Columns - 1;
col = curwin->w_cursor.col - 1;
}
- if (has_mbyte && col > 0 && curwin->w_wcol > 0) {
- /* Correct when the cursor is on the right halve
- * of a double-wide character. */
+ if (col > 0 && curwin->w_wcol > 0) {
+ // Correct when the cursor is on the right halve
+ // of a double-wide character.
ptr = get_cursor_line_ptr();
- col -= (*mb_head_off)(ptr, ptr + col);
- if ((*mb_ptr2cells)(ptr + col) > 1)
- --curwin->w_wcol;
+ col -= utf_head_off(ptr, ptr + col);
+ if (utf_ptr2cells(ptr + col) > 1) {
+ curwin->w_wcol--;
+ }
}
}
setcursor();
@@ -2277,6 +2258,11 @@ static int vgetorpeek(int advance)
/*
* get a character: 3. from the user - get it
*/
+ if (typebuf.tb_len == 0) {
+ // timedout may have been set while waiting for a mapping
+ // that has a <Nop> RHS.
+ timedout = false;
+ }
wait_tb_len = typebuf.tb_len;
c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1,
@@ -2288,7 +2274,7 @@ static int vgetorpeek(int advance)
? -1L
: ((keylen == KEYLEN_PART_KEY && p_ttm >= 0)
? p_ttm
- : p_tm)), typebuf.tb_change_cnt);
+ : p_tm)));
if (i != 0)
pop_showcmd();
@@ -2369,17 +2355,15 @@ static int vgetorpeek(int advance)
* Return the number of obtained characters.
* Return -1 when end of input script reached.
*/
-int
-inchar (
+int inchar(
char_u *buf,
int maxlen,
- long wait_time, /* milli seconds */
- int tb_change_cnt
+ long wait_time // milli seconds
)
{
- int len = 0; /* init for GCC */
- int retesc = FALSE; /* return ESC with gotint */
- int script_char;
+ int len = 0; // Init for GCC.
+ int retesc = false; // Return ESC with gotint.
+ const int tb_change_cnt = typebuf.tb_change_cnt;
if (wait_time == -1L || wait_time > 100L) {
// flush output before waiting
@@ -2397,45 +2381,38 @@ inchar (
}
undo_off = FALSE; /* restart undo now */
- /*
- * Get a character from a script file if there is one.
- * If interrupted: Stop reading script files, close them all.
- */
- script_char = -1;
- while (scriptin[curscript] != NULL && script_char < 0
- && !ignore_script
- ) {
-
-
- if (got_int || (script_char = getc(scriptin[curscript])) < 0) {
- /* Reached EOF.
- * Careful: closescript() frees typebuf.tb_buf[] and buf[] may
- * point inside typebuf.tb_buf[]. Don't use buf[] after this! */
+ // Get a character from a script file if there is one.
+ // If interrupted: Stop reading script files, close them all.
+ ptrdiff_t read_size = -1;
+ while (scriptin[curscript] != NULL && read_size <= 0 && !ignore_script) {
+ char script_char;
+ if (got_int
+ || (read_size = file_read(scriptin[curscript], &script_char, 1)) != 1) {
+ // Reached EOF or some error occurred.
+ // Careful: closescript() frees typebuf.tb_buf[] and buf[] may
+ // point inside typebuf.tb_buf[]. Don't use buf[] after this!
closescript();
- /*
- * When reading script file is interrupted, return an ESC to get
- * back to normal mode.
- * Otherwise return -1, because typebuf.tb_buf[] has changed.
- */
- if (got_int)
- retesc = TRUE;
- else
+ // When reading script file is interrupted, return an ESC to get
+ // back to normal mode.
+ // Otherwise return -1, because typebuf.tb_buf[] has changed.
+ if (got_int) {
+ retesc = true;
+ } else {
return -1;
+ }
} else {
buf[0] = (char_u)script_char;
len = 1;
}
}
- if (script_char < 0) { /* did not get a character from script */
- /*
- * If we got an interrupt, skip all previously typed characters and
- * return TRUE if quit reading script file.
- * Stop reading typeahead when a single CTRL-C was read,
- * fill_input_buf() returns this when not able to read from stdin.
- * Don't use buf[] here, closescript() may have freed typebuf.tb_buf[]
- * and buf may be pointing inside typebuf.tb_buf[].
- */
+ if (read_size <= 0) { // Did not get a character from script.
+ // If we got an interrupt, skip all previously typed characters and
+ // return TRUE if quit reading script file.
+ // Stop reading typeahead when a single CTRL-C was read,
+ // fill_input_buf() returns this when not able to read from stdin.
+ // Don't use buf[] here, closescript() may have freed typebuf.tb_buf[]
+ // and buf may be pointing inside typebuf.tb_buf[].
if (got_int) {
#define DUM_LEN MAXMAPLEN * 3 + 3
char_u dum[DUM_LEN + 1];
@@ -2448,23 +2425,29 @@ inchar (
return retesc;
}
- /*
- * Always flush the output characters when getting input characters
- * from the user.
- */
+ // Always flush the output characters when getting input characters
+ // from the user.
ui_flush();
- /*
- * Fill up to a third of the buffer, because each character may be
- * tripled below.
- */
+ // Fill up to a third of the buffer, because each character may be
+ // tripled below.
len = os_inchar(buf, maxlen / 3, (int)wait_time, tb_change_cnt);
}
- if (typebuf_changed(tb_change_cnt))
+ // If the typebuf was changed further down, it is like nothing was added by
+ // this call.
+ if (typebuf_changed(tb_change_cnt)) {
return 0;
+ }
- return fix_input_buffer(buf, len, script_char >= 0);
+ // Note the change in the typeahead buffer, this matters for when
+ // vgetorpeek() is called recursively, e.g. using getchar(1) in a timer
+ // function.
+ if (len > 0 && ++typebuf.tb_change_cnt == 0) {
+ typebuf.tb_change_cnt = 1;
+ }
+
+ return fix_input_buffer(buf, len);
}
/*
@@ -2472,12 +2455,7 @@ inchar (
* buf[] must have room to triple the number of bytes!
* Returns the new length.
*/
-int
-fix_input_buffer (
- char_u *buf,
- int len,
- int script /* TRUE when reading from a script */
-)
+int fix_input_buffer(char_u *buf, int len)
{
if (!using_script()) {
// Should not escape K_SPECIAL/CSI reading input from the user because vim
@@ -2494,12 +2472,10 @@ fix_input_buffer (
// Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
// Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
// Replace CSI by K_SPECIAL KS_EXTRA KE_CSI
- // Don't replace K_SPECIAL when reading a script file.
for (i = len; --i >= 0; ++p) {
if (p[0] == NUL
|| (p[0] == K_SPECIAL
- && !script
- && (i < 2 || p[1] != KS_EXTRA))) {
+ && (i < 2 || p[1] != KS_EXTRA))) {
memmove(p + 3, p + 1, (size_t)i);
p[2] = (char_u)K_THIRD(p[0]);
p[1] = (char_u)K_SECOND(p[0]);
@@ -2581,7 +2557,6 @@ do_map (
bool unique = false;
bool nowait = false;
bool silent = false;
- bool special = false;
bool expr = false;
int noremap;
char_u *orig_rhs;
@@ -2627,12 +2602,9 @@ do_map (
continue;
}
- /*
- * Check for "<special>": accept special keys in <>
- */
+ // Ignore obsolete "<special>" modifier.
if (STRNCMP(keys, "<special>", 9) == 0) {
keys = skipwhite(keys + 9);
- special = true;
continue;
}
@@ -2701,7 +2673,7 @@ do_map (
// needs to be freed later (*keys_buf and *arg_buf).
// replace_termcodes() also removes CTRL-Vs and sometimes backslashes.
if (haskey) {
- keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, special,
+ keys = replace_termcodes(keys, STRLEN(keys), &keys_buf, true, true, true,
CPO_TO_CPO_FLAGS);
}
orig_rhs = rhs;
@@ -2709,7 +2681,7 @@ do_map (
if (STRICMP(rhs, "<nop>") == 0) { // "<Nop>" means nothing
rhs = (char_u *)"";
} else {
- rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, false, true, special,
+ rhs = replace_termcodes(rhs, STRLEN(rhs), &arg_buf, false, true, true,
CPO_TO_CPO_FLAGS);
}
}
@@ -3165,11 +3137,11 @@ map_clear_int (
}
}
-/*
- * Return characters to represent the map mode in an allocated string.
- * Returns NULL when out of memory.
- */
-char_u *map_mode_to_chars(int mode)
+/// Return characters to represent the map mode in an allocated string
+///
+/// @return [allocated] NUL-terminated string with characters.
+char *map_mode_to_chars(int mode)
+ FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET
{
garray_T mapmode;
@@ -3202,7 +3174,7 @@ char_u *map_mode_to_chars(int mode)
}
ga_append(&mapmode, NUL);
- return (char_u *)mapmode.ga_data;
+ return (char *)mapmode.ga_data;
}
static void
@@ -3211,8 +3183,11 @@ showmap (
int local /* TRUE for buffer-local map */
)
{
- int len = 1;
- char_u *mapchars;
+ size_t len = 1;
+
+ if (message_filtered(mp->m_keys) && message_filtered(mp->m_str)) {
+ return;
+ }
if (msg_didout || msg_silent != 0) {
msg_putchar('\n');
@@ -3220,29 +3195,30 @@ showmap (
return;
}
- mapchars = map_mode_to_chars(mp->m_mode);
- if (mapchars != NULL) {
+ {
+ char *const mapchars = map_mode_to_chars(mp->m_mode);
msg_puts(mapchars);
- len = (int)STRLEN(mapchars);
+ len = strlen(mapchars);
xfree(mapchars);
}
while (++len <= 3)
msg_putchar(' ');
- /* Display the LHS. Get length of what we write. */
- len = msg_outtrans_special(mp->m_keys, TRUE);
+ // Display the LHS. Get length of what we write.
+ len = (size_t)msg_outtrans_special(mp->m_keys, true);
do {
msg_putchar(' '); /* padd with blanks */
++len;
} while (len < 12);
- if (mp->m_noremap == REMAP_NONE)
- msg_puts_attr((char_u *)"*", hl_attr(HLF_8));
- else if (mp->m_noremap == REMAP_SCRIPT)
- msg_puts_attr((char_u *)"&", hl_attr(HLF_8));
- else
+ if (mp->m_noremap == REMAP_NONE) {
+ msg_puts_attr("*", HL_ATTR(HLF_8));
+ } else if (mp->m_noremap == REMAP_SCRIPT) {
+ msg_puts_attr("&", HL_ATTR(HLF_8));
+ } else {
msg_putchar(' ');
+ }
if (local)
msg_putchar('@');
@@ -3251,11 +3227,11 @@ showmap (
/* Use FALSE below if we only want things like <Up> to show up as such on
* the rhs, and not M-x etc, TRUE gets both -- webb */
- if (*mp->m_str == NUL)
- msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
- else {
- /* Remove escaping of CSI, because "m_str" is in a format to be used
- * as typeahead. */
+ if (*mp->m_str == NUL) {
+ msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
+ } else {
+ // Remove escaping of CSI, because "m_str" is in a format to be used
+ // as typeahead.
char_u *s = vim_strsave(mp->m_str);
vim_unescape_csi(s);
msg_outtrans_special(s, FALSE);
@@ -3266,82 +3242,99 @@ showmap (
ui_flush(); /* show one line at a time */
}
-/*
- * Return TRUE if a map exists that has "str" in the rhs for mode "modechars".
- * Recognize termcap codes in "str".
- * Also checks mappings local to the current buffer.
- */
-int map_to_exists(char_u *str, char_u *modechars, int abbr)
+/// Check if a map exists that has given string in the rhs
+///
+/// Also checks mappings local to the current buffer.
+///
+/// @param[in] str String which mapping must have in the rhs. Termcap codes
+/// are recognized in this argument.
+/// @param[in] modechars Mode(s) in which mappings are checked.
+/// @param[in] abbr true if checking abbreviations in place of mappings.
+///
+/// @return true if there is at least one mapping with given parameters.
+bool map_to_exists(const char *const str, const char *const modechars,
+ const bool abbr)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
int mode = 0;
- char_u *rhs;
- char_u *buf;
int retval;
- rhs = replace_termcodes(str, STRLEN(str), &buf, false, true, false,
- CPO_TO_CPO_FLAGS);
-
- if (vim_strchr(modechars, 'n') != NULL)
- mode |= NORMAL;
- if (vim_strchr(modechars, 'v') != NULL)
- mode |= VISUAL + SELECTMODE;
- if (vim_strchr(modechars, 'x') != NULL)
- mode |= VISUAL;
- if (vim_strchr(modechars, 's') != NULL)
- mode |= SELECTMODE;
- if (vim_strchr(modechars, 'o') != NULL)
- mode |= OP_PENDING;
- if (vim_strchr(modechars, 'i') != NULL)
- mode |= INSERT;
- if (vim_strchr(modechars, 'l') != NULL)
- mode |= LANGMAP;
- if (vim_strchr(modechars, 'c') != NULL)
- mode |= CMDLINE;
-
- retval = map_to_exists_mode(rhs, mode, abbr);
+ char_u *buf;
+ char_u *const rhs = replace_termcodes((const char_u *)str, strlen(str), &buf,
+ false, true, true,
+ CPO_TO_CPO_FLAGS);
+
+#define MAPMODE(mode, modechars, chr, modeflags) \
+ do { \
+ if (strchr(modechars, chr) != NULL) { \
+ mode |= modeflags; \
+ } \
+ } while (0)
+ MAPMODE(mode, modechars, 'n', NORMAL);
+ MAPMODE(mode, modechars, 'v', VISUAL|SELECTMODE);
+ MAPMODE(mode, modechars, 'x', VISUAL);
+ MAPMODE(mode, modechars, 's', SELECTMODE);
+ MAPMODE(mode, modechars, 'o', OP_PENDING);
+ MAPMODE(mode, modechars, 'i', INSERT);
+ MAPMODE(mode, modechars, 'l', LANGMAP);
+ MAPMODE(mode, modechars, 'c', CMDLINE);
+#undef MAPMODE
+
+ retval = map_to_exists_mode((const char *)rhs, mode, abbr);
xfree(buf);
return retval;
}
-/*
- * Return TRUE if a map exists that has "str" in the rhs for mode "mode".
- * Also checks mappings local to the current buffer.
- */
-int map_to_exists_mode(char_u *rhs, int mode, int abbr)
+/// Check if a map exists that has given string in the rhs
+///
+/// Also checks mappings local to the current buffer.
+///
+/// @param[in] rhs String which mapping must have in the rhs. Termcap codes
+/// are recognized in this argument.
+/// @param[in] mode Mode(s) in which mappings are checked.
+/// @param[in] abbr true if checking abbreviations in place of mappings.
+///
+/// @return true if there is at least one mapping with given parameters.
+int map_to_exists_mode(const char *const rhs, const int mode, const bool abbr)
{
mapblock_T *mp;
int hash;
- int expand_buffer = FALSE;
+ bool expand_buffer = false;
validate_maphash();
- /* Do it twice: once for global maps and once for local maps. */
- for (;; ) {
- for (hash = 0; hash < 256; ++hash) {
+ // Do it twice: once for global maps and once for local maps.
+ for (;;) {
+ for (hash = 0; hash < 256; hash++) {
if (abbr) {
- if (hash > 0) /* there is only one abbr list */
+ if (hash > 0) { // There is only one abbr list.
break;
- if (expand_buffer)
+ }
+ if (expand_buffer) {
mp = curbuf->b_first_abbr;
- else
+ } else {
mp = first_abbr;
- } else if (expand_buffer)
+ }
+ } else if (expand_buffer) {
mp = curbuf->b_maphash[hash];
- else
+ } else {
mp = maphash[hash];
+ }
for (; mp; mp = mp->m_next) {
if ((mp->m_mode & mode)
- && strstr((char *)mp->m_str, (char *)rhs) != NULL)
- return TRUE;
+ && strstr((char *)mp->m_str, rhs) != NULL) {
+ return true;
+ }
}
}
- if (expand_buffer)
+ if (expand_buffer) {
break;
- expand_buffer = TRUE;
+ }
+ expand_buffer = true;
}
- return FALSE;
+ return false;
}
/*
@@ -3397,6 +3390,10 @@ set_context_in_map_cmd (
arg = skipwhite(arg + 8);
continue;
}
+ if (STRNCMP(arg, "<special>", 9) == 0) {
+ arg = skipwhite(arg + 9);
+ continue;
+ }
if (STRNCMP(arg, "<script>", 8) == 0) {
arg = skipwhite(arg + 8);
continue;
@@ -3439,21 +3436,24 @@ int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file)
for (round = 1; round <= 2; ++round) {
count = 0;
- for (i = 0; i < 6; ++i) {
- if (i == 0)
+ for (i = 0; i < 7; i++) {
+ if (i == 0) {
p = (char_u *)"<silent>";
- else if (i == 1)
+ } else if (i == 1) {
p = (char_u *)"<unique>";
- else if (i == 2)
+ } else if (i == 2) {
p = (char_u *)"<script>";
- else if (i == 3)
+ } else if (i == 3) {
p = (char_u *)"<expr>";
- else if (i == 4 && !expand_buffer)
+ } else if (i == 4 && !expand_buffer) {
p = (char_u *)"<buffer>";
- else if (i == 5)
+ } else if (i == 5) {
p = (char_u *)"<nowait>";
- else
+ } else if (i == 6) {
+ p = (char_u *)"<special>";
+ } else {
continue;
+ }
if (vim_regexec(regmatch, p, (colnr_T)0)) {
if (round == 1)
@@ -3620,8 +3620,8 @@ int check_abbr(int c, char_u *ptr, int col, int mincol)
char_u *q = mp->m_keys;
int match;
- if (vim_strbyte(mp->m_keys, K_SPECIAL) != NULL) {
- /* might have CSI escaped mp->m_keys */
+ if (strchr((const char *)mp->m_keys, K_SPECIAL) != NULL) {
+ // Might have CSI escaped mp->m_keys.
q = vim_strsave(mp->m_keys);
vim_unescape_csi(q);
qlen = (int)STRLEN(q);
@@ -3659,16 +3659,14 @@ int check_abbr(int c, char_u *ptr, int col, int mincol)
tb[j++] = (char_u)K_SECOND(c);
tb[j++] = (char_u)K_THIRD(c);
} else {
- if (c < ABBR_OFF && (c < ' ' || c > '~'))
- tb[j++] = Ctrl_V; /* special char needs CTRL-V */
- if (has_mbyte) {
- /* if ABBR_OFF has been added, remove it here */
- if (c >= ABBR_OFF)
- c -= ABBR_OFF;
- j += (*mb_char2bytes)(c, tb + j);
- } else {
- tb[j++] = (char_u)c;
+ if (c < ABBR_OFF && (c < ' ' || c > '~')) {
+ tb[j++] = Ctrl_V; // special char needs CTRL-V
}
+ // if ABBR_OFF has been added, remove it here.
+ if (c >= ABBR_OFF) {
+ c -= ABBR_OFF;
+ }
+ j += utf_char2bytes(c, tb + j);
}
tb[j] = NUL;
/* insert the last typed char */
@@ -3757,8 +3755,10 @@ eval_map_expr (
*/
char_u *vim_strsave_escape_csi(char_u *p)
{
- /* Need a buffer to hold up to three times as much. */
- char_u *res = xmalloc(STRLEN(p) * 3 + 1);
+ // Need a buffer to hold up to three times as much. Four in case of an
+ // illegal utf-8 byte:
+ // 0xc0 -> 0xc3 - 0x80 -> 0xc3 K_SPECIAL KS_SPECIAL KE_FILLER
+ char_u *res = xmalloc(STRLEN(p) * 4 + 1);
char_u *d = res;
for (char_u *s = p; *s != NUL; ) {
if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
@@ -3767,17 +3767,10 @@ char_u *vim_strsave_escape_csi(char_u *p)
*d++ = *s++;
*d++ = *s++;
} else {
- int len = mb_char2len(PTR2CHAR(s));
- int len2 = mb_ptr2len(s);
- /* Add character, possibly multi-byte to destination, escaping
- * CSI and K_SPECIAL. */
+ // Add character, possibly multi-byte to destination, escaping
+ // CSI and K_SPECIAL. Be careful, it can be an illegal byte!
d = add_char2buf(PTR2CHAR(s), d);
- while (len < len2) {
- /* add following combining char */
- d = add_char2buf(PTR2CHAR(s + len), d);
- len += mb_char2len(PTR2CHAR(s + len));
- }
- mb_ptr_adv(s);
+ s += MB_CPTR2LEN(s);
}
}
*d = NUL;
@@ -3823,8 +3816,7 @@ makemap (
char *cmd;
int abbr;
int hash;
- int did_cpo = FALSE;
- int i;
+ bool did_cpo = false;
validate_maphash();
@@ -3945,20 +3937,22 @@ makemap (
c1 = 't';
break;
default:
- EMSG(_("E228: makemap: Illegal mode"));
+ IEMSG(_("E228: makemap: Illegal mode"));
return FAIL;
}
do { /* do this twice if c2 is set, 3 times with c3 */
/* When outputting <> form, need to make sure that 'cpo'
* is set to the Vim default. */
if (!did_cpo) {
- if (*mp->m_str == NUL) /* will use <Nop> */
- did_cpo = TRUE;
- else
- for (i = 0; i < 2; ++i)
- for (p = (i ? mp->m_str : mp->m_keys); *p; ++p)
- if (*p == K_SPECIAL || *p == NL)
- did_cpo = TRUE;
+ if (*mp->m_str == NUL) { // Will use <Nop>.
+ did_cpo = true;
+ } else {
+ const char specials[] = { (char)(uint8_t)K_SPECIAL, NL, NUL };
+ if (strpbrk((const char *)mp->m_str, specials) != NULL
+ || strpbrk((const char *)mp->m_keys, specials) != NULL) {
+ did_cpo = true;
+ }
+ }
if (did_cpo) {
if (fprintf(fd, "let s:cpo_save=&cpo") < 0
|| put_eol(fd) < 0
@@ -4026,12 +4020,10 @@ int put_escstr(FILE *fd, char_u *strstart, int what)
return OK;
}
- for (; *str != NUL; ++str) {
- char_u *p;
-
- /* Check for a multi-byte character, which may contain escaped
- * K_SPECIAL and CSI bytes */
- p = mb_unescape(&str);
+ for (; *str != NUL; str++) {
+ // Check for a multi-byte character, which may contain escaped
+ // K_SPECIAL and CSI bytes.
+ const char *p = mb_unescape((const char **)&str);
if (p != NULL) {
while (*p != NUL)
if (fputc(*p++, fd) < 0)
@@ -4187,8 +4179,7 @@ void add_map(char_u *map, int mode)
}
// Translate an internal mapping/abbreviation representation into the
-// corresponding external one recognized by :map/:abbrev commands;
-// respects the current B/k/< settings of 'cpoption'.
+// corresponding external one recognized by :map/:abbrev commands.
//
// This function is called when expanding mappings/abbreviations on the
// command-line, and for building the "Ambiguous mapping..." error message.
@@ -4208,7 +4199,6 @@ static char_u * translate_mapping (
ga_init(&ga, 1, 40);
bool cpo_bslash = !(cpo_flags&FLAG_CPO_BSLASH);
- bool cpo_special = !(cpo_flags&FLAG_CPO_SPECI);
for (; *str; ++str) {
int c = *str;
@@ -4221,7 +4211,7 @@ static char_u * translate_mapping (
}
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
- if (expmap && cpo_special) {
+ if (expmap) {
ga_clear(&ga);
return NULL;
}
@@ -4232,8 +4222,8 @@ static char_u * translate_mapping (
}
str += 2;
}
- if (IS_SPECIAL(c) || modifiers) { /* special key */
- if (expmap && cpo_special) {
+ if (IS_SPECIAL(c) || modifiers) { // special key
+ if (expmap) {
ga_clear(&ga);
return NULL;
}
@@ -4243,7 +4233,7 @@ static char_u * translate_mapping (
}
if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V
- || (c == '<' && !cpo_special) || (c == '\\' && !cpo_bslash)) {
+ || (c == '\\' && !cpo_bslash)) {
ga_append(&ga, cpo_bslash ? Ctrl_V : '\\');
}
@@ -4265,3 +4255,90 @@ static bool typebuf_match_len(const uint8_t *str, int *mlen)
*mlen = i;
return str[i] == NUL; // matched the whole string
}
+
+/// Retrieve the mapblock at the index either globally or for a certain buffer
+///
+/// @param index The index in the maphash[]
+/// @param buf The buffer to get the maphash from. NULL for global
+mapblock_T *get_maphash(int index, buf_T *buf)
+ FUNC_ATTR_PURE
+{
+ if (index >= MAX_MAPHASH) {
+ return NULL;
+ }
+
+ return (buf == NULL) ? maphash[index] : buf->b_maphash[index];
+}
+
+/// Get command argument for <Cmd> key
+char_u * getcmdkeycmd(int promptc, void *cookie, int indent)
+{
+ garray_T line_ga;
+ int c1 = -1, c2;
+ int cmod = 0;
+ bool aborted = false;
+
+ ga_init(&line_ga, 1, 32);
+
+ no_mapping++;
+
+ got_int = false;
+ while (c1 != NUL && !aborted) {
+ ga_grow(&line_ga, 32);
+
+ if (vgetorpeek(false) == NUL) {
+ // incomplete <Cmd> is an error, because there is not much the user
+ // could do in this state.
+ EMSG(e_cmdmap_err);
+ aborted = true;
+ break;
+ }
+
+ // Get one character at a time.
+ c1 = vgetorpeek(true);
+ // Get two extra bytes for special keys
+ if (c1 == K_SPECIAL) {
+ c1 = vgetorpeek(true); // no mapping for these chars
+ c2 = vgetorpeek(true);
+ if (c1 == KS_MODIFIER) {
+ cmod = c2;
+ continue;
+ }
+ c1 = TO_SPECIAL(c1, c2);
+ }
+
+
+ if (got_int) {
+ aborted = true;
+ } else if (c1 == '\r' || c1 == '\n') {
+ c1 = NUL; // end the line
+ } else if (c1 == ESC) {
+ aborted = true;
+ } else if (c1 == K_COMMAND) {
+ // special case to give nicer error message
+ EMSG(e_cmdmap_repeated);
+ aborted = true;
+ } else if (IS_SPECIAL(c1)) {
+ if (c1 == K_SNR) {
+ ga_append(&line_ga, (char)K_SPECIAL);
+ ga_append(&line_ga, (char)KS_EXTRA);
+ ga_append(&line_ga, (char)KE_SNR);
+ } else {
+ EMSG2(e_cmdmap_key, get_special_key_name(c1, cmod));
+ aborted = true;
+ }
+ } else {
+ ga_append(&line_ga, (char)c1);
+ }
+
+ cmod = 0;
+ }
+
+ no_mapping--;
+
+ if (aborted) {
+ ga_clear(&line_ga);
+ }
+
+ return (char_u *)line_ga.ga_data;
+}
diff --git a/src/nvim/getchar.h b/src/nvim/getchar.h
index bdf65909b6..4f548d975a 100644
--- a/src/nvim/getchar.h
+++ b/src/nvim/getchar.h
@@ -1,17 +1,38 @@
#ifndef NVIM_GETCHAR_H
#define NVIM_GETCHAR_H
-/* Values for "noremap" argument of ins_typebuf(). Also used for
- * map->m_noremap and menu->noremap[]. */
-#define REMAP_YES 0 /* allow remapping */
-#define REMAP_NONE -1 /* no remapping */
-#define REMAP_SCRIPT -2 /* remap script-local mappings only */
-#define REMAP_SKIP -3 /* no remapping for first char */
+#include "nvim/os/fileio.h"
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/ex_cmds_defs.h"
+
+/// Values for "noremap" argument of ins_typebuf()
+///
+/// Also used for map->m_noremap and menu->noremap[].
+enum {
+ REMAP_YES = 0, ///< Allow remapping.
+ REMAP_NONE = -1, ///< No remapping.
+ REMAP_SCRIPT = -2, ///< Remap script-local mappings only.
+ REMAP_SKIP = -3, ///< No remapping for first char.
+} RemapValues;
+
+// Argument for flush_buffers().
+typedef enum {
+ FLUSH_MINIMAL,
+ FLUSH_TYPEAHEAD, // flush current typebuf contents
+ FLUSH_INPUT // flush typebuf and inchar() input
+} flush_buffers_T;
#define KEYLEN_PART_KEY -1 /* keylen value for incomplete key-code */
#define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */
#define KEYLEN_REMOVED 9999 /* keylen value for removed sequence */
+/// Maximum number of streams to read script from
+enum { NSCRIPT = 15 };
+
+/// Streams to read script from
+extern FileDescriptor *scriptin[NSCRIPT];
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "getchar.h.generated.h"
#endif
diff --git a/src/nvim/gettext.h b/src/nvim/gettext.h
new file mode 100644
index 0000000000..acc7e3a92c
--- /dev/null
+++ b/src/nvim/gettext.h
@@ -0,0 +1,23 @@
+#ifndef NVIM_GETTEXT_H
+#define NVIM_GETTEXT_H
+
+#ifdef HAVE_WORKING_LIBINTL
+# include <libintl.h>
+# define _(x) gettext((char *)(x))
+// XXX do we actually need this?
+# ifdef gettext_noop
+# define N_(x) gettext_noop(x)
+# else
+# define N_(x) x
+# endif
+# define NGETTEXT(x, xs, n) ngettext(x, xs, n)
+#else
+# define _(x) ((char *)(x))
+# define N_(x) x
+# define NGETTEXT(x, xs, n) ((n) == 1 ? (x) : (xs))
+# define bindtextdomain(x, y) // empty
+# define bind_textdomain_codeset(x, y) // empty
+# define textdomain(x) // empty
+#endif
+
+#endif // NVIM_GETTEXT_H
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index ed9862a264..2550fb8163 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -12,32 +12,14 @@
#include "nvim/syntax_defs.h"
#include "nvim/types.h"
#include "nvim/event/loop.h"
-
-/*
- * definition of global variables
- */
+#include "nvim/os/os_defs.h"
#define IOSIZE (1024+1) // file I/O and sprintf buffer size
-#define MAX_MCO 6 // maximum value for 'maxcombine'
-
# define MSG_BUF_LEN 480 // length of buffer for small messages
# define MSG_BUF_CLEN (MSG_BUF_LEN / 6) // cell length (worst case: utf-8
// takes 6 bytes for one cell)
-/*
- * Maximum length of a path (for non-unix systems) Make it a bit long, to stay
- * on the safe side. But not too long to put on the stack.
- * TODO(metrix78): Move this to os_defs.h
- */
-#ifndef MAXPATHL
-# ifdef MAXPATHLEN
-# define MAXPATHL MAXPATHLEN
-# else
-# define MAXPATHL 256
-# endif
-#endif
-
#ifdef WIN32
# define _PATHSEPSTR "\\"
#else
@@ -96,6 +78,11 @@ typedef enum {
kTrue = 1,
} TriState;
+EXTERN struct nvim_stats_s {
+ int64_t fsync;
+ int64_t redraw;
+} g_stats INIT(= { 0, 0 });
+
/* Values for "starting" */
#define NO_SCREEN 2 /* no screen updating yet */
#define NO_BUFFERS 1 /* not all buffers loaded yet */
@@ -104,59 +91,43 @@ typedef enum {
/*
* Number of Rows and Columns in the screen.
* Must be long to be able to use them as options in option.c.
- * Note: Use screen_Rows and screen_Columns to access items in ScreenLines[].
- * They may have different values when the screen wasn't (re)allocated yet
- * after setting Rows or Columns (e.g., when starting up).
+ * Note: Use default_grid.Rows and default_grid.Columns to access items in
+ * default_grid.chars[]. They may have different values when the screen
+ * wasn't (re)allocated yet after setting Rows or Columns (e.g., when starting
+ * up).
*/
-
-#define DFLT_COLS 80 /* default value for 'columns' */
-#define DFLT_ROWS 24 /* default value for 'lines' */
-
+#define DFLT_COLS 80 // default value for 'columns'
+#define DFLT_ROWS 24 // default value for 'lines'
EXTERN long Rows INIT(= DFLT_ROWS); // nr of rows in the screen
-
EXTERN long Columns INIT(= DFLT_COLS); // nr of columns in the screen
-/*
- * The characters and attributes cached for the screen.
- */
-typedef char_u schar_T;
-typedef unsigned short sattr_T;
-
-/*
- * The characters that are currently on the screen are kept in ScreenLines[].
- * It is a single block of characters, the size of the screen plus one line.
- * The attributes for those characters are kept in ScreenAttrs[].
- *
- * "LineOffset[n]" is the offset from ScreenLines[] for the start of line 'n'.
- * The same value is used for ScreenLinesUC[] and ScreenAttrs[].
- *
- * Note: before the screen is initialized and when out of memory these can be
- * NULL.
- */
-EXTERN schar_T *ScreenLines INIT(= NULL);
-EXTERN sattr_T *ScreenAttrs INIT(= NULL);
-EXTERN unsigned *LineOffset INIT(= NULL);
-EXTERN char_u *LineWraps INIT(= NULL); /* line wraps to next line */
-
-/*
- * When using Unicode characters (in UTF-8 encoding) the character in
- * ScreenLinesUC[] contains the Unicode for the character at this position, or
- * NUL when the character in ScreenLines[] is to be used (ASCII char).
- * The composing characters are to be drawn on top of the original character.
- * ScreenLinesC[0][off] is only to be used when ScreenLinesUC[off] != 0.
- * Note: These three are only allocated when enc_utf8 is set!
- */
-EXTERN u8char_T *ScreenLinesUC INIT(= NULL); /* decoded UTF-8 characters */
-EXTERN u8char_T *ScreenLinesC[MAX_MCO]; /* composing characters */
-EXTERN int Screen_mco INIT(= 0); /* value of p_mco used when
- allocating ScreenLinesC[] */
-
-/* Only used for euc-jp: Second byte of a character that starts with 0x8e.
- * These are single-width. */
-EXTERN schar_T *ScreenLines2 INIT(= NULL);
-
-EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
-EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
+// We use 64-bit file functions here, if available. E.g. ftello() returns
+// off_t instead of long, which helps if long is 32 bit and off_t is 64 bit.
+// We assume that when fseeko() is available then ftello() is too.
+// Note that Windows has different function names.
+#if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(__MINGW32__)
+typedef __int64 off_T;
+# ifdef __MINGW32__
+# define vim_lseek lseek64
+# define vim_fseek fseeko64
+# define vim_ftell ftello64
+# else
+# define vim_lseek _lseeki64
+# define vim_fseek _fseeki64
+# define vim_ftell _ftelli64
+# endif
+#else
+typedef off_t off_T;
+# ifdef HAVE_FSEEKO
+# define vim_lseek lseek
+# define vim_ftell ftello
+# define vim_fseek fseeko
+# else
+# define vim_lseek lseek
+# define vim_ftell ftell
+# define vim_fseek(a, b, c) fseek(a, (long)b, c)
+# endif
+#endif
/*
* When vgetc() is called, it sets mod_mask to the set of modifiers that are
@@ -182,8 +153,6 @@ EXTERN int cmdline_star INIT(= FALSE); /* cmdline is crypted */
EXTERN int exec_from_reg INIT(= FALSE); /* executing register */
-EXTERN int screen_cleared INIT(= FALSE); /* screen has been cleared */
-
/*
* When '$' is included in 'cpoptions' option set:
* When a change command is given that deletes only part of a line, a dollar
@@ -221,11 +190,8 @@ EXTERN int compl_cont_status INIT(= 0);
# define CONT_LOCAL 32 /* for ctrl_x_mode 0, ^X^P/^X^N do a local
* expansion, (eg use complete=.) */
-/*
- * Functions for putting characters in the command line,
- * while keeping ScreenLines[] updated.
- */
-EXTERN int cmdmsg_rl INIT(= FALSE); /* cmdline is drawn right to left */
+// state for putting characters in the message area
+EXTERN int cmdmsg_rl INIT(= false); // cmdline is drawn right to left
EXTERN int msg_col;
EXTERN int msg_row;
EXTERN int msg_scrolled; /* Number of screen lines that windows have
@@ -271,24 +237,18 @@ EXTERN int did_wait_return INIT(= FALSE); /* wait_return() was used and
nothing written since then */
EXTERN int need_maketitle INIT(= TRUE); /* call maketitle() soon */
-EXTERN int quit_more INIT(= FALSE); /* 'q' hit at "--more--" msg */
-#if defined(UNIX) || defined(MACOS_X)
-EXTERN int newline_on_exit INIT(= FALSE); /* did msg in altern. screen */
-EXTERN int intr_char INIT(= 0); /* extra interrupt character */
-#endif
-EXTERN int ex_keep_indent INIT(= FALSE); /* getexmodeline(): keep indent */
-EXTERN int vgetc_busy INIT(= 0); /* when inside vgetc() then > 0 */
+EXTERN int quit_more INIT(= false); // 'q' hit at "--more--" msg
+EXTERN int ex_keep_indent INIT(= false); // getexmodeline(): keep indent
+EXTERN int vgetc_busy INIT(= 0); // when inside vgetc() then > 0
EXTERN int didset_vim INIT(= FALSE); /* did set $VIM ourselves */
EXTERN int didset_vimruntime INIT(= FALSE); /* idem for $VIMRUNTIME */
-/*
- * Lines left before a "more" message. Ex mode needs to be able to reset this
- * after you type something.
- */
-EXTERN int lines_left INIT(= -1); /* lines left for listing */
-EXTERN int msg_no_more INIT(= FALSE); /* don't use more prompt, truncate
- messages */
+/// Lines left before a "more" message. Ex mode needs to be able to reset this
+/// after you type something.
+EXTERN int lines_left INIT(= -1); // lines left for listing
+EXTERN int msg_no_more INIT(= false); // don't use more prompt, truncate
+ // messages
EXTERN char_u *sourcing_name INIT( = NULL); /* name of error message source */
EXTERN linenr_T sourcing_lnum INIT(= 0); /* line number of the source file */
@@ -299,120 +259,100 @@ EXTERN int debug_did_msg INIT(= false); // did "debug mode" message
EXTERN int debug_tick INIT(= 0); // breakpoint change count
EXTERN int debug_backtrace_level INIT(= 0); // breakpoint backtrace level
-/* Values for "do_profiling". */
-#define PROF_NONE 0 /* profiling not started */
-#define PROF_YES 1 /* profiling busy */
-#define PROF_PAUSED 2 /* profiling paused */
-EXTERN int do_profiling INIT(= PROF_NONE); /* PROF_ values */
+// Values for "do_profiling".
+#define PROF_NONE 0 ///< profiling not started
+#define PROF_YES 1 ///< profiling busy
+#define PROF_PAUSED 2 ///< profiling paused
+EXTERN int do_profiling INIT(= PROF_NONE); ///< PROF_ values
-/*
- * The exception currently being thrown. Used to pass an exception to
- * a different cstack. Also used for discarding an exception before it is
- * caught or made pending. Only valid when did_throw is TRUE.
- */
+/// Exception currently being thrown. Used to pass an exception to a different
+/// cstack. Also used for discarding an exception before it is caught or made
+/// pending.
EXTERN except_T *current_exception;
-/*
- * did_throw: An exception is being thrown. Reset when the exception is caught
- * or as long as it is pending in a finally clause.
- */
-EXTERN int did_throw INIT(= FALSE);
-
-/*
- * need_rethrow: set to TRUE when a throw that cannot be handled in do_cmdline()
- * must be propagated to the cstack of the previously called do_cmdline().
- */
-EXTERN int need_rethrow INIT(= FALSE);
+/// Set when a throw that cannot be handled in do_cmdline() must be propagated
+/// to the cstack of the previously called do_cmdline().
+EXTERN int need_rethrow INIT(= false);
-/*
- * check_cstack: set to TRUE when a ":finish" or ":return" that cannot be
- * handled in do_cmdline() must be propagated to the cstack of the previously
- * called do_cmdline().
- */
-EXTERN int check_cstack INIT(= FALSE);
+/// Set when a ":finish" or ":return" that cannot be handled in do_cmdline()
+/// must be propagated to the cstack of the previously called do_cmdline().
+EXTERN int check_cstack INIT(= false);
-/*
- * Number of nested try conditionals (across function calls and ":source"
- * commands).
- */
+/// Number of nested try conditionals (across function calls and ":source"
+/// commands).
EXTERN int trylevel INIT(= 0);
-/*
- * When "force_abort" is TRUE, always skip commands after an error message,
- * even after the outermost ":endif", ":endwhile" or ":endfor" or for a
- * function without the "abort" flag. It is set to TRUE when "trylevel" is
- * non-zero (and ":silent!" was not used) or an exception is being thrown at
- * the time an error is detected. It is set to FALSE when "trylevel" gets
- * zero again and there was no error or interrupt or throw.
- */
-EXTERN int force_abort INIT(= FALSE);
-
-/*
- * "msg_list" points to a variable in the stack of do_cmdline() which keeps
- * the list of arguments of several emsg() calls, one of which is to be
- * converted to an error exception immediately after the failing command
- * returns. The message to be used for the exception value is pointed to by
- * the "throw_msg" field of the first element in the list. It is usually the
- * same as the "msg" field of that element, but can be identical to the "msg"
- * field of a later list element, when the "emsg_severe" flag was set when the
- * emsg() call was made.
- */
+/// When "force_abort" is TRUE, always skip commands after an error message,
+/// even after the outermost ":endif", ":endwhile" or ":endfor" or for a
+/// function without the "abort" flag. It is set to TRUE when "trylevel" is
+/// non-zero (and ":silent!" was not used) or an exception is being thrown at
+/// the time an error is detected. It is set to FALSE when "trylevel" gets
+/// zero again and there was no error or interrupt or throw.
+EXTERN int force_abort INIT(= false);
+
+/// "msg_list" points to a variable in the stack of do_cmdline() which keeps
+/// the list of arguments of several emsg() calls, one of which is to be
+/// converted to an error exception immediately after the failing command
+/// returns. The message to be used for the exception value is pointed to by
+/// the "throw_msg" field of the first element in the list. It is usually the
+/// same as the "msg" field of that element, but can be identical to the "msg"
+/// field of a later list element, when the "emsg_severe" flag was set when the
+/// emsg() call was made.
EXTERN struct msglist **msg_list INIT(= NULL);
-/*
- * suppress_errthrow: When TRUE, don't convert an error to an exception. Used
- * when displaying the interrupt message or reporting an exception that is still
- * uncaught at the top level (which has already been discarded then). Also used
- * for the error message when no exception can be thrown.
- */
-EXTERN int suppress_errthrow INIT(= FALSE);
+/// When set, don't convert an error to an exception. Used when displaying the
+/// interrupt message or reporting an exception that is still uncaught at the
+/// top level (which has already been discarded then). Also used for the error
+/// message when no exception can be thrown.
+EXTERN int suppress_errthrow INIT(= false);
-/*
- * The stack of all caught and not finished exceptions. The exception on the
- * top of the stack is the one got by evaluation of v:exception. The complete
- * stack of all caught and pending exceptions is embedded in the various
- * cstacks; the pending exceptions, however, are not on the caught stack.
- */
+/// The stack of all caught and not finished exceptions. The exception on the
+/// top of the stack is the one got by evaluation of v:exception. The complete
+/// stack of all caught and pending exceptions is embedded in the various
+/// cstacks; the pending exceptions, however, are not on the caught stack.
EXTERN except_T *caught_stack INIT(= NULL);
-/*
- * Garbage collection can only take place when we are sure there are no Lists
- * or Dictionaries being used internally. This is flagged with
- * "may_garbage_collect" when we are at the toplevel.
- * "want_garbage_collect" is set by the garbagecollect() function, which means
- * we do garbage collection before waiting for a char at the toplevel.
- * "garbage_collect_at_exit" indicates garbagecollect(1) was called.
- */
-EXTERN int may_garbage_collect INIT(= FALSE);
-EXTERN int want_garbage_collect INIT(= FALSE);
-EXTERN int garbage_collect_at_exit INIT(= FALSE);
-
-/* Special values for current_SID. */
-#define SID_MODELINE -1 /* when using a modeline */
-#define SID_CMDARG -2 /* for "--cmd" argument */
-#define SID_CARG -3 /* for "-c" argument */
-#define SID_ENV -4 /* for sourcing environment variable */
-#define SID_ERROR -5 /* option was reset because of an error */
-#define SID_NONE -6 /* don't set scriptID */
-
-/* ID of script being sourced or was sourced to define the current function. */
+///
+/// Garbage collection can only take place when we are sure there are no Lists
+/// or Dictionaries being used internally. This is flagged with
+/// "may_garbage_collect" when we are at the toplevel.
+/// "want_garbage_collect" is set by the garbagecollect() function, which means
+/// we do garbage collection before waiting for a char at the toplevel.
+/// "garbage_collect_at_exit" indicates garbagecollect(1) was called.
+///
+EXTERN int may_garbage_collect INIT(= false);
+EXTERN int want_garbage_collect INIT(= false);
+EXTERN int garbage_collect_at_exit INIT(= false);
+
+// Special values for current_SID.
+#define SID_MODELINE -1 // when using a modeline
+#define SID_CMDARG -2 // for "--cmd" argument
+#define SID_CARG -3 // for "-c" argument
+#define SID_ENV -4 // for sourcing environment variable
+#define SID_ERROR -5 // option was reset because of an error
+#define SID_NONE -6 // don't set scriptID
+#define SID_LUA -7 // for Lua scripts/chunks
+#define SID_API_CLIENT -8 // for API clients
+
+// ID of script being sourced or was sourced to define the current function.
EXTERN scid_T current_SID INIT(= 0);
+// ID of the current channel making a client API call
+EXTERN uint64_t current_channel_id INIT(= 0);
+
+EXTERN bool did_source_packages INIT(= false);
+
// Scope information for the code that indirectly triggered the current
// provider function call
EXTERN struct caller_scope {
scid_T SID;
uint8_t *sourcing_name, *autocmd_fname, *autocmd_match;
linenr_T sourcing_lnum;
- int autocmd_fname_full, autocmd_bufnr;
+ int autocmd_bufnr;
void *funccalp;
} provider_caller_scope;
EXTERN int provider_call_nesting INIT(= 0);
-/* Magic number used for hashitem "hi_key" value indicating a deleted item.
- * Only the address is used. */
-EXTERN char_u hash_removed;
-
EXTERN int t_colors INIT(= 256); // int value of T_CCO
@@ -434,78 +374,6 @@ EXTERN int did_check_timestamps INIT(= FALSE); /* did check timestamps
recently */
EXTERN int no_check_timestamps INIT(= 0); /* Don't check timestamps */
-/*
- * Values for index in highlight_attr[].
- * When making changes, also update HL_FLAGS below! And update the default
- * value of 'highlight' in option.c.
- */
-typedef enum {
- HLF_8 = 0 /* Meta & special keys listed with ":map", text that is
- displayed different from what it is */
- , HLF_EOB //< after the last line in the buffer
- , HLF_TERM //< terminal cursor focused
- , HLF_TERMNC //< terminal cursor unfocused
- , HLF_AT /* @ characters at end of screen, characters that
- don't really exist in the text */
- , HLF_D /* directories in CTRL-D listing */
- , HLF_E /* error messages */
- , HLF_I /* incremental search */
- , HLF_L /* last search string */
- , HLF_M /* "--More--" message */
- , HLF_CM /* Mode (e.g., "-- INSERT --") */
- , HLF_N /* line number for ":number" and ":#" commands */
- , HLF_CLN /* current line number */
- , HLF_R /* return to continue message and yes/no questions */
- , HLF_S /* status lines */
- , HLF_SNC /* status lines of not-current windows */
- , HLF_C /* column to separate vertically split windows */
- , HLF_T /* Titles for output from ":set all", ":autocmd" etc. */
- , HLF_V /* Visual mode */
- , HLF_VNC /* Visual mode, autoselecting and not clipboard owner */
- , HLF_W /* warning messages */
- , HLF_WM /* Wildmenu highlight */
- , HLF_FL /* Folded line */
- , HLF_FC /* Fold column */
- , HLF_ADD /* Added diff line */
- , HLF_CHD /* Changed diff line */
- , HLF_DED /* Deleted diff line */
- , HLF_TXD /* Text Changed in diff line */
- , HLF_CONCEAL /* Concealed text */
- , HLF_SC /* Sign column */
- , HLF_SPB /* SpellBad */
- , HLF_SPC /* SpellCap */
- , HLF_SPR /* SpellRare */
- , HLF_SPL /* SpellLocal */
- , HLF_PNI /* popup menu normal item */
- , HLF_PSI /* popup menu selected item */
- , HLF_PSB /* popup menu scrollbar */
- , HLF_PST /* popup menu scrollbar thumb */
- , HLF_TP /* tabpage line */
- , HLF_TPS /* tabpage line selected */
- , HLF_TPF /* tabpage line filler */
- , HLF_CUC /* 'cursurcolumn' */
- , HLF_CUL /* 'cursurline' */
- , HLF_MC /* 'colorcolumn' */
- , HLF_COUNT /* MUST be the last one */
-} hlf_T;
-
-/* The HL_FLAGS must be in the same order as the HLF_ enums!
- * When changing this also adjust the default for 'highlight'. */
-#define HL_FLAGS {'8', '~', 'z', 'Z', '@', 'd', 'e', 'i', 'l', 'm', 'M', 'n', \
- 'N', 'r', 's', 'S', 'c', 't', 'v', 'V', 'w', 'W', 'f', 'F', \
- 'A', 'C', 'D', 'T', '-', '>', 'B', 'P', 'R', 'L', '+', '=', \
- 'x', 'X', '*', '#', '_', '!', '.', 'o'}
-
-EXTERN int highlight_attr[HLF_COUNT]; /* Highl. attr for each context. */
-EXTERN int highlight_user[9]; /* User[1-9] attributes */
-EXTERN int highlight_stlnc[9]; /* On top of user */
-EXTERN int cterm_normal_fg_color INIT(= 0);
-EXTERN int cterm_normal_fg_bold INIT(= 0);
-EXTERN int cterm_normal_bg_color INIT(= 0);
-EXTERN RgbValue normal_fg INIT(= -1);
-EXTERN RgbValue normal_bg INIT(= -1);
-EXTERN RgbValue normal_sp INIT(= -1);
-
EXTERN int autocmd_busy INIT(= FALSE); /* Is apply_autocmds() busy? */
EXTERN int autocmd_no_enter INIT(= FALSE); /* *Enter autocmds disabled */
EXTERN int autocmd_no_leave INIT(= FALSE); /* *Leave autocmds disabled */
@@ -515,9 +383,9 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when
starting to execute
autocommands */
-/* When deleting the current buffer, another one must be loaded. If we know
- * which one is preferred, au_new_curbuf is set to it */
-EXTERN buf_T *au_new_curbuf INIT(= NULL);
+// When deleting the current buffer, another one must be loaded.
+// If we know which one is preferred, au_new_curbuf is set to it.
+EXTERN bufref_T au_new_curbuf INIT(= { NULL, 0, 0 });
// When deleting a buffer/window and autocmd_busy is TRUE, do not free the
// buffer/window. but link it in the list starting with
@@ -561,6 +429,7 @@ EXTERN int updating_screen INIT(= FALSE);
EXTERN win_T *firstwin; /* first window */
EXTERN win_T *lastwin; /* last window */
EXTERN win_T *prevwin INIT(= NULL); /* previous window */
+# define ONE_WINDOW (firstwin == lastwin)
/*
* When using this macro "break" only breaks out of the inner loop. Use "goto"
* to break out of the tabpage loop.
@@ -569,6 +438,7 @@ EXTERN win_T *prevwin INIT(= NULL); /* previous window */
FOR_ALL_TABS(tp) \
FOR_ALL_WINDOWS_IN_TAB(wp, tp)
+// -V:FOR_ALL_WINDOWS_IN_TAB:501
# define FOR_ALL_WINDOWS_IN_TAB(wp, tp) \
for (win_T *wp = ((tp) == curtab) \
? firstwin : (tp)->tp_firstwin; wp != NULL; wp = wp->w_next)
@@ -599,16 +469,15 @@ EXTERN int redraw_tabline INIT(= FALSE); /* need to redraw tabline */
* All buffers are linked in a list. 'firstbuf' points to the first entry,
* 'lastbuf' to the last entry and 'curbuf' to the currently active buffer.
*/
-EXTERN buf_T *firstbuf INIT(= NULL); /* first buffer */
-EXTERN buf_T *lastbuf INIT(= NULL); /* last buffer */
-EXTERN buf_T *curbuf INIT(= NULL); /* currently active buffer */
+EXTERN buf_T *firstbuf INIT(= NULL); // first buffer
+EXTERN buf_T *lastbuf INIT(= NULL); // last buffer
+EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer
// Iterates over all buffers in the buffer list.
-# define FOR_ALL_BUFFERS(buf) for (buf_T *buf = firstbuf; buf != NULL; buf = buf->b_next)
-
-/* Flag that is set when switching off 'swapfile'. It means that all blocks
- * are to be loaded into memory. Shouldn't be global... */
-EXTERN int mf_dont_release INIT(= FALSE); /* don't release blocks */
+#define FOR_ALL_BUFFERS(buf) \
+ for (buf_T *buf = firstbuf; buf != NULL; buf = buf->b_next)
+#define FOR_ALL_BUFFERS_BACKWARDS(buf) \
+ for (buf_T *buf = lastbuf; buf != NULL; buf = buf->b_prev)
/*
* List of files being edited (global argument list). curwin->w_alist points
@@ -616,80 +485,70 @@ EXTERN int mf_dont_release INIT(= FALSE); /* don't release blocks */
*/
EXTERN alist_T global_alist; /* global argument list */
EXTERN int max_alist_id INIT(= 0); ///< the previous argument list id
-EXTERN int arg_had_last INIT(= FALSE); /* accessed last file in
- global_alist */
+EXTERN bool arg_had_last INIT(= false); // accessed last file in
+ // global_alist
EXTERN int ru_col; /* column for ruler */
EXTERN int ru_wid; /* 'rulerfmt' width of ruler when non-zero */
EXTERN int sc_col; /* column for shown command */
-/*
- * When starting or exiting some things are done differently (e.g. screen
- * updating).
- */
-EXTERN int starting INIT(= NO_SCREEN);
-/* first NO_SCREEN, then NO_BUFFERS and then
- * set to 0 when starting up finished */
-EXTERN int exiting INIT(= FALSE);
-/* TRUE when planning to exit Vim. Might
- * still keep on running if there is a changed
- * buffer. */
-/* volatile because it is used in signal handler deathtrap(). */
-EXTERN volatile int full_screen INIT(= FALSE);
-/* TRUE when doing full-screen output
- * otherwise only writing some messages */
-
-EXTERN int restricted INIT(= FALSE);
-// TRUE when started in restricted mode (-Z)
-EXTERN int secure INIT(= FALSE);
-/* non-zero when only "safe" commands are
- * allowed, e.g. when sourcing .exrc or .vimrc
- * in current directory */
+//
+// When starting or exiting some things are done differently (e.g. screen
+// updating).
+//
+// First NO_SCREEN, then NO_BUFFERS, then 0 when startup finished.
+EXTERN int starting INIT(= NO_SCREEN);
+// true when planning to exit. Might keep running if there is a changed buffer.
+EXTERN int exiting INIT(= false);
+// is stdin a terminal?
+EXTERN int stdin_isatty INIT(= true);
+// is stdout a terminal?
+EXTERN int stdout_isatty INIT(= true);
+// true when doing full-screen output, otherwise only writing some messages.
+// volatile because it is used in a signal handler.
+EXTERN volatile int full_screen INIT(= false);
+
+// When started in restricted mode (-Z).
+EXTERN int restricted INIT(= false);
+
+/// Non-zero when only "safe" commands are allowed, e.g. when sourcing .exrc or
+/// .vimrc in current directory.
+EXTERN int secure INIT(= false);
+
+/// Non-zero when changing text and jumping to another window/buffer is not
+/// allowed.
EXTERN int textlock INIT(= 0);
-/* non-zero when changing text and jumping to
- * another window or buffer is not allowed */
+/// Non-zero when the current buffer can't be changed. Used for FileChangedRO.
EXTERN int curbuf_lock INIT(= 0);
-/* non-zero when the current buffer can't be
- * changed. Used for FileChangedRO. */
+
+/// Non-zero when no buffer name can be changed, no buffer can be deleted and
+/// current directory can't be changed. Used for SwapExists et al.
EXTERN int allbuf_lock INIT(= 0);
-/* non-zero when no buffer name can be
- * changed, no buffer can be deleted and
- * current directory can't be changed.
- * Used for SwapExists et al. */
+
+/// Non-zero when evaluating an expression in a "sandbox". Several things are
+/// not allowed then.
EXTERN int sandbox INIT(= 0);
-/* Non-zero when evaluating an expression in a
- * "sandbox". Several things are not allowed
- * then. */
-
-EXTERN int silent_mode INIT(= FALSE);
-/* set to TRUE when "-s" commandline argument
- * used for ex */
-
-// Set to true when sourcing of startup scripts (init.vim) is done.
-// Used for options that cannot be changed after startup scripts.
-EXTERN bool did_source_startup_scripts INIT(= false);
-
-EXTERN pos_T VIsual; /* start position of active Visual selection */
-EXTERN int VIsual_active INIT(= FALSE);
-/* whether Visual mode is active */
-EXTERN int VIsual_select INIT(= FALSE);
-/* whether Select mode is active */
-EXTERN int VIsual_reselect;
-/* whether to restart the selection after a
- * Select mode mapping or menu */
-EXTERN int VIsual_mode INIT(= 'v');
-/* type of Visual mode */
+/// Batch-mode: "-es" or "-Es" commandline argument was given.
+EXTERN int silent_mode INIT(= false);
-EXTERN int redo_VIsual_busy INIT(= FALSE);
-/* TRUE when redoing Visual */
+/// Start position of active Visual selection.
+EXTERN pos_T VIsual;
+/// Whether Visual mode is active.
+EXTERN int VIsual_active INIT(= false);
+/// Whether Select mode is active.
+EXTERN int VIsual_select INIT(= false);
+/// Whether to restart the selection after a Select-mode mapping or menu.
+EXTERN int VIsual_reselect;
+/// Type of Visual mode.
+EXTERN int VIsual_mode INIT(= 'v');
+/// TRUE when redoing Visual.
+EXTERN int redo_VIsual_busy INIT(= false);
-/*
- * When pasting text with the middle mouse button in visual mode with
- * restart_edit set, remember where it started so we can set Insstart.
- */
+/// When pasting text with the middle mouse button in visual mode with
+/// restart_edit set, remember where it started so we can set Insstart.
EXTERN pos_T where_paste_started;
/*
@@ -698,7 +557,7 @@ EXTERN pos_T where_paste_started;
* reset when any other editing is done on the line. If an <ESC> or <RETURN>
* is received, and did_ai is TRUE, the line is truncated.
*/
-EXTERN int did_ai INIT(= FALSE);
+EXTERN bool did_ai INIT(= false);
/*
* Column of first char after autoindent. 0 when no autoindent done. Used
@@ -726,19 +585,19 @@ EXTERN int did_syncbind INIT(= FALSE);
* This flag is set when a smart indent has been performed. When the next typed
* character is a '{' the inserted tab will be deleted again.
*/
-EXTERN int did_si INIT(= FALSE);
+EXTERN bool did_si INIT(= false);
/*
* This flag is set after an auto indent. If the next typed character is a '}'
* one indent will be removed.
*/
-EXTERN int can_si INIT(= FALSE);
+EXTERN bool can_si INIT(= false);
/*
* This flag is set after an "O" command. If the next typed character is a '{'
* one indent will be removed.
*/
-EXTERN int can_si_back INIT(= FALSE);
+EXTERN bool can_si_back INIT(= false);
// w_cursor before formatting text.
EXTERN pos_T saved_cursor INIT(= INIT_POS_T(0, 0, 0));
@@ -777,45 +636,16 @@ EXTERN int vr_lines_changed INIT(= 0); /* #Lines changed by "gR" so far */
# define DBCS_2BYTE 1 /* 2byte- */
# define DBCS_DEBUG -1
-EXTERN int enc_dbcs INIT(= 0); /* One of DBCS_xxx values if
- DBCS encoding */
-EXTERN int enc_unicode INIT(= 0); /* 2: UCS-2 or UTF-16, 4: UCS-4 */
-EXTERN bool enc_utf8 INIT(= false); /* UTF-8 encoded Unicode */
-EXTERN int enc_latin1like INIT(= TRUE); /* 'encoding' is latin1 comp. */
-EXTERN int has_mbyte INIT(= 0); /* any multi-byte encoding */
+// mbyte flags that used to depend on 'encoding'. These are now deprecated, as
+// 'encoding' is always "utf-8". Code that use them can be refactored to
+// remove dead code.
+#define enc_dbcs 0
+#define enc_utf8 true
+#define has_mbyte true
/// Encoding used when 'fencs' is set to "default"
EXTERN char_u *fenc_default INIT(= NULL);
-/*
- * To speed up BYTELEN() we fill a table with the byte lengths whenever
- * enc_utf8 or enc_dbcs changes.
- */
-EXTERN char mb_bytelen_tab[256];
-
-/*
- * Function pointers, used to quickly get to the right function. Each has
- * three possible values: latin_ (8-bit), utfc_ or utf_ (utf-8) and dbcs_
- * (DBCS).
- * The value is set in mb_init();
- */
-/* length of char in bytes, including following composing chars */
-EXTERN int (*mb_ptr2len)(const char_u *p) INIT(= latin_ptr2len);
-/* idem, with limit on string length */
-EXTERN int (*mb_ptr2len_len)(const char_u *p, int size) INIT(= latin_ptr2len_len);
-/* byte length of char */
-EXTERN int (*mb_char2len)(int c) INIT(= latin_char2len);
-/* convert char to bytes, return the length */
-EXTERN int (*mb_char2bytes)(int c, char_u *buf) INIT(= latin_char2bytes);
-EXTERN int (*mb_ptr2cells)(const char_u *p) INIT(= latin_ptr2cells);
-EXTERN int (*mb_ptr2cells_len)(const char_u *p, int size) INIT(
- = latin_ptr2cells_len);
-EXTERN int (*mb_char2cells)(int c) INIT(= latin_char2cells);
-EXTERN int (*mb_off2cells)(unsigned off, unsigned max_off) INIT(
- = latin_off2cells);
-EXTERN int (*mb_ptr2char)(const char_u *p) INIT(= latin_ptr2char);
-EXTERN int (*mb_head_off)(const char_u *base, const char_u *p) INIT(= latin_head_off);
-
# if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
/* Pointers to functions and variables to be loaded at runtime */
EXTERN size_t (*iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft,
@@ -826,35 +656,31 @@ EXTERN int (*iconvctl)(iconv_t cd, int request, void *argument);
EXTERN int* (*iconv_errno)(void);
# endif
-/*
- * "State" is the main state of Vim.
- * There are other variables that modify the state:
- * "Visual_mode" When State is NORMAL or INSERT.
- * "finish_op" When State is NORMAL, after typing the operator and before
- * typing the motion command.
- */
-EXTERN int State INIT(= NORMAL); /* This is the current state of the
- * command interpreter. */
+/// "State" is the main state of Vim.
+/// There are other variables that modify the state:
+/// Visual_mode: When State is NORMAL or INSERT.
+/// finish_op : When State is NORMAL, after typing the operator and
+/// before typing the motion command.
+/// motion_force: Last motion_force from do_pending_operator()
+EXTERN int State INIT(= NORMAL); // This is the current state of the
+ // command interpreter.
EXTERN bool finish_op INIT(= false); // true while an operator is pending
EXTERN long opcount INIT(= 0); // count for pending operator
+EXTERN int motion_force INIT(=0); // motion force for pending operator
-/*
- * ex mode (Q) state
- */
-EXTERN int exmode_active INIT(= 0); /* zero, EXMODE_NORMAL or EXMODE_VIM */
-EXTERN int ex_no_reprint INIT(= FALSE); /* no need to print after z or p */
+// Ex Mode (Q) state
+EXTERN int exmode_active INIT(= 0); // Zero, EXMODE_NORMAL or EXMODE_VIM.
+EXTERN int ex_no_reprint INIT(=false); // No need to print after z or p.
-EXTERN int Recording INIT(= FALSE); /* TRUE when recording into a reg. */
-EXTERN int Exec_reg INIT(= FALSE); /* TRUE when executing a register */
+EXTERN int Recording INIT(= false); // TRUE when recording into a reg.
+EXTERN int Exec_reg INIT(= false); // TRUE when executing a register.
-EXTERN int no_mapping INIT(= FALSE); /* currently no mapping allowed */
-EXTERN int no_zero_mapping INIT(= 0); /* mapping zero not allowed */
-EXTERN int allow_keys INIT(= FALSE); /* allow key codes when no_mapping
- * is set */
-EXTERN int no_u_sync INIT(= 0); /* Don't call u_sync() */
-EXTERN int u_sync_once INIT(= 0); /* Call u_sync() once when evaluating
- an expression. */
+EXTERN int no_mapping INIT(= false); // currently no mapping allowed
+EXTERN int no_zero_mapping INIT(= 0); // mapping zero not allowed
+EXTERN int no_u_sync INIT(= 0); // Don't call u_sync()
+EXTERN int u_sync_once INIT(= 0); // Call u_sync() once when evaluating
+ // an expression.
EXTERN bool force_restart_edit INIT(= false); // force restart_edit after
// ex_normal returns
@@ -877,9 +703,10 @@ EXTERN int mapped_ctrl_c INIT(= 0); // Modes where CTRL-C is mapped.
EXTERN cmdmod_T cmdmod; /* Ex command modifiers */
-EXTERN int msg_silent INIT(= 0); /* don't print messages */
-EXTERN int emsg_silent INIT(= 0); /* don't print error messages */
-EXTERN int cmd_silent INIT(= FALSE); /* don't echo the command line */
+EXTERN int msg_silent INIT(= 0); // don't print messages
+EXTERN int emsg_silent INIT(= 0); // don't print error messages
+EXTERN bool emsg_noredir INIT(= false); // don't redirect error messages
+EXTERN bool cmd_silent INIT(= false); // don't echo the command line
/* Values for swap_exists_action: what to do when swap file already exists */
#define SEA_NONE 0 /* don't use dialog */
@@ -893,9 +720,16 @@ EXTERN int swap_exists_action INIT(= SEA_NONE);
EXTERN int swap_exists_did_quit INIT(= FALSE);
/* Selected "quit" at the dialog. */
-EXTERN char_u IObuff[IOSIZE]; /* sprintf's are done in this buffer */
-EXTERN char_u NameBuff[MAXPATHL]; /* buffer for expanding file names */
-EXTERN char_u msg_buf[MSG_BUF_LEN]; /* small buffer for messages */
+EXTERN char_u IObuff[IOSIZE]; ///< Buffer for sprintf, I/O, etc.
+EXTERN char_u NameBuff[MAXPATHL]; ///< Buffer for expanding file names
+EXTERN char_u msg_buf[MSG_BUF_LEN]; ///< Small buffer for messages
+EXTERN char os_buf[ ///< Buffer for the os/ layer
+#if MAXPATHL > IOSIZE
+MAXPATHL
+#else
+IOSIZE
+#endif
+];
/* When non-zero, postpone redrawing. */
EXTERN int RedrawingDisabled INIT(= 0);
@@ -910,13 +744,10 @@ EXTERN int ex_normal_busy INIT(= 0); // recursiveness of ex_normal()
EXTERN int ex_normal_lock INIT(= 0); // forbid use of ex_normal()
EXTERN int ignore_script INIT(= false); // ignore script input
EXTERN int stop_insert_mode; // for ":stopinsert" and 'insertmode'
-EXTERN int KeyTyped; // TRUE if user typed current char
+EXTERN bool KeyTyped; // true if user typed current char
EXTERN int KeyStuffed; // TRUE if current char from stuffbuf
EXTERN int maptick INIT(= 0); // tick for each non-mapped char
-EXTERN uint8_t chartab[256]; // table used in charset.c; See
- // init_chartab() for explanation
-
EXTERN int must_redraw INIT(= 0); /* type of redraw necessary */
EXTERN int skip_redraw INIT(= FALSE); /* skip redraw once */
EXTERN int do_redraw INIT(= FALSE); /* extra redraw once */
@@ -924,14 +755,11 @@ EXTERN int do_redraw INIT(= FALSE); /* extra redraw once */
EXTERN int need_highlight_changed INIT(= true);
EXTERN char *used_shada_file INIT(= NULL); // name of the ShaDa file to use
-#define NSCRIPT 15
-EXTERN FILE *scriptin[NSCRIPT]; /* streams to read script from */
-EXTERN int curscript INIT(= 0); /* index in scriptin[] */
-EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */
+EXTERN FILE *scriptout INIT(= NULL); ///< Stream to write script to.
-/* volatile because it is used in signal handler catch_sigint(). */
-EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt
- signal occurred */
+// volatile because it is used in a signal handler.
+EXTERN volatile int got_int INIT(= false); // set to true when interrupt
+ // signal occurred
EXTERN int bangredo INIT(= FALSE); /* set to TRUE with ! command */
EXTERN int searchcmdlen; /* length of previous search cmd */
EXTERN int reg_do_extmatch INIT(= 0); /* Used when compiling regexp:
@@ -956,16 +784,12 @@ EXTERN char_u *last_cmdline INIT(= NULL); // last command line (for ":)
EXTERN char_u *repeat_cmdline INIT(= NULL); // command line for "."
EXTERN char_u *new_last_cmdline INIT(= NULL); // new value for last_cmdline
EXTERN char_u *autocmd_fname INIT(= NULL); // fname for <afile> on cmdline
-EXTERN int autocmd_fname_full; // autocmd_fname is full path
EXTERN int autocmd_bufnr INIT(= 0); // fnum for <abuf> on cmdline
EXTERN char_u *autocmd_match INIT(= NULL); // name for <amatch> on cmdline
EXTERN int did_cursorhold INIT(= false); // set when CursorHold t'gerd
// for CursorMoved event
EXTERN pos_T last_cursormoved INIT(= INIT_POS_T(0, 0, 0));
-EXTERN int last_changedtick INIT(= 0); // for TextChanged event
-EXTERN buf_T *last_changedtick_buf INIT(= NULL);
-
EXTERN int postponed_split INIT(= 0); /* for CTRL-W CTRL-] command */
EXTERN int postponed_split_flags INIT(= 0); /* args for win_split() */
EXTERN int postponed_split_tab INIT(= 0); /* cmdmod.tab */
@@ -989,18 +813,19 @@ EXTERN int redir_off INIT(= false); // no redirection for a moment
EXTERN FILE *redir_fd INIT(= NULL); // message redirection file
EXTERN int redir_reg INIT(= 0); // message redirection register
EXTERN int redir_vname INIT(= 0); // message redirection variable
-EXTERN garray_T *capture_ga INIT(= NULL); // capture() buffer
+EXTERN garray_T *capture_ga INIT(= NULL); // captured output for execute()
EXTERN char_u langmap_mapchar[256]; /* mapping for language keys */
EXTERN int save_p_ls INIT(= -1); /* Save 'laststatus' setting */
EXTERN int save_p_wmh INIT(= -1); /* Save 'winminheight' setting */
EXTERN int wild_menu_showing INIT(= 0);
-# define WM_SHOWN 1 /* wildmenu showing */
-# define WM_SCROLLED 2 /* wildmenu showing with scroll */
-
+enum {
+ WM_SHOWN = 1, ///< wildmenu showing
+ WM_SCROLLED = 2, ///< wildmenu showing with scroll
+ WM_LIST = 3, ///< cmdline CTRL-D
+};
-EXTERN char breakat_flags[256]; /* which characters are in 'breakat' */
/*
* Some file names are stored in pathdef.c, which is generated from the
@@ -1018,7 +843,7 @@ extern char_u *compiled_sys;
* directory is not a local directory, globaldir is NULL. */
EXTERN char_u *globaldir INIT(= NULL);
-/* Characters from 'listchars' option */
+// 'listchars' characters. Defaults are overridden in set_chars_option().
EXTERN int lcs_eol INIT(= '$');
EXTERN int lcs_ext INIT(= NUL);
EXTERN int lcs_prec INIT(= NUL);
@@ -1029,20 +854,23 @@ EXTERN int lcs_tab2 INIT(= NUL);
EXTERN int lcs_trail INIT(= NUL);
EXTERN int lcs_conceal INIT(= ' ');
-/* Characters from 'fillchars' option */
+// 'fillchars' characters. Defaults are overridden in set_chars_option().
EXTERN int fill_stl INIT(= ' ');
EXTERN int fill_stlnc INIT(= ' ');
-EXTERN int fill_vert INIT(= ' ');
-EXTERN int fill_fold INIT(= '-');
+EXTERN int fill_vert INIT(= 9474); // │
+EXTERN int fill_fold INIT(= 183); // ·
EXTERN int fill_diff INIT(= '-');
+EXTERN int fill_msgsep INIT(= ' ');
+EXTERN int fill_eob INIT(= '~');
/* Whether 'keymodel' contains "stopsel" and "startsel". */
EXTERN int km_stopsel INIT(= FALSE);
EXTERN int km_startsel INIT(= FALSE);
-EXTERN int cedit_key INIT(= -1); /* key value of 'cedit' option */
-EXTERN int cmdwin_type INIT(= 0); /* type of cmdline window or 0 */
-EXTERN int cmdwin_result INIT(= 0); /* result of cmdline window or 0 */
+EXTERN int cedit_key INIT(= -1); ///< key value of 'cedit' option
+EXTERN int cmdwin_type INIT(= 0); ///< type of cmdline window or 0
+EXTERN int cmdwin_result INIT(= 0); ///< result of cmdline window or 0
+EXTERN int cmdwin_level INIT(= 0); ///< cmdline recursion level
EXTERN char_u no_lines_msg[] INIT(= N_("--No lines in buffer--"));
@@ -1069,8 +897,8 @@ EXTERN int no_hlsearch INIT(= FALSE);
EXTERN linenr_T printer_page_num;
-EXTERN int typebuf_was_filled INIT(= FALSE); /* received text from client
- or from feedkeys() */
+EXTERN bool typebuf_was_filled INIT(= false); // received text from client
+ // or from feedkeys()
#ifdef BACKSLASH_IN_FILENAME
@@ -1079,9 +907,9 @@ EXTERN char psepcN INIT(= '/'); // abnormal path separator character
EXTERN char pseps[2] INIT(= { '\\', 0 }); // normal path separator string
#endif
-/* Set to TRUE when an operator is being executed with virtual editing, MAYBE
- * when no operator is being executed, FALSE otherwise. */
-EXTERN int virtual_op INIT(= MAYBE);
+// Set to kTrue when an operator is being executed with virtual editing
+// kNone when no operator is being executed, kFalse otherwise.
+EXTERN TriState virtual_op INIT(= kNone);
/* Display tick, incremented for each call to update_screen() */
EXTERN disptick_T display_tick INIT(= 0);
@@ -1090,10 +918,6 @@ EXTERN disptick_T display_tick INIT(= 0);
* cursor position in Insert mode. */
EXTERN linenr_T spell_redraw_lnum INIT(= 0);
-/* Set when the cursor line needs to be redrawn. */
-EXTERN int need_cursor_line_redraw INIT(= FALSE);
-
-
#ifdef USE_MCH_ERRMSG
// Grow array to collect error messages in until they can be displayed.
EXTERN garray_T error_ga INIT(= GA_EMPTY_INIT_VALUE);
@@ -1123,6 +947,7 @@ EXTERN char_u e_for[] INIT(= N_("E588: :endfor without :for"));
EXTERN char_u e_exists[] INIT(= N_("E13: File exists (add ! to override)"));
EXTERN char_u e_failed[] INIT(= N_("E472: Command failed"));
EXTERN char_u e_internal[] INIT(= N_("E473: Internal error"));
+EXTERN char_u e_intern2[] INIT(= N_("E685: Internal error: %s"));
EXTERN char_u e_interr[] INIT(= N_("Interrupted"));
EXTERN char_u e_invaddr[] INIT(= N_("E14: Invalid address"));
EXTERN char_u e_invarg[] INIT(= N_("E474: Invalid argument"));
@@ -1131,12 +956,20 @@ EXTERN char_u e_invexpr2[] INIT(= N_("E15: Invalid expression: %s"));
EXTERN char_u e_invrange[] INIT(= N_("E16: Invalid range"));
EXTERN char_u e_invcmd[] INIT(= N_("E476: Invalid command"));
EXTERN char_u e_isadir2[] INIT(= N_("E17: \"%s\" is a directory"));
-EXTERN char_u e_invjob[] INIT(= N_("E900: Invalid job id"));
+EXTERN char_u e_invchan[] INIT(= N_("E900: Invalid channel id"));
+EXTERN char_u e_invchanjob[] INIT(= N_("E900: Invalid channel id: not a job"));
EXTERN char_u e_jobtblfull[] INIT(= N_("E901: Job table is full"));
-EXTERN char_u e_jobexe[] INIT(= N_("E902: \"%s\" is not an executable"));
EXTERN char_u e_jobspawn[] INIT(= N_(
- "E903: Process for command \"%s\" could not be spawned"));
-EXTERN char_u e_jobnotpty[] INIT(= N_("E904: Job is not connected to a pty"));
+ "E903: Process failed to start: %s: \"%s\""));
+EXTERN char_u e_channotpty[] INIT(= N_("E904: channel is not a pty"));
+EXTERN char_u e_stdiochan2[] INIT(= N_(
+ "E905: Couldn't open stdio channel: %s"));
+EXTERN char_u e_invstream[] INIT(= N_("E906: invalid stream for channel"));
+EXTERN char_u e_invstreamrpc[] INIT(= N_(
+ "E906: invalid stream for rpc channel, use 'rpc'"));
+EXTERN char_u e_streamkey[] INIT(= N_(
+ "E5210: dict key '%s' already set for buffered stream in channel %"
+ PRIu64));
EXTERN char_u e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\""));
EXTERN char_u e_mkdir[] INIT(= N_("E739: Cannot create directory %s: %s"));
EXTERN char_u e_markinval[] INIT(= N_("E19: Mark has invalid line number"));
@@ -1147,7 +980,6 @@ EXTERN char_u e_nesting[] INIT(= N_("E22: Scripts nested too deep"));
EXTERN char_u e_noalt[] INIT(= N_("E23: No alternate file"));
EXTERN char_u e_noabbr[] INIT(= N_("E24: No such abbreviation"));
EXTERN char_u e_nobang[] INIT(= N_("E477: No ! allowed"));
-EXTERN char_u e_nogvim[] INIT(= N_("E25: Nvim does not have a built-in GUI"));
EXTERN char_u e_nogroup[] INIT(= N_("E28: No such highlight group name: %s"));
EXTERN char_u e_noinstext[] INIT(= N_("E29: No inserted text yet"));
EXTERN char_u e_nolastcmd[] INIT(= N_("E30: No previous command line"));
@@ -1161,9 +993,9 @@ EXTERN char_u e_noprev[] INIT(= N_("E34: No previous command"));
EXTERN char_u e_noprevre[] INIT(= N_("E35: No previous regular expression"));
EXTERN char_u e_norange[] INIT(= N_("E481: No range allowed"));
EXTERN char_u e_noroom[] INIT(= N_("E36: Not enough room"));
-EXTERN char_u e_notcreate[] INIT(= N_("E482: Can't create file %s"));
EXTERN char_u e_notmp[] INIT(= N_("E483: Can't get temp file name"));
EXTERN char_u e_notopen[] INIT(= N_("E484: Can't open file %s"));
+EXTERN char_u e_notopen_2[] INIT(= N_("E484: Can't open file %s: %s"));
EXTERN char_u e_notread[] INIT(= N_("E485: Can't read file %s"));
EXTERN char_u e_nowrtmsg[] INIT(= N_(
"E37: No write since last change (add ! to override)"));
@@ -1183,11 +1015,7 @@ EXTERN char_u e_loclist[] INIT(= N_("E776: No location list"));
EXTERN char_u e_re_damg[] INIT(= N_("E43: Damaged match string"));
EXTERN char_u e_re_corr[] INIT(= N_("E44: Corrupted regexp program"));
EXTERN char_u e_readonly[] INIT(= N_(
- "E45: 'readonly' option is set (add ! to override)"));
-EXTERN char_u e_readonlyvar[] INIT(= N_(
- "E46: Cannot change read-only variable \"%s\""));
-EXTERN char_u e_readonlysbx[] INIT(= N_(
- "E794: Cannot set variable in the sandbox: \"%s\""));
+ "E45: 'readonly' option is set (add ! to override)"));
EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile"));
EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here"));
@@ -1203,6 +1031,7 @@ EXTERN char_u e_longname[] INIT(= N_("E75: Name too long"));
EXTERN char_u e_toomsbra[] INIT(= N_("E76: Too many ["));
EXTERN char_u e_toomany[] INIT(= N_("E77: Too many file names"));
EXTERN char_u e_trailing[] INIT(= N_("E488: Trailing characters"));
+EXTERN char_u e_trailing2[] INIT(= N_("E488: Trailing characters: %s"));
EXTERN char_u e_umark[] INIT(= N_("E78: Unknown mark"));
EXTERN char_u e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards"));
EXTERN char_u e_winheight[] INIT(= N_(
@@ -1210,9 +1039,9 @@ EXTERN char_u e_winheight[] INIT(= N_(
EXTERN char_u e_winwidth[] INIT(= N_(
"E592: 'winwidth' cannot be smaller than 'winminwidth'"));
EXTERN char_u e_write[] INIT(= N_("E80: Error while writing"));
-EXTERN char_u e_zerocount[] INIT(= N_("Zero count"));
-EXTERN char_u e_usingsid[] INIT(= N_("E81: Using <SID> not in a script context"));
-EXTERN char_u e_intern2[] INIT(= N_("E685: Internal error: %s"));
+EXTERN char_u e_zerocount[] INIT(= N_("E939: Positive count required"));
+EXTERN char_u e_usingsid[] INIT(= N_(
+ "E81: Using <SID> not in a script context"));
EXTERN char_u e_maxmempat[] INIT(= N_(
"E363: pattern uses more memory than 'maxmempattern'"));
EXTERN char_u e_emptybuf[] INIT(= N_("E749: empty buffer"));
@@ -1225,7 +1054,19 @@ EXTERN char_u e_notset[] INIT(= N_("E764: Option '%s' is not set"));
EXTERN char_u e_invalidreg[] INIT(= N_("E850: Invalid register name"));
EXTERN char_u e_dirnotf[] INIT(= N_(
"E919: Directory not found in '%s': \"%s\""));
+EXTERN char_u e_au_recursive[] INIT(= N_(
+ "E952: Autocommand caused recursive behavior"));
EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported"));
+EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long"));
+EXTERN char_u e_float_as_string[] INIT(= N_("E806: using Float as a String"));
+EXTERN char_u e_autocmd_err[] INIT(=N_(
+ "E5500: autocmd has thrown an exception: %s"));
+EXTERN char_u e_cmdmap_err[] INIT(=N_(
+ "E5520: <Cmd> mapping must end with <CR>"));
+EXTERN char_u e_cmdmap_repeated[] INIT(=N_(
+ "E5521: <Cmd> mapping must end with <CR> before second <Cmd>"));
+EXTERN char_u e_cmdmap_key[] INIT(=N_(
+ "E5522: <Cmd> mapping must not include %s key"));
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
@@ -1241,11 +1082,12 @@ EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
* can't do anything useful with the value. Assign to this variable to avoid
* the warning.
*/
-EXTERN int ignored;
-EXTERN char *ignoredp;
+EXTERN int vim_ignored;
-// If a msgpack-rpc channel should be started over stdin/stdout
+// Start a msgpack-rpc channel over stdin/stdout.
EXTERN bool embedded_mode INIT(= false);
+// Do not start a UI nor read/write to stdio (unless embedding).
+EXTERN bool headless_mode INIT(= false);
/// Used to track the status of external functions.
/// Currently only used for iconv().
@@ -1255,4 +1097,20 @@ typedef enum {
kBroken
} WorkingStatus;
+/// The scope of a working-directory command like `:cd`.
+///
+/// Scopes are enumerated from lowest to highest. When adding a scope make sure
+/// to update all functions using scopes as well, such as the implementation of
+/// `getcwd()`. When using scopes as limits (e.g. in loops) don't use the scopes
+/// directly, use `MIN_CD_SCOPE` and `MAX_CD_SCOPE` instead.
+typedef enum {
+ kCdScopeInvalid = -1,
+ kCdScopeWindow, ///< Affects one window.
+ kCdScopeTab, ///< Affects one tab page.
+ kCdScopeGlobal, ///< Affects the entire Nvim instance.
+} CdScope;
+
+#define MIN_CD_SCOPE kCdScopeWindow
+#define MAX_CD_SCOPE kCdScopeGlobal
+
#endif /* NVIM_GLOBALS_H */
diff --git a/src/nvim/grid_defs.h b/src/nvim/grid_defs.h
new file mode 100644
index 0000000000..37d85ead0c
--- /dev/null
+++ b/src/nvim/grid_defs.h
@@ -0,0 +1,59 @@
+#ifndef NVIM_GRID_DEFS_H
+#define NVIM_GRID_DEFS_H
+
+#include <stdint.h>
+
+#include "nvim/types.h"
+
+#define MAX_MCO 6 // maximum value for 'maxcombine'
+
+// The characters and attributes drawn on grids.
+typedef char_u schar_T[(MAX_MCO+1) * 4 + 1];
+typedef int16_t sattr_T;
+
+/// ScreenGrid represents a resizable rectuangular grid displayed by UI clients.
+///
+/// chars[] contains the UTF-8 text that is currently displayed on the grid.
+/// It is stored as a single block of cells. When redrawing a part of the grid,
+/// the new state can be compared with the existing state of the grid. This way
+/// we can avoid sending bigger updates than neccessary to the Ul layer.
+///
+/// Screen cells are stored as NUL-terminated UTF-8 strings, and a cell can
+/// contain up to MAX_MCO composing characters after the base character.
+/// The composing characters are to be drawn on top of the original character.
+/// The content after the NUL is not defined (so comparison must be done a
+/// single cell at a time). Double-width characters are stored in the left cell,
+/// and the right cell should only contain the empty string. When a part of the
+/// screen is cleared, the cells should be filled with a single whitespace char.
+///
+/// attrs[] contains the highlighting attribute for each cell.
+/// line_offset[n] is the offset from chars[] and attrs[] for the
+/// start of line 'n'. These offsets are in general not linear, as full screen
+/// scrolling is implemented by rotating the offsets in the line_offset array.
+/// line_wraps[] is an array of boolean flags indicating if the screen line
+/// wraps to the next line. It can only be true if a window occupies the entire
+/// screen width.
+typedef struct {
+ handle_T handle;
+
+ schar_T *chars;
+ sattr_T *attrs;
+ unsigned *line_offset;
+ char_u *line_wraps;
+
+ // the size of the allocated grid.
+ int Rows;
+ int Columns;
+
+ // offsets for the grid relative to the global screen
+ int row_offset;
+ int col_offset;
+
+ // grid size requested by the UI. Used for window grids only.
+ int requested_rows;
+ int requested_cols;
+
+ int was_resized;
+} ScreenGrid;
+
+#endif // NVIM_GRID_DEFS_H
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index 1c9b8e18ef..983dbb7bbe 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.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
+
/*
* hardcopy.c: printing to paper
*/
@@ -23,7 +26,6 @@
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/option.h"
#include "nvim/path.h"
@@ -132,9 +134,9 @@ static int current_syn_id;
#define PRCOLOR_BLACK 0
#define PRCOLOR_WHITE 0xffffff
-static int curr_italic;
-static int curr_bold;
-static int curr_underline;
+static TriState curr_italic;
+static TriState curr_bold;
+static TriState curr_underline;
static uint32_t curr_bg;
static uint32_t curr_fg;
static int page_count;
@@ -270,17 +272,25 @@ char_u *parse_printmbfont(void)
* Returns an error message for an illegal option, NULL otherwise.
* Only used for the printer at the moment...
*/
-static char_u *parse_list_options(char_u *option_str, option_table_T *table, int table_size)
+static char_u *parse_list_options(char_u *option_str, option_table_T *table,
+ size_t table_size)
{
+ option_table_T *old_opts;
+ char_u *ret = NULL;
char_u *stringp;
char_u *colonp;
char_u *commap;
char_u *p;
- int idx = 0; /* init for GCC */
+ size_t idx = 0; // init for GCC
int len;
- for (idx = 0; idx < table_size; ++idx)
- table[idx].present = FALSE;
+ // Save the old values, so that they can be restored in case of an error.
+ old_opts = (option_table_T *)xmalloc(sizeof(option_table_T) * table_size);
+
+ for (idx = 0; idx < table_size; idx++) {
+ old_opts[idx] = table[idx];
+ table[idx].present = false;
+ }
/*
* Repeat for all comma separated parts.
@@ -288,8 +298,10 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table, int
stringp = option_str;
while (*stringp) {
colonp = vim_strchr(stringp, ':');
- if (colonp == NULL)
- return (char_u *)N_("E550: Missing colon");
+ if (colonp == NULL) {
+ ret = (char_u *)N_("E550: Missing colon");
+ break;
+ }
commap = vim_strchr(stringp, ',');
if (commap == NULL)
commap = option_str + STRLEN(option_str);
@@ -300,15 +312,19 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table, int
if (STRNICMP(stringp, table[idx].name, len) == 0)
break;
- if (idx == table_size)
- return (char_u *)N_("E551: Illegal component");
+ if (idx == table_size) {
+ ret = (char_u *)N_("E551: Illegal component");
+ break;
+ }
p = colonp + 1;
table[idx].present = TRUE;
if (table[idx].hasnum) {
- if (!ascii_isdigit(*p))
- return (char_u *)N_("E552: digit expected");
+ if (!ascii_isdigit(*p)) {
+ ret = (char_u *)N_("E552: digit expected");
+ break;
+ }
table[idx].number = getdigits_int(&p);
}
@@ -321,7 +337,15 @@ static char_u *parse_list_options(char_u *option_str, option_table_T *table, int
++stringp;
}
- return NULL;
+ if (ret != NULL) {
+ // Restore old options in case of error
+ for (idx = 0; idx < table_size; idx++) {
+ table[idx] = old_opts[idx];
+ }
+ }
+
+ xfree(old_opts);
+ return ret;
}
@@ -348,7 +372,6 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
{
int colorindex;
uint32_t fg_color;
- char *color;
pattr->bold = (highlight_has_attr(hl_id, HL_BOLD, modec) != NULL);
pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL);
@@ -356,11 +379,12 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL);
{
- color = (char *)highlight_color(hl_id, (char_u *)"fg", modec);
- if (color == NULL)
+ const char *color = highlight_color(hl_id, "fg", modec);
+ if (color == NULL) {
colorindex = 0;
- else
+ } else {
colorindex = atoi(color);
+ }
if (colorindex >= 0 && colorindex < t_colors)
fg_color = prt_get_term_color(colorindex);
@@ -393,7 +417,8 @@ static void prt_set_bg(uint32_t bg)
}
}
-static void prt_set_font(int bold, int italic, int underline)
+static void prt_set_font(const TriState bold, const TriState italic,
+ const TriState underline)
{
if (curr_bold != bold
|| curr_italic != italic
@@ -405,34 +430,32 @@ static void prt_set_font(int bold, int italic, int underline)
}
}
-/*
- * Print the line number in the left margin.
- */
-static void prt_line_number(prt_settings_T *psettings, int page_line, linenr_T lnum)
+// Print the line number in the left margin.
+static void prt_line_number(prt_settings_T *const psettings,
+ const int page_line, const linenr_T lnum)
{
- int i;
- char_u tbuf[20];
-
prt_set_fg(psettings->number.fg_color);
prt_set_bg(psettings->number.bg_color);
prt_set_font(psettings->number.bold, psettings->number.italic,
- psettings->number.underline);
- mch_print_start_line(TRUE, page_line);
+ psettings->number.underline);
+ mch_print_start_line(true, page_line);
- /* Leave two spaces between the number and the text; depends on
- * PRINT_NUMBER_WIDTH. */
- sprintf((char *)tbuf, "%6ld", (long)lnum);
- for (i = 0; i < 6; i++)
+ // Leave two spaces between the number and the text; depends on
+ // PRINT_NUMBER_WIDTH.
+ char_u tbuf[20];
+ snprintf((char *)tbuf, sizeof(tbuf), "%6ld", (long)lnum);
+ for (int i = 0; i < 6; i++) {
(void)mch_print_text_out(&tbuf[i], 1);
+ }
- if (psettings->do_syntax)
- /* Set colors for next character. */
+ if (psettings->do_syntax) {
+ // Set colors for next character.
current_syn_id = -1;
- else {
- /* Set colors and font back to normal. */
+ } else {
+ // Set colors and font back to normal.
prt_set_fg(PRCOLOR_BLACK);
prt_set_bg(PRCOLOR_WHITE);
- prt_set_font(FALSE, FALSE, FALSE);
+ prt_set_font(kFalse, kFalse, kFalse);
}
}
@@ -475,22 +498,20 @@ int prt_get_unit(int idx)
return u;
}
-/*
- * Print the page header.
- */
-static void prt_header(prt_settings_T *psettings, int pagenum, linenr_T lnum)
+// Print the page header.
+static void prt_header(prt_settings_T *const psettings, const int pagenum,
+ const linenr_T lnum)
{
int width = psettings->chars_per_line;
- int page_line;
- char_u *tbuf;
- char_u *p;
- /* Also use the space for the line number. */
- if (prt_use_number())
+ // Also use the space for the line number.
+ if (prt_use_number()) {
width += PRINT_NUMBER_WIDTH;
+ }
assert(width >= 0);
- tbuf = xmalloc((size_t)width + IOSIZE);
+ const size_t tbuf_size = (size_t)width + IOSIZE;
+ char_u *tbuf = xmalloc(tbuf_size);
if (*p_header != NUL) {
linenr_T tmp_lnum, tmp_topline, tmp_botline;
@@ -519,38 +540,40 @@ static void prt_header(prt_settings_T *psettings, int pagenum, linenr_T lnum)
curwin->w_cursor.lnum = tmp_lnum;
curwin->w_topline = tmp_topline;
curwin->w_botline = tmp_botline;
- } else
- sprintf((char *)tbuf, _("Page %d"), pagenum);
+ } else {
+ snprintf((char *)tbuf, tbuf_size, _("Page %d"), pagenum);
+ }
prt_set_fg(PRCOLOR_BLACK);
prt_set_bg(PRCOLOR_WHITE);
- prt_set_font(TRUE, FALSE, FALSE);
+ prt_set_font(kTrue, kFalse, kFalse);
- /* Use a negative line number to indicate printing in the top margin. */
- page_line = 0 - prt_header_height();
- mch_print_start_line(TRUE, page_line);
- for (p = tbuf; *p != NUL; ) {
- int l = (*mb_ptr2len)(p);
+ // Use a negative line number to indicate printing in the top margin.
+ int page_line = 0 - prt_header_height();
+ mch_print_start_line(true, page_line);
+ for (char_u *p = tbuf; *p != NUL; ) {
+ const int l = (*mb_ptr2len)(p);
assert(l >= 0);
if (mch_print_text_out(p, (size_t)l)) {
- ++page_line;
- if (page_line >= 0) /* out of room in header */
+ page_line++;
+ if (page_line >= 0) { // out of room in header
break;
- mch_print_start_line(TRUE, page_line);
+ }
+ mch_print_start_line(true, page_line);
}
p += l;
}
xfree(tbuf);
- if (psettings->do_syntax)
- /* Set colors for next character. */
+ if (psettings->do_syntax) {
+ // Set colors for next character.
current_syn_id = -1;
- else {
- /* Set colors and font back to normal. */
+ } else {
+ // Set colors and font back to normal.
prt_set_fg(PRCOLOR_BLACK);
prt_set_bg(PRCOLOR_WHITE);
- prt_set_font(FALSE, FALSE, FALSE);
+ prt_set_font(kFalse, kFalse, kFalse);
}
}
@@ -559,8 +582,9 @@ static void prt_header(prt_settings_T *psettings, int pagenum, linenr_T lnum)
*/
static void prt_message(char_u *s)
{
- screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
- screen_puts(s, (int)Rows - 1, 0, hl_attr(HLF_R));
+ grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ',
+ 0);
+ grid_puts(&default_grid, s, (int)Rows - 1, 0, HL_ATTR(HLF_R));
ui_flush();
}
@@ -616,21 +640,19 @@ void ex_hardcopy(exarg_T *eap)
else
settings.do_syntax = settings.has_color;
- /* Set up printing attributes for line numbers */
+ // Set up printing attributes for line numbers
settings.number.fg_color = PRCOLOR_BLACK;
settings.number.bg_color = PRCOLOR_WHITE;
- settings.number.bold = FALSE;
- settings.number.italic = TRUE;
- settings.number.underline = FALSE;
- /*
- * Syntax highlighting of line numbers.
- */
- if (prt_use_number() && settings.do_syntax) {
- int id;
+ settings.number.bold = kFalse;
+ settings.number.italic = kTrue;
+ settings.number.underline = kFalse;
- id = syn_name2id((char_u *)"LineNr");
- if (id > 0)
+ // Syntax highlighting of line numbers.
+ if (prt_use_number() && settings.do_syntax) {
+ int id = syn_name2id((char_u *)"LineNr");
+ if (id > 0) {
id = syn_get_final_id(id);
+ }
prt_get_attr(id, &settings.number, settings.modec);
}
@@ -648,13 +670,13 @@ void ex_hardcopy(exarg_T *eap)
/* Set colors and font to normal. */
curr_bg = 0xffffffff;
curr_fg = 0xffffffff;
- curr_italic = MAYBE;
- curr_bold = MAYBE;
- curr_underline = MAYBE;
+ curr_italic = kNone;
+ curr_bold = kNone;
+ curr_underline = kNone;
prt_set_fg(PRCOLOR_BLACK);
prt_set_bg(PRCOLOR_WHITE);
- prt_set_font(FALSE, FALSE, FALSE);
+ prt_set_font(kFalse, kFalse, kFalse);
current_syn_id = -1;
jobsplit = (printer_opts[OPT_PRINT_JOBSPLIT].present
@@ -817,19 +839,17 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
tab_spaces = ppos->lead_spaces;
}
- mch_print_start_line(0, page_line);
+ mch_print_start_line(false, page_line);
line = ml_get(ppos->file_line);
/*
* Loop over the columns until the end of the file line or right margin.
*/
for (col = ppos->column; line[col] != NUL && !need_break; col += outputlen) {
- outputlen = 1;
- if (has_mbyte && (outputlen = (*mb_ptr2len)(line + col)) < 1)
+ if ((outputlen = (*mb_ptr2len)(line + col)) < 1) {
outputlen = 1;
- /*
- * syntax highlighting stuff.
- */
+ }
+ // syntax highlighting stuff.
if (psettings->do_syntax) {
id = syn_get_id(curwin, ppos->file_line, col, 1, NULL, FALSE);
if (id > 0)
@@ -873,10 +893,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T
need_break = 1;
} else {
need_break = mch_print_text_out(line + col, (size_t)outputlen);
- if (has_mbyte)
- print_pos += (*mb_ptr2cells)(line + col);
- else
- print_pos++;
+ print_pos += utf_ptr2cells(line + col);
}
}
@@ -1244,8 +1261,8 @@ static int prt_do_moveto;
static int prt_need_font;
static int prt_font;
static int prt_need_underline;
-static int prt_underline;
-static int prt_do_underline;
+static TriState prt_underline;
+static TriState prt_do_underline;
static int prt_need_fgcol;
static uint32_t prt_fgcol;
static int prt_need_bgcol;
@@ -1523,8 +1540,8 @@ static int prt_find_resource(char *name, struct prt_ps_resource_S *resource)
/* Look for named resource file in runtimepath */
STRCPY(buffer, "print");
add_pathsep((char *)buffer);
- vim_strcat(buffer, (char_u *)name, MAXPATHL);
- vim_strcat(buffer, (char_u *)".ps", MAXPATHL);
+ xstrlcat((char *)buffer, name, MAXPATHL);
+ xstrlcat((char *)buffer, ".ps", MAXPATHL);
resource->filename[0] = NUL;
retval = (do_in_runtimepath(buffer, 0, prt_resource_name, resource->filename)
&& resource->filename[0] != NUL);
@@ -2106,7 +2123,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit)
props = enc_canon_props(p_encoding);
if (!(props & ENC_8BIT) && ((*p_pmcs != NUL) || !(props & ENC_UNICODE))) {
p_mbenc_first = NULL;
- int effective_cmap;
+ int effective_cmap = 0;
for (cmap = 0; cmap < (int)ARRAY_SIZE(prt_ps_mbfonts); cmap++)
if (prt_match_encoding((char *)p_encoding, &prt_ps_mbfonts[cmap],
&p_mbenc)) {
@@ -2557,13 +2574,12 @@ int mch_print_begin(prt_settings_T *psettings)
prt_conv.vc_type = CONV_NONE;
if (!(enc_canon_props(p_enc) & enc_canon_props(p_encoding) & ENC_8BIT)) {
- /* Set up encoding conversion if required */
- if (FAIL == convert_setup(&prt_conv, p_enc, p_encoding)) {
- EMSG2(_("E620: Unable to convert to print encoding \"%s\""),
- p_encoding);
- return FALSE;
+ // Set up encoding conversion if required
+ if (convert_setup(&prt_conv, p_enc, p_encoding) == FAIL) {
+ emsgf(_("E620: Unable to convert to print encoding \"%s\""),
+ p_encoding);
+ return false;
}
- prt_do_conv = TRUE;
}
prt_do_conv = prt_conv.vc_type != CONV_NONE;
@@ -2834,7 +2850,7 @@ int mch_print_begin_page(char_u *str)
/* We have reset the font attributes, force setting them again. */
curr_bg = 0xffffffff;
curr_fg = 0xffffffff;
- curr_bold = MAYBE;
+ curr_bold = kNone;
return !prt_file_error;
}
@@ -2847,11 +2863,12 @@ int mch_print_blank_page(void)
static double prt_pos_x = 0;
static double prt_pos_y = 0;
-void mch_print_start_line(int margin, int page_line)
+void mch_print_start_line(const bool margin, const int page_line)
{
prt_pos_x = prt_left_margin;
- if (margin)
+ if (margin) {
prt_pos_x -= prt_number_width;
+ }
prt_pos_y = prt_top_margin - prt_first_line_height -
page_line * prt_line_height;
@@ -2861,17 +2878,13 @@ void mch_print_start_line(int margin, int page_line)
prt_half_width = FALSE;
}
-int mch_print_text_out(char_u *p, size_t len)
+int mch_print_text_out(char_u *const textp, size_t len)
{
- int need_break;
+ char_u *p = textp;
char_u ch;
char_u ch_buff[8];
- double char_width;
- double next_pos;
- int in_ascii;
- int half_width;
-
- char_width = prt_char_width;
+ char_u *tofree = NULL;
+ double char_width = prt_char_width;
/* Ideally VIM would create a rearranged CID font to combine a Roman and
* CJKV font to do what VIM is doing here - use a Roman font for characters
@@ -2881,7 +2894,7 @@ int mch_print_text_out(char_u *p, size_t len)
* years! If they ever do, a lot of this code will disappear.
*/
if (prt_use_courier) {
- in_ascii = (len == 1 && *p < 0x80);
+ const bool in_ascii = (len == 1 && *p < 0x80);
if (prt_in_ascii) {
if (!in_ascii) {
/* No longer in ASCII range - need to switch font */
@@ -2897,9 +2910,10 @@ int mch_print_text_out(char_u *p, size_t len)
}
}
if (prt_out_mbyte) {
- half_width = ((*mb_ptr2cells)(p) == 1);
- if (half_width)
+ const bool half_width = (utf_ptr2cells(p) == 1);
+ if (half_width) {
char_width /= 2;
+ }
if (prt_half_width) {
if (!half_width) {
prt_half_width = FALSE;
@@ -2972,23 +2986,24 @@ int mch_print_text_out(char_u *p, size_t len)
}
if (prt_do_conv) {
- /* Convert from multi-byte to 8-bit encoding */
- p = string_convert(&prt_conv, p, &len);
- if (p == NULL)
- p = (char_u *)xstrdup("");
+ // Convert from multi-byte to 8-bit encoding
+ tofree = p = string_convert(&prt_conv, p, &len);
+ if (p == NULL) {
+ p = (char_u *)"";
+ len = 0;
+ }
}
if (prt_out_mbyte) {
- /* Multi-byte character strings are represented more efficiently as hex
- * strings when outputting clean 8 bit PS.
- */
- do {
+ // Multi-byte character strings are represented more efficiently as hex
+ // strings when outputting clean 8 bit PS.
+ while (len-- > 0) {
ch = prt_hexchar[(unsigned)(*p) >> 4];
ga_append(&prt_ps_buffer, (char)ch);
ch = prt_hexchar[(*p) & 0xf];
ga_append(&prt_ps_buffer, (char)ch);
p++;
- } while (--len);
+ }
} else {
/* Add next character to buffer of characters to output.
* Note: One printed character may require several PS characters to
@@ -3022,25 +3037,26 @@ int mch_print_text_out(char_u *p, size_t len)
ga_append(&prt_ps_buffer, (char)ch);
}
- /* Need to free any translated characters */
- if (prt_do_conv)
- xfree(p);
+ // Need to free any translated characters
+ xfree(tofree);
prt_text_run += char_width;
prt_pos_x += char_width;
// The downside of fp - use relative error on right margin check
- next_pos = prt_pos_x + prt_char_width;
- need_break = ((next_pos > prt_right_margin)
- && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5)));
+ const double next_pos = prt_pos_x + prt_char_width;
+ const bool need_break = (next_pos > prt_right_margin)
+ && ((next_pos - prt_right_margin) > (prt_right_margin * 1e-5));
- if (need_break)
+ if (need_break) {
prt_flush_buffer();
+ }
return need_break;
}
-void mch_print_set_font(int iBold, int iItalic, int iUnderline)
+void mch_print_set_font(const TriState iBold, const TriState iItalic,
+ const TriState iUnderline)
{
int font = 0;
diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h
index 4ead8dd5d4..c6a3321b08 100644
--- a/src/nvim/hardcopy.h
+++ b/src/nvim/hardcopy.h
@@ -2,6 +2,11 @@
#define NVIM_HARDCOPY_H
#include <stdint.h>
+#include <stdlib.h> // for size_t
+
+#include "nvim/globals.h" // for TriState
+#include "nvim/types.h" // for char_u
+#include "nvim/ex_cmds_defs.h" // for exarg_T
/*
* Structure to hold printing color and font attributes.
@@ -9,9 +14,9 @@
typedef struct {
uint32_t fg_color;
uint32_t bg_color;
- int bold;
- int italic;
- int underline;
+ TriState bold;
+ TriState italic;
+ TriState underline;
int undercurl;
} prt_text_attr_T;
diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c
index 2da937633e..526bc284a4 100644
--- a/src/nvim/hashtab.c
+++ b/src/nvim/hashtab.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
+
/// @file hashtab.c
///
/// Handling of a hashtable with Vim-specific properties.
@@ -28,7 +31,6 @@
#include "nvim/hashtab.h"
#include "nvim/message.h"
#include "nvim/memory.h"
-#include "nvim/misc2.h"
// Magic value for algorithm that walks through the array.
#define PERTURB_SHIFT 5
@@ -37,6 +39,8 @@
# include "hashtab.c.generated.h"
#endif
+char hash_removed;
+
/// Initialize an empty hash table.
void hash_init(hashtab_T *ht)
{
@@ -81,22 +85,43 @@ void hash_clear_all(hashtab_T *ht, unsigned int off)
/// used for that key.
/// WARNING: Returned pointer becomes invalid as soon as the hash table
/// is changed in any way.
-hashitem_T* hash_find(hashtab_T *ht, char_u *key)
+hashitem_T *hash_find(const hashtab_T *const ht, const char_u *const key)
{
- return hash_lookup(ht, key, hash_hash(key));
+ return hash_lookup(ht, (const char *)key, STRLEN(key), hash_hash(key));
+}
+
+/// Like hash_find, but key is not NUL-terminated
+///
+/// @param[in] ht Hashtab to look in.
+/// @param[in] key Key of the looked-for item. Must not be NULL.
+/// @param[in] len Key length.
+///
+/// @return Pointer to the hash item corresponding to the given key.
+/// If not found, then return pointer to the empty item that would be
+/// used for that key.
+///
+/// @warning Returned pointer becomes invalid as soon as the hash table
+/// is changed in any way.
+hashitem_T *hash_find_len(const hashtab_T *const ht, const char *const key,
+ const size_t len)
+{
+ return hash_lookup(ht, key, len, hash_hash_len(key, len));
}
/// Like hash_find(), but caller computes "hash".
///
-/// @param key The key of the looked-for item. Must not be NULL.
-/// @param hash The precomputed hash for the key.
+/// @param[in] key The key of the looked-for item. Must not be NULL.
+/// @param[in] key_len Key length.
+/// @param[in] hash The precomputed hash for the key.
///
/// @return Pointer to the hashitem corresponding to the given key.
/// If not found, then return pointer to the empty item that would be
/// used for that key.
/// WARNING: Returned pointer becomes invalid as soon as the hash table
/// is changed in any way.
-hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash)
+hashitem_T *hash_lookup(const hashtab_T *const ht,
+ const char *const key, const size_t key_len,
+ const hash_T hash)
{
#ifdef HT_DEBUG
hash_count_lookup++;
@@ -116,7 +141,9 @@ hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash)
hashitem_T *freeitem = NULL;
if (hi->hi_key == HI_KEY_REMOVED) {
freeitem = hi;
- } else if ((hi->hi_hash == hash) && (STRCMP(hi->hi_key, key) == 0)) {
+ } else if ((hi->hi_hash == hash)
+ && (STRNCMP(hi->hi_key, key, key_len) == 0)
+ && hi->hi_key[key_len] == NUL) {
return hi;
}
@@ -141,7 +168,8 @@ hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash)
if ((hi->hi_hash == hash)
&& (hi->hi_key != HI_KEY_REMOVED)
- && (STRCMP(hi->hi_key, key) == 0)) {
+ && (STRNCMP(hi->hi_key, key, key_len) == 0)
+ && hi->hi_key[key_len] == NUL) {
return hi;
}
@@ -178,9 +206,9 @@ void hash_debug_results(void)
int hash_add(hashtab_T *ht, char_u *key)
{
hash_T hash = hash_hash(key);
- hashitem_T *hi = hash_lookup(ht, key, hash);
+ hashitem_T *hi = hash_lookup(ht, (const char *)key, STRLEN(key), hash);
if (!HASHITEM_EMPTY(hi)) {
- EMSG2(_(e_intern2), "hash_add()");
+ internal_error("hash_add()");
return FAIL;
}
hash_add_item(ht, hi, key, hash);
@@ -358,27 +386,68 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems)
ht->ht_filled = ht->ht_used;
}
+#define HASH_CYCLE_BODY(hash, p) \
+ hash = hash * 101 + *p++
+
/// Get the hash number for a key.
///
/// If you think you know a better hash function: Compile with HT_DEBUG set and
/// run a script that uses hashtables a lot. Vim will then print statistics
/// when exiting. Try that with the current hash algorithm and yours. The
/// lower the percentage the better.
-hash_T hash_hash(char_u *key)
+hash_T hash_hash(const char_u *key)
{
hash_T hash = *key;
if (hash == 0) {
- // Empty keys are not allowed, but we don't want to crash if we get one.
- return (hash_T) 0;
+ return (hash_T)0;
}
// A simplistic algorithm that appears to do very well.
// Suggested by George Reilly.
- char_u *p = key + 1;
+ const uint8_t *p = key + 1;
while (*p != NUL) {
- hash = hash * 101 + *p++;
+ HASH_CYCLE_BODY(hash, p);
+ }
+
+ return hash;
+}
+
+/// Get the hash number for a key that is not a NUL-terminated string
+///
+/// @warning Function does not check whether key contains NUL. But you will not
+/// be able to get hash entry in this case.
+///
+/// @param[in] key Key.
+/// @param[in] len Key length.
+///
+/// @return Key hash.
+hash_T hash_hash_len(const char *key, const size_t len)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (len == 0) {
+ return 0;
+ }
+
+ hash_T hash = *(uint8_t *)key;
+ const uint8_t *end = (uint8_t *)key + len;
+
+ const uint8_t *p = (const uint8_t *)key + 1;
+ while (p < end) {
+ HASH_CYCLE_BODY(hash, p);
}
return hash;
}
+
+#undef HASH_CYCLE_BODY
+
+/// Function to get HI_KEY_REMOVED value
+///
+/// Used for testing because luajit ffi does not allow getting addresses of
+/// globals.
+const char_u *_hash_key_removed(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return HI_KEY_REMOVED;
+}
diff --git a/src/nvim/hashtab.h b/src/nvim/hashtab.h
index 7233d8c47c..973b97d476 100644
--- a/src/nvim/hashtab.h
+++ b/src/nvim/hashtab.h
@@ -5,14 +5,19 @@
#include "nvim/types.h"
+/// Magic number used for hashitem "hi_key" value indicating a deleted item
+///
+/// Only the address is used.
+extern char hash_removed;
+
/// Type for hash number (hash calculation result).
typedef size_t hash_T;
/// The address of "hash_removed" is used as a magic number
/// for hi_key to indicate a removed item.
-#define HI_KEY_REMOVED &hash_removed
+#define HI_KEY_REMOVED ((char_u *)&hash_removed)
#define HASHITEM_EMPTY(hi) ((hi)->hi_key == NULL \
- || (hi)->hi_key == &hash_removed)
+ || (hi)->hi_key == (char_u *)&hash_removed)
/// A hastable item.
///
@@ -65,6 +70,25 @@ typedef struct hashtable_S {
hashitem_T ht_smallarray[HT_INIT_SIZE]; /// initial array
} hashtab_T;
+/// Iterate over a hashtab
+///
+/// @param[in] ht Hashtab to iterate over.
+/// @param hi Name of the variable with current hashtab entry.
+/// @param code Cycle body.
+#define HASHTAB_ITER(ht, hi, code) \
+ do { \
+ hashtab_T *const hi##ht_ = (ht); \
+ size_t hi##todo_ = hi##ht_->ht_used; \
+ for (hashitem_T *hi = hi##ht_->ht_array; hi##todo_; hi++) { \
+ if (!HASHITEM_EMPTY(hi)) { \
+ { \
+ code \
+ } \
+ hi##todo_--; \
+ } \
+ } \
+ } while (0)
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "hashtab.h.generated.h"
#endif
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
new file mode 100644
index 0000000000..41d60fa3ea
--- /dev/null
+++ b/src/nvim/highlight.c
@@ -0,0 +1,416 @@
+// 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
+
+// highlight.c: low level code for UI and syntax highlighting
+
+#include "nvim/vim.h"
+#include "nvim/highlight.h"
+#include "nvim/highlight_defs.h"
+#include "nvim/map.h"
+#include "nvim/screen.h"
+#include "nvim/syntax.h"
+#include "nvim/ui.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "highlight.c.generated.h"
+#endif
+
+static bool hlstate_active = false;
+
+static kvec_t(HlEntry) attr_entries = KV_INITIAL_VALUE;
+
+static Map(HlEntry, int) *attr_entry_ids;
+static Map(int, int) *combine_attr_entries;
+
+void highlight_init(void)
+{
+ attr_entry_ids = map_new(HlEntry, int)();
+ combine_attr_entries = map_new(int, int)();
+
+ // index 0 is no attribute, add dummy entry:
+ kv_push(attr_entries, ((HlEntry){ .attr = HLATTRS_INIT, .kind = kHlUnknown,
+ .id1 = 0, .id2 = 0 }));
+}
+
+/// @return TRUE if hl table was reset
+bool highlight_use_hlstate(void)
+{
+ if (hlstate_active) {
+ return false;
+ }
+ hlstate_active = true;
+ // hl tables must now be rebuilt.
+ clear_hl_tables(true);
+ return true;
+}
+
+/// Return the attr number for a set of colors and font, and optionally
+/// a semantic description (see ext_hlstate documentation).
+/// Add a new entry to the attr_entries array if the combination is new.
+/// @return 0 for error.
+static int get_attr_entry(HlEntry entry)
+{
+ if (!hlstate_active) {
+ // This information will not be used, erase it and reduce the table size.
+ entry.kind = kHlUnknown;
+ entry.id1 = 0;
+ entry.id2 = 0;
+ }
+
+ int id = map_get(HlEntry, int)(attr_entry_ids, entry);
+ if (id > 0) {
+ return id;
+ }
+
+ static bool recursive = false;
+ if (kv_size(attr_entries) > MAX_TYPENR) {
+ // Running out of attribute entries! remove all attributes, and
+ // compute new ones for all groups.
+ // When called recursively, we are really out of numbers.
+ if (recursive) {
+ EMSG(_("E424: Too many different highlighting attributes in use"));
+ return 0;
+ }
+ recursive = true;
+
+ clear_hl_tables(true);
+
+ recursive = false;
+ if (entry.kind == kHlCombine) {
+ // This entry is now invalid, don't put it
+ return 0;
+ }
+ }
+
+ id = (int)kv_size(attr_entries);
+ kv_push(attr_entries, entry);
+
+ map_put(HlEntry, int)(attr_entry_ids, entry, id);
+
+ Array inspect = hl_inspect(id);
+
+ // Note: internally we don't distinguish between cterm and rgb attributes,
+ // remote_ui_hl_attr_define will however.
+ ui_call_hl_attr_define(id, entry.attr, entry.attr, inspect);
+ api_free_array(inspect);
+ return id;
+}
+
+/// When a UI connects, we need to send it the table of highlights used so far.
+void ui_send_all_hls(UI *ui)
+{
+ for (size_t i = 1; i < kv_size(attr_entries); i++) {
+ Array inspect = hl_inspect((int)i);
+ ui->hl_attr_define(ui, (Integer)i, kv_A(attr_entries, i).attr,
+ kv_A(attr_entries, i).attr, inspect);
+ api_free_array(inspect);
+ }
+}
+
+/// Get attribute code for a syntax group.
+int hl_get_syn_attr(int idx, HlAttrs at_en)
+{
+ // TODO(bfredl): should we do this unconditionally
+ if (at_en.cterm_fg_color != 0 || at_en.cterm_bg_color != 0
+ || at_en.rgb_fg_color != -1 || at_en.rgb_bg_color != -1
+ || at_en.rgb_sp_color != -1 || at_en.cterm_ae_attr != 0
+ || at_en.rgb_ae_attr != 0) {
+ return get_attr_entry((HlEntry){ .attr = at_en, .kind = kHlSyntax,
+ .id1 = idx, .id2 = 0 });
+ } else {
+ // If all the fields are cleared, clear the attr field back to default value
+ return 0;
+ }
+}
+
+/// Get attribute code for a builtin highlight group.
+///
+/// The final syntax group could be modified by hi-link or 'winhighlight'.
+int hl_get_ui_attr(int idx, int final_id, bool optional)
+{
+ HlAttrs attrs = HLATTRS_INIT;
+ bool available = false;
+
+ int syn_attr = syn_id2attr(final_id);
+ if (syn_attr != 0) {
+ attrs = syn_attr2entry(syn_attr);
+ available = true;
+ }
+ if (optional && !available) {
+ return 0;
+ }
+ return get_attr_entry((HlEntry){ .attr = attrs, .kind = kHlUI,
+ .id1 = idx, .id2 = final_id });
+}
+
+void update_window_hl(win_T *wp, bool invalid)
+{
+ if (!wp->w_hl_needs_update && !invalid) {
+ return;
+ }
+ wp->w_hl_needs_update = false;
+
+ // determine window specific background set in 'winhighlight'
+ if (wp != curwin && wp->w_hl_ids[HLF_INACTIVE] > 0) {
+ wp->w_hl_attr_normal = hl_get_ui_attr(HLF_INACTIVE,
+ wp->w_hl_ids[HLF_INACTIVE], true);
+ } else if (wp->w_hl_id_normal > 0) {
+ wp->w_hl_attr_normal = hl_get_ui_attr(-1, wp->w_hl_id_normal, true);
+ } else {
+ wp->w_hl_attr_normal = 0;
+ }
+ if (wp != curwin) {
+ wp->w_hl_attr_normal = hl_combine_attr(HL_ATTR(HLF_INACTIVE),
+ wp->w_hl_attr_normal);
+ }
+
+ for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
+ int attr;
+ if (wp->w_hl_ids[hlf] > 0) {
+ attr = hl_get_ui_attr(hlf, wp->w_hl_ids[hlf], false);
+ } else {
+ attr = HL_ATTR(hlf);
+ }
+ wp->w_hl_attrs[hlf] = attr;
+ }
+}
+
+/// Gets HL_UNDERLINE highlight.
+int hl_get_underline(void)
+{
+ return get_attr_entry((HlEntry){
+ .attr = (HlAttrs){
+ .cterm_ae_attr = (int16_t)HL_UNDERLINE,
+ .cterm_fg_color = 0,
+ .cterm_bg_color = 0,
+ .rgb_ae_attr = (int16_t)HL_UNDERLINE,
+ .rgb_fg_color = -1,
+ .rgb_bg_color = -1,
+ .rgb_sp_color = -1,
+ },
+ .kind = kHlUI,
+ .id1 = 0,
+ .id2 = 0,
+ });
+}
+
+/// Get attribute code for forwarded :terminal highlights.
+int hl_get_term_attr(HlAttrs *aep)
+{
+ return get_attr_entry((HlEntry){ .attr= *aep, .kind = kHlTerminal,
+ .id1 = 0, .id2 = 0 });
+}
+
+/// Clear all highlight tables.
+void clear_hl_tables(bool reinit)
+{
+ if (reinit) {
+ kv_size(attr_entries) = 1;
+ map_clear(HlEntry, int)(attr_entry_ids);
+ map_clear(int, int)(combine_attr_entries);
+ highlight_attr_set_all();
+ highlight_changed();
+ screen_invalidate_highlights();
+ } else {
+ kv_destroy(attr_entries);
+ map_free(HlEntry, int)(attr_entry_ids);
+ map_free(int, int)(combine_attr_entries);
+ }
+}
+
+// Combine special attributes (e.g., for spelling) with other attributes
+// (e.g., for syntax highlighting).
+// "prim_attr" overrules "char_attr".
+// This creates a new group when required.
+// Since we expect there to be few spelling mistakes we don't cache the
+// result.
+// Return the resulting attributes.
+int hl_combine_attr(int char_attr, int prim_attr)
+{
+ if (char_attr == 0) {
+ return prim_attr;
+ } else if (prim_attr == 0) {
+ return char_attr;
+ }
+
+ // TODO(bfredl): could use a struct for clearer intent.
+ int combine_tag = (char_attr << 16) + prim_attr;
+ int id = map_get(int, int)(combine_attr_entries, combine_tag);
+ if (id > 0) {
+ return id;
+ }
+
+ HlAttrs char_aep = syn_attr2entry(char_attr);
+ HlAttrs spell_aep = syn_attr2entry(prim_attr);
+
+ // start with low-priority attribute, and override colors if present below.
+ HlAttrs new_en = char_aep;
+
+ new_en.cterm_ae_attr |= spell_aep.cterm_ae_attr;
+ new_en.rgb_ae_attr |= spell_aep.rgb_ae_attr;
+
+ if (spell_aep.cterm_fg_color > 0) {
+ new_en.cterm_fg_color = spell_aep.cterm_fg_color;
+ }
+
+ if (spell_aep.cterm_bg_color > 0) {
+ new_en.cterm_bg_color = spell_aep.cterm_bg_color;
+ }
+
+ if (spell_aep.rgb_fg_color >= 0) {
+ new_en.rgb_fg_color = spell_aep.rgb_fg_color;
+ }
+
+ if (spell_aep.rgb_bg_color >= 0) {
+ new_en.rgb_bg_color = spell_aep.rgb_bg_color;
+ }
+
+ if (spell_aep.rgb_sp_color >= 0) {
+ new_en.rgb_sp_color = spell_aep.rgb_sp_color;
+ }
+
+ id = get_attr_entry((HlEntry){ .attr = new_en, .kind = kHlCombine,
+ .id1 = char_attr, .id2 = prim_attr });
+ if (id > 0) {
+ map_put(int, int)(combine_attr_entries, combine_tag, id);
+ }
+
+ return id;
+}
+
+/// Get highlight attributes for a attribute code
+HlAttrs syn_attr2entry(int attr)
+{
+ if (attr <= 0 || attr >= (int)kv_size(attr_entries)) {
+ // invalid attribute code, or the tables were cleared
+ return HLATTRS_INIT;
+ }
+ return kv_A(attr_entries, attr).attr;
+}
+
+/// Gets highlight description for id `attr_id` as a map.
+Dictionary hl_get_attr_by_id(Integer attr_id, Boolean rgb, Error *err)
+{
+ Dictionary dic = ARRAY_DICT_INIT;
+
+ if (attr_id == 0) {
+ return dic;
+ }
+
+ if (attr_id <= 0 || attr_id >= (int)kv_size(attr_entries)) {
+ api_set_error(err, kErrorTypeException,
+ "Invalid attribute id: %" PRId64, attr_id);
+ return dic;
+ }
+
+ return hlattrs2dict(syn_attr2entry((int)attr_id), rgb);
+}
+
+/// Converts an HlAttrs into Dictionary
+///
+/// @param[in] aep data to convert
+/// @param use_rgb use 'gui*' settings if true, else resorts to 'cterm*'
+Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb)
+{
+ Dictionary hl = ARRAY_DICT_INIT;
+ int mask = use_rgb ? ae.rgb_ae_attr : ae.cterm_ae_attr;
+
+ if (mask & HL_BOLD) {
+ PUT(hl, "bold", BOOLEAN_OBJ(true));
+ }
+
+ if (mask & HL_STANDOUT) {
+ PUT(hl, "standout", BOOLEAN_OBJ(true));
+ }
+
+ if (mask & HL_UNDERLINE) {
+ PUT(hl, "underline", BOOLEAN_OBJ(true));
+ }
+
+ if (mask & HL_UNDERCURL) {
+ PUT(hl, "undercurl", BOOLEAN_OBJ(true));
+ }
+
+ if (mask & HL_ITALIC) {
+ PUT(hl, "italic", BOOLEAN_OBJ(true));
+ }
+
+ if (mask & HL_INVERSE) {
+ PUT(hl, "reverse", BOOLEAN_OBJ(true));
+ }
+
+ if (use_rgb) {
+ if (ae.rgb_fg_color != -1) {
+ PUT(hl, "foreground", INTEGER_OBJ(ae.rgb_fg_color));
+ }
+
+ if (ae.rgb_bg_color != -1) {
+ PUT(hl, "background", INTEGER_OBJ(ae.rgb_bg_color));
+ }
+
+ if (ae.rgb_sp_color != -1) {
+ PUT(hl, "special", INTEGER_OBJ(ae.rgb_sp_color));
+ }
+ } else {
+ if (cterm_normal_fg_color != ae.cterm_fg_color) {
+ PUT(hl, "foreground", INTEGER_OBJ(ae.cterm_fg_color - 1));
+ }
+
+ if (cterm_normal_bg_color != ae.cterm_bg_color) {
+ PUT(hl, "background", INTEGER_OBJ(ae.cterm_bg_color - 1));
+ }
+ }
+
+ return hl;
+}
+
+Array hl_inspect(int attr)
+{
+ Array ret = ARRAY_DICT_INIT;
+ if (hlstate_active) {
+ hl_inspect_impl(&ret, attr);
+ }
+ return ret;
+}
+
+static void hl_inspect_impl(Array *arr, int attr)
+{
+ Dictionary item = ARRAY_DICT_INIT;
+ if (attr <= 0 || attr >= (int)kv_size(attr_entries)) {
+ return;
+ }
+
+ HlEntry e = kv_A(attr_entries, attr);
+ switch (e.kind) {
+ case kHlSyntax:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("syntax")));
+ PUT(item, "hi_name",
+ STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id1))));
+ break;
+
+ case kHlUI:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("ui")));
+ const char *ui_name = (e.id1 == -1) ? "Normal" : hlf_names[e.id1];
+ PUT(item, "ui_name", STRING_OBJ(cstr_to_string(ui_name)));
+ PUT(item, "hi_name",
+ STRING_OBJ(cstr_to_string((char *)syn_id2name(e.id2))));
+ break;
+
+ case kHlTerminal:
+ PUT(item, "kind", STRING_OBJ(cstr_to_string("term")));
+ break;
+
+ case kHlCombine:
+ // attribute combination is associative, so flatten to an array
+ hl_inspect_impl(arr, e.id1);
+ hl_inspect_impl(arr, e.id2);
+ return;
+
+ case kHlUnknown:
+ return;
+ }
+ PUT(item, "id", INTEGER_OBJ(attr));
+ ADD(*arr, DICTIONARY_OBJ(item));
+}
diff --git a/src/nvim/highlight.h b/src/nvim/highlight.h
new file mode 100644
index 0000000000..6be0d6200b
--- /dev/null
+++ b/src/nvim/highlight.h
@@ -0,0 +1,13 @@
+#ifndef NVIM_HIGHLIGHT_H
+#define NVIM_HIGHLIGHT_H
+
+#include <stdbool.h>
+#include "nvim/highlight_defs.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/ui.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "highlight.h.generated.h"
+#endif
+
+#endif // NVIM_HIGHLIGHT_H
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
new file mode 100644
index 0000000000..40025fcbbb
--- /dev/null
+++ b/src/nvim/highlight_defs.h
@@ -0,0 +1,172 @@
+#ifndef NVIM_HIGHLIGHT_DEFS_H
+#define NVIM_HIGHLIGHT_DEFS_H
+
+#include <inttypes.h>
+
+#include "nvim/macros.h"
+
+typedef int32_t RgbValue;
+
+/// Highlighting attribute bits.
+///
+/// sign bit should not be used here, as it identifies invalid highlight
+typedef enum {
+ HL_INVERSE = 0x01,
+ HL_BOLD = 0x02,
+ HL_ITALIC = 0x04,
+ HL_UNDERLINE = 0x08,
+ HL_UNDERCURL = 0x10,
+ HL_STANDOUT = 0x20,
+} HlAttrFlags;
+
+/// Stores a complete highlighting entry, including colors and attributes
+/// for both TUI and GUI.
+typedef struct attr_entry {
+ int16_t rgb_ae_attr, cterm_ae_attr; ///< HlAttrFlags
+ RgbValue rgb_fg_color, rgb_bg_color, rgb_sp_color;
+ int cterm_fg_color, cterm_bg_color;
+} HlAttrs;
+
+#define HLATTRS_INIT (HlAttrs) { \
+ .rgb_ae_attr = 0, \
+ .cterm_ae_attr = 0, \
+ .rgb_fg_color = -1, \
+ .rgb_bg_color = -1, \
+ .rgb_sp_color = -1, \
+ .cterm_fg_color = 0, \
+ .cterm_bg_color = 0, \
+}
+
+/// Values for index in highlight_attr[].
+/// When making changes, also update hlf_names below!
+typedef enum {
+ HLF_8 = 0 // Meta & special keys listed with ":map", text that is
+ // displayed different from what it is
+ , HLF_EOB // after the last line in the buffer
+ , HLF_TERM // terminal cursor focused
+ , HLF_TERMNC // terminal cursor unfocused
+ , HLF_AT // @ characters at end of screen, characters that
+ // don't really exist in the text
+ , HLF_D // directories in CTRL-D listing
+ , HLF_E // error messages
+ , HLF_I // incremental search
+ , HLF_L // last search string
+ , HLF_M // "--More--" message
+ , HLF_CM // Mode (e.g., "-- INSERT --")
+ , HLF_N // line number for ":number" and ":#" commands
+ , HLF_CLN // current line number
+ , HLF_R // return to continue message and yes/no questions
+ , HLF_S // status lines
+ , HLF_SNC // status lines of not-current windows
+ , HLF_C // column to separate vertically split windows
+ , HLF_T // Titles for output from ":set all", ":autocmd" etc.
+ , HLF_V // Visual mode
+ , HLF_VNC // Visual mode, autoselecting and not clipboard owner
+ , HLF_W // warning messages
+ , HLF_WM // Wildmenu highlight
+ , HLF_FL // Folded line
+ , HLF_FC // Fold column
+ , HLF_ADD // Added diff line
+ , HLF_CHD // Changed diff line
+ , HLF_DED // Deleted diff line
+ , HLF_TXD // Text Changed in diff line
+ , HLF_SC // Sign column
+ , HLF_CONCEAL // Concealed text
+ , HLF_SPB // SpellBad
+ , HLF_SPC // SpellCap
+ , HLF_SPR // SpellRare
+ , HLF_SPL // SpellLocal
+ , HLF_PNI // popup menu normal item
+ , HLF_PSI // popup menu selected item
+ , HLF_PSB // popup menu scrollbar
+ , HLF_PST // popup menu scrollbar thumb
+ , HLF_TP // tabpage line
+ , HLF_TPS // tabpage line selected
+ , HLF_TPF // tabpage line filler
+ , HLF_CUC // 'cursorcolumn'
+ , HLF_CUL // 'cursorline'
+ , HLF_MC // 'colorcolumn'
+ , HLF_QFL // selected quickfix line
+ , HLF_0 // Whitespace
+ , HLF_INACTIVE // NormalNC: Normal text in non-current windows
+ , HLF_MSGSEP // message separator line
+ , HLF_COUNT // MUST be the last one
+} hlf_T;
+
+EXTERN const char *hlf_names[] INIT(= {
+ [HLF_8] = "SpecialKey",
+ [HLF_EOB] = "EndOfBuffer",
+ [HLF_TERM] = "TermCursor",
+ [HLF_TERMNC] = "TermCursorNC",
+ [HLF_AT] = "NonText",
+ [HLF_D] = "Directory",
+ [HLF_E] = "ErrorMsg",
+ [HLF_I] = "IncSearch",
+ [HLF_L] = "Search",
+ [HLF_M] = "MoreMsg",
+ [HLF_CM] = "ModeMsg",
+ [HLF_N] = "LineNr",
+ [HLF_CLN] = "CursorLineNr",
+ [HLF_R] = "Question",
+ [HLF_S] = "StatusLine",
+ [HLF_SNC] = "StatusLineNC",
+ [HLF_C] = "VertSplit",
+ [HLF_T] = "Title",
+ [HLF_V] = "Visual",
+ [HLF_VNC] = "VisualNC",
+ [HLF_W] = "WarningMsg",
+ [HLF_WM] = "WildMenu",
+ [HLF_FL] = "Folded",
+ [HLF_FC] = "FoldColumn",
+ [HLF_ADD] = "DiffAdd",
+ [HLF_CHD] = "DiffChange",
+ [HLF_DED] = "DiffDelete",
+ [HLF_TXD] = "DiffText",
+ [HLF_SC] = "SignColumn",
+ [HLF_CONCEAL] = "Conceal",
+ [HLF_SPB] = "SpellBad",
+ [HLF_SPC] = "SpellCap",
+ [HLF_SPR] = "SpellRare",
+ [HLF_SPL] = "SpellLocal",
+ [HLF_PNI] = "Pmenu",
+ [HLF_PSI] = "PmenuSel",
+ [HLF_PSB] = "PmenuSbar",
+ [HLF_PST] = "PmenuThumb",
+ [HLF_TP] = "TabLine",
+ [HLF_TPS] = "TabLineSel",
+ [HLF_TPF] = "TabLineFill",
+ [HLF_CUC] = "CursorColumn",
+ [HLF_CUL] = "CursorLine",
+ [HLF_MC] = "ColorColumn",
+ [HLF_QFL] = "QuickFixLine",
+ [HLF_0] = "Whitespace",
+ [HLF_INACTIVE] = "NormalNC",
+ [HLF_MSGSEP] = "MsgSeparator",
+});
+
+
+EXTERN int highlight_attr[HLF_COUNT]; // Highl. attr for each context.
+EXTERN int highlight_user[9]; // User[1-9] attributes
+EXTERN int highlight_stlnc[9]; // On top of user
+EXTERN int cterm_normal_fg_color INIT(= 0);
+EXTERN int cterm_normal_bg_color INIT(= 0);
+EXTERN RgbValue normal_fg INIT(= -1);
+EXTERN RgbValue normal_bg INIT(= -1);
+EXTERN RgbValue normal_sp INIT(= -1);
+
+typedef enum {
+ kHlUnknown,
+ kHlUI,
+ kHlSyntax,
+ kHlTerminal,
+ kHlCombine,
+} HlKind;
+
+typedef struct {
+ HlAttrs attr;
+ HlKind kind;
+ int id1;
+ int id2;
+} HlEntry;
+
+#endif // NVIM_HIGHLIGHT_DEFS_H
diff --git a/src/nvim/iconv.h b/src/nvim/iconv.h
index 4ac0d3fdd4..d7234090c4 100644
--- a/src/nvim/iconv.h
+++ b/src/nvim/iconv.h
@@ -10,9 +10,7 @@
// USE_ICONV, or to put the USE_ICONV definition in config.h.in directly. As
// it stands, globals.h needs to be included alongside iconv.h.
-#ifdef HAVE_CONFIG_H
-# include "auto/config.h"
-#endif
+#include "auto/config.h"
// Use iconv() when it's available, either by linking to the library at
// compile time or by loading it at runtime.
@@ -24,10 +22,10 @@
// defined, we provide a type shim (pull in errno.h and define iconv_t).
// This enables us to still load and use iconv dynamically at runtime.
#ifdef USE_ICONV
+# include <errno.h>
# ifdef HAVE_ICONV_H
# include <iconv.h>
# else
-# include <errno.h>
typedef void *iconv_t;
# endif
#endif
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index f2432dd71d..625d6baa17 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.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
+
/*
* CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
* Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
@@ -20,7 +23,6 @@
#include "nvim/eval.h"
#include "nvim/fileio.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/os/time.h"
#include "nvim/path.h"
@@ -52,7 +54,7 @@ static cscmd_T cs_cmds[] =
{ "add", cs_add,
N_("Add a new database"), "add file|dir [pre-path] [flags]", 0 },
{ "find", cs_find,
- N_("Query for a pattern"), "find c|d|e|f|g|i|s|t name", 1 },
+ N_("Query for a pattern"), "find a|c|d|e|f|g|i|s|t name", 1 },
{ "help", cs_help,
N_("Show this message"), "help", 0 },
{ "kill", cs_kill,
@@ -105,13 +107,13 @@ char_u *get_cscope_name(expand_T *xp, int idx)
{
const char *query_type[] =
{
- "c", "d", "e", "f", "g", "i", "s", "t", NULL
+ "a", "c", "d", "e", "f", "g", "i", "s", "t", NULL
};
- /* Complete with query type of ":cscope find {query_type}".
- * {query_type} can be letters (c, d, ... t) or numbers (0, 1,
- * ..., 8) but only complete with letters, since numbers are
- * redundant. */
+ // Complete with query type of ":cscope find {query_type}".
+ // {query_type} can be letters (c, d, ... a) or numbers (0, 1,
+ // ..., 9) but only complete with letters, since numbers are
+ // redundant.
return (char_u *)query_type[idx];
}
case EXP_CSCOPE_KILL:
@@ -141,44 +143,39 @@ char_u *get_cscope_name(expand_T *xp, int idx)
/*
* Handle command line completion for :cscope command.
*/
-void set_context_in_cscope_cmd(expand_T *xp, char_u *arg, cmdidx_T cmdidx)
+void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
{
- char_u *p;
-
- /* Default: expand subcommands */
+ // Default: expand subcommands.
xp->xp_context = EXPAND_CSCOPE;
- xp->xp_pattern = arg;
- expand_what = (cmdidx == CMD_scscope)
- ? EXP_SCSCOPE_SUBCMD : EXP_CSCOPE_SUBCMD;
+ xp->xp_pattern = (char_u *)arg;
+ expand_what = ((cmdidx == CMD_scscope)
+ ? EXP_SCSCOPE_SUBCMD : EXP_CSCOPE_SUBCMD);
/* (part of) subcommand already typed */
if (*arg != NUL) {
- p = skiptowhite(arg);
- if (*p != NUL) { /* past first word */
- xp->xp_pattern = skipwhite(p);
- if (*skiptowhite(xp->xp_pattern) != NUL)
+ const char *p = (const char *)skiptowhite((const char_u *)arg);
+ if (*p != NUL) { // Past first word.
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ if (*skiptowhite(xp->xp_pattern) != NUL) {
xp->xp_context = EXPAND_NOTHING;
- else if (STRNICMP(arg, "add", p - arg) == 0)
+ } else if (STRNICMP(arg, "add", p - arg) == 0) {
xp->xp_context = EXPAND_FILES;
- else if (STRNICMP(arg, "kill", p - arg) == 0)
+ } else if (STRNICMP(arg, "kill", p - arg) == 0) {
expand_what = EXP_CSCOPE_KILL;
- else if (STRNICMP(arg, "find", p - arg) == 0)
+ } else if (STRNICMP(arg, "find", p - arg) == 0) {
expand_what = EXP_CSCOPE_FIND;
- else
+ } else {
xp->xp_context = EXPAND_NOTHING;
+ }
}
}
}
-/*
- * PRIVATE: do_cscope_general
- *
- * Find the command, print help if invalid, and then call the corresponding
- * command function.
- */
-static void
-do_cscope_general (
+/// Find the command, print help if invalid, and then call the corresponding
+/// command function.
+static void
+do_cscope_general(
exarg_T *eap,
int make_split /* whether to split window */
)
@@ -207,29 +204,20 @@ do_cscope_general (
postponed_split_tab = 0;
}
-/*
- * PUBLIC: do_cscope
- */
-void do_cscope(exarg_T *eap)
+/// Implementation of ":cscope" and ":lcscope"
+void ex_cscope(exarg_T *eap)
{
do_cscope_general(eap, FALSE);
}
-/*
- * PUBLIC: do_scscope
- *
- * same as do_cscope, but splits window, too.
- */
-void do_scscope(exarg_T *eap)
+/// Implementation of ":scscope". Same as ex_cscope(), but splits window, too.
+void ex_scscope(exarg_T *eap)
{
do_cscope_general(eap, TRUE);
}
-/*
- * PUBLIC: do_cstag
- *
- */
-void do_cstag(exarg_T *eap)
+/// Implementation of ":cstag"
+void ex_cstag(exarg_T *eap)
{
int ret = FALSE;
@@ -284,18 +272,13 @@ void do_cstag(exarg_T *eap)
(void)EMSG(_("E257: cstag: tag not found"));
g_do_tagpreview = 0;
}
-
-} /* do_cscope */
+}
-/*
- * PUBLIC: cs_find
- *
- * this simulates a vim_fgets(), but for cscope, returns the next line
- * from the cscope output. should only be called from find_tags()
- *
- * returns TRUE if eof, FALSE otherwise
- */
+/// This simulates a vim_fgets(), but for cscope, returns the next line
+/// from the cscope output. should only be called from find_tags()
+///
+/// @return TRUE if eof, FALSE otherwise
int cs_fgets(char_u *buf, int size)
{
char *p;
@@ -308,21 +291,13 @@ int cs_fgets(char_u *buf, int size)
} /* cs_fgets */
-/*
- * PUBLIC: cs_free_tags
- *
- * called only from do_tag(), when popping the tag stack
- */
+/// Called only from do_tag(), when popping the tag stack.
void cs_free_tags(void)
{
cs_manage_matches(NULL, NULL, 0, Free);
}
-/*
- * PUBLIC: cs_print_tags
- *
- * called from do_tag()
- */
+/// Called from do_tag().
void cs_print_tags(void)
{
cs_manage_matches(NULL, NULL, 0, Print);
@@ -403,14 +378,8 @@ int cs_connection(int num, char_u *dbpath, char_u *ppath)
* PRIVATE functions
****************************************************************************/
-/*
- * PRIVATE: cs_add
- *
- * add cscope database or a directory name (to look for cscope.out)
- * to the cscope connection list
- *
- * MAXPATHL 256
- */
+/// Add cscope database or a directory name (to look for cscope.out)
+/// to the cscope connection list.
static int cs_add(exarg_T *eap)
{
char *fname, *ppath, *flags = NULL;
@@ -436,17 +405,13 @@ static void cs_stat_emsg(char *fname)
}
-/*
- * PRIVATE: cs_add_common
- *
- * the common routine to add a new cscope connection. called by
- * cs_add() and cs_reset(). i really don't like to do this, but this
- * routine uses a number of goto statements.
- */
-static int
-cs_add_common (
- char *arg1, /* filename - may contain environment variables */
- char *arg2, /* prepend path - may contain environment variables */
+/// The common routine to add a new cscope connection. Called by
+/// cs_add() and cs_reset(). I really don't like to do this, but this
+/// routine uses a number of goto statements.
+static int
+cs_add_common(
+ char *arg1, // filename - may contain environment variables
+ char *arg2, // prepend path - may contain environment variables
char *flags
)
{
@@ -531,9 +496,9 @@ staterr:
if (p_csverbose) {
msg_clr_eos();
- (void)smsg_attr(hl_attr(HLF_R),
- _("Added cscope database %s"),
- csinfo[i].fname);
+ (void)smsg_attr(HL_ATTR(HLF_R),
+ _("Added cscope database %s"),
+ csinfo[i].fname);
}
}
@@ -560,11 +525,7 @@ static int cs_check_for_tags(void)
return p_tags[0] != NUL && curbuf->b_p_tags != NULL;
} /* cs_check_for_tags */
-/*
- * PRIVATE: cs_cnt_connections
- *
- * count the number of cscope connections
- */
+/// Count the number of cscope connections.
static size_t cs_cnt_connections(void)
{
size_t cnt = 0;
@@ -584,21 +545,23 @@ static void cs_reading_emsg(
}
#define CSREAD_BUFSIZE 2048
-/*
- * PRIVATE: cs_cnt_matches
- *
- * count the number of matches for a given cscope connection.
- */
+/// Count the number of matches for a given cscope connection.
static int cs_cnt_matches(size_t idx)
{
char *stok;
- int nlines;
+ int nlines = 0;
char *buf = xmalloc(CSREAD_BUFSIZE);
for (;; ) {
+ errno = 0;
if (!fgets(buf, CSREAD_BUFSIZE, csinfo[idx].fr_fp)) {
- if (feof(csinfo[idx].fr_fp))
+ if (errno == EINTR) {
+ continue;
+ }
+
+ if (feof(csinfo[idx].fr_fp)) {
errno = EIO;
+ }
cs_reading_emsg(idx);
@@ -606,16 +569,20 @@ static int cs_cnt_matches(size_t idx)
return CSCOPE_FAILURE;
}
- /*
- * If the database is out of date, or there's some other problem,
- * cscope will output error messages before the number-of-lines output.
- * Display/discard any output that doesn't match what we want.
- * Accept "\S*cscope: X lines", also matches "mlcscope".
- */
- if ((stok = strtok(buf, (const char *)" ")) == NULL)
+ // If the database is out of date, or there's some other problem,
+ // cscope will output error messages before the number-of-lines output.
+ // Display/discard any output that doesn't match what we want.
+ // Accept "\S*cscope: X lines", also matches "mlcscope".
+ // Bail out for the "Unable to search" error.
+ if (strstr((const char *)buf, "Unable to search database") != NULL) {
+ break;
+ }
+ if ((stok = strtok(buf, (const char *)" ")) == NULL) {
continue;
- if (strstr((const char *)stok, "cscope:") == NULL)
+ }
+ if (strstr((const char *)stok, "cscope:") == NULL) {
continue;
+ }
if ((stok = strtok(NULL, (const char *)" ")) == NULL)
continue;
@@ -638,11 +605,7 @@ static int cs_cnt_matches(size_t idx)
} /* cs_cnt_matches */
-/*
- * PRIVATE: cs_create_cmd
- *
- * Creates the actual cscope command query from what the user entered.
- */
+/// Creates the actual cscope command query from what the user entered.
static char *cs_create_cmd(char *csoption, char *pattern)
{
char *cmd;
@@ -674,6 +637,9 @@ static char *cs_create_cmd(char *csoption, char *pattern)
case '8': case 'i':
search = 8;
break;
+ case '9': case 'a':
+ search = 9;
+ break;
default:
(void)EMSG(_("E561: unknown cscope search type"));
cs_usage_msg(Find);
@@ -695,12 +661,8 @@ static char *cs_create_cmd(char *csoption, char *pattern)
} /* cs_create_cmd */
-/*
- * PRIVATE: cs_create_connection
- *
- * This piece of code was taken/adapted from nvi. do we need to add
- * the BSD license notice?
- */
+/// This piece of code was taken/adapted from nvi. do we need to add
+/// the BSD license notice?
static int cs_create_connection(size_t i)
{
#ifdef UNIX
@@ -826,7 +788,6 @@ err_closing:
if (execl("/bin/sh", "sh", "-c", cmd, (char *)NULL) == -1)
PERROR(_("cs_create_connection exec failed"));
- stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
exit(127);
/* NOTREACHED */
default: /* parent. */
@@ -889,14 +850,10 @@ err_closing:
} /* cs_create_connection */
-/*
- * PRIVATE: cs_find
- *
- * query cscope using command line interface. parse the output and use tselect
- * to allow choices. like Nvi, creates a pipe to send to/from query/cscope.
- *
- * returns TRUE if we jump to a tag or abort, FALSE if not.
- */
+/// Query cscope using command line interface. Parse the output and use tselect
+/// to allow choices. Like Nvi, creates a pipe to send to/from query/cscope.
+///
+/// @return TRUE if we jump to a tag or abort, FALSE if not.
static int cs_find(exarg_T *eap)
{
char *opt, *pat;
@@ -930,11 +887,7 @@ static int cs_find(exarg_T *eap)
} /* cs_find */
-/*
- * PRIVATE: cs_find_common
- *
- * common code for cscope find, shared by cs_find() and do_cstag()
- */
+/// Common code for cscope find, shared by cs_find() and ex_cstag().
static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
int use_ll, char_u *cmdline)
{
@@ -970,6 +923,9 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
case '8':
cmdletter = 'i';
break;
+ case '9':
+ cmdletter = 'a';
+ break;
default:
cmdletter = opt[0];
}
@@ -989,11 +945,12 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
return FALSE;
}
- if (*qfpos != '0') {
- apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)"cscope",
- curbuf->b_fname, TRUE, curbuf);
- if (did_throw || force_abort)
- return FALSE;
+ if (*qfpos != '0'
+ && apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)"cscope",
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
+ return false;
+ }
}
}
@@ -1044,8 +1001,8 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
return FALSE;
}
- if (qfpos != NULL && *qfpos != '0' && totmatches > 0) {
- /* fill error list */
+ if (qfpos != NULL && *qfpos != '0') {
+ // Fill error list.
FILE *f;
char_u *tmp = vim_tempname();
qf_info_T *qi = NULL;
@@ -1059,9 +1016,9 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
fclose(f);
if (use_ll) /* Use location list */
wp = curwin;
- /* '-' starts a new error list */
+ // '-' starts a new error list
if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m",
- *qfpos == '-', cmdline) > 0) {
+ *qfpos == '-', cmdline, NULL) > 0) {
if (postponed_split != 0) {
(void)win_split(postponed_split > 0 ? postponed_split : 0,
postponed_split_flags);
@@ -1103,11 +1060,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
} /* cs_find_common */
-/*
- * PRIVATE: cs_help
- *
- * print help
- */
+/// Print help.
static int cs_help(exarg_T *eap)
{
cscmd_T *cmdp = cs_cmds;
@@ -1126,14 +1079,15 @@ static int cs_help(exarg_T *eap)
cmdp->usage);
if (strcmp(cmdp->name, "find") == 0)
MSG_PUTS(_("\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"));
+ " 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"));
cmdp++;
}
@@ -1154,11 +1108,7 @@ static void clear_csinfo(size_t i)
csinfo[i].to_fp = NULL;
}
-/*
- * PRIVATE: cs_insert_filelist
- *
- * insert a new cscope database filename into the filelist
- */
+/// Insert a new cscope database filename into the filelist.
static int cs_insert_filelist(char *fname, char *ppath, char *flags,
FileInfo *file_info)
{
@@ -1218,11 +1168,7 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags,
} /* cs_insert_filelist */
-/*
- * PRIVATE: cs_lookup_cmd
- *
- * find cscope command in command table
- */
+/// Find cscope command in command table.
static cscmd_T * cs_lookup_cmd(exarg_T *eap)
{
cscmd_T *cmdp;
@@ -1247,11 +1193,7 @@ static cscmd_T * cs_lookup_cmd(exarg_T *eap)
} /* cs_lookup_cmd */
-/*
- * PRIVATE: cs_kill
- *
- * nuke em
- */
+/// Nuke em.
static int cs_kill(exarg_T *eap)
{
char *stok;
@@ -1288,9 +1230,10 @@ static int cs_kill(exarg_T *eap)
}
}
- if (i >= csinfo_size || csinfo[i].fname == NULL) {
- if (p_csverbose)
+ if (!killall && (i >= csinfo_size || csinfo[i].fname == NULL)) {
+ if (p_csverbose) {
(void)EMSG2(_("E261: cscope connection %s not found"), stok);
+ }
return CSCOPE_FAILURE;
} else {
if (killall) {
@@ -1307,11 +1250,7 @@ static int cs_kill(exarg_T *eap)
} /* cs_kill */
-/*
- * PRIVATE: cs_kill_execute
- *
- * Actually kills a specific cscope connection.
- */
+/// Actually kills a specific cscope connection.
static void cs_kill_execute(
size_t i, /* cscope table index */
char *cname /* cscope database name */
@@ -1319,33 +1258,29 @@ static void cs_kill_execute(
{
if (p_csverbose) {
msg_clr_eos();
- (void)smsg_attr(hl_attr(HLF_R) | MSG_HIST,
- _("cscope connection %s closed"), cname);
+ (void)smsg_attr(HL_ATTR(HLF_R) | MSG_HIST,
+ _("cscope connection %s closed"), cname);
}
cs_release_csp(i, TRUE);
}
-/*
- * PRIVATE: cs_make_vim_style_matches
- *
- * convert the cscope output into a ctags style entry (as might be found
- * in a ctags tags file). there's one catch though: cscope doesn't tell you
- * the type of the tag you are looking for. for example, in Darren Hiebert's
- * ctags (the one that comes with vim), #define's use a line number to find the
- * tag in a file while function definitions use a regexp search pattern.
- *
- * i'm going to always use the line number because cscope does something
- * quirky (and probably other things i don't know about):
- *
- * if you have "# define" in your source file, which is
- * perfectly legal, cscope thinks you have "#define". this
- * will result in a failed regexp search. :(
- *
- * besides, even if this particular case didn't happen, the search pattern
- * would still have to be modified to escape all the special regular expression
- * characters to comply with ctags formatting.
- */
+/// Convert the cscope output into a ctags style entry (as might be found
+/// in a ctags tags file). there's one catch though: cscope doesn't tell you
+/// the type of the tag you are looking for. for example, in Darren Hiebert's
+/// ctags (the one that comes with vim), #define's use a line number to find the
+/// tag in a file while function definitions use a regexp search pattern.
+///
+/// I'm going to always use the line number because cscope does something
+/// quirky (and probably other things i don't know about):
+///
+/// if you have "# define" in your source file, which is
+/// perfectly legal, cscope thinks you have "#define". this
+/// will result in a failed regexp search. :(
+///
+/// Besides, even if this particular case didn't happen, the search pattern
+/// would still have to be modified to escape all the special regular expression
+/// characters to comply with ctags formatting.
static char *cs_make_vim_style_matches(char *fname, char *slno, char *search,
char *tagstr)
{
@@ -1379,24 +1314,20 @@ static char *cs_make_vim_style_matches(char *fname, char *slno, char *search,
} /* cs_make_vim_style_matches */
-/*
- * PRIVATE: cs_manage_matches
- *
- * this is kind of hokey, but i don't see an easy way round this..
- *
- * Store: keep a ptr to the (malloc'd) memory of matches originally
- * generated from cs_find(). the matches are originally lines directly
- * from cscope output, but transformed to look like something out of a
- * ctags. see cs_make_vim_style_matches for more details.
- *
- * Get: used only from cs_fgets(), this simulates a vim_fgets() to return
- * the next line from the cscope output. it basically keeps track of which
- * lines have been "used" and returns the next one.
- *
- * Free: frees up everything and resets
- *
- * Print: prints the tags
- */
+/// This is kind of hokey, but i don't see an easy way round this.
+///
+/// Store: keep a ptr to the (malloc'd) memory of matches originally
+/// generated from cs_find(). the matches are originally lines directly
+/// from cscope output, but transformed to look like something out of a
+/// ctags. see cs_make_vim_style_matches for more details.
+///
+/// Get: used only from cs_fgets(), this simulates a vim_fgets() to return
+/// the next line from the cscope output. it basically keeps track of which
+/// lines have been "used" and returns the next one.
+///
+/// Free: frees up everything and resets
+///
+/// Print: prints the tags
static char *cs_manage_matches(char **matches, char **contexts,
size_t totmatches, mcmd_e cmd)
{
@@ -1440,10 +1371,12 @@ static char *cs_manage_matches(char **matches, char **contexts,
next = 0;
break;
case Print:
+ assert(mp != NULL);
+ assert(cp != NULL);
cs_print_tags_priv(mp, cp, cnt);
break;
- default: /* should not reach here */
- (void)EMSG(_("E570: fatal error in cs_manage_matches"));
+ default: // should not reach here
+ IEMSG(_("E570: fatal error in cs_manage_matches"));
return NULL;
}
@@ -1451,11 +1384,7 @@ static char *cs_manage_matches(char **matches, char **contexts,
} /* cs_manage_matches */
-/*
- * PRIVATE: cs_parse_results
- *
- * parse cscope output
- */
+/// Parse cscope output.
static char *cs_parse_results(size_t cnumber, char *buf, int bufsize,
char **context, char **linenumber, char **search)
{
@@ -1463,9 +1392,16 @@ static char *cs_parse_results(size_t cnumber, char *buf, int bufsize,
char *p;
char *name;
+retry:
+ errno = 0;
if (fgets(buf, bufsize, csinfo[cnumber].fr_fp) == NULL) {
- if (feof(csinfo[cnumber].fr_fp))
+ if (errno == EINTR) {
+ goto retry;
+ }
+
+ if (feof(csinfo[cnumber].fr_fp)) {
errno = EIO;
+ }
cs_reading_emsg(cnumber);
@@ -1505,11 +1441,7 @@ static char *cs_parse_results(size_t cnumber, char *buf, int bufsize,
return name;
}
-/*
- * PRIVATE: cs_file_results
- *
- * write cscope find results to file
- */
+/// Write cscope find results to file.
static void cs_file_results(FILE *f, int *nummatches_a)
{
char *search, *slno;
@@ -1550,13 +1482,9 @@ static void cs_file_results(FILE *f, int *nummatches_a)
xfree(buf);
}
-/*
- * PRIVATE: cs_fill_results
- *
- * get parsed cscope output and calls cs_make_vim_style_matches to convert
- * into ctags format
- * When there are no matches sets "*matches_p" to NULL.
- */
+/// Get parsed cscope output and calls cs_make_vim_style_matches to convert
+/// into ctags format.
+/// When there are no matches sets "*matches_p" to NULL.
static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a,
char ***matches_p, char ***cntxts_p,
size_t *matched)
@@ -1664,16 +1592,16 @@ static void cs_print_tags_priv(char **matches, char **cntxts,
char *buf = xmalloc(newsize);
size_t bufsize = newsize; // Track available bufsize
(void)snprintf(buf, bufsize, cstag_msg, ptag);
- MSG_PUTS_ATTR(buf, hl_attr(HLF_T));
+ MSG_PUTS_ATTR(buf, HL_ATTR(HLF_T));
msg_clr_eos();
// restore matches[0]
*ptag_end = '\t';
// Column headers for match number, line number and filename.
- MSG_PUTS_ATTR(_("\n # line"), hl_attr(HLF_T));
+ MSG_PUTS_ATTR(_("\n # line"), HL_ATTR(HLF_T));
msg_advance(msg_col + 2);
- MSG_PUTS_ATTR(_("filename / context / line\n"), hl_attr(HLF_T));
+ MSG_PUTS_ATTR(_("filename / context / line\n"), HL_ATTR(HLF_T));
for (size_t i = 0; i < num_matches; i++) {
assert(strcnt(matches[i], '\t') >= 2);
@@ -1700,8 +1628,8 @@ static void cs_print_tags_priv(char **matches, char **cntxts,
bufsize = newsize;
}
(void)snprintf(buf, bufsize, csfmt_str, i + 1, lno);
- MSG_PUTS_ATTR(buf, hl_attr(HLF_CM));
- MSG_PUTS_LONG_ATTR(cs_pathcomponents(fname), hl_attr(HLF_CM));
+ MSG_PUTS_ATTR(buf, HL_ATTR(HLF_CM));
+ MSG_PUTS_LONG_ATTR(cs_pathcomponents(fname), HL_ATTR(HLF_CM));
// compute the required space for the context
char *context = cntxts[i] ? cntxts[i] : globalcntx;
@@ -1748,15 +1676,11 @@ static void cs_print_tags_priv(char **matches, char **cntxts,
xfree(buf);
}
-/*
- * PRIVATE: cs_read_prompt
- *
- * read a cscope prompt (basically, skip over the ">> ")
- */
+/// Read a cscope prompt (basically, skip over the ">> ").
static int cs_read_prompt(size_t i)
{
- char ch;
- char *buf = NULL; /* buffer for possible error message from cscope */
+ int ch;
+ char *buf = NULL; // buffer for possible error message from cscope
size_t bufpos = 0;
char *cs_emsg = _("E609: Cscope error: %s");
size_t cs_emsg_len = strlen(cs_emsg);
@@ -1767,40 +1691,50 @@ static int cs_read_prompt(size_t i)
assert(IOSIZE >= cs_emsg_len);
size_t maxlen = IOSIZE - cs_emsg_len;
- for (;; ) {
- while ((ch = (char)getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0])
- /* if there is room and char is printable */
+ while (1) {
+ while (1) {
+ do {
+ errno = 0;
+ ch = fgetc(csinfo[i].fr_fp);
+ } while (ch == EOF && errno == EINTR && ferror(csinfo[i].fr_fp));
+ if (ch == EOF || ch == CSCOPE_PROMPT[0]) {
+ break;
+ }
+ // if there is room and char is printable
if (bufpos < maxlen - 1 && vim_isprintc(ch)) {
// lazy buffer allocation
if (buf == NULL) {
buf = xmalloc(maxlen);
}
- {
- /* append character to the message */
- buf[bufpos++] = ch;
- buf[bufpos] = NUL;
- if (bufpos >= epromptlen
- && strcmp(&buf[bufpos - epromptlen], eprompt) == 0) {
- /* remove eprompt from buf */
- buf[bufpos - epromptlen] = NUL;
-
- /* print message to user */
- (void)EMSG2(cs_emsg, buf);
+ // append character to the message
+ buf[bufpos++] = (char)ch;
+ buf[bufpos] = NUL;
+ if (bufpos >= epromptlen
+ && strcmp(&buf[bufpos - epromptlen], eprompt) == 0) {
+ // remove eprompt from buf
+ buf[bufpos - epromptlen] = NUL;
+
+ // print message to user
+ (void)EMSG2(cs_emsg, buf);
- /* send RETURN to cscope */
- (void)putc('\n', csinfo[i].to_fp);
- (void)fflush(csinfo[i].to_fp);
+ // send RETURN to cscope
+ (void)putc('\n', csinfo[i].to_fp);
+ (void)fflush(csinfo[i].to_fp);
- /* clear buf */
- bufpos = 0;
- buf[bufpos] = NUL;
- }
+ // clear buf
+ bufpos = 0;
+ buf[bufpos] = NUL;
}
}
+ }
- for (size_t n = 0; n < strlen(CSCOPE_PROMPT); ++n) {
- if (n > 0)
- ch = (char)getc(csinfo[i].fr_fp);
+ for (size_t n = 0; n < strlen(CSCOPE_PROMPT); n++) {
+ if (n > 0) {
+ do {
+ errno = 0;
+ ch = fgetc(csinfo[i].fr_fp);
+ } while (ch == EOF && errno == EINTR && ferror(csinfo[i].fr_fp));
+ }
if (ch == EOF) {
PERROR("cs_read_prompt EOF");
if (buf != NULL && buf[0] != NUL)
@@ -1838,12 +1772,8 @@ static void sig_handler(int s) {
#endif
-/*
- * PRIVATE: cs_release_csp
- *
- * Does the actual free'ing for the cs ptr with an optional flag of whether
- * or not to free the filename. Called by cs_kill and cs_reset.
- */
+/// Does the actual free'ing for the cs ptr with an optional flag of whether
+/// or not to free the filename. Called by cs_kill and cs_reset.
static void cs_release_csp(size_t i, int freefnpp)
{
// Trying to exit normally (not sure whether it is fit to Unix cscope)
@@ -1955,15 +1885,11 @@ static void cs_release_csp(size_t i, int freefnpp)
} /* cs_release_csp */
-/*
- * PRIVATE: cs_reset
- *
- * calls cs_kill on all cscope connections then reinits
- */
+/// Calls cs_kill on all cscope connections then reinits.
static int cs_reset(exarg_T *eap)
{
char **dblist = NULL, **pplist = NULL, **fllist = NULL;
- char buf[20]; /* for snprintf " (#%zu)" */
+ char buf[25]; // for snprintf " (#%zu)"
if (csinfo_size == 0)
return CSCOPE_SUCCESS;
@@ -1991,7 +1917,7 @@ static int cs_reset(exarg_T *eap)
* "Added cscope database..."
*/
snprintf(buf, ARRAY_SIZE(buf), " (#%zu)", i);
- MSG_PUTS_ATTR(buf, hl_attr(HLF_R));
+ MSG_PUTS_ATTR(buf, HL_ATTR(HLF_R));
}
}
xfree(dblist[i]);
@@ -2002,23 +1928,20 @@ static int cs_reset(exarg_T *eap)
xfree(pplist);
xfree(fllist);
- if (p_csverbose)
- MSG_ATTR(_("All cscope databases reset"), hl_attr(HLF_R) | MSG_HIST);
+ if (p_csverbose) {
+ msg_attr(_("All cscope databases reset"), HL_ATTR(HLF_R) | MSG_HIST);
+ }
return CSCOPE_SUCCESS;
} /* cs_reset */
-/*
- * PRIVATE: cs_resolve_file
- *
- * Construct the full pathname to a file found in the cscope database.
- * (Prepends ppath, if there is one and if it's not already prepended,
- * otherwise just uses the name found.)
- *
- * We need to prepend the prefix because on some cscope's (e.g., the one that
- * ships with Solaris 2.6), the output never has the prefix prepended.
- * Contrast this with my development system (Digital Unix), which does.
- */
+/// Construct the full pathname to a file found in the cscope database.
+/// (Prepends ppath, if there is one and if it's not already prepended,
+/// otherwise just uses the name found.)
+///
+/// We need to prepend the prefix because on some cscope's (e.g., the one that
+/// ships with Solaris 2.6), the output never has the prefix prepended.
+/// Contrast this with my development system (Digital Unix), which does.
static char *cs_resolve_file(size_t i, char *name)
{
char *fullname;
@@ -2064,11 +1987,7 @@ static char *cs_resolve_file(size_t i, char *name)
}
-/*
- * PRIVATE: cs_show
- *
- * show all cscope connections
- */
+/// Show all cscope connections.
static int cs_show(exarg_T *eap)
{
if (cs_cnt_connections() == 0)
@@ -2076,7 +1995,7 @@ static int cs_show(exarg_T *eap)
else {
MSG_PUTS_ATTR(
_(" # pid database name prepend path\n"),
- hl_attr(HLF_T));
+ HL_ATTR(HLF_T));
for (size_t i = 0; i < csinfo_size; i++) {
if (csinfo[i].fname == NULL)
continue;
@@ -2096,11 +2015,7 @@ static int cs_show(exarg_T *eap)
} /* cs_show */
-/*
- * PUBLIC: cs_end
- *
- * Only called when VIM exits to quit any cscope sessions.
- */
+/// Only called when VIM exits to quit any cscope sessions.
void cs_end(void)
{
for (size_t i = 0; i < csinfo_size; i++)
diff --git a/src/nvim/if_cscope.h b/src/nvim/if_cscope.h
index 351d9caef6..e20462576a 100644
--- a/src/nvim/if_cscope.h
+++ b/src/nvim/if_cscope.h
@@ -1,6 +1,9 @@
#ifndef NVIM_IF_CSCOPE_H
#define NVIM_IF_CSCOPE_H
+#include "nvim/types.h" // for char_u and expand_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "if_cscope.h.generated.h"
#endif
diff --git a/src/nvim/if_cscope_defs.h b/src/nvim/if_cscope_defs.h
index 8cd74c74e6..fa18866840 100644
--- a/src/nvim/if_cscope_defs.h
+++ b/src/nvim/if_cscope_defs.h
@@ -18,6 +18,7 @@
#include "nvim/os/os_defs.h"
#include "nvim/os/fs_defs.h"
+#include "nvim/ex_cmds_defs.h"
#define CSCOPE_SUCCESS 0
#define CSCOPE_FAILURE -1
@@ -25,18 +26,7 @@
#define CSCOPE_DBFILE "cscope.out"
#define CSCOPE_PROMPT ">> "
-/*
- * s 0name Find this C symbol
- * g 1name Find this definition
- * d 2name Find functions called by this function
- * c 3name Find functions calling this function
- * t 4string find text string (cscope 12.9)
- * t 4name Find assignments to (cscope 13.3)
- * 5pattern change pattern -- NOT USED
- * e 6pattern Find this egrep pattern
- * f 7name Find this file
- * i 8name Find files #including this file
- */
+// See ":help cscope-find" for the possible queries.
typedef struct {
char * name;
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index f197669a97..13534ac1a9 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -1,16 +1,20 @@
+// 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 <inttypes.h>
#include <stdbool.h>
#include "nvim/ascii.h"
+#include "nvim/assert.h"
#include "nvim/indent.h"
#include "nvim/eval.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/regexp.h"
@@ -18,6 +22,7 @@
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/undo.h"
+#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -200,7 +205,12 @@ int set_indent(int size, int flags)
// after the if (!curbuf->b_p_et) below.
if (orig_char_len != -1) {
assert(orig_char_len + size - ind_done + line_len >= 0);
- newline = xmalloc((size_t)(orig_char_len + size - ind_done + line_len));
+ size_t n; // = orig_char_len + size - ind_done + line_len
+ size_t n2;
+ STRICT_ADD(orig_char_len, size, &n, size_t);
+ STRICT_ADD(ind_done, line_len, &n2, size_t);
+ STRICT_SUB(n, n2, &n, size_t);
+ newline = xmalloc(n);
todo = size - ind_done;
// Set total length of indent in characters, which may have been
@@ -222,7 +232,9 @@ int set_indent(int size, int flags)
} else {
todo = size;
assert(ind_len + line_len >= 0);
- newline = xmalloc((size_t)(ind_len + line_len));
+ size_t newline_size;
+ STRICT_ADD(ind_len, line_len, &newline_size, size_t);
+ newline = xmalloc(newline_size);
s = newline;
}
@@ -388,7 +400,9 @@ int copy_indent(int size, char_u *src)
// and the rest of the line.
line_len = (int)STRLEN(get_cursor_line_ptr()) + 1;
assert(ind_len + line_len >= 0);
- line = xmalloc((size_t)(ind_len + line_len));
+ size_t line_size;
+ STRICT_ADD(ind_len, line_len, &line_size, size_t);
+ line = xmalloc(line_size);
p = line;
}
}
@@ -451,26 +465,27 @@ int get_number_indent(linenr_T lnum)
* parameters into account. Window must be specified, since it is not
* necessarily always the current one.
*/
-int get_breakindent_win(win_T *wp, char_u *line) {
- static int prev_indent = 0; /* cached indent value */
- static long prev_ts = 0; /* cached tabstop value */
- static char_u *prev_line = NULL; /* cached pointer to line */
- static int prev_tick = 0; // changedtick of cached value
+int get_breakindent_win(win_T *wp, char_u *line)
+ FUNC_ATTR_NONNULL_ARG(1)
+{
+ static int prev_indent = 0; // Cached indent value.
+ static long prev_ts = 0; // Cached tabstop value.
+ static char_u *prev_line = NULL; // cached pointer to line.
+ static varnumber_T prev_tick = 0; // Changedtick of cached value.
int bri = 0;
- /* window width minus window margin space, i.e. what rests for text */
- const int eff_wwidth = wp->w_width
+ // window width minus window margin space, i.e. what rests for text
+ const int eff_wwidth = wp->w_grid.Columns
- ((wp->w_p_nu || wp->w_p_rnu)
&& (vim_strchr(p_cpo, CPO_NUMCOL) == NULL)
? number_width(wp) + 1 : 0);
/* used cached indent, unless pointer or 'tabstop' changed */
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
- || prev_tick != wp->w_buffer->b_changedtick) {
+ || prev_tick != buf_get_changedtick(wp->w_buffer)) {
prev_line = line;
prev_ts = wp->w_buffer->b_p_ts;
- prev_tick = wp->w_buffer->b_changedtick;
- prev_indent = get_indent_str(line,
- (int)wp->w_buffer->b_p_ts, wp->w_p_list);
+ prev_tick = buf_get_changedtick(wp->w_buffer);
+ prev_indent = get_indent_str(line, (int)wp->w_buffer->b_p_ts, wp->w_p_list);
}
bri = prev_indent + wp->w_p_brishift;
@@ -517,7 +532,7 @@ int inindent(int extra)
// Get indent level from 'indentexpr'.
int get_expr_indent(void)
{
- int indent;
+ int indent = -1;
pos_T save_pos;
colnr_T save_curswant;
int save_set_curswant;
@@ -535,7 +550,12 @@ int get_expr_indent(void)
sandbox++;
}
textlock++;
- indent = eval_to_number(curbuf->b_p_inde);
+
+ // Need to make a copy, the 'indentexpr' option could be changed while
+ // evaluating it.
+ char_u *inde_copy = vim_strsave(curbuf->b_p_inde);
+ indent = (int)eval_to_number(inde_copy);
+ xfree(inde_copy);
if (use_sandbox) {
sandbox--;
@@ -599,7 +619,7 @@ int get_lisp_indent(void)
paren = *pos;
pos = findmatch(NULL, '[');
- if ((pos == NULL) || ltp(pos, &paren)) {
+ if ((pos == NULL) || lt(*pos, paren)) {
pos = &paren;
}
}
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index efe8e73a3c..f8ce6200d7 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.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 <inttypes.h>
#include <stdint.h>
@@ -10,9 +13,9 @@
#include "nvim/edit.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
+#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
-#include "nvim/misc2.h"
#include "nvim/option.h"
#include "nvim/search.h"
#include "nvim/strings.h"
@@ -72,11 +75,12 @@ find_start_comment ( /* XXX */
/// Find the start of a comment or raw string, not knowing if we are in a
/// comment or raw string right now.
/// Search starts at w_cursor.lnum and goes backwards.
+/// If is_raw is given and returns start of raw_string, sets it to true.
///
/// @returns NULL when not inside a comment or raw string.
///
/// @note "CORS" -> Comment Or Raw String
-static pos_T *ind_find_start_CORS(void)
+static pos_T *ind_find_start_CORS(linenr_T *is_raw)
{
// XXX
static pos_T comment_pos_copy;
@@ -93,6 +97,9 @@ static pos_T *ind_find_start_CORS(void)
// If comment_pos is before rs_pos the raw string is inside the comment.
// If rs_pos is before comment_pos the comment is inside the raw string.
if (comment_pos == NULL || (rs_pos != NULL && lt(*rs_pos, *comment_pos))) {
+ if (is_raw != NULL && rs_pos != NULL) {
+ *is_raw = rs_pos->lnum;
+ }
return rs_pos;
}
return comment_pos;
@@ -174,9 +181,8 @@ static char_u *skip_string(char_u *p)
char_u *delim = p + 2;
char_u *paren = vim_strchr(delim, '(');
- if (paren != NULL)
- {
- long delim_len = paren - delim;
+ if (paren != NULL) {
+ const ptrdiff_t delim_len = paren - delim;
for (p += 3; *p; ++p)
if (p[0] == ')' && STRNCMP(p + 1, delim, delim_len) == 0
@@ -382,8 +388,9 @@ int cin_islabel(void)
* it.
*/
curwin->w_cursor.col = 0;
- if ((trypos = ind_find_start_CORS()) != NULL) /* XXX */
+ if ((trypos = ind_find_start_CORS(NULL)) != NULL) { // XXX
curwin->w_cursor = *trypos;
+ }
line = get_cursor_line_ptr();
if (cin_ispreproc(line)) /* ignore #defines, #if, etc. */
@@ -513,34 +520,41 @@ int cin_isscopedecl(char_u *s)
/* Maximum number of lines to search back for a "namespace" line. */
#define FIND_NAMESPACE_LIM 20
-/*
- * Recognize a "namespace" scope declaration.
- */
-static int cin_is_cpp_namespace(char_u *s)
+// Recognize a "namespace" scope declaration.
+static bool cin_is_cpp_namespace(char_u *s)
{
- char_u *p;
- int has_name = FALSE;
+ char_u *p;
+ bool has_name = false;
+ bool has_name_start = false;
s = cin_skipcomment(s);
if (STRNCMP(s, "namespace", 9) == 0 && (s[9] == NUL || !vim_iswordc(s[9]))) {
p = cin_skipcomment(skipwhite(s + 9));
while (*p != NUL) {
if (ascii_iswhite(*p)) {
- has_name = TRUE; /* found end of a name */
+ has_name = true; // found end of a name
p = cin_skipcomment(skipwhite(p));
} else if (*p == '{') {
break;
} else if (vim_iswordc(*p)) {
- if (has_name)
- return FALSE; /* word character after skipping past name */
- ++p;
+ has_name_start = true;
+ if (has_name) {
+ return false; // word character after skipping past name
+ }
+ p++;
+ } else if (p[0] == ':' && p[1] == ':' && vim_iswordc(p[2])) {
+ if (!has_name_start || has_name) {
+ return false;
+ }
+ // C++ 17 nested namespace
+ p += 3;
} else {
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/*
@@ -725,16 +739,20 @@ static int cin_ispreproc(char_u *s)
return FALSE;
}
-/*
- * Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
- * continuation line of a preprocessor statement. Decrease "*lnump" to the
- * start and return the line in "*pp".
- */
-static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
+/// Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
+/// continuation line of a preprocessor statement. Decrease "*lnump" to the
+/// start and return the line in "*pp".
+/// Put the amount of indent in "*amount".
+static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount)
{
char_u *line = *pp;
linenr_T lnum = *lnump;
- int retval = FALSE;
+ int retval = false;
+ int candidate_amount = *amount;
+
+ if (*line != NUL && line[STRLEN(line) - 1] == '\\') {
+ candidate_amount = get_indent_lnum(lnum);
+ }
for (;; ) {
if (cin_ispreproc(line)) {
@@ -749,8 +767,12 @@ static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
break;
}
- if (lnum != *lnump)
+ if (lnum != *lnump) {
*pp = ml_get(*lnump);
+ }
+ if (retval) {
+ *amount = candidate_amount;
+ }
return retval;
}
@@ -820,21 +842,22 @@ cin_isterminated (
return found_start;
}
-/*
- * Recognize the basic picture of a function declaration -- it needs to
- * have an open paren somewhere and a close paren at the end of the line and
- * no semicolons anywhere.
- * When a line ends in a comma we continue looking in the next line.
- * "sp" points to a string with the line. When looking at other lines it must
- * be restored to the line. When it's NULL fetch lines here.
- * "lnum" is where we start looking.
- * "min_lnum" is the line before which we will not be looking.
- */
+/// Recognizes the basic picture of a function declaration -- it needs to
+/// have an open paren somewhere and a close paren at the end of the line and
+/// no semicolons anywhere.
+/// When a line ends in a comma we continue looking in the next line.
+///
+/// @param[in] sp Points to a string with the line. When looking at other
+/// lines it must be restored to the line. When it's NULL fetch
+/// lines here.
+/// @param[in] first_lnum Where to start looking.
+/// @param[in] min_lnum The line before which we will not be looking.
static int cin_isfuncdecl(char_u **sp, linenr_T first_lnum, linenr_T min_lnum)
{
char_u *s;
linenr_T lnum = first_lnum;
- int retval = FALSE;
+ linenr_T save_lnum = curwin->w_cursor.lnum;
+ int retval = false;
pos_T *trypos;
int just_started = TRUE;
@@ -843,18 +866,22 @@ static int cin_isfuncdecl(char_u **sp, linenr_T first_lnum, linenr_T min_lnum)
else
s = *sp;
+ curwin->w_cursor.lnum = lnum;
if (find_last_paren(s, '(', ')')
&& (trypos = find_match_paren(curbuf->b_ind_maxparen)) != NULL) {
lnum = trypos->lnum;
- if (lnum < min_lnum)
- return FALSE;
-
+ if (lnum < min_lnum) {
+ curwin->w_cursor.lnum = save_lnum;
+ return false;
+ }
s = ml_get(lnum);
}
- /* Ignore line starting with #. */
- if (cin_ispreproc(s))
- return FALSE;
+ curwin->w_cursor.lnum = save_lnum;
+ // Ignore line starting with #.
+ if (cin_ispreproc(s)) {
+ return false;
+ }
while (*s && *s != '(' && *s != ';' && *s != '\'' && *s != '"') {
// ignore comments
@@ -1292,6 +1319,43 @@ static int cin_starts_with(char_u *s, char *word)
return STRNCMP(s, word, l) == 0 && !vim_isIDc(s[l]);
}
+/// Recognize a `extern "C"` or `extern "C++"` linkage specifications.
+static int cin_is_cpp_extern_c(char_u *s)
+{
+ char_u *p;
+ int has_string_literal = false;
+
+ s = cin_skipcomment(s);
+ if (STRNCMP(s, "extern", 6) == 0 && (s[6] == NUL || !vim_iswordc(s[6]))) {
+ p = cin_skipcomment(skipwhite(s + 6));
+ while (*p != NUL) {
+ if (ascii_iswhite(*p)) {
+ p = cin_skipcomment(skipwhite(p));
+ } else if (*p == '{') {
+ break;
+ } else if (p[0] == '"' && p[1] == 'C' && p[2] == '"') {
+ if (has_string_literal) {
+ return false;
+ }
+ has_string_literal = true;
+ p += 3;
+ } else if (p[0] == '"' && p[1] == 'C' && p[2] == '+' && p[3] == '+'
+ && p[4] == '"') {
+ if (has_string_literal) {
+ return false;
+ }
+ has_string_literal = true;
+ p += 5;
+ } else {
+ return false;
+ }
+ }
+ return has_string_literal ? true : false;
+ }
+ return false;
+}
+
+
/*
* Skip strings, chars and comments until at or past "trypos".
* Return the column found.
@@ -1300,14 +1364,19 @@ static int cin_skip2pos(pos_T *trypos)
{
char_u *line;
char_u *p;
+ char_u *new_p;
p = line = ml_get(trypos->lnum);
while (*p && (colnr_T)(p - line) < trypos->col) {
- if (cin_iscomment(p))
+ if (cin_iscomment(p)) {
p = cin_skipcomment(p);
- else {
- p = skip_string(p);
- ++p;
+ } else {
+ new_p = skip_string(p);
+ if (new_p == p) {
+ p++;
+ } else {
+ p = new_p;
+ }
}
}
return (int)(p - line);
@@ -1337,10 +1406,12 @@ static pos_T *find_start_brace(void)
pos = NULL;
/* ignore the { if it's in a // or / * * / comment */
if ((colnr_T)cin_skip2pos(trypos) == trypos->col
- && (pos = ind_find_start_CORS()) == NULL) /* XXX */
+ && (pos = ind_find_start_CORS(NULL)) == NULL) { // XXX
break;
- if (pos != NULL)
+ }
+ if (pos != NULL) {
curwin->w_cursor.lnum = pos->lnum;
+ }
}
curwin->w_cursor = cursor_save;
return trypos;
@@ -1379,7 +1450,7 @@ retry:
pos_copy = *trypos; /* copy trypos, findmatch will change it */
trypos = &pos_copy;
curwin->w_cursor = *trypos;
- if ((trypos_wk = ind_find_start_CORS()) != NULL) { /* XXX */
+ if ((trypos_wk = ind_find_start_CORS(NULL)) != NULL) { // XXX
ind_maxp_wk = ind_maxparen - (int)(cursor_save.lnum
- trypos_wk->lnum);
if (ind_maxp_wk > 0) {
@@ -1597,6 +1668,12 @@ void parse_cino(buf_T *buf)
* while(). */
buf->b_ind_if_for_while = 0;
+ // indentation for # comments
+ buf->b_ind_hash_comment = 0;
+
+ // Handle C++ extern "C" or "C++"
+ buf->b_ind_cpp_extern_c = 0;
+
for (p = buf->b_p_cino; *p; ) {
l = p++;
if (*p == '-')
@@ -1665,6 +1742,7 @@ void parse_cino(buf_T *buf)
case '#': buf->b_ind_hash_comment = n; break;
case 'N': buf->b_ind_cpp_namespace = n; break;
case 'k': buf->b_ind_if_for_while = n; break;
+ case 'E': buf->b_ind_cpp_extern_c = n; break;
}
if (*p == ',')
++p;
@@ -1722,6 +1800,7 @@ int get_c_indent(void)
int cont_amount = 0; /* amount for continuation line */
int original_line_islabel;
int added_to_amount = 0;
+ linenr_T raw_string_start = 0;
cpp_baseclass_cache_T cache_cpp_baseclass = { false, { MAXLNUM, 0 } };
/* make a copy, value is changed below */
@@ -1980,14 +2059,16 @@ int get_c_indent(void)
amount = -1;
for (lnum = cur_curpos.lnum - 1; lnum > our_paren_pos.lnum; --lnum) {
l = skipwhite(ml_get(lnum));
- if (cin_nocode(l)) /* skip comment lines */
+ if (cin_nocode(l)) { // skip comment lines
continue;
- if (cin_ispreproc_cont(&l, &lnum))
- continue; /* ignore #define, #if, etc. */
+ }
+ if (cin_ispreproc_cont(&l, &lnum, &amount)) {
+ continue; // ignore #define, #if, etc.
+ }
curwin->w_cursor.lnum = lnum;
- /* Skip a comment or raw string. XXX */
- if ((trypos = ind_find_start_CORS()) != NULL) {
+ // Skip a comment or raw string. XXX
+ if ((trypos = ind_find_start_CORS(NULL)) != NULL) {
lnum = trypos->lnum + 1;
continue;
}
@@ -2293,8 +2374,11 @@ int get_c_indent(void)
amount += curbuf->b_ind_open_imag;
l = skipwhite(get_cursor_line_ptr());
- if (cin_is_cpp_namespace(l))
+ if (cin_is_cpp_namespace(l)) {
amount += curbuf->b_ind_cpp_namespace;
+ } else if (cin_is_cpp_extern_c(l)) {
+ amount += curbuf->b_ind_cpp_extern_c;
+ }
} else {
/* Compensate for adding b_ind_open_extra later. */
amount -= curbuf->b_ind_open_extra;
@@ -2339,15 +2423,14 @@ int get_c_indent(void)
* up with it.
*/
if (curwin->w_cursor.lnum <= ourscope) {
- /* we reached end of scope:
- * if looking for an enum or structure initialization
- * go further back:
- * if it is an initializer (enum xxx or xxx =), then
- * don't add ind_continuation, otherwise it is a variable
- * declaration:
- * int x,
- * here; <-- add ind_continuation
- */
+ // We reached end of scope:
+ // If looking for a enum or structure initialization
+ // go further back:
+ // If it is an initializer (enum xxx or xxx =), then
+ // don't add ind_continuation, otherwise it is a variable
+ // declaration:
+ // int x,
+ // here; <-- add ind_continuation
if (lookfor == LOOKFOR_ENUM_OR_INIT) {
if (curwin->w_cursor.lnum == 0
|| curwin->w_cursor.lnum
@@ -2368,18 +2451,19 @@ int get_c_indent(void)
* If we're in a comment or raw string now, skip to
* the start of it.
*/
- trypos = ind_find_start_CORS();
+ trypos = ind_find_start_CORS(NULL);
if (trypos != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
continue;
}
- /*
- * Skip preprocessor directives and blank lines.
- */
- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+ //
+ // Skip preprocessor directives and blank lines.
+ //
+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) {
continue;
+ }
if (cin_nocode(l))
continue;
@@ -2476,22 +2560,26 @@ int get_c_indent(void)
/* If we're in a comment or raw string now, skip
* to the start of it. */
- trypos = ind_find_start_CORS();
+ trypos = ind_find_start_CORS(NULL);
if (trypos != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
continue;
}
- /* Skip preprocessor directives and blank lines. */
- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+ // Skip preprocessor directives and blank lines.
+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) {
continue;
+ }
/* Finally the actual check for "namespace". */
if (cin_is_cpp_namespace(l)) {
amount += curbuf->b_ind_cpp_namespace
- added_to_amount;
break;
+ } else if (cin_is_cpp_extern_c(l)) {
+ amount += curbuf->b_ind_cpp_extern_c - added_to_amount;
+ break;
}
if (cin_nocode(l))
@@ -2501,11 +2589,10 @@ int get_c_indent(void)
break;
}
- /*
- * If we're in a comment or raw string now, skip to the start
- * of it.
- */ /* XXX */
- if ((trypos = ind_find_start_CORS()) != NULL) {
+ // If we're in a comment or raw string now, skip to the start
+ // of it.
+ // XXX
+ if ((trypos = ind_find_start_CORS(&raw_string_start)) != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
continue;
@@ -2648,9 +2735,10 @@ int get_c_indent(void)
* unlocked it)
*/
l = get_cursor_line_ptr();
- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)
- || cin_nocode(l))
+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)
+ || cin_nocode(l)) {
continue;
+ }
/*
* Are we at the start of a cpp base class declaration or
@@ -3015,7 +3103,8 @@ int get_c_indent(void)
}
if (lookfor != LOOKFOR_TERM
&& lookfor != LOOKFOR_JS_KEY
- && lookfor != LOOKFOR_COMMA) {
+ && lookfor != LOOKFOR_COMMA
+ && raw_string_start != curwin->w_cursor.lnum) {
lookfor = LOOKFOR_UNTERM;
}
}
@@ -3270,11 +3359,10 @@ term_again:
l = get_cursor_line_ptr();
- /*
- * If we're in a comment or raw string now, skip to the start
- * of it.
- */ /* XXX */
- if ((trypos = ind_find_start_CORS()) != NULL) {
+ // If we're in a comment or raw string now, skip to the start
+ // of it.
+ // XXX
+ if ((trypos = ind_find_start_CORS(NULL)) != NULL) {
curwin->w_cursor.lnum = trypos->lnum + 1;
curwin->w_cursor.col = 0;
continue;
@@ -3295,11 +3383,12 @@ term_again:
break;
}
- /*
- * Skip preprocessor directives and blank lines.
- */
- if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
+ //
+ // Skip preprocessor directives and blank lines.
+ //
+ if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)) {
continue;
+ }
if (cin_nocode(l))
continue;
@@ -3391,9 +3480,10 @@ term_again:
while (curwin->w_cursor.lnum > 1) {
look = ml_get(--curwin->w_cursor.lnum);
- if (!(cin_nocode(look) || cin_ispreproc_cont(
- &look, &curwin->w_cursor.lnum)))
+ if (!(cin_nocode(look)
+ || cin_ispreproc_cont(&look, &curwin->w_cursor.lnum, &amount))) {
break;
+ }
}
if (curwin->w_cursor.lnum > 0
&& cin_ends_in(look, (char_u *)"}", NULL))
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index 99e94fc60f..ade5487ec8 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.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 <inttypes.h>
#include <limits.h>
@@ -21,23 +24,23 @@
* Some useful tables.
*/
-static struct modmasktable {
- short mod_mask; /* Bit-mask for particular key modifier */
- short mod_flag; /* Bit(s) for particular key modifier */
- char_u name; /* Single letter name of modifier */
-} mod_mask_table[] =
-{
- {MOD_MASK_ALT, MOD_MASK_ALT, (char_u)'M'},
- {MOD_MASK_META, MOD_MASK_META, (char_u)'T'},
- {MOD_MASK_CTRL, MOD_MASK_CTRL, (char_u)'C'},
- {MOD_MASK_SHIFT, MOD_MASK_SHIFT, (char_u)'S'},
- {MOD_MASK_MULTI_CLICK, MOD_MASK_2CLICK, (char_u)'2'},
- {MOD_MASK_MULTI_CLICK, MOD_MASK_3CLICK, (char_u)'3'},
- {MOD_MASK_MULTI_CLICK, MOD_MASK_4CLICK, (char_u)'4'},
- {MOD_MASK_CMD, MOD_MASK_CMD, (char_u)'D'},
+static const struct modmasktable {
+ uint16_t mod_mask; ///< Bit-mask for particular key modifier.
+ uint16_t mod_flag; ///< Bit(s) for particular key modifier.
+ char_u name; ///< Single letter name of modifier.
+} mod_mask_table[] = {
+ { MOD_MASK_ALT, MOD_MASK_ALT, (char_u)'M' },
+ { MOD_MASK_META, MOD_MASK_META, (char_u)'T' },
+ { MOD_MASK_CTRL, MOD_MASK_CTRL, (char_u)'C' },
+ { MOD_MASK_SHIFT, MOD_MASK_SHIFT, (char_u)'S' },
+ { MOD_MASK_MULTI_CLICK, MOD_MASK_2CLICK, (char_u)'2' },
+ { MOD_MASK_MULTI_CLICK, MOD_MASK_3CLICK, (char_u)'3' },
+ { MOD_MASK_MULTI_CLICK, MOD_MASK_4CLICK, (char_u)'4' },
+ { MOD_MASK_CMD, MOD_MASK_CMD, (char_u)'D' },
// 'A' must be the last one
- {MOD_MASK_ALT, MOD_MASK_ALT, (char_u)'A'},
- {0, 0, NUL}
+ { MOD_MASK_ALT, MOD_MASK_ALT, (char_u)'A' },
+ { 0, 0, NUL }
+ // NOTE: when adding an entry, update MAX_KEY_NAME_LEN!
};
/*
@@ -136,156 +139,155 @@ static char_u modifier_keys_table[] =
NUL
};
-static struct key_name_entry {
- int key; /* Special key code or ascii value */
- char_u *name; /* Name of key */
-} key_names_table[] =
-{
- {' ', (char_u *)"Space"},
- {TAB, (char_u *)"Tab"},
- {K_TAB, (char_u *)"Tab"},
- {NL, (char_u *)"NL"},
- {NL, (char_u *)"NewLine"}, /* Alternative name */
- {NL, (char_u *)"LineFeed"}, /* Alternative name */
- {NL, (char_u *)"LF"}, /* Alternative name */
- {CAR, (char_u *)"CR"},
- {CAR, (char_u *)"Return"}, /* Alternative name */
- {CAR, (char_u *)"Enter"}, /* Alternative name */
- {K_BS, (char_u *)"BS"},
- {K_BS, (char_u *)"BackSpace"}, /* Alternative name */
- {ESC, (char_u *)"Esc"},
- {CSI, (char_u *)"CSI"},
- {K_CSI, (char_u *)"xCSI"},
- {'|', (char_u *)"Bar"},
- {'\\', (char_u *)"Bslash"},
- {K_DEL, (char_u *)"Del"},
- {K_DEL, (char_u *)"Delete"}, /* Alternative name */
- {K_KDEL, (char_u *)"kDel"},
- {K_UP, (char_u *)"Up"},
- {K_DOWN, (char_u *)"Down"},
- {K_LEFT, (char_u *)"Left"},
- {K_RIGHT, (char_u *)"Right"},
- {K_XUP, (char_u *)"xUp"},
- {K_XDOWN, (char_u *)"xDown"},
- {K_XLEFT, (char_u *)"xLeft"},
- {K_XRIGHT, (char_u *)"xRight"},
-
- {K_F1, (char_u *)"F1"},
- {K_F2, (char_u *)"F2"},
- {K_F3, (char_u *)"F3"},
- {K_F4, (char_u *)"F4"},
- {K_F5, (char_u *)"F5"},
- {K_F6, (char_u *)"F6"},
- {K_F7, (char_u *)"F7"},
- {K_F8, (char_u *)"F8"},
- {K_F9, (char_u *)"F9"},
- {K_F10, (char_u *)"F10"},
-
- {K_F11, (char_u *)"F11"},
- {K_F12, (char_u *)"F12"},
- {K_F13, (char_u *)"F13"},
- {K_F14, (char_u *)"F14"},
- {K_F15, (char_u *)"F15"},
- {K_F16, (char_u *)"F16"},
- {K_F17, (char_u *)"F17"},
- {K_F18, (char_u *)"F18"},
- {K_F19, (char_u *)"F19"},
- {K_F20, (char_u *)"F20"},
-
- {K_F21, (char_u *)"F21"},
- {K_F22, (char_u *)"F22"},
- {K_F23, (char_u *)"F23"},
- {K_F24, (char_u *)"F24"},
- {K_F25, (char_u *)"F25"},
- {K_F26, (char_u *)"F26"},
- {K_F27, (char_u *)"F27"},
- {K_F28, (char_u *)"F28"},
- {K_F29, (char_u *)"F29"},
- {K_F30, (char_u *)"F30"},
-
- {K_F31, (char_u *)"F31"},
- {K_F32, (char_u *)"F32"},
- {K_F33, (char_u *)"F33"},
- {K_F34, (char_u *)"F34"},
- {K_F35, (char_u *)"F35"},
- {K_F36, (char_u *)"F36"},
- {K_F37, (char_u *)"F37"},
-
- {K_XF1, (char_u *)"xF1"},
- {K_XF2, (char_u *)"xF2"},
- {K_XF3, (char_u *)"xF3"},
- {K_XF4, (char_u *)"xF4"},
-
- {K_HELP, (char_u *)"Help"},
- {K_UNDO, (char_u *)"Undo"},
- {K_INS, (char_u *)"Insert"},
- {K_INS, (char_u *)"Ins"}, /* Alternative name */
- {K_KINS, (char_u *)"kInsert"},
- {K_HOME, (char_u *)"Home"},
- {K_KHOME, (char_u *)"kHome"},
- {K_XHOME, (char_u *)"xHome"},
- {K_ZHOME, (char_u *)"zHome"},
- {K_END, (char_u *)"End"},
- {K_KEND, (char_u *)"kEnd"},
- {K_XEND, (char_u *)"xEnd"},
- {K_ZEND, (char_u *)"zEnd"},
- {K_PAGEUP, (char_u *)"PageUp"},
- {K_PAGEDOWN, (char_u *)"PageDown"},
- {K_KPAGEUP, (char_u *)"kPageUp"},
- {K_KPAGEDOWN, (char_u *)"kPageDown"},
-
- {K_KPLUS, (char_u *)"kPlus"},
- {K_KMINUS, (char_u *)"kMinus"},
- {K_KDIVIDE, (char_u *)"kDivide"},
- {K_KMULTIPLY, (char_u *)"kMultiply"},
- {K_KENTER, (char_u *)"kEnter"},
- {K_KPOINT, (char_u *)"kPoint"},
-
- {K_K0, (char_u *)"k0"},
- {K_K1, (char_u *)"k1"},
- {K_K2, (char_u *)"k2"},
- {K_K3, (char_u *)"k3"},
- {K_K4, (char_u *)"k4"},
- {K_K5, (char_u *)"k5"},
- {K_K6, (char_u *)"k6"},
- {K_K7, (char_u *)"k7"},
- {K_K8, (char_u *)"k8"},
- {K_K9, (char_u *)"k9"},
-
- {'<', (char_u *)"lt"},
-
- {K_MOUSE, (char_u *)"Mouse"},
- {K_LEFTMOUSE, (char_u *)"LeftMouse"},
- {K_LEFTMOUSE_NM, (char_u *)"LeftMouseNM"},
- {K_LEFTDRAG, (char_u *)"LeftDrag"},
- {K_LEFTRELEASE, (char_u *)"LeftRelease"},
- {K_LEFTRELEASE_NM, (char_u *)"LeftReleaseNM"},
- {K_MIDDLEMOUSE, (char_u *)"MiddleMouse"},
- {K_MIDDLEDRAG, (char_u *)"MiddleDrag"},
- {K_MIDDLERELEASE, (char_u *)"MiddleRelease"},
- {K_RIGHTMOUSE, (char_u *)"RightMouse"},
- {K_RIGHTDRAG, (char_u *)"RightDrag"},
- {K_RIGHTRELEASE, (char_u *)"RightRelease"},
- {K_MOUSEDOWN, (char_u *)"ScrollWheelUp"},
- {K_MOUSEUP, (char_u *)"ScrollWheelDown"},
- {K_MOUSELEFT, (char_u *)"ScrollWheelRight"},
- {K_MOUSERIGHT, (char_u *)"ScrollWheelLeft"},
- {K_MOUSEDOWN, (char_u *)"MouseDown"}, /* OBSOLETE: Use */
- {K_MOUSEUP, (char_u *)"MouseUp"}, /* ScrollWheelXXX instead */
- {K_X1MOUSE, (char_u *)"X1Mouse"},
- {K_X1DRAG, (char_u *)"X1Drag"},
- {K_X1RELEASE, (char_u *)"X1Release"},
- {K_X2MOUSE, (char_u *)"X2Mouse"},
- {K_X2DRAG, (char_u *)"X2Drag"},
- {K_X2RELEASE, (char_u *)"X2Release"},
- {K_DROP, (char_u *)"Drop"},
- {K_ZERO, (char_u *)"Nul"},
- {K_SNR, (char_u *)"SNR"},
- {K_PLUG, (char_u *)"Plug"},
- {K_PASTE, (char_u *)"Paste"},
- {K_FOCUSGAINED, (char_u *)"FocusGained"},
- {K_FOCUSLOST, (char_u *)"FocusLost"},
- {0, NULL}
+static const struct key_name_entry {
+ int key; // Special key code or ascii value
+ const char *name; // Name of key
+} key_names_table[] = {
+ { ' ', "Space" },
+ { TAB, "Tab" },
+ { K_TAB, "Tab" },
+ { NL, "NL" },
+ { NL, "NewLine" }, // Alternative name
+ { NL, "LineFeed" }, // Alternative name
+ { NL, "LF" }, // Alternative name
+ { CAR, "CR" },
+ { CAR, "Return" }, // Alternative name
+ { CAR, "Enter" }, // Alternative name
+ { K_BS, "BS" },
+ { K_BS, "BackSpace" }, // Alternative name
+ { ESC, "Esc" },
+ { CSI, "CSI" },
+ { K_CSI, "xCSI" },
+ { '|', "Bar" },
+ { '\\', "Bslash" },
+ { K_DEL, "Del" },
+ { K_DEL, "Delete" }, // Alternative name
+ { K_KDEL, "kDel" },
+ { K_UP, "Up" },
+ { K_DOWN, "Down" },
+ { K_LEFT, "Left" },
+ { K_RIGHT, "Right" },
+ { K_XUP, "xUp" },
+ { K_XDOWN, "xDown" },
+ { K_XLEFT, "xLeft" },
+ { K_XRIGHT, "xRight" },
+
+ { K_F1, "F1" },
+ { K_F2, "F2" },
+ { K_F3, "F3" },
+ { K_F4, "F4" },
+ { K_F5, "F5" },
+ { K_F6, "F6" },
+ { K_F7, "F7" },
+ { K_F8, "F8" },
+ { K_F9, "F9" },
+ { K_F10, "F10" },
+
+ { K_F11, "F11" },
+ { K_F12, "F12" },
+ { K_F13, "F13" },
+ { K_F14, "F14" },
+ { K_F15, "F15" },
+ { K_F16, "F16" },
+ { K_F17, "F17" },
+ { K_F18, "F18" },
+ { K_F19, "F19" },
+ { K_F20, "F20" },
+
+ { K_F21, "F21" },
+ { K_F22, "F22" },
+ { K_F23, "F23" },
+ { K_F24, "F24" },
+ { K_F25, "F25" },
+ { K_F26, "F26" },
+ { K_F27, "F27" },
+ { K_F28, "F28" },
+ { K_F29, "F29" },
+ { K_F30, "F30" },
+
+ { K_F31, "F31" },
+ { K_F32, "F32" },
+ { K_F33, "F33" },
+ { K_F34, "F34" },
+ { K_F35, "F35" },
+ { K_F36, "F36" },
+ { K_F37, "F37" },
+
+ { K_XF1, "xF1" },
+ { K_XF2, "xF2" },
+ { K_XF3, "xF3" },
+ { K_XF4, "xF4" },
+
+ { K_HELP, "Help" },
+ { K_UNDO, "Undo" },
+ { K_INS, "Insert" },
+ { K_INS, "Ins" }, // Alternative name
+ { K_KINS, "kInsert" },
+ { K_HOME, "Home" },
+ { K_KHOME, "kHome" },
+ { K_XHOME, "xHome" },
+ { K_ZHOME, "zHome" },
+ { K_END, "End" },
+ { K_KEND, "kEnd" },
+ { K_XEND, "xEnd" },
+ { K_ZEND, "zEnd" },
+ { K_PAGEUP, "PageUp" },
+ { K_PAGEDOWN, "PageDown" },
+ { K_KPAGEUP, "kPageUp" },
+ { K_KPAGEDOWN, "kPageDown" },
+
+ { K_KPLUS, "kPlus" },
+ { K_KMINUS, "kMinus" },
+ { K_KDIVIDE, "kDivide" },
+ { K_KMULTIPLY, "kMultiply" },
+ { K_KENTER, "kEnter" },
+ { K_KPOINT, "kPoint" },
+
+ { K_K0, "k0" },
+ { K_K1, "k1" },
+ { K_K2, "k2" },
+ { K_K3, "k3" },
+ { K_K4, "k4" },
+ { K_K5, "k5" },
+ { K_K6, "k6" },
+ { K_K7, "k7" },
+ { K_K8, "k8" },
+ { K_K9, "k9" },
+
+ { '<', "lt" },
+
+ { K_MOUSE, "Mouse" },
+ { K_LEFTMOUSE, "LeftMouse" },
+ { K_LEFTMOUSE_NM, "LeftMouseNM" },
+ { K_LEFTDRAG, "LeftDrag" },
+ { K_LEFTRELEASE, "LeftRelease" },
+ { K_LEFTRELEASE_NM, "LeftReleaseNM" },
+ { K_MIDDLEMOUSE, "MiddleMouse" },
+ { K_MIDDLEDRAG, "MiddleDrag" },
+ { K_MIDDLERELEASE, "MiddleRelease" },
+ { K_RIGHTMOUSE, "RightMouse" },
+ { K_RIGHTDRAG, "RightDrag" },
+ { K_RIGHTRELEASE, "RightRelease" },
+ { K_MOUSEDOWN, "ScrollWheelUp" },
+ { K_MOUSEUP, "ScrollWheelDown" },
+ { K_MOUSELEFT, "ScrollWheelRight" },
+ { K_MOUSERIGHT, "ScrollWheelLeft" },
+ { K_MOUSEDOWN, "MouseDown" }, // OBSOLETE: Use
+ { K_MOUSEUP, "MouseUp" }, // ScrollWheelXXX instead
+ { K_X1MOUSE, "X1Mouse" },
+ { K_X1DRAG, "X1Drag" },
+ { K_X1RELEASE, "X1Release" },
+ { K_X2MOUSE, "X2Mouse" },
+ { K_X2DRAG, "X2Drag" },
+ { K_X2RELEASE, "X2Release" },
+ { K_DROP, "Drop" },
+ { K_ZERO, "Nul" },
+ { K_SNR, "SNR" },
+ { K_PLUG, "Plug" },
+ { K_PASTE, "Paste" },
+ { K_COMMAND, "Cmd" },
+ { 0, NULL }
+ // NOTE: When adding a long name update MAX_KEY_NAME_LEN.
};
static struct mousetable {
@@ -317,73 +319,73 @@ static struct mousetable {
{0, 0, 0, 0},
};
-/*
- * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
- * modifier name ('S' for Shift, 'C' for Ctrl etc).
- */
+/// Return the modifier mask bit (#MOD_MASK_*) corresponding to mod name
+///
+/// E.g. 'S' for shift, 'C' for ctrl.
int name_to_mod_mask(int c)
+ FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
- int i;
-
c = TOUPPER_ASC(c);
- for (i = 0; mod_mask_table[i].mod_mask != 0; i++)
- if (c == mod_mask_table[i].name)
+ for (size_t i = 0; mod_mask_table[i].mod_mask != 0; i++) {
+ if (c == mod_mask_table[i].name) {
return mod_mask_table[i].mod_flag;
+ }
+ }
return 0;
}
-/*
- * Check if if there is a special key code for "key" that includes the
- * modifiers specified.
- */
-int simplify_key(int key, int *modifiers)
+/// Check if there is a special key code for "key" with specified modifiers
+///
+/// @param[in] key Initial key code.
+/// @param[in,out] modifiers Initial modifiers, is adjusted to have simplified
+/// modifiers.
+///
+/// @return Simplified key code.
+int simplify_key(const int key, int *modifiers)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- int i;
- int key0;
- int key1;
-
if (*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT)) {
- /* TAB is a special case */
+ // TAB is a special case.
if (key == TAB && (*modifiers & MOD_MASK_SHIFT)) {
*modifiers &= ~MOD_MASK_SHIFT;
return K_S_TAB;
}
- key0 = KEY2TERMCAP0(key);
- key1 = KEY2TERMCAP1(key);
- for (i = 0; modifier_keys_table[i] != NUL; i += MOD_KEYS_ENTRY_SIZE)
+ const int key0 = KEY2TERMCAP0(key);
+ const int key1 = KEY2TERMCAP1(key);
+ for (int i = 0; modifier_keys_table[i] != NUL; i += MOD_KEYS_ENTRY_SIZE) {
if (key0 == modifier_keys_table[i + 3]
&& key1 == modifier_keys_table[i + 4]
&& (*modifiers & modifier_keys_table[i])) {
*modifiers &= ~modifier_keys_table[i];
return TERMCAP2KEY(modifier_keys_table[i + 1],
- modifier_keys_table[i + 2]);
+ modifier_keys_table[i + 2]);
}
+ }
}
return key;
}
-/*
- * Change <xHome> to <Home>, <xUp> to <Up>, etc.
- */
-int handle_x_keys(int key)
+/// Change <xKey> to <Key>
+int handle_x_keys(const int key)
+ FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (key) {
- case K_XUP: return K_UP;
- case K_XDOWN: return K_DOWN;
- case K_XLEFT: return K_LEFT;
- case K_XRIGHT: return K_RIGHT;
- case K_XHOME: return K_HOME;
- case K_ZHOME: return K_HOME;
- case K_XEND: return K_END;
- case K_ZEND: return K_END;
- case K_XF1: return K_F1;
- case K_XF2: return K_F2;
- case K_XF3: return K_F3;
- case K_XF4: return K_F4;
- case K_S_XF1: return K_S_F1;
- case K_S_XF2: return K_S_F2;
- case K_S_XF3: return K_S_F3;
- case K_S_XF4: return K_S_F4;
+ case K_XUP: return K_UP;
+ case K_XDOWN: return K_DOWN;
+ case K_XLEFT: return K_LEFT;
+ case K_XRIGHT: return K_RIGHT;
+ case K_XHOME: return K_HOME;
+ case K_ZHOME: return K_HOME;
+ case K_XEND: return K_END;
+ case K_ZEND: return K_END;
+ case K_XF1: return K_F1;
+ case K_XF2: return K_F2;
+ case K_XF3: return K_F3;
+ case K_XF4: return K_F4;
+ case K_S_XF1: return K_S_F1;
+ case K_S_XF2: return K_S_F2;
+ case K_S_XF3: return K_S_F3;
+ case K_S_XF4: return K_S_F4;
}
return key;
}
@@ -460,29 +462,32 @@ char_u *get_special_key_name(int c, int modifiers)
string[idx++] = '_';
string[idx++] = (char_u)KEY2TERMCAP0(c);
string[idx++] = KEY2TERMCAP1(c);
- }
- /* Not a special key, only modifiers, output directly */
- else {
- if (has_mbyte && (*mb_char2len)(c) > 1)
- idx += (*mb_char2bytes)(c, string + idx);
- else if (vim_isprintc(c))
+ } else {
+ // Not a special key, only modifiers, output directly.
+ if (utf_char2len(c) > 1) {
+ idx += utf_char2bytes(c, string + idx);
+ } else if (vim_isprintc(c)) {
string[idx++] = (char_u)c;
- else {
+ } else {
s = transchar(c);
while (*s)
string[idx++] = *s++;
}
}
- } else { /* use name of special key */
- STRCPY(string + idx, key_names_table[table_idx].name);
- idx = (int)STRLEN(string);
+ } else { // use name of special key
+ size_t len = STRLEN(key_names_table[table_idx].name);
+
+ if ((int)len + idx + 2 <= MAX_KEY_NAME_LEN) {
+ STRCPY(string + idx, key_names_table[table_idx].name);
+ idx += (int)len;
+ }
}
string[idx++] = '>';
string[idx] = NUL;
return string;
}
-/// Try translating a <> name
+/// Try translating a <> name ("keycode").
///
/// @param[in,out] srcp Source from which <> are translated. Is advanced to
/// after the <> name if there is a match.
@@ -490,22 +495,24 @@ char_u *get_special_key_name(int c, int modifiers)
/// @param[out] dst Location where translation result will be kept. Must have
/// at least six bytes.
/// @param[in] keycode Prefer key code, e.g. K_DEL in place of DEL.
+/// @param[in] in_string Inside a double quoted string
///
/// @return Number of characters added to dst, zero for no match.
unsigned int trans_special(const char_u **srcp, const size_t src_len,
- char_u *const dst, const bool keycode)
+ char_u *const dst, const bool keycode,
+ const bool in_string)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
int modifiers = 0;
int key;
unsigned int dlen = 0;
- key = find_special_key(srcp, src_len, &modifiers, keycode, false);
+ key = find_special_key(srcp, src_len, &modifiers, keycode, false, in_string);
if (key == 0) {
return 0;
}
- /* Put the appropriate modifier in a string */
+ // Put the appropriate modifier in a string.
if (modifiers != 0) {
dst[dlen++] = K_SPECIAL;
dst[dlen++] = KS_MODIFIER;
@@ -516,14 +523,12 @@ unsigned int trans_special(const char_u **srcp, const size_t src_len,
dst[dlen++] = K_SPECIAL;
dst[dlen++] = (char_u)KEY2TERMCAP0(key);
dst[dlen++] = KEY2TERMCAP1(key);
- } else if (has_mbyte && !keycode) {
- dlen += (unsigned int)(*mb_char2bytes)(key, dst + dlen);
- } else if (keycode) {
+ } else if (!keycode) {
+ dlen += (unsigned int)utf_char2bytes(key, dst + dlen);
+ } else {
char_u *after = add_char2buf(key, dst + dlen);
assert(after >= dst && (uintmax_t)(after - dst) <= UINT_MAX);
dlen = (unsigned int)(after - dst);
- } else {
- dst[dlen++] = (char_u)key;
}
return dlen;
@@ -536,10 +541,12 @@ unsigned int trans_special(const char_u **srcp, const size_t src_len,
/// @param[out] modp Location where information about modifiers is saved.
/// @param[in] keycode Prefer key code, e.g. K_DEL in place of DEL.
/// @param[in] keep_x_key Don’t translate xHome to Home key.
+/// @param[in] in_string In string, double quote is escaped
///
/// @return Key and modifiers or 0 if there is no match.
int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
- const bool keycode, const bool keep_x_key)
+ const bool keycode, const bool keep_x_key,
+ const bool in_string)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
const char_u *last_dash;
@@ -550,7 +557,7 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
int modifiers;
int bit;
int key;
- unsigned long n;
+ uvarnumber_T n;
int l;
if (src_len == 0) {
@@ -564,17 +571,19 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
// Find end of modifier list
last_dash = src;
- for (bp = src + 1; bp <= end && (*bp == '-' || vim_isIDc(*bp)); bp++) {
+ for (bp = src + 1; bp <= end && (*bp == '-' || ascii_isident(*bp)); bp++) {
if (*bp == '-') {
last_dash = bp;
if (bp + 1 <= end) {
- if (has_mbyte) {
- l = mb_ptr2len_len(bp + 1, (int) (end - bp) + 1);
- } else {
- l = 1;
- }
- if (end - bp > l && bp[l + 1] == '>') {
- bp += l; // anything accepted, like <C-?>
+ l = utfc_ptr2len_len(bp + 1, (int)(end - bp) + 1);
+ // Anything accepted, like <C-?>.
+ // <C-"> or <M-"> are not special in strings as " is
+ // the string delimiter. With a backslash it works: <M-\">
+ if (end - bp > l && !(in_string && bp[1] == '"') && bp[2] == '>') {
+ bp += l;
+ } else if (end - bp > 2 && in_string && bp[1] == '\\'
+ && bp[2] == '"' && bp[3] == '>') {
+ bp += 2;
}
}
}
@@ -610,18 +619,19 @@ int find_special_key(const char_u **srcp, const size_t src_len, int *const modp,
vim_str2nr(last_dash + 6, NULL, NULL, STR2NR_ALL, NULL, &n, 0);
key = (int)n;
} else {
- /*
- * Modifier with single letter, or special key name.
- */
- if (has_mbyte) {
- l = mb_ptr2len(last_dash + 1);
+ int off = 1;
+
+ // Modifier with single letter, or special key name.
+ if (in_string && last_dash[1] == '\\' && last_dash[2] == '"') {
+ // Special case for a double-quoted string
+ off = l = 2;
} else {
- l = 1;
+ l = mb_ptr2len(last_dash + 1);
}
if (modifiers != 0 && last_dash[l + 1] == '>') {
- key = PTR2CHAR(last_dash + 1);
+ key = PTR2CHAR(last_dash + off);
} else {
- key = get_special_key_code(last_dash + 1);
+ key = get_special_key_code(last_dash + off);
if (!keep_x_key) {
key = handle_x_keys(key);
}
@@ -692,33 +702,39 @@ int find_special_key_in_table(int c)
{
int i;
- for (i = 0; key_names_table[i].name != NULL; i++)
- if (c == key_names_table[i].key)
+ for (i = 0; key_names_table[i].name != NULL; i++) {
+ if (c == key_names_table[i].key) {
break;
- if (key_names_table[i].name == NULL)
+ }
+ }
+ if (key_names_table[i].name == NULL) {
i = -1;
+ }
return i;
}
-/*
- * Find the special key with the given name (the given string does not have to
- * end with NUL, the name is assumed to end before the first non-idchar).
- * If the name starts with "t_" the next two characters are interpreted as a
- * termcap name.
- * Return the key code, or 0 if not found.
- */
+/// Find the special key with the given name
+///
+/// @param[in] name Name of the special. Does not have to end with NUL, it is
+/// assumed to end before the first non-idchar. If name starts
+/// with "t_" the next two characters are interpreted as
+/// a termcap name.
+///
+/// @return Key code or 0 if not found.
int get_special_key_code(const char_u *name)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- char_u *table_name;
- int i, j;
-
- for (i = 0; key_names_table[i].name != NULL; i++) {
- table_name = key_names_table[i].name;
- for (j = 0; vim_isIDc(name[j]) && table_name[j] != NUL; j++)
- if (TOLOWER_ASC(table_name[j]) != TOLOWER_ASC(name[j]))
+ for (int i = 0; key_names_table[i].name != NULL; i++) {
+ const char *const table_name = key_names_table[i].name;
+ int j;
+ for (j = 0; ascii_isident(name[j]) && table_name[j] != NUL; j++) {
+ if (TOLOWER_ASC(table_name[j]) != TOLOWER_ASC(name[j])) {
break;
- if (!vim_isIDc(name[j]) && table_name[j] == NUL)
+ }
+ }
+ if (!ascii_isident(name[j]) && table_name[j] == NUL) {
return key_names_table[i].key;
+ }
}
return 0;
@@ -744,9 +760,9 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
/// Replace any terminal code strings with the equivalent internal
/// representation
///
-/// This is used for the "from" and "to" part of a mapping, and the "to" part of
+/// Used for the "from" and "to" part of a mapping, and the "to" part of
/// a menu command. Any strings like "<C-UP>" are also replaced, unless
-/// 'cpoptions' contains '<'. K_SPECIAL by itself is replaced by K_SPECIAL
+/// `special` is false. K_SPECIAL by itself is replaced by K_SPECIAL
/// KS_SPECIAL KE_FILLER.
///
/// @param[in] from What characters to replace.
@@ -759,7 +775,7 @@ int get_mouse_button(int code, bool *is_click, bool *is_drag)
/// When cpo_flags contains #FLAG_CPO_BSLASH, a backslash
/// can be used in place of <C-v>. All other <C-v>
/// characters are removed.
-/// @param[in] special If true, always accept <key> notation.
+/// @param[in] special Replace keycodes, e.g. <CR> becomes a "\n" char.
/// @param[in] cpo_flags Relevant flags derived from p_cpo, see
/// #CPO_TO_CPO_FLAGS.
///
@@ -778,11 +794,9 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
const char_u *src;
const char_u *const end = from + from_len - 1;
int do_backslash; // backslash is a special character
- int do_special; // recognize <> key codes
char_u *result; // buffer for resulting string
do_backslash = !(cpo_flags&FLAG_CPO_BSLASH);
- do_special = !(cpo_flags&FLAG_CPO_SPECI) || special;
// Allocate space for the translation. Worst case a single character is
// replaced by 6 bytes (shifted special key), plus a NUL at the end.
@@ -805,10 +819,9 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
// Copy each byte from *from to result[dlen]
while (src <= end) {
- // If 'cpoptions' does not contain '<', check for special key codes,
- // like "<C-S-LeftMouse>"
- if (do_special && (do_lt || ((end - src) >= 3
- && STRNCMP(src, "<lt>", 4) != 0))) {
+ // Check for special <> keycodes, like "<C-S-LeftMouse>"
+ if (special && (do_lt || ((end - src) >= 3
+ && STRNCMP(src, "<lt>", 4) != 0))) {
// Replace <SID> by K_SNR <script-nr> _.
// (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
if (end - src >= 4 && STRNICMP(src, "<SID>", 5) == 0) {
@@ -826,14 +839,15 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
}
}
- slen = trans_special(&src, (size_t) (end - src) + 1, result + dlen, true);
+ slen = trans_special(&src, (size_t)(end - src) + 1, result + dlen, true,
+ false);
if (slen) {
dlen += slen;
continue;
}
}
- if (do_special) {
+ if (special) {
char_u *p, *s, len;
// Replace <Leader> by the value of "mapleader".
@@ -841,10 +855,10 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
// If "mapleader" or "maplocalleader" isn't set use a backslash.
if (end - src >= 7 && STRNICMP(src, "<Leader>", 8) == 0) {
len = 8;
- p = get_var_value((char_u *)"g:mapleader");
+ p = get_var_value("g:mapleader");
} else if (end - src >= 12 && STRNICMP(src, "<LocalLeader>", 13) == 0) {
len = 13;
- p = get_var_value((char_u *)"g:maplocalleader");
+ p = get_var_value("g:maplocalleader");
} else {
len = 0;
p = NULL;
@@ -881,7 +895,7 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len,
}
// skip multibyte char correctly
- for (i = (*mb_ptr2len_len)(src, (int) (end - src) + 1); i > 0; i--) {
+ for (i = utfc_ptr2len_len(src, (int)(end - src) + 1); i > 0; i--) {
// If the character is K_SPECIAL, replace it with K_SPECIAL
// KS_SPECIAL KE_FILLER.
// If compiled with the GUI replace CSI with K_CSI.
diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h
index bb8ba84a6a..baf8963aa8 100644
--- a/src/nvim/keymap.h
+++ b/src/nvim/keymap.h
@@ -115,134 +115,139 @@
KS_ZERO ? K_ZERO : TERMCAP2KEY(a, b))
// Codes for keys that do not have a termcap name.
+// The numbers are fixed to make sure that recorded key sequences remain valid.
+// Add new entries at the end, not halfway.
//
// K_SPECIAL KS_EXTRA KE_xxx
//
// Entries must be in the range 0x02-0x7f (see comment at K_SPECIAL).
enum key_extra {
- KE_NAME = 3 /* name of this terminal entry */
-
- , KE_S_UP /* shift-up */
- , KE_S_DOWN /* shift-down */
-
- , KE_S_F1 /* shifted function keys */
- , KE_S_F2
- , KE_S_F3
- , KE_S_F4
- , KE_S_F5
- , KE_S_F6
- , KE_S_F7
- , KE_S_F8
- , KE_S_F9
- , KE_S_F10
-
- , KE_S_F11
- , KE_S_F12
- , KE_S_F13
- , KE_S_F14
- , KE_S_F15
- , KE_S_F16
- , KE_S_F17
- , KE_S_F18
- , KE_S_F19
- , KE_S_F20
-
- , KE_S_F21
- , KE_S_F22
- , KE_S_F23
- , KE_S_F24
- , KE_S_F25
- , KE_S_F26
- , KE_S_F27
- , KE_S_F28
- , KE_S_F29
- , KE_S_F30
-
- , KE_S_F31
- , KE_S_F32
- , KE_S_F33
- , KE_S_F34
- , KE_S_F35
- , KE_S_F36
- , KE_S_F37
-
- , KE_MOUSE /* mouse event start */
-
- /*
- * Symbols for pseudo keys which are translated from the real key symbols
- * above.
- */
- , KE_LEFTMOUSE /* Left mouse button click */
- , KE_LEFTDRAG /* Drag with left mouse button down */
- , KE_LEFTRELEASE /* Left mouse button release */
- , KE_MIDDLEMOUSE /* Middle mouse button click */
- , KE_MIDDLEDRAG /* Drag with middle mouse button down */
- , KE_MIDDLERELEASE /* Middle mouse button release */
- , KE_RIGHTMOUSE /* Right mouse button click */
- , KE_RIGHTDRAG /* Drag with right mouse button down */
- , KE_RIGHTRELEASE /* Right mouse button release */
-
- , KE_IGNORE /* Ignored mouse drag/release */
-
- , KE_TAB /* unshifted TAB key */
- , KE_S_TAB_OLD /* shifted TAB key (no longer used) */
-
- , KE_XF1 /* extra vt100 function keys for xterm */
- , KE_XF2
- , KE_XF3
- , KE_XF4
- , KE_XEND /* extra (vt100) end key for xterm */
- , KE_ZEND /* extra (vt100) end key for xterm */
- , KE_XHOME /* extra (vt100) home key for xterm */
- , KE_ZHOME /* extra (vt100) home key for xterm */
- , KE_XUP /* extra vt100 cursor keys for xterm */
- , KE_XDOWN
- , KE_XLEFT
- , KE_XRIGHT
-
- , KE_LEFTMOUSE_NM /* non-mappable Left mouse button click */
- , KE_LEFTRELEASE_NM /* non-mappable left mouse button release */
-
- , KE_S_XF1 /* extra vt100 shifted function keys for xterm */
- , KE_S_XF2
- , KE_S_XF3
- , KE_S_XF4
-
- /* NOTE: The scroll wheel events are inverted: i.e. UP is the same as
- * moving the actual scroll wheel down, LEFT is the same as moving the
- * scroll wheel right. */
- , KE_MOUSEDOWN /* scroll wheel pseudo-button Down */
- , KE_MOUSEUP /* scroll wheel pseudo-button Up */
- , KE_MOUSELEFT /* scroll wheel pseudo-button Left */
- , KE_MOUSERIGHT /* scroll wheel pseudo-button Right */
-
- , KE_KINS /* keypad Insert key */
- , KE_KDEL /* keypad Delete key */
-
- , KE_CSI /* CSI typed directly */
- , KE_SNR /* <SNR> */
- , KE_PLUG /* <Plug> */
- , KE_CMDWIN /* open command-line window from Command-line Mode */
-
- , KE_C_LEFT /* control-left */
- , KE_C_RIGHT /* control-right */
- , KE_C_HOME /* control-home */
- , KE_C_END /* control-end */
-
- , KE_X1MOUSE /* X1/X2 mouse-buttons */
- , KE_X1DRAG
- , KE_X1RELEASE
- , KE_X2MOUSE
- , KE_X2DRAG
- , KE_X2RELEASE
-
- , KE_DROP /* DnD data is available */
- , KE_NOP /* doesn't do something */
- , KE_FOCUSGAINED /* focus gained */
- , KE_FOCUSLOST /* focus lost */
- , KE_EVENT // event
- , KE_PASTE // special key to toggle the 'paste' option.
- // sent only by UIs
+ KE_NAME = 3 // name of this terminal entry
+
+ , KE_S_UP = 4 // shift-up
+ , KE_S_DOWN = 5 // shift-down
+
+ , KE_S_F1 = 6 // shifted function keys
+ , KE_S_F2 = 7
+ , KE_S_F3 = 8
+ , KE_S_F4 = 9
+ , KE_S_F5 = 10
+ , KE_S_F6 = 11
+ , KE_S_F7 = 12
+ , KE_S_F8 = 13
+ , KE_S_F9 = 14
+ , KE_S_F10 = 15
+
+ , KE_S_F11 = 16
+ , KE_S_F12 = 17
+ , KE_S_F13 = 18
+ , KE_S_F14 = 19
+ , KE_S_F15 = 20
+ , KE_S_F16 = 21
+ , KE_S_F17 = 22
+ , KE_S_F18 = 23
+ , KE_S_F19 = 24
+ , KE_S_F20 = 25
+
+ , KE_S_F21 = 26
+ , KE_S_F22 = 27
+ , KE_S_F23 = 28
+ , KE_S_F24 = 29
+ , KE_S_F25 = 30
+ , KE_S_F26 = 31
+ , KE_S_F27 = 32
+ , KE_S_F28 = 33
+ , KE_S_F29 = 34
+ , KE_S_F30 = 35
+
+ , KE_S_F31 = 36
+ , KE_S_F32 = 37
+ , KE_S_F33 = 38
+ , KE_S_F34 = 39
+ , KE_S_F35 = 40
+ , KE_S_F36 = 41
+ , KE_S_F37 = 42
+
+ , KE_MOUSE = 43 // mouse event start
+
+ // Symbols for pseudo keys which are translated from the real key symbols
+ // above.
+ , KE_LEFTMOUSE = 44 // Left mouse button click
+ , KE_LEFTDRAG = 45 // Drag with left mouse button down
+ , KE_LEFTRELEASE = 46 // Left mouse button release
+ , KE_MIDDLEMOUSE = 47 // Middle mouse button click
+ , KE_MIDDLEDRAG = 48 // Drag with middle mouse button down
+ , KE_MIDDLERELEASE = 49 // Middle mouse button release
+ , KE_RIGHTMOUSE = 50 // Right mouse button click
+ , KE_RIGHTDRAG = 51 // Drag with right mouse button down
+ , KE_RIGHTRELEASE = 52 // Right mouse button release
+
+ , KE_IGNORE = 53 // Ignored mouse drag/release
+
+ , KE_TAB = 54 // unshifted TAB key
+ , KE_S_TAB_OLD = 55 // shifted TAB key (no longer used)
+
+ // , KE_SNIFF_UNUSED = 56 // obsolete
+ , KE_XF1 = 57 // extra vt100 function keys for xterm
+ , KE_XF2 = 58
+ , KE_XF3 = 59
+ , KE_XF4 = 60
+ , KE_XEND = 61 // extra (vt100) end key for xterm
+ , KE_ZEND = 62 // extra (vt100) end key for xterm
+ , KE_XHOME = 63 // extra (vt100) home key for xterm
+ , KE_ZHOME = 64 // extra (vt100) home key for xterm
+ , KE_XUP = 65 // extra vt100 cursor keys for xterm
+ , KE_XDOWN = 66
+ , KE_XLEFT = 67
+ , KE_XRIGHT = 68
+
+ , KE_LEFTMOUSE_NM = 69 // non-mappable Left mouse button click
+ , KE_LEFTRELEASE_NM = 70 // non-mappable left mouse button release
+
+ , KE_S_XF1 = 71 // vt100 shifted function keys for xterm
+ , KE_S_XF2 = 72
+ , KE_S_XF3 = 73
+ , KE_S_XF4 = 74
+
+ // NOTE: The scroll wheel events are inverted: i.e. UP is the same as
+ // moving the actual scroll wheel down, LEFT is the same as moving the
+ // scroll wheel right.
+ , KE_MOUSEDOWN = 75 // scroll wheel pseudo-button Down
+ , KE_MOUSEUP = 76 // scroll wheel pseudo-button Up
+ , KE_MOUSELEFT = 77 // scroll wheel pseudo-button Left
+ , KE_MOUSERIGHT = 78 // scroll wheel pseudo-button Right
+
+ , KE_KINS = 79 // keypad Insert key
+ , KE_KDEL = 80 // keypad Delete key
+
+ , KE_CSI = 81 // CSI typed directly
+ , KE_SNR = 82 // <SNR>
+ , KE_PLUG = 83 // <Plug>
+ , KE_CMDWIN = 84 // open command-line window from Command-line Mode
+
+ , KE_C_LEFT = 85 // control-left
+ , KE_C_RIGHT = 86 // control-right
+ , KE_C_HOME = 87 // control-home
+ , KE_C_END = 88 // control-end
+
+ , KE_X1MOUSE = 89 // X1/X2 mouse-buttons
+ , KE_X1DRAG = 90
+ , KE_X1RELEASE = 91
+ , KE_X2MOUSE = 92
+ , KE_X2DRAG = 93
+ , KE_X2RELEASE = 94
+
+ , KE_DROP = 95 // DnD data is available
+ // , KE_CURSORHOLD = 96 // CursorHold event
+ , KE_NOP = 97 // doesn't do something
+ , KE_FOCUSGAINED = 98 // focus gained
+ , KE_FOCUSLOST = 99 // focus lost
+ // , KE_MOUSEMOVE = 100 // mouse moved with no button down
+ // , KE_CANCEL = 101 // return from vgetc
+ , KE_EVENT = 102 // event
+ , KE_PASTE = 103 // special key to toggle the 'paste' option.
+ // sent only by UIs
+ , KE_COMMAND = 104 // <Cmd> special key
};
/*
@@ -428,11 +433,10 @@ enum key_extra {
#define K_CMDWIN TERMCAP2KEY(KS_EXTRA, KE_CMDWIN)
#define K_DROP TERMCAP2KEY(KS_EXTRA, KE_DROP)
-#define K_FOCUSGAINED TERMCAP2KEY(KS_EXTRA, KE_FOCUSGAINED)
-#define K_FOCUSLOST TERMCAP2KEY(KS_EXTRA, KE_FOCUSLOST)
#define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT)
#define K_PASTE TERMCAP2KEY(KS_EXTRA, KE_PASTE)
+#define K_COMMAND TERMCAP2KEY(KS_EXTRA, KE_COMMAND)
/* Bits for modifier mask */
/* 0x01 cannot be used, because the modifier must be 0x02 or higher */
@@ -443,16 +447,17 @@ enum key_extra {
#define MOD_MASK_2CLICK 0x20 // use MOD_MASK_MULTI_CLICK
#define MOD_MASK_3CLICK 0x40 // use MOD_MASK_MULTI_CLICK
#define MOD_MASK_4CLICK 0x60 // use MOD_MASK_MULTI_CLICK
-#define MOD_MASK_CMD 0x80 // "super" key (OSX/Mac: command-key)
+#define MOD_MASK_CMD 0x80 // "super" key (macOS: command-key)
#define MOD_MASK_MULTI_CLICK (MOD_MASK_2CLICK|MOD_MASK_3CLICK| \
MOD_MASK_4CLICK)
/*
* The length of the longest special key name, including modifiers.
- * Current longest is <M-C-S-T-4-MiddleRelease> (length includes '<' and '>').
+ * Current longest is <M-C-S-T-D-A-4-ScrollWheelRight> (length includes '<' and
+ * '>').
*/
-#define MAX_KEY_NAME_LEN 25
+#define MAX_KEY_NAME_LEN 32
// Maximum length of a special key event as tokens. This includes modifiers.
// The longest event is something like <M-C-S-T-4-LeftDrag> which would be the
@@ -464,13 +469,9 @@ enum key_extra {
#define MAX_KEY_CODE_LEN 6
#define FLAG_CPO_BSLASH 0x01
-#define FLAG_CPO_SPECI 0x02
-#define CPO_TO_CPO_FLAGS (((vim_strchr(p_cpo, CPO_BSLASH) == NULL) \
- ? 0 \
- : FLAG_CPO_BSLASH)| \
- (vim_strchr(p_cpo, CPO_SPECI) == NULL \
- ? 0 \
- : FLAG_CPO_SPECI))
+#define CPO_TO_CPO_FLAGS ((vim_strchr(p_cpo, CPO_BSLASH) == NULL) \
+ ? 0 \
+ : FLAG_CPO_BSLASH)
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "keymap.h.generated.h"
diff --git a/src/nvim/lib/kbtree.h b/src/nvim/lib/kbtree.h
new file mode 100644
index 0000000000..e2688064a8
--- /dev/null
+++ b/src/nvim/lib/kbtree.h
@@ -0,0 +1,431 @@
+/*-
+ * Copyright 1997-1999, 2001, John-Mark Gurney.
+ * 2008-2009, Attractive Chaos <attractor@live.co.uk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef NVIM_LIB_KBTREE_H
+#define NVIM_LIB_KBTREE_H
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "nvim/memory.h"
+
+#define KB_MAX_DEPTH 64
+
+#define __KB_KEY(type, x) (x->key)
+#define __KB_PTR(btr, x) (x->ptr)
+
+#define __KB_TREE_T(name,key_t,T) \
+ typedef struct kbnode_##name##_s kbnode_##name##_t; \
+ struct kbnode_##name##_s { \
+ int32_t n; \
+ bool is_internal; \
+ key_t key[2*T-1]; \
+ kbnode_##name##_t *ptr[]; \
+ } ; \
+ \
+ typedef struct { \
+ kbnode_##name##_t *root; \
+ int n_keys, n_nodes; \
+ } kbtree_##name##_t; \
+ \
+ typedef struct { \
+ kbnode_##name##_t *x; \
+ int i; \
+ } kbpos_##name##_t; \
+ typedef struct { \
+ kbpos_##name##_t stack[KB_MAX_DEPTH], *p; \
+ } kbitr_##name##_t; \
+
+
+#define __kb_destroy(kbnode_t,b) do { \
+ int i; \
+ unsigned int max = 8; \
+ kbnode_t *x, **top, **stack = 0; \
+ if (b->root) { \
+ top = stack = (kbnode_t**)xcalloc(max, sizeof(kbnode_t*)); \
+ *top++ = (b)->root; \
+ while (top != stack) { \
+ x = *--top; \
+ if (x->is_internal == 0) { xfree(x); continue; } \
+ for (i = 0; i <= x->n; ++i) \
+ if (__KB_PTR(b, x)[i]) { \
+ if (top - stack == (int)max) { \
+ max <<= 1; \
+ stack = (kbnode_t**)xrealloc(stack, max * sizeof(kbnode_t*)); \
+ top = stack + (max>>1); \
+ } \
+ *top++ = __KB_PTR(b, x)[i]; \
+ } \
+ xfree(x); \
+ } \
+ } \
+ xfree(stack); \
+ } while (0)
+
+#define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
+ static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, key_t * __restrict k, int *r) \
+ { \
+ int tr, *rr, begin = 0, end = x->n; \
+ if (x->n == 0) return -1; \
+ rr = r? r : &tr; \
+ while (begin < end) { \
+ int mid = (begin + end) >> 1; \
+ if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \
+ else end = mid; \
+ } \
+ if (begin == x->n) { *rr = 1; return x->n - 1; } \
+ if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \
+ return begin; \
+ }
+
+#define __KB_GET(name, key_t, kbnode_t) \
+ static key_t *kb_getp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ if (!b->root) { \
+ return 0; \
+ } \
+ int i, r = 0; \
+ kbnode_t *x = b->root; \
+ while (x) { \
+ i = __kb_getp_aux_##name(x, k, &r); \
+ if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \
+ if (x->is_internal == 0) return 0; \
+ x = __KB_PTR(b, x)[i + 1]; \
+ } \
+ return 0; \
+ } \
+ static inline key_t *kb_get_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ return kb_getp_##name(b, &k); \
+ }
+
+#define __KB_INTERVAL(name, key_t, kbnode_t) \
+ static inline void kb_intervalp_##name(kbtree_##name##_t *b, key_t * __restrict k, key_t **lower, key_t **upper) \
+ { \
+ if (!b->root) { \
+ return; \
+ } \
+ int i, r = 0; \
+ kbnode_t *x = b->root; \
+ *lower = *upper = 0; \
+ while (x) { \
+ i = __kb_getp_aux_##name(x, k, &r); \
+ if (i >= 0 && r == 0) { \
+ *lower = *upper = &__KB_KEY(key_t, x)[i]; \
+ return; \
+ } \
+ if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \
+ if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \
+ if (x->is_internal == 0) return; \
+ x = __KB_PTR(b, x)[i + 1]; \
+ } \
+ } \
+ static inline void kb_interval_##name(kbtree_##name##_t *b, key_t k, key_t **lower, key_t **upper) \
+ { \
+ kb_intervalp_##name(b, &k, lower, upper); \
+ }
+
+#define __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ /* x must be an internal node */ \
+ static inline void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \
+ { \
+ kbnode_t *z; \
+ z = (kbnode_t*)xcalloc(1, y->is_internal? ILEN : sizeof(kbnode_##name##_t)); \
+ ++b->n_nodes; \
+ z->is_internal = y->is_internal; \
+ z->n = T - 1; \
+ memcpy(__KB_KEY(key_t, z), &__KB_KEY(key_t, y)[T], sizeof(key_t) * (T - 1)); \
+ if (y->is_internal) memcpy(__KB_PTR(b, z), &__KB_PTR(b, y)[T], sizeof(void*) * T); \
+ y->n = T - 1; \
+ memmove(&__KB_PTR(b, x)[i + 2], &__KB_PTR(b, x)[i + 1], sizeof(void*) * (unsigned int)(x->n - i)); \
+ __KB_PTR(b, x)[i + 1] = z; \
+ memmove(&__KB_KEY(key_t, x)[i + 1], &__KB_KEY(key_t, x)[i], sizeof(key_t) * (unsigned int)(x->n - i)); \
+ __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[T - 1]; \
+ ++x->n; \
+ } \
+ static inline key_t *__kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k) \
+ { \
+ int i = x->n - 1; \
+ key_t *ret; \
+ if (x->is_internal == 0) { \
+ i = __kb_getp_aux_##name(x, k, 0); \
+ if (i != x->n - 1) \
+ memmove(&__KB_KEY(key_t, x)[i + 2], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ ret = &__KB_KEY(key_t, x)[i + 1]; \
+ *ret = *k; \
+ ++x->n; \
+ } else { \
+ i = __kb_getp_aux_##name(x, k, 0) + 1; \
+ if (__KB_PTR(b, x)[i]->n == 2 * T - 1) { \
+ __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \
+ if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \
+ } \
+ ret = __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \
+ } \
+ return ret; \
+ } \
+ static inline key_t *kb_putp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ if (!b->root) { \
+ b->root = (kbnode_t*)xcalloc(1, ILEN); \
+ ++b->n_nodes; \
+ } \
+ kbnode_t *r, *s; \
+ ++b->n_keys; \
+ r = b->root; \
+ if (r->n == 2 * T - 1) { \
+ ++b->n_nodes; \
+ s = (kbnode_t*)xcalloc(1, ILEN); \
+ b->root = s; s->is_internal = 1; s->n = 0; \
+ __KB_PTR(b, s)[0] = r; \
+ __kb_split_##name(b, s, 0, r); \
+ r = s; \
+ } \
+ return __kb_putp_aux_##name(b, r, k); \
+ } \
+ static inline void kb_put_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ kb_putp_##name(b, &k); \
+ }
+
+
+#define __KB_DEL(name, key_t, kbnode_t, T) \
+ static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, int s) \
+ { \
+ int yn, zn, i, r = 0; \
+ kbnode_t *xp, *y, *z; \
+ key_t kp; \
+ if (x == 0) return *k; \
+ if (s) { /* s can only be 0, 1 or 2 */ \
+ r = x->is_internal == 0? 0 : s == 1? 1 : -1; \
+ i = s == 1? x->n - 1 : -1; \
+ } else i = __kb_getp_aux_##name(x, k, &r); \
+ if (x->is_internal == 0) { \
+ if (s == 2) ++i; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ --x->n; \
+ return kp; \
+ } \
+ if (r == 0) { \
+ if ((yn = __KB_PTR(b, x)[i]->n) >= T) { \
+ xp = __KB_PTR(b, x)[i]; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \
+ return kp; \
+ } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= T) { \
+ xp = __KB_PTR(b, x)[i + 1]; \
+ kp = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \
+ return kp; \
+ } else if (yn == T - 1 && zn == T - 1) { \
+ y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \
+ __KB_KEY(key_t, y)[y->n++] = *k; \
+ memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, z), (unsigned int)z->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, z), (unsigned int)(z->n + 1) * sizeof(void*)); \
+ y->n += z->n; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
+ --x->n; \
+ xfree(z); \
+ return __kb_delp_aux_##name(b, y, k, s); \
+ } \
+ } \
+ ++i; \
+ if ((xp = __KB_PTR(b, x)[i])->n == T - 1) { \
+ if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= T) { \
+ memmove(&__KB_KEY(key_t, xp)[1], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
+ if (xp->is_internal) memmove(&__KB_PTR(b, xp)[1], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \
+ __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \
+ __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \
+ if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \
+ --y->n; ++xp->n; \
+ } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= T) { \
+ __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
+ __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \
+ if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \
+ --y->n; \
+ memmove(__KB_KEY(key_t, y), &__KB_KEY(key_t, y)[1], (unsigned int)y->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(__KB_PTR(b, y), &__KB_PTR(b, y)[1], (unsigned int)(y->n + 1) * sizeof(void*)); \
+ } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == T - 1) { \
+ __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \
+ memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
+ if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \
+ y->n += xp->n; \
+ memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, x)[i], (unsigned int)(x->n - i) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, x)[i + 1], (unsigned int)(x->n - i) * sizeof(void*)); \
+ --x->n; \
+ xfree(xp); \
+ xp = y; \
+ } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \
+ __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
+ memmove(&__KB_KEY(key_t, xp)[xp->n], __KB_KEY(key_t, y), (unsigned int)y->n * sizeof(key_t)); \
+ if (xp->is_internal) memmove(&__KB_PTR(b, xp)[xp->n], __KB_PTR(b, y), (unsigned int)(y->n + 1) * sizeof(void*)); \
+ xp->n += y->n; \
+ memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
+ memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
+ --x->n; \
+ xfree(y); \
+ } \
+ } \
+ return __kb_delp_aux_##name(b, xp, k, s); \
+ } \
+ static inline key_t kb_delp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
+ { \
+ kbnode_t *x; \
+ key_t ret; \
+ ret = __kb_delp_aux_##name(b, b->root, k, 0); \
+ --b->n_keys; \
+ if (b->root->n == 0 && b->root->is_internal) { \
+ --b->n_nodes; \
+ x = b->root; \
+ b->root = __KB_PTR(b, x)[0]; \
+ xfree(x); \
+ } \
+ return ret; \
+ } \
+ static inline key_t kb_del_##name(kbtree_##name##_t *b, key_t k) \
+ { \
+ return kb_delp_##name(b, &k); \
+ }
+
+#define __KB_ITR(name, key_t, kbnode_t) \
+ static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ itr->p = 0; \
+ if (b->n_keys == 0) return; \
+ itr->p = itr->stack; \
+ itr->p->x = b->root; itr->p->i = 0; \
+ while (itr->p->x->is_internal && __KB_PTR(b, itr->p->x)[0] != 0) { \
+ kbnode_t *x = itr->p->x; \
+ ++itr->p; \
+ itr->p->x = __KB_PTR(b, x)[0]; itr->p->i = 0; \
+ } \
+ } \
+ static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ if (itr->p < itr->stack) return 0; \
+ for (;;) { \
+ ++itr->p->i; \
+ while (itr->p->x && itr->p->i <= itr->p->x->n) { \
+ itr->p[1].i = 0; \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
+ ++itr->p; \
+ } \
+ --itr->p; \
+ if (itr->p < itr->stack) return 0; \
+ if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \
+ } \
+ } \
+ static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ if (itr->p < itr->stack) return 0; \
+ for (;;) { \
+ while (itr->p->x && itr->p->i >= 0) { \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
+ itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \
+ ++itr->p; \
+ } \
+ --itr->p; \
+ if (itr->p < itr->stack) return 0; \
+ --itr->p->i; \
+ if (itr->p->x && itr->p->i >= 0) return 1; \
+ } \
+ } \
+ static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, kbitr_##name##_t *itr) \
+ { \
+ if (b->n_keys == 0) { \
+ itr->p = NULL; \
+ return 0; \
+ } \
+ int i, r = 0; \
+ itr->p = itr->stack; \
+ itr->p->x = b->root; \
+ while (itr->p->x) { \
+ i = __kb_getp_aux_##name(itr->p->x, k, &r); \
+ itr->p->i = i; \
+ if (i >= 0 && r == 0) return 1; \
+ ++itr->p->i; \
+ itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \
+ ++itr->p; \
+ } \
+ return 0; \
+ } \
+ static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \
+ { \
+ return kb_itr_getp_##name(b,&k,itr); \
+ } \
+ static inline void kb_del_itr_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
+ { \
+ key_t k = kb_itr_key(itr); \
+ kb_delp_##name(b, &k); \
+ kb_itr_getp_##name(b, &k, itr); \
+ }
+
+#define KBTREE_INIT(name, key_t, __cmp, T) \
+ KBTREE_INIT_IMPL(name, key_t, kbnode_##name##_t, __cmp, T, (sizeof(kbnode_##name##_t)+(2*T)*sizeof(void *)))
+
+#define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ __KB_TREE_T(name, key_t, T) \
+ __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
+ __KB_GET(name, key_t, kbnode_t) \
+ __KB_INTERVAL(name, key_t, kbnode_t) \
+ __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
+ __KB_DEL(name, key_t, kbnode_t, T) \
+ __KB_ITR(name, key_t, kbnode_t)
+
+#define KB_DEFAULT_SIZE 512
+
+#define kbtree_t(name) kbtree_##name##_t
+#define kbitr_t(name) kbitr_##name##_t
+#define kb_init(b) ((b)->n_keys = (b)->n_nodes = 0, (b)->root = 0)
+#define kb_destroy(name, b) __kb_destroy(kbnode_##name##_t, b)
+#define kb_get(name, b, k) kb_get_##name(b, k)
+#define kb_put(name, b, k) kb_put_##name(b, k)
+#define kb_del(name, b, k) kb_del_##name(b, k)
+#define kb_interval(name, b, k, l, u) kb_interval_##name(b, k, l, u)
+#define kb_getp(name, b, k) kb_getp_##name(b, k)
+#define kb_putp(name, b, k) kb_putp_##name(b, k)
+#define kb_delp(name, b, k) kb_delp_##name(b, k)
+#define kb_intervalp(name, b, k, l, u) kb_intervalp_##name(b, k, l, u)
+
+#define kb_itr_first(name, b, i) kb_itr_first_##name(b, i)
+#define kb_itr_get(name, b, k, i) kb_itr_get_##name(b, k, i)
+#define kb_itr_getp(name, b, k, i) kb_itr_getp_##name(b, k, i)
+#define kb_itr_next(name, b, i) kb_itr_next_##name(b, i)
+#define kb_itr_prev(name, b, i) kb_itr_prev_##name(b, i)
+#define kb_del_itr(name, b, i) kb_del_itr_##name(b, i)
+#define kb_itr_key(itr) __KB_KEY(dummy, (itr)->p->x)[(itr)->p->i]
+#define kb_itr_valid(itr) ((itr)->p >= (itr)->stack)
+
+#define kb_size(b) ((b)->n_keys)
+
+#define kb_generic_cmp(a, b) (((b) < (a)) - ((a) < (b)))
+#define kb_str_cmp(a, b) strcmp(a, b)
+
+#endif // NVIM_LIB_KBTREE_H
diff --git a/src/nvim/lib/kvec.h b/src/nvim/lib/kvec.h
index 584282d773..93b2f053bc 100644
--- a/src/nvim/lib/kvec.h
+++ b/src/nvim/lib/kvec.h
@@ -41,6 +41,7 @@
#include <string.h>
#include "nvim/memory.h"
+#include "nvim/os/os_defs.h"
#define kv_roundup32(x) \
((--(x)), \
@@ -62,7 +63,16 @@
#define kv_pop(v) ((v).items[--(v).size])
#define kv_size(v) ((v).size)
#define kv_max(v) ((v).capacity)
-#define kv_last(v) kv_A(v, kv_size(v) - 1)
+#define kv_Z(v, i) kv_A(v, kv_size(v) - (i) - 1)
+#define kv_last(v) kv_Z(v, 0)
+
+/// Drop last n items from kvec without resizing
+///
+/// Previously spelled as `(void)kv_pop(v)`, repeated n times.
+///
+/// @param[out] v Kvec to drop items from.
+/// @param[in] n Number of elements to drop.
+#define kv_drop(v, n) ((v).size -= (n))
#define kv_resize(v, s) \
((v).capacity = (s), \
@@ -88,14 +98,14 @@
(*kv_pushp(v) = (x))
#define kv_a(v, i) \
- (((v).capacity <= (size_t) (i) \
+ (*(((v).capacity <= (size_t) (i) \
? ((v).capacity = (v).size = (i) + 1, \
kv_roundup32((v).capacity), \
- kv_resize((v), (v).capacity), 0) \
+ kv_resize((v), (v).capacity), 0UL) \
: ((v).size <= (size_t) (i) \
? (v).size = (i) + 1 \
- : 0)), \
- (v).items[(i)])
+ : 0UL)), \
+ &(v).items[(i)]))
/// Type of a vector with a few first members allocated on stack
///
@@ -132,6 +142,8 @@ static inline void *_memcpy_free(void *const restrict dest,
return dest;
}
+// -V:kvi_push:512
+
/// Resize vector with preallocated array
///
/// @note May not resize to an array smaller then init_array: if requested,
diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h
index 9fcedf298f..ab9270081e 100644
--- a/src/nvim/lib/queue.h
+++ b/src/nvim/lib/queue.h
@@ -1,3 +1,8 @@
+// Queue implemented by circularly-linked list.
+//
+// Adapted from libuv. Simpler and more efficient than klist.h for implementing
+// queues that support arbitrary insertion/removal.
+//
// Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
//
// Permission to use, copy, modify, and/or distribute this software for any
@@ -28,6 +33,8 @@ typedef struct _queue {
#define QUEUE_DATA(ptr, type, field) \
((type *)((char *)(ptr) - offsetof(type, field)))
+// Important note: mutating the list while QUEUE_FOREACH is
+// iterating over its elements results in undefined behavior.
#define QUEUE_FOREACH(q, h) \
for ( /* NOLINT(readability/braces) */ \
(q) = (h)->next; (q) != (h); (q) = (q)->next)
@@ -56,17 +63,6 @@ static inline void QUEUE_ADD(QUEUE *const h, QUEUE *const n)
h->prev->next = h;
}
-static inline void QUEUE_SPLIT(QUEUE *const h, QUEUE *const q, QUEUE *const n)
- FUNC_ATTR_ALWAYS_INLINE
-{
- n->prev = h->prev;
- n->prev->next = n;
- n->next = q;
- h->prev = q->prev;
- h->prev->next = h;
- q->prev = n;
-}
-
static inline void QUEUE_INSERT_HEAD(QUEUE *const h, QUEUE *const q)
FUNC_ATTR_ALWAYS_INLINE
{
diff --git a/src/nvim/lib/ringbuf.h b/src/nvim/lib/ringbuf.h
index 12b75ec65a..e63eae70b0 100644
--- a/src/nvim/lib/ringbuf.h
+++ b/src/nvim/lib/ringbuf.h
@@ -15,6 +15,7 @@
#ifndef NVIM_LIB_RINGBUF_H
#define NVIM_LIB_RINGBUF_H
+#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
@@ -73,6 +74,32 @@ typedef struct { \
RBType *buf_end; \
} TypeName##RingBuffer;
+/// Dummy item free macros, for use in RINGBUF_INIT
+///
+/// This macros actually does nothing.
+///
+/// @param[in] item Item to be freed.
+#define RINGBUF_DUMMY_FREE(item)
+
+/// Static ring buffer
+///
+/// @warning Ring buffers created with this macros must neither be freed nor
+/// deallocated.
+///
+/// @param scope Ring buffer scope.
+/// @param TypeName Ring buffer type name.
+/// @param RBType Type of the single ring buffer element.
+/// @param varname Variable name.
+/// @param rbsize Ring buffer size.
+#define RINGBUF_STATIC(scope, TypeName, RBType, varname, rbsize) \
+static RBType _##varname##_buf[rbsize]; \
+scope TypeName##RingBuffer varname = { \
+ .buf = _##varname##_buf, \
+ .next = _##varname##_buf, \
+ .first = NULL, \
+ .buf_end = _##varname##_buf + rbsize - 1, \
+};
+
/// Initialize a new ring buffer
///
/// @param TypeName Ring buffer type name. Actual type name will be
diff --git a/src/nvim/log.c b/src/nvim/log.c
index c31af6b287..4d912c452b 100644
--- a/src/nvim/log.c
+++ b/src/nvim/log.c
@@ -1,23 +1,26 @@
+// 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 <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
+#if !defined(WIN32)
+# include <sys/time.h> // for gettimeofday()
+#endif
+#include <uv.h>
#include "nvim/log.h"
#include "nvim/types.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
-/// First location of the log file used by log_path_init()
-#define USR_LOG_FILE "$NVIM_LOG_FILE"
-
-/// Fall back location of the log file used by log_path_init()
-#define USR_LOG_FILE_2 "$HOME" _PATHSEPSTR ".nvimlog"
+#define LOG_FILE_ENV "NVIM_LOG_FILE"
-/// Cached location of the log file set by log_path_init()
-static char expanded_log_file_path[MAXPATHL + 1] = { 0 };
+/// Cached location of the expanded log file path decided by log_path_init().
+static char log_file_path[MAXPATHL + 1] = { 0 };
static uv_mutex_t mutex;
@@ -25,31 +28,57 @@ static uv_mutex_t mutex;
# include "log.c.generated.h"
#endif
-/// Initialize path to log file
+#ifdef HAVE_EXECINFO_BACKTRACE
+# include <execinfo.h>
+#endif
+
+static bool log_try_create(char *fname)
+{
+ if (fname == NULL || fname[0] == '\0') {
+ return false;
+ }
+ FILE *log_file = fopen(fname, "a");
+ if (log_file == NULL) {
+ return false;
+ }
+ fclose(log_file);
+ return true;
+}
+
+/// Initializes path to log file. Sets $NVIM_LOG_FILE if empty.
///
-/// Tries to use #USR_LOG_FILE, then falls back #USR_LOG_FILE_2. Path to log
+/// Tries $NVIM_LOG_FILE, or falls back to $XDG_DATA_HOME/nvim/log. Path to log
/// file is cached, so only the first call has effect, unless first call was not
-/// successful. To make initialization not succeed either a bug in expand_env()
-/// is needed or both `$NVIM_LOG_FILE` and `$HOME` environment variables
-/// undefined.
+/// successful. Failed initialization indicates either a bug in expand_env()
+/// or both $NVIM_LOG_FILE and $HOME environment variables are undefined.
///
/// @return true if path was initialized, false otherwise.
static bool log_path_init(void)
{
- if (expanded_log_file_path[0]) {
+ if (log_file_path[0]) {
return true;
}
- expand_env((char_u *)USR_LOG_FILE, (char_u *)expanded_log_file_path,
- sizeof(expanded_log_file_path) - 1);
- // if the log file path expansion failed then fall back to stderr
- if (strcmp(USR_LOG_FILE, expanded_log_file_path) == 0) {
- memset(expanded_log_file_path, 0, sizeof(expanded_log_file_path));
- expand_env((char_u *)USR_LOG_FILE_2, (char_u *)expanded_log_file_path,
- sizeof(expanded_log_file_path) - 1);
- if (strcmp(USR_LOG_FILE_2, expanded_log_file_path) == 0) {
- memset(expanded_log_file_path, 0, sizeof(expanded_log_file_path));
+ size_t size = sizeof(log_file_path);
+ expand_env((char_u *)"$" LOG_FILE_ENV, (char_u *)log_file_path,
+ (int)size - 1);
+ if (strequal("$" LOG_FILE_ENV, log_file_path)
+ || log_file_path[0] == '\0'
+ || os_isdir((char_u *)log_file_path)
+ || !log_try_create(log_file_path)) {
+ // Invalid $NVIM_LOG_FILE or failed to expand; fall back to default.
+ char *defaultpath = stdpaths_user_data_subpath("log", 0, true);
+ size_t len = xstrlcpy(log_file_path, defaultpath, size);
+ xfree(defaultpath);
+ // Fall back to .nvimlog
+ if (len >= size || !log_try_create(log_file_path)) {
+ len = xstrlcpy(log_file_path, ".nvimlog", size);
+ }
+ // Fall back to stderr
+ if (len >= size || !log_try_create(log_file_path)) {
+ log_file_path[0] = '\0';
return false;
}
+ os_setenv(LOG_FILE_ENV, log_file_path, true);
}
return true;
}
@@ -69,9 +98,23 @@ void log_unlock(void)
uv_mutex_unlock(&mutex);
}
-bool do_log(int log_level, const char *func_name, int line_num, bool eol,
- const char* fmt, ...) FUNC_ATTR_UNUSED
+/// @param context description of a shared context or subsystem
+/// @param func_name function name, or NULL
+/// @param line_num source line number, or -1
+bool logmsg(int log_level, const char *context, const char *func_name,
+ int line_num, bool eol, const char *fmt, ...)
+ FUNC_ATTR_UNUSED FUNC_ATTR_PRINTF(6, 7)
{
+ if (log_level < MIN_LOG_LEVEL) {
+ return false;
+ }
+
+#ifdef EXITFREE
+ // Logging after we've already started freeing all our memory will only cause
+ // pain. We need access to VV_PROGPATH, homedir, etc.
+ assert(!entered_free_all_mem);
+#endif
+
log_lock();
bool ret = false;
FILE *log_file = open_log_file();
@@ -82,8 +125,8 @@ bool do_log(int log_level, const char *func_name, int line_num, bool eol,
va_list args;
va_start(args, fmt);
- ret = v_do_log_to_file(log_file, log_level, func_name, line_num, eol,
- fmt, args);
+ ret = v_do_log_to_file(log_file, log_level, context, func_name, line_num,
+ eol, fmt, args);
va_end(args);
if (log_file != stderr && log_file != stdout) {
@@ -94,26 +137,42 @@ end:
return ret;
}
+void log_uv_handles(void *loop)
+{
+ uv_loop_t *l = loop;
+ log_lock();
+ FILE *log_file = open_log_file();
+
+ if (log_file == NULL) {
+ goto end;
+ }
+
+ uv_print_all_handles(l, log_file);
+
+ if (log_file != stderr && log_file != stdout) {
+ fclose(log_file);
+ }
+end:
+ log_unlock();
+}
+
/// Open the log file for appending.
///
-/// @return The FILE* specified by the USR_LOG_FILE path or stderr in case of
-/// error
+/// @return FILE* decided by log_path_init() or stderr in case of error
FILE *open_log_file(void)
{
static bool opening_log_file = false;
-
// check if it's a recursive call
if (opening_log_file) {
- do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, true,
- "Trying to LOG() recursively! Please fix it.");
+ do_log_to_file(stderr, ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true,
+ "Cannot LOG() recursively.");
return stderr;
}
- // expand USR_LOG_FILE if needed and open the file
FILE *log_file = NULL;
opening_log_file = true;
if (log_path_init()) {
- log_file = fopen(expanded_log_file_path, "a");
+ log_file = fopen(log_file_path, "a");
}
opening_log_file = false;
@@ -121,53 +180,126 @@ FILE *open_log_file(void)
return log_file;
}
- do_log_to_file(stderr, ERROR_LOG_LEVEL, __func__, __LINE__, true,
- "Couldn't open USR_LOG_FILE, logging to stderr! This may be "
- "caused by attempting to LOG() before initialization "
- "functions are called (e.g. init_homedir()).");
+ // May happen if:
+ // - LOG() is called before early_init()
+ // - Directory does not exist
+ // - File is not writable
+ do_log_to_file(stderr, ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true,
+ "Logging to stderr, failed to open $" LOG_FILE_ENV ": %s",
+ log_file_path);
return stderr;
}
-static bool do_log_to_file(FILE *log_file, int log_level,
+#ifdef HAVE_EXECINFO_BACKTRACE
+void log_callstack_to_file(FILE *log_file, const char *const func_name,
+ const int line_num)
+{
+ void *trace[100];
+ int trace_size = backtrace(trace, ARRAY_SIZE(trace));
+
+ char exepath[MAXPATHL] = { 0 };
+ size_t exepathlen = MAXPATHL;
+ if (os_exepath(exepath, &exepathlen) != 0) {
+ abort();
+ }
+ assert(24 + exepathlen < IOSIZE); // Must fit in `cmdbuf` below.
+
+ char cmdbuf[IOSIZE + (20 * ARRAY_SIZE(trace)) + MAXPATHL];
+ snprintf(cmdbuf, sizeof(cmdbuf), "addr2line -e %s -f -p", exepath);
+ for (int i = 1; i < trace_size; i++) {
+ char buf[20]; // 64-bit pointer 0xNNNNNNNNNNNNNNNN with leading space.
+ snprintf(buf, sizeof(buf), " %p", trace[i]);
+ xstrlcat(cmdbuf, buf, sizeof(cmdbuf));
+ }
+ // Now we have a command string like:
+ // addr2line -e /path/to/exe -f -p 0x123 0x456 ...
+
+ do_log_to_file(log_file, DEBUG_LOG_LEVEL, NULL, func_name, line_num, true,
+ "trace:");
+ FILE *fp = popen(cmdbuf, "r");
+ char linebuf[IOSIZE];
+ while (fgets(linebuf, sizeof(linebuf) - 1, fp) != NULL) {
+ fprintf(log_file, " %s", linebuf);
+ }
+ pclose(fp);
+
+ if (log_file != stderr && log_file != stdout) {
+ fclose(log_file);
+ }
+}
+
+void log_callstack(const char *const func_name, const int line_num)
+{
+ log_lock();
+ FILE *log_file = open_log_file();
+ if (log_file == NULL) {
+ goto end;
+ }
+
+ log_callstack_to_file(log_file, func_name, line_num);
+
+end:
+ log_unlock();
+}
+#endif
+
+static bool do_log_to_file(FILE *log_file, int log_level, const char *context,
const char *func_name, int line_num, bool eol,
- const char* fmt, ...)
+ const char *fmt, ...)
+ FUNC_ATTR_PRINTF(7, 8)
{
va_list args;
va_start(args, fmt);
- bool ret = v_do_log_to_file(log_file, log_level, func_name, line_num, eol,
- fmt, args);
+ bool ret = v_do_log_to_file(log_file, log_level, context, func_name,
+ line_num, eol, fmt, args);
va_end(args);
return ret;
}
static bool v_do_log_to_file(FILE *log_file, int log_level,
- const char *func_name, int line_num, bool eol,
- const char* fmt, va_list args)
+ const char *context, const char *func_name,
+ int line_num, bool eol, const char *fmt,
+ va_list args)
{
static const char *log_levels[] = {
- [DEBUG_LOG_LEVEL] = "debug",
- [INFO_LOG_LEVEL] = "info",
- [WARNING_LOG_LEVEL] = "warning",
- [ERROR_LOG_LEVEL] = "error"
+ [DEBUG_LOG_LEVEL] = "DEBUG",
+ [INFO_LOG_LEVEL] = "INFO ",
+ [WARN_LOG_LEVEL] = "WARN ",
+ [ERROR_LOG_LEVEL] = "ERROR",
};
assert(log_level >= DEBUG_LOG_LEVEL && log_level <= ERROR_LOG_LEVEL);
- // format current timestamp in local time
+ // Format the timestamp.
struct tm local_time;
- if (os_get_localtime(&local_time) == NULL) {
+ if (os_localtime(&local_time) == NULL) {
return false;
}
char date_time[20];
- if (strftime(date_time, sizeof(date_time), "%Y/%m/%d %H:%M:%S",
+ if (strftime(date_time, sizeof(date_time), "%Y-%m-%dT%H:%M:%S",
&local_time) == 0) {
return false;
}
- // print the log message prefixed by the current timestamp and pid
+ int millis = 0;
+#if !defined(WIN32)
+ struct timeval curtime;
+ if (gettimeofday(&curtime, NULL) == 0) {
+ millis = (int)curtime.tv_usec / 1000;
+ }
+#endif
+
+ // Print the log message.
int64_t pid = os_get_pid();
- if (fprintf(log_file, "%s [%s @ %s:%d] %" PRId64 " - ", date_time,
- log_levels[log_level], func_name, line_num, pid) < 0) {
+ int rv = (line_num == -1 || func_name == NULL)
+ ? fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s",
+ log_levels[log_level], date_time, millis, pid,
+ (context == NULL ? "?:" : context))
+ : fprintf(log_file, "%s %s.%03d %-5" PRId64 " %s%s:%d: ",
+ log_levels[log_level], date_time, millis, pid,
+ (context == NULL ? "" : context),
+ func_name, line_num);
+ if (rv < 0) {
return false;
}
if (vfprintf(log_file, fmt, args) < 0) {
diff --git a/src/nvim/log.h b/src/nvim/log.h
index 32b7276f14..7d4c033565 100644
--- a/src/nvim/log.h
+++ b/src/nvim/log.h
@@ -6,7 +6,7 @@
#define DEBUG_LOG_LEVEL 0
#define INFO_LOG_LEVEL 1
-#define WARNING_LOG_LEVEL 2
+#define WARN_LOG_LEVEL 2
#define ERROR_LOG_LEVEL 3
#define DLOG(...)
@@ -18,55 +18,52 @@
#define ELOG(...)
#define ELOGN(...)
-// Logging is disabled if NDEBUG or DISABLE_LOG is defined.
-#if !defined(DISABLE_LOG) && defined(NDEBUG)
-# define DISABLE_LOG
-#endif
-
-// MIN_LOG_LEVEL can be defined during compilation to adjust the desired level
-// of logging. INFO_LOG_LEVEL is used by default.
#ifndef MIN_LOG_LEVEL
# define MIN_LOG_LEVEL INFO_LOG_LEVEL
#endif
-#ifndef DISABLE_LOG
+#define LOG(level, ...) logmsg((level), NULL, __func__, __LINE__, true, \
+ __VA_ARGS__)
-# if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
-# undef DLOG
-# undef DLOGN
-# define DLOG(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, true, \
- __VA_ARGS__)
-# define DLOGN(...) do_log(DEBUG_LOG_LEVEL, __func__, __LINE__, false, \
- __VA_ARGS__)
-# endif
+#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
+# undef DLOG
+# undef DLOGN
+# define DLOG(...) logmsg(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, true, \
+ __VA_ARGS__)
+# define DLOGN(...) logmsg(DEBUG_LOG_LEVEL, NULL, __func__, __LINE__, false, \
+ __VA_ARGS__)
+#endif
-# if MIN_LOG_LEVEL <= INFO_LOG_LEVEL
-# undef ILOG
-# undef ILOGN
-# define ILOG(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, true, \
- __VA_ARGS__)
-# define ILOGN(...) do_log(INFO_LOG_LEVEL, __func__, __LINE__, false, \
- __VA_ARGS__)
-# endif
+#if MIN_LOG_LEVEL <= INFO_LOG_LEVEL
+# undef ILOG
+# undef ILOGN
+# define ILOG(...) logmsg(INFO_LOG_LEVEL, NULL, __func__, __LINE__, true, \
+ __VA_ARGS__)
+# define ILOGN(...) logmsg(INFO_LOG_LEVEL, NULL, __func__, __LINE__, false, \
+ __VA_ARGS__)
+#endif
-# if MIN_LOG_LEVEL <= WARNING_LOG_LEVEL
-# undef WLOG
-# undef WLOGN
-# define WLOG(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, true, \
- __VA_ARGS__)
-# define WLOGN(...) do_log(WARNING_LOG_LEVEL, __func__, __LINE__, false, \
- __VA_ARGS__)
-# endif
+#if MIN_LOG_LEVEL <= WARN_LOG_LEVEL
+# undef WLOG
+# undef WLOGN
+# define WLOG(...) logmsg(WARN_LOG_LEVEL, NULL, __func__, __LINE__, true, \
+ __VA_ARGS__)
+# define WLOGN(...) logmsg(WARN_LOG_LEVEL, NULL, __func__, __LINE__, false, \
+ __VA_ARGS__)
+#endif
-# if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL
-# undef ELOG
-# undef ELOGN
-# define ELOG(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, true, \
- __VA_ARGS__)
-# define ELOGN(...) do_log(ERROR_LOG_LEVEL, __func__, __LINE__, false, \
- __VA_ARGS__)
-# endif
+#if MIN_LOG_LEVEL <= ERROR_LOG_LEVEL
+# undef ELOG
+# undef ELOGN
+# define ELOG(...) logmsg(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, true, \
+ __VA_ARGS__)
+# define ELOGN(...) logmsg(ERROR_LOG_LEVEL, NULL, __func__, __LINE__, false, \
+ __VA_ARGS__)
+#endif
+#ifdef HAVE_EXECINFO_BACKTRACE
+# define LOG_CALLSTACK() log_callstack(__func__, __LINE__)
+# define LOG_CALLSTACK_TO_FILE(fp) log_callstack_to_file(fp, __func__, __LINE__)
#endif
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
new file mode 100644
index 0000000000..5da6d2c0a0
--- /dev/null
+++ b/src/nvim/lua/converter.c
@@ -0,0 +1,1206 @@
+// 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 <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#include <assert.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/func_attr.h"
+#include "nvim/memory.h"
+#include "nvim/assert.h"
+// FIXME: vim.h is not actually needed, but otherwise it states MAXPATHL is
+// redefined
+#include "nvim/vim.h"
+#include "nvim/globals.h"
+#include "nvim/message.h"
+#include "nvim/eval/typval.h"
+#include "nvim/ascii.h"
+#include "nvim/macros.h"
+
+#include "nvim/lib/kvec.h"
+#include "nvim/eval/decode.h"
+
+#include "nvim/lua/converter.h"
+#include "nvim/lua/executor.h"
+
+/// Determine, which keys lua table contains
+typedef struct {
+ size_t maxidx; ///< Maximum positive integral value found.
+ size_t string_keys_num; ///< Number of string keys.
+ bool has_string_with_nul; ///< True if there is string key with NUL byte.
+ ObjectType type; ///< If has_type_key is true then attached value. Otherwise
+ ///< either kObjectTypeNil, kObjectTypeDictionary or
+ ///< kObjectTypeArray, depending on other properties.
+ lua_Number val; ///< If has_val_key and val_type == LUA_TNUMBER: value.
+ bool has_type_key; ///< True if type key is present.
+} LuaTableProps;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/converter.c.generated.h"
+#endif
+
+#define TYPE_IDX_VALUE true
+#define VAL_IDX_VALUE false
+
+#define LUA_PUSH_STATIC_STRING(lstate, s) \
+ lua_pushlstring(lstate, s, sizeof(s) - 1)
+
+static LuaTableProps nlua_traverse_table(lua_State *const lstate)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ size_t tsize = 0; // Total number of keys.
+ int val_type = 0; // If has_val_key: lua type of the value.
+ bool has_val_key = false; // True if val key was found,
+ // @see nlua_push_val_idx().
+ size_t other_keys_num = 0; // Number of keys that are not string, integral
+ // or type keys.
+ LuaTableProps ret;
+ memset(&ret, 0, sizeof(ret));
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
+ emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 2);
+ ret.type = kObjectTypeNil;
+ return ret;
+ }
+ lua_pushnil(lstate);
+ while (lua_next(lstate, -2)) {
+ switch (lua_type(lstate, -2)) {
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -2, &len);
+ if (memchr(s, NUL, len) != NULL) {
+ ret.has_string_with_nul = true;
+ }
+ ret.string_keys_num++;
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -2);
+ if (n > (lua_Number)SIZE_MAX || n <= 0
+ || ((lua_Number)((size_t)n)) != n) {
+ other_keys_num++;
+ } else {
+ const size_t idx = (size_t)n;
+ if (idx > ret.maxidx) {
+ ret.maxidx = idx;
+ }
+ }
+ break;
+ }
+ case LUA_TBOOLEAN: {
+ const bool b = lua_toboolean(lstate, -2);
+ if (b == TYPE_IDX_VALUE) {
+ if (lua_type(lstate, -1) == LUA_TNUMBER) {
+ lua_Number n = lua_tonumber(lstate, -1);
+ if (n == (lua_Number)kObjectTypeFloat
+ || n == (lua_Number)kObjectTypeArray
+ || n == (lua_Number)kObjectTypeDictionary) {
+ ret.has_type_key = true;
+ ret.type = (ObjectType)n;
+ } else {
+ other_keys_num++;
+ }
+ } else {
+ other_keys_num++;
+ }
+ } else {
+ has_val_key = true;
+ val_type = lua_type(lstate, -1);
+ if (val_type == LUA_TNUMBER) {
+ ret.val = lua_tonumber(lstate, -1);
+ }
+ }
+ break;
+ }
+ default: {
+ other_keys_num++;
+ break;
+ }
+ }
+ tsize++;
+ lua_pop(lstate, 1);
+ }
+ if (ret.has_type_key) {
+ if (ret.type == kObjectTypeFloat
+ && (!has_val_key || val_type != LUA_TNUMBER)) {
+ ret.type = kObjectTypeNil;
+ } else if (ret.type == kObjectTypeArray) {
+ // Determine what is the last number in a *sequence* of keys.
+ // This condition makes sure that Neovim will not crash when it gets table
+ // {[vim.type_idx]=vim.types.array, [SIZE_MAX]=1}: without it maxidx will
+ // be SIZE_MAX, with this condition it should be zero and [SIZE_MAX] key
+ // should be ignored.
+ if (ret.maxidx != 0
+ && ret.maxidx != (tsize
+ - ret.has_type_key
+ - other_keys_num
+ - has_val_key
+ - ret.string_keys_num)) {
+ for (ret.maxidx = 0;; ret.maxidx++) {
+ lua_rawgeti(lstate, -1, (int)ret.maxidx + 1);
+ if (lua_isnil(lstate, -1)) {
+ lua_pop(lstate, 1);
+ break;
+ }
+ lua_pop(lstate, 1);
+ }
+ }
+ }
+ } else {
+ if (tsize == 0
+ || (tsize == ret.maxidx
+ && other_keys_num == 0
+ && ret.string_keys_num == 0)) {
+ ret.type = kObjectTypeArray;
+ } else if (ret.string_keys_num == tsize) {
+ ret.type = kObjectTypeDictionary;
+ } else {
+ ret.type = kObjectTypeNil;
+ }
+ }
+ return ret;
+}
+
+/// Helper structure for nlua_pop_typval
+typedef struct {
+ typval_T *tv; ///< Location where conversion result is saved.
+ bool container; ///< True if tv is a container.
+ bool special; ///< If true then tv is a _VAL part of special dictionary
+ ///< that represents mapping.
+ int idx; ///< Container index (used to detect self-referencing structures).
+} TVPopStackItem;
+
+/// Convert lua object to VimL typval_T
+///
+/// Should pop exactly one value from lua stack.
+///
+/// @param lstate Lua state.
+/// @param[out] ret_tv Where to put the result.
+///
+/// @return `true` in case of success, `false` in case of failure. Error is
+/// reported automatically.
+bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
+{
+ bool ret = true;
+ const int initial_size = lua_gettop(lstate);
+ kvec_t(TVPopStackItem) stack = KV_INITIAL_VALUE;
+ kv_push(stack, ((TVPopStackItem) { ret_tv, false, false, 0 }));
+ while (ret && kv_size(stack)) {
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
+ emsgf(_("E1502: Lua failed to grow stack to %i"), lua_gettop(lstate) + 3);
+ ret = false;
+ break;
+ }
+ TVPopStackItem cur = kv_pop(stack);
+ if (cur.container) {
+ if (cur.special || cur.tv->v_type == VAR_DICT) {
+ assert(cur.tv->v_type == (cur.special ? VAR_LIST : VAR_DICT));
+ bool next_key_found = false;
+ while (lua_next(lstate, -2)) {
+ if (lua_type(lstate, -2) == LUA_TSTRING) {
+ next_key_found = true;
+ break;
+ }
+ lua_pop(lstate, 1);
+ }
+ if (next_key_found) {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -2, &len);
+ if (cur.special) {
+ list_T *const kv_pair = tv_list_alloc(2);
+
+ typval_T s_tv = decode_string(s, len, kTrue, false, false);
+ if (s_tv.v_type == VAR_UNKNOWN) {
+ ret = false;
+ tv_list_unref(kv_pair);
+ continue;
+ }
+ tv_list_append_owned_tv(kv_pair, s_tv);
+
+ // Value: not populated yet, need to create list item to push.
+ tv_list_append_owned_tv(kv_pair, (typval_T) {
+ .v_type = VAR_UNKNOWN,
+ });
+ kv_push(stack, cur);
+ tv_list_append_list(cur.tv->vval.v_list, kv_pair);
+ cur = (TVPopStackItem) {
+ .tv = TV_LIST_ITEM_TV(tv_list_last(kv_pair)),
+ .container = false,
+ .special = false,
+ .idx = 0,
+ };
+ } else {
+ dictitem_T *const di = tv_dict_item_alloc_len(s, len);
+ if (tv_dict_add(cur.tv->vval.v_dict, di) == FAIL) {
+ assert(false);
+ }
+ kv_push(stack, cur);
+ cur = (TVPopStackItem) { &di->di_tv, false, false, 0 };
+ }
+ } else {
+ lua_pop(lstate, 1);
+ continue;
+ }
+ } else {
+ assert(cur.tv->v_type == VAR_LIST);
+ lua_rawgeti(lstate, -1, tv_list_len(cur.tv->vval.v_list) + 1);
+ if (lua_isnil(lstate, -1)) {
+ lua_pop(lstate, 2);
+ continue;
+ }
+ // Not populated yet, need to create list item to push.
+ tv_list_append_owned_tv(cur.tv->vval.v_list, (typval_T) {
+ .v_type = VAR_UNKNOWN,
+ });
+ kv_push(stack, cur);
+ // TODO(ZyX-I): Use indexes, here list item *will* be reallocated.
+ cur = (TVPopStackItem) {
+ .tv = TV_LIST_ITEM_TV(tv_list_last(cur.tv->vval.v_list)),
+ .container = false,
+ .special = false,
+ .idx = 0,
+ };
+ }
+ }
+ assert(!cur.container);
+ *cur.tv = (typval_T) {
+ .v_type = VAR_NUMBER,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_number = 0 },
+ };
+ switch (lua_type(lstate, -1)) {
+ case LUA_TNIL: {
+ cur.tv->v_type = VAR_SPECIAL;
+ cur.tv->vval.v_special = kSpecialVarNull;
+ break;
+ }
+ case LUA_TBOOLEAN: {
+ cur.tv->v_type = VAR_SPECIAL;
+ cur.tv->vval.v_special = (lua_toboolean(lstate, -1)
+ ? kSpecialVarTrue
+ : kSpecialVarFalse);
+ break;
+ }
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -1, &len);
+ *cur.tv = decode_string(s, len, kNone, true, false);
+ if (cur.tv->v_type == VAR_UNKNOWN) {
+ ret = false;
+ }
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -1);
+ if (n > (lua_Number)VARNUMBER_MAX || n < (lua_Number)VARNUMBER_MIN
+ || ((lua_Number)((varnumber_T)n)) != n) {
+ cur.tv->v_type = VAR_FLOAT;
+ cur.tv->vval.v_float = (float_T)n;
+ } else {
+ cur.tv->v_type = VAR_NUMBER;
+ cur.tv->vval.v_number = (varnumber_T)n;
+ }
+ break;
+ }
+ case LUA_TTABLE: {
+ const LuaTableProps table_props = nlua_traverse_table(lstate);
+
+ for (size_t i = 0; i < kv_size(stack); i++) {
+ const TVPopStackItem item = kv_A(stack, i);
+ if (item.container && lua_rawequal(lstate, -1, item.idx)) {
+ tv_copy(item.tv, cur.tv);
+ cur.container = false;
+ goto nlua_pop_typval_table_processing_end;
+ }
+ }
+
+ switch (table_props.type) {
+ case kObjectTypeArray: {
+ cur.tv->v_type = VAR_LIST;
+ cur.tv->vval.v_list = tv_list_alloc((ptrdiff_t)table_props.maxidx);
+ tv_list_ref(cur.tv->vval.v_list);
+ if (table_props.maxidx != 0) {
+ cur.container = true;
+ cur.idx = lua_gettop(lstate);
+ kv_push(stack, cur);
+ }
+ break;
+ }
+ case kObjectTypeDictionary: {
+ if (table_props.string_keys_num == 0) {
+ cur.tv->v_type = VAR_DICT;
+ cur.tv->vval.v_dict = tv_dict_alloc();
+ cur.tv->vval.v_dict->dv_refcount++;
+ } else {
+ cur.special = table_props.has_string_with_nul;
+ if (table_props.has_string_with_nul) {
+ decode_create_map_special_dict(
+ cur.tv, (ptrdiff_t)table_props.string_keys_num);
+ assert(cur.tv->v_type == VAR_DICT);
+ dictitem_T *const val_di = tv_dict_find(cur.tv->vval.v_dict,
+ S_LEN("_VAL"));
+ assert(val_di != NULL);
+ cur.tv = &val_di->di_tv;
+ assert(cur.tv->v_type == VAR_LIST);
+ } else {
+ cur.tv->v_type = VAR_DICT;
+ cur.tv->vval.v_dict = tv_dict_alloc();
+ cur.tv->vval.v_dict->dv_refcount++;
+ }
+ cur.container = true;
+ cur.idx = lua_gettop(lstate);
+ kv_push(stack, cur);
+ lua_pushnil(lstate);
+ }
+ break;
+ }
+ case kObjectTypeFloat: {
+ cur.tv->v_type = VAR_FLOAT;
+ cur.tv->vval.v_float = (float_T)table_props.val;
+ break;
+ }
+ case kObjectTypeNil: {
+ EMSG(_("E5100: Cannot convert given lua table: table "
+ "should either have a sequence of positive integer keys "
+ "or contain only string keys"));
+ ret = false;
+ break;
+ }
+ default: {
+ assert(false);
+ }
+ }
+nlua_pop_typval_table_processing_end:
+ break;
+ }
+ default: {
+ EMSG(_("E5101: Cannot convert given lua type"));
+ ret = false;
+ break;
+ }
+ }
+ if (!cur.container) {
+ lua_pop(lstate, 1);
+ }
+ }
+ kv_destroy(stack);
+ if (!ret) {
+ tv_clear(ret_tv);
+ *ret_tv = (typval_T) {
+ .v_type = VAR_NUMBER,
+ .v_lock = VAR_UNLOCKED,
+ .vval = { .v_number = 0 },
+ };
+ lua_pop(lstate, lua_gettop(lstate) - initial_size + 1);
+ }
+ assert(lua_gettop(lstate) == initial_size - 1);
+ return ret;
+}
+
+#define TYPVAL_ENCODE_ALLOW_SPECIALS true
+
+#define TYPVAL_ENCODE_CONV_NIL(tv) \
+ lua_pushnil(lstate)
+
+#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
+ lua_pushboolean(lstate, (bool)(num))
+
+#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
+ lua_pushnumber(lstate, (lua_Number)(num))
+
+#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER
+
+#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
+ TYPVAL_ENCODE_CONV_NUMBER(tv, flt)
+
+#define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \
+ lua_pushlstring(lstate, (const char *)(str), (len))
+
+#define TYPVAL_ENCODE_CONV_STR_STRING TYPVAL_ENCODE_CONV_STRING
+
+#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, str, len, type) \
+ TYPVAL_ENCODE_CONV_NIL(tv)
+
+#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
+ do { \
+ TYPVAL_ENCODE_CONV_NIL(tv); \
+ goto typval_encode_stop_converting_one_item; \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF(tv, len)
+#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
+ lua_createtable(lstate, 0, 0)
+
+#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
+ nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary)
+
+#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
+ do { \
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
+ emsgf(_("E5102: Lua failed to grow stack to %i"), \
+ lua_gettop(lstate) + 3); \
+ return false; \
+ } \
+ lua_createtable(lstate, (int)(len), 0); \
+ lua_pushnumber(lstate, 1); \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
+
+#define TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS(tv) \
+ do { \
+ lua_Number idx = lua_tonumber(lstate, -2); \
+ lua_rawset(lstate, -3); \
+ lua_pushnumber(lstate, idx + 1); \
+ } while (0)
+
+#define TYPVAL_ENCODE_CONV_LIST_END(tv) \
+ lua_rawset(lstate, -3)
+
+#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
+ do { \
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) { \
+ emsgf(_("E5102: Lua failed to grow stack to %i"), \
+ lua_gettop(lstate) + 3); \
+ return false; \
+ } \
+ lua_createtable(lstate, 0, (int)(len)); \
+ } while (0)
+
+#define TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK(label, kv_pair)
+
+#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
+
+#define TYPVAL_ENCODE_CONV_DICT_AFTER_KEY(tv, dict)
+
+#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
+ lua_rawset(lstate, -3)
+
+#define TYPVAL_ENCODE_CONV_DICT_END(tv, dict) \
+ TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict)
+
+#define TYPVAL_ENCODE_CONV_RECURSE(val, conv_type) \
+ do { \
+ for (size_t backref = kv_size(*mpstack); backref; backref--) { \
+ const MPConvStackVal mpval = kv_A(*mpstack, backref - 1); \
+ if (mpval.type == conv_type) { \
+ if (conv_type == kMPConvDict \
+ ? (void *)mpval.data.d.dict == (void *)(val) \
+ : (void *)mpval.data.l.list == (void *)(val)) { \
+ lua_pushvalue(lstate, \
+ -((int)((kv_size(*mpstack) - backref + 1) * 2))); \
+ break; \
+ } \
+ } \
+ } \
+ } while (0)
+
+#define TYPVAL_ENCODE_SCOPE static
+#define TYPVAL_ENCODE_NAME lua
+#define TYPVAL_ENCODE_FIRST_ARG_TYPE lua_State *const
+#define TYPVAL_ENCODE_FIRST_ARG_NAME lstate
+#include "nvim/eval/typval_encode.c.h"
+#undef TYPVAL_ENCODE_SCOPE
+#undef TYPVAL_ENCODE_NAME
+#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
+#undef TYPVAL_ENCODE_FIRST_ARG_NAME
+
+#undef TYPVAL_ENCODE_CONV_STRING
+#undef TYPVAL_ENCODE_CONV_STR_STRING
+#undef TYPVAL_ENCODE_CONV_EXT_STRING
+#undef TYPVAL_ENCODE_CONV_NUMBER
+#undef TYPVAL_ENCODE_CONV_FLOAT
+#undef TYPVAL_ENCODE_CONV_FUNC_START
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_ARGS
+#undef TYPVAL_ENCODE_CONV_FUNC_BEFORE_SELF
+#undef TYPVAL_ENCODE_CONV_FUNC_END
+#undef TYPVAL_ENCODE_CONV_EMPTY_LIST
+#undef TYPVAL_ENCODE_CONV_LIST_START
+#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
+#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
+#undef TYPVAL_ENCODE_CONV_NIL
+#undef TYPVAL_ENCODE_CONV_BOOL
+#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
+#undef TYPVAL_ENCODE_CONV_DICT_START
+#undef TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START
+#undef TYPVAL_ENCODE_CONV_DICT_END
+#undef TYPVAL_ENCODE_CONV_DICT_AFTER_KEY
+#undef TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS
+#undef TYPVAL_ENCODE_SPECIAL_DICT_KEY_CHECK
+#undef TYPVAL_ENCODE_CONV_LIST_END
+#undef TYPVAL_ENCODE_CONV_LIST_BETWEEN_ITEMS
+#undef TYPVAL_ENCODE_CONV_RECURSE
+#undef TYPVAL_ENCODE_ALLOW_SPECIALS
+
+/// Convert VimL typval_T to lua value
+///
+/// Should leave single value in lua stack. May only fail if lua failed to grow
+/// stack.
+///
+/// @param lstate Lua interpreter state.
+/// @param[in] tv typval_T to convert.
+///
+/// @return true in case of success, false otherwise.
+bool nlua_push_typval(lua_State *lstate, typval_T *const tv)
+{
+ const int initial_size = lua_gettop(lstate);
+ if (!lua_checkstack(lstate, initial_size + 2)) {
+ emsgf(_("E1502: Lua failed to grow stack to %i"), initial_size + 4);
+ return false;
+ }
+ if (encode_vim_to_lua(lstate, tv, "nlua_push_typval argument") == FAIL) {
+ return false;
+ }
+ assert(lua_gettop(lstate) == initial_size + 1);
+ return true;
+}
+
+/// Push value which is a type index
+///
+/// Used for all “typed†tables: i.e. for all tables which represent VimL
+/// values.
+static inline void nlua_push_type_idx(lua_State *lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushboolean(lstate, TYPE_IDX_VALUE);
+}
+
+/// Push value which is a value index
+///
+/// Used for tables which represent scalar values, like float value.
+static inline void nlua_push_val_idx(lua_State *lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushboolean(lstate, VAL_IDX_VALUE);
+}
+
+/// Push type
+///
+/// Type is a value in vim.types table.
+///
+/// @param[out] lstate Lua state.
+/// @param[in] type Type to push.
+static inline void nlua_push_type(lua_State *lstate, ObjectType type)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushnumber(lstate, (lua_Number)type);
+}
+
+/// Create lua table which has an entry that determines its VimL type
+///
+/// @param[out] lstate Lua state.
+/// @param[in] narr Number of “array†entries to be populated later.
+/// @param[in] nrec Number of “dictionary†entries to be populated later.
+/// @param[in] type Type of the table.
+static inline void nlua_create_typed_table(lua_State *lstate,
+ const size_t narr,
+ const size_t nrec,
+ const ObjectType type)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_createtable(lstate, (int)narr, (int)(1 + nrec));
+ nlua_push_type_idx(lstate);
+ nlua_push_type(lstate, type);
+ lua_rawset(lstate, -3);
+}
+
+
+/// Convert given String to lua string
+///
+/// Leaves converted string on top of the stack.
+void nlua_push_String(lua_State *lstate, const String s)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushlstring(lstate, s.data, s.size);
+}
+
+/// Convert given Integer to lua number
+///
+/// Leaves converted number on top of the stack.
+void nlua_push_Integer(lua_State *lstate, const Integer n)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushnumber(lstate, (lua_Number)n);
+}
+
+/// Convert given Float to lua table
+///
+/// Leaves converted table on top of the stack.
+void nlua_push_Float(lua_State *lstate, const Float f)
+ FUNC_ATTR_NONNULL_ALL
+{
+ nlua_create_typed_table(lstate, 0, 1, kObjectTypeFloat);
+ nlua_push_val_idx(lstate);
+ lua_pushnumber(lstate, (lua_Number)f);
+ lua_rawset(lstate, -3);
+}
+
+/// Convert given Float to lua boolean
+///
+/// Leaves converted value on top of the stack.
+void nlua_push_Boolean(lua_State *lstate, const Boolean b)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_pushboolean(lstate, b);
+}
+
+/// Convert given Dictionary to lua table
+///
+/// Leaves converted table on top of the stack.
+void nlua_push_Dictionary(lua_State *lstate, const Dictionary dict)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (dict.size == 0) {
+ nlua_create_typed_table(lstate, 0, 0, kObjectTypeDictionary);
+ } else {
+ lua_createtable(lstate, 0, (int)dict.size);
+ }
+ for (size_t i = 0; i < dict.size; i++) {
+ nlua_push_String(lstate, dict.items[i].key);
+ nlua_push_Object(lstate, dict.items[i].value);
+ lua_rawset(lstate, -3);
+ }
+}
+
+/// Convert given Array to lua table
+///
+/// Leaves converted table on top of the stack.
+void nlua_push_Array(lua_State *lstate, const Array array)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_createtable(lstate, (int)array.size, 0);
+ for (size_t i = 0; i < array.size; i++) {
+ nlua_push_Object(lstate, array.items[i]);
+ lua_rawseti(lstate, -2, (int)i + 1);
+ }
+}
+
+#define GENERATE_INDEX_FUNCTION(type) \
+void nlua_push_##type(lua_State *lstate, const type item) \
+ FUNC_ATTR_NONNULL_ALL \
+{ \
+ lua_pushnumber(lstate, (lua_Number)(item)); \
+}
+
+GENERATE_INDEX_FUNCTION(Buffer)
+GENERATE_INDEX_FUNCTION(Window)
+GENERATE_INDEX_FUNCTION(Tabpage)
+
+#undef GENERATE_INDEX_FUNCTION
+
+/// Convert given Object to lua value
+///
+/// Leaves converted value on top of the stack.
+void nlua_push_Object(lua_State *lstate, const Object obj)
+ FUNC_ATTR_NONNULL_ALL
+{
+ switch (obj.type) {
+ case kObjectTypeNil: {
+ lua_pushnil(lstate);
+ break;
+ }
+#define ADD_TYPE(type, data_key) \
+ case kObjectType##type: { \
+ nlua_push_##type(lstate, obj.data.data_key); \
+ break; \
+ }
+ ADD_TYPE(Boolean, boolean)
+ ADD_TYPE(Integer, integer)
+ ADD_TYPE(Float, floating)
+ ADD_TYPE(String, string)
+ ADD_TYPE(Array, array)
+ ADD_TYPE(Dictionary, dictionary)
+#undef ADD_TYPE
+#define ADD_REMOTE_TYPE(type) \
+ case kObjectType##type: { \
+ nlua_push_##type(lstate, (type)obj.data.integer); \
+ break; \
+ }
+ ADD_REMOTE_TYPE(Buffer)
+ ADD_REMOTE_TYPE(Window)
+ ADD_REMOTE_TYPE(Tabpage)
+#undef ADD_REMOTE_TYPE
+ }
+}
+
+
+/// Convert lua value to string
+///
+/// Always pops one value from the stack.
+String nlua_pop_String(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (lua_type(lstate, -1) != LUA_TSTRING) {
+ lua_pop(lstate, 1);
+ api_set_error(err, kErrorTypeValidation, "Expected lua string");
+ return (String) { .size = 0, .data = NULL };
+ }
+ String ret;
+
+ ret.data = (char *)lua_tolstring(lstate, -1, &(ret.size));
+ assert(ret.data != NULL);
+ ret.data = xmemdupz(ret.data, ret.size);
+ lua_pop(lstate, 1);
+
+ return ret;
+}
+
+/// Convert lua value to integer
+///
+/// Always pops one value from the stack.
+Integer nlua_pop_Integer(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (lua_type(lstate, -1) != LUA_TNUMBER) {
+ lua_pop(lstate, 1);
+ api_set_error(err, kErrorTypeValidation, "Expected lua number");
+ return 0;
+ }
+ const lua_Number n = lua_tonumber(lstate, -1);
+ lua_pop(lstate, 1);
+ if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN
+ || ((lua_Number)((Integer)n)) != n) {
+ api_set_error(err, kErrorTypeException, "Number is not integral");
+ return 0;
+ }
+ return (Integer)n;
+}
+
+/// Convert lua value to boolean
+///
+/// Always pops one value from the stack.
+Boolean nlua_pop_Boolean(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const Boolean ret = lua_toboolean(lstate, -1);
+ lua_pop(lstate, 1);
+ return ret;
+}
+
+/// Check whether typed table on top of the stack has given type
+///
+/// @param[in] lstate Lua state.
+/// @param[out] err Location where error will be saved. May be NULL.
+/// @param[in] type Type to check.
+///
+/// @return @see nlua_traverse_table().
+static inline LuaTableProps nlua_check_type(lua_State *const lstate,
+ Error *const err,
+ const ObjectType type)
+ FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (lua_type(lstate, -1) != LUA_TTABLE) {
+ if (err) {
+ api_set_error(err, kErrorTypeValidation, "Expected lua table");
+ }
+ return (LuaTableProps) { .type = kObjectTypeNil };
+ }
+ LuaTableProps table_props = nlua_traverse_table(lstate);
+
+ if (type == kObjectTypeDictionary && table_props.type == kObjectTypeArray
+ && table_props.maxidx == 0 && !table_props.has_type_key) {
+ table_props.type = kObjectTypeDictionary;
+ }
+
+ if (table_props.type != type) {
+ if (err) {
+ api_set_error(err, kErrorTypeValidation, "Unexpected type");
+ }
+ }
+
+ return table_props;
+}
+
+/// Convert lua table to float
+///
+/// Always pops one value from the stack.
+Float nlua_pop_Float(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (lua_type(lstate, -1) == LUA_TNUMBER) {
+ const Float ret = (Float)lua_tonumber(lstate, -1);
+ lua_pop(lstate, 1);
+ return ret;
+ }
+
+ const LuaTableProps table_props = nlua_check_type(lstate, err,
+ kObjectTypeFloat);
+ lua_pop(lstate, 1);
+ if (table_props.type != kObjectTypeFloat) {
+ return 0;
+ } else {
+ return (Float)table_props.val;
+ }
+}
+
+/// Convert lua table to array without determining whether it is array
+///
+/// @param lstate Lua state.
+/// @param[in] table_props nlua_traverse_table() output.
+/// @param[out] err Location where error will be saved.
+static Array nlua_pop_Array_unchecked(lua_State *const lstate,
+ const LuaTableProps table_props,
+ Error *const err)
+{
+ Array ret = { .size = table_props.maxidx, .items = NULL };
+
+ if (ret.size == 0) {
+ lua_pop(lstate, 1);
+ return ret;
+ }
+
+ ret.items = xcalloc(ret.size, sizeof(*ret.items));
+ for (size_t i = 1; i <= ret.size; i++) {
+ Object val;
+
+ lua_rawgeti(lstate, -1, (int)i);
+
+ val = nlua_pop_Object(lstate, err);
+ if (ERROR_SET(err)) {
+ ret.size = i - 1;
+ lua_pop(lstate, 1);
+ api_free_array(ret);
+ return (Array) { .size = 0, .items = NULL };
+ }
+ ret.items[i - 1] = val;
+ }
+ lua_pop(lstate, 1);
+
+ return ret;
+}
+
+/// Convert lua table to array
+///
+/// Always pops one value from the stack.
+Array nlua_pop_Array(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const LuaTableProps table_props = nlua_check_type(lstate, err,
+ kObjectTypeArray);
+ if (table_props.type != kObjectTypeArray) {
+ return (Array) { .size = 0, .items = NULL };
+ }
+ return nlua_pop_Array_unchecked(lstate, table_props, err);
+}
+
+/// Convert lua table to dictionary
+///
+/// Always pops one value from the stack. Does not check whether whether topmost
+/// value on the stack is a table.
+///
+/// @param lstate Lua interpreter state.
+/// @param[in] table_props nlua_traverse_table() output.
+/// @param[out] err Location where error will be saved.
+static Dictionary nlua_pop_Dictionary_unchecked(lua_State *lstate,
+ const LuaTableProps table_props,
+ Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ Dictionary ret = { .size = table_props.string_keys_num, .items = NULL };
+
+ if (ret.size == 0) {
+ lua_pop(lstate, 1);
+ return ret;
+ }
+ ret.items = xcalloc(ret.size, sizeof(*ret.items));
+
+ lua_pushnil(lstate);
+ for (size_t i = 0; lua_next(lstate, -2) && i < ret.size;) {
+ // stack: dict, key, value
+
+ if (lua_type(lstate, -2) == LUA_TSTRING) {
+ lua_pushvalue(lstate, -2);
+ // stack: dict, key, value, key
+
+ ret.items[i].key = nlua_pop_String(lstate, err);
+ // stack: dict, key, value
+
+ if (!ERROR_SET(err)) {
+ ret.items[i].value = nlua_pop_Object(lstate, err);
+ // stack: dict, key
+ } else {
+ lua_pop(lstate, 1);
+ // stack: dict, key
+ }
+
+ if (ERROR_SET(err)) {
+ ret.size = i;
+ api_free_dictionary(ret);
+ lua_pop(lstate, 2);
+ // stack:
+ return (Dictionary) { .size = 0, .items = NULL };
+ }
+ i++;
+ } else {
+ lua_pop(lstate, 1);
+ // stack: dict, key
+ }
+ }
+ lua_pop(lstate, 1);
+
+ return ret;
+}
+
+/// Convert lua table to dictionary
+///
+/// Always pops one value from the stack.
+Dictionary nlua_pop_Dictionary(lua_State *lstate, Error *err)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ const LuaTableProps table_props = nlua_check_type(lstate, err,
+ kObjectTypeDictionary);
+ if (table_props.type != kObjectTypeDictionary) {
+ lua_pop(lstate, 1);
+ return (Dictionary) { .size = 0, .items = NULL };
+ }
+
+ return nlua_pop_Dictionary_unchecked(lstate, table_props, err);
+}
+
+/// Helper structure for nlua_pop_Object
+typedef struct {
+ Object *obj; ///< Location where conversion result is saved.
+ bool container; ///< True if tv is a container.
+} ObjPopStackItem;
+
+/// Convert lua table to object
+///
+/// Always pops one value from the stack.
+Object nlua_pop_Object(lua_State *const lstate, Error *const err)
+{
+ Object ret = NIL;
+ const int initial_size = lua_gettop(lstate);
+ kvec_t(ObjPopStackItem) stack = KV_INITIAL_VALUE;
+ kv_push(stack, ((ObjPopStackItem) { &ret, false }));
+ while (!ERROR_SET(err) && kv_size(stack)) {
+ if (!lua_checkstack(lstate, lua_gettop(lstate) + 3)) {
+ api_set_error(err, kErrorTypeException, "Lua failed to grow stack");
+ break;
+ }
+ ObjPopStackItem cur = kv_pop(stack);
+ if (cur.container) {
+ if (cur.obj->type == kObjectTypeDictionary) {
+ // stack: …, dict, key
+ if (cur.obj->data.dictionary.size
+ == cur.obj->data.dictionary.capacity) {
+ lua_pop(lstate, 2);
+ continue;
+ }
+ bool next_key_found = false;
+ while (lua_next(lstate, -2)) {
+ // stack: …, dict, new key, val
+ if (lua_type(lstate, -2) == LUA_TSTRING) {
+ next_key_found = true;
+ break;
+ }
+ lua_pop(lstate, 1);
+ // stack: …, dict, new key
+ }
+ if (next_key_found) {
+ // stack: …, dict, new key, val
+ size_t len;
+ const char *s = lua_tolstring(lstate, -2, &len);
+ const size_t idx = cur.obj->data.dictionary.size++;
+ cur.obj->data.dictionary.items[idx].key = (String) {
+ .data = xmemdupz(s, len),
+ .size = len,
+ };
+ kv_push(stack, cur);
+ cur = (ObjPopStackItem) {
+ .obj = &cur.obj->data.dictionary.items[idx].value,
+ .container = false,
+ };
+ } else {
+ // stack: …, dict
+ lua_pop(lstate, 1);
+ // stack: …
+ continue;
+ }
+ } else {
+ if (cur.obj->data.array.size == cur.obj->data.array.capacity) {
+ lua_pop(lstate, 1);
+ continue;
+ }
+ const size_t idx = cur.obj->data.array.size++;
+ lua_rawgeti(lstate, -1, (int)idx + 1);
+ if (lua_isnil(lstate, -1)) {
+ lua_pop(lstate, 2);
+ continue;
+ }
+ kv_push(stack, cur);
+ cur = (ObjPopStackItem) {
+ .obj = &cur.obj->data.array.items[idx],
+ .container = false,
+ };
+ }
+ }
+ assert(!cur.container);
+ *cur.obj = NIL;
+ switch (lua_type(lstate, -1)) {
+ case LUA_TNIL: {
+ break;
+ }
+ case LUA_TBOOLEAN: {
+ *cur.obj = BOOLEAN_OBJ(lua_toboolean(lstate, -1));
+ break;
+ }
+ case LUA_TSTRING: {
+ size_t len;
+ const char *s = lua_tolstring(lstate, -1, &len);
+ *cur.obj = STRING_OBJ(((String) {
+ .data = xmemdupz(s, len),
+ .size = len,
+ }));
+ break;
+ }
+ case LUA_TNUMBER: {
+ const lua_Number n = lua_tonumber(lstate, -1);
+ if (n > (lua_Number)API_INTEGER_MAX || n < (lua_Number)API_INTEGER_MIN
+ || ((lua_Number)((Integer)n)) != n) {
+ *cur.obj = FLOAT_OBJ((Float)n);
+ } else {
+ *cur.obj = INTEGER_OBJ((Integer)n);
+ }
+ break;
+ }
+ case LUA_TTABLE: {
+ const LuaTableProps table_props = nlua_traverse_table(lstate);
+
+ switch (table_props.type) {
+ case kObjectTypeArray: {
+ *cur.obj = ARRAY_OBJ(((Array) {
+ .items = NULL,
+ .size = 0,
+ .capacity = 0,
+ }));
+ if (table_props.maxidx != 0) {
+ cur.obj->data.array.items =
+ xcalloc(table_props.maxidx,
+ sizeof(cur.obj->data.array.items[0]));
+ cur.obj->data.array.capacity = table_props.maxidx;
+ cur.container = true;
+ kv_push(stack, cur);
+ }
+ break;
+ }
+ case kObjectTypeDictionary: {
+ *cur.obj = DICTIONARY_OBJ(((Dictionary) {
+ .items = NULL,
+ .size = 0,
+ .capacity = 0,
+ }));
+ if (table_props.string_keys_num != 0) {
+ cur.obj->data.dictionary.items =
+ xcalloc(table_props.string_keys_num,
+ sizeof(cur.obj->data.dictionary.items[0]));
+ cur.obj->data.dictionary.capacity = table_props.string_keys_num;
+ cur.container = true;
+ kv_push(stack, cur);
+ lua_pushnil(lstate);
+ }
+ break;
+ }
+ case kObjectTypeFloat: {
+ *cur.obj = FLOAT_OBJ((Float)table_props.val);
+ break;
+ }
+ case kObjectTypeNil: {
+ api_set_error(err, kErrorTypeValidation,
+ "Cannot convert given lua table");
+ break;
+ }
+ default: {
+ assert(false);
+ }
+ }
+ break;
+ }
+ default: {
+ api_set_error(err, kErrorTypeValidation,
+ "Cannot convert given lua type");
+ break;
+ }
+ }
+ if (!cur.container) {
+ lua_pop(lstate, 1);
+ }
+ }
+ kv_destroy(stack);
+ if (ERROR_SET(err)) {
+ api_free_object(ret);
+ ret = NIL;
+ lua_pop(lstate, lua_gettop(lstate) - initial_size + 1);
+ }
+ assert(lua_gettop(lstate) == initial_size - 1);
+ return ret;
+}
+
+#define GENERATE_INDEX_FUNCTION(type) \
+type nlua_pop_##type(lua_State *lstate, Error *err) \
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
+{ \
+ type ret; \
+ ret = (type)lua_tonumber(lstate, -1); \
+ lua_pop(lstate, 1); \
+ return ret; \
+}
+
+GENERATE_INDEX_FUNCTION(Buffer)
+GENERATE_INDEX_FUNCTION(Window)
+GENERATE_INDEX_FUNCTION(Tabpage)
+
+#undef GENERATE_INDEX_FUNCTION
+
+/// Record some auxilary values in vim module
+///
+/// Assumes that module table is on top of the stack.
+///
+/// Recorded values:
+///
+/// `vim.type_idx`: @see nlua_push_type_idx()
+/// `vim.val_idx`: @see nlua_push_val_idx()
+/// `vim.types`: table mapping possible values of `vim.type_idx` to string
+/// names (i.e. `array`, `float`, `dictionary`) and back.
+void nlua_init_types(lua_State *const lstate)
+{
+ LUA_PUSH_STATIC_STRING(lstate, "type_idx");
+ nlua_push_type_idx(lstate);
+ lua_rawset(lstate, -3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "val_idx");
+ nlua_push_val_idx(lstate);
+ lua_rawset(lstate, -3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "types");
+ lua_createtable(lstate, 0, 3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "float");
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeFloat);
+ lua_rawset(lstate, -3);
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeFloat);
+ LUA_PUSH_STATIC_STRING(lstate, "float");
+ lua_rawset(lstate, -3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "array");
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeArray);
+ lua_rawset(lstate, -3);
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeArray);
+ LUA_PUSH_STATIC_STRING(lstate, "array");
+ lua_rawset(lstate, -3);
+
+ LUA_PUSH_STATIC_STRING(lstate, "dictionary");
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeDictionary);
+ lua_rawset(lstate, -3);
+ lua_pushnumber(lstate, (lua_Number)kObjectTypeDictionary);
+ LUA_PUSH_STATIC_STRING(lstate, "dictionary");
+ lua_rawset(lstate, -3);
+
+ lua_rawset(lstate, -3);
+}
diff --git a/src/nvim/lua/converter.h b/src/nvim/lua/converter.h
new file mode 100644
index 0000000000..542c56ea3e
--- /dev/null
+++ b/src/nvim/lua/converter.h
@@ -0,0 +1,15 @@
+#ifndef NVIM_LUA_CONVERTER_H
+#define NVIM_LUA_CONVERTER_H
+
+#include <lua.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nvim/api/private/defs.h"
+#include "nvim/func_attr.h"
+#include "nvim/eval.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/converter.h.generated.h"
+#endif
+#endif // NVIM_LUA_CONVERTER_H
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
new file mode 100644
index 0000000000..a7bda9d037
--- /dev/null
+++ b/src/nvim/lua/executor.c
@@ -0,0 +1,549 @@
+// 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 <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include "nvim/misc1.h"
+#include "nvim/getchar.h"
+#include "nvim/garray.h"
+#include "nvim/func_attr.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
+#include "nvim/vim.h"
+#include "nvim/ex_getln.h"
+#include "nvim/ex_cmds2.h"
+#include "nvim/message.h"
+#include "nvim/memline.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/macros.h"
+#include "nvim/screen.h"
+#include "nvim/cursor.h"
+#include "nvim/undo.h"
+#include "nvim/ascii.h"
+
+#include "nvim/lua/executor.h"
+#include "nvim/lua/converter.h"
+
+typedef struct {
+ Error err;
+ String lua_err_str;
+} LuaError;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/vim_module.generated.h"
+# include "lua/executor.c.generated.h"
+#endif
+
+/// Name of the run code for use in messages
+#define NLUA_EVAL_NAME "<VimL compiled string>"
+
+/// Convert lua error into a Vim error message
+///
+/// @param lstate Lua interpreter state.
+/// @param[in] msg Message base, must contain one `%s`.
+static void nlua_error(lua_State *const lstate, const char *const msg)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t len;
+ const char *const str = lua_tolstring(lstate, -1, &len);
+
+ emsgf(msg, (int)len, str);
+
+ lua_pop(lstate, 1);
+}
+
+/// Compare two strings, ignoring case
+///
+/// Expects two values on the stack: compared strings. Returns one of the
+/// following numbers: 0, -1 or 1.
+///
+/// Does no error handling: never call it with non-string or with some arguments
+/// omitted.
+static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ size_t s1_len;
+ size_t s2_len;
+ const char *s1 = luaL_checklstring(lstate, 1, &s1_len);
+ const char *s2 = luaL_checklstring(lstate, 2, &s2_len);
+ char *nul1;
+ char *nul2;
+ int ret = 0;
+ assert(s1[s1_len] == NUL);
+ assert(s2[s2_len] == NUL);
+ do {
+ nul1 = memchr(s1, NUL, s1_len);
+ nul2 = memchr(s2, NUL, s2_len);
+ ret = STRICMP(s1, s2);
+ if (ret == 0) {
+ // Compare "a\0" greater then "a".
+ if ((nul1 == NULL) != (nul2 == NULL)) {
+ ret = ((nul1 != NULL) - (nul2 != NULL));
+ break;
+ }
+ if (nul1 != NULL) {
+ assert(nul2 != NULL);
+ // Can't shift both strings by the same amount of bytes: lowercase
+ // letter may have different byte-length than uppercase.
+ s1_len -= (size_t)(nul1 - s1) + 1;
+ s2_len -= (size_t)(nul2 - s2) + 1;
+ s1 = nul1 + 1;
+ s2 = nul2 + 1;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ } while (true);
+ lua_pop(lstate, 2);
+ lua_pushnumber(lstate, (lua_Number)((ret > 0) - (ret < 0)));
+ return 1;
+}
+
+/// Initialize lua interpreter state
+///
+/// Called by lua interpreter itself to initialize state.
+static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
+{
+ // print
+ lua_pushcfunction(lstate, &nlua_print);
+ lua_setglobal(lstate, "print");
+
+ // debug.debug
+ lua_getglobal(lstate, "debug");
+ lua_pushcfunction(lstate, &nlua_debug);
+ lua_setfield(lstate, -2, "debug");
+ lua_pop(lstate, 1);
+
+ // vim
+ if (luaL_dostring(lstate, (char *)&vim_module[0])) {
+ nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
+ return 1;
+ }
+ // vim.api
+ nlua_add_api_functions(lstate);
+ // vim.types, vim.type_idx, vim.val_idx
+ nlua_init_types(lstate);
+ // stricmp
+ lua_pushcfunction(lstate, &nlua_stricmp);
+ lua_setfield(lstate, -2, "stricmp");
+
+ lua_setglobal(lstate, "vim");
+ return 0;
+}
+
+/// Initialize lua interpreter
+///
+/// Crashes Nvim if initialization fails. Should be called once per lua
+/// interpreter instance.
+///
+/// @return New lua interpreter instance.
+static lua_State *nlua_init(void)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ lua_State *lstate = luaL_newstate();
+ if (lstate == NULL) {
+ EMSG(_("E970: Failed to initialize lua interpreter"));
+ preserve_exit();
+ }
+ luaL_openlibs(lstate);
+ nlua_state_init(lstate);
+ return lstate;
+}
+
+/// Enter lua interpreter
+///
+/// Calls nlua_init() if needed. Is responsible for pre-lua call initalization
+/// like updating `package.[c]path` with directories derived from &runtimepath.
+///
+/// @return Interpreter instance to use. Will either be initialized now or
+/// taken from previous initialization.
+static lua_State *nlua_enter(void)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static lua_State *global_lstate = NULL;
+ if (global_lstate == NULL) {
+ global_lstate = nlua_init();
+ }
+ lua_State *const lstate = global_lstate;
+ // Last used p_rtp value. Must not be dereferenced because value pointed to
+ // may already be freed. Used to check whether &runtimepath option value
+ // changed.
+ static const void *last_p_rtp = NULL;
+ if (last_p_rtp != (const void *)p_rtp) {
+ // stack: (empty)
+ lua_getglobal(lstate, "vim");
+ // stack: vim
+ lua_getfield(lstate, -1, "_update_package_paths");
+ // stack: vim, vim._update_package_paths
+ if (lua_pcall(lstate, 0, 0, 0)) {
+ // stack: vim, error
+ nlua_error(lstate, _("E5117: Error while updating package paths: %.*s"));
+ // stack: vim
+ }
+ // stack: vim
+ lua_pop(lstate, 1);
+ // stack: (empty)
+ last_p_rtp = (const void *)p_rtp;
+ }
+ return lstate;
+}
+
+/// Execute lua string
+///
+/// @param[in] str String to execute.
+/// @param[out] ret_tv Location where result will be saved.
+///
+/// @return Result of the execution.
+void executor_exec_lua(const String str, typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_State *const lstate = nlua_enter();
+
+ if (luaL_loadbuffer(lstate, str.data, str.size, NLUA_EVAL_NAME)) {
+ nlua_error(lstate, _("E5104: Error while creating lua chunk: %.*s"));
+ return;
+ }
+ if (lua_pcall(lstate, 0, 1, 0)) {
+ nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s"));
+ return;
+ }
+
+ nlua_pop_typval(lstate, ret_tv);
+}
+
+/// Print as a Vim message
+///
+/// @param lstate Lua interpreter state.
+static int nlua_print(lua_State *const lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+#define PRINT_ERROR(msg) \
+ do { \
+ errmsg = msg; \
+ errmsg_len = sizeof(msg) - 1; \
+ goto nlua_print_error; \
+ } while (0)
+ const int nargs = lua_gettop(lstate);
+ lua_getglobal(lstate, "tostring");
+ const char *errmsg = NULL;
+ size_t errmsg_len = 0;
+ garray_T msg_ga;
+ ga_init(&msg_ga, 1, 80);
+ int curargidx = 1;
+ for (; curargidx <= nargs; curargidx++) {
+ lua_pushvalue(lstate, -1); // tostring
+ lua_pushvalue(lstate, curargidx); // arg
+ if (lua_pcall(lstate, 1, 1, 0)) {
+ errmsg = lua_tolstring(lstate, -1, &errmsg_len);
+ goto nlua_print_error;
+ }
+ size_t len;
+ const char *const s = lua_tolstring(lstate, -1, &len);
+ if (s == NULL) {
+ PRINT_ERROR(
+ "<Unknown error: lua_tolstring returned NULL for tostring result>");
+ }
+ ga_concat_len(&msg_ga, s, len);
+ if (curargidx < nargs) {
+ ga_append(&msg_ga, ' ');
+ }
+ lua_pop(lstate, 1);
+ }
+#undef PRINT_ERROR
+ lua_pop(lstate, nargs + 1);
+ ga_append(&msg_ga, NUL);
+ {
+ const size_t len = (size_t)msg_ga.ga_len - 1;
+ char *const str = (char *)msg_ga.ga_data;
+
+ for (size_t i = 0; i < len;) {
+ const size_t start = i;
+ while (i < len) {
+ switch (str[i]) {
+ case NUL: {
+ str[i] = NL;
+ i++;
+ continue;
+ }
+ case NL: {
+ str[i] = NUL;
+ i++;
+ break;
+ }
+ default: {
+ i++;
+ continue;
+ }
+ }
+ break;
+ }
+ msg((char_u *)str + start);
+ }
+ if (len && str[len - 1] == NUL) { // Last was newline
+ msg((char_u *)"");
+ }
+ }
+ ga_clear(&msg_ga);
+ return 0;
+nlua_print_error:
+ emsgf(_("E5114: Error while converting print argument #%i: %.*s"),
+ curargidx, (int)errmsg_len, errmsg);
+ ga_clear(&msg_ga);
+ lua_pop(lstate, lua_gettop(lstate));
+ return 0;
+}
+
+/// debug.debug implementation: interaction with user while debugging
+///
+/// @param lstate Lua interpreter state.
+int nlua_debug(lua_State *lstate)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const typval_T input_args[] = {
+ {
+ .v_lock = VAR_FIXED,
+ .v_type = VAR_STRING,
+ .vval.v_string = (char_u *)"lua_debug> ",
+ },
+ {
+ .v_type = VAR_UNKNOWN,
+ },
+ };
+ for (;;) {
+ lua_settop(lstate, 0);
+ typval_T input;
+ get_user_input(input_args, &input, false);
+ msg_putchar('\n'); // Avoid outputting on input line.
+ if (input.v_type != VAR_STRING
+ || input.vval.v_string == NULL
+ || *input.vval.v_string == NUL
+ || STRCMP(input.vval.v_string, "cont") == 0) {
+ tv_clear(&input);
+ return 0;
+ }
+ if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string,
+ STRLEN(input.vval.v_string), "=(debug command)")) {
+ nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
+ }
+ tv_clear(&input);
+ if (lua_pcall(lstate, 0, 0, 0)) {
+ nlua_error(lstate, _("E5116: Error while calling debug string: %.*s"));
+ }
+ }
+ return 0;
+}
+
+/// Evaluate lua string
+///
+/// Used for luaeval().
+///
+/// @param[in] str String to execute.
+/// @param[in] arg Second argument to `luaeval()`.
+/// @param[out] ret_tv Location where result will be saved.
+///
+/// @return Result of the execution.
+void executor_eval_lua(const String str, typval_T *const arg,
+ typval_T *const ret_tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_State *const lstate = nlua_enter();
+
+ garray_T str_ga;
+ ga_init(&str_ga, 1, 80);
+#define EVALHEADER "local _A=select(1,...) return ("
+ const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str.size + 1;
+ char *lcmd;
+ if (lcmd_len < IOSIZE) {
+ lcmd = (char *)IObuff;
+ } else {
+ lcmd = xmalloc(lcmd_len);
+ }
+ memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1);
+ memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size);
+ lcmd[lcmd_len - 1] = ')';
+#undef EVALHEADER
+ if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
+ nlua_error(lstate,
+ _("E5107: Error while creating lua chunk for luaeval(): %.*s"));
+ if (lcmd != (char *)IObuff) {
+ xfree(lcmd);
+ }
+ return;
+ }
+ if (lcmd != (char *)IObuff) {
+ xfree(lcmd);
+ }
+
+ if (arg->v_type == VAR_UNKNOWN) {
+ lua_pushnil(lstate);
+ } else {
+ nlua_push_typval(lstate, arg);
+ }
+ if (lua_pcall(lstate, 1, 1, 0)) {
+ nlua_error(lstate,
+ _("E5108: Error while calling lua chunk for luaeval(): %.*s"));
+ return;
+ }
+
+ nlua_pop_typval(lstate, ret_tv);
+}
+
+/// Execute lua string
+///
+/// Used for nvim_execute_lua().
+///
+/// @param[in] str String to execute.
+/// @param[in] args array of ... args
+/// @param[out] err Location where error will be saved.
+///
+/// @return Return value of the execution.
+Object executor_exec_lua_api(const String str, const Array args, Error *err)
+{
+ lua_State *const lstate = nlua_enter();
+
+ if (luaL_loadbuffer(lstate, str.data, str.size, "<nvim>")) {
+ size_t len;
+ const char *errstr = lua_tolstring(lstate, -1, &len);
+ api_set_error(err, kErrorTypeValidation,
+ "Error loading lua: %.*s", (int)len, errstr);
+ return NIL;
+ }
+
+ for (size_t i = 0; i < args.size; i++) {
+ nlua_push_Object(lstate, args.items[i]);
+ }
+
+ if (lua_pcall(lstate, (int)args.size, 1, 0)) {
+ size_t len;
+ const char *errstr = lua_tolstring(lstate, -1, &len);
+ api_set_error(err, kErrorTypeException,
+ "Error executing lua: %.*s", (int)len, errstr);
+ return NIL;
+ }
+
+ return nlua_pop_Object(lstate, err);
+}
+
+
+/// Run lua string
+///
+/// Used for :lua.
+///
+/// @param eap VimL command being run.
+void ex_lua(exarg_T *const eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t len;
+ char *const code = script_get(eap, &len);
+ if (eap->skip) {
+ xfree(code);
+ return;
+ }
+ typval_T tv = { .v_type = VAR_UNKNOWN };
+ executor_exec_lua((String) { .data = code, .size = len }, &tv);
+ tv_clear(&tv);
+ xfree(code);
+}
+
+/// Run lua string for each line in range
+///
+/// Used for :luado.
+///
+/// @param eap VimL command being run.
+void ex_luado(exarg_T *const eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) {
+ EMSG(_("cannot save undo information"));
+ return;
+ }
+ const char *const cmd = (const char *)eap->arg;
+ const size_t cmd_len = strlen(cmd);
+
+ lua_State *const lstate = nlua_enter();
+
+#define DOSTART "return function(line, linenr) "
+#define DOEND " end"
+ const size_t lcmd_len = (cmd_len
+ + (sizeof(DOSTART) - 1)
+ + (sizeof(DOEND) - 1));
+ char *lcmd;
+ if (lcmd_len < IOSIZE) {
+ lcmd = (char *)IObuff;
+ } else {
+ lcmd = xmalloc(lcmd_len + 1);
+ }
+ memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1);
+ memcpy(lcmd + sizeof(DOSTART) - 1, cmd, cmd_len);
+ memcpy(lcmd + sizeof(DOSTART) - 1 + cmd_len, DOEND, sizeof(DOEND) - 1);
+#undef DOSTART
+#undef DOEND
+
+ if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
+ nlua_error(lstate, _("E5109: Error while creating lua chunk: %.*s"));
+ if (lcmd_len >= IOSIZE) {
+ xfree(lcmd);
+ }
+ return;
+ }
+ if (lcmd_len >= IOSIZE) {
+ xfree(lcmd);
+ }
+ if (lua_pcall(lstate, 0, 1, 0)) {
+ nlua_error(lstate, _("E5110: Error while creating lua function: %.*s"));
+ return;
+ }
+ for (linenr_T l = eap->line1; l <= eap->line2; l++) {
+ if (l > curbuf->b_ml.ml_line_count) {
+ break;
+ }
+ lua_pushvalue(lstate, -1);
+ lua_pushstring(lstate, (const char *)ml_get_buf(curbuf, l, false));
+ lua_pushnumber(lstate, (lua_Number)l);
+ if (lua_pcall(lstate, 2, 1, 0)) {
+ nlua_error(lstate, _("E5111: Error while calling lua function: %.*s"));
+ break;
+ }
+ if (lua_isstring(lstate, -1)) {
+ size_t new_line_len;
+ const char *const new_line = lua_tolstring(lstate, -1, &new_line_len);
+ char *const new_line_transformed = xmemdupz(new_line, new_line_len);
+ for (size_t i = 0; i < new_line_len; i++) {
+ if (new_line_transformed[i] == NUL) {
+ new_line_transformed[i] = '\n';
+ }
+ }
+ ml_replace(l, (char_u *)new_line_transformed, false);
+ changed_bytes(l, 0);
+ }
+ lua_pop(lstate, 1);
+ }
+ lua_pop(lstate, 1);
+ check_cursor();
+ update_screen(NOT_VALID);
+}
+
+/// Run lua file
+///
+/// Used for :luafile.
+///
+/// @param eap VimL command being run.
+void ex_luafile(exarg_T *const eap)
+ FUNC_ATTR_NONNULL_ALL
+{
+ lua_State *const lstate = nlua_enter();
+
+ if (luaL_loadfile(lstate, (const char *)eap->arg)) {
+ nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
+ return;
+ }
+
+ if (lua_pcall(lstate, 0, 0, 0)) {
+ nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
+ return;
+ }
+}
diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h
new file mode 100644
index 0000000000..0cbf290f64
--- /dev/null
+++ b/src/nvim/lua/executor.h
@@ -0,0 +1,25 @@
+#ifndef NVIM_LUA_EXECUTOR_H
+#define NVIM_LUA_EXECUTOR_H
+
+#include <lua.h>
+
+#include "nvim/api/private/defs.h"
+#include "nvim/func_attr.h"
+#include "nvim/eval/typval.h"
+#include "nvim/ex_cmds_defs.h"
+
+// Generated by msgpack-gen.lua
+void nlua_add_api_functions(lua_State *lstate) REAL_FATTR_NONNULL_ALL;
+
+#define set_api_error(s, err) \
+ do { \
+ Error *err_ = (err); \
+ err_->type = kErrorTypeException; \
+ err_->set = true; \
+ memcpy(&err_->msg[0], s, sizeof(s)); \
+ } while (0)
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "lua/executor.h.generated.h"
+#endif
+#endif // NVIM_LUA_EXECUTOR_H
diff --git a/src/nvim/lua/vim.lua b/src/nvim/lua/vim.lua
new file mode 100644
index 0000000000..b0d0bfc74b
--- /dev/null
+++ b/src/nvim/lua/vim.lua
@@ -0,0 +1,212 @@
+-- Internal-only until comments in #8107 are addressed.
+-- Returns:
+-- {errcode}, {output}
+local function _system(cmd)
+ local out = vim.api.nvim_call_function('system', { cmd })
+ local err = vim.api.nvim_get_vvar('shell_error')
+ return err, out
+end
+
+-- Gets process info from the `ps` command.
+-- Used by nvim_get_proc() as a fallback.
+local function _os_proc_info(pid)
+ if pid == nil or pid <= 0 or type(pid) ~= 'number' then
+ error('invalid pid')
+ end
+ local cmd = { 'ps', '-p', pid, '-o', 'comm=', }
+ local err, name = _system(cmd)
+ if 1 == err and string.gsub(name, '%s*', '') == '' then
+ return {} -- Process not found.
+ elseif 0 ~= err then
+ local args_str = vim.api.nvim_call_function('string', { cmd })
+ error('command failed: '..args_str)
+ end
+ local _, ppid = _system({ 'ps', '-p', pid, '-o', 'ppid=', })
+ -- Remove trailing whitespace.
+ name = string.gsub(string.gsub(name, '%s+$', ''), '^.*/', '')
+ ppid = string.gsub(ppid, '%s+$', '')
+ ppid = tonumber(ppid) == nil and -1 or tonumber(ppid)
+ return {
+ name = name,
+ pid = pid,
+ ppid = ppid,
+ }
+end
+
+-- Gets process children from the `pgrep` command.
+-- Used by nvim_get_proc_children() as a fallback.
+local function _os_proc_children(ppid)
+ if ppid == nil or ppid <= 0 or type(ppid) ~= 'number' then
+ error('invalid ppid')
+ end
+ local cmd = { 'pgrep', '-P', ppid, }
+ local err, rv = _system(cmd)
+ if 1 == err and string.gsub(rv, '%s*', '') == '' then
+ return {} -- Process not found.
+ elseif 0 ~= err then
+ local args_str = vim.api.nvim_call_function('string', { cmd })
+ error('command failed: '..args_str)
+ end
+ local children = {}
+ for s in string.gmatch(rv, '%S+') do
+ local i = tonumber(s)
+ if i ~= nil then
+ table.insert(children, i)
+ end
+ end
+ return children
+end
+
+-- TODO(ZyX-I): Create compatibility layer.
+--{{{1 package.path updater function
+-- Last inserted paths. Used to clear out items from package.[c]path when they
+-- are no longer in &runtimepath.
+local last_nvim_paths = {}
+local function _update_package_paths()
+ local cur_nvim_paths = {}
+ local rtps = vim.api.nvim_list_runtime_paths()
+ local sep = package.config:sub(1, 1)
+ for _, key in ipairs({'path', 'cpath'}) do
+ local orig_str = package[key] .. ';'
+ local pathtrails_ordered = {}
+ local orig = {}
+ -- Note: ignores trailing item without trailing `;`. Not using something
+ -- simpler in order to preserve empty items (stand for default path).
+ for s in orig_str:gmatch('[^;]*;') do
+ s = s:sub(1, -2) -- Strip trailing semicolon
+ orig[#orig + 1] = s
+ end
+ if key == 'path' then
+ -- /?.lua and /?/init.lua
+ pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}
+ else
+ local pathtrails = {}
+ for _, s in ipairs(orig) do
+ -- Find out path patterns. pathtrail should contain something like
+ -- /?.so, \?.dll. This allows not to bother determining what correct
+ -- suffixes are.
+ local pathtrail = s:match('[/\\][^/\\]*%?.*$')
+ if pathtrail and not pathtrails[pathtrail] then
+ pathtrails[pathtrail] = true
+ pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail
+ end
+ end
+ end
+ local new = {}
+ for _, rtp in ipairs(rtps) do
+ if not rtp:match(';') then
+ for _, pathtrail in pairs(pathtrails_ordered) do
+ local new_path = rtp .. sep .. 'lua' .. pathtrail
+ -- Always keep paths from &runtimepath at the start:
+ -- append them here disregarding orig possibly containing one of them.
+ new[#new + 1] = new_path
+ cur_nvim_paths[new_path] = true
+ end
+ end
+ end
+ for _, orig_path in ipairs(orig) do
+ -- Handle removing obsolete paths originating from &runtimepath: such
+ -- paths either belong to cur_nvim_paths and were already added above or
+ -- to last_nvim_paths and should not be added at all if corresponding
+ -- entry was removed from &runtimepath list.
+ if not (cur_nvim_paths[orig_path] or last_nvim_paths[orig_path]) then
+ new[#new + 1] = orig_path
+ end
+ end
+ package[key] = table.concat(new, ';')
+ end
+ last_nvim_paths = cur_nvim_paths
+end
+
+local function gsplit(s, sep, plain)
+ assert(type(s) == "string")
+ assert(type(sep) == "string")
+ assert(type(plain) == "boolean" or type(plain) == "nil")
+
+ local start = 1
+ local done = false
+
+ local function pass(i, j, ...)
+ if i then
+ assert(j+1 > start, "Infinite loop detected")
+ local seg = s:sub(start, i - 1)
+ start = j + 1
+ return seg, ...
+ else
+ done = true
+ return s:sub(start)
+ end
+ end
+
+ return function()
+ if done then
+ return
+ end
+ if sep == '' then
+ if start == #s then
+ done = true
+ end
+ return pass(start+1, start)
+ end
+ return pass(s:find(sep, start, plain))
+ end
+end
+
+local function split(s,sep,plain)
+ local t={} for c in gsplit(s, sep, plain) do table.insert(t,c) end
+ return t
+end
+
+local function trim(s)
+ assert(type(s) == "string", "Only strings can be trimmed")
+ local result = s:gsub("^%s+", ""):gsub("%s+$", "")
+ return result
+end
+
+local deepcopy
+
+local function id(v)
+ return v
+end
+
+local deepcopy_funcs = {
+ table = function(orig)
+ local copy = {}
+ for k, v in pairs(orig) do
+ copy[deepcopy(k)] = deepcopy(v)
+ end
+ return copy
+ end,
+ number = id,
+ string = id,
+ ['nil'] = id,
+ boolean = id,
+}
+
+deepcopy = function(orig)
+ return deepcopy_funcs[type(orig)](orig)
+end
+
+local function __index(table, key)
+ if key == "inspect" then
+ table.inspect = require("vim.inspect")
+ return table.inspect
+ end
+end
+
+local module = {
+ _update_package_paths = _update_package_paths,
+ _os_proc_children = _os_proc_children,
+ _os_proc_info = _os_proc_info,
+ _system = _system,
+ trim = trim,
+ split = split,
+ gsplit = gsplit,
+ deepcopy = deepcopy,
+}
+
+setmetatable(module, {
+ __index = __index
+})
+
+return module
diff --git a/src/nvim/macros.h b/src/nvim/macros.h
index 5f69fa2f6a..d447bff765 100644
--- a/src/nvim/macros.h
+++ b/src/nvim/macros.h
@@ -19,41 +19,27 @@
# define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#endif
-/*
- * Position comparisons
- */
-# define lt(a, b) (((a).lnum != (b).lnum) \
- ? (a).lnum < (b).lnum \
- : (a).col != (b).col \
- ? (a).col < (b).col \
- : (a).coladd < (b).coladd)
-# define ltp(a, b) (((a)->lnum != (b)->lnum) \
- ? (a)->lnum < (b)->lnum \
- : (a)->col != (b)->col \
- ? (a)->col < (b)->col \
- : (a)->coladd < (b)->coladd)
-# define equalpos(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col) && \
- ((a).coladd == (b).coladd))
-# define clearpos(a) {(a)->lnum = 0; (a)->col = 0; (a)->coladd = 0; }
-
-#define ltoreq(a, b) (lt(a, b) || equalpos(a, b))
+/// String with length
+///
+/// For use in functions which accept (char *s, size_t len) pair in arguments.
+///
+/// @param[in] s Static string.
+///
+/// @return `s, sizeof(s) - 1`
+#define S_LEN(s) (s), (sizeof(s) - 1)
-/*
- * lineempty() - return TRUE if the line is empty
- */
-#define lineempty(p) (*ml_get(p) == NUL)
+/// LINEEMPTY() - return TRUE if the line is empty
+#define LINEEMPTY(p) (*ml_get(p) == NUL)
-/*
- * bufempty() - return TRUE if the current buffer is empty
- */
-#define bufempty() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == \
+/// BUFEMPTY() - return TRUE if the current buffer is empty
+#define BUFEMPTY() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == \
NUL)
/*
* toupper() and tolower() that use the current locale.
* Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the
* range 0 - 255. toupper()/tolower() on some systems can't handle others.
- * Note: It is often better to use vim_tolower() and vim_toupper(), because many
+ * Note: It is often better to use mb_tolower() and mb_toupper(), because many
* toupper() and tolower() implementations only work for ASCII.
*/
#define TOUPPER_LOC toupper
@@ -73,11 +59,6 @@
/* Returns empty string if it is NULL. */
#define EMPTY_IF_NULL(x) ((x) ? (x) : (char_u *)"")
-/* macro version of chartab().
- * Only works with values 0-255!
- * Doesn't work for UTF-8 mode with chars >= 0x80. */
-#define CHARSIZE(c) (chartab[c] & CT_CELL_MASK)
-
/*
* Adjust chars in a language according to 'langmap' option.
* NOTE that there is no noticeable overhead if 'langmap' is not set.
@@ -90,7 +71,7 @@
do { \
if (*p_langmap \
&& (condition) \
- && (!p_lnr || (p_lnr && typebuf_maplen() == 0)) \
+ && (p_lrm || (vgetc_busy ? typebuf_maplen() == 0 : KeyTyped)) \
&& !KeyStuffed \
&& (c) >= 0) \
{ \
@@ -101,12 +82,6 @@
} \
} while (0)
-/*
- * vim_isbreak() is used very often if 'linebreak' is set, use a macro to make
- * it work fast.
- */
-#define vim_isbreak(c) (breakat_flags[(char_u)(c)])
-
#define WRITEBIN "wb" /* no CR-LF translation */
#define READBIN "rb"
#define APPENDBIN "ab"
@@ -116,8 +91,10 @@
/* mch_open_rw(): invoke os_open() with third argument for user R/W. */
#if defined(UNIX) /* open in rw------- mode */
# define mch_open_rw(n, f) os_open((n), (f), (mode_t)0600)
+#elif defined(WIN32)
+# define mch_open_rw(n, f) os_open((n), (f), S_IREAD | S_IWRITE)
#else
-# define mch_open_rw(n, f) os_open((n), (f), 0)
+# define mch_open_rw(n, f) os_open((n), (f), 0)
#endif
# define REPLACE_NORMAL(s) (((s) & REPLACE_FLAG) && !((s) & VREPLACE_FLAG))
@@ -127,43 +104,98 @@
/* Whether to draw the vertical bar on the right side of the cell. */
# define CURSOR_BAR_RIGHT (curwin->w_p_rl && (!(State & CMDLINE) || cmdmsg_rl))
-/*
- * mb_ptr_adv(): advance a pointer to the next character, taking care of
- * multi-byte characters if needed.
- * mb_ptr_back(): backup a pointer to the previous character, taking care of
- * multi-byte characters if needed.
- * MB_COPY_CHAR(f, t): copy one char from "f" to "t" and advance the pointers.
- * PTR2CHAR(): get character from pointer.
- */
-/* Get the length of the character p points to */
-# define MB_PTR2LEN(p) (has_mbyte ? (*mb_ptr2len)(p) : 1)
-/* Advance multi-byte pointer, skip over composing chars. */
-# define mb_ptr_adv(p) (p += has_mbyte ? (*mb_ptr2len)((char_u *)p) : 1)
-/* Advance multi-byte pointer, do not skip over composing chars. */
-# define mb_cptr_adv(p) (p += \
- enc_utf8 ? utf_ptr2len(p) : has_mbyte ? (*mb_ptr2len)(p) : 1)
-/* Backup multi-byte pointer. Only use with "p" > "s" ! */
-# define mb_ptr_back(s, p) (p -= has_mbyte ? ((*mb_head_off)((char_u *)s, (char_u *)p - 1) + 1) : 1)
-/* get length of multi-byte char, not including composing chars */
-# define mb_cptr2len(p) (enc_utf8 ? utf_ptr2len(p) : (*mb_ptr2len)(p))
-
-# define MB_COPY_CHAR(f, t) \
- if (has_mbyte) mb_copy_char((const char_u **)(&f), &t); \
- else *t++ = *f++
-# define MB_CHARLEN(p) (has_mbyte ? mb_charlen(p) : (int)STRLEN(p))
-# define MB_CHAR2LEN(c) (has_mbyte ? mb_char2len(c) : 1)
-# define PTR2CHAR(p) (has_mbyte ? mb_ptr2char(p) : (int)*(p))
+// MB_PTR_ADV(): advance a pointer to the next character, taking care of
+// multi-byte characters if needed.
+// MB_PTR_BACK(): backup a pointer to the previous character, taking care of
+// multi-byte characters if needed.
+// MB_COPY_CHAR(f, t): copy one char from "f" to "t" and advance the pointers.
+// PTR2CHAR(): get character from pointer.
+
+// Get the length of the character p points to
+# define MB_PTR2LEN(p) mb_ptr2len(p)
+// Advance multi-byte pointer, skip over composing chars.
+# define MB_PTR_ADV(p) (p += mb_ptr2len((char_u *)p))
+// Advance multi-byte pointer, do not skip over composing chars.
+# define MB_CPTR_ADV(p) (p += utf_ptr2len(p))
+// Backup multi-byte pointer. Only use with "p" > "s" !
+# define MB_PTR_BACK(s, p) \
+ (p -= utf_head_off((char_u *)s, (char_u *)p - 1) + 1)
+// get length of multi-byte char, not including composing chars
+# define MB_CPTR2LEN(p) utf_ptr2len(p)
+
+# define MB_COPY_CHAR(f, t) mb_copy_char((const char_u **)(&f), &t);
+
+# define MB_CHARLEN(p) mb_charlen(p)
+# define MB_CHAR2LEN(c) mb_char2len(c)
+# define PTR2CHAR(p) utf_ptr2char(p)
# define RESET_BINDING(wp) (wp)->w_p_scb = FALSE; (wp)->w_p_crb = FALSE
-/// Calculate the length of a C array.
+/// Calculate the length of a C array
+///
+/// This should be called with a real array. Calling this with a pointer is an
+/// error. A mechanism to detect many (though not all) of those errors at
+/// compile time is implemented. It works by the second division producing
+/// a division by zero in those cases (-Wdiv-by-zero in GCC).
+#define ARRAY_SIZE(arr) \
+ ((sizeof(arr)/sizeof((arr)[0])) \
+ / ((size_t)(!(sizeof(arr) % sizeof((arr)[0])))))
+
+/// Get last array entry
///
/// This should be called with a real array. Calling this with a pointer is an
-/// error. A mechanism to detect many (though not all) of those errors at compile
-/// time is implemented. It works by the second division producing a division by
-/// zero in those cases (-Wdiv-by-zero in GCC).
-#define ARRAY_SIZE(arr) ((sizeof(arr)/sizeof((arr)[0])) / ((size_t)(!(sizeof(arr) % sizeof((arr)[0])))))
+/// error.
+#define ARRAY_LAST_ENTRY(arr) (arr)[ARRAY_SIZE(arr) - 1]
+
+// Duplicated in os/win_defs.h to avoid include-order sensitivity.
+#define RGB_(r, g, b) ((r << 16) | (g << 8) | b)
+
+#define STR_(x) #x
+#define STR(x) STR_(x)
+
+#ifndef __has_attribute
+# define NVIM_HAS_ATTRIBUTE(x) 0
+#elif defined(__clang__) && __clang__ == 1 \
+ && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ <= 5))
+// Starting in Clang 3.6, __has_attribute was fixed to only report true for
+// GNU-style attributes. Prior to that, it reported true if _any_ backend
+// supported the attribute.
+# define NVIM_HAS_ATTRIBUTE(x) 0
+#else
+# define NVIM_HAS_ATTRIBUTE __has_attribute
+#endif
+
+#if NVIM_HAS_ATTRIBUTE(fallthrough)
+# define FALLTHROUGH __attribute__((fallthrough))
+#else
+# define FALLTHROUGH
+#endif
+
+// -V:STRUCT_CAST:641
+
+/// Change type of structure pointers: cast `struct a *` to `struct b *`
+///
+/// Used to silence PVS errors.
+///
+/// @param Type Structure to cast to.
+/// @param obj Object to cast.
+///
+/// @return ((Type *)obj).
+#define STRUCT_CAST(Type, obj) ((Type *)(obj))
+
+// Type of uv_buf_t.len is platform-dependent.
+// Related: https://github.com/libuv/libuv/pull/1236
+#if defined(WIN32)
+# define UV_BUF_LEN(x) (ULONG)(x)
+#else
+# define UV_BUF_LEN(x) (x)
+#endif
-#define RGB(r, g, b) ((r << 16) | (g << 8) | b)
+// Type of read()/write() `count` param is platform-dependent.
+#if defined(WIN32)
+# define IO_COUNT(x) (unsigned)(x)
+#else
+# define IO_COUNT(x) (x)
+#endif
#endif // NVIM_MACROS_H
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 64b5de8663..17f3a894d4 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.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
+
#define EXTERN
#include <assert.h>
#include <stdint.h>
@@ -20,6 +23,7 @@
#include "nvim/fold.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
+#include "nvim/highlight.h"
#include "nvim/iconv.h"
#include "nvim/if_cscope.h"
#ifdef HAVE_LOCALE_H
@@ -30,7 +34,6 @@
#include "nvim/memline.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/log.h"
#include "nvim/memory.h"
@@ -55,58 +58,59 @@
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
+#include "nvim/os/fileio.h"
#include "nvim/event/loop.h"
#include "nvim/os/signal.h"
#include "nvim/event/process.h"
-#include "nvim/msgpack_rpc/defs.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/msgpack_rpc/server.h"
#include "nvim/msgpack_rpc/channel.h"
+#include "nvim/api/ui.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/handle.h"
+#include "nvim/api/private/dispatch.h"
+#ifndef WIN32
+# include "nvim/os/pty_process_unix.h"
+#endif
+#include "nvim/api/vim.h"
-/* Maximum number of commands from + or -c arguments. */
+// Maximum number of commands from + or -c arguments.
#define MAX_ARG_CMDS 10
-/* values for "window_layout" */
-#define WIN_HOR 1 /* "-o" horizontally split windows */
-#define WIN_VER 2 /* "-O" vertically split windows */
-#define WIN_TABS 3 /* "-p" windows on tab pages */
+// values for "window_layout"
+#define WIN_HOR 1 // "-o" horizontally split windows
+#define WIN_VER 2 // "-O" vertically split windows
+#define WIN_TABS 3 // "-p" windows on tab pages
-/* Struct for various parameters passed between main() and other functions. */
+// Struct for various parameters passed between main() and other functions.
typedef struct {
int argc;
char **argv;
char *use_vimrc; // vimrc from -u argument
- int n_commands; /* no. of commands from + or -c */
+ int n_commands; // no. of commands from + or -c
char *commands[MAX_ARG_CMDS]; // commands from + or -c arg
- char_u cmds_tofree[MAX_ARG_CMDS]; /* commands that need free() */
- int n_pre_commands; /* no. of commands from --cmd */
+ char_u cmds_tofree[MAX_ARG_CMDS]; // commands that need free()
+ int n_pre_commands; // no. of commands from --cmd
char *pre_commands[MAX_ARG_CMDS]; // commands from --cmd argument
- int edit_type; /* type of editing to do */
- char_u *tagname; /* tag from -t argument */
- char_u *use_ef; /* 'errorfile' from -q argument */
+ int edit_type; // type of editing to do
+ char_u *tagname; // tag from -t argument
+ char_u *use_ef; // 'errorfile' from -q argument
- int want_full_screen;
bool input_isatty; // stdin is a terminal
bool output_isatty; // stdout is a terminal
bool err_isatty; // stderr is a terminal
- bool headless; // Dont try to start an user interface
- // or read/write to stdio(unless
- // embedding)
- int no_swap_file; /* "-n" argument used */
+ int no_swap_file; // "-n" argument used
int use_debug_break_level;
- int window_count; /* number of windows to use */
- int window_layout; /* 0, WIN_HOR, WIN_VER or WIN_TABS */
+ int window_count; // number of windows to use
+ int window_layout; // 0, WIN_HOR, WIN_VER or WIN_TABS
-#if !defined(UNIX)
- int literal; /* don't expand file names */
-#endif
- int diff_mode; /* start with 'diff' set */
+ int diff_mode; // start with 'diff' set
+
+ char *listen_addr; // --listen {address}
} mparm_T;
/* Values for edit_type. */
@@ -122,7 +126,7 @@ typedef struct {
Loop main_loop;
-static char *argv0;
+static char *argv0 = NULL;
// Error messages
static const char *err_arg_missing = N_("Argument missing after");
@@ -147,17 +151,21 @@ void event_init(void)
signal_init();
// finish mspgack-rpc initialization
channel_init();
- server_init();
+ remote_ui_init();
+ api_vim_init();
terminal_init();
}
-void event_teardown(void)
+/// @returns false if main_loop could not be closed gracefully
+bool event_teardown(void)
{
if (!main_loop.events) {
- return;
+ input_stop();
+ return true;
}
- queue_process_events(main_loop.events);
+ multiqueue_process_events(main_loop.events);
+ loop_poll_events(&main_loop, 0); // Drain thread_events, fast_events.
input_stop();
channel_teardown();
process_teardown(&main_loop);
@@ -166,7 +174,7 @@ void event_teardown(void)
signal_teardown();
terminal_teardown();
- loop_close(&main_loop);
+ return loop_close(&main_loop, true);
}
/// Performs early initialization.
@@ -177,12 +185,10 @@ void early_init(void)
log_init();
fs_init();
handle_init();
-
- (void)mb_init(); // init mb_bytelen_tab[] to ones
eval_init(); // init global variables
-
- // Init the table of Normal mode commands.
- init_normal_cmds();
+ init_path(argv0 ? argv0 : "nvim");
+ init_normal_cmds(); // Init the table of Normal mode commands.
+ highlight_init();
#if defined(HAVE_LOCALE_H)
// Setup to use the current locale (for ctype() and many other things).
@@ -216,21 +222,32 @@ void early_init(void)
#ifdef MAKE_LIB
int nvim_main(int argc, char **argv)
+#elif defined(WIN32)
+int wmain(int argc, wchar_t **argv_w) // multibyte args on Windows. #7060
#else
int main(int argc, char **argv)
#endif
{
- argv0 = (char *)path_tail((char_u *)argv[0]);
+#if defined(WIN32) && !defined(MAKE_LIB)
+ char **argv = xmalloc((size_t)argc * sizeof(char *));
+ for (int i = 0; i < argc; i++) {
+ char *buf = NULL;
+ utf16_to_utf8(argv_w[i], &buf);
+ assert(buf);
+ argv[i] = buf;
+ }
+#endif
+
+ argv0 = argv[0];
char_u *fname = NULL; // file name from command line
mparm_T params; // various parameters passed between
// main() and other functions.
- char_u *cwd = NULL; // current workding dir on startup
+ char_u *cwd = NULL; // current working dir on startup
time_init();
- /* Many variables are in "params" so that we can pass them to invoked
- * functions without a lot of arguments. "argc" and "argv" are also
- * copied, so that they can be changed. */
+ // Many variables are in `params` so that we can pass them around easily.
+ // `argc` and `argv` are also copied, so that they can be changed.
init_params(&params, argc, argv);
init_startuptime(&params);
@@ -240,19 +257,23 @@ int main(int argc, char **argv)
// Check if we have an interactive window.
check_and_set_isatty(&params);
- // Get the name with which Nvim was invoked, with and without path.
- set_vim_var_string(VV_PROGPATH, argv[0], -1);
- set_vim_var_string(VV_PROGNAME, (char *) path_tail((char_u *) argv[0]), -1);
-
event_init();
- /*
- * Process the command line arguments. File names are put in the global
- * argument list "global_alist".
- */
+ // Process the command line arguments. File names are put in the global
+ // argument list "global_alist".
command_line_scan(&params);
- if (GARGCOUNT > 0)
- fname = get_fname(&params);
+ if (embedded_mode) {
+ const char *err;
+ if (!channel_from_stdio(true, CALLBACK_READER_INIT, &err)) {
+ abort();
+ }
+ }
+
+ server_init(params.listen_addr);
+
+ if (GARGCOUNT > 0) {
+ fname = get_fname(&params, cwd);
+ }
TIME_MSG("expanding arguments");
@@ -262,57 +283,53 @@ int main(int argc, char **argv)
/* Don't redraw until much later. */
++RedrawingDisabled;
- /*
- * When listing swap file names, don't do cursor positioning et. al.
- */
- if (recoverymode && fname == NULL)
- params.want_full_screen = FALSE;
-
setbuf(stdout, NULL);
- /* This message comes before term inits, but after setting "silent_mode"
- * when the input is not a tty. */
- if (GARGCOUNT > 1 && !silent_mode)
- printf(_("%d files to edit\n"), GARGCOUNT);
+ full_screen = !silent_mode;
- full_screen = true;
- check_tty(&params);
-
- /*
- * Set the default values for the options that use Rows and Columns.
- */
+ // Set the default values for the options that use Rows and Columns.
win_init_size();
// Set the 'diff' option now, so that it can be checked for in a vimrc
// file. There is no buffer yet though.
- if (params.diff_mode)
- diff_win_options(firstwin, FALSE);
+ if (params.diff_mode) {
+ diff_win_options(firstwin, false);
+ }
assert(p_ch >= 0 && Rows >= p_ch && Rows - p_ch <= INT_MAX);
cmdline_row = (int)(Rows - p_ch);
msg_row = cmdline_row;
- screenalloc(false); /* allocate screen buffers */
- set_init_2();
+ screenalloc(false); // allocate screen buffers
+ set_init_2(headless_mode);
TIME_MSG("inits 2");
- msg_scroll = TRUE;
- no_wait_return = TRUE;
+ msg_scroll = true;
+ no_wait_return = true;
- init_highlight(TRUE, FALSE); /* set the default highlight groups */
+ init_highlight(true, false); // Default highlight groups.
TIME_MSG("init highlight");
- /* Set the break level after the terminal is initialized. */
+ // Set the break level after the terminal is initialized.
debug_break_level = params.use_debug_break_level;
- bool reading_input = !params.headless && (params.input_isatty
- || params.output_isatty || params.err_isatty);
-
- if (reading_input) {
+ //
+ // Read user-input if any TTY is connected.
+ // Read ex-commands if invoked with "-es".
+ //
+ bool reading_tty = !headless_mode
+ && !embedded_mode
+ && !silent_mode
+ && (params.input_isatty || params.output_isatty
+ || params.err_isatty);
+ bool reading_excmds = !params.input_isatty
+ && silent_mode
+ && exmode_active == EXMODE_NORMAL;
+ if (reading_tty || reading_excmds) {
// One of the startup commands (arguments, sourced scripts or plugins) may
// prompt the user, so start reading from a tty now.
- int fd = fileno(stdin);
- if (!params.input_isatty || params.edit_type == EDIT_STDIN) {
- // Use stderr or stdout since stdin is not a tty and/or could be used to
- // read the "-" file (eg: cat file | nvim -)
+ int fd = STDIN_FILENO;
+ if (!silent_mode
+ && (!params.input_isatty || params.edit_type == EDIT_STDIN)) {
+ // Use stderr or stdout since stdin is being used to read commands.
fd = params.err_isatty ? fileno(stderr) : fileno(stdout);
}
input_start(fd);
@@ -320,24 +337,50 @@ int main(int argc, char **argv)
// open terminals when opening files that start with term://
#define PROTO "term://"
+ do_cmdline_cmd("augroup nvim_terminal");
+ do_cmdline_cmd("autocmd!");
do_cmdline_cmd("autocmd BufReadCmd " PROTO "* nested "
- ":call termopen( "
+ ":if !exists('b:term_title')|call termopen( "
// Capture the command string
"matchstr(expand(\"<amatch>\"), "
"'\\c\\m" PROTO "\\%(.\\{-}//\\%(\\d\\+:\\)\\?\\)\\?\\zs.*'), "
// capture the working directory
"{'cwd': get(matchlist(expand(\"<amatch>\"), "
- "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})");
+ "'\\c\\m" PROTO "\\(.\\{-}\\)//'), 1, '')})"
+ "|endif");
+ do_cmdline_cmd("augroup END");
#undef PROTO
- /* Execute --cmd arguments. */
+ // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments.
+ // Allows for setting 'loadplugins' there.
+ if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE")) {
+ p_lpl = false;
+ }
+
+ // give embedders a chance to set up nvim, by processing a request before
+ // startup. This allows an external UI to show messages and prompts from
+ // --cmd and buffer loading (e.g. swap files)
+ bool early_ui = false;
+ if (embedded_mode && !headless_mode) {
+ TIME_MSG("waiting for embedder to make request");
+ remote_ui_wait_for_attach();
+ TIME_MSG("done waiting for embedder");
+
+ // prepare screen now, so external UIs can display messages
+ starting = NO_BUFFERS;
+ screenclear();
+ early_ui = true;
+ TIME_MSG("initialized screen early for embedder");
+ }
+
+ // Execute --cmd arguments.
exe_pre_commands(&params);
- /* Source startup scripts. */
+ // Source startup scripts.
source_startup_scripts(&params);
// If using the runtime (-u is not NONE), enable syntax & filetype plugins.
- if (params.use_vimrc == NULL || strcmp(params.use_vimrc, "NONE") != 0) {
+ if (params.use_vimrc == NULL || !strequal(params.use_vimrc, "NONE")) {
// Does ":filetype plugin indent on".
filetype_maybe_enable();
// Sources syntax/syntax.vim, which calls `:filetype on`.
@@ -363,17 +406,21 @@ int main(int argc, char **argv)
mch_exit(0);
}
- // Set a few option defaults after reading vimrc files:
- // 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'.
+ // Set a few option defaults after reading vimrc files: 'title', 'icon',
+ // 'shellpipe', 'shellredir'.
set_init_3();
TIME_MSG("inits 3");
- /*
- * "-n" argument: Disable swap file by setting 'updatecount' to 0.
- * Note that this overrides anything from a vimrc file.
- */
- if (params.no_swap_file)
+ // "-n" argument: Disable swap file by setting 'updatecount' to 0.
+ // Note that this overrides anything from a vimrc file.
+ if (params.no_swap_file) {
p_uc = 0;
+ }
+
+ // XXX: Minimize 'updatetime' for -es/-Es. #7679
+ if (silent_mode) {
+ p_ut = 1;
+ }
if (curwin->w_p_rl && p_altkeymap) {
p_hkmap = FALSE; /* Reset the Hebrew keymap mode */
@@ -389,9 +436,10 @@ int main(int argc, char **argv)
shada_read_everything(NULL, false, true);
TIME_MSG("reading ShaDa");
}
- /* It's better to make v:oldfiles an empty list than NULL. */
- if (get_vim_var_list(VV_OLDFILES) == NULL)
- set_vim_var_list(VV_OLDFILES, list_alloc());
+ // It's better to make v:oldfiles an empty list than NULL.
+ if (get_vim_var_list(VV_OLDFILES) == NULL) {
+ set_vim_var_list(VV_OLDFILES, tv_list_alloc(0));
+ }
/*
* "-q errorfile": Load the error file now.
@@ -405,48 +453,48 @@ int main(int argc, char **argv)
* Clear screen now, so file message will not be cleared.
*/
starting = NO_BUFFERS;
- no_wait_return = FALSE;
- if (!exmode_active)
- msg_scroll = FALSE;
+ no_wait_return = false;
+ if (!exmode_active) {
+ msg_scroll = false;
+ }
- /*
- * If "-" argument given: Read file from stdin.
- * Do this before starting Raw mode, because it may change things that the
- * writing end of the pipe doesn't like, e.g., in case stdin and stderr
- * are the same terminal: "cat | vim -".
- * Using autocommands here may cause trouble...
- */
- if (params.edit_type == EDIT_STDIN && !recoverymode)
+ // Read file (text, not commands) from stdin if:
+ // - stdin is not a tty
+ // - and -e/-es was not given
+ //
+ // Do this before starting Raw mode, because it may change things that the
+ // writing end of the pipe doesn't like, e.g., in case stdin and stderr
+ // are the same terminal: "cat | vim -".
+ // Using autocommands here may cause trouble...
+ if (params.edit_type == EDIT_STDIN && !recoverymode) {
read_stdin();
+ }
-
- if (reading_input && (need_wait_return || msg_didany)) {
- // Since at this point there's no UI instance running yet, error messages
- // would have been printed to stdout. Before starting (which can result in
- // a alternate screen buffer being shown) we need confirmation that the
- // user has seen the messages and that is done with a call to wait_return.
+ if (reading_tty && (need_wait_return || msg_didany)) {
+ // Because there's no UI yet, error messages would have been printed to
+ // stdout. Before starting we need confirmation that the user has seen the
+ // messages and that is done with a call to wait_return.
TIME_MSG("waiting for return");
- wait_return(TRUE);
+ wait_return(true);
}
- if (!params.headless) {
- // Stop reading from input stream, the UI layer will take over now.
- input_stop();
+ if (!headless_mode && !embedded_mode && !silent_mode) {
+ input_stop(); // Stop reading input, let the UI take over.
ui_builtin_start();
}
setmouse(); // may start using the mouse
- ui_reset_scroll_region(); // In case Rows changed
- // Don't clear the screen when starting in Ex mode, unless using the GUI.
- if (exmode_active)
+ if (exmode_active || early_ui) {
+ // Don't clear the screen when starting in Ex mode, or when an
+ // embedding UI might have displayed messages
must_redraw = CLEAR;
- else {
- screenclear(); /* clear screen */
+ } else {
+ screenclear(); // clear screen
TIME_MSG("clearing screen");
}
- no_wait_return = TRUE;
+ no_wait_return = true;
/*
* Create the requested number of windows and edit buffers in them.
@@ -513,9 +561,16 @@ int main(int argc, char **argv)
if (p_im)
need_start_insertmode = TRUE;
- apply_autocmds(EVENT_VIMENTER, NULL, NULL, FALSE, curbuf);
+ set_vim_var_nr(VV_VIM_DID_ENTER, 1L);
+ apply_autocmds(EVENT_VIMENTER, NULL, NULL, false, curbuf);
TIME_MSG("VimEnter autocommands");
+ // Adjust default register name for "unnamed" in 'clipboard'. Can only be
+ // done after the clipboard is available and all initial commands that may
+ // modify the 'clipboard' setting have run; i.e. just before entering the
+ // main loop.
+ set_reg_var(get_default_register_name());
+
/* When a startup script or session file setup for diff'ing and
* scrollbind, sync the scrollbind now. */
if (curwin->w_p_diff && curwin->w_p_scb) {
@@ -535,18 +590,22 @@ int main(int argc, char **argv)
}
TIME_MSG("before starting main loop");
- ILOG("Starting Neovim main loop.");
+ ILOG("starting main loop");
/*
* Call the main command loop. This never returns.
*/
normal_enter(false, false);
+#if defined(WIN32) && !defined(MAKE_LIB)
+ xfree(argv);
+#endif
return 0;
}
-/* Exit properly */
+/// Exit properly
void getout(int exitval)
+ FUNC_ATTR_NORETURN
{
tabpage_T *tp, *next_tp;
@@ -558,6 +617,8 @@ void getout(int exitval)
if (exmode_active)
exitval += ex_exitval;
+ set_vim_var_nr(VV_EXITING, exitval);
+
/* Position the cursor on the last screen line, below all the text */
ui_cursor_goto((int)Rows - 1, 0);
@@ -575,11 +636,16 @@ void getout(int exitval)
}
buf_T *buf = wp->w_buffer;
- if (buf->b_changedtick != -1) {
+ if (buf_get_changedtick(buf) != -1) {
+ bufref_T bufref;
+
+ set_bufref(&bufref, buf);
apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
- buf->b_fname, FALSE, buf);
- buf->b_changedtick = -1; /* note that we did it already */
- /* start all over, autocommands may mess up the lists */
+ buf->b_fname, false, buf);
+ if (bufref_valid(&bufref)) {
+ buf_set_changedtick(buf, -1); // note that we did it already
+ }
+ // start all over, autocommands may mess up the lists
next_tp = first_tabpage;
break;
}
@@ -589,10 +655,13 @@ void getout(int exitval)
/* Trigger BufUnload for buffers that are loaded */
FOR_ALL_BUFFERS(buf) {
if (buf->b_ml.ml_mfp != NULL) {
- apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname,
- FALSE, buf);
- if (!buf_valid(buf)) /* autocmd may delete the buffer */
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, false, buf);
+ if (!bufref_valid(&bufref)) {
+ // Autocmd deleted the buffer.
break;
+ }
}
}
apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
@@ -618,12 +687,18 @@ void getout(int exitval)
/* Position the cursor again, the autocommands may have moved it */
ui_cursor_goto((int)Rows - 1, 0);
+ // Apply 'titleold'.
+ if (p_title && *p_titleold != NUL) {
+ ui_call_set_title(cstr_as_string((char *)p_titleold));
+ }
+
#if defined(USE_ICONV) && defined(DYNAMIC_ICONV)
iconv_end();
#endif
cs_end();
- if (garbage_collect_at_exit)
- garbage_collect();
+ if (garbage_collect_at_exit) {
+ garbage_collect(false);
+ }
mch_exit(exitval);
}
@@ -641,8 +716,9 @@ void getout(int exitval)
///
/// @return argument's numeric value otherwise
static int get_number_arg(const char *p, int *idx, int def)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (ascii_isdigit(p[*idx])) {
+ if (ascii_isdigit(p[*idx])) { // -V522
def = atoi(&(p[*idx]));
while (ascii_isdigit(p[*idx])) {
*idx = *idx + 1;
@@ -652,9 +728,7 @@ static int get_number_arg(const char *p, int *idx, int def)
}
#if defined(HAVE_LOCALE_H)
-/*
- * Setup to use the current locale (for ctype() and many other things).
- */
+/// Setup to use the current locale (for ctype() and many other things).
static void init_locale(void)
{
setlocale(LC_ALL, "");
@@ -670,8 +744,8 @@ static void init_locale(void)
{
char_u *p;
- /* expand_env() doesn't work yet, because chartab[] is not initialized
- * yet, call vim_getenv() directly */
+ // expand_env() doesn't work yet, because g_chartab[] is not
+ // initialized yet, call vim_getenv() directly
p = (char_u *)vim_getenv("VIMRUNTIME");
if (p != NULL && *p != NUL) {
vim_snprintf((char *)NameBuff, MAXPATHL, "%s/lang", p);
@@ -685,63 +759,72 @@ static void init_locale(void)
}
#endif
+/// Decides whether text (as opposed to commands) will be read from stdin.
+/// @see EDIT_STDIN
+static bool edit_stdin(bool explicit, mparm_T *parmp)
+{
+ bool implicit = !headless_mode
+ && !embedded_mode
+ && exmode_active != EXMODE_NORMAL // -E/-Es but not -e/-es.
+ && !parmp->input_isatty
+ && scriptin[0] == NULL; // `-s -` was not given.
+ return explicit || implicit;
+}
-/*
- * Scan the command line arguments.
- */
+/// Scan the command line arguments.
static void command_line_scan(mparm_T *parmp)
{
int argc = parmp->argc;
- char **argv = parmp->argv;
- int argv_idx; /* index in argv[n][] */
- int had_minmin = FALSE; /* found "--" argument */
- int want_argument; /* option argument with argument */
+ char **argv = parmp->argv;
+ int argv_idx; // index in argv[n][]
+ bool had_stdin_file = false; // found explicit "-" argument
+ bool had_minmin = false; // found "--" argument
+ int want_argument; // option argument with argument
int c;
- char_u *p = NULL;
long n;
- --argc;
- ++argv;
- argv_idx = 1; /* active option letter is argv[0][argv_idx] */
+ argc--;
+ argv++;
+ argv_idx = 1; // active option letter is argv[0][argv_idx]
while (argc > 0) {
- /*
- * "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
- */
+ // "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
if (argv[0][0] == '+' && !had_minmin) {
- if (parmp->n_commands >= MAX_ARG_CMDS)
+ if (parmp->n_commands >= MAX_ARG_CMDS) {
mainerr(err_extra_cmd, NULL);
- argv_idx = -1; /* skip to next argument */
- if (argv[0][1] == NUL)
+ }
+ argv_idx = -1; // skip to next argument
+ if (argv[0][1] == NUL) {
parmp->commands[parmp->n_commands++] = "$";
- else
+ } else {
parmp->commands[parmp->n_commands++] = &(argv[0][1]);
- }
- /*
- * Optional argument.
- */
- else if (argv[0][0] == '-' && !had_minmin) {
- want_argument = FALSE;
+ }
+
+ // Optional argument.
+ } else if (argv[0][0] == '-' && !had_minmin) {
+ want_argument = false;
c = argv[0][argv_idx++];
switch (c) {
- case NUL: /* "vim -" read from stdin */
+ case NUL: { // "nvim -" read from stdin
if (exmode_active) {
- // "ex -" silent mode
- silent_mode = TRUE;
+ // "nvim -e -" silent mode
+ silent_mode = true;
} else {
- if (parmp->edit_type != EDIT_NONE) {
+ if (parmp->edit_type != EDIT_NONE
+ && parmp->edit_type != EDIT_FILE
+ && parmp->edit_type != EDIT_STDIN) {
mainerr(err_too_many_args, argv[0]);
}
+ had_stdin_file = true;
parmp->edit_type = EDIT_STDIN;
}
- argv_idx = -1; /* skip to next argument */
+ argv_idx = -1; // skip to next argument
break;
-
- case '-': /* "--" don't take any more option arguments */
- /* "--help" give help message */
- /* "--version" give version message */
- /* "--literal" take files literally */
- /* "--noplugin[s]" skip plugins */
- /* "--cmd <cmd>" execute cmd before vimrc */
+ }
+ case '-': { // "--" don't take any more option arguments
+ // "--help" give help message
+ // "--version" give version message
+ // "--noplugin[s]" skip plugins
+ // "--cmd <cmd>" execute cmd before vimrc
if (STRICMP(argv[0] + argv_idx, "help") == 0) {
usage();
mch_exit(0);
@@ -749,337 +832,376 @@ static void command_line_scan(mparm_T *parmp)
version();
mch_exit(0);
} else if (STRICMP(argv[0] + argv_idx, "api-info") == 0) {
- msgpack_sbuffer* b = msgpack_sbuffer_new();
- msgpack_packer* p = msgpack_packer_new(b, msgpack_sbuffer_write);
- Object md = DICTIONARY_OBJ(api_metadata());
- msgpack_rpc_from_object(md, p);
+ FileDescriptor fp;
+ const int fof_ret = file_open_fd(&fp, STDOUT_FILENO,
+ kFileWriteOnly);
+ msgpack_packer *p = msgpack_packer_new(&fp, msgpack_file_write);
- for (size_t i = 0; i < b->size; i++) {
- putchar(b->data[i]);
+ if (fof_ret != 0) {
+ emsgf(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret));
}
+ if (p == NULL) {
+ EMSG(_(e_outofmem));
+ }
+
+ Object md = DICTIONARY_OBJ(api_metadata());
+ msgpack_rpc_from_object(md, p);
+
msgpack_packer_free(p);
+ const int ff_ret = file_flush(&fp);
+ if (ff_ret < 0) {
+ msgpack_file_write_error(ff_ret);
+ }
mch_exit(0);
} else if (STRICMP(argv[0] + argv_idx, "headless") == 0) {
- parmp->headless = true;
+ headless_mode = true;
} else if (STRICMP(argv[0] + argv_idx, "embed") == 0) {
embedded_mode = true;
- parmp->headless = true;
- channel_from_stdio();
+ } else if (STRNICMP(argv[0] + argv_idx, "listen", 6) == 0) {
+ want_argument = true;
+ argv_idx += 6;
} else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) {
-#if !defined(UNIX)
- parmp->literal = TRUE;
-#endif
- } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0)
- p_lpl = FALSE;
- else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) {
- want_argument = TRUE;
+ // Do nothing: file args are always literal. #7679
+ } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) {
+ p_lpl = false;
+ } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) {
+ want_argument = true;
argv_idx += 3;
} else if (STRNICMP(argv[0] + argv_idx, "startuptime", 11) == 0) {
- want_argument = TRUE;
+ want_argument = true;
argv_idx += 11;
} else {
if (argv[0][argv_idx])
mainerr(err_opt_unknown, argv[0]);
- had_minmin = TRUE;
+ had_minmin = true;
+ }
+ if (!want_argument) {
+ argv_idx = -1; // skip to next argument
}
- if (!want_argument)
- argv_idx = -1; /* skip to next argument */
break;
-
- case 'A': /* "-A" start in Arabic mode */
- set_option_value((char_u *)"arabic", 1L, NULL, 0);
+ }
+ case 'A': { // "-A" start in Arabic mode.
+ set_option_value("arabic", 1L, NULL, 0);
break;
-
- case 'b': /* "-b" binary mode */
- /* Needs to be effective before expanding file names, because
- * for Win32 this makes us edit a shortcut file itself,
- * instead of the file it links to. */
+ }
+ case 'b': { // "-b" binary mode.
+ // Needs to be effective before expanding file names, because
+ // for Win32 this makes us edit a shortcut file itself,
+ // instead of the file it links to.
set_options_bin(curbuf->b_p_bin, 1, 0);
- curbuf->b_p_bin = 1; /* binary file I/O */
+ curbuf->b_p_bin = 1; // Binary file I/O.
break;
+ }
- case 'e': /* "-e" Ex mode */
+ case 'D': { // "-D" Debugging
+ parmp->use_debug_break_level = 9999;
+ break;
+ }
+ case 'd': { // "-d" 'diff'
+ parmp->diff_mode = true;
+ break;
+ }
+ case 'e': { // "-e" Ex mode
exmode_active = EXMODE_NORMAL;
break;
-
- case 'E': /* "-E" Improved Ex mode */
+ }
+ case 'E': { // "-E" Ex mode
exmode_active = EXMODE_VIM;
break;
-
- case 'f': /* "-f" GUI: run in foreground. */
- break;
-
- case 'g': /* "-g" start GUI */
- main_start_gui();
+ }
+ case 'f': { // "-f" GUI: run in foreground.
break;
-
- case 'F': /* "-F" start in Farsi mode: rl + fkmap set */
- p_fkmap = TRUE;
- set_option_value((char_u *)"rl", 1L, NULL, 0);
+ }
+ case 'F': { // "-F" start in Farsi mode: rl + fkmap set.
+ p_fkmap = true;
+ set_option_value("rl", 1L, NULL, 0);
break;
-
- case 'h': /* "-h" give help message */
+ }
+ case '?': // "-?" give help message (for MS-Windows)
+ case 'h': { // "-h" give help message
usage();
mch_exit(0);
-
- case 'H': /* "-H" start in Hebrew mode: rl + hkmap set */
- p_hkmap = TRUE;
- set_option_value((char_u *)"rl", 1L, NULL, 0);
+ }
+ case 'H': { // "-H" start in Hebrew mode: rl + hkmap set.
+ p_hkmap = true;
+ set_option_value("rl", 1L, NULL, 0);
break;
-
- case 'l': /* "-l" lisp mode, 'lisp' and 'showmatch' on */
- set_option_value((char_u *)"lisp", 1L, NULL, 0);
- p_sm = TRUE;
+ }
+ case 'l': { // "-l" lisp mode, 'lisp' and 'showmatch' on.
+ set_option_value("lisp", 1L, NULL, 0);
+ p_sm = true;
break;
-
- case 'M': /* "-M" no changes or writing of files */
+ }
+ case 'M': { // "-M" no changes or writing of files
reset_modifiable();
- /* FALLTHROUGH */
-
- case 'm': /* "-m" no writing of files */
- p_write = FALSE;
+ FALLTHROUGH;
+ }
+ case 'm': { // "-m" no writing of files
+ p_write = false;
break;
+ }
- case 'N': /* "-N" Nocompatible */
- /* No-op */
+ case 'N': // "-N" Nocompatible
+ case 'X': // "-X" Do not connect to X server
+ // No-op
break;
- case 'n': /* "-n" no swap file */
- parmp->no_swap_file = TRUE;
+ case 'n': { // "-n" no swap file
+ parmp->no_swap_file = true;
break;
-
- case 'p': /* "-p[N]" open N tab pages */
-#ifdef TARGET_API_MAC_OSX
- /* For some reason on MacOS X, an argument like:
- -psn_0_10223617 is passed in when invoke from Finder
- or with the 'open' command */
- if (argv[0][argv_idx] == 's') {
- argv_idx = -1; /* bypass full -psn */
- main_start_gui();
- break;
- }
-#endif
- /* default is 0: open window for each file */
+ }
+ case 'p': { // "-p[N]" open N tab pages
+ // default is 0: open window for each file
parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
parmp->window_layout = WIN_TABS;
break;
-
- case 'o': /* "-o[N]" open N horizontal split windows */
- /* default is 0: open window for each file */
+ }
+ case 'o': { // "-o[N]" open N horizontal split windows
+ // default is 0: open window for each file
parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
parmp->window_layout = WIN_HOR;
break;
-
- case 'O': /* "-O[N]" open N vertical split windows */
- /* default is 0: open window for each file */
+ }
+ case 'O': { // "-O[N]" open N vertical split windows
+ // default is 0: open window for each file
parmp->window_count = get_number_arg(argv[0], &argv_idx, 0);
parmp->window_layout = WIN_VER;
break;
-
- case 'q': /* "-q" QuickFix mode */
- if (parmp->edit_type != EDIT_NONE)
+ }
+ case 'q': { // "-q" QuickFix mode
+ if (parmp->edit_type != EDIT_NONE) {
mainerr(err_too_many_args, argv[0]);
+ }
parmp->edit_type = EDIT_QF;
- if (argv[0][argv_idx]) { /* "-q{errorfile}" */
+ if (argv[0][argv_idx]) { // "-q{errorfile}"
parmp->use_ef = (char_u *)argv[0] + argv_idx;
argv_idx = -1;
- } else if (argc > 1) /* "-q {errorfile}" */
- want_argument = TRUE;
+ } else if (argc > 1) { // "-q {errorfile}"
+ want_argument = true;
+ }
break;
-
- case 'R': /* "-R" readonly mode */
- readonlymode = TRUE;
- curbuf->b_p_ro = TRUE;
- p_uc = 10000; /* don't update very often */
+ }
+ case 'R': { // "-R" readonly mode
+ readonlymode = true;
+ curbuf->b_p_ro = true;
+ p_uc = 10000; // don't update very often
break;
-
- case 'r': /* "-r" recovery mode */
- case 'L': /* "-L" recovery mode */
+ }
+ case 'r': // "-r" recovery mode
+ case 'L': { // "-L" recovery mode
recoverymode = 1;
break;
-
- case 's':
- if (exmode_active) /* "-s" silent (batch) mode */
- silent_mode = TRUE;
- else /* "-s {scriptin}" read from script file */
- want_argument = TRUE;
+ }
+ case 's': {
+ if (exmode_active) { // "-es" silent (batch) Ex-mode
+ silent_mode = true;
+ } else { // "-s {scriptin}" read from script file
+ want_argument = true;
+ }
break;
-
- case 't': /* "-t {tag}" or "-t{tag}" jump to tag */
- if (parmp->edit_type != EDIT_NONE)
+ }
+ case 't': { // "-t {tag}" or "-t{tag}" jump to tag
+ if (parmp->edit_type != EDIT_NONE) {
mainerr(err_too_many_args, argv[0]);
+ }
parmp->edit_type = EDIT_TAG;
- if (argv[0][argv_idx]) { /* "-t{tag}" */
+ if (argv[0][argv_idx]) { // "-t{tag}"
parmp->tagname = (char_u *)argv[0] + argv_idx;
argv_idx = -1;
- } else /* "-t {tag}" */
- want_argument = TRUE;
- break;
-
- case 'D': /* "-D" Debugging */
- parmp->use_debug_break_level = 9999;
- break;
- case 'd': /* "-d" 'diff' */
- parmp->diff_mode = TRUE;
+ } else { // "-t {tag}"
+ want_argument = true;
+ }
break;
- case 'v':
+ }
+ case 'v': {
version();
mch_exit(0);
- case 'V': /* "-V{N}" Verbose level */
- /* default is 10: a little bit verbose */
+ }
+ case 'V': { // "-V{N}" Verbose level
+ // default is 10: a little bit verbose
p_verbose = get_number_arg(argv[0], &argv_idx, 10);
if (argv[0][argv_idx] != NUL) {
- set_option_value((char_u *)"verbosefile", 0L,
- (char_u *)argv[0] + argv_idx, 0);
+ set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0);
argv_idx = (int)STRLEN(argv[0]);
}
break;
-
- case 'w': /* "-w{number}" set window height */
- /* "-w {scriptout}" write to script */
+ }
+ case 'w': { // "-w{number}" set window height
+ // "-w {scriptout}" write to script
if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) {
n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value((char_u *)"window", n, NULL, 0);
+ set_option_value("window", n, NULL, 0);
break;
}
- want_argument = TRUE;
+ want_argument = true;
break;
-
- case 'Z': /* "-Z" restricted mode */
- restricted = TRUE;
+ }
+ case 'Z': { // "-Z" restricted mode
+ restricted = true;
break;
+ }
- case 'c': /* "-c{command}" or "-c {command}" execute
- command */
+ case 'c': { // "-c{command}" or "-c {command}" exec command
if (argv[0][argv_idx] != NUL) {
- if (parmp->n_commands >= MAX_ARG_CMDS)
+ if (parmp->n_commands >= MAX_ARG_CMDS) {
mainerr(err_extra_cmd, NULL);
- parmp->commands[parmp->n_commands++] = argv[0]
- + argv_idx;
+ }
+ parmp->commands[parmp->n_commands++] = argv[0] + argv_idx;
argv_idx = -1;
break;
}
- /*FALLTHROUGH*/
- case 'S': /* "-S {file}" execute Vim script */
- case 'i': /* "-i {shada}" use for ShaDa file */
- case 'u': /* "-u {vimrc}" vim inits file */
- case 'U': /* "-U {gvimrc}" gvim inits file */
- case 'W': /* "-W {scriptout}" overwrite */
- want_argument = TRUE;
+ FALLTHROUGH;
+ }
+ case 'S': // "-S {file}" execute Vim script
+ case 'i': // "-i {shada}" use for ShaDa file
+ case 'u': // "-u {vimrc}" vim inits file
+ case 'U': // "-U {gvimrc}" gvim inits file
+ case 'W': { // "-W {scriptout}" overwrite
+ want_argument = true;
break;
+ }
- default:
+ default: {
mainerr(err_opt_unknown, argv[0]);
+ }
}
- /*
- * Handle option arguments with argument.
- */
+ // Handle option arguments with argument.
if (want_argument) {
- /*
- * Check for garbage immediately after the option letter.
- */
- if (argv[0][argv_idx] != NUL)
+ // Check for garbage immediately after the option letter.
+ if (argv[0][argv_idx] != NUL) {
mainerr(err_opt_garbage, argv[0]);
+ }
- --argc;
- if (argc < 1 && c != 'S') /* -S has an optional argument */
+ argc--;
+ if (argc < 1 && c != 'S') { // -S has an optional argument
mainerr(err_arg_missing, argv[0]);
- ++argv;
+ }
+ argv++;
argv_idx = -1;
switch (c) {
- case 'c': /* "-c {command}" execute command */
- case 'S': /* "-S {file}" execute Vim script */
- if (parmp->n_commands >= MAX_ARG_CMDS)
+ case 'c': // "-c {command}" execute command
+ case 'S': { // "-S {file}" execute Vim script
+ if (parmp->n_commands >= MAX_ARG_CMDS) {
mainerr(err_extra_cmd, NULL);
+ }
if (c == 'S') {
- char *a;
+ char *a;
- if (argc < 1)
- /* "-S" without argument: use default session file
- * name. */
+ if (argc < 1) {
+ // "-S" without argument: use default session file name.
a = SESSION_FILE;
- else if (argv[0][0] == '-') {
- /* "-S" followed by another option: use default
- * session file name. */
+ } else if (argv[0][0] == '-') {
+ // "-S" followed by another option: use default session file.
a = SESSION_FILE;
++argc;
--argv;
} else {
a = argv[0];
}
- char *s = xmalloc(STRLEN(a) + 4);
- sprintf(s, "so %s", a);
- parmp->cmds_tofree[parmp->n_commands] = TRUE;
+ size_t s_size = STRLEN(a) + 4;
+ char *s = xmalloc(s_size);
+ snprintf(s, s_size, "so %s", a);
+ parmp->cmds_tofree[parmp->n_commands] = true;
parmp->commands[parmp->n_commands++] = s;
} else {
parmp->commands[parmp->n_commands++] = argv[0];
}
break;
+ }
- case '-':
- if (argv[-1][2] == 'c') {
- /* "--cmd {command}" execute command */
- if (parmp->n_pre_commands >= MAX_ARG_CMDS)
+ case '-': {
+ if (strequal(argv[-1], "--cmd")) {
+ // "--cmd {command}" execute command
+ if (parmp->n_pre_commands >= MAX_ARG_CMDS) {
mainerr(err_extra_cmd, NULL);
+ }
parmp->pre_commands[parmp->n_pre_commands++] = argv[0];
+ } else if (strequal(argv[-1], "--listen")) {
+ // "--listen {address}"
+ parmp->listen_addr = argv[0];
}
- /* "--startuptime <file>" already handled */
+ // "--startuptime <file>" already handled
break;
+ }
- case 'q': /* "-q {errorfile}" QuickFix mode */
+ case 'q': { // "-q {errorfile}" QuickFix mode
parmp->use_ef = (char_u *)argv[0];
break;
+ }
- case 'i': /* "-i {shada}" use for shada */
+ case 'i': { // "-i {shada}" use for shada
used_shada_file = argv[0];
break;
+ }
- case 's': /* "-s {scriptin}" read from script file */
+ case 's': { // "-s {scriptin}" read from script file
if (scriptin[0] != NULL) {
scripterror:
- mch_errmsg(_("Attempt to open script file again: \""));
- mch_errmsg(argv[-1]);
- mch_errmsg(" ");
- mch_errmsg(argv[0]);
- mch_errmsg("\"\n");
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Attempt to open script file again: \"%s %s\"\n"),
+ argv[-1], argv[0]);
+ mch_errmsg((const char *)IObuff);
mch_exit(2);
}
- if ((scriptin[0] = mch_fopen(argv[0], READBIN)) == NULL) {
- mch_errmsg(_("Cannot open for reading: \""));
- mch_errmsg(argv[0]);
- mch_errmsg("\"\n");
+ int error;
+ if (strequal(argv[0], "-")) {
+ const int stdin_dup_fd = os_dup(STDIN_FILENO);
+#ifdef WIN32
+ // Replace the original stdin with the console input handle.
+ close(STDIN_FILENO);
+ const HANDLE conin_handle =
+ CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING, 0, (HANDLE)NULL);
+ const int conin_fd = _open_osfhandle(conin_handle, _O_RDONLY);
+ assert(conin_fd == STDIN_FILENO);
+#endif
+ FileDescriptor *const stdin_dup = file_open_fd_new(
+ &error, stdin_dup_fd, kFileReadOnly|kFileNonBlocking);
+ assert(stdin_dup != NULL);
+ scriptin[0] = stdin_dup;
+ } else if ((scriptin[0] = file_open_new(
+ &error, argv[0], kFileReadOnly|kFileNonBlocking, 0)) == NULL) {
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Cannot open for reading: \"%s\": %s\n"),
+ argv[0], os_strerror(error));
+ mch_errmsg((const char *)IObuff);
mch_exit(2);
}
save_typebuf();
break;
+ }
- case 't': /* "-t {tag}" */
+ case 't': { // "-t {tag}"
parmp->tagname = (char_u *)argv[0];
break;
-
- case 'u': /* "-u {vimrc}" vim inits file */
+ }
+ case 'u': { // "-u {vimrc}" vim inits file
parmp->use_vimrc = argv[0];
break;
-
- case 'U': /* "-U {gvimrc}" gvim inits file */
+ }
+ case 'U': { // "-U {gvimrc}" gvim inits file
break;
+ }
- case 'w': /* "-w {nr}" 'window' value */
- /* "-w {scriptout}" append to script file */
+ case 'w': { // "-w {nr}" 'window' value
+ // "-w {scriptout}" append to script file
if (ascii_isdigit(*((char_u *)argv[0]))) {
argv_idx = 0;
n = get_number_arg(argv[0], &argv_idx, 10);
- set_option_value((char_u *)"window", n, NULL, 0);
+ set_option_value("window", n, NULL, 0);
argv_idx = -1;
break;
}
- /*FALLTHROUGH*/
- case 'W': /* "-W {scriptout}" overwrite script file */
- if (scriptout != NULL)
+ FALLTHROUGH;
+ }
+ case 'W': { // "-W {scriptout}" overwrite script file
+ if (scriptout != NULL) {
goto scripterror;
+ }
if ((scriptout = mch_fopen(argv[0],
c == 'w' ? APPENDBIN : WRITEBIN)) == NULL) {
mch_errmsg(_("Cannot open for script output: \""));
@@ -1088,30 +1210,28 @@ scripterror:
mch_exit(2);
}
break;
-
+ }
}
}
- }
- /*
- * File name argument.
- */
- else {
- argv_idx = -1; /* skip to next argument */
-
- /* Check for only one type of editing. */
- if (parmp->edit_type != EDIT_NONE && parmp->edit_type != EDIT_FILE)
+ } else { // File name argument.
+ argv_idx = -1; // skip to next argument
+
+ // Check for only one type of editing.
+ if (parmp->edit_type != EDIT_NONE
+ && parmp->edit_type != EDIT_FILE
+ && parmp->edit_type != EDIT_STDIN) {
mainerr(err_too_many_args, argv[0]);
+ }
parmp->edit_type = EDIT_FILE;
- /* Add the file to the global argument list. */
+ // Add the file to the global argument list.
ga_grow(&global_alist.al_ga, 1);
- p = vim_strsave((char_u *)argv[0]);
+ char_u *p = vim_strsave((char_u *)argv[0]);
if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0
&& !os_isdir(alist_name(&GARGLIST[0]))) {
- char_u *r;
-
- r = (char_u *)concat_fnames((char *)p, (char *)path_tail(alist_name(&GARGLIST[0])), TRUE);
+ char_u *r = (char_u *)concat_fnames((char *)p,
+ (char *)path_tail(alist_name(&GARGLIST[0])), true);
xfree(p);
p = r;
}
@@ -1121,30 +1241,22 @@ scripterror:
path_fix_case(p);
#endif
- alist_add(&global_alist, p,
-#if !defined(UNIX)
- parmp->literal ? 2 : 0 /* add buffer nr after exp. */
-#else
- 2 /* add buffer number now and use curbuf */
-#endif
- );
-
+ int alist_fnum_flag = edit_stdin(had_stdin_file, parmp)
+ ? 1 // add buffer nr after exp.
+ : 2; // add buffer number now and use curbuf
+ alist_add(&global_alist, p, alist_fnum_flag);
}
- /*
- * If there are no more letters after the current "-", go to next
- * argument. argv_idx is set to -1 when the current argument is to be
- * skipped.
- */
+ // If there are no more letters after the current "-", go to next argument.
+ // argv_idx is set to -1 when the current argument is to be skipped.
if (argv_idx <= 0 || argv[0][argv_idx] == NUL) {
- --argc;
- ++argv;
+ argc--;
+ argv++;
argv_idx = 1;
}
}
- /* If there is a "+123" or "-c" command, set v:swapcommand to the first
- * one. */
+ // If there is a "+123" or "-c" command, set v:swapcommand to the first one.
if (parmp->n_commands > 0) {
const size_t swcmd_len = STRLEN(parmp->commands[0]) + 3;
char *const swcmd = xmalloc(swcmd_len);
@@ -1152,6 +1264,12 @@ scripterror:
set_vim_var_string(VV_SWAPCOMMAND, swcmd, -1);
xfree(swcmd);
}
+
+ // Handle "foo | nvim". EDIT_FILE may be overwritten now. #6299
+ if (edit_stdin(had_stdin_file, parmp)) {
+ parmp->edit_type = EDIT_STDIN;
+ }
+
TIME_MSG("parsing arguments");
}
@@ -1164,15 +1282,12 @@ static void init_params(mparm_T *paramp, int argc, char **argv)
memset(paramp, 0, sizeof(*paramp));
paramp->argc = argc;
paramp->argv = argv;
- paramp->headless = false;
- paramp->want_full_screen = true;
paramp->use_debug_break_level = -1;
paramp->window_count = -1;
+ paramp->listen_addr = NULL;
}
-/*
- * Initialize global startuptime file if "--startuptime" passed as an argument.
- */
+/// Initialize global startuptime file if "--startuptime" passed as an argument.
static void init_startuptime(mparm_T *paramp)
{
for (int i = 1; i < paramp->argc; i++) {
@@ -1188,36 +1303,46 @@ static void init_startuptime(mparm_T *paramp)
static void check_and_set_isatty(mparm_T *paramp)
{
- paramp->input_isatty = os_isatty(fileno(stdin));
- paramp->output_isatty = os_isatty(fileno(stdout));
- paramp->err_isatty = os_isatty(fileno(stderr));
+ stdin_isatty
+ = paramp->input_isatty = os_isatty(STDIN_FILENO);
+ stdout_isatty
+ = paramp->output_isatty = os_isatty(STDOUT_FILENO);
+ paramp->err_isatty = os_isatty(STDERR_FILENO);
+#ifndef WIN32
+ int tty_fd = paramp->input_isatty
+ ? STDIN_FILENO
+ : (paramp->output_isatty
+ ? STDOUT_FILENO
+ : (paramp->err_isatty ? STDERR_FILENO : -1));
+ pty_process_save_termios(tty_fd);
+#endif
TIME_MSG("window checked");
}
-/*
- * Get filename from command line, given that there is one.
- */
-static char_u *get_fname(mparm_T *parmp)
+
+// Sets v:progname and v:progpath. Also modifies $PATH on Windows.
+static void init_path(const char *exename)
+ FUNC_ATTR_NONNULL_ALL
{
-#if !defined(UNIX)
- /*
- * Expand wildcards in file names.
- */
- if (!parmp->literal) {
- cwd = xmalloc(MAXPATHL);
- if (cwd != NULL) {
- os_dirname(cwd, MAXPATHL);
- }
- // Temporarily add '(' and ')' to 'isfname'. These are valid
- // filename characters but are excluded from 'isfname' to make
- // "gf" work on a file name in parenthesis (e.g.: see vim.h).
- do_cmdline_cmd(":set isf+=(,)");
- alist_expand(NULL, 0);
- do_cmdline_cmd(":set isf&");
- if (cwd != NULL) {
- os_chdir((char *)cwd);
- }
+ char exepath[MAXPATHL] = { 0 };
+ size_t exepathlen = MAXPATHL;
+ // Make v:progpath absolute.
+ if (os_exepath(exepath, &exepathlen) != 0) {
+ // Fall back to argv[0]. Missing procfs? #6734
+ path_guess_exepath(exename, exepath, sizeof(exepath));
}
+ set_vim_var_string(VV_PROGPATH, exepath, -1);
+ set_vim_var_string(VV_PROGNAME, (char *)path_tail((char_u *)exename), -1);
+
+#ifdef WIN32
+ // Append the process start directory to $PATH, so that ":!foo" finds tools
+ // shipped with Windows package. This also mimics SearchPath().
+ os_setenv_append_path(exepath);
#endif
+}
+
+/// Get filename from command line, if any.
+static char_u *get_fname(mparm_T *parmp, char_u *cwd)
+{
return alist_name(&GARGLIST[0]);
}
@@ -1241,11 +1366,33 @@ static void set_window_layout(mparm_T *paramp)
static void load_plugins(void)
{
if (p_lpl) {
- source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL); // NOLINT
+ char_u *rtp_copy = NULL;
+
+ // First add all package directories to 'runtimepath', so that their
+ // autoload directories can be found. Only if not done already with a
+ // :packloadall command.
+ // Make a copy of 'runtimepath', so that source_runtime does not use the
+ // pack directories.
+ if (!did_source_packages) {
+ rtp_copy = vim_strsave(p_rtp);
+ add_pack_start_dirs();
+ }
+
+ source_in_path(rtp_copy == NULL ? p_rtp : rtp_copy,
+ (char_u *)"plugin/**/*.vim", // NOLINT
+ DIP_ALL | DIP_NOAFTER);
TIME_MSG("loading plugins");
+ xfree(rtp_copy);
- ex_packloadall(NULL);
+ // Only source "start" packages if not done already with a :packloadall
+ // command.
+ if (!did_source_packages) {
+ load_start_packages();
+ }
TIME_MSG("loading packages");
+
+ source_runtime((char_u *)"plugin/**/*.vim", DIP_ALL | DIP_AFTER);
+ TIME_MSG("loading after plugins");
}
}
@@ -1260,8 +1407,8 @@ static void handle_quickfix(mparm_T *paramp)
set_string_option_direct((char_u *)"ef", -1,
paramp->use_ef, OPT_FREE, SID_CARG);
vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef);
- if (qf_init(NULL, p_ef, p_efm, TRUE, IObuff) < 0) {
- ui_putc('\n');
+ if (qf_init(NULL, p_ef, p_efm, true, IObuff, p_menc) < 0) {
+ msg_putchar('\n');
mch_exit(3);
}
TIME_MSG("reading errorfile");
@@ -1287,55 +1434,23 @@ static void handle_tag(char_u *tagname)
}
}
-// Print a warning if stdout is not a terminal.
-// When starting in Ex mode and commands come from a file, set Silent mode.
-static void check_tty(mparm_T *parmp)
-{
- if (parmp->headless) {
- return;
- }
-
- // is active input a terminal?
- if (exmode_active) {
- if (!parmp->input_isatty) {
- silent_mode = true;
- }
- } else if (parmp->want_full_screen && (!parmp->err_isatty
- && (!parmp->output_isatty || !parmp->input_isatty))) {
-
- if (!parmp->output_isatty) {
- mch_errmsg(_("Vim: Warning: Output is not to a terminal\n"));
- }
-
- if (!parmp->input_isatty) {
- mch_errmsg(_("Vim: Warning: Input is not from a terminal\n"));
- }
-
- ui_flush();
-
- if (scriptin[0] == NULL) {
- os_delay(2000L, true);
- }
-
- TIME_MSG("Warning delay");
- }
-}
-
-/*
- * Read text from stdin.
- */
+/// Read text from stdin.
static void read_stdin(void)
{
- int i;
-
- /* When getting the ATTENTION prompt here, use a dialog */
+ // When getting the ATTENTION prompt here, use a dialog.
swap_exists_action = SEA_DIALOG;
- no_wait_return = TRUE;
- i = msg_didany;
- set_buflisted(TRUE);
- (void)open_buffer(TRUE, NULL, 0); /* create memfile and read file */
- no_wait_return = FALSE;
- msg_didany = i;
+ no_wait_return = true;
+ int save_msg_didany = msg_didany;
+ set_buflisted(true);
+ (void)open_buffer(true, NULL, 0); // create memfile and read file
+ if (BUFEMPTY() && curbuf->b_next != NULL) {
+ // stdin was empty, go to buffer 2 (e.g. "echo file1 | xargs nvim"). #8561
+ do_cmdline_cmd("silent! bnext");
+ // Delete the empty stdin buffer.
+ do_cmdline_cmd("bwipeout 1");
+ }
+ no_wait_return = false;
+ msg_didany = save_msg_didany;
TIME_MSG("reading stdin");
check_swap_exists_action();
}
@@ -1454,7 +1569,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
{
int arg_idx; /* index in argument list */
int i;
- int advance = TRUE;
+ bool advance = true;
win_T *win;
/*
@@ -1465,8 +1580,8 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
/* When w_arg_idx is -1 remove the window (see create_windows()). */
if (curwin->w_arg_idx == -1) {
- win_close(curwin, TRUE);
- advance = FALSE;
+ win_close(curwin, true);
+ advance = false;
}
arg_idx = 1;
@@ -1476,9 +1591,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
}
// When w_arg_idx is -1 remove the window (see create_windows()).
if (curwin->w_arg_idx == -1) {
- ++arg_idx;
- win_close(curwin, TRUE);
- advance = FALSE;
+ arg_idx++;
+ win_close(curwin, true);
+ advance = false;
continue;
}
@@ -1493,7 +1608,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
win_enter(curwin->w_next, false);
}
}
- advance = TRUE;
+ advance = true;
// Only open the file if there is no file in this window yet (that can
// happen when vimrc contains ":sall").
@@ -1512,12 +1627,13 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd)
did_emsg = FALSE; /* avoid hit-enter prompt */
getout(1);
}
- win_close(curwin, TRUE);
- advance = FALSE;
+ win_close(curwin, true);
+ advance = false;
}
- if (arg_idx == GARGCOUNT - 1)
- arg_had_last = TRUE;
- ++arg_idx;
+ if (arg_idx == GARGCOUNT - 1) {
+ arg_had_last = true;
+ }
+ arg_idx++;
}
os_breakcheck();
if (got_int) {
@@ -1605,6 +1721,48 @@ static void exe_commands(mparm_T *parmp)
TIME_MSG("executing command arguments");
}
+/// Source system-wide vimrc if built with one defined
+///
+/// Does one of the following things, stops after whichever succeeds:
+///
+/// 1. Source system vimrc file from $XDG_CONFIG_DIRS/nvim/sysinit.vim
+/// 2. Source system vimrc file from $VIM
+static void do_system_initialization(void)
+{
+ char *const config_dirs = stdpaths_get_xdg_var(kXDGConfigDirs);
+ if (config_dirs != NULL) {
+ const void *iter = NULL;
+ const char path_tail[] = {
+ 'n', 'v', 'i', 'm', PATHSEP,
+ 's', 'y', 's', 'i', 'n', 'i', 't', '.', 'v', 'i', 'm', NUL
+ };
+ do {
+ const char *dir;
+ size_t dir_len;
+ iter = vim_env_iter(':', config_dirs, iter, &dir, &dir_len);
+ if (dir == NULL || dir_len == 0) {
+ break;
+ }
+ char *vimrc = xmalloc(dir_len + sizeof(path_tail) + 1);
+ memcpy(vimrc, dir, dir_len);
+ vimrc[dir_len] = PATHSEP;
+ memcpy(vimrc + dir_len + 1, path_tail, sizeof(path_tail));
+ if (do_source((char_u *)vimrc, false, DOSO_NONE) != FAIL) {
+ xfree(vimrc);
+ xfree(config_dirs);
+ return;
+ }
+ xfree(vimrc);
+ } while (iter != NULL);
+ xfree(config_dirs);
+ }
+
+#ifdef SYS_VIMRC_FILE
+ // Get system wide defaults, if the file name is defined.
+ (void)do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE);
+#endif
+}
+
/// Source vimrc or do other user initialization
///
/// Does one of the following things, stops after whichever succeeds:
@@ -1620,7 +1778,7 @@ static bool do_user_initialization(void)
FUNC_ATTR_WARN_UNUSED_RESULT
{
bool do_exrc = p_exrc;
- if (process_env("VIMINIT", true) == OK) {
+ if (process_env("VIMINIT") == OK) {
do_exrc = p_exrc;
return do_exrc;
}
@@ -1641,7 +1799,7 @@ static bool do_user_initialization(void)
do {
const char *dir;
size_t dir_len;
- iter = vim_colon_env_iter(config_dirs, iter, &dir, &dir_len);
+ iter = vim_env_iter(':', config_dirs, iter, &dir, &dir_len);
if (dir == NULL || dir_len == 0) {
break;
}
@@ -1665,7 +1823,7 @@ static bool do_user_initialization(void)
} while (iter != NULL);
xfree(config_dirs);
}
- if (process_env("EXINIT", false) == OK) {
+ if (process_env("EXINIT") == OK) {
do_exrc = p_exrc;
return do_exrc;
}
@@ -1676,22 +1834,18 @@ static bool do_user_initialization(void)
static void source_startup_scripts(const mparm_T *const parmp)
FUNC_ATTR_NONNULL_ALL
{
- // If -u argument given, use only the initializations from that file and
- // nothing else.
+ // If -u given, use only the initializations from that file and nothing else.
if (parmp->use_vimrc != NULL) {
- if (strcmp(parmp->use_vimrc, "NONE") == 0
- || strcmp(parmp->use_vimrc, "NORC") == 0) {
- if (parmp->use_vimrc[2] == 'N')
- p_lpl = false; // don't load plugins either
+ if (strequal(parmp->use_vimrc, "NONE")
+ || strequal(parmp->use_vimrc, "NORC")) {
+ // Do nothing.
} else {
- if (do_source((char_u *)parmp->use_vimrc, FALSE, DOSO_NONE) != OK)
+ if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) {
EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc);
+ }
}
} else if (!silent_mode) {
-#ifdef SYS_VIMRC_FILE
- // Get system wide defaults, if the file name is defined.
- (void) do_source((char_u *)SYS_VIMRC_FILE, false, DOSO_NONE);
-#endif
+ do_system_initialization();
if (do_user_initialization()) {
// Read initialization commands from ".vimrc" or ".exrc" in current
@@ -1724,35 +1878,20 @@ static void source_startup_scripts(const mparm_T *const parmp)
}
secure = 0;
}
- did_source_startup_scripts = true;
TIME_MSG("sourcing vimrc file(s)");
}
-/*
- * Setup to start using the GUI. Exit with an error when not available.
- */
-static void main_start_gui(void)
-{
- mch_errmsg(_(e_nogvim));
- mch_errmsg("\n");
- mch_exit(2);
-}
-
-
/// Get an environment variable, and execute it as Ex commands.
///
/// @param env environment variable to execute
-/// @param is_viminit when true, called for VIMINIT
///
/// @return FAIL if the environment variable was not executed,
/// OK otherwise.
-static int process_env(char *env, bool is_viminit)
+static int process_env(char *env)
+ FUNC_ATTR_NONNULL_ALL
{
const char *initstr = os_getenv(env);
if (initstr != NULL) {
- if (is_viminit) {
- vimrc_found(NULL, NULL);
- }
char_u *save_sourcing_name = sourcing_name;
linenr_T save_sourcing_lnum = sourcing_lnum;
sourcing_name = (char_u *)env;
@@ -1762,7 +1901,7 @@ static int process_env(char *env, bool is_viminit)
do_cmdline_cmd((char *)initstr);
sourcing_name = save_sourcing_name;
sourcing_lnum = save_sourcing_lnum;
- current_SID = save_sid;;
+ current_SID = save_sid;
return OK;
}
return FAIL;
@@ -1774,6 +1913,7 @@ static int process_env(char *env, bool is_viminit)
/// os_fileinfo_link() respectively for extra security.
static bool file_owned(const char *fname)
{
+ assert(fname != NULL);
uid_t uid = getuid();
FileInfo file_info;
bool file_owned = os_fileinfo(fname, &file_info)
@@ -1792,9 +1932,11 @@ static bool file_owned(const char *fname)
/// @param str string to append to the primary error message, or NULL
static void mainerr(const char *errstr, const char *str)
{
+ char *prgname = (char *)path_tail((char_u *)argv0);
+
signal_stop(); // kill us with CTRL-C here, if you like
- mch_errmsg(argv0);
+ mch_errmsg(prgname);
mch_errmsg(": ");
mch_errmsg(_(errstr));
if (str != NULL) {
@@ -1803,7 +1945,7 @@ static void mainerr(const char *errstr, const char *str)
mch_errmsg("\"");
}
mch_errmsg(_("\nMore info with \""));
- mch_errmsg(argv0);
+ mch_errmsg(prgname);
mch_errmsg(" -h\"\n");
mch_exit(1);
@@ -1824,54 +1966,44 @@ static void usage(void)
signal_stop(); // kill us with CTRL-C here, if you like
mch_msg(_("Usage:\n"));
- mch_msg(_(" nvim [arguments] [file ...] Edit specified file(s)\n"));
- mch_msg(_(" nvim [arguments] - Read text from stdin\n"));
- mch_msg(_(" nvim [arguments] -t <tag> Edit file where tag is defined\n"));
- mch_msg(_(" nvim [arguments] -q [errorfile] Edit file with first error\n"));
- mch_msg(_("\nArguments:\n"));
+ mch_msg(_(" nvim [options] [file ...] Edit file(s)\n"));
+ mch_msg(_(" nvim [options] -t <tag> Edit file where tag is defined\n"));
+ mch_msg(_(" nvim [options] -q [errorfile] Edit file with first error\n"));
+ mch_msg(_("\nOptions:\n"));
mch_msg(_(" -- Only file names after this\n"));
-#if !defined(UNIX)
- mch_msg(_(" --literal Don't expand wildcards\n"));
-#endif
- mch_msg(_(" -e Ex mode\n"));
- mch_msg(_(" -E Improved Ex mode\n"));
- mch_msg(_(" -s Silent (batch) mode (only for ex mode)\n"));
+ mch_msg(_(" + Start at end of file\n"));
+ mch_msg(_(" --cmd <cmd> Execute <cmd> before any config\n"));
+ mch_msg(_(" +<cmd>, -c <cmd> Execute <cmd> after config and first file\n"));
+ mch_msg("\n");
+ mch_msg(_(" -b Binary mode\n"));
mch_msg(_(" -d Diff mode\n"));
- mch_msg(_(" -R Read-only mode\n"));
- mch_msg(_(" -Z Restricted mode\n"));
+ mch_msg(_(" -e, -E Ex mode\n"));
+ mch_msg(_(" -es, -Es Silent (batch) mode\n"));
+ mch_msg(_(" -h, --help Print this help message\n"));
+ mch_msg(_(" -i <shada> Use this shada file\n"));
mch_msg(_(" -m Modifications (writing files) not allowed\n"));
mch_msg(_(" -M Modifications in text not allowed\n"));
- mch_msg(_(" -b Binary mode\n"));
- mch_msg(_(" -l Lisp mode\n"));
- mch_msg(_(" -A Arabic mode\n"));
- mch_msg(_(" -F Farsi mode\n"));
- mch_msg(_(" -H Hebrew mode\n"));
- mch_msg(_(" -V[N][file] Be verbose [level N][log messages to file]\n"));
- mch_msg(_(" -D Debugging mode\n"));
mch_msg(_(" -n No swap file, use memory only\n"));
- mch_msg(_(" -r, -L List swap files and exit\n"));
- mch_msg(_(" -r <file> Recover crashed session\n"));
- mch_msg(_(" -u <vimrc> Use <vimrc> instead of the default\n"));
- mch_msg(_(" -i <shada> Use <shada> instead of the default\n"));
- mch_msg(_(" --noplugin Don't load plugin scripts\n"));
- mch_msg(_(" -o[N] Open N windows (default: one for each file)\n"));
- mch_msg(_(" -O[N] Like -o but split vertically\n"));
- mch_msg(_(" -p[N] Open N tab pages (default: one for each file)\n"));
- mch_msg(_(" + Start at end of file\n"));
- mch_msg(_(" +<linenum> Start at line <linenum>\n"));
- mch_msg(_(" +/<pattern> Start at first occurrence of <pattern>\n"));
- mch_msg(_(" --cmd <command> Execute <command> before loading any vimrc\n"));
- mch_msg(_(" -c <command> Execute <command> after loading the first file\n"));
+ mch_msg(_(" -o[N] Open N windows (default: one per file)\n"));
+ mch_msg(_(" -O[N] Open N vertical windows (default: one per file)\n"));
+ mch_msg(_(" -p[N] Open N tab pages (default: one per file)\n"));
+ mch_msg(_(" -r, -L List swap files\n"));
+ mch_msg(_(" -r <file> Recover edit state for this file\n"));
+ mch_msg(_(" -R Read-only mode\n"));
mch_msg(_(" -S <session> Source <session> after loading the first file\n"));
mch_msg(_(" -s <scriptin> Read Normal mode commands from <scriptin>\n"));
- mch_msg(_(" -w <scriptout> Append all typed characters to <scriptout>\n"));
- mch_msg(_(" -W <scriptout> Write all typed characters to <scriptout>\n"));
- mch_msg(_(" --startuptime <file> Write startup timing messages to <file>\n"));
- mch_msg(_(" --api-info Dump API metadata serialized to msgpack and exit\n"));
+ mch_msg(_(" -u <config> Use this config file\n"));
+ mch_msg(_(" -v, --version Print version information\n"));
+ mch_msg(_(" -V[N][file] Verbose [level][file]\n"));
+ mch_msg(_(" -Z Restricted mode\n"));
+ mch_msg("\n");
+ mch_msg(_(" --api-info Write msgpack-encoded API metadata to stdout\n"));
mch_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n"));
mch_msg(_(" --headless Don't start a user interface\n"));
- mch_msg(_(" -v, --version Print version information and exit\n"));
- mch_msg(_(" -h, --help Print this help message and exit\n"));
+ mch_msg(_(" --listen <address> Serve RPC API from this address\n"));
+ mch_msg(_(" --noplugin Don't load plugins\n"));
+ mch_msg(_(" --startuptime <file> Write startup timing messages to <file>\n"));
+ mch_msg(_("\nSee \":help startup-options\" for all options.\n"));
}
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 03439e7a9c..53ab734802 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.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 <stdlib.h>
#include <stdbool.h>
#include <string.h>
@@ -6,7 +9,7 @@
#include "nvim/map_defs.h"
#include "nvim/vim.h"
#include "nvim/memory.h"
-#include "nvim/msgpack_rpc/defs.h"
+#include "nvim/api/private/dispatch.h"
#include "nvim/lib/khash.h"
@@ -20,6 +23,8 @@
#define int_eq kh_int_hash_equal
#define linenr_T_hash kh_int_hash_func
#define linenr_T_eq kh_int_hash_equal
+#define handle_T_hash kh_int_hash_func
+#define handle_T_eq kh_int_hash_equal
#if defined(ARCH_64)
@@ -129,16 +134,36 @@ static inline khint_t String_hash(String s)
static inline bool String_eq(String a, String b)
{
- return strncmp(a.data, b.data, MIN(a.size, b.size)) == 0;
+ if (a.size != b.size) {
+ return false;
+ }
+ return memcmp(a.data, b.data, a.size) == 0;
+}
+
+static inline khint_t HlEntry_hash(HlEntry ae)
+{
+ const uint8_t *data = (const uint8_t *)&ae;
+ khint_t h = 0;
+ for (size_t i = 0; i < sizeof(ae); i++) {
+ h = (h << 5) - h + data[i];
+ }
+ return h;
+}
+
+static inline bool HlEntry_eq(HlEntry ae1, HlEntry ae2)
+{
+ return memcmp(&ae1, &ae2, sizeof(ae1)) == 0;
}
+
MAP_IMPL(int, int, DEFAULT_INITIALIZER)
-MAP_IMPL(cstr_t, uint64_t, DEFAULT_INITIALIZER)
MAP_IMPL(cstr_t, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(ptr_t, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(uint64_t, ptr_t, DEFAULT_INITIALIZER)
-#define MSGPACK_HANDLER_INITIALIZER {.fn = NULL, .async = false}
+MAP_IMPL(handle_T, ptr_t, DEFAULT_INITIALIZER)
+#define MSGPACK_HANDLER_INITIALIZER { .fn = NULL, .async = false }
MAP_IMPL(String, MsgpackRpcRequestHandler, MSGPACK_HANDLER_INITIALIZER)
#define KVEC_INITIALIZER { .size = 0, .capacity = 0, .items = NULL }
-MAP_IMPL(linenr_T, bufhl_vec_T, KVEC_INITIALIZER)
+MAP_IMPL(HlEntry, int, DEFAULT_INITIALIZER)
+MAP_IMPL(String, handle_T, 0)
diff --git a/src/nvim/map.h b/src/nvim/map.h
index c7d9894bd1..0e4308b953 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -5,8 +5,14 @@
#include "nvim/map_defs.h"
#include "nvim/api/private/defs.h"
-#include "nvim/msgpack_rpc/defs.h"
+#include "nvim/api/private/dispatch.h"
#include "nvim/bufhl_defs.h"
+#include "nvim/highlight_defs.h"
+
+#if defined(__NetBSD__)
+# undef uint64_t
+# define uint64_t uint64_t
+#endif
#define MAP_DECLS(T, U) \
KHASH_DECLARE(T##_##U##_map, T, U) \
@@ -25,12 +31,13 @@
void map_##T##_##U##_clear(Map(T, U) *map);
MAP_DECLS(int, int)
-MAP_DECLS(cstr_t, uint64_t)
MAP_DECLS(cstr_t, ptr_t)
MAP_DECLS(ptr_t, ptr_t)
MAP_DECLS(uint64_t, ptr_t)
+MAP_DECLS(handle_T, ptr_t)
MAP_DECLS(String, MsgpackRpcRequestHandler)
-MAP_DECLS(linenr_T, bufhl_vec_T)
+MAP_DECLS(HlEntry, int)
+MAP_DECLS(String, handle_T)
#define map_new(T, U) map_##T##_##U##_new
#define map_free(T, U) map_##T##_##U##_free
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index fe802e48ba..05f78c76bc 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.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
+
/*
* mark.c: functions for setting marks and jumping to them
*/
@@ -21,7 +24,6 @@
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/path.h"
@@ -63,7 +65,7 @@ int setmark(int c)
/// Free fmark_T item
void free_fmark(fmark_T fm)
{
- dict_unref(fm.additional_data);
+ tv_dict_unref(fm.additional_data);
}
/// Free xfmark_T item
@@ -104,44 +106,52 @@ int setmark_pos(int c, pos_T *pos, int fnum)
return OK;
}
+ // Can't set a mark in a non-existant buffer.
+ buf_T *buf = buflist_findnr(fnum);
+ if (buf == NULL) {
+ return FAIL;
+ }
+
if (c == '"') {
- RESET_FMARK(&curbuf->b_last_cursor, *pos, curbuf->b_fnum);
+ RESET_FMARK(&buf->b_last_cursor, *pos, buf->b_fnum);
return OK;
}
/* Allow setting '[ and '] for an autocommand that simulates reading a
* file. */
if (c == '[') {
- curbuf->b_op_start = *pos;
+ buf->b_op_start = *pos;
return OK;
}
if (c == ']') {
- curbuf->b_op_end = *pos;
+ buf->b_op_end = *pos;
return OK;
}
if (c == '<' || c == '>') {
- if (c == '<')
- curbuf->b_visual.vi_start = *pos;
- else
- curbuf->b_visual.vi_end = *pos;
- if (curbuf->b_visual.vi_mode == NUL)
- /* Visual_mode has not yet been set, use a sane default. */
- curbuf->b_visual.vi_mode = 'v';
+ if (c == '<') {
+ buf->b_visual.vi_start = *pos;
+ } else {
+ buf->b_visual.vi_end = *pos;
+ }
+ if (buf->b_visual.vi_mode == NUL) {
+ // Visual_mode has not yet been set, use a sane default.
+ buf->b_visual.vi_mode = 'v';
+ }
return OK;
}
- if (c > 'z') /* some islower() and isupper() cannot handle
- characters above 127 */
- return FAIL;
- if (islower(c)) {
+ if (ASCII_ISLOWER(c)) {
i = c - 'a';
- RESET_FMARK(curbuf->b_namedm + i, *pos, curbuf->b_fnum);
+ RESET_FMARK(buf->b_namedm + i, *pos, fnum);
return OK;
}
- if (isupper(c)) {
- assert(c >= 'A' && c <= 'Z');
- i = c - 'A';
+ if (ASCII_ISUPPER(c) || ascii_isdigit(c)) {
+ if (ascii_isdigit(c)) {
+ i = c - '0' + NMARKS;
+ } else {
+ i = c - 'A';
+ }
RESET_XFMARK(namedfm + i, *pos, fnum, NULL);
return OK;
}
@@ -163,6 +173,10 @@ void setpcmark(void)
curwin->w_prev_pcmark = curwin->w_pcmark;
curwin->w_pcmark = curwin->w_cursor;
+ if (curwin->w_pcmark.lnum == 0) {
+ curwin->w_pcmark.lnum = 1;
+ }
+
/* If jumplist is full: remove oldest entry */
if (++curwin->w_jumplistlen > JUMPLISTSIZE) {
curwin->w_jumplistlen = JUMPLISTSIZE;
@@ -346,13 +360,14 @@ pos_T *getmark_buf_fnum(buf_T *buf, int c, int changefile, int *fnum)
} else if (c == '<' || c == '>') { /* start/end of visual area */
startp = &buf->b_visual.vi_start;
endp = &buf->b_visual.vi_end;
- if ((c == '<') == lt(*startp, *endp))
+ if (((c == '<') == lt(*startp, *endp) || endp->lnum == 0)
+ && startp->lnum != 0) {
posp = startp;
- else
+ } else {
posp = endp;
- /*
- * For Visual line mode, set mark at begin or end of line
- */
+ }
+
+ // For Visual line mode, set mark at begin or end of line
if (buf->b_visual.vi_mode == 'V') {
pos_copy = *posp;
posp = &pos_copy;
@@ -474,7 +489,7 @@ static void fname2fnum(xfmark_T *fm)
os_dirname(IObuff, IOSIZE);
p = path_shorten_fname(NameBuff, IObuff);
- /* buflist_new() will call fmarks_check_names() */
+ // buflist_new() will call fmarks_check_names()
(void)buflist_new(NameBuff, p, (linenr_T)1, 0);
}
}
@@ -584,11 +599,12 @@ static char_u *mark_line(pos_T *mp, int lead_len)
if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count)
return vim_strsave((char_u *)"-invalid-");
assert(Columns >= 0 && (size_t)Columns <= SIZE_MAX);
- s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns);
+ // Allow for up to 5 bytes per character.
+ s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5);
- /* Truncate the line to fit it in the window */
+ // Truncate the line to fit it in the window
len = 0;
- for (p = s; *p != NUL; mb_ptr_adv(p)) {
+ for (p = s; *p != NUL; MB_PTR_ADV(p)) {
len += ptr2cells(p);
if (len >= Columns - lead_len)
break;
@@ -635,8 +651,8 @@ void do_marks(exarg_T *eap)
show_one_mark(-1, arg, NULL, NULL, false);
}
-static void
-show_one_mark (
+static void
+show_one_mark(
int c,
char_u *arg,
pos_T *p,
@@ -675,9 +691,10 @@ show_one_mark (
mustfree = TRUE;
}
if (name != NULL) {
- msg_outtrans_attr(name, current ? hl_attr(HLF_D) : 0);
- if (mustfree)
+ msg_outtrans_attr(name, current ? HL_ATTR(HLF_D) : 0);
+ if (mustfree) {
xfree(name);
+ }
}
}
ui_flush(); /* show one line at a time */
@@ -788,8 +805,8 @@ void ex_jumps(exarg_T *eap)
curwin->w_jumplist[i].fmark.mark.col);
msg_outtrans(IObuff);
msg_outtrans_attr(name,
- curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
- ? hl_attr(HLF_D) : 0);
+ curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
+ ? HL_ATTR(HLF_D) : 0);
xfree(name);
os_breakcheck();
}
@@ -799,6 +816,13 @@ void ex_jumps(exarg_T *eap)
MSG_PUTS("\n>");
}
+void ex_clearjumps(exarg_T *eap)
+{
+ free_jumplist(curwin);
+ curwin->w_jumplistlen = 0;
+ curwin->w_jumplistidx = 0;
+}
+
/*
* print the changelist
*/
@@ -807,7 +831,7 @@ void ex_changes(exarg_T *eap)
int i;
char_u *name;
- /* Highlight title */
+ // Highlight title
MSG_PUTS_TITLE(_("\nchange line col text"));
for (i = 0; i < curbuf->b_changelistlen && !got_int; ++i) {
@@ -823,7 +847,7 @@ void ex_changes(exarg_T *eap)
curbuf->b_changelist[i].mark.col);
msg_outtrans(IObuff);
name = mark_line(&curbuf->b_changelist[i].mark, 17);
- msg_outtrans_attr(name, hl_attr(HLF_D));
+ msg_outtrans_attr(name, HL_ATTR(HLF_D));
xfree(name);
os_breakcheck();
}
@@ -873,7 +897,29 @@ void ex_changes(exarg_T *eap)
* Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
* or: mark_adjust(56, 55, MAXLNUM, 2);
*/
-void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
+void mark_adjust(linenr_T line1,
+ linenr_T line2,
+ long amount,
+ long amount_after,
+ bool end_temp)
+{
+ mark_adjust_internal(line1, line2, amount, amount_after, true, end_temp);
+}
+
+// mark_adjust_nofold() does the same as mark_adjust() but without adjusting
+// folds in any way. Folds must be adjusted manually by the caller.
+// This is only useful when folds need to be moved in a way different to
+// calling foldMarkAdjust() with arguments line1, line2, amount, amount_after,
+// for an example of why this may be necessary, see do_move().
+void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount,
+ long amount_after, bool end_temp)
+{
+ mark_adjust_internal(line1, line2, amount, amount_after, false, end_temp);
+}
+
+static void mark_adjust_internal(linenr_T line1, linenr_T line2,
+ long amount, long amount_after,
+ bool adjust_folds, bool end_temp)
{
int i;
int fnum = curbuf->b_fnum;
@@ -914,15 +960,21 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
one_adjust_nodel(&(curbuf->b_visual.vi_start.lnum));
one_adjust_nodel(&(curbuf->b_visual.vi_end.lnum));
- /* quickfix marks */
- qf_mark_adjust(NULL, line1, line2, amount, amount_after);
- /* location lists */
+ // quickfix marks
+ if (!qf_mark_adjust(NULL, line1, line2, amount, amount_after)) {
+ curbuf->b_has_qf_entry &= ~BUF_HAS_QF_ENTRY;
+ }
+ // location lists
+ bool found_one = false;
FOR_ALL_TAB_WINDOWS(tab, win) {
- qf_mark_adjust(win, line1, line2, amount, amount_after);
+ found_one |= qf_mark_adjust(win, line1, line2, amount, amount_after);
+ }
+ if (!found_one) {
+ curbuf->b_has_qf_entry &= ~BUF_HAS_LL_ENTRY;
}
sign_mark_adjust(line1, line2, amount, amount_after);
- bufhl_mark_adjust(curbuf, line1, line2, amount, amount_after);
+ bufhl_mark_adjust(curbuf, line1, line2, amount, amount_after, end_temp);
}
/* previous context mark */
@@ -999,8 +1051,9 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after)
}
}
- /* adjust folds */
- foldMarkAdjust(win, line1, line2, amount, amount_after);
+ if (adjust_folds) {
+ foldMarkAdjust(win, line1, line2, amount, amount_after);
+ }
}
}
@@ -1401,3 +1454,30 @@ void free_all_marks(void)
memset(&namedfm[0], 0, sizeof(namedfm));
}
#endif
+
+/// Adjust position to point to the first byte of a multi-byte character
+///
+/// If it points to a tail byte it is move backwards to the head byte.
+///
+/// @param[in] buf Buffer to adjust position in.
+/// @param[out] lp Position to adjust.
+void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (lp->col > 0 || lp->coladd > 1) {
+ const char_u *const p = ml_get_buf(buf, lp->lnum, false);
+ if (*p == NUL || (int)STRLEN(p) < lp->col) {
+ lp->col = 0;
+ } else {
+ lp->col -= utf_head_off(p, p + lp->col);
+ }
+ // Reset "coladd" when the cursor would be on the right half of a
+ // double-wide character.
+ if (lp->coladd == 1
+ && p[lp->col] != TAB
+ && vim_isprintc(utf_ptr2char(p + lp->col))
+ && ptr2cells(p + lp->col) > 1) {
+ lp->coladd = 0;
+ }
+ }
+}
diff --git a/src/nvim/mark.h b/src/nvim/mark.h
index aff6e7273a..ed4e47907b 100644
--- a/src/nvim/mark.h
+++ b/src/nvim/mark.h
@@ -4,10 +4,12 @@
#include "nvim/macros.h"
#include "nvim/ascii.h"
#include "nvim/buffer_defs.h"
+#include "nvim/func_attr.h"
#include "nvim/mark_defs.h"
#include "nvim/memory.h"
#include "nvim/pos.h"
#include "nvim/os/time.h"
+#include "nvim/ex_cmds_defs.h" // for exarg_T
/// Set fmark using given value
#define SET_FMARK(fmarkp_, mark_, fnum_) \
@@ -29,7 +31,7 @@
/// Clear given fmark
#define CLEAR_FMARK(fmarkp_) \
- RESET_FMARK(fmarkp_, ((pos_T) {0, 0, 0}), 0)
+ RESET_FMARK(fmarkp_, ((pos_T) { 0, 0, 0 }), 0)
/// Set given extended mark (regular mark + file name)
#define SET_XFMARK(xfmarkp_, mark_, fnum_, fname_) \
@@ -74,6 +76,46 @@ static inline int mark_local_index(const char name)
: -1))));
}
+static inline bool lt(pos_T, pos_T) REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
+static inline bool equalpos(pos_T, pos_T)
+ REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
+static inline bool ltoreq(pos_T, pos_T)
+ REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
+static inline void clearpos(pos_T *)
+ REAL_FATTR_ALWAYS_INLINE;
+
+/// Return true if position a is before (less than) position b.
+static inline bool lt(pos_T a, pos_T b)
+{
+ if (a.lnum != b.lnum) {
+ return a.lnum < b.lnum;
+ } else if (a.col != b.col) {
+ return a.col < b.col;
+ } else {
+ return a.coladd < b.coladd;
+ }
+}
+
+/// Return true if position a and b are equal.
+static inline bool equalpos(pos_T a, pos_T b)
+{
+ return (a.lnum == b.lnum) && (a.col == b.col) && (a.coladd == b.coladd);
+}
+
+/// Return true if position a is less than or equal to b.
+static inline bool ltoreq(pos_T a, pos_T b)
+{
+ return lt(a, b) || equalpos(a, b);
+}
+
+/// Clear the pos_T structure pointed to by a.
+static inline void clearpos(pos_T *a)
+{
+ a->lnum = 0;
+ a->col = 0;
+ a->coladd = 0;
+}
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mark.h.generated.h"
#endif
diff --git a/src/nvim/mark_defs.h b/src/nvim/mark_defs.h
index 720b2475ed..2cb489501e 100644
--- a/src/nvim/mark_defs.h
+++ b/src/nvim/mark_defs.h
@@ -3,7 +3,7 @@
#include "nvim/pos.h"
#include "nvim/os/time.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
/*
* marks: positions in a file
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 0ba9f8b076..ead6b4405d 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -1,68 +1,30 @@
-/*
- * mbyte.c: Code specifically for handling multi-byte characters.
- * Multibyte extensions partly by Sung-Hoon Baek
- *
- * The encoding used in the core is set with 'encoding'. When 'encoding' is
- * changed, the following four variables are set (for speed).
- * Currently these types of character encodings are supported:
- *
- * "enc_dbcs" When non-zero it tells the type of double byte character
- * encoding (Chinese, Korean, Japanese, etc.).
- * The cell width on the display is equal to the number of
- * bytes. (exception: DBCS_JPNU with first byte 0x8e)
- * Recognizing the first or second byte is difficult, it
- * requires checking a byte sequence from the start.
- * "enc_utf8" When TRUE use Unicode characters in UTF-8 encoding.
- * The cell width on the display needs to be determined from
- * the character value.
- * Recognizing bytes is easy: 0xxx.xxxx is a single-byte
- * char, 10xx.xxxx is a trailing byte, 11xx.xxxx is a leading
- * byte of a multi-byte character.
- * To make things complicated, up to six composing characters
- * are allowed. These are drawn on top of the first char.
- * For most editing the sequence of bytes with composing
- * characters included is considered to be one character.
- * "enc_unicode" When 2 use 16-bit Unicode characters (or UTF-16).
- * When 4 use 32-but Unicode characters.
- * Internally characters are stored in UTF-8 encoding to
- * avoid NUL bytes. Conversion happens when doing I/O.
- * "enc_utf8" will also be TRUE.
- *
- * "has_mbyte" is set when "enc_dbcs" or "enc_utf8" is non-zero.
- *
- * If none of these is TRUE, 8-bit bytes are used for a character. The
- * encoding isn't currently specified (TODO).
- *
- * 'encoding' specifies the encoding used in the core. This is in registers,
- * text manipulation, buffers, etc. Conversion has to be done when characters
- * in another encoding are received or send:
- *
- * clipboard
- * ^
- * | (2)
- * V
- * +---------------+
- * (1) | | (3)
- * keyboard ----->| core |-----> display
- * | |
- * +---------------+
- * ^
- * | (4)
- * V
- * file
- *
- * (1) Typed characters arrive in the current locale.
- * (2) Text will be made available with the encoding specified with
- * 'encoding'. If this is not sufficient, system-specific conversion
- * might be required.
- * (3) For the GUI the correct font must be selected, no conversion done.
- * (4) The encoding of the file is specified with 'fileencoding'. Conversion
- * is to be done when it's different from 'encoding'.
- *
- * The ShaDa file is a special case: Only text is converted, not file names.
- * Vim scripts may contain an ":encoding" command. This has an effect for
- * some commands, like ":menutrans"
- */
+// 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
+
+/// mbyte.c: Code specifically for handling multi-byte characters.
+/// Multibyte extensions partly by Sung-Hoon Baek
+///
+/// The encoding used in nvim is always UTF-8. "enc_utf8" and "has_mbyte" is
+/// thus always true. "enc_dbcs" is always zero. The 'encoding' option is
+/// read-only and always reads "utf-8".
+///
+/// The cell width on the display needs to be determined from the character
+/// value. Recognizing UTF-8 bytes is easy: 0xxx.xxxx is a single-byte char,
+/// 10xx.xxxx is a trailing byte, 11xx.xxxx is a leading byte of a multi-byte
+/// character. To make things complicated, up to six composing characters
+/// are allowed. These are drawn on top of the first char. For most editing
+/// the sequence of bytes with composing characters included is considered to
+/// be one character.
+///
+/// UTF-8 is used everywhere in the core. This is in registers, text
+/// manipulation, buffers, etc. Nvim core communicates with external plugins
+/// and GUIs in this encoding.
+///
+/// The encoding of a file is specified with 'fileencoding'. Conversion
+/// is to be done when it's different from "utf-8".
+///
+/// Vim scripts may contain an ":scriptencoding" command. This has an effect
+/// for some commands, like ":menutrans".
#include <inttypes.h>
#include <stdbool.h>
@@ -75,6 +37,8 @@
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
+#include "nvim/eval.h"
+#include "nvim/path.h"
#include "nvim/iconv.h"
#include "nvim/mbyte.h"
#include "nvim/charset.h"
@@ -84,7 +48,6 @@
#include "nvim/memline.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/option.h"
#include "nvim/screen.h"
@@ -92,6 +55,7 @@
#include "nvim/strings.h"
#include "nvim/os/os.h"
#include "nvim/arabic.h"
+#include "nvim/mark.h"
typedef struct {
int rangeStart;
@@ -110,37 +74,52 @@ struct interval {
# include "unicode_tables.generated.h"
#endif
-/*
- * Lookup table to quickly get the length in bytes of a UTF-8 character from
- * the first byte of a UTF-8 string.
- * Bytes which are illegal when used as the first byte have a 1.
- * The NUL byte has length 1.
- */
-static char utf8len_tab[256] =
-{
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
+char_u e_loadlib[] = "E370: Could not load library %s";
+char_u e_loadfunc[] = "E448: Could not load library function %s";
+
+// To speed up BYTELEN(); keep a lookup table to quickly get the length in
+// bytes of a UTF-8 character from the first byte of a UTF-8 string. Bytes
+// which are illegal when used as the first byte have a 1. The NUL byte has
+// length 1.
+const uint8_t utf8len_tab[] = {
+ // ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B?
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C?
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // D?
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // E?
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1, // F?
};
-/*
- * Like utf8len_tab above, but using a zero for illegal lead bytes.
- */
-static uint8_t utf8len_tab_zero[256] =
-{
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0,
+// Like utf8len_tab above, but using a zero for illegal lead bytes.
+const uint8_t utf8len_tab_zero[] = {
+ // ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?A ?B ?C ?D ?E ?F
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6?
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A?
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B?
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C?
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // D?
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // E?
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0, // F?
};
/*
@@ -386,207 +365,6 @@ int enc_canon_props(const char_u *name)
}
/*
- * Set up for using multi-byte characters.
- * Called in three cases:
- * - by main() to initialize (p_enc == NULL)
- * - by set_init_1() after 'encoding' was set to its default.
- * - by do_set() when 'encoding' has been set.
- * p_enc must have been passed through enc_canonize() already.
- * Sets the "enc_unicode", "enc_utf8", "enc_dbcs" and "has_mbyte" flags.
- * Fills mb_bytelen_tab[] and returns NULL when there are no problems.
- * When there is something wrong: Returns an error message and doesn't change
- * anything.
- */
-char_u * mb_init(void)
-{
- int i;
- int idx;
- int n;
- int enc_dbcs_new = 0;
-#if defined(USE_ICONV) && !defined(WIN3264) && !defined(WIN32UNIX) \
- && !defined(MACOS)
-# define LEN_FROM_CONV
- vimconv_T vimconv;
- char_u *p;
-#endif
-
- if (p_enc == NULL) {
- /* Just starting up: set the whole table to one's. */
- for (i = 0; i < 256; ++i)
- mb_bytelen_tab[i] = 1;
- return NULL;
- } else if (STRNCMP(p_enc, "8bit-", 5) == 0
- || STRNCMP(p_enc, "iso-8859-", 9) == 0) {
- /* Accept any "8bit-" or "iso-8859-" name. */
- enc_unicode = 0;
- enc_utf8 = false;
- } else if (STRNCMP(p_enc, "2byte-", 6) == 0) {
- /* Unix: accept any "2byte-" name, assume current locale. */
- enc_dbcs_new = DBCS_2BYTE;
- } else if ((idx = enc_canon_search(p_enc)) >= 0) {
- i = enc_canon_table[idx].prop;
- if (i & ENC_UNICODE) {
- /* Unicode */
- enc_utf8 = true;
- if (i & (ENC_2BYTE | ENC_2WORD))
- enc_unicode = 2;
- else if (i & ENC_4BYTE)
- enc_unicode = 4;
- else
- enc_unicode = 0;
- } else if (i & ENC_DBCS) {
- /* 2byte, handle below */
- enc_dbcs_new = enc_canon_table[idx].codepage;
- } else {
- /* Must be 8-bit. */
- enc_unicode = 0;
- enc_utf8 = false;
- }
- } else /* Don't know what encoding this is, reject it. */
- return e_invarg;
-
- if (enc_dbcs_new != 0) {
- enc_unicode = 0;
- enc_utf8 = false;
- }
- enc_dbcs = enc_dbcs_new;
- has_mbyte = (enc_dbcs != 0 || enc_utf8);
-
-
- /* Detect an encoding that uses latin1 characters. */
- enc_latin1like = (enc_utf8 || STRCMP(p_enc, "latin1") == 0
- || STRCMP(p_enc, "iso-8859-15") == 0);
-
- /*
- * Set the function pointers.
- */
- if (enc_utf8) {
- mb_ptr2len = utfc_ptr2len;
- mb_ptr2len_len = utfc_ptr2len_len;
- mb_char2len = utf_char2len;
- mb_char2bytes = utf_char2bytes;
- mb_ptr2cells = utf_ptr2cells;
- mb_ptr2cells_len = utf_ptr2cells_len;
- mb_char2cells = utf_char2cells;
- mb_off2cells = utf_off2cells;
- mb_ptr2char = utf_ptr2char;
- mb_head_off = utf_head_off;
- } else if (enc_dbcs != 0) {
- mb_ptr2len = dbcs_ptr2len;
- mb_ptr2len_len = dbcs_ptr2len_len;
- mb_char2len = dbcs_char2len;
- mb_char2bytes = dbcs_char2bytes;
- mb_ptr2cells = dbcs_ptr2cells;
- mb_ptr2cells_len = dbcs_ptr2cells_len;
- mb_char2cells = dbcs_char2cells;
- mb_off2cells = dbcs_off2cells;
- mb_ptr2char = dbcs_ptr2char;
- mb_head_off = dbcs_head_off;
- } else {
- mb_ptr2len = latin_ptr2len;
- mb_ptr2len_len = latin_ptr2len_len;
- mb_char2len = latin_char2len;
- mb_char2bytes = latin_char2bytes;
- mb_ptr2cells = latin_ptr2cells;
- mb_ptr2cells_len = latin_ptr2cells_len;
- mb_char2cells = latin_char2cells;
- mb_off2cells = latin_off2cells;
- mb_ptr2char = latin_ptr2char;
- mb_head_off = latin_head_off;
- }
-
- /*
- * Fill the mb_bytelen_tab[] for MB_BYTE2LEN().
- */
-#ifdef LEN_FROM_CONV
- /* When 'encoding' is different from the current locale mblen() won't
- * work. Use conversion to "utf-8" instead. */
- vimconv.vc_type = CONV_NONE;
- if (enc_dbcs) {
- p = enc_locale();
- if (p == NULL || STRCMP(p, p_enc) != 0) {
- convert_setup(&vimconv, p_enc, (char_u *)"utf-8");
- vimconv.vc_fail = true;
- }
- xfree(p);
- }
-#endif
-
- for (i = 0; i < 256; ++i) {
- /* Our own function to reliably check the length of UTF-8 characters,
- * independent of mblen(). */
- if (enc_utf8)
- n = utf8len_tab[i];
- else if (enc_dbcs == 0)
- n = 1;
- else {
- char buf[MB_MAXBYTES + 1];
- if (i == NUL) /* just in case mblen() can't handle "" */
- n = 1;
- else {
- buf[0] = i;
- buf[1] = 0;
-#ifdef LEN_FROM_CONV
- if (vimconv.vc_type != CONV_NONE) {
- /*
- * string_convert() should fail when converting the first
- * byte of a double-byte character.
- */
- p = string_convert(&vimconv, (char_u *)buf, NULL);
- if (p != NULL) {
- xfree(p);
- n = 1;
- } else
- n = 2;
- } else
-#endif
- {
- /*
- * mblen() should return -1 for invalid (means the leading
- * multibyte) character. However there are some platforms
- * where mblen() returns 0 for invalid character.
- * Therefore, following condition includes 0.
- */
- ignored = mblen(NULL, 0); /* First reset the state. */
- if (mblen(buf, (size_t)1) <= 0)
- n = 2;
- else
- n = 1;
- }
- }
- }
- mb_bytelen_tab[i] = n;
- }
-
-#ifdef LEN_FROM_CONV
- convert_setup(&vimconv, NULL, NULL);
-#endif
-
- /* The cell width depends on the type of multi-byte characters. */
- (void)init_chartab();
-
- /* When enc_utf8 is set or reset, (de)allocate ScreenLinesUC[] */
- screenalloc(false);
-
-#ifdef HAVE_WORKING_LIBINTL
- /* GNU gettext 0.10.37 supports this feature: set the codeset used for
- * translated messages independently from the current locale. */
- (void)bind_textdomain_codeset(PROJECT_NAME,
- enc_utf8 ? "utf-8" : (char *)p_enc);
-#endif
-
-
- /* Fire an autocommand to let people do custom font setup. This must be
- * after Vim has been setup for the new encoding. */
- apply_autocmds(EVENT_ENCODINGCHANGED, NULL, (char_u *)"", FALSE, curbuf);
-
- /* Need to reload spell dictionaries */
- spell_reload();
-
- return NULL;
-}
-
-/*
* Return the size of the BOM for the current buffer:
* 0 - no BOM
* 2 - UCS-2 or UTF-16 BOM
@@ -598,20 +376,15 @@ int bomb_size(void)
int n = 0;
if (curbuf->b_p_bomb && !curbuf->b_p_bin) {
- if (*curbuf->b_p_fenc == NUL) {
- if (enc_utf8) {
- if (enc_unicode != 0)
- n = enc_unicode;
- else
- n = 3;
- }
- } else if (STRCMP(curbuf->b_p_fenc, "utf-8") == 0)
+ if (*curbuf->b_p_fenc == NUL
+ || STRCMP(curbuf->b_p_fenc, "utf-8") == 0) {
n = 3;
- else if (STRNCMP(curbuf->b_p_fenc, "ucs-2", 5) == 0
- || STRNCMP(curbuf->b_p_fenc, "utf-16", 6) == 0)
+ } else if (STRNCMP(curbuf->b_p_fenc, "ucs-2", 5) == 0
+ || STRNCMP(curbuf->b_p_fenc, "utf-16", 6) == 0) {
n = 2;
- else if (STRNCMP(curbuf->b_p_fenc, "ucs-4", 5) == 0)
+ } else if (STRNCMP(curbuf->b_p_fenc, "ucs-4", 5) == 0) {
n = 4;
+ }
}
return n;
}
@@ -621,14 +394,13 @@ int bomb_size(void)
*/
void remove_bom(char_u *s)
{
- if (enc_utf8) {
- char_u *p = s;
+ char *p = (char *)s;
- while ((p = vim_strbyte(p, 0xef)) != NULL) {
- if (p[1] == 0xbb && p[2] == 0xbf)
- STRMOVE(p, p + 3);
- else
- ++p;
+ while ((p = strchr(p, 0xef)) != NULL) {
+ if ((uint8_t)p[1] == 0xbb && (uint8_t)p[2] == 0xbf) {
+ STRMOVE(p, p + 3);
+ } else {
+ p++;
}
}
}
@@ -642,259 +414,21 @@ void remove_bom(char_u *s)
*/
int mb_get_class(const char_u *p)
{
- return mb_get_class_buf(p, curbuf);
+ return mb_get_class_tab(p, curbuf->b_chartab);
}
-int mb_get_class_buf(const char_u *p, buf_T *buf)
+int mb_get_class_tab(const char_u *p, const uint64_t *const chartab)
{
if (MB_BYTE2LEN(p[0]) == 1) {
- if (p[0] == NUL || ascii_iswhite(p[0]))
+ if (p[0] == NUL || ascii_iswhite(p[0])) {
return 0;
- if (vim_iswordc_buf(p[0], buf))
+ }
+ if (vim_iswordc_tab(p[0], chartab)) {
return 2;
+ }
return 1;
}
- if (enc_dbcs != 0 && p[0] != NUL && p[1] != NUL)
- return dbcs_class(p[0], p[1]);
- if (enc_utf8)
- return utf_class(utf_ptr2char(p));
- return 0;
-}
-
-/*
- * Get class of a double-byte character. This always returns 3 or bigger.
- * TODO: Should return 1 for punctuation.
- */
-int dbcs_class(unsigned lead, unsigned trail)
-{
- switch (enc_dbcs) {
- /* please add classify routine for your language in here */
-
- case DBCS_JPNU: /* ? */
- case DBCS_JPN:
- {
- /* JIS code classification */
- unsigned char lb = lead;
- unsigned char tb = trail;
-
- /* convert process code to JIS */
- /*
- * XXX: Code page identification can not use with all
- * system! So, some other encoding information
- * will be needed.
- * In japanese: SJIS,EUC,UNICODE,(JIS)
- * Note that JIS-code system don't use as
- * process code in most system because it uses
- * escape sequences(JIS is context depend encoding).
- */
- /* assume process code is JAPANESE-EUC */
- lb &= 0x7f;
- tb &= 0x7f;
- /* exceptions */
- switch (lb << 8 | tb) {
- case 0x2121: /* ZENKAKU space */
- return 0;
- case 0x2122: /* TOU-TEN (Japanese comma) */
- case 0x2123: /* KU-TEN (Japanese period) */
- case 0x2124: /* ZENKAKU comma */
- case 0x2125: /* ZENKAKU period */
- return 1;
- case 0x213c: /* prolongedsound handled as KATAKANA */
- return 13;
- }
- /* sieved by KU code */
- switch (lb) {
- case 0x21:
- case 0x22:
- /* special symbols */
- return 10;
- case 0x23:
- /* alpha-numeric */
- return 11;
- case 0x24:
- /* hiragana */
- return 12;
- case 0x25:
- /* katakana */
- return 13;
- case 0x26:
- /* greek */
- return 14;
- case 0x27:
- /* russian */
- return 15;
- case 0x28:
- /* lines */
- return 16;
- default:
- /* kanji */
- return 17;
- }
- }
-
- case DBCS_KORU: /* ? */
- case DBCS_KOR:
- {
- /* KS code classification */
- unsigned char c1 = lead;
- unsigned char c2 = trail;
-
- /*
- * 20 : Hangul
- * 21 : Hanja
- * 22 : Symbols
- * 23 : Alpha-numeric/Roman Letter (Full width)
- * 24 : Hangul Letter(Alphabet)
- * 25 : Roman Numeral/Greek Letter
- * 26 : Box Drawings
- * 27 : Unit Symbols
- * 28 : Circled/Parenthesized Letter
- * 29 : Hiragana/Katakana
- * 30 : Cyrillic Letter
- */
-
- if (c1 >= 0xB0 && c1 <= 0xC8)
- /* Hangul */
- return 20;
-
- else if (c1 >= 0xCA && c1 <= 0xFD)
- /* Hanja */
- return 21;
- else switch (c1) {
- case 0xA1:
- case 0xA2:
- /* Symbols */
- return 22;
- case 0xA3:
- /* Alpha-numeric */
- return 23;
- case 0xA4:
- /* Hangul Letter(Alphabet) */
- return 24;
- case 0xA5:
- /* Roman Numeral/Greek Letter */
- return 25;
- case 0xA6:
- /* Box Drawings */
- return 26;
- case 0xA7:
- /* Unit Symbols */
- return 27;
- case 0xA8:
- case 0xA9:
- if (c2 <= 0xAF)
- return 25; /* Roman Letter */
- else if (c2 >= 0xF6)
- return 22; /* Symbols */
- else
- /* Circled/Parenthesized Letter */
- return 28;
- case 0xAA:
- case 0xAB:
- /* Hiragana/Katakana */
- return 29;
- case 0xAC:
- /* Cyrillic Letter */
- return 30;
- }
- }
- default:
- break;
- }
- return 3;
-}
-
-/*
- * mb_char2len() function pointer.
- * Return length in bytes of character "c".
- * Returns 1 for a single-byte character.
- */
-int latin_char2len(int c)
-{
- return 1;
-}
-
-static int dbcs_char2len(int c)
-{
- if (c >= 0x100)
- return 2;
- return 1;
-}
-
-/*
- * mb_char2bytes() function pointer.
- * Convert a character to its bytes.
- * Returns the length in bytes.
- */
-int latin_char2bytes(int c, char_u *buf)
-{
- buf[0] = c;
- return 1;
-}
-
-static int dbcs_char2bytes(int c, char_u *buf)
-{
- if (c >= 0x100) {
- buf[0] = (unsigned)c >> 8;
- buf[1] = c;
- /* Never use a NUL byte, it causes lots of trouble. It's an invalid
- * character anyway. */
- if (buf[1] == NUL)
- buf[1] = '\n';
- return 2;
- }
- buf[0] = c;
- return 1;
-}
-
-/*
- * mb_ptr2len() function pointer.
- * Get byte length of character at "*p" but stop at a NUL.
- * For UTF-8 this includes following composing characters.
- * Returns 0 when *p is NUL.
- */
-int latin_ptr2len(const char_u *p)
-{
- return MB_BYTE2LEN(*p);
-}
-
-static int dbcs_ptr2len(const char_u *p)
-{
- int len;
-
- /* Check if second byte is not missing. */
- len = MB_BYTE2LEN(*p);
- if (len == 2 && p[1] == NUL)
- len = 1;
- return len;
-}
-
-/*
- * mb_ptr2len_len() function pointer.
- * Like mb_ptr2len(), but limit to read "size" bytes.
- * Returns 0 for an empty string.
- * Returns 1 for an illegal char or an incomplete byte sequence.
- */
-int latin_ptr2len_len(const char_u *p, int size)
-{
- if (size < 1 || *p == NUL)
- return 0;
- return 1;
-}
-
-static int dbcs_ptr2len_len(const char_u *p, int size)
-{
- int len;
-
- if (size < 1 || *p == NUL)
- return 0;
- if (size == 1)
- return 1;
- /* Check that second byte is not missing. */
- len = MB_BYTE2LEN(*p);
- if (len == 2 && p[1] == NUL)
- len = 1;
- return len;
+ return utf_class_tab(utf_ptr2char(p), chartab);
}
/*
@@ -950,6 +484,9 @@ int utf_char2cells(int c)
if (intable(doublewidth, ARRAY_SIZE(doublewidth), c))
return 2;
#endif
+ if (p_emoji && intable(emoji_width, ARRAY_SIZE(emoji_width), c)) {
+ return 2;
+ }
}
/* Characters below 0x100 are influenced by 'isprint' option */
else if (c >= 0x80 && !vim_isprintc(c))
@@ -961,16 +498,8 @@ int utf_char2cells(int c)
return 1;
}
-/*
- * mb_ptr2cells() function pointer.
- * Return the number of display cells character at "*p" occupies.
- * This doesn't take care of unprintable characters, use ptr2cells() for that.
- */
-int latin_ptr2cells(const char_u *p)
-{
- return 1;
-}
-
+/// Return the number of display cells character at "*p" occupies.
+/// This doesn't take care of unprintable characters, use ptr2cells() for that.
int utf_ptr2cells(const char_u *p)
{
int c;
@@ -989,26 +518,9 @@ int utf_ptr2cells(const char_u *p)
return 1;
}
-int dbcs_ptr2cells(const char_u *p)
-{
- /* Number of cells is equal to number of bytes, except for euc-jp when
- * the first byte is 0x8e. */
- if (enc_dbcs == DBCS_JPNU && *p == 0x8e)
- return 1;
- return MB_BYTE2LEN(*p);
-}
-
-/*
- * mb_ptr2cells_len() function pointer.
- * Like mb_ptr2cells(), but limit string length to "size".
- * For an empty string or truncated character returns 1.
- */
-int latin_ptr2cells_len(const char_u *p, int size)
-{
- return 1;
-}
-
-static int utf_ptr2cells_len(const char_u *p, int size)
+/// Like utf_ptr2cells(), but limit string length to "size".
+/// For an empty string or truncated character returns 1.
+int utf_ptr2cells_len(const char_u *p, int size)
{
int c;
@@ -1028,35 +540,6 @@ static int utf_ptr2cells_len(const char_u *p, int size)
return 1;
}
-static int dbcs_ptr2cells_len(const char_u *p, int size)
-{
- /* Number of cells is equal to number of bytes, except for euc-jp when
- * the first byte is 0x8e. */
- if (size <= 1 || (enc_dbcs == DBCS_JPNU && *p == 0x8e))
- return 1;
- return MB_BYTE2LEN(*p);
-}
-
-/*
- * mb_char2cells() function pointer.
- * Return the number of display cells character "c" occupies.
- * Only takes care of multi-byte chars, not "^C" and such.
- */
-int latin_char2cells(int c)
-{
- return 1;
-}
-
-static int dbcs_char2cells(int c)
-{
- /* Number of cells is equal to number of bytes, except for euc-jp when
- * the first byte is 0x8e. */
- if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e)
- return 1;
- /* use the first byte */
- return MB_BYTE2LEN((unsigned)c >> 8);
-}
-
/// Calculate the number of cells occupied by string `str`.
///
/// @param str The source string, may not be NULL, must be a NUL-terminated
@@ -1067,95 +550,60 @@ size_t mb_string2cells(const char_u *str)
size_t clen = 0;
for (const char_u *p = str; *p != NUL; p += (*mb_ptr2len)(p)) {
- clen += (*mb_ptr2cells)(p);
+ clen += utf_ptr2cells(p);
}
return clen;
}
-/*
- * mb_off2cells() function pointer.
- * Return number of display cells for char at ScreenLines[off].
- * We make sure that the offset used is less than "max_off".
- */
-int latin_off2cells(unsigned off, unsigned max_off)
-{
- return 1;
-}
-
-int dbcs_off2cells(unsigned off, unsigned max_off)
-{
- /* never check beyond end of the line */
- if (off >= max_off)
- return 1;
-
- /* Number of cells is equal to number of bytes, except for euc-jp when
- * the first byte is 0x8e. */
- if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e)
- return 1;
- return MB_BYTE2LEN(ScreenLines[off]);
-}
-
-int utf_off2cells(unsigned off, unsigned max_off)
-{
- return (off + 1 < max_off && ScreenLines[off + 1] == 0) ? 2 : 1;
-}
-
-/*
- * mb_ptr2char() function pointer.
- * Convert a byte sequence into a character.
- */
-int latin_ptr2char(const char_u *p)
-{
- return *p;
-}
-
-static int dbcs_ptr2char(const char_u *p)
-{
- if (MB_BYTE2LEN(*p) > 1 && p[1] != NUL)
- return (p[0] << 8) + p[1];
- return *p;
-}
-
-/*
- * Convert a UTF-8 byte sequence to a wide character.
- * If the sequence is illegal or truncated by a NUL the first byte is
- * returned.
- * Does not include composing characters, of course.
- */
-int utf_ptr2char(const char_u *p)
+/// Convert a UTF-8 byte sequence to a wide character
+///
+/// If the sequence is illegal or truncated by a NUL then the first byte is
+/// returned.
+/// For an overlong sequence this may return zero.
+/// Does not include composing characters for obvious reasons.
+///
+/// @param[in] p String to convert.
+///
+/// @return Unicode codepoint or byte value.
+int utf_ptr2char(const char_u *const p)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- uint8_t len;
-
- if (p[0] < 0x80) /* be quick for ASCII */
+ if (p[0] < 0x80) { // Be quick for ASCII.
return p[0];
+ }
- len = utf8len_tab_zero[p[0]];
+ const uint8_t len = utf8len_tab_zero[p[0]];
if (len > 1 && (p[1] & 0xc0) == 0x80) {
- if (len == 2)
+ if (len == 2) {
return ((p[0] & 0x1f) << 6) + (p[1] & 0x3f);
+ }
if ((p[2] & 0xc0) == 0x80) {
- if (len == 3)
- return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6)
- + (p[2] & 0x3f);
+ if (len == 3) {
+ return (((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6)
+ + (p[2] & 0x3f));
+ }
if ((p[3] & 0xc0) == 0x80) {
- if (len == 4)
- return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12)
- + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f);
+ if (len == 4) {
+ return (((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12)
+ + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f));
+ }
if ((p[4] & 0xc0) == 0x80) {
- if (len == 5)
- return ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18)
- + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6)
- + (p[4] & 0x3f);
- if ((p[5] & 0xc0) == 0x80 && len == 6)
- return ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24)
- + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12)
- + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f);
+ if (len == 5) {
+ return (((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18)
+ + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6)
+ + (p[4] & 0x3f));
+ }
+ if ((p[5] & 0xc0) == 0x80 && len == 6) {
+ return (((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24)
+ + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12)
+ + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f));
+ }
}
}
}
}
- /* Illegal value, just return the first byte */
+ // Illegal value: just return the first byte.
return p[0];
}
@@ -1175,7 +623,7 @@ int utf_ptr2char(const char_u *p)
* If byte sequence is illegal or incomplete, returns -1 and does not advance
* "s".
*/
-static int utf_safe_read_char_adv(char_u **s, size_t *n)
+static int utf_safe_read_char_adv(const char_u **s, size_t *n)
{
int c;
@@ -1217,11 +665,11 @@ static int utf_safe_read_char_adv(char_u **s, size_t *n)
* Get character at **pp and advance *pp to the next character.
* Note: composing characters are skipped!
*/
-int mb_ptr2char_adv(char_u **pp)
+int mb_ptr2char_adv(const char_u **const pp)
{
int c;
- c = (*mb_ptr2char)(*pp);
+ c = utf_ptr2char(*pp);
*pp += (*mb_ptr2len)(*pp);
return c;
}
@@ -1230,15 +678,12 @@ int mb_ptr2char_adv(char_u **pp)
* Get character at **pp and advance *pp to the next character.
* Note: composing characters are returned as separate characters.
*/
-int mb_cptr2char_adv(char_u **pp)
+int mb_cptr2char_adv(const char_u **pp)
{
int c;
- c = (*mb_ptr2char)(*pp);
- if (enc_utf8)
- *pp += utf_ptr2len(*pp);
- else
- *pp += (*mb_ptr2len)(*pp);
+ c = utf_ptr2char(*pp);
+ *pp += utf_ptr2len(*pp);
return c;
}
@@ -1259,12 +704,14 @@ bool utf_composinglike(const char_u *p1, const char_u *p2)
return arabic_combine(utf_ptr2char(p1), c2);
}
-/*
- * Convert a UTF-8 byte string to a wide character. Also get up to MAX_MCO
- * composing characters.
- *
- * @param [out] pcc: composing chars, last one is 0
- */
+/// Convert a UTF-8 string to a wide character
+///
+/// Also gets up to #MAX_MCO composing characters.
+///
+/// @param[out] pcc Location where to store composing characters. Must have
+/// space at least for #MAX_MCO + 1 elements.
+///
+/// @return leading character.
int utfc_ptr2char(const char_u *p, int *pcc)
{
int len;
@@ -1338,44 +785,24 @@ int utfc_ptr2char_len(const char_u *p, int *pcc, int maxlen)
#undef ISCOMPOSING
}
-/*
- * Convert the character at screen position "off" to a sequence of bytes.
- * Includes the composing characters.
- * "buf" must at least have the length MB_MAXBYTES + 1.
- * Only to be used when ScreenLinesUC[off] != 0.
- * Returns the produced number of bytes.
- */
-int utfc_char2bytes(int off, char_u *buf)
-{
- int len;
- int i;
-
- len = utf_char2bytes(ScreenLinesUC[off], buf);
- for (i = 0; i < Screen_mco; ++i) {
- if (ScreenLinesC[i][off] == 0)
- break;
- len += utf_char2bytes(ScreenLinesC[i][off], buf + len);
- }
- return len;
-}
-
-/*
- * Get the length of a UTF-8 byte sequence, not including any following
- * composing characters.
- * Returns 0 for "".
- * Returns 1 for an illegal byte sequence.
- */
-int utf_ptr2len(const char_u *p)
+/// Get the length of a UTF-8 byte sequence representing a single codepoint
+///
+/// @param[in] p UTF-8 string.
+///
+/// @return Sequence length, 0 for empty string and 1 for non-UTF-8 byte
+/// sequence.
+int utf_ptr2len(const char_u *const p)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- int len;
- int i;
-
- if (*p == NUL)
+ if (*p == NUL) {
return 0;
- len = utf8len_tab[*p];
- for (i = 1; i < len; ++i)
- if ((p[i] & 0xc0) != 0x80)
+ }
+ const int len = utf8len_tab[*p];
+ for (int i = 1; i < len; i++) {
+ if ((p[i] & 0xc0) != 0x80) {
return 1;
+ }
+ }
return len;
}
@@ -1416,38 +843,38 @@ int utf_ptr2len_len(const char_u *p, int size)
return len;
}
-/*
- * Return the number of bytes the UTF-8 encoding of the character at "p" takes.
- * This includes following composing characters.
- */
-int utfc_ptr2len(const char_u *p)
+/// Return the number of bytes occupied by a UTF-8 character in a string
+///
+/// This includes following composing characters.
+int utfc_ptr2len(const char_u *const p)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- int len;
- int b0 = *p;
- int prevlen;
+ uint8_t b0 = (uint8_t)(*p);
- if (b0 == NUL)
+ if (b0 == NUL) {
return 0;
- if (b0 < 0x80 && p[1] < 0x80) /* be quick for ASCII */
+ }
+ if (b0 < 0x80 && p[1] < 0x80) { // be quick for ASCII
return 1;
+ }
- /* Skip over first UTF-8 char, stopping at a NUL byte. */
- len = utf_ptr2len(p);
+ // Skip over first UTF-8 char, stopping at a NUL byte.
+ int len = utf_ptr2len(p);
- /* Check for illegal byte. */
- if (len == 1 && b0 >= 0x80)
+ // Check for illegal byte.
+ if (len == 1 && b0 >= 0x80) {
return 1;
+ }
- /*
- * Check for composing characters. We can handle only the first six, but
- * skip all of them (otherwise the cursor would get stuck).
- */
- prevlen = 0;
- for (;; ) {
- if (p[len] < 0x80 || !UTF_COMPOSINGLIKE(p + prevlen, p + len))
+ // Check for composing characters. We can handle only the first six, but
+ // skip all of them (otherwise the cursor would get stuck).
+ int prevlen = 0;
+ for (;;) {
+ if (p[len] < 0x80 || !UTF_COMPOSINGLIKE(p + prevlen, p + len)) {
return len;
+ }
- /* Skip over composing char */
+ // Skip over composing char.
prevlen = len;
len += utf_ptr2len(p + len);
}
@@ -1505,70 +932,65 @@ int utfc_ptr2len_len(const char_u *p, int size)
return len;
}
-/*
- * Return the number of bytes the UTF-8 encoding of character "c" takes.
- * This does not include composing characters.
- */
-int utf_char2len(int c)
+/// Determine how many bytes certain unicode codepoint will occupy
+int utf_char2len(const int c)
{
- if (c < 0x80)
+ if (c < 0x80) {
return 1;
- if (c < 0x800)
+ } else if (c < 0x800) {
return 2;
- if (c < 0x10000)
+ } else if (c < 0x10000) {
return 3;
- if (c < 0x200000)
+ } else if (c < 0x200000) {
return 4;
- if (c < 0x4000000)
+ } else if (c < 0x4000000) {
return 5;
- return 6;
+ } else {
+ return 6;
+ }
}
-/*
- * Convert Unicode character "c" to UTF-8 string in "buf[]".
- * Returns the number of bytes.
- * This does not include composing characters.
- */
-int utf_char2bytes(int c, char_u *buf)
+/// Convert Unicode character to UTF-8 string
+///
+/// @param c character to convert to \p buf
+/// @param[out] buf UTF-8 string generated from \p c, does not add \0
+/// @return Number of bytes (1-6). Does not include composing characters.
+int utf_char2bytes(const int c, char_u *const buf)
{
- if (c < 0x80) { /* 7 bits */
+ if (c < 0x80) { // 7 bits
buf[0] = c;
return 1;
- }
- if (c < 0x800) { /* 11 bits */
+ } else if (c < 0x800) { // 11 bits
buf[0] = 0xc0 + ((unsigned)c >> 6);
buf[1] = 0x80 + (c & 0x3f);
return 2;
- }
- if (c < 0x10000) { /* 16 bits */
+ } else if (c < 0x10000) { // 16 bits
buf[0] = 0xe0 + ((unsigned)c >> 12);
buf[1] = 0x80 + (((unsigned)c >> 6) & 0x3f);
buf[2] = 0x80 + (c & 0x3f);
return 3;
- }
- if (c < 0x200000) { /* 21 bits */
+ } else if (c < 0x200000) { // 21 bits
buf[0] = 0xf0 + ((unsigned)c >> 18);
buf[1] = 0x80 + (((unsigned)c >> 12) & 0x3f);
buf[2] = 0x80 + (((unsigned)c >> 6) & 0x3f);
buf[3] = 0x80 + (c & 0x3f);
return 4;
- }
- if (c < 0x4000000) { /* 26 bits */
+ } else if (c < 0x4000000) { // 26 bits
buf[0] = 0xf8 + ((unsigned)c >> 24);
buf[1] = 0x80 + (((unsigned)c >> 18) & 0x3f);
buf[2] = 0x80 + (((unsigned)c >> 12) & 0x3f);
buf[3] = 0x80 + (((unsigned)c >> 6) & 0x3f);
buf[4] = 0x80 + (c & 0x3f);
return 5;
+ } else { // 31 bits
+ buf[0] = 0xfc + ((unsigned)c >> 30);
+ buf[1] = 0x80 + (((unsigned)c >> 24) & 0x3f);
+ buf[2] = 0x80 + (((unsigned)c >> 18) & 0x3f);
+ buf[3] = 0x80 + (((unsigned)c >> 12) & 0x3f);
+ buf[4] = 0x80 + (((unsigned)c >> 6) & 0x3f);
+ buf[5] = 0x80 + (c & 0x3f);
+ return 6;
}
- /* 31 bits */
- buf[0] = 0xfc + ((unsigned)c >> 30);
- buf[1] = 0x80 + (((unsigned)c >> 24) & 0x3f);
- buf[2] = 0x80 + (((unsigned)c >> 18) & 0x3f);
- buf[3] = 0x80 + (((unsigned)c >> 12) & 0x3f);
- buf[4] = 0x80 + (((unsigned)c >> 6) & 0x3f);
- buf[5] = 0x80 + (c & 0x3f);
- return 6;
}
/*
@@ -1612,7 +1034,12 @@ bool utf_printable(int c)
* 1: punctuation
* 2 or bigger: some class of word character.
*/
-int utf_class(int c)
+int utf_class(const int c)
+{
+ return utf_class_tab(c, curbuf->b_chartab);
+}
+
+int utf_class_tab(const int c, const uint64_t *const chartab)
{
/* sorted list of non-overlapping intervals */
static struct clinterval {
@@ -1695,11 +1122,13 @@ int utf_class(int c)
/* First quick check for Latin1 characters, use 'iskeyword'. */
if (c < 0x100) {
- if (c == ' ' || c == '\t' || c == NUL || c == 0xa0)
- return 0; /* blank */
- if (vim_iswordc(c))
- return 2; /* word character */
- return 1; /* punctuation */
+ if (c == ' ' || c == '\t' || c == NUL || c == 0xa0) {
+ return 0; // blank
+ }
+ if (vim_iswordc_tab(c, chartab)) {
+ return 2; // word character
+ }
+ return 1; // punctuation
}
/* binary search in table */
@@ -1713,16 +1142,20 @@ int utf_class(int c)
return (int)classes[mid].class;
}
+ // emoji
+ if (intable(emoji_all, ARRAY_SIZE(emoji_all), c)) {
+ return 3;
+ }
+
/* most other characters are "word" characters */
return 2;
}
-/*
- * Code for Unicode case-dependent operations. Based on notes in
- * http://www.unicode.org/Public/UNIDATA/CaseFolding.txt
- * This code uses simple case folding, not full case folding.
- * Last updated for Unicode 5.2.
- */
+bool utf_ambiguous_width(int c)
+{
+ return c >= 0x80 && (intable(ambiguous, ARRAY_SIZE(ambiguous), c)
+ || intable(emoji_all, ARRAY_SIZE(emoji_all), c));
+}
/*
* Generic conversion function for case operations.
@@ -1758,14 +1191,21 @@ static int utf_convert(int a, const convertStruct *const table, size_t n_items)
*/
int utf_fold(int a)
{
+ if (a < 0x80) {
+ // be fast for ASCII
+ return a >= 0x41 && a <= 0x5a ? a + 32 : a;
+ }
return utf_convert(a, foldCase, ARRAY_SIZE(foldCase));
}
-/*
- * Return the upper-case equivalent of "a", which is a UCS-4 character. Use
- * simple case folding.
- */
-int utf_toupper(int a)
+// Vim's own character class functions. These exist because many library
+// islower()/toupper() etc. do not work properly: they crash when used with
+// invalid values or can't handle latin1 when the locale is C.
+// Speed is most important here.
+
+/// Return the upper-case equivalent of "a", which is a UCS-4 character. Use
+/// simple case folding.
+int mb_toupper(int a)
{
/* If 'casemap' contains "keepascii" use ASCII style toupper(). */
if (a < 128 && (cmp_flags & CMP_KEEPASCII))
@@ -1785,17 +1225,15 @@ int utf_toupper(int a)
return utf_convert(a, toUpper, ARRAY_SIZE(toUpper));
}
-bool utf_islower(int a)
+bool mb_islower(int a)
{
- /* German sharp s is lower case but has no upper case equivalent. */
- return (utf_toupper(a) != a) || a == 0xdf;
+ // German sharp s is lower case but has no upper case equivalent.
+ return (mb_toupper(a) != a) || a == 0xdf;
}
-/*
- * Return the lower-case equivalent of "a", which is a UCS-4 character. Use
- * simple case folding.
- */
-int utf_tolower(int a)
+/// Return the lower-case equivalent of "a", which is a UCS-4 character. Use
+/// simple case folding.
+int mb_tolower(int a)
{
/* If 'casemap' contains "keepascii" use ASCII style tolower(). */
if (a < 128 && (cmp_flags & CMP_KEEPASCII))
@@ -1815,12 +1253,13 @@ int utf_tolower(int a)
return utf_convert(a, toLower, ARRAY_SIZE(toLower));
}
-bool utf_isupper(int a)
+bool mb_isupper(int a)
{
- return utf_tolower(a) != a;
+ return mb_tolower(a) != a;
}
-static int utf_strnicmp(char_u *s1, char_u *s2, size_t n1, size_t n2)
+static int utf_strnicmp(const char_u *s1, const char_u *s2, size_t n1,
+ size_t n2)
{
int c1, c2, cdiff;
char_u buffer[6];
@@ -1885,6 +1324,93 @@ static int utf_strnicmp(char_u *s1, char_u *s2, size_t n1, size_t n2)
return n1 == 0 ? -1 : 1;
}
+#ifdef WIN32
+#ifndef CP_UTF8
+# define CP_UTF8 65001 /* magic number from winnls.h */
+#endif
+
+/// Reassigns `strw` to a new, allocated pointer to a UTF16 string.
+int utf8_to_utf16(const char *str, wchar_t **strw)
+ FUNC_ATTR_NONNULL_ALL
+{
+ ssize_t wchar_len = 0;
+
+ // Compute the length needed to store the converted widechar string.
+ wchar_len = MultiByteToWideChar(CP_UTF8,
+ 0, // dwFlags: must be 0 for utf8
+ str, // lpMultiByteStr: string to convert
+ -1, // -1 => process up to NUL
+ NULL, // lpWideCharStr: converted string
+ 0); // 0 => return length, don't convert
+ if (wchar_len == 0) {
+ return GetLastError();
+ }
+
+ ssize_t buf_sz = wchar_len * sizeof(wchar_t);
+
+ if (buf_sz == 0) {
+ *strw = NULL;
+ return 0;
+ }
+
+ char *buf = xmalloc(buf_sz);
+ char *pos = buf;
+
+ int r = MultiByteToWideChar(CP_UTF8,
+ 0,
+ str,
+ -1,
+ (wchar_t *)pos,
+ wchar_len);
+ assert(r == wchar_len);
+ if (r != wchar_len) {
+ EMSG2("MultiByteToWideChar failed: %d", r);
+ }
+ *strw = (wchar_t *)pos;
+
+ return 0;
+}
+
+/// Reassigns `str` to a new, allocated pointer to a UTF8 string.
+int utf16_to_utf8(const wchar_t *strw, char **str)
+ FUNC_ATTR_NONNULL_ALL
+{
+ // Compute the space required to store the string as UTF-8.
+ DWORD utf8_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ strw,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ if (utf8_len == 0) {
+ return GetLastError();
+ }
+
+ *str = xmallocz(utf8_len);
+
+ // Convert to UTF-8.
+ utf8_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ strw,
+ -1,
+ *str,
+ utf8_len,
+ NULL,
+ NULL);
+ if (utf8_len == 0) {
+ free(*str);
+ *str = NULL;
+ return GetLastError();
+ }
+ (*str)[utf8_len] = '\0';
+
+ return 0;
+}
+
+#endif
+
/*
* Version of strnicmp() that handles multi-byte characters.
* Needed for Big5, Shift-JIS and UTF-8 encoding. Other DBCS encodings can
@@ -1893,48 +1419,26 @@ static int utf_strnicmp(char_u *s1, char_u *s2, size_t n1, size_t n2)
* Returns zero if s1 and s2 are equal (ignoring case), the difference between
* two characters otherwise.
*/
-int mb_strnicmp(char_u *s1, char_u *s2, size_t nn)
+int mb_strnicmp(const char_u *s1, const char_u *s2, const size_t nn)
{
- int i, l;
- int cdiff;
- int n = (int)nn;
-
- if (enc_utf8) {
- return utf_strnicmp(s1, s2, nn, nn);
- } else {
- for (i = 0; i < n; i += l) {
- if (s1[i] == NUL && s2[i] == NUL) /* both strings end */
- return 0;
-
- l = (*mb_ptr2len)(s1 + i);
- if (l <= 1) {
- /* Single byte: first check normally, then with ignore case. */
- if (s1[i] != s2[i]) {
- cdiff = vim_tolower(s1[i]) - vim_tolower(s2[i]);
- if (cdiff != 0)
- return cdiff;
- }
- } else {
- /* For non-Unicode multi-byte don't ignore case. */
- if (l > n - i)
- l = n - i;
- cdiff = STRNCMP(s1 + i, s2 + i, l);
- if (cdiff != 0)
- return cdiff;
- }
- }
- }
- return 0;
+ return utf_strnicmp(s1, s2, nn, nn);
}
-/* We need to call mb_stricmp() even when we aren't dealing with a multi-byte
- * encoding because mb_stricmp() takes care of all ascii and non-ascii
- * encodings, including characters with umlauts in latin1, etc., while
- * STRICMP() only handles the system locale version, which often does not
- * handle non-ascii properly. */
-int mb_stricmp(char_u *s1, char_u *s2)
+/// Compare strings case-insensitively
+///
+/// @note We need to call mb_stricmp() even when we aren't dealing with
+/// a multi-byte encoding because mb_stricmp() takes care of all ASCII and
+/// non-ascii encodings, including characters with umlauts in latin1,
+/// etc., while STRICMP() only handles the system locale version, which
+/// often does not handle non-ascii properly.
+///
+/// @param[in] s1 First string to compare, not more then #MAXCOL characters.
+/// @param[in] s2 Second string to compare, not more then #MAXCOL characters.
+///
+/// @return 0 if strings are equal, <0 if s1 < s2, >0 if s1 > s2.
+int mb_stricmp(const char *s1, const char *s2)
{
- return mb_strnicmp(s1, s2, MAXCOL);
+ return mb_strnicmp((const char_u *)s1, (const char_u *)s2, MAXCOL);
}
/*
@@ -1979,68 +1483,9 @@ void show_utf8(void)
msg(IObuff);
}
-/*
- * mb_head_off() function pointer.
- * Return offset from "p" to the first byte of the character it points into.
- * If "p" points to the NUL at the end of the string return 0.
- * Returns 0 when already at the first byte of a character.
- */
-int latin_head_off(const char_u *base, const char_u *p)
-{
- return 0;
-}
-
-int dbcs_head_off(const char_u *base, const char_u *p)
-{
- /* It can't be a trailing byte when not using DBCS, at the start of the
- * string or the previous byte can't start a double-byte. */
- if (p <= base || MB_BYTE2LEN(p[-1]) == 1 || *p == NUL) {
- return 0;
- }
-
- /* This is slow: need to start at the base and go forward until the
- * byte we are looking for. Return 1 when we went past it, 0 otherwise. */
- const char_u *q = base;
- while (q < p) {
- q += dbcs_ptr2len(q);
- }
-
- return (q == p) ? 0 : 1;
-}
-
-/*
- * Special version of dbcs_head_off() that works for ScreenLines[], where
- * single-width DBCS_JPNU characters are stored separately.
- */
-int dbcs_screen_head_off(const char_u *base, const char_u *p)
-{
- /* It can't be a trailing byte when not using DBCS, at the start of the
- * string or the previous byte can't start a double-byte.
- * For euc-jp an 0x8e byte in the previous cell always means we have a
- * lead byte in the current cell. */
- if (p <= base
- || (enc_dbcs == DBCS_JPNU && p[-1] == 0x8e)
- || MB_BYTE2LEN(p[-1]) == 1
- || *p == NUL)
- return 0;
-
- /* This is slow: need to start at the base and go forward until the
- * byte we are looking for. Return 1 when we went past it, 0 otherwise.
- * For DBCS_JPNU look out for 0x8e, which means the second byte is not
- * stored as the next byte. */
- const char_u *q = base;
- while (q < p) {
- if (enc_dbcs == DBCS_JPNU && *q == 0x8e) {
- ++q;
- }
- else {
- q += dbcs_ptr2len(q);
- }
- }
-
- return (q == p) ? 0 : 1;
-}
-
+/// Return offset from "p" to the first byte of the character it points into.
+/// If "p" points to the NUL at the end of the string return 0.
+/// Returns 0 when already at the first byte of a character.
int utf_head_off(const char_u *base, const char_u *p)
{
int c;
@@ -2089,14 +1534,15 @@ int utf_head_off(const char_u *base, const char_u *p)
return (int)(p - q);
}
-/*
- * Copy a character from "*fp" to "*tp" and advance the pointers.
- */
-void mb_copy_char(const char_u **fp, char_u **tp)
+/// Copy a character, advancing the pointers
+///
+/// @param[in,out] fp Source of the character to copy.
+/// @param[in,out] tp Destination to copy to.
+void mb_copy_char(const char_u **const fp, char_u **const tp)
{
- int l = (*mb_ptr2len)(*fp);
+ const size_t l = (size_t)utfc_ptr2len(*fp);
- memmove(*tp, *fp, (size_t)l);
+ memmove(*tp, *fp, l);
*tp += l;
*fp += l;
}
@@ -2111,27 +1557,24 @@ int mb_off_next(char_u *base, char_u *p)
int i;
int j;
- if (enc_utf8) {
- if (*p < 0x80) /* be quick for ASCII */
- return 0;
+ if (*p < 0x80) { // be quick for ASCII
+ return 0;
+ }
- /* Find the next character that isn't 10xx.xxxx */
- for (i = 0; (p[i] & 0xc0) == 0x80; ++i)
- ;
- if (i > 0) {
- /* Check for illegal sequence. */
- for (j = 0; p - j > base; ++j)
- if ((p[-j] & 0xc0) != 0x80)
- break;
- if (utf8len_tab[p[-j]] != i + j)
- return 0;
+ // Find the next character that isn't 10xx.xxxx
+ for (i = 0; (p[i] & 0xc0) == 0x80; i++) {}
+ if (i > 0) {
+ // Check for illegal sequence.
+ for (j = 0; p - j > base; j++) {
+ if ((p[-j] & 0xc0) != 0x80) {
+ break;
+ }
+ }
+ if (utf8len_tab[p[-j]] != i + j) {
+ return 0;
}
- return i;
}
-
- /* Only need to check if we're on a trail byte, it doesn't matter if we
- * want the offset to the next or current character. */
- return (*mb_head_off)(base, p);
+ return i;
}
/*
@@ -2146,26 +1589,20 @@ int mb_tail_off(char_u *base, char_u *p)
if (*p == NUL)
return 0;
- if (enc_utf8) {
- /* Find the last character that is 10xx.xxxx */
- for (i = 0; (p[i + 1] & 0xc0) == 0x80; ++i)
- ;
- /* Check for illegal sequence. */
- for (j = 0; p - j > base; ++j)
- if ((p[-j] & 0xc0) != 0x80)
- break;
- if (utf8len_tab[p[-j]] != i + j + 1)
- return 0;
- return i;
+ // Find the last character that is 10xx.xxxx
+ for (i = 0; (p[i + 1] & 0xc0) == 0x80; i++) {}
+
+ // Check for illegal sequence.
+ for (j = 0; p - j > base; j++) {
+ if ((p[-j] & 0xc0) != 0x80) {
+ break;
+ }
}
- /* It can't be the first byte if a double-byte when not using DBCS, at the
- * end of the string or the byte can't start a double-byte. */
- if (enc_dbcs == 0 || p[1] == NUL || MB_BYTE2LEN(*p) == 1)
+ if (utf8len_tab[p[-j]] != i + j + 1) {
return 0;
-
- /* Return 1 when on the lead byte, 0 when on the tail byte. */
- return 1 - dbcs_head_off(base, p);
+ }
+ return i;
}
/*
@@ -2180,10 +1617,10 @@ void utf_find_illegal(void)
char_u *tofree = NULL;
vimconv.vc_type = CONV_NONE;
- if (enc_utf8 && (enc_canon_props(curbuf->b_p_fenc) & ENC_8BIT)) {
- /* 'encoding' is "utf-8" but we are editing a 8-bit encoded file,
- * possibly a utf-8 file with illegal bytes. Setup for conversion
- * from utf-8 to 'fileencoding'. */
+ if (enc_canon_props(curbuf->b_p_fenc) & ENC_8BIT) {
+ // 'encoding' is "utf-8" but we are editing a 8-bit encoded file,
+ // possibly a utf-8 file with illegal bytes. Setup for conversion
+ // from utf-8 to 'fileencoding'.
convert_setup(&vimconv, p_enc, curbuf->b_p_fenc);
}
@@ -2240,29 +1677,42 @@ theend:
*/
void mb_adjust_cursor(void)
{
- mb_adjustpos(curbuf, &curwin->w_cursor);
+ mark_mb_adjustpos(curbuf, &curwin->w_cursor);
}
-/*
- * Adjust position "*lp" to point to the first byte of a multi-byte character.
- * If it points to a tail byte it's moved backwards to the head byte.
- */
-void mb_adjustpos(buf_T *buf, pos_T *lp)
+/// Checks and adjusts cursor column. Not mode-dependent.
+/// @see check_cursor_col_win
+///
+/// @param win_ Places cursor on a valid column for this window.
+void mb_check_adjust_col(void *win_)
{
- char_u *p;
+ win_T *win = (win_T *)win_;
+ colnr_T oldcol = win->w_cursor.col;
- if (lp->col > 0
- || lp->coladd > 1
- ) {
- p = ml_get_buf(buf, lp->lnum, FALSE);
- lp->col -= (*mb_head_off)(p, p + lp->col);
- /* Reset "coladd" when the cursor would be on the right half of a
- * double-wide character. */
- if (lp->coladd == 1
- && p[lp->col] != TAB
- && vim_isprintc((*mb_ptr2char)(p + lp->col))
- && ptr2cells(p + lp->col) > 1)
- lp->coladd = 0;
+ // Column 0 is always valid.
+ if (oldcol != 0) {
+ char_u *p = ml_get_buf(win->w_buffer, win->w_cursor.lnum, false);
+ colnr_T len = (colnr_T)STRLEN(p);
+
+ // Empty line or invalid column?
+ if (len == 0 || oldcol < 0) {
+ win->w_cursor.col = 0;
+ } else {
+ // Cursor column too big for line?
+ if (oldcol > len) {
+ win->w_cursor.col = len - 1;
+ }
+ // Move the cursor to the head byte.
+ win->w_cursor.col -= utf_head_off(p, p + win->w_cursor.col);
+ }
+
+ // Reset `coladd` when the cursor would be on the right half of a
+ // double-wide character.
+ if (win->w_cursor.coladd == 1 && p[win->w_cursor.col] != TAB
+ && vim_isprintc(utf_ptr2char(p + win->w_cursor.col))
+ && ptr2cells(p + win->w_cursor.col) > 1) {
+ win->w_cursor.coladd = 0;
+ }
}
}
@@ -2274,8 +1724,9 @@ char_u * mb_prevptr(
char_u *p
)
{
- if (p > line)
- mb_ptr_back(line, p);
+ if (p > line) {
+ MB_PTR_BACK(line, p);
+ }
return p;
}
@@ -2311,85 +1762,59 @@ int mb_charlen_len(char_u *str, int len)
return count;
}
-/*
- * Try to un-escape a multi-byte character.
- * Used for the "to" and "from" part of a mapping.
- * Return the un-escaped string if it is a multi-byte character, and advance
- * "pp" to just after the bytes that formed it.
- * Return NULL if no multi-byte char was found.
- */
-char_u * mb_unescape(char_u **pp)
-{
- static char_u buf[6];
- int n;
- int m = 0;
- char_u *str = *pp;
-
- /* Must translate K_SPECIAL KS_SPECIAL KE_FILLER to K_SPECIAL and CSI
- * KS_EXTRA KE_CSI to CSI.
- * Maximum length of a utf-8 character is 4 bytes. */
- for (n = 0; str[n] != NUL && m < 4; ++n) {
- if (str[n] == K_SPECIAL
- && str[n + 1] == KS_SPECIAL
- && str[n + 2] == KE_FILLER) {
- buf[m++] = K_SPECIAL;
- n += 2;
- } else if ((str[n] == K_SPECIAL
- )
- && str[n + 1] == KS_EXTRA
- && str[n + 2] == (int)KE_CSI) {
- buf[m++] = CSI;
- n += 2;
- } else if (str[n] == K_SPECIAL
- )
- break; /* a special key can't be a multibyte char */
- else
- buf[m++] = str[n];
- buf[m] = NUL;
+/// Try to unescape a multibyte character
+///
+/// Used for the rhs and lhs of the mappings.
+///
+/// @param[in,out] pp String to unescape. Is advanced to just after the bytes
+/// that form a multibyte character.
+///
+/// @return Unescaped string if it is a multibyte character, NULL if no
+/// multibyte character was found. Returns a static buffer, always one
+/// and the same.
+const char *mb_unescape(const char **const pp)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ static char buf[6];
+ size_t buf_idx = 0;
+ uint8_t *str = (uint8_t *)(*pp);
+
+ // Must translate K_SPECIAL KS_SPECIAL KE_FILLER to K_SPECIAL and CSI
+ // KS_EXTRA KE_CSI to CSI.
+ // Maximum length of a utf-8 character is 4 bytes.
+ for (size_t str_idx = 0; str[str_idx] != NUL && buf_idx < 4; str_idx++) {
+ if (str[str_idx] == K_SPECIAL
+ && str[str_idx + 1] == KS_SPECIAL
+ && str[str_idx + 2] == KE_FILLER) {
+ buf[buf_idx++] = (char)K_SPECIAL;
+ str_idx += 2;
+ } else if ((str[str_idx] == K_SPECIAL)
+ && str[str_idx + 1] == KS_EXTRA
+ && str[str_idx + 2] == KE_CSI) {
+ buf[buf_idx++] = (char)CSI;
+ str_idx += 2;
+ } else if (str[str_idx] == K_SPECIAL) {
+ break; // A special key can't be a multibyte char.
+ } else {
+ buf[buf_idx++] = (char)str[str_idx];
+ }
+ buf[buf_idx] = NUL;
- /* Return a multi-byte character if it's found. An illegal sequence
- * will result in a 1 here. */
- if ((*mb_ptr2len)(buf) > 1) {
- *pp = str + n + 1;
+ // Return a multi-byte character if it's found. An illegal sequence
+ // will result in a 1 here.
+ if (utf_ptr2len((const char_u *)buf) > 1) {
+ *pp = (const char *)str + str_idx + 1;
return buf;
}
- /* Bail out quickly for ASCII. */
- if (buf[0] < 128)
+ // Bail out quickly for ASCII.
+ if ((uint8_t)buf[0] < 128) {
break;
+ }
}
return NULL;
}
-/*
- * Return true if the character at "row"/"col" on the screen is the left side
- * of a double-width character.
- * Caller must make sure "row" and "col" are not invalid!
- */
-bool mb_lefthalve(int row, int col)
-{
- return (*mb_off2cells)(LineOffset[row] + col,
- LineOffset[row] + screen_Columns) > 1;
-}
-
-/*
- * Correct a position on the screen, if it's the right half of a double-wide
- * char move it to the left half. Returns the corrected column.
- */
-int mb_fix_col(int col, int row)
-{
- col = check_col(col);
- row = check_row(row);
- if (has_mbyte && ScreenLines != NULL && col > 0
- && ((enc_dbcs
- && ScreenLines[LineOffset[row] + col] != NUL
- && dbcs_screen_head_off(ScreenLines + LineOffset[row],
- ScreenLines + LineOffset[row] + col))
- || (enc_utf8 && ScreenLines[LineOffset[row] + col] == 0)))
- return col - 1;
- return col;
-}
-
/*
* Skip the Vim specific head of a 'encoding' name.
@@ -2515,36 +1940,39 @@ char_u * enc_locale(void)
return NULL;
}
- /* The most generic locale format is:
- * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
- * If there is a '.' remove the part before it.
- * if there is something after the codeset, remove it.
- * Make the name lowercase and replace '_' with '-'.
- * Exception: "ja_JP.EUC" == "euc-jp", "zh_CN.EUC" = "euc-cn",
- * "ko_KR.EUC" == "euc-kr"
- */
+ // The most generic locale format is:
+ // language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
+ // If there is a '.' remove the part before it.
+ // if there is something after the codeset, remove it.
+ // Make the name lowercase and replace '_' with '-'.
+ // Exception: "ja_JP.EUC" == "euc-jp", "zh_CN.EUC" = "euc-cn",
+ // "ko_KR.EUC" == "euc-kr"
const char *p = (char *)vim_strchr((char_u *)s, '.');
if (p != NULL) {
if (p > s + 2 && !STRNICMP(p + 1, "EUC", 3)
&& !isalnum((int)p[4]) && p[4] != '-' && p[-3] == '_') {
- /* copy "XY.EUC" to "euc-XY" to buf[10] */
- strcpy(buf + 10, "euc-");
- buf[14] = p[-2];
- buf[15] = p[-1];
- buf[16] = 0;
- s = buf + 10;
- } else
+ // Copy "XY.EUC" to "euc-XY" to buf[10].
+ memmove(buf, "euc-", 4);
+ buf[4] = (ASCII_ISALNUM(p[-2]) ? TOLOWER_ASC(p[-2]) : 0);
+ buf[5] = (ASCII_ISALNUM(p[-1]) ? TOLOWER_ASC(p[-1]) : 0);
+ buf[6] = NUL;
+ } else {
s = p + 1;
+ goto enc_locale_copy_enc;
+ }
+ } else {
+enc_locale_copy_enc:
+ for (i = 0; i < (int)sizeof(buf) - 1 && s[i] != NUL; i++) {
+ if (s[i] == '_' || s[i] == '-') {
+ buf[i] = '-';
+ } else if (ASCII_ISALNUM((uint8_t)s[i])) {
+ buf[i] = TOLOWER_ASC(s[i]);
+ } else {
+ break;
+ }
+ }
+ buf[i] = NUL;
}
- for (i = 0; s[i] != NUL && i < (int)sizeof(buf) - 1; ++i) {
- if (s[i] == '_' || s[i] == '-')
- buf[i] = '-';
- else if (isalnum((int)s[i]))
- buf[i] = TOLOWER_ASC(s[i]);
- else
- break;
- }
- buf[i] = NUL;
return enc_canonize((char_u *)buf);
}
@@ -2571,9 +1999,10 @@ void * my_iconv_open(char_u *to, char_u *from)
return (void *)-1; /* detected a broken iconv() previously */
#ifdef DYNAMIC_ICONV
- /* Check if the iconv.dll can be found. */
- if (!iconv_enabled(true))
+ // Check if the iconv.dll can be found.
+ if (!iconv_enabled(true)) {
return (void *)-1;
+ }
#endif
fd = iconv_open((char *)enc_skip(to), (char *)enc_skip(from));
@@ -2607,8 +2036,8 @@ void * my_iconv_open(char_u *to, char_u *from)
* Returns the converted string in allocated memory. NULL for an error.
* If resultlenp is not NULL, sets it to the result length in bytes.
*/
-static char_u * iconv_string(vimconv_T *vcp, char_u *str, size_t slen,
- size_t *unconvlenp, size_t *resultlenp)
+static char_u *iconv_string(const vimconv_T *const vcp, char_u *str,
+ size_t slen, size_t *unconvlenp, size_t *resultlenp)
{
const char *from;
size_t fromlen;
@@ -2662,15 +2091,10 @@ static char_u * iconv_string(vimconv_T *vcp, char_u *str, size_t slen,
* conversion from 'encoding' to something else. In other
* situations we don't know what to skip anyway. */
*to++ = '?';
- if ((*mb_ptr2cells)((char_u *)from) > 1)
+ if (utf_ptr2cells((char_u *)from) > 1) {
*to++ = '?';
- if (enc_utf8)
- l = utfc_ptr2len_len((const char_u *)from, (int)fromlen);
- else {
- l = (*mb_ptr2len)((char_u *)from);
- if (l > (int)fromlen)
- l = (int)fromlen;
}
+ l = utfc_ptr2len_len((const char_u *)from, (int)fromlen);
from += l;
fromlen -= l;
} else if (ICONV_ERRNO != ICONV_E2BIG) {
@@ -2701,7 +2125,7 @@ static HINSTANCE hMsvcrtDLL = 0;
# ifndef DYNAMIC_ICONV_DLL
# define DYNAMIC_ICONV_DLL "iconv.dll"
-# define DYNAMIC_ICONV_DLL_ALT "libiconv.dll"
+# define DYNAMIC_ICONV_DLL_ALT "libiconv-2.dll"
# endif
# ifndef DYNAMIC_MSVCRT_DLL
# define DYNAMIC_MSVCRT_DLL "msvcrt.dll"
@@ -2747,6 +2171,35 @@ static void * get_iconv_import_func(HINSTANCE hInst,
return NULL;
}
+// Load library "name".
+HINSTANCE vimLoadLib(char *name)
+{
+ HINSTANCE dll = NULL;
+
+ // NOTE: Do not use mch_dirname() and mch_chdir() here, they may call
+ // vimLoadLib() recursively, which causes a stack overflow.
+ wchar_t old_dirw[MAXPATHL];
+
+ // Path to exe dir.
+ char *buf = xstrdup((char *)get_vim_var_str(VV_PROGPATH));
+ // ptrdiff_t len = ;
+ // assert(len > 0);
+ buf[path_tail_with_sep(buf) - buf] = '\0';
+
+ if (GetCurrentDirectoryW(MAXPATHL, old_dirw) != 0) {
+ // Change directory to where the executable is, both to make
+ // sure we find a .dll there and to avoid looking for a .dll
+ // in the current directory.
+ SetCurrentDirectory((LPCSTR)buf);
+ // TODO(justinmk): use uv_dlopen instead. see os_libcall
+ dll = LoadLibrary(name);
+ SetCurrentDirectoryW(old_dirw);
+ }
+
+ return dll;
+}
+
+
/*
* Try opening the iconv.dll and return TRUE if iconv() can be used.
*/
@@ -2794,10 +2247,13 @@ bool iconv_enabled(bool verbose)
void iconv_end(void)
{
- if (hIconvDLL != 0)
+ if (hIconvDLL != 0) {
+ // TODO(justinmk): use uv_dlclose instead.
FreeLibrary(hIconvDLL);
- if (hMsvcrtDLL != 0)
+ }
+ if (hMsvcrtDLL != 0) {
FreeLibrary(hMsvcrtDLL);
+ }
hIconvDLL = 0;
hMsvcrtDLL = 0;
}
@@ -2839,9 +2295,7 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8,
if (vcp->vc_type == CONV_ICONV && vcp->vc_fd != (iconv_t)-1)
iconv_close(vcp->vc_fd);
# endif
- vcp->vc_type = CONV_NONE;
- vcp->vc_factor = 1;
- vcp->vc_fail = false;
+ *vcp = (vimconv_T)MBYTE_NONE_CONV;
/* No conversion when one of the names is empty or they are equal. */
if (from == NULL || *from == NUL || to == NULL || *to == NUL
@@ -2899,7 +2353,7 @@ int convert_setup_ext(vimconv_T *vcp, char_u *from, bool from_unicode_is_utf8,
* Illegal chars are often changed to "?", unless vcp->vc_fail is set.
* When something goes wrong, NULL is returned and "*lenp" is unchanged.
*/
-char_u * string_convert(vimconv_T *vcp, char_u *ptr, size_t *lenp)
+char_u *string_convert(const vimconv_T *const vcp, char_u *ptr, size_t *lenp)
{
return string_convert_ext(vcp, ptr, lenp, NULL);
}
@@ -2909,7 +2363,7 @@ char_u * string_convert(vimconv_T *vcp, char_u *ptr, size_t *lenp)
* an incomplete sequence at the end it is not converted and "*unconvlenp" is
* set to the number of remaining bytes.
*/
-char_u * string_convert_ext(vimconv_T *vcp, char_u *ptr,
+char_u * string_convert_ext(const vimconv_T *const vcp, char_u *ptr,
size_t *lenp, size_t *unconvlenp)
{
char_u *retval = NULL;
@@ -3037,23 +2491,3 @@ char_u * string_convert_ext(vimconv_T *vcp, char_u *ptr,
return retval;
}
-
-// Check bounds for column number
-static int check_col(int col)
-{
- if (col < 0)
- return 0;
- if (col >= screen_Columns)
- return screen_Columns - 1;
- return col;
-}
-
-// Check bounds for row number
-static int check_row(int row)
-{
- if (row < 0)
- return 0;
- if (row >= screen_Rows)
- return screen_Rows - 1;
- return row;
-}
diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h
index 0cfe2c4bab..ed48705c6d 100644
--- a/src/nvim/mbyte.h
+++ b/src/nvim/mbyte.h
@@ -1,7 +1,14 @@
#ifndef NVIM_MBYTE_H
#define NVIM_MBYTE_H
+#include <stdint.h>
#include <stdbool.h>
+#include <string.h>
+
+#include "nvim/iconv.h"
+#include "nvim/func_attr.h"
+#include "nvim/os/os_defs.h" // For indirect
+#include "nvim/types.h" // for char_u
/*
* Return byte length of character that starts with byte "b".
@@ -9,8 +16,11 @@
* MB_BYTE2LEN_CHECK() can be used to count a special key as one byte.
* Don't call MB_BYTE2LEN(b) with b < 0 or b > 255!
*/
-#define MB_BYTE2LEN(b) mb_bytelen_tab[b]
-#define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : mb_bytelen_tab[b])
+#define MB_BYTE2LEN(b) utf8len_tab[b]
+#define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : utf8len_tab[b])
+
+// max length of an unicode char
+#define MB_MAXCHAR 6
/* properties used in enc_canon_table[] (first three mutually exclusive) */
#define ENC_8BIT 0x01
@@ -28,7 +38,56 @@
#define ENC_LATIN9 0x400 /* Latin9 */
#define ENC_MACROMAN 0x800 /* Mac Roman (not Macro Man! :-) */
+// TODO(bfredl): eventually we should keep only one of the namings
+#define mb_ptr2len utfc_ptr2len
+#define mb_char2len utf_char2len
+#define mb_char2cells utf_char2cells
+
+/// Flags for vimconv_T
+typedef enum {
+ CONV_NONE = 0,
+ CONV_TO_UTF8 = 1,
+ CONV_9_TO_UTF8 = 2,
+ CONV_TO_LATIN1 = 3,
+ CONV_TO_LATIN9 = 4,
+ CONV_ICONV = 5,
+} ConvFlags;
+
+#define MBYTE_NONE_CONV { \
+ .vc_type = CONV_NONE, \
+ .vc_factor = 1, \
+ .vc_fail = false, \
+}
+
+/// Structure used for string conversions
+typedef struct {
+ int vc_type; ///< Zero or more ConvFlags.
+ int vc_factor; ///< Maximal expansion factor.
+# ifdef USE_ICONV
+ iconv_t vc_fd; ///< Value for CONV_ICONV.
+# endif
+ bool vc_fail; ///< What to do with invalid characters: if true, fail,
+ ///< otherwise use '?'.
+} vimconv_T;
+
+extern const uint8_t utf8len_tab_zero[256];
+
+extern const uint8_t utf8len_tab[256];
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mbyte.h.generated.h"
#endif
+
+static inline int mb_strcmp_ic(bool ic, const char *s1, const char *s2)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT;
+
+/// Compare strings
+///
+/// @param[in] ic True if case is to be ignored.
+///
+/// @return 0 if s1 == s2, <0 if s1 < s2, >0 if s1 > s2.
+static inline int mb_strcmp_ic(bool ic, const char *s1, const char *s2)
+{
+ return (ic ? mb_stricmp(s1, s2) : strcmp(s1, s2));
+}
#endif // NVIM_MBYTE_H
diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c
index 9fb03c4ac7..0a16f8aafb 100644
--- a/src/nvim/memfile.c
+++ b/src/nvim/memfile.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
+
/// An abstraction to handle blocks of memory which can be stored in a file.
/// This is the implementation of a sort of virtual memory.
///
@@ -48,18 +51,16 @@
#include "nvim/fileio.h"
#include "nvim/memline.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/assert.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
#define MEMFILE_PAGE_SIZE 4096 /// default page size
-static size_t total_mem_used = 0; /// total memory used for memfiles
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "memfile.c.generated.h"
#endif
@@ -76,7 +77,7 @@ static size_t total_mem_used = 0; /// total memory used for memfiles
/// @param flags Flags for open() call.
///
/// @return - The open memory file, on success.
-/// - NULL, on failure.
+/// - NULL, on failure (e.g. file does not exist).
memfile_T *mf_open(char_u *fname, int flags)
{
memfile_T *mfp = xmalloc(sizeof(memfile_T));
@@ -96,7 +97,6 @@ memfile_T *mf_open(char_u *fname, int flags)
mfp->mf_used_first = NULL; // used list is empty
mfp->mf_used_last = NULL;
mfp->mf_dirty = false;
- mfp->mf_used_count = 0;
mf_hash_init(&mfp->mf_hash);
mf_hash_init(&mfp->mf_trans);
mfp->mf_page_size = MEMFILE_PAGE_SIZE;
@@ -106,23 +106,24 @@ memfile_T *mf_open(char_u *fname, int flags)
if (mfp->mf_fd >= 0 && os_fileinfo_fd(mfp->mf_fd, &file_info)) {
uint64_t blocksize = os_fileinfo_blocksize(&file_info);
if (blocksize >= MIN_SWAP_PAGE_SIZE && blocksize <= MAX_SWAP_PAGE_SIZE) {
- assert(blocksize <= UINT_MAX);
+ STATIC_ASSERT(MAX_SWAP_PAGE_SIZE <= UINT_MAX,
+ "MAX_SWAP_PAGE_SIZE must fit into an unsigned");
mfp->mf_page_size = (unsigned)blocksize;
}
}
- off_t size;
+ off_T size;
// When recovering, the actual block size will be retrieved from block 0
// in ml_recover(). The size used here may be wrong, therefore mf_blocknr_max
// must be rounded up.
if (mfp->mf_fd < 0
|| (flags & (O_TRUNC|O_EXCL))
- || (size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0) {
+ || (size = vim_lseek(mfp->mf_fd, 0L, SEEK_END)) <= 0) {
// no file or empty file
mfp->mf_blocknr_max = 0;
} else {
- assert(sizeof(off_t) <= sizeof(blocknr_T)
+ assert(sizeof(off_T) <= sizeof(blocknr_T)
&& mfp->mf_page_size > 0
&& mfp->mf_page_size - 1 <= INT64_MAX - size);
mfp->mf_blocknr_max = (((blocknr_T)size + mfp->mf_page_size - 1)
@@ -132,25 +133,6 @@ memfile_T *mf_open(char_u *fname, int flags)
mfp->mf_neg_count = 0;
mfp->mf_infile_count = mfp->mf_blocknr_max;
- // Compute maximum number of pages ('maxmem' is in Kbytes):
- // 'mammem' * 1Kbyte / page-size-in-bytes.
- // Avoid overflow by first reducing page size as much as possible.
- {
- int shift = 10;
- unsigned page_size = mfp->mf_page_size;
-
- while (shift > 0 && (page_size & 1) == 0) {
- page_size /= 2;
- --shift;
- }
-
- assert(p_mm <= LONG_MAX >> shift); // check we don't overflow
- assert((uintmax_t)(p_mm << shift) <= UINT_MAX); // check we can cast safely
- mfp->mf_used_count_max = (unsigned)(p_mm << shift) / page_size;
- if (mfp->mf_used_count_max < 10)
- mfp->mf_used_count_max = 10;
- }
-
return mfp;
}
@@ -194,7 +176,6 @@ void mf_close(memfile_T *mfp, bool del_file)
// free entries in used list
for (bhdr_T *hp = mfp->mf_used_first, *nextp; hp != NULL; hp = nextp) {
- total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
nextp = hp->bh_next;
mf_free_bhdr(hp);
}
@@ -219,12 +200,9 @@ void mf_close_file(buf_T *buf, bool getlines)
if (getlines) {
// get all blocks in memory by accessing all lines (clumsy!)
- mf_dont_release = true;
- for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum) {
+ for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
(void)ml_get_buf(buf, lnum, false);
}
- mf_dont_release = false;
- // TODO(elmart): should check if all blocks are really in core
}
if (close(mfp->mf_fd) < 0) { // close the file
@@ -242,13 +220,6 @@ void mf_close_file(buf_T *buf, bool getlines)
/// and the size it indicates differs from what was guessed.
void mf_new_page_size(memfile_T *mfp, unsigned new_size)
{
- // Correct the memory used for block 0 to the new size, because it will be
- // freed with that size later on.
- if (new_size >= mfp->mf_page_size) {
- total_mem_used += new_size - mfp->mf_page_size;
- } else {
- total_mem_used -= mfp->mf_page_size - new_size;
- }
mfp->mf_page_size = new_size;
}
@@ -258,10 +229,7 @@ void mf_new_page_size(memfile_T *mfp, unsigned new_size)
/// @param page_count Desired number of pages.
bhdr_T *mf_new(memfile_T *mfp, bool negative, unsigned page_count)
{
- // If we reached the maximum size for the used memory blocks, release one.
- // If a bhdr_T is returned, use it and adjust the page_count if necessary.
- // If no bhdr_T is returned, a new one will be created.
- bhdr_T *hp = mf_release(mfp, page_count); // the block to be returned
+ bhdr_T *hp = NULL;
// Decide on the number to use:
// If there is a free block, use its number.
@@ -269,34 +237,22 @@ bhdr_T *mf_new(memfile_T *mfp, bool negative, unsigned page_count)
// a positive number.
bhdr_T *freep = mfp->mf_free_first; // first free block
if (!negative && freep != NULL && freep->bh_page_count >= page_count) {
- // If the block in the free list has more pages, take only the number
- // of pages needed and allocate a new bhdr_T with data.
- //
- // If the number of pages matches and mf_release() did not return a
- // bhdr_T, use the bhdr_T from the free list and allocate the data.
- //
- // If the number of pages matches and mf_release() returned a bhdr_T,
- // just use the number and free the bhdr_T from the free list
if (freep->bh_page_count > page_count) {
- if (hp == NULL) {
- hp = mf_alloc_bhdr(mfp, page_count);
- }
+ // If the block in the free list has more pages, take only the number
+ // of pages needed and allocate a new bhdr_T with data.
+ hp = mf_alloc_bhdr(mfp, page_count);
hp->bh_bnum = freep->bh_bnum;
freep->bh_bnum += page_count;
freep->bh_page_count -= page_count;
- } else if (hp == NULL) { // need to allocate memory for this block
+ } else { // need to allocate memory for this block
+ // If the number of pages matches use the bhdr_T from the free list and
+ // allocate the data.
void *p = xmalloc(mfp->mf_page_size * page_count);
hp = mf_rem_free(mfp);
hp->bh_data = p;
- } else { // use the number, remove entry from free list
- freep = mf_rem_free(mfp);
- hp->bh_bnum = freep->bh_bnum;
- xfree(freep);
}
} else { // get a new number
- if (hp == NULL) {
- hp = mf_alloc_bhdr(mfp, page_count);
- }
+ hp = mf_alloc_bhdr(mfp, page_count);
if (negative) {
hp->bh_bnum = mfp->mf_blocknr_min--;
mfp->mf_neg_count++;
@@ -337,13 +293,7 @@ bhdr_T *mf_get(memfile_T *mfp, blocknr_T nr, unsigned page_count)
// could check here if the block is in the free list
- // Check if we need to flush an existing block.
- // If so, use that block.
- // If not, allocate a new block.
- hp = mf_release(mfp, page_count);
- if (hp == NULL) {
- hp = mf_alloc_bhdr(mfp, page_count);
- }
+ hp = mf_alloc_bhdr(mfp, page_count);
hp->bh_bnum = nr;
hp->bh_flags = 0;
@@ -372,8 +322,9 @@ void mf_put(memfile_T *mfp, bhdr_T *hp, bool dirty, bool infile)
{
unsigned flags = hp->bh_flags;
- if ((flags & BH_LOCKED) == 0)
- EMSG(_("E293: block was not locked"));
+ if ((flags & BH_LOCKED) == 0) {
+ IEMSG(_("E293: block was not locked"));
+ }
flags &= ~BH_LOCKED;
if (dirty) {
flags |= BH_DIRTY;
@@ -509,8 +460,6 @@ static void mf_ins_used(memfile_T *mfp, bhdr_T *hp)
} else {
hp->bh_next->bh_prev = hp;
}
- mfp->mf_used_count += hp->bh_page_count;
- total_mem_used += hp->bh_page_count * mfp->mf_page_size;
}
/// Remove block from memfile's used list.
@@ -525,82 +474,6 @@ static void mf_rem_used(memfile_T *mfp, bhdr_T *hp)
mfp->mf_used_first = hp->bh_next;
else
hp->bh_prev->bh_next = hp->bh_next;
-
- mfp->mf_used_count -= hp->bh_page_count;
- total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
-}
-
-/// Try to release the least recently used block from the used list if the
-/// number of used memory blocks gets too big.
-///
-/// @return The block header, when release needed and possible.
-/// Resulting block header includes memory block, so it can be
-/// reused. Page count is checked to be right.
-/// NULL, when release not needed, or not possible.
-/// Not needed when number of blocks less than allowed maximum and
-/// total memory used below 'maxmemtot'.
-/// Not possible when:
-/// - Called while closing file.
-/// - Tried to create swap file but couldn't.
-/// - All blocks are locked.
-/// - Unlocked dirty block found, but flush failed.
-static bhdr_T *mf_release(memfile_T *mfp, unsigned page_count)
-{
- // don't release while in mf_close_file()
- if (mf_dont_release)
- return NULL;
-
- /// Need to release a block if the number of blocks for this memfile is
- /// higher than the maximum one or total memory used is over 'maxmemtot'.
- bool need_release = (mfp->mf_used_count >= mfp->mf_used_count_max
- || (total_mem_used >> 10) >= (size_t)p_mmt);
-
- /// Try to create swap file if the amount of memory used is getting too high.
- if (mfp->mf_fd < 0 && need_release && p_uc) {
- // find for which buffer this memfile is
- buf_T *buf = NULL;
- FOR_ALL_BUFFERS(bp) {
- if (bp->b_ml.ml_mfp == mfp) {
- buf = bp;
- break;
- }
- }
- if (buf != NULL && buf->b_may_swap) {
- ml_open_file(buf);
- }
- }
-
- /// Don't release a block if:
- /// there is no file for this memfile
- /// or
- /// the number of blocks for this memfile is lower than the maximum
- /// and
- /// total memory used is not up to 'maxmemtot'
- if (mfp->mf_fd < 0 || !need_release)
- return NULL;
-
- bhdr_T *hp;
- for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
- if (!(hp->bh_flags & BH_LOCKED))
- break;
- if (hp == NULL) // not a single one that can be released
- return NULL;
-
- // If the block is dirty, write it.
- // If the write fails we don't free it.
- if ((hp->bh_flags & BH_DIRTY) && mf_write(mfp, hp) == FAIL)
- return NULL;
-
- mf_rem_used(mfp, hp);
- mf_rem_hash(mfp, hp);
-
- /// Make sure page_count of bh_data is right.
- if (hp->bh_page_count != page_count) {
- xfree(hp->bh_data);
- hp->bh_data = xmalloc(mfp->mf_page_size * page_count);
- hp->bh_page_count = page_count;
- }
- return hp;
}
/// Release as many blocks as possible.
@@ -685,9 +558,9 @@ static int mf_read(memfile_T *mfp, bhdr_T *hp)
return FAIL;
unsigned page_size = mfp->mf_page_size;
- // TODO(elmart): Check (page_size * hp->bh_bnum) within off_t bounds.
- off_t offset = (off_t)(page_size * hp->bh_bnum);
- if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
+ // TODO(elmart): Check (page_size * hp->bh_bnum) within off_T bounds.
+ off_T offset = (off_T)(page_size * hp->bh_bnum);
+ if (vim_lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
PERROR(_("E294: Seek error in swap file read"));
return FAIL;
}
@@ -712,7 +585,7 @@ static int mf_read(memfile_T *mfp, bhdr_T *hp)
/// - Write error in swap file.
static int mf_write(memfile_T *mfp, bhdr_T *hp)
{
- off_t offset; // offset in the file
+ off_T offset; // offset in the file
blocknr_T nr; // block nr which is being written
bhdr_T *hp2;
unsigned page_size; // number of bytes in a page
@@ -741,9 +614,9 @@ static int mf_write(memfile_T *mfp, bhdr_T *hp)
hp2 = hp;
}
- // TODO(elmart): Check (page_size * nr) within off_t bounds.
- offset = (off_t)(page_size * nr);
- if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
+ // TODO(elmart): Check (page_size * nr) within off_T bounds.
+ offset = (off_T)(page_size * nr);
+ if (vim_lseek(mfp->mf_fd, offset, SEEK_SET) != offset) {
PERROR(_("E296: Seek error in swap file write"));
return FAIL;
}
@@ -891,6 +764,7 @@ static bool mf_do_open(memfile_T *mfp, char_u *fname, int flags)
{
// fname cannot be NameBuff, because it must have been allocated.
mf_set_fnames(mfp, fname);
+ assert(mfp->mf_fname != NULL);
/// Extra security check: When creating a swap file it really shouldn't
/// exist yet. If there is a symbolic link, this is most likely an attack.
@@ -910,12 +784,7 @@ static bool mf_do_open(memfile_T *mfp, char_u *fname, int flags)
return false;
}
-#ifdef HAVE_FD_CLOEXEC
- int fdflags = fcntl(mfp->mf_fd, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
- (void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
- }
-#endif
+ (void)os_set_cloexec(mfp->mf_fd);
#ifdef HAVE_SELINUX
mch_copy_sec(fname, mfp->mf_fname);
#endif
diff --git a/src/nvim/memfile_defs.h b/src/nvim/memfile_defs.h
index cc71e1a7ff..2402d2147d 100644
--- a/src/nvim/memfile_defs.h
+++ b/src/nvim/memfile_defs.h
@@ -3,8 +3,10 @@
#include <stdint.h>
#include <stdbool.h>
+#include <stdlib.h>
#include "nvim/types.h"
+#include "nvim/pos.h"
/// A block number.
///
@@ -54,7 +56,6 @@ typedef struct mf_hashtab {
///
/// The used list is a doubly linked list, most recently used block first.
/// The blocks in the used list have a block of memory allocated.
-/// mf_used_count is the number of pages in the used list.
/// The hash lists are used to quickly find a block in the used list.
/// The free list is a single linked list, not sorted.
/// The blocks in the free list have no block of memory allocated and
@@ -93,8 +94,6 @@ typedef struct memfile {
bhdr_T *mf_free_first; /// first block header in free list
bhdr_T *mf_used_first; /// mru block header in used list
bhdr_T *mf_used_last; /// lru block header in used list
- unsigned mf_used_count; /// number of pages in used list
- unsigned mf_used_count_max; /// maximum number of pages in memory
mf_hashtab_T mf_hash; /// hash lists
mf_hashtab_T mf_trans; /// trans lists
blocknr_T mf_blocknr_max; /// highest positive block number + 1
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 673205f08f..4c4f7d65bd 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.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
+
/* for debugging */
/* #define CHECK(c, s) if (c) EMSG(s) */
#define CHECK(c, s)
@@ -46,6 +49,7 @@
#include "nvim/buffer.h"
#include "nvim/cursor.h"
#include "nvim/eval.h"
+#include "nvim/getchar.h"
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/main.h"
@@ -55,7 +59,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/option.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
@@ -244,7 +247,6 @@ typedef enum {
*/
int ml_open(buf_T *buf)
{
- memfile_T *mfp;
bhdr_T *hp = NULL;
ZERO_BL *b0p;
PTR_BL *pp;
@@ -273,12 +275,11 @@ int ml_open(buf_T *buf)
buf->b_may_swap = false;
}
- /*
- * Open the memfile. No swap file is created yet.
- */
- mfp = mf_open(NULL, 0);
- if (mfp == NULL)
+ // Open the memfile. No swap file is created yet.
+ memfile_T *mfp = mf_open(NULL, 0);
+ if (mfp == NULL) {
goto error;
+ }
buf->b_ml.ml_mfp = mfp;
buf->b_ml.ml_flags = ML_EMPTY;
@@ -291,7 +292,7 @@ int ml_open(buf_T *buf)
*/
hp = mf_new(mfp, false, 1);
if (hp->bh_bnum != 0) {
- EMSG(_("E298: Didn't get block nr 0?"));
+ IEMSG(_("E298: Didn't get block nr 0?"));
goto error;
}
b0p = hp->bh_data;
@@ -333,7 +334,7 @@ int ml_open(buf_T *buf)
if ((hp = ml_new_ptr(mfp)) == NULL)
goto error;
if (hp->bh_bnum != 1) {
- EMSG(_("E298: Didn't get block nr 1?"));
+ IEMSG(_("E298: Didn't get block nr 1?"));
goto error;
}
pp = hp->bh_data;
@@ -349,7 +350,7 @@ int ml_open(buf_T *buf)
*/
hp = ml_new_data(mfp, FALSE, 1);
if (hp->bh_bnum != 2) {
- EMSG(_("E298: Didn't get block nr 2?"));
+ IEMSG(_("E298: Didn't get block nr 2?"));
goto error;
}
@@ -363,9 +364,10 @@ int ml_open(buf_T *buf)
error:
if (mfp != NULL) {
- if (hp)
+ if (hp) {
mf_put(mfp, hp, false, false);
- mf_close(mfp, true); /* will also xfree(mfp->mf_fname) */
+ }
+ mf_close(mfp, true); // will also xfree(mfp->mf_fname)
}
buf->b_ml.ml_mfp = NULL;
return FAIL;
@@ -440,14 +442,7 @@ void ml_setname(buf_T *buf)
EMSG(_("E301: Oops, lost the swap file!!!"));
return;
}
-#ifdef HAVE_FD_CLOEXEC
- {
- int fdflags = fcntl(mfp->mf_fd, F_GETFD);
- if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) {
- (void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
- }
- }
-#endif
+ (void)os_set_cloexec(mfp->mf_fd);
}
if (!success)
EMSG(_("E302: Could not rename swap file"));
@@ -539,17 +534,20 @@ void ml_open_file(buf_T *buf)
buf->b_may_swap = false;
}
-/*
- * If still need to create a swap file, and starting to edit a not-readonly
- * file, or reading into an existing buffer, create a swap file now.
- */
-void
-check_need_swap (
- int newfile /* reading file into new buffer */
-)
+/// If still need to create a swap file, and starting to edit a not-readonly
+/// file, or reading into an existing buffer, create a swap file now.
+///
+/// @param newfile reading file into new buffer
+void check_need_swap(int newfile)
{
- if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
+ int old_msg_silent = msg_silent; // might be reset by an E325 message
+ msg_silent = 0; // If swap dialog prompts for input, user needs to see it!
+
+ if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile)) {
ml_open_file(curbuf);
+ }
+
+ msg_silent = old_msg_silent;
}
/*
@@ -624,7 +622,7 @@ static bool ml_check_b0_strings(ZERO_BL *b0p)
return (memchr(b0p->b0_version, NUL, 10)
&& memchr(b0p->b0_uname, NUL, B0_UNAME_SIZE)
&& memchr(b0p->b0_hname, NUL, B0_HNAME_SIZE)
- && memchr(b0p->b0_fname, NUL, B0_FNAME_SIZE_CRYPT));
+ && memchr(b0p->b0_fname, NUL, B0_FNAME_SIZE_CRYPT)); // -V512
}
/*
@@ -640,13 +638,14 @@ static void ml_upd_block0(buf_T *buf, upd_block0_T what)
if (mfp == NULL || (hp = mf_get(mfp, 0, 1)) == NULL)
return;
b0p = hp->bh_data;
- if (ml_check_b0_id(b0p) == FAIL)
- EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
- else {
- if (what == UB_FNAME)
+ if (ml_check_b0_id(b0p) == FAIL) {
+ IEMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
+ } else {
+ if (what == UB_FNAME) {
set_b0_fname(b0p, buf);
- else /* what == UB_SAME_DIR */
+ } else { // what == UB_SAME_DIR
set_b0_dir_flag(b0p, buf);
+ }
}
mf_put(mfp, hp, true, false);
}
@@ -768,7 +767,7 @@ void ml_recover(void)
int idx;
int top;
int txt_start;
- off_t size;
+ off_T size;
int called_from_main;
int serious_error = TRUE;
long mtime;
@@ -777,19 +776,18 @@ void ml_recover(void)
recoverymode = TRUE;
called_from_main = (curbuf->b_ml.ml_mfp == NULL);
- attr = hl_attr(HLF_E);
+ attr = HL_ATTR(HLF_E);
- /*
- * If the file name ends in ".s[uvw][a-z]" we assume this is the swap file.
- * Otherwise a search is done to find the swap file(s).
- */
+ // If the file name ends in ".s[a-w][a-z]" we assume this is the swap file.
+ // Otherwise a search is done to find the swap file(s).
fname = curbuf->b_fname;
if (fname == NULL) /* When there is no file name */
fname = (char_u *)"";
len = (int)STRLEN(fname);
if (len >= 4
&& STRNICMP(fname + len - 4, ".s", 2) == 0
- && vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
+ && vim_strchr((char_u *)"abcdefghijklmnopqrstuvw",
+ TOLOWER_ASC(fname[len - 2])) != NULL
&& ASCII_ISALPHA(fname[len - 1])) {
directly = TRUE;
fname_used = vim_strsave(fname); /* make a copy for mf_open() */
@@ -847,8 +845,7 @@ void ml_recover(void)
mfp = mf_open(fname_used, O_RDONLY);
fname_used = p;
if (mfp == NULL || mfp->mf_fd < 0) {
- if (fname_used != NULL)
- EMSG2(_("E306: Cannot open %s"), fname_used);
+ EMSG2(_("E306: Cannot open %s"), fname_used);
goto theend;
}
buf->b_ml.ml_mfp = mfp;
@@ -919,10 +916,11 @@ void ml_recover(void)
msg_end();
goto theend;
}
- if ((size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
- mfp->mf_blocknr_max = 0; /* no file or empty file */
- else
+ if ((size = vim_lseek(mfp->mf_fd, (off_T)0L, SEEK_END)) <= 0) {
+ mfp->mf_blocknr_max = 0; // no file or empty file
+ } else {
mfp->mf_blocknr_max = size / mfp->mf_page_size;
+ }
mfp->mf_infile_count = mfp->mf_blocknr_max;
/* need to reallocate the memory used to store the data */
@@ -1000,7 +998,7 @@ void ml_recover(void)
if (b0_ff != 0)
set_fileformat(b0_ff - 1, OPT_LOCAL);
if (b0_fenc != NULL) {
- set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL);
+ set_option_value("fenc", 0L, (char *)b0_fenc, OPT_LOCAL);
xfree(b0_fenc);
}
unchanged(curbuf, TRUE);
@@ -1064,11 +1062,12 @@ void ml_recover(void)
if (!cannot_open) {
line_count = pp->pb_pointer[idx].pe_line_count;
if (readfile(curbuf->b_ffname, NULL, lnum,
- pp->pb_pointer[idx].pe_old_lnum - 1,
- line_count, NULL, 0) == FAIL)
- cannot_open = TRUE;
- else
+ pp->pb_pointer[idx].pe_old_lnum - 1, line_count,
+ NULL, 0) != OK) {
+ cannot_open = true;
+ } else {
lnum += line_count;
+ }
}
if (cannot_open) {
++error;
@@ -1180,7 +1179,7 @@ void ml_recover(void)
* empty. Don't set the modified flag then. */
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL)) {
changed_int();
- ++curbuf->b_changedtick;
+ buf_inc_changedtick(curbuf);
}
} else {
for (idx = 1; idx <= lnum; ++idx) {
@@ -1190,7 +1189,7 @@ void ml_recover(void)
xfree(p);
if (i != 0) {
changed_int();
- ++curbuf->b_changedtick;
+ buf_inc_changedtick(curbuf);
break;
}
}
@@ -1299,18 +1298,14 @@ recover_names (
msg_putchar('\n');
}
- /*
- * Do the loop for every directory in 'directory'.
- * First allocate some memory to put the directory name in.
- */
+ // Do the loop for every directory in 'directory'.
+ // First allocate some memory to put the directory name in.
dir_name = xmalloc(STRLEN(p_dir) + 1);
dirp = p_dir;
- while (dir_name != NULL && *dirp) {
- /*
- * Isolate a directory name from *dirp and put it in dir_name (we know
- * it is large enough, so use 31000 for length).
- * Advance dirp to next directory name.
- */
+ while (*dirp) {
+ // Isolate a directory name from *dirp and put it in dir_name (we know
+ // it is large enough, so use 31000 for length).
+ // Advance dirp to next directory name.
(void)copy_option_part(&dirp, dir_name, 31000, ",");
if (dir_name[0] == '.' && dir_name[1] == NUL) { /* check current dir */
@@ -1332,10 +1327,14 @@ recover_names (
names[2] = (char_u *)concat_fnames((char *)dir_name, ".sw?", TRUE);
num_names = 3;
} else {
- p = dir_name + STRLEN(dir_name);
- if (after_pathsep((char *)dir_name, (char *)p) && p[-1] == p[-2]) {
- /* Ends with '//', Use Full path for swap name */
- tail = (char_u *)make_percent_swname((char *)dir_name, (char *)fname_res);
+ int len = (int)STRLEN(dir_name);
+ p = dir_name + len;
+ if (after_pathsep((char *)dir_name, (char *)p)
+ && len > 1
+ && p[-1] == p[-2]) {
+ // Ends with '//', Use Full path for swap name
+ tail = (char_u *)make_percent_swname((char *)dir_name,
+ (char *)fname_res);
} else {
tail = path_tail(fname_res);
tail = (char_u *)concat_fnames((char *)dir_name, (char *)tail, TRUE);
@@ -1374,11 +1373,11 @@ recover_names (
*/
if (curbuf->b_ml.ml_mfp != NULL
&& (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL) {
- for (int i = 0; i < num_files; ++i)
- if (path_full_compare(p, files[i], TRUE) & kEqualFiles) {
- /* Remove the name from files[i]. Move further entries
- * down. When the array becomes empty free it here, since
- * FreeWild() won't be called below. */
+ for (int i = 0; i < num_files; i++) {
+ if (path_full_compare(p, files[i], true) & kEqualFiles) {
+ // Remove the name from files[i]. Move further entries
+ // down. When the array becomes empty free it here, since
+ // FreeWild() won't be called below.
xfree(files[i]);
if (--num_files == 0)
xfree(files);
@@ -1386,6 +1385,7 @@ recover_names (
for (; i < num_files; ++i)
files[i] = files[i + 1];
}
+ }
}
if (nr > 0) {
file_count += num_files;
@@ -1410,8 +1410,8 @@ recover_names (
for (int i = 0; i < num_files; ++i) {
/* print the swap file name */
msg_outnum((long)++file_count);
- MSG_PUTS(". ");
- msg_puts(path_tail(files[i]));
+ msg_puts(". ");
+ msg_puts((const char *)path_tail(files[i]));
msg_putchar('\n');
(void)swapfile_info(files[i]);
}
@@ -1441,7 +1441,7 @@ static char *make_percent_swname(const char *dir, char *name)
char *f = fix_fname(name != NULL ? name : "");
if (f != NULL) {
char *s = xstrdup(f);
- for (d = s; *d != NUL; mb_ptr_adv(d)) {
+ for (d = s; *d != NUL; MB_PTR_ADV(d)) {
if (vim_ispathsep(*d)) {
*d = '%';
}
@@ -1454,7 +1454,7 @@ static char *make_percent_swname(const char *dir, char *name)
}
#ifdef UNIX
-static int process_still_running;
+static bool process_still_running;
#endif
/*
@@ -1463,6 +1463,7 @@ static int process_still_running;
*/
static time_t swapfile_info(char_u *fname)
{
+ assert(fname != NULL);
int fd;
struct block0 b0;
time_t x = (time_t)0;
@@ -1531,8 +1532,8 @@ static time_t swapfile_info(char_u *fname)
msg_outnum(char_to_long(b0.b0_pid));
#if defined(UNIX)
if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0) {
- MSG_PUTS(_(" (still running)"));
- process_still_running = TRUE;
+ MSG_PUTS(_(" (STILL RUNNING)"));
+ process_still_running = true;
}
#endif
}
@@ -1590,7 +1591,7 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
* If 'check_char' is TRUE, stop syncing when character becomes available, but
* always sync at least one block.
*/
-void ml_sync_all(int check_file, int check_char)
+void ml_sync_all(int check_file, int check_char, bool do_fsync)
{
FOR_ALL_BUFFERS(buf) {
if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
@@ -1609,16 +1610,17 @@ void ml_sync_all(int check_file, int check_char)
if (!os_fileinfo((char *)buf->b_ffname, &file_info)
|| file_info.stat.st_mtim.tv_sec != buf->b_mtime_read
|| os_fileinfo_size(&file_info) != buf->b_orig_size) {
- ml_preserve(buf, FALSE);
- did_check_timestamps = FALSE;
- need_check_timestamps = TRUE; /* give message later */
+ ml_preserve(buf, false, do_fsync);
+ did_check_timestamps = false;
+ need_check_timestamps = true; // give message later
}
}
if (buf->b_ml.ml_mfp->mf_dirty) {
(void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
- | (bufIsChanged(buf) ? MFS_FLUSH : 0));
- if (check_char && os_char_avail()) /* character available now */
+ | (do_fsync && bufIsChanged(buf) ? MFS_FLUSH : 0));
+ if (check_char && os_char_avail()) { // character available now
break;
+ }
}
}
}
@@ -1633,7 +1635,7 @@ void ml_sync_all(int check_file, int check_char)
*
* when message is TRUE the success of preserving is reported
*/
-void ml_preserve(buf_T *buf, int message)
+void ml_preserve(buf_T *buf, int message, bool do_fsync)
{
bhdr_T *hp;
linenr_T lnum;
@@ -1651,9 +1653,9 @@ void ml_preserve(buf_T *buf, int message)
* before. */
got_int = FALSE;
- ml_flush_line(buf); /* flush buffered line */
- (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
- status = mf_sync(mfp, MFS_ALL | MFS_FLUSH);
+ ml_flush_line(buf); // flush buffered line
+ (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block
+ status = mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0));
/* stack is invalid after mf_sync(.., MFS_ALL) */
buf->b_ml.ml_stack_top = 0;
@@ -1681,11 +1683,12 @@ void ml_preserve(buf_T *buf, int message)
CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
lnum = buf->b_ml.ml_locked_high + 1;
}
- (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
- /* sync the updated pointer blocks */
- if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL)
+ (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block
+ // sync the updated pointer blocks
+ if (mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0)) == FAIL) {
status = FAIL;
- buf->b_ml.ml_stack_top = 0; /* stack is invalid now */
+ }
+ buf->b_ml.ml_stack_top = 0; // stack is invalid now
}
theend:
got_int |= got_int_save;
@@ -1744,11 +1747,11 @@ ml_get_buf (
if (lnum > buf->b_ml.ml_line_count) { /* invalid line number */
if (recursive == 0) {
- /* Avoid giving this message for a recursive call, may happen when
- * the GUI redraws part of the text. */
- ++recursive;
- EMSGN(_("E315: ml_get: invalid lnum: %" PRId64), lnum);
- --recursive;
+ // Avoid giving this message for a recursive call, may happen when
+ // the GUI redraws part of the text.
+ recursive++;
+ IEMSGN(_("E315: ml_get: invalid lnum: %" PRId64), lnum);
+ recursive--;
}
errorret:
STRCPY(IObuff, "???");
@@ -1766,7 +1769,7 @@ errorret:
* Don't use the last used line when 'swapfile' is reset, need to load all
* blocks.
*/
- if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release) {
+ if (buf->b_ml.ml_line_lnum != lnum) {
ml_flush_line(buf);
/*
@@ -1776,11 +1779,11 @@ errorret:
*/
if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL) {
if (recursive == 0) {
- /* Avoid giving this message for a recursive call, may happen
- * when the GUI redraws part of the text. */
- ++recursive;
- EMSGN(_("E316: ml_get: cannot find line %" PRId64), lnum);
- --recursive;
+ // Avoid giving this message for a recursive call, may happen
+ // when the GUI redraws part of the text.
+ recursive++;
+ IEMSGN(_("E316: ml_get: cannot find line %" PRId64), lnum);
+ recursive--;
}
goto errorret;
}
@@ -2164,7 +2167,7 @@ ml_append_int (
return FAIL;
pp = hp->bh_data; /* must be pointer block */
if (pp->pb_id != PTR_ID) {
- EMSG(_("E317: pointer block id wrong 3"));
+ IEMSG(_("E317: pointer block id wrong 3"));
mf_put(mfp, hp, false, false);
return FAIL;
}
@@ -2297,8 +2300,8 @@ ml_append_int (
* Safety check: fallen out of for loop?
*/
if (stack_idx < 0) {
- EMSG(_("E318: Updated too many blocks?"));
- buf->b_ml.ml_stack_top = 0; /* invalidate stack */
+ IEMSG(_("E318: Updated too many blocks?"));
+ buf->b_ml.ml_stack_top = 0; // invalidate stack
}
}
@@ -2318,7 +2321,7 @@ ml_append_int (
*
* return FAIL for failure, OK otherwise
*/
-int ml_replace(linenr_T lnum, char_u *line, int copy)
+int ml_replace(linenr_T lnum, char_u *line, bool copy)
{
if (line == NULL) /* just checking... */
return FAIL;
@@ -2341,14 +2344,13 @@ int ml_replace(linenr_T lnum, char_u *line, int copy)
return OK;
}
-/*
- * Delete line 'lnum' in the current buffer.
- *
- * Check: The caller of this function should probably also call
- * deleted_lines() after this.
- *
- * return FAIL for failure, OK otherwise
- */
+/// Delete line `lnum` in the current buffer.
+///
+/// @note The caller of this function should probably also call
+/// deleted_lines() after this.
+///
+/// @param message Show "--No lines in buffer--" message.
+/// @return FAIL for failure, OK otherwise
int ml_delete(linenr_T lnum, int message)
{
ml_flush_line(curbuf);
@@ -2384,7 +2386,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int message)
)
set_keep_msg((char_u *)_(no_lines_msg), 0);
- i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
+ i = ml_replace((linenr_T)1, (char_u *)"", true);
buf->b_ml.ml_flags |= ML_EMPTY;
return i;
@@ -2438,7 +2440,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int message)
return FAIL;
pp = hp->bh_data; /* must be pointer block */
if (pp->pb_id != PTR_ID) {
- EMSG(_("E317: pointer block id wrong 4"));
+ IEMSG(_("E317: pointer block id wrong 4"));
mf_put(mfp, hp, false, false);
return FAIL;
}
@@ -2633,9 +2635,9 @@ static void ml_flush_line(buf_T *buf)
new_line = buf->b_ml.ml_line_ptr;
hp = ml_find_line(buf, lnum, ML_FIND);
- if (hp == NULL)
- EMSGN(_("E320: Cannot find line %" PRId64), lnum);
- else {
+ if (hp == NULL) {
+ IEMSGN(_("E320: Cannot find line %" PRId64), lnum);
+ } else {
dp = hp->bh_data;
idx = lnum - buf->b_ml.ml_locked_low;
start = ((dp->db_index[idx]) & DB_INDEX_MASK);
@@ -2768,9 +2770,8 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
if (buf->b_ml.ml_locked) {
if (ML_SIMPLE(action)
&& buf->b_ml.ml_locked_low <= lnum
- && buf->b_ml.ml_locked_high >= lnum
- && !mf_dont_release) {
- /* remember to update pointer blocks and stack later */
+ && buf->b_ml.ml_locked_high >= lnum) {
+ // remember to update pointer blocks and stack later
if (action == ML_INSERT) {
++(buf->b_ml.ml_locked_lineadd);
++(buf->b_ml.ml_locked_high);
@@ -2844,7 +2845,7 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
pp = (PTR_BL *)(dp); /* must be pointer block */
if (pp->pb_id != PTR_ID) {
- EMSG(_("E317: pointer block id wrong"));
+ IEMSG(_("E317: pointer block id wrong"));
goto error_block;
}
@@ -2881,13 +2882,14 @@ static bhdr_T *ml_find_line(buf_T *buf, linenr_T lnum, int action)
break;
}
}
- if (idx >= (int)pp->pb_count) { /* past the end: something wrong! */
- if (lnum > buf->b_ml.ml_line_count)
- EMSGN(_("E322: line number out of range: %" PRId64 " past the end"),
- lnum - buf->b_ml.ml_line_count);
+ if (idx >= (int)pp->pb_count) { // past the end: something wrong!
+ if (lnum > buf->b_ml.ml_line_count) {
+ IEMSGN(_("E322: line number out of range: %" PRId64 " past the end"),
+ lnum - buf->b_ml.ml_line_count);
- else
- EMSGN(_("E323: line count wrong in block %" PRId64), bnum);
+ } else {
+ IEMSGN(_("E323: line count wrong in block %" PRId64), bnum);
+ }
goto error_block;
}
if (action == ML_DELETE) {
@@ -2963,7 +2965,7 @@ static void ml_lineadd(buf_T *buf, int count)
pp = hp->bh_data; /* must be pointer block */
if (pp->pb_id != PTR_ID) {
mf_put(mfp, hp, false, false);
- EMSG(_("E317: pointer block id wrong 2"));
+ IEMSG(_("E317: pointer block id wrong 2"));
break;
}
pp->pb_pointer[ip->ip_index].pe_line_count += count;
@@ -3017,20 +3019,17 @@ int resolve_symlink(const char_u *fname, char_u *buf)
}
buf[ret] = NUL;
- /*
- * Check whether the symlink is relative or absolute.
- * If it's relative, build a new path based on the directory
- * portion of the filename (if any) and the path the symlink
- * points to.
- */
- if (path_is_absolute_path(buf))
+ // Check whether the symlink is relative or absolute.
+ // If it's relative, build a new path based on the directory
+ // portion of the filename (if any) and the path the symlink
+ // points to.
+ if (path_is_absolute(buf)) {
STRCPY(tmp, buf);
- else {
- char_u *tail;
-
- tail = path_tail(tmp);
- if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL)
+ } else {
+ char_u *tail = path_tail(tmp);
+ if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL) {
return FAIL;
+ }
STRCPY(tail, buf);
}
}
@@ -3055,9 +3054,12 @@ char_u *makeswapname(char_u *fname, char_u *ffname, buf_T *buf, char_u *dir_name
#ifdef HAVE_READLINK
char_u fname_buf[MAXPATHL];
#endif
+ int len = (int)STRLEN(dir_name);
- s = dir_name + STRLEN(dir_name);
- if (after_pathsep((char *)dir_name, (char *)s) && s[-1] == s[-2]) { /* Ends with '//', Use Full path */
+ s = dir_name + len;
+ if (after_pathsep((char *)dir_name, (char *)s)
+ && len > 1
+ && s[-1] == s[-2]) { // Ends with '//', Use Full path
r = NULL;
if ((s = (char_u *)make_percent_swname((char *)dir_name, (char *)fname)) != NULL) {
r = (char_u *)modname((char *)s, ".swp", FALSE);
@@ -3139,6 +3141,7 @@ attention_message (
char_u *fname /* swap file name */
)
{
+ assert(buf->b_fname != NULL);
time_t x, sx;
char *p;
@@ -3152,7 +3155,9 @@ attention_message (
msg_outtrans(buf->b_fname);
MSG_PUTS("\"\n");
FileInfo file_info;
- if (os_fileinfo((char *)buf->b_fname, &file_info)) {
+ if (!os_fileinfo((char *)buf->b_fname, &file_info)) {
+ MSG_PUTS(_(" CANNOT BE FOUND"));
+ } else {
MSG_PUTS(_(" dated: "));
x = file_info.stat.st_mtim.tv_sec;
p = ctime(&x); // includes '\n'
@@ -3165,9 +3170,10 @@ attention_message (
}
/* Some of these messages are long to allow translation to
* other languages. */
- MSG_PUTS(_(
- "\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."));
- MSG_PUTS(_(" Quit, or continue with caution.\n"));
+ MSG_PUTS(_("\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."
+ " Quit, or continue with caution.\n"));
MSG_PUTS(_("(2) An edit session for this file crashed.\n"));
MSG_PUTS(_(" If this is the case, use \":recover\" or \"vim -r "));
msg_outtrans(buf->b_fname);
@@ -3348,7 +3354,7 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
int choice = 0;
#ifdef UNIX
- process_still_running = FALSE;
+ process_still_running = false;
#endif
/*
* If there is a SwapExists autocommand and we can handle
@@ -3360,38 +3366,45 @@ static char *findswapname(buf_T *buf, char **dirp, char *old_fname,
choice = do_swapexists(buf, (char_u *) fname);
if (choice == 0) {
- /* Show info about the existing swap file. */
- attention_message(buf, (char_u *) fname);
+ // Show info about the existing swap file.
+ attention_message(buf, (char_u *)fname);
+
+ // We don't want a 'q' typed at the more-prompt
+ // interrupt loading a file.
+ got_int = false;
- /* We don't want a 'q' typed at the more-prompt
- * interrupt loading a file. */
- got_int = FALSE;
+ // If vimrc has "simalt ~x" we don't want it to
+ // interfere with the prompt here.
+ flush_buffers(FLUSH_TYPEAHEAD);
}
if (swap_exists_action != SEA_NONE && choice == 0) {
- char *name;
+ const char *const sw_msg_1 = _("Swap file \"");
+ const char *const sw_msg_2 = _("\" already exists!");
const size_t fname_len = strlen(fname);
- name = xmalloc(fname_len
- + strlen(_("Swap file \""))
- + strlen(_("\" already exists!")) + 5);
- STRCPY(name, _("Swap file \""));
- home_replace(NULL, (char_u *) fname, (char_u *)&name[strlen(name)],
- fname_len, true);
- STRCAT(name, _("\" already exists!"));
- choice = do_dialog(VIM_WARNING,
- (char_u *)_("VIM - ATTENTION"),
- (char_u *)(name == NULL
- ? _("Swap file already exists!")
- : name),
+ const size_t sw_msg_1_len = strlen(sw_msg_1);
+ const size_t sw_msg_2_len = strlen(sw_msg_2);
+
+ const size_t name_len = sw_msg_1_len + fname_len + sw_msg_2_len + 5;
+
+ char *const name = xmalloc(name_len);
+ memcpy(name, sw_msg_1, sw_msg_1_len + 1);
+ home_replace(NULL, (char_u *)fname, (char_u *)&name[sw_msg_1_len],
+ fname_len, true);
+ xstrlcat(name, sw_msg_2, name_len);
+ choice = do_dialog(VIM_WARNING, (char_u *)_("VIM - ATTENTION"),
+ (char_u *)name,
# if defined(UNIX)
- process_still_running
- ? (char_u *)_(
- "&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") :
+ process_still_running
+ ? (char_u *)_(
+ "&Open Read-Only\n&Edit anyway\n&Recover"
+ "\n&Quit\n&Abort") :
# endif
- (char_u *)_(
- "&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"),
- 1, NULL, FALSE);
+ (char_u *)_(
+ "&Open Read-Only\n&Edit anyway\n&Recover"
+ "\n&Delete it\n&Quit\n&Abort"),
+ 1, NULL, false);
# if defined(UNIX)
if (process_still_running && choice >= 4)
@@ -3526,17 +3539,16 @@ static int b0_magic_wrong(ZERO_BL *b0p)
* == 0 == 0 OK FAIL TRUE
*
* current file doesn't exist, inode for swap unknown, both file names not
- * available -> probably same file
- * == 0 == 0 FAIL FAIL FALSE
+ * available -> compare file names
+ * == 0 == 0 FAIL FAIL fname_c != fname_s
*
* Only the last 32 bits of the inode will be used. This can't be changed
* without making the block 0 incompatible with 32 bit versions.
*/
-static int
-fnamecmp_ino (
- char_u *fname_c, /* current file name */
- char_u *fname_s, /* file name from swap file */
+static bool fnamecmp_ino(
+ char_u *fname_c, // current file name
+ char_u *fname_s, // file name from swap file
long ino_block0
)
{
@@ -3577,11 +3589,13 @@ fnamecmp_ino (
/*
* Can't compare inodes or file names, guess that the files are different,
- * unless both appear not to exist at all.
+ * unless both appear not to exist at all, then compare with the file name
+ * in the swap file.
*/
- if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL)
- return FALSE;
- return TRUE;
+ if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL) {
+ return STRCMP(fname_c, fname_s) != 0;
+ }
+ return true;
}
/*
@@ -3700,9 +3714,9 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
curix++) {
curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
}
- } else if (line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines
- && curix < buf->b_ml.ml_usedchunks - 1) {
- /* Adjust cached curix & curline */
+ } else if (curix < buf->b_ml.ml_usedchunks - 1
+ && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines) {
+ // Adjust cached curix & curline
curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
curix++;
}
@@ -3841,13 +3855,17 @@ static void ml_updatechunk(buf_T *buf, linenr_T line, long len, int updtype)
ml_upd_lastcurix = curix;
}
-/*
- * Find offset for line or line with offset.
- * Find line with offset if "lnum" is 0; return remaining offset in offp
- * Find offset of line if "lnum" > 0
- * return -1 if information is not available
- */
-long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
+/// Find offset for line or line with offset.
+///
+/// @param buf buffer to use
+/// @param lnum if > 0, find offset of lnum, store offset in offp
+/// if == 0, return line with offset *offp
+/// @param offp Location where offset of line is stored, or to read offset to
+/// use to find line. In the later case, store remaining offset.
+/// @param no_ff ignore 'fileformat' option, always use one byte for NL.
+///
+/// @return -1 if information is not available
+long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp, bool no_ff)
{
linenr_T curline;
int curix;
@@ -3860,7 +3878,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
int text_end;
long offset;
int len;
- int ffdos = (get_fileformat(buf) == EOL_DOS);
+ int ffdos = !no_ff && (get_fileformat(buf) == EOL_DOS);
int extra = 0;
/* take care of cached line first */
@@ -3955,7 +3973,7 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
/* Don't count the last line break if 'noeol' and ('bin' or
* 'nofixeol'). */
if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
- && buf->b_ml.ml_line_count == lnum) {
+ && lnum > buf->b_ml.ml_line_count) {
size -= ffdos + 1;
}
}
@@ -3963,20 +3981,19 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
return size;
}
-/*
- * Goto byte in buffer with offset 'cnt'.
- */
+/// Goto byte in buffer with offset 'cnt'.
void goto_byte(long cnt)
{
long boff = cnt;
linenr_T lnum;
- ml_flush_line(curbuf); /* cached line may be dirty */
+ ml_flush_line(curbuf); // cached line may be dirty
setpcmark();
- if (boff)
- --boff;
- lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff);
- if (lnum < 1) { /* past the end */
+ if (boff) {
+ boff--;
+ }
+ lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff, false);
+ if (lnum < 1) { // past the end
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
curwin->w_curswant = MAXCOL;
coladvance((colnr_T)MAXCOL);
@@ -3988,7 +4005,87 @@ void goto_byte(long cnt)
}
check_cursor();
- /* Make sure the cursor is on the first byte of a multi-byte char. */
- if (has_mbyte)
+ // Make sure the cursor is on the first byte of a multi-byte char.
+ if (has_mbyte) {
mb_adjust_cursor();
+ }
+}
+
+/// Increment the line pointer "lp" crossing line boundaries as necessary.
+/// Return 1 when going to the next line.
+/// Return 2 when moving forward onto a NUL at the end of the line).
+/// Return -1 when at the end of file.
+/// Return 0 otherwise.
+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);
+ if (*p != NUL) { // still within line, move to next char (may be NUL)
+ const int l = utfc_ptr2len(p);
+
+ lp->col += l;
+ return ((p[l] != NUL) ? 0 : 2);
+ }
+ }
+ if (lp->lnum != curbuf->b_ml.ml_line_count) { // there is a next line
+ lp->col = 0;
+ lp->lnum++;
+ lp->coladd = 0;
+ return 1;
+ }
+ return -1;
+}
+
+/// Same as inc(), but skip NUL at the end of non-empty lines.
+int incl(pos_T *lp)
+{
+ int r;
+
+ if ((r = inc(lp)) >= 1 && lp->col) {
+ r = inc(lp);
+ }
+ return r;
+}
+
+int dec(pos_T *lp)
+{
+ lp->coladd = 0;
+ if (lp->col == MAXCOL) {
+ // past end of line
+ char_u *p = ml_get(lp->lnum);
+ lp->col = (colnr_T)STRLEN(p);
+ lp->col -= utf_head_off(p, p + lp->col);
+ return 0;
+ }
+
+ if (lp->col > 0) {
+ // still within line
+ lp->col--;
+ char_u *p = ml_get(lp->lnum);
+ lp->col -= utf_head_off(p, p + lp->col);
+ return 0;
+ }
+ if (lp->lnum > 1) {
+ // there is a prior line
+ lp->lnum--;
+ char_u *p = ml_get(lp->lnum);
+ lp->col = (colnr_T)STRLEN(p);
+ lp->col -= utf_head_off(p, p + lp->col);
+ return 1;
+ }
+
+ // at start of file
+ return -1;
+}
+
+/// Same as dec(), but skip NUL at the end of non-empty lines.
+int decl(pos_T *lp)
+{
+ int r;
+
+ if ((r = dec(lp)) == 1 && lp->col) {
+ r = dec(lp);
+ }
+ return r;
}
diff --git a/src/nvim/memline.h b/src/nvim/memline.h
index f84e86fea0..a239c6a031 100644
--- a/src/nvim/memline.h
+++ b/src/nvim/memline.h
@@ -2,6 +2,8 @@
#define NVIM_MEMLINE_H
#include "nvim/types.h"
+#include "nvim/pos.h" // for pos_T, linenr_T, colnr_T
+#include "nvim/buffer_defs.h" // for buf_T
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "memline.h.generated.h"
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 8db47b79c1..d38079ca72 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.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
+
// Various routines dealing with allocation and deallocation of memory.
#include <assert.h>
@@ -7,26 +10,53 @@
#include "nvim/vim.h"
#include "nvim/eval.h"
+#include "nvim/highlight.h"
#include "nvim/memfile.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
#include "nvim/ui.h"
+#include "nvim/api/vim.h"
#ifdef HAVE_JEMALLOC
// Force je_ prefix on jemalloc functions.
# define JEMALLOC_NO_DEMANGLE
# include <jemalloc/jemalloc.h>
-# define malloc(size) je_malloc(size)
-# define calloc(count, size) je_calloc(count, size)
-# define realloc(ptr, size) je_realloc(ptr, size)
-# define free(ptr) je_free(ptr)
+#endif
+
+#ifdef UNIT_TESTING
+# define malloc(size) mem_malloc(size)
+# define calloc(count, size) mem_calloc(count, size)
+# define realloc(ptr, size) mem_realloc(ptr, size)
+# define free(ptr) mem_free(ptr)
+# ifdef HAVE_JEMALLOC
+MemMalloc mem_malloc = &je_malloc;
+MemFree mem_free = &je_free;
+MemCalloc mem_calloc = &je_calloc;
+MemRealloc mem_realloc = &je_realloc;
+# else
+MemMalloc mem_malloc = &malloc;
+MemFree mem_free = &free;
+MemCalloc mem_calloc = &calloc;
+MemRealloc mem_realloc = &realloc;
+# endif
+#else
+# ifdef HAVE_JEMALLOC
+# define malloc(size) je_malloc(size)
+# define calloc(count, size) je_calloc(count, size)
+# define realloc(ptr, size) je_realloc(ptr, size)
+# define free(ptr) je_free(ptr)
+# endif
#endif
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "memory.c.generated.h"
#endif
+#ifdef EXITFREE
+bool entered_free_all_mem = false;
+#endif
+
/// Try to free memory. Used when trying to recover from out of memory errors.
/// @see {xmalloc}
void try_to_free_memory(void)
@@ -38,7 +68,7 @@ void try_to_free_memory(void)
trying_to_free = true;
// free any scrollback text
- clear_sb_text();
+ clear_sb_text(true);
// Try to save all buffers and release as many blocks as possible
mf_release_all();
@@ -283,18 +313,16 @@ size_t memcnt(const void *data, char c, size_t len)
return cnt;
}
-/// The xstpcpy() function shall copy the string pointed to by src (including
-/// the terminating NUL character) into the array pointed to by dst.
+/// Copies the string pointed to by src (including the terminating NUL
+/// character) into the array pointed to by dst.
///
-/// The xstpcpy() function shall return a pointer to the terminating NUL
-/// character copied into the dst buffer. This is the only difference with
-/// strcpy(), which returns dst.
+/// @returns pointer to the terminating NUL char copied into the dst buffer.
+/// This is the only difference with strcpy(), which returns dst.
///
-/// WARNING: If copying takes place between objects that overlap, the behavior is
-/// undefined.
+/// WARNING: If copying takes place between objects that overlap, the behavior
+/// is undefined.
///
-/// This is the Neovim version of stpcpy(3) as defined in POSIX 2008. We
-/// don't require that supported platforms implement POSIX 2008, so we
+/// Nvim version of POSIX 2008 stpcpy(3). We do not require POSIX 2008, so
/// implement our own version.
///
/// @param dst
@@ -306,24 +334,19 @@ char *xstpcpy(char *restrict dst, const char *restrict src)
return (char *)memcpy(dst, src, len + 1) + len;
}
-/// The xstpncpy() function shall copy not more than n bytes (bytes that follow
-/// a NUL character are not copied) from the array pointed to by src to the
-/// array pointed to by dst.
+/// Copies not more than n bytes (bytes that follow a NUL character are not
+/// copied) from the array pointed to by src to the array pointed to by dst.
///
-/// If a NUL character is written to the destination, the xstpncpy() function
-/// shall return the address of the first such NUL character. Otherwise, it
-/// shall return &dst[maxlen].
+/// If a NUL character is written to the destination, xstpncpy() returns the
+/// address of the first such NUL character. Otherwise, it shall return
+/// &dst[maxlen].
///
-/// WARNING: If copying takes place between objects that overlap, the behavior is
-/// undefined.
+/// WARNING: If copying takes place between objects that overlap, the behavior
+/// is undefined.
///
/// WARNING: xstpncpy will ALWAYS write maxlen bytes. If src is shorter than
/// maxlen, zeroes will be written to the remaining bytes.
///
-/// TODO(aktau): I don't see a good reason to have this last behaviour, and
-/// it is potentially wasteful. Could we perhaps deviate from the standard
-/// and not zero the rest of the buffer?
-///
/// @param dst
/// @param src
/// @param maxlen
@@ -342,29 +365,62 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen)
}
}
-/// xstrlcpy - Copy a %NUL terminated string into a sized buffer
+/// xstrlcpy - Copy a NUL-terminated string into a sized buffer
+///
+/// Compatible with *BSD strlcpy: the result is always a valid NUL-terminated
+/// string that fits in the buffer (unless, of course, the buffer size is
+/// zero). It does not pad out the result like strncpy() does.
///
-/// Compatible with *BSD strlcpy: the result is always a valid
-/// NUL-terminated string that fits in the buffer (unless,
-/// of course, the buffer size is zero). It does not pad
-/// out the result like strncpy() does.
+/// @param[out] dst Buffer to store the result.
+/// @param[in] src String to be copied.
+/// @param[in] dsize Size of `dst`.
///
-/// @param dst Where to copy the string to
-/// @param src Where to copy the string from
-/// @param size Size of destination buffer
-/// @return Length of the source string (i.e.: strlen(src))
-size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size)
+/// @return Length of `src`. May be greater than `dsize - 1`, which would mean
+/// that string was truncated.
+size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t dsize)
FUNC_ATTR_NONNULL_ALL
{
- size_t ret = strlen(src);
+ size_t slen = strlen(src);
- if (size) {
- size_t len = (ret >= size) ? size - 1 : ret;
- memcpy(dst, src, len);
- dst[len] = '\0';
- }
+ if (dsize) {
+ size_t len = MIN(slen, dsize - 1);
+ memcpy(dst, src, len);
+ dst[len] = '\0';
+ }
+
+ return slen; // Does not include NUL.
+}
+
+/// Appends `src` to string `dst` of size `dsize` (unlike strncat, dsize is the
+/// full size of `dst`, not space left). At most dsize-1 characters
+/// will be copied. Always NUL terminates. `src` and `dst` may overlap.
+///
+/// @see vim_strcat from Vim.
+/// @see strlcat from OpenBSD.
+///
+/// @param[in,out] dst Buffer to be appended-to. Must have a NUL byte.
+/// @param[in] src String to put at the end of `dst`.
+/// @param[in] dsize Size of `dst` including NUL byte. Must be greater than 0.
+///
+/// @return Length of the resulting string as if destination size was #SIZE_MAX.
+/// May be greater than `dsize - 1`, which would mean that string was
+/// truncated.
+size_t xstrlcat(char *const dst, const char *const src, const size_t dsize)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(dsize > 0);
+ const size_t dlen = strlen(dst);
+ assert(dlen < dsize);
+ const size_t slen = strlen(src);
+
+ if (slen > dsize - dlen - 1) {
+ memmove(dst + dlen, src, dsize - dlen - 1);
+ dst[dsize - 1] = '\0';
+ } else {
+ memmove(dst + dlen, src, slen + 1);
+ }
- return ret;
+ return slen + dlen; // Does not include NUL.
}
/// strdup() wrapper
@@ -374,10 +430,24 @@ size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t size)
/// @return pointer to a copy of the string
char *xstrdup(const char *str)
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
+ FUNC_ATTR_NONNULL_ALL
{
return xmemdupz(str, strlen(str));
}
+/// strdup() wrapper
+///
+/// Unlike xstrdup() allocates a new empty string if it receives NULL.
+char *xstrdupnul(const char *const str)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
+{
+ if (str == NULL) {
+ return xmallocz(0);
+ } else {
+ return xstrdup(str);
+ }
+}
+
/// A version of memchr that starts the search at `src + len`.
///
/// Based on glibc's memrchr.
@@ -404,6 +474,7 @@ void *xmemrchr(const void *src, uint8_t c, size_t len)
/// @return pointer to a copy of the string
char *xstrndup(const char *str, size_t len)
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
+ FUNC_ATTR_NONNULL_ALL
{
char *p = memchr(str, '\0', len);
return xmemdupz(str, p ? (size_t)(p - str) : len);
@@ -422,6 +493,20 @@ void *xmemdup(const void *data, size_t len)
return memcpy(xmalloc(len), data, len);
}
+/// Returns true if strings `a` and `b` are equal. Arguments may be NULL.
+bool strequal(const char *a, const char *b)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (a == NULL && b == NULL) || (a && b && strcmp(a, b) == 0);
+}
+
+/// Case-insensitive `strequal`.
+bool striequal(const char *a, const char *b)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (a == NULL && b == NULL) || (a && b && STRICMP(a, b) == 0);
+}
+
/*
* Avoid repeating the error message many times (they take 1 second each).
* Did_outofmem_msg is reset when a character is read.
@@ -440,6 +525,16 @@ void do_outofmem_msg(size_t size)
}
}
+/// Writes time_t to "buf[8]".
+void time_to_bytes(time_t time_, uint8_t buf[8])
+{
+ // time_t can be up to 8 bytes in size, more than uintmax_t in 32 bits
+ // systems, thus we can't use put_bytes() here.
+ for (size_t i = 7, bufi = 0; bufi < 8; i--, bufi++) {
+ buf[bufi] = (uint8_t)((uint64_t)time_ >> (i * 8));
+ }
+}
+
#if defined(EXITFREE)
#include "nvim/file_search.h"
@@ -470,6 +565,7 @@ void do_outofmem_msg(size_t size)
#include "nvim/tag.h"
#include "nvim/window.h"
#include "nvim/os/os.h"
+#include "nvim/eval/typval.h"
/*
* Free everything that we allocated.
@@ -481,13 +577,13 @@ void do_outofmem_msg(size_t size)
void free_all_mem(void)
{
buf_T *buf, *nextbuf;
- static bool entered = false;
- /* When we cause a crash here it is caught and Vim tries to exit cleanly.
- * Don't try freeing everything again. */
- if (entered)
+ // When we cause a crash here it is caught and Vim tries to exit cleanly.
+ // Don't try freeing everything again.
+ if (entered_free_all_mem) {
return;
- entered = true;
+ }
+ entered_free_all_mem = true;
// Don't want to trigger autocommands from here on.
block_autocmds();
@@ -496,7 +592,7 @@ void free_all_mem(void)
p_ea = false;
if (first_tabpage->tp_next != NULL)
do_cmdline_cmd("tabonly!");
- if (firstwin != lastwin)
+ if (!ONE_WINDOW)
do_cmdline_cmd("only!");
/* Free all spell info. */
@@ -524,7 +620,6 @@ void free_all_mem(void)
/* Obviously named calls. */
free_all_autocmds();
- free_all_options();
free_all_marks();
alist_clear(&global_alist);
free_homedir();
@@ -539,7 +634,7 @@ void free_all_mem(void)
free_signs();
set_expr_line(NULL);
diff_clear(curtab);
- clear_sb_text(); /* free any scrollback text */
+ clear_sb_text(true); // free any scrollback text
/* Free some global vars. */
xfree(last_cmdline);
@@ -562,17 +657,8 @@ void free_all_mem(void)
/* Destroy all windows. Must come before freeing buffers. */
win_free_all();
- /* Free all buffers. Reset 'autochdir' to avoid accessing things that
- * were freed already. */
- p_acd = false;
- for (buf = firstbuf; buf != NULL; ) {
- nextbuf = buf->b_next;
- close_buffer(NULL, buf, DOBUF_WIPE, false);
- if (buf_valid(buf))
- buf = nextbuf; /* didn't work, try next one */
- else
- buf = firstbuf;
- }
+ // Free all option values. Must come after closing windows.
+ free_all_options();
free_cmdline_buf();
@@ -596,11 +682,27 @@ void free_all_mem(void)
break;
eval_clear();
+ api_vim_free_all_mem();
+
+ // Free all buffers. Reset 'autochdir' to avoid accessing things that
+ // were freed already.
+ // Must be after eval_clear to avoid it trying to access b:changedtick after
+ // freeing it.
+ p_acd = false;
+ for (buf = firstbuf; buf != NULL; ) {
+ bufref_T bufref;
+ set_bufref(&bufref, buf);
+ nextbuf = buf->b_next;
+ close_buffer(NULL, buf, DOBUF_WIPE, false);
+ // Didn't work, try next one.
+ buf = bufref_valid(&bufref) ? nextbuf : firstbuf;
+ }
- /* screenlines (can't display anything now!) */
- free_screenlines();
+ // free screenlines (can't display anything now!)
+ screen_free_all_mem();
- clear_hl_tables();
+ clear_hl_tables(false);
+ list_free_log();
}
#endif
diff --git a/src/nvim/memory.h b/src/nvim/memory.h
index 7b477da2f5..250ac3e08f 100644
--- a/src/nvim/memory.h
+++ b/src/nvim/memory.h
@@ -1,8 +1,41 @@
#ifndef NVIM_MEMORY_H
#define NVIM_MEMORY_H
+#include <stdbool.h> // for bool
#include <stdint.h> // for uint8_t
#include <stddef.h> // for size_t
+#include <time.h> // for time_t
+
+/// `malloc()` function signature
+typedef void *(*MemMalloc)(size_t);
+
+/// `free()` function signature
+typedef void (*MemFree)(void *);
+
+/// `calloc()` function signature
+typedef void *(*MemCalloc)(size_t, size_t);
+
+/// `realloc()` function signature
+typedef void *(*MemRealloc)(void *, size_t);
+
+#ifdef UNIT_TESTING
+/// When unit testing: pointer to the `malloc()` function, may be altered
+extern MemMalloc mem_malloc;
+
+/// When unit testing: pointer to the `free()` function, may be altered
+extern MemFree mem_free;
+
+/// When unit testing: pointer to the `calloc()` function, may be altered
+extern MemCalloc mem_calloc;
+
+/// When unit testing: pointer to the `realloc()` function, may be altered
+extern MemRealloc mem_realloc;
+#endif
+
+#ifdef EXITFREE
+/// Indicates that free_all_mem function was or is running
+extern bool entered_free_all_mem;
+#endif
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "memory.h.generated.h"
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 3c2394d579..1c54db10eb 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.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
+
/*
* Code for menus. Used for the GUI and 'wildmenu'.
* GUI/Motif support by Robert Webb
@@ -18,12 +21,12 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/garray.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
-
+#include "nvim/eval/typval.h"
#define MENUDEPTH 10 /* maximum depth of menus */
@@ -35,8 +38,8 @@
-/* The character for each menu mode */
-static char_u menu_mode_chars[] = {'n', 'v', 's', 'o', 'i', 'c', 't'};
+/// The character for each menu mode
+static char_u menu_mode_chars[] = { 'n', 'v', 's', 'o', 'i', 'c', 't' };
static char_u e_notsubmenu[] = N_(
"E327: Part of menu-item path is not sub-menu");
@@ -44,28 +47,24 @@ static char_u e_othermode[] = N_("E328: Menu only exists in another mode");
static char_u e_nomenu[] = N_("E329: No menu \"%s\"");
-/*
- * Do the :menu command and relatives.
- */
-void
-ex_menu (
- exarg_T *eap /* Ex command arguments */
-)
+/// Do the :menu command and relatives.
+/// @param eap Ex command arguments
+void
+ex_menu(exarg_T *eap)
{
char_u *menu_path;
int modes;
- char_u *map_to;
+ char_u *map_to; // command mapped to the menu entry
int noremap;
bool silent = false;
- bool special = false;
int unmenu;
char_u *map_buf;
char_u *arg;
char_u *p;
int i;
long pri_tab[MENUDEPTH + 1];
- int enable = MAYBE; /* TRUE for "menu enable", FALSE for "menu
- * disable */
+ TriState enable = kNone; // kTrue for "menu enable",
+ // kFalse for "menu disable
vimmenu_T menuarg;
modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu);
@@ -83,7 +82,7 @@ ex_menu (
continue;
}
if (STRNCMP(arg, "<special>", 9) == 0) {
- special = true;
+ // Ignore obsolete "<special>" modifier.
arg = skipwhite(arg + 9);
continue;
}
@@ -91,13 +90,14 @@ ex_menu (
}
- /* Locate an optional "icon=filename" argument. */
+ // Locate an optional "icon=filename" argument
+ // TODO(nvim): Currently this is only parsed. Should expose it to UIs.
if (STRNCMP(arg, "icon=", 5) == 0) {
arg += 5;
while (*arg != NUL && *arg != ' ') {
if (*arg == '\\')
STRMOVE(arg, arg + 1);
- mb_ptr_adv(arg);
+ MB_PTR_ADV(arg);
}
if (*arg != NUL) {
*arg++ = NUL;
@@ -105,12 +105,12 @@ ex_menu (
}
}
- /*
- * Fill in the priority table.
- */
- for (p = arg; *p; ++p)
- if (!ascii_isdigit(*p) && *p != '.')
+ // Fill in the priority table.
+ for (p = arg; *p; p++) {
+ if (!ascii_isdigit(*p) && *p != '.') {
break;
+ }
+ }
if (ascii_iswhite(*p)) {
for (i = 0; i < MENUDEPTH && !ascii_iswhite(*arg); ++i) {
pri_tab[i] = getdigits_long(&arg);
@@ -133,10 +133,10 @@ ex_menu (
* Check for "disable" or "enable" argument.
*/
if (STRNCMP(arg, "enable", 6) == 0 && ascii_iswhite(arg[6])) {
- enable = TRUE;
+ enable = kTrue;
arg = skipwhite(arg + 6);
} else if (STRNCMP(arg, "disable", 7) == 0 && ascii_iswhite(arg[7])) {
- enable = FALSE;
+ enable = kFalse;
arg = skipwhite(arg + 7);
}
@@ -160,22 +160,21 @@ ex_menu (
/*
* If there is only a menu name, display menus with that name.
*/
- if (*map_to == NUL && !unmenu && enable == MAYBE) {
+ if (*map_to == NUL && !unmenu && enable == kNone) {
show_menus(menu_path, modes);
goto theend;
- } else if (*map_to != NUL && (unmenu || enable != MAYBE)) {
+ } else if (*map_to != NUL && (unmenu || enable != kNone)) {
EMSG(_(e_trailing));
goto theend;
}
- if (enable != MAYBE) {
- /*
- * Change sensitivity of the menu.
- * For the PopUp menu, remove a menu for each mode separately.
- * Careful: menu_nable_recurse() changes menu_path.
- */
- if (STRCMP(menu_path, "*") == 0) /* meaning: do all menus */
+ if (enable != kNone) {
+ // Change sensitivity of the menu.
+ // For the PopUp menu, remove a menu for each mode separately.
+ // Careful: menu_nable_recurse() changes menu_path.
+ if (STRCMP(menu_path, "*") == 0) { // meaning: do all menus
menu_path = (char_u *)"";
+ }
if (menu_is_popup(menu_path)) {
for (i = 0; i < MENU_INDEX_TIP; ++i)
@@ -219,13 +218,12 @@ ex_menu (
map_buf = NULL; // Menu tips are plain text.
} else {
map_to = replace_termcodes(map_to, STRLEN(map_to), &map_buf, false, true,
- special, CPO_TO_CPO_FLAGS);
+ true, CPO_TO_CPO_FLAGS);
}
menuarg.modes = modes;
menuarg.noremap[0] = noremap;
menuarg.silent[0] = silent;
- add_menu_path(menu_path, &menuarg, pri_tab, map_to
- );
+ add_menu_path(menu_path, &menuarg, pri_tab, map_to);
/*
* For the PopUp menu, add a menu for each mode separately.
@@ -244,22 +242,24 @@ ex_menu (
xfree(map_buf);
}
- ui_update_menu();
+ ui_call_update_menu();
theend:
;
}
-/*
- * Add the menu with the given name to the menu hierarchy
- */
-static int
-add_menu_path (
- char_u *menu_path,
- vimmenu_T *menuarg, /* passes modes, iconfile, iconidx,
- icon_builtin, silent[0], noremap[0] */
- long *pri_tab,
- char_u *call_data
+
+/// Add the menu with the given name to the menu hierarchy
+///
+/// @param[out] menuarg menu entry
+/// @param[] pri_tab priority table
+/// @param[in] call_data Right hand side command
+static int
+add_menu_path(
+ const char_u *const menu_path,
+ vimmenu_T *menuarg,
+ const long *const pri_tab,
+ const char_u *const call_data
)
{
char_u *path_name;
@@ -294,8 +294,9 @@ add_menu_path (
if (map_to != NULL) {
en_name = name;
name = map_to;
- } else
+ } else {
en_name = NULL;
+ }
dname = menu_text(name, NULL, NULL);
if (*dname == NUL) {
/* Only a mnemonic or accelerator is not valid. */
@@ -309,14 +310,15 @@ add_menu_path (
while (menu != NULL) {
if (menu_name_equal(name, menu) || menu_name_equal(dname, menu)) {
if (*next_name == NUL && menu->children != NULL) {
- if (!sys_menu)
+ if (!sys_menu) {
EMSG(_("E330: Menu path must not lead to a sub-menu"));
+ }
goto erret;
}
- if (*next_name != NUL && menu->children == NULL
- ) {
- if (!sys_menu)
+ if (*next_name != NUL && menu->children == NULL) {
+ if (!sys_menu) {
EMSG(_(e_notsubmenu));
+ }
goto erret;
}
break;
@@ -350,7 +352,7 @@ add_menu_path (
menu->modes = modes;
menu->enabled = MENU_ALL_MODES;
menu->name = vim_strsave(name);
- /* separate mnemonic and accelerator text from actual menu name */
+ // separate mnemonic and accelerator text from actual menu name
menu->dname = menu_text(name, &menu->mnemonic, &menu->actext);
if (en_name != NULL) {
menu->en_name = vim_strsave(en_name);
@@ -362,9 +364,7 @@ add_menu_path (
menu->priority = pri_tab[pri_idx];
menu->parent = parent;
- /*
- * Add after menu that has lower priority.
- */
+ // Add after menu that has lower priority.
menu->next = *lower_pri;
*lower_pri = menu;
@@ -390,8 +390,9 @@ add_menu_path (
name = next_name;
xfree(dname);
dname = NULL;
- if (pri_tab[pri_idx + 1] != -1)
- ++pri_idx;
+ if (pri_tab[pri_idx + 1] != -1) {
+ pri_idx++;
+ }
}
xfree(path_name);
@@ -417,8 +418,7 @@ add_menu_path (
// Don't do this for "<Nop>".
c = 0;
d = 0;
- if (amenu && call_data != NULL && *call_data != NUL
- ) {
+ if (amenu && call_data != NULL && *call_data != NUL) {
switch (1 << i) {
case MENU_VISUAL_MODE:
case MENU_SELECT_MODE:
@@ -436,9 +436,9 @@ add_menu_path (
if (c != 0) {
menu->strings[i] = xmalloc(STRLEN(call_data) + 5 );
menu->strings[i][0] = c;
- if (d == 0)
+ if (d == 0) {
STRCPY(menu->strings[i] + 1, call_data);
- else {
+ } else {
menu->strings[i][1] = d;
STRCPY(menu->strings[i] + 2, call_data);
}
@@ -450,8 +450,9 @@ add_menu_path (
menu->strings[i][len + 1] = Ctrl_G;
menu->strings[i][len + 2] = NUL;
}
- } else
+ } else {
menu->strings[i] = p;
+ }
menu->noremap[i] = menuarg->noremap[0];
menu->silent[i] = menuarg->silent[0];
}
@@ -655,20 +656,109 @@ static void free_menu_string(vimmenu_T *menu, int idx)
menu->strings[idx] = NULL;
}
-/*
- * Show the mapping associated with a menu item or hierarchy in a sub-menu.
- */
-static int show_menus(char_u *path_name, int modes)
+/// Export menus
+///
+/// @param[in] menu if null, starts from root_menu
+/// @param modes, a choice of \ref MENU_MODES
+/// @return a dict with name/commands
+/// @see menu_get
+static dict_T *menu_get_recursive(const vimmenu_T *menu, int modes)
+{
+ dict_T *dict;
+
+ if (!menu || (menu->modes & modes) == 0x0) {
+ return NULL;
+ }
+
+ dict = tv_dict_alloc();
+ tv_dict_add_str(dict, S_LEN("name"), (char *)menu->dname);
+ tv_dict_add_nr(dict, S_LEN("priority"), (int)menu->priority);
+ tv_dict_add_nr(dict, S_LEN("hidden"), menu_is_hidden(menu->dname));
+
+ if (menu->mnemonic) {
+ char buf[MB_MAXCHAR + 1] = { 0 }; // > max value of utf8_char2bytes
+ utf_char2bytes(menu->mnemonic, (char_u *)buf);
+ tv_dict_add_str(dict, S_LEN("shortcut"), buf);
+ }
+
+ if (menu->actext) {
+ tv_dict_add_str(dict, S_LEN("actext"), (char *)menu->actext);
+ }
+
+ if (menu->modes & MENU_TIP_MODE && menu->strings[MENU_INDEX_TIP]) {
+ tv_dict_add_str(dict, S_LEN("tooltip"),
+ (char *)menu->strings[MENU_INDEX_TIP]);
+ }
+
+ if (!menu->children) {
+ // leaf menu
+ dict_T *commands = tv_dict_alloc();
+ tv_dict_add_dict(dict, S_LEN("mappings"), commands);
+
+ for (int bit = 0; bit < MENU_MODES; bit++) {
+ if ((menu->modes & modes & (1 << bit)) != 0) {
+ dict_T *impl = tv_dict_alloc();
+ tv_dict_add_allocated_str(impl, S_LEN("rhs"),
+ str2special_save((char *)menu->strings[bit],
+ false, false));
+ tv_dict_add_nr(impl, S_LEN("silent"), menu->silent[bit]);
+ tv_dict_add_nr(impl, S_LEN("enabled"),
+ (menu->enabled & (1 << bit)) ? 1 : 0);
+ tv_dict_add_nr(impl, S_LEN("noremap"),
+ (menu->noremap[bit] & REMAP_NONE) ? 1 : 0);
+ tv_dict_add_nr(impl, S_LEN("sid"),
+ (menu->noremap[bit] & REMAP_SCRIPT) ? 1 : 0);
+ tv_dict_add_dict(commands, (char *)&menu_mode_chars[bit], 1, impl);
+ }
+ }
+ } else {
+ // visit recursively all children
+ list_T *const children_list = tv_list_alloc(kListLenMayKnow);
+ for (menu = menu->children; menu != NULL; menu = menu->next) {
+ dict_T *dic = menu_get_recursive(menu, modes);
+ if (tv_dict_len(dict) > 0) {
+ tv_list_append_dict(children_list, dic);
+ }
+ }
+ tv_dict_add_list(dict, S_LEN("submenus"), children_list);
+ }
+ return dict;
+}
+
+
+/// Export menus matching path \p path_name
+///
+/// @param path_name
+/// @param modes supported modes, see \ref MENU_MODES
+/// @param[in,out] list must be allocated
+/// @return false if could not find path_name
+bool menu_get(char_u *const path_name, int modes, list_T *list)
{
- char_u *p;
- char_u *name;
vimmenu_T *menu;
- vimmenu_T *parent = NULL;
+ menu = find_menu(root_menu, path_name, modes);
+ if (!menu) {
+ return false;
+ }
+ for (; menu != NULL; menu = menu->next) {
+ dict_T *dict = menu_get_recursive(menu, modes);
+ if (dict && tv_dict_len(dict) > 0) {
+ tv_list_append_dict(list, dict);
+ }
+ }
+ return true;
+}
- menu = root_menu;
- name = path_name = vim_strsave(path_name);
- /* First, find the (sub)menu with the given name */
+/// Find menu matching required name and modes
+///
+/// @param menu top menu to start looking from
+/// @param name path towards the menu
+/// @return menu if \p name is null, found menu or NULL
+vimmenu_T *
+find_menu(vimmenu_T *menu, char_u * name, int modes)
+{
+ char_u *p;
+
while (*name) {
p = menu_name_skip(name);
while (menu != NULL) {
@@ -676,39 +766,46 @@ static int show_menus(char_u *path_name, int modes)
/* Found menu */
if (*p != NUL && menu->children == NULL) {
EMSG(_(e_notsubmenu));
- xfree(path_name);
- return FAIL;
+ return NULL;
} else if ((menu->modes & modes) == 0x0) {
EMSG(_(e_othermode));
- xfree(path_name);
- return FAIL;
+ return NULL;
}
break;
}
menu = menu->next;
}
+
if (menu == NULL) {
EMSG2(_(e_nomenu), name);
- xfree(path_name);
- return FAIL;
+ return NULL;
}
name = p;
- parent = menu;
menu = menu->children;
}
- xfree(path_name);
+ return menu;
+}
+
+/// Show the mapping associated with a menu item or hierarchy in a sub-menu.
+static int show_menus(char_u *const path_name, int modes)
+{
+ vimmenu_T *menu;
+
+ // First, find the (sub)menu with the given name
+ menu = find_menu(root_menu, path_name, modes);
+ if (!menu) {
+ return FAIL;
+ }
/* Now we have found the matching menu, and we list the mappings */
/* Highlight title */
MSG_PUTS_TITLE(_("\n--- Menus ---"));
- show_menus_recursive(parent, modes, 0);
+ show_menus_recursive(menu->parent, modes, 0);
return OK;
}
-/*
- * Recursively show the mappings associated with the menus under the given one
- */
+/// Recursively show the mappings associated with the menus under the given one
static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
{
int i;
@@ -727,8 +824,8 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
msg_outnum((long)menu->priority);
MSG_PUTS(" ");
}
- /* Same highlighting as for directories!? */
- msg_outtrans_attr(menu->name, hl_attr(HLF_D));
+ // Same highlighting as for directories!?
+ msg_outtrans_attr(menu->name, HL_ATTR(HLF_D));
}
if (menu != NULL && menu->children == NULL) {
@@ -755,10 +852,11 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth)
else
msg_putchar(' ');
MSG_PUTS(" ");
- if (*menu->strings[bit] == NUL)
- msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
- else
- msg_outtrans_special(menu->strings[bit], FALSE);
+ if (*menu->strings[bit] == NUL) {
+ msg_puts_attr("<Nop>", HL_ATTR(HLF_8));
+ } else {
+ msg_outtrans_special(menu->strings[bit], false);
+ }
}
} else {
if (menu == NULL) {
@@ -990,16 +1088,17 @@ char_u *get_menu_names(expand_T *xp, int idx)
return str;
}
-/*
- * Skip over this element of the menu path and return the start of the next
- * element. Any \ and ^Vs are removed from the current element.
- * "name" may be modified.
- */
-char_u *menu_name_skip(char_u *name)
+
+/// Skip over this element of the menu path and return the start of the next
+/// element. Any \ and ^Vs are removed from the current element.
+///
+/// @param name may be modified.
+/// @return start of the next element
+char_u *menu_name_skip(char_u *const name)
{
char_u *p;
- for (p = name; *p && *p != '.'; mb_ptr_adv(p)) {
+ for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) {
if (*p == '\\' || *p == Ctrl_V) {
STRMOVE(p, p + 1);
if (*p == NUL)
@@ -1015,16 +1114,16 @@ char_u *menu_name_skip(char_u *name)
* Return TRUE when "name" matches with menu "menu". The name is compared in
* two ways: raw menu name and menu name without '&'. ignore part after a TAB.
*/
-static int menu_name_equal(char_u *name, vimmenu_T *menu)
+static bool menu_name_equal(const char_u *const name, vimmenu_T *const menu)
{
if (menu->en_name != NULL
&& (menu_namecmp(name, menu->en_name)
|| menu_namecmp(name, menu->en_dname)))
- return TRUE;
+ return true;
return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname);
}
-static int menu_namecmp(char_u *name, char_u *mname)
+static bool menu_namecmp(const char_u *const name, const char_u *const mname)
{
int i;
@@ -1035,18 +1134,20 @@ static int menu_namecmp(char_u *name, char_u *mname)
&& (mname[i] == NUL || mname[i] == TAB);
}
-/*
- * Return the modes specified by the given menu command (eg :menu! returns
- * MENU_CMDLINE_MODE | MENU_INSERT_MODE).
- * If "noremap" is not NULL, then the flag it points to is set according to
- * whether the command is a "nore" command.
- * If "unmenu" is not NULL, then the flag it points to is set according to
- * whether the command is an "unmenu" command.
- */
-static int
-get_menu_cmd_modes (
- char_u *cmd,
- int forceit, /* Was there a "!" after the command? */
+
+/// Returns the \ref MENU_MODES specified by menu command `cmd`.
+/// (eg :menu! returns MENU_CMDLINE_MODE | MENU_INSERT_MODE)
+///
+/// @param[in] cmd string like "nmenu", "vmenu", etc.
+/// @param[in] forceit bang (!) was given after the command
+/// @param[out] noremap If not NULL, the flag it points to is set according
+/// to whether the command is a "nore" command.
+/// @param[out] unmenu If not NULL, the flag it points to is set according
+/// to whether the command is an "unmenu" command.
+int
+get_menu_cmd_modes(
+ const char_u * cmd,
+ bool forceit,
int *noremap,
int *unmenu
)
@@ -1085,14 +1186,17 @@ get_menu_cmd_modes (
modes = MENU_NORMAL_MODE;
break;
}
- /* FALLTHROUGH */
+ FALLTHROUGH;
default:
- --cmd;
- if (forceit) /* menu!! */
+ cmd--;
+ if (forceit) {
+ // menu!!
modes = MENU_INSERT_MODE | MENU_CMDLINE_MODE;
- else /* menu */
+ } else {
+ // menu
modes = MENU_NORMAL_MODE | MENU_VISUAL_MODE | MENU_SELECT_MODE
| MENU_OP_PENDING_MODE;
+ }
}
if (noremap != NULL)
@@ -1198,12 +1302,14 @@ int menu_is_separator(char_u *name)
return name[0] == '-' && name[STRLEN(name) - 1] == '-';
}
-/*
- * Return TRUE if the menu is hidden: Starts with ']'
- */
+
+/// True if a popup menu or starts with \ref MNU_HIDDEN_CHAR
+///
+/// @return true if the menu is hidden
static int menu_is_hidden(char_u *name)
{
- return (name[0] == ']') || (menu_is_popup(name) && name[5] != NUL);
+ return (name[0] == MNU_HIDDEN_CHAR)
+ || (menu_is_popup(name) && name[5] != NUL);
}
/*
@@ -1310,17 +1416,20 @@ void ex_emenu(exarg_T *eap)
idx = MENU_INDEX_NORMAL;
}
- if (idx != MENU_INDEX_INVALID && menu->strings[idx] != NULL) {
- /* When executing a script or function execute the commands right now.
- * Otherwise put them in the typeahead buffer. */
- if (current_SID != 0)
+ assert(idx != MENU_INDEX_INVALID);
+ if (menu->strings[idx] != NULL) {
+ // When executing a script or function execute the commands right now.
+ // Otherwise put them in the typeahead buffer.
+ if (current_SID != 0) {
exec_normal_cmd(menu->strings[idx], menu->noremap[idx],
- menu->silent[idx]);
- else
- ins_typebuf(menu->strings[idx], menu->noremap[idx], 0,
- TRUE, menu->silent[idx]);
- } else
+ menu->silent[idx]);
+ } else {
+ ins_typebuf(menu->strings[idx], menu->noremap[idx], 0, true,
+ menu->silent[idx]);
+ }
+ } else {
EMSG2(_("E335: Menu not defined for %s mode"), mode);
+ }
}
/*
@@ -1439,9 +1548,11 @@ static void menu_unescape_name(char_u *name)
{
char_u *p;
- for (p = name; *p && *p != '.'; mb_ptr_adv(p))
- if (*p == '\\')
+ for (p = name; *p && *p != '.'; MB_PTR_ADV(p)) {
+ if (*p == '\\') {
STRMOVE(p, p + 1);
+ }
+ }
}
/*
diff --git a/src/nvim/menu.h b/src/nvim/menu.h
index 3266c511b4..5ff979f2bf 100644
--- a/src/nvim/menu.h
+++ b/src/nvim/menu.h
@@ -1,7 +1,14 @@
#ifndef NVIM_MENU_H
#define NVIM_MENU_H
-/* Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode */
+#include <stdbool.h> // for bool
+
+#include "nvim/types.h" // for char_u and expand_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+
+/// Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode
+/// \addtogroup MENU_INDEX
+/// @{
#define MENU_INDEX_INVALID -1
#define MENU_INDEX_NORMAL 0
#define MENU_INDEX_VISUAL 1
@@ -11,8 +18,12 @@
#define MENU_INDEX_CMDLINE 5
#define MENU_INDEX_TIP 6
#define MENU_MODES 7
+/// @}
+/// note MENU_INDEX_TIP is not a 'real' mode
-/* Menu modes */
+/// Menu modes
+/// \addtogroup MENU_MODES
+/// @{
#define MENU_NORMAL_MODE (1 << MENU_INDEX_NORMAL)
#define MENU_VISUAL_MODE (1 << MENU_INDEX_VISUAL)
#define MENU_SELECT_MODE (1 << MENU_INDEX_SELECT)
@@ -21,31 +32,30 @@
#define MENU_CMDLINE_MODE (1 << MENU_INDEX_CMDLINE)
#define MENU_TIP_MODE (1 << MENU_INDEX_TIP)
#define MENU_ALL_MODES ((1 << MENU_INDEX_TIP) - 1)
-/*note MENU_INDEX_TIP is not a 'real' mode*/
+/// @}
-/* Start a menu name with this to not include it on the main menu bar */
+/// Start a menu name with this to not include it on the main menu bar
#define MNU_HIDDEN_CHAR ']'
typedef struct VimMenu vimmenu_T;
struct VimMenu {
- int modes; /* Which modes is this menu visible for? */
- int enabled; /* for which modes the menu is enabled */
- char_u *name; /* Name of menu, possibly translated */
- char_u *dname; /* Displayed Name ("name" without '&') */
- char_u *en_name; /* "name" untranslated, NULL when "name"
- * was not translated */
- char_u *en_dname; /* "dname" untranslated, NULL when "dname"
- * was not translated */
- int mnemonic; /* mnemonic key (after '&') */
- char_u *actext; /* accelerator text (after TAB) */
- long priority; /* Menu order priority */
- char_u *strings[MENU_MODES]; /* Mapped string for each mode */
- int noremap[MENU_MODES]; /* A REMAP_ flag for each mode */
- bool silent[MENU_MODES]; /* A silent flag for each mode */
- vimmenu_T *children; /* Children of sub-menu */
- vimmenu_T *parent; /* Parent of menu */
- vimmenu_T *next; /* Next item in menu */
+ int modes; ///< Which modes is this menu visible for
+ int enabled; ///< for which modes the menu is enabled
+ char_u *name; ///< Name of menu, possibly translated
+ char_u *dname; ///< Displayed Name ("name" without '&')
+ char_u *en_name; ///< "name" untranslated, NULL when
+ ///< was not translated
+ char_u *en_dname; ///< NULL when "dname" untranslated
+ int mnemonic; ///< mnemonic key (after '&')
+ char_u *actext; ///< accelerator text (after TAB)
+ long priority; ///< Menu order priority
+ char_u *strings[MENU_MODES]; ///< Mapped string for each mode
+ int noremap[MENU_MODES]; ///< A \ref REMAP_VALUES flag for each mode
+ bool silent[MENU_MODES]; ///< A silent flag for each mode
+ vimmenu_T *children; ///< Children of sub-menu
+ vimmenu_T *parent; ///< Parent of menu
+ vimmenu_T *next; ///< Next item in menu
};
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 77e8f0e4f2..37e40c3cc1 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.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
+
/*
* message.c: functions for displaying messages on the command line
*/
@@ -7,10 +10,10 @@
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
-#include <math.h>
#include "nvim/vim.h"
#include "nvim/ascii.h"
+#include "nvim/assert.h"
#include "nvim/message.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
@@ -19,15 +22,16 @@
#include "nvim/fileio.h"
#include "nvim/func_attr.h"
#include "nvim/getchar.h"
+#include "nvim/main.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/garray.h"
#include "nvim/ops.h"
#include "nvim/option.h"
#include "nvim/normal.h"
+#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
@@ -128,9 +132,9 @@ int verb_msg(char_u *s)
return n;
}
-int msg_attr(char_u *s, int attr) FUNC_ATTR_NONNULL_ARG(1)
+int msg_attr(const char *s, const int attr) FUNC_ATTR_NONNULL_ARG(1)
{
- return msg_attr_keep(s, attr, FALSE);
+ return msg_attr_keep((char_u *)s, attr, false);
}
int
@@ -145,6 +149,12 @@ msg_attr_keep (
int retval;
char_u *buf = NULL;
+ // Skip messages not match ":filter pattern".
+ // Don't filter when there is an error.
+ if (!emsg_on_display && message_filtered(s)) {
+ return true;
+ }
+
if (attr == 0) {
set_vim_var_string(VV_STATUSMSG, (char *) s, -1);
}
@@ -164,8 +174,9 @@ msg_attr_keep (
|| (*s != '<'
&& last_msg_hist != NULL
&& last_msg_hist->msg != NULL
- && STRCMP(s, last_msg_hist->msg)))
- add_msg_hist(s, -1, attr);
+ && STRCMP(s, last_msg_hist->msg))) {
+ add_msg_hist((const char *)s, -1, attr);
+ }
/* When displaying keep_msg, don't let msg_start() free it, caller must do
* that. */
@@ -236,17 +247,19 @@ msg_strtrunc (
* Truncate a string "s" to "buf" with cell width "room".
* "s" and "buf" may be equal.
*/
-void trunc_string(char_u *s, char_u *buf, int room, int buflen)
+void trunc_string(char_u *s, char_u *buf, int room_in, int buflen)
{
- int half;
- int len;
+ size_t room = room_in - 3; // "..." takes 3 chars
+ size_t half;
+ size_t len = 0;
int e;
int i;
int n;
- room -= 3;
+ if (room_in < 3) {
+ room = 0;
+ }
half = room / 2;
- len = 0;
/* First part: Start of the string. */
for (e = 0; len < half && e < buflen; ++e) {
@@ -256,8 +269,9 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen)
return;
}
n = ptr2cells(s + e);
- if (len + n >= half)
+ if (len + n > half) {
break;
+ }
len += n;
buf[e] = s[e];
if (has_mbyte)
@@ -268,45 +282,46 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen)
}
}
- /* Last part: End of the string. */
- i = e;
- if (enc_dbcs != 0) {
- /* For DBCS going backwards in a string is slow, but
- * computing the cell width isn't too slow: go forward
- * until the rest fits. */
- n = vim_strsize(s + i);
- while (len + n > room) {
- n -= ptr2cells(s + i);
- i += (*mb_ptr2len)(s + i);
- }
- } else if (enc_utf8) {
- /* For UTF-8 we can go backwards easily. */
- half = i = (int)STRLEN(s);
- for (;; ) {
- do
- half = half - (*mb_head_off)(s, s + half - 1) - 1;
- while (utf_iscomposing(utf_ptr2char(s + half)) && half > 0);
- n = ptr2cells(s + half);
- if (len + n > room)
- break;
- len += n;
- i = half;
+ // Last part: End of the string.
+ half = i = (int)STRLEN(s);
+ for (;;) {
+ do {
+ half = half - utf_head_off(s, s + half - 1) - 1;
+ } while (half > 0 && utf_iscomposing(utf_ptr2char(s + half)));
+ n = ptr2cells(s + half);
+ if (len + n > room || half == 0) {
+ break;
}
- } else {
- for (i = (int)STRLEN(s); len + (n = ptr2cells(s + i - 1)) <= room; --i)
- len += n;
+ len += n;
+ i = half;
}
- /* Set the middle and copy the last part. */
- if (e + 3 < buflen) {
+ if (i <= e + 3) {
+ // text fits without truncating
+ if (s != buf) {
+ len = STRLEN(s);
+ if (len >= (size_t)buflen) {
+ len = buflen - 1;
+ }
+ len = len - e + 1;
+ if (len < 1) {
+ buf[e - 1] = NUL;
+ } else {
+ memmove(buf + e, s + e, len);
+ }
+ }
+ } else if (e + 3 < buflen) {
+ // set the middle and copy the last part
memmove(buf + e, "...", (size_t)3);
- len = (int)STRLEN(s + i) + 1;
- if (len >= buflen - e - 3)
+ len = STRLEN(s + i) + 1;
+ if (len >= (size_t)buflen - e - 3) {
len = buflen - e - 3 - 1;
+ }
memmove(buf + e + 3, s + i, len);
buf[e + 3 + len - 1] = NUL;
} else {
- buf[e - 1] = NUL; /* make sure it is truncated */
+ // can't fit in the "...", just truncate it
+ buf[e - 1] = NUL;
}
}
@@ -316,6 +331,7 @@ void trunc_string(char_u *s, char_u *buf, int room, int buflen)
*/
int smsg(char *s, ...)
+ FUNC_ATTR_PRINTF(1, 2)
{
va_list arglist;
@@ -326,13 +342,14 @@ int smsg(char *s, ...)
}
int smsg_attr(int attr, char *s, ...)
+ FUNC_ATTR_PRINTF(2, 3)
{
va_list arglist;
va_start(arglist, s);
vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist, NULL);
va_end(arglist);
- return msg_attr(IObuff, attr);
+ return msg_attr((const char *)IObuff, attr);
}
/*
@@ -366,42 +383,40 @@ static int other_sourcing_name(void)
return FALSE;
}
-/*
- * Get the message about the source, as used for an error message.
- * Returns an allocated string with room for one more character.
- * Returns NULL when no message is to be given.
- */
-static char_u *get_emsg_source(void)
+/// Get the message about the source, as used for an error message
+///
+/// @return [allocated] String with room for one more character. NULL when no
+/// message is to be given.
+static char *get_emsg_source(void)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
- char_u *Buf, *p;
-
if (sourcing_name != NULL && other_sourcing_name()) {
- p = (char_u *)_("Error detected while processing %s:");
- Buf = xmalloc(STRLEN(sourcing_name) + STRLEN(p));
- sprintf((char *)Buf, (char *)p, sourcing_name);
- return Buf;
+ const char *const p = _("Error detected while processing %s:");
+ const size_t buf_len = STRLEN(sourcing_name) + strlen(p) + 1;
+ char *const buf = xmalloc(buf_len);
+ snprintf(buf, buf_len, p, sourcing_name);
+ return buf;
}
return NULL;
}
-/*
- * Get the message about the source lnum, as used for an error message.
- * Returns an allocated string with room for one more character.
- * Returns NULL when no message is to be given.
- */
-static char_u *get_emsg_lnum(void)
+/// Get the message about the source lnum, as used for an error message.
+///
+/// @return [allocated] String with room for one more character. NULL when no
+/// message is to be given.
+static char *get_emsg_lnum(void)
+ FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
{
- char_u *Buf, *p;
-
- /* lnum is 0 when executing a command from the command line
- * argument, we don't want a line number then */
+ // lnum is 0 when executing a command from the command line
+ // argument, we don't want a line number then
if (sourcing_name != NULL
&& (other_sourcing_name() || sourcing_lnum != last_sourcing_lnum)
&& sourcing_lnum != 0) {
- p = (char_u *)_("line %4ld:");
- Buf = xmalloc(STRLEN(p) + 20);
- sprintf((char *)Buf, (char *)p, (long)sourcing_lnum);
- return Buf;
+ const char *const p = _("line %4ld:");
+ const size_t buf_len = 20 + strlen(p);
+ char *const buf = xmalloc(buf_len);
+ snprintf(buf, buf_len, p, (long)sourcing_lnum);
+ return buf;
}
return NULL;
}
@@ -413,17 +428,15 @@ static char_u *get_emsg_lnum(void)
*/
void msg_source(int attr)
{
- char_u *p;
-
- ++no_wait_return;
- p = get_emsg_source();
+ no_wait_return++;
+ char *p = get_emsg_source();
if (p != NULL) {
msg_attr(p, attr);
xfree(p);
}
p = get_emsg_lnum();
if (p != NULL) {
- msg_attr(p, hl_attr(HLF_N));
+ msg_attr(p, HL_ATTR(HLF_N));
xfree(p);
last_sourcing_lnum = sourcing_lnum; /* only once for each line */
}
@@ -463,10 +476,10 @@ int emsg_not_now(void)
*
* return TRUE if wait_return not called
*/
-int emsg(char_u *s)
+int emsg(const char_u *s_)
{
+ const char *s = (const char *)s_;
int attr;
- char_u *p;
int ignore = false;
int severe;
@@ -476,9 +489,6 @@ int emsg(char_u *s)
}
called_emsg = true;
- if (emsg_silent == 0) {
- ex_exitval = 1;
- }
// If "emsg_severe" is TRUE: When an error exception is to be thrown,
// prefer this message over previous messages for the same command.
@@ -493,41 +503,47 @@ int emsg(char_u *s)
* when the message should be ignored completely (used for the
* interrupt message).
*/
- if (cause_errthrow(s, severe, &ignore) == true) {
+ if (cause_errthrow((char_u *)s, severe, &ignore) == true) {
if (!ignore) {
- did_emsg = true;
+ did_emsg++;
}
return true;
}
// set "v:errmsg", also when using ":silent! cmd"
- set_vim_var_string(VV_ERRMSG, (char *) s, -1);
+ set_vim_var_string(VV_ERRMSG, s, -1);
/*
* When using ":silent! cmd" ignore error messages.
* But do write it to the redirection file.
*/
if (emsg_silent != 0) {
- msg_start();
- p = get_emsg_source();
- if (p != NULL) {
- STRCAT(p, "\n");
- redir_write(p, STRLEN(p));
- xfree(p);
- }
- p = get_emsg_lnum();
- if (p != NULL) {
- STRCAT(p, "\n");
- redir_write(p, STRLEN(p));
- xfree(p);
+ if (!emsg_noredir) {
+ msg_start();
+ char *p = get_emsg_source();
+ if (p != NULL) {
+ const size_t p_len = strlen(p);
+ p[p_len] = '\n';
+ redir_write(p, p_len + 1);
+ xfree(p);
+ }
+ p = get_emsg_lnum();
+ if (p != NULL) {
+ const size_t p_len = strlen(p);
+ p[p_len] = '\n';
+ redir_write(p, p_len + 1);
+ xfree(p);
+ }
+ redir_write(s, strlen(s));
}
- redir_write(s, STRLEN(s));
return true;
}
+ ex_exitval = 1;
+
// Reset msg_silent, an error causes messages to be switched back on.
msg_silent = 0;
- cmd_silent = FALSE;
+ cmd_silent = false;
if (global_busy) { // break :global command
global_busy++;
@@ -536,14 +552,14 @@ int emsg(char_u *s)
if (p_eb) {
beep_flush(); // also includes flush_buffers()
} else {
- flush_buffers(false); // flush internal buffers
+ flush_buffers(FLUSH_MINIMAL); // flush internal buffers
}
- did_emsg = true; // flag for DoOneCmd()
+ did_emsg++; // flag for DoOneCmd()
}
emsg_on_display = true; // remember there is an error message
msg_scroll++; // don't overwrite a previous message
- attr = hl_attr(HLF_E); // set highlight mode for error messages
+ attr = HL_ATTR(HLF_E); // set highlight mode for error messages
if (msg_scrolled != 0) {
need_wait_return = true; // needed in case emsg() is called after
} // wait_return has reset need_wait_return
@@ -555,10 +571,8 @@ int emsg(char_u *s)
*/
msg_source(attr);
- /*
- * Display the error message itself.
- */
- msg_nowait = FALSE; /* wait for this msg */
+ // Display the error message itself.
+ msg_nowait = false; // Wait for this msg.
return msg_attr(s, attr);
}
@@ -569,17 +583,79 @@ void emsg_invreg(int name)
/// Print an error message with unknown number of arguments
bool emsgf(const char *const fmt, ...)
+ FUNC_ATTR_PRINTF(1, 2)
{
+ bool ret;
+
+ va_list ap;
+ va_start(ap, fmt);
+ ret = emsgfv(fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+/// Print an error message with unknown number of arguments
+static bool emsgfv(const char *fmt, va_list ap)
+{
+ static char errbuf[IOSIZE];
if (emsg_not_now()) {
return true;
}
+ vim_vsnprintf(errbuf, sizeof(errbuf), fmt, ap, NULL);
+
+ return emsg((const char_u *)errbuf);
+}
+
+/// Same as emsg(...), but abort on error when ABORT_ON_INTERNAL_ERROR is
+/// defined. It is used for internal errors only, so that they can be
+/// detected when fuzzing vim.
+void iemsg(const char *s)
+{
+ emsg((char_u *)s);
+#ifdef ABORT_ON_INTERNAL_ERROR
+ abort();
+#endif
+}
+
+/// Same as emsgf(...) but abort on error when ABORT_ON_INTERNAL_ERROR is
+/// defined. It is used for internal errors only, so that they can be
+/// detected when fuzzing vim.
+void iemsgf(const char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ (void)emsgfv(s, ap);
+ va_end(ap);
+#ifdef ABORT_ON_INTERNAL_ERROR
+ abort();
+#endif
+}
+
+/// Give an "Internal error" message.
+void internal_error(char *where)
+{
+ IEMSG2(_(e_intern2), where);
+}
+
+static void msg_emsgf_event(void **argv)
+{
+ char *s = argv[0];
+ (void)emsg((char_u *)s);
+ xfree(s);
+}
+
+void msg_schedule_emsgf(const char *const fmt, ...)
+ FUNC_ATTR_PRINTF(1, 2)
+{
va_list ap;
va_start(ap, fmt);
- vim_vsnprintf((char *) IObuff, IOSIZE, fmt, ap, NULL);
+ vim_vsnprintf((char *)IObuff, IOSIZE, fmt, ap, NULL);
va_end(ap);
- return emsg(IObuff);
+ char *s = xstrdup((char *)IObuff);
+ loop_schedule(&main_loop, event_create(msg_emsgf_event, 1, s));
}
/*
@@ -592,14 +668,14 @@ char_u *msg_trunc_attr(char_u *s, int force, int attr)
{
int n;
- /* Add message to history before truncating */
- add_msg_hist(s, -1, attr);
+ // Add message to history before truncating.
+ add_msg_hist((const char *)s, -1, attr);
s = msg_may_trunc(force, s);
- msg_hist_off = TRUE;
- n = msg_attr(s, attr);
- msg_hist_off = FALSE;
+ msg_hist_off = true;
+ n = msg_attr((const char *)s, attr);
+ msg_hist_off = false;
if (n)
return s;
@@ -627,8 +703,8 @@ char_u *msg_may_trunc(int force, char_u *s)
return s;
for (n = 0; size >= room; ) {
- size -= (*mb_ptr2cells)(s + n);
- n += (*mb_ptr2len)(s + n);
+ size -= utf_ptr2cells(s + n);
+ n += utfc_ptr2len(s + n);
}
--n;
}
@@ -638,12 +714,8 @@ char_u *msg_may_trunc(int force, char_u *s)
return s;
}
-static void
-add_msg_hist (
- char_u *s,
- int len, /* -1 for undetermined length */
- int attr
-)
+/// @param[in] len Length of s or -1.
+static void add_msg_hist(const char *s, int len, int attr)
{
if (msg_hist_off || msg_silent != 0)
return;
@@ -661,9 +733,10 @@ add_msg_hist (
++s;
--len;
}
- while (len > 0 && s[len - 1] == '\n')
- --len;
- p->msg = vim_strnsave(s, len);
+ while (len > 0 && s[len - 1] == '\n') {
+ len--;
+ }
+ p->msg = (char_u *)xmemdupz(s, (size_t)len);
p->next = NULL;
p->attr = attr;
if (last_msg_hist != NULL)
@@ -696,27 +769,53 @@ int delete_first_msg(void)
return OK;
}
-/*
- * ":messages" command.
- */
-void ex_messages(exarg_T *eap)
+/// :messages command implementation
+void ex_messages(void *const eap_p)
+ FUNC_ATTR_NONNULL_ALL
{
+ const exarg_T *const eap = (const exarg_T *)eap_p;
struct msg_hist *p;
- const char *s;
+ int c = 0;
+
+ if (STRCMP(eap->arg, "clear") == 0) {
+ int keep = eap->addr_count == 0 ? 0 : eap->line2;
+
+ while (msg_hist_len > keep) {
+ (void)delete_first_msg();
+ }
+ return;
+ }
+
+ if (*eap->arg != NUL) {
+ EMSG(_(e_invarg));
+ return;
+ }
+
+ msg_hist_off = true;
- msg_hist_off = TRUE;
+ p = first_msg_hist;
- s = os_getenv("LANG");
- if (s)
- msg_attr((char_u *)
- _("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
- hl_attr(HLF_T));
+ if (eap->addr_count != 0) {
+ // Count total messages
+ for (; p != NULL && !got_int; p = p->next) {
+ c++;
+ }
+
+ c -= eap->line2;
+
+ // Skip without number of messages specified
+ for (p = first_msg_hist; p != NULL && !got_int && c > 0; p = p->next, c--) {
+ }
+ }
- for (p = first_msg_hist; p != NULL && !got_int; p = p->next)
- if (p->msg != NULL)
- msg_attr(p->msg, p->attr);
+ // Display what was not skipped.
+ for (; p != NULL && !got_int; p = p->next) {
+ if (p->msg != NULL) {
+ msg_attr((const char *)p->msg, p->attr);
+ }
+ }
- msg_hist_off = FALSE;
+ msg_hist_off = false;
}
/*
@@ -733,12 +832,11 @@ void msg_end_prompt(void)
lines_left = -1;
}
-/*
- * wait for the user to hit a key (normally a return)
- * if 'redraw' is TRUE, clear and redraw the screen
- * if 'redraw' is FALSE, just redraw the screen
- * if 'redraw' is -1, don't redraw at all
- */
+/// wait for the user to hit a key (normally a return)
+///
+/// if 'redraw' is true, redraw the entire screen NOT_VALID
+/// if 'redraw' is false, do a normal redraw
+/// if 'redraw' is -1, don't redraw at all
void wait_return(int redraw)
{
int c;
@@ -748,8 +846,9 @@ void wait_return(int redraw)
int save_Recording;
FILE *save_scriptout;
- if (redraw == TRUE)
- must_redraw = CLEAR;
+ if (redraw == true) {
+ redraw_all_later(NOT_VALID);
+ }
/* If using ":silent cmd", don't wait for a return. Also don't set
* need_wait_return to do it later. */
@@ -803,23 +902,22 @@ void wait_return(int redraw)
* CTRL-C, but we need to loop then. */
had_got_int = got_int;
- /* Don't do mappings here, we put the character back in the
- * typeahead buffer. */
- ++no_mapping;
- ++allow_keys;
+ // Don't do mappings here, we put the character back in the
+ // typeahead buffer.
+ no_mapping++;
- /* Temporarily disable Recording. If Recording is active, the
- * character will be recorded later, since it will be added to the
- * typebuf after the loop */
+ // Temporarily disable Recording. If Recording is active, the
+ // character will be recorded later, since it will be added to the
+ // typebuf after the loop
save_Recording = Recording;
save_scriptout = scriptout;
Recording = FALSE;
scriptout = NULL;
c = safe_vgetc();
- if (had_got_int && !global_busy)
- got_int = FALSE;
- --no_mapping;
- --allow_keys;
+ if (had_got_int && !global_busy) {
+ got_int = false;
+ }
+ no_mapping--;
Recording = save_Recording;
scriptout = save_scriptout;
@@ -940,9 +1038,10 @@ static void hit_return_msg(void)
if (got_int)
MSG_PUTS(_("Interrupt: "));
- MSG_PUTS_ATTR(_("Press ENTER or type command to continue"), hl_attr(HLF_R));
- if (!msg_use_printf())
+ MSG_PUTS_ATTR(_("Press ENTER or type command to continue"), HL_ATTR(HLF_R));
+ if (!msg_use_printf()) {
msg_clr_eos();
+ }
p_more = save_p_more;
}
@@ -996,9 +1095,10 @@ void msg_start(void)
msg_didout = FALSE; /* no output on current line yet */
}
- /* when redirecting, may need to start a new line. */
- if (!did_return)
- redir_write((char_u *)"\n", -1);
+ // When redirecting, may need to start a new line.
+ if (!did_return) {
+ redir_write("\n", 1);
+ }
}
/*
@@ -1017,24 +1117,24 @@ void msg_putchar(int c)
void msg_putchar_attr(int c, int attr)
{
- char_u buf[MB_MAXBYTES + 1];
+ char buf[MB_MAXBYTES + 1];
if (IS_SPECIAL(c)) {
- buf[0] = K_SPECIAL;
- buf[1] = K_SECOND(c);
- buf[2] = K_THIRD(c);
+ buf[0] = (char)K_SPECIAL;
+ buf[1] = (char)K_SECOND(c);
+ buf[2] = (char)K_THIRD(c);
buf[3] = NUL;
} else {
- buf[(*mb_char2bytes)(c, buf)] = NUL;
+ buf[utf_char2bytes(c, (char_u *)buf)] = NUL;
}
msg_puts_attr(buf, attr);
}
void msg_outnum(long n)
{
- char_u buf[20];
+ char buf[20];
- sprintf((char *)buf, "%" PRId64, (int64_t)n);
+ snprintf(buf, sizeof(buf), "%ld", n);
msg_puts(buf);
}
@@ -1045,7 +1145,7 @@ void msg_home_replace(char_u *fname)
void msg_home_replace_hl(char_u *fname)
{
- msg_home_replace_attr(fname, hl_attr(HLF_D));
+ msg_home_replace_attr(fname, HL_ATTR(HLF_D));
}
static void msg_home_replace_attr(char_u *fname, int attr)
@@ -1090,16 +1190,16 @@ char_u *msg_outtrans_one(char_u *p, int attr)
msg_outtrans_len_attr(p, l, attr);
return p + l;
}
- msg_puts_attr(transchar_byte(*p), attr);
+ msg_puts_attr((const char *)transchar_byte(*p), attr);
return p + 1;
}
int msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
{
int retval = 0;
- char_u *str = msgstr;
- char_u *plain_start = msgstr;
- char_u *s;
+ const char *str = (const char *)msgstr;
+ const char *plain_start = (const char *)msgstr;
+ char_u *s;
int mb_l;
int c;
@@ -1109,60 +1209,59 @@ int msg_outtrans_len_attr(char_u *msgstr, int len, int attr)
attr &= ~MSG_HIST;
}
- /* If the string starts with a composing character first draw a space on
- * which the composing char can be drawn. */
- if (enc_utf8 && utf_iscomposing(utf_ptr2char(msgstr)))
- msg_puts_attr((char_u *)" ", attr);
+ // If the string starts with a composing character first draw a space on
+ // which the composing char can be drawn.
+ if (enc_utf8 && utf_iscomposing(utf_ptr2char(msgstr))) {
+ msg_puts_attr(" ", attr);
+ }
/*
* Go over the string. Special characters are translated and printed.
* Normal characters are printed several at a time.
*/
while (--len >= 0) {
- if (enc_utf8)
- /* Don't include composing chars after the end. */
- mb_l = utfc_ptr2len_len(str, len + 1);
- else if (has_mbyte)
- mb_l = (*mb_ptr2len)(str);
- else
- mb_l = 1;
- if (has_mbyte && mb_l > 1) {
- c = (*mb_ptr2char)(str);
- if (vim_isprintc(c))
- /* printable multi-byte char: count the cells. */
- retval += (*mb_ptr2cells)(str);
- else {
- /* unprintable multi-byte char: print the printable chars so
- * far and the translation of the unprintable char. */
- if (str > plain_start)
- msg_puts_attr_len(plain_start, (int)(str - plain_start),
- attr);
+ // Don't include composing chars after the end.
+ mb_l = utfc_ptr2len_len((char_u *)str, len + 1);
+ if (mb_l > 1) {
+ c = utf_ptr2char((char_u *)str);
+ if (vim_isprintc(c)) {
+ // Printable multi-byte char: count the cells.
+ retval += utf_ptr2cells((char_u *)str);
+ } else {
+ // Unprintable multi-byte char: print the printable chars so
+ // far and the translation of the unprintable char.
+ if (str > plain_start) {
+ msg_puts_attr_len(plain_start, str - plain_start, attr);
+ }
plain_start = str + mb_l;
- msg_puts_attr(transchar(c), attr == 0 ? hl_attr(HLF_8) : attr);
+ msg_puts_attr((const char *)transchar(c),
+ (attr == 0 ? HL_ATTR(HLF_8) : attr));
retval += char2cells(c);
}
len -= mb_l - 1;
str += mb_l;
} else {
- s = transchar_byte(*str);
+ s = transchar_byte((uint8_t)(*str));
if (s[1] != NUL) {
- /* unprintable char: print the printable chars so far and the
- * translation of the unprintable char. */
- if (str > plain_start)
- msg_puts_attr_len(plain_start, (int)(str - plain_start),
- attr);
+ // Unprintable char: print the printable chars so far and the
+ // translation of the unprintable char.
+ if (str > plain_start) {
+ msg_puts_attr_len(plain_start, str - plain_start, attr);
+ }
plain_start = str + 1;
- msg_puts_attr(s, attr == 0 ? hl_attr(HLF_8) : attr);
+ msg_puts_attr((const char *)s, attr == 0 ? HL_ATTR(HLF_8) : attr);
retval += (int)STRLEN(s);
- } else
- ++retval;
- ++str;
+ } else {
+ retval++;
+ }
+ str++;
}
}
- if (str > plain_start)
- /* print the printable chars at the end */
- msg_puts_attr_len(plain_start, (int)(str - plain_start), attr);
+ if (str > plain_start) {
+ // Print the printable chars at the end.
+ msg_puts_attr_len(plain_start, str - plain_start, attr);
+ }
return retval;
}
@@ -1183,152 +1282,165 @@ void msg_make(char_u *arg)
}
}
-/*
- * Output the string 'str' upto a NUL character.
- * Return the number of characters it takes on the screen.
- *
- * If K_SPECIAL is encountered, then it is taken in conjunction with the
- * following character and shown as <F1>, <S-Up> etc. Any other character
- * which is not printable shown in <> form.
- * If 'from' is TRUE (lhs of a mapping), a space is shown as <Space>.
- * If a character is displayed in one of these special ways, is also
- * highlighted (its highlight name is '8' in the p_hl variable).
- * Otherwise characters are not highlighted.
- * This function is used to show mappings, where we want to see how to type
- * the character/string -- webb
- */
-int
-msg_outtrans_special (
- char_u *strstart,
- int from /* TRUE for lhs of a mapping */
+/// Output the string 'str' upto a NUL character.
+/// Return the number of characters it takes on the screen.
+///
+/// If K_SPECIAL is encountered, then it is taken in conjunction with the
+/// following character and shown as <F1>, <S-Up> etc. Any other character
+/// which is not printable shown in <> form.
+/// If 'from' is TRUE (lhs of a mapping), a space is shown as <Space>.
+/// If a character is displayed in one of these special ways, is also
+/// highlighted (its highlight name is '8' in the p_hl variable).
+/// Otherwise characters are not highlighted.
+/// This function is used to show mappings, where we want to see how to type
+/// the character/string -- webb
+int msg_outtrans_special(
+ const char_u *strstart,
+ int from ///< true for LHS of a mapping
)
{
- char_u *str = strstart;
+ if (strstart == NULL) {
+ return 0; // Do nothing.
+ }
+ const char_u *str = strstart;
int retval = 0;
- char_u *string;
- int attr;
- int len;
+ int attr = HL_ATTR(HLF_8);
- attr = hl_attr(HLF_8);
while (*str != NUL) {
- /* Leading and trailing spaces need to be displayed in <> form. */
+ const char *string;
+ // Leading and trailing spaces need to be displayed in <> form.
if ((str == strstart || str[1] == NUL) && *str == ' ') {
- string = (char_u *)"<Space>";
- ++str;
- } else
- string = str2special(&str, from);
- len = vim_strsize(string);
- /* Highlight special keys */
- msg_puts_attr(string, len > 1
- && (*mb_ptr2len)(string) <= 1
- ? attr : 0);
+ string = "<Space>";
+ str++;
+ } else {
+ string = str2special((const char **)&str, from, false);
+ }
+ const int len = vim_strsize((char_u *)string);
+ // Highlight special keys
+ msg_puts_attr(string, (len > 1
+ && (*mb_ptr2len)((char_u *)string) <= 1
+ ? attr : 0));
retval += len;
}
return retval;
}
-/*
- * Return the lhs or rhs of a mapping, with the key codes turned into printable
- * strings, in an allocated string.
- */
-char_u *
-str2special_save (
- char_u *str,
- int is_lhs /* TRUE for lhs, FALSE for rhs */
-)
+/// Convert string, replacing key codes with printables
+///
+/// Used for lhs or rhs of mappings.
+///
+/// @param[in] str String to convert.
+/// @param[in] replace_spaces Convert spaces into `<Space>`, normally used fo
+/// lhs, but not rhs.
+/// @param[in] replace_lt Convert `<` into `<lt>`.
+///
+/// @return [allocated] Converted string.
+char *str2special_save(const char *const str, const bool replace_spaces,
+ const bool replace_lt)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
+ FUNC_ATTR_NONNULL_RET
{
garray_T ga;
- char_u *p = str;
-
ga_init(&ga, 1, 40);
- while (*p != NUL)
- ga_concat(&ga, str2special(&p, is_lhs));
+
+ const char *p = str;
+ while (*p != NUL) {
+ ga_concat(&ga, (const char_u *)str2special(&p, replace_spaces, replace_lt));
+ }
ga_append(&ga, NUL);
- return (char_u *)ga.ga_data;
+ return (char *)ga.ga_data;
}
-/*
- * Return the printable string for the key codes at "*sp".
- * Used for translating the lhs or rhs of a mapping to printable chars.
- * Advances "sp" to the next code.
- */
-char_u *
-str2special (
- char_u **sp,
- int from /* TRUE for lhs of mapping */
-)
-{
- int c;
- static char_u buf[7];
- char_u *str = *sp;
- int modifiers = 0;
- int special = FALSE;
-
- if (has_mbyte) {
- char_u *p;
-
- /* Try to un-escape a multi-byte character. Return the un-escaped
- * string if it is a multi-byte character. */
- p = mb_unescape(sp);
- if (p != NULL)
- return p;
+/// Convert character, replacing key with printable representation.
+///
+/// @param[in,out] sp String to convert. Is advanced to the next key code.
+/// @param[in] replace_spaces Convert spaces into <Space>, normally used for
+/// lhs, but not rhs.
+/// @param[in] replace_lt Convert `<` into `<lt>`.
+///
+/// @return Converted key code, in a static buffer. Buffer is always one and the
+/// same, so save converted string somewhere before running str2special
+/// for the second time.
+const char *str2special(const char **const sp, const bool replace_spaces,
+ const bool replace_lt)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
+{
+ static char buf[7];
+
+ // Try to un-escape a multi-byte character. Return the un-escaped
+ // string if it is a multi-byte character.
+ const char *const p = mb_unescape(sp);
+ if (p != NULL) {
+ return p;
}
- c = *str;
+ const char *str = *sp;
+ int c = (uint8_t)(*str);
+ int modifiers = 0;
+ bool special = false;
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
- if (str[1] == KS_MODIFIER) {
- modifiers = str[2];
+ if ((uint8_t)str[1] == KS_MODIFIER) {
+ modifiers = (uint8_t)str[2];
str += 3;
- c = *str;
+ c = (uint8_t)(*str);
}
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
- c = TO_SPECIAL(str[1], str[2]);
+ c = TO_SPECIAL((uint8_t)str[1], (uint8_t)str[2]);
str += 2;
- if (c == KS_ZERO) /* display <Nul> as ^@ or <Nul> */
- c = NUL;
}
- if (IS_SPECIAL(c) || modifiers) /* special key */
- special = TRUE;
+ if (IS_SPECIAL(c) || modifiers) { // Special key.
+ special = true;
+ }
}
- if (has_mbyte && !IS_SPECIAL(c)) {
- int len = (*mb_ptr2len)(str);
+ if (!IS_SPECIAL(c)) {
+ const int len = utf_ptr2len((const char_u *)str);
- /* For multi-byte characters check for an illegal byte. */
- if (has_mbyte && MB_BYTE2LEN(*str) > len) {
- transchar_nonprint(buf, c);
+ // Check for an illegal byte.
+ if (MB_BYTE2LEN((uint8_t)(*str)) > len) {
+ transchar_nonprint((char_u *)buf, c);
*sp = str + 1;
return buf;
}
- /* Since 'special' is TRUE the multi-byte character 'c' will be
- * processed by get_special_key_name() */
- c = (*mb_ptr2char)(str);
+ // Since 'special' is TRUE the multi-byte character 'c' will be
+ // processed by get_special_key_name().
+ c = utf_ptr2char((const char_u *)str);
*sp = str + len;
- } else
+ } else {
*sp = str + 1;
+ }
- /* Make unprintable characters in <> form, also <M-Space> and <Tab>.
- * Use <Space> only for lhs of a mapping. */
- if (special || char2cells(c) > 1 || (from && c == ' '))
- return get_special_key_name(c, modifiers);
- buf[0] = c;
+ // Make unprintable characters in <> form, also <M-Space> and <Tab>.
+ if (special
+ || char2cells(c) > 1
+ || (replace_spaces && c == ' ')
+ || (replace_lt && c == '<')) {
+ return (const char *)get_special_key_name(c, modifiers);
+ }
+ buf[0] = (char)c;
buf[1] = NUL;
return buf;
}
-/*
- * Translate a key sequence into special key names.
- */
-void str2specialbuf(char_u *sp, char_u *buf, int len)
+/// Convert string, replacing key codes with printables
+///
+/// @param[in] str String to convert.
+/// @param[out] buf Buffer to save results to.
+/// @param[in] len Buffer length.
+void str2specialbuf(const char *sp, char *buf, size_t len)
+ FUNC_ATTR_NONNULL_ALL
{
- char_u *s;
-
- *buf = NUL;
while (*sp) {
- s = str2special(&sp, FALSE);
- if ((int)(STRLEN(s) + STRLEN(buf)) < len)
- STRCAT(buf, s);
+ const char *s = str2special(&sp, false, false);
+ const size_t s_len = strlen(s);
+ if (len <= s_len) {
+ break;
+ }
+ memcpy(buf, s, s_len);
+ buf += s_len;
+ len -= s_len;
}
+ *buf = NUL;
}
/*
@@ -1345,7 +1457,6 @@ void msg_prt_line(char_u *s, int list)
int attr = 0;
char_u *trail = NULL;
int l;
- char_u buf[MB_MAXBYTES + 1];
if (curwin->w_p_list)
list = TRUE;
@@ -1364,17 +1475,20 @@ void msg_prt_line(char_u *s, int list)
while (!got_int) {
if (n_extra > 0) {
- --n_extra;
- if (c_extra)
+ n_extra--;
+ if (c_extra) {
c = c_extra;
- else
+ } else {
+ assert(p_extra != NULL);
c = *p_extra++;
- } else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1) {
- col += (*mb_ptr2cells)(s);
+ }
+ } else if ((l = utfc_ptr2len(s)) > 1) {
+ col += utf_ptr2cells(s);
+ char buf[MB_MAXBYTES + 1];
if (lcs_nbsp != NUL && list
- && (mb_ptr2char(s) == 160 || mb_ptr2char(s) == 0x202f)) {
- mb_char2bytes(lcs_nbsp, buf);
- buf[(*mb_ptr2len)(buf)] = NUL;
+ && (utf_ptr2char(s) == 160 || utf_ptr2char(s) == 0x202f)) {
+ utf_char2bytes(lcs_nbsp, (char_u *)buf);
+ buf[utfc_ptr2len((char_u *)buf)] = NUL;
} else {
memmove(buf, s, (size_t)l);
buf[l] = NUL;
@@ -1394,18 +1508,18 @@ void msg_prt_line(char_u *s, int list)
} else {
c = lcs_tab1;
c_extra = lcs_tab2;
- attr = hl_attr(HLF_8);
+ attr = HL_ATTR(HLF_8);
}
} else if (c == 160 && list && lcs_nbsp != NUL) {
c = lcs_nbsp;
- attr = hl_attr(HLF_8);
+ attr = HL_ATTR(HLF_8);
} else if (c == NUL && list && lcs_eol != NUL) {
p_extra = (char_u *)"";
c_extra = NUL;
n_extra = 1;
c = lcs_eol;
- attr = hl_attr(HLF_AT);
- --s;
+ attr = HL_ATTR(HLF_AT);
+ s--;
} else if (c != NUL && (n = byte2cells(c)) > 1) {
n_extra = n - 1;
p_extra = transchar_byte(c);
@@ -1413,13 +1527,13 @@ void msg_prt_line(char_u *s, int list)
c = *p_extra++;
/* Use special coloring to be able to distinguish <hex> from
* the same in plain text. */
- attr = hl_attr(HLF_8);
+ attr = HL_ATTR(HLF_8);
} else if (c == ' ' && trail != NULL && s > trail) {
c = lcs_trail;
- attr = hl_attr(HLF_8);
+ attr = HL_ATTR(HLF_8);
} else if (c == ' ' && list && lcs_space != NUL) {
c = lcs_space;
- attr = hl_attr(HLF_8);
+ attr = HL_ATTR(HLF_8);
}
}
@@ -1432,25 +1546,22 @@ void msg_prt_line(char_u *s, int list)
msg_clr_eos();
}
-/*
- * Use screen_puts() to output one multi-byte character.
- * Return the pointer "s" advanced to the next character.
- */
+// Use grid_puts() to output one multi-byte character.
+// Return the pointer "s" advanced to the next character.
static char_u *screen_puts_mbyte(char_u *s, int l, int attr)
{
int cw;
- msg_didout = TRUE; /* remember that line is not empty */
- cw = (*mb_ptr2cells)(s);
- if (cw > 1 && (
- cmdmsg_rl ? msg_col <= 1 :
- msg_col == Columns - 1)) {
- /* Doesn't fit, print a highlighted '>' to fill it up. */
- msg_screen_putchar('>', hl_attr(HLF_AT));
+ msg_didout = true; // remember that line is not empty
+ cw = utf_ptr2cells(s);
+ if (cw > 1
+ && (cmdmsg_rl ? msg_col <= 1 : msg_col == Columns - 1)) {
+ // Doesn't fit, print a highlighted '>' to fill it up.
+ msg_screen_putchar('>', HL_ATTR(HLF_AT));
return s;
}
- screen_puts_len(s, l, msg_row, msg_col, attr);
+ grid_puts_len(&default_grid, s, l, msg_row, msg_col, attr);
if (cmdmsg_rl) {
msg_col -= cw;
if (msg_col == 0) {
@@ -1471,14 +1582,14 @@ static char_u *screen_puts_mbyte(char_u *s, int l, int attr)
* Output a string to the screen at position msg_row, msg_col.
* Update msg_row and msg_col for the next message.
*/
-void msg_puts(char_u *s)
+void msg_puts(const char *s)
{
msg_puts_attr(s, 0);
}
-void msg_puts_title(char_u *s)
+void msg_puts_title(const char *s)
{
- msg_puts_attr(s, hl_attr(HLF_T));
+ msg_puts_attr(s, HL_ATTR(HLF_T));
}
/*
@@ -1500,7 +1611,7 @@ void msg_puts_long_len_attr(char_u *longstr, int len, int attr)
if (len > room && room >= 20) {
slen = (room - 3) / 2;
msg_outtrans_len_attr(longstr, slen, attr);
- msg_puts_attr((char_u *)"...", hl_attr(HLF_8));
+ msg_puts_attr("...", HL_ATTR(HLF_8));
}
msg_outtrans_len_attr(longstr + len - slen, slen, attr);
}
@@ -1508,18 +1619,22 @@ void msg_puts_long_len_attr(char_u *longstr, int len, int attr)
/*
* Basic function for writing a message with highlight attributes.
*/
-void msg_puts_attr(char_u *s, int attr)
+void msg_puts_attr(const char *const s, const int attr)
{
msg_puts_attr_len(s, -1, attr);
}
-/// Like msg_puts_attr(), but with a maximum length "maxlen" (in bytes).
-/// When "maxlen" is -1 there is no maximum length.
-/// When "maxlen" is >= 0 the message is not put in the history.
-static void msg_puts_attr_len(char_u *str, int maxlen, int attr)
+/// Write a message with highlight attributes
+///
+/// @param[in] str NUL-terminated message string.
+/// @param[in] len Length of the string or -1.
+/// @param[in] attr Highlight attribute.
+void msg_puts_attr_len(const char *const str, const ptrdiff_t len, int attr)
+ FUNC_ATTR_NONNULL_ALL
{
+ assert(len < 0 || memchr(str, 0, len) == NULL);
// If redirection is on, also write to the redirection file.
- redir_write(str, maxlen);
+ redir_write(str, len);
// Don't print anything when using ":silent cmd".
if (msg_silent != 0) {
@@ -1527,8 +1642,8 @@ static void msg_puts_attr_len(char_u *str, int maxlen, int attr)
}
// if MSG_HIST flag set, add message to history
- if ((attr & MSG_HIST) && maxlen < 0) {
- add_msg_hist(str, -1, attr);
+ if (attr & MSG_HIST) {
+ add_msg_hist(str, (int)len, attr);
attr &= ~MSG_HIST;
}
@@ -1547,24 +1662,46 @@ static void msg_puts_attr_len(char_u *str, int maxlen, int attr)
// different, e.g. for Win32 console) or we just don't know where the
// cursor is.
if (msg_use_printf()) {
- msg_puts_printf((char *)str, maxlen);
+ msg_puts_printf(str, len);
} else {
- msg_puts_display(str, maxlen, attr, false);
+ msg_puts_display((const char_u *)str, len, attr, false);
}
}
+/// Print a formatted message
+///
+/// Message printed is limited by #IOSIZE. Must not be used from inside
+/// msg_puts_attr().
+///
+/// @param[in] attr Highlight attributes.
+/// @param[in] fmt Format string.
+void msg_printf_attr(const int attr, const char *const fmt, ...)
+ FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PRINTF(2, 3)
+{
+ static char msgbuf[IOSIZE];
+
+ va_list ap;
+ va_start(ap, fmt);
+ const size_t len = vim_vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap, NULL);
+ va_end(ap);
+
+ msg_scroll = true;
+ msg_puts_attr_len(msgbuf, (ptrdiff_t)len, attr);
+}
+
/*
* The display part of msg_puts_attr_len().
* May be called recursively to display scroll-back text.
*/
-static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
+static void msg_puts_display(const char_u *str, int maxlen, int attr,
+ int recurse)
{
- char_u *s = str;
- char_u *t_s = str; /* string from "t_s" to "s" is still todo */
- int t_col = 0; /* screen cells todo, 0 when "t_s" not used */
+ const char_u *s = str;
+ const char_u *t_s = str; // String from "t_s" to "s" is still todo.
+ int t_col = 0; // Screen cells todo, 0 when "t_s" not used.
int l;
int cw;
- char_u *sb_str = str;
+ const char_u *sb_str = str;
int sb_col = msg_col;
int wrap;
int did_last_char;
@@ -1578,14 +1715,12 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
&& (*s == '\n' || (cmdmsg_rl
? (msg_col <= 1
|| (*s == TAB && msg_col <= 7)
- || (has_mbyte
- && (*mb_ptr2cells)(s) > 1
+ || (utf_ptr2cells(s) > 1
&& msg_col <= 2))
: (msg_col + t_col >= Columns - 1
|| (*s == TAB
&& msg_col + t_col >= ((Columns - 1) & ~7))
- || (has_mbyte
- && (*mb_ptr2cells)(s) > 1
+ || (utf_ptr2cells(s) > 1
&& msg_col + t_col >= Columns - 2))))) {
// The screen is scrolled up when at the last row (some terminals
// scroll automatically, some don't. To avoid problems we scroll
@@ -1606,34 +1741,31 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
if (msg_col >= Columns) /* can happen after screen resize */
msg_col = Columns - 1;
- /* Display char in last column before showing more-prompt. */
- if (*s >= ' '
- && !cmdmsg_rl
- ) {
- if (has_mbyte) {
- if (enc_utf8 && maxlen >= 0)
- /* avoid including composing chars after the end */
- l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
- else
- l = (*mb_ptr2len)(s);
- s = screen_puts_mbyte(s, l, attr);
- } else
- msg_screen_putchar(*s++, attr);
- did_last_char = TRUE;
- } else
- did_last_char = FALSE;
-
- if (p_more)
- /* store text for scrolling back */
- store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
+ // Display char in last column before showing more-prompt.
+ if (*s >= ' ' && !cmdmsg_rl) {
+ if (maxlen >= 0) {
+ // Avoid including composing chars after the end.
+ l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
+ } else {
+ l = utfc_ptr2len(s);
+ }
+ s = screen_puts_mbyte((char_u *)s, l, attr);
+ did_last_char = true;
+ } else {
+ did_last_char = false;
+ }
+
+ if (p_more) {
+ // Store text for scrolling back.
+ store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true);
+ }
inc_msg_scrolled();
- need_wait_return = TRUE; /* may need wait_return in main() */
- if (must_redraw < VALID)
- must_redraw = VALID;
- redraw_cmdline = TRUE;
- if (cmdline_row > 0 && !exmode_active)
- --cmdline_row;
+ need_wait_return = true; // may need wait_return in main()
+ redraw_cmdline = true;
+ if (cmdline_row > 0 && !exmode_active) {
+ cmdline_row--;
+ }
/*
* If screen is completely filled and 'more' is set then wait
@@ -1657,17 +1789,19 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
wrap = *s == '\n'
|| msg_col + t_col >= Columns
- || (has_mbyte && (*mb_ptr2cells)(s) > 1
+ || (utf_ptr2cells(s) > 1
&& msg_col + t_col >= Columns - 1)
;
if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
- || *s == '\t' || *s == BELL))
- /* output any postponed text */
+ || *s == '\t' || *s == BELL)) {
+ // Output any postponed text.
t_puts(&t_col, t_s, s, attr);
+ }
- if (wrap && p_more && !recurse)
- /* store text for scrolling back */
- store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
+ if (wrap && p_more && !recurse) {
+ // Store text for scrolling back.
+ store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true);
+ }
if (*s == '\n') { /* go to next line */
msg_didout = FALSE; /* remember that line is empty */
@@ -1688,24 +1822,20 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
} while (msg_col & 7);
} else if (*s == BELL) { // beep (from ":sh")
vim_beep(BO_SH);
- } else {
- if (has_mbyte) {
- cw = (*mb_ptr2cells)(s);
- if (enc_utf8 && maxlen >= 0)
- /* avoid including composing chars after the end */
- l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
- else
- l = (*mb_ptr2len)(s);
+ } else if (*s >= 0x20) { // printable char
+ cw = utf_ptr2cells(s);
+ if (maxlen >= 0) {
+ // avoid including composing chars after the end
+ l = utfc_ptr2len_len(s, (int)((str + maxlen) - s));
} else {
- cw = 1;
- l = 1;
+ l = utfc_ptr2len(s);
}
// When drawing from right to left or when a double-wide character
// doesn't fit, draw a single character here. Otherwise collect
// characters and draw them all at once later.
if (cmdmsg_rl || (cw > 1 && msg_col + t_col >= Columns - 1)) {
if (l > 1) {
- s = screen_puts_mbyte(s, l, attr) - 1;
+ s = screen_puts_mbyte((char_u *)s, l, attr) - 1;
} else {
msg_screen_putchar(*s, attr);
}
@@ -1720,22 +1850,56 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse)
++s;
}
- /* output any postponed text */
- if (t_col > 0)
+ // Output any postponed text.
+ if (t_col > 0) {
t_puts(&t_col, t_s, s, attr);
- if (p_more && !recurse)
- store_sb_text(&sb_str, s, attr, &sb_col, FALSE);
+ }
+ if (p_more && !recurse) {
+ store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, false);
+ }
msg_check();
}
+/// Return true when ":filter pattern" was used and "msg" does not match
+/// "pattern".
+bool message_filtered(char_u *msg)
+{
+ if (cmdmod.filter_regmatch.regprog == NULL) {
+ return false;
+ }
+
+ bool match = vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0);
+ return cmdmod.filter_force ? match : !match;
+}
+
+/// including horizontal separator
+int msg_scrollsize(void)
+{
+ return msg_scrolled + p_ch + 1;
+}
+
/*
* Scroll the screen up one line for displaying the next message line.
*/
static void msg_scroll_up(void)
{
- /* scrolling up always works */
- screen_del_lines(0, 0, 1, (int)Rows, NULL);
+ if (msg_scrolled == 0) {
+ ui_call_win_scroll_over_start();
+ }
+ if (dy_flags & DY_MSGSEP) {
+ if (msg_scrolled == 0) {
+ grid_fill(&default_grid, Rows-p_ch-1, Rows-p_ch, 0, (int)Columns,
+ fill_msgsep, fill_msgsep, HL_ATTR(HLF_MSGSEP));
+ }
+ int nscroll = MIN(msg_scrollsize()+1, Rows);
+ grid_del_lines(&default_grid, Rows-nscroll, 1, Rows, 0, Columns);
+ } else {
+ grid_del_lines(&default_grid, 0, 1, (int)Rows, 0, Columns);
+ }
+ // TODO(bfredl): when msgsep display is properly batched, this fill should be
+ // eliminated.
+ grid_fill(&default_grid, Rows-1, Rows, 0, (int)Columns, ' ', ' ', 0);
}
/*
@@ -1762,30 +1926,38 @@ static void inc_msg_scrolled(void)
xfree(tofree);
}
msg_scrolled++;
+ if (must_redraw < VALID) {
+ must_redraw = VALID;
+ }
}
-static msgchunk_T *last_msgchunk = NULL; /* last displayed text */
+static msgchunk_T *last_msgchunk = NULL; // last displayed text
+typedef enum {
+ SB_CLEAR_NONE = 0,
+ SB_CLEAR_ALL,
+ SB_CLEAR_CMDLINE_BUSY,
+ SB_CLEAR_CMDLINE_DONE
+} sb_clear_T;
-static int do_clear_sb_text = FALSE; /* clear text on next msg */
+// When to clear text on next msg.
+static sb_clear_T do_clear_sb_text = SB_CLEAR_NONE;
-/*
- * Store part of a printed message for displaying when scrolling back.
- */
-static void
-store_sb_text (
- char_u **sb_str, /* start of string */
- char_u *s, /* just after string */
+/// Store part of a printed message for displaying when scrolling back.
+static void store_sb_text(
+ char_u **sb_str, // start of string
+ char_u *s, // just after string
int attr,
int *sb_col,
- int finish /* line ends */
+ int finish // line ends
)
{
msgchunk_T *mp;
- if (do_clear_sb_text) {
- clear_sb_text();
- do_clear_sb_text = FALSE;
+ if (do_clear_sb_text == SB_CLEAR_ALL
+ || do_clear_sb_text == SB_CLEAR_CMDLINE_DONE) {
+ clear_sb_text(do_clear_sb_text == SB_CLEAR_ALL);
+ do_clear_sb_text = SB_CLEAR_NONE;
}
if (s > *sb_str) {
@@ -1817,21 +1989,43 @@ store_sb_text (
*/
void may_clear_sb_text(void)
{
- do_clear_sb_text = TRUE;
+ do_clear_sb_text = SB_CLEAR_ALL;
}
-/*
- * Clear any text remembered for scrolling back.
- * Called when redrawing the screen.
- */
-void clear_sb_text(void)
+/// Starting to edit the command line, do not clear messages now.
+void sb_text_start_cmdline(void)
+{
+ do_clear_sb_text = SB_CLEAR_CMDLINE_BUSY;
+ msg_sb_eol();
+}
+
+/// Ending to edit the command line. Clear old lines but the last one later.
+void sb_text_end_cmdline(void)
+{
+ do_clear_sb_text = SB_CLEAR_CMDLINE_DONE;
+}
+
+/// Clear any text remembered for scrolling back.
+/// When "all" is FALSE keep the last line.
+/// Called when redrawing the screen.
+void clear_sb_text(int all)
{
msgchunk_T *mp;
+ msgchunk_T **lastp;
- while (last_msgchunk != NULL) {
- mp = last_msgchunk->sb_prev;
- xfree(last_msgchunk);
- last_msgchunk = mp;
+ if (all) {
+ lastp = &last_msgchunk;
+ } else {
+ if (last_msgchunk == NULL) {
+ return;
+ }
+ lastp = &last_msgchunk->sb_prev;
+ }
+
+ while (*lastp != NULL) {
+ mp = (*lastp)->sb_prev;
+ xfree(*lastp);
+ *lastp = mp;
}
}
@@ -1900,11 +2094,12 @@ static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp)
/*
* Output any postponed text for msg_puts_attr_len().
*/
-static void t_puts(int *t_col, char_u *t_s, char_u *s, int attr)
+static void t_puts(int *t_col, const char_u *t_s, const char_u *s, int attr)
{
- /* output postponed text */
- msg_didout = TRUE; /* remember that line is not empty */
- screen_puts_len(t_s, (int)(s - t_s), msg_row, msg_col, attr);
+ // Output postponed text.
+ msg_didout = true; // Remember that line is not empty.
+ grid_puts_len(&default_grid, (char_u *)t_s, (int)(s - t_s), msg_row, msg_col,
+ attr);
msg_col += *t_col;
*t_col = 0;
/* If the string starts with a composing character don't increment the
@@ -1917,21 +2112,22 @@ static void t_puts(int *t_col, char_u *t_s, char_u *s, int attr)
}
}
-// Returns TRUE when messages should be printed to stdout/stderr, which
-// happens when no UIs are attached and nvim is not being embedded
+// Returns TRUE when messages should be printed to stdout/stderr:
+// - "batch mode" ("silent mode", -es/-Es)
+// - no UI and not embedded
int msg_use_printf(void)
{
return !embedded_mode && !ui_active();
}
/// Print a message when there is no valid screen.
-static void msg_puts_printf(char *str, int maxlen)
+static void msg_puts_printf(const char *str, const ptrdiff_t maxlen)
{
- char *s = str;
+ const char *s = str;
char buf[4];
char *p;
- while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) {
+ while ((maxlen < 0 || s - str < maxlen) && *s != NUL) {
if (!(silent_mode && p_verbose == 0)) {
// NL --> CR NL translation (for Unix, not for "--version")
p = &buf[0];
@@ -1986,9 +2182,10 @@ static int do_more_prompt(int typed_char)
int i;
// We get called recursively when a timer callback outputs a message. In
- // that case don't show another prompt. Also when at the hit-Enter prompt.
- if (entered || State == HITRETURN) {
- return false;
+ // that case don't show another prompt. Also when at the hit-Enter prompt
+ // and nothing was typed.
+ if (entered || (State == HITRETURN && typed_char == 0)) {
+ return false;
}
entered = true;
@@ -2069,8 +2266,8 @@ static int do_more_prompt(int typed_char)
skip_redraw = TRUE; /* skip redraw once */
need_wait_return = FALSE; /* don't wait in main() */
}
- /*FALLTHROUGH*/
- case 'q': /* quit */
+ FALLTHROUGH;
+ case 'q': // quit
case Ctrl_C:
case ESC:
if (confirm_msg_used) {
@@ -2117,9 +2314,11 @@ static int do_more_prompt(int typed_char)
mp_last = msg_sb_start(mp_last->sb_prev);
}
- if (toscroll == -1 && screen_ins_lines(0, 0, 1,
- (int)Rows, NULL) == OK) {
- /* display line at top */
+ if (toscroll == -1
+ && grid_ins_lines(&default_grid, 0, 1, (int)Rows,
+ 0, (int)Columns) == OK) {
+ grid_fill(&default_grid, 0, 1, 0, (int)Columns, ' ', ' ', 0);
+ // display line at top
(void)disp_sb_line(0, mp);
} else {
/* redisplay all lines */
@@ -2137,18 +2336,18 @@ static int do_more_prompt(int typed_char)
/* scroll up, display line at bottom */
msg_scroll_up();
inc_msg_scrolled();
- screen_fill((int)Rows - 2, (int)Rows - 1, 0,
- (int)Columns, ' ', ' ', 0);
+ grid_fill(&default_grid, (int)Rows - 2, (int)Rows - 1, 0,
+ (int)Columns, ' ', ' ', 0);
mp_last = disp_sb_line((int)Rows - 2, mp_last);
--toscroll;
}
}
if (toscroll <= 0) {
- /* displayed the requested text, more prompt again */
- screen_fill((int)Rows - 1, (int)Rows, 0,
- (int)Columns, ' ', ' ', 0);
- msg_moremsg(FALSE);
+ // displayed the requested text, more prompt again
+ grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0,
+ (int)Columns, ' ', ' ', 0);
+ msg_moremsg(false);
continue;
}
@@ -2159,8 +2358,9 @@ static int do_more_prompt(int typed_char)
break;
}
- /* clear the --more-- message */
- screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+ // clear the --more-- message
+ grid_fill(&default_grid, (int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ',
+ 0);
State = oldState;
setmouse();
if (quit_more) {
@@ -2188,10 +2388,9 @@ static int do_more_prompt(int typed_char)
* yet. When stderr can't be used, collect error messages until the GUI has
* started and they can be displayed in a message box.
*/
-void mch_errmsg(char *str)
+void mch_errmsg(const char *const str)
+ FUNC_ATTR_NONNULL_ALL
{
- int len;
-
#ifdef UNIX
/* On Unix use stderr if it's a tty.
* When not going to start the GUI also use stderr.
@@ -2205,14 +2404,13 @@ void mch_errmsg(char *str)
/* avoid a delay for a message that isn't there */
emsg_on_display = FALSE;
- len = (int)STRLEN(str) + 1;
+ const size_t len = strlen(str) + 1;
if (error_ga.ga_data == NULL) {
ga_set_growsize(&error_ga, 80);
error_ga.ga_itemsize = 1;
}
ga_grow(&error_ga, len);
- memmove((char_u *)error_ga.ga_data + error_ga.ga_len,
- (char_u *)str, len);
+ memmove(error_ga.ga_data + error_ga.ga_len, str, len);
#ifdef UNIX
/* remove CR characters, they are displayed */
{
@@ -2258,8 +2456,8 @@ void mch_msg(char *str)
*/
static void msg_screen_putchar(int c, int attr)
{
- msg_didout = TRUE; /* remember that line is not empty */
- screen_putchar(c, msg_row, msg_col, attr);
+ msg_didout = true; // remember that line is not empty
+ grid_putchar(&default_grid, c, msg_row, msg_col, attr);
if (cmdmsg_rl) {
if (--msg_col == 0) {
msg_col = Columns;
@@ -2278,12 +2476,13 @@ void msg_moremsg(int full)
int attr;
char_u *s = (char_u *)_("-- More --");
- attr = hl_attr(HLF_M);
- screen_puts(s, (int)Rows - 1, 0, attr);
- if (full)
- screen_puts((char_u *)
- _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "),
- (int)Rows - 1, vim_strsize(s), attr);
+ attr = HL_ATTR(HLF_M);
+ grid_puts(&default_grid, s, (int)Rows - 1, 0, attr);
+ if (full) {
+ grid_puts(&default_grid, (char_u *)
+ _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "),
+ (int)Rows - 1, vim_strsize(s), attr);
+ }
}
/*
@@ -2331,13 +2530,13 @@ void msg_clr_eos(void)
*/
void msg_clr_eos_force(void)
{
- if (cmdmsg_rl) {
- screen_fill(msg_row, msg_row + 1, 0, msg_col + 1, ' ', ' ', 0);
- screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
- } else {
- screen_fill(msg_row, msg_row + 1, msg_col, (int)Columns, ' ', ' ', 0);
- screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
- }
+ int msg_startcol = (cmdmsg_rl) ? 0 : msg_col;
+ int msg_endcol = (cmdmsg_rl) ? msg_col + 1 : (int)Columns;
+
+ grid_fill(&default_grid, msg_row, msg_row + 1, msg_startcol, msg_endcol, ' ',
+ ' ', 0);
+ grid_fill(&default_grid, msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ',
+ 0);
}
/*
@@ -2387,24 +2586,15 @@ void msg_check(void)
* May write a string to the redirection file.
* When "maxlen" is -1 write the whole string, otherwise up to "maxlen" bytes.
*/
-static void redir_write(char_u *str, int maxlen)
+static void redir_write(const char *const str, const ptrdiff_t maxlen)
{
- char_u *s = str;
+ const char_u *s = (char_u *)str;
static int cur_col = 0;
if (maxlen == 0) {
return;
}
- // Append output to capture().
- if (capture_ga) {
- size_t len = 0;
- while (str[len] && (maxlen < 0 ? 1 : (len < (size_t)maxlen))) {
- len++;
- }
- ga_concat_len(capture_ga, (const char *)str, len);
- }
-
/* Don't do anything for displaying prompts and the like. */
if (redir_off)
return;
@@ -2417,6 +2607,9 @@ static void redir_write(char_u *str, int maxlen)
/* If the string doesn't start with CR or NL, go to msg_col */
if (*s != '\n' && *s != '\r') {
while (cur_col < msg_col) {
+ if (capture_ga) {
+ ga_concat_len(capture_ga, " ", 1);
+ }
if (redir_reg) {
write_reg_contents(redir_reg, (char_u *)" ", 1, true);
} else if (redir_vname) {
@@ -2431,28 +2624,36 @@ static void redir_write(char_u *str, int maxlen)
}
}
+ size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen;
+ if (capture_ga) {
+ ga_concat_len(capture_ga, (const char *)str, len);
+ }
if (redir_reg) {
- size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen;
write_reg_contents(redir_reg, s, len, true);
}
if (redir_vname) {
- var_redir_str(s, maxlen);
+ var_redir_str((char_u *)s, maxlen);
}
- /* Write and adjust the current column. */
- while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) {
- if (!redir_reg && !redir_vname)
- if (redir_fd != NULL)
+ // Write and adjust the current column.
+ while (*s != NUL
+ && (maxlen < 0 || (int)(s - (const char_u *)str) < maxlen)) {
+ if (!redir_reg && !redir_vname && !capture_ga) {
+ if (redir_fd != NULL) {
putc(*s, redir_fd);
- if (verbose_fd != NULL)
+ }
+ }
+ if (verbose_fd != NULL) {
putc(*s, verbose_fd);
- if (*s == '\r' || *s == '\n')
+ }
+ if (*s == '\r' || *s == '\n') {
cur_col = 0;
- else if (*s == '\t')
+ } else if (*s == '\t') {
cur_col += (8 - cur_col % 8);
- else
- ++cur_col;
- ++s;
+ } else {
+ cur_col++;
+ }
+ s++;
}
if (msg_silent != 0) /* should update msg_col */
@@ -2463,8 +2664,7 @@ static void redir_write(char_u *str, int maxlen)
int redirecting(void)
{
return redir_fd != NULL || *p_vfile != NUL
- || redir_reg || redir_vname
- ;
+ || redir_reg || redir_vname || capture_ga != NULL;
}
/*
@@ -2559,19 +2759,27 @@ void give_warning(char_u *message, bool hl) FUNC_ATTR_NONNULL_ARG(1)
set_vim_var_string(VV_WARNINGMSG, (char *) message, -1);
xfree(keep_msg);
keep_msg = NULL;
- if (hl)
- keep_msg_attr = hl_attr(HLF_W);
- else
+ if (hl) {
+ keep_msg_attr = HL_ATTR(HLF_W);
+ } else {
keep_msg_attr = 0;
- if (msg_attr(message, keep_msg_attr) && msg_scrolled == 0)
+ }
+ if (msg_attr((const char *)message, keep_msg_attr) && msg_scrolled == 0) {
set_keep_msg(message, keep_msg_attr);
- msg_didout = FALSE; /* overwrite this message */
- msg_nowait = TRUE; /* don't wait for this message */
+ }
+ msg_didout = false; // Overwrite this message.
+ msg_nowait = true; // Don't wait for this message.
msg_col = 0;
--no_wait_return;
}
+void give_warning2(char_u *const message, char_u *const a1, bool hl)
+{
+ vim_snprintf((char *)IObuff, IOSIZE, (char *)message, a1);
+ give_warning(IObuff, hl);
+}
+
/*
* Advance msg cursor to column "col".
*/
@@ -2622,18 +2830,22 @@ do_dialog (
Ex command */
)
{
- int oldState;
int retval = 0;
char_u *hotkeys;
int c;
int i;
- /* Don't output anything in silent mode ("ex -s") */
- if (silent_mode)
- return dfltbutton; /* return default option */
+ if (silent_mode // No dialogs in silent mode ("ex -s")
+ || !ui_active() // Without a UI Nvim waits for input forever.
+ ) {
+ return dfltbutton; // return default option
+ }
- oldState = State;
+ int save_msg_silent = msg_silent;
+ int oldState = State;
+
+ msg_silent = 0; // If dialog prompts for input, user needs to see it! #8788
State = CONFIRM;
setmouse();
@@ -2666,17 +2878,15 @@ do_dialog (
break;
}
- /* Make the character lowercase, as chars in "hotkeys" are. */
- c = vim_tolower(c);
+ // Make the character lowercase, as chars in "hotkeys" are.
+ c = mb_tolower(c);
retval = 1;
- for (i = 0; hotkeys[i]; ++i) {
- if (has_mbyte) {
- if ((*mb_ptr2char)(hotkeys + i) == c)
- break;
- i += (*mb_ptr2len)(hotkeys + i) - 1;
- } else if (hotkeys[i] == c)
+ for (i = 0; hotkeys[i]; i++) {
+ if (utf_ptr2char(hotkeys + i) == c) {
break;
- ++retval;
+ }
+ i += utfc_ptr2len(hotkeys + i) - 1;
+ retval++;
}
if (hotkeys[i])
break;
@@ -2688,6 +2898,7 @@ do_dialog (
xfree(hotkeys);
+ msg_silent = save_msg_silent;
State = oldState;
setmouse();
--no_wait_return;
@@ -2708,25 +2919,13 @@ copy_char (
int lowercase /* make character lower case */
)
{
- int len;
- int c;
-
- if (has_mbyte) {
- if (lowercase) {
- c = vim_tolower((*mb_ptr2char)(from));
- return (*mb_char2bytes)(c, to);
- } else {
- len = (*mb_ptr2len)(from);
- memmove(to, from, (size_t)len);
- return len;
- }
- } else {
- if (lowercase)
- *to = (char_u)TOLOWER_LOC(*from);
- else
- *to = *from;
- return 1;
+ if (lowercase) {
+ int c = mb_tolower(utf_ptr2char(from));
+ return utf_char2bytes(c, to);
}
+ int len = utfc_ptr2len(from);
+ memmove(to, from, (size_t)len);
+ return len;
}
#define HAS_HOTKEY_LEN 30
@@ -2771,7 +2970,7 @@ static char_u * console_dialog_alloc(const char_u *message,
}
// Advance to the next character
- mb_ptr_adv(r);
+ MB_PTR_ADV(r);
}
len += (int)(STRLEN(message)
@@ -2889,7 +3088,7 @@ static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
}
// advance to the next character
- mb_ptr_adv(r);
+ MB_PTR_ADV(r);
}
*msgp++ = ':';
@@ -2902,11 +3101,12 @@ static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons,
*/
void display_confirm_msg(void)
{
- /* avoid that 'q' at the more prompt truncates the message here */
- ++confirm_msg_used;
- if (confirm_msg != NULL)
- msg_puts_attr(confirm_msg, hl_attr(HLF_M));
- --confirm_msg_used;
+ // Avoid that 'q' at the more prompt truncates the message here.
+ confirm_msg_used++;
+ if (confirm_msg != NULL) {
+ msg_puts_attr((const char *)confirm_msg, HL_ATTR(HLF_M));
+ }
+ confirm_msg_used--;
}
int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt)
@@ -2945,802 +3145,3 @@ int vim_dialog_yesnoallcancel(int type, char_u *title, char_u *message, int dflt
}
return VIM_CANCEL;
}
-
-
-
-static char *e_printf = N_("E766: Insufficient arguments for printf()");
-
-/*
- * Get number argument from "idxp" entry in "tvs". First entry is 1.
- */
-static long tv_nr(typval_T *tvs, int *idxp)
-{
- int idx = *idxp - 1;
- long n = 0;
- int err = FALSE;
-
- if (tvs[idx].v_type == VAR_UNKNOWN)
- EMSG(_(e_printf));
- else {
- ++*idxp;
- n = get_tv_number_chk(&tvs[idx], &err);
- if (err)
- n = 0;
- }
- return n;
-}
-
-/*
- * Get string argument from "idxp" entry in "tvs". First entry is 1.
- * Returns NULL for an error.
- */
-static char *tv_str(typval_T *tvs, int *idxp)
-{
- int idx = *idxp - 1;
- char *s = NULL;
-
- if (tvs[idx].v_type == VAR_UNKNOWN)
- EMSG(_(e_printf));
- else {
- ++*idxp;
- s = (char *)get_tv_string_chk(&tvs[idx]);
- }
- return s;
-}
-
-/*
- * Get float argument from "idxp" entry in "tvs". First entry is 1.
- */
-static double tv_float(typval_T *tvs, int *idxp)
-{
- int idx = *idxp - 1;
- double f = 0;
-
- if (tvs[idx].v_type == VAR_UNKNOWN)
- EMSG(_(e_printf));
- else {
- ++*idxp;
- if (tvs[idx].v_type == VAR_FLOAT)
- f = tvs[idx].vval.v_float;
- else if (tvs[idx].v_type == VAR_NUMBER)
- f = tvs[idx].vval.v_number;
- else
- EMSG(_("E807: Expected Float argument for printf()"));
- }
- return f;
-}
-
-/*
- * This code was included to provide a portable vsnprintf() and snprintf().
- * Some systems may provide their own, but we always use this one for
- * consistency.
- *
- * This code is based on snprintf.c - a portable implementation of snprintf
- * by Mark Martinec <mark.martinec@ijs.si>, Version 2.2, 2000-10-06.
- * Included with permission. It was heavily modified to fit in Vim.
- * The original code, including useful comments, can be found here:
- * http://www.ijs.si/software/snprintf/
- *
- * This snprintf() only supports the following conversion specifiers:
- * s, c, b, B, d, u, o, x, X, p (and synonyms: i, D, U, O - see below)
- * with flags: '-', '+', ' ', '0' and '#'.
- * An asterisk is supported for field width as well as precision.
- *
- * Limited support for floating point was added: 'f', 'e', 'E', 'g', 'G'.
- *
- * Length modifiers 'h' (short int) and 'l' (long int) are supported.
- * 'll' (long long int) is not supported.
- *
- * The locale is not used, the string is used as a byte string. This is only
- * relevant for double-byte encodings where the second byte may be '%'.
- *
- * It is permitted for "str_m" to be zero, and it is permitted to specify NULL
- * pointer for resulting string argument if "str_m" is zero (as per ISO C99).
- *
- * The return value is the number of characters which would be generated
- * for the given input, excluding the trailing NUL. If this value
- * is greater or equal to "str_m", not all characters from the result
- * have been stored in str, output bytes beyond the ("str_m"-1) -th character
- * are discarded. If "str_m" is greater than zero it is guaranteed
- * the resulting string will be NUL-terminated.
- */
-
-/*
- * When va_list is not supported we only define vim_snprintf().
- *
- * vim_vsnprintf() can be invoked with either "va_list" or a list of
- * "typval_T". When the latter is not used it must be NULL.
- */
-
-/* Like vim_vsnprintf() but append to the string. */
-int vim_snprintf_add(char *str, size_t str_m, char *fmt, ...)
-{
- va_list ap;
- int str_l;
- size_t len = STRLEN(str);
- size_t space;
-
- if (str_m <= len)
- space = 0;
- else
- space = str_m - len;
- va_start(ap, fmt);
- str_l = vim_vsnprintf(str + len, space, fmt, ap, NULL);
- va_end(ap);
- return str_l;
-}
-
-int vim_snprintf(char *str, size_t str_m, const char *fmt, ...)
-{
- va_list ap;
- int str_l;
-
- va_start(ap, fmt);
- str_l = vim_vsnprintf(str, str_m, fmt, ap, NULL);
- va_end(ap);
- return str_l;
-}
-
-int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap,
- typval_T *tvs)
-{
- size_t str_l = 0;
- bool str_avail = str_l < str_m;
- const char *p = fmt;
- int arg_idx = 1;
-
- if (!p) {
- p = "";
- }
- while (*p) {
- if (*p != '%') {
- // copy up to the next '%' or NUL without any changes
- size_t n = (size_t)(xstrchrnul(p + 1, '%') - p);
- if (str_avail) {
- size_t avail = str_m - str_l;
- memmove(str + str_l, p, MIN(n, avail));
- str_avail = n < avail;
- }
- p += n;
- assert(n <= SIZE_MAX - str_l);
- str_l += n;
- } else {
- size_t min_field_width = 0, precision = 0;
- int zero_padding = 0, precision_specified = 0, justify_left = 0;
- int alternate_form = 0, force_sign = 0;
-
- // if both ' ' and '+' flags appear, ' ' flag should be ignored
- int space_for_positive = 1;
-
- // allowed values: \0, h, l, 2 (for ll), z, L
- char length_modifier = '\0';
-
- // temporary buffer for simple numeric->string conversion
-# define TMP_LEN 350 // 1e308 seems reasonable as the maximum printable
- char tmp[TMP_LEN];
-
- // string address in case of string argument
- const char *str_arg;
-
- // natural field width of arg without padding and sign
- size_t str_arg_l;
-
- // unsigned char argument value (only defined for c conversion);
- // standard explicitly states the char argument for the c
- // conversion is unsigned
- unsigned char uchar_arg;
-
- // number of zeros to be inserted for numeric conversions as
- // required by the precision or minimal field width
- size_t number_of_zeros_to_pad = 0;
-
- // index into tmp where zero padding is to be inserted
- size_t zero_padding_insertion_ind = 0;
-
- // current conversion specifier character
- char fmt_spec = '\0';
-
- str_arg = NULL;
- p++; // skip '%'
-
- // parse flags
- while (*p == '0' || *p == '-' || *p == '+' || *p == ' '
- || *p == '#' || *p == '\'') {
- switch (*p) {
- case '0': zero_padding = 1; break;
- case '-': justify_left = 1; break;
- // if both '0' and '-' flags appear, '0' should be ignored
- case '+': force_sign = 1; space_for_positive = 0; break;
- case ' ': force_sign = 1; break;
- // if both ' ' and '+' flags appear, ' ' should be ignored
- case '#': alternate_form = 1; break;
- case '\'': break;
- }
- p++;
- }
-
- // parse field width
- if (*p == '*') {
- p++;
- int j = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- if (j >= 0) {
- min_field_width = j;
- } else {
- min_field_width = -j;
- justify_left = 1;
- }
- } else if (ascii_isdigit((int)(*p))) {
- // size_t could be wider than unsigned int; make sure we treat
- // argument like common implementations do
- unsigned int uj = *p++ - '0';
-
- while (ascii_isdigit((int)(*p))) {
- uj = 10 * uj + (unsigned int)(*p++ - '0');
- }
- min_field_width = uj;
- }
-
- // parse precision
- if (*p == '.') {
- p++;
- precision_specified = 1;
- if (*p == '*') {
- int j = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- p++;
- if (j >= 0) {
- precision = j;
- } else {
- precision_specified = 0;
- precision = 0;
- }
- } else if (ascii_isdigit((int)(*p))) {
- // size_t could be wider than unsigned int; make sure we
- // treat argument like common implementations do
- unsigned int uj = *p++ - '0';
-
- while (ascii_isdigit((int)(*p))) {
- uj = 10 * uj + (unsigned int)(*p++ - '0');
- }
- precision = uj;
- }
- }
-
- // parse 'h', 'l', 'll' and 'z' length modifiers
- if (*p == 'h' || *p == 'l' || *p == 'z') {
- length_modifier = *p;
- p++;
- if (length_modifier == 'l' && *p == 'l') { // ll, encoded as 2
- length_modifier = '2';
- p++;
- }
- }
-
- fmt_spec = *p;
-
- // common synonyms
- switch (fmt_spec) {
- case 'i': fmt_spec = 'd'; break;
- case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
- case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
- case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
- case 'F': fmt_spec = 'f'; break;
- default: break;
- }
-
- // get parameter value, do initial processing
- switch (fmt_spec) {
- // '%' and 'c' behave similar to 's' regarding flags and field widths
- case '%': case 'c': case 's': case 'S':
- str_arg_l = 1;
- switch (fmt_spec) {
- case '%':
- str_arg = p;
- break;
-
- case 'c': {
- int j = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- // standard demands unsigned char
- uchar_arg = (unsigned char)j;
- str_arg = (char *)&uchar_arg;
- break;
- }
-
- case 's':
- case 'S':
- str_arg = tvs ? tv_str(tvs, &arg_idx) : va_arg(ap, char *);
- if (!str_arg) {
- str_arg = "[NULL]";
- str_arg_l = 6;
- } else if (!precision_specified) {
- // make sure not to address string beyond the specified precision
- str_arg_l = strlen(str_arg);
- } else if (precision == 0) {
- // truncate string if necessary as requested by precision
- str_arg_l = 0;
- } else {
- // memchr on HP does not like n > 2^31
- // TODO(elmart): check if this still holds / is relevant
- str_arg_l = (size_t)((char *)xmemscan(str_arg,
- NUL,
- MIN(precision, 0x7fffffff))
- - str_arg);
- }
- if (fmt_spec == 'S') {
- if (min_field_width != 0)
- min_field_width += strlen(str_arg)
- - mb_string2cells((char_u *) str_arg);
- if (precision) {
- char_u *p1 = (char_u *)str_arg;
- for (size_t i = 0; i < precision && *p1; i++) {
- p1 += mb_ptr2len(p1);
- }
- str_arg_l = precision = p1 - (char_u *)str_arg;
- }
- }
- break;
-
- default:
- break;
- }
- break;
-
- case 'd':
- case 'u':
- case 'b': case 'B':
- case 'o':
- case 'x': case 'X':
- case 'p': {
- // u, b, B, o, x, X and p conversion specifiers imply
- // the value is unsigned; d implies a signed value
-
- // 0 if numeric argument is zero (or if pointer is NULL for 'p'),
- // +1 if greater than zero (or non NULL for 'p'),
- // -1 if negative (unsigned argument is never negative)
- int arg_sign = 0;
-
- // only defined for length modifier h, or for no length modifiers
- int int_arg = 0;
- unsigned int uint_arg = 0;
-
- // only defined for length modifier l
- long int long_arg = 0;
- unsigned long int ulong_arg = 0;
-
- // only defined for length modifier ll
- long long int long_long_arg = 0;
- unsigned long long int ulong_long_arg = 0;
-
- // only defined for length modifier z
- size_t size_t_arg = 0;
-
- // only defined for p conversion
- void *ptr_arg = NULL;
-
- if (fmt_spec == 'p') {
- length_modifier = '\0';
- ptr_arg = tvs ? (void *)tv_str(tvs, &arg_idx) : va_arg(ap, void *);
- if (ptr_arg) {
- arg_sign = 1;
- }
- } else if (fmt_spec == 'd') {
- // signed
- switch (length_modifier) {
- case '\0':
- case 'h':
- // char and short arguments are passed as int
- int_arg = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
- if (int_arg > 0) {
- arg_sign = 1;
- } else if (int_arg < 0) {
- arg_sign = -1;
- }
- break;
- case 'l':
- long_arg = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, long int);
- if (long_arg > 0) {
- arg_sign = 1;
- } else if (long_arg < 0) {
- arg_sign = -1;
- }
- break;
- case '2':
- long_long_arg = tvs ? tv_nr(tvs, &arg_idx)
- : va_arg(ap, long long int); // NOLINT (runtime/int)
- if (long_long_arg > 0) {
- arg_sign = 1;
- } else if (long_long_arg < 0) {
- arg_sign = -1;
- }
- break;
- }
- } else {
- // unsigned
- switch (length_modifier) {
- case '\0':
- case 'h':
- uint_arg = tvs ? (unsigned)tv_nr(tvs, &arg_idx)
- : va_arg(ap, unsigned int);
- if (uint_arg != 0) { arg_sign = 1; }
- break;
- case 'l':
- ulong_arg = tvs ? (unsigned long)tv_nr(tvs, &arg_idx)
- : va_arg(ap, unsigned long int);
- if (ulong_arg != 0) { arg_sign = 1; }
- break;
- case '2':
- ulong_long_arg = tvs
- ? (unsigned long long)tv_nr(tvs, &arg_idx) // NOLINT (runtime/int)
- : va_arg(ap, unsigned long long int); // NOLINT (runtime/int)
- if (ulong_long_arg) { arg_sign = 1; }
- break;
- case 'z':
- size_t_arg = tvs ? (size_t)tv_nr(tvs, &arg_idx)
- : va_arg(ap, size_t);
- if (size_t_arg) { arg_sign = 1; }
- break;
- }
- }
-
- str_arg = tmp;
- str_arg_l = 0;
-
- // For d, i, u, o, x, and X conversions, if precision is specified,
- // '0' flag should be ignored. This is so with Solaris 2.6, Digital UNIX
- // 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
- if (precision_specified) {
- zero_padding = 0;
- }
-
- if (fmt_spec == 'd') {
- if (force_sign && arg_sign >= 0) {
- tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
- }
- // leave negative numbers for sprintf to handle, to
- // avoid handling tricky cases like (short int)-32768
- } else if (alternate_form) {
- if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X'
- || fmt_spec == 'b' || fmt_spec == 'B')) {
- tmp[str_arg_l++] = '0';
- tmp[str_arg_l++] = fmt_spec;
- }
- // alternate form should have no effect for p * conversion, but ...
- }
-
- zero_padding_insertion_ind = str_arg_l;
- if (!precision_specified) {
- precision = 1; // default precision is 1
- }
- if (precision == 0 && arg_sign == 0) {
- // when zero value is formatted with an explicit precision 0,
- // resulting formatted string is empty (d, i, u, b, B, o, x, X, p)
- } else {
- char f[5];
- int f_l = 0;
-
- // construct a simple format string for sprintf
- f[f_l++] = '%';
- if (!length_modifier) {
- } else if (length_modifier == '2') {
- f[f_l++] = 'l';
- f[f_l++] = 'l';
- } else
- f[f_l++] = length_modifier;
- f[f_l++] = fmt_spec;
- f[f_l++] = '\0';
-
- if (fmt_spec == 'p')
- str_arg_l += sprintf(tmp + str_arg_l, f, ptr_arg);
- else if (fmt_spec == 'd') {
- // signed
- switch (length_modifier) {
- case '\0':
- case 'h': str_arg_l += sprintf(tmp + str_arg_l, f, int_arg);
- break;
- case 'l': str_arg_l += sprintf(tmp + str_arg_l, f, long_arg);
- break;
- case '2': str_arg_l += sprintf(tmp + str_arg_l, f, long_long_arg);
- break;
- }
- } else if (fmt_spec == 'b' || fmt_spec == 'B') {
- // binary
- size_t bits = 0;
- switch (length_modifier) {
- case '\0':
- case 'h': for (bits = sizeof(unsigned) * 8; bits > 0; bits--) {
- if ((uint_arg >> (bits - 1)) & 0x1) { break; } }
-
- while (bits > 0) {
- tmp[str_arg_l++] =
- ((uint_arg >> --bits) & 0x1) ? '1' : '0'; }
- break;
- case 'l': for (bits = sizeof(unsigned long) * 8; bits > 0; bits--) {
- if ((ulong_arg >> (bits - 1)) & 0x1) { break; } }
-
- while (bits > 0) {
- tmp[str_arg_l++] =
- ((ulong_arg >> --bits) & 0x1) ? '1' : '0'; }
- break;
- case '2': for (bits = sizeof(unsigned long long) * 8; // NOLINT (runtime/int)
- bits > 0; bits--) {
- if ((ulong_long_arg >> (bits - 1)) & 0x1) { break; } }
-
- while (bits > 0) {
- tmp[str_arg_l++] =
- ((ulong_long_arg >> --bits) & 0x1) ? '1' : '0'; }
- break;
- case 'z': for (bits = sizeof(size_t) * 8; bits > 0; bits--) {
- if ((size_t_arg >> (bits - 1)) & 0x1) { break; } }
-
- while (bits > 0) {
- tmp[str_arg_l++] =
- ((size_t_arg >> --bits) & 0x1) ? '1' : '0'; }
- break;
- }
- } else {
- // unsigned
- switch (length_modifier) {
- case '\0':
- case 'h': str_arg_l += sprintf(tmp + str_arg_l, f, uint_arg);
- break;
- case 'l': str_arg_l += sprintf(tmp + str_arg_l, f, ulong_arg);
- break;
- case '2': str_arg_l += sprintf(tmp + str_arg_l, f, ulong_long_arg);
- break;
- case 'z': str_arg_l += sprintf(tmp + str_arg_l, f, size_t_arg);
- break;
- }
- }
-
- // include the optional minus sign and possible "0x" in the region
- // before the zero padding insertion point
- if (zero_padding_insertion_ind < str_arg_l
- && tmp[zero_padding_insertion_ind] == '-')
- zero_padding_insertion_ind++;
- if (zero_padding_insertion_ind + 1 < str_arg_l
- && tmp[zero_padding_insertion_ind] == '0'
- && (tmp[zero_padding_insertion_ind + 1] == 'x'
- || tmp[zero_padding_insertion_ind + 1] == 'X'
- || tmp[zero_padding_insertion_ind + 1] == 'b'
- || tmp[zero_padding_insertion_ind + 1] == 'B'))
- zero_padding_insertion_ind += 2;
- }
-
- {
- size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
-
- if (alternate_form && fmt_spec == 'o'
- // unless zero is already the first character
- && !(zero_padding_insertion_ind < str_arg_l
- && tmp[zero_padding_insertion_ind] == '0')) {
- // assure leading zero for alternate-form octal numbers
- if (!precision_specified
- || precision < num_of_digits + 1) {
- // precision is increased to force the first character to be zero,
- // except if a zero value is formatted with an explicit precision
- // of zero
- precision = num_of_digits + 1;
- }
- }
- // zero padding to specified precision?
- if (num_of_digits < precision)
- number_of_zeros_to_pad = precision - num_of_digits;
- }
- // zero padding to specified minimal field width?
- if (!justify_left && zero_padding) {
- int n = (int)(min_field_width - (str_arg_l
- + number_of_zeros_to_pad));
- if (n > 0)
- number_of_zeros_to_pad += n;
- }
- break;
- }
-
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- {
- // floating point
- char format[40];
- int l;
- int remove_trailing_zeroes = false;
-
- double f = tvs ? tv_float(tvs, &arg_idx) : va_arg(ap, double);
- double abs_f = f < 0 ? -f : f;
-
- if (fmt_spec == 'g' || fmt_spec == 'G') {
- // can't use %g directly, cause it prints "1.0" as "1"
- if ((abs_f >= 0.001 && abs_f < 10000000.0) || abs_f == 0.0)
- fmt_spec = 'f';
- else
- fmt_spec = fmt_spec == 'g' ? 'e' : 'E';
- remove_trailing_zeroes = true;
- }
-
- if (fmt_spec == 'f' && abs_f > 1.0e307) {
- // avoid a buffer overflow
- strcpy(tmp, "inf");
- str_arg_l = 3;
- } else {
- format[0] = '%';
- l = 1;
- if (precision_specified) {
- size_t max_prec = TMP_LEN - 10;
-
- // make sure we don't get more digits than we have room for
- if (fmt_spec == 'f' && abs_f > 1.0)
- max_prec -= (size_t)log10(abs_f);
- if (precision > max_prec)
- precision = max_prec;
- l += sprintf(format + 1, ".%d", (int)precision);
- }
- format[l] = fmt_spec;
- format[l + 1] = NUL;
- str_arg_l = sprintf(tmp, format, f);
-
- if (remove_trailing_zeroes) {
- int i;
- char *tp;
-
- // using %g or %G: remove superfluous zeroes
- if (fmt_spec == 'f')
- tp = tmp + str_arg_l - 1;
- else {
- tp = (char *)vim_strchr((char_u *)tmp,
- fmt_spec == 'e' ? 'e' : 'E');
- if (tp) {
- // remove superfluous '+' and leading zeroes from exponent
- if (tp[1] == '+') {
- // change "1.0e+07" to "1.0e07"
- STRMOVE(tp + 1, tp + 2);
- --str_arg_l;
- }
- i = (tp[1] == '-') ? 2 : 1;
- while (tp[i] == '0') {
- // change "1.0e07" to "1.0e7"
- STRMOVE(tp + i, tp + i + 1);
- --str_arg_l;
- }
- --tp;
- }
- }
-
- if (tp != NULL && !precision_specified)
- // remove trailing zeroes, but keep the one just after a dot
- while (tp > tmp + 2 && *tp == '0' && tp[-1] != '.') {
- STRMOVE(tp, tp + 1);
- --tp;
- --str_arg_l;
- }
- } else {
- // be consistent: some printf("%e") use 1.0e+12 and some 1.0e+012;
- // remove one zero in the last case
- char *tp = (char *)vim_strchr((char_u *)tmp,
- fmt_spec == 'e' ? 'e' : 'E');
- if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0'
- && ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) {
- STRMOVE(tp + 2, tp + 3);
- --str_arg_l;
- }
- }
- }
- str_arg = tmp;
- break;
- }
-
- default:
- // unrecognized conversion specifier, keep format string as-is
- zero_padding = 0; // turn zero padding off for non-numeric conversion
- justify_left = 1;
- min_field_width = 0; // reset flags
-
- // discard the unrecognized conversion, just keep
- // the unrecognized conversion character
- str_arg = p;
- str_arg_l = 0;
- if (*p)
- str_arg_l++; // include invalid conversion specifier
- // unchanged if not at end-of-string
- break;
- }
-
- if (*p)
- p++; // step over the just processed conversion specifier
-
- // insert padding to the left as requested by min_field_width;
- // this does not include the zero padding in case of numerical conversions
- if (!justify_left) {
- assert(str_arg_l <= SIZE_MAX - number_of_zeros_to_pad);
- if (min_field_width > str_arg_l + number_of_zeros_to_pad) {
- // left padding with blank or zero
- size_t pn = min_field_width - (str_arg_l + number_of_zeros_to_pad);
- if (str_avail) {
- size_t avail = str_m - str_l;
- memset(str + str_l, zero_padding ? '0' : ' ', MIN(pn, avail));
- str_avail = pn < avail;
- }
- assert(pn <= SIZE_MAX - str_l);
- str_l += pn;
- }
- }
-
- // zero padding as requested by the precision or by the minimal
- // field width for numeric conversions required?
- if (number_of_zeros_to_pad == 0) {
- // will not copy first part of numeric right now,
- // force it to be copied later in its entirety
- zero_padding_insertion_ind = 0;
- } else {
- // insert first part of numerics (sign or '0x') before zero padding
- if (zero_padding_insertion_ind > 0) {
- size_t zn = zero_padding_insertion_ind;
- if (str_avail) {
- size_t avail = str_m - str_l;
- memmove(str + str_l, str_arg, MIN(zn, avail));
- str_avail = zn < avail;
- }
- assert(zn <= SIZE_MAX - str_l);
- str_l += zn;
- }
-
- // insert zero padding as requested by precision or min field width
- if (number_of_zeros_to_pad > 0) {
- size_t zn = number_of_zeros_to_pad;
- if (str_avail) {
- size_t avail = str_m - str_l;
- memset(str + str_l, '0', MIN(zn, avail));
- str_avail = zn < avail;
- }
- assert(zn <= SIZE_MAX - str_l);
- str_l += zn;
- }
- }
-
- // insert formatted string
- // (or as-is conversion specifier for unknown conversions)
- if (str_arg_l > zero_padding_insertion_ind) {
- size_t sn = str_arg_l - zero_padding_insertion_ind;
- if (str_avail) {
- size_t avail = str_m - str_l;
- memmove(str + str_l,
- str_arg + zero_padding_insertion_ind,
- MIN(sn, avail));
- str_avail = sn < avail;
- }
- assert(sn <= SIZE_MAX - str_l);
- str_l += sn;
- }
-
- // insert right padding
- if (justify_left) {
- assert(str_arg_l <= SIZE_MAX - number_of_zeros_to_pad);
- if (min_field_width > str_arg_l + number_of_zeros_to_pad) {
- // right blank padding to the field width
- size_t pn = min_field_width - (str_arg_l + number_of_zeros_to_pad);
- if (str_avail) {
- size_t avail = str_m - str_l;
- memset(str + str_l, ' ', MIN(pn, avail));
- str_avail = pn < avail;
- }
- assert(pn <= SIZE_MAX - str_l);
- str_l += pn;
- }
- }
- }
- }
-
- if (str_m > 0) {
- // make sure the string is nul-terminated even at the expense of
- // overwriting the last character (shouldn't happen, but just in case)
- str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0';
- }
-
- if (tvs && tvs[arg_idx - 1].v_type != VAR_UNKNOWN)
- EMSG(_("E767: Too many arguments to printf()"));
-
- // return the number of characters formatted (excluding trailing nul
- // character); that is, the number of characters that would have been
- // written to the buffer if it were large enough.
- return (int)str_l;
-}
diff --git a/src/nvim/message.h b/src/nvim/message.h
index d3a16fff93..82935a36a9 100644
--- a/src/nvim/message.h
+++ b/src/nvim/message.h
@@ -3,8 +3,9 @@
#include <stdbool.h>
#include <stdarg.h>
-#include "nvim/eval_defs.h" // for typval_T
-#include "nvim/ex_cmds_defs.h" // for exarg_T
+#include <stddef.h>
+
+#include "nvim/types.h"
/*
* Types of dialogs passed to do_dialog().
@@ -29,7 +30,7 @@
#define MSG(s) msg((char_u *)(s))
/// Show message highlighted according to the attr
-#define MSG_ATTR(s, attr) msg_attr((char_u *)(s), (attr))
+#define MSG_ATTR(s, attr) msg_attr((const char *)(s), (attr))
/// Display error message
///
@@ -48,14 +49,23 @@
/// Like #EMSG, but for messages with one "%" PRIu64 inside
#define EMSGU(s, n) emsgf((const char *) (s), (uint64_t)(n))
+/// Like #EMSG, but for internal messages
+#define IEMSG(s) iemsg((const char *)(s))
+
+/// Like #EMSG2, but for internal messages
+#define IEMSG2(s, p) iemsgf((const char *)(s), (p))
+
+/// Like #EMSGN, but for internal messages
+#define IEMSGN(s, n) iemsgf((const char *)(s), (int64_t)(n))
+
/// Display message at the recorded position
-#define MSG_PUTS(s) msg_puts((char_u *)(s))
+#define MSG_PUTS(s) msg_puts((const char *)(s))
/// Display message at the recorded position, highlighted
-#define MSG_PUTS_ATTR(s, a) msg_puts_attr((char_u *)(s), (a))
+#define MSG_PUTS_ATTR(s, a) msg_puts_attr((const char *)(s), (a))
/// Like #MSG_PUTS, but highlight like title
-#define MSG_PUTS_TITLE(s) msg_puts_title((char_u *)(s))
+#define MSG_PUTS_TITLE(s) msg_puts_title((const char *)(s))
/// Like #MSG_PUTS, but if middle part of too long messages it will be replaced
#define MSG_PUTS_LONG(s) msg_puts_long_attr((char_u *)(s), 0)
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index d72d8e8513..a66ded13f1 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.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
+
/*
* misc1.c: functions that didn't seem to fit elsewhere
*/
@@ -25,13 +28,13 @@
#include "nvim/getchar.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
+#include "nvim/buffer_updates.h"
#include "nvim/main.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/mouse.h"
@@ -41,6 +44,7 @@
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
#include "nvim/ui.h"
@@ -48,9 +52,11 @@
#include "nvim/window.h"
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
+#include "nvim/os/signal.h"
#include "nvim/os/input.h"
#include "nvim/os/time.h"
#include "nvim/event/stream.h"
+#include "nvim/buffer.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "misc1.c.generated.h"
@@ -93,7 +99,7 @@ open_line (
colnr_T newcol = 0; // new cursor column
int newindent = 0; // auto-indent of the new line
bool trunc_line = false; // truncate current line afterwards
- bool retval = false; // return value, default is false
+ bool retval = false; // return value
int extra_len = 0; // length of p_extra string
int lead_len; // length of comment leader
char_u *lead_flags; // position in 'comments' for comment leader
@@ -102,7 +108,8 @@ open_line (
char_u *p;
char_u saved_char = NUL; // init for GCC
pos_T *pos;
- bool do_si = (!p_paste && curbuf->b_p_si && !curbuf->b_p_cin);
+ bool do_si = (!p_paste && curbuf->b_p_si && !curbuf->b_p_cin
+ && *curbuf->b_p_inde == NUL);
bool no_si = false; // reset did_si afterwards
int first_char = NUL; // init for GCC
int vreplace_mode;
@@ -159,8 +166,8 @@ open_line (
*p_extra = NUL;
}
- u_clearline(); /* cannot do "U" command when adding lines */
- did_si = FALSE;
+ u_clearline(); // cannot do "U" command when adding lines
+ did_si = false;
ai_col = 0;
/*
@@ -196,7 +203,7 @@ open_line (
char_u *ptr;
char_u last_char;
- pos_T old_cursor = curwin->w_cursor;
+ old_cursor = curwin->w_cursor;
ptr = saved_line;
if (flags & OPENLINE_DO_COM)
lead_len = get_leader_len(ptr, NULL, FALSE, TRUE);
@@ -280,8 +287,8 @@ open_line (
* checking for "if" and the like.
*/
if (last_char == '{') {
- did_si = TRUE; /* do indent */
- no_si = TRUE; /* don't delete it when '{' typed */
+ did_si = true; // do indent
+ no_si = true; // don't delete it when '{' typed
}
/*
* Look for "if" and the like, use 'cinwords'.
@@ -290,7 +297,7 @@ open_line (
*/
else if (last_char != ';' && last_char != '}'
&& cin_is_cinword(ptr))
- did_si = TRUE;
+ did_si = true;
}
} else { // dir == BACKWARD
// Skip preprocessor directives, unless they are
@@ -314,17 +321,19 @@ open_line (
}
}
p = skipwhite(ptr);
- if (*p == '}') /* if line starts with '}': do indent */
- did_si = TRUE;
- else /* can delete indent when '{' typed */
- can_si_back = TRUE;
+ if (*p == '}') { // if line starts with '}': do indent
+ did_si = true;
+ } else { // can delete indent when '{' typed
+ can_si_back = true;
+ }
}
curwin->w_cursor = old_cursor;
}
- if (do_si)
- can_si = TRUE;
+ if (do_si) {
+ can_si = true;
+ }
- did_ai = TRUE;
+ did_ai = true;
}
/*
@@ -525,7 +534,7 @@ open_line (
int l;
while (old_size < repl_size && p > leader) {
- mb_ptr_back(leader, p);
+ MB_PTR_BACK(leader, p);
old_size += ptr2cells(p);
}
l = lead_repl_len - (int)(endp - p);
@@ -540,7 +549,7 @@ open_line (
/* blank-out any other chars from the old leader. */
while (--p >= leader) {
- int l = mb_head_off(leader, p);
+ int l = utf_head_off(leader, p);
if (l > 1) {
p -= l;
@@ -566,7 +575,7 @@ open_line (
int i;
int l;
- for (i = 0; p[i] != NUL && i < lead_len; i += l) {
+ for (i = 0; i < lead_len && p[i] != NUL; i += l) {
l = (*mb_ptr2len)(p + i);
if (vim_strnsize(p, i + l) > repl_size)
break;
@@ -659,7 +668,7 @@ open_line (
}
}
- did_si = can_si = FALSE;
+ did_si = can_si = false;
} else if (comment_end != NULL) {
// We have finished a comment, so we don't use the leader.
// If this was a C-comment and 'ai' or 'si' is set do a normal
@@ -693,17 +702,17 @@ open_line (
replace_push(NUL); /* end of extra blanks */
if (curbuf->b_p_ai || (flags & OPENLINE_DELSPACES)) {
while ((*p_extra == ' ' || *p_extra == '\t')
- && (!enc_utf8
- || !utf_iscomposing(utf_ptr2char(p_extra + 1)))
- ) {
- if (REPLACE_NORMAL(State))
+ && !utf_iscomposing(utf_ptr2char(p_extra + 1))) {
+ if (REPLACE_NORMAL(State)) {
replace_push(*p_extra);
- ++p_extra;
- ++less_cols_off;
+ }
+ p_extra++;
+ less_cols_off++;
}
}
- if (*p_extra != NUL)
- did_ai = FALSE; /* append some text, don't truncate now */
+ if (*p_extra != NUL) {
+ did_ai = false; // append some text, don't truncate now
+ }
/* columns for marks adjusted for removed columns */
less_cols = (int)(p_extra - saved_line);
@@ -730,7 +739,7 @@ open_line (
}
STRCAT(leader, p_extra);
p_extra = leader;
- did_ai = TRUE; /* So truncating blanks works with comments */
+ did_ai = true; // So truncating blanks works with comments
less_cols -= lead_len;
} else
end_comment_pending = NUL; /* turns out there was no leader */
@@ -742,10 +751,15 @@ open_line (
if (ml_append(curwin->w_cursor.lnum, p_extra, (colnr_T)0, FALSE)
== FAIL)
goto theend;
- /* Postpone calling changed_lines(), because it would mess up folding
- * with markers. */
- mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L);
- did_append = TRUE;
+ // Postpone calling changed_lines(), because it would mess up folding
+ // with markers.
+ // Skip mark_adjust when adding a line after the last one, there can't
+ // be marks there. But still needed in diff mode.
+ if (curwin->w_cursor.lnum + 1 < curbuf->b_ml.ml_line_count
+ || curwin->w_p_diff) {
+ mark_adjust(curwin->w_cursor.lnum + 1, (linenr_T)MAXLNUM, 1L, 0L, false);
+ }
+ did_append = true;
} else {
/*
* In VREPLACE mode we are starting to replace the next line.
@@ -758,7 +772,7 @@ open_line (
(void)u_save_cursor(); /* errors are ignored! */
vr_lines_changed++;
}
- ml_replace(curwin->w_cursor.lnum, p_extra, TRUE);
+ ml_replace(curwin->w_cursor.lnum, p_extra, true);
changed_bytes(curwin->w_cursor.lnum, 0);
curwin->w_cursor.lnum--;
did_append = FALSE;
@@ -801,8 +815,9 @@ open_line (
}
}
newcol += curwin->w_cursor.col;
- if (no_si)
- did_si = FALSE;
+ if (no_si) {
+ did_si = false;
+ }
}
/*
@@ -817,17 +832,18 @@ open_line (
if (dir == FORWARD) {
if (trunc_line || (State & INSERT)) {
- /* truncate current line at cursor */
+ // truncate current line at cursor
saved_line[curwin->w_cursor.col] = NUL;
- /* Remove trailing white space, unless OPENLINE_KEEPTRAIL used. */
- if (trunc_line && !(flags & OPENLINE_KEEPTRAIL))
+ // Remove trailing white space, unless OPENLINE_KEEPTRAIL used.
+ if (trunc_line && !(flags & OPENLINE_KEEPTRAIL)) {
truncate_spaces(saved_line);
- ml_replace(curwin->w_cursor.lnum, saved_line, FALSE);
+ }
+ ml_replace(curwin->w_cursor.lnum, saved_line, false);
saved_line = NULL;
if (did_append) {
changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
- curwin->w_cursor.lnum + 1, 1L);
- did_append = FALSE;
+ curwin->w_cursor.lnum + 1, 1L, true);
+ did_append = false;
/* Move marks after the line break to the new line. */
if (flags & OPENLINE_MARKFIX)
@@ -844,8 +860,9 @@ open_line (
*/
curwin->w_cursor.lnum = old_cursor.lnum + 1;
}
- if (did_append)
- changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L);
+ if (did_append) {
+ changed_lines(curwin->w_cursor.lnum, 0, curwin->w_cursor.lnum, 1L, true);
+ }
curwin->w_cursor.col = newcol;
curwin->w_cursor.coladd = 0;
@@ -868,8 +885,7 @@ open_line (
&& curbuf->b_p_lisp
&& curbuf->b_p_ai) {
fixthisline(get_lisp_indent);
- p = get_cursor_line_ptr();
- ai_col = (colnr_T)(skipwhite(p) - p);
+ ai_col = (colnr_T)getwhitecols_curline();
}
/*
* May do indenting after opening a new line.
@@ -882,8 +898,7 @@ open_line (
? KEY_OPEN_FORW
: KEY_OPEN_BACK, ' ', linewhite(curwin->w_cursor.lnum))) {
do_c_expr_indent();
- p = get_cursor_line_ptr();
- ai_col = (colnr_T)(skipwhite(p) - p);
+ ai_col = (colnr_T)getwhitecols_curline();
}
if (vreplace_mode != 0)
State = vreplace_mode;
@@ -897,8 +912,8 @@ open_line (
/* Put new line in p_extra */
p_extra = vim_strsave(get_cursor_line_ptr());
- /* Put back original line */
- ml_replace(curwin->w_cursor.lnum, next_line, FALSE);
+ // Put back original line
+ ml_replace(curwin->w_cursor.lnum, next_line, false);
/* Insert new stuff into line again */
curwin->w_cursor.col = 0;
@@ -908,7 +923,7 @@ open_line (
next_line = NULL;
}
- retval = TRUE; /* success! */
+ retval = true; // success!
theend:
curbuf->b_p_pi = saved_pi;
xfree(saved_line);
@@ -1107,8 +1122,9 @@ int get_last_leader_offset(char_u *line, char_u **flags)
if (ascii_iswhite(string[0])) {
if (i == 0 || !ascii_iswhite(line[i - 1]))
continue;
- while (ascii_iswhite(string[0]))
- ++string;
+ while (ascii_iswhite(*string)) {
+ string++;
+ }
}
for (j = 0; string[j] != NUL && string[j] == line[i + j]; ++j)
/* do nothing */;
@@ -1124,6 +1140,19 @@ int get_last_leader_offset(char_u *line, char_u **flags)
continue;
}
+ if (vim_strchr(part_buf, COM_MIDDLE) != NULL) {
+ // For a middlepart comment, only consider it to match if
+ // everything before the current position in the line is
+ // whitespace. Otherwise we would think we are inside a
+ // comment if the middle part appears somewhere in the middle
+ // of the line. E.g. for C the "*" appears often.
+ for (j = 0; ascii_iswhite(line[j]) && j <= i; j++) {
+ }
+ if (j < i) {
+ continue;
+ }
+ }
+
/*
* We have found a match, stop searching.
*/
@@ -1191,16 +1220,15 @@ int get_last_leader_offset(char_u *line, char_u **flags)
/*
* Return the number of window lines occupied by buffer line "lnum".
*/
-int plines(linenr_T lnum)
+int plines(const linenr_T lnum)
{
- return plines_win(curwin, lnum, TRUE);
+ return plines_win(curwin, lnum, true);
}
-int
-plines_win (
- win_T *wp,
- linenr_T lnum,
- int winheight /* when TRUE limit to window height */
+int plines_win(
+ win_T *const wp,
+ const linenr_T lnum,
+ const bool winheight // when true limit to window height
)
{
/* Check for filler lines above this buffer line. When folded the result
@@ -1208,34 +1236,34 @@ plines_win (
return plines_win_nofill(wp, lnum, winheight) + diff_check_fill(wp, lnum);
}
-int plines_nofill(linenr_T lnum)
+int plines_nofill(const linenr_T lnum)
{
- return plines_win_nofill(curwin, lnum, TRUE);
+ return plines_win_nofill(curwin, lnum, true);
}
-int
-plines_win_nofill (
- win_T *wp,
- linenr_T lnum,
- int winheight /* when TRUE limit to window height */
+int plines_win_nofill(
+ win_T *const wp,
+ const linenr_T lnum,
+ const bool winheight // when true limit to window height
)
{
- int lines;
-
- if (!wp->w_p_wrap)
+ if (!wp->w_p_wrap) {
return 1;
+ }
- if (wp->w_width == 0)
+ if (wp->w_grid.Columns == 0) {
return 1;
+ }
- /* A folded lines is handled just like an empty line. */
- /* NOTE: Caller must handle lines that are MAYBE folded. */
- if (lineFolded(wp, lnum) == TRUE)
+ // A folded lines is handled just like an empty line.
+ if (lineFolded(wp, lnum)) {
return 1;
+ }
- lines = plines_win_nofold(wp, lnum);
- if (winheight > 0 && lines > wp->w_height)
- return wp->w_height;
+ const int lines = plines_win_nofold(wp, lnum);
+ if (winheight && lines > wp->w_grid.Rows) {
+ return wp->w_grid.Rows;
+ }
return lines;
}
@@ -1264,9 +1292,9 @@ int plines_win_nofold(win_T *wp, linenr_T lnum)
/*
* Add column offset for 'number', 'relativenumber' and 'foldcolumn'.
*/
- width = wp->w_width - win_col_off(wp);
- if (width <= 0) {
- return 32000; // bigger than the number of lines of the screen
+ width = wp->w_grid.Columns - win_col_off(wp);
+ if (width <= 0 || col > 32000) {
+ return 32000; // bigger than the number of screen columns
}
if (col <= (unsigned int)width) {
return 1;
@@ -1290,8 +1318,9 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column)
if (!wp->w_p_wrap)
return lines + 1;
- if (wp->w_width == 0)
+ if (wp->w_grid.Columns == 0) {
return lines + 1;
+ }
char_u *line = ml_get_buf(wp->w_buffer, lnum, false);
char_u *s = line;
@@ -1299,7 +1328,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column)
colnr_T col = 0;
while (*s != NUL && --column >= 0) {
col += win_lbr_chartabsize(wp, line, s, col, NULL);
- mb_ptr_adv(s);
+ MB_PTR_ADV(s);
}
// If *s is a TAB, and the TAB is not displayed as ^I, and we're not in
@@ -1312,7 +1341,7 @@ int plines_win_col(win_T *wp, linenr_T lnum, long column)
}
// Add column offset for 'number', 'relativenumber', 'foldcolumn', etc.
- int width = wp->w_width - win_col_off(wp);
+ int width = wp->w_grid.Columns - win_col_off(wp);
if (width <= 0) {
return 9999;
}
@@ -1335,11 +1364,12 @@ int plines_m_win(win_T *wp, linenr_T first, linenr_T last)
++count; /* count 1 for "+-- folded" line */
first += x;
} else {
- if (first == wp->w_topline)
- count += plines_win_nofill(wp, first, TRUE) + wp->w_topfill;
- else
- count += plines_win(wp, first, TRUE);
- ++first;
+ if (first == wp->w_topline) {
+ count += plines_win_nofill(wp, first, true) + wp->w_topfill;
+ } else {
+ count += plines_win(wp, first, true);
+ }
+ first++;
}
}
return count;
@@ -1384,7 +1414,7 @@ void ins_bytes_len(char_u *p, size_t len)
void ins_char(int c)
{
char_u buf[MB_MAXBYTES + 1];
- size_t n = (size_t)(*mb_char2bytes)(c, buf);
+ size_t n = (size_t)utf_char2bytes(c, buf);
// When "c" is 0x100, 0x200, etc. we don't want to insert a NUL byte.
// Happens for CTRL-Vu9900.
@@ -1401,7 +1431,6 @@ void ins_char_bytes(char_u *buf, size_t charlen)
coladvance_force(getviscol());
}
- int c = buf[0];
size_t col = (size_t)curwin->w_cursor.col;
linenr_T lnum = curwin->w_cursor.lnum;
char_u *oldp = ml_get(lnum);
@@ -1461,7 +1490,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
}
}
- char_u *newp = (char_u *) xmalloc((size_t)(linelen + newlen - oldlen));
+ char_u *newp = xmalloc((size_t)(linelen + newlen - oldlen));
// Copy bytes before the cursor.
if (col > 0) {
@@ -1470,7 +1499,10 @@ void ins_char_bytes(char_u *buf, size_t charlen)
// Copy bytes after the changed character(s).
char_u *p = newp + col;
- memmove(p + newlen, oldp + col + oldlen, (size_t)(linelen - col - oldlen));
+ if (linelen > col + oldlen) {
+ memmove(p + newlen, oldp + col + oldlen,
+ (size_t)(linelen - col - oldlen));
+ }
// Insert or overwrite the new character.
memmove(p, buf, charlen);
@@ -1480,8 +1512,8 @@ void ins_char_bytes(char_u *buf, size_t charlen)
p[i] = ' ';
}
- /* Replace the line in the buffer. */
- ml_replace(lnum, newp, FALSE);
+ // Replace the line in the buffer.
+ ml_replace(lnum, newp, false);
// mark the buffer as changed and prepare for displaying
changed_bytes(lnum, (colnr_T)col);
@@ -1494,10 +1526,7 @@ void ins_char_bytes(char_u *buf, size_t charlen)
&& msg_silent == 0
&& !ins_compl_active()
) {
- if (has_mbyte)
- showmatch(mb_ptr2char(buf));
- else
- showmatch(c);
+ showmatch(utf_ptr2char(buf));
}
if (!p_ri || (State & REPLACE_FLAG)) {
@@ -1534,19 +1563,17 @@ void ins_str(char_u *s)
memmove(newp, oldp, (size_t)col);
memmove(newp + col, s, (size_t)newlen);
memmove(newp + col + newlen, oldp + col, (size_t)(oldlen - col + 1));
- ml_replace(lnum, newp, FALSE);
+ ml_replace(lnum, newp, false);
changed_bytes(lnum, col);
curwin->w_cursor.col += newlen;
}
-/*
- * Delete one character under the cursor.
- * If "fixpos" is TRUE, don't leave the cursor on the NUL after the line.
- * Caller must have prepared for undo.
- *
- * return FAIL for failure, OK otherwise
- */
-int del_char(int fixpos)
+// Delete one character under the cursor.
+// If "fixpos" is true, don't leave the cursor on the NUL after the line.
+// Caller must have prepared for undo.
+//
+// return FAIL for failure, OK otherwise
+int del_char(bool fixpos)
{
if (has_mbyte) {
/* Make sure the cursor is at the start of a character. */
@@ -1594,11 +1621,19 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
char_u *oldp = ml_get(lnum);
colnr_T oldlen = (colnr_T)STRLEN(oldp);
- /*
- * Can't do anything when the cursor is on the NUL after the line.
- */
- if (col >= oldlen)
+ // Can't do anything when the cursor is on the NUL after the line.
+ if (col >= oldlen) {
+ return FAIL;
+ }
+ // If "count" is zero there is nothing to do.
+ if (count == 0) {
+ return OK;
+ }
+ // If "count" is negative the caller must be doing something wrong.
+ if (count < 1) {
+ IEMSGN("E950: Invalid count for del_bytes(): %ld", count);
return FAIL;
+ }
/* If 'delcombine' is set and deleting (less than) one character, only
* delete the last combining character. */
@@ -1633,9 +1668,7 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
) {
--curwin->w_cursor.col;
curwin->w_cursor.coladd = 0;
- if (has_mbyte)
- curwin->w_cursor.col -=
- (*mb_head_off)(oldp, oldp + curwin->w_cursor.col);
+ curwin->w_cursor.col -= utf_head_off(oldp, oldp + curwin->w_cursor.col);
}
count = oldlen - col;
movelen = 1;
@@ -1652,8 +1685,9 @@ int del_bytes(colnr_T count, bool fixpos_arg, bool use_delcombine)
memmove(newp, oldp, (size_t)col);
}
memmove(newp + col, oldp + col + count, (size_t)movelen);
- if (!was_alloced)
- ml_replace(lnum, newp, FALSE);
+ if (!was_alloced) {
+ ml_replace(lnum, newp, false);
+ }
/* mark the buffer as changed and prepare for displaying */
changed_bytes(lnum, curwin->w_cursor.col);
@@ -1734,23 +1768,11 @@ del_lines (
int gchar_pos(pos_T *pos)
{
- char_u *ptr = ml_get_pos(pos);
-
- if (has_mbyte)
- return (*mb_ptr2char)(ptr);
- return (int)*ptr;
-}
-
-/*
- * Skip to next part of an option argument: Skip space and comma.
- */
-char_u *skip_to_option_part(char_u *p)
-{
- if (*p == ',')
- ++p;
- while (*p == ' ')
- ++p;
- return p;
+ // When searching columns is sometimes put at the end of a line.
+ if (pos->col == MAXCOL) {
+ return NUL;
+ }
+ return utf_ptr2char(ml_get_pos(pos));
}
/*
@@ -1796,7 +1818,7 @@ void changed(void)
}
changed_int();
}
- ++curbuf->b_changedtick;
+ buf_inc_changedtick(curbuf);
}
/*
@@ -1823,6 +1845,10 @@ void changed_bytes(linenr_T lnum, colnr_T col)
{
changedOneline(curbuf, lnum);
changed_common(lnum, col, lnum + 1, 0L);
+ // notify any channels that are watching
+ if (kv_size(curbuf->update_channels)) {
+ buf_updates_send_changes(curbuf, lnum, 1, 1, true);
+ }
/* Diff highlighting in other diff windows may need to be updated too. */
if (curwin->w_p_diff) {
@@ -1863,7 +1889,7 @@ static void changedOneline(buf_T *buf, linenr_T lnum)
*/
void appended_lines(linenr_T lnum, long count)
{
- changed_lines(lnum + 1, 0, lnum + 1, count);
+ changed_lines(lnum + 1, 0, lnum + 1, count, true);
}
/*
@@ -1871,8 +1897,12 @@ void appended_lines(linenr_T lnum, long count)
*/
void appended_lines_mark(linenr_T lnum, long count)
{
- mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L);
- changed_lines(lnum + 1, 0, lnum + 1, count);
+ // Skip mark_adjust when adding a line after the last one, there can't
+ // be marks there. But it's still needed in diff mode.
+ if (lnum + count < curbuf->b_ml.ml_line_count || curwin->w_p_diff) {
+ mark_adjust(lnum + 1, (linenr_T)MAXLNUM, count, 0L, false);
+ }
+ changed_lines(lnum + 1, 0, lnum + 1, count, true);
}
/*
@@ -1882,7 +1912,7 @@ void appended_lines_mark(linenr_T lnum, long count)
*/
void deleted_lines(linenr_T lnum, long count)
{
- changed_lines(lnum, 0, lnum + count, -count);
+ changed_lines(lnum, 0, lnum + count, -count, true);
}
/*
@@ -1892,8 +1922,8 @@ void deleted_lines(linenr_T lnum, long count)
*/
void deleted_lines_mark(linenr_T lnum, long count)
{
- mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count);
- changed_lines(lnum, 0, lnum + count, -count);
+ mark_adjust(lnum, (linenr_T)(lnum + count - 1), (long)MAXLNUM, -count, false);
+ changed_lines(lnum, 0, lnum + count, -count, true);
}
/*
@@ -1908,20 +1938,24 @@ void deleted_lines_mark(linenr_T lnum, long count)
* Takes care of calling changed() and updating b_mod_*.
* Careful: may trigger autocommands that reload the buffer.
*/
-void
-changed_lines (
- linenr_T lnum, /* first line with change */
- colnr_T col, /* column in first line with change */
- linenr_T lnume, /* line below last changed line */
- long xtra /* number of extra lines (negative when deleting) */
+void
+changed_lines(
+ linenr_T lnum, // first line with change
+ colnr_T col, // column in first line with change
+ linenr_T lnume, // line below last changed line
+ long xtra, // number of extra lines (negative when deleting)
+ bool do_buf_event // some callers like undo/redo call changed_lines()
+ // and then increment changedtick *again*. This flag
+ // allows these callers to send the nvim_buf_lines_event
+ // events after they're done modifying changedtick.
)
{
changed_lines_buf(curbuf, lnum, lnume, xtra);
- if (xtra == 0 && curwin->w_p_diff) {
- /* When the number of lines doesn't change then mark_adjust() isn't
- * called and other diff buffers still need to be marked for
- * displaying. */
+ if (xtra == 0 && curwin->w_p_diff && !diff_internal()) {
+ // When the number of lines doesn't change then mark_adjust() isn't
+ // called and other diff buffers still need to be marked for
+ // displaying.
linenr_T wlnum;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
@@ -1937,6 +1971,12 @@ changed_lines (
}
changed_common(lnum, col, lnume, xtra);
+
+ if (do_buf_event && kv_size(curbuf->update_channels)) {
+ int64_t num_added = (int64_t)(lnume + xtra - lnum);
+ int64_t num_removed = lnume - lnum;
+ buf_updates_send_changes(curbuf, lnum, num_added, num_removed, true);
+ }
}
/// Mark line range in buffer as changed.
@@ -1984,6 +2024,10 @@ static void changed_common(linenr_T lnum, colnr_T col, linenr_T lnume, long xtra
/* mark the buffer as modified */
changed();
+ if (curwin->w_p_diff && diff_internal()) {
+ curtab->tp_diff_update = true;
+ }
+
/* set the '. mark */
if (!cmdmod.keepjumps) {
RESET_FMARK(&curbuf->b_last_change, ((pos_T) {lnum, col, 0}), 0);
@@ -2151,7 +2195,7 @@ unchanged (
redraw_tabline = TRUE;
need_maketitle = TRUE; /* set window title later */
}
- ++buf->b_changedtick;
+ buf_inc_changedtick(buf);
}
/*
@@ -2202,12 +2246,12 @@ change_warning (
msg_start();
if (msg_row == Rows - 1)
msg_col = col;
- msg_source(hl_attr(HLF_W));
- MSG_PUTS_ATTR(_(w_readonly), hl_attr(HLF_W) | MSG_HIST);
+ msg_source(HL_ATTR(HLF_W));
+ MSG_PUTS_ATTR(_(w_readonly), HL_ATTR(HLF_W) | MSG_HIST);
set_vim_var_string(VV_WARNINGMSG, _(w_readonly), -1);
msg_clr_eos();
(void)msg_end();
- if (msg_silent == 0 && !silent_mode) {
+ if (msg_silent == 0 && !silent_mode && ui_active()) {
ui_flush();
os_delay(1000L, true); /* give the user time to think about it */
}
@@ -2218,44 +2262,47 @@ change_warning (
}
}
-/*
- * Ask for a reply from the user, a 'y' or a 'n'.
- * No other characters are accepted, the message is repeated until a valid
- * reply is entered or CTRL-C is hit.
- * If direct is TRUE, don't use vgetc() but ui_inchar(), don't get characters
- * from any buffers but directly from the user.
- *
- * return the 'y' or 'n'
- */
-int ask_yesno(char_u *str, int direct)
+/// Ask for a reply from the user, 'y' or 'n'
+///
+/// No other characters are accepted, the message is repeated until a valid
+/// reply is entered or <C-c> is hit.
+///
+/// @param[in] str Prompt: question to ask user. Is always followed by
+/// " (y/n)?".
+/// @param[in] direct Determines what function to use to get user input. If
+/// true then ui_inchar() will be used, otherwise vgetc().
+/// I.e. when direct is true then characters are obtained
+/// directly from the user without buffers involved.
+///
+/// @return 'y' or 'n'. Last is also what will be returned in case of interrupt.
+int ask_yesno(const char *const str, const bool direct)
{
- int r = ' ';
- int save_State = State;
+ const int save_State = State;
- ++no_wait_return;
- State = CONFIRM; /* mouse behaves like with :confirm */
- setmouse(); /* disables mouse for xterm */
- ++no_mapping;
- ++allow_keys; /* no mapping here, but recognize keys */
+ no_wait_return++;
+ State = CONFIRM; // Mouse behaves like with :confirm.
+ setmouse(); // Disable mouse in xterm.
+ no_mapping++;
+ int r = ' ';
while (r != 'y' && r != 'n') {
- /* same highlighting as for wait_return */
- smsg_attr(hl_attr(HLF_R),
- "%s (y/n)?", str);
- if (direct)
+ // Same highlighting as for wait_return.
+ smsg_attr(HL_ATTR(HLF_R), "%s (y/n)?", str);
+ if (direct) {
r = get_keystroke();
- else
+ } else {
r = plain_vgetc();
- if (r == Ctrl_C || r == ESC)
+ }
+ if (r == Ctrl_C || r == ESC) {
r = 'n';
- msg_putchar(r); /* show what you typed */
+ }
+ msg_putchar(r); // Show what you typed.
ui_flush();
}
- --no_wait_return;
+ no_wait_return--;
State = save_State;
setmouse();
- --no_mapping;
- --allow_keys;
+ no_mapping--;
return r;
}
@@ -2328,8 +2375,8 @@ int get_keystroke(void)
* terminal code to complete. */
n = os_inchar(buf + len, maxlen, len == 0 ? -1L : 100L, 0);
if (n > 0) {
- /* Replace zero and CSI by a special key code. */
- n = fix_input_buffer(buf + len, n, FALSE);
+ // Replace zero and CSI by a special key code.
+ n = fix_input_buffer(buf + len, n);
len += n;
waited = 0;
} else if (len > 0)
@@ -2365,16 +2412,12 @@ int get_keystroke(void)
}
break;
}
- if (has_mbyte) {
- if (MB_BYTE2LEN(n) > len)
- continue; /* more bytes to get */
- buf[len >= buflen ? buflen - 1 : len] = NUL;
- n = (*mb_ptr2char)(buf);
+ if (MB_BYTE2LEN(n) > len) {
+ // more bytes to get.
+ continue;
}
-#ifdef UNIX
- if (n == intr_char)
- n = ESC;
-#endif
+ buf[len >= buflen ? buflen - 1 : len] = NUL;
+ n = utf_ptr2char(buf);
break;
}
xfree(buf);
@@ -2405,8 +2448,7 @@ get_number (
if (msg_silent != 0)
return 0;
- ++no_mapping;
- ++allow_keys; /* no mapping here, but recognize keys */
+ no_mapping++;
for (;; ) {
ui_cursor_goto(msg_row, msg_col);
c = safe_vgetc();
@@ -2434,8 +2476,7 @@ get_number (
} else if (c == CAR || c == NL || c == Ctrl_C || c == ESC)
break;
}
- --no_mapping;
- --allow_keys;
+ no_mapping--;
return n;
}
@@ -2461,7 +2502,7 @@ int prompt_for_number(int *mouse_used)
save_cmdline_row = cmdline_row;
cmdline_row = 0;
save_State = State;
- State = CMDLINE;
+ State = ASKMORE; // prevents a screen update when using a timer
i = get_number(TRUE, mouse_used);
if (KeyTyped) {
@@ -2511,8 +2552,9 @@ void msgmore(long n)
vim_snprintf((char *)msg_buf, MSG_BUF_LEN,
_("%" PRId64 " fewer lines"), (int64_t)pn);
}
- if (got_int)
- vim_strcat(msg_buf, (char_u *)_(" (Interrupted)"), MSG_BUF_LEN);
+ if (got_int) {
+ xstrlcat((char *)msg_buf, _(" (Interrupted)"), MSG_BUF_LEN);
+ }
if (msg(msg_buf)) {
set_keep_msg(msg_buf, 0);
keep_msg_more = TRUE;
@@ -2526,7 +2568,7 @@ void msgmore(long n)
void beep_flush(void)
{
if (emsg_silent == 0) {
- flush_buffers(false);
+ flush_buffers(FLUSH_MINIMAL);
vim_beep(BO_ERROR);
}
}
@@ -2538,17 +2580,17 @@ void vim_beep(unsigned val)
if (emsg_silent == 0) {
if (!((bo_flags & val) || (bo_flags & BO_ALL))) {
if (p_vb) {
- ui_visual_bell();
+ ui_call_visual_bell();
} else {
- ui_putc(BELL);
+ ui_call_bell();
}
}
/* When 'verbose' is set and we are sourcing a script or executing a
* function give the user a hint where the beep comes from. */
if (vim_strchr(p_debug, 'e') != NULL) {
- msg_source(hl_attr(HLF_W));
- msg_attr((char_u *)_("Beep!"), hl_attr(HLF_W));
+ msg_source(HL_ATTR(HLF_W));
+ msg_attr(_("Beep!"), HL_ATTR(HLF_W));
}
}
}
@@ -2611,24 +2653,28 @@ int match_user(char_u *name)
return result;
}
-/*
- * Preserve files and exit.
- * When called IObuff must contain a message.
- * NOTE: This may be called from deathtrap() in a signal handler, avoid unsafe
- * functions, such as allocating memory.
- */
+/// Preserve files and exit.
+/// @note IObuff must contain a message.
+/// @note This may be called from deadly_signal() in a signal handler, avoid
+/// unsafe functions, such as allocating memory.
void preserve_exit(void)
+ FUNC_ATTR_NORETURN
{
// 'true' when we are sure to exit, e.g., after a deadly signal
static bool really_exiting = false;
// Prevent repeated calls into this method.
if (really_exiting) {
- stream_set_blocking(input_global_fd(), true); //normalize stream (#2598)
+ if (input_global_fd() >= 0) {
+ // normalize stream (#2598)
+ stream_set_blocking(input_global_fd(), true);
+ }
exit(2);
}
really_exiting = true;
+ // Ignore SIGHUP while we are already exiting. #9274
+ signal_reject_deadly();
mch_errmsg(IObuff);
mch_errmsg("\n");
ui_flush();
@@ -2639,7 +2685,7 @@ void preserve_exit(void)
if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
mch_errmsg((uint8_t *)"Vim: preserving files...\n");
ui_flush();
- ml_sync_all(false, false); // preserve all swap files
+ ml_sync_all(false, false, true); // preserve all swap files
break;
}
}
@@ -2683,6 +2729,44 @@ void fast_breakcheck(void)
}
}
+/// os_call_shell() wrapper. Handles 'verbose', :profile, and v:shell_error.
+/// Invalidates cached tags.
+///
+/// @return shell command exit code
+int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
+{
+ int retval;
+ proftime_T wait_time;
+
+ if (p_verbose > 3) {
+ verbose_enter();
+ smsg(_("Executing command: \"%s\""), cmd == NULL ? p_sh : cmd);
+ msg_putchar('\n');
+ verbose_leave();
+ }
+
+ if (do_profiling == PROF_YES) {
+ prof_child_enter(&wait_time);
+ }
+
+ if (*p_sh == NUL) {
+ EMSG(_(e_shellempty));
+ retval = -1;
+ } else {
+ // The external command may update a tags file, clear cached tags.
+ tag_freematch();
+
+ retval = os_call_shell(cmd, opts, extra_shell_arg);
+ }
+
+ set_vim_var_nr(VV_SHELL_ERROR, (varnumber_T)retval);
+ if (do_profiling == PROF_YES) {
+ prof_child_exit(&wait_time);
+ }
+
+ return retval;
+}
+
/// Get the stdout of an external command.
/// If "ret_len" is NULL replace NUL characters with NL. When "ret_len" is not
/// NULL store the length there.
@@ -2779,4 +2863,3 @@ int goto_im(void)
{
return p_im && stuff_empty() && typebuf_typed();
}
-
diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c
deleted file mode 100644
index 368f83cfb5..0000000000
--- a/src/nvim/misc2.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * misc2.c: Various functions.
- */
-#include <assert.h>
-#include <inttypes.h>
-#include <string.h>
-
-#include "nvim/vim.h"
-#include "nvim/ascii.h"
-#include "nvim/misc2.h"
-#include "nvim/file_search.h"
-#include "nvim/buffer.h"
-#include "nvim/charset.h"
-#include "nvim/cursor.h"
-#include "nvim/diff.h"
-#include "nvim/edit.h"
-#include "nvim/eval.h"
-#include "nvim/ex_cmds.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/ex_getln.h"
-#include "nvim/fileio.h"
-#include "nvim/fold.h"
-#include "nvim/getchar.h"
-#include "nvim/macros.h"
-#include "nvim/mark.h"
-#include "nvim/mbyte.h"
-#include "nvim/memfile.h"
-#include "nvim/memline.h"
-#include "nvim/memory.h"
-#include "nvim/message.h"
-#include "nvim/misc1.h"
-#include "nvim/move.h"
-#include "nvim/option.h"
-#include "nvim/ops.h"
-#include "nvim/os_unix.h"
-#include "nvim/path.h"
-#include "nvim/quickfix.h"
-#include "nvim/regexp.h"
-#include "nvim/screen.h"
-#include "nvim/search.h"
-#include "nvim/spell.h"
-#include "nvim/strings.h"
-#include "nvim/syntax.h"
-#include "nvim/tag.h"
-#include "nvim/ui.h"
-#include "nvim/window.h"
-#include "nvim/os/os.h"
-#include "nvim/os/shell.h"
-
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "misc2.c.generated.h"
-#endif
-/*
- * Return TRUE if in the current mode we need to use virtual.
- */
-int virtual_active(void)
-{
- /* While an operator is being executed we return "virtual_op", because
- * VIsual_active has already been reset, thus we can't check for "block"
- * being used. */
- if (virtual_op != MAYBE)
- return virtual_op;
- return ve_flags == VE_ALL
- || ((ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
- || ((ve_flags & VE_INSERT) && (State & INSERT));
-}
-
-/*
- * Increment the line pointer "lp" crossing line boundaries as necessary.
- * Return 1 when going to the next line.
- * Return 2 when moving forward onto a NUL at the end of the line).
- * Return -1 when at the end of file.
- * Return 0 otherwise.
- */
-int inc(pos_T *lp)
-{
- char_u *p = ml_get_pos(lp);
-
- if (*p != NUL) { /* still within line, move to next char (may be NUL) */
- if (has_mbyte) {
- int l = (*mb_ptr2len)(p);
-
- lp->col += l;
- return (p[l] != NUL) ? 0 : 2;
- }
- lp->col++;
- lp->coladd = 0;
- return (p[1] != NUL) ? 0 : 2;
- }
- if (lp->lnum != curbuf->b_ml.ml_line_count) { /* there is a next line */
- lp->col = 0;
- lp->lnum++;
- lp->coladd = 0;
- return 1;
- }
- return -1;
-}
-
-/*
- * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
- */
-int incl(pos_T *lp)
-{
- int r;
-
- if ((r = inc(lp)) >= 1 && lp->col)
- r = inc(lp);
- return r;
-}
-
-int dec(pos_T *lp)
-{
- char_u *p;
-
- lp->coladd = 0;
- if (lp->col > 0) { /* still within line */
- lp->col--;
- if (has_mbyte) {
- p = ml_get(lp->lnum);
- lp->col -= (*mb_head_off)(p, p + lp->col);
- }
- return 0;
- }
- if (lp->lnum > 1) { /* there is a prior line */
- lp->lnum--;
- p = ml_get(lp->lnum);
- lp->col = (colnr_T)STRLEN(p);
- if (has_mbyte)
- lp->col -= (*mb_head_off)(p, p + lp->col);
- return 1;
- }
- return -1; /* at start of file */
-}
-
-/*
- * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
- */
-int decl(pos_T *lp)
-{
- int r;
-
- if ((r = dec(lp)) == 1 && lp->col)
- r = dec(lp);
- return r;
-}
-
-/*
- * Return TRUE when 'shell' has "csh" in the tail.
- */
-int csh_like_shell(void)
-{
- return strstr((char *)path_tail(p_sh), "csh") != NULL;
-}
-
-/*
- * Isolate one part of a string option where parts are separated with
- * "sep_chars".
- * The part is copied into "buf[maxlen]".
- * "*option" is advanced to the next part.
- * The length is returned.
- */
-size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen, char *sep_chars)
-{
- size_t len = 0;
- char_u *p = *option;
-
- /* skip '.' at start of option part, for 'suffixes' */
- if (*p == '.')
- buf[len++] = *p++;
- while (*p != NUL && vim_strchr((char_u *)sep_chars, *p) == NULL) {
- /*
- * Skip backslash before a separator character and space.
- */
- if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL)
- ++p;
- if (len < maxlen - 1)
- buf[len++] = *p;
- ++p;
- }
- buf[len] = NUL;
-
- if (*p != NUL && *p != ',') /* skip non-standard separator */
- ++p;
- p = skip_to_option_part(p); /* p points to next file name */
-
- *option = p;
- return len;
-}
-
-/*
- * Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
- */
-int get_fileformat(buf_T *buf)
-{
- int c = *buf->b_p_ff;
-
- if (buf->b_p_bin || c == 'u')
- return EOL_UNIX;
- if (c == 'm')
- return EOL_MAC;
- return EOL_DOS;
-}
-
-/*
- * Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
- * argument.
- */
-int
-get_fileformat_force (
- buf_T *buf,
- exarg_T *eap /* can be NULL! */
-)
-{
- int c;
-
- if (eap != NULL && eap->force_ff != 0)
- c = eap->cmd[eap->force_ff];
- else {
- if ((eap != NULL && eap->force_bin != 0)
- ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin)
- return EOL_UNIX;
- c = *buf->b_p_ff;
- }
- if (c == 'u')
- return EOL_UNIX;
- if (c == 'm')
- return EOL_MAC;
- return EOL_DOS;
-}
-
-/// Set the current end-of-line type to EOL_UNIX, EOL_MAC, or EOL_DOS.
-///
-/// Sets 'fileformat'.
-///
-/// @param eol_style End-of-line style.
-/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
-void set_fileformat(int eol_style, int opt_flags)
-{
- char *p = NULL;
-
- switch (eol_style) {
- case EOL_UNIX:
- p = FF_UNIX;
- break;
- case EOL_MAC:
- p = FF_MAC;
- break;
- case EOL_DOS:
- p = FF_DOS;
- break;
- }
-
- // p is NULL if "eol_style" is EOL_UNKNOWN.
- if (p != NULL) {
- set_string_option_direct((char_u *)"ff",
- -1,
- (char_u *)p,
- OPT_FREE | opt_flags,
- 0);
- }
-
- // This may cause the buffer to become (un)modified.
- check_status(curbuf);
- redraw_tabline = TRUE;
- need_maketitle = TRUE; // Set window title later.
-}
-
-/*
- * Return the default fileformat from 'fileformats'.
- */
-int default_fileformat(void)
-{
- switch (*p_ffs) {
- case 'm': return EOL_MAC;
- case 'd': return EOL_DOS;
- }
- return EOL_UNIX;
-}
-
-// Call shell. Calls os_call_shell, with 'shellxquote' added.
-int call_shell(char_u *cmd, ShellOpts opts, char_u *extra_shell_arg)
-{
- char_u *ncmd;
- int retval;
- proftime_T wait_time;
-
- if (p_verbose > 3) {
- verbose_enter();
- smsg(_("Calling shell to execute: \"%s\""),
- cmd == NULL ? p_sh : cmd);
- ui_putc('\n');
- verbose_leave();
- }
-
- if (do_profiling == PROF_YES)
- prof_child_enter(&wait_time);
-
- if (*p_sh == NUL) {
- EMSG(_(e_shellempty));
- retval = -1;
- } else {
- /* The external command may update a tags file, clear cached tags. */
- tag_freematch();
-
- if (cmd == NULL || *p_sxq == NUL)
- retval = os_call_shell(cmd, opts, extra_shell_arg);
- else {
- char_u *ecmd = cmd;
-
- if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) {
- ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE);
- }
- ncmd = xmalloc(STRLEN(ecmd) + STRLEN(p_sxq) * 2 + 1);
- STRCPY(ncmd, p_sxq);
- STRCAT(ncmd, ecmd);
- /* When 'shellxquote' is ( append ).
- * When 'shellxquote' is "( append )". */
- STRCAT(ncmd, STRCMP(p_sxq, "(") == 0 ? (char_u *)")"
- : STRCMP(p_sxq, "\"(") == 0 ? (char_u *)")\""
- : p_sxq);
- retval = os_call_shell(ncmd, opts, extra_shell_arg);
- xfree(ncmd);
-
- if (ecmd != cmd)
- xfree(ecmd);
- }
- }
-
- set_vim_var_nr(VV_SHELL_ERROR, (varnumber_T) retval);
- if (do_profiling == PROF_YES) {
- prof_child_exit(&wait_time);
- }
-
- return retval;
-}
-
-/*
- * VISUAL, SELECTMODE and OP_PENDING State are never set, they are equal to
- * NORMAL State with a condition. This function returns the real State.
- */
-int get_real_state(void)
-{
- if (State & NORMAL) {
- if (VIsual_active) {
- if (VIsual_select)
- return SELECTMODE;
- return VISUAL;
- } else if (finish_op)
- return OP_PENDING;
- }
- return State;
-}
-
-/*
- * Change to a file's directory.
- * Caller must call shorten_fnames()!
- * Return OK or FAIL.
- */
-int vim_chdirfile(char_u *fname)
-{
- char_u dir[MAXPATHL];
-
- STRLCPY(dir, fname, MAXPATHL);
- *path_tail_with_sep(dir) = NUL;
- return os_chdir((char *)dir) == 0 ? OK : FAIL;
-}
-
-/*
- * Change directory to "new_dir". Search 'cdpath' for relative directory names.
- */
-int vim_chdir(char_u *new_dir)
-{
- char_u *dir_name;
- int r;
-
- dir_name = find_directory_in_path(new_dir, STRLEN(new_dir),
- FNAME_MESS, curbuf->b_ffname);
- if (dir_name == NULL)
- return -1;
- r = os_chdir((char *)dir_name);
- xfree(dir_name);
- return r;
-}
-
-/*
- * Read 2 bytes from "fd" and turn them into an int, MSB first.
- */
-int get2c(FILE *fd)
-{
- int n;
-
- n = getc(fd);
- n = (n << 8) + getc(fd);
- return n;
-}
-
-/*
- * Read 3 bytes from "fd" and turn them into an int, MSB first.
- */
-int get3c(FILE *fd)
-{
- int n;
-
- n = getc(fd);
- n = (n << 8) + getc(fd);
- n = (n << 8) + getc(fd);
- return n;
-}
-
-/*
- * Read 4 bytes from "fd" and turn them into an int, MSB first.
- */
-int get4c(FILE *fd)
-{
- /* Use unsigned rather than int otherwise result is undefined
- * when left-shift sets the MSB. */
- unsigned n;
-
- n = (unsigned)getc(fd);
- n = (n << 8) + (unsigned)getc(fd);
- n = (n << 8) + (unsigned)getc(fd);
- n = (n << 8) + (unsigned)getc(fd);
- return (int)n;
-}
-
-/*
- * Read 8 bytes from "fd" and turn them into a time_t, MSB first.
- */
-time_t get8ctime(FILE *fd)
-{
- time_t n = 0;
- int i;
-
- for (i = 0; i < 8; ++i)
- n = (n << 8) + getc(fd);
- return n;
-}
-
-/// Reads a string of length "cnt" from "fd" into allocated memory.
-/// @return pointer to the string or NULL when unable to read that many bytes.
-char *read_string(FILE *fd, size_t cnt)
-{
- uint8_t *str = xmallocz(cnt);
- for (size_t i = 0; i < cnt; i++) {
- int c = getc(fd);
- if (c == EOF) {
- xfree(str);
- return NULL;
- }
- str[i] = (uint8_t)c;
- }
- return (char *)str;
-}
-
-/// Writes a number to file "fd", most significant bit first, in "len" bytes.
-/// @returns false in case of an error.
-bool put_bytes(FILE *fd, uintmax_t number, size_t len)
-{
- assert(len > 0);
- for (size_t i = len - 1; i < len; i--) {
- if (putc((int)(number >> (i * 8)), fd) == EOF) {
- return false;
- }
- }
- return true;
-}
-
-/// Writes time_t to file "fd" in 8 bytes.
-/// @returns FAIL when the write failed.
-int put_time(FILE *fd, time_t time_)
-{
- uint8_t buf[8];
- time_to_bytes(time_, buf);
- return fwrite(buf, sizeof(uint8_t), ARRAY_SIZE(buf), fd) == 1 ? OK : FAIL;
-}
-
-/// Writes time_t to "buf[8]".
-void time_to_bytes(time_t time_, uint8_t buf[8])
-{
- // time_t can be up to 8 bytes in size, more than uintmax_t in 32 bits
- // systems, thus we can't use put_bytes() here.
- for (size_t i = 7, bufi = 0; bufi < 8; i--, bufi++) {
- buf[bufi] = (uint8_t)((uint64_t)time_ >> (i * 8));
- }
-}
diff --git a/src/nvim/misc2.h b/src/nvim/misc2.h
deleted file mode 100644
index 28b5b775d2..0000000000
--- a/src/nvim/misc2.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef NVIM_MISC2_H
-#define NVIM_MISC2_H
-
-#include "nvim/os/shell.h"
-
-#define READ_STRING(x, y) (char_u *)read_string((x), (size_t)(y))
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "misc2.h.generated.h"
-#endif
-
-#endif // NVIM_MISC2_H
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c
index 2f499e477c..887cbde921 100644
--- a/src/nvim/mouse.c
+++ b/src/nvim/mouse.c
@@ -1,11 +1,16 @@
+// 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 <stdbool.h>
#include "nvim/mouse.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/window.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/screen.h"
+#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/os_unix.h"
#include "nvim/fold.h"
@@ -103,12 +108,14 @@ retnomove:
goto retnomove; // ugly goto...
// Remember the character under the mouse, it might be a '-' or '+' in the
- // fold column.
+ // fold column. NB: only works for ASCII chars!
if (row >= 0 && row < Rows && col >= 0 && col <= Columns
- && ScreenLines != NULL)
- mouse_char = ScreenLines[LineOffset[row] + (unsigned)col];
- else
+ && default_grid.chars != NULL) {
+ mouse_char = default_grid.chars[default_grid.line_offset[row]
+ + (unsigned)col][0];
+ } else {
mouse_char = ' ';
+ }
old_curwin = curwin;
old_cursor = curwin->w_cursor;
@@ -119,6 +126,9 @@ retnomove:
// find the window where the row is in
wp = mouse_find_win(&row, &col);
+ if (wp == NULL) {
+ return IN_UNKNOWN;
+ }
dragwin = NULL;
// winpos and height may change in win_enter()!
if (row >= wp->w_height) { // In (or below) status line
@@ -303,9 +313,12 @@ retnomove:
mouse_past_bottom = true;
}
+ if (!(flags & MOUSE_RELEASED) && which_button == MOUSE_LEFT) {
+ col = mouse_adjust_click(curwin, row, col);
+ }
+
// Start Visual mode before coladvance(), for when 'sel' != "old"
if ((flags & MOUSE_MAY_VIS) && !VIsual_active) {
- check_visual_highlight();
VIsual = old_cursor;
VIsual_active = true;
VIsual_reselect = true;
@@ -417,6 +430,7 @@ bool mouse_comp_pos(win_T *win, int *rowp, int *colp, linenr_T *lnump)
// Find the window at screen position "*rowp" and "*colp". The positions are
// updated to become relative to the top-left of the window.
+// Returns NULL when something is wrong.
win_T *mouse_find_win(int *rowp, int *colp)
{
frame_T *fp;
@@ -440,7 +454,14 @@ win_T *mouse_find_win(int *rowp, int *colp)
}
}
}
- return fp->fr_win;
+ // When using a timer that closes a window the window might not actually
+ // exist.
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp == fp->fr_win) {
+ return wp;
+ }
+ }
+ return NULL;
}
/*
@@ -450,6 +471,7 @@ void setmouse(void)
{
int checkfor;
+ ui_cursor_shape();
/* be quick when mouse is off */
if (*p_mouse == NUL)
@@ -469,9 +491,9 @@ void setmouse(void)
checkfor = MOUSE_NORMAL; /* assume normal mode */
if (mouse_has(checkfor)) {
- ui_mouse_on();
+ ui_call_mouse_on();
} else {
- ui_mouse_off();
+ ui_call_mouse_off();
}
}
@@ -515,7 +537,7 @@ static colnr_T scroll_line_len(linenr_T lnum)
if (*line != NUL) {
for (;;) {
int numchar = chartabsize(line, col);
- mb_ptr_adv(line);
+ MB_PTR_ADV(line);
if (*line == NUL) { // don't count the last character
break;
}
@@ -597,3 +619,111 @@ bool mouse_scroll_horiz(int dir)
return leftcol_changed();
}
+
+/// Adjusts the clicked column position when 'conceallevel' > 0
+static int mouse_adjust_click(win_T *wp, int row, int col)
+{
+ if (!(wp->w_p_cole > 0 && curbuf->b_p_smc > 0
+ && wp->w_leftcol < curbuf->b_p_smc && conceal_cursor_line(wp))) {
+ return col;
+ }
+
+ // `col` is the position within the current line that is highlighted by the
+ // cursor without consideration for concealed characters. The current line is
+ // scanned *up to* `col`, nudging it left or right when concealed characters
+ // are encountered.
+ //
+ // chartabsize() is used to keep track of the virtual column position relative
+ // to the line's bytes. For example: if col == 9 and the line starts with a
+ // tab that's 8 columns wide, we would want the cursor to be highlighting the
+ // second byte, not the ninth.
+
+ linenr_T lnum = wp->w_cursor.lnum;
+ char_u *line = ml_get(lnum);
+ char_u *ptr = line;
+ char_u *ptr_end;
+ char_u *ptr_row_offset = line; // Where we begin adjusting `ptr_end`
+
+ // Find the offset where scanning should begin.
+ int offset = wp->w_leftcol;
+ if (row > 0) {
+ offset += row * (wp->w_width - win_col_off(wp) - win_col_off2(wp) -
+ wp->w_leftcol + wp->w_skipcol);
+ }
+
+ int vcol;
+
+ if (offset) {
+ // Skip everything up to an offset since nvim takes care of displaying the
+ // correct portion of the line when horizontally scrolling.
+ // When 'wrap' is enabled, only the row (of the wrapped line) needs to be
+ // checked for concealed characters.
+ vcol = 0;
+ while (vcol < offset && *ptr != NUL) {
+ vcol += chartabsize(ptr, vcol);
+ ptr += utfc_ptr2len(ptr);
+ }
+
+ ptr_row_offset = ptr;
+ }
+
+ // Align `ptr_end` with `col`
+ vcol = offset;
+ ptr_end = ptr_row_offset;
+ while (vcol < col && *ptr_end != NUL) {
+ vcol += chartabsize(ptr_end, vcol);
+ ptr_end += utfc_ptr2len(ptr_end);
+ }
+
+ int matchid;
+ int prev_matchid;
+ int nudge = 0;
+ int cwidth = 0;
+
+ vcol = offset;
+
+#define incr() nudge++; ptr_end += utfc_ptr2len(ptr_end)
+#define decr() nudge--; ptr_end -= utfc_ptr2len(ptr_end)
+
+ while (ptr < ptr_end && *ptr != NUL) {
+ cwidth = chartabsize(ptr, vcol);
+ vcol += cwidth;
+ if (cwidth > 1 && *ptr == '\t' && nudge > 0) {
+ // A tab will "absorb" any previous adjustments.
+ cwidth = MIN(cwidth, nudge);
+ while (cwidth > 0) {
+ decr();
+ cwidth--;
+ }
+ }
+
+ matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line));
+ if (matchid != 0) {
+ if (wp->w_p_cole == 3) {
+ incr();
+ } else {
+ if (!(row > 0 && ptr == ptr_row_offset)
+ && (wp->w_p_cole == 1 || (wp->w_p_cole == 2
+ && (lcs_conceal != NUL
+ || syn_get_sub_char() != NUL)))) {
+ // At least one placeholder character will be displayed.
+ decr();
+ }
+
+ prev_matchid = matchid;
+
+ while (prev_matchid == matchid && *ptr != NUL) {
+ incr();
+ ptr += utfc_ptr2len(ptr);
+ matchid = syn_get_concealed_id(wp, lnum, (colnr_T)(ptr - line));
+ }
+
+ continue;
+ }
+ }
+
+ ptr += utfc_ptr2len(ptr);
+ }
+
+ return col + nudge;
+}
diff --git a/src/nvim/move.c b/src/nvim/move.c
index b129c5cb7a..07b355e603 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.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
+
/*
* move.c: Functions for moving the cursor and scrolling text.
*
@@ -13,7 +16,6 @@
#include <inttypes.h>
#include <stdbool.h>
-#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/move.h"
#include "nvim/charset.h"
@@ -24,7 +26,7 @@
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
+#include "nvim/option.h"
#include "nvim/popupmnu.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
@@ -81,8 +83,9 @@ static void comp_botline(win_T *wp)
redraw_for_cursorline(wp);
wp->w_valid |= (VALID_CROW|VALID_CHEIGHT);
}
- if (done + n > wp->w_height)
+ if (done + n > wp->w_grid.Rows) {
break;
+ }
done += n;
lnum = last;
}
@@ -94,16 +97,34 @@ static void comp_botline(win_T *wp)
set_empty_rows(wp, done);
}
-/*
-* Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is
-* set.
-*/
+void reset_cursorline(void)
+{
+ curwin->w_last_cursorline = 0;
+}
+
+// Redraw when w_cline_row changes and 'relativenumber' or 'cursorline' is set.
static void redraw_for_cursorline(win_T *wp)
{
- if ((wp->w_p_rnu || wp->w_p_cul)
+ if ((wp->w_p_rnu || win_cursorline_standout(wp))
&& (wp->w_valid & VALID_CROW) == 0
&& !pum_visible()) {
- redraw_win_later(wp, SOME_VALID);
+ if (wp->w_p_rnu) {
+ // win_line() will redraw the number column only.
+ redraw_win_later(wp, VALID);
+ }
+ if (win_cursorline_standout(wp)) {
+ if (wp->w_redr_type <= VALID && wp->w_last_cursorline != 0) {
+ // "w_last_cursorline" may be outdated, worst case we redraw
+ // too much. This is optimized for moving the cursor around in
+ // the current window.
+ redrawWinline(wp, wp->w_last_cursorline);
+ redrawWinline(wp, wp->w_cursor.lnum);
+ redraw_win_later(wp, VALID);
+ } else {
+ redraw_win_later(wp, SOME_VALID);
+ }
+ wp->w_last_cursorline = wp->w_cursor.lnum;
+ }
}
}
@@ -129,11 +150,12 @@ void update_topline(void)
bool check_botline = false;
long save_so = p_so;
- if (!screen_valid(true))
- return;
+ // need to have w_grid.Rows/Columns updated
+ win_grid_alloc(curwin);
- // If the window height is zero, just use the cursor line.
- if (curwin->w_height == 0) {
+ // If there is no valid screen and when the window height is zero just use
+ // the cursor line.
+ if (!screen_valid(true) || curwin->w_grid.Rows == 0) {
curwin->w_topline = curwin->w_cursor.lnum;
curwin->w_botline = curwin->w_topline;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
@@ -152,12 +174,11 @@ void update_topline(void)
old_topline = curwin->w_topline;
old_topfill = curwin->w_topfill;
- /*
- * If the buffer is empty, always set topline to 1.
- */
- if (bufempty()) { /* special case - file is empty */
- if (curwin->w_topline != 1)
+ // If the buffer is empty, always set topline to 1.
+ if (BUFEMPTY()) { // special case - file is empty
+ if (curwin->w_topline != 1) {
redraw_later(NOT_VALID);
+ }
curwin->w_topline = 1;
curwin->w_botline = 2;
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
@@ -183,9 +204,10 @@ void update_topline(void)
check_topline = true;
if (check_topline) {
- int halfheight = curwin->w_height / 2 - 1;
- if (halfheight < 2)
+ int halfheight = curwin->w_grid.Rows / 2 - 1;
+ if (halfheight < 2) {
halfheight = 2;
+ }
long n;
if (hasAnyFolding(curwin)) {
/* Count the number of logical lines between the cursor and
@@ -272,20 +294,22 @@ void update_topline(void)
* botline - p_so (approximation of how much will be
* scrolled). */
for (linenr_T lnum = curwin->w_cursor.lnum;
- lnum >= curwin->w_botline - p_so; --lnum) {
- ++line_count;
- /* stop at end of file or when we know we are far off */
- if (lnum <= 0 || line_count > curwin->w_height + 1)
+ lnum >= curwin->w_botline - p_so; lnum--) {
+ line_count++;
+ // stop at end of file or when we know we are far off
+ if (lnum <= 0 || line_count > curwin->w_grid.Rows + 1) {
break;
+ }
(void)hasFolding(lnum, &lnum, NULL);
}
} else
line_count = curwin->w_cursor.lnum - curwin->w_botline
+ 1 + p_so;
- if (line_count <= curwin->w_height + 1)
+ if (line_count <= curwin->w_grid.Rows + 1) {
scroll_cursor_bot(scrolljump_value(), false);
- else
+ } else {
scroll_cursor_halfway(false);
+ }
}
}
}
@@ -329,7 +353,7 @@ void update_topline_win(win_T* win)
*/
static int scrolljump_value(void)
{
- long result = p_sj >= 0 ? p_sj : (curwin->w_height * -p_sj) / 100;
+ long result = p_sj >= 0 ? p_sj : (curwin->w_grid.Rows * -p_sj) / 100;
assert(result <= INT_MAX);
return (int)result;
}
@@ -505,6 +529,7 @@ int cursor_valid(void)
*/
void validate_cursor(void)
{
+ win_grid_alloc(curwin); // we need to have w_grid.Rows/Columns updated
check_cursor_moved(curwin);
if ((curwin->w_valid & (VALID_WCOL|VALID_WROW)) != (VALID_WCOL|VALID_WROW))
curs_columns(true);
@@ -643,18 +668,19 @@ void validate_cursor_col(void)
colnr_T col = curwin->w_virtcol;
colnr_T off = curwin_col_off();
col += off;
- int width = curwin->w_width - off + curwin_col_off2();
-
- /* long line wrapping, adjust curwin->w_wrow */
- if (curwin->w_p_wrap
- && col >= (colnr_T)curwin->w_width
- && width > 0)
- /* use same formula as what is used in curs_columns() */
- col -= ((col - curwin->w_width) / width + 1) * width;
- if (col > (int)curwin->w_leftcol)
+ int width = curwin->w_grid.Columns - off + curwin_col_off2();
+
+ // long line wrapping, adjust curwin->w_wrow
+ if (curwin->w_p_wrap && col >= (colnr_T)curwin->w_grid.Columns
+ && width > 0) {
+ // use same formula as what is used in curs_columns()
+ col -= ((col - curwin->w_grid.Columns) / width + 1) * width;
+ }
+ if (col > (int)curwin->w_leftcol) {
col -= curwin->w_leftcol;
- else
+ } else {
col = 0;
+ }
curwin->w_wcol = col;
curwin->w_valid |= VALID_WCOL;
@@ -670,8 +696,7 @@ int win_col_off(win_T *wp)
return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0)
+ (cmdwin_type == 0 || wp != curwin ? 0 : 1)
+ (int)wp->w_p_fdc
- + (wp->w_buffer->b_signlist != NULL ? 2 : 0)
- ;
+ + (signcolumn_on(wp) ? win_signcol_width(wp) : 0);
}
int curwin_col_off(void)
@@ -744,20 +769,20 @@ void curs_columns(
*/
curwin->w_wrow = curwin->w_cline_row;
- int textwidth = curwin->w_width - extra;
+ int textwidth = curwin->w_grid.Columns - extra;
if (textwidth <= 0) {
- /* No room for text, put cursor in last char of window. */
- curwin->w_wcol = curwin->w_width - 1;
- curwin->w_wrow = curwin->w_height - 1;
+ // No room for text, put cursor in last char of window.
+ curwin->w_wcol = curwin->w_grid.Columns - 1;
+ curwin->w_wrow = curwin->w_grid.Rows - 1;
} else if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
width = textwidth + curwin_col_off2();
- /* long line wrapping, adjust curwin->w_wrow */
- if (curwin->w_wcol >= curwin->w_width) {
- /* this same formula is used in validate_cursor_col() */
- n = (curwin->w_wcol - curwin->w_width) / width + 1;
+ // long line wrapping, adjust curwin->w_wrow
+ if (curwin->w_wcol >= curwin->w_grid.Columns) {
+ // this same formula is used in validate_cursor_col()
+ n = (curwin->w_wcol - curwin->w_grid.Columns) / width + 1;
curwin->w_wcol -= n * width;
curwin->w_wrow += n;
@@ -784,7 +809,7 @@ void curs_columns(
assert(p_siso <= INT_MAX);
int off_left = startcol - curwin->w_leftcol - (int)p_siso;
int off_right =
- endcol - curwin->w_leftcol - curwin->w_width + (int)p_siso + 1;
+ endcol - curwin->w_leftcol - curwin->w_grid.Columns + (int)p_siso + 1;
if (off_left < 0 || off_right > 0) {
int diff = (off_left < 0) ? -off_left: off_right;
@@ -827,17 +852,16 @@ void curs_columns(
prev_skipcol = curwin->w_skipcol;
int p_lines = 0;
- if ((curwin->w_wrow >= curwin->w_height
+ if ((curwin->w_wrow >= curwin->w_grid.Rows
|| ((prev_skipcol > 0
- || curwin->w_wrow + p_so >= curwin->w_height)
+ || curwin->w_wrow + p_so >= curwin->w_grid.Rows)
&& (p_lines =
- plines_win_nofill
- (curwin, curwin->w_cursor.lnum, false))
- - 1 >= curwin->w_height))
- && curwin->w_height != 0
+ plines_win_nofill(curwin, curwin->w_cursor.lnum, false)) - 1
+ >= curwin->w_grid.Rows))
+ && curwin->w_grid.Rows != 0
&& curwin->w_cursor.lnum == curwin->w_topline
&& width > 0
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
/* Cursor past end of screen. Happens with a single line that does
* not fit on screen. Find a skipcol to show the text around the
@@ -859,19 +883,22 @@ void curs_columns(
}
else
n = p_lines;
- if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width)
+ if ((colnr_T)n >= curwin->w_grid.Rows + curwin->w_skipcol / width) {
extra += 2;
+ }
if (extra == 3 || p_lines < p_so * 2) {
- /* not enough room for 'scrolloff', put cursor in the middle */
+ // not enough room for 'scrolloff', put cursor in the middle
n = curwin->w_virtcol / width;
- if (n > curwin->w_height / 2)
- n -= curwin->w_height / 2;
- else
+ if (n > curwin->w_grid.Rows / 2) {
+ n -= curwin->w_grid.Rows / 2;
+ } else {
n = 0;
- /* don't skip more than necessary */
- if (n > p_lines - curwin->w_height + 1)
- n = p_lines - curwin->w_height + 1;
+ }
+ // don't skip more than necessary
+ if (n > p_lines - curwin->w_grid.Rows + 1) {
+ n = p_lines - curwin->w_grid.Rows + 1;
+ }
curwin->w_skipcol = n * width;
} else if (extra == 1) {
/* less then 'scrolloff' lines above, decrease skipcol */
@@ -884,27 +911,29 @@ void curs_columns(
curwin->w_skipcol -= extra * width;
}
} else if (extra == 2) {
- /* less then 'scrolloff' lines below, increase skipcol */
- endcol = (n - curwin->w_height + 1) * width;
- while (endcol > curwin->w_virtcol)
+ // less then 'scrolloff' lines below, increase skipcol
+ endcol = (n - curwin->w_grid.Rows + 1) * width;
+ while (endcol > curwin->w_virtcol) {
endcol -= width;
- if (endcol > curwin->w_skipcol)
+ }
+ if (endcol > curwin->w_skipcol) {
curwin->w_skipcol = endcol;
+ }
}
curwin->w_wrow -= curwin->w_skipcol / width;
- if (curwin->w_wrow >= curwin->w_height) {
- /* small window, make sure cursor is in it */
- extra = curwin->w_wrow - curwin->w_height + 1;
+ if (curwin->w_wrow >= curwin->w_grid.Rows) {
+ // small window, make sure cursor is in it
+ extra = curwin->w_wrow - curwin->w_grid.Rows + 1;
curwin->w_skipcol += extra * width;
curwin->w_wrow -= extra;
}
extra = ((int)prev_skipcol - (int)curwin->w_skipcol) / width;
if (extra > 0) {
- win_ins_lines(curwin, 0, extra, false, false);
+ win_ins_lines(curwin, 0, extra);
} else if (extra < 0) {
- win_del_lines(curwin, 0, -extra, false, false);
+ win_del_lines(curwin, 0, -extra);
}
} else {
curwin->w_skipcol = 0;
@@ -937,9 +966,9 @@ scrolldown (
validate_cursor(); /* w_wrow needs to be valid */
while (line_count-- > 0) {
if (curwin->w_topfill < diff_check(curwin, curwin->w_topline)
- && curwin->w_topfill < curwin->w_height - 1) {
- ++curwin->w_topfill;
- ++done;
+ && curwin->w_topfill < curwin->w_grid.Rows - 1) {
+ curwin->w_topfill++;
+ done++;
} else {
if (curwin->w_topline == 1)
break;
@@ -972,15 +1001,15 @@ scrolldown (
*/
int wrow = curwin->w_wrow;
if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
validate_virtcol();
validate_cheight();
wrow += curwin->w_cline_height - 1 -
- curwin->w_virtcol / curwin->w_width;
+ curwin->w_virtcol / curwin->w_grid.Columns;
}
bool moved = false;
- while (wrow >= curwin->w_height && curwin->w_cursor.lnum > 1) {
+ while (wrow >= curwin->w_grid.Rows && curwin->w_cursor.lnum > 1) {
linenr_T first;
if (hasFolding(curwin->w_cursor.lnum, &first, NULL)) {
--wrow;
@@ -1065,14 +1094,15 @@ check_topfill (
{
if (wp->w_topfill > 0) {
int n = plines_win_nofill(wp, wp->w_topline, true);
- if (wp->w_topfill + n > wp->w_height) {
+ if (wp->w_topfill + n > wp->w_grid.Rows) {
if (down && wp->w_topline > 1) {
--wp->w_topline;
wp->w_topfill = 0;
} else {
- wp->w_topfill = wp->w_height - n;
- if (wp->w_topfill < 0)
+ wp->w_topfill = wp->w_grid.Rows - n;
+ if (wp->w_topfill < 0) {
wp->w_topfill = 0;
+ }
}
}
}
@@ -1085,12 +1115,13 @@ check_topfill (
static void max_topfill(void)
{
int n = plines_nofill(curwin->w_topline);
- if (n >= curwin->w_height)
+ if (n >= curwin->w_grid.Rows) {
curwin->w_topfill = 0;
- else {
+ } else {
curwin->w_topfill = diff_check_fill(curwin, curwin->w_topline);
- if (curwin->w_topfill + n > curwin->w_height)
- curwin->w_topfill = curwin->w_height - n;
+ if (curwin->w_topfill + n > curwin->w_grid.Rows) {
+ curwin->w_topfill = curwin->w_grid.Rows - n;
+ }
}
}
@@ -1121,14 +1152,14 @@ void scrolldown_clamp(void)
else
end_row += plines_nofill(curwin->w_topline - 1);
if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
validate_cheight();
validate_virtcol();
end_row += curwin->w_cline_height - 1 -
- curwin->w_virtcol / curwin->w_width;
+ curwin->w_virtcol / curwin->w_grid.Columns;
}
- if (end_row < curwin->w_height - p_so) {
+ if (end_row < curwin->w_grid.Rows - p_so) {
if (can_fill) {
++curwin->w_topfill;
check_topfill(curwin, true);
@@ -1163,10 +1194,10 @@ void scrollup_clamp(void)
int start_row = curwin->w_wrow - plines_nofill(curwin->w_topline)
- curwin->w_topfill;
if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
validate_virtcol();
- start_row -= curwin->w_virtcol / curwin->w_width;
+ start_row -= curwin->w_virtcol / curwin->w_grid.Columns;
}
if (start_row >= p_so) {
if (curwin->w_topfill > 0)
@@ -1320,10 +1351,12 @@ void scroll_cursor_top(int min_scroll, int always)
else
used += plines(bot);
}
- if (used > curwin->w_height)
+ if (used > curwin->w_grid.Rows) {
break;
- if (top < curwin->w_topline)
+ }
+ if (top < curwin->w_topline) {
scrolled += i;
+ }
/*
* If scrolling is needed, scroll at least 'sj' lines.
@@ -1343,7 +1376,7 @@ void scroll_cursor_top(int min_scroll, int always)
* This makes sure we get the same position when using "k" and "j"
* in a small window.
*/
- if (used > curwin->w_height) {
+ if (used > curwin->w_grid.Rows) {
scroll_cursor_halfway(false);
} else {
/*
@@ -1377,10 +1410,10 @@ void scroll_cursor_top(int min_scroll, int always)
void set_empty_rows(win_T *wp, int used)
{
wp->w_filler_rows = 0;
- if (used == 0)
- wp->w_empty_rows = 0; /* single line that doesn't fit */
- else {
- wp->w_empty_rows = wp->w_height - used;
+ if (used == 0) {
+ wp->w_empty_rows = 0; // single line that doesn't fit
+ } else {
+ wp->w_empty_rows = wp->w_grid.Rows - used;
if (wp->w_botline <= wp->w_buffer->b_ml.ml_line_count) {
wp->w_filler_rows = diff_check_fill(wp, wp->w_botline);
if (wp->w_empty_rows > wp->w_filler_rows)
@@ -1423,8 +1456,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
curwin->w_topline = loff.lnum) {
loff.lnum = curwin->w_topline;
topline_back(&loff);
- if (loff.height == MAXCOL || used + loff.height > curwin->w_height)
+ if (loff.height == MAXCOL || used + loff.height > curwin->w_grid.Rows) {
break;
+ }
used += loff.height;
curwin->w_topfill = loff.fill;
}
@@ -1481,12 +1515,14 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
/* Add one line above */
topline_back(&loff);
- if (loff.height == MAXCOL)
+ if (loff.height == MAXCOL) {
used = MAXCOL;
- else
+ } else {
used += loff.height;
- if (used > curwin->w_height)
+ }
+ if (used > curwin->w_grid.Rows) {
break;
+ }
if (loff.lnum >= curwin->w_botline
&& (loff.lnum > curwin->w_botline
|| loff.fill <= fill_below_window)
@@ -1503,8 +1539,9 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
/* Add one line below */
botline_forw(&boff);
used += boff.height;
- if (used > curwin->w_height)
+ if (used > curwin->w_grid.Rows) {
break;
+ }
if (extra < (
mouse_dragging > 0 ? mouse_dragging - 1 :
p_so) || scrolled < min_scroll) {
@@ -1525,14 +1562,14 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
}
linenr_T line_count;
- /* curwin->w_empty_rows is larger, no need to scroll */
- if (scrolled <= 0)
+ // curwin->w_empty_rows is larger, no need to scroll
+ if (scrolled <= 0) {
line_count = 0;
- /* more than a screenfull, don't scroll but redraw */
- else if (used > curwin->w_height)
+ // more than a screenfull, don't scroll but redraw
+ } else if (used > curwin->w_grid.Rows) {
line_count = used;
- /* scroll minimal number of lines */
- else {
+ // scroll minimal number of lines
+ } else {
line_count = 0;
boff.fill = curwin->w_topfill;
boff.lnum = curwin->w_topline - 1;
@@ -1550,10 +1587,11 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
* Scroll up if the cursor is off the bottom of the screen a bit.
* Otherwise put it at 1/2 of the screen.
*/
- if (line_count >= curwin->w_height && line_count > min_scroll)
+ if (line_count >= curwin->w_grid.Rows && line_count > min_scroll) {
scroll_cursor_halfway(false);
- else
+ } else {
scrollup(line_count, true);
+ }
/*
* If topline didn't change we need to restore w_botline and w_empty_rows
@@ -1592,8 +1630,9 @@ void scroll_cursor_halfway(int atend)
if (boff.lnum < curbuf->b_ml.ml_line_count) {
botline_forw(&boff);
used += boff.height;
- if (used > curwin->w_height)
+ if (used > curwin->w_grid.Rows) {
break;
+ }
below += boff.height;
} else {
++below; /* count a "~" line */
@@ -1608,8 +1647,9 @@ void scroll_cursor_halfway(int atend)
used = MAXCOL;
else
used += loff.height;
- if (used > curwin->w_height)
+ if (used > curwin->w_grid.Rows) {
break;
+ }
above += loff.height;
topline = loff.lnum;
topfill = loff.fill;
@@ -1618,8 +1658,9 @@ void scroll_cursor_halfway(int atend)
if (!hasFolding(topline, &curwin->w_topline, NULL))
curwin->w_topline = topline;
curwin->w_topfill = topfill;
- if (old_topline > curwin->w_topline + curwin->w_height)
+ if (old_topline > curwin->w_topline + curwin->w_grid.Rows) {
curwin->w_botfill = false;
+ }
check_topfill(curwin, false);
curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP);
curwin->w_valid |= VALID_TOPLINE;
@@ -1646,18 +1687,20 @@ void cursor_correct(void)
}
if (curwin->w_topline == 1) {
above_wanted = 0;
- int max_off = curwin->w_height / 2;
- if (below_wanted > max_off)
+ int max_off = curwin->w_grid.Rows / 2;
+ if (below_wanted > max_off) {
below_wanted = max_off;
+ }
}
validate_botline();
if (curwin->w_botline == curbuf->b_ml.ml_line_count + 1
&& mouse_dragging == 0
) {
below_wanted = 0;
- int max_off = (curwin->w_height - 1) / 2;
- if (above_wanted > max_off)
+ int max_off = (curwin->w_grid.Rows - 1) / 2;
+ if (above_wanted > max_off) {
above_wanted = max_off;
+ }
}
/*
@@ -1727,7 +1770,7 @@ void cursor_correct(void)
*
* return FAIL for failure, OK otherwise
*/
-int onepage(int dir, long count)
+int onepage(Direction dir, long count)
{
long n;
int retval = OK;
@@ -1761,7 +1804,7 @@ int onepage(int dir, long count)
loff.fill = 0;
if (dir == FORWARD) {
- if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1) {
+ if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
/* Vi compatible scrolling */
if (p_window <= 2)
++curwin->w_topline;
@@ -1795,7 +1838,7 @@ int onepage(int dir, long count)
max_topfill();
continue;
}
- if (firstwin == lastwin && p_window > 0 && p_window < Rows - 1) {
+ if (ONE_WINDOW && p_window > 0 && p_window < Rows - 1) {
/* Vi compatible scrolling (sort of) */
if (p_window <= 2)
--curwin->w_topline;
@@ -1828,7 +1871,7 @@ int onepage(int dir, long count)
/* Find the line just above the new topline to get the right line
* at the bottom of the window. */
n = 0;
- while (n <= curwin->w_height && loff.lnum >= 1) {
+ while (n <= curwin->w_grid.Rows && loff.lnum >= 1) {
topline_back(&loff);
if (loff.height == MAXCOL)
n = MAXCOL;
@@ -1879,20 +1922,24 @@ int onepage(int dir, long count)
}
foldAdjustCursor();
cursor_correct();
- if (retval == OK)
+ check_cursor_col();
+ if (retval == OK) {
beginline(BL_SOL | BL_FIX);
+ }
curwin->w_valid &= ~(VALID_WCOL|VALID_WROW|VALID_VIRTCOL);
- /*
- * Avoid the screen jumping up and down when 'scrolloff' is non-zero.
- * But make sure we scroll at least one line (happens with mix of long
- * wrapping lines and non-wrapping line).
- */
- if (retval == OK && dir == FORWARD && check_top_offset()) {
- scroll_cursor_top(1, false);
- if (curwin->w_topline <= old_topline
- && old_topline < curbuf->b_ml.ml_line_count) {
- curwin->w_topline = old_topline + 1;
+ if (retval == OK && dir == FORWARD) {
+ // Avoid the screen jumping up and down when 'scrolloff' is non-zero.
+ // But make sure we scroll at least one line (happens with mix of long
+ // wrapping lines and non-wrapping line).
+ if (check_top_offset()) {
+ scroll_cursor_top(1, false);
+ if (curwin->w_topline <= old_topline
+ && old_topline < curbuf->b_ml.ml_line_count) {
+ curwin->w_topline = old_topline + 1;
+ (void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
+ }
+ } else if (curwin->w_botline > curbuf->b_ml.ml_line_count) {
(void)hasFolding(curwin->w_topline, &curwin->w_topline, NULL);
}
}
@@ -1915,7 +1962,7 @@ int onepage(int dir, long count)
*/
static void get_scroll_overlap(lineoff_T *lp, int dir)
{
- int min_height = curwin->w_height - 2;
+ int min_height = curwin->w_grid.Rows - 2;
if (lp->fill > 0)
lp->height = 1;
@@ -1969,13 +2016,15 @@ void halfpage(bool flag, linenr_T Prenum)
long scrolled = 0;
int i;
- if (Prenum)
- curwin->w_p_scr = (Prenum > curwin->w_height) ?
- curwin->w_height : Prenum;
+ if (Prenum) {
+ curwin->w_p_scr = (Prenum > curwin->w_grid.Rows) ? curwin->w_grid.Rows
+ : Prenum;
+ }
assert(curwin->w_p_scr <= INT_MAX);
- int n = curwin->w_p_scr <= curwin->w_height ? (int)curwin->w_p_scr
- : curwin->w_height;
+ int n = curwin->w_p_scr <= curwin->w_grid.Rows ? (int)curwin->w_p_scr
+ : curwin->w_grid.Rows;
+ update_topline();
validate_botline();
int room = curwin->w_empty_rows + curwin->w_filler_rows;
if (flag) {
@@ -1985,9 +2034,8 @@ void halfpage(bool flag, linenr_T Prenum)
while (n > 0 && curwin->w_botline <= curbuf->b_ml.ml_line_count) {
if (curwin->w_topfill > 0) {
i = 1;
- if (--n < 0 && scrolled > 0)
- break;
- --curwin->w_topfill;
+ n--;
+ curwin->w_topfill--;
} else {
i = plines_nofill(curwin->w_topline);
n -= i;
@@ -2063,9 +2111,8 @@ void halfpage(bool flag, linenr_T Prenum)
while (n > 0 && curwin->w_topline > 1) {
if (curwin->w_topfill < diff_check_fill(curwin, curwin->w_topline)) {
i = 1;
- if (--n < 0 && scrolled > 0)
- break;
- ++curwin->w_topfill;
+ n--;
+ curwin->w_topfill++;
} else {
i = plines_nofill(curwin->w_topline - 1);
n -= i;
@@ -2138,18 +2185,17 @@ void do_check_cursorbind(void)
* loop through the cursorbound windows
*/
VIsual_select = VIsual_active = 0;
- for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ curwin = wp;
curbuf = curwin->w_buffer;
/* skip original window and windows with 'noscrollbind' */
if (curwin != old_curwin && curwin->w_p_crb) {
- if (curwin->w_p_diff)
- curwin->w_cursor.lnum
- = diff_get_corresponding_line(old_curbuf,
- line,
- curbuf,
- curwin->w_cursor.lnum);
- else
+ if (curwin->w_p_diff) {
+ curwin->w_cursor.lnum =
+ diff_get_corresponding_line(old_curbuf, line);
+ } else {
curwin->w_cursor.lnum = line;
+ }
curwin->w_cursor.col = col;
curwin->w_cursor.coladd = coladd;
curwin->w_curswant = curswant;
@@ -2161,16 +2207,19 @@ void do_check_cursorbind(void)
int restart_edit_save = restart_edit;
restart_edit = true;
check_cursor();
+ if (win_cursorline_standout(curwin) || curwin->w_p_cuc) {
+ validate_cursor();
+ }
restart_edit = restart_edit_save;
}
- /* Correct cursor for multi-byte character. */
- if (has_mbyte)
- mb_adjust_cursor();
+ // Correct cursor for multi-byte character.
+ mb_adjust_cursor();
redraw_later(VALID);
- /* Only scroll when 'scrollbind' hasn't done this. */
- if (!curwin->w_p_scb)
+ // Only scroll when 'scrollbind' hasn't done this.
+ if (!curwin->w_p_scb) {
update_topline();
+ }
curwin->w_redr_status = true;
}
}
diff --git a/src/nvim/move.h b/src/nvim/move.h
index 3f3bf70929..3670dc9086 100644
--- a/src/nvim/move.h
+++ b/src/nvim/move.h
@@ -2,6 +2,7 @@
#define NVIM_MOVE_H
#include <stdbool.h>
+#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "move.h.generated.h"
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 5b249ee1c7..76fbe407c2 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.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 <stdbool.h>
#include <string.h>
#include <inttypes.h>
@@ -8,6 +11,7 @@
#include "nvim/api/private/helpers.h"
#include "nvim/api/vim.h"
#include "nvim/api/ui.h"
+#include "nvim/channel.h"
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/event/loop.h"
#include "nvim/event/libuv_process.h"
@@ -19,68 +23,20 @@
#include "nvim/main.h"
#include "nvim/ascii.h"
#include "nvim/memory.h"
+#include "nvim/eval.h"
#include "nvim/os_unix.h"
#include "nvim/message.h"
#include "nvim/map.h"
#include "nvim/log.h"
#include "nvim/misc1.h"
#include "nvim/lib/kvec.h"
-
-#define CHANNEL_BUFFER_SIZE 0xffff
+#include "nvim/os/input.h"
#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
#define log_client_msg(...)
#define log_server_msg(...)
#endif
-typedef enum {
- kChannelTypeSocket,
- kChannelTypeProc,
- kChannelTypeStdio
-} ChannelType;
-
-typedef struct {
- uint64_t request_id;
- bool returned, errored;
- Object result;
-} ChannelCallFrame;
-
-typedef struct {
- uint64_t id;
- size_t refcount;
- size_t pending_requests;
- PMap(cstr_t) *subscribed_events;
- bool closed;
- ChannelType type;
- msgpack_unpacker *unpacker;
- union {
- Stream stream;
- struct {
- LibuvProcess uvproc;
- Stream in;
- Stream out;
- Stream err;
- } process;
- struct {
- Stream in;
- Stream out;
- } std;
- } data;
- uint64_t next_request_id;
- kvec_t(ChannelCallFrame *) call_stack;
- kvec_t(WBuffer *) delayed_notifications;
- Queue *events;
-} Channel;
-
-typedef struct {
- Channel *channel;
- MsgpackRpcRequestHandler handler;
- Array args;
- uint64_t request_id;
-} RequestEvent;
-
-static uint64_t next_id = 1;
-static PMap(uint64_t) *channels = NULL;
static PMap(cstr_t) *event_strings = NULL;
static msgpack_sbuffer out_buffer;
@@ -88,104 +44,65 @@ static msgpack_sbuffer out_buffer;
# include "msgpack_rpc/channel.c.generated.h"
#endif
-/// Initializes the module
-void channel_init(void)
+void rpc_init(void)
{
- channels = pmap_new(uint64_t)();
+ ch_before_blocking_events = multiqueue_new_child(main_loop.events);
event_strings = pmap_new(cstr_t)();
msgpack_sbuffer_init(&out_buffer);
- remote_ui_init();
}
-/// Teardown the module
-void channel_teardown(void)
+
+void rpc_start(Channel *channel)
{
- if (!channels) {
- return;
- }
+ channel_incref(channel);
+ channel->is_rpc = true;
+ RpcState *rpc = &channel->rpc;
+ rpc->closed = false;
+ rpc->unpacker = msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
+ rpc->subscribed_events = pmap_new(cstr_t)();
+ rpc->next_request_id = 1;
+ rpc->info = (Dictionary)ARRAY_DICT_INIT;
+ kv_init(rpc->call_stack);
- Channel *channel;
+ if (channel->streamtype != kChannelStreamInternal) {
+ Stream *out = channel_outstream(channel);
+#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
+ Stream *in = channel_instream(channel);
+ DLOG("rpc ch %" PRIu64 " in-stream=%p out-stream=%p", channel->id, in, out);
+#endif
- map_foreach_value(channels, channel, {
- close_channel(channel);
- });
+ rstream_start(out, receive_msgpack, channel);
+ }
}
-/// Creates an API channel by starting a process and connecting to its
-/// stdin/stdout. stderr is forwarded to the editor error stream.
-///
-/// @param argv The argument vector for the process. [consumed]
-/// @return The channel id (> 0), on success.
-/// 0, on error.
-uint64_t channel_from_process(char **argv)
-{
- Channel *channel = register_channel(kChannelTypeProc);
- channel->data.process.uvproc = libuv_process_init(&main_loop, channel);
- Process *proc = &channel->data.process.uvproc.process;
- proc->argv = argv;
- proc->in = &channel->data.process.in;
- proc->out = &channel->data.process.out;
- proc->err = &channel->data.process.err;
- proc->cb = process_exit;
- if (!process_spawn(proc)) {
- loop_poll_events(&main_loop, 0);
- decref(channel);
- return 0;
- }
-
- incref(channel); // process channels are only closed by the exit_cb
- wstream_init(proc->in, 0);
- rstream_init(proc->out, 0);
- rstream_start(proc->out, parse_msgpack);
- rstream_init(proc->err, 0);
- rstream_start(proc->err, forward_stderr);
-
- return channel->id;
-}
-
-/// Creates an API channel from a tcp/pipe socket connection
-///
-/// @param watcher The SocketWatcher ready to accept the connection
-void channel_from_connection(SocketWatcher *watcher)
+
+static Channel *find_rpc_channel(uint64_t id)
{
- Channel *channel = register_channel(kChannelTypeSocket);
- socket_watcher_accept(watcher, &channel->data.stream, channel);
- incref(channel); // close channel only after the stream is closed
- channel->data.stream.internal_close_cb = close_cb;
- channel->data.stream.internal_data = channel;
- wstream_init(&channel->data.stream, 0);
- rstream_init(&channel->data.stream, CHANNEL_BUFFER_SIZE);
- rstream_start(&channel->data.stream, parse_msgpack);
+ Channel *chan = find_channel(id);
+ if (!chan || !chan->is_rpc || chan->rpc.closed) {
+ return NULL;
+ }
+ return chan;
}
-/// Sends event/arguments to channel
+/// Publishes an event to a channel.
///
-/// @param id The channel id. If 0, the event will be sent to all
-/// channels that have subscribed to the event type
-/// @param name The event name, an arbitrary string
-/// @param args Array with event arguments
+/// @param id Channel id. 0 means "broadcast to all subscribed channels"
+/// @param name Event name (application-defined)
+/// @param args Array of event arguments
/// @return True if the event was sent successfully, false otherwise.
-bool channel_send_event(uint64_t id, char *name, Array args)
+bool rpc_send_event(uint64_t id, const char *name, Array args)
{
Channel *channel = NULL;
- if (id && (!(channel = pmap_get(uint64_t)(channels, id))
- || channel->closed)) {
+ if (id && (!(channel = find_rpc_channel(id)))) {
api_free_array(args);
return false;
}
if (channel) {
- if (channel->pending_requests) {
- // Pending request, queue the notification for later sending.
- String method = cstr_as_string(name);
- WBuffer *buffer = serialize_request(id, 0, method, args, &out_buffer, 1);
- kv_push(channel->delayed_notifications, buffer);
- } else {
- send_event(channel, name, args);
- }
+ send_event(channel, name, args);
} else {
- // TODO(tarruda): Implement event broadcasting in vimscript
broadcast_event(name, args);
}
@@ -199,35 +116,35 @@ bool channel_send_event(uint64_t id, char *name, Array args)
/// @param args Array with method arguments
/// @param[out] error True if the return value is an error
/// @return Whatever the remote method returned
-Object channel_send_call(uint64_t id,
- char *method_name,
- Array args,
- Error *err)
+Object rpc_send_call(uint64_t id,
+ const char *method_name,
+ Array args,
+ Error *err)
{
Channel *channel = NULL;
- if (!(channel = pmap_get(uint64_t)(channels, id)) || channel->closed) {
- api_set_error(err, Exception, _("Invalid channel \"%" PRIu64 "\""), id);
+ if (!(channel = find_rpc_channel(id))) {
+ api_set_error(err, kErrorTypeException, "Invalid channel: %" PRIu64, id);
api_free_array(args);
return NIL;
}
- incref(channel);
- uint64_t request_id = channel->next_request_id++;
+ channel_incref(channel);
+ RpcState *rpc = &channel->rpc;
+ uint64_t request_id = rpc->next_request_id++;
// Send the msgpack-rpc request
send_request(channel, request_id, method_name, args);
// Push the frame
ChannelCallFrame frame = { request_id, false, false, NIL };
- kv_push(channel->call_stack, &frame);
- channel->pending_requests++;
+ kv_push(rpc->call_stack, &frame);
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, channel->events, -1, frame.returned);
- (void)kv_pop(channel->call_stack);
- channel->pending_requests--;
+ (void)kv_pop(rpc->call_stack);
if (frame.errored) {
if (frame.result.type == kObjectTypeString) {
- api_set_error(err, Exception, "%s", frame.result.data.string.data);
+ api_set_error(err, kErrorTypeException, "%s",
+ frame.result.data.string.data);
} else if (frame.result.type == kObjectTypeArray) {
// Should be an error in the form [type, message]
Array array = frame.result.data.array;
@@ -235,24 +152,19 @@ Object channel_send_call(uint64_t id,
&& (array.items[0].data.integer == kErrorTypeException
|| array.items[0].data.integer == kErrorTypeValidation)
&& array.items[1].type == kObjectTypeString) {
- err->type = (ErrorType) array.items[0].data.integer;
- xstrlcpy(err->msg, array.items[1].data.string.data, sizeof(err->msg));
- err->set = true;
+ api_set_error(err, (ErrorType)array.items[0].data.integer, "%s",
+ array.items[1].data.string.data);
} else {
- api_set_error(err, Exception, "%s", "unknown error");
+ api_set_error(err, kErrorTypeException, "%s", "unknown error");
}
} else {
- api_set_error(err, Exception, "%s", "unknown error");
+ api_set_error(err, kErrorTypeException, "%s", "unknown error");
}
api_free_object(frame.result);
}
- if (!channel->pending_requests) {
- send_delayed_notifications(channel);
- }
-
- decref(channel);
+ channel_decref(channel);
return frame.errored ? NIL : frame.result;
}
@@ -261,11 +173,11 @@ Object channel_send_call(uint64_t id,
///
/// @param id The channel id
/// @param event The event type string
-void channel_subscribe(uint64_t id, char *event)
+void rpc_subscribe(uint64_t id, char *event)
{
Channel *channel;
- if (!(channel = pmap_get(uint64_t)(channels, id)) || channel->closed) {
+ if (!(channel = find_rpc_channel(id))) {
abort();
}
@@ -276,99 +188,63 @@ void channel_subscribe(uint64_t id, char *event)
pmap_put(cstr_t)(event_strings, event_string, event_string);
}
- pmap_put(cstr_t)(channel->subscribed_events, event_string, event_string);
+ pmap_put(cstr_t)(channel->rpc.subscribed_events, event_string, event_string);
}
/// Unsubscribes to event broadcasts
///
/// @param id The channel id
/// @param event The event type string
-void channel_unsubscribe(uint64_t id, char *event)
+void rpc_unsubscribe(uint64_t id, char *event)
{
Channel *channel;
- if (!(channel = pmap_get(uint64_t)(channels, id)) || channel->closed) {
+ if (!(channel = find_rpc_channel(id))) {
abort();
}
unsubscribe(channel, event);
}
-/// Closes a channel
-///
-/// @param id The channel id
-/// @return true if successful, false otherwise
-bool channel_close(uint64_t id)
-{
- Channel *channel;
-
- if (!(channel = pmap_get(uint64_t)(channels, id)) || channel->closed) {
- return false;
- }
-
- close_channel(channel);
- return true;
-}
-
-/// Creates an API channel from stdin/stdout. This is used when embedding
-/// Neovim
-void channel_from_stdio(void)
-{
- Channel *channel = register_channel(kChannelTypeStdio);
- incref(channel); // stdio channels are only closed on exit
- // read stream
- rstream_init_fd(&main_loop, &channel->data.std.in, 0, CHANNEL_BUFFER_SIZE,
- channel);
- rstream_start(&channel->data.std.in, parse_msgpack);
- // write stream
- wstream_init_fd(&main_loop, &channel->data.std.out, 1, 0, NULL);
-}
-
-static void forward_stderr(Stream *stream, RBuffer *rbuf, size_t count,
- void *data, bool eof)
-{
- while (rbuffer_size(rbuf)) {
- char buf[256];
- size_t read = rbuffer_read(rbuf, buf, sizeof(buf) - 1);
- buf[read] = NUL;
- ELOG("Channel %" PRIu64 " stderr: %s", ((Channel *)data)->id, buf);
- }
-}
-
-static void process_exit(Process *proc, int status, void *data)
-{
- decref(data);
-}
-
-static void parse_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data,
- bool eof)
+static void receive_msgpack(Stream *stream, RBuffer *rbuf, size_t c,
+ void *data, bool eof)
{
Channel *channel = data;
- incref(channel);
+ channel_incref(channel);
if (eof) {
- close_channel(channel);
- call_set_error(channel, "Channel was closed by the client");
+ channel_close(channel->id, kChannelPartRpc, NULL);
+ char buf[256];
+ snprintf(buf, sizeof(buf), "ch %" PRIu64 " was closed by the client",
+ channel->id);
+ call_set_error(channel, buf, WARN_LOG_LEVEL);
goto end;
}
size_t count = rbuffer_size(rbuf);
- DLOG("Feeding the msgpack parser with %u bytes of data from Stream(%p)",
- count,
- stream);
+ DLOG("ch %" PRIu64 ": parsing %zu bytes from msgpack Stream: %p",
+ channel->id, count, stream);
// Feed the unpacker with data
- msgpack_unpacker_reserve_buffer(channel->unpacker, count);
- rbuffer_read(rbuf, msgpack_unpacker_buffer(channel->unpacker), count);
- msgpack_unpacker_buffer_consumed(channel->unpacker, count);
+ msgpack_unpacker_reserve_buffer(channel->rpc.unpacker, count);
+ rbuffer_read(rbuf, msgpack_unpacker_buffer(channel->rpc.unpacker), count);
+ msgpack_unpacker_buffer_consumed(channel->rpc.unpacker, count);
+
+ parse_msgpack(channel);
+
+end:
+ channel_decref(channel);
+}
+static void parse_msgpack(Channel *channel)
+{
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
msgpack_unpack_return result;
// Deserialize everything we can.
- while ((result = msgpack_unpacker_next(channel->unpacker, &unpacked)) ==
- MSGPACK_UNPACK_SUCCESS) {
+ while ((result = msgpack_unpacker_next(channel->rpc.unpacker, &unpacked)) ==
+ MSGPACK_UNPACK_SUCCESS) {
bool is_response = is_rpc_response(&unpacked.data);
log_client_msg(channel->id, !is_response, unpacked.data);
@@ -377,17 +253,15 @@ static void parse_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data,
complete_call(&unpacked.data, channel);
} else {
char buf[256];
- snprintf(buf,
- sizeof(buf),
- "Channel %" PRIu64 " returned a response that doesn't have "
- "a matching request id. Ensure the client is properly "
- "synchronized",
+ snprintf(buf, sizeof(buf),
+ "ch %" PRIu64 " returned a response with an unknown request "
+ "id. Ensure the client is properly synchronized",
channel->id);
- call_set_error(channel, buf);
+ call_set_error(channel, buf, ERROR_LOG_LEVEL);
}
msgpack_unpacked_destroy(&unpacked);
// Bail out from this event loop iteration
- goto end;
+ return;
}
handle_request(channel, &unpacked.data);
@@ -396,7 +270,7 @@ static void parse_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data,
if (result == MSGPACK_UNPACK_NOMEM_ERROR) {
mch_errmsg(e_outofmem);
mch_errmsg("\n");
- decref(channel);
+ channel_decref(channel);
preserve_exit();
}
@@ -405,15 +279,12 @@ static void parse_msgpack(Stream *stream, RBuffer *rbuf, size_t c, void *data,
// causes for this error(search for 'goto _failed')
//
// A not so uncommon cause for this might be deserializing objects with
- // a high nesting level: msgpack will break when it's internal parse stack
- // size exceeds MSGPACK_EMBED_STACK_SIZE(defined as 32 by default)
+ // a high nesting level: msgpack will break when its internal parse stack
+ // size exceeds MSGPACK_EMBED_STACK_SIZE (defined as 32 by default)
send_error(channel, 0, "Invalid msgpack payload. "
"This error can also happen when deserializing "
"an object with high level of nesting");
}
-
-end:
- decref(channel);
}
static void handle_request(Channel *channel, msgpack_object *request)
@@ -423,7 +294,7 @@ static void handle_request(Channel *channel, msgpack_object *request)
Error error = ERROR_INIT;
msgpack_rpc_validate(&request_id, request, &error);
- if (error.set) {
+ if (ERROR_SET(&error)) {
// Validation failed, send response with error
if (channel_write(channel,
serialize_response(channel->id,
@@ -433,41 +304,53 @@ static void handle_request(Channel *channel, msgpack_object *request)
&out_buffer))) {
char buf[256];
snprintf(buf, sizeof(buf),
- "Channel %" PRIu64 " sent an invalid message, closed.",
+ "ch %" PRIu64 " sent an invalid message, closed.",
channel->id);
- call_set_error(channel, buf);
+ call_set_error(channel, buf, ERROR_LOG_LEVEL);
}
+ api_clear_error(&error);
return;
}
- // Retrieve the request handler
MsgpackRpcRequestHandler handler;
msgpack_object *method = msgpack_rpc_method(request);
+ handler = msgpack_rpc_get_handler_for(method->via.bin.ptr,
+ method->via.bin.size,
+ &error);
- if (method) {
- handler = msgpack_rpc_get_handler_for(method->via.bin.ptr,
- method->via.bin.size);
- } else {
- handler.fn = msgpack_rpc_handle_missing_method;
- handler.async = true;
+ // check method arguments
+ Array args = ARRAY_DICT_INIT;
+ if (!ERROR_SET(&error)
+ && !msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) {
+ api_set_error(&error, kErrorTypeException, "Invalid method arguments");
}
- Array args = ARRAY_DICT_INIT;
- if (!msgpack_rpc_to_array(msgpack_rpc_args(request), &args)) {
- handler.fn = msgpack_rpc_handle_invalid_arguments;
- handler.async = true;
+ if (ERROR_SET(&error)) {
+ send_error(channel, request_id, error.msg);
+ api_clear_error(&error);
+ api_free_array(args);
+ return;
}
- RequestEvent *event_data = xmalloc(sizeof(RequestEvent));
- event_data->channel = channel;
- event_data->handler = handler;
- event_data->args = args;
- event_data->request_id = request_id;
- incref(channel);
+ RequestEvent *evdata = xmalloc(sizeof(RequestEvent));
+ evdata->channel = channel;
+ evdata->handler = handler;
+ evdata->args = args;
+ evdata->request_id = request_id;
+ channel_incref(channel);
if (handler.async) {
- on_request_event((void **)&event_data);
+ bool is_get_mode = handler.fn == handle_nvim_get_mode;
+
+ if (is_get_mode && !input_blocking()) {
+ // Defer the event to a special queue used by os/input.c. #6247
+ multiqueue_put(ch_before_blocking_events, on_request_event, 1, evdata);
+ } else {
+ // Invoke immediately.
+ on_request_event((void **)&evdata);
+ }
} else {
- queue_put(channel->events, on_request_event, 1, event_data);
+ multiqueue_put(channel->events, on_request_event, 1, evdata);
+ DLOG("RPC: scheduled %.*s", method->via.bin.size, method->via.bin.ptr);
}
}
@@ -479,7 +362,7 @@ static void on_request_event(void **argv)
Array args = e->args;
uint64_t request_id = e->request_id;
Error error = ERROR_INIT;
- Object result = handler.fn(channel->id, request_id, args, &error);
+ Object result = handler.fn(channel->id, args, &error);
if (request_id != NO_RESPONSE) {
// send the response
msgpack_packer response;
@@ -492,66 +375,79 @@ static void on_request_event(void **argv)
} else {
api_free_object(result);
}
- // All arguments were freed already, but we still need to free the array
- xfree(args.items);
- decref(channel);
+ api_free_array(args);
+ channel_decref(channel);
xfree(e);
+ api_clear_error(&error);
}
static bool channel_write(Channel *channel, WBuffer *buffer)
{
bool success;
- if (channel->closed) {
+ if (channel->rpc.closed) {
wstream_release_wbuffer(buffer);
return false;
}
- switch (channel->type) {
- case kChannelTypeSocket:
- success = wstream_write(&channel->data.stream, buffer);
- break;
- case kChannelTypeProc:
- success = wstream_write(&channel->data.process.in, buffer);
- break;
- case kChannelTypeStdio:
- success = wstream_write(&channel->data.std.out, buffer);
- break;
- default:
- abort();
+ if (channel->streamtype == kChannelStreamInternal) {
+ channel_incref(channel);
+ CREATE_EVENT(channel->events, internal_read_event, 2, channel, buffer);
+ success = true;
+ } else {
+ Stream *in = channel_instream(channel);
+ success = wstream_write(in, buffer);
}
+
if (!success) {
// If the write failed for any reason, close the channel
char buf[256];
snprintf(buf,
sizeof(buf),
- "Before returning from a RPC call, channel %" PRIu64 " was "
- "closed due to a failed write",
+ "ch %" PRIu64 ": stream write failed. "
+ "RPC canceled; closing channel",
channel->id);
- call_set_error(channel, buf);
+ call_set_error(channel, buf, ERROR_LOG_LEVEL);
}
return success;
}
+static void internal_read_event(void **argv)
+{
+ Channel *channel = argv[0];
+ WBuffer *buffer = argv[1];
+
+ msgpack_unpacker_reserve_buffer(channel->rpc.unpacker, buffer->size);
+ memcpy(msgpack_unpacker_buffer(channel->rpc.unpacker),
+ buffer->data, buffer->size);
+ msgpack_unpacker_buffer_consumed(channel->rpc.unpacker, buffer->size);
+
+ parse_msgpack(channel);
+
+ channel_decref(channel);
+ wstream_release_wbuffer(buffer);
+}
+
static void send_error(Channel *channel, uint64_t id, char *err)
{
Error e = ERROR_INIT;
- api_set_error(&e, Exception, "%s", err);
+ api_set_error(&e, kErrorTypeException, "%s", err);
channel_write(channel, serialize_response(channel->id,
id,
&e,
NIL,
&out_buffer));
+ api_clear_error(&e);
}
static void send_request(Channel *channel,
uint64_t id,
- char *name,
+ const char *name,
Array args)
{
- String method = {.size = strlen(name), .data = name};
+ const String method = cstr_as_string((char *)name);
channel_write(channel, serialize_request(channel->id,
id,
method,
@@ -561,10 +457,10 @@ static void send_request(Channel *channel,
}
static void send_event(Channel *channel,
- char *name,
+ const char *name,
Array args)
{
- String method = {.size = strlen(name), .data = name};
+ const String method = cstr_as_string((char *)name);
channel_write(channel, serialize_request(channel->id,
0,
method,
@@ -573,13 +469,14 @@ static void send_event(Channel *channel,
1));
}
-static void broadcast_event(char *name, Array args)
+static void broadcast_event(const char *name, Array args)
{
kvec_t(Channel *) subscribed = KV_INITIAL_VALUE;
Channel *channel;
map_foreach_value(channels, channel, {
- if (pmap_has(cstr_t)(channel->subscribed_events, name)) {
+ if (channel->is_rpc
+ && pmap_has(cstr_t)(channel->rpc.subscribed_events, name)) {
kv_push(subscribed, channel);
}
});
@@ -589,7 +486,7 @@ static void broadcast_event(char *name, Array args)
goto end;
}
- String method = {.size = strlen(name), .data = name};
+ const String method = cstr_as_string((char *)name);
WBuffer *buffer = serialize_request(0,
0,
method,
@@ -598,12 +495,8 @@ static void broadcast_event(char *name, Array args)
kv_size(subscribed));
for (size_t i = 0; i < kv_size(subscribed); i++) {
- Channel *channel = kv_A(subscribed, i);
- if (channel->pending_requests) {
- kv_push(channel->delayed_notifications, buffer);
- } else {
- channel_write(channel, buffer);
- }
+ Channel *c = kv_A(subscribed, i);
+ channel_write(c, buffer);
}
end:
@@ -613,10 +506,16 @@ end:
static void unsubscribe(Channel *channel, char *event)
{
char *event_string = pmap_get(cstr_t)(event_strings, event);
- pmap_del(cstr_t)(channel->subscribed_events, event_string);
+ if (!event_string) {
+ WLOG("RPC: ch %" PRIu64 ": tried to unsubscribe unknown event '%s'",
+ channel->id, event);
+ return;
+ }
+ pmap_del(cstr_t)(channel->rpc.subscribed_events, event_string);
map_foreach_value(channels, channel, {
- if (pmap_has(cstr_t)(channel->subscribed_events, event_string)) {
+ if (channel->is_rpc
+ && pmap_has(cstr_t)(channel->rpc.subscribed_events, event_string)) {
return;
}
});
@@ -626,85 +525,44 @@ static void unsubscribe(Channel *channel, char *event)
xfree(event_string);
}
-/// Close the channel streams/process and free the channel resources.
-static void close_channel(Channel *channel)
+
+/// Mark rpc state as closed, and release its reference to the channel.
+/// Don't call this directly, call channel_close(id, kChannelPartRpc, &error)
+void rpc_close(Channel *channel)
{
- if (channel->closed) {
+ if (channel->rpc.closed) {
return;
}
- channel->closed = true;
+ channel->rpc.closed = true;
+ channel_decref(channel);
- switch (channel->type) {
- case kChannelTypeSocket:
- stream_close(&channel->data.stream, NULL);
- break;
- case kChannelTypeProc:
- if (!channel->data.process.uvproc.process.closed) {
- process_stop(&channel->data.process.uvproc.process);
- }
- break;
- case kChannelTypeStdio:
- stream_close(&channel->data.std.in, NULL);
- stream_close(&channel->data.std.out, NULL);
- queue_put(main_loop.fast_events, exit_event, 1, channel);
- return;
- default:
- abort();
+ if (channel->streamtype == kChannelStreamStdio) {
+ multiqueue_put(main_loop.fast_events, exit_event, 0);
}
-
- decref(channel);
}
static void exit_event(void **argv)
{
- decref(argv[0]);
-
if (!exiting) {
mch_exit(0);
}
}
-static void free_channel(Channel *channel)
+void rpc_free(Channel *channel)
{
remote_ui_disconnect(channel->id);
- pmap_del(uint64_t)(channels, channel->id);
- msgpack_unpacker_free(channel->unpacker);
+ msgpack_unpacker_free(channel->rpc.unpacker);
// Unsubscribe from all events
char *event_string;
- map_foreach_value(channel->subscribed_events, event_string, {
+ map_foreach_value(channel->rpc.subscribed_events, event_string, {
unsubscribe(channel, event_string);
});
- pmap_free(cstr_t)(channel->subscribed_events);
- kv_destroy(channel->call_stack);
- kv_destroy(channel->delayed_notifications);
- queue_free(channel->events);
- xfree(channel);
-}
-
-static void close_cb(Stream *stream, void *data)
-{
- decref(data);
-}
-
-static Channel *register_channel(ChannelType type)
-{
- Channel *rv = xmalloc(sizeof(Channel));
- rv->events = queue_new_child(main_loop.events);
- rv->type = type;
- rv->refcount = 1;
- rv->closed = false;
- rv->unpacker = msgpack_unpacker_new(MSGPACK_UNPACKER_INIT_BUFFER_SIZE);
- rv->id = next_id++;
- rv->pending_requests = 0;
- rv->subscribed_events = pmap_new(cstr_t)();
- rv->next_request_id = 1;
- kv_init(rv->call_stack);
- kv_init(rv->delayed_notifications);
- pmap_put(uint64_t)(channels, rv->id, rv);
- return rv;
+ pmap_free(cstr_t)(channel->rpc.subscribed_events);
+ kv_destroy(channel->rpc.call_stack);
+ api_free_dictionary(channel->rpc.info);
}
static bool is_rpc_response(msgpack_object *obj)
@@ -719,15 +577,18 @@ static bool is_rpc_response(msgpack_object *obj)
static bool is_valid_rpc_response(msgpack_object *obj, Channel *channel)
{
uint64_t response_id = obj->via.array.ptr[1].via.u64;
+ if (kv_size(channel->rpc.call_stack) == 0) {
+ return false;
+ }
+
// Must be equal to the frame at the stack's bottom
- return kv_size(channel->call_stack) && response_id
- == kv_A(channel->call_stack, kv_size(channel->call_stack) - 1)->request_id;
+ ChannelCallFrame *frame = kv_last(channel->rpc.call_stack);
+ return response_id == frame->request_id;
}
static void complete_call(msgpack_object *obj, Channel *channel)
{
- ChannelCallFrame *frame = kv_A(channel->call_stack,
- kv_size(channel->call_stack) - 1);
+ ChannelCallFrame *frame = kv_last(channel->rpc.call_stack);
frame->returned = true;
frame->errored = obj->via.array.ptr[2].type != MSGPACK_OBJECT_NIL;
@@ -738,22 +599,23 @@ static void complete_call(msgpack_object *obj, Channel *channel)
}
}
-static void call_set_error(Channel *channel, char *msg)
+static void call_set_error(Channel *channel, char *msg, int loglevel)
{
- ELOG("msgpack-rpc: %s", msg);
- for (size_t i = 0; i < kv_size(channel->call_stack); i++) {
- ChannelCallFrame *frame = kv_A(channel->call_stack, i);
+ LOG(loglevel, "RPC: %s", msg);
+ for (size_t i = 0; i < kv_size(channel->rpc.call_stack); i++) {
+ ChannelCallFrame *frame = kv_A(channel->rpc.call_stack, i);
frame->returned = true;
frame->errored = true;
+ api_free_object(frame->result);
frame->result = STRING_OBJ(cstr_to_string(msg));
}
- close_channel(channel);
+ channel_close(channel->id, kChannelPartRpc, NULL);
}
static WBuffer *serialize_request(uint64_t channel_id,
uint64_t request_id,
- String method,
+ const String method,
Array args,
msgpack_sbuffer *sbuffer,
size_t refcount)
@@ -779,7 +641,16 @@ static WBuffer *serialize_response(uint64_t channel_id,
{
msgpack_packer pac;
msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write);
- msgpack_rpc_serialize_response(response_id, err, arg, &pac);
+ if (ERROR_SET(err) && response_id == NO_RESPONSE) {
+ Array args = ARRAY_DICT_INIT;
+ ADD(args, INTEGER_OBJ(err->type));
+ ADD(args, STRING_OBJ(cstr_to_string(err->msg)));
+ msgpack_rpc_serialize_request(0, cstr_as_string("nvim_error_event"),
+ args, &pac);
+ api_free_array(args);
+ } else {
+ msgpack_rpc_serialize_response(response_id, err, arg, &pac);
+ }
log_server_msg(channel_id, sbuffer);
WBuffer *rv = wstream_new_buffer(xmemdup(sbuffer->data, sbuffer->size),
sbuffer->size,
@@ -790,33 +661,28 @@ static WBuffer *serialize_response(uint64_t channel_id,
return rv;
}
-static void send_delayed_notifications(Channel* channel)
+void rpc_set_client_info(uint64_t id, Dictionary info)
{
- for (size_t i = 0; i < kv_size(channel->delayed_notifications); i++) {
- WBuffer *buffer = kv_A(channel->delayed_notifications, i);
- channel_write(channel, buffer);
+ Channel *chan = find_rpc_channel(id);
+ if (!chan) {
+ abort();
}
- kv_size(channel->delayed_notifications) = 0;
-}
-
-static void incref(Channel *channel)
-{
- channel->refcount++;
+ api_free_dictionary(chan->rpc.info);
+ chan->rpc.info = info;
+ channel_info_changed(chan, false);
}
-static void decref(Channel *channel)
+Dictionary rpc_client_info(Channel *chan)
{
- if (!(--channel->refcount)) {
- free_channel(channel);
- }
+ return copy_dictionary(chan->rpc.info);
}
#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
-#define REQ "[request] "
-#define RES "[response] "
-#define NOT "[notification] "
-#define ERR "[error] "
+#define REQ "[request] "
+#define RES "[response] "
+#define NOT "[notify] "
+#define ERR "[error] "
// Cannot define array with negative offsets, so this one is needed to be added
// to MSGPACK_UNPACK_\* values.
@@ -834,7 +700,7 @@ static void log_server_msg(uint64_t channel_id,
{
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
- DLOGN("[msgpack-rpc] nvim -> client(%" PRIu64 ") ", channel_id);
+ DLOGN("RPC ->ch %" PRIu64 ": ", channel_id);
const msgpack_unpack_return result =
msgpack_unpack_next(&unpacked, packed->data, packed->size, NULL);
switch (result) {
@@ -871,7 +737,7 @@ static void log_client_msg(uint64_t channel_id,
bool is_request,
msgpack_object msg)
{
- DLOGN("[msgpack-rpc] client(%" PRIu64 ") -> nvim ", channel_id);
+ DLOGN("RPC <-ch %" PRIu64 ": ", channel_id);
log_lock();
FILE *f = open_log_file();
fprintf(f, is_request ? REQ : RES);
@@ -887,4 +753,3 @@ static void log_msg_close(FILE *f, msgpack_object msg)
log_unlock();
}
#endif
-
diff --git a/src/nvim/msgpack_rpc/channel.h b/src/nvim/msgpack_rpc/channel.h
index 104547a7b8..9ff5abdc5f 100644
--- a/src/nvim/msgpack_rpc/channel.h
+++ b/src/nvim/msgpack_rpc/channel.h
@@ -6,10 +6,18 @@
#include "nvim/api/private/defs.h"
#include "nvim/event/socket.h"
+#include "nvim/event/process.h"
#include "nvim/vim.h"
+#include "nvim/channel.h"
#define METHOD_MAXLEN 512
+/// HACK: os/input.c drains this queue immediately before blocking for input.
+/// Events on this queue are async-safe, but they need the resolved state
+/// of os_inchar(), so they are processed "just-in-time".
+MultiQueue *ch_before_blocking_events;
+
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/channel.h.generated.h"
#endif
diff --git a/src/nvim/msgpack_rpc/channel_defs.h b/src/nvim/msgpack_rpc/channel_defs.h
new file mode 100644
index 0000000000..bfa7f7b87c
--- /dev/null
+++ b/src/nvim/msgpack_rpc/channel_defs.h
@@ -0,0 +1,37 @@
+#ifndef NVIM_MSGPACK_RPC_CHANNEL_DEFS_H
+#define NVIM_MSGPACK_RPC_CHANNEL_DEFS_H
+
+#include <stdbool.h>
+#include <uv.h>
+#include <msgpack.h>
+
+#include "nvim/api/private/defs.h"
+#include "nvim/event/socket.h"
+#include "nvim/event/process.h"
+#include "nvim/vim.h"
+
+typedef struct Channel Channel;
+
+typedef struct {
+ uint64_t request_id;
+ bool returned, errored;
+ Object result;
+} ChannelCallFrame;
+
+typedef struct {
+ Channel *channel;
+ MsgpackRpcRequestHandler handler;
+ Array args;
+ uint64_t request_id;
+} RequestEvent;
+
+typedef struct {
+ PMap(cstr_t) *subscribed_events;
+ bool closed;
+ msgpack_unpacker *unpacker;
+ uint64_t next_request_id;
+ kvec_t(ChannelCallFrame *) call_stack;
+ Dictionary info;
+} RpcState;
+
+#endif // NVIM_MSGPACK_RPC_CHANNEL_DEFS_H
diff --git a/src/nvim/msgpack_rpc/defs.h b/src/nvim/msgpack_rpc/defs.h
deleted file mode 100644
index 5611636d4f..0000000000
--- a/src/nvim/msgpack_rpc/defs.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef NVIM_MSGPACK_RPC_DEFS_H
-#define NVIM_MSGPACK_RPC_DEFS_H
-
-
-/// The rpc_method_handlers table, used in msgpack_rpc_dispatch(), stores
-/// functions of this type.
-typedef struct {
- Object (*fn)(uint64_t channel_id,
- uint64_t request_id,
- Array args,
- Error *error);
- bool async; // function is always safe to run immediately instead of being
- // put in a request queue for handling when nvim waits for input.
-} MsgpackRpcRequestHandler;
-
-/// Initializes the msgpack-rpc method table
-void msgpack_rpc_init_method_table(void);
-
-// Add a handler to the method table
-void msgpack_rpc_add_method_handler(String method,
- MsgpackRpcRequestHandler handler);
-
-void msgpack_rpc_init_function_metadata(Dictionary *metadata);
-
-MsgpackRpcRequestHandler msgpack_rpc_get_handler_for(const char *name,
- size_t name_len)
- FUNC_ATTR_NONNULL_ARG(1);
-#endif // NVIM_MSGPACK_RPC_DEFS_H
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index 9195b10614..19cc31f6a6 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -1,12 +1,15 @@
+// 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 <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
#include <msgpack.h>
+#include "nvim/api/private/dispatch.h"
#include "nvim/api/private/helpers.h"
#include "nvim/msgpack_rpc/helpers.h"
-#include "nvim/msgpack_rpc/defs.h"
#include "nvim/lib/kvec.h"
#include "nvim/vim.h"
#include "nvim/log.h"
@@ -21,11 +24,12 @@ static msgpack_zone zone;
static msgpack_sbuffer sbuffer;
#define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \
- bool msgpack_rpc_to_##lt(const msgpack_object *const obj, t *const arg) \
- FUNC_ATTR_NONNULL_ALL \
+ static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \
+ Integer *const arg) \
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
{ \
if (obj->type != MSGPACK_OBJECT_EXT \
- || obj->via.ext.type != kObjectType##t) { \
+ || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \
return false; \
} \
\
@@ -40,17 +44,18 @@ static msgpack_sbuffer sbuffer;
return false; \
} \
\
- *arg = data.via.u64; \
+ *arg = (handle_T)data.via.i64; \
return true; \
} \
\
- void msgpack_rpc_from_##lt(t o, msgpack_packer *res) \
+ static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \
FUNC_ATTR_NONNULL_ARG(2) \
{ \
msgpack_packer pac; \
msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); \
- msgpack_pack_uint64(&pac, o); \
- msgpack_pack_ext(res, sbuffer.size, kObjectType##t); \
+ msgpack_pack_int64(&pac, (handle_T)o); \
+ msgpack_pack_ext(res, sbuffer.size, \
+ kObjectType##t - EXT_OBJECT_TYPE_SHIFT); \
msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); \
msgpack_sbuffer_clear(&sbuffer); \
}
@@ -72,7 +77,7 @@ typedef struct {
size_t idx;
} MPToAPIObjectStackItem;
-/// Convert type used by msgpack parser to Neovim own API type
+/// Convert type used by msgpack parser to Nvim API type.
///
/// @param[in] obj Msgpack value to convert.
/// @param[out] arg Location where result of conversion will be saved.
@@ -83,7 +88,12 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
{
bool ret = true;
kvec_t(MPToAPIObjectStackItem) stack = KV_INITIAL_VALUE;
- kv_push(stack, ((MPToAPIObjectStackItem) { obj, arg, false, 0 }));
+ kv_push(stack, ((MPToAPIObjectStackItem) {
+ .mobj = obj,
+ .aobj = arg,
+ .container = false,
+ .idx = 0,
+ }));
while (ret && kv_size(stack)) {
MPToAPIObjectStackItem cur = kv_last(stack);
if (!cur.container) {
@@ -113,10 +123,16 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
}
break;
}
- case MSGPACK_OBJECT_FLOAT: {
+#ifdef NVIM_MSGPACK_HAS_FLOAT32
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
+#else
+ case MSGPACK_OBJECT_FLOAT:
+#endif
+ {
STATIC_ASSERT(sizeof(Float) == sizeof(cur.mobj->via.f64),
"Msgpack floating-point size does not match API integer");
- *cur.aobj = FLOATING_OBJ(cur.mobj->via.f64);
+ *cur.aobj = FLOAT_OBJ(cur.mobj->via.f64);
break;
}
#define STR_CASE(type, attr, obj, dest, conv) \
@@ -124,7 +140,7 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
dest = conv(((String) { \
.size = obj->via.attr.size, \
.data = (obj->via.attr.ptr == NULL || obj->via.attr.size == 0 \
- ? NULL \
+ ? xmemdupz("", 0) \
: xmemdupz(obj->via.attr.ptr, obj->via.attr.size)), \
})); \
break; \
@@ -180,7 +196,12 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
case MSGPACK_OBJECT_BOOLEAN:
case MSGPACK_OBJECT_POSITIVE_INTEGER:
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
+#ifdef NVIM_MSGPACK_HAS_FLOAT32
+ case MSGPACK_OBJECT_FLOAT32:
+ case MSGPACK_OBJECT_FLOAT64:
+#else
case MSGPACK_OBJECT_FLOAT:
+#endif
case MSGPACK_OBJECT_EXT:
case MSGPACK_OBJECT_MAP:
case MSGPACK_OBJECT_ARRAY: {
@@ -210,20 +231,29 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
break;
}
case MSGPACK_OBJECT_EXT: {
- switch (cur.mobj->via.ext.type) {
+ switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) {
case kObjectTypeBuffer: {
cur.aobj->type = kObjectTypeBuffer;
- ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.buffer);
+ ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer);
break;
}
case kObjectTypeWindow: {
cur.aobj->type = kObjectTypeWindow;
- ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.window);
+ ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.integer);
break;
}
case kObjectTypeTabpage: {
cur.aobj->type = kObjectTypeTabpage;
- ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.tabpage);
+ ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer);
+ break;
+ }
+ case kObjectTypeNil:
+ case kObjectTypeBoolean:
+ case kObjectTypeInteger:
+ case kObjectTypeFloat:
+ case kObjectTypeString:
+ case kObjectTypeArray:
+ case kObjectTypeDictionary: {
break;
}
}
@@ -321,11 +351,13 @@ void msgpack_rpc_from_float(Float result, msgpack_packer *res)
msgpack_pack_double(res, result);
}
-void msgpack_rpc_from_string(String result, msgpack_packer *res)
+void msgpack_rpc_from_string(const String result, msgpack_packer *res)
FUNC_ATTR_NONNULL_ARG(2)
{
msgpack_pack_str(res, result.size);
- msgpack_pack_str_body(res, result.data, result.size);
+ if (result.size > 0) {
+ msgpack_pack_str_body(res, result.data, result.size);
+ }
}
typedef struct {
@@ -334,7 +366,7 @@ typedef struct {
size_t idx;
} APIToMPObjectStackItem;
-/// Convert type used by Neovim API to msgpack
+/// Convert type used by Nvim API to msgpack type.
///
/// @param[in] result Object to convert.
/// @param[out] res Structure that defines where conversion results are saved.
@@ -347,6 +379,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
kv_push(stack, ((APIToMPObjectStackItem) { &result, false, 0 }));
while (kv_size(stack)) {
APIToMPObjectStackItem cur = kv_last(stack);
+ STATIC_ASSERT(kObjectTypeWindow == kObjectTypeBuffer + 1
+ && kObjectTypeTabpage == kObjectTypeWindow + 1,
+ "Buffer, window and tabpage enum items are in order");
switch (cur.aobj->type) {
case kObjectTypeNil: {
msgpack_pack_nil(res);
@@ -369,15 +404,15 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
break;
}
case kObjectTypeBuffer: {
- msgpack_rpc_from_buffer(cur.aobj->data.buffer, res);
+ msgpack_rpc_from_buffer(cur.aobj->data.integer, res);
break;
}
case kObjectTypeWindow: {
- msgpack_rpc_from_window(cur.aobj->data.window, res);
+ msgpack_rpc_from_window(cur.aobj->data.integer, res);
break;
}
case kObjectTypeTabpage: {
- msgpack_rpc_from_tabpage(cur.aobj->data.tabpage, res);
+ msgpack_rpc_from_tabpage(cur.aobj->data.integer, res);
break;
}
case kObjectTypeArray: {
@@ -453,31 +488,9 @@ void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res)
}
}
-/// Handler executed when an invalid method name is passed
-Object msgpack_rpc_handle_missing_method(uint64_t channel_id,
- uint64_t request_id,
- Array args,
- Error *error)
-{
- snprintf(error->msg, sizeof(error->msg), "Invalid method name");
- error->set = true;
- return NIL;
-}
-
-/// Handler executed when malformated arguments are passed
-Object msgpack_rpc_handle_invalid_arguments(uint64_t channel_id,
- uint64_t request_id,
- Array args,
- Error *error)
-{
- snprintf(error->msg, sizeof(error->msg), "Invalid method arguments");
- error->set = true;
- return NIL;
-}
-
/// Serializes a msgpack-rpc request or notification(id == 0)
void msgpack_rpc_serialize_request(uint64_t request_id,
- String method,
+ const String method,
Array args,
msgpack_packer *pac)
FUNC_ATTR_NONNULL_ARG(4)
@@ -504,7 +517,7 @@ void msgpack_rpc_serialize_response(uint64_t response_id,
msgpack_pack_int(pac, 1);
msgpack_pack_uint64(pac, response_id);
- if (err->set) {
+ if (ERROR_SET(err)) {
// error represented by a [type, message] array
msgpack_pack_array(pac, 2);
msgpack_rpc_from_integer(err->type, pac);
@@ -557,49 +570,49 @@ void msgpack_rpc_validate(uint64_t *response_id,
*response_id = NO_RESPONSE;
// Validate the basic structure of the msgpack-rpc payload
if (req->type != MSGPACK_OBJECT_ARRAY) {
- api_set_error(err, Validation, _("Message is not an array"));
+ api_set_error(err, kErrorTypeValidation, "Message is not an array");
return;
}
if (req->via.array.size == 0) {
- api_set_error(err, Validation, _("Message is empty"));
+ api_set_error(err, kErrorTypeValidation, "Message is empty");
return;
}
if (req->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER) {
- api_set_error(err, Validation, _("Message type must be an integer"));
+ api_set_error(err, kErrorTypeValidation, "Message type must be an integer");
return;
}
uint64_t type = req->via.array.ptr[0].via.u64;
if (type != kMessageTypeRequest && type != kMessageTypeNotification) {
- api_set_error(err, Validation, _("Unknown message type"));
+ api_set_error(err, kErrorTypeValidation, "Unknown message type");
return;
}
if ((type == kMessageTypeRequest && req->via.array.size != 4)
|| (type == kMessageTypeNotification && req->via.array.size != 3)) {
- api_set_error(err, Validation, _("Request array size should be 4 (request) "
- "or 3 (notification)"));
+ api_set_error(err, kErrorTypeValidation,
+ "Request array size must be 4 (request) or 3 (notification)");
return;
}
if (type == kMessageTypeRequest) {
msgpack_object *id_obj = msgpack_rpc_msg_id(req);
if (!id_obj) {
- api_set_error(err, Validation, _("ID must be a positive integer"));
+ api_set_error(err, kErrorTypeValidation, "ID must be a positive integer");
return;
}
*response_id = id_obj->via.u64;
}
if (!msgpack_rpc_method(req)) {
- api_set_error(err, Validation, _("Method must be a string"));
+ api_set_error(err, kErrorTypeValidation, "Method must be a string");
return;
}
if (!msgpack_rpc_args(req)) {
- api_set_error(err, Validation, _("Parameters must be an array"));
+ api_set_error(err, kErrorTypeValidation, "Parameters must be an array");
return;
}
}
diff --git a/src/nvim/msgpack_rpc/helpers.h b/src/nvim/msgpack_rpc/helpers.h
index 7d9f114140..0e4cd1be6d 100644
--- a/src/nvim/msgpack_rpc/helpers.h
+++ b/src/nvim/msgpack_rpc/helpers.h
@@ -9,6 +9,13 @@
#include "nvim/event/wstream.h"
#include "nvim/api/private/defs.h"
+/// Value by which objects represented as EXT type are shifted
+///
+/// Subtracted when packing, added when unpacking. Used to allow moving
+/// buffer/window/tabpage block inside ObjectType enum. This block yet cannot be
+/// split or reordered.
+#define EXT_OBJECT_TYPE_SHIFT kObjectTypeBuffer
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/helpers.h.generated.h"
#endif
diff --git a/src/nvim/msgpack_rpc/server.c b/src/nvim/msgpack_rpc/server.c
index abbd3e8aff..e5d80aea1d 100644
--- a/src/nvim/msgpack_rpc/server.c
+++ b/src/nvim/msgpack_rpc/server.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 <stdlib.h>
#include <string.h>
@@ -29,22 +32,27 @@ static garray_T watchers = GA_EMPTY_INIT_VALUE;
#endif
/// Initializes the module
-bool server_init(void)
+bool server_init(const char *listen_addr)
{
ga_init(&watchers, sizeof(SocketWatcher *), 1);
- bool must_free = false;
- const char *listen_address = os_getenv(LISTEN_ADDRESS_ENV_VAR);
- if (listen_address == NULL) {
- must_free = true;
- listen_address = server_address_new();
+ // $NVIM_LISTEN_ADDRESS
+ const char *env_addr = os_getenv(LISTEN_ADDRESS_ENV_VAR);
+ int rv = listen_addr == NULL ? 1 : server_start(listen_addr);
+
+ if (0 != rv) {
+ rv = env_addr == NULL ? 1 : server_start(env_addr);
+ if (0 != rv) {
+ listen_addr = server_address_new();
+ if (listen_addr == NULL) {
+ return false;
+ }
+ rv = server_start(listen_addr);
+ xfree((char *)listen_addr);
+ }
}
- bool ok = (server_start(listen_address) == 0);
- if (must_free) {
- xfree((char *) listen_address);
- }
- return ok;
+ return rv == 0;
}
/// Teardown a single server
@@ -90,39 +98,61 @@ char *server_address_new(void)
#endif
}
-/// Starts listening for API calls on the TCP address or pipe path `endpoint`.
+/// Check if this instance owns a pipe address.
+/// The argument must already be resolved to an absolute path!
+bool server_owns_pipe_address(const char *path)
+{
+ for (int i = 0; i < watchers.ga_len; i++) {
+ if (!strcmp(path, ((SocketWatcher **)watchers.ga_data)[i]->addr)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/// Starts listening for API calls.
+///
/// The socket type is determined by parsing `endpoint`: If it's a valid IPv4
-/// address in 'ip[:port]' format, then it will be TCP socket. The port is
-/// optional and if omitted defaults to NVIM_DEFAULT_TCP_PORT. Otherwise it
-/// will be a unix socket or named pipe.
+/// or IPv6 address in 'ip:[port]' format, then it will be a TCP socket.
+/// Otherwise it will be a Unix socket or named pipe (Windows).
+///
+/// If no port is given, a random one will be assigned.
///
-/// @param endpoint Address of the server. Either a 'ip[:port]' string or an
-/// arbitrary identifier (trimmed to 256 bytes) for the unix socket or
-/// named pipe.
-/// @returns 0 on success, 1 on a regular error, and negative errno
-/// on failure to bind or connect.
+/// @param endpoint Address of the server. Either a 'ip:[port]' string or an
+/// arbitrary identifier (trimmed to 256 bytes) for the Unix
+/// socket or named pipe.
+/// @returns 0: success, 1: validation error, 2: already listening,
+/// -errno: failed to bind or listen.
int server_start(const char *endpoint)
{
- if (endpoint == NULL) {
- ELOG("Attempting to start server on NULL endpoint");
+ if (endpoint == NULL || endpoint[0] == '\0') {
+ WLOG("Empty or NULL endpoint");
return 1;
}
SocketWatcher *watcher = xmalloc(sizeof(SocketWatcher));
- socket_watcher_init(&main_loop, watcher, endpoint, NULL);
+
+ int result = socket_watcher_init(&main_loop, watcher, endpoint);
+ if (result < 0) {
+ xfree(watcher);
+ return result;
+ }
// Check if a watcher for the endpoint already exists
for (int i = 0; i < watchers.ga_len; i++) {
if (!strcmp(watcher->addr, ((SocketWatcher **)watchers.ga_data)[i]->addr)) {
ELOG("Already listening on %s", watcher->addr);
+ if (watcher->stream->type == UV_TCP) {
+ uv_freeaddrinfo(watcher->uv.tcp.addrinfo);
+ }
socket_watcher_close(watcher, free_server);
- return 1;
+ return 2;
}
}
- int result = socket_watcher_start(watcher, MAX_CONNECTIONS, connection_cb);
+ result = socket_watcher_start(watcher, MAX_CONNECTIONS, connection_cb);
if (result < 0) {
- ELOG("Failed to start server: %s", uv_strerror(result));
+ WLOG("Failed to start server: %s", uv_strerror(result));
socket_watcher_close(watcher, free_server);
return result;
}
@@ -148,9 +178,10 @@ int server_start(const char *endpoint)
/// Stops listening on the address specified by `endpoint`.
///
/// @param endpoint Address of the server.
-void server_stop(char *endpoint)
+bool server_stop(char *endpoint)
{
SocketWatcher *watcher;
+ bool watcher_found = false;
char addr[ADDRESS_MAX_SIZE];
// Trim to `ADDRESS_MAX_SIZE`
@@ -160,13 +191,14 @@ void server_stop(char *endpoint)
for (; i < watchers.ga_len; i++) {
watcher = ((SocketWatcher **)watchers.ga_data)[i];
if (strcmp(addr, watcher->addr) == 0) {
+ watcher_found = true;
break;
}
}
- if (i >= watchers.ga_len) {
- ELOG("Not listening on %s", addr);
- return;
+ if (!watcher_found) {
+ WLOG("Not listening on %s", addr);
+ return false;
}
// Unset $NVIM_LISTEN_ADDRESS if it is the stopped address.
@@ -188,6 +220,8 @@ void server_stop(char *endpoint)
if (STRCMP(addr, get_vim_var_str(VV_SEND_SERVER)) == 0) {
set_vservername(&watchers);
}
+
+ return true;
}
/// Returns an allocated array of server addresses.
diff --git a/src/nvim/msgpack_rpc/server.h b/src/nvim/msgpack_rpc/server.h
index f1a6703938..5446e40e0b 100644
--- a/src/nvim/msgpack_rpc/server.h
+++ b/src/nvim/msgpack_rpc/server.h
@@ -1,6 +1,8 @@
#ifndef NVIM_MSGPACK_RPC_SERVER_H
#define NVIM_MSGPACK_RPC_SERVER_H
+#include <stdio.h>
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "msgpack_rpc/server.h.generated.h"
#endif
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index c95e5e1a15..0e3946740a 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -1,8 +1,11 @@
-/*
- * normal.c: Contains the main routine for processing characters in command
- * mode. Communicates closely with the code in ops.c to handle
- * the operators.
- */
+// 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
+
+//
+// normal.c: Contains the main routine for processing characters in command
+// mode. Communicates closely with the code in ops.c to handle
+// the operators.
+//
#include <assert.h>
#include <inttypes.h>
@@ -10,6 +13,7 @@
#include <stdbool.h>
#include <stdlib.h>
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/normal.h"
@@ -36,7 +40,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/move.h"
#include "nvim/mouse.h"
@@ -46,6 +49,7 @@
#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
+#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
@@ -60,12 +64,9 @@
typedef struct normal_state {
VimState state;
- linenr_T conceal_old_cursor_line;
- linenr_T conceal_new_cursor_line;
bool command_finished;
bool ctrl_w;
bool need_flushbuf;
- bool conceal_update_lines;
bool set_prevcount;
bool previous_got_int; // `got_int` was true
bool cmdwin; // command-line window normal mode
@@ -153,196 +154,195 @@ static const struct nv_cmd {
short cmd_arg; /* value for ca.arg */
} nv_cmds[] =
{
- {NUL, nv_error, 0, 0},
- {Ctrl_A, nv_addsub, 0, 0},
- {Ctrl_B, nv_page, NV_STS, BACKWARD},
- {Ctrl_C, nv_esc, 0, true},
- {Ctrl_D, nv_halfpage, 0, 0},
- {Ctrl_E, nv_scroll_line, 0, true},
- {Ctrl_F, nv_page, NV_STS, FORWARD},
- {Ctrl_G, nv_ctrlg, 0, 0},
- {Ctrl_H, nv_ctrlh, 0, 0},
- {Ctrl_I, nv_pcmark, 0, 0},
- {NL, nv_down, 0, false},
- {Ctrl_K, nv_error, 0, 0},
- {Ctrl_L, nv_clear, 0, 0},
- {Ctrl_M, nv_down, 0, true},
- {Ctrl_N, nv_down, NV_STS, false},
- {Ctrl_O, nv_ctrlo, 0, 0},
- {Ctrl_P, nv_up, NV_STS, false},
- {Ctrl_Q, nv_visual, 0, false},
- {Ctrl_R, nv_redo, 0, 0},
- {Ctrl_S, nv_ignore, 0, 0},
- {Ctrl_T, nv_tagpop, NV_NCW, 0},
- {Ctrl_U, nv_halfpage, 0, 0},
- {Ctrl_V, nv_visual, 0, false},
- {'V', nv_visual, 0, false},
- {'v', nv_visual, 0, false},
- {Ctrl_W, nv_window, 0, 0},
- {Ctrl_X, nv_addsub, 0, 0},
- {Ctrl_Y, nv_scroll_line, 0, false},
- {Ctrl_Z, nv_suspend, 0, 0},
- {ESC, nv_esc, 0, false},
- {Ctrl_BSL, nv_normal, NV_NCH_ALW, 0},
- {Ctrl_RSB, nv_ident, NV_NCW, 0},
- {Ctrl_HAT, nv_hat, NV_NCW, 0},
- {Ctrl__, nv_error, 0, 0},
- {' ', nv_right, 0, 0},
- {'!', nv_operator, 0, 0},
- {'"', nv_regname, NV_NCH_NOP|NV_KEEPREG, 0},
- {'#', nv_ident, 0, 0},
- {'$', nv_dollar, 0, 0},
- {'%', nv_percent, 0, 0},
- {'&', nv_optrans, 0, 0},
- {'\'', nv_gomark, NV_NCH_ALW, true},
- {'(', nv_brace, 0, BACKWARD},
- {')', nv_brace, 0, FORWARD},
- {'*', nv_ident, 0, 0},
- {'+', nv_down, 0, true},
- {',', nv_csearch, 0, true},
- {'-', nv_up, 0, true},
- {'.', nv_dot, NV_KEEPREG, 0},
- {'/', nv_search, 0, false},
- {'0', nv_beginline, 0, 0},
- {'1', nv_ignore, 0, 0},
- {'2', nv_ignore, 0, 0},
- {'3', nv_ignore, 0, 0},
- {'4', nv_ignore, 0, 0},
- {'5', nv_ignore, 0, 0},
- {'6', nv_ignore, 0, 0},
- {'7', nv_ignore, 0, 0},
- {'8', nv_ignore, 0, 0},
- {'9', nv_ignore, 0, 0},
- {':', nv_colon, 0, 0},
- {';', nv_csearch, 0, false},
- {'<', nv_operator, NV_RL, 0},
- {'=', nv_operator, 0, 0},
- {'>', nv_operator, NV_RL, 0},
- {'?', nv_search, 0, false},
- {'@', nv_at, NV_NCH_NOP, false},
- {'A', nv_edit, 0, 0},
- {'B', nv_bck_word, 0, 1},
- {'C', nv_abbrev, NV_KEEPREG, 0},
- {'D', nv_abbrev, NV_KEEPREG, 0},
- {'E', nv_wordcmd, 0, true},
- {'F', nv_csearch, NV_NCH_ALW|NV_LANG, BACKWARD},
- {'G', nv_goto, 0, true},
- {'H', nv_scroll, 0, 0},
- {'I', nv_edit, 0, 0},
- {'J', nv_join, 0, 0},
- {'K', nv_ident, 0, 0},
- {'L', nv_scroll, 0, 0},
- {'M', nv_scroll, 0, 0},
- {'N', nv_next, 0, SEARCH_REV},
- {'O', nv_open, 0, 0},
- {'P', nv_put, 0, 0},
- {'Q', nv_exmode, NV_NCW, 0},
- {'R', nv_Replace, 0, false},
- {'S', nv_subst, NV_KEEPREG, 0},
- {'T', nv_csearch, NV_NCH_ALW|NV_LANG, BACKWARD},
- {'U', nv_Undo, 0, 0},
- {'W', nv_wordcmd, 0, true},
- {'X', nv_abbrev, NV_KEEPREG, 0},
- {'Y', nv_abbrev, NV_KEEPREG, 0},
- {'Z', nv_Zet, NV_NCH_NOP|NV_NCW, 0},
- {'[', nv_brackets, NV_NCH_ALW, BACKWARD},
- {'\\', nv_error, 0, 0},
- {']', nv_brackets, NV_NCH_ALW, FORWARD},
- {'^', nv_beginline, 0, BL_WHITE | BL_FIX},
- {'_', nv_lineop, 0, 0},
- {'`', nv_gomark, NV_NCH_ALW, false},
- {'a', nv_edit, NV_NCH, 0},
- {'b', nv_bck_word, 0, 0},
- {'c', nv_operator, 0, 0},
- {'d', nv_operator, 0, 0},
- {'e', nv_wordcmd, 0, false},
- {'f', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD},
- {'g', nv_g_cmd, NV_NCH_ALW, false},
- {'h', nv_left, NV_RL, 0},
- {'i', nv_edit, NV_NCH, 0},
- {'j', nv_down, 0, false},
- {'k', nv_up, 0, false},
- {'l', nv_right, NV_RL, 0},
- {'m', nv_mark, NV_NCH_NOP, 0},
- {'n', nv_next, 0, 0},
- {'o', nv_open, 0, 0},
- {'p', nv_put, 0, 0},
- {'q', nv_record, NV_NCH, 0},
- {'r', nv_replace, NV_NCH_NOP|NV_LANG, 0},
- {'s', nv_subst, NV_KEEPREG, 0},
- {'t', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD},
- {'u', nv_undo, 0, 0},
- {'w', nv_wordcmd, 0, false},
- {'x', nv_abbrev, NV_KEEPREG, 0},
- {'y', nv_operator, 0, 0},
- {'z', nv_zet, NV_NCH_ALW, 0},
- {'{', nv_findpar, 0, BACKWARD},
- {'|', nv_pipe, 0, 0},
- {'}', nv_findpar, 0, FORWARD},
- {'~', nv_tilde, 0, 0},
-
- /* pound sign */
- {POUND, nv_ident, 0, 0},
- {K_MOUSEUP, nv_mousescroll, 0, MSCR_UP},
- {K_MOUSEDOWN, nv_mousescroll, 0, MSCR_DOWN},
- {K_MOUSELEFT, nv_mousescroll, 0, MSCR_LEFT},
- {K_MOUSERIGHT, nv_mousescroll, 0, MSCR_RIGHT},
- {K_LEFTMOUSE, nv_mouse, 0, 0},
- {K_LEFTMOUSE_NM, nv_mouse, 0, 0},
- {K_LEFTDRAG, nv_mouse, 0, 0},
- {K_LEFTRELEASE, nv_mouse, 0, 0},
- {K_LEFTRELEASE_NM, nv_mouse, 0, 0},
- {K_MIDDLEMOUSE, nv_mouse, 0, 0},
- {K_MIDDLEDRAG, nv_mouse, 0, 0},
- {K_MIDDLERELEASE, nv_mouse, 0, 0},
- {K_RIGHTMOUSE, nv_mouse, 0, 0},
- {K_RIGHTDRAG, nv_mouse, 0, 0},
- {K_RIGHTRELEASE, nv_mouse, 0, 0},
- {K_X1MOUSE, nv_mouse, 0, 0},
- {K_X1DRAG, nv_mouse, 0, 0},
- {K_X1RELEASE, nv_mouse, 0, 0},
- {K_X2MOUSE, nv_mouse, 0, 0},
- {K_X2DRAG, nv_mouse, 0, 0},
- {K_X2RELEASE, nv_mouse, 0, 0},
- {K_IGNORE, nv_ignore, NV_KEEPREG, 0},
- {K_NOP, nv_nop, 0, 0},
- {K_INS, nv_edit, 0, 0},
- {K_KINS, nv_edit, 0, 0},
- {K_BS, nv_ctrlh, 0, 0},
- {K_UP, nv_up, NV_SSS|NV_STS, false},
- {K_S_UP, nv_page, NV_SS, BACKWARD},
- {K_DOWN, nv_down, NV_SSS|NV_STS, false},
- {K_S_DOWN, nv_page, NV_SS, FORWARD},
- {K_LEFT, nv_left, NV_SSS|NV_STS|NV_RL, 0},
- {K_S_LEFT, nv_bck_word, NV_SS|NV_RL, 0},
- {K_C_LEFT, nv_bck_word, NV_SSS|NV_RL|NV_STS, 1},
- {K_RIGHT, nv_right, NV_SSS|NV_STS|NV_RL, 0},
- {K_S_RIGHT, nv_wordcmd, NV_SS|NV_RL, false},
- {K_C_RIGHT, nv_wordcmd, NV_SSS|NV_RL|NV_STS, true},
- {K_PAGEUP, nv_page, NV_SSS|NV_STS, BACKWARD},
- {K_KPAGEUP, nv_page, NV_SSS|NV_STS, BACKWARD},
- {K_PAGEDOWN, nv_page, NV_SSS|NV_STS, FORWARD},
- {K_KPAGEDOWN, nv_page, NV_SSS|NV_STS, FORWARD},
- {K_END, nv_end, NV_SSS|NV_STS, false},
- {K_KEND, nv_end, NV_SSS|NV_STS, false},
- {K_S_END, nv_end, NV_SS, false},
- {K_C_END, nv_end, NV_SSS|NV_STS, true},
- {K_HOME, nv_home, NV_SSS|NV_STS, 0},
- {K_KHOME, nv_home, NV_SSS|NV_STS, 0},
- {K_S_HOME, nv_home, NV_SS, 0},
- {K_C_HOME, nv_goto, NV_SSS|NV_STS, false},
- {K_DEL, nv_abbrev, 0, 0},
- {K_KDEL, nv_abbrev, 0, 0},
- {K_UNDO, nv_kundo, 0, 0},
- {K_HELP, nv_help, NV_NCW, 0},
- {K_F1, nv_help, NV_NCW, 0},
- {K_XF1, nv_help, NV_NCW, 0},
- {K_SELECT, nv_select, 0, 0},
- {K_F8, farsi_fkey, 0, 0},
- {K_F9, farsi_fkey, 0, 0},
- {K_EVENT, nv_event, NV_KEEPREG, 0},
- {K_FOCUSGAINED, nv_focusgained, NV_KEEPREG, 0},
- {K_FOCUSLOST, nv_focuslost, NV_KEEPREG, 0},
+ { NUL, nv_error, 0, 0 },
+ { Ctrl_A, nv_addsub, 0, 0 },
+ { Ctrl_B, nv_page, NV_STS, BACKWARD },
+ { Ctrl_C, nv_esc, 0, true },
+ { Ctrl_D, nv_halfpage, 0, 0 },
+ { Ctrl_E, nv_scroll_line, 0, true },
+ { Ctrl_F, nv_page, NV_STS, FORWARD },
+ { Ctrl_G, nv_ctrlg, 0, 0 },
+ { Ctrl_H, nv_ctrlh, 0, 0 },
+ { Ctrl_I, nv_pcmark, 0, 0 },
+ { NL, nv_down, 0, false },
+ { Ctrl_K, nv_error, 0, 0 },
+ { Ctrl_L, nv_clear, 0, 0 },
+ { Ctrl_M, nv_down, 0, true },
+ { Ctrl_N, nv_down, NV_STS, false },
+ { Ctrl_O, nv_ctrlo, 0, 0 },
+ { Ctrl_P, nv_up, NV_STS, false },
+ { Ctrl_Q, nv_visual, 0, false },
+ { Ctrl_R, nv_redo, 0, 0 },
+ { Ctrl_S, nv_ignore, 0, 0 },
+ { Ctrl_T, nv_tagpop, NV_NCW, 0 },
+ { Ctrl_U, nv_halfpage, 0, 0 },
+ { Ctrl_V, nv_visual, 0, false },
+ { 'V', nv_visual, 0, false },
+ { 'v', nv_visual, 0, false },
+ { Ctrl_W, nv_window, 0, 0 },
+ { Ctrl_X, nv_addsub, 0, 0 },
+ { Ctrl_Y, nv_scroll_line, 0, false },
+ { Ctrl_Z, nv_suspend, 0, 0 },
+ { ESC, nv_esc, 0, false },
+ { Ctrl_BSL, nv_normal, NV_NCH_ALW, 0 },
+ { Ctrl_RSB, nv_ident, NV_NCW, 0 },
+ { Ctrl_HAT, nv_hat, NV_NCW, 0 },
+ { Ctrl__, nv_error, 0, 0 },
+ { ' ', nv_right, 0, 0 },
+ { '!', nv_operator, 0, 0 },
+ { '"', nv_regname, NV_NCH_NOP|NV_KEEPREG, 0 },
+ { '#', nv_ident, 0, 0 },
+ { '$', nv_dollar, 0, 0 },
+ { '%', nv_percent, 0, 0 },
+ { '&', nv_optrans, 0, 0 },
+ { '\'', nv_gomark, NV_NCH_ALW, true },
+ { '(', nv_brace, 0, BACKWARD },
+ { ')', nv_brace, 0, FORWARD },
+ { '*', nv_ident, 0, 0 },
+ { '+', nv_down, 0, true },
+ { ',', nv_csearch, 0, true },
+ { '-', nv_up, 0, true },
+ { '.', nv_dot, NV_KEEPREG, 0 },
+ { '/', nv_search, 0, false },
+ { '0', nv_beginline, 0, 0 },
+ { '1', nv_ignore, 0, 0 },
+ { '2', nv_ignore, 0, 0 },
+ { '3', nv_ignore, 0, 0 },
+ { '4', nv_ignore, 0, 0 },
+ { '5', nv_ignore, 0, 0 },
+ { '6', nv_ignore, 0, 0 },
+ { '7', nv_ignore, 0, 0 },
+ { '8', nv_ignore, 0, 0 },
+ { '9', nv_ignore, 0, 0 },
+ { ':', nv_colon, 0, 0 },
+ { ';', nv_csearch, 0, false },
+ { '<', nv_operator, NV_RL, 0 },
+ { '=', nv_operator, 0, 0 },
+ { '>', nv_operator, NV_RL, 0 },
+ { '?', nv_search, 0, false },
+ { '@', nv_at, NV_NCH_NOP, false },
+ { 'A', nv_edit, 0, 0 },
+ { 'B', nv_bck_word, 0, 1 },
+ { 'C', nv_abbrev, NV_KEEPREG, 0 },
+ { 'D', nv_abbrev, NV_KEEPREG, 0 },
+ { 'E', nv_wordcmd, 0, true },
+ { 'F', nv_csearch, NV_NCH_ALW|NV_LANG, BACKWARD },
+ { 'G', nv_goto, 0, true },
+ { 'H', nv_scroll, 0, 0 },
+ { 'I', nv_edit, 0, 0 },
+ { 'J', nv_join, 0, 0 },
+ { 'K', nv_ident, 0, 0 },
+ { 'L', nv_scroll, 0, 0 },
+ { 'M', nv_scroll, 0, 0 },
+ { 'N', nv_next, 0, SEARCH_REV },
+ { 'O', nv_open, 0, 0 },
+ { 'P', nv_put, 0, 0 },
+ { 'Q', nv_exmode, NV_NCW, 0 },
+ { 'R', nv_Replace, 0, false },
+ { 'S', nv_subst, NV_KEEPREG, 0 },
+ { 'T', nv_csearch, NV_NCH_ALW|NV_LANG, BACKWARD },
+ { 'U', nv_Undo, 0, 0 },
+ { 'W', nv_wordcmd, 0, true },
+ { 'X', nv_abbrev, NV_KEEPREG, 0 },
+ { 'Y', nv_abbrev, NV_KEEPREG, 0 },
+ { 'Z', nv_Zet, NV_NCH_NOP|NV_NCW, 0 },
+ { '[', nv_brackets, NV_NCH_ALW, BACKWARD },
+ { '\\', nv_error, 0, 0 },
+ { ']', nv_brackets, NV_NCH_ALW, FORWARD },
+ { '^', nv_beginline, 0, BL_WHITE | BL_FIX },
+ { '_', nv_lineop, 0, 0 },
+ { '`', nv_gomark, NV_NCH_ALW, false },
+ { 'a', nv_edit, NV_NCH, 0 },
+ { 'b', nv_bck_word, 0, 0 },
+ { 'c', nv_operator, 0, 0 },
+ { 'd', nv_operator, 0, 0 },
+ { 'e', nv_wordcmd, 0, false },
+ { 'f', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD },
+ { 'g', nv_g_cmd, NV_NCH_ALW, false },
+ { 'h', nv_left, NV_RL, 0 },
+ { 'i', nv_edit, NV_NCH, 0 },
+ { 'j', nv_down, 0, false },
+ { 'k', nv_up, 0, false },
+ { 'l', nv_right, NV_RL, 0 },
+ { 'm', nv_mark, NV_NCH_NOP, 0 },
+ { 'n', nv_next, 0, 0 },
+ { 'o', nv_open, 0, 0 },
+ { 'p', nv_put, 0, 0 },
+ { 'q', nv_record, NV_NCH, 0 },
+ { 'r', nv_replace, NV_NCH_NOP|NV_LANG, 0 },
+ { 's', nv_subst, NV_KEEPREG, 0 },
+ { 't', nv_csearch, NV_NCH_ALW|NV_LANG, FORWARD },
+ { 'u', nv_undo, 0, 0 },
+ { 'w', nv_wordcmd, 0, false },
+ { 'x', nv_abbrev, NV_KEEPREG, 0 },
+ { 'y', nv_operator, 0, 0 },
+ { 'z', nv_zet, NV_NCH_ALW, 0 },
+ { '{', nv_findpar, 0, BACKWARD },
+ { '|', nv_pipe, 0, 0 },
+ { '}', nv_findpar, 0, FORWARD },
+ { '~', nv_tilde, 0, 0 },
+
+ // pound sign
+ { POUND, nv_ident, 0, 0 },
+ { K_MOUSEUP, nv_mousescroll, 0, MSCR_UP },
+ { K_MOUSEDOWN, nv_mousescroll, 0, MSCR_DOWN },
+ { K_MOUSELEFT, nv_mousescroll, 0, MSCR_LEFT },
+ { K_MOUSERIGHT, nv_mousescroll, 0, MSCR_RIGHT },
+ { K_LEFTMOUSE, nv_mouse, 0, 0 },
+ { K_LEFTMOUSE_NM, nv_mouse, 0, 0 },
+ { K_LEFTDRAG, nv_mouse, 0, 0 },
+ { K_LEFTRELEASE, nv_mouse, 0, 0 },
+ { K_LEFTRELEASE_NM, nv_mouse, 0, 0 },
+ { K_MIDDLEMOUSE, nv_mouse, 0, 0 },
+ { K_MIDDLEDRAG, nv_mouse, 0, 0 },
+ { K_MIDDLERELEASE, nv_mouse, 0, 0 },
+ { K_RIGHTMOUSE, nv_mouse, 0, 0 },
+ { K_RIGHTDRAG, nv_mouse, 0, 0 },
+ { K_RIGHTRELEASE, nv_mouse, 0, 0 },
+ { K_X1MOUSE, nv_mouse, 0, 0 },
+ { K_X1DRAG, nv_mouse, 0, 0 },
+ { K_X1RELEASE, nv_mouse, 0, 0 },
+ { K_X2MOUSE, nv_mouse, 0, 0 },
+ { K_X2DRAG, nv_mouse, 0, 0 },
+ { K_X2RELEASE, nv_mouse, 0, 0 },
+ { K_IGNORE, nv_ignore, NV_KEEPREG, 0 },
+ { K_NOP, nv_nop, 0, 0 },
+ { K_INS, nv_edit, 0, 0 },
+ { K_KINS, nv_edit, 0, 0 },
+ { K_BS, nv_ctrlh, 0, 0 },
+ { K_UP, nv_up, NV_SSS|NV_STS, false },
+ { K_S_UP, nv_page, NV_SS, BACKWARD },
+ { K_DOWN, nv_down, NV_SSS|NV_STS, false },
+ { K_S_DOWN, nv_page, NV_SS, FORWARD },
+ { K_LEFT, nv_left, NV_SSS|NV_STS|NV_RL, 0 },
+ { K_S_LEFT, nv_bck_word, NV_SS|NV_RL, 0 },
+ { K_C_LEFT, nv_bck_word, NV_SSS|NV_RL|NV_STS, 1 },
+ { K_RIGHT, nv_right, NV_SSS|NV_STS|NV_RL, 0 },
+ { K_S_RIGHT, nv_wordcmd, NV_SS|NV_RL, false },
+ { K_C_RIGHT, nv_wordcmd, NV_SSS|NV_RL|NV_STS, true },
+ { K_PAGEUP, nv_page, NV_SSS|NV_STS, BACKWARD },
+ { K_KPAGEUP, nv_page, NV_SSS|NV_STS, BACKWARD },
+ { K_PAGEDOWN, nv_page, NV_SSS|NV_STS, FORWARD },
+ { K_KPAGEDOWN, nv_page, NV_SSS|NV_STS, FORWARD },
+ { K_END, nv_end, NV_SSS|NV_STS, false },
+ { K_KEND, nv_end, NV_SSS|NV_STS, false },
+ { K_S_END, nv_end, NV_SS, false },
+ { K_C_END, nv_end, NV_SSS|NV_STS, true },
+ { K_HOME, nv_home, NV_SSS|NV_STS, 0 },
+ { K_KHOME, nv_home, NV_SSS|NV_STS, 0 },
+ { K_S_HOME, nv_home, NV_SS, 0 },
+ { K_C_HOME, nv_goto, NV_SSS|NV_STS, false },
+ { K_DEL, nv_abbrev, 0, 0 },
+ { K_KDEL, nv_abbrev, 0, 0 },
+ { K_UNDO, nv_kundo, 0, 0 },
+ { K_HELP, nv_help, NV_NCW, 0 },
+ { K_F1, nv_help, NV_NCW, 0 },
+ { K_XF1, nv_help, NV_NCW, 0 },
+ { K_SELECT, nv_select, 0, 0 },
+ { K_F8, farsi_f8, 0, 0 },
+ { K_F9, farsi_f9, 0, 0 },
+ { K_EVENT, nv_event, NV_KEEPREG, 0 },
+ { K_COMMAND, nv_colon, 0, 0 },
};
/* Number of commands in nv_cmds[]. */
@@ -460,7 +460,7 @@ void normal_enter(bool cmdwin, bool noexmode)
normal_state_init(&state);
state.cmdwin = cmdwin;
state.noexmode = noexmode;
- state.toplevel = !cmdwin && !noexmode;
+ state.toplevel = (!cmdwin || cmdwin_result == 0) && !noexmode;
state_enter(&state.state);
}
@@ -538,7 +538,7 @@ static bool normal_handle_special_visual_command(NormalState *s)
return false;
}
-static bool normal_need_aditional_char(NormalState *s)
+static bool normal_need_additional_char(NormalState *s)
{
int flags = nv_cmds[s->idx].cmd_flags;
bool pending_op = s->oa.op_type != OP_NOP;
@@ -618,7 +618,7 @@ static void normal_redraw_mode_message(NormalState *s)
update_screen(0);
// now reset it, otherwise it's put in the history again
keep_msg = kmsg;
- msg_attr(kmsg, keep_msg_attr);
+ msg_attr((const char *)kmsg, keep_msg_attr);
xfree(kmsg);
}
setcursor();
@@ -642,8 +642,7 @@ static void normal_get_additional_char(NormalState *s)
bool langmap_active = false; // using :lmap mappings
int lang; // getting a text character
- ++no_mapping;
- ++allow_keys; // no mapping for nchar, but allow key codes
+ no_mapping++;
// Don't generate a CursorHold event here, most commands can't handle
// it, e.g., nv_replace(), nv_csearch().
did_cursorhold = true;
@@ -681,8 +680,7 @@ static void normal_get_additional_char(NormalState *s)
}
if (lang && curbuf->b_p_iminsert == B_IMODE_LMAP) {
// Allow mappings defined with ":lmap".
- --no_mapping;
- --allow_keys;
+ no_mapping--;
if (repl) {
State = LREPLACE;
} else {
@@ -695,9 +693,7 @@ static void normal_get_additional_char(NormalState *s)
if (langmap_active) {
// Undo the decrement done above
- ++no_mapping;
- ++allow_keys;
- State = NORMAL_BUSY;
+ no_mapping++;
}
State = NORMAL_BUSY;
s->need_flushbuf |= add_to_showcmd(*cp);
@@ -781,8 +777,7 @@ static void normal_get_additional_char(NormalState *s)
}
no_mapping++;
}
- --no_mapping;
- --allow_keys;
+ no_mapping--;
}
static void normal_invert_horizontal(NormalState *s)
@@ -832,8 +827,7 @@ static bool normal_get_command_count(NormalState *s)
}
if (s->ctrl_w) {
- ++no_mapping;
- ++allow_keys; // no mapping for nchar, but keys
+ no_mapping++;
}
++no_zero_mapping; // don't map zero here
@@ -841,8 +835,7 @@ static bool normal_get_command_count(NormalState *s)
LANGMAP_ADJUST(s->c, true);
--no_zero_mapping;
if (s->ctrl_w) {
- --no_mapping;
- --allow_keys;
+ no_mapping--;
}
s->need_flushbuf |= add_to_showcmd(s->c);
}
@@ -852,12 +845,10 @@ static bool normal_get_command_count(NormalState *s)
s->ctrl_w = true;
s->ca.opcount = s->ca.count0; // remember first count
s->ca.count0 = 0;
- ++no_mapping;
- ++allow_keys; // no mapping for nchar, but keys
+ no_mapping++;
s->c = plain_vgetc(); // get next character
LANGMAP_ADJUST(s->c, true);
- --no_mapping;
- --allow_keys;
+ no_mapping--;
s->need_flushbuf |= add_to_showcmd(s->c);
return true;
}
@@ -925,9 +916,7 @@ normal_end:
checkpcmark(); // check if we moved since setting pcmark
xfree(s->ca.searchbuf);
- if (has_mbyte) {
- mb_adjust_cursor();
- }
+ mb_check_adjust_col(curwin); // #6203
if (curwin->w_p_scb && s->toplevel) {
validate_cursor(); // may need to update w_leftcol
@@ -1091,7 +1080,7 @@ static int normal_execute(VimState *state, int key)
}
// Get an additional character if we need one.
- if (normal_need_aditional_char(s)) {
+ if (normal_need_additional_char(s)) {
normal_get_additional_char(s);
}
@@ -1131,6 +1120,7 @@ static int normal_execute(VimState *state, int key)
start_selection();
unshift_special(&s->ca);
s->idx = find_command(s->ca.cmdchar);
+ assert(s->idx >= 0);
} else if ((nv_cmds[s->idx].cmd_flags & NV_SSS)
&& (mod_mask & MOD_MASK_SHIFT)) {
start_selection();
@@ -1164,7 +1154,7 @@ static void normal_check_stuff_buffer(NormalState *s)
if (need_start_insertmode && goto_im() && !VIsual_active) {
need_start_insertmode = false;
- stuffReadbuff((uint8_t *)"i"); // start insert mode next
+ stuffReadbuff("i"); // start insert mode next
// skip the fileinfo message now, because it would be shown
// after insert mode finishes!
need_fileinfo = false;
@@ -1208,27 +1198,17 @@ static void normal_check_cursor_moved(NormalState *s)
apply_autocmds(EVENT_CURSORMOVED, NULL, NULL, false, curbuf);
}
- if (curwin->w_p_cole > 0) {
- s->conceal_old_cursor_line = last_cursormoved.lnum;
- s->conceal_new_cursor_line = curwin->w_cursor.lnum;
- s->conceal_update_lines = true;
- }
-
last_cursormoved = curwin->w_cursor;
}
}
static void normal_check_text_changed(NormalState *s)
{
- // Trigger TextChanged if b_changedtick differs.
+ // Trigger TextChanged if changedtick differs.
if (!finish_op && has_event(EVENT_TEXTCHANGED)
- && last_changedtick != curbuf->b_changedtick) {
- if (last_changedtick_buf == curbuf) {
- apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL, false, curbuf);
- }
-
- last_changedtick_buf = curbuf;
- last_changedtick = curbuf->b_changedtick;
+ && curbuf->b_last_changedtick != buf_get_changedtick(curbuf)) {
+ apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL, false, curbuf);
+ curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
}
}
@@ -1257,6 +1237,13 @@ static void normal_redraw(NormalState *s)
update_topline();
validate_cursor();
+ // If the cursor moves horizontally when 'concealcursor' is active, then the
+ // current line needs to be redrawn in order to calculate the correct
+ // cursor position.
+ if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)) {
+ redrawWinline(curwin, curwin->w_cursor.lnum);
+ }
+
if (VIsual_active) {
update_curbuf(INVERTED); // update inverted part
} else if (must_redraw) {
@@ -1276,11 +1263,12 @@ static void normal_redraw(NormalState *s)
// msg_attr_keep() will set keep_msg to NULL, must free the string here.
// Don't reset keep_msg, msg_attr_keep() uses it to check for duplicates.
char *p = (char *)keep_msg;
- msg_attr((uint8_t *)p, keep_msg_attr);
+ msg_attr(p, keep_msg_attr);
xfree(p);
}
- if (need_fileinfo) { // show file info after redraw
+ // show fileinfo after redraw
+ if (need_fileinfo && !shortmess(SHM_FILEINFO)) {
fileinfo(false, true, false);
need_fileinfo = false;
}
@@ -1291,22 +1279,6 @@ static void normal_redraw(NormalState *s)
may_clear_sb_text(); // clear scroll-back text on next msg
showruler(false);
- if (s->conceal_update_lines
- && (s->conceal_old_cursor_line !=
- s->conceal_new_cursor_line
- || conceal_cursor_line(curwin)
- || need_cursor_line_redraw)) {
- if (s->conceal_old_cursor_line !=
- s->conceal_new_cursor_line
- && s->conceal_old_cursor_line <=
- curbuf->b_ml.ml_line_count) {
- update_single_line(curwin, s->conceal_old_cursor_line);
- }
-
- update_single_line(curwin, s->conceal_new_cursor_line);
- curwin->w_valid &= ~VALID_CROW;
- }
-
setcursor();
}
@@ -1335,6 +1307,14 @@ static int normal_check(VimState *state)
normal_check_cursor_moved(s);
normal_check_text_changed(s);
+ // Updating diffs from changed() does not always work properly,
+ // esp. updating folds. Do an update just before redrawing if
+ // needed.
+ if (curtab->tp_diff_update || curtab->tp_diff_invalid) {
+ ex_diffupdate(NULL);
+ curtab->tp_diff_update = false;
+ }
+
// Scroll-binding for diff mode may have been postponed until
// here. Avoids doing it for every change.
if (diff_need_scrollbind) {
@@ -1361,7 +1341,7 @@ static int normal_check(VimState *state)
// Dict internally somewhere.
// "may_garbage_collect" is reset in vgetc() which is invoked through
// do_exmode() and normal_cmd().
- may_garbage_collect = s->toplevel;
+ may_garbage_collect = !s->cmdwin && !s->noexmode;
// Update w_curswant if w_set_curswant has been set.
// Postponed until here to avoid computing w_virtcol too often.
@@ -1447,8 +1427,10 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
oap->motion_type = kMTCharWise;
} else if (oap->motion_force == Ctrl_V) {
// Change line- or characterwise motion into Visual block mode.
- VIsual_active = true;
- VIsual = oap->start;
+ if (!VIsual_active) {
+ VIsual_active = true;
+ VIsual = oap->start;
+ }
VIsual_mode = Ctrl_V;
VIsual_select = false;
VIsual_reselect = false;
@@ -1458,9 +1440,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
/* Never redo "zf" (define fold). */
if ((vim_strchr(p_cpo, CPO_YANK) != NULL || oap->op_type != OP_YANK)
&& ((!VIsual_active || oap->motion_force)
- /* Also redo Operator-pending Visual mode mappings */
- || (VIsual_active && cap->cmdchar == ':'
- && oap->op_type != OP_COLON))
+ // Also redo Operator-pending Visual mode mappings.
+ || (cap->cmdchar == ':' && oap->op_type != OP_COLON))
&& cap->cmdchar != 'D'
&& oap->op_type != OP_FOLD
&& oap->op_type != OP_FOLDOPEN
@@ -1478,16 +1459,17 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* If 'cpoptions' does not contain 'r', insert the search
* pattern to really repeat the same command.
*/
- if (vim_strchr(p_cpo, CPO_REDO) == NULL)
+ if (vim_strchr(p_cpo, CPO_REDO) == NULL) {
AppendToRedobuffLit(cap->searchbuf, -1);
+ }
AppendToRedobuff(NL_STR);
- } else if (cap->cmdchar == ':') {
- /* do_cmdline() has stored the first typed line in
- * "repeat_cmdline". When several lines are typed repeating
- * won't be possible. */
- if (repeat_cmdline == NULL)
+ } else if (cap->cmdchar == ':' || cap->cmdchar == K_COMMAND) {
+ // do_cmdline() has stored the first typed line in
+ // "repeat_cmdline". When several lines are typed repeating
+ // won't be possible.
+ if (repeat_cmdline == NULL) {
ResetRedobuff();
- else {
+ } else {
AppendToRedobuffLit(repeat_cmdline, -1);
AppendToRedobuff(NL_STR);
xfree(repeat_cmdline);
@@ -1518,10 +1500,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
coladvance(curwin->w_curswant);
}
cap->count0 = redo_VIsual_count;
- if (redo_VIsual_count != 0)
- cap->count1 = redo_VIsual_count;
- else
- cap->count1 = 1;
+ cap->count1 = (cap->count0 == 0 ? 1 : cap->count0);
} else if (VIsual_active) {
if (!gui_yank) {
/* Save the current VIsual area for '< and '> marks, and "gv" */
@@ -1559,8 +1538,10 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
}
oap->start = VIsual;
- if (VIsual_mode == 'V')
+ if (VIsual_mode == 'V') {
oap->start.col = 0;
+ oap->start.coladd = 0;
+ }
}
/*
@@ -1598,6 +1579,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
oap->start = curwin->w_cursor;
}
+ // Just in case lines were deleted that make the position invalid.
+ check_pos(curwin->w_buffer, &oap->end);
oap->line_count = oap->end.lnum - oap->start.lnum + 1;
/* Set "virtual_op" before resetting VIsual_active. */
@@ -1644,16 +1627,22 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
/* Prepare for redoing. Only use the nchar field for "r",
* otherwise it might be the second char of the operator. */
if (cap->cmdchar == 'g' && (cap->nchar == 'n'
- || cap->nchar == 'N'))
+ || cap->nchar == 'N')) {
prep_redo(oap->regname, cap->count0,
- get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
- oap->motion_force, cap->cmdchar, cap->nchar);
- else if (cap->cmdchar != ':')
- prep_redo(oap->regname, 0L, NUL, 'v',
- get_op_char(oap->op_type),
- get_extra_op_char(oap->op_type),
- oap->op_type == OP_REPLACE
- ? cap->nchar : NUL);
+ get_op_char(oap->op_type), get_extra_op_char(oap->op_type),
+ oap->motion_force, cap->cmdchar, cap->nchar);
+ } else if (cap->cmdchar != ':') {
+ int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL;
+
+ // reverse what nv_replace() did
+ if (nchar == REPLACE_CR_NCHAR) {
+ nchar = CAR;
+ } else if (nchar == REPLACE_NL_NCHAR) {
+ nchar = NL;
+ }
+ prep_redo(oap->regname, 0L, NUL, 'v', get_op_char(oap->op_type),
+ get_extra_op_char(oap->op_type), nchar);
+ }
if (!redo_VIsual_busy) {
redo_VIsual_mode = resel_VIsual_mode;
redo_VIsual_vcol = resel_VIsual_vcol;
@@ -1812,7 +1801,10 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
} else {
(void)op_delete(oap);
if (oap->motion_type == kMTLineWise && has_format_option(FO_AUTO)) {
- u_save_cursor(); // cursor line wasn't saved yet
+ // cursor line wasn't saved yet
+ if (u_save_cursor() == FAIL) {
+ break;
+ }
}
auto_format(false, true);
}
@@ -1863,10 +1855,12 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FILTER:
- if (vim_strchr(p_cpo, CPO_FILTER) != NULL)
- AppendToRedobuff((char_u *)"!\r"); /* use any last used !cmd */
- else
- bangredo = true; /* do_bang() will put cmd in redo buffer */
+ if (vim_strchr(p_cpo, CPO_FILTER) != NULL) {
+ AppendToRedobuff("!\r"); // Use any last used !cmd.
+ } else {
+ bangredo = true; // do_bang() will put cmd in redo buffer.
+ }
+ FALLTHROUGH;
case OP_INDENT:
case OP_COLON:
@@ -1901,12 +1895,13 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FORMAT:
- if (*curbuf->b_p_fex != NUL)
- op_formatexpr(oap); /* use expression */
- else if (*p_fp != NUL)
- op_colon(oap); /* use external command */
- else
- op_format(oap, false); /* use internal function */
+ if (*curbuf->b_p_fex != NUL) {
+ op_formatexpr(oap); // use expression
+ } else if (*p_fp != NUL || *curbuf->b_p_fp != NUL) {
+ op_colon(oap); // use external command
+ } else {
+ op_format(oap, false); // use internal function
+ }
break;
case OP_FORMAT2:
@@ -1914,7 +1909,10 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break;
case OP_FUNCTION:
- op_function(oap); /* call 'operatorfunc' */
+ // Restore linebreak, so that when the user edits it looks as
+ // before.
+ curwin->w_p_lbr = lbr_saved;
+ op_function(oap); // call 'operatorfunc'
break;
case OP_INSERT:
@@ -1945,8 +1943,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* the lines. */
auto_format(false, true);
- if (restart_edit == 0)
+ if (restart_edit == 0) {
restart_edit = restart_edit_save;
+ } else {
+ cap->retval |= CA_COMMAND_BUSY;
+ }
}
break;
@@ -2007,7 +2008,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
default:
clearopbeep(oap);
}
- virtual_op = MAYBE;
+ virtual_op = kNone;
if (!gui_yank) {
/*
* if 'sol' not set, go back to old column for some commands
@@ -2022,6 +2023,7 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
curwin->w_cursor = old_cursor;
}
clearop(oap);
+ motion_force = NUL;
}
curwin->w_p_lbr = lbr_saved;
}
@@ -2032,40 +2034,44 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
static void op_colon(oparg_T *oap)
{
stuffcharReadbuff(':');
- if (oap->is_VIsual)
- stuffReadbuff((char_u *)"'<,'>");
- else {
- /*
- * Make the range look nice, so it can be repeated.
- */
- if (oap->start.lnum == curwin->w_cursor.lnum)
+ if (oap->is_VIsual) {
+ stuffReadbuff("'<,'>");
+ } else {
+ // Make the range look nice, so it can be repeated.
+ if (oap->start.lnum == curwin->w_cursor.lnum) {
stuffcharReadbuff('.');
- else
+ } else {
stuffnumReadbuff((long)oap->start.lnum);
+ }
if (oap->end.lnum != oap->start.lnum) {
stuffcharReadbuff(',');
- if (oap->end.lnum == curwin->w_cursor.lnum)
+ if (oap->end.lnum == curwin->w_cursor.lnum) {
stuffcharReadbuff('.');
- else if (oap->end.lnum == curbuf->b_ml.ml_line_count)
+ } else if (oap->end.lnum == curbuf->b_ml.ml_line_count) {
stuffcharReadbuff('$');
- else if (oap->start.lnum == curwin->w_cursor.lnum) {
- stuffReadbuff((char_u *)".+");
+ } else if (oap->start.lnum == curwin->w_cursor.lnum) {
+ stuffReadbuff(".+");
stuffnumReadbuff(oap->line_count - 1);
- } else
+ } else {
stuffnumReadbuff((long)oap->end.lnum);
+ }
}
}
- if (oap->op_type != OP_COLON)
- stuffReadbuff((char_u *)"!");
+ if (oap->op_type != OP_COLON) {
+ stuffReadbuff("!");
+ }
if (oap->op_type == OP_INDENT) {
- stuffReadbuff(get_equalprg());
- stuffReadbuff((char_u *)"\n");
+ stuffReadbuff((const char *)get_equalprg());
+ stuffReadbuff("\n");
} else if (oap->op_type == OP_FORMAT) {
- if (*p_fp == NUL)
- stuffReadbuff((char_u *)"fmt");
- else
- stuffReadbuff(p_fp);
- stuffReadbuff((char_u *)"\n']");
+ if (*curbuf->b_p_fp != NUL) {
+ stuffReadbuff((const char *)curbuf->b_p_fp);
+ } else if (*p_fp != NUL) {
+ stuffReadbuff((const char *)p_fp);
+ } else {
+ stuffReadbuff("fmt");
+ }
+ stuffReadbuff("\n']");
}
/*
@@ -2078,8 +2084,7 @@ static void op_colon(oparg_T *oap)
*/
static void op_function(oparg_T *oap)
{
- char_u *(argv[1]);
- int save_virtual_op = virtual_op;
+ const TriState save_virtual_op = virtual_op;
if (*p_opfunc == NUL)
EMSG(_("E774: 'operatorfunc' is empty"));
@@ -2092,17 +2097,17 @@ static void op_function(oparg_T *oap)
decl(&curbuf->b_op_end);
}
- if (oap->motion_type == kMTBlockWise) {
- argv[0] = (char_u *)"block";
- } else if (oap->motion_type == kMTLineWise) {
- argv[0] = (char_u *)"line";
- } else {
- argv[0] = (char_u *)"char";
- }
+ const char_u *const argv[1] = {
+ (const char_u *)(((const char *const[]) {
+ [kMTBlockWise] = "block",
+ [kMTLineWise] = "line",
+ [kMTCharWise] = "char",
+ })[oap->motion_type]),
+ };
- /* Reset virtual_op so that 'virtualedit' can be changed in the
- * function. */
- virtual_op = MAYBE;
+ // Reset virtual_op so that 'virtualedit' can be changed in the
+ // function.
+ virtual_op = kNone;
(void)call_func_retnr(p_opfunc, 1, argv, false);
@@ -2110,6 +2115,20 @@ static void op_function(oparg_T *oap)
}
}
+// Move the current tab to tab in same column as mouse or to end of the
+// tabline if there is no tab there.
+static void move_tab_to_mouse(void)
+{
+ int tabnr = tab_page_click_defs[mouse_col].tabnr;
+ if (tabnr <= 0) {
+ tabpage_move(9999);
+ } else if (tabnr < tabpage_index(curtab)) {
+ tabpage_move(tabnr - 1);
+ } else {
+ tabpage_move(tabnr);
+ }
+}
+
/*
* Do the appropriate action for the current mouse click in the current mode.
* Not used for Command-line mode.
@@ -2294,7 +2313,7 @@ do_mouse (
if (VIsual_active) {
if (VIsual_select) {
stuffcharReadbuff(Ctrl_G);
- stuffReadbuff((char_u *)"\"+p");
+ stuffReadbuff("\"+p");
} else {
stuffcharReadbuff('y');
stuffcharReadbuff(K_MIDDLEMOUSE);
@@ -2321,10 +2340,11 @@ do_mouse (
if (regname == 0 && eval_has_provider("clipboard")) {
regname = '*';
}
- if ((State & REPLACE_FLAG) && !yank_register_mline(regname))
+ if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) {
insert_reg(regname, true);
- else {
- do_put(regname, NULL, BACKWARD, 1L, fixindent | PUT_CURSEND);
+ } else {
+ do_put(regname, NULL, BACKWARD, 1L,
+ (fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND);
/* Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r */
AppendCharToRedobuff(Ctrl_R);
@@ -2346,12 +2366,7 @@ do_mouse (
if (mouse_row == 0 && firstwin->w_winrow > 0) {
if (is_drag) {
if (in_tab_line) {
- if (tab_page_click_defs[mouse_col].type == kStlClickTabClose) {
- tabpage_move(9999);
- } else {
- int tabnr = tab_page_click_defs[mouse_col].tabnr;
- tabpage_move(tabnr < tabpage_index(curtab) ? tabnr - 1 : tabnr);
- }
+ move_tab_to_mouse();
}
return false;
}
@@ -2454,22 +2469,19 @@ do_mouse (
};
typval_T rettv;
int doesrange;
- (void) call_func((char_u *) tab_page_click_defs[mouse_col].func,
- (int) strlen(tab_page_click_defs[mouse_col].func),
- &rettv, ARRAY_SIZE(argv), argv,
- curwin->w_cursor.lnum, curwin->w_cursor.lnum,
- &doesrange, true, NULL);
- clear_tv(&rettv);
+ (void)call_func((char_u *)tab_page_click_defs[mouse_col].func,
+ (int)strlen(tab_page_click_defs[mouse_col].func),
+ &rettv, ARRAY_SIZE(argv), argv, NULL,
+ curwin->w_cursor.lnum, curwin->w_cursor.lnum,
+ &doesrange, true, NULL, NULL);
+ tv_clear(&rettv);
break;
}
}
}
return true;
} else if (is_drag && in_tab_line) {
- tabpage_move(tab_page_click_defs[mouse_col].type == kStlClickTabClose
- ? 9999
- : tab_page_click_defs[mouse_col].tabnr - 1);
- in_tab_line = false;
+ move_tab_to_mouse();
return false;
}
@@ -2684,7 +2696,8 @@ do_mouse (
*/
if (restart_edit != 0)
where_paste_started = curwin->w_cursor;
- do_put(regname, NULL, dir, count, fixindent | PUT_CURSEND);
+ do_put(regname, NULL, dir, count,
+ (fixindent ? PUT_FIXINDENT : 0)| PUT_CURSEND);
}
/*
* Ctrl-Mouse click or double click in a quickfix window jumps to the
@@ -2693,13 +2706,12 @@ do_mouse (
else if (((mod_mask & MOD_MASK_CTRL)
|| (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
&& bt_quickfix(curbuf)) {
- if (State & INSERT)
- stuffcharReadbuff(Ctrl_O);
- if (curwin->w_llist_ref == NULL) /* quickfix window */
- stuffReadbuff((char_u *)":.cc\n");
- else /* location list window */
- stuffReadbuff((char_u *)":.ll\n");
- got_click = false; /* ignore drag&release now */
+ if (curwin->w_llist_ref == NULL) { // quickfix window
+ do_cmdline_cmd(".cc");
+ } else { // location list window
+ do_cmdline_cmd(".ll");
+ }
+ got_click = false; // ignore drag&release now
}
/*
* Ctrl-Mouse click (or double click in a help window) jumps to the tag
@@ -2734,10 +2746,9 @@ do_mouse (
} else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (NORMAL | INSERT))
&& mouse_has(MOUSE_VISUAL)) {
if (is_click || !VIsual_active) {
- if (VIsual_active)
+ if (VIsual_active) {
orig_cursor = VIsual;
- else {
- check_visual_highlight();
+ } else {
VIsual = curwin->w_cursor;
orig_cursor = VIsual;
VIsual_active = true;
@@ -2840,9 +2851,10 @@ static void find_start_of_word(pos_T *pos)
while (pos->col > 0) {
col = pos->col - 1;
- col -= (*mb_head_off)(line, line + col);
- if (get_mouse_class(line + col) != cclass)
+ col -= utf_head_off(line, line + col);
+ if (get_mouse_class(line + col) != cclass) {
break;
+ }
pos->col = col;
}
}
@@ -2859,8 +2871,8 @@ static void find_end_of_word(pos_T *pos)
line = ml_get(pos->lnum);
if (*p_sel == 'e' && pos->col > 0) {
- --pos->col;
- pos->col -= (*mb_head_off)(line, line + pos->col);
+ pos->col--;
+ pos->col -= utf_head_off(line, line + pos->col);
}
cclass = get_mouse_class(line + pos->col);
while (line[pos->col] != NUL) {
@@ -2907,21 +2919,6 @@ static int get_mouse_class(char_u *p)
}
/*
- * Check if highlighting for visual mode is possible, give a warning message
- * if not.
- */
-void check_visual_highlight(void)
-{
- static bool did_check = false;
-
- if (full_screen) {
- if (!did_check && hl_attr(HLF_V) == 0)
- MSG(_("Warning: terminal cannot highlight"));
- did_check = true;
- }
-}
-
-/*
* End Visual mode.
* This function should ALWAYS be called to end Visual mode, except from
* do_pending_operator().
@@ -2971,6 +2968,43 @@ void reset_VIsual(void)
}
}
+// Check for a balloon-eval special item to include when searching for an
+// identifier. When "dir" is BACKWARD "ptr[-1]" must be valid!
+// Returns true if the character at "*ptr" should be included.
+// "dir" is FORWARD or BACKWARD, the direction of searching.
+// "*colp" is in/decremented if "ptr[-dir]" should also be included.
+// "bnp" points to a counter for square brackets.
+static bool find_is_eval_item(
+ const char_u *const ptr,
+ int *const colp,
+ int *const bnp,
+ const int dir)
+{
+ // Accept everything inside [].
+ if ((*ptr == ']' && dir == BACKWARD) || (*ptr == '[' && dir == FORWARD)) {
+ *bnp += 1;
+ }
+ if (*bnp > 0) {
+ if ((*ptr == '[' && dir == BACKWARD) || (*ptr == ']' && dir == FORWARD)) {
+ *bnp -= 1;
+ }
+ return true;
+ }
+
+ // skip over "s.var"
+ if (*ptr == '.') {
+ return true;
+ }
+
+ // two-character item: s->var
+ if (ptr[dir == BACKWARD ? 0 : 1] == '>'
+ && ptr[dir == BACKWARD ? -1 : 0] == '-') {
+ *colp += dir;
+ return true;
+ }
+ return false;
+}
+
/*
* Find the identifier under or to the right of the cursor.
* "find_type" can have one of three values:
@@ -3011,6 +3045,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
int this_class = 0;
int prev_class;
int prevcol;
+ int bn = 0; // bracket nesting
/*
* if i == 0: try to find an identifier
@@ -3022,71 +3057,62 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
* 1. skip to start of identifier/string
*/
col = startcol;
- if (has_mbyte) {
- while (ptr[col] != NUL) {
- this_class = mb_get_class(ptr + col);
- if (this_class != 0 && (i == 1 || this_class != 1))
- break;
- col += (*mb_ptr2len)(ptr + col);
+ while (ptr[col] != NUL) {
+ // Stop at a ']' to evaluate "a[x]".
+ if ((find_type & FIND_EVAL) && ptr[col] == ']') {
+ break;
}
- } else
- while (ptr[col] != NUL
- && (i == 0 ? !vim_iswordc(ptr[col]) : ascii_iswhite(ptr[col]))
- )
- ++col;
-
-
- /*
- * 2. Back up to start of identifier/string.
- */
- if (has_mbyte) {
- /* Remember class of character under cursor. */
this_class = mb_get_class(ptr + col);
- while (col > 0 && this_class != 0) {
- prevcol = col - 1 - (*mb_head_off)(ptr, ptr + col - 1);
- prev_class = mb_get_class(ptr + prevcol);
- if (this_class != prev_class
- && (i == 0
- || prev_class == 0
- || (find_type & FIND_IDENT))
- )
- break;
- col = prevcol;
+ if (this_class != 0 && (i == 1 || this_class != 1)) {
+ break;
}
+ col += utfc_ptr2len(ptr + col);
+ }
- /* If we don't want just any old string, or we've found an
- * identifier, stop searching. */
- if (this_class > 2)
- this_class = 2;
- if (!(find_type & FIND_STRING) || this_class == 2)
- break;
- } else {
- while (col > 0
- && ((i == 0
- ? vim_iswordc(ptr[col - 1])
- : (!ascii_iswhite(ptr[col - 1])
- && (!(find_type & FIND_IDENT)
- || !vim_iswordc(ptr[col - 1]))))
- ))
- --col;
+ // When starting on a ']' count it, so that we include the '['.
+ bn = ptr[col] == ']';
- /* If we don't want just any old string, or we've found an
- * identifier, stop searching. */
- if (!(find_type & FIND_STRING) || vim_iswordc(ptr[col]))
+ //
+ // 2. Back up to start of identifier/string.
+ //
+ // Remember class of character under cursor.
+ if ((find_type & FIND_EVAL) && ptr[col] == ']') {
+ this_class = mb_get_class((char_u *)"a");
+ } else {
+ this_class = mb_get_class(ptr + col);
+ }
+ while (col > 0 && this_class != 0) {
+ prevcol = col - 1 - utf_head_off(ptr, ptr + col - 1);
+ prev_class = mb_get_class(ptr + prevcol);
+ if (this_class != prev_class
+ && (i == 0
+ || prev_class == 0
+ || (find_type & FIND_IDENT))
+ && (!(find_type & FIND_EVAL)
+ || prevcol == 0
+ || !find_is_eval_item(ptr + prevcol, &prevcol, &bn, BACKWARD))) {
break;
+ }
+ col = prevcol;
+ }
+
+ // If we don't want just any old string, or we've found an
+ // identifier, stop searching.
+ if (this_class > 2) {
+ this_class = 2;
+ }
+ if (!(find_type & FIND_STRING) || this_class == 2) {
+ break;
}
}
- if (ptr[col] == NUL || (i == 0 && (
- has_mbyte ? this_class != 2 :
- !vim_iswordc(ptr[col])))) {
- /*
- * didn't find an identifier or string
- */
- if (find_type & FIND_STRING)
+ if (ptr[col] == NUL || (i == 0 && this_class != 2)) {
+ // Didn't find an identifier or string.
+ if (find_type & FIND_STRING) {
EMSG(_("E348: No string under cursor"));
- else
+ } else {
EMSG(_(e_noident));
+ }
return 0;
}
ptr += col;
@@ -3095,21 +3121,20 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
/*
* 3. Find the end if the identifier/string.
*/
+ bn = 0;
+ startcol -= col;
col = 0;
- if (has_mbyte) {
- /* Search for point of changing multibyte character class. */
- this_class = mb_get_class(ptr);
- while (ptr[col] != NUL
- && ((i == 0 ? mb_get_class(ptr + col) == this_class
- : mb_get_class(ptr + col) != 0)
- ))
- col += (*mb_ptr2len)(ptr + col);
- } else
- while ((i == 0 ? vim_iswordc(ptr[col])
- : (ptr[col] != NUL && !ascii_iswhite(ptr[col])))
- ) {
- ++col;
- }
+ // Search for point of changing multibyte character class.
+ this_class = mb_get_class(ptr);
+ while (ptr[col] != NUL
+ && ((i == 0
+ ? mb_get_class(ptr + col) == this_class
+ : mb_get_class(ptr + col) != 0)
+ || ((find_type & FIND_EVAL)
+ && col <= (int)startcol
+ && find_is_eval_item(ptr + col, &col, &bn, FORWARD)))) {
+ col += utfc_ptr2len(ptr + col);
+ }
assert(col >= 0);
return (size_t)col;
@@ -3409,10 +3434,10 @@ static void display_showcmd(void)
int len;
len = (int)STRLEN(showcmd_buf);
- if (len == 0)
+ if (len == 0) {
showcmd_is_clear = true;
- else {
- screen_puts(showcmd_buf, (int)Rows - 1, sc_col, 0);
+ } else {
+ grid_puts(&default_grid, showcmd_buf, (int)Rows - 1, sc_col, 0);
showcmd_is_clear = false;
}
@@ -3420,7 +3445,8 @@ static void display_showcmd(void)
* clear the rest of an old message by outputting up to SHOWCMD_COLS
* spaces
*/
- screen_puts((char_u *)" " + len, (int)Rows - 1, sc_col + len, 0);
+ grid_puts(&default_grid, (char_u *)" " + len, (int)Rows - 1,
+ sc_col + len, 0);
setcursor(); /* put cursor back where it belongs */
}
@@ -3509,7 +3535,8 @@ void check_scrollbind(linenr_T topline_diff, long leftcol_diff)
* loop through the scrollbound windows and scroll accordingly
*/
VIsual_select = VIsual_active = 0;
- for (curwin = firstwin; curwin; curwin = curwin->w_next) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ curwin = wp;
curbuf = curwin->w_buffer;
/* skip original window and windows with 'noscrollbind' */
if (curwin == old_curwin || !curwin->w_p_scb) {
@@ -3641,10 +3668,44 @@ nv_gd (
size_t len;
char_u *ptr;
if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0
- || !find_decl(ptr, len, nchar == 'd', thisblock, 0))
+ || !find_decl(ptr, len, nchar == 'd', thisblock, SEARCH_START)) {
clearopbeep(oap);
- else if ((fdo_flags & FDO_SEARCH) && KeyTyped && oap->op_type == OP_NOP)
+ } else if ((fdo_flags & FDO_SEARCH) && KeyTyped && oap->op_type == OP_NOP) {
foldOpenCursor();
+ }
+}
+
+// Return true if line[offset] is not inside a C-style comment or string, false
+// otherwise.
+static bool is_ident(char_u *line, int offset)
+{
+ bool incomment = false;
+ int instring = 0;
+ int prev = 0;
+
+ for (int i = 0; i < offset && line[i] != NUL; i++) {
+ if (instring != 0) {
+ if (prev != '\\' && line[i] == instring) {
+ instring = 0;
+ }
+ } else if ((line[i] == '"' || line[i] == '\'') && !incomment) {
+ instring = line[i];
+ } else {
+ if (incomment) {
+ if (prev == '*' && line[i] == '/') {
+ incomment = false;
+ }
+ } else if (prev == '/' && line[i] == '*') {
+ incomment = true;
+ } else if (prev == '/' && line[i] == '/') {
+ return false;
+ }
+ }
+
+ prev = line[i];
+ }
+
+ return incomment == false && instring == 0;
}
/*
@@ -3660,7 +3721,7 @@ find_decl (
size_t len,
bool locally,
bool thisblock,
- int searchflags /* flags passed to searchit() */
+ int flags_arg // flags passed to searchit()
)
{
char_u *pat;
@@ -3672,6 +3733,8 @@ find_decl (
bool save_p_scs;
bool retval = true;
bool incll;
+ int searchflags = flags_arg;
+ bool valid;
pat = xmalloc(len + 7);
@@ -3706,20 +3769,25 @@ find_decl (
/* Search forward for the identifier, ignore comment lines. */
clearpos(&found_pos);
for (;; ) {
+ valid = false;
+ (void)valid; // Avoid "dead assignment" warning.
t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD,
pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum)
t = false; /* match after start is failure too */
if (thisblock && t != false) {
- pos_T *pos;
-
- /* Check that the block the match is in doesn't end before the
- * position where we started the search from. */
- if ((pos = findmatchlimit(NULL, '}', FM_FORWARD,
- (int)(old_pos.lnum - curwin->w_cursor.lnum + 1))) != NULL
- && pos->lnum < old_pos.lnum)
+ const int64_t maxtravel = old_pos.lnum - curwin->w_cursor.lnum + 1;
+ const pos_T *pos = findmatchlimit(NULL, '}', FM_FORWARD, maxtravel);
+
+ // Check that the block the match is in doesn't end before the
+ // position where we started the search from.
+ if (pos != NULL && pos->lnum < old_pos.lnum) {
+ // There can't be a useful match before the end of this block.
+ // Skip to the end
+ curwin->w_cursor = *pos;
continue;
+ }
}
if (t == false) {
@@ -3736,19 +3804,36 @@ find_decl (
curwin->w_cursor.col = 0;
continue;
}
- if (!locally) /* global search: use first match found */
+ valid = is_ident(get_cursor_line_ptr(), curwin->w_cursor.col);
+
+ // If the current position is not a valid identifier and a previous match is
+ // present, favor that one instead.
+ if (!valid && found_pos.lnum != 0) {
+ curwin->w_cursor = found_pos;
break;
- if (curwin->w_cursor.lnum >= par_pos.lnum) {
- /* If we previously found a valid position, use it. */
- if (found_pos.lnum != 0)
+ }
+ // global search: use first match found
+ if (valid && !locally) {
+ break;
+ }
+ if (valid && curwin->w_cursor.lnum >= par_pos.lnum) {
+ // If we previously found a valid position, use it.
+ if (found_pos.lnum != 0) {
curwin->w_cursor = found_pos;
+ }
break;
}
- /* For finding a local variable and the match is before the "{" search
- * to find a later match. For K&R style function declarations this
- * skips the function header without types. */
- found_pos = curwin->w_cursor;
+ // For finding a local variable and the match is before the "{" or
+ // inside a comment, continue searching. For K&R style function
+ // declarations this skips the function header without types.
+ if (!valid) {
+ clearpos(&found_pos);
+ } else {
+ found_pos = curwin->w_cursor;
+ }
+ // Remove SEARCH_START from flags to avoid getting stuck at one position.
+ searchflags &= ~SEARCH_START;
}
if (t == false) {
@@ -3790,18 +3875,16 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
col_off1 = curwin_col_off();
col_off2 = col_off1 - curwin_col_off2();
- width1 = curwin->w_width - col_off1;
- width2 = curwin->w_width - col_off2;
+ width1 = curwin->w_grid.Columns - col_off1;
+ width2 = curwin->w_grid.Columns - col_off2;
if (width2 == 0) {
width2 = 1; // Avoid divide by zero.
}
- if (curwin->w_width != 0) {
- /*
- * Instead of sticking at the last character of the buffer line we
- * try to stick in the last column of the screen.
- */
+ if (curwin->w_grid.Columns != 0) {
+ // Instead of sticking at the last character of the buffer line we
+ // try to stick in the last column of the screen.
if (curwin->w_curswant == MAXCOL) {
atend = true;
validate_virtcol();
@@ -3842,9 +3925,11 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
(void)hasFolding(curwin->w_cursor.lnum,
&curwin->w_cursor.lnum, NULL);
linelen = linetabsize(get_cursor_line_ptr());
- if (linelen > width1)
- curwin->w_curswant += (((linelen - width1 - 1) / width2)
- + 1) * width2;
+ if (linelen > width1) {
+ int w = (((linelen - width1 - 1) / width2) + 1) * width2;
+ assert(curwin->w_curswant <= INT_MAX - w);
+ curwin->w_curswant += w;
+ }
}
} else { /* dir == FORWARD */
if (linelen > width1)
@@ -3917,8 +4002,12 @@ static void nv_mousescroll(cmdarg_T *cap)
row = mouse_row;
col = mouse_col;
- /* find the window at the pointer coordinates */
- curwin = mouse_find_win(&row, &col);
+ // find the window at the pointer coordinates
+ win_T *const wp = mouse_find_win(&row, &col);
+ if (wp == NULL) {
+ return;
+ }
+ curwin = wp;
curbuf = curwin->w_buffer;
}
@@ -4028,12 +4117,10 @@ static void nv_zet(cmdarg_T *cap)
return;
n = nchar - '0';
for (;; ) {
- ++no_mapping;
- ++allow_keys; /* no mapping for nchar, but allow key codes */
+ no_mapping++;
nchar = plain_vgetc();
LANGMAP_ADJUST(nchar, true);
- --no_mapping;
- --allow_keys;
+ no_mapping--;
(void)add_to_showcmd(nchar);
if (nchar == K_DEL || nchar == K_KDEL)
n /= 10;
@@ -4094,12 +4181,12 @@ dozet:
else
curwin->w_cursor.lnum = curwin->w_botline;
}
- /* FALLTHROUGH */
+ FALLTHROUGH;
case NL:
case CAR:
case K_KENTER:
beginline(BL_WHITE | BL_FIX);
- /* FALLTHROUGH */
+ FALLTHROUGH;
case 't': scroll_cursor_top(0, true);
redraw_later(VALID);
@@ -4108,7 +4195,7 @@ dozet:
/* "z." and "zz": put cursor in middle of screen */
case '.': beginline(BL_WHITE | BL_FIX);
- /* FALLTHROUGH */
+ FALLTHROUGH;
case 'z': scroll_cursor_halfway(true);
redraw_later(VALID);
@@ -4126,10 +4213,10 @@ dozet:
curwin->w_cursor.lnum = 1;
else
curwin->w_cursor.lnum = curwin->w_topline - 1;
- /* FALLTHROUGH */
+ FALLTHROUGH;
case '-':
beginline(BL_WHITE | BL_FIX);
- /* FALLTHROUGH */
+ FALLTHROUGH;
case 'b': scroll_cursor_bot(0, true);
redraw_later(VALID);
@@ -4138,8 +4225,8 @@ dozet:
/* "zH" - scroll screen right half-page */
case 'H':
- cap->count1 *= curwin->w_width / 2;
- /* FALLTHROUGH */
+ cap->count1 *= curwin->w_grid.Columns / 2;
+ FALLTHROUGH;
/* "zh" - scroll screen to the right */
case 'h':
@@ -4153,9 +4240,9 @@ dozet:
}
break;
- /* "zL" - scroll screen left half-page */
- case 'L': cap->count1 *= curwin->w_width / 2;
- /* FALLTHROUGH */
+ // "zL" - scroll screen left half-page
+ case 'L': cap->count1 *= curwin->w_grid.Columns / 2;
+ FALLTHROUGH;
/* "zl" - scroll screen to the left */
case 'l':
@@ -4190,11 +4277,12 @@ dozet:
col = 0; /* like the cursor is in col 0 */
else
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
- n = curwin->w_width - curwin_col_off();
- if (col + l_p_siso < n)
+ n = curwin->w_grid.Columns - curwin_col_off();
+ if (col + l_p_siso < n) {
col = 0;
- else
+ } else {
col = col + l_p_siso - n + 1;
+ }
if (curwin->w_leftcol != col) {
curwin->w_leftcol = col;
redraw_later(NOT_VALID);
@@ -4361,20 +4449,18 @@ dozet:
break;
- case 'u': /* "zug" and "zuw": undo "zg" and "zw" */
- ++no_mapping;
- ++allow_keys; /* no mapping for nchar, but allow key codes */
+ case 'u': // "zug" and "zuw": undo "zg" and "zw"
+ no_mapping++;
nchar = plain_vgetc();
LANGMAP_ADJUST(nchar, true);
- --no_mapping;
- --allow_keys;
+ no_mapping--;
(void)add_to_showcmd(nchar);
if (vim_strchr((char_u *)"gGwW", nchar) == NULL) {
clearopbeep(cap->oap);
break;
}
undo = true;
- /*FALLTHROUGH*/
+ FALLTHROUGH;
case 'g': /* "zg": add good word to word list */
case 'w': /* "zw": add wrong word to word list */
@@ -4455,26 +4541,25 @@ static void nv_exmode(cmdarg_T *cap)
}
}
-/*
- * Handle a ":" command.
- */
+/// Handle a ":" command and <Cmd>.
static void nv_colon(cmdarg_T *cap)
{
int old_p_im;
bool cmd_result;
+ bool is_cmdkey = cap->cmdchar == K_COMMAND;
- if (VIsual_active)
+ if (VIsual_active && !is_cmdkey) {
nv_operator(cap);
- else {
+ } else {
if (cap->oap->op_type != OP_NOP) {
// Using ":" as a movement is characterwise exclusive.
cap->oap->motion_type = kMTCharWise;
cap->oap->inclusive = false;
- } else if (cap->count0) {
- /* translate "count:" into ":.,.+(count - 1)" */
+ } else if (cap->count0 && !is_cmdkey) {
+ // translate "count:" into ":.,.+(count - 1)"
stuffcharReadbuff('.');
if (cap->count0 > 1) {
- stuffReadbuff((char_u *)",.+");
+ stuffReadbuff(",.+");
stuffnumReadbuff(cap->count0 - 1L);
}
}
@@ -4485,9 +4570,9 @@ static void nv_colon(cmdarg_T *cap)
old_p_im = p_im;
- /* get a command line and execute it */
- cmd_result = do_cmdline(NULL, getexline, NULL,
- cap->oap->op_type != OP_NOP ? DOCMD_KEEPLINE : 0);
+ // get a command line and execute it
+ cmd_result = do_cmdline(NULL, is_cmdkey ? getcmdkeycmd : getexline, NULL,
+ cap->oap->op_type != OP_NOP ? DOCMD_KEEPLINE : 0);
/* If 'insertmode' changed, enter or exit Insert mode */
if (p_im != old_p_im) {
@@ -4665,6 +4750,11 @@ static void nv_ident(cmdarg_T *cap)
char_u *kp = *curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp; // 'keywordprg'
assert(*kp != NUL); // option.c:do_set() should default to ":help" if empty.
bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command
+ bool kp_help = (STRCMP(kp, ":he") == 0 || STRCMP(kp, ":help") == 0);
+ if (kp_help && *skipwhite(ptr) == NUL) {
+ EMSG(_(e_noident)); // found white space only
+ return;
+ }
size_t buf_size = n * 2 + 30 + STRLEN(kp);
char *buf = xmalloc(buf_size);
buf[0] = NUL;
@@ -4687,7 +4777,9 @@ static void nv_ident(cmdarg_T *cap)
break;
case 'K':
- if (kp_ex) {
+ if (kp_help) {
+ STRCPY(buf, "he! ");
+ } else if (kp_ex) {
if (cap->count0 != 0) { // Send the count to the ex command.
snprintf(buf, buf_size, "%" PRId64, (int64_t)(cap->count0));
}
@@ -4749,13 +4841,16 @@ static void nv_ident(cmdarg_T *cap)
}
}
- /*
- * Now grab the chars in the identifier
- */
- if (cmdchar == 'K' && !kp_ex) {
- /* Escape the argument properly for a shell command */
+ // Now grab the chars in the identifier
+ if (cmdchar == 'K' && !kp_help) {
ptr = vim_strnsave(ptr, n);
- p = vim_strsave_shellescape(ptr, true, true);
+ if (kp_ex) {
+ // Escape the argument properly for an Ex command
+ p = (char_u *)vim_strsave_fnameescape((const char *)ptr, false);
+ } else {
+ // Escape the argument properly for a shell command
+ p = vim_strsave_shellescape(ptr, true, true);
+ }
xfree(ptr);
char *newbuf = xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1);
buf = newbuf;
@@ -4892,11 +4987,11 @@ static void nv_scroll(cmdarg_T *cap)
/* Don't count filler lines above the window. */
used -= diff_check_fill(curwin, curwin->w_topline)
- curwin->w_topfill;
- validate_botline(); /* make sure w_empty_rows is valid */
- half = (curwin->w_height - curwin->w_empty_rows + 1) / 2;
- for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; ++n) {
- /* Count half he number of filler lines to be "below this
- * line" and half to be "above the next line". */
+ validate_botline(); // make sure w_empty_rows is valid
+ half = (curwin->w_grid.Rows - curwin->w_empty_rows + 1) / 2;
+ for (n = 0; curwin->w_topline + n < curbuf->b_ml.ml_line_count; n++) {
+ // Count half he number of filler lines to be "below this
+ // line" and half to be "above the next line".
if (n > 0 && used + diff_check_fill(curwin, curwin->w_topline
+ n) / 2 >= half) {
--n;
@@ -4908,9 +5003,10 @@ static void nv_scroll(cmdarg_T *cap)
if (hasFolding(curwin->w_topline + n, NULL, &lnum))
n = lnum - curwin->w_topline;
}
- if (n > 0 && used > curwin->w_height)
- --n;
- } else { /* (cap->cmdchar == 'H') */
+ if (n > 0 && used > curwin->w_grid.Rows) {
+ n--;
+ }
+ } else { // (cap->cmdchar == 'H')
n = cap->count1 - 1;
if (hasAnyFolding(curwin)) {
/* Count a fold for one screen line. */
@@ -4927,7 +5023,10 @@ static void nv_scroll(cmdarg_T *cap)
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
}
- cursor_correct(); /* correct for 'so' */
+ // Correct for 'so', except when an operator is pending.
+ if (cap->oap->op_type == OP_NOP) {
+ cursor_correct();
+ }
beginline(BL_SOL | BL_FIX);
}
@@ -4962,26 +5061,21 @@ static void nv_right(cmdarg_T *cap)
if ((!PAST_LINE && oneright() == false)
|| (PAST_LINE && *get_cursor_pos_ptr() == NUL)
) {
- /*
- * <Space> wraps to next line if 'whichwrap' has 's'.
- * 'l' wraps to next line if 'whichwrap' has 'l'.
- * CURS_RIGHT wraps to next line if 'whichwrap' has '>'.
- */
- if ( ((cap->cmdchar == ' '
- && vim_strchr(p_ww, 's') != NULL)
- || (cap->cmdchar == 'l'
- && vim_strchr(p_ww, 'l') != NULL)
- || (cap->cmdchar == K_RIGHT
- && vim_strchr(p_ww, '>') != NULL))
- && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
- /* When deleting we also count the NL as a character.
- * Set cap->oap->inclusive when last char in the line is
- * included, move to next line after that */
- if ( cap->oap->op_type != OP_NOP
- && !cap->oap->inclusive
- && !lineempty(curwin->w_cursor.lnum))
+ // <Space> wraps to next line if 'whichwrap' has 's'.
+ // 'l' wraps to next line if 'whichwrap' has 'l'.
+ // CURS_RIGHT wraps to next line if 'whichwrap' has '>'.
+ if (((cap->cmdchar == ' ' && vim_strchr(p_ww, 's') != NULL)
+ || (cap->cmdchar == 'l' && vim_strchr(p_ww, 'l') != NULL)
+ || (cap->cmdchar == K_RIGHT && vim_strchr(p_ww, '>') != NULL))
+ && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
+ // When deleting we also count the NL as a character.
+ // Set cap->oap->inclusive when last char in the line is
+ // included, move to next line after that
+ if (cap->oap->op_type != OP_NOP
+ && !cap->oap->inclusive
+ && !LINEEMPTY(curwin->w_cursor.lnum)) {
cap->oap->inclusive = true;
- else {
+ } else {
++curwin->w_cursor.lnum;
curwin->w_cursor.col = 0;
curwin->w_cursor.coladd = 0;
@@ -4991,12 +5085,14 @@ static void nv_right(cmdarg_T *cap)
continue;
}
if (cap->oap->op_type == OP_NOP) {
- /* Only beep and flush if not moved at all */
- if (n == cap->count1)
+ // Only beep and flush if not moved at all
+ if (n == cap->count1) {
beep_flush();
+ }
} else {
- if (!lineempty(curwin->w_cursor.lnum))
+ if (!LINEEMPTY(curwin->w_cursor.lnum)) {
cap->oap->inclusive = true;
+ }
}
break;
} else if (PAST_LINE) {
@@ -5054,13 +5150,12 @@ static void nv_left(cmdarg_T *cap)
coladvance((colnr_T)MAXCOL);
curwin->w_set_curswant = true;
- /* When the NL before the first char has to be deleted we
- * put the cursor on the NUL after the previous line.
- * This is a very special case, be careful!
- * Don't adjust op_end now, otherwise it won't work. */
- if ( (cap->oap->op_type == OP_DELETE
- || cap->oap->op_type == OP_CHANGE)
- && !lineempty(curwin->w_cursor.lnum)) {
+ // When the NL before the first char has to be deleted we
+ // put the cursor on the NUL after the previous line.
+ // This is a very special case, be careful!
+ // Don't adjust op_end now, otherwise it won't work.
+ if ((cap->oap->op_type == OP_DELETE || cap->oap->op_type == OP_CHANGE)
+ && !LINEEMPTY(curwin->w_cursor.lnum)) {
char_u *cp = get_cursor_pos_ptr();
if (*cp != NUL) {
@@ -5159,13 +5254,13 @@ static void nv_gotofile(cmdarg_T *cap)
if (ptr != NULL) {
// do autowrite if necessary
- if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !P_HID(curbuf)) {
+ if (curbufIsChanged() && curbuf->b_nwindows <= 1 && !buf_hide(curbuf)) {
(void)autowrite(curbuf, false);
}
setpcmark();
- (void)do_ecmd(0, ptr, NULL, NULL, ECMD_LAST,
- P_HID(curbuf) ? ECMD_HIDE : 0, curwin);
- if (cap->nchar == 'F' && lnum >= 0) {
+ if (do_ecmd(0, ptr, NULL, NULL, ECMD_LAST,
+ buf_hide(curbuf) ? ECMD_HIDE : 0, curwin) == OK
+ && cap->nchar == 'F' && lnum >= 0) {
curwin->w_cursor.lnum = lnum;
check_cursor_lnum();
beginline(BL_SOL | BL_FIX);
@@ -5215,6 +5310,7 @@ static void nv_dollar(cmdarg_T *cap)
static void nv_search(cmdarg_T *cap)
{
oparg_T *oap = cap->oap;
+ pos_T save_cursor = curwin->w_cursor;
if (cap->cmdchar == '?' && cap->oap->op_type == OP_ROT13) {
/* Translate "g??" to "g?g?" */
@@ -5224,6 +5320,8 @@ static void nv_search(cmdarg_T *cap)
return;
}
+ // When using 'incsearch' the cursor may be moved to set a different search
+ // start position.
cap->searchbuf = getcmdline(cap->cmdchar, cap->count1, 0);
if (cap->searchbuf == NULL) {
@@ -5232,7 +5330,8 @@ static void nv_search(cmdarg_T *cap)
}
(void)normal_search(cap, cap->cmdchar, cap->searchbuf,
- (cap->arg ? 0 : SEARCH_MARK));
+ (cap->arg || !equalpos(save_cursor, curwin->w_cursor))
+ ? 0 : SEARCH_MARK);
}
/*
@@ -5614,6 +5713,8 @@ static void nv_brackets(cmdarg_T *cap)
cap->nchar == 's', false, NULL) == 0) {
clearopbeep(cap->oap);
break;
+ } else {
+ curwin->w_set_curswant = true;
}
if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped)
foldOpenCursor();
@@ -5783,10 +5884,13 @@ static void nv_replace(cmdarg_T *cap)
if (got_int)
reset_VIsual();
if (had_ctrl_v) {
- if (cap->nchar == '\r')
- cap->nchar = -1;
- else if (cap->nchar == '\n')
- cap->nchar = -2;
+ // Use a special (negative) number to make a difference between a
+ // literal CR or NL and a line break.
+ if (cap->nchar == CAR) {
+ cap->nchar = REPLACE_CR_NCHAR;
+ } else if (cap->nchar == NL) {
+ cap->nchar = REPLACE_NL_NCHAR;
+ }
}
nv_operator(cap);
return;
@@ -5919,6 +6023,8 @@ static void nv_replace(cmdarg_T *cap)
curwin->w_set_curswant = true;
set_last_insert(cap->nchar);
}
+
+ foldUpdateAfterInsert();
}
/*
@@ -6021,10 +6127,11 @@ static void n_swapchar(cmdarg_T *cap)
pos_T startpos;
int did_change = 0;
- if (checkclearopq(cap->oap))
+ if (checkclearopq(cap->oap)) {
return;
+ }
- if (lineempty(curwin->w_cursor.lnum) && vim_strchr(p_ww, '~') == NULL) {
+ if (LINEEMPTY(curwin->w_cursor.lnum) && vim_strchr(p_ww, '~') == NULL) {
clearopbeep(cap->oap);
return;
}
@@ -6058,7 +6165,7 @@ static void n_swapchar(cmdarg_T *cap)
curwin->w_set_curswant = true;
if (did_change) {
changed_lines(startpos.lnum, startpos.col, curwin->w_cursor.lnum + 1,
- 0L);
+ 0L, true);
curbuf->b_op_start = startpos;
curbuf->b_op_end = curwin->w_cursor;
if (curbuf->b_op_end.col > 0)
@@ -6149,17 +6256,15 @@ static void nv_abbrev(cmdarg_T *cap)
*/
static void nv_optrans(cmdarg_T *cap)
{
- static char_u *(ar[8]) = {(char_u *)"dl", (char_u *)"dh",
- (char_u *)"d$", (char_u *)"c$",
- (char_u *)"cl", (char_u *)"cc",
- (char_u *)"yy", (char_u *)":s\r"};
- static char_u *str = (char_u *)"xXDCsSY&";
+ static const char *(ar[]) = { "dl", "dh", "d$", "c$", "cl", "cc", "yy",
+ ":s\r" };
+ static const char *str = "xXDCsSY&";
if (!checkclearopq(cap->oap)) {
if (cap->count0) {
stuffnumReadbuff(cap->count0);
}
- stuffReadbuff(ar[(int)(vim_strchr(str, cap->cmdchar) - str)]);
+ stuffReadbuff(ar[strchr(str, (char)cap->cmdchar) - str]);
}
cap->opcount = 0;
}
@@ -6173,7 +6278,7 @@ static void nv_gomark(cmdarg_T *cap)
pos_T *pos;
int c;
pos_T old_cursor = curwin->w_cursor;
- int old_KeyTyped = KeyTyped; /* getting file may reset it */
+ const bool old_KeyTyped = KeyTyped; // getting file may reset it
if (cap->cmdchar == 'g')
c = cap->extra_char;
@@ -6189,15 +6294,18 @@ static void nv_gomark(cmdarg_T *cap)
} else
nv_cursormark(cap, cap->arg, pos);
- /* May need to clear the coladd that a mark includes. */
- if (!virtual_active())
+ // May need to clear the coladd that a mark includes.
+ if (!virtual_active()) {
curwin->w_cursor.coladd = 0;
+ }
+ check_cursor_col();
if (cap->oap->op_type == OP_NOP
&& pos != NULL
&& (pos == (pos_T *)-1 || !equalpos(old_cursor, *pos))
&& (fdo_flags & FDO_MARK)
- && old_KeyTyped)
+ && old_KeyTyped) {
foldOpenCursor();
+ }
}
/*
@@ -6207,7 +6315,7 @@ static void nv_pcmark(cmdarg_T *cap)
{
pos_T *pos;
linenr_T lnum = curwin->w_cursor.lnum;
- int old_KeyTyped = KeyTyped; /* getting file may reset it */
+ const bool old_KeyTyped = KeyTyped; // getting file may reset it
if (!checkclearopq(cap->oap)) {
if (cap->cmdchar == 'g')
@@ -6267,8 +6375,8 @@ static void nv_visual(cmdarg_T *cap)
/* 'v', 'V' and CTRL-V can be used while an operator is pending to make it
* characterwise, linewise, or blockwise. */
if (cap->oap->op_type != OP_NOP) {
- cap->oap->motion_force = cap->cmdchar;
- finish_op = false; /* operator doesn't finish now but later */
+ motion_force = cap->oap->motion_force = cap->cmdchar;
+ finish_op = false; // operator doesn't finish now but later
return;
}
@@ -6281,9 +6389,8 @@ static void nv_visual(cmdarg_T *cap)
VIsual_mode = cap->cmdchar;
showmode();
}
- redraw_curbuf_later(INVERTED); /* update the inversion */
- } else { /* start Visual mode */
- check_visual_highlight();
+ redraw_curbuf_later(INVERTED); // update the inversion
+ } else { // start Visual mode
if (cap->count0 > 0 && resel_VIsual_mode != NUL) {
/* use previously selected part */
VIsual = curwin->w_cursor;
@@ -6372,9 +6479,6 @@ void may_start_select(int c)
*/
static void n_start_visual_mode(int c)
{
- /* Check for redraw before changing the state. */
- conceal_check_cursur_line();
-
VIsual_mode = c;
VIsual_active = true;
VIsual_reselect = true;
@@ -6390,8 +6494,8 @@ static void n_start_visual_mode(int c)
foldAdjustVisual();
setmouse();
- /* Check for redraw after changing the state. */
- conceal_check_cursur_line();
+ // Check for redraw after changing the state.
+ conceal_check_cursor_line();
if (p_smd && msg_silent == 0)
redraw_cmdline = true; /* show visual mode later */
@@ -6536,7 +6640,7 @@ static void nv_g_cmd(cmdarg_T *cap)
*/
case K_BS:
cap->nchar = Ctrl_H;
- /* FALLTHROUGH */
+ FALLTHROUGH;
case 'h':
case 'H':
case Ctrl_H:
@@ -6602,7 +6706,7 @@ static void nv_g_cmd(cmdarg_T *cap)
*/
case '^':
flag = true;
- /* FALLTHROUGH */
+ FALLTHROUGH;
case '0':
case 'm':
@@ -6611,9 +6715,9 @@ static void nv_g_cmd(cmdarg_T *cap)
oap->motion_type = kMTCharWise;
oap->inclusive = false;
if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
- int width1 = curwin->w_width - curwin_col_off();
+ int width1 = curwin->w_grid.Columns - curwin_col_off();
int width2 = width1 + curwin_col_off2();
validate_virtcol();
@@ -6625,10 +6729,11 @@ static void nv_g_cmd(cmdarg_T *cap)
/* Go to the middle of the screen line. When 'number' or
* 'relativenumber' is on and lines are wrapping the middle can be more
* to the left. */
- if (cap->nchar == 'm')
- i += (curwin->w_width - curwin_col_off()
+ if (cap->nchar == 'm') {
+ i += (curwin->w_grid.Columns - curwin_col_off()
+ ((curwin->w_p_wrap && i > 0)
? curwin_col_off2() : 0)) / 2;
+ }
coladvance((colnr_T)i);
if (flag) {
do
@@ -6672,11 +6777,11 @@ static void nv_g_cmd(cmdarg_T *cap)
oap->motion_type = kMTCharWise;
oap->inclusive = true;
if (curwin->w_p_wrap
- && curwin->w_width != 0
+ && curwin->w_grid.Columns != 0
) {
curwin->w_curswant = MAXCOL; /* so we stay at the end */
if (cap->count1 == 1) {
- int width1 = curwin->w_width - col_off;
+ int width1 = curwin->w_grid.Columns - col_off;
int width2 = width1 + curwin_col_off2();
validate_virtcol();
@@ -6702,7 +6807,7 @@ static void nv_g_cmd(cmdarg_T *cap)
} else if (nv_screengo(oap, FORWARD, cap->count1 - 1) == false)
clearopbeep(oap);
} else {
- i = curwin->w_leftcol + curwin->w_width - col_off - 1;
+ i = curwin->w_leftcol + curwin->w_grid.Columns - col_off - 1;
coladvance((colnr_T)i);
/* Make sure we stick in this column. */
@@ -6780,7 +6885,7 @@ static void nv_g_cmd(cmdarg_T *cap)
/* "g'm" and "g`m": jump to mark without setting pcmark */
case '\'':
cap->arg = true;
- /*FALLTHROUGH*/
+ FALLTHROUGH;
case '`':
nv_gomark(cap);
break;
@@ -6811,7 +6916,7 @@ static void nv_g_cmd(cmdarg_T *cap)
else
show_utf8();
break;
-
+ // "g<": show scrollback text
case '<':
show_sb_text();
break;
@@ -6838,7 +6943,7 @@ static void nv_g_cmd(cmdarg_T *cap)
case 'q':
case 'w':
oap->cursor_start = curwin->w_cursor;
- /*FALLTHROUGH*/
+ FALLTHROUGH;
case '~':
case 'u':
case 'U':
@@ -6943,8 +7048,6 @@ static void nv_g_cmd(cmdarg_T *cap)
*/
static void n_opencmd(cmdarg_T *cap)
{
- linenr_T oldline = curwin->w_cursor.lnum;
-
if (!checkclearopq(cap->oap)) {
if (cap->cmdchar == 'O')
/* Open above the first line of a folded sequence of lines */
@@ -6963,10 +7066,7 @@ static void n_opencmd(cmdarg_T *cap)
has_format_option(FO_OPEN_COMS)
? OPENLINE_DO_COM : 0,
0)) {
- if (curwin->w_p_cole > 0 && oldline != curwin->w_cursor.lnum) {
- update_single_line(curwin, oldline);
- }
- if (curwin->w_p_cul) {
+ if (win_cursorline_standout(curwin)) {
// force redraw of cursorline
curwin->w_valid &= ~VALID_CROW;
}
@@ -7067,7 +7167,7 @@ static void set_op_var(int optype)
assert(opchar0 >= 0 && opchar0 <= UCHAR_MAX);
opchars[0] = (char) opchar0;
- int opchar1 = get_extra_op_char(optype);
+ int opchar1 = get_extra_op_char(optype);
assert(opchar1 >= 0 && opchar1 <= UCHAR_MAX);
opchars[1] = (char) opchar1;
@@ -7185,8 +7285,10 @@ static void nv_wordcmd(cmdarg_T *cap)
// Another strangeness: When standing on the end of a word "ce" will
// change until the end of the next word, but "cw" will change only one
// character! This is done by setting "flag".
- cap->oap->inclusive = true;
- word_end = true;
+ if (vim_strchr(p_cpo, CPO_CHANGEW) != NULL) {
+ cap->oap->inclusive = true;
+ word_end = true;
+ }
flag = true;
}
}
@@ -7280,11 +7382,11 @@ static bool unadjust_for_sel(void)
pp = &curwin->w_cursor;
else
pp = &VIsual;
- if (pp->coladd > 0)
- --pp->coladd;
- else if (pp->col > 0) {
- --pp->col;
- mb_adjustpos(curbuf, pp);
+ if (pp->coladd > 0) {
+ pp->coladd--;
+ } else if (pp->col > 0) {
+ pp->col--;
+ mark_mb_adjustpos(curbuf, pp);
} else if (pp->lnum > 1) {
--pp->lnum;
pp->col = (colnr_T)STRLEN(ml_get(pp->lnum));
@@ -7378,8 +7480,10 @@ static void nv_esc(cmdarg_T *cap)
if (restart_edit == 0
&& cmdwin_type == 0
&& !VIsual_active
- && no_reason)
- MSG(_("Type :quit<Enter> to exit Nvim"));
+ && no_reason) {
+ MSG(_("Type :qa! and press <Enter> to abandon all changes"
+ " and exit Nvim"));
+ }
/* Don't reset "restart_edit" when 'insertmode' is set, it won't be
* set again below when halfway through a mapping. */
@@ -7410,27 +7514,23 @@ static void nv_esc(cmdarg_T *cap)
restart_edit = 'a';
}
-/*
- * Handle "A", "a", "I", "i" and <Insert> commands.
- */
+/// Handle "A", "a", "I", "i" and <Insert> commands.
static void nv_edit(cmdarg_T *cap)
{
- /* <Insert> is equal to "i" */
- if (cap->cmdchar == K_INS || cap->cmdchar == K_KINS)
+ // <Insert> is equal to "i"
+ if (cap->cmdchar == K_INS || cap->cmdchar == K_KINS) {
cap->cmdchar = 'i';
+ }
- /* in Visual mode "A" and "I" are an operator */
- if (VIsual_active && (cap->cmdchar == 'A' || cap->cmdchar == 'I'))
+ // in Visual mode "A" and "I" are an operator
+ if (VIsual_active && (cap->cmdchar == 'A' || cap->cmdchar == 'I')) {
v_visop(cap);
-
- /* in Visual mode and after an operator "a" and "i" are for text objects */
- else if ((cap->cmdchar == 'a' || cap->cmdchar == 'i')
- && (cap->oap->op_type != OP_NOP
- || VIsual_active
- )) {
+ // in Visual mode and after an operator "a" and "i" are for text objects
+ } else if ((cap->cmdchar == 'a' || cap->cmdchar == 'i')
+ && (cap->oap->op_type != OP_NOP || VIsual_active)) {
nv_object(cap);
- } else if (!curbuf->b_p_ma && !p_im) {
- /* Only give this error when 'insertmode' is off. */
+ } else if (!curbuf->b_p_ma && !p_im && !curbuf->terminal) {
+ // Only give this error when 'insertmode' is off.
EMSG(_(e_modifiable));
clearop(cap->oap);
} else if (!checkclearopq(cap->oap)) {
@@ -7603,11 +7703,13 @@ static void nv_record(cmdarg_T *cap)
if (cap->nchar == ':' || cap->nchar == '/' || cap->nchar == '?') {
stuffcharReadbuff(cap->nchar);
stuffcharReadbuff(K_CMDWIN);
- } else
- /* (stop) recording into a named register, unless executing a
- * register */
- if (!Exec_reg && do_record(cap->nchar) == false)
- clearopbeep(cap->oap);
+ } else {
+ // (stop) recording into a named register, unless executing a
+ // register.
+ if (!Exec_reg && do_record(cap->nchar) == FAIL) {
+ clearopbeep(cap->oap);
+ }
+ }
}
}
@@ -7716,16 +7818,22 @@ static void nv_put(cmdarg_T *cap)
savereg = copy_register(regname);
}
- /* Now delete the selected text. */
- cap->cmdchar = 'd';
- cap->nchar = NUL;
- cap->oap->regname = NUL;
- nv_operator(cap);
- do_pending_operator(cap, 0, false);
- empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
+ // To place the cursor correctly after a blockwise put, and to leave the
+ // text in the correct position when putting over a selection with
+ // 'virtualedit' and past the end of the line, we use the 'c' operator in
+ // do_put(), which requires the visual selection to still be active.
+ if (!VIsual_active || VIsual_mode == 'V' || regname != '.') {
+ // Now delete the selected text.
+ cap->cmdchar = 'd';
+ cap->nchar = NUL;
+ cap->oap->regname = NUL;
+ nv_operator(cap);
+ do_pending_operator(cap, 0, false);
+ empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
- /* delete PUT_LINE_BACKWARD; */
- cap->oap->regname = regname;
+ // delete PUT_LINE_BACKWARD;
+ cap->oap->regname = regname;
+ }
/* When deleted a linewise Visual area, put the register as
* lines to avoid it joined with the next line. When deletion was
@@ -7809,7 +7917,7 @@ static void get_op_vcol(
colnr_T end;
if (VIsual_mode != Ctrl_V
- || (!initial && oap->end.col < curwin->w_width)) {
+ || (!initial && oap->end.col < curwin->w_grid.Columns)) {
return;
}
@@ -7817,7 +7925,7 @@ static void get_op_vcol(
// prevent from moving onto a trail byte
if (has_mbyte) {
- mb_adjustpos(curwin->w_buffer, &oap->end);
+ mark_mb_adjustpos(curwin->w_buffer, &oap->end);
}
getvvcol(curwin, &(oap->start), &oap->start_vcol, NULL, &oap->end_vcol);
@@ -7872,28 +7980,17 @@ static void nv_event(cmdarg_T *cap)
{
// Garbage collection should have been executed before blocking for events in
// the `os_inchar` in `state_enter`, but we also disable it here in case the
- // `os_inchar` branch was not executed(!queue_empty(loop.events), which could
- // have `may_garbage_collect` set to true in `normal_check`).
+ // `os_inchar` branch was not executed (!multiqueue_empty(loop.events), which
+ // could have `may_garbage_collect` set to true in `normal_check`).
//
// That is because here we may run code that calls `os_inchar`
// later(`f_confirm` or `get_keystroke` for example), but in these cases it is
// not safe to perform garbage collection because there could be unreferenced
// lists or dicts being used.
may_garbage_collect = false;
- queue_process_events(main_loop.events);
+ multiqueue_process_events(main_loop.events);
cap->retval |= CA_COMMAND_BUSY; // don't call edit() now
-}
-
-/// Trigger FocusGained event.
-static void nv_focusgained(cmdarg_T *cap)
-{
- apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
-}
-
-/// Trigger FocusLost event.
-static void nv_focuslost(cmdarg_T *cap)
-{
- apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
+ finish_op = false;
}
/*
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index a498fc481a..e9cb480647 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.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
+
/*
* ops.c: implementation of various operators: op_shift, op_delete, op_tilde,
* op_change, op_yank, do_put, do_join
@@ -14,8 +17,10 @@
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/assert.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_getln.h"
@@ -30,17 +35,18 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/path.h"
#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/terminal.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
+#include "nvim/macros.h"
#include "nvim/window.h"
#include "nvim/os/input.h"
#include "nvim/os/time.h"
@@ -49,12 +55,11 @@ static yankreg_T y_regs[NUM_REGISTERS];
static yankreg_T *y_previous = NULL; /* ptr to last written yankreg */
-static bool clipboard_didwarn_unnamed = false;
-
-// for behavior between start_global_changes() and end_global_changes())
+// for behavior between start_batch_changes() and end_batch_changes())
+static int batch_change_count = 0; // inside a script
static bool clipboard_delay_update = false; // delay clipboard update
-static int global_change_count = 0; // if set, inside global changes
-static bool clipboard_needs_update = false; // the clipboard was updated
+static bool clipboard_needs_update = false; // clipboard was updated
+static bool clipboard_didwarn = false;
/*
* structure used by block_prep, op_delete and op_yank for blockwise operators
@@ -209,9 +214,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
++curwin->w_cursor.lnum;
}
- changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L);
- /* The cursor line is not in a closed fold */
- foldOpenCursor();
+ changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
if (oap->motion_type == kMTBlockWise) {
curwin->w_cursor.lnum = oap->start.lnum;
@@ -222,6 +225,9 @@ void op_shift(oparg_T *oap, int curs_top, int amount)
} else
--curwin->w_cursor.lnum; /* put cursor on last line, for ":>" */
+ // The cursor line is not in a closed fold
+ foldOpenCursor();
+
if (oap->line_count > p_report) {
if (oap->op_type == OP_RSHIFT)
s = (char_u *)">";
@@ -304,30 +310,32 @@ void shift_line(
*/
static void shift_block(oparg_T *oap, int amount)
{
- int left = (oap->op_type == OP_LSHIFT);
- int oldstate = State;
- int total;
- char_u *newp, *oldp;
- int oldcol = curwin->w_cursor.col;
- int p_sw = get_sw_value(curbuf);
- int p_ts = (int)curbuf->b_p_ts;
+ const bool left = (oap->op_type == OP_LSHIFT);
+ const int oldstate = State;
+ char_u *newp;
+ const int oldcol = curwin->w_cursor.col;
+ const int p_sw = get_sw_value(curbuf);
+ const int p_ts = (int)curbuf->b_p_ts;
struct block_def bd;
int incr;
- colnr_T ws_vcol;
int i = 0, j = 0;
- int len;
- int old_p_ri = p_ri;
+ const int old_p_ri = p_ri;
p_ri = 0; /* don't want revins in indent */
- State = INSERT; /* don't want REPLACE for State */
- block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
- if (bd.is_short)
+ State = INSERT; // don't want REPLACE for State
+ block_prep(oap, &bd, curwin->w_cursor.lnum, true);
+ if (bd.is_short) {
return;
+ }
+
+ // total is number of screen columns to be inserted/removed
+ int total = (int)((unsigned)amount * (unsigned)p_sw);
+ if ((total / p_sw) != amount) {
+ return; // multiplication overflow
+ }
- /* total is number of screen columns to be inserted/removed */
- total = amount * p_sw;
- oldp = get_cursor_line_ptr();
+ char_u *const oldp = get_cursor_line_ptr();
if (!left) {
/*
@@ -336,13 +344,19 @@ static void shift_block(oparg_T *oap, int amount)
* 3. Divvy into TABs & spp
* 4. Construct new string
*/
- total += bd.pre_whitesp; /* all virtual WS up to & incl a split TAB */
- ws_vcol = bd.start_vcol - bd.pre_whitesp;
+ total += bd.pre_whitesp; // all virtual WS up to & incl a split TAB
+ colnr_T ws_vcol = bd.start_vcol - bd.pre_whitesp;
if (bd.startspaces) {
- if (has_mbyte)
- bd.textstart += (*mb_ptr2len)(bd.textstart);
- else
- ++bd.textstart;
+ if (has_mbyte) {
+ if ((*mb_ptr2len)(bd.textstart) == 1) {
+ bd.textstart++;
+ } else {
+ ws_vcol = 0;
+ bd.startspaces = 0;
+ }
+ } else {
+ bd.textstart++;
+ }
}
for (; ascii_iswhite(*bd.textstart); ) {
// TODO: is passing bd.textstart for start of the line OK?
@@ -360,8 +374,8 @@ static void shift_block(oparg_T *oap, int amount)
j = total;
/* if we're splitting a TAB, allow for it */
bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
- len = (int)STRLEN(bd.textstart) + 1;
- newp = (char_u *) xmalloc((size_t)(bd.textcol + i + j + len));
+ const int len = (int)STRLEN(bd.textstart) + 1;
+ newp = (char_u *)xmalloc((size_t)(bd.textcol + i + j + len));
memset(newp, NUL, (size_t)(bd.textcol + i + j + len));
memmove(newp, oldp, (size_t)bd.textcol);
memset(newp + bd.textcol, TAB, (size_t)i);
@@ -378,10 +392,7 @@ static void shift_block(oparg_T *oap, int amount)
size_t fill; // nr of spaces that replace a TAB
size_t new_line_len; // the length of the line after the
// block shift
- colnr_T block_space_width;
- colnr_T shift_amount;
char_u *non_white = bd.textstart;
- colnr_T non_white_col;
/*
* Firstly, let's find the first non-whitespace character that is
@@ -394,22 +405,24 @@ static void shift_block(oparg_T *oap, int amount)
/* If "bd.startspaces" is set, "bd.textstart" points to the character,
* the part of which is displayed at the block's beginning. Let's start
* searching from the next character. */
- if (bd.startspaces)
- mb_ptr_adv(non_white);
+ if (bd.startspaces) {
+ MB_PTR_ADV(non_white);
+ }
- /* The character's column is in "bd.start_vcol". */
- non_white_col = bd.start_vcol;
+ // The character's column is in "bd.start_vcol".
+ colnr_T non_white_col = bd.start_vcol;
while (ascii_iswhite(*non_white)) {
incr = lbr_chartabsize_adv(bd.textstart, &non_white, non_white_col);
non_white_col += incr;
}
- block_space_width = non_white_col - oap->start_vcol;
- /* We will shift by "total" or "block_space_width", whichever is less.
- */
- shift_amount = (block_space_width < total ? block_space_width : total);
+ const colnr_T block_space_width = non_white_col - oap->start_vcol;
+ // We will shift by "total" or "block_space_width", whichever is less.
+ const colnr_T shift_amount = block_space_width < total
+ ? block_space_width
+ : total;
// The column to which we will shift the text.
destination_col = non_white_col - shift_amount;
@@ -431,7 +444,7 @@ static void shift_block(oparg_T *oap, int amount)
if (verbatim_copy_width + incr > destination_col)
break;
verbatim_copy_width += incr;
- mb_ptr_adv(verbatim_copy_end);
+ MB_PTR_ADV(verbatim_copy_end);
}
/* If "destination_col" is different from the width of the initial
@@ -441,7 +454,7 @@ static void shift_block(oparg_T *oap, int amount)
fill = (size_t)(destination_col - verbatim_copy_width);
assert(verbatim_copy_end - oldp >= 0);
- size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp);
+ const size_t verbatim_diff = (size_t)(verbatim_copy_end - oldp);
// The replacement line will consist of:
// - the beginning of the original line up to "verbatim_copy_end",
// - "fill" number of spaces,
@@ -453,8 +466,8 @@ static void shift_block(oparg_T *oap, int amount)
memset(newp + verbatim_diff, ' ', fill);
STRMOVE(newp + verbatim_diff + fill, non_white);
}
- /* replace the line */
- ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+ // replace the line
+ ml_replace(curwin->w_cursor.lnum, newp, false);
changed_bytes(curwin->w_cursor.lnum, (colnr_T)bd.textcol);
State = oldstate;
curwin->w_cursor.col = oldcol;
@@ -507,12 +520,12 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
}
}
- if (has_mbyte && spaces > 0) {
+ if (spaces > 0) {
int off;
// Avoid starting halfway through a multi-byte character.
if (b_insert) {
- off = (*mb_head_off)(oldp, oldp + offset + spaces);
+ off = utf_head_off(oldp, oldp + offset + spaces);
} else {
off = (*mb_off_next)(oldp, oldp + offset);
offset += off;
@@ -548,7 +561,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
offset += count;
STRMOVE(newp + offset, oldp);
- ml_replace(lnum, newp, FALSE);
+ ml_replace(lnum, newp, false);
if (lnum == oap->end.lnum) {
/* Set "']" mark to the end of the block instead of the end of
@@ -558,7 +571,7 @@ static void block_insert(oparg_T *oap, char_u *s, int b_insert, struct block_def
}
} /* for all lnum */
- changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L);
+ changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true);
State = oldstate;
}
@@ -620,12 +633,13 @@ void op_reindent(oparg_T *oap, Indenter how)
/* Mark changed lines so that they will be redrawn. When Visual
* highlighting was present, need to continue until the last line. When
* there is no change still need to remove the Visual highlighting. */
- if (last_changed != 0)
+ if (last_changed != 0) {
changed_lines(first_changed, 0,
- oap->is_VIsual ? start_lnum + oap->line_count :
- last_changed + 1, 0L);
- else if (oap->is_VIsual)
+ oap->is_VIsual ? start_lnum + oap->line_count :
+ last_changed + 1, 0L, true);
+ } else if (oap->is_VIsual) {
redraw_curbuf_later(INVERTED);
+ }
if (oap->line_count > p_report) {
i = oap->line_count - (i + 1);
@@ -792,7 +806,6 @@ static bool is_append_register(int regname)
/// Returns a copy of contents in register `name`
/// for use in do_put. Should be freed by caller.
yankreg_T *copy_register(int name)
- FUNC_ATTR_MALLOC
FUNC_ATTR_NONNULL_RET
{
yankreg_T *reg = get_yank_register(name, YREG_PASTE);
@@ -881,7 +894,7 @@ static void set_yreg_additional_data(yankreg_T *reg, dict_T *additional_data)
if (reg->additional_data == additional_data) {
return;
}
- dict_unref(reg->additional_data);
+ tv_dict_unref(reg->additional_data);
reg->additional_data = additional_data;
}
@@ -926,13 +939,11 @@ static int stuff_yank(int regname, char_u *p)
static int execreg_lastc = NUL;
-/*
- * execute a yank register: copy it into the stuff buffer
- *
- * return FAIL for failure, OK otherwise
- */
-int
-do_execreg (
+/// Execute a yank register: copy it into the stuff buffer
+///
+/// Return FAIL for failure, OK otherwise
+int
+do_execreg(
int regname,
int colon, /* insert ':' before each line */
int addcr, /* always add '\n' to end of line */
@@ -1099,8 +1110,7 @@ int insert_reg(
)
{
int retval = OK;
- char_u *arg;
- int allocated;
+ bool allocated;
/*
* It is possible to get into an endless loop by having CTRL-R a in
@@ -1115,21 +1125,24 @@ int insert_reg(
if (regname != NUL && !valid_yank_reg(regname, false))
return FAIL;
- if (regname == '.') /* insert last inserted text */
- retval = stuff_inserted(NUL, 1L, TRUE);
- else if (get_spec_reg(regname, &arg, &allocated, TRUE)) {
- if (arg == NULL)
+ char_u *arg;
+ if (regname == '.') { // Insert last inserted text.
+ retval = stuff_inserted(NUL, 1L, true);
+ } else if (get_spec_reg(regname, &arg, &allocated, true)) {
+ if (arg == NULL) {
return FAIL;
- stuffescaped(arg, literally);
- if (allocated)
+ }
+ stuffescaped((const char *)arg, literally);
+ if (allocated) {
xfree(arg);
- } else { /* name or number register */
+ }
+ } else { // Name or number register.
yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
if (reg->y_array == NULL) {
retval = FAIL;
} else {
for (size_t i = 0; i < reg->y_size; i++) {
- stuffescaped(reg->y_array[i], literally);
+ stuffescaped((const char *)reg->y_array[i], literally);
// Insert a newline between lines and after last line if
// y_type is kMTLineWise.
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
@@ -1146,115 +1159,125 @@ int insert_reg(
* Stuff a string into the typeahead buffer, such that edit() will insert it
* literally ("literally" TRUE) or interpret is as typed characters.
*/
-static void stuffescaped(char_u *arg, int literally)
+static void stuffescaped(const char *arg, int literally)
{
- int c;
- char_u *start;
-
while (*arg != NUL) {
- /* Stuff a sequence of normal ASCII characters, that's fast. Also
- * stuff K_SPECIAL to get the effect of a special key when "literally"
- * is TRUE. */
- start = arg;
- while ((*arg >= ' ' && *arg < DEL) || (*arg == K_SPECIAL && !literally))
- ++arg;
- if (arg > start)
+ // Stuff a sequence of normal ASCII characters, that's fast. Also
+ // stuff K_SPECIAL to get the effect of a special key when "literally"
+ // is TRUE.
+ const char *const start = arg;
+ while ((*arg >= ' ' && *arg < DEL) || ((uint8_t)(*arg) == K_SPECIAL
+ && !literally)) {
+ arg++;
+ }
+ if (arg > start) {
stuffReadbuffLen(start, (long)(arg - start));
+ }
/* stuff a single special character */
if (*arg != NUL) {
- if (has_mbyte)
- c = mb_cptr2char_adv(&arg);
- else
- c = *arg++;
- if (literally && ((c < ' ' && c != TAB) || c == DEL))
+ const int c = (has_mbyte
+ ? mb_cptr2char_adv((const char_u **)&arg)
+ : (uint8_t)(*arg++));
+ if (literally && ((c < ' ' && c != TAB) || c == DEL)) {
stuffcharReadbuff(Ctrl_V);
+ }
stuffcharReadbuff(c);
}
}
}
-/*
- * If "regname" is a special register, return TRUE and store a pointer to its
- * value in "argp".
- */
-int get_spec_reg(
+// If "regname" is a special register, return true and store a pointer to its
+// value in "argp".
+bool get_spec_reg(
int regname,
char_u **argp,
- int *allocated, /* return: TRUE when value was allocated */
- int errmsg /* give error message when failing */
+ bool *allocated, // return: true when value was allocated
+ bool errmsg // give error message when failing
)
{
size_t cnt;
*argp = NULL;
- *allocated = FALSE;
+ *allocated = false;
switch (regname) {
case '%': /* file name */
if (errmsg)
check_fname(); /* will give emsg if not set */
*argp = curbuf->b_fname;
- return TRUE;
+ return true;
- case '#': /* alternate file name */
- *argp = getaltfname(errmsg); /* may give emsg if not set */
- return TRUE;
+ case '#': // alternate file name
+ *argp = getaltfname(errmsg); // may give emsg if not set
+ return true;
case '=': /* result of expression */
*argp = get_expr_line();
- *allocated = TRUE;
- return TRUE;
+ *allocated = true;
+ return true;
case ':': /* last command line */
if (last_cmdline == NULL && errmsg)
EMSG(_(e_nolastcmd));
*argp = last_cmdline;
- return TRUE;
+ return true;
case '/': /* last search-pattern */
if (last_search_pat() == NULL && errmsg)
EMSG(_(e_noprevre));
*argp = last_search_pat();
- return TRUE;
+ return true;
case '.': /* last inserted text */
*argp = get_last_insert_save();
- *allocated = TRUE;
- if (*argp == NULL && errmsg)
+ *allocated = true;
+ if (*argp == NULL && errmsg) {
EMSG(_(e_noinstext));
- return TRUE;
+ }
+ return true;
- case Ctrl_F: /* Filename under cursor */
- case Ctrl_P: /* Path under cursor, expand via "path" */
- if (!errmsg)
- return FALSE;
- *argp = file_name_at_cursor(FNAME_MESS | FNAME_HYP
- | (regname == Ctrl_P ? FNAME_EXP : 0), 1L, NULL);
- *allocated = TRUE;
- return TRUE;
+ case Ctrl_F: // Filename under cursor
+ case Ctrl_P: // Path under cursor, expand via "path"
+ if (!errmsg) {
+ return false;
+ }
+ *argp = file_name_at_cursor(
+ FNAME_MESS | FNAME_HYP | (regname == Ctrl_P ? FNAME_EXP : 0),
+ 1L, NULL);
+ *allocated = true;
+ return true;
- case Ctrl_W: /* word under cursor */
- case Ctrl_A: /* WORD (mnemonic All) under cursor */
- if (!errmsg)
- return FALSE;
+ case Ctrl_W: // word under cursor
+ case Ctrl_A: // WORD (mnemonic All) under cursor
+ if (!errmsg) {
+ return false;
+ }
cnt = find_ident_under_cursor(argp, (regname == Ctrl_W
? (FIND_IDENT|FIND_STRING)
: FIND_STRING));
*argp = cnt ? vim_strnsave(*argp, cnt) : NULL;
- *allocated = TRUE;
- return TRUE;
+ *allocated = true;
+ return true;
+
+ case Ctrl_L: // Line under cursor
+ if (!errmsg) {
+ return false;
+ }
+
+ *argp = ml_get_buf(curwin->w_buffer, curwin->w_cursor.lnum, false);
+ return true;
case '_': /* black hole: always empty */
*argp = (char_u *)"";
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/// Paste a yank register into the command line.
/// Only for non-special registers.
-/// Used by CTRL-R command in command-line mode
+/// Used by CTRL-R in command-line mode.
/// insert_reg() can't be used here, because special characters from the
/// register contents will be interpreted as commands.
///
@@ -1272,9 +1295,8 @@ bool cmdline_paste_reg(int regname, bool literally, bool remcr)
for (size_t i = 0; i < reg->y_size; i++) {
cmdline_paste_str(reg->y_array[i], literally);
- // Insert ^M between lines and after last line if type is kMTLineWise.
- // Don't do this when "remcr" is true.
- if ((reg->y_type == kMTLineWise || i < reg->y_size - 1) && !remcr) {
+ // Insert ^M between lines, unless `remcr` is true.
+ if (i < reg->y_size - 1 && !remcr) {
cmdline_paste_str((char_u *)"\r", literally);
}
@@ -1397,8 +1419,11 @@ int op_delete(oparg_T *oap)
}
if (oap->regname == 0) {
+ if (reg == NULL) {
+ abort();
+ }
set_clipboard(0, reg);
- yank_do_autocmd(oap, reg);
+ do_autocmd_textyankpost(oap, reg);
}
}
@@ -1412,10 +1437,11 @@ int op_delete(oparg_T *oap)
return FAIL;
}
- for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; ++lnum) {
- block_prep(oap, &bd, lnum, TRUE);
- if (bd.textlen == 0) /* nothing to delete */
+ for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; lnum++) {
+ block_prep(oap, &bd, lnum, true);
+ if (bd.textlen == 0) { // nothing to delete
continue;
+ }
/* Adjust cursor position for tab replaced by spaces and 'lbr'. */
if (lnum == curwin->w_cursor.lnum) {
@@ -1442,7 +1468,7 @@ int op_delete(oparg_T *oap)
check_cursor_col();
changed_lines(curwin->w_cursor.lnum, curwin->w_cursor.col,
- oap->end.lnum + 1, 0L);
+ oap->end.lnum + 1, 0L, true);
oap->line_count = 0; // no lines deleted
} else if (oap->motion_type == kMTLineWise) {
if (oap->op_type == OP_CHANGE) {
@@ -1458,9 +1484,9 @@ int op_delete(oparg_T *oap)
}
if (u_save_cursor() == FAIL)
return FAIL;
- if (curbuf->b_p_ai) { /* don't delete indent */
- beginline(BL_WHITE); /* cursor on first non-white */
- did_ai = TRUE; /* delete the indent when ESC hit */
+ if (curbuf->b_p_ai) { // don't delete indent
+ beginline(BL_WHITE); // cursor on first non-white
+ did_ai = true; // delete the indent when ESC hit
ai_col = curwin->w_cursor.col;
} else
beginline(0); /* cursor in column 0 */
@@ -1616,13 +1642,18 @@ int op_replace(oparg_T *oap, int c)
colnr_T oldlen;
struct block_def bd;
char_u *after_p = NULL;
- int had_ctrl_v_cr = (c == -1 || c == -2);
+ int had_ctrl_v_cr = false;
if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty)
return OK; /* nothing to do */
- if (had_ctrl_v_cr)
- c = (c == -1 ? '\r' : '\n');
+ if (c == REPLACE_CR_NCHAR) {
+ had_ctrl_v_cr = true;
+ c = CAR;
+ } else if (c == REPLACE_NL_NCHAR) {
+ had_ctrl_v_cr = true;
+ c = NL;
+ }
if (has_mbyte)
mb_adjust_opend(oap);
@@ -1636,11 +1667,12 @@ int op_replace(oparg_T *oap, int c)
*/
if (oap->motion_type == kMTBlockWise) {
bd.is_MAX = (curwin->w_curswant == MAXCOL);
- for (; curwin->w_cursor.lnum <= oap->end.lnum; ++curwin->w_cursor.lnum) {
- curwin->w_cursor.col = 0; /* make sure cursor position is valid */
- block_prep(oap, &bd, curwin->w_cursor.lnum, TRUE);
- if (bd.textlen == 0 && (!virtual_op || bd.is_MAX))
- continue; /* nothing to replace */
+ for (; curwin->w_cursor.lnum <= oap->end.lnum; curwin->w_cursor.lnum++) {
+ curwin->w_cursor.col = 0; // make sure cursor position is valid
+ block_prep(oap, &bd, curwin->w_cursor.lnum, true);
+ if (bd.textlen == 0 && (!virtual_op || bd.is_MAX)) {
+ continue; // nothing to replace
+ }
/* n == number of extra chars required
* If we split a TAB, it may be replaced by several characters.
@@ -1700,18 +1732,13 @@ int op_replace(oparg_T *oap, int c)
// insert pre-spaces
memset(newp + bd.textcol, ' ', (size_t)bd.startspaces);
// insert replacement chars CHECK FOR ALLOCATED SPACE
- // -1/-2 is used for entering CR literally.
+ // REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR literally.
size_t after_p_len = 0;
if (had_ctrl_v_cr || (c != '\r' && c != '\n')) {
// strlen(newp) at this point
int newp_len = bd.textcol + bd.startspaces;
- if (has_mbyte) {
- while (--num_chars >= 0) {
- newp_len += (*mb_char2bytes)(c, newp + newp_len);
- }
- } else {
- memset(newp + newp_len, c, (size_t)numc);
- newp_len += numc;
+ while (--num_chars >= 0) {
+ newp_len += utf_char2bytes(c, newp + newp_len);
}
if (!bd.is_short) {
// insert post-spaces
@@ -1727,8 +1754,8 @@ int op_replace(oparg_T *oap, int c)
after_p = (char_u *)xmalloc(after_p_len);
memmove(after_p, oldp, after_p_len);
}
- /* replace the line */
- ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+ // replace the line
+ ml_replace(curwin->w_cursor.lnum, newp, false);
if (after_p != NULL) {
ml_append(curwin->w_cursor.lnum++, after_p, (int)after_p_len, false);
appended_lines_mark(curwin->w_cursor.lnum, 1L);
@@ -1804,7 +1831,7 @@ int op_replace(oparg_T *oap, int c)
curwin->w_cursor = oap->start;
check_cursor();
- changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L);
+ changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1, 0L, true);
/* Set "'[" and "']" marks. */
curbuf->b_op_start = oap->start;
@@ -1832,14 +1859,15 @@ void op_tilde(oparg_T *oap)
for (; pos.lnum <= oap->end.lnum; pos.lnum++) {
int one_change;
- block_prep(oap, &bd, pos.lnum, FALSE);
+ block_prep(oap, &bd, pos.lnum, false);
pos.col = bd.textcol;
one_change = swapchars(oap->op_type, &pos, bd.textlen);
did_change |= one_change;
}
- if (did_change)
- changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L);
+ if (did_change) {
+ changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
+ }
} else { // not block mode
if (oap->motion_type == kMTLineWise) {
oap->start.col = 0;
@@ -1863,7 +1891,7 @@ void op_tilde(oparg_T *oap)
}
if (did_change) {
changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1,
- 0L);
+ 0L, true);
}
}
@@ -1930,13 +1958,12 @@ int swapchar(int op_type, pos_T *pos)
if (c >= 0x80 && op_type == OP_ROT13)
return FALSE;
- if (op_type == OP_UPPER && c == 0xdf
- && (enc_latin1like || STRCMP(p_enc, "iso-8859-2") == 0)) {
+ if (op_type == OP_UPPER && c == 0xdf) {
pos_T sp = curwin->w_cursor;
/* Special handling of German sharp s: change to "SS". */
curwin->w_cursor = *pos;
- del_char(FALSE);
+ del_char(false);
ins_char('S');
ins_char('S');
curwin->w_cursor = sp;
@@ -1946,16 +1973,18 @@ int swapchar(int op_type, pos_T *pos)
if (enc_dbcs != 0 && c >= 0x100) /* No lower/uppercase letter */
return FALSE;
nc = c;
- if (vim_islower(c)) {
- if (op_type == OP_ROT13)
+ if (mb_islower(c)) {
+ if (op_type == OP_ROT13) {
nc = ROT13(c, 'a');
- else if (op_type != OP_LOWER)
- nc = vim_toupper(c);
- } else if (vim_isupper(c)) {
- if (op_type == OP_ROT13)
+ } else if (op_type != OP_LOWER) {
+ nc = mb_toupper(c);
+ }
+ } else if (mb_isupper(c)) {
+ if (op_type == OP_ROT13) {
nc = ROT13(c, 'A');
- else if (op_type != OP_UPPER)
- nc = vim_tolower(c);
+ } else if (op_type != OP_UPPER) {
+ nc = mb_tolower(c);
+ }
}
if (nc != c) {
if (enc_utf8 && (c >= 0x80 || nc >= 0x80)) {
@@ -1980,6 +2009,7 @@ void op_insert(oparg_T *oap, long count1)
{
long ins_len, pre_textlen = 0;
char_u *firstline, *ins_text;
+ colnr_T ind_pre = 0;
struct block_def bd;
int i;
pos_T t1;
@@ -2008,11 +2038,15 @@ void op_insert(oparg_T *oap, long count1)
--curwin->w_cursor.col;
ve_flags = old_ve_flags;
}
- /* Get the info about the block before entering the text */
- block_prep(oap, &bd, oap->start.lnum, TRUE);
+ // Get the info about the block before entering the text
+ block_prep(oap, &bd, oap->start.lnum, true);
+ // Get indent information
+ ind_pre = (colnr_T)getwhitecols_curline();
firstline = ml_get(oap->start.lnum) + bd.textcol;
- if (oap->op_type == OP_APPEND)
+
+ if (oap->op_type == OP_APPEND) {
firstline += bd.textlen;
+ }
pre_textlen = (long)STRLEN(firstline);
}
@@ -2038,15 +2072,16 @@ void op_insert(oparg_T *oap, long count1)
curwin->w_cursor = oap->end;
check_cursor_col();
- /* Works just like an 'i'nsert on the next character. */
- if (!lineempty(curwin->w_cursor.lnum)
- && oap->start_vcol != oap->end_vcol)
+ // Works just like an 'i'nsert on the next character.
+ if (!LINEEMPTY(curwin->w_cursor.lnum)
+ && oap->start_vcol != oap->end_vcol) {
inc_cursor();
+ }
}
}
t1 = oap->start;
- edit(NUL, false, (linenr_T)count1);
+ (void)edit(NUL, false, (linenr_T)count1);
// When a tab was inserted, and the characters in front of the tab
// have been converted to a tab as well, the column of the cursor
@@ -2064,10 +2099,23 @@ void op_insert(oparg_T *oap, long count1)
if (oap->motion_type == kMTBlockWise) {
struct block_def bd2;
-
- /* The user may have moved the cursor before inserting something, try
- * to adjust the block for that. */
- if (oap->start.lnum == curbuf->b_op_start_orig.lnum && !bd.is_MAX) {
+ bool did_indent = false;
+
+ // if indent kicked in, the firstline might have changed
+ // but only do that, if the indent actually increased
+ const colnr_T ind_post = (colnr_T)getwhitecols_curline();
+ if (curbuf->b_op_start.col > ind_pre && ind_post > ind_pre) {
+ bd.textcol += ind_post - ind_pre;
+ bd.start_vcol += ind_post - ind_pre;
+ did_indent = true;
+ }
+
+ // The user may have moved the cursor before inserting something, try
+ // to adjust the block for that. But only do it, if the difference
+ // does not come from indent kicking in.
+ if (oap->start.lnum == curbuf->b_op_start_orig.lnum
+ && !bd.is_MAX
+ && !did_indent) {
if (oap->op_type == OP_INSERT
&& oap->start.col + oap->start.coladd
!= curbuf->b_op_start_orig.col + curbuf->b_op_start_orig.coladd) {
@@ -2096,7 +2144,7 @@ void op_insert(oparg_T *oap, long count1)
* tabs. Get the starting column again and correct the length.
* Don't do this when "$" used, end-of-line will have changed.
*/
- block_prep(oap, &bd2, oap->start.lnum, TRUE);
+ block_prep(oap, &bd2, oap->start.lnum, true);
if (!bd.is_MAX || bd2.textlen < bd.textlen) {
if (oap->op_type == OP_APPEND) {
pre_textlen += bd2.textlen - bd.textlen;
@@ -2111,9 +2159,17 @@ void op_insert(oparg_T *oap, long count1)
* Subsequent calls to ml_get() flush the firstline data - take a
* copy of the required string.
*/
- firstline = ml_get(oap->start.lnum) + bd.textcol;
- if (oap->op_type == OP_APPEND)
- firstline += bd.textlen;
+ firstline = ml_get(oap->start.lnum);
+ const size_t len = STRLEN(firstline);
+ colnr_T add = bd.textcol;
+ if (oap->op_type == OP_APPEND) {
+ add += bd.textlen;
+ }
+ if ((size_t)add > len) {
+ firstline += len; // short line, point to the NUL
+ } else {
+ firstline += add;
+ }
ins_len = (long)STRLEN(firstline) - pre_textlen;
if (pre_textlen >= 0 && ins_len > 0) {
ins_text = vim_strnsave(firstline, (size_t)ins_len);
@@ -2155,7 +2211,7 @@ int op_change(oparg_T *oap)
if (!p_paste && curbuf->b_p_si
&& !curbuf->b_p_cin
)
- can_si = TRUE; /* It's like opening a new line, do si */
+ can_si = true; // It's like opening a new line, do si
}
/* First delete the text in the region. In an empty buffer only need to
@@ -2166,9 +2222,10 @@ int op_change(oparg_T *oap)
} else if (op_delete(oap) == FAIL)
return FALSE;
- if ((l > curwin->w_cursor.col) && !lineempty(curwin->w_cursor.lnum)
- && !virtual_op)
+ if ((l > curwin->w_cursor.col) && !LINEEMPTY(curwin->w_cursor.lnum)
+ && !virtual_op) {
inc_cursor();
+ }
// check for still on same line (<CR> in inserted text meaningless)
// skip blank lines too
@@ -2180,7 +2237,7 @@ int op_change(oparg_T *oap)
}
firstline = ml_get(oap->start.lnum);
pre_textlen = (long)STRLEN(firstline);
- pre_indent = (long)(skipwhite(firstline) - firstline);
+ pre_indent = (long)getwhitecols(firstline);
bd.textcol = curwin->w_cursor.col;
}
@@ -2201,7 +2258,7 @@ int op_change(oparg_T *oap)
// the indent, exclude that indent change from the inserted text.
firstline = ml_get(oap->start.lnum);
if (bd.textcol > (colnr_T)pre_indent) {
- long new_indent = (long)(skipwhite(firstline) - firstline);
+ long new_indent = (long)getwhitecols(firstline);
pre_textlen += new_indent - pre_indent;
bd.textcol += (colnr_T)(new_indent - pre_indent);
@@ -2215,7 +2272,7 @@ int op_change(oparg_T *oap)
STRLCPY(ins_text, firstline + bd.textcol, ins_len + 1);
for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
linenr++) {
- block_prep(oap, &bd, linenr, TRUE);
+ block_prep(oap, &bd, linenr, true);
if (!bd.is_short || virtual_op) {
pos_T vpos;
@@ -2239,11 +2296,11 @@ int op_change(oparg_T *oap)
offset += ins_len;
oldp += bd.textcol;
STRMOVE(newp + offset, oldp);
- ml_replace(linenr, newp, FALSE);
+ ml_replace(linenr, newp, false);
}
}
check_cursor();
- changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L);
+ changed_lines(oap->start.lnum + 1, 0, oap->end.lnum + 1, 0L, true);
xfree(ins_text);
}
}
@@ -2310,7 +2367,7 @@ bool op_yank(oparg_T *oap, bool message)
yankreg_T *reg = get_yank_register(oap->regname, YREG_YANK);
op_yank_reg(oap, message, reg, is_append_register(oap->regname));
set_clipboard(oap->regname, reg);
- yank_do_autocmd(oap, reg);
+ do_autocmd_textyankpost(oap, reg);
return true;
}
@@ -2406,11 +2463,10 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
if (virtual_op) {
getvcol(curwin, &oap->end, &cs, NULL, &ce);
if (p[endcol] == NUL || (cs + oap->end.coladd < ce
- /* Don't add space for double-wide
- * char; endcol will be on last byte
- * of multi-byte char. */
- && (*mb_head_off)(p, p + endcol) == 0
- )) {
+ // Don't add space for double-wide
+ // char; endcol will be on last byte
+ // of multi-byte char.
+ && utf_head_off(p, p + endcol) == 0)) {
if (oap->start.lnum == oap->end.lnum
&& oap->start.col == oap->end.col) {
/* Special case: inside a single char */
@@ -2485,19 +2541,27 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
}
// Some versions of Vi use ">=" here, some don't...
if (yanklines > (size_t)p_report) {
+ char namebuf[100];
+
+ if (oap->regname == NUL) {
+ *namebuf = NUL;
+ } else {
+ vim_snprintf(namebuf, sizeof(namebuf), _(" into \"%c"), oap->regname);
+ }
+
// redisplay now, so message is not deleted
update_topline_redraw();
if (yanklines == 1) {
if (yank_type == kMTBlockWise) {
- MSG(_("block of 1 line yanked"));
+ smsg(_("block of 1 line yanked%s"), namebuf);
} else {
- MSG(_("1 line yanked"));
+ smsg(_("1 line yanked%s"), namebuf);
}
} else if (yank_type == kMTBlockWise) {
- smsg(_("block of %" PRId64 " lines yanked"),
- (int64_t)yanklines);
+ smsg(_("block of %" PRId64 " lines yanked%s"),
+ (int64_t)yanklines, namebuf);
} else {
- smsg(_("%" PRId64 " lines yanked"), (int64_t)yanklines);
+ smsg(_("%" PRId64 " lines yanked%s"), (int64_t)yanklines, namebuf);
}
}
}
@@ -2533,7 +2597,7 @@ static void yank_copy_line(yankreg_T *reg, struct block_def *bd, size_t y_idx)
///
/// @param oap Operator arguments.
/// @param reg The yank register used.
-static void yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
+static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
FUNC_ATTR_NONNULL_ALL
{
static bool recursive = false;
@@ -2550,33 +2614,33 @@ static void yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
dict_T *dict = get_vim_var_dict(VV_EVENT);
// the yanked text
- list_T *list = list_alloc();
+ list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
for (size_t i = 0; i < reg->y_size; i++) {
- list_append_string(list, reg->y_array[i], -1);
+ tv_list_append_string(list, (const char *)reg->y_array[i], -1);
}
- list->lv_lock = VAR_FIXED;
- dict_add_list(dict, "regcontents", list);
+ tv_list_set_lock(list, VAR_FIXED);
+ tv_dict_add_list(dict, S_LEN("regcontents"), list);
// the register type
char buf[NUMBUFLEN+2];
format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf));
- dict_add_nr_str(dict, "regtype", 0, (char_u *)buf);
+ tv_dict_add_str(dict, S_LEN("regtype"), buf);
// name of requested register or the empty string for an unnamed operation.
buf[0] = (char)oap->regname;
buf[1] = NUL;
- dict_add_nr_str(dict, "regname", 0, (char_u *)buf);
+ tv_dict_add_str(dict, S_LEN("regname"), buf);
// kind of operation (yank/delete/change)
buf[0] = (char)get_op_char(oap->op_type);
buf[1] = NUL;
- dict_add_nr_str(dict, "operator", 0, (char_u *)buf);
+ tv_dict_add_str(dict, S_LEN("operator"), buf);
- dict_set_keys_readonly(dict);
+ tv_dict_set_keys_readonly(dict);
textlock++;
apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, false, curbuf);
textlock--;
- dict_clear(dict);
+ tv_dict_clear(dict);
recursive = false;
}
@@ -2606,7 +2670,6 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
colnr_T vcol;
int delcount;
int incr = 0;
- long j;
struct block_def bd;
char_u **y_array = NULL;
long nr_lines = 0;
@@ -2618,7 +2681,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
int lendiff = 0;
pos_T old_pos;
char_u *insert_string = NULL;
- int allocated = FALSE;
+ bool allocated = false;
long cnt;
if (flags & PUT_FIXINDENT)
@@ -2632,12 +2695,81 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
* special characters (newlines, etc.).
*/
if (regname == '.') {
- (void)stuff_inserted((dir == FORWARD ? (count == -1 ? 'o' : 'a') :
- (count == -1 ? 'O' : 'i')), count, FALSE);
- /* Putting the text is done later, so can't really move the cursor to
- * the next character. Use "l" to simulate it. */
- if ((flags & PUT_CURSEND) && gchar_cursor() != NUL)
- stuffcharReadbuff('l');
+ bool non_linewise_vis = (VIsual_active && VIsual_mode != 'V');
+
+ // PUT_LINE has special handling below which means we use 'i' to start.
+ char command_start_char = non_linewise_vis ? 'c' :
+ (flags & PUT_LINE ? 'i' : (dir == FORWARD ? 'a' : 'i'));
+
+ // To avoid 'autoindent' on linewise puts, create a new line with `:put _`.
+ if (flags & PUT_LINE) {
+ do_put('_', NULL, dir, 1, PUT_LINE);
+ }
+
+ // If given a count when putting linewise, we stuff the readbuf with the
+ // dot register 'count' times split by newlines.
+ if (flags & PUT_LINE) {
+ stuffcharReadbuff(command_start_char);
+ for (; count > 0; count--) {
+ (void)stuff_inserted(NUL, 1, count != 1);
+ if (count != 1) {
+ // To avoid 'autoindent' affecting the text, use Ctrl_U to remove any
+ // whitespace. Can't just insert Ctrl_U into readbuf1, this would go
+ // back to the previous line in the case of 'noautoindent' and
+ // 'backspace' includes "eol". So we insert a dummy space for Ctrl_U
+ // to consume.
+ stuffReadbuff("\n ");
+ stuffcharReadbuff(Ctrl_U);
+ }
+ }
+ } else {
+ (void)stuff_inserted(command_start_char, count, false);
+ }
+
+ // Putting the text is done later, so can't move the cursor to the next
+ // character. Simulate it with motion commands after the insert.
+ if (flags & PUT_CURSEND) {
+ if (flags & PUT_LINE) {
+ stuffReadbuff("j0");
+ } else {
+ // Avoid ringing the bell from attempting to move into the space after
+ // the current line. We can stuff the readbuffer with "l" if:
+ // 1) 'virtualedit' is "all" or "onemore"
+ // 2) We are not at the end of the line
+ // 3) We are not (one past the end of the line && on the last line)
+ // This allows a visual put over a selection one past the end of the
+ // line joining the current line with the one below.
+
+ // curwin->w_cursor.col marks the byte position of the cursor in the
+ // currunt line. It increases up to a max of
+ // STRLEN(ml_get(curwin->w_cursor.lnum)). With 'virtualedit' and the
+ // cursor past the end of the line, curwin->w_cursor.coladd is
+ // incremented instead of curwin->w_cursor.col.
+ char_u *cursor_pos = get_cursor_pos_ptr();
+ bool one_past_line = (*cursor_pos == NUL);
+ bool eol = false;
+ if (!one_past_line) {
+ eol = (*(cursor_pos + mb_ptr2len(cursor_pos)) == NUL);
+ }
+
+ bool ve_allows = (ve_flags == VE_ALL || ve_flags == VE_ONEMORE);
+ bool eof = curbuf->b_ml.ml_line_count == curwin->w_cursor.lnum
+ && one_past_line;
+ if (ve_allows || !(eol || eof)) {
+ stuffcharReadbuff('l');
+ }
+ }
+ } else if (flags & PUT_LINE) {
+ stuffReadbuff("g'[");
+ }
+
+ // So the 'u' command restores cursor position after ".p, save the cursor
+ // position now (though not saving any text).
+ if (command_start_char == 'a') {
+ if (u_save(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1) == FAIL) {
+ return;
+ }
+ }
return;
}
@@ -2645,16 +2777,16 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
* For special registers '%' (file name), '#' (alternate file name) and
* ':' (last command line), etc. we have to create a fake yank register.
*/
- if (get_spec_reg(regname, &insert_string, &allocated, TRUE)) {
- if (insert_string == NULL)
+ if (get_spec_reg(regname, &insert_string, &allocated, true)) {
+ if (insert_string == NULL) {
return;
+ }
}
if (!curbuf->terminal) {
// Autocommands may be executed when saving lines for undo, which may make
// y_array invalid. Start undo now to avoid that.
if (u_save(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1) == FAIL) {
- ELOG(_("Failed to save undo information"));
return;
}
}
@@ -2707,16 +2839,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
if (curbuf->terminal) {
- for (int i = 0; i < count; i++) {
- // feed the lines to the terminal
- for (size_t j = 0; j < y_size; j++) {
- if (j) {
- // terminate the previous line
- terminal_send(curbuf->terminal, "\n", 1);
- }
- terminal_send(curbuf->terminal, (char *)y_array[j], STRLEN(y_array[j]));
- }
- }
+ terminal_paste(count, y_array, y_size);
return;
}
@@ -2729,7 +2852,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
char_u *p = get_cursor_pos_ptr();
if (dir == FORWARD && *p != NUL) {
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
ptr = vim_strsave(p);
ml_append(curwin->w_cursor.lnum, ptr, (colnr_T)0, false);
@@ -2738,7 +2861,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
oldp = get_cursor_line_ptr();
p = oldp + curwin->w_cursor.col;
if (dir == FORWARD && *p != NUL) {
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
ptr = vim_strnsave(oldp, (size_t)(p - oldp));
ml_replace(curwin->w_cursor.lnum, ptr, false);
@@ -2774,25 +2897,30 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
}
} else if (y_type == kMTLineWise) {
lnum = curwin->w_cursor.lnum;
- /* Correct line number for closed fold. Don't move the cursor yet,
- * u_save() uses it. */
- if (dir == BACKWARD)
+ // Correct line number for closed fold. Don't move the cursor yet,
+ // u_save() uses it.
+ if (dir == BACKWARD) {
(void)hasFolding(lnum, &lnum, NULL);
- else
+ } else {
(void)hasFolding(lnum, NULL, &lnum);
- if (dir == FORWARD)
- ++lnum;
- /* In an empty buffer the empty line is going to be replaced, include
- * it in the saved lines. */
- if ((bufempty() ? u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL)
+ }
+ if (dir == FORWARD) {
+ lnum++;
+ }
+ // In an empty buffer the empty line is going to be replaced, include
+ // it in the saved lines.
+ if ((BUFEMPTY() ? u_save(0, 2) : u_save(lnum - 1, lnum)) == FAIL) {
goto end;
- if (dir == FORWARD)
+ }
+ if (dir == FORWARD) {
curwin->w_cursor.lnum = lnum - 1;
- else
+ } else {
curwin->w_cursor.lnum = lnum;
- curbuf->b_op_start = curwin->w_cursor; /* for mark_adjust() */
- } else if (u_save_cursor() == FAIL)
+ }
+ curbuf->b_op_start = curwin->w_cursor; // for mark_adjust()
+ } else if (u_save_cursor() == FAIL) {
goto end;
+ }
yanklen = (int)STRLEN(y_array[0]);
@@ -2826,14 +2954,12 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
else
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
- if (has_mbyte)
- /* move to start of next multi-byte character */
- curwin->w_cursor.col += (*mb_ptr2len)(get_cursor_pos_ptr());
- else if (c != TAB || ve_flags != VE_ALL)
- ++curwin->w_cursor.col;
- ++col;
- } else
+ // move to start of next multi-byte character
+ curwin->w_cursor.col += (*mb_ptr2len)(get_cursor_pos_ptr());
+ col++;
+ } else {
getvcol(curwin, &curwin->w_cursor, &col, NULL, &endcol2);
+ }
col += curwin->w_cursor.coladd;
if (ve_flags == VE_ALL
@@ -2887,8 +3013,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
bd.startspaces = incr - bd.endspaces;
--bd.textcol;
delcount = 1;
- if (has_mbyte)
- bd.textcol -= (*mb_head_off)(oldp, oldp + bd.textcol);
+ bd.textcol -= utf_head_off(oldp, oldp + bd.textcol);
if (oldp[bd.textcol] != TAB) {
/* Only a Tab can be split into spaces. Other
* characters will have to be moved to after the
@@ -2900,12 +3025,14 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
yanklen = (int)STRLEN(y_array[i]);
- /* calculate number of spaces required to fill right side of block*/
+ // calculate number of spaces required to fill right side of block
spaces = y_width + 1;
- for (j = 0; j < yanklen; j++)
+ for (long j = 0; j < yanklen; j++) {
spaces -= lbr_chartabsize(NULL, &y_array[i][j], 0);
- if (spaces < 0)
+ }
+ if (spaces < 0) {
spaces = 0;
+ }
// insert the new text
totlen = (size_t)(count * (yanklen + spaces)
@@ -2915,21 +3042,21 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
ptr = newp;
memmove(ptr, oldp, (size_t)bd.textcol);
ptr += bd.textcol;
- /* may insert some spaces before the new text */
+ // may insert some spaces before the new text
memset(ptr, ' ', (size_t)bd.startspaces);
ptr += bd.startspaces;
- /* insert the new text */
- for (j = 0; j < count; ++j) {
+ // insert the new text
+ for (long j = 0; j < count; j++) {
memmove(ptr, y_array[i], (size_t)yanklen);
ptr += yanklen;
- /* insert block's trailing spaces only if there's text behind */
+ // insert block's trailing spaces only if there's text behind
if ((j < count - 1 || !shortline) && spaces) {
memset(ptr, ' ', (size_t)spaces);
ptr += spaces;
}
}
- /* may insert some spaces after the new text */
+ // may insert some spaces after the new text
memset(ptr, ' ', (size_t)bd.endspaces);
ptr += bd.endspaces;
// move the text after the cursor to the end of the line.
@@ -2942,7 +3069,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
curwin->w_cursor.col += bd.startspaces;
}
- changed_lines(lnum, 0, curwin->w_cursor.lnum, nr_lines);
+ changed_lines(lnum, 0, curwin->w_cursor.lnum, nr_lines, true);
/* Set '[ mark. */
curbuf->b_op_start = curwin->w_cursor;
@@ -2970,21 +3097,13 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
// if type is kMTCharWise, FORWARD is the same as BACKWARD on the next
// char
if (dir == FORWARD && gchar_cursor() != NUL) {
- if (has_mbyte) {
- int bytelen = (*mb_ptr2len)(get_cursor_pos_ptr());
-
- /* put it on the next of the multi-byte character. */
- col += bytelen;
- if (yanklen) {
- curwin->w_cursor.col += bytelen;
- curbuf->b_op_end.col += bytelen;
- }
- } else {
- ++col;
- if (yanklen) {
- ++curwin->w_cursor.col;
- ++curbuf->b_op_end.col;
- }
+ int bytelen = (*mb_ptr2len)(get_cursor_pos_ptr());
+
+ // put it on the next of the multi-byte character.
+ col += bytelen;
+ if (yanklen) {
+ curwin->w_cursor.col += bytelen;
+ curbuf->b_op_end.col += bytelen;
}
}
curbuf->b_op_start = curwin->w_cursor;
@@ -2996,15 +3115,26 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
--lnum;
new_cursor = curwin->w_cursor;
- /*
- * simple case: insert into current line
- */
+ // simple case: insert into current line
if (y_type == kMTCharWise && y_size == 1) {
+ linenr_T end_lnum = 0; // init for gcc
+
+ if (VIsual_active) {
+ end_lnum = curbuf->b_visual.vi_end.lnum;
+ if (end_lnum < curbuf->b_visual.vi_start.lnum) {
+ end_lnum = curbuf->b_visual.vi_start.lnum;
+ }
+ }
+
do {
totlen = (size_t)(count * yanklen);
if (totlen > 0) {
oldp = ml_get(lnum);
- newp = (char_u *) xmalloc((size_t)(STRLEN(oldp) + totlen + 1));
+ if (VIsual_active && col > (int)STRLEN(oldp)) {
+ lnum++;
+ continue;
+ }
+ newp = (char_u *)xmalloc((size_t)(STRLEN(oldp) + totlen + 1));
memmove(newp, oldp, (size_t)col);
ptr = newp + col;
for (i = 0; i < (size_t)count; i++) {
@@ -3012,17 +3142,18 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
ptr += yanklen;
}
STRMOVE(ptr, oldp + col);
- ml_replace(lnum, newp, FALSE);
- /* Place cursor on last putted char. */
+ ml_replace(lnum, newp, false);
+ // Place cursor on last putted char.
if (lnum == curwin->w_cursor.lnum) {
- /* make sure curwin->w_virtcol is updated */
+ // make sure curwin->w_virtcol is updated
changed_cline_bef_curs();
curwin->w_cursor.col += (colnr_T)(totlen - 1);
}
}
- if (VIsual_active)
+ if (VIsual_active) {
lnum++;
- } while (VIsual_active && lnum <= curbuf->b_visual.vi_end.lnum);
+ }
+ } while (VIsual_active && lnum <= end_lnum);
if (VIsual_active) { /* reset lnum to the last visual line */
lnum--;
@@ -3058,7 +3189,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
memmove(newp, oldp, (size_t)col);
/* append to first line */
memmove(newp + col, y_array[0], (size_t)(yanklen + 1));
- ml_replace(lnum, newp, FALSE);
+ ml_replace(lnum, newp, false);
curwin->w_cursor.lnum = lnum;
i = 1;
@@ -3104,16 +3235,21 @@ error:
if (dir == FORWARD)
curbuf->b_op_start.lnum++;
}
- mark_adjust(curbuf->b_op_start.lnum + (y_type == kMTCharWise),
- (linenr_T)MAXLNUM, nr_lines, 0L);
+ // Skip mark_adjust when adding lines after the last one, there
+ // can't be marks there. But still needed in diff mode.
+ if (curbuf->b_op_start.lnum + (y_type == kMTCharWise) - 1 + nr_lines
+ < curbuf->b_ml.ml_line_count || curwin->w_p_diff) {
+ mark_adjust(curbuf->b_op_start.lnum + (y_type == kMTCharWise),
+ (linenr_T)MAXLNUM, nr_lines, 0L, false);
+ }
// note changed text for displaying and folding
if (y_type == kMTCharWise) {
changed_lines(curwin->w_cursor.lnum, col,
- curwin->w_cursor.lnum + 1, nr_lines);
+ curwin->w_cursor.lnum + 1, nr_lines, true);
} else {
changed_lines(curbuf->b_op_start.lnum, 0,
- curbuf->b_op_start.lnum, nr_lines);
+ curbuf->b_op_start.lnum, nr_lines, true);
}
/* put '] mark at last inserted character */
@@ -3232,7 +3368,7 @@ void ex_display(exarg_T *eap)
if (arg != NULL && *arg == NUL)
arg = NULL;
- int attr = hl_attr(HLF_8);
+ int attr = HL_ATTR(HLF_8);
/* Highlight title */
MSG_PUTS_TITLE(_("\n--- Registers ---"));
@@ -3254,10 +3390,11 @@ void ex_display(exarg_T *eap)
get_clipboard(name, &yb, true);
- if (name == vim_tolower(redir_reg)
- || (redir_reg == '"' && yb == y_previous))
- continue; /* do not list register being written to, the
- * pointer can be freed */
+ if (name == mb_tolower(redir_reg)
+ || (redir_reg == '"' && yb == y_previous)) {
+ continue; // do not list register being written to, the
+ // pointer can be freed
+ }
if (yb->y_array != NULL) {
msg_putchar('\n');
@@ -3370,43 +3507,47 @@ dis_msg (
os_breakcheck();
}
-/*
- * If "process" is TRUE and the line begins with a comment leader (possibly
- * after some white space), return a pointer to the text after it. Put a boolean
- * value indicating whether the line ends with an unclosed comment in
- * "is_comment".
- * line - line to be processed,
- * process - if FALSE, will only check whether the line ends with an unclosed
- * comment,
- * include_space - whether to also skip space following the comment leader,
- * is_comment - will indicate whether the current line ends with an unclosed
- * comment.
- */
-static char_u *skip_comment(char_u *line, int process, int include_space, int *is_comment)
+/// If \p "process" is true and the line begins with a comment leader (possibly
+/// after some white space), return a pointer to the text after it.
+/// Put a boolean value indicating whether the line ends with an unclosed
+/// comment in "is_comment".
+///
+/// @param line - line to be processed
+/// @param process - if false, will only check whether the line ends
+/// with an unclosed comment,
+/// @param include_space - whether to skip space following the comment leader
+/// @param[out] is_comment - whether the current line ends with an unclosed
+/// comment.
+char_u *skip_comment(
+ char_u *line, bool process, bool include_space, bool *is_comment
+)
{
char_u *comment_flags = NULL;
int lead_len;
int leader_offset = get_last_leader_offset(line, &comment_flags);
- *is_comment = FALSE;
+ *is_comment = false;
if (leader_offset != -1) {
/* Let's check whether the line ends with an unclosed comment.
* If the last comment leader has COM_END in flags, there's no comment.
*/
while (*comment_flags) {
if (*comment_flags == COM_END
- || *comment_flags == ':')
+ || *comment_flags == ':') {
break;
- ++comment_flags;
+ }
+ comment_flags++;
+ }
+ if (*comment_flags != COM_END) {
+ *is_comment = true;
}
- if (*comment_flags != COM_END)
- *is_comment = TRUE;
}
- if (process == FALSE)
+ if (process == false) {
return line;
+ }
- lead_len = get_leader_len(line, &comment_flags, FALSE, include_space);
+ lead_len = get_leader_len(line, &comment_flags, false, include_space);
if (lead_len == 0)
return line;
@@ -3428,8 +3569,9 @@ static char_u *skip_comment(char_u *line, int process, int include_space, int *i
* starting with a closing part of a three-part comment. That's good,
* because we don't want to remove those as this would be annoying.
*/
- if (*comment_flags == ':' || *comment_flags == NUL)
+ if (*comment_flags == ':' || *comment_flags == NUL) {
line += lead_len;
+ }
return line;
}
@@ -3463,7 +3605,7 @@ int do_join(size_t count,
int *comments = NULL;
int remove_comments = (use_formatoptions == TRUE)
&& has_format_option(FO_REMOVE_COMS);
- int prev_was_comment;
+ bool prev_was_comment = false;
if (save_undo && u_save(curwin->w_cursor.lnum - 1,
curwin->w_cursor.lnum + (linenr_T)count) == FAIL) {
@@ -3487,26 +3629,25 @@ int do_join(size_t count,
curwin->w_buffer->b_op_start.col = (colnr_T)STRLEN(curr);
}
if (remove_comments) {
- /* We don't want to remove the comment leader if the
- * previous line is not a comment. */
+ // We don't want to remove the comment leader if the
+ // previous line is not a comment.
if (t > 0 && prev_was_comment) {
-
- char_u *new_curr = skip_comment(curr, TRUE, insert_space,
- &prev_was_comment);
+ char_u *new_curr = skip_comment(curr, true, insert_space,
+ &prev_was_comment);
comments[t] = (int)(new_curr - curr);
curr = new_curr;
- } else
- curr = skip_comment(curr, FALSE, insert_space,
- &prev_was_comment);
+ } else {
+ curr = skip_comment(curr, false, insert_space, &prev_was_comment);
+ }
}
if (insert_space && t > 0) {
curr = skipwhite(curr);
if (*curr != ')' && currsize != 0 && endcurr1 != TAB
&& (!has_format_option(FO_MBYTE_JOIN)
- || (mb_ptr2char(curr) < 0x100 && endcurr1 < 0x100))
+ || (utf_ptr2char(curr) < 0x100 && endcurr1 < 0x100))
&& (!has_format_option(FO_MBYTE_JOIN2)
- || mb_ptr2char(curr) < 0x100 || endcurr1 < 0x100)
+ || utf_ptr2char(curr) < 0x100 || endcurr1 < 0x100)
) {
/* don't add a space if the line is ending in a space */
if (endcurr1 == ' ')
@@ -3523,18 +3664,12 @@ int do_join(size_t count,
sumsize += currsize + spaces[t];
endcurr1 = endcurr2 = NUL;
if (insert_space && currsize > 0) {
- if (has_mbyte) {
- cend = curr + currsize;
- mb_ptr_back(curr, cend);
- endcurr1 = (*mb_ptr2char)(cend);
- if (cend > curr) {
- mb_ptr_back(curr, cend);
- endcurr2 = (*mb_ptr2char)(cend);
- }
- } else {
- endcurr1 = *(curr + currsize - 1);
- if (currsize > 1)
- endcurr2 = *(curr + currsize - 2);
+ cend = curr + currsize;
+ MB_PTR_BACK(curr, cend);
+ endcurr1 = utf_ptr2char(cend);
+ if (cend > curr) {
+ MB_PTR_BACK(curr, cend);
+ endcurr2 = utf_ptr2char(cend);
}
}
line_breakcheck();
@@ -3577,7 +3712,7 @@ int do_join(size_t count,
curr = skipwhite(curr);
currsize = (int)STRLEN(curr);
}
- ml_replace(curwin->w_cursor.lnum, newp, FALSE);
+ ml_replace(curwin->w_cursor.lnum, newp, false);
if (setmark) {
// Set the '] mark.
@@ -3588,7 +3723,7 @@ int do_join(size_t count,
/* Only report the change in the first line here, del_lines() will report
* the deleted line. */
changed_lines(curwin->w_cursor.lnum, currsize,
- curwin->w_cursor.lnum + 1, 0L);
+ curwin->w_cursor.lnum + 1, 0L, true);
/*
* Delete following lines. To do this we move the cursor there
@@ -3774,6 +3909,7 @@ fex_format (
int use_sandbox = was_set_insecurely((char_u *)"formatexpr",
OPT_LOCAL);
int r;
+ char_u *fex;
/*
* Set v:lnum to the first line number and v:count to the number of lines.
@@ -3783,16 +3919,19 @@ fex_format (
set_vim_var_nr(VV_COUNT, (varnumber_T)count);
set_vim_var_char(c);
- /*
- * Evaluate the function.
- */
- if (use_sandbox)
- ++sandbox;
- r = eval_to_number(curbuf->b_p_fex);
- if (use_sandbox)
- --sandbox;
+ // Make a copy, the option could be changed while calling it.
+ fex = vim_strsave(curbuf->b_p_fex);
+ // Evaluate the function.
+ if (use_sandbox) {
+ sandbox++;
+ }
+ r = (int)eval_to_number(fex);
+ if (use_sandbox) {
+ sandbox--;
+ }
set_vim_var_string(VV_CHAR, NULL, -1);
+ xfree(fex);
return r;
}
@@ -3907,7 +4046,7 @@ format_lines (
&& (do_second_indent || do_number_indent)
&& prev_is_end_par
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
- if (do_second_indent && !lineempty(curwin->w_cursor.lnum + 1)) {
+ if (do_second_indent && !LINEEMPTY(curwin->w_cursor.lnum + 1)) {
if (leader_len == 0 && next_leader_len == 0) {
/* no comment found */
second_indent =
@@ -3993,10 +4132,9 @@ format_lines (
if (next_leader_len > 0) {
(void)del_bytes(next_leader_len, false, false);
mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
- (long)-next_leader_len);
- } else if (second_indent > 0) { /* the "leader" for FO_Q_SECOND */
- char_u *p = get_cursor_line_ptr();
- int indent = (int)(skipwhite(p) - p);
+ (long)-next_leader_len);
+ } else if (second_indent > 0) { // the "leader" for FO_Q_SECOND
+ int indent = (int)getwhitecols_curline();
if (indent > 0) {
(void)del_bytes(indent, FALSE, FALSE);
@@ -4125,7 +4263,8 @@ int paragraph_start(linenr_T lnum)
* - start/endspaces is the number of columns of the first/last yanked char
* that are to be yanked.
*/
-static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, int is_del)
+static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum,
+ bool is_del)
{
int incr = 0;
char_u *pend;
@@ -4161,7 +4300,7 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, int i
bdp->pre_whitesp_c = 0;
}
prev_pstart = pstart;
- mb_ptr_adv(pstart);
+ MB_PTR_ADV(pstart);
}
bdp->start_char_vcols = incr;
if (bdp->start_vcol < oap->start_vcol) { /* line too short */
@@ -4254,7 +4393,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
}
change_cnt = do_addsub(oap->op_type, &pos, 0, amount);
if (change_cnt) {
- changed_lines(pos.lnum, 0, pos.lnum + 1, 0L);
+ changed_lines(pos.lnum, 0, pos.lnum + 1, 0L, true);
}
} else {
int one_change;
@@ -4279,7 +4418,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
length = (colnr_T)STRLEN(ml_get(pos.lnum));
} else {
// oap->motion_type == kMTCharWise
- if (!oap->inclusive) {
+ if (pos.lnum == oap->start.lnum && !oap->inclusive) {
dec(&(oap->end));
}
length = (colnr_T)STRLEN(ml_get(pos.lnum));
@@ -4310,7 +4449,7 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
}
}
if (change_cnt) {
- changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L);
+ changed_lines(oap->start.lnum, 0, oap->end.lnum + 1, 0L, true);
}
if (!change_cnt && oap->is_VIsual) {
@@ -4349,8 +4488,8 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
char_u buf2[NUMBUFLEN];
int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin
static bool hexupper = false; // 0xABC
- unsigned long n;
- unsigned long oldn;
+ uvarnumber_T n;
+ uvarnumber_T oldn;
char_u *ptr;
int c;
int todel;
@@ -4387,12 +4526,14 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
if (dobin) {
while (col > 0 && ascii_isbdigit(ptr[col])) {
col--;
+ col -= utf_head_off(ptr, ptr + col);
}
}
if (dohex) {
while (col > 0 && ascii_isxdigit(ptr[col])) {
col--;
+ col -= utf_head_off(ptr, ptr + col);
}
}
if (dobin
@@ -4400,6 +4541,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
&& !((col > 0
&& (ptr[col] == 'X' || ptr[col] == 'x')
&& ptr[col - 1] == '0'
+ && !utf_head_off(ptr, ptr + col - 1)
&& ascii_isxdigit(ptr[col + 1])))) {
// In case of binary/hexadecimal pattern overlap match, rescan
@@ -4407,6 +4549,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
while (col > 0 && ascii_isdigit(ptr[col])) {
col--;
+ col -= utf_head_off(ptr, ptr + col);
}
}
@@ -4414,14 +4557,17 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
&& col > 0
&& (ptr[col] == 'X' || ptr[col] == 'x')
&& ptr[col - 1] == '0'
+ && !utf_head_off(ptr, ptr + col - 1)
&& ascii_isxdigit(ptr[col + 1]))
|| (dobin
&& col > 0
&& (ptr[col] == 'B' || ptr[col] == 'b')
&& ptr[col - 1] == '0'
+ && !utf_head_off(ptr, ptr + col - 1)
&& ascii_isbdigit(ptr[col + 1]))) {
// Found hexadecimal or binary number, move to its start.
col--;
+ col -= utf_head_off(ptr, ptr + col);
} else {
// Search forward and then backward to find the start of number.
col = pos->col;
@@ -4443,15 +4589,18 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
if (visual) {
while (ptr[col] != NUL && length > 0 && !ascii_isdigit(ptr[col])
&& !(doalp && ASCII_ISALPHA(ptr[col]))) {
- col++;
- length--;
+ int mb_len = MB_PTR2LEN(ptr + col);
+
+ col += mb_len;
+ length -= mb_len;
}
if (length == 0) {
goto theend;
}
- if (col > pos->col && ptr[col - 1] == '-') {
+ if (col > pos->col && ptr[col - 1] == '-'
+ && !utf_head_off(ptr, ptr + col - 1)) {
negative = true;
was_positive = false;
}
@@ -4488,16 +4637,15 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
}
}
curwin->w_cursor.col = col;
- if (!did_change) {
- startpos = curwin->w_cursor;
- }
+ startpos = curwin->w_cursor;
did_change = true;
(void)del_char(false);
ins_char(firstdigit);
endpos = curwin->w_cursor;
curwin->w_cursor.col = col;
} else {
- if (col > 0 && ptr[col - 1] == '-' && !visual) {
+ if (col > 0 && ptr[col - 1] == '-'
+ && !utf_head_off(ptr, ptr + col - 1) && !visual) {
// negative number
col--;
negative = true;
@@ -4534,20 +4682,20 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
oldn = n;
- n = subtract ? n - (unsigned long) Prenum1
- : n + (unsigned long) Prenum1;
+ n = subtract ? n - (uvarnumber_T)Prenum1
+ : n + (uvarnumber_T)Prenum1;
// handle wraparound for decimal numbers
if (!pre) {
if (subtract) {
if (n > oldn) {
- n = 1 + (n ^ (unsigned long)-1);
+ n = 1 + (n ^ (uvarnumber_T)-1);
negative ^= true;
}
} else {
// add
if (n < oldn) {
- n = (n ^ (unsigned long)-1);
+ n = (n ^ (uvarnumber_T)-1);
negative ^= true;
}
}
@@ -4564,9 +4712,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
// Delete the old number.
curwin->w_cursor.col = col;
- if (!did_change) {
- startpos = curwin->w_cursor;
- }
+ startpos = curwin->w_cursor;
did_change = true;
todel = length;
c = gchar_cursor();
@@ -4593,11 +4739,8 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
// When there are many leading zeros it could be very long.
// Allocate a bit too much.
buf1 = xmalloc((size_t)length + NUMBUFLEN);
- if (buf1 == NULL) {
- goto theend;
- }
ptr = buf1;
- if (negative && (!visual || (visual && was_positive))) {
+ if (negative && (!visual || was_positive)) {
*ptr++ = '-';
}
if (pre) {
@@ -4631,7 +4774,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIu64, (uint64_t)n);
} else if (pre == '0') {
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIo64, (uint64_t)n);
- } else if (pre && hexupper) {
+ } else if (hexupper) {
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIX64, (uint64_t)n);
} else {
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIx64, (uint64_t)n);
@@ -4652,23 +4795,23 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
ins_str(buf1); // insert the new number
xfree(buf1);
endpos = curwin->w_cursor;
- if (did_change && curwin->w_cursor.col) {
+ if (curwin->w_cursor.col) {
curwin->w_cursor.col--;
}
}
- if (did_change) {
- // set the '[ and '] marks
- curbuf->b_op_start = startpos;
- curbuf->b_op_end = endpos;
- if (curbuf->b_op_end.col > 0) {
- curbuf->b_op_end.col--;
- }
+ // set the '[ and '] marks
+ curbuf->b_op_start = startpos;
+ curbuf->b_op_end = endpos;
+ if (curbuf->b_op_end.col > 0) {
+ curbuf->b_op_end.col--;
}
theend:
if (visual) {
curwin->w_cursor = save_cursor;
+ } else if (did_change) {
+ curwin->w_set_curswant = true;
}
return did_change;
@@ -4751,9 +4894,8 @@ static void *get_reg_wrap_one_line(char_u *s, int flags)
if (!(flags & kGRegList)) {
return s;
}
- list_T *list = list_alloc();
- list_append_string(list, NULL, -1);
- list->lv_first->li_tv.vval.v_string = s;
+ list_T *const list = tv_list_alloc(1);
+ tv_list_append_allocated_string(list, (char *)s);
return list;
}
@@ -4787,10 +4929,11 @@ void *get_reg_contents(int regname, int flags)
return NULL;
char_u *retval;
- int allocated;
- if (get_spec_reg(regname, &retval, &allocated, FALSE)) {
- if (retval == NULL)
+ bool allocated;
+ if (get_spec_reg(regname, &retval, &allocated, false)) {
+ if (retval == NULL) {
return NULL;
+ }
if (allocated) {
return get_reg_wrap_one_line(retval, flags);
}
@@ -4802,9 +4945,9 @@ void *get_reg_contents(int regname, int flags)
return NULL;
if (flags & kGRegList) {
- list_T *list = list_alloc();
+ list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size);
for (size_t i = 0; i < reg->y_size; i++) {
- list_append_string(list, reg->y_array[i], -1);
+ tv_list_append_string(list, (const char *)reg->y_array[i], -1);
}
return list;
@@ -4885,7 +5028,7 @@ void write_reg_contents(int name, const char_u *str, ssize_t len,
write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L);
}
-void write_reg_contents_lst(int name, char_u **strings, int maxlen,
+void write_reg_contents_lst(int name, char_u **strings,
bool must_append, MotionType yank_type,
colnr_T block_len)
{
@@ -5135,11 +5278,13 @@ void clear_oparg(oparg_T *oap)
* case, eol_size will be added to the character count to account for
* the size of the EOL character.
*/
-static long line_count_info(char_u *line, long *wc, long *cc, long limit, int eol_size)
+static varnumber_T line_count_info(char_u *line, varnumber_T *wc,
+ varnumber_T *cc, varnumber_T limit,
+ int eol_size)
{
- long i;
- long words = 0;
- long chars = 0;
+ varnumber_T i;
+ varnumber_T words = 0;
+ varnumber_T chars = 0;
int is_word = 0;
for (i = 0; i < limit && line[i] != NUL; ) {
@@ -5177,15 +5322,15 @@ void cursor_pos_info(dict_T *dict)
char_u buf1[50];
char_u buf2[40];
linenr_T lnum;
- long byte_count = 0;
- long bom_count = 0;
- long byte_count_cursor = 0;
- long char_count = 0;
- long char_count_cursor = 0;
- long word_count = 0;
- long word_count_cursor = 0;
+ varnumber_T byte_count = 0;
+ varnumber_T bom_count = 0;
+ varnumber_T byte_count_cursor = 0;
+ varnumber_T char_count = 0;
+ varnumber_T char_count_cursor = 0;
+ varnumber_T word_count = 0;
+ varnumber_T word_count_cursor = 0;
int eol_size;
- long last_check = 100000L;
+ varnumber_T last_check = 100000L;
long line_count_selected = 0;
pos_T min_pos, max_pos;
oparg_T oparg;
@@ -5257,8 +5402,8 @@ void cursor_pos_info(dict_T *dict)
switch (l_VIsual_mode) {
case Ctrl_V:
virtual_op = virtual_active();
- block_prep(&oparg, &bd, lnum, 0);
- virtual_op = MAYBE;
+ block_prep(&oparg, &bd, lnum, false);
+ virtual_op = kNone;
s = bd.textstart;
len = (long)bd.textlen;
break;
@@ -5292,15 +5437,16 @@ void cursor_pos_info(dict_T *dict)
if (lnum == curwin->w_cursor.lnum) {
word_count_cursor += word_count;
char_count_cursor += char_count;
- byte_count_cursor = byte_count +
- line_count_info(ml_get(lnum),
- &word_count_cursor, &char_count_cursor,
- (long)(curwin->w_cursor.col + 1), eol_size);
+ byte_count_cursor = byte_count
+ + line_count_info(ml_get(lnum), &word_count_cursor,
+ &char_count_cursor,
+ (varnumber_T)(curwin->w_cursor.col + 1),
+ eol_size);
}
}
- /* Add to the running totals */
- byte_count += line_count_info(ml_get(lnum), &word_count,
- &char_count, (long)MAXCOL, eol_size);
+ // Add to the running totals
+ byte_count += line_count_info(ml_get(lnum), &word_count, &char_count,
+ (varnumber_T)MAXCOL, eol_size);
}
// Correction for when last line doesn't have an EOL.
@@ -5389,17 +5535,19 @@ void cursor_pos_info(dict_T *dict)
if (dict != NULL) {
// Don't shorten this message, the user asked for it.
- dict_add_nr_str(dict, "words", word_count, NULL);
- dict_add_nr_str(dict, "chars", char_count, NULL);
- dict_add_nr_str(dict, "bytes", byte_count + bom_count, NULL);
-
- dict_add_nr_str(dict, l_VIsual_active ? "visual_bytes" : "cursor_bytes",
- byte_count_cursor, NULL);
- dict_add_nr_str(dict, l_VIsual_active ? "visual_chars" : "cursor_chars",
- char_count_cursor, NULL);
- dict_add_nr_str(dict, l_VIsual_active ? "visual_words" : "cursor_words",
- word_count_cursor, NULL);
- }
+ tv_dict_add_nr(dict, S_LEN("words"), (varnumber_T)word_count);
+ tv_dict_add_nr(dict, S_LEN("chars"), (varnumber_T)char_count);
+ tv_dict_add_nr(dict, S_LEN("bytes"), (varnumber_T)(byte_count + bom_count));
+
+ STATIC_ASSERT(sizeof("visual") == sizeof("cursor"),
+ "key_len argument in tv_dict_add_nr is wrong");
+ tv_dict_add_nr(dict, l_VIsual_active ? "visual_bytes" : "cursor_bytes",
+ sizeof("visual_bytes") - 1, (varnumber_T)byte_count_cursor);
+ tv_dict_add_nr(dict, l_VIsual_active ? "visual_chars" : "cursor_chars",
+ sizeof("visual_chars") - 1, (varnumber_T)char_count_cursor);
+ tv_dict_add_nr(dict, l_VIsual_active ? "visual_words" : "cursor_words",
+ sizeof("visual_words") - 1, (varnumber_T)word_count_cursor);
+ }
}
/// Check if the default register (used in an unnamed paste) should be a
@@ -5415,7 +5563,7 @@ int get_default_register_name(void)
}
/// Determine if register `*name` should be used as a clipboard.
-/// In an unnammed operation, `*name` is `NUL` and will be adjusted to `'*'/'+'` if
+/// In an unnamed operation, `*name` is `NUL` and will be adjusted to */+ if
/// `clipboard=unnamed[plus]` is set.
///
/// @param name The name of register, or `NUL` if unnamed.
@@ -5426,42 +5574,53 @@ int get_default_register_name(void)
/// if the register isn't a clipboard or provider isn't available.
static yankreg_T *adjust_clipboard_name(int *name, bool quiet, bool writing)
{
- if (*name == '*' || *name == '+') {
- if(!eval_has_provider("clipboard")) {
- if (!quiet) {
- EMSG("clipboard: provider is not available");
- }
- return NULL;
- }
- return &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER];
- } else if ((*name == NUL) && (cb_flags & CB_UNNAMEDMASK)) {
- if(!eval_has_provider("clipboard")) {
- if (!quiet && !clipboard_didwarn_unnamed) {
- msg((char_u*)"clipboard: provider not available, ignoring clipboard=unnamed[plus]");
- clipboard_didwarn_unnamed = true;
- }
- return NULL;
+#define MSG_NO_CLIP "clipboard: No provider. " \
+ "Try \":checkhealth\" or \":h clipboard\"."
+
+ yankreg_T *target = NULL;
+ bool explicit_cb_reg = (*name == '*' || *name == '+');
+ bool implicit_cb_reg = (*name == NUL) && (cb_flags & CB_UNNAMEDMASK);
+ if (!explicit_cb_reg && !implicit_cb_reg) {
+ goto end;
+ }
+
+ if (!eval_has_provider("clipboard")) {
+ if (batch_change_count == 1 && !quiet
+ && (!clipboard_didwarn || (explicit_cb_reg && !redirecting()))) {
+ clipboard_didwarn = true;
+ // Do NOT error (emsg()) here--if it interrupts :redir we get into
+ // a weird state, stuck in "redirect mode".
+ msg((char_u *)MSG_NO_CLIP);
}
+ // ... else, be silent (don't flood during :while, :redir, etc.).
+ goto end;
+ }
+
+ if (explicit_cb_reg) {
+ target = &y_regs[*name == '*' ? STAR_REGISTER : PLUS_REGISTER];
+ goto end;
+ } else { // unnamed register: "implicit" clipboard
if (writing && clipboard_delay_update) {
+ // For "set" (copy), defer the clipboard call.
clipboard_needs_update = true;
- return NULL;
+ goto end;
} else if (!writing && clipboard_needs_update) {
- // use the internal value
- return NULL;
+ // For "get" (paste), use the internal value.
+ goto end;
}
- yankreg_T *target;
if (cb_flags & CB_UNNAMEDPLUS) {
- *name = cb_flags & CB_UNNAMED ? '"': '+';
+ *name = (cb_flags & CB_UNNAMED && writing) ? '"': '+';
target = &y_regs[PLUS_REGISTER];
} else {
*name = '*';
target = &y_regs[STAR_REGISTER];
}
- return target; // unnamed register
+ goto end;
}
- // don't do anything for other register names
- return NULL;
+
+end:
+ return target;
}
static bool get_clipboard(int name, yankreg_T **target, bool quiet)
@@ -5475,9 +5634,9 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
}
free_register(reg);
- list_T *args = list_alloc();
- char_u regname = (char_u)name;
- list_append_string(args, &regname, 1);
+ list_T *const args = tv_list_alloc(1);
+ const char regname = (char)name;
+ tv_list_append_string(args, &regname, 1);
typval_T result = eval_call_provider("clipboard", "get", args);
@@ -5489,14 +5648,16 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
goto err;
}
- list_T *res = result.vval.v_list, *lines = NULL;
- if (res->lv_len == 2 && res->lv_first->li_tv.v_type == VAR_LIST) {
- lines = res->lv_first->li_tv.vval.v_list;
- if (res->lv_last->li_tv.v_type != VAR_STRING) {
+ list_T *res = result.vval.v_list;
+ list_T *lines = NULL;
+ if (tv_list_len(res) == 2
+ && TV_LIST_ITEM_TV(tv_list_first(res))->v_type == VAR_LIST) {
+ lines = TV_LIST_ITEM_TV(tv_list_first(res))->vval.v_list;
+ if (TV_LIST_ITEM_TV(tv_list_last(res))->v_type != VAR_STRING) {
goto err;
}
- char_u *regtype = res->lv_last->li_tv.vval.v_string;
- if (regtype == NULL || strlen((char*)regtype) > 1) {
+ char_u *regtype = TV_LIST_ITEM_TV(tv_list_last(res))->vval.v_string;
+ if (regtype == NULL || strlen((char *)regtype) > 1) {
goto err;
}
switch (regtype[0]) {
@@ -5521,20 +5682,21 @@ static bool get_clipboard(int name, yankreg_T **target, bool quiet)
reg->y_type = kMTUnknown;
}
- reg->y_array = xcalloc((size_t)lines->lv_len, sizeof(uint8_t *));
- reg->y_size = (size_t)lines->lv_len;
+ reg->y_array = xcalloc((size_t)tv_list_len(lines), sizeof(char_u *));
+ reg->y_size = (size_t)tv_list_len(lines);
reg->additional_data = NULL;
reg->timestamp = 0;
// Timestamp is not saved for clipboard registers because clipboard registers
// are not saved in the ShaDa file.
- int i = 0;
- for (listitem_T *li = lines->lv_first; li != NULL; li = li->li_next) {
- if (li->li_tv.v_type != VAR_STRING) {
+ size_t tv_idx = 0;
+ TV_LIST_ITER_CONST(lines, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type != VAR_STRING) {
goto err;
}
- reg->y_array[i++] = (uint8_t *)xstrdup((char *)li->li_tv.vval.v_string);
- }
+ reg->y_array[tv_idx++] = (char_u *)xstrdupnul(
+ (const char *)TV_LIST_ITEM_TV(li)->vval.v_string);
+ });
if (reg->y_size > 0 && strlen((char*)reg->y_array[reg->y_size-1]) == 0) {
// a known-to-be charwise yank might have a final linebreak
@@ -5591,63 +5753,91 @@ static void set_clipboard(int name, yankreg_T *reg)
return;
}
- list_T *lines = list_alloc();
+ list_T *const lines = tv_list_alloc(
+ (ptrdiff_t)reg->y_size + (reg->y_type != kMTCharWise));
for (size_t i = 0; i < reg->y_size; i++) {
- list_append_string(lines, reg->y_array[i], -1);
+ tv_list_append_string(lines, (const char *)reg->y_array[i], -1);
}
- list_T *args = list_alloc();
- list_append_list(args, lines);
-
- char_u regtype;
+ char regtype;
switch (reg->y_type) {
- case kMTLineWise:
- regtype = 'V';
- list_append_string(lines, (char_u*)"", 0);
- break;
- case kMTCharWise:
- regtype = 'v';
- break;
- case kMTBlockWise:
- regtype = 'b';
- list_append_string(lines, (char_u*)"", 0);
- break;
- case kMTUnknown:
- assert(false);
- }
- list_append_string(args, &regtype, 1);
-
- char_u regname = (char_u)name;
- list_append_string(args, &regname, 1);
+ case kMTLineWise: {
+ regtype = 'V';
+ tv_list_append_string(lines, NULL, 0);
+ break;
+ }
+ case kMTCharWise: {
+ regtype = 'v';
+ break;
+ }
+ case kMTBlockWise: {
+ regtype = 'b';
+ tv_list_append_string(lines, NULL, 0);
+ break;
+ }
+ case kMTUnknown: {
+ assert(false);
+ }
+ }
+
+ list_T *args = tv_list_alloc(3);
+ tv_list_append_list(args, lines);
+ tv_list_append_string(args, &regtype, 1); // -V614
+ tv_list_append_string(args, ((char[]) { (char)name }), 1);
(void)eval_call_provider("clipboard", "set", args);
}
-/// Avoid clipboard (slow) during batch operations (:global).
-void start_global_changes(void)
+/// Avoid slow things (clipboard) during batch operations (while/for-loops).
+void start_batch_changes(void)
{
- if (++global_change_count > 1) {
+ if (++batch_change_count > 1) {
return;
}
clipboard_delay_update = true;
- clipboard_needs_update = false;
}
-/// Update the clipboard after :global changes finished.
-void end_global_changes(void)
+/// Counterpart to start_batch_changes().
+void end_batch_changes(void)
{
- if (--global_change_count > 0) {
+ if (--batch_change_count > 0) {
// recursive
return;
}
clipboard_delay_update = false;
if (clipboard_needs_update) {
+ // must be before, as set_clipboard will invoke
+ // start/end_batch_changes recursively
+ clipboard_needs_update = false;
+ // unnamed ("implicit" clipboard)
set_clipboard(NUL, y_previous);
+ }
+}
+
+int save_batch_count(void)
+{
+ int save_count = batch_change_count;
+ batch_change_count = 0;
+ clipboard_delay_update = false;
+ if (clipboard_needs_update) {
clipboard_needs_update = false;
+ // unnamed ("implicit" clipboard)
+ set_clipboard(NUL, y_previous);
}
+ return save_count;
}
+void restore_batch_count(int save_count)
+{
+ assert(batch_change_count == 0);
+ batch_change_count = save_count;
+ if (batch_change_count > 0) {
+ clipboard_delay_update = true;
+ }
+}
+
+
/// Check whether register is empty
static inline bool reg_empty(const yankreg_T *const reg)
FUNC_ATTR_PURE
@@ -5668,7 +5858,7 @@ static inline bool reg_empty(const yankreg_T *const reg)
/// @return Pointer that needs to be passed to next `op_register_iter` call or
/// NULL if iteration is over.
const void *op_register_iter(const void *const iter, char *const name,
- yankreg_T *const reg)
+ yankreg_T *const reg, bool *is_unnamed)
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
*name = NUL;
@@ -5684,6 +5874,7 @@ const void *op_register_iter(const void *const iter, char *const name,
int iter_off = (int)(iter_reg - &(y_regs[0]));
*name = (char)get_register_name(iter_off);
*reg = *iter_reg;
+ *is_unnamed = (iter_reg == y_previous);
while (++iter_reg - &(y_regs[0]) < NUM_SAVED_REGISTERS) {
if (!reg_empty(iter_reg)) {
return (void *) iter_reg;
@@ -5708,10 +5899,11 @@ size_t op_register_amount(void)
/// Set register to a given value
///
/// @param[in] name Register name.
-/// @param[in] reg Register value.
+/// @param[in] reg Register value.
+/// @param[in] is_unnamed Whether to set the unnamed regiseter to reg
///
/// @return true on success, false on failure.
-bool op_register_set(const char name, const yankreg_T reg)
+bool op_register_set(const char name, const yankreg_T reg, bool is_unnamed)
{
int i = op_reg_index(name);
if (i == -1) {
@@ -5719,6 +5911,10 @@ bool op_register_set(const char name, const yankreg_T reg)
}
free_register(&y_regs[i]);
y_regs[i] = reg;
+
+ if (is_unnamed) {
+ y_previous = &y_regs[i];
+ }
return true;
}
@@ -5735,3 +5931,20 @@ const yankreg_T *op_register_get(const char name)
}
return &y_regs[i];
}
+
+/// Set the previous yank register
+///
+/// @param[in] name Register name.
+///
+/// @return true on success, false on failure.
+bool op_register_set_previous(const char name)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int i = op_reg_index(name);
+ if (i == -1) {
+ return false;
+ }
+
+ y_previous = &y_regs[i];
+ return true;
+}
diff --git a/src/nvim/ops.h b/src/nvim/ops.h
index 44df2e9e0c..a8867e02ea 100644
--- a/src/nvim/ops.h
+++ b/src/nvim/ops.h
@@ -6,8 +6,10 @@
#include "nvim/macros.h"
#include "nvim/ascii.h"
#include "nvim/types.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/os/time.h"
+#include "nvim/normal.h" // for MotionType and oparg_T
+#include "nvim/ex_cmds_defs.h" // for exarg_T
typedef int (*Indenter)(void);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 5333c0291d..b8f5957c09 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1,24 +1,25 @@
-/*
- * Code to handle user-settable options. This is all pretty much table-
- * driven. Checklist for adding a new option:
- * - Put it in the options array below (copy an existing entry).
- * - For a global option: Add a variable for it in option_defs.h.
- * - For a buffer or window local option:
- * - Add a PV_XX entry to the enum below.
- * - Add a variable to the window or buffer struct in buffer_defs.h.
- * - For a window option, add some code to copy_winopt().
- * - For a buffer option, add some code to buf_copy_options().
- * - For a buffer string option, add code to check_buf_options().
- * - If it's a numeric option, add any necessary bounds checks to do_set().
- * - If it's a list of flags, add some code in do_set(), search for WW_ALL.
- * - When adding an option with expansion (P_EXPAND), but with a different
- * default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP.
- * - Add documentation! One line in doc/help.txt, full description in
- * options.txt, and any other related places.
- * - Add an entry in runtime/optwin.vim.
- * When making changes:
- * - Adjust the help for the option in doc/option.txt.
- */
+// 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
+
+// User-settable options. Checklist for adding a new option:
+// - Put it in options.lua
+// - For a global option: Add a variable for it in option_defs.h.
+// - For a buffer or window local option:
+// - Add a BV_XX or WV_XX entry to option_defs.h
+// - Add a variable to the window or buffer struct in buffer_defs.h.
+// - For a window option, add some code to copy_winopt().
+// - For a window string option, add code to check_winopt()
+// and clear_winopt(). If setting the option needs parsing,
+// add some code to didset_window_options().
+// - For a buffer option, add some code to buf_copy_options().
+// - For a buffer string option, add code to check_buf_options().
+// - If it's a numeric option, add any necessary bounds checks to
+// set_num_option().
+// - If it's a list of flags, add some code in do_set(), search for WW_ALL.
+// - When adding an option with expansion (P_EXPAND), but with a different
+// default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP.
+// - Add documentation! doc/options.txt, and any other related places.
+// - Add an entry in runtime/optwin.vim.
#define IN_OPTION_C
#include <assert.h>
@@ -31,6 +32,7 @@
#include <limits.h>
#include "nvim/vim.h"
+#include "nvim/macros.h"
#include "nvim/ascii.h"
#include "nvim/edit.h"
#include "nvim/option.h"
@@ -40,6 +42,7 @@
#include "nvim/diff.h"
#include "nvim/digraph.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
@@ -65,13 +68,16 @@
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/spell.h"
+#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/window.h"
#include "nvim/os/os.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/os/input.h"
+#include "nvim/os/lang.h"
/*
* The options that are local to a window or buffer have "indir" set to one of
@@ -102,6 +108,9 @@ typedef enum {
*/
#define VAR_WIN ((char_u *)-1)
+static char *p_term = NULL;
+static char *p_ttytype = NULL;
+
/*
* These are the global values for options which are also local to a buffer.
* Only to be used in option.c!
@@ -112,6 +121,7 @@ static int p_bomb;
static char_u *p_bh;
static char_u *p_bt;
static int p_bl;
+static long p_channel;
static int p_ci;
static int p_cin;
static char_u *p_cink;
@@ -177,16 +187,16 @@ static long p_tw_nopaste;
static long p_wm_nopaste;
typedef struct vimoption {
- char *fullname; /* full option name */
- char *shortname; /* permissible abbreviation */
- uint32_t flags; /* see below */
- char_u *var; /* global option: pointer to variable;
- * window-local option: VAR_WIN;
- * buffer-local option: global value */
- idopt_T indir; /* global option: PV_NONE;
- * local option: indirect option index */
- char_u *def_val[2]; /* default values for variable (vi and vim) */
- scid_T scriptID; /* script in which the option was last set */
+ char *fullname; // full option name
+ char *shortname; // permissible abbreviation
+ uint32_t flags; // see below
+ char_u *var; // global option: pointer to variable;
+ // window-local option: VAR_WIN;
+ // buffer-local option: global value
+ idopt_T indir; // global option: PV_NONE;
+ // local option: indirect option index
+ char_u *def_val[2]; // default values for variable (vi and vim)
+ LastSet last_set; // script in which the option was last set
# define SCRIPTID_INIT , 0
} vimoption_T;
@@ -213,12 +223,12 @@ typedef struct vimoption {
#define P_VI_DEF 0x400U /* Use Vi default for Vim */
#define P_VIM 0x800U /* Vim option */
-/* when option changed, what to display: */
-#define P_RSTAT 0x1000U /* redraw status lines */
-#define P_RWIN 0x2000U /* redraw current window */
-#define P_RBUF 0x4000U /* redraw current buffer */
-#define P_RALL 0x6000U /* redraw all windows */
-#define P_RCLR 0x7000U /* clear and redraw all */
+// when option changed, what to display:
+#define P_RSTAT 0x1000U ///< redraw status lines
+#define P_RWIN 0x2000U ///< redraw current window and recompute text
+#define P_RBUF 0x4000U ///< redraw current buffer and recompute text
+#define P_RALL 0x6000U ///< redraw all windows
+#define P_RCLR 0x7000U ///< clear and redraw all
#define P_COMMA 0x8000U ///< comma separated list
#define P_ONECOMMA 0x18000U ///< P_COMMA and cannot have two consecutive
@@ -236,16 +246,22 @@ typedef struct vimoption {
#define P_NO_ML 0x2000000U ///< not allowed in modeline
#define P_CURSWANT 0x4000000U ///< update curswant required; not needed
///< when there is a redraw flag
+#define P_NO_DEF_EXP 0x8000000U ///< Do not expand default value.
+
+#define P_RWINONLY 0x10000000U ///< only redraw current window
+#define P_NDNAME 0x20000000U ///< only normal dir name chars allowed
+#define P_UI_OPTION 0x40000000U ///< send option to remote ui
#define HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \
"d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr," \
"N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title," \
- "v:Visual,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
+ "v:Visual,V:VisualNOS,w:WarningMsg,W:WildMenu,f:Folded,F:FoldColumn," \
"A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn,-:Conceal," \
"B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel," \
"x:PmenuSbar,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill," \
- "!:CursorColumn,.:CursorLine,o:ColorColumn"
+ "!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine," \
+ "0:Whitespace,I:NormalNC"
/*
* options[] is initialized here.
@@ -287,6 +303,8 @@ static char *(p_fdm_values[]) = { "manual", "expr", "marker", "indent",
static char *(p_fcl_values[]) = { "all", NULL };
static char *(p_cot_values[]) = { "menu", "menuone", "longest", "preview",
"noinsert", "noselect", NULL };
+static char *(p_icm_values[]) = { "nosplit", "split", NULL };
+static char *(p_scl_values[]) = { "yes", "no", "auto", NULL };
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "option.c.generated.h"
@@ -332,7 +350,7 @@ static inline size_t compute_double_colon_len(const char *const val,
do {
size_t dir_len;
const char *dir;
- iter = vim_colon_env_iter(val, iter, &dir, &dir_len);
+ iter = vim_env_iter(':', val, iter, &dir, &dir_len);
if (dir != NULL && dir_len > 0) {
ret += ((dir_len + memcnt(dir, ',', dir_len) + common_suf_len
+ !after_pathsep(dir, dir + dir_len)) * 2
@@ -376,8 +394,8 @@ static inline char *add_colon_dirs(char *dest, const char *const val,
do {
size_t dir_len;
const char *dir;
- iter = (forward ? vim_colon_env_iter : vim_colon_env_iter_rev)(
- val, iter, &dir, &dir_len);
+ iter = (forward ? vim_env_iter : vim_env_iter_rev)(':', val, iter, &dir,
+ &dir_len);
if (dir != NULL && dir_len > 0) {
dest = strcpy_comma_escaped(dest, dir, dir_len);
if (!after_pathsep(dest - 1, dest)) {
@@ -520,6 +538,8 @@ static void set_runtimepath_default(void)
#undef SITE_SIZE
#undef AFTER_SIZE
set_string_default("runtimepath", rtp, true);
+ // Make a copy of 'rtp' for 'packpath'
+ set_string_default("packpath", rtp, false);
xfree(data_dirs);
xfree(config_dirs);
xfree(data_home);
@@ -599,27 +619,6 @@ void set_init_1(void)
}
}
- /*
- * 'maxmemtot' and 'maxmem' may have to be adjusted for available memory
- */
- opt_idx = findoption((char_u *)"maxmemtot");
- if (opt_idx >= 0) {
- {
- /* Use half of amount of memory available to Vim. */
- /* If too much to fit in uintptr_t, get uintptr_t max */
- uint64_t available_kib = os_get_total_mem_kib();
- uintptr_t n = available_kib / 2 > UINTPTR_MAX
- ? UINTPTR_MAX
- : (uintptr_t)(available_kib /2);
- options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
- opt_idx = findoption((char_u *)"maxmem");
- if (opt_idx >= 0) {
- options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
- }
- }
- }
-
-
{
char_u *cdpath;
char_u *buf;
@@ -643,7 +642,7 @@ void set_init_1(void)
}
}
buf[j] = NUL;
- opt_idx = findoption((char_u *)"cdpath");
+ opt_idx = findoption("cdpath");
if (opt_idx >= 0) {
options[opt_idx].def_val[VI_DEFAULT] = buf;
options[opt_idx].flags |= P_DEF_ALLOCED;
@@ -676,15 +675,18 @@ void set_init_1(void)
#endif
false);
- char *backupdir = stdpaths_user_data_subpath("backup", 0);
+ char *backupdir = stdpaths_user_data_subpath("backup", 0, true);
const size_t backupdir_len = strlen(backupdir);
backupdir = xrealloc(backupdir, backupdir_len + 3);
memmove(backupdir + 2, backupdir, backupdir_len + 1);
memmove(backupdir, ".,", 2);
- set_string_default("viewdir", stdpaths_user_data_subpath("view", 0), true);
+ set_string_default("viewdir", stdpaths_user_data_subpath("view", 0, true),
+ true);
set_string_default("backupdir", backupdir, true);
- set_string_default("directory", stdpaths_user_data_subpath("swap", 2), true);
- set_string_default("undodir", stdpaths_user_data_subpath("undo", 0), true);
+ set_string_default("directory", stdpaths_user_data_subpath("swap", 2, true),
+ true);
+ set_string_default("undodir", stdpaths_user_data_subpath("undo", 0, true),
+ true);
// Set default for &runtimepath. All necessary expansions are performed in
// this function.
set_runtimepath_default();
@@ -726,6 +728,9 @@ void set_init_1(void)
* default.
*/
for (opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
+ if (options[opt_idx].flags & P_NO_DEF_EXP) {
+ continue;
+ }
char *p;
if ((options[opt_idx].flags & P_GETTEXT)
&& options[opt_idx].var != NULL) {
@@ -756,29 +761,29 @@ void set_init_1(void)
* NOTE: mlterm's author is being asked to 'set' a variable
* instead of an environment variable due to inheritance.
*/
- if (os_env_exists("MLTERM"))
- set_option_value((char_u *)"tbidi", 1L, NULL, 0);
+ if (os_env_exists("MLTERM")) {
+ set_option_value("tbidi", 1L, NULL, 0);
+ }
didset_options2();
+ lang_init();
+
// enc_locale() will try to find the encoding of the current locale.
// This will be used when 'default' is used as encoding specifier
// in 'fileencodings'
char_u *p = enc_locale();
if (p == NULL) {
// use utf-8 as 'default' if locale encoding can't be detected.
- p = vim_strsave((char_u *)"utf-8");
+ p = (char_u *)xmemdupz(S_LEN("utf-8"));
}
fenc_default = p;
- // Initialize multibyte (utf-8) handling
- mb_init();
-
- // Don't change &encoding when resetting to defaults with ":set all&".
- opt_idx = findoption((char_u *)"encoding");
- if (opt_idx >= 0) {
- options[opt_idx].flags |= P_NODEFAULT;
- }
+#ifdef HAVE_WORKING_LIBINTL
+ // GNU gettext 0.10.37 supports this feature: set the codeset used for
+ // translated messages independently from the current locale.
+ (void)bind_textdomain_codeset(PROJECT_NAME, (char *)p_enc);
+#endif
/* Set the default for 'helplang'. */
set_helplang_default(get_mess_lang());
@@ -806,24 +811,26 @@ set_option_default (
if (flags & P_STRING) {
/* Use set_string_option_direct() for local options to handle
* freeing and allocating the value. */
- if (options[opt_idx].indir != PV_NONE)
+ if (options[opt_idx].indir != PV_NONE) {
set_string_option_direct(NULL, opt_idx,
- options[opt_idx].def_val[dvi], opt_flags, 0);
- else {
- if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED))
+ options[opt_idx].def_val[dvi], opt_flags, 0);
+ } else {
+ if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED)) {
free_string_option(*(char_u **)(varp));
+ }
*(char_u **)varp = options[opt_idx].def_val[dvi];
options[opt_idx].flags &= ~P_ALLOCED;
}
} else if (flags & P_NUM) {
- if (options[opt_idx].indir == PV_SCROLL)
+ if (options[opt_idx].indir == PV_SCROLL) {
win_comp_scroll(curwin);
- else {
- *(long *)varp = (long)options[opt_idx].def_val[dvi];
- /* May also set global value for local option. */
- if (both)
+ } else {
+ *(long *)varp = (long)(intptr_t)options[opt_idx].def_val[dvi];
+ // May also set global value for local option.
+ if (both) {
*(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) =
*(long *)varp;
+ }
}
} else { /* P_BOOL */
*(int *)varp = (int)(intptr_t)options[opt_idx].def_val[dvi];
@@ -877,7 +884,7 @@ set_options_default (
void set_string_default(const char *name, char *val, bool allocated)
FUNC_ATTR_NONNULL_ALL
{
- int opt_idx = findoption((char_u *)name);
+ int opt_idx = findoption(name);
if (opt_idx >= 0) {
if (options[opt_idx].flags & P_DEF_ALLOCED) {
xfree(options[opt_idx].def_val[VI_DEFAULT]);
@@ -899,63 +906,57 @@ void set_number_default(char *name, long val)
{
int opt_idx;
- opt_idx = findoption((char_u *)name);
- if (opt_idx >= 0)
- options[opt_idx].def_val[VI_DEFAULT] = (char_u *)val;
+ opt_idx = findoption(name);
+ if (opt_idx >= 0) {
+ options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(intptr_t)val;
+ }
}
#if defined(EXITFREE)
-/*
- * Free all options.
- */
+/// Free all options.
void free_all_options(void)
{
- int i;
-
- for (i = 0; options[i].fullname; i++) {
+ for (int i = 0; options[i].fullname; i++) {
if (options[i].indir == PV_NONE) {
- /* global option: free value and default value. */
- if (options[i].flags & P_ALLOCED && options[i].var != NULL)
+ // global option: free value and default value.
+ if ((options[i].flags & P_ALLOCED) && options[i].var != NULL) {
free_string_option(*(char_u **)options[i].var);
- if (options[i].flags & P_DEF_ALLOCED)
+ }
+ if (options[i].flags & P_DEF_ALLOCED) {
free_string_option(options[i].def_val[VI_DEFAULT]);
- } else if (options[i].var != VAR_WIN
- && (options[i].flags & P_STRING))
- /* buffer-local option: free global value */
+ }
+ } else if (options[i].var != VAR_WIN && (options[i].flags & P_STRING)) {
+ // buffer-local option: free global value
free_string_option(*(char_u **)options[i].var);
+ }
}
}
-
#endif
-/*
- * Initialize the options, part two: After getting Rows and Columns and
- * setting 'term'.
- */
-void set_init_2(void)
+/// Initialize the options, part two: After getting Rows and Columns.
+void set_init_2(bool headless)
{
int idx;
- /*
- * 'scroll' defaults to half the window height. Note that this default is
- * wrong when the window height changes.
- */
- set_number_default("scroll", Rows / 2);
- idx = findoption((char_u *)"scroll");
- if (idx >= 0 && !(options[idx].flags & P_WAS_SET))
+ // 'scroll' defaults to half the window height. The stored default is zero,
+ // which results in the actual value computed from the window height.
+ idx = findoption("scroll");
+ if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
set_option_default(idx, OPT_LOCAL, p_cp);
+ }
comp_col();
/*
* 'window' is only for backwards compatibility with Vi.
* Default is Rows - 1.
*/
- if (!option_was_set((char_u *)"window"))
+ if (!option_was_set("window")) {
p_window = Rows - 1;
+ }
set_number_default("window", Rows - 1);
- parse_shape_opt(SHAPE_CURSOR); /* set cursor shapes from 'guicursor' */
- (void)parse_printoptions(); /* parse 'printoptions' default value */
+ parse_shape_opt(SHAPE_CURSOR); // set cursor shapes from 'guicursor'
+ (void)parse_printoptions(); // parse 'printoptions' default value
}
/*
@@ -971,16 +972,18 @@ void set_init_3(void)
int idx_sp;
int do_sp;
- idx_srr = findoption((char_u *)"srr");
- if (idx_srr < 0)
- do_srr = FALSE;
- else
+ idx_srr = findoption("srr");
+ if (idx_srr < 0) {
+ do_srr = false;
+ } else {
do_srr = !(options[idx_srr].flags & P_WAS_SET);
- idx_sp = findoption((char_u *)"sp");
- if (idx_sp < 0)
- do_sp = FALSE;
- else
+ }
+ idx_sp = findoption("sp");
+ if (idx_sp < 0) {
+ do_sp = false;
+ } else {
do_sp = !(options[idx_sp].flags & P_WAS_SET);
+ }
size_t len = 0;
char_u *p = (char_u *)invocation_path_tail(p_sh, &len);
@@ -1023,6 +1026,15 @@ void set_init_3(void)
xfree(p);
}
+ if (BUFEMPTY()) {
+ int idx_ffs = findoption_len(S_LEN("ffs"));
+
+ // Apply the first entry of 'fileformats' to the initial buffer.
+ if (idx_ffs >= 0 && (options[idx_ffs].flags & P_WAS_SET)) {
+ set_fileformat(default_fileformat(), OPT_LOCAL);
+ }
+ }
+
set_title_defaults();
}
@@ -1032,19 +1044,27 @@ void set_init_3(void)
*/
void set_helplang_default(const char *lang)
{
- int idx;
+ if (lang == NULL) {
+ return;
+ }
- if (lang == NULL || STRLEN(lang) < 2) /* safety check */
+ const size_t lang_len = strlen(lang);
+ if (lang_len < 2) { // safety check
return;
- idx = findoption((char_u *)"hlg");
+ }
+ int idx = findoption("hlg");
if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
if (options[idx].flags & P_ALLOCED)
free_string_option(p_hlg);
- p_hlg = (char_u *)xstrdup(lang);
- /* zh_CN becomes "cn", zh_TW becomes "tw". */
+ p_hlg = (char_u *)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') {
+ // any C like setting, such as C.UTF-8, becomes "en"
+ p_hlg[0] = 'e';
+ p_hlg[1] = 'n';
}
p_hlg[2] = NUL;
options[idx].flags |= P_ALLOCED;
@@ -1068,12 +1088,12 @@ void set_title_defaults(void)
* icon name. Saves a bit of time, because the X11 display server does
* not need to be contacted.
*/
- idx1 = findoption((char_u *)"title");
+ idx1 = findoption("title");
if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
options[idx1].def_val[VI_DEFAULT] = (char_u *)(intptr_t)0;
p_title = 0;
}
- idx1 = findoption((char_u *)"icon");
+ idx1 = findoption("icon");
if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) {
options[idx1].def_val[VI_DEFAULT] = (char_u *)(intptr_t)0;
p_icon = 0;
@@ -1110,7 +1130,7 @@ do_set (
int afterchar; /* character just after option name */
int len;
int i;
- long value;
+ varnumber_T value;
int key;
uint32_t flags; /* flags for current option */
char_u *varp = NULL; /* pointer to variable for current option */
@@ -1143,15 +1163,12 @@ do_set (
set_options_default(OPT_FREE | opt_flags);
didset_options();
didset_options2();
+ ui_refresh_options();
redraw_all_later(CLEAR);
} else {
showoptions(1, opt_flags);
did_show = TRUE;
}
- } else if (STRNCMP(arg, "termcap",
- 7) == 0 && !(opt_flags & OPT_MODELINE)) {
- did_show = TRUE;
- arg += 7;
} else {
prefix = 1;
if (STRNCMP(arg, "no", 2) == 0) {
@@ -1179,7 +1196,7 @@ do_set (
goto skip;
}
if (arg[1] == 't' && arg[2] == '_') { // could be term code
- opt_idx = findoption_len(arg + 1, (size_t) (len - 1));
+ opt_idx = findoption_len((const char *)arg + 1, (size_t)(len - 1));
}
len++;
if (opt_idx == -1) {
@@ -1195,7 +1212,7 @@ do_set (
len++;
}
}
- opt_idx = findoption_len(arg, (size_t) len);
+ opt_idx = findoption_len((const char *)arg, (size_t)len);
if (opt_idx == -1) {
key = find_key_option(arg);
}
@@ -1319,15 +1336,16 @@ do_set (
if (opt_idx >= 0) {
showoneopt(&options[opt_idx], opt_flags);
if (p_verbose > 0) {
- /* Mention where the option was last set. */
- if (varp == options[opt_idx].var)
- last_set_msg(options[opt_idx].scriptID);
- else if ((int)options[opt_idx].indir & PV_WIN)
- last_set_msg(curwin->w_p_scriptID[
- (int)options[opt_idx].indir & PV_MASK]);
- else if ((int)options[opt_idx].indir & PV_BUF)
- last_set_msg(curbuf->b_p_scriptID[
- (int)options[opt_idx].indir & PV_MASK]);
+ // Mention where the option was last set.
+ if (varp == options[opt_idx].var) {
+ option_last_set_msg(options[opt_idx].last_set);
+ } else if ((int)options[opt_idx].indir & PV_WIN) {
+ option_last_set_msg(curwin->w_p_scriptID[
+ (int)options[opt_idx].indir & PV_MASK]);
+ } else if ((int)options[opt_idx].indir & PV_BUF) {
+ option_last_set_msg(curbuf->b_p_scriptID[
+ (int)options[opt_idx].indir & PV_MASK]);
+ }
}
} else {
errmsg = (char_u *)N_("E846: Key code not set");
@@ -1377,10 +1395,10 @@ do_set (
value = prefix;
}
- errmsg = set_bool_option(opt_idx, varp, (int)value,
- opt_flags);
- } else { /* numeric or string */
- if (vim_strchr((char_u *)"=:&<", nextchar) == NULL
+ errmsg = (char_u *)set_bool_option(opt_idx, varp, (int)value,
+ opt_flags);
+ } else { // Numeric or string.
+ if (vim_strchr((const char_u *)"=:&<", nextchar) == NULL
|| prefix != 1) {
errmsg = e_invarg;
goto skip;
@@ -1396,25 +1414,24 @@ do_set (
* [-]0-9 set number
* other error
*/
- ++arg;
- if (nextchar == '&')
- value = (long)options[opt_idx].def_val[
- ((flags & P_VI_DEF) || cp_val)
- ? VI_DEFAULT : VIM_DEFAULT];
- else if (nextchar == '<') {
- /* For 'undolevels' NO_LOCAL_UNDOLEVEL means to
- * use the global value. */
- if ((long *)varp == &curbuf->b_p_ul
- && opt_flags == OPT_LOCAL)
+ arg++;
+ if (nextchar == '&') {
+ value = (long)(intptr_t)options[opt_idx].def_val[
+ ((flags & P_VI_DEF) || cp_val) ? VI_DEFAULT : VIM_DEFAULT];
+ } else if (nextchar == '<') {
+ // For 'undolevels' NO_LOCAL_UNDOLEVEL means to
+ // use the global value.
+ if ((long *)varp == &curbuf->b_p_ul && opt_flags == OPT_LOCAL) {
value = NO_LOCAL_UNDOLEVEL;
- else
+ } else {
value = *(long *)get_varp_scope(
&(options[opt_idx]), OPT_GLOBAL);
+ }
} else if (((long *)varp == &p_wc
|| (long *)varp == &p_wcm)
&& (*arg == '<'
|| *arg == '^'
- || ((!arg[1] || ascii_iswhite(arg[1]))
+ || (*arg != NUL && (!arg[1] || ascii_iswhite(arg[1]))
&& !ascii_isdigit(*arg)))) {
value = string_to_key(arg);
if (value == 0 && (long *)varp != &p_wcm) {
@@ -1422,8 +1439,7 @@ do_set (
goto skip;
}
} else if (*arg == '-' || ascii_isdigit(*arg)) {
- // Allow negative (for 'undolevels'), octal and
- // hex numbers.
+ // Allow negative, octal and hex numbers.
vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0);
if (arg[i] != NUL && !ascii_iswhite(arg[i])) {
errmsg = e_invarg;
@@ -1434,21 +1450,26 @@ do_set (
goto skip;
}
- if (adding)
+ if (adding) {
value = *(long *)varp + value;
- if (prepending)
+ }
+ if (prepending) {
value = *(long *)varp * value;
- if (removing)
+ }
+ if (removing) {
value = *(long *)varp - value;
- errmsg = set_num_option(opt_idx, varp, value,
- errbuf, sizeof(errbuf), opt_flags);
- } else if (opt_idx >= 0) { /* string */
+ }
+ errmsg = (char_u *)set_num_option(opt_idx, varp, (long)value,
+ errbuf, sizeof(errbuf),
+ opt_flags);
+ } else if (opt_idx >= 0) { // String.
char_u *save_arg = NULL;
char_u *s = NULL;
char_u *oldval = NULL; // previous value if *varp
char_u *newval;
char_u *origval = NULL;
char *saved_origval = NULL;
+ char *saved_newval = NULL;
unsigned newlen;
int comma;
int bs;
@@ -1465,7 +1486,17 @@ do_set (
/* The old value is kept until we are sure that the
* new value is valid. */
oldval = *(char_u **)varp;
- if (nextchar == '&') { /* set to default val */
+
+ // When setting the local value of a global
+ // option, the old value may be the global value.
+ if (((int)options[opt_idx].indir & PV_BOTH) && (opt_flags
+ & OPT_LOCAL)) {
+ origval = *(char_u **)get_varp(&options[opt_idx]);
+ } else {
+ origval = oldval;
+ }
+
+ if (nextchar == '&') { // set to default val
newval = options[opt_idx].def_val[
((flags & P_VI_DEF) || cp_val)
? VI_DEFAULT : VIM_DEFAULT];
@@ -1473,16 +1504,19 @@ do_set (
* default value was already expanded, only
* required when an environment variable was set
* later */
- if (newval == NULL)
+ new_value_alloced = true;
+ if (newval == NULL) {
newval = empty_option;
- else {
+ } else if (!(options[opt_idx].flags & P_NO_DEF_EXP)) {
s = option_expand(opt_idx, newval);
- if (s == NULL)
+ if (s == NULL) {
s = newval;
+ }
newval = vim_strsave(s);
+ } else {
+ newval = (char_u *)xstrdup((char *)newval);
}
- new_value_alloced = TRUE;
- } else if (nextchar == '<') { /* set to global val */
+ } else if (nextchar == '<') { // set to global val
newval = vim_strsave(*(char_u **)get_varp_scope(
&(options[opt_idx]), OPT_GLOBAL));
new_value_alloced = TRUE;
@@ -1521,6 +1555,9 @@ do_set (
break;
}
xfree(oldval);
+ if (origval == oldval) {
+ origval = *(char_u **)varp;
+ }
oldval = *(char_u **)varp;
}
/*
@@ -1557,15 +1594,6 @@ do_set (
++arg;
}
- /* When setting the local value of a global
- * option, the old value may be the global value. */
- if (((int)options[opt_idx].indir & PV_BOTH)
- && (opt_flags & OPT_LOCAL))
- origval = *(char_u **)get_varp(
- &options[opt_idx]);
- else
- origval = oldval;
-
/*
* Copy the new string into allocated memory.
* Can't use set_string_option_direct(), because
@@ -1708,13 +1736,26 @@ do_set (
}
if (flags & P_FLAGLIST) {
- /* Remove flags that appear twice. */
- for (s = newval; *s; ++s)
- if ((!(flags & P_COMMA) || *s != ',')
- && vim_strchr(s + 1, *s) != NULL) {
- STRMOVE(s, s + 1);
- --s;
+ // Remove flags that appear twice.
+ for (s = newval; *s;) {
+ // if options have P_FLAGLIST and P_ONECOMMA such as
+ // 'whichwrap'
+ if (flags & P_ONECOMMA) {
+ if (*s != ',' && *(s + 1) == ','
+ && vim_strchr(s + 2, *s) != NULL) {
+ // Remove the duplicated value and the next comma.
+ STRMOVE(s, s + 2);
+ continue;
+ }
+ } else {
+ if ((!(flags & P_COMMA) || *s != ',')
+ && vim_strchr(s + 1, *s) != NULL) {
+ STRMOVE(s, s + 1);
+ continue;
+ }
}
+ s++;
+ }
}
if (save_arg != NULL) /* number for 'whichwrap' */
@@ -1722,39 +1763,42 @@ do_set (
new_value_alloced = TRUE;
}
- /* Set the new value. */
+ // Set the new value.
*(char_u **)(varp) = newval;
- if (!starting && origval != NULL) {
- // origval may be freed by
- // did_set_string_option(), make a copy.
- saved_origval = xstrdup((char *) origval);
- }
+ // origval may be freed by
+ // did_set_string_option(), make a copy.
+ saved_origval = (origval != NULL) ? xstrdup((char *)origval) : 0;
- /* Handle side effects, and set the global value for
- * ":set" on local options. */
+ // newval (and varp) may become invalid if the
+ // buffer is closed by autocommands.
+ saved_newval = (newval != NULL) ? xstrdup((char *)newval) : 0;
+
+ // Handle side effects, and set the global value for
+ // ":set" on local options. Note: when setting 'syntax'
+ // or 'filetype' autocommands may be triggered that can
+ // cause havoc.
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
new_value_alloced, oldval, errbuf, opt_flags);
+ if (errmsg == NULL) {
+ if (!starting) {
+ trigger_optionsset_string(opt_idx, opt_flags, saved_origval,
+ saved_newval);
+ }
+ if (options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ STRING_OBJ(cstr_as_string(saved_newval)));
+ }
+ }
+ xfree(saved_origval);
+ xfree(saved_newval);
+
// If error detected, print the error message.
if (errmsg != NULL) {
- xfree(saved_origval);
goto skip;
}
- if (saved_origval != NULL) {
- char buf_type[7];
- vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s",
- (opt_flags & OPT_LOCAL) ? "local" : "global");
- set_vim_var_string(VV_OPTION_NEW, *(char **) varp, -1);
- set_vim_var_string(VV_OPTION_OLD, saved_origval, -1);
- set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
- apply_autocmds(EVENT_OPTIONSET,
- (char_u *)options[opt_idx].fullname,
- NULL, false, NULL);
- reset_v_option_vars();
- xfree(saved_origval);
- }
} else {
// key code option(FIXME(tarruda): Show a warning or something
// similar)
@@ -1899,15 +1943,7 @@ did_set_title (
{
if (starting != NO_SCREEN) {
maketitle();
- if (icon) {
- if (!p_icon) {
- ui_set_icon(NULL);
- }
- } else {
- if (!p_title) {
- ui_set_title(NULL);
- }
- }
+ resettitle();
}
}
@@ -2020,13 +2056,15 @@ static char_u *option_expand(int opt_idx, char_u *val)
if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
return NULL;
- /* If val is longer than MAXPATHL no meaningful expansion can be done,
- * expand_env() would truncate the string. */
- if (val != NULL && STRLEN(val) > MAXPATHL)
- return NULL;
-
- if (val == NULL)
+ if (val == NULL) {
val = *(char_u **)options[opt_idx].var;
+ }
+
+ // If val is longer than MAXPATHL no meaningful expansion can be done,
+ // expand_env() would truncate the string.
+ if (val == NULL || STRLEN(val) > MAXPATHL) {
+ return NULL;
+ }
/*
* Expanding this with NameBuff, expand_env() must not be passed IObuff.
@@ -2077,7 +2115,7 @@ static void didset_options(void)
static void didset_options2(void)
{
// Initialize the highlight_attr[] table.
- (void)highlight_changed();
+ highlight_changed();
// Parse default for 'clipboard'.
(void)opt_strings_flags(p_cb, p_cb_values, &cb_flags, true);
@@ -2118,6 +2156,7 @@ void check_buf_options(buf_T *buf)
check_string_option(&buf->b_p_inex);
check_string_option(&buf->b_p_inde);
check_string_option(&buf->b_p_indk);
+ check_string_option(&buf->b_p_fp);
check_string_option(&buf->b_p_fex);
check_string_option(&buf->b_p_kp);
check_string_option(&buf->b_p_mps);
@@ -2154,6 +2193,7 @@ void check_buf_options(buf_T *buf)
check_string_option(&buf->b_p_tsr);
check_string_option(&buf->b_p_lw);
check_string_option(&buf->b_p_bkc);
+ check_string_option(&buf->b_p_menc);
}
/*
@@ -2189,13 +2229,13 @@ static void check_string_option(char_u **pp)
*/
int was_set_insecurely(char_u *opt, int opt_flags)
{
- int idx = findoption(opt);
+ int idx = findoption((const char *)opt);
if (idx >= 0) {
uint32_t *flagp = insecure_flag(idx, opt_flags);
return (*flagp & P_INSECURE) != 0;
}
- EMSG2(_(e_intern2), "was_set_insecurely()");
+ internal_error("was_set_insecurely()");
return -1;
}
@@ -2251,11 +2291,11 @@ set_string_option_direct (
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int idx = opt_idx;
- if (idx == -1) { /* use name */
- idx = findoption(name);
- if (idx < 0) { /* not found (should not happen) */
- EMSG2(_(e_intern2), "set_string_option_direct()");
- EMSG2(_("For option %s"), name);
+ if (idx == -1) { // Use name.
+ idx = findoption((const char *)name);
+ if (idx < 0) { // Not found (should not happen).
+ internal_error("set_string_option_direct()");
+ IEMSG2(_("For option %s"), name);
return;
}
}
@@ -2340,7 +2380,8 @@ static char *set_string_option(const int opt_idx, const char *const value,
char *const oldval = *varp;
*varp = s;
- char *const saved_oldval = (starting ? NULL : xstrdup(oldval));
+ char *const saved_oldval = xstrdup(oldval);
+ char *const saved_newval = xstrdup(s);
char *const r = (char *)did_set_string_option(
opt_idx, (char_u **)varp, (int)true, (char_u *)oldval, NULL, opt_flags);
@@ -2349,23 +2390,38 @@ static char *set_string_option(const int opt_idx, const char *const value,
}
// call autocommand after handling side effects
- if (saved_oldval != NULL) {
- char buf_type[7];
- vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s",
- (opt_flags & OPT_LOCAL) ? "local" : "global");
- set_vim_var_string(VV_OPTION_NEW, (char *)(*varp), -1);
- set_vim_var_string(VV_OPTION_OLD, saved_oldval, -1);
- set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
- apply_autocmds(EVENT_OPTIONSET,
- (char_u *)options[opt_idx].fullname,
- NULL, false, NULL);
- reset_v_option_vars();
- xfree(saved_oldval);
+ if (r == NULL) {
+ if (!starting) {
+ trigger_optionsset_string(opt_idx, opt_flags, saved_oldval, saved_newval);
+ }
+ if (options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ STRING_OBJ(cstr_as_string(saved_newval)));
+ }
}
+ xfree(saved_oldval);
+ xfree(saved_newval);
return r;
}
+/// Return true if "val" is a valid 'filetype' name.
+/// Also used for 'syntax' and 'keymap'.
+static bool valid_filetype(char_u *val)
+{
+ for (char_u *s = val; *s != NUL; s++) {
+ if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)".-_", *s) == NULL) {
+ return false;
+ }
+ }
+ return true;
+}
+
+#ifdef _MSC_VER
+// MSVC optimizations are disabled for this function because it
+// incorrectly generates an empty string for SHM_ALL.
+#pragma optimize("", off)
+#endif
/*
* Handle string options that need some action to perform when changed.
* Returns NULL for success, or an error message for an error.
@@ -2385,6 +2441,7 @@ did_set_string_option (
int did_chartab = FALSE;
char_u **gvarp;
bool free_oldval = (options[opt_idx].flags & P_ALLOCED);
+ bool value_changed = false;
/* Get the global option to compare with, otherwise we would have to check
* two values for all local options. */
@@ -2394,12 +2451,14 @@ did_set_string_option (
if ((secure || sandbox != 0)
&& (options[opt_idx].flags & P_SECURE)) {
errmsg = e_secure;
- }
- /* Check for a "normal" file name in some options. Disallow a path
- * separator (slash and/or backslash), wildcards and characters that are
- * often illegal in a file name. */
- else if ((options[opt_idx].flags & P_NFNAME)
- && vim_strpbrk(*varp, (char_u *)"/\\*?[|<>") != NULL) {
+ } else if (((options[opt_idx].flags & P_NFNAME)
+ && vim_strpbrk(*varp, (char_u *)(secure ? "/\\*?[|;&<>\r\n"
+ : "/\\*?[<>\r\n")) != NULL)
+ || ((options[opt_idx].flags & P_NDNAME)
+ && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) {
+ // Check for a "normal" directory or file name in some options. Disallow a
+ // path separator (slash and/or backslash), wildcards and characters that
+ // are often illegal in a file name. Be more permissive if "secure" is off.
errmsg = e_invarg;
}
/* 'backupcopy' */
@@ -2439,16 +2498,13 @@ did_set_string_option (
else if (varp == &curwin->w_p_briopt) {
if (briopt_check(curwin) == FAIL)
errmsg = e_invarg;
- }
- /*
- * 'isident', 'iskeyword', 'isprint or 'isfname' option: refill chartab[]
- * If the new option is invalid, use old value. 'lisp' option: refill
- * chartab[] for '-' char
- */
- else if ( varp == &p_isi
+ } else if (varp == &p_isi
|| varp == &(curbuf->b_p_isk)
|| varp == &p_isp
|| varp == &p_isf) {
+ // 'isident', 'iskeyword', 'isprint or 'isfname' option: refill g_chartab[]
+ // If the new option is invalid, use old value. 'lisp' option: refill
+ // g_chartab[] for '-' char
if (init_chartab() == FAIL) {
did_chartab = TRUE; /* need to restore it below */
errmsg = e_invarg; /* error in value */
@@ -2481,11 +2537,11 @@ did_set_string_option (
if (s[2] == NUL)
break;
}
- }
- /* 'highlight' */
- else if (varp == &p_hl) {
- if (highlight_changed() == FAIL)
- errmsg = e_invarg; /* invalid flags */
+ } else if (varp == &p_hl) {
+ // 'highlight'
+ if (strcmp((char *)(*varp), HIGHLIGHT_INIT) != 0) {
+ errmsg = e_unsupportedoption;
+ }
}
/* 'nrformats' */
else if (gvarp == &p_nf) {
@@ -2507,15 +2563,15 @@ did_set_string_option (
else if (varp == &p_sbo) {
if (check_opt_strings(p_sbo, p_scbopt_values, TRUE) != OK)
errmsg = e_invarg;
- }
- /* 'ambiwidth' */
- else if (varp == &p_ambw) {
- if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
+ } else if (varp == &p_ambw || (int *)varp == &p_emoji) {
+ // 'ambiwidth'
+ if (check_opt_strings(p_ambw, p_ambw_values, false) != OK) {
errmsg = e_invarg;
- else if (set_chars_option(&p_lcs) != NULL)
+ } else if (set_chars_option(&p_lcs) != NULL) {
errmsg = (char_u *)_("E834: Conflicts with value of 'listchars'");
- else if (set_chars_option(&p_fcs) != NULL)
+ } else if (set_chars_option(&p_fcs) != NULL) {
errmsg = (char_u *)_("E835: Conflicts with value of 'fillchars'");
+ }
}
/* 'background' */
else if (varp == &p_bg) {
@@ -2524,12 +2580,11 @@ did_set_string_option (
init_highlight(FALSE, FALSE);
- if (dark != (*p_bg == 'd')
- && get_var_value((char_u *)"g:colors_name") != NULL) {
- /* The color scheme must have set 'background' back to another
- * value, that's not what we want here. Disable the color
- * scheme and set the colors again. */
- do_unlet((char_u *)"g:colors_name", TRUE);
+ if (dark != (*p_bg == 'd') && get_var_value("g:colors_name") != NULL) {
+ // The color scheme must have set 'background' back to another
+ // value, that's not what we want here. Disable the color
+ // scheme and set the colors again.
+ do_unlet(S_LEN("g:colors_name"), true);
free_string_option(p_bg);
p_bg = vim_strsave((char_u *)(dark ? "dark" : "light"));
check_string_option(&p_bg);
@@ -2558,21 +2613,19 @@ did_set_string_option (
else if (varp == &p_ei) {
if (check_ei() == FAIL)
errmsg = e_invarg;
- /* 'encoding' and 'fileencoding' */
- } else if (varp == &p_enc || gvarp == &p_fenc) {
- if (varp == &p_enc && did_source_startup_scripts) {
- errmsg = e_afterinit;
- } else if (gvarp == &p_fenc) {
- if (!MODIFIABLE(curbuf) && opt_flags != OPT_GLOBAL)
+ // 'encoding', 'fileencoding' and 'makeencoding'
+ } else if (varp == &p_enc || gvarp == &p_fenc || gvarp == &p_menc) {
+ if (gvarp == &p_fenc) {
+ if (!MODIFIABLE(curbuf) && opt_flags != OPT_GLOBAL) {
errmsg = e_modifiable;
- else if (vim_strchr(*varp, ',') != NULL)
- /* No comma allowed in 'fileencoding'; catches confusing it
- * with 'fileencodings'. */
+ } else if (vim_strchr(*varp, ',') != NULL) {
+ // No comma allowed in 'fileencoding'; catches confusing it
+ // with 'fileencodings'.
errmsg = e_invarg;
- else {
- /* May show a "+" in the title now. */
+ } else {
+ // May show a "+" in the title now.
redraw_titles();
- /* Add 'fileencoding' to the swap file. */
+ // Add 'fileencoding' to the swap file.
ml_setflags(curbuf);
}
}
@@ -2583,25 +2636,24 @@ did_set_string_option (
xfree(*varp);
*varp = p;
if (varp == &p_enc) {
- errmsg = mb_init();
- redraw_titles();
+ // only encoding=utf-8 allowed
+ if (STRCMP(p_enc, "utf-8") != 0) {
+ errmsg = e_unsupportedoption;
+ }
}
}
-
- if (errmsg == NULL) {
- /* When 'keymap' is used and 'encoding' changes, reload the keymap
- * (with another encoding). */
- if (varp == &p_enc && *curbuf->b_p_keymap != NUL)
- (void)keymap_init();
- }
} else if (varp == &p_penc) {
/* Canonize printencoding if VIM standard one */
p = enc_canonize(p_penc);
xfree(p_penc);
p_penc = p;
} else if (varp == &curbuf->b_p_keymap) {
- /* load or unload key mapping tables */
- errmsg = keymap_init();
+ if (!valid_filetype(*varp)) {
+ errmsg = e_invarg;
+ } else {
+ // load or unload key mapping tables
+ errmsg = keymap_init();
+ }
if (errmsg == NULL) {
if (*curbuf->b_p_keymap != NUL) {
@@ -2658,7 +2710,7 @@ did_set_string_option (
if (*p != NUL)
x2 = *p++;
if (*p != NUL) {
- x3 = mb_ptr2char(p);
+ x3 = utf_ptr2char(p);
p += mb_ptr2len(p);
}
if (x2 != ':' || x3 == -1 || (*p != NUL && *p != ',')) {
@@ -2728,9 +2780,13 @@ did_set_string_option (
// option.
opt_idx = ((options[opt_idx].fullname[0] == 'v')
? (shada_idx == -1
- ? ((shada_idx = findoption((char_u *) "shada")))
+ ? ((shada_idx = findoption("shada")))
: shada_idx)
: opt_idx);
+ // Update free_oldval now that we have the opt_idx for 'shada', otherwise
+ // there would be a disconnect between the check for P_ALLOCED at the start
+ // of the function and the set of P_ALLOCED at the end of the fuction.
+ free_oldval = (options[opt_idx].flags & P_ALLOCED);
for (s = p_shada; *s; ) {
/* Check it's a valid character */
if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL) {
@@ -2781,13 +2837,14 @@ did_set_string_option (
for (s = p_sbr; *s; ) {
if (ptr2cells(s) != 1)
errmsg = (char_u *)N_("E595: contains unprintable or wide character");
- mb_ptr_adv(s);
+ MB_PTR_ADV(s);
}
}
- /* 'guicursor' */
- else if (varp == &p_guicursor)
+ // 'guicursor'
+ else if (varp == &p_guicursor) {
errmsg = parse_shape_opt(SHAPE_CURSOR);
+ }
else if (varp == &p_popt)
errmsg = parse_printoptions();
@@ -2940,9 +2997,10 @@ did_set_string_option (
if (s[-1] == 'k' || s[-1] == 's') {
/* skip optional filename after 'k' and 's' */
while (*s && *s != ',' && *s != ' ') {
- if (*s == '\\')
- ++s;
- ++s;
+ if (*s == '\\' && s[1] != NUL) {
+ s++;
+ }
+ s++;
}
} else {
if (errbuf != NULL) {
@@ -2964,11 +3022,16 @@ did_set_string_option (
} else {
completeopt_was_set();
}
+ } else if (varp == &curwin->w_p_scl) {
+ // 'signcolumn'
+ if (check_opt_strings(*varp, p_scl_values, false) != OK) {
+ errmsg = e_invarg;
+ }
}
/* 'pastetoggle': translate key codes like in a mapping */
else if (varp == &p_pt) {
if (*p_pt) {
- (void)replace_termcodes(p_pt, STRLEN(p_pt), &p, true, true, false,
+ (void)replace_termcodes(p_pt, STRLEN(p_pt), &p, true, true, true,
CPO_TO_CPO_FLAGS);
if (p != NULL) {
if (new_value_alloced)
@@ -3090,21 +3153,42 @@ did_set_string_option (
else if (gvarp == &p_cino) {
/* TODO: recognize errors */
parse_cino(curbuf);
- }
- /* Options that are a list of flags. */
- else {
+ // inccommand
+ } else if (varp == &p_icm) {
+ if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
+ errmsg = e_invarg;
+ }
+ } else if (gvarp == &p_ft) {
+ if (!valid_filetype(*varp)) {
+ errmsg = e_invarg;
+ } else {
+ value_changed = STRCMP(oldval, *varp) != 0;
+ }
+ } else if (gvarp == &p_syn) {
+ if (!valid_filetype(*varp)) {
+ errmsg = e_invarg;
+ } else {
+ value_changed = STRCMP(oldval, *varp) != 0;
+ }
+ } else if (varp == &curwin->w_p_winhl) {
+ if (!parse_winhl_opt(curwin)) {
+ errmsg = e_invarg;
+ }
+ } else {
+ // Options that are a list of flags.
p = NULL;
- if (varp == &p_ww)
+ if (varp == &p_ww) { // 'whichwrap'
p = (char_u *)WW_ALL;
- if (varp == &p_shm)
+ }
+ if (varp == &p_shm) { // 'shortmess'
p = (char_u *)SHM_ALL;
- else if (varp == &(p_cpo))
+ } else if (varp == &(p_cpo)) { // 'cpoptions'
p = (char_u *)CPO_VI;
- else if (varp == &(curbuf->b_p_fo))
+ } else if (varp == &(curbuf->b_p_fo)) { // 'formatoptions'
p = (char_u *)FO_ALL;
- else if (varp == &curwin->w_p_cocu)
+ } else if (varp == &curwin->w_p_cocu) { // 'concealcursor'
p = (char_u *)COCU_ALL;
- else if (varp == &p_mouse) {
+ } else if (varp == &p_mouse) { // 'mouse'
p = (char_u *)MOUSE_ALL;
}
if (p != NULL) {
@@ -3128,8 +3212,6 @@ did_set_string_option (
*/
if (did_chartab)
(void)init_chartab();
- if (varp == &p_hl)
- (void)highlight_changed();
} else {
/* Remember where the option was set. */
set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
@@ -3162,13 +3244,33 @@ did_set_string_option (
*/
/* When 'syntax' is set, load the syntax of that name */
if (varp == &(curbuf->b_p_syn)) {
- apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
- curbuf->b_fname, TRUE, curbuf);
+ static int syn_recursive = 0;
+
+ syn_recursive++;
+ // Only pass true for "force" when the value changed or not used
+ // recursively, to avoid endless recurrence.
+ apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn, curbuf->b_fname,
+ value_changed || syn_recursive == 1, curbuf);
+ syn_recursive--;
} else if (varp == &(curbuf->b_p_ft)) {
- /* 'filetype' is set, trigger the FileType autocommand */
- did_filetype = TRUE;
- apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft,
- curbuf->b_fname, TRUE, curbuf);
+ // 'filetype' is set, trigger the FileType autocommand
+ // Skip this when called from a modeline and the filetype was
+ // already set to this value.
+ if (!(opt_flags & OPT_MODELINE) || value_changed) {
+ static int ft_recursive = 0;
+
+ ft_recursive++;
+ did_filetype = true;
+ // Only pass true for "force" when the value changed or not
+ // used recursively, to avoid endless recurrence.
+ apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft, curbuf->b_fname,
+ value_changed || ft_recursive == 1, curbuf);
+ ft_recursive--;
+ // Just in case the old "curbuf" is now invalid
+ if (varp != &(curbuf->b_p_ft)) {
+ varp = NULL;
+ }
+ }
}
if (varp == &(curwin->w_s->b_p_spl)) {
char_u fname[200];
@@ -3195,7 +3297,7 @@ did_set_string_option (
if (varp == &p_mouse) {
if (*p_mouse == NUL) {
- ui_mouse_off();
+ ui_call_mouse_off();
} else {
setmouse(); // in case 'mouse' changed
}
@@ -3209,6 +3311,9 @@ did_set_string_option (
return errmsg;
}
+#ifdef _MSC_VER
+#pragma optimize("", on)
+#endif
/*
* Simple int comparison function for use with qsort()
@@ -3285,37 +3390,40 @@ skip:
return NULL; /* no error */
}
-/*
- * Handle setting 'listchars' or 'fillchars'.
- * Returns error message, NULL if it's OK.
- */
+
+/// Handle setting 'listchars' or 'fillchars'.
+/// Assume monocell characters
+///
+/// @param varp either &p_lcs ('listchars') or &p_fcs ('fillchar')
+/// @return error message, NULL if it's OK.
static char_u *set_chars_option(char_u **varp)
{
int round, i, len, entries;
char_u *p, *s;
int c1, c2 = 0;
struct charstab {
- int *cp;
- char *name;
+ int *cp; ///< char value
+ char *name; ///< char id
+ int def; ///< default value
};
- static struct charstab filltab[] =
- {
- {&fill_stl, "stl"},
- {&fill_stlnc, "stlnc"},
- {&fill_vert, "vert"},
- {&fill_fold, "fold"},
- {&fill_diff, "diff"},
+ static struct charstab filltab[] = {
+ { &fill_stl, "stl" , ' ' },
+ { &fill_stlnc, "stlnc", ' ' },
+ { &fill_vert, "vert" , 9474 }, // │
+ { &fill_fold, "fold" , 183 }, // ·
+ { &fill_diff, "diff" , '-' },
+ { &fill_msgsep, "msgsep", ' ' },
+ { &fill_eob, "eob", '~' },
};
- static struct charstab lcstab[] =
- {
- {&lcs_eol, "eol"},
- {&lcs_ext, "extends"},
- {&lcs_nbsp, "nbsp"},
- {&lcs_prec, "precedes"},
- {&lcs_space, "space"},
- {&lcs_tab2, "tab"},
- {&lcs_trail, "trail"},
- {&lcs_conceal, "conceal"},
+ static struct charstab lcstab[] = {
+ { &lcs_eol, "eol", NUL },
+ { &lcs_ext, "extends", NUL },
+ { &lcs_nbsp, "nbsp", NUL },
+ { &lcs_prec, "precedes", NUL },
+ { &lcs_space, "space", NUL },
+ { &lcs_tab2, "tab", NUL },
+ { &lcs_trail, "trail", NUL },
+ { &lcs_conceal, "conceal", NUL },
};
struct charstab *tab;
@@ -3325,20 +3433,29 @@ static char_u *set_chars_option(char_u **varp)
} else {
tab = filltab;
entries = ARRAY_SIZE(filltab);
+ if (*p_ambw == 'd') {
+ // XXX: If ambiwidth=double then "|" and "·" take 2 columns, which is
+ // forbidden (TUI limitation?). Set old defaults.
+ filltab[2].def = '|';
+ filltab[3].def = '-';
+ } else {
+ filltab[2].def = 9474; // │
+ filltab[3].def = 183; // ·
+ }
}
- /* first round: check for valid value, second round: assign values */
- for (round = 0; round <= 1; ++round) {
+ // first round: check for valid value, second round: assign values
+ for (round = 0; round <= 1; round++) {
if (round > 0) {
- /* After checking that the value is valid: set defaults: space for
- * 'fillchars', NUL for 'listchars' */
- for (i = 0; i < entries; ++i)
- if (tab[i].cp != NULL)
- *(tab[i].cp) = (varp == &p_lcs ? NUL : ' ');
- if (varp == &p_lcs)
+ // After checking that the value is valid: set defaults
+ for (i = 0; i < entries; i++) {
+ if (tab[i].cp != NULL) {
+ *(tab[i].cp) = tab[i].def;
+ }
+ }
+ if (varp == &p_lcs) {
lcs_tab1 = NUL;
- else
- fill_diff = '-';
+ }
}
p = *varp;
while (*p) {
@@ -3348,15 +3465,22 @@ static char_u *set_chars_option(char_u **varp)
&& p[len] == ':'
&& p[len + 1] != NUL) {
s = p + len + 1;
- c1 = mb_ptr2char_adv(&s);
- if (mb_char2cells(c1) > 1)
+
+ // TODO(bfredl): use schar_T representation and utfc_ptr2len
+ int c1len = utf_ptr2len(s);
+ c1 = mb_cptr2char_adv((const char_u **)&s);
+ if (mb_char2cells(c1) > 1 || (c1len == 1 && c1 > 127)) {
continue;
+ }
if (tab[i].cp == &lcs_tab2) {
- if (*s == NUL)
+ if (*s == NUL) {
continue;
- c2 = mb_ptr2char_adv(&s);
- if (mb_char2cells(c2) > 1)
+ }
+ int c2len = utf_ptr2len(s);
+ c2 = mb_cptr2char_adv((const char_u **)&s);
+ if (mb_char2cells(c2) > 1 || (c2len == 1 && c2 > 127)) {
continue;
+ }
}
if (*s == ',' || *s == NUL) {
if (round) {
@@ -3496,6 +3620,47 @@ static char_u *compile_cap_prog(synblock_T *synblock)
return NULL;
}
+/// Handle setting `winhighlight' in window "wp"
+static bool parse_winhl_opt(win_T *wp)
+{
+ int w_hl_id_normal = 0;
+ int w_hl_ids[HLF_COUNT] = { 0 };
+ int hlf;
+
+ const char *p = (const char *)wp->w_p_winhl;
+ while (*p) {
+ char *colon = strchr(p, ':');
+ if (!colon) {
+ return false;
+ }
+ size_t nlen = (size_t)(colon-p);
+ char *hi = colon+1;
+ char *commap = xstrchrnul(hi, ',');
+ int hl_id = syn_check_group((char_u *)hi, (int)(commap-hi));
+
+ if (strncmp("Normal", p, nlen) == 0) {
+ w_hl_id_normal = hl_id;
+ } else {
+ for (hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
+ if (strncmp(hlf_names[hlf], p, nlen) == 0) {
+ w_hl_ids[hlf] = hl_id;
+ break;
+ }
+ }
+ if (hlf == HLF_COUNT) {
+ return false;
+ }
+ }
+
+ p = *commap ? commap+1 : "";
+ }
+
+ wp->w_hl_id_normal = w_hl_id_normal;
+ memcpy(wp->w_hl_ids, w_hl_ids, sizeof(w_hl_ids));
+ wp->w_hl_needs_update = true;
+ return true;
+}
+
/*
* Set the scriptID for an option, taking care of setting the buffer- or
* window-local value.
@@ -3504,37 +3669,40 @@ static void set_option_scriptID_idx(int opt_idx, int opt_flags, int id)
{
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int indir = (int)options[opt_idx].indir;
+ const LastSet last_set = { id, current_channel_id };
- /* Remember where the option was set. For local options need to do that
- * in the buffer or window structure. */
- if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0)
- options[opt_idx].scriptID = id;
+ // Remember where the option was set. For local options need to do that
+ // in the buffer or window structure.
+ if (both || (opt_flags & OPT_GLOBAL) || (indir & (PV_BUF|PV_WIN)) == 0) {
+ options[opt_idx].last_set = last_set;
+ }
if (both || (opt_flags & OPT_LOCAL)) {
- if (indir & PV_BUF)
- curbuf->b_p_scriptID[indir & PV_MASK] = id;
- else if (indir & PV_WIN)
- curwin->w_p_scriptID[indir & PV_MASK] = id;
+ if (indir & PV_BUF) {
+ curbuf->b_p_scriptID[indir & PV_MASK] = last_set;
+ } else if (indir & PV_WIN) {
+ curwin->w_p_scriptID[indir & PV_MASK] = last_set;
+ }
}
}
-/*
- * Set the value of a boolean option, and take care of side effects.
- * Returns NULL for success, or an error message for an error.
- */
-static char_u *
-set_bool_option (
- int opt_idx, /* index in options[] table */
- char_u *varp, /* pointer to the option variable */
- int value, /* new value */
- int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
-)
+/// Set the value of a boolean option, taking care of side effects
+///
+/// @param[in] opt_idx Option index in options[] table.
+/// @param[out] varp Pointer to the option variable.
+/// @param[in] value New value.
+/// @param[in] opt_flags OPT_LOCAL and/or OPT_GLOBAL.
+///
+/// @return NULL on success, error message on error.
+static char *set_bool_option(const int opt_idx, char_u *const varp,
+ const int value,
+ const int opt_flags)
{
int old_value = *(int *)varp;
/* Disallow changing some options from secure mode */
if ((secure || sandbox != 0)
&& (options[opt_idx].flags & P_SECURE)) {
- return e_secure;
+ return (char *)e_secure;
}
*(int *)varp = value; /* set the new value */
@@ -3547,29 +3715,37 @@ set_bool_option (
*(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
// Ensure that options set to p_force_on cannot be disabled.
- if ((int *)varp == &p_force_on && p_force_on == FALSE) {
- p_force_on = TRUE;
- return e_unsupportedoption;
- }
+ if ((int *)varp == &p_force_on && p_force_on == false) {
+ p_force_on = true;
+ return (char *)e_unsupportedoption;
// Ensure that options set to p_force_off cannot be enabled.
- else if ((int *)varp == &p_force_off && p_force_off == TRUE) {
- p_force_off = FALSE;
- return e_unsupportedoption;
- }
- /* 'undofile' */
- else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
- /* Only take action when the option was set. When reset we do not
- * delete the undo file, the option may be set again without making
- * any changes in between. */
+ } else if ((int *)varp == &p_force_off && p_force_off == true) {
+ p_force_off = false;
+ return (char *)e_unsupportedoption;
+ } else if ((int *)varp == &p_lrm) {
+ // 'langremap' -> !'langnoremap'
+ p_lnr = !p_lrm;
+ } else if ((int *)varp == &p_lnr) {
+ // 'langnoremap' -> !'langremap'
+ p_lrm = !p_lnr;
+ } else if ((int *)varp == &curwin->w_p_cul && !value && old_value) {
+ // 'cursorline'
+ reset_cursorline();
+ // 'undofile'
+ } else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
+ // Only take action when the option was set. When reset we do not
+ // delete the undo file, the option may be set again without making
+ // any changes in between.
if (curbuf->b_p_udf || p_udf) {
char_u hash[UNDO_HASH_SIZE];
buf_T *save_curbuf = curbuf;
- for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next) {
- /* When 'undofile' is set globally: for every buffer, otherwise
- * only for the current buffer: Try to read in the undofile,
- * if one exists, the buffer wasn't changed and the buffer was
- * loaded */
+ FOR_ALL_BUFFERS(bp) {
+ curbuf = bp;
+ // When 'undofile' is set globally: for every buffer, otherwise
+ // only for the current buffer: Try to read in the undofile,
+ // if one exists, the buffer wasn't changed and the buffer was
+ // loaded
if ((curbuf == save_curbuf
|| (opt_flags & OPT_GLOBAL) || opt_flags == 0)
&& !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL) {
@@ -3647,14 +3823,16 @@ set_bool_option (
/* when 'insertmode' is set from an autocommand need to do work here */
else if ((int *)varp == &p_im) {
if (p_im) {
- if ((State & INSERT) == 0)
- need_start_insertmode = TRUE;
- stop_insert_mode = FALSE;
- } else {
- need_start_insertmode = FALSE;
- stop_insert_mode = TRUE;
- if (restart_edit != 0 && mode_displayed)
- clear_cmdline = TRUE; /* remove "(insert)" */
+ if ((State & INSERT) == 0) {
+ need_start_insertmode = true;
+ }
+ stop_insert_mode = false;
+ } else if (old_value) { // only reset if it was set previously
+ need_start_insertmode = false;
+ stop_insert_mode = true;
+ if (restart_edit != 0 && mode_displayed) {
+ clear_cmdline = true; // remove "(insert)"
+ }
restart_edit = 0;
}
}
@@ -3679,28 +3857,24 @@ set_bool_option (
if (curwin->w_p_pvw) {
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
if (win->w_p_pvw && win != curwin) {
- curwin->w_p_pvw = FALSE;
- return (char_u *)N_("E590: A preview window already exists");
+ curwin->w_p_pvw = false;
+ return N_("E590: A preview window already exists");
}
}
}
- }
-
- /*
- * When 'lisp' option changes include/exclude '-' in
- * keyword characters.
- */
- else if (varp == (char_u *)&(curbuf->b_p_lisp)) {
- (void)buf_init_chartab(curbuf, FALSE); /* ignore errors */
- }
- /* when 'title' changed, may need to change the title; same for 'icon' */
- else if ((int *)varp == &p_title) {
- did_set_title(FALSE);
+ } else if (varp == (char_u *)&(curbuf->b_p_lisp)) {
+ // When 'lisp' option changes include/exclude '-' in
+ // keyword characters.
+ (void)buf_init_chartab(curbuf, false); // ignore errors
+ } else if ((int *)varp == &p_title) {
+ // when 'title' changed, may need to change the title; same for 'icon'
+ did_set_title(false);
} else if ((int *)varp == &p_icon) {
- did_set_title(TRUE);
- } else if ((bool *)varp == &curbuf->b_changed) {
- if (!value)
- save_file_ff(curbuf); /* Buffer is unchanged */
+ did_set_title(true);
+ } else if ((int *)varp == &curbuf->b_changed) {
+ if (!value) {
+ save_file_ff(curbuf); // Buffer is unchanged
+ }
redraw_titles();
modified_was_set = value;
}
@@ -3728,11 +3902,12 @@ set_bool_option (
else if ((int *)varp == &curwin->w_p_wrap) {
if (curwin->w_p_wrap)
curwin->w_leftcol = 0;
- } else if ((bool *)varp == &p_ea) {
- if (p_ea && !old_value)
+ } else if ((int *)varp == &p_ea) {
+ if (p_ea && !old_value) {
win_equal(curwin, false, 0);
- } else if ((bool *)varp == &p_acd) {
- /* Change directories when the 'acd' option is set now. */
+ }
+ } else if ((int *)varp == &p_acd) {
+ // Change directories when the 'acd' option is set now.
do_autochdir();
}
/* 'diff' */
@@ -3812,8 +3987,8 @@ set_bool_option (
/* Enable Arabic shaping (major part of what Arabic requires) */
if (!p_arshape) {
- p_arshape = TRUE;
- redraw_later_clear();
+ p_arshape = true;
+ redraw_all_later(NOT_VALID);
}
}
@@ -3823,17 +3998,16 @@ set_bool_option (
static char *w_arabic = N_(
"W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
- msg_source(hl_attr(HLF_W));
- MSG_ATTR(_(w_arabic), hl_attr(HLF_W));
+ msg_source(HL_ATTR(HLF_W));
+ msg_attr(_(w_arabic), HL_ATTR(HLF_W));
set_vim_var_string(VV_WARNINGMSG, _(w_arabic), -1);
}
/* set 'delcombine' */
p_deco = TRUE;
- /* Force-set the necessary keymap for arabic */
- set_option_value((char_u *)"keymap", 0L, (char_u *)"arabic",
- OPT_LOCAL);
+ // Force-set the necessary keymap for arabic.
+ set_option_value("keymap", 0L, "arabic", OPT_LOCAL);
p_altkeymap = 0;
p_hkmap = 0;
p_fkmap = 0;
@@ -3871,7 +4045,8 @@ set_bool_option (
options[opt_idx].flags |= P_WAS_SET;
- if (!starting) {
+ // 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_new[2];
char buf_type[7];
@@ -3890,6 +4065,11 @@ set_bool_option (
reset_v_option_vars();
}
+ if (options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ BOOLEAN_OBJ(value));
+ }
+
comp_col(); /* in case 'ruler' or 'showcmd' changed */
if (curwin->w_curswant != MAXCOL
&& (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
@@ -3899,20 +4079,18 @@ set_bool_option (
return NULL;
}
-/*
- * Set the value of a number option, and take care of side effects.
- * Returns NULL for success, or an error message for an error.
- */
-static char_u *
-set_num_option (
- int opt_idx, /* index in options[] table */
- char_u *varp, /* pointer to the option variable */
- long value, /* new value */
- char_u *errbuf, /* buffer for error messages */
- size_t errbuflen, /* length of "errbuf" */
- int opt_flags /* OPT_LOCAL, OPT_GLOBAL and
- OPT_MODELINE */
-)
+/// Set the value of a number option, taking care of side effects
+///
+/// @param[in] opt_idx Option index in options[] table.
+/// @param[out] varp Pointer to the option variable.
+/// @param[in] value New value.
+/// @param errbuf Buffer for error messages.
+/// @param[in] errbuflen Length of `errbuf`.
+/// @param[in] opt_flags OPT_LOCAL, OPT_GLOBAL or OPT_MODELINE.
+///
+/// @return NULL on success, error message on error.
+static char *set_num_option(int opt_idx, char_u *varp, long value,
+ char_u *errbuf, size_t errbuflen, int opt_flags)
{
char_u *errmsg = NULL;
long old_value = *(long *)varp;
@@ -3923,113 +4101,198 @@ set_num_option (
/* Disallow changing some options from secure mode. */
if ((secure || sandbox != 0)
&& (options[opt_idx].flags & P_SECURE)) {
- return e_secure;
+ return (char *)e_secure;
}
- *pp = value;
- /* Remember where the option was set. */
- set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
-
- if (curbuf->b_p_sw < 0) {
- errmsg = e_positive;
- curbuf->b_p_sw = curbuf->b_p_ts;
+ // Many number options assume their value is in the signed int range.
+ if (value < INT_MIN || value > INT_MAX) {
+ return (char *)e_invarg;
}
- /*
- * Number options that need some action when changed
- */
- if (pp == &p_wh || pp == &p_hh) {
- if (p_wh < 1) {
+ // Options that need some validation.
+ if (pp == &p_wh) {
+ if (value < 1) {
errmsg = e_positive;
- p_wh = 1;
- }
- if (p_wmh > p_wh) {
+ } else if (p_wmh > value) {
errmsg = e_winheight;
- p_wh = p_wmh;
}
- if (p_hh < 0) {
+ } else if (pp == &p_hh) {
+ if (value < 0) {
errmsg = e_positive;
- p_hh = 0;
}
-
- /* Change window height NOW */
- if (lastwin != firstwin) {
- if (pp == &p_wh && curwin->w_height < p_wh)
- win_setheight((int)p_wh);
- if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
- win_setheight((int)p_hh);
- }
- }
- /* 'winminheight' */
- else if (pp == &p_wmh) {
- if (p_wmh < 0) {
+ } else if (pp == &p_wmh) {
+ if (value < 0) {
errmsg = e_positive;
- p_wmh = 0;
- }
- if (p_wmh > p_wh) {
+ } else if (value > p_wh) {
errmsg = e_winheight;
- p_wmh = p_wh;
}
- win_setminheight();
} else if (pp == &p_wiw) {
- if (p_wiw < 1) {
+ if (value < 1) {
errmsg = e_positive;
- p_wiw = 1;
+ } else if (p_wmw > value) {
+ errmsg = e_winwidth;
}
- if (p_wmw > p_wiw) {
+ } else if (pp == &p_wmw) {
+ if (value < 0) {
+ errmsg = e_positive;
+ } else if (value > p_wiw) {
errmsg = e_winwidth;
- p_wiw = p_wmw;
}
+ } else if (pp == &p_mco) {
+ value = MAX_MCO;
+ } else if (pp == &p_titlelen) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &p_uc) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &p_ch) {
+ if (value < 1) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &p_tm) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &p_hi) {
+ if (value < 0) {
+ errmsg = e_positive;
+ } else if (value > 10000) {
+ errmsg = e_invarg;
+ }
+ } else if (pp == &p_re) {
+ if (value < 0 || value > 2) {
+ errmsg = e_invarg;
+ }
+ } else if (pp == &p_report) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &p_so) {
+ if (value < 0 && full_screen) {
+ errmsg = e_scroll;
+ }
+ } else if (pp == &p_siso) {
+ if (value < 0 && full_screen) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &p_cwh) {
+ if (value < 1) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &p_ut) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &p_ss) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &curwin->w_p_fdl || pp == &curwin->w_allbuf_opt.wo_fdl) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &curwin->w_p_fdc || pp == &curwin->w_allbuf_opt.wo_fdc) {
+ if (value < 0) {
+ errmsg = e_positive;
+ } else if (value > 12) {
+ errmsg = e_invarg;
+ }
+ } else if (pp == &curwin->w_p_cole || pp == &curwin->w_allbuf_opt.wo_cole) {
+ if (value < 0) {
+ errmsg = e_positive;
+ } else if (value > 3) {
+ errmsg = e_invarg;
+ }
+ } else if (pp == &curwin->w_p_nuw || pp == &curwin->w_allbuf_opt.wo_nuw) {
+ if (value < 1) {
+ errmsg = e_positive;
+ } else if (value > 10) {
+ errmsg = e_invarg;
+ }
+ } else if (pp == &curbuf->b_p_iminsert || pp == &p_iminsert) {
+ if (value < 0 || value > B_IMODE_LAST) {
+ errmsg = e_invarg;
+ }
+ } else if (pp == &curbuf->b_p_imsearch || pp == &p_imsearch) {
+ if (value < -1 || value > B_IMODE_LAST) {
+ errmsg = e_invarg;
+ }
+ } else if (pp == &curbuf->b_p_channel || pp == &p_channel) {
+ errmsg = e_invarg;
+ } else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) {
+ if (value < -1 || value > SB_MAX
+ || (value != -1 && opt_flags == OPT_LOCAL && !curbuf->terminal)) {
+ errmsg = e_invarg;
+ }
+ } else if (pp == &curbuf->b_p_sw || pp == &p_sw) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &curbuf->b_p_ts || pp == &p_ts) {
+ if (value < 1) {
+ errmsg = e_positive;
+ }
+ } else if (pp == &curbuf->b_p_tw || pp == &p_tw) {
+ if (value < 0) {
+ errmsg = e_positive;
+ }
+ }
- /* Change window width NOW */
- if (lastwin != firstwin && curwin->w_width < p_wiw)
- win_setwidth((int)p_wiw);
+ // Don't change the value and return early if validation failed.
+ if (errmsg != NULL) {
+ return (char *)errmsg;
}
- /* 'winminwidth' */
- else if (pp == &p_wmw) {
- if (p_wmw < 0) {
- errmsg = e_positive;
- p_wmw = 0;
+
+ *pp = value;
+ // Remember where the option was set.
+ set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
+
+ // For these options we want to fix some invalid values.
+ if (pp == &p_window) {
+ if (p_window < 1) {
+ p_window = Rows - 1;
+ } else if (p_window >= Rows) {
+ p_window = Rows - 1;
}
- if (p_wmw > p_wiw) {
- errmsg = e_winwidth;
- p_wmw = p_wiw;
+ } else if (pp == &p_ch) {
+ if (p_ch > Rows - min_rows() + 1) {
+ p_ch = Rows - min_rows() + 1;
}
+ }
+
+ // Number options that need some action when changed
+ if (pp == &p_wh) {
+ if (!ONE_WINDOW && curwin->w_height < p_wh) {
+ win_setheight((int)p_wh);
+ }
+ } else if (pp == &p_hh) {
+ if (!ONE_WINDOW && curbuf->b_help && curwin->w_height < p_hh) {
+ win_setheight((int)p_hh);
+ }
+ } else if (pp == &p_wmh) {
win_setminheight();
+ } else if (pp == &p_wiw) {
+ if (!ONE_WINDOW && curwin->w_width < p_wiw) {
+ win_setwidth((int)p_wiw);
+ }
} else if (pp == &p_ls) {
- /* (re)set last window status line */
- last_status(false);
- }
- /* (re)set tab page line */
- else if (pp == &p_stal) {
- shell_new_rows(); /* recompute window positions and heights */
- }
- /* 'foldlevel' */
- else if (pp == &curwin->w_p_fdl) {
- if (curwin->w_p_fdl < 0)
- curwin->w_p_fdl = 0;
+ last_status(false); // (re)set last window status line.
+ } else if (pp == &p_stal) {
+ // (re)set tab page line
+ shell_new_rows(); // recompute window positions and heights
+ } else if (pp == &curwin->w_p_fdl) {
newFoldLevel();
- }
- /* 'foldminlines' */
- else if (pp == &curwin->w_p_fml) {
+ } else if (pp == &curwin->w_p_fml) {
foldUpdateAll(curwin);
- }
- /* 'foldnestmax' */
- else if (pp == &curwin->w_p_fdn) {
- if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
+ } else if (pp == &curwin->w_p_fdn) {
+ if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin)) {
foldUpdateAll(curwin);
- }
- /* 'foldcolumn' */
- else if (pp == &curwin->w_p_fdc) {
- if (curwin->w_p_fdc < 0) {
- errmsg = e_positive;
- curwin->w_p_fdc = 0;
- } else if (curwin->w_p_fdc > 12) {
- errmsg = e_invarg;
- curwin->w_p_fdc = 12;
}
- // 'shiftwidth' or 'tabstop'
- } else if (pp == &curbuf->b_p_sw || pp == (long *)&curbuf->b_p_ts) {
+ } else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts) {
+ // 'shiftwidth' or 'tabstop'
if (foldmethodIsIndent(curwin)) {
foldUpdateAll(curwin);
}
@@ -4038,114 +4301,52 @@ set_num_option (
if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0) {
parse_cino(curbuf);
}
- }
- /* 'maxcombine' */
- else if (pp == &p_mco) {
- if (p_mco > MAX_MCO)
- p_mco = MAX_MCO;
- else if (p_mco < 0)
- p_mco = 0;
- screenclear(); /* will re-allocate the screen */
} else if (pp == &curbuf->b_p_iminsert) {
- if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST) {
- errmsg = e_invarg;
- curbuf->b_p_iminsert = B_IMODE_NONE;
- }
- p_iminsert = curbuf->b_p_iminsert;
showmode();
- /* Show/unshow value of 'keymap' in status lines. */
+ // Show/unshow value of 'keymap' in status lines.
status_redraw_curbuf();
- } else if (pp == &p_window) {
- if (p_window < 1)
- p_window = 1;
- else if (p_window >= Rows)
- p_window = Rows - 1;
- } else if (pp == &curbuf->b_p_imsearch) {
- if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST) {
- errmsg = e_invarg;
- curbuf->b_p_imsearch = B_IMODE_NONE;
- }
- p_imsearch = curbuf->b_p_imsearch;
- }
- /* if 'titlelen' has changed, redraw the title */
- else if (pp == &p_titlelen) {
- if (p_titlelen < 0) {
- errmsg = e_positive;
- p_titlelen = 85;
- }
- if (starting != NO_SCREEN && old_value != p_titlelen)
- need_maketitle = TRUE;
- }
- /* if p_ch changed value, change the command line height */
- else if (pp == &p_ch) {
- if (p_ch < 1) {
- errmsg = e_positive;
- p_ch = 1;
- }
- if (p_ch > Rows - min_rows() + 1)
- p_ch = Rows - min_rows() + 1;
-
- /* Only compute the new window layout when startup has been
- * completed. Otherwise the frame sizes may be wrong. */
- if (p_ch != old_value && full_screen
- )
+ } else if (pp == &p_titlelen) {
+ // if 'titlelen' has changed, redraw the title
+ if (starting != NO_SCREEN && old_value != p_titlelen) {
+ need_maketitle = true;
+ }
+ } else if (pp == &p_ch) {
+ // if p_ch changed value, change the command line height
+ // Only compute the new window layout when startup has been
+ // completed. Otherwise the frame sizes may be wrong.
+ if (p_ch != old_value && full_screen) {
command_height();
- }
- /* when 'updatecount' changes from zero to non-zero, open swap files */
- else if (pp == &p_uc) {
- if (p_uc < 0) {
- errmsg = e_positive;
- p_uc = 100;
}
- if (p_uc && !old_value)
+ } else if (pp == &p_uc) {
+ // when 'updatecount' changes from zero to non-zero, open swap files
+ if (p_uc && !old_value) {
ml_open_files();
- } else if (pp == &curwin->w_p_cole) {
- if (curwin->w_p_cole < 0) {
- errmsg = e_positive;
- curwin->w_p_cole = 0;
- } else if (curwin->w_p_cole > 3) {
- errmsg = e_invarg;
- curwin->w_p_cole = 3;
- }
- }
- /* sync undo before 'undolevels' changes */
- else if (pp == &p_ul) {
- /* use the old value, otherwise u_sync() may not work properly */
- p_ul = old_value;
- u_sync(TRUE);
- p_ul = value;
- } else if (pp == &curbuf->b_p_ul) {
- /* use the old value, otherwise u_sync() may not work properly */
- curbuf->b_p_ul = old_value;
- u_sync(TRUE);
- curbuf->b_p_ul = value;
- }
- /* 'numberwidth' must be positive */
- else if (pp == &curwin->w_p_nuw) {
- if (curwin->w_p_nuw < 1) {
- errmsg = e_positive;
- curwin->w_p_nuw = 1;
}
- if (curwin->w_p_nuw > 10) {
+ } else if (pp == &p_pyx) {
+ if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3) {
errmsg = e_invarg;
- curwin->w_p_nuw = 10;
}
- curwin->w_nrwidth_line_count = 0;
+ } else if (pp == &p_ul || pp == &curbuf->b_p_ul) {
+ // sync undo before 'undolevels' changes
+ // use the old value, otherwise u_sync() may not work properly
+ *pp = old_value;
+ u_sync(true);
+ *pp = value;
} else if (pp == &curbuf->b_p_tw) {
- if (curbuf->b_p_tw < 0) {
- errmsg = e_positive;
- curbuf->b_p_tw = 0;
- }
-
FOR_ALL_TAB_WINDOWS(tp, wp) {
check_colorcolumn(wp);
}
-
+ } else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) {
+ if (curbuf->terminal) {
+ // Force the scrollback to take effect.
+ terminal_resize(curbuf->terminal, UINT16_MAX, UINT16_MAX);
+ }
+ } else if (pp == &curwin->w_p_nuw) {
+ curwin->w_nrwidth_line_count = 0;
}
- /*
- * Check the bounds for numeric options here
- */
+
+ // Check the (new) bounds for Rows and Columns here.
if (Rows < min_rows() && full_screen) {
if (errbuf != NULL) {
vim_snprintf((char *)errbuf, errbuflen,
@@ -4165,37 +4366,28 @@ set_num_option (
limit_screen_size();
- /*
- * If the screen (shell) height has been changed, assume it is the
- * physical screenheight.
- */
+ // If the screen (shell) height has been changed, assume it is the
+ // physical screenheight.
if (old_Rows != Rows || old_Columns != Columns) {
- /* Changing the screen size is not allowed while updating the screen. */
+ // Changing the screen size is not allowed while updating the screen.
if (updating_screen) {
*pp = old_value;
} else if (full_screen) {
screen_resize((int)Columns, (int)Rows);
} else {
- /* Postpone the resizing; check the size and cmdline position for
- * messages. */
+ // Postpone the resizing; check the size and cmdline position for
+ // messages.
check_shellsize();
if (cmdline_row > Rows - p_ch && Rows > p_ch) {
assert(p_ch >= 0 && Rows - p_ch <= INT_MAX);
cmdline_row = (int)(Rows - p_ch);
}
}
- if (p_window >= Rows || !option_was_set((char_u *)"window"))
+ if (p_window >= Rows || !option_was_set("window")) {
p_window = Rows - 1;
+ }
}
- if (curbuf->b_p_ts <= 0) {
- errmsg = e_positive;
- curbuf->b_p_ts = 8;
- }
- if (p_tm < 0) {
- errmsg = e_positive;
- p_tm = 0;
- }
if ((curwin->w_p_scr <= 0
|| (curwin->w_p_scr > curwin->w_height
&& curwin->w_height > 0))
@@ -4212,21 +4404,6 @@ set_num_option (
else /* curwin->w_p_scr > curwin->w_height */
curwin->w_p_scr = curwin->w_height;
}
- if (p_hi < 0) {
- errmsg = e_positive;
- p_hi = 0;
- } else if (p_hi > 10000) {
- errmsg = e_invarg;
- p_hi = 10000;
- }
- if (p_re < 0 || p_re > 2) {
- errmsg = e_invarg;
- p_re = 0;
- }
- if (p_report < 0) {
- errmsg = e_positive;
- p_report = 1;
- }
if ((p_sj < -100 || p_sj >= Rows) && full_screen) {
if (Rows != old_Rows) /* Rows changed, just adjust p_sj */
p_sj = Rows / 2;
@@ -4235,34 +4412,21 @@ set_num_option (
p_sj = 1;
}
}
- if (p_so < 0 && full_screen) {
- errmsg = e_scroll;
- p_so = 0;
- }
- if (p_siso < 0 && full_screen) {
- errmsg = e_positive;
- p_siso = 0;
- }
- if (p_cwh < 1) {
- errmsg = e_positive;
- p_cwh = 1;
- }
- if (p_ut < 0) {
- errmsg = e_positive;
- p_ut = 2000;
- }
- if (p_ss < 0) {
- errmsg = e_positive;
- p_ss = 0;
- }
- /* May set global value for local option. */
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
+ // May set global value for local option.
+ if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
*(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
+ }
+
+ if (pp == &curbuf->b_p_scbk && !curbuf->terminal) {
+ // Normal buffer: reset local 'scrollback' after updating the global value.
+ curbuf->b_p_scbk = -1;
+ }
options[opt_idx].flags |= P_WAS_SET;
- if (!starting && errmsg == NULL) {
+ // 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_new[NUMBUFLEN];
char buf_type[7];
@@ -4279,13 +4443,38 @@ set_num_option (
reset_v_option_vars();
}
+ if (errmsg == NULL && options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ INTEGER_OBJ(value));
+ }
+
comp_col(); /* in case 'columns' or 'ls' changed */
if (curwin->w_curswant != MAXCOL
&& (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
curwin->w_set_curswant = TRUE;
check_redraw(options[opt_idx].flags);
- return errmsg;
+ return (char *)errmsg;
+}
+
+static void trigger_optionsset_string(int opt_idx, int opt_flags,
+ char *oldval, char *newval)
+{
+ // Don't do this recursively.
+ if (oldval != NULL
+ && newval != NULL
+ && *get_vim_var_str(VV_OPTION_TYPE) == NUL) {
+ char buf_type[7];
+
+ vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s",
+ (opt_flags & OPT_LOCAL) ? "local" : "global");
+ set_vim_var_string(VV_OPTION_OLD, oldval, -1);
+ set_vim_var_string(VV_OPTION_NEW, newval, -1);
+ set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
+ apply_autocmds(EVENT_OPTIONSET,
+ (char_u *)options[opt_idx].fullname, NULL, false, NULL);
+ reset_v_option_vars();
+ }
}
/*
@@ -4297,17 +4486,24 @@ static void check_redraw(uint32_t flags)
bool doclear = (flags & P_RCLR) == P_RCLR;
bool all = ((flags & P_RALL) == P_RALL || doclear);
- if ((flags & P_RSTAT) || all) /* mark all status lines dirty */
+ if ((flags & P_RSTAT) || all) { // mark all status lines dirty
status_redraw_all();
+ }
- if ((flags & P_RBUF) || (flags & P_RWIN) || all)
+ if ((flags & P_RBUF) || (flags & P_RWIN) || all) {
changed_window_setting();
- if (flags & P_RBUF)
+ }
+ if (flags & P_RBUF) {
redraw_curbuf_later(NOT_VALID);
- if (doclear)
+ }
+ if (flags & P_RWINONLY) {
+ redraw_later(NOT_VALID);
+ }
+ if (doclear) {
redraw_all_later(CLEAR);
- else if (all)
+ } else if (all) {
redraw_all_later(NOT_VALID);
+ }
}
/// Find index for named option
@@ -4316,39 +4512,36 @@ static void check_redraw(uint32_t flags)
/// @param[in] len Length of the option.
///
/// @return Index of the option or -1 if option was not found.
-int findoption_len(const char_u *const arg, const size_t len)
+int findoption_len(const char *const arg, const size_t len)
{
- char *s, *p;
+ const char *s;
+ const char *p;
static int quick_tab[27] = { 0, 0 }; // quick access table
- int is_term_opt;
- /*
- * For first call: Initialize the quick-access table.
- * It contains the index for the first option that starts with a certain
- * letter. There are 26 letters, plus the first "t_" option.
- */
+ // For first call: Initialize the quick-access table.
+ // It contains the index for the first option that starts with a certain
+ // letter. There are 26 letters, plus the first "t_" option.
if (quick_tab[1] == 0) {
p = options[0].fullname;
for (short int i = 1; (s = options[i].fullname) != NULL; i++) {
if (s[0] != p[0]) {
- if (s[0] == 't' && s[1] == '_')
+ if (s[0] == 't' && s[1] == '_') {
quick_tab[26] = i;
- else
+ } else {
quick_tab[CharOrdLow(s[0])] = i;
+ }
}
p = s;
}
}
- /*
- * Check for name starting with an illegal character.
- */
+ // Check for name starting with an illegal character.
if (len == 0 || arg[0] < 'a' || arg[0] > 'z') {
return -1;
}
int opt_idx;
- is_term_opt = (len > 2 && arg[0] == 't' && arg[1] == '_');
+ const bool is_term_opt = (len > 2 && arg[0] == 't' && arg[1] == '_');
if (is_term_opt) {
opt_idx = quick_tab[26];
} else {
@@ -4356,7 +4549,7 @@ int findoption_len(const char_u *const arg, const size_t len)
}
// Match full name
for (; (s = options[opt_idx].fullname) != NULL; opt_idx++) {
- if (STRNCMP(arg, s, len) == 0 && s[len] == NUL) {
+ if (strncmp(arg, s, len) == 0 && s[len] == NUL) {
break;
}
}
@@ -4365,26 +4558,32 @@ int findoption_len(const char_u *const arg, const size_t len)
// Match short name
for (; options[opt_idx].fullname != NULL; opt_idx++) {
s = options[opt_idx].shortname;
- if (s != NULL && STRNCMP(arg, s, len) == 0 && s[len] == NUL) {
+ if (s != NULL && strncmp(arg, s, len) == 0 && s[len] == NUL) {
break;
}
s = NULL;
}
}
- if (s == NULL)
+ if (s == NULL) {
opt_idx = -1;
+ }
return opt_idx;
}
-bool is_tty_option(char *name)
+bool is_tty_option(const char *name)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return (name[0] == 't' && name[1] == '_') || !strcmp((char *)name, "term");
+ return (name[0] == 't' && name[1] == '_')
+ || strequal(name, "term")
+ || strequal(name, "ttytype");
}
#define TCO_BUFFER_SIZE 8
+/// @param name TUI-related option
+/// @param[out,allocated] value option string value
bool get_tty_option(char *name, char **value)
{
- if (!strcmp(name, "t_Co")) {
+ if (strequal(name, "t_Co")) {
if (value) {
if (t_colors <= 1) {
*value = xstrdup("");
@@ -4396,9 +4595,16 @@ bool get_tty_option(char *name, char **value)
return true;
}
- if (!strcmp(name, "term") || !strcmp(name, "ttytype")) {
+ if (strequal(name, "term")) {
if (value) {
- *value = xstrdup("nvim");
+ *value = p_term ? xstrdup(p_term) : xstrdup("nvim");
+ }
+ return true;
+ }
+
+ if (strequal(name, "ttytype")) {
+ if (value) {
+ *value = p_ttytype ? xstrdup(p_ttytype) : xstrdup("nvim");
}
return true;
}
@@ -4414,51 +4620,49 @@ bool get_tty_option(char *name, char **value)
return false;
}
-bool set_tty_option(char *name, char *value)
+bool set_tty_option(const char *name, char *value)
{
- if (!strcmp(name, "t_Co")) {
- int colors = atoi(value);
-
- // Only reinitialize colors if t_Co value has really changed to
- // avoid expensive reload of colorscheme if t_Co is set to the
- // same value multiple times
- if (colors != t_colors) {
- t_colors = colors;
- // We now have a different color setup, initialize it again.
- init_highlight(TRUE, FALSE);
+ if (strequal(name, "term")) {
+ if (p_term) {
+ xfree(p_term);
}
+ p_term = value;
+ return true;
+ }
+ if (strequal(name, "ttytype")) {
+ if (p_ttytype) {
+ xfree(p_ttytype);
+ }
+ p_ttytype = value;
return true;
}
- return is_tty_option(name) || !strcmp(name, "term")
- || !strcmp(name, "ttytype");
+ return false;
}
-/*
- * Find index for option 'arg'.
- * Return -1 if not found.
- */
-static int findoption(char_u *arg)
+/// Find index for an option
+///
+/// @param[in] arg Option name.
+///
+/// @return Option index or -1 if option was not found.
+static int findoption(const char *const arg)
{
- return findoption_len(arg, STRLEN(arg));
+ return findoption_len(arg, strlen(arg));
}
-/*
- * Get the value for an option.
- *
- * Returns:
- * Number or Toggle option: 1, *numval gets value.
- * String option: 0, *stringval gets allocated string.
- * Hidden Number or Toggle option: -1.
- * hidden String option: -2.
- * unknown option: -3.
- */
-int
-get_option_value (
+/// Gets the value for an option.
+///
+/// @returns:
+/// Number or Toggle option: 1, *numval gets value.
+/// String option: 0, *stringval gets allocated string.
+/// Hidden Number or Toggle option: -1.
+/// hidden String option: -2.
+/// unknown option: -3.
+int get_option_value(
char_u *name,
long *numval,
- char_u **stringval, /* NULL when only checking existence */
+ char_u **stringval, ///< NULL when only checking existence
int opt_flags
)
{
@@ -4466,35 +4670,36 @@ get_option_value (
return 0;
}
- int opt_idx;
- char_u *varp;
-
- opt_idx = findoption(name);
- if (opt_idx < 0) /* unknown option */
+ int opt_idx = findoption((const char *)name);
+ if (opt_idx < 0) { // Unknown option.
return -3;
+ }
- varp = get_varp_scope(&(options[opt_idx]), opt_flags);
+ char_u *varp = get_varp_scope(&(options[opt_idx]), opt_flags);
if (options[opt_idx].flags & P_STRING) {
- if (varp == NULL) /* hidden option */
+ if (varp == NULL) { // hidden option
return -2;
+ }
if (stringval != NULL) {
*stringval = vim_strsave(*(char_u **)(varp));
}
return 0;
}
- if (varp == NULL) /* hidden option */
+ if (varp == NULL) { // hidden option
return -1;
- if (options[opt_idx].flags & P_NUM)
+ }
+ if (options[opt_idx].flags & P_NUM) {
*numval = *(long *)varp;
- else {
- /* Special case: 'modified' is b_changed, but we also want to consider
- * it set when 'ff' or 'fenc' changed. */
- if ((bool *)varp == &curbuf->b_changed)
+ } else {
+ // Special case: 'modified' is b_changed, but we also want to consider
+ // it set when 'ff' or 'fenc' changed.
+ if ((int *)varp == &curbuf->b_changed) {
*numval = curbufIsChanged();
- else
- *numval = *(int *)varp;
+ } else {
+ *numval = (long) *(int *)varp; // NOLINT(whitespace/cast)
+ }
}
return 1;
}
@@ -4507,7 +4712,7 @@ get_option_value (
//
// Pretends that option is absent if it is not present in the requested scope
// (i.e. has no global, window-local or buffer-local value depending on
-// opt_type). Uses
+// opt_type).
//
// Returned flags:
// 0 hidden or unknown option, also option that does not have requested
@@ -4526,14 +4731,13 @@ int get_option_value_strict(char *name,
}
char_u *varp = NULL;
- vimoption_T *p;
int rv = 0;
- int opt_idx = findoption((uint8_t *)name);
+ int opt_idx = findoption(name);
if (opt_idx < 0) {
return 0;
}
- p = &(options[opt_idx]);
+ vimoption_T *p = &options[opt_idx];
// Hidden option
if (p->var == NULL) {
@@ -4549,26 +4753,25 @@ int get_option_value_strict(char *name,
}
if (p->indir == PV_NONE) {
- if (opt_type == SREQ_GLOBAL)
+ if (opt_type == SREQ_GLOBAL) {
rv |= SOPT_GLOBAL;
- else
- return 0; // Did not request global-only option
+ } else {
+ return 0; // Did not request global-only option
+ }
} else {
if (p->indir & PV_BOTH) {
rv |= SOPT_GLOBAL;
- } else if (opt_type == SREQ_GLOBAL) {
- return 0; // Requested global option
}
if (p->indir & PV_WIN) {
if (opt_type == SREQ_BUF) {
- return 0; // Did not request window-local option
+ return 0; // Requested buffer-local, not window-local option
} else {
rv |= SOPT_WIN;
}
} else if (p->indir & PV_BUF) {
if (opt_type == SREQ_WIN) {
- return 0; // Did not request buffer-local option
+ return 0; // Requested window-local, not buffer-local option
} else {
rv |= SOPT_BUF;
}
@@ -4580,24 +4783,31 @@ int get_option_value_strict(char *name,
}
if (opt_type == SREQ_GLOBAL) {
- varp = p->var;
+ if (p->var == VAR_WIN) {
+ return 0;
+ } else {
+ varp = p->var;
+ }
} else {
if (opt_type == SREQ_BUF) {
// Special case: 'modified' is b_changed, but we also want to
// consider it set when 'ff' or 'fenc' changed.
if (p->indir == PV_MOD) {
- *numval = bufIsChanged((buf_T *) from);
+ *numval = bufIsChanged((buf_T *)from);
varp = NULL;
} else {
- aco_save_T aco;
- aucmd_prepbuf(&aco, (buf_T *) from);
+ buf_T *save_curbuf = curbuf;
+
+ // only getting a pointer, no need to use aucmd_prepbuf()
+ curbuf = (buf_T *)from;
+ curwin->w_buffer = curbuf;
varp = get_varp(p);
- aucmd_restbuf(&aco);
+ curbuf = save_curbuf;
+ curwin->w_buffer = curbuf;
}
} else if (opt_type == SREQ_WIN) {
- win_T *save_curwin;
- save_curwin = curwin;
- curwin = (win_T *) from;
+ win_T *save_curwin = curwin;
+ curwin = (win_T *)from;
curbuf = curwin->w_buffer;
varp = get_varp(p);
curwin = save_curwin;
@@ -4622,31 +4832,29 @@ int get_option_value_strict(char *name,
return rv;
}
-/*
- * Set the value of option "name".
- * Use "string" for string options, use "number" for other options.
- *
- * Returns NULL on success or error message on error.
- */
-char_u *
-set_option_value (
- char_u *name,
- long number,
- char_u *string,
- int opt_flags /* OPT_LOCAL or 0 (both) */
-)
+/// Set the value of an option
+///
+/// @param[in] name Option name.
+/// @param[in] number New value for the number or boolean option.
+/// @param[in] string New value for string option.
+/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both).
+///
+/// @return NULL on success, error message on error.
+char *set_option_value(const char *const name, const long number,
+ const char *const string, const int opt_flags)
+ FUNC_ATTR_NONNULL_ARG(1)
{
- if (set_tty_option((char *)name, (char *)string)) {
- return NULL;
+ if (is_tty_option(name)) {
+ return NULL; // Fail silently; many old vimrcs set t_xx options.
}
int opt_idx;
char_u *varp;
opt_idx = findoption(name);
- if (opt_idx < 0)
+ if (opt_idx < 0) {
EMSG2(_("E355: Unknown option: %s"), name);
- else {
+ } else {
uint32_t flags = options[opt_idx].flags;
// Disallow changing some options in the sandbox
if (sandbox > 0 && (flags & P_SECURE)) {
@@ -4654,11 +4862,11 @@ set_option_value (
return NULL;
}
if (flags & P_STRING) {
- const char *s = (const char *)string;
+ const char *s = string;
if (s == NULL) {
s = "";
}
- return (char_u *)set_string_option(opt_idx, s, opt_flags);
+ return set_string_option(opt_idx, s, opt_flags);
} else {
varp = get_varp_scope(&(options[opt_idx]), opt_flags);
if (varp != NULL) { /* hidden option is not changed */
@@ -4677,28 +4885,17 @@ set_option_value (
return NULL; // do nothing as we hit an error
}
}
- if (flags & P_NUM)
- return set_num_option(opt_idx, varp, number,
- NULL, 0, opt_flags);
- else
- return set_bool_option(opt_idx, varp, (int)number,
- opt_flags);
+ if (flags & P_NUM) {
+ return set_num_option(opt_idx, varp, number, NULL, 0, opt_flags);
+ } else {
+ return set_bool_option(opt_idx, varp, (int)number, opt_flags);
+ }
}
}
}
return NULL;
}
-char_u *get_highlight_default(void)
-{
- int i;
-
- i = findoption((char_u *)"hl");
- if (i >= 0)
- return options[i].def_val[VI_DEFAULT];
- return (char_u *)NULL;
-}
-
/*
* Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number.
*/
@@ -4714,7 +4911,7 @@ int find_key_option_len(const char_u *arg, size_t len)
} else {
arg--; // put arg at the '<'
modifiers = 0;
- key = find_special_key(&arg, len + 1, &modifiers, true, true);
+ key = find_special_key(&arg, len + 1, &modifiers, true, true, false);
if (modifiers) { // can't handle modifiers here
key = 0;
}
@@ -4727,7 +4924,6 @@ static int find_key_option(const char_u *arg)
return find_key_option_len(arg, STRLEN(arg));
}
-
/*
* if 'all' == 0: show changed options
* if 'all' == 1: show all normal options
@@ -4753,15 +4949,14 @@ showoptions (
vimoption_T **items = xmalloc(sizeof(vimoption_T *) * PARAM_COUNT);
- /* Highlight title */
- if (all == 2)
- MSG_PUTS_TITLE(_("\n--- Terminal codes ---"));
- else if (opt_flags & OPT_GLOBAL)
+ // Highlight title
+ if (opt_flags & OPT_GLOBAL) {
MSG_PUTS_TITLE(_("\n--- Global option values ---"));
- else if (opt_flags & OPT_LOCAL)
+ } else if (opt_flags & OPT_LOCAL) {
MSG_PUTS_TITLE(_("\n--- Local option values ---"));
- else
+ } else {
MSG_PUTS_TITLE(_("\n--- Options ---"));
+ }
/*
* do the loop two times:
@@ -4836,14 +5031,39 @@ static int optval_default(vimoption_T *p, char_u *varp)
if (varp == NULL)
return TRUE; /* hidden option is always at default */
dvi = ((p->flags & P_VI_DEF) || p_cp) ? VI_DEFAULT : VIM_DEFAULT;
- if (p->flags & P_NUM)
- return *(long *)varp == (long)p->def_val[dvi];
- if (p->flags & P_BOOL)
+ if (p->flags & P_NUM) {
+ return *(long *)varp == (long)(intptr_t)p->def_val[dvi];
+ }
+ if (p->flags & P_BOOL) {
return *(int *)varp == (int)(intptr_t)p->def_val[dvi];
- /* P_STRING */
+ }
+ // P_STRING
return STRCMP(*(char_u **)varp, p->def_val[dvi]) == 0;
}
+/// Send update to UIs with values of UI relevant options
+void ui_refresh_options(void)
+{
+ for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
+ uint32_t flags = options[opt_idx].flags;
+ if (!(flags & P_UI_OPTION)) {
+ continue;
+ }
+ String name = cstr_as_string(options[opt_idx].fullname);
+ void *varp = options[opt_idx].var;
+ Object value = OBJECT_INIT;
+ if (flags & P_BOOL) {
+ value = BOOLEAN_OBJ(*(int *)varp);
+ } else if (flags & P_NUM) {
+ value = INTEGER_OBJ(*(long *)varp);
+ } else if (flags & P_STRING) {
+ // cstr_as_string handles NULL string
+ value = STRING_OBJ(cstr_as_string(*(char **)varp));
+ }
+ ui_call_option_set(name, value);
+ }
+}
+
/*
* showoneopt: show the value of one option
* must not be called with a hidden option!
@@ -4862,14 +5082,15 @@ showoneopt (
varp = get_varp_scope(p, opt_flags);
- /* for 'modified' we also need to check if 'ff' or 'fenc' changed. */
- if ((p->flags & P_BOOL) && ((bool *)varp == &curbuf->b_changed
- ? !curbufIsChanged() : !*(bool *)varp))
+ // for 'modified' we also need to check if 'ff' or 'fenc' changed.
+ if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed
+ ? !curbufIsChanged() : !*(int *)varp)) {
MSG_PUTS("no");
- else if ((p->flags & P_BOOL) && *(int *)varp < 0)
+ } else if ((p->flags & P_BOOL) && *(int *)varp < 0) {
MSG_PUTS("--");
- else
+ } else {
MSG_PUTS(" ");
+ }
MSG_PUTS(p->fullname);
if (!(p->flags & P_BOOL)) {
msg_putchar('=');
@@ -5040,9 +5261,13 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, int e
* CTRL-V or backslash */
if (valuep == &p_pt) {
s = *valuep;
- while (*s != NUL)
- if (put_escstr(fd, str2special(&s, FALSE), 2) == FAIL)
+ while (*s != NUL) {
+ if (put_escstr(fd, (char_u *)str2special((const char **)&s, false,
+ false), 2)
+ == FAIL) {
return FAIL;
+ }
+ }
} else if (expand) {
buf = xmalloc(MAXPATHL);
home_replace(NULL, *valuep, buf, MAXPATHL, FALSE);
@@ -5097,7 +5322,7 @@ static int put_setbool(FILE *fd, char *cmd, char *name, int value)
void comp_col(void)
{
- int last_has_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
+ int last_has_status = (p_ls == 2 || (p_ls == 1 && !ONE_WINDOW));
sc_col = 0;
ru_col = 0;
@@ -5132,7 +5357,7 @@ void unset_global_local_option(char *name, void *from)
vimoption_T *p;
buf_T *buf = (buf_T *)from;
- int opt_idx = findoption((uint8_t *)name);
+ int opt_idx = findoption(name);
if (opt_idx < 0) {
EMSG2(_("E355: Unknown option: %s"), name);
return;
@@ -5177,6 +5402,9 @@ void unset_global_local_option(char *name, void *from)
case PV_TSR:
clear_string_option(&buf->b_p_tsr);
break;
+ case PV_FP:
+ clear_string_option(&buf->b_p_fp);
+ break;
case PV_EFM:
clear_string_option(&buf->b_p_efm);
break;
@@ -5195,6 +5423,9 @@ void unset_global_local_option(char *name, void *from)
case PV_LW:
clear_string_option(&buf->b_p_lw);
break;
+ case PV_MENC:
+ clear_string_option(&buf->b_p_menc);
+ break;
}
}
@@ -5210,6 +5441,7 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
}
if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
switch ((int)p->indir) {
+ case PV_FP: return (char_u *)&(curbuf->b_p_fp);
case PV_EFM: return (char_u *)&(curbuf->b_p_efm);
case PV_GP: return (char_u *)&(curbuf->b_p_gp);
case PV_MP: return (char_u *)&(curbuf->b_p_mp);
@@ -5227,6 +5459,7 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
case PV_UL: return (char_u *)&(curbuf->b_p_ul);
case PV_LW: return (char_u *)&(curbuf->b_p_lw);
case PV_BKC: return (char_u *)&(curbuf->b_p_bkc);
+ case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
}
return NULL; /* "cannot happen" */
}
@@ -5268,6 +5501,8 @@ static char_u *get_varp(vimoption_T *p)
? (char_u *)&(curbuf->b_p_dict) : p->var;
case PV_TSR: return *curbuf->b_p_tsr != NUL
? (char_u *)&(curbuf->b_p_tsr) : p->var;
+ case PV_FP: return *curbuf->b_p_fp != NUL
+ ? (char_u *)&(curbuf->b_p_fp) : p->var;
case PV_EFM: return *curbuf->b_p_efm != NUL
? (char_u *)&(curbuf->b_p_efm) : p->var;
case PV_GP: return *curbuf->b_p_gp != NUL
@@ -5280,6 +5515,8 @@ static char_u *get_varp(vimoption_T *p)
? (char_u *)&(curbuf->b_p_ul) : p->var;
case PV_LW: return *curbuf->b_p_lw != NUL
? (char_u *)&(curbuf->b_p_lw) : p->var;
+ case PV_MENC: return *curbuf->b_p_menc != NUL
+ ? (char_u *)&(curbuf->b_p_menc) : p->var;
case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
case PV_LIST: return (char_u *)&(curwin->w_p_list);
@@ -5322,6 +5559,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_BH: return (char_u *)&(curbuf->b_p_bh);
case PV_BT: return (char_u *)&(curbuf->b_p_bt);
case PV_BL: return (char_u *)&(curbuf->b_p_bl);
+ case PV_CHANNEL:return (char_u *)&(curbuf->b_p_channel);
case PV_CI: return (char_u *)&(curbuf->b_p_ci);
case PV_CIN: return (char_u *)&(curbuf->b_p_cin);
case PV_CINK: return (char_u *)&(curbuf->b_p_cink);
@@ -5357,6 +5595,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_PI: return (char_u *)&(curbuf->b_p_pi);
case PV_QE: return (char_u *)&(curbuf->b_p_qe);
case PV_RO: return (char_u *)&(curbuf->b_p_ro);
+ case PV_SCBK: return (char_u *)&(curbuf->b_p_scbk);
case PV_SI: return (char_u *)&(curbuf->b_p_si);
case PV_STS: return (char_u *)&(curbuf->b_p_sts);
case PV_SUA: return (char_u *)&(curbuf->b_p_sua);
@@ -5372,7 +5611,9 @@ static char_u *get_varp(vimoption_T *p)
case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
case PV_WM: return (char_u *)&(curbuf->b_p_wm);
case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
- default: EMSG(_("E356: get_varp ERROR"));
+ case PV_SCL: return (char_u *)&(curwin->w_p_scl);
+ case PV_WINHL: return (char_u *)&(curwin->w_p_winhl);
+ default: IEMSG(_("E356: get_varp ERROR"));
}
/* always return a valid pointer to avoid a crash! */
return (char_u *)&(curbuf->b_p_wm);
@@ -5398,7 +5639,6 @@ void win_copy_options(win_T *wp_from, win_T *wp_to)
copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
/* Is this right? */
wp_to->w_farsi = wp_from->w_farsi;
- briopt_check(wp_to);
}
/*
@@ -5449,7 +5689,9 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_fde = vim_strsave(from->wo_fde);
to->wo_fdt = vim_strsave(from->wo_fdt);
to->wo_fmr = vim_strsave(from->wo_fmr);
- check_winopt(to); /* don't want NULL pointers */
+ to->wo_scl = vim_strsave(from->wo_scl);
+ to->wo_winhl = vim_strsave(from->wo_winhl);
+ check_winopt(to); // don't want NULL pointers
}
/*
@@ -5472,11 +5714,13 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_fde);
check_string_option(&wop->wo_fdt);
check_string_option(&wop->wo_fmr);
+ check_string_option(&wop->wo_scl);
check_string_option(&wop->wo_rlc);
check_string_option(&wop->wo_stl);
check_string_option(&wop->wo_cc);
check_string_option(&wop->wo_cocu);
check_string_option(&wop->wo_briopt);
+ check_string_option(&wop->wo_winhl);
}
/*
@@ -5490,13 +5734,23 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_fde);
clear_string_option(&wop->wo_fdt);
clear_string_option(&wop->wo_fmr);
+ clear_string_option(&wop->wo_scl);
clear_string_option(&wop->wo_rlc);
clear_string_option(&wop->wo_stl);
clear_string_option(&wop->wo_cc);
clear_string_option(&wop->wo_cocu);
clear_string_option(&wop->wo_briopt);
+ clear_string_option(&wop->wo_winhl);
+}
+
+void didset_window_options(win_T *wp)
+{
+ check_colorcolumn(wp);
+ briopt_check(wp);
+ parse_winhl_opt(wp);
}
+
/*
* Copy global option values to local options for one buffer.
* Used when creating a new buffer and sometimes when entering a buffer.
@@ -5514,12 +5768,6 @@ void buf_copy_options(buf_T *buf, int flags)
int did_isk = FALSE;
/*
- * Don't do anything if the buffer is invalid.
- */
- if (buf == NULL || !buf_valid(buf))
- return;
-
- /*
* Skip this when the option defaults have not been set yet. Happens when
* main() allocates the first buffer.
*/
@@ -5560,15 +5808,34 @@ void buf_copy_options(buf_T *buf, int flags)
free_buf_options(buf, TRUE);
buf->b_p_ro = FALSE; /* don't copy readonly */
buf->b_p_fenc = vim_strsave(p_fenc);
- buf->b_p_ff = vim_strsave(p_ff);
+ switch (*p_ffs) {
+ case 'm': {
+ buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
+ break;
+ }
+ case 'd': {
+ buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
+ break;
+ }
+ case 'u': {
+ buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
+ break;
+ }
+ default: {
+ buf->b_p_ff = vim_strsave(p_ff);
+ break;
+ }
+ }
buf->b_p_bh = empty_option;
buf->b_p_bt = empty_option;
- } else
- free_buf_options(buf, FALSE);
+ } else {
+ free_buf_options(buf, false);
+ }
buf->b_p_ai = p_ai;
buf->b_p_ai_nopaste = p_ai_nopaste;
buf->b_p_sw = p_sw;
+ buf->b_p_scbk = -1;
buf->b_p_tw = p_tw;
buf->b_p_tw_nopaste = p_tw_nopaste;
buf->b_p_tw_nobin = p_tw_nobin;
@@ -5584,7 +5851,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_ml = p_ml;
buf->b_p_ml_nobin = p_ml_nobin;
buf->b_p_inf = p_inf;
- buf->b_p_swf = p_swf;
+ buf->b_p_swf = cmdmod.noswapfile ? false : p_swf;
buf->b_p_cpt = vim_strsave(p_cpt);
buf->b_p_cfu = vim_strsave(p_cfu);
buf->b_p_ofu = vim_strsave(p_ofu);
@@ -5597,6 +5864,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_nf = vim_strsave(p_nf);
buf->b_p_mps = vim_strsave(p_mps);
buf->b_p_si = p_si;
+ buf->b_p_channel = 0;
buf->b_p_ci = p_ci;
buf->b_p_cin = p_cin;
buf->b_p_cink = vim_strsave(p_cink);
@@ -5616,6 +5884,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_s.b_p_spl = vim_strsave(p_spl);
buf->b_p_inde = vim_strsave(p_inde);
buf->b_p_indk = vim_strsave(p_indk);
+ buf->b_p_fp = empty_option;
buf->b_p_fex = vim_strsave(p_fex);
buf->b_p_sua = vim_strsave(p_sua);
buf->b_p_keymap = vim_strsave(p_keymap);
@@ -5648,6 +5917,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_qe = vim_strsave(p_qe);
buf->b_p_udf = p_udf;
buf->b_p_lw = empty_option;
+ buf->b_p_menc = empty_option;
/*
* Don't copy the options set by ex_help(), use the saved values,
@@ -5688,11 +5958,12 @@ void reset_modifiable(void)
{
int opt_idx;
- curbuf->b_p_ma = FALSE;
- p_ma = FALSE;
- opt_idx = findoption((char_u *)"ma");
- if (opt_idx >= 0)
- options[opt_idx].def_val[VI_DEFAULT] = FALSE;
+ curbuf->b_p_ma = false;
+ p_ma = false;
+ opt_idx = findoption("ma");
+ if (opt_idx >= 0) {
+ options[opt_idx].def_val[VI_DEFAULT] = false;
+ }
}
/*
@@ -5790,15 +6061,15 @@ set_context_in_set_cmd (
expand_option_name[2] = p[-2];
expand_option_name[3] = p[-1];
} else {
- /* Allow * wildcard */
- while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*')
+ // Allow * wildcard.
+ while (ASCII_ISALNUM(*p) || *p == '_' || *p == '*') {
p++;
- if (*p == NUL)
+ }
+ if (*p == NUL) {
return;
+ }
nextchar = *p;
- *p = NUL;
- opt_idx = findoption(arg);
- *p = nextchar;
+ opt_idx = findoption_len((const char *)arg, (size_t)(p - arg));
if (opt_idx == -1 || options[opt_idx].var == NULL) {
xp->xp_context = EXPAND_NOTHING;
return;
@@ -5820,7 +6091,7 @@ set_context_in_set_cmd (
xp->xp_context = EXPAND_UNSUCCESSFUL;
return;
}
- if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL) {
+ if (p[1] == NUL) {
xp->xp_context = EXPAND_OLD_SETTING;
if (is_term_option)
expand_option_idx = -1;
@@ -5895,8 +6166,8 @@ int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***
int count = 0;
char_u *str;
int loop;
- static char *(names[]) = {"all", "termcap"};
- int ic = regmatch->rm_ic; /* remember the ignore-case flag */
+ static char *(names[]) = { "all" };
+ int ic = regmatch->rm_ic; // remember the ignore-case flag
/* do this loop twice:
* loop == 0: count the number of matching options
@@ -5960,30 +6231,33 @@ void ExpandOldSetting(int *num_file, char_u ***file)
* For a terminal key code expand_option_idx is < 0.
*/
if (expand_option_idx < 0) {
- expand_option_idx = findoption(expand_option_name);
+ expand_option_idx = findoption((const char *)expand_option_name);
}
if (expand_option_idx >= 0) {
- /* put string of option value in NameBuff */
+ // Put string of option value in NameBuff.
option_value2string(&options[expand_option_idx], expand_option_flags);
var = NameBuff;
- } else if (var == NULL)
+ } else {
var = (char_u *)"";
+ }
- /* A backslash is required before some characters. This is the reverse of
- * what happens in do_set(). */
+ // A backslash is required before some characters. This is the reverse of
+ // what happens in do_set().
char_u *buf = vim_strsave_escaped(var, escape_chars);
#ifdef BACKSLASH_IN_FILENAME
/* For MS-Windows et al. we don't double backslashes at the start and
* before a file name character. */
- for (var = buf; *var != NUL; mb_ptr_adv(var))
+ for (var = buf; *var != NUL; MB_PTR_ADV(var)) {
if (var[0] == '\\' && var[1] == '\\'
&& expand_option_idx >= 0
&& (options[expand_option_idx].flags & P_EXPAND)
&& vim_isfilec(var[2])
- && (var[2] != '\\' || (var == buf && var[4] != '\\')))
+ && (var[2] != '\\' || (var == buf && var[4] != '\\'))) {
STRMOVE(var, var + 1);
+ }
+ }
#endif
*file[0] = buf;
@@ -6019,15 +6293,16 @@ option_value2string (
}
} else { // P_STRING
varp = *(char_u **)(varp);
- if (varp == NULL) /* just in case */
+ if (varp == NULL) { // Just in case.
NameBuff[0] = NUL;
- else if (opp->flags & P_EXPAND)
- home_replace(NULL, varp, NameBuff, MAXPATHL, FALSE);
- /* Translate 'pastetoggle' into special key names */
- else if ((char_u **)opp->var == &p_pt)
- str2specialbuf(p_pt, NameBuff, MAXPATHL);
- else
+ } else if (opp->flags & P_EXPAND) {
+ home_replace(NULL, varp, NameBuff, MAXPATHL, false);
+ // Translate 'pastetoggle' into special key names.
+ } else if ((char_u **)opp->var == &p_pt) {
+ str2specialbuf((const char *)p_pt, (char *)NameBuff, MAXPATHL);
+ } else {
STRLCPY(NameBuff, varp, MAXPATHL);
+ }
}
}
@@ -6150,9 +6425,10 @@ static void langmap_set(void)
for (p = p_langmap; p[0] != NUL; ) {
for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';';
- mb_ptr_adv(p2)) {
- if (p2[0] == '\\' && p2[1] != NUL)
- ++p2;
+ MB_PTR_ADV(p2)) {
+ if (p2[0] == '\\' && p2[1] != NUL) {
+ p2++;
+ }
}
if (p2[0] == ';')
++p2; /* abcd;ABCD form, p2 points to A */
@@ -6163,22 +6439,25 @@ static void langmap_set(void)
++p;
break;
}
- if (p[0] == '\\' && p[1] != NUL)
- ++p;
- from = (*mb_ptr2char)(p);
+ if (p[0] == '\\' && p[1] != NUL) {
+ p++;
+ }
+ from = utf_ptr2char(p);
to = NUL;
if (p2 == NULL) {
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
if (p[0] != ',') {
- if (p[0] == '\\')
- ++p;
- to = (*mb_ptr2char)(p);
+ if (p[0] == '\\') {
+ p++;
+ }
+ to = utf_ptr2char(p);
}
} else {
if (p2[0] != ',') {
- if (p2[0] == '\\')
- ++p2;
- to = (*mb_ptr2char)(p2);
+ if (p2[0] == '\\') {
+ p2++;
+ }
+ to = utf_ptr2char(p2);
}
}
if (to == NUL) {
@@ -6194,10 +6473,10 @@ static void langmap_set(void)
langmap_mapchar[from & 255] = (char_u)to;
}
- /* Advance to next pair */
- mb_ptr_adv(p);
+ // Advance to next pair
+ MB_PTR_ADV(p);
if (p2 != NULL) {
- mb_ptr_adv(p2);
+ MB_PTR_ADV(p2);
if (*p == ';') {
p = p2;
if (p[0] != NUL) {
@@ -6343,15 +6622,13 @@ static void paste_option_changed(void)
/// When "fname" is not NULL, use it to set $"envname" when it wasn't set yet.
void vimrc_found(char_u *fname, char_u *envname)
{
- char_u *p;
-
- if (fname != NULL) {
- p = (char_u *)vim_getenv((char *)envname);
+ if (fname != NULL && envname != NULL) {
+ char *p = vim_getenv((char *)envname);
if (p == NULL) {
- /* Set $MYVIMRC to the first vimrc file found. */
- p = (char_u *)FullName_save((char *)fname, FALSE);
+ // Set $MYVIMRC to the first vimrc file found.
+ p = FullName_save((char *)fname, false);
if (p != NULL) {
- vim_setenv((char *)envname, (char *)p);
+ vim_setenv((char *)envname, p);
xfree(p);
}
} else {
@@ -6360,20 +6637,34 @@ void vimrc_found(char_u *fname, char_u *envname)
}
}
-/*
- * Return TRUE when option "name" has been set.
- * Only works correctly for global options.
- */
-int option_was_set(char_u *name)
+/// Check whether global option has been set
+///
+/// @param[in] name Option name.
+///
+/// @return True if it was set.
+bool option_was_set(const char *name)
{
int idx;
idx = findoption(name);
- if (idx < 0) /* unknown option */
- return FALSE;
- if (options[idx].flags & P_WAS_SET)
- return TRUE;
- return FALSE;
+ if (idx < 0) { // Unknown option.
+ return false;
+ } else if (options[idx].flags & P_WAS_SET) {
+ return true;
+ }
+ return false;
+}
+
+/// Reset the flag indicating option "name" was set.
+///
+/// @param[in] name Option name.
+void reset_option_was_set(const char *name)
+{
+ const int idx = findoption(name);
+
+ if (idx >= 0) {
+ options[idx].flags &= ~P_WAS_SET;
+ }
}
/*
@@ -6574,10 +6865,8 @@ int get_sw_value(buf_T *buf)
return (int)result;
}
-/*
- * Return the effective softtabstop value for the current buffer, using the
- * 'tabstop' value when 'softtabstop' is negative.
- */
+// Return the effective softtabstop value for the current buffer,
+// using the effective shiftwidth value when 'softtabstop' is negative.
int get_sts_value(void)
{
long result = curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
@@ -6593,66 +6882,37 @@ int get_sts_value(void)
*/
void find_mps_values(int *initc, int *findc, int *backwards, int switchit)
{
- char_u *ptr;
+ char_u *ptr = curbuf->b_p_mps;
- ptr = curbuf->b_p_mps;
while (*ptr != NUL) {
- if (has_mbyte) {
- char_u *prev;
-
- if (mb_ptr2char(ptr) == *initc) {
- if (switchit) {
- *findc = *initc;
- *initc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
- *backwards = TRUE;
- } else {
- *findc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
- *backwards = FALSE;
- }
- return;
- }
- prev = ptr;
- ptr += mb_ptr2len(ptr) + 1;
- if (mb_ptr2char(ptr) == *initc) {
- if (switchit) {
- *findc = *initc;
- *initc = mb_ptr2char(prev);
- *backwards = FALSE;
- } else {
- *findc = mb_ptr2char(prev);
- *backwards = TRUE;
- }
- return;
- }
- ptr += mb_ptr2len(ptr);
- } else {
- if (*ptr == *initc) {
- if (switchit) {
- *backwards = TRUE;
- *findc = *initc;
- *initc = ptr[2];
- } else {
- *backwards = FALSE;
- *findc = ptr[2];
- }
- return;
+ if (utf_ptr2char(ptr) == *initc) {
+ if (switchit) {
+ *findc = *initc;
+ *initc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1);
+ *backwards = true;
+ } else {
+ *findc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1);
+ *backwards = false;
}
- ptr += 2;
- if (*ptr == *initc) {
- if (switchit) {
- *backwards = FALSE;
- *findc = *initc;
- *initc = ptr[-2];
- } else {
- *backwards = TRUE;
- *findc = ptr[-2];
- }
- return;
+ return;
+ }
+ char_u *prev = ptr;
+ ptr += utfc_ptr2len(ptr) + 1;
+ if (utf_ptr2char(ptr) == *initc) {
+ if (switchit) {
+ *findc = *initc;
+ *initc = utf_ptr2char(prev);
+ *backwards = false;
+ } else {
+ *findc = utf_ptr2char(prev);
+ *backwards = true;
}
- ++ptr;
+ return;
+ }
+ ptr += utfc_ptr2len(ptr);
+ if (*ptr == ',') {
+ ptr++;
}
- if (*ptr == ',')
- ++ptr;
}
}
@@ -6703,3 +6963,189 @@ unsigned int get_bkc_value(buf_T *buf)
{
return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
}
+
+/// Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
+int get_fileformat(buf_T *buf)
+{
+ int c = *buf->b_p_ff;
+
+ if (buf->b_p_bin || c == 'u') {
+ return EOL_UNIX;
+ }
+ if (c == 'm') {
+ return EOL_MAC;
+ }
+ return EOL_DOS;
+}
+
+/// Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
+/// argument.
+///
+/// @param eap can be NULL!
+int get_fileformat_force(buf_T *buf, exarg_T *eap)
+{
+ int c;
+
+ if (eap != NULL && eap->force_ff != 0) {
+ c = eap->cmd[eap->force_ff];
+ } else {
+ if ((eap != NULL && eap->force_bin != 0)
+ ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin) {
+ return EOL_UNIX;
+ }
+ c = *buf->b_p_ff;
+ }
+ if (c == 'u') {
+ return EOL_UNIX;
+ }
+ if (c == 'm') {
+ return EOL_MAC;
+ }
+ return EOL_DOS;
+}
+
+/// Return the default fileformat from 'fileformats'.
+int default_fileformat(void)
+{
+ switch (*p_ffs) {
+ case 'm': return EOL_MAC;
+ case 'd': return EOL_DOS;
+ }
+ return EOL_UNIX;
+}
+
+/// Set the current end-of-line type to EOL_UNIX, EOL_MAC, or EOL_DOS.
+///
+/// Sets 'fileformat'.
+///
+/// @param eol_style End-of-line style.
+/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+void set_fileformat(int eol_style, int opt_flags)
+{
+ char *p = NULL;
+
+ switch (eol_style) {
+ case EOL_UNIX:
+ p = FF_UNIX;
+ break;
+ case EOL_MAC:
+ p = FF_MAC;
+ break;
+ case EOL_DOS:
+ p = FF_DOS;
+ break;
+ }
+
+ // p is NULL if "eol_style" is EOL_UNKNOWN.
+ if (p != NULL) {
+ set_string_option_direct((char_u *)"ff",
+ -1,
+ (char_u *)p,
+ OPT_FREE | opt_flags,
+ 0);
+ }
+
+ // This may cause the buffer to become (un)modified.
+ check_status(curbuf);
+ redraw_tabline = true;
+ need_maketitle = true; // Set window title later.
+}
+
+/// Skip to next part of an option argument: skip space and comma
+char_u *skip_to_option_part(const char_u *p)
+{
+ if (*p == ',') {
+ p++;
+ }
+ while (*p == ' ') {
+ p++;
+ }
+ return (char_u *)p;
+}
+
+/// Isolate one part of a string option separated by `sep_chars`.
+///
+/// @param[in,out] option advanced to the next part
+/// @param[in,out] buf copy of the isolated part
+/// @param[in] maxlen length of `buf`
+/// @param[in] sep_chars chars that separate the option parts
+///
+/// @return length of `*option`
+size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen,
+ char *sep_chars)
+{
+ size_t len = 0;
+ char_u *p = *option;
+
+ // skip '.' at start of option part, for 'suffixes'
+ if (*p == '.') {
+ buf[len++] = *p++;
+ }
+ while (*p != NUL && vim_strchr((char_u *)sep_chars, *p) == NULL) {
+ // Skip backslash before a separator character and space.
+ if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL) {
+ p++;
+ }
+ if (len < maxlen - 1) {
+ buf[len++] = *p;
+ }
+ p++;
+ }
+ buf[len] = NUL;
+
+ if (*p != NUL && *p != ',') { // skip non-standard separator
+ p++;
+ }
+ p = skip_to_option_part(p); // p points to next file name
+
+ *option = p;
+ return len;
+}
+
+/// Return TRUE when 'shell' has "csh" in the tail.
+int csh_like_shell(void)
+{
+ return strstr((char *)path_tail(p_sh), "csh") != NULL;
+}
+
+/// Return true when window "wp" has a column to draw signs in.
+bool signcolumn_on(win_T *wp)
+{
+ if (*wp->w_p_scl == 'n') {
+ return false;
+ }
+ if (*wp->w_p_scl == 'y') {
+ return true;
+ }
+ return wp->w_buffer->b_signlist != NULL;
+}
+
+/// Get window or buffer local options
+dict_T *get_winbuf_options(const int bufopt)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ dict_T *const d = tv_dict_alloc();
+
+ for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
+ struct vimoption *opt = &options[opt_idx];
+
+ if ((bufopt && (opt->indir & PV_BUF))
+ || (!bufopt && (opt->indir & PV_WIN))) {
+ char_u *varp = get_varp(opt);
+
+ if (varp != NULL) {
+ if (opt->flags & P_STRING) {
+ tv_dict_add_str(d, opt->fullname, strlen(opt->fullname),
+ *(const char **)varp);
+ } else if (opt->flags & P_NUM) {
+ tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname),
+ *(long *)varp);
+ } else {
+ tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname), *(int *)varp);
+ }
+ }
+ }
+ }
+
+ return d;
+}
diff --git a/src/nvim/option.h b/src/nvim/option.h
index 5c2b2662b5..60f14dea44 100644
--- a/src/nvim/option.h
+++ b/src/nvim/option.h
@@ -1,22 +1,25 @@
#ifndef NVIM_OPTION_H
#define NVIM_OPTION_H
+#include "nvim/ex_cmds_defs.h" // for exarg_T
+
/* flags for buf_copy_options() */
#define BCO_ENTER 1 /* going to enter the buffer */
#define BCO_ALWAYS 2 /* always copy the options */
#define BCO_NOHELP 4 /* don't touch the help related options */
-/*
- * "flags" values for option-setting functions.
- * When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global
- * values, get local value.
- */
-#define OPT_FREE 1 /* free old value if it was allocated */
-#define OPT_GLOBAL 2 /* use global value */
-#define OPT_LOCAL 4 /* use local value */
-#define OPT_MODELINE 8 /* option in modeline */
-#define OPT_WINONLY 16 /* only set window-local options */
-#define OPT_NOWIN 32 /* don't set window-local options */
+/// Flags for option-setting functions
+///
+/// When OPT_GLOBAL and OPT_LOCAL are both missing, set both local and global
+/// values, get local value.
+typedef enum {
+ OPT_FREE = 1, ///< Free old value if it was allocated.
+ OPT_GLOBAL = 2, ///< Use global value.
+ OPT_LOCAL = 4, ///< Use local value.
+ OPT_MODELINE = 8, ///< Option in modeline.
+ OPT_WINONLY = 16, ///< Only set window-local options.
+ OPT_NOWIN = 32, ///< Don’t set window-local options.
+} OptionFlags;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "option.h.generated.h"
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index 8d6f42e088..7b99b6f266 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -1,10 +1,9 @@
#ifndef NVIM_OPTION_DEFS_H
#define NVIM_OPTION_DEFS_H
-#include <stdbool.h>
-
#include "nvim/types.h"
#include "nvim/macros.h" // For EXTERN
+#include "eval/typval.h" // For scid_T
// option_defs.h: definition of global variables for settable options
@@ -18,9 +17,9 @@
#define SOPT_UNSET 0x40 // Option does not have local value set
// Option types for various functions in option.c
-#define SREQ_GLOBAL 0 // Request global option
-#define SREQ_WIN 1 // Request window-local option
-#define SREQ_BUF 2 // Request buffer-local option
+#define SREQ_GLOBAL 0 // Request global option value
+#define SREQ_WIN 1 // Request window-local option value
+#define SREQ_BUF 2 // Request buffer-local option value
/*
* Default values for 'errorformat'.
@@ -83,57 +82,56 @@
#define DFLT_FO_VIM "tcqj"
#define FO_ALL "tcroq2vlb1mMBn,awj" /* for do_set() */
-/* characters for the p_cpo option: */
-#define CPO_ALTREAD 'a' /* ":read" sets alternate file name */
-#define CPO_ALTWRITE 'A' /* ":write" sets alternate file name */
-#define CPO_BAR 'b' /* "\|" ends a mapping */
-#define CPO_BSLASH 'B' /* backslash in mapping is not special */
+// characters for the p_cpo option:
+#define CPO_ALTREAD 'a' // ":read" sets alternate file name
+#define CPO_ALTWRITE 'A' // ":write" sets alternate file name
+#define CPO_BAR 'b' // "\|" ends a mapping
+#define CPO_BSLASH 'B' // backslash in mapping is not special
#define CPO_SEARCH 'c'
-#define CPO_CONCAT 'C' /* Don't concatenate sourced lines */
-#define CPO_DOTTAG 'd' /* "./tags" in 'tags' is in current dir */
-#define CPO_DIGRAPH 'D' /* No digraph after "r", "f", etc. */
+#define CPO_CONCAT 'C' // Don't concatenate sourced lines
+#define CPO_DOTTAG 'd' // "./tags" in 'tags' is in current dir
+#define CPO_DIGRAPH 'D' // No digraph after "r", "f", etc.
#define CPO_EXECBUF 'e'
-#define CPO_EMPTYREGION 'E' /* operating on empty region is an error */
-#define CPO_FNAMER 'f' /* set file name for ":r file" */
-#define CPO_FNAMEW 'F' /* set file name for ":w file" */
-#define CPO_INTMOD 'i' /* interrupt a read makes buffer modified */
-#define CPO_INDENT 'I' /* remove auto-indent more often */
-#define CPO_ENDOFSENT 'J' /* need two spaces to detect end of sentence */
-#define CPO_KEYCODE 'k' /* don't recognize raw key code in mappings */
-#define CPO_KOFFSET 'K' /* don't wait for key code in mappings */
-#define CPO_LITERAL 'l' /* take char after backslash in [] literal */
-#define CPO_LISTWM 'L' /* 'list' changes wrapmargin */
+#define CPO_EMPTYREGION 'E' // operating on empty region is an error
+#define CPO_FNAMER 'f' // set file name for ":r file"
+#define CPO_FNAMEW 'F' // set file name for ":w file"
+#define CPO_INTMOD 'i' // interrupt a read makes buffer modified
+#define CPO_INDENT 'I' // remove auto-indent more often
+#define CPO_ENDOFSENT 'J' // need two spaces to detect end of sentence
+#define CPO_KOFFSET 'K' // don't wait for key code in mappings
+#define CPO_LITERAL 'l' // take char after backslash in [] literal
+#define CPO_LISTWM 'L' // 'list' changes wrapmargin
#define CPO_SHOWMATCH 'm'
-#define CPO_MATCHBSL 'M' /* "%" ignores use of backslashes */
-#define CPO_NUMCOL 'n' /* 'number' column also used for text */
+#define CPO_MATCHBSL 'M' // "%" ignores use of backslashes
+#define CPO_NUMCOL 'n' // 'number' column also used for text
#define CPO_LINEOFF 'o'
-#define CPO_OVERNEW 'O' /* silently overwrite new file */
-#define CPO_LISP 'p' /* 'lisp' indenting */
-#define CPO_FNAMEAPP 'P' /* set file name for ":w >>file" */
-#define CPO_JOINCOL 'q' /* with "3J" use column after first join */
+#define CPO_OVERNEW 'O' // silently overwrite new file
+#define CPO_LISP 'p' // 'lisp' indenting
+#define CPO_FNAMEAPP 'P' // set file name for ":w >>file"
+#define CPO_JOINCOL 'q' // with "3J" use column after first join
#define CPO_REDO 'r'
-#define CPO_REMMARK 'R' /* remove marks when filtering */
+#define CPO_REMMARK 'R' // remove marks when filtering
#define CPO_BUFOPT 's'
#define CPO_BUFOPTGLOB 'S'
#define CPO_TAGPAT 't'
-#define CPO_UNDO 'u' /* "u" undoes itself */
-#define CPO_BACKSPACE 'v' /* "v" keep deleted text */
-#define CPO_FWRITE 'W' /* "w!" doesn't overwrite readonly files */
+#define CPO_UNDO 'u' // "u" undoes itself
+#define CPO_BACKSPACE 'v' // "v" keep deleted text
+#define CPO_FWRITE 'W' // "w!" doesn't overwrite readonly files
#define CPO_ESC 'x'
-#define CPO_REPLCNT 'X' /* "R" with a count only deletes chars once */
+#define CPO_REPLCNT 'X' // "R" with a count only deletes chars once
#define CPO_YANK 'y'
-#define CPO_KEEPRO 'Z' /* don't reset 'readonly' on ":w!" */
+#define CPO_KEEPRO 'Z' // don't reset 'readonly' on ":w!"
#define CPO_DOLLAR '$'
#define CPO_FILTER '!'
#define CPO_MATCH '%'
-#define CPO_PLUS '+' /* ":write file" resets 'modified' */
-#define CPO_SPECI '<' /* don't recognize <> in mappings */
-#define CPO_REGAPPEND '>' /* insert NL when appending to a register */
-#define CPO_SCOLON ';' /* using "," and ";" will skip over char if
- * cursor would not move */
-/* default values for Vim and Vi */
-#define CPO_VIM "aABceFs"
-#define CPO_VI "aAbBcCdDeEfFiIJkKlLmMnoOpPqrRsStuvWxXyZ$!%+<>;"
+#define CPO_PLUS '+' // ":write file" resets 'modified'
+#define CPO_REGAPPEND '>' // insert NL when appending to a register
+#define CPO_SCOLON ';' // using "," and ";" will skip over char if
+ // cursor would not move
+#define CPO_CHANGEW '_' // "cw" special-case
+// default values for Vim and Vi
+#define CPO_VIM "aABceFs_"
+#define CPO_VI "aAbBcCdDeEfFiIJKlLmMnoOpPqrRsStuvWxXyZ$!%+>;_"
/* characters for p_ww option: */
#define WW_ALL "bshl<>[],~"
@@ -296,16 +294,16 @@ enum {
* The following are actual variables for the options
*/
-EXTERN long p_aleph; /* 'aleph' */
-EXTERN bool p_acd; /* 'autochdir' */
-EXTERN char_u *p_ambw; /* 'ambiwidth' */
-EXTERN int p_ar; /* 'autoread' */
-EXTERN int p_aw; /* 'autowrite' */
-EXTERN int p_awa; /* 'autowriteall' */
-EXTERN char_u *p_bs; /* 'backspace' */
-EXTERN char_u *p_bg; /* 'background' */
-EXTERN int p_bk; /* 'backup' */
-EXTERN char_u *p_bkc; /* 'backupcopy' */
+EXTERN long p_aleph; // 'aleph'
+EXTERN int p_acd; // 'autochdir'
+EXTERN char_u *p_ambw; // 'ambiwidth'
+EXTERN int p_ar; // 'autoread'
+EXTERN int p_aw; // 'autowrite'
+EXTERN int p_awa; // 'autowriteall'
+EXTERN char_u *p_bs; // 'backspace'
+EXTERN char_u *p_bg; // 'background'
+EXTERN int p_bk; // 'backup'
+EXTERN char_u *p_bkc; // 'backupcopy'
EXTERN unsigned int bkc_flags; ///< flags from 'backupcopy'
#ifdef IN_OPTION_C
static char *(p_bkc_values[]) =
@@ -316,9 +314,10 @@ static char *(p_bkc_values[]) =
# define BKC_NO 0x004
# define BKC_BREAKSYMLINK 0x008
# define BKC_BREAKHARDLINK 0x010
-EXTERN char_u *p_bdir; /* 'backupdir' */
-EXTERN char_u *p_bex; /* 'backupext' */
-EXTERN char_u *p_bo; // 'belloff'
+EXTERN char_u *p_bdir; // 'backupdir'
+EXTERN char_u *p_bex; // 'backupext'
+EXTERN char_u *p_bo; // 'belloff'
+EXTERN char breakat_flags[256]; // which characters are in 'breakat'
EXTERN unsigned bo_flags;
# ifdef IN_OPTION_C
static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete",
@@ -370,17 +369,17 @@ static char *(p_cb_values[]) = {"unnamed", "unnamedplus", NULL};
# define CB_UNNAMED 0x001
# define CB_UNNAMEDPLUS 0x002
# define CB_UNNAMEDMASK (CB_UNNAMED | CB_UNNAMEDPLUS)
-EXTERN long p_cwh; /* 'cmdwinheight' */
-EXTERN long p_ch; /* 'cmdheight' */
-EXTERN int p_confirm; /* 'confirm' */
-EXTERN int p_cp; /* 'compatible' */
-EXTERN char_u *p_cot; /* 'completeopt' */
-EXTERN long p_ph; /* 'pumheight' */
-EXTERN char_u *p_cpo; /* 'cpoptions' */
-EXTERN char_u *p_csprg; /* 'cscopeprg' */
-EXTERN int p_csre; /* 'cscoperelative' */
-EXTERN char_u *p_csqf; /* 'cscopequickfix' */
-# define CSQF_CMDS "sgdctefi"
+EXTERN long p_cwh; // 'cmdwinheight'
+EXTERN long p_ch; // 'cmdheight'
+EXTERN int p_confirm; // 'confirm'
+EXTERN int p_cp; // 'compatible'
+EXTERN char_u *p_cot; // 'completeopt'
+EXTERN long p_ph; // 'pumheight'
+EXTERN char_u *p_cpo; // 'cpoptions'
+EXTERN char_u *p_csprg; // 'cscopeprg'
+EXTERN int p_csre; // 'cscoperelative'
+EXTERN char_u *p_csqf; // 'cscopequickfix'
+# define CSQF_CMDS "sgdctefia"
# define CSQF_FLAGS "+-0"
EXTERN int p_cst; /* 'cscopetag' */
EXTERN long p_csto; /* 'cscopetagorder' */
@@ -397,28 +396,31 @@ EXTERN char_u *p_dir; /* 'directory' */
EXTERN char_u *p_dy; /* 'display' */
EXTERN unsigned dy_flags;
#ifdef IN_OPTION_C
-static char *(p_dy_values[]) = {"lastline", "uhex", NULL};
+static char *(p_dy_values[]) = { "lastline", "truncate", "uhex", "msgsep",
+ NULL };
#endif
#define DY_LASTLINE 0x001
-#define DY_UHEX 0x002
-EXTERN int p_ed; /* 'edcompatible' */
-EXTERN char_u *p_ead; /* 'eadirection' */
-EXTERN bool p_ea; /* 'equalalways' */
-EXTERN char_u *p_ep; /* 'equalprg' */
-EXTERN int p_eb; /* 'errorbells' */
-EXTERN char_u *p_ef; /* 'errorfile' */
-EXTERN char_u *p_efm; /* 'errorformat' */
-EXTERN char_u *p_gefm; /* 'grepformat' */
-EXTERN char_u *p_gp; /* 'grepprg' */
-EXTERN char_u *p_ei; /* 'eventignore' */
-EXTERN int p_ek; /* 'esckeys' */
-EXTERN int p_exrc; /* 'exrc' */
-EXTERN char_u *p_fencs; /* 'fileencodings' */
-EXTERN char_u *p_ffs; /* 'fileformats' */
-EXTERN bool p_fic; ///< 'fileignorecase'
-EXTERN char_u *p_fcl; /* 'foldclose' */
-EXTERN long p_fdls; /* 'foldlevelstart' */
-EXTERN char_u *p_fdo; /* 'foldopen' */
+#define DY_TRUNCATE 0x002
+#define DY_UHEX 0x004
+#define DY_MSGSEP 0x008
+EXTERN int p_ed; // 'edcompatible'
+EXTERN int p_emoji; // 'emoji'
+EXTERN char_u *p_ead; // 'eadirection'
+EXTERN int p_ea; // 'equalalways'
+EXTERN char_u *p_ep; // 'equalprg'
+EXTERN int p_eb; // 'errorbells'
+EXTERN char_u *p_ef; // 'errorfile'
+EXTERN char_u *p_efm; // 'errorformat'
+EXTERN char_u *p_gefm; // 'grepformat'
+EXTERN char_u *p_gp; // 'grepprg'
+EXTERN char_u *p_ei; // 'eventignore'
+EXTERN int p_exrc; // 'exrc'
+EXTERN char_u *p_fencs; // 'fileencodings'
+EXTERN char_u *p_ffs; // 'fileformats'
+EXTERN int p_fic; // 'fileignorecase'
+EXTERN char_u *p_fcl; // 'foldclose'
+EXTERN long p_fdls; // 'foldlevelstart'
+EXTERN char_u *p_fdo; // 'foldopen'
EXTERN unsigned fdo_flags;
# ifdef IN_OPTION_C
static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent",
@@ -449,13 +451,13 @@ EXTERN char_u *p_popt; // 'printoptions'
EXTERN char_u *p_header; // 'printheader'
EXTERN int p_prompt; // 'prompt'
EXTERN char_u *p_guicursor; // 'guicursor'
+EXTERN char_u *p_guifont; // 'guifont'
+EXTERN char_u *p_guifontset; // 'guifontset'
+EXTERN char_u *p_guifontwide; // 'guifontwide'
EXTERN char_u *p_hf; // 'helpfile'
EXTERN long p_hh; // 'helpheight'
EXTERN char_u *p_hlg; // 'helplang'
EXTERN int p_hid; // 'hidden'
-// Use P_HID to check if a buffer is to be hidden when it is no longer
-// visible in a window.
-# define P_HID(buf) (buf_hide(buf))
EXTERN char_u *p_hl; // 'highlight'
EXTERN int p_hls; // 'hlsearch'
EXTERN long p_hi; // 'history'
@@ -468,6 +470,7 @@ EXTERN int p_icon; // 'icon'
EXTERN char_u *p_iconstring; // 'iconstring'
EXTERN int p_ic; // 'ignorecase'
EXTERN int p_is; // 'incsearch'
+EXTERN char_u *p_icm; // 'inccommand'
EXTERN int p_im; // 'insertmode'
EXTERN char_u *p_isf; // 'isfname'
EXTERN char_u *p_isi; // 'isident'
@@ -475,9 +478,11 @@ EXTERN char_u *p_isp; // 'isprint'
EXTERN int p_js; // 'joinspaces'
EXTERN char_u *p_kp; // 'keywordprg'
EXTERN char_u *p_km; // 'keymodel'
-EXTERN char_u *p_langmap; // 'langmap'*/
-EXTERN int p_lnr; // 'langnoremap'*/
+EXTERN char_u *p_langmap; // 'langmap'
+EXTERN int p_lnr; // 'langnoremap'
+EXTERN int p_lrm; // 'langremap'
EXTERN char_u *p_lm; // 'langmenu'
+EXTERN long *p_linespace; // 'linespace'
EXTERN char_u *p_lispwords; // 'lispwords'
EXTERN long p_ls; // 'laststatus'
EXTERN long p_stal; // 'showtabline'
@@ -486,6 +491,7 @@ EXTERN char_u *p_lcs; // 'listchars'
EXTERN int p_lz; // 'lazyredraw'
EXTERN int p_lpl; // 'loadplugins'
EXTERN int p_magic; // 'magic'
+EXTERN char_u *p_menc; // 'makeencoding'
EXTERN char_u *p_mef; // 'makeef'
EXTERN char_u *p_mp; // 'makeprg'
EXTERN char_u *p_cc; // 'colorcolumn'
@@ -494,9 +500,7 @@ EXTERN long p_mat; // 'matchtime'
EXTERN long p_mco; // 'maxcombine'
EXTERN long p_mfd; // 'maxfuncdepth'
EXTERN long p_mmd; // 'maxmapdepth'
-EXTERN long p_mm; // 'maxmem'
EXTERN long p_mmp; // 'maxmempattern'
-EXTERN long p_mmt; // 'maxmemtot'
EXTERN long p_mis; // 'menuitems'
EXTERN char_u *p_msm; // 'mkspellmem'
EXTERN long p_mls; // 'modelines'
@@ -512,6 +516,7 @@ EXTERN char_u *p_pex; // 'patchexpr'
EXTERN char_u *p_pm; // 'patchmode'
EXTERN char_u *p_path; // 'path'
EXTERN char_u *p_cdpath; // 'cdpath'
+EXTERN long p_pyx; // 'pyxversion'
EXTERN long p_rdt; // 'redrawtime'
EXTERN int p_remap; // 'remap'
EXTERN long p_re; // 'regexpengine'
@@ -523,6 +528,7 @@ EXTERN int p_ru; // 'ruler'
EXTERN char_u *p_ruf; // 'rulerformat'
EXTERN char_u *p_pp; // 'packpath'
EXTERN char_u *p_rtp; // 'runtimepath'
+EXTERN long p_scbk; // 'scrollback'
EXTERN long p_sj; // 'scrolljump'
EXTERN long p_so; // 'scrolloff'
EXTERN char_u *p_sbo; // 'scrollopt'
@@ -538,7 +544,7 @@ static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
"localoptions", "options", "help", "blank",
"globals", "slash", "unix",
"sesdir", "curdir", "folds", "cursor",
- "tabpages", NULL};
+ "tabpages", NULL };
# endif
# define SSOP_BUFFERS 0x001
# define SSOP_WINPOS 0x002
@@ -556,16 +562,17 @@ static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
# define SSOP_FOLDS 0x2000
# define SSOP_CURSOR 0x4000
# define SSOP_TABPAGES 0x8000
-EXTERN char_u *p_sh; /* 'shell' */
-EXTERN char_u *p_shcf; /* 'shellcmdflag' */
-EXTERN char_u *p_sp; /* 'shellpipe' */
-EXTERN char_u *p_shq; /* 'shellquote' */
-EXTERN char_u *p_sxq; /* 'shellxquote' */
-EXTERN char_u *p_sxe; /* 'shellxescape' */
-EXTERN char_u *p_srr; /* 'shellredir' */
-EXTERN int p_stmp; /* 'shelltemp' */
+
+EXTERN char_u *p_sh; // 'shell'
+EXTERN char_u *p_shcf; // 'shellcmdflag'
+EXTERN char_u *p_sp; // 'shellpipe'
+EXTERN char_u *p_shq; // 'shellquote'
+EXTERN char_u *p_sxq; // 'shellxquote'
+EXTERN char_u *p_sxe; // 'shellxescape'
+EXTERN char_u *p_srr; // 'shellredir'
+EXTERN int p_stmp; // 'shelltemp'
#ifdef BACKSLASH_IN_FILENAME
-EXTERN int p_ssl; /* 'shellslash' */
+EXTERN int p_ssl; // 'shellslash'
#endif
EXTERN char_u *p_stl; // 'statusline'
EXTERN int p_sr; // 'shiftround'
@@ -601,11 +608,14 @@ EXTERN int p_tbs; ///< 'tagbsearch'
EXTERN char_u *p_tc; ///< 'tagcase'
EXTERN unsigned tc_flags; ///< flags from 'tagcase'
#ifdef IN_OPTION_C
-static char *(p_tc_values[]) = { "followic", "ignore", "match", NULL };
+static char *(p_tc_values[]) =
+ { "followic", "ignore", "match", "followscs", "smart", NULL };
#endif
#define TC_FOLLOWIC 0x01
#define TC_IGNORE 0x02
#define TC_MATCH 0x04
+#define TC_FOLLOWSCS 0x08
+#define TC_SMART 0x10
EXTERN long p_tl; ///< 'taglength'
EXTERN int p_tr; ///< 'tagrelative'
EXTERN char_u *p_tags; ///< 'tags'
@@ -620,7 +630,7 @@ EXTERN long p_titlelen; ///< 'titlelen'
EXTERN char_u *p_titleold; ///< 'titleold'
EXTERN char_u *p_titlestring; ///< 'titlestring'
EXTERN char_u *p_tsr; ///< 'thesaurus'
-EXTERN bool p_tgc; ///< 'termguicolors'
+EXTERN int p_tgc; ///< 'termguicolors'
EXTERN int p_ttimeout; ///< 'ttimeout'
EXTERN long p_ttm; ///< 'ttimeoutlen'
EXTERN char_u *p_udir; ///< 'undodir'
@@ -649,26 +659,26 @@ char_u *p_vfile = (char_u *)""; /* used before options are initialized */
#else
extern char_u *p_vfile; /* 'verbosefile' */
#endif
-EXTERN int p_warn; /* 'warn' */
-EXTERN char_u *p_wop; /* 'wildoptions' */
-EXTERN long p_window; /* 'window' */
-EXTERN char_u *p_wak; /* 'winaltkeys' */
-EXTERN char_u *p_wig; /* 'wildignore' */
-EXTERN char_u *p_ww; /* 'whichwrap' */
-EXTERN long p_wc; /* 'wildchar' */
-EXTERN long p_wcm; /* 'wildcharm' */
-EXTERN bool p_wic; ///< 'wildignorecase'
-EXTERN char_u *p_wim; /* 'wildmode' */
-EXTERN int p_wmnu; /* 'wildmenu' */
-EXTERN long p_wh; /* 'winheight' */
-EXTERN long p_wmh; /* 'winminheight' */
-EXTERN long p_wmw; /* 'winminwidth' */
-EXTERN long p_wiw; /* 'winwidth' */
-EXTERN bool p_ws; /* 'wrapscan' */
-EXTERN int p_write; /* 'write' */
-EXTERN int p_wa; /* 'writeany' */
-EXTERN int p_wb; /* 'writebackup' */
-EXTERN long p_wd; /* 'writedelay' */
+EXTERN int p_warn; // 'warn'
+EXTERN char_u *p_wop; // 'wildoptions'
+EXTERN long p_window; // 'window'
+EXTERN char_u *p_wak; // 'winaltkeys'
+EXTERN char_u *p_wig; // 'wildignore'
+EXTERN char_u *p_ww; // 'whichwrap'
+EXTERN long p_wc; // 'wildchar'
+EXTERN long p_wcm; // 'wildcharm'
+EXTERN int p_wic; // 'wildignorecase'
+EXTERN char_u *p_wim; // 'wildmode'
+EXTERN int p_wmnu; // 'wildmenu'
+EXTERN long p_wh; // 'winheight'
+EXTERN long p_wmh; // 'winminheight'
+EXTERN long p_wmw; // 'winminwidth'
+EXTERN long p_wiw; // 'winwidth'
+EXTERN int p_ws; // 'wrapscan'
+EXTERN int p_write; // 'write'
+EXTERN int p_wa; // 'writeany'
+EXTERN int p_wb; // 'writebackup'
+EXTERN long p_wd; // 'writedelay'
EXTERN int p_force_on; ///< options that cannot be turned off.
EXTERN int p_force_off; ///< options that cannot be turned on.
@@ -690,6 +700,7 @@ enum {
, BV_BIN
, BV_BL
, BV_BOMB
+ , BV_CHANNEL
, BV_CI
, BV_CIN
, BV_CINK
@@ -709,6 +720,7 @@ enum {
, BV_EP
, BV_ET
, BV_FENC
+ , BV_FP
, BV_BEXPR
, BV_FEX
, BV_FF
@@ -726,6 +738,7 @@ enum {
, BV_KP
, BV_LISP
, BV_LW
+ , BV_MENC
, BV_MA
, BV_ML
, BV_MOD
@@ -736,6 +749,7 @@ enum {
, BV_PI
, BV_QE
, BV_RO
+ , BV_SCBK
, BV_SI
, BV_SMC
, BV_SYN
@@ -798,10 +812,20 @@ enum {
, WV_WFH
, WV_WFW
, WV_WRAP
- , WV_COUNT /* must be the last one */
+ , WV_SCL
+ , WV_WINHL
+ , WV_COUNT // must be the last one
};
/* Value for b_p_ul indicating the global value must be used. */
#define NO_LOCAL_UNDOLEVEL -123456
+#define SB_MAX 100000 // Maximum 'scrollback' value.
+
+/// Stores an identifier of a script or channel that last set an option.
+typedef struct {
+ scid_T script_id; /// Script ID or one of SID_* special values.
+ uint64_t channel_id; /// Only used when script_id is SID_API_CLIENT.
+} LastSet;
+
#endif // NVIM_OPTION_DEFS_H
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index d19af4f73f..aba8f8b893 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -7,7 +7,7 @@
-- enable_if=nil,
-- defaults={condition=nil, if_true={vi=224, vim=0}, if_false=nil},
-- secure=nil, gettext=nil, noglob=nil, normal_fname_chars=nil,
--- pri_mkrc=nil, deny_in_modelines=nil,
+-- pri_mkrc=nil, deny_in_modelines=nil, normal_dname_chars=nil,
-- expand=nil, nodefault=nil, no_mkrc=nil, vi_def=true, vim=true,
-- alloced=nil,
-- save_pv_indir=nil,
@@ -17,8 +17,8 @@
-- types: bool, number, string
-- lists: (nil), comma, onecomma, flags, flagscomma
-- scopes: global, buffer, window
--- redraw options: statuslines, current_window, current_buffer, all_windows,
--- everything, curswant
+-- redraw options: statuslines, current_window, curent_window_only,
+-- current_buffer, all_windows, everything, curswant
-- default: {vi=…[, vim=…]}
-- defaults: {condition=#if condition, if_true=default, if_false=default}
-- #if condition:
@@ -34,6 +34,11 @@ local macros=function(s)
return s
end
end
+local imacros=function(s)
+ return function()
+ return '(intptr_t)' .. s
+ end
+end
local N_=function(s)
return function()
return 'N_(' .. cstr(s) .. ')'
@@ -63,7 +68,8 @@ return {
type='bool', scope={'global'},
vi_def=true,
vim=true,
- redraw={'everything'},
+ redraw={'all_windows', 'ui_option'},
+
varname='p_arshape',
defaults={if_true={vi=true}}
},
@@ -86,7 +92,7 @@ return {
full_name='ambiwidth', abbreviation='ambw',
type='string', scope={'global'},
vi_def=true,
- redraw={'everything'},
+ redraw={'all_windows', 'ui_option'},
varname='p_ambw',
defaults={if_true={vi="single"}}
},
@@ -126,10 +132,10 @@ return {
{
full_name='background', abbreviation='bg',
type='string', scope={'global'},
- vi_def=true,
- redraw={'everything'},
+ vim=true,
+ redraw={'all_windows'},
varname='p_bg',
- defaults={if_true={vi="light"}}
+ defaults={if_true={vi="light",vim="dark"}}
},
{
full_name='backspace', abbreviation='bs',
@@ -165,7 +171,7 @@ return {
deny_duplicates=true,
secure=true,
vi_def=true,
- expand=true,
+ expand='nodefault',
varname='p_bdir',
defaults={if_true={vi=''}}
},
@@ -190,7 +196,7 @@ return {
type='string', list='comma', scope={'global'},
vi_def=true,
varname='p_bo',
- defaults={if_true={vi=""}}
+ defaults={if_true={vi="all"}}
},
{
full_name='binary', abbreviation='bin',
@@ -290,6 +296,14 @@ return {
defaults={if_true={vi="", vim=macros('CTRL_F_STR')}}
},
{
+ full_name='channel',
+ type='number', scope={'buffer'},
+ no_mkrc=true,
+ nodefault=true,
+ varname='p_channel',
+ defaults={if_true={vi=0}}
+ },
+ {
full_name='charconvert', abbreviation='ccv',
type='string', scope={'global'},
secure=true,
@@ -519,7 +533,7 @@ return {
vi_def=true,
vim=true,
varname='p_csverbose',
- defaults={if_true={vi=0}}
+ defaults={if_true={vi=1}}
},
{
full_name='cursorbind', abbreviation='crb',
@@ -539,7 +553,7 @@ return {
full_name='cursorline', abbreviation='cul',
type='bool', scope={'window'},
vi_def=true,
- redraw={'current_window'},
+ redraw={'current_window_only'},
defaults={if_true={vi=false}}
},
{
@@ -570,6 +584,7 @@ return {
full_name='dictionary', abbreviation='dict',
type='string', list='onecomma', scope={'global', 'buffer'},
deny_duplicates=true,
+ normal_dname_chars=true,
vi_def=true,
expand=true,
varname='p_dict',
@@ -600,7 +615,7 @@ return {
alloced=true,
redraw={'current_window'},
varname='p_dip',
- defaults={if_true={vi="filler"}}
+ defaults={if_true={vi="internal,filler"}}
},
{
full_name='digraph', abbreviation='dg',
@@ -616,7 +631,7 @@ return {
deny_duplicates=true,
secure=true,
vi_def=true,
- expand=true,
+ expand='nodefault',
varname='p_dir',
defaults={if_true={vi=''}}
},
@@ -627,7 +642,7 @@ return {
vim=true,
redraw={'all_windows'},
varname='p_dy',
- defaults={if_true={vi="", vim="lastline"}}
+ defaults={if_true={vi="", vim="lastline,msgsep"}}
},
{
full_name='eadirection', abbreviation='ead',
@@ -644,11 +659,18 @@ return {
defaults={if_true={vi=false}}
},
{
+ full_name='emoji', abbreviation='emo',
+ type='bool', scope={'global'},
+ vi_def=true,
+ redraw={'all_windows', 'ui_option'},
+ varname='p_emoji',
+ defaults={if_true={vi=true}}
+ },
+ {
full_name='encoding', abbreviation='enc',
type='string', scope={'global'},
deny_in_modelines=true,
vi_def=true,
- redraw={'everything'},
varname='p_enc',
defaults={if_true={vi=macros('ENC_DFLT')}}
},
@@ -703,13 +725,6 @@ return {
defaults={if_true={vi=macros('DFLT_EFM')}}
},
{
- full_name='esckeys', abbreviation='ek',
- type='bool', scope={'global'},
- vim=true,
- varname='p_ek',
- defaults={if_true={vi=false, vim=true}}
- },
- {
full_name='eventignore', abbreviation='ei',
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
@@ -796,7 +811,7 @@ return {
vi_def=true,
redraw={'all_windows'},
varname='p_fcs',
- defaults={if_true={vi="vert:|,fold:-"}}
+ defaults={if_true={vi=''}}
},
{
full_name='fixendofline', abbreviation='fixeol',
@@ -947,7 +962,7 @@ return {
},
{
full_name='formatprg', abbreviation='fp',
- type='string', scope={'global'},
+ type='string', scope={'global', 'buffer'},
secure=true,
vi_def=true,
expand=true,
@@ -960,7 +975,7 @@ return {
secure=true,
vi_def=true,
varname='p_fs',
- defaults={if_true={vi=true}}
+ defaults={if_true={vi=false}}
},
{
full_name='gdefault', abbreviation='gd',
@@ -986,11 +1001,11 @@ return {
expand=true,
varname='p_gp',
defaults={
- condition='UNIX',
+ condition='WIN32',
-- Add an extra file name so that grep will always
-- insert a file name in the match line. */
- if_true={vi="grep -n $* /dev/null"},
- if_false={vi="grep -n "},
+ if_true={vi="findstr /n $* nul"},
+ if_false={vi="grep -n $* /dev/null"}
}
},
{
@@ -999,37 +1014,33 @@ return {
deny_duplicates=true,
vi_def=true,
varname='p_guicursor',
- defaults={if_true={vi="n-v-c:block,o:hor50,i-ci:hor15,r-cr:hor30,sm:block"}}
+ defaults={if_true={vi="n-v-c-sm:block,i-ci-ve:ver25,r-cr-o:hor20"}}
},
{
full_name='guifont', abbreviation='gfn',
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
vi_def=true,
- redraw={'everything'},
- enable_if=false,
+ varname='p_guifont',
+ redraw={'ui_option'},
+ defaults={if_true={vi=""}}
},
{
full_name='guifontset', abbreviation='gfs',
type='string', list='onecomma', scope={'global'},
vi_def=true,
- redraw={'everything'},
- enable_if=false,
+ varname='p_guifontset',
+ redraw={'ui_option'},
+ defaults={if_true={vi=""}}
},
{
full_name='guifontwide', abbreviation='gfw',
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
vi_def=true,
- redraw={'everything'},
- enable_if=false,
- },
- {
- full_name='guiheadroom', abbreviation='ghr',
- type='number', scope={'global'},
- vi_def=true,
- enable_if=false,
- defaults={if_true={vi=50}}
+ redraw={'ui_option'},
+ varname='p_guifontwide',
+ defaults={if_true={vi=""}}
},
{
full_name='guioptions', abbreviation='go',
@@ -1087,7 +1098,6 @@ return {
type='string', list='onecomma', scope={'global'},
deny_duplicates=true,
vi_def=true,
- redraw={'everything'},
varname='p_hl',
defaults={if_true={vi=macros('HIGHLIGHT_INIT')}}
},
@@ -1180,6 +1190,14 @@ return {
}
},
{
+ full_name='inccommand', abbreviation='icm',
+ type='string', scope={'global'},
+ vi_def=true,
+ redraw={'all_windows'},
+ varname='p_icm',
+ defaults={if_true={vi=""}}
+ },
+ {
full_name='include', abbreviation='inc',
type='string', scope={'global', 'buffer'},
vi_def=true,
@@ -1338,6 +1356,12 @@ return {
defaults={if_true={vi=false, vim=true}}
},
{
+ full_name='langremap', abbreviation='lrm',
+ type='bool', scope={'global'},
+ varname='p_lrm',
+ defaults={if_true={vi=true, vim=false}}
+ },
+ {
full_name='laststatus', abbreviation='ls',
type='number', scope={'global'},
vim=true,
@@ -1373,8 +1397,9 @@ return {
full_name='linespace', abbreviation='lsp',
type='number', scope={'global'},
vi_def=true,
- redraw={'everything'},
- enable_if=false,
+ redraw={'ui_option'},
+ varname='p_linespace',
+ defaults={if_true={vi=0}}
},
{
full_name='lisp',
@@ -1431,6 +1456,13 @@ return {
defaults={if_true={vi=""}}
},
{
+ full_name='makeencoding', abbreviation='menc',
+ type='string', scope={'global', 'buffer'},
+ vi_def=true,
+ varname='p_menc',
+ defaults={if_true={vi=""}}
+ },
+ {
full_name='makeprg', abbreviation='mp',
type='string', scope={'global', 'buffer'},
secure=true,
@@ -1459,9 +1491,8 @@ return {
full_name='maxcombine', abbreviation='mco',
type='number', scope={'global'},
vi_def=true,
- redraw={'curswant'},
varname='p_mco',
- defaults={if_true={vi=2}}
+ defaults={if_true={vi=6}}
},
{
full_name='maxfuncdepth', abbreviation='mfd',
@@ -1478,13 +1509,6 @@ return {
defaults={if_true={vi=1000}}
},
{
- full_name='maxmem', abbreviation='mm',
- type='number', scope={'global'},
- vi_def=true,
- varname='p_mm',
- defaults={if_true={vi=macros('DFLT_MAXMEM')}}
- },
- {
full_name='maxmempattern', abbreviation='mmp',
type='number', scope={'global'},
vi_def=true,
@@ -1492,13 +1516,6 @@ return {
defaults={if_true={vi=1000}}
},
{
- full_name='maxmemtot', abbreviation='mmt',
- type='number', scope={'global'},
- vi_def=true,
- varname='p_mmt',
- defaults={if_true={vi=macros('DFLT_MAXMEMTOT')}}
- },
- {
full_name='menuitems', abbreviation='mis',
type='number', scope={'global'},
vi_def=true,
@@ -1556,7 +1573,7 @@ return {
full_name='mouse',
type='string', list='flags', scope={'global'},
varname='p_mouse',
- defaults={if_true={vi="", vim="a"}}
+ defaults={if_true={vi="", vim=""}}
},
{
full_name='mousefocus', abbreviation='mousef',
@@ -1737,6 +1754,7 @@ return {
{
full_name='printexpr', abbreviation='pexpr',
type='string', scope={'global'},
+ secure=true,
vi_def=true,
varname='p_pexpr',
defaults={if_true={vi=""}}
@@ -1751,10 +1769,9 @@ return {
{
full_name='printheader', abbreviation='pheader',
type='string', scope={'global'},
- gettext=true,
vi_def=true,
varname='p_header',
- defaults={if_true={vi=N_("%<%f%h%m%=Page %N")}}
+ defaults={if_true={vi="%<%f%h%m%=Page %N"}}
},
{
full_name='printmbcharset', abbreviation='pmbcs',
@@ -1793,6 +1810,14 @@ return {
defaults={if_true={vi=0}}
},
{
+ full_name='pyxversion', abbreviation='pyx',
+ type='number', scope={'global'},
+ secure=true,
+ vi_def=true,
+ varname='p_pyx',
+ defaults={if_true={vi=0}}
+ },
+ {
full_name='quoteescape', abbreviation='qe',
type='string', scope={'buffer'},
vi_def=true,
@@ -1874,7 +1899,7 @@ return {
vim=true,
redraw={'statuslines'},
varname='p_ru',
- defaults={if_true={vi=false}}
+ defaults={if_true={vi=true}}
},
{
full_name='rulerformat', abbreviation='ruf',
@@ -1891,7 +1916,7 @@ return {
deny_duplicates=true,
secure=true,
vi_def=true,
- expand=true,
+ expand='nodefault',
varname='p_rtp',
defaults={if_true={vi=''}}
},
@@ -1901,7 +1926,15 @@ return {
no_mkrc=true,
vi_def=true,
pv_name='p_scroll',
- defaults={if_true={vi=12}}
+ defaults={if_true={vi=0}}
+ },
+ {
+ full_name='scrollback', abbreviation='scbk',
+ type='number', scope={'buffer'},
+ vi_def=true,
+ varname='p_scbk',
+ redraw={'current_buffer'},
+ defaults={if_true={vi=10000}}
},
{
full_name='scrollbind', abbreviation='scb',
@@ -2005,7 +2038,7 @@ return {
varname='p_shcf',
defaults={
condition='WIN32',
- if_true={vi="/c"},
+ if_true={vi="/s /c"},
if_false={vi="-c"}
}
},
@@ -2016,9 +2049,9 @@ return {
vi_def=true,
varname='p_sp',
defaults={
- condition='UNIX',
- if_true={vi="| tee"},
- if_false={vi=">"},
+ condition='WIN32',
+ if_true={vi=">%s 2>&1"},
+ if_false={vi="| tee"},
}
},
{
@@ -2035,7 +2068,11 @@ return {
secure=true,
vi_def=true,
varname='p_srr',
- defaults={if_true={vi=">"}}
+ defaults={
+ condition='WIN32',
+ if_true={vi=">%s 2>&1"},
+ if_false={vi=">"}
+ }
},
{
full_name='shellslash', abbreviation='ssl',
@@ -2057,7 +2094,11 @@ return {
secure=true,
vi_def=true,
varname='p_sxq',
- defaults={if_true={vi=""}}
+ defaults={
+ condition='WIN32',
+ if_true={vi="\""},
+ if_false={vi=""},
+ }
},
{
full_name='shellxescape', abbreviation='sxe',
@@ -2087,7 +2128,7 @@ return {
type='string', list='flags', scope={'global'},
vim=true,
varname='p_shm',
- defaults={if_true={vi="", vim="filnxtToO"}}
+ defaults={if_true={vi="", vim="filnxtToOF"}}
},
{
full_name='showbreak', abbreviation='sbr',
@@ -2102,11 +2143,7 @@ return {
type='bool', scope={'global'},
vim=true,
varname='p_sc',
- defaults={
- condition='UNIX',
- if_true={vi=false, vim=false},
- if_false={vi=false, vim=true},
- }
+ defaults={if_true={vi=false, vim=true}}
},
{
full_name='showfulltag', abbreviation='sft',
@@ -2133,7 +2170,7 @@ return {
full_name='showtabline', abbreviation='stal',
type='number', scope={'global'},
vi_def=true,
- redraw={'all_windows'},
+ redraw={'all_windows', 'ui_option'},
varname='p_stal',
defaults={if_true={vi=1}}
},
@@ -2142,7 +2179,7 @@ return {
type='number', scope={'global'},
vi_def=true,
varname='p_ss',
- defaults={if_true={vi=0}}
+ defaults={if_true={vi=1}}
},
{
full_name='sidescrolloff', abbreviation='siso',
@@ -2154,6 +2191,14 @@ return {
defaults={if_true={vi=0}}
},
{
+ full_name='signcolumn', abbreviation='scl',
+ type='string', scope={'window'},
+ vi_def=true,
+ alloced=true,
+ redraw={'current_window'},
+ defaults={if_true={vi="auto"}}
+ },
+ {
full_name='smartcase', abbreviation='scs',
type='bool', scope={'global'},
vi_def=true,
@@ -2389,14 +2434,13 @@ return {
full_name='termencoding', abbreviation='tenc',
type='string', scope={'global'},
vi_def=true,
- redraw={'everything'},
defaults={if_true={vi=""}}
},
{
full_name='termguicolors', abbreviation='tgc',
type='bool', scope={'global'},
vi_def=false,
- redraw={'everything'},
+ redraw={'ui_option'},
varname='p_tgc',
defaults={if_true={vi=false}}
},
@@ -2420,6 +2464,7 @@ return {
full_name='thesaurus', abbreviation='tsr',
type='string', list='onecomma', scope={'global', 'buffer'},
deny_duplicates=true,
+ normal_dname_chars=true,
vi_def=true,
expand=true,
varname='p_tsr',
@@ -2465,11 +2510,10 @@ return {
full_name='titleold',
type='string', scope={'global'},
secure=true,
- gettext=true,
no_mkrc=true,
vi_def=true,
varname='p_titleold',
- defaults={if_true={vi=N_("Thanks for flying Vim")}}
+ defaults={if_true={vi=""}}
},
{
full_name='titlestring',
@@ -2484,14 +2528,14 @@ return {
vi_def=true,
vim=true,
varname='p_ttimeout',
- defaults={if_true={vi=false}}
+ defaults={if_true={vi=true}}
},
{
full_name='ttimeoutlen', abbreviation='ttm',
type='number', scope={'global'},
vi_def=true,
varname='p_ttm',
- defaults={if_true={vi=-1}}
+ defaults={if_true={vi=50}}
},
{
full_name='ttyfast', abbreviation='tf',
@@ -2507,7 +2551,7 @@ return {
deny_duplicates=true,
secure=true,
vi_def=true,
- expand=true,
+ expand='nodefault',
varname='p_udir',
defaults={if_true={vi=''}}
},
@@ -2568,7 +2612,7 @@ return {
type='string', scope={'global'},
secure=true,
vi_def=true,
- expand=true,
+ expand='nodefault',
varname='p_vdir',
defaults={if_true={vi=''}}
},
@@ -2578,7 +2622,7 @@ return {
deny_duplicates=true,
vi_def=true,
varname='p_vop',
- defaults={if_true={vi="folds,options,cursor"}}
+ defaults={if_true={vi="folds,options,cursor,curdir"}}
},
{
full_name='viminfo', abbreviation='vi',
@@ -2624,7 +2668,7 @@ return {
type='number', scope={'global'},
vim=true,
varname='p_wc',
- defaults={if_true={vi=macros('Ctrl_E'), vim=macros('TAB')}}
+ defaults={if_true={vi=imacros('Ctrl_E'), vim=imacros('TAB')}}
},
{
full_name='wildcharm', abbreviation='wcm',
@@ -2678,6 +2722,14 @@ return {
defaults={if_true={vi="menu"}}
},
{
+ full_name='winhighlight', abbreviation='winhl',
+ type='string', scope={'window'},
+ vi_def=true,
+ alloced=true,
+ redraw={'current_window'},
+ defaults={if_true={vi=""}}
+ },
+ {
full_name='window', abbreviation='wi',
type='number', scope={'global'},
vi_def=true,
diff --git a/src/nvim/os/dl.c b/src/nvim/os/dl.c
index fef02cc784..267cf5ae4b 100644
--- a/src/nvim/os/dl.c
+++ b/src/nvim/os/dl.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
+
/// Functions for using external native libraries
#include <stdbool.h>
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index edc430410c..c6794e4be5 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -1,24 +1,29 @@
-// env.c -- environment variable access
+// 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>
+// Environment inspection
+#include <assert.h>
#include <uv.h>
-// vim.h must be included before charset.h (and possibly others) or things
-// blow up
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/charset.h"
+#include "nvim/fileio.h"
#include "nvim/os/os.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/path.h"
+#include "nvim/macros.h"
#include "nvim/strings.h"
#include "nvim/eval.h"
#include "nvim/ex_getln.h"
#include "nvim/version.h"
+#ifdef WIN32
+#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+#endif
+
#ifdef HAVE__NSGETENVIRON
#include <crt_externs.h>
#endif
@@ -46,7 +51,21 @@ bool os_env_exists(const char *name)
int os_setenv(const char *name, const char *value, int overwrite)
FUNC_ATTR_NONNULL_ALL
{
-#ifdef HAVE_SETENV
+#ifdef WIN32
+ size_t envbuflen = strlen(name) + strlen(value) + 2;
+ char *envbuf = xmalloc(envbuflen);
+ snprintf(envbuf, envbuflen, "%s=%s", name, value);
+
+ wchar_t *p;
+ utf8_to_utf16(envbuf, &p);
+ xfree(envbuf);
+ if (p == NULL) {
+ return -1;
+ }
+ _wputenv(p);
+ xfree(p); // Unlike Unix systems, we can free the string for _wputenv().
+ return 0;
+#elif defined(HAVE_SETENV)
return setenv(name, value, overwrite);
#elif defined(HAVE_PUTENV_S)
if (!overwrite && os_getenv(name) != NULL) {
@@ -100,7 +119,6 @@ char *os_getenvname_at_index(size_t index)
return name;
}
-
/// Get the process ID of the Neovim process.
///
/// @return the process ID.
@@ -113,11 +131,11 @@ int64_t os_get_pid(void)
#endif
}
-/// Get the hostname of the machine running Neovim.
+/// Gets the hostname of the current machine.
///
-/// @param hostname Buffer to store the hostname.
-/// @param len Length of `hostname`.
-void os_get_hostname(char *hostname, size_t len)
+/// @param hostname Buffer to store the hostname.
+/// @param size Size of `hostname`.
+void os_get_hostname(char *hostname, size_t size)
{
#ifdef HAVE_SYS_UTSNAME_H
struct utsname vutsname;
@@ -125,13 +143,29 @@ void os_get_hostname(char *hostname, size_t len)
if (uname(&vutsname) < 0) {
*hostname = '\0';
} else {
- strncpy(hostname, vutsname.nodename, len - 1);
- hostname[len - 1] = '\0';
+ xstrlcpy(hostname, vutsname.nodename, size);
}
+#elif defined(WIN32)
+ wchar_t host_utf16[MAX_COMPUTERNAME_LENGTH + 1];
+ DWORD host_wsize = sizeof(host_utf16) / sizeof(host_utf16[0]);
+ if (GetComputerNameW(host_utf16, &host_wsize) == 0) {
+ *hostname = '\0';
+ DWORD err = GetLastError();
+ EMSG2("GetComputerNameW failed: %d", err);
+ return;
+ }
+ host_utf16[host_wsize] = '\0';
+
+ char *host_utf8;
+ int conversion_result = utf16_to_utf8(host_utf16, &host_utf8);
+ if (conversion_result != 0) {
+ EMSG2("utf16_to_utf8 failed: %d", conversion_result);
+ return;
+ }
+ xstrlcpy(hostname, host_utf8, size);
+ xfree(host_utf8);
#else
- // TODO(unknown): Implement this for windows.
- // See the implementation used in vim:
- // https://code.google.com/p/vim/source/browse/src/os_win32.c?r=6b69d8dde19e32909f4ee3a6337e6a2ecfbb6f72#2899
+ EMSG("os_get_hostname failed: missing uname()");
*hostname = '\0';
#endif
}
@@ -143,15 +177,15 @@ void os_get_hostname(char *hostname, size_t len)
/// - do os_dirname() to get the real name of that directory.
/// This also works with mounts and links.
/// Don't do this for Windows, it will change the "current dir" for a drive.
-static char_u *homedir = NULL;
+static char *homedir = NULL;
void init_homedir(void)
{
- // In case we are called a second time (when 'encoding' changes).
+ // In case we are called a second time.
xfree(homedir);
homedir = NULL;
- char_u *var = (char_u *)os_getenv("HOME");
+ const char *var = os_getenv("HOME");
#ifdef WIN32
// Typically, $HOME is not defined on Windows, unless the user has
@@ -162,33 +196,35 @@ void init_homedir(void)
const char *homedrive = os_getenv("HOMEDRIVE");
const char *homepath = os_getenv("HOMEPATH");
if (homepath == NULL) {
- homepath = "\\";
+ homepath = "\\";
}
- if (homedrive != NULL && strlen(homedrive) + strlen(homepath) < MAXPATHL) {
- snprintf((char *)NameBuff, MAXPATHL, "%s%s", homedrive, homepath);
- if (NameBuff[0] != NUL) {
- var = NameBuff;
- vim_setenv("HOME", (char *)NameBuff);
+ if (homedrive != NULL
+ && strlen(homedrive) + strlen(homepath) < MAXPATHL) {
+ snprintf(os_buf, MAXPATHL, "%s%s", homedrive, homepath);
+ if (os_buf[0] != NUL) {
+ var = os_buf;
}
}
}
+ if (var == NULL) {
+ var = os_getenv("USERPROFILE");
+ }
#endif
if (var != NULL) {
#ifdef UNIX
// Change to the directory and get the actual path. This resolves
// links. Don't do it when we can't return.
- if (os_dirname(NameBuff, MAXPATHL) == OK
- && os_chdir((char *)NameBuff) == 0) {
- if (!os_chdir((char *)var) && os_dirname(IObuff, IOSIZE) == OK) {
- var = IObuff;
+ if (os_dirname((char_u *)os_buf, MAXPATHL) == OK && os_chdir(os_buf) == 0) {
+ if (!os_chdir(var) && os_dirname(IObuff, IOSIZE) == OK) {
+ var = (char *)IObuff;
}
- if (os_chdir((char *)NameBuff) != 0) {
+ if (os_chdir(os_buf) != 0) {
EMSG(_(e_prev_dir));
}
}
#endif
- homedir = vim_strsave(var);
+ homedir = xstrdup(var);
}
}
@@ -227,25 +263,24 @@ char_u *expand_env_save_opt(char_u *src, bool one)
/// "~/" is also expanded, using $HOME. For Unix "~user/" is expanded.
/// Skips over "\ ", "\~" and "\$" (not for Win32 though).
/// If anything fails no expansion is done and dst equals src.
-/// @param src Input string e.g. "$HOME/vim.hlp"
-/// @param dst Where to put the result
-/// @param dstlen Maximum length of the result
+///
+/// @param src Input string e.g. "$HOME/vim.hlp"
+/// @param dst[out] Where to put the result
+/// @param dstlen Maximum length of the result
void expand_env(char_u *src, char_u *dst, int dstlen)
{
expand_env_esc(src, dst, dstlen, false, false, NULL);
}
/// Expand environment variable with path name and escaping.
-/// "~/" is also expanded, using $HOME. For Unix "~user/" is expanded.
-/// Skips over "\ ", "\~" and "\$" (not for Win32 though).
-/// If anything fails no expansion is done and dst equals src.
-/// prefix recognize the start of a new name, for '~' expansion.
-/// @param srcp Input string e.g. "$HOME/vim.hlp"
-/// @param dst Where to put the result
-/// @param dstlen Maximum length of the result
-/// @param esc Should we escape spaces in expanded variables?
-/// @param one Should we expand more than one '~'?
-/// @param prefix Common prefix for paths, can be NULL
+/// @see expand_env
+///
+/// @param srcp Input string e.g. "$HOME/vim.hlp"
+/// @param dst[out] Where to put the result
+/// @param dstlen Maximum length of the result
+/// @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,
@@ -326,7 +361,7 @@ void expand_env_esc(char_u *restrict srcp,
} else if (src[1] == NUL // home directory
|| vim_ispathsep(src[1])
|| vim_strchr((char_u *)" ,\t\n", src[1]) != NULL) {
- var = homedir;
+ var = (char_u *)homedir;
tail = src + 1;
} else { // user directory
#if defined(UNIX)
@@ -341,11 +376,10 @@ void expand_env_esc(char_u *restrict srcp,
*var++ = *tail++;
}
*var = NUL;
- // Use os_get_user_directory() to get the user directory.
- // If this function fails, the shell is used to
- // expand ~user. This is slower and may fail if the shell
- // does not support ~user (old versions of /bin/sh).
- var = (char_u *)os_get_user_directory((char *)dst + 1);
+ // 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_user_directory((char *)dst + 1);
mustfree = true;
if (var == NULL) {
expand_T xpc;
@@ -423,12 +457,15 @@ void expand_env_esc(char_u *restrict srcp,
} else if ((src[0] == ' ' || src[0] == ',') && !one) {
at_start = true;
}
- *dst++ = *src++;
- --dstlen;
+ if (dstlen > 0) {
+ *dst++ = *src++;
+ dstlen--;
- if (prefix != NULL && src - prefix_len >= srcp
- && STRNCMP(src - prefix_len, prefix, prefix_len) == 0) {
- at_start = true;
+ if (prefix != NULL
+ && src - prefix_len >= srcp
+ && STRNCMP(src - prefix_len, prefix, prefix_len) == 0) {
+ at_start = true;
+ }
}
}
}
@@ -490,10 +527,11 @@ static char *remove_tail(char *path, char *pend, char *dirname)
return pend;
}
-/// Iterate over colon-separated list
+/// Iterate over a delimited list.
///
/// @note Environment variables must not be modified during iteration.
///
+/// @param[in] delim Delimiter character.
/// @param[in] val Value of the environment variable to iterate over.
/// @param[in] iter Pointer used for iteration. Must be NULL on first
/// iteration.
@@ -502,18 +540,19 @@ static char *remove_tail(char *path, char *pend, char *dirname)
/// @param[out] len Location where current directory length should be saved.
///
/// @return Next iter argument value or NULL when iteration should stop.
-const void *vim_colon_env_iter(const char *const val,
- const void *const iter,
- const char **const dir,
- size_t *const len)
- FUNC_ATTR_NONNULL_ARG(1, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT
+const void *vim_env_iter(const char delim,
+ const char *const val,
+ const void *const iter,
+ const char **const dir,
+ size_t *const len)
+ FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT
{
const char *varval = (const char *) iter;
if (varval == NULL) {
varval = val;
}
*dir = varval;
- const char *const dirend = strchr(varval, ':');
+ const char *const dirend = strchr(varval, delim);
if (dirend == NULL) {
*len = strlen(varval);
return NULL;
@@ -523,10 +562,11 @@ const void *vim_colon_env_iter(const char *const val,
}
}
-/// Iterate over colon-separated list in reverse order
+/// Iterate over a delimited list in reverse order.
///
/// @note Environment variables must not be modified during iteration.
///
+/// @param[in] delim Delimiter character.
/// @param[in] val Value of the environment variable to iterate over.
/// @param[in] iter Pointer used for iteration. Must be NULL on first
/// iteration.
@@ -535,18 +575,19 @@ const void *vim_colon_env_iter(const char *const val,
/// @param[out] len Location where current directory length should be saved.
///
/// @return Next iter argument value or NULL when iteration should stop.
-const void *vim_colon_env_iter_rev(const char *const val,
- const void *const iter,
- const char **const dir,
- size_t *const len)
- FUNC_ATTR_NONNULL_ARG(1, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT
+const void *vim_env_iter_rev(const char delim,
+ const char *const val,
+ const void *const iter,
+ const char **const dir,
+ size_t *const len)
+ FUNC_ATTR_NONNULL_ARG(2, 4, 5) FUNC_ATTR_WARN_UNUSED_RESULT
{
const char *varend = (const char *) iter;
if (varend == NULL) {
varend = val + strlen(val) - 1;
}
- const size_t varlen = (size_t) (varend - val) + 1;
- const char *const colon = xmemrchr(val, ':', varlen);
+ const size_t varlen = (size_t)(varend - val) + 1;
+ const char *const colon = xmemrchr(val, (uint8_t)delim, varlen);
if (colon == NULL) {
*len = varlen;
*dir = val;
@@ -561,15 +602,24 @@ const void *vim_colon_env_iter_rev(const char *const val,
/// Vim's version of getenv().
/// Special handling of $HOME, $VIM and $VIMRUNTIME, allowing the user to
/// override the vim runtime directory at runtime. Also does ACP to 'enc'
-/// conversion for Win32. Results must be freed by the calling function.
-/// @param name Name of environment variable to expand
+/// conversion for Win32. Result must be freed by the caller.
+/// @param name Environment variable to expand
char *vim_getenv(const char *name)
{
+ // init_path() should have been called before now.
+ assert(get_vim_var_str(VV_PROGPATH)[0] != NUL);
+
const char *kos_env_path = os_getenv(name);
if (kos_env_path != NULL) {
return xstrdup(kos_env_path);
}
+#ifdef WIN32
+ if (strcmp(name, "HOME") == 0) {
+ return xstrdup(homedir);
+ }
+#endif
+
bool vimruntime = (strcmp(name, "VIMRUNTIME") == 0);
if (!vimruntime && strcmp(name, "VIM") != 0) {
return NULL;
@@ -599,6 +649,24 @@ char *vim_getenv(const char *name)
if (p_hf != NULL && vim_strchr(p_hf, '$') == NULL) {
vim_path = (char *)p_hf;
}
+
+ char exe_name[MAXPATHL];
+ // Find runtime path relative to the nvim binary: ../share/nvim/runtime
+ if (vim_path == NULL) {
+ xstrlcpy(exe_name, (char *)get_vim_var_str(VV_PROGPATH),
+ sizeof(exe_name));
+ char *path_end = (char *)path_tail_with_sep((char_u *)exe_name);
+ *path_end = '\0'; // remove the trailing "nvim.exe"
+ path_end = (char *)path_tail((char_u *)exe_name);
+ *path_end = '\0'; // remove the trailing "bin/"
+ if (append_path(
+ exe_name,
+ "share" _PATHSEPSTR "nvim" _PATHSEPSTR "runtime" _PATHSEPSTR,
+ MAXPATHL) == OK) {
+ vim_path = exe_name; // -V507
+ }
+ }
+
if (vim_path != NULL) {
// remove the file name
char *vim_path_end = (char *)path_tail((char_u *)vim_path);
@@ -628,6 +696,7 @@ char *vim_getenv(const char *name)
vim_path = NULL;
}
}
+ assert(vim_path != exe_name);
}
#ifdef HAVE_PATHDEF
@@ -662,107 +731,128 @@ char *vim_getenv(const char *name)
/// Replace home directory by "~" in each space or comma separated file name in
/// 'src'.
+///
+/// Replace home directory with tilde in each file name
+///
/// If anything fails (except when out of space) dst equals src.
-/// @param buf When not NULL, check for help files
-/// @param src Input file name
-/// @param dst Where to put the result
-/// @param dstlen Maximum length of the result
-/// @param one If true, only replace one file name, including spaces and commas
-/// in the file name
-void home_replace(buf_T *buf, char_u *src, char_u *dst, int dstlen, bool one)
+///
+/// @param[in] buf When not NULL, uses this buffer to check whether it is
+/// a help file. If it is then path to file is removed
+/// completely, `one` is ignored and assumed to be true.
+/// @param[in] src Input file names. Assumed to be a space/comma separated
+/// list unless `one` is true.
+/// @param[out] dst Where to put the result.
+/// @param[in] dstlen Destination length.
+/// @param[in] one If true, assumes source is a single file name and not
+/// a list of them.
+///
+/// @return length of the string put into dst, does not include NUL byte.
+size_t home_replace(const buf_T *const buf, const char_u *src,
+ char_u *const dst, size_t dstlen, const bool one)
+ FUNC_ATTR_NONNULL_ARG(3)
{
- size_t dirlen = 0, envlen = 0;
- size_t len;
+ size_t dirlen = 0;
+ size_t envlen = 0;
if (src == NULL) {
*dst = NUL;
- return;
+ return 0;
}
- /*
- * If the file is a help file, remove the path completely.
- */
if (buf != NULL && buf->b_help) {
- STRCPY(dst, path_tail(src));
- return;
+ const size_t dlen = xstrlcpy((char *)dst, (char *)path_tail(src), dstlen);
+ return MIN(dlen, dstlen - 1);
}
- /*
- * We check both the value of the $HOME environment variable and the
- * "real" home directory.
- */
- if (homedir != NULL)
- dirlen = STRLEN(homedir);
+ // We check both the value of the $HOME environment variable and the
+ // "real" home directory.
+ if (homedir != NULL) {
+ dirlen = strlen(homedir);
+ }
- char_u *homedir_env = (char_u *)os_getenv("HOME");
+ const char *homedir_env = os_getenv("HOME");
+#ifdef WIN32
+ if (homedir_env == NULL) {
+ homedir_env = os_getenv("USERPROFILE");
+ }
+#endif
+ char *homedir_env_mod = (char *)homedir_env;
bool must_free = false;
- if (homedir_env != NULL && vim_strchr(homedir_env, '~') != NULL) {
+ if (homedir_env_mod != NULL && *homedir_env_mod == '~') {
must_free = true;
size_t usedlen = 0;
- size_t flen = STRLEN(homedir_env);
+ size_t flen = strlen(homedir_env_mod);
char_u *fbuf = NULL;
- (void)modify_fname((char_u *)":p", &usedlen, &homedir_env, &fbuf, &flen);
- flen = STRLEN(homedir_env);
- if (flen > 0 && vim_ispathsep(homedir_env[flen - 1]))
- /* Remove the trailing / that is added to a directory. */
- homedir_env[flen - 1] = NUL;
+ (void)modify_fname((char_u *)":p", &usedlen, (char_u **)&homedir_env_mod,
+ &fbuf, &flen);
+ flen = strlen(homedir_env_mod);
+ assert(homedir_env_mod != homedir_env);
+ if (vim_ispathsep(homedir_env_mod[flen - 1])) {
+ // Remove the trailing / that is added to a directory.
+ homedir_env_mod[flen - 1] = NUL;
+ }
}
- if (homedir_env != NULL)
- envlen = STRLEN(homedir_env);
+ if (homedir_env_mod != NULL) {
+ envlen = strlen(homedir_env_mod);
+ }
- if (!one)
+ if (!one) {
src = skipwhite(src);
+ }
+ char *dst_p = (char *)dst;
while (*src && dstlen > 0) {
- /*
- * Here we are at the beginning of a file name.
- * First, check to see if the beginning of the file name matches
- * $HOME or the "real" home directory. Check that there is a '/'
- * after the match (so that if e.g. the file is "/home/pieter/bla",
- * and the home directory is "/home/piet", the file does not end up
- * as "~er/bla" (which would seem to indicate the file "bla" in user
- * er's home directory)).
- */
- char_u *p = homedir;
- len = dirlen;
- for (;; ) {
- if ( len
- && fnamencmp(src, p, len) == 0
- && (vim_ispathsep(src[len])
- || (!one && (src[len] == ',' || src[len] == ' '))
- || src[len] == NUL)) {
+ // Here we are at the beginning of a file name.
+ // First, check to see if the beginning of the file name matches
+ // $HOME or the "real" home directory. Check that there is a '/'
+ // after the match (so that if e.g. the file is "/home/pieter/bla",
+ // and the home directory is "/home/piet", the file does not end up
+ // as "~er/bla" (which would seem to indicate the file "bla" in user
+ // er's home directory)).
+ char *p = homedir;
+ size_t len = dirlen;
+ for (;;) {
+ if (len
+ && fnamencmp(src, (char_u *)p, len) == 0
+ && (vim_ispathsep(src[len])
+ || (!one && (src[len] == ',' || src[len] == ' '))
+ || src[len] == NUL)) {
src += len;
- if (--dstlen > 0)
- *dst++ = '~';
-
- /*
- * If it's just the home directory, add "/".
- */
- if (!vim_ispathsep(src[0]) && --dstlen > 0)
- *dst++ = '/';
+ if (--dstlen > 0) {
+ *dst_p++ = '~';
+ }
+
+ // If it's just the home directory, add "/".
+ if (!vim_ispathsep(src[0]) && --dstlen > 0) {
+ *dst_p++ = '/';
+ }
break;
}
- if (p == homedir_env)
+ if (p == homedir_env_mod) {
break;
- p = homedir_env;
+ }
+ p = homedir_env_mod;
len = envlen;
}
- /* if (!one) skip to separator: space or comma */
- while (*src && (one || (*src != ',' && *src != ' ')) && --dstlen > 0)
- *dst++ = *src++;
- /* skip separator */
- while ((*src == ' ' || *src == ',') && --dstlen > 0)
- *dst++ = *src++;
+ // if (!one) skip to separator: space or comma.
+ while (*src && (one || (*src != ',' && *src != ' ')) && --dstlen > 0) {
+ *dst_p++ = (char)(*src++);
+ }
+ // Skip separator.
+ while ((*src == ' ' || *src == ',') && --dstlen > 0) {
+ *dst_p++ = (char)(*src++);
+ }
}
- /* if (dstlen == 0) out of space, what to do??? */
+ // If (dstlen == 0) out of space, what to do???
- *dst = NUL;
+ *dst_p = NUL;
if (must_free) {
- xfree(homedir_env);
+ xfree(homedir_env_mod);
}
+ return (size_t)(dst_p - (char *)dst);
}
/// Like home_replace, store the replaced string in allocated memory.
@@ -775,7 +865,7 @@ char_u * home_replace_save(buf_T *buf, char_u *src) FUNC_ATTR_NONNULL_RET
len += STRLEN(src);
}
char_u *dst = xmalloc(len);
- home_replace(buf, src, dst, (int)len, true);
+ home_replace(buf, src, dst, len, true);
return dst;
}
@@ -813,3 +903,61 @@ char_u *get_env_name(expand_T *xp, int idx)
return NULL;
}
+/// Appends the head of `fname` to $PATH and sets it in the environment.
+///
+/// @param fname Full path whose parent directory will be appended to $PATH.
+///
+/// @return true if `path` was appended-to
+bool os_setenv_append_path(const char *fname)
+ FUNC_ATTR_NONNULL_ALL
+{
+#ifdef WIN32
+// 8191 (plus NUL) is considered the practical maximum.
+# define MAX_ENVPATHLEN 8192
+#else
+// No prescribed maximum on unix.
+# define MAX_ENVPATHLEN INT_MAX
+#endif
+ if (!path_is_absolute((char_u *)fname)) {
+ internal_error("os_setenv_append_path()");
+ return false;
+ }
+ const char *tail = (char *)path_tail_with_sep((char_u *)fname);
+ size_t dirlen = (size_t)(tail - fname);
+ assert(tail >= fname && dirlen + 1 < sizeof(os_buf));
+ xstrlcpy(os_buf, fname, dirlen + 1);
+ const char *path = os_getenv("PATH");
+ const size_t pathlen = path ? strlen(path) : 0;
+ const size_t newlen = pathlen + dirlen + 2;
+ if (newlen < MAX_ENVPATHLEN) {
+ char *temp = xmalloc(newlen);
+ if (pathlen == 0) {
+ temp[0] = NUL;
+ } else {
+ xstrlcpy(temp, path, newlen);
+ xstrlcat(temp, ENV_SEPSTR, newlen);
+ }
+ xstrlcat(temp, os_buf, newlen);
+ os_setenv("PATH", temp, 1);
+ xfree(temp);
+ return true;
+ }
+ return false;
+}
+
+/// Returns true if `sh` looks like it resolves to "cmd.exe".
+bool os_shell_is_cmdexe(const char *sh)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (*sh == NUL) {
+ return false;
+ }
+ if (striequal(sh, "$COMSPEC")) {
+ const char *comspec = os_getenv("COMSPEC");
+ return striequal("cmd.exe", (char *)path_tail((char_u *)comspec));
+ }
+ if (striequal(sh, "cmd.exe") || striequal(sh, "cmd")) {
+ return true;
+ }
+ return striequal("cmd.exe", (char *)path_tail((char_u *)sh));
+}
diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c
index 6cee102305..ccf35fd57c 100644
--- a/src/nvim/os/fileio.c
+++ b/src/nvim/os/fileio.c
@@ -1,10 +1,12 @@
+// 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
+
/// @file fileio.c
///
/// Buffered reading/writing to a file. Unlike fileio.c this is not dealing with
-/// Neovim stuctures for buffer, with autocommands, etc: just fopen/fread/fwrite
+/// Nvim stuctures for buffer, with autocommands, etc: just fopen/fread/fwrite
/// replacement.
-#include <unistd.h>
#include <assert.h>
#include <stddef.h>
#include <stdbool.h>
@@ -24,6 +26,7 @@
#include "nvim/globals.h"
#include "nvim/rbuffer.h"
#include "nvim/macros.h"
+#include "nvim/message.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/fileio.c.generated.h"
@@ -36,18 +39,18 @@
/// @param[in] fname File name to open.
/// @param[in] flags Flags, @see FileOpenFlags. Currently reading from and
/// writing to the file at once is not supported, so either
-/// FILE_WRITE_ONLY or FILE_READ_ONLY is required.
+/// kFileWriteOnly or kFileReadOnly is required.
/// @param[in] mode Permissions for the newly created file (ignored if flags
-/// does not have FILE_CREATE\*).
+/// does not have kFileCreate\*).
///
-/// @return Error code (@see os_strerror()) or 0.
+/// @return Error code, or 0 on success. @see os_strerror()
int file_open(FileDescriptor *const ret_fp, const char *const fname,
const int flags, const int mode)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
int os_open_flags = 0;
- int fd;
TriState wr = kNone;
+ // -V:FLAG:501
#define FLAG(flags, flag, fcntl_flags, wrval, cond) \
do { \
if (flags & flag) { \
@@ -63,19 +66,51 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
FLAG(flags, kFileCreate, O_CREAT|O_WRONLY, kTrue, !(flags & kFileCreateOnly));
FLAG(flags, kFileTruncate, O_TRUNC|O_WRONLY, kTrue,
!(flags & kFileCreateOnly));
+ FLAG(flags, kFileAppend, O_APPEND|O_WRONLY, kTrue,
+ !(flags & kFileCreateOnly));
FLAG(flags, kFileReadOnly, O_RDONLY, kFalse, wr != kTrue);
#ifdef O_NOFOLLOW
FLAG(flags, kFileNoSymlink, O_NOFOLLOW, kNone, true);
#endif
#undef FLAG
+ // wr is used for kFileReadOnly flag, but on
+ // QB:neovim-qb-slave-ubuntu-12-04-64bit it still errors out with
+ // `error: variable ‘wr’ set but not used [-Werror=unused-but-set-variable]`
+ (void)wr;
- fd = os_open(fname, os_open_flags, mode);
+ const int fd = os_open(fname, os_open_flags, mode);
if (fd < 0) {
return fd;
}
+ return file_open_fd(ret_fp, fd, flags);
+}
- ret_fp->wr = (wr == kTrue);
+/// Wrap file descriptor with FileDescriptor structure
+///
+/// @warning File descriptor wrapped like this must not be accessed by other
+/// means.
+///
+/// @param[out] ret_fp Address where information needed for reading from or
+/// writing to a file is saved
+/// @param[in] fd File descriptor to wrap.
+/// @param[in] flags Flags, @see FileOpenFlags. Currently reading from and
+/// writing to the file at once is not supported, so either
+/// FILE_WRITE_ONLY or FILE_READ_ONLY is required.
+///
+/// @return Error code (@see os_strerror()) or 0. Currently always returns 0.
+int file_open_fd(FileDescriptor *const ret_fp, const int fd,
+ const int flags)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ ret_fp->wr = !!(flags & (kFileCreate
+ |kFileCreateOnly
+ |kFileTruncate
+ |kFileAppend
+ |kFileWriteOnly));
+ ret_fp->non_blocking = !!(flags & kFileNonBlocking);
+ // Non-blocking writes not supported currently.
+ assert(!ret_fp->wr || !ret_fp->non_blocking);
ret_fp->fd = fd;
ret_fp->eof = false;
ret_fp->rv = rbuffer_new(kRWBufferSize);
@@ -89,17 +124,16 @@ int file_open(FileDescriptor *const ret_fp, const char *const fname,
/// Like file_open(), but allocate and return ret_fp
///
-/// @param[out] error Error code, @see os_strerror(). Is set to zero on
-/// success.
+/// @param[out] error Error code, or 0 on success. @see os_strerror()
/// @param[in] fname File name to open.
/// @param[in] flags Flags, @see FileOpenFlags.
/// @param[in] mode Permissions for the newly created file (ignored if flags
-/// does not have FILE_CREATE\*).
+/// does not have kFileCreate\*).
///
/// @return [allocated] Opened file or NULL in case of error.
FileDescriptor *file_open_new(int *const error, const char *const fname,
const int flags, const int mode)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
FileDescriptor *const fp = xmalloc(sizeof(*fp));
if ((*error = file_open(fp, fname, flags, mode)) != 0) {
@@ -109,30 +143,55 @@ FileDescriptor *file_open_new(int *const error, const char *const fname,
return fp;
}
+/// Like file_open_fd(), but allocate and return ret_fp
+///
+/// @param[out] error Error code, or 0 on success. @see os_strerror()
+/// @param[in] fd File descriptor to wrap.
+/// @param[in] flags Flags, @see FileOpenFlags.
+/// @param[in] mode Permissions for the newly created file (ignored if flags
+/// does not have FILE_CREATE\*).
+///
+/// @return [allocated] Opened file or NULL in case of error.
+FileDescriptor *file_open_fd_new(int *const error, const int fd,
+ const int flags)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ FileDescriptor *const fp = xmalloc(sizeof(*fp));
+ if ((*error = file_open_fd(fp, fd, flags)) != 0) {
+ xfree(fp);
+ return NULL;
+ }
+ return fp;
+}
+
/// Close file and free its buffer
///
/// @param[in,out] fp File to close.
+/// @param[in] do_fsync If true, use fsync() to write changes to disk.
///
/// @return 0 or error code.
-int file_close(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
+int file_close(FileDescriptor *const fp, const bool do_fsync)
+ FUNC_ATTR_NONNULL_ALL
{
- const int error = file_fsync(fp);
- const int error2 = os_close(fp->fd);
+ const int flush_error = (do_fsync ? file_fsync(fp) : file_flush(fp));
+ const int close_error = os_close(fp->fd);
rbuffer_free(fp->rv);
- if (error2 != 0) {
- return error2;
+ if (close_error != 0) {
+ return close_error;
}
- return error;
+ return flush_error;
}
/// Close and free file obtained using file_open_new()
///
/// @param[in,out] fp File to close.
+/// @param[in] do_fsync If true, use fsync() to write changes to disk.
///
/// @return 0 or error code.
-int file_free(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
+int file_free(FileDescriptor *const fp, const bool do_fsync)
+ FUNC_ATTR_NONNULL_ALL
{
- const int ret = file_close(fp);
+ const int ret = file_close(fp, do_fsync);
xfree(fp);
return ret;
}
@@ -142,19 +201,38 @@ int file_free(FileDescriptor *const fp) FUNC_ATTR_NONNULL_ALL
/// @param[in,out] fp File to work with.
///
/// @return 0 or error code.
-int file_fsync(FileDescriptor *const fp)
+int file_flush(FileDescriptor *const fp)
FUNC_ATTR_NONNULL_ALL
{
if (!fp->wr) {
return 0;
}
file_rb_write_full_cb(fp->rv, fp);
- if (fp->_error != 0) {
- const int error = fp->_error;
- fp->_error = 0;
- return error;
+ const int error = fp->_error;
+ fp->_error = 0;
+ return error;
+}
+
+/// Flush file modifications to disk and run fsync()
+///
+/// @param[in,out] fp File to work with.
+///
+/// @return 0 or error code.
+int file_fsync(FileDescriptor *const fp)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (!fp->wr) {
+ return 0;
+ }
+ const int flush_error = file_flush(fp);
+ if (flush_error != 0) {
+ return flush_error;
+ }
+ const int fsync_error = os_fsync(fp->fd);
+ if (fsync_error != UV_EINVAL && fsync_error != UV_EROFS) {
+ return fsync_error;
}
- return os_fsync(fp->fd);
+ return 0;
}
/// Buffer used for writing
@@ -177,7 +255,8 @@ static void file_rb_write_full_cb(RBuffer *const rv, FileDescriptor *const fp)
return;
}
const size_t read_bytes = rbuffer_read(rv, writebuf, kRWBufferSize);
- const ptrdiff_t wres = os_write(fp->fd, writebuf, read_bytes);
+ const ptrdiff_t wres = os_write(fp->fd, writebuf, read_bytes,
+ fp->non_blocking);
if (wres != (ptrdiff_t)read_bytes) {
if (wres >= 0) {
fp->_error = UV_EIO;
@@ -203,6 +282,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
char *buf = ret_buf;
size_t read_remaining = size;
RBuffer *const rv = fp->rv;
+ bool called_read = false;
while (read_remaining) {
const size_t rv_size = rbuffer_size(rv);
if (rv_size > 0) {
@@ -210,7 +290,9 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
buf += rsize;
read_remaining -= rsize;
}
- if (fp->eof) {
+ if (fp->eof
+ // Allow only at most one os_read[v] call.
+ || (called_read && fp->non_blocking)) {
break;
}
if (read_remaining) {
@@ -227,7 +309,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
};
assert(write_count == kRWBufferSize);
const ptrdiff_t r_ret = os_readv(fp->fd, &fp->eof, iov,
- ARRAY_SIZE(iov));
+ ARRAY_SIZE(iov), fp->non_blocking);
if (r_ret > 0) {
if (r_ret > (ptrdiff_t)read_remaining) {
rbuffer_produced(rv, (size_t)(r_ret - (ptrdiff_t)read_remaining));
@@ -243,7 +325,8 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
if (read_remaining >= kRWBufferSize) {
// …otherwise leave RBuffer empty and populate only target buffer,
// because filtering information through rbuffer will be more syscalls.
- const ptrdiff_t r_ret = os_read(fp->fd, &fp->eof, buf, read_remaining);
+ const ptrdiff_t r_ret = os_read(fp->fd, &fp->eof, buf, read_remaining,
+ fp->non_blocking);
if (r_ret >= 0) {
read_remaining -= (size_t)r_ret;
return (ptrdiff_t)(size - read_remaining);
@@ -254,7 +337,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
size_t write_count;
const ptrdiff_t r_ret = os_read(fp->fd, &fp->eof,
rbuffer_write_ptr(rv, &write_count),
- kRWBufferSize);
+ kRWBufferSize, fp->non_blocking);
assert(write_count == kRWBufferSize);
if (r_ret > 0) {
rbuffer_produced(rv, (size_t)r_ret);
@@ -263,6 +346,7 @@ ptrdiff_t file_read(FileDescriptor *const fp, char *const ret_buf,
}
}
#endif
+ called_read = true;
}
}
return (ptrdiff_t)(size - read_remaining);
@@ -317,3 +401,32 @@ ptrdiff_t file_skip(FileDescriptor *const fp, const size_t size)
return (ptrdiff_t)read_bytes;
}
+
+/// Msgpack callback for writing to a file
+///
+/// @param data File to write to.
+/// @param[in] buf Data to write.
+/// @param[in] len Length of the data to write.
+///
+/// @return 0 in case of success, -1 in case of error.
+int msgpack_file_write(void *data, const char *buf, size_t len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ assert(len < PTRDIFF_MAX);
+ const ptrdiff_t written_bytes = file_write((FileDescriptor *)data, buf, len);
+ if (written_bytes < 0) {
+ return msgpack_file_write_error((int)written_bytes);
+ }
+ return 0;
+}
+
+/// Print error which occurs when failing to write msgpack data
+///
+/// @param[in] error Error code of the error to print.
+///
+/// @return -1 (error return for msgpack_packer callbacks).
+int msgpack_file_write_error(const int error)
+{
+ emsgf(_("E5420: Failed to write to file: %s"), os_strerror(error));
+ return -1;
+}
diff --git a/src/nvim/os/fileio.h b/src/nvim/os/fileio.h
index 2cffd5c851..7c53cd4f07 100644
--- a/src/nvim/os/fileio.h
+++ b/src/nvim/os/fileio.h
@@ -14,6 +14,7 @@ typedef struct {
RBuffer *rv; ///< Read or write buffer.
bool wr; ///< True if file is in write mode.
bool eof; ///< True if end of file was encountered.
+ bool non_blocking; ///< True if EAGAIN should not restart syscalls.
} FileDescriptor;
/// file_open() flags
@@ -30,6 +31,10 @@ typedef enum {
kFileTruncate = 32, ///< Truncate the file if it exists.
///< Implies kFileWriteOnly. Cannot be used with
///< kFileCreateOnly.
+ kFileAppend = 64, ///< Append to the file. Implies kFileWriteOnly. Cannot
+ ///< be used with kFileCreateOnly.
+ kFileNonBlocking = 128, ///< Do not restart read() or write() syscall if
+ ///< EAGAIN was encountered.
} FileOpenFlags;
static inline bool file_eof(const FileDescriptor *const fp)
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index d12d34d595..9a4391a0ae 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -1,9 +1,11 @@
+// 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
+
// fs.c -- filesystem access
#include <stdbool.h>
#include <stddef.h>
#include <assert.h>
#include <limits.h>
-#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@@ -22,10 +24,13 @@
#include "nvim/message.h"
#include "nvim/assert.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/path.h"
#include "nvim/strings.h"
+#ifdef WIN32
+#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+#endif
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/fs.c.generated.h"
#endif
@@ -56,9 +61,9 @@ void fs_init(void)
}
-/// Change to the given directory.
+/// Changes the current directory to `path`.
///
-/// @return `0` on success, a libuv error code on failure.
+/// @return 0 on success, or negative error code.
int os_chdir(const char *path)
FUNC_ATTR_NONNULL_ALL
{
@@ -89,11 +94,11 @@ int os_dirname(char_u *buf, size_t len)
/// Check if the given path is a directory and not a symlink to a directory.
/// @return `true` if `name` is a directory and NOT a symlink to a directory.
/// `false` if `name` is not a directory or if an error occurred.
-bool os_isrealdir(const char_u *name)
+bool os_isrealdir(const char *name)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
- if (uv_fs_lstat(&fs_loop, &request, (char *)name, NULL) != kLibuvSuccess) {
+ if (uv_fs_lstat(&fs_loop, &request, name, NULL) != kLibuvSuccess) {
return false;
}
if (S_ISLNK(request.statbuf.st_mode)) {
@@ -105,11 +110,11 @@ bool os_isrealdir(const char_u *name)
/// Check if the given path is a directory or not.
///
-/// @return `true` if `fname` is a directory.
+/// @return `true` if `name` is a directory.
bool os_isdir(const char_u *name)
FUNC_ATTR_NONNULL_ALL
{
- int32_t mode = os_getperm(name);
+ int32_t mode = os_getperm((const char *)name);
if (mode < 0) {
return false;
}
@@ -121,28 +126,38 @@ bool os_isdir(const char_u *name)
return true;
}
+/// Check if the given path is a directory and is executable.
+/// Gives the same results as `os_isdir()` on Windows.
+///
+/// @return `true` if `name` is a directory and executable.
+bool os_isdir_executable(const char *name)
+ FUNC_ATTR_NONNULL_ALL
+{
+ int32_t mode = os_getperm((const char *)name);
+ if (mode < 0) {
+ return false;
+ }
+
+#ifdef WIN32
+ return (S_ISDIR(mode));
+#else
+ return (S_ISDIR(mode) && (S_IXUSR & mode));
+#endif
+}
+
/// Check what `name` is:
/// @return NODE_NORMAL: file or directory (or doesn't exist)
/// NODE_WRITABLE: writable device, socket, fifo, etc.
/// NODE_OTHER: non-writable things
int os_nodetype(const char *name)
+ FUNC_ATTR_NONNULL_ALL
{
-#ifdef WIN32
- // Edge case from Vim os_win32.c:
- // We can't open a file with a name "\\.\con" or "\\.\prn", trying to read
- // from it later will cause Vim to hang. Thus return NODE_WRITABLE here.
- if (STRNCMP(name, "\\\\.\\", 4) == 0) {
- return NODE_WRITABLE;
- }
-#endif
-
+#ifndef WIN32 // Unix
uv_stat_t statbuf;
if (0 != os_stat(name, &statbuf)) {
return NODE_NORMAL; // File doesn't exist.
}
-
-#ifndef WIN32
- // libuv does not handle BLK and DIR in uv_handle_type.
+ // uv_handle_type does not distinguish BLK and DIR.
// Related: https://github.com/joyent/libuv/pull/1421
if (S_ISREG(statbuf.st_mode) || S_ISDIR(statbuf.st_mode)) {
return NODE_NORMAL;
@@ -150,40 +165,65 @@ int os_nodetype(const char *name)
if (S_ISBLK(statbuf.st_mode)) { // block device isn't writable
return NODE_OTHER;
}
-#endif
+ // Everything else is writable?
+ // buf_write() expects NODE_WRITABLE for char device /dev/stderr.
+ return NODE_WRITABLE;
+#else // Windows
+ // Edge case from Vim os_win32.c:
+ // We can't open a file with a name "\\.\con" or "\\.\prn", trying to read
+ // from it later will cause Vim to hang. Thus return NODE_WRITABLE here.
+ if (STRNCMP(name, "\\\\.\\", 4) == 0) {
+ return NODE_WRITABLE;
+ }
- // Vim os_win32.c:mch_nodetype does this (since patch 7.4.015):
- // if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) {
- // wn = enc_to_utf16(name, NULL);
- // hFile = CreatFile(wn, ...)
- // to get a HANDLE. But libuv just calls win32's _get_osfhandle() on the fd we
- // give it. uv_fs_open calls fs__capture_path which does a similar dance and
- // saves us the hassle.
-
- int nodetype = NODE_WRITABLE;
- int fd = os_open(name, O_RDONLY, 0);
- switch(uv_guess_handle(fd)) {
- case UV_TTY: // FILE_TYPE_CHAR
- nodetype = NODE_WRITABLE;
- break;
- case UV_FILE: // FILE_TYPE_DISK
- nodetype = NODE_NORMAL;
- break;
- case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c
- case UV_UDP: // unix only
- case UV_TCP: // unix only
+ // Vim os_win32.c:mch_nodetype does (since 7.4.015):
+ // wn = enc_to_utf16(name, NULL);
+ // hFile = CreatFile(wn, ...)
+ // to get a HANDLE. Whereas libuv just calls _get_osfhandle() on the fd we
+ // give it. But uv_fs_open later calls fs__capture_path which does a similar
+ // utf8-to-utf16 dance and saves us the hassle.
+
+ // macOS: os_open(/dev/stderr) would return UV_EACCES.
+ int fd = os_open(name, O_RDONLY
+# ifdef O_NONBLOCK
+ | O_NONBLOCK
+# endif
+ , 0);
+ if (fd < 0) { // open() failed.
+ return NODE_NORMAL;
+ }
+ int guess = uv_guess_handle(fd);
+ if (close(fd) == -1) {
+ ELOG("close(%d) failed. name='%s'", fd, name);
+ }
+
+ switch (guess) {
+ case UV_TTY: // FILE_TYPE_CHAR
+ return NODE_WRITABLE;
+ case UV_FILE: // FILE_TYPE_DISK
+ return NODE_NORMAL;
+ case UV_NAMED_PIPE: // not handled explicitly in Vim os_win32.c
+ case UV_UDP: // unix only
+ case UV_TCP: // unix only
case UV_UNKNOWN_HANDLE:
default:
-#ifdef WIN32
- nodetype = NODE_NORMAL;
-#else
- nodetype = NODE_WRITABLE; // Everything else is writable?
-#endif
- break;
+ return NODE_OTHER; // Vim os_win32.c default
}
+#endif
+}
- close(fd);
- return nodetype;
+/// Gets the absolute path of the currently running executable.
+/// May fail if procfs is missing. #6734
+/// @see path_exepath
+///
+/// @param[out] buffer Full path to the executable.
+/// @param[in] size Size of `buffer`.
+///
+/// @return 0 on success, or libuv error code.
+int os_exepath(char *buffer, size_t *size)
+ FUNC_ATTR_NONNULL_ALL
+{
+ return uv_exepath(buffer, size);
}
/// Checks if the given path represents an executable file.
@@ -201,49 +241,87 @@ int os_nodetype(const char *name)
bool os_can_exe(const char_u *name, char_u **abspath, bool use_path)
FUNC_ATTR_NONNULL_ARG(1)
{
- // when use_path is false or if it's an absolute or relative path don't
- // need to use $PATH.
- if (!use_path || path_is_absolute_path(name)
- || (name[0] == '.'
- && (name[1] == '/'
- || (name[1] == '.' && name[2] == '/')))) {
- // There must be a path separator, files in the current directory
- // can't be executed
- if (gettail_dir(name) != name && is_executable(name)) {
+ bool no_path = !use_path || path_is_absolute(name);
+#ifndef WIN32
+ // If the filename is "qualified" (relative or absolute) do not check $PATH.
+ no_path |= (name[0] == '.'
+ && (name[1] == '/' || (name[1] == '.' && name[2] == '/')));
+#endif
+
+ if (no_path) {
+#ifdef WIN32
+ const char *pathext = os_getenv("PATHEXT");
+ if (!pathext) {
+ pathext = ".com;.exe;.bat;.cmd";
+ }
+ bool ok = is_executable((char *)name) || is_executable_ext((char *)name,
+ pathext);
+#else
+ // Must have path separator, cannot execute files in the current directory.
+ const bool ok = ((const char_u *)gettail_dir((const char *)name) != name
+ && is_executable((char *)name));
+#endif
+ if (ok) {
if (abspath != NULL) {
- *abspath = save_absolute_path(name);
+ *abspath = save_abs_path(name);
}
-
return true;
}
-
return false;
}
return is_executable_in_path(name, abspath);
}
-// Return true if "name" is an executable file, false if not or it doesn't
-// exist.
-static bool is_executable(const char_u *name)
+/// Returns true if `name` is an executable file.
+static bool is_executable(const char *name)
FUNC_ATTR_NONNULL_ALL
{
- int32_t mode = os_getperm(name);
+ int32_t mode = os_getperm((const char *)name);
if (mode < 0) {
return false;
}
-#if WIN32
+#ifdef WIN32
// Windows does not have exec bit; just check if the file exists and is not
// a directory.
return (S_ISREG(mode));
#else
return (S_ISREG(mode) && (S_IXUSR & mode));
#endif
+}
+
+#ifdef WIN32
+/// Appends file extensions from `pathext` to `name` and returns true if any
+/// such combination is executable.
+static bool is_executable_ext(char *name, const char *pathext)
+ FUNC_ATTR_NONNULL_ALL
+{
+ xstrlcpy(os_buf, name, sizeof(os_buf));
+ char *buf_end = xstrchrnul(os_buf, '\0');
+ for (const char *ext = pathext; *ext; ext++) {
+ // Skip the extension if there is no suffix after a '.'.
+ if (ext[0] == '.' && (ext[1] == '\0' || ext[1] == ENV_SEPCHAR)) {
+ ext++;
+ continue;
+ }
+
+ const char *ext_end = xstrchrnul(ext, ENV_SEPCHAR);
+ STRLCPY(buf_end, ext, ext_end - ext + 1);
+ if (is_executable(os_buf)) {
+ return true;
+ }
+
+ if (*ext_end != ENV_SEPCHAR) {
+ break;
+ }
+ ext = ext_end;
+ }
return false;
}
+#endif
/// Checks if a file is inside the `$PATH` and is executable.
///
@@ -254,89 +332,69 @@ static bool is_executable(const char_u *name)
static bool is_executable_in_path(const char_u *name, char_u **abspath)
FUNC_ATTR_NONNULL_ARG(1)
{
- const char *path = os_getenv("PATH");
- if (path == NULL) {
+ const char *path_env = os_getenv("PATH");
+ if (path_env == NULL) {
return false;
}
- size_t buf_len = STRLEN(name) + STRLEN(path) + 2;
+#ifdef WIN32
+ // Prepend ".;" to $PATH.
+ size_t pathlen = strlen(path_env);
+ char *path = memcpy(xmallocz(pathlen + 3), "." ENV_SEPSTR, 2);
+ memcpy(path + 2, path_env, pathlen);
+#else
+ char *path = xstrdup(path_env);
+#endif
+
+ size_t buf_len = STRLEN(name) + strlen(path) + 2;
#ifdef WIN32
const char *pathext = os_getenv("PATHEXT");
if (!pathext) {
pathext = ".com;.exe;.bat;.cmd";
}
-
- buf_len += STRLEN(pathext);
+ buf_len += strlen(pathext);
#endif
- char_u *buf = xmalloc(buf_len);
+ char *buf = xmalloc(buf_len);
// Walk through all entries in $PATH to check if "name" exists there and
// is an executable file.
+ char *p = path;
+ bool rv = false;
for (;; ) {
- const char *e = xstrchrnul(path, ENV_SEPCHAR);
-
- // Glue together the given directory from $PATH with name and save into
- // buf.
- STRLCPY(buf, path, e - path + 1);
- append_path((char *) buf, (const char *) name, buf_len);
-
- if (is_executable(buf)) {
- // Check if the caller asked for a copy of the path.
- if (abspath != NULL) {
- *abspath = save_absolute_path(buf);
- }
+ char *e = xstrchrnul(p, ENV_SEPCHAR);
- xfree(buf);
-
- return true;
- }
+ // Combine the $PATH segment with `name`.
+ STRLCPY(buf, p, e - p + 1);
+ append_path(buf, (char *)name, buf_len);
#ifdef WIN32
- // Try appending file extensions from $PATHEXT to the name.
- char *buf_end = xstrchrnul((char *)buf, '\0');
- for (const char *ext = pathext; *ext; ext++) {
- // Skip the extension if there is no suffix after a '.'.
- if (ext[0] == '.' && (ext[1] == '\0' || ext[1] == ';')) {
- *ext++;
-
- continue;
- }
-
- const char *ext_end = xstrchrnul(ext, ENV_SEPCHAR);
- STRLCPY(buf_end, ext, ext_end - ext + 1);
-
- if (is_executable(buf)) {
- // Check if the caller asked for a copy of the path.
- if (abspath != NULL) {
- *abspath = save_absolute_path(buf);
- }
-
- xfree(buf);
-
- return true;
+ bool ok = is_executable(buf) || is_executable_ext(buf, pathext);
+#else
+ bool ok = is_executable(buf);
+#endif
+ if (ok) {
+ if (abspath != NULL) { // Caller asked for a copy of the path.
+ *abspath = save_abs_path((char_u *)buf);
}
- if (*ext_end != ENV_SEPCHAR) {
- break;
- }
- ext = ext_end;
+ rv = true;
+ goto end;
}
-#endif
if (*e != ENV_SEPCHAR) {
// End of $PATH without finding any executable called name.
- xfree(buf);
- return false;
+ goto end;
}
- path = e + 1;
+ p = e + 1;
}
- // We should never get to this point.
- assert(false);
- return false;
+end:
+ xfree(buf);
+ xfree(path);
+ return rv;
}
/// Opens or creates a file and returns a non-negative integer representing
@@ -348,14 +406,45 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
/// @param mode Permissions for the newly-created file (IGNORED if 'flags' is
/// not `O_CREAT` or `O_TMPFILE`), subject to the current umask
/// @return file descriptor, or libuv error code on failure
-int os_open(const char* path, int flags, int mode)
- FUNC_ATTR_NONNULL_ALL
+int os_open(const char *path, int flags, int mode)
{
+ if (path == NULL) { // uv_fs_open asserts on NULL. #7561
+ return UV_EINVAL;
+ }
int r;
RUN_UV_FS_FUNC(r, uv_fs_open, path, flags, mode, NULL);
return r;
}
+/// Sets file descriptor `fd` to close-on-exec.
+//
+// @return -1 if failed to set, 0 otherwise.
+int os_set_cloexec(const int fd)
+{
+#ifdef HAVE_FD_CLOEXEC
+ int e;
+ int fdflags = fcntl(fd, F_GETFD);
+ if (fdflags < 0) {
+ e = errno;
+ ELOG("Failed to get flags on descriptor %d: %s", fd, strerror(e));
+ errno = e;
+ return -1;
+ }
+ if ((fdflags & FD_CLOEXEC) == 0
+ && fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC) == -1) {
+ e = errno;
+ ELOG("Failed to set CLOEXEC on descriptor %d: %s", fd, strerror(e));
+ errno = e;
+ return -1;
+ }
+ return 0;
+#endif
+
+ // No FD_CLOEXEC flag. On Windows, the file should have been opened with
+ // O_NOINHERIT anyway.
+ return -1;
+}
+
/// Close a file
///
/// @return 0 or libuv error code on failure.
@@ -366,6 +455,29 @@ int os_close(const int fd)
return r;
}
+/// Duplicate file descriptor
+///
+/// @param[in] fd File descriptor to duplicate.
+///
+/// @return New file descriptor or libuv error code (< 0).
+int os_dup(const int fd)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int ret;
+os_dup_dup:
+ ret = dup(fd);
+ if (ret < 0) {
+ const int error = os_translate_sys_error(errno);
+ errno = 0;
+ if (error == UV_EINTR) {
+ goto os_dup_dup;
+ } else {
+ return error;
+ }
+ }
+ return ret;
+}
+
/// Read from a file
///
/// Handles EINTR and ENOMEM, but not other errors.
@@ -375,10 +487,11 @@ int os_close(const int fd)
/// to false. Initial value is ignored.
/// @param[out] ret_buf Buffer to write to. May be NULL if size is zero.
/// @param[in] size Amount of bytes to read.
+/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered.
///
/// @return Number of bytes read or libuv error code (< 0).
-ptrdiff_t os_read(const int fd, bool *ret_eof, char *const ret_buf,
- const size_t size)
+ptrdiff_t os_read(const int fd, bool *const ret_eof, char *const ret_buf,
+ const size_t size, const bool non_blocking)
FUNC_ATTR_WARN_UNUSED_RESULT
{
*ret_eof = false;
@@ -389,23 +502,18 @@ ptrdiff_t os_read(const int fd, bool *ret_eof, char *const ret_buf,
size_t read_bytes = 0;
bool did_try_to_free = false;
while (read_bytes != size) {
+ assert(size >= read_bytes);
const ptrdiff_t cur_read_bytes = read(fd, ret_buf + read_bytes,
- size - read_bytes);
+ IO_COUNT(size - read_bytes));
if (cur_read_bytes > 0) {
read_bytes += (size_t)cur_read_bytes;
- assert(read_bytes <= size);
}
if (cur_read_bytes < 0) {
-#ifdef HAVE_UV_TRANSLATE_SYS_ERROR
- const int error = uv_translate_sys_error(errno);
-#else
- const int error = -errno;
- STATIC_ASSERT(-EINTR == UV_EINTR, "Need to translate error codes");
- STATIC_ASSERT(-EAGAIN == UV_EAGAIN, "Need to translate error codes");
- STATIC_ASSERT(-ENOMEM == UV_ENOMEM, "Need to translate error codes");
-#endif
+ const int error = os_translate_sys_error(errno);
errno = 0;
- if (error == UV_EINTR || error == UV_EAGAIN) {
+ if (non_blocking && error == UV_EAGAIN) {
+ break;
+ } else if (error == UV_EINTR || error == UV_EAGAIN) {
continue;
} else if (error == UV_ENOMEM && !did_try_to_free) {
try_to_free_memory();
@@ -435,7 +543,11 @@ ptrdiff_t os_read(const int fd, bool *ret_eof, char *const ret_buf,
/// may change, it is incorrect to use data it points to after
/// os_readv().
/// @param[in] iov_size Number of buffers in iov.
-ptrdiff_t os_readv(int fd, bool *ret_eof, struct iovec *iov, size_t iov_size)
+/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered.
+///
+/// @return Number of bytes read or libuv error code (< 0).
+ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov,
+ size_t iov_size, const bool non_blocking)
FUNC_ATTR_NONNULL_ALL
{
*ret_eof = false;
@@ -449,7 +561,7 @@ ptrdiff_t os_readv(int fd, bool *ret_eof, struct iovec *iov, size_t iov_size)
}
while (read_bytes < toread && iov_size && !*ret_eof) {
ptrdiff_t cur_read_bytes = readv(fd, iov, (int)iov_size);
- if (toread && cur_read_bytes == 0) {
+ if (cur_read_bytes == 0) {
*ret_eof = true;
}
if (cur_read_bytes > 0) {
@@ -466,16 +578,11 @@ ptrdiff_t os_readv(int fd, bool *ret_eof, struct iovec *iov, size_t iov_size)
}
}
} else if (cur_read_bytes < 0) {
-#ifdef HAVE_UV_TRANSLATE_SYS_ERROR
- const int error = uv_translate_sys_error(errno);
-#else
- const int error = -errno;
- STATIC_ASSERT(-EINTR == UV_EINTR, "Need to translate error codes");
- STATIC_ASSERT(-EAGAIN == UV_EAGAIN, "Need to translate error codes");
- STATIC_ASSERT(-ENOMEM == UV_ENOMEM, "Need to translate error codes");
-#endif
+ const int error = os_translate_sys_error(errno);
errno = 0;
- if (error == UV_EINTR || error == UV_EAGAIN) {
+ if (non_blocking && error == UV_EAGAIN) {
+ break;
+ } else if (error == UV_EINTR || error == UV_EAGAIN) {
continue;
} else if (error == UV_ENOMEM && !did_try_to_free) {
try_to_free_memory();
@@ -495,9 +602,11 @@ ptrdiff_t os_readv(int fd, bool *ret_eof, struct iovec *iov, size_t iov_size)
/// @param[in] fd File descriptor to write to.
/// @param[in] buf Data to write. May be NULL if size is zero.
/// @param[in] size Amount of bytes to write.
+/// @param[in] non_blocking Do not restart syscall if EAGAIN was encountered.
///
/// @return Number of bytes written or libuv error code (< 0).
-ptrdiff_t os_write(const int fd, const char *const buf, const size_t size)
+ptrdiff_t os_write(const int fd, const char *const buf, const size_t size,
+ const bool non_blocking)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (buf == NULL) {
@@ -506,23 +615,18 @@ ptrdiff_t os_write(const int fd, const char *const buf, const size_t size)
}
size_t written_bytes = 0;
while (written_bytes != size) {
+ assert(size >= written_bytes);
const ptrdiff_t cur_written_bytes = write(fd, buf + written_bytes,
- size - written_bytes);
+ IO_COUNT(size - written_bytes));
if (cur_written_bytes > 0) {
written_bytes += (size_t)cur_written_bytes;
}
if (cur_written_bytes < 0) {
-#ifdef HAVE_UV_TRANSLATE_SYS_ERROR
- const int error = uv_translate_sys_error(errno);
-#else
- const int error = -errno;
- STATIC_ASSERT(-EINTR == UV_EINTR, "Need to translate error codes");
- STATIC_ASSERT(-EAGAIN == UV_EAGAIN, "Need to translate error codes");
- // According to the man page open() may fail with ENOMEM, but write()
- // can’t.
-#endif
+ const int error = os_translate_sys_error(errno);
errno = 0;
- if (error == UV_EINTR || error == UV_EAGAIN) {
+ if (non_blocking && error == UV_EAGAIN) {
+ break;
+ } else if (error == UV_EINTR || error == UV_EAGAIN) {
continue;
} else {
return error;
@@ -544,15 +648,19 @@ int os_fsync(int fd)
{
int r;
RUN_UV_FS_FUNC(r, uv_fs_fsync, fd, NULL);
+ g_stats.fsync++;
return r;
}
/// Get stat information for a file.
///
-/// @return libuv return code.
+/// @return libuv return code, or -errno
static int os_stat(const char *name, uv_stat_t *statbuf)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ARG(2)
{
+ if (!name) {
+ return UV_EINVAL;
+ }
uv_fs_t request;
int result = uv_fs_stat(&fs_loop, &request, name, NULL);
*statbuf = request.statbuf;
@@ -563,11 +671,10 @@ static int os_stat(const char *name, uv_stat_t *statbuf)
/// Get the file permissions for a given file.
///
/// @return libuv error code on error.
-int32_t os_getperm(const char_u *name)
- FUNC_ATTR_NONNULL_ALL
+int32_t os_getperm(const char *name)
{
uv_stat_t statbuf;
- int stat_result = os_stat((char *)name, &statbuf);
+ int stat_result = os_stat(name, &statbuf);
if (stat_result == kLibuvSuccess) {
return (int32_t)statbuf.st_mode;
} else {
@@ -578,11 +685,11 @@ int32_t os_getperm(const char_u *name)
/// Set the permission of a file.
///
/// @return `OK` for success, `FAIL` for failure.
-int os_setperm(const char_u *name, int perm)
+int os_setperm(const char *const name, int perm)
FUNC_ATTR_NONNULL_ALL
{
int r;
- RUN_UV_FS_FUNC(r, uv_fs_chmod, (const char *)name, perm, NULL);
+ RUN_UV_FS_FUNC(r, uv_fs_chmod, name, perm, NULL);
return (r == kLibuvSuccess ? OK : FAIL);
}
@@ -603,7 +710,6 @@ int os_fchown(int fd, uv_uid_t owner, uv_gid_t group)
///
/// @return `true` if `path` exists
bool os_path_exists(const char_u *path)
- FUNC_ATTR_NONNULL_ALL
{
uv_stat_t statbuf;
return os_stat((char *)path, &statbuf) == kLibuvSuccess;
@@ -793,7 +899,7 @@ int os_remove(const char *path)
/// @param[out] file_info Pointer to a FileInfo to put the information in.
/// @return `true` on success, `false` for failure.
bool os_fileinfo(const char *path, FileInfo *file_info)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ARG(2)
{
return os_stat(path, &(file_info->stat)) == kLibuvSuccess;
}
@@ -804,8 +910,11 @@ bool os_fileinfo(const char *path, FileInfo *file_info)
/// @param[out] file_info Pointer to a FileInfo to put the information in.
/// @return `true` on success, `false` for failure.
bool os_fileinfo_link(const char *path, FileInfo *file_info)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ARG(2)
{
+ if (path == NULL) {
+ return false;
+ }
uv_fs_t request;
int result = uv_fs_lstat(&fs_loop, &request, path, NULL);
file_info->stat = request.statbuf;
@@ -923,10 +1032,223 @@ bool os_fileid_equal(const FileID *file_id_1, const FileID *file_id_2)
/// @param file_info Pointer to a `FileInfo`
/// @return `true` if the `FileID` and the `FileInfo` represent te same file.
bool os_fileid_equal_fileinfo(const FileID *file_id,
- const FileInfo *file_info)
+ const FileInfo *file_info)
FUNC_ATTR_NONNULL_ALL
{
return file_id->inode == file_info->stat.st_ino
&& file_id->device_id == file_info->stat.st_dev;
}
+#ifdef WIN32
+# include <shlobj.h>
+
+/// When "fname" is the name of a shortcut (*.lnk) resolve the file it points
+/// to and return that name in allocated memory.
+/// Otherwise NULL is returned.
+char *os_resolve_shortcut(const char *fname)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
+{
+ HRESULT hr;
+ IPersistFile *ppf = NULL;
+ OLECHAR wsz[MAX_PATH];
+ char *rfname = NULL;
+ IShellLinkW *pslw = NULL;
+ WIN32_FIND_DATAW ffdw;
+
+ // Check if the file name ends in ".lnk". Avoid calling CoCreateInstance(),
+ // it's quite slow.
+ if (fname == NULL) {
+ return rfname;
+ }
+ const size_t len = strlen(fname);
+ if (len <= 4 || STRNICMP(fname + len - 4, ".lnk", 4) != 0) {
+ return rfname;
+ }
+
+ CoInitialize(NULL);
+
+ // create a link manager object and request its interface
+ hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IShellLinkW, (void **)&pslw);
+ if (hr == S_OK) {
+ wchar_t *p;
+ const int conversion_result = utf8_to_utf16(fname, &p);
+ if (conversion_result != 0) {
+ EMSG2("utf8_to_utf16 failed: %d", conversion_result);
+ }
+
+ if (p != NULL) {
+ // Get a pointer to the IPersistFile interface.
+ hr = pslw->lpVtbl->QueryInterface(
+ pslw, &IID_IPersistFile, (void **)&ppf);
+ if (hr != S_OK) {
+ goto shortcut_errorw;
+ }
+
+ // "load" the name and resolve the link
+ hr = ppf->lpVtbl->Load(ppf, p, STGM_READ);
+ if (hr != S_OK) {
+ goto shortcut_errorw;
+ }
+
+# if 0 // This makes Vim wait a long time if the target does not exist.
+ hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI);
+ if (hr != S_OK) {
+ goto shortcut_errorw;
+ }
+# endif
+
+ // Get the path to the link target.
+ ZeroMemory(wsz, MAX_PATH * sizeof(wchar_t));
+ hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0);
+ if (hr == S_OK && wsz[0] != NUL) {
+ const int conversion_result = utf16_to_utf8(wsz, &rfname);
+ if (conversion_result != 0) {
+ EMSG2("utf16_to_utf8 failed: %s", uv_strerror(conversion_result));
+ }
+ }
+
+shortcut_errorw:
+ xfree(p);
+ goto shortcut_end;
+ }
+ }
+
+shortcut_end:
+ // Release all interface pointers (both belong to the same object)
+ if (ppf != NULL) {
+ ppf->lpVtbl->Release(ppf);
+ }
+ if (pslw != NULL) {
+ pslw->lpVtbl->Release(pslw);
+ }
+
+ CoUninitialize();
+ return rfname;
+}
+
+#endif
+
+int os_translate_sys_error(int sys_errno)
+{
+#ifdef HAVE_UV_TRANSLATE_SYS_ERROR
+ return uv_translate_sys_error(sys_errno);
+#elif defined(WIN32)
+ // TODO(equalsraf): libuv does not yet expose uv_translate_sys_error()
+ // in its public API, include a version here until it can be used.
+ // See https://github.com/libuv/libuv/issues/79
+# ifndef ERROR_SYMLINK_NOT_SUPPORTED
+# define ERROR_SYMLINK_NOT_SUPPORTED 1464
+# endif
+
+ if (sys_errno <= 0) {
+ return sys_errno; // If < 0 then it's already a libuv error
+ }
+
+ switch (sys_errno) {
+ case ERROR_NOACCESS: return UV_EACCES;
+ case WSAEACCES: return UV_EACCES;
+ case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
+ case WSAEADDRINUSE: return UV_EADDRINUSE;
+ case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
+ case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT;
+ case WSAEWOULDBLOCK: return UV_EAGAIN;
+ case WSAEALREADY: return UV_EALREADY;
+ case ERROR_INVALID_FLAGS: return UV_EBADF;
+ case ERROR_INVALID_HANDLE: return UV_EBADF;
+ case ERROR_LOCK_VIOLATION: return UV_EBUSY;
+ case ERROR_PIPE_BUSY: return UV_EBUSY;
+ case ERROR_SHARING_VIOLATION: return UV_EBUSY;
+ case ERROR_OPERATION_ABORTED: return UV_ECANCELED;
+ case WSAEINTR: return UV_ECANCELED;
+ case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
+ case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
+ case WSAECONNABORTED: return UV_ECONNABORTED;
+ case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED;
+ case WSAECONNREFUSED: return UV_ECONNREFUSED;
+ case ERROR_NETNAME_DELETED: return UV_ECONNRESET;
+ case WSAECONNRESET: return UV_ECONNRESET;
+ case ERROR_ALREADY_EXISTS: return UV_EEXIST;
+ case ERROR_FILE_EXISTS: return UV_EEXIST;
+ case ERROR_BUFFER_OVERFLOW: return UV_EFAULT;
+ case WSAEFAULT: return UV_EFAULT;
+ case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH;
+ case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
+ case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
+ case ERROR_INVALID_DATA: return UV_EINVAL;
+ case ERROR_INVALID_PARAMETER: return UV_EINVAL;
+ case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
+ case WSAEINVAL: return UV_EINVAL;
+ case WSAEPFNOSUPPORT: return UV_EINVAL;
+ case WSAESOCKTNOSUPPORT: return UV_EINVAL;
+ case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
+ case ERROR_BUS_RESET: return UV_EIO;
+ case ERROR_CRC: return UV_EIO;
+ case ERROR_DEVICE_DOOR_OPEN: return UV_EIO;
+ case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO;
+ case ERROR_DISK_CORRUPT: return UV_EIO;
+ case ERROR_EOM_OVERFLOW: return UV_EIO;
+ case ERROR_FILEMARK_DETECTED: return UV_EIO;
+ case ERROR_GEN_FAILURE: return UV_EIO;
+ case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO;
+ case ERROR_IO_DEVICE: return UV_EIO;
+ case ERROR_NO_DATA_DETECTED: return UV_EIO;
+ case ERROR_NO_SIGNAL_SENT: return UV_EIO;
+ case ERROR_OPEN_FAILED: return UV_EIO;
+ case ERROR_SETMARK_DETECTED: return UV_EIO;
+ case ERROR_SIGNAL_REFUSED: return UV_EIO;
+ case WSAEISCONN: return UV_EISCONN;
+ case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP;
+ case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE;
+ case WSAEMFILE: return UV_EMFILE;
+ case WSAEMSGSIZE: return UV_EMSGSIZE;
+ case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG;
+ case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
+ case WSAENETUNREACH: return UV_ENETUNREACH;
+ case WSAENOBUFS: return UV_ENOBUFS;
+ case ERROR_BAD_PATHNAME: return UV_ENOENT;
+ case ERROR_DIRECTORY: return UV_ENOENT;
+ case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
+ case ERROR_INVALID_NAME: return UV_ENOENT;
+ case ERROR_INVALID_DRIVE: return UV_ENOENT;
+ case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
+ case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
+ case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
+ case WSAHOST_NOT_FOUND: return UV_ENOENT;
+ case WSANO_DATA: return UV_ENOENT;
+ case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM;
+ case ERROR_OUTOFMEMORY: return UV_ENOMEM;
+ case ERROR_CANNOT_MAKE: return UV_ENOSPC;
+ case ERROR_DISK_FULL: return UV_ENOSPC;
+ case ERROR_EA_TABLE_FULL: return UV_ENOSPC;
+ case ERROR_END_OF_MEDIA: return UV_ENOSPC;
+ case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC;
+ case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
+ case WSAENOTCONN: return UV_ENOTCONN;
+ case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY;
+ case WSAENOTSOCK: return UV_ENOTSOCK;
+ case ERROR_NOT_SUPPORTED: return UV_ENOTSUP;
+ case ERROR_BROKEN_PIPE: return UV_EOF;
+ case ERROR_ACCESS_DENIED: return UV_EPERM;
+ case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
+ case ERROR_BAD_PIPE: return UV_EPIPE;
+ case ERROR_NO_DATA: return UV_EPIPE;
+ case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE;
+ case WSAESHUTDOWN: return UV_EPIPE;
+ case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT;
+ case ERROR_WRITE_PROTECT: return UV_EROFS;
+ case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
+ case WSAETIMEDOUT: return UV_ETIMEDOUT;
+ case ERROR_NOT_SAME_DEVICE: return UV_EXDEV;
+ case ERROR_INVALID_FUNCTION: return UV_EISDIR;
+ case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG;
+ default: return UV_UNKNOWN;
+ }
+#else
+ const int error = -errno;
+ STATIC_ASSERT(-EINTR == UV_EINTR, "Need to translate error codes");
+ STATIC_ASSERT(-EAGAIN == UV_EAGAIN, "Need to translate error codes");
+ STATIC_ASSERT(-ENOMEM == UV_ENOMEM, "Need to translate error codes");
+ return error;
+#endif
+}
diff --git a/src/nvim/os/fs_defs.h b/src/nvim/os/fs_defs.h
index 0bd9c37750..2277d926b3 100644
--- a/src/nvim/os/fs_defs.h
+++ b/src/nvim/os/fs_defs.h
@@ -14,7 +14,7 @@ typedef struct {
uint64_t device_id; ///< @private The id of the device containing the file
} FileID;
-#define FILE_ID_EMPTY (FileID) {.inode = 0, .device_id = 0}
+#define FILE_ID_EMPTY (FileID) { .inode = 0, .device_id = 0 }
typedef struct {
uv_fs_t request; ///< @private The request to uv for the directory.
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c
index 0c46dc96ee..f62253cbce 100644
--- a/src/nvim/os/input.c
+++ b/src/nvim/os/input.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 <string.h>
#include <stdbool.h>
@@ -19,7 +22,8 @@
#include "nvim/getchar.h"
#include "nvim/main.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
+#include "nvim/state.h"
+#include "nvim/msgpack_rpc/channel.h"
#define READ_BUFFER_SIZE 0xfff
#define INPUT_BUFFER_SIZE (READ_BUFFER_SIZE * 4)
@@ -30,24 +34,23 @@ typedef enum {
kInputEof
} InbufPollResult;
-static Stream read_stream = {.closed = true};
+static Stream read_stream = { .closed = true }; // Input before UI starts.
static RBuffer *input_buffer = NULL;
static bool input_eof = false;
-static int global_fd = 0;
+static int global_fd = -1;
static int events_enabled = 0;
+static bool blocking = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/input.c.generated.h"
#endif
-// Helper function used to push bytes from the 'event' key sequence partially
-// between calls to os_inchar when maxlen < 3
void input_init(void)
{
input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN);
}
-/// Gets the file from which input was gathered at startup.
+/// Global TTY (or pipe for "-es") input stream, before UI starts.
int input_global_fd(void)
{
return global_fd;
@@ -60,8 +63,8 @@ void input_start(int fd)
}
global_fd = fd;
- rstream_init_fd(&main_loop, &read_stream, fd, READ_BUFFER_SIZE, NULL);
- rstream_start(&read_stream, read_cb);
+ rstream_init_fd(&main_loop, &read_stream, fd, READ_BUFFER_SIZE);
+ rstream_start(&read_stream, input_read_cb, NULL);
}
void input_stop(void)
@@ -71,7 +74,7 @@ void input_stop(void)
}
rstream_stop(&read_stream);
- stream_close(&read_stream, NULL);
+ stream_close(&read_stream, NULL, NULL);
}
static void cursorhold_event(void **argv)
@@ -87,8 +90,8 @@ static void create_cursorhold_event(void)
// have been called(inbuf_poll would return kInputAvail)
// TODO(tarruda): Cursorhold should be implemented as a timer set during the
// `state_check` callback for the states where it can be triggered.
- assert(!events_enabled || queue_empty(main_loop.events));
- queue_put(main_loop.events, cursorhold_event, 0);
+ assert(!events_enabled || multiqueue_empty(main_loop.events));
+ multiqueue_put(main_loop.events, cursorhold_event, 0);
}
// Low level input function
@@ -105,6 +108,11 @@ int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
}
} else {
if ((result = inbuf_poll((int)p_ut)) == kInputNone) {
+ if (read_stream.closed && silent_mode) {
+ // Drained eventloop & initial input; exit silent/batch-mode (-es/-Es).
+ read_error_exit();
+ }
+
if (trigger_cursorhold() && !typebuf_changed(tb_change_cnt)) {
create_cursorhold_event();
} else {
@@ -146,9 +154,15 @@ bool os_char_avail(void)
// Check for CTRL-C typed by reading all available characters.
void os_breakcheck(void)
{
+ int save_us = updating_screen;
+ // We do not want screen_resize() to redraw here.
+ updating_screen++;
+
if (!got_int) {
loop_poll_events(&main_loop, 0);
}
+
+ updating_screen = save_us;
}
void input_enable_events(void)
@@ -172,12 +186,14 @@ bool os_isatty(int fd)
size_t input_enqueue(String keys)
{
- char *ptr = keys.data, *end = ptr + keys.size;
+ char *ptr = keys.data;
+ char *end = ptr + keys.size;
while (rbuffer_space(input_buffer) >= 6 && ptr < end) {
uint8_t buf[6] = { 0 };
- unsigned int new_size = trans_special((const uint8_t **)&ptr, keys.size,
- buf, true);
+ unsigned int new_size
+ = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, true,
+ false);
if (new_size) {
new_size = handle_mouse_event(&ptr, buf, new_size);
@@ -187,8 +203,7 @@ size_t input_enqueue(String keys)
if (*ptr == '<') {
char *old_ptr = ptr;
- // Invalid or incomplete key sequence, skip until the next '>' or until
- // *end
+ // Invalid or incomplete key sequence, skip until the next '>' or *end.
do {
ptr++;
} while (ptr < end && *ptr != '>');
@@ -266,29 +281,32 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf,
}
static int orig_num_clicks = 0;
- static int orig_mouse_code = 0;
- static int orig_mouse_col = 0;
- static int orig_mouse_row = 0;
- static uint64_t orig_mouse_time = 0; // time of previous mouse click
- uint64_t mouse_time = os_hrtime(); // time of current mouse click
-
- // compute the time elapsed since the previous mouse click and
- // convert p_mouse from ms to ns
- uint64_t timediff = mouse_time - orig_mouse_time;
- uint64_t mouset = (uint64_t)p_mouset * 1000000;
- if (mouse_code == orig_mouse_code
- && timediff < mouset
- && orig_num_clicks != 4
- && orig_mouse_col == mouse_col
- && orig_mouse_row == mouse_row) {
- orig_num_clicks++;
- } else {
- orig_num_clicks = 1;
+ if (mouse_code != KE_LEFTRELEASE && mouse_code != KE_RIGHTRELEASE
+ && mouse_code != KE_MIDDLERELEASE) {
+ static int orig_mouse_code = 0;
+ static int orig_mouse_col = 0;
+ static int orig_mouse_row = 0;
+ static uint64_t orig_mouse_time = 0; // time of previous mouse click
+ uint64_t mouse_time = os_hrtime(); // time of current mouse click (ns)
+
+ // compute the time elapsed since the previous mouse click and
+ // convert p_mouse from ms to ns
+ uint64_t timediff = mouse_time - orig_mouse_time;
+ uint64_t mouset = (uint64_t)p_mouset * 1000000;
+ if (mouse_code == orig_mouse_code
+ && timediff < mouset
+ && orig_num_clicks != 4
+ && orig_mouse_col == mouse_col
+ && orig_mouse_row == mouse_row) {
+ orig_num_clicks++;
+ } else {
+ orig_num_clicks = 1;
+ }
+ orig_mouse_code = mouse_code;
+ orig_mouse_col = mouse_col;
+ orig_mouse_row = mouse_row;
+ orig_mouse_time = mouse_time;
}
- orig_mouse_code = mouse_code;
- orig_mouse_col = mouse_col;
- orig_mouse_row = mouse_row;
- orig_mouse_time = mouse_time;
uint8_t modifiers = 0;
if (orig_num_clicks == 2) {
@@ -316,13 +334,27 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf,
return bufsize;
}
+/// @return true if the main loop is blocked and waiting for input.
+bool input_blocking(void)
+{
+ return blocking;
+}
+
static bool input_poll(int ms)
{
if (do_profiling == PROF_YES && ms) {
prof_inchar_enter();
}
+ if ((ms == - 1 || ms > 0) && !events_enabled && !input_eof) {
+ // The pending input provoked a blocking wait. Do special events now. #6247
+ blocking = true;
+ multiqueue_process_events(ch_before_blocking_events);
+ }
+ DLOG("blocking... events_enabled=%d events_pending=%d", events_enabled,
+ !multiqueue_empty(main_loop.events));
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, input_ready() || input_eof);
+ blocking = false;
if (do_profiling == PROF_YES && ms) {
prof_inchar_exit();
@@ -351,11 +383,11 @@ static InbufPollResult inbuf_poll(int ms)
return input_eof ? kInputEof : kInputNone;
}
-static void read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
- bool at_eof)
+static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
+ bool at_eof)
{
if (at_eof) {
- input_eof = true;
+ input_done();
}
assert(rbuffer_space(input_buffer) >= rbuffer_size(buf));
@@ -386,6 +418,8 @@ static void process_interrupts(void)
}
}
+// Helper function used to push bytes from the 'event' key sequence partially
+// between calls to os_inchar when maxlen < 3
static int push_event_key(uint8_t *buf, int maxlen)
{
static const uint8_t key[3] = { K_SPECIAL, KS_EXTRA, KE_EVENT };
@@ -411,13 +445,14 @@ static bool input_ready(void)
// Exit because of an input read error.
static void read_error_exit(void)
{
- if (silent_mode) /* Normal way to exit for "ex -s" */
+ if (silent_mode) { // Normal way to exit for "nvim -es".
getout(0);
+ }
STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
preserve_exit();
}
static bool pending_events(void)
{
- return events_enabled && !queue_empty(main_loop.events);
+ return events_enabled && !multiqueue_empty(main_loop.events);
}
diff --git a/src/nvim/os/lang.c b/src/nvim/os/lang.c
new file mode 100644
index 0000000000..108a9c6c39
--- /dev/null
+++ b/src/nvim/os/lang.c
@@ -0,0 +1,65 @@
+// 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
+
+#ifdef __APPLE__
+# define Boolean CFBoolean // Avoid conflict with API's Boolean
+# include <CoreFoundation/CFLocale.h>
+# include <CoreFoundation/CFString.h>
+# undef Boolean
+#endif
+
+#ifdef HAVE_LOCALE_H
+# include <locale.h>
+#endif
+#include "nvim/os/os.h"
+
+void lang_init(void)
+{
+#ifdef __APPLE__
+ if (os_getenv("LANG") == NULL) {
+ const char *lang_region = NULL;
+ CFTypeRef cf_lang_region = NULL;
+
+ CFLocaleRef cf_locale = CFLocaleCopyCurrent();
+ if (cf_locale) {
+ cf_lang_region = CFLocaleGetValue(cf_locale, kCFLocaleIdentifier);
+ CFRetain(cf_lang_region);
+ lang_region = CFStringGetCStringPtr(cf_lang_region,
+ kCFStringEncodingUTF8);
+ CFRelease(cf_locale);
+ } else {
+ // Use the primary language defined in Preferences -> Language & Region
+ CFArrayRef cf_langs = CFLocaleCopyPreferredLanguages();
+ if (cf_langs && CFArrayGetCount(cf_langs) > 0) {
+ cf_lang_region = CFArrayGetValueAtIndex(cf_langs, 0);
+ CFRetain(cf_lang_region);
+ CFRelease(cf_langs);
+ lang_region = CFStringGetCStringPtr(cf_lang_region,
+ kCFStringEncodingUTF8);
+ } else {
+ ELOG("$LANG is empty and your primary language cannot be inferred.");
+ return;
+ }
+ }
+
+ if (lang_region) {
+ os_setenv("LANG", lang_region, true);
+ } else {
+ char buf[20] = { 0 };
+ if (CFStringGetCString(cf_lang_region, buf, 20,
+ kCFStringEncodingUTF8)) {
+ os_setenv("LANG", buf, true);
+ }
+ }
+ CFRelease(cf_lang_region);
+# ifdef HAVE_LOCALE_H
+ setlocale(LC_ALL, "");
+
+# ifdef LC_NUMERIC
+ // Make sure strtod() uses a decimal point, not a comma.
+ setlocale(LC_NUMERIC, "C");
+# endif
+# endif
+ }
+#endif
+}
diff --git a/src/nvim/os/lang.h b/src/nvim/os/lang.h
new file mode 100644
index 0000000000..f60e064f57
--- /dev/null
+++ b/src/nvim/os/lang.h
@@ -0,0 +1,7 @@
+#ifndef NVIM_OS_LANG_H
+#define NVIM_OS_LANG_H
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/lang.h.generated.h"
+#endif
+#endif // NVIM_OS_LANG_H
diff --git a/src/nvim/os/mem.c b/src/nvim/os/mem.c
index 871ece7a0e..eccb3c97e5 100644
--- a/src/nvim/os/mem.c
+++ b/src/nvim/os/mem.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
+
/// Functions for accessing system memory information.
#include <uv.h>
diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h
index 5e164b54a5..c29af5c160 100644
--- a/src/nvim/os/os_defs.h
+++ b/src/nvim/os/os_defs.h
@@ -16,7 +16,7 @@
#define BASENAMELEN (NAME_MAX - 5)
// Use the system path length if it makes sense.
-#if defined(PATH_MAX) && (PATH_MAX > 1000)
+#if defined(PATH_MAX) && (PATH_MAX > 1024)
# define MAXPATHL PATH_MAX
#else
# define MAXPATHL 1024
@@ -25,15 +25,6 @@
// Command-processing buffer. Use large buffers for all platforms.
#define CMDBUFFSIZE 1024
-// Use up to 5 Mbyte for a buffer.
-#ifndef DFLT_MAXMEM
-# define DFLT_MAXMEM (5*1024)
-#endif
-// use up to 10 Mbyte for Vim.
-#ifndef DFLT_MAXMEMTOT
-# define DFLT_MAXMEMTOT (10*1024)
-#endif
-
// Note: Some systems need both string.h and strings.h (Savage). However,
// some systems can't handle both, only use string.h in that case.
#include <string.h>
diff --git a/src/nvim/os/process.c b/src/nvim/os/process.c
new file mode 100644
index 0000000000..a67e7487eb
--- /dev/null
+++ b/src/nvim/os/process.c
@@ -0,0 +1,267 @@
+// 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
+
+/// OS process functions
+///
+/// psutil is a good reference for cross-platform syscall voodoo:
+/// https://github.com/giampaolo/psutil/tree/master/psutil/arch
+
+#include <uv.h> // for HANDLE (win32)
+
+#ifdef WIN32
+# include <tlhelp32.h> // for CreateToolhelp32Snapshot
+#endif
+
+#if defined(__FreeBSD__) // XXX: OpenBSD ?
+# include <string.h>
+# include <sys/types.h>
+# include <sys/user.h>
+#endif
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+# include <sys/param.h>
+#endif
+
+#if defined(__APPLE__) || defined(BSD)
+# include <sys/sysctl.h>
+# include <pwd.h>
+#endif
+
+#include "nvim/globals.h"
+#include "nvim/log.h"
+#include "nvim/os/process.h"
+#include "nvim/os/os.h"
+#include "nvim/os/os_defs.h"
+#include "nvim/api/private/helpers.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/process.c.generated.h"
+#endif
+
+#ifdef WIN32
+static bool os_proc_tree_kill_rec(HANDLE process, int sig)
+{
+ if (process == NULL) {
+ return false;
+ }
+ PROCESSENTRY32 pe;
+ DWORD pid = GetProcessId(process);
+
+ if (pid != 0) {
+ HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (h != INVALID_HANDLE_VALUE) {
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ if (!Process32First(h, &pe)) {
+ goto theend;
+ }
+ do {
+ if (pe.th32ParentProcessID == pid) {
+ HANDLE ph = OpenProcess(PROCESS_ALL_ACCESS, false, pe.th32ProcessID);
+ if (ph != NULL) {
+ os_proc_tree_kill_rec(ph, sig);
+ CloseHandle(ph);
+ }
+ }
+ } while (Process32Next(h, &pe));
+ CloseHandle(h);
+ }
+ }
+
+theend:
+ return (bool)TerminateProcess(process, (unsigned int)sig);
+}
+/// Kills process `pid` and its descendants recursively.
+bool os_proc_tree_kill(int pid, int sig)
+{
+ assert(sig >= 0);
+ assert(sig == SIGTERM || sig == SIGKILL);
+ if (pid > 0) {
+ ILOG("terminating process tree: %d", pid);
+ HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, (DWORD)pid);
+ return os_proc_tree_kill_rec(h, sig);
+ } else {
+ ELOG("invalid pid: %d", pid);
+ }
+ return false;
+}
+#else
+/// Kills process group where `pid` is the process group leader.
+bool os_proc_tree_kill(int pid, int sig)
+{
+ assert(sig == SIGTERM || sig == SIGKILL);
+ int pgid = getpgid(pid);
+ if (pgid > 0) { // Ignore error. Never kill self (pid=0).
+ if (pgid == pid) {
+ ILOG("sending %s to process group: -%d",
+ sig == SIGTERM ? "SIGTERM" : "SIGKILL", pgid);
+ int rv = uv_kill(-pgid, sig);
+ return rv == 0;
+ } else {
+ // Should never happen, because process_spawn() did setsid() in the child.
+ ELOG("pgid %d != pid %d", pgid, pid);
+ }
+ } else {
+ ELOG("getpgid(%d) returned %d", pid, pgid);
+ }
+ return false;
+}
+#endif
+
+/// Gets the process ids of the immediate children of process `ppid`.
+///
+/// @param ppid Process to inspect.
+/// @param[out,allocated] proc_list Child process ids.
+/// @param[out] proc_count Number of child processes.
+/// @return 0 on success, 1 if process not found, 2 on other error.
+int os_proc_children(int ppid, int **proc_list, size_t *proc_count)
+{
+ if (ppid < 0) {
+ return 2;
+ }
+
+ int *temp = NULL;
+ *proc_list = NULL;
+ *proc_count = 0;
+
+#ifdef WIN32
+ PROCESSENTRY32 pe;
+
+ // Snapshot of all processes.
+ HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (h == INVALID_HANDLE_VALUE) {
+ return 2;
+ }
+
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ // Get root process.
+ if (!Process32First(h, &pe)) {
+ CloseHandle(h);
+ return 2;
+ }
+ // Collect processes whose parent matches `ppid`.
+ do {
+ if (pe.th32ParentProcessID == (DWORD)ppid) {
+ temp = xrealloc(temp, (*proc_count + 1) * sizeof(*temp));
+ temp[*proc_count] = (int)pe.th32ProcessID;
+ (*proc_count)++;
+ }
+ } while (Process32Next(h, &pe));
+ CloseHandle(h);
+
+#elif defined(__APPLE__) || defined(BSD)
+# if defined(__APPLE__)
+# define KP_PID(o) o.kp_proc.p_pid
+# define KP_PPID(o) o.kp_eproc.e_ppid
+# elif defined(__FreeBSD__)
+# define KP_PID(o) o.ki_pid
+# define KP_PPID(o) o.ki_ppid
+# else
+# define KP_PID(o) o.p_pid
+# define KP_PPID(o) o.p_ppid
+# endif
+# ifdef __NetBSD__
+ static int name[] = {
+ CTL_KERN, KERN_PROC2, KERN_PROC_ALL, 0, (int)(sizeof(struct kinfo_proc2)), 0
+ };
+# else
+ static int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
+# endif
+
+ // Get total process count.
+ size_t len = 0;
+ int rv = sysctl(name, ARRAY_SIZE(name) - 1, NULL, &len, NULL, 0);
+ if (rv) {
+ return 2;
+ }
+
+ // Get ALL processes.
+# ifdef __NetBSD__
+ struct kinfo_proc2 *p_list = xmalloc(len);
+# else
+ struct kinfo_proc *p_list = xmalloc(len);
+# endif
+ rv = sysctl(name, ARRAY_SIZE(name) - 1, p_list, &len, NULL, 0);
+ if (rv) {
+ xfree(p_list);
+ return 2;
+ }
+
+ // Collect processes whose parent matches `ppid`.
+ bool exists = false;
+ size_t p_count = len / sizeof(*p_list);
+ for (size_t i = 0; i < p_count; i++) {
+ exists = exists || KP_PID(p_list[i]) == ppid;
+ if (KP_PPID(p_list[i]) == ppid) {
+ temp = xrealloc(temp, (*proc_count + 1) * sizeof(*temp));
+ temp[*proc_count] = KP_PID(p_list[i]);
+ (*proc_count)++;
+ }
+ }
+ xfree(p_list);
+ if (!exists) {
+ return 1; // Process not found.
+ }
+
+#elif defined(__linux__)
+ char proc_p[256] = { 0 };
+ // Collect processes whose parent matches `ppid`.
+ // Rationale: children are defined in thread with same ID of process.
+ snprintf(proc_p, sizeof(proc_p), "/proc/%d/task/%d/children", ppid, ppid);
+ FILE *fp = fopen(proc_p, "r");
+ if (fp == NULL) {
+ return 2; // Process not found, or /proc/…/children not supported.
+ }
+ int match_pid;
+ while (fscanf(fp, "%d", &match_pid) > 0) {
+ temp = xrealloc(temp, (*proc_count + 1) * sizeof(*temp));
+ temp[*proc_count] = match_pid;
+ (*proc_count)++;
+ }
+ fclose(fp);
+#endif
+
+ *proc_list = temp;
+ return 0;
+}
+
+#ifdef WIN32
+/// Gets various properties of the process identified by `pid`.
+///
+/// @param pid Process to inspect.
+/// @return Map of process properties, empty on error.
+Dictionary os_proc_info(int pid)
+{
+ Dictionary pinfo = ARRAY_DICT_INIT;
+ PROCESSENTRY32 pe;
+
+ // Snapshot of all processes. This is used instead of:
+ // OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, …)
+ // to avoid ERROR_PARTIAL_COPY. https://stackoverflow.com/a/29942376
+ HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (h == INVALID_HANDLE_VALUE) {
+ return pinfo; // Return empty.
+ }
+
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ // Get root process.
+ if (!Process32First(h, &pe)) {
+ CloseHandle(h);
+ return pinfo; // Return empty.
+ }
+ // Find the process.
+ do {
+ if (pe.th32ProcessID == (DWORD)pid) {
+ break;
+ }
+ } while (Process32Next(h, &pe));
+ CloseHandle(h);
+
+ if (pe.th32ProcessID == (DWORD)pid) {
+ PUT(pinfo, "pid", INTEGER_OBJ(pid));
+ PUT(pinfo, "ppid", INTEGER_OBJ((int)pe.th32ParentProcessID));
+ PUT(pinfo, "name", STRING_OBJ(cstr_to_string(pe.szExeFile)));
+ }
+
+ return pinfo;
+}
+#endif
diff --git a/src/nvim/os/process.h b/src/nvim/os/process.h
new file mode 100644
index 0000000000..1722d56bd3
--- /dev/null
+++ b/src/nvim/os/process.h
@@ -0,0 +1,11 @@
+#ifndef NVIM_OS_PROCESS_H
+#define NVIM_OS_PROCESS_H
+
+#include <stddef.h>
+#include "nvim/api/private/defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/process.h.generated.h"
+#endif
+
+#endif // NVIM_OS_PROCESS_H
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index 436de030ba..bcf57e1b5b 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -1,16 +1,18 @@
+// 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
+
// Some of the code came from pangoterm and libuv
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
// forkpty is not in POSIX, so headers are platform-specific
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__DragonFly__)
# include <libutil.h>
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
# include <util.h>
@@ -34,57 +36,89 @@
# include "os/pty_process_unix.c.generated.h"
#endif
-bool pty_process_spawn(PtyProcess *ptyproc)
+/// termios saved at startup (for TUI) or initialized by pty_process_spawn().
+static struct termios termios_default;
+
+/// Saves the termios properties associated with `tty_fd`.
+///
+/// @param tty_fd TTY file descriptor, or -1 if not in a terminal.
+void pty_process_save_termios(int tty_fd)
+{
+ DLOG("tty_fd=%d", tty_fd);
+ if (tty_fd == -1 || tcgetattr(tty_fd, &termios_default) != 0) {
+ return;
+ }
+}
+
+/// @returns zero on success, or negative error code
+int pty_process_spawn(PtyProcess *ptyproc)
FUNC_ATTR_NONNULL_ALL
{
- static struct termios termios;
- if (!termios.c_cflag) {
- init_termios(&termios);
+ if (!termios_default.c_cflag) {
+ // TODO(jkeyes): We could pass NULL to forkpty() instead ...
+ init_termios(&termios_default);
}
+ int status = 0; // zero or negative error code (libuv convention)
Process *proc = (Process *)ptyproc;
- assert(!proc->err);
+ assert(proc->err.closed);
uv_signal_start(&proc->loop->children_watcher, chld_handler, SIGCHLD);
ptyproc->winsize = (struct winsize){ ptyproc->height, ptyproc->width, 0, 0 };
uv_disable_stdio_inheritance();
int master;
- int pid = forkpty(&master, NULL, &termios, &ptyproc->winsize);
+ int pid = forkpty(&master, NULL, &termios_default, &ptyproc->winsize);
if (pid < 0) {
+ status = -errno;
ELOG("forkpty failed: %s", strerror(errno));
- return false;
+ return status;
} else if (pid == 0) {
- init_child(ptyproc);
- abort();
+ init_child(ptyproc); // never returns
}
// make sure the master file descriptor is non blocking
int master_status_flags = fcntl(master, F_GETFL);
if (master_status_flags == -1) {
+ status = -errno;
ELOG("Failed to get master descriptor status flags: %s", strerror(errno));
goto error;
}
if (fcntl(master, F_SETFL, master_status_flags | O_NONBLOCK) == -1) {
+ status = -errno;
ELOG("Failed to make master descriptor non-blocking: %s", strerror(errno));
goto error;
}
- if (proc->in && !set_duplicating_descriptor(master, &proc->in->uv.pipe)) {
+ // Other jobs and providers should not get a copy of this file descriptor.
+ if (os_set_cloexec(master) == -1) {
+ status = -errno;
+ ELOG("Failed to set CLOEXEC on ptmx file descriptor");
goto error;
}
- if (proc->out && !set_duplicating_descriptor(master, &proc->out->uv.pipe)) {
+
+ if (!proc->in.closed
+ && (status = set_duplicating_descriptor(master, &proc->in.uv.pipe))) {
+ goto error;
+ }
+ if (!proc->out.closed
+ && (status = set_duplicating_descriptor(master, &proc->out.uv.pipe))) {
goto error;
}
ptyproc->tty_fd = master;
proc->pid = pid;
- return true;
+ return 0;
error:
close(master);
kill(pid, SIGKILL);
waitpid(pid, NULL, 0);
- return false;
+ return status;
+}
+
+const char *pty_process_tty_name(PtyProcess *ptyproc)
+{
+ return ptsname(ptyproc->tty_fd);
}
void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height)
@@ -117,8 +151,12 @@ void pty_process_teardown(Loop *loop)
uv_signal_stop(&loop->children_watcher);
}
-static void init_child(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL
+static void init_child(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
{
+ // New session/process-group. #6530
+ setsid();
+
unsetenv("COLUMNS");
unsetenv("LINES");
unsetenv("TERMCAP");
@@ -134,13 +172,15 @@ static void init_child(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL
Process *proc = (Process *)ptyproc;
if (proc->cwd && os_chdir(proc->cwd) != 0) {
- fprintf(stderr, "chdir failed: %s\n", strerror(errno));
+ ELOG("chdir failed: %s", strerror(errno));
return;
}
+ char *prog = ptyproc->process.argv[0];
setenv("TERM", ptyproc->term_name ? ptyproc->term_name : "ansi", 1);
- execvp(ptyproc->process.argv[0], ptyproc->process.argv);
- fprintf(stderr, "execvp failed: %s\n", strerror(errno));
+ execvp(prog, ptyproc->process.argv);
+ ELOG("execvp failed: %s: %s", strerror(errno), prog);
+ _exit(122); // 122 is EXEC_FAILED in the Vim source.
}
static void init_termios(struct termios *termios) FUNC_ATTR_NONNULL_ALL
@@ -198,22 +238,34 @@ static void init_termios(struct termios *termios) FUNC_ATTR_NONNULL_ALL
termios->c_cc[VTIME] = 0;
}
-static bool set_duplicating_descriptor(int fd, uv_pipe_t *pipe)
+static int set_duplicating_descriptor(int fd, uv_pipe_t *pipe)
FUNC_ATTR_NONNULL_ALL
{
+ int status = 0; // zero or negative error code (libuv convention)
int fd_dup = dup(fd);
if (fd_dup < 0) {
+ status = -errno;
ELOG("Failed to dup descriptor %d: %s", fd, strerror(errno));
- return false;
+ return status;
}
- int uv_result = uv_pipe_open(pipe, fd_dup);
- if (uv_result) {
+
+ if (os_set_cloexec(fd_dup) == -1) {
+ status = -errno;
+ ELOG("Failed to set CLOEXEC on duplicate fd");
+ goto error;
+ }
+
+ status = uv_pipe_open(pipe, fd_dup);
+ if (status) {
ELOG("Failed to set pipe to descriptor %d: %s",
- fd_dup, uv_strerror(uv_result));
- close(fd_dup);
- return false;
+ fd_dup, uv_strerror(status));
+ goto error;
}
- return true;
+ return status;
+
+error:
+ close(fd_dup);
+ return status;
}
static void chld_handler(uv_signal_t *handle, int signum)
@@ -221,26 +273,23 @@ static void chld_handler(uv_signal_t *handle, int signum)
int stat = 0;
int pid;
- do {
- pid = waitpid(-1, &stat, WNOHANG);
- } while (pid < 0 && errno == EINTR);
-
- if (pid <= 0) {
- return;
- }
-
Loop *loop = handle->loop->data;
kl_iter(WatcherPtr, loop->children, current) {
Process *proc = (*current)->data;
- if (proc->pid == pid) {
- if (WIFEXITED(stat)) {
- proc->status = WEXITSTATUS(stat);
- } else if (WIFSIGNALED(stat)) {
- proc->status = WTERMSIG(stat);
- }
- proc->internal_exit_cb(proc);
- break;
+ do {
+ pid = waitpid(proc->pid, &stat, WNOHANG);
+ } while (pid < 0 && errno == EINTR);
+
+ if (pid <= 0) {
+ continue;
+ }
+
+ if (WIFEXITED(stat)) {
+ proc->status = WEXITSTATUS(stat);
+ } else if (WIFSIGNALED(stat)) {
+ proc->status = WTERMSIG(stat);
}
+ proc->internal_exit_cb(proc);
}
}
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c
new file mode 100644
index 0000000000..c5f8efadff
--- /dev/null
+++ b/src/nvim/os/pty_process_win.c
@@ -0,0 +1,418 @@
+// 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 <stdlib.h>
+
+#include <winpty_constants.h>
+
+#include "nvim/os/os.h"
+#include "nvim/ascii.h"
+#include "nvim/memory.h"
+#include "nvim/mbyte.h" // for utf8_to_utf16, utf16_to_utf8
+#include "nvim/os/pty_process_win.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/pty_process_win.c.generated.h"
+#endif
+
+static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused)
+ FUNC_ATTR_NONNULL_ALL
+{
+ PtyProcess *ptyproc = (PtyProcess *)context;
+ Process *proc = (Process *)ptyproc;
+
+ uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer);
+ ptyproc->wait_eof_timer.data = (void *)ptyproc;
+ uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
+}
+
+/// @returns zero on success, or negative error code.
+int pty_process_spawn(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
+{
+ Process *proc = (Process *)ptyproc;
+ int status = 0;
+ winpty_error_ptr_t err = NULL;
+ winpty_config_t *cfg = NULL;
+ winpty_spawn_config_t *spawncfg = NULL;
+ winpty_t *winpty_object = NULL;
+ char *in_name = NULL;
+ char *out_name = NULL;
+ HANDLE process_handle = NULL;
+ uv_connect_t *in_req = NULL;
+ uv_connect_t *out_req = NULL;
+ wchar_t *cmd_line = NULL;
+ wchar_t *cwd = NULL;
+ const char *emsg = NULL;
+
+ assert(proc->err.closed);
+
+ cfg = winpty_config_new(WINPTY_FLAG_ALLOW_CURPROC_DESKTOP_CREATION, &err);
+ if (cfg == NULL) {
+ emsg = "Failed, winpty_config_new.";
+ goto cleanup;
+ }
+
+ winpty_config_set_initial_size(cfg, ptyproc->width, ptyproc->height);
+ winpty_object = winpty_open(cfg, &err);
+ if (winpty_object == NULL) {
+ emsg = "Failed, winpty_open.";
+ goto cleanup;
+ }
+
+ status = utf16_to_utf8(winpty_conin_name(winpty_object), &in_name);
+ if (status != 0) {
+ emsg = "Failed to convert in_name from utf16 to utf8.";
+ goto cleanup;
+ }
+
+ status = utf16_to_utf8(winpty_conout_name(winpty_object), &out_name);
+ if (status != 0) {
+ emsg = "Failed to convert out_name from utf16 to utf8.";
+ goto cleanup;
+ }
+
+ if (!proc->in.closed) {
+ in_req = xmalloc(sizeof(uv_connect_t));
+ uv_pipe_connect(
+ in_req,
+ &proc->in.uv.pipe,
+ in_name,
+ pty_process_connect_cb);
+ }
+
+ if (!proc->out.closed) {
+ out_req = xmalloc(sizeof(uv_connect_t));
+ uv_pipe_connect(
+ out_req,
+ &proc->out.uv.pipe,
+ out_name,
+ pty_process_connect_cb);
+ }
+
+ if (proc->cwd != NULL) {
+ status = utf8_to_utf16(proc->cwd, &cwd);
+ if (status != 0) {
+ emsg = "Failed to convert pwd form utf8 to utf16.";
+ goto cleanup;
+ }
+ }
+
+ status = build_cmd_line(proc->argv, &cmd_line,
+ os_shell_is_cmdexe(proc->argv[0]));
+ if (status != 0) {
+ emsg = "Failed to convert cmd line form utf8 to utf16.";
+ goto cleanup;
+ }
+
+ spawncfg = winpty_spawn_config_new(
+ WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN,
+ NULL, // Optional application name
+ cmd_line,
+ cwd,
+ NULL, // Optional environment variables
+ &err);
+ if (spawncfg == NULL) {
+ emsg = "Failed winpty_spawn_config_new.";
+ goto cleanup;
+ }
+
+ DWORD win_err = 0;
+ if (!winpty_spawn(winpty_object,
+ spawncfg,
+ &process_handle,
+ NULL, // Optional thread handle
+ &win_err,
+ &err)) {
+ if (win_err) {
+ status = (int)win_err;
+ emsg = "Failed spawn process.";
+ } else {
+ emsg = "Failed winpty_spawn.";
+ }
+ goto cleanup;
+ }
+ proc->pid = (int)GetProcessId(process_handle);
+
+ if (!RegisterWaitForSingleObject(
+ &ptyproc->finish_wait,
+ process_handle,
+ pty_process_finish1,
+ ptyproc,
+ INFINITE,
+ WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
+ abort();
+ }
+
+ // Wait until pty_process_connect_cb is called.
+ while ((in_req != NULL && in_req->handle != NULL)
+ || (out_req != NULL && out_req->handle != NULL)) {
+ uv_run(&proc->loop->uv, UV_RUN_ONCE);
+ }
+
+ ptyproc->winpty_object = winpty_object;
+ ptyproc->process_handle = process_handle;
+ winpty_object = NULL;
+ process_handle = NULL;
+
+cleanup:
+ if (status) {
+ // In the case of an error of MultiByteToWideChar or CreateProcessW.
+ ELOG("%s error code: %d", emsg, status);
+ status = os_translate_sys_error(status);
+ } else if (err != NULL) {
+ status = (int)winpty_error_code(err);
+ ELOG("%s error code: %d", emsg, status);
+ status = translate_winpty_error(status);
+ }
+ winpty_error_free(err);
+ winpty_config_free(cfg);
+ winpty_spawn_config_free(spawncfg);
+ winpty_free(winpty_object);
+ xfree(in_name);
+ xfree(out_name);
+ if (process_handle != NULL) {
+ CloseHandle(process_handle);
+ }
+ xfree(in_req);
+ xfree(out_req);
+ xfree(cmd_line);
+ xfree(cwd);
+ return status;
+}
+
+const char *pty_process_tty_name(PtyProcess *ptyproc)
+{
+ return "?";
+}
+
+void pty_process_resize(PtyProcess *ptyproc, uint16_t width,
+ uint16_t height)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (ptyproc->winpty_object != NULL) {
+ winpty_set_size(ptyproc->winpty_object, width, height, NULL);
+ }
+}
+
+void pty_process_close(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
+{
+ Process *proc = (Process *)ptyproc;
+
+ pty_process_close_master(ptyproc);
+
+ if (proc->internal_close_cb) {
+ proc->internal_close_cb(proc);
+ }
+}
+
+void pty_process_close_master(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (ptyproc->winpty_object != NULL) {
+ winpty_free(ptyproc->winpty_object);
+ ptyproc->winpty_object = NULL;
+ }
+}
+
+void pty_process_teardown(Loop *loop)
+ FUNC_ATTR_NONNULL_ALL
+{
+}
+
+static void pty_process_connect_cb(uv_connect_t *req, int status)
+ FUNC_ATTR_NONNULL_ALL
+{
+ assert(status == 0);
+ req->handle = NULL;
+}
+
+static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)
+ FUNC_ATTR_NONNULL_ALL
+{
+ PtyProcess *ptyproc = wait_eof_timer->data;
+ Process *proc = (Process *)ptyproc;
+
+ if (proc->out.closed || !uv_is_readable(proc->out.uvstream)) {
+ uv_timer_stop(&ptyproc->wait_eof_timer);
+ pty_process_finish2(ptyproc);
+ }
+}
+
+static void pty_process_finish2(PtyProcess *ptyproc)
+ FUNC_ATTR_NONNULL_ALL
+{
+ Process *proc = (Process *)ptyproc;
+
+ UnregisterWaitEx(ptyproc->finish_wait, NULL);
+ uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL);
+
+ DWORD exit_code = 0;
+ GetExitCodeProcess(ptyproc->process_handle, &exit_code);
+ proc->status = (int)exit_code;
+
+ CloseHandle(ptyproc->process_handle);
+ ptyproc->process_handle = NULL;
+
+ proc->internal_exit_cb(proc);
+}
+
+/// Build the command line to pass to CreateProcessW.
+///
+/// @param[in] argv Array with string arguments.
+/// @param[out] cmd_line Location where saved builded cmd line.
+///
+/// @returns zero on success, or error code of MultiByteToWideChar function.
+///
+static int build_cmd_line(char **argv, wchar_t **cmd_line, bool is_cmdexe)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t utf8_cmd_line_len = 0;
+ size_t argc = 0;
+ QUEUE args_q;
+
+ QUEUE_INIT(&args_q);
+ while (*argv) {
+ size_t buf_len = is_cmdexe ? (strlen(*argv) + 1) : (strlen(*argv) * 2 + 3);
+ ArgNode *arg_node = xmalloc(sizeof(*arg_node));
+ arg_node->arg = xmalloc(buf_len);
+ if (is_cmdexe) {
+ xstrlcpy(arg_node->arg, *argv, buf_len);
+ } else {
+ quote_cmd_arg(arg_node->arg, buf_len, *argv);
+ }
+ utf8_cmd_line_len += strlen(arg_node->arg);
+ QUEUE_INIT(&arg_node->node);
+ QUEUE_INSERT_TAIL(&args_q, &arg_node->node);
+ argc++;
+ argv++;
+ }
+
+ utf8_cmd_line_len += argc;
+ char *utf8_cmd_line = xmalloc(utf8_cmd_line_len);
+ *utf8_cmd_line = NUL;
+ while (1) {
+ QUEUE *head = QUEUE_HEAD(&args_q);
+ QUEUE_REMOVE(head);
+ ArgNode *arg_node = QUEUE_DATA(head, ArgNode, node);
+ xstrlcat(utf8_cmd_line, arg_node->arg, utf8_cmd_line_len);
+ xfree(arg_node->arg);
+ xfree(arg_node);
+ if (QUEUE_EMPTY(&args_q)) {
+ break;
+ } else {
+ xstrlcat(utf8_cmd_line, " ", utf8_cmd_line_len);
+ }
+ }
+
+ int result = utf8_to_utf16(utf8_cmd_line, cmd_line);
+ xfree(utf8_cmd_line);
+ return result;
+}
+
+/// Emulate quote_cmd_arg of libuv and quotes command line argument.
+/// Most of the code came from libuv.
+///
+/// @param[out] dest Location where saved quotes argument.
+/// @param dest_remaining Destination buffer size.
+/// @param[in] src Pointer to argument.
+///
+static void quote_cmd_arg(char *dest, size_t dest_remaining, const char *src)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t src_len = strlen(src);
+ bool quote_hit = true;
+ char *start = dest;
+
+ if (src_len == 0) {
+ // Need double quotation for empty argument.
+ snprintf(dest, dest_remaining, "\"\"");
+ return;
+ }
+
+ if (NULL == strpbrk(src, " \t\"")) {
+ // No quotation needed.
+ xstrlcpy(dest, src, dest_remaining);
+ return;
+ }
+
+ if (NULL == strpbrk(src, "\"\\")) {
+ // No embedded double quotes or backlashes, so I can just wrap quote marks.
+ // around the whole thing.
+ snprintf(dest, dest_remaining, "\"%s\"", src);
+ return;
+ }
+
+ // Expected input/output:
+ // input : 'hello"world'
+ // output: '"hello\"world"'
+ // input : 'hello""world'
+ // output: '"hello\"\"world"'
+ // input : 'hello\world'
+ // output: 'hello\world'
+ // input : 'hello\\world'
+ // output: 'hello\\world'
+ // input : 'hello\"world'
+ // output: '"hello\\\"world"'
+ // input : 'hello\\"world'
+ // output: '"hello\\\\\"world"'
+ // input : 'hello world\'
+ // output: '"hello world\\"'
+
+ assert(dest_remaining--);
+ *(dest++) = NUL;
+ assert(dest_remaining--);
+ *(dest++) = '"';
+ for (size_t i = src_len; i > 0; i--) {
+ assert(dest_remaining--);
+ *(dest++) = src[i - 1];
+ if (quote_hit && src[i - 1] == '\\') {
+ assert(dest_remaining--);
+ *(dest++) = '\\';
+ } else if (src[i - 1] == '"') {
+ quote_hit = true;
+ assert(dest_remaining--);
+ *(dest++) = '\\';
+ } else {
+ quote_hit = false;
+ }
+ }
+ assert(dest_remaining);
+ *dest = '"';
+
+ while (start < dest) {
+ char tmp = *start;
+ *start = *dest;
+ *dest = tmp;
+ start++;
+ dest--;
+ }
+}
+
+/// Translate winpty error code to libuv error.
+///
+/// @param[in] winpty_errno Winpty error code returned by winpty_error_code
+/// function.
+///
+/// @returns Error code of libuv error.
+int translate_winpty_error(int winpty_errno)
+{
+ if (winpty_errno <= 0) {
+ return winpty_errno; // If < 0 then it's already a libuv error.
+ }
+
+ switch (winpty_errno) {
+ case WINPTY_ERROR_OUT_OF_MEMORY: return UV_ENOMEM;
+ case WINPTY_ERROR_SPAWN_CREATE_PROCESS_FAILED: return UV_EAI_FAIL;
+ case WINPTY_ERROR_LOST_CONNECTION: return UV_ENOTCONN;
+ case WINPTY_ERROR_AGENT_EXE_MISSING: return UV_ENOENT;
+ case WINPTY_ERROR_UNSPECIFIED: return UV_UNKNOWN;
+ case WINPTY_ERROR_AGENT_DIED: return UV_ESRCH;
+ case WINPTY_ERROR_AGENT_TIMEOUT: return UV_ETIMEDOUT;
+ case WINPTY_ERROR_AGENT_CREATION_FAILED: return UV_EAI_FAIL;
+ default: return UV_UNKNOWN;
+ }
+}
diff --git a/src/nvim/os/pty_process_win.h b/src/nvim/os/pty_process_win.h
index 20cc589925..1a4019e654 100644
--- a/src/nvim/os/pty_process_win.h
+++ b/src/nvim/os/pty_process_win.h
@@ -1,19 +1,27 @@
#ifndef NVIM_OS_PTY_PROCESS_WIN_H
#define NVIM_OS_PTY_PROCESS_WIN_H
-#include "nvim/event/libuv_process.h"
+#include <uv.h>
+#include <winpty.h>
+
+#include "nvim/event/process.h"
+#include "nvim/lib/queue.h"
typedef struct pty_process {
Process process;
char *term_name;
uint16_t width, height;
+ winpty_t *winpty_object;
+ HANDLE finish_wait;
+ HANDLE process_handle;
+ uv_timer_t wait_eof_timer;
} PtyProcess;
-#define pty_process_spawn(job) libuv_process_spawn((LibuvProcess *)job)
-#define pty_process_close(job) libuv_process_close((LibuvProcess *)job)
-#define pty_process_close_master(job) libuv_process_close((LibuvProcess *)job)
-#define pty_process_resize(job, width, height)
-#define pty_process_teardown(loop)
+// Structure used by build_cmd_line()
+typedef struct arg_node {
+ char *arg; // pointer to argument.
+ QUEUE node; // QUEUE structure.
+} ArgNode;
static inline PtyProcess pty_process_init(Loop *loop, void *data)
{
@@ -22,7 +30,14 @@ static inline PtyProcess pty_process_init(Loop *loop, void *data)
rv.term_name = NULL;
rv.width = 80;
rv.height = 24;
+ rv.winpty_object = NULL;
+ rv.finish_wait = NULL;
+ rv.process_handle = NULL;
return rv;
}
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/pty_process_win.h.generated.h"
+#endif
+
#endif // NVIM_OS_PTY_PROCESS_WIN_H
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 64c673930a..19d199f4d5 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.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 <string.h>
#include <assert.h>
#include <stdbool.h>
@@ -19,14 +22,15 @@
#include "nvim/message.h"
#include "nvim/memory.h"
#include "nvim/ui.h"
-#include "nvim/misc2.h"
#include "nvim/screen.h"
#include "nvim/memline.h"
#include "nvim/option_defs.h"
#include "nvim/charset.h"
#include "nvim/strings.h"
-#define DYNAMIC_BUFFER_INIT {NULL, 0, 0}
+#define DYNAMIC_BUFFER_INIT { NULL, 0, 0 }
+#define NS_1_SECOND 1000000000U // 1 second, in nanoseconds
+#define OUT_DATA_THRESHOLD 1024 * 10U // 10KB, "a few screenfuls" of data.
typedef struct {
char *data;
@@ -38,14 +42,15 @@ typedef struct {
#endif
/// Builds the argument vector for running the user-configured 'shell' (p_sh)
-/// with an optional command prefixed by 'shellcmdflag' (p_shcf).
+/// with an optional command prefixed by 'shellcmdflag' (p_shcf). E.g.:
+///
+/// ["shell", "-extra_args", "-shellcmdflag", "command with spaces"]
///
/// @param cmd Command string, or NULL to run an interactive shell.
/// @param extra_args Extra arguments to the shell, or NULL.
-/// @return A newly allocated argument vector. It must be freed with
-/// `shell_free_argv` when no longer needed.
+/// @return Newly allocated argument vector. Must be freed with shell_free_argv.
char **shell_build_argv(const char *cmd, const char *extra_args)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC
+ FUNC_ATTR_NONNULL_RET
{
size_t argc = tokenize(p_sh, NULL) + (cmd ? tokenize(p_shcf, NULL) : 0);
char **rv = xmalloc((argc + 4) * sizeof(*rv));
@@ -54,12 +59,12 @@ char **shell_build_argv(const char *cmd, const char *extra_args)
size_t i = tokenize(p_sh, rv);
if (extra_args) {
- rv[i++] = xstrdup(extra_args); // Push a copy of `extra_args`
+ rv[i++] = xstrdup(extra_args); // Push a copy of `extra_args`
}
if (cmd) {
- i += tokenize(p_shcf, rv + i); // Split 'shellcmdflag'
- rv[i++] = xstrdup(cmd); // Push a copy of the command.
+ i += tokenize(p_shcf, rv + i); // Split 'shellcmdflag'
+ rv[i++] = shell_xescape_xquote(cmd); // Copy (and escape) `cmd`.
}
rv[i] = NULL;
@@ -75,27 +80,61 @@ char **shell_build_argv(const char *cmd, const char *extra_args)
void shell_free_argv(char **argv)
{
char **p = argv;
-
if (p == NULL) {
// Nothing was allocated, return
return;
}
-
while (*p != NULL) {
// Free each argument
xfree(*p);
p++;
}
-
xfree(argv);
}
+/// Joins shell arguments from `argv` into a new string.
+/// If the result is too long it is truncated with ellipsis ("...").
+///
+/// @returns[allocated] `argv` joined to a string.
+char *shell_argv_to_str(char **const argv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ size_t n = 0;
+ char **p = argv;
+ char *rv = xcalloc(256, sizeof(*rv));
+ const size_t maxsize = (256 * sizeof(*rv));
+ if (*p == NULL) {
+ return rv;
+ }
+ while (*p != NULL) {
+ xstrlcat(rv, "'", maxsize);
+ xstrlcat(rv, *p, maxsize);
+ n = xstrlcat(rv, "' ", maxsize);
+ if (n >= maxsize) {
+ break;
+ }
+ p++;
+ }
+ if (n < maxsize) {
+ rv[n - 1] = '\0';
+ } else {
+ // Command too long, show ellipsis: "/bin/bash 'foo' 'bar'..."
+ rv[maxsize - 4] = '.';
+ rv[maxsize - 3] = '.';
+ rv[maxsize - 2] = '.';
+ rv[maxsize - 1] = '\0';
+ }
+ return rv;
+}
+
/// Calls the user-configured 'shell' (p_sh) for running a command or wildcard
/// expansion.
///
/// @param cmd The command to execute, or NULL to run an interactive shell.
/// @param opts Options that control how the shell will work.
/// @param extra_args Extra arguments to the shell, or NULL.
+///
+/// @return shell command exit code
int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args)
{
DynamicBuffer input = DYNAMIC_BUFFER_INIT;
@@ -118,36 +157,33 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args)
if (opts & kShellOptRead) {
output_ptr = &output;
forward_output = false;
+ } else if (opts & kShellOptDoOut) {
+ // Caller has already redirected output
+ forward_output = false;
}
}
size_t nread;
-
- int status = do_os_system(shell_build_argv((char *)cmd, (char *)extra_args),
- input.data,
- input.len,
- output_ptr,
- &nread,
- emsg_silent,
- forward_output);
-
+ int exitcode = do_os_system(shell_build_argv((char *)cmd, (char *)extra_args),
+ input.data, input.len, output_ptr, &nread,
+ emsg_silent, forward_output);
xfree(input.data);
if (output) {
- (void)write_output(output, nread, true, true);
+ (void)write_output(output, nread, true);
xfree(output);
}
- if (!emsg_silent && status != 0 && !(opts & kShellOptSilent)) {
+ if (!emsg_silent && exitcode != 0 && !(opts & kShellOptSilent)) {
MSG_PUTS(_("\nshell returned "));
- msg_outnum(status);
+ msg_outnum(exitcode);
msg_putchar('\n');
}
State = current_state;
signal_accept_deadly();
- return status;
+ return exitcode;
}
/// os_system - synchronously execute a command in the shell
@@ -156,14 +192,14 @@ int os_call_shell(char_u *cmd, ShellOpts opts, char_u *extra_args)
/// char *output = NULL;
/// size_t nread = 0;
/// char *argv[] = {"ls", "-la", NULL};
-/// int status = os_sytem(argv, NULL, 0, &output, &nread);
+/// int exitcode = os_sytem(argv, NULL, 0, &output, &nread);
///
/// @param argv The commandline arguments to be passed to the shell. `argv`
/// will be consumed.
/// @param input The input to the shell (NULL for no input), passed to the
/// stdin of the resulting process.
/// @param len The length of the input buffer (not used if `input` == NULL)
-/// @param[out] output A pointer to to a location where the output will be
+/// @param[out] output Pointer to a location where the output will be
/// allocated and stored. Will point to NULL if the shell
/// command did not output anything. If NULL is passed,
/// the shell output will be ignored.
@@ -188,6 +224,10 @@ static int do_os_system(char **argv,
bool silent,
bool forward_output)
{
+ out_data_decide_throttle(0); // Initialize throttle decider.
+ out_data_ring(NULL, 0); // Initialize output ring-buffer.
+ bool has_input = (input != NULL && input[0] != '\0');
+
// the output buffer
DynamicBuffer buf = DYNAMIC_BUFFER_INIT;
stream_read_cb data_cb = system_data_cb;
@@ -205,60 +245,74 @@ static int do_os_system(char **argv,
char prog[MAXPATHL];
xstrlcpy(prog, argv[0], MAXPATHL);
- Stream in, out, err;
LibuvProcess uvproc = libuv_process_init(&main_loop, &buf);
Process *proc = &uvproc.process;
- Queue *events = queue_new_child(main_loop.events);
+ MultiQueue *events = multiqueue_new_child(main_loop.events);
proc->events = events;
proc->argv = argv;
- proc->in = input != NULL ? &in : NULL;
- proc->out = &out;
- proc->err = &err;
- if (!process_spawn(proc)) {
+ int status = process_spawn(proc, has_input, true, true);
+ if (status) {
loop_poll_events(&main_loop, 0);
- // Failed, probably due to `sh` not being executable
+ // Failed, probably 'shell' is not executable.
if (!silent) {
- MSG_PUTS(_("\nCannot execute "));
+ MSG_PUTS(_("\nshell failed to start: "));
+ msg_outtrans((char_u *)os_strerror(status));
+ MSG_PUTS(": ");
msg_outtrans((char_u *)prog);
msg_putchar('\n');
}
- queue_free(events);
+ multiqueue_free(events);
return -1;
}
- // We want to deal with stream events as fast a possible while queueing
- // process events, so reset everything to NULL. It prevents closing the
- // streams while there's still data in the OS buffer(due to the process
+ // Note: unlike process events, stream events are not queued, as we want to
+ // deal with stream events as fast a possible. It prevents closing the
+ // streams while there's still data in the OS buffer (due to the process
// exiting before all data is read).
- if (input != NULL) {
- proc->in->events = NULL;
- wstream_init(proc->in, 0);
+ if (has_input) {
+ wstream_init(&proc->in, 0);
}
- proc->out->events = NULL;
- rstream_init(proc->out, 0);
- rstream_start(proc->out, data_cb);
- proc->err->events = NULL;
- rstream_init(proc->err, 0);
- rstream_start(proc->err, data_cb);
+ rstream_init(&proc->out, 0);
+ rstream_start(&proc->out, data_cb, &buf);
+ rstream_init(&proc->err, 0);
+ rstream_start(&proc->err, data_cb, &buf);
// write the input, if any
- if (input) {
- WBuffer *input_buffer = wstream_new_buffer((char *) input, len, 1, NULL);
+ if (has_input) {
+ WBuffer *input_buffer = wstream_new_buffer((char *)input, len, 1, NULL);
- if (!wstream_write(&in, input_buffer)) {
+ if (!wstream_write(&proc->in, input_buffer)) {
// couldn't write, stop the process and tell the user about it
process_stop(proc);
return -1;
}
// close the input stream after everything is written
- wstream_set_write_cb(&in, shell_write_cb);
+ wstream_set_write_cb(&proc->in, shell_write_cb, NULL);
}
- // invoke busy_start here so event_poll_until wont change the busy state for
- // the UI
+ // Invoke busy_start here so LOOP_PROCESS_EVENTS_UNTIL will not change the
+ // busy state.
ui_busy_start();
ui_flush();
- int status = process_wait(proc, -1, NULL);
+ if (forward_output) {
+ msg_sb_eol();
+ msg_start();
+ msg_no_more = true;
+ lines_left = -1;
+ }
+ int exitcode = process_wait(proc, -1, NULL);
+ if (!got_int && out_data_decide_throttle(0)) {
+ // Last chunk of output was skipped; display it now.
+ out_data_ring(NULL, SIZE_MAX);
+ }
+ if (forward_output) {
+ // caller should decide if wait_return is invoked
+ no_wait_return++;
+ msg_end();
+ no_wait_return--;
+ msg_no_more = false;
+ }
+
ui_busy_stop();
// prepare the out parameters if requested
@@ -278,10 +332,10 @@ static int do_os_system(char **argv,
}
}
- assert(queue_empty(events));
- queue_free(events);
+ assert(multiqueue_empty(events));
+ multiqueue_free(events);
- return status;
+ return exitcode;
}
/// - ensures at least `desired` bytes in buffer
@@ -310,71 +364,178 @@ static void system_data_cb(Stream *stream, RBuffer *buf, size_t count,
dbuf->len += nread;
}
-/// Continue to append data to last screen line.
+/// Tracks output received for the current executing shell command, and displays
+/// a pulsing "..." when output should be skipped. Tracking depends on the
+/// synchronous/blocking nature of ":!".
///
-/// @param output Data to append to screen lines.
-/// @param remaining Size of data.
-/// @param new_line If true, next data output will be on a new line.
-static void append_to_screen_end(char *output, size_t remaining, bool new_line)
+/// Purpose:
+/// 1. CTRL-C is more responsive. #1234 #5396
+/// 2. Improves performance of :! (UI, esp. TUI, is the bottleneck).
+/// 3. Avoids OOM during long-running, spammy :!.
+///
+/// Vim does not need this hack because:
+/// 1. :! in terminal-Vim runs in cooked mode, so CTRL-C is caught by the
+/// terminal and raises SIGINT out-of-band.
+/// 2. :! in terminal-Vim uses a tty (Nvim uses pipes), so commands
+/// (e.g. `git grep`) may page themselves.
+///
+/// @param size Length of data, used with internal state to decide whether
+/// output should be skipped. size=0 resets the internal state and
+/// returns the previous decision.
+///
+/// @returns true if output should be skipped and pulse was displayed.
+/// Returns the previous decision if size=0.
+static bool out_data_decide_throttle(size_t size)
{
- // Column of last row to start appending data to.
- static colnr_T last_col = 0;
+ static uint64_t started = 0; // Start time of the current throttle.
+ static size_t received = 0; // Bytes observed since last throttle.
+ static size_t visit = 0; // "Pulse" count of the current throttle.
+ static char pulse_msg[] = { ' ', ' ', ' ', '\0' };
+
+ if (!size) {
+ bool previous_decision = (visit > 0);
+ started = received = visit = 0;
+ return previous_decision;
+ }
- size_t off = 0;
- int last_row = (int)Rows - 1;
+ received += size;
+ if (received < OUT_DATA_THRESHOLD
+ // Display at least the first chunk of output even if it is big.
+ || (!started && received < size + 1000)) {
+ return false;
+ } else if (!visit) {
+ started = os_hrtime();
+ } else if (visit % 20 == 0) {
+ uint64_t since = os_hrtime() - started;
+ if (since > (3 * NS_1_SECOND)) {
+ received = visit = 0;
+ return false;
+ }
+ }
- while (off < remaining) {
- // Found end of line?
- if (output[off] == NL) {
- // Can we start a new line or do we need to continue the last one?
- if (last_col == 0) {
- screen_del_lines(0, 0, 1, (int)Rows, NULL);
- }
- screen_puts_len((char_u *)output, (int)off, last_row, last_col, 0);
- last_col = 0;
+ visit++;
+ // Pulse "..." at the bottom of the screen.
+ size_t tick = (visit % 20 == 0)
+ ? 3 // Force all dots "..." on last visit.
+ : (visit % 4);
+ pulse_msg[0] = (tick == 0) ? ' ' : '.';
+ pulse_msg[1] = (tick == 0 || 1 == tick) ? ' ' : '.';
+ pulse_msg[2] = (tick == 0 || 1 == tick || 2 == tick) ? ' ' : '.';
+ if (visit == 1) {
+ msg_putchar('\n');
+ }
+ msg_putchar('\r'); // put cursor at start of line
+ msg_puts(pulse_msg);
+ ui_flush();
+ return true;
+}
- size_t skip = off + 1;
- output += skip;
- remaining -= skip;
- off = 0;
- continue;
- }
+/// Saves output in a quasi-ringbuffer. Used to ensure the last ~page of
+/// output for a shell-command is always displayed.
+///
+/// Init mode: Resets the internal state.
+/// output = NULL
+/// size = 0
+/// Print mode: Displays the current saved data.
+/// output = NULL
+/// size = SIZE_MAX
+///
+/// @param output Data to save, or NULL to invoke a special mode.
+/// @param size Length of `output`.
+static void out_data_ring(char *output, size_t size)
+{
+#define MAX_CHUNK_SIZE (OUT_DATA_THRESHOLD / 2)
+ static char last_skipped[MAX_CHUNK_SIZE]; // Saved output.
+ static size_t last_skipped_len = 0;
- // Translate NUL to SOH
- if (output[off] == NUL) {
- output[off] = 1;
- }
+ assert(output != NULL || (size == 0 || size == SIZE_MAX));
- off++;
+ if (output == NULL && size == 0) { // Init mode
+ last_skipped_len = 0;
+ return;
+ }
+
+ if (output == NULL && size == SIZE_MAX) { // Print mode
+ out_data_append_to_screen(last_skipped, &last_skipped_len, true);
+ return;
}
- if (remaining) {
- if (last_col == 0) {
- screen_del_lines(0, 0, 1, (int)Rows, NULL);
+ // This is basically a ring-buffer...
+ if (size >= MAX_CHUNK_SIZE) { // Save mode
+ size_t start = size - MAX_CHUNK_SIZE;
+ memcpy(last_skipped, output + start, MAX_CHUNK_SIZE);
+ last_skipped_len = MAX_CHUNK_SIZE;
+ } else if (size > 0) {
+ // Length of the old data that can be kept.
+ size_t keep_len = MIN(last_skipped_len, MAX_CHUNK_SIZE - size);
+ size_t keep_start = last_skipped_len - keep_len;
+ // Shift the kept part of the old data to the start.
+ if (keep_start) {
+ memmove(last_skipped, last_skipped + keep_start, keep_len);
}
- screen_puts_len((char_u *)output, (int)remaining, last_row, last_col, 0);
- last_col += (colnr_T)remaining;
+ // Copy the entire new data to the remaining space.
+ memcpy(last_skipped + keep_len, output, size);
+ last_skipped_len = keep_len + size;
}
+}
+
+/// Continue to append data to last screen line.
+///
+/// @param output Data to append to screen lines.
+/// @param remaining Size of data.
+/// @param new_line If true, next data output will be on a new line.
+static void out_data_append_to_screen(char *output, size_t *count, bool eof)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char *p = output, *end = output + *count;
+ while (p < end) {
+ if (*p == '\n' || *p == '\r' || *p == TAB || *p == BELL) {
+ msg_putchar_attr((uint8_t)(*p), 0);
+ p++;
+ } else {
+ // Note: this is not 100% precise:
+ // 1. we don't check if received continuation bytes are already invalid
+ // and we thus do some buffering that could be avoided
+ // 2. we don't compose chars over buffer boundaries, even if we see an
+ // incomplete UTF-8 sequence that could be composing with the last
+ // complete sequence.
+ // This will be corrected when we switch to vterm based implementation
+ int i = *p ? utfc_ptr2len_len((char_u *)p, (int)(end-p)) : 1;
+ if (!eof && i == 1 && utf8len_tab_zero[*(uint8_t *)p] > (end-p)) {
+ *count = (size_t)(p - output);
+ goto end;
+ }
- if (new_line) {
- last_col = 0;
+ (void)msg_outtrans_len_attr((char_u *)p, i, 0);
+ p += i;
+ }
}
+end:
ui_flush();
}
static void out_data_cb(Stream *stream, RBuffer *buf, size_t count, void *data,
bool eof)
{
- // We always output the whole buffer, so the buffer can never
- // wrap around.
size_t cnt;
char *ptr = rbuffer_read_ptr(buf, &cnt);
- append_to_screen_end(ptr, cnt, eof);
+ if (ptr != NULL && cnt > 0
+ && out_data_decide_throttle(cnt)) { // Skip output above a threshold.
+ // Save the skipped output. If it is the final chunk, we display it later.
+ out_data_ring(ptr, cnt);
+ } else if (ptr != NULL) {
+ out_data_append_to_screen(ptr, &cnt, eof);
+ }
+
if (cnt) {
rbuffer_consumed(buf, cnt);
}
+
+ // Move remaining data to start of buffer, so the buffer can never
+ // wrap around.
+ rbuffer_reset(buf);
}
/// Parses a command string into a sequence of words, taking quotes into
@@ -463,14 +624,10 @@ static void read_input(DynamicBuffer *buf)
if (len == l) {
// Finished a line, add a NL, unless this line should not have one.
- // FIXME need to make this more readable
if (lnum != curbuf->b_op_end.lnum
- || (!curbuf->b_p_bin
- && curbuf->b_p_fixeol)
+ || (!curbuf->b_p_bin && curbuf->b_p_fixeol)
|| (lnum != curbuf->b_no_eol_lnum
- && (lnum !=
- curbuf->b_ml.ml_line_count
- || curbuf->b_p_eol))) {
+ && (lnum != curbuf->b_ml.ml_line_count || curbuf->b_p_eol))) {
dynamic_buffer_ensure(buf, buf->len + 1);
buf->data[buf->len++] = NL;
}
@@ -486,28 +643,20 @@ static void read_input(DynamicBuffer *buf)
}
}
-static size_t write_output(char *output, size_t remaining, bool to_buffer,
- bool eof)
+static size_t write_output(char *output, size_t remaining, bool eof)
{
if (!output) {
return 0;
}
- char replacement_NUL = to_buffer ? NL : 1;
char *start = output;
size_t off = 0;
- int lastrow = (int)Rows - 1;
while (off < remaining) {
if (output[off] == NL) {
// Insert the line
- if (to_buffer) {
- output[off] = NUL;
- ml_append(curwin->w_cursor.lnum++, (char_u *)output, (int)off + 1,
- false);
- } else {
- screen_del_lines(0, 0, 1, (int)Rows, NULL);
- screen_puts_len((char_u *)output, (int)off, lastrow, 0, 0);
- }
+ output[off] = NUL;
+ ml_append(curwin->w_cursor.lnum++, (char_u *)output, (int)off + 1,
+ false);
size_t skip = off + 1;
output += skip;
remaining -= skip;
@@ -517,24 +666,19 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer,
if (output[off] == NUL) {
// Translate NUL to NL
- output[off] = replacement_NUL;
+ output[off] = NL;
}
off++;
}
if (eof) {
if (remaining) {
- if (to_buffer) {
- // append unfinished line
- ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false);
- // remember that the NL was missing
- curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
- } else {
- screen_del_lines(0, 0, 1, (int)Rows, NULL);
- screen_puts_len((char_u *)output, (int)remaining, lastrow, 0, 0);
- }
+ // append unfinished line
+ ml_append(curwin->w_cursor.lnum++, (char_u *)output, 0, false);
+ // remember that the NL was missing
+ curbuf->b_no_eol_lnum = curwin->w_cursor.lnum;
output += remaining;
- } else if (to_buffer) {
+ } else {
curbuf->b_no_eol_lnum = 0;
}
}
@@ -546,5 +690,47 @@ static size_t write_output(char *output, size_t remaining, bool to_buffer,
static void shell_write_cb(Stream *stream, void *data, int status)
{
- stream_close(stream, NULL);
+ if (status) {
+ // Can happen if system() tries to send input to a shell command that was
+ // backgrounded (:call system("cat - &", "foo")). #3529 #5241
+ msg_schedule_emsgf(_("E5677: Error writing input to shell-command: %s"),
+ uv_err_name(status));
+ }
+ stream_close(stream, NULL, NULL);
+}
+
+/// Applies 'shellxescape' (p_sxe) and 'shellxquote' (p_sxq) to a command.
+///
+/// @param cmd Command string
+/// @return Escaped/quoted command string (allocated).
+static char *shell_xescape_xquote(const char *cmd)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (*p_sxq == NUL) {
+ return xstrdup(cmd);
+ }
+
+ const char *ecmd = cmd;
+ if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) {
+ ecmd = (char *)vim_strsave_escaped_ext((char_u *)cmd, p_sxe, '^', false);
+ }
+ size_t ncmd_size = strlen(ecmd) + STRLEN(p_sxq) * 2 + 1;
+ char *ncmd = xmalloc(ncmd_size);
+
+ // When 'shellxquote' is ( append ).
+ // When 'shellxquote' is "( append )".
+ if (STRCMP(p_sxq, "(") == 0) {
+ vim_snprintf(ncmd, ncmd_size, "(%s)", ecmd);
+ } else if (STRCMP(p_sxq, "\"(") == 0) {
+ vim_snprintf(ncmd, ncmd_size, "\"(%s)\"", ecmd);
+ } else {
+ vim_snprintf(ncmd, ncmd_size, "%s%s%s", p_sxq, ecmd, p_sxq);
+ }
+
+ if (ecmd != cmd) {
+ xfree((void *)ecmd);
+ }
+
+ return ncmd;
}
+
diff --git a/src/nvim/os/shell.h b/src/nvim/os/shell.h
index 58960db157..48503f2601 100644
--- a/src/nvim/os/shell.h
+++ b/src/nvim/os/shell.h
@@ -1,6 +1,8 @@
#ifndef NVIM_OS_SHELL_H
#define NVIM_OS_SHELL_H
+#include <stdio.h>
+
#include "nvim/types.h"
// Flags for os_call_shell() second argument
diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c
index 4abc9cfc36..fc7f9cefd1 100644
--- a/src/nvim/os/signal.c
+++ b/src/nvim/os/signal.c
@@ -1,9 +1,16 @@
+// 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 <uv.h>
+#ifndef WIN32
+# include <signal.h> // for sigset_t
+#endif
#include "nvim/ascii.h"
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/globals.h"
#include "nvim/memline.h"
@@ -11,7 +18,6 @@
#include "nvim/main.h"
#include "nvim/memory.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/event/signal.h"
#include "nvim/os/signal.h"
#include "nvim/event/loop.h"
@@ -29,6 +35,16 @@ static bool rejecting_deadly;
void signal_init(void)
{
+#ifndef WIN32
+ // Ensure a clean slate by unblocking all signals. For example, if SIGCHLD is
+ // blocked, libuv may hang after spawning a subprocess on Linux. #5230
+ sigset_t mask;
+ sigemptyset(&mask);
+ if (pthread_sigmask(SIG_SETMASK, &mask, NULL) != 0) {
+ ELOG("Could not unblock signals, nvim might behave strangely.");
+ }
+#endif
+
signal_watcher_init(&main_loop, &spipe, NULL);
signal_watcher_init(&main_loop, &shup, NULL);
signal_watcher_init(&main_loop, &squit, NULL);
@@ -129,7 +145,7 @@ static void on_signal(SignalWatcher *handle, int signum, void *data)
case SIGPWR:
// Signal of a power failure(eg batteries low), flush the swap files to
// be safe
- ml_sync_all(false, false);
+ ml_sync_all(false, false, true);
break;
#endif
#ifdef SIGPIPE
@@ -147,7 +163,7 @@ static void on_signal(SignalWatcher *handle, int signum, void *data)
}
break;
default:
- fprintf(stderr, "Invalid signal %d", signum);
+ ELOG("invalid signal: %d", signum);
break;
}
}
diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c
index 81ceb919c4..f6503dfdb0 100644
--- a/src/nvim/os/stdpaths.c
+++ b/src/nvim/os/stdpaths.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 <stdbool.h>
#include "nvim/os/stdpaths_defs.h"
@@ -16,20 +19,29 @@ static const char *xdg_env_vars[] = {
[kXDGDataDirs] = "XDG_DATA_DIRS",
};
+#ifdef WIN32
+static const char *const xdg_defaults_env_vars[] = {
+ [kXDGConfigHome] = "LOCALAPPDATA",
+ [kXDGDataHome] = "LOCALAPPDATA",
+ [kXDGCacheHome] = "TEMP",
+ [kXDGRuntimeDir] = NULL,
+ [kXDGConfigDirs] = NULL,
+ [kXDGDataDirs] = NULL,
+};
+#endif
+
/// Defaults for XDGVarType values
///
/// Used in case environment variables contain nothing. Need to be expanded.
static const char *const xdg_defaults[] = {
#ifdef WIN32
- // Windows
- [kXDGConfigHome] = "$LOCALAPPDATA",
- [kXDGDataHome] = "$LOCALAPPDATA",
- [kXDGCacheHome] = "$TEMP",
+ [kXDGConfigHome] = "~\\AppData\\Local",
+ [kXDGDataHome] = "~\\AppData\\Local",
+ [kXDGCacheHome] = "~\\AppData\\Local\\Temp",
[kXDGRuntimeDir] = NULL,
[kXDGConfigDirs] = NULL,
[kXDGDataDirs] = NULL,
#else
- // Linux, BSD, CYGWIN, Apple
[kXDGConfigHome] = "~/.config",
[kXDGDataHome] = "~/.local/share",
[kXDGCacheHome] = "~/.cache",
@@ -50,12 +62,19 @@ char *stdpaths_get_xdg_var(const XDGVarType idx)
const char *const env = xdg_env_vars[idx];
const char *const fallback = xdg_defaults[idx];
- const char *const env_val = os_getenv(env);
+ const char *env_val = os_getenv(env);
+
+#ifdef WIN32
+ if (env_val == NULL && xdg_defaults_env_vars[idx] != NULL) {
+ env_val = os_getenv(xdg_defaults_env_vars[idx]);
+ }
+#endif
+
char *ret = NULL;
if (env_val != NULL) {
ret = xstrdup(env_val);
} else if (fallback) {
- ret = (char *) expand_env_save((char_u *)fallback);
+ ret = (char *)expand_env_save((char_u *)fallback);
}
return ret;
@@ -69,7 +88,7 @@ char *stdpaths_get_xdg_var(const XDGVarType idx)
///
/// In WIN32 get_xdg_home(kXDGDataHome) returns `{xdg_directory}/nvim-data` to
/// avoid storing configuration and data files in the same path.
-static char *get_xdg_home(const XDGVarType idx)
+char *get_xdg_home(const XDGVarType idx)
FUNC_ATTR_WARN_UNUSED_RESULT
{
char *dir = stdpaths_get_xdg_var(idx);
@@ -100,18 +119,30 @@ char *stdpaths_user_conf_subpath(const char *fname)
///
/// @param[in] fname New component of the path.
/// @param[in] trailing_pathseps Amount of trailing path separators to add.
+/// @param[in] escape_commas If true, all commas will be escaped.
///
-/// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}`
+/// @return [allocated] `$XDG_DATA_HOME/nvim/{fname}`.
char *stdpaths_user_data_subpath(const char *fname,
- const size_t trailing_pathseps)
+ const size_t trailing_pathseps,
+ const bool escape_commas)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
char *ret = concat_fnames_realloc(get_xdg_home(kXDGDataHome), fname, true);
- if (trailing_pathseps) {
- const size_t len = strlen(ret);
- ret = xrealloc(ret, len + trailing_pathseps + 1);
- memset(ret + len, PATHSEP, trailing_pathseps);
- ret[len + trailing_pathseps] = NUL;
+ const size_t len = strlen(ret);
+ const size_t numcommas = (escape_commas ? memcnt(ret, ',', len) : 0);
+ if (numcommas || trailing_pathseps) {
+ ret = xrealloc(ret, len + trailing_pathseps + numcommas + 1);
+ for (size_t i = 0 ; i < len + numcommas ; i++) {
+ if (ret[i] == ',') {
+ memmove(ret + i + 1, ret + i, len - i + numcommas);
+ ret[i] = '\\';
+ i++;
+ }
+ }
+ if (trailing_pathseps) {
+ memset(ret + len + numcommas, PATHSEP, trailing_pathseps);
+ }
+ ret[len + trailing_pathseps + numcommas] = NUL;
}
return ret;
}
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c
index 2205ad0958..31ef1a0cd6 100644
--- a/src/nvim/os/time.c
+++ b/src/nvim/os/time.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 <stdint.h>
#include <stdbool.h>
@@ -7,6 +10,7 @@
#include <uv.h>
#include "nvim/os/time.h"
+#include "nvim/os/input.h"
#include "nvim/event/loop.h"
#include "nvim/vim.h"
#include "nvim/main.h"
@@ -34,38 +38,54 @@ uint64_t os_hrtime(void)
return uv_hrtime();
}
-/// Sleeps for a certain amount of milliseconds
+/// Sleeps for `ms` milliseconds.
///
-/// @param milliseconds Number of milliseconds to sleep
-/// @param ignoreinput If true, allow a SIGINT to interrupt us
-void os_delay(uint64_t milliseconds, bool ignoreinput)
+/// @param ms Number of milliseconds to sleep
+/// @param ignoreinput If true, only SIGINT (CTRL-C) can interrupt.
+void os_delay(uint64_t ms, bool ignoreinput)
{
if (ignoreinput) {
- if (milliseconds > INT_MAX) {
- milliseconds = INT_MAX;
+ if (ms > INT_MAX) {
+ ms = INT_MAX;
}
- LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, (int)milliseconds, got_int);
+ LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, (int)ms, got_int);
} else {
- os_microdelay(milliseconds * 1000);
+ os_microdelay(ms * 1000u, ignoreinput);
}
}
-/// Sleeps for a certain amount of microseconds
+/// Sleeps for `us` microseconds.
///
-/// @param microseconds Number of microseconds to sleep
-void os_microdelay(uint64_t microseconds)
+/// @param us Number of microseconds to sleep.
+/// @param ignoreinput If true, ignore all input (including SIGINT/CTRL-C).
+/// If false, waiting is aborted on any input.
+void os_microdelay(uint64_t us, bool ignoreinput)
{
- uint64_t elapsed = 0;
- uint64_t ns = microseconds * 1000; // convert to nanoseconds
+ uint64_t elapsed = 0u;
uint64_t base = uv_hrtime();
+ // Convert microseconds to nanoseconds, or UINT64_MAX on overflow.
+ const uint64_t ns = (us < UINT64_MAX / 1000u) ? us * 1000u : UINT64_MAX;
uv_mutex_lock(&delay_mutex);
while (elapsed < ns) {
- if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns - elapsed)
- == UV_ETIMEDOUT)
+ // If ignoring input, we simply wait the full delay.
+ // Else we check for input in ~100ms intervals.
+ const uint64_t ns_delta = ignoreinput
+ ? ns - elapsed
+ : MIN(ns - elapsed, 100000000u); // 100ms
+
+ const int rv = uv_cond_timedwait(&delay_cond, &delay_mutex, ns_delta);
+ if (0 != rv && UV_ETIMEDOUT != rv) {
+ assert(false);
+ break;
+ } // Else: Timeout proceeded normally.
+
+ if (!ignoreinput && os_char_avail()) {
break;
- uint64_t now = uv_hrtime();
+ }
+
+ const uint64_t now = uv_hrtime();
elapsed += now - base;
base = now;
}
@@ -94,12 +114,12 @@ struct tm *os_localtime_r(const time_t *restrict clock,
#endif
}
-/// Obtains the current Unix timestamp and adjusts it to local time.
+/// Gets the current Unix timestamp and adjusts it to local time.
///
/// @param result Pointer to a 'struct tm' where the result should be placed
/// @return A pointer to a 'struct tm' in the current time zone (the 'result'
/// argument) or NULL in case of error
-struct tm *os_get_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL
+struct tm *os_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL
{
time_t rawtime = time(NULL);
return os_localtime_r(&rawtime, result);
diff --git a/src/nvim/os/tty.c b/src/nvim/os/tty.c
new file mode 100644
index 0000000000..bd5b9b4506
--- /dev/null
+++ b/src/nvim/os/tty.c
@@ -0,0 +1,60 @@
+// 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
+
+//
+// Terminal/console utils
+//
+
+#include "nvim/os/os.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/tty.c.generated.h"
+#endif
+
+#ifdef WIN32
+# if !defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+# endif
+/// Guesses the terminal-type. Calls SetConsoleMode() and uv_set_vterm_state()
+/// if appropriate.
+///
+/// @param[in,out] term Name of the guessed terminal, statically-allocated
+/// @param out_fd stdout file descriptor
+void os_tty_guess_term(const char **term, int out_fd)
+{
+ bool winpty = (os_getenv("NVIM") != NULL);
+
+ if (winpty) {
+ // Force TERM=win32con when running in winpty.
+ *term = "win32con";
+ uv_set_vterm_state(UV_UNSUPPORTED);
+ return;
+ }
+
+ bool conemu_ansi = strequal(os_getenv("ConEmuANSI"), "ON");
+ bool vtp = false;
+
+ HANDLE handle = (HANDLE)_get_osfhandle(out_fd);
+ DWORD dwMode;
+ if (handle != INVALID_HANDLE_VALUE && GetConsoleMode(handle, &dwMode)) {
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ if (SetConsoleMode(handle, dwMode)) {
+ vtp = true;
+ }
+ }
+
+ if (*term == NULL) {
+ if (vtp) {
+ *term = "vtpcon";
+ } else if (conemu_ansi) {
+ *term = "conemu";
+ } else {
+ *term = "win32con";
+ }
+ }
+
+ if (conemu_ansi) {
+ uv_set_vterm_state(UV_SUPPORTED);
+ }
+}
+#endif
diff --git a/src/nvim/os/tty.h b/src/nvim/os/tty.h
new file mode 100644
index 0000000000..d771e63768
--- /dev/null
+++ b/src/nvim/os/tty.h
@@ -0,0 +1,7 @@
+#ifndef NVIM_OS_TTY_H
+#define NVIM_OS_TTY_H
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "os/tty.h.generated.h"
+#endif
+#endif // NVIM_OS_TTY_H
diff --git a/src/nvim/os/unix_defs.h b/src/nvim/os/unix_defs.h
index 690a39c3cd..60a2dfa882 100644
--- a/src/nvim/os/unix_defs.h
+++ b/src/nvim/os/unix_defs.h
@@ -1,14 +1,13 @@
#ifndef NVIM_OS_UNIX_DEFS_H
#define NVIM_OS_UNIX_DEFS_H
-// Windows doesn't have unistd.h, so we include it here to avoid numerous
-// instances of `#ifdef WIN32'.
#include <unistd.h>
+#include <sys/param.h>
// POSIX.1-2008 says that NAME_MAX should be in here
#include <limits.h>
-#define TEMP_DIR_NAMES {"$TMPDIR", "/tmp", ".", "~"}
+#define TEMP_DIR_NAMES { "$TMPDIR", "/tmp", ".", "~" }
#define TEMP_FILE_PATH_MAXLEN 256
#define HAVE_ACL (HAVE_POSIX_ACL || HAVE_SOLARIS_ACL)
@@ -16,7 +15,8 @@
// Special wildcards that need to be handled by the shell.
#define SPECIAL_WILDCHAR "`'{"
-// Separator character for environment variables.
+// Character that separates entries in $PATH.
#define ENV_SEPCHAR ':'
+#define ENV_SEPSTR ":"
#endif // NVIM_OS_UNIX_DEFS_H
diff --git a/src/nvim/os/users.c b/src/nvim/os/users.c
index 8ebb7562ef..c6463c2c92 100644
--- a/src/nvim/os/users.c
+++ b/src/nvim/os/users.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
+
// users.c -- operating system user information
#include <uv.h>
@@ -6,7 +9,6 @@
#include "nvim/os/os.h"
#include "nvim/garray.h"
#include "nvim/memory.h"
-#include "nvim/misc2.h"
#include "nvim/strings.h"
#ifdef HAVE_PWD_H
# include <pwd.h>
@@ -73,11 +75,10 @@ int os_get_uname(uv_uid_t uid, char *s, size_t len)
char *os_get_user_directory(const char *name)
{
#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
- struct passwd *pw;
- if (name == NULL) {
+ if (name == NULL || *name == NUL) {
return NULL;
}
- pw = getpwnam(name); // NOLINT(runtime/threadsafe_fn)
+ struct passwd *pw = getpwnam(name); // NOLINT(runtime/threadsafe_fn)
if (pw != NULL) {
// save the string from the static passwd entry into malloced memory
return xstrdup(pw->pw_dir);
diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h
index 6a29f86e79..356094baa1 100644
--- a/src/nvim/os/win_defs.h
+++ b/src/nvim/os/win_defs.h
@@ -1,6 +1,10 @@
#ifndef NVIM_OS_WIN_DEFS_H
#define NVIM_OS_WIN_DEFS_H
+#ifndef WIN32
+# error Header must be included only when compiling for Windows.
+#endif
+
// winsock2.h must be first to avoid incompatibilities
// with winsock.h (included by windows.h)
#include <winsock2.h>
@@ -15,18 +19,21 @@
#define NAME_MAX _MAX_PATH
-#define TEMP_DIR_NAMES {"$TMP", "$TEMP", "$USERPROFILE", ""}
+#define TEMP_DIR_NAMES { "$TMPDIR", "$TMP", "$TEMP", "$USERPROFILE", "" }
#define TEMP_FILE_PATH_MAXLEN _MAX_PATH
#define FNAME_ILLEGAL "\"*?><|"
-// Separator character for environment variables.
+// Character that separates entries in $PATH.
#define ENV_SEPCHAR ';'
+#define ENV_SEPSTR ";"
#define USE_CRNL
-// We have our own RGB macro in macros.h.
-#undef RGB
+// Windows defines a RGB macro that produces 0x00bbggrr color values for use
+// with GDI. Our macro is different, and we don't use GDI.
+// Duplicated from macros.h to avoid include-order sensitivity.
+#define RGB_(r, g, b) ((r << 16) | (g << 8) | b)
#ifdef _MSC_VER
# ifndef inline
@@ -35,6 +42,9 @@
# ifndef restrict
# define restrict __restrict
# endif
+# ifndef STDIN_FILENO
+# define STDIN_FILENO _fileno(stdin)
+# endif
# ifndef STDOUT_FILENO
# define STDOUT_FILENO _fileno(stdout)
# endif
@@ -49,7 +59,7 @@
#define BACKSLASH_IN_FILENAME
#ifdef _MSC_VER
-typedef SSIZE_T ssize_t;
+typedef int mode_t;
#endif
#ifndef SSIZE_MAX
@@ -86,4 +96,14 @@ typedef SSIZE_T ssize_t;
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
#endif // NVIM_OS_WIN_DEFS_H
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index def7e3b0e5..09ba718302 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.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
+
/*
* os_unix.c -- code for all flavors of Unix (BSD, SYSV, SVR4, POSIX, ...)
*
@@ -27,7 +30,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/mouse.h"
#include "nvim/garray.h"
#include "nvim/path.h"
@@ -63,9 +65,7 @@ static int selinux_enabled = -1;
#if defined(HAVE_SELINUX)
-/*
- * Copy security info from "from_file" to "to_file".
- */
+// Copy security info from "from_file" to "to_file".
void mch_copy_sec(char_u *from_file, char_u *to_file)
{
if (from_file == NULL)
@@ -79,11 +79,12 @@ void mch_copy_sec(char_u *from_file, char_u *to_file)
security_context_t to_context = NULL;
if (getfilecon((char *)from_file, &from_context) < 0) {
- /* If the filesystem doesn't support extended attributes,
- the original had no special security context and the
- target cannot have one either. */
- if (errno == EOPNOTSUPP)
+ // If the filesystem doesn't support extended attributes,
+ // the original had no special security context and the
+ // target cannot have one either.
+ if (errno == EOPNOTSUPP) {
return;
+ }
MSG_PUTS(_("\nCould not get security context for "));
msg_outtrans(from_file);
@@ -108,22 +109,18 @@ void mch_copy_sec(char_u *from_file, char_u *to_file)
freecon(from_context);
}
}
-#endif /* HAVE_SELINUX */
+#endif // HAVE_SELINUX
-/*
- * Return a pointer to the ACL of file "fname" in allocated memory.
- * Return NULL if the ACL is not available for whatever reason.
- */
-vim_acl_T mch_get_acl(char_u *fname)
+// Return a pointer to the ACL of file "fname" in allocated memory.
+// Return NULL if the ACL is not available for whatever reason.
+vim_acl_T mch_get_acl(const char_u *fname)
{
vim_acl_T ret = NULL;
return ret;
}
-/*
- * Set the ACL of file "fname" to "acl" (unless it's NULL).
- */
-void mch_set_acl(char_u *fname, vim_acl_T aclent)
+// Set the ACL of file "fname" to "acl" (unless it's NULL).
+void mch_set_acl(const char_u *fname, vim_acl_T aclent)
{
if (aclent == NULL)
return;
@@ -137,15 +134,22 @@ void mch_free_acl(vim_acl_T aclent)
#endif
void mch_exit(int r)
+ FUNC_ATTR_NORETURN
{
exiting = true;
- ui_builtin_stop();
ui_flush();
- ml_close_all(true); /* remove all memfiles */
+ ui_builtin_stop();
+ ml_close_all(true); // remove all memfiles
+
+ if (!event_teardown() && r == 0) {
+ r = 1; // Exit with error if main_loop did not teardown gracefully.
+ }
+ if (input_global_fd() >= 0) {
+ stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
+ }
- event_teardown();
- stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
+ ILOG("Nvim exit: %d", r);
#ifdef EXITFREE
free_all_mem();
@@ -176,7 +180,7 @@ void mch_exit(int r)
/// @returns OK for success or FAIL for error.
int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
char_u ***file, int flags) FUNC_ATTR_NONNULL_ARG(3)
- FUNC_ATTR_NONNULL_ARG(4)
+ FUNC_ATTR_NONNULL_ARG(4)
{
int i;
size_t len;
@@ -199,17 +203,22 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
int check_spaces;
static bool did_find_nul = false;
bool ampersent = false;
- /* vimglob() function to define for Posix shell */
+ // vimglob() function to define for Posix shell
static char *sh_vimglob_func =
"vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >";
- *num_file = 0; /* default: no files found */
+ bool is_fish_shell =
+#if defined(UNIX)
+ STRNCMP(invocation_path_tail(p_sh, NULL), "fish", 4) == 0;
+#else
+ false;
+#endif
+
+ *num_file = 0; // default: no files found
*file = NULL;
- /*
- * If there are no wildcards, just copy the names to allocated memory.
- * Saves a lot of time, because we don't have to start a new shell.
- */
+ // If there are no wildcards, just copy the names to allocated memory.
+ // Saves a lot of time, because we don't have to start a new shell.
if (!have_wildcard(num_pat, pat)) {
save_patterns(num_pat, pat, num_file, file);
return OK;
@@ -220,87 +229,99 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
return FAIL;
}
- /*
- * Don't allow the use of backticks in secure and restricted mode.
- */
- if (secure || restricted)
- for (i = 0; i < num_pat; ++i)
+ // Don't allow the use of backticks in secure and restricted mode.
+ if (secure || restricted) {
+ for (i = 0; i < num_pat; i++) {
if (vim_strchr(pat[i], '`') != NULL
- && (check_restricted() || check_secure()))
+ && (check_restricted() || check_secure())) {
return FAIL;
+ }
+ }
+ }
- /*
- * get a name for the temp file
- */
+ // get a name for the temp file
if ((tempname = vim_tempname()) == NULL) {
EMSG(_(e_notmp));
return FAIL;
}
- /*
- * Let the shell expand the patterns and write the result into the temp
- * file.
- * STYLE_BT: NL separated
- * If expanding `cmd` execute it directly.
- * STYLE_GLOB: NUL separated
- * If we use *csh, "glob" will work better than "echo".
- * STYLE_PRINT: NL or NUL separated
- * If we use *zsh, "print -N" will work better than "glob".
- * STYLE_VIMGLOB: NL separated
- * If we use *sh*, we define "vimglob()".
- * STYLE_ECHO: space separated.
- * A shell we don't know, stay safe and use "echo".
- */
+ // Let the shell expand the patterns and write the result into the temp
+ // file.
+ // STYLE_BT: NL separated
+ // If expanding `cmd` execute it directly.
+ // STYLE_GLOB: NUL separated
+ // If we use *csh, "glob" will work better than "echo".
+ // STYLE_PRINT: NL or NUL separated
+ // If we use *zsh, "print -N" will work better than "glob".
+ // STYLE_VIMGLOB: NL separated
+ // If we use *sh*, we define "vimglob()".
+ // STYLE_ECHO: space separated.
+ // A shell we don't know, stay safe and use "echo".
if (num_pat == 1 && *pat[0] == '`'
&& (len = STRLEN(pat[0])) > 2
- && *(pat[0] + len - 1) == '`')
+ && *(pat[0] + len - 1) == '`') {
shell_style = STYLE_BT;
- else if ((len = STRLEN(p_sh)) >= 3) {
- if (STRCMP(p_sh + len - 3, "csh") == 0)
+ } 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)
+ } else if (STRCMP(p_sh + len - 3, "zsh") == 0) {
shell_style = STYLE_PRINT;
+ }
}
if (shell_style == STYLE_ECHO && strstr((char *)path_tail(p_sh),
"sh") != NULL)
shell_style = STYLE_VIMGLOB;
- /* 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 */
+ // 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;
if (shell_style == STYLE_VIMGLOB)
len += STRLEN(sh_vimglob_func);
- for (i = 0; i < num_pat; ++i) {
- /* Count the length of the patterns in the same way as they are put in
- * "command" below. */
- ++len; /* add space */
- for (j = 0; pat[i][j] != NUL; ++j) {
- if (vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL)
- ++len; /* may add a backslash */
- ++len;
+ for (i = 0; i < num_pat; i++) {
+ // Count the length of the patterns in the same way as they are put in
+ // "command" below.
+ len++; // add space
+ for (j = 0; pat[i][j] != NUL; j++) {
+ if (vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL) {
+ len++; // may add a backslash
+ }
+ len++;
}
}
+
+ if (is_fish_shell) {
+ len += sizeof("egin;"" end") - 1;
+ }
+
command = xmalloc(len);
- /*
- * Build the shell command:
- * - Set $nonomatch depending on EW_NOTFOUND (hopefully the shell
- * recognizes this).
- * - Add the shell command to print the expanded names.
- * - Add the temp file name.
- * - Add the file name patterns.
- */
+ // Build the shell command:
+ // - Set $nonomatch depending on EW_NOTFOUND (hopefully the shell
+ // recognizes this).
+ // - Add the shell command to print the expanded names.
+ // - Add the temp file name.
+ // - Add the file name patterns.
if (shell_style == STYLE_BT) {
- /* change `command; command& ` to (command; command ) */
- STRCPY(command, "(");
- STRCAT(command, pat[0] + 1); /* exclude first backtick */
+ // change `command; command& ` to (command; command )
+ if (is_fish_shell) {
+ STRCPY(command, "begin; ");
+ } else {
+ STRCPY(command, "(");
+ }
+ STRCAT(command, pat[0] + 1); // exclude first backtick
p = command + STRLEN(command) - 1;
- *p-- = ')'; /* remove last backtick */
- while (p > command && ascii_iswhite(*p))
- --p;
- if (*p == '&') { /* remove trailing '&' */
+ if (is_fish_shell) {
+ *p-- = ';';
+ STRCAT(command, " end");
+ } else {
+ *p-- = ')'; // remove last backtick
+ }
+ while (p > command && ascii_iswhite(*p)) {
+ p--;
+ }
+ if (*p == '&') { // remove trailing '&'
ampersent = true;
*p = ' ';
}
@@ -322,113 +343,108 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
STRCAT(command, tempname);
- if (shell_style != STYLE_BT)
- for (i = 0; i < num_pat; ++i) {
- /* Put a backslash before special
- * characters, except inside ``. */
+ if (shell_style != STYLE_BT) {
+ for (i = 0; i < num_pat; i++) {
+ // Put a backslash before special
+ // characters, except inside ``.
bool intick = false;
p = command + STRLEN(command);
*p++ = ' ';
- for (j = 0; pat[i][j] != NUL; ++j) {
- if (pat[i][j] == '`')
+ for (j = 0; pat[i][j] != NUL; j++) {
+ if (pat[i][j] == '`') {
intick = !intick;
- else if (pat[i][j] == '\\' && pat[i][j + 1] != NUL) {
- /* Remove a backslash, take char literally. But keep
- * backslash inside backticks, before a special character
- * and before a backtick. */
+ } else if (pat[i][j] == '\\' && pat[i][j + 1] != NUL) {
+ // Remove a backslash, take char literally. But keep
+ // backslash inside backticks, before a special character
+ // and before a backtick.
if (intick
|| vim_strchr(SHELL_SPECIAL, pat[i][j + 1]) != NULL
- || pat[i][j + 1] == '`')
+ || pat[i][j + 1] == '`') {
*p++ = '\\';
- ++j;
+ }
+ j++;
} else if (!intick
- && ((flags & EW_KEEPDOLLAR) == 0 || pat[i][j] != '$')
- && vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL)
- /* Put a backslash before a special character, but not
- * when inside ``. And not for $var when EW_KEEPDOLLAR is
- * set. */
+ && ((flags & EW_KEEPDOLLAR) == 0 || pat[i][j] != '$')
+ && vim_strchr(SHELL_SPECIAL, pat[i][j]) != NULL) {
+ // Put a backslash before a special character, but not
+ // when inside ``. And not for $var when EW_KEEPDOLLAR is
+ // set.
*p++ = '\\';
+ }
- /* Copy one character. */
+ // Copy one character.
*p++ = pat[i][j];
}
*p = NUL;
}
+ }
if (flags & EW_SILENT) {
shellopts |= kShellOptHideMess;
}
- if (ampersent)
- STRCAT(command, "&"); /* put the '&' after the redirection */
-
- /*
- * Using zsh -G: If a pattern has no matches, it is just deleted from
- * the argument list, otherwise zsh gives an error message and doesn't
- * expand any other pattern.
- */
- if (shell_style == STYLE_PRINT)
- extra_shell_arg = (char_u *)"-G"; /* Use zsh NULL_GLOB option */
-
- /*
- * If we use -f then shell variables set in .cshrc won't get expanded.
- * vi can do it, so we will too, but it is only necessary if there is a "$"
- * in one of the patterns, otherwise we can still use the fast option.
- */
- else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat))
- extra_shell_arg = (char_u *)"-f"; /* Use csh fast option */
-
- /*
- * execute the shell command
- */
+ if (ampersent) {
+ STRCAT(command, "&"); // put the '&' after the redirection
+ }
+
+ // Using zsh -G: If a pattern has no matches, it is just deleted from
+ // the argument list, otherwise zsh gives an error message and doesn't
+ // expand any other pattern.
+ if (shell_style == STYLE_PRINT) {
+ extra_shell_arg = (char_u *)"-G"; // Use zsh NULL_GLOB option
+
+ // If we use -f then shell variables set in .cshrc won't get expanded.
+ // vi can do it, so we will too, but it is only necessary if there is a "$"
+ // in one of the patterns, otherwise we can still use the fast option.
+ } else if (shell_style == STYLE_GLOB && !have_dollars(num_pat, pat)) {
+ extra_shell_arg = (char_u *)"-f"; // Use csh fast option
+ }
+
+ // execute the shell command
i = call_shell(
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. */
- if (ampersent)
+ // When running in the background, give it some time to create the temp
+ // file, but don't wait for it to finish.
+ if (ampersent) {
os_delay(10L, true);
+ }
xfree(command);
- if (i) { /* os_call_shell() failed */
+ if (i) { // os_call_shell() failed
os_remove((char *)tempname);
xfree(tempname);
- /*
- * With interactive completion, the error message is not printed.
- */
- if (!(flags & EW_SILENT))
- {
- redraw_later_clear(); /* probably messed up screen */
- msg_putchar('\n'); /* clear bottom line quickly */
+ // With interactive completion, the error message is not printed.
+ if (!(flags & EW_SILENT)) {
+ msg_putchar('\n'); // clear bottom line quickly
#if SIZEOF_LONG > SIZEOF_INT
assert(Rows <= (long)INT_MAX + 1);
#endif
- cmdline_row = (int)(Rows - 1); /* continue on last line */
+ cmdline_row = (int)(Rows - 1); // continue on last line
MSG(_(e_wildexpand));
- msg_start(); /* don't overwrite this message */
+ msg_start(); // don't overwrite this message
}
- /* If a `cmd` expansion failed, don't list `cmd` as a match, even when
- * EW_NOTFOUND is given */
- if (shell_style == STYLE_BT)
+ // If a `cmd` expansion failed, don't list `cmd` as a match, even when
+ // EW_NOTFOUND is given
+ if (shell_style == STYLE_BT) {
return FAIL;
+ }
goto notfound;
}
- /*
- * read the names from the file into memory
- */
+ // read the names from the file into memory
fd = fopen((char *)tempname, READBIN);
if (fd == NULL) {
- /* Something went wrong, perhaps a file name with a special char. */
+ // Something went wrong, perhaps a file name with a special char.
if (!(flags & EW_SILENT)) {
MSG(_(e_wildexpand));
- msg_start(); /* don't overwrite this message */
+ msg_start(); // don't overwrite this message
}
xfree(tempname);
goto notfound;
@@ -439,7 +455,7 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
fclose(fd);
return FAIL;
}
- long long templen = ftell(fd); /* get size of temp file */
+ int64_t templen = ftell(fd); // get size of temp file
if (templen < 0) {
xfree(tempname);
fclose(fd);
@@ -457,7 +473,7 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
fclose(fd);
os_remove((char *)tempname);
if (readlen != len) {
- /* unexpected read error */
+ // unexpected read error
EMSG2(_(e_notread), tempname);
xfree(tempname);
xfree(buffer);
@@ -465,41 +481,40 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
}
xfree(tempname);
- /* file names are separated with Space */
+ // file names are separated with Space
if (shell_style == STYLE_ECHO) {
- buffer[len] = '\n'; /* make sure the buffer ends in NL */
+ buffer[len] = '\n'; // make sure the buffer ends in NL
p = buffer;
- for (i = 0; *p != '\n'; ++i) { /* count number of entries */
- while (*p != ' ' && *p != '\n')
- ++p;
- p = skipwhite(p); /* skip to next entry */
+ for (i = 0; *p != '\n'; i++) { // count number of entries
+ while (*p != ' ' && *p != '\n') {
+ p++;
+ }
+ p = skipwhite(p); // skip to next entry
}
- }
- /* file names are separated with NL */
- else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
- buffer[len] = NUL; /* make sure the buffer ends in NUL */
+ // file names are separated with NL
+ } else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
+ buffer[len] = NUL; // make sure the buffer ends in NUL
p = buffer;
- for (i = 0; *p != NUL; ++i) { /* count number of entries */
- while (*p != '\n' && *p != NUL)
- ++p;
- if (*p != NUL)
- ++p;
- p = skipwhite(p); /* skip leading white space */
+ for (i = 0; *p != NUL; i++) { // count number of entries
+ while (*p != '\n' && *p != NUL) {
+ p++;
+ }
+ if (*p != NUL) {
+ p++;
+ }
+ p = skipwhite(p); // skip leading white space
}
- }
- /* file names are separated with NUL */
- else {
- /*
- * Some versions of zsh use spaces instead of NULs to separate
- * results. Only do this when there is no NUL before the end of the
- * buffer, otherwise we would never be able to use file names with
- * embedded spaces when zsh does use NULs.
- * When we found a NUL once, we know zsh is OK, set did_find_nul and
- * don't check for spaces again.
- */
+ // file names are separated with NUL
+ } else {
+ // Some versions of zsh use spaces instead of NULs to separate
+ // results. Only do this when there is no NUL before the end of the
+ // buffer, otherwise we would never be able to use file names with
+ // embedded spaces when zsh does use NULs.
+ // When we found a NUL once, we know zsh is OK, set did_find_nul and
+ // don't check for spaces again.
check_spaces = false;
if (shell_style == STYLE_PRINT && !did_find_nul) {
- /* If there is a NUL, set did_find_nul, else set check_spaces */
+ // If there is a NUL, set did_find_nul, else set check_spaces
buffer[len] = NUL;
if (len && (int)STRLEN(buffer) < (int)len)
did_find_nul = true;
@@ -507,72 +522,69 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
check_spaces = true;
}
- /*
- * Make sure the buffer ends with a NUL. For STYLE_PRINT there
- * already is one, for STYLE_GLOB it needs to be added.
- */
- if (len && buffer[len - 1] == NUL)
- --len;
- else
+ // Make sure the buffer ends with a NUL. For STYLE_PRINT there
+ // already is one, for STYLE_GLOB it needs to be added.
+ if (len && buffer[len - 1] == NUL) {
+ len--;
+ } else {
buffer[len] = NUL;
+ }
i = 0;
- for (p = buffer; p < buffer + len; ++p)
- if (*p == NUL || (*p == ' ' && check_spaces)) { /* count entry */
- ++i;
+ for (p = buffer; p < buffer + len; p++) {
+ if (*p == NUL || (*p == ' ' && check_spaces)) { // count entry
+ i++;
*p = NUL;
}
- if (len)
- ++i; /* count last entry */
+ }
+ if (len) {
+ i++; // count last entry
+ }
}
assert(buffer[len] == NUL || buffer[len] == '\n');
if (i == 0) {
- /*
- * Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
- * /bin/sh will happily expand it to nothing rather than returning an
- * error; and hey, it's good to check anyway -- webb.
- */
+ // Can happen when using /bin/sh and typing ":e $NO_SUCH_VAR^I".
+ // /bin/sh will happily expand it to nothing rather than returning an
+ // error; and hey, it's good to check anyway -- webb.
xfree(buffer);
goto notfound;
}
*num_file = i;
*file = xmalloc(sizeof(char_u *) * (size_t)i);
- /*
- * Isolate the individual file names.
- */
+ // Isolate the individual file names.
p = buffer;
for (i = 0; i < *num_file; ++i) {
(*file)[i] = p;
- /* Space or NL separates */
+ // Space or NL separates
if (shell_style == STYLE_ECHO || shell_style == STYLE_BT
|| shell_style == STYLE_VIMGLOB) {
while (!(shell_style == STYLE_ECHO && *p == ' ')
- && *p != '\n' && *p != NUL)
- ++p;
- if (p == buffer + len) /* last entry */
+ && *p != '\n' && *p != NUL) {
+ p++;
+ }
+ if (p == buffer + len) { // last entry
*p = NUL;
- else {
+ } else {
*p++ = NUL;
- p = skipwhite(p); /* skip to next entry */
+ p = skipwhite(p); // skip to next entry
+ }
+ } else { // NUL separates
+ while (*p && p < buffer + len) { // skip entry
+ p++;
}
- } else { /* NUL separates */
- while (*p && p < buffer + len) /* skip entry */
- ++p;
- ++p; /* skip NUL */
+ p++; // skip NUL
}
}
- /*
- * Move the file names to allocated memory.
- */
+ // Move the file names to allocated memory.
for (j = 0, i = 0; i < *num_file; i++) {
// Require the files to exist. Helps when using /bin/sh
if (!(flags & EW_NOTFOUND) && !os_path_exists((*file)[i])) {
continue;
}
- /* check if this entry should be included */
+ // check if this entry should be included
dir = (os_isdir((*file)[i]));
if ((dir && !(flags & EW_DIR)) || (!dir && !(flags & EW_FILE)))
continue;
@@ -585,14 +597,15 @@ int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
p = xmalloc(STRLEN((*file)[i]) + 1 + dir);
STRCPY(p, (*file)[i]);
- if (dir)
- add_pathsep((char *)p); /* add '/' to a directory name */
+ if (dir) {
+ add_pathsep((char *)p); // add '/' to a directory name
+ }
(*file)[j++] = p;
}
xfree(buffer);
*num_file = j;
- if (*num_file == 0) { /* rejected all entries */
+ if (*num_file == 0) { // rejected all entries
xfree(*file);
*file = NULL;
goto notfound;
@@ -620,8 +633,8 @@ static void save_patterns(int num_pat, char_u **pat, int *num_file,
for (i = 0; i < num_pat; i++) {
s = vim_strsave(pat[i]);
- /* Be compatible with expand_filename(): halve the number of
- * backslashes. */
+ // Be compatible with expand_filename(): halve the number of
+ // backslashes.
backslash_halve(s);
(*file)[i] = s;
}
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 57499429ec..de697642c7 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.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 <inttypes.h>
#include <stdbool.h>
@@ -18,7 +21,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/option.h"
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
@@ -50,7 +52,8 @@
/// @param s2 Second file name.
/// @param checkname When both files don't exist, only compare their names.
/// @return Enum of type FileComparison. @see FileComparison.
-FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname)
+FileComparison path_full_compare(char_u *const s1, char_u *const s2,
+ const bool checkname)
{
assert(s1 && s2);
char_u exp1[MAXPATHL];
@@ -85,23 +88,23 @@ FileComparison path_full_compare(char_u *s1, char_u *s2, int checkname)
///
/// @return pointer just past the last path separator (empty string, if fname
/// ends in a slash), or empty string if fname is NULL.
-char_u *path_tail(char_u *fname)
+char_u *path_tail(const char_u *fname)
FUNC_ATTR_NONNULL_RET
{
if (fname == NULL) {
return (char_u *)"";
}
- char_u *tail = get_past_head(fname);
- char_u *p = tail;
+ const char_u *tail = get_past_head(fname);
+ const char_u *p = tail;
// Find last part of path.
while (*p != NUL) {
if (vim_ispathsep_nocolon(*p)) {
tail = p + 1;
}
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
- return tail;
+ return (char_u *)tail;
}
/// Get pointer to tail of "fname", including path separators.
@@ -142,7 +145,7 @@ const char_u *invocation_path_tail(const char_u *invocation, size_t *len)
const char_u *p = tail;
while (*p != NUL && *p != ' ') {
bool was_sep = vim_ispathsep_nocolon(*p);
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
if (was_sep) {
tail = p; // Now tail points one past the separator.
}
@@ -160,11 +163,11 @@ const char_u *invocation_path_tail(const char_u *invocation, size_t *len)
/// @param fname A file path. (Must be != NULL.)
/// @return Pointer to first found path separator + 1.
/// An empty string, if `fname` doesn't contain a path separator,
-char_u *path_next_component(char_u *fname)
+const char *path_next_component(const char *fname)
{
assert(fname != NULL);
while (*fname != NUL && !vim_ispathsep(*fname)) {
- mb_ptr_adv(fname);
+ MB_PTR_ADV(fname);
}
if (*fname != NUL) {
fname++;
@@ -172,21 +175,25 @@ char_u *path_next_component(char_u *fname)
return fname;
}
-/*
- * Get a pointer to one character past the head of a path name.
- * Unix: after "/"; DOS: after "c:\"; Mac: no head.
- * If there is no head, path is returned.
- */
-char_u *get_past_head(char_u *path)
+/// Get a pointer to one character past the head of a path name.
+/// Unix: after "/"; Win: after "c:\"
+/// If there is no head, path is returned.
+char_u *get_past_head(const char_u *path)
{
- char_u *retval;
+ const char_u *retval = path;
- retval = path;
+#ifdef WIN32
+ // May skip "c:"
+ if (isalpha(path[0]) && path[1] == ':') {
+ retval = path + 2;
+ }
+#endif
- while (vim_ispathsep(*retval))
+ while (vim_ispathsep(*retval)) {
++retval;
+ }
- return retval;
+ return (char_u *)retval;
}
/*
@@ -279,48 +286,63 @@ bool dir_of_file_exists(char_u *fname)
return retval;
}
-/*
- * Versions of fnamecmp() and fnamencmp() that handle '/' and '\' equally
- * and deal with 'fileignorecase'.
- */
-int vim_fnamecmp(char_u *x, char_u *y)
+/// Compare two file names
+///
+/// Handles '/' and '\\' correctly and deals with &fileignorecase option.
+///
+/// @param[in] fname1 First file name.
+/// @param[in] fname2 Second file name.
+///
+/// @return 0 if they are equal, non-zero otherwise.
+int path_fnamecmp(const char *fname1, const char *fname2)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
#ifdef BACKSLASH_IN_FILENAME
- return vim_fnamencmp(x, y, MAXPATHL);
+ const size_t len1 = strlen(fname1);
+ const size_t len2 = strlen(fname2);
+ return path_fnamencmp(fname1, fname2, MAX(len1, len2));
#else
- if (p_fic)
- return mb_stricmp(x, y);
- return STRCMP(x, y);
+ return mb_strcmp_ic((bool)p_fic, fname1, fname2);
#endif
}
-int vim_fnamencmp(char_u *x, char_u *y, size_t len)
+/// Compare two file names
+///
+/// Handles '/' and '\\' correctly and deals with &fileignorecase option.
+///
+/// @param[in] fname1 First file name.
+/// @param[in] fname2 Second file name.
+/// @param[in] len Compare at most len bytes.
+///
+/// @return 0 if they are equal, non-zero otherwise.
+int path_fnamencmp(const char *const fname1, const char *const fname2,
+ size_t len)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
#ifdef BACKSLASH_IN_FILENAME
- char_u *px = x;
- char_u *py = y;
- int cx = NUL;
- int cy = NUL;
+ int c1 = NUL;
+ int c2 = NUL;
+ const char *p1 = fname1;
+ const char *p2 = fname2;
while (len > 0) {
- cx = PTR2CHAR(px);
- cy = PTR2CHAR(py);
- if (cx == NUL || cy == NUL
- || ((p_fic ? vim_tolower(cx) != vim_tolower(cy) : cx != cy)
- && !(cx == '/' && cy == '\\')
- && !(cx == '\\' && cy == '/')))
+ c1 = PTR2CHAR((const char_u *)p1);
+ c2 = PTR2CHAR((const char_u *)p2);
+ if ((c1 == NUL || c2 == NUL
+ || (!((c1 == '/' || c1 == '\\') && (c2 == '\\' || c2 == '/'))))
+ && (p_fic ? (c1 != c2 && CH_FOLD(c1) != CH_FOLD(c2)) : c1 != c2)) {
break;
- len -= MB_PTR2LEN(px);
- px += MB_PTR2LEN(px);
- py += MB_PTR2LEN(py);
+ }
+ len -= (size_t)MB_PTR2LEN((const char_u *)p1);
+ p1 += MB_PTR2LEN((const char_u *)p1);
+ p2 += MB_PTR2LEN((const char_u *)p2);
}
- if (len == 0)
- return 0;
- return cx - cy;
+ return c1 - c2;
#else
- if (p_fic)
- return mb_strnicmp(x, y, len);
- return STRNCMP(x, y, len);
+ if (p_fic) {
+ return mb_strnicmp((const char_u *)fname1, (const char_u *)fname2, len);
+ }
+ return strncmp(fname1, fname2, len);
#endif
}
@@ -388,15 +410,22 @@ char *concat_fnames_realloc(char *fname1, const char *fname2, bool sep)
fname2, len2, sep);
}
-/*
- * Add a path separator to a file name, unless it already ends in a path
- * separator.
- */
-void add_pathsep(char *p)
+/// Adds a path separator to a filename, unless it already ends in one.
+///
+/// @return `true` if the path separator was added or already existed.
+/// `false` if the filename is too long.
+bool add_pathsep(char *p)
FUNC_ATTR_NONNULL_ALL
{
- if (*p != NUL && !after_pathsep(p, p + strlen(p)))
- strcat(p, PATHSEPSTR);
+ const size_t len = strlen(p);
+ if (*p != NUL && !after_pathsep(p, p + len)) {
+ const size_t pathsep_len = sizeof(PATHSEPSTR);
+ if (len > MAXPATHL - pathsep_len) {
+ return false;
+ }
+ memcpy(p + len, PATHSEPSTR, pathsep_len);
+ }
+ return true;
}
/// Get an allocated copy of the full path to a file.
@@ -406,32 +435,28 @@ void add_pathsep(char *p)
///
/// @return [allocated] Copy of absolute path to `fname` or NULL when
/// `fname` is NULL.
-char *FullName_save(char *fname, bool force)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC
+char *FullName_save(const char *fname, bool force)
+ FUNC_ATTR_MALLOC
{
if (fname == NULL) {
return NULL;
}
char *buf = xmalloc(MAXPATHL);
- char *new_fname = NULL;
- if (vim_FullName(fname, buf, MAXPATHL, force) != FAIL) {
- new_fname = xstrdup(buf);
- } else {
- new_fname = xstrdup(fname);
+ if (vim_FullName(fname, buf, MAXPATHL, force) == FAIL) {
+ xfree(buf);
+ return xstrdup(fname);
}
- xfree(buf);
-
- return new_fname;
+ return buf;
}
/// Saves the absolute path.
/// @param name An absolute or relative path.
/// @return The absolute path of `name`.
-char_u *save_absolute_path(const char_u *name)
- FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL
+char_u *save_abs_path(const char_u *name)
+ FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- if (!path_is_absolute_path(name)) {
+ if (!path_is_absolute(name)) {
return (char_u *)FullName_save((char *)name, true);
}
return vim_strsave((char_u *) name);
@@ -444,7 +469,7 @@ char_u *save_absolute_path(const char_u *name)
bool path_has_wildcard(const char_u *p)
FUNC_ATTR_NONNULL_ALL
{
- for (; *p; mb_ptr_adv(p)) {
+ for (; *p; MB_PTR_ADV(p)) {
#if defined(UNIX)
if (p[0] == '\\' && p[1] != NUL) {
p++;
@@ -479,7 +504,7 @@ static int pstrcmp(const void *a, const void *b)
bool path_has_exp_wildcard(const char_u *p)
FUNC_ATTR_NONNULL_ALL
{
- for (; *p != NUL; mb_ptr_adv(p)) {
+ for (; *p != NUL; MB_PTR_ADV(p)) {
#if defined(UNIX)
if (p[0] == '\\' && p[1] != NUL) {
p++;
@@ -562,11 +587,12 @@ static size_t do_path_expand(garray_T *gap, const char_u *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 >= path + wildoff && rem_backslash(path_end))
+ if (path_end >= path + wildoff && rem_backslash(path_end)) {
*p++ = *path_end++;
- else if (*path_end == '/') {
- if (e != NULL)
+ } else if (vim_ispathsep_nocolon(*path_end)) {
+ if (e != NULL) {
break;
+ }
s = p + 1;
} else if (path_end >= path + wildoff
&& (vim_strchr((char_u *)"*?[{~$", *path_end) != NULL
@@ -579,7 +605,7 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
}
if (has_mbyte) {
len = (size_t)(*mb_ptr2len)(path_end);
- STRNCPY(p, path_end, len);
+ memcpy(p, path_end, len);
p += len;
path_end += len;
} else
@@ -648,11 +674,12 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
// Find all matching entries.
char_u *name;
scandir_next_with_dots(NULL); // initialize
- while ((name = (char_u *) scandir_next_with_dots(&dir)) && name != NULL) {
+ while ((name = (char_u *)scandir_next_with_dots(&dir)) != NULL) {
if ((name[0] != '.'
|| starts_with_dot
|| ((flags & EW_DODOT)
- && name[1] != NUL && (name[1] != '.' || name[2] != NUL)))
+ && name[1] != NUL
+ && (name[1] != '.' || name[2] != NUL))) // -V557
&& ((regmatch.regprog != NULL && vim_regexec(&regmatch, name, 0))
|| ((flags & EW_NOTWILD)
&& fnamencmp(path + (s - buf), name, e - s) == 0))) {
@@ -718,7 +745,7 @@ static int find_previous_pathsep(char_u *path, char_u **psep)
while (*psep > path) {
if (vim_ispathsep(**psep))
return OK;
- mb_ptr_back(path, *psep);
+ MB_PTR_BACK(path, *psep);
}
return FAIL;
@@ -789,7 +816,7 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
STRCPY(buf, curdir); // relative to current directory
} else if (path_with_url((char *)buf)) {
continue; // URL can't be used here
- } else if (!path_is_absolute_path(buf)) {
+ } else if (!path_is_absolute(buf)) {
// Expand relative path to their full path equivalent
size_t len = STRLEN(curdir);
if (len + STRLEN(buf) + 3 > MAXPATHL) {
@@ -797,7 +824,7 @@ static void expand_path_option(char_u *curdir, garray_T *gap)
}
STRMOVE(buf + len + 1, buf);
STRCPY(buf, curdir);
- buf[len] = PATHSEP;
+ buf[len] = (char_u)PATHSEP;
simplify_filename(buf);
}
@@ -833,10 +860,12 @@ static char_u *get_path_cutoff(char_u *fname, garray_T *gap)
}
}
- /* skip to the file or directory name */
- if (cutoff != NULL)
- while (vim_ispathsep(*cutoff))
- mb_ptr_adv(cutoff);
+ // skip to the file or directory name
+ if (cutoff != NULL) {
+ while (vim_ispathsep(*cutoff)) {
+ MB_PTR_ADV(cutoff);
+ }
+ }
return cutoff;
}
@@ -884,9 +913,9 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
in_curdir = xcalloc((size_t)gap->ga_len, sizeof(char_u *));
for (int i = 0; i < gap->ga_len && !got_int; i++) {
- char_u *path = fnames[i];
+ char_u *path = fnames[i];
int is_in_curdir;
- char_u *dir_end = gettail_dir(path);
+ char_u *dir_end = (char_u *)gettail_dir((const char *)path);
char_u *pathsep_p;
char_u *path_cutoff;
@@ -899,31 +928,42 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
/* Shorten the filename while maintaining its uniqueness */
path_cutoff = get_path_cutoff(path, &path_ga);
- /* we start at the end of the path */
- pathsep_p = path + len - 1;
-
- while (find_previous_pathsep(path, &pathsep_p))
- if (vim_regexec(&regmatch, pathsep_p + 1, (colnr_T)0)
- && is_unique(pathsep_p + 1, gap, i)
- && path_cutoff != NULL && pathsep_p + 1 >= path_cutoff) {
- sort_again = true;
- memmove(path, pathsep_p + 1, STRLEN(pathsep_p));
- break;
+ // Don't assume all files can be reached without path when search
+ // pattern starts with **/, so only remove path_cutoff
+ // when possible.
+ if (pattern[0] == '*' && pattern[1] == '*'
+ && vim_ispathsep_nocolon(pattern[2])
+ && path_cutoff != NULL
+ && vim_regexec(&regmatch, path_cutoff, (colnr_T)0)
+ && is_unique(path_cutoff, gap, i)) {
+ sort_again = true;
+ memmove(path, path_cutoff, STRLEN(path_cutoff) + 1);
+ } else {
+ // Here all files can be reached without path, so get shortest
+ // unique path. We start at the end of the path. */
+ pathsep_p = path + len - 1;
+ while (find_previous_pathsep(path, &pathsep_p)) {
+ if (vim_regexec(&regmatch, pathsep_p + 1, (colnr_T)0)
+ && is_unique(pathsep_p + 1, gap, i)
+ && path_cutoff != NULL && pathsep_p + 1 >= path_cutoff) {
+ sort_again = true;
+ memmove(path, pathsep_p + 1, STRLEN(pathsep_p));
+ break;
+ }
}
+ }
- if (path_is_absolute_path(path)) {
- /*
- * Last resort: shorten relative to curdir if possible.
- * 'possible' means:
- * 1. It is under the current directory.
- * 2. The result is actually shorter than the original.
- *
- * Before curdir After
- * /foo/bar/file.txt /foo/bar ./file.txt
- * c:\foo\bar\file.txt c:\foo\bar .\file.txt
- * /file.txt / /file.txt
- * c:\file.txt c:\ .\file.txt
- */
+ if (path_is_absolute(path)) {
+ // Last resort: shorten relative to curdir if possible.
+ // 'possible' means:
+ // 1. It is under the current directory.
+ // 2. The result is actually shorter than the original.
+ //
+ // Before curdir After
+ // /foo/bar/file.txt /foo/bar ./file.txt
+ // c:\foo\bar\file.txt c:\foo\bar .\file.txt
+ // /file.txt / /file.txt
+ // c:\file.txt c:\ .\file.txt
short_name = path_shorten_fname(path, curdir);
if (short_name != NULL && short_name > path + 1
) {
@@ -975,20 +1015,22 @@ static void uniquefy_paths(garray_T *gap, char_u *pattern)
ga_remove_duplicate_strings(gap);
}
-/*
- * Return the end of the directory name, on the first path
- * separator:
- * "/path/file", "/path/dir/", "/path//dir", "/file"
- * ^ ^ ^ ^
- */
-char_u *gettail_dir(const char_u *fname)
+/// Find end of the directory name
+///
+/// @param[in] fname File name to process.
+///
+/// @return end of the directory name, on the first path separator:
+///
+/// "/path/file", "/path/dir/", "/path//dir", "/file"
+/// ^ ^ ^ ^
+const char *gettail_dir(const char *const fname)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- const char_u *dir_end = fname;
- const char_u *next_dir_end = fname;
+ const char *dir_end = fname;
+ const char *next_dir_end = fname;
bool look_for_sep = true;
- const char_u *p;
- for (p = fname; *p != NUL; ) {
+ for (const char *p = fname; *p != NUL; ) {
if (vim_ispathsep(*p)) {
if (look_for_sep) {
next_dir_end = p;
@@ -999,9 +1041,9 @@ char_u *gettail_dir(const char_u *fname)
dir_end = next_dir_end;
look_for_sep = true;
}
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
- return (char_u *)dir_end;
+ return dir_end;
}
@@ -1010,30 +1052,35 @@ char_u *gettail_dir(const char_u *fname)
* result in "gap".
* Returns the total number of matches.
*/
-static int
-expand_in_path (
- garray_T *gap,
- char_u *pattern,
- int flags /* EW_* flags */
+static int expand_in_path(
+ garray_T *const gap,
+ char_u *const pattern,
+ const int flags // EW_* flags
)
{
- char_u *curdir;
garray_T path_ga;
- char_u *paths = NULL;
- curdir = xmalloc(MAXPATHL);
+ char_u *const curdir = xmalloc(MAXPATHL);
os_dirname(curdir, MAXPATHL);
ga_init(&path_ga, (int)sizeof(char_u *), 1);
expand_path_option(curdir, &path_ga);
xfree(curdir);
- if (GA_EMPTY(&path_ga))
+ if (GA_EMPTY(&path_ga)) {
return 0;
+ }
- paths = ga_concat_strings(&path_ga);
+ char_u *const paths = ga_concat_strings(&path_ga);
ga_clear_strings(&path_ga);
- globpath(paths, pattern, gap, (flags & EW_ICASE) ? WILD_ICASE : 0);
+ int glob_flags = 0;
+ if (flags & EW_ICASE) {
+ glob_flags |= WILD_ICASE;
+ }
+ if (flags & EW_ADDSLASH) {
+ glob_flags |= WILD_ADD_SLASH;
+ }
+ globpath(paths, pattern, gap, glob_flags);
xfree(paths);
return gap->ga_len;
@@ -1046,29 +1093,29 @@ expand_in_path (
*/
static bool has_env_var(char_u *p)
{
- for (; *p; mb_ptr_adv(p)) {
- if (*p == '\\' && p[1] != NUL)
- ++p;
- else if (vim_strchr((char_u *)
- "$"
- , *p) != NULL)
+ for (; *p; MB_PTR_ADV(p)) {
+ if (*p == '\\' && p[1] != NUL) {
+ p++;
+ } else if (vim_strchr((char_u *) "$" , *p) != NULL) {
return true;
+ }
}
return false;
}
#ifdef SPECIAL_WILDCHAR
-/*
- * Return TRUE if "p" contains a special wildcard character.
- * Allowing for escaping.
- */
+
+// Return TRUE if "p" contains a special wildcard character, one that Vim
+// cannot expand, requires using a shell.
static bool has_special_wildchar(char_u *p)
{
- for (; *p; mb_ptr_adv(p)) {
- if (*p == '\\' && p[1] != NUL)
- ++p;
- else if (vim_strchr((char_u *)SPECIAL_WILDCHAR, *p) != NULL)
+ for (; *p; MB_PTR_ADV(p)) {
+ // Allow for escaping
+ if (*p == '\\' && p[1] != NUL) {
+ p++;
+ } else if (vim_strchr((char_u *)SPECIAL_WILDCHAR, *p) != NULL) {
return true;
+ }
}
return false;
}
@@ -1181,7 +1228,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
*/
if (path_has_exp_wildcard(p)) {
if ((flags & EW_PATH)
- && !path_is_absolute_path(p)
+ && !path_is_absolute(p)
&& !(p[0] == '.'
&& (vim_ispathsep(p[1])
|| (p[1] == '.' && vim_ispathsep(p[2]))))
@@ -1207,7 +1254,7 @@ int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
* "vim c:/" work. */
if (flags & EW_NOTFOUND) {
addfile(&ga, t, flags | EW_DIR | EW_FILE);
- } else if (os_path_exists(t)) {
+ } else {
addfile(&ga, t, flags);
}
xfree(t);
@@ -1296,14 +1343,14 @@ static int expand_backtick(
/// When the path looks like a URL leave it unmodified.
void slash_adjust(char_u *p)
{
- if (path_with_url(p)) {
+ if (path_with_url((const char *)p)) {
return;
}
while (*p) {
- if (*p == psepcN) {
- *p = psepc;
+ if (*p == (char_u)psepcN) {
+ *p = (char_u)psepc;
}
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
}
#endif
@@ -1404,19 +1451,22 @@ void simplify_filename(char_u *filename)
* we are after "start", or strip "." if we are at the beginning
* of an absolute path name . */
tail = p + 1;
- if (p[1] != NUL)
- while (vim_ispathsep(*tail))
- mb_ptr_adv(tail);
- else if (p > start)
- --p; /* strip preceding path separator */
+ if (p[1] != NUL) {
+ while (vim_ispathsep(*tail)) {
+ MB_PTR_ADV(tail);
+ }
+ } else if (p > start) {
+ p--; // strip preceding path separator
+ }
STRMOVE(p, tail);
}
} else if (p[0] == '.' && p[1] == '.'
&& (vim_ispathsep(p[2]) || p[2] == NUL)) {
// Skip to after ".." or "../" or "..///".
tail = p + 2;
- while (vim_ispathsep(*tail))
- mb_ptr_adv(tail);
+ while (vim_ispathsep(*tail)) {
+ MB_PTR_ADV(tail);
+ }
if (components > 0) { /* strip one preceding component */
bool do_strip = false;
@@ -1435,10 +1485,11 @@ void simplify_filename(char_u *filename)
}
p[-1] = saved_char;
- --p;
- /* Skip back to after previous '/'. */
- while (p > start && !after_pathsep((char *)start, (char *)p))
- mb_ptr_back(start, p);
+ p--;
+ // Skip back to after previous '/'.
+ while (p > start && !after_pathsep((char *)start, (char *)p)) {
+ MB_PTR_BACK(start, p);
+ }
if (!do_strip) {
/* If the component exists in the file system, check
@@ -1520,8 +1571,8 @@ void simplify_filename(char_u *filename)
p = tail; /* skip to char after ".." or "../" */
}
} else {
- ++components; /* simple path component */
- p = path_next_component(p);
+ components++; // Simple path component.
+ p = (char_u *)path_next_component((const char *)p);
}
} while (*p != NUL);
}
@@ -1627,35 +1678,48 @@ int path_with_url(const char *fname)
*/
bool vim_isAbsName(char_u *name)
{
- return path_with_url((char *)name) != 0 || path_is_absolute_path(name);
+ return path_with_url((char *)name) != 0 || path_is_absolute(name);
}
/// Save absolute file name to "buf[len]".
///
-/// @param fname is the filename to evaluate
-/// @param[out] buf is the buffer for returning the absolute path for `fname`
-/// @param len is the length of `buf`
-/// @param force is a flag to force expanding even if the path is absolute
+/// @param fname filename to evaluate
+/// @param[out] buf contains `fname` absolute path, or:
+/// - truncated `fname` if longer than `len`
+/// - unmodified `fname` if absolute path fails or is a URL
+/// @param len length of `buf`
+/// @param force flag to force expanding even if the path is absolute
///
/// @return FAIL for failure, OK otherwise
int vim_FullName(const char *fname, char *buf, size_t len, bool force)
FUNC_ATTR_NONNULL_ARG(2)
{
- int retval = OK;
- int url;
-
*buf = NUL;
- if (fname == NULL)
+ if (fname == NULL) {
return FAIL;
+ }
- url = path_with_url(fname);
- if (!url)
- retval = path_get_absolute_path((char_u *)fname, (char_u *)buf, len, force);
- if (url || retval == FAIL) {
- /* something failed; use the file name (truncate when too long) */
+ if (strlen(fname) > (len - 1)) {
+ xstrlcpy(buf, fname, len); // truncate
+#ifdef WIN32
+ slash_adjust((char_u *)buf);
+#endif
+ return FAIL;
+ }
+
+ if (path_with_url(fname)) {
xstrlcpy(buf, fname, len);
+ return OK;
}
- return retval;
+
+ int rv = path_to_absolute((char_u *)fname, (char_u *)buf, len, force);
+ if (rv == FAIL) {
+ xstrlcpy(buf, fname, len); // something failed; use the filename
+ }
+#ifdef WIN32
+ slash_adjust((char_u *)buf);
+#endif
+ return rv;
}
/// Get the full resolved path for `fname`
@@ -1668,7 +1732,7 @@ int vim_FullName(const char *fname, char *buf, size_t len, bool force)
///
/// @param fname is the filename to expand
/// @return [allocated] Full path (NULL for failure).
-char *fix_fname(char *fname)
+char *fix_fname(const char *fname)
{
#ifdef UNIX
return FullName_save(fname, true);
@@ -1688,7 +1752,7 @@ char *fix_fname(char *fname)
path_fix_case((char_u *)fname); // set correct case for file name
# endif
- return fname;
+ return (char *)fname;
#endif
}
@@ -1706,7 +1770,7 @@ void path_fix_case(char_u *name)
}
// Open the directory where the file is located.
- char_u *slash = vim_strrchr(name, '/');
+ char_u *slash = STRRCHR(name, '/');
char_u *tail;
Directory dir;
bool ok;
@@ -1755,7 +1819,7 @@ void path_fix_case(char_u *name)
int after_pathsep(const char *b, const char *p)
{
return p > b && vim_ispathsep(p[-1])
- && (!has_mbyte || (*mb_head_off)((char_u *)b, (char_u *)p - 1) == 0);
+ && utf_head_off((char_u *)b, (char_u *)p - 1) == 0;
}
/*
@@ -1809,7 +1873,7 @@ int pathcmp(const char *p, const char *q, int maxlen)
break;
}
- if ((p_fic ? vim_toupper(c1) != vim_toupper(c2) : c1 != c2)
+ if ((p_fic ? mb_toupper(c1) != mb_toupper(c2) : c1 != c2)
#ifdef BACKSLASH_IN_FILENAME
/* consider '/' and '\\' to be equal */
&& !((c1 == '/' && c2 == '\\')
@@ -1820,8 +1884,8 @@ int pathcmp(const char *p, const char *q, int maxlen)
return -1;
if (vim_ispathsep(c2))
return 1;
- return p_fic ? vim_toupper(c1) - vim_toupper(c2)
- : c1 - c2; /* no match */
+ return p_fic ? mb_toupper(c1) - mb_toupper(c2)
+ : c1 - c2; // no match
}
i += MB_PTR2LEN((char_u *)p + i);
@@ -1857,7 +1921,7 @@ int pathcmp(const char *p, const char *q, int maxlen)
/// - Pointer into `full_path` if shortened.
/// - `full_path` unchanged if no shorter name is possible.
/// - NULL if `full_path` is NULL.
-char_u *path_shorten_fname_if_possible(char_u *full_path)
+char_u *path_try_shorten_fname(char_u *full_path)
{
char_u *dirname = xmalloc(MAXPATHL);
char_u *p = full_path;
@@ -1974,14 +2038,13 @@ int expand_wildcards(int num_pat, char_u **pat, int *num_files, char_u ***files,
if (*p_wig) {
char_u *ffname;
- // check all filess in (*files)[]
+ // check all files in (*files)[]
for (i = 0; i < *num_files; i++) {
ffname = (char_u *)FullName_save((char *)(*files)[i], false);
- if (ffname == NULL) { // out of memory
- break;
- }
+ assert((*files)[i] != NULL);
+ assert(ffname != NULL);
if (match_file_list(p_wig, (*files)[i], ffname)) {
- // remove this matching files from the list
+ // remove this matching file from the list
xfree((*files)[i]);
for (j = i; j + 1 < *num_files; j++) {
(*files)[j] = (*files)[j + 1];
@@ -2099,24 +2162,18 @@ int path_full_dir_name(char *directory, char *buffer, size_t len)
}
// Append to_append to path with a slash in between.
-// Append to_append to path with a slash in between.
int append_path(char *path, const char *to_append, size_t max_len)
{
size_t current_length = strlen(path);
size_t to_append_length = strlen(to_append);
- // Do not append empty strings.
- if (to_append_length == 0) {
- return OK;
- }
-
- // Do not append a dot.
- if (STRCMP(to_append, ".") == 0) {
+ // Do not append empty string or a dot.
+ if (to_append_length == 0 || strcmp(to_append, ".") == 0) {
return OK;
}
- // Glue both paths with a slash.
- if (current_length > 0 && path[current_length-1] != '/') {
+ // Combine the path segments, separated by a slash.
+ if (current_length > 0 && !vim_ispathsep_nocolon(path[current_length-1])) {
current_length += 1; // Count the trailing slash.
// +1 for the NUL at the end.
@@ -2124,7 +2181,7 @@ int append_path(char *path, const char *to_append, size_t max_len)
return FAIL;
}
- STRCAT(path, "/");
+ xstrlcat(path, PATHSEPSTR, max_len);
}
// +1 for the NUL at the end.
@@ -2132,7 +2189,7 @@ int append_path(char *path, const char *to_append, size_t max_len)
return FAIL;
}
- STRCAT(path, to_append);
+ xstrlcat(path, to_append, max_len);
return OK;
}
@@ -2144,8 +2201,8 @@ int append_path(char *path, const char *to_append, size_t max_len)
/// @param force also expand when "fname" is already absolute.
///
/// @return FAIL for failure, OK for success.
-static int path_get_absolute_path(const char_u *fname, char_u *buf,
- size_t len, int force)
+static int path_to_absolute(const char_u *fname, char_u *buf, size_t len,
+ int force)
{
char_u *p;
*buf = NUL;
@@ -2154,15 +2211,22 @@ static int path_get_absolute_path(const char_u *fname, char_u *buf,
char *end_of_path = (char *) fname;
// expand it if forced or not an absolute path
- if (force || !path_is_absolute_path(fname)) {
- if ((p = vim_strrchr(fname, '/')) != NULL) {
+ if (force || !path_is_absolute(fname)) {
+ p = STRRCHR(fname, '/');
+#ifdef WIN32
+ if (p == NULL) {
+ p = STRRCHR(fname, '\\');
+ }
+#endif
+ if (p != NULL) {
// relative to root
if (p == fname) {
// only one path component
- relative_directory[0] = '/';
+ relative_directory[0] = PATHSEP;
relative_directory[1] = NUL;
} else {
- STRNCPY(relative_directory, fname, p-fname);
+ assert(p >= fname);
+ memcpy(relative_directory, fname, (size_t)(p - fname));
relative_directory[p-fname] = NUL;
}
end_of_path = (char *) (p + 1);
@@ -2180,11 +2244,65 @@ static int path_get_absolute_path(const char_u *fname, char_u *buf,
return append_path((char *)buf, end_of_path, len);
}
-/// Check if the given file is absolute.
+/// Check if file `fname` is a full (absolute) path.
///
-/// This just checks if the file name starts with '/' or '~'.
/// @return `TRUE` if "fname" is absolute.
-int path_is_absolute_path(const char_u *fname)
+int path_is_absolute(const char_u *fname)
{
+#ifdef WIN32
+ // A name like "d:/foo" and "//server/share" is absolute
+ return ((isalpha(fname[0]) && fname[1] == ':'
+ && vim_ispathsep_nocolon(fname[2]))
+ || (vim_ispathsep_nocolon(fname[0]) && fname[0] == fname[1]));
+#else
+ // UNIX: This just checks if the file name starts with '/' or '~'.
return *fname == '/' || *fname == '~';
+#endif
+}
+
+/// Builds a full path from an invocation name `argv0`, based on heuristics.
+///
+/// @param[in] argv0 Name by which Nvim was invoked.
+/// @param[out] buf Guessed full path to `argv0`.
+/// @param[in] bufsize Size of `buf`.
+///
+/// @see os_exepath
+void path_guess_exepath(const char *argv0, char *buf, size_t bufsize)
+ FUNC_ATTR_NONNULL_ALL
+{
+ char *path = getenv("PATH");
+
+ if (path == NULL || path_is_absolute((char_u *)argv0)) {
+ xstrlcpy(buf, argv0, bufsize);
+ } else if (argv0[0] == '.' || strchr(argv0, PATHSEP)) {
+ // Relative to CWD.
+ if (os_dirname((char_u *)buf, MAXPATHL) != OK) {
+ buf[0] = NUL;
+ }
+ xstrlcat(buf, PATHSEPSTR, bufsize);
+ xstrlcat(buf, argv0, bufsize);
+ } else {
+ // Search $PATH for plausible location.
+ const void *iter = NULL;
+ do {
+ const char *dir;
+ size_t dir_len;
+ iter = vim_env_iter(ENV_SEPCHAR, path, iter, &dir, &dir_len);
+ if (dir == NULL || dir_len == 0) {
+ break;
+ }
+ if (dir_len + 1 > sizeof(NameBuff)) {
+ continue;
+ }
+ xstrlcpy((char *)NameBuff, dir, dir_len + 1);
+ xstrlcat((char *)NameBuff, PATHSEPSTR, sizeof(NameBuff));
+ xstrlcat((char *)NameBuff, argv0, sizeof(NameBuff));
+ if (os_can_exe(NameBuff, NULL, false)) {
+ xstrlcpy(buf, (char *)NameBuff, bufsize);
+ return;
+ }
+ } while (iter != NULL);
+ // Not found in $PATH, fall back to argv0.
+ xstrlcpy(buf, argv0, bufsize);
+ }
}
diff --git a/src/nvim/po/CMakeLists.txt b/src/nvim/po/CMakeLists.txt
index 184c4894b9..3a70264dd1 100644
--- a/src/nvim/po/CMakeLists.txt
+++ b/src/nvim/po/CMakeLists.txt
@@ -1,15 +1,14 @@
-find_package(Gettext)
+find_package(Gettext REQUIRED)
find_program(XGETTEXT_PRG xgettext)
find_program(ICONV_PRG iconv)
-if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
- set(ENV{OLD_PO_FILE_INPUT} yes)
- set(ENV{OLD_PO_FILE_OUTPUT} yes)
-
+option(LANGUAGES "Localizations to build")
+if(NOT LANGUAGES)
set(LANGUAGES
af
ca
cs
+ da
de
en_GB
eo
@@ -22,22 +21,26 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
ko.UTF-8
nl
no
- pl
+ pl.UTF-8
pt_BR
ru
sk
sv
uk
vi
- zh_CN
zh_CN.UTF-8
- zh_TW
zh_TW.UTF-8)
+endif()
+
+if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
+ set(ENV{OLD_PO_FILE_INPUT} yes)
+ set(ENV{OLD_PO_FILE_OUTPUT} yes)
+
- set(NEOVIM_RELATIVE_SOURCES)
- foreach(SRC ${NEOVIM_SOURCES} ${NEOVIM_HEADERS})
+ set(NVIM_RELATIVE_SOURCES)
+ foreach(SRC ${NVIM_SOURCES} ${NVIM_HEADERS})
file(RELATIVE_PATH RELATIVE_SRC ${CMAKE_CURRENT_SOURCE_DIR} ${SRC})
- list(APPEND NEOVIM_RELATIVE_SOURCES ${RELATIVE_SRC})
+ list(APPEND NVIM_RELATIVE_SOURCES ${RELATIVE_SRC})
endforeach()
set(NVIM_POT ${CMAKE_CURRENT_BINARY_DIR}/nvim.pot)
@@ -48,11 +51,12 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
-DXGETTEXT_PRG=${XGETTEXT_PRG}
-DPOT_FILE=${NVIM_POT}
-DSEARCH_DIR=${CMAKE_CURRENT_SOURCE_DIR}
- "'-DSOURCES=${NEOVIM_RELATIVE_SOURCES}'"
+ "\"-DSOURCES=${NVIM_RELATIVE_SOURCES}\""
-P ${PROJECT_SOURCE_DIR}/cmake/RunXgettext.cmake
- DEPENDS ${NEOVIM_SOURCES})
+ DEPENDS ${NVIM_SOURCES})
add_custom_target(potfile DEPENDS ${NVIM_POT})
+ set_target_properties(potfile PROPERTIES FOLDER po)
set(LANGUAGE_MO_FILES)
set(UPDATE_PO_TARGETS)
@@ -89,6 +93,7 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
COMMENT "Checking ${name}.po"
VERBATIM
DEPENDS ${poFile})
+ set_target_properties(check-po-${name} PROPERTIES FOLDER po/check)
endmacro()
macro(BuildPoIconvGenericWithCharset
@@ -137,49 +142,30 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
endmacro()
# Create some translations from others.
- BuildPoIconv(ja utf-8 euc-jp)
- BuildMo(ja.euc-jp)
-
- BuildPoIconv(cs ISO-8859-2 cp1250)
- BuildMo(cs.cp1250)
-
- BuildPoIconv(pl ISO-8859-2 cp1250)
- BuildMo(pl.cp1250)
-
- BuildPoIconv(pl ISO-8859-2 UTF-8)
- BuildMo(pl.UTF-8)
-
- BuildPoIconv(sk ISO-8859-2 cp1250)
- BuildMo(sk.cp1250)
-
- BuildPoIconv(ru UTF-8 cp1251)
- BuildMo(ru.cp1251)
-
- BuildPoIconv(uk UTF-8 cp1251)
- BuildMo(uk.cp1251)
+ if(";${LANGUAGES};" MATCHES ";ja;")
+ BuildPoIconv(ja utf-8 euc-jp)
+ BuildMo(ja.euc-jp)
+ endif()
- BuildPoIconvGeneric(ko ko.UTF-8 ko UTF-8 euc-kr)
- BuildMo(ko)
+ if(";${LANGUAGES};" MATCHES ";cs;")
+ BuildPoIconv(cs ISO-8859-2 cp1250)
+ BuildMo(cs.cp1250)
+ endif()
- BuildPoIconvGenericWithCharset(zh_CN.cp936 zh_CN zh_CN.cp936 gb2312 cp936 gbk)
- BuildMo(zh_CN.cp936)
+ if(";${LANGUAGES};" MATCHES ";sk;")
+ BuildPoIconv(sk ISO-8859-2 cp1250)
+ BuildMo(sk.cp1250)
+ endif()
add_custom_target(update-po-nb
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/no.po ${CMAKE_CURRENT_SOURCE_DIR}/nb.po
DEPENDS no.po)
list(APPEND UPDATE_PO_TARGETS update-po-nb)
- CheckPo(nb)
- BuildMo(nb)
-
- add_executable(sjiscorr sjiscorr.c)
- add_custom_target(update-po-ja.sjis
- COMMAND iconv -f utf-8 -t cp932 ${CMAKE_CURRENT_SOURCE_DIR}/ja.po |
- $<TARGET_FILE:sjiscorr> > ${CMAKE_CURRENT_SOURCE_DIR}/ja.sjis.po
- DEPENDS ja.po sjiscorr)
- list(APPEND UPDATE_PO_TARGETS update-po-ja.sjis)
- CheckPo(ja.sjis)
- BuildMo(ja.sjis)
+ if(";${LANGUAGES};" MATCHES ";no;")
+ CheckPo(nb)
+ BuildMo(nb)
+ endif()
foreach(LANGUAGE ${LANGUAGES})
set(poFile "${CMAKE_CURRENT_SOURCE_DIR}/${LANGUAGE}.po")
@@ -199,7 +185,9 @@ if(HAVE_WORKING_LIBINTL AND GETTEXT_FOUND AND XGETTEXT_PRG AND ICONV_PRG)
BuildMo(${LANGUAGE})
endforeach()
+ set_target_properties(${UPDATE_PO_TARGETS} PROPERTIES FOLDER po/update)
add_custom_target(translations ALL DEPENDS ${LANGUAGE_MO_FILES})
add_custom_target(update-po DEPENDS ${UPDATE_PO_TARGETS})
+ set_target_properties(translations update-po PROPERTIES FOLDER po)
endif()
diff --git a/src/nvim/po/af.po b/src/nvim/po/af.po
index 6bb93b9e02..61ad72d7e0 100644
--- a/src/nvim/po/af.po
+++ b/src/nvim/po/af.po
@@ -26,7 +26,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim 6.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
+"POT-Creation-Date: 2017-11-07 20:04+0100\n"
"PO-Revision-Date: Wed Oct 31 13:41 SAST 2001\n"
"Last-Translator: Danie Roux <droux@tuks.co.za>\n"
"Language-Team: Danie Roux <droux@tuks.co.za>\n"
@@ -35,101 +35,74 @@ msgstr ""
"Content-Type: text/plain; charset=ISO_8859-1\n"
"Content-Transfer-Encoding: 8-bit\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "E258: Kan nie na kliënt stuur nie"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr ""
+#~ msgid "[Location List]"
+#~ msgstr ""
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr ""
+#~ msgid "[Quickfix List]"
+#~ msgstr ""
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr ""
+#~ msgid "E855: Autocommands caused command to abort"
+#~ msgstr ""
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: Kan nie buffer toeken nie, program sluit..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: Kan nie buffer toeken nie, gaan ander een gebruik..."
-#: ../buffer.c:763
+#~ msgid "E937: Attempt to delete a buffer that is in use"
+#~ msgstr ""
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Geen buffers is uitgelaai nie"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Geen buffers is geskrap nie"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Geen buffers is geskrap nie"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "1 buffer uitgelaai"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d buffers uitgelaai"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "1 buffer geskrap"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d buffers geskrap"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "1 buffer geskrap"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d buffers geskrap"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: Kan nie laaste buffer uitlaai nie"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Geen veranderde buffer gevind nie"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Daar is geen gelyste buffer nie"
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Buffer %<PRId64> bestaan nie"
-
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: Kan nie verby laaste buffer gaan nie"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: Kan nie vóór eerste buffer gaan nie"
-#: ../buffer.c:945
+#, fuzzy, c-format
+#~ msgid "E89: %s will be killed(add ! to override)"
+#~ msgstr "E189: \"%s\" bestaan (gebruik ! om te dwing)"
+
#, c-format
msgid ""
"E89: No write since last change for buffer %<PRId64> (add ! to override)"
@@ -138,117 +111,85 @@ msgstr ""
"dwing)"
#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Waarskuwing: Lêerlys loop oor"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
msgid "E92: Buffer %<PRId64> not found"
msgstr "E92: buffer %<PRId64> kon nie gevind word nie"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: Meer as een treffer vir %s"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: Geen buffer wat by %s pas nie"
-#: ../buffer.c:2161
#, c-format
msgid "line %<PRId64>"
msgstr "reël %<PRId64>"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Buffer met hierdie naam bestaan alreeds"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [Gewysig]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Ongewysig]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Nuwe lêer]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[Leesfoute]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[RO]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[lees alleen]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 reël --%d%%--"
-#: ../buffer.c:2526
#, c-format
msgid "%<PRId64> lines --%d%%--"
msgstr "%<PRId64> reëls --%d%%--"
-#: ../buffer.c:2530
#, c-format
msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
msgstr "reël %<PRId64> van %<PRId64> --%d%%-- kolom "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
#, fuzzy
-msgid "[No Name]"
-msgstr "[Geen lêer]"
+#~ msgid "[No Name]"
+#~ msgstr "[Geen lêer]"
#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "help"
-#: ../buffer.c:3225 ../screen.c:4883
#, fuzzy
-msgid "[Help]"
-msgstr "[help]"
+#~ msgid "[Help]"
+#~ msgstr "[help]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[Voorskou]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Alles"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Ond"
-#: ../buffer.c:3531
msgid "Top"
msgstr "Bo"
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# Buffer lys:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr ""
+#~ msgid "[Scratch]"
+#~ msgstr ""
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -256,208 +197,161 @@ msgstr ""
"\n"
"--- Tekens ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Tekens vir %s:"
-#: ../buffer.c:4543
#, c-format
msgid " line=%<PRId64> id=%d name=%s"
msgstr " reël=%<PRId64> id=%d naam=%s"
-#: ../cursor_shape.c:68
msgid "E545: Missing colon"
msgstr "E545: Ontbrekende dubbelpunt"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
msgid "E546: Illegal mode"
msgstr "E546: Ongeldige modus"
-#: ../cursor_shape.c:134
msgid "E548: digit expected"
msgstr "E548: syfer verwag"
-#: ../cursor_shape.c:138
msgid "E549: Illegal percentage"
msgstr "E549: Ongeldige persentasie"
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Kan nie meer as %<PRId64> buffers 'diff' nie"
+#, fuzzy, c-format
+#~ msgid "E96: Cannot diff more than %<PRId64> buffers"
+#~ msgstr "E96: Kan nie meer as %<PRId64> buffers 'diff' nie"
-#: ../diff.c:753
#, fuzzy
-msgid "E810: Cannot read or write temp files"
-msgstr "E557: Kan nie 'termcap'-lêer oopmaak nie"
+#~ msgid "E810: Cannot read or write temp files"
+#~ msgstr "E557: Kan nie 'termcap'-lêer oopmaak nie"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: Kan nie 'diffs' skep nie "
-#: ../diff.c:966
#, fuzzy
-msgid "E816: Cannot read patch output"
-msgstr "E98: Kan nie 'diff' afvoer lees nie"
+#~ msgid "E816: Cannot read patch output"
+#~ msgstr "E98: Kan nie 'diff' afvoer lees nie"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Kan nie 'diff' afvoer lees nie"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: Huidige buffer is nie in 'diff' modus nie"
-#: ../diff.c:2100
#, fuzzy
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E100: Geen ander buffer in 'diff' modus nie"
+#~ msgid "E793: No other buffer in diff mode is modifiable"
+#~ msgstr "E100: Geen ander buffer in 'diff' modus nie"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: Geen ander buffer in 'diff' modus nie"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr ""
"E101: Meer as twee buffers in 'diff' modus, weet nie watter een om te "
"gebruik nie"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: Kan buffer %s nie vind nie"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Buffer \"%s\" is nie in 'diff' modus nie"
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr ""
+#~ msgid "E787: Buffer changed unexpectedly"
+#~ msgstr ""
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: 'Escape' nie toegelaat in digraaf nie"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: Sleutelbindinglêer nie gevind nie"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :loadkeymap word buite 'n uitvoerlêer gebruik"
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr ""
+#~ msgid "E791: Empty keymap entry"
+#~ msgstr ""
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " Sleutelwoord voltooiing (^N^P)"
#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
#, fuzzy
-msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-msgstr " ^X modus (^E^Y^L^]^F^I^K^D^V^N^P)"
+#~ msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+#~ msgstr " ^X modus (^E^Y^L^]^F^I^K^D^V^N^P)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " Hele-reël voltooiing (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " Lêernaam voltooiing (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " Etiketvoltooiing (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " Gidspatroon voltooiing (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " Definisievoltooiing (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " Woordeboekvoltooiing (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " Tesourusvoltooiing (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " Bevelreëlvoltooiing (^V^N^P)"
-#: ../edit.c:94
#, fuzzy
-msgid " User defined completion (^U^N^P)"
-msgstr " Hele-reël voltooiing (^L^N^P)"
+#~ msgid " User defined completion (^U^N^P)"
+#~ msgstr " Hele-reël voltooiing (^L^N^P)"
-#: ../edit.c:95
#, fuzzy
-msgid " Omni completion (^O^N^P)"
-msgstr " Etiketvoltooiing (^]^N^P)"
+#~ msgid " Omni completion (^O^N^P)"
+#~ msgstr " Etiketvoltooiing (^]^N^P)"
-#: ../edit.c:96
#, fuzzy
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Hele-reël voltooiing (^L^N^P)"
+#~ msgid " Spelling suggestion (s^N^P)"
+#~ msgstr " Hele-reël voltooiing (^L^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " Sleutelwoord Lokale voltooiing (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Het einde van paragraaf getref"
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr ""
+#~ msgid "E839: Completion function changed window"
+#~ msgstr ""
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr ""
+#~ msgid "E840: Completion function deleted text"
+#~ msgstr ""
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "'dictionary' opsie is leeg"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "'thesaurus' opsie is leeg"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Deursoek woordeboek: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (invoeg) Rol (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (vervang) Rol (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "Soek vir: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "Deursoek etikette."
-#: ../edit.c:4519
msgid " Adding"
msgstr " Word bygevoeg"
@@ -465,605 +359,550 @@ msgstr " Word bygevoeg"
#. * be called before line = ml_get(), or when this address is no
#. * longer needed. -- Acevedo.
#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- Soekend..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "Terug by oorspronklike"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "Woord van ander reël"
-#: ../edit.c:4624
msgid "The only match"
msgstr "Die enigste treffer"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "treffer %d van %d"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "treffer %d"
-#: ../eval.c:137
#, fuzzy
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: Onverwagte karakters voor '='"
+#~ msgid "E18: Unexpected characters in :let"
+#~ msgstr "E18: Onverwagte karakters voor '='"
-#: ../eval.c:138
-#, fuzzy, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E322: reëlnommer buite perke: %<PRId64> verby die einde"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Ongedefinieerde veranderlike: %s"
-
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: Ontbrekende ']'"
-#: ../eval.c:141
#, fuzzy, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E487: Parameter moet positief wees"
+#~ msgid "E686: Argument of %s must be a List"
+#~ msgstr "E487: Parameter moet positief wees"
-#: ../eval.c:143
#, fuzzy, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E487: Parameter moet positief wees"
+#~ msgid "E712: Argument of %s must be a List or Dictionary"
+#~ msgstr "E487: Parameter moet positief wees"
-#: ../eval.c:144
#, fuzzy
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E214: Kan nie tydelike lêer vind vir skryf nie"
+#~ msgid "E714: List required"
+#~ msgstr "E471: Parameter benodig"
-#: ../eval.c:145
#, fuzzy
-msgid "E714: List required"
-msgstr "E471: Parameter benodig"
+#~ msgid "E715: Dictionary required"
+#~ msgstr "E129: Funksienaam vereis"
-#: ../eval.c:146
#, fuzzy
-msgid "E715: Dictionary required"
-msgstr "E129: Funksienaam vereis"
+#~ msgid "E928: String required"
+#~ msgstr "E397: Lêernaam benodig"
-#: ../eval.c:147
#, c-format
msgid "E118: Too many arguments for function: %s"
msgstr "E118: Te veel parameters vir funksie: %s"
-#: ../eval.c:148
#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr ""
+#~ msgid "E716: Key not present in Dictionary: %s"
+#~ msgstr ""
-#: ../eval.c:150
#, c-format
msgid "E122: Function %s already exists, add ! to replace it"
msgstr "E122: Funksie %s bestaan alreeds, gebruik ! om te vervang"
-#: ../eval.c:151
#, fuzzy
-msgid "E717: Dictionary entry already exists"
-msgstr "E95: Buffer met hierdie naam bestaan alreeds"
+#~ msgid "E717: Dictionary entry already exists"
+#~ msgstr "E95: Buffer met hierdie naam bestaan alreeds"
-#: ../eval.c:152
#, fuzzy
-msgid "E718: Funcref required"
-msgstr "E129: Funksienaam vereis"
+#~ msgid "E718: Funcref required"
+#~ msgstr "E129: Funksienaam vereis"
-#: ../eval.c:153
#, fuzzy
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E360: Kan nie dop met -f opsie uitvoer nie"
+#~ msgid "E719: Cannot use [:] with a Dictionary"
+#~ msgstr "E360: Kan nie dop met -f opsie uitvoer nie"
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr ""
-
-#: ../eval.c:155
#, fuzzy, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E117: Onbekende funksie: %s"
+#~ msgid "E130: Unknown function: %s"
+#~ msgstr "E117: Onbekende funksie: %s"
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Ongeldige veranderlikenaam: %s"
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E46: Cannot change read-only variable \"%.*s\""
+#~ msgstr "E46: Kan nie lees-alleen veranderlike stel nie \"%s\""
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr ""
+#. TODO(ZyX-I): move to eval/executor
+#, c-format
+#~ msgid "E734: Wrong variable type for %s="
+#~ msgstr ""
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr ""
+#~ msgid "E687: Less targets than List items"
+#~ msgstr ""
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr ""
+#~ msgid "E688: More targets than List items"
+#~ msgstr ""
+
+#~ msgid "Double ; in list of variables"
+#~ msgstr ""
-#: ../eval.c:2078
#, fuzzy, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E138: Kan nie viminfo lêer %s stoor nie!"
+#~ msgid "E738: Can't list variables for %s"
+#~ msgstr "E138: Kan nie viminfo lêer %s stoor nie!"
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E121: Undefined variable: %.*s"
+#~ msgstr "E121: Ongedefinieerde veranderlike: %s"
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr ""
+#~ msgid "E689: Can only index a List or Dictionary"
+#~ msgstr ""
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr ""
+#~ msgid "E708: [:] must come last"
+#~ msgstr ""
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr ""
+#, fuzzy
+#~ msgid "E713: Cannot use empty key after ."
+#~ msgstr "E214: Kan nie tydelike lêer vind vir skryf nie"
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr ""
+#~ msgid "E709: [:] requires a List value"
+#~ msgstr ""
+
+#~ msgid "E710: List value has more items than target"
+#~ msgstr ""
+
+#~ msgid "E711: List value has not enough items"
+#~ msgstr ""
-#: ../eval.c:2867
#, fuzzy
-msgid "E690: Missing \"in\" after :for"
-msgstr "E69: Ontbrekende ] na %s%%["
+#~ msgid "E690: Missing \"in\" after :for"
+#~ msgstr "E69: Ontbrekende ] na %s%%["
-#: ../eval.c:3063
#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: Ontbrekende hakies: %s"
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Geen veranderlike: \"%s\""
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr ""
+#. For historical reasons this error is not given for Lists and
+#. Dictionaries. E.g. b: dictionary may be locked/unlocked.
+#, fuzzy, c-format
+#~ msgid "E940: Cannot lock or unlock variable %s"
+#~ msgstr "E46: Kan nie lees-alleen veranderlike stel nie \"%s\""
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: Ontbrekende ':' na '?'"
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr ""
+#~ msgid "E691: Can only compare List with List"
+#~ msgstr ""
-#: ../eval.c:3895
#, fuzzy
-msgid "E692: Invalid operation for Lists"
-msgstr "E449: Ongeldige uitdrukking ontvang"
+#~ msgid "E692: Invalid operation for List"
+#~ msgstr "E449: Ongeldige uitdrukking ontvang"
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr ""
+#~ msgid "E735: Can only compare Dictionary with Dictionary"
+#~ msgstr ""
-#: ../eval.c:3917
#, fuzzy
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E116: Ongeldige parameters vir funksie %s"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr ""
+#~ msgid "E736: Invalid operation for Dictionary"
+#~ msgstr "E116: Ongeldige parameters vir funksie %s"
-#: ../eval.c:3934
#, fuzzy
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E116: Ongeldige parameters vir funksie %s"
+#~ msgid "E694: Invalid operation for Funcrefs"
+#~ msgstr "E116: Ongeldige parameters vir funksie %s"
-#: ../eval.c:4277
#, fuzzy
-msgid "E804: Cannot use '%' with Float"
-msgstr "E360: Kan nie dop met -f opsie uitvoer nie"
+#~ msgid "E804: Cannot use '%' with Float"
+#~ msgstr "E360: Kan nie dop met -f opsie uitvoer nie"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: Ontbrekende ')'"
-#: ../eval.c:4609
#, fuzzy
-msgid "E695: Cannot index a Funcref"
-msgstr "E90: Kan nie laaste buffer uitlaai nie"
+#~ msgid "E695: Cannot index a Funcref"
+#~ msgstr "E90: Kan nie laaste buffer uitlaai nie"
+
+#, fuzzy
+#~ msgid "E909: Cannot index a special variable"
+#~ msgstr "E90: Kan nie laaste buffer uitlaai nie"
-#: ../eval.c:4839
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Opsienaam ontbreek: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Onbekende opsie: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Ontbrekende aanhalingsteken: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Ontbrekende aanhalingsteken: %s"
-#: ../eval.c:5084
#, fuzzy, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E405: Ontbrekende gelykaanteken: %s"
+#~ msgid "E696: Missing comma in List: %s"
+#~ msgstr "E405: Ontbrekende gelykaanteken: %s"
-#: ../eval.c:5091
#, fuzzy, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E398: Ontbrekende '=': %s"
+#~ msgid "E697: Missing end of List ']': %s"
+#~ msgstr "E398: Ontbrekende '=': %s"
+
+#~ msgid "Not enough memory to set references, garbage collection aborted!"
+#~ msgstr ""
-#: ../eval.c:6475
#, fuzzy, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E242: Ontbrekende kleur: %s"
+#~ msgid "E720: Missing colon in Dictionary: %s"
+#~ msgstr "E242: Ontbrekende kleur: %s"
-#: ../eval.c:6499
#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr ""
+#~ msgid "E721: Duplicate key in Dictionary: \"%s\""
+#~ msgstr ""
-#: ../eval.c:6517
#, fuzzy, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E242: Ontbrekende kleur: %s"
+#~ msgid "E722: Missing comma in Dictionary: %s"
+#~ msgstr "E242: Ontbrekende kleur: %s"
-#: ../eval.c:6524
#, fuzzy, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E126: Ontbrekende ':endfunction'"
+#~ msgid "E723: Missing end of Dictionary '}': %s"
+#~ msgstr "E126: Ontbrekende ':endfunction'"
-#: ../eval.c:6555
-#, fuzzy
-msgid "E724: variable nested too deep for displaying"
-msgstr "E22: Skripte te diep ge-nes"
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Ongeldige parameter: %s"
-#: ../eval.c:7188
#, fuzzy, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E118: Te veel parameters vir funksie: %s"
+#~ msgid "E853: Duplicate argument name: %s"
+#~ msgstr "E125: Ongeldige parameter: %s"
+
+#, fuzzy, c-format
+#~ msgid "E740: Too many arguments for function %s"
+#~ msgstr "E118: Te veel parameters vir funksie: %s"
-#: ../eval.c:7190
#, c-format
msgid "E116: Invalid arguments for function %s"
msgstr "E116: Ongeldige parameters vir funksie %s"
-#: ../eval.c:7377
#, c-format
msgid "E117: Unknown function: %s"
msgstr "E117: Onbekende funksie: %s"
-#: ../eval.c:7383
+#, fuzzy, c-format
+#~ msgid "E933: Function was deleted: %s"
+#~ msgstr "E129: Funksienaam vereis"
+
#, c-format
msgid "E119: Not enough arguments for function: %s"
msgstr "E119: Te min parameters vir funksie: %s"
-#: ../eval.c:7387
#, c-format
msgid "E120: Using <SID> not in a script context: %s"
msgstr "E120: <SID> word buite skripkonteks gebruik: %s"
-#: ../eval.c:7391
#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr ""
+#~ msgid "E725: Calling dict function without Dictionary: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Error converting the call result: %s"
+#~ msgstr ""
-#: ../eval.c:7453
#, fuzzy
-msgid "E808: Number or Float required"
-msgstr "E521: Nommer vereis na ="
+#~ msgid "E699: Too many arguments"
+#~ msgstr "Te veel redigeer-parameters"
-#: ../eval.c:7503
#, fuzzy
-msgid "add() argument"
-msgstr "Ongeldige parameter vir"
+#~ msgid "E785: complete() can only be used in Insert mode"
+#~ msgstr "E328: Kieslys bestaan slegs in 'n ander modus"
+
+msgid "&Ok"
+msgstr "&Ok"
-#: ../eval.c:7907
#, fuzzy
-msgid "E699: Too many arguments"
-msgstr "Te veel redigeer-parameters"
+#~ msgid "dictwatcheradd() argument"
+#~ msgstr "Ongeldige parameter vir"
+
+#~ msgid "extend() argument"
+#~ msgstr ""
-#: ../eval.c:8073
#, fuzzy
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E328: Kieslys bestaan slegs in 'n ander modus"
+#~ msgid "map() argument"
+#~ msgstr " vim [parameters] "
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
+#~ msgid "filter() argument"
+#~ msgstr ""
-#: ../eval.c:8676
#, fuzzy, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E227: binding bestaan alreeds vir %s"
+#~ msgid "+-%s%3ld line: "
+#~ msgid_plural "+-%s%3ld lines: "
+#~ msgstr[0] "+-%s%3ld reëls: "
+#~ msgstr[1] "+-%s%3ld reëls: "
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E700: Unknown function: %s"
+#~ msgstr "E117: Onbekende funksie: %s"
+
+#~ msgid "E922: expected a dict"
+#~ msgstr ""
-#: ../eval.c:8915
#, fuzzy
-msgid "map() argument"
-msgstr " vim [parameters] "
+#~ msgid "E923: Second argument of function() must be a list or a dict"
+#~ msgstr "E487: Parameter moet positief wees"
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr ""
+#, fuzzy
+#~ msgid "E5000: Cannot find tab number."
+#~ msgstr "E90: Kan nie laaste buffer uitlaai nie"
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld reëls: "
+#~ msgid "E5001: Higher scope cannot be -1 if lower scope is >= 0."
+#~ msgstr ""
-#: ../eval.c:9291
-#, fuzzy, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E117: Onbekende funksie: %s"
+#, fuzzy
+#~ msgid "E5002: Cannot find window number."
+#~ msgstr "E671: Kan nie venster titel vind nie \"%s\""
+
+#~ msgid "E5050: {opts} must be the only argument"
+#~ msgstr ""
-#: ../eval.c:10729
msgid "called inputrestore() more often than inputsave()"
msgstr "inputrestore() is meer gereeld as inputsave() geroep"
-#: ../eval.c:10771
#, fuzzy
-msgid "insert() argument"
-msgstr "Te veel redigeer-parameters"
+#~ msgid "insert() argument"
+#~ msgstr "Te veel redigeer-parameters"
-#: ../eval.c:10841
#, fuzzy
-msgid "E786: Range not allowed"
-msgstr "E481: Geen omvang toegelaat nie"
+#~ msgid "E786: Range not allowed"
+#~ msgstr "E481: Geen omvang toegelaat nie"
+
+#~ msgid "Invalid stream on rpc job, use jobclose(id, 'rpc')"
+#~ msgstr ""
+
+#~ msgid "Invalid job stream: Not an rpc job"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Invalid job stream \"%s\""
+#~ msgstr ""
+
+#~ msgid "Can't send data to the job: stdin is closed"
+#~ msgstr ""
+
+#~ msgid "Can't send raw data to rpc channel"
+#~ msgstr ""
+
+#~ msgid "E474: Failed to convert list to string"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Failed to parse %.*s"
+#~ msgstr "E241: Kan nie na %s stuur nie"
-#: ../eval.c:11140
#, fuzzy
-msgid "E701: Invalid type for len()"
-msgstr "E596: Ongeldige font(e)"
+#~ msgid "E701: Invalid type for len()"
+#~ msgstr "E596: Ongeldige font(e)"
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr ""
+#, c-format
+#~ msgid "E798: ID is reserved for \":match\": %<PRId64>"
+#~ msgstr ""
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr ""
+#, c-format
+#~ msgid "E798: ID is reserved for \"match\": %<PRId64>"
+#~ msgstr ""
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "msgpackdump() argument, index %i"
+#~ msgstr " vim [parameters] "
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr ""
+#~ msgid "E5070: Character number must not be less than zero"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E5071: Character number must not be greater than INT_MAX (%i)"
+#~ msgstr ""
+
+#~ msgid "E726: Stride is zero"
+#~ msgstr ""
+
+#~ msgid "E727: Start past end"
+#~ msgstr ""
+
+#~ msgid "<empty>"
+#~ msgstr ""
+
+#~ msgid "remove() argument"
+#~ msgstr ""
-#: ../eval.c:12466
msgid "E655: Too many symbolic links (cycle?)"
msgstr "E655: Te veel simboliese skakels (siklus?)"
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr ""
+#~ msgid "reverse() argument"
+#~ msgstr ""
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E927: Invalid action: '%s'"
+#~ msgstr "E383: Ongeldige soekstring: %s"
+
+#, fuzzy, c-format
+#~ msgid "connection failed: %s"
+#~ msgstr "XSMP 'SmcOpenConnection' het gefaal: %s"
+
+#~ msgid "sort() argument"
+#~ msgstr ""
-#: ../eval.c:13721
#, fuzzy
-msgid "uniq() argument"
-msgstr "Ongeldige parameter vir"
+#~ msgid "uniq() argument"
+#~ msgstr "Ongeldige parameter vir"
-#: ../eval.c:13776
#, fuzzy
-msgid "E702: Sort compare function failed"
-msgstr "E237: Drukker-seleksie het gefaal"
+#~ msgid "E702: Sort compare function failed"
+#~ msgstr "E237: Drukker-seleksie het gefaal"
-#: ../eval.c:13806
-msgid "E882: Uniq compare function failed"
-msgstr ""
+#~ msgid "E882: Uniq compare function failed"
+#~ msgstr ""
-#: ../eval.c:14085
msgid "(Invalid)"
msgstr "(Ongeldig)"
-#: ../eval.c:14590
-#, fuzzy
-msgid "E677: Error writing temp file"
-msgstr "E208: Kan nie skryf na \"%s\""
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E935: invalid submatch number: %d"
+#~ msgstr "E354: Ongeldige registernaam: '%s'"
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr ""
+#~ msgid "Can only call this function in an unmodified buffer"
+#~ msgstr ""
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr ""
+#, fuzzy
+#~ msgid "E921: Invalid callback argument"
+#~ msgstr "E474: Ongeldige parameter"
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E80: Error while writing: %s"
+#~ msgstr "E80: Fout tydens skryfoperasie"
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr ""
+#. Using %s, p and not %c, *p to preserve multibyte characters
+#, fuzzy, c-format
+#~ msgid "E5060: Unknown flag: %s"
+#~ msgstr "E235: Onbekende font: %s"
-#: ../eval.c:16262
#, fuzzy
-msgid "E730: using List as a String"
-msgstr "E374: Ontbrekende ] in formaatstring"
+#~ msgid "E482: Can't open file with an empty name"
+#~ msgstr "E212: Kan lêer nie oopmaak vir skryf nie"
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E482: Can't open file %s for writing: %s"
+#~ msgstr "E212: Kan lêer nie oopmaak vir skryf nie"
-#: ../eval.c:16619
#, fuzzy, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E93: Meer as een treffer vir %s"
+#~ msgid "E80: Error when closing file %s: %s"
+#~ msgstr "E209: Kan \"%s\" nie sluit nie"
-#: ../eval.c:16705
#, fuzzy, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E46: Kan nie lees-alleen veranderlike stel nie \"%s\""
+#~ msgid "E794: Cannot set variable in the sandbox: \"%.*s\""
+#~ msgstr "E46: Kan nie lees-alleen veranderlike stel nie \"%s\""
-#: ../eval.c:16724
#, fuzzy, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
+#~ msgid "E795: Cannot delete variable %.*s"
+#~ msgstr "E46: Kan nie lees-alleen veranderlike stel nie \"%s\""
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E704: Funcref variable name must start with a capital: %s"
+#~ msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
-#: ../eval.c:16763
#, c-format
-msgid "E741: Value is locked: %s"
-msgstr ""
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Onbekend"
-
-#: ../eval.c:16768
-#, fuzzy, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E284: Kan nie IC waardes stel nie"
+#~ msgid "E705: Variable name conflicts with existing function: %s"
+#~ msgstr ""
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr ""
+#~ msgid "E698: variable nested too deep for making a copy"
+#~ msgstr ""
-#: ../eval.c:17249
#, c-format
msgid "E123: Undefined function: %s"
msgstr "E123: Ongedefinieerde funksie: %s"
-#: ../eval.c:17260
#, c-format
msgid "E124: Missing '(': %s"
msgstr "E124: Ontbrekende '(': %s"
-#: ../eval.c:17293
#, fuzzy
-msgid "E862: Cannot use g: here"
-msgstr "E284: Kan nie IC waardes stel nie"
+#~ msgid "E862: Cannot use g: here"
+#~ msgstr "E284: Kan nie IC waardes stel nie"
-#: ../eval.c:17312
#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Ongeldige parameter: %s"
-
-#: ../eval.c:17323
-#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E125: Ongeldige parameter: %s"
+#~ msgid "E932: Closure function should not be at top level: %s"
+#~ msgstr ""
-#: ../eval.c:17416
msgid "E126: Missing :endfunction"
msgstr "E126: Ontbrekende ':endfunction'"
-#: ../eval.c:17537
#, fuzzy, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
+#~ msgid "E707: Function name conflicts with variable: %s"
+#~ msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
-#: ../eval.c:17549
#, c-format
msgid "E127: Cannot redefine function %s: It is in use"
msgstr "E127: Kan funksie %s nie herdefinieer nie: Dit is in gebruik"
-#: ../eval.c:17604
#, fuzzy, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
+#~ msgid "E746: Function name does not match script file name: %s"
+#~ msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
-#: ../eval.c:17716
msgid "E129: Function name required"
msgstr "E129: Funksienaam vereis"
-#: ../eval.c:17824
#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
+#~ msgid "E128: Function name must start with a capital or \"s:\": %s"
+#~ msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
-#: ../eval.c:17833
#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
+#~ msgid "E884: Function name cannot contain a colon: %s"
+#~ msgstr "E128: Funksienaam moet met 'n hoofletter begin: %s"
-#: ../eval.c:18336
#, c-format
msgid "E131: Cannot delete function %s: It is in use"
msgstr "E131: Kan funksie %s nie verwyder nie: Dit is in gebruik"
-#: ../eval.c:18441
+#, fuzzy, c-format
+#~ msgid "Cannot delete function %s: It is being used internally"
+#~ msgstr "E131: Kan funksie %s nie verwyder nie: Dit is in gebruik"
+
msgid "E132: Function call depth is higher than 'maxfuncdepth'"
msgstr "E132: Funksieroepdiepte is groter as 'maxfuncdepth'"
-#: ../eval.c:18568
#, c-format
msgid "calling %s"
msgstr "roep %s"
-#: ../eval.c:18651
#, c-format
msgid "%s aborted"
msgstr "%s gekanselleer"
-#: ../eval.c:18653
#, c-format
msgid "%s returning #%<PRId64>"
msgstr "%s lewer #%<PRId64> op"
-#: ../eval.c:18670
#, fuzzy, c-format
-msgid "%s returning %s"
-msgstr "%s lewer \"%s\" op"
+#~ msgid "%s returning %s"
+#~ msgstr "%s lewer \"%s\" op"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
msgid "continuing in %s"
msgstr "vervolg in %s"
-#: ../eval.c:18795
msgid "E133: :return not inside a function"
msgstr "E133: ':return' buite funksie"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# globale veranderlikes:\n"
-
-#: ../eval.c:19254
msgid ""
"\n"
"\tLast set from "
@@ -1071,154 +910,418 @@ msgstr ""
"\n"
"\tLaas gestel vanaf "
-#: ../eval.c:19272
-#, fuzzy
-msgid "No old files"
-msgstr "Geen ingeslote lêers nie"
+#~ msgid "E5009: $VIMRUNTIME is empty or unset"
+#~ msgstr ""
-#: ../ex_cmds.c:122
#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, Hex %02x, Oktaal %03o"
+#~ msgid "E5009: Invalid $VIMRUNTIME: %s"
+#~ msgstr ""
-#: ../ex_cmds.c:145
#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, Hex %04x, Oktaal %o"
+#~ msgid "E474: Expected comma before list item: %s"
+#~ msgstr ""
-#: ../ex_cmds.c:146
#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, Hex %08x, Oktaal %o"
+#~ msgid "E474: Expected colon before dictionary value: %s"
+#~ msgstr ""
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: Skuif reëls in hulself in"
+#, fuzzy, c-format
+#~ msgid "E474: Expected string key: %s"
+#~ msgstr "E415: onverwagte gelykaanteken: %s"
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "1 reël geskuif"
+#, fuzzy, c-format
+#~ msgid "E474: Expected comma before dictionary key: %s"
+#~ msgstr "E242: Ontbrekende kleur: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unfinished escape sequence: %.*s"
+#~ msgstr "E540: Onvoltooide uitdrukkingreeks"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> reëls geskuif"
+#~ msgid "E474: Unfinished unicode escape sequence: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> reëls filtreer"
+#~ msgid "E474: Expected four hex digits after \\u: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: *Filter* Outobevele mag nie die huidige buffer verander nie"
+#, fuzzy, c-format
+#~ msgid "E474: Unknown escape sequence: %.*s"
+#~ msgstr "E409: Onbekende groepnaam: %s"
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[Ongestoor sedert vorige verandering]\n"
+#, c-format
+#~ msgid "E474: ASCII control characters cannot be present inside string: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1424
#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s in reël: "
+#~ msgid "E474: Only UTF-8 strings allowed: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: Te veel foute, slaan die res van die lêer oor"
+#, c-format
+#~ msgid ""
+#~ "E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: "
+#~ "%.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected string end: %.*s"
+#~ msgstr "E415: onverwagte gelykaanteken: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Leading zeroes are not allowed: %.*s"
+#~ msgstr "E481: Geen omvang toegelaat nie"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing number after minus sign: %.*s"
+#~ msgstr "E526: Ontbrekende nommer na <%s>"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing number after decimal dot: %.*s"
+#~ msgstr "E526: Ontbrekende nommer na <%s>"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing exponent: %.*s"
+#~ msgstr "E114: Ontbrekende aanhalingsteken: %s"
-#: ../ex_cmds.c:1458
#, c-format
-msgid "Reading viminfo file \"%s\"%s%s%s"
-msgstr "Besig om viminfo lêer \"%s\"%s%s%s te lees"
+#~ msgid ""
+#~ "E685: internal error: while converting number \"%.*s\" to float string2float "
+#~ "consumed %zu bytes in place of %zu"
+#~ msgstr ""
-#: ../ex_cmds.c:1460
-msgid " info"
-msgstr " inligting"
+#, c-format
+#~ msgid ""
+#~ "E685: internal error: while converting number \"%.*s\" to integer vim_str2nr "
+#~ "consumed %i bytes in place of %zu"
+#~ msgstr ""
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " merkers"
+#~ msgid "E474: Attempt to decode a blank string"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E474: No container to close: %.*s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E474: Closing list with curly bracket: %.*s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E474: Closing dictionary with square bracket: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Trailing comma: %.*s"
+#~ msgstr "E488: Oorbodige karakters"
+
+#, c-format
+#~ msgid "E474: Expected value after colon: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected value: %.*s"
+#~ msgstr "E415: onverwagte gelykaanteken: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Comma not inside container: %.*s"
+#~ msgstr "E242: Kleurnaam is onbekend: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Duplicate comma: %.*s"
+#~ msgstr "E125: Ongeldige parameter: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Comma after colon: %.*s"
+#~ msgstr "E254: Kan nie kleur %s toeken nie"
+
+#, fuzzy, c-format
+#~ msgid "E474: Using comma in place of colon: %.*s"
+#~ msgstr "E242: Ontbrekende kleur: %s"
+
+#, c-format
+#~ msgid "E474: Leading comma: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Colon not inside container: %.*s"
+#~ msgstr "E242: Kleurnaam is onbekend: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Using colon not in dictionary: %.*s"
+#~ msgstr "E242: Ontbrekende kleur: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unexpected colon: %.*s"
+#~ msgstr "E415: onverwagte gelykaanteken: %s"
+
+#, c-format
+#~ msgid "E474: Colon after comma: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Duplicate colon: %.*s"
+#~ msgstr "gelaaide fontnaam: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected null: %.*s"
+#~ msgstr "E415: onverwagte gelykaanteken: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected true: %.*s"
+#~ msgstr "E415: onverwagte gelykaanteken: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected false: %.*s"
+#~ msgstr "E415: onverwagte gelykaanteken: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unidentified byte: %.*s"
+#~ msgstr "E121: Ongedefinieerde veranderlike: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Trailing characters: %.*s"
+#~ msgstr "E488: Oorbodige karakters"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unexpected end of input: %.*s"
+#~ msgstr "E415: onverwagte gelykaanteken: %s"
+
+#, c-format
+#~ msgid "key %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "key %s at index %i from special map"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "index %i"
+#~ msgstr ""
+
+#~ msgid "partial"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "argument %i"
+#~ msgstr " vim [parameters] "
+
+#~ msgid "partial self dictionary"
+#~ msgstr ""
+
+#~ msgid "itself"
+#~ msgstr ""
+
+#. Only give this message once for a recursive call to avoid
+#. flooding the user with errors.
+#~ msgid "E724: unable to correctly dump variable with self-referencing container"
+#~ msgstr ""
+
+#~ msgid "E474: Unable to represent NaN value in JSON"
+#~ msgstr ""
+
+#~ msgid "E474: Unable to represent infinity in JSON"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "E474: String \"%.*s\" contains byte that does not start any UTF-8 character"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "E474: UTF-8 string contains code point which belongs to a surrogate pair: "
+#~ "%.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1462
#, fuzzy
-msgid " oldfiles"
-msgstr "Geen ingeslote lêers nie"
+#~ msgid "E474: Unable to convert EXT string to JSON"
+#~ msgstr "E620: Kon nie van wye-greep na \"%s\" enkodering verander nie"
-#: ../ex_cmds.c:1463
-msgid " FAILED"
-msgstr " GEFAAL"
+#, c-format
+#~ msgid "E474: Error while dumping %s, %s: attempt to dump function reference"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E474: Invalid key in special dictionary"
+#~ msgstr "E116: Ongeldige parameters vir funksie %s"
+
+#, fuzzy
+#~ msgid "encode_tv2string() argument"
+#~ msgstr "Te veel redigeer-parameters"
+
+#, fuzzy
+#~ msgid ":echo argument"
+#~ msgstr " vim [parameters] "
+
+#, fuzzy
+#~ msgid "encode_tv2json() argument"
+#~ msgstr "Te veel redigeer-parameters"
-#. 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 lêer is nie skryfbaar nie: %s"
+#~ msgid "E5004: Error while dumping %s, %s: attempt to dump function reference"
+#~ msgstr ""
-#: ../ex_cmds.c:1626
#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: Kan nie viminfo lêer %s stoor nie!"
+#~ msgid "E5005: Unable to dump %s: container references itself in %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E684: list index out of range: %<PRId64>"
+#~ msgstr "E322: reëlnommer buite perke: %<PRId64> verby die einde"
+
+#~ msgid "E6000: Argument is not a function or function name"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E737: Key already exists: %s"
+#~ msgstr "E227: binding bestaan alreeds vir %s"
+
+#~ msgid "E743: variable nested too deep for (un)lock"
+#~ msgstr ""
-#: ../ex_cmds.c:1635
#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "Besig om viminfo lêer \"%s\" te stoor"
+#~ msgid "E741: Value is locked: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E742: Cannot change value of %.*s"
+#~ msgstr "E284: Kan nie IC waardes stel nie"
+
+msgid "Unknown"
+msgstr "Onbekend"
+
+#~ msgid "E805: Expected a Number or a String, Float found"
+#~ msgstr ""
+
+#~ msgid "E703: Expected a Number or a String, Funcref found"
+#~ msgstr ""
+
+#~ msgid "E745: Expected a Number or a String, List found"
+#~ msgstr ""
+
+#~ msgid "E728: Expected a Number or a String, Dictionary found"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E5300: Expected a Number or a String"
+#~ msgstr "E373: Onverwagte %%%c in formaatstring"
+
+#~ msgid "E745: Using a List as a Number"
+#~ msgstr ""
+
+#~ msgid "E728: Using a Dictionary as a Number"
+#~ msgstr ""
+
+#~ msgid "E805: Using a Float as a Number"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E685: using an invalid value as a Number"
+#~ msgstr "E19: Merker het ongeldige reëlnommer"
+
+#, fuzzy
+#~ msgid "E730: using List as a String"
+#~ msgstr "E374: Ontbrekende ] in formaatstring"
+
+#~ msgid "E731: using Dictionary as a String"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E908: using an invalid value as a String"
+#~ msgstr "E374: Ontbrekende ] in formaatstring"
+
+#~ msgid "E891: Using a Funcref as a Float"
+#~ msgstr ""
+
+#~ msgid "E892: Using a String as a Float"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E893: Using a List as a Float"
+#~ msgstr "E374: Ontbrekende ] in formaatstring"
+
+#, fuzzy
+#~ msgid "E894: Using a Dictionary as a Float"
+#~ msgstr "E242: Ontbrekende kleur: %s"
+
+#~ msgid "E907: Using a special value as a Float"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E808: Number or Float required"
+#~ msgstr "E521: Nommer vereis na ="
+
+#~ msgid "tcp address must be host:port"
+#~ msgstr ""
+
+#~ msgid "failed to lookup host or port"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "connection refused"
+#~ msgstr "'cscope' verbinding gesluit"
-#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# Hierdie viminfo lêer is gegenereer deur Vim %s.\n"
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hex %02x, Oktaal %03o"
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# Jy mag dit wysig as jy versigtig is!\n"
-"\n"
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Hex %04x, Oktaal %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Hex %08x, Oktaal %o"
-#: ../ex_cmds.c:1723
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# Waarde van 'encoding' toe hierdie lêer gestoor is\n"
+msgid "E134: Move lines into themselves"
+msgstr "E134: Skuif reëls in hulself in"
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "Ongeldige beginkarakter"
+msgid "1 line moved"
+msgstr "1 reël geskuif"
+
+#, c-format
+msgid "%<PRId64> lines moved"
+msgstr "%<PRId64> reëls geskuif"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Kan nie lêer %s skep nie"
+
+#, c-format
+msgid "%<PRId64> lines filtered"
+msgstr "%<PRId64> reëls filtreer"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter* Outobevele mag nie die huidige buffer verander nie"
+
+msgid "[No write since last change]\n"
+msgstr "[Ongestoor sedert vorige verandering]\n"
-#: ../ex_cmds.c:2162
msgid "Write partial file?"
msgstr "Skryf gedeeltelike lêer?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: Gebruik ! om gedeeltelike buffer te skryf"
-#: ../ex_cmds.c:2281
#, fuzzy, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "Oorskryf bestaande lêer \"%.*s\"?"
+#~ msgid "Overwrite existing file \"%s\"?"
+#~ msgstr "Oorskryf bestaande lêer \"%.*s\"?"
-#: ../ex_cmds.c:2317
#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr ""
+#~ msgid "Swap file \"%s\" exists, overwrite anyway?"
+#~ msgstr ""
-#: ../ex_cmds.c:2326
#, fuzzy, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E13: Lêer bestaan (gebruik ! om te dwing)"
+#~ msgid "E768: Swap file exists: %s (:silent! overrides)"
+#~ msgstr "E13: Lêer bestaan (gebruik ! om te dwing)"
-#: ../ex_cmds.c:2381
#, c-format
msgid "E141: No file name for buffer %<PRId64>"
msgstr "E141: Geen lêernaam vir buffer %<PRId64> nie"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: Lêer nie gestoor nie: Stoor is afgeskakel deur die 'write' opsie"
-#: ../ex_cmds.c:2434
#, fuzzy, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1227,823 +1330,667 @@ msgstr ""
"'readonly' opsie is aan vir \"%.*s\".\n"
"Wil jy dit forseer?"
-#: ../ex_cmds.c:2439
#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
+#~ msgid ""
+#~ "File permissions of \"%s\" are read-only.\n"
+#~ "It may still be possible to write it.\n"
+#~ "Do you wish to try?"
+#~ msgstr ""
-#: ../ex_cmds.c:2451
#, fuzzy, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "is lees-alleen (gebruik ! om te dwing)"
+#~ msgid "E505: \"%s\" is read-only (add ! to override)"
+#~ msgstr "is lees-alleen (gebruik ! om te dwing)"
-#: ../ex_cmds.c:3120
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: Outobevele het nuwe buffer %s onverwags geskrap"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: nie-numeriese parameter vir :z"
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: Dop bevele nie toegelaat in rvim"
+#, fuzzy
+#~ msgid "E145: Shell commands not allowed in restricted mode"
+#~ msgstr "E145: Dop bevele nie toegelaat in rvim"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: Patrone kan nie deur letters afgebaken word nie"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "vervang met %s (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Onderbreek) "
-#: ../ex_cmds.c:4384
#, fuzzy
-msgid "1 match"
-msgstr "; treffer "
+#~ msgid "1 match"
+#~ msgstr "; treffer "
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 vervanging"
-#: ../ex_cmds.c:4387
#, fuzzy, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> veranderinge"
+#~ msgid "%<PRId64> matches"
+#~ msgstr "%<PRId64> veranderinge"
-#: ../ex_cmds.c:4388
#, c-format
msgid "%<PRId64> substitutions"
msgstr "%<PRId64> vervangings"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " op 1 reël"
-#: ../ex_cmds.c:4395
#, c-format
msgid " on %<PRId64> lines"
msgstr " op %<PRId64> reëls"
-#: ../ex_cmds.c:4438
msgid "E147: Cannot do :global recursive"
msgstr "E147: Kan nie :global rekursief doen nie "
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: Patroon ontbreek uit globaal"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "Patroon gevind in elke reël: %s"
-#: ../ex_cmds.c:4510
#, fuzzy, c-format
-msgid "Pattern not found: %s"
-msgstr "Patroon nie gevind nie"
+#~ msgid "Pattern not found: %s"
+#~ msgstr "Patroon nie gevind nie"
-#: ../ex_cmds.c:4587
-msgid ""
-"\n"
-"# Last Substitute String:\n"
-"$"
-msgstr ""
-"\n"
-"# Vorige Vervangstring:\n"
-"$"
-
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: Bly kalm!"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: Jammer, geen '%s' hulp vir %s nie"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: Jammer, geen hulp vir %s nie"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "Jammer, hulplêer \"%s\" kan nie gevind word nie"
-#: ../ex_cmds.c:5323
-#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Nie 'n gids nie: %s"
+#, fuzzy, c-format
+#~ msgid "E151: No match: %s"
+#~ msgstr "E480: Geen treffer: %s"
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: Kan nie %s oopmaak om te skryf nie"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: Kan nie %s oop maak om te lees nie"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: 'n Mengsel van hulplêer enkoderings in 'n taal: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: Duplikaat etiket \"%s\" in lêer %s/%s"
-#: ../ex_cmds.c:5687
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Nie 'n gids nie: %s"
+
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Onbekende funksie: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Ontbrekende tekennaam"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: Te veel tekens gedefinieer"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Ongeldige tekenteks: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Onbekende opsie: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Ontbrekende tekennommer"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Ongeldige buffernaam: %s"
-#: ../ex_cmds.c:6008
+#~ msgid "E934: Cannot jump to a buffer that does not have a name"
+#~ msgstr ""
+
#, c-format
msgid "E157: Invalid sign ID: %<PRId64>"
msgstr "E157: Ongeldige teken ID: %<PRId64>"
-#: ../ex_cmds.c:6066
+#, c-format
+#~ msgid "E885: Not possible to change sign %s"
+#~ msgstr ""
+
msgid " (not supported)"
msgstr " (word nie ondersteun nie)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[Geskrap]"
-#: ../ex_cmds2.c:139
+#, fuzzy
+#~ msgid "No old files"
+#~ msgstr "Geen ingeslote lêers nie"
+
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "Ontfoutmodus begin nou. Tik \"cont\" om te verlaat."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
msgid "line %<PRId64>: %s"
msgstr "reël %<PRId64>: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "cmd: %s"
-#: ../ex_cmds2.c:322
+#~ msgid "frame is zero"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "frame at highest level: %d"
+#~ msgstr ""
+
#, c-format
msgid "Breakpoint in \"%s%s\" line %<PRId64>"
msgstr "Inspeksiepunt in \"%s%s\" reël %<PRId64>"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Inspeksiepunt kon nie gevind word nie: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Geen inspeksiepunte gedefinieer nie"
-#: ../ex_cmds2.c:617
#, c-format
msgid "%3d %s %s line %<PRId64>"
msgstr "%3d %s %s reël %<PRId64>"
-#: ../ex_cmds2.c:942
-msgid "E750: First use \":profile start {fname}\""
-msgstr ""
+#~ msgid "E750: First use \":profile start {fname}\""
+#~ msgstr ""
-#: ../ex_cmds2.c:1269
#, fuzzy, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "Stoor veranderinge na \"%.*s\"?"
+#~ msgid "Save changes to \"%s\"?"
+#~ msgstr "Stoor veranderinge na \"%.*s\"?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
msgstr "Ongetiteld"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Buffer \"%s\" is nie geskryf sedert vorige wysiging nie"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "Waarskuwing: Ander buffer onverwags betree (kyk na outobevele)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Daar is net een lêer om te bewerk"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: Kan nie vóór die eerste lêer gaan nie"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: Kan nie verby die laaste lêer gaan nie"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: vertaler word nie ondersteun nie: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "Besig om te soek vir \"%s\" in \"%s\""
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "Besig om te soek vir \"%s\""
-#: ../ex_cmds2.c:2307
-#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "kon nie in 'runtimepath' gevind word nie: \"%s\""
+#, fuzzy, c-format
+#~ msgid "not found in '%s': \"%s\""
+#~ msgstr "kon nie in 'runtimepath' gevind word nie: \"%s\""
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "Kan nie gids uitvoer nie: \"%s\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "kon nie \"%s\" uitvoer nie"
-#: ../ex_cmds2.c:2520
#, c-format
msgid "line %<PRId64>: could not source \"%s\""
msgstr "reël %<PRId64>: kon nie \"%s\" uitvoer nie"
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "besig om \"%s\" uit te voer"
-#: ../ex_cmds2.c:2537
#, c-format
msgid "line %<PRId64>: sourcing \"%s\""
msgstr "reël %<PRId64>: voer nou \"%s\" uit"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "%s klaar uitgevoer"
-#: ../ex_cmds2.c:2765
#, fuzzy
-msgid "modeline"
-msgstr "1 reël meer"
+#~ msgid "modeline"
+#~ msgstr "1 reël meer"
-#: ../ex_cmds2.c:2767
#, fuzzy
-msgid "--cmd argument"
-msgstr " vim [parameters] "
+#~ msgid "--cmd argument"
+#~ msgstr " vim [parameters] "
-#: ../ex_cmds2.c:2769
#, fuzzy
-msgid "-c argument"
-msgstr " vim [parameters] "
+#~ msgid "-c argument"
+#~ msgstr " vim [parameters] "
-#: ../ex_cmds2.c:2771
#, fuzzy
-msgid "environment variable"
-msgstr "Stel die 'LANG' omgewingsveranderlike na jou lokaal toe"
+#~ msgid "environment variable"
+#~ msgstr "Stel die 'LANG' omgewingsveranderlike na jou lokaal toe"
-#: ../ex_cmds2.c:2773
#, fuzzy
-msgid "error handler"
-msgstr "Fout en onderbreking"
+#~ msgid "error handler"
+#~ msgstr "Fout en onderbreking"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: Waarskuwing: Verkeerde reëlskeiding, ^M ontbreek dalk"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: ':scriptencoding' buite 'n uitvoerlêer gebruik"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: ':finish' buite 'n uitvoerlêer gebruik"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "Huidige %staal: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Kan nie taal na \"%s\" verander nie"
#. don't redisplay the window
#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "Betree Ex modus. Tik \"visual\" om na Normale modus terug te keer."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: By lêereinde"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Bevel te rekursief"
-#: ../ex_docmd.c:1006
+#, fuzzy
+#~ msgid "line %"
+#~ msgstr "reël %4ld:"
+
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Uitsondering nie gevang nie: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Einde van uitvoerlêer"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Einde van funksie "
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: Dubbelsinnige gebruik van gebruiker-gedefinieerde bevel"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Nie 'n verwerkerbevel nie"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: Terugwaardse omvang gegee"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "Terugwaardse omvang gegee, OK om te ruil"
#. append
#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: Gebruik w of w>>"
-#: ../ex_docmd.c:3454
msgid "E319: The command is not available in this version"
msgstr "E319: Jammer, die bevel is nie geïmplementeer nie"
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: Slegs een lêernaam toegelaat"
-
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
msgstr "Nog 1 lêer om te bewerk. Stop in elk geval?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
msgstr "Nog %d lêers om te bewerk. Stop in elk geval?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
msgstr "E173: Nog 1 lêer om te bewerk"
-#: ../ex_docmd.c:4250
#, c-format
msgid "E173: %<PRId64> more files to edit"
msgstr "E173: Nog %<PRId64> lêers om te bewerk"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: Bevel bestaan alreeds: gebruik ! om te herdefinieer"
-#: ../ex_docmd.c:4432
+#, fuzzy
msgid ""
"\n"
-" Name Args Range Complete Definition"
+" Name Args Address Complete Definition"
msgstr ""
"\n"
" Naam Args Reeks Klaar Definisie"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "Geen gebruiker-gedefinieerde bevele gevind nie"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: Geen eienskappe gespesifiseer nie"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: Ongeldige aantal parameters"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: Telling kan nie twee keer gespesifiseer word nie"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: Ongeldige verstekwaarde vir telling"
-#: ../ex_docmd.c:4625
#, fuzzy
-msgid "E179: argument required for -complete"
-msgstr "E179: parameter nodig vir voltooiing"
+#~ msgid "E179: argument required for -complete"
+#~ msgstr "E179: parameter nodig vir voltooiing"
+
+#, fuzzy
+#~ msgid "E179: argument required for -addr"
+#~ msgstr "E179: parameter nodig vir voltooiing"
-#: ../ex_docmd.c:4635
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Ongeldige eienskap: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Ongeldige bevelnaam"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr "E183: Gebruiker-gedefinieerde bevele moet met 'n hoofletter begin"
-#: ../ex_docmd.c:4696
#, fuzzy
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E464: Dubbelsinnige gebruik van gebruiker-gedefinieerde bevel"
+#~ msgid "E841: Reserved name, cannot be used for user defined command"
+#~ msgstr "E464: Dubbelsinnige gebruik van gebruiker-gedefinieerde bevel"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: Geen gebruiker-gedefinieerde bevel nie: %s"
-#: ../ex_docmd.c:5219
+#, fuzzy, c-format
+#~ msgid "E180: Invalid address type value: %s"
+#~ msgstr "E180: Ongeldige voltooiingswaarde: %s"
+
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: Ongeldige voltooiingswaarde: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr "E468: Voltooiingsargument words slegs toegelaat vir eie voltooiing"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: Eie voltooiing benodig 'n funksie parameter"
-#: ../ex_docmd.c:5257
#, fuzzy, c-format
-msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Kan nie kleurskema %s vind nie"
+#~ msgid "E185: Cannot find color scheme '%s'"
+#~ msgstr "E185: Kan nie kleurskema %s vind nie"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Goeiedag, Vim gebruiker!"
-#: ../ex_docmd.c:5431
#, fuzzy
-msgid "E784: Cannot close last tab page"
-msgstr "E444: Kan nie laaste venster toemaak nie"
+#~ msgid "E784: Cannot close last tab page"
+#~ msgstr "E444: Kan nie laaste venster toemaak nie"
-#: ../ex_docmd.c:5462
#, fuzzy
-msgid "Already only one tab page"
-msgstr "Daar is alreeds slegs een venster"
+#~ msgid "Already only one tab page"
+#~ msgstr "Daar is alreeds slegs een venster"
-#: ../ex_docmd.c:6004
#, fuzzy, c-format
-msgid "Tab page %d"
-msgstr "Bladsy %d"
+#~ msgid "Tab page %d"
+#~ msgstr "Bladsy %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Geen ruillêer"
-#: ../ex_docmd.c:6478
-#, fuzzy
-msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
-msgstr "E509: Kan rugsteunlêer nie skep nie (gebruik ! om te dwing)"
-
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Geen vorige gids nie"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Onbekend"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: ':winsize' benodig twee nommer parameters"
-#: ../ex_docmd.c:6655
-msgid "E188: Obtaining window position not implemented for this platform"
-msgstr ""
-"E188: Verkryging van vensterposisie is nie vir hierdie platform "
-"geïmplementeer nie"
-
-#: ../ex_docmd.c:6662
-msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos benodig twee parameters"
-
-#: ../ex_docmd.c:7241
-#, fuzzy, c-format
-msgid "E739: Cannot create directory: %s"
-msgstr "Kan nie gids uitvoer nie: \"%s\""
-
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" bestaan (gebruik ! om te dwing)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Kan \"%s\" nie oopmaak vir skryf nie"
#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr ""
"E191: Parameter moet 'n letter of 'n terug/vorentoe aanhalingsteken wees"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: Rekursiewe gebruik van ':normal' te diep"
-#: ../ex_docmd.c:7807
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: Geen alternatiewe lêernaam vir '#' nie"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: geen outobevel-lêernaam om \"<afile>\" mee te vervang nie"
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: geen outobevel buffernommer om \"<abuf>\" mee te vervang nie"
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr "E497: geen outobevel treffernaam om \"<amatch>\" mee te vervang nie"
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: geen ':source' lêernaam om \"<sfile>\" mee te vervang nie"
-#: ../ex_docmd.c:7876
#, fuzzy
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: geen ':source' lêernaam om \"<sfile>\" mee te vervang nie"
+#~ msgid "E842: no line number to use for \"<slnum>\""
+#~ msgstr "E498: geen ':source' lêernaam om \"<sfile>\" mee te vervang nie"
-#: ../ex_docmd.c:7903
#, c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr "E499: Leë lêernaam vir '%' of '#', werk slegs met \":p:h\""
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: Evalueer na 'n leë string"
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: Kan 'viminfo' lêer nie oopmaak om te lees nie"
-
-#: ../ex_eval.c:464
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: Kan nie uitsonderings ':throw' met 'Vim' voorvoegsel nie"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Uitsondering gegooi: %s"
-#: ../ex_eval.c:545
+#. always scroll up, don't overwrite
#, c-format
msgid "Exception finished: %s"
msgstr "Uitsondering het klaar gemaak: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Uitsondering weg gegooi: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
msgid "%s, line %<PRId64>"
msgstr "%s, reël %<PRId64>"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Uitsondering gevang: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s is afwagtend gemaak"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s teruggekeer"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s weg gegooi"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Uitsondering"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Fout en onderbreking"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Fout"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Onderbreek"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: geneste ':if' te diep"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: ':endif' sonder ':if'"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: ':else' sonder ':if'"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: ':elseif' sonder ':if'"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: meer as een ':else'"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: ':elseif' na ':else'"
-#: ../ex_eval.c:941
#, fuzzy
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: ':while' te diep genes"
+#~ msgid "E585: :while/:for nesting too deep"
+#~ msgstr "E585: ':while' te diep genes"
-#: ../ex_eval.c:1028
#, fuzzy
-msgid "E586: :continue without :while or :for"
-msgstr "E586: ':continue' sonder ':while'"
+#~ msgid "E586: :continue without :while or :for"
+#~ msgstr "E586: ':continue' sonder ':while'"
-#: ../ex_eval.c:1061
#, fuzzy
-msgid "E587: :break without :while or :for"
-msgstr "E587: ':break' sonder ':while'"
+#~ msgid "E587: :break without :while or :for"
+#~ msgstr "E587: ':break' sonder ':while'"
-#: ../ex_eval.c:1102
#, fuzzy
-msgid "E732: Using :endfor with :while"
-msgstr "E170: Ontbrekende ':endwhile'"
+#~ msgid "E732: Using :endfor with :while"
+#~ msgstr "E170: Ontbrekende ':endwhile'"
-#: ../ex_eval.c:1104
#, fuzzy
-msgid "E733: Using :endwhile with :for"
-msgstr "E170: Ontbrekende ':endwhile'"
+#~ msgid "E733: Using :endwhile with :for"
+#~ msgstr "E170: Ontbrekende ':endwhile'"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: geneste ':try' te diep"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: ':catch' sonder ':try'"
#. Give up for a ":catch" after ":finally" and ignore it.
#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: ':catch' na ':finally'"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: ':finally' sonder ':try'"
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: meer as een ':finally'"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: ':endtry' sonder ':try'"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: ':endfunction' nie in 'n funksie nie"
-#: ../ex_getln.c:1643
#, fuzzy
-msgid "E788: Not allowed to edit another buffer now"
-msgstr "E48: Nie toegelaat in sandput nie"
+#~ msgid "E788: Not allowed to edit another buffer now"
+#~ msgstr "E48: Nie toegelaat in sandput nie"
-#: ../ex_getln.c:1656
#, fuzzy
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E94: Geen buffer wat by %s pas nie"
+#~ msgid "E811: Not allowed to change buffer information now"
+#~ msgstr "E94: Geen buffer wat by %s pas nie"
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "etiketnaam"
+#, c-format
+#~ msgid "E5408: Unable to get g:Nvim_color_cmdline callback: %s"
+#~ msgstr ""
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " tipe lêer\n"
+#, c-format
+#~ msgid "E5409: Unable to get g:Nvim_color_expr callback: %s"
+#~ msgstr ""
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "'history' opsie is nul"
+#, c-format
+#~ msgid "E5407: Callback has thrown an exception: %s"
+#~ msgstr ""
+
+#~ msgid "E5400: Callback should return list"
+#~ msgstr ""
-#: ../ex_getln.c:5046
#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s Geskiedenis (van nuutste na oudste):\n"
+#~ msgid "E5401: List item %i is not a List"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E5402: List item %i has incorrect length: %li /= 3"
+#~ msgstr ""
+
+#~ msgid "E5403: Chunk %i start %"
+#~ msgstr ""
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "Bevelreël"
+#~ msgid "E5405: Chunk %i start %"
+#~ msgstr ""
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "Soekstring"
+#~ msgid "E5404: Chunk %i end %"
+#~ msgstr ""
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "Uitdrukking"
+#~ msgid "E5406: Chunk %i end %"
+#~ msgstr ""
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "Invoer Lyn"
+msgid "tagname"
+msgstr "etiketnaam"
+
+msgid " kind file\n"
+msgstr " tipe lêer\n"
+
+msgid "'history' option is zero"
+msgstr "'history' opsie is nul"
-#: ../ex_getln.c:5117
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: 'cmd_pchar' verby die einde van opdraglengte"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Aktiewe venster of buffer geskrap"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr ""
+#~ msgid "E854: path too long for completion"
+#~ msgstr ""
-#: ../file_search.c:446
#, c-format
msgid ""
"E343: Invalid path: '**[number]' must be at the end of the path or be "
@@ -2052,267 +1999,208 @@ msgstr ""
"E343: Ongeldige pad: '**[nommer]' moet aan die einde van 'n pad wees of "
"gevolg wees deur %s'."
-#: ../file_search.c:1505
#, c-format
msgid "E344: Can't find directory \"%s\" in cdpath"
msgstr "E344: Kan nie gids \"%s\" in 'cdpath' vind nie"
-#: ../file_search.c:1508
#, c-format
msgid "E345: Can't find file \"%s\" in path"
msgstr "E345: Kan lêer \"%s\" nie vind in pad nie"
-#: ../file_search.c:1512
#, c-format
msgid "E346: No more directory \"%s\" found in cdpath"
msgstr "E346: Geen gids \"%s\" meer gevind in 'cdpath' nie"
-#: ../file_search.c:1515
#, c-format
msgid "E347: No more file \"%s\" found in path"
msgstr "E347: Geen lêer \"%s\" meer gevind in pad nie"
-#: ../fileio.c:137
#, fuzzy
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E135: *Filter* Outobevele mag nie die huidige buffer verander nie"
+#~ msgid "E812: Autocommands changed buffer or buffer name"
+#~ msgstr "E135: *Filter* Outobevele mag nie die huidige buffer verander nie"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Ongeldige lêernaam"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "is 'n gids"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "is nie 'n lêer nie"
-#: ../fileio.c:508 ../fileio.c:3522
msgid "[New File]"
msgstr "[Nuwe lêer]"
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr ""
+#~ msgid "[New DIRECTORY]"
+#~ msgstr ""
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr ""
+#. libuv only returns -errno in Unix and in Windows open() does not
+#. set EOVERFLOW
+#~ msgid "[File too big]"
+#~ msgstr ""
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Toestemming Geweier]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: '*ReadPre' outobevele het die lêer onleesbaar gemaak"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: '*ReadPre' outobevele mag nie die huidige buffer verander nie"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: Lees nou vanaf 'stdin'...\n"
-
#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: Omsetting het lêer onleesbaar gemaak!"
#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[fifo/socket]"
#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[fifo]"
#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[socket]"
#. or character special
-#: ../fileio.c:1801
#, fuzzy
-msgid "[character special]"
-msgstr "1 karakter"
+#~ msgid "[character special]"
+#~ msgstr "1 karakter"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR ontbreek]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[lang reëls verdeel]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[NIE omgesit nie]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[omgesit]"
-#: ../fileio.c:1831
#, fuzzy, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[ONWETTIGE GREEP in reël %<PRId64>]"
+#~ msgid "[CONVERSION ERROR in line %<PRId64>]"
+#~ msgstr "[ONWETTIGE GREEP in reël %<PRId64>]"
-#: ../fileio.c:1835
#, c-format
msgid "[ILLEGAL BYTE in line %<PRId64>]"
msgstr "[ONWETTIGE GREEP in reël %<PRId64>]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[LEESFOUTE]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "Kan nie tydelike lêer vir omsetting vind nie"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "Omsetting met 'charconvert' het gefaal"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "kan afvoer van 'charconvert' nie lees nie"
-#: ../fileio.c:2437
#, fuzzy
-msgid "E676: No matching autocommands for acwrite buffer"
-msgstr "Geen passende outobevele nie"
+#~ msgid "E676: No matching autocommands for acwrite buffer"
+#~ msgstr "Geen passende outobevele nie"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: Outobevele het die skryfbuffer geskrap of uitgelaai"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: Outobevel het etlike reëls op onverwagse wyse verander "
-#: ../fileio.c:2548 ../fileio.c:2565
msgid "is not a file or writable device"
msgstr "is nie 'n lêer of 'n skryfbare toestel nie"
-#: ../fileio.c:2601
msgid "is read-only (add ! to override)"
msgstr "is lees-alleen (gebruik ! om te dwing)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr "E506: Kan nie na rugsteunlêer skryf nie (gebruik ! om te dwing)"
-#: ../fileio.c:2898
-msgid "E507: Close error for backup file (add ! to override)"
-msgstr "E507: Sluitfout vir rugsteunlêer (gebruik ! om te dwing)"
+#, fuzzy, c-format
+#~ msgid "E507: Close error for backup file (add ! to override): %s"
+#~ msgstr "E507: Sluitfout vir rugsteunlêer (gebruik ! om te dwing)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr "E508: Kan rugsteunlêer nie lees nie (gebruik ! om te dwing)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: Kan rugsteunlêer nie skep nie (gebruik ! om te dwing)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: Kan rugsteunlêer nie skep nie (gebruik ! om te dwing)"
#. Can't write without a tempfile!
-#: ../fileio.c:3121
msgid "E214: Can't find temp file for writing"
msgstr "E214: Kan nie tydelike lêer vind vir skryf nie"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: Kan nie omsit nie (gebruik ! om te skryf sonder omsetting)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Kan lêer nie oopmaak vir skryf nie"
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: Kan lêer nie oopmaak vir skryf nie"
+#, fuzzy, c-format
+#~ msgid "E212: Can't open file for writing: %s"
+#~ msgstr "E212: Kan lêer nie oopmaak vir skryf nie"
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: 'Fsync' het gefaal"
+#, fuzzy, c-format
+#~ msgid "E667: Fsync failed: %s"
+#~ msgstr "E667: 'Fsync' het gefaal"
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Sluiting gefaal"
+#, fuzzy, c-format
+#~ msgid "E512: Close failed: %s"
+#~ msgstr "E512: Sluiting gefaal"
-#: ../fileio.c:3436
#, fuzzy
-msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: skryffout, omsetting gefaal"
+#~ msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+#~ msgstr "E513: skryffout, omsetting gefaal"
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
+#, fuzzy
+#~ msgid "E513: write error, conversion failed in line %"
+#~ msgstr "E513: skryffout, omsetting gefaal"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: skryffout (lêerstelsel vol?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " OMSETTINGSFOUT"
-#: ../fileio.c:3509
#, fuzzy, c-format
-msgid " in line %<PRId64>;"
-msgstr "reël %<PRId64>"
+#~ msgid " in line %<PRId64>;"
+#~ msgstr "reël %<PRId64>"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Toestel]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Nuut]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " bygevoeg"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " geskryf"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: patchmode: kan oorspronklike lêer nie stoor nie"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: kan leë oorspronglêer nie 'touch' nie"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Kan rugsteunlêer nie verwyder nie"
-#: ../fileio.c:3672
+#. Set highlight for error messages.
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2320,96 +2208,75 @@ msgstr ""
"\n"
"WAARSKUWING: Oorspronklike lêer mag verlore of beskadig wees\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "moenie die verwerker verlaat voor die lêer suksesvol geskryf is nie!"
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[dos formaat]"
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
+msgid "[dos]"
+msgstr "[dos]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[mac formaat]"
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
+msgid "[mac]"
+msgstr "[mac]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[unix formaat]"
-#: ../fileio.c:3831
+msgid "[unix]"
+msgstr "[unix]"
+
msgid "1 line, "
msgstr "1 reël, "
-#: ../fileio.c:3833
#, c-format
msgid "%<PRId64> lines, "
msgstr "%<PRId64> reëls, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 karakter"
-#: ../fileio.c:3838
#, c-format
msgid "%<PRId64> characters"
msgstr "%<PRId64> karakters"
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[Onvoltooide laaste reël]"
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
+msgid "[noeol]"
+msgstr "[noeol]"
+
+#. Don't overwrite messages here.
+#. Must give this prompt.
+#. Don't use emsg() here, don't want to flush the buffers.
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "WAARSKUWING: Die lêer het verander sedert dit gelees is!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "Wil jy regtig soontoe skryf?"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Kan nie skryf na \"%s\""
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Kan \"%s\" nie sluit nie"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Kan \"%s\" nie lees nie"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: 'FileChangedShell' outobevel het buffer verwyder"
-#: ../fileio.c:4894
#, fuzzy, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Waarskuwing: Lêer \"%s\" is nie meer beskikbaar nie"
+#~ msgid "E211: File \"%s\" no longer available"
+#~ msgstr "E211: Waarskuwing: Lêer \"%s\" is nie meer beskikbaar nie"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2418,42 +2285,34 @@ msgstr ""
"W12: Waarskuwing: Lêer \"%s\" het verander sedert bewerking begin het en die "
"buffer in Vim het ook verander"
-#: ../fileio.c:4907
#, fuzzy
-msgid "See \":help W12\" for more info."
-msgstr "Sien \":help W11\" vir meer inligting."
+#~ msgid "See \":help W12\" for more info."
+#~ msgstr "Sien \":help W11\" vir meer inligting."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: Waarskuwing: Lêer \"%s\" het verander sedert bewerking begin het"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "Sien \":help W11\" vir meer inligting."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr ""
"W16: Waarskuwing: Modus van lêer \"%s\" het verander sedert bewerking begin "
"het"
-#: ../fileio.c:4915
#, fuzzy
-msgid "See \":help W16\" for more info."
-msgstr "Sien \":help W11\" vir meer inligting."
+#~ msgid "See \":help W16\" for more info."
+#~ msgstr "Sien \":help W11\" vir meer inligting."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: Waarskuwing: Lêer \"%s\" is geskep sedert bewerking begin het"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Waarskuwing"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2461,157 +2320,135 @@ msgstr ""
"&OK\n"
"&Laai Lêer"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Kon nie voorberei vir herlaai nie \"%s\""
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Kon nie \"%s\" herlaai nie"
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--Geskrap--"
-#: ../fileio.c:5732
#, c-format
-msgid "auto-removing autocommand: %s <buffer=%d>"
-msgstr ""
+#~ msgid "auto-removing autocommand: %s <buffer=%d>"
+#~ msgstr ""
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: Geen sodanige groep nie: \"%s\""
-#: ../fileio.c:5897
+#, fuzzy
+#~ msgid "E936: Cannot delete the current group"
+#~ msgstr "E351: Kan nie vou skrap met huidige 'foldmethod' nie"
+
+#~ msgid "W19: Deleting augroup that is still in use"
+#~ msgstr ""
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: Ongeldige karakter na *: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: Geen sodanige gebeurtenis nie: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: Geen sodanige groep of gebeurtenis nie: %s"
#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Outobevele ---"
-#: ../fileio.c:6293
#, fuzzy, c-format
-msgid "E680: <buffer=%d>: invalid buffer number "
-msgstr "ongeldige buffernommer"
+#~ msgid "E680: <buffer=%d>: invalid buffer number "
+#~ msgstr "ongeldige buffernommer"
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Kan nie outobevele uitvoer vir 'ALL' gebeurtenisse nie"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "Geen passende outobevele nie"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: outobevele te diep genes"
-#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s outobevele vir \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "Voer %s uit"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "outobevel %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: Ontbrekende {."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: Ontbrekende }."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: Geen vou gevind nie"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: Kan nie vou skep met huidige 'foldmethod' nie"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: Kan nie vou skrap met huidige 'foldmethod' nie"
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld reëls gevou "
+#, fuzzy, c-format
+#~ msgid "+--%3ld line folded"
+#~ msgid_plural "+--%3ld lines folded "
+#~ msgstr[0] "+--%3ld reëls gevou "
+#~ msgstr[1] "+--%3ld reëls gevou "
#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: Voeg by leesbuffer"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: rekursiewe binding"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: globale afkorting bestaan alreeds vir %s"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: globale binding bestaan alreeds vir %s"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: afkorting bestaan already vir %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: binding bestaan alreeds vir %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "Geen afkorting gevind nie"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "Geen binding gevind nie"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: Ongeldige modus"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
+#. /< key value of 'cedit' option
+#. /< type of cmdline window or 0
+#. /< result of cmdline window or 0
+#. /< cmdline recursion level
msgid "--No lines in buffer--"
msgstr "--Geen reëls in buffer--"
@@ -2619,696 +2456,566 @@ msgstr "--Geen reëls in buffer--"
#. * The error messages that can be shared are included here.
#. * Excluded are errors that are only used once and debugging messages.
#.
-#: ../globals.h:996
msgid "E470: Command aborted"
msgstr "E470: Bevel gekanselleer"
-#: ../globals.h:997
+#, fuzzy
+#~ msgid "E905: Cannot set this option after startup"
+#~ msgstr "E529: Kan nie 'term' stel na leë string nie"
+
+#, fuzzy
+#~ msgid "E903: Could not spawn API job"
+#~ msgstr "E623: Kon nie 'cscope' proses skep nie"
+
msgid "E471: Argument required"
msgstr "E471: Parameter benodig"
-#: ../globals.h:998
msgid "E10: \\ should be followed by /, ? or &"
msgstr "E10: \\ moet gevolg word deur /, ? of &"
-#: ../globals.h:1000
msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
msgstr "E11: Ongeldig in bevelreël venster: <CR> voer uit, CTRL-C stop"
-#: ../globals.h:1002
msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
msgstr ""
"E12: Bevel uit exrc/vimrc nie toegelaat in huidige gids- of etiketsoektog nie"
-#: ../globals.h:1003
msgid "E171: Missing :endif"
msgstr "E171: Ontbrekende ':endif'"
-#: ../globals.h:1004
msgid "E600: Missing :endtry"
msgstr "E600: Ontbrekende ':endtry'"
-#: ../globals.h:1005
msgid "E170: Missing :endwhile"
msgstr "E170: Ontbrekende ':endwhile'"
-#: ../globals.h:1006
#, fuzzy
-msgid "E170: Missing :endfor"
-msgstr "E171: Ontbrekende ':endif'"
+#~ msgid "E170: Missing :endfor"
+#~ msgstr "E171: Ontbrekende ':endif'"
-#: ../globals.h:1007
msgid "E588: :endwhile without :while"
msgstr "E588: ':endwhile' sonder ':while'"
-#: ../globals.h:1008
#, fuzzy
-msgid "E588: :endfor without :for"
-msgstr "E580: ':endif' sonder ':if'"
+#~ msgid "E588: :endfor without :for"
+#~ msgstr "E580: ':endif' sonder ':if'"
-#: ../globals.h:1009
msgid "E13: File exists (add ! to override)"
msgstr "E13: Lêer bestaan (gebruik ! om te dwing)"
-#: ../globals.h:1010
msgid "E472: Command failed"
msgstr "E472: Bevel het gefaal"
-#: ../globals.h:1011
msgid "E473: Internal error"
msgstr "E473: Interne fout"
-#: ../globals.h:1012
msgid "Interrupted"
msgstr "Onderbreek"
-#: ../globals.h:1013
msgid "E14: Invalid address"
msgstr "E14: Ongeldige adres"
-#: ../globals.h:1014
msgid "E474: Invalid argument"
msgstr "E474: Ongeldige parameter"
-#: ../globals.h:1015
#, c-format
msgid "E475: Invalid argument: %s"
msgstr "E475: Ongeldige parameter: %s"
-#: ../globals.h:1016
#, c-format
msgid "E15: Invalid expression: %s"
msgstr "E15: Ongeldige uitdrukking: %s"
-#: ../globals.h:1017
msgid "E16: Invalid range"
msgstr "E16: Ongeldige omvang"
-#: ../globals.h:1018
msgid "E476: Invalid command"
msgstr "E476: Ongeldige bevel"
-#: ../globals.h:1019
#, c-format
msgid "E17: \"%s\" is a directory"
msgstr "E17: \"%s\" is 'n gids"
-#: ../globals.h:1020
#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Ongeldige rolgrootte"
+#~ msgid "E900: Invalid job id"
+#~ msgstr "E49: Ongeldige rolgrootte"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+#~ msgid "E901: Job table is full"
+#~ msgstr ""
-#: ../globals.h:1022
#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
+#~ msgid "E903: Process failed to start: %s: \"%s\""
+#~ msgstr ""
+
+#~ msgid "E904: Job is not connected to a pty"
+#~ msgstr ""
-#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
msgstr "E364: Biblioteekroep het gefaal vir \"%s\"()"
-#: ../globals.h:1026
+#, fuzzy, c-format
+#~ msgid "E739: Cannot create directory %s: %s"
+#~ msgstr "Kan nie gids uitvoer nie: \"%s\""
+
msgid "E19: Mark has invalid line number"
msgstr "E19: Merker het ongeldige reëlnommer"
-#: ../globals.h:1027
msgid "E20: Mark not set"
msgstr "E20: Merker nie gestel nie"
-#: ../globals.h:1029
msgid "E21: Cannot make changes, 'modifiable' is off"
msgstr "E21: Kan nie wysig nie, 'modifiable' is af"
-#: ../globals.h:1030
msgid "E22: Scripts nested too deep"
msgstr "E22: Skripte te diep ge-nes"
-#: ../globals.h:1031
msgid "E23: No alternate file"
msgstr "E23: Geen alternatiewe lêer nie"
-#: ../globals.h:1032
msgid "E24: No such abbreviation"
msgstr "E24: Afkorting bestaan nie"
-#: ../globals.h:1033
msgid "E477: No ! allowed"
msgstr "E477: Geen ! toegelaat nie"
-#: ../globals.h:1035
msgid "E25: Nvim does not have a built-in GUI"
msgstr "E25: GUI kan nie gebruik word nie: Nie tydens kompilering gekies nie"
-#: ../globals.h:1036
#, c-format
msgid "E28: No such highlight group name: %s"
msgstr "E28: Geen sodanige uitliggroepnaam nie: %s"
-#: ../globals.h:1037
msgid "E29: No inserted text yet"
msgstr "E29: Nog geen ingevoegde teks nie"
-#: ../globals.h:1038
msgid "E30: No previous command line"
msgstr "E30: Geen vorige bevelreël nie"
-#: ../globals.h:1039
msgid "E31: No such mapping"
msgstr "E31: Geen so 'n binding nie"
-#: ../globals.h:1040
msgid "E479: No match"
msgstr "E479: Geen treffer nie"
-#: ../globals.h:1041
#, c-format
msgid "E480: No match: %s"
msgstr "E480: Geen treffer: %s"
-#: ../globals.h:1042
msgid "E32: No file name"
msgstr "E32: Geen lêernaam"
-#: ../globals.h:1044
msgid "E33: No previous substitute regular expression"
msgstr "E33: Geen vorige vervangingspatroon nie"
-#: ../globals.h:1045
msgid "E34: No previous command"
msgstr "E34: Geen vorige bevel nie"
-#: ../globals.h:1046
msgid "E35: No previous regular expression"
msgstr "E35: Geen vorige patroon nie"
-#: ../globals.h:1047
msgid "E481: No range allowed"
msgstr "E481: Geen omvang toegelaat nie"
-#: ../globals.h:1048
msgid "E36: Not enough room"
msgstr "E36: Te min plek"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Kan nie lêer %s skep nie"
-
-#: ../globals.h:1050
msgid "E483: Can't get temp file name"
msgstr "E483: Kan nie tydelike lêernaam kry nie"
-#: ../globals.h:1051
#, c-format
msgid "E484: Can't open file %s"
msgstr "E484: Kan nie lêer %s oopmaak nie"
-#: ../globals.h:1052
#, c-format
msgid "E485: Can't read file %s"
msgstr "E485: Kan nie lêer %s lees nie"
-#: ../globals.h:1054
msgid "E37: No write since last change (add ! to override)"
msgstr "E37: Ongeskryf sedert vorige verandering (gebruik ! om te dwing)"
-#: ../globals.h:1055
#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Ongestoor sedert vorige verandering]\n"
+#~ msgid "E37: No write since last change"
+#~ msgstr "[Ongestoor sedert vorige verandering]\n"
-#: ../globals.h:1056
msgid "E38: Null argument"
msgstr "E38: Nul parameter"
-#: ../globals.h:1057
msgid "E39: Number expected"
msgstr "E39: Nommer verwag"
-#: ../globals.h:1058
#, c-format
msgid "E40: Can't open errorfile %s"
msgstr "E40: Kan nie foutlêer %s oopmaak nie"
-#: ../globals.h:1059
msgid "E41: Out of memory!"
msgstr "E41: Geheue op!"
-#: ../globals.h:1060
msgid "Pattern not found"
msgstr "Patroon nie gevind nie"
-#: ../globals.h:1061
#, c-format
msgid "E486: Pattern not found: %s"
msgstr "E486: Patroon nie gevind nie: %s"
-#: ../globals.h:1062
msgid "E487: Argument must be positive"
msgstr "E487: Parameter moet positief wees"
-#: ../globals.h:1064
msgid "E459: Cannot go back to previous directory"
msgstr "E459: Kan nie terug gaan na die vorige gids nie"
-#: ../globals.h:1066
msgid "E42: No Errors"
msgstr "E42: Geen Foute"
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr ""
+#~ msgid "E776: No location list"
+#~ msgstr ""
-#: ../globals.h:1068
msgid "E43: Damaged match string"
msgstr "E43: Beskadige trefferstring"
-#: ../globals.h:1069
msgid "E44: Corrupted regexp program"
msgstr "E44: Korrupte patroonprogram"
-#: ../globals.h:1071
msgid "E45: 'readonly' option is set (add ! to override)"
msgstr "E45: 'readonly' opsie is aan (gebruik ! om te dwing)"
-#: ../globals.h:1073
-#, fuzzy, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Kan nie lees-alleen veranderlike stel nie \"%s\""
-
-#: ../globals.h:1075
-#, fuzzy, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E46: Kan nie lees-alleen veranderlike stel nie \"%s\""
-
-#: ../globals.h:1076
msgid "E47: Error while reading errorfile"
msgstr "E47: Fout tydens lees van 'errorfile'"
-#: ../globals.h:1078
msgid "E48: Not allowed in sandbox"
msgstr "E48: Nie toegelaat in sandput nie"
-#: ../globals.h:1080
msgid "E523: Not allowed here"
msgstr "E523: Nie hier toegelaat nie"
-#: ../globals.h:1082
msgid "E359: Screen mode setting not supported"
msgstr "E359: Skermmodus instelling nie ondersteun nie"
-#: ../globals.h:1083
msgid "E49: Invalid scroll size"
msgstr "E49: Ongeldige rolgrootte"
-#: ../globals.h:1084
msgid "E91: 'shell' option is empty"
msgstr "E91: 'shell' (dop) opsie is leeg"
-#: ../globals.h:1085
msgid "E255: Couldn't read in sign data!"
msgstr "E255: Fout -- kon nie tekendata lees nie!"
-#: ../globals.h:1086
msgid "E72: Close error on swap file"
msgstr "E72: Sluitfout met ruillêer"
-#: ../globals.h:1087
msgid "E73: tag stack empty"
msgstr "E73: etiketstapel leeg"
-#: ../globals.h:1088
msgid "E74: Command too complex"
msgstr "E74: Bevel te kompleks"
-#: ../globals.h:1089
msgid "E75: Name too long"
msgstr "E75: Naam te lank"
-#: ../globals.h:1090
msgid "E76: Too many ["
msgstr "E76: Te veel ["
-#: ../globals.h:1091
msgid "E77: Too many file names"
msgstr "E77: Te veel lêername"
-#: ../globals.h:1092
msgid "E488: Trailing characters"
msgstr "E488: Oorbodige karakters"
-#: ../globals.h:1093
+#, fuzzy, c-format
+#~ msgid "E488: Trailing characters: %s"
+#~ msgstr "E488: Oorbodige karakters"
+
msgid "E78: Unknown mark"
msgstr "E78: Onbekende merker"
-#: ../globals.h:1094
msgid "E79: Cannot expand wildcards"
msgstr "E79: Kan nie plekhouers uitbrei nie"
-#: ../globals.h:1096
msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
msgstr "E591: 'winheight' kan nie kleiner as 'winminheight' wees nie"
-#: ../globals.h:1098
msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
msgstr "E592: 'winwidth' kan nie kleiner as 'winminwidth' wees nie"
-#: ../globals.h:1099
msgid "E80: Error while writing"
msgstr "E80: Fout tydens skryfoperasie"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Nul telling"
+#, fuzzy
+#~ msgid "E939: Positive count required"
+#~ msgstr "E397: Lêernaam benodig"
-#: ../globals.h:1101
msgid "E81: Using <SID> not in a script context"
msgstr "E81: Gebruik van '<SID>' buite skripkonteks"
-#: ../globals.h:1102
#, fuzzy, c-format
-msgid "E685: Internal error: %s"
-msgstr "E473: Interne fout"
+#~ msgid "E685: Internal error: %s"
+#~ msgstr "E473: Interne fout"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr ""
+#~ msgid "E363: pattern uses more memory than 'maxmempattern'"
+#~ msgstr ""
-#: ../globals.h:1105
#, fuzzy
-msgid "E749: empty buffer"
-msgstr "E279: Nie 'n SNiFF+ buffer nie"
+#~ msgid "E749: empty buffer"
+#~ msgstr "E279: Nie 'n SNiFF+ buffer nie"
+
+#, c-format
+msgid "E86: Buffer %<PRId64> does not exist"
+msgstr "E86: Buffer %<PRId64> bestaan nie"
-#: ../globals.h:1108
#, fuzzy
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E383: Ongeldige soekstring: %s"
+#~ msgid "E682: Invalid search pattern or delimiter"
+#~ msgstr "E383: Ongeldige soekstring: %s"
-#: ../globals.h:1109
msgid "E139: File is loaded in another buffer"
msgstr "E139: Lêer is gelaai in ander buffer"
-#: ../globals.h:1110
#, fuzzy, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E236: Font \"%s\" is nie 'n vaste-wydte font nie"
+#~ msgid "E764: Option '%s' is not set"
+#~ msgstr "E236: Font \"%s\" is nie 'n vaste-wydte font nie"
-#: ../globals.h:1111
#, fuzzy
-msgid "E850: Invalid register name"
-msgstr "E354: Ongeldige registernaam: '%s'"
+#~ msgid "E850: Invalid register name"
+#~ msgstr "E354: Ongeldige registernaam: '%s'"
+
+#, fuzzy, c-format
+#~ msgid "E919: Directory not found in '%s': \"%s\""
+#~ msgstr "E161: Inspeksiepunt kon nie gevind word nie: %s"
+
+msgid "E519: Option not supported"
+msgstr "E519: Opsie is nie ondersteun nie"
+
+#, fuzzy
+#~ msgid "E856: Filename too long"
+#~ msgstr "E75: Naam te lank"
+
+#~ msgid "E806: using Float as a String"
+#~ msgstr ""
-#: ../globals.h:1114
msgid "search hit TOP, continuing at BOTTOM"
msgstr "soektog het BO getref, gaan voort van ONDER af"
-#: ../globals.h:1115
msgid "search hit BOTTOM, continuing at TOP"
msgstr "soektog het ONDER getref, gaan voort van BO af"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: Ontbrekende dubbelpunt"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: Ongeldige komponent"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: syfer verwag"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "Bladsy %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "Geen teks om te druk nie"
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "Druk nou bladsy %d (%d%%)"
+#, fuzzy, c-format
+#~ msgid "Printing page %d (%zu%%)"
+#~ msgstr "Druk nou bladsy %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Kopie %d van %d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Gedruk: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Drukkery gestaak"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: Kan nie na 'PostScript' afvoerlêer skryf nie"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Kan nie lêer \"%s\" oopmaak nie"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Kan nie 'PostScript' hulpbron-lêer \"%s\" lees nie"
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: Lêer \"%s\" is nie 'n 'PostScript' hulpbron-lêer nie"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr ""
"E619: Lêer \"%s\" is nie 'n ondersteunde 'PostScript' hulpbron-lêer nie"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: \"%s\" die hulpbron lêer het die verkeerde weergawe"
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr ""
+#~ msgid "E673: Incompatible multi-byte encoding and character set."
+#~ msgstr ""
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr ""
+#~ msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+#~ msgstr ""
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr ""
+#~ msgid "E675: No default font specified for multi-byte printing."
+#~ msgstr ""
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: Kan nie 'PostScript' afvoerlêer oopmaak nie"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Kan nie lêer %s oopmaak nie"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: Kan nie 'PostScript' hulpbron-lêer \"prolog.ps\" lees nie"
-#: ../hardcopy.c:2593
#, fuzzy
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: Kan nie 'PostScript' hulpbron-lêer \"%s\" vind nie"
+#~ msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+#~ msgstr "E456: Kan nie 'PostScript' hulpbron-lêer \"%s\" vind nie"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: Kan nie 'PostScript' hulpbron-lêer \"%s\" vind nie"
-#: ../hardcopy.c:2654
#, fuzzy, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: Kon nie van wye-greep na \"%s\" enkodering verander nie"
+#~ msgid "E620: Unable to convert to print encoding \"%s\""
+#~ msgstr "E620: Kon nie van wye-greep na \"%s\" enkodering verander nie"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "Besig om te stuur na drukker..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: Kon nie 'PostScript' lêer druk nie"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "Druktaak gestuur."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "Voeg 'n nuwe databasis by"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Soek vir 'n patroon"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "Wys hierdie boodskap"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Sluit 'n verbinding"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Herstel alle verbindings"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Wys verbindings"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: Gebruik: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr ""
"Hierdie 'cscope' bevel ondersteun nie die splitsing van die venster nie.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: Gebruik: 'cstag <ident>'"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: 'cstag': etiket nie gevind nie"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: 'stat(%s)' fout: %d"
-#: ../if_cscope.c:551
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s is nie 'n gids of 'n geldige 'cscope' databasis nie"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "'cscope' databasis %s bygevoeg"
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: 'cscope' verbinding %<PRId64> kon nie gelees word nie"
+#, fuzzy, c-format
+#~ msgid "E262: error reading cscope connection %<PRIu64>"
+#~ msgstr "E262: 'cscope' verbinding %<PRId64> kon nie gelees word nie"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: onbekende 'cscope' soektipe"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Kon nie 'cscope' pype skep nie"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Kon nie vurk vir 'cscope' nie"
-#: ../if_cscope.c:849
#, fuzzy
-msgid "cs_create_connection setpgid failed"
-msgstr "'cs_create_connection' uitvoering het misluk"
+#~ msgid "cs_create_connection setpgid failed"
+#~ msgstr "'cs_create_connection' uitvoering het misluk"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "'cs_create_connection' uitvoering het misluk"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "'cs_create_connection': 'fdopen' vir 'to_fp' het misluk"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "'cs_create_connection': 'fdopen' vir 'fr_fp' het misluk"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: Kon nie 'cscope' proses skep nie"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: geen 'cscope' verbindings nie"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: ongeldige 'cscopequickfix' vlag %c vir %c"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: geen treffers gevind vir 'cscope' versoek %s van %s nie"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "'cscope' bevele:\n"
-#: ../if_cscope.c:1150
#, fuzzy, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %-30s: (Gebruik: %s)"
+#~ msgid "%-5s: %s%*s (Usage: %s)"
+#~ msgstr "%-5s: %-30s: (Gebruik: %s)"
-#: ../if_cscope.c:1155
-msgid ""
-"\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 ""
+#~ 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 ""
-#: ../if_cscope.c:1226
msgid "E568: duplicate cscope database not added"
msgstr "E568: duplikaat 'cscope' databasis nie bygevoeg nie"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: 'cscope' verbinding %s nie gevind nie"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "'cscope' verbinding %s gesluit"
#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: fatale fout in 'cs_manage_matches'"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Cscope etiket: %s"
-#: ../if_cscope.c:1711
+#. Column headers for match number, line number and filename.
msgid ""
"\n"
" # line"
@@ -3316,329 +3023,314 @@ msgstr ""
"\n"
" # reël"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "lêernaam / konteks / reël\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Cscope fout: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Alle 'cscope' databasisse herstel"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "geen 'cscope' verbindings nie\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid databasis naam gidsvoorvoegsel\n"
-#: ../main.c:144
-#, fuzzy
-msgid "Unknown option argument"
-msgstr "Onbekende opsie"
+#, c-format
+#~ msgid "E1502: Lua failed to grow stack to %i"
+#~ msgstr ""
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "Te veel redigeer-parameters"
+#~ msgid ""
+#~ "E5100: Cannot convert given lua table: table should either have a sequence "
+#~ "of positive integer keys or contain only string keys"
+#~ msgstr ""
+
+#~ msgid "E5101: Cannot convert given lua type"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E5102: Lua failed to grow stack to %i"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E5104: Error while creating lua chunk: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5105: Error while calling lua chunk: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5109: Error while creating lua chunk: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5110: Error while creating lua function: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5111: Error while calling lua function: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5112: Error while creating lua chunk: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5113: Error while calling lua chunk: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5106: Error while creating vim module: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
-#: ../main.c:148
+#~ msgid "E970: Failed to initialize lua interpreter"
+#~ msgstr ""
+
+#. stack: vim, error
+#, fuzzy, c-format
+#~ msgid "E5117: Error while updating package paths: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5107: Error while creating lua chunk for luaeval(): %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5108: Error while calling lua chunk for luaeval(): %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, c-format
+#~ msgid "E5114: Error while converting print argument #%i: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E5115: Error while loading debug string: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "E5116: Error while calling debug string: %.*s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+msgid "cannot save undo information"
+msgstr "kan nie herwin-inligting stoor nie"
+
+#. Error messages
msgid "Argument missing after"
msgstr "Parameter ontbreek na"
-#: ../main.c:150
#, fuzzy
-msgid "Garbage after option argument"
-msgstr "Gemors na opsie"
+#~ msgid "Garbage after option argument"
+#~ msgstr "Gemors na opsie"
+
+#, fuzzy
+#~ msgid "Unknown option argument"
+#~ msgstr "Onbekende opsie"
+
+msgid "Too many edit arguments"
+msgstr "Te veel redigeer-parameters"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "Te veel \"+command\", \"-c command\" of \"--cmd command\" parameters"
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "Ongeldige parameter vir"
-
-#: ../main.c:294
-#, c-format
-msgid "%d files to edit\n"
-msgstr "%d lêers om te bewerk\n"
+#, fuzzy, c-format
+#~ msgid "E5421: Failed to open stdin: %s"
+#~ msgstr "E286: Gefaal om invoermetode oop te maak"
-#: ../main.c:1342
msgid "Attempt to open script file again: \""
msgstr "Probeer weer om skriplêer oop te maak: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Kan nie oopmaak om te lees nie: \""
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Kan nie oopmaak vir skrip-afvoer nie: \""
-#: ../main.c:1622
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: Waarskuwing: Afvoer gaan nie na 'n terminaal nie\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim: Waarskuwing: Invoer kom nie vanaf 'n terminaal nie\n"
#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "vóór-'vimrc' bevelreël"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Kan nie lees uit \"%s\" nie"
-#: ../main.c:2149
+#, fuzzy
msgid ""
"\n"
-"More info with: \"vim -h\"\n"
+"More info with \""
msgstr ""
"\n"
"Meer inligting met: \"vim -h\"\n"
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[lêer ..] bewerk lêer(s)"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- lees teks uit 'stdin'"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t tag bewerk lêer waar etiket gedefinieer is"
+#. kill us with CTRL-C here, if you like
+#, fuzzy
+#~ msgid "Usage:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "\n"
+#~ "gebruik:"
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [foutlêer] bewerk lêer met eerste fout"
+#, fuzzy
+#~ msgid " nvim [options] [file ...] Edit file(s)\n"
+#~ msgstr "[lêer ..] bewerk lêer(s)"
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"gebruik:"
+#, fuzzy
+#~ msgid " nvim [options] - Read text from stdin\n"
+#~ msgstr "- lees teks uit 'stdin'"
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [parameters] "
+#, fuzzy
+#~ msgid " nvim [options] -t <tag> Edit file where tag is defined\n"
+#~ msgstr "-t tag bewerk lêer waar etiket gedefinieer is"
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" of:"
+#, fuzzy
+#~ msgid " nvim [options] -q [errorfile] Edit file with first error\n"
+#~ msgstr "-q [foutlêer] bewerk lêer met eerste fout"
-#: ../main.c:2196
+#, fuzzy
msgid ""
"\n"
-"\n"
-"Arguments:\n"
+"Options:\n"
msgstr ""
"\n"
-"\n"
-"Parameters:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tSlegs lêername hierna"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tMoet nie plekhouers uitbrei nie"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tVi modus (soos \"vi\")"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tEx modus (soos \"ex\")"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tStil (bondel) modus (slegs vir \"ex\")"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tDiff modus (soos \"vimdiff\")"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tEasy modus (soos \"evim\", modusloos)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tLeesalleen modus (soos \"view\")"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tBeperkte modus (soos \"rvim\")"
+"--- Opsies ---"
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\tVeranderings (skryf van lêers) nie toegelaat nie"
+#, fuzzy
+#~ msgid " -- Only file names after this\n"
+#~ msgstr "--\t\t\tSlegs lêername hierna"
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tVeranderings aan teks nie toegelaat nie"
+#, fuzzy
+#~ msgid " + Start at end of file\n"
+#~ msgstr " vir twee modusse "
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tBinêre modus"
+#, fuzzy
+#~ msgid " --cmd <cmd> Execute <cmd> before any config\n"
+#~ msgstr "--cmd <bevel>\tVoer <bevel> uit voor enige .vimrc-lêer gelaai word"
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tLisp modus"
+#, fuzzy
+#~ msgid " +<cmd>, -c <cmd> Execute <cmd> after config and first file\n"
+#~ msgstr "-c <bevel>\t\tVoer <bevel> uit na eerste lêer gelaai is"
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tVersoenbaar met Vi: 'compatible'"
+#, fuzzy
+#~ msgid " -b Binary mode\n"
+#~ msgstr " vir twee modusse "
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tNie ten volle Vi-versoenbaar nie: 'nocompatible'"
+#, fuzzy
+#~ msgid " -d Diff mode\n"
+#~ msgstr " vir twee modusse "
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr ""
+#~ msgid " -e, -E Ex mode, Improved Ex mode\n"
+#~ msgstr ""
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tOntfoutmodus"
+#, fuzzy
+#~ msgid " -es Silent (batch) mode\n"
+#~ msgstr " vir twee modusse "
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tGeen ruillêer, gebruik slegs geheue"
+#~ msgid " -h, --help Print this help message\n"
+#~ msgstr ""
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tLys ruillêers en verlaat vim"
+#~ msgid " -i <shada> Use this shada file\n"
+#~ msgstr ""
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (met lêer naam)\tHerwin ineengestorte sessie"
+#, fuzzy
+#~ msgid " -m Modifications (writing files) not allowed\n"
+#~ msgstr "-m\t\t\tVeranderings (skryf van lêers) nie toegelaat nie"
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tSelfde as -r"
+#, fuzzy
+#~ msgid " -M Modifications in text not allowed\n"
+#~ msgstr "-M\t\t\tVeranderings aan teks nie toegelaat nie"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tbegin in Arabiese modus"
+#, fuzzy
+#~ msgid " -n No swap file, use memory only\n"
+#~ msgstr "-n\t\t\tGeen ruillêer, gebruik slegs geheue"
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tBegin in Hebreeuse modus"
+#, fuzzy
+#~ msgid " -o[N] Open N windows (default: one per file)\n"
+#~ msgstr "-o[N]\t\tMaak N vensters oop (verstek: een vir elke lêer)"
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tBegin in Farsi modus"
+#, fuzzy
+msgid ""
+" -O[N] Open N vertical windows (default: one per file)\n"
+msgstr "-o[N]\t\tMaak N vensters oop (verstek: een vir elke lêer)"
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminaal>\tStel terminaaltipe na <terminaal>"
+#, fuzzy
+#~ msgid " -p[N] Open N tab pages (default: one per file)\n"
+#~ msgstr "-o[N]\t\tMaak N vensters oop (verstek: een vir elke lêer)"
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tGebruik <vimrc> in plaas van enige ander .vimrc"
+#~ msgid " -r, -L List swap files\n"
+#~ msgstr ""
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tMoet nie inpropskripte laai nie"
+#~ msgid " -r <file> Recover edit state for this file\n"
+#~ msgstr ""
-#: ../main.c:2227
#, fuzzy
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-o[N]\t\tMaak N vensters oop (verstek: een vir elke lêer)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\tMaak N vensters oop (verstek: een vir elke lêer)"
+#~ msgid " -R Read-only mode\n"
+#~ msgstr " vir twee modusse "
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tSoos -o maar verdeel vertikaal"
+#, fuzzy
+#~ msgid " -S <session> Source <session> after loading the first file\n"
+#~ msgstr ""
+#~ "-S <sessie>\t\tVoer bevele in lêer <sessie> uit na eerste lêer gelaai is"
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tBegin by einde van lêer"
+#, fuzzy
+#~ msgid " -s <scriptin> Read Normal mode commands from <scriptin>\n"
+#~ msgstr "-s <skripin>\t\tLees Normale-modus bevele van lêer <skripin>"
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\tBegin by reël <lnum>"
+#~ msgid " -u <config> Use this config file\n"
+#~ msgstr ""
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <bevel>\tVoer <bevel> uit voor enige .vimrc-lêer gelaai word"
+#, fuzzy
+#~ msgid " -v, --version Print version information\n"
+#~ msgstr "--version\t\tSkryf weergawe-inligting en sluit"
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <bevel>\t\tVoer <bevel> uit na eerste lêer gelaai is"
+#~ msgid " -V[N][file] Verbose [level][file]\n"
+#~ msgstr ""
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr ""
-"-S <sessie>\t\tVoer bevele in lêer <sessie> uit na eerste lêer gelaai is"
+#, fuzzy
+#~ msgid " -Z Restricted mode\n"
+#~ msgstr " vir twee modusse "
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <skripin>\t\tLees Normale-modus bevele van lêer <skripin>"
+#~ msgid " --api-info Write msgpack-encoded API metadata to stdout\n"
+#~ msgstr ""
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <skripuit>\tLas alle getikte bevele aan by lêer <skripuit>"
+#~ msgid " --embed Use stdin/stdout as a msgpack-rpc channel\n"
+#~ msgstr ""
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <skripuit>\tSkryf alle getikte bevele na lêer <skripuit>"
+#~ msgid " --headless Don't start a user interface\n"
+#~ msgstr ""
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr ""
+#, fuzzy
+#~ msgid " --literal Don't expand wildcards\n"
+#~ msgstr "--literal\t\tMoet nie plekhouers uitbrei nie"
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tGebruik <viminfo> in plaas van .viminfo"
+#, fuzzy
+#~ msgid " --noplugin Don't load plugins\n"
+#~ msgstr "--noplugin\t\tMoet nie inpropskripte laai nie"
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h of --help\tSkryf Hulp (hierdie boodskap) en sluit"
+#~ msgid " --startuptime <file> Write startup timing messages to <file>\n"
+#~ msgstr ""
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\tSkryf weergawe-inligting en sluit"
+#~ msgid ""
+#~ "\n"
+#~ "See \":help startup-options\" for all options.\n"
+#~ msgstr ""
-#: ../mark.c:676
msgid "No marks set"
msgstr "Geen merkers gestel nie"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: Geen merkers pas op \"%s\" nie"
#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3647,7 +3339,6 @@ msgstr ""
"merk reël kol lêer/teks"
#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3656,7 +3347,6 @@ msgstr ""
" spring reël kol lêer/teks"
#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3664,110 +3354,63 @@ msgstr ""
"\n"
"verander reël kol teks"
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Lêermerkers:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Springlys (nuutste eerste):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Geskiedenis van merkers in lêers (nuutste tot oudste):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "Ontbrekende '>'"
-
-#: ../memfile.c:426
msgid "E293: block was not locked"
msgstr "E293: blok was nie gesluit nie"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Soekfout in lees van ruillêer"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Leesfout in ruillêer"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Soekfout in skryf van ruillêer"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Skryffout in ruillêer"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: Ruillêer bestaan alreeds! ('symlink' probleem?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Het nie blok no 0 gekry nie?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: Het nie blok no 1 gekry nie?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Het nie blok no 2 gekry nie?"
#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: Hiert, die ruillêer is weg!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Kon nie ruillêer vernoem nie"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: Kon nie ruillêer oopmaak vir \"%s\" nie, herwinning onmoontlik"
-#: ../memline.c:666
#, fuzzy
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: 'ml_timestamp': Het nie blok 0 gekry nie??"
+#~ msgid "E304: ml_upd_block0(): Didn't get block 0??"
+#~ msgstr "E304: 'ml_timestamp': Het nie blok 0 gekry nie??"
#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Geen ruillêer gevind vir %s nie"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Tik die nommer van die ruillêer om te gebruik (0 om te stop)"
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Kan %s nie oopmaak nie"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Kan nie blok 0 lees vanaf "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3775,28 +3418,22 @@ msgstr ""
"\n"
"Vim het die ruillêer nie opgedateer nie. Dalk was niks verander nie."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " kan nie gebruik word met hierdie weergawe van Vim nie.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Gebruik Vim weergawe 3.0.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s lyk nie soos 'n Vim ruillêer nie"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " kan nie gebruik word op hierdie rekenaar nie.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "Die lêer is geskep op "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3804,85 +3441,66 @@ msgstr ""
",\n"
"of die lêer is beskadig."
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr ""
+#~ msgid " has been damaged (page size is smaller than minimum value).\n"
+#~ msgstr ""
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "Gebruik ruillêer \"%s\""
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "Oorspronklike lêer \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: Waarskuwing: Oorspronklike lêer is dalk gewysig"
-#: ../memline.c:1061
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Kan nie block 1 lees van %s"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???BAIE REËLS WEG"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???REËLTELLING FOUTIEF"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???LEË BLOK"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???REËLS WEG"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: Blok 1 se ID is foutief (%s nie 'n .swp lêer nie?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???BLOK WEG"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? van hier tot ???END mag reëls deurmekaar wees"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? van hier tot ???END mag daar reëls ingevoeg/geskrap wees"
-#: ../memline.c:1181
msgid "???END"
msgstr "???END"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: Herwinning onderbreek"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: Foute raakgesien gedurende herwinning; soek vir reëls wat begin met ???"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "Sien \":help E312\" vir meer inligting."
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "Herwinning is klaar. Kyk of alles reg is."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3890,16 +3508,13 @@ msgstr ""
"\n"
"(Jy wil dalk die lêer stoor onder 'n ander naam\n"
-#: ../memline.c:1252
#, fuzzy
-msgid "and run diff with the original file to check for changes)"
-msgstr "en dit \"diff\" teen die oorspronklike lêer om wysigings te soek)\n"
+#~ msgid "and run diff with the original file to check for changes)"
+#~ msgstr "en dit \"diff\" teen die oorspronklike lêer om wysigings te soek)\n"
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr ""
+#~ msgid "Recovery completed. Buffer contents equals file contents."
+#~ msgstr ""
-#: ../memline.c:1255
#, fuzzy
msgid ""
"\n"
@@ -3910,51 +3525,42 @@ msgstr ""
"\n"
#. use msg() to start the scrolling properly
-#: ../memline.c:1327
msgid "Swap files found:"
msgstr "Ruillêers gevind:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " In huidige gids:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " Wat gespesifiseerde naam gebruik:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " In gids "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- geen --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " eienaar: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " gedateer: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " gedateer: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [van Vim weergawe 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [lyk nie soos 'n Vim ruillêer nie]"
-#: ../memline.c:1552
+#~ msgid " [garbled strings (not nul terminated)]"
+#~ msgstr ""
+
msgid " file name: "
msgstr " lêernaam: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3962,15 +3568,12 @@ msgstr ""
"\n"
" gewysig: "
-#: ../memline.c:1559
msgid "YES"
msgstr "JA"
-#: ../memline.c:1559
msgid "no"
msgstr "nee"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3978,11 +3581,9 @@ msgstr ""
"\n"
" gebruikersnaam: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " gasheernaam: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3990,7 +3591,6 @@ msgstr ""
"\n"
" gasheernaam: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3998,11 +3598,9 @@ msgstr ""
"\n"
" proses ID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (nog steeds aan die uitvoer)"
-#: ../memline.c:1586
msgid ""
"\n"
" [not usable on this computer]"
@@ -4010,97 +3608,75 @@ msgstr ""
"\n"
" [nie bruikbaar op hierdie rekenaar nie]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [kan nie gelees word nie]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [kan nie oopgemaak word nie]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: Kan nie bewaar nie, daar is geen ruillêer nie"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "Lêer bewaar"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: Kon nie bewaar nie"
-#: ../memline.c:1819
#, c-format
msgid "E315: ml_get: invalid lnum: %<PRId64>"
msgstr "E315: 'ml_get': ongeldige 'lnum': %<PRId64>"
-#: ../memline.c:1851
#, c-format
msgid "E316: ml_get: cannot find line %<PRId64>"
msgstr "E316: 'ml_get': kan reël %<PRId64> nie vind nie"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: wyser blok id verkeerd 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "'stack_idx' moet 0 wees"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: Te veel blokke opgedateer?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: wyser blok id verkeerd 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "verwyder blok 1?"
-#: ../memline.c:2707
#, c-format
msgid "E320: Cannot find line %<PRId64>"
msgstr "E320: Kan nie reël %<PRId64> vind nie"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: wyser blok id verkeerd"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "'pe_line_count' is nul"
-#: ../memline.c:2955
#, c-format
msgid "E322: line number out of range: %<PRId64> past the end"
msgstr "E322: reëlnommer buite perke: %<PRId64> verby die einde"
-#: ../memline.c:2959
#, c-format
msgid "E323: line count wrong in block %<PRId64>"
msgstr "E323: reëltelling mag verkeerd wees in blok %<PRId64>"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "Stapel grootte verhoog"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: wyser blok id verkeerd 2"
-#: ../memline.c:3070
#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr ""
+#~ msgid "E773: Symlink loop for \"%s\""
+#~ msgstr ""
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: LET OP"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4108,44 +3684,35 @@ msgstr ""
"\n"
"Het 'n ruillêer gevind met die naam \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Tydens oopmaak van lêer \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " NUWER as die ruillêer!\n"
-#: ../memline.c:3244
+#. Some of these messages are long to allow translation to
+#. * other languages.
#, fuzzy
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 Ander program mag besig wees met hierdie lêer.\n"
" Indien wel, pas op om nie met twee verskillende weergawes\n"
" van dieselfde lêer te sit wanneer veranderinge gemaak word nie.\n"
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " Stop, of gaan versigtig voort.\n"
-
-#: ../memline.c:3246
#, fuzzy
-msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) 'n Bewerkingsessie van hierdie lêer het ineengestort.\n"
+#~ msgid "(2) An edit session for this file crashed.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "(2) 'n Bewerkingsessie van hierdie lêer het ineengestort.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " Indien wel, gebruik \":recover\" of \"vim -r"
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4153,11 +3720,9 @@ msgstr ""
"\"\n"
" om die veranderinge te herwin (sien \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " Indien jy dit alreeds gedoen het, verwyder die ruillêer \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4165,23 +3730,15 @@ msgstr ""
"\"\n"
" om hierdie boodskap te vermy.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Ruillêer \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" bestaan alreeds!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - LET OP"
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "Ruillêer bestaan alreeds!"
-
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4195,7 +3752,6 @@ msgstr ""
"&Verlaat\n"
"&Stop"
-#: ../memline.c:3467
#, fuzzy
msgid ""
"&Open Read-Only\n"
@@ -4219,48 +3775,47 @@ msgstr ""
#.
#. ".s?a"
#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: Te veel ruillêers gevind"
-#: ../memory.c:227
+#, fuzzy, c-format
+msgid ""
+"E303: Unable to create directory \"%s\" for swap file, recovery impossible: "
+"%s"
+msgstr "E303: Kon nie ruillêer oopmaak vir \"%s\" nie, herwinning onmoontlik"
+
+#~ msgid "Vim: Data too large to fit into virtual memory space\n"
+#~ msgstr ""
+
#, c-format
msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
msgstr "E342: Geheue is op! (ken %<PRIu64> grepe toe)"
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Deel van kieslys-item pad is nie 'n sub-kieslys nie"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Kieslys bestaan slegs in 'n ander modus"
-#: ../menu.c:64
#, fuzzy, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: Geen kieslys met daardie naam nie"
+#~ msgid "E329: No menu \"%s\""
+#~ msgstr "E329: Geen kieslys met daardie naam nie"
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-msgid "E792: Empty menu name"
-msgstr ""
+#~ msgid "E792: Empty menu name"
+#~ msgstr ""
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Kieslyspad moenie lei na 'n sub-kieslys nie"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: Moenie kieslysitems direk by kieslysstaaf voeg nie"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Verdeler kan nie deel wees van kieslyspad nie"
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4268,74 +3823,49 @@ msgstr ""
"\n"
"--- Kieslyste ---"
-#: ../menu.c:1313
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: Kieslyspad moet lei na 'n kieslysitem"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: Kieslys nie gevind nie: %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
msgstr "E335: Kieslys nie gedefinieer vir %s modus nie"
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: Kieslyspad moet lei na 'n sub-kieslys"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: Kieslys nie gevind nie - maak seker oor die kieslys name"
-
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Fout ontdek tydens verwerking van %s: "
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "reël %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Ongeldige registernaam: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Boodskappe onderhouers: Danie Roux en Jean Jordaan <droux@tuks.co.za>"
-
-#: ../message.c:986
msgid "Interrupt: "
msgstr "Onderbreek: "
-#: ../message.c:988
#, fuzzy
-msgid "Press ENTER or type command to continue"
-msgstr "Druk ENTER of tik 'n bevel om voort te gaan"
+#~ msgid "Press ENTER or type command to continue"
+#~ msgstr "Druk ENTER of tik 'n bevel om voort te gaan"
-#: ../message.c:1843
#, fuzzy, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s, reël %<PRId64>"
+#~ msgid "%s line %<PRId64>"
+#~ msgstr "%s, reël %<PRId64>"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- Meer --"
-#: ../message.c:2398
-msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr ""
+#~ msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+#~ msgstr ""
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Vraag"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4343,7 +3873,6 @@ msgstr ""
"&Ja\n"
"&Nee"
-#: ../message.c:3033
msgid ""
"&Yes\n"
"&No\n"
@@ -4353,7 +3882,6 @@ msgstr ""
"&Nee\n"
"&Kanselleer"
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4367,180 +3895,131 @@ msgstr ""
"&Gooi alles weg\n"
"&Kanselleer"
-#: ../message.c:3058
-#, fuzzy
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E116: Ongeldige parameters vir funksie %s"
-
-#: ../message.c:3119
-msgid "E807: Expected Float argument for printf()"
-msgstr ""
-
-#: ../message.c:3873
-#, fuzzy
-msgid "E767: Too many arguments to printf()"
-msgstr "E118: Te veel parameters vir funksie: %s"
-
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Waarskuwing: Jy wysig aan 'n leesalleen lêer"
-#: ../misc1.c:2537
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr ""
+#~ msgid "Type number and <Enter> or click with mouse (empty cancels): "
+#~ msgstr ""
-#: ../misc1.c:2539
-msgid "Type number and <Enter> (empty cancels): "
-msgstr ""
+#~ msgid "Type number and <Enter> (empty cancels): "
+#~ msgstr ""
-#: ../misc1.c:2585
msgid "1 more line"
msgstr "1 reël meer"
-#: ../misc1.c:2588
msgid "1 line less"
msgstr "1 reël minder"
-#: ../misc1.c:2593
#, c-format
msgid "%<PRId64> more lines"
msgstr "%<PRId64> meer reëls"
-#: ../misc1.c:2596
#, c-format
msgid "%<PRId64> fewer lines"
msgstr "%<PRId64> minder reëls"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Onderbreek)"
-#: ../misc1.c:2635
-msgid "Beep!"
-msgstr ""
+#~ msgid "Beep!"
+#~ msgstr ""
-#: ../misc2.c:738
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "Roep dop om uit te voer: \"%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.
+#.
msgid "E349: No identifier under cursor"
msgstr "E349: Geen identifiseerder onder loper nie"
-#: ../normal.c:1866
#, fuzzy
-msgid "E774: 'operatorfunc' is empty"
-msgstr "E221: 'commentstring' opsie is leeg"
+#~ msgid "E774: 'operatorfunc' is empty"
+#~ msgstr "E221: 'commentstring' opsie is leeg"
-#: ../normal.c:2637
msgid "Warning: terminal cannot highlight"
msgstr "Waarskuwing: terminaal kan nie teks uitlig nie"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Geen string onder loper nie"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: Kan nie voue verwyder met huidige 'foldmethod' nie"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: 'changelist' is leeg"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: By die begin van die veranderingslys"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: By die einde van die veranderingslys"
-#: ../normal.c:7053
msgid "Type :quit<Enter> to exit Nvim"
msgstr "Tik :quit<Enter> om Vim te verlaat"
# Het te doen met < en >
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 reël 1 keer ge-%s"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 reël ge-%s %d keer"
-#: ../ops.c:253
#, c-format
msgid "%<PRId64> lines %sed 1 time"
msgstr "%<PRId64> reëls 1 keer ge-%s"
-#: ../ops.c:256
#, c-format
msgid "%<PRId64> lines %sed %d times"
msgstr "%<PRId64> reëls ge-%s %d keer"
-#: ../ops.c:592
#, c-format
msgid "%<PRId64> lines to indent... "
msgstr "%<PRId64> reëls om in te keep..."
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 reël ingekeep "
-#: ../ops.c:636
#, c-format
msgid "%<PRId64> lines indented "
msgstr "%<PRId64> reëls ingekeep "
-#: ../ops.c:938
#, fuzzy
-msgid "E748: No previously used register"
-msgstr "E186: Geen vorige gids nie"
-
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "kan nie pluk nie: verwyder in elk geval"
+#~ msgid "E748: No previously used register"
+#~ msgstr "E186: Geen vorige gids nie"
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "1 reël verander"
-#: ../ops.c:1931
#, c-format
msgid "%<PRId64> lines changed"
msgstr "%<PRId64> reëls verander"
-#: ../ops.c:2521
#, fuzzy
-msgid "block of 1 line yanked"
-msgstr "1 reël gepluk"
+#~ msgid "block of 1 line yanked"
+#~ msgstr "1 reël gepluk"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "1 reël gepluk"
-#: ../ops.c:2525
#, fuzzy, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "%<PRId64> reëls gepluk"
+#~ msgid "block of %<PRId64> lines yanked"
+#~ msgstr "%<PRId64> reëls gepluk"
-#: ../ops.c:2528
#, c-format
msgid "%<PRId64> lines yanked"
msgstr "%<PRId64> reëls gepluk"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: Niks in register %s nie"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4548,29 +4027,15 @@ msgstr ""
"\n"
"--- Registers ---"
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "Ongeldige registernaam"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# Registers:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: Onbekende registertipe %d"
+#~ msgid ""
+#~ "E883: search pattern and expression register may not contain two or more "
+#~ "lines"
+#~ msgstr ""
-#: ../ops.c:5089
#, c-format
msgid "%<PRId64> Cols; "
msgstr "%<PRId64> Kolomme; "
-#: ../ops.c:5097
#, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
@@ -4579,7 +4044,6 @@ msgstr ""
"%s%<PRId64> van %<PRId64> reëls gekies; %<PRId64> van %<PRId64> Woorde; "
"%<PRId64> van %<PRId64> Grepe"
-#: ../ops.c:5105
#, fuzzy, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
@@ -4589,7 +4053,6 @@ msgstr ""
"%<PRId64> van %<PRId64> Grepe"
# njj: Karakters kan meerdere grepe wees, sien ':h multibyte'
-#: ../ops.c:5123
#, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
@@ -4599,7 +4062,6 @@ msgstr ""
"Greep %<PRId64> van %<PRId64>"
# njj: Karakters kan meerdere grepe wees, sien ':h multibyte'
-#: ../ops.c:5133
#, fuzzy, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
@@ -4608,148 +4070,104 @@ msgstr ""
"Kol %s van %s; Reël %<PRId64> van %<PRId64>; Woord %<PRId64> van %<PRId64>; "
"Greep %<PRId64> van %<PRId64>"
-#: ../ops.c:5146
#, c-format
msgid "(+%<PRId64> for BOM)"
msgstr "(+%<PRId64> vir 'BOM')"
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Bladsy %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "Dankie dat jy vlieg met Vim"
-
#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Onbekende opsie"
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: Opsie is nie ondersteun nie"
-
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: Nie toegelaat in 'n moduslyn nie"
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr ""
+#~ msgid "E846: Key code not set"
+#~ msgstr ""
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: Nommer vereis na ="
-#: ../option.c:3226 ../option.c:3864
-msgid "E522: Not found in termcap"
-msgstr "E522: Nie gevind in 'termcap' nie"
-
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Ongeldige karakter <%s>"
-#: ../option.c:3862
-msgid "E529: Cannot set 'term' to empty string"
-msgstr "E529: Kan nie 'term' stel na leë string nie"
+#, c-format
+#~ msgid "For option %s"
+#~ msgstr ""
-#: ../option.c:3885
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' en 'patchmode' is dieselfde"
-#: ../option.c:3964
-msgid "E834: Conflicts with value of 'listchars'"
-msgstr ""
+#~ msgid "E834: Conflicts with value of 'listchars'"
+#~ msgstr ""
-#: ../option.c:3966
-msgid "E835: Conflicts with value of 'fillchars'"
-msgstr ""
+#~ msgid "E835: Conflicts with value of 'fillchars'"
+#~ msgstr ""
-#: ../option.c:4163
msgid "E524: Missing colon"
msgstr "E524: Ontbrekende dubbelpunt"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Nul-lengte string"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
msgstr "E526: Ontbrekende nommer na <%s>"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Ontbrekende komma"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: Moet 'n ' waarde spesifiseer"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: bevat 'n ondrukbare of wye karakter"
-#: ../option.c:4469
#, c-format
msgid "E535: Illegal character after <%c>"
msgstr "E535: Ongeldige karakter na <%c>"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: komma benodig"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr "E537: 'commentstring' moet leeg wees of %s bevat"
-#: ../option.c:4928
msgid "E540: Unclosed expression sequence"
msgstr "E540: Onvoltooide uitdrukkingreeks"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: te veel items"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
msgstr "E542: ongebalanseerde groepe"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: Daar bestaan reeds 'n voorskouvenster"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr "W17: Arabies benodig UTF-8, doen ':set encoding=utf-8'"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: Benodig ten minste %d reëls"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Benodig ten minste %d kolomme"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Onbekende opsie: %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
+#. is empty. In both cases, we are trying to set a
+#. num option using a string.
#, fuzzy, c-format
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: Nommer vereis na ="
+#~ msgid "E521: Number required: &%s = '%s'"
+#~ msgstr "E521: Nommer vereis na ="
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4757,7 +4175,6 @@ msgstr ""
"\n"
"--- Terminaal kodes ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4765,7 +4182,6 @@ msgstr ""
"\n"
"--- Globale opsie waardes ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4773,7 +4189,6 @@ msgstr ""
"\n"
"--- Lokale opsie waardes ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4781,29 +4196,28 @@ msgstr ""
"\n"
"--- Opsies ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: 'get_varp' FOUT"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': Passende karakter ontbreek vir %s"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap: Ekstra karakters na kommapunt: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Kan nie dop uitvoer nie "
+#, c-format
+#~ msgid "dlerror = \"%s\""
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E5420: Failed to write to file: %s"
+#~ msgstr "E365: Kon nie 'PostScript' lêer druk nie"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Fout met lees van invoer, verlaat...\n"
-#: ../os/shell.c:439
msgid ""
"\n"
"shell returned "
@@ -4811,959 +4225,930 @@ msgstr ""
"\n"
"dop lewer "
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
+#~ msgid ""
+#~ "\n"
+#~ "shell failed to start: "
+#~ msgstr ""
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
+#. Can happen if system() tries to send input to a shell command that was
+#. backgrounded (:call system("cat - &", "foo")). #3529 #5241
+#, fuzzy, c-format
+#~ msgid "E5677: Error writing input to shell-command: %s"
+#~ msgstr "E208: Kan nie skryf na \"%s\""
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr ""
+#~ msgid ""
+#~ "\n"
+#~ "Could not get security context for "
+#~ msgstr ""
+
+#~ msgid ""
+#~ "\n"
+#~ "Could not set security context for "
+#~ msgstr ""
-#: ../path.c:1449
#, c-format
msgid "E447: Can't find file \"%s\" in path"
msgstr "E447: Kan lêer \"%s\" nie vind in pad nie"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: Te veel %%%c in formaatstring"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: Onverwagte %%%c in formaatstring"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: Ontbrekende ] in formaatstring"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: Ongesteunde %%%c in formaatstring"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: Ongeldige %%%c in formaatstringvoorvoegsel"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: Ongeldige %%%c in formaatstring"
#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' bevat geen patroon nie"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: Ontbrekende of leë gidsnaam"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Geen items meer nie"
-#: ../quickfix.c:1674
+#~ msgid "E924: Current window was closed"
+#~ msgstr ""
+
+#~ msgid "E925: Current quickfix was changed"
+#~ msgstr ""
+
+#~ msgid "E926: Current location list was changed"
+#~ msgstr ""
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d van %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (reël verwyder)"
-#: ../quickfix.c:1863
+#, fuzzy, c-format
+#~ msgid "%serror list %d of %d; %d errors "
+#~ msgstr "foutelys %d van %d; %d foute"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: Onder aan 'quickfix' stapel"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: Bo aan 'quickfix' stapel"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "foutelys %d van %d; %d foute"
+#~ msgid "No entries"
+#~ msgstr ""
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: Kan nie skryf nie, 'buftype' opsie is aan"
-#: ../quickfix.c:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr ""
+#~ msgid "E683: File name missing or invalid pattern"
+#~ msgstr ""
-#: ../quickfix.c:2911
#, fuzzy, c-format
-msgid "Cannot open file \"%s\""
-msgstr "Kan nie lêer %s oopmaak nie"
+#~ msgid "Cannot open file \"%s\""
+#~ msgstr "Kan nie lêer %s oopmaak nie"
-#: ../quickfix.c:3429
#, fuzzy
-msgid "E681: Buffer is not loaded"
-msgstr "1 buffer uitgelaai"
+#~ msgid "E681: Buffer is not loaded"
+#~ msgstr "1 buffer uitgelaai"
-#: ../quickfix.c:3487
#, fuzzy
-msgid "E777: String or List expected"
-msgstr "E548: syfer verwag"
+#~ msgid "E777: String or List expected"
+#~ msgstr "E548: syfer verwag"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: ongeldige item in %s%%[]"
-#: ../regexp.c:374
#, fuzzy, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E69: Ontbrekende ] na %s%%["
+#~ msgid "E769: Missing ] after %s["
+#~ msgstr "E69: Ontbrekende ] na %s%%["
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: Onpaar %s%%("
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: Onpaar %s("
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: Onpaar %s)"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: \\z( nie hier toegelaat nie"
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
+msgid "E67: \\z1 - \\z9 not allowed here"
msgstr "E67: \\z1 e.a. nie hier toegelaat nie"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: Ontbrekende ] na %s%%["
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: Leë %s%%[]"
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
msgstr "E339: Patroon te lank"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: Te veel \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: Te veel %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: Onpaar \\z("
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: ongeldige karakter na %s@"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Te veel komplekse %s{...}ies"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61: Geneste %s*"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62: Geneste %s%c"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: ongeldige gebruik van \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64: %s%c volg niks"
-#: ../regexp.c:1902
msgid "E65: Illegal back reference"
msgstr "E65: Ongeldige tru-verwysing"
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: ongeldige karakter na \\z"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, fuzzy, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E71: Ongeldige karakter na %s%%"
+#~ msgid "E678: Invalid character after %s%%[dxouU]"
+#~ msgstr "E71: Ongeldige karakter na %s%%"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: Ongeldige karakter na %s%%"
-#: ../regexp.c:3017
+#, fuzzy, c-format
+#~ msgid "E888: (NFA regexp) cannot repeat %s"
+#~ msgstr "E50: Te veel \\z("
+
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Sintaksfout in %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "Eksterne subtreffers:\n"
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr ""
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-
-#. 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 ""
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
-
-#: ../regexp_nfa.c:2042
-#, fuzzy
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: Te veel \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr ""
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
+#~ msgid ""
+#~ "E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+#~ "used "
+#~ msgstr ""
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
+#~ msgid "Switching to backtracking RE engine for pattern: "
+#~ msgstr ""
-#: ../regexp_nfa.c:6049
-#, fuzzy
-msgid "Could not open temporary log file for writing "
-msgstr "E214: Kan nie tydelike lêer vind vir skryf nie"
+#~ msgid " TERMINAL"
+#~ msgstr ""
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " VVERVANG"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " VERVANG"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " OMKEER"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " INVOEG"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (invoeg)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (vervang)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (vvervang)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " Hebreeus"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " Arabies"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (taal)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (plak)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " VISUELE"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " VISUELE REËL"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " VISUELE BLOK"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " KIES"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " KIES REËL"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " KIES BLOK"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "besig om op te neem"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Ongeldige soekstring: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: soektog het BO getref sonder treffer vir: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: soektog het ONDER getref sonder treffer vir: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: Verwag '?' of '/' na ';'"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (sluit in vorige gelyste treffer)"
#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- Ingeslote lêers"
-#: ../search.c:4106
msgid "not found "
msgstr "nie gevind nie "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "in pad ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Alreeds gelys)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " NIE GEVIND NIE"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "Deursoek ingeslote lêer: %s"
-#: ../search.c:4216
#, fuzzy, c-format
-msgid "Searching included file %s"
-msgstr "Deursoek ingeslote lêer: %s"
+#~ msgid "Searching included file %s"
+#~ msgstr "Deursoek ingeslote lêer: %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: Treffer is op huidige reël"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Alle ingeslote lêers is gevind"
-#: ../search.c:4519
msgid "No included files"
msgstr "Geen ingeslote lêers nie"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: Kon definisie nie vind nie"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: Kon patroon nie vind nie"
-#: ../search.c:4668
-#, fuzzy
-msgid "Substitute "
-msgstr "1 vervanging"
+#~ msgid "too few bytes read"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while skipping in ShaDa file: %s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
-#: ../search.c:4681
#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
+#~ msgid ""
+#~ "Error while reading ShaDa file: last entry specified that it occupies "
+#~ "%<PRIu64> bytes, but file ended earlier"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while closing ShaDa file: %s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "System error while writing ShaDa file: %s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "Reading ShaDa file \"%s\"%s%s%s"
+#~ msgstr "Besig om viminfo lêer \"%s\"%s%s%s te lees"
+
+msgid " info"
+msgstr " inligting"
+
+msgid " marks"
+msgstr " merkers"
-#: ../spell.c:951
#, fuzzy
-msgid "E759: Format error in spell file"
-msgstr "E297: Skryffout in ruillêer"
+#~ msgid " oldfiles"
+#~ msgstr "Geen ingeslote lêers nie"
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr ""
+msgid " FAILED"
+msgstr " GEFAAL"
-#: ../spell.c:953
#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr ""
+#~ msgid "System error while opening ShaDa file %s for reading: %s"
+#~ msgstr ""
+
+#~ msgid "additional elements of ShaDa "
+#~ msgstr ""
+
+#~ msgid "additional data of ShaDa "
+#~ msgstr ""
-#: ../spell.c:954
#, c-format
-msgid "Affix name too long in %s line %d: %s"
-msgstr ""
+#~ msgid "Failed to write variable %s"
+#~ msgstr ""
-#: ../spell.c:955
-#, fuzzy
-msgid "E761: Format error in affix file FOL, LOW or UPP"
-msgstr "E431: Formaatfout in etiketlêer \"%s\""
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file due to a msgpack parser error at position "
+#~ "%<PRIu64>"
+#~ msgstr ""
-#: ../spell.c:957
-msgid "E762: Character in FOL, LOW or UPP is out of range"
-msgstr ""
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file: incomplete msgpack string at position %<PRIu64>"
+#~ msgstr ""
-#: ../spell.c:958
-msgid "Compressing word tree..."
-msgstr ""
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file: extra bytes in msgpack string at position "
+#~ "%<PRIu64>"
+#~ msgstr ""
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr ""
+#, c-format
+#~ msgid ""
+#~ "System error while opening ShaDa file %s for reading to merge before writing "
+#~ "it: %s"
+#~ msgstr ""
-#: ../spell.c:2249
+#. Tried names from .tmp.a to .tmp.z, all failed. Something must be
+#. wrong then.
#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
+#~ msgid "E138: All %s.tmp.X files exist, cannot write ShaDa file!"
+#~ msgstr ""
-#: ../spell.c:2473
#, fuzzy, c-format
-msgid "Reading spell file \"%s\""
-msgstr "Gebruik ruillêer \"%s\""
+#~ msgid "System error while opening temporary ShaDa file %s for writing: %s"
+#~ msgstr "E214: Kan nie tydelike lêer vind vir skryf nie"
-#: ../spell.c:2496
-#, fuzzy
-msgid "E757: This does not look like a spell file"
-msgstr "E307: %s lyk nie soos 'n Vim ruillêer nie"
+#, c-format
+#~ msgid "Failed to create directory %s for writing ShaDa file: %s"
+#~ msgstr ""
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr ""
+#, c-format
+#~ msgid "System error while opening ShaDa file %s for writing: %s"
+#~ msgstr ""
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "Writing ShaDa file \"%s\""
+#~ msgstr "Besig om viminfo lêer \"%s\" te stoor"
-#: ../spell.c:2602
-#, fuzzy
-msgid "E770: Unsupported section in spell file"
-msgstr "E297: Skryffout in ruillêer"
+#, fuzzy, c-format
+#~ msgid "Failed setting uid and gid for file %s: %s"
+#~ msgstr "%s klaar uitgevoer"
-#: ../spell.c:3762
#, fuzzy, c-format
-msgid "Warning: region %s not supported"
-msgstr "E519: Opsie is nie ondersteun nie"
+#~ msgid "E137: ShaDa file is not writable: %s"
+#~ msgstr "E137: Viminfo lêer is nie skryfbaar nie: %s"
+
+#, c-format
+#~ msgid "Can't rename ShaDa file from %s to %s!"
+#~ msgstr ""
-#: ../spell.c:4550
#, fuzzy, c-format
-msgid "Reading affix file %s ..."
-msgstr "Deursoek etiketlêer %s"
+#~ msgid "Did not rename %s because %s does not look like a ShaDa file"
+#~ msgstr " [lyk nie soos 'n Vim ruillêer nie]"
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr ""
+#~ msgid "Did not rename %s to %s because there were errors during writing it"
+#~ msgstr ""
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr ""
+#~ msgid "Do not forget to remove %s or rename it manually to %s."
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while reading ShaDa file: %s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "System error while reading integer from ShaDa file: %s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
-#: ../spell.c:4642
#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr ""
+#~ msgid ""
+#~ "Error while reading ShaDa file: expected positive integer at position "
+#~ "%<PRIu64>, but got nothing"
+#~ msgstr ""
-#: ../spell.c:4655
#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr ""
+#~ msgid ""
+#~ "Error while reading ShaDa file: expected positive integer at position "
+#~ "%<PRIu64>"
+#~ msgstr ""
-#: ../spell.c:4723
#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
+#~ msgid ""
+#~ "Error while reading ShaDa file: there is an item at position %<PRIu64> that "
+#~ "is stated to be too long"
+#~ msgstr ""
-#: ../spell.c:4731
+#. 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.
#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
+#~ 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 ""
-#: ../spell.c:4747
#, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr ""
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry that is not a dictionary"
+#~ msgstr ""
-#: ../spell.c:4771
#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr ""
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry with invalid line number"
+#~ msgstr ""
-#: ../spell.c:4777
#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr ""
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry with invalid column number"
+#~ msgstr ""
-#: ../spell.c:4783
#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr ""
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry that does not have a file name"
+#~ msgstr ""
+
+#. values for ts_isdiff
+#. no different byte (yet)
+#. different byte found
+#. inserting character
+#. values for ts_flags
+#. already checked that prefix is OK
+#. tried split at this point
+#. did a delete, "ts_delidx" has index
+#. special values ts_prefixdepth
+#. not using prefixes
+#. walking through the prefix tree
+#. highest value that's not special
+#. 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
+#, fuzzy
+#~ msgid "E759: Format error in spell file"
+#~ msgstr "E297: Skryffout in ruillêer"
+
+#~ msgid "E756: Spell checking is not enabled"
+#~ msgstr ""
-#: ../spell.c:4795
#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr ""
+#~ msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E797: SpellFileMissing autocommand deleted buffer"
+#~ msgstr "E246: 'FileChangedShell' outobevel het buffer verwyder"
+
+#. This is probably an error. Give a warning and
+#. accept the words anyway.
+#, fuzzy, c-format
+#~ msgid "Warning: region %s not supported"
+#~ msgstr "E519: Opsie is nie ondersteun nie"
+
+#~ msgid "Sorry, no suggestions"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Sorry, only %<PRId64> suggestions"
+#~ msgstr " op %<PRId64> reëls"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, fuzzy, c-format
+#~ msgid "Change \"%.*s\" to:"
+#~ msgstr "Stoor veranderinge na \"%.*s\"?"
-#: ../spell.c:4847
#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr ""
+#~ msgid " < \"%.*s\""
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E752: No previous spell replacement"
+#~ msgstr "E35: Geen vorige patroon nie"
-#: ../spell.c:4850
#, fuzzy, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "E154: Duplikaat etiket \"%s\" in lêer %s/%s"
+#~ msgid "E753: Not found: %s"
+#~ msgstr "E334: Kieslys nie gevind nie: %s"
+
+#~ msgid "E758: Truncated spell file"
+#~ msgstr ""
-#: ../spell.c:4871
#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
+#~ msgid "Trailing text in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:4893
#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr ""
+#~ msgid "Affix name too long in %s line %d: %s"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E761: Format error in affix file FOL, LOW or UPP"
+#~ msgstr "E431: Formaatfout in etiketlêer \"%s\""
+
+#~ msgid "E762: Character in FOL, LOW or UPP is out of range"
+#~ msgstr ""
+
+#~ msgid "Compressing word tree..."
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Reading spell file \"%s\""
+#~ msgstr "Gebruik ruillêer \"%s\""
+
+#, fuzzy
+#~ msgid "E757: This does not look like a spell file"
+#~ msgstr "E307: %s lyk nie soos 'n Vim ruillêer nie"
+
+#, fuzzy, c-format
+#~ msgid "E5042: Failed to read spell file %s: %s"
+#~ msgstr "E482: Kan nie lêer %s skep nie"
+
+#~ msgid "E771: Old spell file, needs to be updated"
+#~ msgstr ""
+
+#~ msgid "E772: Spell file is for newer version of Vim"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E770: Unsupported section in spell file"
+#~ msgstr "E297: Skryffout in ruillêer"
+
+#, fuzzy, c-format
+#~ msgid "E778: This does not look like a .sug file: %s"
+#~ msgstr "E307: %s lyk nie soos 'n Vim ruillêer nie"
-#: ../spell.c:4968
#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr ""
+#~ msgid "E779: Old .sug file, needs to be updated: %s"
+#~ msgstr ""
-#: ../spell.c:5091
#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr ""
+#~ msgid "E780: .sug file is for newer version of Vim: %s"
+#~ msgstr ""
-#: ../spell.c:5120
#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr ""
+#~ msgid "E781: .sug file doesn't match .spl file: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E782: error while reading .sug file: %s"
+#~ msgstr "E47: Fout tydens lees van 'errorfile'"
+
+#, fuzzy, c-format
+#~ msgid "Reading affix file %s ..."
+#~ msgstr "Deursoek etiketlêer %s"
-#: ../spell.c:5132
#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr ""
+#~ msgid "Conversion failure for word in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5176
#, c-format
-msgid "Unrecognized or duplicate item in %s line %d: %s"
-msgstr ""
+#~ msgid "Conversion in %s not supported: from %s to %s"
+#~ msgstr ""
-#: ../spell.c:5197
#, c-format
-msgid "Missing FOL/LOW/UPP line in %s"
-msgstr ""
+#~ msgid "Invalid value for FLAG in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5220
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr ""
+#, c-format
+#~ msgid "FLAG after using flags in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5236
-#, fuzzy
-msgid "Too many postponed prefixes"
-msgstr "Te veel redigeer-parameters"
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
-#: ../spell.c:5238
-#, fuzzy
-msgid "Too many compound flags"
-msgstr "Te veel redigeer-parameters"
+#, c-format
+#~ msgid ""
+#~ "Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+#~ "%d"
+#~ msgstr ""
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr ""
+#, c-format
+#~ msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5250
#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr ""
+#~ msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5253
#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr ""
+#~ msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5331
#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr ""
+#~ msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5334
#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr ""
+#~ msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr ""
+#~ msgid "Different combining flag in continued affix block in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5602
#, fuzzy, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Deursoek woordeboek: %s"
+#~ msgid "Duplicate affix in %s line %d: %s"
+#~ msgstr "E154: Duplikaat etiket \"%s\" in lêer %s/%s"
-#: ../spell.c:5611
#, c-format
-msgid "E760: No word count in %s"
-msgstr ""
+#~ msgid ""
+#~ "Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGESTin %s "
+#~ "line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5669
#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr ""
-
-#: ../spell.c:5691
-#, fuzzy, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "Patroon gevind in elke reël: %s"
+#~ msgid "Expected Y or N in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5694
#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr ""
+#~ msgid "Broken condition in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:5746
#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr ""
+#~ msgid "Expected REP(SAL) count in %s line %d"
+#~ msgstr ""
-#: ../spell.c:5748
#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr ""
+#~ msgid "Expected MAP count in %s line %d"
+#~ msgstr ""
-#: ../spell.c:6115
-#, fuzzy, c-format
-msgid "Reading word file %s ..."
-msgstr "Lees nou vanaf stdin... "
+#, c-format
+#~ msgid "Duplicate character in MAP in %s line %d"
+#~ msgstr ""
-#: ../spell.c:6155
#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr ""
+#~ msgid "Unrecognized or duplicate item in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:6159
#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr ""
+#~ msgid "Missing FOL/LOW/UPP line in %s"
+#~ msgstr ""
+
+#~ msgid "COMPOUNDSYLMAX used without SYLLABLE"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Too many postponed prefixes"
+#~ msgstr "Te veel redigeer-parameters"
+
+#, fuzzy
+#~ msgid "Too many compound flags"
+#~ msgstr "Te veel redigeer-parameters"
+
+#~ msgid "Too many postponed prefixes and/or compound flags"
+#~ msgstr ""
-#: ../spell.c:6180
#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr ""
+#~ msgid "Missing SOFO%s line in %s"
+#~ msgstr ""
-#: ../spell.c:6185
#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr ""
+#~ msgid "Both SAL and SOFO lines in %s"
+#~ msgstr ""
-#: ../spell.c:6198
#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr ""
+#~ msgid "Flag is not a number in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:6224
-#, fuzzy, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "E573: Ongeldige bediener-id gebruik: %s"
+#, c-format
+#~ msgid "Illegal flag in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:6230
#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr ""
+#~ msgid "%s value differs from what is used in another .aff file"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Reading dictionary file %s ..."
+#~ msgstr "Deursoek woordeboek: %s"
-#: ../spell.c:6257
#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr ""
+#~ msgid "E760: No word count in %s"
+#~ msgstr ""
-#: ../spell.c:6656
#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr ""
+#~ msgid "line %6d, word %6d - %s"
+#~ msgstr ""
-#: ../spell.c:7340
-msgid "Reading back spell file..."
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "Duplicate word in %s line %d: %s"
+#~ msgstr "Patroon gevind in elke reël: %s"
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
-msgid "Performing soundfolding..."
-msgstr ""
+#, c-format
+#~ msgid "First duplicate word in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr ""
+#~ msgid "%d duplicate word(s) in %s"
+#~ msgstr ""
-#: ../spell.c:7476
#, c-format
-msgid "Total number of words: %d"
-msgstr ""
+#~ msgid "Ignored %d word(s) with non-ASCII characters in %s"
+#~ msgstr ""
-#: ../spell.c:7655
#, fuzzy, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Besig om viminfo lêer \"%s\" te stoor"
+#~ msgid "Reading word file %s ..."
+#~ msgstr "Lees nou vanaf stdin... "
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr ""
+#~ msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:7820
-msgid "E751: Output file name must not have region name"
-msgstr ""
+#, c-format
+#~ msgid "/encoding= line after word ignored in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:7822
-#, fuzzy
-msgid "E754: Only up to 8 regions supported"
-msgstr "E519: Opsie is nie ondersteun nie"
+#, c-format
+#~ msgid "Duplicate /regions= line ignored in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:7846
-#, fuzzy, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E15: Ongeldige uitdrukking: %s"
+#, c-format
+#~ msgid "Too many regions in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr ""
+#, c-format
+#~ msgid "/ line ignored in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:7920
#, fuzzy, c-format
-msgid "Writing spell file %s ..."
-msgstr "Besig om viminfo lêer \"%s\" te stoor"
+#~ msgid "Invalid region nr in %s line %d: %s"
+#~ msgstr "E573: Ongeldige bediener-id gebruik: %s"
-#: ../spell.c:7925
-msgid "Done!"
-msgstr ""
-
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr ""
+#~ msgid "Unrecognized flags in %s line %d: %s"
+#~ msgstr ""
-#: ../spell.c:8074
#, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr ""
+#~ msgid "Ignored %d words with non-ASCII characters"
+#~ msgstr ""
-#: ../spell.c:8117
#, c-format
-msgid "Word '%.*s' added to %s"
-msgstr ""
+#~ msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+#~ msgstr ""
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr ""
+#~ msgid "Reading back spell file..."
+#~ msgstr ""
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr ""
+#. Go through the trie of good words, soundfold each word and add it to
+#. the soundfold trie.
+#~ msgid "Performing soundfolding..."
+#~ msgstr ""
-#: ../spell.c:8687
-#, fuzzy, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr " op %<PRId64> reëls"
+#, c-format
+#~ msgid "Number of words after soundfolding: %<PRId64>"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Total number of words: %d"
+#~ msgstr ""
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
#, fuzzy, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Stoor veranderinge na \"%.*s\"?"
+#~ msgid "Writing suggestion file %s ..."
+#~ msgstr "Besig om viminfo lêer \"%s\" te stoor"
-#: ../spell.c:8737
#, c-format
-msgid " < \"%.*s\""
-msgstr ""
+#~ msgid "Estimated runtime memory use: %d bytes"
+#~ msgstr ""
+
+#~ msgid "E751: Output file name must not have region name"
+#~ msgstr ""
-#: ../spell.c:8882
#, fuzzy
-msgid "E752: No previous spell replacement"
-msgstr "E35: Geen vorige patroon nie"
+#~ msgid "E754: Only up to 8 regions supported"
+#~ msgstr "E519: Opsie is nie ondersteun nie"
-#: ../spell.c:8925
#, fuzzy, c-format
-msgid "E753: Not found: %s"
-msgstr "E334: Kieslys nie gevind nie: %s"
+#~ msgid "E755: Invalid region in %s"
+#~ msgstr "E15: Ongeldige uitdrukking: %s"
+
+#~ msgid "Warning: both compounding and NOBREAK specified"
+#~ msgstr ""
-#: ../spell.c:9276
#, fuzzy, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E307: %s lyk nie soos 'n Vim ruillêer nie"
+#~ msgid "Writing spell file %s ..."
+#~ msgstr "Besig om viminfo lêer \"%s\" te stoor"
+
+#~ msgid "Done!"
+#~ msgstr ""
-#: ../spell.c:9282
#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr ""
+#~ msgid "E765: 'spellfile' does not have %<PRId64> entries"
+#~ msgstr ""
-#: ../spell.c:9286
#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr ""
+#~ msgid "Word '%.*s' removed from %s"
+#~ msgstr ""
-#: ../spell.c:9295
#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr ""
+#~ msgid "Word '%.*s' added to %s"
+#~ msgstr ""
-#: ../spell.c:9305
-#, fuzzy, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E47: Fout tydens lees van 'errorfile'"
+#~ msgid "E763: Word characters differ between spell files"
+#~ msgstr ""
#. This should have been checked when generating the .spl
#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr ""
+#~ msgid "E783: duplicate char in MAP entry"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E766: Insufficient arguments for printf()"
+#~ msgstr "E116: Ongeldige parameters vir funksie %s"
+
+#~ msgid "E807: Expected Float argument for printf()"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E767: Too many arguments to printf()"
+#~ msgstr "E118: Te veel parameters vir funksie: %s"
-#: ../syntax.c:266
msgid "No Syntax items defined for this buffer"
msgstr "Geen Sintaks-items gedefinieer vir hierdie buffer nie"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
#, c-format
msgid "E390: Illegal argument: %s"
msgstr "E390: Ongeldige parameter: %s"
-#: ../syntax.c:3299
+#~ msgid "syntax iskeyword "
+#~ msgstr ""
+
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Geen sodanige sintakskluster nie: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "sinchroniseer met C-styl kommentaar"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "geen sinchronisering"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "sinchronisasie begin "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " reëls voor boonste lyn"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5771,7 +5156,6 @@ msgstr ""
"\n"
"--- Sintaks sync items ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5779,7 +5163,6 @@ msgstr ""
"\n"
"sinchronisering met items"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5787,275 +5170,216 @@ msgstr ""
"\n"
"--- Sintaks items ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Geen sodanige sintakskluster nie: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimaal "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maksimaal "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; treffer "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " reël breuke"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: bevat parameters nie hier aanvaar nie"
-#: ../syntax.c:4096
#, fuzzy
-msgid "E844: invalid cchar value"
-msgstr "E474: Ongeldige parameter"
+#~ msgid "E844: invalid cchar value"
+#~ msgstr "E474: Ongeldige parameter"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: 'group[t]here' nie hier aanvaar nie"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: Kon nie omgewingsitem vind vir %s nie"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Lêernaam benodig"
-#: ../syntax.c:4221
#, fuzzy
-msgid "E847: Too many syntax includes"
-msgstr "E77: Te veel lêername"
+#~ msgid "E847: Too many syntax includes"
+#~ msgstr "E77: Te veel lêername"
-#: ../syntax.c:4303
#, fuzzy, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E398: Ontbrekende '=': %s"
+#~ msgid "E789: Missing ']': %s"
+#~ msgstr "E398: Ontbrekende '=': %s"
+
+#, fuzzy, c-format
+#~ msgid "E890: trailing char after ']': %s]%s"
+#~ msgstr "E488: Oorbodige karakters"
-#: ../syntax.c:4531
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: Ontbrekende '=': %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Nie genoeg parameters nie: sintaksomgewing %s"
-#: ../syntax.c:4870
#, fuzzy
-msgid "E848: Too many syntax clusters"
-msgstr "E391: Geen sodanige sintakskluster nie: %s"
+#~ msgid "E848: Too many syntax clusters"
+#~ msgstr "E391: Geen sodanige sintakskluster nie: %s"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: Geen kluster gespesifiseer nie"
#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Patroonbegrenser nie gevind nie: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: Gemors na patroon: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: sintaks sync: reëlvoortgaanpatroon twee keer gespesifiseer"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Ongeldige parameters: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: Ontbrekende gelykaanteken: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: Leë parameter: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s nie toegelaat hier nie"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s moet vóór in 'contains' lys wees"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: Onbekende groepnaam: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Ongeldige :syntax subbevel %s"
-#: ../syntax.c:5854
-msgid ""
-" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-msgstr ""
+#~ msgid ""
+#~ " TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+#~ msgstr ""
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: rekursiewe lus gedurende laai van syncolor.vim"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: uitliggroep nie gevind nie: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Te min parameters: \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: Te veel parameters: \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr ""
"E414: groep het instellings, uitligskakel ('highlight link') geïgnoreer"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: onverwagte gelykaanteken: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: ontbrekende gelykaanteken: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: ontbrekende parameter: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Ongeldige waarde: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: FG kleur onbekend"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: BG kleur onbekend"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: Kleurnaam of -nommer nie herken nie: %s"
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: terminaalkode te lank: %s"
-
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Ongeldige parameter: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: Te veel verskillende uitlig-eienskappe in gebruik"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: Onvertoonbare karakter in groepnaam"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: Ongeldige karakter groepnaam"
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr ""
+#~ msgid "E849: Too many highlight and syntax groups"
+#~ msgstr ""
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: onderaan etiketstapel"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: bo-aan etiketstapel"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: Kan nie vóór eerste etiket-treffer gaan nie"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: etiket nie gevind nie: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # pri tipe etiket"
-#: ../tag.c:531
msgid "file\n"
msgstr "lêer\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: Daar is slegs een etiket-treffer"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: Kan nie verby laaste etiket-treffer gaan nie"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "Lêer \"%s\" bestaan nie"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "etiket %d van %d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " of meer"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " Gaan etiket met ander kas gebruik!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Lêer \"%s\" bestaan nie"
#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6063,275 +5387,173 @@ msgstr ""
"\n"
" # NA etiket VAN reël in lêer/teks"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "Deursoek etiketlêer %s"
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr ""
+#~ msgid "Ignoring long line in tags file"
+#~ msgstr ""
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Formaatfout in etiketlêer \"%s\""
-#: ../tag.c:1917
#, c-format
msgid "Before byte %<PRId64>"
msgstr "Voor greep %<PRId64>"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Etiketlêer ongesorteer: %s"
#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: Geen etiketlêer nie"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: Kan nie etiketpatroon vind nie"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: Kon nie etiket vind nie, ek raai maar!"
-#: ../tag.c:2797
#, fuzzy, c-format
-msgid "Duplicate field name: %s"
-msgstr "gelaaide fontnaam: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' onbekend. Beskikbare ingeboude terminale is:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "gebruik verstek '"
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: Kan nie 'termcap'-lêer oopmaak nie"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: Terminaalinskrywing nie in 'terminfo' gevind nie"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: Terminaalinskrywing nie in 'termcap' gevind nie"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: Geen \"%s\" inskrywing in termcap nie"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: terminaalvermoë \"cm\" vereis"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Terminaal sleutels ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: Fout met lees van invoer, verlaat...\n"
+#~ msgid "Duplicate field name: %s"
+#~ msgstr "gelaaide fontnaam: %s"
#. This happens when the FileChangedRO autocommand changes the
#. * file in a way it becomes shorter.
-#: ../undo.c:379
-msgid "E881: Line count changed unexpectedly"
-msgstr ""
+#~ msgid "E881: Line count changed unexpectedly"
+#~ msgstr ""
-#: ../undo.c:627
#, fuzzy, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E212: Kan lêer nie oopmaak vir skryf nie"
+#~ msgid "E828: Cannot open undo file for writing: %s"
+#~ msgstr "E212: Kan lêer nie oopmaak vir skryf nie"
+
+#, fuzzy, c-format
+#~ msgid "E5003: Unable to create directory \"%s\" for undo file: %s"
+#~ msgstr "E346: Geen gids \"%s\" meer gevind in 'cdpath' nie"
-#: ../undo.c:717
#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr ""
+#~ msgid "E825: Corrupted undo file (%s): %s"
+#~ msgstr ""
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr ""
+#~ msgid "Cannot write undo file in any directory in 'undodir'"
+#~ msgstr ""
-#: ../undo.c:1074
#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr ""
+#~ msgid "Will not overwrite with undo file, cannot read: %s"
+#~ msgstr ""
-#: ../undo.c:1092
#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr ""
+#~ msgid "Will not overwrite, this is not an undo file: %s"
+#~ msgstr ""
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr ""
+#~ msgid "Skipping undo file write, nothing to undo"
+#~ msgstr ""
-#: ../undo.c:1121
#, fuzzy, c-format
-msgid "Writing undo file: %s"
-msgstr "Besig om viminfo lêer \"%s\" te stoor"
+#~ msgid "Writing undo file: %s"
+#~ msgstr "Besig om viminfo lêer \"%s\" te stoor"
-#: ../undo.c:1213
#, fuzzy, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E297: Skryffout in ruillêer"
+#~ msgid "E829: write error in undo file: %s"
+#~ msgstr "E297: Skryffout in ruillêer"
-#: ../undo.c:1280
#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr ""
+#~ msgid "Not reading undo file, owner differs: %s"
+#~ msgstr ""
-#: ../undo.c:1292
#, fuzzy, c-format
-msgid "Reading undo file: %s"
-msgstr "Besig om viminfo lêer \"%s\"%s%s%s te lees"
+#~ msgid "Reading undo file: %s"
+#~ msgstr "Besig om viminfo lêer \"%s\"%s%s%s te lees"
-#: ../undo.c:1299
#, fuzzy, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E195: Kan 'viminfo' lêer nie oopmaak om te lees nie"
+#~ msgid "E822: Cannot open undo file for reading: %s"
+#~ msgstr "E195: Kan 'viminfo' lêer nie oopmaak om te lees nie"
-#: ../undo.c:1308
#, fuzzy, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E484: Kan nie lêer %s oopmaak nie"
+#~ msgid "E823: Not an undo file: %s"
+#~ msgstr "E484: Kan nie lêer %s oopmaak nie"
-#: ../undo.c:1313
#, fuzzy, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E484: Kan nie lêer %s oopmaak nie"
+#~ msgid "E824: Incompatible undo file: %s"
+#~ msgstr "E484: Kan nie lêer %s oopmaak nie"
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr ""
+#~ msgid "File contents changed, cannot use undo info"
+#~ msgstr ""
-#: ../undo.c:1497
#, fuzzy, c-format
-msgid "Finished reading undo file %s"
-msgstr "%s klaar uitgevoer"
+#~ msgid "Finished reading undo file %s"
+#~ msgstr "%s klaar uitgevoer"
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr ""
+#~ msgid "Already at oldest change"
+#~ msgstr ""
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr ""
+#~ msgid "Already at newest change"
+#~ msgstr ""
-#: ../undo.c:1806
#, fuzzy, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E92: buffer %<PRId64> kon nie gevind word nie"
+#~ msgid "E830: Undo number %<PRId64> not found"
+#~ msgstr "E92: buffer %<PRId64> kon nie gevind word nie"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: reëlnommers foutief"
-#: ../undo.c:2183
#, fuzzy
-msgid "more line"
-msgstr "1 reël meer"
+#~ msgid "more line"
+#~ msgstr "1 reël meer"
-#: ../undo.c:2185
#, fuzzy
-msgid "more lines"
-msgstr "1 reël meer"
+#~ msgid "more lines"
+#~ msgstr "1 reël meer"
-#: ../undo.c:2187
#, fuzzy
-msgid "line less"
-msgstr "1 reël minder"
+#~ msgid "line less"
+#~ msgstr "1 reël minder"
-#: ../undo.c:2189
#, fuzzy
-msgid "fewer lines"
-msgstr "%<PRId64> minder reëls"
+#~ msgid "fewer lines"
+#~ msgstr "%<PRId64> minder reëls"
-#: ../undo.c:2193
#, fuzzy
-msgid "change"
-msgstr "1 verandering"
+#~ msgid "change"
+#~ msgstr "1 verandering"
-#: ../undo.c:2195
#, fuzzy
-msgid "changes"
-msgstr "1 verandering"
+#~ msgid "changes"
+#~ msgstr "1 verandering"
-#: ../undo.c:2225
#, fuzzy, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64>R, %<PRId64>K"
+#~ msgid "%<PRId64> %s; %s #%<PRId64> %s"
+#~ msgstr "%<PRId64>R, %<PRId64>K"
-#: ../undo.c:2228
-msgid "before"
-msgstr ""
+#~ msgid "after"
+#~ msgstr ""
-#: ../undo.c:2228
-msgid "after"
-msgstr ""
+#~ msgid "before"
+#~ msgstr ""
-#: ../undo.c:2325
#, fuzzy
-msgid "Nothing to undo"
-msgstr "Geen binding gevind nie"
+#~ msgid "Nothing to undo"
+#~ msgstr "Geen binding gevind nie"
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr ""
+#~ msgid "number changes when saved"
+#~ msgstr ""
-#: ../undo.c:2360
#, fuzzy, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> Kolomme; "
+#~ msgid "%<PRId64> seconds ago"
+#~ msgstr "%<PRId64> Kolomme; "
-#: ../undo.c:2372
#, fuzzy
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E407: %s nie toegelaat hier nie"
+#~ msgid "E790: undojoin is not allowed after undo"
+#~ msgstr "E407: %s nie toegelaat hier nie"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: herstellys korrup"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: herstelreël ontbreek"
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Ingeslote laslappies:"
-
-#: ../version.c:627
-#, fuzzy
-msgid ""
-"\n"
-"Extra patches: "
-msgstr "Eksterne subtreffers:\n"
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Gewysig deur "
-
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6339,933 +5561,919 @@ msgstr ""
"\n"
"Gekompileer op "
-#: ../version.c:649
msgid "by "
msgstr "deur "
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"Enorme weergawe "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "sonder GUI."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " Kenmerke in- (+) of uitgesluit (-):\n"
+#~ msgid ""
+#~ "\n"
+#~ "\n"
+#~ "Features: "
+#~ msgstr ""
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " stelsel vimrc-lêer: \""
-#: ../version.c:672
-msgid " user vimrc file: \""
-msgstr " gebruiker vimrc-lêer: \""
-
-#: ../version.c:677
-msgid " 2nd user vimrc file: \""
-msgstr " 2de gebruiker vimrc-lêer \""
-
-#: ../version.c:682
-msgid " 3rd user vimrc file: \""
-msgstr " 3de gebruiker vimrc-lêer \""
-
-#: ../version.c:687
-msgid " user exrc file: \""
-msgstr " gebruiker exrc-lêer: \""
-
-#: ../version.c:692
-msgid " 2nd user exrc file: \""
-msgstr " 2de gebruiker exrc-lêer: \""
-
-#: ../version.c:699
msgid " fall-back for $VIM: \""
msgstr " bystand vir $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " bystand vir $VIMRUNTIME: \""
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "Kompilering: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Koppeling: "
+#, fuzzy
+#~ msgid "Nvim is open source and freely distributable"
+#~ msgstr "Vim is vryekode, en vrylik verspreibaar"
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " ONTFOUTINGS-KOMPILERING"
+#~ msgid "https://neovim.io/community"
+#~ msgstr ""
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi Met skop"
+#, fuzzy
+#~ msgid "type :help nvim<Enter> if you are new! "
+#~ msgstr "tik :help uganda<Enter> as jy hou van Vim "
-# njj: :))
-#: ../version.c:769
-msgid "version "
-msgstr "Weergawe "
+#, fuzzy
+#~ msgid "type :checkhealth<Enter> to optimize Nvim"
+#~ msgstr "Tik :quit<Enter> om Vim te verlaat"
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "deur Bram Moolenaar et al."
+msgid "type :q<Enter> to exit "
+msgstr "tik :q<Enter> om program verlaat "
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim is vryekode, en vrylik verspreibaar"
+#, fuzzy
+#~ msgid "type :help<Enter> for help "
+#~ msgstr "tik :q<Enter> om program verlaat "
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "Help arm kinders in Uganda!"
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "tik :help iccf<Enter> vir meer inligting hieroor "
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr "tik :q<Enter> om program verlaat "
-
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "tik :help<Enter> of <F1> vir aanlyn hulp "
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "tik :help version7<Enter> vir weergawe-inligting"
-
-#: ../version.c:784
-msgid "Running in Vi compatible mode"
-msgstr "Voer tans uit in Vi-versoenbare modus"
-
-#: ../version.c:785
-msgid "type :set nocp<Enter> for Vim defaults"
-msgstr "tik :set nocp<Enter> vir Vim verstekwaardes "
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "tik :help cp-default<Enter> vir meer inligting hieroor"
-
-#: ../version.c:827
msgid "Sponsor Vim development!"
msgstr "Borg Vim ontwikkeling!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Word 'n geregistreerde Vim gebruiker!"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "tik :help sponsor<Enter> vir meer inligting hieroor "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "tik :help register<Enter> vir meer inligting hieroor "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "menu Hulp->Borg/Registreer vir meer inligting"
-#: ../window.c:119
msgid "Already only one window"
msgstr "Daar is alreeds slegs een venster"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Daar is nie 'n voorskou-venster nie"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: Kan nie bo-links en onder-regs terselfdertyd verdeel nie"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: Kan nie roteer terwyl 'n ander venster verdeel is nie"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: Kan nie laaste venster toemaak nie"
-#: ../window.c:1810
#, fuzzy
-msgid "E813: Cannot close autocmd window"
-msgstr "E444: Kan nie laaste venster toemaak nie"
+#~ msgid "E813: Cannot close autocmd window"
+#~ msgstr "E444: Kan nie laaste venster toemaak nie"
-#: ../window.c:1814
#, fuzzy
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E444: Kan nie laaste venster toemaak nie"
+#~ msgid "E814: Cannot close window, only autocmd window would remain"
+#~ msgstr "E444: Kan nie laaste venster toemaak nie"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: Die ander venster bevat veranderinge"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: Geen lêernaam onder loper"
-#~ msgid "[Error List]"
-#~ msgstr "[Foutlys]"
-
-#~ msgid "[No File]"
-#~ msgstr "[Geen lêer]"
+#, c-format
+#~ msgid "E799: Invalid ID: %<PRId64> (must be greater than or equal to 1)"
+#~ msgstr ""
-#~ msgid "Patch file"
-#~ msgstr "Laslap lêer"
+#, fuzzy, c-format
+#~ msgid "E801: ID already taken: %<PRId64>"
+#~ msgstr "E157: Ongeldige teken ID: %<PRId64>"
-#~ msgid "E106: Unknown variable: \"%s\""
-#~ msgstr "E106: Onbekende veranderlike: \"%s\""
+#, fuzzy
+#~ msgid "List or number required"
+#~ msgstr "E471: Parameter benodig"
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
+#, c-format
+#~ msgid "E802: Invalid ID: %<PRId64> (must be greater than or equal to 1)"
#~ msgstr ""
-#~ "&OK\n"
-#~ "&Kanselleer"
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Geen verbinding met Vim bediener"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Kon bediener-terugvoer nie lees nie"
+#, fuzzy, c-format
+#~ msgid "E803: ID not found: %<PRId64>"
+#~ msgstr "E320: Kan nie reël %<PRId64> vind nie"
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Kan nie na %s stuur nie"
+#~ msgid "WARNING: tag command changed a buffer!!!"
+#~ msgstr "WAARSKUWING: etiketbevel het buffer verander!!!"
-#~ msgid "E130: Undefined function: %s"
-#~ msgstr "E130: Ongedefinieerde funksie: %s"
+#~ msgid "Leave: %s"
+#~ msgstr "Verlaat: %s"
-#~ msgid "Save As"
-#~ msgstr "Stoor As"
+#~ msgid "File name '%s' is valid"
+#~ msgstr "lêernaam '%s is ongeldig"
-#~ msgid "Source Vim script"
-#~ msgstr "Voer Vim skrip uit"
+#~ msgid "Not a proper file name: '%s'"
+#~ msgstr "Nie 'n geldige lêernaam nie: '%s'"
-#~ msgid "Edit File"
-#~ msgstr "Verander lêer"
+#~ msgid "Change dir debugging enabled."
+#~ msgstr "Verandergids ontfouting in staat gestel"
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (NIE GEVIND NIE)"
+#~ msgid "Warning: %s option changed from modeline"
+#~ msgstr "Waarskuwing: %s opsie verander vanaf moduslyn"
-#~ msgid "Edit File in new window"
-#~ msgstr "Bewerk lêer in nuwe venster"
+#~ msgid "Security error: shell command output is a symbolic link"
+#~ msgstr "Sekuriteitsfout: Dop-bevel afvoer is 'n simboliese skakel"
-#~ msgid "Append File"
-#~ msgstr "Las aan by lêer"
+#~ msgid "No fold at this line"
+#~ msgstr "Geen vou by hierdie reël nie"
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Vensterposisie: X %d, Y %d"
+#~ msgid "Fold must be at least two lines"
+#~ msgstr "'n Vou moet ten minste 2 reëls wees"
-#~ msgid "Save Redirection"
-#~ msgstr "Stoor Herversturing"
+#~ msgid "Security error: filter input is a symbolic link: %s"
+#~ msgstr "Sekuriteitsfout: filter invoer is 'n simboliese skakel"
-#~ msgid "Save View"
-#~ msgstr "Stoor Oorsig"
+#~ msgid "Security error: 'charconvert' output is a symbolic link"
+#~ msgstr "Sekuriteitsfout: 'charconvert' afvoer is 'n simboliese skakel"
-#~ msgid "Save Session"
-#~ msgstr "Stoor Sessie"
+#~ msgid "Security error: filter output is a symbolic link: %s"
+#~ msgstr "Sekuriteitsfout: filter afvoer is 'n simboliese skakel"
-#~ msgid "Save Setup"
-#~ msgstr "Stoor konfigurasie"
+#~ msgid "makeef option not set"
+#~ msgstr "'makeef' opsie nie aan nie"
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Geen digrawe in hierdie weergawe nie"
+#~ msgid "line ~%<PRId64>: %s"
+#~ msgstr "reël ~%<PRId64>: %s"
-#~ msgid "[NL found]"
-#~ msgstr "[NL gevind]"
+#~ msgid "Security error: new viminfo file is a symbolic link"
+#~ msgstr "Sekuriteitsfout: nuwe viminfo lêer is a simboliese skakel"
-#~ msgid "[crypted]"
-#~ msgstr "[gekodeer]"
+#~ msgid " PPC has a much better architecture. "
+#~ msgstr " PPC het 'n veel beter argitektuur. "
-#~ msgid "[CONVERSION ERROR]"
-#~ msgstr "[OMSETTINGSFOUT]"
+#~ msgid " WARNING: Intel CPU detected. "
+#~ msgstr " WAARSKUWING: Intel SVE bespeur. "
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans laat nie skryf toe van onveranderde buffers nie"
+#~ msgid "Unexpected magic character; check META."
+#~ msgstr "Onverwagte toorkarakter; kyk na META."
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Gedeeltelike skryf word nie toegelaat vir NetBeans buffers nie"
+#~ msgid "\\* follows nothing"
+#~ msgstr "\\* volg niks"
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Die hulpbronvurk sal verlore gaan (gebruik ! om te dwing)"
+#~ msgid "\\{ follows nothing"
+#~ msgstr "\\{ volg niks"
-#~ msgid "<cannot open> "
-#~ msgstr "<kan nie oopmaak nie> "
+#~ msgid "\\@ follows nothing"
+#~ msgstr "\\@ volg niks"
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: 'vim_SelFile': kan font %s nie kry nie"
+#~ msgid "\\+ follows nothing"
+#~ msgstr "\\+ volg niks"
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: 'vim_SelFile': Kan nie terugkeer na huidige gids nie"
+#~ msgid "\\= follows nothing"
+#~ msgstr "\\= volg niks"
-#~ msgid "Pathname:"
-#~ msgstr "Gidsnaam:"
+#~ msgid "Nested *, \\=, \\+, \\! or \\{"
+#~ msgstr "Geneste *, \\=, \\+, \\! of \\{"
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: Kan nie huidige gids verkry nie"
+#~ msgid "Unmatched \\("
+#~ msgstr "Onpaar \\("
-#~ msgid "OK"
-#~ msgstr "OK"
+#~ msgid "Too many \\("
+#~ msgstr "Te veel \\("
-#~ msgid "Cancel"
-#~ msgstr "Kanselleer"
+#~ msgid "Ambiguous mapping, conflicts with \"%s\""
+#~ msgstr "Dubbelsinnige binding, bots met \"%s\""
-#~ msgid "Vim dialog"
-#~ msgstr "Vim dialooghokkie"
+#~ msgid "Ambiguous mapping"
+#~ msgstr "Dubbelsinnige binding"
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Rolstaafelement: Kon nie pikselmatriks-duimnael se geometrie kry nie"
+#~ msgid "Command too long"
+#~ msgstr "Bevel te lank"
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Kan nie BalloonEval skep met beide boodskap en terugroep nie"
+#~ msgid "GUI is not running"
+#~ msgstr "GUI voer nie uit nie"
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Kan nie die GUI begin nie"
+#~ msgid "Cannot clear all highlight groups"
+#~ msgstr "Kan nie alle uitliggroepe leegmaak nie"
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Kan nie lees uit \"%s\" nie"
+#~ msgid "Library call failed"
+#~ msgstr "Biblioteekfunksieroep het gefaal"
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Kan nie GUI begin nie, geen geldige font gevind nie"
+#~ msgid "some"
+#~ msgstr "sommige"
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' ongeldig"
+#~ msgid "deadly signal"
+#~ msgstr "dodelike sein"
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Waarde van 'imactivatekey' is ongeldig"
+#~ msgid "Unsupported screen mode"
+#~ msgstr "Ongesteunde skermmodus"
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Kan nie kleur %s toeken nie"
+#~ msgid "PC (16 bits Vim)"
+#~ msgstr "PC (16 bisse Vim)"
-#~ msgid "Vim dialog..."
-#~ msgstr "Vim dialooghokkie..."
+#~ msgid "PC (32 bits Vim)"
+#~ msgstr "PC (32 bisse Vim)"
-#~ msgid "Input _Methods"
-#~ msgstr "Invoer _Metodes"
+#~ msgid "Out of memory"
+#~ msgstr "Geheue op"
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Soek en Vervang..."
+#~ msgid "Sorry, deleting a menu is not possible in the Athena version"
+#~ msgstr ""
+#~ "Jammer, in die Athena weergawe is dit onmoontlik om 'n kieslys te skrap"
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Soek..."
+#~ msgid "Can't create input context."
+#~ msgstr "Kan nie invoerkonteks skep nie."
-#~ msgid "Find what:"
-#~ msgstr "Soek na:"
+#~ msgid "Unrecognized sniff request [%s]"
+#~ msgstr "Onbekende sniff versoek [%s]"
-#~ msgid "Replace with:"
-#~ msgstr "Vervang met:"
+#~ msgid "-- SNiFF+ commands --"
+#~ msgstr "-- SNiFF+ bevele --"
-#~ msgid "Match whole word only"
-#~ msgstr "Tref slegs presiese woord"
+#~ msgid "Retrieve next symbol"
+#~ msgstr "Kry volgende simbool"
-#~ msgid "Match case"
-#~ msgstr "Tref kas"
+#~ msgid "cs_add_common: alloc fail #4"
+#~ msgstr "'cs_add_common': toeken onsuksesvol #4"
-#~ msgid "Direction"
-#~ msgstr "Rigting"
+#~ msgid "cs_add_common: alloc fail #3"
+#~ msgstr "'cs_add_common': toeken onsuksesvol #3"
-#~ msgid "Up"
-#~ msgstr "Op"
+#~ msgid "cs_add_common: alloc fail #2"
+#~ msgstr "'cs_add_common': toeken onsuksesvol #2"
-#~ msgid "Down"
-#~ msgstr "Af"
+#~ msgid "cs_add_common: alloc fail #1"
+#~ msgstr "'cs_add_common': toeken onsuksesvol #1"
-#~ msgid "Find Next"
-#~ msgstr "Vind volgende"
+#~ msgid "automata ERROR: internal"
+#~ msgstr "automata FOUT: intern"
-#~ msgid "Replace"
-#~ msgstr "Vervang"
+#~ msgid "Your language Font missing"
+#~ msgstr "Jou taal Font ontbreek"
-#~ msgid "Replace All"
-#~ msgstr "Vervang alles"
+#~ msgid "fontset name: %s"
+#~ msgstr "fontstel naam: %s"
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: Het die \"die\" opdrag ontvang van sessiebestuurder\n"
+#~ msgid " sh : export LANG=ko"
+#~ msgstr " sh: export LANG=af"
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Hoofvenster onverwags verwoes\n"
+#~ msgid " csh: setenv LANG ko"
+#~ msgstr " csh: setenv LANG af"
-#~ msgid "Font Selection"
-#~ msgstr "Fontkeuse"
+#~ msgid "For korean:"
+#~ msgstr "Vir Afrikaans:"
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "'CUT_BUFFER0' is gebruik in plaas van leë seleksie"
+#~ msgid "locale is not set correctly"
+#~ msgstr "lokaal is nie korrek gestel nie"
-#~ msgid "Filter"
-#~ msgstr "Filter"
+#~ msgid "Error: During loading fontset %s"
+#~ msgstr "Fout: Gedurende die laai van fontstel %s"
-#~ msgid "Directories"
-#~ msgstr "Gidse"
+#~ msgid "Topic:"
+#~ msgstr "Onderwerp:"
-#~ msgid "Help"
-#~ msgstr "Hulp"
+#~ msgid "VIM - Help on..."
+#~ msgstr "VIM - Hulp met.."
-#~ msgid "Files"
-#~ msgstr "Lêers"
+#~ msgid "Cannot use :normal from event handler"
+#~ msgstr "Kan ':normal' nie vanuit gebeurtenishanteerder gebruik nie"
-#~ msgid "Selection"
-#~ msgstr "Seleksie"
+#~ msgid "Invalid line number: %<PRId64>"
+#~ msgstr "Ongeldige reëlnommer: %<PRId64>"
-#~ msgid "Undo"
-#~ msgstr "Herroep"
+#~ msgid "Missing filename"
+#~ msgstr "Ontbrekende lêernaam"
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Kan nie venster titel vind nie \"%s\""
+#~ msgid "No servers found for this display"
+#~ msgstr "Geen bedieners gevind vir die 'display' nie"
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Parameter nie bekend: \"-%s\"; Gebruik die OLE weergawe."
+#~ msgid "E258: no matches found in cscope connections"
+#~ msgstr "E258: geen treffers gevind in 'cscope' verbindings nie"
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Kon nie venster oopmaak binne 'n MDI toepassing nie"
+#~ msgid "Binary tag search"
+#~ msgstr "Binêre etiketsoek"
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Vind string (gebruik '\\\\' om 'n '\\' te vind"
+#~ msgid "Linear tag search"
+#~ msgstr "Liniêre etiketsoek"
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Vind & vervang string (gebruik '\\\\' om 'n '\\' te vind"
+#~ msgid " LINE"
+#~ msgstr " REËL"
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Kan nie kleurkaart-inskrywing toeken nie, sommige kleure mag "
-#~ "verkeerd wees"
+#~ msgid " BLOCK"
+#~ msgstr " BLOK"
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr ""
-#~ "E250: Fonte vir die volgende karakterstelle ontbreek in fontversameling "
-#~ "%s:"
+#~ msgid "%<PRId64> lines ~ed"
+#~ msgstr "%<PRId64> reëls ge-~"
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Fontstel naam: %s"
+#~ msgid "1 line ~ed"
+#~ msgstr "1 reël ge-~"
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Font '%s' is nie 'n vaste-wydte font nie"
+#~ msgid "--help\t\tShow Gnome arguments"
+#~ msgstr "--help\t\tWys Gnome parameters"
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Fonstel naam: %s\n"
+#~ msgid "\"\n"
+#~ msgstr "\"\n"
-#~ msgid "Font0: %s\n"
-#~ msgstr "Font0: %s\n"
+#~ msgid "E249: couldn't read VIM instance registry property"
+#~ msgstr "E249: kon nie VIM instansie register-kenmerk lees nie"
-#~ msgid "Font1: %s\n"
-#~ msgstr "Font1: %s\n"
+#~ msgid "%2d %-5ld %-34s <none>\n"
+#~ msgstr "%2d %-5ld %-34s <geen>\n"
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "Font%<PRId64> wydte is nie twee keer díe van font0 nie\n"
+# njj: dalk 'verbinding' ipv 'verbinding' orals?
+#~ msgid "couldn't malloc\n"
+#~ msgstr "kon nie 'malloc' nie\n"
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "Font0 wydte: %<PRId64>\n"
+#~ msgid "E260: cscope connection not found"
+#~ msgstr "E260: 'cscope' verbinding nie gevind nie"
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Font1 wydte: %<PRId64>\n"
-#~ "\n"
+#~ msgid "error reading cscope connection %d"
+#~ msgstr "'cscope' verbinding %d kon nie gelees word nie"
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Hangul outomatiserings FOUT"
+#~ msgid "Run Macro"
+#~ msgstr "Voer Makro uit"
-#~ msgid "E563: stat error"
-#~ msgstr "E563: 'stat' fout"
+#~ msgid "function "
+#~ msgstr "funksie "
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: Kon nie 'cscope' databasis oopmaak nie: %s"
+#~ msgid "E463: Region is guarded, cannot modify"
+#~ msgstr "E463: Omgewing is onder bewaking, kan nie verander nie"
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: kan nie 'cscope' databasisinligting kry nie"
+#~ msgid "E233: cannot open display"
+#~ msgstr "E233: kan nie vertoonskerm oopmaak nie"
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: maksimum aantal 'cscope' verbindings bereik"
+#~ msgid "E247: no registered server named \"%s\""
+#~ msgstr "E247: geen geregistreerde bediener genaamd \"%s\""
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
+#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
#~ msgstr ""
-#~ "E263: Jammer, hierdie bevel is afgeskakel, die Python biblioteek lêer kon "
-#~ "nie gelaai word nie."
+#~ "E800: Arabies kan nie gebruik word nie: Nie tydens kompilering gekies "
+#~ "nie\n"
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Kan nie Python rekursief roep nie"
+#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+#~ msgstr ""
+#~ "E27: Farsi kan nie gebruik word nie: Nie tydens kompilering gekies nie\n"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "kan nie 'OutputObject' eienskappe skrap nie"
+#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+#~ msgstr ""
+#~ "E26: Hebreeus kan nie gebruik word nie: Nie tydens kompilering gekies "
+#~ "nie\n"
-#~ msgid "softspace must be an integer"
-#~ msgstr "'softspace' moet 'n heelgetal wees"
+#~ msgid "E448: Could not load library function %s"
+#~ msgstr "E448: Kon nie biblioteek funksie laai nie %s"
-#~ msgid "invalid attribute"
-#~ msgstr "ongeldige eienskap"
+#~ msgid "E234: Unknown fontset: %s"
+#~ msgstr "E234: Onbekende fontstel: %s"
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "'writelines()' benodig 'n lys van stringe"
+#~ msgid "Path length too long!"
+#~ msgstr "Pad-lengte te lank"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: Kon nie I/O objekte inwy nie"
+#~ msgid "gvimext.dll error"
+#~ msgstr "'gvimext.dll' fout"
-# njj: net 'n voorstel ..
-#~ msgid "invalid expression"
-#~ msgstr "ongeldige uitdrukking"
+#~ msgid "Error creating process: Check if gvim is in your path!"
+#~ msgstr "FOut met die skep van proses: Kyk of gvim in jou pad is!"
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "uitdrukkings afgeskakel tydens kompilering"
+#~ msgid "Edits the selected file(s) with Vim"
+#~ msgstr "Wysig die gekose lêer(s) met Vim"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "poging om na 'n geskrapte buffer te verwys"
+#~ msgid "Edit with existing Vim - &"
+#~ msgstr "Wysig met bestaande Vim - &"
-#~ msgid "line number out of range"
-#~ msgstr "reëlnommer buite omvang"
+#~ msgid "Edit with &Vim"
+#~ msgstr "Wysig met &Vim"
-#~ msgid "<buffer object (deleted) at %8lX>"
-#~ msgstr "<buffervoorwerp (geskrap) by %8lX>"
+#~ msgid "&Diff with Vim"
+#~ msgstr "Wys verskille ('&diff') met Vim"
-#~ msgid "invalid mark name"
-#~ msgstr "onbekende merknaam"
+#~ msgid "Edit with single &Vim"
+#~ msgstr "Wysig met 'n enkel &Vim"
-#~ msgid "no such buffer"
-#~ msgstr "buffer bestaan nie"
+#~ msgid "Edit with &multiple Vims"
+#~ msgstr "Wysig met &meer as een Vim"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "poging om na geskrapte venster te verwys"
+#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+#~ msgstr ""
+#~ "E299: Perl evaluasie verbied in die sandput sonder die 'Safe' module"
-#~ msgid "readonly attribute"
-#~ msgstr "leesalleen eienskap"
+#~ msgid ""
+#~ "Sorry, this command is disabled: the Perl library could not be loaded."
+#~ msgstr ""
+#~ "Jammer, hierdie bevel is afgeskakel: die Perl biblioteek kon nie gelaai "
+#~ "word nie."
-#~ msgid "cursor position outside buffer"
-#~ msgstr "loperposisie buite buffer"
+#~ msgid "E370: Could not load library %s"
+#~ msgstr "E370: Kon nie biblioteek laai nie %s"
-#~ msgid "<window object (deleted) at %.8lX>"
-#~ msgstr "<venster voorwerp (geskrap) by %.8lX>"
+#~ msgid "type :help windows95<Enter> for info on this"
+#~ msgstr "tik :help windows95<Enter> vir meer inligting hieroor"
-#~ msgid "<window object (unknown) at %.8lX>"
-#~ msgstr "<verwyder voorwerp (onbekend) by %.8lX>"
+#~ msgid "WARNING: Windows 95/98/ME detected"
+#~ msgstr "WAARSKUWING: Windows 95/98/ME bespeur"
-#~ msgid "<window %d>"
-#~ msgstr "<venster %d>"
+#~ msgid " for Vim defaults "
+#~ msgstr " vir Vim verstekwaardes"
-#~ msgid "no such window"
-#~ msgstr "geen sodanige venster nie"
+#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+#~ msgstr "menu Redigeer->Global verstellings->Stel en herstel Vi Versoenbaar"
-#~ msgid "cannot save undo information"
-#~ msgstr "kan nie herwin-inligting stoor nie"
+#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
+#~ msgstr "menu Redigeer->Globale verstellings->Stel en herstel Invoeg Modus"
-#~ msgid "cannot delete line"
-#~ msgstr "kan reël nie verwyder nie"
+#~ msgid "Running modeless, typed text is inserted"
+#~ msgstr "Voer modus-loos uit, getikte teks word ingevoeg"
-#~ msgid "cannot replace line"
-#~ msgstr "kan reël nie vervang nie"
+#~ msgid "menu Help->Orphans for information "
+#~ msgstr "menu Hulp->Weeskinders vir meer inligting hieroor "
-#~ msgid "cannot insert line"
-#~ msgstr "kan reël nie byvoeg nie"
+#~ msgid "Compiler: "
+#~ msgstr "Kompileerder: "
-#~ msgid "string cannot contain newlines"
-#~ msgstr "string kan nie 'newlines' bevat nie"
+#~ msgid " system menu file: \""
+#~ msgstr " stelsel kieslys-lêer: \""
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Jammer, hierdie bevel is afgeskakel, die Ruby biblioteeklêer kon "
-#~ "nie gelaai word nie."
+#~ msgid "3rd user gvimrc file: \""
+#~ msgstr "3de gebruiker gvimrc-lêer: \""
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: Onbekende 'longjmp' status %d"
+#~ msgid "2nd user gvimrc file: \""
+#~ msgstr "2de gebruiker gvimrc-lêer: \""
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Stel en herstel implimentasie/definisie"
+#~ msgid " user gvimrc file: \""
+#~ msgstr " gebruiker gvimrc-lêer: \""
-#~ msgid "Show base class of"
-#~ msgstr "Wys basisklas van"
+#~ msgid " system gvimrc file: \""
+#~ msgstr " stelsel gvimrc-lêer: \""
-#~ msgid "Show overridden member function"
-#~ msgstr "Wys vervangde lidfunksie"
+#~ msgid "with (classic) GUI."
+#~ msgstr "met (klassieke) GUI."
-#~ msgid "Retrieve from file"
-#~ msgstr "Gaan haal uit lêer"
+#~ msgid "with Cocoa GUI."
+#~ msgstr "met Cocoa GUI."
-#~ msgid "Retrieve from project"
-#~ msgstr "Gaan haal uit projek"
+#~ msgid "with Carbon GUI."
+#~ msgstr "met Carbon GUI."
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Gaan haal uit alle projekte"
+#~ msgid "with GUI."
+#~ msgstr "met GUI."
-#~ msgid "Retrieve"
-#~ msgstr "Gaan haal"
+#~ msgid "with Photon GUI."
+#~ msgstr "met Photon GUI."
-#~ msgid "Show source of"
-#~ msgstr "Wys kode van"
+#~ msgid "with BeOS GUI."
+#~ msgstr "met BeOS GUI"
-#~ msgid "Find symbol"
-#~ msgstr "Vind simbool"
+#~ msgid "with X11-Athena GUI."
+#~ msgstr "met X11-Athena GUI"
-#~ msgid "Browse class"
-#~ msgstr "Kyk klas deur"
+#~ msgid "with X11-neXtaw GUI."
+#~ msgstr "met X11-neXtaw GUI"
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Wys klas in hiërargie"
+#~ msgid "with X11-Motif GUI."
+#~ msgstr "met X11-Motif GUI."
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Wys klas in beperkte hiërargie"
+#~ msgid "with GTK GUI."
+#~ msgstr "met GTK GUI"
-#~ msgid "Xref refers to"
-#~ msgstr "Xref verwys na"
+#~ msgid "with GTK2 GUI."
+#~ msgstr "met GTK2 GUI"
-#~ msgid "Xref referred by"
-#~ msgstr "Xref verwys deur"
+#~ msgid "with GTK-GNOME GUI."
+#~ msgstr "met GTK-GNOME GUI."
-#~ msgid "Xref has a"
-#~ msgstr "Xref het 'n"
+#~ msgid "with GTK2-GNOME GUI."
+#~ msgstr "met GTK2-GNOME GUI."
-#~ msgid "Xref used by"
-#~ msgstr "Xref gebruik deur"
+#~ msgid ""
+#~ "\n"
+#~ "Tiny version "
+#~ msgstr ""
+#~ "\n"
+#~ "Piepklein weergawe "
-#~ msgid "Show docu of"
-#~ msgstr "Wys 'docu' van"
+#~ msgid ""
+#~ "\n"
+#~ "Small version "
+#~ msgstr ""
+#~ "\n"
+#~ "Klein weergawe "
-#~ msgid "Generate docu for"
-#~ msgstr "Genereer 'docu' vir"
+#~ msgid ""
+#~ "\n"
+#~ "Normal version "
+#~ msgstr ""
+#~ "\n"
+#~ "Normale weergawe "
#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
+#~ "\n"
+#~ "Big version "
#~ msgstr ""
-#~ "Kan nie 'n verbinding met 'SNiFF+' maak nie. Kyk of die omgewing reg is "
-#~ "('sniffemacs' moet in '$PATH' gevind word).\n"
+#~ "\n"
+#~ "Groot weergawe "
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Fout gedurende lees. Verbinding gebreek"
+#~ msgid ""
+#~ "\n"
+#~ "RISC OS version"
+#~ msgstr ""
+#~ "\n"
+#~ "RISC OS weergawe"
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ is tans"
+#~ msgid ""
+#~ "\n"
+#~ "MacOS version"
+#~ msgstr ""
+#~ "\n"
+#~ "MacOS weergawe"
-#~ msgid "not "
-#~ msgstr "nie "
+#~ msgid ""
+#~ "\n"
+#~ "MacOS X version"
+#~ msgstr ""
+#~ "\n"
+#~ "MacOS X weergawe"
-#~ msgid "connected"
-#~ msgstr "gekonnekteer"
+#~ msgid ""
+#~ "\n"
+#~ "MacOS X (unix) version"
+#~ msgstr ""
+#~ "\n"
+#~ "MacOS X (unix) weergawe"
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Onbekende SNiFF+ versoek: %s"
+#~ msgid ""
+#~ "\n"
+#~ "16-bit MS-DOS version"
+#~ msgstr ""
+#~ "\n"
+#~ "16-bis MS-DOS weergawe"
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Fout in konnekteer met SNiFF+"
+#~ msgid ""
+#~ "\n"
+#~ "32-bit MS-DOS version"
+#~ msgstr ""
+#~ "\n"
+#~ "32-bis MS-DOS weergawe"
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ is nie gekonnekteer nie"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 16-bit version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 16-bis weergawe"
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: Fout gedurende stoor. Verbinding gebreek"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 32-bit console version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32-bis konsole weergawe"
-#~ msgid "not implemented yet"
-#~ msgstr "nog nie geïmplementeer nie"
+#~ msgid " with OLE support"
+#~ msgstr " met OLE ondersteuning"
-#~ msgid "unknown option"
-#~ msgstr "onbekende opsie"
+#~ msgid " in Win32s mode"
+#~ msgstr " in Win32s modus"
-#~ msgid "cannot set line(s)"
-#~ msgstr "kan nie reël(s) stel nie"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 32-bit GUI version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32-bis GUI version"
-#~ msgid "mark not set"
-#~ msgstr "merker nie gestel nie"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 16/32-bit GUI version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 16/32-bis GUI weergawe"
-#~ msgid "row %d column %d"
-#~ msgstr "ry %d kolom %d"
+#~ msgid "No undo possible; continue anyway"
+#~ msgstr "Geen herstel moontlik; gaan in elk geval voort"
-#~ msgid "cannot insert/append line"
-#~ msgstr "kan nie reël invoeg/aanlas nie"
+#~ msgid "new shell started\n"
+#~ msgstr "nuwe dop begin\n"
-#~ msgid "unknown flag: "
-#~ msgstr "onbekende vlag: "
+#~ msgid "E430: Tag file path truncated for %s\n"
+#~ msgstr "E430: Etiketlêergids afgekap vir %s\n"
-#~ msgid "unknown vimOption"
-#~ msgstr "onbekende 'vimOption'"
+#~ msgid "Enter nr of choice (<CR> to abort): "
+#~ msgstr "Sleutel nommer van keuse in (<CR> om te stop): "
-#~ msgid "keyboard interrupt"
-#~ msgstr "sleutelbordonderbreking"
+#~ msgid "E396: containedin argument not accepted here"
+#~ msgstr "E396: 'containedin' parameter nie hier aanvaar nie"
-#~ msgid "vim error"
-#~ msgstr "vim fout"
+#~ msgid "E363: pattern caused out-of-stack error"
+#~ msgstr "E363: patroon het lëe-stapel fout veroorsaak"
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "kan nie buffer/venster bevel skep nie: voorwerp word geskrap"
+#~ msgid "E361: Crash intercepted; regexp too complex?"
+#~ msgstr "E361: Ineenstorting onderskep. Patroon te kompleks?"
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "kan nie terugroepbevel registreer nie: buffer/venster word alreeds geskrap"
+#~ msgid "E58: %s{ operand could be empty"
+#~ msgstr "E58: %s{ operand mag leeg wees"
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL FATALE FOUT: verwlys korrup!? Rapporteer dit asb. aan <vim-"
-#~ "dev@vim.org>"
+#~ msgid "E57: %s+ operand could be empty"
+#~ msgstr "E57: %s+ operand mag leeg wees"
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "kan terugroepbevel nie registreer nie: buffer/vensterverwysing nie gevind "
-#~ "nie"
+#~ msgid "E56: %s* operand could be empty"
+#~ msgstr "E56: %s* operand mag leeg wees"
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: Jammer, hierdie bevel is afgeskakel, die Tcl biblioteek kon nie "
-#~ "gelaai word nie."
+#~ msgid "Vim Warning"
+#~ msgstr "Vim Waarskuwing"
#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
+#~ "VIMRUN.EXE not found in your $PATH.\n"
+#~ "External commands will not pause after completion.\n"
+#~ "See :help win32-vimrun for more information."
#~ msgstr ""
-#~ "E281: TCL FOUT: verlaatkode is nie 'n 'int'!? Rapporteer dit asb. aan "
-#~ "<vim-dev@vim.org>"
-
-#~ msgid "cannot get line"
-#~ msgstr "kan nie reël kry nie"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Kon nie bevelbediener naam registreer nie"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Het gefaal om bevel na doel program te stuur"
+#~ "'VIMRUN.EXE' nie gevind in '$PATH' nie.\n"
+#~ "Eksterne opdragte sal nie wag na voltooiing nie\n"
+#~ "Sien ':help win32-vimrun' vir meer inligting."
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM instansie register-kenmerk is swak gevorm. Geskrap!"
+#~ msgid "E371: Command not found"
+#~ msgstr "E371: Bevel nie gevind nie"
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Hierdie Vim is nie gekompileer met 'diff' funksionaliteit nie."
+#~ msgid "shutdown"
+#~ msgstr "sit af"
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tRegistreer hierdie gvim vir OLE"
+#~ msgid "logoff"
+#~ msgstr "teken uit"
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tOnregistreer gvim vir OLE"
+#~ msgid "close"
+#~ msgstr "maak toe"
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tVoer uit met die GUI (soos \"gvim\")"
+#~ msgid "Vim: Caught %s event\n"
+#~ msgstr "Vim: Het %s gebeurtenis gevang\n"
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f of --nofork\tVoorgrond: Moenie vurk wanneer GUI begin nie"
+#~ msgid "shell returned %d"
+#~ msgstr "dop het %d gelewer"
-#~ msgid "-V[N]\t\tVerbose level"
-#~ msgstr "-V[N]\t\tOmslagtigheidsgraad"
+#~ msgid "Could not fix up function pointers to the DLL!"
+#~ msgstr "Kon nie funksiewysers na die DLL opstel nie!"
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tMoet nie 'newcli' gebruik om venster oop te maak nie"
+#~ msgid "Could not load vim32.dll!"
+#~ msgstr "Kon nie 'vim32.dll' laai nie!"
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <toestel>\t\tGebruik <toestel> vir I/O"
+#~ msgid "VIM Error"
+#~ msgstr "VIM Fout"
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tGebruik <gvimrc> in plaas van enige .gvimrc"
+#~ msgid "Could not allocate memory for command line."
+#~ msgstr "Kan nie geheue toeken vir bevelreël nie"
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tBewerk geënkripteerde lêers"
+#~ msgid "At line"
+#~ msgstr "By reël"
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tKoppel vim aan hierdie X-bediener"
+#~ msgid "XSMP ICE connection watch failed"
+#~ msgstr "XSMP ICE konneksie beloer het gefaal"
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tMoet nie verbinding met X-bediener maak nie"
+#~ msgid "XSMP opening connection"
+#~ msgstr "XSMP maak nou konneksie oop"
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <lêers>\tWysig die <lêers> in a Vim bediener indien moontlik"
+#~ msgid "XSMP handling save-yourself request"
+#~ msgstr "XSMP hanteer 'save-yourself' versoek"
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent <lêers> Dieselfde, moet nie kla as daar nie so 'n "
-#~ "bediener is nie"
+#~ msgid "Opening the X display failed"
+#~ msgstr "Oopmaak van die X vertoonskerm het gefaal"
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <lêers> Soos '--remote', maar wag vir lêers om gewysig te "
-#~ "word"
+#~ msgid "XSMP lost ICE connection"
+#~ msgstr "XSMP het ICE konneksie verloor"
#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <lêers> Dieselfde, moet nie kla as daar nie so 'n "
-#~ "bediener is nie"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+#~ "\n"
+#~ "Command terminated\n"
#~ msgstr ""
-#~ "--remote-send <sleutels>\tStuur <sleutels> na 'n Vim-bediener en verlaat"
+#~ "\n"
+#~ "Bevel beëindig\n"
#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+#~ "\n"
+#~ "Cannot fork\n"
#~ msgstr ""
-#~ "--remote-expr <expr>\tEvalueer <expr> in 'n Vim-bediener en druk resultaat"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tLys beskikbare Vim-bediener name en verlaat"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <naam>\tStuur na/word die Vim-bediener <naam>"
+#~ "\n"
+#~ "Kan nie vurk nie\n"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
+#~ "Cannot create pipes\n"
#~ msgstr ""
#~ "\n"
-#~ "Parameters deur gvim herken (Motif weergawe):\n"
+#~ "Kan nie pype skep nie\n"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
+#~ "Cannot execute shell sh\n"
#~ msgstr ""
#~ "\n"
-#~ "Parameters deur gvim herken (neXtaw weergawe):\n"
+#~ "Kan nie dop 'sh' uitvoer nie\n"
+
+#~ msgid "Opening the X display timed out"
+#~ msgstr "Oopmaak van die X-vertoonskerm het uitgetel"
+
+#~ msgid "Testing the X display failed"
+#~ msgstr "Toetsing van die X-vertoonskerm het gefaal"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
+#~ "Vim: Got X error\n"
#~ msgstr ""
#~ "\n"
-#~ "Parameters deur gvim herken (Athena weergawe):\n"
+#~ "Vim: Het X fout ontvang\n"
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\tVoer vim op <display> uit"
+#~ msgid "Opening the X display took %<PRId64> msec"
+#~ msgstr "Om die X-vertoonskerm oop te maak het %<PRId64> msek gevat"
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tBegin vim as ikoon"
+#~ msgid "Vim: Caught deadly signal\n"
+#~ msgstr "Vim: Het dodelike sein gevang\n"
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <name>\t\tGebruik hulpbron asof vim <name> was"
+#~ msgid "Vim: Caught deadly signal %s\n"
+#~ msgstr "Vim: Het dodelike sein %s gevang\n"
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (Nog nie geïmplementeer nie)\n"
+#~ msgid "Vim: Double signal, exiting\n"
+#~ msgstr "Vim: Dubbel sein, staak\n"
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <kleur>\tGebruik <kleur> vir die agtergrond (ook: -bg)"
+#~ msgid "E245: Illegal char '%c' in font name \"%s\""
+#~ msgstr "E245: Ongeldige karakter '%c' in fontnaam \"%s\""
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-voorgrond <kleur>\tGebruik <kleur> vir normale teks (ook: -fg)"
+#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+#~ msgstr "E244: Ongeldige karakterstelnaam \"%s\" in fontnaam \"%s\""
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\tGebruik <font> vir normale teks (ook -fn)"
+#~ msgid "Printing '%s'"
+#~ msgstr "Druk nou '%s'"
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "­boldfont <font>\t Gebruik <font> vir vetletter teks"
+#~ msgid "E238: Print error: %s"
+#~ msgstr "E238: Drukfout: %s"
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <font>\tGebruik <font> vir kursiewe teks"
+#~ msgid "E613: Unknown printer font: %s"
+#~ msgstr "E613: Onbekende drukker font: %s"
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\tGebruik <geom> vir aanvanklike geometrie"
+#~ msgid "to %s on %s"
+#~ msgstr "na %s op %s"
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <wydte>\tGebruik 'n grenswydte van <wydte> (ook: -bw)"
+#~ msgid "'columns' is not 80, cannot execute external commands"
+#~ msgstr "'columns' is nie 80 nie, kan nie eksterne bevele uitvoer nie"
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <wydte>\tGebruik 'n rolstaafwydte van <wydte> (ook: -sw>"
+#~ msgid "...(truncated)"
+#~ msgstr "...(afgekap)"
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <hoogte>\tGebruik a kieslysstaafhoogte van <hoogte> (ook: -mh)"
+#~ msgid "I/O ERROR"
+#~ msgstr "I/O FOUT"
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tGebruik tru-video (ook: -rv)"
+#~ msgid "ANCHOR_BUF_SIZE too small."
+#~ msgstr "'ANCHOR_BUF_SIZE' is te klein"
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tMoet nie tru-video gebruik nie (ook: +rv)"
+#~ msgid " returned\n"
+#~ msgstr " teruggekeer\n"
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <hulpbron>\tStel die gespesifiseerde hulpbron"
+#~ msgid "shell "
+#~ msgstr "dop "
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Parameters wat gvim verstaan (RISC OS weergawe):\n"
+#~ msgid "Cannot execute "
+#~ msgstr "Kan nie uitvoer nie "
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <aantal>\tAanvanklike wydte van venster in kolomme"
+#~ msgid "mch_get_shellsize: not a console??\n"
+#~ msgstr "'mch_get_shellsize': nie 'n konsole nie??\n"
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <aantal>\tAanvanklike hoogte van venster in rye"
+#~ msgid "cannot change console mode ?!\n"
+#~ msgstr "kan konsole-modus nie verander nie ?!\n"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Parameters wat gvim verstaan (GTK+ weergawe):\n"
+#~ msgid "Vim exiting with %d\n"
+#~ msgstr "Vim stop met %d\n"
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <skerm>\tVoer vim op <skerm> uit: (ook --display)"
+#~ msgid "Cannot create "
+#~ msgstr "Kan nie skep nie: "
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <rol>\tStel 'n unieke rol om die hoofvenster te identifiseer"
+#~ msgid "Cannot open NIL:\n"
+#~ msgstr "Kan nie NIL: oopmaak nie\n"
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tMaak Vim in 'n ander GTK element oop"
+#~ msgid "Need %s version %<PRId64>\n"
+#~ msgstr "Benodig %s weergawe %<PRId64>\n"
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <ouer title>\tMaak Vim oop binne 'n ouer toepassing"
+#~ msgid "Need Amigados version 2.04 or later\n"
+#~ msgstr "Benodig Amigados weergawe 2.04 of later\n"
-#~ msgid "No display"
-#~ msgstr "Geen vertoonskerm"
+#~ msgid "VIM: Can't open window!\n"
+#~ msgstr "VIM: Kan nie venster oopmaak nie!\n"
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Stuur het gefaal.\n"
+#~ msgid "cannot open "
+#~ msgstr "kan nie oopmaak nie "
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Stuur het gefaal. Probeer om lokaal uit te voer\n"
+#~ msgid "E538: No mouse support"
+#~ msgstr "E538: Geen muisondersteuning nie"
-#~ msgid "%d of %d edited"
-#~ msgstr "%d van %d lêers bewerk"
+#~ msgid "E534: Invalid wide font"
+#~ msgstr "E534: Ongeldige wye font"
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Geen vertoonskerm: Stuur van uitdrukking het gefaal.\n"
+#~ msgid "E533: can't select wide font"
+#~ msgstr "E533: kan nie wye font kies nie"
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Stuur van uitdrukking het gefaal.\n"
+#~ msgid "E598: Invalid fontset"
+#~ msgstr "E598: Ongeldige fontstel"
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Nie 'n geldige kodeblad nie"
+#~ msgid "E597: can't select fontset"
+#~ msgstr "E597: kan nie fontstel kies nie"
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Gefaal met die skep van invoerkonteks"
+#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+#~ msgstr "E617: Kan nie 'term' verander in die GTK+ 2 GUI nie"
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Gefaal om invoermetode oop te maak"
+#~ msgid "E531: Use \":gui\" to start the GUI"
+#~ msgstr "E531: Gebruik \":gui\" om die GUI te begin"
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: Waarskuwing: Kon nie uitwis-terugroep na IM stel nie"
+#~ msgid "E530: Cannot change term in GUI"
+#~ msgstr "E530: Kan nie 'term' verander in GUI nie"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: invoermetode ondersteun geen styl nie"
+#~ msgid "freeing %<PRId64> lines"
+#~ msgstr "laat %<PRId64> reëls gaan"
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: invoermetode ondersteun nie my voor-bewerking tipe nie"
+#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
+#~ msgstr "E658: NetBeans konneksie vir buffer %<PRId64> verloor"
-#~ msgid "E290: over-the-spot style requires fontset"
-#~ msgstr "E290: oor-die-plek styl vereis fontstel"
+#~ msgid "read from Netbeans socket"
+#~ msgstr "lees vanaf Netbeans 'socket'"
-#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
-#~ msgstr "E291: Jou GTK+ is ouer as 1.2.3. Statusarea afgeskakel"
+#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+#~ msgstr ""
+#~ "E668: Verkeerde toegangsmodue vir NetBeans konneksie inligtingslêer: \"%s"
+#~ "\""
-#~ msgid "E292: Input Method Server is not running"
-#~ msgstr "E292: Invoermetodebediener voer nie uit nie"
+#~ msgid "Cannot connect to Netbeans"
+#~ msgstr "Kan nie aan Netbeans koppel nie"
+
+#~ msgid "Cannot connect to Netbeans #2"
+#~ msgstr "Kan nie aan Netbeans #2 koppel nie"
+
+#~ msgid "Keys don't match!"
+#~ msgstr "Sleutels verskil!"
+
+#~ msgid "Enter same key again: "
+#~ msgstr "Voer die sleutel weer in: "
+
+#~ msgid "Enter encryption key: "
+#~ msgstr "Voer enkripsie-sleutel in: "
+
+#~ msgid "E547: Illegal mouseshape"
+#~ msgstr "E547: Ongeldige muisvorm"
+
+#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
+#~ msgstr "E341: Interne fout: 'lalloc(%<PRId64>, )'"
+
+#~ msgid "E340: Line is becoming too long"
+#~ msgstr "E340: Rëel word te lank"
#~ msgid ""
+#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
#~ "\n"
-#~ " [not usable with this version of Vim]"
#~ msgstr ""
+#~ "[roepe] totaal re/malloc()'s %<PRIu64>, totale free()'s %<PRIu64>\n"
#~ "\n"
-#~ " [nie bruikbaar met hierdie weergawe van Vim nie]"
+
+#~ msgid ""
+#~ "\n"
+#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
+#~ "%<PRIu64>\n"
+#~ msgstr ""
+#~ "\n"
+#~ "[grepe] totaal 'alloc'-vrygelaat %<PRIu64>-%<PRIu64>, in gebruik "
+#~ "%<PRIu64>, piekgebruik %<PRIu64>\n"
+
+#~ msgid "ERROR: "
+#~ msgstr "FOUT: "
+
+#~ msgid "Vim: Finished.\n"
+#~ msgstr "Vim: Klaar.\n"
+
+#~ msgid "Vim: preserving files...\n"
+#~ msgstr "Vim: bewaar lêers...\n"
+
+#~ msgid "E338: Sorry, no file browser in console mode"
+#~ msgstr "E338: Jammer, lêerblaaier nie beskikbaar in konsole-modus nie"
+
+#~ msgid "Open File dialog"
+#~ msgstr "Maak lêer oop dialooghokkie"
+
+#~ msgid "Save File dialog"
+#~ msgstr "Stoor Lêer dialooghokkie"
+
+#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
+#~ msgstr " (RET: reël, SPACE: bladsy, d: halwe bladsy, q: los dit"
+
+#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
+#~ msgstr " (RET/BS: reël, SPACE/b: bladsy, d/u: halwe bladsy, q: los dit"
+
+#~ msgid "Hit ENTER to continue"
+#~ msgstr "Druk ENTER om voort te gaan"
+
+#~ msgid "[string too long]"
+#~ msgstr "[string te lank]"
+
+#~ msgid "Tear off this menu"
+#~ msgstr "Skeur die kieslys af"
#~ msgid ""
#~ "&Open Read-Only\n"
@@ -7282,824 +6490,1139 @@ msgstr "E446: Geen lêernaam onder loper"
#~ "&Stop\n"
#~ "S&krap dit"
-#~ msgid "Tear off this menu"
-#~ msgstr "Skeur die kieslys af"
+#~ msgid ""
+#~ "\n"
+#~ " [not usable with this version of Vim]"
+#~ msgstr ""
+#~ "\n"
+#~ " [nie bruikbaar met hierdie weergawe van Vim nie]"
-#~ msgid "[string too long]"
-#~ msgstr "[string te lank]"
+#~ msgid "E292: Input Method Server is not running"
+#~ msgstr "E292: Invoermetodebediener voer nie uit nie"
-#~ msgid "Hit ENTER to continue"
-#~ msgstr "Druk ENTER om voort te gaan"
+#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
+#~ msgstr "E291: Jou GTK+ is ouer as 1.2.3. Statusarea afgeskakel"
-#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
-#~ msgstr " (RET/BS: reël, SPACE/b: bladsy, d/u: halwe bladsy, q: los dit"
+#~ msgid "E290: over-the-spot style requires fontset"
+#~ msgstr "E290: oor-die-plek styl vereis fontstel"
-#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
-#~ msgstr " (RET: reël, SPACE: bladsy, d: halwe bladsy, q: los dit"
+#~ msgid "E289: input method doesn't support my preedit type"
+#~ msgstr "E289: invoermetode ondersteun nie my voor-bewerking tipe nie"
-#~ msgid "Save File dialog"
-#~ msgstr "Stoor Lêer dialooghokkie"
+#~ msgid "E288: input method doesn't support any style"
+#~ msgstr "E288: invoermetode ondersteun geen styl nie"
-#~ msgid "Open File dialog"
-#~ msgstr "Maak lêer oop dialooghokkie"
+#~ msgid "E287: Warning: Could not set destroy callback to IM"
+#~ msgstr "E287: Waarskuwing: Kon nie uitwis-terugroep na IM stel nie"
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Jammer, lêerblaaier nie beskikbaar in konsole-modus nie"
+#~ msgid "E285: Failed to create input context"
+#~ msgstr "E285: Gefaal met die skep van invoerkonteks"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: bewaar lêers...\n"
+#~ msgid "E543: Not a valid codepage"
+#~ msgstr "E543: Nie 'n geldige kodeblad nie"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: Klaar.\n"
+#~ msgid ": Send expression failed.\n"
+#~ msgstr ": Stuur van uitdrukking het gefaal.\n"
-#~ msgid "ERROR: "
-#~ msgstr "FOUT: "
+#~ msgid "No display: Send expression failed.\n"
+#~ msgstr "Geen vertoonskerm: Stuur van uitdrukking het gefaal.\n"
+
+#~ msgid "%d of %d edited"
+#~ msgstr "%d van %d lêers bewerk"
+
+#~ msgid ": Send failed. Trying to execute locally\n"
+#~ msgstr ": Stuur het gefaal. Probeer om lokaal uit te voer\n"
+
+#~ msgid ": Send failed.\n"
+#~ msgstr ": Stuur het gefaal.\n"
+
+#~ msgid "No display"
+#~ msgstr "Geen vertoonskerm"
+
+#~ msgid "-P <parent title>\tOpen Vim inside parent application"
+#~ msgstr "-P <ouer title>\tMaak Vim oop binne 'n ouer toepassing"
+
+#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+#~ msgstr "--socketid <xid>\tMaak Vim in 'n ander GTK element oop"
+
+#~ msgid "--role <role>\tSet a unique role to identify the main window"
+#~ msgstr "--role <rol>\tStel 'n unieke rol om die hoofvenster te identifiseer"
+
+#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
+#~ msgstr "-display <skerm>\tVoer vim op <skerm> uit: (ook --display)"
#~ msgid ""
#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
+#~ "Arguments recognised by gvim (GTK+ version):\n"
#~ msgstr ""
#~ "\n"
-#~ "[grepe] totaal 'alloc'-vrygelaat %<PRIu64>-%<PRIu64>, in gebruik "
-#~ "%<PRIu64>, piekgebruik %<PRIu64>\n"
+#~ "Parameters wat gvim verstaan (GTK+ weergawe):\n"
+
+#~ msgid "--rows <number>\tInitial height of window in rows"
+#~ msgstr "--rows <aantal>\tAanvanklike hoogte van venster in rye"
+
+#~ msgid "--columns <number>\tInitial width of window in columns"
+#~ msgstr "--columns <aantal>\tAanvanklike wydte van venster in kolomme"
#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
#~ "\n"
+#~ "Arguments recognised by gvim (RISC OS version):\n"
#~ msgstr ""
-#~ "[roepe] totaal re/malloc()'s %<PRIu64>, totale free()'s %<PRIu64>\n"
#~ "\n"
+#~ "Parameters wat gvim verstaan (RISC OS weergawe):\n"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Rëel word te lank"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Interne fout: 'lalloc(%<PRId64>, )'"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Ongeldige muisvorm"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "Voer enkripsie-sleutel in: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "Voer die sleutel weer in: "
+#~ msgid "-xrm <resource>\tSet the specified resource"
+#~ msgstr "-xrm <hulpbron>\tStel die gespesifiseerde hulpbron"
-#~ msgid "Keys don't match!"
-#~ msgstr "Sleutels verskil!"
+#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+#~ msgstr "+reverse\t\tMoet nie tru-video gebruik nie (ook: +rv)"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Kan nie aan Netbeans #2 koppel nie"
+#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
+#~ msgstr "-reverse\t\tGebruik tru-video (ook: -rv)"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Kan nie aan Netbeans koppel nie"
+#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+#~ msgstr ""
+#~ "-menuheight <hoogte>\tGebruik a kieslysstaafhoogte van <hoogte> (ook: -mh)"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+#~ msgid ""
+#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
#~ msgstr ""
-#~ "E668: Verkeerde toegangsmodue vir NetBeans konneksie inligtingslêer: \"%s"
-#~ "\""
+#~ "-scrollbarwidth <wydte>\tGebruik 'n rolstaafwydte van <wydte> (ook: -sw>"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "lees vanaf Netbeans 'socket'"
+#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+#~ msgstr "-borderwidth <wydte>\tGebruik 'n grenswydte van <wydte> (ook: -bw)"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: NetBeans konneksie vir buffer %<PRId64> verloor"
+#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+#~ msgstr "-geometry <geom>\tGebruik <geom> vir aanvanklike geometrie"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "laat %<PRId64> reëls gaan"
+#~ msgid "-italicfont <font>\tUse <font> for italic text"
+#~ msgstr "-italicfont <font>\tGebruik <font> vir kursiewe teks"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Kan nie 'term' verander in GUI nie"
+#~ msgid "-boldfont <font>\tUse <font> for bold text"
+#~ msgstr "­boldfont <font>\t Gebruik <font> vir vetletter teks"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Gebruik \":gui\" om die GUI te begin"
+#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+#~ msgstr "-font <font>\t\tGebruik <font> vir normale teks (ook -fn)"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Kan nie 'term' verander in die GTK+ 2 GUI nie"
+#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+#~ msgstr "-voorgrond <kleur>\tGebruik <kleur> vir normale teks (ook: -fg)"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: kan nie fontstel kies nie"
+#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
+#~ msgstr "-background <kleur>\tGebruik <kleur> vir die agtergrond (ook: -bg)"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Ongeldige fontstel"
+#~ msgid "\t\t\t (Unimplemented)\n"
+#~ msgstr "\t\t\t (Nog nie geïmplementeer nie)\n"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: kan nie wye font kies nie"
+#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
+#~ msgstr "-name <name>\t\tGebruik hulpbron asof vim <name> was"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Ongeldige wye font"
+#~ msgid "-iconic\t\tStart vim iconified"
+#~ msgstr "-iconic\t\tBegin vim as ikoon"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Geen muisondersteuning nie"
+#~ msgid "-display <display>\tRun vim on <display>"
+#~ msgstr "-display <display>\tVoer vim op <display> uit"
-#~ msgid "cannot open "
-#~ msgstr "kan nie oopmaak nie "
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (Athena version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Parameters deur gvim herken (Athena weergawe):\n"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Kan nie venster oopmaak nie!\n"
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (neXtaw version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Parameters deur gvim herken (neXtaw weergawe):\n"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Benodig Amigados weergawe 2.04 of later\n"
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (Motif version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Parameters deur gvim herken (Motif weergawe):\n"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Benodig %s weergawe %<PRId64>\n"
+#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
+#~ msgstr "--servername <naam>\tStuur na/word die Vim-bediener <naam>"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Kan nie NIL: oopmaak nie\n"
+#~ msgid "--serverlist\t\tList available Vim server names and exit"
+#~ msgstr "--serverlist\t\tLys beskikbare Vim-bediener name en verlaat"
-#~ msgid "Cannot create "
-#~ msgstr "Kan nie skep nie: "
+#~ msgid ""
+#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+#~ msgstr ""
+#~ "--remote-expr <expr>\tEvalueer <expr> in 'n Vim-bediener en druk resultaat"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim stop met %d\n"
+#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+#~ msgstr ""
+#~ "--remote-send <sleutels>\tStuur <sleutels> na 'n Vim-bediener en verlaat"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "kan konsole-modus nie verander nie ?!\n"
+#~ msgid ""
+#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
+#~ msgstr ""
+#~ "--remote-wait-silent <lêers> Dieselfde, moet nie kla as daar nie so 'n "
+#~ "bediener is nie"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "'mch_get_shellsize': nie 'n konsole nie??\n"
+#~ msgid ""
+#~ "--remote-wait <files> As --remote but wait for files to have been edited"
+#~ msgstr ""
+#~ "--remote-wait <lêers> Soos '--remote', maar wag vir lêers om gewysig te "
+#~ "word"
-#~ msgid "Cannot execute "
-#~ msgstr "Kan nie uitvoer nie "
+#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
+#~ msgstr ""
+#~ "--remote-silent <lêers> Dieselfde, moet nie kla as daar nie so 'n "
+#~ "bediener is nie"
-#~ msgid "shell "
-#~ msgstr "dop "
+#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+#~ msgstr ""
+#~ "--remote <lêers>\tWysig die <lêers> in a Vim bediener indien moontlik"
-#~ msgid " returned\n"
-#~ msgstr " teruggekeer\n"
+#~ msgid "-X\t\t\tDo not connect to X server"
+#~ msgstr "-X\t\t\tMoet nie verbinding met X-bediener maak nie"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "'ANCHOR_BUF_SIZE' is te klein"
+#~ msgid "-display <display>\tConnect vim to this particular X-server"
+#~ msgstr "-display <display>\tKoppel vim aan hierdie X-bediener"
-#~ msgid "I/O ERROR"
-#~ msgstr "I/O FOUT"
+#~ msgid "-x\t\t\tEdit encrypted files"
+#~ msgstr "-x\t\t\tBewerk geënkripteerde lêers"
-#~ msgid "...(truncated)"
-#~ msgstr "...(afgekap)"
+#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+#~ msgstr "-U <gvimrc>\t\tGebruik <gvimrc> in plaas van enige .gvimrc"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' is nie 80 nie, kan nie eksterne bevele uitvoer nie"
+#~ msgid "-dev <device>\t\tUse <device> for I/O"
+#~ msgstr "-dev <toestel>\t\tGebruik <toestel> vir I/O"
-#~ msgid "to %s on %s"
-#~ msgstr "na %s op %s"
+#~ msgid "-f\t\t\tDon't use newcli to open window"
+#~ msgstr "-f\t\t\tMoet nie 'newcli' gebruik om venster oop te maak nie"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Onbekende drukker font: %s"
+#~ msgid "-V[N]\t\tVerbose level"
+#~ msgstr "-V[N]\t\tOmslagtigheidsgraad"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Drukfout: %s"
+#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+#~ msgstr "-f of --nofork\tVoorgrond: Moenie vurk wanneer GUI begin nie"
-#~ msgid "Printing '%s'"
-#~ msgstr "Druk nou '%s'"
+#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+#~ msgstr "-g\t\t\tVoer uit met die GUI (soos \"gvim\")"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: Ongeldige karakterstelnaam \"%s\" in fontnaam \"%s\""
+#~ msgid "-unregister\t\tUnregister gvim for OLE"
+#~ msgstr "-unregister\t\tOnregistreer gvim vir OLE"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Ongeldige karakter '%c' in fontnaam \"%s\""
+#~ msgid "-register\t\tRegister this gvim for OLE"
+#~ msgstr "-register\t\tRegistreer hierdie gvim vir OLE"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Dubbel sein, staak\n"
+#~ msgid "This Vim was not compiled with the diff feature."
+#~ msgstr "Hierdie Vim is nie gekompileer met 'diff' funksionaliteit nie."
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Het dodelike sein %s gevang\n"
+#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
+#~ msgstr "E251: VIM instansie register-kenmerk is swak gevorm. Geskrap!"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Het dodelike sein gevang\n"
+#~ msgid "E248: Failed to send command to the destination program"
+#~ msgstr "E248: Het gefaal om bevel na doel program te stuur"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Om die X-vertoonskerm oop te maak het %<PRId64> msek gevat"
+#~ msgid "Unable to register a command server name"
+#~ msgstr "Kon nie bevelbediener naam registreer nie"
+
+#~ msgid "cannot get line"
+#~ msgstr "kan nie reël kry nie"
#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
+#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
+#~ "org"
#~ msgstr ""
-#~ "\n"
-#~ "Vim: Het X fout ontvang\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "Toetsing van die X-vertoonskerm het gefaal"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Oopmaak van die X-vertoonskerm het uitgetel"
+#~ "E281: TCL FOUT: verlaatkode is nie 'n 'int'!? Rapporteer dit asb. aan "
+#~ "<vim-dev@vim.org>"
#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
+#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
+#~ "loaded."
#~ msgstr ""
-#~ "\n"
-#~ "Kan nie dop 'sh' uitvoer nie\n"
+#~ "E571: Jammer, hierdie bevel is afgeskakel, die Tcl biblioteek kon nie "
+#~ "gelaai word nie."
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
+#~ msgid "cannot register callback command: buffer/window reference not found"
#~ msgstr ""
-#~ "\n"
-#~ "Kan nie pype skep nie\n"
+#~ "kan terugroepbevel nie registreer nie: buffer/vensterverwysing nie gevind "
+#~ "nie"
#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
+#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
+#~ "dev@vim.org"
#~ msgstr ""
-#~ "\n"
-#~ "Kan nie vurk nie\n"
+#~ "E280: TCL FATALE FOUT: verwlys korrup!? Rapporteer dit asb. aan <vim-"
+#~ "dev@vim.org>"
#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
+#~ "cannot register callback command: buffer/window is already being deleted"
#~ msgstr ""
-#~ "\n"
-#~ "Bevel beëindig\n"
+#~ "kan nie terugroepbevel registreer nie: buffer/venster word alreeds geskrap"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP het ICE konneksie verloor"
+#~ msgid "cannot create buffer/window command: object is being deleted"
+#~ msgstr "kan nie buffer/venster bevel skep nie: voorwerp word geskrap"
-#~ msgid "Opening the X display failed"
-#~ msgstr "Oopmaak van die X vertoonskerm het gefaal"
+#~ msgid "vim error"
+#~ msgstr "vim fout"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP hanteer 'save-yourself' versoek"
+#~ msgid "keyboard interrupt"
+#~ msgstr "sleutelbordonderbreking"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP maak nou konneksie oop"
+#~ msgid "unknown vimOption"
+#~ msgstr "onbekende 'vimOption'"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICE konneksie beloer het gefaal"
+#~ msgid "unknown flag: "
+#~ msgstr "onbekende vlag: "
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP 'SmcOpenConnection' het gefaal: %s"
+#~ msgid "cannot insert/append line"
+#~ msgstr "kan nie reël invoeg/aanlas nie"
-#~ msgid "At line"
-#~ msgstr "By reël"
+#~ msgid "row %d column %d"
+#~ msgstr "ry %d kolom %d"
-#~ msgid "Could not allocate memory for command line."
-#~ msgstr "Kan nie geheue toeken vir bevelreël nie"
+#~ msgid "mark not set"
+#~ msgstr "merker nie gestel nie"
-#~ msgid "VIM Error"
-#~ msgstr "VIM Fout"
+#~ msgid "cannot set line(s)"
+#~ msgstr "kan nie reël(s) stel nie"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Kon nie 'vim32.dll' laai nie!"
+#~ msgid "unknown option"
+#~ msgstr "onbekende opsie"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Kon nie funksiewysers na die DLL opstel nie!"
+#~ msgid "not implemented yet"
+#~ msgstr "nog nie geïmplementeer nie"
-#~ msgid "shell returned %d"
-#~ msgstr "dop het %d gelewer"
+#~ msgid "Sniff: Error during write. Disconnected"
+#~ msgstr "Sniff: Fout gedurende stoor. Verbinding gebreek"
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Het %s gebeurtenis gevang\n"
+#~ msgid "E278: SNiFF+ not connected"
+#~ msgstr "E278: SNiFF+ is nie gekonnekteer nie"
-#~ msgid "close"
-#~ msgstr "maak toe"
+#~ msgid "E276: Error connecting to SNiFF+"
+#~ msgstr "E276: Fout in konnekteer met SNiFF+"
-#~ msgid "logoff"
-#~ msgstr "teken uit"
+#~ msgid "E275: Unknown SNiFF+ request: %s"
+#~ msgstr "E275: Onbekende SNiFF+ versoek: %s"
-#~ msgid "shutdown"
-#~ msgstr "sit af"
+#~ msgid "connected"
+#~ msgstr "gekonnekteer"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Bevel nie gevind nie"
+#~ msgid "not "
+#~ msgstr "nie "
+
+#~ msgid "SNiFF+ is currently "
+#~ msgstr "SNiFF+ is tans"
+
+#~ msgid "E274: Sniff: Error during read. Disconnected"
+#~ msgstr "E274: Sniff: Fout gedurende lees. Verbinding gebreek"
#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
+#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
+#~ "$PATH).\n"
#~ msgstr ""
-#~ "'VIMRUN.EXE' nie gevind in '$PATH' nie.\n"
-#~ "Eksterne opdragte sal nie wag na voltooiing nie\n"
-#~ "Sien ':help win32-vimrun' vir meer inligting."
+#~ "Kan nie 'n verbinding met 'SNiFF+' maak nie. Kyk of die omgewing reg is "
+#~ "('sniffemacs' moet in '$PATH' gevind word).\n"
-#~ msgid "Vim Warning"
-#~ msgstr "Vim Waarskuwing"
+#~ msgid "Generate docu for"
+#~ msgstr "Genereer 'docu' vir"
-#~ msgid "E56: %s* operand could be empty"
-#~ msgstr "E56: %s* operand mag leeg wees"
+#~ msgid "Show docu of"
+#~ msgstr "Wys 'docu' van"
-#~ msgid "E57: %s+ operand could be empty"
-#~ msgstr "E57: %s+ operand mag leeg wees"
+#~ msgid "Xref used by"
+#~ msgstr "Xref gebruik deur"
-#~ msgid "E58: %s{ operand could be empty"
-#~ msgstr "E58: %s{ operand mag leeg wees"
+#~ msgid "Xref has a"
+#~ msgstr "Xref het 'n"
-#~ msgid "E361: Crash intercepted; regexp too complex?"
-#~ msgstr "E361: Ineenstorting onderskep. Patroon te kompleks?"
+#~ msgid "Xref referred by"
+#~ msgstr "Xref verwys deur"
-#~ msgid "E363: pattern caused out-of-stack error"
-#~ msgstr "E363: patroon het lëe-stapel fout veroorsaak"
+#~ msgid "Xref refers to"
+#~ msgstr "Xref verwys na"
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: 'containedin' parameter nie hier aanvaar nie"
+#~ msgid "Show class in restricted hierarchy"
+#~ msgstr "Wys klas in beperkte hiërargie"
-#~ msgid "Enter nr of choice (<CR> to abort): "
-#~ msgstr "Sleutel nommer van keuse in (<CR> om te stop): "
+#~ msgid "Show class in hierarchy"
+#~ msgstr "Wys klas in hiërargie"
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Etiketlêergids afgekap vir %s\n"
+#~ msgid "Browse class"
+#~ msgstr "Kyk klas deur"
-#~ msgid "new shell started\n"
-#~ msgstr "nuwe dop begin\n"
+#~ msgid "Find symbol"
+#~ msgstr "Vind simbool"
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Geen herstel moontlik; gaan in elk geval voort"
+#~ msgid "Show source of"
+#~ msgstr "Wys kode van"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32-bis GUI weergawe"
+#~ msgid "Retrieve"
+#~ msgstr "Gaan haal"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32-bis GUI version"
+#~ msgid "Retrieve from all projects"
+#~ msgstr "Gaan haal uit alle projekte"
-#~ msgid " in Win32s mode"
-#~ msgstr " in Win32s modus"
+#~ msgid "Retrieve from project"
+#~ msgstr "Gaan haal uit projek"
-#~ msgid " with OLE support"
-#~ msgstr " met OLE ondersteuning"
+#~ msgid "Retrieve from file"
+#~ msgstr "Gaan haal uit lêer"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32-bis konsole weergawe"
+#~ msgid "Show overridden member function"
+#~ msgstr "Wys vervangde lidfunksie"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16-bis weergawe"
+#~ msgid "Show base class of"
+#~ msgstr "Wys basisklas van"
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32-bis MS-DOS weergawe"
+#~ msgid "Toggle implementation/definition"
+#~ msgstr "Stel en herstel implimentasie/definisie"
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16-bis MS-DOS weergawe"
+#~ msgid "E273: unknown longjmp status %d"
+#~ msgstr "E273: Onbekende 'longjmp' status %d"
#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
+#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
+#~ "loaded."
#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) weergawe"
+#~ "E266: Jammer, hierdie bevel is afgeskakel, die Ruby biblioteeklêer kon "
+#~ "nie gelaai word nie."
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X weergawe"
+#~ msgid "string cannot contain newlines"
+#~ msgstr "string kan nie 'newlines' bevat nie"
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS weergawe"
+#~ msgid "cannot insert line"
+#~ msgstr "kan reël nie byvoeg nie"
+
+#~ msgid "cannot replace line"
+#~ msgstr "kan reël nie vervang nie"
+
+#~ msgid "cannot delete line"
+#~ msgstr "kan reël nie verwyder nie"
+
+#~ msgid "no such window"
+#~ msgstr "geen sodanige venster nie"
+
+#~ msgid "<window %d>"
+#~ msgstr "<venster %d>"
+
+#~ msgid "<window object (unknown) at %.8lX>"
+#~ msgstr "<verwyder voorwerp (onbekend) by %.8lX>"
+
+#~ msgid "<window object (deleted) at %.8lX>"
+#~ msgstr "<venster voorwerp (geskrap) by %.8lX>"
+
+#~ msgid "cursor position outside buffer"
+#~ msgstr "loperposisie buite buffer"
+
+#~ msgid "readonly attribute"
+#~ msgstr "leesalleen eienskap"
+
+#~ msgid "attempt to refer to deleted window"
+#~ msgstr "poging om na geskrapte venster te verwys"
+
+#~ msgid "no such buffer"
+#~ msgstr "buffer bestaan nie"
+
+#~ msgid "invalid mark name"
+#~ msgstr "onbekende merknaam"
+
+#~ msgid "<buffer object (deleted) at %8lX>"
+#~ msgstr "<buffervoorwerp (geskrap) by %8lX>"
+
+#~ msgid "line number out of range"
+#~ msgstr "reëlnommer buite omvang"
+
+#~ msgid "attempt to refer to deleted buffer"
+#~ msgstr "poging om na 'n geskrapte buffer te verwys"
+
+#~ msgid "expressions disabled at compile time"
+#~ msgstr "uitdrukkings afgeskakel tydens kompilering"
+
+# njj: net 'n voorstel ..
+#~ msgid "invalid expression"
+#~ msgstr "ongeldige uitdrukking"
+
+#~ msgid "E264: Python: Error initialising I/O objects"
+#~ msgstr "E264: Python: Kon nie I/O objekte inwy nie"
+
+#~ msgid "writelines() requires list of strings"
+#~ msgstr "'writelines()' benodig 'n lys van stringe"
+
+#~ msgid "invalid attribute"
+#~ msgstr "ongeldige eienskap"
+
+#~ msgid "softspace must be an integer"
+#~ msgstr "'softspace' moet 'n heelgetal wees"
+
+#~ msgid "can't delete OutputObject attributes"
+#~ msgstr "kan nie 'OutputObject' eienskappe skrap nie"
+
+#~ msgid "E659: Cannot invoke Python recursively"
+#~ msgstr "E659: Kan nie Python rekursief roep nie"
#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
+#~ "E263: Sorry, this command is disabled, the Python library could not be "
+#~ "loaded."
#~ msgstr ""
-#~ "\n"
-#~ "RISC OS weergawe"
+#~ "E263: Jammer, hierdie bevel is afgeskakel, die Python biblioteek lêer kon "
+#~ "nie gelaai word nie."
+
+#~ msgid "E569: maximum number of cscope connections reached"
+#~ msgstr "E569: maksimum aantal 'cscope' verbindings bereik"
+
+#~ msgid "E626: cannot get cscope database information"
+#~ msgstr "E626: kan nie 'cscope' databasisinligting kry nie"
+
+#~ msgid "E625: cannot open cscope database: %s"
+#~ msgstr "E625: Kon nie 'cscope' databasis oopmaak nie: %s"
+
+#~ msgid "E563: stat error"
+#~ msgstr "E563: 'stat' fout"
+
+#~ msgid "E256: Hangul automata ERROR"
+#~ msgstr "E256: Hangul outomatiserings FOUT"
#~ msgid ""
+#~ "Font1 width: %<PRId64>\n"
#~ "\n"
-#~ "Big version "
#~ msgstr ""
+#~ "Font1 wydte: %<PRId64>\n"
#~ "\n"
-#~ "Groot weergawe "
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
+#~ msgid "Font0 width: %<PRId64>\n"
+#~ msgstr "Font0 wydte: %<PRId64>\n"
+
+#~ msgid "Font%<PRId64> width is not twice that of font0\n"
+#~ msgstr "Font%<PRId64> wydte is nie twee keer díe van font0 nie\n"
+
+#~ msgid "Font1: %s\n"
+#~ msgstr "Font1: %s\n"
+
+#~ msgid "Font0: %s\n"
+#~ msgstr "Font0: %s\n"
+
+#~ msgid "E253: Fontset name: %s\n"
+#~ msgstr "E253: Fonstel naam: %s\n"
+
+#~ msgid "Font '%s' is not fixed-width"
+#~ msgstr "Font '%s' is nie 'n vaste-wydte font nie"
+
+#~ msgid "E252: Fontset name: %s"
+#~ msgstr "E252: Fontstel naam: %s"
+
+#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
#~ msgstr ""
-#~ "\n"
-#~ "Normale weergawe "
+#~ "E250: Fonte vir die volgende karakterstelle ontbreek in fontversameling "
+#~ "%s:"
#~ msgid ""
-#~ "\n"
-#~ "Small version "
+#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
#~ msgstr ""
-#~ "\n"
-#~ "Klein weergawe "
+#~ "Vim E458: Kan nie kleurkaart-inskrywing toeken nie, sommige kleure mag "
+#~ "verkeerd wees"
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
+#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
+#~ msgstr "Vind & vervang string (gebruik '\\\\' om 'n '\\' te vind"
+
+#~ msgid "Find string (use '\\\\' to find a '\\')"
+#~ msgstr "Vind string (gebruik '\\\\' om 'n '\\' te vind"
+
+#~ msgid "E672: Unable to open window inside MDI application"
+#~ msgstr "E672: Kon nie venster oopmaak binne 'n MDI toepassing nie"
+
+#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+#~ msgstr "E243: Parameter nie bekend: \"-%s\"; Gebruik die OLE weergawe."
+
+#~ msgid "Undo"
+#~ msgstr "Herroep"
+
+#~ msgid "Selection"
+#~ msgstr "Seleksie"
+
+#~ msgid "Files"
+#~ msgstr "Lêers"
+
+#~ msgid "Help"
+#~ msgstr "Hulp"
+
+#~ msgid "Directories"
+#~ msgstr "Gidse"
+
+#~ msgid "Filter"
+#~ msgstr "Filter"
+
+#~ msgid "Used CUT_BUFFER0 instead of empty selection"
+#~ msgstr "'CUT_BUFFER0' is gebruik in plaas van leë seleksie"
+
+#~ msgid "Font Selection"
+#~ msgstr "Fontkeuse"
+
+#~ msgid "Vim: Main window unexpectedly destroyed\n"
+#~ msgstr "Vim: Hoofvenster onverwags verwoes\n"
+
+#~ msgid "Vim: Received \"die\" request from session manager\n"
+#~ msgstr "Vim: Het die \"die\" opdrag ontvang van sessiebestuurder\n"
+
+#~ msgid "Replace All"
+#~ msgstr "Vervang alles"
+
+#~ msgid "Replace"
+#~ msgstr "Vervang"
+
+#~ msgid "Find Next"
+#~ msgstr "Vind volgende"
+
+#~ msgid "Down"
+#~ msgstr "Af"
+
+#~ msgid "Up"
+#~ msgstr "Op"
+
+#~ msgid "Direction"
+#~ msgstr "Rigting"
+
+#~ msgid "Match case"
+#~ msgstr "Tref kas"
+
+#~ msgid "Match whole word only"
+#~ msgstr "Tref slegs presiese woord"
+
+#~ msgid "Replace with:"
+#~ msgstr "Vervang met:"
+
+#~ msgid "Find what:"
+#~ msgstr "Soek na:"
+
+#~ msgid "VIM - Search..."
+#~ msgstr "VIM - Soek..."
+
+#~ msgid "VIM - Search and Replace..."
+#~ msgstr "VIM - Soek en Vervang..."
+
+#~ msgid "Input _Methods"
+#~ msgstr "Invoer _Metodes"
+
+#~ msgid "Vim dialog..."
+#~ msgstr "Vim dialooghokkie..."
+
+#~ msgid "E599: Value of 'imactivatekey' is invalid"
+#~ msgstr "E599: Waarde van 'imactivatekey' is ongeldig"
+
+#~ msgid "E231: 'guifontwide' invalid"
+#~ msgstr "E231: 'guifontwide' ongeldig"
+
+#~ msgid "E665: Cannot start GUI, no valid font found"
+#~ msgstr "E665: Kan nie GUI begin nie, geen geldige font gevind nie"
+
+#~ msgid "E230: Cannot read from \"%s\""
+#~ msgstr "E230: Kan nie lees uit \"%s\" nie"
+
+#~ msgid "E229: Cannot start the GUI"
+#~ msgstr "E229: Kan nie die GUI begin nie"
+
+#~ msgid "E232: Cannot create BalloonEval with both message and callback"
+#~ msgstr "E232: Kan nie BalloonEval skep met beide boodskap en terugroep nie"
+
+#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
#~ msgstr ""
-#~ "\n"
-#~ "Piepklein weergawe "
+#~ "Rolstaafelement: Kon nie pikselmatriks-duimnael se geometrie kry nie"
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "met GTK2-GNOME GUI."
+#~ msgid "Vim dialog"
+#~ msgstr "Vim dialooghokkie"
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "met GTK-GNOME GUI."
+#~ msgid "Cancel"
+#~ msgstr "Kanselleer"
-#~ msgid "with GTK2 GUI."
-#~ msgstr "met GTK2 GUI"
+#~ msgid "OK"
+#~ msgstr "OK"
-#~ msgid "with GTK GUI."
-#~ msgstr "met GTK GUI"
+#~ msgid "E615: vim_SelFile: can't get current directory"
+#~ msgstr "E615: vim_SelFile: Kan nie huidige gids verkry nie"
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "met X11-Motif GUI."
+#~ msgid "Pathname:"
+#~ msgstr "Gidsnaam:"
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "met X11-neXtaw GUI"
+#~ msgid "E614: vim_SelFile: can't return to current directory"
+#~ msgstr "E614: 'vim_SelFile': Kan nie terugkeer na huidige gids nie"
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "met X11-Athena GUI"
+#~ msgid "E616: vim_SelFile: can't get font %s"
+#~ msgstr "E616: 'vim_SelFile': kan font %s nie kry nie"
-#~ msgid "with BeOS GUI."
-#~ msgstr "met BeOS GUI"
+#~ msgid "<cannot open> "
+#~ msgstr "<kan nie oopmaak nie> "
-#~ msgid "with Photon GUI."
-#~ msgstr "met Photon GUI."
+#~ msgid "E460: The resource fork would be lost (add ! to override)"
+#~ msgstr "E460: Die hulpbronvurk sal verlore gaan (gebruik ! om te dwing)"
-#~ msgid "with GUI."
-#~ msgstr "met GUI."
+#~ msgid "Partial writes disallowed for NetBeans buffers"
+#~ msgstr "Gedeeltelike skryf word nie toegelaat vir NetBeans buffers nie"
-#~ msgid "with Carbon GUI."
-#~ msgstr "met Carbon GUI."
+#~ msgid "NetBeans disallows writes of unmodified buffers"
+#~ msgstr "NetBeans laat nie skryf toe van onveranderde buffers nie"
-#~ msgid "with Cocoa GUI."
-#~ msgstr "met Cocoa GUI."
+#~ msgid "[CONVERSION ERROR]"
+#~ msgstr "[OMSETTINGSFOUT]"
-#~ msgid "with (classic) GUI."
-#~ msgstr "met (klassieke) GUI."
+#~ msgid "[crypted]"
+#~ msgstr "[gekodeer]"
-#~ msgid " system gvimrc file: \""
-#~ msgstr " stelsel gvimrc-lêer: \""
+#~ msgid "[NL found]"
+#~ msgstr "[NL gevind]"
-#~ msgid " user gvimrc file: \""
-#~ msgstr " gebruiker gvimrc-lêer: \""
+#~ msgid "E196: No digraphs in this version"
+#~ msgstr "E196: Geen digrawe in hierdie weergawe nie"
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "2de gebruiker gvimrc-lêer: \""
+#~ msgid "Save Setup"
+#~ msgstr "Stoor konfigurasie"
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "3de gebruiker gvimrc-lêer: \""
+#~ msgid "Save Session"
+#~ msgstr "Stoor Sessie"
-#~ msgid " system menu file: \""
-#~ msgstr " stelsel kieslys-lêer: \""
+#~ msgid "Save View"
+#~ msgstr "Stoor Oorsig"
-#~ msgid "Compiler: "
-#~ msgstr "Kompileerder: "
+#~ msgid "Save Redirection"
+#~ msgstr "Stoor Herversturing"
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "menu Hulp->Weeskinders vir meer inligting hieroor "
+#~ msgid "Window position: X %d, Y %d"
+#~ msgstr "Vensterposisie: X %d, Y %d"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Voer modus-loos uit, getikte teks word ingevoeg"
+#~ msgid "Append File"
+#~ msgstr "Las aan by lêer"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "menu Redigeer->Globale verstellings->Stel en herstel Invoeg Modus"
+#~ msgid "Edit File in new window"
+#~ msgstr "Bewerk lêer in nuwe venster"
-#~ msgid " for two modes "
-#~ msgstr " vir twee modusse "
+#~ msgid " (NOT FOUND)"
+#~ msgstr " (NIE GEVIND NIE)"
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "menu Redigeer->Global verstellings->Stel en herstel Vi Versoenbaar"
+#~ msgid "Edit File"
+#~ msgstr "Verander lêer"
-#~ msgid " for Vim defaults "
-#~ msgstr " vir Vim verstekwaardes"
+#~ msgid "Source Vim script"
+#~ msgstr "Voer Vim skrip uit"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "WAARSKUWING: Windows 95/98/ME bespeur"
+#~ msgid "Save As"
+#~ msgstr "Stoor As"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "tik :help windows95<Enter> vir meer inligting hieroor"
+#~ msgid "E130: Undefined function: %s"
+#~ msgstr "E130: Ongedefinieerde funksie: %s"
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Kon nie biblioteek laai nie %s"
+#~ msgid "E277: Unable to read a server reply"
+#~ msgstr "E277: Kon bediener-terugvoer nie lees nie"
+
+#~ msgid "E240: No connection to Vim server"
+#~ msgstr "E240: Geen verbinding met Vim bediener"
#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
+#~ "&OK\n"
+#~ "&Cancel"
#~ msgstr ""
-#~ "Jammer, hierdie bevel is afgeskakel: die Perl biblioteek kon nie gelaai "
-#~ "word nie."
+#~ "&OK\n"
+#~ "&Kanselleer"
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Perl evaluasie verbied in die sandput sonder die 'Safe' module"
+#~ msgid "E106: Unknown variable: \"%s\""
+#~ msgstr "E106: Onbekende veranderlike: \"%s\""
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Wysig met &meer as een Vim"
+#~ msgid "Patch file"
+#~ msgstr "Laslap lêer"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Wysig met 'n enkel &Vim"
+#~ msgid "[No File]"
+#~ msgstr "[Geen lêer]"
-#~ msgid "&Diff with Vim"
-#~ msgstr "Wys verskille ('&diff') met Vim"
+#~ msgid "[Error List]"
+#~ msgstr "[Foutlys]"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Wysig met &Vim"
+#~ msgid "type :help cp-default<Enter> for info on this"
+#~ msgstr "tik :help cp-default<Enter> vir meer inligting hieroor"
-#~ msgid "Edit with existing Vim - &"
-#~ msgstr "Wysig met bestaande Vim - &"
+#~ msgid "type :set nocp<Enter> for Vim defaults"
+#~ msgstr "tik :set nocp<Enter> vir Vim verstekwaardes "
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Wysig die gekose lêer(s) met Vim"
+#~ msgid "Running in Vi compatible mode"
+#~ msgstr "Voer tans uit in Vi-versoenbare modus"
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "FOut met die skep van proses: Kyk of gvim in jou pad is!"
+#~ msgid "type :help version7<Enter> for version info"
+#~ msgstr "tik :help version7<Enter> vir weergawe-inligting"
-#~ msgid "gvimext.dll error"
-#~ msgstr "'gvimext.dll' fout"
+#~ msgid "type :help<Enter> or <F1> for on-line help"
+#~ msgstr "tik :help<Enter> of <F1> vir aanlyn hulp "
-#~ msgid "Path length too long!"
-#~ msgstr "Pad-lengte te lank"
+#~ msgid "by Bram Moolenaar et al."
+#~ msgstr "deur Bram Moolenaar et al."
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Onbekende fontstel: %s"
+# njj: :))
+#~ msgid "version "
+#~ msgstr "Weergawe "
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Onbekende font: %s"
+#~ msgid "VIM - Vi IMproved"
+#~ msgstr "VIM - Vi Met skop"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Kon nie biblioteek funksie laai nie %s"
+#~ msgid " DEBUG BUILD"
+#~ msgstr " ONTFOUTINGS-KOMPILERING"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+#~ msgid "Linking: "
+#~ msgstr "Koppeling: "
+
+#~ msgid "Compilation: "
+#~ msgstr "Kompilering: "
+
+#~ msgid " 2nd user exrc file: \""
+#~ msgstr " 2de gebruiker exrc-lêer: \""
+
+#~ msgid " user exrc file: \""
+#~ msgstr " gebruiker exrc-lêer: \""
+
+#~ msgid " 3rd user vimrc file: \""
+#~ msgstr " 3de gebruiker vimrc-lêer \""
+
+#~ msgid " 2nd user vimrc file: \""
+#~ msgstr " 2de gebruiker vimrc-lêer \""
+
+#~ msgid " user vimrc file: \""
+#~ msgstr " gebruiker vimrc-lêer: \""
+
+#~ msgid " Features included (+) or not (-):\n"
+#~ msgstr " Kenmerke in- (+) of uitgesluit (-):\n"
+
+#~ msgid "without GUI."
+#~ msgstr "sonder GUI."
+
+#~ msgid ""
+#~ "\n"
+#~ "Huge version "
#~ msgstr ""
-#~ "E26: Hebreeus kan nie gebruik word nie: Nie tydens kompilering gekies "
-#~ "nie\n"
+#~ "\n"
+#~ "Enorme weergawe "
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+#~ msgid "Modified by "
+#~ msgstr "Gewysig deur "
+
+#, fuzzy
+#~ msgid ""
+#~ "\n"
+#~ "Extra patches: "
+#~ msgstr "Eksterne subtreffers:\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "Included patches: "
#~ msgstr ""
-#~ "E27: Farsi kan nie gebruik word nie: Nie tydens kompilering gekies nie\n"
+#~ "\n"
+#~ "Ingeslote laslappies:"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+#~ msgid ""
+#~ "\n"
+#~ "--- Terminal keys ---"
#~ msgstr ""
-#~ "E800: Arabies kan nie gebruik word nie: Nie tydens kompilering gekies "
-#~ "nie\n"
+#~ "\n"
+#~ "--- Terminaal sleutels ---"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: geen geregistreerde bediener genaamd \"%s\""
+#~ msgid "E437: terminal capability \"cm\" required"
+#~ msgstr "E437: terminaalvermoë \"cm\" vereis"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: kan nie vertoonskerm oopmaak nie"
+#~ msgid "E436: No \"%s\" entry in termcap"
+#~ msgstr "E436: Geen \"%s\" inskrywing in termcap nie"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Omgewing is onder bewaking, kan nie verander nie"
+#~ msgid "E559: Terminal entry not found in termcap"
+#~ msgstr "E559: Terminaalinskrywing nie in 'termcap' gevind nie"
-#~ msgid "function "
-#~ msgstr "funksie "
+#~ msgid "E558: Terminal entry not found in terminfo"
+#~ msgstr "E558: Terminaalinskrywing nie in 'terminfo' gevind nie"
-#~ msgid "Run Macro"
-#~ msgstr "Voer Makro uit"
+#~ msgid "E557: Cannot open termcap file"
+#~ msgstr "E557: Kan nie 'termcap'-lêer oopmaak nie"
-#~ msgid "E242: Color name not recognized: %s"
-#~ msgstr "E242: Kleurnaam is onbekend: %s"
+#~ msgid "defaulting to '"
+#~ msgstr "gebruik verstek '"
-#~ msgid "error reading cscope connection %d"
-#~ msgstr "'cscope' verbinding %d kon nie gelees word nie"
+#~ msgid "' not known. Available builtin terminals are:"
+#~ msgstr "' onbekend. Beskikbare ingeboude terminale is:"
-#~ msgid "E260: cscope connection not found"
-#~ msgstr "E260: 'cscope' verbinding nie gevind nie"
+#~ msgid "E422: terminal code too long: %s"
+#~ msgstr "E422: terminaalkode te lank: %s"
-#~ msgid "cscope connection closed"
-#~ msgstr "'cscope' verbinding gesluit"
+#, fuzzy
+#~ msgid "Substitute "
+#~ msgstr "1 vervanging"
-# njj: dalk 'verbinding' ipv 'verbinding' orals?
-#~ msgid "couldn't malloc\n"
-#~ msgstr "kon nie 'malloc' nie\n"
+#~ msgid " (lang)"
+#~ msgstr " (taal)"
-#~ msgid "%2d %-5ld %-34s <none>\n"
-#~ msgstr "%2d %-5ld %-34s <geen>\n"
+#~ msgid ""
+#~ "\n"
+#~ "Cannot execute shell "
+#~ msgstr ""
+#~ "\n"
+#~ "Kan nie dop uitvoer nie "
-#~ msgid "E249: couldn't read VIM instance registry property"
-#~ msgstr "E249: kon nie VIM instansie register-kenmerk lees nie"
+#~ msgid "E522: Not found in termcap"
+#~ msgstr "E522: Nie gevind in 'termcap' nie"
-#~ msgid "\"\n"
-#~ msgstr "\"\n"
+#~ msgid "Thanks for flying Vim"
+#~ msgstr "Dankie dat jy vlieg met Vim"
-#~ msgid "--help\t\tShow Gnome arguments"
-#~ msgstr "--help\t\tWys Gnome parameters"
+#~ msgid "%<%f%h%m%=Page %N"
+#~ msgstr "%<%f%h%m%=Bladsy %N"
-#~ msgid "1 line ~ed"
-#~ msgstr "1 reël ge-~"
+#~ msgid "E574: Unknown register type %d"
+#~ msgstr "E574: Onbekende registertipe %d"
-#~ msgid "%<PRId64> lines ~ed"
-#~ msgstr "%<PRId64> reëls ge-~"
+#~ msgid ""
+#~ "\n"
+#~ "# Registers:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Registers:\n"
-#~ msgid " BLOCK"
-#~ msgstr " BLOK"
+#~ msgid "Illegal register name"
+#~ msgstr "Ongeldige registernaam"
-#~ msgid " LINE"
-#~ msgstr " REËL"
+#~ msgid "cannot yank; delete anyway"
+#~ msgstr "kan nie pluk nie: verwyder in elk geval"
-#~ msgid "Linear tag search"
-#~ msgstr "Liniêre etiketsoek"
+#~ msgid "E337: Menu not found - check menu names"
+#~ msgstr "E337: Kieslys nie gevind nie - maak seker oor die kieslys name"
-#~ msgid "Binary tag search"
-#~ msgstr "Binêre etiketsoek"
+#~ msgid "E336: Menu path must lead to a sub-menu"
+#~ msgstr "E336: Kieslyspad moet lei na 'n sub-kieslys"
-#~ msgid "E258: no matches found in cscope connections"
-#~ msgstr "E258: geen treffers gevind in 'cscope' verbindings nie"
+#~ msgid "Swap file already exists!"
+#~ msgstr "Ruillêer bestaan alreeds!"
-#~ msgid "No servers found for this display"
-#~ msgstr "Geen bedieners gevind vir die 'display' nie"
+#, fuzzy
+#~ msgid " Quit, or continue with caution.\n"
+#~ msgstr " Stop, of gaan versigtig voort.\n"
-#~ msgid "Missing filename"
-#~ msgstr "Ontbrekende lêernaam"
+#~ msgid "Missing '>'"
+#~ msgstr "Ontbrekende '>'"
-#~ msgid "Invalid line number: %<PRId64>"
-#~ msgstr "Ongeldige reëlnommer: %<PRId64>"
+#~ msgid ""
+#~ "\n"
+#~ "# History of marks within files (newest to oldest):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Geskiedenis van merkers in lêers (nuutste tot oudste):\n"
-#~ msgid "Cannot use :normal from event handler"
-#~ msgstr "Kan ':normal' nie vanuit gebeurtenishanteerder gebruik nie"
+#~ msgid ""
+#~ "\n"
+#~ "# Jumplist (newest first):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Springlys (nuutste eerste):\n"
-#~ msgid "VIM - Help on..."
-#~ msgstr "VIM - Hulp met.."
+#~ msgid ""
+#~ "\n"
+#~ "# File marks:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Lêermerkers:\n"
-#~ msgid "Topic:"
-#~ msgstr "Onderwerp:"
+#~ msgid "-h or --help\tPrint Help (this message) and exit"
+#~ msgstr "-h of --help\tSkryf Hulp (hierdie boodskap) en sluit"
-#~ msgid "Error: During loading fontset %s"
-#~ msgstr "Fout: Gedurende die laai van fontstel %s"
+#~ msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+#~ msgstr "-i <viminfo>\t\tGebruik <viminfo> in plaas van .viminfo"
-#~ msgid "locale is not set correctly"
-#~ msgstr "lokaal is nie korrek gestel nie"
+#~ msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+#~ msgstr "-W <skripuit>\tSkryf alle getikte bevele na lêer <skripuit>"
-#~ msgid "For korean:"
-#~ msgstr "Vir Afrikaans:"
+#~ msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+#~ msgstr "-w <skripuit>\tLas alle getikte bevele aan by lêer <skripuit>"
-#~ msgid " csh: setenv LANG ko"
-#~ msgstr " csh: setenv LANG af"
+#~ msgid "+<lnum>\t\tStart at line <lnum>"
+#~ msgstr "+<lnum>\t\tBegin by reël <lnum>"
-#~ msgid " sh : export LANG=ko"
-#~ msgstr " sh: export LANG=af"
+#~ msgid "+\t\t\tStart at end of file"
+#~ msgstr "+\t\t\tBegin by einde van lêer"
-#~ msgid "fontset name: %s"
-#~ msgstr "fontstel naam: %s"
+#~ msgid "-O[N]\t\tLike -o but split vertically"
+#~ msgstr "-O[N]\t\tSoos -o maar verdeel vertikaal"
-#~ msgid "Your language Font missing"
-#~ msgstr "Jou taal Font ontbreek"
+#~ msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+#~ msgstr "-u <vimrc>\t\tGebruik <vimrc> in plaas van enige ander .vimrc"
-#~ msgid "automata ERROR: internal"
-#~ msgstr "automata FOUT: intern"
+#~ msgid "-T <terminal>\tSet terminal type to <terminal>"
+#~ msgstr "-T <terminaal>\tStel terminaaltipe na <terminaal>"
-#~ msgid "cs_add_common: alloc fail #1"
-#~ msgstr "'cs_add_common': toeken onsuksesvol #1"
+#~ msgid "-F\t\t\tStart in Farsi mode"
+#~ msgstr "-F\t\t\tBegin in Farsi modus"
-#~ msgid "cs_add_common: alloc fail #2"
-#~ msgstr "'cs_add_common': toeken onsuksesvol #2"
+#~ msgid "-H\t\t\tStart in Hebrew mode"
+#~ msgstr "-H\t\t\tBegin in Hebreeuse modus"
-#~ msgid "cs_add_common: alloc fail #3"
-#~ msgstr "'cs_add_common': toeken onsuksesvol #3"
+#~ msgid "-A\t\t\tstart in Arabic mode"
+#~ msgstr "-A\t\t\tbegin in Arabiese modus"
-#~ msgid "cs_add_common: alloc fail #4"
-#~ msgstr "'cs_add_common': toeken onsuksesvol #4"
+#~ msgid "-L\t\t\tSame as -r"
+#~ msgstr "-L\t\t\tSelfde as -r"
-#~ msgid "Retrieve next symbol"
-#~ msgstr "Kry volgende simbool"
+#~ msgid "-r (with file name)\tRecover crashed session"
+#~ msgstr "-r (met lêer naam)\tHerwin ineengestorte sessie"
-#~ msgid "-- SNiFF+ commands --"
-#~ msgstr "-- SNiFF+ bevele --"
+#~ msgid "-r\t\t\tList swap files and exit"
+#~ msgstr "-r\t\t\tLys ruillêers en verlaat vim"
-#~ msgid "Unrecognized sniff request [%s]"
-#~ msgstr "Onbekende sniff versoek [%s]"
+#~ msgid "-D\t\t\tDebugging mode"
+#~ msgstr "-D\t\t\tOntfoutmodus"
-#~ msgid "Can't create input context."
-#~ msgstr "Kan nie invoerkonteks skep nie."
+#~ msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+#~ msgstr "-N\t\t\tNie ten volle Vi-versoenbaar nie: 'nocompatible'"
-#~ msgid "Sorry, deleting a menu is not possible in the Athena version"
-#~ msgstr ""
-#~ "Jammer, in die Athena weergawe is dit onmoontlik om 'n kieslys te skrap"
+#~ msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+#~ msgstr "-C\t\t\tVersoenbaar met Vi: 'compatible'"
-#~ msgid "Out of memory"
-#~ msgstr "Geheue op"
+#~ msgid "-l\t\t\tLisp mode"
+#~ msgstr "-l\t\t\tLisp modus"
-#~ msgid "PC (32 bits Vim)"
-#~ msgstr "PC (32 bisse Vim)"
+#~ msgid "-b\t\t\tBinary mode"
+#~ msgstr "-b\t\t\tBinêre modus"
-#~ msgid "PC (16 bits Vim)"
-#~ msgstr "PC (16 bisse Vim)"
+#~ msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+#~ msgstr "-Z\t\t\tBeperkte modus (soos \"rvim\")"
-#~ msgid "Unsupported screen mode"
-#~ msgstr "Ongesteunde skermmodus"
+#~ msgid "-R\t\t\tReadonly mode (like \"view\")"
+#~ msgstr "-R\t\t\tLeesalleen modus (soos \"view\")"
-#~ msgid "deadly signal"
-#~ msgstr "dodelike sein"
+#~ msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+#~ msgstr "-y\t\t\tEasy modus (soos \"evim\", modusloos)"
-#~ msgid "some"
-#~ msgstr "sommige"
+#~ msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+#~ msgstr "-d\t\t\tDiff modus (soos \"vimdiff\")"
-#~ msgid "Library call failed"
-#~ msgstr "Biblioteekfunksieroep het gefaal"
+#~ msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+#~ msgstr "-s\t\t\tStil (bondel) modus (slegs vir \"ex\")"
-#~ msgid "Cannot clear all highlight groups"
-#~ msgstr "Kan nie alle uitliggroepe leegmaak nie"
+#~ msgid "-e\t\t\tEx mode (like \"ex\")"
+#~ msgstr "-e\t\t\tEx modus (soos \"ex\")"
-#~ msgid "GUI is not running"
-#~ msgstr "GUI voer nie uit nie"
+#~ msgid "-v\t\t\tVi mode (like \"vi\")"
+#~ msgstr "-v\t\t\tVi modus (soos \"vi\")"
-#~ msgid "Command too long"
-#~ msgstr "Bevel te lank"
+#~ msgid ""
+#~ "\n"
+#~ "\n"
+#~ "Arguments:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "\n"
+#~ "Parameters:\n"
-#~ msgid "Ambiguous mapping"
-#~ msgstr "Dubbelsinnige binding"
+#~ msgid ""
+#~ "\n"
+#~ " or:"
+#~ msgstr ""
+#~ "\n"
+#~ " of:"
-#~ msgid "Ambiguous mapping, conflicts with \"%s\""
-#~ msgstr "Dubbelsinnige binding, bots met \"%s\""
+#~ msgid " vim [arguments] "
+#~ msgstr " vim [parameters] "
-#~ msgid "Too many \\("
-#~ msgstr "Te veel \\("
+#~ msgid "%d files to edit\n"
+#~ msgstr "%d lêers om te bewerk\n"
-#~ msgid "Unmatched \\("
-#~ msgstr "Onpaar \\("
+#~ msgid "Invalid argument for"
+#~ msgstr "Ongeldige parameter vir"
-#~ msgid "Nested *, \\=, \\+, \\! or \\{"
-#~ msgstr "Geneste *, \\=, \\+, \\! of \\{"
+#~ msgid "Zero count"
+#~ msgstr "Nul telling"
-#~ msgid "\\= follows nothing"
-#~ msgstr "\\= volg niks"
+#~ msgid "Nvim: Reading from stdin...\n"
+#~ msgstr "Vim: Lees nou vanaf 'stdin'...\n"
-#~ msgid "\\+ follows nothing"
-#~ msgstr "\\+ volg niks"
+#~ msgid "Input Line"
+#~ msgstr "Invoer Lyn"
-#~ msgid "\\@ follows nothing"
-#~ msgstr "\\@ volg niks"
+#~ msgid "Expression"
+#~ msgstr "Uitdrukking"
-#~ msgid "\\{ follows nothing"
-#~ msgstr "\\{ volg niks"
+#~ msgid "Search String"
+#~ msgstr "Soekstring"
-#~ msgid "\\* follows nothing"
-#~ msgstr "\\* volg niks"
+#~ msgid "Command Line"
+#~ msgstr "Bevelreël"
-#~ msgid "Unexpected magic character; check META."
-#~ msgstr "Onverwagte toorkarakter; kyk na META."
+#~ msgid ""
+#~ "\n"
+#~ "# %s History (newest to oldest):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# %s Geskiedenis (van nuutste na oudste):\n"
-#~ msgid "type :help uganda<Enter> if you like Vim "
-#~ msgstr "tik :help uganda<Enter> as jy hou van Vim "
+#~ msgid "E195: Cannot open viminfo file for reading"
+#~ msgstr "E195: Kan 'viminfo' lêer nie oopmaak om te lees nie"
-#~ msgid " WARNING: Intel CPU detected. "
-#~ msgstr " WAARSKUWING: Intel SVE bespeur. "
+#~ msgid "E466: :winpos requires two number arguments"
+#~ msgstr "E466: :winpos benodig twee parameters"
-#~ msgid " PPC has a much better architecture. "
-#~ msgstr " PPC het 'n veel beter argitektuur. "
+#~ msgid "E188: Obtaining window position not implemented for this platform"
+#~ msgstr ""
+#~ "E188: Verkryging van vensterposisie is nie vir hierdie platform "
+#~ "geïmplementeer nie"
-#~ msgid "Security error: new viminfo file is a symbolic link"
-#~ msgstr "Sekuriteitsfout: nuwe viminfo lêer is a simboliese skakel"
+#, fuzzy
+#~ msgid ""
+#~ "E747: Cannot change directory, buffer is modified (add ! to override)"
+#~ msgstr "E509: Kan rugsteunlêer nie skep nie (gebruik ! om te dwing)"
-#~ msgid "line ~%<PRId64>: %s"
-#~ msgstr "reël ~%<PRId64>: %s"
+#~ msgid "E172: Only one file name allowed"
+#~ msgstr "E172: Slegs een lêernaam toegelaat"
-#~ msgid "makeef option not set"
-#~ msgstr "'makeef' opsie nie aan nie"
+#~ msgid ""
+#~ "\n"
+#~ "# Last Substitute String:\n"
+#~ "$"
+#~ msgstr ""
+#~ "\n"
+#~ "# Vorige Vervangstring:\n"
+#~ "$"
-#~ msgid "Security error: filter output is a symbolic link: %s"
-#~ msgstr "Sekuriteitsfout: filter afvoer is 'n simboliese skakel"
+#~ msgid "Illegal starting char"
+#~ msgstr "Ongeldige beginkarakter"
-#~ msgid "Security error: 'charconvert' output is a symbolic link"
-#~ msgstr "Sekuriteitsfout: 'charconvert' afvoer is 'n simboliese skakel"
+#~ msgid "# Value of 'encoding' when this file was written\n"
+#~ msgstr "# Waarde van 'encoding' toe hierdie lêer gestoor is\n"
-#~ msgid "Security error: filter input is a symbolic link: %s"
-#~ msgstr "Sekuriteitsfout: filter invoer is 'n simboliese skakel"
+#~ msgid ""
+#~ "# You may edit it if you're careful!\n"
+#~ "\n"
+#~ msgstr ""
+#~ "# Jy mag dit wysig as jy versigtig is!\n"
+#~ "\n"
-#~ msgid "Fold must be at least two lines"
-#~ msgstr "'n Vou moet ten minste 2 reëls wees"
+#~ msgid "# This viminfo file was generated by Vim %s.\n"
+#~ msgstr "# Hierdie viminfo lêer is gegenereer deur Vim %s.\n"
-#~ msgid "No fold at this line"
-#~ msgstr "Geen vou by hierdie reël nie"
+#~ msgid "E138: Can't write viminfo file %s!"
+#~ msgstr "E138: Kan nie viminfo lêer %s stoor nie!"
-#~ msgid "Security error: shell command output is a symbolic link"
-#~ msgstr "Sekuriteitsfout: Dop-bevel afvoer is 'n simboliese skakel"
+#~ msgid "E136: viminfo: Too many errors, skipping rest of file"
+#~ msgstr "E136: viminfo: Te veel foute, slaan die res van die lêer oor"
-#~ msgid "Warning: %s option changed from modeline"
-#~ msgstr "Waarskuwing: %s opsie verander vanaf moduslyn"
+#~ msgid "%sviminfo: %s in line: "
+#~ msgstr "%sviminfo: %s in reël: "
-#~ msgid "Change dir debugging enabled."
-#~ msgstr "Verandergids ontfouting in staat gestel"
+#~ msgid ""
+#~ "\n"
+#~ "# global variables:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# globale veranderlikes:\n"
-#~ msgid "Not a proper file name: '%s'"
-#~ msgstr "Nie 'n geldige lêernaam nie: '%s'"
+#, fuzzy
+#~ msgid "E706: Variable type mismatch for: %s"
+#~ msgstr "E93: Meer as een treffer vir %s"
-#~ msgid "File name '%s' is valid"
-#~ msgstr "lêernaam '%s is ongeldig"
+#, fuzzy
+#~ msgid "E724: variable nested too deep for displaying"
+#~ msgstr "E22: Skripte te diep ge-nes"
-#~ msgid "Leave: %s"
-#~ msgstr "Verlaat: %s"
+#~ msgid ""
+#~ "\n"
+#~ "# Buffer list:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Buffer lys:\n"
-#~ msgid "WARNING: tag command changed a buffer!!!"
-#~ msgstr "WAARSKUWING: etiketbevel het buffer verander!!!"
+#, fuzzy
+#~ msgid "Unable to get option value"
+#~ msgstr "E258: Kan nie na kliënt stuur nie"
diff --git a/src/nvim/po/ca.po b/src/nvim/po/ca.po
index 79434cfdcd..7e83cb08ed 100644
--- a/src/nvim/po/ca.po
+++ b/src/nvim/po/ca.po
@@ -299,7 +299,7 @@ msgstr "E100: No hi ha cap altre buffer en mode diff"
#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr "E101: Hi ha més de 2 buffers en mode diff, no se sap quin usar"
+msgstr "E101: Hi ha més de 2 buffers en mode diff"
#: ../diff.c:2141
#, c-format
@@ -1095,7 +1095,7 @@ msgstr "%<PRId64> línies filtrades"
#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: Les auto-ordres *Filter* no poden canviar el buffer actual"
+msgstr "E135: Les ordres automàtiques *Filter* han de no modificar el buffer"
#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
@@ -1582,7 +1582,7 @@ msgstr "E605: No s'ha interceptat l'excepció: %s"
#: ../ex_docmd.c:1085
msgid "End of sourced file"
-msgstr "Final del fitxer interpretat"
+msgstr "Final de l'script"
#: ../ex_docmd.c:1086
msgid "End of function"
@@ -1881,7 +1881,7 @@ msgstr "%s s'ha descartat"
#: ../ex_eval.c:708
msgid "Exception"
-msgstr "Exepció"
+msgstr "Excepció"
#: ../ex_eval.c:713
msgid "Error and interrupt"
@@ -2162,7 +2162,7 @@ msgstr "[ERRORS DE LECTURA]"
#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
-msgstr "No s'ha trobat el fitxer temporal per la conversió"
+msgstr "No s'ha trobat el fitxer temporal per a fer la conversió"
#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
@@ -2298,7 +2298,7 @@ msgstr "E205: patchmode: no s'ha pogut desar el fitxer original"
#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: patchmode: no s'ha pogut tocar el fitxer original buit"
+msgstr "E206: patchmode: no s'ha pogut fer un toc al fitxer original buit"
#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
@@ -2308,9 +2308,7 @@ msgstr "E207: No s'ha pogut eliminar la còpia de seguretat"
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"ATENCIÓ: El fitxer original es pot haver fet malbé\n"
+msgstr "\nATENCIÓ: El fitxer original es pot haver perdut o fet malbé\n"
#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
@@ -2460,7 +2458,7 @@ msgstr ""
#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: No s'han pogut fer les preparacions per rellegir \"%s\""
+msgstr "E462: No s'han pogut fer les preparacions per a rellegir \"%s\""
#: ../fileio.c:5078
#, c-format
@@ -2536,7 +2534,7 @@ msgstr "Executant %s"
#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
-msgstr "auto-ordre %s"
+msgstr "ordre automàtica %s"
#: ../fileio.c:7795
msgid "E219: Missing {."
@@ -2717,11 +2715,6 @@ msgstr "E49: La distància de desplaçament no és vàlida"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3048,7 +3041,7 @@ msgstr "No hi ha text per imprimir"
#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
-msgstr "S'està imprimint la pàgina %d (%d%%)"
+msgstr "Imprimint la pàgina %d (%d%%)"
#: ../hardcopy.c:680
#, c-format
@@ -3062,7 +3055,7 @@ msgstr "S'ha imprès: %s"
#: ../hardcopy.c:740
msgid "Printing aborted"
-msgstr "S'ha avortat l'impressió"
+msgstr "S'ha avortat la impressió"
#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
@@ -3319,7 +3312,7 @@ msgstr "E609: Error de cscope: %s"
#: ../if_cscope.c:2053
msgid "All cscope databases reset"
-msgstr "S'han reiniciat totes les bases de dades cscope"
+msgstr "S'han restablert totes les bases de dades cscope"
#: ../if_cscope.c:2123
msgid "no cscope connections\n"
@@ -3416,7 +3409,7 @@ msgstr "-q [ftxerrors] edita el fitxer on hi ha el primer error"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -3522,7 +3515,7 @@ msgstr "-n\t\t\tNo usa fitxers d'intercanvi, només memòria"
#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tLlista els fitxers d'intercanvi i surt"
+msgstr "-r\t\t\tLlistat dels fitxers d'intercanvi"
#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
@@ -3554,7 +3547,7 @@ msgstr "-u <vimrc>\t\tUsa <vimrc> en lloc de qualsevol altre .vimrc"
#: ../main.c:2226
msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tNo carrega cap plugin"
+msgstr "--noplugin\t\tNo carrega plugins"
#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
@@ -3566,7 +3559,7 @@ msgstr "-o[N]\t\tObre N finestres (per omissió: una per fitxer)"
#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tCom -o però amb divisions verticals"
+msgstr "-O[N]\t\tCom -o però amb divisió vertical"
#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
@@ -3744,7 +3737,7 @@ msgstr "E305: No s'ha trobat el fitxer d'intercanvi de %s"
#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
-msgstr "Entreu el número del fitxer d'intercanvi a utilitzar (0 per sortir): "
+msgstr "Entreu el número del fitxer .swp a utilitzar (0 per a sortir): "
#: ../memline.c:879
#, c-format
@@ -3812,6 +3805,30 @@ msgstr "E308: Atenció: El fitxer original pot haver canviat"
#: ../memline.c:1061
#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "El fitxer d'intercanvi està xifrat: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr "\nSi vau entrar una nova clau de xifrat però no vau desar el fitxer,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr "\nentreu la nova clau."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr "\nSi vau desar el fitxer després de canviar la clau, premeu Entrar per a"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr "\nusar la mateixa clau per al fitxer de text i per al fitxer d'intercanvi."
+
+#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: No s'ha pogut llegir el bloc 1 de %s"
@@ -3936,7 +3953,7 @@ msgstr " [del Vim versió 3.0]"
#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
-msgstr " [no sembla un fitxer d'intercanvi de Vim]"
+msgstr " [no sembla un fitxer .swp de Vim]"
#: ../memline.c:1552
msgid " file name: "
@@ -4008,7 +4025,7 @@ msgstr " [no es pot obrir]"
#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: No s'ha pogut preservar, no hi ha fitxer d'intercanvi"
+msgstr "E313: No s'ha pogut preservar, no existeix cap fitxer d'intercanvi"
#: ../memline.c:1747
msgid "File preserved"
@@ -4030,7 +4047,7 @@ msgstr "E316: ml_get: no s'ha trobat la línia %<PRId64>"
#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
-msgstr "E317: Punter a la id d'un bloc incorrecte 3"
+msgstr "E317: punter a id de bloc incorrecte 3"
#: ../memline.c:2311
msgid "stack_idx should be 0"
@@ -4042,7 +4059,7 @@ msgstr "E318: S'han actualitzat massa blocs?"
#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
-msgstr "E317: Punter a la id d'un bloc incorrecte 4"
+msgstr "E317: Punter a id de bloc incorrecte 4"
#: ../memline.c:2536
msgid "deleted block 1?"
@@ -4092,9 +4109,7 @@ msgstr "E325: ATENCIÓ"
msgid ""
"\n"
"Found a swap file by the name \""
-msgstr ""
-"\n"
-"S'ha trobat un fitxer d'intercanvi de nom \""
+msgstr "\nS'ha trobat un fitxer d'intercanvi amb nom \""
#: ../memline.c:3226
msgid "While opening file \""
@@ -4139,7 +4154,7 @@ msgid ""
" to recover the changes (see \":help recovery\").\n"
msgstr ""
"\"\n"
-" per recuperar els canvis (vegeu \":help recovery\").\n"
+" per a recuperar els canvis (vegeu \":help recovery\").\n"
#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
@@ -4151,7 +4166,7 @@ msgid ""
" to avoid this message.\n"
msgstr ""
"\"\n"
-" per evitar aquest missatge.\n"
+" per a evitar aquest missatge.\n"
#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
@@ -4177,7 +4192,7 @@ msgid ""
"&Quit\n"
"&Abort"
msgstr ""
-"&Obrir només-lectura\n"
+"&Obrir amb només lectura\n"
"&Editar igualment\n"
"&Recuperar\n"
"&Sortir\n"
@@ -4293,10 +4308,6 @@ msgstr "línia %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: El nom de registre no és vàlid: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Traducció dels missatges: Ernest Adrogué <eadrogue@gmx.net>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Interrupció: "
@@ -4849,7 +4860,7 @@ msgstr "E377: %%%c no vàlid a la cadena de format"
#. nothing found
#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: L'opció 'errorformat' no conté cap patró"
+msgstr "E378: 'errorformat' no conté cap patró"
#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
@@ -5243,7 +5254,7 @@ msgstr "S'han trobat tots els fitxers inclosos"
#: ../search.c:4519
msgid "No included files"
-msgstr "No hi han fitxers inclosos"
+msgstr "No hi ha fitxers inclosos"
#: ../search.c:4527
msgid "E388: Couldn't find definition"
@@ -5338,8 +5349,8 @@ msgstr "Atenció: la regió %s no està suportada"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Llegint el fitxer d'afixos %s ..."
+msgid "Reading affix file %s..."
+msgstr "Llegint el fitxer d'afixos %s..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
@@ -5537,8 +5548,8 @@ msgstr "%d paraula/es ignorada/es amb caràcters no-ASCII a %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Llegint el fitxer de paraules %s ..."
+msgid "Reading word file %s..."
+msgstr "Llegint el fitxer de paraules %s..."
#: ../spell.c:6155
#, c-format
@@ -5608,13 +5619,13 @@ msgstr "Nombre total de paraules: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Escrivint el fitxer de suggeriments %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "Escrivint el fitxer de suggeriments %s..."
#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
-msgstr "Ús estimat de memòria en funcionament: %d octets"
+msgstr "Ús estimat de memòria durant l'execució: %d octets"
#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
@@ -5631,12 +5642,12 @@ msgstr "E755: Regió no vàlida a %s"
#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
-msgstr "Atenció: heu especificat composició i NOBREAK alhora"
+msgstr "Atenció: s'ha especificat composició i NOBREAK alhora"
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Escrivint el fitxer d'ortografia %s ..."
+msgid "Writing spell file %s..."
+msgstr "Escrivint el fitxer d'ortografia %s..."
#: ../spell.c:7925
msgid "Done!"
@@ -6382,7 +6393,7 @@ msgstr " alternativa per a $VIM: \""
# 29 caràcters fins el ":" (inclòs)
#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
-msgstr " alt per a $VIMRUNTIME: \""
+msgstr " altern. per a $VIMRUNTIME: \""
#: ../version.c:709
msgid "Compilation: "
@@ -6410,7 +6421,7 @@ msgstr "per Bram Moolenaar et al."
#: ../version.c:774
msgid "Vim is open source and freely distributable"
-msgstr "Vim és un programa obert i lliure distribució"
+msgstr "Vim és un programa obert i de lliure distribució"
#: ../version.c:776
msgid "Help poor children in Uganda!"
diff --git a/src/nvim/po/check.vim b/src/nvim/po/check.vim
index 1622741da6..eae27ef74d 100644
--- a/src/nvim/po/check.vim
+++ b/src/nvim/po/check.vim
@@ -33,36 +33,67 @@ func! GetMline()
return substitute(idline, '[^%]*\(%[-+ #''.0-9*]*l\=[dsuxXpoc%]\)\=', '\1', 'g')
endfunc
-" This only works when 'wrapscan' is set.
+" This only works when 'wrapscan' is not set.
let s:save_wrapscan = &wrapscan
-set wrapscan
+set nowrapscan
" Start at the first "msgid" line.
+let wsv = winsaveview()
1
-/^msgid
-let startline = line('.')
+/^msgid\>
+
+" When an error is detected this is set to the line number.
+" Note: this is used in the Makefile.
let error = 0
while 1
if getline(line('.') - 1) !~ "no-c-format"
- let fromline = GetMline()
+ " go over the "msgid" and "msgid_plural" lines
+ let prevfromline = 'foobar'
+ while 1
+ let fromline = GetMline()
+ if prevfromline != 'foobar' && prevfromline != fromline
+ echomsg 'Mismatching % in line ' . (line('.') - 1)
+ echomsg 'msgid: ' . prevfromline
+ echomsg 'msgid ' . fromline
+ if error == 0
+ let error = line('.')
+ endif
+ endif
+ if getline('.') !~ 'msgid_plural'
+ break
+ endif
+ let prevfromline = fromline
+ endwhile
+
if getline('.') !~ '^msgstr'
- echo 'Missing "msgstr" in line ' . line('.')
- let error = 1
- endif
- let toline = GetMline()
- if fromline != toline
- echo 'Mismatching % in line ' . (line('.') - 1)
- echo 'msgid: ' . fromline
- echo 'msgstr: ' . toline
- let error = 1
+ echomsg 'Missing "msgstr" in line ' . line('.')
+ if error == 0
+ let error = line('.')
+ endif
endif
+
+ " check all the 'msgstr' lines
+ while getline('.') =~ '^msgstr'
+ let toline = GetMline()
+ if fromline != toline
+ echomsg 'Mismatching % in line ' . (line('.') - 1)
+ echomsg 'msgid: ' . fromline
+ echomsg 'msgstr: ' . toline
+ if error == 0
+ let error = line('.')
+ endif
+ endif
+ if line('.') == line('$')
+ break
+ endif
+ endwhile
endif
- " Find next msgid.
- " Wrap around at the end of the file, quit when back at the first one.
- /^msgid
- if line('.') == startline
+ " Find next msgid. Quit when there is no more.
+ let lnum = line('.')
+ silent! /^msgid\>
+ if line('.') == lnum
break
endif
endwhile
@@ -77,12 +108,103 @@ endwhile
"
1
if search('msgid "\("\n"\)\?\([EW][0-9]\+:\).*\nmsgstr "\("\n"\)\?[^"]\@=\2\@!') > 0
- echo 'Mismatching error/warning code in line ' . line('.')
- let error = 1
+ echomsg 'Mismatching error/warning code in line ' . line('.')
+ if error == 0
+ let error = line('.')
+ endif
endif
+func! CountNl(first, last)
+ let nl = 0
+ for lnum in range(a:first, a:last)
+ let nl += count(getline(lnum), "\n")
+ endfor
+ return nl
+endfunc
+
+" Check that the \n at the end of the msgid line is also present in the msgstr
+" line. Skip over the header.
+1
+/^"MIME-Version:
+while 1
+ let lnum = search('^msgid\>')
+ if lnum <= 0
+ break
+ endif
+ let strlnum = search('^msgstr\>')
+ let end = search('^$')
+ if end <= 0
+ let end = line('$') + 1
+ endif
+ let origcount = CountNl(lnum, strlnum - 1)
+ let transcount = CountNl(strlnum, end - 1)
+ " Allow for a few more or less line breaks when there are 2 or more
+ if origcount != transcount && (origcount <= 2 || transcount <= 2)
+ echomsg 'Mismatching "\n" in line ' . line('.')
+ if error == 0
+ let error = lnum
+ endif
+ endif
+endwhile
+
+" Check that the file is well formed according to msgfmts understanding
+if executable("msgfmt")
+ let filename = expand("%")
+ let a = system("msgfmt --statistics OLD_PO_FILE_INPUT=yes " . filename)
+ if v:shell_error != 0
+ let error = matchstr(a, filename.':\zs\d\+\ze:')+0
+ for line in split(a, '\n') | echomsg line | endfor
+ endif
+endif
+
+" Check that the plural form is properly initialized
+1
+let plural = search('^msgid_plural ', 'n')
+if (plural && search('^"Plural-Forms: ', 'n') == 0) || (plural && search('^msgstr\[0\] ".\+"', 'n') != plural + 1)
+ if search('^"Plural-Forms: ', 'n') == 0
+ echomsg "Missing Plural header"
+ if error == 0
+ let error = search('\(^"[A-Za-z-_]\+: .*\\n"\n\)\+\zs', 'n') - 1
+ endif
+ elseif error == 0
+ let error = plural
+ endif
+elseif !plural && search('^"Plural-Forms: ', 'n')
+ " We allow for a stray plural header, msginit adds one.
+endif
+
+" Check that 8bit encoding is used instead of 8-bit
+let cte = search('^"Content-Transfer-Encoding:\s\+8-bit', 'n')
+let ctc = search('^"Content-Type:.*;\s\+\<charset=[iI][sS][oO]_', 'n')
+let ctu = search('^"Content-Type:.*;\s\+\<charset=utf-8', 'n')
+if cte
+ echomsg "Content-Transfer-Encoding should be 8bit instead of 8-bit"
+ " TODO: make this an error
+ " if error == 0
+ " let error = cte
+ " endif
+elseif ctc
+ echomsg "Content-Type charset should be 'ISO-...' instead of 'ISO_...'"
+ " TODO: make this an error
+ " if error == 0
+ " let error = ct
+ " endif
+elseif ctu
+ echomsg "Content-Type charset should be 'UTF-8' instead of 'utf-8'"
+ " TODO: make this an error
+ " if error == 0
+ " let error = ct
+ " endif
+endif
+
+
if error == 0
- echo "OK"
+ " If all was OK restore the view.
+ call winrestview(wsv)
+ echomsg "OK"
+else
+ " Put the cursor on the line with the error.
+ exe error
endif
redir END
diff --git a/src/nvim/po/cleanup.vim b/src/nvim/po/cleanup.vim
index 24ae74ed38..b27d88092f 100644
--- a/src/nvim/po/cleanup.vim
+++ b/src/nvim/po/cleanup.vim
@@ -8,12 +8,18 @@
let s:was_diff = &diff
setl nodiff
-silent g/^#: /d
+" untranslated message preceded by c-format or comment
+silent g/^#, c-format\n#/.d
+silent g/^#\..*\n#/.d
+
+silent g/^#[:~] /d
silent g/^#, fuzzy\(, .*\)\=\nmsgid ""\@!/.+1,/^$/-1s/^/#\~ /
silent g/^msgstr"/s//msgstr "/
silent g/^msgid"/s//msgid "/
silent g/^msgstr ""\(\n"\)\@!/?^msgid?,.s/^/#\~ /
+silent g/^\n\n\n/.d
+
if s:was_diff
setl diff
endif
diff --git a/src/nvim/po/cs.cp1250.po b/src/nvim/po/cs.cp1250.po
index 1e62034317..26bdbe8c45 100644
--- a/src/nvim/po/cs.cp1250.po
+++ b/src/nvim/po/cs.cp1250.po
@@ -2535,7 +2535,7 @@ msgstr "E216: Událost %s neexistuje"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Automatické pøíkazy ---"
@@ -2559,7 +2559,7 @@ msgstr "E218: vnoøení automatického pøíkazu pøíliš hluboká"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s automatické pøíkazy pro \"%s\""
#: ../fileio.c:7149
@@ -2763,11 +2763,6 @@ msgstr "E49: Chybná hodnota volby 'scroll'"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3491,7 +3486,7 @@ msgstr "-q [chybový soubor] editovat soubor na místì výskytu první chyby"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4378,10 +4373,6 @@ msgstr "øádek %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: '%s' není pøípustné jméno registru"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Správce zpráv: Bram Moolenaar <Bram@vim.org>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Pøerušení: "
diff --git a/src/nvim/po/cs.po b/src/nvim/po/cs.po
index dd7016fedb..986d6753a8 100644
--- a/src/nvim/po/cs.po
+++ b/src/nvim/po/cs.po
@@ -2535,7 +2535,7 @@ msgstr "E216: Událost %s neexistuje"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Automatické pøíkazy ---"
@@ -2559,7 +2559,7 @@ msgstr "E218: vnoøení automatického pøíkazu pøíli¹ hluboká"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s automatické pøíkazy pro \"%s\""
#: ../fileio.c:7149
@@ -2763,11 +2763,6 @@ msgstr "E49: Chybná hodnota volby 'scroll'"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3491,7 +3486,7 @@ msgstr "-q [chybový soubor] editovat soubor na místì výskytu první chyby"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4378,10 +4373,6 @@ msgstr "øádek %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: '%s' není pøípustné jméno registru"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Správce zpráv: Bram Moolenaar <Bram@vim.org>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Pøeru¹ení: "
diff --git a/src/nvim/po/da.po b/src/nvim/po/da.po
new file mode 100644
index 0000000000..58cd19210b
--- /dev/null
+++ b/src/nvim/po/da.po
@@ -0,0 +1,7088 @@
+# Danish translation for Vim
+# Copyright (C) 2018 The Vim authors
+# This file is distributed under the same license as the vim package.
+# scootergrisen, 2018.
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim 8.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2018-06-08 22:09+0200\n"
+"PO-Revision-Date: 2018-06-23 23:30+0200\n"
+"Last-Translator: scootergrisen\n"
+"Language-Team: Danish\n"
+"Language: da\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() kaldt med tom adgangskode"
+
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Forkert brug af stor/lille byterækkefølge for blowfish"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: sha256-test mislykkede"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Blowfish-test mislykkede"
+
+msgid "[Location List]"
+msgstr "[Placeringsliste]"
+
+msgid "[Quickfix List]"
+msgstr "[Quickfix-liste]"
+
+msgid "E855: Autocommands caused command to abort"
+msgstr "E855: Autokommandoer forårsagede afbrydelse af kommando"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Kan ikke allokere buffer, afslutter..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Kan ikke allokere buffer, bruger en anden..."
+
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: Buffer kan ikke registreres"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Forsøg på at slette en buffer som er i brug"
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Ingen buffere blev udlæst"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Ingen brugere blev slettet"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Ingen buffere blev ryddet"
+
+msgid "1 buffer unloaded"
+msgstr "1 buffer udlæst"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d buffere udlæst"
+
+msgid "1 buffer deleted"
+msgstr "1 buffer slettet"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d buffere slettet"
+
+msgid "1 buffer wiped out"
+msgstr "1 buffer ryddet"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d buffere ryddet"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: Kan ikke udlæse sidste buffer"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Fandt ingen ændret buffer"
+
+msgid "E85: There is no listed buffer"
+msgstr "E85: Der er ingen oplistet buffer"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Kan ikke gå over sidste buffer"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Kan ikke gå før første buffer"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Ingen skrivning siden sidste ændring for bufferen %ld (tilføj ! for at "
+"tilsidesætte)"
+
+msgid "E948: Job still running (add ! to end the job)"
+msgstr "E948: Job kører stadig (tilføj ! for at afslutte jobbet)"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr ""
+"E37: Ingen skrivning siden sidste ændring (tilføj ! for at tilsidesætte)"
+
+msgid "E948: Job still running"
+msgstr "E948: Job kører stadig"
+
+msgid "E37: No write since last change"
+msgstr "E37: Ingen skrivning siden sidste ændring"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr "W14: Advarsel: Overløb i liste over filnavne"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Bufferen %ld blev ikke fundet"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Flere end ét match for %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Ingen matchende buffer for %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "linje %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Buffer med dette navn findes allerede"
+
+msgid " [Modified]"
+msgstr " [Ændret]"
+
+msgid "[Not edited]"
+msgstr "[Ikke redigeret]"
+
+msgid "[New file]"
+msgstr "[Ny fil]"
+
+msgid "[Read errors]"
+msgstr "[Læsefejl]"
+
+msgid "[RO]"
+msgstr "[SB]"
+
+msgid "[readonly]"
+msgstr "[skrivebeskyttet]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 linje --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld linjer --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "linje %ld af %ld --%d%%-- kol "
+
+msgid "[No Name]"
+msgstr "[Intet navn]"
+
+msgid "help"
+msgstr "hjælp"
+
+msgid "[Help]"
+msgstr "[Hjælp]"
+
+msgid "[Preview]"
+msgstr "[Forhåndsvisning]"
+
+msgid "All"
+msgstr "Alt"
+
+msgid "Bot"
+msgstr "Ned"
+
+msgid "Top"
+msgstr "Øve"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# Bufferliste:\n"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Kan ikke skrive, 'buftype'-tilvalget er sat"
+
+msgid "[Prompt]"
+msgstr "[Prompt]"
+
+msgid "[Scratch]"
+msgstr "[Kladdeblok]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Signs ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Signs for %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " linje=%ld id=%d navn=%s"
+
+msgid "E902: Cannot connect to port"
+msgstr "E902: Kan ikke oprette forbindelse til port"
+
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() i channel_open()"
+
+msgid "E898: socket() in channel_open()"
+msgstr "E898: socket() i channel_open()"
+
+msgid "E903: received command with non-string argument"
+msgstr "E903: modtog kommando med argument som ikke er en streng"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: sidste argument for udtryk/kald skal være et nummer"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: tredje argument for kald skal være en liste"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: modtog ukendt kommando: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): skrivning mens der ikke er forbindelse"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): skrivning mislykkedes"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: Kan ikke bruge et callback med %s()"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr ""
+"E912: kan ikke bruge ch_evalexpr()/ch_sendexpr() med en rå- eller nl-kanal"
+
+msgid "E906: not an open channel"
+msgstr "E906: ikke en åben kanal"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: _io-fil kræver at _name er sat"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: in_io-buffer kræver at in_buf eller in_name er sat"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: buffer skal være indlæst: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Filen er krypteret med ukendt metode"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "Advarsel: Bruger en svag krypteringsmetode; se :help 'cm'"
+
+msgid "Enter encryption key: "
+msgstr "Indtast krypteringsnøgle: "
+
+msgid "Enter same key again: "
+msgstr "Indtast samme nøgle igen: "
+
+msgid "Keys don't match!"
+msgstr "Nøglerne er ikke ens!"
+
+msgid "[crypted]"
+msgstr "[crypted]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Manglende kolon i ordbog: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Duplikeret nøgle i ordbog: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Manglende komma i ordbog: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Manglende slutning på ordbog '}': %s"
+
+msgid "extend() argument"
+msgstr "extend()-argument"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Nøgle findes allerede: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: Kan ikke diff'e flere end %ld buffere"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Kan ikke læse eller skrive midlertidige filer"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Kan ikke oprette diff'er"
+
+msgid "Patch file"
+msgstr "Patch-fil"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Kan ikke læse patch-output"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Kan ikke læse diff-output"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Nuværende buffer er ikke i diff-tilstand"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Ingen anden buffer i diff-tilstand kan ændres"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: Ingen anden buffer i diff-tilstand"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr ""
+"E101: Mere end to buffere i diff-tilstand, ved ikke hvilke der skal bruges"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Kan ikke finde bufferen \"%s\""
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Bufferen \"%s\" er ikke i diff-tilstand"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Buffer ændret uventet"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape ikke tilladt i digraf"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Keymap-fil ikke fundet"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Bruger :loadkeymap ikke i en sourced fil"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Tom keymap-post"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Fuldførelse af nøgleord (^N^P)"
+
+msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+msgstr " ^X tilstand (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Fuldførelse af hel linje (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Fuldførelse af filnavn (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Fuldførelse af tag (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Fuldførelse af sti (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Fuldførelse af definition (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Fuldførelse af ordbog (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Fuldførelse af tesaurus (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Fuldførelse af kommandolinje (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " Fuldførelse af brugerdefineret (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Fuldførelse af omni (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " Staveforslag (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Fuldførelse af nøgleord local (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "Stødte på slutningen af afsnit"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: Fuldførelse-funktion ændrede vindue"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: Fuldførelse-funktion slettede tekst"
+
+msgid "'dictionary' option is empty"
+msgstr "'dictionary'-tilvalget er tomt"
+
+msgid "'thesaurus' option is empty"
+msgstr "'thesaurus'-tilvalget er tomt"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Skanner ordbog: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (indsæt) Rul (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (erstat) Rul (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Skanner: %s"
+
+msgid "Scanning tags."
+msgstr "Skanner tags."
+
+msgid "match in file"
+msgstr "match i fil"
+
+msgid " Adding"
+msgstr " Tilføjer"
+
+msgid "-- Searching..."
+msgstr "-- Søger..."
+
+msgid "Back at original"
+msgstr "Tilbage ved original"
+
+msgid "Word from other line"
+msgstr "Ord fra anden linje"
+
+msgid "The only match"
+msgstr "Det eneste match"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "match %d af %d"
+
+#, c-format
+msgid "match %d"
+msgstr "match %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Uventede tegn i :let"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: Udefineret variabel: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: Manglende ']'"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Kan ikke bruge [:] med en ordbog"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Forkert variabeltype for %s="
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Ulovligt variabelnavn: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: bruger flydende kommatal som en streng"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Færre mål end listepunkter"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Flere mål end listepunkter"
+
+msgid "Double ; in list of variables"
+msgstr "Dobbelt ; i liste over variabler"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Kan ikke opliste variabler for %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Kan kun indeksere en liste eller ordbog"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] skal være sidst"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] kræver en listeværdi"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: Listeværdi har flere punkter end mål"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: Listeværdi har ikke nok punkter"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: Manglende \"in\" efter :for"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Ingen sådan variabel: \"%s\""
+
+#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: Kan ikke låse eller låse op for variablen %s"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: variabel indlejret for dybt til at blive låst/låst op"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: Manglende ':' efter '?'"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: Kan ikke bruge '%' med flydende kommatal"
+
+msgid "E110: Missing ')'"
+msgstr "E110: Manglende ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Kan ikke indeksere en funcref"
+
+msgid "E909: Cannot index a special variable"
+msgstr "E909: Kan ikke indeksere en speciel variabel"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: Tilvalgsnavn mangler: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Ukendt tilvalg: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: Manglende citationstegn: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: Manglende citationstegn: %s"
+
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr "Ikke nok hukommelse til at sætte referencer, affaldsindsamling afbrudt!"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: variabel indlejret for dybt til at blive vist"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Bruger et flydende kommatal som et nummer"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Bruger en funcref som et nummer"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Bruger en liste som et nummer"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Bruger en ordbog som et nummer"
+
+msgid "E910: Using a Job as a Number"
+msgstr "E910: Bruger et job som et nummer"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: Bruger en kanal som et nummer"
+
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: Bruger en funcref som et fyldende kommatal"
+
+msgid "E892: Using a String as a Float"
+msgstr "E892: Bruger en streng som et flydende kommatal"
+
+msgid "E893: Using a List as a Float"
+msgstr "E893: Bruger en liste som et flydende kommatal"
+
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: Bruger en ordbog som et flydende kommatal"
+
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Bruger en speciel værdi som et flydende kommatal"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: Bruger et job som et flydende kommatal"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: Bruger en kanal som et flydende kommatal"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: bruger funcref som en streng"
+
+msgid "E730: using List as a String"
+msgstr "E730: bruger liste som en streng"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: bruger ordbog som en streng"
+
+msgid "E908: using an invalid value as a String"
+msgstr "E908: bruger en ugyldig værdi som en streng"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Kan ikke slette variablen %s"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Funcref-variabelnavn skal begynde med et stort bogstav: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Variabelnavn er i konflikt med eksisterende funktion: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: Værdien er låst: %s"
+
+msgid "Unknown"
+msgstr "Ukendt"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Kan ikke ændre værdien af %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: variabel indlejret for dybt til at lave en kopi"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# globale variabler:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tSidst sat fra "
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Kan kun sammenligne liste med liste"
+
+msgid "E692: Invalid operation for List"
+msgstr "E692: Ugyldig handling for liste"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Kan kun sammenligne ordbog med ordbog"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Ugyldig handling for ordbog"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Ugyldig handling for funcref'er"
+
+msgid "map() argument"
+msgstr "map()-argument"
+
+msgid "filter() argument"
+msgstr "filter()-argument"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argument af %s skal være en liste"
+
+msgid "E928: String required"
+msgstr "E928: Streng kræves"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Nummer eller flydende kommatal kræves"
+
+msgid "add() argument"
+msgstr "add()-argument"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() kan kun bruges i indsæt-tilstand"
+
+msgid "&Ok"
+msgstr "&Ok"
+
+#, c-format
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld linje: "
+msgstr[1] "+-%s%3ld linjer: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Ukendt funktion: %s"
+
+msgid "E922: expected a dict"
+msgstr "E922: ventede en ordbog"
+
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: Andet argument af function() skal være en liste eller en ordbog"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"&Annuller"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "kaldte inputrestore() flere gange end inputsave()"
+
+msgid "insert() argument"
+msgstr "insert()-argument"
+
+msgid "E786: Range not allowed"
+msgstr "E786: Område ikke tilladt"
+
+msgid "E916: not a valid job"
+msgstr "E916: ikke et gyldigt job"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Ugyldig type for len()"
+
+#, c-format
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID er reserveret til \":match\": %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Stride er nul"
+
+msgid "E727: Start past end"
+msgstr "E727: Start efter slutningen"
+
+msgid "<empty>"
+msgstr "<tom>"
+
+msgid "E240: No connection to the X server"
+msgstr "E240: Ingen forbindelse til X-serveren"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Kan ikke sende til %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Kan ikke læse et serversvar"
+
+msgid "E941: already started a server"
+msgstr "E941: allerede startet en server"
+
+msgid "E942: +clientserver feature not available"
+msgstr "E942: +clientserver-funktionalitet ikke tilgængelig"
+
+msgid "remove() argument"
+msgstr "remove()-argument"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: For mange symbolske links (cyklus?)"
+
+msgid "reverse() argument"
+msgstr "reverse()-argument"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Kan ikke sende til klient"
+
+#, c-format
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Ugyldig handling: '%s'"
+
+msgid "sort() argument"
+msgstr "sort()-argument"
+
+msgid "uniq() argument"
+msgstr "uniq()-argument"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Sort-sammenligningsfunktion mislykkedes"
+
+msgid "E882: Uniq compare function failed"
+msgstr "E882: Uniq-sammenligningsfunktion mislykkedes"
+
+msgid "(Invalid)"
+msgstr "(Ugyldig)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: ugyldigt undermatch-nummer: %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Fejl ved skrivning af midlertidig fil"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: Ugyldigt callback-argument"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"
+msgstr "<%s>%s%s %d, hex %02x, oct %03o, digr %s"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, hex %02x, octal %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Oct %o, Digr %s"
+msgstr "> %d, hex %04x, oct %o, digr %s"
+
+#, c-format
+msgid "> %d, Hex %08x, Oct %o, Digr %s"
+msgstr "> %d, hex %08x, oct %o, digr %s"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, hex %04x, octal %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, hex %08x, octal %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: flyt linjer ind i dem selv"
+
+msgid "1 line moved"
+msgstr "1 linje flyttet"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld linjer flyttet"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld linjer filtreret"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter*-autokommandoer må ikke ændre nuværende buffer"
+
+msgid "[No write since last change]\n"
+msgstr "[Ingen skrivning siden sidste ændring]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s på linje: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: For mange fejl, springer resten af filen over"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Læser viminfo-filen \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " info"
+
+msgid " marks"
+msgstr " mærker"
+
+msgid " oldfiles"
+msgstr " gamle filer"
+
+msgid " FAILED"
+msgstr " MISLYKKEDES"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo-filen er skrivebeskyttet: %s"
+
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: For mange midlertidige filer for viminfo, såsom %s!"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Kan ikke skrive viminfo-filen %s!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "Skriver viminfo-filen \"%s\""
+
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: Kan ikke omdøbe viminfo-fil til %s!"
+
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Denne viminfo-fil blev genereret af Vim %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Du kan redigere den, hvis du er forsigtig!\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# Værdien af 'encoding' da filen blev skrevet\n"
+
+msgid "Illegal starting char"
+msgstr "Ulovligt tegn i begyndelsen"
+
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"#-bjælkelinjer, kopieret ordret:\n"
+
+msgid "Save As"
+msgstr "Gem som"
+
+msgid "Write partial file?"
+msgstr "Skriv ufuldstændig fil?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: Brug ! til at skrive ufuldstændig buffer"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Overskriv eksisterende fil \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Swap-filen \"%s\" findes, overskriv alligevel?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Swap-filen findes: %s (:silent! tilsidesætter)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Intet filnavn for buffer %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Fil ikke skrevet: Skrivning er deaktiveret af 'write'-tilvalget"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"'readonly'-tilvalget er sat for \"%s\".\n"
+"Vil du skrive alligevel?"
+
+#, c-format
+msgid ""
+"File permissions of \"%s\" are read-only.\n"
+"It may still be possible to write it.\n"
+"Do you wish to try?"
+msgstr ""
+"Filtilladelserne for \"%s\" er skrivebeskyttede.\n"
+"Der kan stadig være mulighed for at skrive den.\n"
+"Vil du prøve?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" er skrivebeskyttet (tilføj ! for at tilsidesætte)"
+
+msgid "Edit File"
+msgstr "Rediger fil"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Autokommandoer slettede uventede ny buffer %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: ikke-numerisk argument til :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Skalkommandoer er ikke tilladt i rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Regulære udtryk kan ikke afgrænses af bogstaver"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "erstat med %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Afbrudt) "
+
+msgid "1 match"
+msgstr "1 match"
+
+msgid "1 substitution"
+msgstr "1 erstatning"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld match"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld erstatninger"
+
+msgid " on 1 line"
+msgstr " på 1 linje"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " på %ld linjer"
+
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: Kan ikke foretage :global rekursivt med et område"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: Regulære udtryk mangler fra global"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Mønster fundet på hver linje: %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Mønster ikke fundet: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# Sidste erstatningsstreng:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Tag det bare helt roligt!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Beklager, ingen '%s' hjælp til %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Beklager, ingen hjælp til %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Beklager, hjælpfilen \"%s\" ikke fundet"
+
+#, c-format
+msgid "E151: No match: %s"
+msgstr "E151: Intet match: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: Kan ikke åbne %s til skrivning"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: Kan ikke åbne %s til læsning"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Blanding af kodninger for hjælpfiler i samme sprog: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Duplikeret tag \"%s\" i fil %s/%s"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ikke en mappe: %s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Ukendt sign-kommando: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: Manglende sign-navn"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: For mange signs defineret"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: Ugyldig sign-tekst: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Ukendt sign: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: Manglende sign-nummer"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: Ugyldigt buffernavn: %s"
+
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Kan ikke hoppe til en buffer som ikke har et navn"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Ugyldigt sign-ID: %ld"
+
+#, c-format
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Det er ikke muligt at ændre sign %s"
+
+msgid " (NOT FOUND)"
+msgstr " (IKKE FUNDET)"
+
+msgid " (not supported)"
+msgstr " (understøttes ikke)"
+
+msgid "[Deleted]"
+msgstr "[Slettet]"
+
+msgid "No old files"
+msgstr "Ingen gamle filer"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Går i fejlretningstilstand. Skriv \"cont\" for at fortsætte."
+
+#, c-format
+msgid "Oldval = \"%s\""
+msgstr "Oldval = \"%s\""
+
+#, c-format
+msgid "Newval = \"%s\""
+msgstr "Newval = \"%s\""
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "linje %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "cmd: %s"
+
+msgid "frame is zero"
+msgstr "ramme er nul"
+
+#, c-format
+msgid "frame at highest level: %d"
+msgstr "ramme på højeste niveau: %d"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Breakpoint i \"%s%s\" linje %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Breakpoint ikke fundet: %s"
+
+msgid "No breakpoints defined"
+msgstr "Ingen breakpoints defineret"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s linje %ld"
+
+#, c-format
+msgid "%3d expr %s"
+msgstr "%3d udtryk %s"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Brug først \":profile start {fname}\""
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Gem ændringer til \"%s\"?"
+
+#, c-format
+msgid "E947: Job still running in buffer \"%s\""
+msgstr "E947: Job kører stadig i bufferen \"%s\""
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Ingen skrivning siden sidste ændring for bufferen \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Advarsel: Indtastede anden buffer uventede (tjek autokommandoer)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: Der er kun én fil at redigere"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Kan ikke gå før første fil"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Kan ikke gå over sidste fil"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: kompiler understøttes ikke: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Søger efter \"%s\" i \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Søger efter \"%s\""
+
+#, c-format
+msgid "not found in '%s': \"%s\""
+msgstr "ikke fundet i '%s': \"%s\""
+
+#, c-format
+msgid "W20: Required python version 2.x not supported, ignoring file: %s"
+msgstr "W20: Krævede python-version 2.x understøttes ikke, ignorerer fil: %s"
+
+#, c-format
+msgid "W21: Required python version 3.x not supported, ignoring file: %s"
+msgstr "W21: Krævede python-version 3.x understøttes ikke, ignorerer fil: %s"
+
+msgid "Source Vim script"
+msgstr "Source Vim-script"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Kan ikke source en mappe: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "kunne ikke source \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "linje %ld: kunne ikke source \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "sourcing \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "linje %ld: sourcing \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "færdig med sourcing af %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "fortsætter i %s"
+
+msgid "modeline"
+msgstr "tilstandslinje"
+
+msgid "--cmd argument"
+msgstr "--cmd-argument"
+
+msgid "-c argument"
+msgstr "-c-argument"
+
+msgid "environment variable"
+msgstr "miljøvariabel"
+
+msgid "error handler"
+msgstr "fejlhåndtering"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Advarsel: Forkert linjeseparator, ^M mangler muligvis"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding brugt udenfor en sourced fil"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish udenfor en sourced fil"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Nuværende %ssprog: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Kan ikke sætte sprog til \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr "Går i Ex-tilstand. Skriv \"visual\" for at gå til normal tilstand."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Ved filens slutning"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Kommando for rekursiv"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Undtagelse ikke fanget: %s"
+
+msgid "End of sourced file"
+msgstr "Slut på sourced fil"
+
+msgid "End of function"
+msgstr "Slutning af funktion"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: Flertydig brug af brugerdefineret kommando"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Ikke en editor-kommando"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Baglæns område givet"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Baglæns område givet, OK at bytte om"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: Brug w eller w>>"
+
+msgid "E943: Command table needs to be updated, run 'make cmdidxs'"
+msgstr "E943: Kommandotabel skal opdateres, kør 'make cmdidxs'"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Beklager, kommandoen er ikke tilgængelig i denne version"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "1 fil mere at redigere. Afslut alligevel?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "%d filer mere at redigere. Afslut alligevel?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: 1 fil mere at redigere"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld filer mere at redigere"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Kommandoen findes allerede: tilføj ! for at erstatte den"
+
+msgid ""
+"\n"
+" Name Args Address Complete Definition"
+msgstr ""
+"\n"
+" Navn Argumenter Adresse Fuldført Definition"
+
+msgid "No user-defined commands found"
+msgstr "Fandt ingen brugerdefinerede kommandoer"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Ingen attribut angivet"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: Ugyldigt antal argumenter"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Tælling må ikke angives to gange"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: Ugyldig standardværdi for tælling"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: argument kræves til -complete"
+
+msgid "E179: argument required for -addr"
+msgstr "E179: argument kræves til -addr"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: Ugyldig attribut: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: Ugyldigt kommandonavn"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: Brugerdefinerede kommandoer skal begynde med et stort bogstav"
+
+msgid "E841: Reserved name, cannot be used for user defined command"
+msgstr "E841: Reserveret navn, kan ikke bruges til brugerdefineret kommando"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Ingen sådan brugerdefineret kommando: %s"
+
+#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: Ugyldig værdi for adressetype: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: Ugyldig complete-værdi: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Fuldførelse-argument kun tilladt for tilpasset fuldførelse"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Tilpasset fuldførelse kræver et funktion-argument"
+
+msgid "unknown"
+msgstr "ukendt"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Kan ikke finde farveskemaet '%s'"
+
+msgid "Greetings, Vim user!"
+msgstr "Hejsa, Vim-bruger!"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: Kan ikke lukke sidste fanebladsside"
+
+msgid "Already only one tab page"
+msgstr "Allerede kun én fanebladsside"
+
+msgid "Edit File in new window"
+msgstr "Rediger fil i nyt vindue"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Fanebladsside %d"
+
+msgid "No swap file"
+msgstr "Ingen swap-fil"
+
+msgid "Append File"
+msgstr "Tilføj fil til slutningen"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Kan ikke skifte mappe, buffer er ændret (tilføj ! for at tilsidesætte)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Ingen tidligere ordbog"
+
+msgid "E187: Unknown"
+msgstr "E187: Ukendt"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize kræver to nummer-argumenter"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Vinduesplacering: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr ""
+"E188: Indhentelse af vinduesplacering ikke implementeret på denne platform"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos kræver to nummer-argumenter"
+
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: Kan ikke bruge :redir i execute()"
+
+msgid "Save Redirection"
+msgstr "Gem omdirigering"
+
+msgid "Save View"
+msgstr "Gem visning"
+
+msgid "Save Session"
+msgstr "Gem session"
+
+msgid "Save Setup"
+msgstr "Gem opsætning"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Kan ikke oprette mappe: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" findes (tilføj ! for at tilsidesætte)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: Kan ikke åbne \"%s\" til skrivning"
+
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr ""
+"E191: Argument skal være et bogstav eller retvendt/omvendt citationstegn"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Rekursiv brug af :normal for dyb"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< er ikke tilgængelig uden +eval-funktionaliteten"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Intet alternate-filnavn til erstatning for '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: intet autokommando-filnavn til erstatning for \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: intet autokommando-buffernummer til erstatning for \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: intet autokommando-matchnavn til erstatning for \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: intet :source-filnavn til erstatning for \"<sfile>\""
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: intet linjenummer til brug for \"<slnum>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Tomt filnavn for '%' eller '#', virker kun med \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Evaluerer til en tom streng"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: Kan ikke åbne viminfo-fil til læsning"
+
+msgid "Untitled"
+msgstr "Unavngivet"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Ingen digraffer i denne version"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: Kan ikke :throw-undtagelser med 'Vim'-præfiks"
+
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Undtagelse kastet: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Undtagelse færdig: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Undtagelse forkastet: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, linje %ld"
+
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Undtagelse fanget: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s gjort afventende"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s genoptaget"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s forkastet"
+
+msgid "Exception"
+msgstr "Undtagelse"
+
+msgid "Error and interrupt"
+msgstr "Fejl og afbryd"
+
+msgid "Error"
+msgstr "Fejl"
+
+msgid "Interrupt"
+msgstr "Afbryd"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if-indlejring for dyb"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif uden :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else uden :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif uden :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: flere :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif efter :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while/:for-indlejring for dyb"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue uden :while eller :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break uden :while eller :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Bruger :endfor med :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Bruger :endwhile med :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try-indlejring for dyb"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch uden :try"
+
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch efter :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally uden :try"
+
+msgid "E607: multiple :finally"
+msgstr "E607: flere :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry uden :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction ikke i en funktion"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Ikke tilladt at redigere anden buffer nu"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Ikke tilladt at ændre bufferinformation nu"
+
+msgid "tagname"
+msgstr "tagnavn"
+
+msgid " kind file\n"
+msgstr " kind-fil\n"
+
+msgid "'history' option is zero"
+msgstr "'history'-tilvalget er nul"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s Historik (nyeste til ældste):\n"
+
+msgid "Command Line"
+msgstr "Kommandolinje"
+
+msgid "Search String"
+msgstr "Søgestreng"
+
+msgid "Expression"
+msgstr "Udtryk"
+
+msgid "Input Line"
+msgstr "Inputlinje"
+
+msgid "Debug Line"
+msgstr "Fejlretningslinje"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar efter kommandolængden"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Aktivt vindue eller buffer slettet"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Autokommandoer ændrede buffer eller buffernavn"
+
+msgid "Illegal file name"
+msgstr "Ulovlig filnavn"
+
+msgid "is a directory"
+msgstr "er en mappe"
+
+msgid "is not a file"
+msgstr "er ikke en fil"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "er en enhed (deaktiveret med 'opendevice'-tilvalget)"
+
+msgid "[New File]"
+msgstr "[Ny fil]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Ny MAPPE]"
+
+msgid "[File too big]"
+msgstr "[Filen er for stor]"
+
+msgid "[Permission Denied]"
+msgstr "[Tilladelse nægtet]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre-autokommandoer gjorde filen ulæselig"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre-autokommandoer må ikke ændre nuværende buffer"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Læser fra stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Læser fra stdin..."
+
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Konvertering gjorde filen ulæselig!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/sokkel]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[sokkel]"
+
+msgid "[character special]"
+msgstr "[character special]"
+
+msgid "[CR missing]"
+msgstr "[CR mangler]"
+
+msgid "[long lines split]"
+msgstr "[opdeling af lange linjer]"
+
+msgid "[NOT converted]"
+msgstr "[IKKE konverteret]"
+
+msgid "[converted]"
+msgstr "[konverteret]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[KONVERTERINGSFEJL på linje %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[ULOVLIG BYTE på linje %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[LÆSEFEJL]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Kan ikke finde midlertidig fil til konvertering"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Konvertering med 'charconvert' mislykkedes"
+
+msgid "can't read output of 'charconvert'"
+msgstr "kan ikke læse output af 'charconvert'"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Ingen matchende autokommandoer for acwrite-buffer"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr "E203: Autokommandoer slettet eller udlæste buffer som skal skrives"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Autokommando ændrede antal linjer på en uventede måde"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans tillader ikke skrivninger af uændrede buffere"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Ufuldstændige skrivninger er ikke tilladt for NetBeans-buffere"
+
+msgid "is not a file or writable device"
+msgstr "er ikke en fil eller enhed som der kan skrives til"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "skrivning til enhed er deaktiveret med 'opendevice'-tilvalget"
+
+msgid "is read-only (add ! to override)"
+msgstr "er skrivebeskyttet (tilføj ! for at tilsidesætte)"
+
+msgid "E506: Can't write to backup file (add ! to override)"
+msgstr ""
+"E506: Kan ikke skrive til sikkerhedskopieret fil (tilføj ! for at "
+"tilsidesætte)"
+
+msgid "E507: Close error for backup file (add ! to override)"
+msgstr ""
+"E507: Fejl ved lukning af sikkerhedskopieret fil (tilføj ! for at "
+"tilsidesætte)"
+
+msgid "E508: Can't read file for backup (add ! to override)"
+msgstr ""
+"E508: Kan ikke læse fil til sikkerhedskopiering (tilføj ! for at "
+"tilsidesætte)"
+
+msgid "E509: Cannot create backup file (add ! to override)"
+msgstr ""
+"E509: Kan ikke oprette (create) sikkerhedskopieret fil (tilføj ! for at "
+"tilsidesætte)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr ""
+"E510: Kan ikke oprette (make) sikkerhedskopieret fil (tilføj ! for at "
+"tilsidesætte)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Kan ikke finde midlertidig fil til skrivning"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Kan ikke konvertere (tilføj ! for at skrive uden konvertering)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Kan ikke åbne linket fil til skrivning"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Kan ikke åbne filen til skrivning"
+
+msgid "E949: File changed while writing"
+msgstr "E949: Filen blev ændret ved skrivning"
+
+msgid "E512: Close failed"
+msgstr "E512: Lukning mislykkedes"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr ""
+"E513: fejl ved skrivning, konvertering mislykkedes (gør 'fenc' tom for at "
+"tilsidesætte)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: fejl ved skrivning, konvertering mislykkedes på linje %ld (gør 'fenc' "
+"tom for at tilsidesætte)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: skrivefejl (er filsystemet fuldt?)"
+
+msgid " CONVERSION ERROR"
+msgstr " KONVERTERINGSFEJL"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " på linje %ld;"
+
+msgid "[Device]"
+msgstr "[Enhed]"
+
+msgid "[New]"
+msgstr "[Ny]"
+
+msgid " [a]"
+msgstr " [a]"
+
+msgid " appended"
+msgstr " tilføjet i slutningen"
+
+msgid " [w]"
+msgstr " [s]"
+
+msgid " written"
+msgstr " skrevet"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patchmode: kan ikke gemme original fil"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: patchmode: kan ikke touch tom original fil"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Kan ikke slette sikkerhedskopieret fil"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"ADVARSEL: Den originale fil kan man mistet eller beskadiget\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "afslut ikke editoren inden filen er blevet skrevet!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dos-format]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[mac-format]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unix-format]"
+
+msgid "1 line, "
+msgstr "1 linje, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld linjer, "
+
+msgid "1 character"
+msgstr "1 tegn"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld tegn"
+
+msgid "[noeol]"
+msgstr "[ingen eol]"
+
+msgid "[Incomplete last line]"
+msgstr "[Ufuldstændig sidste linje]"
+
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "ADVARSEL: Filen er blevet ændret siden den blev læst!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Vil du virkelig skrive den"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Fejl ved skrivning til \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Fejl ved lukning af \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Fejl ved læsning af \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: FileChangedShell-autokommando slettede buffer"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Filen \"%s\" er ikke længere tilgængelig"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Advarsel: Filen \"%s\" er blevet ændret og bufferen blev også ændret i "
+"Vim"
+
+msgid "See \":help W12\" for more info."
+msgstr "Se \":help W12\" for mere info."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr "W11: Advarsel: Filen \"%s\" er blevet ændret siden redigeringen startede"
+
+msgid "See \":help W11\" for more info."
+msgstr "Se \":help W11\" for mere info."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Advarsel: Tilstanden af filen \"%s\" er blevet ændret siden redigeringen "
+"startede"
+
+msgid "See \":help W16\" for more info."
+msgstr "Se \":help W16\" for mere info."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr ""
+"W13: Advarsel: Filen \"%s\" er blevet oprettet efter redigeringen startede"
+
+msgid "Warning"
+msgstr "Advarsel"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Indlæs fil"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Kunne ikke forbedre til genindlæsning af \"%s\""
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: Kunne ikke genindlæse \"%s\""
+
+msgid "--Deleted--"
+msgstr "--Slettet--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "auto-removing-autokommando: %s <buffer=%d>"
+
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Ingen sådan gruppe: \"%s\""
+
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Kan ikke slette den nuværende gruppe"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: Sletter augroup som stadig er i brug"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Ulovligt tegn efter *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Ingen sådan hændelse: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Ingen sådan gruppe eller hændelse: %s"
+
+msgid ""
+"\n"
+"--- Auto-Commands ---"
+msgstr ""
+"\n"
+"--- Auto-kommandoer ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <buffer=%d>: ugyldigt buffernummer "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Kan ikke udføre autokommandoer for ALLE hændelser"
+
+msgid "No matching autocommands"
+msgstr "Ingen matchende autokommandoer"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: autokommando indlejret for dyb"
+
+#, c-format
+msgid "%s Auto commands for \"%s\""
+msgstr "%s Auto-kommandoer for \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Udfører %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "autokommando %s"
+
+msgid "E219: Missing {."
+msgstr "E219: Manglende {."
+
+msgid "E220: Missing }."
+msgstr "E220: Manglende }."
+
+msgid "E490: No fold found"
+msgstr "E490: Ingen sammenfoldning fundet"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Kan ikke oprette sammenfoldning med nuværende 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Kan ikke slette sammenfoldning med nuværende 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld linje sammenfoldet "
+msgstr[1] "+--%3ld linjer sammenfoldet "
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Tilføj til læsebuffer"
+
+msgid "E223: recursive mapping"
+msgstr "E223: rekursiv mapping"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: global forkortelse findes allerede for %s"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: global mapping findes allerede for %s"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: forkortelse findes allerede for %s"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: mapping findes allerede for %s"
+
+msgid "No abbreviation found"
+msgstr "Ingen forkortelse fundet"
+
+msgid "No mapping found"
+msgstr "Ingen mapping fundet"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Ulovlig tilstand"
+
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: Kunne ikke oprette en ny proces for GUI'en"
+
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: Barneprocessen kunne ikke starte GUI'en"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Kan ikke starte GUI'en"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Kan ikke læse fra \"%s\""
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Kan ikke starte GUI, ingen gyldig skrifttype fundet"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ugyldig"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Værdien af 'imactivatekey' er ugyldig"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Kan ikke allokere farven %s"
+
+msgid "No match at cursor, finding next"
+msgstr "Intet match ved markør, finder næste"
+
+msgid "<cannot open> "
+msgstr "<kan ikke åbne> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: kan ikke hente skrifttypen %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: kan ikke vende tilbage til nuværende mappe"
+
+msgid "Pathname:"
+msgstr "Stinavn:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: kan ikke hente nuværende mappe"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Cancel"
+msgstr "Annuller"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr ""
+"Rullebjælke-widget: Kunne ikke hente geometri eller pixelkort til miniature."
+
+msgid "Vim dialog"
+msgstr "Vim-dialog"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Kan ikke oprette BalloonEval med både meddelelse og callback"
+
+msgid "_Cancel"
+msgstr "_Annuller"
+
+msgid "_Save"
+msgstr "_Gem"
+
+msgid "_Open"
+msgstr "_Ã…bn"
+
+msgid "_OK"
+msgstr "_OK"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nej\n"
+"&Annuller"
+
+msgid "Yes"
+msgstr "Ja"
+
+msgid "No"
+msgstr "Nej"
+
+msgid "Input _Methods"
+msgstr "Input_metoder"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Søg og erstat..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Søg..."
+
+msgid "Find what:"
+msgstr "Find hvad:"
+
+msgid "Replace with:"
+msgstr "Erstat med:"
+
+msgid "Match whole word only"
+msgstr "Match kun hele ord"
+
+msgid "Match case"
+msgstr "Der skelnes ikke mellem store og små bogstaver"
+
+msgid "Direction"
+msgstr "Retning"
+
+msgid "Up"
+msgstr "Op"
+
+msgid "Down"
+msgstr "Ned"
+
+msgid "Find Next"
+msgstr "Find næste"
+
+msgid "Replace"
+msgstr "Erstat"
+
+msgid "Replace All"
+msgstr "Erstat alle"
+
+msgid "_Close"
+msgstr "_Luk"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Modtog \"die\"-anmodning fra sessionshåndtering\n"
+
+msgid "Close tab"
+msgstr "Luk faneblad"
+
+msgid "New tab"
+msgstr "Nyt faneblad"
+
+msgid "Open Tab..."
+msgstr "Ã…bn faneblad..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Hovedvindue uventet ødelagt\n"
+
+msgid "&Filter"
+msgstr "&Filter"
+
+msgid "&Cancel"
+msgstr "&Annuller"
+
+msgid "Directories"
+msgstr "Mapper"
+
+msgid "Filter"
+msgstr "Filter"
+
+msgid "&Help"
+msgstr "&Hjælp"
+
+msgid "Files"
+msgstr "Filer"
+
+msgid "&OK"
+msgstr "&OK"
+
+msgid "Selection"
+msgstr "Markering"
+
+msgid "Find &Next"
+msgstr "Find &næste"
+
+msgid "&Replace"
+msgstr "&Erstat"
+
+msgid "Replace &All"
+msgstr "Erstat &alle"
+
+msgid "&Undo"
+msgstr "&Fortryd"
+
+msgid "Open tab..."
+msgstr "Ã…bn faneblad..."
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Find streng (brug '\\\\' til at finde et '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Find og erstat (brug '\\\\' til at finde et '\\')"
+
+msgid "Not Used"
+msgstr "Ikke brugt"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Mappe\t\t*.nothing\n"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Kan ikke finde vinduestitlen \"%s\""
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argumentet understøttes ikke: \"-%s\"; Brug OLE-versionen."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Kan ikke åbne vindue i MDI-program"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Kan ikke allokere colormap-post, nogle farver kan være forkerte"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Skrifttyper for følgende tegnsæt mangler i skrifttypesættet %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Skrifttypesætnavn: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Skrifttypen '%s' er ikke med fast bredde"
+
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Skrifttypesætnavn: %s"
+
+#, c-format
+msgid "Font0: %s"
+msgstr "Skrifttype0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "Skrifttype1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Bredden på skrifttype%ld er ikke det dobbelte af skrifttype0"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Bredden på skrifttype0: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Bredden på skrifttype1: %ld"
+
+msgid "Invalid font specification"
+msgstr "Ugyldig skrifttypespecifikation"
+
+msgid "&Dismiss"
+msgstr "&Luk"
+
+msgid "no specific match"
+msgstr "intet specifikt match"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Skrifttypevælger"
+
+msgid "Name:"
+msgstr "Navn:"
+
+msgid "Show size in Points"
+msgstr "Vis størrelse i punkter"
+
+msgid "Encoding:"
+msgstr "Kodning:"
+
+msgid "Font:"
+msgstr "Skrifttype:"
+
+msgid "Style:"
+msgstr "Stil:"
+
+msgid "Size:"
+msgstr "Størrelse:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: FEJL ved Hangul automata"
+
+msgid "E550: Missing colon"
+msgstr "E550: Manglende kolon"
+
+msgid "E551: Illegal component"
+msgstr "E551: Ulovlig komponent"
+
+msgid "E552: digit expected"
+msgstr "E552: ciffer ventet"
+
+#, c-format
+msgid "Page %d"
+msgstr "Side %d"
+
+msgid "No text to be printed"
+msgstr "Ingen tekst at udskrive"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Udskriver side %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Kopi %d af %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Udskrev: %s"
+
+msgid "Printing aborted"
+msgstr "Udskrivning afbrudt"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Fejl ved skrivning til PostScript-output-fil"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Kan ikke åbne filen \"%s\""
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: Kan ikke læse PostScript-ressourcefilen \"%s\""
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: filen \"%s\" er ikke en PostScript-ressourcefil"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: filen \"%s\" er ikke en understøttet PostScript-ressourcefil"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\"-ressourcefilen har forkert version"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Inkompatibel multibyte-kodning og -tegnsæt."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset må ikke være tom med multibyte-kodning."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Ingen standardskrifttype angivet for multibyte-udskrivning."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: Kan ikke åbne PostScript-output-fil"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Kan ikke åbne filen \"%s\""
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: Kan ikke finde PostScript-ressourcefilen \"prolog.ps\""
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr "E456: Kan ikke finde PostScript-ressourcefilen \"cidfont.ps\""
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: Kan ikke finde PostScript-ressourcefilen \"%s.ps\""
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Kan ikke konvertere til udskrivningskodningen \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Sender til printer..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: Kunne ikke udskrive PostScript-fil"
+
+msgid "Print job sent."
+msgstr "Udskrivningsjob sendt."
+
+msgid "Add a new database"
+msgstr "Tilføj en ny database"
+
+msgid "Query for a pattern"
+msgstr "Forespørgsel til et mønster"
+
+msgid "Show this message"
+msgstr "Vis denne meddelelse"
+
+msgid "Kill a connection"
+msgstr "Dræb en forbindelse"
+
+msgid "Reinit all connections"
+msgstr "Geninitialisere alle forbindelser"
+
+msgid "Show connections"
+msgstr "Vis forbindelser"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Anvendelse: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Denne cscope-kommando understøtter ikke opdeling af vinduet.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Anvendelse: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: tag ikke fundet"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: fejl ved stat(%s): %d"
+
+msgid "E563: stat error"
+msgstr "E563: fejl ved stat"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s er ikke en mappe eller en gyldig cscope-database"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "Tilføjede cscope-databasen %s"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: fejl ved læsning af cscope-forbindelse %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: ukendt cscope-søgetype"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: Kunne ikke oprette cscope-pipes"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Kunne ikke fork for cscope"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "cs_create_connection setpgid mislykkedes"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection exec mislykkedes"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen for to_fp mislykkedes"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen for fr_fp mislykkedes"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Kunne ikke spawn cscope-proces"
+
+msgid "E567: no cscope connections"
+msgstr "E567: ingen cscope-forbindelser"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: ugyldigt cscopequickfix-flag %c for %c"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: ingen match fundet for cscope-forespørgsel %s af %s"
+
+msgid "cscope commands:\n"
+msgstr "cscope-kommandoer:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Anvendelse: %s)"
+
+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: Find tildelinger til symbolet\n"
+" c: Find funktioner som kalder funktionen\n"
+" d: Find funktioner som kaldes af funktionen\n"
+" e: Find dette egrep-mønster\n"
+" f: Find filen\n"
+" g: Find definitionen\n"
+" i: Find filer som #inkludere filen\n"
+" s: Find C-symbolet\n"
+" t: Find tekststrengen\n"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: kan ikke åbne cscope-database: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: kan ikke hente information for cscope-database"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: duplikeret cscope-database ikke tilføjet"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope-forbindelsen %s ikke fundet"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope-forbindelsen %s lukket"
+
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: fatal fejl i cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope-tag: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # linje"
+
+msgid "filename / context / line\n"
+msgstr "filnavn/kontekst/linje\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Fejl ved cscope: %s"
+
+msgid "All cscope databases reset"
+msgstr "Alle cscope-databaser nulstillet"
+
+msgid "no cscope connections\n"
+msgstr "ingen cscope-forbindelser\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid databasenavn prepend-sti\n"
+
+msgid "Lua library cannot be loaded."
+msgstr "Lua-bibliotek kan ikke indlæses."
+
+msgid "cannot save undo information"
+msgstr "kan ikke gemme fortrydinformation"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: Beklager, kommandoen er deaktiveret, MzScheme-bibliotekerne kunne ikke "
+"indlæses."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: Beklager, kommandoen er deaktiveret, MzScheme's racket-/base-modul "
+"kunne ikke indlæses."
+
+msgid "invalid expression"
+msgstr "ugyldigt udtryk"
+
+msgid "expressions disabled at compile time"
+msgstr "udtryk deaktiveret ved kompileringstid"
+
+msgid "hidden option"
+msgstr "skjult tilvalg"
+
+msgid "unknown option"
+msgstr "ukendt tilvalg"
+
+msgid "window index is out of range"
+msgstr "vinduesindeks udenfor område"
+
+msgid "couldn't open buffer"
+msgstr "kan ikke åbne buffer"
+
+msgid "cannot delete line"
+msgstr "kan ikke slette linje"
+
+msgid "cannot replace line"
+msgstr "kan ikke erstatte linje"
+
+msgid "cannot insert line"
+msgstr "kan ikke indsætte linje"
+
+msgid "string cannot contain newlines"
+msgstr "streng må ikke indeholde linjeskift"
+
+msgid "error converting Scheme values to Vim"
+msgstr "fejl ved konvertering af Scheme-værdier til Vim"
+
+msgid "Vim error: ~a"
+msgstr "Fejl ved Vim: ~a"
+
+msgid "Vim error"
+msgstr "Fejl ved Vim"
+
+msgid "buffer is invalid"
+msgstr "buffer er ugyldig"
+
+msgid "window is invalid"
+msgstr "vindue er ugyldigt"
+
+msgid "linenr out of range"
+msgstr "linjenummer udenfor område"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "ikke tilladt i Vim-sandboksen"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: Denne Vim kan ikke udføre :python efter brug af :py3"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Beklager, kommandoen er deaktiveret, Python-biblioteket kunne ikke "
+"indlæses."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: Beklager, kommandoen er deaktiveret, Python's site-modul kunne ikke "
+"indlæses."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Kan ikke starte Python rekursivt"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: Denne Vim kan ikke udføre :py3 efter brug af :python"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ skal være en instans af streng"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Beklager, kommandoen er deaktiveret, Ruby-biblioteket kunne ikke "
+"indlæses."
+
+msgid "E267: unexpected return"
+msgstr "E267: uventet return"
+
+msgid "E268: unexpected next"
+msgstr "E268: uventet next"
+
+msgid "E269: unexpected break"
+msgstr "E269: uventet break"
+
+msgid "E270: unexpected redo"
+msgstr "E270: uventet redo"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: prøv igen udenfor rescue clause"
+
+msgid "E272: unhandled exception"
+msgstr "E272: uhåndteret undtagelse"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: ukendt longjmp-status %d"
+
+msgid "invalid buffer number"
+msgstr "ugyldigt buffernummer"
+
+msgid "not implemented yet"
+msgstr "endnu ikke implementeret"
+
+msgid "cannot set line(s)"
+msgstr "kan ikke sætte linje(r)"
+
+msgid "invalid mark name"
+msgstr "ugyldigt mærkenavn"
+
+msgid "mark not set"
+msgstr "mærke ikke sat"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "række %d kolonne %d"
+
+msgid "cannot insert/append line"
+msgstr "kan ikke indsætte/tilføje linje"
+
+msgid "line number out of range"
+msgstr "linjenummer udenfor område"
+
+msgid "unknown flag: "
+msgstr "ukendt flag: "
+
+msgid "unknown vimOption"
+msgstr "ukendt vimOption"
+
+msgid "keyboard interrupt"
+msgstr "tastaturafbryd"
+
+msgid "vim error"
+msgstr "fejl ved vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "kan ikke oprette buffer-/vindue-kommando: objekt slettes"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"kan ikke registrere callback-kommando: buffer/vindue er allerede ved at "
+"blive slettet"
+
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: FATAL FEJL VED TCL: reflist korrupt!? Rapportér det venligst til vim-"
+"dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"kan ikke registrere callback-kommando: buffer-/vindue-reference ikke fundet"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Beklager, kommandoen er deaktiveret: Tcl-biblioteket kunne ikke "
+"indlæses."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: afslutningskode %d"
+
+msgid "cannot get line"
+msgstr "kan ikke hente linje"
+
+msgid "Unable to register a command server name"
+msgstr "Kan ikke registrere et kommandoservernavn"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Kunne ikke sende kommando til destinationsprogrammet"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Ugyldigt server-id brugt: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr ""
+"E251: Registreringsegenskab for VIM-instans er dårligt udformet. Slettet!"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Duplikeret nøgle i JSON: \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Manglende komma i liste: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Manglende slutning på List ']': %s"
+
+msgid "Unknown option argument"
+msgstr "Ukendt tilvalgsargument"
+
+msgid "Too many edit arguments"
+msgstr "For mange redigeringsargumenter"
+
+msgid "Argument missing after"
+msgstr "Argument mangler efter"
+
+msgid "Garbage after option argument"
+msgstr "Affald efter tilvalgsargument"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr ""
+"For mange \"+kommando\"-, \"-c kommando\"- eller \"--cmd kommando\"-argumenter"
+
+msgid "Invalid argument for"
+msgstr "Ugyldigt argument for"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d filer at redigere\n"
+
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans understøttes ikke med denne GUI\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' kan ikke bruges: ikke aktiveret ved kompileringstid\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Denne Vim blev ikke kompileret med diff-funktionaliteten."
+
+msgid "Attempt to open script file again: \""
+msgstr "Forsøg på at åbne scriptfil igen: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Kan ikke åbne til læsning: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Kan ikke åbne for script-output: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Fejl: Kunne ikke starte gvim fra NetBeans\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr "Vim: Fejl: Denne version af Vim kører ikke i en Cygwin-terminal\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Advarsel: Output er ikke til en terminal\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Advarsel: Input er ikke fra en terminal\n"
+
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc-kommandolinje"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Kan ikke læse fra \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Mere info med: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[fil ..] rediger angivne fil(er)"
+
+msgid "- read text from stdin"
+msgstr "- læs tekst fra stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag rediger fil hvor tag er defineret"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [fejlfil] rediger fil med første fejl"
+
+msgid ""
+"\n"
+"\n"
+"usage:"
+msgstr ""
+"\n"
+"\n"
+"anvendelse:"
+
+msgid " vim [arguments] "
+msgstr " vim [argumenter] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" eller:"
+
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Når der ikke skelnes mellem store og små bogstaver, så tilføj / i "
+"begyndelsen for at gøre flag til store bogstaver"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Argumenter:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tKun filnavne herefter"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tUdvid ikke jokertegn"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistrer denne gvim til OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tAfregistrer gvim for OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tKør med GUI (ligesom \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f eller --nofork\tForgrund: Fork ikke når GUI startes"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi-tilstand (ligesom \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx-tilstand (ligesom \"ex\")"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\tForbedret Ex-tilstand"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tStille (batch) tilstand (kun til \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff-tilstand (ligesom \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tEasy-tilstand (ligesom \"evim\", tilstandsløs)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tSkrivebeskyttet tilstand (ligesom \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tRestriktiv tilstand (ligesom \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tÆndringer (skrivning af filer) ikke tilladt"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tÆndringer i tekst ikke tilladt"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tBinær tilstand"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp-tilstand"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tKompatibel med Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tIkke fuldt ud Vi-kompatibel: 'nocompatible'"
+
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr "-V[N][fnavn]\t\tVær uddybende [niveau N] [log meddelelser til fnavn]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tFejlretningstilstand"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tIngen swap-fil, brug kun hukommelse"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tOplist swap-filer og afslut"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (med filnavn)\tGendan session som holdt op med at virke"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tSamme som -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tBrug ikke newcli til at åbne vindue"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <enhed>\t\tBrug <enhed> til I/O"
+
+msgid "-A\t\t\tstart in Arabic mode"
+msgstr "-A\t\t\tstart i arabisk tilstand"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tStart i hebraisk tilstand"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tStart i persisk tilstand"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <terminal>\tSæt terminaltype til <terminal>"
+
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr ""
+"--not-a-term\t\tSpring advarsel over for input/output som ikke er en terminal"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr "--ttyfail\t\tAfslut hvis input eller output ikke er en terminal"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tBrug <vimrc> i stedet for nogen .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tBrug <gvimrc> i stedet for nogen .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tIndlæs ikke plugin-scripts"
+
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-p[N]\t\tÅbn N fanebladssider (standard: én pr. fil)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tÅbn N vinduer (standard: én pr. fil)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tLigesom -o men opdel lodret"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tBegynd ved slutningen af filen"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<lnum>\t\tBegynd ved linje <lnum>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr "--cmd <kommando>\tUdfør <kommando> inden indlæsning af vimrc-filer"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <kommando>\tUdfør <kommando> efter indlæsning af den første fil"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr "-S <session>\t\tSource filen <session> efter indlæsning af den første fil"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr "-s <scriptind>\tLæs normal tilstand-kommandoer fra filen <scriptind>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr ""
+"-w <scriptud>\tTilføj alle indtastede kommandoer til slutningen af filen "
+"<scriptud>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <scriptud>\tSkriv alle indtastede kommandoer til filen <scriptud>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tRediger krypterede filer"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tForbind vim til denne X-server"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tOpret ikke forbindelse til X-server"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <filer>\tRediger <filer> i en Vim-server, hvis det er muligt"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent <filer> Samme, men vær tavs hvis der ikke er nogen server"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <filer> Som --remote men vent på filer som skal redigeres"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <filer> Samme, men vær tavs hvis der ikke er nogen "
+"server"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <filer> Som --remote men brug fanebladsside "
+"pr. fil"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <nøgler>\tSend <nøgler> til en Vim-server og afslut"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <udtryk>\tEvaluér <udtryk> i en Vim-server og udskriv "
+"resultatet"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tOplist tilgængelige Vim-servernavne og afslut"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <navn>\tSend til/bliv Vim-serveren <navn>"
+
+msgid "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr "--startuptime <fil>\tSkriv meddelelser om opstartstiming til <fil>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tBrug <viminfo> i stedet for .viminfo"
+
+msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo"
+msgstr "--clean\t\t'nocompatible', Vim-standarder, ingen plugins, ingen viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h eller --help\tUdskriv hjælp (denne meddelelse) og afslut"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tUdskriv versionsinformation og afslut"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argumenter som genkendes af gvim (Motif-version):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argumenter som genkendes af gvim (neXtaw-version):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argumenter som genkendes af gvim (Athena-version):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\tKør vim på <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tStart vim som ikon"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <farve>\tBrug <farve> til baggrunden (også: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <farve>\tBrug <farve> til normal tekst (også: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <skrifttype>\tBrug <skrifttype> til normal tekst (også: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <skrifttype>\tBrug <skrifttype> til fed tekst"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <skriftt.>\tBrug <skrifttype> til kursiv tekst"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tBrug <geom> for indledende geometri (også: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <bredde>\tBrug en kantbredde på <bredde> (også: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <bredde> Brug en rullebjælkebredde på <bredde> (også: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <højde>\tBrug en menulinjehøjde på <højde> (også: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tBrug omvendt grafik (også: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tBrug ikke omvendt grafik (også: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <ressource>\tSæt den angivne ressource"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argumenter genkendt af gvim (GTK+-version):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\tKør vim på <display> (også: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <rolle>\tSæt en unik rolle til at identificere hovedvinduet"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tÃ…bn Vim i en anden GTK-widget"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tFÃ¥ gvim til at skrive vinduets ID til stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <forældertitel>\tÅbn Vim i forælderprogram"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tÃ…bn Vim i en anden win32-widget"
+
+msgid "No display"
+msgstr "Intet display"
+
+msgid ": Send failed.\n"
+msgstr ": Sending mislykkedes.\n"
+
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Sending mislykkedes. Prøver at udføre lokalt\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d af %d redigeret"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Intet display: Send-udtryk mislykkedes.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Send-udtryk mislykkedes.\n"
+
+msgid "No marks set"
+msgstr "Ingen mærker sat"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Ingen mærker matcher \"%s\""
+
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"mærke linje kol fil/tekst"
+
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" hop linje kol fil/tekst"
+
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"skift linje kol tekst"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Filmærker:\n"
+
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Hopliste (nyeste først):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# Historik over mærker i filer (nyeste til ældste):\n"
+
+msgid "Missing '>'"
+msgstr "Manglende '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Ikke en gyldig tegnkodningstabel"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Kan ikke sætte IC-værdier"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Kunne ikke oprette inputkontekst"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Kunne ikke åbne inputmetode"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Advarsel: Kunne ikke sætte destroy callback til IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: inputmetode understøtter ikke nogen stil"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: inputmetode understøtter ikke min preedit-type"
+
+msgid "E293: block was not locked"
+msgstr "E293: blok blev ikke låst"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Søgefejl ved læsning af swap-fil"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Læsefejl i swap-fil"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Søgefejl ved skrivning af swap-fil"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Skrivefejl i swap-fil"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Swap-filen findes allerede (symlink angreb?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Blev blok nr. 0 ikke hentet?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Blev blok nr. 1 ikke hentet?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Blev blok nr. 2 ikke hentet?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Fejl ved opdatering af crypt for swap-fil"
+
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: Ups, mistede swap-filen!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Kunne ikke omdøbe swap-fil"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr "E303: Kan ikke åbne swap-filen for \"%s\", gendannelse er ikke muligt"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Blev blok 0 ikke hentet??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: Fandt ingen swap-fil for %s"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "Indtast antal swap-filer som der skal bruges (0 for at afslutte): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: Kan ikke åbne %s"
+
+msgid "Unable to read block 0 from "
+msgstr "Kan ikke læse blok 0 fra "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Måske er der ikke foretaget nogen ændringer eller Vim opdaterede ikke swap-"
+"filen."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " kan ikke bruges med denne version af Vim.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "Brug Vim version 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s ligner ikke en Vim swap-fil"
+
+msgid " cannot be used on this computer.\n"
+msgstr " kan ikke bruges på denne computer.\n"
+
+msgid "The file was created on "
+msgstr "Filen blev oprettet på "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"eller filen er beskadiget."
+
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: %s er krypteret og denne version af Vim understøtter ikke kryptering"
+
+msgid " has been damaged (page size is smaller than minimum value).\n"
+msgstr " er beskadiget (sidestørrelsen er mindre end minimumsværdien).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "Bruger swap-filen \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Den originale fil \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Advarsel: Den originale fil kan være ændret"
+
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Swap-filen er krypteret: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"Hvis du indtastede en ny crypt-nøgle men ikke skrev tekstfilen,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"så indtast den nye crypt-nøgle."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"Hvis du skrev tekstfilen efter crypt-nøglen blev ændret, så tryk på enter"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"for at bruge den samme nøgle til tekstfilen og swap-filen"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Kan ikke læse blok 1 fra %s"
+
+msgid "???MANY LINES MISSING"
+msgstr "???MANGE LINJER MANGLER"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???LINJEANTAL FORKERT"
+
+msgid "???EMPTY BLOCK"
+msgstr "???TOM BLOK"
+
+msgid "???LINES MISSING"
+msgstr "???LINJER MANGLER"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: Forkert ID for blok 1 (%s ikke en .swp-fil?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???BLOK MANGLER"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? herfra indtil ???SLUT kan linjer være rodet"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? herfra indtil ???SLUT kan linjer være indsat/slettet"
+
+msgid "???END"
+msgstr "???SLUT"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Gendannelse afbrudt"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Fejl registreret ved gendannelse; kig efter linjer som begynder med "
+"???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Se \":help E312\" for mere information."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Gendannelse gennemført. Du bør tjekke om alt er OK."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Det kan være du vil skrive filen under et andet navn\n"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "og kør diff men den originale fil for at tjekke for ændringer)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr ""
+"Gendannelse gennemført. Bufferens indhold er det samme som filens indhold."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"Det kan være du vil slette .swp-filen nu.\n"
+"\n"
+
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr "Bruger crypt-nøglen fra swap-filen til tekstfilen.\n"
+
+msgid "Swap files found:"
+msgstr "Swap-filer fundet:"
+
+msgid " In current directory:\n"
+msgstr " I nuværende mappe:\n"
+
+msgid " Using specified name:\n"
+msgstr " Bruger angivne navn:\n"
+
+msgid " In directory "
+msgstr " I mappe "
+
+msgid " -- none --\n"
+msgstr " -- ingen --\n"
+
+msgid " owned by: "
+msgstr " ejet af: "
+
+msgid " dated: "
+msgstr " dateret: "
+
+msgid " dated: "
+msgstr " dateret: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [fra Vim version 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [ligner ikke en Vim swap-fil]"
+
+msgid " file name: "
+msgstr " filnavn: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" ændret: "
+
+msgid "YES"
+msgstr "JA"
+
+msgid "no"
+msgstr "nej"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" brugernavn: "
+
+msgid " host name: "
+msgstr " værtsnavn: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" værtsnavn: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" proces-ID: "
+
+msgid " (still running)"
+msgstr " (kører stadig)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ikke anvendelig med denne version af Vim]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [ikke anvendelig på denne computer]"
+
+msgid " [cannot be read]"
+msgstr " [kan ikke læses]"
+
+msgid " [cannot be opened]"
+msgstr " [kan ikke åbnes]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Kan ikke bevares, der er ikke nogen swap-fil"
+
+msgid "File preserved"
+msgstr "Fil bevaret"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Bevaring mislykkedes"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: ugyldig lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: kan ikke finde linje %ld"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: forkert blok-id for pointer 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx skal være 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: Opdaterede for mange blokke?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: forkert blok-id for pointer 4"
+
+msgid "deleted block 1?"
+msgstr "slettede blok 1?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Kan ikke finde linje %ld"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: forkert blok-id for pointer"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count er nul"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: linjenummer udenfor område: %ld efter slutningen"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: linje antal forkert i blok %ld"
+
+msgid "Stack size increases"
+msgstr "Stakstørrelse øges"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: forkert blok-id for pointer 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Symlink-løkke for \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: OBS"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Fandt en swap-fil ved navn \""
+
+msgid "While opening file \""
+msgstr "Ved åbning af filen \""
+
+msgid " NEWER than swap file!\n"
+msgstr " NYERE end swap-fil!\n"
+
+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. Quit, or continue with caution.\n"
+msgstr ""
+"\n"
+"(1) Et andet program redigere muligvis den samme fil. Hvis det er tilfældet,\n"
+" så pas på ikke at ende med to forskellige instanser af den samme\n"
+" fil når der foretages ændringer. Afslut, eller fortsæt med forsigtighed.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) En redigeringssession for filen holdt op med at virke.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Hvis det er tilfældet, så brug \":recover\" eller \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" for at gendanne ændringerne (se \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Hvis du allerede har gjort det, så slet swap-filen \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" for at undgå denne meddelelse.\n"
+
+msgid "Swap file \""
+msgstr "Swap-filen \""
+
+msgid "\" already exists!"
+msgstr "\" findes allerede!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - OBS"
+
+msgid "Swap file already exists!"
+msgstr "Swap-filen findes allerede!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Ã…bn skrivebeskyttet\n"
+"&Rediger alligevel\n"
+"&Gendan\n"
+"&Afslut\n"
+"&Afbryd"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"&Ã…bn skrivebeskyttet\n"
+"&Rediger alligevel\n"
+"&Gendan\n"
+"&Slet den\n"
+"&Afslut\n"
+"&Afbryd"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: For mange swap-filer fundet"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Del af sti til menupunkt er ikke undermenu"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Menuen findes kun i en anden tilstand"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ingen menu \"%s\""
+
+msgid "E792: Empty menu name"
+msgstr "E792: Tomt menunavn"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Menusti må ikke lede til en undermenu"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Må ikke tilføje menupunkter direkte til menulinje"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Separator må ikke være del af en menusti"
+
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Menuer ---"
+
+msgid "Tear off this menu"
+msgstr "Løsriv menuen"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menu ikke defineret for %s-tilstand"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Menusti skal lede til et menupunkt"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Menu ikke fundet: %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Menusti skal lede til en undermenu"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Menu ikke fundet - tjek menunavne"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Fejl registreret ved behandling af %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "linje %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: Ugyldigt registernavn: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Oversætter: scootergrisen"
+
+msgid "Interrupt: "
+msgstr "Afbryd: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Tryk på ENTER eller skriv kommando for at fortsætte"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s linje %ld"
+
+msgid "-- More --"
+msgstr "-- Mere --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " MELLEMRUM/d/j: skærm/side/linje ned, b/u/k: op, q: afslut "
+
+msgid "Question"
+msgstr "Spørgsmål"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Ja\n"
+"&Nej"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Ja\n"
+"&Nej\n"
+"Gem &alle\n"
+"&Forkast alle\n"
+"&Annuller"
+
+msgid "Select Directory dialog"
+msgstr "Vælg mappe-dialog"
+
+msgid "Save File dialog"
+msgstr "Gem fil-dialog"
+
+msgid "Open File dialog"
+msgstr "Ã…bn fil-dialog"
+
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Beklager, ingen filbrowser i konsol-tilstand"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Ikke nok argumenter for printf()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Ventede flydende kommatal-argument for printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: For mange argumenter til printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Advarsel: Ændre en skrivebeskyttet fil"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr "Skriv nummer og <Enter> eller klik med musen (tom annullerer): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "Skriv nummer og <Enter> (tom annullerer): "
+
+msgid "1 more line"
+msgstr "1 linje mere"
+
+msgid "1 line less"
+msgstr "1 linje mindre"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld linjer mere"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld linjere mindre"
+
+msgid " (Interrupted)"
+msgstr " (Afbrudt)"
+
+msgid "Beep!"
+msgstr "Bip!"
+
+msgid "ERROR: "
+msgstr "FEJL: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[byte] samlet allok-frigivet %lu-%lu, i brug %lu, spidspunktsbrug %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[kald] samlet re/malloc()'er %lu, samlet free()'er %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Linje er ved at blive for lang"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Intern fejl: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Ikke mere ledig hukommelse! (allokerer %lu byte)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Kalder skal til udførelse af: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: Manglende kolon"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Ulovlig tilstand"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Ulovlig museform"
+
+msgid "E548: digit expected"
+msgstr "E548: ciffer ventet"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Ulovlig procent"
+
+msgid "E854: path too long for completion"
+msgstr "E854: sti for lang til fuldførelse"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Ugyldig sti: '**[nummer]' skal være i slutningen af stien eller "
+"efterfølges af '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Kan ikke finde mappen \"%s\" i cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Kan ikke finde filen \"%s\" i path"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Ikke flere mappe \"%s\" fundet i cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Ikke flere fil \"%s\" fundet i path"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Forkert adgangstilstand for NetBeans-forbindelsens info-fil: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: NetBeans-forbindelse mistet for buffer %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: netbeans understøttes ikke med denne GUI"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: netbeans allerede forbundet"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s er skrivebeskyttet (tilføj ! for at tilsidesætte)"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Ingen identifikator under markør"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' er tom"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Eval-funktionalitet ikke tilgængelig"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Advarsel: terminal kan ikke fremhæve"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Ingen streng under markør"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Kan ikke slette sammenfoldninger med nuværende 'foldmethod'"
+
+msgid "E664: changelist is empty"
+msgstr "E664: ændringsliste er tom"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Ved begyndelsen af ændringsliste"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Ved slutningen af ændringsliste"
+
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim"
+msgstr ""
+"Skriv :qa! og tryk på <Enter> for at droppe alle ændringer og afslut Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 linje %sed 1 gang"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 linje %sed %d gange"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld linjer %sed 1 gang"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld linjer %sed %d gange"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld linjer at indrykke... "
+
+msgid "1 line indented "
+msgstr "1 linje indrykket "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld linjer indrykket "
+
+msgid "E748: No previously used register"
+msgstr "E748: Intet tidligere brugt register"
+
+msgid "cannot yank; delete anyway"
+msgstr "kan ikke rykke; slet alligevel"
+
+msgid "1 line changed"
+msgstr "1 linje ændret"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld linjer ændret"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "frigør %ld linjer"
+
+#, c-format
+msgid " into \"%c"
+msgstr " i \"%c"
+
+#, c-format
+msgid "block of 1 line yanked%s"
+msgstr "blok på 1 linje rykket%s"
+
+#, c-format
+msgid "1 line yanked%s"
+msgstr "1 linje rykket%s"
+
+#, c-format
+msgid "block of %ld lines yanked%s"
+msgstr "blok på %ld linjer rykket%s"
+
+#, c-format
+msgid "%ld lines yanked%s"
+msgstr "%ld linjer rykket%s"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: Intet i register %s"
+
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- Registre ---"
+
+msgid "Illegal register name"
+msgstr "Ulovligt registernavn"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# Registre:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Ukendt registertype %d"
+
+msgid ""
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr ""
+"E883: søgemønster og udtryksregister må ikke indeholde to eller flere linjer"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld kolonner; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
+msgstr "Markerede %s%ld af %ld linje; %lld af %lld ord; %lld af %lld byte"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
+msgstr ""
+"Markerede %s%ld af %ld linje; %lld af %lld ord; %lld af %lld tegn; %lld af %"
+"lld byte"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "Kol %s af %s; Linje %ld af %ld; Ord %lld af %lld; Byte %lld af %lld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
+msgstr ""
+"Kol %s af %s; Linje %ld af %ld; Ord %lld af %lld; Tegn %lld af %lld; Byte %"
+"lld af %lld"
+
+#, c-format
+msgid "(+%lld for BOM)"
+msgstr "(+%lld for BOM)"
+
+msgid "Thanks for flying Vim"
+msgstr "Tak fordi du fløj med Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Ukendt tilvalg"
+
+msgid "E519: Option not supported"
+msgstr "E519: Tilvalg understøttes ikke"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Ikke tilladt på en tilstandslinje"
+
+msgid "E846: Key code not set"
+msgstr "E846: Tastekode ikke sat"
+
+msgid "E521: Number required after ="
+msgstr "E521: Nummer kræves efter ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Ikke fundet i termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Ulovligt tegn <%s>"
+
+#, c-format
+msgid "For option %s"
+msgstr "For tilvalget %s"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: Kan ikke sætte 'term' til tom streng"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Kan ikke skifte term i GUI"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Brug \":gui\" til at starte GUI'en"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' og 'patchmode' er ens"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: Er i konflikt med værdien af 'listchars'"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: Er i konflikt med værdien af 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Kan ikke ændres i GTK+ 2 GUI'en"
+
+#, c-format
+msgid "E950: Cannot convert between %s and %s"
+msgstr "E950: Kan ikke konvertere mellem %s og %s"
+
+msgid "E524: Missing colon"
+msgstr "E524: Manglende kolon"
+
+msgid "E525: Zero length string"
+msgstr "E525: Streng uden længde"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: Manglende nummer efter <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: Manglende komma"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Skal angive en '-værdi"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: indeholder tegn som ikke kan udskrives eller er bredt"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: Ugyldig skrifttype(r)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: kan ikke vælge skrifttypesæt"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Ugyldigt skrifttypesæt"
+
+msgid "E533: can't select wide font"
+msgstr "E533: kan ikke vælge bred skrifttype"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Ugyldig bred skrifttype"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Ulovligt tegn efter <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: komma kræves"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' skal være tom eller indeholde %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Ingen understøttelse af mus"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Ulukket udtryk-sekvens"
+
+msgid "E541: too many items"
+msgstr "E541: for mange punkter"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: ubalancerede grupper"
+
+msgid "E946: Cannot make a terminal with running job modifiable"
+msgstr "E946: Kan ikke gøre en terminal med kørende job ændringsbar"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Der findes allerede et forhåndsvisningsvindue"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: Arabisk kræver UTF-8, brug ':set encoding=utf-8'"
+
+msgid "E954: 24-bit colors are not supported on this environment"
+msgstr "E954: 24-bit farver understøttes ikke i dette miljø"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Skal være mindst %d linjer"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Skal være mindst %d kolonner"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Ukendt tilvalg: %s"
+
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Nummer kræves: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Terminal-koder ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- Værdier for globale tilvalg ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- Værdier for lokale tilvalg ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Tilvalg ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: Fejl ved get_varp"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': Matchende tegn mangler for %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Ekstra tegn efter semikolon: %s"
+
+msgid "cannot open "
+msgstr "kan ikke åbne "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Kan ikke åbne vindue!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Behøver Amigados version 2.04 eller senere\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Behøver %s version %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Kan ikke åbne NIL:\n"
+
+msgid "Cannot create "
+msgstr "Kan ikke oprette "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim afsluttede med %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "kan ikke skifte konsoltilstand ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ikke en konsol??\n"
+
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Kan ikke udføre skal med -f-tilvalget"
+
+msgid "Cannot execute "
+msgstr "Kan ikke udføre "
+
+msgid "shell "
+msgstr "skal "
+
+msgid " returned\n"
+msgstr " returnerede\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE for lille."
+
+msgid "I/O ERROR"
+msgstr "FEJL VED I/O"
+
+msgid "Message"
+msgstr "Meddelelse"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Valg af printer mislykkedes"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "til %s på %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Ukendt skrifttype til printer: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Fejl ved udskrivning: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Udskriver '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Ulovligt tegnsætnavn \"%s\" i skrifttypenavnet \"%s\""
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: Ulovligt kvalitetsnavn \"%s\" i skrifttypenavnet \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Ulovligt tegn '%c' i skrifttypenavnet \"%s\""
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Ã…bningen af X-displayet tog %ld ms"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Fik fejl ved X\n"
+
+msgid "Testing the X display failed"
+msgstr "Test af X-displayet mislykkedes"
+
+msgid "Opening the X display timed out"
+msgstr "Ã…bningen af X-displayet fik timeout"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Kunne ikke hente sikkerhedskontekst for "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Kunne ikke sætte sikkerhedskontekst for "
+
+#, c-format
+msgid "Could not set security context %s for %s"
+msgstr "Kunne ikke sætte sikkerhedskonteksten %s for %s"
+
+#, c-format
+msgid "Could not get security context %s for %s. Removing it!"
+msgstr "Kunne ikke hente sikkerhedskonteksten %s for %s. Fjerner den!"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Kan ikke udføre skallen sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"skal returnerede "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Kan ikke oprette pipes\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Kan ikke fork\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Kan ikke udføre skallen "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Kommando termineret\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP mistede ICE-forbindelse"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Ã…bningen af X-displayet mislykkedes"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP-håndtering save-yourself-anmodning"
+
+msgid "XSMP opening connection"
+msgstr "XSMP åbner forbindelse"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICE-forbindelse watch mislykkedes"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection mislykkedes: %s"
+
+msgid "At line"
+msgstr "PÃ¥ linje"
+
+msgid "Could not load vim32.dll!"
+msgstr "Kunne ikke indlæse vim32.dll!"
+
+msgid "VIM Error"
+msgstr "Fejl ved VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Kunne ikke rette op på funktion-pointere til DLL'en!"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Fangede %s-hændelse\n"
+
+msgid "close"
+msgstr "luk"
+
+msgid "logoff"
+msgstr "log ud"
+
+msgid "shutdown"
+msgstr "luk ned"
+
+msgid "E371: Command not found"
+msgstr "E371: Kommando ikke fundet"
+
+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 ""
+"VIMRUN.EXE ikke fundet i din $PATH.\n"
+"Eksterne kommandoer sættes ikke på pause efter fuldførelse.\n"
+"Se :help win32-vimrun for mere information."
+
+msgid "Vim Warning"
+msgstr "Advarsel ved Vim"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "skal returnerede %d"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Nuværende placeringsliste blev ændret"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: For mange %%%c i formatet streng"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Uventet %%%c i formatet streng"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: Manglende ] i formatet streng"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Ikke-understøttet %%%c i formatet streng"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Ugyldig %%%c i præfiks for formatet streng"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Ugyldig %%%c i formatet streng"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' indeholder ikke noget mønter"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Manglende eller tomt mappenavn"
+
+msgid "E553: No more items"
+msgstr "E553: Ikke flere punkter"
+
+msgid "E924: Current window was closed"
+msgstr "E924: Nuværende vindue blev lukket"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Nuværende quickfix blev ændret"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d af %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (linje slettet)"
+
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%sfejlliste %d af %d; %d fejl "
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Nederst i quickfix-stakken"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Øverst i quickfix-stakken"
+
+msgid "No entries"
+msgstr "Ingen poster"
+
+msgid "Error file"
+msgstr "Fejlfil"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: Filnavn mangler eller ugyldigt mønster"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Kan ikke åbne filen \"%s\""
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Buffer er ikke indlæst"
+
+msgid "E777: String or List expected"
+msgstr "E777: Streng eller liste ventet"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: ugyldigt punkt i %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: Manglende ] efter %s["
+
+msgid "E944: Reverse range in character class"
+msgstr "E944: Baglæns område i tegnklasse"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: Område for stort i tegnklasse"
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Ikke-matchet %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Ikke-matchet %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Ikke-matchet %s)"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( ikke tilladt her"
+
+msgid "E67: \\z1 et al. not allowed here"
+msgstr "E67: \\z1 og andre ikke tilladt her"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: Manglende ] efter %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Tom %s%%[]"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Ulovlig tilbage-reference"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Mønster for langt"
+
+msgid "E50: Too many \\z("
+msgstr "E50: For mange \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: For mange %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Ikke-matchet \\z("
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: ugyldigt tegn efter %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: For mange komplekse %s{...}s"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Indlejret %s*"
+
+#, c-format
+msgid "E62: Nested %s%c"
+msgstr "E62: Indlejret %s%c"
+
+msgid "E63: invalid use of \\_"
+msgstr "E63: ugyldig brug af \\_"
+
+#, c-format
+msgid "E64: %s%c follows nothing"
+msgstr "E64: %s%c efterfølger intet"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Ugyldigt tegn efter \\z"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Ugyldigt tegn efter %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Ugyldigt tegn efter %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: Fejl ved syntaks i %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Eksterne undermatch:\n"
+
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (NFA regexp) kan ikke gentage %s"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: \\%#= må kun efterfølges af 0, 1 eller 2. Bruger den automatiske motor "
+
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "Skifter til backtracking RE-motor for mønster: "
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Mødte slutningen på regulært udtryk for tidligt"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA regexp) Forkert placeret %c"
+
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (NFA regexp) Ugyldig tegnklasse: %ld"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Ukendt operator '\\z%c'"
+
+msgid "E951: \\% value too large"
+msgstr "E951: \\%-værdi for stor"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) Ukendt operator '\\%%%c'"
+
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Fejl ved bygning af NFA med ligestillet klasse!"
+
+#, c-format
+msgid "E869: (NFA) Unknown operator '\\@%c'"
+msgstr "E869: (NFA) Ukendt operator '\\@%c'"
+
+msgid "E870: (NFA regexp) Error reading repetition limits"
+msgstr "E870: (NFA regexp) Fejl ved læsning af gentagelsesgrænser"
+
+msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgstr "E871: (NFA regexp) En multi må ikke efterfølges af en multi !"
+
+msgid "E872: (NFA regexp) Too many '('"
+msgstr "E872: (NFA regexp) For mange '('"
+
+msgid "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (NFA regexp) For mange \\z("
+
+msgid "E873: (NFA regexp) proper termination error"
+msgstr "E873: (NFA regexp) fejl ved korrekt terminering"
+
+msgid "E874: (NFA) Could not pop the stack !"
+msgstr "E874: (NFA) Kunne ikke pop'e stakken !"
+
+msgid ""
+"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
+"left on stack"
+msgstr ""
+"E875: (NFA regexp) (Ved konvertering fra postfix til NFA), for mange "
+"tilstande tilbage på stak"
+
+msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (NFA regexp) Ikke nok plads til at lagre hele NFA'en "
+
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (NFA) Kunne ikke allokere hukommelse til gennemgang af gren!"
+
+msgid ""
+"Could not open temporary log file for writing, displaying on stderr ... "
+msgstr "Kunne ikke åbne midlertidig logfil til skrivning, viser på stderr ... "
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) KUNNE IKKE Ã…BNE %s !"
+
+msgid "Could not open temporary log file for writing "
+msgstr "Kunne ikke åbne midlertidig logfil til skrivning "
+
+msgid " VREPLACE"
+msgstr " VERSTAT"
+
+msgid " REPLACE"
+msgstr " ERSTAT"
+
+msgid " REVERSE"
+msgstr " BAGLÆNS"
+
+msgid " INSERT"
+msgstr " INDSÆT"
+
+msgid " (insert)"
+msgstr " (indsæt)"
+
+msgid " (replace)"
+msgstr " (erstat)"
+
+msgid " (vreplace)"
+msgstr " (verstat)"
+
+msgid " Hebrew"
+msgstr " Hebraisk"
+
+msgid " Arabic"
+msgstr " Arabisk"
+
+msgid " (paste)"
+msgstr " (indsæt)"
+
+msgid " VISUAL"
+msgstr " VISUEL"
+
+msgid " VISUAL LINE"
+msgstr " VISUEL LINJE"
+
+msgid " VISUAL BLOCK"
+msgstr " VISUEL BLOK"
+
+msgid " SELECT"
+msgstr " VÆLG"
+
+msgid " SELECT LINE"
+msgstr " VÆLG LINJE"
+
+msgid " SELECT BLOCK"
+msgstr " VÆLG BLOK"
+
+msgid "recording"
+msgstr "optager"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: Ugyldig søgestreng: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: søgning ramte ØVERST uden match for: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: søgning ramte NEDERST uden match for: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Ventede '?' eller '/' efter ';'"
+
+msgid " (includes previously listed match)"
+msgstr " (inkluderer tidligere oplistet match)"
+
+msgid "--- Included files "
+msgstr "--- Inkluderede filer "
+
+msgid "not found "
+msgstr "ikke fundet "
+
+msgid "in path ---\n"
+msgstr "i sti ---\n"
+
+msgid " (Already listed)"
+msgstr " (Allerede oplistet)"
+
+msgid " NOT FOUND"
+msgstr " IKKE FUNDET"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Skanner inkluderede filer: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Søger efter inkluderede fil %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Match er på nuværende linje"
+
+msgid "All included files were found"
+msgstr "Alle inkluderede filer blev fundet"
+
+msgid "No included files"
+msgstr "Ingen inkluderede filer"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Kunne ikke finde definition"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Kunne ikke finde mønster"
+
+msgid "Substitute "
+msgstr "Erstatning "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# Sidste %sSøgemønster:\n"
+"~"
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Stavekontrol er ikke aktiveret"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr "Advarsel: Kan ikke finde ordlisten \"%s_%s.spl\" eller \"%s_ascii.spl\""
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Advarsel: Kan ikke finde ordlisten \"%s.%s.spl\" eller \"%s.ascii.spl\""
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: SpellFileMissing-autokommando slettede buffer"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Advarsel: regionen %s understøttes ikke"
+
+msgid "Sorry, no suggestions"
+msgstr "Beklager, ingen forslag"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Beklager, kun %ld forslag"
+
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Ændr \"%.*s\" til:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Ingen tidligere staveerstatning"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Ikke fundet: %s"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: Afkortet spell-fil"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "Efterstillede tekst i %s linje %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Affix-navn for langt i %s linje %d: %s"
+
+msgid "E761: Format error in affix file FOL, LOW or UPP"
+msgstr "E761: Fejl i format i affix-filens FOL, LOW eller UPP"
+
+msgid "E762: Character in FOL, LOW or UPP is out of range"
+msgstr "E762: Tegn i FOL, LOW eller UPP er udenfor område"
+
+msgid "Compressing word tree..."
+msgstr "Komprimerer ordtræ..."
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Læser spell-filen \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Det ligner ikke en spell-fil"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Gammel spell-fil, som skal opdateres"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: Spell-filen er til en nyere version af Vim"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Ikke-understøttet sektion i spell-fil"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: ligner ikke en .sug-fil: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Gammel .sug-fil, som skal opdateres: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug-filen er til en nyere version af Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug-filen matcher ikke .spl-filen: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: fejl ved læsning af .sug-fil: %s"
+
+#, c-format
+msgid "Reading affix file %s ..."
+msgstr "Læser affix-filen %s ..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "Mislykkede konvertering for ordet %s linje %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Konvertering i %s understøttes ikke: fra %s til %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konvertering i %s understøttes ikke"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Ugyldig værdi for FLAG i %s linje %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG efter brug af flag i %s linje %d: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Definering af COMPOUNDFORBIDFLAG efter PFX-punkt kan give forkerte "
+"resultater i %s linje %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"Definering af COMPOUNDPERMITFLAG efter PFX-punkt kan give forkerte "
+"resultater i %s linje %d"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Forkert COMPOUNDRULES-værdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Forkert COMPOUNDWORDMAX-værdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Forkert COMPOUNDMIN-værdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Forkert COMPOUNDSYLMAX-værdi i %s linje %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Forkert CHECKCOMPOUNDPATTERN-værdi i %s linje %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr "Forskellige kombineringsflag i fortsat affix-blok i %s linje %d: %s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Duplikeret affix i %s linje %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"Affix også brugt for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST i %s "
+"linje %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Ventede Y eller N i %s linje %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Ødelagt betingelse i %s linje %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Ventede REP(SAL)-tælling i %s linje %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Ventede MAP-tælling i %s linje %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Duplikeret tegn i MAP i %s linje %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "Ikke-genkendt eller duplikeret punkt i %s linje %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "Manglende FOL-/LOW-/UPP-linje i %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX brugt uden SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "For mange udskudte præfikser"
+
+msgid "Too many compound flags"
+msgstr "For mange compound-flag"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "For mange udskudte præfikser og/eller compound-flag"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "Manglende SOFO%s-linje i %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "BÃ¥de SAL- og SOFO-linjer i %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Flag er ikke et nummer i %s linje %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Ulovligt flag i %s linje %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr "%s-værdi er ikke den samme som bruges i en anden .aff-fil"
+
+#, c-format
+msgid "Reading dictionary file %s ..."
+msgstr "Læser ordbogsfilen %s ..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Ingen ordtælling i %s"
+
+#, c-format
+msgid "line %6d, word %6ld - %s"
+msgstr "linje %6d, ord %6ld - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Duplikeret ord i %s linje %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Første duplikeret ord i %s linje %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d duplikeret ord i %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "Ignorerede %d ord med ikke-ASCII-tegn i %s"
+
+#, c-format
+msgid "Reading word file %s ..."
+msgstr "Læser ordfilen %s ..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Duplikeret /encoding=-linje ignoreret i %s linje %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "/encoding=-linje efter ord ignoreret i %s linje %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Duplikerede /regions=-linjer ignoreret i %s linje %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "For mange regioner i %s linje %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "/-linje ignoreret i %s linje %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Ugyldigt regisionsnummer i %s linje %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Ugenkendte flag i %s linje %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "Ignorerer %d ord med ikke-ASCII-tegn"
+
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Ikke nok hukommelse, ordlisten vil være ufuldstændig"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "Komprimerede %d af %d punkter; %d (%d%%) tilbage"
+
+msgid "Reading back spell file..."
+msgstr "Læser spell-fil tilbage..."
+
+msgid "Performing soundfolding..."
+msgstr "Udfører lydsammenfoldning..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Antal ord efter lydsammenfoldning: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Samlet antal ord: %d"
+
+#, c-format
+msgid "Writing suggestion file %s ..."
+msgstr "Skriver forslagsfilen %s ..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Anslået brug af afviklingshukommelse: %d byte"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Outputfilnavn må ikke have regionsnavn"
+
+#, c-format
+msgid "E754: Only up to %ld regions supported"
+msgstr "E754: Kun op til %ld regioner understøttes"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Ugyldig region i %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Advarsel: både compounding og NOBREAK angivet"
+
+#, c-format
+msgid "Writing spell file %s ..."
+msgstr "Skriver spell-filen %s ..."
+
+msgid "Done!"
+msgstr "Færdig!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' har ingen %ld-poster"
+
+#, c-format
+msgid "Word '%.*s' removed from %s"
+msgstr "Ordet '%.*s' fjernet fra %s"
+
+#, c-format
+msgid "Word '%.*s' added to %s"
+msgstr "Ordet '%.*s' tilføjet til %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Ordtegn er ikke ens i spell-filer"
+
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: duplikeret tegn i MAP-post"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "Ingen syntakspunkter defineret for denne buffer"
+
+msgid "syntax conceal on"
+msgstr "syntax conceal on"
+
+msgid "syntax conceal off"
+msgstr "syntax conceal off"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Ulovligt argument: %s"
+
+msgid "syntax case ignore"
+msgstr "syntax case ignore"
+
+msgid "syntax case match"
+msgstr "syntax case match"
+
+msgid "syntax spell toplevel"
+msgstr "syntax spell toplevel"
+
+msgid "syntax spell notoplevel"
+msgstr "syntax spell notoplevel"
+
+msgid "syntax spell default"
+msgstr "syntax spell default"
+
+msgid "syntax iskeyword "
+msgstr "syntax iskeyword "
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Ingen sådan syntaks-cluster: %s"
+
+msgid "syncing on C-style comments"
+msgstr "synkronisering på C-style-kommentarer"
+
+msgid "no syncing"
+msgstr "ingen synkronisering"
+
+msgid "syncing starts "
+msgstr "synkronisering starter "
+
+msgid " lines before top line"
+msgstr " linjer inden øverste linje"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Syntaks-synkroniseringspunkter ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"synkroniserer på punkter"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Syntakspunkter ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: Ingen sådan syntaks-cluster: %s"
+
+msgid "minimal "
+msgstr "minimal "
+
+msgid "maximal "
+msgstr "maksimal "
+
+msgid "; match "
+msgstr "; match "
+
+msgid " line breaks"
+msgstr " linjeombrydninger"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: indeholder argument som ikke accepteres her"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: ugyldig cchar-værdi"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here accepteres ikke her"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Find ikke regionspunkter for %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Filnavn kræves"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: For mange syntaks inkluderinger"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: Manglende ']': %s"
+
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: efterstillede tegn efter ']': %s]%s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: Manglende '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: For mange argumenter: syntaks region %s"
+
+msgid "E848: Too many syntax clusters"
+msgstr "E848: For mange syntaks-clusters"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Ingen cluster angivet"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Mønsterafgrænser ikke fundet: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Affald efter mønster: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr ""
+"E403: syntaks synkronisering: linjefortsættelsesmønster angivet to gange"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Ulovlige argumenter: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: Manglende lighedstegn: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Tomt argument: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s ikke tilladt her"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s skal være først i contains-liste"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Ukendt gruppenavn: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Ugyldig :syntax-underkommando: %s"
+
+msgid ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+msgstr ""
+" SAMLET ANTAL MATCH LANGSOMST GENNEMS. NAVN MØNSTER"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: rekursiv løkke ved indlæsning af syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: fremhævningsgruppe ikke fundet: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Ikke nok argumenter: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: For mange argumenter: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: gruppe har indstillinger, highlight link ignoreret"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: uventet lighedstegn: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: manglende lighedstegn: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: manglende argument: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Ulovlig værdi: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Forgrundsfarve ukendt"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Baggrundsfarve ukendt"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Farvenavn eller -nummer ikke genkendt: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: terminalkode for lang: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Ulovligt argument: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: For mange forskellige fremhævningsattributter i brug"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: Tegn som ikke kan udskrives i gruppenavn"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ugyldige tegn i gruppenavn"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: For mange fremhævnings- og syntaksgrupper"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: nederst i tag-stak"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: øverst i tag-stak"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Kan ikke gå efter første matchende tag"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: tag ikke fundet: %s"
+
+msgid " # pri kind tag"
+msgstr " # pri kind tag"
+
+msgid "file\n"
+msgstr "fil\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: Der er kun ét matchende tag"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Kan ikke gå efter sidste matchende tag"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Filen \"%s\" findes ikke"
+
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "tag %d af %d%s"
+
+msgid " or more"
+msgstr " eller flere"
+
+msgid " Using tag with different case!"
+msgstr " Bruger tag med anden versaltype!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Filen \"%s\" findes ikke"
+
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # TIL tag FRA linje i fil/tekst"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Søger i tags-filen %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Tag-filens sti afkortet for %s\n"
+
+msgid "Ignoring long line in tags file"
+msgstr "Ignorerer lang linje i tags-fil"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Fejl ved format i tags-filen \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Inden byte %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Tags-fil ikke sorteret: %s"
+
+msgid "E433: No tags file"
+msgstr "E433: Ingen tags-fil"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Kan ikke finde tag-mønster"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Kunne ikke finde tag, gætter bare!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Duplikeret feltnavn: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' ikke kendt. Tilgængelige indbyggede terminaler:"
+
+msgid "defaulting to '"
+msgstr "bruger standarden '"
+
+msgid "E557: Cannot open termcap file"
+msgstr "E557: Kan ikke åbne termcap-fil"
+
+msgid "E558: Terminal entry not found in terminfo"
+msgstr "E558: Terminal-post ikke fundet i terminfo"
+
+msgid "E559: Terminal entry not found in termcap"
+msgstr "E559: Terminal-post ikke fundet i termcap"
+
+#, c-format
+msgid "E436: No \"%s\" entry in termcap"
+msgstr "E436: Ingen \"%s\"-post i termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: terminal-formåenheden \"cm\" kræves"
+
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- Terminal-taster ---"
+
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "Kan ikke åbne $VIMRUNTIME/rgb.txt"
+
+#, c-format
+msgid "Kill job in \"%s\"?"
+msgstr "Dræb job i \"%s\"?"
+
+msgid "Terminal"
+msgstr "Terminal"
+
+msgid "Terminal-finished"
+msgstr "Terminal-færdig"
+
+msgid "active"
+msgstr "aktiv"
+
+msgid "running"
+msgstr "køre"
+
+msgid "finished"
+msgstr "færdig"
+
+#, c-format
+msgid "E953: File exists: %s"
+msgstr "E953: Filen findes: %s"
+
+msgid "E955: Not a terminal buffer"
+msgstr "E955: Ikke en terminal-buffer"
+
+msgid "new shell started\n"
+msgstr "ny skal startet\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Fejl ved læsning af input, afslutter...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Brugte CUT_BUFFER0 i stedet for tom markering"
+
+msgid "E881: Line count changed unexpectedly"
+msgstr "E881: Linjeantal ændret uventet"
+
+msgid "No undo possible; continue anyway"
+msgstr "Ingen fortryd mulig; fortsætter alligevel"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Kan ikke åbne fortrydelsesfil til skrivning: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: Korrupt fortrydelsesfil (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr "Kan ikke skrive fortrydelsesfil i nogen mappe i 'undodir'"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr "Overskriver ikke med fortrydelsesfil, kan ikke læse: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "Overskriver ikke, det er ikke en fortrydelsesfil: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "Springer skrivning af fortrydelsesfil over, intet at fortryde"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "Skriver fortrydelsesfil: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: fejl ved skrivning i fortrydelsesfil: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Læser ikke fortrydelsesfil, ejer er ikke den samme: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "Læser fortrydelsesfil: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Kan ikke åbne fortrydelsesfil til læsning: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: Ikke en fortrydelsesfil: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Ikke-krypteret fil har krypteret fortrydelsesfil: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Dekryptering af fortrydelsesfil mislykkedes: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Fortrydelsesfilen er krypteret: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: Inkompatibel fortrydelsesfil: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr "Filindholdet ændret, kan ikke bruge fortrydelsesinfo"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Færdig med at læse fortrydelsesfilen %s"
+
+msgid "Already at oldest change"
+msgstr "Allerede ved ældste ændring"
+
+msgid "Already at newest change"
+msgstr "Allerede ved nyeste ændring"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Fortrydelsesnummer %ld ikke fundet"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: linjenumre forkerte"
+
+msgid "more line"
+msgstr "linje mere"
+
+msgid "more lines"
+msgstr "linjer mere"
+
+msgid "line less"
+msgstr "linje mindre"
+
+msgid "fewer lines"
+msgstr "linjere mindre"
+
+msgid "change"
+msgstr "ændring"
+
+msgid "changes"
+msgstr "ændringer"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "inden"
+
+msgid "after"
+msgstr "efter"
+
+msgid "Nothing to undo"
+msgstr "Intet at fortryde"
+
+msgid "number changes when saved"
+msgstr "nummer ændrin. hvornår gemt"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "%ld sekunder siden"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin ikke tilladt efter undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: fortrydelsesliste korrupt"
+
+msgid "E440: undo line missing"
+msgstr "E440: fortrydelseslinje mangler"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Funktionen %s findes allerede, tilføj ! for at erstatte den"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Ordbog-post findes allerede"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref kræves"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Ukendt funktion: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Ulovligt argument: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Duplikeret argumentnavn: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: For mange argumenter til funktionen %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Ugyldige argumenter til funktionen %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Dybden af funktionskald er større end 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "kalder %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s afbrudt"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s returnerer #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s returnerer %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: For mange argumenter"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Ukendt funktion: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: Funktion blev slettet: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Ikke nok argumenter til funktionen: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Bruger <SID> ikke i et script kontekst: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Kalder dict-funktion uden ordbog: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Funktionsnavn kræves"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: Funktionsnavnet skal begynde med et stort bogstav eller \"s:\": %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: Funktionsnavnet må ikke indeholdet et kolon: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Udefineret funktion: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Manglende '(': %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Kan ikke bruge g: her"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: Closure-funktion skal ikke være på topniveau: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Manglende :endfunction"
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: Tekst fundet efter :endfunction: %s"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Funktionsnavnet er i konflikt med variablen: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Kan ikke redefinere funktionen %s: Den er i brug"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Funktionsnavn matcher ikke scriptfilnavn: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Kan ikke slette funktionen %s: Den er i brug"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return ikke i en funktion"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Manglende parenteser: %s"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 64-bit GUI-version"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32-bit GUI-version"
+
+msgid " with OLE support"
+msgstr " med understøttelse af OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 64-bit konsol-version"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-bit konsol-version"
+
+msgid ""
+"\n"
+"macOS version"
+msgstr ""
+"\n"
+"macOS-version"
+
+msgid ""
+"\n"
+"macOS version w/o darwin feat."
+msgstr ""
+"\n"
+"macOS-version med/uden darwin-funktionalitet."
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"OpenVMS-version"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Rettelser som er med: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"Ekstra rettelser: "
+
+msgid "Modified by "
+msgstr "Ændret af "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Kompileret "
+
+msgid "by "
+msgstr "af "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Huge-version "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Big-version "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normal-version "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Small-version "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Tiny-version "
+
+msgid "without GUI."
+msgstr "uden GUI."
+
+msgid "with GTK3 GUI."
+msgstr "med GTK3-GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "med GTK2-GNOME-GUI."
+
+msgid "with GTK2 GUI."
+msgstr "med GTK2-GUI."
+
+msgid "with X11-Motif GUI."
+msgstr "med X11-Motif-GUI."
+
+msgid "with X11-neXtaw GUI."
+msgstr "med X11-neXtaw-GUI."
+
+msgid "with X11-Athena GUI."
+msgstr "med X11-Athena-GUI."
+
+msgid "with Photon GUI."
+msgstr "med Photon-GUI."
+
+msgid "with GUI."
+msgstr "med GUI."
+
+msgid "with Carbon GUI."
+msgstr "med Carbon-GUI."
+
+msgid "with Cocoa GUI."
+msgstr "med Cocoa-GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " Funktionaliteter som er med (+) eller ikke (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " system vimrc-fil: \""
+
+msgid " user vimrc file: \""
+msgstr " bruger vimrc-fil: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2. bruger vimrc-fil: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3. bruger vimrc-fil: \""
+
+msgid " user exrc file: \""
+msgstr " bruger exrc-fil: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2. bruger exrc-fil: \""
+
+msgid " system gvimrc file: \""
+msgstr " system gvimrc-fil: \""
+
+msgid " user gvimrc file: \""
+msgstr " bruger gvimrc-fil: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "2. bruger gvimrc-fil: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "3. bruger gvimrc-fil: \""
+
+msgid " defaults file: \""
+msgstr " defaults-fil: \""
+
+msgid " system menu file: \""
+msgstr " system menu-fil: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " fall-back for $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr " f-b for $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Kompilering: "
+
+msgid "Compiler: "
+msgstr "Kompiler: "
+
+msgid "Linking: "
+msgstr "Linking: "
+
+msgid " DEBUG BUILD"
+msgstr " FEJLRETNINGSBYG"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "version "
+
+msgid "by Bram Moolenaar et al."
+msgstr "af Bram Moolenaar og andre"
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim er open source og kan frit distribueres"
+
+msgid "Help poor children in Uganda!"
+msgstr "Hjælp fattige børn i Uganda!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "skriv :help iccf<Enter> for information "
+
+msgid "type :q<Enter> to exit "
+msgstr "skriv :q<Enter> for at afslutte "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "skriv :help<Enter> eller <F1> for onlinehjælp "
+
+msgid "type :help version8<Enter> for version info"
+msgstr "skriv :help version8<Enter> for versionsinfo"
+
+msgid "Running in Vi compatible mode"
+msgstr "Kører i Vi-kompatibel-tilstand"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "skriv :set nocp<Enter> for Vim-standarder"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "skriv :help cp-default<Enter> for info om det "
+
+msgid "menu Help->Orphans for information "
+msgstr "menu Hjælp->Forældreløse børnfor information "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Kører tilstandsløs, skrevet tekst indsættes"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menu Rediger->Globale indstillinger->Indsæt-tilstand til/fra "
+
+msgid " for two modes "
+msgstr " for to-tilstande "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "menu Rediger->Globale indstillinger->Vi-kompatibel til/fra"
+
+msgid " for Vim defaults "
+msgstr " for Vim-standarder "
+
+msgid "Sponsor Vim development!"
+msgstr "Sponsorer udviklingen af Vim!"
+
+msgid "Become a registered Vim user!"
+msgstr "Bliv en registreret Vim-bruger!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "skriv :help sponsor<Enter> for information "
+
+msgid "type :help register<Enter> for information "
+msgstr "skriv :help register<Enter> for information "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "menu Hjælp->Sponsorer/registrer for information "
+
+msgid "Already only one window"
+msgstr "Allerede kun ét vindue"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Der er ikke noget forhåndsvisningsvindue"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Kan ikke opdele øverste venstre og nederste højre på samme tid"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Kan ikke rotere når et andet vindue er opdelt"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: Kan ikke lukke sidste vindue"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Kan ikke lukke autocmd-vindue"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Kan ikke lukke vindue, kun autocmd-vindue ville være tilbage"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Et andet vindue indeholder ændringer"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Intet filnavn under markør"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Kan ikke finde filen \"%s\" i sti"
+
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: Ugyldigt ID: %ld (skal være større end eller lig med 1)"
+
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID allerede taget: %ld"
+
+msgid "List or number required"
+msgstr "Liste eller nummer kræves"
+
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: Ugyldigt ID: %ld (skal være større end eller lig med 1)"
+
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID ikke fundet: %ld"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Kunne ikke indlæse biblioteket %s"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"Beklager, kommandoen er deaktiveret: Perl-biblioteket kunne ikke indlæses."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Perl-evaluering forbudt i sandbox uden Safe-modulet"
+
+msgid "Edit with &multiple Vims"
+msgstr "Rediger med &flere Vim'er"
+
+msgid "Edit with single &Vim"
+msgstr "Rediger med én &Vim"
+
+msgid "Diff with Vim"
+msgstr "Diff med Vim"
+
+msgid "Edit with &Vim"
+msgstr "Rediger med &Vim"
+
+msgid "Edit with existing Vim - "
+msgstr "Rediger med eksisterende Vim - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Redigerer den valgt fil(er) med Vim"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Fejl ved oprettelse af proces: Tjek om gvim er i din sti!"
+
+msgid "gvimext.dll error"
+msgstr "fejl ved gvimext.dll"
+
+msgid "Path length too long!"
+msgstr "Stiens længde er for lang!"
+
+msgid "--No lines in buffer--"
+msgstr "--Ingen linjer i buffer--"
+
+msgid "E470: Command aborted"
+msgstr "E470: Kommando afbrudt"
+
+msgid "E471: Argument required"
+msgstr "E471: Argument kræves"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ skal efterføles af /, ? eller &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: Ugyldig i kommandolinjevindue; <CR> udfører, CTRL-C afslutter"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Kommando ikke tilladt fra exrc/vimrc i nuværende mappe- eller "
+"tagsøgning"
+
+msgid "E171: Missing :endif"
+msgstr "E171: Manglende :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: Manglende :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: Manglende :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: Manglende :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile uden :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor uden :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Filen findes (tilføj ! for at tilsidesætte)"
+
+msgid "E472: Command failed"
+msgstr "E472: Kommando mislykkede"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Ukendt skrifttypesæt: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Ukendt skrifttype: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Skrifttypen \"%s\" er ikke med fast bredde"
+
+msgid "E473: Internal error"
+msgstr "E473: Intern fejl"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Intern fejl: %s"
+
+msgid "Interrupted"
+msgstr "Afbrudt"
+
+msgid "E14: Invalid address"
+msgstr "E14: Ugyldig adresse"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Ugyldigt argument"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Ugyldigt argument: %s"
+
+#, c-format
+msgid "E475: Invalid value for argument %s"
+msgstr "E475: Ugyldig værdi for argumentet %s"
+
+#, c-format
+msgid "E475: Invalid value for argument %s: %s"
+msgstr "E475: Ugyldig værdi for argumentet %s: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Ugyldigt udtryk: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Ugyldigt område"
+
+msgid "E476: Invalid command"
+msgstr "E476: Ugyldig kommando"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" er en mappe"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Kald af bibliotek mislykkedes for \"%s()\""
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync mislykkedes"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Kunne ikke indlæse biblioteksfunktionen %s"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Mærke har ugyldigt linjenummer"
+
+msgid "E20: Mark not set"
+msgstr "E20: Mærke ikke sat"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Kan ikke foretage ændringer, 'modifiable' er slået fra"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Scripts indlejret for dybt"
+
+msgid "E23: No alternate file"
+msgstr "E23: Ingen alternate-fil"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Ingen sådan forkortelse"
+
+msgid "E477: No ! allowed"
+msgstr "E477: Ingen ! tilladt"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI kan ikke bruges: Ikke aktiveret ved kompileringstid"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Hebraisk kan ikke bruges: Ikke aktiveret ved kompileringstid\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E27: Persisk kan ikke bruges: Ikke aktiveret ved kompileringstid\n"
+"\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Arabisk kan ikke bruges: Ikke aktiveret ved kompileringstid\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Intet sådan fremhævningsgruppenavn: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: Endnu ingen indsat tekst"
+
+msgid "E30: No previous command line"
+msgstr "E30: Ingen tidligere kommandolinje"
+
+msgid "E31: No such mapping"
+msgstr "E31: Ingen sådan mapping"
+
+msgid "E479: No match"
+msgstr "E479: Intet match"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Intet match: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Intet filnavn"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Ingen tidligere erstatnings regulært udtryk"
+
+msgid "E34: No previous command"
+msgstr "E34: Ingen tidligere kommando"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Ingen tidligere regulære udtryk"
+
+msgid "E481: No range allowed"
+msgstr "E481: Intet område tilladt"
+
+msgid "E36: Not enough room"
+msgstr "E36: Ikke plads nok"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: ingen registreret server ved navn \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Kan ikke oprette filen %s"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Kan ikke hente midlertidigt filnavn"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Kan ikke åbne filen %s"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Kan ikke læse filen %s"
+
+msgid "E38: Null argument"
+msgstr "E38: Null-argument"
+
+msgid "E39: Number expected"
+msgstr "E39: Nummer ventet"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Kan ikke åbne fejlfilen %s"
+
+msgid "E233: cannot open display"
+msgstr "E233: kan ikke åbne display"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Ikke mere ledig hukommelse!"
+
+msgid "Pattern not found"
+msgstr "Mønster ikke fundet"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Mønster ikke fundet: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Argument skal være positivt"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Kan ikke gå tilbage til tidligere mappe"
+
+msgid "E42: No Errors"
+msgstr "E42: Ingen fejl"
+
+msgid "E776: No location list"
+msgstr "E776: Ingen placeringsliste"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Beskadiget matchstreng"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Korrupt regexp-program"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly'-tilvalget er sat (tilføj ! for at tilsidesætte)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Kan ikke ændre skrivebeskyttet variabel \"%s\""
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Kan ikke sætte variabel i sandboksen: \"%s\""
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Kan ikke bruge tom nøgle til ordbog"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Ordbog kræves"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: listeindeks udenfor område: %ld"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: For mange argumenter til funktion: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Nøgle findes ikke i ordbog: %s"
+
+msgid "E714: List required"
+msgstr "E714: Liste kræves"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argument af %s skal være en liste eller ordbog"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Fejl ved læsning af fejlfil"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ikke tilladt i sandboks"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Ikke tilladt her"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Skærmtilstand-indstilling understøttes ikke"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Ugyldig rullestørrelse"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell'-tilvalget er tomt"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Kunne ikke læse i sign-data!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Fejl ved lukning af swap-fil"
+
+msgid "E73: tag stack empty"
+msgstr "E73: tag-stak tom"
+
+msgid "E74: Command too complex"
+msgstr "E74: Kommando for kompleks"
+
+msgid "E75: Name too long"
+msgstr "E75: Navn for langt"
+
+msgid "E76: Too many ["
+msgstr "E76: For mange ["
+
+msgid "E77: Too many file names"
+msgstr "E77: For mange filnavne"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Efterstillede tegn"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Ukendt mærke"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Kan ikke udvide jokertegn"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' må ikke være mindre end 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' må ikke være mindre end 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Fejl ved skrivning"
+
+msgid "E939: Positive count required"
+msgstr "E939: Positiv tælling kræves"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Bruger <SID> ikke i et script kontekst"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Ugyldigt udtryk modtaget"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Regionen er beskyttet, kan ikke ændre"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans tillader ikke ændringer i skrivebeskyttede filer"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: mønster bruger mere hukommelse end 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: tom buffer"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Bufferen %ld findes ikke"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Ugyldigt søgemønster eller -afgrænser"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Filen er indlæst i en anden buffer"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Tilvalget '%s' er ikke sat"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Ugyldigt registernavn"
+
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Mappe ikke fundet i '%s': \"%s\""
+
+msgid "E952: Autocommand caused recursive behavior"
+msgstr "E952: Autokommando forårsagede rekursiv opførsel"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "søgning ramte ØVERST, fortsætter ved NEDERST"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "søgning ramte NEDERST, fortsætter ved ØVERST"
+
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Behøver krypteringsnøgle til \"%s\""
+
+msgid "empty keys are not allowed"
+msgstr "tomme nøgler er ikke tilladt"
+
+msgid "dictionary is locked"
+msgstr "ordbog er låst"
+
+msgid "list is locked"
+msgstr "liste er låst"
+
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "kunne ikke tilføje nøglen '%s' til ordbog"
+
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "indeks skal være heltal eller slice, ikke %s"
+
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "ventede str()- eller unicode()-instans, men fik %s"
+
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "ventede bytes()- eller str()-instans, min fik %s"
+
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr ""
+"ventede int(), long() eller noget som understøtter coercing til long(), min "
+"fik %s"
+
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr ""
+"ventede int() eller noget som understøtter coercing til int(), min fik %s"
+
+msgid "value is too large to fit into C int type"
+msgstr "værdi er for stor til at passe i C-heltalstype"
+
+msgid "value is too small to fit into C int type"
+msgstr "værdi er for lille til at passe i C-heltalstype"
+
+msgid "number must be greater than zero"
+msgstr "nummer skal være større end nul"
+
+msgid "number must be greater or equal to zero"
+msgstr "nummer skal være større end eller lig med nul"
+
+msgid "can't delete OutputObject attributes"
+msgstr "kan ikke slette OutputObject-attributter"
+
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "ugyldig attribut: %s"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Fejl ved initialisering af I/O-objekter"
+
+msgid "failed to change directory"
+msgstr "kunne ikke skifte mappe"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "ventede 3-tuple som imp.find_module() resultat, men fik %s"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr ""
+"ventede 3-tuple som imp.find_module() resultat, men fik tuple af størrelse %"
+"d"
+
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "intern fejl: imp.find_module returnerede tuple med NULL"
+
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "kan ikke slette vim.Dictionary-attributter"
+
+msgid "cannot modify fixed dictionary"
+msgstr "kan ikke ændre fast ordbog"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "kan ikke sætte attributten %s"
+
+msgid "hashtab changed during iteration"
+msgstr "hashtab ændret under gennemløb"
+
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "ventede sekvenselement af størrelse 2, men fik sekvens af størrelse %d"
+
+msgid "list constructor does not accept keyword arguments"
+msgstr "liste-constructor accepterer ikke nøgleord-argumenter"
+
+msgid "list index out of range"
+msgstr "listeindeks udenfor område"
+
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "intern fejl: kunne ikke hente vim-listepunkt %d"
+
+msgid "slice step cannot be zero"
+msgstr "slice-trin må ikke være nul"
+
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "forsøg på at tildele sekvens som er større end %d til udvidet slice"
+
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "intern fejl: intet vim-listepunkt %d"
+
+msgid "internal error: not enough list items"
+msgstr "intern fejl: ikke nok listepunkter"
+
+msgid "internal error: failed to add item to list"
+msgstr "intern fejl: kunne ikke tilføje punkt til liste"
+
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr ""
+"forsøg på at tildele sekvens af størrelsen %d til udvidet slice af "
+"størrelsen %d"
+
+msgid "failed to add item to list"
+msgstr "kunne ikke tilføje punkt til liste"
+
+msgid "cannot delete vim.List attributes"
+msgstr "kan ikke slette vim.List-attributter"
+
+msgid "cannot modify fixed list"
+msgstr "kan ikke ændre fast liste"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "unavngivet funktion %s findes ikke"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "funktionen %s findes ikke"
+
+#, c-format
+msgid "failed to run function %s"
+msgstr "kunne ikke køre funktionen %s"
+
+msgid "unable to get option value"
+msgstr "kan ikke hente tilvalgsværdi"
+
+msgid "internal error: unknown option type"
+msgstr "intern fejl: ukendt tilvalgstype"
+
+msgid "problem while switching windows"
+msgstr "problem ved skift af vinduer"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "kan ikke fjerne det globale tilvalg %s"
+
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "kan ikke fjerne tilvalget %s som ikke har global værdi"
+
+msgid "attempt to refer to deleted tab page"
+msgstr "forsøg på at referere til slettet fanebladsside"
+
+msgid "no such tab page"
+msgstr "ingen sådan fanebladsside"
+
+msgid "attempt to refer to deleted window"
+msgstr "forsøg på at referere til slettet vindue"
+
+msgid "readonly attribute: buffer"
+msgstr "skrivebeskyttet attribut: buffer"
+
+msgid "cursor position outside buffer"
+msgstr "markørposition udenfor buffer"
+
+msgid "no such window"
+msgstr "intet sådan vindue"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "forsøg på at referere til slettet buffer"
+
+msgid "failed to rename buffer"
+msgstr "kunne ikke omdøbe bufferen"
+
+msgid "mark name must be a single character"
+msgstr "mærkenavn skal være ét tegn"
+
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "ventede vim.Buffer-objekt, men fik %s"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "kunne ikke skifte til bufferen %d"
+
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "ventede vim.Window-objekt, men fik %s"
+
+msgid "failed to find window in the current tab page"
+msgstr "kunne ikke finde vindue i den nuværende fanebladsside"
+
+msgid "did not switch to the specified window"
+msgstr "skiftede ikke til det angivne vindue"
+
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "ventede vim.TabPage-objekt, men fik %s"
+
+msgid "did not switch to the specified tab page"
+msgstr "skiftede ikke til den angivne fanebladsside"
+
+msgid "failed to run the code"
+msgstr "kunne ikke køre koden"
+
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval returnerede ikke et gyldigt python-objekt"
+
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Kunne ikke konvertere returnerede python-objekt til vim-værdi"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "kan ikke konvertere %s til vim-ordbog"
+
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "kan ikke konvertere %s til vim-liste"
+
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "kan ikke konvertere %s til vim-struktur"
+
+msgid "internal error: NULL reference passed"
+msgstr "intern fejl: NULL-reference givet"
+
+msgid "internal error: invalid value type"
+msgstr "intern fejl: ugyldig værditype"
+
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"Kunne ikke sætte sti-hook: sys.path_hooks er ikke en liste\n"
+"Du bør nu gøre følgende:\n"
+"- tilføj vim.path_hook til slutningen af sys.path_hooks\n"
+"- tilføj vim.VIM_SPECIAL_PATH til slutningen af sys.path\n"
+
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"Kunne ikke sætte sti: sys.path er ikke en liste\n"
+"Du bør nu tilføje vim.VIM_SPECIAL_PATH til slutningen af sys.path"
+
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*.*)\t*.*\n"
+msgstr ""
+"Vim-makrofiler (*.vim)\t*.vim\n"
+"Alle filer (*.*)\t*.*\n"
+
+msgid "All Files (*.*)\t*.*\n"
+msgstr "Alle filer (*.*)\t*.*\n"
+
+msgid ""
+"All Files (*.*)\t*.*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VB code (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"Alle filer (*.*)\t*.*\n"
+"C-kildekode (*.c, *.h)\t*.c;*.h\n"
+"C++-kildekode (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VB-kode (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vim-filer (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*)\t*\n"
+msgstr ""
+"Vim-makrofiler (*.vim)\t*.vim\n"
+"Alle filer (*)\t*\n"
+
+msgid "All Files (*)\t*\n"
+msgstr "Alle filer (*)\t*\n"
+
+msgid ""
+"All Files (*)\t*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"Alle filer (*)\t*\n"
+"C-kildekode (*.c, *.h)\t*.c;*.h\n"
+"C++-kildekode (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vim-filer (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
diff --git a/src/nvim/po/de.po b/src/nvim/po/de.po
index 4950533a21..a6ba8476d8 100644
--- a/src/nvim/po/de.po
+++ b/src/nvim/po/de.po
@@ -12,7 +12,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-06-26 15:13+0200\n"
"PO-Revision-Date: 2008-05-24 17:26+0200\n"
-"Last-Translator: Georg Dahn <georg.dahn@gmail.com>\n"
+"Last-Translator: was: Georg Dahn\n"
"Language-Team: German <de@li.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
@@ -377,7 +377,7 @@ msgstr " Definitions-Ergänzung (^D^N^P)"
#: ../edit.c:92
msgid " Dictionary completion (^K^N^P)"
-msgstr " Wörterbuch-Ergänzung (^K^N^P) "
+msgstr " Dictionary-Ergänzung (^K^N^P) "
#: ../edit.c:93
msgid " Thesaurus completion (^T^N^P)"
@@ -401,7 +401,7 @@ msgstr " Vorschlag der Rechtschreibprüfung (s^N^P)"
#: ../edit.c:98
msgid " Keyword Local completion (^N^P)"
-msgstr " Lokale Schlüsselwort-Ergänzung(^N^P)"
+msgstr " Lokale Stichwort-Ergänzung(^N^P)"
#: ../edit.c:101
msgid "Hit end of paragraph"
@@ -443,7 +443,7 @@ msgstr "Durchsuche: %s"
#: ../edit.c:3513
msgid "Scanning tags."
-msgstr "Durchsuchen von Tags."
+msgstr "Durchsuche Tags"
#: ../edit.c:4418
msgid " Adding"
@@ -633,6 +633,9 @@ msgstr ""
#: ../ex_cmds.c:2433
#, c-format
+msgid "Pattern not found: %s"
+msgstr "Muster nicht gefunden: %s"
+
msgid ""
"File permissions of \"%s\" are read-only.\n"
"It may still be possible to write it.\n"
@@ -713,11 +716,6 @@ msgstr "E148: Regulärer Ausdruck fehlt in global"
msgid "Pattern found in every line: %s"
msgstr "Muster in jeder Zeile gefunden: %s"
-#: ../ex_cmds.c:4504
-#, c-format
-msgid "Pattern not found: %s"
-msgstr "Muster nicht gefunden: %s"
-
#: ../ex_cmds.c:4581
msgid ""
"\n"
@@ -1920,7 +1918,7 @@ msgstr "E216: Keine solche Gruppe oder Ereignis: %s"
#: ../fileio.c:5993
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Autokommandos ---"
@@ -1944,7 +1942,7 @@ msgstr "E218: Autokommandos zu tief verschachtelt"
#: ../fileio.c:7042
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Autokommandos für \"%s\""
#: ../fileio.c:7048
@@ -1996,7 +1994,7 @@ msgstr "E223: rekursive Zuordnung"
#: ../getchar.c:2835
#, c-format
msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: Globale Abkürzung für %s existiert bereits"
+msgstr "E224: Globale Kurzform für %s existiert bereits"
#: ../getchar.c:2838
#, c-format
@@ -2137,11 +2135,6 @@ msgstr "E900: Ungültige Job-ID"
msgid "E901: Job table is full"
msgstr "E901: Job-Tabelle ist voll"
-#: ../globals.h:1021
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr "E902: \"%s\" ist nicht ausführbar"
-
#: ../globals.h:1023
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -2169,7 +2162,7 @@ msgstr "E23: Keine alternative Datei"
#: ../globals.h:1031
msgid "E24: No such abbreviation"
-msgstr "E24: Keine Abkürzung gefunden"
+msgstr "E24: Diese Kurzform nicht gefunden"
#: ../globals.h:1032
msgid "E477: No ! allowed"
@@ -2842,7 +2835,7 @@ msgstr "-q [Fehler-Datei] öffne Datei mit erstem Fehler"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4778,8 +4771,8 @@ msgstr "Achtung: Region %s nicht unterstützt"
#: ../spell.c:4364
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Lese Affix-Datei %s ..."
+msgid "Reading affix file %s..."
+msgstr "Lese Affix-Datei %s..."
#: ../spell.c:4403 ../spell.c:5449 ../spell.c:5954
#, c-format
@@ -4945,8 +4938,8 @@ msgstr ""
#: ../spell.c:5416
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Lese Wörterbuch-Datei %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Lese Wörterbuch-Datei %s..."
#: ../spell.c:5425
#, c-format
@@ -4980,8 +4973,8 @@ msgstr "%d Wort(e) mit Nicht-ASCII-Zeichen ignoriert in %s"
#: ../spell.c:5929
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Lese Wort-Datei %s ..."
+msgid "Reading word file %s..."
+msgstr "Lese Wort-Datei %s..."
#: ../spell.c:5969
#, c-format
@@ -5050,8 +5043,8 @@ msgstr "Gesamte Anzahl von Wörtern: %d"
#: ../spell.c:7468
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Schreibe Datei %s für Vorschläge ..."
+msgid "Writing suggestion file %s..."
+msgstr "Schreibe Datei %s für Vorschläge..."
#: ../spell.c:7520 ../spell.c:7740
#, c-format
@@ -5077,8 +5070,8 @@ msgstr "Achtung: Sowohl zusammengesetzte Wörter als auch NOBREAK angegeben"
#: ../spell.c:7733
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Schreibe Rechtschreibwörterbuch %s ..."
+msgid "Writing spell file %s..."
+msgstr "Schreibe Rechtschreibwörterbuch %s..."
#: ../spell.c:7738
msgid "Done!"
@@ -6493,7 +6486,7 @@ msgid ""
"\tLast set from "
msgstr ""
"\n"
-"\tZuletzt gesetzt von "
+"\tZuletzt gesetzt in "
#: ../eval.c:18682
msgid "No old files"
diff --git a/src/nvim/po/en_GB.po b/src/nvim/po/en_GB.po
index b4b38e11e3..00a05195b4 100644
--- a/src/nvim/po/en_GB.po
+++ b/src/nvim/po/en_GB.po
@@ -2623,11 +2623,6 @@ msgstr ""
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -4128,10 +4123,6 @@ msgstr ""
msgid "E354: Invalid register name: '%s'"
msgstr ""
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Messages maintainer: Mike Williams <mrw@eandem.co.uk>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr ""
diff --git a/src/nvim/po/eo.po b/src/nvim/po/eo.po
index 6bc76506ae..d1ce47d97c 100644
--- a/src/nvim/po/eo.po
+++ b/src/nvim/po/eo.po
@@ -5,7 +5,7 @@
#
# UNUA TRADUKISTO Dominique PELLE <dominique.pelle ĉe gmail.com>
# PROVLEGANTO(J) Felipe CASTRO <fefcas ĉe gmail.com>
-# Antono MECHELYNCK <antoine.mechelynck ĉe skynet.be>
+# Antono MECHELYNCK <antoine.mechelynck ĉe gmail.com>
# Yves NEVELSTEEN
#
# Uzitaj vortaroj kaj fakvortaroj:
@@ -13,18 +13,12 @@
# Komputeko: http://komputeko.net/index_eo.php
# Komputada leksikono: http://bertilow.com/div/komputada_leksikono/
#
-# Lasta versio:
-# http://dominique.pelle.free.fr/vim-eo.php
-#
-# Ĉiu komento estas bonvenata...
-# Every remark is welcome...
-#
msgid ""
msgstr ""
"Project-Id-Version: Vim(Esperanto)\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-02-13 23:42+0100\n"
-"PO-Revision-Date: 2016-02-13 23:45+0100\n"
+"POT-Creation-Date: 2017-10-02 22:42+0200\n"
+"PO-Revision-Date: 2017-10-02 22:57+0200\n"
"Last-Translator: Dominique PELLÉ <dominique.pelle@gmail.com>\n"
"Language-Team: \n"
"Language: eo\n"
@@ -32,203 +26,174 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "fiaskis akiri valoron de opcio"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() alvokita kun malplena pasvorto"
-#: ../api/private/helpers.c:204
-#, fuzzy
-msgid "internal error: unknown option type"
-msgstr "interna eraro: neniu vim-a listero"
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Misuzo de pezkomenca/pezfina en blowfish"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: Testo de sha256 malsukcesis"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Testo de blowfish malsukcesis"
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[Listo de lokoj]"
# DP: Ĉu vere indas traduki Quickfix?
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Listo de rapidriparoj]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: AÅ­tokomandoj haltigis komandon"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: Ne eblas disponigi iun ajn bufron, nun eliras..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: Ne eblas disponigi bufron, nun uzas alian..."
-#: ../buffer.c:763
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: Bufro ne povas esti registrita"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Provo de forviÅo de bufro, kiu estas en uzo"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Neniu bufro estis malÅargita"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Neniu bufro estis forviÅita"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Neniu bufro estis detruita"
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "1 bufro malÅargita"
-
-#: ../buffer.c:774
#, c-format
-msgid "%d buffers unloaded"
-msgstr "%d bufroj malÅargitaj"
+msgid "%d buffer unloaded"
+msgid_plural "%d buffers unloaded"
+msgstr[0] "%d bufro malÅargita"
+msgstr[1] "%d bufroj malÅargitaj"
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "1 bufro forviÅita"
-
-#: ../buffer.c:779
#, c-format
-msgid "%d buffers deleted"
-msgstr "%d bufroj forviÅitaj"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "1 bufro detruita"
+msgid "%d buffer deleted"
+msgid_plural "%d buffers deleted"
+msgstr[0] "%d bufro forviÅita"
+msgstr[1] "%d bufroj forviÅitaj"
-#: ../buffer.c:784
#, c-format
-msgid "%d buffers wiped out"
-msgstr "%d bufroj detruitaj"
+msgid "%d buffer wiped out"
+msgid_plural "%d buffers wiped out"
+msgstr[0] "%d bufro detruita"
+msgstr[1] "%d bufroj detruitaj"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: Ne eblas malÅargi la lastan bufron"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Neniu modifita bufro trovita"
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Estas neniu listigita bufro"
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: Ne eblas iri preter la lastan bufron"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: Ne eblas iri antaÅ­ la unuan bufron"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
msgstr ""
-"E89: Neniu skribo de post la lasta ÅanÄo de la bufro %<PRId64> (aldonu ! por "
+"E89: Neniu skribo de post la lasta ÅanÄo de la bufro %ld (aldonu ! por "
"transpasi)"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
+msgid "E948: Job still running (add ! to end the job)"
+msgstr "E948: Tasko akoraÅ­ aktiva (aldonu ! por fini la taskon)"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Neniu skribo de post lasta ÅanÄo (aldonu ! por transpasi)"
+
+msgid "E948: Job still running"
+msgstr "E948: Tasko ankoraÅ­ aktiva"
+
+msgid "E37: No write since last change"
+msgstr "E37: Neniu skribo de post lasta ÅanÄo"
+
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Averto: Listo de dosiernomoj troas"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Bufro %<PRId64> ne trovita"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Bufro %ld ne trovita"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: Pli ol unu kongruo kun %s"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: Neniu bufro kongruas kun %s"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "linio %<PRId64>"
+msgid "line %ld"
+msgstr "linio %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Bufro kun tiu nomo jam ekzistas"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr "[Modifita]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Ne redaktita]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Nova dosiero]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[Eraroj de legado]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[Nurlegebla]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[nurlegebla]"
-#: ../buffer.c:2524
-#, c-format
-msgid "1 line --%d%%--"
-msgstr "1 linio --%d%%--"
-
-#: ../buffer.c:2526
#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> linioj --%d%%--"
+msgid "%ld line --%d%%--"
+msgid_plural "%ld lines --%d%%--"
+msgstr[0] "%ld linio --%d%%--"
+msgstr[1] "%ld linioj --%d%%--"
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "linio %<PRId64> de %<PRId64> --%d%%-- kol "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "linio %ld de %ld --%d%%-- kol "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[Neniu nomo]"
-#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "helpo"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Helpo]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[AntaÅ­vido]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Ĉio"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Subo"
-#: ../buffer.c:3531
msgid "Top"
msgstr "Supro"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -236,12 +201,16 @@ msgstr ""
"\n"
"# Listo de bufroj:\n"
-#: ../buffer.c:4289
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Ne eblas skribi, opcio 'buftype' estas Åaltita"
+
+msgid "[Prompt]"
+msgstr "[Invito]"
+
msgid "[Scratch]"
msgstr "[Malneto]"
# DP: Vidu ":help sign-support" por klarigo pri "Sign"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -249,630 +218,396 @@ msgstr ""
"\n"
"--- Emfazaj simbolaĵoj ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Emfazaj simbolaĵoj de %s:"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " linio=%<PRId64> id=%d nomo=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " linio=%ld id=%d nomo=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: Mankas dupunkto"
+msgid "E902: Cannot connect to port"
+msgstr "E902: Ne eblas konekti al pordo"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: ReÄimo nepermesata"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() en channel_open()"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: cifero atendata"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: gethostbyname() en channel_open()"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Nevalida procento"
+msgid "E903: received command with non-string argument"
+msgstr "E903: ricevis komandon kun argumento, kiu ne estas ĉeno"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: lasta argumento de \"expr/call\" devas esti nombro"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: tria argumento de \"call\" devas esti listo"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Ne eblas dosierdiferenci pli ol %<PRId64> bufrojn"
+msgid "E905: received unknown command: %s"
+msgstr "E905: nekonata komando ricevita: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): konservo dum nekonektita"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): Konservo malsukcesis"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: Ne eblas uzi reagfunkcion kun %s()"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr "E912: ne eblas uzi ch_evalexpr()/ch_sendexpr() kun kruda aÅ­ nl kanalo"
+
+msgid "E906: not an open channel"
+msgstr "E906: ne estas malfermita kanalo"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: dosiero _io bezonas _name"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: bufro in_io bezonas in_buf aÅ­ in_name"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: bufro devas esti Åargita: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Dosiero estas ĉifrita per nekonata metodo"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "Averto: uzo de malfortika ĉifrada metodo; vidu :help 'cm'"
+
+msgid "Enter encryption key: "
+msgstr "Tajpu la Ålosilon de ĉifrado: "
+
+msgid "Enter same key again: "
+msgstr "Tajpu la Ålosilon denove: "
+
+msgid "Keys don't match!"
+msgstr "Åœlosiloj ne kongruas!"
+
+msgid "[crypted]"
+msgstr "[ĉifrita]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Mankas dupunkto en la vortaro: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Ripetita Ålosilo en la vortaro: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Mankas komo en la vortaro: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Mankas fino de vortaro '}': %s"
+
+msgid "extend() argument"
+msgstr "argumento de extend()"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Åœlosilo jam ekzistas: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: Ne eblas dosierdiferenci pli ol %ld bufrojn"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: Ne eblas legi aÅ­ skribi provizorajn dosierojn"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: Ne eblas krei dosierdiferencojn"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "Flika dosiero"
+
msgid "E816: Cannot read patch output"
msgstr "E816: Ne eblas legi eliron de flikilo \"patch\""
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Ne eblas legi eliron de dosierdiferencilo \"diff\""
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: Aktuala bufro ne estas en dosierdiferenca reÄimo"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: Neniu alia bufro en dosierdiferenca reÄimo estas modifebla"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: Neniu alia bufro en dosierdiferenca reÄimo"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr "E101: Pli ol du bufroj en dosierdiferenca reÄimo, ne scias kiun uzi"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: Ne eblas trovi bufron \"%s\""
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Bufro \"%s\" ne estas en dosierdiferenca reÄimo"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Bufro ÅanÄiÄis neatendite"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: Eskapsigno nepermesebla en duliteraĵo"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: Dosiero de klavmapo ne troveblas"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: Uzo de \":loadkeymap\" nur eblas en vim-skripto"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: Malplena rikordo en klavmapo"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " Kompletigo de Ålosilvorto (^N^P)"
-#. 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 " ReÄimo ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " Kompletigo de tuta linio (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " Kompletigo de dosiernomo (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " Kompletigo de etikedo (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " Kompletigo de Åablona dosierindiko (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " Kompletigo de difino (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " Kompletigo de vortaro (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " Kompletigo de tezaÅ­ro (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " Kompletigo de komanda linio (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " Kompletigo difinita de uzanto (^U^N^P)"
# DP: Ĉu eblas trovi pli bonan tradukon?
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " Kompletigo Omni (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Sugesto de literumo (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " Kompletigo loka de Ålosilvorto (^N/^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Atingis finon de alineo"
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: Kompletiga funkcio ÅanÄis la fenestron"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: Kompletiga funkcio forviÅis tekston"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "La opcio 'dictionary' estas malplena"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "La opcio 'thesaurus' estas malplena"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Analizas vortaron: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (enmeto) Rulumo (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (anstataÅ­igo) Rulumo (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "Analizas: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "Analizas etikedojn."
-#: ../edit.c:4519
+msgid "match in file"
+msgstr "kongruo en dosiero"
+
msgid " Adding"
msgstr " Aldonanta"
-#. 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 "-- Serĉanta..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "Reveninta al originalo"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "Vorto el alia linio"
-#: ../edit.c:4624
msgid "The only match"
msgstr "La sola kongruo"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "kongruo %d de %d"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "kongruo %d"
-#: ../eval.c:137
msgid "E18: Unexpected characters in :let"
msgstr "E18: Neatenditaj signoj en \":let\""
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: indekso de listo ekster limoj: %<PRId64>"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: Nedifinita variablo: %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: Mankas ']'"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: Argumento de %s devas esti Listo"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Argumento de %s devas esti Listo aÅ­ Vortaro"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: Listo bezonata"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Vortaro bezonata"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: Tro da argumentoj por funkcio: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Åœlosilo malekzistas en Vortaro: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: La funkcio %s jam ekzistas (aldonu ! por anstataÅ­igi Äin)"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Rikordo de vortaro jam ekzistas"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Funcref bezonata"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: Uzo de [:] ne eblas kun Vortaro"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: Nevalida datumtipo de variablo de %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Nekonata funkcio: %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Nevalida nomo de variablo: %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: uzo de Glitpunktnombro kiel Ĉeno"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: Malpli da celoj ol Listeroj"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: Pli da celoj ol Listeroj"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "Duobla ; en listo de variabloj"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Ne eblas listigi variablojn de %s"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: Nur eblas indeksi Liston aÅ­ Vortaron"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] devas esti laste"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: [:] bezonas listan valoron"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: Lista valoro havas pli da eroj ol la celo"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: Lista valoro ne havas sufiĉe da eroj"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
-msgstr "E690: \"in\" mankas post \":for\""
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Mankas krampoj: %s"
+msgstr "E690: \"in\" mankas malantaÅ­ \":for\""
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Ne estas tia variablo: \"%s\""
-#: ../eval.c:3333
+#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: Ne eblas Ålosi aÅ­ malÅlosi variablon %s"
+
msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: variablo ingita tro profunde por malÅlosi"
+msgstr "E743: variablo ingita tro profunde por (mal)Ålosi"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
-msgstr "E109: Mankas ':' post '?'"
+msgstr "E109: Mankas ':' malantaÅ­ '?'"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: Eblas nur kompari Liston kun Listo"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: Nevalida operacio de Listoj"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: Eblas nur kompari Vortaron kun Vortaro"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: Nevalida operacio de Vortaro"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Eblas nur kompari Funcref kun Funcref"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: Nevalida operacio de Funcref-oj"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: Ne eblas uzi '%' kun Glitpunktnombro"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: Mankas ')'"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: Ne eblas indeksi Funcref"
msgid "E909: Cannot index a special variable"
msgstr "E909: Ne eblas indeksi specialan variablon"
-#: ../eval.c:4839
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Mankas nomo de opcio: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Nekonata opcio: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Mankas citilo: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Mankas citilo: %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Mankas komo en Listo: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: Mankas fino de Listo ']': %s"
-
-#: ../eval.c:5750
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr "Ne sufiĉa memoro por valorigi referencojn, senrubigado ĉesigita!"
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Mankas dupunkto en la vortaro: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Ripetita Ålosilo en la vortaro: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Mankas komo en la vortaro: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Mankas fino de vortaro '}': %s"
-
-#: ../eval.c:6555
msgid "E724: variable nested too deep for displaying"
msgstr "E724: variablo ingita tro profunde por vidigi"
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: Tro da argumentoj por funkcio: %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Nevalidaj argumentoj por funkcio: %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Nekonata funkcio: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Ne sufiĉe da argumentoj por funkcio: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> estas uzata ekster kunteksto de skripto: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Alvoko de funkcio dict sen Vortaro: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Nombro aÅ­ Glitpunktnombro bezonata"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "argumento de add()"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: Tro da argumentoj"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() uzeblas nur en Enmeta reÄimo"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Bone"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Åœlosilo jam ekzistas: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "argumento de extend()"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "argumento de map()"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "argumento de filter()"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld linioj: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: Nekonata funkcio: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "alvokis inputrestore() pli ofte ol inputsave()"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "argumento de insert()"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: Amplekso nepermesebla"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: Nevalida datumtipo de len()"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: PaÅo estas nul"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: Komenco preter fino"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<malplena>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "argumento de remove()"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: Tro da simbolaj ligiloj (ĉu estas ciklo?)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "argumento de reverse()"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "argumento de sort()"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "argumento de add()"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Ordiga funkcio fiaskis"
-
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Ordiga funkcio fiaskis"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(Nevalida)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Eraro dum skribo de provizora dosiero"
-
-#: ../eval.c:16159
msgid "E805: Using a Float as a Number"
msgstr "E805: Uzo de Glitpunktnombro kiel Nombro"
-#: ../eval.c:16162
msgid "E703: Using a Funcref as a Number"
msgstr "E703: Uzo de Funcref kiel Nombro"
-#: ../eval.c:16170
msgid "E745: Using a List as a Number"
msgstr "E745: Uzo de Listo kiel Nombro"
-#: ../eval.c:16173
msgid "E728: Using a Dictionary as a Number"
msgstr "E728: Uzo de Vortaro kiel Nombro"
+msgid "E910: Using a Job as a Number"
+msgstr "E910: Uzo de Tasko kiel Nombro"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: Uzo de Kanalo kiel Nombro"
+
msgid "E891: Using a Funcref as a Float"
msgstr "E891: Uzo de Funcref kiel Glitpunktnombro"
@@ -885,268 +620,275 @@ msgstr "E893: Uzo de Listo kiel Glitpunktnombro"
msgid "E894: Using a Dictionary as a Float"
msgstr "E894: Uzo de Vortaro kiel Glitpunktnombro"
-#: ../eval.c:16259
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Uzo de speciala valoro kiel Glitpunktnombro"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: Uzo de Tasko kiel Glitpunktnombro"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: Uzo de Kanalo kiel Glitpunktnombro"
+
msgid "E729: using Funcref as a String"
msgstr "E729: uzo de Funcref kiel Ĉeno"
-#: ../eval.c:16262
msgid "E730: using List as a String"
msgstr "E730: uzo de Listo kiel Ĉeno"
-#: ../eval.c:16265
msgid "E731: using Dictionary as a String"
msgstr "E731: uzo de Vortaro kiel Ĉeno"
msgid "E908: using an invalid value as a String"
msgstr "E908: uzo de nevalida valoro kiel Ĉeno"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Nekongrua datumtipo de variablo: %s"
-
-#: ../eval.c:16705
#, c-format
msgid "E795: Cannot delete variable %s"
msgstr "E795: Ne eblas forviÅi variablon %s"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Nomo de variablo Funcref devas finiÄi per majusklo: %s"
+msgstr "E704: Nomo de variablo Funcref devas eki per majusklo: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: Nomo de variablo konfliktas kun ekzistanta funkcio: %s"
-#: ../eval.c:16763
#, c-format
msgid "E741: Value is locked: %s"
msgstr "E741: Valoro estas Ålosita: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
msgid "Unknown"
msgstr "Nekonata"
-#: ../eval.c:16768
#, c-format
msgid "E742: Cannot change value of %s"
msgstr "E742: Ne eblas ÅanÄi valoron de %s"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: variablo ingita tro profunde por fari kopion"
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Nedifinita funkcio: %s"
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# mallokaj variabloj:\n"
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: Mankas '(': %s"
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tLaste Åaltita de "
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: Ne eblas uzi g: ĉi tie"
+msgid "map() argument"
+msgstr "argumento de map()"
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Nevalida argumento: %s"
+msgid "filter() argument"
+msgstr "argumento de filter()"
-#: ../eval.c:17323
#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Ripetita nomo de argumento: %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Argumento de %s devas esti Listo"
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: Mankas \":endfunction\""
+msgid "E928: String required"
+msgstr "E928: Ĉeno bezonata"
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Nomo de funkcio konfliktas kun variablo: %s"
+msgid "E808: Number or Float required"
+msgstr "E808: Nombro aÅ­ Glitpunktnombro bezonata"
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Ne eblas redifini funkcion %s: Estas nuntempe uzata"
+msgid "add() argument"
+msgstr "argumento de add()"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() uzeblas nur en Enmeta reÄimo"
+
+msgid "&Ok"
+msgstr "&Bone"
-#: ../eval.c:17604
#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: Nomo de funkcio ne kongruas kun dosiernomo de skripto: %s"
+msgid "E700: Unknown function: %s"
+msgstr "E700: Nekonata funkcio: %s"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: Nomo de funkcio bezonata"
+msgid "E922: expected a dict"
+msgstr "E922: vortaro atendita"
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: Nomo de funkcio devas eki per majusklo aÅ­ enhavi dupunkton: %s"
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: Dua argumento de function() devas esti listo aÅ­ Vortaro"
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: Nomo de funkcio devas eki per majusklo aÅ­ enhavi dupunkton: %s"
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&Bone\n"
+"&Rezigni"
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Ne eblas forviÅi funkcion %s: Estas nuntempe uzata"
+msgid "called inputrestore() more often than inputsave()"
+msgstr "alvokis inputrestore() pli ofte ol inputsave()"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Profundo de funkcia alvoko superas 'maxfuncdepth'"
+msgid "insert() argument"
+msgstr "argumento de insert()"
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "alvokas %s"
+msgid "E786: Range not allowed"
+msgstr "E786: Amplekso nepermesebla"
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ĉesigita"
+msgid "E916: not a valid job"
+msgstr "E916: nevalida tasko"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Nevalida datumtipo de len()"
+
+msgid "E957: Invalid window number"
+msgstr "E957: Nevalida numero de vindozo"
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s liveras #%<PRId64>"
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID estas rezervita por \":match\": %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: PaÅo estas nul"
+
+msgid "E727: Start past end"
+msgstr "E727: Komenco preter fino"
+
+msgid "<empty>"
+msgstr "<malplena>"
+
+msgid "E240: No connection to the X server"
+msgstr "E240: Neniu konekto al X-servilo"
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s liveras %s"
+msgid "E241: Unable to send to %s"
+msgstr "E241: Ne eblas sendi al %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Ne eblas legi respondon de servilo"
+
+msgid "E941: already started a server"
+msgstr "E941: servilo jam lanĉita"
+
+msgid "E942: +clientserver feature not available"
+msgstr "E942: la eblo +clientserver ne disponeblas"
+
+msgid "remove() argument"
+msgstr "argumento de remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Tro da simbolaj ligiloj (ĉu estas ciklo?)"
+
+msgid "reverse() argument"
+msgstr "argumento de reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Ne eblas sendi al kliento"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "daÅ­rigas en %s"
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Nevalida ago: '%s'"
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: \":return\" ekster funkcio"
+msgid "sort() argument"
+msgstr "argumento de sort()"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# mallokaj variabloj:\n"
+msgid "uniq() argument"
+msgstr "argumento de uniq()"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tLaste Åaltita de "
+msgid "E702: Sort compare function failed"
+msgstr "E702: Ordiga funkcio malsukcesis"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Neniu malnova dosiero"
+msgid "E882: Uniq compare function failed"
+msgstr "E882: kompara funkcio de uniq() malsukcesis"
+
+msgid "(Invalid)"
+msgstr "(Nevalida)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: nevalida indekso de \"submatch\": %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Eraro dum skribo de provizora dosiero"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: Nevalida argumento de reagfunctio"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, Deksesuma %02x, Okuma %03o"
-#: ../ex_cmds.c:145
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, Deksesuma %04x, Okuma %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, Deksesuma %08x, Okuma %o"
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: Movas liniojn en ilin mem"
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "1 linio movita"
-
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> linioj movitaj"
+msgid "%ld line moved"
+msgid_plural "%ld lines moved"
+msgstr[0] "%ld linio movita"
+msgstr[1] "%ld linioj movitaj"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> linioj filtritaj"
+msgid "%ld lines filtered"
+msgstr "%ld linioj filtritaj"
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr "E135: *Filtraj* AÅ­tokomandoj ne rajtas ÅanÄi aktualan bufron"
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[Neniu skribo de post lasta ÅanÄo]\n"
-#: ../ex_cmds.c:1424
#, c-format
msgid "%sviminfo: %s in line: "
msgstr "%sviminfo: %s en linio: "
-#: ../ex_cmds.c:1431
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr "E136: viminfo: Tro da eraroj, nun ignoras la reston de la dosiero"
-#: ../ex_cmds.c:1458
#, c-format
msgid "Reading viminfo file \"%s\"%s%s%s"
msgstr "Legado de dosiero viminfo \"%s\"%s%s%s"
-#: ../ex_cmds.c:1460
msgid " info"
msgstr " informo"
-#: ../ex_cmds.c:1461
msgid " marks"
msgstr " markoj"
-#: ../ex_cmds.c:1462
msgid " oldfiles"
msgstr " malnovaj dosieroj"
-#: ../ex_cmds.c:1463
msgid " FAILED"
-msgstr " FIASKIS"
+msgstr " MALSUKCESIS"
-#. 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: Dosiero viminfo ne skribeblas: %s"
-#: ../ex_cmds.c:1626
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: Tro da provizoraj dosieroj viminfo, kiel %s!"
+
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: Ne eblas skribi dosieron viminfo %s!"
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "Skribas dosieron viminfo \"%s\""
-#. Write the info:
-#: ../ex_cmds.c:1720
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: Ne eblas renomi dosieron viminfo al %s!"
+
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# Tiu dosiero viminfo estis kreita de Vim %s.\n"
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1154,47 +896,47 @@ msgstr ""
"# Vi povas redakti Äin se vi estas singarda.\n"
"\n"
-#: ../ex_cmds.c:1723
msgid "# Value of 'encoding' when this file was written\n"
msgstr "# Valoro de 'encoding' kiam tiu dosiero estis kreita\n"
-#: ../ex_cmds.c:1800
msgid "Illegal starting char"
msgstr "Nevalida eka signo"
-#: ../ex_cmds.c:2162
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# Linioj komencantaj per |, kopiitaj sen ÅanÄo:\n"
+
+msgid "Save As"
+msgstr "Konservi kiel"
+
msgid "Write partial file?"
msgstr "Ĉu skribi partan dosieron?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: Uzu ! por skribi partan bufron"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "Ĉu anstataŭigi ekzistantan dosieron \"%s\"?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Permutodosiero .swp \"%s\" ekzistas, ĉu tamen anstataÅ­igi Äin?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Permutodosiero .swp ekzistas: %s (:silent! por transpasi)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Neniu dosiernomo de bufro %<PRId64>"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Neniu dosiernomo de bufro %ld"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: Dosiero ne skribita: Skribo malÅaltita per la opcio 'write'"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1203,7 +945,6 @@ msgstr ""
"La opcio 'readonly' estas Åaltita por \"%s\".\n"
"Ĉu vi tamen volas skribi?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1214,84 +955,72 @@ msgstr ""
"BonÅance Äi eble skribeblus.\n"
"Ĉu vi volas provi?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: \"%s\" estas nurlegebla (aldonu ! por transpasi)"
-#: ../ex_cmds.c:3120
+msgid "Edit File"
+msgstr "Redakti dosieron"
+
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: AÅ­tokomandoj neatendite forviÅis novan bufron %s"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: nenumera argumento de :z"
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: Åœelkomandoj nepermeseblaj en rvim"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: Ne eblas limigi regulesprimon per literoj"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "ĉu anstataŭigi per %s (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Interrompita) "
-#: ../ex_cmds.c:4384
-msgid "1 match"
-msgstr "1 kongruo"
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "1 anstataÅ­igo"
-
-#: ../ex_cmds.c:4387
#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> kongruoj"
+msgid "%ld match on %ld line"
+msgid_plural "%ld matches on %ld line"
+msgstr[0] "%ld kongruo en %ld linio"
+msgstr[1] "%ld kongruoj en %ld linio"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> anstataÅ­igoj"
+msgid "%ld substitution on %ld line"
+msgid_plural "%ld substitutions on %ld line"
+msgstr[0] "%ld anstataÅ­igo en %ld linio"
+msgstr[1] "%ld anstataÅ­igoj en %ld linio"
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr " en 1 linio"
+#, c-format
+msgid "%ld match on %ld lines"
+msgid_plural "%ld matches on %ld lines"
+msgstr[0] "%ld kongruo en %ld linioj"
+msgstr[1] "%ld kongruoj en %ld linioj"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " en %<PRId64> linioj"
+msgid "%ld substitution on %ld lines"
+msgid_plural "%ld substitutions on %ld lines"
+msgstr[0] "%ld anstataÅ­igo en %ld linioj"
+msgstr[1] "%ld anstataÅ­igoj en %ld linioj"
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: Ne eblas fari \":global\" rekursie"
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: Ne eblas fari \":global\" rekursie kun amplekso"
# DP: global estas por ":global" do mi ne tradukis Äin
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: Regulesprimo mankas el global"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "Ŝablono trovita en ĉiuj linioj: %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "Åœablono ne trovita: %s"
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1302,105 +1031,100 @@ msgstr ""
"$"
# This message should *so* be E42!
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: Ne paniku!"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: BedaÅ­rinde estas neniu helpo '%s' por %s"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: BedaÅ­rinde estas neniu helpo por %s"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "BedaÅ­rinde, la helpdosiero \"%s\" ne troveblas"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Ne estas dosierujo: %s"
+msgid "E151: No match: %s"
+msgstr "E151: Neniu kongruo: %s"
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: Ne eblas malfermi %s en skribreÄimo"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: Ne eblas malfermi %s en legreÄimo"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: Miksaĵo de kodoprezento de helpa dosiero en lingvo: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: Ripetita etikedo \"%s\" en dosiero %s/%s"
-#: ../ex_cmds.c:5687
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ne estas dosierujo: %s"
+
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Nekonata simbola komando: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Mankas nomo de simbolo"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: Tro da simboloj estas difinitaj"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Nevalida teksto de simbolo: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Nekonata simbolo: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Mankas numero de simbolo"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Nevalida nomo de bufro: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Ne eblas salti al sennoma bufro"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Nevalida identigilo de simbolo: %ld"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: Nevalida identigilo de simbolo: %<PRId64>"
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Ne eblas ÅanÄi simbolon %s"
+
+msgid " (NOT FOUND)"
+msgstr " (NETROVITA)"
-#: ../ex_cmds.c:6066
msgid " (not supported)"
msgstr " (nesubtenata)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[ForviÅita]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "Neniu malnova dosiero"
+
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "Eniras sencimigan reÄimon. Tajpu \"cont\" por daÅ­rigi."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "linio %<PRId64>: %s"
+msgid "line %ld: %s"
+msgstr "linio %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "kmd: %s"
@@ -1412,231 +1136,193 @@ msgstr "kadro estas nul"
msgid "frame at highest level: %d"
msgstr "kadro je la plej alta nivelo: %d"
-#: ../ex_cmds2.c:322
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Kontrolpunkto en \"%s%s\" linio %<PRId64>"
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Kontrolpunkto en \"%s%s\" linio %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Kontrolpunkto ne trovita: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Neniu kontrolpunkto estas difinita"
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s linio %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s linio %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: Uzu unue \":profile start {dosiernomo}\""
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Ĉu konservi ÅanÄojn al \"%s\"?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "Sen titolo"
+#, c-format
+msgid "E947: Job still running in buffer \"%s\""
+msgstr "E947: Tasko ankoraÅ­ aktiva en la bufro \"%s\""
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Neniu skribo de post la lasta ÅanÄo por bufro \"%s\""
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "Averto: Eniris neatendite alian bufron (kontrolu aÅ­tokomandojn)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Estas nur unu redaktenda dosiero"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: Ne eblas iri antaÅ­ ol la unuan dosieron"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: Ne eblas iri preter la lastan dosieron"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: kompililo nesubtenata: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "Serĉado de \"%s\" en \"%s\""
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "Serĉado de \"%s\""
-#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "ne trovita en 'runtimepath': \"%s\""
+msgid "not found in '%s': \"%s\""
+msgstr "ne trovita en '%s: \"%s\""
+
+#, c-format
+msgid "W20: Required python version 2.x not supported, ignoring file: %s"
+msgstr "W20: Pitono versio 2.x bezonata sed nesubtenata, ignoro de dosiero: %s"
+
+#, c-format
+msgid "W21: Required python version 3.x not supported, ignoring file: %s"
+msgstr "W21: pitono versio 3.x bezonata sed nesubtenata, ignoro de dosiero: %s"
+
+msgid "Source Vim script"
+msgstr "Ruli Vim-skripton"
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "Ne eblas ruli dosierujon: \"%s\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "ne eblis ruli \"%s\""
-#: ../ex_cmds2.c:2520
#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "linio %<PRId64>: ne eblis ruli \"%s\""
+msgid "line %ld: could not source \"%s\""
+msgstr "linio %ld: ne eblis ruli \"%s\""
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "rulas \"%s\""
-#: ../ex_cmds2.c:2537
#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "linio %<PRId64>: rulas \"%s\""
+msgid "line %ld: sourcing \"%s\""
+msgstr "linio %ld: rulas \"%s\""
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "finis ruli %s"
-#: ../ex_cmds2.c:2765
+#, c-format
+msgid "continuing in %s"
+msgstr "daÅ­rigas en %s"
+
msgid "modeline"
msgstr "reÄimlinio"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "--cmd argumento"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "-c argumento"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
msgstr "medivariablo"
-#: ../ex_cmds2.c:2773
msgid "error handler"
msgstr "erartraktilo"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: Averto: NeÄusta disigilo de linio, ^M eble mankas"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: \":scriptencoding\" uzita ekster rulita dosiero"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: \":finish\" uzita ekster rulita dosiero"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "Aktuala %slingvo: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Ne eblas ÅanÄi la lingvon al \"%s\""
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "Eniras reÄimon Ex. Tajpu \"visual\" por iri al reÄimo Normala."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: Ĉe fino-de-dosiero"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Komando tro rekursia"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Escepto nekaptita: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Fino de rulita dosiero"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Fino de funkcio"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: Ambigua uzo de komando difinita de uzanto"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Ne estas redaktila komando"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: Inversa amplekso donita"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "Inversa amplekso donita, permuteblas"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: Uzu w aÅ­ w>>"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
+msgid "E943: Command table needs to be updated, run 'make cmdidxs'"
+msgstr "E943: Tabulo de komandoj estas Äisdatigenda, lanĉu 'make cmdidx'"
+
+msgid "E319: Sorry, the command is not available in this version"
msgstr "E319: BedaÅ­rinde, tiu komando ne haveblas en tiu versio"
-#: ../ex_docmd.c:3752
msgid "E172: Only one file name allowed"
msgstr "E172: Nur unu dosiernomo permesebla"
-#: ../ex_docmd.c:4238
-msgid "1 more file to edit. Quit anyway?"
-msgstr "1 plia redaktenda dosiero. Ĉu tamen eliri?"
-
-#: ../ex_docmd.c:4242
#, c-format
-msgid "%d more files to edit. Quit anyway?"
-msgstr "%d pliaj redaktendaj dosieroj. Ĉu tamen eliri?"
+msgid "%d more file to edit. Quit anyway?"
+msgid_plural "%d more files to edit. Quit anyway?"
+msgstr[0] "%d plia redaktenda dosiero. Ĉu tamen eliri?"
+msgstr[1] "%d pliaj redaktendaj dosieroj. Ĉu tamen eliri?"
-#: ../ex_docmd.c:4248
-msgid "E173: 1 more file to edit"
-msgstr "E173: 1 plia redaktenda dosiero"
-
-#: ../ex_docmd.c:4250
#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: %<PRId64> pliaj redaktendaj dosieroj"
+msgid "E173: %ld more file to edit"
+msgid_plural "E173: %ld more files to edit"
+msgstr[0] "E173: %ld plia redaktenda dosiero"
+msgstr[1] "E173: %ld pliaj redaktendaj dosieroj"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: La komando jam ekzistas: aldonu ! por anstataÅ­igi Äin"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
" Name Args Address Complete Definition"
@@ -1644,352 +1330,307 @@ msgstr ""
"\n"
" Nomo Argumentoj Adreso Kompleto Difino"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "Neniu komando difinita de uzanto trovita"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: Neniu atributo specifita"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: Nevalida nombro de argumentoj"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: Kvantoro ne povas aperi dufoje"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: Nevalida defaÅ­lta valoro de kvantoro"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: argumento bezonata por -complete"
-#: ../ex_docmd.c:4933
msgid "E179: argument required for -addr"
msgstr "E179: argumento bezonata por -addr"
-#: ../ex_docmd.c:4635
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Nevalida atributo: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Nevalida komanda nomo"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr "E183: Komandoj difinataj de uzanto devas eki per majusklo"
-#: ../ex_docmd.c:4696
msgid "E841: Reserved name, cannot be used for user defined command"
msgstr "E841: Rezervita nomo, neuzebla por komando difinita de uzanto"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: Neniu komando-difinita-de-uzanto kiel: %s"
-#: ../ex_docmd.c:5516
#, c-format
msgid "E180: Invalid address type value: %s"
msgstr "E180: Nevalida valoro de tipo de adreso: %s"
-#: ../ex_docmd.c:5219
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: Nevalida valoro de kompletigo: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr ""
"E468: Argumento de kompletigo nur permesebla por kompletigo difinita de "
"uzanto"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: Uzula kompletigo bezonas funkcian argumenton"
-#: ../ex_docmd.c:5257
+msgid "unknown"
+msgstr "nekonata"
+
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: Ne eblas trovi agordaron de koloroj '%s'"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Bonvenon, uzanto de Vim!"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: Ne eblas fermi lastan langeton"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "Jam nur unu langeto"
-#: ../ex_docmd.c:6004
+msgid "Edit File in new tab page"
+msgstr "Redakti Dosieron en nova langeto"
+
+msgid "Edit File in new window"
+msgstr "Redakti Dosieron en nova fenestro"
+
#, c-format
msgid "Tab page %d"
msgstr "Langeto %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Neniu permutodosiero .swp"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "Postaldoni dosieron"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
"E747: Ne eblas ÅanÄi dosierujon, bufro estas ÅanÄita (aldonu ! por transpasi)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Neniu antaÅ­a dosierujo"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Nekonata"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: \":winsize\" bezonas du numerajn argumentojn"
-#: ../ex_docmd.c:6655
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Pozicio de fenestro: X %d, Y %d"
+
msgid "E188: Obtaining window position not implemented for this platform"
msgstr ""
"E188: Akiro de pozicio de fenestro ne estas realigita por tiu platformo"
-#: ../ex_docmd.c:6662
msgid "E466: :winpos requires two number arguments"
msgstr "E466: \":winpos\" bezonas du numerajn argumentojn"
-#: ../ex_docmd.c:7241
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: Ne eblas uzi :redir en execute()"
+
+msgid "Save Redirection"
+msgstr "Konservi alidirekton"
+
+# DP: mi ne certas pri superflugo
+msgid "Save View"
+msgstr "Konservi superflugon"
+
+msgid "Save Session"
+msgstr "Konservi seancon"
+
+msgid "Save Setup"
+msgstr "Konservi agordaron"
+
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: Ne eblas krei dosierujon %s"
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" ekzistas (aldonu ! por transpasi)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Ne eblas malfermi \"%s\" por skribi"
-#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: Argumento devas esti litero, citilo aÅ­ retrocitilo"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: Tro profunda rekursia alvoko de \":normal\""
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< ne haveblas sen la eblo +eval"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: Neniu alterna dosiernomo por anstataÅ­igi al '#'"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: neniu dosiernomo de aÅ­tokomando por anstataÅ­igi al \"<afile>\""
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr ""
"E496: neniu numero de bufro de aÅ­tokomando por anstataÅ­igi al \"<abuf>\""
# DP: ĉu match estas verbo aŭ nomo en la angla version?
# AM: ĉi tie, nomo, Åajnas al mi
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr ""
"E497: neniu nomo de kongruo de aÅ­tokomando por anstataÅ­igi al \"<amatch>\""
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: neniu dosiernomo \":source\" por anstataÅ­igi al \"<sfile>\""
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: neniu uzebla numero de linio por \"<slnum>\""
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr "E499: Malplena dosiernomo por '%' aÅ­ '#', nur funkcias kun \":p:h\""
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: Liveras malplenan ĉenon"
-#: ../ex_docmd.c:8838
msgid "E195: Cannot open viminfo file for reading"
msgstr "E195: Ne eblas malfermi dosieron viminfo en lega reÄimo"
-#: ../ex_eval.c:464
+msgid "Untitled"
+msgstr "Sen titolo"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Neniu duliteraĵo en tiu versio"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: Ne eblas lanĉi (:throw) escepton kun prefikso 'Vim'"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Escepto lanĉita: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "Escepto finiÄis: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Escepto ne konservita: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, linio %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, linio %ld"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Kaptis escepton: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s iÄis atendanta(j)"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s daÅ­rigita(j)"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s ne konservita(j)"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Escepto"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Eraro kaj interrompo"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Eraro"
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Interrompo"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: \":if\" tro profunde ingita"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: \":endif\" sen \":if\""
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: \":else\" sen \":if\""
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: \":elseif\" sen \":if\""
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: pluraj \":else\""
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
-msgstr "E584: \":elseif\" post \":else\""
+msgstr "E584: \":elseif\" malantaÅ­ \":else\""
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: \":while/:for\" ingita tro profunde"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: \":continue\" sen \":while\" aÅ­ \":for\""
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: \":break\" sen \":while\" aÅ­ \":for\""
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: Uzo de \":endfor\" kun \":while\""
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: Uzo de \":endwhile\" kun \":for\""
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: \":try\" ingita tro profunde"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: \":catch\" sen \":try\""
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
-msgstr "E604: \":catch\" post \":finally\""
+msgstr "E604: \":catch\" malantaÅ­ \":finally\""
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: \":finally\" sen \":try\""
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: pluraj \":finally\""
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: \":endtry\" sen \":try\""
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: \":endfunction\" ekster funkcio"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: Ne eblas redakti alian bufron nun"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: Ne eblas ÅanÄi informon de bufro nun"
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "nomo de etikedo"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " tipo de dosiero\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "opcio 'history' estas nul"
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -1998,303 +1639,220 @@ msgstr ""
"\n"
"# Historio %s (de plej nova al plej malnova):\n"
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "Komanda linio"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "Serĉa ĉeno"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "Esprimo"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "Eniga linio"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "Sencimiga linio"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar preter la longo de komando"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Aktiva fenestro aÅ­ bufro forviÅita"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: tro longa vojo por kompletigo"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Nevalida vojo: '**[nombro]' devas esti ĉe la fino de la vojo aŭ "
-"sekvita de '%s'."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Ne eblas trovi dosierujon \"%s\" en cdpath"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Ne eblas trovi dosieron \"%s\" en serĉvojo"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Ne plu trovis dosierujon \"%s\" en cdpath"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Ne plu trovis dosieron \"%s\" en serĉvojo"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: AÅ­tokomandoj ÅanÄis bufron aÅ­ nomon de bufro"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Nevalida dosiernomo"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "estas dosierujo"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "ne estas dosiero"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "estas aparatdosiero (malÅaltita per la opcio 'opendevice')"
+
msgid "[New File]"
msgstr "[Nova dosiero]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[Nova DOSIERUJO]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[Dosiero tro granda]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Permeso rifuzita]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: La aÅ­tokomandoj *ReadPre igis la dosieron nelegebla"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: La aÅ­tokomandoj *ReadPre ne rajtas ÅanÄi la aktualan bufron"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim: Legado el stdin...\n"
-#. Re-opening the original file failed!
-#: ../fileio.c:909
+msgid "Reading from stdin..."
+msgstr "Legado el stdin..."
+
msgid "E202: Conversion made file unreadable!"
msgstr "E202: Konverto igis la dosieron nelegebla!"
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[rektvica memoro/kontaktoskatolo]"
-
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[rektvica memoro]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[kontaktoskatolo]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[speciala signo]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR mankas]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[divido de longaj linioj]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[NE konvertita]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[konvertita]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[ERARO DE KONVERTO en linio %<PRId64>]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERARO DE KONVERTO en linio %ld]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[NEVALIDA BAJTO en linio %<PRId64>]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[NEVALIDA BAJTO en linio %ld]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[ERAROJ DE LEGADO]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "Ne eblas trovi provizoran dosieron por konverti"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
-msgstr "Konverto kun 'charconvert' fiaskis"
+msgstr "Konverto kun 'charconvert' malsukcesis"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "ne eblas legi la eligon de 'charconvert'"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Neniu kongrua aÅ­tokomando por la bufro acwrite"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: AÅ­tokomandoj forviÅis aÅ­ malÅargis la skribendan bufron"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: AÅ­tokomando ÅanÄis la nombron de linioj neatendite"
-#: ../fileio.c:2548 ../fileio.c:2565
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans malpermesas skribojn de neÅanÄitaj bufroj"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Partaj skriboj malpermesitaj ĉe bufroj NetBeans"
+
msgid "is not a file or writable device"
msgstr "ne estas dosiero aÅ­ skribebla aparatdosiero"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "skribo al aparatdosiero malÅaltita per la opcio 'opendevice'"
+
msgid "is read-only (add ! to override)"
msgstr "estas nurlegebla (aldonu ! por transpasi)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr "E506: Ne eblas skribi restaÅ­rkopion (aldonu ! por transpasi)"
-#: ../fileio.c:2898
msgid "E507: Close error for backup file (add ! to override)"
msgstr "E507: Eraro dum fermo de restaÅ­rkopio (aldonu ! transpasi)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr "E508: Ne eblas legi restaÅ­rkopion (aldonu ! por transpasi)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: Ne eblas krei restaÅ­rkopion (aldonu ! por transpasi)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: Ne eblas krei restaÅ­rkopion (aldonu ! por transpasi)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: La rimeda forko estus perdita (aldonu ! por transpasi)"
+
msgid "E214: Can't find temp file for writing"
msgstr "E214: Ne eblas trovi provizoran dosieron por skribi"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: Ne eblas konverti (aldonu ! por skribi sen konverto)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Ne eblas malfermi ligitan dosieron por skribi"
-#: ../fileio.c:3173
msgid "E212: Can't open file for writing"
msgstr "E212: Ne eblas malfermi la dosieron por skribi"
# AM: fsync: ne traduku (nomo de C-komando)
-#: ../fileio.c:3363
msgid "E667: Fsync failed"
-msgstr "E667: Fsync fiaskis"
+msgstr "E667: Fsync malsukcesis"
-#: ../fileio.c:3398
msgid "E512: Close failed"
-msgstr "E512: Fermo fiaskis"
+msgstr "E512: Fermo malsukcesis"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: skriberaro, konverto fiaskis (igu 'fenc' malplena por transpasi)"
+msgstr ""
+"E513: skriberaro, konverto malsukcesis (igu 'fenc' malplena por transpasi)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: skriberaro, konverto fiaskis en linio %<PRId64> (igu 'fenc' malplena "
+"E513: skriberaro, konverto malsukcesis en linio %ld (igu 'fenc' malplena "
"por transpasi)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: skriberaro (ĉu plena dosiersistemo?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " ERARO DE KONVERTO"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " en linio %<PRId64>;"
+msgid " in line %ld;"
+msgstr " en linio %ld;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Aparatdosiero]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Nova]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " postaldonita(j)"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [s]"
-#: ../fileio.c:3537
msgid " written"
msgstr " skribita(j)"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: Patchmode: ne eblas konservi originalan dosieron"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: ne eblas tuÅi malplenan originalan dosieron"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Ne eblas forviÅi restaÅ­rkopion"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2302,96 +1860,70 @@ msgstr ""
"\n"
"AVERTO: Originala dosiero estas eble perdita aÅ­ difekta\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "ne eliru el la redaktilo Äis kiam la dosiero estas sukcese konservita!"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[formato dos]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[formato mac]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unikso]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[formato unikso]"
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 linio, "
-
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> linioj, "
+msgid "%ld line, "
+msgid_plural "%ld lines, "
+msgstr[0] "%ld linio, "
+msgstr[1] "%ld linioj, "
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 signo"
-
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> signoj"
+msgid "%lld character"
+msgid_plural "%lld characters"
+msgstr[0] "%lld signo"
+msgstr[1] "%lld signoj"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[sen EOL]"
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[Nekompleta lasta linio]"
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "AVERTO: La dosiero estas ÅanÄita de post kiam Äi estis legita!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "Ĉu vi vere volas skribi al Äi"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Eraro dum skribo de \"%s\""
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Eraro dum fermo de \"%s\""
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Eraro dum lego de \"%s\""
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: AÅ­tokomando FileChangedShell forviÅis bufron"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: Dosiero \"%s\" ne plu haveblas"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2399,38 +1931,30 @@ msgid ""
msgstr ""
"W12: Averto: Dosiero \"%s\" ÅanÄiÄis kaj la bufro estis ÅanÄita ankaÅ­ en Vim"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
msgstr "Vidu \":help W12\" por pliaj informoj."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: Averto: La dosiero \"%s\" ÅanÄiÄis ekde redakti Äin"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "Vidu \":help W11\" por pliaj informoj."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr "W16: Averto: Permeso de dosiero \"%s\" ÅanÄiÄis ekde redakti Äin"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "Vidu \":help W16\" por pliaj informoj."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: Averto: Dosiero \"%s\" kreiÄis post la komenco de redaktado"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Averto"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2438,821 +1962,593 @@ msgstr ""
"&Bone\n"
"Ŝ&argi Dosieron"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Ne eblis prepari por reÅargi \"%s\""
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Ne eblis reÅargi \"%s\""
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--ForviÅita--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "aÅ­to-forviÅas aÅ­tokomandon: %s <bufro=%d>"
-#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: Ne ekzistas tia grupo: \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Ne eblas forviÅi la aktualan grupon"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: ForviÅo de augroup kiu estas ankoraÅ­ uzata"
+
#, c-format
msgid "E215: Illegal character after *: %s"
-msgstr "E215: Nevalida signo post *: %s"
+msgstr "E215: Nevalida signo malantaÅ­ *: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: Ne estas tia evento: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: Ne ekzistas tia grupo aÅ­ evento: %s"
-#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- AÅ­to-Komandoj ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <bufro=%d>: nevalida numero de bufro "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Ne eblas plenumi aŭtokomandojn por ĈIUJ eventoj"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "Neniu kongrua aÅ­tokomando"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: aÅ­tokomando tro ingita"
-#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s AÅ­tokomandoj por \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "Plenumado de %s"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "aÅ­tokomando %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: Mankas {."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: Mankas }."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: Neniu faldo trovita"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: Ne eblas krei faldon per la aktuala 'foldmethod'"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: Ne eblas forviÅi faldon per la aktuala 'foldmethod'"
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld linioj falditaj "
-
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: Aldoni al lega bufro"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: rekursia mapo"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: malloka mallongigo jam ekzistas por %s"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: malloka mapo jam ekzistas por %s"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: mallongigo jam ekzistas por %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: mapo jam ekzistas por %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "Neniu mallongigo trovita"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "Neniu mapo trovita"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: Nevalida reÄimo"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--Neniu linio en bufro--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: komando ĉesigita"
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: Malsukcesis krei novan procezon por la grafika interfaco"
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: Argumento bezonata"
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: La ida procezo malsukcesis startigi la grafikan interfacon"
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ devus esti sekvita de /, ? aÅ­ &"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Ne eblas lanĉi la grafikan interfacon"
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr ""
-"E11: Nevalida en fenestro de komanda linio; <CR> plenumas, CTRL-C eliras"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Ne eblas legi el \"%s\""
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgid "E665: Cannot start GUI, no valid font found"
msgstr ""
-"E12: Nepermesebla komando el exrc/vimrc en aktuala dosierujo aŭ etikeda serĉo"
+"E665: Ne eblas startigi grafikan interfacon, neniu valida tiparo trovita"
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: Mankas \":endif\""
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: Mankas \":endtry\""
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' nevalida"
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: Mankas \":endwhile\""
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Valoro de 'imactivatekey' estas nevalida"
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: Mankas \":endfor\""
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Ne eblas disponigi koloron %s"
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: \":endwhile\" sen \":while\""
+msgid "No match at cursor, finding next"
+msgstr "Neniu kongruo ĉe kursorpozicio, trovas sekvan"
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: \":endfor\" sen \":for\""
+msgid "<cannot open> "
+msgstr "<ne eblas malfermi> "
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Dosiero ekzistas (aldonu ! por transpasi)"
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: ne eblas akiri tiparon %s"
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: La komando fiaskis"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: ne eblas reveni al la aktuala dosierujo"
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: Interna eraro"
+msgid "Pathname:"
+msgstr "Serĉvojo:"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Interrompita"
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: ne eblas akiri aktualan dosierujon"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Nevalida adreso"
+msgid "OK"
+msgstr "Bone"
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Nevalida argumento"
+msgid "Cancel"
+msgstr "Rezigni"
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Nevalida argumento: %s"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr ""
+"Fenestraĵo de rulumskalo: Ne eblis akiri geometrion de reduktita rastrumbildo"
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Nevalida esprimo: %s"
+msgid "Vim dialog"
+msgstr "Vim dialogo"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Nevalida amplekso"
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Ne eblas krei BalloonEval kun ambaÅ­ mesaÄo kaj reagfunkcio"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Nevalida komando"
+msgid "_Cancel"
+msgstr "_Rezigni"
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" estas dosierujo"
+msgid "_Save"
+msgstr "_Konservi"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Nevalida grando de rulumo"
+msgid "_Open"
+msgstr "_Malfermi"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+msgid "_OK"
+msgstr "_Bone"
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
msgstr ""
+"&Jes\n"
+"&Ne\n"
+"&Rezigni"
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Alvoko al biblioteko fiaskis por \"%s()\""
+msgid "Yes"
+msgstr "Jes"
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: Marko havas nevalidan numeron de linio"
+msgid "No"
+msgstr "Ne"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Marko ne estas agordita"
+# todo '_' is for hotkey, i guess?
+msgid "Input _Methods"
+msgstr "Enigaj _metodoj"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Ne eblas fari ÅanÄojn, 'modifiable' estas malÅaltita"
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Serĉi kaj anstataŭigi..."
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Tro profunde ingitaj skriptoj"
+msgid "VIM - Search..."
+msgstr "VIM- Serĉi..."
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Neniu alterna dosiero"
+msgid "Find what:"
+msgstr "Serĉi kion:"
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Ne estas tia mallongigo"
+msgid "Replace with:"
+msgstr "AnstataÅ­igi per:"
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: Neniu ! permesebla"
+msgid "Match whole word only"
+msgstr "Kongrui kun nur plena vorto"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: Grafika interfaco ne uzeblas: MalÅaltita dum kompilado"
+msgid "Match case"
+msgstr "Uskleca kongruo"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Neniu grupo de emfazo kiel: %s"
+msgid "Direction"
+msgstr "Direkto"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: AnkoraÅ­ neniu enmetita teksto"
+msgid "Up"
+msgstr "Supren"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Neniu antaÅ­a komanda linio"
+msgid "Down"
+msgstr "Suben"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Neniu tiel mapo"
+msgid "Find Next"
+msgstr "Trovi sekvantan"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Neniu kongruo"
+msgid "Replace"
+msgstr "AnstataÅ­igi"
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Neniu kongruo: %s"
+msgid "Replace All"
+msgstr "Anstataŭigi ĉiujn"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Neniu dosiernomo"
+msgid "_Close"
+msgstr "_Fermi"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Neniu antaÅ­a regulesprimo de anstataÅ­igo"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Ricevis peton \"die\" (morti) el la seanca administrilo\n"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Neniu antaÅ­a komando"
+msgid "Close tab"
+msgstr "Fermi langeton"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Neniu antaÅ­a regulesprimo"
+msgid "New tab"
+msgstr "Nova langeto"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Amplekso nepermesebla"
+msgid "Open Tab..."
+msgstr "Malfermi langeton..."
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: Ne sufiĉe da spaco"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Ĉefa fenestro neatendite detruiÄis\n"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Ne eblas krei dosieron %s"
+msgid "&Filter"
+msgstr "&Filtri"
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Ne eblas akiri provizoran dosiernomon"
+msgid "&Cancel"
+msgstr "&Rezigni"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Ne eblas malfermi dosieron %s"
+msgid "Directories"
+msgstr "Dosierujoj"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: Ne eblas legi dosieron %s"
+msgid "Filter"
+msgstr "Filtri"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: Neniu skribo de post lasta ÅanÄo (aldonu ! por transpasi)"
+msgid "&Help"
+msgstr "&Helpo"
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Neniu skribo de post lasta ÅanÄo]\n"
+msgid "Files"
+msgstr "Dosieroj"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: Nula argumento"
+msgid "&OK"
+msgstr "&Bone"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Nombro atendita"
+msgid "Selection"
+msgstr "Apartigo"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Ne eblas malfermi eraran dosieron %s"
+msgid "Find &Next"
+msgstr "Trovi &Sekvanta"
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Ne plu restas memoro!"
+msgid "&Replace"
+msgstr "&AnstataÅ­igi"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Åœablono ne trovita"
+msgid "Replace &All"
+msgstr "Anstataŭigi ĉi&on"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Åœablono ne trovita: %s"
+msgid "&Undo"
+msgstr "&Malfari"
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: La argumento devas esti pozitiva"
+msgid "Open tab..."
+msgstr "Malfermi langeton..."
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Ne eblas reiri al antaÅ­a dosierujo"
+msgid "Find string"
+msgstr "Trovi ĉenon"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Neniu eraro"
+msgid "Find & Replace"
+msgstr "Trovi & AnstataÅ­igi"
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Neniu listo de loko"
+msgid "Not Used"
+msgstr "Ne uzata"
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: Difekta kongruenda ĉeno"
+msgid "Directory\t*.nothing\n"
+msgstr "Dosierujo\t*.nenio\n"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: Difekta programo de regulesprimo"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: La opcio 'readonly' estas Åaltita '(aldonu ! por transpasi)"
-
-#: ../globals.h:1073
#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Ne eblas ÅanÄi nurlegeblan variablon \"%s\""
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Ne eblas trovi titolon de fenestro \"%s\""
-#: ../globals.h:1075
#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Ne eblas agordi variablon en la sabloludejo: \"%s\""
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Ne subtenata argumento: \"-%s\"; Uzu la version OLE."
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Ne eblas uzi malplenan Ålosilon de Vortaro"
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Eraro dum legado de erardosiero"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Ne eblas malfermi fenestron interne de aplikaĵo MDI"
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Nepermesebla en sabloludejo"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Nepermesebla tie"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ReÄimo de ekrano ne subtenata"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Nevalida grando de rulumo"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: La opcio 'shell' estas malplena"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Ne eblis legi datumojn de simboloj!"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: Eraro dum malfermo de permutodosiero .swp"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: malplena stako de etikedo"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Komando tro kompleksa"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Nomo tro longa"
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Ne eblas disponigi rikordon de kolormapo, iuj koloroj estas eble "
+"neÄustaj"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: Tro da ["
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Tiparoj de tiuj signaroj mankas en aro de tiparo %s:"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: Tro da dosiernomoj"
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nomo de tiparo: %s"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Vostaj signoj"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Tiparo '%s' ne estas egallarÄa"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Nekonata marko"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Nomo de tiparo: %s"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Ne eblas malvolvi ĵokerojn"
+#, c-format
+msgid "Font0: %s"
+msgstr "Font0: %s"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ne rajtas esti malpli ol 'winminheight'"
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ne rajtas esti malpli ol 'winminwidth'"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Font%ld ne estas duoble pli larÄa ol font0"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: Eraro dum skribado"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "LarÄo de font0: %ld"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Nul kvantoro"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "LarÄo de Font1: %ld"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: Uzo de <SID> ekster kunteksto de skripto"
+msgid "Invalid font specification"
+msgstr "Nevalida tiparo specifita"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Interna eraro: %s"
+msgid "&Dismiss"
+msgstr "&Forlasi"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: Åablono uzas pli da memoro ol 'maxmempattern'"
+msgid "no specific match"
+msgstr "Neniu specifa kongruo"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: malplena bufro"
+msgid "Vim - Font Selector"
+msgstr "Vim - Elektilo de tiparo"
-#: ../globals.h:1226
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: La bufro %<PRId64> ne ekzistas"
+msgid "Name:"
+msgstr "Nomo:"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Nevalida serĉa Åablono aÅ­ disigilo"
+msgid "Show size in Points"
+msgstr "Montri grandon en punktoj"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Dosiero estas Åargita en alia bufro"
+msgid "Encoding:"
+msgstr "Kodoprezento:"
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: La opcio '%s' ne estas Åaltita"
+msgid "Font:"
+msgstr "Tiparo:"
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: Nevalida nomo de reÄistro"
+msgid "Style:"
+msgstr "Stilo:"
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "serĉo atingis SUPRON, daŭrigonte al SUBO"
+msgid "Size:"
+msgstr "Grando:"
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "serĉo atingis SUBON, daŭrigonte al SUPRO"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ERARO en aÅ­tomato de korea alfabeto"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: Mankas dupunkto"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: Nevalida komponento"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: cifero atendita"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "PaÄo %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "Neniu presenda teksto"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "Presas paÄon %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Kopio %d de %d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Presis: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Presado ĉesigita"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: Eraro dum skribo de PostSkripta eliga dosiero"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Ne eblas malfermi dosieron \"%s\""
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Ne eblas legi dosieron de PostSkripta rimedo \"%s\""
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: \"%s\" ne estas dosiero de PostSkripta rimedo"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: \"%s\" ne estas subtenata dosiero de PostSkripta rimedo"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: \"%s\" dosiero de rimedo havas neÄustan version"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: Nekongrua plurbajta kodoprezento kaj signaro."
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr ""
"E674: printmbcharset ne rajtas esti malplena kun plurbajta kodoprezento."
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Neniu defaÅ­lta tiparo specifita por plurbajta presado."
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: Ne eblas malfermi eligan PostSkriptan dosieron"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Ne eblas malfermi dosieron \"%s\""
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: Dosiero de PostSkripta rimedo \"prolog.ps\" ne troveblas"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: Dosiero de PostSkripta rimedo \"cidfont.ps\" ne troveblas"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: Dosiero de PostSkripta rimedo \"%s.ps\" ne troveblas"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: Ne eblas konverti al la presa kodoprezento \"%s\""
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "Sendas al presilo..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
-msgstr "E365: Presado de PostSkripta dosiero fiaskis"
+msgstr "E365: Presado de PostSkripta dosiero malsukcesis"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "Laboro de presado sendita."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "Aldoni novan datumbazon"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Serĉi Åablonon"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "Montri tiun mesaÄon"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Ĉesigi konekton"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Repravalorizi ĉiujn konektojn"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Montri konektojn"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: Uzo: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "Tiu ĉi komando de cscope ne subtenas dividon de fenestro.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: Uzo: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag: etikedo netrovita"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: Eraro de stat(%s): %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: Eraro de stat"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s ne estas dosierujo aÅ­ valida datumbazo de cscope"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "Aldonis datumbazon de cscope %s"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: eraro dum legado de konekto de cscope %<PRId64>"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: eraro dum legado de konekto de cscope %ld"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: nekonata tipo de serĉo de cscope"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Ne eblis krei duktojn de cscope"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Ne eblis forki cscope"
-#: ../if_cscope.c:849
-#, fuzzy
msgid "cs_create_connection setpgid failed"
-msgstr "plenumo de cs_create_connection fiaskis"
+msgstr "plenumo de cs_create_connection-setgpid malsukcesis"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
-msgstr "plenumo de cs_create_connection fiaskis"
+msgstr "plenumo de cs_create_connection malsukcesis"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen de to_fp fiaskis"
+msgstr "cs_create_connection: fdopen de to_fp malsukcesis"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen de fr_fp fiaskis"
+msgstr "cs_create_connection: fdopen de fr_fp malsukcesis"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: Ne eblis naskigi procezon cscope"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: neniu konekto al cscope"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: nevalida flago cscopequickfix %c de %c"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: neniu kongruo trovita por serĉo per cscope %s de %s"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "komandoj de cscope:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (Uzo: %s)"
-#: ../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"
@@ -3263,6 +2559,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: Trovi valorizojn al tiu simbolo\n"
" c: Trovi funkciojn, kiuj alvokas tiun funkcion\n"
" d: Trovi funkciojn alvokataj de tiu funkcio\n"
" e: Trovi tiun egrep-Åablonon\n"
@@ -3272,31 +2569,31 @@ msgstr ""
" s: Trovi tiun C-simbolon\n"
" t: Trovi tiun ĉenon\n"
-#: ../if_cscope.c:1226
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: ne eblas malfermi datumbazon de cscope: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: ne eblas akiri informojn pri la datumbazo de cscope"
+
msgid "E568: duplicate cscope database not added"
msgstr "E568: ripetita datumbazo de cscope ne aldonita"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: konekto cscope %s netrovita"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "konekto cscope %s fermita"
-#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: neriparebla eraro en cs_manage_matches"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Etikedo de cscope: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3304,87 +2601,303 @@ msgstr ""
"\n"
" nro linio"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "dosiernomo / kunteksto / linio\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Eraro de cscope: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "ReÅargo de ĉiuj datumbazoj de cscope"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "neniu konekto de cscope\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid nomo de datumbazo prefiksa vojo\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "La biblioteko Lua no Åargeblis."
+
+msgid "cannot save undo information"
+msgstr "ne eblas konservi informojn de malfaro"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: BedaÅ­rinde, tiu komando estas malÅaltita, ne eblis Åargi la "
+"bibliotekojn."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: BedaÅ­rinde, tiu komando estas malÅaltita, ne eblis Åargi la modulon de "
+"MzScheme racket/base."
+
+msgid "invalid expression"
+msgstr "nevalida esprimo"
+
+msgid "expressions disabled at compile time"
+msgstr "esprimoj malÅaltitaj dum kompilado"
+
+msgid "hidden option"
+msgstr "kaÅita opcio"
+
+msgid "unknown option"
+msgstr "nekonata opcio"
+
+msgid "window index is out of range"
+msgstr "indekso de fenestro estas ekster limoj"
+
+msgid "couldn't open buffer"
+msgstr "ne eblis malfermi bufron"
+
+msgid "cannot delete line"
+msgstr "ne eblas forviÅi linion"
+
+msgid "cannot replace line"
+msgstr "ne eblas anstataÅ­igi linion"
+
+msgid "cannot insert line"
+msgstr "ne eblas enmeti linion"
+
+msgid "string cannot contain newlines"
+msgstr "ĉeno ne rajtas enhavi liniavancojn"
+
+msgid "error converting Scheme values to Vim"
+msgstr "eraro dum konverto de Scheme-valoro al Vim"
+
+msgid "Vim error: ~a"
+msgstr "Eraro de Vim: ~a"
+
+msgid "Vim error"
+msgstr "Eraro de Vim"
+
+msgid "buffer is invalid"
+msgstr "bufro estas nevalida"
+
+msgid "window is invalid"
+msgstr "fenestro estas nevalida"
+
+msgid "linenr out of range"
+msgstr "numero de linio ekster limoj"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "nepermesebla en sabloludejo de Vim"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: Vim ne povas plenumi :python post uzo de :py3"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Pitono ne "
+"Åargeblis."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887` BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Pitono ne "
+"Åargeblis."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Ne eblas alvoki Pitonon rekursie"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: Vim ne povas plenumi :py3 post uzo de :python"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ devas esti apero de Ĉeno"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: BedaÅ­rinde tiu komando estas malÅaltita, la biblioteko Ruby ne "
+"Åargeblis."
+
+msgid "E267: unexpected return"
+msgstr "E267: \"return\" neatendita"
+
+msgid "E268: unexpected next"
+msgstr "E268: \"next\" neatendita"
+
+msgid "E269: unexpected break"
+msgstr "E269: \"break\" neatendita"
+
+msgid "E270: unexpected redo"
+msgstr "E270: \"redo\" neatendita"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: \"retry\" ekster klaÅ­zo \"rescue\""
+
+msgid "E272: unhandled exception"
+msgstr "E272: netraktita escepto"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: nekonata stato de longjmp: %d"
+
+msgid "invalid buffer number"
+msgstr "nevalida numero de bufro"
+
+msgid "not implemented yet"
+msgstr "ankoraÅ­ ne realigita"
+
+msgid "cannot set line(s)"
+msgstr "ne eblas meti la linio(j)n"
+
+msgid "invalid mark name"
+msgstr "nevalida nomo de marko"
+
+msgid "mark not set"
+msgstr "marko ne estas metita"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "linio %d kolumno %d"
+
+msgid "cannot insert/append line"
+msgstr "ne eblas enmeti/postaldoni linion"
+
+msgid "line number out of range"
+msgstr "numero de linio ekster limoj"
+
+msgid "unknown flag: "
+msgstr "nekonata flago: "
+
+# DP: ĉu traduki vimOption
+msgid "unknown vimOption"
+msgstr "nekonata vimOption"
+
+msgid "keyboard interrupt"
+msgstr "klavara interrompo"
+
+msgid "vim error"
+msgstr "eraro de Vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "ne eblas krei komandon de bufro/fenestro: objekto estas forviÅiÄanta"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"ne eblas registri postalvokan komandon: bufro/fenestro estas jam forviÅiÄanta"
+
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: NERIPAREBLA TCL-ERARO: reflist difekta!? Bv. retpoÅti al vim-dev@vim."
+"org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"ne eblas registri postalvokan komandon: referenco de bufro/fenestro ne "
+"troveblas"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko Tcl ne "
+"Åargeblis."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: elira kodo %d"
+
+msgid "cannot get line"
+msgstr "ne eblas akiri linion"
+
+msgid "Unable to register a command server name"
+msgstr "Ne eblas registri nomon de komanda servilo"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Sendo de komando al cela programo malsukcesis"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Nevalida identigilo de servilo uzita: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr ""
+"E251: Ecoj de registro de apero de VIM estas nevalide formata. ForviÅita!"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Ripetita Ålosilo en JSON: \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Mankas komo en Listo: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Mankas fino de Listo ']': %s"
+
msgid "Unknown option argument"
msgstr "Nekonata argumento de opcio"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "Tro da argumentoj de redakto"
-#: ../main.c:148
msgid "Argument missing after"
-msgstr "Argumento mankas post"
+msgstr "Argumento mankas malantaÅ­"
-#: ../main.c:150
msgid "Garbage after option argument"
-msgstr "Forĵetindaĵo post argumento de opcio"
+msgstr "Forĵetindaĵo malantaŭ argumento de opcio"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "Tro da argumentoj \"+komando\", \"-c komando\" aÅ­ \"--cmd komando\""
-#: ../main.c:154
msgid "Invalid argument for"
msgstr "Nevalida argumento por"
-#: ../main.c:294
#, c-format
msgid "%d files to edit\n"
msgstr "%d redaktendaj dosieroj\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans ne estas subtenata kun tiu grafika interfaco\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' ne uzeblas: malÅaltita dum kompilado\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Tiu Vim ne estis kompilita kun la kompara eblo."
+
msgid "Attempt to open script file again: \""
msgstr "Provas malfermi skriptan dosieron denove: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Ne eblas malfermi en lega reÄimo: \""
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Ne eblas malfermi por eligo de skripto: \""
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Eraro: malsukcesis lanĉi gvim el NetBeans\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr "Vim: Eraro: Tiu versio de Vim ne ruliÄas en terminalo Cygwin\n"
+
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: Averto: Eligo ne estas al terminalo\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim: Averto: Enigo ne estas el terminalo\n"
-#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "komanda linio pre-vimrc"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Ne eblas legi el \"%s\""
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3393,37 +2906,30 @@ msgstr ""
"Pliaj informoj per: \"vim -h\"\n"
# DP: tajpu "vim --help" por testi tiujn mesaÄojn
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[dosiero...] redakti specifita(j)n dosiero(j)n"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- legi tekston el stdin"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t etikedo redakti dosieron kie etikedo estas difinata"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [erardosiero] redakti dosieron kun unua eraro"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
" uzo:"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [argumentoj] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3431,7 +2937,13 @@ msgstr ""
"\n"
" aÅ­:"
-#: ../main.c:2196
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Kie uskleco estas ignorita antaÅ­aldonu / por igi flagon majuskla"
+
msgid ""
"\n"
"\n"
@@ -3441,197 +2953,335 @@ msgstr ""
"\n"
"Argumentoj:\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tNur dosiernomoj post tio"
+msgstr "--\t\t\tNur dosiernomoj malantaÅ­ tio"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\t\tNe malvolvi ĵokerojn"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tRegistri tiun gvim al OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tMalregistri gvim de OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tRuli per grafika interfaco (kiel \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f aŭ --nofork\tMalfono: ne forki kiam lanĉas grafikan interfacon"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\t\tReÄimo Vi (kiel \"vi\")"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\t\tReÄimo Ex (kiel \"ex\")"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
msgstr "-E\t\t\tPlibonigita Ex-reÄimo"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\t\tSilenta (stapla) reÄimo (nur por \"ex\")"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\t\tKompara reÄimo (kiel \"vimdiff\")"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
msgstr "-y\t\t\tFacila reÄimo (kiel \"evim\", senreÄima)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\t\tNurlegebla reÄimo (kiel \"view\")"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\t\tLimigita reÄimo (kiel \"rvim\")"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\t\tÅœanÄoj (skribo al dosieroj) nepermeseblaj"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\t\tÅœanÄoj al teksto nepermeseblaj"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\t\tDuuma reÄimo"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\t\tReÄimo Lisp"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\t\tKongrua kun Vi: 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\t\tNe tute kongrua kun Vi: 'nocompatible'"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr ""
"-V[N][dosiernomo]\tEsti babilema [nivelo N] [konservi mesaÄojn al dosiernomo]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\t\tSencimiga reÄimo"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\t\tNeniu permutodosiero .swp, uzas nur memoron"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\t\tListigi permutodosierojn .swp kaj eliri"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r (kun dosiernomo)\tRestaÅ­ri kolapsintan seancon"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\t\tKiel -r"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNe uzi newcli por malfermi fenestrojn"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <aparatdosiero>\t\tUzi <aparatdosiero>-n por eneligo"
+
+msgid "-A\t\t\tStart in Arabic mode"
msgstr "-A\t\t\tKomenci en araba reÄimo"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\t\tKomenci en hebrea reÄimo"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\t\tKomenci en persa reÄimo"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <terminalo>\tAgordi terminalon al <terminalo>"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr ""
+"--not-a-term\t\tPreterpasi averton por enigo/eligo, kiu ne estas terminalo"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr "--ttyfail\t\tEliri se la eniro aÅ­ eliro ne estas terminalo"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\t\tUzi <vimrc> anstataÅ­ iun ajn .vimrc"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tUzi <gvimrc> anstataÅ­ iun ajn .gvimrc"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\tNe Åargi kromaĵajn skriptojn"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
msgstr "-p[N]\t\tMalfermi N langetojn (defaŭlto: po unu por ĉiu dosiero)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tMalfermi N fenestrojn (defaŭlto: po unu por ĉiu dosiero)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\t\tKiel -o sed dividi vertikale"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\t\tKomenci ĉe la fino de la dosiero"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<numL>\t\tKomenci ĉe linio <numL>"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr ""
"--cmd <komando>\tPlenumi <komando>-n antaÅ­ ol Åargi iun ajn dosieron vimrc"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <komando>\t\tPlenumi <komando>-n post kiam la unua dosiero ÅargiÄis"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr ""
"-S <seanco>\t\tRuli dosieron <seanco>-n post kiam la unua dosiero ÅargiÄis"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <skripto>\t\tLegi komandojn en Normala reÄimo el dosiero <skripto>"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr ""
"-w <eligaskripto>\tPostaldoni ĉiujn tajpitajn komandojn al dosiero "
"<eligaskripto>"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr ""
"-W <eligaskripto>\tSkribi ĉiujn tajpitajn komandojn al dosiero <eligaskripto>"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tRedakti ĉifradan dosieron"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <ekrano>\tKonekti Vim al tiu X-servilo"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNe konekti al X-servilo"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <dosieroj>\tRedakti <dosieroj>-n en Vim-servilo se eblas"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <dosieroj> Same, sed ne plendi se ne estas servilo"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <dosieroj> Kiel --remote sed atendi Äis dosieroj estas "
+"redaktitaj"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <dosieroj> Same, sed ne plendi se ne estas servilo"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <dosieroj> Kiel --remote sed uzi langeton por "
+"ĉiu dosiero"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <klavoj> Sendi <klavoj>-n al Vim-servilo kaj eliri"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <espr>\tKomputi <espr> en Vim-servilo kaj afiÅi rezulton"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tListigi haveblajn nomojn de Vim-serviloj kaj eliri"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <nomo>\tSendu al/iÄi la Vim-servilo <nomo>"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr ""
"--startuptime <dosiero> Skribi mesaÄojn de komenca tempomezurado al "
"<dosiero>"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\tUzi <viminfo> anstataÅ­ .viminfo"
-#: ../main.c:2243
+msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo"
+msgstr "--clean\t\t'nocompatible', defaÅ­ltaj agordoj de Vim, neniu viminfo"
+
msgid "-h or --help\tPrint Help (this message) and exit"
msgstr "-h aÅ­ --help\tAfiÅi Helpon (tiun mesaÄon) kaj eliri"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\tAfiÅi informon de versio kaj eliri"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argumentoj agnoskitaj de gvim (versio Motif):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argumentoj agnoskitaj de gvim (versio neXtaw):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argumentoj agnoskitaj de gvim (versio Athena):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <ekrano>\tLanĉi vim sur <ekrano>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tLanĉi vim piktograme"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <koloro>\tUzi <koloro>-n por la fona koloro (ankaÅ­: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr ""
+"-foreground <koloro>\tUzi <koloro>-n por la malfona koloro (ankaÅ­: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <tiparo>\tUzi <tiparo>-n por normala teksto (ankaÅ­: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <tiparo>\tUzi <tiparo>-n por grasa teksto"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <tiparo>\tUzi <tiparo>-n por kursiva teksto"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tUzi <geom> kiel komenca geometrio (ankaÅ­: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <larÄo>\tUzi <larÄo>-n kiel larÄo de bordero (ankaÅ­: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <larÄo> Uzi <larÄo>-n kiel larÄo de rulumskalo (ankaÅ­: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <alto>\tUzi <alto>-n kiel alto de menuzona alto (ankaÅ­: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tUzi inversan videon (ankaÅ­: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNe uzi inversan videon (ankaÅ­: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <rimedo>\tAgordi la specifitan <rimedo>-n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argumentoj agnoskitaj de gvim (versio GTK+):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <ekrano>\tLanĉi Vim sur tiu <ekrano> (ankaŭ: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <rolo>\tDoni unikan rolon por identigi la ĉefan fenestron"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tMalfermi Vim en alia GTK fenestraĵo"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tIgas gvim afiÅi la identigilon de vindozo sur stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <gepatra titolo>\tMalfermi Vim en gepatra aplikaĵo"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tMalfermi Vim en alia win32 fenestraĵo"
+
+msgid "No display"
+msgstr "Neniu ekrano"
+
+msgid ": Send failed.\n"
+msgstr ": Sendo malsukcesis.\n"
+
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Sendo malsukcesis. Provo de loka plenumo\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d de %d redaktita(j)"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Neniu ekrano: Sendado de esprimo malsukcesis.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Sendado de esprimo malsukcesis.\n"
+
msgid "No marks set"
msgstr "Neniu marko"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: Neniu marko kongruas kun \"%s\""
-#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3639,8 +3289,6 @@ msgstr ""
"\n"
"mark linio kol dosiero/teksto"
-#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3648,8 +3296,6 @@ msgstr ""
"\n"
" salt linio kol dosiero/teksto"
-#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3657,7 +3303,6 @@ msgstr ""
"\n"
"ÅanÄo linio kol teksto"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3665,8 +3310,6 @@ msgstr ""
"\n"
"# Markoj de dosiero:\n"
-#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3674,7 +3317,6 @@ msgstr ""
"\n"
"# Saltlisto (plej novaj unue):\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3682,85 +3324,89 @@ msgstr ""
"\n"
"# Historio de markoj en dosieroj (de plej nova al plej malnova):\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "Mankas '>'"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: Nevalida kodpaÄo"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Ne eblas agordi valorojn de IC"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Kreado de eniga kunteksto malsukcesis"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Malfermo de eniga metodo malsukcesis"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Averto: Ne eblis agordi detruan reagfunkcion al IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: eniga metodo subtenas neniun stilon"
+
+# DP: mi ne scias, kio estas "preedit"
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: eniga metodo ne subtenas mian antaÅ­redaktan tipon"
+
msgid "E293: block was not locked"
msgstr "E293: bloko ne estis Ålosita"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Eraro de enpoziciigo dum lego de permutodosiero .swp"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Eraro de lego en permutodosiero .swp"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Eraro de enpoziciigo dum skribo de permutodosiero .swp"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Skriberaro en permutodosiero .swp"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: Permutodosiero .swp jam ekzistas (ĉu atako per simbola ligilo?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Ĉu ne akiris blokon n-ro 0?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: Ĉu ne akiris blokon n-ro 1?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Ĉu ne akiris blokon n-ro 2?"
-#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Eraro dum Äisdatigo de ĉifrada permutodosiero .swp"
+
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: Ve, perdis la permutodosieron .swp!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Ne eblis renomi la permutodosieron .swp"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr ""
"E303: Ne eblas malfermi permutodosieron .swp de \"%s\", restaÅ­ro neeblas"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): Ne akiris blokon 0??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Neniu permutodosiero .swp trovita por %s"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Entajpu la uzendan numeron de permutodosiero .swp (0 por eliri): "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Ne eblas malfermi %s"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Ne eblas legi blokon 0 de "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3768,28 +3414,22 @@ msgstr ""
"\n"
"Eble neniu ÅanÄo estis farita aÅ­ Vim ne Äisdatigis la permutodosieron .swp."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " ne uzeblas per tiu versio de vim.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Uzu version 3.0 de Vim\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ne aspektas kiel permutodosiero .swp de Vim"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " ne uzeblas per tiu komputilo.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "La dosiero estas kreita je "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3797,85 +3437,104 @@ msgstr ""
",\n"
"aÅ­ la dosiero estas difekta."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr "E833: %s estas ĉifrita kaj tiu versio de Vim ne subtenas ĉifradon"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " difektiÄis (paÄa grando pli malgranda ol minimuma valoro).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "Uzado de permutodosiero .swp \"%s\""
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "Originala dosiero \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: Averto: Originala dosiero eble ÅanÄiÄis"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Permutodosiero .swp estas ĉifrita: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"Se vi tajpis novan Ålosilon de ĉifrado sed ne skribis la tekstan dosieron,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"tajpu la novan Ålosilon de ĉifrado."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"Se vi skribis la tekstan dosieron post ÅanÄo de la Ålosilo de ĉifrado, premu "
+"enenklavon"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"por uzi la saman Ålosilon por la teksta dosiero kaj permutodosiero .swp"
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Ne eblas legi blokon 1 de %s"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???MULTAJ LINIOJ MANKAS"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???NOMBRO DE LINIOJ NE ÄœUSTAS"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???MALPLENA BLOKO"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???LINIOJ MANKANTAJ"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr ""
"E310: Nevalida identigilo de bloko 1 (ĉu %s ne estas permutodosiero .swp?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???MANKAS BLOKO"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? ekde tie Äis ???FINO linioj estas eble difektaj"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? ekde tie Äis ???FINO linioj estas eble enmetitaj/forviÅitaj"
-#: ../memline.c:1181
msgid "???END"
msgstr "???FINO"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: RestaÅ­ro interrompita"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr "E312: Eraroj dum restaÅ­ro; rigardu liniojn komencantajn per ???"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "Vidu \":help E312\" por pliaj informoj."
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "RestaÅ­ro finiÄis. Indus kontroli ĉu ĉio estas en ordo."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3883,16 +3542,13 @@ msgstr ""
"\n"
"(Indas konservi tiun dosieron per alia nomo\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "kaj lanĉi diff kun la originala dosiero por kontroli la ÅanÄojn)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr ""
"RestaÅ­ro finiÄis. La enhavo de la bufro samas kun la enhavo de la dosiero."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3902,52 +3558,43 @@ msgstr ""
"La dosiero .swp nun forviÅindas.\n"
"\n"
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr ""
+"Uzas Ålosilon de ĉifrado el permutodosiero .swp por la teksta dosiero.\n"
+
msgid "Swap files found:"
msgstr "Permutodosiero .swp trovita:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " En la aktuala dosierujo:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " Uzado de specifita nomo:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " En dosierujo "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- nenio --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " posedata de: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " dato: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " dato: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [de Vim versio 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [ne aspektas kiel permutodosiero .swp de Vim]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " dosiernomo: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3955,15 +3602,12 @@ msgstr ""
"\n"
" modifita: "
-#: ../memline.c:1559
msgid "YES"
msgstr "JES"
-#: ../memline.c:1559
msgid "no"
msgstr "ne"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3971,11 +3615,9 @@ msgstr ""
"\n"
" uzantonomo: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " komputila nomo: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3983,7 +3625,6 @@ msgstr ""
"\n"
" komputila nomo: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3991,11 +3632,16 @@ msgstr ""
"\n"
" proceza ID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (ankoraÅ­ ruliÄas)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ne uzebla per tiu versio de Vim]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -4003,97 +3649,75 @@ msgstr ""
"\n"
" [neuzebla per tiu komputilo]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [nelegebla]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [nemalfermebla]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: Ne eblas konservi, ne estas permutodosiero .swp"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "Dosiero konservita"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
-msgstr "E314: Konservo fiaskis"
+msgstr "E314: Konservo malsukcesis"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: nevalida lnum: %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: nevalida lnum: %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: ne eblas trovi linion %<PRId64>"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: ne eblas trovi linion %ld"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: nevalida referenco de bloko id 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx devus esti 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: Ĉu Äisdatigis tro da blokoj?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: nevalida referenco de bloko id 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "ĉu forviÅita bloko 1?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Ne eblas trovi linion %<PRId64>"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Ne eblas trovi linion %ld"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: nevalida referenco de bloko id"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count estas nul"
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: numero de linio ekster limoj: %<PRId64> preter la fino"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numero de linio ekster limoj: %ld preter la fino"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: nevalida nombro de linioj en bloko %<PRId64>"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: nevalida nombro de linioj en bloko %ld"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "Stako pligrandiÄas"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: nevalida referenco de bloko id 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: Buklo de simbolaj ligiloj por \"%s\""
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: ATENTO"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4101,15 +3725,12 @@ msgstr ""
"\n"
"Trovis permutodosieron .swp kun la nomo \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Dum malfermo de dosiero \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " PLI NOVA ol permutodosiero .swp!\n"
-#: ../memline.c:3244
msgid ""
"\n"
"(1) Another program may be editing the same file. If this is the case,\n"
@@ -4121,19 +3742,12 @@ msgstr ""
" por ne havi du malsamajn aperojn de la sama dosiero, kiam vi faros\n"
" ÅanÄojn. Eliru aÅ­ daÅ­rigu singarde.\n"
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " Eliru, aÅ­ daÅ­rigu singarde.\n"
-
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) Redakta seanco de tiu dosiero kolapsis.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " Se veras, uzu \":recover\" aÅ­ \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4141,11 +3755,9 @@ msgstr ""
"\"\n"
" por restaÅ­ri la ÅanÄojn (vidu \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " Se vi jam faris Äin, forviÅu la permutodosieron .swp \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4153,25 +3765,20 @@ msgstr ""
"\"\n"
" por eviti tiun mesaÄon.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Permutodosiero .swp \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" jam ekzistas!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - ATENTO"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "Permutodosiero .swp jam ekzistas!"
# AM: ĉu Vim konvertos la unuliterajn respondojn de la uzulo?
# DP: jes, la '&' respondoj bone funkcias (mi kontrolis)
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4185,7 +3792,6 @@ msgstr ""
"&Eliri\n"
"Ĉe&sigi"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4201,56 +3807,31 @@ msgstr ""
"&Eliri\n"
"Ĉe&sigi"
-#.
-#. * 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
msgid "E326: Too many swap files found"
msgstr "E326: Tro da dosieroj trovitaj"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Ne plu restas memoro! (disponigo de %<PRIu64> bajtoj)"
-
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Parto de vojo de menuero ne estas sub-menuo"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Menuo nur ekzistas en alia reÄimo"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Neniu menuo \"%s\""
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: Malplena nomo de menuo"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Vojo de menuo ne rajtas konduki al sub-menuo"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: Aldono de menueroj direkte al menuzono estas malpermesita"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Disigilo ne rajtas esti ero de vojo de menuo"
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4258,73 +3839,60 @@ msgstr ""
"\n"
"--- Menuoj ---"
-#: ../menu.c:1313
+msgid "Tear off this menu"
+msgstr "Disigi tiun menuon"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Menuo ne estas difinita por reÄimo %s"
+
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: Vojo de menuo devas konduki al menuero"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: Menuo netrovita: %s"
-#: ../menu.c:1396
-#, c-format
-msgid "E335: Menu not defined for %s mode"
-msgstr "E335: Menuo ne estas difinita por reÄimo %s"
-
-#: ../menu.c:1426
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: Vojo de menuo devas konduki al sub-menuo"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: Menuo ne trovita - kontrolu nomojn de menuoj"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Eraro okazis dum traktado de %s:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "linio %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Nevalida nomo de reÄistro: '%s'"
-#: ../message.c:745
msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
msgstr "Flegado de mesaÄoj: Dominique PELLÉ <dominique.pelle@gmail.com>"
-#: ../message.c:986
msgid "Interrupt: "
msgstr "Interrompo: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "Premu ENEN-KLAVON aÅ­ tajpu komandon por daÅ­rigi"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s linio %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s linio %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- Pli --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " SPACETO/d/j: ekrano/paÄo/sub linio, b/u/k: supre, q: eliri "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Demando"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4332,19 +3900,8 @@ msgstr ""
"&Jes\n"
"&Ne"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Jes\n"
-"&Ne\n"
-"&Rezigni"
-
# AM: ĉu Vim konvertos unuliterajn respondojn?
# DP: jes, '&' bone funkcias (mi kontrolis)
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4358,175 +3915,242 @@ msgstr ""
"&Forlasi Ĉion\n"
"&Rezigni"
-#: ../message.c:3058
+msgid "Select Directory dialog"
+msgstr "Dialogujo de dosiera elekto"
+
+msgid "Save File dialog"
+msgstr "Dialogujo de dosiera konservo"
+
+msgid "Open File dialog"
+msgstr "Dialogujo de dosiera malfermo"
+
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: BedaÅ­rinde ne estas dosierfoliumilo en konzola reÄimo"
+
msgid "E766: Insufficient arguments for printf()"
msgstr "E766: Ne sufiĉaj argumentoj por printf()"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
-msgstr "E807: Atendis Glitpunktnombron kiel argumento de printf()"
+msgstr "E807: Atendis Glitpunktnombron kiel argumenton de printf()"
-#: ../message.c:3873
msgid "E767: Too many arguments to printf()"
msgstr "E767: Tro da argumentoj al printf()"
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Averto: ÅœanÄo de nurlegebla dosiero"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr ""
"Tajpu nombron kaj <Enenklavon> aÅ­ alklaku per la muso (malpleno rezignas): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "Tajpu nombron kaj <Enenklavon> (malpleno rezignas): "
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "1 plia linio"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "1 malplia linio"
-
-#: ../misc1.c:2593
#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> pliaj linioj"
+msgid "%ld more line"
+msgid_plural "%ld more lines"
+msgstr[0] "%ld plia linio"
+msgstr[1] "%ld pliaj linioj"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> malpliaj linioj"
+msgid "%ld line less"
+msgid_plural "%ld fewer lines"
+msgstr[0] "%ld malplia linio"
+msgstr[1] "%ld malpliaj linioj"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Interrompita)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "Bip!"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "ERARO: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[bajtoj] totalaj disponigitaj/maldisponigitaj %lu-%lu, nun uzataj %lu, "
+"kulmina uzo %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[alvokoj] totalaj re/malloc() %lu, totalaj free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Linio iÄas tro longa"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Interna eraro: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Ne plu restas memoro! (disponigo de %lu bajtoj)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "Alvokas Åelon por plenumi: \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: Mankas dupunkto"
+
+msgid "E546: Illegal mode"
+msgstr "E546: ReÄimo nepermesata"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Nevalida formo de muskursoro"
+
+msgid "E548: digit expected"
+msgstr "E548: cifero atendata"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Nevalida procento"
+
+msgid "E854: path too long for completion"
+msgstr "E854: tro longa vojo por kompletigo"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Nevalida vojo: '**[nombro]' devas esti ĉe la fino de la vojo aŭ "
+"sekvita de '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Ne eblas trovi dosierujon \"%s\" en cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Ne eblas trovi dosieron \"%s\" en serĉvojo"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Ne plu trovis dosierujon \"%s\" en cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Ne plu trovis dosieron \"%s\" en serĉvojo"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Nevalida permeso de dosiero de informo de konekto NetBeans: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Konekto de NetBeans perdita por bufro %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: netbeans ne estas subtenata kun tiu grafika interfaco"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: nebeans jam konektata"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s estas nurlegebla (aldonu ! por transpasi)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: Neniu identigilo sub la kursoro"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' estas malplena"
-#: ../normal.c:2637
+# DP: ĉu Eval devas esti tradukita?
+msgid "E775: Eval feature not available"
+msgstr "E775: Eval eblo ne disponeblas"
+
msgid "Warning: terminal cannot highlight"
msgstr "Averto: terminalo ne povas emfazi"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Neniu ĉeno sub la kursoro"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: Ne eblas forviÅi faldon per aktuala 'foldmethod'"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: Listo de ÅanÄoj estas malplena"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Ĉe komenco de ÅanÄlisto"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Ĉe fino de ÅanÄlisto"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "Tajpu \":quit<Enenklavo>\" por eliri el Vim"
-
-#: ../ops.c:248
-#, c-format
-msgid "1 line %sed 1 time"
-msgstr "1 linio %sita 1 foje"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 linio %sita %d foje"
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim"
+msgstr ""
+"Tajpu :qa! kaj premu <Enenklavon> por forlasi ĉiujn ÅanÄojn kaj eliri el "
+"Vim"
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> linio %sita 1 foje"
+msgid "%ld line %sed %d time"
+msgid_plural "%ld line %sed %d times"
+msgstr[0] "%ld linio %sita %d foje"
+msgstr[1] "%ld linio %sita %d foje"
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> linioj %sitaj %d foje"
+msgid "%ld lines %sed %d time"
+msgid_plural "%ld lines %sed %d times"
+msgstr[0] "%ld linioj %sitaj %d foje"
+msgstr[1] "%ld linioj %sitaj %d foje"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> krommarÄenendaj linioj... "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "1 linio krommarÄenita "
+msgid "%ld lines to indent... "
+msgstr "%ld krommarÄenendaj linioj... "
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> linioj krommarÄenitaj "
+msgid "%ld line indented "
+msgid_plural "%ld lines indented "
+msgstr[0] "%ld linio krommarÄenita "
+msgstr[1] "%ld linioj krommarÄenitaj "
-#: ../ops.c:938
msgid "E748: No previously used register"
msgstr "E748: Neniu reÄistro antaÅ­e uzata"
-#. must display the prompt
-#: ../ops.c:1433
msgid "cannot yank; delete anyway"
-msgstr "ne eblas kopii; forviÅi tamene"
+msgstr "ne eblas kopii; tamen forviÅi"
-#: ../ops.c:1929
-msgid "1 line changed"
-msgstr "1 linio ÅanÄita"
-
-#: ../ops.c:1931
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> linioj ÅanÄitaj"
+msgid "%ld line changed"
+msgid_plural "%ld lines changed"
+msgstr[0] "%ld linio ÅanÄita"
+msgstr[1] "%ld linioj ÅanÄitaj"
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "bloko de 1 linio kopiita"
+#, c-format
+msgid "freeing %ld lines"
+msgstr "malokupas %ld liniojn"
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "1 linio kopiita"
+#, c-format
+msgid " into \"%c"
+msgstr " en \"%c"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "bloko de %<PRId64> linioj kopiita"
+msgid "block of %ld line yanked%s"
+msgid_plural "block of %ld lines yanked%s"
+msgstr[0] "bloko de %ld linio kopiita%s"
+msgstr[1] "bloko de %ld linioj kopiitaj%s"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> linioj kopiitaj"
+msgid "%ld line yanked%s"
+msgid_plural "%ld lines yanked%s"
+msgstr[0] "%ld linio kopiita%s"
+msgstr[1] "%ld linioj kopiitaj%s"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: Nenio en reÄistro %s"
-#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4534,11 +4158,9 @@ msgstr ""
"\n"
"--- ReÄistroj ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "Nevalida nomo de reÄistro"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4546,199 +4168,181 @@ msgstr ""
"\n"
"# ReÄistroj:\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: Nekonata tipo de reÄistro %d"
-#: ../ops.c:5089
+msgid ""
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr ""
+"E883: serĉa Åablono kaj esprima reÄistro ne povas enhavi du aÅ­ pliajn liniojn"
+
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Kolumnoj; "
+msgid "%ld Cols; "
+msgstr "%ld Kolumnoj; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
msgstr ""
-"Apartigis %s%<PRId64> de %<PRId64> Linioj; %<PRId64> de %<PRId64> Vortoj; "
-"%<PRId64> de %<PRId64> Bajtoj"
+"Apartigis %s%ld de %ld Linioj; %lld de %lld Vortoj; %lld de %lld Bajtoj"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"Apartigis %s%<PRId64> de %<PRId64> Linioj; %<PRId64> de %<PRId64> Vortoj; "
-"%<PRId64> de %<PRId64> Signoj; %<PRId64> de %<PRId64> Bajtoj"
+"Apartigis %s%ld de %ld Linioj; %lld de %lld Vortoj; %lld de %lld Signoj; "
+"%lld de %lld Bajtoj"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Kol %s de %s; Linio %<PRId64> de %<PRId64>; Vorto %<PRId64> de %<PRId64>; "
-"Bajto %<PRId64> de %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "Kol %s de %s; Linio %ld de %ld; Vorto %lld de %lld; Bajto %lld de %lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"Kol %s de %s; Linio %<PRId64> de %<PRId64>; Vorto %<PRId64> de %<PRId64>; "
-"Signo %<PRId64> de %<PRId64>; Bajto %<PRId64> de %<PRId64>"
+"Kol %s de %s; Linio %ld de %ld; Vorto %lld de %lld; Signo %lld de %lld; "
+"Bajto %lld de %lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> por BOM)"
+msgid "(+%ld for BOM)"
+msgstr "(+%ld por BOM)"
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Folio %N"
-
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Dankon pro flugi per Vim"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Nekonata opcio"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: Opcio ne subtenata"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: Nepermesebla en reÄimlinio"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: Klavkodo ne agordita"
-#: ../option.c:2924
msgid "E521: Number required after ="
-msgstr "E521: Nombro bezonata post ="
+msgstr "E521: Nombro bezonata malantaÅ­ ="
-#: ../option.c:3226 ../option.c:3864
msgid "E522: Not found in termcap"
msgstr "E522: Netrovita en termcap"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Nevalida signo <%s>"
-#: ../option.c:2253
#, c-format
msgid "For option %s"
msgstr "Por opcio %s"
-#: ../option.c:3862
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: Ne eblas agordi 'term' al malplena ĉeno"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: term ne ÅanÄeblas en grafika interfaco"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Uzu \":gui\" por lanĉi la grafikan interfacon"
+
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' kaj 'patchmode' estas egalaj"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
msgstr "E834: Konfliktoj kun la valoro de 'listchars'"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: Konfliktoj kun la valoro de 'fillchars'"
-#: ../option.c:4163
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Ne ÅanÄeblas en la grafika interfaco GTK+ 2"
+
msgid "E524: Missing colon"
msgstr "E524: Mankas dupunkto"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Ĉeno de nula longo"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
-msgstr "E526: Mankas nombro post <%s>"
+msgstr "E526: Mankas nombro malantaÅ­ <%s>"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Mankas komo"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: Devas specifi ' valoron"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: enhavas nepreseblan aÅ­ plurĉellarÄan signon"
-#: ../option.c:4469
+msgid "E596: Invalid font(s)"
+msgstr "E596: Nevalida(j) tiparo(j)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: ne eblas elekti tiparon"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Nevalida tiparo"
+
+msgid "E533: can't select wide font"
+msgstr "E533: ne eblas elekti larÄan tiparon"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Nevalida larÄa tiparo"
+
#, c-format
msgid "E535: Illegal character after <%c>"
-msgstr "E535: Nevalida signo post <%c>"
+msgstr "E535: Nevalida signo malantaÅ­ <%c>"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: komo bezonata"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr "E537: 'commentstring' devas esti malplena aÅ­ enhavi %s"
-#: ../option.c:4928
+msgid "E538: No mouse support"
+msgstr "E538: Neniu muso subtenata"
+
msgid "E540: Unclosed expression sequence"
msgstr "E540: '}' mankas"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: tro da elementoj"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
-msgstr "E542: misekvilibritaj grupoj"
+msgstr "E542: misekvilibraj grupoj"
+
+msgid "E946: Cannot make a terminal with running job modifiable"
+msgstr "E946: Ne eblas igi modifebla terminalon kun aktiva tasko"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: AntaÅ­vida fenestro jam ekzistas"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr "W17: La araba bezonas UTF-8, tajpu \":set encoding=utf-8\""
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: Bezonas almenaÅ­ %d liniojn"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Bezonas almenaÅ­ %d kolumnojn"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Nekonata opcio: %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
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: Nombro bezonata: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4746,7 +4350,6 @@ msgstr ""
"\n"
"--- Kodoj de terminalo ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4754,7 +4357,6 @@ msgstr ""
"\n"
"--- Mallokaj opcioj ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4762,7 +4364,6 @@ msgstr ""
"\n"
"--- Valoroj de lokaj opcioj ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4770,37 +4371,115 @@ msgstr ""
"\n"
"--- Opcioj ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: ERARO get_varp"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': Kongrua signo mankas por %s"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': Ekstraj signoj post punktokomo: %s"
+msgstr "E358: 'langmap': Ekstraj signoj malantaÅ­ punktokomo: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Ne eblas plenumi Åelon "
+msgid "cannot open "
+msgstr "ne eblas malfermi "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Ne eblas malfermi fenestron!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Bezonas version 2.04 de Amigados aÅ­ pli novan\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Bezonas %s-on versio %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Ne eblas malfermi NIL:\n"
+
+msgid "Cannot create "
+msgstr "Ne eblas krei "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim eliras kun %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "ne eblas ÅanÄi reÄimon de konzolo?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ne estas konzolo??\n"
+
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Ne eblas plenumi Åelon kun opcio -f"
+
+msgid "Cannot execute "
+msgstr "Ne eblas plenumi "
+
+msgid "shell "
+msgstr "Åelo "
+
+msgid " returned\n"
+msgstr " liveris\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE tro malgranda."
+
+msgid "I/O ERROR"
+msgstr "ERARO DE ENIGO/ELIGO"
+
+msgid "Message"
+msgstr "MesaÄo"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Elekto de presilo malsukcesis"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "al %s de %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Nekonata tiparo de presilo: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Eraro de presado: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Presas '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Nevalida nomo de signaro \"%s\" en nomo de tiparo \"%s\""
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: Nevalida nomo de kvalito \"%s\" en nomo de tiparo \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Nevalida signo '%c' en nomo de tiparo \"%s\""
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Malfermo de vidigo X daÅ­ris %ld msek"
-#: ../os/shell.c:439
msgid ""
"\n"
-"shell returned "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"Åelo liveris "
+"Vim: Alvenis X eraro\n"
+
+msgid "Testing the X display failed"
+msgstr "Testo de la vidigo X malsukcesis"
+
+msgid "Opening the X display timed out"
+msgstr "Tempolimo okazis dum malfermo de vidigo X"
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
"Could not get security context for "
@@ -4808,7 +4487,6 @@ msgstr ""
"\n"
"Ne povis akiri kuntekston de sekureco por "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4823,221 +4501,300 @@ msgstr "Ne povis Åalti kuntekston de sekureco %s por %s"
#, c-format
msgid "Could not get security context %s for %s. Removing it!"
msgstr ""
-"Ne povis akiri kuntekston de sekureco %s por %s. Gi nun estas forigata!"
+"Ne povis akiri kuntekston de sekureco %s por %s. Äœi nun estas forigata!"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Ne eblas plenumi Åelon sh\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"Åelo liveris "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Ne eblas krei duktojn\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Ne eblas forki\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Ne eblas plenumi Åelon "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Komando terminigita\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP perdis la konekton ICE"
-#: ../os_unix.c:1558 ../os_unix.c:1647
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "Malfermo de vidigo X malsukcesis"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP: traktado de peto konservi-mem"
+
+msgid "XSMP opening connection"
+msgstr "XSMP: malfermo de konekto"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP: kontrolo de konekto ICE malsukcesis"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Ne eblas trovi dosieron \"%s\" en serĉvojo"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP: SmcOpenConnection malsukcesis: %s"
+
+msgid "At line"
+msgstr "Ĉe linio"
+
+msgid "Could not load vim32.dll!"
+msgstr "Ne eblis Åargi vim32.dll!"
+
+msgid "VIM Error"
+msgstr "Eraro de VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Ne eblis ripari referencojn de funkcioj al la DLL!"
+
+# DP: la eventoj estas tiuj, kiuj estas en la sekvantaj ĉenoj
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Kaptis eventon %s\n"
+
+msgid "close"
+msgstr "fermo"
+
+msgid "logoff"
+msgstr "elsaluto"
+
+msgid "shutdown"
+msgstr "sistemfermo"
+
+msgid "E371: Command not found"
+msgstr "E371: Netrovebla komando"
+
+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 ""
+"VIMRUN.EXE ne troveblas en via $PATH.\n"
+"Eksteraj komandoj ne paÅ­zos post kompletigo.\n"
+"Vidu :help win32-vimrun por pliaj informoj."
+
+msgid "Vim Warning"
+msgstr "Averto de Vim"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "la Åelo liveris %d"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: Tro da %%%c en formata ĉeno"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: Neatendita %%%c en formata ĉeno"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: Mankas ] en formata ĉeno"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: Nesubtenata %%%c en formata ĉeno"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: Nevalida %%%c en prefikso de formata ĉeno"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: Nevalida %%%c en formata ĉeno"
-#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' enhavas neniun Åablonon"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: Nomo de dosierujo mankas aÅ­ estas malplena"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Ne plu estas eroj"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: Aktuala vindozo fermiÄis"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Aktuala rapidriparo ÅanÄiÄis"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Aktuala listo de lokoj ÅanÄiÄis"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d de %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (forviÅita linio)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%slisto de eraroj %d de %d; %d eraroj"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: Ĉe la subo de stako de rapidriparo"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: Ĉe la supro de stako de rapidriparo"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "listo de eraroj %d de %d; %d eraroj"
+msgid "No entries"
+msgstr "Neniu ano"
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: Ne eblas skribi, opcio 'buftype' estas Åaltita"
+msgid "Error file"
+msgstr "Erara Dosiero"
-#: ../quickfix.c:2812
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Dosiernomo mankas aÅ­ nevalida Åablono"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Ne eblas malfermi dosieron \"%s\""
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: Bufro ne estas Åargita"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: Ĉeno aŭ Listo atendita"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: nevalida ano en %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
-msgstr "E769: Mankas ] post %s["
+msgstr "E769: Mankas ] malantaÅ­ %s["
+
+msgid "E944: Reverse range in character class"
+msgstr "E944: Inversa amplekso en klaso de signoj"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: tro larga amplekso de klaso de signoj"
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: Neekvilibra %s%%("
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: Neekvilibra %s("
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: Neekvilibra %s"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( estas permesebla tie"
+msgstr "E66: \\z( estas nepermesebla tie"
# DP: vidu http://www.thefreedictionary.com/et+al.
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
+msgid "E67: \\z1 - \\z9 not allowed here"
msgstr "E67: \\z1 kaj aliaj estas nepermeseblaj tie"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
-msgstr "E69: Mankas ] post %s%%["
+msgstr "E69: Mankas ] malantaÅ­ %s%%["
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: Malplena %s%%[]"
-#: ../regexp.c:1209 ../regexp.c:1224
+msgid "E956: Cannot use pattern recursively"
+msgstr "E956: Ne eblas uzi Åablonon rekursie"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Nevalida retro-referenco"
+
msgid "E339: Pattern too long"
msgstr "E339: Åœablono tro longa"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: Tro da \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: Tro da %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: Neekvilibra \\z("
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
-msgstr "E59: nevalida signo post %s@"
+msgstr "E59: nevalida signo malantaÅ­ %s@"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Tro da kompleksaj %s{...}-oj"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61: Ingita %s*"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62: Ingita %s%c"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: nevalida uzo de \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64: %s%c sekvas nenion"
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: Nevalida retro-referenco"
-
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
-msgstr "E68: Nevalida signo post \\z"
+msgstr "E68: Nevalida signo malantaÅ­ \\z"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: Nevalida signo post %s%%[dxouU]"
+msgstr "E678: Nevalida signo malantaÅ­ %s%%[dxouU]"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
-msgstr "E71: Nevalida signo post %s%%"
+msgstr "E71: Nevalida signo malantaÅ­ %s%%"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Sintaksa eraro en %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "Eksteraj subkongruoj:\n"
-#: ../regexp.c:7022
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (NFA-regulesprimo) ne eblas ripeti %s"
+
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5045,65 +4802,60 @@ msgstr ""
"E864: \\%#= povas nur esti sekvita de 0, 1, aÅ­ 2. La aÅ­tomata motoro de "
"regulesprimo estos uzata "
-#: ../regexp_nfa.c:239
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "ÅœanÄas al malavanca motoro de regulesprimo por Åablono: "
+
msgid "E865: (NFA) Regexp end encountered prematurely"
msgstr "E865: (NFA) Trovis finon de regulesprimo tro frue"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
msgstr "E866: (NFA-regulesprimo) Mispoziciigita %c"
-#: ../regexp_nfa.c:242
-#, fuzzy, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (NFA-regulesprimo) Nevalida klaso de signo "
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (NFA-regulesprimo) Nevalida klaso de signoj: %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
msgstr "E867: (NFA) Nekonata operatoro '\\z%c'"
-#: ../regexp_nfa.c:1387
-#, fuzzy, c-format
+#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) Nekonata operatoro '\\z%c'"
+msgstr "E867: (NFA) Nekonata operatoro '\\%%%c'"
+
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Eraro dum prekomputado de NFA kun ekvivalentoklaso!"
-#: ../regexp_nfa.c:1802
#, c-format
msgid "E869: (NFA) Unknown operator '\\@%c'"
msgstr "E869: (NFA) Nekonata operatoro '\\@%c'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
msgstr "E870: (NFS-regulesprimo) Eraro dum legado de limoj de ripeto"
-#. Can't have a multi follow a multi.
-#: ../regexp_nfa.c:1895
-msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+msgid "E871: (NFA regexp) Can't have a multi follow a multi"
msgstr ""
"E871: (NFA-regulesprimo) Ne povas havi mult-selekton tuj post alia mult-"
-"selekto!"
+"selekto"
-#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
msgstr "E872: (NFA-regulesprimo) tro da '('"
-#: ../regexp_nfa.c:2042
-#, fuzzy
msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E872: (NFA-regulesprimo) tro da '('"
+msgstr "E879: (NFA-regulesprimo) tro da \\z("
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
msgstr "E873: (NFA-regulesprimo) propra end-eraro"
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
+msgid "Could not open temporary log file for writing, displaying on stderr... "
+msgstr ""
+"Ne povis malfermi provizoran protokolan dosieron por skribi, nun montras sur "
+"stderr..."
+
+msgid "E874: (NFA) Could not pop the stack!"
msgstr "E874: (NFA) Ne povis elpreni de la staplo!"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
@@ -5111,177 +4863,122 @@ msgstr ""
"E875: (NFA-regulesprimo) (dum konverto de postmeto al NFA), restas tro da "
"statoj en la staplo"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr "E876: (NFA-regulesprimo) ne sufiĉa spaco por enmomorigi la tutan NFA "
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"Ne povis malfermi provizoran protokolan dosieron por skribi, nun montras sur "
-"stderr ..."
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) NE POVIS MALFERMI %s!"
+msgstr "E876: (NFA-regulesprimo) ne sufiĉa spaco por enmemorigi la tutan NFA "
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "Ne povis malfermi la provizoran protokolan dosieron por skribi "
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (NFA) Ne povis asigni memoron por traigi branĉojn!"
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " V-ANSTATAŬIGO"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ANSTATAŬIGO"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " INVERSI"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " ENMETO"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (enmeto)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (anstataÅ­igo)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (v-anstataÅ­igo)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " hebrea"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " araba"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (lingvo)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (algluo)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " VIDUMA"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " VIDUMA LINIO"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " VIDUMA BLOKO"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " APARTIGO"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " APARTIGITA LINIO"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " APARTIGITA BLOKO"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "registrado"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Nevalida serĉenda ĉeno: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: serĉo atingis SUPRON sen trovi: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: serĉo atingis SUBON sen trovi: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: Atendis '?' aÅ­ '/' post ';'"
+msgstr "E386: Atendis '?' aÅ­ '/' malantaÅ­ ';'"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (enhavas antaÅ­e listigitajn kongruojn)"
-#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- Inkluzivitaj dosieroj "
-#: ../search.c:4106
msgid "not found "
msgstr "netrovitaj "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "en serĉvojo ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Jam listigita)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " NETROVITA"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "Skanado de inkluzivitaj dosieroj: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "Serĉado de inkluzivitaj dosieroj %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: Kongruo estas ĉe aktuala linio"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Ĉiuj inkluzivitaj dosieroj estis trovitaj"
-#: ../search.c:4519
msgid "No included files"
msgstr "Neniu inkluzivita dosiero"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: Ne eblis trovi difinon"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: Ne eblis trovi Åablonon"
-#: ../search.c:4668
msgid "Substitute "
msgstr "AnstataÅ­igi "
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5292,97 +4989,126 @@ msgstr ""
"# Lasta serĉa Åablono %s:\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Eraro de formato en literuma dosiero"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Literumilo ne estas Åaltita"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr "Averto: Ne eblas trovi vortliston \"%s_%s.spl\" aÅ­ \"%s_ascii.spl\""
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Averto: Ne eblas trovi vortliston \"%s.%s.spl\" aÅ­ \"%s.ascii.spl\""
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: AÅ­tokomando SpellFileMissing forviÅis bufron"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Averto: regiono %s ne subtenata"
+
+msgid "Sorry, no suggestions"
+msgstr "BedaÅ­rinde ne estas sugestoj"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "BedaÅ­rinde estas nur %ld sugestoj"
+
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "AnstataÅ­igi \"%.*s\" per:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Neniu antaÅ­a literuma anstataÅ­igo"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Netrovita: %s"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: Trunkita literuma dosiero"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "Vosta teksto en %s linio %d: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "Nomo de afikso tro longa en %s linio %d: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr "E761: Eraro de formato en afiksa dosiero FOL, LOW aÅ­ UPP"
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
msgstr "E762: Signo en FOL, LOW aÅ­ UPP estas ekster limoj"
-#: ../spell.c:958
msgid "Compressing word tree..."
msgstr "Densigas arbon de vortoj..."
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: Literumilo ne estas Åaltita"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr "Averto: Ne eblas trovi vortliston \"%s.%s.spl\" aÅ­ \"%s.ascii.spl\""
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "Legado de literuma dosiero \"%s\""
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Tio ne Åajnas esti literuma dosiero"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: Malnova literuma dosiero, Äisdatigo bezonata"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Literuma dosiero estas por pli nova versio de Vim"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Nesubtenata sekcio en literuma dosiero"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Averto: regiono %s ne subtenata"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Tio ne Åajnas esti dosiero .sug: %s"
-#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Legado de afiksa dosiero %s ..."
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Malnova dosiero .sug, bezonas Äisdatigon: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Dosiero .sug estas por pli nova versio de Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Dosiero .sug ne kongruas kun dosiero .spl: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: eraro dum legado de dosiero .sug: %s"
+
+#, c-format
+msgid "Reading affix file %s..."
+msgstr "Legado de afiksa dosiero %s..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "Malsukceso dum konverto de vorto en %s linio %d: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "Konverto en %s nesubtenata: de %s al %s"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Konverto en %s nesubtenata"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "Nevalida valoro de FLAG en %s linio %d: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "FLAG post flagoj en %s linio %d: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5391,7 +5117,6 @@ msgstr ""
"Difino de COMPOUNDFORBIDFLAG post ano PFX povas doni neÄustajn rezultojn en "
"%s linio %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5400,42 +5125,34 @@ msgstr ""
"Difino de COMPOUNDPERMITFLAG post ano PFX povas doni neÄustajn rezultojn en "
"%s linio %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "Nevalida valoro de COMPOUNDRULES en %s linio %d: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "Nevalida valoro de COMPOUNDWORDMAX en %s linio %d: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "Nevalida valoro de COMPOUNDMIN en %s linio %d: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "Nevalida valoro de COMPOUNDSYLMAX en %s linio %d: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "Nevalida valoro de CHECKCOMPOUNDPATTERN en %s linio %d: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr "Malsama flago de kombino en daÅ­ra bloko de afikso en %s linio %d: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "Ripetita afikso en %s linio %d: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5444,337 +5161,251 @@ msgstr ""
"Afikso ankaÅ­ uzata por BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST en "
"%s linio %d: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "Y aÅ­ N atendita en %s linio %d: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "Nevalida kondiĉo en %s linio %d: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "Neatendita nombro REP(SAL) en %s linio %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "Neatendita nombro de MAPen %s linio %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "Ripetita signo en MAP en %s linio %d"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "Neagnoskita aÅ­ ripetita ano en %s linio %d: %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "Mankas linio FOL/LOW/UPP en %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "COMPOUNDSYLMAX uzita sen SYLLABLE"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "Tro da prokrastitaj prefiksoj"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Tro da kunmetitaj flagoj"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "Tro da prokrastitaj prefiksoj kaj/aÅ­ kunmetitaj flagoj"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Mankas SOFO%s-aj linioj en %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "AmbaÅ­ SAL kaj SOFO linioj en %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "Flago ne estas nombro en %s linio %d: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "Nevalida flago en %s linio %d: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "Valoro de %s malsamas ol tiu en alia dosiero .aff"
-#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Legado de vortardosiero %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Legado de vortardosiero %s..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Ne estas nombro de vortoj en %s"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "linio %6d, vorto %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "Ripetita vorto en %s linio %d: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "Unua ripetita vorto en %s linio %d: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d ripetita(j) vorto(j) en %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "%d ignorita(j) vorto(j) kun neaskiaj signoj en %s"
-#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Legado de dosiero de vortoj %s ..."
+msgid "Reading word file %s..."
+msgstr "Legado de dosiero de vortoj %s..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "Ripetita linio /encoding= ignorita en %s linio %d: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr "Linio /encoding= post vorto ignorita en %s linio %d: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "Ripetita linio /regions= ignorita en %s linio %d: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
msgstr "Tro da regionoj en %s linio %d: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "Linio / ignorita en %s linio %d: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "Nevalida regiono nr en %s linio %d: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "Nekonata flago en %s linio %d: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "Ignoris %d vorto(j)n kun neaskiaj signoj"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Ne sufiĉe da memoro, vortlisto estos nekompleta."
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "Densigis %d de %d nodoj; %d (%d%%) restantaj"
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "Relegas la dosieron de literumo..."
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
msgid "Performing soundfolding..."
msgstr "Fonetika analizado..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Nombro de vortoj post fonetika analizado: %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "Nombro de vortoj post fonetika analizado: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Totala nombro de vortoj: %d"
-#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Skribado de dosiero de sugesto %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "Skribado de dosiero de sugesto %s..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "Evaluo de memoro uzata: %d bajtoj"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
msgstr "E751: Nomo de eliga dosiero ne devas havi nomon de regiono"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
msgstr "E754: Nur 8 regionoj subtenataj"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Nevalida regiono en %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "Averto: ambaÅ­ NOBREAK kaj NOBREAK specifitaj"
-#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Skribado de literuma dosiero %s ..."
+msgid "Writing spell file %s..."
+msgstr "Skribado de literuma dosiero %s..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Farita!"
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ne havas %<PRId64> rikordojn"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' ne havas %ld rikordojn"
-#: ../spell.c:8074
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "Vorto fortirita el %s"
+msgstr "Vorto '%.*s' fortirita el %s"
-#: ../spell.c:8117
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "Vorto aldonita al %s"
+msgstr "Vorto '%.*s' aldonita al %s"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: Signoj de vorto malsamas tra literumaj dosieroj"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "BedaÅ­rinde ne estas sugestoj"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "BedaÅ­rinde estas nur %<PRId64> sugestoj"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "AnstataÅ­igi \"%.*s\" per:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: ripetita signo en rikordo MAP"
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Neniu antaÅ­a literuma anstataÅ­igo"
+msgid "No Syntax items defined for this buffer"
+msgstr "Neniu sintaksa elemento difinita por tiu bufro"
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Netrovita: %s"
+msgid "'redrawtime' exceeded, syntax highlighting disabled"
+msgstr "'redrawtime' transpasita, sintaksa emfazo malÅaltita"
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Tio ne Åajnas esti dosiero .sug: %s"
+msgid "syntax conceal on"
+msgstr "sintakso de conceal Åaltata"
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Malnova dosiero .sug, bezonas Äisdatigon: %s"
+msgid "syntax conceal off"
+msgstr "sintakso de conceal malÅaltita"
-#: ../spell.c:9286
#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Dosiero .sug estas por pli nova versio de Vim: %s"
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Nevalida argumento: %s"
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Dosiero .sug ne kongruas kun dosiero .spl: %s"
+msgid "syntax case ignore"
+msgstr "sintakso ignoras usklecon"
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: eraro dum legado de dosiero .sug: %s"
+msgid "syntax case match"
+msgstr "sintakso konsideras usklecon"
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: ripetita signo en rikordo MAP"
+msgid "syntax spell toplevel"
+msgstr "literumado en teksto sen sintaksa grupo"
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "Neniu sintaksa elemento difinita por tiu bufro"
+msgid "syntax spell notoplevel"
+msgstr "sen literumado en teksto sen sintaksa grupo"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: Nevalida argumento: %s"
+msgid "syntax spell default"
+msgstr ""
+"literumado en teksto sen sintaksa grupo, nur se ne estas @Spell aÅ­ @NoSpell"
msgid "syntax iskeyword "
msgstr "sintakso iskeyword "
-#: ../syntax.c:3299
+msgid "syntax iskeyword not set"
+msgstr "sintakso iskeyword ne Åaltita"
+
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Nenia sintaksa fasko: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "sinkronigo per C-stilaj komentoj"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "neniu sinkronigo"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "sinkronigo ekas "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " linioj antaÅ­ supra linio"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5782,7 +5413,6 @@ msgstr ""
"\n"
"--- Eroj de sintaksa sinkronigo ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5790,7 +5420,6 @@ msgstr ""
"\n"
"sinkronigo per eroj"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5798,276 +5427,215 @@ msgstr ""
"\n"
"--- Sintakseroj ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Nenia sintaksa fasko: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimuma "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maksimuma "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; kongruo "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " liniavancoj"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: La argumento \"contains\" ne akcepteblas tie"
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: nevalida valoro de cchar"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: La argumento \"group[t]here\" ne akcepteblas tie"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: Ne trovis regionan elementon por %s"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Dosiernomo bezonata"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: Tro da sintaksaj inkluzivoj"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: Mankas ']': %s"
#, c-format
msgid "E890: trailing char after ']': %s]%s"
-msgstr "E890: vosta signo post ']': %s]%s"
+msgstr "E890: vosta signo malantaÅ­ ']': %s]%s"
-#: ../syntax.c:4531
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: Mankas '=': %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Ne sufiĉaj argumentoj: sintaksa regiono %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: Tro da sintaksaj grupoj"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: Neniu fasko specifita"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Disigilo de Åablono netrovita: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
-msgstr "E402: Forĵetindaĵo post Åablono: %s"
+msgstr "E402: Forĵetindaĵo malantaÅ­ Åablono: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: sintaksa sinkronigo: Åablono de linia daÅ­rigo specifita dufoje"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Nevalidaj argumentoj: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: Mankas egalsigno: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: Malplena argumento: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s ne estas permesebla tie"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s devas esti la unua ano de la listo \"contains\""
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: Nekonata nomo de grupo: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Nevalida \":syntax\" subkomando: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
+" TOTALO NOMBRO KONGRUO PLEJ MALRAPID MEZA NOMO ÅœABLONO"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: rekursia buklo dum Åargo de syncolor.vim"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: emfaza grupo netrovita: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Ne sufiĉaj argumentoj: \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
-msgstr "E413: Tro argumentoj: \":highlight link %s\""
+msgstr "E413: Tro da argumentoj: \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr "E414: grupo havas agordojn, ligilo de emfazo ignorita"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: neatendita egalsigno: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: mankas egalsigno: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: mankas argumento: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Nevalida valoro: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: Nekonata malfona koloro"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: Nekonata fona koloro"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: Kolora nomo aÅ­ nombro nerekonita: %s"
-#: ../syntax.c:6714
#, c-format
msgid "E422: terminal code too long: %s"
msgstr "E422: kodo de terminalo estas tro longa: %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Nevalida argumento: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: Tro da malsamaj atributoj de emfazo uzataj"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: Nepresebla signo en nomo de grupo"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: Nevalida signo en nomo de grupo"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: Tro da emfazaj kaj sintaksaj grupoj"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: ĉe subo de stako de etikedoj"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: ĉe supro de stako de etikedoj"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: Ne eblas iri antaÅ­ la unuan kongruan etikedon"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: etikedo netrovita: %s"
# DP: "pri" estas "priority"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr "nro pri tipo etikedo"
-#: ../tag.c:531
msgid "file\n"
msgstr "dosiero\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: Estas nur unu kongrua etikedo"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: Ne eblas iri preter lastan kongruan etikedon"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "La dosiero \"%s\" ne ekzistas"
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "etikedo %d de %d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " aÅ­ pli"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " Uzo de etikedo kun malsama uskleco!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Dosiero \"%s\" ne ekzistas"
-#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6075,79 +5643,64 @@ msgstr ""
"\n"
"nro AL etikedo DE linio en dosiero/teksto"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "Serĉado de dosiero de etikedoj %s"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Vojo de etikeda dosiero trunkita por %s\n"
+
msgid "Ignoring long line in tags file"
msgstr "Ignoro de longa linio en etikeda dosiero"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Eraro de formato en etikeda dosiero \"%s\""
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "AntaÅ­ bajto %<PRId64>"
+msgid "Before byte %ld"
+msgstr "AntaÅ­ bajto %ld"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Etikeda dosiero ne estas ordigita: %s"
-#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: Neniu etikeda dosiero"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: Ne eblas trovi Åablonon de etikedo"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: Ne eblis trovi etikedon, nur divenas!"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "Ripetita kamponomo: %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' nekonata. Haveblaj terminaloj estas:"
-#: ../term.c:1463
msgid "defaulting to '"
msgstr "defaÅ­lto al '"
-#: ../term.c:1731
msgid "E557: Cannot open termcap file"
msgstr "E557: Ne eblas malfermi la dosieron termcap"
-#: ../term.c:1735
msgid "E558: Terminal entry not found in terminfo"
msgstr "E558: Ne trovis rikordon de terminalo terminfo"
-#: ../term.c:1737
msgid "E559: Terminal entry not found in termcap"
msgstr "E559: Ne trovis rikordon de terminalo en termcap"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: Neniu rikordo \"%s\" en termcap"
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: kapablo de terminalo \"cm\" bezonata"
-#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6155,169 +5708,361 @@ msgstr ""
"\n"
"--- Klavoj de terminalo ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "Ne povas malfermi $VIMRUNTIME/rgb.txt"
+
+msgid "Terminal"
+msgstr "Terminalo"
+
+msgid "Terminal-finished"
+msgstr "Terminalo-finiÄis"
+
+msgid "active"
+msgstr "aktiva"
+
+msgid "running"
+msgstr "ruliÄas"
+
+msgid "finished"
+msgstr "finiÄis"
+
+msgid "new shell started\n"
+msgstr "nova Åelo lanĉita\n"
+
msgid "Vim: Error reading input, exiting...\n"
msgstr "Vim: Eraro dum legado de eniro, elironta...\n"
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Uzis CUT_BUFFER0 anstataÅ­ malplenan apartigon"
+
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Nombro de linioj ÅanÄiÄis neatendite"
+msgstr "E881: Nombro de linioj ÅanÄiÄis neatendite"
+
+msgid "No undo possible; continue anyway"
+msgstr "Malfaro neebla; tamen daÅ­rigi"
-#: ../undo.c:627
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: Ne eblas malfermi la malfaran dosieron por skribi: %s"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: Difektita malfara dosiero (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr "Ne eblis skribi malfaran dosieron en iu dosiero ajn de 'undodir'"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "Ne superskribos malfaran dosieron, ne eblis legi: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "Ne superskribos, tio ne estas malfara dosiero: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Preterpasas skribon de malfara dosiero, nenio por malfari"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "Skribas malfaran dosieron: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: Skriberaro en malfara dosiero: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "Ne legas malfaran dosieron, posedanto malsamas: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "Legado de malfara dosiero: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: Ne eblas malfermi malfaran dosieron por legi: %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: Ne estas malfara dosiero: %s"
-#: ../undo.c:1313
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Ne ĉifrita dosiero havas ĉifritan malfaran dosieron: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Malĉifrado de malfara dosiero malsukcesis: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Malfara dosiero estas ĉifrita: %s"
+
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: Malkongrua malfara dosiero: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr "Enhavo de dosiero ÅanÄiÄis, ne eblas uzi malfarajn informojn"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "Finis legi malfaran dosieron %s"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Jam al la plej malnova ÅanÄo"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Jam al la plej nova ÅanÄo"
-#: ../undo.c:1806
#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Malfara numero %<PRId64> netrovita"
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Malfara numero %ld netrovita"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: nevalidaj numeroj de linioj"
-#: ../undo.c:2183
msgid "more line"
msgstr "plia linio"
-#: ../undo.c:2185
msgid "more lines"
msgstr "pliaj linioj"
-#: ../undo.c:2187
msgid "line less"
msgstr "malpli linio"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "malpli linioj"
-#: ../undo.c:2193
msgid "change"
msgstr "ÅanÄo"
-#: ../undo.c:2195
msgid "changes"
msgstr "ÅanÄoj"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
-#: ../undo.c:2228
msgid "before"
msgstr "antaÅ­"
-#: ../undo.c:2228
msgid "after"
msgstr "post"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "Nenio por malfari"
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "numero ÅanÄoj tempo konservita"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "antaÅ­ %<PRId64> sekundoj"
+msgid "%ld second ago"
+msgid_plural "%ld seconds ago"
+msgstr[0] "antaÅ­ %ld sekundo"
+msgstr[1] "antaÅ­ %ld sekundoj"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: undojoin estas nepermesebla post malfaro"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: listo de malfaro estas difekta"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: linio de malfaro mankas"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: La funkcio %s jam ekzistas (aldonu ! por anstataÅ­igi Äin)"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Rikordo de vortaro jam ekzistas"
+
+msgid "E718: Funcref required"
+msgstr "E718: Funcref bezonata"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Nekonata funkcio: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Nevalida argumento: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Ripetita nomo de argumento: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Tro da argumentoj por funkcio: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Nevalidaj argumentoj por funkcio: %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Profundo de funkcia alvoko superas 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "alvokas %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s ĉesigita"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s liveras #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s liveras %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Tro da argumentoj"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Nekonata funkcio: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: funkcio estis forviÅita: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Ne sufiĉe da argumentoj por funkcio: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> estas uzata ekster kunteksto de skripto: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Alvoko de funkcio dict sen Vortaro: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Nomo de funkcio bezonata"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: Nomo de funkcio devas eki per majusklo aÅ­ per \"s:\": %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: Nomo de funkcio ne povas enhavi dupunkton: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Nedifinita funkcio: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Mankas '(': %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Ne eblas uzi g: ĉi tie"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: Fermo-funkcio devus esti je la plej alta nivelo: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Mankas \":endfunction\""
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: Teksto trovita malantaÅ­ :endfunction: %s"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Nomo de funkcio konfliktas kun variablo: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Ne eblas redifini funkcion %s: Estas nuntempe uzata"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Nomo de funkcio ne kongruas kun dosiernomo de skripto: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Ne eblas forviÅi funkcion %s: Estas nuntempe uzata"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: \":return\" ekster funkcio"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Mankas krampoj: %s"
+
+#, c-format
+msgid "%s (%s, compiled %s)"
+msgstr "%s (%s, kompilita %s)"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Grafika versio MS-Vindozo 64-bitoj"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Grafika versio MS-Vindozo 32-bitoj"
+
+msgid " with OLE support"
+msgstr " kun subteno de OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Versio konzola MS-Vindozo 64-bitoj"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Versio konzola MS-Vindozo 32-bitoj"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Versio Mak OS X (unikso)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Versio Mak OS X"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Versio Mak OS"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"Versio OpenVMS"
+
msgid ""
"\n"
"Included patches: "
@@ -6325,7 +6070,6 @@ msgstr ""
"\n"
"Flikaĵoj inkluzivitaj: "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6333,11 +6077,9 @@ msgstr ""
"\n"
"Ekstraj flikaĵoj: "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Modifita de "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6345,11 +6087,9 @@ msgstr ""
"\n"
"Kompilita "
-#: ../version.c:649
msgid "by "
msgstr "de "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6357,1897 +6097,924 @@ msgstr ""
"\n"
"Grandega versio "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Granda versio "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Normala versio "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Malgranda versio "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Malgrandega versio "
+
msgid "without GUI."
msgstr "sen grafika interfaco."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "kun grafika interfaco GTK3."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "kun grafika interfaco GTK2-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "kun grafika interfaco GTK2."
+
+msgid "with X11-Motif GUI."
+msgstr "kun grafika interfaco X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "kun grafika interfaco X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "kun grafika interfaco X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "kun grafika interfaco Photon."
+
+msgid "with GUI."
+msgstr "sen grafika interfaco."
+
+msgid "with Carbon GUI."
+msgstr "kun grafika interfaco Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "kun grafika interfaco Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "kun (klasika) grafika interfaco."
+
msgid " Features included (+) or not (-):\n"
msgstr " Ebloj inkluzivitaj (+) aÅ­ ne (-):\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " sistema dosiero vimrc: \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " dosiero vimrc de uzanto: \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " 2-a dosiero vimrc de uzanto: \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " 3-a dosiero vimrc de uzanto: \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " dosiero exrc de uzanto: \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " 2-a dosiero exrc de uzanto: \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " sistema dosiero gvimrc: \""
+
+msgid " user gvimrc file: \""
+msgstr " dosiero gvimrc de uzanto: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " 2-a dosiero gvimrc de uzanto: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " 3-a dosiero gvimrc de uzanto: \""
+
+msgid " defaults file: \""
+msgstr " dosiero de defaÅ­ltoj: \""
+
+msgid " system menu file: \""
+msgstr " dosiero de sistema menuo: \""
+
msgid " fall-back for $VIM: \""
msgstr " defaÅ­lto de $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " defaÅ­lto de VIMRUNTIME: \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "Kompilado: "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "Kompililo: "
+
msgid "Linking: "
msgstr "Ligado: "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr " SENCIMIGA MUNTO"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi plibonigita"
-#: ../version.c:769
msgid "version "
msgstr "versio "
# DP: vidu http://www.thefreedictionary.com/et+al.
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "de Bram Moolenaar kaj aliuloj"
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Vim estas libera programo kaj disdoneblas libere"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "Helpu malriĉajn infanojn en Ugando!"
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "tajpu :help iccf<Enenklavo> por pliaj informoj "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "tajpu :q<Enenklavo> por eliri "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:780
msgid "type :help<Enter> or <F1> for on-line help"
msgstr "tajpu :help<Enenklavo> aÅ­ <F1> por aliri la helpon "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "tajpu :help version7<Enenklavo> por informo de versio"
+msgid "type :help version8<Enter> for version info"
+msgstr "tajpu :help version8<Enenklavo> por informo de versio"
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "RuliÄas en reÄimo kongrua kun Vi"
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr "tajpu :set nocp<Enenklavo> por Vim defaÅ­ltoj "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr "tajpu :help cp-default<Enenklavo> por pliaj informoj "
-#: ../version.c:827
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+msgid "menu Help->Orphans for information "
+msgstr "menuo Help->Orfinoj por pliaj informoj "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "RuliÄas senreÄime, tajpita teksto estas enmetita"
+
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi Enmetan ReÄimon"
+
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+msgid " for two modes "
+msgstr " por du reÄimoj "
+
+# DP: tiu ĉeno pli longas (mi ne volas igi ĉiujn aliajn ĉenojn
+# pli longajn)
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi ReÄimon Kongruan kun Vi"
+
+# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
+msgid " for Vim defaults "
+msgstr " por defaÅ­ltoj de Vim "
+
msgid "Sponsor Vim development!"
msgstr "Subtenu la programadon de Vim!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "IÄu registrita uzanto de Vim!"
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "tajpu :help sponsor<Enenklavo> por pliaj informoj "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "tajpu :help register<Enenklavo> por pliaj informoj "
# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "menuo Helpo->Subteni/Registri por pliaj informoj "
-#: ../window.c:119
msgid "Already only one window"
msgstr "Jam nur unu fenestro"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Ne estas antaÅ­vida fenestro"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: Ne eblas dividi supralivan kaj subdekstran samtempe"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: Ne eblas rotacii kiam alia fenestro estas dividita"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: Ne eblas fermi la lastan fenestron"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: Ne eblas fermi la fenestron de aÅ­tokomandoj"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr "E814: Ne eblas fermi fenestron, nur la fenestro de aÅ­tokomandoj restus"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: La alia fenestro enhavas ÅanÄojn"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: Neniu dosiernomo sub la kursoro"
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() alvokita kun malplena pasvorto"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Misuzo de pezkomenca/pezfina en blowfish"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: Testo de sha256 fiaskis"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Testo de blowfish fiaskis"
-
-#~ msgid "Patch file"
-#~ msgstr "Flika dosiero"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&Bone\n"
-#~ "&Rezigni"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Neniu konekto al Vim-servilo"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Ne eblas sendi al %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Ne eblas legi respondon de servilo"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Ne eblas sendi al kliento"
-
-#~ msgid "Save As"
-#~ msgstr "Konservi kiel"
-
-#~ msgid "Edit File"
-#~ msgstr "Redakti dosieron"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (NETROVITA)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Ruli Vim-skripton"
-
-#~ msgid "unknown"
-#~ msgstr "nekonata"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "Redakti Dosieron en nova fenestro"
-
-#~ msgid "Append File"
-#~ msgstr "Postaldoni dosieron"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Pozicio de fenestro: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "Konservi alidirekton"
-
-# DP: mi ne certas pri superflugo
-#~ msgid "Save View"
-#~ msgstr "Konservi superflugon"
-
-#~ msgid "Save Session"
-#~ msgstr "Konservi seancon"
-
-#~ msgid "Save Setup"
-#~ msgstr "Konservi agordaron"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< ne haveblas sen la eblo +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Neniu duliteraĵo en tiu versio"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "estas aparatdosiero (malÅaltita per la opcio 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "Legado el stdin..."
-
-#~ msgid "[crypted]"
-#~ msgstr "[ĉifrita]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Dosiero estas ĉifrata per nekonata metodo"
-
-#~ msgid "Warning: Using a weak encryption method; see :help 'cm'"
-#~ msgstr "Averto: uzo de malfortika ĉifrada metodo; vidu :help 'cm'"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans malpermesas skribojn de neÅanÄitaj bufroj"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Partaj skriboj malpermesitaj ĉe bufroj NetBeans"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "skribo al aparatdosiero malÅaltita per la opcio 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: La rimeda forko estus perdita (aldonu ! por transpasi)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: Ne sukcesis krei novan procezon por la grafika interfaco"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: La ida procezo ne sukcesis startigi la grafikan interfacon"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Ne eblas lanĉi la grafikan interfacon"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Ne eblas legi el \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr ""
-#~ "E665: Ne eblas startigi grafikan interfacon, neniu valida tiparo trovita"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' nevalida"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Valoro de 'imactivatekey' estas nevalida"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Ne eblas disponigi koloron %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Neniu kongruo ĉe kursorpozicio, trovas sekvan"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<ne eblas malfermi> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ne eblas akiri tiparon %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ne eblas reveni al la aktuala dosierujo"
-
-#~ msgid "Pathname:"
-#~ msgstr "Serĉvojo:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ne eblas akiri aktualan dosierujon"
-
-#~ msgid "OK"
-#~ msgstr "Bone"
-
-#~ msgid "Cancel"
-#~ msgstr "Rezigni"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Fenestraĵo de rulumskalo: Ne eblis akiri geometrion de reduktita "
-#~ "rastrumbildo"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim dialogo"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Ne eblas krei BalloonEval kun ambaÅ­ mesaÄo kaj reagfunkcio"
-
-# todo '_' is for hotkey, i guess?
-#~ msgid "Input _Methods"
-#~ msgstr "Enigaj _metodoj"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Serĉi kaj anstataŭigi..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM- Serĉi..."
-
-#~ msgid "Find what:"
-#~ msgstr "Serĉi kion:"
-
-#~ msgid "Replace with:"
-#~ msgstr "AnstataÅ­igi per:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Kongrui kun nur plena vorto"
-
-#~ msgid "Match case"
-#~ msgstr "Uskleca kongruo"
-
-#~ msgid "Direction"
-#~ msgstr "Direkto"
-
-#~ msgid "Up"
-#~ msgstr "Supren"
-
-#~ msgid "Down"
-#~ msgstr "Suben"
-
-#~ msgid "Find Next"
-#~ msgstr "Trovi sekvantan"
-
-#~ msgid "Replace"
-#~ msgstr "AnstataÅ­igi"
-
-#~ msgid "Replace All"
-#~ msgstr "Anstataŭigi ĉiujn"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: Ricevis peton \"die\" (morti) el la seanca administrilo\n"
-
-#~ msgid "Close tab"
-#~ msgstr "Fermi langeton"
-
-#~ msgid "New tab"
-#~ msgstr "Nova langeto"
-
-#~ msgid "Open Tab..."
-#~ msgstr "Malfermi langeton..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Ĉefa fenestro neatendite detruiÄis\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&Filtri"
-
-#~ msgid "&Cancel"
-#~ msgstr "&Rezigni"
-
-#~ msgid "Directories"
-#~ msgstr "Dosierujoj"
-
-#~ msgid "Filter"
-#~ msgstr "Filtri"
-
-#~ msgid "&Help"
-#~ msgstr "&Helpo"
-
-#~ msgid "Files"
-#~ msgstr "Dosieroj"
-
-#~ msgid "&OK"
-#~ msgstr "&Bone"
-
-#~ msgid "Selection"
-#~ msgstr "Apartigo"
-
-#~ msgid "Find &Next"
-#~ msgstr "Trovi &Sekvanta"
-
-#~ msgid "&Replace"
-#~ msgstr "&AnstataÅ­igi"
-
-#~ msgid "Replace &All"
-#~ msgstr "Anstataŭigi ĉi&on"
-
-#~ msgid "&Undo"
-#~ msgstr "&Malfari"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Ne eblas trovi titolon de fenestro \"%s\""
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Ne subtenata argumento: \"-%s\"; Uzu la version OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Ne eblas malfermi fenestron interne de aplikaĵo MDI"
-
-#~ msgid "Open tab..."
-#~ msgstr "Malfermi langeton..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Trovi ĉenon (uzu '\\\\' por trovi '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Trovi kaj anstataÅ­igi (uzu '\\\\' por trovi '\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "Ne uzata"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Dosierujo\t*.nenio\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Ne eblas disponigi rikordon de kolormapo, iuj koloroj estas "
-#~ "eble neÄustaj"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Tiparoj de tiuj signaroj mankas en aro de tiparo %s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Nomo de tiparo: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Tiparo '%s' ne estas egallarÄa"
-
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Nomo de tiparo: %s\n"
-
-#~ msgid "Font0: %s\n"
-#~ msgstr "Font0: %s\n"
-
-#~ msgid "Font1: %s\n"
-#~ msgstr "Font1: %s\n"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "Font%<PRId64> ne estas duoble pli larÄa ol font0\n"
-
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "LarÄo de font0: %<PRId64>\n"
-
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "LarÄo de Font1: %<PRId64>\n"
-#~ "\n"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Nevalida tiparo specifita"
-
-#~ msgid "&Dismiss"
-#~ msgstr "&Forlasi"
-
-#~ msgid "no specific match"
-#~ msgstr "Neniu specifa kongruo"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - Elektilo de tiparo"
-
-#~ msgid "Name:"
-#~ msgstr "Nomo:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Montri grandon en punktoj"
-
-#~ msgid "Encoding:"
-#~ msgstr "Kodoprezento:"
-
-#~ msgid "Font:"
-#~ msgstr "Tiparo:"
-
-#~ msgid "Style:"
-#~ msgstr "Stilo:"
-
-#~ msgid "Size:"
-#~ msgstr "Grando:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ERARO en aÅ­tomato de korea alfabeto"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: Eraro de stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: ne eblas malfermi datumbazon de cscope: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: ne eblas akiri informojn pri la datumbazo de cscope"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "La biblioteko Lua no Åargeblis."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "ne eblas konservi informojn de malfaro"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: BedaÅ­rinde, tiu komando estas malÅaltita, ne eblis Åargi la "
-#~ "bibliotekojn."
-
-#~ msgid "invalid expression"
-#~ msgstr "nevalida esprimo"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "esprimoj malÅaltitaj dum kompilado"
-
-#~ msgid "hidden option"
-#~ msgstr "kaÅita opcio"
-
-#~ msgid "unknown option"
-#~ msgstr "nekonata opcio"
-
-#~ msgid "window index is out of range"
-#~ msgstr "indekso de fenestro estas ekster limoj"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "ne eblis malfermi bufron"
-
-#~ msgid "cannot delete line"
-#~ msgstr "ne eblas forviÅi linion"
-
-#~ msgid "cannot replace line"
-#~ msgstr "ne eblas anstataÅ­igi linion"
-
-#~ msgid "cannot insert line"
-#~ msgstr "ne eblas enmeti linion"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ĉeno ne rajtas enhavi liniavancojn"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "eraro dum konverto de Scheme-valoro al Vim"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Eraro de Vim: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Eraro de Vim"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "bufro estas nevalida"
-
-#~ msgid "window is invalid"
-#~ msgstr "fenestro estas nevalida"
-
-#~ msgid "linenr out of range"
-#~ msgstr "numero de linio ekster limoj"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "nepermesebla en sabloludejo de Vim"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: Vim ne povas plenumi :python post uzo de :py3"
-
-#~ msgid "only string keys are allowed"
-#~ msgstr "nur ĉenaj Ålosiloj estas permeseblaj"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Pitono ne "
-#~ "Åargeblis."
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Ne eblas alvoki Pitonon rekursie"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: Vim ne povas plenumi :py3 post uzo de :python"
-
-#~ msgid "index must be int or slice"
-#~ msgstr "indekso devas esti 'int' aÅ­ 'slice'"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ devas esti apero de Ĉeno"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: BedaÅ­rinde tiu komando estas malÅaltita, la biblioteko Ruby ne "
-#~ "Åargeblis."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: \"return\" neatendita"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: \"next\" neatendita"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: \"break\" neatendita"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: \"redo\" neatendita"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: \"retry\" ekster klaÅ­zo \"rescue\""
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: netraktita escepto"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: nekonata stato de longjmp: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Baskuligi realigon/difinon"
-
-#~ msgid "Show base class of"
-#~ msgstr "Vidigi bazan klason de"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Montri anajn homonimigajn funkciojn"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Rekuperi el dosiero"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Rekuperi el projekto"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Rekuperi de ĉiuj projektoj"
-
-#~ msgid "Retrieve"
-#~ msgstr "Rekuperi"
-
-#~ msgid "Show source of"
-#~ msgstr "Vidigi fonton de"
-
-#~ msgid "Find symbol"
-#~ msgstr "Trovi simbolon"
-
-#~ msgid "Browse class"
-#~ msgstr "Foliumi klasojn"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Montri klason en hierarkio"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Montri klason en hierarkio restriktita"
-
-# todo
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ligas al"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ligiÄas de"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref havas"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref uzita de"
-
-# DP: mi ne certas pri kio temas
-#~ msgid "Show docu of"
-#~ msgstr "Vidigi dokumentaron de"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Krei dokumentaron de"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Konekto al SNiFF+ neeblas. Kontrolu medion (sniffemacs trovendas en "
-#~ "$PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Eraro dum lego. Malkonektita"
-
-# DP: Tiuj 3 mesaÄoj estas kune
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ estas aktuale "
-
-#~ msgid "not "
-#~ msgstr "ne "
-
-#~ msgid "connected"
-#~ msgstr "konektita"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Nekonata peto de SNiFF+: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Eraro dum konekto al SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ne estas konektita"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Ne estas bufro SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: Eraro dum skribo. Malkonektita"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "nevalida numero de bufro"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ankoraÅ­ ne realigita"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "ne eblas meti la linio(j)n"
-
-#~ msgid "invalid mark name"
-#~ msgstr "nevalida nomo de marko"
-
-#~ msgid "mark not set"
-#~ msgstr "marko ne estas metita"
-
-#~ msgid "row %d column %d"
-#~ msgstr "linio %d kolumno %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "ne eblas enmeti/postaldoni linion"
-
-#~ msgid "line number out of range"
-#~ msgstr "numero de linio ekster limoj"
-
-#~ msgid "unknown flag: "
-#~ msgstr "nekonata flago: "
-
-# DP: ĉu traduki vimOption
-#~ msgid "unknown vimOption"
-#~ msgstr "nekonata vimOption"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "klavara interrompo"
-
-#~ msgid "vim error"
-#~ msgstr "eraro de Vim"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "ne eblas krei komandon de bufro/fenestro: objekto estas forviÅiÄanta"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "ne eblas registri postalvokan komandon: bufro/fenestro estas jam "
-#~ "forviÅiÄanta"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: NERIPAREBLA TCL-ERARO: reflist difekta!? Bv. retpoÅti al vim-"
-#~ "dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "ne eblas registri postalvokan komandon: referenco de bufro/fenestro ne "
-#~ "troveblas"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko Tcl ne "
-#~ "Åargeblis."
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: elira kodo %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "ne eblas akiri linion"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Ne eblas registri nomon de komanda servilo"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Sendo de komando al cela programo fiaskis"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Nevalida identigilo de servilo uzita: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: Ecoj de registro de apero de VIM estas nevalide formata. ForviÅita!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ne estas subtenata kun tiu grafika interfaco\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Tiu Vim ne estis kompilita kun la kompara eblo."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' ne uzeblas: malÅaltita dum kompilado\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Eraro: Fiaskis lanĉi gvim el NetBeans\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "Kie uskleco estas ignorita antaÅ­aldonu / por igi flagon majuskla"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tRegistri tiun gvim al OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tMalregistri gvim de OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tRuli per grafika interfaco (kiel \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f aŭ --nofork\tMalfono: ne forki kiam lanĉas grafikan interfacon"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tNe uzi newcli por malfermi fenestrojn"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <aparatdosiero>\t\tUzi <aparatdosiero>-n por eneligo"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tUzi <gvimrc> anstataÅ­ iun ajn .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tRedakti ĉifradan dosieron"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <ekrano>\tKonekti Vim al tiu X-servilo"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tNe konekti al X-servilo"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <dosieroj>\tRedakti <dosieroj>-n en Vim-servilo se eblas"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <dosieroj> Same, sed ne plendi se ne estas servilo"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <dosieroj> Kiel --remote sed atendi Äis dosieroj estas "
-#~ "redaktitaj"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <dosieroj> Same, sed ne plendi se ne estas servilo"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <dosieroj> Kiel --remote sed uzi langeton "
-#~ "por ĉiu dosiero"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <klavoj> Sendi <klavoj>-n al Vim-servilo kaj eliri"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <espr>\tKomputi <espr> en Vim-servilo kaj afiÅi rezulton"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tListigi haveblajn nomojn de Vim-serviloj kaj eliri"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <nomo>\tSendu al/iÄi la Vim-servilo <nomo>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumentoj agnoskitaj de gvim (versio Motif):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumentoj agnoskitaj de gvim (versio neXtaw):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumentoj agnoskitaj de gvim (versio Athena):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <ekrano>\tLanĉi vim sur <ekrano>"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tLanĉi vim piktograme"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr ""
-#~ "-background <koloro>\tUzi <koloro>-n por la fona koloro (ankaÅ­: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <koloro>\tUzi <koloro>-n por la malfona koloro (ankaÅ­: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <tiparo>\tUzi <tiparo>-n por normala teksto (ankaÅ­: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <tiparo>\tUzi <tiparo>-n por grasa teksto"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <tiparo>\tUzi <tiparo>-n por kursiva teksto"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\tUzi <geom> kiel komenca geometrio (ankaÅ­: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr ""
-#~ "-borderwidth <larÄo>\tUzi <larÄo>-n kiel larÄo de bordero (ankaÅ­: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <larÄo> Uzi <larÄo>-n kiel larÄo de rulumskalo (ankaÅ­: -"
-#~ "sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <alto>\tUzi <alto>-n kiel alto de menuzona alto (ankaÅ­: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tUzi inversan videon (ankaÅ­: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tNe uzi inversan videon (ankaÅ­: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <rimedo>\tAgordi la specifitan <rimedo>-n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumentoj agnoskitaj de gvim (versio GTK+):\n"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Ne eblas trovi dosieron \"%s\" en serĉvojo"
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <ekrano>\tLanĉi Vim sur tiu <ekrano> (ankaŭ: --display)"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: Nevalida ID: %ld (devas esti egala aÅ­ pli granda ol 1)"
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <rolo>\tDoni unikan rolon por identigi la ĉefan fenestron"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID jam uzata: %ld"
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tMalfermi Vim en alia GTK fenestraĵo"
+msgid "List or number required"
+msgstr "Listo aÅ­ nombro bezonata"
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tIgas gvim afiÅi la identigilon de vindozo sur stdout"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: Nevalida ID: %ld (devas esti egala aÅ­ pli granda ol 1)"
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <gepatra titolo>\tMalfermi Vim en gepatra aplikaĵo"
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID netrovita: %ld"
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tMalfermi Vim en alia win32 fenestraĵo"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Ne eblis Åargi bibliotekon %s"
-#~ msgid "No display"
-#~ msgstr "Neniu ekrano"
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Perl ne Åargeblis."
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Sendo fiaskis.\n"
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: Plenumo de Perl esprimoj malpermesata en sabloludejo sen la modulo Safe"
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Sendo fiaskis. Provo de loka plenumo\n"
+msgid "Edit with &multiple Vims"
+msgstr "Redakti per &pluraj Vim-oj"
-#~ msgid "%d of %d edited"
-#~ msgstr "%d de %d redaktita(j)"
+msgid "Edit with single &Vim"
+msgstr "Redakti per unuopa &Vim"
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Neniu ekrano: Sendado de esprimo fiaskis.\n"
+msgid "Diff with Vim"
+msgstr "Kompari per Vim"
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Sendado de esprimo fiaskis.\n"
+msgid "Edit with &Vim"
+msgstr "Redakti per &Vim"
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Nevalida kodpaÄo"
+msgid "Edit with existing Vim - "
+msgstr "Redakti per ekzistanta Vim - "
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: Ne eblas agordi valorojn de IC"
+msgid "Edits the selected file(s) with Vim"
+msgstr "Redakti la apartigita(j)n dosiero(j)n per Vim"
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Ne eblis krei enigan kuntekston"
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "Eraro dum kreo de procezo: Kontrolu ĉu gvim estas en via serĉvojo!"
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Ne eblis malfermi enigan metodon"
+msgid "gvimext.dll error"
+msgstr "Eraro de gvimext.dll"
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: Averto: Ne eblis agordi detruan reagfunkcion al IM"
+msgid "Path length too long!"
+msgstr "Serĉvojo estas tro longa!"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: eniga metodo subtenas neniun stilon"
+msgid "--No lines in buffer--"
+msgstr "--Neniu linio en bufro--"
-# DP: mi ne scias, kio estas "preedit"
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: eniga metodo ne subtenas mian antaÅ­redaktan tipon"
-
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: Eraro dum Äisdatigo de ĉifrada permutodosiero .swp"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s estas ĉifrata kaj tiu versio de Vim ne subtenas ĉifradon"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Perumutodosiero .swp estas ĉifrata: \"%s\""
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "Se vi tajpis novan Ålosilon de ĉifrado sed ne skribis la tekstan dosieron,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "tajpu la novan Ålosilon de ĉifrado."
+msgid "E470: Command aborted"
+msgstr "E470: komando ĉesigita"
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "Se vi skribis la tekstan dosieron post ÅanÄo de la Ålosilo de ĉifrado, "
-#~ "premu enenklavon"
+msgid "E471: Argument required"
+msgstr "E471: Argumento bezonata"
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "por uzi la saman Ålosilon por la teksta dosiero kaj permuto dosiero .swp"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ devus esti sekvita de /, ? aÅ­ &"
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr ""
-#~ "Uzas Ålosilon de ĉifrado el permuto dosiero .swp por la teksta dosiero.\n"
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Nevalida en fenestro de komanda linio; <CR> plenumas, CTRL-C eliras"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [ne uzebla per tiu versio de Vim]"
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Nepermesebla komando el exrc/vimrc en aktuala dosierujo aŭ etikeda serĉo"
-#~ msgid "Tear off this menu"
-#~ msgstr "Disigi tiun menuon"
+msgid "E171: Missing :endif"
+msgstr "E171: Mankas \":endif\""
-#~ msgid "Select Directory dialog"
-#~ msgstr "Dialogujo de dosiera elekto"
+msgid "E600: Missing :endtry"
+msgstr "E600: Mankas \":endtry\""
-#~ msgid "Save File dialog"
-#~ msgstr "Dialogujo de dosiera konservo"
+msgid "E170: Missing :endwhile"
+msgstr "E170: Mankas \":endwhile\""
-#~ msgid "Open File dialog"
-#~ msgstr "Dialogujo de dosiera malfermo"
+msgid "E170: Missing :endfor"
+msgstr "E170: Mankas \":endfor\""
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: BedaÅ­rinde ne estas dosierfoliumilo en konzola reÄimo"
+msgid "E588: :endwhile without :while"
+msgstr "E588: \":endwhile\" sen \":while\""
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: konservo de dosieroj...\n"
+msgid "E588: :endfor without :for"
+msgstr "E588: \":endfor\" sen \":for\""
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: Finita.\n"
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Dosiero ekzistas (aldonu ! por transpasi)"
-#~ msgid "ERROR: "
-#~ msgstr "ERARO: "
+msgid "E472: Command failed"
+msgstr "E472: La komando malsukcesis"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[bajtoj] totalaj disponigitaj/maldisponigitaj %<PRIu64>-%<PRIu64>, nun "
-#~ "uzataj %<PRIu64>, kulmina uzo %<PRIu64>\n"
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Nekonata familio de tiparo: %s"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[alvokoj] totalaj re/malloc() %<PRIu64>, totalaj free() %<PRIu64>\n"
-#~ "\n"
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Nekonata tiparo: %s"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Linio iÄas tro longa"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: La tiparo \"%s\" ne estas egallarÄa"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Interna eraro: lalloc(%<PRId64>, )"
+msgid "E473: Internal error"
+msgstr "E473: Interna eraro"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Nevalida formo de muskursoro"
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Interna eraro: %s"
-#~ msgid "Enter encryption key: "
-#~ msgstr "Tajpu la Ålosilon de ĉifrado: "
+msgid "Interrupted"
+msgstr "Interrompita"
-#~ msgid "Enter same key again: "
-#~ msgstr "Tajpu la Ålosilon denove: "
+msgid "E14: Invalid address"
+msgstr "E14: Nevalida adreso"
-#~ msgid "Keys don't match!"
-#~ msgstr "Åœlosiloj ne kongruas!"
+msgid "E474: Invalid argument"
+msgstr "E474: Nevalida argumento"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Ne eblas konekti al Netbeans n-ro 2"
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Nevalida argumento: %s"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Ne eblas konekti al Netbeans"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Nevalida esprimo: %s"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Nevalida permeso de dosiero de informo de konekto NetBeans: \"%s\""
+msgid "E16: Invalid range"
+msgstr "E16: Nevalida amplekso"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "lego el kontaktoskatolo de Netbeans"
+msgid "E476: Invalid command"
+msgstr "E476: Nevalida komando"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Konekto de NetBeans perdita por bufro %<PRId64>"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" estas dosierujo"
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: netbeans ne estas subtenata kun tiu grafika interfaco"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Alvoko al biblioteko malsukcesis por \"%s()\""
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: nebeans jam konektata"
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Ne eblis Åargi bibliotekan funkcion %s"
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s estas nurlegebla (aldonu ! por transpasi)"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Marko havas nevalidan numeron de linio"
-# DP: ĉu Eval devas esti tradukita?
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Eval eblo ne disponeblas"
+msgid "E20: Mark not set"
+msgstr "E20: Marko ne estas agordita"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "malokupas %<PRId64> liniojn"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Ne eblas fari ÅanÄojn, 'modifiable' estas malÅaltita"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: term ne ÅanÄeblas en grafika interfaco"
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Tro profunde ingitaj skriptoj"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Uzu \":gui\" por lanĉi la grafikan interfacon"
+msgid "E23: No alternate file"
+msgstr "E23: Neniu alterna dosiero"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Ne ÅanÄeblas en la grafika interfaco GTK+ 2"
+msgid "E24: No such abbreviation"
+msgstr "E24: Ne estas tia mallongigo"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Nevalida(j) tiparo(j)"
+msgid "E477: No ! allowed"
+msgstr "E477: Neniu ! permesebla"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ne eblas elekti tiparon"
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Grafika interfaco ne uzeblas: MalÅaltita dum kompilado"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Nevalida tiparo"
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: La hebrea ne uzeblas: MalÅaltita dum kompilado\n"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ne eblas elekti larÄan tiparon"
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: La persa ne uzeblas: MalÅaltita dum kompilado\n"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Nevalida larÄa tiparo"
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: La araba ne uzeblas: MalÅaltita dum kompilado\n"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Neniu muso subtenata"
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Neniu grupo de emfazo kiel: %s"
-#~ msgid "cannot open "
-#~ msgstr "ne eblas malfermi "
+msgid "E29: No inserted text yet"
+msgstr "E29: AnkoraÅ­ neniu enmetita teksto"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Ne eblas malfermi fenestron!\n"
+msgid "E30: No previous command line"
+msgstr "E30: Neniu antaÅ­a komanda linio"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Bezonas version 2.04 de Amigados aÅ­ pli novan\n"
+msgid "E31: No such mapping"
+msgstr "E31: Neniu tiel mapo"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Bezonas %s-on versio %<PRId64>\n"
+msgid "E479: No match"
+msgstr "E479: Neniu kongruo"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Ne eblas malfermi NIL:\n"
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Neniu kongruo: %s"
-#~ msgid "Cannot create "
-#~ msgstr "Ne eblas krei "
+msgid "E32: No file name"
+msgstr "E32: Neniu dosiernomo"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim eliras kun %d\n"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Neniu antaÅ­a regulesprimo de anstataÅ­igo"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "ne eblas ÅanÄi reÄimon de konzolo?!\n"
+msgid "E34: No previous command"
+msgstr "E34: Neniu antaÅ­a komando"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ne estas konzolo??\n"
+msgid "E35: No previous regular expression"
+msgstr "E35: Neniu antaÅ­a regulesprimo"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Ne eblas plenumi Åelon kun opcio -f"
+msgid "E481: No range allowed"
+msgstr "E481: Amplekso nepermesebla"
-#~ msgid "Cannot execute "
-#~ msgstr "Ne eblas plenumi "
+msgid "E36: Not enough room"
+msgstr "E36: Ne sufiĉe da spaco"
-#~ msgid "shell "
-#~ msgstr "Åelo "
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: neniu registrita servilo nomita \"%s\""
-#~ msgid " returned\n"
-#~ msgstr " liveris\n"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Ne eblas krei dosieron %s"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE tro malgranda."
+msgid "E483: Can't get temp file name"
+msgstr "E483: Ne eblas akiri provizoran dosiernomon"
-#~ msgid "I/O ERROR"
-#~ msgstr "ERARO DE ENIGO/ELIGO"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Ne eblas malfermi dosieron %s"
-#~ msgid "Message"
-#~ msgstr "MesaÄo"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Ne eblas legi dosieron %s"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ne estas 80, ne eblas plenumi eksternajn komandojn"
+msgid "E38: Null argument"
+msgstr "E38: Nula argumento"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Elekto de presilo fiaskis"
+msgid "E39: Number expected"
+msgstr "E39: Nombro atendita"
-#~ msgid "to %s on %s"
-#~ msgstr "al %s de %s"
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Ne eblas malfermi eraran dosieron %s"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Nekonata tiparo de presilo: %s"
+msgid "E233: cannot open display"
+msgstr "E233: ne eblas malfermi vidigon"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Eraro de presado: %s"
+msgid "E41: Out of memory!"
+msgstr "E41: Ne plu restas memoro!"
-#~ msgid "Printing '%s'"
-#~ msgstr "Presas '%s'"
+msgid "Pattern not found"
+msgstr "Åœablono ne trovita"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: Nevalida nomo de signaro \"%s\" en nomo de tiparo \"%s\""
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Åœablono ne trovita: %s"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Nevalida signo '%c' en nomo de tiparo \"%s\""
+msgid "E487: Argument must be positive"
+msgstr "E487: La argumento devas esti pozitiva"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Duobla signalo, eliranta\n"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Ne eblas reiri al antaÅ­a dosierujo"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Kaptis mortigantan signalon %s\n"
+msgid "E42: No Errors"
+msgstr "E42: Neniu eraro"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Kaptis mortigantan signalon\n"
+msgid "E776: No location list"
+msgstr "E776: Neniu listo de lokoj"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Malfermo de vidigo X daÅ­ris %<PRId64> msek"
+msgid "E43: Damaged match string"
+msgstr "E43: Difekta kongruenda ĉeno"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Alvenis X eraro\n"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Difekta programo de regulesprimo"
-#~ msgid "Testing the X display failed"
-#~ msgstr "Testo de la vidigo X fiaskis"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: La opcio 'readonly' estas Åaltita '(aldonu ! por transpasi)"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Tempolimo okazis dum malfermo de vidigo X"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Ne eblas ÅanÄi nurlegeblan variablon \"%s\""
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ne eblas plenumi Åelon sh\n"
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Ne eblas agordi variablon en la sabloludejo: \"%s\""
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ne eblas krei duktojn\n"
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ne eblas uzi malplenan Ålosilon de Vortaro"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ne eblas forki\n"
+msgid "E715: Dictionary required"
+msgstr "E715: Vortaro bezonata"
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Komando terminigita\n"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: indekso de listo ekster limoj: %ld"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP perdis la konekton ICE"
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Tro da argumentoj por funkcio: %s"
-#~ msgid "Opening the X display failed"
-#~ msgstr "Malfermo de vidigo X fiaskis"
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Åœlosilo malekzistas en Vortaro: %s"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP: traktado de peto konservi-mem"
+msgid "E714: List required"
+msgstr "E714: Listo bezonata"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP: malfermo de konekto"
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Argumento de %s devas esti Listo aÅ­ Vortaro"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP: kontrolo de konekto ICE fiaskis"
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Eraro dum legado de erardosiero"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP: SmcOpenConnection fiaskis: %s"
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Nepermesebla en sabloludejo"
-#~ msgid "At line"
-#~ msgstr "Ĉe linio"
+msgid "E523: Not allowed here"
+msgstr "E523: Nepermesebla tie"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Ne eblis Åargi vim32.dll!"
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: ReÄimo de ekrano ne subtenata"
-#~ msgid "VIM Error"
-#~ msgstr "Eraro de VIM"
+msgid "E49: Invalid scroll size"
+msgstr "E49: Nevalida grando de rulumo"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Ne eblis ripari referencojn de funkcioj al la DLL!"
+msgid "E91: 'shell' option is empty"
+msgstr "E91: La opcio 'shell' estas malplena"
-#~ msgid "shell returned %d"
-#~ msgstr "la Åelo liveris %d"
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Ne eblis legi datumojn de simboloj!"
-# DP: la eventoj estas tiuj, kiuj estas en la sekvantaj ĉenoj
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Kaptis eventon %s\n"
+msgid "E72: Close error on swap file"
+msgstr "E72: Eraro dum malfermo de permutodosiero .swp"
-#~ msgid "close"
-#~ msgstr "fermo"
+msgid "E73: tag stack empty"
+msgstr "E73: malplena stako de etikedo"
-#~ msgid "logoff"
-#~ msgstr "elsaluto"
+msgid "E74: Command too complex"
+msgstr "E74: Komando tro kompleksa"
-#~ msgid "shutdown"
-#~ msgstr "sistemfermo"
+msgid "E75: Name too long"
+msgstr "E75: Nomo tro longa"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Netrovebla komando"
+msgid "E76: Too many ["
+msgstr "E76: Tro da ["
-#~ 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 ""
-#~ "VIMRUN.EXE ne troveblas en via $PATH.\n"
-#~ "Eksteraj komandoj ne paÅ­zos post kompletigo.\n"
-#~ "Vidu :help win32-vimrun por pliaj informoj."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Averto de Vim"
-
-#~ msgid "Error file"
-#~ msgstr "Erara Dosiero"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: Eraro dum prekomputado de NFA kun ekvivalentoklaso!"
-
-#~ msgid "E999: (NFA regexp internal error) Should not process NOT node !"
-#~ msgstr ""
-#~ "E999: (interna eraro de NFA-regulesprimo) Ne devus procezi nodon 'NOT'!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) Ne povis asigni memoron por traigi branĉojn!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr "Averto: Ne eblas trovi vortliston \"%s_%s.spl\" aÅ­ \"%s_ascii.spl\""
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Konverto en %s nesubtenata"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: Ne sufiĉe da memoro, vortlisto estos nekompleta."
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Vojo de etikeda dosiero trunkita por %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "nova Åelo lanĉita\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "Uzis CUT_BUFFER0 anstataÅ­ malplenan apartigon"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Malfaro neebla; daÅ­rigi tamene"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Ne ĉifrata dosiero havas ĉifratan malfaran dosieron: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Malĉifrado de malfara dosiero fiaskis: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Malfara dosiero estas ĉifrata: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Grafika versio MS-Vindozo 16/32-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Grafika versio MS-Vindozo 64-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Grafika versio MS-Vindozo 32-bitoj"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " en reÄimo Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " kun subteno de OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio konzola MS-Vindozo 64-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio konzola MS-Vindozo 32-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio MS-Vindozo 16-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio MS-DOS 32-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio MS-DOS 16-bitoj"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio Mak OS X (unikso)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio Mak OS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio Mak OS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Versio OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Granda versio "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Normala versio "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Malgranda versio "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Malgrandega versio "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "kun grafika interfaco GTK2-GNOME."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "kun grafika interfaco GTK2."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "kun grafika interfaco X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "kun grafika interfaco X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "kun grafika interfaco X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "kun grafika interfaco Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "sen grafika interfaco."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "kun grafika interfaco Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "kun grafika interfaco Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "kun (klasika) grafika interfaco."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " sistema dosiero gvimrc: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " dosiero gvimrc de uzanto: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " 2-a dosiero gvimrc de uzanto: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " 3-a dosiero gvimrc de uzanto: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " dosiero de sistema menuo: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Kompililo: "
+msgid "E77: Too many file names"
+msgstr "E77: Tro da dosiernomoj"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "menuo Help->Orfinoj por pliaj informoj "
+msgid "E488: Trailing characters"
+msgstr "E488: Vostaj signoj"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "RuliÄas senreÄime, tajpita teksto estas enmetita"
+msgid "E78: Unknown mark"
+msgstr "E78: Nekonata marko"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi Enmetan ReÄimon"
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Ne eblas malvolvi ĵokerojn"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid " for two modes "
-#~ msgstr " por du reÄimoj "
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' ne rajtas esti malpli ol 'winminheight'"
-# DP: tiu ĉeno pli longas (mi ne volas igi ĉiujn aliajn ĉenojn
-# pli longajn)
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "menuo Redakti->Mallokaj Agordoj->Baskuligi ReÄimon Kongruan kun Vi"
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' ne rajtas esti malpli ol 'winminwidth'"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid " for Vim defaults "
-#~ msgstr " por defaÅ­ltoj de Vim "
+msgid "E80: Error while writing"
+msgstr "E80: Eraro dum skribado"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "AVERTO: Trovis Vindozon 95/98/ME"
+msgid "E939: Positive count required"
+msgstr "E939: Pozitiva kvantoro bezonata"
-# DP: atentu al la spacetoj: ĉiuj ĉenoj devas havi la saman longon
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "tajpu :help windows95<Enenklavo> por pliaj informoj "
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: Uzo de <SID> ekster kunteksto de skripto"
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Ne eblis Åargi bibliotekon %s"
+msgid "E449: Invalid expression received"
+msgstr "E449: Nevalida esprimo ricevita"
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "BedaÅ­rinde tiu komando estas malÅaltita: la biblioteko de Perl ne "
-#~ "Åargeblis."
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Regiono estas gardita, ne eblas ÅanÄi"
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Plenumo de Perl esprimoj malpermesata en sabloludejo sen la modulo "
-#~ "Safe"
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ne permesas ÅanÄojn en nurlegeblaj dosieroj"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Redakti per &pluraj Vim-oj"
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: Åablono uzas pli da memoro ol 'maxmempattern'"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Redakti per unuopa &Vim"
+msgid "E749: empty buffer"
+msgstr "E749: malplena bufro"
-#~ msgid "Diff with Vim"
-#~ msgstr "Kompari per Vim"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: La bufro %ld ne ekzistas"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Redakti per &Vim"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Nevalida serĉa Åablono aÅ­ disigilo"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Redakti per ekzistanta Vim - "
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Dosiero estas Åargita en alia bufro"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Redakti la apartigita(j)n dosiero(j)n per Vim"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: La opcio '%s' ne estas Åaltita"
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "Eraro dum kreo de procezo: Kontrolu ĉu gvim estas en via serĉvojo!"
+msgid "E850: Invalid register name"
+msgstr "E850: Nevalida nomo de reÄistro"
-#~ msgid "gvimext.dll error"
-#~ msgstr "Eraro de gvimext.dll"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Dosierujo ne trovita en '%s': \"%s\""
-#~ msgid "Path length too long!"
-#~ msgstr "Serĉvojo estas tro longa!"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "serĉo atingis SUPRON, daŭrigonte al SUBO"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Nekonata familio de tiparo: %s"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "serĉo atingis SUBON, daŭrigonte al SUPRO"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Nekonata tiparo: %s"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Ŝlosilo de ĉifrado bezonata por \"%s\""
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: La tiparo \"%s\" ne estas egallarÄa"
+msgid "empty keys are not allowed"
+msgstr "malplenaj Ålosiloj nepermeseblaj"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Ne eblis Åargi bibliotekan funkcion %s"
+msgid "dictionary is locked"
+msgstr "vortaro estas Ålosita"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: La hebrea ne uzeblas: MalÅaltita dum kompilado\n"
+msgid "list is locked"
+msgstr "listo estas Ålosita"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: La persa ne uzeblas: MalÅaltita dum kompilado\n"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "aldono de Ålosilo '%s' al vortaro malsukcesis"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: La araba ne uzeblas: MalÅaltita dum kompilado\n"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "indekso devas esti 'int' aÅ­ 'slice', ne %s"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: neniu registrita servilo nomita \"%s\""
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "atendis aperon de str() aÅ­ unicode(), sed ricevis %s"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ne eblas malfermi vidigon"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "atendis aperon de bytes() aÅ­ str(), sed ricevis %s"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Nevalida esprimo ricevita"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr "atendis int(), long() aÅ­ ion konverteblan al long(), sed ricevis %s"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Regiono estas gardita, ne eblas ÅanÄi"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr "atendis int() aÅ­ ion konverteblan al int(), sed ricevis %s"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ne permesas ÅanÄojn en nurlegeblaj dosieroj"
+msgid "value is too large to fit into C int type"
+msgstr "valoro estas tro grada por C-tipo 'int'"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Ŝlosilo de ĉifrado bezonata por \"%s\""
+msgid "value is too small to fit into C int type"
+msgstr "valoro estas tro malgranda por C-tipo 'int'"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "ne eblas forviÅi atributojn de OutputObject"
+msgid "number must be greater than zero"
+msgstr "nombro devas esti pli granda ol nul"
-#~ msgid "softspace must be an integer"
-#~ msgstr "malmolspaceto (softspace) devas esti entjero"
+msgid "number must be greater or equal to zero"
+msgstr "nombro devas esti egala aÅ­ pli granda ol nul"
-#~ msgid "invalid attribute"
-#~ msgstr "nevalida atributo"
+msgid "can't delete OutputObject attributes"
+msgstr "ne eblas forviÅi atributojn de OutputObject"
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines() bezonas liston de ĉenoj"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "nevalida atributo: %s"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Pitono: Eraro de pravalorizo de eneligaj objektoj"
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Pitono: Eraro de pravalorizo de eneligaj objektoj"
-#~ msgid "empty keys are not allowed"
-#~ msgstr "malplenaj Ålosiloj nepermeseblaj"
+msgid "failed to change directory"
+msgstr "malsukcesis ÅanÄi dosierujon"
-#~ msgid "Cannot delete DictionaryObject attributes"
-#~ msgstr "ne eblas forviÅi atributojn de DictionaryObject"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "atendis 3-opon kiel rezulto de imp.find_module(), sed ricevis %s"
-#~ msgid "Cannot modify fixed dictionary"
-#~ msgstr "Ne eblas ÅanÄi fiksan vortaron"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "atendis 3-opon kiel rezulto de imp.find_module(), sed ricevis %d-opon"
-#~ msgid "Cannot set this attribute"
-#~ msgstr "Ne eblas agordi tiun atributon"
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "interna eraro: imp.find_module liveris opon kun NULL"
-#~ msgid "dict is locked"
-#~ msgstr "vortaro estas Ålosita"
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "ne eblas forviÅi atributojn de 'vim.Dictionary'"
-#~ msgid "failed to add key to dictionary"
-#~ msgstr "aldono de Ålosilo al vortaro fiaskis"
+msgid "cannot modify fixed dictionary"
+msgstr "ne eblas ÅanÄi fiksan vortaron"
-#~ msgid "list index out of range"
-#~ msgstr "indekso de listo ekster limoj"
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "ne eblas agordi atributon %s"
-#~ msgid "internal error: failed to get vim list item"
-#~ msgstr "interna eraro: obteno de vim-a listero fiaskis"
+msgid "hashtab changed during iteration"
+msgstr "hakettabelo ÅanÄiÄis dum iteracio"
-#~ msgid "list is locked"
-#~ msgstr "listo estas Ålosita"
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "atendis 2-longan sekvencon, sed ricevis %d-longan sekvencon"
-#~ msgid "Failed to add item to list"
-#~ msgstr "Aldono de listero fiaskis"
+msgid "list constructor does not accept keyword arguments"
+msgstr "konstruilo de listo ne akceptas Ålosilvortajn argumentojn"
-#~ msgid "can only assign lists to slice"
-#~ msgstr "nur eblas pravalorizi listojn al segmento"
+msgid "list index out of range"
+msgstr "indekso de listo ekster limoj"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "interna eraro: aldono de listero fiaskis"
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "interna eraro: obteno de vim-a listero %d malsukcesis"
-#~ msgid "can only concatenate with lists"
-#~ msgstr "eblas nur kunmeti kun listoj"
+msgid "slice step cannot be zero"
+msgstr "paÅo de sekco ne povas esti nul"
-#~ msgid "cannot delete vim.dictionary attributes"
-#~ msgstr "ne eblas forviÅi atributojn de 'vim.dictionary'"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "provis valorizi sekvencon kun pli ol %d eroj en etendita sekco"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "ne eblas ÅanÄi fiksan liston"
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "interna eraro: neniu vim-a listero %d"
-#~ msgid "cannot set this attribute"
-#~ msgstr "ne eblas agordi tiun atributon"
+msgid "internal error: not enough list items"
+msgstr "interna eraro: ne sufiĉaj listeroj"
-#~ msgid "'self' argument must be a dictionary"
-#~ msgstr "argumento 'self' devas esti vortaro"
+msgid "internal error: failed to add item to list"
+msgstr "interna eraro: aldono de listero malsukcesis"
-#~ msgid "failed to run function"
-#~ msgstr "fiaskis ruli funkcion"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr "provis valorizi sekvencon kun %d eroj al etendita sekco kun %d eroj"
-#~ msgid "unable to unset global option"
-#~ msgstr "ne povis malÅalti mallokan opcion"
+msgid "failed to add item to list"
+msgstr "aldono de listero malsukcesis"
-#~ msgid "unable to unset option without global value"
-#~ msgstr "ne povis malÅalti opcion sen malloka valoro"
+msgid "cannot delete vim.List attributes"
+msgstr "ne eblas forviÅi atributojn de 'vim.List'"
-#~ msgid "object must be integer"
-#~ msgstr "objekto devas esti entjero."
+msgid "cannot modify fixed list"
+msgstr "ne eblas ÅanÄi fiksan liston"
-#~ msgid "object must be string"
-#~ msgstr "objekto devas esti ĉeno"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "sennoma funkcio %s ne ekzistas"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "provo de referenco al forviÅita langeto"
+#, c-format
+msgid "function %s does not exist"
+msgstr "funkcio %s ne ekzistas"
-#~ msgid "<tabpage object (deleted) at %p>"
-#~ msgstr "<langeta objekto (forviÅita) ĉe %p>"
+#, c-format
+msgid "failed to run function %s"
+msgstr "malsukcesis ruli funkcion %s"
-#~ msgid "<tabpage object (unknown) at %p>"
-#~ msgstr "<langeta objekto (nekonata) ĉe %p>"
+msgid "unable to get option value"
+msgstr "malsukcesis akiri valoron de opcio"
-#~ msgid "<tabpage %d>"
-#~ msgstr "<langeto %d>"
+msgid "internal error: unknown option type"
+msgstr "interna eraro: nekonata tipo de opcio"
-#~ msgid "no such tab page"
-#~ msgstr "ne estas tia langeto"
+msgid "problem while switching windows"
+msgstr "problemo dum salto al vindozoj"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "provo de referenco al forviÅita fenestro"
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "ne povis malÅalti mallokan opcion %s"
-#~ msgid "readonly attribute"
-#~ msgstr "nurlegebla atributo"
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "ne povis malÅalti opcion %s, kiu ne havas mallokan valoron"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "kursoro poziciita ekster bufro"
+msgid "attempt to refer to deleted tab page"
+msgstr "provo de referenco al forviÅita langeto"
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<fenestra objekto (forviÅita) ĉe %p>"
+msgid "no such tab page"
+msgstr "ne estas tia langeto"
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<objekta fenestro (nekonata) ĉe %p>"
+msgid "attempt to refer to deleted window"
+msgstr "provo de referenco al forviÅita fenestro"
-#~ msgid "<window %d>"
-#~ msgstr "<fenestro %d>"
+msgid "readonly attribute: buffer"
+msgstr "nurlegebla atributo: buffer"
-#~ msgid "no such window"
-#~ msgstr "ne estas tia fenestro"
+msgid "cursor position outside buffer"
+msgstr "kursoro poziciita ekster bufro"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "provo de referenco al forviÅita bufro"
+msgid "no such window"
+msgstr "ne estas tia fenestro"
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<bufra objekto (forviÅita) ĉe %p>"
+msgid "attempt to refer to deleted buffer"
+msgstr "provo de referenco al forviÅita bufro"
-#~ msgid "key must be integer"
-#~ msgstr "Ålosilo devas esti entjero."
+msgid "failed to rename buffer"
+msgstr "malsukcesis renomi bufron"
-#~ msgid "expected vim.buffer object"
-#~ msgstr "atendis objekton vim.buffer"
+msgid "mark name must be a single character"
+msgstr "nomo de marko devas esti unuopa signo"
-#~ msgid "failed to switch to given buffer"
-#~ msgstr "ne povis salti al la specifita bufro"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "atendis objekton vim.Buffer, sed ricevis %s"
-#~ msgid "expected vim.window object"
-#~ msgstr "atendis objekton vim.window"
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "salto al la bufro %d malsukcesis"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "ne povis trovi vindozon en la nuna langeto"
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "atendis objekton vim.window, sed ricevis %s"
-#~ msgid "did not switch to the specified window"
-#~ msgstr "ne saltis al la specifita vindozo"
+msgid "failed to find window in the current tab page"
+msgstr "malsukcesis trovi vindozon en la nuna langeto"
-#~ msgid "expected vim.tabpage object"
-#~ msgstr "atendis objekton vim.tabpage"
+msgid "did not switch to the specified window"
+msgstr "ne saltis al la specifita vindozo"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "ne saltis al la specifita langeto"
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "atendis objekton vim.TabPage, sed ricevis %s"
-#~ msgid "failed to run the code"
-#~ msgstr "fiaskis ruli la kodon"
+msgid "did not switch to the specified tab page"
+msgstr "ne saltis al la specifita langeto"
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: Eval ne revenis kun valida python-objekto"
+msgid "failed to run the code"
+msgstr "malsukcesis ruli la kodon"
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: Konverto de revena python-objekto al vim-valoro fiaskis"
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval ne revenis kun valida python-objekto"
-#~ msgid "unable to convert to vim structure"
-#~ msgstr "ne povis konverti al vim-strukturo"
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Konverto de revena python-objekto al vim-valoro malsukcesis"
-#~ msgid "NULL reference passed"
-#~ msgstr "NULL-referenco argumento"
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "ne povis konverti %s al vim-vortaro"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "interna eraro: nevalida tipo de valoro"
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "ne povis konverti %s al vim-listo"
-#~ msgid "E863: return value must be an instance of str"
-#~ msgstr "E863: elira valoro devas esti apero de str"
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "ne povis konverti %s al vim-strukturo"
-#~ msgid "E860: Eval did not return a valid python 3 object"
-#~ msgstr "E860: Eval ne revenis kun valida python3-objekto"
+msgid "internal error: NULL reference passed"
+msgstr "interna eraro: NULL-referenco argumento"
-#~ msgid "E861: Failed to convert returned python 3 object to vim value"
-#~ msgstr "E861: Konverto de revena python3-objekto al vim-valoro fiaskis"
+msgid "internal error: invalid value type"
+msgstr "interna eraro: nevalida tipo de valoro"
-#~ msgid "Only boolean objects are allowed"
-#~ msgstr "Nur buleaj objektoj estas permeseblaj"
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"Valorizo de sys.path_hooks malsukcesis: sys.path_hooks ne estas listo\n"
+"Vi nun devas fari tion:\n"
+"- postaldoni vim.path_hook al sys.path_hooks\n"
+"- postaldoni vim.VIM_SPECIAL_PATH al sys.path\n"
-#~ msgid "no such key in dictionary"
-#~ msgstr "tiu Ålosilo ne ekzistas en vortaro"
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"Agordo de serĉvojo malsukcesis: sys.path ne estas listo\n"
+"Vi nun devas aldoni vim.VIM_SPECIAL_PATH al sys.path"
diff --git a/src/nvim/po/es.po b/src/nvim/po/es.po
index 8a9c86e88d..f30e8780f9 100644
--- a/src/nvim/po/es.po
+++ b/src/nvim/po/es.po
@@ -1197,7 +1197,7 @@ msgstr "E141: No existe un nombre de archivo para el búfer %<PRId64>"
#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr ""
-"E142: No se ha escrito el archivo: escritura desactivada por \n"
+"E142: No se ha escrito el archivo: escritura desactivada por "
"la opción 'write'"
#: ../ex_cmds.c:2434
@@ -2209,7 +2209,7 @@ msgstr "es de solo lectura (añada ! para sobreescribir)"
#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr ""
-"E506: No se pudo escribir en el archivo de recuperación\n"
+"E506: No se pudo escribir en el archivo de recuperación "
"(añada ! para forzar la orden)"
#: ../fileio.c:2898
@@ -2525,7 +2525,7 @@ msgstr "E216: No existe tal grupo o evento: %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Auto-órdenes ---"
@@ -2549,7 +2549,7 @@ msgstr "E218: La auto-orden se anida en exceso"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Auto-órdenes para \"%s\""
#: ../fileio.c:7149
@@ -2748,11 +2748,6 @@ msgstr "E49: La longitud de desplazamiento no es válida"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3141,7 +3136,7 @@ msgstr ""
#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr ""
-"E675: No se ha definido un tipo de letra predeterminado para impresión\n"
+"E675: No se ha definido un tipo de letra predeterminado para impresión "
"multi-byte"
#: ../hardcopy.c:2426
@@ -3398,7 +3393,7 @@ msgstr "Basura después de la opción"
#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr ""
-"Demasiados argumentos tales como: \"+orden\", \"-c orden\" \n"
+"Demasiados argumentos tales como: \"+orden\", \"-c orden\" "
"o \"--cmd orden\""
#: ../main.c:154
@@ -3469,7 +3464,7 @@ msgstr "-q [fich. err.] Editar el archivo con el primer error"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -3802,7 +3797,7 @@ msgstr "E302: No pude cambiar el nombre del archivo de intercambio"
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr ""
-"E303: Incapaz de abrir el archivo de intercambio para %s,\n"
+"E303: Incapaz de abrir el archivo de intercambio para %s, "
"recuperación imposible"
#: ../memline.c:666
@@ -3921,7 +3916,7 @@ msgstr "??? desde aquí hasta ???FIN las líneas pueden estar desordenadas"
#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr ""
-"??? desde aquí hasta ???FIN las líneas pueden haber sido\n"
+"??? desde aquí hasta ???FIN las líneas pueden haber sido "
"insertadas/borradas"
#: ../memline.c:1181
@@ -3936,7 +3931,7 @@ msgstr "E311: Recuperación interrumpida"
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
-"E312: Se han detectado errores al recuperar; busque líneas que\n"
+"E312: Se han detectado errores al recuperar; busque líneas que "
"empiecen con ???"
#: ../memline.c:1245
@@ -4377,12 +4372,6 @@ msgstr "línea %4ld"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Nombre de registro no válido: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr ""
-"Traducción: Proyecto vim-doc-es <http://www.assembla.com/wiki/show/vim-doc-"
-"es>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Interrupción: "
@@ -5393,7 +5382,7 @@ msgstr "E756: La corrección ortográfica está desactivada"
#, c-format
msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
msgstr ""
-"Advertencia: No se pudo hallar la lista de palabras \"%s.%s.spl\" \n"
+"Advertencia: No se pudo hallar la lista de palabras \"%s.%s.spl\" "
"or \"%s.ascii.spl\""
#: ../spell.c:2473
@@ -5424,7 +5413,7 @@ msgstr "Advertencia: la región %s no es compatible"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
+msgid "Reading affix file %s..."
msgstr "Leyendo el archivo de afijos \"%s\"..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
@@ -5454,8 +5443,7 @@ msgid ""
"%d"
msgstr ""
"Definir COMPOUNDFORBIDFLAG después de un elemento PFX puede dar resultados "
-"erróneos\n"
-"en %s línea %d"
+"erróneos en %s línea %d"
#: ../spell.c:4731
#, c-format
@@ -5464,8 +5452,7 @@ msgid ""
"%d"
msgstr ""
"Definir COMPOUNDPERMITFLAG después de un ítem PFX puede dar resultados "
-"erróneos\n"
-"en %s línea %d"
+"erróneos en %s línea %d"
#: ../spell.c:4747
#, c-format
@@ -5496,7 +5483,7 @@ msgstr "Valor equivocado de CHECKCOMPOUNDPATTERN en %s línea %d: %s"
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
-"Marca de combinación diferente en el bloque de afijos continuo\n"
+"Marca de combinación diferente en el bloque de afijos continuo "
"en %s línea %d: %s"
#: ../spell.c:4850
@@ -5511,8 +5498,7 @@ msgid ""
"line %d: %s"
msgstr ""
"Afijo usado también para BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
-"en\n"
-"%s línea %d: %s"
+"en %s línea %d: %s"
#: ../spell.c:4893
#, c-format
@@ -5592,8 +5578,8 @@ msgstr "El valor %s difiere de los que se usa en otro archivo .aff"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Leyendo el archivo de diccionario %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Leyendo el archivo de diccionario %s..."
#: ../spell.c:5611
#, c-format
@@ -5627,8 +5613,8 @@ msgstr "Ignorando %d palabra(s) con caracteres no-ASCII en %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Leyendo archivo de palabras \"%s\" ..."
+msgid "Reading word file %s..."
+msgstr "Leyendo archivo de palabras \"%s\"..."
#: ../spell.c:6155
#, c-format
@@ -5697,8 +5683,8 @@ msgstr "Número total de palabras: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Escribiendo el archivo de sugerencias %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "Escribiendo el archivo de sugerencias %s..."
#: ../spell.c:7707 ../spell.c:7927
#, c-format
@@ -5725,8 +5711,8 @@ msgstr "Advertencia: Se especificó \"compounding\" y NOBREAK"
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Escribiendo archivo de ortografía \"%s\" ..."
+msgid "Writing spell file %s..."
+msgstr "Escribiendo archivo de ortografía \"%s\"..."
#: ../spell.c:7925
msgid "Done!"
@@ -5953,7 +5939,7 @@ msgstr "E402: Basura después del patrón: %s"
#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr ""
-"E403: Sincronización de sintaxis: Se especificó dos veces un\n"
+"E403: Sincronización de sintaxis: Se especificó dos veces un "
"patrón de continuación de línea"
#: ../syntax.c:5169
@@ -6580,7 +6566,7 @@ msgstr "E813: No se puede cerrar la ventana de autocmd"
#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr ""
-"E814: No se pudo cerrar la última ventana, solo quedará\n"
+"E814: No se pudo cerrar la última ventana, solo quedará "
"la ventana de autocmd"
#: ../window.c:2717
diff --git a/src/nvim/po/fi.po b/src/nvim/po/fi.po
index d4082135aa..4612988c95 100644
--- a/src/nvim/po/fi.po
+++ b/src/nvim/po/fi.po
@@ -1,247 +1,417 @@
# Finnish translation for Vim.
# Copyright (C) 2003-2006 Free Software Foundation, Inc.
-# 2007-2010, Flammie Pirinen <flammie@iki.fi>
+# 2007-2018, Flammie Pirinen <flammie@iki.fi>
#
-# Vimin käyttäjät on nörttejä. Sanasto on jargonia :-p
-#
-# Lähinnä latin-1:tä, sillä vim pitää portata ilmeisen obskuureille
-# alustoille. Myös: pluralit puuttuu, ohjelman käyttöliittymän fontti
-# tasavälinen, tila rajattu, jne. jne., luovia ratkaisuja edessä.
+# Jargonia ei ole yritetty suotta kotoperäistää missä teknisempi lainasanasto
+# tulee paremmin kyseeseen.
#
# Sanastosta:
-# Fold on sellainen moderneissa ohjelmointi-IDE:issä oleva toiminto, jolla
-# lohko koodia esim. funktio piilotetaan näkymästä: suom. taitos alkup.
+# * Fold on sellainen moderneissa ohjelmointi-IDE:issä oleva toiminto, jolla
+# lohko koodia esim. funktio piilotetaan näkymästä: suom. taitos alkup.
# analogian mukaan
-# source v. lataa tiedoston, kuten bash-komento source (tai .)
+# * source, v. lataa tiedoston, kuten bash-komento source (tai .)
+# * dictionary (dict) on vaihtelevasti sanakirja tai tietorakenne
#
msgid ""
msgstr ""
"Project-Id-Version: Vim 7\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2010-08-09 02:35+0300\n"
-"Last-Translator: Flammie Pirinen <flammie@iki.fi>\n"
+"POT-Creation-Date: 2017-04-19 16:46+0200\n"
+"PO-Revision-Date: 2016-08-29 11:27+0200\n"
+"Last-Translator: Flammie A Pirinen <flammie@iki.fi>\n"
"Language-Team: Finnish <laatu@lokalisointi.org>\n"
"Language: fi\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: ../api/private/helpers.c:201
#, fuzzy
-msgid "Unable to get option value"
-msgstr "Roskaa argumentin perässä"
+#~ msgid "Index out of bounds"
+#~ msgstr "ei löytynyt "
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
+#, fuzzy
+#~ msgid "Line index is too high"
+#~ msgstr "ikkunan indeksi alueen ulkopuolella"
+
+#~ msgid "Argument \"start\" is higher than \"end\""
+#~ msgstr ""
+
+#~ msgid "All items in the replacement array must be strings"
+#~ msgstr ""
+
+msgid "string cannot contain newlines"
+msgstr "merkkijono ei saa sisältää rivinvaihtoja"
+
+#, fuzzy
+#~ msgid "Failed to save undo information"
+#~ msgstr "ei voitu tallentaa kumoustietoja"
+
+#, fuzzy
+#~ msgid "Failed to delete line"
+#~ msgstr "ei voitu poistaa riviä"
+
+#~ msgid "Index value is too high"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Failed to replace line"
+#~ msgstr "ei voitu korvata riviä"
+
+#, fuzzy
+#~ msgid "Failed to insert line"
+#~ msgstr "ei voitu lisätä riviä"
+
+#, fuzzy
+#~ msgid "Failed to rename buffer"
+#~ msgstr "ei voity uudelleennimetä puskuria"
+
+#, fuzzy
+#~ msgid "Mark name must be a single character"
+#~ msgstr "merkin nimen pitää olla yksi merkki"
+
+#, fuzzy
+#~ msgid "Invalid mark name"
+#~ msgstr "virheellinen merkin nimi"
+
+#, fuzzy
+#~ msgid "Line number outside range"
+#~ msgstr "rivinumero arvoalueen ulkopuolella"
+
+#, fuzzy
+#~ msgid "Column value outside range"
+#~ msgstr "rivinumero arvoalueen ulkopuolella"
+
+#, fuzzy
+#~ msgid "Keyboard interrupt"
+#~ msgstr "näppäimistökeskeytys"
+
+#, fuzzy
+#~ msgid "Key not found"
+#~ msgstr "ei löytynyt "
+
+#, fuzzy
+#~ msgid "Dictionary is locked"
+#~ msgstr "dictionary on lukittu"
+
+#, fuzzy
+#~ msgid "Empty variable names aren't allowed"
+#~ msgstr "tyhjiä avaimia ei voi käyttää"
+
+#, fuzzy
+#~ msgid "Key length is too high"
+#~ msgstr "Liian pitkä polku"
+
+#, c-format
+#~ msgid "Key is read-only: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Key is fixed: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Key is locked: %s"
+#~ msgstr "E741: Arvo on lukittu: %s"
+
+#. Doesn't exist, fail
+#, fuzzy, c-format
+#~ msgid "Key does not exist: %s"
+#~ msgstr "Tiedostoa %s ei ole"
+
+#, fuzzy
+#~ msgid "Empty option name"
+#~ msgstr "E792: tyhjä valikkonimi"
+
+#, fuzzy, c-format
+#~ msgid "Invalid option name \"%s\""
+#~ msgstr "E755: Virheellinen alue kohteelle %s"
+
+#, fuzzy, c-format
+#~ msgid "Unable to get value for option \"%s\""
+#~ msgstr "ei voi tyhjentää yleistä asetusta %s"
+
+#, fuzzy, c-format
+#~ msgid "Unknown type for option \"%s\""
+#~ msgstr "E113: Tuntematon asetus: %s"
+
+#, fuzzy, c-format
+#~ msgid "Unable to unset option \"%s\""
+#~ msgstr "ei voi tyhjentää yleistä asetusta %s"
+
+#, fuzzy, c-format
+#~ msgid "Cannot unset option \"%s\" because it doesn't have a global value"
+#~ msgstr "ei voi tyhjentää asetusta %s jolla ei ole yleistä arvoa"
+
+#, c-format
+#~ msgid "Option \"%s\" requires a boolean value"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Option \"%s\" requires an integer value"
+#~ msgstr "E709: [:] toimii vain listalla"
+
+#, c-format
+#~ msgid "Value for option \"%s\" is outside range"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Option \"%s\" requires a string value"
+#~ msgstr "E709: [:] toimii vain listalla"
+
+#, fuzzy
+#~ msgid "Invalid buffer id"
+#~ msgstr "virheellinen puskurinumero"
+
+#, fuzzy
+#~ msgid "Invalid window id"
+#~ msgstr "E534: Viallinen leveä fontti"
+
+#, fuzzy
+#~ msgid "Invalid tabpage id"
+#~ msgstr "Väärä argumentti valitsimelle"
+
+#~ msgid "Integer value outside range"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Empty dictionary keys aren't allowed"
+#~ msgstr "tyhjiä avaimia ei voi käyttää"
+
+#, fuzzy
+#~ msgid "Problem while switching windows"
+#~ msgstr "virhe ikkunaa vaihtaessa"
+
+#, fuzzy
+#~ msgid "UI already attached for channel"
+#~ msgstr "Vanhimmassa muutoksessa"
+
+#~ msgid "Expected width > 0 and height > 0"
+#~ msgstr ""
+
+#~ msgid "UI is not attached for channel"
+#~ msgstr ""
+
+#~ msgid "rgb must be a Boolean"
+#~ msgstr ""
+
+#~ msgid "popupmenu_external must be a Boolean"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "No such ui option"
+#~ msgstr "E24: Lyhennettä ei ole"
+
+#~ msgid "Function called with too many arguments."
+#~ msgstr ""
+
+#~ msgid "Error calling function."
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "String length is too high"
+#~ msgstr "Liian pitkä polku"
+
+#~ msgid "Directory string is too long"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Failed to change directory"
+#~ msgstr "hakemistoa ei voitu muuttaa"
+
+#, fuzzy, c-format
+#~ msgid "Failed to switch to buffer %d"
+#~ msgstr "ei voitu vaihtaa puskuriin %d"
+
+#, fuzzy, c-format
+#~ msgid "Failed to switch to window %d"
+#~ msgstr "ei voitu vaihtaa puskuriin %d"
+
+#, fuzzy, c-format
+#~ msgid "Failed to switch to tabpage %d"
+#~ msgstr "ei voitu vaihtaa puskuriin %d"
+
+#~ msgid "All items in calls array must be arrays"
+#~ msgstr ""
+
+#~ msgid "All items in calls array must be arrays of size 2"
+#~ msgstr ""
+
+#~ msgid "name must be String"
+#~ msgstr ""
+
+#~ msgid "args must be Array"
+#~ msgstr ""
+
+# datarakenteita
+#, fuzzy
+#~ msgid "Argument \"pos\" must be a [row, col] array"
+#~ msgstr "E712: Argumentin %s pitää olla lista tai sanakirja"
+
+#, fuzzy
+#~ msgid "Cursor position outside buffer"
+#~ msgstr "kursorin sijainti puskurin ulkopuolella"
+
+#~ msgid "Height value outside range"
+#~ msgstr ""
+
+#~ msgid "Width value outside range"
+#~ msgstr ""
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[Sijaintiluettelo]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Pikakorjausluettelo]"
-#: ../buffer.c:94
-#, fuzzy
msgid "E855: Autocommands caused command to abort"
-msgstr "E812: Autocommands muutti puskurin tai sen nimen"
+msgstr "E855: Autocommands lopetti komennon"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: Mitään puskuria ei voitu varata, lopetetaan..."
+msgstr "E82: Mitään puskuria ei voitu varata, lopetetaan..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: Puskuria ei voitu varata, käytetään toista..."
+msgstr "E83: Puskuria ei voitu varata, käytetään toista..."
+
+#, fuzzy
+#~ msgid "E937: Attempt to delete a buffer that is in use"
+#~ msgstr "E934: Ei voida hypätä puskuriin jolla ei ole nimeä"
-#: ../buffer.c:763
msgid "E515: No buffers were unloaded"
msgstr "E515: Puskureita ei vapautettu"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Puskureita ei poistettu"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Puskureita ei pyyhitty"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "1 puskuri vapautettiin"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d puskuria vapautettiin"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "1 puskuri poistettu"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d puskuria poistettu"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "1 puskuri pyyhitty"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d puskuria pyyhitty"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
-msgstr "E90: Ei voi vapauttaa viimeistä puskuria"
+msgstr "E90: Ei voi vapauttaa viimeistä puskuria"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Ei muokattuja puskureita"
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Luetteloitua puskuria ei ole"
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Puskuria %<PRId64> ei ole"
-
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: Viimeisen puskurin ohi ei voi edetä"
+msgstr "E87: Viimeisen puskurin ohi ei voi edetä"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
-msgstr "E88: Ensimmäisen puskurin ohi ei voi edetä"
+msgstr "E88: Ensimmäisen puskurin ohi ei voi edetä"
-#: ../buffer.c:945
-#, c-format
+#, fuzzy, c-format
+#~ msgid "E89: %s will be killed(add ! to override)"
+#~ msgstr "E189: %s on jo olemassa (lisää komentoon ! ohittaaksesi)"
+
+#, fuzzy, c-format
msgid ""
"E89: No write since last change for buffer %<PRId64> (add ! to override)"
msgstr ""
-"E89: Puskurin %<PRId64> muutoksia ei ole tallennettu (lisää komentoon ! "
+"E89: Puskurin %ld muutoksia ei ole tallennettu (lisää komentoon ! "
"ohittaaksesi)"
#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Varoitus: Tiedostonimiluettelon ylivuoto"
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Puskuria %<PRId64> ei löydy"
+#, fuzzy, c-format
+#~ msgid "E92: Buffer %<PRId64> not found"
+#~ msgstr "E92: Puskuria %ld ei löydy"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
-msgstr "E93: %s täsmää useampaan kuin yhteen puskuriin"
+msgstr "E93: %s täsmää useampaan kuin yhteen puskuriin"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
-msgstr "E94: %s ei täsmää yhteenkään puskuriin"
+msgstr "E94: %s ei täsmää yhteenkään puskuriin"
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "rivi %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "line %<PRId64>"
+#~ msgstr "rivi %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Samanniminen puskuri on jo olemassa"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [Muokattu]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Muokkaamaton]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Uusi tiedosto]"
-#: ../buffer.c:2505
msgid "[Read errors]"
-msgstr "[Lukuvirheitä]"
+msgstr "[Lukuvirheitä]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[Luku]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[kirjoitussuojattu]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 rivi --%d %%--"
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> riviä --%d %%--"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines --%d%%--"
+#~ msgstr "%ld riviä --%d %%--"
-#: ../buffer.c:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "rivi %<PRId64>/%<PRId64> --%d %%-- sarake "
+#, fuzzy, c-format
+#~ msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
+#~ msgstr "rivi %ld/%ld --%d %%-- sarake "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
-msgstr "[Nimetön]"
+msgstr "[Nimetön]"
-#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "ohje"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Ohje]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[Esikatselu]"
# sijainti tiedostossa -indikaattoreja:
-# 4 merkkiä sais riittää
-#: ../buffer.c:3528
+# 4 merkkiä sais riittää
msgid "All"
msgstr "Kaik"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Loppu"
-#: ../buffer.c:3531
msgid "Top"
msgstr "Alku"
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# Puskuriluettelo:\n"
-
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[Raapust]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -249,795 +419,664 @@ msgstr ""
"\n"
"--- Merkit ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Merkit kohteelle %s:"
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " rivi=%<PRId64> id=%d nimi=%s"
+#, fuzzy, c-format
+#~ msgid " line=%<PRId64> id=%d name=%s"
+#~ msgstr " rivi=%ld id=%d nimi=%s"
-#: ../cursor_shape.c:68
msgid "E545: Missing colon"
msgstr "E545: Kaksoispiste puuttuu"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
msgid "E546: Illegal mode"
msgstr "E546: Virheellinen tila"
-#: ../cursor_shape.c:134
msgid "E548: digit expected"
-msgstr "E548: pitää olla numero"
+msgstr "E548: pitää olla numero"
-#: ../cursor_shape.c:138
msgid "E549: Illegal percentage"
msgstr "E549: Virheellinen prosenttiluku"
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Ei voi diffata enempää kuin %<PRId64> puskuria"
+#, fuzzy, c-format
+#~ msgid "E96: Cannot diff more than %<PRId64> buffers"
+#~ msgstr "E96: Ei voi diffata enempää kuin %ld puskuria"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
-msgstr "E810: Ei voi lukea tai kirjoittaa väliaikaistiedostoja"
+msgstr "E810: Ei voi lukea tai kirjoittaa väliaikaistiedostoja"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
-msgstr "E97: Ei voi luoda diffejä"
+msgstr "E97: Ei voi luoda diffejä"
-#: ../diff.c:966
msgid "E816: Cannot read patch output"
msgstr "E816: Ei voi lukea patchin tulostetta"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Ei voi lukea diffin tulostetta"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: Tämä puskuri ei ole diff-tilassa"
+msgstr "E99: Tämä puskuri ei ole diff-tilassa"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E793: Yksikään muu diff-tilan puskurit ei ole muokattavissa"
+msgstr "E793: Yksikään muu diff-tilan puskurit ei ole muokattavissa"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
-msgstr "E100: Yksikään muu puskuri ei ole diff-tilassa"
+msgstr "E100: Yksikään muu puskuri ei ole diff-tilassa"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr "E101: Monta puskuria on diff-tilassa, käytettävän valinta ei onnistu"
+msgstr "E101: Monta puskuria on diff-tilassa, käytettävän valinta ei onnistu"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: Puskuria %s ei löydy"
+msgstr "E102: Puskuria %s ei löydy"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Puskuri %s ei ole diff-tilassa"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Puskuri vaihtui odottamatta"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
-msgstr "E104: Escapea ei voi käyttää digraafissa"
+msgstr "E104: Escapea ei voi käyttää digraafissa"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
-msgstr "E544: Näppäinkarttaa ei löydy"
+msgstr "E544: Näppäinkarttaa ei löydy"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: Käytetään :loadkeymapia ladatun tiedoston ulkopuolella"
+msgstr "E105: Käytetään :loadkeymapia ladatun tiedoston ulkopuolella"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
-msgstr "E791: Tyhjä keymap-kenttä"
+msgstr "E791: Tyhjä keymap-kenttä"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
-msgstr " Avainsanatäydennys (^N^P)"
+msgstr " Avainsanatäydennys (^N^P)"
-#. 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-tila (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
-msgstr " Täysrivitäydennys (^L^N^P)"
+msgstr " Täysrivitäydennys (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
-msgstr " Tiedostonimitäydennys (^F^N^P)"
+msgstr " Tiedostonimitäydennys (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
-msgstr " Tägitäydennys (^]^N^P)"
+msgstr " Tägitäydennys (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
-msgstr " Polkukuviotäydennys (^N^P)"
+msgstr " Polkukuviotäydennys (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
-msgstr " Määritelmätäydennys (^D^N^P)"
+msgstr " Määritelmätäydennys (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
-msgstr " Sanakirjatäydennys (^K^N^P)"
+msgstr " Sanakirjatäydennys (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
-msgstr " Thesaurus-täydennys (^T^N^P)"
+msgstr " Thesaurus-täydennys (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
-msgstr " Komentorivitäydennys (^V^N^P)"
+msgstr " Komentorivitäydennys (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
-msgstr " Käyttäjän määrittelemä täydennys (^U^N^P)"
+msgstr " Käyttäjän määrittelemä täydennys (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
-msgstr " Omnitäydennys (^O^N^P)"
+msgstr " Omnitäydennys (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Oikaisulukuehdotus (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
-msgstr " Avainsanan paikallinen täydennys (^N^P)"
+msgstr " Avainsanan paikallinen täydennys (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Kappaleen loppu tuli vastaan"
-#: ../edit.c:101
-#, fuzzy
msgid "E839: Completion function changed window"
-msgstr "E813: Ei voi sulkea autocmd-ikkunaa"
+msgstr "E839: Täydennys vaihtoi ikkunaa"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
-msgstr ""
+msgstr "E840: Täydennys poisti tekstiä"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
-msgstr "dictionary-asetus on tyhjä"
+msgstr "dictionary-asetus on tyhjä"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
-msgstr "thesaurus-asetus on tyhjä"
+msgstr "thesaurus-asetus on tyhjä"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Luetaan sanakirjaa: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
-msgstr " (syöttö) Vieritys (^E/^Y)"
+msgstr " (syöttö) Vieritys (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (korvaus) Vieritys (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "Luetaan: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
-msgstr "Luetaan tägejä."
+msgstr "Luetaan tägejä."
-#: ../edit.c:4519
msgid " Adding"
-msgstr " Lisätään"
+msgstr " Lisätään"
-#. 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 "-- Haetaan..."
-#: ../edit.c:4618
msgid "Back at original"
-msgstr "Takaisin lähtöpisteessä"
+msgstr "Takaisin lähtöpisteessä"
-#: ../edit.c:4621
msgid "Word from other line"
-msgstr "Sana toisella rivillä"
+msgstr "Sana toisella rivillä"
-#: ../edit.c:4624
msgid "The only match"
-msgstr "Ainoa täsmäys"
+msgstr "Ainoa täsmäys"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
-msgstr "täsmäys %d/%d"
+msgstr "täsmäys %d/%d"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
-msgstr "täsmäys %d"
+msgstr "täsmäys %d"
-#: ../eval.c:137
msgid "E18: Unexpected characters in :let"
-msgstr "E18: Odottamattomia merkkejä komennossa :let"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: Indeksi %<PRId64> luettelon rajojen ulkopuolella"
+msgstr "E18: Odottamattomia merkkejä komennossa :let"
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Määrittelemätön muuttuja: %s"
-
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: ] puuttuu"
-#: ../eval.c:141
#, c-format
msgid "E686: Argument of %s must be a List"
-msgstr "E686: Argumentin %s pitää olla lista"
+msgstr "E686: Argumentin %s pitää olla lista"
# datarakenteita
-#: ../eval.c:143
#, c-format
msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Argumentin %s pitää olla lista tai sanakirja"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Sanakirjassa ei voi olla tyhjiä avaimia"
+msgstr "E712: Argumentin %s pitää olla lista tai sanakirja"
-#: ../eval.c:145
msgid "E714: List required"
msgstr "E714: Lista tarvitaan"
-#: ../eval.c:146
msgid "E715: Dictionary required"
msgstr "E715: Sanakirja tarvitaan"
-#: ../eval.c:147
+msgid "E928: String required"
+msgstr "E928: Merkkijono puuttuu"
+
#, c-format
msgid "E118: Too many arguments for function: %s"
msgstr "E118: Liikaa argumentteja funktiolle: %s"
-#: ../eval.c:148
#, c-format
msgid "E716: Key not present in Dictionary: %s"
msgstr "E716: Avainta %s ei ole sanakirjassa"
-#: ../eval.c:150
#, c-format
msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: Funktio %s on jo olemassa, lisää ! korvataksesi"
+msgstr "E122: Funktio %s on jo olemassa, lisää ! korvataksesi"
-#: ../eval.c:151
msgid "E717: Dictionary entry already exists"
msgstr "E717: Sanakirja-alkio on jo olemassa"
-#: ../eval.c:152
msgid "E718: Funcref required"
msgstr "E718: Funcref tarvitaan"
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: Sanakirjassa ei voi käyttää merkintää [:]"
+msgstr "E719: Sanakirjassa ei voi käyttää merkintää [:]"
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: Väärä muuttujatyyppi muuttujalle %s="
-
-#: ../eval.c:155
#, c-format
msgid "E130: Unknown function: %s"
msgstr "E130: Tuntematon funktio: %s"
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Virheellinen muuttujanimi: %s"
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: Float ei käy merkkijonosta"
+#, fuzzy, c-format
+#~ msgid "E46: Cannot change read-only variable \"%.*s\""
+#~ msgstr "E46: Kirjoitussuojattua muuttujaa %s ei voi muuttaa"
+
+#. TODO(ZyX-I): move to eval/executor
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Väärä muuttujatyyppi muuttujalle %s="
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
-msgstr "E687: Kohteita on vähemmän kuin listan alkioita"
+msgstr "E687: Kohteita on vähemmän kuin listan alkioita"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
-msgstr "E688: Kohteita on enemmän kuin listan alkioita"
+msgstr "E688: Kohteita on enemmän kuin listan alkioita"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
-msgstr "Kaksi ;:ttä listan muuttujissa"
+msgstr "Kaksi ;:ttä listan muuttujissa"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Kohteen %s muuttujia ei voi listata"
-#: ../eval.c:2391
+#, fuzzy, c-format
+#~ msgid "E121: Undefined variable: %.*s"
+#~ msgstr "E121: Määrittelemätön muuttuja: %s"
+
msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: Vain listalla ja sanakirjalla voi olla indeksejä"
+msgstr "E689: Vain listalla ja sanakirjalla voi olla indeksejä"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
-msgstr "E708: [:]:n pitää olla viimeisenä"
+msgstr "E708: [:]:n pitää olla viimeisenä"
+
+#, fuzzy
+#~ msgid "E713: Cannot use empty key after ."
+#~ msgstr "E713: Sanakirjassa ei voi olla tyhjiä avaimia"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: [:] toimii vain listalla"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
-msgstr "E710: Listalla on enemmän alkioita kuin kohteella"
+msgstr "E710: Listalla on enemmän alkioita kuin kohteella"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: Listalla ei ole tarpeeksi alkioita"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: :for-kommenolta puuttuu in"
-#: ../eval.c:3063
#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: Sulkeita puuttuu: %s"
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Muuttujaa %s ei ole"
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: muuttujassa liian monta tasoa lukituksen käsittelyyn"
+#. For historical reasons this error is not given for Lists and
+#. Dictionaries. E.g. b: dictionary may be locked/unlocked.
+#, fuzzy, c-format
+#~ msgid "E940: Cannot lock or unlock variable %s"
+#~ msgstr "E46: Kirjoitussuojattua muuttujaa %s ei voi muuttaa"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
-msgstr "E109: ?:n jälkeen puuttuu :"
+msgstr "E109: ?:n jälkeen puuttuu :"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: Listaa voi verrata vain listaan"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: Virheellinen toiminto listalle"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: Sanakirjaa voi verrata vain sanakirjaan"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: Virheellinen toiminto sanakirjalle"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Funcrefiä voi verrata vain funcrefiin"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: Virheellinen toiminto funcrefille"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
-msgstr "E804: Ei voi käyttää '%':a Floatin kanssa"
+msgstr "E804: Ei voi käyttää '%':a Floatin kanssa"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ) puuttuu"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
-msgstr "E695: Funcrefiä ei voi indeksoida"
+msgstr "E695: Funcrefiä ei voi indeksoida"
+
+msgid "E909: Cannot index a special variable"
+msgstr "E909: erikoismuuttujaa ei voi indeksoida"
-#: ../eval.c:4839
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Asetuksen nimi puuttuu: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Tuntematon asetus: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Puuttuva lainausmerkki: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Puuttuva lainausmerkki: %s"
-#: ../eval.c:5084
#, c-format
msgid "E696: Missing comma in List: %s"
msgstr "E696: Listasta puuttuu pilkku: %s"
-#: ../eval.c:5091
#, c-format
msgid "E697: Missing end of List ']': %s"
msgstr "E697: Listan lopusta puuttuu ]: %s"
-#: ../eval.c:6475
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"Ei tarpeeksi muistia viitteiden asettamista varten, roskiekeruu peruttiin."
+
#, c-format
msgid "E720: Missing colon in Dictionary: %s"
msgstr "E720: Sanakirjasta puuttuu kaksoispiste: %s"
-#: ../eval.c:6499
#, c-format
msgid "E721: Duplicate key in Dictionary: \"%s\""
msgstr "E721: Kaksi samaa avainta sanakirjassa: %s"
-#: ../eval.c:6517
#, c-format
msgid "E722: Missing comma in Dictionary: %s"
msgstr "E722: Sanakirjasta puuttuu pilkku: %s"
-#: ../eval.c:6524
#, c-format
msgid "E723: Missing end of Dictionary '}': %s"
msgstr "E723: Sanakirjan lopusta puuttuu }: %s"
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: muuttuja on upotettu liian syvälle näytettäväksi"
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Virheellinen argumentti: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Kaksoiskappale argumentin nimestä: %s"
-#: ../eval.c:7188
#, c-format
msgid "E740: Too many arguments for function %s"
msgstr "E740: Liikaa argumentteja funktiolle %s"
-#: ../eval.c:7190
#, c-format
msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Vääriä argumentteja funktiolle %s"
+msgstr "E116: Vääriä argumentteja funktiolle %s"
-#: ../eval.c:7377
#, c-format
msgid "E117: Unknown function: %s"
msgstr "E117: Tuntematon funktio: %s"
-#: ../eval.c:7383
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: Funktion nimi poistettu: %s"
+
#, c-format
msgid "E119: Not enough arguments for function: %s"
msgstr "E119: Liikaa argumentteja funktiolle %s"
-#: ../eval.c:7387
#, c-format
msgid "E120: Using <SID> not in a script context: %s"
msgstr "E120: <SID> skriptin ulkopuolella: %s"
-#: ../eval.c:7391
#, c-format
msgid "E725: Calling dict function without Dictionary: %s"
msgstr "E725: dict-funktio ilman sanakirjaa: %s"
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Number tai Float vaaditaan"
+#, fuzzy, c-format
+#~ msgid "Error converting the call result: %s"
+#~ msgstr "virhe Schemestä Vimiin konversiossa"
-#: ../eval.c:7503
-#, fuzzy
msgid "add() argument"
-msgstr "-c-argumentti"
+msgstr "add()-argumentti"
-#: ../eval.c:7907
msgid "E699: Too many arguments"
msgstr "E699: Liikaa argumentteja"
-#: ../eval.c:8073
msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() toimii vain syöttötilassa"
+msgstr "E785: complete() toimii vain syöttötilassa"
-#: ../eval.c:8156
msgid "&Ok"
msgstr "&Ok"
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Avain on jo olemassa: %s"
-
-#: ../eval.c:8692
#, fuzzy
+#~ msgid "dictwatcheradd() argument"
+#~ msgstr "add()-argumentti"
+
msgid "extend() argument"
-msgstr "--cmd-argumentti"
+msgstr "extend()-argumentti"
-#: ../eval.c:8915
-#, fuzzy
msgid "map() argument"
-msgstr "-c-argumentti"
+msgstr "map()-argumentti"
-#: ../eval.c:8916
-#, fuzzy
msgid "filter() argument"
-msgstr "-c-argumentti"
+msgstr "filter()-argumentti"
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld riviä: "
+#, fuzzy, c-format
+#~ msgid "+-%s%3ld lines: "
+#~ msgstr "+-%s%3ld rivi: "
-#: ../eval.c:9291
#, c-format
msgid "E700: Unknown function: %s"
msgstr "E700: Tuntematon funktio: %s"
-#: ../eval.c:10729
+msgid "E922: expected a dict"
+msgstr "E922: odotettiin dictiä"
+
+# datarakenteita
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: toisen function()-argumentin pitää olla lista tai sanakirja"
+
+#, fuzzy
+#~ msgid "E5000: Cannot find tab number."
+#~ msgstr "E695: Funcrefiä ei voi indeksoida"
+
+#~ msgid "E5001: Higher scope cannot be -1 if lower scope is >= 0."
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E5002: Cannot find window number."
+#~ msgstr "E671: Ikkunan otsikkoa ei löydy %s"
+
msgid "called inputrestore() more often than inputsave()"
msgstr "inputrestore() suoritettu useammin kuin inputsave()"
-#: ../eval.c:10771
-#, fuzzy
msgid "insert() argument"
-msgstr "-c-argumentti"
+msgstr "insert()-argumentti"
-#: ../eval.c:10841
msgid "E786: Range not allowed"
-msgstr "E786: Aluetta ei voi käyttää"
+msgstr "E786: Aluetta ei voi käyttää"
+
+#~ msgid "Invalid stream on rpc job, use jobclose(id, 'rpc')"
+#~ msgstr ""
+
+#~ msgid "Invalid job stream: Not an rpc job"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Invalid job stream \"%s\""
+#~ msgstr ""
+
+#~ msgid "Can't send data to the job: stdin is closed"
+#~ msgstr ""
+
+#~ msgid "Can't send raw data to rpc channel"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E474: Failed to convert list to string"
+#~ msgstr "ei voitu konvertoida tyypistä %s vim-listaksi"
+
+#, fuzzy, c-format
+#~ msgid "E474: Failed to parse %.*s"
+#~ msgstr "E241: Kohteeseen %s lähettäminen ei onnistunut"
-#: ../eval.c:11140
msgid "E701: Invalid type for len()"
msgstr "E701: Virheellinen tyyppi funktiolle len()"
-#: ../eval.c:11980
+#, fuzzy, c-format
+#~ msgid "msgpackdump() argument, index %i"
+#~ msgstr "map()-argumentti"
+
+#, fuzzy
+#~ msgid "E5070: Character number must not be less than zero"
+#~ msgstr "luvun on oltava nollaa suurempi"
+
+#, fuzzy, c-format
+#~ msgid "E5071: Character number must not be greater than INT_MAX (%i)"
+#~ msgstr "luvun on oltava nollaa suurempi"
+
msgid "E726: Stride is zero"
msgstr "E726: Stride on nolla"
-#: ../eval.c:11982
msgid "E727: Start past end"
-msgstr "E727: Alku on lopun jälkeen"
+msgstr "E727: Alku on lopun jälkeen"
-#: ../eval.c:12024 ../eval.c:15297
msgid "<empty>"
-msgstr "<tyhjä>"
+msgstr "<tyhjä>"
-#: ../eval.c:12282
-#, fuzzy
msgid "remove() argument"
-msgstr "--cmd-argumentti"
+msgstr "remove()-argumentti"
-#: ../eval.c:12466
msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: Liikaa symbolisia linkkejä (mahdollinen sykli)"
+msgstr "E655: Liikaa symbolisia linkkejä (mahdollinen sykli)"
-#: ../eval.c:12593
-#, fuzzy
msgid "reverse() argument"
-msgstr "-c-argumentti"
+msgstr "reverse()-argumentti"
+
+#, c-format
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Viallinen toiminto: %s"
-#: ../eval.c:13721
-#, fuzzy
msgid "sort() argument"
-msgstr "-c-argumentti"
+msgstr "sort()-argumentti"
-#: ../eval.c:13721
-#, fuzzy
msgid "uniq() argument"
-msgstr "-c-argumentti"
+msgstr "uniq()-argumentti"
-#: ../eval.c:13776
msgid "E702: Sort compare function failed"
msgstr "E702: Lajittelun vertausfunktio ei onnistunut"
-#: ../eval.c:13806
-#, fuzzy
msgid "E882: Uniq compare function failed"
-msgstr "E702: Lajittelun vertausfunktio ei onnistunut"
+msgstr "E882: Uniqin vertausfunktio ei onnistunut"
-#: ../eval.c:14085
msgid "(Invalid)"
msgstr "(Virheellinen)"
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Väliaikaistiedostoon kirjoittaminen ei onnistunut"
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: Virheellinen alitäsmäyksen numero: %d"
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Float ei käy Numberista"
+#~ msgid "Can only call this function in an unmodified buffer"
+#~ msgstr ""
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Funcref ei käy Numberista"
+msgid "E921: Invalid callback argument"
+msgstr "E921: Virheellinen callback-argumentti"
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: Lista ei käy Numberista"
+#, fuzzy, c-format
+#~ msgid "E80: Error while writing: %s"
+#~ msgstr "E80: Kirjoitusvirhe"
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Sanakirja ei käy Numberista"
+#. Using %s, p and not %c, *p to preserve multibyte characters
+#, fuzzy, c-format
+#~ msgid "E5060: Unknown flag: %s"
+#~ msgstr "E235: Tuntematon fontti: %s"
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: Funcref ei käy merkkijonosta"
+#, fuzzy
+#~ msgid "E482: Can't open file with an empty name"
+#~ msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: Lista ei käy merkkijonosta"
+#, fuzzy, c-format
+#~ msgid "E482: Can't open file %s for writing: %s"
+#~ msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Sanakirja ei käy merkkijonosta"
+#, fuzzy, c-format
+#~ msgid "E80: Error when closing file %s: %s"
+#~ msgstr "E209: Virhe suljettaessa tiedostoa %s"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Muuttujatyyppi ei täsmää: %s"
+#, fuzzy, c-format
+#~ msgid "E794: Cannot set variable in the sandbox: \"%.*s\""
+#~ msgstr "E794: Muuttujaa ei voi asettaa hiekkalaatikossa: %s"
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Muuttujaa %s ei voi poistaa"
+#, fuzzy, c-format
+#~ msgid "E795: Cannot delete variable %.*s"
+#~ msgstr "E795: Muuttujaa %s ei voi poistaa"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Funcrefin muuttujanimen pitää alkaa suuraakkosella: %s"
+msgstr "E704: Funcrefin muuttujanimen pitää alkaa suuraakkosella: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: Muuttujanimi on sama kuin olemassaolevan funktion: %s"
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: Arvo on lukittu: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Tuntematon"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Ei voi muuttaa muuttujan %s arvoa"
-
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: muuttuja on upotettu liian syvälle kopioitavaksi"
+msgstr "E698: muuttuja on upotettu liian syvälle kopioitavaksi"
-#: ../eval.c:17249
#, c-format
msgid "E123: Undefined function: %s"
msgstr "E123: Tuntematon funktio: %s"
-#: ../eval.c:17260
#, c-format
msgid "E124: Missing '(': %s"
msgstr "E124: ( puuttuu: %s"
-#: ../eval.c:17293
-#, fuzzy
msgid "E862: Cannot use g: here"
-msgstr "E284: Ei voi asettaa IC-arvoja"
+msgstr "E862: g: ei toimi täällä"
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Virheellinen argumentti: %s"
-
-#: ../eval.c:17323
#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "Kaksoiskappale kentän nimestä: %s"
+#~ msgid "E932: Closure function should not be at top level: %s"
+#~ msgstr "E932 Sulkeumafunktio ei voi olla uloimmalla tasolla: %s"
-#: ../eval.c:17416
msgid "E126: Missing :endfunction"
msgstr "E126: :endfunction puuttuu"
-#: ../eval.c:17537
#, c-format
msgid "E707: Function name conflicts with variable: %s"
msgstr "E707: Funktion nimi on ristiriidassa muuttujan kanssa: %s"
-#: ../eval.c:17549
#, c-format
msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Funktiota %s ei voi määritellä uudestaan, koska se on käytössä"
+msgstr "E127: Funktiota %s ei voi määritellä uudestaan, koska se on käytössä"
-#: ../eval.c:17604
#, c-format
msgid "E746: Function name does not match script file name: %s"
msgstr "E746: Funktion nimi ei ole sama kuin skriptin tiedostonnimi: %s"
-#: ../eval.c:17716
msgid "E129: Function name required"
msgstr "E129: Funktion nimi puuttuu"
-#: ../eval.c:17824
-#, fuzzy, c-format
+#, c-format
msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Funktion nimen pitää alkaa suuraakkosella tai sisältää kaksoispisteen: "
-"%s"
+msgstr "E128: Funktion nimen pitää alkaa suuraakkosella tai merkeillä ’s:’: %s"
-#: ../eval.c:17833
-#, fuzzy, c-format
+#, c-format
msgid "E884: Function name cannot contain a colon: %s"
-msgstr ""
-"E128: Funktion nimen pitää alkaa suuraakkosella tai sisältää kaksoispisteen: "
-"%s"
+msgstr "E884: Funktion nimessä ei saa olla kaksoispistettä: %s"
-#: ../eval.c:18336
#, c-format
msgid "E131: Cannot delete function %s: It is in use"
msgstr "E131: Funktiota %s ei voi poistaa"
-#: ../eval.c:18441
+#, fuzzy, c-format
+#~ msgid "Cannot delete function %s: It is being used internally"
+#~ msgstr "E131: Funktiota %s ei voi poistaa"
+
msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Funktiokutsujen syvyys on enemmän kuin maxfuncdepth"
+msgstr "E132: Funktiokutsujen syvyys on enemmän kuin maxfuncdepth"
-#: ../eval.c:18568
#, c-format
msgid "calling %s"
msgstr "kutsutaan funktiota %s"
-#: ../eval.c:18651
#, c-format
msgid "%s aborted"
msgstr "%s keskeytettiin"
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s palaa kohdassa #%<PRId64>"
+#, fuzzy, c-format
+#~ msgid "%s returning #%<PRId64>"
+#~ msgstr "%s palaa kohdassa #%ld"
-#: ../eval.c:18670
#, c-format
msgid "%s returning %s"
msgstr "%s palaa kohdassa %s"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
msgid "continuing in %s"
msgstr "jatkaa kohdassa %s"
-#: ../eval.c:18795
msgid "E133: :return not inside a function"
-msgstr "E133: :return ei ole funktion sisällä"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# globaalit muuttujat:\n"
+msgstr "E133: :return ei ole funktion sisällä"
-#: ../eval.c:19254
msgid ""
"\n"
"\tLast set from "
@@ -1045,154 +1084,408 @@ msgstr ""
"\n"
"\tViimeksi asetettu kohteesta "
-#: ../eval.c:19272
msgid "No old files"
msgstr "Ei vanhoja tiedostoja"
-# puhutaan merkin ulkoasusta snprintf(..., c, c, c, c)
-#: ../ex_cmds.c:122
#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, heksana %02x, oktaalina %03o"
+#~ msgid "E474: Expected comma before list item: %s"
+#~ msgstr ""
-#: ../ex_cmds.c:145
#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, heksana %04x, oktaalina %o"
+#~ msgid "E474: Expected colon before dictionary value: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected string key: %s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected comma before dictionary key: %s"
+#~ msgstr "E722: Sanakirjasta puuttuu pilkku: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unfinished escape sequence: %.*s"
+#~ msgstr "E540: Sulkematon lausekesarja"
-#: ../ex_cmds.c:146
#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, hekdana %08x, oktaalina %o"
+#~ msgid "E474: Unfinished unicode escape sequence: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: Rivien siirto itsejensä päälle"
+#, c-format
+#~ msgid "E474: Expected four hex digits after \\u: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "1 rivi siirretty"
+#, fuzzy, c-format
+#~ msgid "E474: Unknown escape sequence: %.*s"
+#~ msgstr "E409: Tuntematon ryhmän nimi: %s"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> riviä siirretty"
+#~ msgid "E474: ASCII control characters cannot be present inside string: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> riviä suodatettu"
+#~ msgid "E474: Only UTF-8 strings allowed: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: *Filter*-autocommand ei voi vaihtaa puskuria"
+#, c-format
+#~ msgid ""
+#~ "E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: "
+#~ "%.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[Viimeisintä muutosta ei ole kirjoitettu]\n"
+#, fuzzy, c-format
+#~ msgid "E474: Expected string end: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Leading zeroes are not allowed: %.*s"
+#~ msgstr "E786: Aluetta ei voi käyttää"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing number after minus sign: %.*s"
+#~ msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing number after decimal dot: %.*s"
+#~ msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
+
+#, fuzzy, c-format
+#~ msgid "E474: Missing exponent: %.*s"
+#~ msgstr "E114: Puuttuva lainausmerkki: %s"
+
+#, c-format
+#~ msgid ""
+#~ "E685: internal error: while converting number \"%.*s\" to float string2float "
+#~ "consumed %zu bytes in place of %zu"
+#~ msgstr ""
-#: ../ex_cmds.c:1424
#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s rivillä: "
+#~ msgid ""
+#~ "E685: internal error: while converting number \"%.*s\" to integer vim_str2nr "
+#~ "consumed %i bytes in place of %zu"
+#~ msgstr ""
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: liikaa virheitä, ohitetaan lopputiedosto"
+#~ msgid "E474: Attempt to decode a blank string"
+#~ msgstr ""
-#: ../ex_cmds.c:1458
#, c-format
-msgid "Reading viminfo file \"%s\"%s%s%s"
-msgstr "Luetaan viminfo-tiedostoa \"%s\"%s%s%s"
+#~ msgid "E474: No container to close: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1460
-msgid " info"
-msgstr " info"
+#, c-format
+#~ msgid "E474: Closing list with curly bracket: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " merkit"
+#, fuzzy, c-format
+#~ msgid "E474: Closing dictionary with square bracket: %.*s"
+#~ msgstr "E725: dict-funktio ilman sanakirjaa: %s"
-#: ../ex_cmds.c:1462
-msgid " oldfiles"
-msgstr " vanhaatiedostoa"
+#, fuzzy, c-format
+#~ msgid "E474: Trailing comma: %.*s"
+#~ msgstr "E488: Ylimääräisiä merkkejä perässä"
-#: ../ex_cmds.c:1463
-msgid " FAILED"
-msgstr " EPÄONNISTUI"
+#, c-format
+#~ msgid "E474: Expected value after colon: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected value: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
-#. 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-tiedostoon ei voitu kirjoittaa: %s"
+#~ msgid "E474: Comma not inside container: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Duplicate comma: %.*s"
+#~ msgstr "E721: Kaksi samaa avainta sanakirjassa: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Comma after colon: %.*s"
+#~ msgstr "E254: Väriä %s ei voi määritellä"
+
+#, fuzzy, c-format
+#~ msgid "E474: Using comma in place of colon: %.*s"
+#~ msgstr "E722: Sanakirjasta puuttuu pilkku: %s"
-#: ../ex_cmds.c:1626
#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: Viminfo-tiedoston kirjoittaminen ei onnistu %s"
+#~ msgid "E474: Leading comma: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1635
#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "Kirjoitetaan viminfo-tiedostoa %s"
+#~ msgid "E474: Colon not inside container: %.*s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E474: Using colon not in dictionary: %.*s"
+#~ msgstr "E720: Sanakirjasta puuttuu kaksoispiste: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unexpected colon: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
-#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# Vimin %s generoima viminfo-tiedosto.\n"
+#~ msgid "E474: Colon after comma: %.*s"
+#~ msgstr ""
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# Muokkaa varovasti!\n"
-"\n"
+#, fuzzy, c-format
+#~ msgid "E474: Duplicate colon: %.*s"
+#~ msgstr "E721: Kaksi samaa avainta sanakirjassa: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected null: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected true: %.*s"
+#~ msgstr "E270: odotuksenvastainen redo"
+
+#, fuzzy, c-format
+#~ msgid "E474: Expected false: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unidentified byte: %.*s"
+#~ msgstr "E121: Määrittelemätön muuttuja: %s"
+
+#, fuzzy, c-format
+#~ msgid "E474: Trailing characters: %.*s"
+#~ msgstr "E488: Ylimääräisiä merkkejä perässä"
+
+#, fuzzy, c-format
+#~ msgid "E474: Unexpected end of input: %.*s"
+#~ msgstr "E415: odotuksenvastainen =-merkki: %s"
+
+#, c-format
+#~ msgid "key %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "key %s at index %i from special map"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "index %i"
+#~ msgstr ""
+
+#~ msgid "partial"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "argument %i"
+#~ msgstr "-c-argumentti"
+
+#, fuzzy
+#~ msgid "partial self dictionary"
+#~ msgstr "ei voida muuttaa kiinnitettyä sanakirjaa"
+
+#~ msgid "itself"
+#~ msgstr ""
+
+#. Only give this message once for a recursive call to avoid
+#. flooding the user with errors.
+#~ msgid "E724: unable to correctly dump variable with self-referencing container"
+#~ msgstr ""
+
+#~ msgid "E474: Unable to represent NaN value in JSON"
+#~ msgstr ""
+
+#~ msgid "E474: Unable to represent infinity in JSON"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "E474: String \"%.*s\" contains byte that does not start any UTF-8 character"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "E474: UTF-8 string contains code point which belongs to a surrogate pair: "
+#~ "%.*s"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E474: Unable to convert EXT string to JSON"
+#~ msgstr "E620: Tulostuskoodaukseen %s muunto ei onnistu"
+
+#, c-format
+#~ msgid "E474: Error while dumping %s, %s: attempt to dump function reference"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E474: Invalid key in special dictionary"
+#~ msgstr "E736: Virheellinen toiminto sanakirjalle"
+
+#, c-format
+#~ msgid "E5004: Error while dumping %s, %s: attempt to dump function reference"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "E5005: Unable to dump %s: container references itself in %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "E684: list index out of range: %<PRId64>"
+#~ msgstr "E684: Indeksi %ld luettelon rajojen ulkopuolella"
-#: ../ex_cmds.c:1723
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# encoding-muuttujan arvo tiedostoa kirjoitettaessa\n"
+#~ msgid "E6000: Argument is not a function or function name"
+#~ msgstr ""
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Avain on jo olemassa: %s"
+
+#, fuzzy
+#~ msgid "tv_clear() argument"
+#~ msgstr "filter()-argumentti"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: muuttujassa liian monta tasoa lukituksen käsittelyyn"
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "Virheellinen aloitusmerkki"
+#, fuzzy, c-format
+#~ msgid "E741: Value is locked: %.*s"
+#~ msgstr "E741: Arvo on lukittu: %s"
+
+#, fuzzy, c-format
+#~ msgid "E742: Cannot change value of %.*s"
+#~ msgstr "E742: Ei voi muuttaa muuttujan %s arvoa"
+
+msgid "Unknown"
+msgstr "Tuntematon"
+
+#, fuzzy
+#~ msgid "E805: Expected a Number or a String, Float found"
+#~ msgstr "E807: Odotettiin Float-argumenttia printf():lle"
+
+#~ msgid "E703: Expected a Number or a String, Funcref found"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E745: Expected a Number or a String, List found"
+#~ msgstr "E807: Odotettiin Float-argumenttia printf():lle"
+
+#~ msgid "E728: Expected a Number or a String, Dictionary found"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "E5300: Expected a Number or a String"
+#~ msgstr "E807: Odotettiin Float-argumenttia printf():lle"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: Lista ei käy Numberista"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Sanakirja ei käy Numberista"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Float ei käy Numberista"
+
+#, fuzzy
+#~ msgid "E685: using an invalid value as a Number"
+#~ msgstr "E908: huono arvo merkkijonolle"
+
+msgid "E730: using List as a String"
+msgstr "E730: Lista ei käy merkkijonosta"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Sanakirja ei käy merkkijonosta"
+
+msgid "E908: using an invalid value as a String"
+msgstr "E908: huono arvo merkkijonolle"
+
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: Funcref ei käy Floatista"
+
+msgid "E892: Using a String as a Float"
+msgstr "E892: String ei käy Floatista"
+
+msgid "E893: Using a List as a Float"
+msgstr "E893: Lista ei käy Floatista"
+
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: Sanakirja ei käy Floatista"
+
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Käytettiin erikoisarvoa Floattina"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Number tai Float vaaditaan"
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "rivi %ld: %s"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Katkaisukohta %s%s rivillä %ld"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s rivi %ld"
+
+# puhutaan merkin ulkoasusta snprintf(..., c, c, c, c)
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, heksana %02x, oktaalina %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, heksana %04x, oktaalina %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, hekdana %08x, oktaalina %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Rivien siirto itsejensä päälle"
+
+msgid "1 line moved"
+msgstr "1 rivi siirretty"
+
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines moved"
+#~ msgstr "%ld riviä siirretty"
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Tiedostoa %s ei voi luoda"
+
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines filtered"
+#~ msgstr "%ld riviä suodatettu"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Filter*-autocommand ei voi vaihtaa puskuria"
+
+msgid "[No write since last change]\n"
+msgstr "[Viimeisintä muutosta ei ole kirjoitettu]\n"
-#: ../ex_cmds.c:2162
msgid "Write partial file?"
msgstr "Kirjoita osittainen tiedosto"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
-msgstr "E140: Käytä !-komentoa osittaisen puskurin kirjoittamiseen"
+msgstr "E140: Käytä !-komentoa osittaisen puskurin kirjoittamiseen"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "Ylikirjoitetaanko olemassaoleva tiedosto %s?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Swap-tiedosto %s on olemassa, ylikirjoitetaanko?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Swap-tiedosto on jo olemassa: %s (komento :silent! ohittaa)"
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Ei tiedostonimeä puskurille %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "E141: No file name for buffer %<PRId64>"
+#~ msgstr "E141: Ei tiedostonimeä puskurille %ld"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr ""
-"E142: Tiedostoa ei kirjoitettu; write-asetus poistaa kirjoituksen käytöstä"
+"E142: Tiedostoa ei kirjoitettu; write-asetus poistaa kirjoituksen käytöstä"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1201,7 +1494,6 @@ msgstr ""
"readonly asetettu tiedostolle \"%s\".\n"
"Kirjoitetaanko?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1210,799 +1502,597 @@ msgid ""
msgstr ""
"Tiedosto %s on kirjoitussuojattu.\n"
"Siihen saattaa voida silti kirjoittaa.\n"
-"Yritetäänkö?"
+"Yritetäänkö?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
+msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
-#: ../ex_cmds.c:3120
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: Autocommand poisti uuden puskurin odotuksen vastaisesti %s"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: :z:n argumentti ei ole numero"
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: Kuoren komennot eivät toimi rvimissä"
+#, fuzzy
+#~ msgid "E145: Shell commands not allowed in restricted mode"
+#~ msgstr "E145: Kuoren komennot eivät toimi rvimissä"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: Säännöllistä ilmausta ei voi rajata kirjaimilla"
+msgstr "E146: Säännöllistä ilmausta ei voi rajata kirjaimilla"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "korvaa kohteella %s (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Keskeytetty)"
-#: ../ex_cmds.c:4384
msgid "1 match"
-msgstr "1 täsmäys"
+msgstr "1 täsmäys"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 korvaus"
-#: ../ex_cmds.c:4387
-#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> täsmäystä"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> matches"
+#~ msgstr "%ld täsmäystä"
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> korvausta"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> substitutions"
+#~ msgstr "%ld korvausta"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
-msgstr " 1 rivillä"
+msgstr " 1 rivillä"
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr " %<PRId64> rivillä"
+#, fuzzy, c-format
+#~ msgid " on %<PRId64> lines"
+#~ msgstr " %ld rivillä"
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
+msgid "E147: Cannot do :global recursive with a range"
msgstr "E147: :globalia ei voi suorittaa rekursiivisesti"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
-msgstr "E148: Säännöllinen ilmaus puuttuu globaalista"
+msgstr "E148: Säännöllinen ilmaus puuttuu globaalista"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
-msgstr "Kuvio löytyi joka riviltä: %s"
+msgstr "Kuvio löytyi joka riviltä: %s"
-#: ../ex_cmds.c:4510
-#, fuzzy, c-format
+#, c-format
msgid "Pattern not found: %s"
-msgstr "Kuviota ei löydy"
-
-#: ../ex_cmds.c:4587
-msgid ""
-"\n"
-"# Last Substitute String:\n"
-"$"
-msgstr ""
-"\n"
-"# Viimeisin korvausmerkkijono:\n"
-"$"
+msgstr "Kuviota ei löydy: %s"
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
-msgstr "E478: Älä panikoi."
+msgstr "E478: Älä panikoi."
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
-msgstr "E661: Sori, ei löydy %s-ohjetta kohteelle %s"
+msgstr "E661: ei löydy %s-ohjetta kohteelle %s"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
-msgstr "E149: Sori, ei löydy ohjetta kohteelle %s"
+msgstr "E149: ei löydy ohjetta kohteelle %s"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
-msgstr "Sori, ohjetiedostoa %s ei löydy"
+msgstr "ohjetiedostoa %s ei löydy"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Ei ole hakemisto: %s"
+msgid "E151: No match: %s"
+msgstr "E151: Ei täsmää: %s"
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: Ei voi avata tiedostoa %s kirjoittamista varten"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: Ei voi avata tiedostoa %s lukemista varten"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
-msgstr "E670: Monia ohjetiedostokoodauksia kielessä: %s"
+msgstr "E670: Monia ohjetiedostokoodauksia kielessä: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
-msgstr "E154: Kaksoiskappale tägistä %s tiedostossa %s/%s"
+msgstr "E154: Kaksoiskappale tägistä %s tiedostossa %s/%s"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ei ole hakemisto: %s"
-#: ../ex_cmds.c:5687
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Tuntematon merkkikomento: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Merkki puuttuu"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
-msgstr "E612: Liikaa merkkejä määritelty"
+msgstr "E612: Liikaa merkkejä määritelty"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Virheellinen merkkiteksti: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Tuntematon merkki: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Merkin numero puuttuu"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Virheellinen puskurin nimi: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Ei voida hypätä puskuriin jolla ei ole nimeä"
+
+#, fuzzy, c-format
+#~ msgid "E157: Invalid sign ID: %<PRId64>"
+#~ msgstr "E157: Virheellinen merkin tunnus: %ld"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: Virheellinen merkin tunnus: %<PRId64>"
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Ei voida muuttaa merkkiä %s"
-#: ../ex_cmds.c:6066
msgid " (not supported)"
msgstr " (ei tuettu)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[Poistettu]"
-#: ../ex_cmds2.c:139
msgid "Entering Debug mode. Type \"cont\" to continue."
-msgstr "Siirrytään vianetsintätilaan, kirjoita cont jatkaaksesi."
+msgstr "Siirrytään vianetsintätilaan, kirjoita cont jatkaaksesi."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
-#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "rivi %<PRId64>: %s"
+#, fuzzy, c-format
+#~ msgid "line %<PRId64>: %s"
+#~ msgstr "rivi %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "kmnt: %s"
-#: ../ex_cmds2.c:322
+msgid "frame is zero"
+msgstr "kehys on nolla"
+
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Katkaisukohta %s%s rivillä %<PRId64>"
+msgid "frame at highest level: %d"
+msgstr "kehys ylimmällä tasolla: %d"
+
+#, fuzzy, c-format
+#~ msgid "Breakpoint in \"%s%s\" line %<PRId64>"
+#~ msgstr "Katkaisukohta %s%s rivillä %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Katkaisukohta puuttuu: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Ei katkaisukohtia"
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s rivi %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "%3d %s %s line %<PRId64>"
+#~ msgstr "%3d %s %s rivi %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: Aloita käskyllä :profile start {fname}"
+msgstr "E750: Aloita käskyllä :profile start {fname}"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Tallennetaanko muutokset tiedostoon %s?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
-msgstr "Nimetön"
+msgstr "Nimetön"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: Muutoksia ei ole kirjoitettu puskurin %s viime muutoksen jälkeen"
+msgstr "E162: Muutoksia ei ole kirjoitettu puskurin %s viime muutoksen jälkeen"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "Varoitus: Puskuri vaihtui odottamatta (tarkista autocommands)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Vain yksi tiedosto muokattavana"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
-msgstr "E164: Ensimmäisen tiedoston ohi ei voi mennä"
+msgstr "E164: Ensimmäisen tiedoston ohi ei voi mennä"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
-msgstr "E165: Viimeisen tiedoston ohi ei voi mennä"
+msgstr "E165: Viimeisen tiedoston ohi ei voi mennä"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
-msgstr "E666: kääntäjää ei tueta: %s"
+msgstr "E666: kääntäjää ei tueta: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
-msgstr "Etsitään ilmausta %s kohteesta %s"
+msgstr "Etsitään ilmausta %s kohteesta %s"
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
-msgstr "Etsitään ilmausta %s"
+msgstr "Etsitään ilmausta %s"
-#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "ei löydy runtimepathista: %s"
+msgid "not found in '%s': \"%s\""
+msgstr "'%s' ei löydy kohteesta: %s"
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "Hakemistoa ei voi ladata: %s"
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "ei voitu ladata %s"
-#: ../ex_cmds2.c:2520
-#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "rivi %<PRId64>: ei voitu ladata %s"
+#, fuzzy, c-format
+#~ msgid "line %<PRId64>: could not source \"%s\""
+#~ msgstr "rivi %ld: ei voitu ladata %s"
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "ladataan %s"
-#: ../ex_cmds2.c:2537
-#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "rivi %<PRId64>: ladataan %s"
+#, fuzzy, c-format
+#~ msgid "line %<PRId64>: sourcing \"%s\""
+#~ msgstr "rivi %ld: ladataan %s"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "ladattu %s"
-#: ../ex_cmds2.c:2765
msgid "modeline"
msgstr "mode-rivi"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "--cmd-argumentti"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "-c-argumentti"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
-msgstr "ympäristömuuttuja"
+msgstr "ympäristömuuttuja"
-#: ../ex_cmds2.c:2773
msgid "error handler"
-msgstr "virhekäsittelin"
+msgstr "virhekäsittelin"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
-msgstr "W15: Varoitus: Väärä rivierotin, ^M saattaa puuttua"
+msgstr "W15: Varoitus: Väärä rivierotin, ^M saattaa puuttua"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding ladatun tiedoston ulkopuolella"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish ladatun tiedoston ulkopuolella"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
-msgstr "Käytössä oleva %skieli: %s"
+msgstr "Käytössä oleva %skieli: %s"
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: Kieleksi ei voitu asettaa kieltä %s"
+msgstr "E197: Kieleksi ei voitu asettaa kieltä %s"
#. don't redisplay the window
#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "Siirrytään Ex-tilaan, kirjoita visual palataksesi normaaliin tilaan."
+msgstr "Siirrytään Ex-tilaan, kirjoita visual palataksesi normaaliin tilaan."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: Tiedoston lopussa"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Liian rekursiivinen komento"
-#: ../ex_docmd.c:1006
+#, fuzzy
+#~ msgid "line %"
+#~ msgstr "rivi %ld"
+
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Kiinniottamaton poikkeus: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Ladatun tiedoston loppu"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Funktion loppu"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
-msgstr "E464: Käyttäjän määrittelemän komennon monimerkityksinen käyttö"
+msgstr "E464: Käyttäjän määrittelemän komennon monimerkityksinen käyttö"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Ei ole editorikomento"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: Takaperoinen arvoalue annettu"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
-msgstr "Takaperoinen arvoalue annettu, OK kääntää"
+msgstr "Takaperoinen arvoalue annettu, OK kääntää"
#. append
#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
-msgstr "E494: Käytä w:tä tai w>>:aa"
+msgstr "E494: Käytä w:tä tai w>>:aa"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: Komento ei ole käytettävissä tässä versiossa"
-
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: Vain yksi tiedostonimi sallitaan"
+#, fuzzy
+#~ msgid "E319: The command is not available in this version"
+#~ msgstr "E319: Komento ei ole käytettävissä tässä versiossa"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
-msgstr "vielä 1 tiedosto muokattavana, lopetaanko silti?"
+msgstr "vielä 1 tiedosto muokattavana, lopetaanko silti?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
-msgstr "vielä %d tiedostoa muokattavana, lopetetaanko silti?"
+msgstr "vielä %d tiedostoa muokattavana, lopetetaanko silti?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
-msgstr "E173: vielä 1 tiedosto muokattavana"
+msgstr "E173: vielä 1 tiedosto muokattavana"
-#: ../ex_docmd.c:4250
-#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: vielä %<PRId64> tiedostoa muokattavana"
+#, fuzzy, c-format
+#~ msgid "E173: %<PRId64> more files to edit"
+#~ msgstr "E173: vielä %ld tiedostoa muokattavana"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
-msgstr "E174: Komento on jo olemassa, käytä !:ä korvataksesi"
+msgstr "E174: Komento on jo olemassa, käytä !:ä korvataksesi"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
-" Name Args Range Complete Definition"
+" Name Args Address Complete Definition"
msgstr ""
"\n"
-" Nimi Arg Arvot Valmis Määritelmä"
+" Nimi Argumentit Osoite Valmis Määritelmä"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
-msgstr "Ei käyttäjän määrittelemiä komentoja"
+msgstr "Ei käyttäjän määrittelemiä komentoja"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
-msgstr "E175: Ei attribuutteja määriteltynä"
+msgstr "E175: Ei attribuutteja määriteltynä"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
-msgstr "E176: Väärä määrä attribuutteja"
+msgstr "E176: Väärä määrä attribuutteja"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
-msgstr "E177: Lukumäärää ei voi määritellä kahdesti"
+msgstr "E177: Lukumäärää ei voi määritellä kahdesti"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
-msgstr "E178: Lukumäärän oletusarvo on väärä"
+msgstr "E178: Lukumäärän oletusarvo on väärä"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: -complete vaatii argumentin"
-#: ../ex_docmd.c:4635
+msgid "E179: argument required for -addr"
+msgstr "E179: -addr vaatii argumentin"
+
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Virheellinen attribuutti: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Virheellinen komennon nimi"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
-msgstr "E183: Käyttäjän määrittelemän komennon pitää alkaa suuraakkosella"
+msgstr "E183: Käyttäjän määrittelemän komennon pitää alkaa suuraakkosella"
-#: ../ex_docmd.c:4696
-#, fuzzy
msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E464: Käyttäjän määrittelemän komennon monimerkityksinen käyttö"
+msgstr "E841: Varattua nimeä ei voi käyttää käyttäjän määrittelemänä komentona"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
-msgstr "E184: Käyttäjän komentoa ei ole olemassa: %s"
+msgstr "E184: Käyttäjän komentoa ei ole olemassa: %s"
+
+#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: Virheellinen osoitetyyppiarvo: %s"
-#: ../ex_docmd.c:5219
#, c-format
msgid "E180: Invalid complete value: %s"
-msgstr "E180: Virheellinen täydennysarvo: %s"
+msgstr "E180: Virheellinen täydennysarvo: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
-msgstr "E468: Täydennysargumentti sopii vain itse määriteltyyn täydennykseen"
+msgstr "E468: Täydennysargumentti sopii vain itse määriteltyyn täydennykseen"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Itse määritelty täydennys vaatii funktioargumentin"
+msgstr "E467: Itse määritelty täydennys vaatii funktioargumentin"
-#: ../ex_docmd.c:5257
-#, fuzzy, c-format
+#, c-format
msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Väriteemaa %s ei löydy"
+msgstr "E185: Väriteemaa %s ei löydy"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
-msgstr "Tervehdys, Vimin käyttäjä."
+msgstr "Tervehdys, Vimin käyttäjä."
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
-msgstr "E784: Viimeistä välilehteä ei voi sulkea"
+msgstr "E784: Viimeistä välilehteä ei voi sulkea"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
-msgstr "Vain yksi välilehti jäljellä enää"
+msgstr "Vain yksi välilehti jäljellä enää"
-#: ../ex_docmd.c:6004
#, c-format
msgid "Tab page %d"
msgstr "Tabisivu %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Ei swap-tiedostoa"
-#: ../ex_docmd.c:6478
-msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
-msgstr ""
-"E747: Hakemistoa ei voida muuttaa, puskuria on muokattu (lisää komentoon ! "
-"ohittaaksesi"
-
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
-msgstr "E186: Ei edellistä hakemistoa"
+msgstr "E186: Ei edellistä hakemistoa"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Tuntematon"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: :winsize vaatii kaksi numeroargumenttia"
-#: ../ex_docmd.c:6655
-msgid "E188: Obtaining window position not implemented for this platform"
-msgstr "E188: Ikkunan sijainnin selvitys ei toimi tällä alustalla"
-
-#: ../ex_docmd.c:6662
-msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos vaatii kaksi lukuargumenttia"
-
-#: ../ex_docmd.c:7241
-#, c-format
-msgid "E739: Cannot create directory: %s"
-msgstr "E739: hakemistoa ei voi luoda: %s"
-
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: %s on jo olemassa (lisää komentoon ! ohittaaksesi)"
+msgstr "E189: %s on jo olemassa (lisää komentoon ! ohittaaksesi)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Tiedostoa %s ei voitu avata kirjoittamista varten"
-#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: Argumentin eteen- tai taaksepäin lainaukseen pitää olla kirjain"
+msgstr "E191: Argumentin eteen- tai taaksepäin lainaukseen pitää olla kirjain"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: :normalin liian syvä rekursio"
+msgstr "E192: :normalin liian syvä rekursio"
-#: ../ex_docmd.c:7807
msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: Ei vaihtoehtoista tiedostonimeä #:lle"
+msgstr "E194: Ei vaihtoehtoista tiedostonimeä #:lle"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: ei autocommand-tiedostoa kohteelle <afile>"
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: ei autocommand-puskurinumeroa kohteelle <abuf>"
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
-msgstr "E497: ei autocommand-täsmäysnimeä kohteella <amatch>"
+msgstr "E497: ei autocommand-täsmäysnimeä kohteella <amatch>"
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
-msgstr "E498: ei :source-tiedostonimeä kohteelle <sfile>"
+msgstr "E498: ei :source-tiedostonimeä kohteelle <sfile>"
-#: ../ex_docmd.c:7876
-#, fuzzy
msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: ei :source-tiedostonimeä kohteelle <sfile>"
+msgstr "E842: ei rivinumeroa kohteelle <slnum>"
-#: ../ex_docmd.c:7903
#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: Tyhjä tiedostonimi kohteissa % tai # toimii vain :p:h"
+#~ msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+#~ msgstr "E499: Tyhjä tiedostonimi kohteissa % tai # toimii vain :p:h"
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
-msgstr "E500: Loppuarvo on tyhjä merkkijono"
-
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: Viminfoa ei voi avata lukemista varten"
+msgstr "E500: Loppuarvo on tyhjä merkkijono"
-#: ../ex_eval.c:464
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: Vim-alkuisia poikkeuksia ei voi heittää :throw-komennolla"
+msgstr "E608: Vim-alkuisia poikkeuksia ei voi heittää :throw-komennolla"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Poikkeus heitetty: %s"
-#: ../ex_eval.c:545
+#. always scroll up, don't overwrite
#, c-format
msgid "Exception finished: %s"
msgstr "Poikkeus lopeteltu: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Poikkeus poistettu: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, rivi %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "%s, line %<PRId64>"
+#~ msgstr "%s, rivi %ld"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Poikkeus otettu kiinni: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s odotutettu"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s palautettu"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s poistettu"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Poikkeus"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Virhe ja keskeytys"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Virhe"
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Keskeytys"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: liian monta kerrosta :if-komennossa"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :endif ilman komentoa :if"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :else ilman komentoa :if"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :elseif ilman komentoa :if"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: :else monta kertaa"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
-msgstr "E584: :elseif komennon :else jälkeen"
+msgstr "E584: :elseif komennon :else jälkeen"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: liian monta tasoa :while- tai :for-komennoissa"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :continue ilman komentoa :while tai :for"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :break ilman komentoa :while tai :for"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: :endfor ilman komentoa :while"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: :endwhile ilman komentoa :for"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: liian monta tasoa :try-komennossa"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :catch ilman komentoa :try"
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :catch ilman komentoa :finally"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :finally ilman komentoa :try"
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: :finally monta kertaa"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :endtry ilman komentoa :try"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: :endfunction funktion ulkopuolella"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: Puskuria ei voi muokata nyt"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: Puskuria ei voi vaihtaa nyt"
-#: ../ex_getln.c:3178
msgid "tagname"
-msgstr "täginimi"
+msgstr "täginimi"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " -tiedostotyyppi\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "history-asetus on nolla"
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s Historia (uusimmasta alkaen):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "Komentorivi"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "Hakujono"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "Ilmaus"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "Syöterivi"
-
-#: ../ex_getln.c:5117
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar komennon pituuden ulkopuolella"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Aktiivinen ikkuna tai puskuri poistettu"
-#: ../file_search.c:203
msgid "E854: path too long for completion"
-msgstr ""
+msgstr "E854: polku on liian pitkä täydennykseen"
-#: ../file_search.c:446
#, c-format
msgid ""
"E343: Invalid path: '**[number]' must be at the end of the path or be "
@@ -2011,376 +2101,295 @@ msgstr ""
"E343: Virheellinen polku: '**[numero]' kuuluu polun loppuun tai ennen kohtaa "
"%s."
-#: ../file_search.c:1505
#, c-format
msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Hakemistoa %s ei löydy cdpathista"
+msgstr "E344: Hakemistoa %s ei löydy cdpathista"
-#: ../file_search.c:1508
#, c-format
msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Tiedostoa %s ei löydy polulta"
+msgstr "E345: Tiedostoa %s ei löydy polulta"
-#: ../file_search.c:1512
#, c-format
msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Hakemisto %s ei ole enää cdpathissa"
+msgstr "E346: Hakemisto %s ei ole enää cdpathissa"
-#: ../file_search.c:1515
#, c-format
msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Tiedosto %s ei ole enää polulla"
+msgstr "E347: Tiedosto %s ei ole enää polulla"
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: Autocommands muutti puskurin tai sen nimen"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Virheellinen tiedostonimi"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "on hakemisto"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "ei ole tiedosto"
-#: ../fileio.c:508 ../fileio.c:3522
msgid "[New File]"
msgstr "[Uusi tiedosto]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[uusi HAKEMISTO]"
-#: ../fileio.c:529 ../fileio.c:532
+#. libuv only returns -errno in Unix and in Windows open() does not
+#. set EOVERFLOW
msgid "[File too big]"
msgstr "[Liian iso tiedosto]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Lupa kielletty]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr ""
-"E200: *ReadPre-autocommand-komennot tekivät tiedostosta lukukelvottoman"
+"E200: *ReadPre-autocommand-komennot tekivät tiedostosta lukukelvottoman"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: *ReadPre-autocommand-komennot eivät saa muuttaa puskuria"
+msgstr "E201: *ReadPre-autocommand-komennot eivät saa muuttaa puskuria"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: Luetaan vakiosyötteestä...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: Muunnos teki tiedostosta lukukelvottoman."
#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[fifo t. soketti]"
#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[fifo]"
#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[soketti]"
#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[merkki erikoinen]"
-# Carriage Return elikkä rivinvaihtomerkin eräs muoto/osa (vrt. LF)
-#: ../fileio.c:1815
+# Carriage Return elikkä rivinvaihtomerkin eräs muoto/osa (vrt. LF)
msgid "[CR missing]"
msgstr "[CR puuttuu]"
-#: ../fileio.c:1819
msgid "[long lines split]"
-msgstr "[pitkät rivit hajotettu]"
+msgstr "[pitkät rivit hajotettu]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[EI muunnettu]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[muunnettu]"
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[MUUNNOSVIRHE rivillä %<PRId64>]"
+#, fuzzy, c-format
+#~ msgid "[CONVERSION ERROR in line %<PRId64>]"
+#~ msgstr "[MUUNNOSVIRHE rivillä %ld]"
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[VIRHEELLINEN OKTETTI rivillä %<PRId64>]"
+#, fuzzy, c-format
+#~ msgid "[ILLEGAL BYTE in line %<PRId64>]"
+#~ msgstr "[VIRHEELLINEN OKTETTI rivillä %ld]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
-msgstr "[LUKUVIRHEITÄ]"
+msgstr "[LUKUVIRHEITÄ]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
-msgstr "Ei voi löytää väliaikaistiedstoa muuntamiseksi"
+msgstr "Ei voi löytää väliaikaistiedstoa muuntamiseksi"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
-msgstr "Muunnos charconvert epäonnistui"
+msgstr "Muunnos charconvert epäonnistui"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "charconvertin tulostetta ei voida lukea"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Ei autocommand-komentoa acwrite-puskurille"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr ""
"E203: Autocommand-komennot poistivat tai vapauttivat puskurin, johon piti "
"kirjoittaa"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: Autocommand-komento muutti rivien määrä odottamatta"
+msgstr "E204: Autocommand-komento muutti rivien määrä odottamatta"
-#: ../fileio.c:2548 ../fileio.c:2565
msgid "is not a file or writable device"
msgstr "ei ole tiedosto tai kirjoitettava laite"
-#: ../fileio.c:2601
msgid "is read-only (add ! to override)"
-msgstr "on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
+msgstr "on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr ""
-"E506: Ei voi kirjoittaa varmuuskopiotiedostoon (lisää komentoon ! "
+"E506: Ei voi kirjoittaa varmuuskopiotiedostoon (lisää komentoon ! "
"ohittaaksesi)"
-#: ../fileio.c:2898
-msgid "E507: Close error for backup file (add ! to override)"
-msgstr ""
-"E507: Varmuuskopiotiedoston sulkeminen ei onnistu (lisää komentoon ! "
-"ohittaaksesi)"
+#, fuzzy, c-format
+#~ msgid "E507: Close error for backup file (add ! to override): %s"
+#~ msgstr ""
+#~ "E507: Varmuuskopiotiedoston sulkeminen ei onnistu (lisää komentoon ! "
+#~ "ohittaaksesi)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr ""
-"E508: Varmuuskopiotiedostoa ei voi lukea (lisää komentoon ! ohittaaksesi)"
+"E508: Varmuuskopiotiedostoa ei voi lukea (lisää komentoon ! ohittaaksesi)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr ""
-"E509: Ei voi luoda varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
+"E509: Ei voi luoda varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr ""
-"E510: Ei voi tehdä varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
+"E510: Ei voi tehdä varmuuskopiotiedostoa (lisää komentoon ! ohittaaksesi)"
#. Can't write without a tempfile!
-#: ../fileio.c:3121
msgid "E214: Can't find temp file for writing"
-msgstr "E214: Ei voi löytää väliaikaistiedostoa kirjoitettavaksi"
+msgstr "E214: Ei voi löytää väliaikaistiedostoa kirjoitettavaksi"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr ""
-"E213: Muunnos ei onnistu (lisää komentoon ! kirjoittaaksesi muuntamatta)"
+"E213: Muunnos ei onnistu (lisää komentoon ! kirjoittaaksesi muuntamatta)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Linkitetyn tiedoston avaus kirjoittamista varten ei onnistu"
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
+#, fuzzy, c-format
+#~ msgid "E212: Can't open file for writing: %s"
+#~ msgstr "E212: Tiedoston avaus kirjoittamista varten ei onnistu"
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: Fsync ei onnistunut"
+#, fuzzy, c-format
+#~ msgid "E667: Fsync failed: %s"
+#~ msgstr "E667: Fsync ei onnistunut"
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Sulkeminen ei onnistunut"
+#, fuzzy, c-format
+#~ msgid "E512: Close failed: %s"
+#~ msgstr "E512: Sulkeminen ei onnistunut"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: kirjoitusvirhe, muunnos epäonnistui (tyhjää fenc ohittaaksesi)"
+msgstr "E513: kirjoitusvirhe, muunnos epäonnistui (tyhjää fenc ohittaaksesi)"
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: kirjoitusvirhe, muunnos epäonnistui rivillä %<PRId64>(tyhjää fenc "
-"ohittaaksesi)"
+#, fuzzy
+#~ msgid "E513: write error, conversion failed in line %"
+#~ msgstr ""
+#~ "E513: kirjoitusvirhe, muunnos epäonnistui rivillä %ld(tyhjää fenc "
+#~ "ohittaaksesi)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
-msgstr "E514: kirjoitusvirhe (tiedostojärjestelmä täysi)"
+msgstr "E514: kirjoitusvirhe (tiedostojärjestelmä täysi)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " MUUNNOSVIRHE"
-#: ../fileio.c:3509
-#, c-format
-msgid " in line %<PRId64>;"
-msgstr " rivillä %<PRId64>"
+#, fuzzy, c-format
+#~ msgid " in line %<PRId64>;"
+#~ msgstr " rivillä %ld"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Laite]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Uusi]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
-msgstr " lisätty"
+msgstr " lisätty"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " kirjoitettu"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Patch-tilassa ei voi tallentaa alkuperäistiedostoa"
+msgstr "E205: Patch-tilassa ei voi tallentaa alkuperäistiedostoa"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: patch-tilassa ei voi muuttaa tyhjää alkuperäistiedostoa"
+msgstr "E206: patch-tilassa ei voi muuttaa tyhjää alkuperäistiedostoa"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Ei voi poistaa varmuuskopiota"
-#: ../fileio.c:3672
+#. Set highlight for error messages.
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
msgstr ""
"\n"
-"VAROITUS: Alkuperäistiedosto voi hävitä tai vahingoittua\n"
+"VAROITUS: Alkuperäistiedosto voi hävitä tai vahingoittua\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
-msgstr "älä lopeta editoria kesken tallentamisen."
+msgstr "älä lopeta editoria kesken tallentamisen."
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[dos-muoto]"
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
+msgid "[dos]"
+msgstr "[dos]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[mac-muoto]"
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
+msgid "[mac]"
+msgstr "[mac]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[unix-muoto]"
-#: ../fileio.c:3831
+msgid "[unix]"
+msgstr "[unix]"
+
msgid "1 line, "
msgstr "1 rivi, "
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> riviä, "
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines, "
+#~ msgstr "%ld riviä, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 merkki"
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> merkkiä"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> characters"
+#~ msgstr "%lld merkkiä"
+
+msgid "[Incomplete last line]"
+msgstr "[Vajaa viimeinen rivi]"
# ei rivinvaihtoja
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[eiriviv.]"
-#: ../fileio.c:3849
-msgid "[Incomplete last line]"
-msgstr "[Vajaa viimeinen rivi]"
-
-# Jos aukiolevaa tiedostoa sörkkii toisella ohjelmalla
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
+# Jos aukiolevaa tiedostoa sörkkii toisella ohjelmalla
+#. Don't overwrite messages here.
+#. Must give this prompt.
+#. Don't use emsg() here, don't want to flush the buffers.
msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "VAROITUS: tiedosto on muuttunut viime lukukerran jälkeen!"
+msgstr "VAROITUS: tiedosto on muuttunut viime lukukerran jälkeen!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "Kirjoitetaanko"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Virhe kirjoitettaessa tiedostoon %s"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Virhe suljettaessa tiedostoa %s"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Virhe luettaessa tiedostoa %s"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: FileChangedShell-autocommand poisti puskurin"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Tiedostoa %s ei ole enää"
+msgstr "E211: Tiedostoa %s ei ole enää"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2389,41 +2398,33 @@ msgstr ""
"W12: Varoitus: Tiedostoa %s on muutettu ja Vimin puskurissa on muutoksia "
"tiedostoon"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
-msgstr ":help W12 kertoo lisätietoja."
+msgstr ":help W12 kertoo lisätietoja."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: Varoitus: Tiedostoa %s on muutettu muokkauksen aloituksen jälkeen"
+msgstr "W11: Varoitus: Tiedostoa %s on muutettu muokkauksen aloituksen jälkeen"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
-msgstr ":help W11 kertoo lisätietoja."
+msgstr ":help W11 kertoo lisätietoja."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr ""
"W16: Varoitus: Tiedoston %s oikeuksia on muutettu muokkauksen aloituksen "
-"jälkeen"
+"jälkeen"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
-msgstr ":help W16 kertoo lisätietoja."
+msgstr ":help W16 kertoo lisätietoja."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: Varoitus: Tiedosto %s on luotu muokkauksen aloituksen jälkeen"
+msgstr "W13: Varoitus: Tiedosto %s on luotu muokkauksen aloituksen jälkeen"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Varoitus"
-# yllä olevien varoitusten ratkaisut
-#: ../fileio.c:4948
+# yllä olevien varoitusten ratkaisut
msgid ""
"&OK\n"
"&Load File"
@@ -2431,816 +2432,657 @@ msgstr ""
"&OK\n"
"&Avaa tiedosto uudelleen"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Ei voitu valmistella uudelleen avausta %s"
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Ei voitu uudelleenavata %s"
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--Poistettu--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "poistetaan autocommand automaattisesti: %s <puskuri=%d>"
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
-msgstr "E367: Ryhmää ei ole: %s"
+msgstr "E367: Ryhmää ei ole: %s"
+
+#, fuzzy
+#~ msgid "E936: Cannot delete the current group"
+#~ msgstr "E351: Taitosta ei voi poistaa tällä foldmethodilla"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: käytössä oleva augroup poistetaan"
-#: ../fileio.c:5897
#, c-format
msgid "E215: Illegal character after *: %s"
-msgstr "E215: Virheellinen merkki *:n jälkeen: %s"
+msgstr "E215: Virheellinen merkki *:n jälkeen: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
-msgstr "E216: Eventtiä ei ole: %s"
+msgstr "E216: Eventtiä ei ole: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
-msgstr "E216: Ryhmää tai eventtiä ei ole: %s"
+msgstr "E216: Ryhmää tai eventtiä ei ole: %s"
-#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Autocommandit ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <puskuri=%d>: virheellinen puskurinumero"
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Ei voi suorittaa autocommandsia kaikille eventeille"
-#: ../fileio.c:6393
msgid "No matching autocommands"
-msgstr "Ei täsmääviä autocommandsia"
+msgstr "Ei täsmääviä autocommandsia"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: liian monta tasoa autocommandissa"
-#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Autocommands kohteelle %s"
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "Suoritetaan %s"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "autocommand %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { puuttuu."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } puuttuu."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: taitos puuttuu"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: Taitoksia ei voi tehdä tällä foldmethodilla"
+msgstr "E350: Taitoksia ei voi tehdä tällä foldmethodilla"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: Taitosta ei voi poistaa tällä foldmethodilla"
+msgstr "E351: Taitosta ei voi poistaa tällä foldmethodilla"
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld riviä taitettu pois "
+#, fuzzy, c-format
+#~ msgid "+--%3ld lines folded "
+#~ msgstr "+--%3ld rivi taitettu pois "
#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
-msgstr "E222: Lisää lukupuskuriin"
+msgstr "E222: Lisää lukupuskuriin"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: rekursiivinen kuvaus"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: globaali lyhenne merkinnälle %s on jo olemassa"
+msgstr "E224: globaali lyhenne merkinnälle %s on jo olemassa"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
-msgstr "E225: globaali kuvaus merkinnälle %s on jo olemassa"
+msgstr "E225: globaali kuvaus merkinnälle %s on jo olemassa"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: lyhenne on jo olemassa %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: kuvaus on jo olemassa %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
-msgstr "Lyhennettä ei löydy"
+msgstr "Lyhennettä ei löydy"
-#: ../getchar.c:3010
msgid "No mapping found"
-msgstr "Kuvausta ei löydy"
+msgstr "Kuvausta ei löydy"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: Virheellinen tila"
#. key value of 'cedit' option
#. type of cmdline window or 0
#. result of cmdline window or 0
-#: ../globals.h:924
msgid "--No lines in buffer--"
-msgstr "--Ei rivejä puskurissa--"
+msgstr "--Ei rivejä puskurissa--"
#.
#. * The error messages that can be shared are included here.
#. * Excluded are errors that are only used once and debugging messages.
#.
-#: ../globals.h:996
msgid "E470: Command aborted"
msgstr "E470: Komento peruttu"
-#: ../globals.h:997
+#, fuzzy
+#~ msgid "E905: Cannot set this option after startup"
+#~ msgstr "E529: Termiä ei voi asettaa tyhjäksi merkkijonoksi"
+
+#, fuzzy
+#~ msgid "E903: Could not spawn API job"
+#~ msgstr "E623: Cscope-prosessin luonti epäonnistui"
+
msgid "E471: Argument required"
msgstr "E471: Argumentti puuttuu"
-#: ../globals.h:998
msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\:n jälkeen pitää tulla /, ? tai &"
+msgstr "E10: \\:n jälkeen pitää tulla /, ? tai &"
-#: ../globals.h:1000
msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
msgstr "E11: Virheellinen komentorivi-ikkuna, <CR> suorittaa, Ctrl C lopettaa"
-#: ../globals.h:1002
msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
msgstr ""
-"E12: Komentoa ei tueta exrc:ssä tai vimrc:ssä tässä hakemistossa tai "
-"tägihaussa"
+"E12: Komentoa ei tueta exrc:ssä tai vimrc:ssä tässä hakemistossa tai "
+"tägihaussa"
-#: ../globals.h:1003
msgid "E171: Missing :endif"
msgstr "E171: :endif puuttuu"
-#: ../globals.h:1004
msgid "E600: Missing :endtry"
msgstr "E600: :endtry puuttuu"
-#: ../globals.h:1005
msgid "E170: Missing :endwhile"
msgstr "E170: :endwhile puuttuu"
-#: ../globals.h:1006
msgid "E170: Missing :endfor"
msgstr "E170: :endfor puuttuu"
-#: ../globals.h:1007
msgid "E588: :endwhile without :while"
msgstr "E588: :endwhile ilman komentoa :while"
-#: ../globals.h:1008
msgid "E588: :endfor without :for"
msgstr "E588: :endfor ilman komentoa :for"
-#: ../globals.h:1009
msgid "E13: File exists (add ! to override)"
-msgstr "E13: Tiedosto on jo olemassa (lisää ! ohittaaksesi)"
+msgstr "E13: Tiedosto on jo olemassa (lisää ! ohittaaksesi)"
-#: ../globals.h:1010
msgid "E472: Command failed"
-msgstr "E472: Komento epäonnistui"
+msgstr "E472: Komento epäonnistui"
-#: ../globals.h:1011
msgid "E473: Internal error"
-msgstr "E473: Sisäinen virhe"
+msgstr "E473: Sisäinen virhe"
-#: ../globals.h:1012
msgid "Interrupted"
msgstr "Keskeytetty"
-#: ../globals.h:1013
msgid "E14: Invalid address"
msgstr "E14: Virheellinen osoite"
-#: ../globals.h:1014
msgid "E474: Invalid argument"
msgstr "E474: Virheellinen argumentti"
-#: ../globals.h:1015
#, c-format
msgid "E475: Invalid argument: %s"
msgstr "E475: Virheellinen argumentti: %s"
-#: ../globals.h:1016
#, c-format
msgid "E15: Invalid expression: %s"
msgstr "E15: Virheellinen ilmaus: %s"
-#: ../globals.h:1017
msgid "E16: Invalid range"
msgstr "E16: Virheellinen arvoalue"
-#: ../globals.h:1018
msgid "E476: Invalid command"
msgstr "E476: Virheellinen komento"
-#: ../globals.h:1019
#, c-format
msgid "E17: \"%s\" is a directory"
msgstr "E17: %s on hakemisto"
-#: ../globals.h:1020
#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Virheellinen vierityskoko"
+#~ msgid "E900: Invalid job id"
+#~ msgstr "E916: ei ole job"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+#~ msgid "E901: Job table is full"
+#~ msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
+#, fuzzy, c-format
+#~ msgid "E903: Process failed to start: %s: \"%s\""
+#~ msgstr "E852: Lapsiprosesi ei voinut käynnistää käyttöliittymää"
+
+#, fuzzy
+#~ msgid "E904: Job is not connected to a pty"
+#~ msgstr "E902: Ei voi yhdistää porttiin"
-#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Kirjastukutsu %s() epäonnistui"
+msgstr "E364: Kirjastukutsu %s() epäonnistui"
+
+#, fuzzy, c-format
+#~ msgid "E739: Cannot create directory %s: %s"
+#~ msgstr "E739: hakemistoa ei voi luoda: %s"
-#: ../globals.h:1026
msgid "E19: Mark has invalid line number"
-msgstr "E19: Merkillä on virheellinen rivinumero"
+msgstr "E19: Merkillä on virheellinen rivinumero"
-#: ../globals.h:1027
msgid "E20: Mark not set"
-msgstr "E20: Merkkiä ei asetettu"
+msgstr "E20: Merkkiä ei asetettu"
-#: ../globals.h:1029
msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Ei voi tehdä muutoksia, modifiable on pois päältä"
+msgstr "E21: Ei voi tehdä muutoksia, modifiable on pois päältä"
-#: ../globals.h:1030
msgid "E22: Scripts nested too deep"
-msgstr "E22: Liian monta tasoa skripteissä"
+msgstr "E22: Liian monta tasoa skripteissä"
-#: ../globals.h:1031
msgid "E23: No alternate file"
msgstr "E23: Eo vaihtoehtoista tiedostoa"
-#: ../globals.h:1032
msgid "E24: No such abbreviation"
-msgstr "E24: Lyhennettä ei ole"
+msgstr "E24: Lyhennettä ei ole"
-#: ../globals.h:1033
msgid "E477: No ! allowed"
msgstr "E477: ! ei sallittu"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUIta ei voi käyttää, koska sitä ei käännetty mukaan"
+#~ msgid "E25: Nvim does not have a built-in GUI"
+#~ msgstr ""
-#: ../globals.h:1036
#, c-format
msgid "E28: No such highlight group name: %s"
-msgstr "E28: Korostusryhmää ei ole nimellä: %s"
+msgstr "E28: Korostusryhmää ei ole nimellä: %s"
-#: ../globals.h:1037
msgid "E29: No inserted text yet"
-msgstr "E29: Tekstiä ei ole syötetty vielä"
+msgstr "E29: Tekstiä ei ole syötetty vielä"
-#: ../globals.h:1038
msgid "E30: No previous command line"
-msgstr "E30: Ei edellistä komentoriviä"
+msgstr "E30: Ei edellistä komentoriviä"
-#: ../globals.h:1039
msgid "E31: No such mapping"
msgstr "E31: Kuvausta ei ole"
-#: ../globals.h:1040
msgid "E479: No match"
-msgstr "E479: Ei täsmää"
+msgstr "E479: Ei täsmää"
-#: ../globals.h:1041
#, c-format
msgid "E480: No match: %s"
-msgstr "E480: Ei tsämää: %s"
+msgstr "E480: Ei tsämää: %s"
-#: ../globals.h:1042
msgid "E32: No file name"
-msgstr "E32: Ei tiedostonimeä"
+msgstr "E32: Ei tiedostonimeä"
-#: ../globals.h:1044
msgid "E33: No previous substitute regular expression"
-msgstr "E33: Ei edellistä korvausta säännölliselle ilmaukselle"
+msgstr "E33: Ei edellistä korvausta säännölliselle ilmaukselle"
-#: ../globals.h:1045
msgid "E34: No previous command"
-msgstr "E34: Ei edellistä komentoa"
+msgstr "E34: Ei edellistä komentoa"
-#: ../globals.h:1046
msgid "E35: No previous regular expression"
-msgstr "E35: Ei edellistä säännöllistä ilmausta"
+msgstr "E35: Ei edellistä säännöllistä ilmausta"
-#: ../globals.h:1047
msgid "E481: No range allowed"
msgstr "E481: Arvoalue ei sallittu"
-#: ../globals.h:1048
msgid "E36: Not enough room"
-msgstr "E36: Tila ei riitä"
-
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Tiedostoa %s ei voi luoda"
+msgstr "E36: Tila ei riitä"
-#: ../globals.h:1050
msgid "E483: Can't get temp file name"
-msgstr "E483: väliaikaistiedoston nimeä ei saada selville"
+msgstr "E483: väliaikaistiedoston nimeä ei saada selville"
-#: ../globals.h:1051
#, c-format
msgid "E484: Can't open file %s"
msgstr "E484: Ei voi avata tiedostoa %s"
-#: ../globals.h:1052
#, c-format
msgid "E485: Can't read file %s"
msgstr "E485: Ei voi lukea tiedostoa %s"
-#: ../globals.h:1054
msgid "E37: No write since last change (add ! to override)"
msgstr ""
-"E37: Viimeisen muutoksen jälkeen ei ole kirjoitettu (lisää ! ohittaaksesi)"
+"E37: Viimeisen muutoksen jälkeen ei ole kirjoitettu (lisää ! ohittaaksesi)"
-#: ../globals.h:1055
-#, fuzzy
msgid "E37: No write since last change"
-msgstr "[Viimeisintä muutosta ei ole kirjoitettu]\n"
+msgstr "E37: Viimeisimmän muutoksen jälkeen ei ole kirjoitettu mitään"
-#: ../globals.h:1056
msgid "E38: Null argument"
msgstr "E38: Null-argumentti"
-#: ../globals.h:1057
msgid "E39: Number expected"
-msgstr "E39: Pitää olla numero"
+msgstr "E39: Pitää olla numero"
-#: ../globals.h:1058
#, c-format
msgid "E40: Can't open errorfile %s"
msgstr "E40: virhetiedostoa %s ei voi avata"
-#: ../globals.h:1059
msgid "E41: Out of memory!"
msgstr "E41: Muisti loppui"
-#: ../globals.h:1060
msgid "Pattern not found"
-msgstr "Kuviota ei löydy"
+msgstr "Kuviota ei löydy"
-#: ../globals.h:1061
#, c-format
msgid "E486: Pattern not found: %s"
-msgstr "E486: Kuviota ei löydy: %s"
+msgstr "E486: Kuviota ei löydy: %s"
-#: ../globals.h:1062
msgid "E487: Argument must be positive"
-msgstr "E487: Argumentin pitää olla positiivinen"
+msgstr "E487: Argumentin pitää olla positiivinen"
-#: ../globals.h:1064
msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Ei voi siirtyä edelliseen hakemistoon"
+msgstr "E459: Ei voi siirtyä edelliseen hakemistoon"
# ;-)
-#: ../globals.h:1066
msgid "E42: No Errors"
-msgstr "E42: Ei virheitä"
+msgstr "E42: Ei virheitä"
-#: ../globals.h:1067
msgid "E776: No location list"
msgstr "E776: Ei sijaintilistaa"
-#: ../globals.h:1068
msgid "E43: Damaged match string"
-msgstr "E43: Viallinen täsmäysmerkkijono"
+msgstr "E43: Viallinen täsmäysmerkkijono"
-#: ../globals.h:1069
msgid "E44: Corrupted regexp program"
msgstr "E44: Viallinen regexp-ohjelma"
-#: ../globals.h:1071
msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: readonly asetettu (lisää ! ohittaaksesi)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Kirjoitussuojattua muuttujaa %s ei voi muuttaa"
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Muuttujaa ei voi asettaa hiekkalaatikossa: %s"
+msgstr "E45: readonly asetettu (lisää ! ohittaaksesi)"
-#: ../globals.h:1076
msgid "E47: Error while reading errorfile"
msgstr "E47: Virhe virhetiedostoa luettaessa"
-#: ../globals.h:1078
msgid "E48: Not allowed in sandbox"
msgstr "E48: Ei sallittu hiekkalaatikossa"
-#: ../globals.h:1080
msgid "E523: Not allowed here"
-msgstr "E523: Ei sallittu täällä"
+msgstr "E523: Ei sallittu täällä"
-#: ../globals.h:1082
msgid "E359: Screen mode setting not supported"
-msgstr "E359: Näyttötila-asetus ei tuettu"
+msgstr "E359: Näyttötila-asetus ei tuettu"
-#: ../globals.h:1083
msgid "E49: Invalid scroll size"
msgstr "E49: Virheellinen vierityskoko"
-#: ../globals.h:1084
msgid "E91: 'shell' option is empty"
-msgstr "E91: shell-asetus on tyhjä"
+msgstr "E91: shell-asetus on tyhjä"
-#: ../globals.h:1085
msgid "E255: Couldn't read in sign data!"
msgstr "E255: Merkkidatan luku ei onnistu"
-#: ../globals.h:1086
msgid "E72: Close error on swap file"
msgstr "E72: Swap-tiedoston sulkemisvirhe"
-#: ../globals.h:1087
msgid "E73: tag stack empty"
-msgstr "E73: tägipino tyhjä"
+msgstr "E73: tägipino tyhjä"
-#: ../globals.h:1088
msgid "E74: Command too complex"
msgstr "E74: Liian monimutkainen komento"
-#: ../globals.h:1089
msgid "E75: Name too long"
-msgstr "E75: Liian pitkä nimi"
+msgstr "E75: Liian pitkä nimi"
-#: ../globals.h:1090
msgid "E76: Too many ["
msgstr "E76: Liian monta [:a"
-#: ../globals.h:1091
msgid "E77: Too many file names"
-msgstr "E77: Liikaa tiedostonimiä"
+msgstr "E77: Liikaa tiedostonimiä"
-#: ../globals.h:1092
msgid "E488: Trailing characters"
-msgstr "E488: Ylimääräisiä merkkejä perässä"
+msgstr "E488: Ylimääräisiä merkkejä perässä"
-#: ../globals.h:1093
msgid "E78: Unknown mark"
msgstr "E78: Tuntematon merkki"
-#: ../globals.h:1094
msgid "E79: Cannot expand wildcards"
msgstr "E79: Jokerimerkkien avaus ei onnistu"
-#: ../globals.h:1096
msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
msgstr "E591: winheight ei voi olla pienempi kuin winminheight"
-#: ../globals.h:1098
msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
msgstr "E592: winwidth ei voi olla pienempi kuin winminwidth"
-#: ../globals.h:1099
msgid "E80: Error while writing"
msgstr "E80: Kirjoitusvirhe"
-#: ../globals.h:1100
msgid "Zero count"
msgstr "Nollalaskuri"
-#: ../globals.h:1101
msgid "E81: Using <SID> not in a script context"
msgstr "E81: <SID> skriptin ulkopuolella"
-#: ../globals.h:1102
#, c-format
msgid "E685: Internal error: %s"
-msgstr "E685: Sisäinen virhe: %s"
+msgstr "E685: Sisäinen virhe: %s"
-#: ../globals.h:1104
msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: kuvio käyttää enemmän muistia kuin maxmempattern on"
+msgstr "E363: kuvio käyttää enemmän muistia kuin maxmempattern on"
-#: ../globals.h:1105
msgid "E749: empty buffer"
-msgstr "E749: tyhjä puskuri"
+msgstr "E749: tyhjä puskuri"
+
+#, fuzzy, c-format
+#~ msgid "E86: Buffer %<PRId64> does not exist"
+#~ msgstr "E86: Puskuria %ld ei ole"
-#: ../globals.h:1108
msgid "E682: Invalid search pattern or delimiter"
msgstr "E682: Virheellinen hakulauseke tai erotin"
-#: ../globals.h:1109
msgid "E139: File is loaded in another buffer"
msgstr "E139: Tiedosto on ladattu toiseen puskuriin"
-#: ../globals.h:1110
#, c-format
msgid "E764: Option '%s' is not set"
msgstr "E764: Asetus %s on asettamatta"
-#: ../globals.h:1111
-#, fuzzy
msgid "E850: Invalid register name"
-msgstr "E354: Virheellinen rekisterin nimi: %s"
+msgstr "E850: Virheellinen rekisterin nimi"
+
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Hakemisto puuttuu kohteesta %s: %s"
+
+msgid "E519: Option not supported"
+msgstr "E519: Asetusta ei tueta"
+
+#, fuzzy
+#~ msgid "E856: Filename too long"
+#~ msgstr "E75: Liian pitkä nimi"
+
+msgid "E806: using Float as a String"
+msgstr "E806: Float ei käy merkkijonosta"
-#: ../globals.h:1114
msgid "search hit TOP, continuing at BOTTOM"
-msgstr "haku pääsi ALKUUN, jatketaan LOPUSTA"
+msgstr "haku pääsi ALKUUN, jatketaan LOPUSTA"
-#: ../globals.h:1115
msgid "search hit BOTTOM, continuing at TOP"
-msgstr "haku pääsi LOPPUUN, jatketaan ALUSTA"
+msgstr "haku pääsi LOPPUUN, jatketaan ALUSTA"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: kaksoispiste puuttuu"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: Virheellinen komponentti"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
-msgstr "E552: pitäisi olla numero"
+msgstr "E552: pitäisi olla numero"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "Sivu %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
-msgstr "Ei tekstiä tulostettavaksi"
+msgstr "Ei tekstiä tulostettavaksi"
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "Tulostetaan sivua %d (%d %%)"
+#, fuzzy, c-format
+#~ msgid "Printing page %d (%zu%%)"
+#~ msgstr "Tulostetaan sivua %d (%d %%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Kopio %d/%d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Tulostettu: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Tulostus peruttu"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
-msgstr "E455: Virhe kirjoitettaessa PostScriptiä tiedostoon"
+msgstr "E455: Virhe kirjoitettaessa PostScriptiä tiedostoon"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Ei voi avata tiedostoa %s"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Ei voi lukea PostScript-resurssitiedostoa %s"
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: tiedosto %s ei ole PostScript-resurssitiedosto"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: tiedosto %s ei ole tuettu PostScript-resurssitiedosto"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: resurssitiedoston %s versio on väärä"
+msgstr "E621: resurssitiedoston %s versio on väärä"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: Tukematon monitvauinen merkistökoodaus ja merkistö."
+msgstr "E673: Tukematon monitvauinen merkistökoodaus ja merkistö."
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: printmbcharset ei voi olla tyhjä monitavuiselle koodaukselle."
+msgstr "E674: printmbcharset ei voi olla tyhjä monitavuiselle koodaukselle."
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Ei oletusfonttia monitavuiseen tulostukseen"
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: PostScript-tulostetiedoston avaus ei onnistu"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Tiedoston %s avaus ei onnistu"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: PostScript-resurssitiedostoa prolog.ps ei löydy"
+msgstr "E456: PostScript-resurssitiedostoa prolog.ps ei löydy"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: PostScript-resurssitiedostoa cidfont.ps ei löydy"
+msgstr "E456: PostScript-resurssitiedostoa cidfont.ps ei löydy"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: Postscript-resurssitiedosta %s.ps ei löydy"
+msgstr "E456: Postscript-resurssitiedosta %s.ps ei löydy"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: Tulostuskoodaukseen %s muunto ei onnistu"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
-msgstr "Lähetetään tulostimelle..."
+msgstr "Lähetetään tulostimelle..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
-msgstr "E365: PostScript-tiedoston tulostus epäonnistui"
+msgstr "E365: PostScript-tiedoston tulostus epäonnistui"
-#: ../hardcopy.c:2883
msgid "Print job sent."
-msgstr "Tulostustyö lähetetty."
+msgstr "Tulostustyö lähetetty."
-#: ../if_cscope.c:85
msgid "Add a new database"
-msgstr "Lisää uusi tietokanta"
+msgstr "Lisää uusi tietokanta"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Hae kuviota"
-#: ../if_cscope.c:89
msgid "Show this message"
-msgstr "Näytä tämä viesti"
+msgstr "Näytä tämä viesti"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Tapa yhteys"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Alusta uudelleen yhteydet"
-#: ../if_cscope.c:95
msgid "Show connections"
-msgstr "Näytä yhteydet"
+msgstr "Näytä yhteydet"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Käyttö: cs[cope] %s"
+msgstr "E560: Käyttö: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
-msgstr "Tämä cscope-komento ei tue ikkunan jakamista.\n"
+msgstr "Tämä cscope-komento ei tue ikkunan jakamista.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Käyttö: cstag <ident>"
+msgstr "E562: Käyttö: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: tägia ei löydy"
+msgstr "E257: cstag: tägia ei löydy"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: stat(%s)-virhe: %d"
-#: ../if_cscope.c:551
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s ei ole hakemisto eikä cscope-tietokanta"
+msgstr "E564: %s ei ole hakemisto eikä cscope-tietokanta"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
-msgstr "Lisätty cscope-tietokanta %s"
+msgstr "Lisätty cscope-tietokanta %s"
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: Virhe luettaessa cscope-yhteyttä %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "E262: error reading cscope connection %<PRIu64>"
+#~ msgstr "E262: Virhe luettaessa cscope-yhteyttä %ld"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: tuntematon cscope-hakutyyppi"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Ei voitu luoda cscope-putkia"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Ei voitu haarauttaa cscopea"
-#: ../if_cscope.c:849
-#, fuzzy
msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection epäonnistui"
+msgstr "cs_create_connection setpgid epäonnistui"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection epäonnistui"
+msgstr "cs_create_connection epäonnistui"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen to_fp epäonnistui"
+msgstr "cs_create_connection: fdopen to_fp epäonnistui"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen fr_fp epäonnistui"
+msgstr "cs_create_connection: fdopen fr_fp epäonnistui"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
-msgstr "E623: Cscope-prosessin luonti epäonnistui"
+msgstr "E623: Cscope-prosessin luonti epäonnistui"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
-msgstr "E567: ei cscope-yhteyksiä"
+msgstr "E567: ei cscope-yhteyksiä"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: virheellinen cscopequickfix-asetus %c kohteelle %c"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: ei täsmäyksiä cscope-hakuun %s/%s"
+msgstr "E259: ei täsmäyksiä cscope-hakuun %s/%s"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "cscope-komennot:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %s%*s (Käyttö: %s)"
+msgstr "%-5s: %s%*s (Käyttö: %s)"
-#: ../if_cscope.c:1155
-#, fuzzy
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"
@@ -3251,40 +3093,35 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
-" c: Etsi tätä funktiota kutsuvat funktiot\n"
-" d: Etsi tämän funktion kutsumat funktiot\n"
-" e: Etsi tämä egrep-lauseke\n"
-" f: Find tämä tiedosto\n"
-" g: Etsi tämä määritys\n"
-" i: Etsi tiedostoja jotka #inkluudaavat tämän\n"
-" s: Etsi tämä C-symboli\n"
+" a: Etsi sijotukset tähän symboliin\n"
+" c: Etsi tätä funktiota kutsuvat funktiot\n"
+" d: Etsi tämän funktion kutsumat funktiot\n"
+" e: Etsi tämä egrep-lauseke\n"
+" f: Etsi tämä tiedosto\n"
+" g: Etsi tämä määritys\n"
+" i: Etsi tiedostoja jotka #inkluudaavat tämän\n"
+" s: Etsi tämä C-symboli\n"
" t: Etsi sijoitukset muuttujaan \n"
-#: ../if_cscope.c:1226
msgid "E568: duplicate cscope database not added"
-msgstr "E568: kaksoiskappaletta cscope-tietokannasta ei lisätty"
+msgstr "E568: kaksoiskappaletta cscope-tietokannasta ei lisätty"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: cscope-yhteys %s puuttuu"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "cscope-yhteys %s on katkaistu"
-#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: kriittinen virhe cs_manage_matches-funktiossa"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
-msgstr "Cscope-tägi: %s"
+msgstr "Cscope-tägi: %s"
-#: ../if_cscope.c:1711
+#. Column headers for match number, line number and filename.
msgid ""
"\n"
" # line"
@@ -3292,326 +3129,270 @@ msgstr ""
"\n"
" # rivi"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "tiedosto / konteksti / rivi\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Cscope-virhe: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Kaikki cscope-tietokannat nollattu"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
-msgstr "ei cscope-yhteyksiä\n"
+msgstr "ei cscope-yhteyksiä\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
-msgstr " # pid tietokanta lisäyspolku\n"
+msgstr " # pid tietokanta lisäyspolku\n"
+
+#. Error messages
+msgid "Argument missing after"
+msgstr "Argumentti puuttuu kohdasta"
+
+msgid "Garbage after option argument"
+msgstr "Roskaa argumentin perässä"
-#: ../main.c:144
msgid "Unknown option argument"
msgstr "Tuntematon asetusargumentti"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "Liikaa muokkausargumentteja"
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "Argumentti puuttuu kohdasta"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "Roskaa argumentin perässä"
-
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "Liikaa +komentoja, -c-komentoja tai --cmd-komentoja"
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "Väärä argumentti valitsimelle"
-
-#: ../main.c:294
-#, c-format
-msgid "%d files to edit\n"
-msgstr "%d tiedostoa muokattavana\n"
-
-#: ../main.c:1342
msgid "Attempt to open script file again: \""
msgstr "Yritettiin avata skriptitiedostoa uudestaan:"
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Ei voi avata luettavaksi: "
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Ei voi avata skriptin tulostetta varten: "
-#: ../main.c:1622
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: Varoitus: Tuloste ei mene terminaalille\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
-msgstr "Vim: Varoitus: Syöte ei tule terminaalilta\n"
+msgstr "Vim: Varoitus: Syöte ei tule terminaalilta\n"
-#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "esi-vimrc-komentorivi"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Ei voida lukea kohteesta %s"
-#: ../main.c:2149
+#, fuzzy
msgid ""
"\n"
-"More info with: \"vim -h\"\n"
+"More info with \""
msgstr ""
"\n"
-"Lisätietoja: \"vim -h\"\n"
+"Lisätietoja: \"vim -h\"\n"
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[tiedosto ..] muokkaa tiedostoja"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- lue vakiosyötteestä"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t tägi muokkaa tiedostoa tägistä"
+#. kill us with CTRL-C here, if you like
+#, fuzzy
+#~ msgid "Usage:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "\n"
+#~ "käyttö:"
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [virhetiedosto] muokkaa tiedostoa ensimmäisestä virheestä"
+#, fuzzy
+#~ msgid " nvim [arguments] [file ...] Edit specified file(s)\n"
+#~ msgstr "[tiedosto ..] muokkaa tiedostoja"
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"käyttö:"
+#, fuzzy
+#~ msgid " nvim [arguments] - Read text from stdin\n"
+#~ msgstr "- lue vakiosyötteestä"
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [argumentit] "
+#, fuzzy
+#~ msgid " nvim [arguments] -t <tag> Edit file where tag is defined\n"
+#~ msgstr "-t tägi muokkaa tiedostoa tägistä"
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" tai:"
+#, fuzzy
+#~ msgid " nvim [arguments] -q [errorfile] Edit file with first error\n"
+#~ msgstr "-q [virhetiedosto] muokkaa tiedostoa ensimmäisestä virheestä"
-#: ../main.c:2196
+#, fuzzy
msgid ""
"\n"
-"\n"
"Arguments:\n"
msgstr ""
"\n"
"\n"
"Argumentit:\n"
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tvain tiedostonimiä tämän jälkeen"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tÄlä käsittele jokerimerkkejä "
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tVi-tila (kuten villä)"
+#, fuzzy
+#~ msgid " -- Only file names after this\n"
+#~ msgstr "--\t\t\tvain tiedostonimiä tämän jälkeen"
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tEx-tila (kute exillä)"
+#, fuzzy
+#~ msgid " --literal Don't expand wildcards\n"
+#~ msgstr "--literal\t\tÄlä käsittele jokerimerkkejä "
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
+#, fuzzy
+#~ msgid " -e Ex mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tHiljainen (eräajo)tila (vain exillä)"
+#, fuzzy
+#~ msgid " -E Improved Ex mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tDiff-tila (kuten vimdiffillä)"
+#, fuzzy
+#~ msgid " -s Silent (batch) mode (only for ex mode)\n"
+#~ msgstr "-s\t\t\tHiljainen (eräajo)tila (vain exillä)"
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tHelppokäyttötila (kuten evimissä, ilman tiloja)"
+#, fuzzy
+#~ msgid " -d Diff mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tKirjoitussuojattu tila (kuten view'lla)"
+#, fuzzy
+#~ msgid " -R Read-only mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tRajoitettu tila (kuten rvimillä)"
+#, fuzzy
+#~ msgid " -Z Restricted mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\tMuokkaukset (kirjoittaminen tiedostoon) pois käytöstä"
+#, fuzzy
+#~ msgid " -m Modifications (writing files) not allowed\n"
+#~ msgstr "-m\t\t\tMuokkaukset (kirjoittaminen tiedostoon) pois käytöstä"
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tTekstin muokkaus pois käytöstä"
+#, fuzzy
+#~ msgid " -M Modifications in text not allowed\n"
+#~ msgstr "-M\t\t\tTekstin muokkaus pois käytöstä"
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tBinääritila"
+#, fuzzy
+#~ msgid " -b Binary mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tLisp-tila"
+#, fuzzy
+#~ msgid " -l Lisp mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tVi-yhteensopivuustila: compatible"
+#, fuzzy
+#~ msgid " -A Arabic mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tEi Vi-yhteensopivuutta: nocompatible"
+#, fuzzy
+#~ msgid " -F Farsi mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr ""
-"-V[N][tnimi]\t\tMonisanainen tuloste [Taso N] [kirjoita tuloste tnimeen] "
+#, fuzzy
+#~ msgid " -H Hebrew mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tVianetsintätila"
+#, fuzzy
+#~ msgid " -V[N][file] Be verbose [level N][log messages to file]\n"
+#~ msgstr ""
+#~ "-V[N][tnimi]\t\tMonisanainen tuloste [Taso N] [kirjoita tuloste tnimeen] "
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tEi swap-tiedostoja, käytä muistia"
+#, fuzzy
+#~ msgid " -D Debugging mode\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tLuetteloi swap-tiedostot ja poistu"
+#, fuzzy
+#~ msgid " -n No swap file, use memory only\n"
+#~ msgstr "-n\t\t\tEi swap-tiedostoja, käytä muistia"
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (tiedostonimi)\tPalauta kaatunut sessio"
+#, fuzzy
+#~ msgid " -r, -L List swap files and exit\n"
+#~ msgstr "-r\t\t\tLuetteloi swap-tiedostot ja poistu"
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tkuten -r"
+#, fuzzy
+#~ msgid " -r <file> Recover crashed session\n"
+#~ msgstr "-r (tiedostonimi)\tPalauta kaatunut sessio"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tkäynnistä arabia-tilassa"
+#, fuzzy
+#~ msgid " -u <vimrc> Use <vimrc> instead of the default\n"
+#~ msgstr "-u <vimrc>\t\tKäytä <vimrc>-tiedostoa .vimrc:iden sijasta"
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tkäynnistä heprea-tilassa"
+#~ msgid " -i <shada> Use <shada> instead of the default\n"
+#~ msgstr ""
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tkäynnistä farsi-tilassa"
+#, fuzzy
+#~ msgid " --noplugin Don't load plugin scripts\n"
+#~ msgstr "--noplugin\t\tÄlä lataa liitännäisiä"
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminaali>\tAseta terminaalin tyypiksi <terminaali>"
+#, fuzzy
+#~ msgid " -o[N] Open N windows (default: one for each file)\n"
+#~ msgstr "-o[N]\t\tAvaa N ikkunaa (oletus: yksi per tiedosto)"
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tKäytä <vimrc>-tiedostoa .vimrc:iden sijasta"
+#, fuzzy
+#~ msgid " -O[N] Like -o but split vertically\n"
+#~ msgstr "-O[N]\t\tKuten -o, mutta jaa pystysuunnassa"
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tÄlä lataa liitännäisiä"
+#, fuzzy
+#~ msgid " -p[N] Open N tab pages (default: one for each file)\n"
+#~ msgstr "-p[N]\t\tAvaa N välilehteä (oletus: yksi per tiedosto)"
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tAvaa N välilehteä (oletus: yksi per tiedosto)"
+#, fuzzy
+#~ msgid " + Start at end of file\n"
+#~ msgstr " kahta tilaa varten "
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\tAvaa N ikkunaa (oletus: yksi per tiedosto)"
+#, fuzzy
+#~ msgid " +<linenum> Start at line <linenum>\n"
+#~ msgstr "+<rivi>\t\t\tAloita riviltä <rivi>"
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tKuten -o, mutta jaa pystysuunnassa"
+#~ msgid " +/<pattern> Start at first occurrence of <pattern>\n"
+#~ msgstr ""
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tAloita tiedoston lopusta"
+#, fuzzy
+#~ msgid " --cmd <command> Execute <command> before loading any vimrc\n"
+#~ msgstr "--cmd <komento>\tSuorita <komento> ennen vimrc:iden latausta"
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<rivi>\t\t\tAloita riviltä <rivi>"
+#, fuzzy
+msgid ""
+" -c <command> Execute <command> after loading the first file\n"
+msgstr "-c <komento>\t\tSuorita <komento> ensimmäisen tiedoston latauduttua"
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <komento>\tSuorita <komento> ennen vimrc:iden latausta"
+#, fuzzy
+#~ msgid " -S <session> Source <session> after loading the first file\n"
+#~ msgstr "-S <sessio>\t\tLataa <sessio> ensimmäisen tiedoston latauduttua"
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <komento>\t\tSuorita <komento> ensimmäisen tiedoston latauduttua"
+#, fuzzy
+#~ msgid " -s <scriptin> Read Normal mode commands from <scriptin>\n"
+#~ msgstr "-s <skripti>\tLue normaalitilan komentoja <skripti>-tiedostosta"
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <sessio>\t\tLataa <sessio> ensimmäisen tiedoston latauduttua"
+#, fuzzy
+#~ msgid " -w <scriptout> Append all typed characters to <scriptout>\n"
+#~ msgstr "-w <skripti>\tLisää kirjoitetut komennot <skripti>-tiedostoon"
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <skripti>\tLue normaalitilan komentoja <skripti>-tiedostosta"
+#, fuzzy
+#~ msgid " -W <scriptout> Write all typed characters to <scriptout>\n"
+#~ msgstr "-W <skripti>\tKirjoita komennot <skripti>-tiedostoon"
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <skripti>\tLisää kirjoitetut komennot <skripti>-tiedostoon"
+#, fuzzy
+#~ msgid " --startuptime <file> Write startup timing messages to <file>\n"
+#~ msgstr "--startuptime <file>\tKirjoita käynnistysaikaviestit tiedostoon <file>"
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <skripti>\tKirjoita komennot <skripti>-tiedostoon"
+#~ msgid ""
+#~ " --api-info Dump API metadata serialized to msgpack and exit\n"
+#~ msgstr ""
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr "--startuptime <file>\tKirjoita käynnistysaikaviestit tiedostoon <file>"
+#~ msgid " --embed Use stdin/stdout as a msgpack-rpc channel\n"
+#~ msgstr ""
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tKäytä <viminfo>-tiedostoa .viminfon sijaan"
+#~ msgid " --headless Don't start a user interface\n"
+#~ msgstr ""
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h tai --help\tTulosta ohje (tämä viesti) ja lopeta"
+#, fuzzy
+#~ msgid " -v, --version Print version information and exit\n"
+#~ msgstr "--version\t\t\tTulosta versiotiedot ja lopeta"
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\t\tTulosta versiotiedot ja lopeta"
+#, fuzzy
+#~ msgid " -h, --help Print this help message and exit\n"
+#~ msgstr "-h tai --help\tTulosta ohje (tämä viesti) ja lopeta"
-#: ../mark.c:676
msgid "No marks set"
-msgstr "Ei asetettuja merkkejä"
+msgstr "Ei asetettuja merkkejä"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
-msgstr "E283: Mikään merkki ei täsmää ilmaukseen \"%s\""
+msgstr "E283: Mikään merkki ei täsmää ilmaukseen \"%s\""
-#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3619,8 +3400,6 @@ msgstr ""
"\n"
"merkki rivi sarake tiedosto/teksti"
-#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3628,8 +3407,6 @@ msgstr ""
"\n"
"hyppy rivi sarake tiedosto/teksti"
-#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3637,138 +3414,84 @@ msgstr ""
"\n"
"muutos rivi sarake teksti"
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Tiedoston merkit:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Hyppylista (uusin ensiksi):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Tiedostojen merkkien historia (uusimmasta vanhimpaan):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "> puuttuu"
-
-#: ../memfile.c:426
msgid "E293: block was not locked"
msgstr "E293: lohkoa ei ole lukittu"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Hakuvirhe swap-tiedostoa luettaessa"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Lukuvirhe swap-tiedostossa"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Hakuvirhe swap-tiedostoa kirjoitettaessa"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Kirjoitusvirhe swap-tiedostossa"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: Swaptiedosto on jo olemassa (symlink-hyökkäys?)"
+msgstr "E300: Swaptiedosto on jo olemassa (symlink-hyökkäys?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Lohko 0:aa ei saatu?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
-msgstr "E298: Lohko 1:tä ei saatu?"
+msgstr "E298: Lohko 1:tä ei saatu?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Lohko 2:ta ei saatu?"
-#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: Hups, swap-tiedosto hävisi!"
+msgstr "E301: Hups, swap-tiedosto hävisi!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Swap-tiedoston uudellennimeys ei onnistu"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: Swap-tiedostoa %s ei voi avata, palautus ei onnistu"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): Lohko 0:aa ei saatu?"
#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Ei swap-tiedostoa tiedostolle %s"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Anna swap-tiedoston numero tai 0 lopettaaksesi: "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Ei voi avata tiedostoa %s"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Ei voi lukea lohkoa 0 kohteesta "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
msgstr ""
"\n"
-"Muutoksia ei tehty, tai Vim ei päivittänyt swap-tiedostoa."
+"Muutoksia ei tehty, tai Vim ei päivittänyt swap-tiedostoa."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
-msgstr " ei toimi tämän version Vimin kanssa.\n"
+msgstr " ei toimi tämän version Vimin kanssa.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
-msgstr "Käytä Vimin versiota 3.0\n"
+msgstr "Käytä Vimin versiota 3.0\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ei ole Vimin swap-tiedosto"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
-msgstr " ei toimi tällä koneella.\n"
+msgstr " ei toimi tällä koneella.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "Tiedosto luotiin "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3776,100 +3499,78 @@ msgstr ""
",\n"
"tai tiedosto on vahingoittunut."
-#: ../memline.c:945
msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr " on vioittunut (sivun koko on vähimmäisarvoa pienempi).\n"
+msgstr " on vioittunut (sivun koko on vähimmäisarvoa pienempi).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
-msgstr "Käytetään swap-tiedostoa %s"
+msgstr "Käytetään swap-tiedostoa %s"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
-msgstr "Alkuperäinen tiedosto %s"
+msgstr "Alkuperäinen tiedosto %s"
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: Varoitus: Alkuperäistä tiedostoa saattaa olla muutettu"
+msgstr "E308: Varoitus: Alkuperäistä tiedostoa saattaa olla muutettu"
-#: ../memline.c:1061
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Ei voitu lukea lohkoa 1 tiedostosta %s"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
-msgstr "???PALJON RIVEJÄ PUUTTUU"
+msgstr "???PALJON RIVEJÄ PUUTTUU"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
-msgstr "???RIVIMÄÄRÄ PIELESSÄ"
+msgstr "???RIVIMÄÄRÄ PIELESSÄ"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
-msgstr "???TYHJÄ LOHKO"
+msgstr "???TYHJÄ LOHKO"
-#: ../memline.c:1103
msgid "???LINES MISSING"
-msgstr "???RIVEJÄ PUUTTUU"
+msgstr "???RIVEJÄ PUUTTUU"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: Lohon 1 tunniste väärä (%s ei ole .swp-tiedosto?)"
+msgstr "E310: Lohon 1 tunniste väärä (%s ei ole .swp-tiedosto?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???LOHKO PUUTTUU"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
-msgstr "??? tästä kohtaan ???LOPPU rivejä sekaisin"
+msgstr "??? tästä kohtaan ???LOPPU rivejä sekaisin"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? tästä kohtaan ???LOPPU rivejä saattaa olla lisätty tai poistettu"
+msgstr "??? tästä kohtaan ???LOPPU rivejä saattaa olla lisätty tai poistettu"
-#: ../memline.c:1181
msgid "???END"
msgstr "???LOPPU"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: Palautus keskeytetty"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr "E312: Palautuksessa oli virheitä, etsi rivejä, jotka alkavat ???"
+msgstr "E312: Palautuksessa oli virheitä, etsi rivejä, jotka alkavat ???"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
-msgstr ":help E312 kertoo lisätietoja"
+msgstr ":help E312 kertoo lisätietoja"
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
-msgstr "Palautus onnistui. Tarkista, että kaikki on kunnossa."
+msgstr "Palautus onnistui. Tarkista, että kaikki on kunnossa."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
msgstr ""
"\n"
-"(Saattaa kannattaa kirjoittaa tämä tiedosto toisella nimellä\n"
+"(Saattaa kannattaa kirjoittaa tämä tiedosto toisella nimellä\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
-msgstr "ja katso diffillä muutokset alkuperäiseen tiedostoon)"
+msgstr "ja katso diffillä muutokset alkuperäiseen tiedostoon)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
-msgstr "Palautus onnistui. Puskurin ja tiedoston sisällöt täsmäävät."
+msgstr "Palautus onnistui. Puskurin ja tiedoston sisällöt täsmäävät."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3879,52 +3580,42 @@ msgstr ""
"Voit poistaa .swp-tiedosto nyt.\n"
"\n"
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
msgid "Swap files found:"
-msgstr "Swap-tiedostoja löytyi:"
+msgstr "Swap-tiedostoja löytyi:"
-#: ../memline.c:1446
msgid " In current directory:\n"
-msgstr " Tässä hakemistossa:\n"
+msgstr " Tässä hakemistossa:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
-msgstr " Määritellyllä nimellä:\n"
+msgstr " Määritellyllä nimellä:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " Hakemistossa "
-#: ../memline.c:1465
msgid " -- none --\n"
-msgstr " -- ei mitään --\n"
+msgstr " -- ei mitään --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " omistaja: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " ajalta: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " ajalta:"
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [Vimin 3.0-versiosta]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
-msgstr " [ei näytä Vimin swap-tiedostolta]"
+msgstr " [ei näytä Vimin swap-tiedostolta]"
+
+#~ msgid " [garbled strings (not nul terminated)]"
+#~ msgstr ""
-#: ../memline.c:1552
msgid " file name: "
msgstr " tiedostonimi: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3932,27 +3623,22 @@ msgstr ""
"\n"
" muokattu: "
-#: ../memline.c:1559
msgid "YES"
-msgstr "KYLLÄ"
+msgstr "KYLLÄ"
-#: ../memline.c:1559
msgid "no"
msgstr "ei"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
msgstr ""
"\n"
-" käyttäjänimi: "
+" käyttäjänimi: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " laitenimi: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3960,7 +3646,6 @@ msgstr ""
"\n"
" laitenimi: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3968,190 +3653,141 @@ msgstr ""
"\n"
" prosessin tunniste: "
-#: ../memline.c:1579
msgid " (still running)"
-msgstr " (käynnissä)"
+msgstr " (käynnissä)"
-#: ../memline.c:1586
msgid ""
"\n"
" [not usable on this computer]"
msgstr ""
"\n"
-" [ei toimi tällä koneella]"
+" [ei toimi tällä koneella]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [ei voi lukea]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [ei voi avata]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: Ei voi säilyttää, swap-tiedostoa ei ole"
+msgstr "E313: Ei voi säilyttää, swap-tiedostoa ei ole"
-#: ../memline.c:1747
msgid "File preserved"
-msgstr "Tiedosto säilytetty"
+msgstr "Tiedosto säilytetty"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
-msgstr "E314: Säilyttäminen epäonnistui"
+msgstr "E314: Säilyttäminen epäonnistui"
-#: ../memline.c:1819
-#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: virheellinen lnum: %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "E315: ml_get: invalid lnum: %<PRId64>"
+#~ msgstr "E315: ml_get: virheellinen lnum: %ld"
-#: ../memline.c:1851
-#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: riviä %<PRId64> ei löydy"
+#, fuzzy, c-format
+#~ msgid "E316: ml_get: cannot find line %<PRId64>"
+#~ msgstr "E316: ml_get: riviä %ld ei löydy"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
-msgstr "E317: osoitinlohkon tunnus väärä 3"
+msgstr "E317: osoitinlohkon tunnus väärä 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
-msgstr "stack_idx pitää olla 0"
+msgstr "stack_idx pitää olla 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
-msgstr "E318: Päivitetty liikaa lohkoja"
+msgstr "E318: Päivitetty liikaa lohkoja"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
-msgstr "E317: osoitinlohkon tunnus väärä 4"
+msgstr "E317: osoitinlohkon tunnus väärä 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "poistettu lohko 1?"
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Riviä %<PRId64> ei löydy"
+#, fuzzy, c-format
+#~ msgid "E320: Cannot find line %<PRId64>"
+#~ msgstr "E320: Riviä %ld ei löydy"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
-msgstr "E317: osoitinlohkon tunnus väärä"
+msgstr "E317: osoitinlohkon tunnus väärä"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count on nolla"
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: rivinumero arvoalueen ulkopuoleta: %<PRId64> on loppua suurempi"
+#, fuzzy, c-format
+#~ msgid "E322: line number out of range: %<PRId64> past the end"
+#~ msgstr "E322: rivinumero arvoalueen ulkopuoleta: %ld on loppua suurempi"
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: rivimäärä väärin lohkossa %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "E323: line count wrong in block %<PRId64>"
+#~ msgstr "E323: rivimäärä väärin lohkossa %ld"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "Pinon koko kasvaa"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
-msgstr "E317: osoitinlohon tunnus väärä 2"
+msgstr "E317: osoitinlohon tunnus väärä 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: Symlinkkisilmukka kohteelle %s"
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: HUOMAA"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
msgstr ""
"\n"
-"Swap-tiedosto löytyi: \""
+"Swap-tiedosto löytyi: \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Avattaessa tiedostoa "
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " joka on UUDEMPI kuin swap-tiedosto!\n"
-#: ../memline.c:3244
-#, fuzzy
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) Toinen ohjelma saattaa käyttää samaa tiedostoa.\n"
-" Jos näin on, varo, ettet muokkaa saman tiedoston\n"
-" kahta instanssia yhtä aikaa.\n"
+"(1) Toinen ohjelma saattaa käyttää samaa tiedostoa.\n"
+" Jos näin on, varo, ettet muokkaa saman tiedoston\n"
+" kahta instanssia yhtä aikaa. Lopeta tai jatka varoen.\n"
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " Lopeta, tai jatka.\n"
-
-#: ../memline.c:3246
-#, fuzzy
msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) Ohjelma on kaatunut muokatessa tiedostoa.\n"
+msgstr "(2) Tiedostonmuokkausistunto on kaatunut.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " Jos näin on, käytä komentoa :recover tai vim -r "
+msgstr " Jos näin on, käytä komentoa :recover tai vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
msgstr ""
"\"\n"
-" palauttaaksesi muutokset (lisätietoja: \":help recovery\").\n"
+" palauttaaksesi muutokset (lisätietoja: \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
-msgstr " Jos teit jo näin, poista swap-tiedosto "
+msgstr " Jos teit jo näin, poista swap-tiedosto "
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
msgstr ""
"\"\n"
-" välttääksesi tämän viestin.\n"
+" välttääksesi tämän viestin.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Swap-tiedosto "
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr " on jo olemassa"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - HUOMAUTUS"
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "Swap-tiedosto on jo olemassa"
-
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4165,7 +3801,6 @@ msgstr ""
"&Lopeta\n"
"P&eru"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4189,48 +3824,45 @@ msgstr ""
#.
#. ".s?a"
#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: Liian monta swap-tiedostoa"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Muisti loppui! (varattaessa %<PRIu64> tavua)"
+#, fuzzy, c-format
+msgid ""
+"E303: Unable to create directory \"%s\" for swap file, recovery impossible: "
+"%s"
+msgstr "E303: Swap-tiedostoa %s ei voi avata, palautus ei onnistu"
+
+#, fuzzy
+#~ msgid "Vim: Data too large to fit into virtual memory space\n"
+#~ msgstr "arvo on liian suuri mahtumaan C:n int-tyyppiin"
+
+#, fuzzy, c-format
+#~ msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
+#~ msgstr "E342: Muisti loppui! (varattaessa %lu tavua)"
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Valikkokohtapolun osa ei ole alivalikko"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Valikko on olemassa vain toisessa tilassa"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Ei valikkoa %s"
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
-msgstr "E792: tyhjä valikkonimi"
+msgstr "E792: tyhjä valikkonimi"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Valikkopolku ei saa johtaa alivalikkoon"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: Valikkokohtia ei saa lisätä suoraan valikkopalkkiin"
+msgstr "E331: Valikkokohtia ei saa lisätä suoraan valikkopalkkiin"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Erotin ei voi olla valikkopolun osa"
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4238,91 +3870,64 @@ msgstr ""
"\n"
"--- Valikot ---"
-#: ../menu.c:1313
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: Valikkopolun on johdettava valikkokohtaan"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
-msgstr "E334: Valikkoa ei löydy: %s"
+msgstr "E334: Valikkoa ei löydy: %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
-msgstr "E335: Valikkoa ei ole määritelty %s-tilassa"
-
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: Valikkopolun pitää johtaa alivalikkoon"
+msgstr "E335: Valikkoa ei ole määritelty %s-tilassa"
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: Valikkoa ei löytynyt - tarkista valikkojen nimet"
-
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Virhe suoritettaessa komentoja %s:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "rivi %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Virheellinen rekisterin nimi: %s"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Käännöksen ylläpitäjä: Flammie Pirinen <flammie@iki.fi>"
-
-#: ../message.c:986
msgid "Interrupt: "
msgstr "Keskeytys: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
-msgstr "Paina enteriä tai kirjoita komento aloittaaksesi "
+msgstr "Paina enteriä tai kirjoita komento aloittaaksesi "
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s rivi %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "%s line %<PRId64>"
+#~ msgstr "%s rivi %ld"
-#: ../message.c:2392
msgid "-- More --"
-msgstr "-- Lisää --"
+msgstr "-- Lisää --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr " SPACE/d/j: ruutu/sivu/rivi alas, b/u/k: ylös, q: lopeta "
+msgstr " SPACE/d/j: ruutu/sivu/rivi alas, b/u/k: ylös, q: lopeta "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Kysymys"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
msgstr ""
-"&Kyllä\n"
+"&Kyllä\n"
"&Ei"
-#: ../message.c:3033
msgid ""
"&Yes\n"
"&No\n"
"&Cancel"
msgstr ""
-"&Kyllä\n"
+"&Kyllä\n"
"&Ei\n"
"&Peru"
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4330,180 +3935,165 @@ msgid ""
"&Discard All\n"
"&Cancel"
msgstr ""
-"&Kyllä\n"
+"&Kyllä\n"
"&Ei\n"
"&Tallenna kaikki\n"
"T&uhoa kaikki\n"
"&Peru"
-#: ../message.c:3058
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: printf():lle ei annettu tarpeeksi argumentteja"
-
-#: ../message.c:3119
-msgid "E807: Expected Float argument for printf()"
-msgstr "E807: Odotettiin Float-argumenttia printf():lle"
-
-#: ../message.c:3873
-msgid "E767: Too many arguments to printf()"
-msgstr "E767: printf():lle annettiin liikaa argumentteja"
-
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Varoitus: Muutetaan kirjoitussuojattua tiedostoa"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr "Kirjoita numero ja <Enter> tai valitse hiirellä (tyhjä peruu): "
+msgstr "Kirjoita numero ja <Enter> tai valitse hiirellä (tyhjä peruu): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
-msgstr "Valitse numero ja <Enter> (tyhjä peruu): "
+msgstr "Valitse numero ja <Enter> (tyhjä peruu): "
-#: ../misc1.c:2585
msgid "1 more line"
-msgstr "1 rivi lisää"
+msgstr "1 rivi lisää"
-#: ../misc1.c:2588
msgid "1 line less"
-msgstr "1 rivi vähemmän"
+msgstr "1 rivi vähemmän"
-#: ../misc1.c:2593
-#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> riviä lisää"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> more lines"
+#~ msgstr "%ld riviä lisää"
-#: ../misc1.c:2596
-#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> riviä vähemmän"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> fewer lines"
+#~ msgstr "%ld riviä vähemmän"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Keskeytetty)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "Piip!"
-#: ../misc2.c:738
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "Kutsutaan kuorta suorittamaan: %s"
-#: ../normal.c:183
+#, c-format
+#~ msgid "Invalid channel: %<PRIu64>"
+#~ msgstr ""
+
+#~ msgid "Message is not an array"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Message is empty"
+#~ msgstr "Viesti"
+
+#~ msgid "Message type must be an integer"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Unknown message type"
+#~ msgstr "E574: Tuntematon rekisterityyppi %d"
+
+#~ msgid "Request array size must be 4 (request) or 3 (notification)"
+#~ msgstr ""
+
+#~ msgid "ID must be a positive integer"
+#~ msgstr ""
+
+#~ msgid "Method must be a string"
+#~ msgstr ""
+
+#, fuzzy
+#~ msgid "Parameters must be an array"
+#~ msgstr "merkin nimen pitää olla yksi merkki"
+
+#.
+#. * 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.
+#.
msgid "E349: No identifier under cursor"
msgstr "E349: Ei tunnistetta osoittimen alla"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
-msgstr "E774: operatorfunc on tyhjä"
+msgstr "E774: operatorfunc on tyhjä"
-#: ../normal.c:2637
msgid "Warning: terminal cannot highlight"
msgstr "Varoitus: terminaalista puuttuu korostus"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Ei merkkijonoa kursorin alla"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: taitoksia ei voi poistaa tällä foldmethodilla"
+msgstr "E352: taitoksia ei voi poistaa tällä foldmethodilla"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
-msgstr "E664: muutoslista on tyhjä"
+msgstr "E664: muutoslista on tyhjä"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Muutoslistan alussa"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Muutoslistan lopussa"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "Komento :quit<Enter> lopettaa Vimin"
+#, fuzzy
+#~ msgid "Type :quit<Enter> to exit Nvim"
+#~ msgstr "Komento :quit<Enter> lopettaa Vimin"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
-msgstr "1 riviä %s kerran"
+msgstr "1 riviä %s kerran"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
-msgstr "1 riviä %s %d kertaa"
+msgstr "1 riviä %s %d kertaa"
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> riviä %s kerran"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines %sed 1 time"
+#~ msgstr "%ld riviä %s kerran"
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> riviä %s %d kertaa"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines %sed %d times"
+#~ msgstr "%ld riviä %s %d kertaa"
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> riviä sisennettävänä..."
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines to indent... "
+#~ msgstr "%ld riviä sisennettävänä..."
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 rivi sisennetty "
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> riviä sisennetty "
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines indented "
+#~ msgstr "%ld riviä sisennetty "
-#: ../ops.c:938
msgid "E748: No previously used register"
-msgstr "E748: Ei aiemmin käytettyjä rekisterejä"
-
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "Ei voi kopioida; poista joka tapauksessa"
+msgstr "E748: Ei aiemmin käytettyjä rekisterejä"
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "1 rivi muuttui"
-#: ../ops.c:1931
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> riviä muuttui"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines changed"
+#~ msgstr "%ld riviä muuttui"
-#: ../ops.c:2521
msgid "block of 1 line yanked"
msgstr "1 rivin lohko kopioitu"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "1 rivi kopioitu"
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "lohko %<PRId64> riviltä kopioitu"
+#, fuzzy, c-format
+#~ msgid "block of %<PRId64> lines yanked"
+#~ msgstr "lohko %ld riviltä kopioitu"
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> riviä kopioitu"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> lines yanked"
+#~ msgstr "%ld riviä kopioitu"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
-msgstr "E353: Rekisterissä %s ei ole mitään"
+msgstr "E353: Rekisterissä %s ei ole mitään"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4511,207 +4101,142 @@ msgstr ""
"\n"
"--- Rekisterit ---"
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "Virheellinen rekisterin nimi"
-
-#: ../ops.c:4533
msgid ""
-"\n"
-"# Registers:\n"
+"E883: search pattern and expression register may not contain two or more "
+"lines"
msgstr ""
-"\n"
-"# Rekisterit:\n"
+"E883: hakulauseke- ja -ilmausrekisteri ei voi sisältää kahta tai useampaa "
+"riviä"
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: Tuntematon rekisterityyppi %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> saraketta, "
+#, fuzzy, c-format
+#~ msgid "%<PRId64> Cols; "
+#~ msgstr "%ld saraketta, "
-#: ../ops.c:5097
-#, c-format
+#, fuzzy, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Valittu %s%<PRId64>/%<PRId64> riviä, %<PRId64>/%<PRId64> sanaa, %<PRId64>/"
-"%<PRId64> tavua"
+msgstr "Valittu %s%ld/%ld riviä, %lld/%lld sanaa, %lld/%lld tavua"
-#: ../ops.c:5105
-#, c-format
+#, fuzzy, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
msgstr ""
-"Valittu %s%<PRId64>/%<PRId64> riviä, %<PRId64>/%<PRId64> sanaa, %<PRId64>/"
-"%<PRId64> merkkiä, %<PRId64>/%<PRId64> tavua"
+"Valittu %s%ld/%ld riviä, %lld/%lld sanaa, %lld/%lld merkkiä, %lld/%lld tavua"
-#: ../ops.c:5123
-#, c-format
+#, fuzzy, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
"%<PRId64> of %<PRId64>"
-msgstr ""
-"Sarake %s/%s, Rivi %<PRId64>/%<PRId64>, sana %<PRId64>/%<PRId64>, tavu "
-"%<PRId64>/%<PRId64>"
+msgstr "Sarake %s/%s, Rivi %ld/%ld, sana %lld/%lld, tavu %lld/%lld"
-#: ../ops.c:5133
-#, c-format
+#, fuzzy, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
msgstr ""
-"Sarake %s/%s, rivi %<PRId64>/%<PRId64>, sana %<PRId64>/%<PRId64>, merkki "
-"%<PRId64>/%<PRId64>, tavu %<PRId64>/%<PRId64>"
+"Sarake %s/%s, rivi %ld/%ld, sana %lld/%lld, merkki %lld/%lld, tavu %lld/%lld"
# Unicode Byte Order Mark
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> BOMista)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Sivu %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "Kiitos että ajoit Vimiä"
+#, fuzzy, c-format
+#~ msgid "(+%<PRId64> for BOM)"
+#~ msgstr "(+%ld BOMista)"
#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Tuntematon asetus"
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: Asetusta ei tueta"
-
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
-msgstr "E520: Ei sallitu modeline-rivillä"
+msgstr "E520: Ei sallitu modeline-rivillä"
-#: ../option.c:2815
msgid "E846: Key code not set"
-msgstr ""
+msgstr "E846: Avainkoodi puuttuu"
-#: ../option.c:2924
msgid "E521: Number required after ="
-msgstr "E521: =:n jälkeen tarvitaan luku"
-
-#: ../option.c:3226 ../option.c:3864
-msgid "E522: Not found in termcap"
-msgstr "E522: Puuttuu termcapista"
+msgstr "E521: =:n jälkeen tarvitaan luku"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Virheellinen merkki <%s>"
-#: ../option.c:3862
-msgid "E529: Cannot set 'term' to empty string"
-msgstr "E529: Termiä ei voi asettaa tyhjäksi merkkijonoksi"
+#, c-format
+msgid "For option %s"
+msgstr "Asetukselle %s"
-#: ../option.c:3885
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: backupext ja patchmod ovat samat"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
msgstr "E834: listcharsin arvoissa on ristiriitoja"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: fillcharsin arvossa on ristiriitoja"
-#: ../option.c:4163
msgid "E524: Missing colon"
msgstr "E524: Kaksoispiste puuttuu"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Nollan pituinen merkkijono"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
-msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
+msgstr "E526: Lukuarvo puuttuu merkkijonon <%s> jälkeen"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Pilkku puuttuu"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
-msgstr "E528: '-arvo pitää antaa"
+msgstr "E528: '-arvo pitää antaa"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
-msgstr "E595: Sisältää tulostumattomia tai leveitä merkkejä"
+msgstr "E595: Sisältää tulostumattomia tai leveitä merkkejä"
-#: ../option.c:4469
#, c-format
msgid "E535: Illegal character after <%c>"
-msgstr "E535: Virheellinen merkki merkin <%c> jälkeen"
+msgstr "E535: Virheellinen merkki merkin <%c> jälkeen"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: pilkku puuttuu"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
-msgstr "E537: commentstringin pitää olla tyhjä tai sisältää %s"
+msgstr "E537: commentstringin pitää olla tyhjä tai sisältää %s"
-#: ../option.c:4928
msgid "E540: Unclosed expression sequence"
msgstr "E540: Sulkematon lausekesarja"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: liikaa kohteita"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
-msgstr "E542: epätasapainoisia ryhmiä"
+msgstr "E542: epätasapainoisia ryhmiä"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: Esikatseluikkuna on jo olemassa"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: Arabialle pitää olla UTF-8:aa, aseta :set encoding=utf-8"
+msgstr "W17: Arabialle pitää olla UTF-8:aa, aseta :set encoding=utf-8"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
-msgstr "E593: Tarvitaan ainakin %d riviä"
+msgstr "E593: Tarvitaan ainakin %d riviä"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Tarvitaan ainakin %d saraketta"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Tuntematon asetus: %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
+#. is empty. In both cases, we are trying to set a
+#. num option using a string.
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: tarvitaan luku: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4719,7 +4244,6 @@ msgstr ""
"\n"
"--- Terminaalikoodit ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4727,7 +4251,6 @@ msgstr ""
"\n"
"--- Globaalit asetukset ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4735,7 +4258,6 @@ msgstr ""
"\n"
"--- Paikalliset asetukset ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4743,29 +4265,24 @@ msgstr ""
"\n"
"--- Asetukset ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: get_varp-virhe"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: langmap: Merkkiin %s täsmäävä merkki puuttuu"
+msgstr "E357: langmap: Merkkiin %s täsmäävä merkki puuttuu"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: langmap: ylimääräisiä merkkejä puolipisteen jälkeen: %s"
+msgstr "E358: langmap: ylimääräisiä merkkejä puolipisteen jälkeen: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Kuoren suoritus ei onnistu "
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = %s"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Virhe luettaessa syötettä, poistutaan...\n"
-#: ../os/shell.c:439
msgid ""
"\n"
"shell returned "
@@ -4773,8 +4290,18 @@ msgstr ""
"\n"
"kuoren palautusarvo "
-# mikä security context?
-#: ../os_unix.c:465 ../os_unix.c:471
+#~ msgid ""
+#~ "\n"
+#~ "shell failed to start: "
+#~ msgstr ""
+
+#. Can happen if system() tries to send input to a shell command that was
+#. backgrounded (:call system("cat - &", "foo")). #3529 #5241
+#, fuzzy, c-format
+#~ msgid "E5677: Error writing input to shell-command: %s"
+#~ msgstr "E677: Väliaikaistiedostoon kirjoittaminen ei onnistunut"
+
+# mikä security context?
msgid ""
"\n"
"Could not get security context for "
@@ -4782,7 +4309,6 @@ msgstr ""
"\n"
"Ei saatu turvallisuuskontekstia kohteelle "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4790,947 +4316,890 @@ msgstr ""
"\n"
"Ei voitu asettaa turvallisuuskontekstia kohteelle "
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = %s"
-
-#: ../path.c:1449
#, c-format
msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Tiedosto %s ei löydy polulta"
+msgstr "E447: Tiedosto %s ei löydy polulta"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: Liikaa %%%c-juttuja muotoilumerkkijonossa"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: Odottamaton %%%c muotoilumerkkijonossa"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: ] puuttuu muotoilemerkkijonosta"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: Tukematon %%%c muotoilumerkkijonossa"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: Virheellinen %%%c muotoilumerkkijonon alussa"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: Virheellinen %%%c muotoilumerkkijonossa"
-#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: errorformatissa ei ole kuvioita"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
-msgstr "E379: Puuttuva tai tyhjä hakemiston nimi"
+msgstr "E379: Puuttuva tai tyhjä hakemiston nimi"
-#: ../quickfix.c:1305
msgid "E553: No more items"
-msgstr "E553: Ei enää kohteita"
+msgstr "E553: Ei enää kohteita"
+
+msgid "E924: Current window was closed"
+msgstr "E924: Nykyinen ikkuna on suljettu"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Nykyinen quickfix on muuttunut"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Nykyinen sijaintiluettelo on muuttunut"
-#: ../quickfix.c:1674
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d/%d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (rivi poistettu)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%svirhelista %d/%d, %d virhettä"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: quickfix-pinon pohjalla"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: quickfix-pinon huipulla"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "virhelista %d/%d, %d virhettä"
+msgid "No entries"
+msgstr "Ei kenttiä"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: Ei voi kirjoittaa, buftype asetettu"
-#: ../quickfix.c:2812
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Tiedostonimi puuttuu tai kuvio on viallinen"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Tiedostoa %s ei voi avata"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: Puskuria ei ole ladattu"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
-msgstr "E777: Pitää olla merkkijono tai lista"
+msgstr "E777: Pitää olla merkkijono tai lista"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: virheellinen olio kohdassa %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
-msgstr "E769: ] puuttuu merkinnän %s[ jäljestä"
+msgstr "E769: ] puuttuu merkinnän %s[ jäljestä"
-#: ../regexp.c:375
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: Pariton %s%%("
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: Pariton %s("
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: Pariton %s)"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( ei ole sallittu tässä"
+msgstr "E66: \\z( ei ole sallittu tässä"
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 jne. ei ole sallittu tässä"
+msgid "E67: \\z1 - \\z9 not allowed here"
+msgstr "E67: \\z1 jne. ei ole sallittu tässä"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
-msgstr "E69: ] puuttuu merkinnän %s%%[ jäljestä"
+msgstr "E69: ] puuttuu merkinnän %s%%[ jäljestä"
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
-msgstr "E70: Tyhjä %s%%[]"
+msgstr "E70: Tyhjä %s%%[]"
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
-msgstr "E339: Liian pitkä kuvio"
+msgstr "E339: Liian pitkä kuvio"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
-msgstr "E50: Liikaa merkkejä \\z("
+msgstr "E50: Liikaa merkkejä \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
-msgstr "E51: Liikaa merkkejä %s("
+msgstr "E51: Liikaa merkkejä %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: Pariton \\z("
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
-msgstr "E59: virheellinen merkki kohdan %s@ jälkeen"
+msgstr "E59: virheellinen merkki kohdan %s@ jälkeen"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Liikaa monimutkaisia ilmauksia %s{...}s"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
-msgstr "E61: Sisäkkäistetty %s*"
+msgstr "E61: Sisäkkäistetty %s*"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
-msgstr "E62: Sisäkkäistetty %s%c"
+msgstr "E62: Sisäkkäistetty %s%c"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
-msgstr "E63: väärinkäytetty \\_"
+msgstr "E63: väärinkäytetty \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c jälkeen ei minkään"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: Virheellinen täsmäysviittaus"
+msgstr "E64: %s%c jälkeen ei minkään"
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
-msgstr "E68: Virheellinen merkki ilmauksen \\z jälkeen"
+msgstr "E68: Virheellinen merkki ilmauksen \\z jälkeen"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: Virheellinen merkki merkinnän %s%%[dxouU] jäljessä"
+msgstr "E678: Virheellinen merkki merkinnän %s%%[dxouU] jäljessä"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
-msgstr "E71: Virheellinen merkki merkinnän %s%% jäljessä"
+msgstr "E71: Virheellinen merkki merkinnän %s%% jäljessä"
+
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (NFA-säänn. ilmaus) ei voi toistaa kohdetta %s"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Syntaksivirhe ilmauksessa %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
-msgstr "Ulkoisia alitäsmäyksiä:\n"
+msgstr "Ulkoisia alitäsmäyksiä:\n"
-#: ../regexp.c:7022
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
msgstr ""
+"E864: \\%#=-merkkien perään voi tulla vain 0, 1 tai 2. Käytetään "
+"automaattista engineä "
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr ""
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-
-#. 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 ""
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
-
-#: ../regexp_nfa.c:2042
-#, fuzzy
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: Liikaa merkkejä \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "Vaihdetaan käyttämään backtrackkaavaa RE-engineä ilmaukselle: "
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr ""
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
-
-#: ../regexp_nfa.c:6049
-#, fuzzy
-msgid "Could not open temporary log file for writing "
-msgstr "E828: Kumoustiedoston avaus kirjoittamista varten ei onnistu: %s"
+#~ msgid " TERMINAL"
+#~ msgstr ""
# tiloja
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " VKORVAUS"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " KORVAUS"
-#: ../screen.c:7440
msgid " REVERSE"
-msgstr " KÄÄNTEIS"
+msgstr " KÄÄNTEIS"
-#: ../screen.c:7441
msgid " INSERT"
-msgstr " SYÖTTÖ"
+msgstr " SYÖTTÖ"
-#: ../screen.c:7443
msgid " (insert)"
-msgstr " (syöttö)"
+msgstr " (syöttö)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (korvaus)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (vkorvaus)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " Heprea"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " Arabia"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (kieli)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (liitos)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " VALINTA"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " VALINTARIVI"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " VALINTALOHKO"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " WALINTA"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " WALINTARIVI"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " WALINTALOHKO"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "tallennetaan"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Viallinen hakujono: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: Haku pääsi alkuun löytämättä jonoa: %s"
+msgstr "E384: Haku pääsi alkuun löytämättä jonoa: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: Haku pääsi loppuun löytämättä jonoa: %s"
+msgstr "E385: Haku pääsi loppuun löytämättä jonoa: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: ;:n jälkeen pitää olla ? tai /"
+msgstr "E386: ;:n jälkeen pitää olla ? tai /"
-#: ../search.c:4085
msgid " (includes previously listed match)"
-msgstr " (sisältää viimeksi luetellun täsmäyksen)"
+msgstr " (sisältää viimeksi luetellun täsmäyksen)"
-#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
-msgstr "--- Sisällytetyt tiedostot "
+msgstr "--- Sisällytetyt tiedostot "
-#: ../search.c:4106
msgid "not found "
-msgstr "ei löytynyt "
+msgstr "ei löytynyt "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "polusta ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Jo lueteltu)"
-#: ../search.c:4170
msgid " NOT FOUND"
-msgstr " EI LÖYTYNYT"
+msgstr " EI LÖYTYNYT"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
-msgstr "Haku sisälsi tiedoston: %s"
+msgstr "Haku sisälsi tiedoston: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
-msgstr "Haku sisälsi tiedoston %s"
+msgstr "Haku sisälsi tiedoston %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
-msgstr "E387: Täsmäys tällä rivillä"
+msgstr "E387: Täsmäys tällä rivillä"
-#: ../search.c:4517
msgid "All included files were found"
-msgstr "Kaikki sisällytetyt rivit löytyivät"
+msgstr "Kaikki sisällytetyt rivit löytyivät"
-#: ../search.c:4519
msgid "No included files"
-msgstr "Ei sisällytettyjä tiedostoja"
+msgstr "Ei sisällytettyjä tiedostoja"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
-msgstr "E388: Määritelmä ei löydy"
+msgstr "E388: Määritelmä ei löydy"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
-msgstr "E389: kuvio ei löydy"
+msgstr "E389: kuvio ei löydy"
+
+#~ msgid "too few bytes read"
+#~ msgstr ""
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Korvaa "
+#, fuzzy, c-format
+#~ msgid "System error while skipping in ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
-#: ../search.c:4681
#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-"\n"
-"# Edellinen %sHakulauseke:\n"
-"~"
+#~ msgid ""
+#~ "Error while reading ShaDa file: last entry specified that it occupies "
+#~ "%<PRIu64> bytes, but file ended earlier"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while closing ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#, fuzzy, c-format
+#~ msgid "System error while writing ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#, fuzzy, c-format
+#~ msgid "Reading ShaDa file \"%s\"%s%s%s"
+#~ msgstr "Luetaan viminfo-tiedostoa \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " info"
+
+msgid " marks"
+msgstr " merkit"
+
+msgid " oldfiles"
+msgstr " vanhaatiedostoa"
+
+msgid " FAILED"
+msgstr " EPÄONNISTUI"
+
+#, c-format
+#~ msgid "System error while opening ShaDa file %s for reading: %s"
+#~ msgstr ""
+
+#~ msgid "additional elements of ShaDa "
+#~ msgstr ""
+
+#~ msgid "additional data of ShaDa "
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Failed to write variable %s"
+#~ msgstr "ei voitu vaihtaa puskuriin %d"
+
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file due to a msgpack parser error at position "
+#~ "%<PRIu64>"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file: incomplete msgpack string at position %<PRIu64>"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Failed to parse ShaDa file: extra bytes in msgpack string at position "
+#~ "%<PRIu64>"
+#~ msgstr ""
+
+#, 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.
+#, c-format
+#~ msgid "E138: All %s.tmp.X files exist, cannot write ShaDa file!"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while opening temporary ShaDa file %s for writing: %s"
+#~ msgstr "Väliaikaislokitiedoston avaus kirjoittamista varten ei onnistu"
+
+#, c-format
+#~ msgid "Failed to create directory %s for writing ShaDa file: %s"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "System error while opening ShaDa file %s for writing: %s"
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "Writing ShaDa file \"%s\""
+#~ msgstr "Kirjoitetaan viminfo-tiedostoa %s"
+
+#, fuzzy, c-format
+#~ msgid "Failed setting uid and gid for file %s: %s"
+#~ msgstr "Ladattu kumoustiedoto %s"
+
+#, fuzzy, c-format
+#~ msgid "E137: ShaDa file is not writable: %s"
+#~ msgstr "E137: Viminfo-tiedostoon ei voitu kirjoittaa: %s"
+
+#, fuzzy, c-format
+#~ msgid "Can't rename ShaDa file from %s to %s!"
+#~ msgstr "E886: Viminfo-tiedostoa ei voit uudelleennimetä nimelle %s"
+
+#, fuzzy, c-format
+#~ msgid "Did not rename %s because %s does not look like a ShaDa file"
+#~ msgstr " [ei näytä Vimin swap-tiedostolta]"
+
+#, c-format
+#~ msgid "Did not rename %s to %s because there were errors during writing it"
+#~ msgstr ""
+
+#, c-format
+#~ msgid "Do not forget to remove %s or rename it manually to %s."
+#~ msgstr ""
+
+#, fuzzy, c-format
+#~ msgid "System error while reading ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#, fuzzy, c-format
+#~ msgid "System error while reading integer from ShaDa file: %s"
+#~ msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Muotoiluvirhe oikolukutiedostossa"
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: expected positive integer at position "
+#~ "%<PRIu64>, but got nothing"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: expected positive integer at position "
+#~ "%<PRIu64>"
+#~ 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.
+#, 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 ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry that is not a dictionary"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry with invalid line number"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry with invalid column number"
+#~ msgstr ""
+
+#, c-format
+#~ msgid ""
+#~ "Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+#~ "entry that does not have a file name"
+#~ msgstr ""
+
+#. values for ts_isdiff
+#. no different byte (yet)
+#. different byte found
+#. inserting character
+#. values for ts_flags
+#. already checked that prefix is OK
+#. tried split at this point
+#. did a delete, "ts_delidx" has index
+#. special values ts_prefixdepth
+#. not using prefixes
+#. walking through the prefix tree
+#. highest value that's not special
+#. 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
+#, fuzzy
+#~ msgid "E759: Format error in spell file"
+#~ msgstr "E297: Kirjoitusvirhe swap-tiedostossa"
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Oikaisuluku ei ole päällä"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Varoitus: Ei löydetty sanalistaa %s.%s.spl tai %s.ascii.spl"
+
+#. This is probably an error. Give a warning and
+#. accept the words anyway.
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Varoitus: osaa %s ei tueta"
+
+msgid "Sorry, no suggestions"
+msgstr "ei ehdotuksia"
+
+#, fuzzy, c-format
+#~ msgid "Sorry, only %<PRId64> suggestions"
+#~ msgstr "vain %ld ehdotusta"
+
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Muuta %.*s:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < %.*s"
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Ei edellistä oikaisulukukorjausta"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Ei löytynyt: %s"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: Oikolukutiedosto katkaistu"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
-msgstr "Tekstiä rivin perässä tiedostossa %s rivillä %d: %s"
+msgstr "Tekstiä rivin perässä tiedostossa %s rivillä %d: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
-msgstr "Affiksin nimi on liian pitkä tiedostossa %s rivillä %d: %s"
+msgstr "Affiksin nimi on liian pitkä tiedostossa %s rivillä %d: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr "E761: Affiksitiedoston FOL-, LOW- tai UPP-muotovirhe "
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
-msgstr "E762: Merkki FOL:ssä, LOW:ssä tai UPP:ssä ei kuulu arvoalueeseen"
+msgstr "E762: Merkki FOL:ssä, LOW:ssä tai UPP:ssä ei kuulu arvoalueeseen"
-#: ../spell.c:958
msgid "Compressing word tree..."
-msgstr "Tiivistetään sanapuuta..."
+msgstr "Tiivistetään sanapuuta..."
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: Oikaisuluku ei ole päällä"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr "Varoitus: Ei löydetty sanalistaa %s.%s.spl tai %s.ascii.spl"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "Luetaan oikaisulukutiedosta %s"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Ei vaikuta oikaisulukutiedostolta"
-#: ../spell.c:2501
+#, fuzzy, c-format
+#~ msgid "E5042: Failed to read spell file %s: %s"
+#~ msgstr "E482: Tiedostoa %s ei voi luoda"
+
msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: Vanha oikaisulukutiedosto vaatii päivittämistä"
+msgstr "E771: Vanha oikaisulukutiedosto vaatii päivittämistä"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Oikaisulukutiedosto on uudemmalle Vimille"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Tukematon osio oikaisulukutiedostossa"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Varoitus: osaa %s ei tueta"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Ei vaikuta .sug-tiedostolta: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Vanha .sug-tiedosto pitää päivittää: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug-tiedosto on uudemmalle Vimille: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug-tiedosto ei täsmää .spl-tiedostoon: %s"
-#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+
+#, c-format
+msgid "Reading affix file %s..."
msgstr "Luetaan affiksitiedostoa %s..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
-msgstr "Muunnosvirhe sanalle %s rivillä %d: %s"
+msgstr "Muunnosvirhe sanalle %s rivillä %d: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "Muunnosta kohteessa %s ei tueta: kohteesta %s kohteeseen %s"
-#: ../spell.c:4642
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "Tuntematon FLAG kohteessa %s rivillä %d: %s"
+msgstr "Tuntematon FLAG kohteessa %s rivillä %d: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
-msgstr "FLAG kohteessa %s lippujen jälkeen rivillä %d: %s"
+msgstr "FLAG kohteessa %s lippujen jälkeen rivillä %d: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
"%d"
msgstr ""
-"COMPOUNDFORBIDFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s "
-"rivillä %d"
+"COMPOUNDFORBIDFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s "
+"rivillä %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
"%d"
msgstr ""
-"COMPOUNDPERMITFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s "
-"rivillä %d"
+"COMPOUNDPERMITFLAG PFX:n jälkeen voi antaa vääriä tuloksia kohteessa %s "
+"rivillä %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "Väärä COMPOUNDRULES-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä COMPOUNDRULES-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "Väärä COMPOUNDWORDMAX-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä COMPOUNDWORDMAX-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "Väärä COMPOUNDMIN-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä COMPOUNDMIN-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "Väärä COMPOUNDSYLMAX-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä COMPOUNDSYLMAX-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "Väärä CHECKCOMPOUNDPATTERN-arvo kohteessa %s rivillä %d: %s"
+msgstr "Väärä CHECKCOMPOUNDPATTERN-arvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
-"Eri yhdistelmälippu jatketussa affiksilohkossa kohteessa %s rivillä %d: %s"
+"Eri yhdistelmälippu jatketussa affiksilohkossa kohteessa %s rivillä %d: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
-msgstr "Kaksoiskappale affiksista kohteessa %s rivillä %d: %s"
+msgstr "Kaksoiskappale affiksista kohteessa %s rivillä %d: %s"
-#: ../spell.c:4871
-#, c-format
+#, fuzzy, c-format
msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGESTin %s "
"line %d: %s"
msgstr ""
-"Affiksia käytetty myös BAD-, RARE-, KEEPCASE-, NEEDAFFIX-, NEEDCOMPOUND- tai "
-"NOSUGGEST-arvossa kohteessa %s rivillä %d: %s"
+"Affiksia käytetty myös BAD-, RARE-, KEEPCASE-, NEEDAFFIX-, NEEDCOMPOUND- tai "
+"NOSUGGEST-arvossa kohteessa %s rivillä %d: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
-msgstr "Odotettiin Y:tä tai N:ää kohteessa %s rivillä %d: %s"
+msgstr "Odotettiin Y:tä tai N:ää kohteessa %s rivillä %d: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
-msgstr "Viallinen ehto kohteessa %s rivillä %d: %s"
+msgstr "Viallinen ehto kohteessa %s rivillä %d: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
-msgstr "Odotettiin REP(SAL)-arvoa kohteessa %s rivillä %d"
+msgstr "Odotettiin REP(SAL)-arvoa kohteessa %s rivillä %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
-msgstr "Odotettiin MAP-arvoa kohteessa %s rivillä %d"
+msgstr "Odotettiin MAP-arvoa kohteessa %s rivillä %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
-msgstr "Kaksoiskappale merkistä MAP:ssä kohteessa %s rivillä %d"
+msgstr "Kaksoiskappale merkistä MAP:ssä kohteessa %s rivillä %d"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
-msgstr "Tunnistamaton tai kaksoiskappale arvosta kohteessa %s rivillä %d: %s"
+msgstr "Tunnistamaton tai kaksoiskappale arvosta kohteessa %s rivillä %d: %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "Puuttuva FOL, LOW tai UPP rivi kohteessa %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "COMPOUNDSYLMAX ilman SYLLABLEa"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
-msgstr "Liikaa jälkikäteistettyjä prefiksejä"
+msgstr "Liikaa jälkikäteistettyjä prefiksejä"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Liikaa yhdyssanalippuja"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
-msgstr "Liikaa jälkikäteistettyjä prefiksejä tai yhdyssanalippuja"
+msgstr "Liikaa jälkikäteistettyjä prefiksejä tai yhdyssanalippuja"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Puuttuva SOFO%s-rivi kohteessa %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "SAL- ja SOFO-rivit kohteessa %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
-msgstr "Lippu ei ole lukuarvo kohteessa %s rivillä %d: %s"
+msgstr "Lippu ei ole lukuarvo kohteessa %s rivillä %d: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
-msgstr "Tuntematon lippu kohteessa %s rivillä %d: %s"
+msgstr "Tuntematon lippu kohteessa %s rivillä %d: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "%s-arvo eroaa toisessa .aff-tiedostossa olevasta"
-#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
+msgid "Reading dictionary file %s..."
msgstr "Luetaan sanakirjatiedostoa %s"
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Ei sanalaskuria kohteessa %s"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "rivi %6d, sana %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
-msgstr "Toistettu sana kohteessa %s rivillä %d: %s"
+msgstr "Toistettu sana kohteessa %s rivillä %d: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
-msgstr "Ensimmäinen kappale kohteessa %s rivillä %d: %s"
+msgstr "Ensimmäinen kappale kohteessa %s rivillä %d: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "toistettuja sanoja %d kohteessa %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "Ei-ASCII-merkkien takia ohitettuja sanoja %d kohteessa %s"
-#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
+msgid "Reading word file %s..."
msgstr "Luetaan sanatiedostoa %s..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "Toistettu /encoding= ohitettu kohteessa %s rivillä %d: %s"
+msgstr "Toistettu /encoding= ohitettu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "/encoding= sanojen jälkeen ohitettu kohteessa %s rivillä %d: %s"
+msgstr "/encoding= sanojen jälkeen ohitettu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "Toistettu /regions= ohitettu kohteessa %s rivillä %d: %s"
+msgstr "Toistettu /regions= ohitettu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
-msgstr "Liikaa regionseja kohteessa %s rivillä %d: %s"
+msgstr "Liikaa regionseja kohteessa %s rivillä %d: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
-msgstr "/ ohitettu kohteessa %s rivillä %d: %s"
+msgstr "/ ohitettu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
-msgstr "Virheellinen region-luku kohteessa %s rivillä %d: %s"
+msgstr "Virheellinen region-luku kohteessa %s rivillä %d: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
-msgstr "Tunnistamaton lippu kohteessa %s rivillä %d: %s"
+msgstr "Tunnistamaton lippu kohteessa %s rivillä %d: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "Ei-ASCIIn takia ohitettuja sanoja %d"
-#: ../spell.c:6656
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "Tiivistetty %d/%d noodia. %d (%d %%) jäljellä"
+msgstr "Tiivistetty %d/%d noodia. %d (%d %%) jäljellä"
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "Luetaan taas oikaisulukutiedostoa..."
#. Go through the trie of good words, soundfold each word and add it to
#. the soundfold trie.
-#: ../spell.c:7357
msgid "Performing soundfolding..."
-msgstr "Ääntämyksen mukaan yhdistellään..."
+msgstr "Ääntämyksen mukaan yhdistellään..."
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Sanoja ääntämysyhdistelyn jälkeen: %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "Number of words after soundfolding: %<PRId64>"
+#~ msgstr "Sanoja ääntämysyhdistelyn jälkeen: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
-msgstr "Sanoja yhteensä: %d"
+msgstr "Sanoja yhteensä: %d"
-#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
+msgid "Writing suggestion file %s..."
msgstr "Kirjoitetaan ehdotustiedostoa %s..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
-msgstr "Arvioitu käyttömuisti: %d tavua"
+msgstr "Arvioitu käyttömuisti: %d tavua"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
-msgstr "E751: Tulostetiedostonimessä ei saa olla alueen nimeä"
+msgstr "E751: Tulostetiedostonimessä ei saa olla alueen nimeä"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
-msgstr "E754: Enintään 8 aluetta tuetaan"
+msgstr "E754: Enintään 8 aluetta tuetaan"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Virheellinen alue kohteelle %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
-msgstr "Varoitus: sekä yhdyssanamuodostus että NOBREAK käytössä"
+msgstr "Varoitus: sekä yhdyssanamuodostus että NOBREAK käytössä"
-#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
+msgid "Writing spell file %s..."
msgstr "Kirjoitetaan oikaisulukutiedostoa %s..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Valmista."
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: spellfile ei sisällä %<PRId64> kohtaa"
-
-#: ../spell.c:8074
-#, fuzzy, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "Sana poistettu kohteesta %s"
-
-#: ../spell.c:8117
#, fuzzy, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "Sana lisätty kohteeseen %s"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: Sanan merkit muuttuvat oikaisulukutiedostojen välillä"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Sori, ei ehdotuksia"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Sori, vain %<PRId64> ehdotusta"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Muuta %.*s:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < %.*s"
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Ei edellistä oikaisulukukorjausta"
+#~ msgid "E765: 'spellfile' does not have %<PRId64> entries"
+#~ msgstr "E765: spellfile ei sisällä %ld kohtaa"
-#: ../spell.c:8925
#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Ei löytynyt: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Ei vaikuta .sug-tiedostolta: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Vanha .sug-tiedosto pitää päivittää: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: .sug-tiedosto on uudemmalle Vimille: %s"
+msgid "Word '%.*s' removed from %s"
+msgstr "Sana %.*s poistettu kohteesta %s"
-#: ../spell.c:9295
#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: .sug-tiedosto ei täsmää .spl-tiedostoon: %s"
+msgid "Word '%.*s' added to %s"
+msgstr "Sana %.*s lisätty kohteeseen %s"
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: virhe luettaessa .sug-tiedostoa: %s"
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Sanan merkit muuttuvat oikaisulukutiedostojen välillä"
#. This should have been checked when generating the .spl
#. file.
-#: ../spell.c:11575
msgid "E783: duplicate char in MAP entry"
-msgstr "E783: kaksoiskappale merkistä MAP-kohdassa"
+msgstr "E783: kaksoiskappale merkistä MAP-kohdassa"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: printf():lle ei annettu tarpeeksi argumentteja"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Odotettiin Float-argumenttia printf():lle"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: printf():lle annettiin liikaa argumentteja"
-#: ../syntax.c:266
msgid "No Syntax items defined for this buffer"
-msgstr "Ei syntaksikohteita tälle puskurille"
+msgstr "Ei syntaksikohteita tälle puskurille"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
#, c-format
msgid "E390: Illegal argument: %s"
msgstr "E390: Virheellinen argumentti: %s"
-#: ../syntax.c:3299
+msgid "syntax iskeyword "
+msgstr "syntax iskeyword "
+
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Syntaksiklusteri puuttuu: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "synkkaa C-tyylin kommentteihin"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "ei synkkausta"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "synkkaus aloitettu "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
-msgstr " riviä ennen alkua"
+msgstr " riviä ennen alkua"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5738,7 +5207,6 @@ msgstr ""
"\n"
"--- Syntax sync -kohteet ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5746,7 +5214,6 @@ msgstr ""
"\n"
"synkataan kohteisiin"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5754,2314 +5221,2496 @@ msgstr ""
"\n"
"--- Syntax-kohteet ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: syntaksiklusteria ei ole: %s"
-#: ../syntax.c:3497
msgid "minimal "
-msgstr "vähintään "
+msgstr "vähintään "
-#: ../syntax.c:3503
msgid "maximal "
-msgstr "enitntään "
+msgstr "enitntään "
-#: ../syntax.c:3513
msgid "; match "
-msgstr "; täsmää "
+msgstr "; täsmää "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " rivinvaihdot"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
-msgstr "E395: contains ei sovi tähän"
+msgstr "E395: contains ei sovi tähän"
-#: ../syntax.c:4096
-#, fuzzy
msgid "E844: invalid cchar value"
-msgstr "E474: Virheellinen argumentti"
+msgstr "E844: Virheellinen cchar-arvo"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
-msgstr "E393: group[t]here ei sovi tähän"
+msgstr "E393: group[t]here ei sovi tähän"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
-msgstr "E394: Aluetta nimelle %s ei löydy"
+msgstr "E394: Aluetta nimelle %s ei löydy"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Tiedostonimi puuttuu"
-#: ../syntax.c:4221
-#, fuzzy
msgid "E847: Too many syntax includes"
-msgstr "E77: Liikaa tiedostonimiä"
+msgstr "E847: Liikaa syntax includeja"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ] puuttuu: %s"
-#: ../syntax.c:4531
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: Ylimääräisiä merkkejä merkin ] perässä: %s]%s"
+
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: = puuttuu: %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Argumentteja puuttuu: syntaksialue %s"
-#: ../syntax.c:4870
-#, fuzzy
msgid "E848: Too many syntax clusters"
-msgstr "E391: Syntaksiklusteri puuttuu: %s"
+msgstr "E848: Liikaa syntaksiklustereita"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
-msgstr "E400: klusteri määrittelemättä"
+msgstr "E400: klusteri määrittelemättä"
#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Kuvoin erotin puuttuu: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
-msgstr "E402: Roskia kuvion jäljessä: %s"
+msgstr "E402: Roskia kuvion jäljessä: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: syntax sync: rivinjatkamiskuvio määritelty kahdesti"
+msgstr "E403: syntax sync: rivinjatkamiskuvio määritelty kahdesti"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Virheelliset argumentit: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: = puuttuu: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
-msgstr "E406: Tyhjä argumentti: %s"
+msgstr "E406: Tyhjä argumentti: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
-msgstr "E407: %s ei sovi tähän"
+msgstr "E407: %s ei sovi tähän"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s kuuluu contains-listan alkuun"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
-msgstr "E409: Tuntematon ryhmän nimi: %s"
+msgstr "E409: Tuntematon ryhmän nimi: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Virheelluinen :syntax-osakomento: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
+" KAIKKI MÄÄRÄ TÄSMÄYS HITAIN KEKSIARVO NIMI ILMAUS"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
-msgstr "E679: rekursiivinen silmukka syncolor.vimissä"
+msgstr "E679: rekursiivinen silmukka syncolor.vimissä"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
-msgstr "E411: korostusryhmää ei löytynyt: %s"
+msgstr "E411: korostusryhmää ei löytynyt: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Argumentteja puuttuu: :highlight link %s"
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: Liikaa argumentteja: :highlight link %s"
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
-msgstr "E414: ryhmällä on asetuksia, highlight link -komento ohitetaan"
+msgstr "E414: ryhmällä on asetuksia, highlight link -komento ohitetaan"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: odotuksenvastainen =-merkki: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: puuttuva =-merkki: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: puuttuva argumentti: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Viallinen arvo: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
-msgstr "E419: edustaväri tuntematon"
+msgstr "E419: edustaväri tuntematon"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
-msgstr "E420: taustaväri tuntematon"
+msgstr "E420: taustaväri tuntematon"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
-msgstr "E421: Värin nimi tai numero tuntematon: %s"
+msgstr "E421: Värin nimi tai numero tuntematon: %s"
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: terminaalikoodi liian pitkä: %s"
-
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Virheellinen argumentti: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: Liikaa eri korostusattribuutteja"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
-msgstr "E669: Tulostuskelvoton merkki ryhmän nimessä"
+msgstr "E669: Tulostuskelvoton merkki ryhmän nimessä"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
-msgstr "W18: Virheellinen merkki ryhmän nimessä"
+msgstr "W18: Virheellinen merkki ryhmän nimessä"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
-msgstr ""
+msgstr "E849: Liikaa korostuksia ja syntaksiryhmiä"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
-msgstr "E555: tägipinon pohja"
+msgstr "E555: tägipinon pohja"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
-msgstr "E556: tägipinon huippu"
+msgstr "E556: tägipinon huippu"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Ei voida mennä ensimmäistä täsmäävää tägiä alummaksi"
+msgstr "E425: Ei voida mennä ensimmäistä täsmäävää tägiä alummaksi"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
-msgstr "E426: tägi puuttuu: %s"
+msgstr "E426: tägi puuttuu: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
-msgstr " # arvo tyyppi tägi"
+msgstr " # arvo tyyppi tägi"
-#: ../tag.c:531
msgid "file\n"
msgstr "tiedosto\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
-msgstr "E427: Vain yksi tägi täsmää"
+msgstr "E427: Vain yksi tägi täsmää"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: Ei voida edetä viimeisen täsmäävän tägin ohi"
+msgstr "E428: Ei voida edetä viimeisen täsmäävän tägin ohi"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "Tiedostoa %s ei ole"
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
-msgstr "tägi %d/%d%s"
+msgstr "tägi %d/%d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " tai useammasta"
-#: ../tag.c:864
msgid " Using tag with different case!"
-msgstr " Tägissä eri kirjaintaso"
+msgstr " Tägissä eri kirjaintaso"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Tiedostoa %s ei ole"
-#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
msgstr ""
"\n"
-" # TILL tagg FRÅN LINJE i fil/text"
+" # TILL tagg FRÃ…N LINJE i fil/text"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
-msgstr "Etsitään tägitiedostoa %s"
+msgstr "Etsitään tägitiedostoa %s"
-#: ../tag.c:1545
msgid "Ignoring long line in tags file"
-msgstr "Ohitetaan pitkä rivi tägitiedostossa"
+msgstr "Ohitetaan pitkä rivi tägitiedostossa"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: Muotovirh tägitiedostossa %s"
+msgstr "E431: Muotovirh tägitiedostossa %s"
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Ennen tavua %<PRId64>"
+#, fuzzy, c-format
+#~ msgid "Before byte %<PRId64>"
+#~ msgstr "Ennen tavua %ld"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Tägitiedosto ei ole järjestetty: %s"
+msgstr "E432: Tägitiedosto ei ole järjestetty: %s"
-#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
-msgstr "E433: Ei tägitiedostoja"
+msgstr "E433: Ei tägitiedostoja"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
-msgstr "E434: Tägikuviota ei löydy"
+msgstr "E434: Tägikuviota ei löydy"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: Tägiä ei löydy, arvataan."
+msgstr "E435: Tägiä ei löydy, arvataan."
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
-msgstr "Kaksoiskappale kentän nimestä: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr " ei tunnettu. Tuetut terminaalit:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "oletusarvona "
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: Ei voi avata termcap-tiedostoa"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: Terminaalia ei löytynyt terminfosta"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: Terminaalia ei löytynyt termcapista"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: %s ei löytynyt termcapista"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: terminaalilla pitää olla cm kyvyissään"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Terminaalinäppäimet ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: Virhe luettaessa syötettä, poistutaan...\n"
+msgstr "Kaksoiskappale kentän nimestä: %s"
#. This happens when the FileChangedRO autocommand changes the
#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Rivimäärä vaihtui odottamatta"
+msgstr "E881: Rivimäärä vaihtui odottamatta"
-#: ../undo.c:627
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: Kumoustiedoston avaus kirjoittamista varten ei onnistu: %s"
-#: ../undo.c:717
+#, fuzzy, c-format
+#~ msgid "E5003: Unable to create directory \"%s\" for undo file: %s"
+#~ msgstr "E346: Hakemisto %s ei ole enää cdpathissa"
+
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: Pilaanntunut kumoustiedosto (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr "Ei voitu lukea kumoustiedostoa mistään undodir-muuttujan hakemistosta"
+msgstr "Ei voitu lukea kumoustiedostoa mistään undodir-muuttujan hakemistosta"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "Ei ylikirjoitetat kumoustiedostolla, koska ei voida lukea: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
-msgstr "Ei ylikirjoiteta, koska tämä ei ole kumoustiedosto: %s"
+msgstr "Ei ylikirjoiteta, koska tämä ei ole kumoustiedosto: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Ohitetaan kumoustiedoston kirjoitus, koska ei ole peruutettavia"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "Kirjoitetaan kumoustiedostoa: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: Kirjoitusvirhe kumoustiedostossa: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "Ei lueta kumoustiedosto jonka omistaja on eri: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "Luetaan kumoustiedostoa: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: Kumoustiedostoa ei voi avata lukemista varten: %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: Ei ole kumoustiedosto: %s"
-#: ../undo.c:1313
#, c-format
msgid "E824: Incompatible undo file: %s"
-msgstr "E824: Epäyhteensopiva kumoustiedosto: %s"
+msgstr "E824: Epäyhteensopiva kumoustiedosto: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr ""
-"Tiedoston sisältö on muuttunut, joen kumoustiedot ovat käyttökelvottomia"
+"Tiedoston sisältö on muuttunut, joen kumoustiedot ovat käyttökelvottomia"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "Ladattu kumoustiedoto %s"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Vanhimmassa muutoksessa"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Nuorimmassa muutoksessa"
-#: ../undo.c:1806
-#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Kumouslukua %<PRId64> ei löydy"
+#, fuzzy, c-format
+#~ msgid "E830: Undo number %<PRId64> not found"
+#~ msgstr "E830: Kumouslukua %ld ei löydy"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: väärät rivinumerot"
+msgstr "E438: u_undo: väärät rivinumerot"
-#: ../undo.c:2183
msgid "more line"
-msgstr "rivi lisää"
+msgstr "rivi lisää"
-#: ../undo.c:2185
msgid "more lines"
-msgstr "riviä lisää"
+msgstr "riviä lisää"
-#: ../undo.c:2187
msgid "line less"
-msgstr "rivi vähemmän"
+msgstr "rivi vähemmän"
-#: ../undo.c:2189
msgid "fewer lines"
-msgstr "riviä vähemmän"
+msgstr "riviä vähemmän"
-#: ../undo.c:2193
msgid "change"
msgstr "muutos"
-#: ../undo.c:2195
msgid "changes"
msgstr "muutosta"
-# eka %s yläpuolelta, toka %s alapuolelta, kolmas %s aika
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s, %s #%<PRId64> %s"
+# eka %s yläpuolelta, toka %s alapuolelta, kolmas %s aika
+#, fuzzy, c-format
+#~ msgid "%<PRId64> %s; %s #%<PRId64> %s"
+#~ msgstr "%ld %s, %s #%ld %s"
+
+msgid "after"
+msgstr "jälkeen muutoksen"
-#: ../undo.c:2228
msgid "before"
msgstr "ennen muutosta"
-#: ../undo.c:2228
-msgid "after"
-msgstr "jälkeen muutoksen"
-
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "Ei kumottavaa"
-#: ../undo.c:2330
-#, fuzzy
msgid "number changes when saved"
-msgstr "muutoksia aika tallennettu"
+msgstr "numero muutoksia aika tallennettu"
-#: ../undo.c:2360
-#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> sekuntia sitten"
+#, fuzzy, c-format
+#~ msgid "%<PRId64> seconds ago"
+#~ msgstr "%ld sekuntia sitten"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
-msgstr "E790: undojoin ei toimi undon jälkeen"
+msgstr "E790: undojoin ei toimi undon jälkeen"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: kumouslista rikki"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: kumousrivi puuttuu"
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Pätsit: "
-
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
msgstr ""
"\n"
-"Muita pätsejä: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Muokannut "
+"Muita pätsejä: "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
msgstr ""
"\n"
-"Kääntänyt "
+"Kääntänyt "
-#: ../version.c:649
msgid "by "
msgstr ": "
-#: ../version.c:660
+#, fuzzy
msgid ""
"\n"
-"Huge version "
-msgstr ""
"\n"
-"Huge-versio "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "ilman GUIta."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
+"Optional features included (+) or not (-): "
msgstr " Ominaisuudet mukana (+) ja poissa (-):\n"
-#: ../version.c:667
msgid " system vimrc file: \""
-msgstr " järjestelmän vimrc: \""
-
-#: ../version.c:672
-msgid " user vimrc file: \""
-msgstr " käyttäjän vimrc: \""
-
-#: ../version.c:677
-msgid " 2nd user vimrc file: \""
-msgstr " 2. käyttäjän vimrc: \""
+msgstr " järjestelmän vimrc: \""
-#: ../version.c:682
-msgid " 3rd user vimrc file: \""
-msgstr " 3. käyttäjän vimrc: \""
-
-#: ../version.c:687
-msgid " user exrc file: \""
-msgstr " käyttäjän exrc: \""
-
-#: ../version.c:692
-msgid " 2nd user exrc file: \""
-msgstr " 2. käyttäjän exrc: \""
-
-#: ../version.c:699
msgid " fall-back for $VIM: \""
msgstr " $VIMin fallback: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " $VIMRUNTIMEn f-b: \""
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "Käännös: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Linkitys: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " DEBUG-versio"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi IMproved"
-
-#: ../version.c:769
-msgid "version "
-msgstr "versio "
-
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
-msgstr "tekijät Bram Moolenaar et al."
+msgstr "tekijät Bram Moolenaar et al."
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim on avointa lähdekoodia ja vapaasti jaossa"
+#, fuzzy
+#~ msgid "Nvim is open source and freely distributable"
+#~ msgstr "Vim on avointa lähdekoodia ja vapaasti jaossa"
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "Auta Ugandan köyhiä lapsia"
+#~ msgid "https://neovim.io/community"
+#~ msgstr ""
-#: ../version.c:777
-msgid "type :help iccf<Enter> for information "
-msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
+#, fuzzy
+#~ msgid "type :help nvim<Enter> if you are new! "
+#~ msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
+
+#, fuzzy
+#~ msgid "type :CheckHealth<Enter> to optimize Nvim"
+#~ msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "kirjoita :q<Enter> lopettaaksesi "
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "kirjoita :help<Enter> tai <F1> ohjetta varten "
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "kirjoita :help version7<Enter> versiotietoja varten "
-
-#: ../version.c:784
-msgid "Running in Vi compatible mode"
-msgstr "Suoritetaan Vi-yhteensopivuustilaa"
+#, fuzzy
+#~ msgid "type :help<Enter> for help "
+#~ msgstr "kirjoita :q<Enter> lopettaaksesi "
-#: ../version.c:785
-msgid "type :set nocp<Enter> for Vim defaults"
-msgstr "kirjoita :set nocp<Enter> Vimin oletuksiin "
+msgid "Help poor children in Uganda!"
+msgstr "Auta Ugandan köyhiä lapsia"
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "kirjoita :help cp-default<Enter> ohjetta oletuksista varten"
+msgid "type :help iccf<Enter> for information "
+msgstr "kirjoita :help iccf<Enter> lisätietoa varten "
-#: ../version.c:827
msgid "Sponsor Vim development!"
-msgstr "Tue Vimin kehitystä"
+msgstr "Tue Vimin kehitystä"
-#: ../version.c:828
msgid "Become a registered Vim user!"
-msgstr "Rekisteröidy Vim-käyttäjäksi."
+msgstr "Rekisteröidy Vim-käyttäjäksi."
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
-msgstr "kirjoita :help sponsor<Enter> lisätietoja varten"
+msgstr "kirjoita :help sponsor<Enter> lisätietoja varten"
-#: ../version.c:832
msgid "type :help register<Enter> for information "
-msgstr "kirjoita :help register<Enter> lisätietoja varten"
+msgstr "kirjoita :help register<Enter> lisätietoja varten"
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
-msgstr "valikko Ohje->Sponsoroi/Rekisteröi lisätietoja varten"
+msgstr "valikko Ohje->Sponsoroi/Rekisteröi lisätietoja varten"
-#: ../window.c:119
msgid "Already only one window"
-msgstr "Enää yksi ikkuna jäljellä"
+msgstr "Enää yksi ikkuna jäljellä"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Ei esikatseluikkunaa"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: Ei voi jakaa vasenta ylänurkkaa ja oikeaa alanurkkaa yhtäaikaa"
+msgstr "E442: Ei voi jakaa vasenta ylänurkkaa ja oikeaa alanurkkaa yhtäaikaa"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: Ei voi kiertää kun toinen ikkuna on jaettu"
+msgstr "E443: Ei voi kiertää kun toinen ikkuna on jaettu"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
-msgstr "E444: Ei voi sulkea viimeistä ikkunaa"
+msgstr "E444: Ei voi sulkea viimeistä ikkunaa"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: Ei voi sulkea autocmd-ikkunaa"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: Ei voi sulkea viimeistä ikkunaa, joka ei ole autocmd-ikkuna"
+msgstr "E814: Ei voi sulkea viimeistä ikkunaa, joka ei ole autocmd-ikkuna"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
-msgstr "E445: Toinen ikkuna sisältää muutoksia"
+msgstr "E445: Toinen ikkuna sisältää muutoksia"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
-msgstr "E446: Ei tiedostonimeä kursorin alla"
+msgstr "E446: Ei tiedostonimeä kursorin alla"
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() tyhjällä salasanalla"
+msgid "List or number required"
+msgstr "Lista tai luku tarvitaan"
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
+#~ msgid ""
+#~ "Failed to set path: sys.path is not a list\n"
+#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
+#~ msgstr ""
+#~ "Ei onnistuttu asettaman polkua: sys.path ei ole list\n"
+#~ "Lisää vim.VIM_SPECIAL_PATH muuttujaan sys.path"
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfishin tavujärjestys väärä"
+#~ msgid ""
+#~ "Failed to set path hook: sys.path_hooks is not a list\n"
+#~ "You should now do the following:\n"
+#~ "- append vim.path_hook to sys.path_hooks\n"
+#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
+#~ msgstr ""
+#~ "Ei voitu asettaa polkukoukkua: sys.path_hooks ei ole lista\n"
+#~ "Koeta seuraavaa:\n"
+#~ "- lisää vim.path_hook muuttujaan sys.path_hooks\n"
+#~ "- lisää vim.VIM_SPECIAL_PATH muuttujaan sys.path\n"
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: sha256-testi epäonnistui failed"
+#~ msgid "internal error: invalid value type"
+#~ msgstr "sisäinen virhe: huono arvotyyppi"
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Blowfish-testi epäonnistui"
+#~ msgid "internal error: NULL reference passed"
+#~ msgstr "sisäinen virhe: NULL-viite annettu"
-#~ msgid "Patch file"
-#~ msgstr "Patch-tiedosto"
+#~ msgid "unable to convert %s to vim structure"
+#~ msgstr "ei voi konvertoida oliota %s vim-tietorakenteeksi"
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&OK\n"
-#~ "&Peru"
+#~ msgid "unable to convert %s to vim dictionary"
+#~ msgstr "ei voitu konvertoida oliota %s vim-sanakirjaksi"
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Ei yhteyttä vim-palvelimeen"
+#~ msgid "E859: Failed to convert returned python object to vim value"
+#~ msgstr "E859: Ei voitu konvertoida python-oliota vim-arvoksi"
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Kohteeseen %s lähettäminen ei onnistunut"
+#~ msgid "E858: Eval did not return a valid python object"
+#~ msgstr "E858: Eval ei palauttanut python-oliota"
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Palvelimen vastauksen lukeminen ei onnistunut"
+#~ msgid "failed to run the code"
+#~ msgstr "ei voitu suorittaa koodia"
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Asiakkaalle lähetys ei onnistunut"
+#~ msgid "did not switch to the specified tab page"
+#~ msgstr "ei voitu vaihtaa annetulle välilehtisivulle"
-#~ msgid "Save As"
-#~ msgstr "Tallenna nimellä"
+#~ msgid "expected vim.TabPage object, but got %s"
+#~ msgstr "odotettiin vim.TabPage-oliota, saatiin %s"
-#~ msgid "Source Vim script"
-#~ msgstr "Lataa vim-skripti"
+#~ msgid "did not switch to the specified window"
+#~ msgstr "ei vaihdettu annettuun ikkunaan"
-#~ msgid "Edit File"
-#~ msgstr "Muokkaa tiedostoa"
+#~ msgid "failed to find window in the current tab page"
+#~ msgstr "ei voitu löytää ikkunaa nykyiselle välilehtisivulle"
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (EI LÖYTYNYT)"
+#~ msgid "expected vim.Window object, but got %s"
+#~ msgstr "odotettiin vim.Window-oliota, saatiin %s"
-#~ msgid "unknown"
-#~ msgstr "tuntematon"
+#~ msgid "expected vim.Buffer object, but got %s"
+#~ msgstr "odotettiin vim.Buffer-oliota, ei %s"
-#~ msgid "Edit File in new window"
-#~ msgstr "Muokkaa uudessa ikkunassa"
+#~ msgid "attempt to refer to deleted buffer"
+#~ msgstr "yritettiin viitata poistettuun puskuriin"
-#~ msgid "Append File"
-#~ msgstr "Lisää tiedostoon"
+#~ msgid "no such window"
+#~ msgstr "ikkunaa ei ole"
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Ikkunan sijainti: X %d, Y %d"
+#~ msgid "readonly attribute: buffer"
+#~ msgstr "kirjoitussuojausattribuutti: puskuri"
-#~ msgid "Save Redirection"
-#~ msgstr "Tallenna uudelleenosoitus"
+#~ msgid "attempt to refer to deleted window"
+#~ msgstr "yritettiin viitata poistettuun ikkunaan"
-#~ msgid "Save View"
-#~ msgstr "Tallenna näkymä"
+#~ msgid "no such tab page"
+#~ msgstr "välilehteä ei ole"
-#~ msgid "Save Session"
-#~ msgstr "Tallenna sessio"
+#~ msgid "attempt to refer to deleted tab page"
+#~ msgstr "yritettiin viitata poistettuun välilehteen"
-#~ msgid "Save Setup"
-#~ msgstr "Tallenna asetukset"
+#~ msgid "internal error: unknown option type"
+#~ msgstr "sisäinen virhe: tuntematon asetustyyppi"
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< ei ole käytössä jollei +eval ole päällä"
+#~ msgid "unable to get option value"
+#~ msgstr "ei voitu hakea asetuksen arvoa"
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Digraafeja ei ole tässä versiossa"
+#~ msgid "failed to run function %s"
+#~ msgstr "ei voitu suorittaa funktiota %s"
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "on laite (ei käytössä opendevice-asetuksen takia)"
+#~ msgid "function %s does not exist"
+#~ msgstr "funktiota %s ei ole"
-#~ msgid "Reading from stdin..."
-#~ msgstr "Luetaan vakiosyötteestä"
+#~ msgid "unnamed function %s does not exist"
+#~ msgstr "nimetöntä funktiota %s ei ole"
-#~ msgid "[crypted]"
-#~ msgstr "[salattu]"
+#~ msgid "cannot modify fixed list"
+#~ msgstr "ei voida muokata kiinitettyä listaa"
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Tiedoston salaus on tuntematon"
+#~ msgid "cannot delete vim.List attributes"
+#~ msgstr "ei voi poistaa vim.List-attribuutteja"
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans ei salli kirjoittaa muokkaamattomiin puskureihin"
+#~ msgid "failed to add item to list"
+#~ msgstr "ei voitu lisätä kohtaa listaan"
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Osittaiset kirjoitukset kielletty NetBeans-puskureissa"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "laitteeseen kirjoittaminen pois käytöstä opendevice-asetuksella"
+#~ msgid "attempt to assign sequence of size %d to extended slice of size %d"
+#~ msgstr ""
+#~ "yritettiin asettaa sekvenssiä jonka koko on %d sliceen jonka koko on %d"
-# tietääkseni resurssiforkki on applen tiedostojärjestelmän tunnistejuttujuttu
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: resurssiosa häviäisi (lisää komentoon ! ohittaaksesi)"
+#~ msgid "internal error: failed to add item to list"
+#~ msgstr "sisäinen virhe: ei voitu lisätä kohtaa listaan"
-#~ msgid "<cannot open> "
-#~ msgstr "<ei voi avata> "
+#~ msgid "internal error: not enough list items"
+#~ msgstr "sisäinen virhe: ei tarpeeksi listan kohtia"
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ei saada fonttia %s"
+#~ msgid "internal error: no vim list item %d"
+#~ msgstr "sisäinen virhe: ei vim-listan indeksiä %d"
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: nykyiseen hakemistoon ei voi palata"
+#~ msgid "attempt to assign sequence of size greater than %d to extended slice"
+#~ msgstr ""
+#~ "yritettiin sijoittaa sekvenssiä jonka koko on enemmän kuin %d sliceen"
-#~ msgid "Pathname:"
-#~ msgstr "Polku:"
+#~ msgid "slice step cannot be zero"
+#~ msgstr "slicen askel ei voi olla nolla"
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: nykyistä hakemistoa ei saada selville"
+#~ msgid "internal error: failed to get vim list item %d"
+#~ msgstr "sisäinen virhe: ei pystytty hakea vimin listan indeksiä %d"
-#~ msgid "OK"
-#~ msgstr "OK"
+#~ msgid "list index out of range"
+#~ msgstr "listaindeksi arvoalueen ulkopuolelta"
-#~ msgid "Cancel"
-#~ msgstr "Peru"
+#~ msgid "list constructor does not accept keyword arguments"
+#~ msgstr "listakonstruktori ei tue avainsanaparametrejä"
-#~ msgid "Vim dialog"
-#~ msgstr "Vim-ikkuna"
+#~ msgid "expected sequence element of size 2, but got sequence of size %d"
+#~ msgstr "sekvenssin elementin koon pitäisi olla 2, ei %d"
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "Vierityspalkki: Pixmapin geometria ei selviä"
+#~ msgid "hashtab changed during iteration"
+#~ msgstr "hashtab muuttui kesken iteraation"
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Ei voi luoda BalloonEvalia viestille ja callbackille"
+#~ msgid "cannot set attribute %s"
+#~ msgstr "ei voi asettaa attribuuttia %s"
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: GUIn käynnistys ei onnistu"
+#~ msgid "cannot delete vim.Dictionary attributes"
+#~ msgstr "ei voi poistaa vim.Dictionary-attribuutteja"
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Ei voi lukea kohteesta %s"
+#~ msgid "internal error: imp.find_module returned tuple with NULL"
+#~ msgstr ""
+#~ "sisäinen virhe: imp.find_module palautti tuplen joka sisältää nullin"
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Ei voi avata GUIta, sopivaa fonttia ei löydy"
+#~ msgid ""
+#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+#~ msgstr ""
+#~ "odotettiin 3-tuple tuloksnea imp.find_module()-kutsulle, mutta tuplen "
+#~ "koko onkin %d"
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: guifontwide virheellinen"
+#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
+#~ msgstr "odotettiin 3-tuplea tuloksena imp.find_module()-kutsulle, ei %s"
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: imactivatekeyn arvo on virheellinen"
+#~ msgid "E264: Python: Error initialising I/O objects"
+#~ msgstr "E264: Python: Virhe IO-olioiden alustuksessa"
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Väriä %s ei voi määritellä"
+#~ msgid "invalid attribute: %s"
+#~ msgstr "virheellinen attribuutti: %s"
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Ei täsmäystä kursorin alla, etsitään seuraava"
+#~ msgid "can't delete OutputObject attributes"
+#~ msgstr "ei voi poistaa OutputObject-attribuutteja"
-#~ msgid "Input _Methods"
-#~ msgstr "Syöte_menetelmät"
+#~ msgid "number must be greater or equal to zero"
+#~ msgstr "luvun on oltava yhtä suuri tai suurempi kuin nolla"
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Etsi ja korvaa..."
+#~ msgid "value is too small to fit into C int type"
+#~ msgstr "arvo on liian pieni mahtumaan C:n int-tyyppiin"
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Etsi..."
+#~ msgid "expected int() or something supporting coercing to int(), but got %s"
+#~ msgstr ""
+#~ "odotettiin tyyppiä int() tai jotain joka muuntuu tyyppiin int(), ei %s"
-#~ msgid "Find what:"
-#~ msgstr "Etsi:"
+#~ msgid ""
+#~ "expected int(), long() or something supporting coercing to long(), but "
+#~ "got %s"
+#~ msgstr ""
+#~ "odotettiin instanssia tyypeistä int(), long() tai mitä tahansa joka "
+#~ "muuntuisi tyyppiin long(), ei %s"
-#~ msgid "Replace with:"
-#~ msgstr "Korvaa:"
+#~ msgid "expected bytes() or str() instance, but got %s"
+#~ msgstr "odotettiin instanssia tyypeistä bytes() tai str(), ei %s"
-#~ msgid "Match whole word only"
-#~ msgstr "Korvaa kokonaisia sanoja"
+#~ msgid "expected str() or unicode() instance, but got %s"
+#~ msgstr "odottettiin insanssia tyypeistä str() tai unicode(), ei %s"
-#~ msgid "Match case"
-#~ msgstr "Kirjaintaso"
+#~ msgid "index must be int or slice, not %s"
+#~ msgstr "indeksin pitää olla int tai slice, ei %s"
-#~ msgid "Direction"
-#~ msgstr "Suunta"
+#~ msgid "failed to add key '%s' to dictionary"
+#~ msgstr "avaimen %s lisääminen sanakirjaan ei onnistu"
-#~ msgid "Up"
-#~ msgstr "Ylös"
+#~ msgid "list is locked"
+#~ msgstr "luettelo on lukittu"
-#~ msgid "Down"
-#~ msgstr "Alas"
+#~ msgid "Need encryption key for \"%s\""
+#~ msgstr "Tarvitaan salausavain kohteelle %s "
-#~ msgid "Find Next"
-#~ msgstr "Etsi seuraava"
+#~ msgid "E744: NetBeans does not allow changes in read-only files"
+#~ msgstr "E744: NetBeans ei tue muutoksia kirjoitussuojattuihin tiedostoihin"
-#~ msgid "Replace"
-#~ msgstr "Korvaa"
+#~ msgid "E463: Region is guarded, cannot modify"
+#~ msgstr "E463: Alue on suojattu, muuttaminen ei onnistu"
-#~ msgid "Replace All"
-#~ msgstr "Korvaa kaikki"
+#~ msgid "E449: Invalid expression received"
+#~ msgstr "E449: Virheellinen ilmaus saatu"
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: sessiomanageri lähetti die-pyynnön\n"
+#~ msgid "E233: cannot open display"
+#~ msgstr "E233: näyttöä ei voi avata"
-#~ msgid "Close"
-#~ msgstr "Sulje"
+#~ msgid "E247: no registered server named \"%s\""
+#~ msgstr "E247: palvelinta %s ei ole rekisteröitynä"
-#~ msgid "New tab"
-#~ msgstr "Uusi välilehti"
+#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+#~ msgstr "E800: Arabiaa ei voi käyttää, koska sitä ei käännetty mukaan\n"
-#~ msgid "Open Tab..."
-#~ msgstr "Avaa välilehti..."
+#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+#~ msgstr "E27: Farsia ei voi käyttää, koska sitä ei käännetty mukaan\n"
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Pääikkuna tuhoutui odottamatta\n"
+#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+#~ msgstr "E26: Hepreaa ei voi käyttää, koska sitä ei käännetty mukaan\n"
-#~ msgid "&Filter"
-#~ msgstr "&Suodata"
+#~ msgid "E25: GUI cannot be used: Not enabled at compile time"
+#~ msgstr "E25: GUIta ei voi käyttää, koska sitä ei käännetty mukaan"
-#~ msgid "&Cancel"
-#~ msgstr "&Peru"
+#~ msgid "E448: Could not load library function %s"
+#~ msgstr "E448: Ei voitu ladta kirjastofunktiota %s"
-#~ msgid "Directories"
-#~ msgstr "Hakemistot"
+#~ msgid "E236: Font \"%s\" is not fixed-width"
+#~ msgstr "E236: Fontti %s ei ole tasavälinen"
-#~ msgid "Filter"
-#~ msgstr "Suodatus"
+#~ msgid "E234: Unknown fontset: %s"
+#~ msgstr "E234: Tuntematon fontset: %s"
-#~ msgid "&Help"
-#~ msgstr "O&hje"
+#~ msgid "gvimext.dll error"
+#~ msgstr "gvimext.dll-virhe"
-#~ msgid "Files"
-#~ msgstr "Tiedostot"
+#~ msgid "Error creating process: Check if gvim is in your path!"
+#~ msgstr "Virhe prosessin käynnistämisessä, varmista että gvim on polulla"
-#~ msgid "&OK"
-#~ msgstr "&Ok"
+#~ msgid "Edits the selected file(s) with Vim"
+#~ msgstr "Muokkaa valittuja tiedostoja Vimillä"
-#~ msgid "Selection"
-#~ msgstr "Valinta"
+#~ msgid "Edit with existing Vim - "
+#~ msgstr "Muokkaa olemassaolevalla Vimillä - "
-#~ msgid "Find &Next"
-#~ msgstr "Hae &seuraava"
+#~ msgid "Edit with &Vim"
+#~ msgstr "Muokkaa &Vimillä"
-#~ msgid "&Replace"
-#~ msgstr "Ko&rvaa"
+#~ msgid "Diff with Vim"
+#~ msgstr "Diffi Vimillä"
-#~ msgid "Replace &All"
-#~ msgstr "Korvaa k&aikki"
+#~ msgid "Edit with single &Vim"
+#~ msgstr "Muokkaa yhdellä &Vimillä"
-#~ msgid "&Undo"
-#~ msgstr "&Kumoa"
+#~ msgid "Edit with &multiple Vims"
+#~ msgstr "&Muokkaa usealla Vimillä"
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Ikkunan otsikkoa ei löydy %s"
+#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+#~ msgstr "E299: Perl-suoritus kielletty hiekkalaatikossa ilman Safe-moduulia"
-# OLE on object linking and embedding på windowska
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Argumenttia ei tueta: -%s, käytä OLE-versiota"
+#~ msgid ""
+#~ "Sorry, this command is disabled: the Perl library could not be loaded."
+#~ msgstr "komento ei toimi, Perl kirjastoa ei voinut ladata."
-# MDI eli windowsin moni-ikkunasovellus
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Ikkunaa ei voitu avata MDI-sovellukseen"
+#~ msgid "E370: Could not load library %s"
+#~ msgstr "E370: Kirjaston %s lataaminen ei onnistu"
-#~ msgid "Close tab"
-#~ msgstr "Sulje välilehti"
+#~ msgid "type :help windows95<Enter> for info on this"
+#~ msgstr "kirjoita :help windows95<Enter> lisätietoja varten"
-#~ msgid "Open tab..."
-#~ msgstr "Avaa välilehti..."
+#~ msgid "WARNING: Windows 95/98/ME detected"
+#~ msgstr "VAROITUS: Window 95/98/ME havaittu"
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Etsi merkkijonoa (\\\\:llä löytää \\:t)"
+#~ msgid " for Vim defaults "
+#~ msgstr " Vim-oletuksia varten"
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Etsi ja korvaa (\\\\:llä löytää \\:t)"
+#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda Vi-yhteensopivuutta"
-#~ msgid "Not Used"
-#~ msgstr "Ei käytössä"
+#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
+#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda syötetilaa"
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Hakemisto\t*.nothing\n"
+#~ msgid "Running modeless, typed text is inserted"
+#~ msgstr "Suoritetaan tilattomana, kirjoitettu teksti syötetään"
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Ei voi varata värikartan alkiota, värit voivat mennä väärin"
+#~ msgid "menu Help->Orphans for information "
+#~ msgstr "valikko Ohje->Orvot lisätietoja varten "
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Seuraavien merkistöjoukkojen fontit puuttuvat fontsetistä %s:"
+#~ msgid "type :help cp-default<Enter> for info on this"
+#~ msgstr "kirjoita :help cp-default<Enter> ohjetta oletuksista varten"
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Fontsetin nimi: %s"
+#~ msgid "type :set nocp<Enter> for Vim defaults"
+#~ msgstr "kirjoita :set nocp<Enter> Vimin oletuksiin "
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Fontti %s ei ole tasavälinen"
+#~ msgid "Running in Vi compatible mode"
+#~ msgstr "Suoritetaan Vi-yhteensopivuustilaa"
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Fontsetin nimi: %s\n"
+#~ msgid "type :help version8<Enter> for version info"
+#~ msgstr "kirjoita :help version8<Enter> versiotietoja varten "
-#~ msgid "Font0: %s\n"
-#~ msgstr "Fontti0: %s\n"
+#~ msgid "type :help<Enter> or <F1> for on-line help"
+#~ msgstr "kirjoita :help<Enter> tai <F1> ohjetta varten "
-#~ msgid "Font1: %s\n"
-#~ msgstr "Fontti1: %s\n"
+#~ msgid "version "
+#~ msgstr "versio "
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "Fontti%<PRId64>:n leveys ei ole kaksi kertaa fontti0:n\n"
+#~ msgid "VIM - Vi IMproved"
+#~ msgstr "VIM - Vi IMproved"
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "Fontti0:n leveys: %<PRId64>\n"
+#~ msgid " DEBUG BUILD"
+#~ msgstr " DEBUG-versio"
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Fontti1:n leveys: %<PRId64>\n"
-#~ "\n"
+#~ msgid "Linking: "
+#~ msgstr "Linkitys: "
-#~ msgid "Invalid font specification"
-#~ msgstr "Virheellinen fonttimääritys"
+#~ msgid "Compiler: "
+#~ msgstr "Käännin: "
-#~ msgid "&Dismiss"
-#~ msgstr "&Ohita"
+#~ msgid "Compilation: "
+#~ msgstr "Käännös: "
-#~ msgid "no specific match"
-#~ msgstr "ei tarkkaa täsmäystä"
+#~ msgid " system menu file: \""
+#~ msgstr " järjestelmävalikko: \""
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - fonttivalitsin"
+#~ msgid " defaults file: \""
+#~ msgstr " defaults-tiedosto: \""
-#~ msgid "Name:"
-#~ msgstr "Nimi:"
+#~ msgid "3rd user gvimrc file: \""
+#~ msgstr "3. käyttäjän gvimrc: \""
-#~ msgid "Show size in Points"
-#~ msgstr "Näytä koko pisteinä"
+#~ msgid "2nd user gvimrc file: \""
+#~ msgstr "2. käyttäjän gvimrc: \""
-#~ msgid "Encoding:"
-#~ msgstr "Koodaus:"
+#~ msgid " user gvimrc file: \""
+#~ msgstr " käyttäjän gvimrc: \""
-#~ msgid "Font:"
-#~ msgstr "Fontti:"
+#~ msgid " system gvimrc file: \""
+#~ msgstr " järjestelmän gvimrc: \""
-#~ msgid "Style:"
-#~ msgstr "Tyyli:"
+#~ msgid " 2nd user exrc file: \""
+#~ msgstr " 2. käyttäjän exrc: \""
-#~ msgid "Size:"
-#~ msgstr "Koko:"
+#~ msgid " user exrc file: \""
+#~ msgstr " käyttäjän exrc: \""
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Hangu-automaattivirhe"
+#~ msgid " 3rd user vimrc file: \""
+#~ msgstr " 3. käyttäjän vimrc: \""
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat-virhe"
+#~ msgid " 2nd user vimrc file: \""
+#~ msgstr " 2. käyttäjän vimrc: \""
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: ei voi avata cscope-tietokantaa: %s"
+#~ msgid " user vimrc file: \""
+#~ msgstr " käyttäjän vimrc: \""
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: ei voi hakea cscope-tietokannan tietoja"
+#~ msgid "with (classic) GUI."
+#~ msgstr "perinteisellä GUIlla."
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Luan kirjastoa ei voitu ladata."
+#~ msgid "with Cocoa GUI."
+#~ msgstr "Cocoa-GUIlla."
-#~ msgid "cannot save undo information"
-#~ msgstr "ei voitu tallentaa kumoustietoja"
+#~ msgid "with Carbon GUI."
+#~ msgstr "Carbon-GUIlla."
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr "E815: Sori, komento ei toimi, MzScheme-kirjastoa ei voitu ladata."
+#~ msgid "with GUI."
+#~ msgstr "GUIlla."
-#~ msgid "invalid expression"
-#~ msgstr "virheellinen ilmaus"
+#~ msgid "with Photon GUI."
+#~ msgstr "Photon-GUIlla."
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "ilmaukset poistettu käytöstä käännösaikana"
+#~ msgid "with X11-Athena GUI."
+#~ msgstr "X11-Athena-GUIlla."
-#~ msgid "hidden option"
-#~ msgstr "piilotettu asetus"
+#~ msgid "with X11-neXtaw GUI."
+#~ msgstr "X11-neXtaw-GUIlla."
-#~ msgid "unknown option"
-#~ msgstr "tuntematon asetus"
+#~ msgid "with X11-Motif GUI."
+#~ msgstr "X11-Motif-GUIlla."
-#~ msgid "window index is out of range"
-#~ msgstr "ikkunan indeksi alueen ulkopuolella"
+#~ msgid "with GTK2 GUI."
+#~ msgstr "GTK2-GUIlla."
-#~ msgid "couldn't open buffer"
-#~ msgstr "ei voitu avata puskuria"
+#~ msgid "with GTK2-GNOME GUI."
+#~ msgstr "GTK2-Gnome-GUIlla."
-#~ msgid "cannot delete line"
-#~ msgstr "ei voitu poistaa riviä"
+#~ msgid "with GTK3 GUI."
+#~ msgstr "GTK3-GUIlla."
-#~ msgid "cannot replace line"
-#~ msgstr "ei voitu korvata riviä"
+#~ msgid "without GUI."
+#~ msgstr "ilman GUIta."
-#~ msgid "cannot insert line"
-#~ msgstr "ei voitu lisätä riviä"
+#~ msgid ""
+#~ "\n"
+#~ "Tiny version "
+#~ msgstr ""
+#~ "\n"
+#~ "Tiny-versio "
-#~ msgid "string cannot contain newlines"
-#~ msgstr "merkkijono ei saa sisältää rivinvaihtoja"
+#~ msgid ""
+#~ "\n"
+#~ "Small version "
+#~ msgstr ""
+#~ "\n"
+#~ "Small-versio "
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim-virhe: ~a"
+#~ msgid ""
+#~ "\n"
+#~ "Normal version "
+#~ msgstr ""
+#~ "\n"
+#~ "Normal-versio "
-#~ msgid "Vim error"
-#~ msgstr "Vim-virhe"
+#~ msgid ""
+#~ "\n"
+#~ "Big version "
+#~ msgstr ""
+#~ "\n"
+#~ "Big-version "
-#~ msgid "buffer is invalid"
-#~ msgstr "puskuri on virheellinen"
+#~ msgid ""
+#~ "\n"
+#~ "Huge version "
+#~ msgstr ""
+#~ "\n"
+#~ "Huge-versio "
-#~ msgid "window is invalid"
-#~ msgstr "ikkuna on virheellinen"
+#~ msgid "Modified by "
+#~ msgstr "Muokannut "
-#~ msgid "linenr out of range"
-#~ msgstr "rivinumero arvoalueen ulkopuolelta"
+#~ msgid ""
+#~ "\n"
+#~ "Included patches: "
+#~ msgstr ""
+#~ "\n"
+#~ "Pätsit: "
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "ei sallittu Vimin hiekkalaatikossa"
+#~ msgid ""
+#~ "\n"
+#~ "OpenVMS version"
+#~ msgstr ""
+#~ "\n"
+#~ "OpenVMS-version"
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
+#~ msgid ""
+#~ "\n"
+#~ "MacOS version"
#~ msgstr ""
-#~ "E836: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+#~ "\n"
+#~ "MacOS-version"
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
+#~ msgid ""
+#~ "\n"
+#~ "MacOS X version"
#~ msgstr ""
-#~ "E837: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+#~ "\n"
+#~ "MacOS X-version"
#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
+#~ "\n"
+#~ "MacOS X (unix) version"
#~ msgstr ""
-#~ "E263: Sori, komento ei toimi, Python-kirjaston lataaminen ei onnistunut."
+#~ "\n"
+#~ "MacOS X-version (unix)"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "ei voi poistaa OutputObject-attribuutteja"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 32-bit console version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32-bittinen konsoliversio"
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspacen pitää olla kokonaisluku"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 64-bit console version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32-bittinen konsoliversio"
-#~ msgid "invalid attribute"
-#~ msgstr "virheellinen attribuutti"
+#~ msgid " with OLE support"
+#~ msgstr " OLE-tuella"
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<puskuriolio (poistettu) kohdassa %p>"
+#~ msgid " in Win32s mode"
+#~ msgstr " Win32s-tilassa"
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Pythonia ei voi kutsua rekursiivisesti"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 32-bit GUI version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 32-bittinen GUI-version"
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: muuttujan $_ pitää olla Stringin instanssi"
+#~ msgid ""
+#~ "\n"
+#~ "MS-Windows 64-bit GUI version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 64-bittinen GUI-versio"
#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr "E266: Sori, komento ei toimi, Ruby-kirjastoa ei voitu ladata."
+#~ "\n"
+#~ "MS-Windows 16/32-bit GUI version"
+#~ msgstr ""
+#~ "\n"
+#~ "MS-Windows 16- t. 32-bittinen GUI-versio"
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: odotuksenvastainen return"
+#~ msgid "E827: Undo file is encrypted: %s"
+#~ msgstr "E827: Kumoustiedosto on salattu: %s"
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: Odotuksenvastainen next"
+#~ msgid "E826: Undo file decryption failed: %s"
+#~ msgstr "E826: Kumoustiedoston purku epäonnistui: %s"
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: Odotuksenvastainen break"
+#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
+#~ msgstr "E832: Salaamattomalla tiedostolla on salattu kumoustiedosto: %s"
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: odotuksenvastainen redo"
+#~ msgid "No undo possible; continue anyway"
+#~ msgstr "Ei voi kumota, jatketaan silti"
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: retry rescuen ulkopuolella"
+#~ msgid "Used CUT_BUFFER0 instead of empty selection"
+#~ msgstr "Käytettiin CUT_BUFFER0:aa tyhjän valinnan sijaan"
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: käsittelemätön poikkeus"
+#~ msgid "new shell started\n"
+#~ msgstr "uusi kuori avattu\n"
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: tuntematon longjmp-tila %d"
+#~ msgid "Cannot open $VIMRUNTIME/rgb.txt"
+#~ msgstr "Ei voida avata tiedostoa $VIMRUNTIME/rgb.txt"
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Vaihda toteutuksen ja määritelmän välillä"
+#~ msgid ""
+#~ "\n"
+#~ "--- Terminal keys ---"
+#~ msgstr ""
+#~ "\n"
+#~ "--- Terminaalinäppäimet ---"
-#~ msgid "Show base class of"
-#~ msgstr "Näytä kantaluokka kohteelle"
+#~ msgid "E437: terminal capability \"cm\" required"
+#~ msgstr "E437: terminaalilla pitää olla cm kyvyissään"
-#~ msgid "Show overridden member function"
-#~ msgstr "Näytä korvattu jäsenfunktio"
+#~ msgid "E436: No \"%s\" entry in termcap"
+#~ msgstr "E436: %s ei löytynyt termcapista"
-#~ msgid "Retrieve from file"
-#~ msgstr "Jäljitä tiedostosta"
+#~ msgid "E559: Terminal entry not found in termcap"
+#~ msgstr "E559: Terminaalia ei löytynyt termcapista"
-#~ msgid "Retrieve from project"
-#~ msgstr "Jäljitä projektista"
+#~ msgid "E558: Terminal entry not found in terminfo"
+#~ msgstr "E558: Terminaalia ei löytynyt terminfosta"
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Jäljitä kaikista projekteista"
+#~ msgid "E557: Cannot open termcap file"
+#~ msgstr "E557: Ei voi avata termcap-tiedostoa"
-#~ msgid "Retrieve"
-#~ msgstr "Jäljitä"
+#~ msgid "defaulting to '"
+#~ msgstr "oletusarvona "
-#~ msgid "Show source of"
-#~ msgstr "Näytä lähdekoodi kohteelle"
+#~ msgid "' not known. Available builtin terminals are:"
+#~ msgstr " ei tunnettu. Tuetut terminaalit:"
-#~ msgid "Find symbol"
-#~ msgstr "Etsi symboli"
+#~ msgid "E430: Tag file path truncated for %s\n"
+#~ msgstr "E430: Tägitiedoston polku katkaistu kohdassa %s\n"
-#~ msgid "Browse class"
-#~ msgstr "Selaa luokkaa"
+#~ msgid "E422: terminal code too long: %s"
+#~ msgstr "E422: terminaalikoodi liian pitkä: %s"
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Näytä luokka hierarkiassa"
+#~ msgid "E845: Insufficient memory, word list will be incomplete"
+#~ msgstr "E845: Muisti ei riitä, sanalista jää keskeneräiseksi"
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Näytä luokka rajoitetussa hierarkiassa"
+#~ msgid "Conversion in %s not supported"
+#~ msgstr "Muutosta kohteessa %s ei tueta"
-#~ msgid "Xref refers to"
-#~ msgstr "Xref viittaa kohteeseen"
+#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+#~ msgstr "Varoitus: Ei löydetty sanalistaa %s_%s.spl tai %s_ascii.spl"
-#~ msgid "Xref referred by"
-#~ msgstr "Xref viitattu kohteesta"
+#~ msgid ""
+#~ "\n"
+#~ "# Last %sSearch Pattern:\n"
+#~ "~"
+#~ msgstr ""
+#~ "\n"
+#~ "# Edellinen %sHakulauseke:\n"
+#~ "~"
+
+#~ msgid "Substitute "
+#~ msgstr "Korvaa "
-#~ msgid "Xref has a"
-#~ msgstr "Xref sisältää kohteen"
+#~ msgid "(NFA) COULD NOT OPEN %s !"
+#~ msgstr "(NFA) EI VOI AVATA KOHDETTA %s"
-#~ msgid "Xref used by"
-#~ msgstr "Xrefiä käyttää"
+#~ msgid ""
+#~ "Could not open temporary log file for writing, displaying on stderr ... "
+#~ msgstr ""
+#~ "Ei voitu avata väliaikaislokitiedosta kirjoittamista varten, joten "
+#~ "virheet näytetään vakiovirhevirrassa. "
-#~ msgid "Show docu of"
-#~ msgstr "Näytä dokumentti kohteelle"
+#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+#~ msgstr "E878: (NFA) Ei voitu allokoida muistia polkujen läpikäyntiin"
-#~ msgid "Generate docu for"
-#~ msgstr "Luo dokumentti kohteelle"
+#~ msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+#~ msgstr "E876: (NFA regexp) Tila ei riitä NFA:n tallentamiseen"
#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
+#~ "E875: (NFA regexp) (While converting from postfix to NFA), too many "
+#~ "states left on stack"
#~ msgstr ""
-#~ "Ei voida yhdistää SNiFF+:aan. Tarkista ympäristömuuttujat (sniffemacsin "
-#~ "löytyä polkumuuttujasta $PATH).\n"
+#~ "E875: (NFA regexp) (Muunnettaessa postfixistä NFA:ksi), liikaa tiloja "
+#~ "jäljellä pinossa"
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Virhe luettaessa, yhteys katkaistu"
+#~ msgid "E874: (NFA) Could not pop the stack !"
+#~ msgstr "E874: (NFA) Ei voida poistaa pinosta"
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ "
+#~ msgid "E873: (NFA regexp) proper termination error"
+#~ msgstr "E873: (NFA regexp) oikea lopetusvirhe"
-#~ msgid "not "
-#~ msgstr "ei ole "
+#~ msgid "E879: (NFA regexp) Too many \\z("
+#~ msgstr "E879: (NFA regexp) Liikaa merkkejä \\z("
-#~ msgid "connected"
-#~ msgstr "yhdistetty"
+#~ msgid "E872: (NFA regexp) Too many '('"
+#~ msgstr "E872: (NFA regexp) Liian monta suljetta '('"
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Tuntematon SNiFF+-pyyntö: %s"
+#~ msgid "E871: (NFA regexp) Can't have a multi follow a multi !"
+#~ msgstr "E871: (NFA regexp) Multi ei voi seurata multia"
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Virhe yhdistettäessä SNiFF+:aan"
+#~ msgid "E870: (NFA regexp) Error reading repetition limits"
+#~ msgstr "E870: (NFA regexp) Virhe luettaessa toiston määriä"
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ei ole yhdistetty"
+#~ msgid "E869: (NFA) Unknown operator '\\@%c'"
+#~ msgstr "E869: (NFA) Tuntematon operaattori '\\@%c'"
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Ei ole SNiFF+-puskuri"
+#~ msgid "E868: Error building NFA with equivalence class!"
+#~ msgstr "E868: Virhe NFA:n ekvivalenssiluokkia tekemisessä"
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: Virhe kirjoituksessa, yhteys katkaistu"
+#~ msgid "E867: (NFA) Unknown operator '\\%%%c'"
+#~ msgstr "E867: (NFA) Tuntematon operaattori '\\%%%c'"
-#~ msgid "invalid buffer number"
-#~ msgstr "virheellinen puskurinumero"
+#~ msgid "E867: (NFA) Unknown operator '\\z%c'"
+#~ msgstr "E867: (NFA) Tuntematon operaattori '\\z%c'"
-#~ msgid "not implemented yet"
-#~ msgstr "ei toteutettu"
+#~ msgid "E877: (NFA regexp) Invalid character class: %ld"
+#~ msgstr "E877: (NFA regexp) Virheellinen merkkiluokka: %ld"
-#~ msgid "cannot set line(s)"
-#~ msgstr "ei voi asettaa rivejä"
+#~ msgid "E866: (NFA regexp) Misplaced %c"
+#~ msgstr "E866: (NFA-regexp) %c väärässä paikassa"
-#~ msgid "invalid mark name"
-#~ msgstr "virheellinen merkin nimi"
+#~ msgid "E865: (NFA) Regexp end encountered prematurely"
+#~ msgstr "E865: (NFA) Säännöllisen ilmauksen ennenaikainen loppu"
-#~ msgid "mark not set"
-#~ msgstr "merkko ei ole asetettu"
+#~ msgid "Error file"
+#~ msgstr "Virhetiedosto"
-#~ msgid "row %d column %d"
-#~ msgstr "rivi %d sarake %d"
+#~ msgid "shell returned %d"
+#~ msgstr "kuori palautti arvon %d"
-#~ msgid "cannot insert/append line"
-#~ msgstr "rivin lisäys ei onnistu"
+#~ msgid "Vim Warning"
+#~ msgstr "Vim-varoitus"
-#~ msgid "line number out of range"
-#~ msgstr "rivinumero arvoalueen ulkopuolella"
+#~ 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 ""
+#~ "VIMRUN.EXEä ei löydy muuttujasta $PATH.\n"
+#~ "Ulkoiset komennot eivät pysähdy suorituksen lopussa.\n"
+#~ "Lisätietoja komennolla :help win32-vimrun"
-#~ msgid "unknown flag: "
-#~ msgstr "tuntematon asetus: "
+#~ msgid "E371: Command not found"
+#~ msgstr "E371: Komentoa ei löydy"
-#~ msgid "unknown vimOption"
-#~ msgstr "tuntematon vimOption"
+#~ msgid "shutdown"
+#~ msgstr "sammutus"
-#~ msgid "keyboard interrupt"
-#~ msgstr "näppäimistökeskeytys"
+#~ msgid "logoff"
+#~ msgstr "uloskirjautuminen"
-#~ msgid "vim error"
-#~ msgstr "vim-virhe"
+#~ msgid "close"
+#~ msgstr "sulkeminen"
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "ei voi luoda puskuri- tai ikkunakomentoa, olio on poistumassa"
+#~ msgid "Vim: Caught %s event\n"
+#~ msgstr "Vim: Napattiin %s\n"
+
+#~ msgid "Could not fix up function pointers to the DLL!"
+#~ msgstr "Ei voitu korjata funktio-osoittimia DLL:ssä"
+
+#~ msgid "VIM Error"
+#~ msgstr "VIM-virhe"
+
+#~ msgid "Could not load vim32.dll!"
+#~ msgstr "Vim32.dll:ää ei voitu ladata"
+
+#~ msgid "At line"
+#~ msgstr "Rivillä"
+
+#~ msgid "XSMP SmcOpenConnection failed: %s"
+#~ msgstr "XSMP SmcOpenConnection epäonnistui: %s"
+
+#~ msgid "XSMP ICE connection watch failed"
+#~ msgstr "XSMP:n ICE-yhteyden tarkkailu epäonnistui"
+
+#~ msgid "XSMP opening connection"
+#~ msgstr "XSMP avaa yhteyttä"
+
+#~ msgid "XSMP handling save-yourself request"
+#~ msgstr "XSMP käsittelee save-yourself-pyyntöä"
+
+#~ msgid "Opening the X display failed"
+#~ msgstr "X-näytön avaus epäonnistui"
+
+#~ msgid "XSMP lost ICE connection"
+#~ msgstr "XSMP kadotti ICE-yhteyden"
#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "callbackia ei voi rekisteröidä: puskuri tai ikkuna on poistettu"
+#~ "\n"
+#~ "Command terminated\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Komento loppui\n"
#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
+#~ "\n"
+#~ "Cannot execute shell "
#~ msgstr ""
-#~ "E280: kriittinen TCL-virhe: reflist hajalla? Ilmoita asiasta "
-#~ "postituslistalle vim-dev@vim.org"
+#~ "\n"
+#~ "Kuoren suoritus ei onnistu "
-#~ msgid "cannot register callback command: buffer/window reference not found"
+#~ msgid ""
+#~ "\n"
+#~ "Cannot fork\n"
#~ msgstr ""
-#~ "callbackia ei voi rekisteröidä: puskurin tai ikkunan viitettä ei löydy"
+#~ "\n"
+#~ "Ei voi haarauttaa\n"
#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr "E571: Sori, komento ei toimi, Tcl-kirjastoa ei voitu ladata."
+#~ "\n"
+#~ "Cannot create pipes\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Putkia ei voi tehdä\n"
#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
+#~ "\n"
+#~ "Cannot execute shell sh\n"
#~ msgstr ""
-#~ "E281: TCL-virhe: lopetuskoodi ei ole kokonaisluku? Ilmoita asiasta "
-#~ "postituslistalle vim-dev@vim.org"
+#~ "\n"
+#~ "Kuoren sh suoritus ei onnistu\n"
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: palautusarvo %d"
+# mikä security context?
+#~ msgid "Could not get security context %s for %s. Removing it!"
+#~ msgstr "Ei saatu turvallisuuskontekstia %s kohteelle %s ja se poistetaan"
-#~ msgid "cannot get line"
-#~ msgstr "ei voida hakea riviä"
+#~ msgid "Could not set security context %s for %s"
+#~ msgstr "Ei voitu asettaa turvallisuuskontekstia %s kohteelle %s"
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Komentopalvelimen nimen rekisteröinti ei onnistu"
+#~ msgid "Opening the X display timed out"
+#~ msgstr "X-näytön avaus aikakatkaistiin"
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Komennon lähetys kohdeohjelmalle ei onnistu"
+#~ msgid "Testing the X display failed"
+#~ msgstr "X-näytön testaus epäonnistui"
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Virheellinen palvelimen tunniste: %s"
+#~ msgid ""
+#~ "\n"
+#~ "Vim: Got X error\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Vim: X-virhe\n"
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIMin instanssin rekisteriarvo on virheellinen, poistettiin."
+#~ msgid "Opening the X display took %ld msec"
+#~ msgstr "X-näytön avaus vei %ld millisekuntia"
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ei toimi tässä käyttöliittymässä\n"
+#~ msgid "E245: Illegal char '%c' in font name \"%s\""
+#~ msgstr "E245: Virheellinen merkki %c fontin nimessä %s"
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Tähän Vimiin ei ole käännetty diff-toimintoja mukaan."
+#~ msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+#~ msgstr "E244: Virheellinen laatunimi %s fontin nimessä %s"
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "-nb:tä ei voi käyttää, koska sitä ei käännetty mukaan\n"
+#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+#~ msgstr "E244: Virheellinen merkistön nimi %s fontin nimessä %s"
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Virhe: Gvimin käynnistys NetBeansistä ei onnistu\n"
+#~ msgid "Printing '%s'"
+#~ msgstr "Tulostetaan %s"
+
+#~ msgid "E238: Print error: %s"
+#~ msgstr "E238: Tulostinvirhe: %s"
+
+#~ msgid "E613: Unknown printer font: %s"
+#~ msgstr "E613: Tuntematon tulostimen fontti: %s"
+
+#~ msgid "to %s on %s"
+#~ msgstr "tulostimelle %s kohteessa %s"
+
+#~ msgid "E237: Printer selection failed"
+#~ msgstr "E237: Tulostimen valinta epäonnistui"
+
+#~ msgid "'columns' is not 80, cannot execute external commands"
+#~ msgstr "columns ei ole 80, ei voi suorittaa ulkoista komentoa"
+
+#~ msgid "I/O ERROR"
+#~ msgstr "IO-virhe"
+
+#~ msgid "ANCHOR_BUF_SIZE too small."
+#~ msgstr "ANCHOR_BUF_SIZE liian pieni."
+
+#~ msgid " returned\n"
+#~ msgstr " palautti\n"
+
+#~ msgid "shell "
+#~ msgstr "kuori "
+
+#~ msgid "Cannot execute "
+#~ msgstr "Ei voi suorittaa "
+
+#~ msgid "E360: Cannot execute shell with -f option"
+#~ msgstr "E360: Kuorta ei voi avata asetuksella -f"
+
+#~ msgid "mch_get_shellsize: not a console??\n"
+#~ msgstr "mch_get_shellsize: ei ole konsoli?\n"
+
+#~ msgid "cannot change console mode ?!\n"
+#~ msgstr "ei voi vaihtaa konsolitilaa?\n"
+
+#~ msgid "Vim exiting with %d\n"
+#~ msgstr "Vim sulkeutuu koodilla %d\n"
+
+#~ msgid "Cannot create "
+#~ msgstr "Ei voi luoda "
+
+#~ msgid "Cannot open NIL:\n"
+#~ msgstr "Ei voi avata NILiä:\n"
+
+#~ msgid "Need %s version %ld\n"
+#~ msgstr "Tarvitaan %s versio %ld\n"
+
+#~ msgid "Need Amigados version 2.04 or later\n"
+#~ msgstr "Amigados 2.04 tai uudempi tarvitaan\n"
+
+#~ msgid "VIM: Can't open window!\n"
+#~ msgstr "VIM: Ei voi avata ikkunaa\n"
+
+#~ msgid "cannot open "
+#~ msgstr "ei voi avata "
+
+#~ msgid "E538: No mouse support"
+#~ msgstr "E538: Hiirtä ei tueta"
+
+#~ msgid "E533: can't select wide font"
+#~ msgstr "E533: Leveän fontin valinta ei onnistu"
+
+#~ msgid "E598: Invalid fontset"
+#~ msgstr "E598: Viallinen fontset"
+
+#~ msgid "E597: can't select fontset"
+#~ msgstr "E597: Fontsetin valinta ei onnistu"
+
+#~ msgid "E596: Invalid font(s)"
+#~ msgstr "E596: Viallisia fontteja"
+
+#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+#~ msgstr "E617: Ei voi muuttaa GTK+2-GUIssa"
+
+#~ msgid "E531: Use \":gui\" to start the GUI"
+#~ msgstr "E531: Käytä komentoa :gui GUIn käynnistämiseen"
+
+#~ msgid "E530: Cannot change term in GUI"
+#~ msgstr "E530: Ei voi vaihtaa termiä GUIssa"
+
+#~ msgid "E522: Not found in termcap"
+#~ msgstr "E522: Puuttuu termcapista"
+
+#~ msgid "Thanks for flying Vim"
+#~ msgstr "Kiitos että ajoit Vimiä"
+
+#~ msgid "%<%f%h%m%=Page %N"
+#~ msgstr "%<%f%h%m%=Sivu %N"
#~ msgid ""
#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
+#~ "# Registers:\n"
#~ msgstr ""
#~ "\n"
-#~ "Jos aakkoslaji on ohitettu, lisää alkuun / tehdäksesi asetuksesta "
-#~ "suuraakkosia"
+#~ "# Rekisterit:\n"
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\trekisteröi gvim OLEa varten"
+#~ msgid "Illegal register name"
+#~ msgstr "Virheellinen rekisterin nimi"
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tPoista gvim OLE-rekisteristä"
+#~ msgid "freeing %ld lines"
+#~ msgstr "vapautetaan %ld riviä"
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tAvaa GUI (kuten gvimillä)"
+#~ msgid "cannot yank; delete anyway"
+#~ msgstr "Ei voi kopioida; poista joka tapauksessa"
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f tai --nofork\tEdustalle: Älä haarauta GUIn käynnistyksessä"
+#~ msgid "E775: Eval feature not available"
+#~ msgstr "E775: Eval ei ole käytettävissä"
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tÄlä käytä newcli:tä ikkunan avaamiseen"
+#~ msgid "E505: %s is read-only (add ! to override)"
+#~ msgstr "E505: %s on kirjoitussuojattu (lisää komentoon ! ohittaaksesi)"
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <laite>\t\tKäytä <laitetta> IO:hon"
+#~ msgid "E511: netbeans already connected"
+#~ msgstr "E511: netbeans on yhdistetty jo"
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tKäytä <gvimrc>-tiedostoa .gvimrc:iden sijasta"
+#~ msgid "E838: netbeans is not supported with this GUI"
+#~ msgstr "E838: netbeans ei toimi tässä käyttöliittymässä"
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tMuokkaa salattua tiedostoa"
+#~ msgid "E658: NetBeans connection lost for buffer %ld"
+#~ msgstr "E658: NetBeans-yhteys katkesi puskurille %ld"
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <näyttö>\tYhdistä vim tiettyyn X-palvelimeen"
+#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+#~ msgstr "E668: Väärä avaustila NetBeans-yhteyden infotiedostolle: %s"
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tÄlä yhdistä X-palvelimeen"
+#~ msgid "E547: Illegal mouseshape"
+#~ msgstr "E547: Virheellinen hiiren muoto"
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <tiedostoja>\tMuokkaa <tiedostoja> Vim-palvelimessa, jos "
-#~ "mahdollista"
+#~ msgid "E341: Internal error: lalloc(%ld, )"
+#~ msgstr "E341: Sisäinen virhe: lalloc(%ld, )"
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent <tiedostoja>\tSama, mutta älä ilmoita puuttuvasta "
-#~ "palvelimesta"
+#~ msgid "E340: Line is becoming too long"
+#~ msgstr "E340: Rivistä tulee liian pitkä"
#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
+#~ "[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+#~ "\n"
#~ msgstr ""
-#~ "--remote-wait <tiedostoja> kuten --remote, mutta odota tiedostojen "
-#~ "muokkaamista"
+#~ "[kutsut] yht. re/malloc() %lu, yht. free() %lu\n"
+#~ "\n"
#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
+#~ "\n"
+#~ "[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
#~ msgstr ""
-#~ "--remote-wait-silent <tiedostoja> sama, mutta älä ilmoita puuttuvasta "
-#~ "palvelimesta"
+#~ "\n"
+#~ "[tavua] yht. alloc-free %lu-%lu, käytössä %lu, käyttöhuippu %lu\n"
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <tiedostoja> kuten --remote, mutta avaa "
-#~ "välilehti joka tiedostolle"
+#~ msgid "ERROR: "
+#~ msgstr "VIRHE: "
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <näppäimiä>\tLähetä <näppäimiä> painalluksina Vimille ja "
-#~ "lopeta"
+#~ msgid "E338: Sorry, no file browser in console mode"
+#~ msgstr "E338: tiedostonselain puuttuu konsolitilasta"
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <ilmaus>\tKäsittele <ilmaus> Vim-palvelimella ja tulosta "
-#~ "tulos"
+#~ msgid "Open File dialog"
+#~ msgstr "Avausikkuna"
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tLuettele Vim-palvelinten nimet ja lopeta"
+#~ msgid "Save File dialog"
+#~ msgstr "Tallennusikkuna"
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <nimi>\tLähetä Vim-palvelimelle <nimi> tai luo se"
+#~ msgid "Select Directory dialog"
+#~ msgstr "Hakemiston valintaikkuna"
+
+#~ msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+#~ msgstr "Käännöksen ylläpitäjä: Flammie Pirinen <flammie@iki.fi>"
+
+#~ msgid "E337: Menu not found - check menu names"
+#~ msgstr "E337: Valikkoa ei löytynyt - tarkista valikkojen nimet"
+
+#~ msgid "E336: Menu path must lead to a sub-menu"
+#~ msgstr "E336: Valikkopolun pitää johtaa alivalikkoon"
+
+#~ msgid "Tear off this menu"
+#~ msgstr "Repäise valikko irti"
+
+#~ msgid "Swap file already exists!"
+#~ msgstr "Swap-tiedosto on jo olemassa"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
+#~ " [not usable with this version of Vim]"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (Motif-version) tuntemat argumentit:\n"
+#~ " [ei toimi tämän Vim-version kanssa]"
+
+#~ msgid "Using crypt key from swap file for the text file.\n"
+#~ msgstr "Käytetään swäpin salausavainta tekstitiedostolle\n"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
+#~ "to use the same key for text file and swap file"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (neXtaw-version) tuntemat argumentit:\n"
+#~ "käyttääksesi samaa avainta teksti- ja swäppitiedostoille"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
+#~ "If you wrote the text file after changing the crypt key press enter"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (Athena-version) tuntemat argumentit:\n"
+#~ "Jos kirjoitit tekstitiedoston salausavaimen vaihdon jälkeen paina enteriä"
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <näyttö>\tSuorita vim <näytössä>"
+#~ msgid ""
+#~ "\n"
+#~ "enter the new crypt key."
+#~ msgstr ""
+#~ "\n"
+#~ "anna uusi salausavain."
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tKäynnistä pienennettynä"
+#~ msgid ""
+#~ "\n"
+#~ "If you entered a new crypt key but did not write the text file,"
+#~ msgstr ""
+#~ "\n"
+#~ "Jos käytit uutta salausavainta muttet kirjoittanut tekstitiedostoa,"
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <väri>\tKäytä <väriä> taustavärinä (myös: -bg)"
+#~ msgid "Swap file is encrypted: \"%s\""
+#~ msgstr "Swap-tiedosto on salattu: %s"
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <väri>\tKäytä <väriä> tekstin värinä (myös: -fg)"
+#~ msgid ""
+#~ "E833: %s is encrypted and this version of Vim does not support encryption"
+#~ msgstr "E833: %s on salattu eikä tämä Vim tue salausta"
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <fontti>\t\tKäytä <fonttia> tekstissä (myös: -fn)"
+#~ msgid "E843: Error while updating swap file crypt"
+#~ msgstr "E843: Virhe päivitettäessä swapin kryptausta"
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <fontti>\tKäytä <fonttia> lihavoidussa tekstissä"
+#~ msgid "E289: input method doesn't support my preedit type"
+#~ msgstr "E289: syötemetodi ei tue tätä preedit-tyyppiä"
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <fontti>\tKäytä <fonttia> kursivoidussa tekstissä"
+#~ msgid "E288: input method doesn't support any style"
+#~ msgstr "E288: syötemetodi ei tue tyylejä"
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+#~ msgid "E287: Warning: Could not set destroy callback to IM"
#~ msgstr ""
-#~ "-geometry <geom>\tKäytä mittoja <geom> ikkunan asetteluun (myös: -geom)"
+#~ "E287: Varoitus: Ei voitu asettaa destroy-kutsua syötemetodipalvelimelle"
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidt <leveys>\tKäytä <leveyttä> reunuksissa (myös: -bw) "
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <leveys> Käytä <leveyttä> vierityspalkissa (myös: -sw)"
+#~ msgid "E286: Failed to open input method"
+#~ msgstr "E286: Syötemetodin avaus ei onnistu"
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <korkeus>\tKäytä <korkeutta> valikossa (myös: -mh)"
+#~ msgid "E285: Failed to create input context"
+#~ msgstr "E285: Syötekontekstin luonti ei onnistu"
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tKäytä käänteisvärejä (myös: -rv) "
+#~ msgid "E284: Cannot set IC values"
+#~ msgstr "E284: Ei voi asettaa IC-arvoja"
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tÄlä käytä käänteisvärejä (myös: +rv)"
+#~ msgid "E543: Not a valid codepage"
+#~ msgstr "E543: Koodisivu ei ole käypä"
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resurssi>\tAseta resurssi"
+#~ msgid "Missing '>'"
+#~ msgstr "> puuttuu"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
+#~ "# History of marks within files (newest to oldest):\n"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (RISC OS -version) tuntemat argumentit:\n"
-
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <luku>\tIkkunan alkuleveys sarakkeina"
+#~ "# Tiedostojen merkkien historia (uusimmasta vanhimpaan):\n"
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <luku>\tIkkunan alkukorkeus riveinä"
+#~ msgid ""
+#~ "\n"
+#~ "# Jumplist (newest first):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Hyppylista (uusin ensiksi):\n"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
+#~ "# File marks:\n"
#~ msgstr ""
#~ "\n"
-#~ "Gvimin (GTK+-version) tuntemat argumentit:\n"
+#~ "# Tiedoston merkit:\n"
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <näyttö>\tSuorita vim näytöllä <näyttö> (myös: --display)"
+#~ msgid ": Send expression failed.\n"
+#~ msgstr ": Ilmauksen lähetys epäonnistui.\n"
-# X-ikkunointijärjestelmässä saman sovelluksen saman luokan ikkunat
-# tunnistetaan rooliresursseista
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr ""
-#~ "--role <rooli>\tAseta pääikkunalle ainutlaatuinen rooli tunnisteeksi"
+#~ msgid "No display: Send expression failed.\n"
+#~ msgstr "Ei näyttöä: Ilmauksen lähetys epäonnistui.\n"
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tAvaa Vim annettuun GTK-olioon "
+#~ msgid "%d of %d edited"
+#~ msgstr "%d/%d muokattu"
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <otsikko>\tAvaa Vim isäntäohjelman sisään"
+#~ msgid ": Send failed. Trying to execute locally\n"
+#~ msgstr ": Lähetys epäonnistui. Yritetään suorittaa paikallisena\n"
+
+#~ msgid ": Send failed.\n"
+#~ msgstr ": Lähetys epäonnistui.\n"
+
+#~ msgid "No display"
+#~ msgstr "Ei näyttöä"
#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
#~ msgstr "--windowid <HWND>\tAvaa Vim annettuun win32-olioon "
-#~ msgid "No display"
-#~ msgstr "Ei näyttöä"
+#~ msgid "-P <parent title>\tOpen Vim inside parent application"
+#~ msgstr "-P <otsikko>\tAvaa Vim isäntäohjelman sisään"
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Lähetys epäonnistui.\n"
+#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+#~ msgstr "--echo-wid\t\tTulosta gvimin Window ID vakiotulosteeseen"
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Lähetys epäonnistui. Yritetään suorittaa paikallisena\n"
+#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+#~ msgstr "--socketid <xid>\tAvaa Vim annettuun GTK-olioon "
-#~ msgid "%d of %d edited"
-#~ msgstr "%d/%d muokattu"
+# X-ikkunointijärjestelmässä saman sovelluksen saman luokan ikkunat
+# tunnistetaan rooliresursseista
+#~ msgid "--role <role>\tSet a unique role to identify the main window"
+#~ msgstr ""
+#~ "--role <rooli>\tAseta pääikkunalle ainutlaatuinen rooli tunnisteeksi"
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Ei näyttöä: Ilmauksen lähetys epäonnistui.\n"
+#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
+#~ msgstr "-display <näyttö>\tSuorita vim näytöllä <näyttö> (myös: --display)"
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Ilmauksen lähetys epäonnistui.\n"
+#~ msgid ""
+#~ "\n"
+#~ "Arguments recognised by gvim (GTK+ version):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Gvimin (GTK+-version) tuntemat argumentit:\n"
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Koodisivu ei ole käypä"
+#~ msgid "-xrm <resource>\tSet the specified resource"
+#~ msgstr "-xrm <resurssi>\tAseta resurssi"
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Syötekontekstin luonti ei onnistu"
+#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+#~ msgstr "+reverse\t\tÄlä käytä käänteisvärejä (myös: +rv)"
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Syötemetodin avaus ei onnistu"
+#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
+#~ msgstr "-reverse\t\tKäytä käänteisvärejä (myös: -rv) "
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
+#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+#~ msgstr "-menuheight <korkeus>\tKäytä <korkeutta> valikossa (myös: -mh)"
+
+#~ msgid ""
+#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
#~ msgstr ""
-#~ "E287: Varoitus: Ei voitu asettaa destroy-kutsua syötemetodipalvelimelle"
+#~ "-scrollbarwidth <leveys> Käytä <leveyttä> vierityspalkissa (myös: -sw)"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: syötemetodi ei tue tyylejä"
+#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+#~ msgstr "-borderwidt <leveys>\tKäytä <leveyttä> reunuksissa (myös: -bw) "
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: syötemetodi ei tue tätä preedit-tyyppiä"
+#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+#~ msgstr ""
+#~ "-geometry <geom>\tKäytä mittoja <geom> ikkunan asetteluun (myös: -geom)"
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s on salattu eikä tämä Vim tue salausta"
+#~ msgid "-italicfont <font>\tUse <font> for italic text"
+#~ msgstr "-italicfont <fontti>\tKäytä <fonttia> kursivoidussa tekstissä"
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Swap-tiedosto on salattu: %s"
+#~ msgid "-boldfont <font>\tUse <font> for bold text"
+#~ msgstr "-boldfont <fontti>\tKäytä <fonttia> lihavoidussa tekstissä"
+
+#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+#~ msgstr "-font <fontti>\t\tKäytä <fonttia> tekstissä (myös: -fn)"
+
+#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+#~ msgstr "-foreground <väri>\tKäytä <väriä> tekstin värinä (myös: -fg)"
+
+#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
+#~ msgstr "-background <väri>\tKäytä <väriä> taustavärinä (myös: -bg)"
+
+#~ msgid "-iconic\t\tStart vim iconified"
+#~ msgstr "-iconic\t\tKäynnistä pienennettynä"
+
+#~ msgid "-display <display>\tRun vim on <display>"
+#~ msgstr "-display <näyttö>\tSuorita vim <näytössä>"
#~ msgid ""
#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
+#~ "Arguments recognised by gvim (Athena version):\n"
#~ msgstr ""
#~ "\n"
-#~ "Jos käytit uutta salausavainta muttet kirjoittanut tekstitiedostoa,"
+#~ "Gvimin (Athena-version) tuntemat argumentit:\n"
#~ msgid ""
#~ "\n"
-#~ "enter the new crypt key."
+#~ "Arguments recognised by gvim (neXtaw version):\n"
#~ msgstr ""
#~ "\n"
-#~ "anna uusi salausavain."
+#~ "Gvimin (neXtaw-version) tuntemat argumentit:\n"
#~ msgid ""
#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
+#~ "Arguments recognised by gvim (Motif version):\n"
#~ msgstr ""
#~ "\n"
-#~ "Jos kirjoitit tekstitiedoston salausavaimen vaihdon jälkeen paina enteriä"
+#~ "Gvimin (Motif-version) tuntemat argumentit:\n"
+
+#~ msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+#~ msgstr "-i <viminfo>\t\tKäytä <viminfo>-tiedostoa .viminfon sijaan"
+
+#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
+#~ msgstr "--servername <nimi>\tLähetä Vim-palvelimelle <nimi> tai luo se"
+
+#~ msgid "--serverlist\t\tList available Vim server names and exit"
+#~ msgstr "--serverlist\t\tLuettele Vim-palvelinten nimet ja lopeta"
#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
+#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
#~ msgstr ""
-#~ "\n"
-#~ "käyttääksesi samaa avainta teksti- ja swäppitiedostoille"
+#~ "--remote-expr <ilmaus>\tKäsittele <ilmaus> Vim-palvelimella ja tulosta "
+#~ "tulos"
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "Käytetään swäpin salausavainta tekstitiedostolle\n"
+#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+#~ msgstr ""
+#~ "--remote-send <näppäimiä>\tLähetä <näppäimiä> painalluksina Vimille ja "
+#~ "lopeta"
#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
+#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
+#~ "file"
#~ msgstr ""
-#~ "\n"
-#~ " [ei toimi tämän Vim-version kanssa]"
+#~ "--remote-tab[-wait][-silent] <tiedostoja> kuten --remote, mutta avaa "
+#~ "välilehti joka tiedostolle"
-#~ msgid "Tear off this menu"
-#~ msgstr "Repäise valikko irti"
+#~ msgid ""
+#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
+#~ msgstr ""
+#~ "--remote-wait-silent <tiedostoja> sama, mutta älä ilmoita puuttuvasta "
+#~ "palvelimesta"
-#~ msgid "Select Directory dialog"
-#~ msgstr "Hakemiston valintaikkuna"
+#~ msgid ""
+#~ "--remote-wait <files> As --remote but wait for files to have been edited"
+#~ msgstr ""
+#~ "--remote-wait <tiedostoja> kuten --remote, mutta odota tiedostojen "
+#~ "muokkaamista"
-#~ msgid "Save File dialog"
-#~ msgstr "Tallennusikkuna"
+#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
+#~ msgstr ""
+#~ "--remote-silent <tiedostoja>\tSama, mutta älä ilmoita puuttuvasta "
+#~ "palvelimesta"
-#~ msgid "Open File dialog"
-#~ msgstr "Avausikkuna"
+#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+#~ msgstr ""
+#~ "--remote <tiedostoja>\tMuokkaa <tiedostoja> Vim-palvelimessa, jos "
+#~ "mahdollista"
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Sori, tiedostonselain puuttuu konsolitilasta"
+#~ msgid "-X\t\t\tDo not connect to X server"
+#~ msgstr "-X\t\t\tÄlä yhdistä X-palvelimeen"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: säästetään tiedostoja...\n"
+#~ msgid "-display <display>\tConnect vim to this particular X-server"
+#~ msgstr "-display <näyttö>\tYhdistä vim tiettyyn X-palvelimeen"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: Valmis.\n"
+#~ msgid "-x\t\t\tEdit encrypted files"
+#~ msgstr "-x\t\t\tMuokkaa salattua tiedostoa"
-#~ msgid "ERROR: "
-#~ msgstr "VIRHE: "
+#~ msgid "+\t\t\tStart at end of file"
+#~ msgstr "+\t\t\tAloita tiedoston lopusta"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[tavua] yht. alloc-free %<PRIu64>-%<PRIu64>, käytössä %<PRIu64>, "
-#~ "käyttöhuippu %<PRIu64>\n"
+#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+#~ msgstr "-U <gvimrc>\t\tKäytä <gvimrc>-tiedostoa .gvimrc:iden sijasta"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[kutsut] yht. re/malloc() %<PRIu64>, yht. free() %<PRIu64>\n"
-#~ "\n"
+#~ msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+#~ msgstr "--not-a-term\t\tOhita varoitus siitä että i/o ei ole terminaali"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Rivistä tulee liian pitkä"
+#~ msgid "-T <terminal>\tSet terminal type to <terminal>"
+#~ msgstr "-T <terminaali>\tAseta terminaalin tyypiksi <terminaali>"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Sisäinen virhe: lalloc(%<PRId64>, )"
+#~ msgid "-F\t\t\tStart in Farsi mode"
+#~ msgstr "-F\t\t\tkäynnistä farsi-tilassa"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Virheellinen hiiren muoto"
+#~ msgid "-H\t\t\tStart in Hebrew mode"
+#~ msgstr "-H\t\t\tkäynnistä heprea-tilassa"
-#~ msgid "Enter encryption key: "
-#~ msgstr "Anna salausavain: "
+#~ msgid "-A\t\t\tstart in Arabic mode"
+#~ msgstr "-A\t\t\tkäynnistä arabia-tilassa"
-#~ msgid "Enter same key again: "
-#~ msgstr "Anna sama avain uudestaan: "
+#~ msgid "-dev <device>\t\tUse <device> for I/O"
+#~ msgstr "-dev <laite>\t\tKäytä <laitetta> IO:hon"
-#~ msgid "Keys don't match!"
-#~ msgstr "Avaimet eivät täsmää!"
+#~ msgid "-f\t\t\tDon't use newcli to open window"
+#~ msgstr "-f\t\t\tÄlä käytä newcli:tä ikkunan avaamiseen"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Ei voi yhdistää Netbeans #2:een"
+#~ msgid "-L\t\t\tSame as -r"
+#~ msgstr "-L\t\t\tkuten -r"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Ei voi yhdistää Netbeansiin"
+#~ msgid "-D\t\t\tDebugging mode"
+#~ msgstr "-D\t\t\tVianetsintätila"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: Väärä avaustila NetBeans-yhteyden infotiedostolle: %s"
+#~ msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+#~ msgstr "-N\t\t\tEi Vi-yhteensopivuutta: nocompatible"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "luettu Netbeans-soketista"
+#~ msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+#~ msgstr "-C\t\t\tVi-yhteensopivuustila: compatible"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: NetBeans-yhteys katkesi puskurille %<PRId64>"
+#~ msgid "-l\t\t\tLisp mode"
+#~ msgstr "-l\t\t\tLisp-tila"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans on yhdistetty jo"
+#~ msgid "-b\t\t\tBinary mode"
+#~ msgstr "-b\t\t\tBinääritila"
-#~ msgid "E505: "
-#~ msgstr "E505: "
+#~ msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+#~ msgstr "-Z\t\t\tRajoitettu tila (kuten rvimillä)"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Eval ei ole käytettävissä"
+#~ msgid "-R\t\t\tReadonly mode (like \"view\")"
+#~ msgstr "-R\t\t\tKirjoitussuojattu tila (kuten view'lla)"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "vapautetaan %<PRId64> riviä"
+#~ msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+#~ msgstr "-y\t\t\tHelppokäyttötila (kuten evimissä, ilman tiloja)"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Ei voi vaihtaa termiä GUIssa"
+#~ msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+#~ msgstr "-d\t\t\tDiff-tila (kuten vimdiffillä)"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Käytä komentoa :gui GUIn käynnistämiseen"
+#~ msgid "-E\t\t\tImproved Ex mode"
+#~ msgstr "-E\t\t\tParanneltu Ex-tila"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Ei voi muuttaa GTK+2-GUIssa"
+#~ msgid "-e\t\t\tEx mode (like \"ex\")"
+#~ msgstr "-e\t\t\tEx-tila (kute exillä)"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Viallisia fontteja"
+#~ msgid "-v\t\t\tVi mode (like \"vi\")"
+#~ msgstr "-v\t\t\tVi-tila (kuten villä)"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: Fontsetin valinta ei onnistu"
+#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+#~ msgstr "-f tai --nofork\tEdustalle: Älä haarauta GUIn käynnistyksessä"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Viallinen fontset"
+#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+#~ msgstr "-g\t\t\tAvaa GUI (kuten gvimillä)"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: Leveän fontin valinta ei onnistu"
+#~ msgid "-unregister\t\tUnregister gvim for OLE"
+#~ msgstr "-unregister\t\tPoista gvim OLE-rekisteristä"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Viallinen leveä fontti"
+#~ msgid "-register\t\tRegister this gvim for OLE"
+#~ msgstr "-register\t\trekisteröi gvim OLEa varten"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Hiirtä ei tueta"
+#~ msgid ""
+#~ "\n"
+#~ "Where case is ignored prepend / to make flag upper case"
+#~ msgstr ""
+#~ "\n"
+#~ "Jos aakkoslaji on ohitettu, lisää alkuun / tehdäksesi asetuksesta "
+#~ "suuraakkosia"
-#~ msgid "cannot open "
-#~ msgstr "ei voi avata "
+#~ msgid ""
+#~ "\n"
+#~ " or:"
+#~ msgstr ""
+#~ "\n"
+#~ " tai:"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Ei voi avata ikkunaa\n"
+#~ msgid " vim [arguments] "
+#~ msgstr " vim [argumentit] "
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigados 2.04 tai uudempi tarvitaan\n"
+#~ msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+#~ msgstr "Vim: Virhe: Tämä versio Vimistä ei toimi Cygwinin terminaalissa\n"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Tarvitaan %s versio %<PRId64>\n"
+#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+#~ msgstr "Vim: Virhe: Gvimin käynnistys NetBeansistä ei onnistu\n"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Ei voi avata NILiä:\n"
+#~ msgid "This Vim was not compiled with the diff feature."
+#~ msgstr "Tähän Vimiin ei ole käännetty diff-toimintoja mukaan."
-#~ msgid "Cannot create "
-#~ msgstr "Ei voi luoda "
+#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
+#~ msgstr "-nb:tä ei voi käyttää, koska sitä ei käännetty mukaan\n"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim sulkeutuu koodilla %d\n"
+#~ msgid "netbeans is not supported with this GUI\n"
+#~ msgstr "netbeans ei toimi tässä käyttöliittymässä\n"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "ei voi vaihtaa konsolitilaa?\n"
+#~ msgid "%d files to edit\n"
+#~ msgstr "%d tiedostoa muokattavana\n"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ei ole konsoli?\n"
+#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
+#~ msgstr "E251: VIMin instanssin rekisteriarvo on virheellinen, poistettiin."
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Kuorta ei voi avata asetuksella -f"
+#~ msgid "E573: Invalid server id used: %s"
+#~ msgstr "E573: Virheellinen palvelimen tunniste: %s"
-#~ msgid "Cannot execute "
-#~ msgstr "Ei voi suorittaa "
+#~ msgid "E248: Failed to send command to the destination program"
+#~ msgstr "E248: Komennon lähetys kohdeohjelmalle ei onnistu"
-#~ msgid "shell "
-#~ msgstr "kuori "
+#~ msgid "Unable to register a command server name"
+#~ msgstr "Komentopalvelimen nimen rekisteröinti ei onnistu"
-#~ msgid " returned\n"
-#~ msgstr " palautti\n"
+#~ msgid "cannot get line"
+#~ msgstr "ei voida hakea riviä"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE liian pieni."
+#~ msgid "E572: exit code %d"
+#~ msgstr "E572: palautusarvo %d"
-#~ msgid "I/O ERROR"
-#~ msgstr "IO-virhe"
+#~ msgid ""
+#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
+#~ "loaded."
+#~ msgstr "E571: komento ei toimi, Tcl-kirjastoa ei voitu ladata."
-#~ msgid "Message"
-#~ msgstr "Viesti"
+#~ msgid "cannot register callback command: buffer/window reference not found"
+#~ msgstr ""
+#~ "callbackia ei voi rekisteröidä: puskurin tai ikkunan viitettä ei löydy"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "columns ei ole 80, ei voi suorittaa ulkoista komentoa"
+#~ msgid ""
+#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
+#~ "dev@vim.org"
+#~ msgstr ""
+#~ "E280: kriittinen TCL-virhe: reflist hajalla? Ilmoita asiasta "
+#~ "postituslistalle vim-dev@vim.org"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Tulostimen valinta epäonnistui"
+#~ msgid ""
+#~ "cannot register callback command: buffer/window is already being deleted"
+#~ msgstr "callbackia ei voi rekisteröidä: puskuri tai ikkuna on poistettu"
-#~ msgid "to %s on %s"
-#~ msgstr "tulostimelle %s kohteessa %s"
+#~ msgid "cannot create buffer/window command: object is being deleted"
+#~ msgstr "ei voi luoda puskuri- tai ikkunakomentoa, olio on poistumassa"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Tuntematon tulostimen fontti: %s"
+#~ msgid "vim error"
+#~ msgstr "vim-virhe"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Tulostinvirhe: %s"
+#~ msgid "unknown vimOption"
+#~ msgstr "tuntematon vimOption"
-#~ msgid "Printing '%s'"
-#~ msgstr "Tulostetaan %s"
+#~ msgid "unknown flag: "
+#~ msgstr "tuntematon asetus: "
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: Virheellinen merkistön nimi %s fontin nimessä %s"
+#~ msgid "cannot insert/append line"
+#~ msgstr "rivin lisäys ei onnistu"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Virheellinen merkki %c fontin nimessä %s"
+#~ msgid "row %d column %d"
+#~ msgstr "rivi %d sarake %d"
+
+#~ msgid "mark not set"
+#~ msgstr "merkko ei ole asetettu"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Kaksoissignaali, lopetetaan\n"
+#~ msgid "cannot set line(s)"
+#~ msgstr "ei voi asettaa rivejä"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Tappava signaali %s\n"
+#~ msgid "not implemented yet"
+#~ msgstr "ei toteutettu"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Tappava signaali\n"
+#~ msgid "E273: unknown longjmp status %d"
+#~ msgstr "E273: tuntematon longjmp-tila %d"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "X-näytön avaus vei %<PRId64> millisekuntia"
+#~ msgid "E272: unhandled exception"
+#~ msgstr "E272: käsittelemätön poikkeus"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: X-virhe\n"
+#~ msgid "E271: retry outside of rescue clause"
+#~ msgstr "E271: retry rescuen ulkopuolella"
-#~ msgid "Testing the X display failed"
-#~ msgstr "X-näytön testaus epäonnistui"
+#~ msgid "E269: unexpected break"
+#~ msgstr "E269: Odotuksenvastainen break"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "X-näytön avaus aikakatkaistiin"
+#~ msgid "E268: unexpected next"
+#~ msgstr "E268: Odotuksenvastainen next"
+
+#~ msgid "E267: unexpected return"
+#~ msgstr "E267: odotuksenvastainen return"
#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
+#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
+#~ "loaded."
+#~ msgstr "E266: komento ei toimi, Ruby-kirjastoa ei voitu ladata."
+
+#~ msgid "E265: $_ must be an instance of String"
+#~ msgstr "E265: muuttujan $_ pitää olla Stringin instanssi"
+
+#~ msgid "E837: This Vim cannot execute :py3 after using :python"
#~ msgstr ""
-#~ "\n"
-#~ "Kuoren sh suoritus ei onnistu\n"
+#~ "E837: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+
+#~ msgid "E659: Cannot invoke Python recursively"
+#~ msgstr "E659: Pythonia ei voi kutsua rekursiivisesti"
#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
+#~ "E887: Sorry, this command is disabled, the Python's site module could not "
+#~ "be loaded."
#~ msgstr ""
-#~ "\n"
-#~ "Putkia ei voi tehdä\n"
+#~ "E887: Komento ei toimi, Pythonin site-moduulien lataaminen ei onnistunut."
#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
+#~ "E263: Sorry, this command is disabled, the Python library could not be "
+#~ "loaded."
+#~ msgstr "E263: komento ei toimi, Python-kirjaston lataaminen ei onnistunut."
+
+#~ msgid "E836: This Vim cannot execute :python after using :py3"
#~ msgstr ""
-#~ "\n"
-#~ "Ei voi haarauttaa\n"
+#~ "E836: Python: Ei voi käyttää komentoja :py ja :py3 samassa istunnossa"
+
+#~ msgid "not allowed in the Vim sandbox"
+#~ msgstr "ei sallittu Vimin hiekkalaatikossa"
+
+#~ msgid "linenr out of range"
+#~ msgstr "rivinumero arvoalueen ulkopuolelta"
+
+#~ msgid "window is invalid"
+#~ msgstr "ikkuna on virheellinen"
+
+#~ msgid "buffer is invalid"
+#~ msgstr "puskuri on virheellinen"
+
+#~ msgid "Vim error"
+#~ msgstr "Vim-virhe"
+
+#~ msgid "Vim error: ~a"
+#~ msgstr "Vim-virhe: ~a"
+
+#~ msgid "couldn't open buffer"
+#~ msgstr "ei voitu avata puskuria"
+
+#~ msgid "unknown option"
+#~ msgstr "tuntematon asetus"
+
+#~ msgid "hidden option"
+#~ msgstr "piilotettu asetus"
+
+#~ msgid "expressions disabled at compile time"
+#~ msgstr "ilmaukset poistettu käytöstä käännösaikana"
+
+#~ msgid "invalid expression"
+#~ msgstr "virheellinen ilmaus"
#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
+#~ "E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+#~ "could not be loaded."
#~ msgstr ""
-#~ "\n"
-#~ "Komento loppui\n"
+#~ "E895: Komento ei toimi, MzScheme-moduulia racket/base ei voitu ladata."
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP kadotti ICE-yhteyden"
+#~ msgid ""
+#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
+#~ "be loaded."
+#~ msgstr "E815: komento ei toimi, MzScheme-kirjastoa ei voitu ladata."
-#~ msgid "Opening the X display failed"
-#~ msgstr "X-näytön avaus epäonnistui"
+#~ msgid "Lua library cannot be loaded."
+#~ msgstr "Luan kirjastoa ei voitu ladata."
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP käsittelee save-yourself-pyyntöä"
+#~ msgid "E626: cannot get cscope database information"
+#~ msgstr "E626: ei voi hakea cscope-tietokannan tietoja"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP avaa yhteyttä"
+#~ msgid "E625: cannot open cscope database: %s"
+#~ msgstr "E625: ei voi avata cscope-tietokantaa: %s"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP:n ICE-yhteyden tarkkailu epäonnistui"
+#~ msgid "E563: stat error"
+#~ msgstr "E563: stat-virhe"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection epäonnistui: %s"
+#~ msgid "E256: Hangul automata ERROR"
+#~ msgstr "E256: Hangu-automaattivirhe"
-#~ msgid "At line"
-#~ msgstr "Rivillä"
+#~ msgid "Size:"
+#~ msgstr "Koko:"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Vim32.dll:ää ei voitu ladata"
+#~ msgid "Style:"
+#~ msgstr "Tyyli:"
-#~ msgid "VIM Error"
-#~ msgstr "VIM-virhe"
+#~ msgid "Font:"
+#~ msgstr "Fontti:"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Ei voitu korjata funktio-osoittimia DLL:ssä"
+#~ msgid "Encoding:"
+#~ msgstr "Koodaus:"
-#~ msgid "shell returned %d"
-#~ msgstr "kuori palautti arvon %d"
+#~ msgid "Show size in Points"
+#~ msgstr "Näytä koko pisteinä"
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Napattiin %s\n"
+#~ msgid "Name:"
+#~ msgstr "Nimi:"
-#~ msgid "close"
-#~ msgstr "sulkeminen"
+#~ msgid "Vim - Font Selector"
+#~ msgstr "Vim - fonttivalitsin"
-#~ msgid "logoff"
-#~ msgstr "uloskirjautuminen"
+#~ msgid "no specific match"
+#~ msgstr "ei tarkkaa täsmäystä"
-#~ msgid "shutdown"
-#~ msgstr "sammutus"
+#~ msgid "&Dismiss"
+#~ msgstr "&Ohita"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Komentoa ei löydy"
+#~ msgid "Invalid font specification"
+#~ msgstr "Virheellinen fonttimääritys"
+
+#~ msgid "Font1 width: %ld"
+#~ msgstr "Fontti1:n leveys: %ld"
+
+#~ msgid "Font0 width: %ld"
+#~ msgstr "Fontti0:n leveys: %ld"
+
+#~ msgid "Font%ld width is not twice that of font0"
+#~ msgstr "Fontti%ld:n leveys ei ole kaksi kertaa fontti0:n"
+
+#~ msgid "Font1: %s"
+#~ msgstr "Fontti1: %s"
+
+#~ msgid "Font0: %s"
+#~ msgstr "Fontti0: %s"
+
+#~ msgid "E253: Fontset name: %s"
+#~ msgstr "E253: Fontsetin nimi: %s"
+
+#~ msgid "Font '%s' is not fixed-width"
+#~ msgstr "Fontti %s ei ole tasavälinen"
+
+#~ msgid "E252: Fontset name: %s"
+#~ msgstr "E252: Fontsetin nimi: %s"
+
+#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+#~ msgstr "E250: Seuraavien merkistöjoukkojen fontit puuttuvat fontsetistä %s:"
#~ msgid ""
-#~ "VIMRUN.EXE not found in your $PATH.\n"
-#~ "External commands will not pause after completion.\n"
-#~ "See :help win32-vimrun for more information."
+#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
#~ msgstr ""
-#~ "VIMRUN.EXEä ei löydy muuttujasta $PATH.\n"
-#~ "Ulkoiset komennot eivät pysähdy suorituksen lopussa.\n"
-#~ "Lisätietoja komennolla :help win32-vimrun"
+#~ "Vim E458: Ei voi varata värikartan alkiota, värit voivat mennä väärin"
-#~ msgid "Vim Warning"
-#~ msgstr "Vim-varoitus"
+# MDI eli windowsin moni-ikkunasovellus
+#~ msgid "E672: Unable to open window inside MDI application"
+#~ msgstr "E672: Ikkunaa ei voitu avata MDI-sovellukseen"
-#~ msgid "Error file"
-#~ msgstr "Virhetiedosto"
+# OLE on object linking and embedding på windowska
+#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+#~ msgstr "E243: Argumenttia ei tueta: -%s, käytä OLE-versiota"
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Muutosta kohteessa %s ei tueta"
+#~ msgid "Directory\t*.nothing\n"
+#~ msgstr "Hakemisto\t*.nothing\n"
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Tägitiedoston polku katkaistu kohdassa %s\n"
+#~ msgid "Not Used"
+#~ msgstr "Ei käytössä"
-#~ msgid "new shell started\n"
-#~ msgstr "uusi kuori avattu\n"
+#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
+#~ msgstr "Etsi ja korvaa (\\\\:llä löytää \\:t)"
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "Käytettiin CUT_BUFFER0:aa tyhjän valinnan sijaan"
+#~ msgid "Find string (use '\\\\' to find a '\\')"
+#~ msgstr "Etsi merkkijonoa (\\\\:llä löytää \\:t)"
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Ei voi kumota, jatketaan silti"
+#~ msgid "Open tab..."
+#~ msgstr "Avaa välilehti..."
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Salaamattomalla tiedostolla on salattu kumoustiedosto: %s"
+#~ msgid "&Undo"
+#~ msgstr "&Kumoa"
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Kumoustiedoston purku epäonnistui: %s"
+#~ msgid "Replace &All"
+#~ msgstr "Korvaa k&aikki"
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Kumoustiedosto on salattu: %s"
+#~ msgid "&Replace"
+#~ msgstr "Ko&rvaa"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16- t. 32-bittinen GUI-versio"
+#~ msgid "Find &Next"
+#~ msgstr "Hae &seuraava"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64-bittinen GUI-versio"
+#~ msgid "Selection"
+#~ msgstr "Valinta"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32-bittinen GUI-version"
+#~ msgid "&OK"
+#~ msgstr "&Ok"
-#~ msgid " in Win32s mode"
-#~ msgstr " Win32s-tilassa"
+#~ msgid "Files"
+#~ msgstr "Tiedostot"
-#~ msgid " with OLE support"
-#~ msgstr " OLE-tuella"
+#~ msgid "&Help"
+#~ msgstr "O&hje"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32-bittinen konsoliversio"
+#~ msgid "Filter"
+#~ msgstr "Suodatus"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32-bittinen konsoliversio"
+#~ msgid "Directories"
+#~ msgstr "Hakemistot"
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16-bittinen versio"
+#~ msgid "&Cancel"
+#~ msgstr "&Peru"
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32-bittinen MS-DOS-versio"
+#~ msgid "&Filter"
+#~ msgstr "&Suodata"
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16-bittinen MS-DOS-versio"
+#~ msgid "Vim: Main window unexpectedly destroyed\n"
+#~ msgstr "Vim: Pääikkuna tuhoutui odottamatta\n"
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X-version (unix)"
+#~ msgid "Open Tab..."
+#~ msgstr "Avaa välilehti..."
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X-version"
+#~ msgid "New tab"
+#~ msgstr "Uusi välilehti"
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS-version"
+#~ msgid "Close tab"
+#~ msgstr "Sulje välilehti"
-#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
-#~ msgstr ""
-#~ "\n"
-#~ "RISC OS-version"
+#~ msgid "Vim: Received \"die\" request from session manager\n"
+#~ msgstr "Vim: sessiomanageri lähetti die-pyynnön\n"
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "OpenVMS-version"
+#~ msgid "_Close"
+#~ msgstr "_Sulje"
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Big-version "
+#~ msgid "Replace All"
+#~ msgstr "Korvaa kaikki"
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Normal-versio "
+#~ msgid "Replace"
+#~ msgstr "Korvaa"
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Small-versio "
+#~ msgid "Find Next"
+#~ msgstr "Etsi seuraava"
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Tiny-versio "
+#~ msgid "Down"
+#~ msgstr "Alas"
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "GTK2-Gnome-GUIlla."
+#~ msgid "Up"
+#~ msgstr "Ylös"
-#~ msgid "with GTK2 GUI."
-#~ msgstr "GTK2-GUIlla."
+#~ msgid "Direction"
+#~ msgstr "Suunta"
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "X11-Motif-GUIlla."
+#~ msgid "Match case"
+#~ msgstr "Kirjaintaso"
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "X11-neXtaw-GUIlla."
+#~ msgid "Match whole word only"
+#~ msgstr "Korvaa kokonaisia sanoja"
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "X11-Athena-GUIlla."
+#~ msgid "Replace with:"
+#~ msgstr "Korvaa:"
-#~ msgid "with Photon GUI."
-#~ msgstr "Photon-GUIlla."
+#~ msgid "Find what:"
+#~ msgstr "Etsi:"
-#~ msgid "with GUI."
-#~ msgstr "GUIlla."
+#~ msgid "VIM - Search..."
+#~ msgstr "VIM - Etsi..."
-#~ msgid "with Carbon GUI."
-#~ msgstr "Carbon-GUIlla."
+#~ msgid "VIM - Search and Replace..."
+#~ msgstr "VIM - Etsi ja korvaa..."
-#~ msgid "with Cocoa GUI."
-#~ msgstr "Cocoa-GUIlla."
+#~ msgid "Input _Methods"
+#~ msgstr "Syöte_menetelmät"
-#~ msgid "with (classic) GUI."
-#~ msgstr "perinteisellä GUIlla."
+#~ msgid "No"
+#~ msgstr "Ei"
-#~ msgid " system gvimrc file: \""
-#~ msgstr " järjestelmän gvimrc: \""
+#~ msgid "Yes"
+#~ msgstr "Kyllä"
-#~ msgid " user gvimrc file: \""
-#~ msgstr " käyttäjän gvimrc: \""
+#~ msgid "_OK"
+#~ msgstr "_OK"
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "2. käyttäjän gvimrc: \""
+#~ msgid "_Open"
+#~ msgstr "_Avaa"
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "3. käyttäjän gvimrc: \""
+#~ msgid "_Save"
+#~ msgstr "_Tallenna"
-#~ msgid " system menu file: \""
-#~ msgstr " järjestelmävalikko: \""
+#~ msgid "_Cancel"
+#~ msgstr "_Peru"
-#~ msgid "Compiler: "
-#~ msgstr "Käännin: "
+#~ msgid "E232: Cannot create BalloonEval with both message and callback"
+#~ msgstr "E232: Ei voi luoda BalloonEvalia viestille ja callbackille"
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "valikko Ohje->Orvot lisätietoja varten "
+#~ msgid "Vim dialog"
+#~ msgstr "Vim-ikkuna"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Suoritetaan tilattomana, kirjoitettu teksti syötetään"
+#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+#~ msgstr "Vierityspalkki: Pixmapin geometria ei selviä"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda syötetilaa"
+#~ msgid "Cancel"
+#~ msgstr "Peru"
-#~ msgid " for two modes "
-#~ msgstr " kahta tilaa varten "
+#~ msgid "OK"
+#~ msgstr "OK"
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "valikko Muokkaa->Yleiset asetukset->Vaihda Vi-yhteensopivuutta"
+#~ msgid "E615: vim_SelFile: can't get current directory"
+#~ msgstr "E615: vim_SelFile: nykyistä hakemistoa ei saada selville"
-#~ msgid " for Vim defaults "
-#~ msgstr " Vim-oletuksia varten"
+#~ msgid "Pathname:"
+#~ msgstr "Polku:"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "VAROITUS: Window 95/98/ME havaittu"
+#~ msgid "E614: vim_SelFile: can't return to current directory"
+#~ msgstr "E614: vim_SelFile: nykyiseen hakemistoon ei voi palata"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "kirjoita :help windows95<Enter> lisätietoja varten"
+#~ msgid "E616: vim_SelFile: can't get font %s"
+#~ msgstr "E616: vim_SelFile: ei saada fonttia %s"
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Kirjaston %s lataaminen ei onnistu"
+#~ msgid "<cannot open> "
+#~ msgstr "<ei voi avata> "
+
+#~ msgid "No match at cursor, finding next"
+#~ msgstr "Ei täsmäystä kursorin alla, etsitään seuraava"
+
+#~ msgid "E599: Value of 'imactivatekey' is invalid"
+#~ msgstr "E599: imactivatekeyn arvo on virheellinen"
+
+#~ msgid "E231: 'guifontwide' invalid"
+#~ msgstr "E231: guifontwide virheellinen"
+
+#~ msgid "E665: Cannot start GUI, no valid font found"
+#~ msgstr "E665: Ei voi avata GUIta, sopivaa fonttia ei löydy"
+
+#~ msgid "E230: Cannot read from \"%s\""
+#~ msgstr "E230: Ei voi lukea kohteesta %s"
+
+#~ msgid "E229: Cannot start the GUI"
+#~ msgstr "E229: GUIn käynnistys ei onnistu"
+
+#~ msgid "E851: Failed to create a new process for the GUI"
+#~ msgstr "E851: Ei voitu luoda uutta prosessia käyttöliittymälle"
+
+# tietääkseni resurssiforkki on applen tiedostojärjestelmän tunnistejuttujuttu
+#~ msgid "E460: The resource fork would be lost (add ! to override)"
+#~ msgstr "E460: resurssiosa häviäisi (lisää komentoon ! ohittaaksesi)"
+
+#~ msgid "writing to device disabled with 'opendevice' option"
+#~ msgstr "laitteeseen kirjoittaminen pois käytöstä opendevice-asetuksella"
+
+#~ msgid "Partial writes disallowed for NetBeans buffers"
+#~ msgstr "Osittaiset kirjoitukset kielletty NetBeans-puskureissa"
+
+#~ msgid "NetBeans disallows writes of unmodified buffers"
+#~ msgstr "NetBeans ei salli kirjoittaa muokkaamattomiin puskureihin"
+
+#~ msgid "Reading from stdin..."
+#~ msgstr "Luetaan vakiosyötteestä"
+
+#~ msgid "Vim: Reading from stdin...\n"
+#~ msgstr "Vim: Luetaan vakiosyötteestä...\n"
+
+#~ msgid "is a device (disabled with 'opendevice' option)"
+#~ msgstr "on laite (ei käytössä opendevice-asetuksen takia)"
+
+#~ msgid "Debug Line"
+#~ msgstr "Vianetsintärivi"
+
+#~ msgid "Input Line"
+#~ msgstr "Syöterivi"
+
+#~ msgid "Expression"
+#~ msgstr "Ilmaus"
+
+#~ msgid "Search String"
+#~ msgstr "Hakujono"
+
+#~ msgid "Command Line"
+#~ msgstr "Komentorivi"
#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr "Sori, komento ei toimi, Perl kirjastoa ei voinut ladata."
+#~ "\n"
+#~ "# %s History (newest to oldest):\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# %s Historia (uusimmasta alkaen):\n"
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr "E299: Perl-suoritus kielletty hiekkalaatikossa ilman Safe-moduulia"
+#~ msgid "E196: No digraphs in this version"
+#~ msgstr "E196: Digraafeja ei ole tässä versiossa"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "&Muokkaa usealla Vimillä"
+#~ msgid "E195: Cannot open viminfo file for reading"
+#~ msgstr "E195: Viminfoa ei voi avata lukemista varten"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Muokkaa yhdellä &Vimillä"
+#~ msgid "E809: #< is not available without the +eval feature"
+#~ msgstr "E809: #< ei ole käytössä jollei +eval ole päällä"
-#~ msgid "Diff with Vim"
-#~ msgstr "Diffi Vimillä"
+#~ msgid "Save Setup"
+#~ msgstr "Tallenna asetukset"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Muokkaa &Vimillä"
+#~ msgid "Save Session"
+#~ msgstr "Tallenna sessio"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Muokkaa olemassaolevalla Vimillä - "
+#~ msgid "Save View"
+#~ msgstr "Tallenna näkymä"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Muokkaa valittuja tiedostoja Vimillä"
+#~ msgid "Save Redirection"
+#~ msgstr "Tallenna uudelleenosoitus"
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "Virhe prosessin käynnistämisessä, varmista että gvim on polulla"
+#~ msgid "E930: Cannot use :redir inside execute()"
+#~ msgstr "E930: Komentoa :redir ei voi käyttää funktion execute() sisällä"
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll-virhe"
+#~ msgid "E466: :winpos requires two number arguments"
+#~ msgstr "E466: :winpos vaatii kaksi lukuargumenttia"
-#~ msgid "Path length too long!"
-#~ msgstr "Liian pitkä polku"
+#~ msgid "E188: Obtaining window position not implemented for this platform"
+#~ msgstr "E188: Ikkunan sijainnin selvitys ei toimi tällä alustalla"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Tuntematon fontset: %s"
+#~ msgid "Window position: X %d, Y %d"
+#~ msgstr "Ikkunan sijainti: X %d, Y %d"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Tuntematon fontti: %s"
+#~ msgid ""
+#~ "E747: Cannot change directory, buffer is modified (add ! to override)"
+#~ msgstr ""
+#~ "E747: Hakemistoa ei voida muuttaa, puskuria on muokattu (lisää "
+#~ "komentoon ! ohittaaksesi"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Fontti %s ei ole tasavälinen"
+#~ msgid "Append File"
+#~ msgstr "Lisää tiedostoon"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Ei voitu ladta kirjastofunktiota %s"
+#~ msgid "Edit File in new window"
+#~ msgstr "Muokkaa uudessa ikkunassa"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: Hepreaa ei voi käyttää, koska sitä ei käännetty mukaan\n"
+#~ msgid "unknown"
+#~ msgstr "tuntematon"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Farsia ei voi käyttää, koska sitä ei käännetty mukaan\n"
+#~ msgid "E172: Only one file name allowed"
+#~ msgstr "E172: Vain yksi tiedostonimi sallitaan"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: Arabiaa ei voi käyttää, koska sitä ei käännetty mukaan\n"
+#~ msgid "Source Vim script"
+#~ msgstr "Lataa vim-skripti"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: palvelinta %s ei ole rekisteröitynä"
+#~ msgid " (NOT FOUND)"
+#~ msgstr " (EI LÖYTYNYT)"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: näyttöä ei voi avata"
+#~ msgid ""
+#~ "\n"
+#~ "# Last Substitute String:\n"
+#~ "$"
+#~ msgstr ""
+#~ "\n"
+#~ "# Viimeisin korvausmerkkijono:\n"
+#~ "$"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Virheellinen ilmaus saatu"
+#~ msgid "Edit File"
+#~ msgstr "Muokkaa tiedostoa"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Alue on suojattu, muuttaminen ei onnistu"
+#~ msgid "Save As"
+#~ msgstr "Tallenna nimellä"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ei tue muutoksia kirjoitussuojattuihin tiedostoihin"
+#~ msgid ""
+#~ "\n"
+#~ "# Bar lines, copied verbatim:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Bar-rivit, kopiotu sellaisenaan:\n"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Tarvitaan salausavain kohteelle %s "
+#~ msgid "Illegal starting char"
+#~ msgstr "Virheellinen aloitusmerkki"
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines()-komennolle pitää antaa merkkijonolista"
+#~ msgid "# Value of 'encoding' when this file was written\n"
+#~ msgstr "# encoding-muuttujan arvo tiedostoa kirjoitettaessa\n"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: Virhe IO-olioiden alustuksessa"
+#~ msgid ""
+#~ "# You may edit it if you're careful!\n"
+#~ "\n"
+#~ msgstr ""
+#~ "# Muokkaa varovasti!\n"
+#~ "\n"
-#~ msgid "no such buffer"
-#~ msgstr "puskuria ei ole"
+#~ msgid "# This viminfo file was generated by Vim %s.\n"
+#~ msgstr "# Vimin %s generoima viminfo-tiedosto.\n"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "yritettiin viitata poistettuun ikkunaan"
+#~ msgid "E138: Can't write viminfo file %s!"
+#~ msgstr "E138: Viminfo-tiedoston kirjoittaminen ei onnistu %s"
-#~ msgid "readonly attribute"
-#~ msgstr "kirjoitussuojattu attribuutti"
+#~ msgid "E929: Too many viminfo temp files, like %s!"
+#~ msgstr "E929: liikaa viminfo-väliaikaistiedostoja, kuten %s."
-#~ msgid "cursor position outside buffer"
-#~ msgstr "kursorin sijainti puskurin ulkopuolella"
+#~ msgid "E136: viminfo: Too many errors, skipping rest of file"
+#~ msgstr "E136: viminfo: liikaa virheitä, ohitetaan lopputiedosto"
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<ikkunaolio (poistettu) kohdassa %p>"
+#~ msgid "%sviminfo: %s in line: "
+#~ msgstr "%sviminfo: %s rivillä: "
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<ikkunaolio (tuntematon) kohdassa %p>"
+#~ msgid "E258: Unable to send to client"
+#~ msgstr "E258: Asiakkaalle lähetys ei onnistunut"
-#~ msgid "<window %d>"
-#~ msgstr "<ikkuna %d>"
+#~ msgid "E277: Unable to read a server reply"
+#~ msgstr "E277: Palvelimen vastauksen lukeminen ei onnistunut"
-#~ msgid "no such window"
-#~ msgstr "ikkunaa ei ole"
+#~ msgid "E240: No connection to Vim server"
+#~ msgstr "E240: Ei yhteyttä vim-palvelimeen"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "yritettiin viitata poistettuun puskuriin"
+#~ msgid ""
+#~ "&OK\n"
+#~ "&Cancel"
+#~ msgstr ""
+#~ "&OK\n"
+#~ "&Peru"
+
+#~ msgid ""
+#~ "\n"
+#~ "# global variables:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# globaalit muuttujat:\n"
+
+#~ msgid "E729: using Funcref as a String"
+#~ msgstr "E729: Funcref ei käy merkkijonosta"
+
+#~ msgid "E914: Using a Channel as a Float"
+#~ msgstr "E914: Käytettiin Channelia Floattina"
+
+#~ msgid "E911: Using a Job as a Float"
+#~ msgstr "E911: Job ei käy Floatista"
+
+#~ msgid "E913: Using a Channel as a Number"
+#~ msgstr "E913: Channel ei käy Numberista"
+
+#~ msgid "E910: Using a Job as a Number"
+#~ msgstr "E910: Job ei käy Numberista"
+
+#~ msgid "E703: Using a Funcref as a Number"
+#~ msgstr "E703: Funcref ei käy Numberista"
+
+#~ msgid "E724: variable nested too deep for displaying"
+#~ msgstr "E724: muuttuja on upotettu liian syvälle näytettäväksi"
+
+#~ msgid "Patch file"
+#~ msgstr "Patch-tiedosto"
+
+#~ msgid "[crypted]"
+#~ msgstr "[salattu]"
+
+#~ msgid "Keys don't match!"
+#~ msgstr "Avaimet eivät täsmää!"
-# New Line eli uusi rivinvaihtomerkki (ei CR, LF tai CR LF)
-#~ msgid "[NL found]"
-#~ msgstr "[NL puuttuu]"
+#~ msgid "Enter same key again: "
+#~ msgstr "Anna sama avain uudestaan: "
-#~ msgid "Vim dialog..."
-#~ msgstr "Vim-ikkuna..."
+#~ msgid "Enter encryption key: "
+#~ msgstr "Anna salausavain: "
-#~ msgid "Font Selection"
-#~ msgstr "Fontin valinta"
+#~ msgid "Warning: Using a weak encryption method; see :help 'cm'"
+#~ msgstr "Varoitus: Käytetään heikkoa salausmenetelmää, ks. :help 'cm'"
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: enimmäismäärä cscope-yhteyksiä otettu"
+#~ msgid "E821: File is encrypted with unknown method"
+#~ msgstr "E821: Tiedoston salaus on tuntematon"
+
+#~ msgid "E918: buffer must be loaded: %s"
+#~ msgstr "E918: puskuria ei voi ladata: %s"
+
+#~ msgid "E915: in_io buffer requires in_buf or in_name to be set"
+#~ msgstr "E915: in_io-puskurilla pitää olla in_buf tai in_name asetettu"
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <nimi>\t\tKäytä resurssia vim <nimenä>"
+#~ msgid "E920: _io file requires _name to be set"
+#~ msgstr "E920: _io-tiedostolla pitää olla _name asetettu"
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (toteuttamatta)\n"
+#~ msgid "E906: not an open channel"
+#~ msgstr "E906: ei ole avoin kanava"
+
+#~ msgid ""
+#~ "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+#~ msgstr ""
+#~ "E912: ei voida käyttää funktioita ch_evalexpr(), ch_sendexpr() raa'an tai "
+#~ "nl-kanavan kanssa"
-#~ msgid "E290: over-the-spot style requires fontset"
-#~ msgstr "E290: over-the-spot-tyylissä pitää olla fontset"
+#~ msgid "E917: Cannot use a callback with %s()"
+#~ msgstr "E917: Ei voitu käyttää callbackia %s()"
-#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
-#~ msgstr "E291: GTK+-versio vanhempi kuin 1.2.3: Tila-alue poistettu käytöstä"
+#~ msgid ""
+#~ "\n"
+#~ "# Buffer list:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "# Puskuriluettelo:\n"
-#~ msgid "E292: Input Method Server is not running"
-#~ msgstr "E292: Syötemetodipalvelin ei ole käynnissä"
+#~ msgid "E931: Buffer cannot be registered"
+#~ msgstr "E931: Puskuria ei voi rekisteröidä"
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: containedin ei sovi tähän"
+#~ msgid "E819: Blowfish test failed"
+#~ msgstr "E819: Blowfish-testi epäonnistui"
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "GTK-Gnome-GUIlla."
+#~ msgid "E818: sha256 test failed"
+#~ msgstr "E818: sha256-testi epäonnistui failed"
-#~ msgid "with GTK GUI."
-#~ msgstr "GTK-GUIlla."
+#~ msgid "E817: Blowfish big/little endian use wrong"
+#~ msgstr "E817: Blowfishin tavujärjestys väärä"
-#~ msgid "-V[N]\t\tVerbose level"
-#~ msgstr "-V[N]\t\tMonisanaisuustaso"
+#~ msgid "E820: sizeof(uint32_t) != 4"
+#~ msgstr "E820: sizeof(uint32_t) != 4"
-#~ msgid "...(truncated)"
-#~ msgstr "...(katkaistu)"
+#~ msgid "E831: bf_key_init() called with empty password"
+#~ msgstr "E831: bf_key_init() tyhjällä salasanalla"
diff --git a/src/nvim/po/fr.po b/src/nvim/po/fr.po
index 41efd5c5e3..5c4c154654 100644
--- a/src/nvim/po/fr.po
+++ b/src/nvim/po/fr.po
@@ -1,224 +1,199 @@
+
# French Translation for Vim
#
# Do ":help uganda" in Vim to read copying and usage conditions.
# Do ":help credits" in Vim to see a list of people who contributed.
#
-# FIRST AUTHOR DindinX <David.Odin@bigfoot.com> 2000.
-# SECOND AUTHOR Adrien Beau <version.francaise@free.fr> 2002, 2003.
-# THIRD AUTHOR David Blanchet <david.blanchet@free.fr> 2006, 2008.
-# FOURTH AUTHOR Dominique Pellé <dominique.pelle@gmail.com> 2008, 2015.
-#
-# Latest translation available at:
-# http://dominique.pelle.free.fr/vim-fr.php
+# FIRST AUTHOR DindinX <David.Odin@bigfoot.com> 2000.
+# SECOND AUTHOR Adrien Beau <version.francaise@free.fr> 2002, 2003.
+# THIRD AUTHOR David Blanchet <david.blanchet@free.fr> 2006, 2008.
+# FOURTH AUTHOR Dominique Pellé <dominique.pelle@gmail.com> 2008, 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Vim(Français)\n"
+"Project-Id-Version: Vim 8.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-30 17:54+0200\n"
-"PO-Revision-Date: 2015-07-30 18:00+0200\n"
+"POT-Creation-Date: 2018-09-01 14:20+0200\n"
+"PO-Revision-Date: 2018-09-01 17:15+0200\n"
"Last-Translator: Dominique Pellé <dominique.pelle@gmail.com>\n"
-"Language-Team: \n"
+"Language-Team: French\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO_8859-15\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "impossible d'obtenir la valeur d'une option"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() appelée avec un mot de passe vide"
-#: ../api/private/helpers.c:204
-#, fuzzy
-msgid "internal error: unknown option type"
-msgstr "erreur interne : pas d'élément de liste vim"
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: petit/gros boutisme incorrect dans blowfish"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: le test de sha256 a échoué"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: le test de blowfish a échoué"
# DB - TODO : Trouver une traduction valable et attestée pour "location".
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[Liste des emplacements]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Liste Quickfix]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: Des autocommandes ont causé la terminaison de la commande"
# AB - Il faut respecter l'esprit plus que la lettre.
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: Aucun tampon ne peut être alloué, Vim doit s'arrêter"
# AB - La situation est probablement plus grave que la version anglaise ne le
# laisse entendre (voir l'aide en ligne). La version française est plus
# explicite.
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr ""
"E83: L'allocation du tampon a échoué : arrêtez Vim, libérez de la mémoire"
-#: ../buffer.c:763
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: Le tampon ne peut pas être enregistré"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Tentative de suppression d'un tampon en cours d'utilisation"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Aucun tampon n'a été déchargé"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Aucun tampon n'a été effacé"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Aucun tampon n'a été détruit"
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "1 tampon a été déchargé"
-
-#: ../buffer.c:774
#, c-format
-msgid "%d buffers unloaded"
-msgstr "%d tampons ont été déchargés"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "1 tampon a été effacé"
+msgid "%d buffer unloaded"
+msgid_plural "%d buffers unloaded"
+msgstr[0] "%d tampon a été déchargé"
+msgstr[1] "%d tampons ont été déchargés"
-#: ../buffer.c:779
#, c-format
-msgid "%d buffers deleted"
-msgstr "%d tampons ont été effacés"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "1 tampon a été détruit"
+msgid "%d buffer deleted"
+msgid_plural "%d buffers deleted"
+msgstr[0] "%d tampon a été effacé"
+msgstr[1] "%d tampons ont été effacés"
-#: ../buffer.c:784
#, c-format
-msgid "%d buffers wiped out"
-msgstr "%d tampons ont été détruits"
+msgid "%d buffer wiped out"
+msgid_plural "%d buffers wiped out"
+msgstr[0] "%d tampon a été détruit"
+msgstr[1] "%d tampons ont été détruits"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: Impossible de décharger le dernier tampon"
# AB - La version française est meilleure que la version anglaise.
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Aucun tampon n'est modifié"
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Aucun tampon n'est listé"
# AB - Je ne suis pas sûr que l'on puisse obtenir ce message.
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: Impossible d'aller après le dernier tampon"
# AB - Je ne suis pas sûr que l'on puisse obtenir ce message.
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: Impossible d'aller avant le premier tampon"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
msgstr ""
-"E89: Le tampon %<PRId64> n'a pas été enregistré (ajoutez ! pour passer outre)"
+"E89: Le tampon %ld n'a pas été enregistré (ajoutez ! pour passer outre)"
+
+msgid "E948: Job still running (add ! to end the job)"
+msgstr "E948: Tâche en cours d'exécution (ajouter ! pour terminer la tâche)"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Modifications non enregistrées (ajoutez ! pour passer outre)"
+
+msgid "E948: Job still running"
+msgstr "E948: Tâche en cours d'exécution"
+
+msgid "E37: No write since last change"
+msgstr "E37: Modifications non enregistrées"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Alerte : La liste des noms de fichier déborde"
# AB - Vu le code source, la version française est meilleure que la
# version anglaise. Ce message est similaire au message E86.
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Le tampon %<PRId64> n'existe pas"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Le tampon %ld n'existe pas"
# AB - Il faut respecter l'esprit plus que la lettre.
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: Plusieurs tampons correspondent à %s"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: Aucun tampon ne correspond à %s"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "ligne %<PRId64>"
+msgid "line %ld"
+msgstr "ligne %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Un tampon porte déjà ce nom"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr "[Modifié]"
# AB - "[Inédité]" est plus correct, mais sonne faux.
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Non édité]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Nouveau fichier]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[Erreurs de lecture]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[RO]"
# AB - La version courte, "[RO]", devrait-elle être traduite par "[LS]" ?
# Il faudrait faire un sondage auprès des utilisateurs francophones.
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[lecture-seule]"
-#: ../buffer.c:2524
#, c-format
-msgid "1 line --%d%%--"
-msgstr "1 ligne --%d%%--"
-
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> lignes --%d%%--"
+msgid "%ld line --%d%%--"
+msgid_plural "%ld lines --%d%%--"
+msgstr[0] "%ld ligne --%d%%--"
+msgstr[1] "%ld lignes --%d%%--"
# AB - Faut-il remplacer "sur" par "de" ?
# DB - Mon avis : oui.
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "ligne %<PRId64> sur %<PRId64> --%d%%-- col "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "ligne %ld sur %ld --%d%%-- col "
# DB - Je trouvais [Aucun fichier] (VO : [No file]) plus naturel
# lors du lancement de Vim en mode graphique (ce message
# apparaît notamment dans le titre de la fenêtre).
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[Aucun nom]"
-#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "aide"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Aide]"
@@ -226,24 +201,19 @@ msgstr "[Aide]"
# traduction littérale et brève, mais qui risque fort d'être mal comprise.
# J'ai finalement choisi d'utiliser une abréviation, mais cela ne me
# satisfait pas.
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[Prévisu]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Tout"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Bas"
# AB - Attention, on passe de trois à quatre lettres.
-#: ../buffer.c:3531
msgid "Top"
msgstr "Haut"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -251,11 +221,15 @@ msgstr ""
"\n"
"# Liste des tampons :\n"
-#: ../buffer.c:4289
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Écriture impossible, l'option 'buftype' est activée"
+
+msgid "[Prompt]"
+msgstr "[Invite]"
+
msgid "[Scratch]"
msgstr "[Brouillon]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -263,175 +237,219 @@ msgstr ""
"\n"
"--- Symboles ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Symboles dans %s :"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ligne=%<PRId64> id=%d nom=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " ligne=%ld id=%d nom=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ':' manquant"
+msgid "E902: Cannot connect to port"
+msgstr "E902: Impossible de se connecter au port"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: Mode non autorisé"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() dans channel_open()"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: chiffre attendu"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: socket() dans channel_open()"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Pourcentage non autorisé"
+msgid "E903: received command with non-string argument"
+msgstr "E903: commande reçue avec un argument qui n'est pas une chaîne"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: le dernier argument de expr/call doit être un nombre"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: le troisième argument de \"call\" doit être une liste"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: commande inconnue reçue : %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s() : écriture sans être connecté"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s() : erreur d'écriture"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: Impossible d'utiliser un callback avec %s()"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr ""
+"E912: Impossible d'utiliser ch_evalexpr()/ch_sendexpr() avec un canal brut "
+"ou nl"
+
+msgid "E906: not an open channel"
+msgstr "E906: pas un canal ouvert"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: fichier _io nécessite _name"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: tampon in_io nécessite in_buf ou in_name "
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: le tampon doit être chargé : %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Le fichier est chiffré avec une méthode inconnue"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr ""
+"Alerte : utilisation d'une méthode de chiffrage faible ; consultez :help 'cm'"
+
+msgid "Enter encryption key: "
+msgstr "Tapez la clé de chiffrement : "
+
+msgid "Enter same key again: "
+msgstr "Tapez la clé à nouveau : "
+
+msgid "Keys don't match!"
+msgstr "Les clés ne correspondent pas !"
+
+msgid "[crypted]"
+msgstr "[chiffré]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Il manque ':' dans le Dictionnaire %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Clé dupliquée dans le Dictionnaire : %s"
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Il manque une virgule dans le Dictionnaire : %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: Il manque '}' à la fin du Dictionnaire : %s"
+
+msgid "extend() argument"
+msgstr "argument de extend()"
-# AB - Je n'ai pas trouvé de traduction satisfaisante au verbe "diff". Comme
-# Vim fait en pratique appel au programme "diff" pour evaluer les
-# différences entre fichiers, "to diff" a été traduit par "utiliser diff"
-# et d'autres expressions appropriées.
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Impossible d'utiliser diff sur plus de %<PRId64> tampons"
+msgid "E737: Key already exists: %s"
+msgstr "E737: La clé existe déjà : %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: Impossible d'utiliser diff sur plus de %ld tampons"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: Impossible de lire ou écrire des fichiers temporaires"
# AB - La version française est meilleure que la version anglaise.
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: diff ne fonctionne pas"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "Fichier rustine"
+
msgid "E816: Cannot read patch output"
msgstr "E816: Le fichier intermédiaire produit par patch n'a pu être lu"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Le fichier intermédiaire produit par diff n'a pu être lu"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: Le tampon courant n'est pas en mode diff"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: Aucun autre tampon en mode diff n'est modifiable"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: Aucun autre tampon n'est en mode diff"
# AB - La version française est meilleure que la version anglaise, mais elle
# peut être améliorée.
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr "E101: Plus de deux tampons sont en mode diff, soyez plus précis"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: Le tampon %s est introuvable"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Le tampon %s n'est pas en mode diff"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Le tampon a été modifié inopinément"
# AB - Je cherche une traduction plus concise pour "escape".
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: Un digraphe ne peut contenir le caractère d'échappement"
# AB - La version française est trop verbeuse.
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: Le fichier descripteur de clavier est introuvable"
# AB - La version française est meilleure que la version anglaise.
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :loadkeymap ne peut être utilisé que dans un script Vim"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: Entrée du descripteur de clavier (keymap) vide"
# AB - Remplacer "complétion" par "complètement" ? Voir l'éthymologie
# d'"accrétion".
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " Complètement de mot-clé (^N^P)"
# DB - todo : Faut-il une majuscule à "mode" ?
-#. 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 " mode ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " Complètement de ligne entière (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " Complètement de nom de fichier (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " Complètement de marqueur (^]^N^P)"
# AB - J'ai dû avoir une bonne raison de faire une version française aussi
# différente de la version anglaise. Il me faut la retrouver.
# DB - TODO
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " Complètement global de mot-clé (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " Complètement de définition (^D^N^P)"
# AB - Trouver une meilleure formulation que "selon le".
# DB : proposition : "avec"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " Complètement avec le dictionnaire (^K^N^P)"
# AB - Trouver une meilleure formulation que "selon le".
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " Complètement avec le thésaurus (^T^N^P)"
# AB - La version française est meilleure que la version anglaise.
# DB : Suggestion.
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " Complètement de ligne de commande (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " Complètement défini par l'utilisateur (^U^N^P)"
# DB : On doit pouvoir trouver nettement mieux que ça.
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " Complètement selon le type de fichier (Omni) (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Suggestion d'orthographe (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " Complètement local de mot-clé (^N/^P)"
@@ -439,290 +457,168 @@ msgstr " Complètement local de mot-clé (^N/^P)"
# Il faut éviter de le faire trop long. Je pense que la version française
# est suffisamment compréhensible dans le contexte dans lequel elle est
# affichée.
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Fin du paragraphe"
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: La fonction de complètement a changé la fenêtre"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: La fonction de complètement a effacé du texte"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "L'option 'dictionary' est vide"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "L'option 'thesaurus' est vide"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Examen du dictionnaire : %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (insertion) Défilement (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (remplacement) Défilement (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "Examen : %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "Examen des marqueurs."
+msgid "match in file"
+msgstr "correspondance dans le fichier"
+
# AB - Cette chaîne de caractères est ajoutée en début de ligne lorsqu'une
# opération de complétion est répétée (typiquement avec CTRL-X CTRL-N).
# Que ce soit en anglais ou en français, il y a un problème de majuscules.
# Bien qu'insatisfaisante, cette traduction semble optimale.
-#: ../edit.c:4519
msgid " Adding"
msgstr " Ajout"
-#. 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 "-- Recherche en cours..."
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
# AB - Faut-il utiliser "origine" ou "originel" au lieu d'"original" ?
# DB : Suggestion.
-#: ../edit.c:4618
msgid "Back at original"
msgstr "Retour au point de départ"
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "Mot d'une autre ligne"
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
-#: ../edit.c:4624
msgid "The only match"
msgstr "La seule correspondance"
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
# AB - Faut-il remplacer "sur" par "de" ?
# DB : Pour moi, non.
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "Correspondance %d sur %d"
# AB - Ce texte s'ajoute à la fin d'un des messages de complétion ci-dessus.
# DB - todo : la VO n'a pas de majuscule.
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "Correspondance %d"
-#: ../eval.c:137
msgid "E18: Unexpected characters in :let"
msgstr "E18: Caractères inattendus avant '='"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: index de Liste hors limites : %<PRId64> au-delà de la fin"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: Variable non définie : %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: ']' manquant"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: L'argument de %s doit être une Liste"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: L'argument de %s doit être une Liste ou un Dictionnaire"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Impossible d'utiliser une clé vide dans un Dictionnaire"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: Liste requise"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Dictionnaire requis"
-
-# DB : Suggestion
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: La fonction %s a reçu trop d'arguments"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: La clé %s n'existe pas dans le Dictionnaire"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: La fonction %s existe déjà (ajoutez ! pour la remplacer)"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Une entrée du Dictionnaire porte déjà ce nom"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Référence de fonction (Funcref) requise"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: Utilisation de [:] impossible avec un Dictionnaire"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: Type de variable erroné avec %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Fonction inconnue : %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Nom de variable invalide : %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: Utilisation d'un Flottant comme une Chaîne"
# DB - todo : trouver mieux que "destinations".
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: Moins de destinations que d'éléments dans la Liste"
# DB - todo : trouver mieux que "destinations".
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: Plus de destinations que d'éléments dans la Liste"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "Double ; dans une liste de variables"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Impossible de lister les variables de %s"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: Seul une Liste ou un Dictionnaire peut être indexé"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] ne peut être spécifié qu'en dernier"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
-msgstr "E709: [:] requiert une Liste"
+msgstr "E709: [:] nécessite une Liste"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: La Liste a plus d'éléments que la destination"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: La Liste n'a pas assez d'éléments"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: \"in\" manquant après :for"
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Parenthèses manquantes : %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Variable inexistante : %s"
-#: ../eval.c:3333
+#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: Impossible de (dé)verrouiller la variable %s"
+
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: variable trop imbriquée pour la (dé)verrouiller"
# AB - Je suis partagé entre la concision d'une traduction assez littérale et
# la lourdeur d'une traduction plus correcte.
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: Il manque ':' après '?'"
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: Une Liste ne peut être comparée qu'avec une Liste"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: Opération invalide avec les Listes"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: Un Dictionnaire ne peut être comparé qu'avec un Dictionnaire"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: Opération invalide avec les Dictionnaires"
-
-# DB - todo : Traduction valable (et courte) pour Funcref ?
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Une Funcref ne peut être comparée qu'à une Funcref"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: Opération invalide avec les Funcrefs"
-
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: Impossible d'utiliser '%' avec un Flottant"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ')' manquant"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: Impossible d'indexer une Funcref"
+msgid "E909: Cannot index a special variable"
+msgstr "E909: Impossible d'indexer une variable spéciale"
+
# AB - La version française est meilleure que la version anglaise.
-#: ../eval.c:4839
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Il manque un nom d'option après %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Option inconnue : %s"
@@ -730,464 +626,335 @@ msgstr "E113: Option inconnue : %s"
# AB - La version française est meilleure que la version anglaise, qui est
# erronée, d'ailleurs : il s'agit d'une "double quote" et non d'une
# "quote".
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Il manque \" à la fin de %s"
# AB - La version française est meilleure que la version anglaise.
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Il manque ' à la fin de %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Il manque une virgule dans la Liste %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: Il manque ']' à la fin de la Liste %s"
-
-#: ../eval.c:5750
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr ""
"Pas assez de mémoire pour les références, arrêt du ramassage de miètes !"
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Il manque ':' dans le Dictionnaire %s"
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: variable trop imbriquée pour être affichée"
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Clé \"%s\" dupliquée dans le Dictionnaire"
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Utilisation d'un Flottant comme un Nombre"
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Il manque une virgule dans le Dictionnaire %s"
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Utilisation d'une Funcref comme un Nombre"
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Il manque '}' à la fin du Dictionnaire %s"
+msgid "E745: Using a List as a Number"
+msgstr "E745: Utilisation d'une Liste comme un Nombre"
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: variable trop imbriquée pour être affichée"
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Utilisation d'un Dictionnaire comme un Nombre"
+
+msgid "E910: Using a Job as a Number"
+msgstr "E910: Utilisation d'une Tâche comme un Nombre"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: Utilisation d'un Canal comme un Nombre"
+
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: Utilisation d'une Funcref comme un Flottant"
+
+msgid "E892: Using a String as a Float"
+msgstr "E892: Utilisation d'une Chaîne comme un Flottant"
+
+msgid "E893: Using a List as a Float"
+msgstr "E893: Utilisation d'une Liste comme un Flottant"
+
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: Utilisation d'un Dictionnaire comme un Flottant"
+
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Utilisation d'une valeur spéciale comme un Flottant"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: Utilisation d'une Tâche comme un Flottant"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: Utilisation d'un Canal comme un Flottant"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: Utilisation d'une Funcref comme une Chaîne"
+
+msgid "E730: using List as a String"
+msgstr "E730: Utilisation d'une Liste comme une Chaîne"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Utilisation d'un Dictionnaire comme une Chaîne"
+
+msgid "E908: using an invalid value as a String"
+msgstr "E908: Utilisation d'une valeur invalide comme une Chaîne"
-#: ../eval.c:7188
#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: Trop d'arguments pour la fonction %s"
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Impossible de supprimer la variable %s"
-#: ../eval.c:7190
#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Arguments invalides pour la fonction %s"
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Le nom d'une Funcref doit commencer par une majuscule : %s"
-#: ../eval.c:7377
#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Fonction inconnue : %s"
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Le nom d'une variable entre en conflit avec la fonction %s"
-#: ../eval.c:7383
#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: La fonction %s n'a pas reçu assez d'arguments"
+msgid "E741: Value is locked: %s"
+msgstr "E741: La valeur de %s est verrouillée"
+
+msgid "Unknown"
+msgstr "Inconnu"
-#: ../eval.c:7387
#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> utilisé en dehors d'un script : %s"
+msgid "E742: Cannot change value of %s"
+msgstr "E742: Impossible de modifier la valeur de %s"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: variable trop imbriquée pour en faire une copie"
+
+# AB - La version française est capitalisée pour être en accord avec les autres
+# commentaires enregistrés dans le fichier viminfo.
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# Variables globales:\n"
+
+# DB - Plus précis ("la dernière fois") ?
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tModifié la dernière fois dans "
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: Une Liste ne peut être comparée qu'avec une Liste"
+
+msgid "E692: Invalid operation for List"
+msgstr "E692: Opération invalide avec les Liste"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Un Dictionnaire ne peut être comparé qu'avec un Dictionnaire"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: Opération invalide avec les Dictionnaires"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: Opération invalide avec les Funcrefs"
+
+msgid "map() argument"
+msgstr "argument de map()"
+
+msgid "filter() argument"
+msgstr "argument de filter()"
-#: ../eval.c:7391
#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Appel d'une fonction « dict » sans Dictionnaire : %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: L'argument de %s doit être une Liste"
+
+msgid "E928: String required"
+msgstr "E928: Chaîne requis"
-#: ../eval.c:7453
msgid "E808: Number or Float required"
msgstr "E808: Nombre ou Flottant requis"
-#: ../eval.c:7503
msgid "add() argument"
msgstr "argument de add()"
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: Trop d'arguments"
-
-#: ../eval.c:8073
msgid "E785: complete() can only be used in Insert mode"
msgstr "E785: complete() n'est utilisable que dans le mode Insertion"
# AB - Texte par défaut du bouton de la boîte de dialogue affichée par la
# fonction confirm().
-#: ../eval.c:8156
msgid "&Ok"
msgstr "&Ok"
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "argument de extend()"
-
-#: ../eval.c:9345
#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: un mappage existe déjà pour %s"
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld ligne : "
+msgstr[1] "+-%s%3ld lignes : "
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "argument de map()"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "argument de filter()"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld lignes : "
-
-#: ../eval.c:9291
#, c-format
msgid "E700: Unknown function: %s"
msgstr "E700: Fonction inconnue : %s"
+msgid "E922: expected a dict"
+msgstr "E922: dictionnaire attendu"
+
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr ""
+"E923: Le second argument de function() doit être une liste ou un dictionnaire"
+
+# AB - Textes des boutons de la boîte de dialogue affichée par inputdialog().
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&Ok\n"
+"&Annuler"
+
# AB - La version française est meilleure que la version anglaise.
-#: ../eval.c:10729
msgid "called inputrestore() more often than inputsave()"
msgstr "inputrestore() a été appelé plus de fois qu'inputsave()"
-#: ../eval.c:10771
msgid "insert() argument"
msgstr "argument de insert()"
-#: ../eval.c:10841
msgid "E786: Range not allowed"
msgstr "E786: Les plages ne sont pas autorisées"
-#: ../eval.c:11140
+msgid "E916: not a valid job"
+msgstr "E916: tâche invalide"
+
msgid "E701: Invalid type for len()"
msgstr "E701: Type invalide avec len()"
-#: ../eval.c:11980
+msgid "E957: Invalid window number"
+msgstr "E957: numéro de fenêtre invalide"
+
+#, c-format
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID est réservé pour \":match\": %ld"
+
msgid "E726: Stride is zero"
msgstr "E726: Le pas est nul"
-#: ../eval.c:11982
msgid "E727: Start past end"
msgstr "E727: Début au-delà de la fin"
-#: ../eval.c:12024 ../eval.c:15297
msgid "<empty>"
msgstr "<vide>"
-#: ../eval.c:12282
+msgid "E240: No connection to the X server"
+msgstr "E240: Pas de connexion au serveur X"
+
+# AB - La version française est meilleure que la version anglaise.
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: L'envoi au serveur %s a échoué"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Impossible de lire la réponse du serveur"
+
+msgid "E941: already started a server"
+msgstr "E941: serveur déjà démarré"
+
+msgid "E942: +clientserver feature not available"
+msgstr "E942: La fonctionnalité +clientserver n'est pas disponible"
+
msgid "remove() argument"
msgstr "argument de remove()"
-#: ../eval.c:12466
msgid "E655: Too many symbolic links (cycle?)"
msgstr "E655: Trop de liens symboliques (cycle ?)"
-#: ../eval.c:12593
msgid "reverse() argument"
msgstr "argument de reverse()"
-#: ../eval.c:13721
+# AB - La version française est meilleure que la version anglaise.
+msgid "E258: Unable to send to client"
+msgstr "E258: La réponse n'a pas pu être envoyée au client"
+
+#, c-format
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Action invalide : « %s »"
+
msgid "sort() argument"
msgstr "argument de sort()"
-#: ../eval.c:13721
-#, fuzzy
msgid "uniq() argument"
-msgstr "argument de add()"
+msgstr "argument de uniq()"
-#: ../eval.c:13776
msgid "E702: Sort compare function failed"
msgstr "E702: La fonction de comparaison de sort() a échoué"
-#: ../eval.c:13806
-#, fuzzy
msgid "E882: Uniq compare function failed"
-msgstr "E702: La fonction de comparaison de sort() a échoué"
+msgstr "E882: La fonction de comparaison de uniq() a échoué"
-#: ../eval.c:14085
msgid "(Invalid)"
msgstr "(Invalide)"
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Erreur lors de l'écriture du fichier temporaire"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Utilisation d'un Flottant comme un Nombre"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Utilisation d'une Funcref comme un Nombre"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: Utilisation d'une Liste comme un Nombre"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Utilisation d'un Dictionnaire comme un Nombre"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: Utilisation d'une Funcref comme une Chaîne"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: Utilisation d'une Liste comme une Chaîne"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Utilisation d'un Dictionnaire comme une Chaîne"
-
-# DB : On doit pouvoir trouver nettement mieux que ça.
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Type de variable incohérent pour %s"
-
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Impossible de supprimer la variable %s"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Le nom d'une Funcref doit commencer par une majuscule : %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: Le nom d'une variable entre en conflit avec la fonction %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: La valeur de %s est verrouillée"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Inconnu"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Impossible de modifier la valeur de %s"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: variable trop imbriquée pour en faire une copie"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Fonction non définie : %s"
-
-# AB - La version française est plus consistante que la version anglaise.
-# AB - Je suis partagé entre la concision d'une traduction assez littérale et
-# la lourdeur d'une traduction plus correcte.
-#: ../eval.c:17260
#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: Il manque '(' après %s"
-
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: Impossible d'utiliser g: ici"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Argument invalide : %s"
-
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Nom d'argument dupliqué : %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: Il manque :endfunction"
-
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Le nom de fonction entre en conflit avec la variable : %s"
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: numéro de submatch invalide : %d"
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Impossible de redéfinir fonction %s : déjà utilisée"
-
-# DB - Le contenu du "c-format" est le nom de la fonction.
-#: ../eval.c:17604
-#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: Le nom de la fonction %s ne correspond pas le nom du script"
-
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: Nom de fonction requis"
-
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: La fonction %s ne commence pas par une majuscule ou contient ':'"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: La fonction %s ne commence pas par une majuscule ou contient ':'"
-
-# AB - Il est difficile de créer une version française qui fasse moins de 80
-# caractères de long, nom de la fonction compris : "It is in use" est une
-# expression très dense. Traductions possibles : "elle est utilisée",
-# "elle s'exécute" ou "elle est occupée".
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Impossible d'effacer %s : cette fonction est utilisée"
-
-# AB - Vérifier dans la littérature technique s'il n'existe pas une meilleure
-# traduction pour "function call depth".
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr ""
-"E132: La profondeur d'appel de fonction est supérieure à 'maxfuncdepth'"
-
-# AB - Ce texte fait partie d'un message de débogage.
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "appel de %s"
+msgid "E677: Error writing temp file"
+msgstr "E677: Erreur lors de l'écriture du fichier temporaire"
-# AB - Vérifier.
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s annulée"
+msgid "E921: Invalid callback argument"
+msgstr "E921: Argument de callback invalide"
-# AB - Ce texte fait partie d'un message de débogage.
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s a retourné #%<PRId64>"
+msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"
+msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o, Digr %s"
-# AB - Ce texte fait partie d'un message de débogage.
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s a retourné \"%s\""
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o"
-# AB - Ce texte fait partie d'un message de débogage.
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "de retour dans %s"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return en dehors d'une fonction"
-
-# AB - La version française est capitalisée pour être en accord avec les autres
-# commentaires enregistrés dans le fichier viminfo.
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# Variables globales:\n"
-
-# DB - Plus précis ("la dernière fois") ?
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tModifié la dernière fois dans "
+msgid "> %d, Hex %04x, Oct %o, Digr %s"
+msgstr "> %d, Hexa %04x, Octal %o, Digr %s"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Aucun vieux fichier"
-
-#: ../ex_cmds.c:122
#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, Hexa %02x, Octal %03o"
+msgid "> %d, Hex %08x, Oct %o, Digr %s"
+msgstr "> %d, Hexa %08x, Octal %o, Digr %s"
-#: ../ex_cmds.c:145
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, Hexa %04x, Octal %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, Hexa %08x, Octal %o"
# AB - La version anglaise est très mauvaise, ce qui m'oblige a inventer une
# version française.
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: La destination est dans la plage d'origine"
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "1 ligne déplacée"
-
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> lignes déplacées"
+msgid "%ld line moved"
+msgid_plural "%ld lines moved"
+msgstr[0] "%ld ligne déplacée"
+msgstr[1] "%ld lignes déplacées"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> lignes filtrées"
+msgid "%ld lines filtered"
+msgstr "%ld lignes filtrées"
# AB - J'ai volontairement omis l'astérisque initiale car je pense que le
# motif "Filter*" décrit plus clairement les quatre autocommandes liées
# au filtrage (FilterReadPre, FilterReadPost, FilterWritePre et
# FilterWritePost) que "*Filter*" que l'on confond avec une tentative de
# mise en valeur.
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr ""
"E135: Les autocommandes Filter* ne doivent pas changer le tampon courant"
# AB - Il faut respecter l'esprit plus que la lettre. Dans le cas présent,
# nettement plus.
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[Attention : tout n'est pas enregistré]\n"
# AB - Le numéro et le message d'erreur (%s ci-dessous) et le "numéro" de ligne
# sont des chaînes de caractères dont le contenu est à la discrétion de
# l'appelant de la fonction viminfo_error().
-#: ../ex_cmds.c:1424
#, c-format
msgid "%sviminfo: %s in line: "
msgstr "%sviminfo : %s à la ligne "
# AB - La version française est meilleure que la version anglaise.
-#: ../ex_cmds.c:1431
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr ""
"E136: Il y a trop d'erreurs ; interruption de la lecture du fichier viminfo"
@@ -1195,30 +962,25 @@ msgstr ""
# AB - Ce texte fait partie d'un message de débogage.
# DB - ... dont les valeurs possibles sont les messages
# qui suivent.
-#: ../ex_cmds.c:1458
#, c-format
msgid "Reading viminfo file \"%s\"%s%s%s"
msgstr "Lecture du fichier viminfo \"%s\"%s%s%s"
# AB - Ce texte fait partie d'un message de débogage.
# DB - Voir ci-dessus.
-#: ../ex_cmds.c:1460
msgid " info"
msgstr " info"
# AB - Ce texte fait partie d'un message de débogage.
# DB - Voir ci-dessus.
-#: ../ex_cmds.c:1461
msgid " marks"
msgstr " marques"
-#: ../ex_cmds.c:1462
msgid " oldfiles"
msgstr " vieux fichiers"
# AB - Ce texte fait partie d'un message de débogage.
# DB - Voir ci-dessus.
-#: ../ex_cmds.c:1463
msgid " FAILED"
msgstr " ÉCHEC"
@@ -1226,34 +988,35 @@ msgstr " ÉCHEC"
# ses droits d'accès.
# AB - Le mot "viminfo" a été retiré pour que le message ne dépasse pas 80
# caractères dans le cas courant où %s = /home/12345678/.viminfo
-#. 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: L'écriture dans le fichier %s est interdite"
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: Trop de fichiers temporaires viminfo, comme %s!"
+
# AB - Le point d'exclamation est superflu.
# AB - Le mot "viminfo" a été retiré pour que le message ne dépasse pas 80
# caractères dans le cas courant où %s = /home/12345678/.viminfo
-#: ../ex_cmds.c:1626
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: Impossible d'écrire le fichier %s"
# AB - Ce texte est un message de débogage.
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "Écriture du fichier viminfo \"%s\""
-#. Write the info:
-#: ../ex_cmds.c:1720
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: Impossible de renommer viminfo en %s"
+
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# Ce fichier viminfo a été généré par Vim %s.\n"
# AB - Les deux versions, bien que différentes, se valent.
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1261,58 +1024,61 @@ msgstr ""
"# Vous pouvez l'éditer, mais soyez prudent.\n"
"\n"
-#: ../ex_cmds.c:1723
msgid "# Value of 'encoding' when this file was written\n"
msgstr "# 'encoding' dans lequel ce fichier a été écrit\n"
# AB - Ce texte est passé en argument à la fonction viminfo_error().
# AB - "illégal" est un terme trop fort à mon goût.
-#: ../ex_cmds.c:1800
msgid "Illegal starting char"
msgstr "Caractère initial non valide"
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# Lignes commençant par |, copiées littéralement :\n"
+
+# AB - Ceci est un titre de boîte de dialogue. Vérifier que la version
+# française est correcte pour les trois références ; j'ai un doute quant
+# à la troisième.
+msgid "Save As"
+msgstr "Enregistrer sous - Vim"
+
# AB - Ceci est un contenu de boîte de dialogue (éventuellement en mode texte).
# AB - La version française est meilleure que la version anglaise.
-#: ../ex_cmds.c:2162
msgid "Write partial file?"
msgstr "Perdre une partie du fichier ?"
# AB - La version française est nettement meilleure que la version anglaise.
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr ""
"E140: Une partie du fichier serait perdue (ajoutez ! pour passer outre)"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "Écraser le fichier %s existant ?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Le fichier d'échange \"%s\" existe déjà, l'écraser ?"
# DB - Un peu long à mon avis.
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Le fichier d'échange %s existe déjà (:silent! pour passer outre)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Pas de nom de fichier pour le tampon %<PRId64>"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Pas de nom de fichier pour le tampon %ld"
# AB - Il faut respecter l'esprit plus que la lettre.
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr ""
"E142: L'option 'nowrite' est activée et empêche toute écriture du fichier"
# AB - Ceci est un contenu de boîte de dialogue (éventuellement en mode texte).
# AB - "activée pour" n'est pas une formulation très heureuse.
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1321,7 +1087,6 @@ msgstr ""
"L'option 'readonly' est activée pour \"%s\".\n"
"Voulez-vous tout de même enregistrer ?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1332,94 +1097,84 @@ msgstr ""
"Il peut être possible de l'écrire tout de même.\n"
"Tenter ?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: \"%s\" est en lecture seule (ajoutez ! pour passer outre)"
+# AB - Ceci est un titre de boîte de dialogue.
+msgid "Edit File"
+msgstr "Ouvrir un fichier - Vim"
+
# AB - Il faut respecter l'esprit plus que la lettre.
# AB - J'hésite à ajouter "à sa création" après le nom du tampon. Ce message
# devrait n'être affiché qu'après une tentative d'ouverture de fichier,
# la version actuelle devrait donc suffire.
# DB - Suggestion : "nouveau tampon" ?
-#: ../ex_cmds.c:3120
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: Une autocommande a effacé le nouveau tampon %s"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: L'argument de :z n'est pas numérique"
# AB - La version française fera peut-être mieux passer l'amère pilule.
# La consultation de l'aide donnera l'explication complète à ceux qui
# ne comprendraient pas à quoi ce message est dû.
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: Les commandes externes sont indisponibles dans rvim"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr ""
"E146: Les expressions régulières ne peuvent pas être délimitées par des "
"lettres"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "remplacer par %s (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Interrompu) "
-#: ../ex_cmds.c:4384
-msgid "1 match"
-msgstr "1 correspondance"
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "1 substitution"
-
-#: ../ex_cmds.c:4387
#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> correspondances"
+msgid "%ld match on %ld line"
+msgid_plural "%ld matches on %ld line"
+msgstr[0] "%ld correspondance sur %ld ligne"
+msgstr[1] "%ld correspondances sur %ld ligne"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> substitutions"
+msgid "%ld substitution on %ld line"
+msgid_plural "%ld substitutions on %ld line"
+msgstr[0] "%ld substitution sur %ld ligne"
+msgstr[1] "%ld substitutions sur %ld ligne"
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr " sur 1 ligne"
+#, c-format
+msgid "%ld match on %ld lines"
+msgid_plural "%ld matches on %ld lines"
+msgstr[0] "%ld correspondance sur %ld lignes"
+msgstr[1] "%ld correspondances sur %ld lignes"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " sur %<PRId64> lignes"
+msgid "%ld substitution on %ld lines"
+msgid_plural "%ld substitutions on %ld lines"
+msgstr[0] "%ld substitution sur %ld lignes"
+msgstr[1] "%ld substitutions sur %ld lignes"
# AB - Il faut respecter l'esprit plus que la lettre.
# AB - Ce message devrait contenir une référence à :vglobal.
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global ne peut pas exécuter :global"
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: :global ne peut pas exécuter :global avec une plage"
# AB - Ce message devrait contenir une référence à :vglobal.
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: :global doit être suivi par une expression régulière"
# AB - Ce message est utilisé lorsque :vglobal ne trouve rien. Lorsque :global
# ne trouve rien, c'est "Pattern not found: %s" / "Motif introuvable: %s"
# qui est utilisé.
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "Motif trouvé dans toutes les lignes : %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "Motif introuvable: %s"
@@ -1430,7 +1185,6 @@ msgstr "Motif introuvable: %s"
# à internationalisation. J'attends que les deux autres messages soient
# traduisibles pour traduire celui-ci.
# DB - TODO : Qu'en est-il à présent ?
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1441,43 +1195,33 @@ msgstr ""
"$"
# This message should *so* be E42!
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: Pas de panique !"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: Désolé, aucune aide en langue '%s' pour %s"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: Désolé, aucune aide pour %s"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "Désolé, le fichier d'aide \"%s\" est introuvable"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: %s n'est pas un répertoire"
+msgid "E151: No match: %s"
+msgstr "E151: Aucune correspondance : %s"
-# AB - La version anglaise est plus précise, mais trop technique.
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
-msgstr "E152: Impossible d'écrire %s"
+msgstr "E152: Impossible d'ouvrir %s en écriture"
-# AB - La version anglaise est plus précise, mais trop technique.
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
-msgstr "E153: Impossible de lire %s"
+msgstr "E153: Impossible d'ouvrir %s en lecture"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: Encodages différents dans les fichiers d'aide en langue %s"
@@ -1487,315 +1231,297 @@ msgstr "E670: Encodages différents dans les fichiers d'aide en langue %s"
# traduction de 40 caractères ou moins. Ce qui est loin d'être le cas
# présent.
# DB - Suggestion.
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: Marqueur \"%s\" dupliqué dans le fichier %s/%s"
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: %s n'est pas un répertoire"
+
# AB - Il faut respecter l'esprit plus que la lettre.
-#: ../ex_cmds.c:5687
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Commande inconnue : :sign %s"
# AB - La version française est meilleure que la version anglaise.
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Il manque le nom du symbole"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: Trop de symboles sont définis"
# AB - Cette traduction ne me satisfait pas.
# DB - Suggestion.
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Le texte du symbole est invalide : %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Symbole inconnu : %s"
# AB - La version française est meilleure que la version anglaise.
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Il manque l'ID du symbole"
# AB - Vu le code source, la version française est meilleure que la
# version anglaise. Ce message est similaire au message E102.
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Le tampon %s est introuvable"
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Impossible de sauter à un tampon sans nom"
+
# AB - Vu le code source, la version française est meilleure que la
# version anglaise.
-#: ../ex_cmds.c:6008
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: Le symbole %<PRId64> est introuvable"
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: Le symbole %ld est introuvable"
+
+#, c-format
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Impossible de changer le symbole %s"
+
+msgid " (NOT FOUND)"
+msgstr " (INTROUVABLE)"
-#: ../ex_cmds.c:6066
msgid " (not supported)"
msgstr " (non supporté)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[Effacé]"
+msgid "No old files"
+msgstr "Aucun vieux fichier"
+
# AB - La version française de la première phrase ne me satisfait pas.
# DB - Suggestion.
-#: ../ex_cmds2.c:139
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "Mode débogage activé. Tapez \"cont\" pour continuer."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "ligne %<PRId64> : %s"
+msgid "Oldval = \"%s\""
+msgstr "Ancienneval = \"%s\""
+
+#, c-format
+msgid "Newval = \"%s\""
+msgstr "Nouvelleval = \"%s\""
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "ligne %ld : %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "cmde : %s"
-#: ../ex_cmds2.c:322
+msgid "frame is zero"
+msgstr "le cadre de pile est zéro"
+
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Point d'arrêt dans %s%s ligne %<PRId64>"
+msgid "frame at highest level: %d"
+msgstr "cadre de pile au niveau le plus haut : %d"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Point d'arrêt dans %s%s ligne %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Le point d'arrêt %s est introuvable"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Aucun point d'arrêt n'est défini"
# AB - Le deuxième %s est remplacé par "func" ou "file" sans que l'on puisse
# traduire ces mots.
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s ligne %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s ligne %ld"
+
+#, c-format
+msgid "%3d expr %s"
+msgstr "%3d expr %s"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: Utilisez d'abord \":profile start {nomfichier}\""
# AB - "changes to" est redondant et a été omis de la version française.
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Enregistrer \"%s\" ?"
-# AB - Si les parenthèses posent problème, il faudra remettre les guillemets
-# ci-dessus.
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "(sans titre)"
+#, c-format
+msgid "E947: Job still running in buffer \"%s\""
+msgstr "E947: Tâche en cours d'exécution dans le buffer \"%s\""
# AB - Il faut respecter l'esprit plus que la lettre.
# AB - Ce message est similaire au message E89.
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Le tampon %s n'a pas été enregistré"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
-msgstr "Alerte : Entrée inattendue dans un autre tampon (vérifier autocmdes)"
+msgstr ""
+"Alerte : Entrée inattendue dans un autre tampon (vérifier autocommandes)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Il n'y a qu'un seul fichier à éditer"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: Impossible d'aller avant le premier fichier"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: Impossible d'aller au-delà du dernier fichier"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: Compilateur %s non supporté"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "Recherche de \"%s\" dans \"%s\""
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "Recherche de \"%s\""
-#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "introuvable dans 'runtimepath' : \"%s\""
+msgid "not found in '%s': \"%s\""
+msgstr "introuvable dans '%s' : \"%s\""
+
+#, c-format
+msgid "W20: Required python version 2.x not supported, ignoring file: %s"
+msgstr "W20: Python version 2.x non supporté, fichier %s ignoré"
+
+#, c-format
+msgid "W21: Required python version 3.x not supported, ignoring file: %s"
+msgstr "W21: Python 3.x non supporté, fichier %s ignoré"
+
+msgid "Source Vim script"
+msgstr "Sourcer un script - Vim"
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "Impossible de sourcer un répertoire : \"%s\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "impossible de sourcer \"%s\""
-#: ../ex_cmds2.c:2520
#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "ligne %<PRId64> : impossible de sourcer \"%s\""
+msgid "line %ld: could not source \"%s\""
+msgstr "ligne %ld : impossible de sourcer \"%s\""
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "sourcement \"%s\""
-#: ../ex_cmds2.c:2537
#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "ligne %<PRId64> : sourcement de \"%s\""
+msgid "line %ld: sourcing \"%s\""
+msgstr "ligne %ld : sourcement de \"%s\""
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "fin du sourcement de %s"
-#: ../ex_cmds2.c:2765
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "continuing in %s"
+msgstr "de retour dans %s"
+
msgid "modeline"
msgstr "ligne de mode"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "argument --cmd"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "argument -c"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
msgstr "variable d'environnement"
-#: ../ex_cmds2.c:2773
msgid "error handler"
msgstr "gestionnaire d'erreur"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: Alerte : Séparateur de ligne erroné, ^M possiblement manquant"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding utilisé en dehors d'un fichier sourcé"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish utilisé en dehors d'un fichier sourcé"
# DB - Le premier %s est, au choix : "time ", "ctype " ou "messages ",
# sans qu'il soit possible de les traduire.
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "Langue courante pour %s : \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Impossible de choisir la langue \"%s\""
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "Mode Ex activé. Tapez \"visual\" pour passer en mode Normal."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: À la fin du fichier"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Commande trop récursive"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Exception non interceptée : %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Fin du fichier sourcé"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Fin de la fonction"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: Utilisation ambiguë d'une commande définie par l'utilisateur"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Commande inconnue"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: La plage spécifiée est inversée"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "La plage spécifiée est inversée, OK pour l'inverser"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: Utilisez w ou w>>"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: Désolé, cette commande n'est pas disponible dans cette version"
-
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: Un seul nom de fichier autorisé"
+msgid "E943: Command table needs to be updated, run 'make cmdidxs'"
+msgstr ""
+"E943: La table des commandes doit être mise à jour, lancez 'make cmdidxs'"
-#: ../ex_docmd.c:4238
-msgid "1 more file to edit. Quit anyway?"
-msgstr "Encore 1 fichier à éditer. Quitter tout de même ?"
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Désolé, cette commande n'est pas disponible dans cette version"
-#: ../ex_docmd.c:4242
#, c-format
-msgid "%d more files to edit. Quit anyway?"
-msgstr "Encore %d fichiers à éditer. Quitter tout de même ?"
+msgid "%d more file to edit. Quit anyway?"
+msgid_plural "%d more files to edit. Quit anyway?"
+msgstr[0] "Encore %d fichier à éditer. Quitter tout de même ?"
+msgstr[1] "Encore %d fichiers à éditer. Quitter tout de même ?"
-#: ../ex_docmd.c:4248
-msgid "E173: 1 more file to edit"
-msgstr "E173: encore 1 fichier à éditer"
-
-#: ../ex_docmd.c:4250
#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: encore %<PRId64> fichiers à éditer"
+msgid "E173: %ld more file to edit"
+msgid_plural "E173: %ld more files to edit"
+msgstr[0] "E173: encore %ld fichier à éditer"
+msgstr[1] "E173: encore %ld fichiers à éditer"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: La commande existe déjà : ajoutez ! pour la redéfinir"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
" Name Args Address Complete Definition"
@@ -1803,356 +1529,312 @@ msgstr ""
"\n"
" Nom Args Adresse Complet. Définition"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "Aucune commande définie par l'utilisateur trouvée"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: Pas d'attribut spécifié"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: Nombre d'arguments invalide"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: Le quantificateur ne peut être spécifié deux fois"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: La valeur par défaut du quantificateur est invalide"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: argument requis avec -complete"
-#: ../ex_docmd.c:4933
msgid "E179: argument required for -addr"
msgstr "E179: argument requis avec -addr"
-#: ../ex_docmd.c:4635
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Attribut invalide : %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Nom de commande invalide"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr "E183: Les commandes utilisateur doivent commencer par une majuscule"
-#: ../ex_docmd.c:4696
msgid "E841: Reserved name, cannot be used for user defined command"
msgstr ""
"E841: Nom réservé, ne peux pas être utilisé pour une commande utilisateur"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: Aucune commande %s définie par l'utilisateur"
-#: ../ex_docmd.c:5516
#, c-format
msgid "E180: Invalid address type value: %s"
msgstr "E180: Valeur de type d'adresse invalide : %s"
-#: ../ex_docmd.c:5219
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: Valeur invalide pour \"-complete=\" : %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr "E468: Seul le complètement personnalisé accepte un argument"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Le complètement personnalisé requiert une fonction en argument"
+msgstr "E467: Le complètement personnalisé nécessite une fonction en argument"
+
+msgid "unknown"
+msgstr "inconnu"
-#: ../ex_docmd.c:5257
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: Impossible de trouver le jeu de couleurs '%s'"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Bienvenue, utilisateur de Vim !"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: Impossible de fermer le dernier onglet"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "Il ne reste déjà plus qu'un seul onglet"
-#: ../ex_docmd.c:6004
+msgid "Edit File in new tab page"
+msgstr "Ouvrir un fichier dans un nouvel onglet"
+
+msgid "Edit File in new window"
+msgstr "Ouvrir un fichier dans une nouvelle fenêtre - Vim"
+
#, c-format
msgid "Tab page %d"
msgstr "Onglet %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Pas de fichier d'échange"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "Ajouter fichier"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
"E747: Tampon modifié : impossible de changer de répertoire (ajoutez ! pour "
"passer outre)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Pas de répertoire précédent"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Inconnu"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
-msgstr "E465: :winsize requiert deux arguments numériques"
+msgstr "E465: :winsize nécessite deux arguments numériques"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Position de la fenêtre : X %d, Y %d"
# DB : Suggestion, sans doute perfectible.
-#: ../ex_docmd.c:6655
msgid "E188: Obtaining window position not implemented for this platform"
msgstr ""
"E188: Récupérer la position de la fenêtre non implémenté dans cette version"
-#: ../ex_docmd.c:6662
msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos requiert deux arguments numériques"
+msgstr "E466: :winpos nécessite deux arguments numériques"
+
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: Impossible d'utiliser :redir dans execute()"
+
+msgid "Save Redirection"
+msgstr "Enregistrer la redirection"
+
+msgid "Save View"
+msgstr "Enregistrer la vue - Vim"
+
+msgid "Save Session"
+msgstr "Enregistrer la session - Vim"
+
+msgid "Save Setup"
+msgstr "Enregistrer les réglages - Vim"
-#: ../ex_docmd.c:7241
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: Impossible de créer le répertoire \"%s\""
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" existe (ajoutez ! pour passer outre)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Impossible d'ouvrir \"%s\" pour y écrire"
-#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: L'argument doit être une lettre ou une (contre-)apostrophe"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: Appel récursif de :normal trop important"
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< n'est pas disponible sans la fonctionnalité +eval"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: Aucun nom de fichier alternatif à substituer à '#'"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: Aucun nom de ficher d'autocommande à substituer à \"<afile>\""
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: Aucun numéro de tampon d'autocommande à substituer à \"<abuf>\""
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr "E497: Aucune correspondance d'autocommande à substituer à \"<amatch>\""
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: Aucun nom de fichier :source à substituer à \"<sfile>\""
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: aucun numéro de ligne à utiliser pour \"<slnum>\""
-#: ../ex_docmd.c:7903
-#, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr "E499: Nom de fichier vide pour '%' ou '#', ne marche qu'avec \":p:h\""
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: Évalué en une chaîne vide"
-#: ../ex_docmd.c:8838
msgid "E195: Cannot open viminfo file for reading"
msgstr "E195: Impossible d'ouvrir le viminfo en lecture"
-#: ../ex_eval.c:464
+# AB - Si les parenthèses posent problème, il faudra remettre les guillemets
+# ci-dessus.
+msgid "Untitled"
+msgstr "(sans titre)"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: Pas de digraphes dans cette version"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: Impossible d'émettre des exceptions avec 'Vim' comme préfixe"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Exception émise : %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "Exception terminée : %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Exception éliminée : %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, ligne %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, ligne %ld"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Exception interceptée : %s"
# DB - Le c-format est féminin, singulier ou pluriel (cf. 3 messages plus bas).
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s mise(s) en attente"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s ré-émise(s)"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s éliminée(s)"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Exception"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Erreur et interruption"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Erreur"
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Interruption"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: Imbrication de :if trop importante"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :endif sans :if"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :else sans :if"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :elseif sans :if"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: Il ne peut y avoir qu'un seul :else"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :elseif après :else"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: Imbrication de :while ou :for trop importante"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :continue sans :while ou :for"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :break sans :while ou :for"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: Utilisation de :endfor avec :while"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: Utilisation de :endwhile avec :for"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: Imbrication de :try trop importante"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :catch sans :try"
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :catch après :finally"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :finally sans :try"
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: Il ne peut y avoir qu'un seul :finally"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :endtry sans :try"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: :endfunction en dehors d'une fonction"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: L'édition d'un autre tampon n'est plus permise"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr ""
"E811: Changement des informations du tampon n'est pas permise maintenant"
# DB - TODO : Pas compris le message ni comment le déclencher malgré une visite
# dans le code.
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "nom du marqueur"
# DB - TODO : Idem précédent.
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " type de fichier\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "l'option 'history' vaut zéro"
# DB - Messages et les suivants : fichier .viminfo.
# Pas de majuscule nécessaire pour les messages d'après.
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -2161,311 +1843,224 @@ msgstr ""
"\n"
"# Historique %s (chronologie décroissante) :\n"
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "ligne de commande"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "chaîne de recherche"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "expression"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "ligne de saisie"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "Ligne de débogage"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar au-delà de la longueur de la commande"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Fenêtre ou tampon actif effacé"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: chemin trop long pour complètement"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Chemin invalide : '**[nombre]' doit être à la fin du chemin ou être "
-"suivi de '%s'."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Répertoire \"%s\" introuvable dans 'cdpath'"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Fichier \"%s\" introuvable dans 'path'"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Plus de répertoire \"%s\" dans 'cdpath'"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Plus de fichier \"%s\" dans 'path'"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: Des autocommandes ont changé le tampon ou le nom du tampon"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Nom de fichier invalide"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "est un répertoire"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "n'est pas un fichier"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "est un périphérique (désactivé par l'option 'opendevice')"
+
msgid "[New File]"
msgstr "[Nouveau fichier]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[Nouveau RÉPERTOIRE]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[Fichier trop volumineux]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Permission refusée]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: Les autocommandes *ReadPre ont rendu le fichier illisible"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr ""
"E201: Autocommandes *ReadPre ne doivent pas modifier le contenu du tampon "
"courant"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim : Lecture de stdin...\n"
-#. Re-opening the original file failed!
-#: ../fileio.c:909
+msgid "Reading from stdin..."
+msgstr "Lecture de stdin..."
+
msgid "E202: Conversion made file unreadable!"
msgstr "E202: La conversion a rendu le fichier illisible !"
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[fifo/socket]"
-
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[fifo]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[socket]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[caractère spécial]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR manquant]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[lignes longues coupées]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[NON converti]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[converti]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[ERREUR DE CONVERSION à la ligne %<PRId64>]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ERREUR DE CONVERSION à la ligne %ld]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[OCTET INVALIDE à la ligne %<PRId64>]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[OCTET INVALIDE à la ligne %ld]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[ERREURS DE LECTURE]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "Impossible de générer un fichier temporaire pour la conversion"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "La conversion avec 'charconvert' a échoué"
# DB : Pas de majuscule ?
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "Impossible de lire la sortie de 'charconvert'"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Pas d'autocommande correspondante pour le tampon acwrite"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: Des autocommandes ont effacé ou déchargé le tampon à écrire"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr ""
"E204: L'autocommande a modifié le nombre de lignes de manière inattendue"
-#: ../fileio.c:2548 ../fileio.c:2565
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans interdit l'écriture des tampons non modifiés"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Netbeans interdit l'écriture partielle de ses tampons"
+
msgid "is not a file or writable device"
msgstr "n'est pas un fichier ou un périphérique inscriptible"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "écriture vers un périphérique désactivé par l'option 'opendevice'"
+
msgid "is read-only (add ! to override)"
msgstr "est en lecture seule (ajoutez ! pour passer outre)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr "E506: Impossible d'écrire la copie de secours (! pour passer outre)"
-#: ../fileio.c:2898
msgid "E507: Close error for backup file (add ! to override)"
msgstr "E507: Erreur de fermeture de la copie de secours (! pour passer outre)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr ""
"E508: Impossible de lire le fichier pour la copie de secours (ajoutez ! pour "
"passer outre)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr ""
"E509: Impossible de créer la copie de secours (ajoutez ! pour passer outre)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr ""
"E510: Impossible de générer la copie de secours (ajoutez ! pour passer outre)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
msgid "E214: Can't find temp file for writing"
msgstr "E214: Impossible de générer un fichier temporaire pour y écrire"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: Impossible de convertir (ajoutez ! pour écrire sans convertir)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Impossible d'ouvrir le lien pour y écrire"
-#: ../fileio.c:3173
msgid "E212: Can't open file for writing"
msgstr "E212: Impossible d'ouvrir le fichier pour y écrire"
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: Fsynch a échoué"
+msgid "E949: File changed while writing"
+msgstr "E949: Fichier modifié après écriture"
-#: ../fileio.c:3398
msgid "E512: Close failed"
msgstr "E512: Erreur de fermeture de fichier"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
msgstr ""
"E513: Erreur d'écriture, échec de conversion (videz 'fenc' pour passer outre)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: Erreur d'écriture, échec de conversion à la ligne %<PRId64> (videz "
-"'fenc' pour passer outre)"
+"E513: Erreur d'écriture, échec de conversion à la ligne %ld (videz 'fenc' "
+"pour passer outre)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: erreur d'écriture (système de fichiers plein ?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " ERREUR DE CONVERSION"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " à la ligne %<PRId64>"
+msgid " in line %ld;"
+msgstr " à la ligne %ld"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Périph.]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Nouveau]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " ajouté(s)"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [e]"
-#: ../fileio.c:3537
msgid " written"
msgstr " écrit(s)"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: Patchmode : impossible d'enregistrer le fichier original"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode : impossible de créer le fichier original vide"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Impossible d'effacer la copie de secours"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2474,99 +2069,73 @@ msgstr ""
"ALERTE: Le fichier original est peut-être perdu ou endommagé\n"
# DB - todo : un peu long...
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr ""
"ne quittez pas l'éditeur tant que le fichier n'est pas correctement "
"enregistré !"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[format dos]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[format mac]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[format unix]"
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 ligne, "
-
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> lignes, "
+msgid "%ld line, "
+msgid_plural "%ld lines, "
+msgstr[0] "%ld ligne, "
+msgstr[1] "%ld lignes, "
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 caractère"
-
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> caractères"
+msgid "%lld character"
+msgid_plural "%lld characters"
+msgstr[0] "%lld caractère"
+msgstr[1] "%lld caractères"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[noeol]"
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[Dernière ligne incomplète]"
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "ALERTE : Le fichier a été modifié depuis que Vim l'a lu !"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "Voulez-vous vraiment écrire dedans"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Erreur lors de l'écriture dans \"%s\""
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Erreur lors de la fermeture de \"%s\""
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Erreur lors de la lecture de \"%s\""
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: L'autocommande FileChangedShell a effacé le tampon"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: Le fichier \"%s\" n'est plus disponible"
# DB - todo : Suggestion. Bof bof, à améliorer.
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2574,40 +2143,32 @@ msgid ""
msgstr ""
"W12: Alerte : Le fichier \"%s\" a été modifié, ainsi que le tampon dans Vim"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
msgstr "Consultez \":help W12\" pour plus d'information."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: Alerte : Le fichier \"%s\" a changé depuis le début de l'édition"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "Consultez \":help W11\" pour plus d'information."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr ""
"W16: Alerte : Les permissions de \"%s\" ont changé depuis le début de "
"l'édition"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "Consultez \":help W16\" pour plus d'information."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: Alerte : Le fichier \"%s\" a été créé après le début de l'édition"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Alerte"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2615,830 +2176,618 @@ msgstr ""
"&Ok\n"
"&Charger le fichier"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Impossible de préparer le rechargement de \"%s\""
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Impossible de recharger \"%s\""
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--Effacé--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "Autocommandes marquées pour auto-suppression : %s <tampon=%d>"
-#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: Aucun groupe \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Impossible de supprimer le groupe courant"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: Effacement d'augroup toujours en usage"
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: Caractère non valide après * : %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: Aucun événement %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: Aucun événement ou groupe %s"
-#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Auto-commandes ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <buffer=%d> : numéro de tampon invalide"
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr ""
"E217: Impossible d'exécuter les autocommandes pour TOUS les événements (ALL)"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "Aucune autocommande correspondante"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: autocommandes trop imbriquées"
-#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "Autocommandes %s pour \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "Exécution de %s"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "autocommande %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { manquant."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } manquant."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: Aucun repli trouvé"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: Impossible de créer un repli avec la 'foldmethod'e actuelle"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: Impossible de supprimer un repli avec la 'foldmethod'e actuelle"
-#: ../fold.c:1784
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld lignes repliées "
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld ligne déplacée "
+msgstr[1] "+--%3ld lignes déplacées "
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: Ajout au tampon de lecture"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: mappage récursif"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: une abréviation globale existe déjà pour %s"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: un mappage global existe déjà pour %s"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: une abréviation existe déjà pour %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: un mappage existe déjà pour %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "Aucune abréviation trouvée"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "Aucun mappage trouvé"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap : mode invalide"
-# msgstr "--Pas de lignes dans le tampon--"
-# DB - todo : ou encore : msgstr "--Aucune ligne dans le tampon--"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--Le tampon est vide--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: Commande annulée"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: Argument requis"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ devrait être suivi de /, ? ou &"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgid "E851: Failed to create a new process for the GUI"
msgstr ""
-"E11: Invalide dans la fenêtre ligne-de-commande ; <CR> exécute, CTRL-C quitte"
+"E851: Échec lors de la création d'un nouveau processus pour l'interface "
+"graphique"
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgid "E852: The child process failed to start the GUI"
msgstr ""
-"E12: commande non autorisée depuis un exrc/vimrc dans répertoire courant ou "
-"une recherche de marqueur"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif manquant"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry manquant"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile manquant"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor manquant"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile sans :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor sans :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Le fichier existe déjà (ajoutez ! pour passer outre)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: La commande a échoué"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: Erreur interne"
+"E852: Le processus fils n'a pas réussi à démarrer l'interface graphique"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Interrompu"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Adresse invalide"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Argument invalide"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Impossible de démarrer l'interface graphique"
-#: ../globals.h:1015
#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Argument invalide : %s"
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Impossible de lire \"%s\""
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Expression invalide : %s"
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr ""
+"E665: Impossible de démarrer l'IHM graphique, aucune police valide trouvée"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Plage invalide"
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' est invalide"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Commande invalide"
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Valeur de 'imactivatekey' invalide"
-#: ../globals.h:1019
#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" est un répertoire"
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Impossible d'allouer la couleur %s"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Valeur de défilement invalide"
+msgid "No match at cursor, finding next"
+msgstr "Aucune correspondance sous le curseur, recherche de la suivante"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+msgid "<cannot open> "
+msgstr "<impossible d'ouvrir> "
-#: ../globals.h:1022
#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile : impossible d'obtenir la police %s"
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: L'appel à la bibliothèque a échoué pour \"%s()\""
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile : impossible de revenir dans le répertoire courant"
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: La marque a un numéro de ligne invalide"
+msgid "Pathname:"
+msgstr "Chemin :"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Marque non positionnée"
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile : impossible d'obtenir le répertoire courant"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Impossible de modifier, 'modifiable' est désactivé"
+msgid "OK"
+msgstr "Ok"
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Trop de récursion dans les scripts"
+msgid "Cancel"
+msgstr "Annuler"
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Pas de fichier alternatif"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Widget scrollbar : Impossible d'obtenir la géométrie du pixmap 'thumb'"
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Cette abréviation n'existe pas"
+msgid "Vim dialog"
+msgstr "Vim"
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: Le ! n'est pas autorisé"
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: Impossible de créer un BalloonEval avec message ET callback"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: L'interface graphique n'a pas été compilée dans cette version"
+msgid "_Cancel"
+msgstr "_Annuler"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Aucun nom de groupe de surbrillance %s"
+msgid "_Save"
+msgstr "_Enregistrer"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: Pas encore de texte inséré"
+msgid "_Open"
+msgstr "_Ouvrir"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Aucune ligne de commande précédente"
+msgid "_OK"
+msgstr "_Ok"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Mappage inexistant"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Oui\n"
+"&Non\n"
+"&Annuler"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Aucune correspondance"
+msgid "Yes"
+msgstr "Oui"
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Aucune correspondance : %s"
+msgid "No"
+msgstr "Non"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Aucun nom de fichier"
+# todo '_' is for hotkey, i guess?
+msgid "Input _Methods"
+msgstr "_Méthodes de saisie"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Aucune expression régulière de substitution précédente"
+msgid "VIM - Search and Replace..."
+msgstr "Remplacer - Vim"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Aucune commande précédente"
+msgid "VIM - Search..."
+msgstr "Rechercher - Vim"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Aucune expression régulière précédente"
+msgid "Find what:"
+msgstr "Rechercher :"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Les plages ne sont pas autorisées"
+msgid "Replace with:"
+msgstr "Remplacer par :"
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: Pas assez de place"
+msgid "Match whole word only"
+msgstr "Mots entiers seulement"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Impossible de créer le fichier %s"
+msgid "Match case"
+msgstr "Respecter la casse"
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Impossible d'obtenir un nom de fichier temporaire"
+msgid "Direction"
+msgstr "Direction"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Impossible d'ouvrir le fichier \"%s\""
+msgid "Up"
+msgstr "Haut"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: Impossible de lire le fichier %s"
+msgid "Down"
+msgstr "Bas"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: Modifications non enregistrées (ajoutez ! pour passer outre)"
+msgid "Find Next"
+msgstr "Suivant"
-# AB - Il faut respecter l'esprit plus que la lettre. Dans le cas présent,
-# nettement plus.
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Attention : tout n'est pas enregistré]\n"
+msgid "Replace"
+msgstr "Remplacer"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: Argument null"
+msgid "Replace All"
+msgstr "Remplacer tout"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Nombre attendu"
+msgid "_Close"
+msgstr "_Fermer"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Impossible d'ouvrir le fichier d'erreurs %s"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim : Une requête \"die\" a été reçue par le gestionnaire de session\n"
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Mémoire épuisée"
+msgid "Close tab"
+msgstr "Fermer l'onglet"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Motif introuvable"
+msgid "New tab"
+msgstr "Nouvel onglet"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Motif introuvable : %s"
+# DB - todo : un peu long. Cet entrée de menu permet d'ouvrir un fichier
+# dans un nouvel onglet via le sélecteur de fichiers graphique.
+msgid "Open Tab..."
+msgstr "Ouvrir dans un onglet..."
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: L'argument doit être positif"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim : Fenêtre principale détruite inopinément\n"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Impossible de retourner au répertoire précédent"
+msgid "&Filter"
+msgstr "&Filtrer"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Aucune erreur"
+msgid "&Cancel"
+msgstr "&Annuler"
-# DB - TODO : trouver une traduction valable et attestée pour "location".
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Aucune liste d'emplacements"
+msgid "Directories"
+msgstr "Répertoires"
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: La chaîne de recherche est endommagée"
+msgid "Filter"
+msgstr "Filtre"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: L'automate de regexp est corrompu"
+msgid "&Help"
+msgstr "&Aide"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: L'option 'readonly' est activée (ajoutez ! pour passer outre)"
+msgid "Files"
+msgstr "Fichiers"
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: La variable \"%s\" est en lecture seule"
+msgid "&OK"
+msgstr "&Ok"
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr ""
-"E794: Impossible de modifier une variable depuis le bac à sable : \"%s\""
+msgid "Selection"
+msgstr "Sélection"
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Erreur lors de la lecture du fichier d'erreurs"
+msgid "Find &Next"
+msgstr "Suiva&nt"
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Opération interdite dans le bac à sable"
+msgid "&Replace"
+msgstr "&Remplacer"
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Interdit à cet endroit"
+msgid "Replace &All"
+msgstr "Rempl&acer tout"
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: Choix du mode d'écran non supporté"
+msgid "&Undo"
+msgstr "Ann&uler"
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Valeur de défilement invalide"
+msgid "Open tab..."
+msgstr "Ouvrir dans un onglet..."
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: L'option 'shell' est vide"
+msgid "Find string"
+msgstr "Trouver une chaîne"
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Impossible de lire les données du symbole !"
+msgid "Find & Replace"
+msgstr "Trouver & remplacer"
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: Erreur lors de la fermeture du fichier d'échange"
+# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un
+# paramétrage bidon afin de sélectionner un répertoire plutôt qu'un
+# fichier.
+msgid "Not Used"
+msgstr "Non utilisé"
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: La pile des marqueurs est vide"
+# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un
+# paramétrage bidon afin de sélectionner un répertoire plutôt qu'un
+# fichier.
+msgid "Directory\t*.nothing\n"
+msgstr "Répertoire\t*.rien\n"
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Commande trop complexe"
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Titre de fenêtre \"%s\" introuvable"
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Nom trop long"
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argument non supporté : \"-%s\" ; Utilisez la version OLE."
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: Trop de ["
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Impossible d'ouvrir une fenêtre dans une application MDI"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: Trop de noms de fichiers"
+# DB - todo : perfectible.
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Erreur d'allocation de couleurs, couleurs possiblement incorrectes"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Caractères surnuméraires"
+# DB - todo : La VF est-elle compréhensible ?
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr ""
+"E250: Des polices manquent dans %s pour les jeux de caractères suivants :"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Marque inconnue"
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Nom du jeu de polices : %s"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Impossible de développer les métacaractères"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "La police '%s' n'a pas une largeur fixe"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ne peut pas être plus petit que 'winminheight'"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Nom du jeu de polices : %s"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ne peut pas être plus petit que 'winminwidth'"
+#, c-format
+msgid "Font0: %s"
+msgstr "Font0: %s"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: Erreur lors de l'écriture"
+#, c-format
+msgid "Font1: %s"
+msgstr "Font1: %s"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Le quantificateur est nul"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "La largeur de Font%ld n'est pas le double de celle de Font0"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: <SID> utilisé en dehors d'un script"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Largeur de Font0 : %ld"
-#: ../globals.h:1102
#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Erreur interne : %s"
+msgid "Font1 width: %ld"
+msgstr "Largeur de Font1 : %ld"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: le motif utilise plus de mémoire que 'maxmempattern'"
+# DB - todo : Pas certain de mon coup, ici...
+msgid "Invalid font specification"
+msgstr "La spécification de la police est invalide"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: tampon vide"
+msgid "&Dismiss"
+msgstr "Aban&donner"
-#: ../buffer.c:1587
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Le tampon %<PRId64> n'existe pas"
+# DB - todo : Pas certain de mon coup, ici...
+msgid "no specific match"
+msgstr "aucune correspondance particulière"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Délimiteur ou motif de recherche invalide"
+msgid "Vim - Font Selector"
+msgstr "Choisir une police - Vim"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Le fichier est chargé dans un autre tampon"
+msgid "Name:"
+msgstr "Nom :"
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: L'option '%s' n'est pas activée"
+msgid "Show size in Points"
+msgstr "Afficher la taille en Points"
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: Nom de registre invalide"
+msgid "Encoding:"
+msgstr "Encodage :"
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "La recherche a atteint le HAUT, et continue en BAS"
+msgid "Font:"
+msgstr "Police :"
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "La recherche a atteint le BAS, et continue en HAUT"
+msgid "Style:"
+msgstr "Style :"
+
+msgid "Size:"
+msgstr "Taille :"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ERREUR dans l'automate Hangul"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: ':' manquant"
# DB - Il s'agit ici d'un problème lors du parsing d'une option dont le contenu
# est une liste d'éléments séparés par des virgules.
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: élément invalide"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: chiffre attendu"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "Page %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "Aucun texte à imprimer"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "Impression de la page %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Copie %d sur %d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Imprimé : %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Impression interrompue"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: Erreur lors de l'écriture du fichier PostScript"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Impossible d'ouvrir le fichier \"%s\""
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Impossible de lire le fichier de ressource PostScript \"%s\""
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: \"%s\" n'est pas un fichier de ressource PostScript"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: \"%s\" n'est pas un fichier de ressource PostScript supporté"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: La version du fichier de ressource \"%s\" est erronée"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: Jeu de caractères et encodage multi-octets incompatibles"
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr ""
"E674: 'printmbcharset' ne peut pas être vide avec un encodage multi-octets"
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Aucune police par défaut pour l'impression multi-octets"
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: Impossible d'ouvrir le fichier PostScript de sortie"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Impossible d'ouvrir le fichier \"%s\""
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: Le fichier de ressource PostScript \"prolog.ps\" est introuvable"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr ""
"E456: Le fichier de ressource PostScript \"cidfont.ps\" est introuvable"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: Le fichier de ressource PostScript \"%s.ps\" est introuvable"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: La conversion pour imprimer dans l'encodage \"%s\" a échoué"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "Envoi à l'imprimante..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: L'impression du fichier PostScript a échoué"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "Tâche d'impression envoyée."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "Ajouter une base de données"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Rechercher un motif"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "Afficher ce message"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Fermer une connexion"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Réinitialiser toutes les connexions"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Afficher les connexions"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: Utilisation : cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "Cette commande cscope ne supporte pas le partage de la fenêtre.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: Utilisation : cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag : marqueur introuvable"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: Erreur stat(%s) : %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: Erreur stat"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s n'est pas un répertoire ou une base de données cscope valide"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "Base de données cscope %s ajoutée"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: erreur lors de la lecture de la connexion cscope %<PRId64>"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: erreur lors de la lecture de la connexion cscope %ld"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: type de recherche cscope inconnu"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Impossible de créer les tuyaux (pipes) cscope"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Impossible de forker pour cscope"
-#: ../if_cscope.c:849
-#, fuzzy
msgid "cs_create_connection setpgid failed"
-msgstr "exec de cs_create_connection a échoué"
+msgstr "cs_create_connection setpgid a échoué"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "exec de cs_create_connection a échoué"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection : fdopen pour to_fp a échoué"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection : fdopen pour fr_fp a échoué"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: Impossible d'engendrer le processus cscope"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: Aucune connexion cscope"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: Drapeau cscopequickfix %c invalide pour %c"
# DB - todo
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: aucune correspondance trouvée pour la requête cscope %s de %s"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "commandes cscope :\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (Utilisation : %s)"
-#: ../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"
@@ -3449,6 +2798,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: Trouver les affectations à ce symbole\n"
" c: Trouver les fonctions appelant cette fonction\n"
" d: Trouver les fonctions appelées par cette fonction\n"
" e: Trouver ce motif egrep\n"
@@ -3458,31 +2808,32 @@ msgstr ""
" s: Trouver ce symbole C\n"
" t: Trouver cette chaîne\n"
-#: ../if_cscope.c:1226
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: impossible d'ouvrir la base de données cscope %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr ""
+"E626: impossible d'obtenir des informations sur la base de données cscope"
+
msgid "E568: duplicate cscope database not added"
msgstr "E568: base de données cscope redondante non ajoutée"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: Connexion cscope %s introuvable"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "connexion cscope %s fermée"
-#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: erreur fatale dans cs_manage_matches"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Marqueur cscope : %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3491,87 +2842,304 @@ msgstr ""
" # ligne"
# DB - todo : Faut-il respecter l'alignement ici ?
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "nom / contexte/ ligne\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Erreur cscope : %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Toutes les bases de données cscope ont été réinitialisées"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "aucune connexion cscope\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid nom de la base de données chemin\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "La bibliothèque Lua n'a pas pu être chargée."
+
+msgid "cannot save undo information"
+msgstr "impossible d'enregistrer les informations d'annulation"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: Désolé, cette commande est désactivée : les bibliothèques MzScheme "
+"n'ont pas pu être chargées."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: Désolé, cette commande est désactivée : le module MzScheme racket/base "
+"ne peut pas être chargé."
+
+msgid "invalid expression"
+msgstr "expression invalide"
+
+msgid "expressions disabled at compile time"
+msgstr "expressions désactivées lors de la compilation"
+
+msgid "hidden option"
+msgstr "option cachée"
+
+msgid "unknown option"
+msgstr "option inconnue"
+
+msgid "window index is out of range"
+msgstr "numéro de fenêtre hors limites"
+
+msgid "couldn't open buffer"
+msgstr "impossible d'ouvrir le tampon"
+
+msgid "cannot delete line"
+msgstr "impossible d'effacer la ligne"
+
+msgid "cannot replace line"
+msgstr "impossible de remplacer la ligne"
+
+msgid "cannot insert line"
+msgstr "impossible d'insérer la ligne"
+
+msgid "string cannot contain newlines"
+msgstr "une chaîne ne peut pas contenir de saut-de-ligne"
+
+msgid "error converting Scheme values to Vim"
+msgstr "erreur lors de la conversion d'une valeur de Scheme à Vim"
+
+msgid "Vim error: ~a"
+msgstr "Erreur Vim : ~a"
+
+msgid "Vim error"
+msgstr "Erreur Vim"
+
+msgid "buffer is invalid"
+msgstr "tampon invalide"
+
+msgid "window is invalid"
+msgstr "fenêtre invalide"
+
+msgid "linenr out of range"
+msgstr "numéro de ligne hors limites"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "non autorisé dans le bac à sable"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: Vim ne peut pas exécuter :python après avoir utilisé :py3"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Désolé, commande désactivée : la bibliothèque Python n'a pas pu être "
+"chargée."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: Désolé, commande désactivée : la bibliothèque Python n'a pas pu être "
+"chargée."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Impossible d'invoquer Python récursivement"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: Vim ne peut pas exécuter :py3 après avoir utilisé :python"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ doit être une instance de chaîne (String)"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Désolé, commande désactivée : la bibliothèque Ruby n'a pas pu être "
+"chargée."
+
+msgid "E267: unexpected return"
+msgstr "E267: « return » inattendu"
+
+msgid "E268: unexpected next"
+msgstr "E268: « next » inattendu"
+
+msgid "E269: unexpected break"
+msgstr "E269: « break » inattendu"
+
+msgid "E270: unexpected redo"
+msgstr "E270: « redo » inattendu"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: « retry » hors d'une clause « rescue »"
+
+msgid "E272: unhandled exception"
+msgstr "E272: Exception non prise en charge"
+
+# DB - todo
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: contexte de longjmp inconnu : %d"
+
+msgid "invalid buffer number"
+msgstr "numéro de tampon invalide"
+
+msgid "not implemented yet"
+msgstr "pas encore implémenté"
+
+# DB - TODO : le contexte est celui d'une annulation.
+msgid "cannot set line(s)"
+msgstr "Impossible de remettre la/les ligne(s)"
+
+msgid "invalid mark name"
+msgstr "nom de marque invalide"
+
+msgid "mark not set"
+msgstr "marque non positionnée"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "ligne %d colonne %d"
+
+msgid "cannot insert/append line"
+msgstr "Impossible d'insérer/ajouter de lignes"
+
+msgid "line number out of range"
+msgstr "numéro de ligne hors limites"
+
+msgid "unknown flag: "
+msgstr "drapeau inconnu : "
+
+msgid "unknown vimOption"
+msgstr "vimOption inconnue"
+
+msgid "keyboard interrupt"
+msgstr "interruption clavier"
+
+msgid "vim error"
+msgstr "erreur Vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr ""
+"Impossible de créer commande de tampon/fenêtre : objet en cours d'effacement"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"Impossible d'inscrire la commande de rappel : tampon/fenêtre en effacement"
+
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: ERREUR FATALE TCL: reflist corrompue ?! Contactez vim-dev@vim.org, SVP."
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"Impossible d'inscrire la commande de rappel : réf. tampon/fenêtre introuvable"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Désolé, commande désactivée: la bibliothèque Tcl n'a pas pu être "
+"chargée."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: code de sortie %d"
+
+msgid "cannot get line"
+msgstr "Impossible d'obtenir la ligne"
+
+msgid "Unable to register a command server name"
+msgstr "Impossible d'inscrire un nom de serveur de commande"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Échec de l'envoi de la commande au programme cible"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Id utilisé pour le serveur invalide : %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: Entrée registre de l'instance de Vim mal formatée. Suppression !"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Clé dupliquée dans le document JSON : \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Il manque une virgule dans la Liste %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: Il manque ']' à la fin de la Liste %s"
+
msgid "Unknown option argument"
msgstr "Option inconnue"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "Trop d'arguments d'édition"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "Argument manquant après"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "arguments en trop après l'option"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "Trop d'arguments \"+command\", \"-c command\" ou \"--cmd command\""
-#: ../main.c:154
msgid "Invalid argument for"
msgstr "Argument invalide pour"
-#: ../main.c:294
#, c-format
msgid "%d files to edit\n"
msgstr "%d fichiers à éditer\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans n'est pas supporté avec cette interface graphique\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' ne peut pas être utilisé : désactivé à la compilation\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Ce Vim n'a pas été compilé avec la fonctionnalité diff"
+
msgid "Attempt to open script file again: \""
msgstr "Nouvelle tentative pour ouvrir le script : \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Impossible d'ouvrir en lecture : \""
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Impossible d'ouvrir pour la sortie script : \""
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim : Erreur : Impossible de démarrer gvim depuis NetBeans\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr ""
+"Vim : Erreur : Cette version de Vim ne fonctionne pas dans un terminal "
+"Cygwin\n"
+
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim : Alerte : La sortie ne s'effectue pas sur un terminal\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim : Alerte : L'entrée ne se fait pas sur un terminal\n"
-#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "ligne de commande pre-vimrc"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Impossible de lire \"%s\""
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3579,37 +3147,30 @@ msgstr ""
"\n"
"Plus d'info avec : \"vim -h\"\n"
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[fichier ...] ouvrir le ou les fichiers spécifiés"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- lire le texte à partir de stdin"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t marqueur ouvrir le fichier qui contient le marqueur"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [fichErr] ouvrir à l'endroit de la première erreur"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
-"utilisation :"
+"Utilisation :"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [args] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3617,7 +3178,15 @@ msgstr ""
"\n"
" ou :"
-#: ../main.c:2196
+# DB - todo (VMS uniquement).
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"pour lesquels la casse est indifférente (/ pour que le drapeau soit "
+"majuscule)"
+
msgid ""
"\n"
"\n"
@@ -3627,192 +3196,338 @@ msgstr ""
"\n"
"Arguments :\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\tSeuls des noms de fichier sont spécifiés après ceci"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\tNe pas développer les métacaractères"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\tInscrire ce gvim pour OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\tDésinscrire gvim de OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\tLancer l'interface graphique (comme \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr ""
+"-f, --nofork\tPremier-plan : ne pas détacher l'interface graphique du "
+"terminal"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\tMode Vi (comme \"vi\")"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\tMode Ex (comme \"ex\")"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
msgstr "-E\t\t\tMode Ex amélioré"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\tMode silencieux (batch) (seulement pour \"ex\")"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\tMode diff (comme \"vimdiff\")"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
msgstr "-y\t\tMode facile (comme \"evim\", vim sans modes)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\tMode lecture seule (comme \"view\")"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\tMode restreint (comme \"rvim\")"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\tInterdire l'enregistrement des fichiers"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\tInterdire toute modification de texte"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\tMode binaire"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\tMode lisp"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\tCompatible avec Vi : 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\tPas totalement compatible avec Vi : 'nocompatible'"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr "-V[N][<fichier>]\tMode verbeux [niveau N] [dans <fichier>]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\tMode débogage"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\tNe pas utiliser de fichier d'échange, seulement la mémoire"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\tLister les fichiers d'échange et quitter"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r <fichier>\tRécupérer une session plantée"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\tComme -r"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\tNe pas utiliser newcli pour l'ouverture des fenêtres"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <périph>\tUtiliser <périphérique> pour les E/S"
+
+msgid "-A\t\t\tStart in Arabic mode"
msgstr "-A\t\tDémarrer en mode arabe"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\tDémarrer en mode hébreu"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\tDémarrer en mode farsi"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <term>\tRégler le type du terminal sur <terminal>"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr ""
+"--no-a-term\t\tAucun avertissement si l'entrée/sortie n'est pas un terminal"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr "--ttyfail\t\tQuitte si l'entrée ou la sortie ne sont pas un terminal"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\tUtiliser <vimrc> au lieu du vimrc habituel"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\tUtiliser <gvimrc> au lieu du gvimrc habituel"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\tNe charger aucun greffon"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
msgstr "-p[N]\tOuvrir N onglets (défaut : un pour chaque fichier)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\tOuvrir N fenêtres (défaut : une pour chaque fichier)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\tComme -o, mais partager verticalement"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\tOuvrir à la fin du fichier"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<numL>\tOuvrir le fichier à la ligne <numL>"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr "--cmd <cmde>\tExécuter <commande> avant de charger les fichiers vimrc"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <cmde>\tExécuter <commande> une fois le 1er fichier chargé"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr ""
"-S <session>\tSourcer le fichier <session> une fois le 1er fichier chargé"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <src>\tLire les commandes du mode Normal à partir du fichier <src>"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr "-w <dest>\tAjouter toutes les commandes tapées dans le fichier <dest>"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr "-W <dest>\tÉcrire toutes les commandes tapées dans le fichier <dest>"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tÉditer des fichiers chiffrés"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tConnecter Vim au serveur X spécifié"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNe pas se connecter à un serveur X"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <fich>\tÉditer les <fichiers> dans un serveur Vim si possible"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent ...\tPareil, mais pas d'erreur s'il n'y a aucun serveur"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <fich>\tComme --remote mais ne quitter qu'à la fin de l'édition"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent\tPareil, mais pas d'erreur s'il n'y a aucun serveur"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <fich>\tComme --remote mais ouvrir un onglet "
+"pour chaque fichier"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <tche>\tEnvoyer <touches> à un serveur Vim puis quitter"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <expr>\tÉvaluer <expr> dans un serveur Vim, afficher le "
+"résultat"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr ""
+"--serverlist\t\tLister les noms des serveurs Vim disponibles et quitter"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <nom>\tEnvoyer au/devenir le serveur Vim nommé <nom>"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr ""
"--startuptime <fich>\tÉcrire les messages d'horodatage au démarrage dans "
"<fich>"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\tUtiliser <viminfo> au lieu du viminfo habituel"
-#: ../main.c:2243
+msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo"
+msgstr ""
+"--clean\t\t'nocompatible', réglages par défaut, aucun greffon ni viminfo"
+
msgid "-h or --help\tPrint Help (this message) and exit"
msgstr "-h ou --help\t\tAfficher l'aide (ce message) puis quitter"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\tAfficher les informations de version et quitter"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Arguments reconnus par gvim (version Motif) :\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Arguments reconnus par gvim (version neXtaw) :\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Arguments reconnus par gvim (version Athena) :\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <écran>\tLancer Vim sur ce <display>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tIconifier Vim au démarrage"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr ""
+"-background <coul>\tUtiliser <couleur> pour l'arrière-plan\t (abrv : -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr ""
+"-foreground <coul>\tUtiliser <couleur> pour le texte normal\t (abrv : -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <fonte>\tUtiliser <fonte> pour le texte normal\t (abrv : -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <fonte>\tUtiliser <fonte> pour le texte gras"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <fonte>\tUtiliser <fonte> pour le texte italique"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <géom>\tUtiliser cette <géométrie> initiale\t (abrv : -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr ""
+"-borderwidth <épais>\tUtiliser cette <épaisseur> de bordure\t (abrv : -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <lg>\tUtiliser cette <largeur> de barre de défil. (abrv: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <haut>\tUtiliser cette <hauteur> de menu\t (abrv : -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tUtiliser la vidéo inverse\t\t (abrv : -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNe pas utiliser de vidéo inverse\t (abrv : +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <ressource>\tConfigurer la <ressource> spécifiée"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Arguments reconnus par gvim (version GTK+) :\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr ""
+"-display <display>\tLancer Vim sur ce <display>\t(également : --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <rôle>\tDonner un rôle pour identifier la fenêtre principale"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tOuvrir Vim dans un autre widget GTK"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tGvim affiche l'ID de la fenêtre sur stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <titre parent>\tOuvrir Vim dans une application parente"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tOuvrir Vim dans un autre widget win32"
+
+msgid "No display"
+msgstr "Aucun display"
+
+msgid ": Send failed.\n"
+msgstr " : L'envoi a échoué.\n"
+
+msgid ": Send failed. Trying to execute locally\n"
+msgstr " : L'envoi a échoué. Tentative d'exécution locale\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d édités sur %d"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Aucun display : L'envoi de l'expression a échoué.\n"
+
+msgid ": Send expression failed.\n"
+msgstr " : L'envoi de l'expression a échoué.\n"
+
msgid "No marks set"
msgstr "Aucune marque positionnée"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: Aucune marque ne correspond à \"%s\""
-#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3820,8 +3535,6 @@ msgstr ""
"\n"
"marq ligne col fichier/texte"
-#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3829,8 +3542,6 @@ msgstr ""
"\n"
" saut ligne col fichier/texte"
-#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3838,7 +3549,6 @@ msgstr ""
"\n"
"modif ligne col fichier/texte"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3846,8 +3556,6 @@ msgstr ""
"\n"
"# Marques dans le fichier :\n"
-#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3855,7 +3563,6 @@ msgstr ""
"\n"
"# Liste de sauts (le plus récent en premier) :\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3863,84 +3570,90 @@ msgstr ""
"\n"
"# Historique des marques dans les fichiers (les plus récentes en premier) :\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "'>' manquant"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: Page de codes non valide"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Impossible de régler les valeurs IC"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Échec de la création du contexte de saisie"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Échec de l'ouverture de la méthode de saisie"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr ""
+"E287: Alerte : Impossible d'inscrire le callback de destruction dans la MS"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: la méthode de saisie ne supporte aucun style"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr ""
+"E289: le type de préédition de Vim n'est pas supporté par la méthode de "
+"saisie"
+
msgid "E293: block was not locked"
msgstr "E293: le bloc n'était pas verrouillé"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Erreur de positionnement lors de la lecture du fichier d'échange"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Erreur de lecture dans le fichier d'échange"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Erreur de positionnement lors de l'écriture du fichier d'échange"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Erreur d'écriture dans le fichier d'échange"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: Le fichier d'échange existe déjà (attaque par symlink ?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Bloc n°0 non récupéré ?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: Bloc n°1 non récupéré ?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Bloc n°2 non récupéré ?"
-#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Erreur lors de la mise à jour du fichier d'échange crypté"
+
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: Oups, le fichier d'échange a disparu !"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Impossible de renommer le fichier d'échange"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: Impossible d'ouvrir fichier .swp pour \"%s\", récup. impossible"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0() : bloc 0 non récupéré ?!"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Aucun fichier d'échange trouvé pour %s"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Entrez le numéro du fichier d'échange à utiliser (0 pour quitter) : "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Impossible d'ouvrir %s"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Impossible de lire le bloc 0 de "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3949,28 +3662,22 @@ msgstr ""
"Il est possible qu'aucune modification n'a été faite ou que Vim n'a pas mis "
"à jour le fichier d'échange."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " ne peut pas être utilisé avec cette version de Vim.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Utilisez Vim version 3.0.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ne semble pas être un fichier d'échange de Vim"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " ne peut pas être utilisé sur cet ordinateur.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "Le fichier a été créé le "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3978,86 +3685,107 @@ msgstr ""
",\n"
"ou le fichier a été endommagé."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: %s est chiffré et cette version de Vim ne supporte pas le chiffrement"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " a été endommagé (taille de page inférieure à la valeur minimale).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "Utilisation du fichier d'échange \"%s\""
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "Fichier original \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: Alerte : Le fichier original a pu être modifié"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Fichier d'échange chiffré : \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"Si vous avez tapé une nouvelle clé de chiffrement mais n'avez pas enregistré "
+"le fichier texte,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"tapez la nouvelle clé de chiffrement."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"Si vous avez écrit le fichier texte après avoir changé la clé de "
+"chiffrement, appuyez sur entrée"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"afin d'utiliser la même clé pour le fichier texte et le fichier d'échange"
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Impossible de lire le bloc 1 de %s"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???DE NOMBREUSES LIGNES MANQUENT"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???NOMBRE DE LIGNES ERRONÉ"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???BLOC VIDE"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???LIGNES MANQUANTES"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: ID du bloc 1 erroné (%s n'est pas un fichier d'échange ?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???BLOC MANQUANT"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? d'ici jusqu'à ???FIN des lignes peuvent être corrompues"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? d'ici jusqu'à ???FIN des lignes ont pu être insérées/effacées"
-#: ../memline.c:1181
msgid "???END"
msgstr "???FIN"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: Récupération interrompue"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: Erreurs lors de la récupération ; examinez les lignes commençant "
"par ???"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "Consultez \":help E312\" pour plus d'information."
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "Récupération achevée. Vérifiez que tout est correct."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -4065,17 +3793,14 @@ msgstr ""
"\n"
"(Vous voudrez peut-être enregistrer ce fichier sous un autre nom\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "et lancer diff avec le fichier original pour repérer les changements)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr ""
"Récupération achevée. Le contenu du tampon est identique au contenu du "
"fichier."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -4085,52 +3810,44 @@ msgstr ""
"Il est conseillé d'effacer maintenant le fichier .swp.\n"
"\n"
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr ""
+"Utilisation de la clé de chiffrement du fichier d'échange pour le fichier "
+"texte.\n"
+
msgid "Swap files found:"
msgstr "Fichiers d'échange trouvés :"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " Dans le répertoire courant :\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr "Utilisant le nom indiqué :\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " Dans le répertoire "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- aucun --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " propriété de : "
-#: ../memline.c:1529
msgid " dated: "
msgstr " daté : "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " daté : "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [de Vim version 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [ne semble pas être un fichier d'échange Vim]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " nom de fichier : "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -4138,15 +3855,12 @@ msgstr ""
"\n"
" modifié : "
-#: ../memline.c:1559
msgid "YES"
msgstr "OUI"
-#: ../memline.c:1559
msgid "no"
msgstr "non"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -4154,11 +3868,9 @@ msgstr ""
"\n"
" nom d'utilisateur : "
-#: ../memline.c:1568
msgid " host name: "
msgstr " nom d'hôte : "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -4166,7 +3878,6 @@ msgstr ""
"\n"
" nom d'hôte : "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -4174,11 +3885,16 @@ msgstr ""
"\n"
" processus n° : "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (en cours d'exécution)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [inutilisable avec cette version de Vim]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -4186,97 +3902,75 @@ msgstr ""
"\n"
" [inutilisable sur cet ordinateur]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [ne peut être lu]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [ne peut être ouvert]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: Préservation impossible, il n'y a pas de fichier d'échange"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "Fichier préservé"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: Échec de la préservation"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get : numéro de ligne invalide : %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get : numéro de ligne invalide : %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get : ligne %<PRId64> introuvable"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get : ligne %ld introuvable"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: mauvais id de pointeur de bloc 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx devrait être 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: Trop de blocs mis à jour ?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: mauvais id de pointeur de bloc 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "bloc 1 effacé ?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Ligne %<PRId64> introuvable"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Ligne %ld introuvable"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: mauvais id de pointeur de bloc"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count vaut zéro"
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: numéro de ligne hors limites : %<PRId64> au-delà de la fin"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: numéro de ligne hors limites : %ld au-delà de la fin"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: nombre de lignes erroné dans le bloc %<PRId64>"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: nombre de lignes erroné dans le bloc %ld"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "La taille de la pile s'accroît"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: mauvais id de pointeur de block 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: cycle de liens symboliques avec \"%s\""
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: ATTENTION"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4284,39 +3978,30 @@ msgstr ""
"\n"
"Trouvé un fichier d'échange nommé \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Lors de l'ouverture du fichier \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " PLUS RÉCENT que le fichier d'échange !\n"
-#: ../memline.c:3244
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) Un autre programme est peut-être en train d'éditer ce fichier.\n"
" Si c'est le cas, faites attention à ne pas vous retrouver avec\n"
-" deux versions différentes du même fichier en faisant des modifications."
+" deux versions différentes du même fichier en faisant des modifications.\n"
+" Quitter ou continuer avec attention.\n"
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " Quittez, ou continuez prudemment.\n"
-
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) Une session d'édition de ce fichier a planté.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " Si c'est le cas, utilisez \":recover\" ou \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4324,11 +4009,9 @@ msgstr ""
"\"\n"
" pour récupérer le fichier (consultez \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " Si vous l'avez déjà fait, effacez le fichier d'échange \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4336,23 +4019,18 @@ msgstr ""
"\"\n"
" pour éviter ce message.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Le fichier d'échange \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" existe déjà !"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - ATTENTION"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "Un fichier d'échange existe déjà !"
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4366,7 +4044,6 @@ msgstr ""
"&Quitter\n"
"&Abandonner"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4382,58 +4059,33 @@ msgstr ""
"&Quitter\n"
"&Abandonner"
-#.
-#. * 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
msgid "E326: Too many swap files found"
msgstr "E326: Trop de fichiers d'échange trouvés"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Mémoire épuisée ! (allocation de %<PRIu64> octets)"
-
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Une partie du chemin de l'élément de menu n'est pas un sous-menu"
# DB - todo : J'hésite avec
# msgstr "E328: Le menu n'existe pas dans ce mode"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Le menu n'existe que dans un autre mode"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Aucun menu \"%s\""
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: Nom de menu vide"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Le chemin de menu ne doit pas conduire à un sous-menu"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: Ajout d'éléments de menu directement dans barre de menu interdit"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Un séparateur ne peut faire partie d'un chemin de menu"
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4441,75 +4093,62 @@ msgstr ""
"\n"
"--- Menus ---"
-#: ../menu.c:1313
+msgid "Tear off this menu"
+msgstr "Détacher ce menu"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Le menu n'est pas défini pour le mode %s"
+
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: Le chemin du menu doit conduire à un élément de menu"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: Menu introuvable : %s"
-#: ../menu.c:1396
-#, c-format
-msgid "E335: Menu not defined for %s mode"
-msgstr "E335: Le menu n'est pas défini pour le mode %s"
-
-#: ../menu.c:1426
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: Le chemin du menu doit conduire à un sous-menu"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: Menu introuvable - vérifiez les noms des menus"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Erreur détectée en traitant %s :"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "ligne %4ld :"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Nom de registre invalide : '%s'"
# DB - todo : mettre à jour ?
-#: ../message.c:745
msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
msgstr "Maintenance des messages : Dominique Pellé <dominique.pelle@gmail.com>"
-#: ../message.c:986
msgid "Interrupt: "
msgstr "Interruption : "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "Appuyez sur ENTRÉE ou tapez une commande pour continuer"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s, ligne %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s, ligne %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- Plus --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr ""
"ESPACE/d/j : écran/page/ligne vers le bas, b/u/k : vers le haut, q : quitter"
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Question"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4517,17 +4156,6 @@ msgstr ""
"&Oui\n"
"&Non"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Oui\n"
-"&Non\n"
-"&Annuler"
-
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4541,176 +4169,244 @@ msgstr ""
"Tout aban&donner\n"
"&Annuler"
-#: ../message.c:3058
+# DB : Les trois messages qui suivent sont des titres de boîtes
+# de dialogue par défaut.
+msgid "Select Directory dialog"
+msgstr "Sélecteur de répertoire"
+
+msgid "Save File dialog"
+msgstr "Enregistrer un fichier"
+
+msgid "Open File dialog"
+msgstr "Ouvrir un fichier"
+
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Désolé, pas de sélecteur de fichiers en mode console"
+
msgid "E766: Insufficient arguments for printf()"
msgstr "E766: Pas assez d'arguments pour printf()"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
msgstr "E807: printf() attend un argument de type Flottant"
-#: ../message.c:3873
msgid "E767: Too many arguments to printf()"
msgstr "E767: Trop d'arguments pour printf()"
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Alerte : Modification d'un fichier en lecture seule"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr "Tapez un nombre et <Entrée> ou cliquez avec la souris (rien annule) :"
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "Tapez un nombre et <Entrée> (rien annule) :"
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "1 ligne en plus"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "1 ligne en moins"
-
-#: ../misc1.c:2593
#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> lignes en plus"
+msgid "%ld more line"
+msgid_plural "%ld more lines"
+msgstr[0] "%ld ligne en plus"
+msgstr[1] "%ld lignes en plus"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> lignes en moins"
+msgid "%ld line less"
+msgid_plural "%ld fewer lines"
+msgstr[0] "%ld ligne en moins"
+msgstr[1] "%ld lignes en moins"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Interrompu)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "Bip !"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "ERREUR : "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[octets] total alloué-libéré %lu-%lu, utilisé %lu, pic %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[appels] total re/malloc() %lu, total free() %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: La ligne devient trop longue"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Erreur interne : lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Mémoire épuisée ! (allocation de %lu octets)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "Appel du shell pour exécuter : \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: ':' manquant"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Mode non autorisé"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Forme de curseur invalide"
+
+msgid "E548: digit expected"
+msgstr "E548: chiffre attendu"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Pourcentage non autorisé"
+
+msgid "E854: path too long for completion"
+msgstr "E854: chemin trop long pour complètement"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Chemin invalide : '**[nombre]' doit être à la fin du chemin ou être "
+"suivi de '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Répertoire \"%s\" introuvable dans 'cdpath'"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Fichier \"%s\" introuvable dans 'path'"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Plus de répertoire \"%s\" dans 'cdpath'"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Plus de fichier \"%s\" dans 'path'"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: Mode d'accès incorrect au fichier d'infos de connexion NetBeans : \"%s"
+"\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Connexion NetBeans perdue pour le tampon %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: netbeans n'est pas supporté avec cette interface graphique"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: netbeans déjà connecté"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s est en lecture seule (ajoutez ! pour passer outre)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: Aucun identifiant sous le curseur"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' est vide"
+msgid "E775: Eval feature not available"
+msgstr "E775: La fonctionnalité d'évaluation n'est pas disponible"
+
# DB : Il est ici question du mode Visuel.
-#: ../normal.c:2637
msgid "Warning: terminal cannot highlight"
msgstr "Alerte : le terminal ne peut pas surligner"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Aucune chaîne sous le curseur"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: Impossible d'effacer des replis avec la 'foldmethod'e actuelle"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: La liste des modifications (changelist) est vide"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Au début de la liste des modifications"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: À la fin de la liste des modifications"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "tapez :q<Entrée> pour quitter Vim"
-
-#: ../ops.c:248
-#, c-format
-msgid "1 line %sed 1 time"
-msgstr "1 ligne %sée 1 fois"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 ligne %sée %d fois"
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim"
+msgstr ""
+"Tapez :qa! puis <Entrée> pour abandonner tous les changements et quitter "
+"Vim"
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> lignes %sées 1 fois"
+msgid "%ld line %sed %d time"
+msgid_plural "%ld line %sed %d times"
+msgstr[0] "%ld lignes %sées %d fois"
+msgstr[1] "%ld lignes %sées %d fois"
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> lignes %sées %d fois"
+msgid "%ld lines %sed %d time"
+msgid_plural "%ld lines %sed %d times"
+msgstr[0] "%ld lignes %sées %d fois"
+msgstr[1] "%ld lignes %sées %d fois"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> lignes à indenter... "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "1 ligne indentée "
+msgid "%ld lines to indent... "
+msgstr "%ld lignes à indenter... "
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> lignes indentées "
+msgid "%ld line indented "
+msgid_plural "%ld lines indented "
+msgstr[0] "%ld ligne indentée "
+msgstr[1] "%ld lignes indentées "
-#: ../ops.c:938
msgid "E748: No previously used register"
msgstr "E748: Aucun registre n'a été précédemment utilisé"
# DB - Question O/N.
-#. must display the prompt
-#: ../ops.c:1433
msgid "cannot yank; delete anyway"
msgstr "impossible de réaliser une copie ; effacer tout de même"
-#: ../ops.c:1929
-msgid "1 line changed"
-msgstr "1 ligne modifiée"
-
-#: ../ops.c:1931
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> lignes modifiées"
+msgid "%ld line changed"
+msgid_plural "%ld lines changed"
+msgstr[0] "%ld ligne modifiée"
+msgstr[1] "%ld lignes modifiées"
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "bloc de 1 ligne copié"
+#, c-format
+msgid "freeing %ld lines"
+msgstr "libération de %ld lignes"
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "1 ligne copiée"
+#, c-format
+msgid " into \"%c"
+msgstr " dans \"%c"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "bloc de %<PRId64> lignes copié"
+msgid "block of %ld line yanked%s"
+msgid_plural "block of %ld lines yanked%s"
+msgstr[0] "bloc de %ld ligne copié%s"
+msgstr[1] "bloc de %ld lignes copié%s"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> lignes copiées"
+msgid "%ld line yanked%s"
+msgid_plural "%ld lines yanked%s"
+msgstr[0] "%ld ligne copiée%s"
+msgstr[1] "%ld lignes copiées%s"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: Le registre %s est vide"
-#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4718,11 +4414,9 @@ msgstr ""
"\n"
"--- Registres ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "Nom de registre invalide"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4730,202 +4424,195 @@ msgstr ""
"\n"
"# Registres :\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: Type de registre %d inconnu"
-#: ../ops.c:5089
+msgid ""
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr ""
+"E883: le motif de recherche et le registre d'expression ne peuvent pas "
+"contenir deux lignes ou plus"
+
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Colonnes ; "
+msgid "%ld Cols; "
+msgstr "%ld Colonnes ; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
msgstr ""
-"%s%<PRId64> sur %<PRId64> Lignes ; %<PRId64> sur %<PRId64> Mots ; %<PRId64> "
-"sur %<PRId64> Octets sélectionnés"
+"%s%ld sur %ld Lignes ; %lld sur %lld Mots ; %lld sur %lld Octets sélectionnés"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"%s%<PRId64> sur %<PRId64> Lignes ; %<PRId64> sur %<PRId64> Mots ; %<PRId64> "
-"sur %<PRId64> Caractères ; %<PRId64> sur %<PRId64> octets sélectionnés"
+"%s%ld sur %ld Lignes ; %lld sur %lld Mots ; %lld sur %lld Caractères ; %lld "
+"sur %lld octets sélectionnés"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
msgstr ""
-"Colonne %s sur %s ; Ligne %<PRId64> sur %<PRId64> ; Mot %<PRId64> sur "
-"%<PRId64> ; Octet %<PRId64> sur %<PRId64>"
+"Colonne %s sur %s ; Ligne %ld sur %ld ; Mot %lld sur %lld ; Octet %lld sur "
+"%lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"Colonne %s sur %s ; Ligne %<PRId64> sur %<PRId64> ; Mot %<PRId64> sur "
-"%<PRId64> ; Caractère %<PRId64> sur %<PRId64> ; Octet %<PRId64> sur %<PRId64>"
+"Colonne %s sur %s ; Ligne %ld sur %ld ; Mot %lld sur %lld ; Caractère %lld "
+"sur %lld ; Octet %lld sur %lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> pour le BOM)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Page %N"
+msgid "(+%lld for BOM)"
+msgstr "(+%lld pour le BOM)"
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Merci d'avoir choisi Vim"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Option inconnue"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: Option non supportée"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: Non autorisé dans une ligne de mode"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: Le code de touche n'est pas configuré"
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: Nombre requis après ="
-#: ../option.c:3226 ../option.c:3864
msgid "E522: Not found in termcap"
msgstr "E522: Introuvable dans termcap"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Caractère <%s> invalide"
-#: ../option.c:2253
#, c-format
msgid "For option %s"
msgstr "Pour l'option %s"
-#: ../option.c:3862
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: 'term' ne doit pas être une chaîne vide"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Impossible de modifier term dans l'interface graphique"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Utilisez \":gui\" pour démarrer l'interface graphique"
+
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: 'backupext' et 'patchmode' sont égaux"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
msgstr "E834: Conflits avec la valeur de 'listchars'"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
msgstr "E835: Conflits avec la valeur de 'fillchars'"
-#: ../option.c:4163
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Non modifiable dans l'interface graphique GTK+ 2"
+
+#, c-format
+msgid "E950: Cannot convert between %s and %s"
+msgstr "E950: Impossible de convertir de %s à %s"
+
msgid "E524: Missing colon"
msgstr "E524: ':' manquant"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Chaîne de longueur nulle"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
msgstr "E526: Nombre manquant après <%s>"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Virgule manquante"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: Une valeur ' doit être spécifiée"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: contient des caractères à largeur double non-imprimables"
-#: ../option.c:4469
+msgid "E596: Invalid font(s)"
+msgstr "E596: Police(s) invalide(s)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: Impossible de sélectionner un jeu de polices"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Jeu de polices invalide"
+
+msgid "E533: can't select wide font"
+msgstr "E533: Impossible de sélectionner une police à largeur double"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Police à largeur double invalide"
+
#, c-format
msgid "E535: Illegal character after <%c>"
msgstr "E535: Caractère invalide après <%c>"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: virgule requise"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr "E537: 'commentstring' doit être vide ou contenir %s"
+msgid "E538: No mouse support"
+msgstr "E538: La souris n'est pas supportée"
+
# DB - Le code est sans ambiguïté sur le caractère manquant.
# À défaut d'une traduction valable, au moins comprend-on
# ce qui se passe.
-#: ../option.c:4928
msgid "E540: Unclosed expression sequence"
msgstr "E540: '}' manquant"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: trop d'éléments"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
msgstr "E542: parenthèses non équilibrées"
-#: ../option.c:5148
+msgid "E946: Cannot make a terminal with running job modifiable"
+msgstr ""
+"E946: terminal avec tâche en cours d'exécution ne peut pas être modifiable"
+
msgid "E590: A preview window already exists"
msgstr "E590: Il existe déjà une fenêtre de prévisualisation"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: L'arabe requiert l'UTF-8, tapez ':set encoding=utf-8'"
+msgstr "W17: L'arabe nécessite l'UTF-8, tapez ':set encoding=utf-8'"
+
+msgid "E954: 24-bit colors are not supported on this environment"
+msgstr "E954: Couleurs en 24-bits non-supportées sur cet environnement."
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: Au moins %d lignes sont nécessaires"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Au moins %d colonnes sont nécessaires"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Option inconnue : %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
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: Nombre requis : &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4933,7 +4620,6 @@ msgstr ""
"\n"
"--- Codes de terminal ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4941,7 +4627,6 @@ msgstr ""
"\n"
"--- Valeur des options globales ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4949,7 +4634,6 @@ msgstr ""
"\n"
"--- Valeur des options locales ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4957,29 +4641,146 @@ msgstr ""
"\n"
"--- Options ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: ERREUR get_varp"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap' : Aucun caractère correspondant pour %s"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap' : Caractères surnuméraires après point-virgule : %s"
-#: ../os/shell.c:194
+msgid "cannot open "
+msgstr "impossible d'ouvrir "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM : Impossible d'ouvrir la fenêtre !\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Amigados version 2.04 ou ultérieure est nécessaire\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "%s version %ld est nécessaire\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Impossible d'ouvrir NIL :\n"
+
+msgid "Cannot create "
+msgstr "Impossible de créer "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim quitte avec %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "Impossible de modifier le mode de la console ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize : pas une console ?!\n"
+
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Impossible d'exécuter un shell avec l'option -f"
+
+msgid "Cannot execute "
+msgstr "Impossible d'exécuter "
+
+msgid "shell "
+msgstr "le shell "
+
+msgid " returned\n"
+msgstr " a été retourné\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE trop petit."
+
+msgid "I/O ERROR"
+msgstr "ERREUR d'E/S"
+
+msgid "Message"
+msgstr "Message"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: La sélection de l'imprimante a échoué"
+
+# DB - Contenu des c-formats : Imprimante puis Port.
+#, c-format
+msgid "to %s on %s"
+msgstr "vers %s sur %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Police d'imprimante inconnue : %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Erreur d'impression : %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Impression de '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Jeu de caractères \"%s\" invalide dans le nom de fonte \"%s\""
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: Nom de qualité \"%s\" invalide dans le nom de fonte \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Caractère '%c' invalide dans le nom de fonte \"%s\""
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "L'ouverture du display X a pris %ld ms"
+
msgid ""
"\n"
-"Cannot execute shell "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"Impossible d'exécuter le shell "
+"Vim : Réception d'une erreur X\n"
+
+msgid "Testing the X display failed"
+msgstr "Le test du display X a échoué"
+
+msgid "Opening the X display timed out"
+msgstr "L'ouverture du display X a dépassé le délai d'attente"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Impossible d'obtenir le contexte de sécurité pour "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Impossible de modifier le contexte de sécurité pour "
+
+#, c-format
+msgid "Could not set security context %s for %s"
+msgstr "Impossible d'initialiser le contexte de sécurité %s pour %s"
+
+#, c-format
+msgid "Could not get security context %s for %s. Removing it!"
+msgstr ""
+"Impossible d'obtenir le contexte de sécurité %s pour %s. Il sera supprimé !"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Impossible d'exécuter le shell sh\n"
-#: ../os/shell.c:439
msgid ""
"\n"
"shell returned "
@@ -4987,234 +4788,283 @@ msgstr ""
"\n"
"le shell a retourné "
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
-"Could not get security context for "
+"Cannot create pipes\n"
msgstr ""
"\n"
-"Impossible d'obtenir le contexte de sécurité pour "
+"Impossible de créer des tuyaux (pipes)\n"
-#: ../os_unix.c:479
msgid ""
"\n"
-"Could not set security context for "
+"Cannot fork\n"
msgstr ""
"\n"
-"Impossible de modifier le contexte de sécurité pour "
+"Impossible de forker\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Impossible d'exécuter le shell "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Commande interrompue\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP a perdu la connexion ICE"
-#: ../os_unix.c:1558 ../os_unix.c:1647
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "L'ouverture du display X a échoué"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP : prise en charge d'une requête save-yourself"
+
+msgid "XSMP opening connection"
+msgstr "XSMP : ouverture de la connexion"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP : échec de la surveillance de connexion ICE"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Le fichier \"%s\" est introuvable dans 'path'"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP : SmcOpenConnection a échoué : %s"
+
+msgid "At line"
+msgstr "À la ligne"
+
+msgid "Could not load vim32.dll!"
+msgstr "Impossible de charger vim32.dll !"
+
+msgid "VIM Error"
+msgstr "Erreur VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Impossible d'initialiser les pointeurs de fonction vers la DLL !"
+
+# DB - Les événements en question sont ceux des messages qui suivent.
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim : Événement %s intercepté\n"
+
+msgid "close"
+msgstr "de fermeture"
+
+msgid "logoff"
+msgstr "de déconnexion"
+
+msgid "shutdown"
+msgstr "d'arrêt"
+
+msgid "E371: Command not found"
+msgstr "E371: Commande introuvable"
+
+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 ""
+"VIMRUN.EXE est introuvable votre $PATH.\n"
+"Les commandes externes ne feront pas de pause une fois terminées.\n"
+"Consultez :help win32-vimrun pour plus d'informations."
+
+msgid "Vim Warning"
+msgstr "Alerte Vim"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "le shell a retourné %d"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: La liste d'emplacements courante a changé"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: Trop de %%%c dans la chaîne de format"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: %%%c inattendu dans la chaîne de format"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: ] manquant dans la chaîne de format"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: %%%c non supporté dans la chaîne de format"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: %%%c invalide dans le préfixe de la chaîne de format"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: %%%c invalide dans la chaîne de format"
-#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' ne contient aucun motif"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: Nom de répertoire vide ou absent"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Plus d'éléments"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: La fenêtre courante doit être fermée"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Le quickfix courant a changé"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d sur %d)%s%s : "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (ligne effacée)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%sliste d'erreurs %d sur %d ; %d erreurs"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: En bas de la pile quickfix"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: Au sommet de la pile quickfix"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "liste d'erreurs %d sur %d ; %d erreurs"
+msgid "No entries"
+msgstr "Aucune entrée"
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: Écriture impossible, l'option 'buftype' est activée"
+msgid "Error file"
+msgstr "Fichier d'erreurs"
-#: ../quickfix.c:2812
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Nom de fichier manquant ou motif invalide"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Impossible d'ouvrir le fichier \"%s\""
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: le tampon n'est pas chargé"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: Chaîne ou Liste attendue"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: élément invalide dans %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: ']' manquant après %s["
-#: ../regexp.c:375
+msgid "E944: Reverse range in character class"
+msgstr "E944: Classe de caractères inversée"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: Plage de classe de caractères trop large"
+
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: Pas de correspondance pour %s%%("
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: %s( ouvrante non fermée"
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: %s) fermante non ouverte"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: \\z( n'est pas autorisé ici"
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
+msgid "E67: \\z1 - \\z9 not allowed here"
msgstr "E67: \\z1 et co. ne sont pas autorisés ici"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: ']' manquant après %s%%["
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] vide"
-#: ../regexp.c:1209 ../regexp.c:1224
+msgid "E956: Cannot use pattern recursively"
+msgstr "E956: Impossible d'utiliser le motif récursivement"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: post-référence invalide"
+
msgid "E339: Pattern too long"
msgstr "E339: Motif trop long"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: Trop de \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: Trop de %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: Pas de correspondance pour \\z("
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: caractère invalide après %s@"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Trop de %s{...}s complexes"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61: %s* imbriqués"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62: %s%c imbriqués"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: utilisation invalide de \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64: %s%c ne suit aucun atome"
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: post-référence invalide"
-
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: Caractère invalide après \\z"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: Caractère invalide après %s%%[dxouU]"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: Caractère invalide après %s%%"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Erreur de syntaxe dans %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "Sous-correspondances externes :\n"
-#: ../regexp.c:7022
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (regexp NFA) %s ne peut pas être répété"
+
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5222,63 +5072,61 @@ msgstr ""
"E864: \\%#= peut être suivi uniquement de 0, 1 ou 2. Le moteur automatique "
"sera utilisé "
-#: ../regexp_nfa.c:239
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "Moteur RE avec backtracking utilisé pour le motif : "
+
msgid "E865: (NFA) Regexp end encountered prematurely"
msgstr "E865: (NFA) Fin de regexp rencontrée prématurément"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
msgstr "E866: (regexp NFA) %c au mauvais endroit"
-#: ../regexp_nfa.c:242
-#, fuzzy, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (regexp NFA) Classe de caractère invalide "
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (regexp NFA) Classe de caractère invalide : %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
msgstr "E867: (NFA) Opérateur inconnu '\\z%c'"
-#: ../regexp_nfa.c:1387
-#, fuzzy, c-format
+msgid "E951: \\% value too large"
+msgstr "E951: valeur \\% trop grande"
+
+#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) Opérateur inconnu '\\z%c'"
+msgstr "E867: (NFA) Opérateur inconnu '\\%%%c'"
+
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Erreur lors de la construction du NFA avec classe d'équivalence"
-#: ../regexp_nfa.c:1802
#, c-format
msgid "E869: (NFA) Unknown operator '\\@%c'"
msgstr "E869: (NFA) Opérateur inconnu '\\@%c'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
msgstr "E870: (regexp NFA) Erreur à la lecture des limites de répétition"
-#. 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: (regexp NFA) Un multi ne peut pas suivre un multi !"
+msgid "E871: (NFA regexp) Can't have a multi follow a multi"
+msgstr "E871: (regexp NFA) Un multi ne peut pas suivre un multi"
-#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
msgstr "E872: (regexp NFA) Trop de '('"
-#: ../regexp_nfa.c:2042
-#, fuzzy
msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E872: (regexp NFA) Trop de '('"
+msgstr "E879: (regexp NFA) Trop de \\z("
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
msgstr "E873: (NFA regexp) erreur de terminaison"
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
+msgid "Could not open temporary log file for writing, displaying on stderr... "
+msgstr ""
+"Impossible d'ouvrir le fichier de log temporaire en écriture, affichage sur "
+"stderr... "
+
+msgid "E874: (NFA) Could not pop the stack!"
msgstr "E874: (NFA) Impossible de dépiler !"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
@@ -5286,178 +5134,124 @@ msgstr ""
"E875: (regexp NFA) (lors de la conversion de postfix à NFA), il reste trop "
"d'états sur la pile"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
msgstr "E876: (regexp NFA) Pas assez de mémoire pour stocker le NFA"
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
msgstr ""
-"Impossible d'ouvrir le fichier de log temporaire en écriture, affichage sur "
-"stderr ... "
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) IMPOSSIBLE D'OUVRIR %s !"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "Impossible d'ouvrir le fichier de log en écriture"
+"E878: (NFA) Impossible d'allouer la mémoire pour parcourir les branches !"
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " VREMPLACEMENT"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " REMPLACEMENT"
# DB - todo
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " REVERSE"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " INSERTION"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (insertion)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (remplacement)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (vremplacement)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " hébreu"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " arabe"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (langue)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (collage)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " VISUEL"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " VISUEL LIGNE"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " VISUEL BLOC"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " SÉLECTION"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " SÉLECTION LIGNE"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " SÉLECTION BLOC"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "Enregistrement"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Chaîne de recherche invalide : %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: la recherche a atteint le HAUT sans trouver : %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: la recherche a atteint le BAS sans trouver : %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: '?' ou '/' attendu après ';'"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (inclut des correspondances listées précédemment)"
-#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- Fichiers inclus "
-#: ../search.c:4106
msgid "not found "
msgstr "introuvables "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "dans le chemin ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Déjà listé)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " INTROUVABLE"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "Examen des fichiers inclus : %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "Recherche du fichier inclus %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: La correspondance est sur la ligne courante"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Tous les fichiers inclus ont été trouvés"
-#: ../search.c:4519
msgid "No included files"
msgstr "Aucun fichier inclus"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: Impossible de trouver la définition"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: Impossible de trouver le motif"
-#: ../search.c:4668
msgid "Substitute "
msgstr "Substitue "
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5468,97 +5262,127 @@ msgstr ""
"# Dernier motif de recherche %s :\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Erreur de format du fichier orthographique"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: La vérification orthographique n'est pas activée"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr "Alerte : Liste de mots \"%s_%s.spl\" ou \"%s_ascii.spl\" introuvable"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr "Alerte : Liste de mots \"%s.%s.spl\" ou \"%s.ascii.spl\" introuvable"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: L'autocommande SpellFileMissing a effacé le tampon"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Alerte : région %s non supportée"
+
+msgid "Sorry, no suggestions"
+msgstr "Désolé, aucune suggestion"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Désolé, seulement %ld suggestions"
+
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Remplacer \"%.*s\" par :"
+
+# DB - todo : l'intérêt de traduire ce message m'échappe.
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Pas de suggestion orthographique précédente"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Introuvable : %s"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: Fichier orthographique tronqué"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "Texte en trop dans %s ligne %d : %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "Nom d'affixe trop long dans %s ligne %d : %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr "E761: Erreur de format dans le fichier d'affixe FOL, LOW et UPP"
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
msgstr "E762: Un caractère dans FOL, LOW ou UPP est hors-limites"
-#: ../spell.c:958
msgid "Compressing word tree..."
msgstr "Compression de l'arbre des mots"
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: La vérification orthographique n'est pas activée"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr "Alerte : Liste de mots \"%s.%s.spl\" ou \"%s.ascii.spl\" introuvable"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "Lecture du fichier orthographique \"%s\""
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Le fichier ne ressemble pas à un fichier orthographique"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: Fichier orthographique obsolète, sa mise à jour est nécessaire"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Le fichier est prévu pour une version de Vim plus récente"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Section non supportée dans le fichier orthographique"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Alerte : région %s non supportée"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: %s ne semble pas être un fichier .sug"
-#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Fichier de suggestions obsolète, mise à jour nécessaire : %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Fichier .sug prévu pour une version de Vim plus récente : %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Le fichier .sug ne correspond pas au fichier .spl : %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: Erreur lors de la lecture de fichier de suggestions : %s"
+
+#, c-format
+msgid "Reading affix file %s..."
msgstr "Lecture du fichier d'affixes %s..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "Échec de conversion du mot dans %s ligne %d : %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "La conversion dans %s non supportée : de %s vers %s"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "La conversion dans %s non supportée"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "Valeur de FLAG invalide dans %s ligne %d : %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "FLAG trouvé après des drapeaux dans %s ligne %d : %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5567,7 +5391,6 @@ msgstr ""
"Définir COMPOUNDFORBIDFLAG après des PFX peut donner des résultats erronés "
"dans %s ligne %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5576,45 +5399,37 @@ msgstr ""
"Définir COMPOUNDPERMITFLAG après des PFX peut donner des résultats erronés "
"dans %s ligne %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "Valeur de COMPOUNDRULES erronée dans %s ligne %d : %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "Valeur de COMPOUNDWORDMAX erronée dans %s ligne %d : %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "Valeur de COMPOUNDMIN erronée dans %s ligne %d : %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "Valeur de COMPOUNDSYLMAX erronée dans %s ligne %d : %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "Valeur de CHECKCOMPOUNDPATTERN erronée dans %s ligne %d : %s"
# DB - TODO
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
"Drapeaux de composition différents dans un bloc d'affixes continu dans %s "
"ligne %d : %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "Affixe dupliqué dans %s ligne %d : %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5623,339 +5438,257 @@ msgstr ""
"Affixe aussi utilisée pour BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
"NOSUGGEST dans %s ligne %d : %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "Y ou N attendu dans %s ligne %d : %s"
# DB - todo (regexp impossible à compiler...)
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "Condition non valide dans %s ligne %d : %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "Nombre de REP(SAL) attendu dans %s ligne %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "Nombre de MAP attendu dans %s ligne %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "Caractère dupliqué dans MAP dans %s ligne %d"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "Élément non reconnu ou dupliqué dans %s ligne %d : %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "Ligne FOL/LOW/UPP manquante dans %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "Utilisation de COMPOUNDSYLMAX sans SYLLABLE"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "Trop de préfixes reportés (PFXPOSTPONE)"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Trop de drapeaux de composition"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "Trop de préfixes reportés et/ou de drapeaux de composition"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Ligne SOFO%s manquante dans %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "Lignes SAL et lignes SOFO présentes dans %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "Le drapeau n'est pas un nombre dans %s ligne %d : %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "Drapeau non autorisé dans %s ligne %d : %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "La valeur de %s est différente de celle d'un autre fichier .aff"
-#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
+msgid "Reading dictionary file %s..."
msgstr "Lecture du fichier orthographique %s..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Nombre de mots non indiqué dans %s"
-#: ../spell.c:5669
#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "ligne %6d, mot %6d - %s"
+msgid "line %6d, word %6ld - %s"
+msgstr "ligne %6d, mot %6ld - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "Mot dupliqué dans %s ligne %d : %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "Premier mot dupliqué dans %s ligne %d : %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d mot(s) dupliqué(s) dans %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "%d mot(s) ignoré(s) avec des caractères non-ASCII dans %s"
-#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
+msgid "Reading word file %s..."
msgstr "Lecture de la liste de mots %s..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "Ligne /encoding= en double ignorée dans %s ligne %d : %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr "Ligne /encoding= après des mots ignorée dans %s ligne %d : %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "Ligne /regions= en double ignorée dans %s ligne %d : %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
msgstr "Trop de régions dans %s ligne %d : %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "Ligne / ignorée dans %s ligne %d : %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "Numéro de région invalide dans %s ligne %d : %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "Drapeaux non reconnus dans %s ligne %d : %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "%d mot(s) ignoré(s) avec des caractères non-ASCII"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: mémoire insuffisante, liste de mots peut-être incomplète"
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "%d noeuds compressés sur %d ; %d (%d%%) restants "
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "Relecture du fichier orthographique"
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
msgid "Performing soundfolding..."
msgstr "Analyse phonétique en cours..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Nombre de mots après l'analyse phonétique : %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "Nombre de mots après l'analyse phonétique : %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Nombre total de mots : %d"
-#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
+msgid "Writing suggestion file %s..."
msgstr "Écriture du fichier de suggestions %s..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "Estimation de mémoire consommée : %d octets"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
msgstr "E751: Le nom du fichier ne doit pas contenir de nom de région"
-#: ../spell.c:7822
-msgid "E754: Only up to 8 regions supported"
-msgstr "E754: 8 régions au maximum sont supportées"
+#, c-format
+msgid "E754: Only up to %ld regions supported"
+msgstr "E754: %ld régions au maximum supportées"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Région invalide dans %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "Alerte : la composition et NOBREAK sont tous les deux spécifiés"
-#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
+msgid "Writing spell file %s..."
msgstr "Écriture du fichier orthographique %s..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Terminé !"
# DB - todo : perfectible.
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' n'a pas %<PRId64> entrées"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' n'a pas %ld entrées"
-#: ../spell.c:8074
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "Mot retiré de %s"
+msgstr "Mot '%.*s' retiré de %s"
-#: ../spell.c:8117
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "Mot ajouté dans %s"
+msgstr "Mot '%.*s' ajouté dans %s"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr ""
"E763: Les caractères de mots diffèrent entre les fichiers orthographiques"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Désolé, aucune suggestion"
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: caractère dupliqué dans l'entrée MAP"
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Désolé, seulement %<PRId64> suggestions"
+msgid "No Syntax items defined for this buffer"
+msgstr "Aucun élément de syntaxe défini pour ce tampon"
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Remplacer \"%.*s\" par :"
+msgid "'redrawtime' exceeded, syntax highlighting disabled"
+msgstr "'redrawtime' écoulé, surbrillance de syntaxe désactivée"
-# DB - todo : l'intérêt de traduire ce message m'échappe.
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Pas de suggestion orthographique précédente"
+msgid "syntax conceal on"
+msgstr "\"syntax conceal\" activée"
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Introuvable : %s"
+msgid "syntax conceal off"
+msgstr "\"syntax conceal\" désactivée"
-#: ../spell.c:9276
#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: %s ne semble pas être un fichier .sug"
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Argument invalide : %s"
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Fichier de suggestions obsolète, mise à jour nécessaire : %s"
+msgid "syntax case ignore"
+msgstr "syntaxe ignore la casse"
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Fichier .sug prévu pour une version de Vim plus récente : %s"
+msgid "syntax case match"
+msgstr "syntaxe respecte la casse"
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Le fichier .sug ne correspond pas au fichier .spl : %s"
+msgid "syntax spell toplevel"
+msgstr "contrôle orthographique dans le texte sans groupe syntaxique"
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: Erreur lors de la lecture de fichier de suggestions : %s"
+msgid "syntax spell notoplevel"
+msgstr "pas de contrôle orthographique dans le texte sans groupe syntaxique"
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: caractères dupliqué dans l'entrée MAP"
+msgid "syntax spell default"
+msgstr ""
+"contrôle orthographique dans le texte sans groupe syntaxique, sauf si @Spell/"
+"@NoSpell"
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "Aucun élément de syntaxe défini pour ce tampon"
+msgid "syntax iskeyword "
+msgstr "syntaxe iskeyword "
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: Argument invalide : %s"
+msgid "syntax iskeyword not set"
+msgstr "iskeyword n'est pas activé"
-#: ../syntax.c:3299
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Aucune grappe de syntaxe %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "synchronisation sur les commentaires de type C"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "Aucune synchronisation"
# DB - Les deux messages qui suivent vont ensemble.
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "La synchronisation débute "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " lignes avant la ligne du haut"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5963,7 +5696,6 @@ msgstr ""
"\n"
"--- Éléments de synchronisation syntaxique ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5971,7 +5703,6 @@ msgstr ""
"\n"
"synchronisation sur éléments"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5979,275 +5710,218 @@ msgstr ""
"\n"
"--- Éléments de syntaxe ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Aucune grappe de syntaxe %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimum "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maximum "
# DB - todo
-#: ../syntax.c:3513
msgid "; match "
msgstr "; correspond avec "
# DB - todo
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " coupures de ligne"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: L'argument « contains » n'est pas accepté ici"
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: valeur de cchar invalide"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: L'argument « group[t]here » n'est pas accepté ici"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: Aucun élément de type région trouvé pour %s"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Nom de fichier requis"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: Trop d'inclusions de syntaxe"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ']' manquant : %s"
-#: ../syntax.c:4531
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: Caractère surnuméraire après ']': %s]%s"
+
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: '=' manquant : %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Pas assez d'arguments : syntax region %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: Trop de grappes de syntaxe"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: Aucune grappe spécifiée"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Délimiteur de motif introuvable : %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: caractères en trop après le motif : %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr ""
"E403: synchro syntax : motif de continuation de ligne présent deux fois"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Arguments invalides : %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: '=' manquant : %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: Argument vide : %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s n'est pas autorisé ici"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s doit être le premier élément d'une liste « contains »"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: Nom de groupe inconnu : %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Sous-commande de :syntax invalide : %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
+" TOTAL NOMBRE MATCH PLUS LENT MOYEN NOM MOTIF"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: boucle récursive lors du chargement de syncolor.vim"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: groupe de surbrillance introuvable : %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Trop peu d'arguments : \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: Trop d'arguments : \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr "E414: le groupe a déjà des attributs, lien de surbrillance ignoré"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: signe égal inattendu : %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: '=' manquant : %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: argument manquant : %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Valeur invalide : %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: Couleur de premier plan inconnue"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: Couleur d'arrière-plan inconnue"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: Nom ou numéro de couleur non reconnu : %s"
-#: ../syntax.c:6714
#, c-format
msgid "E422: terminal code too long: %s"
msgstr "E422: le code de terminal est trop long : %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Argument invalide : %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr ""
"E424: Trop d'attributs de surbrillance différents en cours d'utilisation"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: Caractère non-imprimable dans un nom de groupe"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: Caractère invalide dans un nom de groupe"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: Trop de groupes de surbrillance et de syntaxe"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: En bas de la pile de marqueurs"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: Au sommet de la pile de marqueurs"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: Impossible d'aller avant le premier marqueur correspondant"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: Marqueur introuvable : %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # pri type marqueur"
-#: ../tag.c:531
msgid "file\n"
msgstr "fichier\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: Il n'y a qu'un marqueur correspondant"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: Impossible d'aller au-delà du dernier marqueur correspondant"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "Le fichier \"%s\" n'existe pas"
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "marqueur %d sur %d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " ou plus"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " Utilisation d'un marqueur avec une casse différente !"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Le fichier \"%s\" n'existe pas"
-#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6255,80 +5929,65 @@ msgstr ""
"\n"
" # VERS marqueur DE ligne dans le fichier/texte"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "Examen du fichier de marqueurs %s"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Chemin de fichiers de marqueurs tronqué pour %s\n"
+
msgid "Ignoring long line in tags file"
msgstr "Ignore longue ligne dans le fichier de marqueurs"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Erreur de format dans le fichier de marqueurs \"%s\""
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Avant l'octet %<PRId64>"
+msgid "Before byte %ld"
+msgstr "Avant l'octet %ld"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Le fichier de marqueurs %s n'est pas ordonné"
-#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: Aucun fichier de marqueurs"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: Le motif de marqueur est introuvable"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: Marqueur introuvable, tentative pour deviner !"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "Nom de champ dupliqué : %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' inconnu. Les terminaux intégrés sont :"
-#: ../term.c:1463
msgid "defaulting to '"
msgstr "utilisation par défaut de '"
-#: ../term.c:1731
msgid "E557: Cannot open termcap file"
msgstr "E557: Impossible d'ouvrir le fichier termcap"
-#: ../term.c:1735
msgid "E558: Terminal entry not found in terminfo"
msgstr "E558: La description du terminal est introuvable dans terminfo"
-#: ../term.c:1737
msgid "E559: Terminal entry not found in termcap"
msgstr "E559: La description du terminal est introuvable dans termcap"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: Aucune entrée \"%s\" dans termcap"
# DB - todo : Comment améliorer ?
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: capacité de terminal \"cm\" requise"
-#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6336,174 +5995,391 @@ msgstr ""
"\n"
"--- Touches du terminal ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "Impossible d'ouvrir $VIMRUNTIME/rgb.txt"
+
+#, c-format
+msgid "Kill job in \"%s\"?"
+msgstr "Terminer la tâche d'exécution dans \"%s\"?"
+
+msgid "Terminal"
+msgstr "Terminal"
+
+msgid "Terminal-finished"
+msgstr "Terminal-fini"
+
+msgid "active"
+msgstr "actif"
+
+msgid "running"
+msgstr "en cours"
+
+msgid "finished"
+msgstr "fini"
+
+#, c-format
+msgid "E953: File exists: %s"
+msgstr "E953: Le fichier existe déjà : %s"
+
+msgid "E955: Not a terminal buffer"
+msgstr "E955: Ce n'est pas un buffer de terminal"
+
+msgid "new shell started\n"
+msgstr "nouveau shell démarré\n"
+
msgid "Vim: Error reading input, exiting...\n"
msgstr "Vim : Erreur lors de la lecture de l'entrée, sortie...\n"
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
+# DB - Message de débogage.
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "CUT_BUFFER0 utilisé plutôt qu'une sélection vide"
+
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Le nombre de lignes a été changé inopinément"
+msgstr "E881: Le nombre de lignes a été changé inopinément"
+
+# DB - Question O/N.
+msgid "No undo possible; continue anyway"
+msgstr "Annulation impossible ; continuer"
-#: ../undo.c:627
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: Impossible d'ouvrir le fichier d'annulations en écriture : %s"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: Fichier d'annulations corrompu (%s) : %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr ""
"Impossible d'écrire le fichier d'annulations dans n'importe quel répertoire "
"de 'undodir'"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "Le fichier d'annulations ne sera pas écrasé, impossible de lire : %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "Fichier ne sera pas écrasé, ce n'est pas un fichier d'annulations : %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Le fichier d'annulations n'est pas écrit, rien à annuler"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "Écriture du fichier d'annulations : %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: Erreur d'écriture dans le fichier d'annulations : %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "Le fichier d'annulations n'est pas lu, propriétaire différent : %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "Lecture du fichier d'annulations : %s..."
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: Impossible d'ouvrir le fichier d'annulations en lecture : %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: Ce n'est pas un fichier d'annulations : %s"
-#: ../undo.c:1313
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Fichier non-chiffré a un fichier d'annulations chiffré : %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Déchiffrage du fichier d'annulation a échoué : %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Le fichier d'annulations est chiffré : %s"
+
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: Fichier d'annulations incompatible : %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr ""
"Le contenu du fichier a changé, impossible d'utiliser les informations "
"d'annulation"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "Fin de lecture du fichier d'annulations %s"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Déjà à la modification la plus ancienne"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Déjà à la modification la plus récente"
-#: ../undo.c:1806
#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Annulation n° %<PRId64> introuvable"
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Annulation n° %ld introuvable"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo : numéros de ligne erronés"
-#: ../undo.c:2183
msgid "more line"
msgstr "ligne en plus"
-#: ../undo.c:2185
msgid "more lines"
msgstr "lignes en plus"
-#: ../undo.c:2187
msgid "line less"
msgstr "ligne en moins"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "lignes en moins"
-#: ../undo.c:2193
msgid "change"
msgstr "modification"
-#: ../undo.c:2195
msgid "changes"
msgstr "modifications"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s ; %s #%<PRId64> ; %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s ; %s #%ld ; %s"
-#: ../undo.c:2228
msgid "before"
msgstr "avant"
-#: ../undo.c:2228
msgid "after"
msgstr "après"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "Rien à annuler"
# DB - Les deux premières colonnes sont alignées à droite.
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "numéro modif. instant enregistré"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "il y a %<PRId64> secondes"
+msgid "%ld second ago"
+msgid_plural "%ld seconds ago"
+msgstr[0] "il y a %ld seconde"
+msgstr[1] "il y a %ld secondes"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: undojoin n'est pas autorisé après une annulation"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: la liste d'annulation est corrompue"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: ligne d'annulation manquante"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: La fonction %s existe déjà (ajoutez ! pour la remplacer)"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Une entrée du Dictionnaire porte déjà ce nom"
+
+msgid "E718: Funcref required"
+msgstr "E718: Référence de fonction (Funcref) requise"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Fonction inconnue : %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argument invalide : %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Nom d'argument dupliqué : %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Trop d'arguments pour la fonction %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Arguments invalides pour la fonction %s"
+
+# AB - Vérifier dans la littérature technique s'il n'existe pas une meilleure
+# traduction pour "function call depth".
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr ""
+"E132: La profondeur d'appel de fonction est supérieure à 'maxfuncdepth'"
+
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "calling %s"
+msgstr "appel de %s"
+
+# AB - Vérifier.
+#, c-format
+msgid "%s aborted"
+msgstr "%s annulée"
+
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s a retourné #%ld"
+
+# AB - Ce texte fait partie d'un message de débogage.
+#, c-format
+msgid "%s returning %s"
+msgstr "%s a retourné \"%s\""
+
+msgid "E699: Too many arguments"
+msgstr "E699: Trop d'arguments"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Fonction inconnue : %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: La fonction a été effacée: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: La fonction %s n'a pas reçu assez d'arguments"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> utilisé en dehors d'un script : %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Appel d'une fonction « dict » sans Dictionnaire : %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Nom de fonction requis"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr ""
+"E128: Le nom de la fonction doit commencer par une majuscule ou \"s:\": %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr ""
+"E884: Le nom de la fonction ne peut pas contenir le caractère deux-points : "
+"%s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Fonction non définie : %s"
+
+# AB - La version française est plus consistante que la version anglaise.
+# AB - Je suis partagé entre la concision d'une traduction assez littérale et
+# la lourdeur d'une traduction plus correcte.
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: Il manque '(' après %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Impossible d'utiliser g: ici"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr ""
+"E932: une fonction fermeture ne devrait pas être au niveau principal : %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: Il manque :endfunction"
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: Texte trouvé après :endfunction: %s"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Le nom de fonction entre en conflit avec la variable : %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Impossible de redéfinir fonction %s : déjà utilisée"
+
+# DB - Le contenu du "c-format" est le nom de la fonction.
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Le nom de la fonction %s ne correspond pas le nom du script"
+
+# AB - Il est difficile de créer une version française qui fasse moins de 80
+# caractères de long, nom de la fonction compris : "It is in use" est une
+# expression très dense. Traductions possibles : "elle est utilisée",
+# "elle s'exécute" ou "elle est occupée".
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Impossible d'effacer %s : cette fonction est utilisée"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return en dehors d'une fonction"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Parenthèses manquantes : %s"
+
+#, c-format
+msgid "%s (%s, compiled %s)"
+msgstr "%s (%s, compilé %s)"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Version graphique MS-Windows 64 bits"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Version graphique MS-Windows 32 bits"
+
+msgid " with OLE support"
+msgstr " supportant l'OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Version console MS-Windows 64 bits"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Version console MS-Windows 32 bits"
+
+msgid ""
+"\n"
+"macOS version"
+msgstr ""
+"\n"
+"Version macOS"
+
+msgid ""
+"\n"
+"macOS version w/o darwin feat."
+msgstr ""
+"\n"
+"Version macOS sans fonctionalités darwin"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"Version OpenVMS"
+
msgid ""
"\n"
"Included patches: "
@@ -6511,7 +6387,6 @@ msgstr ""
"\n"
"Rustines incluses : "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6519,11 +6394,9 @@ msgstr ""
"\n"
"Rustines extra : "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Modifié par "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6531,11 +6404,9 @@ msgstr ""
"\n"
"Compilé "
-#: ../version.c:649
msgid "by "
msgstr "par "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6543,1866 +6414,992 @@ msgstr ""
"\n"
"Énorme version "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Grosse version "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Version normale "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Petite version "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Version minuscule "
+
msgid "without GUI."
msgstr "sans interface graphique."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "avec interface graphique GTK3."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "avec interface graphique GTK2-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "avec interface graphique GTK2."
+
+msgid "with X11-Motif GUI."
+msgstr "avec interface graphique X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "avec interface graphique X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "avec interface graphique X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "avec interface graphique Photon."
+
+msgid "with GUI."
+msgstr "avec une interface graphique."
+
+msgid "with Carbon GUI."
+msgstr "avec interface graphique Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "avec interface graphique Cocoa."
+
msgid " Features included (+) or not (-):\n"
msgstr " Fonctionnalités incluses (+) ou non (-) :\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " fichier vimrc système : \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " fichier vimrc utilisateur : \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " 2me fichier vimrc utilisateur : \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " 3me fichier vimrc utilisateur : \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " fichier exrc utilisateur : \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " 2me fichier exrc utilisateur : \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " fichier gvimrc système : \""
+
+msgid " user gvimrc file: \""
+msgstr " fichier gvimrc utilisateur : \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "2me fichier gvimrc utilisateur : \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "3me fichier gvimrc utilisateur : \""
+
+msgid " defaults file: \""
+msgstr " fichier de valeurs par défaut : \""
+
+msgid " system menu file: \""
+msgstr " fichier menu système : \""
+
msgid " fall-back for $VIM: \""
msgstr " $VIM par défaut : \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " $VIMRUNTIME par défaut : \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "Compilation : "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "Compilateur : "
+
msgid "Linking: "
msgstr "Édition de liens : "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr " VERSION DE DÉBOGAGE"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi Amélioré"
-#: ../version.c:769
msgid "version "
msgstr "version "
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "par Bram Moolenaar et al."
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Vim est un logiciel libre"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "Aidez les enfants pauvres d'Ouganda !"
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "tapez :help iccf<Entrée> pour plus d'informations "
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "tapez :q<Entrée> pour sortir du programme "
-#: ../version.c:780
msgid "type :help<Enter> or <F1> for on-line help"
msgstr "tapez :help<Entrée> ou <F1> pour accéder à l'aide en ligne "
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "tapez :help version7<Entrée> pour lire les notes de mise à jour"
+msgid "type :help version8<Enter> for version info"
+msgstr "tapez :help version8<Entrée> pour lire les notes de mise à jour"
# DB - Pour les trois messages qui suivent :
# :set cp
# :intro
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "Compatibilité avec Vi activée"
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr "tapez :set nocp<Entrée> pour la désactiver"
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr "tapez :help cp-default<Entrée> pour plus d'info"
-#: ../version.c:827
+msgid "menu Help->Orphans for information "
+msgstr "menu Aide->Orphelins pour plus d'info"
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Les modes sont désactivés, le texte saisi est inséré"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "menu Édition->Réglages Globaux->Insertion Permanente"
+
+# DB - todo
+msgid " for two modes "
+msgstr " pour les modes "
+
+# DB - todo
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "menu Édition->Réglages Globaux->Compatibilité Vi"
+
+# DB - todo
+msgid " for Vim defaults "
+msgstr " pour déf. de Vim "
+
msgid "Sponsor Vim development!"
msgstr "Sponsorisez le développement de Vim !"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Devenez un utilisateur de Vim enregistré !"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "tapez :help sponsor<Entrée> pour plus d'informations "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "tapez :help register<Entrée> pour plus d'informations "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "menu Aide->Sponsor/Enregistrement pour plus d'info"
-#: ../window.c:119
msgid "Already only one window"
msgstr "Il n'y a déjà plus qu'une fenêtre"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Il n'y a pas de fenêtre de prévisualisation"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: Impossible de partager topleft et botright en même temps"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: Rotation impossible quand une autre fenêtre est partagée"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: Impossible de fermer la dernière fenêtre"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: Impossible de fermer la fenêtre des autocommandes"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr ""
"E814: Impossible de fermer la fenêtre, seule la fenêtre des autocommandes "
"resterait"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: Les modifications de l'autre fenêtre n'ont pas été enregistrées"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: Aucun nom de fichier sous le curseur"
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() appelée avec un mot de passe vide"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: petit/gros boutisme incorrect dans blowfish"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: le test de sha256 a échoué"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: le test de blowfish a échoué"
-
-#~ msgid "Patch file"
-#~ msgstr "Fichier rustine"
-
-# AB - Textes des boutons de la boîte de dialogue affichée par inputdialog().
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&Ok\n"
-#~ "&Annuler"
-
-# AB - À mon avis, la version anglaise est erronée.
-# DB : Vérifier
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Pas de connexion au serveur X"
-
-# AB - La version française est meilleure que la version anglaise.
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: L'envoi au serveur %s à échoué"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Impossible de lire la réponse du serveur"
-
-# AB - La version française est meilleure que la version anglaise.
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: La réponse n'a pas pu être envoyée au client"
-
-# AB - Ceci est un titre de boîte de dialogue. Vérifier que la version
-# française est correcte pour les trois références ; j'ai un doute quant
-# à la troisième.
-#~ msgid "Save As"
-#~ msgstr "Enregistrer sous - Vim"
-
-# AB - Ceci est un titre de boîte de dialogue.
-#~ msgid "Edit File"
-#~ msgstr "Ouvrir un fichier - Vim"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (INTROUVABLE)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Sourcer un script - Vim"
-
-#~ msgid "unknown"
-#~ msgstr "inconnu"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "Ouvrir un fichier dans une nouvelle fenêtre - Vim"
-
-#~ msgid "Append File"
-#~ msgstr "Ajouter fichier"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Position de la fenêtre : X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "Enregistrer la redirection"
-
-#~ msgid "Save View"
-#~ msgstr "Enregistrer la vue - Vim"
-
-#~ msgid "Save Session"
-#~ msgstr "Enregistrer la session - Vim"
-
-#~ msgid "Save Setup"
-#~ msgstr "Enregistrer les réglages - Vim"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< n'est pas disponible sans la fonctionnalité +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Pas de digraphes dans cette version"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "est un périphérique (désactivé par l'option 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "Lecture de stdin..."
-
-#~ msgid "[crypted]"
-#~ msgstr "[chiffré]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Le fichier est chiffré avec une méthode inconnue"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans interdit l'écriture des tampons non modifiés"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Netbeans interdit l'écriture partielle de ses tampons"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "écriture vers un périphérique désactivé par l'option 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr ""
-#~ "E460: Les ressources partagées seraient perdues (ajoutez ! pour passer "
-#~ "outre)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr ""
-#~ "E851: Échec lors de la création d'un nouveau processus pour l'interface "
-#~ "graphique"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr ""
-#~ "E852: Le processus fils n'a pas réussi à démarrer l'interface graphique"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Impossible de démarrer l'interface graphique"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Impossible de lire \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr ""
-#~ "E665: Impossible de démarrer l'IHM graphique, aucune police valide trouvée"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' est invalide"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Valeur de 'imactivatekey' invalide"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Impossible d'allouer la couleur %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Aucune correspondance sous le curseur, recherche de la suivante"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<impossible d'ouvrir> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile : impossible d'obtenir la police %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr ""
-#~ "E614: vim_SelFile : impossible de revenir dans le répertoire courant"
-
-#~ msgid "Pathname:"
-#~ msgstr "Chemin :"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile : impossible d'obtenir le répertoire courant"
-
-#~ msgid "OK"
-#~ msgstr "Ok"
-
-#~ msgid "Cancel"
-#~ msgstr "Annuler"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Widget scrollbar : Impossible d'obtenir la géométrie du pixmap 'thumb'"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Impossible de créer un BalloonEval avec message ET callback"
-
-# todo '_' is for hotkey, i guess?
-#~ msgid "Input _Methods"
-#~ msgstr "_Méthodes de saisie"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "Remplacer - Vim"
-
-#~ msgid "VIM - Search..."
-#~ msgstr "Rechercher - Vim"
-
-#~ msgid "Find what:"
-#~ msgstr "Rechercher :"
-
-#~ msgid "Replace with:"
-#~ msgstr "Remplacer par :"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Mots entiers seulement"
-
-#~ msgid "Match case"
-#~ msgstr "Respecter la casse"
-
-#~ msgid "Direction"
-#~ msgstr "Direction"
-
-#~ msgid "Up"
-#~ msgstr "Haut"
-
-#~ msgid "Down"
-#~ msgstr "Bas"
-
-#~ msgid "Find Next"
-#~ msgstr "Suivant"
-
-#~ msgid "Replace"
-#~ msgstr "Remplacer"
-
-#~ msgid "Replace All"
-#~ msgstr "Remplacer tout"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr ""
-#~ "Vim : Une requête \"die\" a été reçue par le gestionnaire de session\n"
-
-#~ msgid "Close tab"
-#~ msgstr "Fermer l'onglet"
-
-#~ msgid "New tab"
-#~ msgstr "Nouvel onglet"
-
-# DB - todo : un peu long. Cet entrée de menu permet d'ouvrir un fichier
-# dans un nouvel onglet via le sélecteur de fichiers graphique.
-#~ msgid "Open Tab..."
-#~ msgstr "Ouvrir dans un onglet..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim : Fenêtre principale détruite inopinément\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&Filtrer"
-
-#~ msgid "&Cancel"
-#~ msgstr "&Annuler"
-
-#~ msgid "Directories"
-#~ msgstr "Répertoires"
-
-#~ msgid "Filter"
-#~ msgstr "Filtre"
-
-#~ msgid "&Help"
-#~ msgstr "&Aide"
-
-#~ msgid "Files"
-#~ msgstr "Fichiers"
-
-#~ msgid "&OK"
-#~ msgstr "&Ok"
-
-#~ msgid "Selection"
-#~ msgstr "Sélection"
-
-#~ msgid "Find &Next"
-#~ msgstr "Suiva&nt"
-
-#~ msgid "&Replace"
-#~ msgstr "&Remplacer"
-
-#~ msgid "Replace &All"
-#~ msgstr "Rempl&acer tout"
-
-#~ msgid "&Undo"
-#~ msgstr "Ann&uler"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Titre de fenêtre \"%s\" introuvable"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Argument non supporté : \"-%s\" ; Utilisez la version OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Impossible d'ouvrir une fenêtre dans une application MDI"
-
-#~ msgid "Open tab..."
-#~ msgstr "Ouvrir dans un onglet..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Chercher une chaîne (utilisez '\\\\' pour chercher un '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Chercher et remplacer (utilisez '\\\\' pour trouver un '\\')"
-
-# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un
-# paramétrage bidon afin de sélectionner un répertoire plutôt qu'un
-# fichier.
-#~ msgid "Not Used"
-#~ msgstr "Non utilisé"
-
-# DB - Traduction non indispensable puisque le code indique qu'il s'agit d'un
-# paramétrage bidon afin de sélectionner un répertoire plutôt qu'un
-# fichier.
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Répertoire\t*.rien\n"
-
-# DB - todo : perfectible.
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Erreur d'allocation de couleurs, couleurs possiblement "
-#~ "incorrectes"
-
-# DB - todo : La VF est-elle compréhensible ?
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr ""
-#~ "E250: Des polices manquent dans %s pour les jeux de caractères suivants :"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Nom du jeu de polices : %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "La police '%s' n'a pas une largeur fixe"
-
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Nom du jeu de polices : %s\n"
-
-#~ msgid "Font0: %s\n"
-#~ msgstr "Font0: %s\n"
-
-#~ msgid "Font1: %s\n"
-#~ msgstr "Font1: %s\n"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "La largeur de Font%<PRId64> n'est pas le double de celle de Font0\n"
-
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "Largeur de Font0 : %<PRId64>\n"
-
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Largeur de Font1 : %<PRId64>\n"
-#~ "\n"
-
-# DB - todo : Pas certain de mon coup, ici...
-#~ msgid "Invalid font specification"
-#~ msgstr "La spécification de la police est invalide"
-
-#~ msgid "&Dismiss"
-#~ msgstr "Aban&donner"
-
-# DB - todo : Pas certain de mon coup, ici...
-#~ msgid "no specific match"
-#~ msgstr "aucune correspondance particulière"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Choisir une police - Vim"
-
-#~ msgid "Name:"
-#~ msgstr "Nom :"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Afficher la taille en Points"
-
-#~ msgid "Encoding:"
-#~ msgstr "Encodage :"
-
-#~ msgid "Font:"
-#~ msgstr "Police :"
-
-#~ msgid "Style:"
-#~ msgstr "Style :"
-
-#~ msgid "Size:"
-#~ msgstr "Taille :"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ERREUR dans l'automate Hangul"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: Erreur stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: impossible d'ouvrir la base de données cscope %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr ""
-#~ "E626: impossible d'obtenir des informations sur la base de données cscope"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "La bibliothèque Lua n'a pas pu être chargée."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "impossible d'enregistrer les informations d'annulation"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: Désolé, cette commande est désactivée : les bibliothèques MzScheme "
-#~ "n'ont pas pu être chargées."
-
-#~ msgid "invalid expression"
-#~ msgstr "expression invalide"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "expressions désactivée lors de la compilation"
-
-#~ msgid "hidden option"
-#~ msgstr "option cachée"
-
-#~ msgid "unknown option"
-#~ msgstr "option inconnue"
-
-#~ msgid "window index is out of range"
-#~ msgstr "numéro de fenêtre hors limites"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "impossible d'ouvrir le tampon"
-
-#~ msgid "cannot delete line"
-#~ msgstr "impossible d'effacer la ligne"
-
-#~ msgid "cannot replace line"
-#~ msgstr "impossible de remplacer la ligne"
-
-#~ msgid "cannot insert line"
-#~ msgstr "impossible d'insérer la ligne"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "une chaîne ne peut pas contenir de saut-de-ligne"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "erreur lors de la conversion d'une valeur de Scheme à Vim"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Erreur Vim : ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Erreur Vim"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "tampon invalide"
-
-#~ msgid "window is invalid"
-#~ msgstr "fenêtre invalide"
-
-#~ msgid "linenr out of range"
-#~ msgstr "numéro de ligne hors limites"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "non autorisé dans le bac à sable"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: Vim ne peut pas exécuter :python après avoir utilisé :py3"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: Désolé, commande désactivée : la bibliothèque Python n'a pas pu "
-#~ "être chargée."
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Impossible d'invoquer Python récursivement"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: Vim ne peut pas exécuter :py3 après avoir utilisé :python"
-
-#~ msgid "index must be int or slice"
-#~ msgstr "index doit être int ou slice"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ doit être une instance de chaîne (String)"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Désolé, commande désactivée : la bibliothèque Ruby n'a pas pu être "
-#~ "chargée."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: « return » inattendu"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: « next » inattendu"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: « break » inattendu"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: « redo » inattendu"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: « retry » hors d'une clause « rescue »"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: Exception non prise en charge"
-
-# DB - todo
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: contexte de longjmp inconnu : %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Basculer implémentation/définition"
-
-#~ msgid "Show base class of"
-#~ msgstr "Montrer la classe de base de"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Montrer les fonctions membres surchargées"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Récupérer du fichier"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Récupérer du projet"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Récupérer de tous les projets"
-
-#~ msgid "Retrieve"
-#~ msgstr "Récupérer"
-
-#~ msgid "Show source of"
-#~ msgstr "Montrer source de"
-
-#~ msgid "Find symbol"
-#~ msgstr "Trouver symbole"
-
-#~ msgid "Browse class"
-#~ msgstr "Parcourir classe"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Montrer classe dans hiérarchie"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Montrer classe dans hiérarchie restreinte"
-
-# todo
-#~ msgid "Xref refers to"
-#~ msgstr "Xref référence"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref est référencé par"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref a un(e)"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref utilisée par"
-
-#~ msgid "Show docu of"
-#~ msgstr "Montrer doc de"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Générer la doc de"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Connexion à SNiFF+ impossible. Vérifiez l'environnement (sniffemacs doit "
-#~ "être dans le $PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff : Erreur de lecture. Déconnexion"
-
-# DB - Les trois messages suivants vont ensembles.
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ est actuellement "
-
-#~ msgid "not "
-#~ msgstr "dé"
-
-#~ msgid "connected"
-#~ msgstr "connecté"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Requête SNiFF+ inconnue : %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Erreur lors de la connexion à SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ n'est pas connecté"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Ce tampon n'est pas un tampon SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff : Erreur lors d'une écriture. Déconnexion"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "numéro de tampon invalide"
-
-#~ msgid "not implemented yet"
-#~ msgstr "pas encore implémenté"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Le fichier \"%s\" est introuvable dans 'path'"
-# DB - TODO : le contexte est celui d'une annulation.
-#~ msgid "cannot set line(s)"
-#~ msgstr "Impossible de remettre la/les ligne(s)"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: ID invalide : %ld (doit être plus grand ou égal à 1)"
-#~ msgid "invalid mark name"
-#~ msgstr "nom de marque invalide"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID déjà pris: %ld"
-#~ msgid "mark not set"
-#~ msgstr "marque non positionnée"
+msgid "List or number required"
+msgstr "Liste ou nombre requis"
-#~ msgid "row %d column %d"
-#~ msgstr "ligne %d colonne %d"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: ID invalide : %ld (doit être plus grand ou égal à 1)"
-#~ msgid "cannot insert/append line"
-#~ msgstr "Impossible d'insérer/ajouter de lignes"
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID introuvable : %ld"
-#~ msgid "line number out of range"
-#~ msgstr "numéro de ligne hors limites"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Impossible de charger la bibliothèque %s"
-#~ msgid "unknown flag: "
-#~ msgstr "drapeau inconnu : "
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"Désolé, commande désactivée : la bibliothèque Perl n'a pas pu être chargée."
-#~ msgid "unknown vimOption"
-#~ msgstr "vimOption inconnue"
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Évaluation Perl interdite dans bac à sable sans le module Safe"
-#~ msgid "keyboard interrupt"
-#~ msgstr "interruption clavier"
+msgid "Edit with &multiple Vims"
+msgstr "Éditer dans &plusieurs Vims"
-#~ msgid "vim error"
-#~ msgstr "erreur Vim"
+msgid "Edit with single &Vim"
+msgstr "Éditer dans un seul &Vim"
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "Impossible de créer commande de tampon/fenêtre : objet en cours "
-#~ "d'effacement"
+msgid "Diff with Vim"
+msgstr "&Comparer avec Vim"
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "Impossible d'inscrire la commande de rappel : tampon/fenêtre en effacement"
+msgid "Edit with &Vim"
+msgstr "Éditer dans &Vim"
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: ERREUR FATALE TCL: reflist corrompue ?! Contactez vim-dev@vim.org, "
-#~ "SVP."
+msgid "Edit with existing Vim - "
+msgstr "Éditer dans le Vim existant - "
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "Impossible d'inscrire la commande de rappel : réf. tampon/fenêtre "
-#~ "introuvable"
+msgid "Edits the selected file(s) with Vim"
+msgstr "Édites le(s) fichier(s) sélectionné(s) avec Vim"
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: Désolé, commande désactivée: la bibliothèque Tcl n'a pas pu être "
-#~ "chargée."
+# DB - MessageBox win32, la longueur n'est pas un problème !
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr ""
+"Erreur de création du processus : vérifiez que gvim est bien dans votre "
+"chemin !"
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: code de sortie %d"
+msgid "gvimext.dll error"
+msgstr "Erreur de gvimext.dll"
-#~ msgid "cannot get line"
-#~ msgstr "Impossible d'obtenir la ligne"
+msgid "Path length too long!"
+msgstr "Le chemin est trop long !"
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Impossible d'inscrire un nom de serveur de commande"
+# msgstr "--Pas de lignes dans le tampon--"
+# DB - todo : ou encore : msgstr "--Aucune ligne dans le tampon--"
+msgid "--No lines in buffer--"
+msgstr "--Le tampon est vide--"
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Échec de l'envoi de la commande au programme cible"
+msgid "E470: Command aborted"
+msgstr "E470: Commande annulée"
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Id utilisé pour le serveur invalide : %s"
+msgid "E471: Argument required"
+msgstr "E471: Argument requis"
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: Entrée registre de l'instance de Vim mal formatée. Suppression !"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ devrait être suivi de /, ? ou &"
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans n'est pas supporté avec cette interface graphique\n"
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Invalide dans la fenêtre ligne-de-commande ; <CR> exécute, CTRL-C quitte"
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Ce Vim n'a pas été compilé avec la fonctionnalité diff"
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: commande non autorisée depuis un exrc/vimrc dans répertoire courant ou "
+"une recherche de marqueur"
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' ne peut pas être utilisé : désactivé à la compilation\n"
+msgid "E171: Missing :endif"
+msgstr "E171: :endif manquant"
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim : Erreur : Impossible de démarrer gvim depuis NetBeans\n"
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry manquant"
-# DB - todo (VMS uniquement).
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "pour lesquels la casse est indifférente (/ pour que le drapeau soit "
-#~ "majuscule)"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\tInscrire ce gvim pour OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\tDésinscrire gvim de OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\tLancer l'interface graphique (comme \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr ""
-#~ "-f, --nofork\tPremier-plan : ne pas détacher l'interface graphique du "
-#~ "terminal"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\tNe pas utiliser newcli pour l'ouverture des fenêtres"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <périph>\tUtiliser <périphérique> pour les E/S"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\tUtiliser <gvimrc> au lieu du gvimrc habituel"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tÉditer des fichiers chiffrés"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tConnecter Vim au serveur X spécifié"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tNe pas se connecter à un serveur X"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <fich>\tÉditer les <fichiers> dans un serveur Vim si possible"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent ...\tPareil, mais pas d'erreur s'il n'y a aucun serveur"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <fich>\tComme --remote mais ne quitter qu'à la fin de "
-#~ "l'édition"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent\tPareil, mais pas d'erreur s'il n'y a aucun serveur"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <fich>\tComme --remote mais ouvrir un onglet "
-#~ "pour chaque fichier"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <tche>\tEnvoyer <touches> à un serveur Vim puis quitter"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <expr>\tÉvaluer <expr> dans un serveur Vim, afficher le "
-#~ "résultat"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr ""
-#~ "--serverlist\t\tLister les noms des serveurs Vim disponibles et quitter"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <nom>\tEnvoyer au/devenir le serveur Vim nommé <nom>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Arguments reconnus par gvim (version Motif) :\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Arguments reconnus par gvim (version neXtaw) :\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Arguments reconnus par gvim (version Athena) :\n"
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile manquant"
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <écran>\tLancer Vim sur ce <display>"
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor manquant"
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tIconifier Vim au démarrage"
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile sans :while"
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr ""
-#~ "-background <coul>\tUtiliser <couleur> pour l'arrière-plan\t (abrv : -"
-#~ "bg)"
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor sans :for"
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <coul>\tUtiliser <couleur> pour le texte normal\t (abrv : -"
-#~ "fg)"
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Le fichier existe déjà (ajoutez ! pour passer outre)"
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr ""
-#~ "-font <fonte>\tUtiliser <fonte> pour le texte normal\t (abrv : -fn)"
+msgid "E472: Command failed"
+msgstr "E472: La commande a échoué"
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <fonte>\tUtiliser <fonte> pour le texte gras"
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Jeu de police inconnu : %s"
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <fonte>\tUtiliser <fonte> pour le texte italique"
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Police inconnue : %s"
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr ""
-#~ "-geometry <géom>\tUtiliser cette <géométrie> initiale\t (abrv : -geom)"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: La police \"%s\" n'a pas une chasse (largeur) fixe"
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr ""
-#~ "-borderwidth <épais>\tUtiliser cette <épaisseur> de bordure\t (abrv : -"
-#~ "bw)"
+msgid "E473: Internal error"
+msgstr "E473: Erreur interne"
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <lg>\tUtiliser cette <largeur> de barre de défil. (abrv: -"
-#~ "sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <haut>\tUtiliser cette <hauteur> de menu\t (abrv : -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tUtiliser la vidéo inverse\t\t (abrv : -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tNe pas utiliser de vidéo inverse\t (abrv : +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <ressource>\tConfigurer la <ressource> spécifiée"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Arguments reconnus par gvim (version GTK+) :\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr ""
-#~ "-display <display>\tLancer Vim sur ce <display>\t(également : --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <rôle>\tDonner un rôle pour identifier la fenêtre principale"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tOuvrir Vim dans un autre widget GTK"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tGvim affiche l'ID de la fenêtre sur stdout"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <titre parent>\tOuvrir Vim dans une application parente"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tOuvrir Vim dans un autre widget win32"
-
-#~ msgid "No display"
-#~ msgstr "Aucun display"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr " : L'envoi a échoué.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr " : L'envoi a échoué. Tentative d'exécution locale\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d édités sur %d"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Aucun display : L'envoi de l'expression a échoué.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr " : L'envoi de l'expression a échoué.\n"
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Erreur interne : %s"
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Page de codes non valide"
+msgid "Interrupted"
+msgstr "Interrompu"
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: Impossible de régler les valeurs IC"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Échec de la création du contexte de saisie"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Échec de l'ouverture de la méthode de saisie"
+msgid "E14: Invalid address"
+msgstr "E14: Adresse invalide"
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr ""
-#~ "E287: Alerte : Impossible d'inscrire la callback de destruction dans la MS"
+msgid "E474: Invalid argument"
+msgstr "E474: Argument invalide"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: la méthode de saisie ne supporte aucun style"
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Argument invalide : %s"
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr ""
-#~ "E289: le type de préédition de Vim n'est pas supporté par la méthode de "
-#~ "saisie"
+#, c-format
+msgid "E475: Invalid value for argument %s"
+msgstr "E475: Valeur d'argument invalide : %s"
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: Erreur lors de la mise à jour du fichier d'échange crypté"
+#, c-format
+msgid "E475: Invalid value for argument %s: %s"
+msgstr "E475: Valeur d'argument invalide %s : %s"
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr ""
-#~ "E833: %s est chiffré et cette version de Vim ne supporte pas le "
-#~ "chiffrement"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Fichier d'échange chiffré : \"%s\""
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Expression invalide : %s"
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "Si vous avez tapé une nouvelle clé de chiffrement mais n'avez pas "
-#~ "enregistré le fichier texte,"
+msgid "E16: Invalid range"
+msgstr "E16: Plage invalide"
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "tapez la nouvelle clé de chiffrement."
+msgid "E476: Invalid command"
+msgstr "E476: Commande invalide"
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "Si vous avez écrit le fichier texte après avoir changé la clé de "
-#~ "chiffrement, appuyez sur entrée"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" est un répertoire"
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "afin d'utiliser la même clé pour le fichier texte et le fichier d'échange"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: L'appel à la bibliothèque a échoué pour \"%s()\""
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr ""
-#~ "Utilisation de la clé de chiffrement du fichier d'échange pour le fichier "
-#~ "texte.\n"
+msgid "E667: Fsync failed"
+msgstr "E667: Fsynch a échoué"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [inutilisable avec cette version de Vim]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "Détacher ce menu"
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Impossible de charger la fonction %s de la bibliothèque"
-# DB : Les trois messages qui suivent sont des titres de boîtes
-# de dialogue par défaut.
-#~ msgid "Select Directory dialog"
-#~ msgstr "Sélecteur de répertoire"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: La marque a un numéro de ligne invalide"
-#~ msgid "Save File dialog"
-#~ msgstr "Enregistrer un fichier"
+msgid "E20: Mark not set"
+msgstr "E20: Marque non positionnée"
-#~ msgid "Open File dialog"
-#~ msgstr "Ouvrir un fichier"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Impossible de modifier, 'modifiable' est désactivé"
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Désolé, pas de sélecteur de fichiers en mode console"
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Trop de récursion dans les scripts"
-#~ msgid "ERROR: "
-#~ msgstr "ERREUR : "
+msgid "E23: No alternate file"
+msgstr "E23: Pas de fichier alternatif"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[octets] total alloué-libéré %<PRIu64>-%<PRIu64>, utilisé %<PRIu64>, pic "
-#~ "%<PRIu64>\n"
+msgid "E24: No such abbreviation"
+msgstr "E24: Cette abréviation n'existe pas"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[appels] total re/malloc() %<PRIu64>, total free() %<PRIu64>\n"
-#~ "\n"
+msgid "E477: No ! allowed"
+msgstr "E477: Le ! n'est pas autorisé"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: La ligne devient trop longue"
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: L'interface graphique n'a pas été compilée dans cette version"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Erreur interne : lalloc(%<PRId64>, )"
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: Le support de l'hébreu n'a pas été compilé dans cette version\n"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Forme de curseur invalide"
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: Le support du farsi n'a pas été compilé dans cette version\n"
-#~ msgid "Warning: Using a weak encryption method; see :help 'cm'"
-#~ msgstr ""
-#~ "Alerte : utilisation d'une méthode de chiffrage faible ; consultez :help 'cm'"
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: Le support de l'arabe n'a pas été compilé dans cette version\n"
-#~ msgid "Enter encryption key: "
-#~ msgstr "Tapez la clé de chiffrement : "
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Aucun nom de groupe de surbrillance %s"
-#~ msgid "Enter same key again: "
-#~ msgstr "Tapez la clé à nouveau : "
+msgid "E29: No inserted text yet"
+msgstr "E29: Pas encore de texte inséré"
-#~ msgid "Keys don't match!"
-#~ msgstr "Les clés ne correspondent pas !"
+msgid "E30: No previous command line"
+msgstr "E30: Aucune ligne de commande précédente"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Impossible de se connecter à Netbeans n°2"
+msgid "E31: No such mapping"
+msgstr "E31: Mappage inexistant"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Impossible de se connecter à Netbeans"
+msgid "E479: No match"
+msgstr "E479: Aucune correspondance"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Mode d'accès incorrect au fichier d'infos de connexion NetBeans : "
-#~ "\"%s\""
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Aucune correspondance : %s"
-# DB : message d'un appel à perror().
-#~ msgid "read from Netbeans socket"
-#~ msgstr "read sur la socket Netbeans"
+msgid "E32: No file name"
+msgstr "E32: Aucun nom de fichier"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Connexion NetBeans perdue pour le tampon %<PRId64>"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Aucune expression régulière de substitution précédente"
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: netbeans n'est pas supporté avec cette interface graphique"
+msgid "E34: No previous command"
+msgstr "E34: Aucune commande précédente"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans déjà connecté"
+msgid "E35: No previous regular expression"
+msgstr "E35: Aucune expression régulière précédente"
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s est en lecture seule (ajoutez ! pour passer outre)"
+msgid "E481: No range allowed"
+msgstr "E481: Les plages ne sont pas autorisées"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: La fonctionnalité d'évaluation n'est pas disponible"
+msgid "E36: Not enough room"
+msgstr "E36: Pas assez de place"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "libération de %<PRId64> lignes"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: aucun serveur nommé \"%s\" n'est enregistré"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Impossible de modifier term dans l'interface graphique"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Impossible de créer le fichier %s"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Utilisez \":gui\" pour démarrer l'interface graphique"
+msgid "E483: Can't get temp file name"
+msgstr "E483: Impossible d'obtenir un nom de fichier temporaire"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Non modifiable dans l'interface graphique GTK+ 2"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Impossible d'ouvrir le fichier \"%s\""
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Police(s) invalide(s)"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Impossible de lire le fichier %s"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: Impossible de sélectionner un jeu de polices"
+msgid "E38: Null argument"
+msgstr "E38: Argument null"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Jeu de polices invalide"
+msgid "E39: Number expected"
+msgstr "E39: Nombre attendu"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: Impossible de sélectionner une police à largeur double"
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Impossible d'ouvrir le fichier d'erreurs %s"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Police à largeur double invalide"
+msgid "E233: cannot open display"
+msgstr "E233: ouverture du display impossible"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: La souris n'est pas supportée"
+msgid "E41: Out of memory!"
+msgstr "E41: Mémoire épuisée"
-#~ msgid "cannot open "
-#~ msgstr "impossible d'ouvrir "
+msgid "Pattern not found"
+msgstr "Motif introuvable"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM : Impossible d'ouvrir la fenêtre !\n"
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Motif introuvable : %s"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigados version 2.04 ou ultérieure est nécessaire\n"
+msgid "E487: Argument must be positive"
+msgstr "E487: L'argument doit être positif"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "%s version %<PRId64> est nécessaire\n"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Impossible de retourner au répertoire précédent"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Impossible d'ouvrir NIL :\n"
+msgid "E42: No Errors"
+msgstr "E42: Aucune erreur"
-#~ msgid "Cannot create "
-#~ msgstr "Impossible de créer "
+# DB - TODO : trouver une traduction valable et attestée pour "location".
+msgid "E776: No location list"
+msgstr "E776: Aucune liste d'emplacements"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim quitte avec %d\n"
+msgid "E43: Damaged match string"
+msgstr "E43: La chaîne de recherche est endommagée"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "Impossible de modifier le mode de la console ?!\n"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: L'automate de regexp est corrompu"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize : pas une console ?!\n"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: L'option 'readonly' est activée (ajoutez ! pour passer outre)"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Impossible d'exécuter un shell avec l'option -f"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: La variable \"%s\" est en lecture seule"
-#~ msgid "Cannot execute "
-#~ msgstr "Impossible d'exécuter "
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr ""
+"E794: Impossible de modifier une variable depuis le bac à sable : \"%s\""
-#~ msgid "shell "
-#~ msgstr "le shell "
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Impossible d'utiliser une clé vide dans un Dictionnaire"
-#~ msgid " returned\n"
-#~ msgstr " a été retourné\n"
+msgid "E715: Dictionary required"
+msgstr "E715: Dictionnaire requis"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE trop petit."
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: index de Liste hors limites : %ld au-delà de la fin"
-#~ msgid "I/O ERROR"
-#~ msgstr "ERREUR d'E/S"
+# DB : Suggestion
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: La fonction %s a reçu trop d'arguments"
-#~ msgid "Message"
-#~ msgstr "Message"
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: La clé %s n'existe pas dans le Dictionnaire"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr ""
-#~ "'columns' ne vaut pas 80, impossible d'exécuter des commandes externes"
+msgid "E714: List required"
+msgstr "E714: Liste requise"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: La sélection de l'imprimante a échoué"
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: L'argument de %s doit être une Liste ou un Dictionnaire"
-# DB - Contenu des c-formats : Imprimante puis Port.
-#~ msgid "to %s on %s"
-#~ msgstr "vers %s sur %s"
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Erreur lors de la lecture du fichier d'erreurs"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Police d'imprimante inconnue : %s"
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Opération interdite dans le bac à sable"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Erreur d'impression : %s"
+msgid "E523: Not allowed here"
+msgstr "E523: Interdit à cet endroit"
-#~ msgid "Printing '%s'"
-#~ msgstr "Impression de '%s'"
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Choix du mode d'écran non supporté"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: Jeu de caractères \"%s\" invalide dans le nom de fonte \"%s\""
+msgid "E49: Invalid scroll size"
+msgstr "E49: Valeur de défilement invalide"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Caractère '%c' invalide dans le nom de fonte \"%s\""
+msgid "E91: 'shell' option is empty"
+msgstr "E91: L'option 'shell' est vide"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "L'ouverture du display X a pris %<PRId64> ms"
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Impossible de lire les données du symbole !"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim : Réception d'une erreur X\n"
+msgid "E72: Close error on swap file"
+msgstr "E72: Erreur lors de la fermeture du fichier d'échange"
-#~ msgid "Testing the X display failed"
-#~ msgstr "Le test du display X a échoué"
+msgid "E73: tag stack empty"
+msgstr "E73: La pile des marqueurs est vide"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "L'ouverture du display X a dépassé le délai d'attente"
+msgid "E74: Command too complex"
+msgstr "E74: Commande trop complexe"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Impossible d'exécuter le shell sh\n"
+msgid "E75: Name too long"
+msgstr "E75: Nom trop long"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Impossible de créer des tuyaux (pipes)\n"
+msgid "E76: Too many ["
+msgstr "E76: Trop de ["
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Impossible de forker\n"
+msgid "E77: Too many file names"
+msgstr "E77: Trop de noms de fichiers"
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Commande interrompue\n"
+msgid "E488: Trailing characters"
+msgstr "E488: Caractères surnuméraires"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP a perdu la connexion ICE"
+msgid "E78: Unknown mark"
+msgstr "E78: Marque inconnue"
-#~ msgid "Opening the X display failed"
-#~ msgstr "L'ouverture du display X a échoué"
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Impossible de développer les métacaractères"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP : prise en charge d'une requête save-yourself"
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' ne peut pas être plus petit que 'winminheight'"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP : ouverture de la connexion"
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' ne peut pas être plus petit que 'winminwidth'"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP : échec de la surveillance de connexion ICE"
+msgid "E80: Error while writing"
+msgstr "E80: Erreur lors de l'écriture"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP : SmcOpenConnection a échoué : %s"
+msgid "E939: Positive count required"
+msgstr "E939: Quantificateur positif requis"
-#~ msgid "At line"
-#~ msgstr "À la ligne"
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> utilisé en dehors d'un script"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Impossible de charger vim32.dll !"
+msgid "E449: Invalid expression received"
+msgstr "E449: Expression invalide reçue"
-#~ msgid "VIM Error"
-#~ msgstr "Erreur VIM"
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Cette zone est verrouillée et ne peut pas être modifiée"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Impossible d'initialiser les pointeurs de fonction vers la DLL !"
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr ""
+"E744: NetBeans n'autorise pas la modification des fichiers en lecture seule"
-#~ msgid "shell returned %d"
-#~ msgstr "le shell a retourné %d"
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: le motif utilise plus de mémoire que 'maxmempattern'"
-# DB - Les événements en question sont ceux des messages qui suivent.
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim : Événement %s intercepté\n"
+msgid "E749: empty buffer"
+msgstr "E749: tampon vide"
-#~ msgid "close"
-#~ msgstr "de fermeture"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Le tampon %ld n'existe pas"
-#~ msgid "logoff"
-#~ msgstr "de déconnexion"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Délimiteur ou motif de recherche invalide"
-#~ msgid "shutdown"
-#~ msgstr "d'arrêt"
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Le fichier est chargé dans un autre tampon"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Commande introuvable"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: L'option '%s' n'est pas activée"
-#~ 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 ""
-#~ "VIMRUN.EXE est introuvable votre $PATH.\n"
-#~ "Les commandes externes ne feront pas de pause une fois terminées.\n"
-#~ "Consultez :help win32-vimrun pour plus d'informations."
+msgid "E850: Invalid register name"
+msgstr "E850: Nom de registre invalide"
-#~ msgid "Vim Warning"
-#~ msgstr "Alerte Vim"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Répertoire introuvable dans '%s' : \"%s\""
-#~ msgid "Error file"
-#~ msgstr "Fichier d'erreurs"
+msgid "E952: Autocommand caused recursive behavior"
+msgstr "E952: Une autocommande a causé une récursivité"
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr ""
-#~ "E868: Erreur lors de la construction du NFA avec classe d'équivalence"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "La recherche a atteint le HAUT, et continue en BAS"
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr ""
-#~ "E878: (NFA) Impossible d'allouer la mémoire pour parcourir les branches!"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "La recherche a atteint le BAS, et continue en HAUT"
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "Alerte : Liste de mots \"%s_%s.spl\" ou \"%s_ascii.spl\" introuvable"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Besoin de la clé de chiffrement pour \"%s\""
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "La conversion dans %s non supportée"
+msgid "empty keys are not allowed"
+msgstr "les clés vides ne sont pas autorisées"
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: mémoire insuffisante, liste de mots peut-être incomplète"
+msgid "dictionary is locked"
+msgstr "dictionnaire est verrouillé"
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Chemin de fichiers de marqueurs tronqué pour %s\n"
+msgid "list is locked"
+msgstr "liste verrouillée"
-#~ msgid "new shell started\n"
-#~ msgstr "nouveau shell démarré\n"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "l'ajout de clé '%s' au dictionnaire a échoué"
-# DB - Message de débogage.
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "CUT_BUFFER0 utilisé plutôt qu'une sélection vide"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "index doit être int ou slice, et non %s"
-# DB - Question O/N.
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Annulation impossible ; continuer"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Fichier non-chiffré a un fichier d'annulations chiffré : %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Déchiffrage du fichier d'annulation a échoué : %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Le fichier d'annulations est chiffré : %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version graphique MS-Windows 16/32 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version graphique MS-Windows 64 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version graphique MS-Windows 32 bits"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " lancée en mode Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " supportant l'OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version console MS-Windows 64 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version console MS-Windows 32 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MS-Windows 16 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MS-DOS 32 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MS-DOS 16 bits"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MaxOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version MacOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Version OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Grosse version "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Version normale "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Petite version "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Version minuscule "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "avec interface graphique GTK2-GNOME."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "avec interface graphique GTK2."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "avec interface graphique X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "avec interface graphique X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "avec interface graphique X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "avec interface graphique Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "avec une interface graphique."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "avec interface graphique Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "avec interface graphique Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "avec interface graphique (classic)."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " fichier gvimrc système : \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " fichier gvimrc utilisateur : \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "2me fichier gvimrc utilisateur : \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "3me fichier gvimrc utilisateur : \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " fichier menu système : \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Compilateur : "
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "attendu instance de str() ou unicode(), mais reçu %s"
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "menu Aide->Orphelins pour plus d'info"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "attendu instance de bytes() ou str(), mais reçu %s"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Les modes sont désactivés, le texte saisi est inséré"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr ""
+"attendu int(), long() ou quelque chose qui peut être transformé en long(), "
+"mais reçu %s"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "menu Édition->Réglages Globaux->Insertion Permanente"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr ""
+"attendu int() ou quelque chose qui peut être transformé en int(), mais reçu "
+"%s"
-# DB - todo
-#~ msgid " for two modes "
-#~ msgstr " pour les modes "
+msgid "value is too large to fit into C int type"
+msgstr "valeur trop grande pour être stockée dans le type C int"
-# DB - todo
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "menu Édition->Réglages Globaux->Compatibilité Vi"
+msgid "value is too small to fit into C int type"
+msgstr "valeur trop petite pour être stockée dans le type C int"
-# DB - todo
-#~ msgid " for Vim defaults "
-#~ msgstr " pour déf. de Vim "
+msgid "number must be greater than zero"
+msgstr "le nombre doit être plus grand que zéro"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "ALERTE: Windows 95/98/ME détecté"
+msgid "number must be greater or equal to zero"
+msgstr "le nombre doit être plus grand ou égal à zéro"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "tapez :help windows95<Entrée> pour plus d'information"
+msgid "can't delete OutputObject attributes"
+msgstr "impossible d'effacer les attributs d'OutputObject"
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Impossible de charger la bibliothèque %s"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "attribut invalide : %s"
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "Désolé, commande désactivée : la bibliothèque Perl n'a pas pu être "
-#~ "chargée."
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python : Erreur d'initialisation des objets d'E/S"
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Évaluation Perl interdite dans bac à sable sans le module Safe"
+msgid "failed to change directory"
+msgstr "changement de répertoire a échoué"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Éditer dans &plusieurs Vims"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "attendu un 3-tuple comme résultat de imp.find_module(), mais reçu %s"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Éditer dans un seul &Vim"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr ""
+"attendu un 3-tuple comme résultat de imp.find_module(), mais reçu un tuple "
+"de taille %d"
-#~ msgid "Diff with Vim"
-#~ msgstr "&Comparer avec Vim"
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "erreur interne : imp.find_module a retourné un tuple contenant NULL"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Éditer dans &Vim"
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "impossible d'effacer les attributs de vim.Dictionary"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Éditer dans le Vim existant - "
+msgid "cannot modify fixed dictionary"
+msgstr "impossible de modifier un dictionnaire fixe"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Édites le(s) fichier(s) sélectionné(s) avec Vim"
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "impossible d'initialiser l'attribut %s"
-# DB - MessageBox win32, la longueur n'est pas un problème !
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr ""
-#~ "Erreur de création du processus : vérifiez que gvim est bien dans votre "
-#~ "chemin !"
+msgid "hashtab changed during iteration"
+msgstr "la table de hachage a été changée pendant une itération"
-#~ msgid "gvimext.dll error"
-#~ msgstr "Erreur de gvimext.dll"
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr ""
+"attendu une séquence d'éléments de taille 2, mais reçu une séquence de "
+"taille %d"
-#~ msgid "Path length too long!"
-#~ msgstr "Le chemin est trop long !"
+msgid "list constructor does not accept keyword arguments"
+msgstr "le constructeur de liste n'accepte pas les arguments nommés"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Jeu de police inconnu : %s"
+msgid "list index out of range"
+msgstr "index de liste hors limites"
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Police inconnue : %s"
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "erreur interne : accès à un élément %d de liste a échoué"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: La police \"%s\" n'a pas une chasse (largeur) fixe"
+msgid "slice step cannot be zero"
+msgstr "le pas du découpage en tranche ne peut pas être zéro"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Impossible de charger la fonction %s de la bibliothèque"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr ""
+"tentative d'assigner une séquence de taille plus grande que %d à un "
+"découpage en tranche étendu "
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E26: Le support de l'hébreu n'a pas été compilé dans cette version\n"
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "erreur interne : pas d'élément %d de liste vim"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Le support du farsi n'a pas été compilé dans cette version\n"
+msgid "internal error: not enough list items"
+msgstr "erreur interne : pas assez d'éléments de liste"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: Le support de l'arabe n'a pas été compilé dans cette version\n"
+msgid "internal error: failed to add item to list"
+msgstr "erreur interne : ajout d'élément à la liste a échoué"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: aucun serveur nommé \"%s\" n'est enregistré"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr ""
+"tentative d'assigner une séquence de taille %d à un découpage en tranche "
+"étendu de taille %d"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ouverture du display impossible"
+msgid "failed to add item to list"
+msgstr "ajout à la liste a échoué"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Expression invalide reçue"
+msgid "cannot delete vim.List attributes"
+msgstr "impossible d'effacer les attributs de vim.List"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Cette zone est verrouillée et ne peut pas être modifiée"
+msgid "cannot modify fixed list"
+msgstr "impossible de modifier une liste fixe"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr ""
-#~ "E744: NetBeans n'autorise pas la modification des fichiers en lecture "
-#~ "seule"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "la fonction sans nom %s n'existe pas"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Besoin de la clé de chiffrement pour \"%s\""
+#, c-format
+msgid "function %s does not exist"
+msgstr "la fonction %s n'existe pas"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "impossible d'effacer les attributs d'OutputObject"
+#, c-format
+msgid "failed to run function %s"
+msgstr "exécution de la fonction %s a échoué"
-#~ msgid "invalid attribute"
-#~ msgstr "attribut invalide"
+msgid "unable to get option value"
+msgstr "impossible d'obtenir la valeur d'une option"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python : Erreur d'initialisation des objets d'E/S"
+msgid "internal error: unknown option type"
+msgstr "erreur interne : type d'option inconnu"
-#~ msgid "empty keys are not allowed"
-#~ msgstr "les clés vides ne sont pas autorisées"
+msgid "problem while switching windows"
+msgstr "problème lors du changement de fenêtres"
-#~ msgid "Cannot modify fixed dictionary"
-#~ msgstr "Impossible de modifier un dictionnaire fixe"
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "impossible de désactiver une option globale %s"
-#~ msgid "dict is locked"
-#~ msgstr "dictionnaire est verrouillé"
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "impossible de désactiver l'option %s qui n'a pas de valeur globale"
-#~ msgid "failed to add key to dictionary"
-#~ msgstr "l'ajout de clé au dictionnaire a échoué"
+msgid "attempt to refer to deleted tab page"
+msgstr "tentative de référencer un onglet effacé"
-#~ msgid "list index out of range"
-#~ msgstr "index de liste hors limites"
+msgid "no such tab page"
+msgstr "cet onglet n'existe pas"
-#~ msgid "internal error: failed to get vim list item"
-#~ msgstr "erreur interne : accès à un élément de liste a échoué"
+msgid "attempt to refer to deleted window"
+msgstr "tentative de référencer une fenêtre effacée"
-#~ msgid "list is locked"
-#~ msgstr "liste verrouillée"
+msgid "readonly attribute: buffer"
+msgstr "attribut en lecture seule : tampon"
-#~ msgid "Failed to add item to list"
-#~ msgstr "Ajout à la liste a échoué"
+msgid "cursor position outside buffer"
+msgstr "curseur positionné en dehors du tampon"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "erreur interne : ajout d'élément à la liste a échoué"
+msgid "no such window"
+msgstr "Cette fenêtre n'existe pas"
-#~ msgid "cannot delete vim.dictionary attributes"
-#~ msgstr "impossible d'effacer les attributs de vim.dictionary"
+msgid "attempt to refer to deleted buffer"
+msgstr "tentative de référencer un tampon effacé"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "impossible de modifier une liste fixe"
+msgid "failed to rename buffer"
+msgstr "impossible de renommer le tampon"
-#~ msgid "cannot set this attribute"
-#~ msgstr "impossible d'initialiser cet attribut"
+msgid "mark name must be a single character"
+msgstr "le nom de marque doit être un seul caractère"
-#~ msgid "failed to run function"
-#~ msgstr "exécution de la fonction a échoué"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "attendu un objet vim.Buffer, mais reçu %s"
-#~ msgid "unable to unset global option"
-#~ msgstr "impossible de désactiver une option globale"
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "impossible de se déplacer au tampon %d"
-#~ msgid "unable to unset option without global value"
-#~ msgstr "impossible de désactiver une option sans une valeur globale"
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "attendu un objet vim.Window, mais reçu %s"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "tentative de référencer un onglet effacé"
+msgid "failed to find window in the current tab page"
+msgstr "impossible de trouver une fenêtre dans l'onglet courant"
-#~ msgid "no such tab page"
-#~ msgstr "cet onglet n'existe pas"
+msgid "did not switch to the specified window"
+msgstr "ne s'est pas déplacé à la fenêtre spécifiée"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "tentative de référencer une fenêtre effacée"
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "attendu un objet vim.TabPage, mais reçu %s"
-#~ msgid "readonly attribute"
-#~ msgstr "attribut en lecture seule"
+msgid "did not switch to the specified tab page"
+msgstr "impossible de se déplacer à l'onglet spécifié"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "curseur positionné en dehors du tampon"
+msgid "failed to run the code"
+msgstr "exécution du code a échoué"
-#~ msgid "no such window"
-#~ msgstr "Cette fenêtre n'existe pas"
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval n'a pas retourné un objet python valide"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "tentative de référencer un tampon effacé"
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Conversion d'objet python à une valeur de vim a échoué"
-#~ msgid "expected vim.buffer object"
-#~ msgstr "objet vim.buffer attendu"
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "impossible de convertir %s à un dictionnaire vim"
-#~ msgid "failed to switch to given buffer"
-#~ msgstr "impossible de se déplacer au tampon donné"
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "impossible de convertir %s à une liste de vim"
-#~ msgid "expected vim.window object"
-#~ msgstr "objet vim.window attendu"
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "impossible de convertir %s à une structure de vim"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "impossible de trouver une fenêtre dans l'onglet courant"
+msgid "internal error: NULL reference passed"
+msgstr "erreur interne : référence NULL passée"
-#~ msgid "did not switch to the specified window"
-#~ msgstr "ne s'est pas déplacé à la fenêtre spécifiée"
+msgid "internal error: invalid value type"
+msgstr "erreur interne : type de valeur invalide"
-#~ msgid "expected vim.tabpage object"
-#~ msgstr "objet vim.tabpage attendu"
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"Impossible d'initialiser sys.path_hook qui n'est pas un liste\n"
+"Vous devez maintenant :\n"
+"- ajouter vim.path_hook à sys.path_hooks\n"
+"- ajouter vim.VIM_SPECIAL_PATH à sys.path\n"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "impossible de se déplacer à l'onglet spécifié"
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"Impossible d'initialiser le chemin : sys.math n'est pas une liste\n"
+"Vous devez maintenant ajouter vim.VIM_SPECIAL_PATH à sys.path"
-#~ msgid "failed to run the code"
-#~ msgstr "exécution du code a échoué"
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*.*)\t*.*\n"
+msgstr ""
+"Fichiers de macros Vim (*.vim)\t*.vim\n"
+"Tous les fichiers (*.*)\t*.*\n"
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: Eval n'a pas retourné un objet python valide"
+msgid "All Files (*.*)\t*.*\n"
+msgstr "Tous les fichiers (*.)\t*.*\n"
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: Conversion d'objet python à une valeur de vim a échoué"
+msgid ""
+"All Files (*.*)\t*.*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VB code (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"Tous les fichiers (*.*)\t*.*\n"
+"Source C (*.c, *.h)\t*.c;*.h\n"
+"Source C++ (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Code VB (*.bas, *.frm)\t*.bas;*.frm\n"
+"Fichiers Vim (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
-#~ msgid "unable to convert to vim structure"
-#~ msgstr "conversion à une structure vim impossible"
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*)\t*\n"
+msgstr ""
+"Fichiers de macros Vim (*.vim)\t*.vim\n"
+"Tous les fichiers (*)\t*\n"
-#~ msgid "NULL reference passed"
-#~ msgstr "référence NULL passée"
+msgid "All Files (*)\t*\n"
+msgstr "Tous les fichiers (*)\t*\n"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "erreur interne : type de valeur invalide"
+msgid ""
+"All Files (*)\t*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"Tous les fichiers (*)\t*\n"
+"Source C (*.c, *.h)\t*.c;*.h\n"
+"Source C++ (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Fichiers Vim (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
diff --git a/src/nvim/po/ga.po b/src/nvim/po/ga.po
index f7117c6e86..617b805eb8 100644
--- a/src/nvim/po/ga.po
+++ b/src/nvim/po/ga.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vim 7.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
+"POT-Creation-Date: 2017-07-11 15:45-0500\n"
"PO-Revision-Date: 2010-04-14 10:01-0500\n"
"Last-Translator: Kevin Patrick Scannell <kscanne@gmail.com>\n"
"Language-Team: Irish <gaeilge-gnulinux@lists.sourceforge.net>\n"
@@ -14,208 +14,171 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=5; plural=n==1 ? 0 : n==2 ? 1 : (n>2 && n<7) ? 2 :"
+"(n>6 && n<11) ? 3 : 4;\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "Dramhaíl i ndiaidh argóinte rogha"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: cuireadh glaoch ar bf_key_init() le focal faire folamh"
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Úsáid mhícheart Blowfish mórcheannach/caolcheannach"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: Theip ar thástáil sha256"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Theip ar thástáil Blowfish"
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[Liosta Suíomh]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
-msgstr "[Liosta Ceartúchán Tapa]"
+msgstr "[Liosta Mearcheartúchán]"
-#: ../buffer.c:94
-#, fuzzy
msgid "E855: Autocommands caused command to abort"
-msgstr "E812: Bhí maolán nó ainm maoláin athraithe ag orduithe uathoibríocha"
+msgstr "E855: Tobscoireadh an t-ordú mar gheall ar uathorduithe"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: Ní féidir maolán a dháileadh, ag scor..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: Ní féidir maolán a dháileadh, ag úsáid cinn eile..."
-#: ../buffer.c:763
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: Ní féidir an maolán a chlárú"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Iarracht ar mhaolán in úsáid a scriosadh"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Ní raibh aon mhaolán díluchtaithe"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Ní raibh aon mhaolán scriosta"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Ní raibh aon mhaolán bánaithe"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "Bhí maolán amháin díluchtaithe"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "%d maolán folmhaithe"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "Bhí maolán amháin scriosta"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "%d maolán scriosta"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "Bhí maolán amháin bánaithe"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d maolán bánaithe"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: Ní féidir an maolán deireanach a dhíluchtú"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Níor aimsíodh maolán mionathraithe"
#. back where we started, didn't find anything.
-#: ../buffer.c:903
msgid "E85: There is no listed buffer"
msgstr "E85: Níl aon mhaolán liostaithe ann"
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Níl a leithéid de mhaolán %<PRId64>"
-
-#: ../buffer.c:915
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: Ní féidir a dhul thar an maolán deireanach"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: Ní féidir a dhul roimh an chéad mhaolán"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
msgstr ""
-"E89: Athraíodh maolán %<PRId64> ach nach bhfuil sé sábháilte ó shin (cuir ! "
-"leis an ordú chun sárú)"
+"E89: Athraíodh maolán %ld ach nach bhfuil sé sábháilte ó shin (cuir ! leis "
+"an ordú chun sárú)"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Rabhadh: Liosta ainmneacha comhaid thar maoil"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Maolán %<PRId64> gan aimsiú"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Maolán %ld gan aimsiú"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: Níos mó ná teaghrán amháin comhoiriúnaithe le %s"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: Níl aon mhaolán comhoiriúnaithe le %s"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "líne %<PRId64>:"
+msgid "line %ld"
+msgstr "líne %ld:"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Tá maolán ann leis an ainm seo cheana"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [Mionathraithe]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Gan eagrú]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Comhad nua]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[Earráidí léimh]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[L-A]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[inléite amháin]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "1 líne --%d%%--"
-#: ../buffer.c:2526
#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> líne --%d%%--"
+msgid "%ld lines --%d%%--"
+msgstr "%ld líne --%d%%--"
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "líne %<PRId64> de %<PRId64> --%d%%-- col "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "líne %ld de %ld --%d%%-- col "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[Gan Ainm]"
#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "cabhair"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Cabhair]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[Réamhamharc]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Uile"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Bun"
-#: ../buffer.c:3531
msgid "Top"
msgstr "Barr"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -223,11 +186,9 @@ msgstr ""
"\n"
"# Liosta maoláin:\n"
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[Sealadach]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -235,202 +196,240 @@ msgstr ""
"\n"
"--- Comharthaí ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Comharthaí do %s:"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " líne=%<PRId64> id=%d ainm=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " líne=%ld id=%d ainm=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: Idirstad ar iarraidh"
+msgid "E902: Cannot connect to port"
+msgstr "E902: Ní féidir ceangal leis an bport"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: Mód neamhcheadaithe"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() in channel_open()"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: ag súil le digit"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: socket() in channel_open()"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Céatadán neamhcheadaithe"
+msgid "E903: received command with non-string argument"
+msgstr "E903: fuarthas ordú le hargóint nach bhfuil ina theaghrán"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: ní mór don argóint dheireanach ar expr/call a bheith ina huimhir"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: Caithfidh an tríú argóint a bheith ina liosta"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: fuarthas ordú anaithnid: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): scríobh gan ceangal a bheith ann"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): theip ar scríobh"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Ní féidir diff a dhéanamh ar níos mó ná %<PRId64> maolán"
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: Ní féidir aisghlaoch a úsáid le %s()"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr ""
+"E912: ní féidir ch_evalexpr()/ch_sendexpr() a úsáid le cainéal raw nó nl"
+
+msgid "E906: not an open channel"
+msgstr "E906: ní cainéal oscailte é"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: caithfear _name a shocrú chun comhad _io a úsáid"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: caithfear in_buf nó in_name a shocrú chun maolán in_io a úsáid"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: ní mór an maolán a luchtú: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Comhad criptithe le modh anaithnid"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "Rabhadh: Criptiúchán lag; féach :help 'cm'"
+
+msgid "Enter encryption key: "
+msgstr "Iontráil eochair chriptiúcháin: "
+
+msgid "Enter same key again: "
+msgstr "Iontráil an eochair arís: "
+
+msgid "Keys don't match!"
+msgstr "Níl na heochracha comhoiriúnach le chéile!"
+
+msgid "[crypted]"
+msgstr "[criptithe]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: Idirstad ar iarraidh i bhFoclóir: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Eochair dhúblach i bhFoclóir: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: Camóg ar iarraidh i bhFoclóir: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: '}' ar iarraidh ag deireadh foclóra: %s"
+
+msgid "extend() argument"
+msgstr "argóint extend()"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Tá eochair ann cheana: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: Ní féidir diff a dhéanamh ar níos mó ná %ld maolán"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: Ní féidir comhaid shealadacha a léamh nó a scríobh"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: Ní féidir diffeanna a chruthú"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "Comhad paiste"
+
msgid "E816: Cannot read patch output"
msgstr "E816: Ní féidir aschur ó 'patch' a léamh"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Ní féidir aschur ó 'diff' a léamh"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: Níl an maolán reatha sa mhód diff"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: Ní féidir aon mhaolán eile a athrú sa mhód diff"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: Níl aon mhaolán eile sa mhód diff"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr ""
"E101: Tá níos mó ná dhá mhaolán sa mhód diff, níl fhios agam cé acu ba chóir "
"a úsáid"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: Tá maolán \"%s\" gan aimsiú"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Níl maolán \"%s\" i mód diff"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Athraíodh an maolán gan choinne"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: Ní cheadaítear carachtair éalúcháin i ndéghraf"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: Comhad eochairmhapála gan aimsiú"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: Ag úsáid :loadkeymap ach ní comhad foinsithe é seo"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: Iontráil fholamh eochairmhapála"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " Comhlánú lorgfhocal (^N^P)"
#. 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 " mód ^X (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " Comhlánú Línte Ina Iomlán (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " Comhlánú de na hainmneacha comhaid (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " Comhlánú clibeanna (^]/^N/^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " Comhlánú Conaire (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " Comhlánú de na sainmhínithe (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " Comhlánú foclóra (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " Comhlánú teasárais (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " Comhlánú den líne ordaithe (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " Comhlánú saincheaptha (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " Comhlánú Omni (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Moladh litrithe (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " Comhlánú logánta lorgfhocal (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "Sroicheadh críoch an pharagraif"
-#: ../edit.c:101
-#, fuzzy
msgid "E839: Completion function changed window"
-msgstr "E813: Ní féidir fuinneog autocmd a dhúnadh"
+msgstr "E839: D'athraigh an fheidhm chomhlánaithe an fhuinneog"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
-msgstr ""
+msgstr "E840: Scrios an fheidhm chomhlánaithe roinnt téacs"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "tá an rogha 'dictionary' folamh"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "tá an rogha 'thesaurus' folamh"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "Foclóir á scanadh: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (ionsáigh) Scrollaigh (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (ionadaigh) Scrollaigh (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "%s á scanadh"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "Clibeanna á scanadh."
-#: ../edit.c:4519
+msgid "match in file"
+msgstr "meaitseáil sa chomhad"
+
msgid " Adding"
msgstr " Méadú"
@@ -438,702 +437,456 @@ msgstr " Méadú"
#. * be called before line = ml_get(), or when this address is no
#. * longer needed. -- Acevedo.
#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- Ag Cuardach..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "Ar ais ag an mbunáit"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "Focal as líne eile"
-#: ../edit.c:4624
msgid "The only match"
msgstr "An t-aon teaghrán amháin comhoiriúnaithe"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "comhoiriúnú %d as %d"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "comhoiriúnú %d"
-#: ../eval.c:137
+#. maximum nesting of lists and dicts
msgid "E18: Unexpected characters in :let"
msgstr "E18: Carachtair gan choinne i :let"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: innéacs liosta as raon: %<PRId64>"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: Athróg gan sainmhíniú: %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: `]' ar iarraidh"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: Caithfidh argóint de %s a bheith ina Liosta"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Caithfidh argóint de %s a bheith ina Liosta nó Foclóir"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Ní féidir eochair fholamh a úsáid le Foclóir"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: Tá gá le liosta"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Tá gá le foclóir"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: An iomarca argóintí d'fheidhm: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Níl an eochair seo san Fhoclóir: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: Tá feidhm %s ann cheana, cuir ! leis an ordú chun é a asáitiú"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Tá an iontráil foclóra seo ann cheana"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Tá gá le Funcref"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: Ní féidir [:] a úsáid le foclóir"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: Cineál mícheart athróige le haghaidh %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Feidhm anaithnid: %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: Ainm athróige neamhcheadaithe: %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: Snámhphointe á úsáid mar Theaghrán"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: Níos lú spriocanna ná míreanna Liosta"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: Níos mó spriocanna ná míreanna Liosta"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "; dúblach i liosta na n-athróg"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Ní féidir athróga do %s a thaispeáint"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: Is féidir Liosta nó Foclóir amháin a innéacsú"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: caithfidh [:] a bheith ar deireadh"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: ní foláir Liosta a thabhairt le [:]"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: Tá níos mó míreanna ag an Liosta ná an sprioc"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: Níl go leor míreanna ag an Liosta"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: \"in\" ar iarraidh i ndiaidh :for"
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Lúibíní ar iarraidh: %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Níl a leithéid d'athróg: \"%s\""
-#: ../eval.c:3333
+#. For historic reasons this error is not given for a list or dict.
+#. * E.g., the b: dict could be locked/unlocked.
+#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: Ní féidir athróg %s a ghlasáil nó a dhíghlasáil"
+
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: athróg neadaithe ródhomhain chun í a (dí)ghlasáil"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: ':' ar iarraidh i ndiaidh '?'"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: Is féidir Liosta a chur i gcomparáid le Liosta eile amháin"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: Oibríocht neamhbhailí ar Liostaí"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: Is féidir Foclóir a chur i gcomparáid le Foclóir eile amháin"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: Oibríocht neamhbhailí ar Fhoclóir"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Is féidir Funcref a chur i gcomparáid le Funcref eile amháin"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: Oibríocht neamhbhailí ar Funcref"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: Ní féidir '%' a úsáid le Snámhphointe"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ')' ar iarraidh"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: Ní féidir Funcref a innéacsú"
-#: ../eval.c:4839
+msgid "E909: Cannot index a special variable"
+msgstr "E909: Ní féidir athróg speisialta a innéacsú"
+
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Ainm rogha ar iarraidh: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Rogha anaithnid: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Comhartha athfhriotail ar iarraidh: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Comhartha athfhriotail ar iarraidh: %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Camóg ar iarraidh i Liosta: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: ']' ar iarraidh ag deireadh liosta: %s"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Idirstad ar iarraidh i bhFoclóir: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Eochair dhúblach i bhFoclóir: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Camóg ar iarraidh i bhFoclóir: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: '}' ar iarraidh ag deireadh foclóra: %s"
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"Níl go leor cuimhne ann le tagairtí a shocrú; bailiú dramhaíola á thobscor!"
-#: ../eval.c:6555
msgid "E724: variable nested too deep for displaying"
msgstr "E724: athróg neadaithe ródhomhain chun í a thaispeáint"
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: An iomarca argóintí d'fheidhm %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Argóintí neamhbhailí d'fheidhm %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Feidhm anaithnid: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Níl go leor feidhmeanna d'fheidhm: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> á úsáid ach gan a bheith i gcomhthéacs scripte: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Feidhm 'dict' á ghlao gan Foclóir: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Uimhir nó Snámhphointe de dhíth"
-
-#: ../eval.c:7503
-#, fuzzy
-msgid "add() argument"
-msgstr "argóint -c"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: An iomarca argóintí"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: is féidir complete() a úsáid sa mhód Ionsáite amháin"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Tá eochair ann cheana: %s"
-
-#: ../eval.c:8692
-#, fuzzy
-msgid "extend() argument"
-msgstr "argóint --cmd"
-
-#: ../eval.c:8915
-#, fuzzy
-msgid "map() argument"
-msgstr "argóint -c"
-
-#: ../eval.c:8916
-#, fuzzy
-msgid "filter() argument"
-msgstr "argóint -c"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld líne: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: Feidhm anaithnid: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "Glaodh inputrestore() níos minice ná inputsave()"
-
-#: ../eval.c:10771
-#, fuzzy
-msgid "insert() argument"
-msgstr "argóint -c"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: Ní cheadaítear an raon"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: Cineál neamhbhailí le haghaidh len()"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: Is nialas í an chéim"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: Tosach thar dheireadh"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<folamh>"
-
-#: ../eval.c:12282
-#, fuzzy
-msgid "remove() argument"
-msgstr "argóint --cmd"
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Snámhphointe á úsáid mar Uimhir"
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: An iomarca naisc shiombalacha (ciogal?)"
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: Funcref á úsáid mar Uimhir"
-#: ../eval.c:12593
-#, fuzzy
-msgid "reverse() argument"
-msgstr "argóint -c"
+msgid "E745: Using a List as a Number"
+msgstr "E745: Liosta á úsáid mar Uimhir"
-#: ../eval.c:13721
-#, fuzzy
-msgid "sort() argument"
-msgstr "argóint -c"
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Foclóir á úsáid mar Uimhir"
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "argóint -c"
+msgid "E910: Using a Job as a Number"
+msgstr "E910: Jab á úsáid mar Uimhir"
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Theip ar fheidhm chomparáide le linn sórtála"
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: Cainéal á úsáid mar Uimhir"
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Theip ar fheidhm chomparáide le linn sórtála"
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: Funcref á úsáid mar Shnámhphointe"
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(Neamhbhailí)"
+msgid "E892: Using a String as a Float"
+msgstr "E892: Teaghrán á úsáid mar Shnámhphointe"
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Earráid agus comhad sealadach á scríobh"
+msgid "E893: Using a List as a Float"
+msgstr "E893: Liosta á úsáid mar Shnámhphointe"
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Snámhphointe á úsáid mar Uimhir"
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: Foclóir á úsáid mar Shnámhphointe"
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Funcref á úsáid mar Uimhir"
+msgid "E907: Using a special value as a Float"
+msgstr "E907: Luach speisialta á úsáid mar Shnámhphointe"
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: Liosta á úsáid mar Uimhir"
+msgid "E911: Using a Job as a Float"
+msgstr "E911: Jab á úsáid mar Shnámhphointe"
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Foclóir á úsáid mar Uimhir"
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: Cainéal á úsáid mar Shnámhphointe"
-#: ../eval.c:16259
msgid "E729: using Funcref as a String"
msgstr "E729: Funcref á úsáid mar Theaghrán"
-#: ../eval.c:16262
msgid "E730: using List as a String"
msgstr "E730: Liosta á úsáid mar Theaghrán"
-#: ../eval.c:16265
msgid "E731: using Dictionary as a String"
msgstr "E731: Foclóir á úsáid mar Theaghrán"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Mímheaitseáil idir cineálacha athróige: %s"
+msgid "E908: using an invalid value as a String"
+msgstr "E908: luach neamhbhailí á úsáid mar Theaghrán"
-#: ../eval.c:16705
#, c-format
msgid "E795: Cannot delete variable %s"
msgstr "E795: Ní féidir athróg %s a scriosadh"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
msgstr "E704: Caithfidh ceannlitir a bheith ar dtús ainm Funcref: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: Tagann ainm athróige salach ar fheidhm atá ann cheana: %s"
-#: ../eval.c:16763
#, c-format
msgid "E741: Value is locked: %s"
msgstr "E741: Tá an luach faoi ghlas: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
msgid "Unknown"
msgstr "Anaithnid"
-#: ../eval.c:16768
#, c-format
msgid "E742: Cannot change value of %s"
msgstr "E742: Ní féidir an luach de %s a athrú"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: athróg neadaithe ródhomhain chun í a chóipeáil"
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Feidhm gan sainmhíniú: %s"
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# athróga comhchoiteanna:\n"
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: '(' ar iarraidh: %s"
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tSocraithe is déanaí ó "
-#: ../eval.c:17293
-#, fuzzy
-msgid "E862: Cannot use g: here"
-msgstr "E284: Ní féidir luachanna IC a shocrú"
+msgid "map() argument"
+msgstr "argóint map()"
+
+msgid "filter() argument"
+msgstr "argóint filter()"
-#: ../eval.c:17312
#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Argóint neamhcheadaithe: %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Caithfidh argóint de %s a bheith ina Liosta"
-#: ../eval.c:17323
-#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E125: Argóint neamhcheadaithe: %s"
+msgid "E928: String required"
+msgstr "E928: Teaghrán de dhíth"
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunction ar iarraidh"
+msgid "E808: Number or Float required"
+msgstr "E808: Uimhir nó Snámhphointe de dhíth"
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Tagann ainm na feidhme salach ar athróg: %s"
+msgid "add() argument"
+msgstr "argóint add()"
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr ""
-"E127: Ní féidir sainmhíniú nua a dhéanamh ar fheidhm %s: In úsáid cheana"
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: is féidir complete() a úsáid sa mhód Ionsáite amháin"
+
+#.
+#. * Yes this is ugly, I don't particularly like it either. But doing it
+#. * this way has the compelling advantage that translations need not to
+#. * be touched at all. See below what 'ok' and 'ync' are used for.
+#.
+msgid "&Ok"
+msgstr "&Ok"
-#: ../eval.c:17604
#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr ""
-"E746: Níl ainm na feidhme comhoiriúnach le hainm comhaid na scripte: %s"
+msgid "E700: Unknown function: %s"
+msgstr "E700: Feidhm anaithnid: %s"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: Tá gá le hainm feidhme"
+msgid "E922: expected a dict"
+msgstr "E922: bhíothas ag súil le foclóir"
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgid "E923: Second argument of function() must be a list or a dict"
msgstr ""
-"E128: Caithfidh ceannlitir a bheith ar dtús ainm feidhme, nó idirstad a "
-"bheith ann: %s"
+"E923: Caithfidh an dara hargóint de function() a bheith ina liosta nó ina "
+"foclóir"
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
+msgid ""
+"&OK\n"
+"&Cancel"
msgstr ""
-"E128: Caithfidh ceannlitir a bheith ar dtús ainm feidhme, nó idirstad a "
-"bheith ann: %s"
+"&OK\n"
+"&Cealaigh"
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Ní féidir feidhm %s a scriosadh: Tá sé in úsáid faoi láthair"
+msgid "called inputrestore() more often than inputsave()"
+msgstr "Glaodh inputrestore() níos minice ná inputsave()"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Doimhneacht na nglaonna níos mó ná 'maxfuncdepth'"
+msgid "insert() argument"
+msgstr "argóint insert()"
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "%s á glao"
+msgid "E786: Range not allowed"
+msgstr "E786: Ní cheadaítear an raon"
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s tobscortha"
+msgid "E916: not a valid job"
+msgstr "E916: ní jab bailí é"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: Cineál neamhbhailí le haghaidh len()"
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ag aisfhilleadh #%<PRId64>"
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: Aitheantas in áirithe do \":match\": %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Is nialas í an chéim"
+
+msgid "E727: Start past end"
+msgstr "E727: Tosach thar dheireadh"
+
+msgid "<empty>"
+msgstr "<folamh>"
+
+msgid "E240: No connection to the X server"
+msgstr "E240: Níl aon cheangal leis an bhfreastalaí X"
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s ag aisfhilleadh %s"
+msgid "E241: Unable to send to %s"
+msgstr "E241: Ní féidir aon rud a sheoladh chuig %s"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Ní féidir freagra ón fhreastalaí a léamh"
+
+msgid "E941: already started a server"
+msgstr "E941: tosaíodh freastalaí cheana"
+
+msgid "E942: +clientserver feature not available"
+msgstr "E942: níl an ghné +clientserver ar fáil"
+
+msgid "remove() argument"
+msgstr "argóint remove()"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: An iomarca naisc shiombalacha (ciogal?)"
+
+msgid "reverse() argument"
+msgstr "argóint reverse()"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Ní féidir aon rud a sheoladh chuig an chliant"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "ag leanúint i %s"
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Gníomh neamhbhailí: '%s'"
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: Caithfidh :return a bheith isteach i bhfeidhm"
+msgid "sort() argument"
+msgstr "argóint sort()"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# athróga comhchoiteanna:\n"
+msgid "uniq() argument"
+msgstr "argóint uniq()"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tSocraithe is déanaí ó "
+msgid "E702: Sort compare function failed"
+msgstr "E702: Theip ar fheidhm chomparáide le linn sórtála"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Gan seanchomhaid"
+msgid "E882: Uniq compare function failed"
+msgstr "E882: Theip ar fheidhm chomparáide Uniq"
+
+msgid "(Invalid)"
+msgstr "(Neamhbhailí)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: uimhir fho-mheaitseála neamhbhailí: %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Earráid agus comhad sealadach á scríobh"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: Argóint neamhbhailí ar aisghlaoch"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, Heics %02x, Ocht %03o"
-#: ../ex_cmds.c:145
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, Heics %04x, Ocht %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, Heics %08x, Ocht %o"
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: Bog línte isteach iontu féin"
-#: ../ex_cmds.c:747
msgid "1 line moved"
msgstr "Bogadh líne amháin"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "Bogadh %<PRId64> líne"
+msgid "%ld lines moved"
+msgstr "Bogadh %ld líne"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "Scagadh %<PRId64> líne"
+msgid "%ld lines filtered"
+msgstr "Scagadh %ld líne"
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr ""
"E135: Ní cheadaítear d'uathorduithe *scagaire* an maolán reatha a athrú"
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[Athraithe agus nach sábháilte ó shin]\n"
-#: ../ex_cmds.c:1424
#, c-format
msgid "%sviminfo: %s in line: "
msgstr "%sviminfo: %s i líne: "
-#: ../ex_cmds.c:1431
msgid "E136: viminfo: Too many errors, skipping rest of file"
msgstr ""
"E136: viminfo: An iomarca earráidí, ag scipeáil an chuid eile den chomhad"
-#: ../ex_cmds.c:1458
#, c-format
msgid "Reading viminfo file \"%s\"%s%s%s"
msgstr "Comhad viminfo \"%s\"%s%s%s á léamh"
-#: ../ex_cmds.c:1460
msgid " info"
msgstr " eolas"
-#: ../ex_cmds.c:1461
msgid " marks"
msgstr " marcanna"
-#: ../ex_cmds.c:1462
msgid " oldfiles"
msgstr " seanchomhad"
-#: ../ex_cmds.c:1463
msgid " FAILED"
msgstr " TEIPTHE"
#. 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: Níl an comhad Viminfo inscríofa: %s"
-#: ../ex_cmds.c:1626
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: An iomarca comhad sealadach viminfo, mar shampla %s!"
+
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: Ní féidir comhad viminfo %s a scríobh!"
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "Comhad viminfo \"%s\" á scríobh"
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: Ní féidir ainm %s a chur ar an gcomhad viminfo!"
+
#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# Chruthaigh Vim an comhad viminfo seo %s.\n"
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1141,47 +894,47 @@ msgstr ""
"# Is féidir leat an comhad seo a chur in eagar ach bí cúramach!\n"
"\n"
-#: ../ex_cmds.c:1723
msgid "# Value of 'encoding' when this file was written\n"
msgstr "# Luach 'encoding' agus an comhad seo á scríobh\n"
-#: ../ex_cmds.c:1800
msgid "Illegal starting char"
msgstr "Carachtar neamhcheadaithe tosaigh"
-#: ../ex_cmds.c:2162
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# Barralínte, cóipeáilte focal ar fhocal:\n"
+
+msgid "Save As"
+msgstr "Sábháil Mar"
+
msgid "Write partial file?"
msgstr "Scríobh comhad neamhiomlán?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: Bain úsáid as ! chun maolán neamhiomlán a scríobh"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "Forscríobh comhad \"%s\" atá ann cheana?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Tá comhad babhtála \"%s\" ann cheana; forscríobh mar sin féin?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Tá comhad babhtála ann cheana: %s (úsáid :silent! chun sárú)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Níl aon ainm ar mhaolán %<PRId64>"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Níl aon ainm ar mhaolán %ld"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: Níor scríobhadh an comhad: díchumasaithe leis an rogha 'write'"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1190,7 +943,6 @@ msgstr ""
"tá an rogha 'readonly' socraithe do \"%s\".\n"
"Ar mhaith leat é a scríobh mar sin féin?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1201,85 +953,71 @@ msgstr ""
"Seans gurbh fhéidir scríobh ann mar sin féin.\n"
"An bhfuil fonn ort triail a bhaint as?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: is inléite amháin é \"%s\" (cuir ! leis an ordú chun sárú)"
-#: ../ex_cmds.c:3120
+msgid "Edit File"
+msgstr "Cuir Comhad in Eagar"
+
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: Scrios na huathorduithe maolán nua %s go tobann"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: argóint neamhuimhriúil chun :z"
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: Ní cheadaítear orduithe blaoisce i rvim"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr ""
"E146: Ní cheadaítear litreacha mar theormharcóirí ar shloinn ionadaíochta"
-#: ../ex_cmds.c:3964
#, c-format
msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
msgstr "cuir %s ina ionad (y/n/a/q/l/^E/^Y)?"
-#: ../ex_cmds.c:4379
msgid "(Interrupted) "
msgstr "(Idirbhriste) "
-#: ../ex_cmds.c:4384
msgid "1 match"
msgstr "1 rud comhoiriúnach"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "1 ionadaíocht"
-#: ../ex_cmds.c:4387
#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> rud comhoiriúnach"
+msgid "%ld matches"
+msgstr "%ld rud comhoiriúnach"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> ionadaíocht"
+msgid "%ld substitutions"
+msgstr "%ld ionadaíocht"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " ar líne amháin"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " ar %<PRId64> líne"
+msgid " on %ld lines"
+msgstr " ar %ld líne"
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: Ní cheadaítear :global go hathchúrsach"
+#. will increment global_busy to break out of the loop
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: Ní cheadaítear :global athchúrsach le raon"
# should have ":"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: Slonn ionadaíochta ar iarraidh ó :global"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "Aimsíodh an patrún i ngach líne: %s"
-#: ../ex_cmds.c:4510
-#, fuzzy, c-format
+#, c-format
msgid "Pattern not found: %s"
-msgstr "Patrún gan aimsiú"
+msgstr "Patrún gan aimsiú: %s"
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1289,682 +1027,610 @@ msgstr ""
"# Teaghrán Ionadach Is Déanaí:\n"
"$"
-#: ../ex_cmds.c:4679
msgid "E478: Don't panic!"
msgstr "E478: Ná téigh i scaoll!"
-#: ../ex_cmds.c:4717
#, c-format
msgid "E661: Sorry, no '%s' help for %s"
msgstr "E661: Tá brón orm, ní aon chabhair '%s' do %s"
-#: ../ex_cmds.c:4719
#, c-format
msgid "E149: Sorry, no help for %s"
msgstr "E149: Tá brón orm, níl aon chabhair do %s"
-#: ../ex_cmds.c:4751
#, c-format
msgid "Sorry, help file \"%s\" not found"
msgstr "Tá brón orm, comhad cabhrach \"%s\" gan aimsiú"
-#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Ní comhadlann é: %s"
+msgid "E151: No match: %s"
+msgstr "E151: Gan meaitseáil: %s"
-#: ../ex_cmds.c:5446
#, c-format
msgid "E152: Cannot open %s for writing"
msgstr "E152: Ní féidir %s a oscailt chun scríobh ann"
-#: ../ex_cmds.c:5471
#, c-format
msgid "E153: Unable to open %s for reading"
msgstr "E153: Ní féidir %s a oscailt chun é a léamh"
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: Ionchóduithe éagsúla do chomhaid chabhracha i dteanga aonair: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: Clib dhúblach \"%s\" i gcomhad %s/%s"
-#: ../ex_cmds.c:5687
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ní comhadlann é: %s"
+
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Ordú anaithnid comhartha: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Ainm comhartha ar iarraidh"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: An iomarca comharthaí sainmhínithe"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Téacs neamhbhailí comhartha: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Comhartha anaithnid: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Uimhir chomhartha ar iarraidh"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Ainm maoláin neamhbhailí: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Ní féidir léim go maolán gan ainm"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: ID neamhbhailí comhartha: %<PRId64>"
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ID neamhbhailí comhartha: %ld"
+
+#, c-format
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Ní féidir an comhartha a athrú: %s"
+
+msgid " (NOT FOUND)"
+msgstr " (AR IARRAIDH)"
-#: ../ex_cmds.c:6066
msgid " (not supported)"
msgstr " (níl an rogha seo ar fáil)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[Scriosta]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "Gan seanchomhaid"
+
msgid "Entering Debug mode. Type \"cont\" to continue."
msgstr "Mód dífhabhtaithe á thosú. Clóscríobh \"cont\" chun leanúint."
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "líne %<PRId64>: %s"
+msgid "line %ld: %s"
+msgstr "líne %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "ordú: %s"
-#: ../ex_cmds2.c:322
+msgid "frame is zero"
+msgstr "is nialas é an fráma"
+
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Brisphointe i \"%s%s\" líne %<PRId64>"
+msgid "frame at highest level: %d"
+msgstr "fráma ag an leibhéal is airde: %d"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Brisphointe i \"%s%s\" líne %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Brisphointe gan aimsiú: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Níl aon bhrisphointe socraithe"
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s líne %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s líne %ld"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: Úsáid \":profile start {ainm}\" ar dtús"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Sábháil athruithe ar \"%s\"?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
msgid "Untitled"
msgstr "Gan Teideal"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Athraíodh maolán \"%s\" ach nach bhfuil sé sábháilte ó shin"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "Rabhadh: Chuathas i maolán eile go tobann (seiceáil na huathorduithe)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: Níl ach aon chomhad amháin le cur in eagar"
-#: ../ex_cmds2.c:1828
msgid "E164: Cannot go before first file"
msgstr "E164: Ní féidir a dhul roimh an chéad chomhad"
-#: ../ex_cmds2.c:1830
msgid "E165: Cannot go beyond last file"
msgstr "E165: Ní féidir a dhul thar an gcomhad deireanach"
-#: ../ex_cmds2.c:2175
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: ní ghlactar leis an tiomsaitheoir: %s"
-#: ../ex_cmds2.c:2257
#, c-format
msgid "Searching for \"%s\" in \"%s\""
msgstr "Ag déanamh cuardach ar \"%s\" i \"%s\""
-#: ../ex_cmds2.c:2284
#, c-format
msgid "Searching for \"%s\""
msgstr "Ag déanamh cuardach ar \"%s\""
-#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "gan aimsiú i 'runtimepath': \"%s\""
+msgid "not found in '%s': \"%s\""
+msgstr "gan aimsiú in '%s': \"%s\""
+
+#, c-format
+msgid "W20: Required python version 2.x not supported, ignoring file: %s"
+msgstr "W20: Níl leagan 2.x de Python ar fáil; ag déanamh neamhaird de %s"
+
+#, c-format
+msgid "W21: Required python version 3.x not supported, ignoring file: %s"
+msgstr "W21: Níl leagan 3.x de Python ar fáil; ag déanamh neamhaird de %s"
+
+msgid "Source Vim script"
+msgstr "Foinsigh script Vim"
-#: ../ex_cmds2.c:2472
#, c-format
msgid "Cannot source a directory: \"%s\""
msgstr "Ní féidir comhadlann a léamh: \"%s\""
-#: ../ex_cmds2.c:2518
#, c-format
msgid "could not source \"%s\""
msgstr "níorbh fhéidir \"%s\" a léamh"
-#: ../ex_cmds2.c:2520
#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "líne %<PRId64>: níorbh fhéidir \"%s\" a fhoinsiú"
+msgid "line %ld: could not source \"%s\""
+msgstr "líne %ld: níorbh fhéidir \"%s\" a fhoinsiú"
-#: ../ex_cmds2.c:2535
#, c-format
msgid "sourcing \"%s\""
msgstr "\"%s\" á fhoinsiú"
-#: ../ex_cmds2.c:2537
#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "líne %<PRId64>: \"%s\" á fhoinsiú"
+msgid "line %ld: sourcing \"%s\""
+msgstr "líne %ld: \"%s\" á fhoinsiú"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "deireadh ag foinsiú %s"
-#: ../ex_cmds2.c:2765
+#, c-format
+msgid "continuing in %s"
+msgstr "ag leanúint i %s"
+
msgid "modeline"
msgstr "módlíne"
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "argóint --cmd"
-#: ../ex_cmds2.c:2769
msgid "-c argument"
msgstr "argóint -c"
-#: ../ex_cmds2.c:2771
msgid "environment variable"
msgstr "athróg thimpeallachta"
-#: ../ex_cmds2.c:2773
msgid "error handler"
msgstr "láimhseálaí earráidí"
-#: ../ex_cmds2.c:3020
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr ""
"W15: Rabhadh: Deighilteoir línte mícheart, is féidir go bhfuil ^M ar iarraidh"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: ní úsáidtear :scriptencoding ach i gcomhad foinsithe"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: ní úsáidtear :finish ach i gcomhaid foinsithe"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "%sTeanga faoi láthair: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Ní féidir an teanga a shocrú mar \"%s\""
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "Mód Ex á thosú. Clóscríobh \"visual\" le haghaidh an ghnáthmhód."
# in FARF -KPS
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: Ag an chomhadchríoch"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Ordú ró-athchúrsach"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Eisceacht gan láimhseáil: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Críoch chomhaid foinsithe"
-#: ../ex_docmd.c:1086
msgid "End of function"
msgstr "Críoch fheidhme"
-#: ../ex_docmd.c:1628
msgid "E464: Ambiguous use of user-defined command"
msgstr "E464: Úsáid athbhríoch d'ordú saincheaptha"
-#: ../ex_docmd.c:1638
msgid "E492: Not an editor command"
msgstr "E492: Níl ina ordú eagarthóra"
-#: ../ex_docmd.c:1729
msgid "E493: Backwards range given"
msgstr "E493: Raon droim ar ais"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "Raon droim ar ais, babhtáil"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: Bain úsáid as w nó w>>"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
+msgid "E943: Command table needs to be updated, run 'make cmdidxs'"
+msgstr "E943: Caithfear tábla na n-orduithe a nuashonrú; rith 'make cmdidxs'"
+
+msgid "E319: Sorry, the command is not available in this version"
msgstr "E319: Tá brón orm, níl an t-ordú ar fáil sa leagan seo"
-#: ../ex_docmd.c:3752
msgid "E172: Only one file name allowed"
msgstr "E172: Ní cheadaítear ach aon ainm comhaid amháin"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
msgstr "1 comhad le cur in eagar fós. Scoir mar sin féin?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
msgstr "%d comhad le cur in eagar fós. Scoir mar sin féin?"
-#: ../ex_docmd.c:4248
msgid "E173: 1 more file to edit"
msgstr "E173: 1 chomhad le heagrú fós"
-#: ../ex_docmd.c:4250
#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: %<PRId64> comhad le cur in eagar"
+msgid "E173: %ld more files to edit"
+msgstr "E173: %ld comhad le cur in eagar"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: Tá an t-ordú ann cheana: cuir ! leis chun sárú"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
-" Name Args Range Complete Definition"
+" Name Args Address Complete Definition"
msgstr ""
"\n"
-" Ainm Arg Raon Iomlán Sainmhíniú"
+" Ainm Arg Seoladh Iomlán Sainmhíniú"
-#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
msgstr "Níl aon ordú aimsithe atá sainithe ag an úsáideoir"
-#: ../ex_docmd.c:4538
msgid "E175: No attribute specified"
msgstr "E175: Níl aon aitreabúid sainithe"
-#: ../ex_docmd.c:4583
msgid "E176: Invalid number of arguments"
msgstr "E176: Tá líon na n-argóintí mícheart"
-#: ../ex_docmd.c:4594
msgid "E177: Count cannot be specified twice"
msgstr "E177: Ní cheadaítear an t-áireamh a bheith tugtha faoi dhó"
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: Luach réamhshocraithe neamhbhailí ar áireamh"
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: tá gá le hargóint i ndiaidh -complete"
-#: ../ex_docmd.c:4635
+msgid "E179: argument required for -addr"
+msgstr "E179: tá gá le hargóint i ndiaidh -addr"
+
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Aitreabúid neamhbhailí: %s"
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Ainm neamhbhailí ordaithe"
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr ""
"E183: Caithfidh ceannlitir a bheith ar dtús orduithe atá sainithe ag an "
"úsáideoir"
-#: ../ex_docmd.c:4696
-#, fuzzy
msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E464: Úsáid athbhríoch d'ordú saincheaptha"
+msgstr ""
+"E841: Ainm in áirithe, ní féidir é a chur ar ordú sainithe ag an úsáideoir"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: Níl a leithéid d'ordú saincheaptha: %s"
-#: ../ex_docmd.c:5219
+#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: Cineál neamhbhailí seolta: %s"
+
#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: Luach iomlán neamhbhailí: %s"
-#: ../ex_docmd.c:5225
msgid "E468: Completion argument only allowed for custom completion"
msgstr ""
"E468: Ní cheadaítear argóint chomhlánaithe ach le comhlánú saincheaptha"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: Tá gá le hargóint fheidhme le comhlánú saincheaptha"
-#: ../ex_docmd.c:5257
-#, fuzzy, c-format
+msgid "unknown"
+msgstr "anaithnid"
+
+#, c-format
msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Scéim dathanna %s gan aimsiú"
+msgstr "E185: Scéim dathanna '%s' gan aimsiú"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Dia duit, a úsáideoir Vim!"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
-msgstr "E784: Ní féidir an leathanach cluaisín deiridh a dhúnadh"
+msgstr "E784: Ní féidir an leathanach cluaisíní deiridh a dhúnadh"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
-msgstr "Níl ach leathanach cluaisín amháin cheana féin"
+msgstr "Níl ach leathanach cluaisíní amháin cheana féin"
+
+msgid "Edit File in new window"
+msgstr "Cuir comhad in eagar i bhfuinneog nua"
-#: ../ex_docmd.c:6004
#, c-format
msgid "Tab page %d"
msgstr "Leathanach cluaisín %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "Níl aon chomhad babhtála ann"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "Ceangail Comhad ag an Deireadh"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
"E747: Ní féidir an chomhadlann a athrú, mionathraíodh an maolán (cuir ! leis "
"an ordú chun sárú)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Níl aon chomhadlann roimhe seo"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Anaithnid"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: ní foláir dhá argóint uimhriúla le :winsize"
-#: ../ex_docmd.c:6655
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Ionad na fuinneoige: X %d, Y %d"
+
msgid "E188: Obtaining window position not implemented for this platform"
-msgstr "E188: Ní féidir ionad na fuinneoige a fháil amach ar an chóras seo"
+msgstr "E188: Ní féidir ionad na fuinneoige a fháil amach ar an gcóras seo"
-#: ../ex_docmd.c:6662
msgid "E466: :winpos requires two number arguments"
-msgstr "E466: ní foláir dhá argóint uimhriúla le :winpos"
+msgstr "E466: dhá argóint uimhriúla de dhíth le :winpos"
+
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: Ní féidir :redir a úsáid laistigh de execute()"
+
+msgid "Save Redirection"
+msgstr "Sábháil Atreorú"
+
+msgid "Save View"
+msgstr "Sábháil an tAmharc"
+
+msgid "Save Session"
+msgstr "Sábháil an Seisiún"
+
+msgid "Save Setup"
+msgstr "Sábháil an Socrú"
-#: ../ex_docmd.c:7241
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: Ní féidir comhadlann a chruthú: %s"
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: Tá \"%s\" ann cheana (cuir ! leis an ordú chun sárú)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Ní féidir \"%s\" a oscailt chun léamh"
#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: Caithfidh an argóint a bheith litir nó comhartha athfhriotal"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: athchúrsáil :normal ródhomhain"
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: níl #< ar fáil gan ghné +eval"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: Níl aon ainm comhaid a chur in ionad '#'"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: níl aon ainm comhaid uathordaithe le cur in ionad \"<afile>\""
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: níl aon uimhir mhaolán uathordaithe le cur in ionad \"<abuf>\""
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr ""
"E497: níl aon ainm meaitseála uathordaithe le cur in ionad \"<amatch>\""
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: níl aon ainm comhaid :source le cur in ionad \"<sfile>\""
-#: ../ex_docmd.c:7876
-#, fuzzy
msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: níl aon ainm comhaid :source le cur in ionad \"<sfile>\""
+msgstr "E842: níl aon líne-uimhir ar fáil le haghaidh \"<slnum>\""
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr ""
"E499: Ainm comhaid folamh le haghaidh '%' nó '#', oibreoidh sé le \":p:h\" "
"amháin"
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: Luacháiltear é seo mar theaghrán folamh"
-#: ../ex_docmd.c:8838
msgid "E195: Cannot open viminfo file for reading"
msgstr "E195: Ní féidir an comhad viminfo a oscailt chun léamh"
-#: ../ex_eval.c:464
+msgid "E196: No digraphs in this version"
+msgstr "E196: Ní cheadaítear déghraif sa leagan seo"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: Ní féidir eisceachtaí a :throw le réimír 'Vim'"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Gineadh eisceacht: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "Eisceacht curtha i gcrích: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Eisceacht curtha i leataobh: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, líne %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, líne %ld"
#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Láimhseáladh eisceacht: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s ar feitheamh anois"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "atosaíodh %s"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s curtha i leataobh"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Eisceacht"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Earráid agus idirbhriseadh"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Earráid"
#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Idirbhriseadh"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: :if neadaithe ródhomhain"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :endif gan :if"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :else gan :if"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :elseif gan :if"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: :else iomadúla"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :elseif i ndiaidh :else"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: :while/:for neadaithe ródhomhain"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :continue gan :while ná :for"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :break gan :while ná :for"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: :endfor á úsáid le :while"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: :endwhile á úsáid le :for"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: :try neadaithe ródhomhain"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :catch gan :try"
#. Give up for a ":catch" after ":finally" and ignore it.
#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :catch i ndiaidh :finally"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :finally gan :try"
#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: :finally iomadúla"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :endtry gan :try"
-#: ../ex_eval.c:2026
msgid "E193: :endfunction not inside a function"
msgstr "E193: Caithfidh :endfunction a bheith isteach i bhfeidhm"
-#: ../ex_getln.c:1643
msgid "E788: Not allowed to edit another buffer now"
msgstr "E788: Níl cead agat maolán eile a chur in eagar anois"
-#: ../ex_getln.c:1656
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: Níl cead agat faisnéis an mhaoláin a athrú anois"
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "clibainm"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " cineál comhaid\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "tá an rogha 'history' nialas"
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -1975,310 +1641,230 @@ msgstr ""
# this gets plugged into the %s in the previous string,
# hence the colon
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "Líne na nOrduithe:"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "Teaghrán Cuardaigh"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "Sloinn:"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "Líne an Ionchuir:"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "Líne Dhífhabhtaithe"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar os cionn fad an ordaithe"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Scriosadh an fhuinneog reatha nó an maolán reatha"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr ""
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Conair neamhbhailí: ní mór '**[uimhir]' a bheith ag deireadh na "
-"conaire, nó le '%s' ina dhiaidh."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Ní féidir comhadlann \"%s\" a aimsiú sa cdpath"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Ní féidir comhad \"%s\" a aimsiú sa chonair"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Níl comhadlann \"%s\" sa cdpath a thuilleadh"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Níl comhad \"%s\" sa chonair a thuilleadh"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: Bhí maolán nó ainm maoláin athraithe ag orduithe uathoibríocha"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Ainm comhaid neamhcheadaithe"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "is comhadlann é"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "ní comhad é"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "is gléas é seo (díchumasaithe le rogha 'opendevice')"
+
msgid "[New File]"
msgstr "[Comhad Nua]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[COMHADLANN nua]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[Comhad rómhór]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Cead Diúltaithe]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: Rinne uathorduithe *ReadPre praiseach as an chomhad"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: Ní cheadaítear d'uathorduithe *ReadPre an maolán reatha a athrú"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim: Ag léamh ón ionchur caighdeánach...\n"
+msgid "Reading from stdin..."
+msgstr "Ag léamh ón ionchur caighdeánach..."
+
#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: Comhad doléite i ndiaidh an tiontaithe!"
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[fifo/soicéad]"
# `TITA' ?! -KPS
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[fifo]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[soicéad]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[comhad speisialta den chineál carachtar]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR ar iarraidh]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[línte fada deighilte]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[NÍ tiontaithe]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[tiontaithe]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[EARRÁID TIONTAITHE i líne %<PRId64>]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[EARRÁID TIONTAITHE i líne %ld]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[BEART NEAMHCHEADAITHE i líne %<PRId64>]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[BEART NEAMHCHEADAITHE i líne %ld]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[EARRÁIDÍ LÉIMH]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "Ní féidir comhad sealadach a aimsiú le haghaidh tiontaithe"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "Theip ar thiontú le 'charconvert'"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "ní féidir an t-aschur ó 'charconvert' a léamh"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Níl aon uathordú comhoiriúnaithe le haghaidh maoláin acwrite"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: Scrios nó dhíluchtaigh uathorduithe an maolán le scríobh"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: D'athraigh uathordú líon na línte gan choinne"
-#: ../fileio.c:2548 ../fileio.c:2565
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "Ní cheadaíonn NetBeans maoláin gan athrú a bheith scríofa"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Ní cheadaítear maoláin NetBeans a bheith scríofa go neamhiomlán"
+
msgid "is not a file or writable device"
msgstr "ní comhad ná gléas inscríofa á"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "díchumasaíodh scríobh chuig gléas le rogha 'opendevice'"
+
msgid "is read-only (add ! to override)"
msgstr "is inléite amháin é (cuir ! leis an ordú chun sárú)"
-#: ../fileio.c:2886
msgid "E506: Can't write to backup file (add ! to override)"
msgstr ""
"E506: Ní féidir scríobh a dhéanamh sa chomhad cúltaca (úsáid ! chun sárú)"
-#: ../fileio.c:2898
msgid "E507: Close error for backup file (add ! to override)"
msgstr ""
"E507: Earráid agus comhad cúltaca á dhúnadh (cuir ! leis an ordú chun sárú)"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr ""
"E508: Ní féidir an comhad cúltaca a léamh (cuir ! leis an ordú chun sárú)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr ""
"E509: Ní féidir comhad cúltaca a chruthú (cuir ! leis an ordú chun sárú)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr ""
"E510: Ní féidir comhad cúltaca a chruthú (cuir ! leis an ordú chun sárú)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
+msgid "E460: The resource fork would be lost (add ! to override)"
+msgstr "E460: Chaillfí an forc acmhainne (cuir ! leis an ordú chun sárú)"
+
msgid "E214: Can't find temp file for writing"
msgstr "E214: Ní féidir comhad sealadach a aimsiú chun scríobh ann"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: Ní féidir tiontú (cuir ! leis an ordú chun scríobh gan tiontú)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Ní féidir comhad nasctha a oscailt chun scríobh ann"
-#: ../fileio.c:3173
msgid "E212: Can't open file for writing"
msgstr "E212: Ní féidir comhad a oscailt chun scríobh ann"
-#: ../fileio.c:3363
msgid "E667: Fsync failed"
msgstr "E667: Theip ar fsync"
-#: ../fileio.c:3398
msgid "E512: Close failed"
msgstr "E512: Theip ar dúnadh"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
msgstr ""
"E513: earráid le linn scríobh, theip ar thiontú (úsáid 'fenc' folamh chun "
"sárú)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: earráid le linn scríofa, theip ar thiontú ar líne %<PRId64> (úsáid "
-"'fenc' folamh le sárú)"
+"E513: earráid le linn scríofa, theip ar thiontú ar líne %ld (úsáid 'fenc' "
+"folamh le sárú)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: earráid le linn scríofa (an bhfuil an córas comhaid lán?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " EARRÁID TIONTAITHE"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " ar líne %<PRId64>;"
+msgid " in line %ld;"
+msgstr " ar líne %ld;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[Gléas]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Nua]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " iarcheangailte"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " scríofa"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: Patchmode: ní féidir an comhad bunúsach a shábháil"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: ní féidir an comhad bunúsach folamh a theagmháil"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Ní féidir an comhad cúltaca a scriosadh"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2286,96 +1872,75 @@ msgstr ""
"\n"
"RABHADH: Is féidir gur caillte nó loite an comhad bunúsach\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "ná scoir go dtí go scríobhfaí an comhad!"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[formáid dos]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[formáid mac]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[formáid unix]"
-#: ../fileio.c:3831
msgid "1 line, "
msgstr "1 líne, "
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> líne, "
+msgid "%ld lines, "
+msgstr "%ld líne, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 carachtar"
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> carachtar"
+msgid "%lld characters"
+msgstr "%lld carachtar"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[ganEOL]"
-#: ../fileio.c:3849
msgid "[Incomplete last line]"
msgstr "[Is neamhiomlán an líne dheireanach]"
#. don't overwrite messages here
#. must give this prompt
#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "RABHADH: Athraíodh an comhad ó léadh é!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "An bhfuil tú cinnte gur mhaith leat é a scríobh"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Earráid agus \"%s\" á scríobh"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Earráid agus \"%s\" á dhúnadh"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Earráid agus \"%s\" á léamh"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: Scrios uathordú FileChangedShell an maolán"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: Níl comhad \"%s\" ar fáil feasta"
-#: ../fileio.c:4906
#, c-format
msgid ""
"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
@@ -2383,39 +1948,31 @@ msgid ""
msgstr ""
"W12: Rabhadh: Athraíodh comhad \"%s\" agus athraíodh an maolán i Vim fosta"
-#: ../fileio.c:4907
msgid "See \":help W12\" for more info."
msgstr "Bain triail as \":help W12\" chun tuilleadh eolais a fháil."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: Rabhadh: Athraíodh comhad \"%s\" ó tosaíodh é a chur in eagar"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "Bain triail as \":help W11\" chun tuilleadh eolais a fháil."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr ""
"W16: Rabhadh: Athraíodh mód an chomhaid \"%s\" ó tosaíodh é a chur in eagar"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "Bain triail as \":help W16\" chun tuilleadh eolais a fháil."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: Rabhadh: Cruthaíodh comhad \"%s\" ó tosaíodh é a chur in eagar"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "Rabhadh"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2423,819 +1980,604 @@ msgstr ""
"&OK\n"
"&Luchtaigh Comhad"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Ní féidir \"%s\" a ullmhú le haghaidh athluchtaithe"
-#: ../fileio.c:5078
#, c-format
msgid "E321: Could not reload \"%s\""
msgstr "E321: Ní féidir \"%s\" a athluchtú"
-#: ../fileio.c:5601
msgid "--Deleted--"
msgstr "--Scriosta--"
-#: ../fileio.c:5732
#, c-format
msgid "auto-removing autocommand: %s <buffer=%d>"
msgstr "uathordú á bhaint go huathoibríoch: %s <maolán=%d>"
#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: Níl a leithéid de ghrúpa: \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Ní féidir an grúpa reatha a scriosadh"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: Iarracht ar augroup atá fós in úsáid a scriosadh"
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: Carachtar neamhcheadaithe i ndiaidh *: %s"
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: Níl a leithéid de theagmhas: %s"
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: Níl a leithéid de ghrúpa nó theagmhas: %s"
#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Uathorduithe ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <maolán=%d>: uimhir neamhbhailí mhaoláin "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Ní féidir uathorduithe a rith i gcomhair teagmhas UILE"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "Níl aon uathordú comhoiriúnaithe"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: uathordú neadaithe ródhomhain"
-#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Uathorduithe do \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "%s á rith"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "uathordú %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { ar iarraidh."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } ar iarraidh."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: Níor aimsíodh aon fhilleadh"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: Ní féidir filleadh a chruthú leis an 'foldmethod' reatha"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: Ní féidir filleadh a scriosadh leis an 'foldmethod' reatha"
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld líne fillte "
-
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: Cuir leis an maolán léite"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
msgstr "E223: mapáil athchúrsach"
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: tá giorrúchán comhchoiteann ann cheana le haghaidh %s"
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
msgstr "E225: tá mapáil chomhchoiteann ann cheana le haghaidh %s"
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: tá giorrúchán ann cheana le haghaidh %s"
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
msgstr "E227: tá mapáil ann cheana le haghaidh %s"
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "Níor aimsíodh aon ghiorrúchán"
-#: ../getchar.c:3010
msgid "No mapping found"
msgstr "Níor aimsíodh aon mhapáil"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: Mód neamhcheadaithe"
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--Tá an maolán folamh--"
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: Níorbh fhéidir próiseas nua a chruthú don GUI"
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: Ordú tobscortha"
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: Theip ar an macphróiseas an GUI a thosú"
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: Tá gá le hargóint"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: Ní féidir an GUI a chur ag obair"
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: Ba chóir /, ? nó & a chur i ndiaidh \\"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr ""
-"E11: Neamhbhailí i bhfuinneog líne na n-orduithe; <CR>=rith, CTRL-C=scoir"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Ní féidir léamh ó \"%s\""
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgid "E665: Cannot start GUI, no valid font found"
msgstr ""
-"E12: Ní cheadaítear ordú ó exrc/vimrc sa chomhadlann reatha ná ó chuardach "
-"clibe"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif ar iarraidh"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry ar iarraidh"
+"E665: Ní féidir an GUI a chur ag obair, níl aon chlófhoireann bhailí ann"
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile ar iarraidh"
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' neamhbhailí"
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor ar iarraidh"
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: Luach neamhbhailí ar 'imactivatekey'"
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile gan :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor gan :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Tá comhad ann cheana (cuir ! leis an ordú chun forscríobh)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: Theip ar ordú"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: Earráid inmheánach"
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Ní féidir dath %s a dháileadh"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Idirbhriste"
+msgid "No match at cursor, finding next"
+msgstr "Níl a leithéid ag an chúrsóir, ag cuardach ar an chéad cheann eile"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Drochsheoladh"
+msgid "<cannot open> "
+msgstr "<ní féidir a oscailt> "
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Argóint neamhbhailí"
-
-#: ../globals.h:1015
#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Argóint neamhbhailí: %s"
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: níl aon fháil ar an chlófhoireann %s"
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Slonn neamhbhailí: %s"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: ní féidir dul ar ais go dtí an chomhadlann reatha"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Raon neamhbhailí"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Ordú neamhbhailí"
+msgid "Pathname:"
+msgstr "Conair:"
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: is comhadlann \"%s\""
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: níl an chomhadlann reatha ar fáil"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Méid neamhbhailí scrollaithe"
+msgid "OK"
+msgstr "OK"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+msgid "Cancel"
+msgstr "Cealaigh"
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
msgstr ""
+"Giuirléid Scrollbharra: Ní féidir céimseata an mhapa picteilíní a fháil."
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Theip ar ghlao leabharlainne \"%s()\""
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: Tá líne-uimhir neamhbhailí ag an mharc"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Marc gan socrú"
+msgid "Vim dialog"
+msgstr "Dialóg Vim"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
+msgid "E232: Cannot create BalloonEval with both message and callback"
msgstr ""
-"E21: Ní féidir athruithe a chur i bhfeidhm, níl an bhratach 'modifiable' "
-"socraithe"
+"E232: Ní féidir BalloonEval a chruthú le teachtaireacht agus aisghlaoch araon"
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: scripteanna neadaithe ródhomhain"
+msgid "_Cancel"
+msgstr "_Cealaigh"
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Níl aon chomhad malartach"
+msgid "_Save"
+msgstr "_Sábháil"
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Níl a leithéid de ghiorrúchán ann"
+msgid "_Open"
+msgstr "_Oscail"
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: Ní cheadaítear !"
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: Ní féidir an GUI a úsáid: Níor cumasaíodh é ag am tiomsaithe"
+msgid "_OK"
+msgstr "_OK"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Níl a leithéid d'ainm grúpa aibhsithe: %s"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Tá\n"
+"&Níl\n"
+"&Cealaigh"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: Níl aon téacs ionsáite go dtí seo"
+msgid "Yes"
+msgstr "Tá"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Níl aon líne na n-orduithe roimhe seo"
+msgid "No"
+msgstr "Níl"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Níl a leithéid de mhapáil"
+msgid "Input _Methods"
+msgstr "_Modhanna ionchuir"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Níl aon rud comhoiriúnach ann"
+# in OLT --KPS
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Cuardaigh agus Athchuir..."
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Níl aon rud comhoiriúnach ann: %s"
+msgid "VIM - Search..."
+msgstr "VIM - Cuardaigh..."
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Níl aon ainm comhaid"
+msgid "Find what:"
+msgstr "Aimsigh:"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Níl aon slonn ionadaíochta roimhe seo"
+msgid "Replace with:"
+msgstr "Le cur in ionad:"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Níl aon ordú roimhe seo"
+#. whole word only button
+msgid "Match whole word only"
+msgstr "Focal iomlán amháin"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Níl aon slonn ionadaíochta roimhe seo"
+#. match case button
+msgid "Match case"
+msgstr "Meaitseáil an cás"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Ní cheadaítear raon"
+msgid "Direction"
+msgstr "Treo"
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: Níl slí a dhóthain ann"
+#. 'Up' and 'Down' buttons
+msgid "Up"
+msgstr "Suas"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Ní féidir comhad %s a chruthú"
+msgid "Down"
+msgstr "Síos"
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Níl aon fháil ar ainm comhaid sealadach"
+msgid "Find Next"
+msgstr "An Chéad Cheann Eile"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Ní féidir comhad %s a oscailt"
+msgid "Replace"
+msgstr "Ionadaigh"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: Ní féidir comhad %s a léamh"
+msgid "Replace All"
+msgstr "Ionadaigh Uile"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: Tá athruithe ann gan sábháil (cuir ! leis an ordú chun sárú)"
+msgid "_Close"
+msgstr "_Dún"
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Athraithe agus nach sábháilte ó shin]\n"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Fuarthas iarratas \"die\" ó bhainisteoir an tseisiúin\n"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: Argóint nialasach"
+msgid "Close tab"
+msgstr "Dún cluaisín"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Ag súil le huimhir"
+msgid "New tab"
+msgstr "Cluaisín nua"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Ní féidir an comhad earráide %s a oscailt"
+msgid "Open Tab..."
+msgstr "Oscail Cluaisín..."
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Cuimhne ídithe!"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Milleadh an príomhfhuinneog gan choinne\n"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Patrún gan aimsiú"
+msgid "&Filter"
+msgstr "&Scagaire"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Patrún gan aimsiú: %s"
+msgid "&Cancel"
+msgstr "&Cealaigh"
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: Ní foláir argóint dheimhneach"
+msgid "Directories"
+msgstr "Comhadlanna"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Ní féidir a fhilleadh ar an chomhadlann roimhe seo"
+msgid "Filter"
+msgstr "Scagaire"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Níl Aon Earráid Ann"
+msgid "&Help"
+msgstr "&Cabhair"
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Gan liosta suíomh"
+msgid "Files"
+msgstr "Comhaid"
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: Teaghrán cuardaigh loite"
+msgid "&OK"
+msgstr "&OK"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: Clár na sloinn ionadaíochta truaillithe"
+msgid "Selection"
+msgstr "Roghnú"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: tá an rogha 'readonly' socraithe (cuir ! leis an ordú chun sárú)"
+msgid "Find &Next"
+msgstr "An Chéad Chea&nn Eile"
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Ní féidir athróg inléite amháin \"%s\" a athrú"
+msgid "&Replace"
+msgstr "&Ionadaigh"
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Ní féidir athróg a shocrú sa bhosca gainimh: \"%s\""
+msgid "Replace &All"
+msgstr "Ionadaigh &Uile"
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Earráid agus comhad earráide á léamh"
+msgid "&Undo"
+msgstr "&Cealaigh"
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Ní cheadaítear é seo i mbosca gainimh"
+msgid "Open tab..."
+msgstr "Oscail cluaisín..."
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Ní cheadaítear é anseo"
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Aimsigh teaghrán (bain úsáid as '\\\\' chun '\\' a aimsiú)"
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: Ní féidir an mód scáileáin a shocrú"
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Aimsigh & Athchuir (úsáid '\\\\' chun '\\' a aimsiú)"
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Méid neamhbhailí scrollaithe"
+#. We fake this: Use a filter that doesn't select anything and a default
+#. * file name that won't be used.
+msgid "Not Used"
+msgstr "Gan Úsáid"
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: rogha 'shell' folamh"
+msgid "Directory\t*.nothing\n"
+msgstr "Comhadlann\t*.neamhní\n"
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Níorbh fhéidir na sonraí comhartha a léamh!"
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: Ní féidir teideal na fuinneoige \"%s\" a aimsiú"
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: Earráid agus comhad babhtála á dhúnadh"
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Argóint gan tacaíocht: \"-%s\"; Bain úsáid as an leagan OLE."
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: tá cruach na gclibeanna folamh"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Ní féidir fuinneog a oscailt isteach i bhfeidhmchlár MDI"
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Ordú róchasta"
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: Ní féidir iontráil dathmhapála a dháileadh, is féidir go mbeidh "
+"dathanna míchearta ann"
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Ainm rófhada"
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr ""
+"E250: Clónna ar iarraidh le haghaidh na dtacar carachtar i dtacar cló %s:"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: an iomarca ["
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Ainm an tacar cló: %s"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: An iomarca ainmneacha comhaid"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Ní cló aonleithid é '%s'"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Carachtair chun deiridh"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Ainm an tacar cló: %s"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Marc anaithnid"
+#, c-format
+msgid "Font0: %s"
+msgstr "Cló0: %s"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Ní féidir saoróga a leathnú"
+#, c-format
+msgid "Font1: %s"
+msgstr "Cló1: %s"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: ní cheadaítear 'winheight' a bheith níos lú ná 'winminheight'"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Níl Cló%ld níos leithne faoi dhó ná cló0"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: ní cheadaítear 'winwidth' a bheith níos lú ná 'winminwidth'"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Leithead Cló0: %ld"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: Earráid agus á scríobh"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Leithead cló1: %ld"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Nialas"
+msgid "Invalid font specification"
+msgstr "Sonrú neamhbhailí cló"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: <SID> á úsáid nach i gcomhthéacs scripte"
+msgid "&Dismiss"
+msgstr "&Ruaig"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Earráid inmheánach: %s"
+msgid "no specific match"
+msgstr "níl a leithéid ann"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: úsáideann an patrún níos mó cuimhne ná 'maxmempattern'"
+msgid "Vim - Font Selector"
+msgstr "Vim - Roghnú Cló"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: maolán folamh"
+msgid "Name:"
+msgstr "Ainm:"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Patrún nó teormharcóir neamhbhailí cuardaigh"
+#. create toggle button
+msgid "Show size in Points"
+msgstr "Taispeáin méid (Pointí)"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Tá an comhad luchtaithe i maolán eile"
+msgid "Encoding:"
+msgstr "Ionchódú:"
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: Rogha '%s' gan socrú"
+msgid "Font:"
+msgstr "Cló:"
-#: ../globals.h:1111
-#, fuzzy
-msgid "E850: Invalid register name"
-msgstr "E354: Ainm neamhbhailí tabhaill: '%s'"
+msgid "Style:"
+msgstr "Stíl:"
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "Buaileadh an BARR le linn an chuardaigh, ag leanúint ag an CHRÍOCH"
+msgid "Size:"
+msgstr "Méid:"
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "Buaileadh an BUN le linn an chuardaigh, ag leanúint ag an BHARR"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: EARRÁID leis na huathoibreáin Hangul"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: Idirstad ar iarraidh"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: Comhpháirt neamhcheadaithe"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: ag súil le digit"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "Leathanach %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "Níl aon téacs le priontáil"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "Leathanach %d (%d%%) á phriontáil"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " Cóip %d de %d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Priontáilte: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Priontáil tobscortha"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: Earráid le linn scríobh chuig aschomhad PostScript"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Ní féidir an comhad \"%s\" a oscailt"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Ní féidir comhad acmhainne PostScript \"%s\" a léamh"
-#: ../hardcopy.c:1772
#, c-format
msgid "E618: file \"%s\" is not a PostScript resource file"
msgstr "E618: Níl comhad \"%s\" ina chomhad acmhainne PostScript"
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: Tá \"%s\" ina chomhad acmhainne PostScript gan tacú"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: Tá an leagan mícheart ar an gcomhad acmhainne \"%s\""
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: Ionchódú agus tacar carachtar ilbhirt neamh-chomhoiriúnach."
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr ""
"E674: ní cheadaítear printmbcharset a bheith folamh le hionchódú ilbhirt."
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Níor réamhshocraíodh cló le haghaidh priontála ilbhirt."
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: Ní féidir aschomhad PostScript a oscailt"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Ní féidir an comhad \"%s\" a oscailt"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: Comhad acmhainne PostScript \"prolog.ps\" gan aimsiú"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: Comhad acmhainne PostScript \"cidfont.ps\" gan aimsiú"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: Comhad acmhainne PostScript \"%s.ps\" gan aimsiú"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: Ní féidir an t-ionchódú priontála \"%s\" a thiontú"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "Á sheoladh chuig an phrintéir..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: Theip ar phriontáil comhaid PostScript"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "Seoladh jab priontála."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "Bunachar sonraí nua"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Iarratas ar phatrún"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "Taispeáin an teachtaireacht seo"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Maraigh nasc"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Atúsaigh gach nasc"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Taispeáin naisc"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: Úsáid: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "Ní féidir fuinneoga a scoilteadh leis an ordú seo `cscope'.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: Úsáid: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag: clib gan aimsiú"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: earráid stat(%s): %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: earráid stat"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: Níl %s ina comhadlann nó bunachar sonraí cscope bailí"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "Bunachar sonraí nua cscope: %s"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: earráid agus an nasc cscope %<PRId64> á léamh"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: earráid agus an nasc cscope %ld á léamh"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: cineál anaithnid cuardaigh cscope"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Níorbh fhéidir píopaí cscope a chruthú"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Níorbh fhéidir forc a dhéanamh le haghaidh cscope"
-#: ../if_cscope.c:849
-#, fuzzy
msgid "cs_create_connection setpgid failed"
-msgstr "theip ar rith cs_create_connection"
+msgstr "theip ar setpgid do cs_create_connection"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "theip ar rith cs_create_connection"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection: theip ar fdopen le haghaidh to_fp"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection: theip ar fdopen le haghaidh fr_fp"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: Níorbh fhéidir próiseas cscope a sceitheadh"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: níl aon nasc cscope ann"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: bratach neamhbhailí cscopequickfix %c le haghaidh %c"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr ""
"E259: níor aimsíodh aon rud comhoiriúnach leis an iarratas cscope %s de %s"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "Orduithe cscope:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (Úsáid: %s)"
-#: ../if_cscope.c:1155
-#, fuzzy
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"
@@ -3246,6 +2588,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: Aimsigh ráitis sannacháin leis an tsiombail seo\n"
" c: Aimsigh feidhmeanna a chuireann glaoch ar an bhfeidhm seo\n"
" d: Aimsigh feidhmeanna a gcuireann an fheidhm seo glaoch orthu\n"
" e: Aimsigh an patrún egrep seo\n"
@@ -3253,33 +2596,34 @@ msgstr ""
" g: Aimsigh an sainmhíniú seo\n"
" i: Aimsigh comhaid a #include-áil an comhad seo\n"
" s: Aimsigh an tsiombail C seo\n"
-" t: Aimsigh sanntaí do\n"
+" t: Aimsigh an teaghrán téacs seo\n"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: ní féidir bunachar sonraí cscope a oscailt: %s"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: ní féidir eolas a fháil faoin bhunachar sonraí cscope"
-#: ../if_cscope.c:1226
msgid "E568: duplicate cscope database not added"
msgstr "E568: níor cuireadh bunachar sonraí dúblach cscope leis"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: nasc cscope %s gan aimsiú"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "Dúnadh nasc cscope %s"
#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: earráid mharfach i cs_manage_matches"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Clib cscope: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3287,88 +2631,306 @@ msgstr ""
"\n"
" # líne"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "ainm comhaid / comhthéacs / líne\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Earráid cscope: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Athshocraíodh gach bunachar sonraí cscope"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "níl aon nasc cscope\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid ainm bunachair conair thosaigh\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "Ní féidir an leabharlann Lua a luchtú."
+
+msgid "cannot save undo information"
+msgstr "ní féidir eolas cealaithe a shábháil"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: Tá brón orm, bhí an t-ordú seo díchumasaithe, níorbh fhéidir "
+"leabharlanna MzScheme a luchtú."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: Ár leithscéal, tá an t-ordú seo díchumasaithe; níorbh fhéidir modúl "
+"racket/base MzScheme a luchtú."
+
+msgid "invalid expression"
+msgstr "slonn neamhbhailí"
+
+msgid "expressions disabled at compile time"
+msgstr "díchumasaíodh sloinn ag am an tiomsaithe"
+
+msgid "hidden option"
+msgstr "rogha fholaithe"
+
+msgid "unknown option"
+msgstr "rogha anaithnid"
+
+msgid "window index is out of range"
+msgstr "innéacs fuinneoige as raon"
+
+msgid "couldn't open buffer"
+msgstr "ní féidir maolán a oscailt"
+
+msgid "cannot delete line"
+msgstr "ní féidir an líne a scriosadh"
+
+msgid "cannot replace line"
+msgstr "ní féidir an líne a athchur"
+
+msgid "cannot insert line"
+msgstr "ní féidir líne a ionsá"
+
+msgid "string cannot contain newlines"
+msgstr "ní cheadaítear carachtair líne nua sa teaghrán"
+
+msgid "error converting Scheme values to Vim"
+msgstr "earráid agus luach Scheme á thiontú go Vim"
+
+msgid "Vim error: ~a"
+msgstr "earráid Vim: ~a"
+
+msgid "Vim error"
+msgstr "earráid Vim"
+
+msgid "buffer is invalid"
+msgstr "maolán neamhbhailí"
+
+msgid "window is invalid"
+msgstr "fuinneog neamhbhailí"
+
+msgid "linenr out of range"
+msgstr "líne-uimhir as raon"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "ní cheadaítear é seo i mbosca gainimh Vim"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr ""
+"E836: Ní féidir leis an leagan seo de Vim :python a rith tar éis :py3 a úsáid"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Tá brón orm, níl an t-ordú seo le fáil, níorbh fhéidir an leabharlann "
+"Python a luchtú."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: Ár leithscéal, níl an t-ordú seo le fáil, níorbh fhéidir an modúl "
+"Python a luchtú."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Ní féidir Python a rith go hathchúrsach"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr ""
+"E837: Ní féidir leis an leagan seo de Vim :py3 a rith tar éis :python a úsáid"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: caithfidh $_ a bheith cineál Teaghráin"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Tá brón orm, níl an t-ordú seo le fáil, níorbh fhéidir an leabharlann "
+"Ruby a luchtú."
+
+msgid "E267: unexpected return"
+msgstr "E267: \"return\" gan choinne"
+
+msgid "E268: unexpected next"
+msgstr "E268: \"next\" gan choinne"
+
+msgid "E269: unexpected break"
+msgstr "E269: \"break\" gan choinne"
+
+msgid "E270: unexpected redo"
+msgstr "E270: \"redo\" gan choinne"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: \"retry\" taobh amuigh de chlásal tarrthála"
+
+msgid "E272: unhandled exception"
+msgstr "E272: eisceacht gan láimhseáil"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: stádas anaithnid longjmp %d"
+
+msgid "invalid buffer number"
+msgstr "uimhir neamhbhailí mhaoláin"
+
+msgid "not implemented yet"
+msgstr "níl ar fáil"
+
+#. ???
+msgid "cannot set line(s)"
+msgstr "ní féidir lín(t)e a shocrú"
+
+msgid "invalid mark name"
+msgstr "ainm neamhbhailí mairc"
+
+msgid "mark not set"
+msgstr "marc gan socrú"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "líne %d colún %d"
+
+msgid "cannot insert/append line"
+msgstr "ní féidir líne a ionsá/iarcheangal"
+
+msgid "line number out of range"
+msgstr "líne-uimhir as raon"
+
+msgid "unknown flag: "
+msgstr "bratach anaithnid: "
+
+msgid "unknown vimOption"
+msgstr "vimOption anaithnid"
+
+msgid "keyboard interrupt"
+msgstr "idirbhriseadh méarchláir"
+
+msgid "vim error"
+msgstr "earráid vim"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "ní féidir ordú maoláin/fuinneoige a chruthú: réad á scriosadh"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr "ní féidir ordú aisghlaoch a chlárú: maolán/fuinneog á scriosadh cheana"
+
+#. This should never happen. Famous last word?
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: EARRÁID MHARFACH TCL: liosta truaillithe tagartha!? Seol tuairisc "
+"fhabht chuig <vim-dev@vim.org> le do thoil"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"ní féidir ordú aisghlaoch a chlárú: tagairt mhaolán/fhuinneoige gan aimsiú"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Tá brón orm, níl an t-ordú seo le fáil: níorbh fhéidir an leabharlann "
+"Tcl a luchtú."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: cód scortha %d"
+
+msgid "cannot get line"
+msgstr "ní féidir an líne a fháil"
+
+msgid "Unable to register a command server name"
+msgstr "Ní féidir ainm fhreastalaí ordaithe a chlárú"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Theip ar sheoladh ordú chuig an sprioc-chlár"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: Aitheantas neamhbhailí freastalaí in úsáid: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: Airí míchumtha sa chlárlann áisc VIM. Scriosta!"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Eochair dhúblach in JSON: \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: Camóg ar iarraidh i Liosta: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ']' ar iarraidh ag deireadh liosta: %s"
+
msgid "Unknown option argument"
msgstr "Argóint anaithnid rogha"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "An iomarca argóintí eagarthóireachta"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "Argóint ar iarraidh i ndiaidh"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "Dramhaíl i ndiaidh argóinte rogha"
-#: ../main.c:152
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr ""
"An iomarca argóintí den chineál \"+ordú\", \"-c ordú\" nó \"--cmd ordú\""
-#: ../main.c:154
msgid "Invalid argument for"
msgstr "Argóint neamhbhailí do"
-#: ../main.c:294
#, c-format
msgid "%d files to edit\n"
msgstr "%d comhad le heagrú\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "Ní thacaítear le netbeans sa GUI seo\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "Ní féidir '-nb' a úsáid: níor cumasaíodh é ag am tiomsaithe\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Níor tiomsaíodh an leagan Vim seo le `diff' ar fáil."
+
msgid "Attempt to open script file again: \""
msgstr "Déan iarracht ar oscailt na scripte arís: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "Ní féidir é a oscailt chun léamh: \""
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "Ní féidir a oscailt le haghaidh an aschuir scripte: \""
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Earráid: Theip ar thosú gvim ó NetBeans\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr ""
+"Vim: Earráid: Ní féidir an leagan seo de Vim a rith i dteirminéal Cygwin\n"
+
msgid "Vim: Warning: Output is not to a terminal\n"
msgstr "Vim: Rabhadh: Níl an t-aschur ag dul chuig teirminéal\n"
-#: ../main.c:1624
msgid "Vim: Warning: Input is not from a terminal\n"
msgstr "Vim: Rabhadh: Níl an t-ionchur ag teacht ó theirminéal\n"
#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "líne na n-orduithe pre-vimrc"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Ní féidir léamh ó \"%s\""
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3376,37 +2938,30 @@ msgstr ""
"\n"
"Tuilleadh eolais: \"vim -h\"\n"
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[comhad ..] cuir na comhaid ceaptha in eagar"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- scríobh téacs ó stdin"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t tag cuir an comhad ina bhfuil an chlib in eagar"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [comhadearr] cuir comhad leis an chéad earráid in eagar"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
"úsáid:"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [argóintí] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3414,7 +2969,14 @@ msgstr ""
"\n"
" nó:"
-#: ../main.c:2196
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Nuair nach cásíogair é, cuir '/' ag tosach na brataí chun í a chur sa chás "
+"uachtair"
+
msgid ""
"\n"
"\n"
@@ -3424,194 +2986,343 @@ msgstr ""
"\n"
"Argóintí:\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\t\tNí cheadaítear ach ainmneacha comhaid i ndiaidh é seo"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\t\tNá leathnaigh saoróga"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tCláraigh an gvim seo le haghaidh OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tDíchláraigh an gvim seo le haghaidh OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tRith agus úsáid an GUI (mar \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f nó --nofork\tTulra: Ná déan forc agus an GUI á thosú"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\t\tMód Vi (mar \"vi\")"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\t\tMód Ex (mar \"ex\")"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
+msgstr "-E\t\t\tMód Ex feabhsaithe"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\t\tMód ciúin (baiscphróiseála) (do \"ex\" amháin)"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\t\tMód diff (mar \"vimdiff\")"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
msgstr "-y\t\t\tMód éasca (mar \"evim\", gan mhóid)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\t\tMód inléite amháin (mar \"view\")"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\t\tMód srianta (mar \"rvim\")"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\t\tNí cheadaítear athruithe (.i. scríobh na gcomhad)"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\t\tNí cheadaítear athruithe sa téacs"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\t\tMód dénártha"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\t\tMód Lisp"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\t\tComhoiriúnach le Vi: 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\t\tNí comhoiriúnaithe le Vi go hiomlán: 'nocompatible'"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr ""
"-V[N][fname]\t\tBí foclach [leibhéal N] [logáil teachtaireachtaí i fname]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\t\tMód dífhabhtaithe"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\t\tNá húsáid comhad babhtála .i. ná húsáid ach an chuimhne"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\t\tTaispeáin comhaid bhabhtála agus scoir"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r (le hainm comhaid)\tAthshlánaigh ó chliseadh"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\t\tAr comhbhrí le -r"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\ttosaigh sa mhód Araibise"
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tNá húsáid newcli chun fuinneog a oscailt"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <gléas>\t\tBain úsáid as <gléas> do I/A"
+
+msgid "-A\t\t\tStart in Arabic mode"
+msgstr "-A\t\t\tTosaigh sa mhód Araibise"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\t\tTosaigh sa mhód Eabhraise"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\t\tTosaigh sa mhód Pheirsise"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <teirminéal>\tSocraigh cineál teirminéal"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr ""
+"--not-a-term\t\tNá bac le rabhadh faoi ionchur/aschur gan a bheith ón "
+"teirminéal"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr "--ttyfail\t\tScoir mura bhfuil ionchur agus aschur ina dteirminéil"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\t\tÚsáid <vimrc> in ionad aon .vimrc"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tBain úsáid as <gvimrc> in ionad aon .gvimrc"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\tNá luchtaigh breiseáin"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tOscail N leathanach cluaisín (default: ceann do gach comhad)"
+msgstr "-p[N]\t\tOscail N leathanach cluaisíní (default: ceann do gach comhad)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tOscail N fuinneog (réamhshocrú: ceann do gach comhad)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\t\tMar -o, ach roinn go hingearach"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\t\tTosaigh ag an chomhadchríoch"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<lnum>\t\tTosaigh ar líne <lnum>"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr "--cmd <ordú>\tRith <ordú> roimh aon chomhad vimrc a luchtú"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <ordú>\t\tRith <ordú> i ndiaidh luchtú an chéad chomhad"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr ""
"-S <seisiún>\t\tLéigh comhad <seisiún> i ndiaidh an chéad chomhad á léamh"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <script>\tLéigh orduithe gnáthmhóid ón chomhad <script>"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr ""
"-w <script>\tIarcheangail gach ordú iontráilte leis an gcomhad <script>"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr "-W <aschur>\tScríobh gach ordú clóscríofa sa chomhad <aschur>"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tCuir comhaid chriptithe in eagar"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <freastalaí>\tNasc vim leis an bhfreastalaí-X seo"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tNá naisc leis an bhfreastalaí X"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr ""
+"--remote <comhaid>\tCuir <comhaid> in eagar le freastalaí Vim más féidir"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-silent <comhaid> Mar an gcéanna, ná déan gearán mura bhfuil "
+"freastalaí ann"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <comhaid> Mar --remote ach fan leis na comhaid a bheith "
+"curtha in eagar"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <comhaid> Mar an gcéanna, ná déan gearán mura bhfuil "
+"freastalaí ann"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <comhaid> Cosúil le --remote ach oscail "
+"cluaisín do gach comhad"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr ""
+"--remote-send <eochracha>\tSeol <eochracha> chuig freastalaí Vim agus scoir"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <slonn>\tLuacháil <slonn> le freastalaí Vim agus taispeáin an "
+"toradh"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tTaispeáin freastalaithe Vim atá ar fáil agus scoir"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <ainm>\tSeol chuig/Téigh i do fhreastalaí Vim <ainm>"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr ""
"--startuptime <comhad>\tScríobh faisnéis maidir le tréimhse tosaithe i "
"<comhad>"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\tÚsáid <viminfo> in ionad .viminfo"
-#: ../main.c:2243
msgid "-h or --help\tPrint Help (this message) and exit"
msgstr "-h nó --help\tTaispeáin an chabhair seo agus scoir"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\tTaispeáin eolas faoin leagan agus scoir"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan Motif):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan neXtaw):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan Athena):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <scáileán>\tRith vim ar <scáileán>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tTosaigh vim sa mhód íoslaghdaithe"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <dath>\tBain úsáid as <dath> don chúlra (-bg fosta)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <dath>\tÚsáid <dath> le haghaidh gnáth-théacs (fosta: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <cló>\t\tÚsáid <cló> le haghaidh gnáth-théacs (fosta: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <cló>\tBain úsáid as <cló> do chló trom"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <cló>\tÚsáid <cló> le haghaidh téacs iodálach"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr ""
+"-geometry <geoim>\tÚsáid <geoim> le haghaidh na céimseatan tosaigh (fosta: -"
+"geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <leithead>\tSocraigh <leithead> na himlíne (-bw fosta)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <leithead> Socraigh leithead na scrollbharraí a bheith "
+"<leithead> (fosta: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <airde>\tSocraigh airde an bharra roghchláir a bheith <airde> "
+"(fosta: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tÚsáid fís aisiompaithe (fosta: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tNá húsáid fís aisiompaithe (fosta: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <acmhainn>\tSocraigh an acmhainn sainithe"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Argóintí ar eolas do gvim (leagan GTK+):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <scáileán>\tRith vim ar <scáileán> (fosta: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <ról>\tSocraigh ról sainiúil chun an phríomhfhuinneog a aithint"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tOscail Vim isteach i ngiuirléid GTK eile"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tTaispeánann gvim aitheantas na fuinneoige ar stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <máthairchlár>\tOscail Vim isteach sa mháthairchlár"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tOscail Vim isteach i ngiuirléid win32 eile"
+
+msgid "No display"
+msgstr "Gan taispeáint"
+
+#. Failed to send, abort.
+msgid ": Send failed.\n"
+msgstr ": Theip ar seoladh.\n"
+
+#. Let vim start normally.
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Theip ar seoladh. Ag baint triail as go logánta\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d as %d déanta"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Gan taispeáint: Theip ar sheoladh sloinn.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Theip ar sheoladh sloinn.\n"
+
msgid "No marks set"
msgstr "Níl aon mharc socraithe"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: Níl aon mharc comhoiriúnaithe le \"%s\""
#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3620,7 +3331,6 @@ msgstr ""
"marc líne col comhad/téacs"
#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3629,7 +3339,6 @@ msgstr ""
" léim líne col comhad/téacs"
#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3637,7 +3346,6 @@ msgstr ""
"\n"
"athrú líne col téacs"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3646,7 +3354,6 @@ msgstr ""
"# Marcanna comhaid:\n"
#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3654,7 +3361,6 @@ msgstr ""
"\n"
"# Liosta léimeanna (is nuaí i dtosach):\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3662,116 +3368,114 @@ msgstr ""
"\n"
"# Stair na marcanna i gcomhaid (is nuaí ar dtús):\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "`>' ar iarraidh"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: Ní códleathanach bailí é"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: Ní féidir luachanna IC a shocrú"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Theip ar chruthú comhthéacs ionchuir"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Theip ar oscailt mhodh ionchuir"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: Rabhadh: Níorbh fhéidir aisghlaoch léirscriosta a shocrú le IM"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: Ní thacaíonn an modh ionchuir aon stíl"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: ní thacaíonn an modh ionchuir mo chineál réamheagair"
+
msgid "E293: block was not locked"
msgstr "E293: ní raibh an bloc faoi ghlas"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Earráid chuardaigh agus comhad babhtála á léamh"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Earráid sa léamh i gcomhad babhtála"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Earráid chuardaigh agus comhad babhtála á scríobh"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Earráid sa scríobh i gcomhad babhtála"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: Tá comhad babhtála ann cheana (ionsaí le naisc shiombalacha?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Ní bhfuarthas bloc 0?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: Ní bhfuarthas bloc a haon?"
-#: ../memline.c:377
msgid "E298: Didn't get block nr 2?"
msgstr "E298: Ní bhfuarthas bloc a dó?"
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Earráid agus criptiú an chomhaid bhabhtála á nuashonrú"
+
#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: Úps, cailleadh an comhad babhtála!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Níorbh fhéidir an comhad babhtála a athainmniú"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr ""
"E303: Ní féidir comhad babhtála le haghaidh \"%s\" a oscailt, ní féidir "
"athshlánú"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): Ní bhfuarthas bloc 0??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Níor aimsíodh comhad babhtála le haghaidh %s"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Iontráil uimhir an chomhaid babhtála le húsáid (0 = scoir): "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Ní féidir %s a oscailt"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Ní féidir bloc 0 a léamh ó "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
msgstr ""
"\n"
-"B'fhéidir nach raibh aon athrú á dhéanamh, nó tá an comhad\n"
+"B'fhéidir nach raibh aon athrú á dhéanamh, nó tá an comhad "
"babhtála as dáta."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " níl ar fáil leis an leagan seo de Vim.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Bain úsáid as Vim, leagan 3.0.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: Níl %s cosúil le comhad babhtála Vim"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " níl ar fáil ar an ríomhaire seo.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "Cruthaíodh an comhad seo ar "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3779,86 +3483,107 @@ msgstr ""
",\n"
"is é sin nó rinneadh dochar don chomhad."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: tá %s criptithe agus ní thacaíonn an leagan seo de Vim le criptiú"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " rinneadh dochar dó (méid an leathanaigh níos lú ná an íosmhéid).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "Comhad babhtála \"%s\" á úsáid"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "Comhad bunúsach \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: Rabhadh: Is féidir gur athraíodh an comhad bunúsach"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Tá an comhad babhtála criptithe: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"Má chuir tú eochair nua chriptiúcháin isteach, ach mura scríobh tú an "
+"téacschomhad,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"cuir isteach an eochair nua chriptiúcháin."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"Má scríobh tú an téacschomhad tar éis duit an eochair chriptiúcháín a athrú, "
+"brúigh Enter"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"chun an eochair chéanna a úsáid don téacschomhad agus an comhad babhtála"
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Ní féidir bloc a haon a léamh ó %s"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???GO LEOR LÍNTE AR IARRAIDH"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???LÍON MÍCHEART NA LÍNTE"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???BLOC FOLAMH"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???LÍNTE AR IARRAIDH"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: Aitheantas mícheart ar bhloc a haon (níl %s ina chomhad .swp?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???BLOC AR IARRAIDH"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? is féidir go ndearnadh praiseach de línte ó anseo go ???END"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? is féidir go bhfuil línte ionsáite/scriosta ó anseo go ???END"
-#: ../memline.c:1181
msgid "???END"
msgstr "???DEIREADH"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: Idirbhriseadh an t-athshlánú"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: Braitheadh earráidí le linn athshlánaithe; féach ar na línte le ??? ar "
"tosach"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "Bain triail as \":help E312\" chun tuilleadh eolais a fháil."
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "Athshlánaíodh. Ba chóir duit gach rud a sheiceáil uair amháin eile."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3866,73 +3591,61 @@ msgstr ""
"\n"
"(B'fhéidir gur mian leat an comhad seo a shábháil de réir ainm eile\n"
-#: ../memline.c:1252
-#, fuzzy
msgid "and run diff with the original file to check for changes)"
-msgstr ""
-"agus déan comparáid leis an chomhad bhunúsach (m.sh. le `diff') chun "
-"athruithe a scrúdú)\n"
+msgstr "agus déan comparáid leis an mbunchomhad chun athruithe a lorg)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr ""
+"Athshlánú críochnaithe. Is ionann an t-ábhar sa mhaolán agus an t-ábhar sa "
+"chomhad."
-#: ../memline.c:1255
-#, fuzzy
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
"\n"
msgstr ""
-"Scrios an comhad .swp tar éis sin.\n"
"\n"
+"B'fhéidir gur mhaith leat an comhad .swp a scriosadh anois.\n"
+"\n"
+
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr ""
+"Eochair chriptiúcháin ón gcomhad babhtála á húsáid ar an téacschomhad.\n"
#. use msg() to start the scrolling properly
-#: ../memline.c:1327
msgid "Swap files found:"
msgstr "Comhaid bhabhtála aimsithe:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " Sa chomhadlann reatha:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " Ag baint úsáid as ainm socraithe:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " Sa chomhadlann "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- neamhní --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " úinéir: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " dátaithe: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " dátaithe: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [ó leagan 3.0 Vim]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [ní cosúil le comhad babhtála Vim]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " ainm comhaid: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3940,15 +3653,12 @@ msgstr ""
"\n"
" mionathraithe: "
-#: ../memline.c:1559
msgid "YES"
msgstr "IS SEA"
-#: ../memline.c:1559
msgid "no"
msgstr "ní hea"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3956,11 +3666,9 @@ msgstr ""
"\n"
" úsáideoir: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " ainm an óstríomhaire: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3968,7 +3676,6 @@ msgstr ""
"\n"
" óstainm: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3976,11 +3683,16 @@ msgstr ""
"\n"
" PID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (ag rith fós)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ní inúsáidte leis an leagan seo Vim]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -3988,97 +3700,75 @@ msgstr ""
"\n"
" [ní inúsáidte ar an ríomhaire seo]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [ní féidir a léamh]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [ní féidir oscailt]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: Ní féidir é a chaomhnú, níl aon chomhad babhtála ann"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "Caomhnaíodh an comhad"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: Theip ar chaomhnú"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: lnum neamhbhailí: %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: lnum neamhbhailí: %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: líne %<PRId64> gan aimsiú"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: líne %ld gan aimsiú"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: aitheantas mícheart ar an mbloc pointeora 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "ba chóir do stack_idx a bheith 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: An iomarca bloic nuashonraithe?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: aitheantas mícheart ar an mbloc pointeora 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "bloc a haon scriosta?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Líne %<PRId64> gan aimsiú"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Líne %ld gan aimsiú"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: aitheantas mícheart ar an mbloc pointeora"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "is 0 pe_line_count\""
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: líne-uimhir as raon: %<PRId64> thar dheireadh"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: líne-uimhir as raon: %ld thar dheireadh"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: líon mícheart na línte i mbloc %<PRId64>"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: líon mícheart na línte i mbloc %ld"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "Méadaíonn an chruach"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: aitheantas mícheart ar an mbloc pointeora 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: Ciogal i naisc shiombalacha le haghaidh \"%s\""
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: AIRE"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4086,45 +3776,31 @@ msgstr ""
"\n"
"Fuarthas comhad babhtála darbh ainm \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "Agus an comhad seo á oscailt: \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " NÍOS NUAÍ ná comhad babhtála!\n"
-#: ../memline.c:3244
-#, fuzzy
+#. Some of these messages are long to allow translation to
+#. * other languages.
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) Is féidir go bhfuil clár eile ag rochtain an comhad seo.\n"
-" Más ea, bí cúramach nach bhfuil dhá leagan den chomhad\n"
-" céanna.\n"
-
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " Scoir, nó lean ar aghaidh go hairdeallach.\n"
+"(1) Seans go bhfuil an comhad seo á chur in eagar ag clár eile. Má tá,\n"
+" bí cúramach nach bhfuil dhá leagan den chomhad céanna agat nuair\n"
+" a athraíonn tú é. Scoir anois, nó lean ort go faichilleach.\n"
-#: ../memline.c:3246
-#, fuzzy
msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) Rinne Vim thobscor agus an comhad seo\n"
-" idir lámha agat.\n"
+msgstr "(2) Thuairteáil seisiún eagarthóireachta.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " Más amhlaidh, bain úsáid as \":recover\" nó \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4132,11 +3808,9 @@ msgstr ""
"\"\n"
" chun na hathruithe a fháil ar ais (féach \":help recovery\").\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " Má tá sé seo déanta cheana agat, scrios an comhad babhtála \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4144,23 +3818,18 @@ msgstr ""
"\"\n"
" chun an teachtaireacht seo a sheachaint.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Comhad babhtála \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" tá sé ann cheana!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - AIRE"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "Tá comhad babhtála ann cheana!"
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4174,7 +3843,6 @@ msgstr ""
"&Scoir\n"
"&Tobscoir"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4190,58 +3858,36 @@ msgstr ""
"&Scoir\n"
"&Tobscoir"
-#.
-#. * 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
msgid "E326: Too many swap files found"
msgstr "E326: Aimsíodh an iomarca comhaid bhabhtála"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Cuimhne ídithe! (%<PRIu64> beart á ndáileadh)"
-
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: Ní fo-roghchlár í páirt de chonair roghchláir"
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Níl an roghchlár ar fáil sa mhód seo"
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Níl aon roghchlár darbh ainm \"%s\""
#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: Ainm folamh ar an roghchlár"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: Ní cheadaítear conair roghchláir a threoraíonn go fo-roghchlár"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr ""
"E331: Ní cheadaítear míreanna roghchláir a chur le barra roghchláir go "
"díreach"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Ní cheadaítear deighilteoir mar pháirt de chonair roghchláir"
#. Now we have found the matching menu, and we list the mappings
#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4249,74 +3895,61 @@ msgstr ""
"\n"
"--- Roghchláir ---"
-#: ../menu.c:1313
+msgid "Tear off this menu"
+msgstr "Bain an roghchlár seo"
+
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: Ní mór conair roghchláir a threorú chun mír roghchláir"
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: Roghchlár gan aimsiú: %s"
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
msgstr "E335: Níl an roghchlár ar fáil sa mhód %s"
-#: ../menu.c:1426
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: Ní mór conair roghchláir a threorú chun fo-roghchlár"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: Roghchlár gan aimsiú - deimhnigh ainmneacha na roghchlár"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "Earráid agus %s á phróiseáil:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "líne %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Ainm neamhbhailí tabhaill: '%s'"
-#: ../message.c:745
msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
msgstr ""
"Cothaitheoir na dteachtaireachtaí: Kevin P. Scannell <scannell@slu.edu>"
-#: ../message.c:986
msgid "Interrupt: "
msgstr "Idirbhriseadh: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "Brúigh ENTER nó iontráil ordú le leanúint"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s líne %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s líne %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- Tuilleadh --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " SPÁS/d/j: scáileán/leathanach/líne síos, b/u/k: suas, q: scoir "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "Ceist"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4324,17 +3957,6 @@ msgstr ""
"&Tá\n"
"&Níl"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Tá\n"
-"&Níl\n"
-"&Cealaigh"
-
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4348,180 +3970,251 @@ msgstr ""
"&Dealaigh Uile\n"
"&Cealaigh"
-#: ../message.c:3058
+msgid "Select Directory dialog"
+msgstr "Dialóg `Roghnaigh Comhadlann'"
+
+msgid "Save File dialog"
+msgstr "Dialóg `Sábháil Comhad'"
+
+msgid "Open File dialog"
+msgstr "Dialóg `Oscail Comhad'"
+
+#. TODO: non-GUI file selector here
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Níl brabhsálaí comhaid ar fáil sa mhód consóil"
+
msgid "E766: Insufficient arguments for printf()"
msgstr "E766: Easpa argóintí d'fheidhm printf()"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
msgstr "E807: Bhíothas ag súil le hargóint Snámhphointe d'fheidhm printf()"
-#: ../message.c:3873
msgid "E767: Too many arguments to printf()"
msgstr "E767: An iomarca argóintí d'fheidhm printf()"
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: Rabhadh: Comhad inléite amháin á athrú"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr ""
"Clóscríobh uimhir agus <Enter> nó cliceáil leis an luch (fág folamh le "
"cealú): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "Clóscríobh uimhir agus <Enter> (fág folamh le cealú): "
-#: ../misc1.c:2585
msgid "1 more line"
msgstr "1 líne eile"
-#: ../misc1.c:2588
msgid "1 line less"
msgstr "1 líne níos lú"
-#: ../misc1.c:2593
#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> líne eile"
+msgid "%ld more lines"
+msgstr "%ld líne eile"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> líne níos lú"
+msgid "%ld fewer lines"
+msgstr "%ld líne níos lú"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (Idirbhriste)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "Bíp!"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "EARRÁID: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[beart] iomlán dáilte-saor %lu-%lu, in úsáid %lu, buaic %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[glaonna] re/malloc(): %lu, free(): %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Tá an líne ag éirí rófhada"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Earráid inmheánach: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Cuimhne ídithe! (%lu beart á ndáileadh)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "An t-ordú seo á rith leis an bhlaosc: \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: Idirstad ar iarraidh"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Mód neamhcheadaithe"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Cruth neamhcheadaithe luiche"
+
+msgid "E548: digit expected"
+msgstr "E548: ag súil le digit"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Céatadán neamhcheadaithe"
+
+msgid "E854: path too long for completion"
+msgstr "E854: conair rófhada le comhlánú"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: Conair neamhbhailí: ní mór '**[uimhir]' a bheith ag deireadh na "
+"conaire, nó le '%s' ina dhiaidh."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Ní féidir comhadlann \"%s\" a aimsiú sa cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Ní féidir comhad \"%s\" a aimsiú sa chonair"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Níl comhadlann \"%s\" sa cdpath a thuilleadh"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Níl comhad \"%s\" sa chonair a thuilleadh"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Mód mícheart rochtana ar an chomhad eolas naisc NetBeans: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: Cailleadh nasc NetBeans le haghaidh maoláin %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: Ní thacaítear le netbeans sa GUI seo"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: Tá netbeans ceangailte cheana"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: Tá %s inléite amháin (cuir ! leis chun sárú)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: Níl aitheantóir faoin chúrsóir"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' folamh"
-#: ../normal.c:2637
+msgid "E775: Eval feature not available"
+msgstr "E775: Níl an ghné Eval le fáil"
+
msgid "Warning: terminal cannot highlight"
msgstr "Rabhadh: ní féidir leis an teirminéal aibhsiú"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: Níl teaghrán faoin chúrsóir"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: Ní féidir fillteacha a léirscriosadh leis an 'foldmethod' reatha"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: tá liosta na n-athruithe folamh"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Ag tosach liosta na n-athruithe"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Ag deireadh liosta na n-athruithe"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "Clóscríobh :quit<Enter> chun Vim a scor"
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim"
+msgstr "Clóscríobh :qa! agus brúigh <Enter> le fágáil ó Vim gan athruithe a shábháil"
# ouch - English -ed ?
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 líne %s uair amháin"
# ouch - English -ed ?
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 líne %s %d uair"
# ouch - English -ed ?
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> líne %sed uair amháin"
+msgid "%ld lines %sed 1 time"
+msgstr "%ld líne %sed uair amháin"
# ouch - English -ed ?
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> líne %sed %d uair"
+msgid "%ld lines %sed %d times"
+msgstr "%ld líne %sed %d uair"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> líne le heangú... "
+msgid "%ld lines to indent... "
+msgstr "%ld líne le heangú... "
-#: ../ops.c:634
msgid "1 line indented "
msgstr "eangaíodh líne amháin "
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> líne eangaithe "
+msgid "%ld lines indented "
+msgstr "%ld líne eangaithe "
-#: ../ops.c:938
msgid "E748: No previously used register"
msgstr "E748: Níl aon tabhall úsáidte roimhe seo"
#. must display the prompt
-#: ../ops.c:1433
msgid "cannot yank; delete anyway"
msgstr "ní féidir a sracadh; scrios mar sin féin"
-#: ../ops.c:1929
msgid "1 line changed"
msgstr "athraíodh líne amháin"
-#: ../ops.c:1931
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "athraíodh %<PRId64> líne"
+msgid "%ld lines changed"
+msgstr "athraíodh %ld líne"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "%ld líne á saoradh"
-#: ../ops.c:2521
msgid "block of 1 line yanked"
msgstr "sracadh bloc de líne amháin"
-#: ../ops.c:2523
msgid "1 line yanked"
msgstr "sracadh líne amháin"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "sracadh bloc de %<PRId64> líne"
+msgid "block of %ld lines yanked"
+msgstr "sracadh bloc de %ld líne"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> líne sractha"
+msgid "%ld lines yanked"
+msgstr "%ld líne sractha"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: Tabhall folamh %s"
#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4529,11 +4222,9 @@ msgstr ""
"\n"
"--- Tabhaill ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "Ainm neamhcheadaithe tabhaill"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4541,185 +4232,177 @@ msgstr ""
"\n"
"# Tabhaill:\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: Cineál anaithnid tabhaill %d"
-#: ../ops.c:5089
+msgid ""
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr ""
+"E883: ní cheadaítear níos mó ná líne amháin i bpatrún cuardaigh ná sa "
+"slonntabhall"
+
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Colún; "
+msgid "%ld Cols; "
+msgstr "%ld Colún; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Roghnaíodh %s%<PRId64> as %<PRId64> Líne; %<PRId64> as %<PRId64> Focal; "
-"%<PRId64> as %<PRId64> Beart"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
+msgstr "Roghnaíodh %s%ld as %ld Líne; %lld as %lld Focal; %lld as %lld Beart"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"Roghnaíodh %s%<PRId64> as %<PRId64> Líne; %<PRId64> as %<PRId64> Focal; "
-"%<PRId64> as %<PRId64> Carachtar; %<PRId64> as %<PRId64> Beart"
+"Roghnaíodh %s%ld as %ld Líne; %lld as %lld Focal; %lld as %lld Carachtar; "
+"%lld as %lld Beart"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Col %s as %s; Líne %<PRId64> as %<PRId64>; Focal %<PRId64> as %<PRId64>; "
-"Beart %<PRId64> as %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "Col %s as %s; Líne %ld as %ld; Focal %lld as %lld; Beart %lld as %lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"Col %s as %s; Líne %<PRId64> as %<PRId64>; Focal %<PRId64> as %<PRId64>; "
-"Carachtar %<PRId64> as %<PRId64>; Beart %<PRId64> as %<PRId64>"
+"Col %s as %s; Líne %ld as %ld; Focal %lld as %lld; Carachtar %lld as %lld; "
+"Beart %lld as %lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> do BOM)"
+msgid "(+%ld for BOM)"
+msgstr "(+%ld do BOM)"
-#: ../option.c:1238
msgid "%<%f%h%m%=Page %N"
msgstr "%<%f%h%m%=Leathanach %N"
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Go raibh míle maith agat as Vim a úsáid"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Rogha anaithnid"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: Níl an rogha seo ar fáil"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: Ní cheadaithe i módlíne"
-#: ../option.c:2815
msgid "E846: Key code not set"
-msgstr ""
+msgstr "E846: Cód eochrach gan socrú"
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: Tá gá le huimhir i ndiaidh ="
-#: ../option.c:3226 ../option.c:3864
msgid "E522: Not found in termcap"
msgstr "E522: Gan aimsiú sa termcap"
-#: ../option.c:3335
#, c-format
msgid "E539: Illegal character <%s>"
msgstr "E539: Carachtar neamhcheadaithe <%s>"
-#: ../option.c:3862
+#, c-format
+msgid "For option %s"
+msgstr "Le haghaidh rogha %s"
+
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: Ní féidir 'term' a shocrú mar theaghrán folamh"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: Ní féidir 'term' a athrú sa GUI"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: Úsáid \":gui\" chun an GUI a chur ag obair"
+
msgid "E589: 'backupext' and 'patchmode' are equal"
msgstr "E589: is ionann iad 'backupext' agus 'patchmode'"
-#: ../option.c:3964
msgid "E834: Conflicts with value of 'listchars'"
-msgstr ""
+msgstr "E834: Tagann sé salach ar luach de 'listchars'"
-#: ../option.c:3966
msgid "E835: Conflicts with value of 'fillchars'"
-msgstr ""
+msgstr "E835: Tagann sé salach ar luach de 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Ní féidir é a athrú sa GUI GTK+ 2"
-#: ../option.c:4163
msgid "E524: Missing colon"
msgstr "E524: Idirstad ar iarraidh"
-#: ../option.c:4165
msgid "E525: Zero length string"
msgstr "E525: Teaghrán folamh"
-#: ../option.c:4220
#, c-format
msgid "E526: Missing number after <%s>"
msgstr "E526: Uimhir ar iarraidh i ndiaidh <%s>"
-#: ../option.c:4232
msgid "E527: Missing comma"
msgstr "E527: Camóg ar iarraidh"
-#: ../option.c:4239
msgid "E528: Must specify a ' value"
msgstr "E528: Caithfidh luach ' a shonrú"
-#: ../option.c:4271
msgid "E595: contains unprintable or wide character"
msgstr "E595: tá carachtar neamhghrafach nó leathan ann"
-#: ../option.c:4469
+msgid "E596: Invalid font(s)"
+msgstr "E596: Cló(nna) neamhbhailí"
+
+msgid "E597: can't select fontset"
+msgstr "E597: ní féidir tacar cló a roghnú"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: Tacar cló neamhbhailí"
+
+msgid "E533: can't select wide font"
+msgstr "E533: ní féidir cló leathan a roghnú"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: Cló leathan neamhbhailí"
+
#, c-format
msgid "E535: Illegal character after <%c>"
msgstr "E535: Carachtar neamhbhailí i ndiaidh <%c>"
-#: ../option.c:4534
msgid "E536: comma required"
msgstr "E536: tá gá le camóg"
-#: ../option.c:4543
#, c-format
msgid "E537: 'commentstring' must be empty or contain %s"
msgstr ""
"E537: ní mór %s a bheith i 'commentstring', is é sin nó ní mór dó a bheith "
"folamh"
-#: ../option.c:4928
+msgid "E538: No mouse support"
+msgstr "E538: Gan tacaíocht luiche"
+
msgid "E540: Unclosed expression sequence"
msgstr "E540: Seicheamh gan dúnadh"
-#: ../option.c:4932
msgid "E541: too many items"
msgstr "E541: an iomarca míreanna"
-#: ../option.c:4934
msgid "E542: unbalanced groups"
msgstr "E542: grúpaí neamhchothromaithe"
-#: ../option.c:5148
msgid "E590: A preview window already exists"
msgstr "E590: Tá fuinneog réamhamhairc ann cheana"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr ""
"W17: Tá UTF-8 ag teastáil le haghaidh Araibise, socraigh é le ':set "
"encoding=utf-8'"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: Tá gá le %d líne ar a laghad"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Tá gá le %d colún ar a laghad"
-#: ../option.c:6011
#, c-format
msgid "E355: Unknown option: %s"
msgstr "E355: Rogha anaithnid: %s"
@@ -4727,12 +4410,10 @@ msgstr "E355: Rogha anaithnid: %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
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: Uimhir de dhíth: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4740,7 +4421,6 @@ msgstr ""
"\n"
"--- Cóid teirminéil ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4748,7 +4428,6 @@ msgstr ""
"\n"
"--- Luachanna na roghanna comhchoiteann ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4756,7 +4435,6 @@ msgstr ""
"\n"
"--- Luachanna na roghanna logánta ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4764,29 +4442,148 @@ msgstr ""
"\n"
"--- Roghanna ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: EARRÁID get_varp"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': Carachtar comhoiriúnach ar iarraidh le haghaidh %s"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap': Carachtair breise i ndiaidh an idirstad: %s"
-#: ../os/shell.c:194
+msgid "cannot open "
+msgstr "ní féidir a oscailt: "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Ní féidir fuinneog a oscailt!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Tá gá le Amigados leagan 2.04 nó níos déanaí\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Tá gá le %s, leagan %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Ní féidir NIL a oscailt:\n"
+
+msgid "Cannot create "
+msgstr "Ní féidir a chruthú: "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim á scor le stádas %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "ní féidir mód consóil a athrú ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ní consól é seo??\n"
+
+#. if Vim opened a window: Executing a shell may cause crashes
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Ní féidir blaosc a rith le rogha -f"
+
+msgid "Cannot execute "
+msgstr "Ní féidir blaosc a rith: "
+
+msgid "shell "
+msgstr "blaosc "
+
+msgid " returned\n"
+msgstr " aisfhilleadh\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE róbheag."
+
+msgid "I/O ERROR"
+msgstr "EARRÁID I/A"
+
+msgid "Message"
+msgstr "Teachtaireacht"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Theip ar roghnú printéara"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "go %s ar %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Clófhoireann anaithnid printéara: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Earráid phriontála: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "'%s' á phriontáil"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr ""
+"E244: Ainm neamhcheadaithe ar thacar carachtar \"%s\" mar pháirt d'ainm cló "
+"\"%s\""
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: Ainm neamhcheadaithe ar cháilíocht \"%s\" in ainm cló \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: Carachtar neamhcheadaithe '%c' mar pháirt d'ainm cló \"%s\""
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Thóg %ld ms chun an scáileán X a oscailt"
+
msgid ""
"\n"
-"Cannot execute shell "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"Ní féidir blaosc a rith "
+"Vim: Fuarthas earráid ó X\n"
+
+msgid "Testing the X display failed"
+msgstr "Theip ar thástáil an scáileáin X"
+
+msgid "Opening the X display timed out"
+msgstr "Oscailt an scáileáin X thar am"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Níorbh fhéidir comhthéacs slándála a fháil le haghaidh "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Níorbh fhéidir comhthéacs slándála a shocrú le haghaidh "
+
+#, c-format
+msgid "Could not set security context %s for %s"
+msgstr "Níorbh fhéidir comhthéacs slándála %s a shocrú le haghaidh %s"
+
+#, c-format
+msgid "Could not get security context %s for %s. Removing it!"
+msgstr ""
+"Níorbh fhéidir comhthéacs slándála %s a fháil le haghaidh %s. Á bhaint!"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Ní féidir an bhlaosc sh a rith\n"
-#: ../os/shell.c:439
msgid ""
"\n"
"shell returned "
@@ -4794,472 +4591,482 @@ msgstr ""
"\n"
"d'aisfhill an bhlaosc "
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
-"Could not get security context for "
+"Cannot create pipes\n"
msgstr ""
"\n"
-"Níorbh fhéidir comhthéacs slándála a fháil le haghaidh "
+"Ní féidir píopaí a chruthú\n"
-#: ../os_unix.c:479
+# "fork" not in standard refs/corpus. Maybe want a "gabhl*" word instead? -KPS
msgid ""
"\n"
-"Could not set security context for "
+"Cannot fork\n"
msgstr ""
"\n"
-"Níorbh fhéidir comhthéacs slándála a shocrú le haghaidh "
+"Ní féidir forc a dhéanamh\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Ní féidir blaosc a rith "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Ordú críochnaithe\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "Chaill XSMP an nasc ICE"
-#: ../os_unix.c:1558 ../os_unix.c:1647
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "Theip ar oscailt an scáileáin X"
+
+msgid "XSMP handling save-yourself request"
+msgstr "Iarratas sábháil-do-féin á láimhseáil ag XSMP"
+
+msgid "XSMP opening connection"
+msgstr "Nasc á oscailt ag XSMP"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "Theip ar fhaire nasc ICE XSMP"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Níl aon fháil ar chomhad \"%s\" sa chonair"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "Theip ar XSMP SmcOpenConnection: %s"
+
+msgid "At line"
+msgstr "Ag líne"
+
+msgid "Could not load vim32.dll!"
+msgstr "Níorbh fhéidir vim32.dll a luchtú!"
+
+msgid "VIM Error"
+msgstr "Earráid VIM"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Níorbh fhéidir pointeoirí feidhme a chóiriú i gcomhair an DLL!"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Fuarthas teagmhas %s\n"
+
+msgid "close"
+msgstr "dún"
+
+msgid "logoff"
+msgstr "logáil amach"
+
+msgid "shutdown"
+msgstr "múchadh"
+
+msgid "E371: Command not found"
+msgstr "E371: Ní bhfuarthas an t-ordú"
+
+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 ""
+"Níor aimsíodh VIMRUN.EXE i do $PATH.\n"
+"Ní mhoilleoidh orduithe seachtracha agus iad curtha i gcrích.\n"
+"Féach ar :help win32-vimrun chun níos mó eolas a fháil."
+
+msgid "Vim Warning"
+msgstr "Rabhadh Vim"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "d'aisfhill an bhlaosc %d"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: An iomarca %%%c i dteaghrán formáide"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: %%%c gan choinne i dteaghrán formáide"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: ] ar iarraidh i dteaghrán formáide"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: %%%c gan tacaíocht i dteaghrán formáide"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: %%%c neamhbhailí i réimír an teaghráin formáide"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: %%%c neamhbhailí i dteaghrán formáide"
#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: Níl aon phatrún i 'errorformat'"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: Ainm comhadlainne ar iarraidh, nó folamh"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Níl aon mhír eile"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: Dúnadh an fhuinneog reatha"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Athraíodh an mearcheartúchán reatha"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Athraíodh an liosta suíomh reatha"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d as %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (líne scriosta)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%sliosta earráidí %d as %d; %d earráid "
+
msgid "E380: At bottom of quickfix stack"
-msgstr "E380: In íochtar na cruaiche quickfix"
+msgstr "E380: In íochtar chruach na mearcheartúchán"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
-msgstr "E381: In uachtar na cruaiche quickfix"
+msgstr "E381: In uachtar chruach na mearcheartúchán"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "liosta earráidí %d as %d; %d earráid"
+msgid "No entries"
+msgstr "Gan iontráil"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: Ní féidir scríobh, rogha 'buftype' socraithe"
-#: ../quickfix.c:2812
+msgid "Error file"
+msgstr "Comhad earráide"
+
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Ainm comhaid ar iarraidh, nó patrún neamhbhailí"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Ní féidir comhad \"%s\" a oscailt"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: Níl an maolán luchtaithe"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: Bhíothas ag súil le Teaghrán nó Liosta"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: mír neamhbhailí i %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: ] ar iarraidh i ndiaidh %s["
-#: ../regexp.c:375
+msgid "E944: Reverse range in character class"
+msgstr "E944: Raon aisiompaithe in aicme carachtar"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: Raon rómhór in aicme carachtar"
+
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: %s%%( corr"
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: %s( corr"
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: %s) corr"
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: ní cheadaítear \\z( anseo"
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: ní cheadaítear \\z1 et al. anseo"
+msgid "E67: \\z1 - \\z9 not allowed here"
+msgstr "E67: ní cheadaítear \\z1 - \\z9 anseo"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: ] ar iarraidh i ndiaidh %s%%["
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] folamh"
-#: ../regexp.c:1209 ../regexp.c:1224
+msgid "E65: Illegal back reference"
+msgstr "E65: Cúltagairt neamhbhailí"
+
msgid "E339: Pattern too long"
msgstr "E339: Slonn rófhada"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: an iomarca \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: an iomarca %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: \\z( corr"
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: carachtar neamhbhailí i ndiaidh %s@"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: An iomarca %s{...} coimpléascach"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61: %s* neadaithe"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62: %s%c neadaithe"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: úsáid neamhbhailí de \\_"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64: níl aon rud roimh %s%c"
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: Cúltagairt neamhbhailí"
-
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: Carachtar neamhbhailí i ndiaidh \\z"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: Carachtar neamhbhailí i ndiaidh %s%%[dxouU]"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: Carachtar neamhbhailí i ndiaidh %s%%"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: Earráid chomhréire i %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "Fo-mheaitseáil sheachtrach:\n"
-#: ../regexp.c:7022
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (slonn NFA) ní féidir %s a athdhéanamh"
+
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
msgstr ""
+"E864: Ní cheadaítear ach 0, 1, nó 2 tar éis \\%#=. Úsáidfear an t-inneall "
+"uathoibríoch "
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
+msgid "Switching to backtracking RE engine for pattern: "
msgstr ""
+"Ag athrú go dtí an t-inneall rianaithe siar le haghaidh an phatrúin seo: "
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: (NFA) Thángthas ar dheireadh an tsloinn gan súil leis"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
+msgstr "E866: (slonn NFA) %c as áit"
-#: ../regexp_nfa.c:242
#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (slonn NFA) Aicme carachtar neamhbhailí: %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
+msgstr "E867: (NFA) Oibreoir anaithnid '\\z%c'"
-#: ../regexp_nfa.c:1387
#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
+msgstr "E867: (NFA) Oibreoir anaithnid '\\%%%c'"
+
+#. should never happen
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Earráid agus NFA á thógáil le haicme coibhéise!"
-#: ../regexp_nfa.c:1802
#, c-format
msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
+msgstr "E869: (NFA) Oibreoir anaithnid '\\@%c'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
+msgstr "E870: (slonn NFA) Earráid agus teorainneacha athdhéanta á léamh"
#. 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 ""
+msgid "E871: (NFA regexp) Can't have a multi follow a multi"
+msgstr "E871: (slonn NFA) Ní cheadaítear ilchodach tar éis ilchodach"
#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
+msgstr "E872: (slonn NFA) An iomarca '('"
-#: ../regexp_nfa.c:2042
-#, fuzzy
msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: an iomarca \\z("
+msgstr "E879: (slonn NFA) An iomarca \\z("
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
+msgstr "E873: (slonn NFA) críochnú neamhoiriúnach"
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
+msgid "E874: (NFA) Could not pop the stack!"
+msgstr "E874: (NFA) Níorbh fhéidir an chruach a phlobadh!"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
msgstr ""
+"E875: (slonn NFA) (Le linn tiontaithe ó postfix go NFA), an iomarca "
+"staideanna fágtha ar an gcruach"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr "E876: (slonn NFA) Níl go leor spáis ann don NFA iomlán "
+
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
msgstr ""
+"E878: (NFA) Níorbh fhéidir cuimhne a leithdháileadh leis an gcraobh a "
+"thrasnaíl!"
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
+"Could not open temporary log file for writing, displaying on stderr... "
msgstr ""
+"Níorbh fhéidir logchomhad sealadach a oscailt le scríobh ann, á thaispeáint "
+"ar stderr..."
-#: ../regexp_nfa.c:4840
#, c-format
msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
+msgstr "(NFA) NÍORBH FHÉIDIR %s A OSCAILT!"
-#: ../regexp_nfa.c:6049
-#, fuzzy
msgid "Could not open temporary log file for writing "
-msgstr "E214: Ní féidir comhad sealadach a aimsiú chun scríobh ann"
+msgstr "Níorbh fhéidir logchomhad sealadach a oscailt le scríobh ann "
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " V-IONADAIGH"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ATHCHUR"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " TIONTÚ"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " IONSÁ"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (ionsáigh)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (ionadaigh)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (v-ionadaigh)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " Eabhrais"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " Araibis"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (teanga)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (greamaigh)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " RADHARCACH"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " LÍNE RADHARCACH"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " BLOC RADHARCACH"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " ROGHNÚ"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " SELECT LINE"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " SELECT BLOCK"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "á thaifeadadh"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Teaghrán cuardaigh neamhbhailí: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: bhuail an cuardach an BARR gan teaghrán comhoiriúnach le %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: bhuail an cuardach an BUN gan teaghrán comhoiriúnach le %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: Ag súil le '?' nó '/' i ndiaidh ';'"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (tá an teaghrán comhoiriúnaithe roimhe seo san áireamh)"
#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- Comhaid cheanntáisc "
-#: ../search.c:4106
msgid "not found "
msgstr "gan aimsiú"
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "i gconair ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Liostaithe cheana féin)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " AR IARRAIDH"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "Comhad ceanntáisc á scanadh: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "Comhad ceanntáisc %s á chuardach"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: Tá an teaghrán comhoiriúnaithe ar an líne reatha"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Aimsíodh gach comhad ceanntáisc"
-#: ../search.c:4519
msgid "No included files"
msgstr "Gan comhaid cheanntáisc"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: Sainmhíniú gan aimsiú"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: Patrún gan aimsiú"
-#: ../search.c:4668
msgid "Substitute "
msgstr "Ionadú "
# in .viminfo
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5270,98 +5077,130 @@ msgstr ""
"# %sPatrún Cuardaigh Is Déanaí:\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Earráid fhormáide i gcomhad litrithe"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Níl seiceáil litrithe cumasaithe"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr ""
+"Rabhadh: Ní féidir liosta focal \"%s_%s.spl\" nó \"%s_ascii.spl\" a aimsiú"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr ""
+"Rabhadh: Ní féidir liosta focal \"%s.%s.spl\" nó \"%s.ascii.spl\" a aimsiú"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: Scrios uathordú SpellFileMissing an maolán"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Rabhadh: réigiún %s gan tacaíocht"
+
+msgid "Sorry, no suggestions"
+msgstr "Tá brón orm, níl aon mholadh ann"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Tá brón orm, níl ach %ld moladh ann"
+
+#. for when 'cmdheight' > 1
+#. avoid more prompt
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Athraigh \"%.*s\" go:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Níl aon ionadaí litrithe roimhe seo"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Gan aimsiú: %s"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: Comhad teasctha litrithe"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "Téacs chun deiridh i %s líne %d: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "Ainm foircinn rófhada i %s líne %d: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr "E761: Earráid fhormáide i gcomhad foircinn FOL, LOW, nó UPP"
-#: ../spell.c:957
msgid "E762: Character in FOL, LOW or UPP is out of range"
msgstr "E762: Carachtar i FOL, LOW nó UPP as raon"
-#: ../spell.c:958
msgid "Compressing word tree..."
msgstr "Crann focal á chomhbhrú..."
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: Níl seiceáil litrithe cumasaithe"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
-"Rabhadh: Ní féidir liosta focal \"%s.%s.spl\" nó \"%s.ascii.spl\" a aimsiú"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "Comhad litrithe \"%s\" á léamh"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Níl sé cosúil le comhad litrithe"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: Seanchomhad litrithe, tá gá lena nuashonrú"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Oibríonn an comhad litrithe le leagan níos nuaí de Vim"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Rannán gan tacaíocht i gcomhad litrithe"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Rabhadh: réigiún %s gan tacaíocht"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Níl sé cosúil le comhad .sug: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Seanchomhad .sug, tá gá lena nuashonrú: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Oibríonn an comhad .sug le leagan níos nuaí de Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Níl an comhad .sug comhoiriúnach leis an gcomhad .spl: %s"
-#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: earráid agus comhad .sug á léamh: %s"
+
+#, c-format
+msgid "Reading affix file %s..."
msgstr "Comhad foircinn %s á léamh..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "Theip ar thiontú focail i %s líne %d: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "Tiontú i %s gan tacaíocht: ó %s go %s"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Tiontú i %s gan tacaíocht"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "Luach neamhbhailí ar FLAG i %s líne %d: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "FLAG i ndiaidh bratacha in úsáid i %s líne %d: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5370,7 +5209,6 @@ msgstr ""
"Seans go bhfaighfidh tú torthaí míchearta má chuireann tú COMPOUNDFORBIDFLAG "
"tar éis míre PFX i %s líne %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5379,42 +5217,34 @@ msgstr ""
"Seans go bhfaighfidh tú torthaí míchearta má chuireann tú COMPOUNDPERMITFLAG "
"tar éis míre PFX i %s líne %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "Luach mícheart ar COMPOUNDRULES i %s líne %d: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "Luach mícheart ar COMPOUNDWORDMAX i %s líne %d: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "Luach mícheart ar COMPOUNDMIN i %s líne %d: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "Luach mícheart ar COMPOUNDSYLMAX i %s líne %d: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "Luach mícheart ar CHECKCOMPOUNDPATTERN i %s líne %d: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr "Bratach dhifriúil cheangail i mbloc leanta foircinn i %s líne %d: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "Clib dhúblach i %s líne %d: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5423,335 +5253,251 @@ msgstr ""
"Foirceann in úsáid le haghaidh BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
"NOSUGGEST freisin i %s líne %d: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "Bhíothas ag súil le `Y' nó `N' i %s líne %d: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "Coinníoll briste i %s líne %d: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "Bhíothas ag súil le líon na REP(SAL) i %s líne %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "Bhíothas ag súil le líon na MAP i %s líne %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "Carachtar dúblach i MAP i %s líne %d"
-#: ../spell.c:5176
#, c-format
msgid "Unrecognized or duplicate item in %s line %d: %s"
msgstr "Mír anaithnid nó dhúblach i %s líne %d: %s"
-#: ../spell.c:5197
#, c-format
msgid "Missing FOL/LOW/UPP line in %s"
msgstr "Líne FOL/LOW/UPP ar iarraidh i %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "COMPOUNDSYLMAX in úsáid gan SYLLABLE"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "An iomarca réimíreanna curtha siar"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "An iomarca bratach comhfhocail"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "An iomarca réimíreanna curtha siar agus/nó bratacha comhfhocal"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Líne SOFO%s ar iarraidh i %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "Línte SAL agus SOFO araon i %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "Ní uimhir í an bhratach i %s líne %d: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "Bratach neamhcheadaithe i %s líne %d: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "Tá difear idir luach %s agus an luach i gcomhad .aff eile"
-#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Foclóir %s á léamh ..."
+msgid "Reading dictionary file %s..."
+msgstr "Foclóir %s á léamh..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Líon na bhfocal ar iarraidh i %s"
-#: ../spell.c:5669
#, c-format
msgid "line %6d, word %6d - %s"
msgstr "líne %6d, focal %6d - %s"
-#: ../spell.c:5691
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "Focal dúblach i %s líne %d: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "An chéad fhocal dúblach i %s líne %d: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d focal dúblach i %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "Rinneadh neamhshuim ar %d focal le carachtair neamh-ASCII i %s"
-#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Comhad focail %s á léamh ..."
+msgid "Reading word file %s..."
+msgstr "Comhad focail %s á léamh..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "Rinneadh neamhshuim ar líne dhúblach `/encoding=' i %s líne %d: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr ""
"Rinneadh neamhshuim ar líne `/encoding=' i ndiaidh focail i %s líne %d: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "Rinneadh neamhshuim ar líne `/regions=' i %s líne %d: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
msgstr "An iomarca réigiún i %s líne %d: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "Rinneadh neamhshuim ar líne `/' i %s líne %d: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "Uimhir neamhbhailí réigiúin i %s líne %d: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "Bratacha anaithnide i %s líne %d: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "Rinneadh neamhshuim ar %d focal le carachtair neamh-ASCII"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Easpa cuimhne, beidh an liosta focal neamhiomlán"
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "Comhbhrúdh %d as %d nód; %d (%d%%) fágtha"
-#: ../spell.c:7340
msgid "Reading back spell file..."
msgstr "Comhad litrithe á léamh arís..."
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
+#.
+#. * Go through the trie of good words, soundfold each word and add it to
+#. * the soundfold trie.
+#.
msgid "Performing soundfolding..."
msgstr "Fuaimfhilleadh..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Líon na bhfocal tar éis fuaimfhillte: %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "Líon na bhfocal tar éis fuaimfhillte: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Líon iomlán na bhfocal: %d"
-#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Comhad moltaí %s á scríobh ..."
+msgid "Writing suggestion file %s..."
+msgstr "Comhad moltaí %s á scríobh..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "Cuimhne measta a bheith in úsáid le linn rite: %d beart"
-#: ../spell.c:7820
msgid "E751: Output file name must not have region name"
msgstr "E751: Ní cheadaítear ainm réigiúin in ainm an aschomhaid"
-#: ../spell.c:7822
msgid "E754: Only up to 8 regions supported"
msgstr "E754: Ní thacaítear le níos mó ná 8 réigiún"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Réigiún neamhbhailí i %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "Rabhadh: sonraíodh comhfhocail agus NOBREAK araon"
-#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Comhad litrithe %s á scríobh ..."
+msgid "Writing spell file %s..."
+msgstr "Comhad litrithe %s á scríobh..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Críochnaithe!"
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: níl %<PRId64> iontráil i 'spellfile'"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: níl %ld iontráil i 'spellfile'"
-#: ../spell.c:8074
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "Baineadh focal ó %s"
+msgstr "Baineadh focal '%.*s' ó %s"
-#: ../spell.c:8117
-#, fuzzy, c-format
+#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "Cuireadh focal le %s"
+msgstr "Cuireadh focal '%.*s' le %s"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: Tá carachtair dhifriúla fhocail sna comhaid litrithe"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Tá brón orm, níl aon mholadh ann"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Tá brón orm, níl ach %<PRId64> moladh ann"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Athraigh \"%.*s\" go:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
+#. This should have been checked when generating the .spl
+#. * file.
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: carachtar dúblach in iontráil MAP"
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Níl aon ionadaí litrithe roimhe seo"
+msgid "No Syntax items defined for this buffer"
+msgstr "Níl aon mhír chomhréire sainmhínithe le haghaidh an mhaoláin seo"
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Gan aimsiú: %s"
+msgid "syntax conceal on"
+msgstr "syntax conceal on"
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Níl sé cosúil le comhad .sug: %s"
+msgid "syntax conceal off"
+msgstr "syntax conceal off"
-#: ../spell.c:9282
#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Seanchomhad .sug, tá gá lena nuashonrú: %s"
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Argóint neamhcheadaithe: %s"
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Oibríonn an comhad .sug le leagan níos nuaí de Vim: %s"
+msgid "syntax case ignore"
+msgstr "syntax case ignore"
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Níl an comhad .sug comhoiriúnach leis an gcomhad .spl: %s"
+msgid "syntax case match"
+msgstr "syntax case match"
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: earráid agus comhad .sug á léamh: %s"
+msgid "syntax spell toplevel"
+msgstr "syntax spell toplevel"
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: carachtar dúblach in iontráil MAP"
+msgid "syntax spell notoplevel"
+msgstr "syntax spell notoplevel"
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "Níl aon mhír chomhréire sainmhínithe le haghaidh an mhaoláin seo"
+msgid "syntax spell default"
+msgstr "syntax spell default"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: Argóint neamhcheadaithe: %s"
+msgid "syntax iskeyword "
+msgstr "syntax iskeyword "
-#: ../syntax.c:3299
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Níl a leithéid de mhogall comhréire: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "ag sioncrónú ar nóta den nós C"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "gan sioncrónú"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "tosaíonn an sioncrónú "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " línte roimh an bharr"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5759,7 +5505,6 @@ msgstr ""
"\n"
"--- Míreanna Comhréire Sionc ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5767,7 +5512,6 @@ msgstr ""
"\n"
"ag sioncrónú ar mhíreanna"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5775,275 +5519,217 @@ msgstr ""
"\n"
"--- Míreanna comhréire ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Níl a leithéid de mhogall comhréire: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "íosta "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "uasta "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; meaitseáil "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " bristeacha líne"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: tá argóint ann nach nglactar leis anseo"
-#: ../syntax.c:4096
-#, fuzzy
msgid "E844: invalid cchar value"
-msgstr "E474: Argóint neamhbhailí"
+msgstr "E844: luach neamhbhailí cchar"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: ní ghlactar le group[t]here anseo"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: Níor aimsíodh mír réigiúin le haghaidh %s"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Tá gá le hainm comhaid"
-#: ../syntax.c:4221
-#, fuzzy
msgid "E847: Too many syntax includes"
-msgstr "E77: An iomarca ainmneacha comhaid"
+msgstr "E847: An iomarca comhad comhréire in úsáid"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ']' ar iarraidh: %s"
-#: ../syntax.c:4531
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: carachtar tar éis ']': %s]%s"
+
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: '=' ar iarraidh: %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Níl go leor argóintí ann: réigiún comhréire %s"
-#: ../syntax.c:4870
-#, fuzzy
msgid "E848: Too many syntax clusters"
-msgstr "E391: Níl a leithéid de mhogall comhréire: %s"
+msgstr "E848: An iomarca mogall comhréire"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: Níor sonraíodh mogall"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Teormharcóir patrúin gan aimsiú: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: Dramhaíl i ndiaidh patrúin: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: comhréir sionc: tugadh patrún leanúint líne faoi dhó"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Argóintí neamhcheadaithe: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: Sín chothroime ar iarraidh: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: Argóint fholamh: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: ní cheadaítear %s anseo"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: ní foláir %s a thabhairt ar dtús sa liosta `contains'"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: Ainm anaithnid grúpa: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Fo-ordú neamhbhailí :syntax: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
+" IOMLÁN LÍON MEAITS IS MOILLE MEÁN AINM PATRÚN"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: lúb athchúrsach agus syncolor.vim á luchtú"
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: Grúpa aibhsithe gan aimsiú: %s"
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: Easpa argóintí: \":highlight link %s\""
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: An iomarca argóintí: \":highlight link %s\""
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr ""
"E414: tá socruithe ag an ghrúpa, ag déanamh neamhshuim ar nasc aibhsithe"
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: sín chothroime gan choinne: %s"
-#: ../syntax.c:6395
#, c-format
msgid "E416: missing equal sign: %s"
msgstr "E416: sín chothroime ar iarraidh: %s"
-#: ../syntax.c:6418
#, c-format
msgid "E417: missing argument: %s"
msgstr "E417: argóint ar iarraidh: %s"
-#: ../syntax.c:6446
#, c-format
msgid "E418: Illegal value: %s"
msgstr "E418: Luach neamhcheadaithe: %s"
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: Dath anaithnid an chúlra"
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: Dath anaithnid an tulra"
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: Níor aithníodh ainm/uimhir an datha: %s"
-#: ../syntax.c:6714
#, c-format
msgid "E422: terminal code too long: %s"
msgstr "E422: cód teirminéil rófhada: %s"
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Argóint neamhcheadaithe: %s"
-#: ../syntax.c:6925
msgid "E424: Too many different highlighting attributes in use"
msgstr "E424: An iomarca tréithe aibhsithe in úsáid"
-#: ../syntax.c:7427
msgid "E669: Unprintable character in group name"
msgstr "E669: Carachtar neamhghrafach in ainm grúpa"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: Carachtar neamhbhailí in ainm grúpa"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
-msgstr ""
+msgstr "E849: An iomarca grúpaí aibhsithe agus comhréire"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: in íochtar na cruaiche clibeanna"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: in uachtar na cruaiche clibeanna"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
msgstr "E425: Ní féidir a dhul roimh an chéad chlib chomhoiriúnach"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: clib gan aimsiú: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # tos cin clib"
-#: ../tag.c:531
msgid "file\n"
msgstr "comhad\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: Tá aon chlib chomhoiriúnach amháin"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
msgstr "E428: Ní féidir a dhul thar an chlib chomhoiriúnach deireanach"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "Níl a leithéid de chomhad \"%s\" ann"
#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "clib %d as %d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " nó os a chionn"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " Ag úsáid clib le cás eile!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Níl a leithéid de chomhad \"%s\""
#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6051,79 +5737,66 @@ msgstr ""
"\n"
" # Go clib Ó líne i gcomhad/téacs"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "Comhad clibeanna %s á chuardach"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Teascadh conair an chomhaid clibeanna le haghaidh %s\n"
+
msgid "Ignoring long line in tags file"
msgstr "Ag déanamh neamhaird de líne fhada sa chomhad clibeanna"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Earráid fhormáide i gcomhad clibeanna \"%s\""
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Roimh bheart %<PRId64>"
+msgid "Before byte %ld"
+msgstr "Roimh bheart %ld"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Comhad clibeanna gan sórtáil: %s"
#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: Níl aon chomhad clibeanna"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: Patrún clibe gan aimsiú"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: Clib gan aimsiú, ag tabhairt buille faoi thuairim!"
-#: ../tag.c:2797
-#, fuzzy, c-format
+#, c-format
msgid "Duplicate field name: %s"
-msgstr "Clib dhúblach i %s líne %d: %s"
+msgstr "Ainm réimse dúbailte: %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' anaithnid. Is iad seo na teirminéil insuite:"
-#: ../term.c:1463
msgid "defaulting to '"
msgstr "réamhshocrú = '"
-#: ../term.c:1731
msgid "E557: Cannot open termcap file"
msgstr "E557: Ní féidir an comhad termcap a oscailt"
-#: ../term.c:1735
msgid "E558: Terminal entry not found in terminfo"
msgstr "E558: Iontráil teirminéil gan aimsiú sa terminfo"
-#: ../term.c:1737
msgid "E559: Terminal entry not found in termcap"
msgstr "E559: Iontráil teirminéil gan aimsiú sa termcap"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: Níl aon iontráil \"%s\" sa termcap"
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: tá gá leis an chumas teirminéil \"cm\""
#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6131,169 +5804,346 @@ msgstr ""
"\n"
"--- Eochracha teirminéil ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "Ní féidir $VIMRUNTIME/rgb.txt a oscailt"
+
+msgid "new shell started\n"
+msgstr "tosaíodh blaosc nua\n"
+
msgid "Vim: Error reading input, exiting...\n"
msgstr "Vim: Earráid agus an t-inchomhad á léamh; ag scor...\n"
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "Úsáideadh CUT_BUFFER0 in ionad roghnúcháin folaimh"
+
#. This happens when the FileChangedRO autocommand changes the
#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E787: Athraíodh an maolán gan choinne"
+msgstr "E881: Athraíodh líon na línte gan súil leis"
+
+#. must display the prompt
+msgid "No undo possible; continue anyway"
+msgstr "Ní féidir a chealú; lean ar aghaidh mar sin féin"
-#: ../undo.c:627
-#, fuzzy, c-format
+#, c-format
msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E212: Ní féidir comhad a oscailt chun scríobh ann"
+msgstr "E828: Ní féidir comhad staire a oscailt le scríobh ann: %s"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
-msgstr ""
+msgstr "E825: Comhad staire truaillithe (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr ""
+msgstr "Ní féidir comhad staire a shábháil in aon chomhadlann in 'undodir'"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr ""
+msgstr "Ní forscríobhfar le comhad staire, ní féidir é a léamh: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
-msgstr ""
+msgstr "Ní forscríobhfar é, ní comhad staire é seo: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
-msgstr ""
+msgstr "Ní scríobhfar an comhad staire, níl aon stair ann"
-#: ../undo.c:1121
-#, fuzzy, c-format
+#, c-format
msgid "Writing undo file: %s"
-msgstr "Comhad viminfo \"%s\" á scríobh"
+msgstr "Comhad staire á scríobh: %s"
-#: ../undo.c:1213
-#, fuzzy, c-format
+#, c-format
msgid "E829: write error in undo file: %s"
-msgstr "E297: Earráid sa scríobh i gcomhad babhtála"
+msgstr "E829: earráid le linn scríofa i gcomhad staire: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
-msgstr ""
+msgstr "Níor léadh an comhad staire; úinéir difriúil: %s"
-#: ../undo.c:1292
-#, fuzzy, c-format
+#, c-format
msgid "Reading undo file: %s"
-msgstr "Comhad focail %s á léamh ..."
+msgstr "Comhad staire á léamh: %s"
-#: ../undo.c:1299
-#, fuzzy, c-format
+#, c-format
msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E195: Ní féidir an comhad viminfo a oscailt chun léamh"
+msgstr "E822: Ní féidir an comhad staire a oscailt lena léamh: %s"
-#: ../undo.c:1308
-#, fuzzy, c-format
+#, c-format
msgid "E823: Not an undo file: %s"
-msgstr "E753: Gan aimsiú: %s"
+msgstr "E823: Ní comhad staire é: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Comhad neamhchriptithe le comhad staire criptithe: %s"
-#: ../undo.c:1313
-#, fuzzy, c-format
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Níorbh fhéidir an comhad staire a dhíchriptiú: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Tá an comhad staire criptithe: %s"
+
+#, c-format
msgid "E824: Incompatible undo file: %s"
-msgstr "E484: Ní féidir comhad %s a oscailt"
+msgstr "E824: Comhad staire neamh-chomhoiriúnach: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
-msgstr ""
+msgstr "Athraíodh ábhar an chomhaid, ní féidir comhad staire a úsáid"
-#: ../undo.c:1497
-#, fuzzy, c-format
+#, c-format
msgid "Finished reading undo file %s"
-msgstr "deireadh ag foinsiú %s"
+msgstr "Comhad staire %s léite"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Ag an athrú is sine cheana"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Ag an athrú is nuaí cheana"
-#: ../undo.c:1806
-#, fuzzy, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "Níor aimsíodh cealú uimhir a %<PRId64>"
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Mír staire %ld gan aimsiú"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: líne-uimhreacha míchearta"
-#: ../undo.c:2183
msgid "more line"
msgstr "líne eile"
-#: ../undo.c:2185
msgid "more lines"
msgstr "líne eile"
-#: ../undo.c:2187
msgid "line less"
msgstr "líne níos lú"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "líne níos lú"
-#: ../undo.c:2193
msgid "change"
msgstr "athrú"
-#: ../undo.c:2195
msgid "changes"
msgstr "athrú"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
-#: ../undo.c:2228
msgid "before"
msgstr "roimh"
-#: ../undo.c:2228
msgid "after"
msgstr "tar éis"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "Níl faic le cealú"
-#: ../undo.c:2330
msgid "number changes when saved"
-msgstr ""
+msgstr "athraíonn an uimhir ag am sábhála"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> soicind ó shin"
+msgid "%ld seconds ago"
+msgstr "%ld soicind ó shin"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: ní cheadaítear \"undojoin\" tar éis \"undo\""
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: tá an liosta cealaithe truaillithe"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: líne chealaithe ar iarraidh"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Tá feidhm %s ann cheana, cuir ! leis an ordú chun é a asáitiú"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Tá an iontráil foclóra seo ann cheana"
+
+msgid "E718: Funcref required"
+msgstr "E718: Tá gá le Funcref"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Feidhm anaithnid: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Argóint neamhcheadaithe: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Argóint dhúbailte: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: An iomarca argóintí d'fheidhm %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Argóintí neamhbhailí d'fheidhm %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Doimhneacht na nglaonna níos mó ná 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "%s á glao"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s tobscortha"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ag aisfhilleadh #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ag aisfhilleadh %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: An iomarca argóintí"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Feidhm anaithnid: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: Scriosadh an fheidhm: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Níl go leor feidhmeanna d'fheidhm: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: <SID> á úsáid ach gan a bheith i gcomhthéacs scripte: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Feidhm 'dict' á ghlao gan Foclóir: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Tá gá le hainm feidhme"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr ""
+"E128: Caithfidh ceannlitir a bheith ar dtús ainm feidhme, nó \"s:\": %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: Ní cheadaítear idirstad in ainm feidhme: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: Feidhm gan sainmhíniú: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '(' ar iarraidh: %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: Ní féidir g: a úsáid anseo"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: Ní mór don chlabhsúr a bheith ag an mbarrleibhéal: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ar iarraidh"
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: Aimsíodh téacs tar éis :endfunction: %s"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Tagann ainm na feidhme salach ar athróg: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr ""
+"E127: Ní féidir sainmhíniú nua a dhéanamh ar fheidhm %s: In úsáid cheana"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr ""
+"E746: Níl ainm na feidhme comhoiriúnach le hainm comhaid na scripte: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Ní féidir feidhm %s a scriosadh: Tá sé in úsáid faoi láthair"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: Caithfidh :return a bheith isteach i bhfeidhm"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: Lúibíní ar iarraidh: %s"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"Leagan GUI 64 giotán MS-Windows"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"Leagan GUI 32 giotán MS-Windows"
+
+msgid " with OLE support"
+msgstr " le tacaíocht OLE"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"Leagan consóil 64 giotán MS-Windows"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"Leagan consóil 32 giotán MS-Windows"
+
+msgid ""
+"\n"
+"MacOS X (unix) version"
+msgstr ""
+"\n"
+"Leagan MacOS X (unix)"
+
+msgid ""
+"\n"
+"MacOS X version"
+msgstr ""
+"\n"
+"Leagan MacOS X"
+
+msgid ""
+"\n"
+"MacOS version"
+msgstr ""
+"\n"
+"Leagan MacOS"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"Leagan OpenVMS"
+
msgid ""
"\n"
"Included patches: "
@@ -6301,7 +6151,6 @@ msgstr ""
"\n"
"Paistí san áireamh: "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6309,11 +6158,9 @@ msgstr ""
"\n"
"Paistí sa bhreis: "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Mionathraithe ag "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6322,11 +6169,9 @@ msgstr ""
"Tiomsaithe "
# with "Tiomsaithe"
-#: ../version.c:649
msgid "by "
msgstr "ag "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6334,656 +6179,974 @@ msgstr ""
"\n"
"Leagan ollmhór "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Leagan mór "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Leagan coitianta "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Leagan beag "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Leagan beag bídeach "
+
msgid "without GUI."
msgstr "gan GUI."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "le GUI GTK3."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "le GUI GTK2-GNOME."
+
+msgid "with GTK2 GUI."
+msgstr "le GUI GTK2."
+
+msgid "with X11-Motif GUI."
+msgstr "le GUI X11-Motif."
+
+msgid "with X11-neXtaw GUI."
+msgstr "le GUI X11-neXtaw."
+
+msgid "with X11-Athena GUI."
+msgstr "le GUI X11-Athena."
+
+msgid "with Photon GUI."
+msgstr "le GUI Photon."
+
+msgid "with GUI."
+msgstr "le GUI."
+
+msgid "with Carbon GUI."
+msgstr "le GUI Carbon."
+
+msgid "with Cocoa GUI."
+msgstr "le GUI Cocoa."
+
+msgid "with (classic) GUI."
+msgstr "le GUI (clasaiceach)."
+
msgid " Features included (+) or not (-):\n"
msgstr " Gnéithe san áireamh (+) nó nach bhfuil (-):\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " comhad vimrc an chórais: \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " comhad vimrc úsáideora: \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " dara comhad vimrc úsáideora: \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " tríú comhad vimrc úsáideora: \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " comhad exrc úsáideora: \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " dara comhad úsáideora exrc: \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " comhad gvimrc córais: \""
+
+msgid " user gvimrc file: \""
+msgstr " comhad gvimrc úsáideora: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "dara comhad gvimrc úsáideora: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "tríú comhad gvimrc úsáideora: \""
+
+msgid " defaults file: \""
+msgstr " comhad na réamhshocruithe: \""
+
+msgid " system menu file: \""
+msgstr " comhad roghchláir an chórais: \""
+
msgid " fall-back for $VIM: \""
msgstr " rogha thánaisteach do $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " f-b do $VIMRUNTIME: \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "Tiomsú: "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "Tiomsaitheoir: "
+
msgid "Linking: "
msgstr "Nascáil: "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr " LEAGAN DÍFHABHTAITHE"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi IMproved"
-#: ../version.c:769
msgid "version "
msgstr "leagan "
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "le Bram Moolenaar et al."
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Is saorbhogearra é Vim"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "Tabhair cabhair do pháistí bochta in Uganda!"
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
msgstr "clóscríobh :help iccf<Enter> chun eolas a fháil "
-#: ../version.c:779
msgid "type :q<Enter> to exit "
msgstr "clóscríobh :q<Enter> chun scoir "
-#: ../version.c:780
msgid "type :help<Enter> or <F1> for on-line help"
msgstr "clóscríobh :help<Enter> nó <F1> le haghaidh cabhrach ar líne"
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "clóscríobh :help version7<Enter> le haghaidh eolais faoin leagan"
+msgid "type :help version8<Enter> for version info"
+msgstr "clóscríobh :help version8<Enter> le haghaidh eolais faoin leagan"
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "Sa mhód comhoiriúnachta Vi"
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr ""
"clóscríobh :set nocp<Enter> chun na réamhshocruithe Vim a thaispeáint"
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr ""
"clóscríobh :help cp-default<Enter> chun níos mó eolas faoi seo a fháil"
-#: ../version.c:827
+# don't see where to localize "Help->Orphans"? --kps
+msgid "menu Help->Orphans for information "
+msgstr "roghchlár Help->Orphans chun eolas a fháil "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "Á rith gan mhóid, ag ionsá an téacs atá iontráilte"
+
+# same problem --kps
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "roghchlár Edit->Global Settings->Toggle Insert Mode "
+
+msgid " for two modes "
+msgstr " do dhá mhód "
+
+# same problem --kps
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "roghchlár Edit->Global Settings->Toggle Vi Compatible"
+
+msgid " for Vim defaults "
+msgstr " le haghaidh réamhshocruithe Vim "
+
msgid "Sponsor Vim development!"
msgstr "Bí i d'urraitheoir Vim!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Bí i d'úsáideoir cláraithe Vim!"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "clóscríobh :help sponsor<Enter> chun eolas a fháil "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "clóscríobh :help register<Enter> chun eolas a fháil "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "roghchlár Help->Sponsor/Register chun eolas a fháil "
-#: ../window.c:119
msgid "Already only one window"
msgstr "Níl ach aon fhuinneog amháin ann cheana"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: Níl aon fhuinneog réamhamhairc ann"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: Ní féidir a scoilteadh topleft agus botright san am céanna"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: Ní féidir rothlú nuair atá fuinneog eile scoilte"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: Ní féidir an fhuinneog dheiridh a dhúnadh"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: Ní féidir fuinneog autocmd a dhúnadh"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr ""
"E814: Ní féidir an fhuinneog a dhúnadh, ní bheadh ach fuinneog autocmd fágtha"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: Tá athruithe ann san fhuinneog eile"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: Níl ainm comhaid faoin chúrsóir"
-#~ msgid "Patch file"
-#~ msgstr "Comhad paiste"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Níl aon fháil ar chomhad \"%s\" sa chonair"
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&OK\n"
-#~ "&Cealaigh"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: Aitheantas neamhbhailí: %ld (ní mór dó a bheith >= 1)"
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Níl aon nasc le freastalaí Vim"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: Aitheantas in úsáid cheana: %ld"
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Ní féidir aon rud a sheoladh chuig %s"
+msgid "List or number required"
+msgstr "Tá gá le liosta nó uimhir"
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Ní féidir freagra ón fhreastalaí a léamh"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: Aitheantas neamhbhailí: %ld (ní mór dó a bheith >= 1)"
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Ní féidir aon rud a sheoladh chuig an chliant"
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: Aitheantas gan aimsiú: %ld"
-#~ msgid "Save As"
-#~ msgstr "Sábháil Mar"
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Níorbh fhéidir an leabharlann %s a oscailt"
-#~ msgid "Edit File"
-#~ msgstr "Cuir Comhad in Eagar"
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"Tá brón orm, níl an t-ordú seo le fáil: níorbh fhéidir an leabharlann Perl a "
+"luchtú."
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (AR IARRAIDH)"
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Ní cheadaítear luacháil Perl i mbosca gainimh gan an modúl Safe"
-#~ msgid "Source Vim script"
-#~ msgstr "Foinsigh script Vim"
+msgid "Edit with &multiple Vims"
+msgstr "Cuir in eagar le Vimeanna io&madúla"
-#~ msgid "Edit File in new window"
-#~ msgstr "Cuir comhad in eagar i bhfuinneog nua"
+msgid "Edit with single &Vim"
+msgstr "Cuir in eagar le &Vim aonair"
-#~ msgid "Append File"
-#~ msgstr "Cuir Comhad i nDeireadh"
+msgid "Diff with Vim"
+msgstr "Diff le Vim"
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Ionad na fuinneoige: X %d, Y %d"
+msgid "Edit with &Vim"
+msgstr "Cuir in Eagar le &Vim"
-#~ msgid "Save Redirection"
-#~ msgstr "Sábháil Atreorú"
+#. Now concatenate
+msgid "Edit with existing Vim - "
+msgstr "Cuir in Eagar le Vim beo - "
-#~ msgid "Save View"
-#~ msgstr "Sábháil an tAmharc"
+msgid "Edits the selected file(s) with Vim"
+msgstr "Cuir an comhad roghnaithe in eagar le Vim"
-#~ msgid "Save Session"
-#~ msgstr "Sábháil an Seisiún"
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr ""
+"Earráid agus próiseas á chruthú: Deimhnigh go bhfuil gvim i do chonair!"
-#~ msgid "Save Setup"
-#~ msgstr "Sábháil an Socrú"
+msgid "gvimext.dll error"
+msgstr "earráid gvimext.dll"
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: níl #< ar fáil gan ghné +eval"
+msgid "Path length too long!"
+msgstr "Conair rófhada!"
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Ní cheadaítear déghraif sa leagan seo"
+msgid "--No lines in buffer--"
+msgstr "--Tá an maolán folamh--"
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "is gléas é seo (díchumasaithe le rogha 'opendevice')"
+#.
+#. * The error messages that can be shared are included here.
+#. * Excluded are errors that are only used once and debugging messages.
+#.
+msgid "E470: Command aborted"
+msgstr "E470: Ordú tobscortha"
-#~ msgid "Reading from stdin..."
-#~ msgstr "Ag léamh ón ionchur caighdeánach..."
+msgid "E471: Argument required"
+msgstr "E471: Tá gá le hargóint"
-#~ msgid "[crypted]"
-#~ msgstr "[criptithe]"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: Ba chóir /, ? nó & a chur i ndiaidh \\"
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "Ní cheadaíonn NetBeans maoláin gan athrú a bheith scríofa"
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Neamhbhailí i bhfuinneog líne na n-orduithe; <CR>=rith, CTRL-C=scoir"
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Ní cheadaítear maoláin NetBeans a bheith scríofa go neamhiomlán"
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: Ní cheadaítear ordú ó exrc/vimrc sa chomhadlann reatha ná ó chuardach "
+"clibe"
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "díchumasaíodh scríobh chuig gléas le rogha 'opendevice'"
+msgid "E171: Missing :endif"
+msgstr "E171: :endif ar iarraidh"
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Chaillfí an forc acmhainne (cuir ! leis an ordú chun sárú)"
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry ar iarraidh"
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Ní féidir an GUI a chur ag obair"
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile ar iarraidh"
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Ní féidir léamh ó \"%s\""
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor ar iarraidh"
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr ""
-#~ "E665: Ní féidir an GUI a chur ag obair, níl aon chlófhoireann bhailí ann"
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile gan :while"
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' neamhbhailí"
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor gan :for"
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Luach neamhbhailí ar 'imactivatekey'"
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Tá comhad ann cheana (cuir ! leis an ordú chun forscríobh)"
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Ní féidir dath %s a dháileadh"
+msgid "E472: Command failed"
+msgstr "E472: Theip ar ordú"
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Níl a leithéid ag an chúrsóir, ag cuardach ar an chéad cheann eile"
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Tacar cló anaithnid: %s"
-#~ msgid "<cannot open> "
-#~ msgstr "<ní féidir a oscailt> "
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Clófhoireann anaithnid: %s"
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: níl aon fháil ar an chlófhoireann %s"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Ní cló aonleithid é \"%s\""
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr ""
-#~ "E614: vim_SelFile: ní féidir dul ar ais go dtí an chomhadlann reatha"
+msgid "E473: Internal error"
+msgstr "E473: Earráid inmheánach"
-#~ msgid "Pathname:"
-#~ msgstr "Conair:"
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Earráid inmheánach: %s"
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: níl an chomhadlann reatha ar fáil"
+msgid "Interrupted"
+msgstr "Idirbhriste"
-#~ msgid "OK"
-#~ msgstr "OK"
+msgid "E14: Invalid address"
+msgstr "E14: Drochsheoladh"
-#~ msgid "Cancel"
-#~ msgstr "Cealaigh"
+msgid "E474: Invalid argument"
+msgstr "E474: Argóint neamhbhailí"
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Giuirléid Scrollbharra: Ní féidir céimseata an mhapa picteilíní a fháil."
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Argóint neamhbhailí: %s"
-#~ msgid "Vim dialog"
-#~ msgstr "Dialóg Vim"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Slonn neamhbhailí: %s"
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr ""
-#~ "E232: Ní féidir BalloonEval a chruthú le teachtaireacht agus aisghlaoch "
-#~ "araon"
+msgid "E16: Invalid range"
+msgstr "E16: Raon neamhbhailí"
-#~ msgid "Vim dialog..."
-#~ msgstr "Dialóg Vim..."
+msgid "E476: Invalid command"
+msgstr "E476: Ordú neamhbhailí"
-#~ msgid "Input _Methods"
-#~ msgstr "_Modhanna ionchuir"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: is comhadlann \"%s\""
-# in OLT --KPS
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Cuardaigh agus Athchuir..."
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Theip ar ghlao leabharlainne \"%s()\""
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Cuardaigh..."
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Ní féidir feidhm %s leabharlainne a luchtú"
-#~ msgid "Find what:"
-#~ msgstr "Aimsigh:"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Tá líne-uimhir neamhbhailí ag an mharc"
-#~ msgid "Replace with:"
-#~ msgstr "Le cur in ionad:"
+msgid "E20: Mark not set"
+msgstr "E20: Marc gan socrú"
-#~ msgid "Match whole word only"
-#~ msgstr "Focal iomlán amháin"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr ""
+"E21: Ní féidir athruithe a chur i bhfeidhm, níl an bhratach 'modifiable' "
+"socraithe"
-#~ msgid "Match case"
-#~ msgstr "Meaitseáil an cás"
+msgid "E22: Scripts nested too deep"
+msgstr "E22: scripteanna neadaithe ródhomhain"
-#~ msgid "Direction"
-#~ msgstr "Treo"
+msgid "E23: No alternate file"
+msgstr "E23: Níl aon chomhad malartach"
-#~ msgid "Up"
-#~ msgstr "Suas"
+msgid "E24: No such abbreviation"
+msgstr "E24: Níl a leithéid de ghiorrúchán ann"
-#~ msgid "Down"
-#~ msgstr "Síos"
+msgid "E477: No ! allowed"
+msgstr "E477: Ní cheadaítear !"
-#~ msgid "Find Next"
-#~ msgstr "An Chéad Cheann Eile"
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: Ní féidir an GUI a úsáid: Níor cumasaíodh é ag am tiomsaithe"
-#~ msgid "Replace"
-#~ msgstr "Ionadaigh"
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E26: Níl tacaíocht Eabhraise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-#~ msgid "Replace All"
-#~ msgstr "Ionadaigh Uile"
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E27: Níl tacaíocht Pheirsise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: Fuarthas iarratas \"die\" ó bhainisteoir an tseisiúin\n"
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E800: Níl tacaíocht Araibise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-#~ msgid "Close"
-#~ msgstr "Dún"
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Níl a leithéid d'ainm grúpa aibhsithe: %s"
-#~ msgid "New tab"
-#~ msgstr "Cluaisín nua"
+msgid "E29: No inserted text yet"
+msgstr "E29: Níl aon téacs ionsáite go dtí seo"
-#~ msgid "Open Tab..."
-#~ msgstr "Oscail Cluaisín..."
+msgid "E30: No previous command line"
+msgstr "E30: Níl aon líne na n-orduithe roimhe seo"
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Milleadh an príomhfhuinneog gan choinne\n"
+msgid "E31: No such mapping"
+msgstr "E31: Níl a leithéid de mhapáil"
-#~ msgid "Font Selection"
-#~ msgstr "Roghnú Cló"
+msgid "E479: No match"
+msgstr "E479: Níl aon rud comhoiriúnach ann"
-#~ msgid "&Filter"
-#~ msgstr "&Scagaire"
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Níl aon rud comhoiriúnach ann: %s"
-#~ msgid "&Cancel"
-#~ msgstr "&Cealaigh"
+msgid "E32: No file name"
+msgstr "E32: Níl aon ainm comhaid"
-#~ msgid "Directories"
-#~ msgstr "Comhadlanna"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Níl aon slonn ionadaíochta roimhe seo"
-#~ msgid "Filter"
-#~ msgstr "Scagaire"
+msgid "E34: No previous command"
+msgstr "E34: Níl aon ordú roimhe seo"
-#~ msgid "&Help"
-#~ msgstr "&Cabhair"
+msgid "E35: No previous regular expression"
+msgstr "E35: Níl aon slonn ionadaíochta roimhe seo"
-#~ msgid "Files"
-#~ msgstr "Comhaid"
+msgid "E481: No range allowed"
+msgstr "E481: Ní cheadaítear raon"
-#~ msgid "&OK"
-#~ msgstr "&OK"
+msgid "E36: Not enough room"
+msgstr "E36: Níl slí a dhóthain ann"
-#~ msgid "Selection"
-#~ msgstr "Roghnú"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: níl aon fhreastalaí cláraithe leis an ainm \"%s\""
-#~ msgid "Find &Next"
-#~ msgstr "An Chéad Chea&nn Eile"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Ní féidir comhad %s a chruthú"
-#~ msgid "&Replace"
-#~ msgstr "&Ionadaigh"
+msgid "E483: Can't get temp file name"
+msgstr "E483: Níl aon fháil ar ainm comhaid sealadach"
-#~ msgid "Replace &All"
-#~ msgstr "Ionadaigh &Uile"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Ní féidir comhad %s a oscailt"
-#~ msgid "&Undo"
-#~ msgstr "&Cealaigh"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Ní féidir comhad %s a léamh"
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Ní féidir teideal na fuinneoige \"%s\" a aimsiú"
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Tá athruithe ann gan sábháil (cuir ! leis an ordú chun sárú)"
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Argóint gan tacaíocht: \"-%s\"; Bain úsáid as an leagan OLE."
+msgid "E37: No write since last change"
+msgstr "E37: Gan scríobh ón athrú is déanaí"
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Ní féidir fuinneog a oscailt isteach i bhfeidhmchlár MDI"
+msgid "E38: Null argument"
+msgstr "E38: Argóint nialasach"
-#~ msgid "Close tab"
-#~ msgstr "Dún cluaisín"
+msgid "E39: Number expected"
+msgstr "E39: Ag súil le huimhir"
-#~ msgid "Open tab..."
-#~ msgstr "Oscail cluaisín..."
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Ní féidir an comhad earráide %s a oscailt"
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Aimsigh teaghrán (bain úsáid as '\\\\' chun '\\' a aimsiú)"
+msgid "E233: cannot open display"
+msgstr "E233: ní féidir an scáileán a oscailt"
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Aimsigh & Athchuir (úsáid '\\\\' chun '\\' a aimsiú)"
+msgid "E41: Out of memory!"
+msgstr "E41: Cuimhne ídithe!"
-#~ msgid "Not Used"
-#~ msgstr "Gan Úsáid"
+msgid "Pattern not found"
+msgstr "Patrún gan aimsiú"
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Comhadlann\t*.neamhní\n"
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Patrún gan aimsiú: %s"
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Ní féidir iontráil dathmhapála a dháileadh, is féidir go mbeidh "
-#~ "dathanna míchearta ann"
+msgid "E487: Argument must be positive"
+msgstr "E487: Argóint dheimhneach de dhíth"
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr ""
-#~ "E250: Clónna ar iarraidh le haghaidh na dtacar carachtar i dtacar cló %s:"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Ní féidir a fhilleadh ar an chomhadlann roimhe seo"
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Ainm an tacar cló: %s"
+msgid "E42: No Errors"
+msgstr "E42: Níl Aon Earráid Ann"
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Ní cló aonleithid é '%s'"
+msgid "E776: No location list"
+msgstr "E776: Gan liosta suíomh"
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Ainm an tacar cló: %s\n"
+msgid "E43: Damaged match string"
+msgstr "E43: Teaghrán cuardaigh loite"
-#~ msgid "Font0: %s\n"
-#~ msgstr "Cló0: %s\n"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: Clár na sloinn ionadaíochta truaillithe"
-#~ msgid "Font1: %s\n"
-#~ msgstr "Cló1: %s\n"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: tá an rogha 'readonly' socraithe (cuir ! leis an ordú chun sárú)"
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "Níl Cló%<PRId64> níos leithne faoi dhó ná cló0\n"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Ní féidir athróg inléite amháin \"%s\" a athrú"
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "Leithead Cló0: %<PRId64>\n"
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Ní féidir athróg a shocrú sa bhosca gainimh: \"%s\""
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "Leithead Cló1: %<PRId64>\n"
-#~ "\n"
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ní féidir eochair fholamh a úsáid le Foclóir"
-#~ msgid "Invalid font specification"
-#~ msgstr "Sonrú neamhbhailí cló"
+msgid "E715: Dictionary required"
+msgstr "E715: Tá gá le foclóir"
-#~ msgid "&Dismiss"
-#~ msgstr "&Ruaig"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: innéacs liosta as raon: %ld"
-#~ msgid "no specific match"
-#~ msgstr "níl a leithéid ann"
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: An iomarca argóintí d'fheidhm: %s"
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - Roghnú Cló"
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: Níl an eochair seo san Fhoclóir: %s"
-#~ msgid "Name:"
-#~ msgstr "Ainm:"
+msgid "E714: List required"
+msgstr "E714: Tá gá le liosta"
-#~ msgid "Show size in Points"
-#~ msgstr "Taispeáin méid (Pointí)"
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Caithfidh argóint de %s a bheith ina Liosta nó Foclóir"
-#~ msgid "Encoding:"
-#~ msgstr "Ionchódú:"
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Earráid agus comhad earráide á léamh"
-#~ msgid "Font:"
-#~ msgstr "Cló:"
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ní cheadaítear é seo i mbosca gainimh"
-#~ msgid "Style:"
-#~ msgstr "Stíl:"
+msgid "E523: Not allowed here"
+msgstr "E523: Ní cheadaítear é anseo"
-#~ msgid "Size:"
-#~ msgstr "Méid:"
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Ní féidir an mód scáileáin a shocrú"
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: EARRÁID leis na huathoibreáin Hangul"
+msgid "E49: Invalid scroll size"
+msgstr "E49: Méid neamhbhailí scrollaithe"
-#~ msgid "E563: stat error"
-#~ msgstr "E563: earráid stat"
+msgid "E91: 'shell' option is empty"
+msgstr "E91: rogha 'shell' folamh"
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: ní féidir bunachar sonraí cscope a oscailt: %s"
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Níorbh fhéidir na sonraí comhartha a léamh!"
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: ní féidir eolas a fháil faoin bhunachar sonraí cscope"
+msgid "E72: Close error on swap file"
+msgstr "E72: Earráid agus comhad babhtála á dhúnadh"
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: Tá brón orm, bhí an t-ordú seo díchumasaithe, níorbh fhéidir "
-#~ "leabharlanna MzScheme a luchtú."
+msgid "E73: tag stack empty"
+msgstr "E73: tá cruach na gclibeanna folamh"
-#~ msgid "invalid expression"
-#~ msgstr "slonn neamhbhailí"
+msgid "E74: Command too complex"
+msgstr "E74: Ordú róchasta"
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "díchumasaíodh sloinn ag am an tiomsaithe"
+msgid "E75: Name too long"
+msgstr "E75: Ainm rófhada"
-#~ msgid "hidden option"
-#~ msgstr "rogha fholaithe"
+msgid "E76: Too many ["
+msgstr "E76: an iomarca ["
-#~ msgid "unknown option"
-#~ msgstr "rogha anaithnid"
+msgid "E77: Too many file names"
+msgstr "E77: An iomarca ainmneacha comhaid"
-#~ msgid "window index is out of range"
-#~ msgstr "innéacs fuinneoige as raon"
+msgid "E488: Trailing characters"
+msgstr "E488: Carachtair chun deiridh"
-#~ msgid "couldn't open buffer"
-#~ msgstr "ní féidir maolán a oscailt"
+msgid "E78: Unknown mark"
+msgstr "E78: Marc anaithnid"
-#~ msgid "cannot save undo information"
-#~ msgstr "ní féidir eolas cealaithe a shábháil"
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Ní féidir saoróga a leathnú"
-#~ msgid "cannot delete line"
-#~ msgstr "ní féidir an líne a scriosadh"
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: ní cheadaítear 'winheight' a bheith níos lú ná 'winminheight'"
-#~ msgid "cannot replace line"
-#~ msgstr "ní féidir an líne a athchur"
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: ní cheadaítear 'winwidth' a bheith níos lú ná 'winminwidth'"
-#~ msgid "cannot insert line"
-#~ msgstr "ní féidir líne a ionsá"
+msgid "E80: Error while writing"
+msgstr "E80: Earráid agus á scríobh"
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ní cheadaítear carachtair líne nua sa teaghrán"
+msgid "E939: Positive count required"
+msgstr "E939: Uimhir dheimhneach de dhíth"
-#~ msgid "Vim error: ~a"
-#~ msgstr "earráid Vim: ~a"
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> á úsáid nach i gcomhthéacs scripte"
-#~ msgid "Vim error"
-#~ msgstr "earráid Vim"
+msgid "E449: Invalid expression received"
+msgstr "E449: Fuarthas slonn neamhbhailí"
-#~ msgid "buffer is invalid"
-#~ msgstr "maolán neamhbhailí"
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Réigiún cosanta, ní féidir é a athrú"
-#~ msgid "window is invalid"
-#~ msgstr "fuinneog neamhbhailí"
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: Ní cheadaíonn NetBeans aon athrú i gcomhaid inléite amháin"
-#~ msgid "linenr out of range"
-#~ msgstr "líne-uimhir as raon"
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: úsáideann an patrún níos mó cuimhne ná 'maxmempattern'"
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "ní cheadaítear é seo i mbosca gainimh Vim"
+msgid "E749: empty buffer"
+msgstr "E749: maolán folamh"
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: Tá brón orm, níl an t-ordú seo le fáil, níorbh fhéidir an "
-#~ "leabharlann Python a luchtú."
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Níl a leithéid de mhaolán %ld"
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Ní féidir Python a rith go hathchúrsach"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Patrún nó teormharcóir neamhbhailí cuardaigh"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "ní féidir tréithe OutputObject a scriosadh"
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Tá an comhad luchtaithe i maolán eile"
-#~ msgid "softspace must be an integer"
-#~ msgstr "caithfidh softspace a bheith ina shlánuimhir"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Rogha '%s' gan socrú"
-#~ msgid "invalid attribute"
-#~ msgstr "aitreabúid neamhbhailí"
+msgid "E850: Invalid register name"
+msgstr "E850: Ainm neamhbhailí tabhaill"
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "liosta teaghrán ag teastáil ó writelines()"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Comhadlann gan aimsiú in '%s': \"%s\""
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: Earráid agus réada I/A á dtúsú"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "Buaileadh an BARR le linn an chuardaigh, ag leanúint ag an CHRÍOCH"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "rinneadh iarracht ar mhaolán scriosta a rochtain"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "Buaileadh an BUN le linn an chuardaigh, ag leanúint ag an BHARR"
-#~ msgid "line number out of range"
-#~ msgstr "líne-uimhir as raon"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Eochair chriptiúcháin le haghaidh \"%s\" de dhíth"
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<réad maoláin (scriosta) ag %p>"
+msgid "empty keys are not allowed"
+msgstr "ní cheadaítear eochracha folmha"
-#~ msgid "invalid mark name"
-#~ msgstr "ainm neamhbhailí mairc"
+msgid "dictionary is locked"
+msgstr "tá an foclóir faoi ghlas"
-#~ msgid "no such buffer"
-#~ msgstr "níl a leithéid de mhaolán ann"
+msgid "list is locked"
+msgstr "tá an liosta faoi ghlas"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "rinneadh iarracht ar fhuinneog scriosta a rochtain"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "níorbh fhéidir eochair '%s' a chur leis an bhfoclóir"
-#~ msgid "readonly attribute"
-#~ msgstr "tréith inléite amháin"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "ní mór don innéacs a bheith ina shlánuimhir nó ina shlisne, seachas %s"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "cúrsóir taobh amuigh den mhaolán"
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "bhíothas ag súil le str() nó unicode(), ach fuarthas %s"
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<réad fuinneoige (scriosta) ag %p>"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "bhíothas ag súil le bytes() nó str(), ach fuarthas %s"
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<réad fuinneoige (anaithnid) ag %p>"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr ""
+"bhíothas ag súil le int(), long(), nó rud éigin inathraithe ina long(), ach "
+"fuarthas %s"
-#~ msgid "<window %d>"
-#~ msgstr "<fuinneog %d>"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr ""
+"bhíothas ag súil le int() nó rud éigin inathraithe ina int(), ach fuarthas %s"
-#~ msgid "no such window"
-#~ msgstr "níl a leithéid d'fhuinneog ann"
+msgid "value is too large to fit into C int type"
+msgstr "tá an luach níos mó ná athróg int sa teanga C"
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: caithfidh $_ a bheith cineál Teaghráin"
+msgid "value is too small to fit into C int type"
+msgstr "tá an luach níos lú ná athróg int sa teanga C"
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Tá brón orm, níl an t-ordú seo le fáil, níorbh fhéidir an "
-#~ "leabharlann Ruby a luchtú."
+msgid "number must be greater than zero"
+msgstr "ní mór don uimhir a bheith deimhneach"
+
+msgid "number must be greater or equal to zero"
+msgstr "ní mór don uimhir a bheith >= 0"
+
+msgid "can't delete OutputObject attributes"
+msgstr "ní féidir tréithe OutputObject a scriosadh"
+
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "aitreabúid neamhbhailí: %s"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Earráid agus réada I/A á dtúsú"
+
+msgid "failed to change directory"
+msgstr "níorbh fhéidir an chomhadlann a athrú"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr ""
+"bhíothas ag súil le 3-chodach mar thoradh ar imp.find_module(), ach fuarthas "
+"%s"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr ""
+"bhíothas ag súil le 3-chodach mar thoradh ar imp.find_module(), ach fuarthas "
+"%d-chodach"
+
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "earráid inmheánach: fuarthas codach NULL ar ais ó imp.find_module"
+
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "ní féidir tréithe vim.Dictionary a scriosadh"
+
+msgid "cannot modify fixed dictionary"
+msgstr "ní féidir foclóir socraithe a athrú"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "ní féidir tréith %s a shocrú"
+
+msgid "hashtab changed during iteration"
+msgstr "athraíodh an haistáb le linn atriallta"
+
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "bhíothas ag súil le heilimint de mhéid 2, ach fuarthas méid %d"
+
+msgid "list constructor does not accept keyword arguments"
+msgstr "ní ghlacann cruthaitheoir an liosta le hargóintí eochairfhocail"
+
+msgid "list index out of range"
+msgstr "innéacs liosta as raon"
+
+#. No more suitable format specifications in python-2.3
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "earráid inmheánach: níl aon fháil ar mhír %d sa liosta vim"
+
+msgid "slice step cannot be zero"
+msgstr "ní cheadaítear slisne le céim 0"
+
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "iarracht ar sheicheamh níos mó ná %d a shannadh do shlisne fadaithe"
+
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "earráid inmheánach: níl aon mhír %d sa liosta vim"
+
+msgid "internal error: not enough list items"
+msgstr "earráid inmheánach: níl go leor míreanna liosta ann"
+
+msgid "internal error: failed to add item to list"
+msgstr "earráid inmheánach: níorbh fhéidir mír a chur leis an liosta"
+
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr "iarracht ar sheicheamh de mhéid %d a shannadh do shlisne de mhéid %d"
+
+msgid "failed to add item to list"
+msgstr "níorbh fhéidir mír a chur leis an liosta"
+
+msgid "cannot delete vim.List attributes"
+msgstr "ní féidir tréithe vim.List a scriosadh"
+
+msgid "cannot modify fixed list"
+msgstr "ní féidir liosta socraithe a athrú"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "níl feidhm %s gan ainm ann"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "níl feidhm %s ann"
+
+#, c-format
+msgid "failed to run function %s"
+msgstr "níorbh fhéidir feidhm %s a rith"
+
+msgid "unable to get option value"
+msgstr "ní féidir luach na rogha a fháil"
+
+msgid "internal error: unknown option type"
+msgstr "earráid inmheánach: cineál rogha anaithnid"
+
+msgid "problem while switching windows"
+msgstr "tharla earráid agus an fhuinneog á hathrú"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "ní féidir rogha chomhchoiteann %s a dhíshocrú"
+
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "ní féidir rogha %s gan luach comhchoiteann a dhíshocrú"
+
+msgid "attempt to refer to deleted tab page"
+msgstr "tagairt déanta do leathanach cluaisíní scriosta"
+
+msgid "no such tab page"
+msgstr "níl a leithéid de leathanach cluaisíní ann"
+
+msgid "attempt to refer to deleted window"
+msgstr "rinneadh iarracht ar fhuinneog scriosta a rochtain"
+
+msgid "readonly attribute: buffer"
+msgstr "tréith inléite amháin: maolán"
+
+msgid "cursor position outside buffer"
+msgstr "cúrsóir taobh amuigh den mhaolán"
+
+msgid "no such window"
+msgstr "níl a leithéid d'fhuinneog ann"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "rinneadh iarracht ar mhaolán scriosta a rochtain"
+
+msgid "failed to rename buffer"
+msgstr "níorbh fhéidir ainm nua a chur ar an maolán"
+
+msgid "mark name must be a single character"
+msgstr "ní cheadaítear ach carachtar amháin in ainm an mhairc"
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: \"return\" gan choinne"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "bhíothas ag súil le réad vim.Buffer, ach fuarthas %s"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "níorbh fhéidir athrú go dtí maolán a %d"
+
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "bhíothas ag súil le réad vim.Window, ach fuarthas %s"
+
+msgid "failed to find window in the current tab page"
+msgstr "níor aimsíodh fuinneog sa leathanach cluaisíní reatha"
+
+msgid "did not switch to the specified window"
+msgstr "níor athraíodh go dtí an fhuinneog roghnaithe"
+
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "bhíothas ag súil le réad vim.TabPage, ach fuarthas %s"
+
+msgid "did not switch to the specified tab page"
+msgstr "níor athraíodh go dtí an leathanach cluaisíní roghnaithe"
+
+msgid "failed to run the code"
+msgstr "níorbh fhéidir an cód a chur ar siúl"
+
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Ní bhfuarthas réad bailí python ar ais ó Eval"
+
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Níorbh fhéidir luach vim a dhéanamh as an réad python"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "ní féidir foclóir vim a dhéanamh as %s"
+
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "ní féidir liosta vim a dhéanamh as %s"
+
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "ní féidir struchtúr vim a dhéanamh as %s"
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: \"next\" gan choinne"
+msgid "internal error: NULL reference passed"
+msgstr "earráid inmheánach: tagairt NULL seolta"
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: \"break\" gan choinne"
+msgid "internal error: invalid value type"
+msgstr "earráid inmheánach: cineál neamhbhailí"
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: \"redo\" gan choinne"
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"Níorbh fhéidir path_hook a shocrú: ní liosta é sys.path_hooks\n"
+"Ba chóir duit na rudaí seo a leanas a dhéanamh:\n"
+"- cuir vim.path_hook le deireadh sys.path_hooks\n"
+"- cuir vim.VIM_SPECIAL_PATH le deireadh sys.path\n"
+
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"Níorbh fhéidir an chonair a shocrú: ní liosta é sys.path\n"
+"Ba chóir duit vim.VIM_SPECIAL_PATH a cheangal le deireadh sys.path"
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: \"retry\" taobh amuigh de chlásal tarrthála"
+#~ msgid "+-%s%3ld line: "
+#~ msgid_plural "+-%s%3ld lines: "
+#~ msgstr[0] "+-%s%3ld líne: "
+#~ msgstr[1] "+-%s%3ld líne: "
+#~ msgstr[2] "+-%s%3ld líne: "
+#~ msgstr[3] "+-%s%3ld líne: "
+#~ msgstr[4] "+-%s%3ld líne: "
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: eisceacht gan láimhseáil"
+#~ msgid "+--%3ld line folded "
+#~ msgid_plural "+--%3ld lines folded "
+#~ msgstr[0] "+--%3ld líne fillte "
+#~ msgstr[1] "+--%3ld líne fillte "
+#~ msgstr[2] "+--%3ld líne fillte "
+#~ msgstr[3] "+--%3ld líne fillte "
+#~ msgstr[4] "+--%3ld líne fillte "
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: stádas anaithnid longjmp %d"
+#~ msgid "Type :quit<Enter> to exit Vim"
+#~ msgstr "Clóscríobh :quit<Enter> chun Vim a scor"
+
+#~ msgid "Zero count"
+#~ msgstr "Nialas"
+
+#~ msgid "E693: Can only compare Funcref with Funcref"
+#~ msgstr "E693: Is féidir Funcref a chur i gcomparáid le Funcref eile amháin"
+
+#~ msgid "E706: Variable type mismatch for: %s"
+#~ msgstr "E706: Mímheaitseáil idir cineálacha athróige: %s"
+
+#~ msgid "%ld characters"
+#~ msgstr "%ld carachtar"
#~ msgid "Toggle implementation/definition"
#~ msgstr "Scoránaigh feidhmiú/sainmhíniú"
@@ -7073,255 +7236,112 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgid "Sniff: Error during write. Disconnected"
#~ msgstr "Sniff: Earráid sa scríobh. Dínasctha"
-#~ msgid "invalid buffer number"
-#~ msgstr "uimhir neamhbhailí mhaoláin"
-
-#~ msgid "not implemented yet"
-#~ msgstr "níl ar fáil"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "ní féidir lín(t)e a shocrú"
-
-#~ msgid "mark not set"
-#~ msgstr "marc gan socrú"
-
-#~ msgid "row %d column %d"
-#~ msgstr "líne %d colún %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "ní féidir líne a ionsá/iarcheangal"
-
-#~ msgid "unknown flag: "
-#~ msgstr "bratach anaithnid: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "vimOption anaithnid"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "idirbhriseadh méarchláir"
-
-#~ msgid "vim error"
-#~ msgstr "earráid vim"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "ní féidir ordú maoláin/fuinneoige a chruthú: réad á scriosadh"
+#~ msgid " Quit, or continue with caution.\n"
+#~ msgstr " Scoir, nó lean ar aghaidh go hairdeallach.\n"
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "ní féidir ordú aisghlaoch a chlárú: maolán/fuinneog á scriosadh cheana"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: EARRÁID MHARFACH TCL: liosta truaillithe tagartha!? Seol tuairisc "
-#~ "fhabht chuig <vim-dev@vim.org> le do thoil"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "ní féidir ordú aisghlaoch a chlárú: tagairt mhaolán/fhuinneoige gan aimsiú"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: Tá brón orm, níl an t-ordú seo le fáil: níorbh fhéidir an "
-#~ "leabharlann Tcl a luchtú."
-
-#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
-#~ msgstr ""
-#~ "E281: EARRÁID TCL: níl an cód scortha ina shlánuimhir!? Seol tuairisc "
-#~ "fhabht chuig <vim-dev@vim.org> le do thoil"
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: cód scortha %d"
+#~ msgid "Cannot connect to Netbeans #2"
+#~ msgstr "Ní féidir nascadh le Netbeans #2"
-#~ msgid "cannot get line"
-#~ msgstr "ní féidir an líne a fháil"
+#~ msgid "read from Netbeans socket"
+#~ msgstr "léadh ó shoicéad Netbeans"
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Ní féidir ainm fhreastalaí ordaithe a chlárú"
+#~ msgid "'columns' is not 80, cannot execute external commands"
+#~ msgstr "ní 80 é 'columns', ní féidir orduithe seachtracha a rith"
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Theip ar sheoladh ordú chuig an sprioc-chlár"
+#~ msgid "Could not set security context "
+#~ msgstr "Níorbh fhéidir comhthéacs slándála a shocrú "
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Aitheantas neamhbhailí freastalaí in úsáid: %s"
+#~ msgid " for "
+#~ msgstr " le haghaidh "
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: Airí míchumtha sa chlárlann áisc VIM. Scriosta!"
+#~ msgid "Could not get security context "
+#~ msgstr "Níorbh fhéidir comhthéacs slándála a fháil "
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Níor tiomsaíodh an leagan Vim seo le `diff' ar fáil."
+#~ msgid ". Removing it!\n"
+#~ msgstr ". Á scriosadh!\n"
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "Ní féidir '-nb' a úsáid: níor cumasaíodh é ag am tiomsaithe\n"
+#~ msgid " (lang)"
+#~ msgstr " (teanga)"
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Earráid: Theip ar thosú gvim ó NetBeans\n"
+#~ msgid "E759: Format error in spell file"
+#~ msgstr "E759: Earráid fhormáide i gcomhad litrithe"
#~ msgid ""
#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
+#~ "MS-Windows 16/32-bit GUI version"
#~ msgstr ""
#~ "\n"
-#~ "Nuair nach cásíogair é, cuir '/' ag tosach na brataí chun í a chur sa "
-#~ "chás uachtair"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tCláraigh an gvim seo le haghaidh OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tDíchláraigh an gvim seo le haghaidh OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tRith agus úsáid an GUI (mar \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f nó --nofork\tTulra: Ná déan forc agus an GUI á thosú"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tNá húsáid newcli chun fuinneog a oscailt"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <gléas>\t\tBain úsáid as <gléas> do I/A"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tBain úsáid as <gvimrc> in ionad aon .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tCuir comhaid chriptithe in eagar"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <freastalaí>\tNasc vim leis an bhfreastalaí-X seo"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tNá naisc leis an bhfreastalaí X"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <comhaid>\tCuir <comhaid> in eagar le freastalaí Vim más féidir"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent <comhaid> Mar an gcéanna, ná déan gearán mura bhfuil "
-#~ "freastalaí ann"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <comhaid> Mar --remote ach fan leis na comhaid a bheith "
-#~ "curtha in eagar"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <comhaid> Mar an gcéanna, ná déan gearán mura "
-#~ "bhfuil freastalaí ann"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <comhaid> Cosúil le --remote ach oscail "
-#~ "cluaisín do gach comhad"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <eochracha>\tSeol <eochracha> chuig freastalaí Vim agus "
-#~ "scoir"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <slonn>\tLuacháil <slonn> le freastalaí Vim agus taispeáin "
-#~ "an toradh"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tTaispeáin freastalaithe Vim atá ar fáil agus scoir"
+#~ "Leagan GUI 16/32 giotán MS-Windows"
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <ainm>\tSeol chuig/Téigh i do fhreastalaí Vim <ainm>"
+#~ msgid " in Win32s mode"
+#~ msgstr " i mód Win32s"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
+#~ "MS-Windows 16-bit version"
#~ msgstr ""
#~ "\n"
-#~ "Argóintí ar eolas do gvim (leagan Motif):\n"
+#~ "Leagan 16 giotán MS-Windows"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
+#~ "32-bit MS-DOS version"
#~ msgstr ""
#~ "\n"
-#~ "Argóintí ar eolas do gvim (leagan neXtaw):\n"
+#~ "Leagan 32 giotán MS-DOS"
#~ msgid ""
#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
+#~ "16-bit MS-DOS version"
#~ msgstr ""
#~ "\n"
-#~ "Argóintí ar eolas do gvim (leagan Athena):\n"
+#~ "Leagan 16 giotán MS-DOS"
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <scáileán>\tRith vim ar <scáileán>"
+#~ msgid "WARNING: Windows 95/98/ME detected"
+#~ msgstr "RABHADH: Braitheadh Windows 95/98/ME"
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tTosaigh vim sa mhód íoslaghdaithe"
+#~ msgid "type :help windows95<Enter> for info on this"
+#~ msgstr "clóscríobh :help windows95<Enter> chun eolas a fháil "
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <ainm>\t\tÚsáid acmhainn mar a bheadh vim <ainm>"
+#~ msgid "function constructor does not accept keyword arguments"
+#~ msgstr "ní ghlacann cruthaitheoir na feidhme le hargóintí eochairfhocail"
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (Níl ar fáil)\n"
+#~ msgid "Vim dialog..."
+#~ msgstr "Dialóg Vim..."
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <dath>\tBain úsáid as <dath> don chúlra (-bg fosta)"
+#~ msgid "Font Selection"
+#~ msgstr "Roghnú Cló"
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <dath>\tÚsáid <dath> le haghaidh gnáth-théacs (fosta: -fg)"
+#~ msgid "softspace must be an integer"
+#~ msgstr "caithfidh softspace a bheith ina shlánuimhir"
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <cló>\t\tÚsáid <cló> le haghaidh gnáth-théacs (fosta: -fn)"
+#~ msgid "writelines() requires list of strings"
+#~ msgstr "liosta teaghrán ag teastáil ó writelines()"
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <cló>\tBain úsáid as <cló> do chló trom"
+#~ msgid "<buffer object (deleted) at %p>"
+#~ msgstr "<réad maoláin (scriosta) ag %p>"
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <cló>\tÚsáid <cló> le haghaidh téacs iodálach"
+#~ msgid "<window object (deleted) at %p>"
+#~ msgstr "<réad fuinneoige (scriosta) ag %p>"
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr ""
-#~ "-geometry <geoim>\tÚsáid <geoim> le haghaidh na céimseatan tosaigh "
-#~ "(fosta: -geom)"
+#~ msgid "<window object (unknown) at %p>"
+#~ msgstr "<réad fuinneoige (anaithnid) ag %p>"
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <leithead>\tSocraigh <leithead> na himlíne (-bw fosta)"
+#~ msgid "<window %d>"
+#~ msgstr "<fuinneog %d>"
#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <leithead> Socraigh leithead na scrollbharraí a bheith "
-#~ "<leithead> (fosta: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
+#~ "org"
#~ msgstr ""
-#~ "-menuheight <airde>\tSocraigh airde an bharra roghchláir a bheith <airde> "
-#~ "(fosta: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tÚsáid fís aisiompaithe (fosta: -rv)"
+#~ "E281: EARRÁID TCL: níl an cód scortha ina shlánuimhir!? Seol tuairisc "
+#~ "fhabht chuig <vim-dev@vim.org> le do thoil"
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tNá húsáid fís aisiompaithe (fosta: +rv)"
+#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
+#~ msgstr "-name <ainm>\t\tÚsáid acmhainn mar a bheadh vim <ainm>"
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <acmhainn>\tSocraigh an acmhainn sainithe"
+#~ msgid "\t\t\t (Unimplemented)\n"
+#~ msgstr "\t\t\t (Níl ar fáil)\n"
#~ msgid ""
#~ "\n"
@@ -7336,66 +7356,6 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgid "--rows <number>\tInitial height of window in rows"
#~ msgstr "--rows <uimhir>\tAirde fhuinneoige i dtosach (rónna)"
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argóintí ar eolas do gvim (leagan GTK+):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <scáileán>\tRith vim ar <scáileán> (fosta: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr ""
-#~ "--role <ról>\tSocraigh ról sainiúil chun an phríomhfhuinneog a aithint"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tOscail Vim isteach i ngiuirléid GTK eile"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <máthairchlár>\tOscail Vim isteach sa mháthairchlár"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tOscail Vim isteach i ngiuirléid win32 eile"
-
-#~ msgid "No display"
-#~ msgstr "Gan taispeáint"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Theip ar seoladh.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Theip ar seoladh. Ag baint triail as go logánta\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d as %d déanta"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Gan taispeáint: Theip ar sheoladh sloinn.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Theip ar sheoladh sloinn.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Ní códleathanach bailí é"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Theip ar chruthú comhthéacs ionchuir"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Theip ar oscailt mhodh ionchuir"
-
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr ""
-#~ "E287: Rabhadh: Níorbh fhéidir aisghlaoch léirscriosta a shocrú le IM"
-
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: Ní thacaíonn an modh ionchuir aon stíl"
-
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: ní thacaíonn an modh ionchuir mo chineál réamheagair"
-
#~ msgid "E290: over-the-spot style requires fontset"
#~ msgstr "E290: tacar cló ag teastáil ó stíl thar-an-spota"
@@ -7407,197 +7367,15 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgid "E292: Input Method Server is not running"
#~ msgstr "E292: Níl an Freastalaí Mhodh Ionchuir ag rith"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [ní inúsáidte leis an leagan seo Vim]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "Bain an roghchlár seo"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Dialóg `Roghnaigh Comhadlann'"
-
-#~ msgid "Save File dialog"
-#~ msgstr "Dialóg `Sábháil Comhad'"
-
-#~ msgid "Open File dialog"
-#~ msgstr "Dialóg `Oscail Comhad'"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Níl brabhsálaí comhaid ar fáil sa mhód consóil"
-
#~ msgid "Vim: preserving files...\n"
#~ msgstr "Vim: comhaid á gcaomhnú...\n"
#~ msgid "Vim: Finished.\n"
#~ msgstr "Vim: Críochnaithe.\n"
-#~ msgid "ERROR: "
-#~ msgstr "EARRÁID: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[beart] iomlán dáilte-saor %<PRIu64>-%<PRIu64>, in úsáid %<PRIu64>, buaic "
-#~ "%<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[glaonna] re/malloc(): %<PRIu64>, free(): %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Tá an líne ag éirí rófhada"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Earráid inmheánach: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Cruth neamhcheadaithe luiche"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "Iontráil eochair chriptiúcháin: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "Iontráil an eochair arís: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Níl na heochracha comhoiriúnach le chéile!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Ní féidir nascadh le Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Ní féidir nascadh le Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Mód mícheart rochtana ar an chomhad eolas naisc NetBeans: \"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "léadh ó shoicéad Netbeans"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Cailleadh nasc NetBeans le haghaidh maoláin %<PRId64>"
-
#~ msgid "E505: "
#~ msgstr "E505: "
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Níl an ghné Eval le fáil"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "%<PRId64> líne á saoradh"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Ní féidir 'term' a athrú sa GUI"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Úsáid \":gui\" chun an GUI a chur ag obair"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Ní féidir é a athrú sa GUI GTK+ 2"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Cló(nna) neamhbhailí"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ní féidir tacar cló a roghnú"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Tacar cló neamhbhailí"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ní féidir cló leathan a roghnú"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Cló leathan neamhbhailí"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Gan tacaíocht luiche"
-
-#~ msgid "cannot open "
-#~ msgstr "ní féidir a oscailt: "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Ní féidir fuinneog a oscailt!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Tá gá le Amigados leagan 2.04 nó níos déanaí\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Tá gá le %s, leagan %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Ní féidir NIL a oscailt:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "Ní féidir a chruthú: "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim á scor le stádas %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "ní féidir mód consóil a athrú ?!\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ní consól é seo??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Ní féidir blaosc a rith le rogha -f"
-
-#~ msgid "Cannot execute "
-#~ msgstr "Ní féidir blaosc a rith: "
-
-#~ msgid "shell "
-#~ msgstr "blaosc "
-
-#~ msgid " returned\n"
-#~ msgstr " aisfhilleadh\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE róbheag."
-
-#~ msgid "I/O ERROR"
-#~ msgstr "EARRÁID I/A"
-
-#~ msgid "Message"
-#~ msgstr "Teachtaireacht"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "ní 80 é 'columns', ní féidir orduithe seachtracha a rith"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Theip ar roghnú printéara"
-
-#~ msgid "to %s on %s"
-#~ msgstr "go %s ar %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Clófhoireann anaithnid printéara: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Earráid phriontála: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "'%s' á phriontáil"
-
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr ""
-#~ "E244: Ainm neamhcheadaithe ar thacar carachtar \"%s\" mar pháirt d'ainm "
-#~ "cló \"%s\""
-
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Carachtar neamhcheadaithe '%c' mar pháirt d'ainm cló \"%s\""
-
#~ msgid "Vim: Double signal, exiting\n"
#~ msgstr "Vim: Comhartha dúbailte, ag scor\n"
@@ -7607,419 +7385,23 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgid "Vim: Caught deadly signal\n"
#~ msgstr "Vim: Fuarthas comhartha marfach\n"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Thóg %<PRId64> ms chun an scáileán X a oscailt"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Fuarthas earráid ó X\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "Theip ar thástáil an scáileáin X"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Oscailt an scáileáin X thar am"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ní féidir an bhlaosc sh a rith\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ní féidir píopaí a chruthú\n"
-
-# "fork" not in standard refs/corpus. Maybe want a "gabhl*" word instead? -KPS
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ní féidir forc a dhéanamh\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ordú críochnaithe\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "Chaill XSMP an nasc ICE"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "Theip ar oscailt an scáileáin X"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "Iarratas sábháil-do-féin á láimhseáil ag XSMP"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "Nasc á oscailt ag XSMP"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "Theip ar fhaire nasc ICE XSMP"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "Theip ar XSMP SmcOpenConnection: %s"
-
-#~ msgid "At line"
-#~ msgstr "Ag líne"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Níorbh fhéidir vim32.dll a luchtú!"
-
-#~ msgid "VIM Error"
-#~ msgstr "Earráid VIM"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Níorbh fhéidir pointeoirí feidhme a chóiriú i gcomhair an DLL!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "d'aisfhill an bhlaosc %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Fuarthas teagmhas %s\n"
-
-#~ msgid "close"
-#~ msgstr "dún"
-
-#~ msgid "logoff"
-#~ msgstr "logáil amach"
-
-#~ msgid "shutdown"
-#~ msgstr "múchadh"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Ní bhfuarthas an t-ordú"
-
-#~ 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 ""
-#~ "Níor aimsíodh VIMRUN.EXE i do $PATH.\n"
-#~ "Ní mhoilleoidh orduithe seachtracha agus iad curtha i gcrích.\n"
-#~ "Féach ar :help win32-vimrun chun níos mó eolas a fháil."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Rabhadh Vim"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Tiontú i %s gan tacaíocht"
-
#~ msgid "E396: containedin argument not accepted here"
#~ msgstr "E396: ní ghlactar leis an argóint containedin anseo"
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Teascadh conair an chomhaid clibeanna le haghaidh %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "tosaíodh blaosc nua\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "Úsáideadh CUT_BUFFER0 in ionad roghnúcháin folaimh"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Ní féidir a chealú; lean ar aghaidh mar sin féin"
-
# columns?
#~ msgid "number changes time"
#~ msgstr "uimhir athruithe am"
#~ msgid ""
#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan GUI 16/32 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan GUI 64 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan GUI 32 giotán MS-Windows"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " i mód Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " le tacaíocht OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan consóil 64 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan consóil 32 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan 16 giotán MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan 32 giotán MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan 16 giotán MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan MacOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan MacOS"
-
-#~ msgid ""
-#~ "\n"
#~ "RISC OS version"
#~ msgstr ""
#~ "\n"
#~ "Leagan RISC OS"
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan mór "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan coitianta "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan beag "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Leagan beag bídeach "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "le GUI GTK2-GNOME."
-
#~ msgid "with GTK-GNOME GUI."
#~ msgstr "le GUI GTK-GNOME."
-#~ msgid "with GTK2 GUI."
-#~ msgstr "le GUI GTK2."
-
-#~ msgid "with GTK GUI."
-#~ msgstr "le GUI GTK."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "le GUI X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "le GUI X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "le GUI X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "le GUI Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "le GUI."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "le GUI Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "le GUI Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "le GUI (clasaiceach)."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " comhad gvimrc córais: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " comhad gvimrc úsáideora: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "dara comhad gvimrc úsáideora: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "tríú comhad gvimrc úsáideora: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " comhad roghchláir an chórais: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Tiomsaitheoir: "
-
-# don't see where to localize "Help->Orphans"? --kps
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "roghchlár Help->Orphans chun eolas a fháil "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Á rith gan mhóid, ag ionsá an téacs atá iontráilte"
-
-# same problem --kps
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "roghchlár Edit->Global Settings->Toggle Insert Mode "
-
-#~ msgid " for two modes "
-#~ msgstr " do dhá mhód "
-
-# same problem --kps
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "roghchlár Edit->Global Settings->Toggle Vi Compatible"
-
-#~ msgid " for Vim defaults "
-#~ msgstr " le haghaidh réamhshocruithe Vim "
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "RABHADH: Braitheadh Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "clóscríobh :help windows95<Enter> chun eolas a fháil "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Níorbh fhéidir an leabharlann %s a oscailt"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "Tá brón orm, níl an t-ordú seo le fáil: níorbh fhéidir an leabharlann "
-#~ "Perl a luchtú."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Ní cheadaítear luacháil Perl i mbosca gainimh gan an modúl Safe"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Cuir in eagar le Vimeanna io&madúla"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Cuir in eagar le &Vim aonair"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Diff le Vim"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Cuir in Eagar le &Vim"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Cuir in Eagar le Vim beo - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Cuir an comhad roghnaithe in eagar le Vim"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr ""
-#~ "Earráid agus próiseas á chruthú: Deimhnigh go bhfuil gvim i do chonair!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "earráid gvimext.dll"
-
-#~ msgid "Path length too long!"
-#~ msgstr "Conair rófhada!"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Tacar cló anaithnid: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Clófhoireann anaithnid: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Ní cló aonleithid é \"%s\""
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Ní féidir feidhm %s leabharlainne a luchtú"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E26: Níl tacaíocht Eabhraise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E27: Níl tacaíocht Pheirsise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: Níl tacaíocht Araibise ar fáil: Níor cumasaíodh é ag am tiomsaithe\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: níl aon fhreastalaí cláraithe leis an ainm \"%s\""
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ní féidir an scáileán a oscailt"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Fuarthas slonn neamhbhailí"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Réigiún cosanta, ní féidir é a athrú"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: Ní cheadaíonn NetBeans aon athrú i gcomhaid inléite amháin"
-
#~ msgid "E569: maximum number of cscope connections reached"
#~ msgstr "E569: ní cheadaítear níos mó ná an líon uasta nasc cscope"
@@ -8080,8 +7462,8 @@ msgstr "E446: Níl ainm comhaid faoin chúrsóir"
#~ msgstr ""
#~ "Ní mór do charachtar a úsáidtear ar SLASH a bheith ASCII; i %s líne %d: %s"
-#~ msgid "%<PRId64> changes"
-#~ msgstr "%<PRId64> athrú"
+#~ msgid "%ld changes"
+#~ msgstr "%ld athrú"
#~ msgid "with KDE GUI."
#~ msgstr "le GUI KDE."
diff --git a/src/nvim/po/it.po b/src/nvim/po/it.po
index 084102da60..9d5709e1ab 100644
--- a/src/nvim/po/it.po
+++ b/src/nvim/po/it.po
@@ -1,6 +1,8 @@
-# Italian Translation for Vim
+# Italian translation for Vim
#
-# FIRST AUTHOR Antonio Colombo <azc100@gmail.com>, 2000
+# Antonio Colombo <azc100@gmail.com>, 2000
+# Vlad Sandrini <vlad.gently@gmail.com>, 2002
+# Luciano Montanaro <mikelima@cirulla.net>, 2006
#
# Ogni commento è benvenuto...
# Every remark is very welcome...
@@ -11,7 +13,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: vim 7.4\n"
+"Project-Id-Version: vim 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-11 12:10+0100\n"
"PO-Revision-Date: 2016-02-11 14:42+0200\n"
@@ -884,7 +886,6 @@ msgstr "E730: uso di Lista come Stringa"
msgid "E731: using Dictionary as a String"
msgstr "E731: uso di Dizionario come Stringa"
-# nuovo
msgid "E908: using an invalid value as a String"
msgstr "E908: uso di un valore non valido come Stringa"
@@ -1402,6 +1403,45 @@ msgstr "com: %s"
msgid "frame is zero"
msgstr "al livello zero"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() in channel_open()"
+
+msgid "E898: socket() in channel_open()"
+msgstr "E898: socket() in channel_open()"
+
+msgid "E903: received command with non-string argument"
+msgstr "E903: il comando ricevuto non aveva come argomento una stringa"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: l'ultimo argomento per espressione/chiamata dev'essere numerico"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: il terzo argomento della chiamata dev'essere una Lista"
+
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld riga: "
+msgstr[1] "+-%s%3ld righe: "
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: recevuto comando non conosciuto: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): scrittura in mancanza di connessione"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): scrittura non riuscita"
+
+msgid "Oldval = \"%s\""
+msgstr "Vecchioval = \"%s\""
+
+#, c-format
+msgid "Newval = \"%s\""
+msgstr "Nuovoval = \"%s\""
+
#, c-format
msgid "frame at highest level: %d"
msgstr "al livello più alto: %d"
@@ -2493,7 +2533,7 @@ msgid ""
"--- Auto-Commands ---"
msgstr ""
"\n"
-"--- Auto-Comandi ---"
+"--- Autocomandi ---"
#: ../fileio.c:6293
#, c-format
@@ -2541,7 +2581,7 @@ msgstr "E490: Non trovo alcuna piegatura"
#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: Non posso create piegatura con il 'foldmethod' in uso"
+msgstr "E350: Non posso creare piegatura con il 'foldmethod' in uso"
#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
@@ -2704,11 +2744,6 @@ msgstr "E900: 'Job id' non valido"
msgid "E901: Job table is full"
msgstr "E901: Job table piena"
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr "E902: \"%s\" non è un esegubile"
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3415,11 +3450,11 @@ msgstr "-q [errorfile] apri file col primo errore"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
-" uso:"
+" Uso:"
#: ../main.c:2189
msgid " vim [arguments] "
@@ -4294,10 +4329,6 @@ msgstr "riga %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Nome registro non valido: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Manutentore messaggi: Vlad Sandrini <marco@sandrini.biz>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Interruzione: "
@@ -4821,10 +4852,20 @@ msgstr ""
"\n"
"Non posso impostare il contesto di sicurezza per "
+msgid "E954: 24-bit colors are not supported on this environment"
+msgstr "E954: colori a 24-bit non supportati in questo ambiente"
+
+#, c-format
+msgid "E151: No match: %s"
+msgstr "E151: Nessuna corrispondenza: %s"
+
#, c-format
msgid "Could not set security context %s for %s"
msgstr "Non posso impostare il contesto di sicurezza %s per %s"
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Impossibile passare a un buffer che non ha un nome"
+
#, c-format
msgid "Could not get security context %s for %s. Removing it!"
msgstr "Non posso ottenere il contesto di sicurezza %s per %s. Lo rimuovo!"
@@ -5126,9 +5167,9 @@ msgstr "E876: (NFA regexp) Non c'è spazio per immagazzinare l'intero NFA "
#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
+"Could not open temporary log file for writing, displaying on stderr... "
msgstr ""
-"Non posso aprire il file temporaneo per la scrittura, mostro su stderr ... "
+"Non posso aprire il file temporaneo per la scrittura, mostro su stderr... "
#: ../regexp_nfa.c:4840
#, c-format
@@ -5360,15 +5401,23 @@ msgstr "E772: Il file ortografico è per versioni di Vim più recenti"
msgid "E770: Unsupported section in spell file"
msgstr "E770: Sezione non supportata nel file ortografico"
-#: ../spell.c:3762
+msgid "E944: Reverse range in character class"
+msgstr "E944: Intervallo invertito nella classe di caratteri"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: Intervallo troppo ampio nella classe di caratteri"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: La lista delle locazioni corrente è stata cambiata"
+
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Avviso: regione %s non supportata"
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: File .sug obsoleto, è necessario aggiornarlo: %s"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Lettura file affissi %s ..."
+msgid "Reading affix file %s..."
+msgstr "Lettura file affissi %s..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
@@ -5530,8 +5579,8 @@ msgstr "Il valore di %s è diverso da quello usato in un altro file .aff"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Lettura file dizionario %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Lettura file dizionario %s..."
#: ../spell.c:5611
#, c-format
@@ -5565,8 +5614,8 @@ msgstr "%d parole con caratteri non-ASCII ignorate in %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Lettura file parole %s ..."
+msgid "Reading word file %s..."
+msgstr "Lettura file parole %s..."
#: ../spell.c:6155
#, c-format
@@ -5635,8 +5684,8 @@ msgstr "Conteggio totale delle parole: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Scrivo file di suggerimenti %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "Scrivo file di suggerimenti %s..."
#: ../spell.c:7707 ../spell.c:7927
#, c-format
@@ -5662,8 +5711,8 @@ msgstr "Avviso: specificati sia composizione sia NOBREAK"
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Scrivo file ortografico %s ..."
+msgid "Writing spell file %s..."
+msgstr "Scrivo file ortografico %s..."
#: ../spell.c:7925
msgid "Done!"
@@ -5723,11 +5772,6 @@ msgstr "E753: Non trovato: %s"
msgid "E778: This does not look like a .sug file: %s"
msgstr "E778: Questo non sembra un file .sug: %s"
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: File .sug obsoleto, è necessario aggiornarlo: %s"
-
#: ../spell.c:9286
#, c-format
msgid "E780: .sug file is for newer version of Vim: %s"
diff --git a/src/nvim/po/ja.euc-jp.po b/src/nvim/po/ja.euc-jp.po
index 85042e3506..dc3c4368ab 100644
--- a/src/nvim/po/ja.euc-jp.po
+++ b/src/nvim/po/ja.euc-jp.po
@@ -1,10 +1,11 @@
+
# Japanese translation for Vim
#
# Do ":help uganda" in Vim to read copying and usage conditions.
# Do ":help credits" in Vim to see a list of people who contributed.
#
-# Copyright (C) 2001-2016 MURAOKA Taro <koron.kaoriya@gmail.com>,
-# vim-jp (http://vim-jp.org/)
+# Copyright (C) 2001-2018 MURAOKA Taro <koron.kaoriya@gmail.com>,
+# vim-jp <http://vim-jp.org/>
#
# THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
#
@@ -12,215 +13,188 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Vim 7.4\n"
+"Project-Id-Version: Vim 8.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-02-01 09:02+0900\n"
-"PO-Revision-Date: 2016-02-01 09:08+0900\n"
+"POT-Creation-Date: 2018-07-18 00:43+0900\n"
+"PO-Revision-Date: 2017-05-18 00:45+0900\n"
"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
-"Language-Team: vim-jp (https://github.com/vim-jp/lang-ja)\n"
-"Language: Japanese\n"
+"Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n"
+"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=euc-jp\n"
-"Content-Transfer-Encoding: 8-bit\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "¥ª¥×¥·¥ç¥ó¤ÎÃͤϼèÆÀ¤Ç¤­¤Þ¤»¤ó"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() ¤¬¶õ¥Ñ¥¹¥ï¡¼¥É¤Ç¸Æ¤Ó½Ð¤µ¤ì¤Þ¤·¤¿"
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "ÆâÉô¥¨¥é¡¼: ̤ÃΤΥª¥×¥·¥ç¥ó·¿¤Ç¤¹"
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Blowfish°Å¹æ¤Î¥Ó¥Ã¥°/¥ê¥È¥ë¥¨¥ó¥Ç¥£¥¢¥ó¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: sha256¤Î¥Æ¥¹¥È¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Blowfish°Å¹æ¤Î¥Æ¥¹¥È¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Quickfix¥ê¥¹¥È]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: autocommand¤¬¥³¥Þ¥ó¥É¤ÎÄä»ß¤ò°ú¤­µ¯¤³¤·¤Þ¤·¤¿"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: ¥Ð¥Ã¥Õ¥¡¤ò1¤Ä¤âºîÀ®¤Ç¤­¤Ê¤¤¤Î¤Ç, ½ªÎ»¤·¤Þ¤¹..."
+msgstr "E82: ¥Ð¥Ã¥Õ¥¡¤ò1¤Ä¤âºîÀ®¤Ç¤­¤Ê¤¤¤Î¤Ç¡¢½ªÎ»¤·¤Þ¤¹..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: ¥Ð¥Ã¥Õ¥¡¤òºîÀ®¤Ç¤­¤Ê¤¤¤Î¤Ç, ¾¤Î¤ò»ÈÍѤ·¤Þ¤¹..."
+msgstr "E83: ¥Ð¥Ã¥Õ¥¡¤òºîÀ®¤Ç¤­¤Ê¤¤¤Î¤Ç¡¢Â¾¤Î¤ò»ÈÍѤ·¤Þ¤¹..."
+
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: ¥Ð¥Ã¥Õ¥¡¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: »ÈÍÑÃæ¤Î¥Ð¥Ã¥Õ¥¡¤òºï½ü¤·¤è¤¦¤È»î¤ß¤Þ¤·¤¿"
-#: ../buffer.c:763
msgid "E515: No buffers were unloaded"
msgstr "E515: ²òÊü¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: ºï½ü¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../buffer.c:767
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:782
msgid "1 buffer wiped out"
msgstr "1 ¸Ä¤Î¥Ð¥Ã¥Õ¥¡¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d ¸Ä¤Î¥Ð¥Ã¥Õ¥¡¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: ºÇ¸å¤Î¥Ð¥Ã¥Õ¥¡¤Ï²òÊü¤Ç¤­¤Þ¤»¤ó"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Êѹ¹¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
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
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: ºÇ¸å¤Î¥Ð¥Ã¥Õ¥¡¤ò±Û¤¨¤Æ°Üư¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: ºÇ½é¤Î¥Ð¥Ã¥Õ¥¡¤è¤êÁ°¤Ø¤Ï°Üư¤Ç¤­¤Þ¤»¤ó"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤ÎÊѹ¹¤ÏÊݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤ÇÊѹ¹¤òÇË´þ)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: ¥Ð¥Ã¥Õ¥¡ %ld ¤ÎÊѹ¹¤ÏÊݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤ÇÊѹ¹¤òÇË´þ)"
+
+msgid "E948: Job still running (add ! to end the job)"
+msgstr "E948: ¥¸¥ç¥Ö¤Ï¤Þ¤À¼Â¹ÔÃæ¤Ç¤¹ (! ¤òÄɲäǥ¸¥ç¥Ö¤ò½ªÎ»)"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤òÄɲäÇÊѹ¹¤òÇË´þ)"
+
+msgid "E948: Job still running"
+msgstr "E948: ¥¸¥ç¥Ö¤Ï¤Þ¤À¼Â¹ÔÃæ¤Ç¤¹"
+
+msgid "E37: No write since last change"
+msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: ·Ù¹ð: ¥Õ¥¡¥¤¥ë̾¤Î¥ê¥¹¥È¤¬Ä¹²á¤®¤Þ¤¹"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: ¥Ð¥Ã¥Õ¥¡ %ld ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: %s ¤ËÊ£¿ô¤Î³ºÅö¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: %s ¤Ë³ºÅö¤¹¤ë¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "¹Ô %<PRId64>"
+msgid "line %ld"
+msgstr "¹Ô %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: ¤³¤Î̾Á°¤Î¥Ð¥Ã¥Õ¥¡¤Ï´û¤Ë¤¢¤ê¤Þ¤¹"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [Êѹ¹¤¢¤ê]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[̤ÊÔ½¸]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[¿·¥Õ¥¡¥¤¥ë]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[ÆÉ¹þ¥¨¥é¡¼]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[ÆÉÀì]"
-#: ../buffer.c:2507 ../fileio.c:1807
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%%--"
+msgid "%ld lines --%d%%--"
+msgstr "%ld ¹Ô --%d%%--"
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "¹Ô %<PRId64> (Á´ÂÎ %<PRId64>) --%d%%-- col "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "¹Ô %ld (Á´ÂÎ %ld) --%d%%-- col "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[̵̾]"
-#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "¥Ø¥ë¥×"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[¥Ø¥ë¥×]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[¥×¥ì¥Ó¥å¡¼]"
-#: ../buffer.c:3528
msgid "All"
msgstr "Á´¤Æ"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "ËöÈø"
-#: ../buffer.c:3531
msgid "Top"
msgstr "ÀèÆ¬"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -228,11 +202,15 @@ msgstr ""
"\n"
"# ¥Ð¥Ã¥Õ¥¡¥ê¥¹¥È:\n"
-#: ../buffer.c:4289
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 'buftype' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç½ñ¹þ¤á¤Þ¤»¤ó"
+
+msgid "[Prompt]"
+msgstr "[¥×¥í¥ó¥×¥È]"
+
msgid "[Scratch]"
msgstr "[²¼½ñ¤­]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -240,634 +218,385 @@ msgstr ""
"\n"
"--- ¥µ¥¤¥ó ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "%s ¤Î¥µ¥¤¥ó:"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ¹Ô=%<PRId64> ¼±ÊÌ»Ò=%d ̾Á°=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " ¹Ô=%ld ¼±ÊÌ»Ò=%d ̾Á°=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E902: Cannot connect to port"
+msgstr "E902: ¥Ý¡¼¥È¤ËÀܳ¤Ç¤­¤Þ¤»¤ó"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: ÉÔÀµ¤Ê¥â¡¼¥É¤Ç¤¹"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: channel_open() Æâ¤Î gethostbyname() ¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: ¿ôÃͤ¬É¬ÍפǤ¹"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: channel_open() Æâ¤Î socket() ¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: ÉÔÀµ¤Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¤Ç¤¹"
+msgid "E903: received command with non-string argument"
+msgstr "E903: Èóʸ»úÎó¤Î°ú¿ô¤Î¥³¥Þ¥ó¥É¤ò¼õ¿®¤·¤Þ¤·¤¿"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: expr/call ¤ÎºÇ¸å¤Î°ú¿ô¤Ï¿ô»ú¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: call ¤Î3ÈÖÌܤΰú¿ô¤Ï¥ê¥¹¥È·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: %<PRId64> °Ê¾å¤Î¥Ð¥Ã¥Õ¥¡¤Ïdiff¤Ç¤­¤Þ¤»¤ó"
+msgid "E905: received unknown command: %s"
+msgstr "E905: ̤ÃΤΥ³¥Þ¥ó¥É¤ò¼õ¿®¤·¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): ÈóÀܳ¾õÂ֤ǽñ¤­¹þ¤ß¤Þ¤·¤¿"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): ½ñ¤­¹þ¤ß¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: %s() ¤Ë¥³¡¼¥ë¥Ð¥Ã¥¯¤Ï»È¤¨¤Þ¤»¤ó"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr ""
+"E912: raw ¤ä nl ¥â¡¼¥É¤Î¥Á¥ã¥Í¥ë¤Ë ch_evalexpr()/ch_sendexpr() ¤Ï»È¤¨¤Þ¤»¤ó"
+
+msgid "E906: not an open channel"
+msgstr "E906: ³«¤¤¤Æ¤¤¤Ê¤¤¥Á¥ã¥Í¥ë¤Ç¤¹"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: _io ¥Õ¥¡¥¤¥ë¤Ï _name ¤ÎÀßÄ꤬ɬÍפǤ¹"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: in_io ¥Ð¥Ã¥Õ¥¡¤Ï in_buf ¤« in_name ¤ÎÀßÄ꤬ɬÍפǤ¹"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: ¥Ð¥Ã¥Õ¥¡¤¬¥í¡¼¥É¤µ¤ì¤Æ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: ¥Õ¥¡¥¤¥ë¤¬Ì¤ÃΤÎÊýË¡¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "·Ù¹ð: ¼å¤¤°Å¹æÊýË¡¤ò»È¤Ã¤Æ¤¤¤Þ¤¹; :help 'cm' ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
+
+msgid "Enter encryption key: "
+msgstr "°Å¹æ²½ÍѤΥ­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+
+msgid "Enter same key again: "
+msgstr "¤â¤¦°ìÅÙÆ±¤¸¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+
+msgid "Keys don't match!"
+msgstr "¥­¡¼¤¬°ìÃפ·¤Þ¤»¤ó"
+
+msgid "[crypted]"
+msgstr "[°Å¹æ²½]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: ¼­½ñ·¿¤Ë¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: ¼­½ñ·¿¤Ë½ÅÊ£¥­¡¼¤¬¤¢¤ê¤Þ¤¹: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: ¼­½ñ·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: ¼­½ñ·¿¤ÎºÇ¸å¤Ë '}' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+msgid "extend() argument"
+msgstr "extend() ¤Î°ú¿ô"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: ¥­¡¼¤Ï´û¤Ë¸ºß¤·¤Þ¤¹: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: %ld °Ê¾å¤Î¥Ð¥Ã¥Õ¥¡¤Ïdiff¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: °ì»þ¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þ¤â¤·¤¯¤Ï½ñ¹þ¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: º¹Ê¬¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "¥Ñ¥Ã¥Á¥Õ¥¡¥¤¥ë"
+
msgid "E816: Cannot read patch output"
msgstr "E816: patch¤Î½ÐÎϤòÆÉ¹þ¤á¤Þ¤»¤ó"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: diff¤Î½ÐÎϤòÆÉ¹þ¤á¤Þ¤»¤ó"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: ¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤Ïº¹Ê¬¥â¡¼¥É¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: º¹Ê¬¥â¡¼¥É¤Ç¤¢¤ë¾¤Î¥Ð¥Ã¥Õ¥¡¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: º¹Ê¬¥â¡¼¥É¤Ç¤¢¤ë¾¤Î¥Ð¥Ã¥Õ¥¡¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr ""
"E101: º¹Ê¬¥â¡¼¥É¤Î¥Ð¥Ã¥Õ¥¡¤¬2¸Ä°Ê¾å¤¢¤ë¤Î¤Ç¡¢¤É¤ì¤ò»È¤¦¤«ÆÃÄê¤Ç¤­¤Þ¤»¤ó"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: ¥Ð¥Ã¥Õ¥¡ \"%s\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: ¥Ð¥Ã¥Õ¥¡ \"%s\" ¤Ïº¹Ê¬¥â¡¼¥É¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: ͽ´ü¤»¤º¥Ð¥Ã¥Õ¥¡¤¬Êѹ¹Êѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: ¹ç»ú¤ËEscape¤Ï»ÈÍѤǤ­¤Þ¤»¤ó"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: ¥­¡¼¥Þ¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :source ¤Ç¼è¹þ¤à¥Õ¥¡¥¤¥ë°Ê³°¤Ç¤Ï :loadkeymap ¤ò»È¤¨¤Þ¤»¤ó"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: ¶õ¤Î¥­¡¼¥Þ¥Ã¥×¥¨¥ó¥È¥ê"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " ¥­¡¼¥ï¡¼¥ÉÊä´° (^N^P)"
-#. 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)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " ¹Ô(Á´ÂÎ)Êä´° (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " ¥Õ¥¡¥¤¥ë̾Êä´° (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " ¥¿¥°Êä´° (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " ¥Ñ¥¹¥Ñ¥¿¡¼¥óÊä´° (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " ÄêµÁÊä´° (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " ¼­½ñÊä´° (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " ¥·¥½¡¼¥é¥¹Êä´° (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " ¥³¥Þ¥ó¥É¥é¥¤¥óÊä´° (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " ¥æ¡¼¥¶¡¼ÄêµÁÊä´° (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " ¥ª¥à¥ËÊä´° (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Ä֤꽤Àµ¸õÊä (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " ¶É½ê¥­¡¼¥ï¡¼¥ÉÊä´° (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "ÃÊÍî¤ÎºÇ¸å¤Ë¥Ò¥Ã¥È"
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: Êä´Ö´Ø¿ô¤¬¥¦¥£¥ó¥É¥¦¤òÊѹ¹¤·¤Þ¤·¤¿"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: Êä´°´Ø¿ô¤¬¥Æ¥­¥¹¥È¤òºï½ü¤·¤Þ¤·¤¿"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "'dictionary' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "'thesaurus' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "¼­½ñ¤ò¥¹¥­¥ã¥óÃæ: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (ÁÞÆþ) ¥¹¥¯¥í¡¼¥ë(^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (ÃÖ´¹) ¥¹¥¯¥í¡¼¥ë (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "¥¹¥­¥ã¥óÃæ: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "¥¿¥°¤ò¥¹¥­¥ã¥óÃæ."
-#: ../edit.c:4519
+msgid "match in file"
+msgstr "¥Õ¥¡¥¤¥ëÆâ¤Î¥Þ¥Ã¥Á"
+
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.
-#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- ¸¡º÷Ãæ..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "»Ï¤á¤ËÌá¤ë"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "¾¤Î¹Ô¤Îñ¸ì"
-#: ../edit.c:4624
msgid "The only match"
msgstr "Í£°ì¤Î³ºÅö"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "%d ÈÖÌܤγºÅö (Á´³ºÅö %d ¸ÄÃæ)"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "%d ÈÖÌܤγºÅö"
-#: ../eval.c:137
msgid "E18: Unexpected characters in :let"
msgstr "E18: ͽ´ü¤»¤Ìʸ»ú¤¬ :let ¤Ë¤¢¤ê¤Þ¤·¤¿"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: ¥ê¥¹¥È¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬Èϰϳ°¤Ç¤¹: %<PRId64>"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: ̤ÄêµÁ¤ÎÊÑ¿ô¤Ç¤¹: %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: ']' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Þ¤¿¤Ï¼­½ñ·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: ¼­½ñ·¿¤Ë¶õ¤Î¥­¡¼¤ò»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: ¥ê¥¹¥È·¿¤¬É¬ÍפǤ¹"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: ¼­½ñ·¿¤¬É¬ÍפǤ¹"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: ´Ø¿ô¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: ¼­½ñ·¿¤Ë¥­¡¼¤¬Â¸ºß¤·¤Þ¤»¤ó: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: ´Ø¿ô %s ¤ÏÄêµÁºÑ¤Ç¤¹, ºÆÄêµÁ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: ¼­½ñ·¿Æâ¤Ë¥¨¥ó¥È¥ê¤¬´û¤Ë¸ºß¤·¤Þ¤¹"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: ´Ø¿ô»²¾È·¿¤¬Í׵ᤵ¤ì¤Þ¤¹"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: [:] ¤ò¼­½ñ·¿¤ÈÁȤ߹ç¤ï¤»¤Æ¤Ï»È¤¨¤Þ¤»¤ó"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: °Û¤Ê¤Ã¤¿·¿¤ÎÊÑ¿ô¤Ç¤¹ %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: ̤ÃΤδؿô¤Ç¤¹: %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: ÉÔÀµ¤ÊÊÑ¿ô̾¤Ç¤¹: %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: ÉâÆ°¾®¿ôÅÀ¿ô¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: ¥¿¡¼¥²¥Ã¥È¤¬¥ê¥¹¥È·¿Æâ¤ÎÍ×ÁǤè¤ê¤â¾¯¤Ê¤¤¤Ç¤¹"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: ¥¿¡¼¥²¥Ã¥È¤¬¥ê¥¹¥È·¿Æâ¤ÎÍ×ÁǤè¤ê¤â¿¤¤¤Ç¤¹"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "¥ê¥¹¥È·¿¤ÎÃͤË2¤Ä°Ê¾å¤Î ; ¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: %s ¤ÎÃͤò°ìÍ÷ɽ¼¨¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: ¥ê¥¹¥È·¿¤È¼­½ñ·¿°Ê³°¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹»ØÄê¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] ¤ÏºÇ¸å¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: [:] ¤Ë¤Ï¥ê¥¹¥È·¿¤ÎÃͤ¬É¬ÍפǤ¹"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: ¥ê¥¹¥È·¿ÊÑ¿ô¤Ë¥¿¡¼¥²¥Ã¥È¤è¤ê¤â¿¤¤Í×ÁǤ¬¤¢¤ê¤Þ¤¹"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: ¥ê¥¹¥È·¿ÊÑ¿ô¤Ë½½Ê¬¤Ê¿ô¤ÎÍ×ÁǤ¬¤¢¤ê¤Þ¤»¤ó"
-#
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: :for ¤Î¸å¤Ë \"in\" ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: ¥«¥Ã¥³ '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: ¤½¤ÎÊÑ¿ô¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\""
-#: ../eval.c:3333
+#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: ÊÑ¿ô %s ¤Ï¥í¥Ã¥¯¤Þ¤¿¤Ï¥¢¥ó¥í¥Ã¥¯¤Ç¤­¤Þ¤»¤ó"
+
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: (¥¢¥ó)¥í¥Ã¥¯¤¹¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: '?' ¤Î¸å¤Ë ':' ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: ¥ê¥¹¥È·¿¤Ï¥ê¥¹¥È·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: ¥ê¥¹¥È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: ¼­½ñ·¿¤Ï¼­½ñ·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: ¼­½ñ·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: ´Ø¿ô»²¾È·¿¤Ï´Ø¿ô»²¾È·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: ´Ø¿ô»²¾È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: '%' ¤òÉâÆ°¾®¿ôÅÀ¿ô¤ÈÁȤ߹ç¤ï¤»¤Æ¤Ï»È¤¨¤Þ¤»¤ó"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ')' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: ´Ø¿ô»²¾È·¿¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:4839
+msgid "E909: Cannot index a special variable"
+msgstr "E909: ÆÃ¼ìÊÑ¿ô¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤­¤Þ¤»¤ó"
+
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: ¥ª¥×¥·¥ç¥ó̾¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: ̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: °úÍÑÉä (\") ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: °úÍÑÉä (') ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: ¥ê¥¹¥È·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: ¥ê¥¹¥È·¿¤ÎºÇ¸å¤Ë ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:5807
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr ""
"¥¬¡¼¥Ù¥Ã¥¸¥³¥ì¥¯¥·¥ç¥ó¤òÃæ»ß¤·¤Þ¤·¤¿! »²¾È¤òºîÀ®¤¹¤ë¤Î¤Ë¥á¥â¥ê¤¬ÉÔ­¤·¤Þ¤·¤¿"
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: ¼­½ñ·¿¤Ë¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: ¼­½ñ·¿¤Ë½ÅÊ£¥­¡¼¤¬¤¢¤ê¤Þ¤¹: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: ¼­½ñ·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: ¼­½ñ·¿¤ÎºÇ¸å¤Ë '}' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:6555
msgid "E724: variable nested too deep for displaying"
msgstr "E724: ɽ¼¨¤¹¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: ´Ø¿ô¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹: %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: ´Ø¿ô¤Î̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: ̤ÃΤδؿô¤Ç¤¹: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: ´Ø¿ô¤Î°ú¿ô¤¬Â­¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç<SID>¤¬»È¤ï¤ì¤Þ¤·¤¿: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: ¼­½ñÍÑ´Ø¿ô¤¬¸Æ¤Ð¤ì¤Þ¤·¤¿¤¬¼­½ñ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: ¿ôÃͤ«ÉâÆ°¾®¿ôÅÀ¿ô¤¬É¬ÍפǤ¹"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "add() ¤Î°ú¿ô"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: °ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() ¤ÏÁÞÆþ¥â¡¼¥É¤Ç¤·¤«ÍøÍѤǤ­¤Þ¤»¤ó"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: ¥­¡¼¤Ï´û¤Ë¸ºß¤·¤Þ¤¹: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "extend() ¤Î°ú¿ô"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "map() ¤Î°ú¿ô"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "filter() ¤Î°ú¿ô"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld ¹Ô: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: ̤ÃΤδؿô¤Ç¤¹: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "inputrestore() ¤¬ inputsave() ¤è¤ê¤â¿¤¯¸Æ¤Ð¤ì¤Þ¤·¤¿"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "insert() ¤Î°ú¿ô"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: ÈϰϻØÄê¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: len() ¤Ë¤Ï̵¸ú¤Ê·¿¤Ç¤¹"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: ¥¹¥È¥é¥¤¥É(Á°¿ÊÎÌ)¤¬ 0 ¤Ç¤¹"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: ³«»Ï°ÌÃÖ¤¬½ªÎ»°ÌÃÖ¤ò±Û¤¨¤Þ¤·¤¿"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<¶õ>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "remove() ¤Î°ú¿ô"
-
-# Added at 10-Mar-2004.
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: ¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤¬Â¿²á¤®¤Þ¤¹ (½Û´Ä¤·¤Æ¤¤¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "reverse() ¤Î°ú¿ô"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "sort() ¤Î°ú¿ô"
-
-#: ../eval.c:13721
-msgid "uniq() argument"
-msgstr "uniq() ¤Î°ú¿ô"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: ¥½¡¼¥È¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#: ../eval.c:13806
-msgid "E882: Uniq compare function failed"
-msgstr "E882: Uniq ¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(̵¸ú)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: °ì»þ¥Õ¥¡¥¤¥ë½ñ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
-
-#: ../eval.c:16159
msgid "E805: Using a Float as a Number"
msgstr "E805: ÉâÆ°¾®¿ôÅÀ¿ô¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16162
msgid "E703: Using a Funcref as a Number"
-msgstr "E703: ´Ø¿ô»²¾È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£"
+msgstr "E703: ´Ø¿ô»²¾È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16170
msgid "E745: Using a List as a Number"
msgstr "E745: ¥ê¥¹¥È·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16173
msgid "E728: Using a Dictionary as a Number"
msgstr "E728: ¼­½ñ·¿¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+msgid "E910: Using a Job as a Number"
+msgstr "E910: ¥¸¥ç¥Ö¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: ¥Á¥ã¥Í¥ë¤ò¿ôÃͤȤ·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
msgid "E891: Using a Funcref as a Float"
-msgstr "E891: ´Ø¿ô»²¾È·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹¡£"
+msgstr "E891: ´Ø¿ô»²¾È·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
msgid "E892: Using a String as a Float"
msgstr "E892: ʸ»úÎó¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
@@ -878,265 +607,306 @@ msgstr "E893: ¥ê¥¹¥È·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
msgid "E894: Using a Dictionary as a Float"
msgstr "E894: ¼­½ñ·¿¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16259
+msgid "E907: Using a special value as a Float"
+msgstr "E907: ÆÃ¼ìÃͤòÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: ¥¸¥ç¥Ö¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: ¥Á¥ã¥Í¥ë¤òÉâÆ°¾®¿ôÅÀ¿ô¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
+
msgid "E729: using Funcref as a String"
msgstr "E729: ´Ø¿ô»²¾È·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16262
msgid "E730: using List as a String"
msgstr "E730: ¥ê¥¹¥È·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16265
msgid "E731: using Dictionary as a String"
msgstr "E731: ¼­½ñ·¿¤òʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: ÊÑ¿ô¤Î·¿¤¬°ìÃפ·¤Þ¤»¤ó: %s"
+msgid "E908: using an invalid value as a String"
+msgstr "E908: ̵¸ú¤ÊÃͤòʸ»úÎó¤È¤·¤Æ°·¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../eval.c:16705
#, c-format
msgid "E795: Cannot delete variable %s"
msgstr "E795: ÊÑ¿ô %s ¤òºï½ü¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
msgstr "E704: ´Ø¿ô»²¾È·¿ÊÑ¿ô̾¤ÏÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: ÊÑ¿ô̾¤¬´û¸¤Î´Ø¿ô̾¤È¾×ÆÍ¤·¤Þ¤¹: %s"
-#: ../eval.c:16763
#, c-format
msgid "E741: Value is locked: %s"
msgstr "E741: Ãͤ¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
msgid "Unknown"
msgstr "ÉÔÌÀ"
-#: ../eval.c:16768
#, c-format
msgid "E742: Cannot change value of %s"
msgstr "E742: %s ¤ÎÃͤòÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: ¥³¥Ô¡¼¤ò¼è¤ë¤Ë¤ÏÊÑ¿ô¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: ̤ÄêµÁ¤Î´Ø¿ô¤Ç¤¹: %s"
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# ¥°¥í¡¼¥Ð¥ëÊÑ¿ô:\n"
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tºÇ¸å¤Ë¥»¥Ã¥È¤·¤¿¥¹¥¯¥ê¥×¥È: "
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: ¤³¤³¤Ç¤Ï g: ¤Ï»È¤¨¤Þ¤»¤ó"
+msgid "E691: Can only compare List with List"
+msgstr "E691: ¥ê¥¹¥È·¿¤Ï¥ê¥¹¥È·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
+msgid "E692: Invalid operation for List"
+msgstr "E692: ¥ê¥¹¥È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: °ú¿ô̾¤¬½ÅÊ£¤·¤Æ¤¤¤Þ¤¹: %s"
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: ¼­½ñ·¿¤Ï¼­½ñ·¿¤È¤·¤«Èæ³Ó¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunction ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: ¼­½ñ·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: ´Ø¿ô̾¤¬ÊÑ¿ô̾¤È¾×ÆÍ¤·¤Þ¤¹: %s"
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: ´Ø¿ô»²¾È·¿¤Ë¤Ï̵¸ú¤ÊÁàºî¤Ç¤¹"
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: ´Ø¿ô %s ¤òºÆÄêµÁ¤Ç¤­¤Þ¤»¤ó: »ÈÍÑÃæ¤Ç¤¹"
+msgid "map() argument"
+msgstr "map() ¤Î°ú¿ô"
+
+msgid "filter() argument"
+msgstr "filter() ¤Î°ú¿ô"
-#: ../eval.c:17604
#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: ´Ø¿ô̾¤¬¥¹¥¯¥ê¥×¥È¤Î¥Õ¥¡¥¤¥ë̾¤È°ìÃפ·¤Þ¤»¤ó: %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: ´Ø¿ô̾¤¬Í׵ᤵ¤ì¤Þ¤¹"
+msgid "E928: String required"
+msgstr "E928: ʸ»úÎó¤¬É¬ÍפǤ¹"
-#: ../eval.c:17824
-#, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: ´Ø¿ô̾¤ÏÂçʸ»ú¤« \"s:\" ¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
+msgid "E808: Number or Float required"
+msgstr "E808: ¿ôÃͤ«ÉâÆ°¾®¿ôÅÀ¿ô¤¬É¬ÍפǤ¹"
-#: ../eval.c:17833
-#, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E884: ´Ø¿ô̾¤Ë¤Ï¥³¥í¥ó¤Ï´Þ¤á¤é¤ì¤Þ¤»¤ó: %s"
+msgid "add() argument"
+msgstr "add() ¤Î°ú¿ô"
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: ´Ø¿ô %s ¤òºï½ü¤Ç¤­¤Þ¤»¤ó: »ÈÍÑÃæ¤Ç¤¹"
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ¤ÏÁÞÆþ¥â¡¼¥É¤Ç¤·¤«ÍøÍѤǤ­¤Þ¤»¤ó"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: ´Ø¿ô¸Æ½Ð¤ÎÆþ¤ì»Ò¿ô¤¬ 'maxfuncdepth' ¤òͤ¨¤Þ¤·¤¿"
+msgid "&Ok"
+msgstr "&Ok"
-#: ../eval.c:18568
#, c-format
-msgid "calling %s"
-msgstr "%s ¤ò¼Â¹ÔÃæ¤Ç¤¹"
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld ¹Ô: "
-#: ../eval.c:18651
#, c-format
-msgid "%s aborted"
-msgstr "%s ¤¬ÃæÃǤµ¤ì¤Þ¤·¤¿"
+msgid "E700: Unknown function: %s"
+msgstr "E700: ̤ÃΤδؿô¤Ç¤¹: %s"
+
+msgid "E922: expected a dict"
+msgstr "E922: ¼­½ñ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: function() ¤ÎÂè 2 °ú¿ô¤Ï¥ê¥¹¥È·¿¤Þ¤¿¤Ï¼­½ñ·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"·èÄê(&O)\n"
+"¥­¥ã¥ó¥»¥ë(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() ¤¬ inputsave() ¤è¤ê¤â¿¤¯¸Æ¤Ð¤ì¤Þ¤·¤¿"
+
+msgid "insert() argument"
+msgstr "insert() ¤Î°ú¿ô"
+
+msgid "E786: Range not allowed"
+msgstr "E786: ÈϰϻØÄê¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "E916: not a valid job"
+msgstr "E916: Í­¸ú¤Ê¥¸¥ç¥Ö¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len() ¤Ë¤Ï̵¸ú¤Ê·¿¤Ç¤¹"
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ¤¬ #%<PRId64> ¤òÊÖ¤·¤Þ¤·¤¿"
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID ¤Ï \":match\" ¤Î¤¿¤á¤ËͽÌó¤µ¤ì¤Æ¤¤¤Þ¤¹: %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ¥¹¥È¥é¥¤¥É(Á°¿ÊÎÌ)¤¬ 0 ¤Ç¤¹"
+
+msgid "E727: Start past end"
+msgstr "E727: ³«»Ï°ÌÃÖ¤¬½ªÎ»°ÌÃÖ¤ò±Û¤¨¤Þ¤·¤¿"
+
+msgid "<empty>"
+msgstr "<¶õ>"
+
+msgid "E240: No connection to the X server"
+msgstr "E240: X ¥µ¡¼¥Ð¡¼¤Ø¤ÎÀܳ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿"
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s ¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: ¥µ¡¼¥Ð¡¼¤Î±þÅú¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E941: already started a server"
+msgstr "E941: ¥µ¡¼¥Ð¡¼¤Ï¤¹¤Ç¤Ë³«»Ï¤·¤Æ¤¤¤Þ¤¹"
+
+msgid "E942: +clientserver feature not available"
+msgstr "E942: +clientserver µ¡Ç½¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
+
+msgid "remove() argument"
+msgstr "remove() ¤Î°ú¿ô"
+
+# Added at 10-Mar-2004.
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: ¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤¬Â¿²á¤®¤Þ¤¹ (½Û´Ä¤·¤Æ¤¤¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹)"
+
+msgid "reverse() argument"
+msgstr "reverse() ¤Î°ú¿ô"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: ¥¯¥é¥¤¥¢¥ó¥È¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "%s ¤Î¼Â¹Ô¤ò·ÑÂ³Ãæ¤Ç¤¹"
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: ̵¸ú¤ÊÁàºî¤Ç¤¹: %s"
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: ´Ø¿ô³°¤Ë :return ¤¬¤¢¤ê¤Þ¤·¤¿"
+msgid "sort() argument"
+msgstr "sort() ¤Î°ú¿ô"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# ¥°¥í¡¼¥Ð¥ëÊÑ¿ô:\n"
+msgid "uniq() argument"
+msgstr "uniq() ¤Î°ú¿ô"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tLast set from "
+msgid "E702: Sort compare function failed"
+msgstr "E702: ¥½¡¼¥È¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "¸Å¤¤¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "E882: Uniq compare function failed"
+msgstr "E882: Uniq ¤ÎÈæ³Ó´Ø¿ô¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "(Invalid)"
+msgstr "(̵¸ú)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: ̵¸ú¤Ê¥µ¥Ö¥Þ¥Ã¥ÁÈÖ¹æ: %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: °ì»þ¥Õ¥¡¥¤¥ë½ñ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: ̵¸ú¤Ê¥³¡¼¥ë¥Ð¥Ã¥¯°ú¿ô¤Ç¤¹"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"
+msgstr "<%s>%s%s %d, 16¿Ê¿ô %02x, 8¿Ê¿ô %03o, ¥À¥¤¥°¥é¥Õ %s"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, 16¿Ê¿ô %02x, 8¿Ê¿ô %03o"
-#: ../ex_cmds.c:145
+#, c-format
+msgid "> %d, Hex %04x, Oct %o, Digr %s"
+msgstr "> %d, 16¿Ê¿ô %04x, 8¿Ê¿ô %o, ¥À¥¤¥°¥é¥Õ %s"
+
+#, c-format
+msgid "> %d, Hex %08x, Oct %o, Digr %s"
+msgstr "> %d, 16¿Ê¿ô %08x, 8¿Ê¿ô %o, ¥À¥¤¥°¥é¥Õ %s"
+
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, 16¿Ê¿ô %04x, 8¿Ê¿ô %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, 16¿Ê¿ô %08x, 8¿Ê¿ô %o"
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: ¹Ô¤ò¤½¤ì¼«¿È¤Ë¤Ï°Üư¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_cmds.c:747
msgid "1 line moved"
msgstr "1 ¹Ô¤¬°Üư¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> ¹Ô¤¬°Üư¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines moved"
+msgstr "%ld ¹Ô¤¬°Üư¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> ¹Ô¤¬¥Õ¥£¥ë¥¿½èÍý¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines filtered"
+msgstr "%ld ¹Ô¤¬¥Õ¥£¥ë¥¿½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr "E135: *¥Õ¥£¥ë¥¿* autocommand¤Ï¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤òÊѹ¹¤·¤Æ¤Ï¤¤¤±¤Þ¤»¤ó"
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó]\n"
-#: ../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: ¥¨¥é¡¼¤¬Â¿²á¤®¤ë¤Î¤Ç, °Ê¹ß¤Ï¥¹¥­¥Ã¥×¤·¤Þ¤¹"
+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
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 "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: °ì»þviminfo¥Õ¥¡¥¤¥ë¤¬Â¿²á¤®¤Þ¤¹! Îã: %s"
+
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: viminfo¥Õ¥¡¥¤¥ë %s ¤òÊݸ¤Ç¤­¤Þ¤»¤ó!"
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "viminfo¥Õ¥¡¥¤¥ë \"%s\" ¤ò½ñ¹þ¤ßÃæ"
-#. Write the info:
-#: ../ex_cmds.c:1720
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: viminfo¥Õ¥¡¥¤¥ë¤ò %s ¤ØÌ¾Á°Êѹ¹¤Ç¤­¤Þ¤»¤ó!"
+
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# ¤³¤Î viminfo ¥Õ¥¡¥¤¥ë¤Ï Vim %s ¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤Þ¤·¤¿.\n"
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1144,47 +914,47 @@ msgstr ""
"# Êѹ¹¤¹¤ëºÝ¤Ë¤Ï½½Ê¬Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤!\n"
"\n"
-#: ../ex_cmds.c:1723
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
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# '|' ¤Ç»Ï¤Þ¤ë¹Ô¤Î¡¢Ê¸»úÄ̤ê¤Î¥³¥Ô¡¼:\n"
+
+msgid "Save As"
+msgstr "ÊÌ̾¤ÇÊݸ"
+
msgid "Write partial file?"
msgstr "¥Õ¥¡¥¤¥ë¤òÉôʬŪ¤ËÊݸ¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: ¥Ð¥Ã¥Õ¥¡¤òÉôʬŪ¤ËÊݸ¤¹¤ë¤Ë¤Ï ! ¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "´û¸¤Î¥Õ¥¡¥¤¥ë \"%s\" ¤ò¾å½ñ¤­¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \"%s\" ¤¬Â¸ºß¤·¤Þ¤¹. ¾å½ñ¤­¤ò¶¯À©¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Þ¤¹: %s (:silent! ¤òÄɲäǾå½ñ)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤Ë¤Ï̾Á°¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: ¥Ð¥Ã¥Õ¥¡ %ld ¤Ë¤Ï̾Á°¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: ¥Õ¥¡¥¤¥ë¤ÏÊݸ¤µ¤ì¤Þ¤»¤ó¤Ç¤·¤¿: 'write' ¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê̵¸ú¤Ç¤¹"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1193,7 +963,6 @@ msgstr ""
"\"%s\" ¤Ë¤Ï 'readonly' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹.\n"
"¾å½ñ¤­¶¯À©¤ò¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1204,83 +973,68 @@ msgstr ""
"¤½¤ì¤Ç¤â¶²¤é¤¯½ñ¤­¹þ¤à¤³¤È¤Ï²Äǽ¤Ç¤¹.\n"
"·Ñ³¤·¤Þ¤¹¤«?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: \"%s\" ¤ÏÆÉ¹þÀìÍѤǤ¹ (¶¯À©½ñ¹þ¤Ë¤Ï ! ¤òÄɲÃ)"
-#: ../ex_cmds.c:3120
+msgid "Edit File"
+msgstr "¥Õ¥¡¥¤¥ë¤òÊÔ½¸"
+
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: autocommand¤¬Í½´ü¤»¤º¿·¤·¤¤¥Ð¥Ã¥Õ¥¡ %s ¤òºï½ü¤·¤Þ¤·¤¿"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: ¿ô¤Ç¤Ï¤Ê¤¤°ú¿ô¤¬ :z ¤ËÅϤµ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: rvim¤Ç¤Ï¥·¥§¥ë¥³¥Þ¥ó¥É¤ò»È¤¨¤Þ¤»¤ó"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: Àµµ¬É½¸½¤Ïʸ»ú¤Ç¶èÀڤ뤳¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_cmds.c:3964
#, 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
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> ²Õ½ê³ºÅö¤·¤Þ¤·¤¿"
+msgid "%ld matches"
+msgstr "%ld ²Õ½ê³ºÅö¤·¤Þ¤·¤¿"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> ²Õ½êÃÖ´¹¤·¤Þ¤·¤¿"
+msgid "%ld substitutions"
+msgstr "%ld ²Õ½êÃÖ´¹¤·¤Þ¤·¤¿"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " (·× 1 ¹ÔÆâ)"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " (·× %<PRId64> ¹ÔÆâ)"
+msgid " on %ld lines"
+msgstr " (·× %ld ¹ÔÆâ)"
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global ¤òºÆµ¢Åª¤Ë¤Ï»È¤¨¤Þ¤»¤ó"
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: :global ¤òÈϰÏÉÕ¤­¤ÇºÆµ¢Åª¤Ë¤Ï»È¤¨¤Þ¤»¤ó"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: global¥³¥Þ¥ó¥É¤ËÀµµ¬É½¸½¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "¥Ñ¥¿¡¼¥ó¤¬Á´¤Æ¤Î¹Ô¤Ç¸«¤Ä¤«¤ê¤Þ¤·¤¿: %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿: %s"
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1290,110 +1044,110 @@ msgstr ""
"# ºÇ¸å¤ËÃÖ´¹¤µ¤ì¤¿Ê¸»úÎó:\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"
+msgid "E151: No match: %s"
+msgstr "E151: ¥Þ¥Ã¥Á¤Ï¤¢¤ê¤Þ¤»¤ó: %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 ¤ò³«¤±¤Þ¤»¤ó"
# Added at 29-Apr-2004.
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: 1¤Ä¤Î¸À¸ì¤Î¥Ø¥ë¥×¥Õ¥¡¥¤¥ë¤ËÊ£¿ô¤Î¥¨¥ó¥³¡¼¥É¤¬º®ºß¤·¤Æ¤¤¤Þ¤¹: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: ¥¿¥° \"%s\" ¤¬¥Õ¥¡¥¤¥ë %s/%s ¤Ë½ÅÊ£¤·¤Æ¤¤¤Þ¤¹"
-#: ../ex_cmds.c:5687
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: ¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
+
#, 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: sign¤ÎÄêµÁ¤¬Â¿¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿"
-#: ../ex_cmds.c:5813
#, 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
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: ̾Á°¤Î̵¤¤¥Ð¥Ã¥Õ¥¡¤Ø¤Ï¥¸¥ã¥ó¥×¤Ç¤­¤Þ¤»¤ó"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: ̵¸ú¤Êsign¼±Ê̻ҤǤ¹: %<PRId64>"
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ̵¸ú¤Êsign¼±Ê̻ҤǤ¹: %ld"
#, c-format
msgid "E885: Not possible to change sign %s"
msgstr "E885: Êѹ¹¤Ç¤­¤Ê¤¤ sign ¤Ç¤¹: %s"
-#: ../ex_cmds.c:6066
+# Added at 27-Jan-2004.
+msgid " (NOT FOUND)"
+msgstr " (¸«¤Ä¤«¤ê¤Þ¤»¤ó)"
+
msgid " (not supported)"
msgstr " (È󥵥ݡ¼¥È)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[ºï½üºÑ]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "¸Å¤¤¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
+
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"
+msgid "Oldval = \"%s\""
+msgstr "¸Å¤¤ÃÍ = \"%s\""
+
+#, c-format
+msgid "Newval = \"%s\""
+msgstr "¿·¤·¤¤ÃÍ = \"%s\""
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "¹Ô %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "¥³¥Þ¥ó¥É: %s"
@@ -1405,232 +1159,199 @@ msgstr "¥Õ¥ì¡¼¥à¤¬ 0 ¤Ç¤¹"
msgid "frame at highest level: %d"
msgstr "ºÇ¹â¥ì¥Ù¥ë¤Î¥Õ¥ì¡¼¥à: %d"
-#: ../ex_cmds2.c:322
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È \"%s%s\" ¹Ô %<PRId64>"
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È \"%s%s\" ¹Ô %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: ¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s ¹Ô %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s ¹Ô %ld"
+
+#, c-format
+msgid "%3d expr %s"
+msgstr "%3d expr %s"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: ½é¤á¤Ë \":profile start {fname}\" ¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Êѹ¹¤ò \"%s\" ¤ËÊݸ¤·¤Þ¤¹¤«?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "̵Âê"
+#, c-format
+msgid "E947: Job still running in buffer \"%s\""
+msgstr "E947: ¥¸¥ç¥Ö¤Ï¥Ð¥Ã¥Õ¥¡ \"%s\" ¤Ç¤Þ¤À¼Â¹ÔÃæ¤Ç¤¹"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: ¥Ð¥Ã¥Õ¥¡ \"%s\" ¤ÎÊѹ¹¤ÏÊݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "·Ù¹ð: ͽ´ü¤»¤ºÂ¾¥Ð¥Ã¥Õ¥¡¤Ø°Üư¤·¤Þ¤·¤¿ (autocommands ¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: ÊÔ½¸¤¹¤ë¥Õ¥¡¥¤¥ë¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
-#: ../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
#, 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\""
+msgid "not found in '%s': \"%s\""
+msgstr "'%s' ¤ÎÃæ¤Ë¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\""
+
+#, c-format
+msgid "W20: Required python version 2.x not supported, ignoring file: %s"
+msgstr "W20: Í׵ᤵ¤ì¤¿python 2.x¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó¡¢¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹: %s"
+
+#, c-format
+msgid "W21: Required python version 3.x not supported, ignoring file: %s"
+msgstr "W21: Í׵ᤵ¤ì¤¿python 3.x¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó¡¢¥Õ¥¡¥¤¥ë¤ò̵»ë¤·¤Þ¤¹: %s"
+
+msgid "Source Vim script"
+msgstr "Vim¥¹¥¯¥ê¥×¥È¤Î¼è¹þ¤ß"
-#: ../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\" ¤ò¼è¹þ¤á¤Þ¤»¤ó"
+msgid "line %ld: could not source \"%s\""
+msgstr "¹Ô %ld: \"%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 ¤ò¼è¹þÃæ"
+msgid "line %ld: sourcing \"%s\""
+msgstr "¹Ô %ld: %s ¤ò¼è¹þÃæ"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "%s ¤Î¼è¹þ¤ò´°Î»"
-#: ../ex_cmds2.c:2765
+#, c-format
+msgid "continuing in %s"
+msgstr "%s ¤Î¼Â¹Ô¤ò·ÑÂ³Ãæ¤Ç¤¹"
+
msgid "modeline"
msgstr "¥â¡¼¥É¹Ô"
-#: ../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_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding ¤¬¼è¹þ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç»ÈÍѤµ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish ¤¬¼è¹þ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç»ÈÍѤµ¤ì¤Þ¤·¤¿"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "¸½ºß¤Î %s¸À¸ì: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: ¸À¸ì¤ò \"%s\" ¤ËÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr ""
"Ex¥â¡¼¥É¤ËÆþ¤ê¤Þ¤¹. ¥Î¡¼¥Þ¥ë¥â¡¼¥É¤ËÌá¤ë¤Ë¤Ï\"visual\"¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: ¥Õ¥¡¥¤¥ë¤Î½ªÎ»°ÌÃÖ"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: ¥³¥Þ¥ó¥É¤¬ºÆµ¢Åª²á¤®¤Þ¤¹"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: Îã³°¤¬Ê᪤µ¤ì¤Þ¤»¤ó¤Ç¤·¤¿: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "¼è¹þ¥Õ¥¡¥¤¥ë¤ÎºÇ¸å¤Ç¤¹"
-#: ../ex_docmd.c:1086
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:1729
msgid "E493: Backwards range given"
msgstr "E493: µÕ¤µ¤Þ¤ÎÈϰϤ¬»ØÄꤵ¤ì¤Þ¤·¤¿"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
-msgstr "µÕ¤µ¤Þ¤ÎÈϰϤ¬»ØÄꤵ¤ì¤Þ¤·¤¿, ÆþÂØ¤¨¤Þ¤¹¤«?"
+msgstr "µÕ¤µ¤Þ¤ÎÈϰϤ¬»ØÄꤵ¤ì¤Þ¤·¤¿¡¢ÆþÂØ¤¨¤Þ¤¹¤«?"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: w ¤â¤·¤¯¤Ï w>> ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¤³¤Î¥³¥Þ¥ó¥É¤ÏÍøÍѤǤ­¤Þ¤»¤ó, ¤´¤á¤ó¤Ê¤µ¤¤"
+msgid "E943: Command table needs to be updated, run 'make cmdidxs'"
+msgstr ""
+"E943: ¥³¥Þ¥ó¥É¥Æ¡¼¥Ö¥ë¤ò¹¹¿·¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¢'make cmdidxs' ¤ò¼Â¹Ô¤·¤Æ¤¯¤À"
+"¤µ¤¤"
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: ¥Õ¥¡¥¤¥ë̾¤Ï 1 ¤Ä¤Ë¤·¤Æ¤¯¤À¤µ¤¤"
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¤³¤Î¥³¥Þ¥ó¥É¤ÏÍøÍѤǤ­¤Þ¤»¤ó¡¢¤´¤á¤ó¤Ê¤µ¤¤"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
-msgstr "ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬ 1 ¸Ä¤¢¤ê¤Þ¤¹¤¬, ½ªÎ»¤·¤Þ¤¹¤«?"
+msgstr "ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬ 1 ¸Ä¤¢¤ê¤Þ¤¹¤¬¡¢½ªÎ»¤·¤Þ¤¹¤«?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
-msgstr "ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬¤¢¤È %d ¸Ä¤¢¤ê¤Þ¤¹¤¬, ½ªÎ»¤·¤Þ¤¹¤«?"
+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> ¸Ä¤¢¤ê¤Þ¤¹"
+msgid "E173: %ld more files to edit"
+msgstr "E173: ÊÔ½¸¤¹¤Ù¤­¥Õ¥¡¥¤¥ë¤¬¤¢¤È %ld ¸Ä¤¢¤ê¤Þ¤¹"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: ¥³¥Þ¥ó¥É¤¬´û¤Ë¤¢¤ê¤Þ¤¹: ºÆÄêµÁ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
" Name Args Address Complete Definition"
@@ -1638,51 +1359,40 @@ 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: ¥«¥¦¥ó¥È¤ò2½Å»ØÄꤹ¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../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 ¤Ë¤Ï°ú¿ô¤¬É¬ÍפǤ¹"
msgid "E179: argument required for -addr"
msgstr "E179: -addr ¤Ë¤Ï°ú¿ô¤¬É¬ÍפǤ¹"
-#: ../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: ¥æ¡¼¥¶ÄêµÁ¥³¥Þ¥ó¥É¤Ï±ÑÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+msgstr "E183: ¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤Ï±ÑÂçʸ»ú¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:4696
msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E841: ͽÌó̾¤Ê¤Î¤Ç, ¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤ËÍøÍѤǤ­¤Þ¤»¤ó"
+msgstr "E841: ͽÌó̾¤Ê¤Î¤Ç¡¢¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤ËÍøÍѤǤ­¤Þ¤»¤ó"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: ¤½¤Î¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
@@ -1691,293 +1401,260 @@ msgstr "E184: ¤½¤Î¥æ¡¼¥¶¡¼ÄêµÁ¥³¥Þ¥ó¥É¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
msgid "E180: Invalid address type value: %s"
msgstr "E180: ̵¸ú¤Ê¥¢¥É¥ì¥¹¥¿¥¤¥×ÃͤǤ¹: %s"
-#: ../ex_docmd.c:5219
#, 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: Êä´°°ú¿ô¤Ï¥«¥¹¥¿¥àÊä´°¤Ç¤·¤«»ÈÍѤǤ­¤Þ¤»¤ó"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: ¥«¥¹¥¿¥àÊä´°¤Ë¤Ï°ú¿ô¤È¤·¤Æ´Ø¿ô¤¬É¬ÍפǤ¹"
-#: ../ex_docmd.c:5257
+msgid "unknown"
+msgstr "ÉÔÌÀ"
+
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: ¥«¥é¡¼¥¹¥­¡¼¥à '%s' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Vim »È¤¤¤µ¤ó¡¢¤ä¤¢!"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: ºÇ¸å¤Î¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "´û¤Ë¥¿¥Ö¥Ú¡¼¥¸¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:6004
+msgid "Edit File in new tab page"
+msgstr "¿·¤·¤¤¥¿¥Ö¥Ú¡¼¥¸¤Ç¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤¹"
+
+msgid "Edit File in new window"
+msgstr "¿·¤·¤¤¥¦¥£¥ó¥É¥¦¤Ç¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤¹"
+
#, c-format
msgid "Tab page %d"
msgstr "¥¿¥Ö¥Ú¡¼¥¸ %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "Äɲåե¡¥¤¥ë"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
-"E747: ¥Ð¥Ã¥Õ¥¡¤¬½¤Àµ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç, ¥Ç¥£¥ì¥¯¥È¥ê¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó (! ¤òÄɲäÇ"
+"E747: ¥Ð¥Ã¥Õ¥¡¤¬½¤Àµ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢¥Ç¥£¥ì¥¯¥È¥ê¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó (! ¤òÄɲäÇ"
"¾å½ñ)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: Á°¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: ̤ÃÎ"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: :winsize ¤Ë¤Ï2¤Ä¤Î¿ôÃͤΰú¿ô¤¬É¬ÍפǤ¹"
-#: ../ex_docmd.c:6655
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "¥¦¥£¥ó¥É¥¦°ÌÃÖ: X %d, Y %d"
+
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 ¤Ë¤Ï2¤Ä¤Î¿ôÃͤΰú¿ô¤¬É¬ÍפǤ¹"
-#: ../ex_docmd.c:7241
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: execute() ¤ÎÃæ¤Ç¤Ï :redir ¤Ï»È¤¨¤Þ¤»¤ó"
+
+msgid "Save Redirection"
+msgstr "¥ê¥À¥¤¥ì¥¯¥È¤òÊݸ¤·¤Þ¤¹"
+
+msgid "Save View"
+msgstr "¥Ó¥å¡¼¤òÊݸ¤·¤Þ¤¹"
+
+msgid "Save Session"
+msgstr "¥»¥Ã¥·¥ç¥ó¾ðÊó¤òÊݸ¤·¤Þ¤¹"
+
+msgid "Save Setup"
+msgstr "ÀßÄê¤òÊݸ¤·¤Þ¤¹"
+
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: ¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤Ç¤­¤Þ¤»¤ó: %s"
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" ¤¬Â¸ºß¤·¤Þ¤¹ (¾å½ñ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: \"%s\" ¤ò½ñ¹þ¤ßÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó"
-#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: °ú¿ô¤Ï1ʸ»ú¤Î±Ñ»ú¤«°úÍÑÉä (' ¤« `) ¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: :normal ¤ÎºÆµ¢ÍøÍѤ¬¿¼¤¯¤Ê¤ê²á¤®¤Þ¤·¤¿"
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< ¤Ï +eval µ¡Ç½¤¬Ìµ¤¤¤ÈÍøÍѤǤ­¤Þ¤»¤ó"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: '#'¤òÃÖ¤­´¹¤¨¤ëÉû¥Õ¥¡¥¤¥ë¤Î̾Á°¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: \"<afile>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¤Î¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: \"<abuf>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¥Ð¥Ã¥Õ¥¡Èֹ椬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr "E497: \"<amatch>\"¤òÃÖ¤­´¹¤¨¤ëautocommand¤Î³ºÅö̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: \"<sfile>\"¤òÃÖ¤­´¹¤¨¤ë :source Âоݥե¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: \"<slnum>\"¤òÃÖ¤­´¹¤¨¤ë¹ÔÈֹ椬¤¢¤ê¤Þ¤»¤ó"
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr ""
"E499: '%' ¤ä '#' ¤¬ÌµÌ¾¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç \":p:h\" ¤òȼ¤ï¤Ê¤¤»È¤¤Êý¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../ex_docmd.c:7905
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_eval.c:464
+msgid "Untitled"
+msgstr "̵Âê"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¹ç»ú¤Ï¤¢¤ê¤Þ¤»¤ó"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: 'Vim' ¤Ç»Ï¤Þ¤ëÎã³°¤Ï :throw ¤Ç¤­¤Þ¤»¤ó"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "Îã³°¤¬È¯À¸¤·¤Þ¤·¤¿: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "Îã³°¤¬¼ý«¤·¤Þ¤·¤¿: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "Îã³°¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, ¹Ô %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, ¹Ô %ld"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Îã³°¤¬Ê᪤µ¤ì¤Þ¤·¤¿: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s ¤Ë¤è¤ê̤·èÄê¾õÂÖ¤¬À¸¤¸¤Þ¤·¤¿"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s ¤¬ºÆ³«¤·¤Þ¤·¤¿"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s ¤¬ÇË´þ¤µ¤ì¤Þ¤·¤¿"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "Îã³°"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "¥¨¥é¡¼¤È³ä¹þ¤ß"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "¥¨¥é¡¼"
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "³ä¹þ¤ß"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: :if ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :if ¤Î¤Ê¤¤ :endif ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :if ¤Î¤Ê¤¤ :else ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :if ¤Î¤Ê¤¤ :elseif ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: Ê£¿ô¤Î :else ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :else ¤Î¸å¤Ë :elseif ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: :while ¤ä :for ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :while ¤ä :for ¤Î¤Ê¤¤ :continue ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :while ¤ä :for ¤Î¤Ê¤¤ :break ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: :endfor ¤ò :while ¤ÈÁȤ߹ç¤ï¤»¤Æ¤¤¤Þ¤¹"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: :endwhile ¤ò :for ¤ÈÁȤ߹ç¤ï¤»¤Æ¤¤¤Þ¤¹"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: :try ¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :try ¤Î¤Ê¤¤ :catch ¤¬¤¢¤ê¤Þ¤¹"
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :finally ¤Î¸å¤Ë :catch ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :try ¤Î¤Ê¤¤ :finally ¤¬¤¢¤ê¤Þ¤¹"
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: Ê£¿ô¤Î :finally ¤¬¤¢¤ê¤Þ¤¹"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :try ¤Î¤Ê¤¤ :endtry ¤Ç¤¹"
-#: ../ex_eval.c:2026
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
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: ¸½ºß¤Ï¥Ð¥Ã¥Õ¥¡¾ðÊó¤òÊѹ¹¤¹¤ë¤³¤È¤Ïµö¤µ¤ì¤Þ¤»¤ó"
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "¥¿¥°Ì¾"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " ¥Õ¥¡¥¤¥ë¼ïÎà\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "¥ª¥×¥·¥ç¥ó 'history' ¤¬¥¼¥í¤Ç¤¹"
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -1986,303 +1663,220 @@ msgstr ""
"\n"
"# %s ¹àÌܤÎÍúÎò (¿·¤·¤¤¤â¤Î¤«¤é¸Å¤¤¤â¤Î¤Ø):\n"
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "¥³¥Þ¥ó¥É¥é¥¤¥ó"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "¸¡º÷ʸ»úÎó"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "¼°"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "ÆþÎϹÔ"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "¥Ç¥Ð¥Ã¥°¹Ô"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar ¤¬¥³¥Þ¥ó¥ÉŤòͤ¨¤Þ¤·¤¿"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: ¥¢¥¯¥Æ¥£¥Ö¤Ê¥¦¥£¥ó¥É¥¦¤«¥Ð¥Ã¥Õ¥¡¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: ¥Ñ¥¹¤¬Ä¹²á¤®¤ÆÊä´°¤Ç¤­¤Þ¤»¤ó"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: ̵¸ú¤Ê¥Ñ¥¹¤Ç¤¹: '**[¿ôÃÍ]' ¤Ïpath¤ÎºÇ¸å¤« '%s' ¤¬Â³¤¤¤Æ¤Ê¤¤¤È¤¤¤±¤Þ¤»"
-"¤ó."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpath¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: cdpath¤Ë¤Ï¤³¤ì°Ê¾å \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: ¥Ñ¥¹¤Ë¤Ï¤³¤ì°Ê¾å \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: autocommand¤¬¥Ð¥Ã¥Õ¥¡¤«¥Ð¥Ã¥Õ¥¡Ì¾¤òÊѹ¹¤·¤Þ¤·¤¿"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "ÉÔÀµ¤Ê¥Õ¥¡¥¤¥ë̾"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "¤Ï¥Õ¥¡¥¤¥ë¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "¤Ï¥Ç¥Ð¥¤¥¹¤Ç¤¹ ('opendevice' ¥ª¥×¥·¥ç¥ó¤Ç²óÈò¤Ç¤­¤Þ¤¹)"
+
msgid "[New File]"
msgstr "[¿·¥Õ¥¡¥¤¥ë]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[¿·µ¬¥Ç¥£¥ì¥¯¥È¥ê]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[¥Õ¥¡¥¤¥ë²áÂç]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[¸¢¸Â¤¬¤¢¤ê¤Þ¤»¤ó]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre autocommand ¤¬¥Õ¥¡¥¤¥ë¤òÆÉ¹þÉԲĤˤ·¤Þ¤·¤¿"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: *ReadPre autocommand ¤Ï¸½ºß¤Î¥Ð¥Ã¥Õ¥¡¤òÊѤ¨¤é¤ì¤Þ¤»¤ó"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim: ɸ½àÆþÎϤ«¤éÆÉ¹þÃæ...\n"
-#. Re-opening the original file failed!
-#: ../fileio.c:909
+msgid "Reading from stdin..."
+msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ..."
+
msgid "E202: Conversion made file unreadable!"
msgstr "E202: ÊÑ´¹¤¬¥Õ¥¡¥¤¥ë¤òÆÉ¹þÉԲĤˤ·¤Þ¤·¤¿"
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[FIFO/¥½¥±¥Ã¥È]"
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[FIFO]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[¥½¥±¥Ã¥È]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[¥­¥ã¥é¥¯¥¿¡¦¥Ç¥Ð¥¤¥¹]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CR̵]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[Ĺ¹Ôʬ³ä]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[̤ÊÑ´¹]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[ÊÑ´¹ºÑ]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[%<PRId64> ¹ÔÌܤÇÊÑ´¹¥¨¥é¡¼]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[%ld ¹ÔÌܤÇÊÑ´¹¥¨¥é¡¼]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[%<PRId64> ¹ÔÌܤÎÉÔÀµ¤Ê¥Ð¥¤¥È]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[%ld ¹ÔÌܤÎÉÔÀµ¤Ê¥Ð¥¤¥È]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[ÆÉ¹þ¥¨¥é¡¼]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "ÊÑ´¹¤ËɬÍפʰì»þ¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "'charconvert' ¤Ë¤è¤ëÊÑ´¹¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "'charconvert' ¤Î½ÐÎϤòÆÉ¹þ¤á¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: acwrite¥Ð¥Ã¥Õ¥¡¤Î³ºÅö¤¹¤ëautocommand¤Ï¸ºß¤·¤Þ¤»¤ó"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: Êݸ¤¹¤ë¥Ð¥Ã¥Õ¥¡¤òautocommand¤¬ºï½ü¤«²òÊü¤·¤Þ¤·¤¿"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: autocommand¤¬Í½´ü¤»¤ÌÊýË¡¤Ç¹Ô¿ô¤òÊѹ¹¤·¤Þ¤·¤¿"
-#: ../fileio.c:2548 ../fileio.c:2565
+# Added at 19-Jan-2004.
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans¤Ï̤Êѹ¹¤Î¥Ð¥Ã¥Õ¥¡¤ò¾å½ñ¤¹¤ë¤³¤È¤Ïµö²Ä¤·¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "NetBeans¥Ð¥Ã¥Õ¥¡¤Î°ìÉô¤ò½ñ¤­½Ð¤¹¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
msgid "is not a file or writable device"
msgstr "¤Ï¥Õ¥¡¥¤¥ë¤Ç¤â½ñ¹þ¤ß²Äǽ¥Ç¥Ð¥¤¥¹¤Ç¤â¤¢¤ê¤Þ¤»¤ó"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "'opendevice' ¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¥Ç¥Ð¥¤¥¹¤Ø¤Î½ñ¤­¹þ¤ß¤Ï¤Ç¤­¤Þ¤»¤ó"
+
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:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤òºî¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©ºîÀ®)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤òºî¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©ºîÀ®)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
msgid "E214: Can't find temp file for writing"
msgstr "E214: ÊݸÍѰì»þ¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: ÊÑ´¹¤Ç¤­¤Þ¤»¤ó (! ¤òÄɲäÇÊÑ´¹¤»¤º¤ËÊݸ)"
-#: ../fileio.c:3169
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: fsync ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E949: File changed while writing"
+msgstr "E949: ½ñ¹þ¤ßÃæ¤Ë¥Õ¥¡¥¤¥ë¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../fileio.c:3398
msgid "E512: Close failed"
msgstr "E512: ÊĤ¸¤ë¤³¤È¤Ë¼ºÇÔ"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: ½ñ¹þ¤ß¥¨¥é¡¼, ÊÑ´¹¼ºÇÔ (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ¤¤)"
+msgstr "E513: ½ñ¹þ¤ß¥¨¥é¡¼¡¢ÊÑ´¹¼ºÇÔ (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ¤¤)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: ½ñ¹þ¤ß¥¨¥é¡¼, ÊÑ´¹¼ºÇÔ, ¹Ô¿ô %<PRId64> (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ"
-"¤¯¤À¤µ¤¤)"
+"E513: ½ñ¹þ¤ß¥¨¥é¡¼¡¢ÊÑ´¹¼ºÇÔ¡¢¹Ô¿ô %ld (¾å½ñ¤¹¤ë¤Ë¤Ï 'fenc' ¤ò¶õ¤Ë¤·¤Æ¤¯¤À¤µ"
+"¤¤)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
-msgstr "E514: ½ñ¹þ¤ß¥¨¥é¡¼, (¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤¬ËþÇÕ?)"
+msgstr "E514: ½ñ¹þ¤ß¥¨¥é¡¼ (¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤¬ËþÇÕ?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " ÊÑ´¹¥¨¥é¡¼"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " ¹Ô %<PRId64>;"
+msgid " in line %ld;"
+msgstr " ¹Ô %ld;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[¥Ç¥Ð¥¤¥¹]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[¿·]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " ÄɲÃ"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " ½ñ¹þ¤ß"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: patchmode: ¸¶ËÜ¥Õ¥¡¥¤¥ë¤òÊݸ¤Ç¤­¤Þ¤»¤ó"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: ¶õ¤Î¸¶ËÜ¥Õ¥¡¥¤¥ë¤òtouch¤Ç¤­¤Þ¤»¤ó"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: ¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤ò¾Ã¤»¤Þ¤»¤ó"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2290,134 +1884,102 @@ msgstr ""
"\n"
"·Ù¹ð: ¸¶ËÜ¥Õ¥¡¥¤¥ë¤¬¼º¤ï¤ì¤¿¤«Êѹ¹¤µ¤ì¤Þ¤·¤¿\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "¥Õ¥¡¥¤¥ë¤ÎÊݸ¤ËÀ®¸ù¤¹¤ë¤Þ¤Ç¥¨¥Ç¥£¥¿¤ò½ªÎ»¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤!"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[dos¥Õ¥©¡¼¥Þ¥Ã¥È]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[mac¥Õ¥©¡¼¥Þ¥Ã¥È]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[unix¥Õ¥©¡¼¥Þ¥Ã¥È]"
-#: ../fileio.c:3831
msgid "1 line, "
msgstr "1 ¹Ô, "
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> ¹Ô, "
+msgid "%ld lines, "
+msgstr "%ld ¹Ô, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 ʸ»ú"
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> ʸ»ú"
+msgid "%lld characters"
+msgstr "%lld ʸ»ú"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[noeol]"
-#: ../fileio.c:3849
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
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "·Ù¹ð: ÆÉ¹þ¤ó¤À¸å¤Ë¥Õ¥¡¥¤¥ë¤ËÊѹ¹¤¬¤¢¤ê¤Þ¤·¤¿!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "ËÜÅö¤Ë¾å½ñ¤­¤·¤Þ¤¹¤«"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: \"%s\" ¤ò½ñ¹þ¤ßÃæ¤Î¥¨¥é¡¼¤Ç¤¹"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: \"%s\" ¤òÊĤ¸¤ë»þ¤Ë¥¨¥é¡¼¤Ç¤¹"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: \"%s\" ¤òÆÉ¹þÃæ¤Î¥¨¥é¡¼¤Ç¤¹"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: autocommand ¤Î FileChangedShell ¤¬¥Ð¥Ã¥Õ¥¡¤òºï½ü¤·¤Þ¤·¤¿"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: ¥Õ¥¡¥¤¥ë \"%s\" ¤Ï´û¤Ë¸ºß¤·¤Þ¤»¤ó"
-#: ../fileio.c:4906
#, 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
msgid "See \":help W12\" for more info."
msgstr "¾ÜºÙ¤Ï \":help W12\" ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: ·Ù¹ð: ¥Õ¥¡¥¤¥ë \"%s\" ¤ÏÊÔ½¸³«»Ï¸å¤ËÊѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "¾ÜºÙ¤Ï \":help W11\" ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr "W16: ·Ù¹ð: ¥Õ¥¡¥¤¥ë \"%s\" ¤Î¥â¡¼¥É¤¬ÊÔ½¸³«»Ï¸å¤ËÊѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "¾ÜºÙ¤Ï \":help W16\" ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: ·Ù¹ð: ¥Õ¥¡¥¤¥ë \"%s\" ¤ÏÊÔ½¸³«»Ï¸å¤ËºîÀ®¤µ¤ì¤Þ¤·¤¿"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "·Ù¹ð"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2425,810 +1987,593 @@ msgstr ""
"&OK\n"
"¥Õ¥¡¥¤¥ëÆÉ¹þ(&L)"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: \"%s\" ¤ò¥ê¥í¡¼¥É¤¹¤ë½àÈ÷¤¬¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../fileio.c:5078
#, 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 "autocommand: %s <¥Ð¥Ã¥Õ¥¡=%d> ¤¬¼«Æ°Åª¤Ëºï½ü¤µ¤ì¤Þ¤¹"
-#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: ¤½¤Î¥°¥ë¡¼¥×¤Ï¤¢¤ê¤Þ¤»¤ó: \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: ¸½ºß¤Î¥°¥ë¡¼¥×¤Ïºï½ü¤Ç¤­¤Þ¤»¤ó"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: »ÈÍÑÃæ¤Î augroup ¤ò¾Ã¤½¤¦¤È¤·¤Æ¤¤¤Þ¤¹"
+
#, 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"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <¥Ð¥Ã¥Õ¥¡=%d>: ̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡ÈÖ¹æ¤Ç¤¹ "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Á´¤Æ¤Î¥¤¥Ù¥ó¥È¤ËÂФ·¤Æ¤Îautocommand¤Ï¼Â¹Ô¤Ç¤­¤Þ¤»¤ó"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "³ºÅö¤¹¤ëautocommand¤Ï¸ºß¤·¤Þ¤»¤ó"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: autocommand¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
+msgstr "%s Autocommands for \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "%s ¤ò¼Â¹Ô¤·¤Æ¤¤¤Þ¤¹"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "autocommand %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { ¤¬¤¢¤ê¤Þ¤»¤ó."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } ¤¬¤¢¤ê¤Þ¤»¤ó."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: ÀÞ¾ö¤ß¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: ¸½ºß¤Î 'foldmethod' ¤Ç¤ÏÀÞ¾ö¤ß¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: ¸½ºß¤Î 'foldmethod' ¤Ç¤ÏÀÞ¾ö¤ß¤òºï½ü¤Ç¤­¤Þ¤»¤ó"
-#: ../fold.c:1784
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld ¹Ô¤¬ÀÞ¾ö¤Þ¤ì¤Þ¤·¤¿ "
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld ¹Ô¤¬ÀÞ¾ö¤Þ¤ì¤Þ¤·¤¿"
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: ÆÉ¹þ¥Ð¥Ã¥Õ¥¡¤ØÄɲÃ"
-#: ../getchar.c:2040
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
-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
-msgid "E470: Command aborted"
-msgstr "E470: ¥³¥Þ¥ó¥É¤¬ÃæÃǤµ¤ì¤Þ¤·¤¿"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: °ú¿ô¤¬É¬ÍפǤ¹"
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: GUIÍÑ¤Î¥×¥í¥»¥¹¤Îµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ ¤Î¸å¤Ï / ¤« ? ¤« & ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: »Ò¥×¥í¥»¥¹¤¬GUI¤Îµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: ¥³¥Þ¥ó¥É¥é¥¤¥ó¤Ç¤Ï̵¸ú¤Ç¤¹; <CR>¤Ç¼Â¹Ô, CTRL-C¤Ç¤ä¤á¤ë"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: GUI¤ò³«»Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ä¥¿¥°¸¡º÷¤Ç¤Ïexrc/vimrc¤Î¥³¥Þ¥ó¥É¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: \"%s\"¤«¤éÆÉ¹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: Í­¸ú¤Ê¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤¤¤Î¤Ç¡¢GUI¤ò³«»Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ¤¬Ìµ¸ú¤Ç¤¹"
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: 'imactivatekey' ¤ËÀßÄꤵ¤ì¤¿Ãͤ¬Ìµ¸ú¤Ç¤¹"
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor ¤¬¤¢¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: %s ¤Î¿§¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :while ¤Î¤Ê¤¤ :endwhile ¤¬¤¢¤ê¤Þ¤¹"
+msgid "No match at cursor, finding next"
+msgstr "¥«¡¼¥½¥ë¤Î°ÌÃ֤˥ޥåÁ¤Ï¤¢¤ê¤Þ¤»¤ó¡¢¼¡¤ò¸¡º÷¤·¤Æ¤¤¤Þ¤¹"
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor ¤Î¤Ê¤¤ :for ¤¬¤¢¤ê¤Þ¤¹"
+msgid "<cannot open> "
+msgstr "<³«¤±¤Þ¤»¤ó> "
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: ¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Þ¤¹ (! ¤òÄɲäǾå½ñ)"
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: ¥Õ¥©¥ó¥È %s ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: ¥³¥Þ¥ó¥É¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÌá¤ì¤Þ¤»¤ó"
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: ÆâÉô¥¨¥é¡¼¤Ç¤¹"
+msgid "Pathname:"
+msgstr "¥Ñ¥¹Ì¾:"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "³ä¹þ¤Þ¤ì¤Þ¤·¤¿"
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: ̵¸ú¤Ê¥¢¥É¥ì¥¹¤Ç¤¹"
+msgid "OK"
+msgstr "OK"
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: ̵¸ú¤Ê°ú¿ô¤Ç¤¹"
+msgid "Cancel"
+msgstr "¥­¥ã¥ó¥»¥ë"
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: ̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "¥¹¥¯¥í¡¼¥ë¥Ð¡¼: ²èÁü¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: ̵¸ú¤Ê¼°¤Ç¤¹: %s"
+msgid "Vim dialog"
+msgstr "Vim ¥À¥¤¥¢¥í¥°"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: ̵¸ú¤ÊÈϰϤǤ¹"
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: ¥á¥Ã¥»¡¼¥¸¤È¥³¡¼¥ë¥Ð¥Ã¥¯¤Î¤¢¤ë BalloonEval ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: ̵¸ú¤Ê¥³¥Þ¥ó¥É¤Ç¤¹"
+msgid "_Cancel"
+msgstr "¥­¥ã¥ó¥»¥ë(_C)"
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹"
+msgid "_Save"
+msgstr "Êݸ(_S)"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: ̵¸ú¤Ê¥¹¥¯¥í¡¼¥ëÎ̤Ǥ¹"
+msgid "_Open"
+msgstr "³«¤¯(_O)"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+msgid "_OK"
+msgstr "_OK"
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
msgstr ""
+"¤Ï¤¤(&Y)\n"
+"¤¤¤¤¤¨(&N)\n"
+"¥­¥ã¥ó¥»¥ë(&C)"
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: \"%s\"() ¤Î¥é¥¤¥Ö¥é¥ê¸Æ½Ð¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "Yes"
+msgstr "¤Ï¤¤"
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: ¥Þ¡¼¥¯¤Ë̵¸ú¤Ê¹ÔÈֹ椬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤·¤¿"
+msgid "No"
+msgstr "¤¤¤¤¤¨"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: ¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Input _Methods"
+msgstr "¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: 'modifiable' ¤¬¥ª¥Õ¤Ê¤Î¤Ç, Êѹ¹¤Ç¤­¤Þ¤»¤ó"
+msgid "VIM - Search and Replace..."
+msgstr "VIM - ¸¡º÷¤ÈÃÖ´¹..."
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: ¥¹¥¯¥ê¥×¥È¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Éû¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "VIM - Search..."
+msgstr "VIM - ¸¡º÷..."
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ¤½¤Î¤è¤¦¤Êû½ÌÆþÎϤϤ¢¤ê¤Þ¤»¤ó"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ! ¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Find what:"
+msgstr "¸¡º÷ʸ»úÎó:"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUI¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹"
+msgid "Replace with:"
+msgstr "ÃÖ´¹Ê¸»úÎó:"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ¤½¤Î¤è¤¦¤Ê̾¤Î¥Ï¥¤¥é¥¤¥È¥°¥ë¡¼¥×¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
+msgid "Match whole word only"
+msgstr "Àµ³Î¤Ë³ºÅö¤¹¤ë¤â¤Î¤À¤±"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ¤Þ¤À¥Æ¥­¥¹¥È¤¬ÁÞÆþ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Match case"
+msgstr "Âçʸ»ú/¾®Ê¸»ú¤ò¶èÊ̤¹¤ë"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: °ÊÁ°¤Ë¥³¥Þ¥ó¥É¹Ô¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "Direction"
+msgstr "Êý¸þ"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ¤½¤Î¤è¤¦¤Ê¥Þ¥Ã¥Ô¥ó¥°¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "Up"
+msgstr "¾å"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: ³ºÅö¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "Down"
+msgstr "²¼"
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: ³ºÅö¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
+msgid "Find Next"
+msgstr "¼¡¤ò¸¡º÷"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "Replace"
+msgstr "ÃÖ´¹"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Àµµ¬É½¸½ÃÖ´¹¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Replace All"
+msgstr "Á´¤ÆÃÖ´¹"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: ¥³¥Þ¥ó¥É¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "_Close"
+msgstr "ÊĤ¸¤ë(_C)"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Àµµ¬É½¸½¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: ¥»¥Ã¥·¥ç¥ó¥Þ¥Í¡¼¥¸¥ã¤«¤é \"die\" Í×µá¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿\n"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: ÈϰϻØÄê¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Close tab"
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë"
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: ¥¦¥£¥ó¥É¥¦¤Ë½½Ê¬¤Ê¹â¤µ¤â¤·¤¯¤ÏÉý¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "New tab"
+msgstr "¿·µ¬¥¿¥Ö¥Ú¡¼¥¸"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
+msgid "Open Tab..."
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯..."
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: °ì»þ¥Õ¥¡¥¤¥ë¤Î̾Á°¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: ¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤¬ÉÔ°Õ¤ËÇ˲õ¤µ¤ì¤Þ¤·¤¿\n"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
+msgid "&Filter"
+msgstr "¥Õ¥£¥ë¥¿(&F)"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
+msgid "&Cancel"
+msgstr "¥­¥ã¥ó¥»¥ë(&C)"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó (! ¤òÄɲäÇÊѹ¹¤òÇË´þ)"
+msgid "Directories"
+msgstr "¥Ç¥£¥ì¥¯¥È¥ê"
-#: ../globals.h:1055
-msgid "E37: No write since last change"
-msgstr "E37: ºÇ¸å¤ÎÊѹ¹¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Filter"
+msgstr "¥Õ¥£¥ë¥¿"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: °ú¿ô¤¬¶õ¤Ç¤¹"
+msgid "&Help"
+msgstr "¥Ø¥ë¥×(&H)"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: ¿ôÃͤ¬Í׵ᤵ¤ì¤Æ¤¤¤Þ¤¹"
+msgid "Files"
+msgstr "¥Õ¥¡¥¤¥ë"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó"
+msgid "&OK"
+msgstr "&OK"
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: ¥á¥â¥ê¤¬¿Ô¤­²Ì¤Æ¤Þ¤·¤¿!"
+msgid "Selection"
+msgstr "ÁªÂò"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "Find &Next"
+msgstr "¼¡¤ò¸¡º÷(&N)"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: ¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿: %s"
+msgid "&Replace"
+msgstr "ÃÖ´¹(&R)"
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: °ú¿ô¤ÏÀµ¤ÎÃͤǤʤ±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+msgid "Replace &All"
+msgstr "Á´¤ÆÃÖ´¹(&A)"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Á°¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÌá¤ì¤Þ¤»¤ó"
+msgid "&Undo"
+msgstr "¥¢¥ó¥É¥¥(&U)"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: ¥¨¥é¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "Open tab..."
+msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯"
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: ¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "¸¡º÷ʸ»úÎó ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: ³ºÅöʸ»úÎó¤¬ÇË»¤·¤Æ¤¤¤Þ¤¹"
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "¸¡º÷¡¦ÃÖ´¹ ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: ÉÔÀµ¤ÊÀµµ¬É½¸½¥×¥í¥°¥é¥à¤Ç¤¹"
+msgid "Not Used"
+msgstr "»È¤ï¤ì¤Þ¤»¤ó"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: 'readonly' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹ (! ¤òÄɲäǾå½ñ¤­)"
+msgid "Directory\t*.nothing\n"
+msgstr "¥Ç¥£¥ì¥¯¥È¥ê\t*.nothing\n"
-#: ../globals.h:1073
#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: ÆÉ¼èÀìÍÑÊÑ¿ô \"%s\" ¤Ë¤ÏÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: ¥¿¥¤¥È¥ë¤¬ \"%s\" ¤Î¥¦¥£¥ó¥É¥¦¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../globals.h:1075
#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤ÏÊÑ¿ô \"%s\" ¤ËÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: °ú¿ô¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó: \"-%s\"; OLEÈǤò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤."
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: MDI¥¢¥×¥ê¤ÎÃæ¤Ç¤Ï¥¦¥£¥ó¥É¥¦¤ò³«¤±¤Þ¤»¤ó"
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: ¿§»ØÄ꤬Àµ¤·¤¯¤Ê¤¤¤Î¤Ç¥¨¥ó¥È¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ¤³¤³¤Ç¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ¥¹¥¯¥ê¡¼¥ó¥â¡¼¥É¤ÎÀßÄê¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: ̵¸ú¤Ê¥¹¥¯¥í¡¼¥ëÎ̤Ǥ¹"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: 'shell' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: sign ¤Î¥Ç¡¼¥¿¤òÆÉ¹þ¤á¤Þ¤»¤ó¤Ç¤·¤¿"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î¥¯¥í¡¼¥º»þ¥¨¥é¡¼¤Ç¤¹"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: ¥¿¥°¥¹¥¿¥Ã¥¯¤¬¶õ¤Ç¤¹"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: ¥³¥Þ¥ó¥É¤¬Ê£»¨²á¤®¤Þ¤¹"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: ̾Á°¤¬Ä¹²á¤®¤Þ¤¹"
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: °Ê²¼¤Îʸ»ú¥»¥Ã¥È¤Î¥Õ¥©¥ó¥È¤¬¤¢¤ê¤Þ¤»¤ó %s:"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: [ ¤¬Â¿²á¤®¤Þ¤¹"
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: ¥Õ¥©¥ó¥È¥»¥Ã¥È̾: %s"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ¥Õ¥¡¥¤¥ë̾¤¬Â¿²á¤®¤Þ¤¹"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "¥Õ¥©¥ó¥È '%s' ¤Ï¸ÇÄêÉý¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: ;ʬ¤Êʸ»ú¤¬¸å¤í¤Ë¤¢¤ê¤Þ¤¹"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: ¥Õ¥©¥ó¥È¥»¥Ã¥È̾: %s"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: ̤ÃΤΥޡ¼¥¯"
+#, c-format
+msgid "Font0: %s"
+msgstr "¥Õ¥©¥ó¥È0: %s"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: ¥ï¥¤¥ë¥É¥«¡¼¥É¤òŸ³«¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "Font1: %s"
+msgstr "¥Õ¥©¥ó¥È1: %s"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ¤Ï 'winminheight' ¤è¤ê¾®¤µ¤¯¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "¥Õ¥©¥ó¥È%ld ¤ÎÉý¤¬¥Õ¥©¥ó¥È0¤Î2ÇܤǤϤ¢¤ê¤Þ¤»¤ó"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ¤Ï 'winminwidth' ¤è¤ê¾®¤µ¤¯¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "¥Õ¥©¥ó¥È0¤ÎÉý: %ld"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: ½ñ¹þ¤ßÃæ¤Î¥¨¥é¡¼"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "¥Õ¥©¥ó¥È1¤ÎÉý: %ld"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "¥¼¥í¥«¥¦¥ó¥È"
+msgid "Invalid font specification"
+msgstr "̵¸ú¤Ê¥Õ¥©¥ó¥È»ØÄê¤Ç¤¹"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç<SID>¤¬»È¤ï¤ì¤Þ¤·¤¿"
+msgid "&Dismiss"
+msgstr "µÑ²¼¤¹¤ë(&D)"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: ÆâÉô¥¨¥é¡¼¤Ç¤¹: %s"
+msgid "no specific match"
+msgstr "¥Þ¥Ã¥Á¤¹¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: ¥Ñ¥¿¡¼¥ó¤¬ 'maxmempattern' °Ê¾å¤Î¥á¥â¥ê¤ò»ÈÍѤ·¤Þ¤¹"
+msgid "Vim - Font Selector"
+msgstr "Vim - ¥Õ¥©¥ó¥ÈÁªÂò"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: ¥Ð¥Ã¥Õ¥¡¤¬¶õ¤Ç¤¹"
+msgid "Name:"
+msgstr "̾Á°:"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: ¸¡º÷¥Ñ¥¿¡¼¥ó¤«¶èÀڤ국¹æ¤¬ÉÔÀµ¤Ç¤¹"
+msgid "Show size in Points"
+msgstr "¥µ¥¤¥º¤ò¥Ý¥¤¥ó¥È¤Çɽ¼¨¤¹¤ë"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Ʊ¤¸Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¾¤Î¥Ð¥Ã¥Õ¥¡¤ÇÆÉ¹þ¤Þ¤ì¤Æ¤¤¤Þ¤¹"
+msgid "Encoding:"
+msgstr "¥¨¥ó¥³¡¼¥É:"
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: ¥ª¥×¥·¥ç¥ó '%s' ¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "Font:"
+msgstr "¥Õ¥©¥ó¥È:"
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: ̵¸ú¤Ê¥ì¥¸¥¹¥¿Ì¾¤Ç¤¹"
+msgid "Style:"
+msgstr "¥¹¥¿¥¤¥ë:"
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "¾å¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç²¼¤ËÌá¤ê¤Þ¤¹"
+msgid "Size:"
+msgstr "¥µ¥¤¥º:"
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "²¼¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç¾å¤ËÌá¤ê¤Þ¤¹"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ¥Ï¥ó¥°¥ë¥ª¡¼¥È¥Þ¥È¥ó¥¨¥é¡¼"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: ¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: ÉÔÀµ¤Ê¹½Ê¸Í×ÁǤǤ¹"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: ¿ôÃͤ¬É¬ÍפǤ¹"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "%d ¥Ú¡¼¥¸"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "°õºþ¤¹¤ë¥Æ¥­¥¹¥È¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "°õºþÃæ: ¥Ú¡¼¥¸ %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " ¥³¥Ô¡¼ %d (Á´ %d Ãæ)"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "°õºþ¤·¤Þ¤·¤¿: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "°õºþ¤¬Ãæ»ß¤µ¤ì¤Þ¤·¤¿"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: PostScript½ÐÎÏ¥Õ¥¡¥¤¥ë¤Î½ñ¹þ¤ß¥¨¥é¡¼¤Ç¤¹"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%s\" ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
-#: ../hardcopy.c:1772
#, 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
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: ¥Õ¥¡¥¤¥ë \"%s\" ¤ÏÂбþ¤·¤Æ¤¤¤Ê¤¤ PostScript ¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤Ç¤¹"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: ¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%s\" ¤Ï¥Ð¡¼¥¸¥ç¥ó¤¬°Û¤Ê¤ê¤Þ¤¹"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: ¸ß´¹À­¤Î̵¤¤¥Þ¥ë¥Á¥Ð¥¤¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Èʸ»ú¥»¥Ã¥È¤Ç¤¹"
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr "E674: ¥Þ¥ë¥Á¥Ð¥¤¥È¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤Ç¤Ï printmbcharset ¤ò¶õ¤Ë¤Ç¤­¤Þ¤»¤ó"
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr ""
"E675: ¥Þ¥ë¥Á¥Ð¥¤¥Èʸ»ú¤ò°õºþ¤¹¤ë¤¿¤á¤Î¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: PostScript½ÐÎÏÍѤΥե¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"prolog.ps\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"cidfont.ps\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: PostScript¤Î¥ê¥½¡¼¥¹¥Õ¥¡¥¤¥ë \"%s.ps\" ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: °õºþ¥¨¥ó¥³¡¼¥É \"%s\" ¤ØÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "¥×¥ê¥ó¥¿¤ËÁ÷¿®Ãæ..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: PostScript¥Õ¥¡¥¤¥ë¤Î°õºþ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "°õºþ¥¸¥ç¥Ö¤òÁ÷¿®¤·¤Þ¤·¤¿."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "¿·¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÄɲÃ"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "¥Ñ¥¿¡¼¥ó¤Î¥¯¥¨¥ê¡¼¤òÄɲÃ"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "¤³¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤¹¤ë"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Àܳ¤ò½ªÎ»¤¹¤ë"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "Á´¤Æ¤ÎÀܳ¤òºÆ½é´ü²½¤¹¤ë"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Àܳ¤òɽ¼¨¤¹¤ë"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: »ÈÍÑÊýË¡: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "¤³¤Îcscope¥³¥Þ¥ó¥É¤Ïʬ³ä¥¦¥£¥ó¥É¥¦¤Ç¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: »ÈÍÑË¡: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag: ¥¿¥°¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: stat(%s) ¥¨¥é¡¼: %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: stat ¥¨¥é¡¼"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s ¤Ï¥Ç¥£¥ì¥¯¥È¥êµÚ¤ÓÍ­¸ú¤Êcscope¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "cscope¥Ç¡¼¥¿¥Ù¡¼¥¹ %s ¤òÄɲÃ"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: cscope¤ÎÀܳ %<PRId64> ¤òÆÉ¹þ¤ßÃæ¤Î¥¨¥é¡¼¤Ç¤¹"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: cscope¤ÎÀܳ %ld ¤òÆÉ¹þ¤ßÃæ¤Î¥¨¥é¡¼¤Ç¤¹"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: ̤ÃΤÎcscope¸¡º÷·¿¤Ç¤¹"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: cscope¥Ñ¥¤¥×¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: cscope¤Îµ¯Æ°½àÈ÷(fork)¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:849
msgid "cs_create_connection setpgid failed"
msgstr "cs_create_connection ¤Ø¤Î setpgid ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "cs_create_connection ¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection: to_fp ¤Î fdopen ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection: fr_fp ¤Î fdopen ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: cscope¥×¥í¥»¥¹¤òµ¯Æ°¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: cscopeÀܳ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: ̵¸ú¤Ê cscopequickfix ¥Õ¥é¥° %c ¤Î %c ¤Ç¤¹"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: cscope¥¯¥¨¥ê¡¼ %s of %s ¤Ë³ºÅö¤¬¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "cscope¥³¥Þ¥ó¥É:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (»ÈÍÑË¡: %s)"
-#: ../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"
@@ -3239,6 +2584,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: ¤³¤Î¥·¥ó¥Ü¥ë¤ËÂФ¹¤ëÂåÆþ¤òõ¤¹\n"
" c: ¤³¤Î´Ø¿ô¤ò¸Æ¤ó¤Ç¤¤¤ë´Ø¿ô¤òõ¤¹\n"
" d: ¤³¤Î´Ø¿ô¤«¤é¸Æ¤ó¤Ç¤¤¤ë´Ø¿ô¤òõ¤¹\n"
" e: ¤³¤Îegrep¥Ñ¥¿¡¼¥ó¤òõ¤¹\n"
@@ -3248,31 +2594,31 @@ msgstr ""
" s: ¤³¤ÎC¥·¥ó¥Ü¥ë¤òõ¤¹\n"
" t: ¤³¤Î¥Æ¥­¥¹¥Èʸ»úÎó¤òõ¤¹\n"
-#: ../if_cscope.c:1226
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: cscope¥Ç¡¼¥¿¥Ù¡¼¥¹: %s ¤ò³«¤¯¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: cscope¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
+
msgid "E568: duplicate cscope database not added"
msgstr "E568: ½ÅÊ£¤¹¤ëcscope¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÏÄɲ䵤ì¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: cscopeÀܳ %s ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "cscopeÀܳ %s ¤¬ÊĤ¸¤é¤ì¤Þ¤·¤¿"
-#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: cs_manage_matches ¤ÇÃ×̿Ū¤Ê¥¨¥é¡¼¤Ç¤¹"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Cscope ¥¿¥°: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3280,87 +2626,314 @@ msgstr ""
"\n"
" # ¹ÔÈÖ¹æ"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "¥Õ¥¡¥¤¥ë̾ / ʸ̮ / ¹Ô\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: cscope¥¨¥é¡¼: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "Á´¤Æ¤Îcscope¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥ê¥»¥Ã¥È¤·¤Þ¤¹"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "cscopeÀܳ¤¬¤¢¤ê¤Þ¤»¤ó\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid ¥Ç¡¼¥¿¥Ù¡¼¥¹Ì¾ prepend ¥Ñ¥¹\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "Lua¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó."
+
+msgid "cannot save undo information"
+msgstr "¥¢¥ó¥É¥¥¾ðÊó¤¬Êݸ¤Ç¤­¤Þ¤»¤ó"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr "E815: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹. MzScheme ¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤. MzScheme ¤Î racket/base ¥â¥¸¥å¡¼"
+"¥ë¤¬¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
+
+msgid "invalid expression"
+msgstr "̵¸ú¤Ê¼°¤Ç¤¹"
+
+msgid "expressions disabled at compile time"
+msgstr "¼°¤Ï¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
+msgid "hidden option"
+msgstr "±£¤·¥ª¥×¥·¥ç¥ó"
+
+msgid "unknown option"
+msgstr "̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹"
+
+msgid "window index is out of range"
+msgstr "Èϰϳ°¤Î¥¦¥£¥ó¥É¥¦ÈÖ¹æ¤Ç¤¹"
+
+msgid "couldn't open buffer"
+msgstr "¥Ð¥Ã¥Õ¥¡¤ò³«¤±¤Þ¤»¤ó"
+
+msgid "cannot delete line"
+msgstr "¹Ô¤ò¾Ã¤»¤Þ¤»¤ó"
+
+msgid "cannot replace line"
+msgstr "¹Ô¤òÃÖ´¹¤Ç¤­¤Þ¤»¤ó"
+
+msgid "cannot insert line"
+msgstr "¹Ô¤òÁÞÆþ¤Ç¤­¤Þ¤»¤ó"
+
+msgid "string cannot contain newlines"
+msgstr "ʸ»úÎó¤Ë¤Ï²þ¹Ôʸ»ú¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó"
+
+msgid "error converting Scheme values to Vim"
+msgstr "SchemeÃͤÎVim¤Ø¤ÎÊÑ´¹¥¨¥é¡¼"
+
+msgid "Vim error: ~a"
+msgstr "Vim ¥¨¥é¡¼: ~a"
+
+msgid "Vim error"
+msgstr "Vim ¥¨¥é¡¼"
+
+msgid "buffer is invalid"
+msgstr "¥Ð¥Ã¥Õ¥¡¤Ï̵¸ú¤Ç¤¹"
+
+msgid "window is invalid"
+msgstr "¥¦¥£¥ó¥É¥¦¤Ï̵¸ú¤Ç¤¹"
+
+msgid "linenr out of range"
+msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: ¥é¥¤¥Ö¥é¥ê %s ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤: Perl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ï Safe ¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ·¤Ê¤¤Perl¥¹¥¯¥ê¥×¥È¤Ï¶Ø¤¸¤é¤ì"
+"¤Æ¤¤¤Þ¤¹"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: ¤³¤ÎVim¤Ç¤Ï :py3 ¤ò»È¤Ã¤¿¸å¤Ë :python ¤ò»È¤¨¤Þ¤»¤ó"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤: Python¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»"
+"¤ó¤Ç¤·¤¿."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤. Python ¤Î site ¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É"
+"¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
+
+# Added at 07-Feb-2004.
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python ¤òºÆµ¢Åª¤Ë¼Â¹Ô¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: ¤³¤ÎVim¤Ç¤Ï :python ¤ò»È¤Ã¤¿¸å¤Ë :py3 ¤ò»È¤¨¤Þ¤»¤ó"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ ¤Ïʸ»úÎó¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤: Ruby¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó"
+"¤Ç¤·¤¿."
+
+msgid "E267: unexpected return"
+msgstr "E267: ͽ´ü¤»¤Ì return ¤Ç¤¹"
+
+msgid "E268: unexpected next"
+msgstr "E268: ͽ´ü¤»¤Ì next ¤Ç¤¹"
+
+msgid "E269: unexpected break"
+msgstr "E269: ͽ´ü¤»¤Ì break ¤Ç¤¹"
+
+msgid "E270: unexpected redo"
+msgstr "E270: ͽ´ü¤»¤Ì redo ¤Ç¤¹"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: rescue ¤Î³°¤Î retry ¤Ç¤¹"
+
+msgid "E272: unhandled exception"
+msgstr "E272: ¼è¤ê°·¤ï¤ì¤Ê¤«¤Ã¤¿Îã³°¤¬¤¢¤ê¤Þ¤¹"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: ̤ÃΤÎlongjmp¾õÂÖ: %d"
+
+msgid "invalid buffer number"
+msgstr "̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡ÈÖ¹æ¤Ç¤¹"
+
+msgid "not implemented yet"
+msgstr "¤Þ¤À¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "cannot set line(s)"
+msgstr "¹Ô¤òÀßÄê¤Ç¤­¤Þ¤»¤ó"
+
+msgid "invalid mark name"
+msgstr "̵¸ú¤Ê¥Þ¡¼¥¯Ì¾¤Ç¤¹"
+
+msgid "mark not set"
+msgstr "¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "¹Ô %d Îó %d"
+
+msgid "cannot insert/append line"
+msgstr "¹Ô¤ÎÁÞÆþ/Äɲäò¤Ç¤­¤Þ¤»¤ó"
+
+msgid "line number out of range"
+msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹"
+
+msgid "unknown flag: "
+msgstr "̤ÃΤΥե饰: "
+
+msgid "unknown vimOption"
+msgstr "̤ÃΤΠvimOption ¤Ç¤¹"
+
+msgid "keyboard interrupt"
+msgstr "¥­¡¼¥Ü¡¼¥É³ä¹þ¤ß"
+
+msgid "vim error"
+msgstr "vim ¥¨¥é¡¼"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr ""
+"¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦ºîÀ®¥³¥Þ¥ó¥É¤òºîÀ®¤Ç¤­¤Þ¤»¤ó: ¥ª¥Ö¥¸¥§¥¯¥È¤¬¾Ãµî¤µ¤ì¤Æ¤¤¤Þ"
+"¤·¤¿"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¾Ãµî¤µ¤ì¤Þ¤·¤¿"
+
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL Ã×̿Ū¥¨¥é¡¼: reflist ±øÀ÷!? vim-dev@vim.org ¤ËÊó¹ð¤·¤Æ¤¯¤À¤µ¤¤"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤Î»²¾È¤¬¸«¤Ä¤«¤ê¤Þ¤»"
+"¤ó"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹¡¢¤´¤á¤ó¤Ê¤µ¤¤: Tcl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç"
+"¤·¤¿."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: ½ªÎ»¥³¡¼¥É %d"
+
+msgid "cannot get line"
+msgstr "¹Ô¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
+
+msgid "Unable to register a command server name"
+msgstr "Ì¿Î᥵¡¼¥Ð¡¼¤Î̾Á°¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: ÌÜŪ¤Î¥×¥í¥°¥é¥à¤Ø¤Î¥³¥Þ¥ó¥ÉÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: ̵¸ú¤Ê¥µ¡¼¥Ð¡¼ID¤¬»È¤ï¤ì¤Þ¤·¤¿: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: VIM ¼ÂÂΤÎÅÐÏ¿¥×¥í¥Ñ¥Æ¥£¤¬ÉÔÀµ¤Ç¤¹. ¾Ãµî¤·¤Þ¤·¤¿!"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: JSON¤Ë½ÅÊ£¥­¡¼¤¬¤¢¤ê¤Þ¤¹: \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: ¥ê¥¹¥È·¿¤Ë¥«¥ó¥Þ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ¥ê¥¹¥È·¿¤ÎºÇ¸å¤Ë ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
msgid "Unknown option argument"
msgstr "̤ÃΤΥª¥×¥·¥ç¥ó°ú¿ô¤Ç¤¹"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "ÊÔ½¸°ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "°ú¿ô¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "¥ª¥×¥·¥ç¥ó°ú¿ô¤Î¸å¤Ë¥´¥ß¤¬¤¢¤ê¤Þ¤¹"
-#: ../main.c:152
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
#, c-format
msgid "%d files to edit\n"
msgstr "%d ¸Ä¤Î¥Õ¥¡¥¤¥ë¤¬ÊÔ½¸¤ò¹µ¤¨¤Æ¤¤¤Þ¤¹\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans ¤Ï¤³¤ÎGUI¤Ç¤ÏÍøÍѤǤ­¤Þ¤»¤ó\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' »ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "¤³¤ÎVim¤Ë¤Ïdiffµ¡Ç½¤¬¤¢¤ê¤Þ¤»¤ó(¥³¥ó¥Ñ¥¤¥ë»þÀßÄê)."
+
msgid "Attempt to open script file again: \""
-msgstr "¥¹¥¯¥ê¥×¥È¥Õ¥¡¥¤¥ë¤òºÆ¤Ó³«¤¤¤Æ¤ß¤Þ¤¹: \""
+msgstr "¥¹¥¯¥ê¥×¥È¥Õ¥¡¥¤¥ë¤òºÆ¤Ó³«¤³¤¦¤È¤·¤Þ¤·¤¿: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "ÆÉ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó"
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "¥¹¥¯¥ê¥×¥È½ÐÎÏÍѤò³«¤±¤Þ¤»¤ó"
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: ¥¨¥é¡¼: NetBeans¤«¤égvim¤ò¥¹¥¿¡¼¥È¤Ç¤­¤Þ¤»¤ó\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr "Vim: ¥¨¥é¡¼: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ÎVim¤ÏCygwinüËö¤Ç¤Ïưºî¤·¤Þ¤»¤ó\n"
+
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"
-#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "vimrcÁ°¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: \"%s\"¤«¤éÆÉ¹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3368,37 +2941,30 @@ msgstr ""
"\n"
"¤è¤ê¾ÜºÙ¤Ê¾ðÊó¤Ï: \"vim -h\"\n"
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[¥Õ¥¡¥¤¥ë..] ¤¢¤ë¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤¹¤ë"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- ɸ½àÆþÎϤ«¤é¥Æ¥­¥¹¥È¤òÆÉ¹þ¤à"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t ¥¿¥° ¥¿¥°¤¬ÄêµÁ¤µ¤ì¤¿¤È¤³¤í¤«¤éÊÔ½¸¤¹¤ë"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [errorfile] ºÇ½é¤Î¥¨¥é¡¼¤ÇÊÔ½¸¤¹¤ë"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
"»ÈÍÑË¡:"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [°ú¿ô] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3406,7 +2972,13 @@ msgstr ""
"\n"
" ¤â¤·¤¯¤Ï:"
-#: ../main.c:2196
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Â羮ʸ»ú¤¬Ìµ»ë¤µ¤ì¤ë¾ì¹ç¤ÏÂçʸ»ú¤Ë¤¹¤ë¤¿¤á¤Ë / ¤òÁ°ÃÖ¤·¤Æ¤¯¤À¤µ¤¤"
+
msgid ""
"\n"
"\n"
@@ -3416,189 +2988,322 @@ msgstr ""
"\n"
"°ú¿ô:\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\t\t¤³¤Î¤¢¤È¤Ë¤Ï¥Õ¥¡¥¤¥ë̾¤À¤±"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\t\t¥ï¥¤¥ë¥É¥«¡¼¥É¤òŸ³«¤·¤Ê¤¤"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\t¤³¤Îgvim¤òOLE¤È¤·¤ÆÅÐÏ¿¤¹¤ë"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tgvim¤ÎOLEÅÐÏ¿¤ò²ò½ü¤¹¤ë"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tGUI¤Çµ¯Æ°¤¹¤ë (\"gvim\" ¤ÈƱ¤¸)"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f or --nofork\t¥Õ¥©¥¢¥°¥é¥¦¥ó¥É: GUI¤ò»Ï¤á¤ë¤È¤­¤Ëfork¤·¤Ê¤¤"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\t\tVi¥â¡¼¥É (\"vi\" ¤ÈƱ¤¸)"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\t\tEx¥â¡¼¥É (\"ex\" ¤ÈƱ¤¸)"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
msgstr "-E\t\t\t²þÎÉEx¥â¡¼¥É"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\t\t¥µ¥¤¥ì¥ó¥È(¥Ð¥Ã¥Á)¥â¡¼¥É (\"ex\" ÀìÍÑ)"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\t\tº¹Ê¬¥â¡¼¥É (\"vidiff\" ¤ÈƱ¤¸)"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\t¥¤¡¼¥¸¡¼¥â¡¼¥É (\"evim\" ¤ÈƱ¤¸, ¥â¡¼¥É̵)"
+msgstr "-y\t\t\t¥¤¡¼¥¸¡¼¥â¡¼¥É (\"evim\" ¤ÈƱ¤¸¡¢¥â¡¼¥É̵)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\t\tÆÉ¹þÀìÍѥ⡼¥É (\"view\" ¤ÈƱ¤¸)"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\t\tÀ©¸Â¥â¡¼¥É (\"rvim\" ¤ÈƱ¤¸)"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\t\tÊѹ¹ (¥Õ¥¡¥¤¥ëÊݸ»þ) ¤ò¤Ç¤­¤Ê¤¤¤è¤¦¤Ë¤¹¤ë"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\t\t¥Æ¥­¥¹¥È¤ÎÊÔ½¸¤ò¹Ô¤Ê¤¨¤Ê¤¤¤è¤¦¤Ë¤¹¤ë"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\t\t¥Ð¥¤¥Ê¥ê¥â¡¼¥É"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\t\tLisp¥â¡¼¥É"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\t\tVi¸ß´¹¥â¡¼¥É: 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\t\tViÈó¸ß´¹¥â¡¼¥É: 'nocompatible"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr "-V[N][fname]\t\t¥í¥°½ÐÎÏÀßÄê [¥ì¥Ù¥ë N] [¥í¥°¥Õ¥¡¥¤¥ë̾ fname]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\t\t¥Ç¥Ð¥Ã¥°¥â¡¼¥É"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\t\t¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ»¤º¥á¥â¥ê¤À¤±"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\t\t¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤òÎóµó¤·½ªÎ»"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r (¥Õ¥¡¥¤¥ë̾)\t¥¯¥é¥Ã¥·¥å¤·¤¿¥»¥Ã¥·¥ç¥ó¤òÉüµ¢"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\t\t-r¤ÈƱ¤¸"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\t¥¦¥£¥ó¥É¥¦¤ò³«¤¯¤Î¤Ë newcli ¤ò»ÈÍѤ·¤Ê¤¤"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\tI/O¤Ë <device> ¤ò»ÈÍѤ¹¤ë"
+
+msgid "-A\t\t\tStart in Arabic mode"
msgstr "-A\t\t\t¥¢¥é¥Ó¥¢¸ì¥â¡¼¥É¤Çµ¯Æ°¤¹¤ë"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\t\t¥Ø¥Ö¥é¥¤¸ì¥â¡¼¥É¤Çµ¯Æ°¤¹¤ë"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\t\t¥Ú¥ë¥·¥¢¸ì¥â¡¼¥É¤Çµ¯Æ°¤¹¤ë"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <terminal>\tüËö¤ò <terminal> ¤ËÀßÄꤹ¤ë"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr "--not-a-term\t\tÆþ½ÐÎϤ¬Ã¼Ëö¤Ç¤Ê¤¤¤È¤Î·Ù¹ð¤ò¥¹¥­¥Ã¥×¤¹¤ë"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr "--ttyfail\t\tÆþ½ÐÎϤ¬Ã¼Ëö¤Ç¤Ê¤±¤ì¤Ð½ªÎ»¤¹¤ë"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\t\t.vimrc¤ÎÂå¤ï¤ê¤Ë <vimrc> ¤ò»È¤¦"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\t.gvimrc¤ÎÂå¤ï¤ê¤Ë <gvimrc> ¤ò»È¤¦"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\t¥×¥é¥°¥¤¥ó¥¹¥¯¥ê¥×¥È¤ò¥í¡¼¥É¤·¤Ê¤¤"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
msgstr "-p[N]\t\tN ¸Ä¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯(¾ÊάÃÍ: ¥Õ¥¡¥¤¥ë¤Ë¤Ä¤­1¸Ä)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tN ¸Ä¥¦¥£¥ó¥É¥¦¤ò³«¤¯(¾ÊάÃÍ: ¥Õ¥¡¥¤¥ë¤Ë¤Ä¤­1¸Ä)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\t\t-o¤ÈƱ¤¸¤À¤¬¿âľʬ³ä"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\t\t¥Õ¥¡¥¤¥ë¤ÎºÇ¸å¤«¤é¤Ï¤¸¤á¤ë"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<lnum>\t\t<lnum> ¹Ô¤«¤é¤Ï¤¸¤á¤ë"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr "--cmd <command>\tvimrc¤ò¥í¡¼¥É¤¹¤ëÁ°¤Ë <command> ¤ò¼Â¹Ô¤¹¤ë"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <command>\t\tºÇ½é¤Î¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¸å <command> ¤ò¼Â¹Ô¤¹¤ë"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr "-S <session>\t\tºÇ½é¤Î¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¸å¥Õ¥¡¥¤¥ë <session> ¤ò¼è¹þ¤à"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <scriptin>\t¥Õ¥¡¥¤¥ë <scriptin> ¤«¤é¥Î¡¼¥Þ¥ë¥³¥Þ¥ó¥É¤òÆÉ¹þ¤à"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr "-w <scriptout>\tÆþÎϤ·¤¿Á´¥³¥Þ¥ó¥É¤ò¥Õ¥¡¥¤¥ë <scriptout> ¤ËÄɲ乤ë"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr "-W <scriptout>\tÆþÎϤ·¤¿Á´¥³¥Þ¥ó¥É¤ò¥Õ¥¡¥¤¥ë <scriptout> ¤ËÊݸ¤¹¤ë"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\t°Å¹æ²½¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤¹¤ë"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tvim¤ò»ØÄꤷ¤¿ X ¥µ¡¼¥Ð¡¼¤ËÀܳ¤¹¤ë"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tX¥µ¡¼¥Ð¡¼¤ËÀܳ¤·¤Ê¤¤"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <files>\t²Äǽ¤Ê¤é¤ÐVim¥µ¡¼¥Ð¡¼¤Ç <files> ¤òÊÔ½¸¤¹¤ë"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <files> Ʊ¾å¡¢¥µ¡¼¥Ð¡¼¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr "--remote-wait <files>\t--remote¸å ¥Õ¥¡¥¤¥ë¤ÎÊÔ½¸¤¬½ª¤ï¤ë¤Î¤òÂÔ¤Ä"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <files> Ʊ¾å¡¢¥µ¡¼¥Ð¡¼¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <files> --remote¤Ç¥Õ¥¡¥¤¥ë1¤Ä¤Ë¤Ä¤­1¤Ä¤Î¥¿¥Ö"
+"¥Ú¡¼¥¸¤ò³«¤¯"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <keys>\tVim¥µ¡¼¥Ð¡¼¤Ë <keys> ¤òÁ÷¿®¤·¤Æ½ªÎ»¤¹¤ë"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <expr>\t¥µ¡¼¥Ð¡¼¤Ç <expr> ¤ò¼Â¹Ô¤·¤Æ·ë²Ì¤òɽ¼¨¤¹¤ë"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tVim¥µ¡¼¥Ð¡¼Ì¾¤Î°ìÍ÷¤òɽ¼¨¤·¤Æ½ªÎ»¤¹¤ë"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <name>\tVim¥µ¡¼¥Ð¡¼ <name> ¤ËÁ÷¿®/̾Á°ÀßÄꤹ¤ë"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr "--startuptime <file>\tµ¯Æ°¤Ë¤«¤«¤Ã¤¿»þ´Ö¤Î¾ÜºÙ¤ò <file> ¤Ø½ÐÎϤ¹¤ë"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\t.viminfo¤ÎÂå¤ï¤ê¤Ë <viminfo> ¤ò»È¤¦"
-#: ../main.c:2243
+msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo"
+msgstr "--clean\t\t'nocompatible'¡¢Vim¤Î´ûÄê¡¢¥×¥é¥°¥¤¥ó¤Ê¤·¡¢viminfo¤Ê¤·"
+
msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h or --help\t¥Ø¥ë¥×(¤³¤Î¥á¥Ã¥»¡¼¥¸)¤òɽ¼¨¤·½ªÎ»¤¹¤ë"
+msgstr "-h or --help\t¥Ø¥ë¥×(¤³¤Î¥á¥Ã¥»¡¼¥¸)¤òɽ¼¨¤·½ªÎ»¤¹¤ë"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\t¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤òɽ¼¨¤·½ªÎ»¤¹¤ë"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(Motif¥Ð¡¼¥¸¥ç¥ó):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(neXtaw¥Ð¡¼¥¸¥ç¥ó):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(Athena¥Ð¡¼¥¸¥ç¥ó):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\t<display> ¤Çvim¤ò¼Â¹Ô¤¹¤ë"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tºÇ¾®²½¤·¤¿¾õÂÖ¤Çvim¤òµ¯Æ°¤¹¤ë"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <color>\tÇØ·Ê¿§¤Ë <color> ¤ò»È¤¦(ƱµÁ: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <color>\tÁ°·Ê¿§¤Ë <color> ¤ò»È¤¦(ƱµÁ: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <font>\t\t¥Æ¥­¥¹¥Èɽ¼¨¤Ë <font> ¤ò»È¤¦(ƱµÁ: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <font>\tÂÀ»ú¤Ë <font> ¤ò»È¤¦"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <for>\t¼ÐÂλú¤Ë <font> ¤ò»È¤¦"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\t½é´üÇÛÃÖ¤Ë <geom> ¤ò»È¤¦(ƱµÁ: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <width>\t¶­³¦¤ÎÉý¤ò <width> ¤Ë¤¹¤ë(ƱµÁ: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <width> ¥¹¥¯¥í¡¼¥ë¥Ð¡¼¤ÎÉý¤ò <width> ¤Ë¤¹¤ë(ƱµÁ: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <height>\t¥á¥Ë¥å¡¼¥Ð¡¼¤Î¹â¤µ¤ò <height> ¤Ë¤¹¤ë(ƱµÁ: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tȿž±ÇÁü¤ò»ÈÍѤ¹¤ë(ƱµÁ: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tȿž±ÇÁü¤ò»ÈÍѤ·¤Ê¤¤(ƱµÁ: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\tÆÃÄê¤Î¥ê¥½¡¼¥¹¤ò»ÈÍѤ¹¤ë"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(GTK+¥Ð¡¼¥¸¥ç¥ó):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\t<display> ¤Çvim¤ò¼Â¹Ô¤¹¤ë(ƱµÁ: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <role>\t¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤ò¼±Ê̤¹¤ë°ì°Õ¤ÊÌò³ä(role)¤òÀßÄꤹ¤ë"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\t°Û¤Ê¤ëGTK widget¤ÇVim¤ò³«¤¯"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\t¥¦¥£¥ó¥É¥¦ID¤òɸ½à½ÐÎϤ˽ÐÎϤ¹¤ë"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <¿Æ¤Î¥¿¥¤¥È¥ë>\tVim¤ò¿Æ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÃæ¤Çµ¯Æ°¤¹¤ë"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\t°Û¤Ê¤ëWin32 widget¤ÎÆâÉô¤ËVim¤ò³«¤¯"
+
+msgid "No display"
+msgstr "¥Ç¥£¥¹¥×¥ì¥¤¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+msgid ": Send failed.\n"
+msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
+
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿. ¥í¡¼¥«¥ë¤Ç¤Î¼Â¹Ô¤ò»î¤ß¤Æ¤¤¤Þ¤¹\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d ¸Ä (%d ¸ÄÃæ) ¤Î¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤·¤¿"
+
+msgid "No display: Send expression failed.\n"
+msgstr "¥Ç¥£¥¹¥×¥ì¥¤¤¬¤¢¤ê¤Þ¤»¤ó: ¼°¤ÎÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": ¼°¤ÎÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
+
msgid "No marks set"
msgstr "¥Þ¡¼¥¯¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: \"%s\" ¤Ë³ºÅö¤¹¤ë¥Þ¡¼¥¯¤¬¤¢¤ê¤Þ¤»¤ó"
-#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3606,8 +3311,6 @@ msgstr ""
"\n"
"mark ¹Ô Îó ¥Õ¥¡¥¤¥ë/¥Æ¥­¥¹¥È"
-#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3615,8 +3318,6 @@ msgstr ""
"\n"
" jump ¹Ô Îó ¥Õ¥¡¥¤¥ë/¥Æ¥­¥¹¥È"
-#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3624,7 +3325,6 @@ msgstr ""
"\n"
"Êѹ¹ ¹Ô Îó ¥Æ¥­¥¹¥È"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3632,8 +3332,6 @@ msgstr ""
"\n"
"# ¥Õ¥¡¥¤¥ë¥Þ¡¼¥¯:\n"
-#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3641,7 +3339,6 @@ msgstr ""
"\n"
"# ¥¸¥ã¥ó¥×¥ê¥¹¥È (¿·¤·¤¤¤â¤Î¤¬Àè):\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3649,84 +3346,87 @@ msgstr ""
"\n"
"# ¥Õ¥¡¥¤¥ëÆâ¥Þ¡¼¥¯¤ÎÍúÎò (¿·¤·¤¤¤â¤Î¤«¤é¸Å¤¤¤â¤Î):\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "'>' ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: ̵¸ú¤Ê¥³¡¼¥É¥Ú¡¼¥¸¤Ç¤¹"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: IC¤ÎÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: ¥¤¥ó¥×¥Ã¥È¥³¥ó¥Æ¥­¥¹¥È¤ÎºîÀ®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Î¥ª¡¼¥×¥ó¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: ·Ù¹ð: IM¤ÎÇ˲õ¥³¡¼¥ë¥Ð¥Ã¥¯¤òÀßÄê¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Ï¤É¤ó¤Ê¥¹¥¿¥¤¥ë¤â¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Ï my preedit type ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó"
+
msgid "E293: block was not locked"
msgstr "E293: ¥Ö¥í¥Ã¥¯¤¬¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ëÆÉ¹þ»þ¤Ë¥·¡¼¥¯¥¨¥é¡¼¤Ç¤¹"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þ¤ß¥¨¥é¡¼¤Ç¤¹"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë½ñ¹þ¤ß»þ¤Ë¥·¡¼¥¯¥¨¥é¡¼¤Ç¤¹"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î½ñ¹þ¤ß¥¨¥é¡¼¤Ç¤¹"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬´û¤Ë¸ºß¤·¤Þ¤¹ (symlink¤Ë¤è¤ë¹¶·â?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: ¥Ö¥í¥Ã¥¯ 0 ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: ¥Ö¥í¥Ã¥¯ 1 ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó?"
-#: ../memline.c:377
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
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î°Å¹æ¤ò¹¹¿·Ãæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+
msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: ¤ª¤Ã¤È, ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¼º¤ï¤ì¤Þ¤·¤¿!!!"
+msgstr "E301: ¤ª¤Ã¤È¡¢¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¼º¤ï¤ì¤Þ¤·¤¿!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î̾Á°¤òÊѤ¨¤é¤ì¤Þ¤»¤ó"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: \"%s\" ¤Î¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò³«¤±¤Ê¤¤¤Î¤Ç¥ê¥«¥Ð¥ê¤ÏÉÔ²Äǽ¤Ç¤¹"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): ¥Ö¥í¥Ã¥¯ 0 ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: %s ¤Ë¤Ï¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "»ÈÍѤ¹¤ë¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ÎÈÖ¹æ¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤(0 ¤Ç½ªÎ»): "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: %s ¤ò³«¤±¤Þ¤»¤ó"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "¥Ö¥í¥Ã¥¯ 0 ¤òÆÉ¹þ¤á¤Þ¤»¤ó "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3734,28 +3434,22 @@ msgstr ""
"\n"
"¶²¤é¤¯Êѹ¹¤¬¤µ¤ì¤Æ¤¤¤Ê¤¤¤«Vim¤¬¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò¹¹¿·¤·¤Æ¤¤¤Þ¤»¤ó."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " Vim¤Î¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Vim¤Î¥Ð¡¼¥¸¥ç¥ó3.0¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ¤ÏVim¤Î¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " ¤³¤Î¥³¥ó¥Ô¥å¡¼¥¿¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¼¡¤Î¾ì½ê¤Çºî¤é¤ì¤Þ¤·¤¿ "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3763,101 +3457,117 @@ msgstr ""
",\n"
"¤â¤·¤¯¤Ï¥Õ¥¡¥¤¥ë¤¬Â»½ý¤·¤Æ¤¤¤Þ¤¹."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: %s ¤Ï¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ÎVim¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤·Á¼°¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " ¤Ï»½ý¤·¤Æ¤¤¤Þ¤¹ (¥Ú¡¼¥¸¥µ¥¤¥º¤¬ºÇ¾®Ãͤò²¼²ó¤Ã¤Æ¤¤¤Þ¤¹).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \"%s\" ¤ò»ÈÍÑÃæ"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "¸¶ËÜ¥Õ¥¡¥¤¥ë \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: ·Ù¹ð: ¸¶ËÜ¥Õ¥¡¥¤¥ë¤¬Êѹ¹¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ï°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"¿·¤·¤¤°Å¹æ¥­¡¼¤òÆþÎϤ·¤¿¤¢¤È¤Ë¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"¿·¤·¤¤°Å¹æ¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"°Å¹æ¥­¡¼¤òÊѤ¨¤¿¤¢¤È¤Ë¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤¿¾ì¹ç¤Ï¡¢¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤È"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ËƱ¤¸°Å¹æ¥­¡¼¤ò»È¤¦¤¿¤á¤Ëenter¤À¤±¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤."
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: %s ¤«¤é¥Ö¥í¥Ã¥¯ 1 ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???¿¤¯¤Î¹Ô¤¬¼º¤ï¤ì¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???¹Ô¿ô¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???¥Ö¥í¥Ã¥¯¤¬¶õ¤Ç¤¹"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???¹Ô¤¬¼º¤ï¤ì¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: ¥Ö¥í¥Ã¥¯ 1 ¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹(%s ¤¬.swp¥Õ¥¡¥¤¥ë¤Ç¤Ê¤¤?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???¥Ö¥í¥Ã¥¯¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? ¤³¤³¤«¤é ???END ¤Þ¤Ç¤Î¹Ô¤¬Ç˲õ¤µ¤ì¤Æ¤¤¤ë¤è¤¦¤Ç¤¹"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? ¤³¤³¤«¤é ???END ¤Þ¤Ç¤Î¹Ô¤¬ÁÞÆþ¤«ºï½ü¤µ¤ì¤¿¤è¤¦¤Ç¤¹"
-#: ../memline.c:1181
msgid "???END"
msgstr "???END"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: ¥ê¥«¥Ð¥ê¤¬³ä¹þ¤Þ¤ì¤Þ¤·¤¿"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: ¥ê¥«¥Ð¥ê¤ÎºÇÃæ¤Ë¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿; ???¤Ç»Ï¤Þ¤ë¹Ô¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "¾ÜºÙ¤Ï \":help E312\" ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "¥ê¥«¥Ð¥ê¤¬½ªÎ»¤·¤Þ¤·¤¿. Á´¤Æ¤¬Àµ¤·¤¤¤«¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
msgstr ""
"\n"
-"(Êѹ¹¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤¿¤á¤Ë, ¤³¤Î¥Õ¥¡¥¤¥ë¤òÊ̤Î̾Á°¤ÇÊݸ¤·¤¿¾å¤Ç\n"
+"(Êѹ¹¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤¿¤á¤Ë¡¢¤³¤Î¥Õ¥¡¥¤¥ë¤òÊ̤Î̾Á°¤ÇÊݸ¤·¤¿¾å¤Ç\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "¸¶ËÜ¥Õ¥¡¥¤¥ë¤È¤Î diff ¤ò¼Â¹Ô¤¹¤ë¤ÈÎɤ¤¤Ç¤·¤ç¤¦)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr "Éü¸µ´°Î». ¥Ð¥Ã¥Õ¥¡¤ÎÆâÍÆ¤Ï¥Õ¥¡¥¤¥ë¤ÈƱ¤¸¤Ë¤Ê¤ê¤Þ¤·¤¿."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3867,52 +3577,42 @@ msgstr ""
"¸µ¤Î.swp¥Õ¥¡¥¤¥ë¤Ïºï½ü¤·¤Æ¤â¹½¤¤¤Þ¤»¤ó\n"
"\n"
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤«¤é¼èÆÀ¤·¤¿°Å¹æ¥­¡¼¤ò¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Ë»È¤¤¤Þ¤¹.\n"
+
msgid "Swap files found:"
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Ê£¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " °Ê²¼¤Î̾Á°¤ò»ÈÍÑÃæ:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " ¥Ç¥£¥ì¥¯¥È¥ê "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- ¤Ê¤· --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " ½êÍ­¼Ô: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " ÆüÉÕ: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " ÆüÉÕ: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [from Vim version 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [Vim¤Î¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " ¥Õ¥¡¥¤¥ë̾: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3920,15 +3620,12 @@ msgstr ""
"\n"
" Êѹ¹¾õÂÖ: "
-#: ../memline.c:1559
msgid "YES"
msgstr "¤¢¤ê"
-#: ../memline.c:1559
msgid "no"
msgstr "¤Ê¤·"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3936,11 +3633,9 @@ msgstr ""
"\n"
" ¥æ¡¼¥¶¡¼Ì¾: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " ¥Û¥¹¥È̾: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3948,7 +3643,6 @@ msgstr ""
"\n"
" ¥Û¥¹¥È̾: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3956,11 +3650,16 @@ msgstr ""
"\n"
" ¥×¥í¥»¥¹ID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (¤Þ¤À¼Â¹ÔÃæ)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [¤³¤ÎVim¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -3968,97 +3667,75 @@ msgstr ""
"\n"
" [¤³¤Î¥³¥ó¥Ô¥å¡¼¥¿¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [ÆÉ¹þ¤á¤Þ¤»¤ó]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [³«¤±¤Þ¤»¤ó]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Ìµ¤¤¤Î¤Ç°Ý»ý¤Ç¤­¤Þ¤»¤ó"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "¥Õ¥¡¥¤¥ë¤¬°Ý»ý¤µ¤ì¤Þ¤¹"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: °Ý»ý¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: ̵¸ú¤Êlnum¤Ç¤¹: %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: ̵¸ú¤Êlnum¤Ç¤¹: %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: ¹Ô %<PRId64> ¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: ¹Ô %ld ¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx ¤Ï 0 ¤Ç¤¢¤ë¤Ù¤­¤Ç¤¹"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: ¹¹¿·¤µ¤ì¤¿¥Ö¥í¥Ã¥¯¤¬Â¿²á¤®¤ë¤«¤â?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "¥Ö¥í¥Ã¥¯ 1 ¤Ï¾Ã¤µ¤ì¤¿?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: ¹Ô %<PRId64> ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: ¹Ô %ld ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count ¤¬¥¼¥í¤Ç¤¹"
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: ¹ÔÈֹ椬Èϰϳ°¤Ç¤¹: %<PRId64> ͤ¨¤Æ¤¤¤Þ¤¹"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: ¹ÔÈֹ椬Èϰϳ°¤Ç¤¹: %ld ͤ¨¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ¥Ö¥í¥Ã¥¯ %<PRId64> ¤Î¹Ô¥«¥¦¥ó¥È¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: ¥Ö¥í¥Ã¥¯ %ld ¤Î¹Ô¥«¥¦¥ó¥È¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤¬Áý¤¨¤Þ¤¹"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: ¥Ý¥¤¥ó¥¿¥Ö¥í¥Ã¥¯¤ÎID¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹ 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: \"%s\" ¤Î¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤¬¥ë¡¼¥×¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: Ãí°Õ"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4066,39 +3743,30 @@ msgstr ""
"\n"
"¼¡¤Î̾Á°¤Ç¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ò¸«¤Ä¤±¤Þ¤·¤¿ \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "¼¡¤Î¥Õ¥¡¥¤¥ë¤ò³«¤¤¤Æ¤¤¤ëºÇÃæ \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤è¤ê¤â¿·¤·¤¤¤Ç¤¹!\n"
-#: ../memline.c:3244
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"
-" ¤³¤Î¾ì¹ç¤Ë¤Ï, Êѹ¹¤ò¤·¤Æ¤·¤Þ¤¦¤È1¤Ä¤Î¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ°Û¤Ê¤ë2¤Ä¤Î\n"
-" ¥¤¥ó¥¹¥¿¥ó¥¹¤¬¤Ç¤­¤Æ¤·¤Þ¤¦¤Î¤Ç, ¤½¤¦¤·¤Ê¤¤¤è¤¦¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤."
+" ¤³¤Î¾ì¹ç¤Ë¤Ï¡¢Êѹ¹¤ò¤·¤Æ¤·¤Þ¤¦¤È1¤Ä¤Î¥Õ¥¡¥¤¥ë¤ËÂФ·¤Æ°Û¤Ê¤ë2¤Ä¤Î\n"
+" ¥¤¥ó¥¹¥¿¥ó¥¹¤¬¤Ç¤­¤Æ¤·¤Þ¤¦¤Î¤Ç¡¢¤½¤¦¤·¤Ê¤¤¤è¤¦¤Ëµ¤¤ò¤Ä¤±¤Æ¤¯¤À¤µ¤¤.\n"
+" ½ªÎ»¤¹¤ë¤«¡¢Ãí°Õ¤·¤Ê¤¬¤é³¤±¤Æ¤¯¤À¤µ¤¤.\n"
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " ½ªÎ»¤¹¤ë¤«, Ãí°Õ¤·¤Ê¤¬¤é³¤±¤Æ¤¯¤À¤µ¤¤.\n"
-
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) ¤³¤Î¥Õ¥¡¥¤¥ë¤ÎÊÔ½¸¥»¥Ã¥·¥ç¥ó¤¬¥¯¥é¥Ã¥·¥å¤·¤¿.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " ¤³¤Î¾ì¹ç¤Ë¤Ï \":recover\" ¤« \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4106,11 +3774,9 @@ msgstr ""
"\"\n"
" ¤ò»ÈÍѤ·¤ÆÊѹ¹¤ò¥ê¥«¥Ð¡¼¤·¤Þ¤¹(\":help recovery\" ¤ò»²¾È).\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
-msgstr " ´û¤Ë¤³¤ì¤ò¹Ô¤Ê¤Ã¤¿¤Î¤Ê¤é¤Ð, ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \""
+msgstr " ´û¤Ë¤³¤ì¤ò¹Ô¤Ê¤Ã¤¿¤Î¤Ê¤é¤Ð¡¢¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4118,23 +3784,18 @@ msgstr ""
"\"\n"
" ¤ò¾Ã¤»¤Ð¤³¤Î¥á¥Ã¥»¡¼¥¸¤ò²óÈò¤Ç¤­¤Þ¤¹.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" ¤¬´û¤Ë¤¢¤ê¤Þ¤¹!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - Ãí°Õ"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬´û¤Ë¸ºß¤·¤Þ¤¹!"
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4148,7 +3809,6 @@ msgstr ""
"½ªÎ»¤¹¤ë(&Q)\n"
"Ãæ»ß¤¹¤ë(&A)"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4164,56 +3824,31 @@ 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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤¬Â¿¿ô¸«¤Ä¤«¤ê¤Þ¤·¤¿"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: ¥á¥â¥ê¤¬Â­¤ê¤Þ¤»¤ó! (%<PRIu64> ¥Ð¥¤¥È¤ò³äÅöÍ×µá)"
-
-#: ../menu.c:62
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
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: \"%s\" ¤È¤¤¤¦¥á¥Ë¥å¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: ¥á¥Ë¥å¡¼Ì¾¤¬¶õ¤Ç¤¹"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥µ¥Ö¥á¥Ë¥å¡¼¤òÀ¸¤¸¤ë¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: ¥á¥Ë¥å¡¼¥Ð¡¼¤Ë¤ÏľÀÜ¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤òÄɲäǤ­¤Þ¤»¤ó"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: ¶èÀÚ¤ê¤Ï¥á¥Ë¥å¡¼¥Ñ¥¹¤Î°ìÉô¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4221,73 +3856,60 @@ msgstr ""
"\n"
"--- ¥á¥Ë¥å¡¼ ---"
-#: ../menu.c:1313
+msgid "Tear off this menu"
+msgstr "¤³¤Î¥á¥Ë¥å¡¼¤òÀÚ¤ê¼è¤ë"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %s ¤Ë¤Ï¥á¥Ë¥å¡¼¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥á¥Ë¥å¡¼¥¢¥¤¥Æ¥à¤òÀ¸¤¸¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
-#: ../menu.c:1330
#, 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
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: ¥á¥Ë¥å¡¼¥Ñ¥¹¤Ï¥µ¥Ö¥á¥Ë¥å¡¼¤òÀ¸¤¸¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: ¥á¥Ë¥å¡¼¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó - ¥á¥Ë¥å¡¼Ì¾¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "%s ¤Î½èÍýÃæ¤Ë¥¨¥é¡¼¤¬¸¡½Ð¤µ¤ì¤Þ¤·¤¿:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "¹Ô %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: ̵¸ú¤Ê¥ì¥¸¥¹¥¿Ì¾: '%s'"
-#: ../message.c:745
msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
msgstr "ÆüËܸì¥á¥Ã¥»¡¼¥¸ËÝÌõ/´Æ½¤: ¼²¬ ÂÀϺ <koron.kaoriya@gmail.com>"
-#: ../message.c:986
msgid "Interrupt: "
msgstr "³ä¹þ¤ß: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "³¤±¤ë¤Ë¤ÏENTER¤ò²¡¤¹¤«¥³¥Þ¥ó¥É¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s ¹Ô %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s ¹Ô %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- ·Ñ³ --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " SPACE/d/j: ²èÌÌ/¥Ú¡¼¥¸/¹Ô ²¼, b/u/k: ¾å, q: ½ªÎ» "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "¼ÁÌä"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4295,17 +3917,6 @@ msgstr ""
"¤Ï¤¤(&Y)\n"
"¤¤¤¤¤¨(&N)"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"¤Ï¤¤(&Y)\n"
-"¤¤¤¤¤¨(&N)\n"
-"¥­¥ã¥ó¥»¥ë(&C)"
-
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4319,175 +3930,252 @@ msgstr ""
"Á´¤ÆÊü´þ(&D)\n"
"¥­¥ã¥ó¥»¥ë(&C)"
-#: ../message.c:3058
+msgid "Select Directory dialog"
+msgstr "¥Ç¥£¥ì¥¯¥È¥êÁªÂò¥À¥¤¥¢¥í¥°"
+
+msgid "Save File dialog"
+msgstr "¥Õ¥¡¥¤¥ëÊݸ¥À¥¤¥¢¥í¥°"
+
+msgid "Open File dialog"
+msgstr "¥Õ¥¡¥¤¥ëÆÉ¹þ¥À¥¤¥¢¥í¥°"
+
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: ¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤Ç¤Ï¥Õ¥¡¥¤¥ë¥Ö¥é¥¦¥¶¤ò»È¤¨¤Þ¤»¤ó¡¢¤´¤á¤ó¤Ê¤µ¤¤"
+
msgid "E766: Insufficient arguments for printf()"
msgstr "E766: printf() ¤Î°ú¿ô¤¬ÉÔ½½Ê¬¤Ç¤¹"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
-msgstr "E807: 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
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr ""
"ÈÖ¹æ¤È<Enter>¤òÆþÎϤ¹¤ë¤«¥Þ¥¦¥¹¤Ç¥¯¥ê¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤ (¶õ¤Ç¥­¥ã¥ó¥»¥ë): "
-#: ../misc1.c:2539
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> ¹Ô Äɲä·¤Þ¤·¤¿"
+msgid "%ld more lines"
+msgstr "%ld ¹Ô Äɲä·¤Þ¤·¤¿"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> ¹Ô ºï½ü¤·¤Þ¤·¤¿"
+msgid "%ld fewer lines"
+msgstr "%ld ¹Ô ºï½ü¤·¤Þ¤·¤¿"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (³ä¹þ¤Þ¤ì¤Þ¤·¤¿)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "¥Ó¡¼¥Ã!"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "¥¨¥é¡¼: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[¥á¥â¥ê(¥Ð¥¤¥È)] Áí³äÅö-²òÊüÎÌ %lu-%lu, »ÈÍÑÎÌ %lu, ¥Ô¡¼¥¯»þ %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[¸Æ½Ð] Áí re/malloc() ²ó¿ô %lu, Áí free() ²ó¿ô %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: ¹Ô¤¬Ä¹¤¯¤Ê¤ê²á¤®¤Þ¤·¤¿"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: ÆâÉô¥¨¥é¡¼: lalloc(%ld,)"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: ¥á¥â¥ê¤¬Â­¤ê¤Þ¤»¤ó! (%lu ¥Ð¥¤¥È¤ò³äÅöÍ×µá)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "¼Â¹Ô¤Î¤¿¤á¤Ë¥·¥§¥ë¤ò¸Æ½Ð¤·Ãæ: \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: ¥³¥í¥ó¤¬¤¢¤ê¤Þ¤»¤ó"
+
+msgid "E546: Illegal mode"
+msgstr "E546: ÉÔÀµ¤Ê¥â¡¼¥É¤Ç¤¹"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: ÉÔÀµ¤Ê 'mouseshape' ¤Ç¤¹"
+
+msgid "E548: digit expected"
+msgstr "E548: ¿ôÃͤ¬É¬ÍפǤ¹"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: ÉÔÀµ¤Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¤Ç¤¹"
+
+msgid "E854: path too long for completion"
+msgstr "E854: ¥Ñ¥¹¤¬Ä¹²á¤®¤ÆÊä´°¤Ç¤­¤Þ¤»¤ó"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: ̵¸ú¤Ê¥Ñ¥¹¤Ç¤¹: '**[¿ôÃÍ]' ¤Ïpath¤ÎºÇ¸å¤« '%s' ¤¬Â³¤¤¤Æ¤Ê¤¤¤È¤¤¤±¤Þ¤»"
+"¤ó."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: cdpath¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: cdpath¤Ë¤Ï¤³¤ì°Ê¾å \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: ¥Ñ¥¹¤Ë¤Ï¤³¤ì°Ê¾å \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: NetBeans¤ÎÀܳ¾ðÊó¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹¥â¡¼¥É¤ËÌäÂ꤬¤¢¤ê¤Þ¤¹: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: ¥Ð¥Ã¥Õ¥¡ %ld ¤Î NetBeans Àܳ¤¬¼º¤ï¤ì¤Þ¤·¤¿"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: NetBeans¤Ï¤³¤ÎGUI¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: NetBeans¤Ï´û¤ËÀܳ¤·¤Æ¤¤¤Þ¤¹"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s ¤ÏÆÉ¹þÀìÍѤǤ¹ (¶¯À©½ñ¹þ¤Ë¤Ï ! ¤òÄɲÃ)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: ¥«¡¼¥½¥ë¤Î°ÌÃ֤ˤϼ±Ê̻Ҥ¬¤¢¤ê¤Þ¤»¤ó"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-#: ../normal.c:2637
+msgid "E775: Eval feature not available"
+msgstr "E775: ¼°É¾²Áµ¡Ç½¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
+
msgid "Warning: terminal cannot highlight"
msgstr "·Ù¹ð: »ÈÍѤ·¤Æ¤¤¤ëüËö¤Ï¥Ï¥¤¥é¥¤¥È¤Ç¤­¤Þ¤»¤ó"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: ¥«¡¼¥½¥ë¤Î°ÌÃ֤ˤÏʸ»úÎ󤬤¢¤ê¤Þ¤»¤ó"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: ¸½ºß¤Î 'foldmethod' ¤Ç¤ÏÀÞ¾ö¤ß¤ò¾Ãµî¤Ç¤­¤Þ¤»¤ó"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: Êѹ¹¥ê¥¹¥È¤¬¶õ¤Ç¤¹"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Êѹ¹¥ê¥¹¥È¤ÎÀèÆ¬"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Êѹ¹¥ê¥¹¥È¤ÎËöÈø"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "Vim¤ò½ªÎ»¤¹¤ë¤Ë¤Ï :quit<Enter> ¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤"
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim"
+msgstr ""
+"¤¹¤Ù¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¡¢Vim¤ò½ªÎ»¤¹¤ë¤Ë¤Ï :qa! ¤ÈÆþÎϤ· <Enter> ¤ò²¡¤·¤Æ¤¯¤À"
+"¤µ¤¤"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 ¹Ô¤¬ %s ¤Ç 1 ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 ¹Ô¤¬ %s ¤Ç %d ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> ¹Ô¤¬ %s ¤Ç 1 ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines %sed 1 time"
+msgstr "%ld ¹Ô¤¬ %s ¤Ç 1 ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> ¹Ô¤¬ %s ¤Ç %d ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines %sed %d times"
+msgstr "%ld ¹Ô¤¬ %s ¤Ç %d ²ó½èÍý¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> ¹Ô¤¬¥¤¥ó¥Ç¥ó¥È¤µ¤ì¤Þ¤¹... "
+msgid "%ld lines to indent... "
+msgstr "%ld ¹Ô¤¬¥¤¥ó¥Ç¥ó¥È¤µ¤ì¤Þ¤¹... "
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 ¹Ô¤ò¥¤¥ó¥Ç¥ó¥È¤·¤Þ¤·¤¿ "
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> ¹Ô¤ò¥¤¥ó¥Ç¥ó¥È¤·¤Þ¤·¤¿ "
+msgid "%ld lines indented "
+msgstr "%ld ¹Ô¤ò¥¤¥ó¥Ç¥ó¥È¤·¤Þ¤·¤¿ "
-#: ../ops.c:938
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
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> ¹Ô¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+msgid "%ld lines changed"
+msgstr "%ld ¹Ô¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "1 ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+#, c-format
+msgid "freeing %ld lines"
+msgstr "%ld ¹Ô¤ò²òÊüÃæ"
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "1 ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+#, c-format
+msgid " into \"%c"
+msgstr " \"%c ¤Ë"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "%<PRId64> ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+msgid "block of 1 line yanked%s"
+msgstr "1 ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬%s¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> ¹Ô¤¬¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+msgid "1 line yanked%s"
+msgstr "1 ¹Ô¤¬%s¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "block of %ld lines yanked%s"
+msgstr "%ld ¹Ô¤Î¥Ö¥í¥Ã¥¯¤¬%s¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "%ld lines yanked%s"
+msgstr "%ld ¹Ô¤¬%s¥ä¥ó¥¯¤µ¤ì¤Þ¤·¤¿"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: ¥ì¥¸¥¹¥¿ %s ¤Ë¤Ï²¿¤â¤¢¤ê¤Þ¤»¤ó"
-#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4495,11 +4183,9 @@ msgstr ""
"\n"
"--- ¥ì¥¸¥¹¥¿ ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "ÉÔÀµ¤Ê¥ì¥¸¥¹¥¿Ì¾"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4507,7 +4193,6 @@ msgstr ""
"\n"
"# ¥ì¥¸¥¹¥¿:\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: ̤ÃΤΥ쥸¥¹¥¿·¿ %d ¤Ç¤¹"
@@ -4517,86 +4202,58 @@ msgid ""
"lines"
msgstr "E883: ¸¡º÷¥Ñ¥¿¡¼¥ó¤È¼°¥ì¥¸¥¹¥¿¤Ë¤Ï2¹Ô°Ê¾å¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó"
-#: ../ops.c:5089
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Îó; "
+msgid "%ld Cols; "
+msgstr "%ld Îó; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"ÁªÂò %s%<PRId64> / %<PRId64> ¹Ô; %<PRId64> / %<PRId64> ñ¸ì; %<PRId64> / "
-"%<PRId64> ¥Ð¥¤¥È"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
+msgstr "ÁªÂò %s%ld / %ld ¹Ô; %lld / %lld ñ¸ì; %lld / %lld ¥Ð¥¤¥È"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"ÁªÂò %s%<PRId64> / %<PRId64> ¹Ô; %<PRId64> / %<PRId64> ñ¸ì; %<PRId64> / "
-"%<PRId64> ʸ»ú; %<PRId64> / %<PRId64> ¥Ð¥¤¥È"
+"ÁªÂò %s%ld / %ld ¹Ô; %lld / %lld ñ¸ì; %lld / %lld ʸ»ú; %lld / %lld ¥Ð¥¤¥È"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Îó %s / %s; ¹Ô %<PRId64> of %<PRId64>; ñ¸ì %<PRId64> / %<PRId64>; ¥Ð¥¤¥È "
-"%<PRId64> / %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "Îó %s / %s; ¹Ô %ld of %ld; ñ¸ì %lld / %lld; ¥Ð¥¤¥È %lld / %lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"Îó %s / %s; ¹Ô %<PRId64> / %<PRId64>; ñ¸ì %<PRId64> / %<PRId64>; ʸ»ú "
-"%<PRId64> / %<PRId64>; ¥Ð¥¤¥È %<PRId64> of %<PRId64>"
+"Îó %s / %s; ¹Ô %ld / %ld; ñ¸ì %lld / %lld; ʸ»ú %lld / %lld; ¥Ð¥¤¥È %lld of "
+"%lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> for BOM)"
+msgid "(+%lld for BOM)"
+msgstr "(+%lld for BOM)"
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=%N ¥Ú¡¼¥¸"
-
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Vim ¤ò»È¤Ã¤Æ¤¯¤ì¤Æ¤¢¤ê¤¬¤È¤¦"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: ̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: ¥ª¥×¥·¥ç¥ó¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: modeline ¤Ç¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: ¥­¡¼¥³¡¼¥É¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../option.c:2924
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>"
@@ -4605,106 +4262,117 @@ msgstr "E539: ÉÔÀµ¤Êʸ»ú¤Ç¤¹ <%s>"
msgid "For option %s"
msgstr "¥ª¥×¥·¥ç¥ó: %s"
-#: ../option.c:3862
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: 'term' ¤Ë¤Ï¶õʸ»úÎó¤òÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: GUI¤Ç¤Ï 'term' ¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: GUI¤ò¥¹¥¿¡¼¥È¤¹¤ë¤Ë¤Ï \":gui\" ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤"
+
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 "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: GTK+2 GUI¤Ç¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+
+#, c-format
+msgid "E950: Cannot convert between %s and %s"
+msgstr "E950: %s ¤È %s ¤Î´Ö¤ÇÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
+
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
+msgid "E596: Invalid font(s)"
+msgstr "E596: ̵¸ú¤Ê¥Õ¥©¥ó¥È¤Ç¤¹"
+
+msgid "E597: can't select fontset"
+msgstr "E597: ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: ̵¸ú¤Ê¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ç¤¹"
+
+msgid "E533: can't select wide font"
+msgstr "E533: ¥ï¥¤¥É¥Õ¥©¥ó¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: ̵¸ú¤Ê¥ï¥¤¥É¥Õ¥©¥ó¥È¤Ç¤¹"
+
#, 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 "E538: No mouse support"
+msgstr "E538: ¥Þ¥¦¥¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó"
+
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
+msgid "E946: Cannot make a terminal with running job modifiable"
+msgstr "E946: ¼Â¹ÔÃæ¤Î¥¸¥ç¥Ö¤¬¤¢¤ëüËö¤ÏÊѹ¹²Äǽ¤Ë¤Ç¤­¤Þ¤»¤ó"
+
msgid "E590: A preview window already exists"
msgstr "E590: ¥×¥ì¥Ó¥å¡¼¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¸ºß¤·¤Þ¤¹"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr ""
-"W17: ¥¢¥é¥Ó¥¢Ê¸»ú¤Ë¤ÏUTF-8¤¬É¬ÍפʤΤÇ, ':set encoding=utf-8' ¤·¤Æ¤¯¤À¤µ¤¤"
+"W17: ¥¢¥é¥Ó¥¢Ê¸»ú¤Ë¤ÏUTF-8¤¬É¬ÍפʤΤǡ¢':set encoding=utf-8' ¤·¤Æ¤¯¤À¤µ¤¤"
+
+msgid "E954: 24-bit colors are not supported on this environment"
+msgstr "E954: 24bit¿§¤Ï¤³¤Î´Ä¶­¤Ç¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: ºÇÄã %d ¤Î¹Ô¿ô¤¬É¬ÍפǤ¹"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: ºÇÄã %d ¤Î¥«¥é¥àÉý¤¬É¬ÍפǤ¹"
-#: ../option.c:6011
#, 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
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: ¿ô»ú¤¬É¬ÍפǤ¹: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4712,7 +4380,6 @@ msgstr ""
"\n"
"--- üËö¥³¡¼¥É ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4720,7 +4387,6 @@ msgstr ""
"\n"
"--- ¥°¥í¡¼¥Ð¥ë¥ª¥×¥·¥ç¥óÃÍ ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4728,7 +4394,6 @@ msgstr ""
"\n"
"--- ¥í¡¼¥«¥ë¥ª¥×¥·¥ç¥óÃÍ ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4736,37 +4401,115 @@ msgstr ""
"\n"
"--- ¥ª¥×¥·¥ç¥ó ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: get_varp ¥¨¥é¡¼"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': %s ¤ËÂбþ¤¹¤ëʸ»ú¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap': ¥»¥ß¥³¥í¥ó¤Î¸å¤Ë;ʬ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó "
+msgid "cannot open "
+msgstr "³«¤±¤Þ¤»¤ó "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: ¥¦¥£¥ó¥É¥¦¤ò³«¤±¤Þ¤»¤ó!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Amigados¤Î¥Ð¡¼¥¸¥ç¥ó 2.04¤«¤½¤ì°Ê¹ß¤¬É¬ÍפǤ¹\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "%s ¤Î¥Ð¡¼¥¸¥ç¥ó %ld ¤¬É¬ÍפǤ¹\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "NIL¤ò³«¤±¤Þ¤»¤ó:\n"
+
+msgid "Cannot create "
+msgstr "ºîÀ®¤Ç¤­¤Þ¤»¤ó "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim¤Ï %d ¤Ç½ªÎ»¤·¤Þ¤¹\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: ¥³¥ó¥½¡¼¥ë¤Ç¤Ï¤Ê¤¤??\n"
+
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: -f ¥ª¥×¥·¥ç¥ó¤Ç¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó"
+
+msgid "Cannot execute "
+msgstr "¼Â¹Ô¤Ç¤­¤Þ¤»¤ó "
+
+msgid "shell "
+msgstr "¥·¥§¥ë "
+
+msgid " returned\n"
+msgstr " Ìá¤ê¤Þ¤·¤¿\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE ¤¬¾®¤µ²á¤®¤Þ¤¹."
+
+msgid "I/O ERROR"
+msgstr "Æþ½ÐÎÏ¥¨¥é¡¼"
+
+msgid "Message"
+msgstr "¥á¥Ã¥»¡¼¥¸"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: ¥×¥ê¥ó¥¿¤ÎÁªÂò¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "%s ¤Ø (%s ¾å¤Î)"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: ̤ÃΤΥץê¥ó¥¿¥ª¥×¥·¥ç¥ó¤Ç¤¹: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: °õºþ¥¨¥é¡¼: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "°õºþ¤·¤Æ¤¤¤Þ¤¹: '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: ʸ»ú¥»¥Ã¥È̾ \"%s\" ¤ÏÉÔÀµ¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: ÉʼÁ̾ \"%s\" ¤ÏÉÔÀµ¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: '%c' ¤ÏÉÔÀµ¤Êʸ»ú¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "X¥µ¡¼¥Ð¡¼¤Ø¤ÎÀܳ¤Ë %ld ¥ß¥êÉ䫤«¤ê¤Þ¤·¤¿"
-#: ../os/shell.c:439
msgid ""
"\n"
-"shell returned "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"¥·¥§¥ë¤¬ÃͤòÊÖ¤·¤Þ¤·¤¿ "
+"Vim: X ¤Î¥¨¥é¡¼¤ò¸¡½Ð¤·¤Þ¤·¤¿r\n"
+
+msgid "Testing the X display failed"
+msgstr "X display ¤Î¥Á¥§¥Ã¥¯¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "Opening the X display timed out"
+msgstr "X display ¤Î open ¤¬¥¿¥¤¥à¥¢¥¦¥È¤·¤Þ¤·¤¿"
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
"Could not get security context for "
@@ -4774,7 +4517,6 @@ msgstr ""
"\n"
"¥»¥­¥å¥ê¥Æ¥£¥³¥ó¥Æ¥­¥¹¥È¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4790,223 +4532,289 @@ msgstr "¥»¥­¥å¥ê¥Æ¥£¥³¥ó¥Æ¥­¥¹¥È %s ¤ò %s ¤ËÀßÄê¤Ç¤­¤Þ¤»¤ó"
msgid "Could not get security context %s for %s. Removing it!"
msgstr "¥»¥­¥å¥ê¥Æ¥£¥³¥ó¥Æ¥­¥¹¥È %s ¤ò %s ¤«¤é¼èÆÀ¤Ç¤­¤Þ¤»¤ó. ºï½ü¤·¤Þ¤¹!"
-#: ../os_unix.c:1558 ../os_unix.c:1647
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"sh ¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"¥·¥§¥ë¤¬ÃͤòÊÖ¤·¤Þ¤·¤¿ "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"¥Ñ¥¤¥×¤òºîÀ®¤Ç¤­¤Þ¤»¤ó\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"fork ¤Ç¤­¤Þ¤»¤ó\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"¥³¥Þ¥ó¥É¤òÃæÃǤ·¤Þ¤·¤¿\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP ¤¬ICEÀܳ¤ò¼º¤¤¤Þ¤·¤¿"
+
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "X display ¤Î open ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP ¤¬save-yourselfÍ×µá¤ò½èÍý¤·¤Æ¤¤¤Þ¤¹"
+
+msgid "XSMP opening connection"
+msgstr "XSMP ¤¬Àܳ¤ò³«»Ï¤·¤Æ¤¤¤Þ¤¹"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICEÀܳ¤¬¼ºÇÔ¤·¤¿¤è¤¦¤Ç¤¹"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection¤¬¼ºÇÔ¤·¤Þ¤·¤¿: %s"
+
+msgid "At line"
+msgstr "¹Ô"
+
+msgid "Could not load vim32.dll!"
+msgstr "vim32.dll ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+
+msgid "VIM Error"
+msgstr "VIM¥¨¥é¡¼"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "DLL¤«¤é´Ø¿ô¥Ý¥¤¥ó¥¿¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: ¥¤¥Ù¥ó¥È %s ¤ò¸¡ÃÎ\n"
+
+msgid "close"
+msgstr "ÊĤ¸¤ë"
+
+msgid "logoff"
+msgstr "¥í¥°¥ª¥Õ"
+
+msgid "shutdown"
+msgstr "¥·¥ã¥Ã¥È¥À¥¦¥ó"
+
+msgid "E371: Command not found"
+msgstr "E371: ¥³¥Þ¥ó¥É¤¬¤¢¤ê¤Þ¤»¤ó"
+
+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 ""
+"VIMRUN.EXE¤¬ $PATH ¤ÎÃæ¤Ë¸«¤Ä¤«¤ê¤Þ¤»¤ó.\n"
+"³°Éô¥³¥Þ¥ó¥É¤Î½ªÎ»¸å¤Ë°ì»þÄä»ß¤ò¤·¤Þ¤»¤ó.\n"
+"¾ÜºÙ¤Ï :help win32-vimrun ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤."
+
+msgid "Vim Warning"
+msgstr "Vim¤Î·Ù¹ð"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "¥·¥§¥ë¤¬¥³¡¼¥É %d ¤Ç½ªÎ»¤·¤Þ¤·¤¿"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: ¸½ºß¤Î¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë %%%c ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ëͽ´ü¤»¤Ì %%%c ¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ç¤Ï %%%c ¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤ÎÁ°ÃÖ¤Ë̵¸ú¤Ê %%%c ¤¬¤¢¤ê¤Þ¤¹"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: ¥Õ¥©¡¼¥Þ¥Ã¥Èʸ»úÎó¤Ë̵¸ú¤Ê %%%c ¤¬¤¢¤ê¤Þ¤¹"
-#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' ¤Ë¥Ñ¥¿¡¼¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: ¥Ç¥£¥ì¥¯¥È¥ê̾¤¬Ìµ¤¤¤«¶õ¤Ç¤¹"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Í×ÁǤ¬¤â¤¦¤¢¤ê¤Þ¤»¤ó"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: ¸½ºß¤Î¥¦¥£¥ó¥É¥¦¤¬ÊĤ¸¤é¤ì¤Þ¤·¤¿"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: ¸½ºß¤Î quickfix ¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d of %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (¹Ô¤¬ºï½ü¤µ¤ì¤Þ¤·¤¿)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%s ¥¨¥é¡¼°ìÍ÷ %d of %d; %d ¸Ä¥¨¥é¡¼"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: quickfix ¥¹¥¿¥Ã¥¯¤ÎËöÈø¤Ç¤¹"
-#: ../quickfix.c:1869
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 of %d; %d ¸Ä¥¨¥é¡¼"
+msgid "No entries"
+msgstr "¥¨¥ó¥È¥ê¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: 'buftype' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç½ñ¹þ¤ß¤Þ¤»¤ó"
+msgid "Error file"
+msgstr "¥¨¥é¡¼¥Õ¥¡¥¤¥ë"
-#: ../quickfix.c:2812
msgid "E683: File name missing or invalid pattern"
msgstr "E683: ¥Õ¥¡¥¤¥ë̾¤¬Ìµ¤¤¤«Ìµ¸ú¤Ê¥Ñ¥¿¡¼¥ó¤Ç¤¹"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: ¥Ð¥Ã¥Õ¥¡¤ÏÆÉ¤ß¹þ¤Þ¤ì¤Þ¤»¤ó¤Ç¤·¤¿"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: ʸ»úÎ󤫥ꥹ¥È¤¬É¬ÍפǤ¹"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: ̵¸ú¤Ê¹àÌܤǤ¹: %s%%[]"
-#
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: %s[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../regexp.c:375
+msgid "E944: Reverse range in character class"
+msgstr "E944: ʸ»ú¥¯¥é¥¹¤ÎÈϰϤ¬µÕ¤Ç¤¹"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: ʸ»ú¥¯¥é¥¹¤ÎÈϰϤ¬Â礭¤¹¤®¤Þ¤¹"
+
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: %s%%( ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó"
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: %s( ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó"
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: %s) ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó"
-#
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: \\z( ¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 ¤½¤Î¾¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "E67: \\z1 - \\z9 not allowed here"
+msgstr "E67: \\z1 - \\z9 ¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: %s%%[ ¤Î¸å¤Ë ] ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] ¤¬¶õ¤Ç¤¹"
-#: ../regexp.c:1209 ../regexp.c:1224
+msgid "E956: Cannot use pattern recursively"
+msgstr "E956: ¥Ñ¥¿¡¼¥ó¤òºÆµ¢Åª¤Ë»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: ÉÔÀµ¤Ê¸åÊý»²¾È¤Ç¤¹"
+
msgid "E339: Pattern too long"
msgstr "E339: ¥Ñ¥¿¡¼¥ó¤¬Ä¹²á¤®¤Þ¤¹"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: \\z( ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: %s( ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: \\z( ¤¬Äà¤ê¹ç¤Ã¤Æ¤¤¤Þ¤»¤ó"
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: %s@ ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Ê£»¨¤Ê %s{...} ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61:%s* ¤¬Æþ¤ì»Ò¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62:%s%c ¤¬Æþ¤ì»Ò¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
-#
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: \\_ ¤Î̵¸ú¤Ê»ÈÍÑÊýË¡¤Ç¤¹"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64:%s%c ¤Î¸å¤Ë¤Ê¤Ë¤â¤¢¤ê¤Þ¤»¤ó"
-#
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: ÉÔÀµ¤Ê¸åÊý»²¾È¤Ç¤¹"
-
-#
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: \\z ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿"
-#
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: %s%%[dxouU] ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿"
-#
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: %s%% ¤Î¸å¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤·¤¿"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: %s{...} Æâ¤Ëʸˡ¥¨¥é¡¼¤¬¤¢¤ê¤Þ¤¹"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "³°Éô¤ÎÉôʬ³ºÅö:\n"
@@ -5014,7 +4822,6 @@ msgstr "³°Éô¤ÎÉôʬ³ºÅö:\n"
msgid "E888: (NFA regexp) cannot repeat %s"
msgstr "E888: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤»¤Þ¤»¤ó %s"
-#: ../regexp.c:7022
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5025,62 +4832,58 @@ msgstr ""
msgid "Switching to backtracking RE engine for pattern: "
msgstr "¼¡¤Î¥Ñ¥¿¡¼¥ó¤Ë¥Ð¥Ã¥¯¥È¥é¥Ã¥­¥ó¥° RE ¥¨¥ó¥¸¥ó¤òŬÍѤ·¤Þ¤¹: "
-#: ../regexp_nfa.c:239
msgid "E865: (NFA) Regexp end encountered prematurely"
msgstr "E865: (NFA) ´üÂÔ¤è¤êÁ᤯Àµµ¬É½¸½¤Î½ªÃ¼¤ËÅþ㤷¤Þ¤·¤¿"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
msgstr "E866: (NFA Àµµ¬É½¸½) °ÌÃÖ¤¬¸í¤Ã¤Æ¤¤¤Þ¤¹: %c"
-#: ../regexp_nfa.c:242
#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (NFA Àµµ¬É½¸½) ̵¸ú¤Êʸ»ú¥¯¥é¥¹: %<PRId64>"
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (NFA Àµµ¬É½¸½) ̵¸ú¤Êʸ»ú¥¯¥é¥¹: %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
msgstr "E867: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\z%c'"
-#: ../regexp_nfa.c:1387
+msgid "E951: \\% value too large"
+msgstr "E951: \\% Ãͤ¬Ä¹²á¤®¤Þ¤¹"
+
#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
msgstr "E867: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\%%%c'"
-#: ../regexp_nfa.c:1802
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Åù²Á¥¯¥é¥¹¤ò´Þ¤àNFA¹½Ãۤ˼ºÇÔ¤·¤Þ¤·¤¿!"
+
#, c-format
msgid "E869: (NFA) Unknown operator '\\@%c'"
msgstr "E869: (NFA) ̤ÃΤΥª¥Ú¥ì¡¼¥¿¤Ç¤¹: '\\@%c'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
msgstr "E870: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤·¤ÎÀ©¸Â²ó¿ô¤òÆÉ¹þÃæ¤Ë¥¨¥é¡¼"
-#. 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 Àµµ¬É½¸½) ·«¤êÊÖ¤· ¤Î¸å¤Ë ·«¤êÊÖ¤· ¤Ï¤Ç¤­¤Þ¤»¤ó!"
+msgid "E871: (NFA regexp) Can't have a multi follow a multi"
+msgstr "E871: (NFA Àµµ¬É½¸½) ·«¤êÊÖ¤· ¤Î¸å¤Ë ·«¤êÊÖ¤· ¤Ï¤Ç¤­¤Þ¤»¤ó"
-#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
msgstr "E872: (NFA Àµµ¬É½¸½) '(' ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp_nfa.c:2042
msgid "E879: (NFA regexp) Too many \\z("
msgstr "E879: (NFA Àµµ¬É½¸½) \\z( ¤¬Â¿²á¤®¤Þ¤¹"
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
msgstr "E873: (NFA Àµµ¬É½¸½) ½ªÃ¼µ­¹æ¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
+msgid "Could not open temporary log file for writing, displaying on stderr... "
+msgstr ""
+"NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£¥í¥°¤Ïɸ½à¥¨¥é¡¼"
+"½ÐÎϤ˽ÐÎϤ·¤Þ¤¹¡£"
+
+msgid "E874: (NFA) Could not pop the stack!"
msgstr "E874: (NFA) ¥¹¥¿¥Ã¥¯¤ò¥Ý¥Ã¥×¤Ç¤­¤Þ¤»¤ó!"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
@@ -5088,177 +4891,122 @@ msgstr ""
"E875: (NFA Àµµ¬É½¸½) (¸åÃÖʸ»úÎó¤òNFA¤ËÊÑ´¹Ãæ¤Ë) ¥¹¥¿¥Ã¥¯¤Ë»Ä¤µ¤ì¤¿¥¹¥Æ¡¼¥È¤¬"
"¿²á¤®¤Þ¤¹"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
msgstr "E876: (NFA Àµµ¬É½¸½) NFAÁ´ÂΤòÊݸ¤¹¤ë¤Ë¤Ï¶õ¤­¥¹¥Ú¡¼¥¹¤¬Â­¤ê¤Þ¤»¤ó"
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£¥í¥°¤Ïɸ½à½ÐÎϤË"
-"½ÐÎϤ·¤Þ¤¹¡£"
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) ¥í¥°¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó!"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "NFAÀµµ¬É½¸½¥¨¥ó¥¸¥óÍÑ¤Î¥í¥°¥Õ¥¡¥¤¥ë¤ò½ñ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó¡£"
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (NFA) ¸½ºß²£ÃÇÃæ¤Î¥Ö¥é¥ó¥Á¤Ë½½Ê¬¤Ê¥á¥â¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó!"
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " ²¾ÁÛÃÖ´¹"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ÃÖ´¹"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " ȿž"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " ÁÞÆþ"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (ÁÞÆþ)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (ÃÖ´¹)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (²¾ÁÛÃÖ´¹)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " ¥Ø¥Ö¥é¥¤"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " ¥¢¥é¥Ó¥¢"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (¸À¸ì)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (ޤêÉÕ¤±)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " ¥Ó¥¸¥å¥¢¥ë"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " ¥Ó¥¸¥å¥¢¥ë ¹Ô"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " ¥Ó¥¸¥å¥¢¥ë ¶ë·Á"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " ¥»¥ì¥¯¥È"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " ¹Ô»Ø¸þÁªÂò"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " ¶ë·ÁÁªÂò"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "µ­Ï¿Ãæ"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: ̵¸ú¤Ê¸¡º÷ʸ»úÎó¤Ç¤¹: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: ¾å¤Þ¤Ç¸¡º÷¤·¤Þ¤·¤¿¤¬³ºÅö²Õ½ê¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: ²¼¤Þ¤Ç¸¡º÷¤·¤Þ¤·¤¿¤¬³ºÅö²Õ½ê¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: ';' ¤Î¤¢¤È¤Ë¤Ï '?' ¤« '/' ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (Á°¤ËÎóµó¤·¤¿³ºÅö²Õ½ê¤ò´Þ¤à)"
-#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- ¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë "
-#: ../search.c:4106
msgid "not found "
msgstr "¸«¤Ä¤«¤ê¤Þ¤»¤ó "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "¥Ñ¥¹¤Ë ----\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (´û¤ËÎóµó)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " ¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¥¹¥­¥ã¥óÃæ: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
-msgstr "¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¥¹¥­¥ã¥óÃæ %s"
+msgstr "¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¸¡º÷Ãæ %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: ¸½ºß¹Ô¤Ë³ºÅö¤¬¤¢¤ê¤Þ¤¹"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Á´¤Æ¤Î¥¤¥ó¥¯¥ë¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿"
-#: ../search.c:4519
msgid "No included files"
msgstr "¥¤¥ó¥¯¥ë¡¼¥É¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: ÄêµÁ¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: ¥Ñ¥¿¡¼¥ó¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../search.c:4668
msgid "Substitute "
msgstr "Substitute "
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5269,99 +5017,129 @@ msgstr ""
"# ºÇ¸å¤Î %s¸¡º÷¥Ñ¥¿¡¼¥ó:\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Î½ñ¼°¥¨¥é¡¼¤Ç¤¹"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: ¥¹¥Ú¥ë¥Á¥§¥Ã¥¯¤Ï̵¸ú²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr ""
+"·Ù¹ð: ñ¸ì¥ê¥¹¥È \"%s_%s.spl\" ¤ª¤è¤Ó \"%s_ascii.spl\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr ""
+"·Ù¹ð: ñ¸ì¥ê¥¹¥È \"%s.%s.spl\" ¤ª¤è¤Ó \"%s.ascii.spl\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: autocommand ¤Î SpellFileMissing ¤¬¥Ð¥Ã¥Õ¥¡¤òºï½ü¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "·Ù¹ð9: %s ¤È¤¤¤¦ÈϰϤϥµ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+msgid "Sorry, no suggestions"
+msgstr "»Äǰ¤Ç¤¹¤¬¡¢½¤Àµ¸õÊä¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "»Äǰ¤Ç¤¹¤¬¡¢½¤Àµ¸õÊä¤Ï %ld ¸Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "\"%.*s\" ¤ò¼¡¤ØÊÑ´¹:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: ¥¹¥Ú¥ëÃÖ´¹¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: ¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤¬ÀÚ¼è¤é¤ì¤Æ¤¤¤ë¤è¤¦¤Ç¤¹"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "%s (%d ¹ÔÌÜ) ¤Ë³¤¯¥Æ¥­¥¹¥È: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "%s (%d ¹ÔÌÜ) ¤Î affix ̾¤¬Ä¹²á¤®¤Þ¤¹: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr ""
"E761: affix¥Õ¥¡¥¤¥ë¤Î 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
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\" ¤ª¤è¤Ó \"%s.ascii.spl\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë \"%s\" ¤òÆÉ¹þÃæ"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: ¸Å¤¤¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç, ¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤"
+msgstr "E771: ¸Å¤¤¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç¡¢¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: ¤è¤ê¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤Î Vim ÍѤΥ¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ç¤¹"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: ¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤Ë¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¥»¥¯¥·¥ç¥ó¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "·Ù¹ð9: %s ¤È¤¤¤¦ÈϰϤϥµ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: .sug ¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹: %s"
-#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: ¸Å¤¤ .sug ¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç¡¢¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: ¤è¤ê¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤Î Vim ÍѤΠ.sug ¥Õ¥¡¥¤¥ë¤Ç¤¹: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug ¥Õ¥¡¥¤¥ë¤¬ .spl ¥Õ¥¡¥¤¥ë¤È°ìÃפ·¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: .sug ¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "Reading affix file %s..."
msgstr "affix ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þÃæ..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "%s (%d ¹ÔÌÜ) ¤Îñ¸ì¤òÊÑ´¹¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "%s Æâ¤Î¼¡¤ÎÊÑ´¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó: %s ¤«¤é %s ¤Ø"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "%s Æâ¤ÎÊÑ´¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "%s Æâ¤Î %d ¹ÔÌܤΠFLAG ¤Ë̵¸ú¤ÊÃͤ¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "%s Æâ¤Î %d ¹ÔÌܤ˥ե饰¤ÎÆó½Å»ÈÍѤ¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5370,7 +5148,6 @@ msgstr ""
"%s ¤Î %d ¹ÔÌܤΠPFX ¹àÌܤθå¤Î COMPOUNDFORBIDFLAG ¤ÎÄêµÁ¤Ï¸í¤Ã¤¿·ë²Ì¤òÀ¸¤¸¤ë"
"¤³¤È¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5379,43 +5156,35 @@ msgstr ""
"%s ¤Î %d ¹ÔÌܤΠPFX ¹àÌܤθå¤Î COMPOUNDPERMITFLAG ¤ÎÄêµÁ¤Ï¸í¤Ã¤¿·ë²Ì¤òÀ¸¤¸¤ë"
"¤³¤È¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "COMPOUNDRULES ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹. ¥Õ¥¡¥¤¥ë %s ¤Î %d ¹ÔÌÜ: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDWORDMAX ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDMIN ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠCOMPOUNDSYLMAX ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠCHECKCOMPOUNDPATTERN ¤ÎÃͤ˸í¤ê¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
"%s ¤Î %d ¹ÔÌܤΠϢ³ affix ¥Ö¥í¥Ã¥¯¤Î¥Õ¥é¥°¤ÎÁȹ礻¤Ë°ã¤¤¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë ½ÅÊ£¤·¤¿ affix ¤ò¸¡½Ð¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5424,337 +5193,245 @@ msgstr ""
"%s ¤Î %d ¹ÔÌܤΠaffix ¤Ï BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
"¤Ë»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ç¤Ï Y ¤« N ¤¬É¬ÍפǤ¹: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ¾ò·ï¤Ï²õ¤ì¤Æ¤¤¤Þ¤¹: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë¤Ï REP(SAL) ¤Î²ó¿ô¤¬É¬ÍפǤ¹"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ë¤Ï MAP ¤Î²ó¿ô¤¬É¬ÍפǤ¹"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "%s ¤Î %d ¹ÔÌܤΠMAP ¤Ë½ÅÊ£¤·¤¿Ê¸»ú¤¬¤¢¤ê¤Þ¤¹"
-#: ../spell.c:5176
#, 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
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "SYLLABLE ¤¬»ØÄꤵ¤ì¤Ê¤¤ COMPOUNDSYLMAX"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "ÃÙ±ä¸åÃÖ»Ò¤¬Â¿²á¤®¤Þ¤¹"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Ê£¹ç¥Õ¥é¥°¤¬Â¿²á¤®¤Þ¤¹"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "ÃÙ±ä¸åÃÖ»Ò ¤È/¤â¤·¤¯¤Ï Ê£¹ç¥Õ¥é¥°¤¬Â¿²á¤®¤Þ¤¹"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "SOFO%s ¹Ô¤¬ %s ¤Ë¤¢¤ê¤Þ¤»¤ó"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "SAL¹Ô ¤È SOFO¹Ô ¤¬ %s ¤ÇξÊý»ØÄꤵ¤ì¤Æ¤¤¤Þ¤¹"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "%s ¤Î %d ¹Ô¤Î ¥Õ¥é¥°¤¬¿ôÃͤǤϤ¢¤ê¤Þ¤»¤ó: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ¥Õ¥é¥°¤¬ÉÔÀµ¤Ç¤¹: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "ÃÍ %s ¤Ï¾¤Î .aff ¥Õ¥¡¥¤¥ë¤Ç»ÈÍѤµ¤ì¤¿¤Î¤È°Û¤Ê¤ê¤Þ¤¹"
-#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "¼­½ñ¥Õ¥¡¥¤¥ë %s ¤ò¥¹¥­¥ã¥óÃæ..."
+msgid "Reading dictionary file %s..."
+msgstr "¼­½ñ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤ßÃæ..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: %s ¤Ë¤Ïñ¸ì¿ô¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../spell.c:5669
#, 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
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ¤Ç ½Åʣñ¸ì¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "½ÅÊ£¤Î¤¦¤ÁºÇ½é¤Îñ¸ì¤Ï %s ¤Î %d ¹ÔÌܤǤ¹: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d ¸Ä¤Îñ¸ì¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿ (%s Æâ)"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "ÈóASCIIʸ»ú¤ò´Þ¤à %d ¸Ä¤Îñ¸ì¤ò̵»ë¤·¤Þ¤·¤¿ (%s Æâ)"
-#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ %s ..."
+msgid "Reading word file %s..."
+msgstr "ñ¸ì¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤ßÃæ..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ /encoding= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠñ¸ì¤Î¸å¤Î /encoding= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ /regions= ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
-msgstr "%s ¤Î %d ¹ÔÌÜ, ÈϰϻØÄ꤬¿²á¤®¤Þ¤¹: %s"
+msgstr "%s ¤Î %d ¹ÔÌÜ¡¢ÈϰϻØÄ꤬¿²á¤®¤Þ¤¹: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌܤΠ½ÅÊ£¤·¤¿ / ¹Ô¤ò̵»ë¤·¤Þ¤·¤¿: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ Ìµ¸ú¤Ê nr Îΰè¤Ç¤¹: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "%s ¤Î %d ¹ÔÌÜ Ç§¼±ÉÔǽ¤Ê¥Õ¥é¥°¤Ç¤¹: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "ÈóASCIIʸ»ú¤ò´Þ¤à %d ¸Ä¤Îñ¸ì¤ò̵»ë¤·¤Þ¤·¤¿"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: ¥á¥â¥ê¤¬Â­¤ê¤Ê¤¤¤Î¤Ç¡¢Ã±¸ì¥ê¥¹¥È¤ÏÉÔ´°Á´¤Ç¤¹"
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "¥Î¡¼¥É %d ¸Ä(Á´ %d ¸ÄÃæ) ¤ò°µ½Ì¤·¤Þ¤·¤¿; »Ä¤ê %d (%d%%)"
-#: ../spell.c:7340
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
msgid "Performing soundfolding..."
msgstr "²»À¼¾ö¹þ¤ß¤ò¼Â¹ÔÃæ..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "²»À¼¾ö¹þ¤ß¸å¤ÎÁíñ¸ì¿ô: %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "²»À¼¾ö¹þ¤ß¸å¤ÎÁíñ¸ì¿ô: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Áíñ¸ì¿ô: %d"
-#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
+msgid "Writing suggestion file %s..."
msgstr "½¤Àµ¸õÊä¥Õ¥¡¥¤¥ë \"%s\" ¤ò½ñ¹þ¤ßÃæ..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "¿äÄê¥á¥â¥ê»ÈÍÑÎÌ: %d ¥Ð¥¤¥È"
-#: ../spell.c:7820
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 ¸Ä¤Þ¤Ç¤·¤«¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+#, c-format
+msgid "E754: Only up to %ld regions supported"
+msgstr "E754: ÈÏ°Ï¤Ï %ld ¸Ä¤Þ¤Ç¤·¤«¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: ̵¸ú¤ÊÈϰϤǤ¹: %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "·Ù¹ð: Ê£¹ç¥Õ¥é¥°¤È NOBREAK ¤¬Î¾Êý¤È¤â»ØÄꤵ¤ì¤Þ¤·¤¿"
-#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
+msgid "Writing spell file %s..."
msgstr "¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë %s ¤ò½ñ¹þ¤ßÃæ..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "¼Â¹Ô¤·¤Þ¤·¤¿!"
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ¤Ë¤Ï %<PRId64> ¸Ä¤Î¥¨¥ó¥È¥ê¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' ¤Ë¤Ï %ld ¸Ä¤Î¥¨¥ó¥È¥ê¤Ï¤¢¤ê¤Þ¤»¤ó"
-#: ../spell.c:8074
#, c-format
msgid "Word '%.*s' removed from %s"
msgstr "ñ¸ì '%.*s' ¤¬ %s ¤«¤éºï½ü¤µ¤ì¤Þ¤·¤¿"
-#: ../spell.c:8117
#, c-format
msgid "Word '%.*s' added to %s"
msgstr "ñ¸ì '%.*s' ¤¬ %s ¤ØÄɲ䵤ì¤Þ¤·¤¿"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: ñ¸ì¤Îʸ»ú¤¬¥¹¥Ú¥ë¥Õ¥¡¥¤¥ë¤È°Û¤Ê¤ê¤Þ¤¹"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï¤¢¤ê¤Þ¤»¤ó"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "»Äǰ¤Ç¤¹¤¬, ½¤Àµ¸õÊä¤Ï %<PRId64> ¸Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "\"%.*s\" ¤ò¼¡¤ØÊÑ´¹:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: ¥¹¥Ú¥ëÃÖ´¹¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: MAP ¥¨¥ó¥È¥ê¤Ë½Åʣʸ»ú¤¬Â¸ºß¤·¤Þ¤¹"
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: ¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
+msgid "No Syntax items defined for this buffer"
+msgstr "¤³¤Î¥Ð¥Ã¥Õ¥¡¤ËÄêµÁ¤µ¤ì¤¿¹½Ê¸Í×ÁǤϤ¢¤ê¤Þ¤»¤ó"
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: .sug ¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤è¤¦¤Ç¤¹: %s"
+msgid "syntax conceal on"
+msgstr "¹½Ê¸¤Î conceal ¤Ï¸½ºß on ¤Ç¤¹"
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: ¸Å¤¤ .sug ¥Õ¥¡¥¤¥ë¤Ê¤Î¤Ç, ¥¢¥Ã¥×¥Ç¡¼¥È¤·¤Æ¤¯¤À¤µ¤¤: %s"
+msgid "syntax conceal off"
+msgstr "¹½Ê¸¤Î conceal ¤Ï¸½ºß off ¤Ç¤¹"
-#: ../spell.c:9286
#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: ¤è¤ê¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó¤Î Vim ÍѤΠ.sug ¥Õ¥¡¥¤¥ë¤Ç¤¹: %s"
+msgid "E390: Illegal argument: %s"
+msgstr "E390: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: .sug ¥Õ¥¡¥¤¥ë¤¬ .spl ¥Õ¥¡¥¤¥ë¤È°ìÃפ·¤Þ¤»¤ó: %s"
+msgid "syntax case ignore"
+msgstr "¹½Ê¸¤ÎÂçʸ»ú¾®Ê¸»ú¤Ï¸½ºß ignore ¤Ç¤¹"
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: .sug ¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿: %s"
+msgid "syntax case match"
+msgstr "¹½Ê¸¤ÎÂçʸ»ú¾®Ê¸»ú¤Ï¸½ºß match ¤Ç¤¹"
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: MAP ¥¨¥ó¥È¥ê¤Ë½Åʣʸ»ú¤¬Â¸ºß¤·¤Þ¤¹"
+msgid "syntax spell toplevel"
+msgstr "¹½Ê¸¤Î spell ¤Ï¸½ºß toplevel ¤Ç¤¹"
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "¤³¤Î¥Ð¥Ã¥Õ¥¡¤ËÄêµÁ¤µ¤ì¤¿¹½Ê¸Í×ÁǤϤ¢¤ê¤Þ¤»¤ó"
+msgid "syntax spell notoplevel"
+msgstr "¹½Ê¸¤Î spell ¤Ï¸½ºß notoplevel ¤Ç¤¹"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
+msgid "syntax spell default"
+msgstr "¹½Ê¸¤Î spell ¤Ï¸½ºß default ¤Ç¤¹"
msgid "syntax iskeyword "
-msgstr "¥·¥ó¥¿¥Ã¥¯¥¹ÍÑ iskeyword "
+msgstr "¹½Ê¸ÍÑ iskeyword "
-#: ../syntax.c:3299
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: ¤½¤Î¤è¤¦¤Ê¹½Ê¸¥¯¥é¥¹¥¿¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "C¸À¸ìÉ÷¥³¥á¥ó¥È¤«¤éƱ´üÃæ"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "È󯱴ü"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "Ʊ´ü³«»Ï "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " ¹ÔÁ°(¥È¥Ã¥×¹Ô¤è¤ê¤â)"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5762,7 +5439,6 @@ msgstr ""
"\n"
"--- ¹½Ê¸Æ±´üÍ×ÁÇ ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5770,7 +5446,6 @@ msgstr ""
"\n"
"Í×ÁǾå¤ÇƱ´üÃæ"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5778,53 +5453,41 @@ msgstr ""
"\n"
"--- ¹½Ê¸Í×ÁÇ ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: ¤½¤Î¤è¤¦¤Ê¹½Ê¸¥¯¥é¥¹¥¿¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimal "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maximal "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; ³ºÅö "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " ¸Ä¤Î²þ¹Ô"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: ¤³¤Î¾ì½ê¤Ç¤Ï°ú¿ôcontains¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: ̵¸ú¤Êcchar¤ÎÃͤǤ¹"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: ¤³¤³¤Ç¤Ï¥°¥ë¡¼¥×¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: %s ¤ÎÈϰÏÍ×ÁǤ¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: ¥Õ¥¡¥¤¥ë̾¤¬É¬ÍפǤ¹"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: ¹½Ê¸¤Î¼è¤ê¹þ¤ß(include)¤¬Â¿²á¤®¤Þ¤¹"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
@@ -5833,221 +5496,171 @@ msgstr "E789: ']' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
msgid "E890: trailing char after ']': %s]%s"
msgstr "E890: ']' ¤Î¸å¤í¤Ë;ʬ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹: %s]%s"
-#: ../syntax.c:4531
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: '=' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: °ú¿ô¤¬Â­¤ê¤Þ¤»¤ó: ¹½Ê¸ÈÏ°Ï %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: ¹½Ê¸¥¯¥é¥¹¥¿¤¬Â¿²á¤®¤Þ¤¹"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: ¥¯¥é¥¹¥¿¤¬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: ¥Ñ¥¿¡¼¥ó¶èÀڤ꤬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: ¥Ñ¥¿¡¼¥ó¤Î¤¢¤È¤Ë¥´¥ß¤¬¤¢¤ê¤Þ¤¹: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: ¹½Ê¸Æ±´ü: Ϣ³¹Ô¥Ñ¥¿¡¼¥ó¤¬2ÅÙ»ØÄꤵ¤ì¤Þ¤·¤¿"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: Åù¹æ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: ¶õ¤Î°ú¿ô: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s ¤Ï¥³¥³¤Ç¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s ¤ÏÆâÍÆ¥ê¥¹¥È¤ÎÀèÆ¬¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: ̤ÃΤΥ°¥ë¡¼¥×̾: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: ̵¸ú¤Ê :syntax ¤Î¥µ¥Ö¥³¥Þ¥ó¥É: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-#: ../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: ¥Ï¥¤¥é¥¤¥È¥°¥ë¡¼¥×¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %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: ¥°¥ë¡¼¥×¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç¥Ï¥¤¥é¥¤¥È¥ê¥ó¥¯¤Ï̵»ë¤µ¤ì¤Þ¤¹"
-#: ../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: ¥°¥ë¡¼¥×̾¤Ë°õºþÉÔ²Äǽ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: ¥°¥ë¡¼¥×̾¤ËÉÔÀµ¤Êʸ»ú¤¬¤¢¤ê¤Þ¤¹"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: ¥Ï¥¤¥é¥¤¥È¤È¹½Ê¸¥°¥ë¡¼¥×¤¬Â¿²á¤®¤Þ¤¹"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: ¥¿¥°¥¹¥¿¥Ã¥¯¤ÎËöÈø¤Ç¤¹"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: ¥¿¥°¥¹¥¿¥Ã¥¯¤ÎÀèÆ¬¤Ç¤¹"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
-msgstr "E425: ºÇ½é¤Î³ºÅö¥¿¥°¤òͤ¨¤ÆÌá¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+msgstr "E425: ºÇ½é¤Î³ºÅö¥¿¥°¤ò±Û¤¨¤ÆÌá¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: ¥¿¥°¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # pri kind tag"
-#: ../tag.c:531
msgid "file\n"
msgstr "¥Õ¥¡¥¤¥ë\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: ³ºÅö¥¿¥°¤¬1¤Ä¤À¤±¤·¤«¤¢¤ê¤Þ¤»¤ó"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: ºÇ¸å¤Ë³ºÅö¤¹¤ë¥¿¥°¤òͤ¨¤Æ¿Ê¤à¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
+msgstr "E428: ºÇ¸å¤Î³ºÅö¥¿¥°¤ò±Û¤¨¤Æ¿Ê¤à¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "¥Õ¥¡¥¤¥ë \"%s\" ¤¬¤¢¤ê¤Þ¤»¤ó"
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "¥¿¥° %d (Á´%d%s)"
-#: ../tag.c:862
msgid " or more"
msgstr " ¤«¤½¤ì°Ê¾å"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " ¥¿¥°¤ò°Û¤Ê¤ëcase¤Ç»ÈÍѤ·¤Þ¤¹!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: ¥Õ¥¡¥¤¥ë \"%s\" ¤¬¤¢¤ê¤Þ¤»¤ó"
-#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6055,79 +5668,64 @@ msgstr ""
"\n"
" # TO ¥¿¥° FROM ¹Ô in file/text"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "¥¿¥°¥Õ¥¡¥¤¥ë %s ¤ò¸¡º÷Ãæ"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: ¥¿¥°¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤¬ %s ¤ËÀÚ¤ê¼Î¤Æ¤é¤ì¤Þ¤·¤¿\n"
+
msgid "Ignoring long line in tags file"
msgstr "¥¿¥°¥Õ¥¡¥¤¥ëÆâ¤ÎŤ¤¹Ô¤ò̵»ë¤·¤Þ¤¹"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: ¥¿¥°¥Õ¥¡¥¤¥ë \"%s\" ¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë¥¨¥é¡¼¤¬¤¢¤ê¤Þ¤¹"
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "ľÁ°¤Î %<PRId64> ¥Ð¥¤¥È"
+msgid "Before byte %ld"
+msgstr "ľÁ°¤Î %ld ¥Ð¥¤¥È"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: ¥¿¥°¥Õ¥¡¥¤¥ë¤¬¥½¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó: %s"
-#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: ¥¿¥°¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: ¥¿¥°¥Ñ¥¿¡¼¥ó¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: ¥¿¥°¤ò¸«¤Ä¤±¤é¤ì¤Ê¤¤¤Î¤Çñ¤Ë¿ä¬¤·¤Þ¤¹!"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "½ÅÊ£¤·¤¿¥Õ¥£¡¼¥ë¥É̾: %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' ¤Ï̤ÃΤǤ¹. ¸½¹Ô¤ÎÁȤ߹þ¤ßüËö¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:"
-#: ../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¤ËüËö¥¨¥ó¥È¥ê¤ò¸«¤Ä¤±¤é¤ì¤Þ¤»¤ó"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: termcap¤Ë \"%s\" ¤Î¥¨¥ó¥È¥ê¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: üËö¤Ë \"cm\" µ¡Ç½¤¬É¬ÍפǤ¹"
-#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6135,168 +5733,363 @@ msgstr ""
"\n"
"--- üËö¥­¡¼ ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "$VIMRUNTIME/rgb.txt¤ò³«¤±¤Þ¤»¤ó"
+
+#, c-format
+msgid "Kill job in \"%s\"?"
+msgstr "\"%s\" Æâ¤Î¥¸¥ç¥Ö¤ò½ªÎ»¤·¤Þ¤¹¤«?"
+
+msgid "Terminal"
+msgstr "üËö"
+
+msgid "Terminal-finished"
+msgstr "üËö (½ªÎ»)"
+
+msgid "active"
+msgstr "¥¢¥¯¥Æ¥£¥Ö"
+
+msgid "running"
+msgstr "¼Â¹ÔÃæ"
+
+msgid "finished"
+msgstr "½ªÎ»"
+
+#, c-format
+msgid "E953: File exists: %s"
+msgstr "E953: ¥Õ¥¡¥¤¥ë¤Ï´û¤Ë¸ºß¤·¤Þ¤¹: %s"
+
+msgid "E955: Not a terminal buffer"
+msgstr "E955: üËö¥Ð¥Ã¥Õ¥¡¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+
+msgid "new shell started\n"
+msgstr "¿·¤·¤¤¥·¥§¥ë¤òµ¯Æ°¤·¤Þ¤¹\n"
+
msgid "Vim: Error reading input, exiting...\n"
msgstr "Vim: ÆþÎϤòÆÉ¹þ¤ßÃæ¤Î¥¨¥é¡¼¤Ë¤è¤ê½ªÎ»¤·¤Þ¤¹...\n"
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "¶õ¤ÎÁªÂòÎΰè¤Î¤«¤ï¤ê¤ËCUT_BUFFER0¤¬»ÈÍѤµ¤ì¤Þ¤·¤¿"
+
msgid "E881: Line count changed unexpectedly"
msgstr "E881: ͽ´ü¤»¤º¹Ô¥«¥¦¥ó¥È¤¬ÊѤï¤ê¤Þ¤·¤¿"
-#: ../undo.c:627
+msgid "No undo possible; continue anyway"
+msgstr "²Äǽ¤Ê¥¢¥ó¥É¥¥¤Ï¤¢¤ê¤Þ¤»¤ó: ¤È¤ê¤¢¤¨¤ºÂ³¤±¤Þ¤¹"
+
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: ½ñ¹þ¤ßÍѤ˥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤ò³«¤±¤Þ¤»¤ó: %s"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤¬²õ¤ì¤Æ¤¤¤Þ¤¹ (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr "'undodir'¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤ò½ñ¤­¹þ¤á¤Þ¤»¤ó"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤È¤·¤ÆÆÉ¤ß¹þ¤á¤Ê¤¤¤Î¤Ç¾å½ñ¤­¤·¤Þ¤»¤ó: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Ç¤Ï¤Ê¤¤¤Î¤Ç¾å½ñ¤­¤·¤Þ¤»¤ó: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Âоݤ¬¤Ê¤¤¤Î¤Ç¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Î½ñ¤­¹þ¤ß¤ò¥¹¥­¥Ã¥×¤·¤Þ¤¹"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë½ñ¤­¹þ¤ßÃæ: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Î½ñ¤­¹þ¤ß¥¨¥é¡¼¤Ç¤¹: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "¥ª¡¼¥Ê¡¼¤¬°Û¤Ê¤ë¤Î¤Ç¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤òÆÉ¤ß¹þ¤ß¤Þ¤»¤ó: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ëÆÉ¹þÃæ: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤òÆÉ¹þÍѤȤ·¤Æ³«¤±¤Þ¤»¤ó: %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#: ../undo.c:1313
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: Èó°Å¹æ²½¥Õ¥¡¥¤¥ë¤¬°Å¹æ²½¤µ¤ì¤¿¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ¤Þ¤¹: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: °Å¹æ²½¤µ¤ì¤¿¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Î²òÆÉ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤¬°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: %s"
+
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: ¸ß´¹À­¤Î̵¤¤¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Ç¤¹: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr "¥Õ¥¡¥¤¥ë¤ÎÆâÍÆ¤¬ÊѤï¤Ã¤Æ¤¤¤ë¤¿¤á¡¢¥¢¥ó¥É¥¥¾ðÊó¤òÍøÍѤǤ­¤Þ¤»¤ó"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë %s ¤Î¼è¹þ¤ò´°Î»"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "´û¤Ë°ìÈָŤ¤Êѹ¹¤Ç¤¹"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "´û¤Ë°ìÈÖ¿·¤·¤¤Êѹ¹¤Ç¤¹"
-#: ../undo.c:1806
#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: ¥¢¥ó¥É¥¥ÈÖ¹æ %<PRId64> ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
+msgid "E830: Undo number %ld not found"
+msgstr "E830: ¥¢¥ó¥É¥¥ÈÖ¹æ %ld ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: ¹ÔÈֹ椬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-#: ../undo.c:2183
msgid "more line"
msgstr "¹Ô Äɲä·¤Þ¤·¤¿"
-#: ../undo.c:2185
msgid "more lines"
msgstr "¹Ô Äɲä·¤Þ¤·¤¿"
-#: ../undo.c:2187
msgid "line less"
msgstr "¹Ô ºï½ü¤·¤Þ¤·¤¿"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "¹Ô ºï½ü¤·¤Þ¤·¤¿"
-#: ../undo.c:2193
msgid "change"
msgstr "²Õ½êÊѹ¹¤·¤Þ¤·¤¿"
-#: ../undo.c:2195
msgid "changes"
msgstr "²Õ½êÊѹ¹¤·¤Þ¤·¤¿"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
-#: ../undo.c:2228
msgid "before"
msgstr "Á°Êý"
-#: ../undo.c:2228
msgid "after"
msgstr "¸åÊý"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "¥¢¥ó¥É¥¥Âоݤ¬¤¢¤ê¤Þ¤»¤ó"
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "ÄÌÈÖ Êѹ¹¿ô Êѹ¹»þ´ü ÊݸºÑ"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> É÷вᤷ¤Æ¤¤¤Þ¤¹"
+msgid "%ld seconds ago"
+msgstr "%ld É÷вᤷ¤Æ¤¤¤Þ¤¹"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: undo ¤Îľ¸å¤Ë undojoin ¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: ¥¢¥ó¥É¥¥¥ê¥¹¥È¤¬²õ¤ì¤Æ¤¤¤Þ¤¹"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: ¥¢¥ó¥É¥¥¹Ô¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: ´Ø¿ô %s ¤ÏÄêµÁºÑ¤Ç¤¹¡¢ºÆÄêµÁ¤¹¤ë¤Ë¤Ï ! ¤òÄɲ䷤Ƥ¯¤À¤µ¤¤"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: ¼­½ñ·¿Æâ¤Ë¥¨¥ó¥È¥ê¤¬´û¤Ë¸ºß¤·¤Þ¤¹"
+
+msgid "E718: Funcref required"
+msgstr "E718: ´Ø¿ô»²¾È·¿¤¬Í׵ᤵ¤ì¤Þ¤¹"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: ̤ÃΤδؿô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: ÉÔÀµ¤Ê°ú¿ô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: °ú¿ô̾¤¬½ÅÊ£¤·¤Æ¤¤¤Þ¤¹: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: ´Ø¿ô¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: ´Ø¿ô¤Î̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: ´Ø¿ô¸Æ½Ð¤ÎÆþ¤ì»Ò¿ô¤¬ 'maxfuncdepth' ¤òͤ¨¤Þ¤·¤¿"
+
+#, c-format
+msgid "calling %s"
+msgstr "%s ¤ò¼Â¹ÔÃæ¤Ç¤¹"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s ¤¬ÃæÃǤµ¤ì¤Þ¤·¤¿"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ¤¬ #%ld ¤òÊÖ¤·¤Þ¤·¤¿"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿"
+
+msgid "E699: Too many arguments"
+msgstr "E699: °ú¿ô¤¬Â¿²á¤®¤Þ¤¹"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: ̤ÃΤδؿô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: ´Ø¿ô¤Ïºï½ü¤µ¤ì¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: ´Ø¿ô¤Î°ú¿ô¤¬Â­¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç<SID>¤¬»È¤ï¤ì¤Þ¤·¤¿: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: ¼­½ñÍÑ´Ø¿ô¤¬¸Æ¤Ð¤ì¤Þ¤·¤¿¤¬¼­½ñ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: ´Ø¿ô̾¤¬Í׵ᤵ¤ì¤Þ¤¹"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: ´Ø¿ô̾¤ÏÂçʸ»ú¤« \"s:\" ¤Ç»Ï¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: ´Ø¿ô̾¤Ë¤Ï¥³¥í¥ó¤Ï´Þ¤á¤é¤ì¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: ̤ÄêµÁ¤Î´Ø¿ô¤Ç¤¹: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: ¤³¤³¤Ç¤Ï g: ¤Ï»È¤¨¤Þ¤»¤ó"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: ¥¯¥í¡¼¥¸¥ã¡¼´Ø¿ô¤Ï¥È¥Ã¥×¥ì¥Ù¥ë¤Ëµ­½Ò¤Ç¤­¤Þ¤»¤ó: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ¤¬¤¢¤ê¤Þ¤»¤ó"
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: :endfunction ¤Î¸å¤Ëʸ»ú¤¬¤¢¤ê¤Þ¤¹: %s"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: ´Ø¿ô̾¤¬ÊÑ¿ô̾¤È¾×ÆÍ¤·¤Þ¤¹: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: ´Ø¿ô %s ¤òºÆÄêµÁ¤Ç¤­¤Þ¤»¤ó: »ÈÍÑÃæ¤Ç¤¹"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: ´Ø¿ô̾¤¬¥¹¥¯¥ê¥×¥È¤Î¥Õ¥¡¥¤¥ë̾¤È°ìÃפ·¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: ´Ø¿ô %s ¤òºï½ü¤Ç¤­¤Þ¤»¤ó: »ÈÍÑÃæ¤Ç¤¹"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: ´Ø¿ô³°¤Ë :return ¤¬¤¢¤ê¤Þ¤·¤¿"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ¥«¥Ã¥³ '(' ¤¬¤¢¤ê¤Þ¤»¤ó: %s"
+
+#, c-format
+msgid "%s (%s, compiled %s)"
+msgstr "%s (%s, compiled %s)"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 64 ¥Ó¥Ã¥È GUI ÈÇ"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32 ¥Ó¥Ã¥È GUI ÈÇ"
+
+msgid " with OLE support"
+msgstr " with OLE ¥µ¥Ý¡¼¥È"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 64 ¥Ó¥Ã¥È ¥³¥ó¥½¡¼¥ë ÈÇ"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32 ¥Ó¥Ã¥È ¥³¥ó¥½¡¼¥ë ÈÇ"
+
+msgid ""
+"\n"
+"macOS version"
+msgstr ""
+"\n"
+"macOS ÈÇ"
+
+msgid ""
+"\n"
+"macOS version w/o darwin feat."
+msgstr ""
+"\n"
+"macOS ÈÇ (darwin ̵¤·)"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"OpenVMS ÈÇ"
+
msgid ""
"\n"
"Included patches: "
@@ -6304,7 +6097,6 @@ msgstr ""
"\n"
"ŬÍѺѥѥåÁ: "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6312,11 +6104,9 @@ msgstr ""
"\n"
"ÄɲóÈÄ¥¥Ñ¥Ã¥Á: "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Modified by "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6324,11 +6114,9 @@ msgstr ""
"\n"
"Compiled "
-#: ../version.c:649
msgid "by "
msgstr "by "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6336,1886 +6124,950 @@ msgstr ""
"\n"
"Huge ÈÇ "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Big ÈÇ "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Ä̾ï ÈÇ "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Small ÈÇ "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Tiny ÈÇ "
+
msgid "without GUI."
msgstr "without GUI."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "with GTK3 GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "with GTK2-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "with GTK2 GUI."
+
+msgid "with X11-Motif GUI."
+msgstr "with X11-Motif GUI."
+
+msgid "with X11-neXtaw GUI."
+msgstr "with X11-neXtaw GUI."
+
+msgid "with X11-Athena GUI."
+msgstr "with X11-Athena GUI."
+
+msgid "with Photon GUI."
+msgstr "with Photon GUI."
+
+msgid "with GUI."
+msgstr "with GUI."
+
+msgid "with Carbon GUI."
+msgstr "with Carbon GUI."
+
+msgid "with Cocoa GUI."
+msgstr "with Cocoa GUI."
+
msgid " Features included (+) or not (-):\n"
msgstr " µ¡Ç½¤Î°ìÍ÷ Í­¸ú(+)/̵¸ú(-)\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " ¥·¥¹¥Æ¥à vimrc: \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " ¥æ¡¼¥¶¡¼ vimrc: \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " Âè2¥æ¡¼¥¶¡¼ vimrc: \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " Âè3¥æ¡¼¥¶¡¼ vimrc: \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " ¥æ¡¼¥¶¡¼ exrc: \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " Âè2¥æ¡¼¥¶¡¼ exrc: \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " ¥·¥¹¥Æ¥à gvimrc: \""
+
+msgid " user gvimrc file: \""
+msgstr " ¥æ¡¼¥¶¡¼ gvimrc: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " Âè2¥æ¡¼¥¶¡¼ gvimrc: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " Âè3¥æ¡¼¥¶¡¼ gvimrc: \""
+
+msgid " defaults file: \""
+msgstr " ¥Ç¥Õ¥©¥ë¥È¥Õ¥¡¥¤¥ë: \""
+
+msgid " system menu file: \""
+msgstr " ¥·¥¹¥Æ¥à¥á¥Ë¥å¡¼: \""
+
msgid " fall-back for $VIM: \""
msgstr " ¾Êά»þ¤Î $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr "¾Êά»þ¤Î $VIMRUNTIME: \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "¥³¥ó¥Ñ¥¤¥ë: "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "¥³¥ó¥Ñ¥¤¥é: "
+
msgid "Linking: "
msgstr "¥ê¥ó¥¯: "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr "¥Ç¥Ð¥Ã¥°¥Ó¥ë¥É"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi IMproved"
-#: ../version.c:769
msgid "version "
msgstr "version "
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "by Bram Moolenaar ¾."
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Vim ¤Ï¥ª¡¼¥×¥ó¥½¡¼¥¹¤Ç¤¢¤ê¼«Í³¤ËÇÛÉÛ²Äǽ¤Ç¤¹"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "¥¦¥¬¥ó¥À¤Î·Ã¤Þ¤ì¤Ê¤¤»Ò¶¡¤¿¤Á¤Ë±ç½õ¤ò!"
-#: ../version.c:777
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> "
+msgid "type :help version8<Enter> for version info"
+msgstr "¥Ð¡¼¥¸¥ç¥ó¾ðÊó¤Ï :help version8<Enter> "
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "Vi¸ß´¹¥â¡¼¥É¤ÇưºîÃæ"
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr "Vim¿ä¾©Ãͤˤ¹¤ë¤Ë¤Ï :set nocp<Enter> "
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr "¾ÜºÙ¤Ê¾ðÊó¤Ï :help cp-default<Enter>"
-#: ../version.c:827
+msgid "menu Help->Orphans for information "
+msgstr "¾ÜºÙ¤Ï¥á¥Ë¥å¡¼¤Î ¥Ø¥ë¥×->¸É»ù ¤ò»²¾È¤·¤Æ²¼¤µ¤¤ "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "¥â¡¼¥É̵¤Ç¼Â¹ÔÃæ¡£¥¿¥¤¥×¤·¤¿Ê¸»ú¤¬ÁÞÆþ¤µ¤ì¤Þ¤¹"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸->Á´ÂÎÀßÄê->ÁÞÆþ(½é¿´¼Ô)¥â¡¼¥ÉÀÚÂØ "
+
+msgid " for two modes "
+msgstr " ¤Ç¥â¡¼¥ÉÍ­¤Ë "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸->Á´ÂÎÀßÄê->Vi¸ß´¹¥â¡¼¥ÉÀÚÂØ "
+
+msgid " for Vim defaults "
+msgstr " ¤ÇVim¤È¤·¤ÆÆ°ºî "
+
msgid "Sponsor Vim development!"
msgstr "Vim¤Î³«È¯¤ò±þ±ç¤·¤Æ¤¯¤À¤µ¤¤!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Vim¤ÎÅÐÏ¿¥æ¡¼¥¶¡¼¤Ë¤Ê¤Ã¤Æ¤¯¤À¤µ¤¤!"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "¾ÜºÙ¤Ê¾ðÊó¤Ï :help sponsor<Enter> "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "¾ÜºÙ¤Ê¾ðÊó¤Ï :help register<Enter> "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "¾ÜºÙ¤Ï¥á¥Ë¥å¡¼¤Î ¥Ø¥ë¥×->¥¹¥Ý¥ó¥µ¡¼/ÅÐÏ¿ ¤ò»²¾È¤·¤Æ²¼¤µ¤¤"
-#: ../window.c:119
msgid "Already only one window"
msgstr "´û¤Ë¥¦¥£¥ó¥É¥¦¤Ï1¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: ¥×¥ì¥Ó¥å¡¼¥¦¥£¥ó¥É¥¦¤¬¤¢¤ê¤Þ¤»¤ó"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: º¸¾å¤È±¦²¼¤òƱ»þ¤Ëʬ³ä¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: ¾¤Î¥¦¥£¥ó¥É¥¦¤¬Ê¬³ä¤µ¤ì¤Æ¤¤¤ë»þ¤Ë¤Ï½ç²ó¤Ç¤­¤Þ¤»¤ó"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: ºÇ¸å¤Î¥¦¥£¥ó¥É¥¦¤òÊĤ¸¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: autocmd¥¦¥£¥ó¥É¥¦¤ÏÊĤ¸¤é¤ì¤Þ¤»¤ó"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr "E814: autocmd¥¦¥£¥ó¥É¥¦¤·¤«»Ä¤é¤Ê¤¤¤¿¤á¡¢¥¦¥£¥ó¥É¥¦¤ÏÊĤ¸¤é¤ì¤Þ¤»¤ó"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: ¾¤Î¥¦¥£¥ó¥É¥¦¤Ë¤ÏÊѹ¹¤¬¤¢¤ê¤Þ¤¹"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: ¥«¡¼¥½¥ë¤Î²¼¤Ë¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
-msgid "List or number required"
-msgstr "¥ê¥¹¥È¤«¿ôÃͤ¬É¬ÍפǤ¹"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() ¤¬¶õ¥Ñ¥¹¥ï¡¼¥É¤Ç¸Æ¤Ó½Ð¤µ¤ì¤Þ¤·¤¿"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfish°Å¹æ¤Î¥Ó¥Ã¥°/¥ê¥È¥ë¥¨¥ó¥Ç¥£¥¢¥ó¤¬´Ö°ã¤Ã¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: sha256¤Î¥Æ¥¹¥È¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Blowfish°Å¹æ¤Î¥Æ¥¹¥È¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "Patch file"
-#~ msgstr "¥Ñ¥Ã¥Á¥Õ¥¡¥¤¥ë"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "·èÄê(&O)\n"
-#~ "¥­¥ã¥ó¥»¥ë(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Vim ¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: %s ¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: ¥µ¡¼¥Ð¤Î±þÅú¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: ¥¯¥é¥¤¥¢¥ó¥È¤ØÁ÷¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "Save As"
-#~ msgstr "ÊÌ̾¤ÇÊݸ"
-
-#~ msgid "Edit File"
-#~ msgstr "¥Õ¥¡¥¤¥ë¤òÊÔ½¸"
-
-# Added at 27-Jan-2004.
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (¸«¤Ä¤«¤ê¤Þ¤»¤ó)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Vim¥¹¥¯¥ê¥×¥È¤Î¼è¹þ¤ß"
-
-#~ msgid "unknown"
-#~ msgstr "ÉÔÌÀ"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "¿·¤·¤¤¥¦¥£¥ó¥É¥¦¤Ç¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤¹"
-
-#~ msgid "Append File"
-#~ msgstr "Äɲåե¡¥¤¥ë"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "¥¦¥£¥ó¥É¥¦°ÌÃÖ: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "¥ê¥À¥¤¥ì¥¯¥È¤òÊݸ¤·¤Þ¤¹"
-
-#~ msgid "Save View"
-#~ msgstr "¥Ó¥å¡¼¤òÊݸ¤·¤Þ¤¹"
-
-#~ msgid "Save Session"
-#~ msgstr "¥»¥Ã¥·¥ç¥ó¾ðÊó¤òÊݸ¤·¤Þ¤¹"
-
-#~ msgid "Save Setup"
-#~ msgstr "ÀßÄê¤òÊݸ¤·¤Þ¤¹"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< ¤Ï +eval µ¡Ç½¤¬Ìµ¤¤¤ÈÍøÍѤǤ­¤Þ¤»¤ó"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¹ç»ú¤Ï¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr " ¤Ï¥Ç¥Ð¥¤¥¹¤Ç¤¹ ('opendevice' ¥ª¥×¥·¥ç¥ó¤Ç²óÈò¤Ç¤­¤Þ¤¹)"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "ɸ½àÆþÎϤ«¤éÆÉ¹þ¤ßÃæ..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfish°Å¹æ²½]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[°Å¹æ²½]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: ¥Õ¥¡¥¤¥ë¤¬Ì¤ÃΤÎÊýË¡¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
-
-# Added at 19-Jan-2004.
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans¤Ï̤Êѹ¹¤Î¥Ð¥Ã¥Õ¥¡¤ò¾å½ñ¤¹¤ë¤³¤È¤Ïµö²Ä¤·¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeans¥Ð¥Ã¥Õ¥¡¤Î°ìÉô¤ò½ñ¤­½Ð¤¹¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "'opendevice' ¥ª¥×¥·¥ç¥ó¤Ë¤è¤ê¥Ç¥Ð¥¤¥¹¤Ø¤Î½ñ¤­¹þ¤ß¤Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: ¥ê¥½¡¼¥¹¥Õ¥©¡¼¥¯¤¬¼º¤ï¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó (! ¤òÄɲäǶ¯À©)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: GUIÍÑ¤Î¥×¥í¥»¥¹¤Îµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: »Ò¥×¥í¥»¥¹¤¬GUI¤Îµ¯Æ°¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: GUI¤ò³«»Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: \"%s\"¤«¤éÆÉ¹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Í­¸ú¤Ê¥Õ¥©¥ó¥È¤¬¸«¤Ä¤«¤é¤Ê¤¤¤Î¤Ç, GUI¤ò³«»Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' ¤¬Ìµ¸ú¤Ç¤¹"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' ¤ËÀßÄꤵ¤ì¤¿Ãͤ¬Ìµ¸ú¤Ç¤¹"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: %s ¤Î¿§¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "¥«¡¼¥½¥ë¤Î°ÌÃ֤˥ޥåÁ¤Ï¤¢¤ê¤Þ¤»¤ó, ¼¡¤ò¸¡º÷¤·¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<³«¤±¤Þ¤»¤ó> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ¥Õ¥©¥ó¥È %s ¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÌá¤ì¤Þ¤»¤ó"
-
-#~ msgid "Pathname:"
-#~ msgstr "¥Ñ¥¹Ì¾:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "OK"
-#~ msgstr "OK"
-
-#~ msgid "Cancel"
-#~ msgstr "¥­¥ã¥ó¥»¥ë"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "¥¹¥¯¥í¡¼¥ë¥Ð¡¼: ²èÁü¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿."
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim ¥À¥¤¥¢¥í¥°"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: ¥á¥Ã¥»¡¼¥¸¤È¥³¡¼¥ë¥Ð¥Ã¥¯¤Î¤¢¤ë BalloonEval ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "Input _Methods"
-#~ msgstr "¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - ¸¡º÷¤ÈÃÖ´¹..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - ¸¡º÷..."
-
-#~ msgid "Find what:"
-#~ msgstr "¸¡º÷ʸ»úÎó:"
-
-#~ msgid "Replace with:"
-#~ msgstr "ÃÖ´¹Ê¸»úÎó:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Àµ³Î¤Ë³ºÅö¤¹¤ë¤â¤Î¤À¤±"
-
-#~ msgid "Match case"
-#~ msgstr "Âçʸ»ú/¾®Ê¸»ú¤ò¶èÊ̤¹¤ë"
-
-#~ msgid "Direction"
-#~ msgstr "Êý¸þ"
-
-#~ msgid "Up"
-#~ msgstr "¾å"
-
-#~ msgid "Down"
-#~ msgstr "²¼"
-
-#~ msgid "Find Next"
-#~ msgstr "¼¡¤ò¸¡º÷"
-
-#~ msgid "Replace"
-#~ msgstr "ÃÖ´¹"
-
-#~ msgid "Replace All"
-#~ msgstr "Á´¤ÆÃÖ´¹"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: ¥»¥Ã¥·¥ç¥ó¥Þ¥Í¡¼¥¸¥ã¤«¤é \"die\" Í×µá¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿\n"
-
-#~ msgid "Close"
-#~ msgstr "ÊĤ¸¤ë"
-
-#~ msgid "New tab"
-#~ msgstr "¿·µ¬¥¿¥Ö¥Ú¡¼¥¸"
-
-#~ msgid "Open Tab..."
-#~ msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: ¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤¬ÉÔ°Õ¤ËÇ˲õ¤µ¤ì¤Þ¤·¤¿\n"
-
-#~ msgid "&Filter"
-#~ msgstr "¥Õ¥£¥ë¥¿(&F)"
-
-#~ msgid "&Cancel"
-#~ msgstr "¥­¥ã¥ó¥»¥ë(&C)"
-
-#~ msgid "Directories"
-#~ msgstr "¥Ç¥£¥ì¥¯¥È¥ê"
-
-#~ msgid "Filter"
-#~ msgstr "¥Õ¥£¥ë¥¿"
-
-#~ msgid "&Help"
-#~ msgstr "¥Ø¥ë¥×(&H)"
-
-#~ msgid "Files"
-#~ msgstr "¥Õ¥¡¥¤¥ë"
-
-#~ msgid "&OK"
-#~ msgstr "&OK"
-
-#~ msgid "Selection"
-#~ msgstr "ÁªÂò"
-
-#~ msgid "Find &Next"
-#~ msgstr "¼¡¤ò¸¡º÷(&N)"
-
-#~ msgid "&Replace"
-#~ msgstr "ÃÖ´¹(&R)"
-
-#~ msgid "Replace &All"
-#~ msgstr "Á´¤ÆÃÖ´¹(&A)"
-
-#~ msgid "&Undo"
-#~ msgstr "¥¢¥ó¥É¥¥(&U)"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: ¥¿¥¤¥È¥ë¤¬ \"%s\" ¤Î¥¦¥£¥ó¥É¥¦¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: °ú¿ô¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó: \"-%s\"; OLEÈǤò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: MDI¥¢¥×¥ê¤ÎÃæ¤Ç¤Ï¥¦¥£¥ó¥É¥¦¤ò³«¤±¤Þ¤»¤ó"
-
-#~ msgid "Close tab"
-#~ msgstr "¥¿¥Ö¥Ú¡¼¥¸¤òÊĤ¸¤ë"
-
-#~ msgid "Open tab..."
-#~ msgstr "¥¿¥Ö¥Ú¡¼¥¸¤ò³«¤¯"
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "¸¡º÷ʸ»úÎó ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "¸¡º÷¡¦ÃÖ´¹ ('\\' ¤ò¸¡º÷¤¹¤ë¤Ë¤Ï '\\\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "»È¤ï¤ì¤Þ¤»¤ó"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "¥Ç¥£¥ì¥¯¥È¥ê\t*.nothing\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: ¿§»ØÄ꤬Àµ¤·¤¯¤Ê¤¤¤Î¤Ç¥¨¥ó¥È¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: °Ê²¼¤Îʸ»ú¥»¥Ã¥È¤Î¥Õ¥©¥ó¥È¤¬¤¢¤ê¤Þ¤»¤ó %s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: ¥Õ¥©¥ó¥È¥»¥Ã¥È̾: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "¥Õ¥©¥ó¥È '%s' ¤Ï¸ÇÄêÉý¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: ¥Õ¥©¥ó¥È¥»¥Ã¥È̾: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "¥Õ¥©¥ó¥È0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "¥Õ¥©¥ó¥È1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "¥Õ¥©¥ó¥È%<PRId64> ¤ÎÉý¤¬¥Õ¥©¥ó¥È0¤Î2ÇܤǤϤ¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "¥Õ¥©¥ó¥È0¤ÎÉý: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "¥Õ¥©¥ó¥È1¤ÎÉý: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "̵¸ú¤Ê¥Õ¥©¥ó¥È»ØÄê¤Ç¤¹"
-
-#~ msgid "&Dismiss"
-#~ msgstr "µÑ²¼¤¹¤ë(&D)"
-
-#~ msgid "no specific match"
-#~ msgstr "¥Þ¥Ã¥Á¤¹¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - ¥Õ¥©¥ó¥ÈÁªÂò"
-
-#~ msgid "Name:"
-#~ msgstr "̾Á°:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "¥µ¥¤¥º¤ò¥Ý¥¤¥ó¥È¤Çɽ¼¨¤¹¤ë"
-
-#~ msgid "Encoding:"
-#~ msgstr "¥¨¥ó¥³¡¼¥É:"
-
-#~ msgid "Font:"
-#~ msgstr "¥Õ¥©¥ó¥È:"
-
-#~ msgid "Style:"
-#~ msgstr "¥¹¥¿¥¤¥ë:"
-
-#~ msgid "Size:"
-#~ msgstr "¥µ¥¤¥º:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ¥Ï¥ó¥°¥ë¥ª¡¼¥È¥Þ¥È¥ó¥¨¥é¡¼"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat ¥¨¥é¡¼"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: cscope¥Ç¡¼¥¿¥Ù¡¼¥¹: %s ¤ò³«¤¯¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: cscope¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Lua¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "¥¢¥ó¥É¥¥¾ðÊó¤¬Êݸ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹. MzScheme ¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó."
-
-#~ msgid "invalid expression"
-#~ msgstr "̵¸ú¤Ê¼°¤Ç¤¹"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "¼°¤Ï¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "hidden option"
-#~ msgstr "±£¤·¥ª¥×¥·¥ç¥ó"
-
-#~ msgid "unknown option"
-#~ msgstr "̤ÃΤΥª¥×¥·¥ç¥ó¤Ç¤¹"
-
-#~ msgid "window index is out of range"
-#~ msgstr "Èϰϳ°¤Î¥¦¥£¥ó¥É¥¦ÈÖ¹æ¤Ç¤¹"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "¥Ð¥Ã¥Õ¥¡¤ò³«¤±¤Þ¤»¤ó"
-
-#~ msgid "cannot delete line"
-#~ msgstr "¹Ô¤ò¾Ã¤»¤Þ¤»¤ó"
-
-#~ msgid "cannot replace line"
-#~ msgstr "¹Ô¤òÃÖ´¹¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "cannot insert line"
-#~ msgstr "¹Ô¤òÁÞÆþ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ʸ»úÎó¤Ë¤Ï²þ¹Ôʸ»ú¤ò´Þ¤á¤é¤ì¤Þ¤»¤ó"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "SchemeÃͤÎVim¤Ø¤ÎÊÑ´¹¥¨¥é¡¼"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim ¥¨¥é¡¼: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Vim ¥¨¥é¡¼"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "¥Ð¥Ã¥Õ¥¡¤Ï̵¸ú¤Ç¤¹"
-
-#~ msgid "window is invalid"
-#~ msgstr "¥¦¥£¥ó¥É¥¦¤Ï̵¸ú¤Ç¤¹"
-
-#~ msgid "linenr out of range"
-#~ msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: ¥é¥¤¥Ö¥é¥ê %s ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹, ¤´¤á¤ó¤Ê¤µ¤¤: Perl¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·"
-#~ "¤¿."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ï Safe ¥â¥¸¥å¡¼¥ë¤ò»ÈÍѤ·¤Ê¤¤Perl¥¹¥¯¥ê¥×¥È¤Ï¶Ø¤¸¤é"
-#~ "¤ì¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: ¤³¤ÎVim¤Ç¤Ï :py3 ¤ò»È¤Ã¤¿¸å¤Ë :python ¤ò»È¤¨¤Þ¤»¤ó"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Python¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ"
-#~ "¤»¤ó¤Ç¤·¤¿."
-
-# Added at 07-Feb-2004.
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Python ¤òºÆµ¢Åª¤Ë¼Â¹Ô¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: ¤³¤ÎVim¤Ç¤Ï :python ¤ò»È¤Ã¤¿¸å¤Ë :py3 ¤ò»È¤¨¤Þ¤»¤ó"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ ¤Ïʸ»úÎó¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: ¤³¤Î¥³¥Þ¥ó¥É¤Ï̵¸ú¤Ç¤¹,¤´¤á¤ó¤Ê¤µ¤¤: Ruby¥é¥¤¥Ö¥é¥ê¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»"
-#~ "¤ó¤Ç¤·¤¿."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: ͽ´ü¤»¤Ì return ¤Ç¤¹"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: ͽ´ü¤»¤Ì next ¤Ç¤¹"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: ͽ´ü¤»¤Ì break ¤Ç¤¹"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: ͽ´ü¤»¤Ì redo ¤Ç¤¹"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: rescue ¤Î³°¤Î retry ¤Ç¤¹"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: ¼è¤ê°·¤ï¤ì¤Ê¤«¤Ã¤¿Îã³°¤¬¤¢¤ê¤Þ¤¹"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: ̤ÃΤÎlongjmp¾õÂÖ: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "¼ÂÁõ¤ÈÄêµÁ¤òÀÚ¤êÂØ¤¨¤ë"
-
-#~ msgid "Show base class of"
-#~ msgstr "¼¡¤Î¥¯¥é¥¹¤Î´ðÄì¤òɽ¼¨"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "¥ª¡¼¥Ð¡¼¥é¥¤¥É¤µ¤ì¤¿¥á¥ó¥Ð´Ø¿ô¤òɽ¼¨"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "¥Õ¥¡¥¤¥ë¤«¤é²óÉü¤¹¤ë"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "¥×¥í¥¸¥§¥¯¥È¤«¤é²óÉü¤¹¤ë"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Á´¤Æ¤Î¥×¥í¥¸¥§¥¯¥È¤«¤é²óÉü¤¹¤ë"
-
-#~ msgid "Retrieve"
-#~ msgstr "²óÉü"
-
-#~ msgid "Show source of"
-#~ msgstr "¼¡¤Î¥½¡¼¥¹¤òɽ¼¨¤¹¤ë"
-
-#~ msgid "Find symbol"
-#~ msgstr "¸«¤Ä¤±¤¿¥·¥ó¥Ü¥ë"
-
-#~ msgid "Browse class"
-#~ msgstr "¥¯¥é¥¹¤ò»²¾È"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "³¬Áؤǥ¯¥é¥¹¤òɽ¼¨"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "¸ÂÄꤵ¤ì¤¿³¬Áؤǥ¯¥é¥¹¤òɽ¼¨"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ¤Î»²¾ÈÀè"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ¤¬»²¾È¤µ¤ì¤ë"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ¤¬¼¡¤Î¤â¤Î¤ò¤â¤Ã¤Æ¤¤¤Þ¤¹"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref ¤¬»ÈÍѤµ¤ì¤ë"
-
-#~ msgid "Show docu of"
-#~ msgstr "¼¡¤Îʸ¾Ï¤òɽ¼¨"
-
-#~ msgid "Generate docu for"
-#~ msgstr "¼¡¤Îʸ¾Ï¤òÀ¸À®"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "SNiFF+¤ËÀܳ¤Ç¤­¤Þ¤»¤ó. ´Ä¶­¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤(sniffemacs ¤¬ $PATH ¤Ë"
-#~ "¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: ÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿. ÀÚÃǤ·¤Þ¤·¤¿"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "¸½ºßSNiFF+ ¤Î¾õÂ֤ϡÖ"
-
-#~ msgid "not "
-#~ msgstr "̤"
-
-#~ msgid "connected"
-#~ msgstr "Àܳ¡×¤Ç¤¹"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: ̤ÃΤΠSNiFF+ ¥ê¥¯¥¨¥¹¥È¤Ç¤¹: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: SNiFF+ ¤Ø¤ÎÀÜÂ³Ãæ¤Î¥¨¥é¡¼¤Ç¤¹"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ¤ËÀܳ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: SNiFF+ ¥Ð¥Ã¥Õ¥¡¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: ½ñ¹þ¤ßÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤Î¤ÇÀÚÃǤ·¤Þ¤·¤¿"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "̵¸ú¤Ê¥Ð¥Ã¥Õ¥¡ÈÖ¹æ¤Ç¤¹"
-
-#~ msgid "not implemented yet"
-#~ msgstr "¤Þ¤À¼ÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "¹Ô¤òÀßÄê¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "invalid mark name"
-#~ msgstr "̵¸ú¤Ê¥Þ¡¼¥¯Ì¾¤Ç¤¹"
-
-#~ msgid "mark not set"
-#~ msgstr "¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "row %d column %d"
-#~ msgstr "¹Ô %d Îó %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "¹Ô¤ÎÁÞÆþ/Äɲäò¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "line number out of range"
-#~ msgstr "Èϰϳ°¤Î¹ÔÈÖ¹æ¤Ç¤¹"
-
-#~ msgid "unknown flag: "
-#~ msgstr "̤ÃΤΥե饰: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "̤ÃΤΠvimOption ¤Ç¤¹"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "¥­¡¼¥Ü¡¼¥É³ä¹þ¤ß"
-
-#~ msgid "vim error"
-#~ msgstr "vim ¥¨¥é¡¼"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦ºîÀ®¥³¥Þ¥ó¥É¤òºîÀ®¤Ç¤­¤Þ¤»¤ó: ¥ª¥Ö¥¸¥§¥¯¥È¤¬¾Ãµî¤µ¤ì¤Æ"
-#~ "¤¤¤Þ¤·¤¿"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤¬´û¤Ë¾Ãµî¤µ¤ì¤Þ"
-#~ "¤·¤¿"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL Ã×̿Ū¥¨¥é¡¼: reflist ±øÀ÷!? vim-dev@vim.org ¤ËÊó¹ð¤·¤Æ¤¯¤À¤µ¤¤"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "¥³¡¼¥ë¥Ð¥Ã¥¯¥³¥Þ¥ó¥É¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó: ¥Ð¥Ã¥Õ¥¡/¥¦¥£¥ó¥É¥¦¤Î»²¾È¤¬¸«¤Ä¤«¤ê"
-#~ "¤Þ¤»¤ó"
-
-#~ 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 "cannot get line"
-#~ msgstr "¹Ô¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Ì¿Î᥵¡¼¥Ð¤Î̾Á°¤òÅÐÏ¿¤Ç¤­¤Þ¤»¤ó"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: ÌÜŪ¤Î¥×¥í¥°¥é¥à¤Ø¤Î¥³¥Þ¥ó¥ÉÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: ̵¸ú¤Ê¥µ¡¼¥ÐID¤¬»È¤ï¤ì¤Þ¤·¤¿: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM ¼ÂÂΤÎÅÐÏ¿¥×¥í¥Ñ¥Æ¥£¤¬ÉÔÀµ¤Ç¤¹. ¾Ãµî¤·¤Þ¤·¤¿!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ¤Ï¤³¤ÎGUI¤Ç¤ÏÍøÍѤǤ­¤Þ¤»¤ó\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "¤³¤ÎVim¤Ë¤Ïdiffµ¡Ç½¤¬¤¢¤ê¤Þ¤»¤ó(¥³¥ó¥Ñ¥¤¥ë»þÀßÄê)."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' »ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: ¥¨¥é¡¼: NetBeans¤«¤égvim¤ò¥¹¥¿¡¼¥È¤Ç¤­¤Þ¤»¤ó\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "Â羮ʸ»ú¤¬Ìµ»ë¤µ¤ì¤ë¾ì¹ç¤ÏÂçʸ»ú¤Ë¤¹¤ë¤¿¤á¤Ë / ¤òÁ°ÃÖ¤·¤Æ¤¯¤À¤µ¤¤"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\t¤³¤Îgvim¤òOLE¤È¤·¤ÆÅÐÏ¿¤¹¤ë"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tgvim¤ÎOLEÅÐÏ¿¤ò²ò½ü¤¹¤ë"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tGUI¤Çµ¯Æ°¤¹¤ë (\"gvim\" ¤ÈƱ¤¸)"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f or --nofork\t¥Õ¥©¥¢¥°¥é¥¦¥ó¥É: GUI¤ò»Ï¤á¤ë¤È¤­¤Ëfork¤·¤Ê¤¤"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\t¥¦¥£¥ó¥É¥¦¤ò³«¤¯¤Î¤Ë newcli ¤ò»ÈÍѤ·¤Ê¤¤"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tI/O¤Ë <device> ¤ò»ÈÍѤ¹¤ë"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\t.gvimrc¤ÎÂå¤ï¤ê¤Ë <gvimrc> ¤ò»È¤¦"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\t°Å¹æ²½¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤¹¤ë"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tvim¤ò»ØÄꤷ¤¿ X ¥µ¡¼¥Ð¤ËÀܳ¤¹¤ë"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tX¥µ¡¼¥Ð¤ËÀܳ¤·¤Ê¤¤"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\t²Äǽ¤Ê¤é¤ÐVim¥µ¡¼¥Ð¤Ç <files> ¤òÊÔ½¸¤¹¤ë"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> Ʊ¾å, ¥µ¡¼¥Ð¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr "--remote-wait <files>\t--remote¸å ¥Õ¥¡¥¤¥ë¤ÎÊÔ½¸¤¬½ª¤ï¤ë¤Î¤òÂÔ¤Ä"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <files> Ʊ¾å, ¥µ¡¼¥Ð¤¬Ìµ¤¯¤Æ¤â·Ù¹ðʸ¤ò½ÐÎϤ·¤Ê¤¤"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <files> --remote¤Ç¥Õ¥¡¥¤¥ë1¤Ä¤Ë¤Ä¤­1¤Ä¤Î¥¿¥Ö"
-#~ "¥Ú¡¼¥¸¤ò³«¤¯"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\tVim¥µ¡¼¥Ð¤Ë <keys> ¤òÁ÷¿®¤·¤Æ½ªÎ»¤¹¤ë"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\t¥µ¡¼¥Ð¤Ç <expr> ¤ò¼Â¹Ô¤·¤Æ·ë²Ì¤òɽ¼¨¤¹¤ë"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tVim¥µ¡¼¥Ð̾¤Î°ìÍ÷¤òɽ¼¨¤·¤Æ½ªÎ»¤¹¤ë"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <name>\tVim¥µ¡¼¥Ð <name> ¤ËÁ÷¿®/̾Á°ÀßÄꤹ¤ë"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(Motif¥Ð¡¼¥¸¥ç¥ó):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(neXtaw¥Ð¡¼¥¸¥ç¥ó):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(Athena¥Ð¡¼¥¸¥ç¥ó):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\t<display> ¤Çvim¤ò¼Â¹Ô¤¹¤ë"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tºÇ¾®²½¤·¤¿¾õÂÖ¤Çvim¤òµ¯Æ°¤¹¤ë"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\tÇØ·Ê¿§¤Ë <color> ¤ò»È¤¦(ƱµÁ: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\tÁ°·Ê¿§¤Ë <color> ¤ò»È¤¦(ƱµÁ: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\t¥Æ¥­¥¹¥Èɽ¼¨¤Ë <font> ¤ò»È¤¦(ƱµÁ: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\tÂÀ»ú¤Ë <font> ¤ò»È¤¦"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <for>\t¼ÐÂλú¤Ë <font> ¤ò»È¤¦"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\t½é´üÇÛÃÖ¤Ë <geom> ¤ò»È¤¦(ƱµÁ: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\t¶­³¦¤ÎÉý¤ò <width> ¤Ë¤¹¤ë(ƱµÁ: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <width> ¥¹¥¯¥í¡¼¥ë¥Ð¡¼¤ÎÉý¤ò <width> ¤Ë¤¹¤ë(ƱµÁ: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <height>\t¥á¥Ë¥å¡¼¥Ð¡¼¤Î¹â¤µ¤ò <height> ¤Ë¤¹¤ë(ƱµÁ: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tȿž±ÇÁü¤ò»ÈÍѤ¹¤ë(ƱµÁ: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tȿž±ÇÁü¤ò»ÈÍѤ·¤Ê¤¤(ƱµÁ: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\tÆÃÄê¤Î¥ê¥½¡¼¥¹¤ò»ÈÍѤ¹¤ë"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim¤Ë¤è¤Ã¤Æ²ò¼á¤µ¤ì¤ë°ú¿ô(GTK+¥Ð¡¼¥¸¥ç¥ó):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\t<display> ¤Çvim¤ò¼Â¹Ô¤¹¤ë(ƱµÁ: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\t¥á¥¤¥ó¥¦¥£¥ó¥É¥¦¤ò¼±Ê̤¹¤ë°ì°Õ¤ÊÌò³ä(role)¤òÀßÄꤹ¤ë"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\t°Û¤Ê¤ëGTK widget¤ÇVim¤ò³«¤¯"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\t¥¦¥£¥ó¥É¥¦ID¤òɸ½à½ÐÎϤ˽ÐÎϤ¹¤ë"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <¿Æ¤Î¥¿¥¤¥È¥ë>\tVim¤ò¿Æ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÃæ¤Çµ¯Æ°¤¹¤ë"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\t°Û¤Ê¤ëWin32 widget¤ÎÆâÉô¤ËVim¤ò³«¤¯"
-
-#~ msgid "No display"
-#~ msgstr "¥Ç¥£¥¹¥×¥ì¥¤¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Á÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿. ¥í¡¼¥«¥ë¤Ç¤Î¼Â¹Ô¤ò»î¤ß¤Æ¤¤¤Þ¤¹\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d ¸Ä (%d ¸ÄÃæ) ¤Î¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Þ¤·¤¿"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "¥Ç¥£¥¹¥×¥ì¥¤¤¬¤¢¤ê¤Þ¤»¤ó: ¼°¤ÎÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": ¼°¤ÎÁ÷¿®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: ̵¸ú¤Ê¥³¡¼¥É¥Ú¡¼¥¸¤Ç¤¹"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: IC¤ÎÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: path¤Ë¤Ï \"%s\" ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: ¥¤¥ó¥×¥Ã¥È¥³¥ó¥Æ¥­¥¹¥È¤ÎºîÀ®¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: ̵¸ú¤Ê ID: %ld (1 °Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó)"
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Î¥ª¡¼¥×¥ó¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID ¤Ï¤¹¤Ç¤ËÍøÍÑÃæ¤Ç¤¹: %ld"
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: ·Ù¹ð: IM¤ÎÇ˲õ¥³¡¼¥ë¥Ð¥Ã¥¯¤òÀßÄê¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "List or number required"
+msgstr "¥ê¥¹¥È¤«¿ôÃͤ¬É¬ÍפǤ¹"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Ï¤É¤ó¤Ê¥¹¥¿¥¤¥ë¤â¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: ̵¸ú¤Ê ID: %ld (1 °Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó)"
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: ¥¤¥ó¥×¥Ã¥È¥á¥½¥Ã¥É¤Ï my preedit type ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó"
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID ¤Ï¤¢¤ê¤Þ¤»¤ó: %ld"
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î°Å¹æ¤ò¹¹¿·Ãæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
+msgid "Edit with &multiple Vims"
+msgstr "Ê£¿ô¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&M)"
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr ""
-#~ "E833: %s ¤Ï¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ÎVim¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤·Á¼°¤Ç°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹"
+msgid "Edit with single &Vim"
+msgstr "1¤Ä¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&V)"
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Ï°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: \"%s\""
+msgid "Diff with Vim"
+msgstr "Vim¤Çº¹Ê¬¤òɽ¼¨¤¹¤ë"
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "¿·¤·¤¤°Å¹æ¥­¡¼¤òÆþÎϤ·¤¿¤¢¤È¤Ë¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï,"
+msgid "Edit with &Vim"
+msgstr "Vim¤ÇÊÔ½¸¤¹¤ë (&V)"
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "¿·¤·¤¤°Å¹æ¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤."
+msgid "Edit with existing Vim - "
+msgstr "µ¯Æ°ºÑ¤ÎVim¤ÇÊÔ½¸¤¹¤ë - "
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "°Å¹æ¥­¡¼¤òÊѤ¨¤¿¤¢¤È¤Ë¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤òÊݸ¤·¤¿¾ì¹ç¤Ï, ¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤È"
+msgid "Edits the selected file(s) with Vim"
+msgstr "ÁªÂò¤·¤¿¥Õ¥¡¥¤¥ë¤òVim¤ÇÊÔ½¸¤¹¤ë"
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤ËƱ¤¸°Å¹æ¥­¡¼¤ò»È¤¦¤¿¤á¤Ëenter¤À¤±¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤."
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "¥×¥í¥»¥¹¤ÎºîÀ®¤Ë¼ºÇÔ: gvim¤¬´Ä¶­ÊÑ¿ôPATH¾å¤Ë¤¢¤ë¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤!"
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤«¤é¼èÆÀ¤·¤¿°Å¹æ¥­¡¼¤ò¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤Ë»È¤¤¤Þ¤¹.\n"
+msgid "gvimext.dll error"
+msgstr "gvimext.dll ¥¨¥é¡¼"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [¤³¤ÎVim¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó]"
+msgid "Path length too long!"
+msgstr "¥Ñ¥¹¤¬Ä¹²á¤®¤Þ¤¹!"
-#~ msgid "Tear off this menu"
-#~ msgstr "¤³¤Î¥á¥Ë¥å¡¼¤òÀÚ¤ê¼è¤ë"
+msgid "--No lines in buffer--"
+msgstr "--¥Ð¥Ã¥Õ¥¡¤Ë¹Ô¤¬¤¢¤ê¤Þ¤»¤ó--"
-#~ msgid "Select Directory dialog"
-#~ msgstr "¥Ç¥£¥ì¥¯¥È¥êÁªÂò¥À¥¤¥¢¥í¥°"
+msgid "E470: Command aborted"
+msgstr "E470: ¥³¥Þ¥ó¥É¤¬ÃæÃǤµ¤ì¤Þ¤·¤¿"
-#~ msgid "Save File dialog"
-#~ msgstr "¥Õ¥¡¥¤¥ëÊݸ¥À¥¤¥¢¥í¥°"
+msgid "E471: Argument required"
+msgstr "E471: °ú¿ô¤¬É¬ÍפǤ¹"
-#~ msgid "Open File dialog"
-#~ msgstr "¥Õ¥¡¥¤¥ëÆÉ¹þ¥À¥¤¥¢¥í¥°"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ ¤Î¸å¤Ï / ¤« ? ¤« & ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr ""
-#~ "E338: ¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤Ç¤Ï¥Õ¥¡¥¤¥ë¥Ö¥é¥¦¥¶¤ò»È¤¨¤Þ¤»¤ó, ¤´¤á¤ó¤Ê¤µ¤¤"
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: ¥³¥Þ¥ó¥É¥é¥¤¥ó¤Ç¤Ï̵¸ú¤Ç¤¹; <CR>¤Ç¼Â¹Ô, CTRL-C¤Ç¤ä¤á¤ë"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: ¥Õ¥¡¥¤¥ë¤òÊÝÂ¸Ãæ...\n"
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ä¥¿¥°¸¡º÷¤Ç¤Ïexrc/vimrc¤Î¥³¥Þ¥ó¥É¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: ½ªÎ»¤·¤Þ¤·¤¿.\n"
+msgid "E171: Missing :endif"
+msgstr "E171: :endif ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "ERROR: "
-#~ msgstr "¥¨¥é¡¼: "
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[¥á¥â¥ê(¥Ð¥¤¥È)] Áí³äÅö-²òÊüÎÌ %<PRIu64>-%<PRIu64>, »ÈÍÑÎÌ %<PRIu64>, ¥Ô¡¼"
-#~ "¥¯»þ %<PRIu64>\n"
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[¸Æ½Ð] Áí re/malloc() ²ó¿ô %<PRIu64>, Áí free() ²ó¿ô %<PRIu64>\n"
-#~ "\n"
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: ¹Ô¤¬Ä¹¤¯¤Ê¤ê²á¤®¤Þ¤·¤¿"
+msgid "E588: :endwhile without :while"
+msgstr "E588: :while ¤Î¤Ê¤¤ :endwhile ¤¬¤¢¤ê¤Þ¤¹"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: ÆâÉô¥¨¥é¡¼: lalloc(%<PRId64>,)"
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor ¤Î¤Ê¤¤ :for ¤¬¤¢¤ê¤Þ¤¹"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: ÉÔÀµ¤Ê 'mouseshape' ¤Ç¤¹"
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: ¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Þ¤¹ (! ¤òÄɲäǾå½ñ)"
-#~ msgid "Enter encryption key: "
-#~ msgstr "°Å¹æ²½ÍѤΥ­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+msgid "E472: Command failed"
+msgstr "E472: ¥³¥Þ¥ó¥É¤¬¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "Enter same key again: "
-#~ msgstr "¤â¤¦°ìÅÙÆ±¤¸¥­¡¼¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤: "
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: ̤ÃΤΥե©¥ó¥È¥»¥Ã¥È: %s"
-#~ msgid "Keys don't match!"
-#~ msgstr "¥­¡¼¤¬°ìÃפ·¤Þ¤»¤ó"
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: ̤ÃΤΥե©¥ó¥È: %s"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Netbeans #2 ¤ËÀܳ¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: ¥Õ¥©¥ó¥È \"%s\" ¤Ï¸ÇÄêÉý¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Netbeans ¤ËÀܳ¤Ç¤­¤Þ¤»¤ó"
+msgid "E473: Internal error"
+msgstr "E473: ÆâÉô¥¨¥é¡¼¤Ç¤¹"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: NetBeans¤ÎÀܳ¾ðÊó¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹¥â¡¼¥É¤ËÌäÂ꤬¤¢¤ê¤Þ¤¹: \"%s\""
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: ÆâÉô¥¨¥é¡¼¤Ç¤¹: %s"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "Netbeans ¤Î¥½¥±¥Ã¥È¤òÆÉ¹þ¤ß"
+msgid "Interrupted"
+msgstr "³ä¹þ¤Þ¤ì¤Þ¤·¤¿"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: ¥Ð¥Ã¥Õ¥¡ %<PRId64> ¤Î NetBeans Àܳ¤¬¼º¤ï¤ì¤Þ¤·¤¿"
+msgid "E14: Invalid address"
+msgstr "E14: ̵¸ú¤Ê¥¢¥É¥ì¥¹¤Ç¤¹"
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: NetBeans¤Ï¤³¤ÎGUI¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó"
+msgid "E474: Invalid argument"
+msgstr "E474: ̵¸ú¤Ê°ú¿ô¤Ç¤¹"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: NetBeans¤Ï´û¤ËÀܳ¤·¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: ̵¸ú¤Ê°ú¿ô¤Ç¤¹: %s"
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s ¤ÏÆÉ¹þÀìÍѤǤ¹ (¶¯À©½ñ¹þ¤Ë¤Ï ! ¤òÄɲÃ)"
+#, c-format
+msgid "E475: Invalid value for argument %s"
+msgstr "E475: °ú¿ô %s ¤ËÂФ·¤ÆÌµ¸ú¤ÊÃͤǤ¹"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: ¼°É¾²Áµ¡Ç½¤¬Ìµ¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid "E475: Invalid value for argument %s: %s"
+msgstr "E475: °ú¿ô %s ¤ËÂФ·¤ÆÌµ¸ú¤ÊÃͤǤ¹: %s"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "%<PRId64> ¹Ô¤ò²òÊüÃæ"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: ̵¸ú¤Ê¼°¤Ç¤¹: %s"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: GUI¤Ç¤Ï 'term' ¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+msgid "E16: Invalid range"
+msgstr "E16: ̵¸ú¤ÊÈϰϤǤ¹"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: GUI¤ò¥¹¥¿¡¼¥È¤¹¤ë¤Ë¤Ï \":gui\" ¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤"
+msgid "E476: Invalid command"
+msgstr "E476: ̵¸ú¤Ê¥³¥Þ¥ó¥É¤Ç¤¹"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: GTK+2 GUI¤Ç¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" ¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: ̵¸ú¤Ê¥Õ¥©¥ó¥È¤Ç¤¹"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: \"%s\"() ¤Î¥é¥¤¥Ö¥é¥ê¸Æ½Ð¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ¥Õ¥©¥ó¥È¥»¥Ã¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+msgid "E667: Fsync failed"
+msgstr "E667: fsync ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: ̵¸ú¤Ê¥Õ¥©¥ó¥È¥»¥Ã¥È¤Ç¤¹"
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: ¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô %s ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ¥ï¥¤¥É¥Õ¥©¥ó¥È¤òÁªÂò¤Ç¤­¤Þ¤»¤ó"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: ¥Þ¡¼¥¯¤Ë̵¸ú¤Ê¹ÔÈֹ椬»ØÄꤵ¤ì¤Æ¤¤¤Þ¤·¤¿"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: ̵¸ú¤Ê¥ï¥¤¥É¥Õ¥©¥ó¥È¤Ç¤¹"
+msgid "E20: Mark not set"
+msgstr "E20: ¥Þ¡¼¥¯¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: ¥Þ¥¦¥¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: 'modifiable' ¤¬¥ª¥Õ¤Ê¤Î¤Ç¡¢Êѹ¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "cannot open "
-#~ msgstr "³«¤±¤Þ¤»¤ó "
+msgid "E22: Scripts nested too deep"
+msgstr "E22: ¥¹¥¯¥ê¥×¥È¤ÎÆþ¤ì»Ò¤¬¿¼²á¤®¤Þ¤¹"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: ¥¦¥£¥ó¥É¥¦¤ò³«¤±¤Þ¤»¤ó!\n"
+msgid "E23: No alternate file"
+msgstr "E23: Éû¥Õ¥¡¥¤¥ë¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigados¤Î¥Ð¡¼¥¸¥ç¥ó 2.04¤«¤½¤ì°Ê¹ß¤¬É¬ÍפǤ¹\n"
+msgid "E24: No such abbreviation"
+msgstr "E24: ¤½¤Î¤è¤¦¤Êû½ÌÆþÎϤϤ¢¤ê¤Þ¤»¤ó"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "%s ¤Î¥Ð¡¼¥¸¥ç¥ó %<PRId64> ¤¬É¬ÍפǤ¹\n"
+msgid "E477: No ! allowed"
+msgstr "E477: ! ¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "NIL¤ò³«¤±¤Þ¤»¤ó:\n"
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "Cannot create "
-#~ msgstr "ºîÀ®¤Ç¤­¤Þ¤»¤ó "
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: ¥Ø¥Ö¥é¥¤¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim¤Ï %d ¤Ç½ªÎ»¤·¤Þ¤¹\n"
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: ¥Ú¥ë¥·¥¢¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "¥³¥ó¥½¡¼¥ë¥â¡¼¥É¤òÊѹ¹¤Ç¤­¤Þ¤»¤ó?!\n"
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: ¥¢¥é¥Ó¥¢¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ¥³¥ó¥½¡¼¥ë¤Ç¤Ï¤Ê¤¤??\n"
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: ¤½¤Î¤è¤¦¤Ê̾¤Î¥Ï¥¤¥é¥¤¥È¥°¥ë¡¼¥×¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: -f ¥ª¥×¥·¥ç¥ó¤Ç¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó"
+msgid "E29: No inserted text yet"
+msgstr "E29: ¤Þ¤À¥Æ¥­¥¹¥È¤¬ÁÞÆþ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "Cannot execute "
-#~ msgstr "¼Â¹Ô¤Ç¤­¤Þ¤»¤ó "
+msgid "E30: No previous command line"
+msgstr "E30: °ÊÁ°¤Ë¥³¥Þ¥ó¥É¹Ô¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "shell "
-#~ msgstr "¥·¥§¥ë "
+msgid "E31: No such mapping"
+msgstr "E31: ¤½¤Î¤è¤¦¤Ê¥Þ¥Ã¥Ô¥ó¥°¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid " returned\n"
-#~ msgstr " Ìá¤ê¤Þ¤·¤¿\n"
+msgid "E479: No match"
+msgstr "E479: ³ºÅö¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE ¤¬¾®¤µ²á¤®¤Þ¤¹."
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: ³ºÅö¤Ï¤¢¤ê¤Þ¤»¤ó: %s"
-#~ msgid "I/O ERROR"
-#~ msgstr "Æþ½ÐÎÏ¥¨¥é¡¼"
+msgid "E32: No file name"
+msgstr "E32: ¥Õ¥¡¥¤¥ë̾¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Message"
-#~ msgstr "¥á¥Ã¥»¡¼¥¸"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Àµµ¬É½¸½ÃÖ´¹¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ¤¬80¤Ç¤Ï¤Ê¤¤¤¿¤á, ³°Éô¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó"
+msgid "E34: No previous command"
+msgstr "E34: ¥³¥Þ¥ó¥É¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: ¥×¥ê¥ó¥¿¤ÎÁªÂò¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E35: No previous regular expression"
+msgstr "E35: Àµµ¬É½¸½¤¬¤Þ¤À¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "to %s on %s"
-#~ msgstr "%s ¤Ø (%s ¾å¤Î)"
+msgid "E481: No range allowed"
+msgstr "E481: ÈϰϻØÄê¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: ̤ÃΤΥץê¥ó¥¿¥ª¥×¥·¥ç¥ó¤Ç¤¹: %s"
+msgid "E36: Not enough room"
+msgstr "E36: ¥¦¥£¥ó¥É¥¦¤Ë½½Ê¬¤Ê¹â¤µ¤â¤·¤¯¤ÏÉý¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: °õºþ¥¨¥é¡¼: %s"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: %s ¤È¤¤¤¦Ì¾Á°¤ÎÅÐÏ¿¤µ¤ì¤¿¥µ¡¼¥Ð¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Printing '%s'"
-#~ msgstr "°õºþ¤·¤Æ¤¤¤Þ¤¹: '%s'"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: ʸ»ú¥»¥Ã¥È̾ \"%s\" ¤ÏÉÔÀµ¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+msgid "E483: Can't get temp file name"
+msgstr "E483: °ì»þ¥Õ¥¡¥¤¥ë¤Î̾Á°¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: '%c' ¤ÏÉÔÀµ¤Êʸ»ú¤Ç¤¹ (¥Õ¥©¥ó¥È̾ \"%s\")"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: ¥Õ¥¡¥¤¥ë \"%s\" ¤ò³«¤±¤Þ¤»¤ó"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: 2½Å¤Î¥·¥°¥Ê¥ë¤Î¤¿¤á, ½ªÎ»¤·¤Þ¤¹\n"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: ¥Õ¥¡¥¤¥ë %s ¤òÆÉ¹þ¤á¤Þ¤»¤ó"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Ã×̿Ū¥·¥°¥Ê¥ë %s ¤ò¸¡ÃΤ·¤Þ¤·¤¿\n"
+msgid "E38: Null argument"
+msgstr "E38: °ú¿ô¤¬¶õ¤Ç¤¹"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Ã×̿Ū¥·¥°¥Ê¥ë¤ò¸¡ÃΤ·¤Þ¤·¤¿\n"
+msgid "E39: Number expected"
+msgstr "E39: ¿ôÃͤ¬Í׵ᤵ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "X¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤Ë %<PRId64> ¥ß¥êÉ䫤«¤ê¤Þ¤·¤¿"
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë %s ¤ò³«¤±¤Þ¤»¤ó"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: X ¤Î¥¨¥é¡¼¤ò¸¡½Ð¤·¤Þ¤·¤¿r\n"
+msgid "E233: cannot open display"
+msgstr "E233: ¥Ç¥£¥¹¥×¥ì¥¤¤ò³«¤±¤Þ¤»¤ó"
-#~ msgid "Testing the X display failed"
-#~ msgstr "X display ¤Î¥Á¥§¥Ã¥¯¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E41: Out of memory!"
+msgstr "E41: ¥á¥â¥ê¤¬¿Ô¤­²Ì¤Æ¤Þ¤·¤¿!"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "X display ¤Î open ¤¬¥¿¥¤¥à¥¢¥¦¥È¤·¤Þ¤·¤¿"
+msgid "Pattern not found"
+msgstr "¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "sh ¥·¥§¥ë¤ò¼Â¹Ô¤Ç¤­¤Þ¤»¤ó\n"
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: ¥Ñ¥¿¡¼¥ó¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó¤Ç¤·¤¿: %s"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¥Ñ¥¤¥×¤òºîÀ®¤Ç¤­¤Þ¤»¤ó\n"
+msgid "E487: Argument must be positive"
+msgstr "E487: °ú¿ô¤ÏÀµ¤ÎÃͤǤʤ±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "fork ¤Ç¤­¤Þ¤»¤ó\n"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Á°¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ËÌá¤ì¤Þ¤»¤ó"
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¥³¥Þ¥ó¥É¤òÃæÃǤ·¤Þ¤·¤¿\n"
+msgid "E42: No Errors"
+msgstr "E42: ¥¨¥é¡¼¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP ¤¬ICEÀܳ¤ò¼º¤¤¤Þ¤·¤¿"
+msgid "E776: No location list"
+msgstr "E776: ¥í¥±¡¼¥·¥ç¥ó¥ê¥¹¥È¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Opening the X display failed"
-#~ msgstr "X display ¤Î open ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E43: Damaged match string"
+msgstr "E43: ³ºÅöʸ»úÎó¤¬ÇË»¤·¤Æ¤¤¤Þ¤¹"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP ¤¬save-yourselfÍ×µá¤ò½èÍý¤·¤Æ¤¤¤Þ¤¹"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: ÉÔÀµ¤ÊÀµµ¬É½¸½¥×¥í¥°¥é¥à¤Ç¤¹"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP ¤¬Àܳ¤ò³«»Ï¤·¤Æ¤¤¤Þ¤¹"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly' ¥ª¥×¥·¥ç¥ó¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹ (! ¤òÄɲäǾå½ñ¤­)"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICEÀܳ¤¬¼ºÇÔ¤·¤¿¤è¤¦¤Ç¤¹"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: ÆÉ¼èÀìÍÑÊÑ¿ô \"%s\" ¤Ë¤ÏÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection¤¬¼ºÇÔ¤·¤Þ¤·¤¿: %s"
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤ÏÊÑ¿ô \"%s\" ¤ËÃͤòÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "At line"
-#~ msgstr "¹Ô"
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: ¼­½ñ·¿¤Ë¶õ¤Î¥­¡¼¤ò»È¤¦¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "vim32.dll ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "E715: Dictionary required"
+msgstr "E715: ¼­½ñ·¿¤¬É¬ÍפǤ¹"
-#~ msgid "VIM Error"
-#~ msgstr "VIM¥¨¥é¡¼"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: ¥ê¥¹¥È¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬Èϰϳ°¤Ç¤¹: %ld"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "DLL¤«¤é´Ø¿ô¥Ý¥¤¥ó¥¿¤ò¼èÆÀ¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: ´Ø¿ô¤Î°ú¿ô¤¬Â¿²á¤®¤Þ¤¹: %s"
-#~ msgid "shell returned %d"
-#~ msgstr "¥·¥§¥ë¤¬¥³¡¼¥É %d ¤Ç½ªÎ»¤·¤Þ¤·¤¿"
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: ¼­½ñ·¿¤Ë¥­¡¼¤¬Â¸ºß¤·¤Þ¤»¤ó: %s"
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: ¥¤¥Ù¥ó¥È %s ¤ò¸¡ÃÎ\n"
+msgid "E714: List required"
+msgstr "E714: ¥ê¥¹¥È·¿¤¬É¬ÍפǤ¹"
-#~ msgid "close"
-#~ msgstr "ÊĤ¸¤ë"
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ¤Î°ú¿ô¤Ï¥ê¥¹¥È·¿¤Þ¤¿¤Ï¼­½ñ·¿¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "logoff"
-#~ msgstr "¥í¥°¥ª¥Õ"
+msgid "E47: Error while reading errorfile"
+msgstr "E47: ¥¨¥é¡¼¥Õ¥¡¥¤¥ë¤ÎÆÉ¹þÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿"
-#~ msgid "shutdown"
-#~ msgstr "¥·¥ã¥Ã¥È¥À¥¦¥ó"
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: ¥µ¥ó¥É¥Ü¥Ã¥¯¥¹¤Ç¤Ïµö¤µ¤ì¤Þ¤»¤ó"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: ¥³¥Þ¥ó¥É¤¬¤¢¤ê¤Þ¤»¤ó"
-
-#~ 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 ""
-#~ "VIMRUN.EXE¤¬ $PATH ¤ÎÃæ¤Ë¸«¤Ä¤«¤ê¤Þ¤»¤ó.\n"
-#~ "³°Éô¥³¥Þ¥ó¥É¤Î½ªÎ»¸å¤Ë°ì»þÄä»ß¤ò¤·¤Þ¤»¤ó.\n"
-#~ "¾ÜºÙ¤Ï :help win32-vimrun ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Vim¤Î·Ù¹ð"
-
-#~ msgid "Error file"
-#~ msgstr "¥¨¥é¡¼¥Õ¥¡¥¤¥ë"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: Åù²Á¥¯¥é¥¹¤ò´Þ¤àNFA¹½Ãۤ˼ºÇÔ¤·¤Þ¤·¤¿!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) ¸½ºß²£ÃÇÃæ¤Î¥Ö¥é¥ó¥Á¤Ë½½Ê¬¤Ê¥á¥â¥ê¤ò³ä¤êÅö¤Æ¤é¤ì¤Þ¤»¤ó!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "·Ù¹ð: ñ¸ì¥ê¥¹¥È \"%s_%s.spl\" ¤ª¤è¤Ó \"%s_ascii.spl\" ¤Ï¸«¤Ä¤«¤ê¤Þ¤»¤ó"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "%s Æâ¤ÎÊÑ´¹¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: ¥á¥â¥ê¤¬Â­¤ê¤Ê¤¤¤Î¤Ç¡¢Ã±¸ì¥ê¥¹¥È¤ÏÉÔ´°Á´¤Ç¤¹"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: ¥¿¥°¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤¬ %s ¤ËÀÚ¤ê¼Î¤Æ¤é¤ì¤Þ¤·¤¿\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "¿·¤·¤¤¥·¥§¥ë¤òµ¯Æ°¤·¤Þ¤¹\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "¶õ¤ÎÁªÂòÎΰè¤Î¤«¤ï¤ê¤ËCUT_BUFFER0¤¬»ÈÍѤµ¤ì¤Þ¤·¤¿"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "²Äǽ¤Ê¥¢¥ó¥É¥¥¤Ï¤¢¤ê¤Þ¤»¤ó: ¤È¤ê¤¢¤¨¤ºÂ³¤±¤Þ¤¹"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr ""
-#~ "E832: Èó°Å¹æ²½¥Õ¥¡¥¤¥ë¤¬°Å¹æ²½¤µ¤ì¤¿¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ¤Þ¤¹: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: °Å¹æ²½¤µ¤ì¤¿¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤Î²òÆÉ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: ¥¢¥ó¥É¥¥¥Õ¥¡¥¤¥ë¤¬°Å¹æ²½¤µ¤ì¤Æ¤¤¤Þ¤¹: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 ¥Ó¥Ã¥È GUI ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ¥Ó¥Ã¥È GUI ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ¥Ó¥Ã¥È GUI ÈÇ"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " in Win32s ¥â¡¼¥É"
-
-#~ msgid " with OLE support"
-#~ msgstr " with OLE ¥µ¥Ý¡¼¥È"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ¥Ó¥Ã¥È ¥³¥ó¥½¡¼¥ë ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ¥Ó¥Ã¥È ¥³¥ó¥½¡¼¥ë ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16 ¥Ó¥Ã¥È ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 ¥Ó¥Ã¥È MS-DOS ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 ¥Ó¥Ã¥È MS-DOS ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "OpenVMS ÈÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Big ÈÇ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Ä̾ï ÈÇ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Small ÈÇ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Tiny ÈÇ "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "with GTK2-GNOME GUI."
+msgid "E523: Not allowed here"
+msgstr "E523: ¤³¤³¤Ç¤Ïµö²Ä¤µ¤ì¤Þ¤»¤ó"
-#~ msgid "with GTK2 GUI."
-#~ msgstr "with GTK2 GUI."
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: ¥¹¥¯¥ê¡¼¥ó¥â¡¼¥É¤ÎÀßÄê¤Ë¤ÏÂбþ¤·¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "with X11-Motif GUI."
+msgid "E49: Invalid scroll size"
+msgstr "E49: ̵¸ú¤Ê¥¹¥¯¥í¡¼¥ëÎ̤Ǥ¹"
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "with X11-neXtaw GUI."
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell' ¥ª¥×¥·¥ç¥ó¤¬¶õ¤Ç¤¹"
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "with X11-Athena GUI."
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: sign ¤Î¥Ç¡¼¥¿¤òÆÉ¹þ¤á¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "with Photon GUI."
-#~ msgstr "with Photon GUI."
+msgid "E72: Close error on swap file"
+msgstr "E72: ¥¹¥ï¥Ã¥×¥Õ¥¡¥¤¥ë¤Î¥¯¥í¡¼¥º»þ¥¨¥é¡¼¤Ç¤¹"
-#~ msgid "with GUI."
-#~ msgstr "with GUI."
+msgid "E73: tag stack empty"
+msgstr "E73: ¥¿¥°¥¹¥¿¥Ã¥¯¤¬¶õ¤Ç¤¹"
-#~ msgid "with Carbon GUI."
-#~ msgstr "with Carbon GUI."
+msgid "E74: Command too complex"
+msgstr "E74: ¥³¥Þ¥ó¥É¤¬Ê£»¨²á¤®¤Þ¤¹"
-#~ msgid "with Cocoa GUI."
-#~ msgstr "with Cocoa GUI."
+msgid "E75: Name too long"
+msgstr "E75: ̾Á°¤¬Ä¹²á¤®¤Þ¤¹"
-#~ msgid "with (classic) GUI."
-#~ msgstr "with (¥¯¥é¥·¥Ã¥¯) GUI."
+msgid "E76: Too many ["
+msgstr "E76: [ ¤¬Â¿²á¤®¤Þ¤¹"
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ¥·¥¹¥Æ¥à gvimrc: \""
+msgid "E77: Too many file names"
+msgstr "E77: ¥Õ¥¡¥¤¥ë̾¤¬Â¿²á¤®¤Þ¤¹"
-#~ msgid " user gvimrc file: \""
-#~ msgstr " ¥æ¡¼¥¶ gvimrc: \""
+msgid "E488: Trailing characters"
+msgstr "E488: ;ʬ¤Êʸ»ú¤¬¸å¤í¤Ë¤¢¤ê¤Þ¤¹"
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " Âè2¥æ¡¼¥¶ gvimrc: \""
+msgid "E78: Unknown mark"
+msgstr "E78: ̤ÃΤΥޡ¼¥¯"
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " Âè3¥æ¡¼¥¶ gvimrc: \""
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: ¥ï¥¤¥ë¥É¥«¡¼¥É¤òŸ³«¤Ç¤­¤Þ¤»¤ó"
-#~ msgid " system menu file: \""
-#~ msgstr " ¥·¥¹¥Æ¥à¥á¥Ë¥å¡¼: \""
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' ¤Ï 'winminheight' ¤è¤ê¾®¤µ¤¯¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "Compiler: "
-#~ msgstr "¥³¥ó¥Ñ¥¤¥é: "
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' ¤Ï 'winminwidth' ¤è¤ê¾®¤µ¤¯¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "¾ÜºÙ¤Ï¥á¥Ë¥å¡¼¤Î ¥Ø¥ë¥×¢ª¸É»ù ¤ò»²¾È¤·¤Æ²¼¤µ¤¤ "
+msgid "E80: Error while writing"
+msgstr "E80: ½ñ¹þ¤ßÃæ¤Î¥¨¥é¡¼"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "¥â¡¼¥É̵¤Ç¼Â¹ÔÃæ, ¥¿¥¤¥×¤·¤¿Ê¸»ú¤¬ÁÞÆþ¤µ¤ì¤Þ¤¹"
+msgid "E939: Positive count required"
+msgstr "E939: Àµ¤Î¥«¥¦¥ó¥È¤¬É¬ÍפǤ¹"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸¢ªÁ´ÂÎÀßÄꢪÁÞÆþ(½é¿´¼Ô)¥â¡¼¥ÉÀÚÂØ "
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: ¥¹¥¯¥ê¥×¥È°Ê³°¤Ç<SID>¤¬»È¤ï¤ì¤Þ¤·¤¿"
-#~ msgid " for two modes "
-#~ msgstr " ¤Ç¥â¡¼¥ÉÍ­¤Ë "
+msgid "E449: Invalid expression received"
+msgstr "E449: ̵¸ú¤Ê¼°¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿"
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "¥á¥Ë¥å¡¼¤Î ÊÔ½¸¢ªÁ´ÂÎÀßÄꢪVi¸ß´¹¥â¡¼¥ÉÀÚÂØ "
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Îΰ褬Êݸ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢Êѹ¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid " for Vim defaults "
-#~ msgstr " ¤ÇVim¤È¤·¤ÆÆ°ºî "
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ¤ÏÆÉ¹þÀìÍÑ¥Õ¥¡¥¤¥ë¤òÊѹ¹¤¹¤ë¤³¤È¤òµö¤·¤Þ¤»¤ó"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr " ·Ù¹ð: Windows 95/98/Me ¤ò¸¡½Ð "
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: ¥Ñ¥¿¡¼¥ó¤¬ 'maxmempattern' °Ê¾å¤Î¥á¥â¥ê¤ò»ÈÍѤ·¤Þ¤¹"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr " ¾ÜºÙ¤Ê¾ðÊó¤Ï :help windows95<Enter> "
+msgid "E749: empty buffer"
+msgstr "E749: ¥Ð¥Ã¥Õ¥¡¤¬¶õ¤Ç¤¹"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Ê£¿ô¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&M)"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ¥Ð¥Ã¥Õ¥¡ %ld ¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "1¤Ä¤ÎVim¤ÇÊÔ½¸¤¹¤ë (&V)"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: ¸¡º÷¥Ñ¥¿¡¼¥ó¤«¶èÀڤ국¹æ¤¬ÉÔÀµ¤Ç¤¹"
-#~ msgid "Diff with Vim"
-#~ msgstr "Vim¤Çº¹Ê¬¤òɽ¼¨¤¹¤ë"
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Ʊ¤¸Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¾¤Î¥Ð¥Ã¥Õ¥¡¤ÇÆÉ¹þ¤Þ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Vim¤ÇÊÔ½¸¤¹¤ë (&V)"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: ¥ª¥×¥·¥ç¥ó '%s' ¤ÏÀßÄꤵ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "µ¯Æ°ºÑ¤ÎVim¤ÇÊÔ½¸¤¹¤ë - "
+msgid "E850: Invalid register name"
+msgstr "E850: ̵¸ú¤Ê¥ì¥¸¥¹¥¿Ì¾¤Ç¤¹"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "ÁªÂò¤·¤¿¥Õ¥¡¥¤¥ë¤òVim¤ÇÊÔ½¸¤¹¤ë"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: ¥Ç¥£¥ì¥¯¥È¥ê¤¬ '%s' ¤ÎÃæ¤Ë¤¢¤ê¤Þ¤»¤ó: \"%s\""
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "¥×¥í¥»¥¹¤ÎºîÀ®¤Ë¼ºÇÔ: gvim¤¬´Ä¶­ÊÑ¿ôPATH¾å¤Ë¤¢¤ë¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤!"
+msgid "E952: Autocommand caused recursive behavior"
+msgstr "E952: Autocommand¤¬ºÆµ¢¤ò°ú¤­µ¯¤³¤·¤Þ¤·¤¿"
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll ¥¨¥é¡¼"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "¾å¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç²¼¤ËÌá¤ê¤Þ¤¹"
-#~ msgid "Path length too long!"
-#~ msgstr "¥Ñ¥¹¤¬Ä¹¤¹¤®¤Þ¤¹!"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "²¼¤Þ¤Ç¸¡º÷¤·¤¿¤Î¤Ç¾å¤ËÌá¤ê¤Þ¤¹"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: ̤ÃΤΥե©¥ó¥È¥»¥Ã¥È: %s"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "°Å¹æ¥­¡¼¤¬É¬ÍפǤ¹: \"%s\""
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: ̤ÃΤΥե©¥ó¥È: %s"
+msgid "empty keys are not allowed"
+msgstr "¶õ¤Î¥­¡¼¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: ¥Õ¥©¥ó¥È \"%s\" ¤Ï¸ÇÄêÉý¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "dictionary is locked"
+msgstr "¼­½ñ¤Ï¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: ¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô %s ¤ò¥í¡¼¥É¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "list is locked"
+msgstr "¥ê¥¹¥È¤Ï¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: ¥Ø¥Ö¥é¥¤¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "¼­½ñ¤Ë¥­¡¼ '%s' ¤òÄɲ乤ë¤Î¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: ¥Ú¥ë¥·¥¢¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï %s ¤Ç¤Ï¤Ê¤¯À°¿ô¤«¥¹¥é¥¤¥¹¤Ë¤·¤Æ¤¯¤À¤µ¤¤"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: ¥¢¥é¥Ó¥¢¸ì¤Ï»ÈÍÑÉÔ²Äǽ¤Ç¤¹: ¥³¥ó¥Ñ¥¤¥ë»þ¤Ë̵¸ú¤Ë¤µ¤ì¤Æ¤¤¤Þ¤¹\n"
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "str() ¤â¤·¤¯¤Ï unicode() ¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: %s ¤È¤¤¤¦Ì¾Á°¤ÎÅÐÏ¿¤µ¤ì¤¿¥µ¡¼¥Ð¤Ï¤¢¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "bytes() ¤â¤·¤¯¤Ï str() ¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ¥Ç¥£¥¹¥×¥ì¥¤¤ò³«¤±¤Þ¤»¤ó"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr "long() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: ̵¸ú¤Ê¼°¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr "int() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Îΰ褬Êݸ¤ì¤Æ¤¤¤ë¤Î¤Ç, Êѹ¹¤Ç¤­¤Þ¤»¤ó"
+msgid "value is too large to fit into C int type"
+msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬Â礭²á¤®¤Þ¤¹"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ¤ÏÆÉ¹þÀìÍÑ¥Õ¥¡¥¤¥ë¤òÊѹ¹¤¹¤ë¤³¤È¤òµö¤·¤Þ¤»¤ó"
+msgid "value is too small to fit into C int type"
+msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬¾®¤µ²á¤®¤Þ¤¹"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "°Å¹æ¥­¡¼¤¬É¬ÍפǤ¹: \"%s\""
+msgid "number must be greater than zero"
+msgstr "¿ôÃÍ¤Ï 0 ¤è¤êÂ礭¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "empty keys are not allowed"
-#~ msgstr "¶õ¤Î¥­¡¼¤Ïµö²Ä¤µ¤ì¤Æ¤¤¤Þ¤»¤ó"
+msgid "number must be greater or equal to zero"
+msgstr "¿ôÃÍ¤Ï 0 ¤«¤½¤ì°Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "dictionary is locked"
-#~ msgstr "¼­½ñ¤Ï¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹"
+msgid "can't delete OutputObject attributes"
+msgstr "OutputObject°À­¤ò¾Ã¤»¤Þ¤»¤ó"
-#~ msgid "list is locked"
-#~ msgstr "¥ê¥¹¥È¤Ï¥í¥Ã¥¯¤µ¤ì¤Æ¤¤¤Þ¤¹"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "̵¸ú¤Ê°À­¤Ç¤¹: %s"
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "¼­½ñ¤Ë¥­¡¼ '%s' ¤òÄɲ乤ë¤Î¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: I/O¥ª¥Ö¥¸¥§¥¯¥È¤Î½é´ü²½¥¨¥é¡¼"
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï %s ¤Ç¤Ï¤Ê¤¯À°¿ô¤«¥¹¥é¥¤¥¹¤Ë¤·¤Æ¤¯¤À¤µ¤¤"
+msgid "failed to change directory"
+msgstr "¼­½ñ¤ÎÊѹ¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr ""
-#~ "str() ¤â¤·¤¯¤Ï unicode() ¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "imp.find_module() ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 3 Í×ÁǤΥ¿¥×¥ë)"
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "bytes() ¤â¤·¤¯¤Ï str() ¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "imp.find_module() ¤¬ %d Í×ÁǤΥ¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 3)"
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr "long() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "ÆâÉô¥¨¥é¡¼: imp.find_module ¤¬ NULL ¤ò´Þ¤à¥¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿"
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr "int() ¤«¤½¤ì¤ØÊÑ´¹²Äǽ¤Ê¤â¤Î¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "vim.Dictionary°À­¤Ï¾Ã¤»¤Þ¤»¤ó"
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬Â礭²á¤®¤Þ¤¹"
+msgid "cannot modify fixed dictionary"
+msgstr "¸ÇÄꤵ¤ì¤¿¼­½ñ¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "C¸À¸ì¤Î int ·¿¤È¤·¤Æ¤ÏÃͤ¬¾®¤µ²á¤®¤Þ¤¹"
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "°À­ %s ¤ÏÀßÄê¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "number must be greater then zero"
-#~ msgstr "¿ôÃÍ¤Ï 0 ¤è¤êÂ礭¤¯¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+msgid "hashtab changed during iteration"
+msgstr "¥¤¥Æ¥ì¡¼¥·¥ç¥óÃæ¤Ë hashtab ¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "¿ôÃÍ¤Ï 0 ¤«¤½¤ì°Ê¾å¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "¥·¡¼¥±¥ó¥¹¤ÎÍ×ÁÇ¿ô¤Ë¤Ï 2 ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤Þ¤·¤¿¤¬ %d ¤Ç¤·¤¿"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "OutputObject°À­¤ò¾Ã¤»¤Þ¤»¤ó"
+msgid "list constructor does not accept keyword arguments"
+msgstr "¥ê¥¹¥È¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï¥­¡¼¥ï¡¼¥É°ú¿ô¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó"
-#~ msgid "invalid attribute: %s"
-#~ msgstr "̵¸ú¤Ê°À­¤Ç¤¹: %s"
+msgid "list index out of range"
+msgstr "¥ê¥¹¥ÈÈϰϳ°¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¹"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: I/O¥ª¥Ö¥¸¥§¥¯¥È¤Î½é´ü²½¥¨¥é¡¼"
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Î¼èÆÀ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "failed to change directory"
-#~ msgstr "¼­½ñ¤ÎÊѹ¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "slice step cannot be zero"
+msgstr "¥¹¥é¥¤¥¹¤Î¥¹¥Æ¥Ã¥×¤Ë 0 ¤Ï»ØÄê¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "imp.find_module() ¤¬ %s ¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 2 Í×ÁǤΥ¿¥×¥ë)"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "Ťµ %d ¤Î³ÈÄ¥¥¹¥é¥¤¥¹¤Ë¡¢¤è¤êŤ¤¥¹¥é¥¤¥¹¤ò³ä¤êÅö¤Æ¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr "impl.find_module() ¤¬ %d Í×ÁǤΥ¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿ (´üÂÔÃÍ: 2)"
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: imp.find_module ¤¬ NULL ¤ò´Þ¤à¥¿¥×¥ë¤òÊÖ¤·¤Þ¤·¤¿"
+msgid "internal error: not enough list items"
+msgstr "ÆâÉô¥¨¥é¡¼: ¥ê¥¹¥È¤Ë½½Ê¬¤ÊÍ×ÁǤ¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "vim.Dictionary°À­¤Ï¾Ã¤»¤Þ¤»¤ó"
+msgid "internal error: failed to add item to list"
+msgstr "ÆâÉô¥¨¥é¡¼: ¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "cannot modify fixed dictionary"
-#~ msgstr "¸ÇÄꤵ¤ì¤¿¼­½ñ¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr "Ťµ %d ¤Î¥¹¥é¥¤¥¹¤ò %d ¤Î³ÈÄ¥¥¹¥é¥¤¥¹¤Ë³ä¤êÅö¤Æ¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "cannot set attribute %s"
-#~ msgstr "°À­ %s ¤ÏÀßÄê¤Ç¤­¤Þ¤»¤ó"
+msgid "failed to add item to list"
+msgstr "¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "¥¤¥Æ¥ì¡¼¥·¥ç¥óÃæ¤Ë hashtab ¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿"
+msgid "cannot delete vim.List attributes"
+msgstr "vim.List °À­¤Ï¾Ã¤»¤Þ¤»¤ó"
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr "¥·¡¼¥±¥ó¥¹¤ÎÍ×ÁÇ¿ô¤Ë¤Ï 2 ¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤Þ¤·¤¿¤¬ %d ¤Ç¤·¤¿"
+msgid "cannot modify fixed list"
+msgstr "¸ÇÄꤵ¤ì¤¿¥ê¥¹¥È¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "¥ê¥¹¥È¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï¥­¡¼¥ï¡¼¥É°ú¿ô¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "̵̾´Ø¿ô %s ¤Ï¸ºß¤·¤Þ¤»¤ó"
-#~ msgid "list index out of range"
-#~ msgstr "¥ê¥¹¥ÈÈϰϳ°¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¹"
+#, c-format
+msgid "function %s does not exist"
+msgstr "´Ø¿ô %s ¤¬¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Î¼èÆÀ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+#, c-format
+msgid "failed to run function %s"
+msgstr "´Ø¿ô %s ¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "failed to add item to list"
-#~ msgstr "¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "unable to get option value"
+msgstr "¥ª¥×¥·¥ç¥ó¤ÎÃͤϼèÆÀ¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: vim¤Î¥ê¥¹¥ÈÍ×ÁÇ %d ¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "internal error: unknown option type"
+msgstr "ÆâÉô¥¨¥é¡¼: ̤ÃΤΥª¥×¥·¥ç¥ó·¿¤Ç¤¹"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: ¥ê¥¹¥È¤Ø¤ÎÍ×ÁÇÄɲä˼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "problem while switching windows"
+msgstr "¥¦¥£¥ó¥É¥¦¤òÀÚ´¹Ãæ¤ËÌäÂ꤬ȯÀ¸¤·¤Þ¤·¤¿"
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "vim.List °À­¤Ï¾Ã¤»¤Þ¤»¤ó"
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "¥°¥í¡¼¥Ð¥ë¥ª¥×¥·¥ç¥ó %s ¤ÎÀßÄê²ò½ü¤Ï¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "¸ÇÄꤵ¤ì¤¿¥ê¥¹¥È¤ÏÊѹ¹¤Ç¤­¤Þ¤»¤ó"
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "¥°¥í¡¼¥Ð¥ë¤ÊÃͤÎ̵¤¤¥ª¥×¥·¥ç¥ó %s ¤ÎÀßÄê²ò½ü¤Ï¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "̵̾´Ø¿ô %s ¤Ï¸ºß¤·¤Þ¤»¤ó"
+msgid "attempt to refer to deleted tab page"
+msgstr "ºï½ü¤µ¤ì¤¿¥¿¥Ö¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "function %s does not exist"
-#~ msgstr "´Ø¿ô %s ¤¬¤¢¤ê¤Þ¤»¤ó"
+msgid "no such tab page"
+msgstr "¤½¤Î¤è¤¦¤Ê¥¿¥Ö¥Ú¡¼¥¸¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "´Ø¿ô¤Î¥³¥ó¥¹¥È¥é¥¯¥¿¤Ï¥­¡¼¥ï¡¼¥É°ú¿ô¤ò¼õ¤±ÉÕ¤±¤Þ¤»¤ó"
+msgid "attempt to refer to deleted window"
+msgstr "ºï½ü¤µ¤ì¤¿¥¦¥£¥ó¥É¥¦¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "failed to run function %s"
-#~ msgstr "´Ø¿ô %s ¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "readonly attribute: buffer"
+msgstr "ÆÉ¹þÀìÍѰÀ­: ¥Ð¥Ã¥Õ¥¡¡¼"
-#~ msgid "problem while switching windows"
-#~ msgstr "¥¦¥£¥ó¥É¥¦¤òÀÚ´¹Ãæ¤ËÌäÂ꤬ȯÀ¸¤·¤Þ¤·¤¿"
+msgid "cursor position outside buffer"
+msgstr "¥«¡¼¥½¥ë°ÌÃÖ¤¬¥Ð¥Ã¥Õ¥¡¤Î³°Â¦¤Ç¤¹"
-#~ msgid "unable to unset global option %s"
-#~ msgstr "¥°¥í¡¼¥Ð¥ë¥ª¥×¥·¥ç¥ó %s ¤ÎÀßÄê²ò½ü¤Ï¤Ç¤­¤Þ¤»¤ó"
+msgid "no such window"
+msgstr "¤½¤Î¤è¤¦¤Ê¥¦¥£¥ó¥É¥¦¤Ï¤¢¤ê¤Þ¤»¤ó"
-#~ msgid "unable to unset option %s which does not have global value"
-#~ msgstr "¥°¥í¡¼¥Ð¥ë¤ÊÃͤÎ̵¤¤¥ª¥×¥·¥ç¥ó %s ¤ÎÀßÄê²ò½ü¤Ï¤Ç¤­¤Þ¤»¤ó"
+msgid "attempt to refer to deleted buffer"
+msgstr "ºï½ü¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "ºï½ü¤µ¤ì¤¿¥¿¥Ö¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
+msgid "failed to rename buffer"
+msgstr "¥Ð¥Ã¥Õ¥¡Ì¾¤ÎÊѹ¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "no such tab page"
-#~ msgstr "¤½¤Î¤è¤¦¤Ê¥¿¥Ö¥Ú¡¼¥¸¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "mark name must be a single character"
+msgstr "¥Þ¡¼¥¯Ì¾¤Ï1ʸ»ú¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "ºï½ü¤µ¤ì¤¿¥¦¥£¥ó¥É¥¦¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "vim.Buffer¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "ÆÉ¹þÀìÍѰÀ­: ¥Ð¥Ã¥Õ¥¡¡¼"
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "»ØÄꤵ¤ì¤¿¥Ð¥Ã¥Õ¥¡ %d ¤Ø¤ÎÀÚ¤êÂØ¤¨¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "¥«¡¼¥½¥ë°ÌÃÖ¤¬¥Ð¥Ã¥Õ¥¡¤Î³°Â¦¤Ç¤¹"
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "vim.Window¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "no such window"
-#~ msgstr "¤½¤Î¤è¤¦¤Ê¥¦¥£¥ó¥É¥¦¤Ï¤¢¤ê¤Þ¤»¤ó"
+msgid "failed to find window in the current tab page"
+msgstr "¸½ºß¤Î¥¿¥Ö¤Ë¤Ï»ØÄꤵ¤ì¤¿¥¦¥£¥ó¥É¥¦¤¬¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "ºï½ü¤µ¤ì¤¿¥Ð¥Ã¥Õ¥¡¤ò»²¾È¤·¤è¤¦¤È¤·¤Þ¤·¤¿"
+msgid "did not switch to the specified window"
+msgstr "»ØÄꤵ¤ì¤¿¥¦¥£¥ó¥É¥¦¤ËÀÚ¤êÂØ¤¨¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "failed to rename buffer"
-#~ msgstr "¥Ð¥Ã¥Õ¥¡Ì¾¤ÎÊѹ¹¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "vim.TabPage¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
-#~ msgid "mark name must be a single character"
-#~ msgstr "¥Þ¡¼¥¯Ì¾¤Ï1ʸ»ú¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤Ç¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó"
+msgid "did not switch to the specified tab page"
+msgstr "»ØÄꤵ¤ì¤¿¥¿¥Ö¥Ú¡¼¥¸¤ËÀÚ¤êÂØ¤¨¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "vim.Buffer¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "failed to run the code"
+msgstr "¥³¡¼¥É¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "»ØÄꤵ¤ì¤¿¥Ð¥Ã¥Õ¥¡ %d ¤Ø¤ÎÀÚ¤êÂØ¤¨¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: ¼°É¾²Á¤ÏÍ­¸ú¤Êpython¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤·¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "vim.Window¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: ÊÖ¤µ¤ì¤¿python¥ª¥Ö¥¸¥§¥¯¥È¤òvim¤ÎÃͤËÊÑ´¹¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "¸½ºß¤Î¥¿¥Ö¤Ë¤Ï»ØÄꤵ¤ì¤¿¥¦¥£¥ó¥É¥¦¤¬¤¢¤ê¤Þ¤»¤ó¤Ç¤·¤¿"
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "%s vim¤Î¼­½ñ·¿¤ËÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "did not switch to the specified window"
-#~ msgstr "»ØÄꤵ¤ì¤¿¥¦¥£¥ó¥É¥¦¤ËÀÚ¤êÂØ¤¨¤Þ¤»¤ó¤Ç¤·¤¿"
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "%s ¤òvim¤Î¥ê¥¹¥È¤ËÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "expected vim.TabPage object, but got %s"
-#~ msgstr "vim.TabPage¥ª¥Ö¥¸¥§¥¯¥È¤¬´üÂÔ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ë %s ¤Ç¤·¤¿"
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "%s ¤òvim¤Î¹½Â¤ÂΤËÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "»ØÄꤵ¤ì¤¿¥¿¥Ö¥Ú¡¼¥¸¤ËÀÚ¤êÂØ¤¨¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid "internal error: NULL reference passed"
+msgstr "ÆâÉô¥¨¥é¡¼: NULL»²¾È¤¬ÅϤµ¤ì¤Þ¤·¤¿"
-#~ msgid "failed to run the code"
-#~ msgstr "¥³¡¼¥É¤Î¼Â¹Ô¤Ë¼ºÇÔ¤·¤Þ¤·¤¿"
+msgid "internal error: invalid value type"
+msgstr "ÆâÉô¥¨¥é¡¼: ̵¸ú¤ÊÃÍ·¿¤Ç¤¹"
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: ¼°É¾²Á¤ÏÍ­¸ú¤Êpython¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤·¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"¥Ñ¥¹¥Õ¥Ã¥¯¤ÎÀßÄê¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: sys.path_hooks ¤¬¥ê¥¹¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó\n"
+"¤¹¤°¤Ë²¼µ­¤ò¼Â»Ü¤·¤Æ¤¯¤À¤µ¤¤:\n"
+"- vim.path_hooks ¤ò sys.path_hooks ¤ØÄɲÃ\n"
+"- vim.VIM_SPECIAL_PATH ¤ò sys.path ¤ØÄɲÃ\n"
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: ÊÖ¤µ¤ì¤¿python¥ª¥Ö¥¸¥§¥¯¥È¤òvim¤ÎÃͤËÊÑ´¹¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿"
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"¥Ñ¥¹¤ÎÀßÄê¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: sys.path ¤¬¥ê¥¹¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó\n"
+"¤¹¤°¤Ë vim.VIM_SPECIAL_PATH ¤ò sys.path ¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤"
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "%s vim¤Î¼­½ñ·¿¤ËÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*.*)\t*.*\n"
+msgstr ""
+"Vim¥Þ¥¯¥í¥Õ¥¡¥¤¥ë (*.vim)\t*.vim\n"
+"¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*.*)\t*.*\n"
-#~ msgid "unable to convert %s to vim structure"
-#~ msgstr "%s ¤òvim¤Î¹½Â¤ÂΤËÊÑ´¹¤Ç¤­¤Þ¤»¤ó"
+msgid "All Files (*.*)\t*.*\n"
+msgstr "¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*.*)\t*.*\n"
-#~ msgid "internal error: NULL reference passed"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: NULL»²¾È¤¬ÅϤµ¤ì¤Þ¤·¤¿"
+msgid ""
+"All Files (*.*)\t*.*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VB code (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*.*)\t*.*\n"
+"C¥½¡¼¥¹ (*.c, *.h)\t*.c;*.h\n"
+"C++¥½¡¼¥¹ (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VB¥³¡¼¥É (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vim¥Õ¥¡¥¤¥ë (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "ÆâÉô¥¨¥é¡¼: ̵¸ú¤ÊÃÍ·¿¤Ç¤¹"
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*)\t*\n"
+msgstr ""
+"Vim ¥Þ¥¯¥í¥Õ¥¡¥¤¥ë (*.vim)\t*.vim\n"
+"¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*)\t*\n"
-#~ msgid ""
-#~ "Failed to set path hook: sys.path_hooks is not a list\n"
-#~ "You should now do the following:\n"
-#~ "- append vim.path_hook to sys.path_hooks\n"
-#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
-#~ msgstr ""
-#~ "¥Ñ¥¹¥Õ¥Ã¥¯¤ÎÀßÄê¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: sys.path_hooks ¤¬¥ê¥¹¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó\n"
-#~ "¤¹¤°¤Ë²¼µ­¤ò¼Â»Ü¤·¤Æ¤¯¤À¤µ¤¤:\n"
-#~ "- vim.path_hooks ¤ò sys.path_hooks ¤ØÄɲÃ\n"
-#~ "- vim.VIM_SPECIAL_PATH ¤ò sys.path ¤ØÄɲÃ\n"
+msgid "All Files (*)\t*\n"
+msgstr "¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*)\t*\n"
-#~ msgid ""
-#~ "Failed to set path: sys.path is not a list\n"
-#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
-#~ msgstr ""
-#~ "¥Ñ¥¹¤ÎÀßÄê¤Ë¼ºÇÔ¤·¤Þ¤·¤¿: sys.path ¤¬¥ê¥¹¥È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó\n"
-#~ "¤¹¤°¤Ë vim.VIM_SPECIAL_PATH ¤ò sys.path ¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤"
+msgid ""
+"All Files (*)\t*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"¤¹¤Ù¤Æ¤Î¥Õ¥¡¥¤¥ë (*)\t*\n"
+"C¥½¡¼¥¹ (*.c, *.h)\t*.c;*.h\n"
+"C++¥½¡¼¥¹ (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vim¥Õ¥¡¥¤¥ë (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
diff --git a/src/nvim/po/ja.po b/src/nvim/po/ja.po
index 8a3fcb8f78..4c5661464a 100644
--- a/src/nvim/po/ja.po
+++ b/src/nvim/po/ja.po
@@ -1,10 +1,11 @@
+
# Japanese translation for Vim
#
# Do ":help uganda" in Vim to read copying and usage conditions.
# Do ":help credits" in Vim to see a list of people who contributed.
#
-# Copyright (C) 2001-2016 MURAOKA Taro <koron.kaoriya@gmail.com>,
-# vim-jp (http://vim-jp.org/)
+# Copyright (C) 2001-2018 MURAOKA Taro <koron.kaoriya@gmail.com>,
+# vim-jp <http://vim-jp.org/>
#
# THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
#
@@ -12,215 +13,188 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Vim 7.4\n"
+"Project-Id-Version: Vim 8.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-02-01 09:02+0900\n"
-"PO-Revision-Date: 2013-06-02-01 09:08+09n"
+"POT-Creation-Date: 2018-07-18 00:43+0900\n"
+"PO-Revision-Date: 2017-05-18 00:45+0900\n"
"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
-"Language-Team: vim-jp (https://github.com/vim-jp/lang-ja)\n"
-"Language: Japanese\n"
+"Language-Team: Japanese <https://github.com/vim-jp/lang-ja>\n"
+"Language: ja\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
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "オプションã®å€¤ã¯å–å¾—ã§ãã¾ã›ã‚“"
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() ãŒç©ºãƒ‘スワードã§å‘¼ã³å‡ºã•れã¾ã—ãŸ"
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "内部エラー: 未知ã®ã‚ªãƒ—ション型ã§ã™"
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Blowfishæš—å·ã®ãƒ“ッグ/リトルエンディアンãŒé–“é•ã£ã¦ã„ã¾ã™"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: sha256ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Blowfishæš—å·ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[ロケーションリスト]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[Quickfixリスト]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: autocommandãŒã‚³ãƒžãƒ³ãƒ‰ã®åœæ­¢ã‚’引ãèµ·ã“ã—ã¾ã—ãŸ"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: ãƒãƒƒãƒ•ã‚¡ã‚’1ã¤ã‚‚作æˆã§ããªã„ã®ã§, 終了ã—ã¾ã™..."
+msgstr "E82: ãƒãƒƒãƒ•ã‚¡ã‚’1ã¤ã‚‚作æˆã§ããªã„ã®ã§ã€çµ‚了ã—ã¾ã™..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: ãƒãƒƒãƒ•ァを作æˆã§ããªã„ã®ã§, ä»–ã®ã‚’使用ã—ã¾ã™..."
+msgstr "E83: ãƒãƒƒãƒ•ァを作æˆã§ããªã„ã®ã§ã€ä»–ã®ã‚’使用ã—ã¾ã™..."
+
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: ãƒãƒƒãƒ•ァを登録ã§ãã¾ã›ã‚“"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: 使用中ã®ãƒãƒƒãƒ•ァを削除ã—よã†ã¨è©¦ã¿ã¾ã—ãŸ"
-#: ../buffer.c:763
msgid "E515: No buffers were unloaded"
msgstr "E515: 解放ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: 削除ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#: ../buffer.c:767
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:782
msgid "1 buffer wiped out"
msgstr "1 個ã®ãƒãƒƒãƒ•ã‚¡ãŒç ´æ£„ã•れã¾ã—ãŸ"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "%d 個ã®ãƒãƒƒãƒ•ã‚¡ãŒç ´æ£„ã•れã¾ã—ãŸ"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: 最後ã®ãƒãƒƒãƒ•ã‚¡ã¯è§£æ”¾ã§ãã¾ã›ã‚“"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: 変更ã•れãŸãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
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
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: 最後ã®ãƒãƒƒãƒ•ã‚¡ã‚’è¶Šãˆã¦ç§»å‹•ã¯ã§ãã¾ã›ã‚“"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: 最åˆã®ãƒãƒƒãƒ•ァよりå‰ã¸ã¯ç§»å‹•ã§ãã¾ã›ã‚“"
-#: ../buffer.c:945
#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ã®å¤‰æ›´ã¯ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! ã§å¤‰æ›´ã‚’破棄)"
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr "E89: ãƒãƒƒãƒ•ã‚¡ %ld ã®å¤‰æ›´ã¯ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! ã§å¤‰æ›´ã‚’破棄)"
+
+msgid "E948: Job still running (add ! to end the job)"
+msgstr "E948: ジョブã¯ã¾ã å®Ÿè¡Œä¸­ã§ã™ (! を追加ã§ã‚¸ãƒ§ãƒ–を終了)"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! を追加ã§å¤‰æ›´ã‚’破棄)"
+
+msgid "E948: Job still running"
+msgstr "E948: ジョブã¯ã¾ã å®Ÿè¡Œä¸­ã§ã™"
+
+msgid "E37: No write since last change"
+msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: 警告: ファイルåã®ãƒªã‚¹ãƒˆãŒé•·éŽãŽã¾ã™"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+msgid "E92: Buffer %ld not found"
+msgstr "E92: ãƒãƒƒãƒ•ã‚¡ %ld ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: %s ã«è¤‡æ•°ã®è©²å½“ãŒã‚りã¾ã—ãŸ"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: %s ã«è©²å½“ã™ã‚‹ãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“ã§ã—ãŸ"
-#: ../buffer.c:2161
#, c-format
-msgid "line %<PRId64>"
-msgstr "行 %<PRId64>"
+msgid "line %ld"
+msgstr "行 %ld"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: ã“ã®åå‰ã®ãƒãƒƒãƒ•ã‚¡ã¯æ—¢ã«ã‚りã¾ã™"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [変更ã‚り]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[未編集]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[新ファイル]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[読込エラー]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[読専]"
-#: ../buffer.c:2507 ../fileio.c:1807
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%%--"
+msgid "%ld lines --%d%%--"
+msgstr "%ld 行 --%d%%--"
-#: ../buffer.c:2530
#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "行 %<PRId64> (全体 %<PRId64>) --%d%%-- col "
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "行 %ld (全体 %ld) --%d%%-- col "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[ç„¡å]"
-#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "ヘルプ"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[ヘルプ]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[プレビュー]"
-#: ../buffer.c:3528
msgid "All"
msgstr "å…¨ã¦"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "末尾"
-#: ../buffer.c:3531
msgid "Top"
msgstr "先頭"
-#: ../buffer.c:4244
msgid ""
"\n"
"# Buffer list:\n"
@@ -228,11 +202,15 @@ msgstr ""
"\n"
"# ãƒãƒƒãƒ•ァリスト:\n"
-#: ../buffer.c:4289
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: 'buftype' オプションãŒè¨­å®šã•れã¦ã„ã‚‹ã®ã§æ›¸è¾¼ã‚ã¾ã›ã‚“"
+
+msgid "[Prompt]"
+msgstr "[プロンプト]"
+
msgid "[Scratch]"
msgstr "[下書ã]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -240,633 +218,385 @@ msgstr ""
"\n"
"--- サイン ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "%s ã®ã‚µã‚¤ãƒ³:"
-#: ../buffer.c:4543
#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " 行=%<PRId64> 識別å­=%d åå‰=%s"
+msgid " line=%ld id=%d name=%s"
+msgstr " 行=%ld 識別å­=%d åå‰=%s"
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: コロンãŒã‚りã¾ã›ã‚“"
+msgid "E902: Cannot connect to port"
+msgstr "E902: ãƒãƒ¼ãƒˆã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: 䏿­£ãªãƒ¢ãƒ¼ãƒ‰ã§ã™"
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: channel_open() 内㮠gethostbyname() ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: 数値ãŒå¿…è¦ã§ã™"
+msgid "E898: socket() in channel_open()"
+msgstr "E898: channel_open() 内㮠socket() ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: 䏿­£ãªãƒ‘ーセンテージã§ã™"
+msgid "E903: received command with non-string argument"
+msgstr "E903: éžæ–‡å­—列ã®å¼•æ•°ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’å—ä¿¡ã—ã¾ã—ãŸ"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: expr/call ã®æœ€å¾Œã®å¼•æ•°ã¯æ•°å­—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: call ã®3番目ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: %<PRId64> 以上ã®ãƒãƒƒãƒ•ã‚¡ã¯diffã§ãã¾ã›ã‚“"
+msgid "E905: received unknown command: %s"
+msgstr "E905: 未知ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’å—ä¿¡ã—ã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): éžæŽ¥ç¶šçŠ¶æ…‹ã§æ›¸ãè¾¼ã¿ã¾ã—ãŸ"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): 書ãè¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: %s() ã«ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ä½¿ãˆã¾ã›ã‚“"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr ""
+"E912: raw ã‚„ nl モードã®ãƒãƒ£ãƒãƒ«ã« ch_evalexpr()/ch_sendexpr() ã¯ä½¿ãˆã¾ã›ã‚“"
+
+msgid "E906: not an open channel"
+msgstr "E906: é–‹ã„ã¦ã„ãªã„ãƒãƒ£ãƒãƒ«ã§ã™"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: _io ファイル㯠_name ã®è¨­å®šãŒå¿…è¦ã§ã™"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: in_io ãƒãƒƒãƒ•ァ㯠in_buf ã‹ in_name ã®è¨­å®šãŒå¿…è¦ã§ã™"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: ãƒãƒƒãƒ•ã‚¡ãŒãƒ­ãƒ¼ãƒ‰ã•れã¦ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: ãƒ•ã‚¡ã‚¤ãƒ«ãŒæœªçŸ¥ã®æ–¹æ³•ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "警告: å¼±ã„æš—å·æ–¹æ³•を使ã£ã¦ã„ã¾ã™; :help 'cm' ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
+
+msgid "Enter encryption key: "
+msgstr "æš—å·åŒ–用ã®ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+
+msgid "Enter same key again: "
+msgstr "ã‚‚ã†ä¸€åº¦åŒã˜ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+
+msgid "Keys don't match!"
+msgstr "キーãŒä¸€è‡´ã—ã¾ã›ã‚“"
+
+msgid "[crypted]"
+msgstr "[æš—å·åŒ–]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: 辞書型ã«ã‚³ãƒ­ãƒ³ãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: 辞書型ã«é‡è¤‡ã‚­ãƒ¼ãŒã‚りã¾ã™: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: 辞書型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: è¾žæ›¸åž‹ã®æœ€å¾Œã« '}' ãŒã‚りã¾ã›ã‚“: %s"
+
+msgid "extend() argument"
+msgstr "extend() ã®å¼•æ•°"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: ã‚­ãƒ¼ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: %ld 以上ã®ãƒãƒƒãƒ•ã‚¡ã¯diffã§ãã¾ã›ã‚“"
-#: ../diff.c:753
msgid "E810: Cannot read or write temp files"
msgstr "E810: 一時ファイルã®èª­è¾¼ã‚‚ã—ãã¯æ›¸è¾¼ãŒã§ãã¾ã›ã‚“"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: 差分を作æˆã§ãã¾ã›ã‚“"
-#: ../diff.c:966
+msgid "Patch file"
+msgstr "パッãƒãƒ•ァイル"
+
msgid "E816: Cannot read patch output"
msgstr "E816: patchã®å‡ºåŠ›ã‚’èª­è¾¼ã‚ã¾ã›ã‚“"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: diffã®å‡ºåŠ›ã‚’èª­è¾¼ã‚ã¾ã›ã‚“"
-#: ../diff.c:2081
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: ç¾åœ¨ã®ãƒãƒƒãƒ•ã‚¡ã¯å·®åˆ†ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: 差分モードã§ã‚ã‚‹ä»–ã®ãƒãƒƒãƒ•ã‚¡ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: 差分モードã§ã‚ã‚‹ä»–ã®ãƒãƒƒãƒ•ã‚¡ã¯ã‚りã¾ã›ã‚“"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr ""
"E101: 差分モードã®ãƒãƒƒãƒ•ã‚¡ãŒ2個以上ã‚ã‚‹ã®ã§ã€ã©ã‚Œã‚’使ã†ã‹ç‰¹å®šã§ãã¾ã›ã‚“"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: ãƒãƒƒãƒ•ã‚¡ \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: ãƒãƒƒãƒ•ã‚¡ \"%s\" ã¯å·®åˆ†ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: 予期ã›ãšãƒãƒƒãƒ•ã‚¡ãŒå¤‰æ›´å¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: åˆå­—ã«Escapeã¯ä½¿ç”¨ã§ãã¾ã›ã‚“"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: キーマップファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :source ã§å–込むファイル以外ã§ã¯ :loadkeymap を使ãˆã¾ã›ã‚“"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: 空ã®ã‚­ãƒ¼ãƒžãƒƒãƒ—エントリ"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " キーワード補完 (^N^P)"
-#. 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)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " 行(全体)補完 (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " ファイルå補完 (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
msgstr " タグ補完 (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " パスパターン補完 (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " 定義補完 (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " 辞書補完 (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " シソーラス補完 (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " コマンドライン補完 (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " ユーザー定義補完 (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " オムニ補完 (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " 綴り修正候補 (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " 局所キーワード補完 (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "段è½ã®æœ€å¾Œã«ãƒ’ット"
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: 補間関数ãŒã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’変更ã—ã¾ã—ãŸ"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: 補完関数ãŒãƒ†ã‚­ã‚¹ãƒˆã‚’削除ã—ã¾ã—ãŸ"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "'dictionary' オプションãŒç©ºã§ã™"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "'thesaurus' オプションãŒç©ºã§ã™"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "辞書をスキャン中: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
msgstr " (挿入) スクロール(^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (ç½®æ›) スクロール (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "スキャン中: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "タグをスキャン中."
-#: ../edit.c:4519
+msgid "match in file"
+msgstr "ファイル内ã®ãƒžãƒƒãƒ"
+
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.
-#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- 検索中..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "å§‹ã‚ã«æˆ»ã‚‹"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "ä»–ã®è¡Œã®å˜èªž"
-#: ../edit.c:4624
msgid "The only match"
msgstr "唯一ã®è©²å½“"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "%d 番目ã®è©²å½“ (全該当 %d 個中)"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "%d 番目ã®è©²å½“"
-#: ../eval.c:137
msgid "E18: Unexpected characters in :let"
msgstr "E18: 予期ã›ã¬æ–‡å­—㌠:let ã«ã‚りã¾ã—ãŸ"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: リストã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç¯„囲外ã§ã™: %<PRId64>"
-
-#: ../eval.c:139
#, c-format
msgid "E121: Undefined variable: %s"
msgstr "E121: 未定義ã®å¤‰æ•°ã§ã™: %s"
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: ']' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã¾ãŸã¯è¾žæ›¸åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: 辞書型ã«ç©ºã®ã‚­ãƒ¼ã‚’使ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: リスト型ãŒå¿…è¦ã§ã™"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: 辞書型ãŒå¿…è¦ã§ã™"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: 関数ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: 辞書型ã«ã‚­ãƒ¼ãŒå­˜åœ¨ã—ã¾ã›ã‚“: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: 関数 %s ã¯å®šç¾©æ¸ˆã§ã™, å†å®šç¾©ã™ã‚‹ã«ã¯ ! を追加ã—ã¦ãã ã•ã„"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: 辞書型内ã«ã‚¨ãƒ³ãƒˆãƒªãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: 関数å‚ç…§åž‹ãŒè¦æ±‚ã•れã¾ã™"
-
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: [:] を辞書型ã¨çµ„ã¿åˆã‚ã›ã¦ã¯ä½¿ãˆã¾ã›ã‚“"
-#: ../eval.c:154
#, c-format
msgid "E734: Wrong variable type for %s="
msgstr "E734: ç•°ãªã£ãŸåž‹ã®å¤‰æ•°ã§ã™ %s="
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: 未知ã®é–¢æ•°ã§ã™: %s"
-
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: 䏿­£ãªå¤‰æ•°åã§ã™: %s"
-#: ../eval.c:157
msgid "E806: using Float as a String"
msgstr "E806: æµ®å‹•å°æ•°ç‚¹æ•°ã‚’文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: ターゲットãŒãƒªã‚¹ãƒˆåž‹å†…ã®è¦ç´ ã‚ˆã‚Šã‚‚å°‘ãªã„ã§ã™"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: ターゲットãŒãƒªã‚¹ãƒˆåž‹å†…ã®è¦ç´ ã‚ˆã‚Šã‚‚多ã„ã§ã™"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "リスト型ã®å€¤ã«2ã¤ä»¥ä¸Šã® ; ãŒæ¤œå‡ºã•れã¾ã—ãŸ"
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: %s ã®å€¤ã‚’一覧表示ã§ãã¾ã›ã‚“"
-#: ../eval.c:2391
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: リスト型ã¨è¾žæ›¸åž‹ä»¥å¤–ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹æŒ‡å®šã§ãã¾ã›ã‚“"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] ã¯æœ€å¾Œã§ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
-#: ../eval.c:2439
msgid "E709: [:] requires a List value"
msgstr "E709: [:] ã«ã¯ãƒªã‚¹ãƒˆåž‹ã®å€¤ãŒå¿…è¦ã§ã™"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: リスト型変数ã«ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚ˆã‚Šã‚‚多ã„è¦ç´ ãŒã‚りã¾ã™"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: リスト型変数ã«ååˆ†ãªæ•°ã®è¦ç´ ãŒã‚りã¾ã›ã‚“"
-#
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: :for ã®å¾Œã« \"in\" ãŒã‚りã¾ã›ã‚“"
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: カッコ '(' ãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: ãã®å¤‰æ•°ã¯ã‚りã¾ã›ã‚“: \"%s\""
-#: ../eval.c:3333
+#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: 変数 %s ã¯ãƒ­ãƒƒã‚¯ã¾ãŸã¯ã‚¢ãƒ³ãƒ­ãƒƒã‚¯ã§ãã¾ã›ã‚“"
+
msgid "E743: variable nested too deep for (un)lock"
msgstr "E743: (アン)ロックã™ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: '?' ã®å¾Œã« ':' ãŒã‚りã¾ã›ã‚“"
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: リスト型ã¯ãƒªã‚¹ãƒˆåž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: リスト型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: 辞書型ã¯è¾žæ›¸åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: 辞書型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: 関数å‚ç…§åž‹ã¯é–¢æ•°å‚ç…§åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: 関数å‚ç…§åž‹ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: '%' ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨çµ„ã¿åˆã‚ã›ã¦ã¯ä½¿ãˆã¾ã›ã‚“"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: ')' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: 関数å‚ç…§åž‹ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ãã¾ã›ã‚“"
-#: ../eval.c:4839
+msgid "E909: Cannot index a special variable"
+msgstr "E909: 特殊変数ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ãã¾ã›ã‚“"
+
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: オプションåãŒã‚りã¾ã›ã‚“: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: 未知ã®ã‚ªãƒ—ションã§ã™: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: 引用符 (\") ãŒã‚りã¾ã›ã‚“: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: 引用符 (') ãŒã‚りã¾ã›ã‚“: %s"
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: リスト型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: ãƒªã‚¹ãƒˆåž‹ã®æœ€å¾Œã« ']' ãŒã‚りã¾ã›ã‚“: %s"
-
msgid "Not enough memory to set references, garbage collection aborted!"
msgstr ""
"ガーベッジコレクションを中止ã—ã¾ã—ãŸ! å‚照を作æˆã™ã‚‹ã®ã«ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¾ã—ãŸ"
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: 辞書型ã«ã‚³ãƒ­ãƒ³ãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: 辞書型ã«é‡è¤‡ã‚­ãƒ¼ãŒã‚りã¾ã™: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: 辞書型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: è¾žæ›¸åž‹ã®æœ€å¾Œã« '}' ãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:6555
msgid "E724: variable nested too deep for displaying"
msgstr "E724: 表示ã™ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: 関数ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™: %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: 関数ã®ç„¡åйãªå¼•æ•°ã§ã™: %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: 未知ã®é–¢æ•°ã§ã™: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: 関数ã®å¼•æ•°ãŒè¶³ã‚Šã¾ã›ã‚“: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: スクリプト以外ã§<SID>ãŒä½¿ã‚れã¾ã—ãŸ: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: 辞書用関数ãŒå‘¼ã°ã‚Œã¾ã—ãŸãŒè¾žæ›¸ãŒã‚りã¾ã›ã‚“: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: æ•°å€¤ã‹æµ®å‹•å°æ•°ç‚¹æ•°ãŒå¿…è¦ã§ã™"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "add() ã®å¼•æ•°"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: 引数ãŒå¤šéŽãŽã¾ã™"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() ã¯æŒ¿å…¥ãƒ¢ãƒ¼ãƒ‰ã§ã—ã‹åˆ©ç”¨ã§ãã¾ã›ã‚“"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: ã‚­ãƒ¼ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "extend() ã®å¼•æ•°"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "map() ã®å¼•æ•°"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "filter() ã®å¼•æ•°"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld 行: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: 未知ã®é–¢æ•°ã§ã™: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "inputrestore() ㌠inputsave() よりも多ã呼ã°ã‚Œã¾ã—ãŸ"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "insert() ã®å¼•æ•°"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: 範囲指定ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: len() ã«ã¯ç„¡åйãªåž‹ã§ã™"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: ストライド(å‰é€²é‡)㌠0 ã§ã™"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: é–‹å§‹ä½ç½®ãŒçµ‚了ä½ç½®ã‚’è¶Šãˆã¾ã—ãŸ"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<空>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "remove() ã®å¼•æ•°"
-
-# Added at 10-Mar-2004.
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: シンボリックリンクãŒå¤šéŽãŽã¾ã™ (循環ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "reverse() ã®å¼•æ•°"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "sort() ã®å¼•æ•°"
-
-#: ../eval.c:13721
-msgid "uniq() argument"
-msgstr "uniq() ã®å¼•æ•°"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: ã‚½ãƒ¼ãƒˆã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-
-#: ../eval.c:13806
-msgid "E882: Uniq compare function failed"
-msgstr "E882: Uniq ã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(無効)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: 一時ファイル書込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-
-#: ../eval.c:16159
msgid "E805: Using a Float as a Number"
msgstr "E805: æµ®å‹•å°æ•°ç‚¹æ•°ã‚’数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16162
msgid "E703: Using a Funcref as a Number"
-msgstr "E703: 関数å‚照型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚"
+msgstr "E703: 関数å‚照型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16170
msgid "E745: Using a List as a Number"
msgstr "E745: リスト型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16173
msgid "E728: Using a Dictionary as a Number"
msgstr "E728: 辞書型を数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+msgid "E910: Using a Job as a Number"
+msgstr "E910: ジョブを数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: ãƒãƒ£ãƒãƒ«ã‚’数値ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
msgid "E891: Using a Funcref as a Float"
-msgstr "E891: 関数å‚ç…§åž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™ã€‚"
+msgstr "E891: 関数å‚ç…§åž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
msgid "E892: Using a String as a Float"
msgstr "E892: æ–‡å­—åˆ—ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
@@ -877,265 +607,306 @@ msgstr "E893: ãƒªã‚¹ãƒˆåž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
msgid "E894: Using a Dictionary as a Float"
msgstr "E894: è¾žæ›¸åž‹ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16259
+msgid "E907: Using a special value as a Float"
+msgstr "E907: ç‰¹æ®Šå€¤ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: ã‚¸ãƒ§ãƒ–ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: ãƒãƒ£ãƒãƒ«ã‚’æµ®å‹•å°æ•°ç‚¹æ•°ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
+
msgid "E729: using Funcref as a String"
msgstr "E729: 関数å‚照型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16262
msgid "E730: using List as a String"
msgstr "E730: リスト型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16265
msgid "E731: using Dictionary as a String"
msgstr "E731: 辞書型を文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: 変数ã®åž‹ãŒä¸€è‡´ã—ã¾ã›ã‚“: %s"
+msgid "E908: using an invalid value as a String"
+msgstr "E908: 無効ãªå€¤ã‚’文字列ã¨ã—ã¦æ‰±ã£ã¦ã„ã¾ã™"
-#: ../eval.c:16705
#, c-format
msgid "E795: Cannot delete variable %s"
msgstr "E795: 変数 %s を削除ã§ãã¾ã›ã‚“"
-#: ../eval.c:16724
#, c-format
msgid "E704: Funcref variable name must start with a capital: %s"
msgstr "E704: 関数å‚照型変数åã¯å¤§æ–‡å­—ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
-#: ../eval.c:16732
#, c-format
msgid "E705: Variable name conflicts with existing function: %s"
msgstr "E705: 変数åãŒæ—¢å­˜ã®é–¢æ•°åã¨è¡çªã—ã¾ã™: %s"
-#: ../eval.c:16763
#, c-format
msgid "E741: Value is locked: %s"
msgstr "E741: 値ãŒãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™: %s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
msgid "Unknown"
msgstr "䏿˜Ž"
-#: ../eval.c:16768
#, c-format
msgid "E742: Cannot change value of %s"
msgstr "E742: %s ã®å€¤ã‚’変更ã§ãã¾ã›ã‚“"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: コピーをå–ã‚‹ã«ã¯å¤‰æ•°ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: 未定義ã®é–¢æ•°ã§ã™: %s"
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# グローãƒãƒ«å¤‰æ•°:\n"
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: '(' ãŒã‚りã¾ã›ã‚“: %s"
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\t最後ã«ã‚»ãƒƒãƒˆã—ãŸã‚¹ã‚¯ãƒªãƒ—ト: "
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: ã“ã“ã§ã¯ g: ã¯ä½¿ãˆã¾ã›ã‚“"
+msgid "E691: Can only compare List with List"
+msgstr "E691: リスト型ã¯ãƒªã‚¹ãƒˆåž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: 䏿­£ãªå¼•æ•°ã§ã™: %s"
+msgid "E692: Invalid operation for List"
+msgstr "E692: リスト型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: 引数åãŒé‡è¤‡ã—ã¦ã„ã¾ã™: %s"
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: 辞書型ã¯è¾žæ›¸åž‹ã¨ã—ã‹æ¯”較ã§ãã¾ã›ã‚“"
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunction ãŒã‚りã¾ã›ã‚“"
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: 辞書型ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: 関数åãŒå¤‰æ•°åã¨è¡çªã—ã¾ã™: %s"
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: 関数å‚ç…§åž‹ã«ã¯ç„¡åŠ¹ãªæ“作ã§ã™"
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: 関数 %s ã‚’å†å®šç¾©ã§ãã¾ã›ã‚“: 使用中ã§ã™"
+msgid "map() argument"
+msgstr "map() ã®å¼•æ•°"
+
+msgid "filter() argument"
+msgstr "filter() ã®å¼•æ•°"
-#: ../eval.c:17604
#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: 関数åãŒã‚¹ã‚¯ãƒªãƒ—トã®ãƒ•ァイルåã¨ä¸€è‡´ã—ã¾ã›ã‚“: %s"
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: 関数åãŒè¦æ±‚ã•れã¾ã™"
+msgid "E928: String required"
+msgstr "E928: 文字列ãŒå¿…è¦ã§ã™"
-#: ../eval.c:17824
-#, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: 関数åã¯å¤§æ–‡å­—ã‹ \"s:\" ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
+msgid "E808: Number or Float required"
+msgstr "E808: æ•°å€¤ã‹æµ®å‹•å°æ•°ç‚¹æ•°ãŒå¿…è¦ã§ã™"
-#: ../eval.c:17833
-#, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E884: 関数åã«ã¯ã‚³ãƒ­ãƒ³ã¯å«ã‚られã¾ã›ã‚“: %s"
+msgid "add() argument"
+msgstr "add() ã®å¼•æ•°"
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: 関数 %s を削除ã§ãã¾ã›ã‚“: 使用中ã§ã™"
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() ã¯æŒ¿å…¥ãƒ¢ãƒ¼ãƒ‰ã§ã—ã‹åˆ©ç”¨ã§ãã¾ã›ã‚“"
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: 関数呼出ã®å…¥ã‚Œå­æ•°ãŒ 'maxfuncdepth' ã‚’è¶…ãˆã¾ã—ãŸ"
+msgid "&Ok"
+msgstr "&Ok"
-#: ../eval.c:18568
#, c-format
-msgid "calling %s"
-msgstr "%s を実行中ã§ã™"
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld 行: "
-#: ../eval.c:18651
#, c-format
-msgid "%s aborted"
-msgstr "%s ãŒä¸­æ–­ã•れã¾ã—ãŸ"
+msgid "E700: Unknown function: %s"
+msgstr "E700: 未知ã®é–¢æ•°ã§ã™: %s"
+
+msgid "E922: expected a dict"
+msgstr "E922: è¾žæ›¸ãŒæœŸå¾…ã•れã¦ã„ã¾ã™"
+
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: function() ã®ç¬¬ 2 引数ã¯ãƒªã‚¹ãƒˆåž‹ã¾ãŸã¯è¾žæ›¸åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"決定(&O)\n"
+"キャンセル(&C)"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() ㌠inputsave() よりも多ã呼ã°ã‚Œã¾ã—ãŸ"
+
+msgid "insert() argument"
+msgstr "insert() ã®å¼•æ•°"
+
+msgid "E786: Range not allowed"
+msgstr "E786: 範囲指定ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "E916: not a valid job"
+msgstr "E916: 有効ãªã‚¸ãƒ§ãƒ–ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: len() ã«ã¯ç„¡åйãªåž‹ã§ã™"
-#: ../eval.c:18653
#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ㌠#%<PRId64> ã‚’è¿”ã—ã¾ã—ãŸ"
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ID 㯠\":match\" ã®ãŸã‚ã«äºˆç´„ã•れã¦ã„ã¾ã™: %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: ストライド(å‰é€²é‡)㌠0 ã§ã™"
+
+msgid "E727: Start past end"
+msgstr "E727: é–‹å§‹ä½ç½®ãŒçµ‚了ä½ç½®ã‚’è¶Šãˆã¾ã—ãŸ"
+
+msgid "<empty>"
+msgstr "<空>"
+
+msgid "E240: No connection to the X server"
+msgstr "E240: X サーãƒãƒ¼ã¸ã®æŽ¥ç¶šãŒã‚りã¾ã›ã‚“"
-#: ../eval.c:18670
#, c-format
-msgid "%s returning %s"
-msgstr "%s ㌠%s ã‚’è¿”ã—ã¾ã—ãŸ"
+msgid "E241: Unable to send to %s"
+msgstr "E241: %s ã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: サーãƒãƒ¼ã®å¿œç­”ãŒã‚りã¾ã›ã‚“"
+
+msgid "E941: already started a server"
+msgstr "E941: サーãƒãƒ¼ã¯ã™ã§ã«é–‹å§‹ã—ã¦ã„ã¾ã™"
+
+msgid "E942: +clientserver feature not available"
+msgstr "E942: +clientserver 機能ãŒç„¡åйã«ãªã£ã¦ã„ã¾ã™"
+
+msgid "remove() argument"
+msgstr "remove() ã®å¼•æ•°"
+
+# Added at 10-Mar-2004.
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: シンボリックリンクãŒå¤šéŽãŽã¾ã™ (循環ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™)"
+
+msgid "reverse() argument"
+msgstr "reverse() ã®å¼•æ•°"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: クライアントã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
-msgid "continuing in %s"
-msgstr "%s ã®å®Ÿè¡Œã‚’継続中ã§ã™"
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: ç„¡åŠ¹ãªæ“作ã§ã™: %s"
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: 関数外㫠:return ãŒã‚りã¾ã—ãŸ"
+msgid "sort() argument"
+msgstr "sort() ã®å¼•æ•°"
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# グローãƒãƒ«å¤‰æ•°:\n"
+msgid "uniq() argument"
+msgstr "uniq() ã®å¼•æ•°"
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tLast set from "
+msgid "E702: Sort compare function failed"
+msgstr "E702: ã‚½ãƒ¼ãƒˆã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "å¤ã„ファイルã¯ã‚りã¾ã›ã‚“"
+msgid "E882: Uniq compare function failed"
+msgstr "E882: Uniq ã®æ¯”較関数ãŒå¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "(Invalid)"
+msgstr "(無効)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: 無効ãªã‚µãƒ–マッãƒç•ªå·: %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: 一時ファイル書込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: 無効ãªã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯å¼•æ•°ã§ã™"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"
+msgstr "<%s>%s%s %d, 16進数 %02x, 8進数 %03o, ダイグラフ %s"
-#: ../ex_cmds.c:122
#, c-format
msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
msgstr "<%s>%s%s %d, 16進数 %02x, 8進数 %03o"
-#: ../ex_cmds.c:145
+#, c-format
+msgid "> %d, Hex %04x, Oct %o, Digr %s"
+msgstr "> %d, 16進数 %04x, 8進数 %o, ダイグラフ %s"
+
+#, c-format
+msgid "> %d, Hex %08x, Oct %o, Digr %s"
+msgstr "> %d, 16進数 %08x, 8進数 %o, ダイグラフ %s"
+
#, c-format
msgid "> %d, Hex %04x, Octal %o"
msgstr "> %d, 16進数 %04x, 8進数 %o"
-#: ../ex_cmds.c:146
#, c-format
msgid "> %d, Hex %08x, Octal %o"
msgstr "> %d, 16進数 %08x, 8進数 %o"
-#: ../ex_cmds.c:684
msgid "E134: Move lines into themselves"
msgstr "E134: 行をãれ自身ã«ã¯ç§»å‹•ã§ãã¾ã›ã‚“"
-#: ../ex_cmds.c:747
msgid "1 line moved"
msgstr "1 行ãŒç§»å‹•ã•れã¾ã—ãŸ"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> 行ãŒç§»å‹•ã•れã¾ã—ãŸ"
+msgid "%ld lines moved"
+msgstr "%ld 行ãŒç§»å‹•ã•れã¾ã—ãŸ"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> 行ãŒãƒ•ィルタ処ç†ã•れã¾ã—ãŸ"
+msgid "%ld lines filtered"
+msgstr "%ld 行ãŒãƒ•ィルタ処ç†ã•れã¾ã—ãŸ"
-#: ../ex_cmds.c:1194
msgid "E135: *Filter* Autocommands must not change current buffer"
msgstr "E135: *フィルタ* autocommandã¯ç¾åœ¨ã®ãƒãƒƒãƒ•ァを変更ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“"
-#: ../ex_cmds.c:1244
msgid "[No write since last change]\n"
msgstr "[最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“]\n"
-#: ../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: エラーãŒå¤šéŽãŽã‚‹ã®ã§, 以é™ã¯ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™"
+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
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 "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: 一時viminfoファイルãŒå¤šéŽãŽã¾ã™! 例: %s"
+
#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: viminfoファイル %s ã‚’ä¿å­˜ã§ãã¾ã›ã‚“!"
-#: ../ex_cmds.c:1635
#, c-format
msgid "Writing viminfo file \"%s\""
msgstr "viminfoファイル \"%s\" を書込ã¿ä¸­"
-#. Write the info:
-#: ../ex_cmds.c:1720
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: viminfoファイルを %s ã¸åå‰å¤‰æ›´ã§ãã¾ã›ã‚“!"
+
#, c-format
msgid "# This viminfo file was generated by Vim %s.\n"
msgstr "# ã“ã® viminfo ファイル㯠Vim %s ã«ã‚ˆã£ã¦ç”Ÿæˆã•れã¾ã—ãŸ.\n"
-#: ../ex_cmds.c:1722
msgid ""
"# You may edit it if you're careful!\n"
"\n"
@@ -1143,47 +914,47 @@ msgstr ""
"# 変更ã™ã‚‹éš›ã«ã¯å分注æ„ã—ã¦ãã ã•ã„!\n"
"\n"
-#: ../ex_cmds.c:1723
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
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# '|' ã§å§‹ã¾ã‚‹è¡Œã®ã€æ–‡å­—通りã®ã‚³ãƒ”ー:\n"
+
+msgid "Save As"
+msgstr "別åã§ä¿å­˜"
+
msgid "Write partial file?"
msgstr "ファイルを部分的ã«ä¿å­˜ã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: ãƒãƒƒãƒ•ァを部分的ã«ä¿å­˜ã™ã‚‹ã«ã¯ ! を使ã£ã¦ãã ã•ã„"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "既存ã®ãƒ•ァイル \"%s\" を上書ãã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "スワップファイル \"%s\" ãŒå­˜åœ¨ã—ã¾ã™. 上書ãを強制ã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: スワップファイルãŒå­˜åœ¨ã—ã¾ã™: %s (:silent! を追加ã§ä¸Šæ›¸)"
-#: ../ex_cmds.c:2381
#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ã«ã¯åå‰ãŒã‚りã¾ã›ã‚“"
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: ãƒãƒƒãƒ•ã‚¡ %ld ã«ã¯åå‰ãŒã‚りã¾ã›ã‚“"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: ファイルã¯ä¿å­˜ã•れã¾ã›ã‚“ã§ã—ãŸ: 'write' オプションã«ã‚ˆã‚Šç„¡åйã§ã™"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1192,7 +963,6 @@ msgstr ""
"\"%s\" ã«ã¯ 'readonly' オプションãŒè¨­å®šã•れã¦ã„ã¾ã™.\n"
"上書ã強制をã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1203,83 +973,68 @@ msgstr ""
"ãれã§ã‚‚æã‚‰ã書ã込むã“ã¨ã¯å¯èƒ½ã§ã™.\n"
"継続ã—ã¾ã™ã‹?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: \"%s\" ã¯èª­è¾¼å°‚用ã§ã™ (強制書込ã«ã¯ ! を追加)"
-#: ../ex_cmds.c:3120
+msgid "Edit File"
+msgstr "ファイルを編集"
+
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: autocommandãŒäºˆæœŸã›ãšæ–°ã—ã„ãƒãƒƒãƒ•ã‚¡ %s を削除ã—ã¾ã—ãŸ"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: æ•°ã§ã¯ãªã„引数㌠:z ã«æ¸¡ã•れã¾ã—ãŸ"
-#: ../ex_cmds.c:3404
msgid "E145: Shell commands not allowed in rvim"
msgstr "E145: rvimã§ã¯ã‚·ã‚§ãƒ«ã‚³ãƒžãƒ³ãƒ‰ã‚’使ãˆã¾ã›ã‚“"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: æ­£è¦è¡¨ç¾ã¯æ–‡å­—ã§åŒºåˆ‡ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
-#: ../ex_cmds.c:3964
#, 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
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> 箇所該当ã—ã¾ã—ãŸ"
+msgid "%ld matches"
+msgstr "%ld 箇所該当ã—ã¾ã—ãŸ"
-#: ../ex_cmds.c:4388
#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> 箇所置æ›ã—ã¾ã—ãŸ"
+msgid "%ld substitutions"
+msgstr "%ld 箇所置æ›ã—ã¾ã—ãŸ"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " (計 1 行内)"
-#: ../ex_cmds.c:4395
#, c-format
-msgid " on %<PRId64> lines"
-msgstr " (計 %<PRId64> 行内)"
+msgid " on %ld lines"
+msgstr " (計 %ld 行内)"
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global ã‚’å†å¸°çš„ã«ã¯ä½¿ãˆã¾ã›ã‚“"
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: :global を範囲付ãã§å†å¸°çš„ã«ã¯ä½¿ãˆã¾ã›ã‚“"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: globalã‚³ãƒžãƒ³ãƒ‰ã«æ­£è¦è¡¨ç¾ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "パターンãŒå…¨ã¦ã®è¡Œã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ: %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s"
-#: ../ex_cmds.c:4587
msgid ""
"\n"
"# Last Substitute String:\n"
@@ -1289,110 +1044,110 @@ msgstr ""
"# 最後ã«ç½®æ›ã•ã‚ŒãŸæ–‡å­—列:\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"
+msgid "E151: No match: %s"
+msgstr "E151: マッãƒã¯ã‚りã¾ã›ã‚“: %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 ã‚’é–‹ã‘ã¾ã›ã‚“"
# Added at 29-Apr-2004.
-#: ../ex_cmds.c:5500
#, c-format
msgid "E670: Mix of help file encodings within a language: %s"
msgstr "E670: 1ã¤ã®è¨€èªžã®ãƒ˜ãƒ«ãƒ—ファイルã«è¤‡æ•°ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ãŒæ··åœ¨ã—ã¦ã„ã¾ã™: %s"
-#: ../ex_cmds.c:5565
#, c-format
msgid "E154: Duplicate tag \"%s\" in file %s/%s"
msgstr "E154: ã‚¿ã‚° \"%s\" ãŒãƒ•ァイル %s/%s ã«é‡è¤‡ã—ã¦ã„ã¾ã™"
-#: ../ex_cmds.c:5687
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: ディレクトリã§ã¯ã‚りã¾ã›ã‚“: %s"
+
#, 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: signã®å®šç¾©ãŒå¤šæ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
-#: ../ex_cmds.c:5813
#, 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
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: åå‰ã®ç„¡ã„ãƒãƒƒãƒ•ã‚¡ã¸ã¯ã‚¸ãƒ£ãƒ³ãƒ—ã§ãã¾ã›ã‚“"
+
#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: 無効ãªsign識別å­ã§ã™: %<PRId64>"
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: 無効ãªsign識別å­ã§ã™: %ld"
#, c-format
msgid "E885: Not possible to change sign %s"
msgstr "E885: 変更ã§ããªã„ sign ã§ã™: %s"
-#: ../ex_cmds.c:6066
+# Added at 27-Jan-2004.
+msgid " (NOT FOUND)"
+msgstr " (見ã¤ã‹ã‚Šã¾ã›ã‚“)"
+
msgid " (not supported)"
msgstr " (éžã‚µãƒãƒ¼ãƒˆ)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[削除済]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "å¤ã„ファイルã¯ã‚りã¾ã›ã‚“"
+
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"
+msgid "Oldval = \"%s\""
+msgstr "å¤ã„値 = \"%s\""
+
+#, c-format
+msgid "Newval = \"%s\""
+msgstr "æ–°ã—ã„値 = \"%s\""
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "行 %ld: %s"
-#: ../ex_cmds2.c:145
#, c-format
msgid "cmd: %s"
msgstr "コマンド: %s"
@@ -1404,232 +1159,199 @@ msgstr "フレーム㌠0 ã§ã™"
msgid "frame at highest level: %d"
msgstr "最高レベルã®ãƒ•レーム: %d"
-#: ../ex_cmds2.c:322
#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "ブレークãƒã‚¤ãƒ³ãƒˆ \"%s%s\" 行 %<PRId64>"
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "ブレークãƒã‚¤ãƒ³ãƒˆ \"%s%s\" 行 %ld"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: ブレークãƒã‚¤ãƒ³ãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "ブレークãƒã‚¤ãƒ³ãƒˆãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
-#: ../ex_cmds2.c:617
#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s 行 %<PRId64>"
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s 行 %ld"
+
+#, c-format
+msgid "%3d expr %s"
+msgstr "%3d expr %s"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: åˆã‚ã« \":profile start {fname}\" を実行ã—ã¦ãã ã•ã„"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "変更を \"%s\" ã«ä¿å­˜ã—ã¾ã™ã‹?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "無題"
+#, c-format
+msgid "E947: Job still running in buffer \"%s\""
+msgstr "E947: ジョブã¯ãƒãƒƒãƒ•ã‚¡ \"%s\" ã§ã¾ã å®Ÿè¡Œä¸­ã§ã™"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: ãƒãƒƒãƒ•ã‚¡ \"%s\" ã®å¤‰æ›´ã¯ä¿å­˜ã•れã¦ã„ã¾ã›ã‚“"
-#: ../ex_cmds2.c:1480
msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
msgstr "警告: 予期ã›ãšä»–ãƒãƒƒãƒ•ã‚¡ã¸ç§»å‹•ã—ã¾ã—㟠(autocommands を調ã¹ã¦ãã ã•ã„)"
-#: ../ex_cmds2.c:1826
msgid "E163: There is only one file to edit"
msgstr "E163: 編集ã™ã‚‹ãƒ•ァイルã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“"
-#: ../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
#, 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\""
+msgid "not found in '%s': \"%s\""
+msgstr "'%s' ã®ä¸­ã«ã¯ã‚りã¾ã›ã‚“: \"%s\""
+
+#, c-format
+msgid "W20: Required python version 2.x not supported, ignoring file: %s"
+msgstr "W20: è¦æ±‚ã•れãŸpython 2.xã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“ã€ãƒ•ァイルを無視ã—ã¾ã™: %s"
+
+#, c-format
+msgid "W21: Required python version 3.x not supported, ignoring file: %s"
+msgstr "W21: è¦æ±‚ã•れãŸpython 3.xã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“ã€ãƒ•ァイルを無視ã—ã¾ã™: %s"
+
+msgid "Source Vim script"
+msgstr "Vimスクリプトã®å–è¾¼ã¿"
-#: ../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\" ã‚’å–è¾¼ã‚ã¾ã›ã‚“"
+msgid "line %ld: could not source \"%s\""
+msgstr "行 %ld: \"%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 ã‚’å–込中"
+msgid "line %ld: sourcing \"%s\""
+msgstr "行 %ld: %s ã‚’å–込中"
-#: ../ex_cmds2.c:2693
#, c-format
msgid "finished sourcing %s"
msgstr "%s ã®å–込を完了"
-#: ../ex_cmds2.c:2765
+#, c-format
+msgid "continuing in %s"
+msgstr "%s ã®å®Ÿè¡Œã‚’継続中ã§ã™"
+
msgid "modeline"
msgstr "モード行"
-#: ../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_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding ãŒå–込スクリプト以外ã§ä½¿ç”¨ã•れã¾ã—ãŸ"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish ãŒå–込スクリプト以外ã§ä½¿ç”¨ã•れã¾ã—ãŸ"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "ç¾åœ¨ã® %s言語: \"%s\""
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: 言語を \"%s\" ã«è¨­å®šã§ãã¾ã›ã‚“"
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr ""
"Exモードã«å…¥ã‚Šã¾ã™. ãƒŽãƒ¼ãƒžãƒ«ãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã‚‹ã«ã¯\"visual\"ã¨å…¥åŠ›ã—ã¦ãã ã•ã„."
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: ファイルã®çµ‚了ä½ç½®"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: コマンドãŒå†å¸°çš„éŽãŽã¾ã™"
-#: ../ex_docmd.c:1006
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: ä¾‹å¤–ãŒæ•æ‰ã•れã¾ã›ã‚“ã§ã—ãŸ: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "å–è¾¼ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¾Œã§ã™"
-#: ../ex_docmd.c:1086
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:1729
msgid "E493: Backwards range given"
msgstr "E493: 逆ã•ã¾ã®ç¯„å›²ãŒæŒ‡å®šã•れã¾ã—ãŸ"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
-msgstr "逆ã•ã¾ã®ç¯„å›²ãŒæŒ‡å®šã•れã¾ã—ãŸ, 入替ãˆã¾ã™ã‹?"
+msgstr "逆ã•ã¾ã®ç¯„å›²ãŒæŒ‡å®šã•れã¾ã—ãŸã€å…¥æ›¿ãˆã¾ã™ã‹?"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: w ã‚‚ã—ã㯠w>> を使用ã—ã¦ãã ã•ã„"
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“, ã”ã‚ã‚“ãªã•ã„"
+msgid "E943: Command table needs to be updated, run 'make cmdidxs'"
+msgstr ""
+"E943: コマンドテーブルを更新ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€'make cmdidxs' を実行ã—ã¦ãã "
+"ã•ã„"
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: ファイルå㯠1 ã¤ã«ã—ã¦ãã ã•ã„"
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“ã€ã”ã‚ã‚“ãªã•ã„"
-#: ../ex_docmd.c:4238
msgid "1 more file to edit. Quit anyway?"
-msgstr "編集ã™ã¹ãファイル㌠1 個ã‚りã¾ã™ãŒ, 終了ã—ã¾ã™ã‹?"
+msgstr "編集ã™ã¹ãファイル㌠1 個ã‚りã¾ã™ãŒã€çµ‚了ã—ã¾ã™ã‹?"
-#: ../ex_docmd.c:4242
#, c-format
msgid "%d more files to edit. Quit anyway?"
-msgstr "編集ã™ã¹ãファイルãŒã‚㨠%d 個ã‚りã¾ã™ãŒ, 終了ã—ã¾ã™ã‹?"
+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> 個ã‚りã¾ã™"
+msgid "E173: %ld more files to edit"
+msgstr "E173: 編集ã™ã¹ãファイルãŒã‚㨠%ld 個ã‚りã¾ã™"
-#: ../ex_docmd.c:4320
msgid "E174: Command already exists: add ! to replace it"
msgstr "E174: ã‚³ãƒžãƒ³ãƒ‰ãŒæ—¢ã«ã‚りã¾ã™: å†å®šç¾©ã™ã‚‹ã«ã¯ ! を追加ã—ã¦ãã ã•ã„"
-#: ../ex_docmd.c:4432
msgid ""
"\n"
" Name Args Address Complete Definition"
@@ -1637,51 +1359,40 @@ 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: カウントを2釿Œ‡å®šã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../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 ã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™"
msgid "E179: argument required for -addr"
msgstr "E179: -addr ã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™"
-#: ../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
msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E841: 予約åãªã®ã§, ユーザー定義コマンドã«åˆ©ç”¨ã§ãã¾ã›ã‚“"
+msgstr "E841: 予約åãªã®ã§ã€ãƒ¦ãƒ¼ã‚¶ãƒ¼å®šç¾©ã‚³ãƒžãƒ³ãƒ‰ã«åˆ©ç”¨ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: ãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å®šç¾©ã‚³ãƒžãƒ³ãƒ‰ã¯ã‚りã¾ã›ã‚“: %s"
@@ -1690,293 +1401,260 @@ msgstr "E184: ãã®ãƒ¦ãƒ¼ã‚¶ãƒ¼å®šç¾©ã‚³ãƒžãƒ³ãƒ‰ã¯ã‚りã¾ã›ã‚“: %s"
msgid "E180: Invalid address type value: %s"
msgstr "E180: 無効ãªã‚¢ãƒ‰ãƒ¬ã‚¹ã‚¿ã‚¤ãƒ—値ã§ã™: %s"
-#: ../ex_docmd.c:5219
#, 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: 補完引数ã¯ã‚«ã‚¹ã‚¿ãƒ è£œå®Œã§ã—ã‹ä½¿ç”¨ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: カスタム補完ã«ã¯å¼•æ•°ã¨ã—ã¦é–¢æ•°ãŒå¿…è¦ã§ã™"
-#: ../ex_docmd.c:5257
+msgid "unknown"
+msgstr "䏿˜Ž"
+
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: カラースキーム '%s' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "Vim 使ã„ã•ã‚“ã€ã‚„ã‚!"
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: 最後ã®ã‚¿ãƒ–ページを閉ã˜ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "æ—¢ã«ã‚¿ãƒ–ページã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:6004
+msgid "Edit File in new tab page"
+msgstr "æ–°ã—ã„タブページã§ãƒ•ァイルを編集ã—ã¾ã™"
+
+msgid "Edit File in new window"
+msgstr "æ–°ã—ã„ウィンドウã§ãƒ•ァイルを編集ã—ã¾ã™"
+
#, c-format
msgid "Tab page %d"
msgstr "タブページ %d"
-#: ../ex_docmd.c:6295
msgid "No swap file"
msgstr "スワップファイルãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:6478
+msgid "Append File"
+msgstr "追加ファイル"
+
msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
msgstr ""
-"E747: ãƒãƒƒãƒ•ã‚¡ãŒä¿®æ­£ã•れã¦ã„ã‚‹ã®ã§, ディレクトリを変更ã§ãã¾ã›ã‚“ (! を追加ã§"
+"E747: ãƒãƒƒãƒ•ã‚¡ãŒä¿®æ­£ã•れã¦ã„ã‚‹ã®ã§ã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’変更ã§ãã¾ã›ã‚“ (! を追加ã§"
"上書)"
-#: ../ex_docmd.c:6485
msgid "E186: No previous directory"
msgstr "E186: å‰ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¯ã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: 未知"
-#: ../ex_docmd.c:6610
msgid "E465: :winsize requires two number arguments"
msgstr "E465: :winsize ã«ã¯2ã¤ã®æ•°å€¤ã®å¼•æ•°ãŒå¿…è¦ã§ã™"
-#: ../ex_docmd.c:6655
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "ウィンドウä½ç½®: X %d, Y %d"
+
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 ã«ã¯2ã¤ã®æ•°å€¤ã®å¼•æ•°ãŒå¿…è¦ã§ã™"
-#: ../ex_docmd.c:7241
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: execute() ã®ä¸­ã§ã¯ :redir ã¯ä½¿ãˆã¾ã›ã‚“"
+
+msgid "Save Redirection"
+msgstr "リダイレクトをä¿å­˜ã—ã¾ã™"
+
+msgid "Save View"
+msgstr "ビューをä¿å­˜ã—ã¾ã™"
+
+msgid "Save Session"
+msgstr "セッション情報をä¿å­˜ã—ã¾ã™"
+
+msgid "Save Setup"
+msgstr "設定をä¿å­˜ã—ã¾ã™"
+
#, c-format
msgid "E739: Cannot create directory: %s"
msgstr "E739: ディレクトリを作æˆã§ãã¾ã›ã‚“: %s"
-#: ../ex_docmd.c:7268
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: \"%s\" ãŒå­˜åœ¨ã—ã¾ã™ (上書ã™ã‚‹ã«ã¯ ! を追加ã—ã¦ãã ã•ã„)"
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: \"%s\" を書込ã¿ç”¨ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“"
-#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: 引数ã¯1文字ã®è‹±å­—ã‹å¼•用符 (' ã‹ `) ã§ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: :normal ã®å†å¸°åˆ©ç”¨ãŒæ·±ããªã‚ŠéŽãŽã¾ã—ãŸ"
-#: ../ex_docmd.c:7807
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< 㯠+eval 機能ãŒç„¡ã„ã¨åˆ©ç”¨ã§ãã¾ã›ã‚“"
+
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: '#'ã‚’ç½®ãæ›ãˆã‚‹å‰¯ãƒ•ァイルã®åå‰ãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: \"<afile>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandã®ãƒ•ァイルåãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: \"<abuf>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandãƒãƒƒãƒ•ァ番å·ãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7861
msgid "E497: no autocommand match name to substitute for \"<amatch>\""
msgstr "E497: \"<amatch>\"ã‚’ç½®ãæ›ãˆã‚‹autocommandã®è©²å½“åãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7870
msgid "E498: no :source file name to substitute for \"<sfile>\""
msgstr "E498: \"<sfile>\"ã‚’ç½®ãæ›ãˆã‚‹ :source 対象ファイルåãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: \"<slnum>\"ã‚’ç½®ãæ›ãˆã‚‹è¡Œç•ªå·ãŒã‚りã¾ã›ã‚“"
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, no-c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr ""
"E499: '%' ã‚„ '#' ãŒç„¡åファイルãªã®ã§ \":p:h\" ã‚’ä¼´ã‚ãªã„ä½¿ã„æ–¹ã¯ã§ãã¾ã›ã‚“"
-#: ../ex_docmd.c:7905
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_eval.c:464
+msgid "Untitled"
+msgstr "無題"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«åˆå­—ã¯ã‚りã¾ã›ã‚“"
+
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: 'Vim' ã§å§‹ã¾ã‚‹ä¾‹å¤–㯠:throw ã§ãã¾ã›ã‚“"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "例外ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "例外ãŒåŽæŸã—ã¾ã—ãŸ: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "例外ãŒç ´æ£„ã•れã¾ã—ãŸ: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, 行 %<PRId64>"
+msgid "%s, line %ld"
+msgstr "%s, 行 %ld"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "ä¾‹å¤–ãŒæ•æ‰ã•れã¾ã—ãŸ: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "%s ã«ã‚ˆã‚Šæœªæ±ºå®šçŠ¶æ…‹ãŒç”Ÿã˜ã¾ã—ãŸ"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "%s ãŒå†é–‹ã—ã¾ã—ãŸ"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "%s ãŒç ´æ£„ã•れã¾ã—ãŸ"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "例外"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "エラーã¨å‰²è¾¼ã¿"
-#: ../ex_eval.c:715
msgid "Error"
msgstr "エラー"
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "割込ã¿"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: :if ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :if ã®ãªã„ :endif ãŒã‚りã¾ã™"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :if ã®ãªã„ :else ãŒã‚りã¾ã™"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :if ã®ãªã„ :elseif ãŒã‚りã¾ã™"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: 複数㮠:else ãŒã‚りã¾ã™"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :else ã®å¾Œã« :elseif ãŒã‚りã¾ã™"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: :while ã‚„ :for ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :while ã‚„ :for ã®ãªã„ :continue ãŒã‚りã¾ã™"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :while ã‚„ :for ã®ãªã„ :break ãŒã‚りã¾ã™"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: :endfor ã‚’ :while ã¨çµ„ã¿åˆã‚ã›ã¦ã„ã¾ã™"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: :endwhile ã‚’ :for ã¨çµ„ã¿åˆã‚ã›ã¦ã„ã¾ã™"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: :try ã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../ex_eval.c:1317
msgid "E603: :catch without :try"
msgstr "E603: :try ã®ãªã„ :catch ãŒã‚りã¾ã™"
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
msgid "E604: :catch after :finally"
msgstr "E604: :finally ã®å¾Œã« :catch ãŒã‚りã¾ã™"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :try ã®ãªã„ :finally ãŒã‚りã¾ã™"
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: 複数㮠:finally ãŒã‚りã¾ã™"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :try ã®ãªã„ :endtry ã§ã™"
-#: ../ex_eval.c:2026
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
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: ç¾åœ¨ã¯ãƒãƒƒãƒ•ァ情報を変更ã™ã‚‹ã“ã¨ã¯è¨±ã•れã¾ã›ã‚“"
-#: ../ex_getln.c:3178
msgid "tagname"
msgstr "ã‚¿ã‚°å"
-#: ../ex_getln.c:3181
msgid " kind file\n"
msgstr " ファイル種類\n"
-#: ../ex_getln.c:4799
msgid "'history' option is zero"
msgstr "オプション 'history' ãŒã‚¼ãƒ­ã§ã™"
-#: ../ex_getln.c:5046
#, c-format
msgid ""
"\n"
@@ -1985,303 +1663,220 @@ msgstr ""
"\n"
"# %s é …ç›®ã®å±¥æ­´ (æ–°ã—ã„ã‚‚ã®ã‹ã‚‰å¤ã„ã‚‚ã®ã¸):\n"
-#: ../ex_getln.c:5047
msgid "Command Line"
msgstr "コマンドライン"
-#: ../ex_getln.c:5048
msgid "Search String"
msgstr "検索文字列"
-#: ../ex_getln.c:5049
msgid "Expression"
msgstr "å¼"
-#: ../ex_getln.c:5050
msgid "Input Line"
msgstr "入力行"
-#: ../ex_getln.c:5117
+msgid "Debug Line"
+msgstr "デãƒãƒƒã‚°è¡Œ"
+
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar ãŒã‚³ãƒžãƒ³ãƒ‰é•·ã‚’è¶…ãˆã¾ã—ãŸ"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: アクティブãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ãƒãƒƒãƒ•ã‚¡ãŒå‰Šé™¤ã•れã¾ã—ãŸ"
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: パスãŒé•·éŽãŽã¦è£œå®Œã§ãã¾ã›ã‚“"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: 無効ãªãƒ‘スã§ã™: '**[数値]' ã¯pathã®æœ€å¾Œã‹ '%s' ãŒç¶šã„ã¦ãªã„ã¨ã„ã‘ã¾ã›"
-"ã‚“."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: cdpathã«ã¯ã“れ以上 \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: パスã«ã¯ã“れ以上 \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: autocommandãŒãƒãƒƒãƒ•ã‚¡ã‹ãƒãƒƒãƒ•ã‚¡åを変更ã—ã¾ã—ãŸ"
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "䏿­£ãªãƒ•ァイルå"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "ã¯ãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“"
-#: ../fileio.c:508 ../fileio.c:3522
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "ã¯ãƒ‡ãƒã‚¤ã‚¹ã§ã™ ('opendevice' オプションã§å›žé¿ã§ãã¾ã™)"
+
msgid "[New File]"
msgstr "[新ファイル]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[æ–°è¦ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[ファイルéŽå¤§]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[権é™ãŒã‚りã¾ã›ã‚“]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: *ReadPre autocommand ãŒãƒ•ァイルを読込ä¸å¯ã«ã—ã¾ã—ãŸ"
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: *ReadPre autocommand ã¯ç¾åœ¨ã®ãƒãƒƒãƒ•ァを変ãˆã‚‰ã‚Œã¾ã›ã‚“"
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
+msgid "Vim: Reading from stdin...\n"
msgstr "Vim: 標準入力ã‹ã‚‰èª­è¾¼ä¸­...\n"
-#. Re-opening the original file failed!
-#: ../fileio.c:909
+msgid "Reading from stdin..."
+msgstr "標準入力ã‹ã‚‰èª­è¾¼ã¿ä¸­..."
+
msgid "E202: Conversion made file unreadable!"
msgstr "E202: 変æ›ãŒãƒ•ァイルを読込ä¸å¯ã«ã—ã¾ã—ãŸ"
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[FIFO/ソケット]"
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[FIFO]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[ソケット]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[キャラクタ・デãƒã‚¤ã‚¹]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[CRç„¡]"
-#: ../fileio.c:1819
msgid "[long lines split]"
msgstr "[長行分割]"
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[未変æ›]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[å¤‰æ›æ¸ˆ]"
-#: ../fileio.c:1831
#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[%<PRId64> 行目ã§å¤‰æ›ã‚¨ãƒ©ãƒ¼]"
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[%ld 行目ã§å¤‰æ›ã‚¨ãƒ©ãƒ¼]"
-#: ../fileio.c:1835
#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[%<PRId64> 行目ã®ä¸æ­£ãªãƒã‚¤ãƒˆ]"
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[%ld 行目ã®ä¸æ­£ãªãƒã‚¤ãƒˆ]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[読込エラー]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "変æ›ã«å¿…è¦ãªä¸€æ™‚ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "'charconvert' ã«ã‚ˆã‚‹å¤‰æ›ãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "'charconvert' ã®å‡ºåŠ›ã‚’èª­è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ"
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: acwriteãƒãƒƒãƒ•ã‚¡ã®è©²å½“ã™ã‚‹autocommandã¯å­˜åœ¨ã—ã¾ã›ã‚“"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: ä¿å­˜ã™ã‚‹ãƒãƒƒãƒ•ã‚¡ã‚’autocommandãŒå‰Šé™¤ã‹è§£æ”¾ã—ã¾ã—ãŸ"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: autocommandãŒäºˆæœŸã›ã¬æ–¹æ³•ã§è¡Œæ•°ã‚’変更ã—ã¾ã—ãŸ"
-#: ../fileio.c:2548 ../fileio.c:2565
+# Added at 19-Jan-2004.
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeansã¯æœªå¤‰æ›´ã®ãƒãƒƒãƒ•ァを上書ã™ã‚‹ã“ã¨ã¯è¨±å¯ã—ã¦ã„ã¾ã›ã‚“"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "NetBeansãƒãƒƒãƒ•ã‚¡ã®ä¸€éƒ¨ã‚’書ã出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
msgid "is not a file or writable device"
msgstr "ã¯ãƒ•ァイルã§ã‚‚書込ã¿å¯èƒ½ãƒ‡ãƒã‚¤ã‚¹ã§ã‚‚ã‚りã¾ã›ã‚“"
-#: ../fileio.c:2601
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "'opendevice' オプションã«ã‚ˆã‚Šãƒ‡ãƒã‚¤ã‚¹ã¸ã®æ›¸ãè¾¼ã¿ã¯ã§ãã¾ã›ã‚“"
+
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:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを作れã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶ä½œæˆ)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを作れã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶ä½œæˆ)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
msgid "E214: Can't find temp file for writing"
msgstr "E214: ä¿å­˜ç”¨ä¸€æ™‚ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: 変æ›ã§ãã¾ã›ã‚“ (! を追加ã§å¤‰æ›ã›ãšã«ä¿å­˜)"
-#: ../fileio.c:3169
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: fsync ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E949: File changed while writing"
+msgstr "E949: 書込ã¿ä¸­ã«ãƒ•ァイルãŒå¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../fileio.c:3398
msgid "E512: Close failed"
msgstr "E512: é–‰ã˜ã‚‹ã“ã¨ã«å¤±æ•—"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: 書込ã¿ã‚¨ãƒ©ãƒ¼, 変æ›å¤±æ•— (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•ã„)"
+msgstr "E513: 書込ã¿ã‚¨ãƒ©ãƒ¼ã€å¤‰æ›å¤±æ•— (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•ã„)"
-#: ../fileio.c:3441
#, c-format
msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
"override)"
msgstr ""
-"E513: 書込ã¿ã‚¨ãƒ©ãƒ¼, 変æ›å¤±æ•—, 行数 %<PRId64> (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦"
-"ãã ã•ã„)"
+"E513: 書込ã¿ã‚¨ãƒ©ãƒ¼ã€å¤‰æ›å¤±æ•—ã€è¡Œæ•° %ld (上書ã™ã‚‹ã«ã¯ 'fenc' を空ã«ã—ã¦ãã ã•"
+"ã„)"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
-msgstr "E514: 書込ã¿ã‚¨ãƒ©ãƒ¼, (ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ãŒæº€æ¯?)"
+msgstr "E514: 書込ã¿ã‚¨ãƒ©ãƒ¼ (ãƒ•ã‚¡ã‚¤ãƒ«ã‚·ã‚¹ãƒ†ãƒ ãŒæº€æ¯?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " 変æ›ã‚¨ãƒ©ãƒ¼"
-#: ../fileio.c:3509
#, c-format
-msgid " in line %<PRId64>;"
-msgstr " 行 %<PRId64>;"
+msgid " in line %ld;"
+msgstr " 行 %ld;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[デãƒã‚¤ã‚¹]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[æ–°]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr " [a]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " 追加"
-#: ../fileio.c:3537
msgid " [w]"
msgstr " [w]"
-#: ../fileio.c:3537
msgid " written"
msgstr " 書込ã¿"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: patchmode: 原本ファイルをä¿å­˜ã§ãã¾ã›ã‚“"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: patchmode: 空ã®åŽŸæœ¬ãƒ•ã‚¡ã‚¤ãƒ«ã‚’touchã§ãã¾ã›ã‚“"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ファイルを消ã›ã¾ã›ã‚“"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2289,134 +1884,102 @@ msgstr ""
"\n"
"警告: 原本ファイルãŒå¤±ã‚れãŸã‹å¤‰æ›´ã•れã¾ã—ãŸ\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "ファイルã®ä¿å­˜ã«æˆåŠŸã™ã‚‹ã¾ã§ã‚¨ãƒ‡ã‚£ã‚¿ã‚’終了ã—ãªã„ã§ãã ã•ã„!"
-#: ../fileio.c:3795
msgid "[dos]"
msgstr "[dos]"
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[dosフォーマット]"
-#: ../fileio.c:3801
msgid "[mac]"
msgstr "[mac]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[macフォーマット]"
-#: ../fileio.c:3807
msgid "[unix]"
msgstr "[unix]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[unixフォーマット]"
-#: ../fileio.c:3831
msgid "1 line, "
msgstr "1 行, "
-#: ../fileio.c:3833
#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> 行, "
+msgid "%ld lines, "
+msgstr "%ld 行, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "1 文字"
-#: ../fileio.c:3838
#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> 文字"
+msgid "%lld characters"
+msgstr "%lld 文字"
-#: ../fileio.c:3849
msgid "[noeol]"
msgstr "[noeol]"
-#: ../fileio.c:3849
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
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "警告: 読込んã å¾Œã«ãƒ•ァイルã«å¤‰æ›´ãŒã‚りã¾ã—ãŸ!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "本当ã«ä¸Šæ›¸ãã—ã¾ã™ã‹"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: \"%s\" を書込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: \"%s\" ã‚’é–‰ã˜ã‚‹æ™‚ã«ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: \"%s\" を読込中ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: autocommand ã® FileChangedShell ãŒãƒãƒƒãƒ•ァを削除ã—ã¾ã—ãŸ"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: ファイル \"%s\" ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã›ã‚“"
-#: ../fileio.c:4906
#, 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
msgid "See \":help W12\" for more info."
msgstr "詳細㯠\":help W12\" ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: 警告: ファイル \"%s\" ã¯ç·¨é›†é–‹å§‹å¾Œã«å¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "詳細㯠\":help W11\" ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr "W16: 警告: ファイル \"%s\" ã®ãƒ¢ãƒ¼ãƒ‰ãŒç·¨é›†é–‹å§‹å¾Œã«å¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "詳細㯠\":help W16\" ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: 警告: ファイル \"%s\" ã¯ç·¨é›†é–‹å§‹å¾Œã«ä½œæˆã•れã¾ã—ãŸ"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "警告"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2424,810 +1987,593 @@ msgstr ""
"&OK\n"
"ファイル読込(&L)"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: \"%s\" をリロードã™ã‚‹æº–å‚™ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#: ../fileio.c:5078
#, 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 "autocommand: %s <ãƒãƒƒãƒ•ã‚¡=%d> ãŒè‡ªå‹•çš„ã«å‰Šé™¤ã•れã¾ã™"
-#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: ãã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚りã¾ã›ã‚“: \"%s\""
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: ç¾åœ¨ã®ã‚°ãƒ«ãƒ¼ãƒ—ã¯å‰Šé™¤ã§ãã¾ã›ã‚“"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: 使用中㮠augroup を消ãã†ã¨ã—ã¦ã„ã¾ã™"
+
#, 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"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <ãƒãƒƒãƒ•ã‚¡=%d>: 無効ãªãƒãƒƒãƒ•ァ番å·ã§ã™ "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: å…¨ã¦ã®ã‚¤ãƒ™ãƒ³ãƒˆã«å¯¾ã—ã¦ã®autocommandã¯å®Ÿè¡Œã§ãã¾ã›ã‚“"
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "該当ã™ã‚‹autocommandã¯å­˜åœ¨ã—ã¾ã›ã‚“"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: autocommandã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
+msgstr "%s Autocommands for \"%s\""
-#: ../fileio.c:7149
#, c-format
msgid "Executing %s"
msgstr "%s を実行ã—ã¦ã„ã¾ã™"
-#: ../fileio.c:7211
#, c-format
msgid "autocommand %s"
msgstr "autocommand %s"
-#: ../fileio.c:7795
msgid "E219: Missing {."
msgstr "E219: { ãŒã‚りã¾ã›ã‚“."
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: } ãŒã‚りã¾ã›ã‚“."
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: 折畳ã¿ãŒã‚りã¾ã›ã‚“"
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: ç¾åœ¨ã® 'foldmethod' ã§ã¯æŠ˜ç•³ã¿ã‚’作æˆã§ãã¾ã›ã‚“"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: ç¾åœ¨ã® 'foldmethod' ã§ã¯æŠ˜ç•³ã¿ã‚’削除ã§ãã¾ã›ã‚“"
-#: ../fold.c:1784
#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld è¡ŒãŒæŠ˜ç•³ã¾ã‚Œã¾ã—㟠"
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld è¡ŒãŒæŠ˜ç•³ã¾ã‚Œã¾ã—ãŸ"
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: 読込ãƒãƒƒãƒ•ã‚¡ã¸è¿½åŠ "
-#: ../getchar.c:2040
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
-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
-msgid "E470: Command aborted"
-msgstr "E470: コマンドãŒä¸­æ–­ã•れã¾ã—ãŸ"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: 引数ãŒå¿…è¦ã§ã™"
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: GUI用ã®ãƒ—ロセスã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ ã®å¾Œã¯ / ã‹ ? ã‹ & ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: å­ãƒ—ロセスãŒGUIã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: コマンドラインã§ã¯ç„¡åйã§ã™; <CR>ã§å®Ÿè¡Œ, CTRL-Cã§ã‚„ã‚ã‚‹"
+msgid "E229: Cannot start the GUI"
+msgstr "E229: GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“"
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚„タグ検索ã§ã¯exrc/vimrcã®ã‚³ãƒžãƒ³ãƒ‰ã¯è¨±å¯ã•れã¾ã›ã‚“"
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: \"%s\"ã‹ã‚‰èª­è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“"
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif ãŒã‚りã¾ã›ã‚“"
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: 有効ãªãƒ•ォントãŒè¦‹ã¤ã‹ã‚‰ãªã„ã®ã§ã€GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“"
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry ãŒã‚りã¾ã›ã‚“"
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' ãŒç„¡åйã§ã™"
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile ãŒã‚りã¾ã›ã‚“"
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: 'imactivatekey' ã«è¨­å®šã•れãŸå€¤ãŒç„¡åйã§ã™"
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor ãŒã‚りã¾ã›ã‚“"
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: %s ã®è‰²ã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :while ã®ãªã„ :endwhile ãŒã‚りã¾ã™"
+msgid "No match at cursor, finding next"
+msgstr "カーソルã®ä½ç½®ã«ãƒžãƒƒãƒã¯ã‚りã¾ã›ã‚“ã€æ¬¡ã‚’検索ã—ã¦ã„ã¾ã™"
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor ã®ãªã„ :for ãŒã‚りã¾ã™"
+msgid "<cannot open> "
+msgstr "<é–‹ã‘ã¾ã›ã‚“> "
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: ファイルãŒå­˜åœ¨ã—ã¾ã™ (! を追加ã§ä¸Šæ›¸)"
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: フォント %s ã‚’å–å¾—ã§ãã¾ã›ã‚“"
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: コマンドãŒå¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æˆ»ã‚Œã¾ã›ã‚“"
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: 内部エラーã§ã™"
+msgid "Pathname:"
+msgstr "パスå:"
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "割込ã¾ã‚Œã¾ã—ãŸ"
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“"
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: 無効ãªã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã™"
+msgid "OK"
+msgstr "OK"
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: 無効ãªå¼•æ•°ã§ã™"
+msgid "Cancel"
+msgstr "キャンセル"
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: 無効ãªå¼•æ•°ã§ã™: %s"
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "スクロールãƒãƒ¼: ç”»åƒã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ."
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: 無効ãªå¼ã§ã™: %s"
+msgid "Vim dialog"
+msgstr "Vim ダイアログ"
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: 無効ãªç¯„囲ã§ã™"
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr "E232: メッセージã¨ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®ã‚ã‚‹ BalloonEval を作æˆã§ãã¾ã›ã‚“"
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: 無効ãªã‚³ãƒžãƒ³ãƒ‰ã§ã™"
+msgid "_Cancel"
+msgstr "キャンセル(_C)"
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™"
+msgid "_Save"
+msgstr "ä¿å­˜(_S)"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: 無効ãªã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«é‡ã§ã™"
+msgid "_Open"
+msgstr "é–‹ã(_O)"
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
+msgid "_OK"
+msgstr "_OK"
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
msgstr ""
+"ã¯ã„(&Y)\n"
+"ã„ã„ãˆ(&N)\n"
+"キャンセル(&C)"
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: \"%s\"() ã®ãƒ©ã‚¤ãƒ–ラリ呼出ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "Yes"
+msgstr "ã¯ã„"
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: マークã«ç„¡åйãªè¡Œç•ªå·ãŒæŒ‡å®šã•れã¦ã„ã¾ã—ãŸ"
+msgid "No"
+msgstr "ã„ã„ãˆ"
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
+msgid "Input _Methods"
+msgstr "インプットメソッド"
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: 'modifiable' ãŒã‚ªãƒ•ãªã®ã§, 変更ã§ãã¾ã›ã‚“"
+msgid "VIM - Search and Replace..."
+msgstr "VIM - 検索ã¨ç½®æ›..."
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: スクリプトã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: 副ファイルã¯ã‚りã¾ã›ã‚“"
+msgid "VIM - Search..."
+msgstr "VIM - 検索..."
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ãã®ã‚ˆã†ãªçŸ­ç¸®å…¥åŠ›ã¯ã‚りã¾ã›ã‚“"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ! ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+msgid "Find what:"
+msgstr "検索文字列:"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUIã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™"
+msgid "Replace with:"
+msgstr "ç½®æ›æ–‡å­—列:"
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ãã®ã‚ˆã†ãªåã®ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚りã¾ã›ã‚“: %s"
+msgid "Match whole word only"
+msgstr "正確ã«è©²å½“ã™ã‚‹ã‚‚ã®ã ã‘"
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ã¾ã ãƒ†ã‚­ã‚¹ãƒˆãŒæŒ¿å…¥ã•れã¦ã„ã¾ã›ã‚“"
+msgid "Match case"
+msgstr "大文字/å°æ–‡å­—を区別ã™ã‚‹"
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: 以å‰ã«ã‚³ãƒžãƒ³ãƒ‰è¡ŒãŒã‚りã¾ã›ã‚“"
+msgid "Direction"
+msgstr "æ–¹å‘"
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ãã®ã‚ˆã†ãªãƒžãƒƒãƒ”ングã¯ã‚りã¾ã›ã‚“"
+msgid "Up"
+msgstr "上"
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: 該当ã¯ã‚りã¾ã›ã‚“"
+msgid "Down"
+msgstr "下"
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: 該当ã¯ã‚りã¾ã›ã‚“: %s"
+msgid "Find Next"
+msgstr "次を検索"
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ファイルåãŒã‚りã¾ã›ã‚“"
+msgid "Replace"
+msgstr "ç½®æ›"
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: æ­£è¦è¡¨ç¾ç½®æ›ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
+msgid "Replace All"
+msgstr "å…¨ã¦ç½®æ›"
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: コマンドãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
+msgid "_Close"
+msgstr "é–‰ã˜ã‚‹(_C)"
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: æ­£è¦è¡¨ç¾ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: セッションマãƒãƒ¼ã‚¸ãƒ£ã‹ã‚‰ \"die\" è¦æ±‚ã‚’å—ã‘å–りã¾ã—ãŸ\n"
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: 範囲指定ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+msgid "Close tab"
+msgstr "タブページを閉ã˜ã‚‹"
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: ウィンドウã«å分ãªé«˜ã•ã‚‚ã—ãã¯å¹…ãŒã‚りã¾ã›ã‚“"
+msgid "New tab"
+msgstr "æ–°è¦ã‚¿ãƒ–ページ"
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: ファイル %s を作æˆã§ãã¾ã›ã‚“"
+msgid "Open Tab..."
+msgstr "タブページを開ã..."
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: 一時ファイルã®åå‰ã‚’å–å¾—ã§ãã¾ã›ã‚“"
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: メインウィンドウãŒä¸æ„ã«ç ´å£Šã•れã¾ã—ãŸ\n"
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
+msgid "&Filter"
+msgstr "フィルタ(&F)"
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: ファイル %s を読込ã‚ã¾ã›ã‚“"
+msgid "&Cancel"
+msgstr "キャンセル(&C)"
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“ (! を追加ã§å¤‰æ›´ã‚’破棄)"
+msgid "Directories"
+msgstr "ディレクトリ"
-#: ../globals.h:1055
-msgid "E37: No write since last change"
-msgstr "E37: 最後ã®å¤‰æ›´ãŒä¿å­˜ã•れã¦ã„ã¾ã›ã‚“"
+msgid "Filter"
+msgstr "フィルタ"
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: 引数ãŒç©ºã§ã™"
+msgid "&Help"
+msgstr "ヘルプ(&H)"
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: 数値ãŒè¦æ±‚ã•れã¦ã„ã¾ã™"
+msgid "Files"
+msgstr "ファイル"
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: エラーファイル %s ã‚’é–‹ã‘ã¾ã›ã‚“"
+msgid "&OK"
+msgstr "&OK"
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: メモリãŒå°½ãæžœã¦ã¾ã—ãŸ!"
+msgid "Selection"
+msgstr "é¸æŠž"
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
+msgid "Find &Next"
+msgstr "次を検索(&N)"
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s"
+msgid "&Replace"
+msgstr "ç½®æ›(&R)"
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: å¼•æ•°ã¯æ­£ã®å€¤ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgid "Replace &All"
+msgstr "å…¨ã¦ç½®æ›(&A)"
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: å‰ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æˆ»ã‚Œã¾ã›ã‚“"
+msgid "&Undo"
+msgstr "アンドゥ(&U)"
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: エラーã¯ã‚りã¾ã›ã‚“"
+msgid "Open tab..."
+msgstr "タブページを開ã"
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: ロケーションリストã¯ã‚りã¾ã›ã‚“"
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "検索文字列 ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: 該当文字列ãŒç ´æã—ã¦ã„ã¾ã™"
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "æ¤œç´¢ãƒ»ç½®æ› ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: 䏿­£ãªæ­£è¦è¡¨ç¾ãƒ—ログラムã§ã™"
+msgid "Not Used"
+msgstr "使ã‚れã¾ã›ã‚“"
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: 'readonly' オプションãŒè¨­å®šã•れã¦ã„ã¾ã™ (! を追加ã§ä¸Šæ›¸ã)"
+msgid "Directory\t*.nothing\n"
+msgstr "ディレクトリ\t*.nothing\n"
-#: ../globals.h:1073
#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: 読å–専用変数 \"%s\" ã«ã¯å€¤ã‚’設定ã§ãã¾ã›ã‚“"
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: タイトル㌠\"%s\" ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../globals.h:1075
#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: サンドボックスã§ã¯å¤‰æ•° \"%s\" ã«å€¤ã‚’設定ã§ãã¾ã›ã‚“"
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: 引数ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“: \"-%s\"; OLE版を使用ã—ã¦ãã ã•ã„."
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: エラーファイルã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: MDIアプリã®ä¸­ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr "Vim E458: è‰²æŒ‡å®šãŒæ­£ã—ããªã„ã®ã§ã‚¨ãƒ³ãƒˆãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ã“ã“ã§ã¯è¨±å¯ã•れã¾ã›ã‚“"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: スクリーンモードã®è¨­å®šã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: 無効ãªã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«é‡ã§ã™"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: 'shell' オプションãŒç©ºã§ã™"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: sign ã®ãƒ‡ãƒ¼ã‚¿ã‚’読込ã‚ã¾ã›ã‚“ã§ã—ãŸ"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: スワップファイルã®ã‚¯ãƒ­ãƒ¼ã‚ºæ™‚エラーã§ã™"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: タグスタックãŒç©ºã§ã™"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: コマンドãŒè¤‡é›‘éŽãŽã¾ã™"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: åå‰ãŒé•·éŽãŽã¾ã™"
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: ä»¥ä¸‹ã®æ–‡å­—セットã®ãƒ•ォントãŒã‚りã¾ã›ã‚“ %s:"
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: [ ãŒå¤šéŽãŽã¾ã™"
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: フォントセットå: %s"
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ファイルåãŒå¤šéŽãŽã¾ã™"
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "フォント '%s' ã¯å›ºå®šå¹…ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: ä½™åˆ†ãªæ–‡å­—ãŒå¾Œã‚ã«ã‚りã¾ã™"
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: フォントセットå: %s"
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: 未知ã®ãƒžãƒ¼ã‚¯"
+#, c-format
+msgid "Font0: %s"
+msgstr "フォント0: %s"
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: ワイルドカードを展開ã§ãã¾ã›ã‚“"
+#, c-format
+msgid "Font1: %s"
+msgstr "フォント1: %s"
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' 㯠'winminheight' よりå°ã•ãã§ãã¾ã›ã‚“"
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "フォント%ld ã®å¹…ãŒãƒ•ォント0ã®2å€ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' 㯠'winminwidth' よりå°ã•ãã§ãã¾ã›ã‚“"
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "フォント0ã®å¹…: %ld"
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: 書込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼"
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "フォント1ã®å¹…: %ld"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "ゼロカウント"
+msgid "Invalid font specification"
+msgstr "無効ãªãƒ•ォント指定ã§ã™"
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: スクリプト以外ã§<SID>ãŒä½¿ã‚れã¾ã—ãŸ"
+msgid "&Dismiss"
+msgstr "å´ä¸‹ã™ã‚‹(&D)"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: 内部エラーã§ã™: %s"
+msgid "no specific match"
+msgstr "マッãƒã™ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“"
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: パターン㌠'maxmempattern' 以上ã®ãƒ¡ãƒ¢ãƒªã‚’使用ã—ã¾ã™"
+msgid "Vim - Font Selector"
+msgstr "Vim - ãƒ•ã‚©ãƒ³ãƒˆé¸æŠž"
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: ãƒãƒƒãƒ•ã‚¡ãŒç©ºã§ã™"
+msgid "Name:"
+msgstr "åå‰:"
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: 検索パターンã‹åŒºåˆ‡ã‚Šè¨˜å·ãŒä¸æ­£ã§ã™"
+msgid "Show size in Points"
+msgstr "サイズをãƒã‚¤ãƒ³ãƒˆã§è¡¨ç¤ºã™ã‚‹"
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: åŒã˜åå‰ã®ãƒ•ァイルãŒä»–ã®ãƒãƒƒãƒ•ã‚¡ã§èª­è¾¼ã¾ã‚Œã¦ã„ã¾ã™"
+msgid "Encoding:"
+msgstr "エンコード:"
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: オプション '%s' ã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
+msgid "Font:"
+msgstr "フォント:"
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: 無効ãªãƒ¬ã‚¸ã‚¹ã‚¿åã§ã™"
+msgid "Style:"
+msgstr "スタイル:"
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "上ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸‹ã«æˆ»ã‚Šã¾ã™"
+msgid "Size:"
+msgstr "サイズ:"
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "下ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸Šã«æˆ»ã‚Šã¾ã™"
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ãƒãƒ³ã‚°ãƒ«ã‚ªãƒ¼ãƒˆãƒžãƒˆãƒ³ã‚¨ãƒ©ãƒ¼"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: コロンãŒã‚りã¾ã›ã‚“"
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: 䏿­£ãªæ§‹æ–‡è¦ç´ ã§ã™"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: 数値ãŒå¿…è¦ã§ã™"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "%d ページ"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "å°åˆ·ã™ã‚‹ãƒ†ã‚­ã‚¹ãƒˆãŒã‚りã¾ã›ã‚“"
-#: ../hardcopy.c:668
#, c-format
msgid "Printing page %d (%d%%)"
msgstr "å°åˆ·ä¸­: ページ %d (%d%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " コピー %d (全 %d 中)"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "å°åˆ·ã—ã¾ã—ãŸ: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "å°åˆ·ãŒä¸­æ­¢ã•れã¾ã—ãŸ"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: PostScriptå‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"%s\" を読込ã‚ã¾ã›ã‚“"
-#: ../hardcopy.c:1772
#, 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
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: ファイル \"%s\" ã¯å¯¾å¿œã—ã¦ã„ãªã„ PostScript リソースファイルã§ã™"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: リソースファイル \"%s\" ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒç•°ãªã‚Šã¾ã™"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: äº’æ›æ€§ã®ç„¡ã„マルãƒãƒã‚¤ãƒˆã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã¨æ–‡å­—セットã§ã™"
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr "E674: マルãƒãƒã‚¤ãƒˆã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã§ã¯ printmbcharset を空ã«ã§ãã¾ã›ã‚“"
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr ""
"E675: マルãƒãƒã‚¤ãƒˆæ–‡å­—ã‚’å°åˆ·ã™ã‚‹ãŸã‚ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆãƒ•ã‚©ãƒ³ãƒˆãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: PostScript出力用ã®ãƒ•ァイルを開ã‘ã¾ã›ã‚“"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"prolog.ps\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"cidfont.ps\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: PostScriptã®ãƒªã‚½ãƒ¼ã‚¹ãƒ•ァイル \"%s.ps\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: å°åˆ·ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ \"%s\" ã¸å¤‰æ›ã§ãã¾ã›ã‚“"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "プリンタã«é€ä¿¡ä¸­..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: PostScriptファイルã®å°åˆ·ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "å°åˆ·ã‚¸ãƒ§ãƒ–ã‚’é€ä¿¡ã—ã¾ã—ãŸ."
-#: ../if_cscope.c:85
msgid "Add a new database"
msgstr "新データベースを追加"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "パターンã®ã‚¯ã‚¨ãƒªãƒ¼ã‚’追加"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã™ã‚‹"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "接続を終了ã™ã‚‹"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "å…¨ã¦ã®æŽ¥ç¶šã‚’å†åˆæœŸåŒ–ã™ã‚‹"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "接続を表示ã™ã‚‹"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: 使用方法: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "ã“ã®cscopeコマンドã¯åˆ†å‰²ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: 使用法: cstag <ident>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
msgstr "E257: cstag: ã‚¿ã‚°ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: stat(%s) エラー: %d"
-#: ../if_cscope.c:551
+msgid "E563: stat error"
+msgstr "E563: stat エラー"
+
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªåŠã³æœ‰åйãªcscopeã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã§ã¯ã‚りã¾ã›ã‚“"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "cscopeデータベース %s を追加"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: cscopeã®æŽ¥ç¶š %<PRId64> を読込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: cscopeã®æŽ¥ç¶š %ld を読込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: 未知ã®cscope検索型ã§ã™"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: cscopeパイプを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: cscopeã®èµ·å‹•準備(fork)ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:849
msgid "cs_create_connection setpgid failed"
msgstr "cs_create_connection ã¸ã® setpgid ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "cs_create_connection ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection: to_fp ã® fdopen ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection: fr_fp ã® fdopen ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: cscopeプロセスを起動ã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: cscope接続ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: 無効㪠cscopequickfix フラグ %c ã® %c ã§ã™"
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: cscopeクエリー %s of %s ã«è©²å½“ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "cscopeコマンド:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (使用法: %s)"
-#: ../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"
@@ -3238,6 +2584,7 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: ã“ã®ã‚·ãƒ³ãƒœãƒ«ã«å¯¾ã™ã‚‹ä»£å…¥ã‚’探ã™\n"
" c: ã“ã®é–¢æ•°ã‚’呼んã§ã„る関数を探ã™\n"
" d: ã“ã®é–¢æ•°ã‹ã‚‰å‘¼ã‚“ã§ã„る関数を探ã™\n"
" e: ã“ã®egrepパターンを探ã™\n"
@@ -3247,31 +2594,31 @@ msgstr ""
" s: ã“ã®Cシンボルを探ã™\n"
" t: ã“ã®ãƒ†ã‚­ã‚¹ãƒˆæ–‡å­—列を探ã™\n"
-#: ../if_cscope.c:1226
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: cscopeデータベース: %s ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: cscopeãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æƒ…報をå–å¾—ã§ãã¾ã›ã‚“"
+
msgid "E568: duplicate cscope database not added"
msgstr "E568: é‡è¤‡ã™ã‚‹cscopeデータベースã¯è¿½åŠ ã•れã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: cscope接続 %s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "cscope接続 %s ãŒé–‰ã˜ã‚‰ã‚Œã¾ã—ãŸ"
-#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: cs_manage_matches ã§è‡´å‘½çš„ãªã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
msgstr "Cscope ã‚¿ã‚°: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3279,87 +2626,314 @@ msgstr ""
"\n"
" # 行番å·"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "ファイルå / 文脈 / 行\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: cscopeエラー: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "å…¨ã¦ã®cscopeデータベースをリセットã—ã¾ã™"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "cscope接続ãŒã‚りã¾ã›ã‚“\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid データベースå prepend パス\n"
-#: ../main.c:144
+msgid "Lua library cannot be loaded."
+msgstr "Luaライブラリをロードã§ãã¾ã›ã‚“."
+
+msgid "cannot save undo information"
+msgstr "アンドゥ情報ãŒä¿å­˜ã§ãã¾ã›ã‚“"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr "E815: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™. MzScheme ライブラリをロードã§ãã¾ã›ã‚“."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„. MzScheme ã® racket/base モジュー"
+"ルãŒãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ."
+
+msgid "invalid expression"
+msgstr "無効ãªå¼ã§ã™"
+
+msgid "expressions disabled at compile time"
+msgstr "å¼ã¯ã‚³ãƒ³ãƒ‘イル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™"
+
+msgid "hidden option"
+msgstr "éš ã—オプション"
+
+msgid "unknown option"
+msgstr "未知ã®ã‚ªãƒ—ションã§ã™"
+
+msgid "window index is out of range"
+msgstr "範囲外ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ç•ªå·ã§ã™"
+
+msgid "couldn't open buffer"
+msgstr "ãƒãƒƒãƒ•ã‚¡ã‚’é–‹ã‘ã¾ã›ã‚“"
+
+msgid "cannot delete line"
+msgstr "行を消ã›ã¾ã›ã‚“"
+
+msgid "cannot replace line"
+msgstr "行を置æ›ã§ãã¾ã›ã‚“"
+
+msgid "cannot insert line"
+msgstr "行を挿入ã§ãã¾ã›ã‚“"
+
+msgid "string cannot contain newlines"
+msgstr "文字列ã«ã¯æ”¹è¡Œæ–‡å­—ã‚’å«ã‚られã¾ã›ã‚“"
+
+msgid "error converting Scheme values to Vim"
+msgstr "Scheme値ã®Vimã¸ã®å¤‰æ›ã‚¨ãƒ©ãƒ¼"
+
+msgid "Vim error: ~a"
+msgstr "Vim エラー: ~a"
+
+msgid "Vim error"
+msgstr "Vim エラー"
+
+msgid "buffer is invalid"
+msgstr "ãƒãƒƒãƒ•ã‚¡ã¯ç„¡åйã§ã™"
+
+msgid "window is invalid"
+msgstr "ウィンドウã¯ç„¡åйã§ã™"
+
+msgid "linenr out of range"
+msgstr "範囲外ã®è¡Œç•ªå·ã§ã™"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: ライブラリ %s をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„: Perlライブラリをロードã§ãã¾ã›ã‚“ã§ã—ãŸ."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr ""
+"E299: サンドボックスã§ã¯ Safe モジュールを使用ã—ãªã„Perlスクリプトã¯ç¦ã˜ã‚‰ã‚Œ"
+"ã¦ã„ã¾ã™"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: ã“ã®Vimã§ã¯ :py3 を使ã£ãŸå¾Œã« :python を使ãˆã¾ã›ã‚“"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„: Pythonライブラリをロードã§ãã¾ã›"
+"ã‚“ã§ã—ãŸ."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„. Python ã® site モジュールをロード"
+"ã§ãã¾ã›ã‚“ã§ã—ãŸ."
+
+# Added at 07-Feb-2004.
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python ã‚’å†å¸°çš„ã«å®Ÿè¡Œã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: ã“ã®Vimã§ã¯ :python を使ã£ãŸå¾Œã« :py3 を使ãˆã¾ã›ã‚“"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ ã¯æ–‡å­—列ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„: Rubyライブラリをロードã§ãã¾ã›ã‚“"
+"ã§ã—ãŸ."
+
+msgid "E267: unexpected return"
+msgstr "E267: 予期ã›ã¬ return ã§ã™"
+
+msgid "E268: unexpected next"
+msgstr "E268: 予期ã›ã¬ next ã§ã™"
+
+msgid "E269: unexpected break"
+msgstr "E269: 予期ã›ã¬ break ã§ã™"
+
+msgid "E270: unexpected redo"
+msgstr "E270: 予期ã›ã¬ redo ã§ã™"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: rescue ã®å¤–ã® retry ã§ã™"
+
+msgid "E272: unhandled exception"
+msgstr "E272: å–り扱ã‚れãªã‹ã£ãŸä¾‹å¤–ãŒã‚りã¾ã™"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: 未知ã®longjmp状態: %d"
+
+msgid "invalid buffer number"
+msgstr "無効ãªãƒãƒƒãƒ•ァ番å·ã§ã™"
+
+msgid "not implemented yet"
+msgstr "ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "cannot set line(s)"
+msgstr "行を設定ã§ãã¾ã›ã‚“"
+
+msgid "invalid mark name"
+msgstr "無効ãªãƒžãƒ¼ã‚¯åã§ã™"
+
+msgid "mark not set"
+msgstr "マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "行 %d 列 %d"
+
+msgid "cannot insert/append line"
+msgstr "è¡Œã®æŒ¿å…¥/追加をã§ãã¾ã›ã‚“"
+
+msgid "line number out of range"
+msgstr "範囲外ã®è¡Œç•ªå·ã§ã™"
+
+msgid "unknown flag: "
+msgstr "未知ã®ãƒ•ラグ: "
+
+msgid "unknown vimOption"
+msgstr "未知㮠vimOption ã§ã™"
+
+msgid "keyboard interrupt"
+msgstr "キーボード割込ã¿"
+
+msgid "vim error"
+msgstr "vim エラー"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr ""
+"ãƒãƒƒãƒ•ã‚¡/ウィンドウ作æˆã‚³ãƒžãƒ³ãƒ‰ã‚’作æˆã§ãã¾ã›ã‚“: ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæ¶ˆåŽ»ã•れã¦ã„ã¾"
+"ã—ãŸ"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«æ¶ˆåŽ»ã•れã¾ã—ãŸ"
+
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL 致命的エラー: reflist 汚染!? vim-dev@vim.org ã«å ±å‘Šã—ã¦ãã ã•ã„"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ウィンドウã®å‚ç…§ãŒè¦‹ã¤ã‹ã‚Šã¾ã›"
+"ã‚“"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™ã€ã”ã‚ã‚“ãªã•ã„: Tclライブラリをロードã§ãã¾ã›ã‚“ã§"
+"ã—ãŸ."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: 終了コード %d"
+
+msgid "cannot get line"
+msgstr "行をå–å¾—ã§ãã¾ã›ã‚“"
+
+msgid "Unable to register a command server name"
+msgstr "命令サーãƒãƒ¼ã®åå‰ã‚’登録ã§ãã¾ã›ã‚“"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: 目的ã®ãƒ—ログラムã¸ã®ã‚³ãƒžãƒ³ãƒ‰é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: 無効ãªã‚µãƒ¼ãƒãƒ¼IDãŒä½¿ã‚れã¾ã—ãŸ: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: VIM 実体ã®ç™»éŒ²ãƒ—ロパティãŒä¸æ­£ã§ã™. 消去ã—ã¾ã—ãŸ!"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: JSONã«é‡è¤‡ã‚­ãƒ¼ãŒã‚りã¾ã™: \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: リスト型ã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ãƒªã‚¹ãƒˆåž‹ã®æœ€å¾Œã« ']' ãŒã‚りã¾ã›ã‚“: %s"
+
msgid "Unknown option argument"
msgstr "未知ã®ã‚ªãƒ—ション引数ã§ã™"
-#: ../main.c:146
msgid "Too many edit arguments"
msgstr "編集引数ãŒå¤šéŽãŽã¾ã™"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "引数ãŒã‚りã¾ã›ã‚“"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "オプション引数ã®å¾Œã«ã‚´ãƒŸãŒã‚りã¾ã™"
-#: ../main.c:152
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
#, c-format
msgid "%d files to edit\n"
msgstr "%d 個ã®ãƒ•ァイルãŒç·¨é›†ã‚’控ãˆã¦ã„ã¾ã™\n"
-#: ../main.c:1342
+msgid "netbeans is not supported with this GUI\n"
+msgstr "netbeans ã¯ã“ã®GUIã§ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' 使用ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "ã“ã®Vimã«ã¯diff機能ãŒã‚りã¾ã›ã‚“(コンパイル時設定)."
+
msgid "Attempt to open script file again: \""
-msgstr "スクリプトファイルをå†ã³é–‹ã„ã¦ã¿ã¾ã™: \""
+msgstr "スクリプトファイルをå†ã³é–‹ã“ã†ã¨ã—ã¾ã—ãŸ: \""
-#: ../main.c:1350
msgid "Cannot open for reading: \""
msgstr "読込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“"
-#: ../main.c:1393
msgid "Cannot open for script output: \""
msgstr "スクリプト出力用を開ã‘ã¾ã›ã‚“"
-#: ../main.c:1622
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: エラー: NetBeansã‹ã‚‰gvimをスタートã§ãã¾ã›ã‚“\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr "Vim: エラー: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®Vimã¯Cygwin端末ã§ã¯å‹•作ã—ã¾ã›ã‚“\n"
+
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"
-#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "vimrcå‰ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: \"%s\"ã‹ã‚‰èª­è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“"
-#: ../main.c:2149
msgid ""
"\n"
"More info with: \"vim -h\"\n"
@@ -3367,37 +2941,30 @@ msgstr ""
"\n"
"ã‚ˆã‚Šè©³ç´°ãªæƒ…å ±ã¯: \"vim -h\"\n"
-#: ../main.c:2178
msgid "[file ..] edit specified file(s)"
msgstr "[ファイル..] ã‚るファイルを編集ã™ã‚‹"
-#: ../main.c:2179
msgid "- read text from stdin"
msgstr "- 標準入力ã‹ã‚‰ãƒ†ã‚­ã‚¹ãƒˆã‚’読込む"
-#: ../main.c:2180
msgid "-t tag edit file where tag is defined"
msgstr "-t ã‚¿ã‚° ã‚¿ã‚°ãŒå®šç¾©ã•れãŸã¨ã“ã‚ã‹ã‚‰ç·¨é›†ã™ã‚‹"
-#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr "-q [errorfile] 最åˆã®ã‚¨ãƒ©ãƒ¼ã§ç·¨é›†ã™ã‚‹"
-#: ../main.c:2187
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
"使用法:"
-#: ../main.c:2189
msgid " vim [arguments] "
msgstr " vim [引数] "
-#: ../main.c:2193
msgid ""
"\n"
" or:"
@@ -3405,7 +2972,13 @@ msgstr ""
"\n"
" ã‚‚ã—ãã¯:"
-#: ../main.c:2196
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"大尿–‡å­—ãŒç„¡è¦–ã•れる場åˆã¯å¤§æ–‡å­—ã«ã™ã‚‹ãŸã‚ã« / ã‚’å‰ç½®ã—ã¦ãã ã•ã„"
+
msgid ""
"\n"
"\n"
@@ -3415,189 +2988,322 @@ msgstr ""
"\n"
"引数:\n"
-#: ../main.c:2197
msgid "--\t\t\tOnly file names after this"
msgstr "--\t\t\tã“ã®ã‚ã¨ã«ã¯ãƒ•ァイルåã ã‘"
-#: ../main.c:2199
msgid "--literal\t\tDon't expand wildcards"
msgstr "--literal\t\tワイルドカードを展開ã—ãªã„"
-#: ../main.c:2201
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tã“ã®gvimã‚’OLEã¨ã—ã¦ç™»éŒ²ã™ã‚‹"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tgvimã®OLE登録を解除ã™ã‚‹"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tGUIã§èµ·å‹•ã™ã‚‹ (\"gvim\" ã¨åŒã˜)"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f or --nofork\tフォアグラウンド: GUIã‚’å§‹ã‚ã‚‹ã¨ãã«forkã—ãªã„"
+
msgid "-v\t\t\tVi mode (like \"vi\")"
msgstr "-v\t\t\tViモード (\"vi\" ã¨åŒã˜)"
-#: ../main.c:2202
msgid "-e\t\t\tEx mode (like \"ex\")"
msgstr "-e\t\t\tExモード (\"ex\" ã¨åŒã˜)"
-#: ../main.c:2203
msgid "-E\t\t\tImproved Ex mode"
msgstr "-E\t\t\t改良Exモード"
-#: ../main.c:2204
msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
msgstr "-s\t\t\tサイレント(ãƒãƒƒãƒ)モード (\"ex\" 専用)"
-#: ../main.c:2205
msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
msgstr "-d\t\t\t差分モード (\"vidiff\" ã¨åŒã˜)"
-#: ../main.c:2206
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tイージーモード (\"evim\" ã¨åŒã˜, モード無)"
+msgstr "-y\t\t\tイージーモード (\"evim\" ã¨åŒã˜ã€ãƒ¢ãƒ¼ãƒ‰ç„¡)"
-#: ../main.c:2207
msgid "-R\t\t\tReadonly mode (like \"view\")"
msgstr "-R\t\t\t読込専用モード (\"view\" ã¨åŒã˜)"
-#: ../main.c:2208
msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
msgstr "-Z\t\t\t制é™ãƒ¢ãƒ¼ãƒ‰ (\"rvim\" ã¨åŒã˜)"
-#: ../main.c:2209
msgid "-m\t\t\tModifications (writing files) not allowed"
msgstr "-m\t\t\t変更 (ファイルä¿å­˜æ™‚) ã‚’ã§ããªã„よã†ã«ã™ã‚‹"
-#: ../main.c:2210
msgid "-M\t\t\tModifications in text not allowed"
msgstr "-M\t\t\tテキストã®ç·¨é›†ã‚’行ãªãˆãªã„よã†ã«ã™ã‚‹"
-#: ../main.c:2211
msgid "-b\t\t\tBinary mode"
msgstr "-b\t\t\tãƒã‚¤ãƒŠãƒªãƒ¢ãƒ¼ãƒ‰"
-#: ../main.c:2212
msgid "-l\t\t\tLisp mode"
msgstr "-l\t\t\tLispモード"
-#: ../main.c:2213
msgid "-C\t\t\tCompatible with Vi: 'compatible'"
msgstr "-C\t\t\tVi互æ›ãƒ¢ãƒ¼ãƒ‰: 'compatible'"
-#: ../main.c:2214
msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
msgstr "-N\t\t\tViéžäº’æ›ãƒ¢ãƒ¼ãƒ‰: 'nocompatible"
-#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr "-V[N][fname]\t\tログ出力設定 [レベル N] [ログファイルå fname]"
-#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
msgstr "-D\t\t\tデãƒãƒƒã‚°ãƒ¢ãƒ¼ãƒ‰"
-#: ../main.c:2217
msgid "-n\t\t\tNo swap file, use memory only"
msgstr "-n\t\t\tスワップファイルを使用ã›ãšãƒ¡ãƒ¢ãƒªã ã‘"
-#: ../main.c:2218
msgid "-r\t\t\tList swap files and exit"
msgstr "-r\t\t\tスワップファイルを列挙ã—終了"
-#: ../main.c:2219
msgid "-r (with file name)\tRecover crashed session"
msgstr "-r (ファイルå)\tクラッシュã—ãŸã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚’復帰"
-#: ../main.c:2220
msgid "-L\t\t\tSame as -r"
msgstr "-L\t\t\t-rã¨åŒã˜"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tウィンドウを開ãã®ã« newcli を使用ã—ãªã„"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <device>\t\tI/Oã« <device> を使用ã™ã‚‹"
+
+msgid "-A\t\t\tStart in Arabic mode"
msgstr "-A\t\t\tアラビア語モードã§èµ·å‹•ã™ã‚‹"
-#: ../main.c:2222
msgid "-H\t\t\tStart in Hebrew mode"
msgstr "-H\t\t\tヘブライ語モードã§èµ·å‹•ã™ã‚‹"
-#: ../main.c:2223
msgid "-F\t\t\tStart in Farsi mode"
msgstr "-F\t\t\tペルシア語モードã§èµ·å‹•ã™ã‚‹"
-#: ../main.c:2224
msgid "-T <terminal>\tSet terminal type to <terminal>"
msgstr "-T <terminal>\t端末を <terminal> ã«è¨­å®šã™ã‚‹"
-#: ../main.c:2225
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr "--not-a-term\t\t入出力ãŒç«¯æœ«ã§ãªã„ã¨ã®è­¦å‘Šã‚’スキップã™ã‚‹"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr "--ttyfail\t\t入出力ãŒç«¯æœ«ã§ãªã‘れã°çµ‚了ã™ã‚‹"
+
msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
msgstr "-u <vimrc>\t\t.vimrcã®ä»£ã‚り㫠<vimrc> を使ã†"
-#: ../main.c:2226
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\t.gvimrcã®ä»£ã‚り㫠<gvimrc> を使ã†"
+
msgid "--noplugin\t\tDon't load plugin scripts"
msgstr "--noplugin\t\tプラグインスクリプトをロードã—ãªã„"
-#: ../main.c:2227
msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
msgstr "-p[N]\t\tN 個タブページを開ã(çœç•¥å€¤: ファイルã«ã¤ã1個)"
-#: ../main.c:2228
msgid "-o[N]\t\tOpen N windows (default: one for each file)"
msgstr "-o[N]\t\tN 個ウィンドウを開ã(çœç•¥å€¤: ファイルã«ã¤ã1個)"
-#: ../main.c:2229
msgid "-O[N]\t\tLike -o but split vertically"
msgstr "-O[N]\t\t-oã¨åŒã˜ã ãŒåž‚直分割"
-#: ../main.c:2230
msgid "+\t\t\tStart at end of file"
msgstr "+\t\t\tãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¾Œã‹ã‚‰ã¯ã˜ã‚ã‚‹"
-#: ../main.c:2231
msgid "+<lnum>\t\tStart at line <lnum>"
msgstr "+<lnum>\t\t<lnum> 行ã‹ã‚‰ã¯ã˜ã‚ã‚‹"
-#: ../main.c:2232
msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
msgstr "--cmd <command>\tvimrcをロードã™ã‚‹å‰ã« <command> を実行ã™ã‚‹"
-#: ../main.c:2233
msgid "-c <command>\t\tExecute <command> after loading the first file"
msgstr "-c <command>\t\t最åˆã®ãƒ•ァイルをロード後 <command> を実行ã™ã‚‹"
-#: ../main.c:2235
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr "-S <session>\t\t最åˆã®ãƒ•ァイルをロード後ファイル <session> ã‚’å–込む"
-#: ../main.c:2236
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
msgstr "-s <scriptin>\tファイル <scriptin> ã‹ã‚‰ãƒŽãƒ¼ãƒžãƒ«ã‚³ãƒžãƒ³ãƒ‰ã‚’読込む"
-#: ../main.c:2237
msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
msgstr "-w <scriptout>\t入力ã—ãŸå…¨ã‚³ãƒžãƒ³ãƒ‰ã‚’ファイル <scriptout> ã«è¿½åŠ ã™ã‚‹"
-#: ../main.c:2238
msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
msgstr "-W <scriptout>\t入力ã—ãŸå…¨ã‚³ãƒžãƒ³ãƒ‰ã‚’ファイル <scriptout> ã«ä¿å­˜ã™ã‚‹"
-#: ../main.c:2240
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tæš—å·åŒ–ã•れãŸãƒ•ァイルを編集ã™ã‚‹"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <display>\tvimを指定ã—㟠X サーãƒãƒ¼ã«æŽ¥ç¶šã™ã‚‹"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tXサーãƒãƒ¼ã«æŽ¥ç¶šã—ãªã„"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <files>\tå¯èƒ½ãªã‚‰ã°Vimサーãƒãƒ¼ã§ <files> を編集ã™ã‚‹"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <files> åŒä¸Šã€ã‚µãƒ¼ãƒãƒ¼ãŒç„¡ãã¦ã‚‚警告文を出力ã—ãªã„"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr "--remote-wait <files>\t--remote後 ファイルã®ç·¨é›†ãŒçµ‚ã‚ã‚‹ã®ã‚’å¾…ã¤"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr ""
+"--remote-wait-silent <files> åŒä¸Šã€ã‚µãƒ¼ãƒãƒ¼ãŒç„¡ãã¦ã‚‚警告文を出力ã—ãªã„"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <files> --remoteã§ãƒ•ァイル1ã¤ã«ã¤ã1ã¤ã®ã‚¿ãƒ–"
+"ページを開ã"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <keys>\tVimサーãƒãƒ¼ã« <keys> ã‚’é€ä¿¡ã—ã¦çµ‚了ã™ã‚‹"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr "--remote-expr <expr>\tサーãƒãƒ¼ã§ <expr> を実行ã—ã¦çµæžœã‚’表示ã™ã‚‹"
+
+msgid "--serverlist\t\tList available Vim server names and exit"
+msgstr "--serverlist\t\tVimサーãƒãƒ¼åã®ä¸€è¦§ã‚’表示ã—ã¦çµ‚了ã™ã‚‹"
+
+msgid "--servername <name>\tSend to/become the Vim server <name>"
+msgstr "--servername <name>\tVimサーãƒãƒ¼ <name> ã«é€ä¿¡/åå‰è¨­å®šã™ã‚‹"
+
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr "--startuptime <file>\tèµ·å‹•ã«ã‹ã‹ã£ãŸæ™‚é–“ã®è©³ç´°ã‚’ <file> ã¸å‡ºåŠ›ã™ã‚‹"
-#: ../main.c:2242
msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
msgstr "-i <viminfo>\t\t.viminfoã®ä»£ã‚り㫠<viminfo> を使ã†"
-#: ../main.c:2243
+msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo"
+msgstr "--clean\t\t'nocompatible'ã€Vimã®æ—¢å®šã€ãƒ—ラグインãªã—ã€viminfoãªã—"
+
msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h or --help\tヘルプ(ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸)を表示ã—終了ã™ã‚‹"
+msgstr "-h or --help\tヘルプ(ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸)を表示ã—終了ã™ã‚‹"
-#: ../main.c:2244
msgid "--version\t\tPrint version information and exit"
msgstr "--version\t\tãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—終了ã™ã‚‹"
-#: ../mark.c:676
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(Motifãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(neXtawãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(Athenaãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <display>\t<display> ã§vimを実行ã™ã‚‹"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\t最å°åŒ–ã—ãŸçŠ¶æ…‹ã§vimã‚’èµ·å‹•ã™ã‚‹"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <color>\t背景色㫠<color> を使ã†(åŒç¾©: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <color>\t剿™¯è‰²ã« <color> を使ã†(åŒç¾©: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <font>\t\tテキスト表示㫠<font> を使ã†(åŒç¾©: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <font>\t太字㫠<font> を使ã†"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <for>\t斜体字㫠<font> を使ã†"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <geom>\tåˆæœŸé…置㫠<geom> を使ã†(åŒç¾©: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <width>\t境界ã®å¹…ã‚’ <width> ã«ã™ã‚‹(åŒç¾©: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <width> スクロールãƒãƒ¼ã®å¹…ã‚’ <width> ã«ã™ã‚‹(åŒç¾©: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr "-menuheight <height>\tメニューãƒãƒ¼ã®é«˜ã•ã‚’ <height> ã«ã™ã‚‹(åŒç¾©: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tå転映åƒã‚’使用ã™ã‚‹(åŒç¾©: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tå転映åƒã‚’使用ã—ãªã„(åŒç¾©: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <resource>\t特定ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’使用ã™ã‚‹"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(GTK+ãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <display>\t<display> ã§vimを実行ã™ã‚‹(åŒç¾©: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr "--role <role>\tメインウィンドウを識別ã™ã‚‹ä¸€æ„ãªå½¹å‰²(role)を設定ã™ã‚‹"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tç•°ãªã‚‹GTK widgetã§Vimã‚’é–‹ã"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tウィンドウIDを標準出力ã«å‡ºåŠ›ã™ã‚‹"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <親ã®ã‚¿ã‚¤ãƒˆãƒ«>\tVimを親アプリケーションã®ä¸­ã§èµ·å‹•ã™ã‚‹"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tç•°ãªã‚‹Win32 widgetã®å†…部ã«Vimã‚’é–‹ã"
+
+msgid "No display"
+msgstr "ディスプレイãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid ": Send failed.\n"
+msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
+
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ. ローカルã§ã®å®Ÿè¡Œã‚’試ã¿ã¦ã„ã¾ã™\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d 個 (%d 個中) ã®ãƒ•ァイルを編集ã—ã¾ã—ãŸ"
+
+msgid "No display: Send expression failed.\n"
+msgstr "ディスプレイãŒã‚りã¾ã›ã‚“: å¼ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": å¼ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
+
msgid "No marks set"
msgstr "マークãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: \"%s\" ã«è©²å½“ã™ã‚‹ãƒžãƒ¼ã‚¯ãŒã‚りã¾ã›ã‚“"
-#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3605,8 +3311,6 @@ msgstr ""
"\n"
"mark 行 列 ファイル/テキスト"
-#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3614,8 +3318,6 @@ msgstr ""
"\n"
" jump 行 列 ファイル/テキスト"
-#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3623,7 +3325,6 @@ msgstr ""
"\n"
"変更 行 列 テキスト"
-#: ../mark.c:1238
msgid ""
"\n"
"# File marks:\n"
@@ -3631,8 +3332,6 @@ msgstr ""
"\n"
"# ファイルマーク:\n"
-#. Write the jumplist with -'
-#: ../mark.c:1271
msgid ""
"\n"
"# Jumplist (newest first):\n"
@@ -3640,7 +3339,6 @@ msgstr ""
"\n"
"# ジャンプリスト (æ–°ã—ã„ã‚‚ã®ãŒå…ˆ):\n"
-#: ../mark.c:1352
msgid ""
"\n"
"# History of marks within files (newest to oldest):\n"
@@ -3648,84 +3346,87 @@ msgstr ""
"\n"
"# ファイル内マークã®å±¥æ­´ (æ–°ã—ã„ã‚‚ã®ã‹ã‚‰å¤ã„ã‚‚ã®):\n"
-#: ../mark.c:1431
msgid "Missing '>'"
msgstr "'>' ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../memfile.c:426
+msgid "E543: Not a valid codepage"
+msgstr "E543: 無効ãªã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¸ã§ã™"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: ICã®å€¤ã‚’設定ã§ãã¾ã›ã‚“"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: インプットコンテキストã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: インプットメソッドã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr "E287: 警告: IMã®ç ´å£Šã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: インプットメソッドã¯ã©ã‚“ãªã‚¹ã‚¿ã‚¤ãƒ«ã‚‚サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: インプットメソッド㯠my preedit type をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+
msgid "E293: block was not locked"
msgstr "E293: ブロックãŒãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã›ã‚“"
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: スワップファイル読込時ã«ã‚·ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: スワップファイルã®èª­è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«æ›¸è¾¼ã¿æ™‚ã«ã‚·ãƒ¼ã‚¯ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸è¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™ (symlinkã«ã‚ˆã‚‹æ”»æ’ƒ?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: ブロック 0 ã‚’å–å¾—ã§ãã¾ã›ã‚“?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: ブロック 1 ã‚’å–å¾—ã§ãã¾ã›ã‚“?"
-#: ../memline.c:377
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
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æš—å·ã‚’更新中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+
msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: ãŠã£ã¨, スワップファイルãŒå¤±ã‚れã¾ã—ãŸ!!!"
+msgstr "E301: ãŠã£ã¨ã€ã‚¹ãƒ¯ãƒƒãƒ—ファイルãŒå¤±ã‚れã¾ã—ãŸ!!!"
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: スワップファイルã®åå‰ã‚’変ãˆã‚‰ã‚Œã¾ã›ã‚“"
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: \"%s\" ã®ã‚¹ãƒ¯ãƒƒãƒ—ファイルを開ã‘ãªã„ã®ã§ãƒªã‚«ãƒãƒªã¯ä¸å¯èƒ½ã§ã™"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): ブロック 0 ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: %s ã«ã¯ã‚¹ãƒ¯ãƒƒãƒ—ファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "使用ã™ã‚‹ã‚¹ãƒ¯ãƒƒãƒ—ファイルã®ç•ªå·ã‚’入力ã—ã¦ãã ã•ã„(0 ã§çµ‚了): "
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: %s ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "ブロック 0 を読込ã‚ã¾ã›ã‚“ "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3733,28 +3434,22 @@ msgstr ""
"\n"
"æã‚‰ã変更ãŒã•れã¦ã„ãªã„ã‹VimãŒã‚¹ãƒ¯ãƒƒãƒ—ファイルを更新ã—ã¦ã„ã¾ã›ã‚“."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " Vimã®ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Vimã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³3.0を使用ã—ã¦ãã ã•ã„.\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s ã¯Vimã®ã‚¹ãƒ¯ãƒƒãƒ—ファイルã§ã¯ãªã„よã†ã§ã™"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " ã“ã®ã‚³ãƒ³ãƒ”ュータã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã¯æ¬¡ã®å ´æ‰€ã§ä½œã‚‰ã‚Œã¾ã—㟠"
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3762,101 +3457,117 @@ msgstr ""
",\n"
"ã‚‚ã—ãã¯ãƒ•ã‚¡ã‚¤ãƒ«ãŒæå‚·ã—ã¦ã„ã¾ã™."
-#: ../memline.c:945
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr ""
+"E833: %s ã¯ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®Vimã§ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„å½¢å¼ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
+
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " ã¯æå‚·ã—ã¦ã„ã¾ã™ (ãƒšãƒ¼ã‚¸ã‚µã‚¤ã‚ºãŒæœ€å°å€¤ã‚’下回ã£ã¦ã„ã¾ã™).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "スワップファイル \"%s\" を使用中"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "原本ファイル \"%s\""
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: 警告: 原本ファイルãŒå¤‰æ›´ã•れã¦ã„ã¾ã™"
-#: ../memline.c:1061
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã¯æš—å·åŒ–ã•れã¦ã„ã¾ã™: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"æ–°ã—ã„æš—å·ã‚­ãƒ¼ã‚’入力ã—ãŸã‚ã¨ã«ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルをä¿å­˜ã—ã¦ã„ãªã„å ´åˆã¯ã€"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"æ–°ã—ã„æš—å·ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"æš—å·ã‚­ãƒ¼ã‚’変ãˆãŸã‚ã¨ã«ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルをä¿å­˜ã—ãŸå ´åˆã¯ã€ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルã¨"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"スワップファイルã«åŒã˜æš—å·ã‚­ãƒ¼ã‚’使ã†ãŸã‚ã«enterã ã‘を押ã—ã¦ãã ã•ã„."
+
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: %s ã‹ã‚‰ãƒ–ロック 1 を読込ã‚ã¾ã›ã‚“"
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "???多ãã®è¡ŒãŒå¤±ã‚れã¦ã„ã¾ã™"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "???行数ãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "???ブロックãŒç©ºã§ã™"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "???行ãŒå¤±ã‚れã¦ã„ã¾ã™"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: ブロック 1 ã®IDãŒé–“é•ã£ã¦ã„ã¾ã™(%s ãŒ.swpファイルã§ãªã„?)"
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "???ブロックãŒã‚りã¾ã›ã‚“"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? ã“ã“ã‹ã‚‰ ???END ã¾ã§ã®è¡ŒãŒç ´å£Šã•れã¦ã„るよã†ã§ã™"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? ã“ã“ã‹ã‚‰ ???END ã¾ã§ã®è¡ŒãŒæŒ¿å…¥ã‹å‰Šé™¤ã•れãŸã‚ˆã†ã§ã™"
-#: ../memline.c:1181
msgid "???END"
msgstr "???END"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: リカãƒãƒªãŒå‰²è¾¼ã¾ã‚Œã¾ã—ãŸ"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: リカãƒãƒªã®æœ€ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒæ¤œå‡ºã•れã¾ã—ãŸ; ???ã§å§‹ã¾ã‚‹è¡Œã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "詳細㯠\":help E312\" ã‚’å‚ç…§ã—ã¦ãã ã•ã„"
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "リカãƒãƒªãŒçµ‚了ã—ã¾ã—ãŸ. å…¨ã¦ãŒæ­£ã—ã„ã‹ãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
msgstr ""
"\n"
-"(変更をãƒã‚§ãƒƒã‚¯ã™ã‚‹ãŸã‚ã«, ã“ã®ãƒ•ァイルを別ã®åå‰ã§ä¿å­˜ã—ãŸä¸Šã§\n"
+"(変更をãƒã‚§ãƒƒã‚¯ã™ã‚‹ãŸã‚ã«ã€ã“ã®ãƒ•ァイルを別ã®åå‰ã§ä¿å­˜ã—ãŸä¸Šã§\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "原本ファイルã¨ã® diff を実行ã™ã‚‹ã¨è‰¯ã„ã§ã—ょã†)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr "復元完了. ãƒãƒƒãƒ•ã‚¡ã®å†…容ã¯ãƒ•ァイルã¨åŒã˜ã«ãªã‚Šã¾ã—ãŸ."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3866,52 +3577,42 @@ msgstr ""
"å…ƒã®.swpファイルã¯å‰Šé™¤ã—ã¦ã‚‚æ§‹ã„ã¾ã›ã‚“\n"
"\n"
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr "スワップファイルã‹ã‚‰å–å¾—ã—ãŸæš—å·ã‚­ãƒ¼ã‚’テキストファイルã«ä½¿ã„ã¾ã™.\n"
+
msgid "Swap files found:"
msgstr "スワップファイルãŒè¤‡æ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " 以下ã®åå‰ã‚’使用中:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " ディレクトリ "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- ãªã— --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " 所有者: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " 日付: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " 日付: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [from Vim version 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [Vimã®ã‚¹ãƒ¯ãƒƒãƒ—ファイルã§ã¯ãªã„よã†ã§ã™]"
-#: ../memline.c:1552
msgid " file name: "
msgstr " ファイルå: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -3919,15 +3620,12 @@ msgstr ""
"\n"
" 変更状態: "
-#: ../memline.c:1559
msgid "YES"
msgstr "ã‚り"
-#: ../memline.c:1559
msgid "no"
msgstr "ãªã—"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -3935,11 +3633,9 @@ msgstr ""
"\n"
" ユーザーå: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " ホストå: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -3947,7 +3643,6 @@ msgstr ""
"\n"
" ホストå: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -3955,11 +3650,16 @@ msgstr ""
"\n"
" プロセスID: "
-#: ../memline.c:1579
msgid " (still running)"
msgstr " (ã¾ã å®Ÿè¡Œä¸­)"
-#: ../memline.c:1586
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [ã“ã®Vimãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“]"
+
msgid ""
"\n"
" [not usable on this computer]"
@@ -3967,97 +3667,75 @@ msgstr ""
"\n"
" [ã“ã®ã‚³ãƒ³ãƒ”ュータã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [読込ã‚ã¾ã›ã‚“]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [é–‹ã‘ã¾ã›ã‚“]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: スワップファイルãŒç„¡ã„ã®ã§ç¶­æŒã§ãã¾ã›ã‚“"
-#: ../memline.c:1747
msgid "File preserved"
msgstr "ファイルãŒç¶­æŒã•れã¾ã™"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: ç¶­æŒã«å¤±æ•—ã—ã¾ã—ãŸ"
-#: ../memline.c:1819
#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: 無効ãªlnumã§ã™: %<PRId64>"
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: 無効ãªlnumã§ã™: %ld"
-#: ../memline.c:1851
#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: 行 %<PRId64> を見ã¤ã‘られã¾ã›ã‚“"
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: 行 %ld を見ã¤ã‘られã¾ã›ã‚“"
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 3"
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx 㯠0 ã§ã‚ã‚‹ã¹ãã§ã™"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: æ›´æ–°ã•れãŸãƒ–ロックãŒå¤šéŽãŽã‚‹ã‹ã‚‚?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "ブロック 1 ã¯æ¶ˆã•れãŸ?"
-#: ../memline.c:2707
#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: 行 %<PRId64> ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+msgid "E320: Cannot find line %ld"
+msgstr "E320: 行 %ld ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count ãŒã‚¼ãƒ­ã§ã™"
-#: ../memline.c:2955
#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: 行番å·ãŒç¯„囲外ã§ã™: %<PRId64> è¶…ãˆã¦ã„ã¾ã™"
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: 行番å·ãŒç¯„囲外ã§ã™: %ld è¶…ãˆã¦ã„ã¾ã™"
-#: ../memline.c:2959
#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ブロック %<PRId64> ã®è¡Œã‚«ã‚¦ãƒ³ãƒˆãŒé–“é•ã£ã¦ã„ã¾ã™"
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: ブロック %ld ã®è¡Œã‚«ã‚¦ãƒ³ãƒˆãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "スタックサイズãŒå¢—ãˆã¾ã™"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: ãƒã‚¤ãƒ³ã‚¿ãƒ–ロックã®IDãŒé–“é•ã£ã¦ã„ã¾ã™ 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: \"%s\" ã®ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ãŒãƒ«ãƒ¼ãƒ—ã«ãªã£ã¦ã„ã¾ã™"
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: 注æ„"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4065,39 +3743,30 @@ msgstr ""
"\n"
"次ã®åå‰ã§ã‚¹ãƒ¯ãƒƒãƒ—ファイルを見ã¤ã‘ã¾ã—㟠\""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "次ã®ãƒ•ァイルを開ã„ã¦ã„る最中 \""
-#: ../memline.c:3239
msgid " NEWER than swap file!\n"
msgstr " スワップファイルよりも新ã—ã„ã§ã™!\n"
-#: ../memline.c:3244
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"
-" ã“ã®å ´åˆã«ã¯, 変更をã—ã¦ã—ã¾ã†ã¨1ã¤ã®ãƒ•ァイルã«å¯¾ã—ã¦ç•°ãªã‚‹2ã¤ã®\n"
-" インスタンスãŒã§ãã¦ã—ã¾ã†ã®ã§, ãã†ã—ãªã„よã†ã«æ°—ã‚’ã¤ã‘ã¦ãã ã•ã„."
+" ã“ã®å ´åˆã«ã¯ã€å¤‰æ›´ã‚’ã—ã¦ã—ã¾ã†ã¨1ã¤ã®ãƒ•ァイルã«å¯¾ã—ã¦ç•°ãªã‚‹2ã¤ã®\n"
+" インスタンスãŒã§ãã¦ã—ã¾ã†ã®ã§ã€ãã†ã—ãªã„よã†ã«æ°—ã‚’ã¤ã‘ã¦ãã ã•ã„.\n"
+" 終了ã™ã‚‹ã‹ã€æ³¨æ„ã—ãªãŒã‚‰ç¶šã‘ã¦ãã ã•ã„.\n"
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " 終了ã™ã‚‹ã‹, 注æ„ã—ãªãŒã‚‰ç¶šã‘ã¦ãã ã•ã„.\n"
-
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) ã“ã®ãƒ•ァイルã®ç·¨é›†ã‚»ãƒƒã‚·ãƒ§ãƒ³ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸ.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " ã“ã®å ´åˆã«ã¯ \":recover\" ã‹ \"vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4105,11 +3774,9 @@ msgstr ""
"\"\n"
" を使用ã—ã¦å¤‰æ›´ã‚’リカãƒãƒ¼ã—ã¾ã™(\":help recovery\" ã‚’å‚ç…§).\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
-msgstr " æ—¢ã«ã“れを行ãªã£ãŸã®ãªã‚‰ã°, スワップファイル \""
+msgstr " æ—¢ã«ã“れを行ãªã£ãŸã®ãªã‚‰ã°ã€ã‚¹ãƒ¯ãƒƒãƒ—ファイル \""
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
@@ -4117,23 +3784,18 @@ msgstr ""
"\"\n"
" を消ã›ã°ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’回é¿ã§ãã¾ã™.\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "スワップファイル \""
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "\" ãŒæ—¢ã«ã‚りã¾ã™!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM - 注æ„"
-#: ../memline.c:3459
msgid "Swap file already exists!"
msgstr "ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™!"
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4147,7 +3809,6 @@ msgstr ""
"終了ã™ã‚‹(&Q)\n"
"中止ã™ã‚‹(&A)"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4163,56 +3824,31 @@ 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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: スワップファイルãŒå¤šæ•°è¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: メモリãŒè¶³ã‚Šã¾ã›ã‚“! (%<PRIu64> ãƒã‚¤ãƒˆã‚’å‰²å½“è¦æ±‚)"
-
-#: ../menu.c:62
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
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: \"%s\" ã¨ã„ã†ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã¯ã‚りã¾ã›ã‚“"
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: メニューåãŒç©ºã§ã™"
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: メニューパスã¯ã‚µãƒ–メニューを生ã˜ã‚‹ã¹ãã§ã¯ã‚りã¾ã›ã‚“"
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: メニューãƒãƒ¼ã«ã¯ç›´æŽ¥ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚¢ã‚¤ãƒ†ãƒ ã‚’追加ã§ãã¾ã›ã‚“"
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: 区切りã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãƒ‘スã®ä¸€éƒ¨ã§ã¯ã‚りã¾ã›ã‚“"
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4220,73 +3856,60 @@ msgstr ""
"\n"
"--- メニュー ---"
-#: ../menu.c:1313
+msgid "Tear off this menu"
+msgstr "ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’切りå–ã‚‹"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: %s ã«ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“"
+
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: メニューパスã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚¢ã‚¤ãƒ†ãƒ ã‚’生ã˜ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
-#: ../menu.c:1330
#, 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
msgid "E336: Menu path must lead to a sub-menu"
msgstr "E336: メニューパスã¯ã‚µãƒ–メニューを生ã˜ãªã‘れã°ã„ã‘ã¾ã›ã‚“"
-#: ../menu.c:1447
msgid "E337: Menu not found - check menu names"
msgstr "E337: メニューãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ - メニューåを確èªã—ã¦ãã ã•ã„"
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "%s ã®å‡¦ç†ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒæ¤œå‡ºã•れã¾ã—ãŸ:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "行 %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: 無効ãªãƒ¬ã‚¸ã‚¹ã‚¿å: '%s'"
-#: ../message.c:745
msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
msgstr "日本語メッセージ翻訳/監修: æ‘岡 太郎 <koron.kaoriya@gmail.com>"
-#: ../message.c:986
msgid "Interrupt: "
msgstr "割込ã¿: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "ç¶šã‘ã‚‹ã«ã¯ENTERを押ã™ã‹ã‚³ãƒžãƒ³ãƒ‰ã‚’入力ã—ã¦ãã ã•ã„"
-#: ../message.c:1843
#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s 行 %<PRId64>"
+msgid "%s line %ld"
+msgstr "%s 行 %ld"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- 継続 --"
-#: ../message.c:2398
msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
msgstr " SPACE/d/j: ç”»é¢/ページ/行 下, b/u/k: 上, q: 終了 "
-#: ../message.c:3021 ../message.c:3031
msgid "Question"
msgstr "質å•"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4294,17 +3917,6 @@ msgstr ""
"ã¯ã„(&Y)\n"
"ã„ã„ãˆ(&N)"
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"ã¯ã„(&Y)\n"
-"ã„ã„ãˆ(&N)\n"
-"キャンセル(&C)"
-
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4318,175 +3930,252 @@ msgstr ""
"å…¨ã¦æ”¾æ£„(&D)\n"
"キャンセル(&C)"
-#: ../message.c:3058
+msgid "Select Directory dialog"
+msgstr "ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªé¸æŠžãƒ€ã‚¤ã‚¢ãƒ­ã‚°"
+
+msgid "Save File dialog"
+msgstr "ファイルä¿å­˜ãƒ€ã‚¤ã‚¢ãƒ­ã‚°"
+
+msgid "Open File dialog"
+msgstr "ファイル読込ダイアログ"
+
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: コンソールモードã§ã¯ãƒ•ァイルブラウザを使ãˆã¾ã›ã‚“ã€ã”ã‚ã‚“ãªã•ã„"
+
msgid "E766: Insufficient arguments for printf()"
msgstr "E766: printf() ã®å¼•æ•°ãŒä¸å分ã§ã™"
-#: ../message.c:3119
msgid "E807: Expected Float argument for printf()"
-msgstr "E807: 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
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr ""
"番å·ã¨<Enter>を入力ã™ã‚‹ã‹ãƒžã‚¦ã‚¹ã§ã‚¯ãƒªãƒƒã‚¯ã—ã¦ãã ã•ã„ (空ã§ã‚­ãƒ£ãƒ³ã‚»ãƒ«): "
-#: ../misc1.c:2539
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> 行 追加ã—ã¾ã—ãŸ"
+msgid "%ld more lines"
+msgstr "%ld 行 追加ã—ã¾ã—ãŸ"
-#: ../misc1.c:2596
#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> 行 削除ã—ã¾ã—ãŸ"
+msgid "%ld fewer lines"
+msgstr "%ld 行 削除ã—ã¾ã—ãŸ"
-#: ../misc1.c:2599
msgid " (Interrupted)"
msgstr " (割込ã¾ã‚Œã¾ã—ãŸ)"
-#: ../misc1.c:2635
msgid "Beep!"
msgstr "ビーッ!"
-#: ../misc2.c:738
+msgid "ERROR: "
+msgstr "エラー: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[メモリ(ãƒã‚¤ãƒˆ)] ç·å‰²å½“-è§£æ”¾é‡ %lu-%lu, ä½¿ç”¨é‡ %lu, ピーク時 %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[呼出] ç· re/malloc() 回数 %lu, ç· free() 回数 %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: 行ãŒé•·ããªã‚ŠéŽãŽã¾ã—ãŸ"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: 内部エラー: lalloc(%ld,)"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: メモリãŒè¶³ã‚Šã¾ã›ã‚“! (%lu ãƒã‚¤ãƒˆã‚’å‰²å½“è¦æ±‚)"
+
#, c-format
msgid "Calling shell to execute: \"%s\""
msgstr "実行ã®ãŸã‚ã«ã‚·ã‚§ãƒ«ã‚’呼出ã—中: \"%s\""
-#: ../normal.c:183
+msgid "E545: Missing colon"
+msgstr "E545: コロンãŒã‚りã¾ã›ã‚“"
+
+msgid "E546: Illegal mode"
+msgstr "E546: 䏿­£ãªãƒ¢ãƒ¼ãƒ‰ã§ã™"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: 䏿­£ãª 'mouseshape' ã§ã™"
+
+msgid "E548: digit expected"
+msgstr "E548: 数値ãŒå¿…è¦ã§ã™"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: 䏿­£ãªãƒ‘ーセンテージã§ã™"
+
+msgid "E854: path too long for completion"
+msgstr "E854: パスãŒé•·éŽãŽã¦è£œå®Œã§ãã¾ã›ã‚“"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: 無効ãªãƒ‘スã§ã™: '**[数値]' ã¯pathã®æœ€å¾Œã‹ '%s' ãŒç¶šã„ã¦ãªã„ã¨ã„ã‘ã¾ã›"
+"ã‚“."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: cdpathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: cdpathã«ã¯ã“れ以上 \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: パスã«ã¯ã“れ以上 \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr ""
+"E668: NetBeansã®æŽ¥ç¶šæƒ…å ±ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«å•題ãŒã‚りã¾ã™: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: ãƒãƒƒãƒ•ã‚¡ %ld ã® NetBeans 接続ãŒå¤±ã‚れã¾ã—ãŸ"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: NetBeansã¯ã“ã®GUIã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: NetBeansã¯æ—¢ã«æŽ¥ç¶šã—ã¦ã„ã¾ã™"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s ã¯èª­è¾¼å°‚用ã§ã™ (強制書込ã«ã¯ ! を追加)"
+
msgid "E349: No identifier under cursor"
msgstr "E349: カーソルã®ä½ç½®ã«ã¯è­˜åˆ¥å­ãŒã‚りã¾ã›ã‚“"
-#: ../normal.c:1866
msgid "E774: 'operatorfunc' is empty"
msgstr "E774: 'operatorfunc' オプションãŒç©ºã§ã™"
-#: ../normal.c:2637
+msgid "E775: Eval feature not available"
+msgstr "E775: å¼è©•価機能ãŒç„¡åйã«ãªã£ã¦ã„ã¾ã™"
+
msgid "Warning: terminal cannot highlight"
msgstr "警告: 使用ã—ã¦ã„る端末ã¯ãƒã‚¤ãƒ©ã‚¤ãƒˆã§ãã¾ã›ã‚“"
-#: ../normal.c:2807
msgid "E348: No string under cursor"
msgstr "E348: カーソルã®ä½ç½®ã«ã¯æ–‡å­—列ãŒã‚りã¾ã›ã‚“"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: ç¾åœ¨ã® 'foldmethod' ã§ã¯æŠ˜ç•³ã¿ã‚’消去ã§ãã¾ã›ã‚“"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: 変更リストãŒç©ºã§ã™"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: 変更リストã®å…ˆé ­"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: å¤‰æ›´ãƒªã‚¹ãƒˆã®æœ«å°¾"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "Vimを終了ã™ã‚‹ã«ã¯ :quit<Enter> ã¨å…¥åŠ›ã—ã¦ãã ã•ã„"
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim"
+msgstr ""
+"ã™ã¹ã¦ã®å¤‰æ›´ã‚’破棄ã—ã€Vimを終了ã™ã‚‹ã«ã¯ :qa! ã¨å…¥åŠ›ã— <Enter> を押ã—ã¦ãã "
+"ã•ã„"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "1 行㌠%s ã§ 1 回処ç†ã•れã¾ã—ãŸ"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "1 行㌠%s ã§ %d 回処ç†ã•れã¾ã—ãŸ"
-#: ../ops.c:253
#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> 行㌠%s ã§ 1 回処ç†ã•れã¾ã—ãŸ"
+msgid "%ld lines %sed 1 time"
+msgstr "%ld 行㌠%s ã§ 1 回処ç†ã•れã¾ã—ãŸ"
-#: ../ops.c:256
#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> 行㌠%s ã§ %d 回処ç†ã•れã¾ã—ãŸ"
+msgid "%ld lines %sed %d times"
+msgstr "%ld 行㌠%s ã§ %d 回処ç†ã•れã¾ã—ãŸ"
-#: ../ops.c:592
#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> 行ãŒã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•れã¾ã™... "
+msgid "%ld lines to indent... "
+msgstr "%ld 行ãŒã‚¤ãƒ³ãƒ‡ãƒ³ãƒˆã•れã¾ã™... "
-#: ../ops.c:634
msgid "1 line indented "
msgstr "1 行をインデントã—ã¾ã—㟠"
-#: ../ops.c:636
#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> 行をインデントã—ã¾ã—㟠"
+msgid "%ld lines indented "
+msgstr "%ld 行をインデントã—ã¾ã—㟠"
-#: ../ops.c:938
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
#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> 行ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
+msgid "%ld lines changed"
+msgstr "%ld 行ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "1 行ã®ãƒ–ロックãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+#, c-format
+msgid "freeing %ld lines"
+msgstr "%ld 行を解放中"
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "1 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+#, c-format
+msgid " into \"%c"
+msgstr " \"%c ã«"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "%<PRId64> 行ã®ãƒ–ロックãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+msgid "block of 1 line yanked%s"
+msgstr "1 行ã®ãƒ–ロックãŒ%sヤンクã•れã¾ã—ãŸ"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> 行ãŒãƒ¤ãƒ³ã‚¯ã•れã¾ã—ãŸ"
+msgid "1 line yanked%s"
+msgstr "1 行ãŒ%sヤンクã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "block of %ld lines yanked%s"
+msgstr "%ld 行ã®ãƒ–ロックãŒ%sヤンクã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "%ld lines yanked%s"
+msgstr "%ld 行ãŒ%sヤンクã•れã¾ã—ãŸ"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: レジスタ %s ã«ã¯ä½•ã‚‚ã‚りã¾ã›ã‚“"
-#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4494,11 +4183,9 @@ msgstr ""
"\n"
"--- レジスタ ---"
-#: ../ops.c:4455
msgid "Illegal register name"
msgstr "䏿­£ãªãƒ¬ã‚¸ã‚¹ã‚¿å"
-#: ../ops.c:4533
msgid ""
"\n"
"# Registers:\n"
@@ -4506,7 +4193,6 @@ msgstr ""
"\n"
"# レジスタ:\n"
-#: ../ops.c:4575
#, c-format
msgid "E574: Unknown register type %d"
msgstr "E574: 未知ã®ãƒ¬ã‚¸ã‚¹ã‚¿åž‹ %d ã§ã™"
@@ -4516,86 +4202,58 @@ msgid ""
"lines"
msgstr "E883: 検索パターンã¨å¼ãƒ¬ã‚¸ã‚¹ã‚¿ã«ã¯2行以上をå«ã‚られã¾ã›ã‚“"
-#: ../ops.c:5089
#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> 列; "
+msgid "%ld Cols; "
+msgstr "%ld 列; "
-#: ../ops.c:5097
#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"é¸æŠž %s%<PRId64> / %<PRId64> 行; %<PRId64> / %<PRId64> å˜èªž; %<PRId64> / "
-"%<PRId64> ãƒã‚¤ãƒˆ"
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
+msgstr "é¸æŠž %s%ld / %ld 行; %lld / %lld å˜èªž; %lld / %lld ãƒã‚¤ãƒˆ"
-#: ../ops.c:5105
#, c-format
msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
msgstr ""
-"é¸æŠž %s%<PRId64> / %<PRId64> 行; %<PRId64> / %<PRId64> å˜èªž; %<PRId64> / "
-"%<PRId64> 文字; %<PRId64> / %<PRId64> ãƒã‚¤ãƒˆ"
+"é¸æŠž %s%ld / %ld 行; %lld / %lld å˜èªž; %lld / %lld 文字; %lld / %lld ãƒã‚¤ãƒˆ"
-#: ../ops.c:5123
#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"列 %s / %s; 行 %<PRId64> of %<PRId64>; å˜èªž %<PRId64> / %<PRId64>; ãƒã‚¤ãƒˆ "
-"%<PRId64> / %<PRId64>"
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "列 %s / %s; 行 %ld of %ld; å˜èªž %lld / %lld; ãƒã‚¤ãƒˆ %lld / %lld"
-#: ../ops.c:5133
#, c-format
msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte "
+"%lld of %lld"
msgstr ""
-"列 %s / %s; 行 %<PRId64> / %<PRId64>; å˜èªž %<PRId64> / %<PRId64>; 文字 "
-"%<PRId64> / %<PRId64>; ãƒã‚¤ãƒˆ %<PRId64> of %<PRId64>"
+"列 %s / %s; 行 %ld / %ld; å˜èªž %lld / %lld; 文字 %lld / %lld; ãƒã‚¤ãƒˆ %lld of "
+"%lld"
-#: ../ops.c:5146
#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> for BOM)"
+msgid "(+%lld for BOM)"
+msgstr "(+%lld for BOM)"
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=%N ページ"
-
-#: ../option.c:1574
msgid "Thanks for flying Vim"
msgstr "Vim を使ã£ã¦ãれã¦ã‚りãŒã¨ã†"
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: 未知ã®ã‚ªãƒ—ションã§ã™"
-#: ../option.c:2709
msgid "E519: Option not supported"
msgstr "E519: オプションã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: modeline ã§ã¯è¨±å¯ã•れã¾ã›ã‚“"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: キーコードãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../option.c:2924
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>"
@@ -4604,106 +4262,117 @@ msgstr "E539: 䏿­£ãªæ–‡å­—ã§ã™ <%s>"
msgid "For option %s"
msgstr "オプション: %s"
-#: ../option.c:3862
msgid "E529: Cannot set 'term' to empty string"
msgstr "E529: 'term' ã«ã¯ç©ºæ–‡å­—列を設定ã§ãã¾ã›ã‚“"
-#: ../option.c:3885
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: GUIã§ã¯ 'term' を変更ã§ãã¾ã›ã‚“"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: GUIをスタートã™ã‚‹ã«ã¯ \":gui\" を使用ã—ã¦ãã ã•ã„"
+
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 "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: GTK+2 GUIã§ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+
+#, c-format
+msgid "E950: Cannot convert between %s and %s"
+msgstr "E950: %s 㨠%s ã®é–“ã§å¤‰æ›ã§ãã¾ã›ã‚“"
+
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
+msgid "E596: Invalid font(s)"
+msgstr "E596: 無効ãªãƒ•ォントã§ã™"
+
+msgid "E597: can't select fontset"
+msgstr "E597: ãƒ•ã‚©ãƒ³ãƒˆã‚»ãƒƒãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: 無効ãªãƒ•ォントセットã§ã™"
+
+msgid "E533: can't select wide font"
+msgstr "E533: ãƒ¯ã‚¤ãƒ‰ãƒ•ã‚©ãƒ³ãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: 無効ãªãƒ¯ã‚¤ãƒ‰ãƒ•ォントã§ã™"
+
#, 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 "E538: No mouse support"
+msgstr "E538: マウスã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“"
+
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
+msgid "E946: Cannot make a terminal with running job modifiable"
+msgstr "E946: 実行中ã®ã‚¸ãƒ§ãƒ–ãŒã‚る端末ã¯å¤‰æ›´å¯èƒ½ã«ã§ãã¾ã›ã‚“"
+
msgid "E590: A preview window already exists"
msgstr "E590: ãƒ—ãƒ¬ãƒ“ãƒ¥ãƒ¼ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr ""
-"W17: アラビア文字ã«ã¯UTF-8ãŒå¿…è¦ãªã®ã§, ':set encoding=utf-8' ã—ã¦ãã ã•ã„"
+"W17: アラビア文字ã«ã¯UTF-8ãŒå¿…è¦ãªã®ã§ã€':set encoding=utf-8' ã—ã¦ãã ã•ã„"
+
+msgid "E954: 24-bit colors are not supported on this environment"
+msgstr "E954: 24bit色ã¯ã“ã®ç’°å¢ƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: 最低 %d ã®è¡Œæ•°ãŒå¿…è¦ã§ã™"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: 最低 %d ã®ã‚«ãƒ©ãƒ å¹…ãŒå¿…è¦ã§ã™"
-#: ../option.c:6011
#, 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
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: æ•°å­—ãŒå¿…è¦ã§ã™: &%s = '%s'"
-#: ../option.c:6149
msgid ""
"\n"
"--- Terminal codes ---"
@@ -4711,7 +4380,6 @@ msgstr ""
"\n"
"--- 端末コード ---"
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4719,7 +4387,6 @@ msgstr ""
"\n"
"--- グローãƒãƒ«ã‚ªãƒ—ション値 ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4727,7 +4394,6 @@ msgstr ""
"\n"
"--- ローカルオプション値 ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4735,37 +4401,115 @@ msgstr ""
"\n"
"--- オプション ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: get_varp エラー"
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': %s ã«å¯¾å¿œã™ã‚‹æ–‡å­—ãŒã‚りã¾ã›ã‚“"
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap': セミコロンã®å¾Œã«ä½™åˆ†ãªæ–‡å­—ãŒã‚りã¾ã™: %s"
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"シェルを実行ã§ãã¾ã›ã‚“ "
+msgid "cannot open "
+msgstr "é–‹ã‘ã¾ã›ã‚“ "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: ウィンドウを開ã‘ã¾ã›ã‚“!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Amigadosã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2.04ã‹ãれ以é™ãŒå¿…è¦ã§ã™\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "%s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %ld ãŒå¿…è¦ã§ã™\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "NILã‚’é–‹ã‘ã¾ã›ã‚“:\n"
+
+msgid "Cannot create "
+msgstr "作æˆã§ãã¾ã›ã‚“ "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim㯠%d ã§çµ‚了ã—ã¾ã™\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "コンソールモードを変更ã§ãã¾ã›ã‚“?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: コンソールã§ã¯ãªã„??\n"
+
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: -f オプションã§ã‚·ã‚§ãƒ«ã‚’実行ã§ãã¾ã›ã‚“"
+
+msgid "Cannot execute "
+msgstr "実行ã§ãã¾ã›ã‚“ "
+
+msgid "shell "
+msgstr "シェル "
+
+msgid " returned\n"
+msgstr " 戻りã¾ã—ãŸ\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE ãŒå°ã•éŽãŽã¾ã™."
+
+msgid "I/O ERROR"
+msgstr "入出力エラー"
+
+msgid "Message"
+msgstr "メッセージ"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: プリンタã®é¸æŠžã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "%s 㸠(%s 上ã®)"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: 未知ã®ãƒ—リンタオプションã§ã™: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: å°åˆ·ã‚¨ãƒ©ãƒ¼: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "å°åˆ·ã—ã¦ã„ã¾ã™: '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: 文字セットå \"%s\" ã¯ä¸æ­£ã§ã™ (フォントå \"%s\")"
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: å“質å \"%s\" ã¯ä¸æ­£ã§ã™ (フォントå \"%s\")"
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: '%c' ã¯ä¸æ­£ãªæ–‡å­—ã§ã™ (フォントå \"%s\")"
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Xサーãƒãƒ¼ã¸ã®æŽ¥ç¶šã« %ld ミリ秒ã‹ã‹ã‚Šã¾ã—ãŸ"
-#: ../os/shell.c:439
msgid ""
"\n"
-"shell returned "
+"Vim: Got X error\n"
msgstr ""
"\n"
-"シェルãŒå€¤ã‚’è¿”ã—ã¾ã—㟠"
+"Vim: X ã®ã‚¨ãƒ©ãƒ¼ã‚’検出ã—ã¾ã—ãŸr\n"
+
+msgid "Testing the X display failed"
+msgstr "X display ã®ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "Opening the X display timed out"
+msgstr "X display ã® open ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ"
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
"Could not get security context for "
@@ -4773,7 +4517,6 @@ msgstr ""
"\n"
"セキュリティコンテキストをå–å¾—ã§ãã¾ã›ã‚“ "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4789,223 +4532,289 @@ msgstr "セキュリティコンテキスト %s ã‚’ %s ã«è¨­å®šã§ãã¾ã›ã‚“"
msgid "Could not get security context %s for %s. Removing it!"
msgstr "セキュリティコンテキスト %s ã‚’ %s ã‹ã‚‰å–å¾—ã§ãã¾ã›ã‚“. 削除ã—ã¾ã™!"
-#: ../os_unix.c:1558 ../os_unix.c:1647
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"sh シェルを実行ã§ãã¾ã›ã‚“\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"シェルãŒå€¤ã‚’è¿”ã—ã¾ã—㟠"
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"パイプを作æˆã§ãã¾ã›ã‚“\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"fork ã§ãã¾ã›ã‚“\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"シェルを実行ã§ãã¾ã›ã‚“ "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"コマンドを中断ã—ã¾ã—ãŸ\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP ãŒICE接続を失ã„ã¾ã—ãŸ"
+
#, c-format
msgid "dlerror = \"%s\""
msgstr "dlerror = \"%s\""
-#: ../path.c:1449
+msgid "Opening the X display failed"
+msgstr "X display ã® open ã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP ãŒsave-yourselfè¦æ±‚を処ç†ã—ã¦ã„ã¾ã™"
+
+msgid "XSMP opening connection"
+msgstr "XSMP ãŒæŽ¥ç¶šã‚’é–‹å§‹ã—ã¦ã„ã¾ã™"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICE接続ãŒå¤±æ•—ã—ãŸã‚ˆã†ã§ã™"
+
#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnectionãŒå¤±æ•—ã—ã¾ã—ãŸ: %s"
+
+msgid "At line"
+msgstr "行"
+
+msgid "Could not load vim32.dll!"
+msgstr "vim32.dll をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+msgid "VIM Error"
+msgstr "VIMエラー"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "DLLã‹ã‚‰é–¢æ•°ãƒã‚¤ãƒ³ã‚¿ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: イベント %s を検知\n"
+
+msgid "close"
+msgstr "é–‰ã˜ã‚‹"
+
+msgid "logoff"
+msgstr "ログオフ"
+
+msgid "shutdown"
+msgstr "シャットダウン"
+
+msgid "E371: Command not found"
+msgstr "E371: コマンドãŒã‚りã¾ã›ã‚“"
+
+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 ""
+"VIMRUN.EXE㌠$PATH ã®ä¸­ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“.\n"
+"外部コマンドã®çµ‚了後ã«ä¸€æ™‚åœæ­¢ã‚’ã—ã¾ã›ã‚“.\n"
+"詳細㯠:help win32-vimrun ã‚’å‚ç…§ã—ã¦ãã ã•ã„."
+
+msgid "Vim Warning"
+msgstr "Vimã®è­¦å‘Š"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "シェルãŒã‚³ãƒ¼ãƒ‰ %d ã§çµ‚了ã—ã¾ã—ãŸ"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: ç¾åœ¨ã®ãƒ­ã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒªã‚¹ãƒˆãŒå¤‰æ›´ã•れã¾ã—ãŸ"
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: フォーマット文字列㫠%%%c ãŒå¤šéŽãŽã¾ã™"
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: フォーマット文字列ã«äºˆæœŸã›ã¬ %%%c ãŒã‚りã¾ã—ãŸ"
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: フォーマット文字列㫠] ãŒã‚りã¾ã›ã‚“"
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: フォーマット文字列ã§ã¯ %%%c ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“"
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: フォーマット文字列ã®å‰ç½®ã«ç„¡åŠ¹ãª %%%c ãŒã‚りã¾ã™"
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: フォーマット文字列ã«ç„¡åŠ¹ãª %%%c ãŒã‚りã¾ã™"
-#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' ã«ãƒ‘ã‚¿ãƒ¼ãƒ³ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: ディレクトリåãŒç„¡ã„ã‹ç©ºã§ã™"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: è¦ç´ ãŒã‚‚ã†ã‚りã¾ã›ã‚“"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: ç¾åœ¨ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒé–‰ã˜ã‚‰ã‚Œã¾ã—ãŸ"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: ç¾åœ¨ã® quickfix ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d of %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (行ãŒå‰Šé™¤ã•れã¾ã—ãŸ)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%s エラー一覧 %d of %d; %d 個エラー"
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: quickfix ã‚¹ã‚¿ãƒƒã‚¯ã®æœ«å°¾ã§ã™"
-#: ../quickfix.c:1869
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 of %d; %d 個エラー"
+msgid "No entries"
+msgstr "エントリãŒã‚りã¾ã›ã‚“"
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: 'buftype' オプションãŒè¨­å®šã•れã¦ã„ã‚‹ã®ã§æ›¸è¾¼ã¿ã¾ã›ã‚“"
+msgid "Error file"
+msgstr "エラーファイル"
-#: ../quickfix.c:2812
msgid "E683: File name missing or invalid pattern"
msgstr "E683: ファイルåãŒç„¡ã„ã‹ç„¡åйãªãƒ‘ターンã§ã™"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: ãƒãƒƒãƒ•ã‚¡ã¯èª­ã¿è¾¼ã¾ã‚Œã¾ã›ã‚“ã§ã—ãŸ"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: 文字列ã‹ãƒªã‚¹ãƒˆãŒå¿…è¦ã§ã™"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: 無効ãªé …ç›®ã§ã™: %s%%[]"
-#
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: %s[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“"
-#: ../regexp.c:375
+msgid "E944: Reverse range in character class"
+msgstr "E944: 文字クラスã®ç¯„囲ãŒé€†ã§ã™"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: 文字クラスã®ç¯„囲ãŒå¤§ãã™ãŽã¾ã™"
+
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: %s%%( ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“"
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: %s( ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“"
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: %s) ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“"
-#
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: \\z( ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 ãã®ä»–ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+msgid "E67: \\z1 - \\z9 not allowed here"
+msgstr "E67: \\z1 - \\z9 ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: %s%%[ ã®å¾Œã« ] ãŒã‚りã¾ã›ã‚“"
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] ãŒç©ºã§ã™"
-#: ../regexp.c:1209 ../regexp.c:1224
+msgid "E956: Cannot use pattern recursively"
+msgstr "E956: パターンをå†å¸°çš„ã«ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: 䏿­£ãªå¾Œæ–¹å‚ç…§ã§ã™"
+
msgid "E339: Pattern too long"
msgstr "E339: パターンãŒé•·éŽãŽã¾ã™"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: \\z( ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: %s( ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: \\z( ãŒé‡£ã‚Šåˆã£ã¦ã„ã¾ã›ã‚“"
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: %s@ ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: 複雑㪠%s{...} ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61:%s* ãŒå…¥ã‚Œå­ã«ãªã£ã¦ã„ã¾ã™"
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62:%s%c ãŒå…¥ã‚Œå­ã«ãªã£ã¦ã„ã¾ã™"
-#
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: \\_ ã®ç„¡åйãªä½¿ç”¨æ–¹æ³•ã§ã™"
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64:%s%c ã®å¾Œã«ãªã«ã‚‚ã‚りã¾ã›ã‚“"
-#
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: 䏿­£ãªå¾Œæ–¹å‚ç…§ã§ã™"
-
-#
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: \\z ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ"
-#
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: %s%%[dxouU] ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ"
-#
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: %s%% ã®å¾Œã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã—ãŸ"
-#: ../regexp.c:3017
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: %s{...} å†…ã«æ–‡æ³•エラーãŒã‚りã¾ã™"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "外部ã®éƒ¨åˆ†è©²å½“:\n"
@@ -5013,7 +4822,6 @@ msgstr "外部ã®éƒ¨åˆ†è©²å½“:\n"
msgid "E888: (NFA regexp) cannot repeat %s"
msgstr "E888: (NFA æ­£è¦è¡¨ç¾) 繰り返ã›ã¾ã›ã‚“ %s"
-#: ../regexp.c:7022
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5024,62 +4832,58 @@ msgstr ""
msgid "Switching to backtracking RE engine for pattern: "
msgstr "次ã®ãƒ‘ターンã«ãƒãƒƒã‚¯ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚° RE エンジンをé©ç”¨ã—ã¾ã™: "
-#: ../regexp_nfa.c:239
msgid "E865: (NFA) Regexp end encountered prematurely"
msgstr "E865: (NFA) æœŸå¾…ã‚ˆã‚Šæ—©ãæ­£è¦è¡¨ç¾ã®çµ‚端ã«åˆ°é”ã—ã¾ã—ãŸ"
-#: ../regexp_nfa.c:240
#, c-format
msgid "E866: (NFA regexp) Misplaced %c"
msgstr "E866: (NFA æ­£è¦è¡¨ç¾) ä½ç½®ãŒèª¤ã£ã¦ã„ã¾ã™: %c"
-#: ../regexp_nfa.c:242
#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (NFA æ­£è¦è¡¨ç¾) ç„¡åŠ¹ãªæ–‡å­—クラス: %<PRId64>"
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (NFA æ­£è¦è¡¨ç¾) ç„¡åŠ¹ãªæ–‡å­—クラス: %ld"
-#: ../regexp_nfa.c:1261
#, c-format
msgid "E867: (NFA) Unknown operator '\\z%c'"
msgstr "E867: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\z%c'"
-#: ../regexp_nfa.c:1387
+msgid "E951: \\% value too large"
+msgstr "E951: \\% 値ãŒé•·éŽãŽã¾ã™"
+
#, c-format
msgid "E867: (NFA) Unknown operator '\\%%%c'"
msgstr "E867: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\%%%c'"
-#: ../regexp_nfa.c:1802
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: 等価クラスをå«ã‚€NFA構築ã«å¤±æ•—ã—ã¾ã—ãŸ!"
+
#, c-format
msgid "E869: (NFA) Unknown operator '\\@%c'"
msgstr "E869: (NFA) 未知ã®ã‚ªãƒšãƒ¬ãƒ¼ã‚¿ã§ã™: '\\@%c'"
-#: ../regexp_nfa.c:1831
msgid "E870: (NFA regexp) Error reading repetition limits"
msgstr "E870: (NFA æ­£è¦è¡¨ç¾) 繰り返ã—ã®åˆ¶é™å›žæ•°ã‚’読込中ã«ã‚¨ãƒ©ãƒ¼"
-#. 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 æ­£è¦è¡¨ç¾) 繰り返㗠ã®å¾Œã« 繰り返㗠ã¯ã§ãã¾ã›ã‚“!"
+msgid "E871: (NFA regexp) Can't have a multi follow a multi"
+msgstr "E871: (NFA æ­£è¦è¡¨ç¾) 繰り返㗠ã®å¾Œã« 繰り返㗠ã¯ã§ãã¾ã›ã‚“"
-#. Too many `('
-#: ../regexp_nfa.c:2037
msgid "E872: (NFA regexp) Too many '('"
msgstr "E872: (NFA æ­£è¦è¡¨ç¾) '(' ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp_nfa.c:2042
msgid "E879: (NFA regexp) Too many \\z("
msgstr "E879: (NFA æ­£è¦è¡¨ç¾) \\z( ãŒå¤šéŽãŽã¾ã™"
-#: ../regexp_nfa.c:2066
msgid "E873: (NFA regexp) proper termination error"
msgstr "E873: (NFA æ­£è¦è¡¨ç¾) 終端記å·ãŒã‚りã¾ã›ã‚“"
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
+msgid "Could not open temporary log file for writing, displaying on stderr... "
+msgstr ""
+"NFAæ­£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒ­ã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“ã€‚ãƒ­ã‚°ã¯æ¨™æº–エラー"
+"出力ã«å‡ºåŠ›ã—ã¾ã™ã€‚"
+
+msgid "E874: (NFA) Could not pop the stack!"
msgstr "E874: (NFA) スタックをãƒãƒƒãƒ—ã§ãã¾ã›ã‚“!"
-#: ../regexp_nfa.c:3298
msgid ""
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
"left on stack"
@@ -5087,177 +4891,122 @@ msgstr ""
"E875: (NFA æ­£è¦è¡¨ç¾) (後置文字列をNFAã«å¤‰æ›ä¸­ã«) ã‚¹ã‚¿ãƒƒã‚¯ã«æ®‹ã•れãŸã‚¹ãƒ†ãƒ¼ãƒˆãŒ"
"多éŽãŽã¾ã™"
-#: ../regexp_nfa.c:3302
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
msgstr "E876: (NFA æ­£è¦è¡¨ç¾) NFA全体をä¿å­˜ã™ã‚‹ã«ã¯ç©ºãスペースãŒè¶³ã‚Šã¾ã›ã‚“"
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"NFAæ­£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒ­ã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“ã€‚ãƒ­ã‚°ã¯æ¨™æº–出力ã«"
-"出力ã—ã¾ã™ã€‚"
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) ログファイル %s ã‚’é–‹ã‘ã¾ã›ã‚“!"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "NFAæ­£è¦è¡¨ç¾ã‚¨ãƒ³ã‚¸ãƒ³ç”¨ã®ãƒ­ã‚°ãƒ•ァイルを書込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“。"
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (NFA) ç¾åœ¨æ¨ªæ–­ä¸­ã®ãƒ–ランãƒã«å分ãªãƒ¡ãƒ¢ãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“!"
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " 仮想置æ›"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ç½®æ›"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " å転"
-#: ../screen.c:7441
msgid " INSERT"
msgstr " 挿入"
-#: ../screen.c:7443
msgid " (insert)"
msgstr " (挿入)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (ç½®æ›)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (仮想置æ›)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " ヘブライ"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " アラビア"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (言語)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (貼り付ã‘)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " ビジュアル"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " ビジュアル 行"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " ビジュアル 矩形"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " セレクト"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " 行指å‘é¸æŠž"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " çŸ©å½¢é¸æŠž"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "記録中"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: ç„¡åŠ¹ãªæ¤œç´¢æ–‡å­—列ã§ã™: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: 上ã¾ã§æ¤œç´¢ã—ã¾ã—ãŸãŒè©²å½“箇所ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: 下ã¾ã§æ¤œç´¢ã—ã¾ã—ãŸãŒè©²å½“箇所ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: ';' ã®ã‚ã¨ã«ã¯ '?' ã‹ '/' ãŒæœŸå¾…ã•れã¦ã„ã‚‹"
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (å‰ã«åˆ—挙ã—ãŸè©²å½“箇所をå«ã‚€)"
-#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- インクルードã•れãŸãƒ•ァイル "
-#: ../search.c:4106
msgid "not found "
msgstr "見ã¤ã‹ã‚Šã¾ã›ã‚“ "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "パス㫠----\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (æ—¢ã«åˆ—挙)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " 見ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "インクルードã•れãŸãƒ•ァイルをスキャン中: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
-msgstr "インクルードã•れãŸãƒ•ァイルをスキャン中 %s"
+msgstr "インクルードã•れãŸãƒ•ァイルを検索中 %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: ç¾åœ¨è¡Œã«è©²å½“ãŒã‚りã¾ã™"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "å…¨ã¦ã®ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ã•れãŸãƒ•ァイルãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ"
-#: ../search.c:4519
msgid "No included files"
msgstr "インクルードファイルã¯ã‚りã¾ã›ã‚“"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: 定義を見ã¤ã‘られã¾ã›ã‚“"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: パターンを見ã¤ã‘られã¾ã›ã‚“"
-#: ../search.c:4668
msgid "Substitute "
msgstr "Substitute "
-#: ../search.c:4681
#, c-format
msgid ""
"\n"
@@ -5268,99 +5017,129 @@ msgstr ""
"# 最後㮠%s検索パターン:\n"
"~"
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: ã‚¹ãƒšãƒ«ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸å¼ã‚¨ãƒ©ãƒ¼ã§ã™"
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: スペルãƒã‚§ãƒƒã‚¯ã¯ç„¡åŠ¹åŒ–ã•れã¦ã„ã¾ã™"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr ""
+"警告: å˜èªžãƒªã‚¹ãƒˆ \"%s_%s.spl\" ãŠã‚ˆã³ \"%s_ascii.spl\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr ""
+"警告: å˜èªžãƒªã‚¹ãƒˆ \"%s.%s.spl\" ãŠã‚ˆã³ \"%s.ascii.spl\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: autocommand ã® SpellFileMissing ãŒãƒãƒƒãƒ•ァを削除ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "警告9: %s ã¨ã„ã†ç¯„囲ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+
+msgid "Sorry, no suggestions"
+msgstr "残念ã§ã™ãŒã€ä¿®æ­£å€™è£œã¯ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "残念ã§ã™ãŒã€ä¿®æ­£å€™è£œã¯ %ld 個ã—ã‹ã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "\"%.*s\" を次ã¸å¤‰æ›:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: スペル置æ›ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: 見ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../spell.c:952
msgid "E758: Truncated spell file"
msgstr "E758: スペルファイルãŒåˆ‡å–られã¦ã„るよã†ã§ã™"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "%s (%d 行目) ã«ç¶šãテキスト: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "%s (%d 行目) ã® affix åãŒé•·éŽãŽã¾ã™: %s"
-#: ../spell.c:955
msgid "E761: Format error in affix file FOL, LOW or UPP"
msgstr ""
"E761: affixファイル㮠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
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\" ãŠã‚ˆã³ \"%s.ascii.spl\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "スペルファイル \"%s\" を読込中"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: スペルファイルã§ã¯ãªã„よã†ã§ã™"
-#: ../spell.c:2501
msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: å¤ã„スペルファイルãªã®ã§, アップデートã—ã¦ãã ã•ã„"
+msgstr "E771: å¤ã„スペルファイルãªã®ã§ã€ã‚¢ãƒƒãƒ—デートã—ã¦ãã ã•ã„"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: より新ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® Vim 用ã®ã‚¹ãƒšãƒ«ãƒ•ァイルã§ã™"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: スペルファイルã«ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„セクションãŒã‚りã¾ã™"
-#: ../spell.c:3762
#, c-format
-msgid "Warning: region %s not supported"
-msgstr "警告9: %s ã¨ã„ã†ç¯„囲ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: .sug ファイルã§ã¯ãªã„よã†ã§ã™: %s"
-#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: å¤ã„ .sug ファイルãªã®ã§ã€ã‚¢ãƒƒãƒ—デートã—ã¦ãã ã•ã„: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: より新ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® Vim 用㮠.sug ファイルã§ã™: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug ファイル㌠.spl ファイルã¨ä¸€è‡´ã—ã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: .sug ファイルã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "Reading affix file %s..."
msgstr "affix ファイル %s を読込中..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "%s (%d 行目) ã®å˜èªžã‚’変æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "%s å†…ã®æ¬¡ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“: %s ã‹ã‚‰ %s ã¸"
-#: ../spell.c:4642
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "%s 内ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "%s 内㮠%d 行目㮠FLAG ã«ç„¡åйãªå€¤ãŒã‚りã¾ã™: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "%s 内㮠%d 行目ã«ãƒ•ラグã®äºŒé‡ä½¿ç”¨ãŒã‚りã¾ã™: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5369,7 +5148,6 @@ msgstr ""
"%s ã® %d 行目㮠PFX é …ç›®ã®å¾Œã® COMPOUNDFORBIDFLAG ã®å®šç¾©ã¯èª¤ã£ãŸçµæžœã‚’生ã˜ã‚‹"
"ã“ã¨ãŒã‚りã¾ã™"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5378,43 +5156,35 @@ msgstr ""
"%s ã® %d 行目㮠PFX é …ç›®ã®å¾Œã® COMPOUNDPERMITFLAG ã®å®šç¾©ã¯èª¤ã£ãŸçµæžœã‚’生ã˜ã‚‹"
"ã“ã¨ãŒã‚りã¾ã™"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "COMPOUNDRULES ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™. ファイル %s ã® %d 行目: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "%s ã® %d 行目㮠COMPOUNDWORDMAX ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "%s ã® %d 行目㮠COMPOUNDMIN ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "%s ã® %d 行目㮠COMPOUNDSYLMAX ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "%s ã® %d 行目㮠CHECKCOMPOUNDPATTERN ã®å€¤ã«èª¤ã‚ŠãŒã‚りã¾ã™: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
"%s ã® %d 行目㮠連続 affix ブロックã®ãƒ•ラグã®çµ„åˆã›ã«é•ã„ãŒã‚りã¾ã™: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "%s ã® %d 行目㫠é‡è¤‡ã—㟠affix を検出ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
@@ -5423,337 +5193,245 @@ msgstr ""
"%s 㮠%d 行目㮠affix 㯠BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
"ã«ä½¿ç”¨ã—ã¦ãã ã•ã„: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "%s ã® %d 行目ã§ã¯ Y ã‹ N ãŒå¿…è¦ã§ã™: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "%s ã® %d 行目㮠æ¡ä»¶ã¯å£Šã‚Œã¦ã„ã¾ã™: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "%s ã® %d 行目ã«ã¯ REP(SAL) ã®å›žæ•°ãŒå¿…è¦ã§ã™"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "%s ã® %d 行目ã«ã¯ MAP ã®å›žæ•°ãŒå¿…è¦ã§ã™"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "%s ã® %d 行目㮠MAP ã«é‡è¤‡ã—ãŸæ–‡å­—ãŒã‚りã¾ã™"
-#: ../spell.c:5176
#, 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
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "SYLLABLE ãŒæŒ‡å®šã•れãªã„ COMPOUNDSYLMAX"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "é…延後置å­ãŒå¤šéŽãŽã¾ã™"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "複åˆãƒ•ラグãŒå¤šéŽãŽã¾ã™"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "é…å»¶å¾Œç½®å­ ã¨/ã‚‚ã—ã㯠複åˆãƒ•ラグãŒå¤šéŽãŽã¾ã™"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "SOFO%s 行㌠%s ã«ã‚りã¾ã›ã‚“"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "SAL行 㨠SOFO行 ㌠%s ã§ä¸¡æ–¹æŒ‡å®šã•れã¦ã„ã¾ã™"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "%s ã® %d è¡Œã® ãƒ•ãƒ©ã‚°ãŒæ•°å€¤ã§ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "%s ã® %d 行目㮠フラグãŒä¸æ­£ã§ã™: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "値 %s ã¯ä»–ã® .aff ファイルã§ä½¿ç”¨ã•れãŸã®ã¨ç•°ãªã‚Šã¾ã™"
-#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "辞書ファイル %s をスキャン中..."
+msgid "Reading dictionary file %s..."
+msgstr "辞書ファイル %s を読込ã¿ä¸­..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: %s ã«ã¯å˜èªžæ•°ãŒã‚りã¾ã›ã‚“"
-#: ../spell.c:5669
#, 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
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "%s ã® %d 行目㧠é‡è¤‡å˜èªžãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "é‡è¤‡ã®ã†ã¡æœ€åˆã®å˜èªžã¯ %s ã® %d 行目ã§ã™: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d 個ã®å˜èªžãŒè¦‹ã¤ã‹ã‚Šã¾ã—㟠(%s 内)"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "éžASCII文字をå«ã‚€ %d 個ã®å˜èªžã‚’無視ã—ã¾ã—㟠(%s 内)"
-#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "標準入力ã‹ã‚‰èª­è¾¼ã¿ä¸­ %s ..."
+msgid "Reading word file %s..."
+msgstr "å˜èªžãƒ•ァイル %s を読込ã¿ä¸­..."
-#: ../spell.c:6155
#, c-format
msgid "Duplicate /encoding= line ignored in %s line %d: %s"
msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/encoding= 行を無視ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:6159
#, c-format
msgid "/encoding= line after word ignored in %s line %d: %s"
msgstr "%s ã® %d 行目㮠å˜èªžã®å¾Œã® /encoding= 行を無視ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:6180
#, c-format
msgid "Duplicate /regions= line ignored in %s line %d: %s"
msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/regions= 行を無視ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:6185
#, c-format
msgid "Too many regions in %s line %d: %s"
-msgstr "%s ã® %d 行目, 範囲指定ãŒå¤šéŽãŽã¾ã™: %s"
+msgstr "%s ã® %d 行目ã€ç¯„囲指定ãŒå¤šéŽãŽã¾ã™: %s"
-#: ../spell.c:6198
#, c-format
msgid "/ line ignored in %s line %d: %s"
msgstr "%s ã® %d 行目㮠é‡è¤‡ã—㟠/ 行を無視ã—ã¾ã—ãŸ: %s"
-#: ../spell.c:6224
#, c-format
msgid "Invalid region nr in %s line %d: %s"
msgstr "%s ã® %d 行目 無効㪠nr 領域ã§ã™: %s"
-#: ../spell.c:6230
#, c-format
msgid "Unrecognized flags in %s line %d: %s"
msgstr "%s ã® %d 行目 èªè­˜ä¸èƒ½ãªãƒ•ラグã§ã™: %s"
-#: ../spell.c:6257
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "éžASCII文字をå«ã‚€ %d 個ã®å˜èªžã‚’無視ã—ã¾ã—ãŸ"
-#: ../spell.c:6656
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: メモリãŒè¶³ã‚Šãªã„ã®ã§ã€å˜èªžãƒªã‚¹ãƒˆã¯ä¸å®Œå…¨ã§ã™"
+
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "ノード %d 個(å…¨ %d 個中) を圧縮ã—ã¾ã—ãŸ; 残り %d (%d%%)"
-#: ../spell.c:7340
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
msgid "Performing soundfolding..."
msgstr "音声畳込ã¿ã‚’実行中..."
-#: ../spell.c:7368
#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "音声畳込ã¿å¾Œã®ç·å˜èªžæ•°: %<PRId64>"
+msgid "Number of words after soundfolding: %ld"
+msgstr "音声畳込ã¿å¾Œã®ç·å˜èªžæ•°: %ld"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "ç·å˜èªžæ•°: %d"
-#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
+msgid "Writing suggestion file %s..."
msgstr "修正候補ファイル \"%s\" を書込ã¿ä¸­..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "推定メモリ使用é‡: %d ãƒã‚¤ãƒˆ"
-#: ../spell.c:7820
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 個ã¾ã§ã—ã‹ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
+#, c-format
+msgid "E754: Only up to %ld regions supported"
+msgstr "E754: 範囲㯠%ld 個ã¾ã§ã—ã‹ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: 無効ãªç¯„囲ã§ã™: %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "警告: 複åˆãƒ•ラグ㨠NOBREAK ãŒä¸¡æ–¹ã¨ã‚‚指定ã•れã¾ã—ãŸ"
-#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
+msgid "Writing spell file %s..."
msgstr "スペルファイル %s を書込ã¿ä¸­..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "実行ã—ã¾ã—ãŸ!"
-#: ../spell.c:8034
#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ã«ã¯ %<PRId64> 個ã®ã‚¨ãƒ³ãƒˆãƒªã¯ã‚りã¾ã›ã‚“"
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' ã«ã¯ %ld 個ã®ã‚¨ãƒ³ãƒˆãƒªã¯ã‚りã¾ã›ã‚“"
-#: ../spell.c:8074
#, c-format
msgid "Word '%.*s' removed from %s"
msgstr "å˜èªž '%.*s' ㌠%s ã‹ã‚‰å‰Šé™¤ã•れã¾ã—ãŸ"
-#: ../spell.c:8117
#, c-format
msgid "Word '%.*s' added to %s"
-msgstr "%s ã«å˜èªžãŒè¿½åŠ ã•れã¾ã—ãŸ"
+msgstr "å˜èªž '%.*s' ㌠%s ã¸è¿½åŠ ã•れã¾ã—ãŸ"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: å˜èªžã®æ–‡å­—ãŒã‚¹ãƒšãƒ«ãƒ•ァイルã¨ç•°ãªã‚Šã¾ã™"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "残念ã§ã™ãŒ, 修正候補ã¯ã‚りã¾ã›ã‚“"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "残念ã§ã™ãŒ, 修正候補㯠%<PRId64> 個ã—ã‹ã‚りã¾ã›ã‚“"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "\"%.*s\" を次ã¸å¤‰æ›:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: スペル置æ›ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: MAP エントリã«é‡è¤‡æ–‡å­—ãŒå­˜åœ¨ã—ã¾ã™"
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: 見ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
+msgid "No Syntax items defined for this buffer"
+msgstr "ã“ã®ãƒãƒƒãƒ•ã‚¡ã«å®šç¾©ã•ã‚ŒãŸæ§‹æ–‡è¦ç´ ã¯ã‚りã¾ã›ã‚“"
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: .sug ファイルã§ã¯ãªã„よã†ã§ã™: %s"
+msgid "syntax conceal on"
+msgstr "構文㮠conceal ã¯ç¾åœ¨ on ã§ã™"
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: å¤ã„ .sug ファイルãªã®ã§, アップデートã—ã¦ãã ã•ã„: %s"
+msgid "syntax conceal off"
+msgstr "構文㮠conceal ã¯ç¾åœ¨ off ã§ã™"
-#: ../spell.c:9286
#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: より新ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® Vim 用㮠.sug ファイルã§ã™: %s"
+msgid "E390: Illegal argument: %s"
+msgstr "E390: 䏿­£ãªå¼•æ•°ã§ã™: %s"
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: .sug ファイル㌠.spl ファイルã¨ä¸€è‡´ã—ã¾ã›ã‚“: %s"
+msgid "syntax case ignore"
+msgstr "æ§‹æ–‡ã®å¤§æ–‡å­—å°æ–‡å­—ã¯ç¾åœ¨ ignore ã§ã™"
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: .sug ファイルã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: %s"
+msgid "syntax case match"
+msgstr "æ§‹æ–‡ã®å¤§æ–‡å­—å°æ–‡å­—ã¯ç¾åœ¨ match ã§ã™"
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: MAP エントリã«é‡è¤‡æ–‡å­—ãŒå­˜åœ¨ã—ã¾ã™"
+msgid "syntax spell toplevel"
+msgstr "構文㮠spell ã¯ç¾åœ¨ toplevel ã§ã™"
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "ã“ã®ãƒãƒƒãƒ•ã‚¡ã«å®šç¾©ã•ã‚ŒãŸæ§‹æ–‡è¦ç´ ã¯ã‚りã¾ã›ã‚“"
+msgid "syntax spell notoplevel"
+msgstr "構文㮠spell ã¯ç¾åœ¨ notoplevel ã§ã™"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: 䏿­£ãªå¼•æ•°ã§ã™: %s"
+msgid "syntax spell default"
+msgstr "構文㮠spell ã¯ç¾åœ¨ default ã§ã™"
msgid "syntax iskeyword "
-msgstr "シンタックス用 iskeyword "
+msgstr "構文用 iskeyword "
-#: ../syntax.c:3299
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: ãã®ã‚ˆã†ãªæ§‹æ–‡ã‚¯ãƒ©ã‚¹ã‚¿ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "C言語風コメントã‹ã‚‰åŒæœŸä¸­"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "éžåŒæœŸ"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "åŒæœŸé–‹å§‹ "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " 行å‰(トップ行よりも)"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5761,7 +5439,6 @@ msgstr ""
"\n"
"--- æ§‹æ–‡åŒæœŸè¦ç´  ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5769,7 +5446,6 @@ msgstr ""
"\n"
"è¦ç´ ä¸Šã§åŒæœŸä¸­"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5777,53 +5453,41 @@ msgstr ""
"\n"
"--- æ§‹æ–‡è¦ç´  ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: ãã®ã‚ˆã†ãªæ§‹æ–‡ã‚¯ãƒ©ã‚¹ã‚¿ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "minimal "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "maximal "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; 該当 "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " å€‹ã®æ”¹è¡Œ"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: ã“ã®å ´æ‰€ã§ã¯å¼•æ•°containsã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: 無効ãªccharã®å€¤ã§ã™"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: ã“ã“ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¯è¨±å¯ã•れã¾ã›ã‚“"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: %s ã®ç¯„囲è¦ç´ ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: ファイルåãŒå¿…è¦ã§ã™"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: æ§‹æ–‡ã®å–り込ã¿(include)ãŒå¤šéŽãŽã¾ã™"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: ']' ãŒã‚りã¾ã›ã‚“: %s"
@@ -5832,221 +5496,171 @@ msgstr "E789: ']' ãŒã‚りã¾ã›ã‚“: %s"
msgid "E890: trailing char after ']': %s]%s"
msgstr "E890: ']' ã®å¾Œã‚ã«ä½™åˆ†ãªæ–‡å­—ãŒã‚りã¾ã™: %s]%s"
-#: ../syntax.c:4531
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: '=' ãŒã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: 引数ãŒè¶³ã‚Šã¾ã›ã‚“: 構文範囲 %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: 構文クラスタãŒå¤šéŽãŽã¾ã™"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: ã‚¯ãƒ©ã‚¹ã‚¿ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: パターン区切りãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: パターンã®ã‚ã¨ã«ã‚´ãƒŸãŒã‚りã¾ã™: %s"
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr "E403: æ§‹æ–‡åŒæœŸ: 連続行パターンãŒ2度指定ã•れã¾ã—ãŸ"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: 䏿­£ãªå¼•æ•°ã§ã™: %s"
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: ç­‰å·ãŒã‚りã¾ã›ã‚“: %s"
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: 空ã®å¼•æ•°: %s"
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s ã¯ã‚³ã‚³ã§ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s ã¯å†…容リストã®å…ˆé ­ã§ãªã‘れã°ãªã‚‰ãªã„"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: 未知ã®ã‚°ãƒ«ãƒ¼ãƒ—å: %s"
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: 無効㪠:syntax ã®ã‚µãƒ–コマンド: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-#: ../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: ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %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: グループãŒè¨­å®šã•れã¦ã„ã‚‹ã®ã§ãƒã‚¤ãƒ©ã‚¤ãƒˆãƒªãƒ³ã‚¯ã¯ç„¡è¦–ã•れã¾ã™"
-#: ../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: グループåã«å°åˆ·ä¸å¯èƒ½ãªæ–‡å­—ãŒã‚りã¾ã™"
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: グループåã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã™"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: ãƒã‚¤ãƒ©ã‚¤ãƒˆã¨æ§‹æ–‡ã‚°ãƒ«ãƒ¼ãƒ—ãŒå¤šéŽãŽã¾ã™"
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
msgstr "E555: ã‚¿ã‚°ã‚¹ã‚¿ãƒƒã‚¯ã®æœ«å°¾ã§ã™"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
msgstr "E556: タグスタックã®å…ˆé ­ã§ã™"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
-msgstr "E425: 最åˆã®è©²å½“ã‚¿ã‚°ã‚’è¶…ãˆã¦æˆ»ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+msgstr "E425: 最åˆã®è©²å½“ã‚¿ã‚°ã‚’è¶Šãˆã¦æˆ»ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
msgstr "E426: ã‚¿ã‚°ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: %s"
-#: ../tag.c:528
msgid " # pri kind tag"
msgstr " # pri kind tag"
-#: ../tag.c:531
msgid "file\n"
msgstr "ファイル\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
msgstr "E427: 該当タグãŒ1ã¤ã ã‘ã—ã‹ã‚りã¾ã›ã‚“"
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: 最後ã«è©²å½“ã™ã‚‹ã‚¿ã‚°ã‚’è¶…ãˆã¦é€²ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“"
+msgstr "E428: 最後ã®è©²å½“ã‚¿ã‚°ã‚’è¶Šãˆã¦é€²ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "ファイル \"%s\" ãŒã‚りã¾ã›ã‚“"
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
msgstr "ã‚¿ã‚° %d (å…¨%d%s)"
-#: ../tag.c:862
msgid " or more"
msgstr " ã‹ãれ以上"
-#: ../tag.c:864
msgid " Using tag with different case!"
msgstr " ã‚¿ã‚°ã‚’ç•°ãªã‚‹caseã§ä½¿ç”¨ã—ã¾ã™!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: ファイル \"%s\" ãŒã‚りã¾ã›ã‚“"
-#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
@@ -6054,79 +5668,64 @@ msgstr ""
"\n"
" # TO タグ FROM 行 in file/text"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "タグファイル %s を検索中"
-#: ../tag.c:1545
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: タグファイルã®ãƒ‘ス㌠%s ã«åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã—ãŸ\n"
+
msgid "Ignoring long line in tags file"
msgstr "タグファイル内ã®é•·ã„行を無視ã—ã¾ã™"
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: タグファイル \"%s\" ã®ãƒ•ォーマットã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™"
-#: ../tag.c:1917
#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "ç›´å‰ã® %<PRId64> ãƒã‚¤ãƒˆ"
+msgid "Before byte %ld"
+msgstr "ç›´å‰ã® %ld ãƒã‚¤ãƒˆ"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: タグファイルãŒã‚½ãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“: %s"
-#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: タグファイルãŒã‚りã¾ã›ã‚“"
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
msgstr "E434: タグパターンを見ã¤ã‘られã¾ã›ã‚“"
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
msgstr "E435: タグを見ã¤ã‘られãªã„ã®ã§å˜ã«æŽ¨æ¸¬ã—ã¾ã™!"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "é‡è¤‡ã—ãŸãƒ•ィールドå: %s"
-#: ../term.c:1442
msgid "' not known. Available builtin terminals are:"
msgstr "' ã¯æœªçŸ¥ã§ã™. ç¾è¡Œã®çµ„ã¿è¾¼ã¿ç«¯æœ«ã¯æ¬¡ã®ã¨ãŠã‚Šã§ã™:"
-#: ../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ã«ç«¯æœ«ã‚¨ãƒ³ãƒˆãƒªã‚’見ã¤ã‘られã¾ã›ã‚“"
-#: ../term.c:1878
#, c-format
msgid "E436: No \"%s\" entry in termcap"
msgstr "E436: termcapã« \"%s\" ã®ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“"
-#: ../term.c:2249
msgid "E437: terminal capability \"cm\" required"
msgstr "E437: 端末㫠\"cm\" 機能ãŒå¿…è¦ã§ã™"
-#. Highlight title
-#: ../term.c:4376
msgid ""
"\n"
"--- Terminal keys ---"
@@ -6134,168 +5733,363 @@ msgstr ""
"\n"
"--- 端末キー ---"
-#: ../ui.c:481
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "$VIMRUNTIME/rgb.txtã‚’é–‹ã‘ã¾ã›ã‚“"
+
+#, c-format
+msgid "Kill job in \"%s\"?"
+msgstr "\"%s\" 内ã®ã‚¸ãƒ§ãƒ–を終了ã—ã¾ã™ã‹?"
+
+msgid "Terminal"
+msgstr "端末"
+
+msgid "Terminal-finished"
+msgstr "端末 (終了)"
+
+msgid "active"
+msgstr "アクティブ"
+
+msgid "running"
+msgstr "実行中"
+
+msgid "finished"
+msgstr "終了"
+
+#, c-format
+msgid "E953: File exists: %s"
+msgstr "E953: ãƒ•ã‚¡ã‚¤ãƒ«ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™: %s"
+
+msgid "E955: Not a terminal buffer"
+msgstr "E955: 端末ãƒãƒƒãƒ•ã‚¡ã§ã¯ã‚りã¾ã›ã‚“"
+
+msgid "new shell started\n"
+msgstr "æ–°ã—ã„シェルを起動ã—ã¾ã™\n"
+
msgid "Vim: Error reading input, exiting...\n"
msgstr "Vim: 入力を読込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼ã«ã‚ˆã‚Šçµ‚了ã—ã¾ã™...\n"
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "空ã®é¸æŠžé ˜åŸŸã®ã‹ã‚りã«CUT_BUFFER0ãŒä½¿ç”¨ã•れã¾ã—ãŸ"
+
msgid "E881: Line count changed unexpectedly"
msgstr "E881: 予期ã›ãšè¡Œã‚«ã‚¦ãƒ³ãƒˆãŒå¤‰ã‚りã¾ã—ãŸ"
-#: ../undo.c:627
+msgid "No undo possible; continue anyway"
+msgstr "å¯èƒ½ãªã‚¢ãƒ³ãƒ‰ã‚¥ã¯ã‚りã¾ã›ã‚“: ã¨ã‚Šã‚ãˆãšç¶šã‘ã¾ã™"
+
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: 書込ã¿ç”¨ã«ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを開ã‘ã¾ã›ã‚“: %s"
-#: ../undo.c:717
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: アンドゥファイルãŒå£Šã‚Œã¦ã„ã¾ã™ (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr "'undodir'ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを書ãè¾¼ã‚ã¾ã›ã‚“"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "アンドゥファイルã¨ã—ã¦èª­ã¿è¾¼ã‚ãªã„ã®ã§ä¸Šæ›¸ãã—ã¾ã›ã‚“: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "アンドゥファイルã§ã¯ãªã„ã®ã§ä¸Šæ›¸ãã—ã¾ã›ã‚“: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "対象ãŒãªã„ã®ã§ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ãè¾¼ã¿ã‚’スキップã—ã¾ã™"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "アンドゥファイル書ãè¾¼ã¿ä¸­: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ãè¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "オーナーãŒç•°ãªã‚‹ã®ã§ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを読ã¿è¾¼ã¿ã¾ã›ã‚“: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "アンドゥファイル読込中: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: アンドゥファイルを読込用ã¨ã—ã¦é–‹ã‘ã¾ã›ã‚“: %s"
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: アンドゥファイルã§ã¯ã‚りã¾ã›ã‚“: %s"
-#: ../undo.c:1313
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr "E832: éžæš—å·åŒ–ãƒ•ã‚¡ã‚¤ãƒ«ãŒæš—å·åŒ–ã•れãŸã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを使ã£ã¦ã¾ã™: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: æš—å·åŒ–ã•れãŸã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルã®è§£èª­ã«å¤±æ•—ã—ã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ã‚¡ã‚¤ãƒ«ãŒæš—å·åŒ–ã•れã¦ã„ã¾ã™: %s"
+
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: äº’æ›æ€§ã®ç„¡ã„アンドゥファイルã§ã™: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr "ファイルã®å†…容ãŒå¤‰ã‚ã£ã¦ã„ã‚‹ãŸã‚ã€ã‚¢ãƒ³ãƒ‰ã‚¥æƒ…報を利用ã§ãã¾ã›ã‚“"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "アンドゥファイル %s ã®å–込を完了"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "æ—¢ã«ä¸€ç•ªå¤ã„変更ã§ã™"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "æ—¢ã«ä¸€ç•ªæ–°ã—ã„変更ã§ã™"
-#: ../undo.c:1806
#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: ã‚¢ãƒ³ãƒ‰ã‚¥ç•ªå· %<PRId64> ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+msgid "E830: Undo number %ld not found"
+msgstr "E830: ã‚¢ãƒ³ãƒ‰ã‚¥ç•ªå· %ld ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: 行番å·ãŒé–“é•ã£ã¦ã„ã¾ã™"
-#: ../undo.c:2183
msgid "more line"
msgstr "行 追加ã—ã¾ã—ãŸ"
-#: ../undo.c:2185
msgid "more lines"
msgstr "行 追加ã—ã¾ã—ãŸ"
-#: ../undo.c:2187
msgid "line less"
msgstr "行 削除ã—ã¾ã—ãŸ"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "行 削除ã—ã¾ã—ãŸ"
-#: ../undo.c:2193
msgid "change"
msgstr "箇所変更ã—ã¾ã—ãŸ"
-#: ../undo.c:2195
msgid "changes"
msgstr "箇所変更ã—ã¾ã—ãŸ"
-#: ../undo.c:2225
#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
-#: ../undo.c:2228
msgid "before"
msgstr "剿–¹"
-#: ../undo.c:2228
msgid "after"
msgstr "後方"
-#: ../undo.c:2325
msgid "Nothing to undo"
msgstr "アンドゥ対象ãŒã‚りã¾ã›ã‚“"
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "通番 変更数 変更時期 ä¿å­˜æ¸ˆ"
-#: ../undo.c:2360
#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> 秒経éŽã—ã¦ã„ã¾ã™"
+msgid "%ld seconds ago"
+msgstr "%ld 秒経éŽã—ã¦ã„ã¾ã™"
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: undo ã®ç›´å¾Œã« undojoin ã¯ã§ãã¾ã›ã‚“"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: アンドゥリストãŒå£Šã‚Œã¦ã„ã¾ã™"
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: アンドゥ行ãŒã‚りã¾ã›ã‚“"
-#: ../version.c:600
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: 関数 %s ã¯å®šç¾©æ¸ˆã§ã™ã€å†å®šç¾©ã™ã‚‹ã«ã¯ ! を追加ã—ã¦ãã ã•ã„"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: 辞書型内ã«ã‚¨ãƒ³ãƒˆãƒªãŒæ—¢ã«å­˜åœ¨ã—ã¾ã™"
+
+msgid "E718: Funcref required"
+msgstr "E718: 関数å‚ç…§åž‹ãŒè¦æ±‚ã•れã¾ã™"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: 未知ã®é–¢æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: 䏿­£ãªå¼•æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: 引数åãŒé‡è¤‡ã—ã¦ã„ã¾ã™: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: 関数ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™: %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: 関数ã®ç„¡åйãªå¼•æ•°ã§ã™: %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: 関数呼出ã®å…¥ã‚Œå­æ•°ãŒ 'maxfuncdepth' ã‚’è¶…ãˆã¾ã—ãŸ"
+
+#, c-format
+msgid "calling %s"
+msgstr "%s を実行中ã§ã™"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s ãŒä¸­æ–­ã•れã¾ã—ãŸ"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s ㌠#%ld ã‚’è¿”ã—ã¾ã—ãŸ"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s ㌠%s ã‚’è¿”ã—ã¾ã—ãŸ"
+
+msgid "E699: Too many arguments"
+msgstr "E699: 引数ãŒå¤šéŽãŽã¾ã™"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: 未知ã®é–¢æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: 関数ã¯å‰Šé™¤ã•れã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: 関数ã®å¼•æ•°ãŒè¶³ã‚Šã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: スクリプト以外ã§<SID>ãŒä½¿ã‚れã¾ã—ãŸ: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: 辞書用関数ãŒå‘¼ã°ã‚Œã¾ã—ãŸãŒè¾žæ›¸ãŒã‚りã¾ã›ã‚“: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: 関数åãŒè¦æ±‚ã•れã¾ã™"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: 関数åã¯å¤§æ–‡å­—ã‹ \"s:\" ã§å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: 関数åã«ã¯ã‚³ãƒ­ãƒ³ã¯å«ã‚られã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: 未定義ã®é–¢æ•°ã§ã™: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: '(' ãŒã‚りã¾ã›ã‚“: %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: ã“ã“ã§ã¯ g: ã¯ä½¿ãˆã¾ã›ã‚“"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: クロージャー関数ã¯ãƒˆãƒƒãƒ—レベルã«è¨˜è¿°ã§ãã¾ã›ã‚“: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: :endfunction ãŒã‚りã¾ã›ã‚“"
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: :endfunction ã®å¾Œã«æ–‡å­—ãŒã‚りã¾ã™: %s"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: 関数åãŒå¤‰æ•°åã¨è¡çªã—ã¾ã™: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: 関数 %s ã‚’å†å®šç¾©ã§ãã¾ã›ã‚“: 使用中ã§ã™"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: 関数åãŒã‚¹ã‚¯ãƒªãƒ—トã®ãƒ•ァイルåã¨ä¸€è‡´ã—ã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: 関数 %s を削除ã§ãã¾ã›ã‚“: 使用中ã§ã™"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: 関数外㫠:return ãŒã‚りã¾ã—ãŸ"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: カッコ '(' ãŒã‚りã¾ã›ã‚“: %s"
+
+#, c-format
+msgid "%s (%s, compiled %s)"
+msgstr "%s (%s, compiled %s)"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 64 ビット GUI 版"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32 ビット GUI 版"
+
+msgid " with OLE support"
+msgstr " with OLE サãƒãƒ¼ãƒˆ"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 64 ビット コンソール 版"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32 ビット コンソール 版"
+
+msgid ""
+"\n"
+"macOS version"
+msgstr ""
+"\n"
+"macOS 版"
+
+msgid ""
+"\n"
+"macOS version w/o darwin feat."
+msgstr ""
+"\n"
+"macOS 版 (darwin ç„¡ã—)"
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"OpenVMS 版"
+
msgid ""
"\n"
"Included patches: "
@@ -6303,7 +6097,6 @@ msgstr ""
"\n"
"é©ç”¨æ¸ˆãƒ‘ッãƒ: "
-#: ../version.c:627
msgid ""
"\n"
"Extra patches: "
@@ -6311,11 +6104,9 @@ msgstr ""
"\n"
"追加拡張パッãƒ: "
-#: ../version.c:639 ../version.c:864
msgid "Modified by "
msgstr "Modified by "
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6323,11 +6114,9 @@ msgstr ""
"\n"
"Compiled "
-#: ../version.c:649
msgid "by "
msgstr "by "
-#: ../version.c:660
msgid ""
"\n"
"Huge version "
@@ -6335,1886 +6124,950 @@ msgstr ""
"\n"
"Huge 版 "
-#: ../version.c:661
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Big 版 "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"通常 版 "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Small 版 "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Tiny 版 "
+
msgid "without GUI."
msgstr "without GUI."
-#: ../version.c:662
+msgid "with GTK3 GUI."
+msgstr "with GTK3 GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "with GTK2-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "with GTK2 GUI."
+
+msgid "with X11-Motif GUI."
+msgstr "with X11-Motif GUI."
+
+msgid "with X11-neXtaw GUI."
+msgstr "with X11-neXtaw GUI."
+
+msgid "with X11-Athena GUI."
+msgstr "with X11-Athena GUI."
+
+msgid "with Photon GUI."
+msgstr "with Photon GUI."
+
+msgid "with GUI."
+msgstr "with GUI."
+
+msgid "with Carbon GUI."
+msgstr "with Carbon GUI."
+
+msgid "with Cocoa GUI."
+msgstr "with Cocoa GUI."
+
msgid " Features included (+) or not (-):\n"
msgstr " 機能ã®ä¸€è¦§ 有効(+)/無効(-)\n"
-#: ../version.c:667
msgid " system vimrc file: \""
msgstr " システム vimrc: \""
-#: ../version.c:672
msgid " user vimrc file: \""
msgstr " ユーザー vimrc: \""
-#: ../version.c:677
msgid " 2nd user vimrc file: \""
msgstr " 第2ユーザー vimrc: \""
-#: ../version.c:682
msgid " 3rd user vimrc file: \""
msgstr " 第3ユーザー vimrc: \""
-#: ../version.c:687
msgid " user exrc file: \""
msgstr " ユーザー exrc: \""
-#: ../version.c:692
msgid " 2nd user exrc file: \""
msgstr " 第2ユーザー exrc: \""
-#: ../version.c:699
+msgid " system gvimrc file: \""
+msgstr " システム gvimrc: \""
+
+msgid " user gvimrc file: \""
+msgstr " ユーザー gvimrc: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr " 第2ユーザー gvimrc: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr " 第3ユーザー gvimrc: \""
+
+msgid " defaults file: \""
+msgstr " デフォルトファイル: \""
+
+msgid " system menu file: \""
+msgstr " システムメニュー: \""
+
msgid " fall-back for $VIM: \""
msgstr " çœç•¥æ™‚ã® $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr "çœç•¥æ™‚ã® $VIMRUNTIME: \""
-#: ../version.c:709
msgid "Compilation: "
msgstr "コンパイル: "
-#: ../version.c:712
+msgid "Compiler: "
+msgstr "コンパイラ: "
+
msgid "Linking: "
msgstr "リンク: "
-#: ../version.c:717
msgid " DEBUG BUILD"
msgstr "デãƒãƒƒã‚°ãƒ“ルド"
-#: ../version.c:767
msgid "VIM - Vi IMproved"
msgstr "VIM - Vi IMproved"
-#: ../version.c:769
msgid "version "
msgstr "version "
-#: ../version.c:770
msgid "by Bram Moolenaar et al."
msgstr "by Bram Moolenaar ä»–."
-#: ../version.c:774
msgid "Vim is open source and freely distributable"
msgstr "Vim ã¯ã‚ªãƒ¼ãƒ—ンソースã§ã‚り自由ã«é…布å¯èƒ½ã§ã™"
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "ã‚¦ã‚¬ãƒ³ãƒ€ã®æµã¾ã‚Œãªã„å­ä¾›ãŸã¡ã«æ´åŠ©ã‚’!"
-#: ../version.c:777
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> "
+msgid "type :help version8<Enter> for version info"
+msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報㯠:help version8<Enter> "
-#: ../version.c:784
msgid "Running in Vi compatible mode"
msgstr "Vi互æ›ãƒ¢ãƒ¼ãƒ‰ã§å‹•作中"
-#: ../version.c:785
msgid "type :set nocp<Enter> for Vim defaults"
msgstr "Vim推奨値ã«ã™ã‚‹ã«ã¯ :set nocp<Enter> "
-#: ../version.c:786
msgid "type :help cp-default<Enter> for info on this"
msgstr "è©³ç´°ãªæƒ…報㯠:help cp-default<Enter>"
-#: ../version.c:827
+msgid "menu Help->Orphans for information "
+msgstr "詳細ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã® ヘルプ->å­¤å… ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„ "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "モード無ã§å®Ÿè¡Œä¸­ã€‚タイプã—ãŸæ–‡å­—ãŒæŒ¿å…¥ã•れã¾ã™"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "メニュー㮠編集->全体設定->挿入(åˆå¿ƒè€…)モード切替 "
+
+msgid " for two modes "
+msgstr " ã§ãƒ¢ãƒ¼ãƒ‰æœ‰ã« "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "メニュー㮠編集->全体設定->Vi互æ›ãƒ¢ãƒ¼ãƒ‰åˆ‡æ›¿ "
+
+msgid " for Vim defaults "
+msgstr " ã§Vimã¨ã—ã¦å‹•作 "
+
msgid "Sponsor Vim development!"
msgstr "Vimã®é–‹ç™ºã‚’応æ´ã—ã¦ãã ã•ã„!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Vimã®ç™»éŒ²ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ãªã£ã¦ãã ã•ã„!"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
msgstr "è©³ç´°ãªæƒ…報㯠:help sponsor<Enter> "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
msgstr "è©³ç´°ãªæƒ…報㯠:help register<Enter> "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
msgstr "詳細ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã® ヘルプ->スãƒãƒ³ã‚µãƒ¼/登録 ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„"
-#: ../window.c:119
msgid "Already only one window"
msgstr "æ—¢ã«ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯1ã¤ã—ã‹ã‚りã¾ã›ã‚“"
-#: ../window.c:224
msgid "E441: There is no preview window"
msgstr "E441: プレビューウィンドウãŒã‚りã¾ã›ã‚“"
-#: ../window.c:559
msgid "E442: Can't split topleft and botright at the same time"
msgstr "E442: 左上ã¨å³ä¸‹ã‚’åŒæ™‚ã«åˆ†å‰²ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../window.c:1228
msgid "E443: Cannot rotate when another window is split"
msgstr "E443: ä»–ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒåˆ†å‰²ã•れã¦ã„る時ã«ã¯é †å›žã§ãã¾ã›ã‚“"
-#: ../window.c:1803
msgid "E444: Cannot close last window"
msgstr "E444: 最後ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‰ã˜ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#: ../window.c:1810
msgid "E813: Cannot close autocmd window"
msgstr "E813: autocmdウィンドウã¯é–‰ã˜ã‚‰ã‚Œã¾ã›ã‚“"
-#: ../window.c:1814
msgid "E814: Cannot close window, only autocmd window would remain"
msgstr "E814: autocmdウィンドウã—ã‹æ®‹ã‚‰ãªã„ãŸã‚ã€ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯é–‰ã˜ã‚‰ã‚Œã¾ã›ã‚“"
-#: ../window.c:2717
msgid "E445: Other window contains changes"
msgstr "E445: ä»–ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«ã¯å¤‰æ›´ãŒã‚りã¾ã™"
-#: ../window.c:4805
msgid "E446: No file name under cursor"
msgstr "E446: カーソルã®ä¸‹ã«ãƒ•ァイルåãŒã‚りã¾ã›ã‚“"
-msgid "List or number required"
-msgstr "ãƒªã‚¹ãƒˆã‹æ•°å€¤ãŒå¿…è¦ã§ã™"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() ãŒç©ºãƒ‘スワードã§å‘¼ã³å‡ºã•れã¾ã—ãŸ"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfishæš—å·ã®ãƒ“ッグ/リトルエンディアンãŒé–“é•ã£ã¦ã„ã¾ã™"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: sha256ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Blowfishæš—å·ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "Patch file"
-#~ msgstr "パッãƒãƒ•ァイル"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "決定(&O)\n"
-#~ "キャンセル(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Vim サーãƒã¸ã®æŽ¥ç¶šãŒã‚りã¾ã›ã‚“"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: %s ã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: サーãƒã®å¿œç­”ãŒã‚りã¾ã›ã‚“"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: クライアントã¸é€ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“"
-
-#~ msgid "Save As"
-#~ msgstr "別åã§ä¿å­˜"
-
-#~ msgid "Edit File"
-#~ msgstr "ファイルを編集"
-
-# Added at 27-Jan-2004.
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (見ã¤ã‹ã‚Šã¾ã›ã‚“)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Vimスクリプトã®å–è¾¼ã¿"
-
-#~ msgid "unknown"
-#~ msgstr "䏿˜Ž"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "æ–°ã—ã„ウィンドウã§ãƒ•ァイルを編集ã—ã¾ã™"
-
-#~ msgid "Append File"
-#~ msgstr "追加ファイル"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "ウィンドウä½ç½®: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "リダイレクトをä¿å­˜ã—ã¾ã™"
-
-#~ msgid "Save View"
-#~ msgstr "ビューをä¿å­˜ã—ã¾ã™"
-
-#~ msgid "Save Session"
-#~ msgstr "セッション情報をä¿å­˜ã—ã¾ã™"
-
-#~ msgid "Save Setup"
-#~ msgstr "設定をä¿å­˜ã—ã¾ã™"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< 㯠+eval 機能ãŒç„¡ã„ã¨åˆ©ç”¨ã§ãã¾ã›ã‚“"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«åˆå­—ã¯ã‚りã¾ã›ã‚“"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr " ã¯ãƒ‡ãƒã‚¤ã‚¹ã§ã™ ('opendevice' オプションã§å›žé¿ã§ãã¾ã™)"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "標準入力ã‹ã‚‰èª­è¾¼ã¿ä¸­..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfishæš—å·åŒ–]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[æš—å·åŒ–]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: ãƒ•ã‚¡ã‚¤ãƒ«ãŒæœªçŸ¥ã®æ–¹æ³•ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
-
-# Added at 19-Jan-2004.
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeansã¯æœªå¤‰æ›´ã®ãƒãƒƒãƒ•ァを上書ã™ã‚‹ã“ã¨ã¯è¨±å¯ã—ã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeansãƒãƒƒãƒ•ã‚¡ã®ä¸€éƒ¨ã‚’書ã出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "'opendevice' オプションã«ã‚ˆã‚Šãƒ‡ãƒã‚¤ã‚¹ã¸ã®æ›¸ãè¾¼ã¿ã¯ã§ãã¾ã›ã‚“"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: リソースフォークãŒå¤±ã‚れるã‹ã‚‚ã—れã¾ã›ã‚“ (! を追加ã§å¼·åˆ¶)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: GUI用ã®ãƒ—ロセスã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: å­ãƒ—ロセスãŒGUIã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: \"%s\"ã‹ã‚‰èª­è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“"
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: 有効ãªãƒ•ォントãŒè¦‹ã¤ã‹ã‚‰ãªã„ã®ã§, GUIã‚’é–‹å§‹ã§ãã¾ã›ã‚“"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' ãŒç„¡åйã§ã™"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' ã«è¨­å®šã•れãŸå€¤ãŒç„¡åйã§ã™"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: %s ã®è‰²ã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "カーソルã®ä½ç½®ã«ãƒžãƒƒãƒã¯ã‚りã¾ã›ã‚“, 次を検索ã—ã¦ã„ã¾ã™"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<é–‹ã‘ã¾ã›ã‚“> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: フォント %s ã‚’å–å¾—ã§ãã¾ã›ã‚“"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æˆ»ã‚Œã¾ã›ã‚“"
-
-#~ msgid "Pathname:"
-#~ msgstr "パスå:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“"
-
-#~ msgid "OK"
-#~ msgstr "OK"
-
-#~ msgid "Cancel"
-#~ msgstr "キャンセル"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "スクロールãƒãƒ¼: ç”»åƒã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ."
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim ダイアログ"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: メッセージã¨ã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã®ã‚ã‚‹ BalloonEval を作æˆã§ãã¾ã›ã‚“"
-
-#~ msgid "Input _Methods"
-#~ msgstr "インプットメソッド"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - 検索ã¨ç½®æ›..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - 検索..."
-
-#~ msgid "Find what:"
-#~ msgstr "検索文字列:"
-
-#~ msgid "Replace with:"
-#~ msgstr "ç½®æ›æ–‡å­—列:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "正確ã«è©²å½“ã™ã‚‹ã‚‚ã®ã ã‘"
-
-#~ msgid "Match case"
-#~ msgstr "大文字/å°æ–‡å­—を区別ã™ã‚‹"
-
-#~ msgid "Direction"
-#~ msgstr "æ–¹å‘"
-
-#~ msgid "Up"
-#~ msgstr "上"
-
-#~ msgid "Down"
-#~ msgstr "下"
-
-#~ msgid "Find Next"
-#~ msgstr "次を検索"
-
-#~ msgid "Replace"
-#~ msgstr "ç½®æ›"
-
-#~ msgid "Replace All"
-#~ msgstr "å…¨ã¦ç½®æ›"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: セッションマãƒãƒ¼ã‚¸ãƒ£ã‹ã‚‰ \"die\" è¦æ±‚ã‚’å—ã‘å–りã¾ã—ãŸ\n"
-
-#~ msgid "Close"
-#~ msgstr "é–‰ã˜ã‚‹"
-
-#~ msgid "New tab"
-#~ msgstr "æ–°è¦ã‚¿ãƒ–ページ"
-
-#~ msgid "Open Tab..."
-#~ msgstr "タブページを開ã..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: メインウィンドウãŒä¸æ„ã«ç ´å£Šã•れã¾ã—ãŸ\n"
-
-#~ msgid "&Filter"
-#~ msgstr "フィルタ(&F)"
-
-#~ msgid "&Cancel"
-#~ msgstr "キャンセル(&C)"
-
-#~ msgid "Directories"
-#~ msgstr "ディレクトリ"
-
-#~ msgid "Filter"
-#~ msgstr "フィルタ"
-
-#~ msgid "&Help"
-#~ msgstr "ヘルプ(&H)"
-
-#~ msgid "Files"
-#~ msgstr "ファイル"
-
-#~ msgid "&OK"
-#~ msgstr "&OK"
-
-#~ msgid "Selection"
-#~ msgstr "é¸æŠž"
-
-#~ msgid "Find &Next"
-#~ msgstr "次を検索(&N)"
-
-#~ msgid "&Replace"
-#~ msgstr "ç½®æ›(&R)"
-
-#~ msgid "Replace &All"
-#~ msgstr "å…¨ã¦ç½®æ›(&A)"
-
-#~ msgid "&Undo"
-#~ msgstr "アンドゥ(&U)"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: タイトル㌠\"%s\" ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: 引数ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“: \"-%s\"; OLE版を使用ã—ã¦ãã ã•ã„."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: MDIアプリã®ä¸­ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’é–‹ã‘ã¾ã›ã‚“"
-
-#~ msgid "Close tab"
-#~ msgstr "タブページを閉ã˜ã‚‹"
-
-#~ msgid "Open tab..."
-#~ msgstr "タブページを開ã"
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "検索文字列 ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "æ¤œç´¢ãƒ»ç½®æ› ('\\' を検索ã™ã‚‹ã«ã¯ '\\\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "使ã‚れã¾ã›ã‚“"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "ディレクトリ\t*.nothing\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: è‰²æŒ‡å®šãŒæ­£ã—ããªã„ã®ã§ã‚¨ãƒ³ãƒˆãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: ä»¥ä¸‹ã®æ–‡å­—セットã®ãƒ•ォントãŒã‚りã¾ã›ã‚“ %s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: フォントセットå: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "フォント '%s' ã¯å›ºå®šå¹…ã§ã¯ã‚りã¾ã›ã‚“"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: フォントセットå: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "フォント0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "フォント1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "フォント%<PRId64> ã®å¹…ãŒãƒ•ォント0ã®2å€ã§ã¯ã‚りã¾ã›ã‚“"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "フォント0ã®å¹…: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "フォント1ã®å¹…: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "無効ãªãƒ•ォント指定ã§ã™"
-
-#~ msgid "&Dismiss"
-#~ msgstr "å´ä¸‹ã™ã‚‹(&D)"
-
-#~ msgid "no specific match"
-#~ msgstr "マッãƒã™ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - ãƒ•ã‚©ãƒ³ãƒˆé¸æŠž"
-
-#~ msgid "Name:"
-#~ msgstr "åå‰:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "サイズをãƒã‚¤ãƒ³ãƒˆã§è¡¨ç¤ºã™ã‚‹"
-
-#~ msgid "Encoding:"
-#~ msgstr "エンコード:"
-
-#~ msgid "Font:"
-#~ msgstr "フォント:"
-
-#~ msgid "Style:"
-#~ msgstr "スタイル:"
-
-#~ msgid "Size:"
-#~ msgstr "サイズ:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ãƒãƒ³ã‚°ãƒ«ã‚ªãƒ¼ãƒˆãƒžãƒˆãƒ³ã‚¨ãƒ©ãƒ¼"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat エラー"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: cscopeデータベース: %s ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: cscopeãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æƒ…報をå–å¾—ã§ãã¾ã›ã‚“"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Luaライブラリをロードã§ãã¾ã›ã‚“."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "アンドゥ情報ãŒä¿å­˜ã§ãã¾ã›ã‚“"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™. MzScheme ライブラリをロードã§ãã¾ã›ã‚“."
-
-#~ msgid "invalid expression"
-#~ msgstr "無効ãªå¼ã§ã™"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "å¼ã¯ã‚³ãƒ³ãƒ‘イル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™"
-
-#~ msgid "hidden option"
-#~ msgstr "éš ã—オプション"
-
-#~ msgid "unknown option"
-#~ msgstr "未知ã®ã‚ªãƒ—ションã§ã™"
-
-#~ msgid "window index is out of range"
-#~ msgstr "範囲外ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ç•ªå·ã§ã™"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "ãƒãƒƒãƒ•ã‚¡ã‚’é–‹ã‘ã¾ã›ã‚“"
-
-#~ msgid "cannot delete line"
-#~ msgstr "行を消ã›ã¾ã›ã‚“"
-
-#~ msgid "cannot replace line"
-#~ msgstr "行を置æ›ã§ãã¾ã›ã‚“"
-
-#~ msgid "cannot insert line"
-#~ msgstr "行を挿入ã§ãã¾ã›ã‚“"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "文字列ã«ã¯æ”¹è¡Œæ–‡å­—ã‚’å«ã‚られã¾ã›ã‚“"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "Scheme値ã®Vimã¸ã®å¤‰æ›ã‚¨ãƒ©ãƒ¼"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim エラー: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Vim エラー"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "ãƒãƒƒãƒ•ã‚¡ã¯ç„¡åйã§ã™"
-
-#~ msgid "window is invalid"
-#~ msgstr "ウィンドウã¯ç„¡åйã§ã™"
-
-#~ msgid "linenr out of range"
-#~ msgstr "範囲外ã®è¡Œç•ªå·ã§ã™"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: ライブラリ %s をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™, ã”ã‚ã‚“ãªã•ã„: Perlライブラリをロードã§ãã¾ã›ã‚“ã§ã—"
-#~ "ãŸ."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: サンドボックスã§ã¯ Safe モジュールを使用ã—ãªã„Perlスクリプトã¯ç¦ã˜ã‚‰"
-#~ "れã¦ã„ã¾ã™"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: ã“ã®Vimã§ã¯ :py3 を使ã£ãŸå¾Œã« :python を使ãˆã¾ã›ã‚“"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Pythonライブラリをロードã§ãã¾"
-#~ "ã›ã‚“ã§ã—ãŸ."
-
-# Added at 07-Feb-2004.
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Python ã‚’å†å¸°çš„ã«å®Ÿè¡Œã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: ã“ã®Vimã§ã¯ :python を使ã£ãŸå¾Œã« :py3 を使ãˆã¾ã›ã‚“"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ ã¯æ–‡å­—列ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡åйã§ã™,ã”ã‚ã‚“ãªã•ã„: Rubyライブラリをロードã§ãã¾ã›"
-#~ "ã‚“ã§ã—ãŸ."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: 予期ã›ã¬ return ã§ã™"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: 予期ã›ã¬ next ã§ã™"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: 予期ã›ã¬ break ã§ã™"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: 予期ã›ã¬ redo ã§ã™"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: rescue ã®å¤–ã® retry ã§ã™"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: å–り扱ã‚れãªã‹ã£ãŸä¾‹å¤–ãŒã‚りã¾ã™"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: 未知ã®longjmp状態: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "実装ã¨å®šç¾©ã‚’切り替ãˆã‚‹"
-
-#~ msgid "Show base class of"
-#~ msgstr "次ã®ã‚¯ãƒ©ã‚¹ã®åŸºåº•を表示"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã•れãŸãƒ¡ãƒ³ãƒé–¢æ•°ã‚’表示"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "ファイルã‹ã‚‰å›žå¾©ã™ã‚‹"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "プロジェクトã‹ã‚‰å›žå¾©ã™ã‚‹"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "å…¨ã¦ã®ãƒ—ロジェクトã‹ã‚‰å›žå¾©ã™ã‚‹"
-
-#~ msgid "Retrieve"
-#~ msgstr "回復"
-
-#~ msgid "Show source of"
-#~ msgstr "次ã®ã‚½ãƒ¼ã‚¹ã‚’表示ã™ã‚‹"
-
-#~ msgid "Find symbol"
-#~ msgstr "見ã¤ã‘ãŸã‚·ãƒ³ãƒœãƒ«"
-
-#~ msgid "Browse class"
-#~ msgstr "クラスをå‚ç…§"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "階層ã§ã‚¯ãƒ©ã‚¹ã‚’表示"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "é™å®šã•れãŸéšŽå±¤ã§ã‚¯ãƒ©ã‚¹ã‚’表示"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ã®å‚ç…§å…ˆ"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ãŒå‚ç…§ã•れる"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ãŒæ¬¡ã®ã‚‚ã®ã‚’ã‚‚ã£ã¦ã„ã¾ã™"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref ãŒä½¿ç”¨ã•れる"
-
-#~ msgid "Show docu of"
-#~ msgstr "æ¬¡ã®æ–‡ç« ã‚’表示"
-
-#~ msgid "Generate docu for"
-#~ msgstr "æ¬¡ã®æ–‡ç« ã‚’生æˆ"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "SNiFF+ã«æŽ¥ç¶šã§ãã¾ã›ã‚“. 環境をãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„(sniffemacs ㌠$PATH ã«"
-#~ "ãªã‘れã°ãªã‚Šã¾ã›ã‚“).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: 読込中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ. 切断ã—ã¾ã—ãŸ"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "ç¾åœ¨SNiFF+ ã®çŠ¶æ…‹ã¯ã€Œ"
-
-#~ msgid "not "
-#~ msgstr "未"
-
-#~ msgid "connected"
-#~ msgstr "接続ã€ã§ã™"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: 未知㮠SNiFF+ リクエストã§ã™: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: SNiFF+ ã¸ã®æŽ¥ç¶šä¸­ã®ã‚¨ãƒ©ãƒ¼ã§ã™"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ã«æŽ¥ç¶šã•れã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: SNiFF+ ãƒãƒƒãƒ•ã‚¡ãŒã‚りã¾ã›ã‚“"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: 書込ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ãŸã®ã§åˆ‡æ–­ã—ã¾ã—ãŸ"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "無効ãªãƒãƒƒãƒ•ァ番å·ã§ã™"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "行を設定ã§ãã¾ã›ã‚“"
-
-#~ msgid "invalid mark name"
-#~ msgstr "無効ãªãƒžãƒ¼ã‚¯åã§ã™"
-
-#~ msgid "mark not set"
-#~ msgstr "マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "row %d column %d"
-#~ msgstr "行 %d 列 %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "è¡Œã®æŒ¿å…¥/追加をã§ãã¾ã›ã‚“"
-
-#~ msgid "line number out of range"
-#~ msgstr "範囲外ã®è¡Œç•ªå·ã§ã™"
-
-#~ msgid "unknown flag: "
-#~ msgstr "未知ã®ãƒ•ラグ: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "未知㮠vimOption ã§ã™"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "キーボード割込ã¿"
-
-#~ msgid "vim error"
-#~ msgstr "vim エラー"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "ãƒãƒƒãƒ•ã‚¡/ウィンドウ作æˆã‚³ãƒžãƒ³ãƒ‰ã‚’作æˆã§ãã¾ã›ã‚“: ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæ¶ˆåŽ»ã•れã¦"
-#~ "ã„ã¾ã—ãŸ"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒæ—¢ã«æ¶ˆåŽ»ã•れã¾"
-#~ "ã—ãŸ"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL 致命的エラー: reflist 汚染!? vim-dev@vim.org ã«å ±å‘Šã—ã¦ãã ã•ã„"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "コールãƒãƒƒã‚¯ã‚³ãƒžãƒ³ãƒ‰ã‚’登録ã§ãã¾ã›ã‚“: ãƒãƒƒãƒ•ã‚¡/ウィンドウã®å‚ç…§ãŒè¦‹ã¤ã‹ã‚Š"
-#~ "ã¾ã›ã‚“"
-
-#~ 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 "cannot get line"
-#~ msgstr "行をå–å¾—ã§ãã¾ã›ã‚“"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "命令サーãƒã®åå‰ã‚’登録ã§ãã¾ã›ã‚“"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: 目的ã®ãƒ—ログラムã¸ã®ã‚³ãƒžãƒ³ãƒ‰é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: 無効ãªã‚µãƒ¼ãƒIDãŒä½¿ã‚れã¾ã—ãŸ: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM 実体ã®ç™»éŒ²ãƒ—ロパティãŒä¸æ­£ã§ã™. 消去ã—ã¾ã—ãŸ!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ã¯ã“ã®GUIã§ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "ã“ã®Vimã«ã¯diff機能ãŒã‚りã¾ã›ã‚“(コンパイル時設定)."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' 使用ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: エラー: NetBeansã‹ã‚‰gvimをスタートã§ãã¾ã›ã‚“\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "大尿–‡å­—ãŒç„¡è¦–ã•れる場åˆã¯å¤§æ–‡å­—ã«ã™ã‚‹ãŸã‚ã« / ã‚’å‰ç½®ã—ã¦ãã ã•ã„"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tã“ã®gvimã‚’OLEã¨ã—ã¦ç™»éŒ²ã™ã‚‹"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tgvimã®OLE登録を解除ã™ã‚‹"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tGUIã§èµ·å‹•ã™ã‚‹ (\"gvim\" ã¨åŒã˜)"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f or --nofork\tフォアグラウンド: GUIã‚’å§‹ã‚ã‚‹ã¨ãã«forkã—ãªã„"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tウィンドウを開ãã®ã« newcli を使用ã—ãªã„"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tI/Oã« <device> を使用ã™ã‚‹"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\t.gvimrcã®ä»£ã‚り㫠<gvimrc> を使ã†"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tæš—å·åŒ–ã•れãŸãƒ•ァイルを編集ã™ã‚‹"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tvimを指定ã—㟠X サーãƒã«æŽ¥ç¶šã™ã‚‹"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tXサーãƒã«æŽ¥ç¶šã—ãªã„"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\tå¯èƒ½ãªã‚‰ã°Vimサーãƒã§ <files> を編集ã™ã‚‹"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> åŒä¸Š, サーãƒãŒç„¡ãã¦ã‚‚警告文を出力ã—ãªã„"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr "--remote-wait <files>\t--remote後 ファイルã®ç·¨é›†ãŒçµ‚ã‚ã‚‹ã®ã‚’å¾…ã¤"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <files> åŒä¸Š, サーãƒãŒç„¡ãã¦ã‚‚警告文を出力ã—ãªã„"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <files> --remoteã§ãƒ•ァイル1ã¤ã«ã¤ã1ã¤ã®ã‚¿ãƒ–"
-#~ "ページを開ã"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\tVimサーãƒã« <keys> ã‚’é€ä¿¡ã—ã¦çµ‚了ã™ã‚‹"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\tサーãƒã§ <expr> を実行ã—ã¦çµæžœã‚’表示ã™ã‚‹"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tVimサーãƒåã®ä¸€è¦§ã‚’表示ã—ã¦çµ‚了ã™ã‚‹"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <name>\tVimサーム<name> ã«é€ä¿¡/åå‰è¨­å®šã™ã‚‹"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(Motifãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(neXtawãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(Athenaãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\t<display> ã§vimを実行ã™ã‚‹"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\t最å°åŒ–ã—ãŸçŠ¶æ…‹ã§vimã‚’èµ·å‹•ã™ã‚‹"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\t背景色㫠<color> を使ã†(åŒç¾©: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\t剿™¯è‰²ã« <color> を使ã†(åŒç¾©: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\tテキスト表示㫠<font> を使ã†(åŒç¾©: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\t太字㫠<font> を使ã†"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <for>\t斜体字㫠<font> を使ã†"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\tåˆæœŸé…置㫠<geom> を使ã†(åŒç¾©: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\t境界ã®å¹…ã‚’ <width> ã«ã™ã‚‹(åŒç¾©: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <width> スクロールãƒãƒ¼ã®å¹…ã‚’ <width> ã«ã™ã‚‹(åŒç¾©: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <height>\tメニューãƒãƒ¼ã®é«˜ã•ã‚’ <height> ã«ã™ã‚‹(åŒç¾©: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tå転映åƒã‚’使用ã™ã‚‹(åŒç¾©: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tå転映åƒã‚’使用ã—ãªã„(åŒç¾©: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\t特定ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’使用ã™ã‚‹"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimã«ã‚ˆã£ã¦è§£é‡ˆã•れる引数(GTK+ãƒãƒ¼ã‚¸ãƒ§ãƒ³):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\t<display> ã§vimを実行ã™ã‚‹(åŒç¾©: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\tメインウィンドウを識別ã™ã‚‹ä¸€æ„ãªå½¹å‰²(role)を設定ã™ã‚‹"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tç•°ãªã‚‹GTK widgetã§Vimã‚’é–‹ã"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tウィンドウIDを標準出力ã«å‡ºåŠ›ã™ã‚‹"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <親ã®ã‚¿ã‚¤ãƒˆãƒ«>\tVimを親アプリケーションã®ä¸­ã§èµ·å‹•ã™ã‚‹"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tç•°ãªã‚‹Win32 widgetã®å†…部ã«Vimã‚’é–‹ã"
-
-#~ msgid "No display"
-#~ msgstr "ディスプレイãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ. ローカルã§ã®å®Ÿè¡Œã‚’試ã¿ã¦ã„ã¾ã™\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d 個 (%d 個中) ã®ãƒ•ァイルを編集ã—ã¾ã—ãŸ"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "ディスプレイãŒã‚りã¾ã›ã‚“: å¼ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": å¼ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: 無効ãªã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¸ã§ã™"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: ICã®å€¤ã‚’設定ã§ãã¾ã›ã‚“"
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: pathã«ã¯ \"%s\" ã¨ã„ã†ãƒ•ァイルãŒã‚りã¾ã›ã‚“"
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: インプットコンテキストã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸ"
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: 無効㪠ID: %ld (1 以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“)"
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: インプットメソッドã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ"
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ID ã¯ã™ã§ã«åˆ©ç”¨ä¸­ã§ã™: %ld"
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: 警告: IMã®ç ´å£Šã‚³ãƒ¼ãƒ«ãƒãƒƒã‚¯ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+msgid "List or number required"
+msgstr "ãƒªã‚¹ãƒˆã‹æ•°å€¤ãŒå¿…è¦ã§ã™"
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: インプットメソッドã¯ã©ã‚“ãªã‚¹ã‚¿ã‚¤ãƒ«ã‚‚サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: 無効㪠ID: %ld (1 以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“)"
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: インプットメソッド㯠my preedit type をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“"
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ID ã¯ã‚りã¾ã›ã‚“: %ld"
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã®æš—å·ã‚’更新中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+msgid "Edit with &multiple Vims"
+msgstr "複数ã®Vimã§ç·¨é›†ã™ã‚‹ (&M)"
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr ""
-#~ "E833: %s ã¯ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®Vimã§ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„å½¢å¼ã§æš—å·åŒ–ã•れã¦ã„ã¾ã™"
+msgid "Edit with single &Vim"
+msgstr "1ã¤ã®Vimã§ç·¨é›†ã™ã‚‹ (&V)"
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "ã‚¹ãƒ¯ãƒƒãƒ—ãƒ•ã‚¡ã‚¤ãƒ«ã¯æš—å·åŒ–ã•れã¦ã„ã¾ã™: \"%s\""
+msgid "Diff with Vim"
+msgstr "Vimã§å·®åˆ†ã‚’表示ã™ã‚‹"
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "æ–°ã—ã„æš—å·ã‚­ãƒ¼ã‚’入力ã—ãŸã‚ã¨ã«ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルをä¿å­˜ã—ã¦ã„ãªã„å ´åˆã¯,"
+msgid "Edit with &Vim"
+msgstr "Vimã§ç·¨é›†ã™ã‚‹ (&V)"
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "æ–°ã—ã„æš—å·ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„."
+msgid "Edit with existing Vim - "
+msgstr "起動済ã®Vimã§ç·¨é›†ã™ã‚‹ - "
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "æš—å·ã‚­ãƒ¼ã‚’変ãˆãŸã‚ã¨ã«ãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルをä¿å­˜ã—ãŸå ´åˆã¯, テキストファイルã¨"
+msgid "Edits the selected file(s) with Vim"
+msgstr "é¸æŠžã—ãŸãƒ•ァイルをVimã§ç·¨é›†ã™ã‚‹"
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "スワップファイルã«åŒã˜æš—å·ã‚­ãƒ¼ã‚’使ã†ãŸã‚ã«enterã ã‘を押ã—ã¦ãã ã•ã„."
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr "プロセスã®ä½œæˆã«å¤±æ•—: gvimãŒç’°å¢ƒå¤‰æ•°PATH上ã«ã‚ã‚‹ã‹ç¢ºèªã—ã¦ãã ã•ã„!"
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "スワップファイルã‹ã‚‰å–å¾—ã—ãŸæš—å·ã‚­ãƒ¼ã‚’テキストファイルã«ä½¿ã„ã¾ã™.\n"
+msgid "gvimext.dll error"
+msgstr "gvimext.dll エラー"
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [ã“ã®Vimãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“]"
+msgid "Path length too long!"
+msgstr "パスãŒé•·éŽãŽã¾ã™!"
-#~ msgid "Tear off this menu"
-#~ msgstr "ã“ã®ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‚’切りå–ã‚‹"
+msgid "--No lines in buffer--"
+msgstr "--ãƒãƒƒãƒ•ã‚¡ã«è¡ŒãŒã‚りã¾ã›ã‚“--"
-#~ msgid "Select Directory dialog"
-#~ msgstr "ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªé¸æŠžãƒ€ã‚¤ã‚¢ãƒ­ã‚°"
+msgid "E470: Command aborted"
+msgstr "E470: コマンドãŒä¸­æ–­ã•れã¾ã—ãŸ"
-#~ msgid "Save File dialog"
-#~ msgstr "ファイルä¿å­˜ãƒ€ã‚¤ã‚¢ãƒ­ã‚°"
+msgid "E471: Argument required"
+msgstr "E471: 引数ãŒå¿…è¦ã§ã™"
-#~ msgid "Open File dialog"
-#~ msgstr "ファイル読込ダイアログ"
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: \\ ã®å¾Œã¯ / ã‹ ? ã‹ & ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr ""
-#~ "E338: コンソールモードã§ã¯ãƒ•ァイルブラウザを使ãˆã¾ã›ã‚“, ã”ã‚ã‚“ãªã•ã„"
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr "E11: コマンドラインã§ã¯ç„¡åйã§ã™; <CR>ã§å®Ÿè¡Œ, CTRL-Cã§ã‚„ã‚ã‚‹"
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: ファイルをä¿å­˜ä¸­...\n"
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚„タグ検索ã§ã¯exrc/vimrcã®ã‚³ãƒžãƒ³ãƒ‰ã¯è¨±å¯ã•れã¾ã›ã‚“"
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: 終了ã—ã¾ã—ãŸ.\n"
+msgid "E171: Missing :endif"
+msgstr "E171: :endif ãŒã‚りã¾ã›ã‚“"
-#~ msgid "ERROR: "
-#~ msgstr "エラー: "
+msgid "E600: Missing :endtry"
+msgstr "E600: :endtry ãŒã‚りã¾ã›ã‚“"
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[メモリ(ãƒã‚¤ãƒˆ)] ç·å‰²å½“-è§£æ”¾é‡ %<PRIu64>-%<PRIu64>, ä½¿ç”¨é‡ %<PRIu64>, ピー"
-#~ "ク時 %<PRIu64>\n"
+msgid "E170: Missing :endwhile"
+msgstr "E170: :endwhile ãŒã‚りã¾ã›ã‚“"
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[呼出] ç· re/malloc() 回数 %<PRIu64>, ç· free() 回数 %<PRIu64>\n"
-#~ "\n"
+msgid "E170: Missing :endfor"
+msgstr "E170: :endfor ãŒã‚りã¾ã›ã‚“"
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: 行ãŒé•·ããªã‚ŠéŽãŽã¾ã—ãŸ"
+msgid "E588: :endwhile without :while"
+msgstr "E588: :while ã®ãªã„ :endwhile ãŒã‚りã¾ã™"
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: 内部エラー: lalloc(%<PRId64>,)"
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor ã®ãªã„ :for ãŒã‚りã¾ã™"
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: 䏿­£ãª 'mouseshape' ã§ã™"
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: ファイルãŒå­˜åœ¨ã—ã¾ã™ (! を追加ã§ä¸Šæ›¸)"
-#~ msgid "Enter encryption key: "
-#~ msgstr "æš—å·åŒ–用ã®ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+msgid "E472: Command failed"
+msgstr "E472: コマンドãŒå¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "Enter same key again: "
-#~ msgstr "ã‚‚ã†ä¸€åº¦åŒã˜ã‚­ãƒ¼ã‚’入力ã—ã¦ãã ã•ã„: "
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: 未知ã®ãƒ•ォントセット: %s"
-#~ msgid "Keys don't match!"
-#~ msgstr "キーãŒä¸€è‡´ã—ã¾ã›ã‚“"
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: 未知ã®ãƒ•ォント: %s"
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Netbeans #2 ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: フォント \"%s\" ã¯å›ºå®šå¹…ã§ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Netbeans ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
+msgid "E473: Internal error"
+msgstr "E473: 内部エラーã§ã™"
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: NetBeansã®æŽ¥ç¶šæƒ…å ±ãƒ•ã‚¡ã‚¤ãƒ«ã®ã‚¢ã‚¯ã‚»ã‚¹ãƒ¢ãƒ¼ãƒ‰ã«å•題ãŒã‚りã¾ã™: \"%s\""
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: 内部エラーã§ã™: %s"
-#~ msgid "read from Netbeans socket"
-#~ msgstr "Netbeans ã®ã‚½ã‚±ãƒƒãƒˆã‚’読込ã¿"
+msgid "Interrupted"
+msgstr "割込ã¾ã‚Œã¾ã—ãŸ"
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: ãƒãƒƒãƒ•ã‚¡ %<PRId64> ã® NetBeans 接続ãŒå¤±ã‚れã¾ã—ãŸ"
+msgid "E14: Invalid address"
+msgstr "E14: 無効ãªã‚¢ãƒ‰ãƒ¬ã‚¹ã§ã™"
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: NetBeansã¯ã“ã®GUIã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“"
+msgid "E474: Invalid argument"
+msgstr "E474: 無効ãªå¼•æ•°ã§ã™"
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: NetBeansã¯æ—¢ã«æŽ¥ç¶šã—ã¦ã„ã¾ã™"
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: 無効ãªå¼•æ•°ã§ã™: %s"
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s ã¯èª­è¾¼å°‚用ã§ã™ (強制書込ã«ã¯ ! を追加)"
+#, c-format
+msgid "E475: Invalid value for argument %s"
+msgstr "E475: 引数 %s ã«å¯¾ã—ã¦ç„¡åйãªå€¤ã§ã™"
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: å¼è©•価機能ãŒç„¡åйã«ãªã£ã¦ã„ã¾ã™"
+#, c-format
+msgid "E475: Invalid value for argument %s: %s"
+msgstr "E475: 引数 %s ã«å¯¾ã—ã¦ç„¡åйãªå€¤ã§ã™: %s"
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "%<PRId64> 行を解放中"
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: 無効ãªå¼ã§ã™: %s"
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: GUIã§ã¯ 'term' を変更ã§ãã¾ã›ã‚“"
+msgid "E16: Invalid range"
+msgstr "E16: 無効ãªç¯„囲ã§ã™"
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: GUIをスタートã™ã‚‹ã«ã¯ \":gui\" を使用ã—ã¦ãã ã•ã„"
+msgid "E476: Invalid command"
+msgstr "E476: 無効ãªã‚³ãƒžãƒ³ãƒ‰ã§ã™"
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: GTK+2 GUIã§ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™"
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: 無効ãªãƒ•ォントã§ã™"
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: \"%s\"() ã®ãƒ©ã‚¤ãƒ–ラリ呼出ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ãƒ•ã‚©ãƒ³ãƒˆã‚»ãƒƒãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+msgid "E667: Fsync failed"
+msgstr "E667: fsync ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: 無効ãªãƒ•ォントセットã§ã™"
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: ライブラリã®é–¢æ•° %s をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ãƒ¯ã‚¤ãƒ‰ãƒ•ã‚©ãƒ³ãƒˆã‚’é¸æŠžã§ãã¾ã›ã‚“"
+msgid "E19: Mark has invalid line number"
+msgstr "E19: マークã«ç„¡åйãªè¡Œç•ªå·ãŒæŒ‡å®šã•れã¦ã„ã¾ã—ãŸ"
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: 無効ãªãƒ¯ã‚¤ãƒ‰ãƒ•ォントã§ã™"
+msgid "E20: Mark not set"
+msgstr "E20: マークã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: マウスã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“"
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: 'modifiable' ãŒã‚ªãƒ•ãªã®ã§ã€å¤‰æ›´ã§ãã¾ã›ã‚“"
-#~ msgid "cannot open "
-#~ msgstr "é–‹ã‘ã¾ã›ã‚“ "
+msgid "E22: Scripts nested too deep"
+msgstr "E22: スクリプトã®å…¥ã‚Œå­ãŒæ·±éŽãŽã¾ã™"
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: ウィンドウを開ã‘ã¾ã›ã‚“!\n"
+msgid "E23: No alternate file"
+msgstr "E23: 副ファイルã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigadosã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2.04ã‹ãれ以é™ãŒå¿…è¦ã§ã™\n"
+msgid "E24: No such abbreviation"
+msgstr "E24: ãã®ã‚ˆã†ãªçŸ­ç¸®å…¥åŠ›ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "%s ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %<PRId64> ãŒå¿…è¦ã§ã™\n"
+msgid "E477: No ! allowed"
+msgstr "E477: ! ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "NILã‚’é–‹ã‘ã¾ã›ã‚“:\n"
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUIã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™"
-#~ msgid "Cannot create "
-#~ msgstr "作æˆã§ãã¾ã›ã‚“ "
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr "E26: ヘブライ語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim㯠%d ã§çµ‚了ã—ã¾ã™\n"
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: ペルシア語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "コンソールモードを変更ã§ãã¾ã›ã‚“?!\n"
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr "E800: アラビア語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: コンソールã§ã¯ãªã„??\n"
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: ãã®ã‚ˆã†ãªåã®ãƒã‚¤ãƒ©ã‚¤ãƒˆã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚りã¾ã›ã‚“: %s"
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: -f オプションã§ã‚·ã‚§ãƒ«ã‚’実行ã§ãã¾ã›ã‚“"
+msgid "E29: No inserted text yet"
+msgstr "E29: ã¾ã ãƒ†ã‚­ã‚¹ãƒˆãŒæŒ¿å…¥ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "Cannot execute "
-#~ msgstr "実行ã§ãã¾ã›ã‚“ "
+msgid "E30: No previous command line"
+msgstr "E30: 以å‰ã«ã‚³ãƒžãƒ³ãƒ‰è¡ŒãŒã‚りã¾ã›ã‚“"
-#~ msgid "shell "
-#~ msgstr "シェル "
+msgid "E31: No such mapping"
+msgstr "E31: ãã®ã‚ˆã†ãªãƒžãƒƒãƒ”ングã¯ã‚りã¾ã›ã‚“"
-#~ msgid " returned\n"
-#~ msgstr " 戻りã¾ã—ãŸ\n"
+msgid "E479: No match"
+msgstr "E479: 該当ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE ãŒå°ã•éŽãŽã¾ã™."
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: 該当ã¯ã‚りã¾ã›ã‚“: %s"
-#~ msgid "I/O ERROR"
-#~ msgstr "入出力エラー"
+msgid "E32: No file name"
+msgstr "E32: ファイルåãŒã‚りã¾ã›ã‚“"
-#~ msgid "Message"
-#~ msgstr "メッセージ"
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: æ­£è¦è¡¨ç¾ç½®æ›ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ãŒ80ã§ã¯ãªã„ãŸã‚, 外部コマンドを実行ã§ãã¾ã›ã‚“"
+msgid "E34: No previous command"
+msgstr "E34: コマンドãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: プリンタã®é¸æŠžã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E35: No previous regular expression"
+msgstr "E35: æ­£è¦è¡¨ç¾ãŒã¾ã å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "to %s on %s"
-#~ msgstr "%s 㸠(%s 上ã®)"
+msgid "E481: No range allowed"
+msgstr "E481: 範囲指定ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: 未知ã®ãƒ—リンタオプションã§ã™: %s"
+msgid "E36: Not enough room"
+msgstr "E36: ウィンドウã«å分ãªé«˜ã•ã‚‚ã—ãã¯å¹…ãŒã‚りã¾ã›ã‚“"
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: å°åˆ·ã‚¨ãƒ©ãƒ¼: %s"
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: %s ã¨ã„ã†åå‰ã®ç™»éŒ²ã•れãŸã‚µãƒ¼ãƒãƒ¼ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Printing '%s'"
-#~ msgstr "å°åˆ·ã—ã¦ã„ã¾ã™: '%s'"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: ファイル %s を作æˆã§ãã¾ã›ã‚“"
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: 文字セットå \"%s\" ã¯ä¸æ­£ã§ã™ (フォントå \"%s\")"
+msgid "E483: Can't get temp file name"
+msgstr "E483: 一時ファイルã®åå‰ã‚’å–å¾—ã§ãã¾ã›ã‚“"
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: '%c' ã¯ä¸æ­£ãªæ–‡å­—ã§ã™ (フォントå \"%s\")"
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“"
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: 2é‡ã®ã‚·ã‚°ãƒŠãƒ«ã®ãŸã‚, 終了ã—ã¾ã™\n"
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: ファイル %s を読込ã‚ã¾ã›ã‚“"
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: 致命的シグナル %s を検知ã—ã¾ã—ãŸ\n"
+msgid "E38: Null argument"
+msgstr "E38: 引数ãŒç©ºã§ã™"
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: 致命的シグナルを検知ã—ã¾ã—ãŸ\n"
+msgid "E39: Number expected"
+msgstr "E39: 数値ãŒè¦æ±‚ã•れã¦ã„ã¾ã™"
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Xサーãƒã¸ã®æŽ¥ç¶šã« %<PRId64> ミリ秒ã‹ã‹ã‚Šã¾ã—ãŸ"
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: エラーファイル %s ã‚’é–‹ã‘ã¾ã›ã‚“"
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: X ã®ã‚¨ãƒ©ãƒ¼ã‚’検出ã—ã¾ã—ãŸr\n"
+msgid "E233: cannot open display"
+msgstr "E233: ディスプレイを開ã‘ã¾ã›ã‚“"
-#~ msgid "Testing the X display failed"
-#~ msgstr "X display ã®ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E41: Out of memory!"
+msgstr "E41: メモリãŒå°½ãæžœã¦ã¾ã—ãŸ!"
-#~ msgid "Opening the X display timed out"
-#~ msgstr "X display ã® open ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ"
+msgid "Pattern not found"
+msgstr "パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "sh シェルを実行ã§ãã¾ã›ã‚“\n"
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: パターンã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "パイプを作æˆã§ãã¾ã›ã‚“\n"
+msgid "E487: Argument must be positive"
+msgstr "E487: å¼•æ•°ã¯æ­£ã®å€¤ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "fork ã§ãã¾ã›ã‚“\n"
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: å‰ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æˆ»ã‚Œã¾ã›ã‚“"
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "コマンドを中断ã—ã¾ã—ãŸ\n"
+msgid "E42: No Errors"
+msgstr "E42: エラーã¯ã‚りã¾ã›ã‚“"
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP ãŒICE接続を失ã„ã¾ã—ãŸ"
+msgid "E776: No location list"
+msgstr "E776: ロケーションリストã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Opening the X display failed"
-#~ msgstr "X display ã® open ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E43: Damaged match string"
+msgstr "E43: 該当文字列ãŒç ´æã—ã¦ã„ã¾ã™"
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP ãŒsave-yourselfè¦æ±‚を処ç†ã—ã¦ã„ã¾ã™"
+msgid "E44: Corrupted regexp program"
+msgstr "E44: 䏿­£ãªæ­£è¦è¡¨ç¾ãƒ—ログラムã§ã™"
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP ãŒæŽ¥ç¶šã‚’é–‹å§‹ã—ã¦ã„ã¾ã™"
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: 'readonly' オプションãŒè¨­å®šã•れã¦ã„ã¾ã™ (! を追加ã§ä¸Šæ›¸ã)"
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICE接続ãŒå¤±æ•—ã—ãŸã‚ˆã†ã§ã™"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: 読å–専用変数 \"%s\" ã«ã¯å€¤ã‚’設定ã§ãã¾ã›ã‚“"
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnectionãŒå¤±æ•—ã—ã¾ã—ãŸ: %s"
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: サンドボックスã§ã¯å¤‰æ•° \"%s\" ã«å€¤ã‚’設定ã§ãã¾ã›ã‚“"
-#~ msgid "At line"
-#~ msgstr "行"
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: 辞書型ã«ç©ºã®ã‚­ãƒ¼ã‚’使ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“"
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "vim32.dll をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
+msgid "E715: Dictionary required"
+msgstr "E715: 辞書型ãŒå¿…è¦ã§ã™"
-#~ msgid "VIM Error"
-#~ msgstr "VIMエラー"
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: リストã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒç¯„囲外ã§ã™: %ld"
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "DLLã‹ã‚‰é–¢æ•°ãƒã‚¤ãƒ³ã‚¿ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: 関数ã®å¼•æ•°ãŒå¤šéŽãŽã¾ã™: %s"
-#~ msgid "shell returned %d"
-#~ msgstr "シェルãŒã‚³ãƒ¼ãƒ‰ %d ã§çµ‚了ã—ã¾ã—ãŸ"
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: 辞書型ã«ã‚­ãƒ¼ãŒå­˜åœ¨ã—ã¾ã›ã‚“: %s"
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: イベント %s を検知\n"
+msgid "E714: List required"
+msgstr "E714: リスト型ãŒå¿…è¦ã§ã™"
-#~ msgid "close"
-#~ msgstr "é–‰ã˜ã‚‹"
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: %s ã®å¼•æ•°ã¯ãƒªã‚¹ãƒˆåž‹ã¾ãŸã¯è¾žæ›¸åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "logoff"
-#~ msgstr "ログオフ"
+msgid "E47: Error while reading errorfile"
+msgstr "E47: エラーファイルã®èª­è¾¼ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-#~ msgid "shutdown"
-#~ msgstr "シャットダウン"
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: サンドボックスã§ã¯è¨±ã•れã¾ã›ã‚“"
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: コマンドãŒã‚りã¾ã›ã‚“"
-
-#~ 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 ""
-#~ "VIMRUN.EXE㌠$PATH ã®ä¸­ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“.\n"
-#~ "外部コマンドã®çµ‚了後ã«ä¸€æ™‚åœæ­¢ã‚’ã—ã¾ã›ã‚“.\n"
-#~ "詳細㯠:help win32-vimrun ã‚’å‚ç…§ã—ã¦ãã ã•ã„."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Vimã®è­¦å‘Š"
-
-#~ msgid "Error file"
-#~ msgstr "エラーファイル"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: 等価クラスをå«ã‚€NFA構築ã«å¤±æ•—ã—ã¾ã—ãŸ!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) ç¾åœ¨æ¨ªæ–­ä¸­ã®ãƒ–ランãƒã«å分ãªãƒ¡ãƒ¢ãƒªã‚’割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "警告: å˜èªžãƒªã‚¹ãƒˆ \"%s_%s.spl\" ãŠã‚ˆã³ \"%s_ascii.spl\" ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "%s 内ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: メモリãŒè¶³ã‚Šãªã„ã®ã§ã€å˜èªžãƒªã‚¹ãƒˆã¯ä¸å®Œå…¨ã§ã™"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: タグファイルã®ãƒ‘ス㌠%s ã«åˆ‡ã‚Šæ¨ã¦ã‚‰ã‚Œã¾ã—ãŸ\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "æ–°ã—ã„シェルを起動ã—ã¾ã™\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "空ã®é¸æŠžé ˜åŸŸã®ã‹ã‚りã«CUT_BUFFER0ãŒä½¿ç”¨ã•れã¾ã—ãŸ"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "å¯èƒ½ãªã‚¢ãƒ³ãƒ‰ã‚¥ã¯ã‚りã¾ã›ã‚“: ã¨ã‚Šã‚ãˆãšç¶šã‘ã¾ã™"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr ""
-#~ "E832: éžæš—å·åŒ–ãƒ•ã‚¡ã‚¤ãƒ«ãŒæš—å·åŒ–ã•れãŸã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルを使ã£ã¦ã¾ã™: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: æš—å·åŒ–ã•れãŸã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ァイルã®è§£èª­ã«å¤±æ•—ã—ã¾ã—ãŸ: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: ã‚¢ãƒ³ãƒ‰ã‚¥ãƒ•ã‚¡ã‚¤ãƒ«ãŒæš—å·åŒ–ã•れã¦ã„ã¾ã™: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 ビット GUI 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ビット GUI 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ビット GUI 版"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " in Win32s モード"
-
-#~ msgid " with OLE support"
-#~ msgstr " with OLE サãƒãƒ¼ãƒˆ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ビット コンソール 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ビット コンソール 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16 ビット 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 ビット MS-DOS 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 ビット MS-DOS 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "OpenVMS 版"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Big 版 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "通常 版 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Small 版 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Tiny 版 "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "with GTK2-GNOME GUI."
+msgid "E523: Not allowed here"
+msgstr "E523: ã“ã“ã§ã¯è¨±å¯ã•れã¾ã›ã‚“"
-#~ msgid "with GTK2 GUI."
-#~ msgstr "with GTK2 GUI."
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: スクリーンモードã®è¨­å®šã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“"
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "with X11-Motif GUI."
+msgid "E49: Invalid scroll size"
+msgstr "E49: 無効ãªã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«é‡ã§ã™"
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "with X11-neXtaw GUI."
+msgid "E91: 'shell' option is empty"
+msgstr "E91: 'shell' オプションãŒç©ºã§ã™"
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "with X11-Athena GUI."
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: sign ã®ãƒ‡ãƒ¼ã‚¿ã‚’読込ã‚ã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "with Photon GUI."
-#~ msgstr "with Photon GUI."
+msgid "E72: Close error on swap file"
+msgstr "E72: スワップファイルã®ã‚¯ãƒ­ãƒ¼ã‚ºæ™‚エラーã§ã™"
-#~ msgid "with GUI."
-#~ msgstr "with GUI."
+msgid "E73: tag stack empty"
+msgstr "E73: タグスタックãŒç©ºã§ã™"
-#~ msgid "with Carbon GUI."
-#~ msgstr "with Carbon GUI."
+msgid "E74: Command too complex"
+msgstr "E74: コマンドãŒè¤‡é›‘éŽãŽã¾ã™"
-#~ msgid "with Cocoa GUI."
-#~ msgstr "with Cocoa GUI."
+msgid "E75: Name too long"
+msgstr "E75: åå‰ãŒé•·éŽãŽã¾ã™"
-#~ msgid "with (classic) GUI."
-#~ msgstr "with (クラシック) GUI."
+msgid "E76: Too many ["
+msgstr "E76: [ ãŒå¤šéŽãŽã¾ã™"
-#~ msgid " system gvimrc file: \""
-#~ msgstr " システム gvimrc: \""
+msgid "E77: Too many file names"
+msgstr "E77: ファイルåãŒå¤šéŽãŽã¾ã™"
-#~ msgid " user gvimrc file: \""
-#~ msgstr " ユーザ gvimrc: \""
+msgid "E488: Trailing characters"
+msgstr "E488: ä½™åˆ†ãªæ–‡å­—ãŒå¾Œã‚ã«ã‚りã¾ã™"
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " 第2ユーザ gvimrc: \""
+msgid "E78: Unknown mark"
+msgstr "E78: 未知ã®ãƒžãƒ¼ã‚¯"
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " 第3ユーザ gvimrc: \""
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: ワイルドカードを展開ã§ãã¾ã›ã‚“"
-#~ msgid " system menu file: \""
-#~ msgstr " システムメニュー: \""
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' 㯠'winminheight' よりå°ã•ãã§ãã¾ã›ã‚“"
-#~ msgid "Compiler: "
-#~ msgstr "コンパイラ: "
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' 㯠'winminwidth' よりå°ã•ãã§ãã¾ã›ã‚“"
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "詳細ã¯ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã® ãƒ˜ãƒ«ãƒ—â†’å­¤å… ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„ "
+msgid "E80: Error while writing"
+msgstr "E80: 書込ã¿ä¸­ã®ã‚¨ãƒ©ãƒ¼"
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "モード無ã§å®Ÿè¡Œä¸­, タイプã—ãŸæ–‡å­—ãŒæŒ¿å…¥ã•れã¾ã™"
+msgid "E939: Positive count required"
+msgstr "E939: æ­£ã®ã‚«ã‚¦ãƒ³ãƒˆãŒå¿…è¦ã§ã™"
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "メニュー㮠編集→全体設定→挿入(åˆå¿ƒè€…)モード切替 "
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: スクリプト以外ã§<SID>ãŒä½¿ã‚れã¾ã—ãŸ"
-#~ msgid " for two modes "
-#~ msgstr " ã§ãƒ¢ãƒ¼ãƒ‰æœ‰ã« "
+msgid "E449: Invalid expression received"
+msgstr "E449: 無効ãªå¼ã‚’å—ã‘å–りã¾ã—ãŸ"
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "メニュー㮠編集→全体設定→Vi互æ›ãƒ¢ãƒ¼ãƒ‰åˆ‡æ›¿ "
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: 領域ãŒä¿è­·ã•れã¦ã„ã‚‹ã®ã§ã€å¤‰æ›´ã§ãã¾ã›ã‚“"
-#~ msgid " for Vim defaults "
-#~ msgstr " ã§Vimã¨ã—ã¦å‹•作 "
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr "E744: NetBeans ã¯èª­è¾¼å°‚用ファイルを変更ã™ã‚‹ã“ã¨ã‚’許ã—ã¾ã›ã‚“"
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr " 警告: Windows 95/98/Me を検出 "
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: パターン㌠'maxmempattern' 以上ã®ãƒ¡ãƒ¢ãƒªã‚’使用ã—ã¾ã™"
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr " è©³ç´°ãªæƒ…報㯠:help windows95<Enter> "
+msgid "E749: empty buffer"
+msgstr "E749: ãƒãƒƒãƒ•ã‚¡ãŒç©ºã§ã™"
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "複数ã®Vimã§ç·¨é›†ã™ã‚‹ (&M)"
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: ãƒãƒƒãƒ•ã‚¡ %ld ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "Edit with single &Vim"
-#~ msgstr "1ã¤ã®Vimã§ç·¨é›†ã™ã‚‹ (&V)"
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: 検索パターンã‹åŒºåˆ‡ã‚Šè¨˜å·ãŒä¸æ­£ã§ã™"
-#~ msgid "Diff with Vim"
-#~ msgstr "Vimã§å·®åˆ†ã‚’表示ã™ã‚‹"
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: åŒã˜åå‰ã®ãƒ•ァイルãŒä»–ã®ãƒãƒƒãƒ•ã‚¡ã§èª­è¾¼ã¾ã‚Œã¦ã„ã¾ã™"
-#~ msgid "Edit with &Vim"
-#~ msgstr "Vimã§ç·¨é›†ã™ã‚‹ (&V)"
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: オプション '%s' ã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "起動済ã®Vimã§ç·¨é›†ã™ã‚‹ - "
+msgid "E850: Invalid register name"
+msgstr "E850: 無効ãªãƒ¬ã‚¸ã‚¹ã‚¿åã§ã™"
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "é¸æŠžã—ãŸãƒ•ァイルをVimã§ç·¨é›†ã™ã‚‹"
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: ディレクトリ㌠'%s' ã®ä¸­ã«ã‚りã¾ã›ã‚“: \"%s\""
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "プロセスã®ä½œæˆã«å¤±æ•—: gvimãŒç’°å¢ƒå¤‰æ•°PATH上ã«ã‚ã‚‹ã‹ç¢ºèªã—ã¦ãã ã•ã„!"
+msgid "E952: Autocommand caused recursive behavior"
+msgstr "E952: AutocommandãŒå†å¸°ã‚’引ãèµ·ã“ã—ã¾ã—ãŸ"
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll エラー"
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "上ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸‹ã«æˆ»ã‚Šã¾ã™"
-#~ msgid "Path length too long!"
-#~ msgstr "パスãŒé•·ã™ãŽã¾ã™!"
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "下ã¾ã§æ¤œç´¢ã—ãŸã®ã§ä¸Šã«æˆ»ã‚Šã¾ã™"
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: 未知ã®ãƒ•ォントセット: %s"
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "æš—å·ã‚­ãƒ¼ãŒå¿…è¦ã§ã™: \"%s\""
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: 未知ã®ãƒ•ォント: %s"
+msgid "empty keys are not allowed"
+msgstr "空ã®ã‚­ãƒ¼ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: フォント \"%s\" ã¯å›ºå®šå¹…ã§ã¯ã‚りã¾ã›ã‚“"
+msgid "dictionary is locked"
+msgstr "辞書ã¯ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™"
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: ライブラリã®é–¢æ•° %s をロードã§ãã¾ã›ã‚“ã§ã—ãŸ"
+msgid "list is locked"
+msgstr "リストã¯ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™"
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: ヘブライ語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "辞書ã«ã‚­ãƒ¼ '%s' を追加ã™ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: ペルシア語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "インデックス㯠%s ã§ã¯ãªãæ•´æ•°ã‹ã‚¹ãƒ©ã‚¤ã‚¹ã«ã—ã¦ãã ã•ã„"
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: アラビア語ã¯ä½¿ç”¨ä¸å¯èƒ½ã§ã™: コンパイル時ã«ç„¡åйã«ã•れã¦ã„ã¾ã™\n"
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "str() ã‚‚ã—ã㯠unicode() ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: %s ã¨ã„ã†åå‰ã®ç™»éŒ²ã•れãŸã‚µãƒ¼ãƒã¯ã‚りã¾ã›ã‚“"
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "bytes() ã‚‚ã—ã㯠str() ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ディスプレイを開ã‘ã¾ã›ã‚“"
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr "long() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: 無効ãªå¼ã‚’å—ã‘å–りã¾ã—ãŸ"
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr "int() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: 領域ãŒä¿è­·ã•れã¦ã„ã‚‹ã®ã§, 変更ã§ãã¾ã›ã‚“"
+msgid "value is too large to fit into C int type"
+msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå¤§ãéŽãŽã¾ã™"
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ã¯èª­è¾¼å°‚用ファイルを変更ã™ã‚‹ã“ã¨ã‚’許ã—ã¾ã›ã‚“"
+msgid "value is too small to fit into C int type"
+msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå°ã•éŽãŽã¾ã™"
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "æš—å·ã‚­ãƒ¼ãŒå¿…è¦ã§ã™: \"%s\""
+msgid "number must be greater than zero"
+msgstr "数値㯠0 より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "empty keys are not allowed"
-#~ msgstr "空ã®ã‚­ãƒ¼ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“"
+msgid "number must be greater or equal to zero"
+msgstr "数値㯠0 ã‹ãれ以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "dictionary is locked"
-#~ msgstr "辞書ã¯ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™"
+msgid "can't delete OutputObject attributes"
+msgstr "OutputObject属性を消ã›ã¾ã›ã‚“"
-#~ msgid "list is locked"
-#~ msgstr "リストã¯ãƒ­ãƒƒã‚¯ã•れã¦ã„ã¾ã™"
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "無効ãªå±žæ€§ã§ã™: %s"
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "辞書ã«ã‚­ãƒ¼ '%s' を追加ã™ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: I/Oオブジェクトã®åˆæœŸåŒ–エラー"
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "インデックス㯠%s ã§ã¯ãªãæ•´æ•°ã‹ã‚¹ãƒ©ã‚¤ã‚¹ã«ã—ã¦ãã ã•ã„"
+msgid "failed to change directory"
+msgstr "辞書ã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr ""
-#~ "str() ã‚‚ã—ã㯠unicode() ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "imp.find_module() ㌠%s ã‚’è¿”ã—ã¾ã—㟠(期待値: 3 è¦ç´ ã®ã‚¿ãƒ—ル)"
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "bytes() ã‚‚ã—ã㯠str() ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr "imp.find_module() ㌠%d è¦ç´ ã®ã‚¿ãƒ—ルを返ã—ã¾ã—㟠(期待値: 3)"
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr "long() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "内部エラー: imp.find_module ㌠NULL ã‚’å«ã‚€ã‚¿ãƒ—ルを返ã—ã¾ã—ãŸ"
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr "int() ã‹ãれã¸å¤‰æ›å¯èƒ½ãªã‚‚ã®ãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "vim.Dictionaryå±žæ€§ã¯æ¶ˆã›ã¾ã›ã‚“"
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå¤§ãéŽãŽã¾ã™"
+msgid "cannot modify fixed dictionary"
+msgstr "固定ã•れãŸè¾žæ›¸ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "C言語㮠int åž‹ã¨ã—ã¦ã¯å€¤ãŒå°ã•éŽãŽã¾ã™"
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "属性 %s ã¯è¨­å®šã§ãã¾ã›ã‚“"
-#~ msgid "number must be greater then zero"
-#~ msgstr "数値㯠0 より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgid "hashtab changed during iteration"
+msgstr "イテレーション中㫠hashtab ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "数値㯠0 ã‹ãれ以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr "シーケンスã®è¦ç´ æ•°ã«ã¯ 2 ãŒæœŸå¾…ã•れã¦ã„ã¾ã—ãŸãŒ %d ã§ã—ãŸ"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "OutputObject属性を消ã›ã¾ã›ã‚“"
+msgid "list constructor does not accept keyword arguments"
+msgstr "リストã®ã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ã¯ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å¼•æ•°ã‚’å—ã‘付ã‘ã¾ã›ã‚“"
-#~ msgid "invalid attribute: %s"
-#~ msgstr "無効ãªå±žæ€§ã§ã™: %s"
+msgid "list index out of range"
+msgstr "リスト範囲外ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: I/Oオブジェクトã®åˆæœŸåŒ–エラー"
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´  %d ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "failed to change directory"
-#~ msgstr "辞書ã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "slice step cannot be zero"
+msgstr "スライスã®ã‚¹ãƒ†ãƒƒãƒ—ã« 0 ã¯æŒ‡å®šã§ãã¾ã›ã‚“"
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "imp.find_module() ㌠%s ã‚’è¿”ã—ã¾ã—㟠(期待値: 2 è¦ç´ ã®ã‚¿ãƒ—ル)"
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "é•·ã• %d ã®æ‹¡å¼µã‚¹ãƒ©ã‚¤ã‚¹ã«ã€ã‚ˆã‚Šé•·ã„スライスを割り当ã¦ã‚ˆã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr "impl.find_module() ㌠%d è¦ç´ ã®ã‚¿ãƒ—ルを返ã—ã¾ã—㟠(期待値: 2)"
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´  %d ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "内部エラー: imp.find_module ㌠NULL ã‚’å«ã‚€ã‚¿ãƒ—ルを返ã—ã¾ã—ãŸ"
+msgid "internal error: not enough list items"
+msgstr "内部エラー: リストã«å分ãªè¦ç´ ãŒã‚りã¾ã›ã‚“"
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "vim.Dictionaryå±žæ€§ã¯æ¶ˆã›ã¾ã›ã‚“"
+msgid "internal error: failed to add item to list"
+msgstr "内部エラー: リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "cannot modify fixed dictionary"
-#~ msgstr "固定ã•れãŸè¾žæ›¸ã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr "é•·ã• %d ã®ã‚¹ãƒ©ã‚¤ã‚¹ã‚’ %d ã®æ‹¡å¼µã‚¹ãƒ©ã‚¤ã‚¹ã«å‰²ã‚Šå½“ã¦ã‚ˆã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "cannot set attribute %s"
-#~ msgstr "属性 %s ã¯è¨­å®šã§ãã¾ã›ã‚“"
+msgid "failed to add item to list"
+msgstr "リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "イテレーション中㫠hashtab ãŒå¤‰æ›´ã•れã¾ã—ãŸ"
+msgid "cannot delete vim.List attributes"
+msgstr "vim.List å±žæ€§ã¯æ¶ˆã›ã¾ã›ã‚“"
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr "シーケンスã®è¦ç´ æ•°ã«ã¯ 2 ãŒæœŸå¾…ã•れã¦ã„ã¾ã—ãŸãŒ %d ã§ã—ãŸ"
+msgid "cannot modify fixed list"
+msgstr "固定ã•れãŸãƒªã‚¹ãƒˆã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "リストã®ã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ã¯ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å¼•æ•°ã‚’å—ã‘付ã‘ã¾ã›ã‚“"
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "ç„¡å関数 %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
-#~ msgid "list index out of range"
-#~ msgstr "リスト範囲外ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™"
+#, c-format
+msgid "function %s does not exist"
+msgstr "関数 %s ãŒã‚りã¾ã›ã‚“"
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´  %d ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ"
+#, c-format
+msgid "failed to run function %s"
+msgstr "関数 %s ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "failed to add item to list"
-#~ msgstr "リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "unable to get option value"
+msgstr "オプションã®å€¤ã¯å–å¾—ã§ãã¾ã›ã‚“"
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "内部エラー: vimã®ãƒªã‚¹ãƒˆè¦ç´  %d ã¯ã‚りã¾ã›ã‚“"
+msgid "internal error: unknown option type"
+msgstr "内部エラー: 未知ã®ã‚ªãƒ—ション型ã§ã™"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "内部エラー: リストã¸ã®è¦ç´ è¿½åŠ ã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "problem while switching windows"
+msgstr "ウィンドウを切æ›ä¸­ã«å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "vim.List å±žæ€§ã¯æ¶ˆã›ã¾ã›ã‚“"
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "グローãƒãƒ«ã‚ªãƒ—ション %s ã®è¨­å®šè§£é™¤ã¯ã§ãã¾ã›ã‚“"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "固定ã•れãŸãƒªã‚¹ãƒˆã¯å¤‰æ›´ã§ãã¾ã›ã‚“"
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "グローãƒãƒ«ãªå€¤ã®ç„¡ã„オプション %s ã®è¨­å®šè§£é™¤ã¯ã§ãã¾ã›ã‚“"
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "ç„¡å関数 %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“"
+msgid "attempt to refer to deleted tab page"
+msgstr "削除ã•れãŸã‚¿ãƒ–ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "function %s does not exist"
-#~ msgstr "関数 %s ãŒã‚りã¾ã›ã‚“"
+msgid "no such tab page"
+msgstr "ãã®ã‚ˆã†ãªã‚¿ãƒ–ページã¯ã‚りã¾ã›ã‚“"
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "関数ã®ã‚³ãƒ³ã‚¹ãƒˆãƒ©ã‚¯ã‚¿ã¯ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å¼•æ•°ã‚’å—ã‘付ã‘ã¾ã›ã‚“"
+msgid "attempt to refer to deleted window"
+msgstr "削除ã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "failed to run function %s"
-#~ msgstr "関数 %s ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "readonly attribute: buffer"
+msgstr "読込専用属性: ãƒãƒƒãƒ•ァー"
-#~ msgid "problem while switching windows"
-#~ msgstr "ウィンドウを切æ›ä¸­ã«å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+msgid "cursor position outside buffer"
+msgstr "カーソルä½ç½®ãŒãƒãƒƒãƒ•ã‚¡ã®å¤–å´ã§ã™"
-#~ msgid "unable to unset global option %s"
-#~ msgstr "グローãƒãƒ«ã‚ªãƒ—ション %s ã®è¨­å®šè§£é™¤ã¯ã§ãã¾ã›ã‚“"
+msgid "no such window"
+msgstr "ãã®ã‚ˆã†ãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯ã‚りã¾ã›ã‚“"
-#~ msgid "unable to unset option %s which does not have global value"
-#~ msgstr "グローãƒãƒ«ãªå€¤ã®ç„¡ã„オプション %s ã®è¨­å®šè§£é™¤ã¯ã§ãã¾ã›ã‚“"
+msgid "attempt to refer to deleted buffer"
+msgstr "削除ã•れãŸãƒãƒƒãƒ•ã‚¡ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "削除ã•れãŸã‚¿ãƒ–ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
+msgid "failed to rename buffer"
+msgstr "ãƒãƒƒãƒ•ã‚¡åã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "no such tab page"
-#~ msgstr "ãã®ã‚ˆã†ãªã‚¿ãƒ–ページã¯ã‚りã¾ã›ã‚“"
+msgid "mark name must be a single character"
+msgstr "マークåã¯1文字ã®ã‚¢ãƒ«ãƒ•ァベットã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "削除ã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "vim.Bufferã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "読込専用属性: ãƒãƒƒãƒ•ァー"
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "指定ã•れãŸãƒãƒƒãƒ•ã‚¡ %d ã¸ã®åˆ‡ã‚Šæ›¿ãˆã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "カーソルä½ç½®ãŒãƒãƒƒãƒ•ã‚¡ã®å¤–å´ã§ã™"
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "vim.Windowã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "no such window"
-#~ msgstr "ãã®ã‚ˆã†ãªã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¯ã‚りã¾ã›ã‚“"
+msgid "failed to find window in the current tab page"
+msgstr "ç¾åœ¨ã®ã‚¿ãƒ–ã«ã¯æŒ‡å®šã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "削除ã•れãŸãƒãƒƒãƒ•ã‚¡ã‚’å‚ç…§ã—よã†ã¨ã—ã¾ã—ãŸ"
+msgid "did not switch to the specified window"
+msgstr "指定ã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«åˆ‡ã‚Šæ›¿ãˆã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "failed to rename buffer"
-#~ msgstr "ãƒãƒƒãƒ•ã‚¡åã®å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸ"
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "vim.TabPageã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
-#~ msgid "mark name must be a single character"
-#~ msgstr "マークåã¯1文字ã®ã‚¢ãƒ«ãƒ•ァベットã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“"
+msgid "did not switch to the specified tab page"
+msgstr "指定ã•れãŸã‚¿ãƒ–ページã«åˆ‡ã‚Šæ›¿ãˆã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "vim.Bufferã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "failed to run the code"
+msgstr "コードã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "指定ã•れãŸãƒãƒƒãƒ•ã‚¡ %d ã¸ã®åˆ‡ã‚Šæ›¿ãˆã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: å¼è©•ä¾¡ã¯æœ‰åйãªpythonオブジェクトを返ã—ã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "vim.Windowã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: è¿”ã•れãŸpythonオブジェクトをvimã®å€¤ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "ç¾åœ¨ã®ã‚¿ãƒ–ã«ã¯æŒ‡å®šã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ"
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "%s vimã®è¾žæ›¸åž‹ã«å¤‰æ›ã§ãã¾ã›ã‚“"
-#~ msgid "did not switch to the specified window"
-#~ msgstr "指定ã•れãŸã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã«åˆ‡ã‚Šæ›¿ãˆã¾ã›ã‚“ã§ã—ãŸ"
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "%s ã‚’vimã®ãƒªã‚¹ãƒˆã«å¤‰æ›ã§ãã¾ã›ã‚“"
-#~ msgid "expected vim.TabPage object, but got %s"
-#~ msgstr "vim.TabPageã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆãŒæœŸå¾…ã•れã¦ã„ã‚‹ã®ã« %s ã§ã—ãŸ"
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "%s ã‚’vimã®æ§‹é€ ä½“ã«å¤‰æ›ã§ãã¾ã›ã‚“"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "指定ã•れãŸã‚¿ãƒ–ページã«åˆ‡ã‚Šæ›¿ãˆã¾ã›ã‚“ã§ã—ãŸ"
+msgid "internal error: NULL reference passed"
+msgstr "内部エラー: NULLå‚ç…§ãŒæ¸¡ã•れã¾ã—ãŸ"
-#~ msgid "failed to run the code"
-#~ msgstr "コードã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ"
+msgid "internal error: invalid value type"
+msgstr "内部エラー: 無効ãªå€¤åž‹ã§ã™"
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: å¼è©•ä¾¡ã¯æœ‰åйãªpythonオブジェクトを返ã—ã¾ã›ã‚“ã§ã—ãŸ"
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"パスフックã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸ: sys.path_hooks ãŒãƒªã‚¹ãƒˆã§ã¯ã‚りã¾ã›ã‚“\n"
+"ã™ãã«ä¸‹è¨˜ã‚’実施ã—ã¦ãã ã•ã„:\n"
+"- vim.path_hooks ã‚’ sys.path_hooks ã¸è¿½åŠ \n"
+"- vim.VIM_SPECIAL_PATH ã‚’ sys.path ã¸è¿½åŠ \n"
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: è¿”ã•れãŸpythonオブジェクトをvimã®å€¤ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"パスã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸ: sys.path ãŒãƒªã‚¹ãƒˆã§ã¯ã‚りã¾ã›ã‚“\n"
+"ã™ãã« vim.VIM_SPECIAL_PATH ã‚’ sys.path ã«è¿½åŠ ã—ã¦ãã ã•ã„"
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "%s vimã®è¾žæ›¸åž‹ã«å¤‰æ›ã§ãã¾ã›ã‚“"
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*.*)\t*.*\n"
+msgstr ""
+"Vimマクロファイル (*.vim)\t*.vim\n"
+"ã™ã¹ã¦ã®ãƒ•ァイル (*.*)\t*.*\n"
-#~ msgid "unable to convert %s to vim structure"
-#~ msgstr "%s ã‚’vimã®æ§‹é€ ä½“ã«å¤‰æ›ã§ãã¾ã›ã‚“"
+msgid "All Files (*.*)\t*.*\n"
+msgstr "ã™ã¹ã¦ã®ãƒ•ァイル (*.*)\t*.*\n"
-#~ msgid "internal error: NULL reference passed"
-#~ msgstr "内部エラー: NULLå‚ç…§ãŒæ¸¡ã•れã¾ã—ãŸ"
+msgid ""
+"All Files (*.*)\t*.*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VB code (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"ã™ã¹ã¦ã®ãƒ•ァイル (*.*)\t*.*\n"
+"Cソース (*.c, *.h)\t*.c;*.h\n"
+"C++ソース (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VBコード (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vimファイル (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "内部エラー: 無効ãªå€¤åž‹ã§ã™"
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*)\t*\n"
+msgstr ""
+"Vim マクロファイル (*.vim)\t*.vim\n"
+"ã™ã¹ã¦ã®ãƒ•ァイル (*)\t*\n"
-#~ msgid ""
-#~ "Failed to set path hook: sys.path_hooks is not a list\n"
-#~ "You should now do the following:\n"
-#~ "- append vim.path_hook to sys.path_hooks\n"
-#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
-#~ msgstr ""
-#~ "パスフックã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸ: sys.path_hooks ãŒãƒªã‚¹ãƒˆã§ã¯ã‚りã¾ã›ã‚“\n"
-#~ "ã™ãã«ä¸‹è¨˜ã‚’実施ã—ã¦ãã ã•ã„:\n"
-#~ "- vim.path_hooks ã‚’ sys.path_hooks ã¸è¿½åŠ \n"
-#~ "- vim.VIM_SPECIAL_PATH ã‚’ sys.path ã¸è¿½åŠ \n"
+msgid "All Files (*)\t*\n"
+msgstr "ã™ã¹ã¦ã®ãƒ•ァイル (*)\t*\n"
-#~ msgid ""
-#~ "Failed to set path: sys.path is not a list\n"
-#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
-#~ msgstr ""
-#~ "パスã®è¨­å®šã«å¤±æ•—ã—ã¾ã—ãŸ: sys.path ãŒãƒªã‚¹ãƒˆã§ã¯ã‚りã¾ã›ã‚“\n"
-#~ "ã™ãã« vim.VIM_SPECIAL_PATH ã‚’ sys.path ã«è¿½åŠ ã—ã¦ãã ã•ã„"
+msgid ""
+"All Files (*)\t*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"ã™ã¹ã¦ã®ãƒ•ァイル (*)\t*\n"
+"Cソース (*.c, *.h)\t*.c;*.h\n"
+"C++ソース (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vimファイル (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
diff --git a/src/nvim/po/ja.sjis.po b/src/nvim/po/ja.sjis.po
deleted file mode 100644
index 16a5d2ce36..0000000000
--- a/src/nvim/po/ja.sjis.po
+++ /dev/null
@@ -1,8223 +0,0 @@
-# Japanese translation for Vim
-#
-# Do ":help uganda" in Vim to read copying and usage conditions.
-# Do ":help credits" in Vim to see a list of people who contributed.
-#
-# Copyright (C) 2001-2016 MURAOKA Taro <koron.kaoriya@gmail.com>,
-# vim-jp (http://vim-jp.org/)
-#
-# THIS FILE IS DISTRIBUTED UNDER THE VIM LICENSE.
-#
-# Original translations.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Vim 7.4\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2016-02-01 09:02+0900\n"
-"PO-Revision-Date: 2016-02-01 09:08+0900\n"
-"Last-Translator: MURAOKA Taro <koron.kaoriya@gmail.com>\n"
-"Language-Team: vim-jpj (https://github.com/vim-jp/lang-ja)\n"
-"Language: Japanese\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=cp932\n"
-"Content-Transfer-Encoding: 8-bit\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "ƒIƒvƒVƒ‡ƒ“‚Ì’l‚͎擾‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "“à•”ƒGƒ‰[: –¢’m‚̃IƒvƒVƒ‡ƒ“Œ^‚Å‚·"
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[ƒƒP[ƒVƒ‡ƒ“ƒŠƒXƒg]"
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[QuickfixƒŠƒXƒg]"
-
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr "E855: autocommand‚ªƒRƒ}ƒ“ƒh‚Ì’âŽ~‚ðˆø‚«‹N‚±‚µ‚Ü‚µ‚½"
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: ƒoƒbƒtƒ@‚ð1‚‚à쬂ł«‚È‚¢‚Ì‚Å, I—¹‚µ‚Ü‚·..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: ƒoƒbƒtƒ@‚ð쬂ł«‚È‚¢‚Ì‚Å, ‘¼‚Ì‚ðŽg—p‚µ‚Ü‚·..."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: ‰ð•ú‚³‚ꂽƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: 휂³‚ꂽƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../buffer.c:767
-msgid "E517: No buffers were wiped out"
-msgstr "E517: ”jŠü‚³‚ꂽƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "1 ŒÂ‚̃oƒbƒtƒ@‚ª‰ð•ú‚³‚ê‚Ü‚µ‚½"
-
-#: ../buffer.c:774
-#, c-format
-msgid "%d buffers unloaded"
-msgstr "%d ŒÂ‚̃oƒbƒtƒ@‚ª‰ð•ú‚³‚ê‚Ü‚µ‚½"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "1 ŒÂ‚̃oƒbƒtƒ@‚ªíœ‚³‚ê‚Ü‚µ‚½"
-
-#: ../buffer.c:779
-#, c-format
-msgid "%d buffers deleted"
-msgstr "%d ŒÂ‚̃oƒbƒtƒ@‚ªíœ‚³‚ê‚Ü‚µ‚½"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "1 ŒÂ‚̃oƒbƒtƒ@‚ª”jŠü‚³‚ê‚Ü‚µ‚½"
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "%d ŒÂ‚̃oƒbƒtƒ@‚ª”jŠü‚³‚ê‚Ü‚µ‚½"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: ÅŒã‚̃oƒbƒtƒ@‚͉ð•ú‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: •ÏX‚³‚ꂽƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-msgid "E85: There is no listed buffer"
-msgstr "E85: ƒŠƒXƒg•\\ަ‚³‚ê‚éƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: ƒoƒbƒtƒ@ %<PRId64> ‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../buffer.c:915
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: ÅŒã‚̃oƒbƒtƒ@‚ð‰z‚¦‚Ĉړ®‚͂ł«‚Ü‚¹‚ñ"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: ʼn‚̃oƒbƒtƒ@‚æ‚è‘O‚ւ͈ړ®‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: ƒoƒbƒtƒ@ %<PRId64> ‚Ì•ÏX‚͕ۑ¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ (! ‚Å•ÏX‚ð”jŠü)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: Œx: ƒtƒ@ƒCƒ‹–¼‚ÌƒŠƒXƒg‚ª’·‰ß‚¬‚Ü‚·"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: ƒoƒbƒtƒ@ %<PRId64> ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: %s ‚É•¡”‚ÌŠY“–‚ª‚ ‚è‚Ü‚µ‚½"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: %s ‚ÉŠY“–‚·‚éƒoƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "s %<PRId64>"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: ‚±‚Ì–¼‘O‚̃oƒbƒtƒ@‚ÍŠù‚É‚ ‚è‚Ü‚·"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [•ÏX‚ ‚è]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[–¢•ÒW]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[Vƒtƒ@ƒCƒ‹]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[“ÇžƒGƒ‰[]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[“Çê]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-msgid "[readonly]"
-msgstr "[“Çžê—p]"
-
-#: ../buffer.c:2524
-#, c-format
-msgid "1 line --%d%%--"
-msgstr "1 s --%d%%--"
-
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> s --%d%%--"
-
-#: ../buffer.c:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "s %<PRId64> (‘S‘Ì %<PRId64>) --%d%%-- col "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-msgid "[No Name]"
-msgstr "[–³–¼]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "ƒwƒ‹ƒv"
-
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[ƒwƒ‹ƒv]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[ƒvƒŒƒrƒ…[]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "‘S‚Ä"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "––”ö"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "擪"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# ƒoƒbƒtƒ@ƒŠƒXƒg:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr "[‰º‘‚«]"
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- ƒTƒCƒ“ ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "%s ‚̃TƒCƒ“:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " s=%<PRId64> ޝ•ÊŽq=%d –¼‘O=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ƒRƒƒ“‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: •s³‚ȃ‚[ƒh‚Å‚·"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: ”’l‚ª•K—v‚Å‚·"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: •s³‚ȃp[ƒZƒ“ƒe[ƒW‚Å‚·"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: %<PRId64> ˆÈã‚̃oƒbƒtƒ@‚Ídiff‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../diff.c:753
-msgid "E810: Cannot read or write temp files"
-msgstr "E810: ˆêŽžƒtƒ@ƒCƒ‹‚̓Ǟ‚à‚µ‚­‚Í‘ž‚ª‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: ·•ª‚ð쬂ł«‚Ü‚¹‚ñ"
-
-#: ../diff.c:966
-msgid "E816: Cannot read patch output"
-msgstr "E816: patch‚Ìo—Í‚ð“Çž‚߂܂¹‚ñ"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: diff‚Ìo—Í‚ð“Çž‚߂܂¹‚ñ"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: Œ»Ý‚̃oƒbƒtƒ@‚Í·•ªƒ‚[ƒh‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../diff.c:2100
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E793: ·•ªƒ‚[ƒh‚Å‚ ‚鑼‚̃oƒbƒtƒ@‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: ·•ªƒ‚[ƒh‚Å‚ ‚鑼‚̃oƒbƒtƒ@‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr ""
-"E101: ·•ªƒ‚[ƒh‚̃oƒbƒtƒ@‚ª2ŒÂˆÈã‚ ‚é‚Ì‚ÅA‚Ç‚ê‚ðŽg‚¤‚©“Á’è‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: ƒoƒbƒtƒ@ \"%s\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: ƒoƒbƒtƒ@ \"%s\" ‚Í·•ªƒ‚[ƒh‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr "E787: —\\Šú‚¹‚¸ƒoƒbƒtƒ@‚ª•ÏX•ÏX‚³‚ê‚Ü‚µ‚½"
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: ‡Žš‚ÉEscape‚ÍŽg—p‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: ƒL[ƒ}ƒbƒvƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: :source ‚Ŏ枂ރtƒ@ƒCƒ‹ˆÈŠO‚Å‚Í :loadkeymap ‚ðŽg‚¦‚Ü‚¹‚ñ"
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr "E791: ‹ó‚̃L[ƒ}ƒbƒvƒGƒ“ƒgƒŠ"
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " ƒL[ƒ[ƒh•⊮ (^N^P)"
-
-#. 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 ƒ‚[ƒh (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " s(‘S‘Ì)•⊮ (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " ƒtƒ@ƒCƒ‹–¼•⊮ (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " ƒ^ƒO•⊮ (^]^N^P)"
-
-#: ../edit.c:88
-msgid " Path pattern completion (^N^P)"
-msgstr " ƒpƒXƒpƒ^[ƒ“•⊮ (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " ’è‹`•⊮ (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Ž«‘•⊮ (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " ƒVƒ\\[ƒ‰ƒX•⊮ (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“•⊮ (^V^N^P)"
-
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr " ƒ†[ƒU[’è‹`•⊮ (^U^N^P)"
-
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " ƒIƒ€ƒj•⊮ (^O^N^P)"
-
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ’Ô‚èC³Œó•â (s^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " ‹ÇŠƒL[ƒ[ƒh•⊮ (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "’i—Ž‚ÌÅŒã‚Ƀqƒbƒg"
-
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr "E839: •âŠÔŠÖ”‚ªƒEƒBƒ“ƒhƒE‚ð•ÏX‚µ‚Ü‚µ‚½"
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr "E840: •⊮ŠÖ”‚ªƒeƒLƒXƒg‚ð휂µ‚Ü‚µ‚½"
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "'dictionary' ƒIƒvƒVƒ‡ƒ“‚ª‹ó‚Å‚·"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "'thesaurus' ƒIƒvƒVƒ‡ƒ“‚ª‹ó‚Å‚·"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "Ž«‘‚ðƒXƒLƒƒƒ“’†: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (‘}“ü) ƒXƒNƒ[ƒ‹(^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (’uŠ·) ƒXƒNƒ[ƒ‹ (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "ƒXƒLƒƒƒ“’†: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "ƒ^ƒO‚ðƒXƒLƒƒƒ“’†."
-
-#: ../edit.c:4519
-msgid " Adding"
-msgstr " ’ljÁ’†"
-
-#. 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 "-- ŒŸõ’†..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "Žn‚߂ɖ߂é"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "‘¼‚Ìs‚Ì’PŒê"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "—Bˆê‚ÌŠY“–"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "%d ”Ô–Ú‚ÌŠY“– (‘SŠY“– %d ŒÂ’†)"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "%d ”Ô–Ú‚ÌŠY“–"
-
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: —\\Šú‚¹‚Ê•¶Žš‚ª :let ‚É‚ ‚è‚Ü‚µ‚½"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: ƒŠƒXƒg‚̃Cƒ“ƒfƒbƒNƒX‚ª”͈͊O‚Å‚·: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: –¢’è‹`‚̕ϔ‚Å‚·: %s"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: ']' ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s ‚̈ø”‚ÍƒŠƒXƒgŒ^‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s ‚̈ø”‚ÍƒŠƒXƒgŒ^‚Ü‚½‚ÍŽ«‘Œ^‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Ž«‘Œ^‚É‹ó‚̃L[‚ðŽg‚¤‚±‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: ƒŠƒXƒgŒ^‚ª•K—v‚Å‚·"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Ž«‘Œ^‚ª•K—v‚Å‚·"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: ŠÖ”‚̈ø”‚ª‘½‰ß‚¬‚Ü‚·: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Ž«‘Œ^‚ɃL[‚ª‘¶Ý‚µ‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: ŠÖ” %s ‚Í’è‹`ςł·, Ä’è‹`‚·‚é‚É‚Í ! ‚ð’ljÁ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Ž«‘Œ^“à‚ɃGƒ“ƒgƒŠ‚ªŠù‚É‘¶Ý‚µ‚Ü‚·"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: ŠÖ”ŽQÆŒ^‚ª—v‹‚³‚ê‚Ü‚·"
-
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: [:] ‚ðŽ«‘Œ^‚Æ‘g‚݇‚킹‚Ă͎g‚¦‚Ü‚¹‚ñ"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: ˆÙ‚È‚Á‚½Œ^‚̕ϔ‚Å‚· %s="
-
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: –¢’m‚ÌŠÖ”‚Å‚·: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: •s³‚ȕϔ–¼‚Å‚·: %s"
-
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: •‚“®¬”“_”‚ð•¶Žš—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: ƒ^[ƒQƒbƒg‚ªƒŠƒXƒgŒ^“à‚Ì—v‘f‚æ‚è‚à­‚È‚¢‚Å‚·"
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: ƒ^[ƒQƒbƒg‚ªƒŠƒXƒgŒ^“à‚Ì—v‘f‚æ‚è‚à‘½‚¢‚Å‚·"
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "ƒŠƒXƒgŒ^‚Ì’l‚É2‚ˆÈã‚Ì ; ‚ªŒŸo‚³‚ê‚Ü‚µ‚½"
-
-#: ../eval.c:2078
-#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: %s ‚Ì’l‚ðˆê——•\\ަ‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: ƒŠƒXƒgŒ^‚ÆŽ«‘Œ^ˆÈŠO‚̓Cƒ“ƒfƒbƒNƒXŽw’è‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:] ‚ÍÅŒã‚łȂ¯‚ê‚΂¢‚¯‚Ü‚¹‚ñ"
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:] ‚É‚ÍƒŠƒXƒgŒ^‚Ì’l‚ª•K—v‚Å‚·"
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: ƒŠƒXƒgŒ^•Ï”‚Ƀ^[ƒQƒbƒg‚æ‚è‚à‘½‚¢—v‘f‚ª‚ ‚è‚Ü‚·"
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: ƒŠƒXƒgŒ^•Ï”‚É\\•ª‚È”‚Ì—v‘f‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: :for ‚ÌŒã‚É \"in\" ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: ƒJƒbƒR '(' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: ‚»‚̕ϔ‚Í‚ ‚è‚Ü‚¹‚ñ: \"%s\""
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: (ƒAƒ“)ƒƒbƒN‚·‚é‚ɂ͕ϔ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: '?' ‚ÌŒã‚É ':' ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: ƒŠƒXƒgŒ^‚ÍƒŠƒXƒgŒ^‚Æ‚µ‚©”äŠr‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: ƒŠƒXƒgŒ^‚ɂ͖³Œø‚È‘€ì‚Å‚·"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: Ž«‘Œ^‚ÍŽ«‘Œ^‚Æ‚µ‚©”äŠr‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: Ž«‘Œ^‚ɂ͖³Œø‚È‘€ì‚Å‚·"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: ŠÖ”ŽQÆŒ^‚ÍŠÖ”ŽQÆŒ^‚Æ‚µ‚©”äŠr‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: ŠÖ”ŽQÆŒ^‚ɂ͖³Œø‚È‘€ì‚Å‚·"
-
-#: ../eval.c:4277
-msgid "E804: Cannot use '%' with Float"
-msgstr "E804: '%' ‚ð•‚“®¬”“_”‚Æ‘g‚݇‚킹‚Ă͎g‚¦‚Ü‚¹‚ñ"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: ')' ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: ŠÖ”ŽQÆŒ^‚̓Cƒ“ƒfƒbƒNƒX‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: ƒIƒvƒVƒ‡ƒ“–¼‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: –¢’m‚̃IƒvƒVƒ‡ƒ“‚Å‚·: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: ˆø—p•„ (\") ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: ˆø—p•„ (') ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: ƒŠƒXƒgŒ^‚ɃJƒ“ƒ}‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: ƒŠƒXƒgŒ^‚ÌÅŒã‚É ']' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-msgid "Not enough memory to set references, garbage collection aborted!"
-msgstr ""
-"ƒK[ƒxƒbƒWƒRƒŒƒNƒVƒ‡ƒ“‚𒆎~‚µ‚Ü‚µ‚½! ŽQÆ‚ð쬂·‚é‚̂Ƀƒ‚ƒŠ‚ª•s‘«‚µ‚Ü‚µ‚½"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Ž«‘Œ^‚ɃRƒƒ“‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Ž«‘Œ^‚Éd•¡ƒL[‚ª‚ ‚è‚Ü‚·: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Ž«‘Œ^‚ɃJƒ“ƒ}‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Ž«‘Œ^‚ÌÅŒã‚É '}' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: •\\ަ‚·‚é‚ɂ͕ϔ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
-
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: ŠÖ”‚̈ø”‚ª‘½‰ß‚¬‚Ü‚·: %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: ŠÖ”‚Ì–³Œø‚Ȉø”‚Å‚·: %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: –¢’m‚ÌŠÖ”‚Å‚·: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: ŠÖ”‚̈ø”‚ª‘«‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: ƒXƒNƒŠƒvƒgˆÈŠO‚Å<SID>‚ªŽg‚í‚ê‚Ü‚µ‚½: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Ž«‘—pŠÖ”‚ªŒÄ‚΂ê‚Ü‚µ‚½‚ªŽ«‘‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: ”’l‚©•‚“®¬”“_”‚ª•K—v‚Å‚·"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "add() ‚̈ø”"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: ˆø”‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() ‚Í‘}“üƒ‚[ƒh‚Å‚µ‚©—˜—p‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: ƒL[‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "extend() ‚̈ø”"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "map() ‚̈ø”"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "filter() ‚̈ø”"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld s: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: –¢’m‚ÌŠÖ”‚Å‚·: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "inputrestore() ‚ª inputsave() ‚æ‚è‚à‘½‚­ŒÄ‚΂ê‚Ü‚µ‚½"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "insert() ‚̈ø”"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: ”͈͎w’è‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: len() ‚ɂ͖³Œø‚ÈŒ^‚Å‚·"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: ƒXƒgƒ‰ƒCƒh(‘Oi—Ê)‚ª 0 ‚Å‚·"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: ŠJŽnˆÊ’u‚ªI—¹ˆÊ’u‚ð‰z‚¦‚Ü‚µ‚½"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<‹ó>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "remove() ‚̈ø”"
-
-# Added at 10-Mar-2004.
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: ƒVƒ“ƒ{ƒŠƒbƒNƒŠƒ“ƒN‚ª‘½‰ß‚¬‚Ü‚· (zŠÂ‚µ‚Ä‚¢‚é‰Â”\\«‚ª‚ ‚è‚Ü‚·)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "reverse() ‚̈ø”"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "sort() ‚̈ø”"
-
-#: ../eval.c:13721
-msgid "uniq() argument"
-msgstr "uniq() ‚̈ø”"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: ƒ\\[ƒg‚Ì”äŠrŠÖ”‚ªŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../eval.c:13806
-msgid "E882: Uniq compare function failed"
-msgstr "E882: Uniq ‚Ì”äŠrŠÖ”‚ªŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(–³Œø)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: ˆêŽžƒtƒ@ƒCƒ‹‘ž’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: •‚“®¬”“_”‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: ŠÖ”ŽQÆŒ^‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·B"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: ƒŠƒXƒgŒ^‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Ž«‘Œ^‚ð”’l‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-msgid "E891: Using a Funcref as a Float"
-msgstr "E891: ŠÖ”ŽQÆŒ^‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·B"
-
-msgid "E892: Using a String as a Float"
-msgstr "E892: •¶Žš—ñ‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-msgid "E893: Using a List as a Float"
-msgstr "E893: ƒŠƒXƒgŒ^‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-msgid "E894: Using a Dictionary as a Float"
-msgstr "E894: Ž«‘Œ^‚ð•‚“®¬”“_”‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: ŠÖ”ŽQÆŒ^‚ð•¶Žš—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: ƒŠƒXƒgŒ^‚ð•¶Žš—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Ž«‘Œ^‚ð•¶Žš—ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: •Ï”‚ÌŒ^‚ªˆê’v‚µ‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: •Ï” %s ‚ð휂ł«‚Ü‚¹‚ñ"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: ŠÖ”ŽQÆŒ^•Ï”–¼‚Í‘å•¶Žš‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: •Ï”–¼‚ªŠù‘¶‚ÌŠÖ”–¼‚ÆÕ“Ë‚µ‚Ü‚·: %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: ’l‚ªƒƒbƒN‚³‚ê‚Ä‚¢‚Ü‚·: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "•s–¾"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: %s ‚Ì’l‚ð•ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: ƒRƒs[‚ðŽæ‚é‚ɂ͕ϔ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: –¢’è‹`‚ÌŠÖ”‚Å‚·: %s"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: '(' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: ‚±‚±‚Å‚Í g: ‚ÍŽg‚¦‚Ü‚¹‚ñ"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: •s³‚Ȉø”‚Å‚·: %s"
-
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: ˆø”–¼‚ªd•¡‚µ‚Ä‚¢‚Ü‚·: %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunction ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: ŠÖ”–¼‚ª•Ï”–¼‚ÆÕ“Ë‚µ‚Ü‚·: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: ŠÖ” %s ‚ðÄ’è‹`‚Å‚«‚Ü‚¹‚ñ: Žg—p’†‚Å‚·"
-
-#: ../eval.c:17604
-#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: ŠÖ”–¼‚ªƒXƒNƒŠƒvƒg‚̃tƒ@ƒCƒ‹–¼‚ƈê’v‚µ‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: ŠÖ”–¼‚ª—v‹‚³‚ê‚Ü‚·"
-
-#: ../eval.c:17824
-#, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: ŠÖ”–¼‚Í‘å•¶Žš‚© \"s:\" ‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:17833
-#, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E884: ŠÖ”–¼‚ɂ̓Rƒƒ“‚͊܂߂ç‚ê‚Ü‚¹‚ñ: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: ŠÖ” %s ‚ð휂ł«‚Ü‚¹‚ñ: Žg—p’†‚Å‚·"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: ŠÖ”ŒÄo‚Ì“ü‚êŽq”‚ª 'maxfuncdepth' ‚ð’´‚¦‚Ü‚µ‚½"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "%s ‚ðŽÀs’†‚Å‚·"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ‚ª’†’f‚³‚ê‚Ü‚µ‚½"
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ‚ª #%<PRId64> ‚ð•Ô‚µ‚Ü‚µ‚½"
-
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%s ‚ª %s ‚ð•Ô‚µ‚Ü‚µ‚½"
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "%s ‚ÌŽÀs‚ðŒp‘±’†‚Å‚·"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: ŠÖ”ŠO‚É :return ‚ª‚ ‚è‚Ü‚µ‚½"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# ƒOƒ[ƒoƒ‹•Ï”:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tLast set from "
-
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "ŒÃ‚¢ƒtƒ@ƒCƒ‹‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, 16i” %02x, 8i” %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, 16i” %04x, 8i” %o"
-
-#: ../ex_cmds.c:146
-#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, 16i” %08x, 8i” %o"
-
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: s‚ð‚»‚êŽ©g‚ɂ͈ړ®‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "1 s‚ªˆÚ“®‚³‚ê‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> s‚ªˆÚ“®‚³‚ê‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> s‚ªƒtƒBƒ‹ƒ^ˆ—‚³‚ê‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: *ƒtƒBƒ‹ƒ^* autocommand‚ÍŒ»Ý‚̃oƒbƒtƒ@‚ð•ÏX‚µ‚Ă͂¢‚¯‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[ÅŒã‚Ì•ÏX‚ª•Û‘¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ]\n"
-
-#: ../ex_cmds.c:1424
-#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s s–Ú: "
-
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: ƒGƒ‰[‚ª‘½‰ß‚¬‚é‚Ì‚Å, ˆÈ~‚̓XƒLƒbƒv‚µ‚Ü‚·"
-
-#: ../ex_cmds.c:1458
-#, c-format
-msgid "Reading viminfo file \"%s\"%s%s%s"
-msgstr "viminfoƒtƒ@ƒCƒ‹ \"%s\"%s%s%s ‚ð“Çž‚Ý’†"
-
-#: ../ex_cmds.c:1460
-msgid " info"
-msgstr " î•ñ"
-
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " ƒ}[ƒN"
-
-#: ../ex_cmds.c:1462
-msgid " oldfiles"
-msgstr " ‹Œƒtƒ@ƒCƒ‹ŒQ"
-
-#: ../ex_cmds.c:1463
-msgid " FAILED"
-msgstr " ޏ”s"
-
-#. 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ƒtƒ@ƒCƒ‹‚ª‘ž‚݂ł«‚Ü‚¹‚ñ: %s"
-
-#: ../ex_cmds.c:1626
-#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: viminfoƒtƒ@ƒCƒ‹ %s ‚ð•Û‘¶‚Å‚«‚Ü‚¹‚ñ!"
-
-#: ../ex_cmds.c:1635
-#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "viminfoƒtƒ@ƒCƒ‹ \"%s\" ‚𑞂ݒ†"
-
-#. Write the info:
-#: ../ex_cmds.c:1720
-#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# ‚±‚Ì viminfo ƒtƒ@ƒCƒ‹‚Í Vim %s ‚É‚æ‚Á‚ͬ‚³‚ê‚Ü‚µ‚½.\n"
-
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# •ÏX‚·‚éÛ‚É‚Í\\•ª’ˆÓ‚µ‚Ä‚­‚¾‚³‚¢!\n"
-"\n"
-
-#: ../ex_cmds.c:1723
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# ‚±‚̃tƒ@ƒCƒ‹‚ª‘‚©‚ê‚½Žž‚Ì 'encoding' ‚Ì’l\n"
-
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "•s³‚Èæ“ª•¶Žš‚Å‚·"
-
-#: ../ex_cmds.c:2162
-msgid "Write partial file?"
-msgstr "ƒtƒ@ƒCƒ‹‚ð•”•ª“I‚ɕۑ¶‚µ‚Ü‚·‚©?"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: ƒoƒbƒtƒ@‚ð•”•ª“I‚ɕۑ¶‚·‚é‚É‚Í ! ‚ðŽg‚Á‚Ä‚­‚¾‚³‚¢"
-
-#: ../ex_cmds.c:2281
-#, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "Šù‘¶‚̃tƒ@ƒCƒ‹ \"%s\" ‚ðã‘‚«‚µ‚Ü‚·‚©?"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹ \"%s\" ‚ª‘¶Ý‚µ‚Ü‚·. ã‘‚«‚ð‹­§‚µ‚Ü‚·‚©?"
-
-#: ../ex_cmds.c:2326
-#, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E768: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª‘¶Ý‚µ‚Ü‚·: %s (:silent! ‚ð’ljÁ‚Åã‘)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: ƒoƒbƒtƒ@ %<PRId64> ‚ɂ͖¼‘O‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: ƒtƒ@ƒCƒ‹‚͕ۑ¶‚³‚ê‚Ü‚¹‚ñ‚Å‚µ‚½: 'write' ƒIƒvƒVƒ‡ƒ“‚É‚æ‚è–³Œø‚Å‚·"
-
-#: ../ex_cmds.c:2434
-#, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"\"%s\" ‚É‚Í 'readonly' ƒIƒvƒVƒ‡ƒ“‚ªÝ’肳‚ê‚Ä‚¢‚Ü‚·.\n"
-"ã‘‚«‹­§‚ð‚µ‚Ü‚·‚©?"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-"ƒtƒ@ƒCƒ‹ \"%s\" ‚̃p[ƒ~ƒbƒVƒ‡ƒ“‚ª“Çžê—p‚Å‚·.\n"
-"‚»‚ê‚Å‚à‹°‚ç‚­‘‚«ž‚Þ‚±‚Ƃ͉”\\‚Å‚·.\n"
-"Œp‘±‚µ‚Ü‚·‚©?"
-
-#: ../ex_cmds.c:2451
-#, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "E505: \"%s\" ‚͓Ǟê—p‚Å‚· (‹­§‘ž‚É‚Í ! ‚ð’ljÁ)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: autocommand‚ª—\\Šú‚¹‚¸V‚µ‚¢ƒoƒbƒtƒ@ %s ‚ð휂µ‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: ”‚ł͂Ȃ¢ˆø”‚ª :z ‚É“n‚³‚ê‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: rvim‚ł̓VƒFƒ‹ƒRƒ}ƒ“ƒh‚ðŽg‚¦‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: ³‹K•\\Œ»‚Í•¶Žš‚Å‹æØ‚é‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:3964
-#, c-format
-msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
-msgstr "%s ‚É’uŠ·‚µ‚Ü‚·‚©? (y/n/a/q/l/^E/^Y)"
-
-#: ../ex_cmds.c:4379
-msgid "(Interrupted) "
-msgstr "(Š„ž‚Ü‚ê‚Ü‚µ‚½) "
-
-#: ../ex_cmds.c:4384
-msgid "1 match"
-msgstr "1 ‰ÓŠŠY“–‚µ‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "1 ‰ÓŠ’uŠ·‚µ‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:4387
-#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> ‰ÓŠŠY“–‚µ‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> ‰ÓŠ’uŠ·‚µ‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr " (Œv 1 s“à)"
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr " (Œv %<PRId64> s“à)"
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global ‚ðÄ‹A“I‚ɂ͎g‚¦‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: globalƒRƒ}ƒ“ƒh‚ɳ‹K•\\Œ»‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:4508
-#, c-format
-msgid "Pattern found in every line: %s"
-msgstr "ƒpƒ^[ƒ“‚ª‘S‚Ä‚Ìs‚ÅŒ©‚‚©‚è‚Ü‚µ‚½: %s"
-
-#: ../ex_cmds.c:4510
-#, c-format
-msgid "Pattern not found: %s"
-msgstr "ƒpƒ^[ƒ“‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½: %s"
-
-#: ../ex_cmds.c:4587
-msgid ""
-"\n"
-"# Last Substitute String:\n"
-"$"
-msgstr ""
-"\n"
-"# ÅŒã‚É’uŠ·‚³‚ꂽ•¶Žš—ñ:\n"
-"$"
-
-#: ../ex_cmds.c:4679
-msgid "E478: Don't panic!"
-msgstr "E478: Q‚ĂȂ¢‚Å‚­‚¾‚³‚¢"
-
-#: ../ex_cmds.c:4717
-#, c-format
-msgid "E661: Sorry, no '%s' help for %s"
-msgstr "E661: Žc”O‚Å‚·‚ª '%s' ‚̃wƒ‹ƒv‚ª %s ‚ɂ͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:4719
-#, c-format
-msgid "E149: Sorry, no help for %s"
-msgstr "E149: Žc”O‚Å‚·‚ª %s ‚ɂ̓wƒ‹ƒv‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:4751
-#, c-format
-msgid "Sorry, help file \"%s\" not found"
-msgstr "Žc”O‚Å‚·‚ªƒwƒ‹ƒvƒtƒ@ƒCƒ‹ \"%s\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:5323
-#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: ƒfƒBƒŒƒNƒgƒŠ‚ł͂ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../ex_cmds.c:5446
-#, c-format
-msgid "E152: Cannot open %s for writing"
-msgstr "E152: ‘ž‚Ý—p‚É %s ‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../ex_cmds.c:5471
-#, c-format
-msgid "E153: Unable to open %s for reading"
-msgstr "E153: “Çž—p‚É %s ‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-# Added at 29-Apr-2004.
-#: ../ex_cmds.c:5500
-#, c-format
-msgid "E670: Mix of help file encodings within a language: %s"
-msgstr "E670: 1‚‚̌¾Œê‚̃wƒ‹ƒvƒtƒ@ƒCƒ‹‚É•¡”‚̃Gƒ“ƒR[ƒh‚ª¬Ý‚µ‚Ä‚¢‚Ü‚·: %s"
-
-#: ../ex_cmds.c:5565
-#, c-format
-msgid "E154: Duplicate tag \"%s\" in file %s/%s"
-msgstr "E154: ƒ^ƒO \"%s\" ‚ªƒtƒ@ƒCƒ‹ %s/%s ‚Éd•¡‚µ‚Ä‚¢‚Ü‚·"
-
-#: ../ex_cmds.c:5687
-#, c-format
-msgid "E160: Unknown sign command: %s"
-msgstr "E160: –¢’m‚ÌsignƒRƒ}ƒ“ƒh‚Å‚·: %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: sign‚Ì’è‹`‚ª‘½”Œ©‚‚©‚è‚Ü‚µ‚½"
-
-#: ../ex_cmds.c:5813
-#, c-format
-msgid "E239: Invalid sign text: %s"
-msgstr "E239: –³Œø‚Èsign‚̃eƒLƒXƒg‚Å‚·: %s"
-
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
-#, c-format
-msgid "E155: Unknown sign: %s"
-msgstr "E155: –¢’m‚Ì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: –³Œø‚ȃoƒbƒtƒ@–¼‚Å‚·: %s"
-
-#: ../ex_cmds.c:6008
-#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: –³Œø‚Èsignޝ•ÊŽq‚Å‚·: %<PRId64>"
-
-#, c-format
-msgid "E885: Not possible to change sign %s"
-msgstr "E885: •ÏX‚Å‚«‚È‚¢ sign ‚Å‚·: %s"
-
-#: ../ex_cmds.c:6066
-msgid " (not supported)"
-msgstr " (”ñƒTƒ|[ƒg)"
-
-#: ../ex_cmds.c:6169
-msgid "[Deleted]"
-msgstr "[íœÏ]"
-
-#: ../ex_cmds2.c:139
-msgid "Entering Debug mode. Type \"cont\" to continue."
-msgstr "ƒfƒoƒbƒOƒ‚[ƒh‚É“ü‚è‚Ü‚·. ‘±‚¯‚é‚É‚Í \"cont\" ‚Æ“ü—Í‚µ‚Ä‚­‚¾‚³‚¢."
-
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
-#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "s %<PRId64>: %s"
-
-#: ../ex_cmds2.c:145
-#, c-format
-msgid "cmd: %s"
-msgstr "ƒRƒ}ƒ“ƒh: %s"
-
-msgid "frame is zero"
-msgstr "ƒtƒŒ[ƒ€‚ª 0 ‚Å‚·"
-
-#, c-format
-msgid "frame at highest level: %d"
-msgstr "Å‚ƒŒƒxƒ‹‚̃tƒŒ[ƒ€: %d"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "ƒuƒŒ[ƒNƒ|ƒCƒ“ƒg \"%s%s\" s %<PRId64>"
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: ƒuƒŒ[ƒNƒ|ƒCƒ“ƒg‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "ƒuƒŒ[ƒNƒ|ƒCƒ“ƒg‚ª’è‹`‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s s %<PRId64>"
-
-#: ../ex_cmds2.c:942
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: ‰‚ß‚É \":profile start {fname}\" ‚ðŽÀs‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../ex_cmds2.c:1269
-#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "•ÏX‚ð \"%s\" ‚ɕۑ¶‚µ‚Ü‚·‚©?"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "–³‘è"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: ƒoƒbƒtƒ@ \"%s\" ‚Ì•ÏX‚͕ۑ¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../ex_cmds2.c:1480
-msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
-msgstr "Œx: —\\Šú‚¹‚¸‘¼ƒoƒbƒtƒ@‚ÖˆÚ“®‚µ‚Ü‚µ‚½ (autocommands ‚𒲂ׂĂ­‚¾‚³‚¢)"
-
-#: ../ex_cmds2.c:1826
-msgid "E163: There is only one file to edit"
-msgstr "E163: •ÒW‚·‚éƒtƒ@ƒCƒ‹‚Í1‚‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_cmds2.c:1828
-msgid "E164: Cannot go before first file"
-msgstr "E164: ʼn‚̃tƒ@ƒCƒ‹‚æ‚è‘O‚É‚Ís‚¯‚Ü‚¹‚ñ"
-
-#: ../ex_cmds2.c:1830
-msgid "E165: Cannot go beyond last file"
-msgstr "E165: ÅŒã‚̃tƒ@ƒCƒ‹‚ð‰z‚¦‚ÄŒã‚É‚Ís‚¯‚Ü‚¹‚ñ"
-
-#: ../ex_cmds2.c:2175
-#, c-format
-msgid "E666: compiler not supported: %s"
-msgstr "E666: ‚»‚̃Rƒ“ƒpƒCƒ‰‚ɂ͑Ήž‚µ‚Ä‚¢‚Ü‚¹‚ñ: %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 "ƒfƒBƒŒƒNƒgƒŠ‚͎枂߂܂¹‚ñ: \"%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 "s %<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 "s %<PRId64>: %s ‚ðŽæž’†"
-
-#: ../ex_cmds2.c:2693
-#, c-format
-msgid "finished sourcing %s"
-msgstr "%s ‚ÌŽæž‚ðŠ®—¹"
-
-#: ../ex_cmds2.c:2765
-msgid "modeline"
-msgstr "ƒ‚[ƒhs"
-
-#: ../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 "ƒGƒ‰[ƒnƒ“ƒhƒ‰"
-
-#: ../ex_cmds2.c:3020
-msgid "W15: Warning: Wrong line separator, ^M may be missing"
-msgstr "W15: Œx: s‹æØ‚ª•s³‚Å‚·. ^M ‚ª‚È‚¢‚̂łµ‚傤"
-
-#: ../ex_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: :scriptencoding ‚ªŽæžƒXƒNƒŠƒvƒgˆÈŠO‚ÅŽg—p‚³‚ê‚Ü‚µ‚½"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: :finish ‚ªŽæžƒXƒNƒŠƒvƒgˆÈŠO‚ÅŽg—p‚³‚ê‚Ü‚µ‚½"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "Œ»Ý‚Ì %sŒ¾Œê: \"%s\""
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: Œ¾Œê‚ð \"%s\" ‚ÉÝ’è‚Å‚«‚Ü‚¹‚ñ"
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr ""
-"Exƒ‚[ƒh‚É“ü‚è‚Ü‚·. ƒm[ƒ}ƒ‹ƒ‚[ƒh‚É–ß‚é‚É‚Í\"visual\"‚Æ“ü—Í‚µ‚Ä‚­‚¾‚³‚¢."
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: ƒtƒ@ƒCƒ‹‚ÌI—¹ˆÊ’u"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: ƒRƒ}ƒ“ƒh‚ªÄ‹A“I‰ß‚¬‚Ü‚·"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: —áŠO‚ª•ß‘¨‚³‚ê‚Ü‚¹‚ñ‚Å‚µ‚½: %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "Žæžƒtƒ@ƒCƒ‹‚ÌÅŒã‚Å‚·"
-
-#: ../ex_docmd.c:1086
-msgid "End of function"
-msgstr "ŠÖ”‚ÌÅŒã‚Å‚·"
-
-#: ../ex_docmd.c:1628
-msgid "E464: Ambiguous use of user-defined command"
-msgstr "E464: ƒ†[ƒU[’è‹`ƒRƒ}ƒ“ƒh‚Ì‚ ‚¢‚Ü‚¢‚ÈŽg—p‚Å‚·"
-
-#: ../ex_docmd.c:1638
-msgid "E492: Not an editor command"
-msgstr "E492: ƒGƒfƒBƒ^‚̃Rƒ}ƒ“ƒh‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:1729
-msgid "E493: Backwards range given"
-msgstr "E493: ‹t‚³‚܂͈̔͂ªŽw’肳‚ê‚Ü‚µ‚½"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "‹t‚³‚܂͈̔͂ªŽw’肳‚ê‚Ü‚µ‚½, “ü‘Ö‚¦‚Ü‚·‚©?"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: w ‚à‚µ‚­‚Í w>> ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: ‚±‚̃o[ƒWƒ‡ƒ“‚ł͂±‚̃Rƒ}ƒ“ƒh‚Í—˜—p‚Å‚«‚Ü‚¹‚ñ, ‚²‚ß‚ñ‚È‚³‚¢"
-
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: ƒtƒ@ƒCƒ‹–¼‚Í 1 ‚‚ɂµ‚Ä‚­‚¾‚³‚¢"
-
-#: ../ex_docmd.c:4238
-msgid "1 more file to edit. Quit anyway?"
-msgstr "•ÒW‚·‚ׂ«ƒtƒ@ƒCƒ‹‚ª 1 ŒÂ‚ ‚è‚Ü‚·‚ª, I—¹‚µ‚Ü‚·‚©?"
-
-#: ../ex_docmd.c:4242
-#, c-format
-msgid "%d more files to edit. Quit anyway?"
-msgstr "•ÒW‚·‚ׂ«ƒtƒ@ƒCƒ‹‚ª‚ ‚Æ %d ŒÂ‚ ‚è‚Ü‚·‚ª, I—¹‚µ‚Ü‚·‚©?"
-
-#: ../ex_docmd.c:4248
-msgid "E173: 1 more file to edit"
-msgstr "E173: •ÒW‚·‚ׂ«ƒtƒ@ƒCƒ‹‚ª 1 ŒÂ‚ ‚è‚Ü‚·"
-
-#: ../ex_docmd.c:4250
-#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: •ÒW‚·‚ׂ«ƒtƒ@ƒCƒ‹‚ª‚ ‚Æ %<PRId64> ŒÂ‚ ‚è‚Ü‚·"
-
-#: ../ex_docmd.c:4320
-msgid "E174: Command already exists: add ! to replace it"
-msgstr "E174: ƒRƒ}ƒ“ƒh‚ªŠù‚É‚ ‚è‚Ü‚·: Ä’è‹`‚·‚é‚É‚Í ! ‚ð’ljÁ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../ex_docmd.c:4432
-msgid ""
-"\n"
-" Name Args Address Complete Definition"
-msgstr ""
-"\n"
-" –¼‘O ˆø” ƒAƒhƒŒƒX •⊮ ’è‹`"
-
-#: ../ex_docmd.c:4516
-msgid "No user-defined commands found"
-msgstr "ƒ†[ƒU[’è‹`ƒRƒ}ƒ“ƒh‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../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: ƒJƒEƒ“ƒg‚ð2dŽw’è‚·‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:4603
-msgid "E178: Invalid default value for count"
-msgstr "E178: ƒJƒEƒ“ƒg‚ÌÈ—ª’l‚ª–³Œø‚Å‚·"
-
-#: ../ex_docmd.c:4625
-msgid "E179: argument required for -complete"
-msgstr "E179: -complete ‚ɂ͈ø”‚ª•K—v‚Å‚·"
-
-msgid "E179: argument required for -addr"
-msgstr "E179: -addr ‚ɂ͈ø”‚ª•K—v‚Å‚·"
-
-#: ../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: –³Œø‚ȃRƒ}ƒ“ƒh–¼‚Å‚·"
-
-#: ../ex_docmd.c:4691
-msgid "E183: User defined commands must start with an uppercase letter"
-msgstr "E183: ƒ†[ƒU[’è‹`ƒRƒ}ƒ“ƒh‚͉p‘å•¶Žš‚ÅŽn‚Ü‚ç‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:4696
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E841: —\\–ñ–¼‚Ȃ̂Å, ƒ†[ƒU[’è‹`ƒRƒ}ƒ“ƒh‚É—˜—p‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: ‚»‚̃†[ƒU[’è‹`ƒRƒ}ƒ“ƒh‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#, c-format
-msgid "E180: Invalid address type value: %s"
-msgstr "E180: –³Œø‚ȃAƒhƒŒƒXƒ^ƒCƒv’l‚Å‚·: %s"
-
-#: ../ex_docmd.c:5219
-#, c-format
-msgid "E180: Invalid complete value: %s"
-msgstr "E180: –³Œø‚ȕ⊮Žw’è‚Å‚·: %s"
-
-#: ../ex_docmd.c:5225
-msgid "E468: Completion argument only allowed for custom completion"
-msgstr "E468: •⊮ˆø”‚̓JƒXƒ^ƒ€•⊮‚Å‚µ‚©Žg—p‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:5231
-msgid "E467: Custom completion requires a function argument"
-msgstr "E467: ƒJƒXƒ^ƒ€•⊮‚ɂ͈ø”‚Æ‚µ‚ÄŠÖ”‚ª•K—v‚Å‚·"
-
-#: ../ex_docmd.c:5257
-#, c-format
-msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: ƒJƒ‰[ƒXƒL[ƒ€ '%s' ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "Vim Žg‚¢‚³‚ñA‚â‚ !"
-
-#: ../ex_docmd.c:5431
-msgid "E784: Cannot close last tab page"
-msgstr "E784: ÅŒã‚̃^ƒuƒy[ƒW‚ð•‚¶‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:5462
-msgid "Already only one tab page"
-msgstr "Šù‚Ƀ^ƒuƒy[ƒW‚Í1‚‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:6004
-#, c-format
-msgid "Tab page %d"
-msgstr "ƒ^ƒuƒy[ƒW %d"
-
-#: ../ex_docmd.c:6295
-msgid "No swap file"
-msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:6478
-msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
-msgstr ""
-"E747: ƒoƒbƒtƒ@‚ªC³‚³‚ê‚Ä‚¢‚é‚Ì‚Å, ƒfƒBƒŒƒNƒgƒŠ‚ð•ÏX‚Å‚«‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å"
-"ã‘)"
-
-#: ../ex_docmd.c:6485
-msgid "E186: No previous directory"
-msgstr "E186: ‘O‚̃fƒBƒŒƒNƒgƒŠ‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: –¢’m"
-
-#: ../ex_docmd.c:6610
-msgid "E465: :winsize requires two number arguments"
-msgstr "E465: :winsize ‚É‚Í2‚‚̔’l‚̈ø”‚ª•K—v‚Å‚·"
-
-#: ../ex_docmd.c:6655
-msgid "E188: Obtaining window position not implemented for this platform"
-msgstr ""
-"E188: ‚±‚̃vƒ‰ƒbƒgƒz[ƒ€‚ɂ̓EƒBƒ“ƒhƒEˆÊ’u‚̎擾‹@”\\‚ÍŽÀ‘•‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:6662
-msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos ‚É‚Í2‚‚̔’l‚̈ø”‚ª•K—v‚Å‚·"
-
-#: ../ex_docmd.c:7241
-#, c-format
-msgid "E739: Cannot create directory: %s"
-msgstr "E739: ƒfƒBƒŒƒNƒgƒŠ‚ð쬂ł«‚Ü‚¹‚ñ: %s"
-
-#: ../ex_docmd.c:7268
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: \"%s\" ‚ª‘¶Ý‚µ‚Ü‚· (ã‘‚·‚é‚É‚Í ! ‚ð’ljÁ‚µ‚Ä‚­‚¾‚³‚¢)"
-
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: \"%s\" ‚𑞂ݗp‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñ"
-
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: ˆø”‚Í1•¶Žš‚̉pŽš‚©ˆø—p•„ (' ‚© `) ‚łȂ¯‚ê‚΂¢‚¯‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: :normal ‚ÌÄ‹A—˜—p‚ª[‚­‚È‚è‰ß‚¬‚Ü‚µ‚½"
-
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: '#'‚ð’u‚«Š·‚¦‚é•›ƒtƒ@ƒCƒ‹‚Ì–¼‘O‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: \"<afile>\"‚ð’u‚«Š·‚¦‚éautocommand‚̃tƒ@ƒCƒ‹–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: \"<abuf>\"‚ð’u‚«Š·‚¦‚éautocommandƒoƒbƒtƒ@”Ô†‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:7861
-msgid "E497: no autocommand match name to substitute for \"<amatch>\""
-msgstr "E497: \"<amatch>\"‚ð’u‚«Š·‚¦‚éautocommand‚ÌŠY“––¼‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:7870
-msgid "E498: no :source file name to substitute for \"<sfile>\""
-msgstr "E498: \"<sfile>\"‚ð’u‚«Š·‚¦‚é :source ‘ÎÛƒtƒ@ƒCƒ‹–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:7876
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E842: \"<slnum>\"‚ð’u‚«Š·‚¦‚és”Ô†‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr ""
-"E499: '%' ‚â '#' ‚ª–³–¼ƒtƒ@ƒCƒ‹‚Ȃ̂Š\":p:h\" ‚𔺂í‚È‚¢Žg‚¢•û‚͂ł«‚Ü‚¹‚ñ"
-
-#: ../ex_docmd.c:7905
-msgid "E500: Evaluates to an empty string"
-msgstr "E500: ‹ó•¶Žš—ñ‚Æ‚µ‚Ä•]‰¿‚³‚ê‚Ü‚µ‚½"
-
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: viminfoƒtƒ@ƒCƒ‹‚ð“Çž—p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../ex_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: 'Vim' ‚ÅŽn‚Ü‚é—áŠO‚Í :throw ‚Å‚«‚Ü‚¹‚ñ"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "—áŠO‚ª”­¶‚µ‚Ü‚µ‚½: %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "—áŠO‚ªŽû‘©‚µ‚Ü‚µ‚½: %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "—áŠO‚ª”jŠü‚³‚ê‚Ü‚µ‚½: %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, s %<PRId64>"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "—áŠO‚ª•ß‘¨‚³‚ê‚Ü‚µ‚½: %s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr "%s ‚É‚æ‚è–¢Œˆ’èó‘Ô‚ª¶‚¶‚Ü‚µ‚½"
-
-#: ../ex_eval.c:679
-#, c-format
-msgid "%s resumed"
-msgstr "%s ‚ªÄŠJ‚µ‚Ü‚µ‚½"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr "%s ‚ª”jŠü‚³‚ê‚Ü‚µ‚½"
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "—áŠO"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "ƒGƒ‰[‚ÆŠ„ž‚Ý"
-
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "ƒGƒ‰["
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "Š„ž‚Ý"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: :if ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :if ‚̂Ȃ¢ :endif ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :if ‚̂Ȃ¢ :else ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :if ‚̂Ȃ¢ :elseif ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: •¡”‚Ì :else ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :else ‚ÌŒã‚É :elseif ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:941
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: :while ‚â :for ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
-
-#: ../ex_eval.c:1028
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :while ‚â :for ‚̂Ȃ¢ :continue ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:1061
-msgid "E587: :break without :while or :for"
-msgstr "E587: :while ‚â :for ‚̂Ȃ¢ :break ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:1102
-msgid "E732: Using :endfor with :while"
-msgstr "E732: :endfor ‚ð :while ‚Æ‘g‚݇‚킹‚Ä‚¢‚Ü‚·"
-
-#: ../ex_eval.c:1104
-msgid "E733: Using :endwhile with :for"
-msgstr "E733: :endwhile ‚ð :for ‚Æ‘g‚݇‚킹‚Ä‚¢‚Ü‚·"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: :try ‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
-
-#: ../ex_eval.c:1317
-msgid "E603: :catch without :try"
-msgstr "E603: :try ‚̂Ȃ¢ :catch ‚ª‚ ‚è‚Ü‚·"
-
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
-msgid "E604: :catch after :finally"
-msgstr "E604: :finally ‚ÌŒã‚É :catch ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :try ‚̂Ȃ¢ :finally ‚ª‚ ‚è‚Ü‚·"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: •¡”‚Ì :finally ‚ª‚ ‚è‚Ü‚·"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :try ‚̂Ȃ¢ :endtry ‚Å‚·"
-
-#: ../ex_eval.c:2026
-msgid "E193: :endfunction not inside a function"
-msgstr "E193: ŠÖ”‚ÌŠO‚É :endfunction ‚ª‚ ‚è‚Ü‚µ‚½"
-
-#: ../ex_getln.c:1643
-msgid "E788: Not allowed to edit another buffer now"
-msgstr "E788: Œ»Ý‚Í‘¼‚̃oƒbƒtƒ@‚ð•ÒW‚·‚邱‚Ƃ͋–‚³‚ê‚Ü‚¹‚ñ"
-
-#: ../ex_getln.c:1656
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E811: Œ»Ý‚̓oƒbƒtƒ@î•ñ‚ð•ÏX‚·‚邱‚Ƃ͋–‚³‚ê‚Ü‚¹‚ñ"
-
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "ƒ^ƒO–¼"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " ƒtƒ@ƒCƒ‹Ží—Þ\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "ƒIƒvƒVƒ‡ƒ“ 'history' ‚ªƒ[ƒ‚Å‚·"
-
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s €–Ú‚Ì—š—ð (V‚µ‚¢‚à‚Ì‚©‚çŒÃ‚¢‚à‚Ì‚Ö):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "ŒŸõ•¶Žš—ñ"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "Ž®"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "“ü—Ís"
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar ‚ªƒRƒ}ƒ“ƒh’·‚ð’´‚¦‚Ü‚µ‚½"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: ƒAƒNƒeƒBƒu‚ȃEƒBƒ“ƒhƒE‚©ƒoƒbƒtƒ@‚ªíœ‚³‚ê‚Ü‚µ‚½"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: ƒpƒX‚ª’·‰ß‚¬‚ĕ⊮‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: –³Œø‚ȃpƒX‚Å‚·: '**[”’l]' ‚Ípath‚ÌŌォ '%s' ‚ª‘±‚¢‚ĂȂ¢‚Æ‚¢‚¯‚Ü‚¹"
-"‚ñ."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpath‚É‚Í \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: path‚É‚Í \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: cdpath‚ɂ͂±‚êˆÈã \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: ƒpƒX‚ɂ͂±‚êˆÈã \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../fileio.c:137
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E812: autocommand‚ªƒoƒbƒtƒ@‚©ƒoƒbƒtƒ@–¼‚ð•ÏX‚µ‚Ü‚µ‚½"
-
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "•s³‚ȃtƒ@ƒCƒ‹–¼"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "‚̓fƒBƒŒƒNƒgƒŠ‚Å‚·"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "‚̓tƒ@ƒCƒ‹‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[Vƒtƒ@ƒCƒ‹]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr "[V‹KƒfƒBƒŒƒNƒgƒŠ]"
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr "[ƒtƒ@ƒCƒ‹‰ß‘å]"
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[Œ ŒÀ‚ª‚ ‚è‚Ü‚¹‚ñ]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200: *ReadPre autocommand ‚ªƒtƒ@ƒCƒ‹‚ð“Çž•s‰Â‚É‚µ‚Ü‚µ‚½"
-
-#: ../fileio.c:655
-msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: *ReadPre autocommand ‚ÍŒ»Ý‚̃oƒbƒtƒ@‚ð•Ï‚¦‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: •W€“ü—Í‚©‚ç“Çž’†...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202: •ÏŠ·‚ªƒtƒ@ƒCƒ‹‚ð“Çž•s‰Â‚É‚µ‚Ü‚µ‚½"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[FIFO/ƒ\\ƒPƒbƒg]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[FIFO]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[ƒ\\ƒPƒbƒg]"
-
-#. or character special
-#: ../fileio.c:1801
-msgid "[character special]"
-msgstr "[ƒLƒƒƒ‰ƒNƒ^EƒfƒoƒCƒX]"
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[CR–³]"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[’·s•ªŠ„]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[–¢•ÏŠ·]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[•ÏŠ·Ï]"
-
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[%<PRId64> s–ڂŕϊ·ƒGƒ‰[]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[%<PRId64> s–Ú‚Ì•s³‚ȃoƒCƒg]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[“ÇžƒGƒ‰[]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "•ÏŠ·‚É•K—v‚Ȉꎞƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "'charconvert' ‚É‚æ‚é•ÏŠ·‚ªŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../fileio.c:2113
-msgid "can't read output of 'charconvert'"
-msgstr "'charconvert' ‚Ìo—Í‚ð“Çž‚߂܂¹‚ñ‚Å‚µ‚½"
-
-#: ../fileio.c:2437
-msgid "E676: No matching autocommands for acwrite buffer"
-msgstr "E676: acwriteƒoƒbƒtƒ@‚ÌŠY“–‚·‚éautocommand‚Í‘¶Ý‚µ‚Ü‚¹‚ñ"
-
-#: ../fileio.c:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr "E203: •Û‘¶‚·‚éƒoƒbƒtƒ@‚ðautocommand‚ªíœ‚©‰ð•ú‚µ‚Ü‚µ‚½"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: autocommand‚ª—\\Šú‚¹‚Ê•û–@‚Ås”‚ð•ÏX‚µ‚Ü‚µ‚½"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "‚̓tƒ@ƒCƒ‹‚Å‚à‘ž‚݉”\\ƒfƒoƒCƒX‚Å‚à‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../fileio.c:2601
-msgid "is read-only (add ! to override)"
-msgstr "‚͓Ǟê—p‚Å‚· (‹­§‘ž‚É‚Í ! ‚ð’ljÁ)"
-
-#: ../fileio.c:2886
-msgid "E506: Can't write to backup file (add ! to override)"
-msgstr "E506: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ð•Û‘¶‚Å‚«‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å‹­§•Û‘¶)"
-
-#: ../fileio.c:2898
-msgid "E507: Close error for backup file (add ! to override)"
-msgstr ""
-"E507: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ð•‚¶‚éۂɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½ (! ‚ð’ljÁ‚Å‹­§)"
-
-#: ../fileio.c:2901
-msgid "E508: Can't read file for backup (add ! to override)"
-msgstr "E508: ƒoƒbƒNƒAƒbƒv—pƒtƒ@ƒCƒ‹‚ð“Çž‚߂܂¹‚ñ (! ‚ð’ljÁ‚Å‹­§“Çž)"
-
-#: ../fileio.c:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr "E509: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ðì‚ê‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å‹­§ì¬)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr "E510: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ðì‚ê‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å‹­§ì¬)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: •Û‘¶—pˆêŽžƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr "E213: •ÏŠ·‚Å‚«‚Ü‚¹‚ñ (! ‚ð’ljÁ‚ŕϊ·‚¹‚¸‚ɕۑ¶)"
-
-#: ../fileio.c:3169
-msgid "E166: Can't open linked file for writing"
-msgstr "E166: ƒŠƒ“ƒN‚³‚ꂽƒtƒ@ƒCƒ‹‚É‘ž‚߂܂¹‚ñ"
-
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: ‘ž‚Ý—p‚Ƀtƒ@ƒCƒ‹‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: fsync ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: •‚¶‚邱‚ƂɎ¸”s"
-
-#: ../fileio.c:3436
-msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: ‘ž‚݃Gƒ‰[, •ÏŠ·Ž¸”s (ã‘‚·‚é‚É‚Í 'fenc' ‚ð‹ó‚É‚µ‚Ä‚­‚¾‚³‚¢)"
-
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: ‘ž‚݃Gƒ‰[, •ÏŠ·Ž¸”s, s” %<PRId64> (ã‘‚·‚é‚É‚Í 'fenc' ‚ð‹ó‚É‚µ‚Ä"
-"‚­‚¾‚³‚¢)"
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: ‘ž‚݃Gƒ‰[, (ƒtƒ@ƒCƒ‹ƒVƒXƒeƒ€‚ª–ž”t?)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr " •ÏŠ·ƒGƒ‰["
-
-#: ../fileio.c:3509
-#, c-format
-msgid " in line %<PRId64>;"
-msgstr " s %<PRId64>;"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[ƒfƒoƒCƒX]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[V]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr " [a]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " ’ljÁ"
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr " [w]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " ‘ž‚Ý"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: patchmode: Œ´–{ƒtƒ@ƒCƒ‹‚ð•Û‘¶‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: patchmode: ‹ó‚ÌŒ´–{ƒtƒ@ƒCƒ‹‚ðtouch‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: ƒoƒbƒNƒAƒbƒvƒtƒ@ƒCƒ‹‚ðÁ‚¹‚Ü‚¹‚ñ"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"Œx: Œ´–{ƒtƒ@ƒCƒ‹‚ªŽ¸‚í‚ꂽ‚©•ÏX‚³‚ê‚Ü‚µ‚½\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "ƒtƒ@ƒCƒ‹‚̕ۑ¶‚ɬŒ÷‚·‚é‚܂ŃGƒfƒBƒ^‚ðI—¹‚µ‚È‚¢‚Å‚­‚¾‚³‚¢!"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[dosƒtƒH[ƒ}ƒbƒg]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[macƒtƒH[ƒ}ƒbƒg]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[unixƒtƒH[ƒ}ƒbƒg]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 s, "
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> s, "
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 •¶Žš"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> •¶Žš"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-msgid "[Incomplete last line]"
-msgstr "[ÅIs‚ª•sŠ®‘S]"
-
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "Œx: “Çž‚ñ‚¾Œã‚Ƀtƒ@ƒCƒ‹‚É•ÏX‚ª‚ ‚è‚Ü‚µ‚½!!!"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "–{“–‚Éã‘‚«‚µ‚Ü‚·‚©"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: \"%s\" ‚𑞂ݒ†‚̃Gƒ‰[‚Å‚·"
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: \"%s\" ‚ð•‚¶‚鎞‚ɃGƒ‰[‚Å‚·"
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: \"%s\" ‚ð“Çž’†‚̃Gƒ‰[‚Å‚·"
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: autocommand ‚Ì FileChangedShell ‚ªƒoƒbƒtƒ@‚ð휂µ‚Ü‚µ‚½"
-
-#: ../fileio.c:4894
-#, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: ƒtƒ@ƒCƒ‹ \"%s\" ‚ÍŠù‚É‘¶Ý‚µ‚Ü‚¹‚ñ"
-
-#: ../fileio.c:4906
-#, c-format
-msgid ""
-"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
-"well"
-msgstr "W12: Œx: ƒtƒ@ƒCƒ‹ \"%s\" ‚ª•ÏX‚³‚êVim‚̃oƒbƒtƒ@‚à•ÏX‚³‚ê‚Ü‚µ‚½"
-
-#: ../fileio.c:4907
-msgid "See \":help W12\" for more info."
-msgstr "Ú×‚Í \":help W12\" ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: Œx: ƒtƒ@ƒCƒ‹ \"%s\" ‚Í•ÒWŠJŽnŒã‚É•ÏX‚³‚ê‚Ü‚µ‚½"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "Ú×‚Í \":help W11\" ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr "W16: Œx: ƒtƒ@ƒCƒ‹ \"%s\" ‚̃‚[ƒh‚ª•ÒWŠJŽnŒã‚É•ÏX‚³‚ê‚Ü‚µ‚½"
-
-#: ../fileio.c:4915
-msgid "See \":help W16\" for more info."
-msgstr "Ú×‚Í \":help W16\" ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: Œx: ƒtƒ@ƒCƒ‹ \"%s\" ‚Í•ÒWŠJŽnŒã‚É쬂³‚ê‚Ü‚µ‚½"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "Œx"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"&OK\n"
-"ƒtƒ@ƒCƒ‹“Çž(&L)"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: \"%s\" ‚ðƒŠƒ[ƒh‚·‚途õ‚ª‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../fileio.c:5078
-#, c-format
-msgid "E321: Could not reload \"%s\""
-msgstr "E321: \"%s\" ‚ÍƒŠƒ[ƒh‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../fileio.c:5601
-msgid "--Deleted--"
-msgstr "--íœÏ--"
-
-#: ../fileio.c:5732
-#, c-format
-msgid "auto-removing autocommand: %s <buffer=%d>"
-msgstr "autocommand: %s <ƒoƒbƒtƒ@=%d> ‚ªŽ©“®“I‚É휂³‚ê‚Ü‚·"
-
-#. the group doesn't exist
-#: ../fileio.c:5772
-#, c-format
-msgid "E367: No such group: \"%s\""
-msgstr "E367: ‚»‚̃Oƒ‹[ƒv‚Í‚ ‚è‚Ü‚¹‚ñ: \"%s\""
-
-#: ../fileio.c:5897
-#, c-format
-msgid "E215: Illegal character after *: %s"
-msgstr "E215: * ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½: %s"
-
-#: ../fileio.c:5905
-#, c-format
-msgid "E216: No such event: %s"
-msgstr "E216: ‚»‚̂悤‚ȃCƒxƒ“ƒg‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../fileio.c:5907
-#, c-format
-msgid "E216: No such group or event: %s"
-msgstr "E216: ‚»‚̂悤‚ȃOƒ‹[ƒv‚à‚µ‚­‚̓Cƒxƒ“ƒg‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#. Highlight title
-#: ../fileio.c:6090
-msgid ""
-"\n"
-"--- Auto-Commands ---"
-msgstr ""
-"\n"
-"--- Auto-Commands ---"
-
-#: ../fileio.c:6293
-#, c-format
-msgid "E680: <buffer=%d>: invalid buffer number "
-msgstr "E680: <ƒoƒbƒtƒ@=%d>: –³Œø‚ȃoƒbƒtƒ@”Ô†‚Å‚· "
-
-#: ../fileio.c:6370
-msgid "E217: Can't execute autocommands for ALL events"
-msgstr "E217: ‘S‚ẴCƒxƒ“ƒg‚ɑ΂µ‚Ä‚Ìautocommand‚ÍŽÀs‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../fileio.c:6393
-msgid "No matching autocommands"
-msgstr "ŠY“–‚·‚éautocommand‚Í‘¶Ý‚µ‚Ü‚¹‚ñ"
-
-#: ../fileio.c:6831
-msgid "E218: autocommand nesting too deep"
-msgstr "E218: autocommand‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
-
-#: ../fileio.c:7143
-#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "%s Auto commands for \"%s\""
-
-#: ../fileio.c:7149
-#, c-format
-msgid "Executing %s"
-msgstr "%s ‚ðŽÀs‚µ‚Ä‚¢‚Ü‚·"
-
-#: ../fileio.c:7211
-#, c-format
-msgid "autocommand %s"
-msgstr "autocommand %s"
-
-#: ../fileio.c:7795
-msgid "E219: Missing {."
-msgstr "E219: { ‚ª‚ ‚è‚Ü‚¹‚ñ."
-
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: } ‚ª‚ ‚è‚Ü‚¹‚ñ."
-
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: Üô‚Ý‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: Œ»Ý‚Ì 'foldmethod' ‚Å‚ÍÜô‚Ý‚ð쬂ł«‚Ü‚¹‚ñ"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: Œ»Ý‚Ì 'foldmethod' ‚Å‚ÍÜô‚Ý‚ð휂ł«‚Ü‚¹‚ñ"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld s‚ªÜô‚Ü‚ê‚Ü‚µ‚½ "
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: “Çžƒoƒbƒtƒ@‚֒ljÁ"
-
-#: ../getchar.c:2040
-msgid "E223: recursive mapping"
-msgstr "E223: Ä‹A“Iƒ}ƒbƒsƒ“ƒO"
-
-#: ../getchar.c:2849
-#, c-format
-msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: %s ‚Æ‚¢‚¤ƒOƒ[ƒoƒ‹’Zk“ü—͂͊ù‚É‘¶Ý‚µ‚Ü‚·"
-
-#: ../getchar.c:2852
-#, c-format
-msgid "E225: global mapping already exists for %s"
-msgstr "E225: %s ‚Æ‚¢‚¤ƒOƒ[ƒoƒ‹ƒ}ƒbƒsƒ“ƒO‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·"
-
-#: ../getchar.c:2952
-#, c-format
-msgid "E226: abbreviation already exists for %s"
-msgstr "E226: %s ‚Æ‚¢‚¤’Zk“ü—͂͊ù‚É‘¶Ý‚µ‚Ü‚·"
-
-#: ../getchar.c:2955
-#, c-format
-msgid "E227: mapping already exists for %s"
-msgstr "E227: %s ‚Æ‚¢‚¤ƒ}ƒbƒsƒ“ƒO‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·"
-
-#: ../getchar.c:3008
-msgid "No abbreviation found"
-msgstr "’Zk“ü—͂͌©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../getchar.c:3010
-msgid "No mapping found"
-msgstr "ƒ}ƒbƒsƒ“ƒO‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../getchar.c:3974
-msgid "E228: makemap: Illegal mode"
-msgstr "E228: makemap: •s³‚ȃ‚[ƒh"
-
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--ƒoƒbƒtƒ@‚És‚ª‚ ‚è‚Ü‚¹‚ñ--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: ƒRƒ}ƒ“ƒh‚ª’†’f‚³‚ê‚Ü‚µ‚½"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: ˆø”‚ª•K—v‚Å‚·"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ ‚ÌŒã‚Í / ‚© ? ‚© & ‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: ƒRƒ}ƒ“ƒhƒ‰ƒCƒ“‚ł͖³Œø‚Å‚·; <CR>‚ÅŽÀs, CTRL-C‚Å‚â‚ß‚é"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: Œ»Ý‚̃fƒBƒŒƒNƒgƒŠ‚âƒ^ƒOŒŸõ‚Å‚Íexrc/vimrc‚̃Rƒ}ƒ“ƒh‚Í‹–‰Â‚³‚ê‚Ü‚¹‚ñ"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhile ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :while ‚̂Ȃ¢ :endwhile ‚ª‚ ‚è‚Ü‚·"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor ‚̂Ȃ¢ :for ‚ª‚ ‚è‚Ü‚·"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: ƒtƒ@ƒCƒ‹‚ª‘¶Ý‚µ‚Ü‚· (! ‚ð’ljÁ‚Åã‘)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: ƒRƒ}ƒ“ƒh‚ªŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: “à•”ƒGƒ‰[‚Å‚·"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Š„ž‚Ü‚ê‚Ü‚µ‚½"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: –³Œø‚ȃAƒhƒŒƒX‚Å‚·"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: –³Œø‚Ȉø”‚Å‚·"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: –³Œø‚Ȉø”‚Å‚·: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: –³Œø‚ÈŽ®‚Å‚·: %s"
-
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: –³Œø‚Ȕ͈͂ł·"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: –³Œø‚ȃRƒ}ƒ“ƒh‚Å‚·"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ‚̓fƒBƒŒƒNƒgƒŠ‚Å‚·"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: –³Œø‚ȃXƒNƒ[ƒ‹—ʂł·"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: \"%s\"() ‚̃‰ƒCƒuƒ‰ƒŠŒÄo‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: ƒ}[ƒN‚É–³Œø‚Ès”Ô†‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚µ‚½"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: ƒ}[ƒN‚Íݒ肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: 'modifiable' ‚ªƒIƒt‚Ȃ̂Å, •ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: ƒXƒNƒŠƒvƒg‚Ì“ü‚êŽq‚ª[‰ß‚¬‚Ü‚·"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: •›ƒtƒ@ƒCƒ‹‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ‚»‚̂悤‚È’Zk“ü—͂͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ! ‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUI‚ÍŽg—p•s‰Â”\\‚Å‚·: ƒRƒ“ƒpƒCƒ‹Žž‚É–³Œø‚É‚³‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ‚»‚̂悤‚È–¼‚̃nƒCƒ‰ƒCƒgƒOƒ‹[ƒv‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ‚Ü‚¾ƒeƒLƒXƒg‚ª‘}“ü‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: ˆÈ‘O‚ɃRƒ}ƒ“ƒhs‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ‚»‚̂悤‚ȃ}ƒbƒsƒ“ƒO‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: ŠY“–‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: ŠY“–‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ƒtƒ@ƒCƒ‹–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: ³‹K•\\Œ»’uŠ·‚ª‚Ü‚¾ŽÀs‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: ƒRƒ}ƒ“ƒh‚ª‚Ü‚¾ŽÀs‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: ³‹K•\\Œ»‚ª‚Ü‚¾ŽÀs‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: ”͈͎w’è‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: ƒEƒBƒ“ƒhƒE‚É\\•ª‚È‚‚³‚à‚µ‚­‚Í•‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: ƒtƒ@ƒCƒ‹ %s ‚ð쬂ł«‚Ü‚¹‚ñ"
-
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: ˆêŽžƒtƒ@ƒCƒ‹‚Ì–¼‘O‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: ƒtƒ@ƒCƒ‹ \"%s\" ‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: ƒtƒ@ƒCƒ‹ %s ‚ð“Çž‚߂܂¹‚ñ"
-
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: ÅŒã‚Ì•ÏX‚ª•Û‘¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å•ÏX‚ð”jŠü)"
-
-#: ../globals.h:1055
-msgid "E37: No write since last change"
-msgstr "E37: ÅŒã‚Ì•ÏX‚ª•Û‘¶‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: ˆø”‚ª‹ó‚Å‚·"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: ”’l‚ª—v‹‚³‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: ƒGƒ‰[ƒtƒ@ƒCƒ‹ %s ‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: ƒƒ‚ƒŠ‚ªs‚«‰Ê‚Ă܂µ‚½!"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "ƒpƒ^[ƒ“‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: ƒpƒ^[ƒ“‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: ˆø”‚ͳ‚Ì’l‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: ‘O‚̃fƒBƒŒƒNƒgƒŠ‚É–ß‚ê‚Ü‚¹‚ñ"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: ƒGƒ‰[‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: ƒƒP[ƒVƒ‡ƒ“ƒŠƒXƒg‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: ŠY“–•¶Žš—ñ‚ª”j‘¹‚µ‚Ä‚¢‚Ü‚·"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: •s³‚ȳ‹K•\\Œ»ƒvƒƒOƒ‰ƒ€‚Å‚·"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: 'readonly' ƒIƒvƒVƒ‡ƒ“‚ªÝ’肳‚ê‚Ä‚¢‚Ü‚· (! ‚ð’ljÁ‚Åã‘‚«)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: “ÇŽæê—p•Ï” \"%s\" ‚ɂ͒l‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: ƒTƒ“ƒhƒ{ƒbƒNƒX‚ł͕ϔ \"%s\" ‚É’l‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: ƒGƒ‰[ƒtƒ@ƒCƒ‹‚̓Ǟ’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: ƒTƒ“ƒhƒ{ƒbƒNƒX‚ł͋–‚³‚ê‚Ü‚¹‚ñ"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ‚±‚±‚ł͋–‰Â‚³‚ê‚Ü‚¹‚ñ"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ƒXƒNƒŠ[ƒ“ƒ‚[ƒh‚ÌÝ’è‚ɂ͑Ήž‚µ‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: –³Œø‚ȃXƒNƒ[ƒ‹—ʂł·"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: 'shell' ƒIƒvƒVƒ‡ƒ“‚ª‹ó‚Å‚·"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: sign ‚̃f[ƒ^‚ð“Çž‚߂܂¹‚ñ‚Å‚µ‚½"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚̃Nƒ[ƒYŽžƒGƒ‰[‚Å‚·"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: ƒ^ƒOƒXƒ^ƒbƒN‚ª‹ó‚Å‚·"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: ƒRƒ}ƒ“ƒh‚ª•¡ŽG‰ß‚¬‚Ü‚·"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: –¼‘O‚ª’·‰ß‚¬‚Ü‚·"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: [ ‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ƒtƒ@ƒCƒ‹–¼‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: —]•ª‚È•¶Žš‚ªŒã‚ë‚É‚ ‚è‚Ü‚·"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: –¢’m‚̃}[ƒN"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: ƒƒCƒ‹ƒhƒJ[ƒh‚ð“WŠJ‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ‚Í 'winminheight' ‚æ‚謂³‚­‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ‚Í 'winminwidth' ‚æ‚謂³‚­‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: ‘ž‚Ý’†‚̃Gƒ‰["
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "ƒ[ƒƒJƒEƒ“ƒg"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: ƒXƒNƒŠƒvƒgˆÈŠO‚Å<SID>‚ªŽg‚í‚ê‚Ü‚µ‚½"
-
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: “à•”ƒGƒ‰[‚Å‚·: %s"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: ƒpƒ^[ƒ“‚ª 'maxmempattern' ˆÈã‚̃ƒ‚ƒŠ‚ðŽg—p‚µ‚Ü‚·"
-
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: ƒoƒbƒtƒ@‚ª‹ó‚Å‚·"
-
-#, c-format
-msgid "E86: Buffer %ld does not exist"
-msgstr "E86: ƒoƒbƒtƒ@ %ld ‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: ŒŸõƒpƒ^[ƒ“‚©‹æØ‚è‹L†‚ª•s³‚Å‚·"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: “¯‚¶–¼‘O‚̃tƒ@ƒCƒ‹‚ª‘¼‚̃oƒbƒtƒ@‚œǞ‚Ü‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: ƒIƒvƒVƒ‡ƒ“ '%s' ‚Íݒ肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: –³Œø‚ȃŒƒWƒXƒ^–¼‚Å‚·"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "ã‚܂ŌŸõ‚µ‚½‚̂ʼnº‚É–ß‚è‚Ü‚·"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "‰º‚܂ŌŸõ‚µ‚½‚Ì‚Åã‚É–ß‚è‚Ü‚·"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: ƒRƒƒ“‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: •s³‚È\\•¶—v‘f‚Å‚·"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: ”’l‚ª•K—v‚Å‚·"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "%d ƒy[ƒW"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "ˆóü‚·‚éƒeƒLƒXƒg‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "ˆóü’†: ƒy[ƒW %d (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr " ƒRƒs[ %d (‘S %d ’†)"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "ˆóü‚µ‚Ü‚µ‚½: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "ˆóü‚ª’†Ž~‚³‚ê‚Ü‚µ‚½"
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: PostScripto—̓tƒ@ƒCƒ‹‚Ì‘ž‚݃Gƒ‰[‚Å‚·"
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: ƒtƒ@ƒCƒ‹ \"%s\" ‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: PostScript‚ÌƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"%s\" ‚ð“Çž‚߂܂¹‚ñ"
-
-#: ../hardcopy.c:1772
-#, c-format
-msgid "E618: file \"%s\" is not a PostScript resource file"
-msgstr "E618: ƒtƒ@ƒCƒ‹ \"%s\" ‚Í PostScript ƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: ƒtƒ@ƒCƒ‹ \"%s\" ‚͑Ήž‚µ‚Ä‚¢‚È‚¢ PostScript ƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹‚Å‚·"
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: ƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"%s\" ‚̓o[ƒWƒ‡ƒ“‚ªˆÙ‚È‚è‚Ü‚·"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: ŒÝŠ·«‚Ì–³‚¢ƒ}ƒ‹ƒ`ƒoƒCƒgƒGƒ“ƒR[ƒfƒBƒ“ƒO‚Æ•¶ŽšƒZƒbƒg‚Å‚·"
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: ƒ}ƒ‹ƒ`ƒoƒCƒgƒGƒ“ƒR[ƒfƒBƒ“ƒO‚Å‚Í printmbcharset ‚ð‹ó‚ɂł«‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr ""
-"E675: ƒ}ƒ‹ƒ`ƒoƒCƒg•¶Žš‚ðˆóü‚·‚邽‚߂̃fƒtƒHƒ‹ƒgƒtƒHƒ“ƒg‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: PostScripto—Í—p‚̃tƒ@ƒCƒ‹‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: ƒtƒ@ƒCƒ‹ \"%s\" ‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: PostScript‚ÌƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"prolog.ps\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:2593
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: PostScript‚ÌƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"cidfont.ps\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: PostScript‚ÌƒŠƒ\\[ƒXƒtƒ@ƒCƒ‹ \"%s.ps\" ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:2654
-#, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: ˆóüƒGƒ“ƒR[ƒh \"%s\" ‚Ö•ÏŠ·‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "ƒvƒŠƒ“ƒ^‚É‘—M’†..."
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: PostScriptƒtƒ@ƒCƒ‹‚̈óü‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "ˆóüƒWƒ‡ƒu‚ð‘—M‚µ‚Ü‚µ‚½."
-
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "Vƒf[ƒ^ƒx[ƒX‚ð’ljÁ"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "ƒpƒ^[ƒ“‚̃NƒGƒŠ[‚ð’ljÁ"
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "‚±‚̃ƒbƒZ[ƒW‚ð•\\ަ‚·‚é"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "Ú‘±‚ðI—¹‚·‚é"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "‘S‚Ä‚ÌÚ‘±‚ðĉŠú‰»‚·‚é"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "Ú‘±‚ð•\\ަ‚·‚é"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Žg—p•û–@: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "‚±‚ÌcscopeƒRƒ}ƒ“ƒh‚Í•ªŠ„ƒEƒBƒ“ƒhƒE‚ł̓Tƒ|[ƒg‚³‚ê‚Ü‚¹‚ñ.\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Žg—p–@: cstag <ident>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: ƒ^ƒO‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) ƒGƒ‰[: %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s ‚̓fƒBƒŒƒNƒgƒŠ‹y‚Ñ—LŒø‚Ècscope‚̃f[ƒ^ƒx[ƒX‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "cscopeƒf[ƒ^ƒx[ƒX %s ‚ð’ljÁ"
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: cscope‚ÌÚ‘± %<PRId64> ‚ð“Çž‚Ý’†‚̃Gƒ‰[‚Å‚·"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: –¢’m‚ÌcscopeŒŸõŒ^‚Å‚·"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: cscopeƒpƒCƒv‚ð쬂ł«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: cscope‚Ì‹N“®€”õ(fork)‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../if_cscope.c:849
-msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection ‚Ö‚Ì setpgid ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection ‚ÌŽÀs‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: to_fp ‚Ì fdopen ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fr_fp ‚Ì fdopen ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: cscopeƒvƒƒZƒX‚ð‹N“®‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: cscopeÚ‘±‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: –³Œø‚È cscopequickfix ƒtƒ‰ƒO %c ‚Ì %c ‚Å‚·"
-
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: cscopeƒNƒGƒŠ[ %s of %s ‚ÉŠY“–‚ª‚ ‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "cscopeƒRƒ}ƒ“ƒh:\n"
-
-#: ../if_cscope.c:1150
-#, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %s%*s (Žg—p–@: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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"
-" c: ‚±‚ÌŠÖ”‚ðŒÄ‚ñ‚Å‚¢‚éŠÖ”‚ð’T‚·\n"
-" d: ‚±‚ÌŠÖ”‚©‚çŒÄ‚ñ‚Å‚¢‚éŠÖ”‚ð’T‚·\n"
-" e: ‚±‚Ìegrepƒpƒ^[ƒ“‚ð’T‚·\n"
-" f: ‚±‚̃tƒ@ƒCƒ‹‚ð’T‚·\n"
-" g: ‚±‚Ì’è‹`‚ð’T‚·\n"
-" i: ‚±‚̃tƒ@ƒCƒ‹‚ð#include‚µ‚Ä‚¢‚éƒtƒ@ƒCƒ‹‚ð’T‚·\n"
-" s: ‚±‚ÌCƒVƒ“ƒ{ƒ‹‚ð’T‚·\n"
-" t: ‚±‚̃eƒLƒXƒg•¶Žš—ñ‚ð’T‚·\n"
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: d•¡‚·‚écscopeƒf[ƒ^ƒx[ƒX‚͒ljÁ‚³‚ê‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: cscopeÚ‘± %s ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "cscopeÚ‘± %s ‚ª•‚¶‚ç‚ê‚Ü‚µ‚½"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: cs_manage_matches ‚Å’v–½“I‚ȃGƒ‰[‚Å‚·"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Cscope ƒ^ƒO: %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # s”Ô†"
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "ƒtƒ@ƒCƒ‹–¼ / •¶–¬ / s\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: cscopeƒGƒ‰[: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "‘S‚Ä‚Ìcscopeƒf[ƒ^ƒx[ƒX‚ðƒŠƒZƒbƒg‚µ‚Ü‚·"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "cscopeÚ‘±‚ª‚ ‚è‚Ü‚¹‚ñ\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid ƒf[ƒ^ƒx[ƒX–¼ prepend ƒpƒX\n"
-
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "–¢’m‚̃IƒvƒVƒ‡ƒ“ˆø”‚Å‚·"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "•ÒWˆø”‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "ˆø”‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "ƒIƒvƒVƒ‡ƒ“ˆø”‚ÌŒã‚ɃSƒ~‚ª‚ ‚è‚Ü‚·"
-
-#: ../main.c:152
-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
-#, c-format
-msgid "%d files to edit\n"
-msgstr "%d ŒÂ‚̃tƒ@ƒCƒ‹‚ª•ÒW‚ðT‚¦‚Ä‚¢‚Ü‚·\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "ƒXƒNƒŠƒvƒgƒtƒ@ƒCƒ‹‚ðĂъJ‚¢‚Ă݂܂·: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "“Çž—p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../main.c:1393
-msgid "Cannot open for script output: \""
-msgstr "ƒXƒNƒŠƒvƒgo—Í—p‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../main.c:1622
-msgid "Vim: Warning: Output is not to a terminal\n"
-msgstr "Vim: Œx: ’[––‚Ö‚Ìo—͂ł͂ ‚è‚Ü‚¹‚ñ\n"
-
-#: ../main.c:1624
-msgid "Vim: Warning: Input is not from a terminal\n"
-msgstr "Vim: Œx: ’[––‚©‚ç‚Ì“ü—͂ł͂ ‚è‚Ü‚¹‚ñ\n"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "vimrc‘O‚̃Rƒ}ƒ“ƒhƒ‰ƒCƒ“"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: \"%s\"‚©‚ç“Çž‚Þ‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"‚æ‚èÚׂÈî•ñ‚Í: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[ƒtƒ@ƒCƒ‹..] ‚ ‚éƒtƒ@ƒCƒ‹‚ð•ÒW‚·‚é"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- •W€“ü—Í‚©‚çƒeƒLƒXƒg‚ð“Çž‚Þ"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t ƒ^ƒO ƒ^ƒO‚ª’è‹`‚³‚ꂽ‚Æ‚±‚ë‚©‚ç•ÒW‚·‚é"
-
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [errorfile] ʼn‚̃Gƒ‰[‚Å•ÒW‚·‚é"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"Žg—p–@:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [ˆø”] "
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" ‚à‚µ‚­‚Í:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"ˆø”:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\t‚±‚Ì‚ ‚Ƃɂ̓tƒ@ƒCƒ‹–¼‚¾‚¯"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tƒƒCƒ‹ƒhƒJ[ƒh‚ð“WŠJ‚µ‚È‚¢"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tViƒ‚[ƒh (\"vi\" ‚Æ“¯‚¶)"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tExƒ‚[ƒh (\"ex\" ‚Æ“¯‚¶)"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr "-E\t\t\t‰ü—ÇExƒ‚[ƒh"
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tƒTƒCƒŒƒ“ƒg(ƒoƒbƒ`)ƒ‚[ƒh (\"ex\" ê—p)"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\t·•ªƒ‚[ƒh (\"vidiff\" ‚Æ“¯‚¶)"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tƒC[ƒW[ƒ‚[ƒh (\"evim\" ‚Æ“¯‚¶, ƒ‚[ƒh–³)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\t“Çžê—pƒ‚[ƒh (\"view\" ‚Æ“¯‚¶)"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\t§ŒÀƒ‚[ƒh (\"rvim\" ‚Æ“¯‚¶)"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\t•ÏX (ƒtƒ@ƒCƒ‹•Û‘¶Žž) ‚ð‚Å‚«‚È‚¢‚悤‚É‚·‚é"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tƒeƒLƒXƒg‚Ì•ÒW‚ðs‚È‚¦‚È‚¢‚悤‚É‚·‚é"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tƒoƒCƒiƒŠƒ‚[ƒh"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tLispƒ‚[ƒh"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tViŒÝŠ·ƒ‚[ƒh: 'compatible'"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tVi”ñŒÝŠ·ƒ‚[ƒh: 'nocompatible"
-
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr "-V[N][fname]\t\tƒƒOo—ÍÝ’è [ƒŒƒxƒ‹ N] [ƒƒOƒtƒ@ƒCƒ‹–¼ fname]"
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tƒfƒoƒbƒOƒ‚[ƒh"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ðŽg—p‚¹‚¸ƒƒ‚ƒŠ‚¾‚¯"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ð—ñ‹“‚µI—¹"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (ƒtƒ@ƒCƒ‹–¼)\tƒNƒ‰ƒbƒVƒ…‚µ‚½ƒZƒbƒVƒ‡ƒ“‚𕜋A"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\t-r‚Æ“¯‚¶"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tƒAƒ‰ƒrƒAŒêƒ‚[ƒh‚Å‹N“®‚·‚é"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tƒwƒuƒ‰ƒCŒêƒ‚[ƒh‚Å‹N“®‚·‚é"
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tƒyƒ‹ƒVƒAŒêƒ‚[ƒh‚Å‹N“®‚·‚é"
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminal>\t’[––‚ð <terminal> ‚ÉÝ’è‚·‚é"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\t.vimrc‚Ì‘ã‚í‚è‚É <vimrc> ‚ðŽg‚¤"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tƒvƒ‰ƒOƒCƒ“ƒXƒNƒŠƒvƒg‚ðƒ[ƒh‚µ‚È‚¢"
-
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tN ŒÂƒ^ƒuƒy[ƒW‚ðŠJ‚­(È—ª’l: ƒtƒ@ƒCƒ‹‚ɂ‚«1ŒÂ)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\tN ŒÂƒEƒBƒ“ƒhƒE‚ðŠJ‚­(È—ª’l: ƒtƒ@ƒCƒ‹‚ɂ‚«1ŒÂ)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\t-o‚Æ“¯‚¶‚¾‚ª‚’¼•ªŠ„"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tƒtƒ@ƒCƒ‹‚ÌŌォ‚ç‚Í‚¶‚ß‚é"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\t<lnum> s‚©‚ç‚Í‚¶‚ß‚é"
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <command>\tvimrc‚ðƒ[ƒh‚·‚é‘O‚É <command> ‚ðŽÀs‚·‚é"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <command>\t\tʼn‚̃tƒ@ƒCƒ‹‚ðƒ[ƒhŒã <command> ‚ðŽÀs‚·‚é"
-
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <session>\t\tʼn‚̃tƒ@ƒCƒ‹‚ðƒ[ƒhŒãƒtƒ@ƒCƒ‹ <session> ‚ðŽæž‚Þ"
-
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <scriptin>\tƒtƒ@ƒCƒ‹ <scriptin> ‚©‚çƒm[ƒ}ƒ‹ƒRƒ}ƒ“ƒh‚ð“Çž‚Þ"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <scriptout>\t“ü—Í‚µ‚½‘SƒRƒ}ƒ“ƒh‚ðƒtƒ@ƒCƒ‹ <scriptout> ‚ɒljÁ‚·‚é"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <scriptout>\t“ü—Í‚µ‚½‘SƒRƒ}ƒ“ƒh‚ðƒtƒ@ƒCƒ‹ <scriptout> ‚ɕۑ¶‚·‚é"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr "--startuptime <file>\t‹N“®‚É‚©‚©‚Á‚½ŽžŠÔ‚ÌÚׂð <file> ‚Öo—Í‚·‚é"
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\t.viminfo‚Ì‘ã‚í‚è‚É <viminfo> ‚ðŽg‚¤"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h or --help\tƒwƒ‹ƒv(‚±‚̃ƒbƒZ[ƒW)‚ð•\\ަ‚µI—¹‚·‚é"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\tƒo[ƒWƒ‡ƒ“î•ñ‚ð•\\ަ‚µI—¹‚·‚é"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "ƒ}[ƒN‚ªÝ’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: \"%s\" ‚ÉŠY“–‚·‚éƒ}[ƒN‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"mark s —ñ ƒtƒ@ƒCƒ‹/ƒeƒLƒXƒg"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-" jump s —ñ ƒtƒ@ƒCƒ‹/ƒeƒLƒXƒg"
-
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-"\n"
-"•ÏX s —ñ ƒeƒLƒXƒg"
-
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# ƒtƒ@ƒCƒ‹ƒ}[ƒN:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# ƒWƒƒƒ“ƒvƒŠƒXƒg (V‚µ‚¢‚à‚Ì‚ªæ):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# ƒtƒ@ƒCƒ‹“àƒ}[ƒN‚Ì—š—ð (V‚µ‚¢‚à‚Ì‚©‚çŒÃ‚¢‚à‚Ì):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "'>' ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: ƒuƒƒbƒN‚ªƒƒbƒN‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: ƒXƒƒbƒvƒtƒ@ƒCƒ‹“ÇžŽž‚ɃV[ƒNƒGƒ‰[‚Å‚·"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚̓Ǟ‚݃Gƒ‰[‚Å‚·"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‘ž‚ÝŽž‚ɃV[ƒNƒGƒ‰[‚Å‚·"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚Ì‘ž‚݃Gƒ‰[‚Å‚·"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ªŠù‚É‘¶Ý‚µ‚Ü‚· (symlink‚É‚æ‚éUŒ‚?)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: ƒuƒƒbƒN 0 ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ?"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: ƒuƒƒbƒN 1 ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ?"
-
-#: ../memline.c:377
-msgid "E298: Didn't get block nr 2?"
-msgstr "E298: ƒuƒƒbƒN 2 ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ?"
-
-#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: ‚¨‚Á‚Æ, ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ªŽ¸‚í‚ê‚Ü‚µ‚½!!!"
-
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚Ì–¼‘O‚ð•Ï‚¦‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr "E303: \"%s\" ‚̃Xƒƒbƒvƒtƒ@ƒCƒ‹‚ðŠJ‚¯‚È‚¢‚Ì‚ÅƒŠƒJƒoƒŠ‚Í•s‰Â”\\‚Å‚·"
-
-#: ../memline.c:666
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_upd_block0(): ƒuƒƒbƒN 0 ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½??"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: %s ‚ɂ̓Xƒƒbƒvƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr "Žg—p‚·‚éƒXƒƒbƒvƒtƒ@ƒCƒ‹‚̔Ԇ‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢(0 ‚ÅI—¹): "
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: %s ‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "ƒuƒƒbƒN 0 ‚ð“Çž‚߂܂¹‚ñ "
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"‹°‚ç‚­•ÏX‚ª‚³‚ê‚Ä‚¢‚È‚¢‚©Vim‚ªƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ðXV‚µ‚Ä‚¢‚Ü‚¹‚ñ."
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " Vim‚Ì‚±‚̃o[ƒWƒ‡ƒ“‚ł͎g—p‚Å‚«‚Ü‚¹‚ñ.\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "Vim‚̃o[ƒWƒ‡ƒ“3.0‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢.\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %s ‚ÍVim‚̃Xƒƒbƒvƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚悤‚Å‚·"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " ‚±‚̃Rƒ“ƒsƒ…[ƒ^‚ł͎g—p‚Å‚«‚Ü‚¹‚ñ.\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr "‚±‚̃tƒ@ƒCƒ‹‚ÍŽŸ‚ÌꊂÅì‚ç‚ê‚Ü‚µ‚½ "
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-",\n"
-"‚à‚µ‚­‚̓tƒ@ƒCƒ‹‚ª‘¹‚µ‚Ä‚¢‚Ü‚·."
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr " ‚Í‘¹‚µ‚Ä‚¢‚Ü‚· (ƒy[ƒWƒTƒCƒY‚ªÅ¬’l‚ð‰º‰ñ‚Á‚Ä‚¢‚Ü‚·).\n"
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹ \"%s\" ‚ðŽg—p’†"
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "Œ´–{ƒtƒ@ƒCƒ‹ \"%s\""
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: Œx: Œ´–{ƒtƒ@ƒCƒ‹‚ª•ÏX‚³‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../memline.c:1061
-#, c-format
-msgid "E309: Unable to read block 1 from %s"
-msgstr "E309: %s ‚©‚çƒuƒƒbƒN 1 ‚ð“Çž‚߂܂¹‚ñ"
-
-#: ../memline.c:1065
-msgid "???MANY LINES MISSING"
-msgstr "???‘½‚­‚Ìs‚ªŽ¸‚í‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../memline.c:1076
-msgid "???LINE COUNT WRONG"
-msgstr "???s”‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../memline.c:1082
-msgid "???EMPTY BLOCK"
-msgstr "???ƒuƒƒbƒN‚ª‹ó‚Å‚·"
-
-#: ../memline.c:1103
-msgid "???LINES MISSING"
-msgstr "???s‚ªŽ¸‚í‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../memline.c:1128
-#, c-format
-msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: ƒuƒƒbƒN 1 ‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·(%s ‚ª.swpƒtƒ@ƒCƒ‹‚łȂ¢?)"
-
-#: ../memline.c:1133
-msgid "???BLOCK MISSING"
-msgstr "???ƒuƒƒbƒN‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../memline.c:1147
-msgid "??? from here until ???END lines may be messed up"
-msgstr "??? ‚±‚±‚©‚ç ???END ‚܂łÌs‚ª”j‰ó‚³‚ê‚Ä‚¢‚邿‚¤‚Å‚·"
-
-#: ../memline.c:1164
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? ‚±‚±‚©‚ç ???END ‚܂łÌs‚ª‘}“ü‚©íœ‚³‚ꂽ‚悤‚Å‚·"
-
-#: ../memline.c:1181
-msgid "???END"
-msgstr "???END"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: ƒŠƒJƒoƒŠ‚ªŠ„ž‚Ü‚ê‚Ü‚µ‚½"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr ""
-"E312: ƒŠƒJƒoƒŠ‚ÌÅ’†‚ɃGƒ‰[‚ªŒŸo‚³‚ê‚Ü‚µ‚½; ???‚ÅŽn‚Ü‚és‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "Ú×‚Í \":help E312\" ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr "ƒŠƒJƒoƒŠ‚ªI—¹‚µ‚Ü‚µ‚½. ‘S‚Ä‚ª³‚µ‚¢‚©ƒ`ƒFƒbƒN‚µ‚Ä‚­‚¾‚³‚¢."
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(•ÏX‚ðƒ`ƒFƒbƒN‚·‚邽‚ß‚É, ‚±‚̃tƒ@ƒCƒ‹‚ð•ʂ̖¼‘O‚ŕۑ¶‚µ‚½ã‚Å\n"
-
-#: ../memline.c:1252
-msgid "and run diff with the original file to check for changes)"
-msgstr "Œ´–{ƒtƒ@ƒCƒ‹‚Æ‚Ì diff ‚ðŽÀs‚·‚邯—Ç‚¢‚Å‚µ‚傤)"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr "•œŒ³Š®—¹. ƒoƒbƒtƒ@‚Ì“à—e‚̓tƒ@ƒCƒ‹‚Æ“¯‚¶‚ɂȂè‚Ü‚µ‚½."
-
-#: ../memline.c:1255
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"\n"
-"Œ³‚Ì.swpƒtƒ@ƒCƒ‹‚Í휂µ‚Ä‚à\\‚¢‚Ü‚¹‚ñ\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª•¡”Œ©‚‚©‚è‚Ü‚µ‚½:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr " Œ»Ý‚̃fƒBƒŒƒNƒgƒŠ:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " ˆÈ‰º‚Ì–¼‘O‚ðŽg—p’†:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " ƒfƒBƒŒƒNƒgƒŠ "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- ‚È‚µ --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " Š—LŽÒ: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " “ú•t: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " “ú•t: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [from Vim version 3.0]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [Vim‚̃Xƒƒbƒvƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚悤‚Å‚·]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " ƒtƒ@ƒCƒ‹–¼: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" •ÏXó‘Ô: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "‚ ‚è"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "‚È‚µ"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" ƒ†[ƒU[–¼: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " ƒzƒXƒg–¼: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" ƒzƒXƒg–¼: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" ƒvƒƒZƒXID: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (‚Ü‚¾ŽÀs’†)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [‚±‚̃Rƒ“ƒsƒ…[ƒ^‚ł͎g—p‚Å‚«‚Ü‚¹‚ñ]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [“Çž‚߂܂¹‚ñ]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [ŠJ‚¯‚Ü‚¹‚ñ]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª–³‚¢‚̂ňێ‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "ƒtƒ@ƒCƒ‹‚ªˆÛŽ‚³‚ê‚Ü‚·"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: ˆÛŽ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#: ../memline.c:1819
-#, 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>"
-msgstr "E316: ml_get: s %<PRId64> ‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: ƒ|ƒCƒ“ƒ^ƒuƒƒbƒN‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚· 3"
-
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "stack_idx ‚Í 0 ‚Å‚ ‚é‚ׂ«‚Å‚·"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: XV‚³‚ꂽƒuƒƒbƒN‚ª‘½‰ß‚¬‚é‚©‚à?"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: ƒ|ƒCƒ“ƒ^ƒuƒƒbƒN‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚· 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "ƒuƒƒbƒN 1 ‚ÍÁ‚³‚ꂽ?"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: s %<PRId64> ‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: ƒ|ƒCƒ“ƒ^ƒuƒƒbƒN‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "pe_line_count ‚ªƒ[ƒ‚Å‚·"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: s”Ô†‚ª”͈͊O‚Å‚·: %<PRId64> ’´‚¦‚Ä‚¢‚Ü‚·"
-
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ƒuƒƒbƒN %<PRId64> ‚ÌsƒJƒEƒ“ƒg‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "ƒXƒ^ƒbƒNƒTƒCƒY‚ª‘‚¦‚Ü‚·"
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: ƒ|ƒCƒ“ƒ^ƒuƒƒbƒN‚ÌID‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚· 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr "E773: \"%s\" ‚̃Vƒ“ƒ{ƒŠƒbƒNƒŠƒ“ƒN‚ªƒ‹[ƒv‚ɂȂÁ‚Ä‚¢‚Ü‚·"
-
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: ’ˆÓ"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"ŽŸ‚Ì–¼‘O‚ŃXƒƒbƒvƒtƒ@ƒCƒ‹‚ðŒ©‚Â‚¯‚Ü‚µ‚½ \""
-
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "ŽŸ‚̃tƒ@ƒCƒ‹‚ðŠJ‚¢‚Ä‚¢‚éÅ’† \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚æ‚è‚àV‚µ‚¢‚Å‚·!\n"
-
-#: ../memline.c:3244
-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."
-msgstr ""
-"\n"
-"(1) •ʂ̃vƒƒOƒ‰ƒ€‚ª“¯‚¶ƒtƒ@ƒCƒ‹‚ð•ÒW‚µ‚Ä‚¢‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñ.\n"
-" ‚±‚ÌꇂɂÍ, •ÏX‚ð‚µ‚Ä‚µ‚Ü‚¤‚Æ1‚‚̃tƒ@ƒCƒ‹‚ɑ΂µ‚ĈقȂé2‚‚Ì\n"
-" ƒCƒ“ƒXƒ^ƒ“ƒX‚ª‚Å‚«‚Ä‚µ‚Ü‚¤‚Ì‚Å, ‚»‚¤‚µ‚È‚¢‚悤‚É‹C‚ð‚‚¯‚Ä‚­‚¾‚³‚¢."
-
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " I—¹‚·‚é‚©, ’ˆÓ‚µ‚È‚ª‚瑱‚¯‚Ä‚­‚¾‚³‚¢.\n"
-
-#: ../memline.c:3246
-msgid "(2) An edit session for this file crashed.\n"
-msgstr "(2) ‚±‚̃tƒ@ƒCƒ‹‚Ì•ÒWƒZƒbƒVƒ‡ƒ“‚ªƒNƒ‰ƒbƒVƒ…‚µ‚½.\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " ‚±‚Ìê‡‚É‚Í \":recover\" ‚© \"vim -r "
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"\"\n"
-" ‚ðŽg—p‚µ‚Ä•ÏX‚ðƒŠƒJƒo[‚µ‚Ü‚·(\":help recovery\" ‚ðŽQÆ).\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " Šù‚É‚±‚ê‚ðs‚È‚Á‚½‚̂Ȃç‚Î, ƒXƒƒbƒvƒtƒ@ƒCƒ‹ \""
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"\"\n"
-" ‚ðÁ‚¹‚΂±‚̃ƒbƒZ[ƒW‚ð‰ñ”ð‚Å‚«‚Ü‚·.\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹ \""
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "\" ‚ªŠù‚É‚ ‚è‚Ü‚·!"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "VIM - ’ˆÓ"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ªŠù‚É‘¶Ý‚µ‚Ü‚·!"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"“Çžê—p‚ÅŠJ‚­(&O)\n"
-"‚Ƃɂ©‚­•ÒW‚·‚é(&E)\n"
-"•œŠˆ‚³‚¹‚é(&R)\n"
-"I—¹‚·‚é(&Q)\n"
-"’†Ž~‚·‚é(&A)"
-
-#: ../memline.c:3467
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"“Çžê—p‚ÅŠJ‚­(&O)\n"
-"‚Ƃɂ©‚­•ÒW‚·‚é(&E)\n"
-"•œŠˆ‚³‚¹‚é(&R)\n"
-"휂·‚é(&D)\n"
-"I—¹‚·‚é(&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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
-msgid "E326: Too many swap files found"
-msgstr "E326: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚ª‘½”Œ©‚‚©‚è‚Ü‚µ‚½"
-
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: ƒƒ‚ƒŠ‚ª‘«‚è‚Ü‚¹‚ñ! (%<PRIu64> ƒoƒCƒg‚ðŠ„“–—v‹)"
-
-#: ../menu.c:62
-msgid "E327: Part of menu-item path is not sub-menu"
-msgstr "E327: ƒƒjƒ…[ƒAƒCƒeƒ€‚̃pƒX‚Ì•”•ª‚ªƒTƒuƒƒjƒ…[‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../menu.c:63
-msgid "E328: Menu only exists in another mode"
-msgstr "E328: ƒƒjƒ…[‚Í‘¼‚̃‚[ƒh‚É‚¾‚¯‚ ‚è‚Ü‚·"
-
-#: ../menu.c:64
-#, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: \"%s\" ‚Æ‚¢‚¤ƒƒjƒ…[‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-msgid "E792: Empty menu name"
-msgstr "E792: ƒƒjƒ…[–¼‚ª‹ó‚Å‚·"
-
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: ƒƒjƒ…[ƒpƒX‚̓Tƒuƒƒjƒ…[‚ð¶‚¶‚é‚ׂ«‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: ƒƒjƒ…[ƒo[‚ɂ͒¼Úƒƒjƒ…[ƒAƒCƒeƒ€‚ð’ljÁ‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: ‹æØ‚è‚̓ƒjƒ…[ƒpƒX‚̈ꕔ‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- ƒƒjƒ…[ ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: ƒƒjƒ…[ƒpƒX‚̓ƒjƒ…[ƒAƒCƒeƒ€‚ð¶‚¶‚È‚¯‚ê‚΂¢‚¯‚Ü‚¹‚ñ"
-
-#: ../menu.c:1330
-#, c-format
-msgid "E334: Menu not found: %s"
-msgstr "E334: ƒƒjƒ…[‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ: %s"
-
-#: ../menu.c:1396
-#, c-format
-msgid "E335: Menu not defined for %s mode"
-msgstr "E335: %s ‚ɂ̓ƒjƒ…[‚ª’è‹`‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: ƒƒjƒ…[ƒpƒX‚̓Tƒuƒƒjƒ…[‚ð¶‚¶‚È‚¯‚ê‚΂¢‚¯‚Ü‚¹‚ñ"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: ƒƒjƒ…[‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ - ƒƒjƒ…[–¼‚ðŠm”F‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "%s ‚̈—’†‚ɃGƒ‰[‚ªŒŸo‚³‚ê‚Ü‚µ‚½:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "s %4ld:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: –³Œø‚ȃŒƒWƒXƒ^–¼: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "“ú–{ŒêƒƒbƒZ[ƒW–|–ó/ŠÄC: ‘º‰ª ‘¾˜Y <koron.kaoriya@gmail.com>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "Š„ž‚Ý: "
-
-#: ../message.c:988
-msgid "Press ENTER or type command to continue"
-msgstr "‘±‚¯‚é‚É‚ÍENTER‚ð‰Ÿ‚·‚©ƒRƒ}ƒ“ƒh‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s s %<PRId64>"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- Œp‘± --"
-
-#: ../message.c:2398
-msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr " SPACE/d/j: ‰æ–Ê/ƒy[ƒW/s ‰º, b/u/k: ã, q: I—¹ "
-
-#: ../message.c:3021 ../message.c:3031
-msgid "Question"
-msgstr "Ž¿–â"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"‚Í‚¢(&Y)\n"
-"‚¢‚¢‚¦(&N)"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"‚Í‚¢(&Y)\n"
-"‚¢‚¢‚¦(&N)\n"
-"ƒLƒƒƒ“ƒZƒ‹(&C)"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"‚Í‚¢(&Y)\n"
-"‚¢‚¢‚¦(&N)\n"
-"‘S‚ĕۑ¶(&A)\n"
-"‘S‚Ä•úŠü(&D)\n"
-"ƒLƒƒƒ“ƒZƒ‹(&C)"
-
-#: ../message.c:3058
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: printf() ‚̈ø”‚ª•s\\•ª‚Å‚·"
-
-#: ../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: Œx: “Çžê—pƒtƒ@ƒCƒ‹‚ð•ÏX‚µ‚Ü‚·"
-
-#: ../misc1.c:2537
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr ""
-"”Ô†‚Æ<Enter>‚ð“ü—Í‚·‚é‚©ƒ}ƒEƒX‚ŃNƒŠƒbƒN‚µ‚Ä‚­‚¾‚³‚¢ (‹ó‚ŃLƒƒƒ“ƒZƒ‹): "
-
-#: ../misc1.c:2539
-msgid "Type number and <Enter> (empty cancels): "
-msgstr "”Ô†‚Æ<Enter>‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢ (‹ó‚ŃLƒƒƒ“ƒZƒ‹): "
-
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "1 s ’ljÁ‚µ‚Ü‚µ‚½"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "1 s 휂µ‚Ü‚µ‚½"
-
-#: ../misc1.c:2593
-#, c-format
-msgid "%<PRId64> more lines"
-msgstr "%<PRId64> s ’ljÁ‚µ‚Ü‚µ‚½"
-
-#: ../misc1.c:2596
-#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "%<PRId64> s 휂µ‚Ü‚µ‚½"
-
-#: ../misc1.c:2599
-msgid " (Interrupted)"
-msgstr " (Š„ž‚Ü‚ê‚Ü‚µ‚½)"
-
-#: ../misc1.c:2635
-msgid "Beep!"
-msgstr "ƒr[ƒb!"
-
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "ŽÀs‚Ì‚½‚߂ɃVƒFƒ‹‚ðŒÄo‚µ’†: \"%s\""
-
-#: ../normal.c:183
-msgid "E349: No identifier under cursor"
-msgstr "E349: ƒJ[ƒ\\ƒ‹‚̈ʒu‚ɂ͎¯•ÊŽq‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../normal.c:1866
-msgid "E774: 'operatorfunc' is empty"
-msgstr "E774: 'operatorfunc' ƒIƒvƒVƒ‡ƒ“‚ª‹ó‚Å‚·"
-
-#: ../normal.c:2637
-msgid "Warning: terminal cannot highlight"
-msgstr "Œx: Žg—p‚µ‚Ä‚¢‚é’[––‚̓nƒCƒ‰ƒCƒg‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../normal.c:2807
-msgid "E348: No string under cursor"
-msgstr "E348: ƒJ[ƒ\\ƒ‹‚̈ʒu‚ɂ͕¶Žš—ñ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: Œ»Ý‚Ì 'foldmethod' ‚Å‚ÍÜô‚Ý‚ðÁ‹Ž‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: •ÏXƒŠƒXƒg‚ª‹ó‚Å‚·"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr "E662: •ÏXƒŠƒXƒg‚Ìæ“ª"
-
-#: ../normal.c:5901
-msgid "E663: At end of changelist"
-msgstr "E663: •ÏXƒŠƒXƒg‚Ì––”ö"
-
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "Vim‚ðI—¹‚·‚é‚É‚Í :quit<Enter> ‚Æ“ü—Í‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../ops.c:248
-#, c-format
-msgid "1 line %sed 1 time"
-msgstr "1 s‚ª %s ‚Å 1 ‰ñˆ—‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 s‚ª %s ‚Å %d ‰ñˆ—‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> s‚ª %s ‚Å 1 ‰ñˆ—‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> s‚ª %s ‚Å %d ‰ñˆ—‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> s‚ªƒCƒ“ƒfƒ“ƒg‚³‚ê‚Ü‚·... "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "1 s‚ðƒCƒ“ƒfƒ“ƒg‚µ‚Ü‚µ‚½ "
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> s‚ðƒCƒ“ƒfƒ“ƒg‚µ‚Ü‚µ‚½ "
-
-#: ../ops.c:938
-msgid "E748: No previously used register"
-msgstr "E748: ‚Ü‚¾ƒŒƒWƒXƒ^‚ðŽg—p‚µ‚Ä‚¢‚Ü‚¹‚ñ"
-
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "ƒ„ƒ“ƒN‚Å‚«‚Ü‚¹‚ñ; ‚Ƃɂ©‚­Á‹Ž"
-
-#: ../ops.c:1929
-msgid "1 line changed"
-msgstr "1 s‚ª•ÏX‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:1931
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> s‚ª•ÏX‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "1 s‚̃uƒƒbƒN‚ªƒ„ƒ“ƒN‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "1 s‚ªƒ„ƒ“ƒN‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "%<PRId64> s‚̃uƒƒbƒN‚ªƒ„ƒ“ƒN‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> s‚ªƒ„ƒ“ƒN‚³‚ê‚Ü‚µ‚½"
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353: ƒŒƒWƒXƒ^ %s ‚ɂ͉½‚à‚ ‚è‚Ü‚¹‚ñ"
-
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- ƒŒƒWƒXƒ^ ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "•s³‚ȃŒƒWƒXƒ^–¼"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# ƒŒƒWƒXƒ^:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: –¢’m‚̃ŒƒWƒXƒ^Œ^ %d ‚Å‚·"
-
-msgid ""
-"E883: search pattern and expression register may not contain two or more "
-"lines"
-msgstr "E883: ŒŸõƒpƒ^[ƒ“‚ÆŽ®ƒŒƒWƒXƒ^‚É‚Í2sˆÈã‚ðŠÜ‚ß‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> —ñ; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"‘I‘ð %s%<PRId64> / %<PRId64> s; %<PRId64> / %<PRId64> ’PŒê; %<PRId64> / "
-"%<PRId64> ƒoƒCƒg"
-
-#: ../ops.c:5105
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"‘I‘ð %s%<PRId64> / %<PRId64> s; %<PRId64> / %<PRId64> ’PŒê; %<PRId64> / "
-"%<PRId64> •¶Žš; %<PRId64> / %<PRId64> ƒoƒCƒg"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"—ñ %s / %s; s %<PRId64> of %<PRId64>; ’PŒê %<PRId64> / %<PRId64>; ƒoƒCƒg "
-"%<PRId64> / %<PRId64>"
-
-#: ../ops.c:5133
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"—ñ %s / %s; s %<PRId64> / %<PRId64>; ’PŒê %<PRId64> / %<PRId64>; •¶Žš "
-"%<PRId64> / %<PRId64>; ƒoƒCƒg %<PRId64> of %<PRId64>"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> for BOM)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=%N ƒy[ƒW"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "Vim ‚ðŽg‚Á‚Ä‚­‚ê‚Ä‚ ‚肪‚Æ‚¤"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: –¢’m‚̃IƒvƒVƒ‡ƒ“‚Å‚·"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: ƒIƒvƒVƒ‡ƒ“‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: modeline ‚ł͋–‰Â‚³‚ê‚Ü‚¹‚ñ"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr "E846: ƒL[ƒR[ƒh‚ªÝ’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../option.c:2924
-msgid "E521: Number required after ="
-msgstr "E521: = ‚ÌŒã‚É‚Í”Žš‚ª•K—v‚Å‚·"
-
-#: ../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³‚È•¶Žš‚Å‚· <%s>"
-
-#, c-format
-msgid "For option %s"
-msgstr "ƒIƒvƒVƒ‡ƒ“: %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'‚Ì’l‚É–µ‚‚ª‚ ‚è‚Ü‚·"
-
-#: ../option.c:3966
-msgid "E835: Conflicts with value of 'fillchars'"
-msgstr "E835: 'fillchars'‚Ì’l‚É–µ‚‚ª‚ ‚è‚Ü‚·"
-
-#: ../option.c:4163
-msgid "E524: Missing colon"
-msgstr "E524: ƒRƒƒ“‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../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: ƒJƒ“ƒ}‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../option.c:4239
-msgid "E528: Must specify a ' value"
-msgstr "E528: ' ‚Ì’l‚ðŽw’肵‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#: ../option.c:4271
-msgid "E595: contains unprintable or wide character"
-msgstr "E595: •\\ަ‚Å‚«‚È‚¢•¶Žš‚©ƒƒCƒh•¶Žš‚ðŠÜ‚ñ‚Å‚¢‚Ü‚·"
-
-#: ../option.c:4469
-#, c-format
-msgid "E535: Illegal character after <%c>"
-msgstr "E535: <%c> ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚·"
-
-#: ../option.c:4534
-msgid "E536: comma required"
-msgstr "E536: ƒJƒ“ƒ}‚ª•K—v‚Å‚·"
-
-#: ../option.c:4543
-#, c-format
-msgid "E537: 'commentstring' must be empty or contain %s"
-msgstr "E537: 'commentstring' ‚Í‹ó‚Å‚ ‚é‚© %s ‚ðŠÜ‚Þ•K—v‚ª‚ ‚è‚Ü‚·"
-
-#: ../option.c:4928
-msgid "E540: Unclosed expression sequence"
-msgstr "E540: Ž®‚ªI—¹‚µ‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../option.c:4932
-msgid "E541: too many items"
-msgstr "E541: —v‘f‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../option.c:4934
-msgid "E542: unbalanced groups"
-msgstr "E542: ƒOƒ‹[ƒv‚ª’Þ‡‚¢‚Ü‚¹‚ñ"
-
-#: ../option.c:5148
-msgid "E590: A preview window already exists"
-msgstr "E590: ƒvƒŒƒrƒ…[ƒEƒBƒ“ƒhƒE‚ªŠù‚É‘¶Ý‚µ‚Ü‚·"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr ""
-"W17: ƒAƒ‰ƒrƒA•¶Žš‚É‚ÍUTF-8‚ª•K—v‚Ȃ̂Å, ':set encoding=utf-8' ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: Å’á %d ‚Ìs”‚ª•K—v‚Å‚·"
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: Å’á %d ‚̃Jƒ‰ƒ€•‚ª•K—v‚Å‚·"
-
-#: ../option.c:6011
-#, c-format
-msgid "E355: Unknown option: %s"
-msgstr "E355: –¢’m‚̃IƒvƒVƒ‡ƒ“‚Å‚·: %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
-#, c-format
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: ”Žš‚ª•K—v‚Å‚·: &%s = '%s'"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- ’[––ƒR[ƒh ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- ƒOƒ[ƒoƒ‹ƒIƒvƒVƒ‡ƒ“’l ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- ƒ[ƒJƒ‹ƒIƒvƒVƒ‡ƒ“’l ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- ƒIƒvƒVƒ‡ƒ“ ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: get_varp ƒGƒ‰["
-
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': %s ‚ɑΉž‚·‚é•¶Žš‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': ƒZƒ~ƒRƒƒ“‚ÌŒã‚É—]•ª‚È•¶Žš‚ª‚ ‚è‚Ü‚·: %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"ƒVƒFƒ‹‚ðŽÀs‚Å‚«‚Ü‚¹‚ñ "
-
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"ƒVƒFƒ‹‚ª’l‚ð•Ô‚µ‚Ü‚µ‚½ "
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-"\n"
-"ƒZƒLƒ…ƒŠƒeƒBƒRƒ“ƒeƒLƒXƒg‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ "
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-"\n"
-"ƒZƒLƒ…ƒŠƒeƒBƒRƒ“ƒeƒLƒXƒg‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ "
-
-#, c-format
-msgid "Could not set security context %s for %s"
-msgstr "ƒZƒLƒ…ƒŠƒeƒBƒRƒ“ƒeƒLƒXƒg %s ‚ð %s ‚ÉÝ’è‚Å‚«‚Ü‚¹‚ñ"
-
-#, c-format
-msgid "Could not get security context %s for %s. Removing it!"
-msgstr "ƒZƒLƒ…ƒŠƒeƒBƒRƒ“ƒeƒLƒXƒg %s ‚ð %s ‚©‚çŽæ“¾‚Å‚«‚Ü‚¹‚ñ. 휂µ‚Ü‚·!"
-
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = \"%s\""
-
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: path‚É‚Í \"%s\" ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚É %%%c ‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚É—\\Šú‚¹‚Ê %%%c ‚ª‚ ‚è‚Ü‚µ‚½"
-
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚É ] ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚Å‚Í %%%c ‚̓Tƒ|[ƒg‚³‚ê‚Ü‚¹‚ñ"
-
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚Ì‘O’u‚É–³Œø‚È %%%c ‚ª‚ ‚è‚Ü‚·"
-
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: ƒtƒH[ƒ}ƒbƒg•¶Žš—ñ‚É–³Œø‚È %%%c ‚ª‚ ‚è‚Ü‚·"
-
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: 'errorformat' ‚Ƀpƒ^[ƒ“‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: ƒfƒBƒŒƒNƒgƒŠ–¼‚ª–³‚¢‚©‹ó‚Å‚·"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: —v‘f‚ª‚à‚¤‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d of %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (s‚ªíœ‚³‚ê‚Ü‚µ‚½)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: quickfix ƒXƒ^ƒbƒN‚Ì––”ö‚Å‚·"
-
-#: ../quickfix.c:1869
-msgid "E381: At top of quickfix stack"
-msgstr "E381: quickfix ƒXƒ^ƒbƒN‚Ìæ“ª‚Å‚·"
-
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "ƒGƒ‰[ˆê—— %d of %d; %d ŒÂƒGƒ‰["
-
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: 'buftype' ƒIƒvƒVƒ‡ƒ“‚ªÝ’肳‚ê‚Ä‚¢‚é‚̂őž‚݂܂¹‚ñ"
-
-#: ../quickfix.c:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr "E683: ƒtƒ@ƒCƒ‹–¼‚ª–³‚¢‚©–³Œø‚ȃpƒ^[ƒ“‚Å‚·"
-
-#: ../quickfix.c:2911
-#, c-format
-msgid "Cannot open file \"%s\""
-msgstr "ƒtƒ@ƒCƒ‹ \"%s\" ‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../quickfix.c:3429
-msgid "E681: Buffer is not loaded"
-msgstr "E681: ƒoƒbƒtƒ@‚͓ǂݞ‚Ü‚ê‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#: ../quickfix.c:3487
-msgid "E777: String or List expected"
-msgstr "E777: •¶Žš—ñ‚©ƒŠƒXƒg‚ª•K—v‚Å‚·"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: –³Œø‚È€–Ú‚Å‚·: %s%%[]"
-
-#
-#: ../regexp.c:374
-#, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E769: %s[ ‚ÌŒã‚É ] ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: %s%%( ‚ª’ނ臂Á‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: %s( ‚ª’ނ臂Á‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: %s) ‚ª’ނ臂Á‚Ä‚¢‚Ü‚¹‚ñ"
-
-#
-#: ../regexp.c:378
-msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( ‚̓RƒR‚ł͋–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 ‚»‚Ì‘¼‚̓RƒR‚ł͋–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#
-#: ../regexp.c:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: %s%%[ ‚ÌŒã‚É ] ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: %s%%[] ‚ª‹ó‚Å‚·"
-
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: ƒpƒ^[ƒ“‚ª’·‰ß‚¬‚Ü‚·"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: \\z( ‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: %s( ‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: \\z( ‚ª’ނ臂Á‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: %s@ ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: •¡ŽG‚È %s{...} ‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61:%s* ‚ª“ü‚êŽq‚ɂȂÁ‚Ä‚¢‚Ü‚·"
-
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62:%s%c ‚ª“ü‚êŽq‚ɂȂÁ‚Ä‚¢‚Ü‚·"
-
-#
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: \\_ ‚Ì–³Œø‚ÈŽg—p•û–@‚Å‚·"
-
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64:%s%c ‚ÌŒã‚É‚È‚É‚à‚ ‚è‚Ü‚¹‚ñ"
-
-#
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: •s³‚ÈŒã•ûŽQƂł·"
-
-#
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: \\z ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½"
-
-#
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: %s%%[dxouU] ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½"
-
-#
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: %s%% ‚ÌŒã‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚µ‚½"
-
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: %s{...} “à‚É•¶–@ƒGƒ‰[‚ª‚ ‚è‚Ü‚·"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "ŠO•”‚Ì•”•ªŠY“–:\n"
-
-#, c-format
-msgid "E888: (NFA regexp) cannot repeat %s"
-msgstr "E888: (NFA ³‹K•\\Œ») ŒJ‚è•Ô‚¹‚Ü‚¹‚ñ %s"
-
-#: ../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 ‚݂̂ª‘±‚¯‚ç‚ê‚Ü‚·B³‹K•\\Œ»ƒGƒ“ƒWƒ“‚ÍŽ©“®‘I"
-"‘ð‚³‚ê‚Ü‚·B"
-
-msgid "Switching to backtracking RE engine for pattern: "
-msgstr "ŽŸ‚̃pƒ^[ƒ“‚ɃoƒbƒNƒgƒ‰ƒbƒLƒ“ƒO RE ƒGƒ“ƒWƒ“‚ð“K—p‚µ‚Ü‚·: "
-
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr "E865: (NFA) Šú‘Ò‚æ‚è‘‚­³‹K•\\Œ»‚ÌI’[‚É“ž’B‚µ‚Ü‚µ‚½"
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr "E866: (NFA ³‹K•\\Œ») ˆÊ’u‚ªŒë‚Á‚Ä‚¢‚Ü‚·: %c"
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr "E877: (NFA ³‹K•\\Œ») –³Œø‚È•¶ŽšƒNƒ‰ƒX: %<PRId64>"
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr "E867: (NFA) –¢’m‚̃IƒyƒŒ[ƒ^‚Å‚·: '\\z%c'"
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) –¢’m‚̃IƒyƒŒ[ƒ^‚Å‚·: '\\%%%c'"
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr "E869: (NFA) –¢’m‚̃IƒyƒŒ[ƒ^‚Å‚·: '\\@%c'"
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr "E870: (NFA ³‹K•\\Œ») ŒJ‚è•Ô‚µ‚̧ŒÀ‰ñ”‚ð“Çž’†‚ɃGƒ‰["
-
-#. 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 ³‹K•\\Œ») ŒJ‚è•Ô‚µ ‚ÌŒã‚É ŒJ‚è•Ô‚µ ‚͂ł«‚Ü‚¹‚ñ!"
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr "E872: (NFA ³‹K•\\Œ») '(' ‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../regexp_nfa.c:2042
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E879: (NFA ³‹K•\\Œ») \\z( ‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr "E873: (NFA ³‹K•\\Œ») I’[‹L†‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr "E874: (NFA) ƒXƒ^ƒbƒN‚ðƒ|ƒbƒv‚Å‚«‚Ü‚¹‚ñ!"
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-"E875: (NFA ³‹K•\\Œ») (Œã’u•¶Žš—ñ‚ðNFA‚ɕϊ·’†‚É) ƒXƒ^ƒbƒN‚ÉŽc‚³‚ꂽƒXƒe[ƒg‚ª"
-"‘½‰ß‚¬‚Ü‚·"
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr "E876: (NFA ³‹K•\\Œ») NFA‘S‘Ì‚ð•Û‘¶‚·‚é‚ɂ͋󂫃Xƒy[ƒX‚ª‘«‚è‚Ü‚¹‚ñ"
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"NFA³‹K•\\Œ»ƒGƒ“ƒWƒ“—p‚̃ƒOƒtƒ@ƒCƒ‹‚𑞗p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñBƒƒO‚Í•W€o—Í‚É"
-"o—Í‚µ‚Ü‚·B"
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) ƒƒOƒtƒ@ƒCƒ‹ %s ‚ðŠJ‚¯‚Ü‚¹‚ñ!"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "NFA³‹K•\\Œ»ƒGƒ“ƒWƒ“—p‚̃ƒOƒtƒ@ƒCƒ‹‚𑞗p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñB"
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " ‰¼‘z’uŠ·"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " ’uŠ·"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " ”½“]"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " ‘}“ü"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (‘}“ü)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (’uŠ·)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (‰¼‘z’uŠ·)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " ƒwƒuƒ‰ƒC"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " ƒAƒ‰ƒrƒA"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (Œ¾Œê)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (“\\‚è•t‚¯)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " ƒrƒWƒ…ƒAƒ‹"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " ƒrƒWƒ…ƒAƒ‹ s"
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " ƒrƒWƒ…ƒAƒ‹ ‹éŒ`"
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " ƒZƒŒƒNƒg"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " sŽwŒü‘I‘ð"
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " ‹éŒ`‘I‘ð"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "‹L˜^’†"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: –³Œø‚ÈŒŸõ•¶Žš—ñ‚Å‚·: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: ã‚܂ŌŸõ‚µ‚Ü‚µ‚½‚ªŠY“–‰ÓŠ‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: ‰º‚܂ŌŸõ‚µ‚Ü‚µ‚½‚ªŠY“–‰ÓŠ‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: ';' ‚Ì‚ ‚Æ‚É‚Í '?' ‚© '/' ‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é"
-
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (‘O‚É—ñ‹“‚µ‚½ŠY“–‰ÓŠ‚ðŠÜ‚Þ)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- ƒCƒ“ƒNƒ‹[ƒh‚³‚ꂽƒtƒ@ƒCƒ‹ "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "Œ©‚‚©‚è‚Ü‚¹‚ñ "
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "ƒpƒX‚É ----\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (Šù‚É—ñ‹“)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " Œ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "ƒCƒ“ƒNƒ‹[ƒh‚³‚ꂽƒtƒ@ƒCƒ‹‚ðƒXƒLƒƒƒ“’†: %s"
-
-#: ../search.c:4216
-#, c-format
-msgid "Searching included file %s"
-msgstr "ƒCƒ“ƒNƒ‹[ƒh‚³‚ꂽƒtƒ@ƒCƒ‹‚ðƒXƒLƒƒƒ“’† %s"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: Œ»Ýs‚ÉŠY“–‚ª‚ ‚è‚Ü‚·"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "‘S‚ẴCƒ“ƒNƒ‹[ƒh‚³‚ꂽƒtƒ@ƒCƒ‹‚ªŒ©‚‚©‚è‚Ü‚µ‚½"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "ƒCƒ“ƒNƒ‹[ƒhƒtƒ@ƒCƒ‹‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: ’è‹`‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: ƒpƒ^[ƒ“‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Substitute "
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-"\n"
-"# ÅŒã‚Ì %sŒŸõƒpƒ^[ƒ“:\n"
-"~"
-
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚Ì‘Ž®ƒGƒ‰[‚Å‚·"
-
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr "E758: ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ªØŽæ‚ç‚ê‚Ä‚¢‚邿‚¤‚Å‚·"
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr "%s (%d s–Ú) ‚É‘±‚­ƒeƒLƒXƒg: %s"
-
-#: ../spell.c:954
-#, c-format
-msgid "Affix name too long in %s line %d: %s"
-msgstr "%s (%d s–Ú) ‚Ì affix –¼‚ª’·‰ß‚¬‚Ü‚·: %s"
-
-#: ../spell.c:955
-msgid "E761: Format error in affix file FOL, LOW or UPP"
-msgstr ""
-"E761: affixƒtƒ@ƒCƒ‹‚Ì FOL, LOW ‚à‚µ‚­‚Í UPP ‚̃tƒH[ƒ}ƒbƒg‚ɃGƒ‰[‚ª‚ ‚è‚Ü‚·"
-
-#: ../spell.c:957
-msgid "E762: Character in FOL, LOW or UPP is out of range"
-msgstr "E762: FOL, LOW ‚à‚µ‚­‚Í UPP ‚Ì•¶Žš‚ª”͈͊O‚Å‚·"
-
-#: ../spell.c:958
-msgid "Compressing word tree..."
-msgstr "’PŒêƒcƒŠ[‚ðˆ³k‚µ‚Ä‚¢‚Ü‚·..."
-
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: ƒXƒyƒ‹ƒ`ƒFƒbƒN‚Í–³Œø‰»‚³‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
-"Œx: ’PŒêƒŠƒXƒg \"%s.%s.spl\" ‚¨‚æ‚Ñ \"%s.ascii.spl\" ‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../spell.c:2473
-#, c-format
-msgid "Reading spell file \"%s\""
-msgstr "ƒXƒyƒ‹ƒtƒ@ƒCƒ‹ \"%s\" ‚ð“Çž’†"
-
-#: ../spell.c:2496
-msgid "E757: This does not look like a spell file"
-msgstr "E757: ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚悤‚Å‚·"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: ŒÃ‚¢ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚Ȃ̂Å, ƒAƒbƒvƒf[ƒg‚µ‚Ä‚­‚¾‚³‚¢"
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr "E772: ‚æ‚èV‚µ‚¢ƒo[ƒWƒ‡ƒ“‚Ì Vim —p‚̃Xƒyƒ‹ƒtƒ@ƒCƒ‹‚Å‚·"
-
-#: ../spell.c:2602
-msgid "E770: Unsupported section in spell file"
-msgstr "E770: ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ɃTƒ|[ƒg‚µ‚Ä‚¢‚È‚¢ƒZƒNƒVƒ‡ƒ“‚ª‚ ‚è‚Ü‚·"
-
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Œx9: %s ‚Æ‚¢‚¤”͈͂̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../spell.c:4550
-#, c-format
-msgid "Reading affix file %s ..."
-msgstr "affix ƒtƒ@ƒCƒ‹ %s ‚ð“Çž’†..."
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr "%s (%d s–Ú) ‚Ì’PŒê‚ð•ÏŠ·‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½: %s"
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr "%s “à‚ÌŽŸ‚̕ϊ·‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ: %s ‚©‚ç %s ‚Ö"
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "%s “à‚Ì %d s–Ú‚Ì FLAG ‚É–³Œø‚È’l‚ª‚ ‚è‚Ü‚·: %s"
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr "%s “à‚Ì %d s–ڂɃtƒ‰ƒO‚Ì“ñdŽg—p‚ª‚ ‚è‚Ü‚·: %s"
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"%s ‚Ì %d s–Ú‚Ì PFX €–Ú‚ÌŒã‚Ì COMPOUNDFORBIDFLAG ‚Ì’è‹`‚ÍŒë‚Á‚½Œ‹‰Ê‚ð¶‚¶‚é"
-"‚±‚Æ‚ª‚ ‚è‚Ü‚·"
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"%s ‚Ì %d s–Ú‚Ì PFX €–Ú‚ÌŒã‚Ì COMPOUNDPERMITFLAG ‚Ì’è‹`‚ÍŒë‚Á‚½Œ‹‰Ê‚ð¶‚¶‚é"
-"‚±‚Æ‚ª‚ ‚è‚Ü‚·"
-
-#: ../spell.c:4747
-#, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "COMPOUNDRULES ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·. ƒtƒ@ƒCƒ‹ %s ‚Ì %d s–Ú: %s"
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì COMPOUNDWORDMAX ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·: %s"
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì COMPOUNDMIN ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·: %s"
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì COMPOUNDSYLMAX ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·: %s"
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì CHECKCOMPOUNDPATTERN ‚Ì’l‚ÉŒë‚肪‚ ‚è‚Ü‚·: %s"
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr ""
-"%s ‚Ì %d s–Ú‚Ì ˜A‘± affix ƒuƒƒbƒN‚̃tƒ‰ƒO‚Ì‘g‡‚¹‚ɈႢ‚ª‚ ‚è‚Ü‚·: %s"
-
-#: ../spell.c:4850
-#, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚É d•¡‚µ‚½ affix ‚ðŒŸo‚µ‚Ü‚µ‚½: %s"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-"%s ‚Ì %d s–Ú‚Ì affix ‚Í BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST "
-"‚ÉŽg—p‚µ‚Ä‚­‚¾‚³‚¢: %s"
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Å‚Í Y ‚© N ‚ª•K—v‚Å‚·: %s"
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì ðŒ‚͉ó‚ê‚Ä‚¢‚Ü‚·: %s"
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr "%s ‚Ì %d s–Ú‚É‚Í REP(SAL) ‚̉ñ”‚ª•K—v‚Å‚·"
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr "%s ‚Ì %d s–Ú‚É‚Í MAP ‚̉ñ”‚ª•K—v‚Å‚·"
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr "%s ‚Ì %d s–Ú‚Ì MAP ‚Éd•¡‚µ‚½•¶Žš‚ª‚ ‚è‚Ü‚·"
-
-#: ../spell.c:5176
-#, c-format
-msgid "Unrecognized or duplicate item in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚É ”Fޝ‚Å‚«‚È‚¢‚©d•¡‚µ‚½€–Ú‚ª‚ ‚è‚Ü‚·: %s"
-
-#: ../spell.c:5197
-#, c-format
-msgid "Missing FOL/LOW/UPP line in %s"
-msgstr "%s s–Ú‚É FOL/LOW/UPP ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../spell.c:5220
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr "SYLLABLE ‚ªŽw’肳‚ê‚È‚¢ COMPOUNDSYLMAX"
-
-#: ../spell.c:5236
-msgid "Too many postponed prefixes"
-msgstr "’x‰„Œã’uŽq‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../spell.c:5238
-msgid "Too many compound flags"
-msgstr "•¡‡ƒtƒ‰ƒO‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr "’x‰„Œã’uŽq ‚Æ/‚à‚µ‚­‚Í •¡‡ƒtƒ‰ƒO‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr "SOFO%s s‚ª %s ‚É‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr "SALs ‚Æ SOFOs ‚ª %s ‚Å—¼•ûŽw’肳‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr "%s ‚Ì %d s‚Ì ƒtƒ‰ƒO‚ª”’l‚ł͂ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì ƒtƒ‰ƒO‚ª•s³‚Å‚·: %s"
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr "’l %s ‚Í‘¼‚Ì .aff ƒtƒ@ƒCƒ‹‚ÅŽg—p‚³‚ꂽ‚̂ƈقȂè‚Ü‚·"
-
-#: ../spell.c:5602
-#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Ž«‘ƒtƒ@ƒCƒ‹ %s ‚ðƒXƒLƒƒƒ“’†..."
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr "E760: %s ‚ɂ͒PŒê”‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "s %6d, ’PŒê %6d - %s"
-
-#: ../spell.c:5691
-#, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Å d•¡’PŒê‚ªŒ©‚‚©‚è‚Ü‚µ‚½: %s"
-
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr "d•¡‚Ì‚¤‚¿Å‰‚Ì’PŒê‚Í %s ‚Ì %d s–Ú‚Å‚·: %s"
-
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr "%d ŒÂ‚Ì’PŒê‚ªŒ©‚‚©‚è‚Ü‚µ‚½ (%s “à)"
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr "”ñASCII•¶Žš‚ðŠÜ‚Þ %d ŒÂ‚Ì’PŒê‚𖳎‹‚µ‚Ü‚µ‚½ (%s “à)"
-
-#: ../spell.c:6115
-#, c-format
-msgid "Reading word file %s ..."
-msgstr "•W€“ü—Í‚©‚ç“Çž‚Ý’† %s ..."
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì d•¡‚µ‚½ /encoding= s‚𖳎‹‚µ‚Ü‚µ‚½: %s"
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì ’PŒê‚ÌŒã‚Ì /encoding= s‚𖳎‹‚µ‚Ü‚µ‚½: %s"
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì d•¡‚µ‚½ /regions= s‚𖳎‹‚µ‚Ü‚µ‚½: %s"
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú, ”͈͎w’肪‘½‰ß‚¬‚Ü‚·: %s"
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú‚Ì d•¡‚µ‚½ / s‚𖳎‹‚µ‚Ü‚µ‚½: %s"
-
-#: ../spell.c:6224
-#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú –³Œø‚È nr —̈æ‚Å‚·: %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "%s ‚Ì %d s–Ú ”Fޝ•s”\\‚ȃtƒ‰ƒO‚Å‚·: %s"
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr "”ñASCII•¶Žš‚ðŠÜ‚Þ %d ŒÂ‚Ì’PŒê‚𖳎‹‚µ‚Ü‚µ‚½"
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "ƒm[ƒh %d ŒÂ(‘S %d ŒÂ’†) ‚ðˆ³k‚µ‚Ü‚µ‚½; Žc‚è %d (%d%%)"
-
-#: ../spell.c:7340
-msgid "Reading back spell file..."
-msgstr "ƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ð‹t“Çž’†"
-
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
-msgid "Performing soundfolding..."
-msgstr "‰¹ºôž‚Ý‚ðŽÀs’†..."
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "‰¹ºôž‚ÝŒã‚Ì‘’PŒê”: %<PRId64>"
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr "‘’PŒê”: %d"
-
-#: ../spell.c:7655
-#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "C³Œó•âƒtƒ@ƒCƒ‹ \"%s\" ‚𑞂ݒ†..."
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr "„’胃‚ƒŠŽg—p—Ê: %d ƒoƒCƒg"
-
-#: ../spell.c:7820
-msgid "E751: Output file name must not have region name"
-msgstr "E751: o—̓tƒ@ƒCƒ‹–¼‚ɂ͔͈͖¼‚ðŠÜ‚ß‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../spell.c:7822
-msgid "E754: Only up to 8 regions supported"
-msgstr "E754: ”ÍˆÍ‚Í 8 ŒÂ‚܂łµ‚©ƒTƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../spell.c:7846
-#, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E755: –³Œø‚Ȕ͈͂ł·: %s"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr "Œx: •¡‡ƒtƒ‰ƒO‚Æ NOBREAK ‚ª—¼•û‚Æ‚àŽw’肳‚ê‚Ü‚µ‚½"
-
-#: ../spell.c:7920
-#, c-format
-msgid "Writing spell file %s ..."
-msgstr "ƒXƒyƒ‹ƒtƒ@ƒCƒ‹ %s ‚𑞂ݒ†..."
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr "ŽÀs‚µ‚Ü‚µ‚½!"
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ‚É‚Í %<PRId64> ŒÂ‚̃Gƒ“ƒgƒŠ‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../spell.c:8074
-#, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "’PŒê '%.*s' ‚ª %s ‚©‚ç휂³‚ê‚Ü‚µ‚½"
-
-#: ../spell.c:8117
-#, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "’PŒê '%.*s' ‚ª %s ‚֒ljÁ‚³‚ê‚Ü‚µ‚½"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: ’PŒê‚Ì•¶Žš‚ªƒXƒyƒ‹ƒtƒ@ƒCƒ‹‚ƈقȂè‚Ü‚·"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Žc”O‚Å‚·‚ª, C³Œó•â‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Žc”O‚Å‚·‚ª, C³Œó•â‚Í %<PRId64> ŒÂ‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "\"%.*s\" ‚ðŽŸ‚Ö•ÏŠ·:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: ƒXƒyƒ‹’uŠ·‚ª‚Ü‚¾ŽÀs‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Œ©‚‚©‚è‚Ü‚¹‚ñ: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: .sug ƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚悤‚Å‚·: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: ŒÃ‚¢ .sug ƒtƒ@ƒCƒ‹‚Ȃ̂Å, ƒAƒbƒvƒf[ƒg‚µ‚Ä‚­‚¾‚³‚¢: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: ‚æ‚èV‚µ‚¢ƒo[ƒWƒ‡ƒ“‚Ì Vim —p‚Ì .sug ƒtƒ@ƒCƒ‹‚Å‚·: %s"
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: .sug ƒtƒ@ƒCƒ‹‚ª .spl ƒtƒ@ƒCƒ‹‚ƈê’v‚µ‚Ü‚¹‚ñ: %s"
-
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: .sug ƒtƒ@ƒCƒ‹‚̓Ǟ’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½: %s"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: MAP ƒGƒ“ƒgƒŠ‚Éd•¡•¶Žš‚ª‘¶Ý‚µ‚Ü‚·"
-
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "‚±‚̃oƒbƒtƒ@‚É’è‹`‚³‚ꂽ\\•¶—v‘f‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: •s³‚Ȉø”‚Å‚·: %s"
-
-msgid "syntax iskeyword "
-msgstr "ƒVƒ“ƒ^ƒbƒNƒX—p iskeyword "
-
-#: ../syntax.c:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: ‚»‚̂悤‚È\\•¶ƒNƒ‰ƒXƒ^‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "CŒ¾Œê•—ƒRƒƒ“ƒg‚©‚瓯Šú’†"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "”ñ“¯Šú"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "“¯ŠúŠJŽn "
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr " s‘O(ƒgƒbƒvs‚æ‚è‚à)"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- \\•¶“¯Šú—v‘f ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"—v‘fã‚Å“¯Šú’†"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- \\•¶—v‘f ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: ‚»‚̂悤‚È\\•¶ƒNƒ‰ƒXƒ^‚Í‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "minimal "
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "maximal "
-
-#: ../syntax.c:3513
-msgid "; match "
-msgstr "; ŠY“– "
-
-#: ../syntax.c:3515
-msgid " line breaks"
-msgstr " ŒÂ‚̉üs"
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: ‚±‚Ìꊂł͈ø”contains‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../syntax.c:4096
-msgid "E844: invalid cchar value"
-msgstr "E844: –³Œø‚Ècchar‚Ì’l‚Å‚·"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: ‚±‚±‚ł̓Oƒ‹[ƒv‚Í‹–‰Â‚³‚ê‚Ü‚¹‚ñ"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: %s ‚͈̔͗v‘f‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: ƒtƒ@ƒCƒ‹–¼‚ª•K—v‚Å‚·"
-
-#: ../syntax.c:4221
-msgid "E847: Too many syntax includes"
-msgstr "E847: \\•¶‚ÌŽæ‚èž‚Ý(include)‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../syntax.c:4303
-#, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E789: ']' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#, c-format
-msgid "E890: trailing char after ']': %s]%s"
-msgstr "E890: ']' ‚ÌŒã‚ë‚É—]•ª‚È•¶Žš‚ª‚ ‚è‚Ü‚·: %s]%s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: '=' ‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: ˆø”‚ª‘«‚è‚Ü‚¹‚ñ: \\•¶”ÍˆÍ %s"
-
-#: ../syntax.c:4870
-msgid "E848: Too many syntax clusters"
-msgstr "E848: \\•¶ƒNƒ‰ƒXƒ^‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: ƒNƒ‰ƒXƒ^‚ªŽw’肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: ƒpƒ^[ƒ“‹æØ‚肪Œ©‚‚©‚è‚Ü‚¹‚ñ: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: ƒpƒ^[ƒ“‚Ì‚ ‚ƂɃSƒ~‚ª‚ ‚è‚Ü‚·: %s"
-
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: \\•¶“¯Šú: ˜A‘±sƒpƒ^[ƒ“‚ª2“xŽw’肳‚ê‚Ü‚µ‚½"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: •s³‚Ȉø”‚Å‚·: %s"
-
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: “™†‚ª‚ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: ‹ó‚̈ø”: %s"
-
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %s ‚̓RƒR‚ł͋–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %s ‚Í“à—eƒŠƒXƒg‚Ìæ“ª‚łȂ¯‚ê‚΂Ȃç‚È‚¢"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: –¢’m‚̃Oƒ‹[ƒv–¼: %s"
-
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: –³Œø‚È :syntax ‚̃TƒuƒRƒ}ƒ“ƒh: %s"
-
-#: ../syntax.c:5854
-msgid ""
-" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-msgstr ""
-" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-
-#: ../syntax.c:6146
-msgid "E679: recursive loop loading syncolor.vim"
-msgstr "E679: syncolor.vim ‚ÌÄ‹AŒÄ‚Ño‚µ‚ðŒŸo‚µ‚Ü‚µ‚½"
-
-#: ../syntax.c:6256
-#, c-format
-msgid "E411: highlight group not found: %s"
-msgstr "E411: ƒnƒCƒ‰ƒCƒgƒOƒ‹[ƒv‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ: %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: ƒOƒ‹[ƒv‚ªÝ’肳‚ê‚Ä‚¢‚é‚̂ŃnƒCƒ‰ƒCƒgƒŠƒ“ƒN‚Í–³Ž‹‚³‚ê‚Ü‚·"
-
-#: ../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³‚È’l‚Å‚·: %s"
-
-#: ../syntax.c:6496
-msgid "E419: FG color unknown"
-msgstr "E419: –¢’m‚Ì‘OŒiF‚Å‚·"
-
-#: ../syntax.c:6504
-msgid "E420: BG color unknown"
-msgstr "E420: –¢’m‚Ì”wŒiF‚Å‚·"
-
-#: ../syntax.c:6564
-#, c-format
-msgid "E421: Color name or number not recognized: %s"
-msgstr "E421: ƒJƒ‰[–¼‚â”Ô†‚ð”Fޝ‚Å‚«‚Ü‚¹‚ñ: %s"
-
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: I’[ƒR[ƒh‚ª’·‰ß‚¬‚Ü‚·: %s"
-
-#: ../syntax.c:6753
-#, c-format
-msgid "E423: Illegal argument: %s"
-msgstr "E423: •s³‚Ȉø”‚Å‚·: %s"
-
-#: ../syntax.c:6925
-msgid "E424: Too many different highlighting attributes in use"
-msgstr "E424: ‘½‚­‚̈قȂéƒnƒCƒ‰ƒCƒg‘®«‚ªŽg‚í‚ê‰ß‚¬‚Ä‚¢‚Ü‚·"
-
-#: ../syntax.c:7427
-msgid "E669: Unprintable character in group name"
-msgstr "E669: ƒOƒ‹[ƒv–¼‚Ɉóü•s‰Â”\\‚È•¶Žš‚ª‚ ‚è‚Ü‚·"
-
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: ƒOƒ‹[ƒv–¼‚É•s³‚È•¶Žš‚ª‚ ‚è‚Ü‚·"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr "E849: ƒnƒCƒ‰ƒCƒg‚Æ\\•¶ƒOƒ‹[ƒv‚ª‘½‰ß‚¬‚Ü‚·"
-
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: ƒ^ƒOƒXƒ^ƒbƒN‚Ì––”ö‚Å‚·"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: ƒ^ƒOƒXƒ^ƒbƒN‚Ìæ“ª‚Å‚·"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: ʼn‚ÌŠY“–ƒ^ƒO‚ð’´‚¦‚Ė߂邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#: ../tag.c:504
-#, c-format
-msgid "E426: tag not found: %s"
-msgstr "E426: ƒ^ƒO‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ: %s"
-
-#: ../tag.c:528
-msgid " # pri kind tag"
-msgstr " # pri kind tag"
-
-#: ../tag.c:531
-msgid "file\n"
-msgstr "ƒtƒ@ƒCƒ‹\n"
-
-#: ../tag.c:829
-msgid "E427: There is only one matching tag"
-msgstr "E427: ŠY“–ƒ^ƒO‚ª1‚‚¾‚¯‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: ÅŒã‚ÉŠY“–‚·‚éƒ^ƒO‚ð’´‚¦‚Äi‚Þ‚±‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "ƒtƒ@ƒCƒ‹ \"%s\" ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "ƒ^ƒO %d (‘S%d%s)"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " ‚©‚»‚êˆÈã"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " ƒ^ƒO‚ðˆÙ‚È‚écase‚ÅŽg—p‚µ‚Ü‚·!"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: ƒtƒ@ƒCƒ‹ \"%s\" ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # TO ƒ^ƒO FROM s in file/text"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "ƒ^ƒOƒtƒ@ƒCƒ‹ %s ‚ðŒŸõ’†"
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr "ƒ^ƒOƒtƒ@ƒCƒ‹“à‚Ì’·‚¢s‚𖳎‹‚µ‚Ü‚·"
-
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: ƒ^ƒOƒtƒ@ƒCƒ‹ \"%s\" ‚̃tƒH[ƒ}ƒbƒg‚ɃGƒ‰[‚ª‚ ‚è‚Ü‚·"
-
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "’¼‘O‚Ì %<PRId64> ƒoƒCƒg"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: ƒ^ƒOƒtƒ@ƒCƒ‹‚ªƒ\\[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ: %s"
-
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: ƒ^ƒOƒtƒ@ƒCƒ‹‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: ƒ^ƒOƒpƒ^[ƒ“‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: ƒ^ƒO‚ðŒ©‚Â‚¯‚ç‚ê‚È‚¢‚̂ŒP‚É„‘ª‚µ‚Ü‚·!"
-
-#: ../tag.c:2797
-#, c-format
-msgid "Duplicate field name: %s"
-msgstr "d•¡‚µ‚½ƒtƒB[ƒ‹ƒh–¼: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' ‚Í–¢’m‚Å‚·. Œ»s‚Ì‘g‚Ýž‚Ý’[––‚ÍŽŸ‚̂Ƃ¨‚è‚Å‚·:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "È—ª’l‚ðŽŸ‚Ì‚æ‚¤‚Éݒ肵‚Ü‚· '"
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: termcapƒtƒ@ƒCƒ‹‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: terminfo‚É’[––ƒGƒ“ƒgƒŠ‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: termcap‚É’[––ƒGƒ“ƒgƒŠ‚ðŒ©‚Â‚¯‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: termcap‚É \"%s\" ‚̃Gƒ“ƒgƒŠ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: ’[––‚É \"cm\" ‹@”\\‚ª•K—v‚Å‚·"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- ’[––ƒL[ ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: “ü—Í‚ð“Çž‚Ý’†‚̃Gƒ‰[‚É‚æ‚èI—¹‚µ‚Ü‚·...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-msgid "E881: Line count changed unexpectedly"
-msgstr "E881: —\\Šú‚¹‚¸sƒJƒEƒ“ƒg‚ª•Ï‚í‚è‚Ü‚µ‚½"
-
-#: ../undo.c:627
-#, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E828: ‘ž‚Ý—p‚ɃAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ðŠJ‚¯‚Ü‚¹‚ñ: %s"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr "E825: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ª‰ó‚ê‚Ä‚¢‚Ü‚· (%s): %s"
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr "'undodir'‚̃fƒBƒŒƒNƒgƒŠ‚ɃAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ð‘‚«ž‚߂܂¹‚ñ"
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚Æ‚µ‚ēǂݞ‚߂Ȃ¢‚Ì‚Åã‘‚«‚µ‚Ü‚¹‚ñ: %s"
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ł͂Ȃ¢‚Ì‚Åã‘‚«‚µ‚Ü‚¹‚ñ: %s"
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr "‘ÎÛ‚ª‚È‚¢‚̂ŃAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚Ì‘‚«ž‚Ý‚ðƒXƒLƒbƒv‚µ‚Ü‚·"
-
-#: ../undo.c:1121
-#, c-format
-msgid "Writing undo file: %s"
-msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‘‚«ž‚Ý’†: %s"
-
-#: ../undo.c:1213
-#, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E829: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚Ì‘‚«ž‚݃Gƒ‰[‚Å‚·: %s"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr "ƒI[ƒi[‚ªˆÙ‚È‚é‚̂ŃAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ð“ǂݞ‚݂܂¹‚ñ: %s"
-
-#: ../undo.c:1292
-#, c-format
-msgid "Reading undo file: %s"
-msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹“Çž’†: %s"
-
-#: ../undo.c:1299
-#, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E822: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ð“Çž—p‚Æ‚µ‚ÄŠJ‚¯‚Ü‚¹‚ñ: %s"
-
-#: ../undo.c:1308
-#, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E823: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ł͂ ‚è‚Ü‚¹‚ñ: %s"
-
-#: ../undo.c:1313
-#, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E824: ŒÝŠ·«‚Ì–³‚¢ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚Å‚·: %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr "ƒtƒ@ƒCƒ‹‚Ì“à—e‚ª•Ï‚í‚Á‚Ä‚¢‚邽‚ßAƒAƒ“ƒhƒDî•ñ‚ð—˜—p‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../undo.c:1497
-#, c-format
-msgid "Finished reading undo file %s"
-msgstr "ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹ %s ‚ÌŽæž‚ðŠ®—¹"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr "Šù‚Ɉê”Ԍ¢•ÏX‚Å‚·"
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr "Šù‚Ɉê”ÔV‚µ‚¢•ÏX‚Å‚·"
-
-#: ../undo.c:1806
-#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: ƒAƒ“ƒhƒD”Ô† %<PRId64> ‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: s”Ô†‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
-
-#: ../undo.c:2183
-msgid "more line"
-msgstr "s ’ljÁ‚µ‚Ü‚µ‚½"
-
-#: ../undo.c:2185
-msgid "more lines"
-msgstr "s ’ljÁ‚µ‚Ü‚µ‚½"
-
-#: ../undo.c:2187
-msgid "line less"
-msgstr "s 휂µ‚Ü‚µ‚½"
-
-#: ../undo.c:2189
-msgid "fewer lines"
-msgstr "s 휂µ‚Ü‚µ‚½"
-
-#: ../undo.c:2193
-msgid "change"
-msgstr "‰ÓŠ•ÏX‚µ‚Ü‚µ‚½"
-
-#: ../undo.c:2195
-msgid "changes"
-msgstr "‰ÓŠ•ÏX‚µ‚Ü‚µ‚½"
-
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr "‘O•û"
-
-#: ../undo.c:2228
-msgid "after"
-msgstr "Œã•û"
-
-#: ../undo.c:2325
-msgid "Nothing to undo"
-msgstr "ƒAƒ“ƒhƒD‘ÎÛ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr "’Ê”Ô •ÏX” •ÏXŽžŠú •Û‘¶Ï"
-
-#: ../undo.c:2360
-#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> •bŒo‰ß‚µ‚Ä‚¢‚Ü‚·"
-
-#: ../undo.c:2372
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E790: undo ‚Ì’¼Œã‚É undojoin ‚͂ł«‚Ü‚¹‚ñ"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: ƒAƒ“ƒhƒDƒŠƒXƒg‚ª‰ó‚ê‚Ä‚¢‚Ü‚·"
-
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: ƒAƒ“ƒhƒDs‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"“K—pσpƒbƒ`: "
-
-#: ../version.c:627
-msgid ""
-"\n"
-"Extra patches: "
-msgstr ""
-"\n"
-"’ljÁŠg’£ƒpƒbƒ`: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Modified by "
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"Compiled "
-
-#: ../version.c:649
-msgid "by "
-msgstr "by "
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"Huge Ӂ "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "without GUI."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " ‹@”\\‚̈ꗗ —LŒø(+)/–³Œø(-)\n"
-
-#: ../version.c:667
-msgid " system vimrc file: \""
-msgstr " ƒVƒXƒeƒ€ vimrc: \""
-
-#: ../version.c:672
-msgid " user vimrc file: \""
-msgstr " ƒ†[ƒU[ vimrc: \""
-
-#: ../version.c:677
-msgid " 2nd user vimrc file: \""
-msgstr " ‘æ2ƒ†[ƒU[ vimrc: \""
-
-#: ../version.c:682
-msgid " 3rd user vimrc file: \""
-msgstr " ‘æ3ƒ†[ƒU[ vimrc: \""
-
-#: ../version.c:687
-msgid " user exrc file: \""
-msgstr " ƒ†[ƒU[ exrc: \""
-
-#: ../version.c:692
-msgid " 2nd user exrc file: \""
-msgstr " ‘æ2ƒ†[ƒU[ exrc: \""
-
-#: ../version.c:699
-msgid " fall-back for $VIM: \""
-msgstr " È—ªŽž‚Ì $VIM: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr "È—ªŽž‚Ì $VIMRUNTIME: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "ƒRƒ“ƒpƒCƒ‹: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "ƒŠƒ“ƒN: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr "ƒfƒoƒbƒOƒrƒ‹ƒh"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi IMproved"
-
-#: ../version.c:769
-msgid "version "
-msgstr "version "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "by Bram Moolenaar ‘¼."
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim ‚̓I[ƒvƒ“ƒ\\[ƒX‚Å‚ ‚莩—R‚É”z•z‰Â”\\‚Å‚·"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "ƒEƒKƒ“ƒ_‚ÌŒb‚Ü‚ê‚È‚¢Žq‹Ÿ‚½‚¿‚ɉ‡•‚ð!"
-
-#: ../version.c:777
-msgid "type :help iccf<Enter> for information "
-msgstr "ÚׂÈî•ñ‚Í :help iccf<Enter> "
-
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr "I—¹‚·‚é‚É‚Í :q<Enter> "
-
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "ƒIƒ“ƒ‰ƒCƒ“ƒwƒ‹ƒv‚Í :help<Enter> ‚© <F1> "
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "ƒo[ƒWƒ‡ƒ“î•ñ‚Í :help version7<Enter> "
-
-#: ../version.c:784
-msgid "Running in Vi compatible mode"
-msgstr "ViŒÝŠ·ƒ‚[ƒh‚Å“®ì’†"
-
-#: ../version.c:785
-msgid "type :set nocp<Enter> for Vim defaults"
-msgstr "Vim„§’l‚É‚·‚é‚É‚Í :set nocp<Enter> "
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "ÚׂÈî•ñ‚Í :help cp-default<Enter>"
-
-#: ../version.c:827
-msgid "Sponsor Vim development!"
-msgstr "Vim‚ÌŠJ”­‚ð‰ž‰‡‚µ‚Ä‚­‚¾‚³‚¢!"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "Vim‚Ì“o˜^ƒ†[ƒU[‚ɂȂÁ‚Ä‚­‚¾‚³‚¢!"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr "ÚׂÈî•ñ‚Í :help sponsor<Enter> "
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr "ÚׂÈî•ñ‚Í :help register<Enter> "
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "Úׂ̓ƒjƒ…[‚Ì ƒwƒ‹ƒv->ƒXƒ|ƒ“ƒT[/“o˜^ ‚ðŽQÆ‚µ‚ĉº‚³‚¢"
-
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "Šù‚ɃEƒBƒ“ƒhƒE‚Í1‚‚µ‚©‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: ƒvƒŒƒrƒ…[ƒEƒBƒ“ƒhƒE‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: ¶ã‚ƉE‰º‚𓯎ž‚É•ªŠ„‚·‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: ‘¼‚̃EƒBƒ“ƒhƒE‚ª•ªŠ„‚³‚ê‚Ä‚¢‚鎞‚ɂ͇‰ñ‚Å‚«‚Ü‚¹‚ñ"
-
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: ÅŒã‚̃EƒBƒ“ƒhƒE‚ð•‚¶‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#: ../window.c:1810
-msgid "E813: Cannot close autocmd window"
-msgstr "E813: autocmdƒEƒBƒ“ƒhƒE‚͕‚¶‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../window.c:1814
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: autocmdƒEƒBƒ“ƒhƒE‚µ‚©Žc‚ç‚È‚¢‚½‚ßAƒEƒBƒ“ƒhƒE‚͕‚¶‚ç‚ê‚Ü‚¹‚ñ"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: ‘¼‚̃EƒBƒ“ƒhƒE‚ɂ͕ÏX‚ª‚ ‚è‚Ü‚·"
-
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: ƒJ[ƒ\\ƒ‹‚̉º‚Ƀtƒ@ƒCƒ‹–¼‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-msgid "List or number required"
-msgstr "ƒŠƒXƒg‚©”’l‚ª•K—v‚Å‚·"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() ‚ª‹óƒpƒXƒ[ƒh‚ŌĂÑo‚³‚ê‚Ü‚µ‚½"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: BlowfishˆÃ†‚̃rƒbƒO/ƒŠƒgƒ‹ƒGƒ“ƒfƒBƒAƒ“‚ªŠÔˆá‚Á‚Ä‚¢‚Ü‚·"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: sha256‚̃eƒXƒg‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: BlowfishˆÃ†‚̃eƒXƒg‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "Patch file"
-#~ msgstr "ƒpƒbƒ`ƒtƒ@ƒCƒ‹"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "Œˆ’è(&O)\n"
-#~ "ƒLƒƒƒ“ƒZƒ‹(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Vim ƒT[ƒo‚Ö‚ÌÚ‘±‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: %s ‚Ö‘—‚邱‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: ƒT[ƒo‚̉ž“š‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: ƒNƒ‰ƒCƒAƒ“ƒg‚Ö‘—‚邱‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "Save As"
-#~ msgstr "•Ê–¼‚ŕۑ¶"
-
-#~ msgid "Edit File"
-#~ msgstr "ƒtƒ@ƒCƒ‹‚ð•ÒW"
-
-# Added at 27-Jan-2004.
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (Œ©‚‚©‚è‚Ü‚¹‚ñ)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "VimƒXƒNƒŠƒvƒg‚ÌŽæž‚Ý"
-
-#~ msgid "unknown"
-#~ msgstr "•s–¾"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "V‚µ‚¢ƒEƒBƒ“ƒhƒE‚Ńtƒ@ƒCƒ‹‚ð•ÒW‚µ‚Ü‚·"
-
-#~ msgid "Append File"
-#~ msgstr "’ljÁƒtƒ@ƒCƒ‹"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "ƒEƒBƒ“ƒhƒEˆÊ’u: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "ƒŠƒ_ƒCƒŒƒNƒg‚ð•Û‘¶‚µ‚Ü‚·"
-
-#~ msgid "Save View"
-#~ msgstr "ƒrƒ…[‚ð•Û‘¶‚µ‚Ü‚·"
-
-#~ msgid "Save Session"
-#~ msgstr "ƒZƒbƒVƒ‡ƒ“î•ñ‚ð•Û‘¶‚µ‚Ü‚·"
-
-#~ msgid "Save Setup"
-#~ msgstr "Ý’è‚ð•Û‘¶‚µ‚Ü‚·"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< ‚Í +eval ‹@”\\‚ª–³‚¢‚Æ—˜—p‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ‚±‚̃o[ƒWƒ‡ƒ“‚É‡Žš‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr " ‚̓fƒoƒCƒX‚Å‚· ('opendevice' ƒIƒvƒVƒ‡ƒ“‚ʼnñ”ð‚Å‚«‚Ü‚·)"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "•W€“ü—Í‚©‚ç“Çž‚Ý’†..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfishˆÃ†‰»]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[ˆÃ†‰»]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: ƒtƒ@ƒCƒ‹‚ª–¢’m‚Ì•û–@‚ňƉ»‚³‚ê‚Ä‚¢‚Ü‚·"
-
-# Added at 19-Jan-2004.
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans‚Í–¢•ÏX‚̃oƒbƒtƒ@‚ðã‘‚·‚邱‚Ƃ͋–‰Â‚µ‚Ä‚¢‚Ü‚¹‚ñ"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeansƒoƒbƒtƒ@‚̈ꕔ‚ð‘‚«o‚·‚±‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "'opendevice' ƒIƒvƒVƒ‡ƒ“‚É‚æ‚èƒfƒoƒCƒX‚Ö‚Ì‘‚«ž‚݂͂ł«‚Ü‚¹‚ñ"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: ƒŠƒ\\[ƒXƒtƒH[ƒN‚ªŽ¸‚í‚ê‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñ (! ‚ð’ljÁ‚Å‹­§)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: GUI—p‚̃vƒƒZƒX‚Ì‹N“®‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: ŽqƒvƒƒZƒX‚ªGUI‚Ì‹N“®‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: GUI‚ðŠJŽn‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: \"%s\"‚©‚ç“Çž‚Þ‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: —LŒø‚ȃtƒHƒ“ƒg‚ªŒ©‚‚©‚ç‚È‚¢‚Ì‚Å, GUI‚ðŠJŽn‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide' ‚ª–³Œø‚Å‚·"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' ‚Éݒ肳‚ꂽ’l‚ª–³Œø‚Å‚·"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: %s ‚ÌF‚ðŠ„‚è“–‚Ä‚ç‚ê‚Ü‚¹‚ñ"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "ƒJ[ƒ\\ƒ‹‚̈ʒu‚Ƀ}ƒbƒ`‚Í‚ ‚è‚Ü‚¹‚ñ, ŽŸ‚ðŒŸõ‚µ‚Ä‚¢‚Ü‚·"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<ŠJ‚¯‚Ü‚¹‚ñ> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ƒtƒHƒ“ƒg %s ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: Œ»Ý‚̃fƒBƒŒƒNƒgƒŠ‚É–ß‚ê‚Ü‚¹‚ñ"
-
-#~ msgid "Pathname:"
-#~ msgstr "ƒpƒX–¼:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: Œ»Ý‚̃fƒBƒŒƒNƒgƒŠ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "OK"
-#~ msgstr "OK"
-
-#~ msgid "Cancel"
-#~ msgstr "ƒLƒƒƒ“ƒZƒ‹"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "ƒXƒNƒ[ƒ‹ƒo[: ‰æ‘œ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½."
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim ƒ_ƒCƒAƒƒO"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: ƒƒbƒZ[ƒW‚ƃR[ƒ‹ƒoƒbƒN‚Ì‚ ‚é BalloonEval ‚ð쬂ł«‚Ü‚¹‚ñ"
-
-#~ msgid "Input _Methods"
-#~ msgstr "ƒCƒ“ƒvƒbƒgƒƒ\\ƒbƒh"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - ŒŸõ‚Æ’uŠ·..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - ŒŸõ..."
-
-#~ msgid "Find what:"
-#~ msgstr "ŒŸõ•¶Žš—ñ:"
-
-#~ msgid "Replace with:"
-#~ msgstr "’uŠ·•¶Žš—ñ:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "³Šm‚ÉŠY“–‚·‚é‚à‚Ì‚¾‚¯"
-
-#~ msgid "Match case"
-#~ msgstr "‘å•¶Žš/¬•¶Žš‚ð‹æ•Ê‚·‚é"
-
-#~ msgid "Direction"
-#~ msgstr "•ûŒü"
-
-#~ msgid "Up"
-#~ msgstr "ã"
-
-#~ msgid "Down"
-#~ msgstr "‰º"
-
-#~ msgid "Find Next"
-#~ msgstr "ŽŸ‚ðŒŸõ"
-
-#~ msgid "Replace"
-#~ msgstr "’uŠ·"
-
-#~ msgid "Replace All"
-#~ msgstr "‘S‚Ä’uŠ·"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: ƒZƒbƒVƒ‡ƒ“ƒ}ƒl[ƒWƒƒ‚©‚ç \"die\" —v‹‚ðŽó‚¯Žæ‚è‚Ü‚µ‚½\n"
-
-#~ msgid "Close"
-#~ msgstr "•‚¶‚é"
-
-#~ msgid "New tab"
-#~ msgstr "V‹Kƒ^ƒuƒy[ƒW"
-
-#~ msgid "Open Tab..."
-#~ msgstr "ƒ^ƒuƒy[ƒW‚ðŠJ‚­..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: ƒƒCƒ“ƒEƒBƒ“ƒhƒE‚ª•sˆÓ‚É”j‰ó‚³‚ê‚Ü‚µ‚½\n"
-
-#~ msgid "&Filter"
-#~ msgstr "ƒtƒBƒ‹ƒ^(&F)"
-
-#~ msgid "&Cancel"
-#~ msgstr "ƒLƒƒƒ“ƒZƒ‹(&C)"
-
-#~ msgid "Directories"
-#~ msgstr "ƒfƒBƒŒƒNƒgƒŠ"
-
-#~ msgid "Filter"
-#~ msgstr "ƒtƒBƒ‹ƒ^"
-
-#~ msgid "&Help"
-#~ msgstr "ƒwƒ‹ƒv(&H)"
-
-#~ msgid "Files"
-#~ msgstr "ƒtƒ@ƒCƒ‹"
-
-#~ msgid "&OK"
-#~ msgstr "&OK"
-
-#~ msgid "Selection"
-#~ msgstr "‘I‘ð"
-
-#~ msgid "Find &Next"
-#~ msgstr "ŽŸ‚ðŒŸõ(&N)"
-
-#~ msgid "&Replace"
-#~ msgstr "’uŠ·(&R)"
-
-#~ msgid "Replace &All"
-#~ msgstr "‘S‚Ä’uŠ·(&A)"
-
-#~ msgid "&Undo"
-#~ msgstr "ƒAƒ“ƒhƒD(&U)"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: ƒ^ƒCƒgƒ‹‚ª \"%s\" ‚̃EƒBƒ“ƒhƒE‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: ˆø”‚̓Tƒ|[ƒg‚³‚ê‚Ü‚¹‚ñ: \"-%s\"; OLE”Å‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: MDIƒAƒvƒŠ‚Ì’†‚ł̓EƒBƒ“ƒhƒE‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#~ msgid "Close tab"
-#~ msgstr "ƒ^ƒuƒy[ƒW‚ð•‚¶‚é"
-
-#~ msgid "Open tab..."
-#~ msgstr "ƒ^ƒuƒy[ƒW‚ðŠJ‚­"
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "ŒŸõ•¶Žš—ñ ('\\' ‚ðŒŸõ‚·‚é‚É‚Í '\\\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "ŒŸõE’uŠ· ('\\' ‚ðŒŸõ‚·‚é‚É‚Í '\\\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "Žg‚í‚ê‚Ü‚¹‚ñ"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "ƒfƒBƒŒƒNƒgƒŠ\t*.nothing\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: FŽw’肪³‚µ‚­‚È‚¢‚̂ŃGƒ“ƒgƒŠ‚ðŠ„‚è“–‚Ä‚ç‚ê‚Ü‚¹‚ñ"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: ˆÈ‰º‚Ì•¶ŽšƒZƒbƒg‚̃tƒHƒ“ƒg‚ª‚ ‚è‚Ü‚¹‚ñ %s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: ƒtƒHƒ“ƒgƒZƒbƒg–¼: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "ƒtƒHƒ“ƒg '%s' ‚͌Œ蕂ł͂ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: ƒtƒHƒ“ƒgƒZƒbƒg–¼: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "ƒtƒHƒ“ƒg0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "ƒtƒHƒ“ƒg1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "ƒtƒHƒ“ƒg%<PRId64> ‚Ì•‚ªƒtƒHƒ“ƒg0‚Ì2”{‚ł͂ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "ƒtƒHƒ“ƒg0‚Ì•: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "ƒtƒHƒ“ƒg1‚Ì•: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "–³Œø‚ȃtƒHƒ“ƒgŽw’è‚Å‚·"
-
-#~ msgid "&Dismiss"
-#~ msgstr "‹p‰º‚·‚é(&D)"
-
-#~ msgid "no specific match"
-#~ msgstr "ƒ}ƒbƒ`‚·‚é‚à‚Ì‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - ƒtƒHƒ“ƒg‘I‘ð"
-
-#~ msgid "Name:"
-#~ msgstr "–¼‘O:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "ƒTƒCƒY‚ðƒ|ƒCƒ“ƒg‚Å•\\ަ‚·‚é"
-
-#~ msgid "Encoding:"
-#~ msgstr "ƒGƒ“ƒR[ƒh:"
-
-#~ msgid "Font:"
-#~ msgstr "ƒtƒHƒ“ƒg:"
-
-#~ msgid "Style:"
-#~ msgstr "ƒXƒ^ƒCƒ‹:"
-
-#~ msgid "Size:"
-#~ msgstr "ƒTƒCƒY:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ƒnƒ“ƒOƒ‹ƒI[ƒgƒ}ƒgƒ“ƒGƒ‰["
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat ƒGƒ‰["
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: cscopeƒf[ƒ^ƒx[ƒX: %s ‚ðŠJ‚­‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: cscopeƒf[ƒ^ƒx[ƒX‚Ìî•ñ‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Luaƒ‰ƒCƒuƒ‰ƒŠ‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñ."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "ƒAƒ“ƒhƒDî•ñ‚ª•Û‘¶‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: ‚±‚̃Rƒ}ƒ“ƒh‚Í–³Œø‚Å‚·. MzScheme ƒ‰ƒCƒuƒ‰ƒŠ‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñ."
-
-#~ msgid "invalid expression"
-#~ msgstr "–³Œø‚ÈŽ®‚Å‚·"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "Ž®‚̓Rƒ“ƒpƒCƒ‹Žž‚É–³Œø‚É‚³‚ê‚Ä‚¢‚Ü‚·"
-
-#~ msgid "hidden option"
-#~ msgstr "‰B‚µƒIƒvƒVƒ‡ƒ“"
-
-#~ msgid "unknown option"
-#~ msgstr "–¢’m‚̃IƒvƒVƒ‡ƒ“‚Å‚·"
-
-#~ msgid "window index is out of range"
-#~ msgstr "”͈͊O‚̃EƒBƒ“ƒhƒE”Ô†‚Å‚·"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "ƒoƒbƒtƒ@‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#~ msgid "cannot delete line"
-#~ msgstr "s‚ðÁ‚¹‚Ü‚¹‚ñ"
-
-#~ msgid "cannot replace line"
-#~ msgstr "s‚ð’uŠ·‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "cannot insert line"
-#~ msgstr "s‚ð‘}“ü‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "•¶Žš—ñ‚ɂ͉üs•¶Žš‚ðŠÜ‚ß‚ç‚ê‚Ü‚¹‚ñ"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "Scheme’l‚ÌVim‚ւ̕ϊ·ƒGƒ‰["
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim ƒGƒ‰[: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Vim ƒGƒ‰["
-
-#~ msgid "buffer is invalid"
-#~ msgstr "ƒoƒbƒtƒ@‚Í–³Œø‚Å‚·"
-
-#~ msgid "window is invalid"
-#~ msgstr "ƒEƒBƒ“ƒhƒE‚Í–³Œø‚Å‚·"
-
-#~ msgid "linenr out of range"
-#~ msgstr "”͈͊O‚Ìs”Ô†‚Å‚·"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "ƒTƒ“ƒhƒ{ƒbƒNƒX‚ł͋–‚³‚ê‚Ü‚¹‚ñ"
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: ƒ‰ƒCƒuƒ‰ƒŠ %s ‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "‚±‚̃Rƒ}ƒ“ƒh‚Í–³Œø‚Å‚·, ‚²‚ß‚ñ‚È‚³‚¢: Perlƒ‰ƒCƒuƒ‰ƒŠ‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñ‚Å‚µ"
-#~ "‚½."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: ƒTƒ“ƒhƒ{ƒbƒNƒX‚Å‚Í Safe ƒ‚ƒWƒ…[ƒ‹‚ðŽg—p‚µ‚È‚¢PerlƒXƒNƒŠƒvƒg‚͋ւ¶‚ç"
-#~ "‚ê‚Ä‚¢‚Ü‚·"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: ‚±‚ÌVim‚Å‚Í :py3 ‚ðŽg‚Á‚½Œã‚É :python ‚ðŽg‚¦‚Ü‚¹‚ñ"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: ‚±‚̃Rƒ}ƒ“ƒh‚Í–³Œø‚Å‚·,‚²‚ß‚ñ‚È‚³‚¢: Pythonƒ‰ƒCƒuƒ‰ƒŠ‚ðƒ[ƒh‚Å‚«‚Ü"
-#~ "‚¹‚ñ‚Å‚µ‚½."
-
-# Added at 07-Feb-2004.
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Python ‚ðÄ‹A“I‚ÉŽÀs‚·‚邱‚Ƃ͂ł«‚Ü‚¹‚ñ"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: ‚±‚ÌVim‚Å‚Í :python ‚ðŽg‚Á‚½Œã‚É :py3 ‚ðŽg‚¦‚Ü‚¹‚ñ"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ ‚Í•¶Žš—ñ‚̃Cƒ“ƒXƒ^ƒ“ƒX‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: ‚±‚̃Rƒ}ƒ“ƒh‚Í–³Œø‚Å‚·,‚²‚ß‚ñ‚È‚³‚¢: Rubyƒ‰ƒCƒuƒ‰ƒŠ‚ðƒ[ƒh‚Å‚«‚Ü‚¹"
-#~ "‚ñ‚Å‚µ‚½."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: —\\Šú‚¹‚Ê return ‚Å‚·"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: —\\Šú‚¹‚Ê next ‚Å‚·"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: —\\Šú‚¹‚Ê break ‚Å‚·"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: —\\Šú‚¹‚Ê redo ‚Å‚·"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: rescue ‚ÌŠO‚Ì retry ‚Å‚·"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: Žæ‚舵‚í‚ê‚È‚©‚Á‚½—áŠO‚ª‚ ‚è‚Ü‚·"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: –¢’m‚Ìlongjmpó‘Ô: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "ŽÀ‘•‚Æ’è‹`‚ðØ‚è‘Ö‚¦‚é"
-
-#~ msgid "Show base class of"
-#~ msgstr "ŽŸ‚̃Nƒ‰ƒX‚ÌŠî’ê‚ð•\\ަ"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "ƒI[ƒo[ƒ‰ƒCƒh‚³‚ꂽƒƒ“ƒoŠÖ”‚ð•\\ަ"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "ƒtƒ@ƒCƒ‹‚©‚ç‰ñ•œ‚·‚é"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "ƒvƒƒWƒFƒNƒg‚©‚ç‰ñ•œ‚·‚é"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "‘S‚ẴvƒƒWƒFƒNƒg‚©‚ç‰ñ•œ‚·‚é"
-
-#~ msgid "Retrieve"
-#~ msgstr "‰ñ•œ"
-
-#~ msgid "Show source of"
-#~ msgstr "ŽŸ‚̃\\[ƒX‚ð•\\ަ‚·‚é"
-
-#~ msgid "Find symbol"
-#~ msgstr "Œ©‚‚¯‚½ƒVƒ“ƒ{ƒ‹"
-
-#~ msgid "Browse class"
-#~ msgstr "ƒNƒ‰ƒX‚ðŽQÆ"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "ŠK‘w‚ŃNƒ‰ƒX‚ð•\\ަ"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "ŒÀ’肳‚ꂽŠK‘w‚ŃNƒ‰ƒX‚ð•\\ަ"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ‚ÌŽQÆæ"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ‚ªŽQÆ‚³‚ê‚é"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ‚ªŽŸ‚Ì‚à‚Ì‚ð‚à‚Á‚Ä‚¢‚Ü‚·"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref ‚ªŽg—p‚³‚ê‚é"
-
-#~ msgid "Show docu of"
-#~ msgstr "ŽŸ‚Ì•¶Í‚ð•\\ަ"
-
-#~ msgid "Generate docu for"
-#~ msgstr "ŽŸ‚Ì•¶Í‚ð¶¬"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "SNiFF+‚ÉÚ‘±‚Å‚«‚Ü‚¹‚ñ. ŠÂ‹«‚ðƒ`ƒFƒbƒN‚µ‚Ä‚­‚¾‚³‚¢(sniffemacs ‚ª $PATH ‚É"
-#~ "‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: “Çž’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½. Ø’f‚µ‚Ü‚µ‚½"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "Œ»ÝSNiFF+ ‚Ìó‘Ô‚Íu"
-
-#~ msgid "not "
-#~ msgstr "–¢"
-
-#~ msgid "connected"
-#~ msgstr "Ú‘±v‚Å‚·"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: –¢’m‚Ì SNiFF+ ƒŠƒNƒGƒXƒg‚Å‚·: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: SNiFF+ ‚Ö‚ÌÚ‘±’†‚̃Gƒ‰[‚Å‚·"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ ‚ÉÚ‘±‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: SNiFF+ ƒoƒbƒtƒ@‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: ‘ž‚Ý’†‚ɃGƒ‰[‚ª”­¶‚µ‚½‚Ì‚ÅØ’f‚µ‚Ü‚µ‚½"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "–³Œø‚ȃoƒbƒtƒ@”Ô†‚Å‚·"
-
-#~ msgid "not implemented yet"
-#~ msgstr "‚Ü‚¾ŽÀ‘•‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "s‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "invalid mark name"
-#~ msgstr "–³Œø‚ȃ}[ƒN–¼‚Å‚·"
-
-#~ msgid "mark not set"
-#~ msgstr "ƒ}[ƒN‚Íݒ肳‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#~ msgid "row %d column %d"
-#~ msgstr "s %d —ñ %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "s‚Ì‘}“ü/’ljÁ‚ð‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "line number out of range"
-#~ msgstr "”͈͊O‚Ìs”Ô†‚Å‚·"
-
-#~ msgid "unknown flag: "
-#~ msgstr "–¢’m‚̃tƒ‰ƒO: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "–¢’m‚Ì vimOption ‚Å‚·"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "ƒL[ƒ{[ƒhŠ„ž‚Ý"
-
-#~ msgid "vim error"
-#~ msgstr "vim ƒGƒ‰["
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "ƒoƒbƒtƒ@/ƒEƒBƒ“ƒhƒE쬃Rƒ}ƒ“ƒh‚ð쬂ł«‚Ü‚¹‚ñ: ƒIƒuƒWƒFƒNƒg‚ªÁ‹Ž‚³‚ê‚Ä"
-#~ "‚¢‚Ü‚µ‚½"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "ƒR[ƒ‹ƒoƒbƒNƒRƒ}ƒ“ƒh‚ð“o˜^‚Å‚«‚Ü‚¹‚ñ: ƒoƒbƒtƒ@/ƒEƒBƒ“ƒhƒE‚ªŠù‚ÉÁ‹Ž‚³‚ê‚Ü"
-#~ "‚µ‚½"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL ’v–½“IƒGƒ‰[: reflist ‰˜õ!? vim-dev@vim.org ‚É•ñ‚µ‚Ä‚­‚¾‚³‚¢"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "ƒR[ƒ‹ƒoƒbƒNƒRƒ}ƒ“ƒh‚ð“o˜^‚Å‚«‚Ü‚¹‚ñ: ƒoƒbƒtƒ@/ƒEƒBƒ“ƒhƒE‚ÌŽQÆ‚ªŒ©‚‚©‚è"
-#~ "‚Ü‚¹‚ñ"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: ‚±‚̃Rƒ}ƒ“ƒh‚Í–³Œø‚Å‚·,‚²‚ß‚ñ‚È‚³‚¢: Tclƒ‰ƒCƒuƒ‰ƒŠ‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñ"
-#~ "‚Å‚µ‚½."
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: I—¹ƒR[ƒh %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "s‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "–½—߃T[ƒo‚Ì–¼‘O‚ð“o˜^‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: –Ú“I‚̃vƒƒOƒ‰ƒ€‚ւ̃Rƒ}ƒ“ƒh‘—M‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: –³Œø‚ȃT[ƒoID‚ªŽg‚í‚ê‚Ü‚µ‚½: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM ŽÀ‘̂̓o˜^ƒvƒƒpƒeƒB‚ª•s³‚Å‚·. Á‹Ž‚µ‚Ü‚µ‚½!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans ‚Í‚±‚ÌGUI‚ł͗˜—p‚Å‚«‚Ü‚¹‚ñ\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "‚±‚ÌVim‚É‚Ídiff‹@”\\‚ª‚ ‚è‚Ü‚¹‚ñ(ƒRƒ“ƒpƒCƒ‹ŽžÝ’è)."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' Žg—p•s‰Â”\\‚Å‚·: ƒRƒ“ƒpƒCƒ‹Žž‚É–³Œø‚É‚³‚ê‚Ä‚¢‚Ü‚·\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: ƒGƒ‰[: NetBeans‚©‚çgvim‚ðƒXƒ^[ƒg‚Å‚«‚Ü‚¹‚ñ\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "‘嬕¶Žš‚ª–³Ž‹‚³‚ê‚éê‡‚Í‘å•¶Žš‚É‚·‚邽‚ß‚É / ‚ð‘O’u‚µ‚Ä‚­‚¾‚³‚¢"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\t‚±‚Ìgvim‚ðOLE‚Æ‚µ‚Ä“o˜^‚·‚é"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tgvim‚ÌOLE“o˜^‚ð‰ðœ‚·‚é"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tGUI‚Å‹N“®‚·‚é (\"gvim\" ‚Æ“¯‚¶)"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f or --nofork\tƒtƒHƒAƒOƒ‰ƒEƒ“ƒh: GUI‚ðŽn‚߂邯‚«‚Éfork‚µ‚È‚¢"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tƒEƒBƒ“ƒhƒE‚ðŠJ‚­‚Ì‚É newcli ‚ðŽg—p‚µ‚È‚¢"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tI/O‚É <device> ‚ðŽg—p‚·‚é"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\t.gvimrc‚Ì‘ã‚í‚è‚É <gvimrc> ‚ðŽg‚¤"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tˆÃ†‰»‚³‚ꂽƒtƒ@ƒCƒ‹‚ð•ÒW‚·‚é"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tvim‚ðŽw’肵‚½ X ƒT[ƒo‚ÉÚ‘±‚·‚é"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tXƒT[ƒo‚ÉÚ‘±‚µ‚È‚¢"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\t‰Â”\\‚È‚ç‚ÎVimƒT[ƒo‚Å <files> ‚ð•ÒW‚·‚é"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> “¯ã, ƒT[ƒo‚ª–³‚­‚Ä‚àŒx•¶‚ðo—Í‚µ‚È‚¢"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr "--remote-wait <files>\t--remoteŒã ƒtƒ@ƒCƒ‹‚Ì•ÒW‚ªI‚í‚é‚Ì‚ð‘Ò‚Â"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <files> “¯ã, ƒT[ƒo‚ª–³‚­‚Ä‚àŒx•¶‚ðo—Í‚µ‚È‚¢"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <files> --remote‚Ńtƒ@ƒCƒ‹1‚‚ɂ‚«1‚‚̃^ƒu"
-#~ "ƒy[ƒW‚ðŠJ‚­"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\tVimƒT[ƒo‚É <keys> ‚ð‘—M‚µ‚ÄI—¹‚·‚é"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\tƒT[ƒo‚Å <expr> ‚ðŽÀs‚µ‚ÄŒ‹‰Ê‚ð•\\ަ‚·‚é"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tVimƒT[ƒo–¼‚̈ꗗ‚ð•\\ަ‚µ‚ÄI—¹‚·‚é"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <name>\tVimƒT[ƒo <name> ‚É‘—M/–¼‘OÝ’è‚·‚é"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim‚É‚æ‚Á‚ĉðŽß‚³‚ê‚éˆø”(Motifƒo[ƒWƒ‡ƒ“):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim‚É‚æ‚Á‚ĉðŽß‚³‚ê‚éˆø”(neXtawƒo[ƒWƒ‡ƒ“):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim‚É‚æ‚Á‚ĉðŽß‚³‚ê‚éˆø”(Athenaƒo[ƒWƒ‡ƒ“):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\t<display> ‚Åvim‚ðŽÀs‚·‚é"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tŬ‰»‚µ‚½ó‘Ô‚Åvim‚ð‹N“®‚·‚é"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\t”wŒiF‚É <color> ‚ðŽg‚¤(“¯‹`: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\t‘OŒiF‚É <color> ‚ðŽg‚¤(“¯‹`: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\tƒeƒLƒXƒg•\\ަ‚É <font> ‚ðŽg‚¤(“¯‹`: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\t‘¾Žš‚É <font> ‚ðŽg‚¤"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <for>\tŽÎ‘ÌŽš‚É <font> ‚ðŽg‚¤"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\t‰Šú”z’u‚É <geom> ‚ðŽg‚¤(“¯‹`: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\t‹«ŠE‚Ì•‚ð <width> ‚É‚·‚é(“¯‹`: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <width> ƒXƒNƒ[ƒ‹ƒo[‚Ì•‚ð <width> ‚É‚·‚é(“¯‹`: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <height>\tƒƒjƒ…[ƒo[‚Ì‚‚³‚ð <height> ‚É‚·‚é(“¯‹`: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\t”½“]‰f‘œ‚ðŽg—p‚·‚é(“¯‹`: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\t”½“]‰f‘œ‚ðŽg—p‚µ‚È‚¢(“¯‹`: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\t“Á’è‚ÌƒŠƒ\\[ƒX‚ðŽg—p‚·‚é"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim‚É‚æ‚Á‚ĉðŽß‚³‚ê‚éˆø”(GTK+ƒo[ƒWƒ‡ƒ“):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\t<display> ‚Åvim‚ðŽÀs‚·‚é(“¯‹`: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\tƒƒCƒ“ƒEƒBƒ“ƒhƒE‚ðŽ¯•Ê‚·‚éˆêˆÓ‚È–ðŠ„(role)‚ðÝ’è‚·‚é"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tˆÙ‚È‚éGTK widget‚ÅVim‚ðŠJ‚­"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tƒEƒBƒ“ƒhƒEID‚ð•W€o—Í‚Éo—Í‚·‚é"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <e‚̃^ƒCƒgƒ‹>\tVim‚ðeƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚Ì’†‚Å‹N“®‚·‚é"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tˆÙ‚È‚éWin32 widget‚Ì“à•”‚ÉVim‚ðŠJ‚­"
-
-#~ msgid "No display"
-#~ msgstr "ƒfƒBƒXƒvƒŒƒC‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": ‘—M‚ÉŽ¸”s‚µ‚Ü‚µ‚½.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": ‘—M‚ÉŽ¸”s‚µ‚Ü‚µ‚½. ƒ[ƒJƒ‹‚ł̎Às‚ðŽŽ‚Ý‚Ä‚¢‚Ü‚·\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d ŒÂ (%d ŒÂ’†) ‚̃tƒ@ƒCƒ‹‚ð•ÒW‚µ‚Ü‚µ‚½"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "ƒfƒBƒXƒvƒŒƒC‚ª‚ ‚è‚Ü‚¹‚ñ: Ž®‚Ì‘—M‚ÉŽ¸”s‚µ‚Ü‚µ‚½.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Ž®‚Ì‘—M‚ÉŽ¸”s‚µ‚Ü‚µ‚½.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: –³Œø‚ȃR[ƒhƒy[ƒW‚Å‚·"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: IC‚Ì’l‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: ƒCƒ“ƒvƒbƒgƒRƒ“ƒeƒLƒXƒg‚Ì쬂Ɏ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: ƒCƒ“ƒvƒbƒgƒƒ\\ƒbƒh‚̃I[ƒvƒ“‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: Œx: IM‚Ì”j‰óƒR[ƒ‹ƒoƒbƒN‚ðÝ’è‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: ƒCƒ“ƒvƒbƒgƒƒ\\ƒbƒh‚͂ǂñ‚ȃXƒ^ƒCƒ‹‚àƒTƒ|[ƒg‚µ‚Ü‚¹‚ñ"
-
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: ƒCƒ“ƒvƒbƒgƒƒ\\ƒbƒh‚Í my preedit type ‚ðƒTƒ|[ƒg‚µ‚Ü‚¹‚ñ"
-
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚̈Æ‚ðXV’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr ""
-#~ "E833: %s ‚Í‚±‚̃o[ƒWƒ‡ƒ“‚ÌVim‚ŃTƒ|[ƒg‚µ‚Ä‚¢‚È‚¢Œ`Ž®‚ňƉ»‚³‚ê‚Ä‚¢‚Ü‚·"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚͈Ɖ»‚³‚ê‚Ä‚¢‚Ü‚·: \"%s\""
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "V‚µ‚¢ˆÃ†ƒL[‚ð“ü—Í‚µ‚½‚ ‚ƂɃeƒLƒXƒgƒtƒ@ƒCƒ‹‚ð•Û‘¶‚µ‚Ä‚¢‚È‚¢ê‡‚Í,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "V‚µ‚¢ˆÃ†ƒL[‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢."
-
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "ˆÃ†ƒL[‚ð•Ï‚¦‚½‚ ‚ƂɃeƒLƒXƒgƒtƒ@ƒCƒ‹‚ð•Û‘¶‚µ‚½ê‡‚Í, ƒeƒLƒXƒgƒtƒ@ƒCƒ‹‚Æ"
-
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚É“¯‚¶ˆÃ†ƒL[‚ðŽg‚¤‚½‚ß‚Éenter‚¾‚¯‚ð‰Ÿ‚µ‚Ä‚­‚¾‚³‚¢."
-
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "ƒXƒƒbƒvƒtƒ@ƒCƒ‹‚©‚çŽæ“¾‚µ‚½ˆÃ†ƒL[‚ðƒeƒLƒXƒgƒtƒ@ƒCƒ‹‚ÉŽg‚¢‚Ü‚·.\n"
-
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [‚±‚ÌVimƒo[ƒWƒ‡ƒ“‚ł͎g—p‚Å‚«‚Ü‚¹‚ñ]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "‚±‚̃ƒjƒ…[‚ðØ‚èŽæ‚é"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "ƒfƒBƒŒƒNƒgƒŠ‘I‘ðƒ_ƒCƒAƒƒO"
-
-#~ msgid "Save File dialog"
-#~ msgstr "ƒtƒ@ƒCƒ‹•Û‘¶ƒ_ƒCƒAƒƒO"
-
-#~ msgid "Open File dialog"
-#~ msgstr "ƒtƒ@ƒCƒ‹“Çžƒ_ƒCƒAƒƒO"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr ""
-#~ "E338: ƒRƒ“ƒ\\[ƒ‹ƒ‚[ƒh‚ł̓tƒ@ƒCƒ‹ƒuƒ‰ƒEƒU‚ðŽg‚¦‚Ü‚¹‚ñ, ‚²‚ß‚ñ‚È‚³‚¢"
-
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: ƒtƒ@ƒCƒ‹‚ð•Û‘¶’†...\n"
-
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: I—¹‚µ‚Ü‚µ‚½.\n"
-
-#~ msgid "ERROR: "
-#~ msgstr "ƒGƒ‰[: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[ƒƒ‚ƒŠ(ƒoƒCƒg)] ‘Š„“–-‰ð•ú—Ê %<PRIu64>-%<PRIu64>, Žg—p—Ê %<PRIu64>, ƒs["
-#~ "ƒNŽž %<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[ŒÄo] ‘ re/malloc() ‰ñ” %<PRIu64>, ‘ free() ‰ñ” %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: s‚ª’·‚­‚È‚è‰ß‚¬‚Ü‚µ‚½"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: “à•”ƒGƒ‰[: lalloc(%<PRId64>,)"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: •s³‚È 'mouseshape' ‚Å‚·"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "ˆÃ†‰»—p‚̃L[‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "‚à‚¤ˆê“x“¯‚¶ƒL[‚ð“ü—Í‚µ‚Ä‚­‚¾‚³‚¢: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "ƒL[‚ªˆê’v‚µ‚Ü‚¹‚ñ"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Netbeans #2 ‚ÉÚ‘±‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Netbeans ‚ÉÚ‘±‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: NetBeans‚ÌÚ‘±î•ñƒtƒ@ƒCƒ‹‚̃AƒNƒZƒXƒ‚[ƒh‚É–â‘肪‚ ‚è‚Ü‚·: \"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "Netbeans ‚̃\\ƒPƒbƒg‚ð“Çž‚Ý"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: ƒoƒbƒtƒ@ %<PRId64> ‚Ì NetBeans Ú‘±‚ªŽ¸‚í‚ê‚Ü‚µ‚½"
-
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: NetBeans‚Í‚±‚ÌGUI‚ɂ͑Ήž‚µ‚Ä‚¢‚Ü‚¹‚ñ"
-
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: NetBeans‚ÍŠù‚ÉÚ‘±‚µ‚Ä‚¢‚Ü‚·"
-
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s ‚͓Ǟê—p‚Å‚· (‹­§‘ž‚É‚Í ! ‚ð’ljÁ)"
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Ž®•]‰¿‹@”\\‚ª–³Œø‚ɂȂÁ‚Ä‚¢‚Ü‚·"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "%<PRId64> s‚ð‰ð•ú’†"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: GUI‚Å‚Í 'term' ‚ð•ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: GUI‚ðƒXƒ^[ƒg‚·‚é‚É‚Í \":gui\" ‚ðŽg—p‚µ‚Ä‚­‚¾‚³‚¢"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: GTK+2 GUI‚ł͕ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: –³Œø‚ȃtƒHƒ“ƒg‚Å‚·"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ƒtƒHƒ“ƒgƒZƒbƒg‚ð‘I‘ð‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: –³Œø‚ȃtƒHƒ“ƒgƒZƒbƒg‚Å‚·"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ƒƒCƒhƒtƒHƒ“ƒg‚ð‘I‘ð‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: –³Œø‚ȃƒCƒhƒtƒHƒ“ƒg‚Å‚·"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: ƒ}ƒEƒX‚̓Tƒ|[ƒg‚³‚ê‚Ü‚¹‚ñ"
-
-#~ msgid "cannot open "
-#~ msgstr "ŠJ‚¯‚Ü‚¹‚ñ "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: ƒEƒBƒ“ƒhƒE‚ðŠJ‚¯‚Ü‚¹‚ñ!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Amigados‚̃o[ƒWƒ‡ƒ“ 2.04‚©‚»‚êˆÈ~‚ª•K—v‚Å‚·\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "%s ‚̃o[ƒWƒ‡ƒ“ %<PRId64> ‚ª•K—v‚Å‚·\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "NIL‚ðŠJ‚¯‚Ü‚¹‚ñ:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "쬂ł«‚Ü‚¹‚ñ "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim‚Í %d ‚ÅI—¹‚µ‚Ü‚·\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "ƒRƒ“ƒ\\[ƒ‹ƒ‚[ƒh‚ð•ÏX‚Å‚«‚Ü‚¹‚ñ?!\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ƒRƒ“ƒ\\[ƒ‹‚ł͂Ȃ¢??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: -f ƒIƒvƒVƒ‡ƒ“‚ŃVƒFƒ‹‚ðŽÀs‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "Cannot execute "
-#~ msgstr "ŽÀs‚Å‚«‚Ü‚¹‚ñ "
-
-#~ msgid "shell "
-#~ msgstr "ƒVƒFƒ‹ "
-
-#~ msgid " returned\n"
-#~ msgstr " –ß‚è‚Ü‚µ‚½\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE ‚ª¬‚³‰ß‚¬‚Ü‚·."
-
-#~ msgid "I/O ERROR"
-#~ msgstr "“üo—̓Gƒ‰["
-
-#~ msgid "Message"
-#~ msgstr "ƒƒbƒZ[ƒW"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ‚ª80‚ł͂Ȃ¢‚½‚ß, ŠO•”ƒRƒ}ƒ“ƒh‚ðŽÀs‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: ƒvƒŠƒ“ƒ^‚Ì‘I‘ð‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "to %s on %s"
-#~ msgstr "%s ‚Ö (%s ã‚Ì)"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: –¢’m‚̃vƒŠƒ“ƒ^ƒIƒvƒVƒ‡ƒ“‚Å‚·: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: ˆóüƒGƒ‰[: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "ˆóü‚µ‚Ä‚¢‚Ü‚·: '%s'"
-
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: •¶ŽšƒZƒbƒg–¼ \"%s\" ‚Í•s³‚Å‚· (ƒtƒHƒ“ƒg–¼ \"%s\")"
-
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: '%c' ‚Í•s³‚È•¶Žš‚Å‚· (ƒtƒHƒ“ƒg–¼ \"%s\")"
-
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: 2d‚̃VƒOƒiƒ‹‚Ì‚½‚ß, I—¹‚µ‚Ü‚·\n"
-
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: ’v–½“IƒVƒOƒiƒ‹ %s ‚ðŒŸ’m‚µ‚Ü‚µ‚½\n"
-
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: ’v–½“IƒVƒOƒiƒ‹‚ðŒŸ’m‚µ‚Ü‚µ‚½\n"
-
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "XƒT[ƒo‚Ö‚ÌÚ‘±‚É %<PRId64> ƒ~ƒŠ•b‚©‚©‚è‚Ü‚µ‚½"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: X ‚̃Gƒ‰[‚ðŒŸo‚µ‚Ü‚µ‚½r\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "X display ‚̃`ƒFƒbƒN‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "X display ‚Ì open ‚ªƒ^ƒCƒ€ƒAƒEƒg‚µ‚Ü‚µ‚½"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "sh ƒVƒFƒ‹‚ðŽÀs‚Å‚«‚Ü‚¹‚ñ\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ƒpƒCƒv‚ð쬂ł«‚Ü‚¹‚ñ\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "fork ‚Å‚«‚Ü‚¹‚ñ\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ƒRƒ}ƒ“ƒh‚ð’†’f‚µ‚Ü‚µ‚½\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP ‚ªICEÚ‘±‚ðŽ¸‚¢‚Ü‚µ‚½"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "X display ‚Ì open ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP ‚ªsave-yourself—v‹‚ðˆ—‚µ‚Ä‚¢‚Ü‚·"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP ‚ªÚ‘±‚ðŠJŽn‚µ‚Ä‚¢‚Ü‚·"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICEÚ‘±‚ªŽ¸”s‚µ‚½‚悤‚Å‚·"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection‚ªŽ¸”s‚µ‚Ü‚µ‚½: %s"
-
-#~ msgid "At line"
-#~ msgstr "s"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "vim32.dll ‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "VIM Error"
-#~ msgstr "VIMƒGƒ‰["
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "DLL‚©‚çŠÖ”ƒ|ƒCƒ“ƒ^‚ðŽæ“¾‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "shell returned %d"
-#~ msgstr "ƒVƒFƒ‹‚ªƒR[ƒh %d ‚ÅI—¹‚µ‚Ü‚µ‚½"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: ƒCƒxƒ“ƒg %s ‚ðŒŸ’m\n"
-
-#~ msgid "close"
-#~ msgstr "•‚¶‚é"
-
-#~ msgid "logoff"
-#~ msgstr "ƒƒOƒIƒt"
-
-#~ msgid "shutdown"
-#~ msgstr "ƒVƒƒƒbƒgƒ_ƒEƒ“"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: ƒRƒ}ƒ“ƒh‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#~ 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 ""
-#~ "VIMRUN.EXE‚ª $PATH ‚Ì’†‚ÉŒ©‚‚©‚è‚Ü‚¹‚ñ.\n"
-#~ "ŠO•”ƒRƒ}ƒ“ƒh‚ÌI—¹Œã‚Ɉꎞ’âŽ~‚ð‚µ‚Ü‚¹‚ñ.\n"
-#~ "Ú×‚Í :help win32-vimrun ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Vim‚ÌŒx"
-
-#~ msgid "Error file"
-#~ msgstr "ƒGƒ‰[ƒtƒ@ƒCƒ‹"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: “™‰¿ƒNƒ‰ƒX‚ðŠÜ‚ÞNFA\\’z‚ÉŽ¸”s‚µ‚Ü‚µ‚½!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) Œ»Ý‰¡’f’†‚̃uƒ‰ƒ“ƒ`‚É\\•ª‚ȃƒ‚ƒŠ‚ðŠ„‚è“–‚Ä‚ç‚ê‚Ü‚¹‚ñ!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "Œx: ’PŒêƒŠƒXƒg \"%s_%s.spl\" ‚¨‚æ‚Ñ \"%s_ascii.spl\" ‚ÍŒ©‚‚©‚è‚Ü‚¹‚ñ"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "%s “à‚̕ϊ·‚̓Tƒ|[ƒg‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: ƒƒ‚ƒŠ‚ª‘«‚è‚È‚¢‚Ì‚ÅA’PŒêƒŠƒXƒg‚Í•sŠ®‘S‚Å‚·"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: ƒ^ƒOƒtƒ@ƒCƒ‹‚̃pƒX‚ª %s ‚ÉØ‚èŽÌ‚Ä‚ç‚ê‚Ü‚µ‚½\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "V‚µ‚¢ƒVƒFƒ‹‚ð‹N“®‚µ‚Ü‚·\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "‹ó‚Ì‘I‘ð—̈æ‚Ì‚©‚í‚è‚ÉCUT_BUFFER0‚ªŽg—p‚³‚ê‚Ü‚µ‚½"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "‰Â”\\‚ȃAƒ“ƒhƒD‚Í‚ ‚è‚Ü‚¹‚ñ: ‚Ƃ肠‚¦‚¸‘±‚¯‚Ü‚·"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr ""
-#~ "E832: ”ñˆÃ†‰»ƒtƒ@ƒCƒ‹‚ªˆÃ†‰»‚³‚ꂽƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ðŽg‚Á‚Ă܂·: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: ˆÃ†‰»‚³‚ꂽƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚̉ð“ǂɎ¸”s‚µ‚Ü‚µ‚½: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: ƒAƒ“ƒhƒDƒtƒ@ƒCƒ‹‚ªˆÃ†‰»‚³‚ê‚Ä‚¢‚Ü‚·: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 ƒrƒbƒg GUI ”Å"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ƒrƒbƒg GUI ”Å"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ƒrƒbƒg GUI ”Å"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " in Win32s ƒ‚[ƒh"
-
-#~ msgid " with OLE support"
-#~ msgstr " with OLE ƒTƒ|[ƒg"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64 ƒrƒbƒg ƒRƒ“ƒ\\[ƒ‹ ”Å"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 ƒrƒbƒg ƒRƒ“ƒ\\[ƒ‹ ”Å"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16 ƒrƒbƒg ”Å"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 ƒrƒbƒg MS-DOS ”Å"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 ƒrƒbƒg MS-DOS ”Å"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) Ӂ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X Ӂ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS Ӂ"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "OpenVMS Ӂ"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Big Ӂ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "’Êí ”Å "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Small Ӂ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Tiny Ӂ "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "with GTK2-GNOME GUI."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "with GTK2 GUI."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "with X11-Motif GUI."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "with X11-neXtaw GUI."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "with X11-Athena GUI."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "with Photon GUI."
-
-#~ msgid "with GUI."
-#~ msgstr "with GUI."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "with Carbon GUI."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "with Cocoa GUI."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "with (ƒNƒ‰ƒVƒbƒN) GUI."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ƒVƒXƒeƒ€ gvimrc: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " ƒ†[ƒU gvimrc: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " ‘æ2ƒ†[ƒU gvimrc: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " ‘æ3ƒ†[ƒU gvimrc: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " ƒVƒXƒeƒ€ƒƒjƒ…[: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "ƒRƒ“ƒpƒCƒ‰: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "Úׂ̓ƒjƒ…[‚Ì ƒwƒ‹ƒv¨ŒÇŽ™ ‚ðŽQÆ‚µ‚ĉº‚³‚¢ "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "ƒ‚[ƒh–³‚ÅŽÀs’†, ƒ^ƒCƒv‚µ‚½•¶Žš‚ª‘}“ü‚³‚ê‚Ü‚·"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "ƒƒjƒ…[‚Ì •ÒW¨‘S‘Ìݒ訑}“ü(‰SŽÒ)ƒ‚[ƒhØ‘Ö "
-
-#~ msgid " for two modes "
-#~ msgstr " ‚Ń‚[ƒh—L‚É "
-
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "ƒƒjƒ…[‚Ì •ÒW¨‘S‘ÌÝ’è¨ViŒÝŠ·ƒ‚[ƒhØ‘Ö "
-
-#~ msgid " for Vim defaults "
-#~ msgstr " ‚ÅVim‚Æ‚µ‚Ä“®ì "
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr " Œx: Windows 95/98/Me ‚ðŒŸo "
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr " ÚׂÈî•ñ‚Í :help windows95<Enter> "
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "•¡”‚ÌVim‚Å•ÒW‚·‚é (&M)"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "1‚‚ÌVim‚Å•ÒW‚·‚é (&V)"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Vim‚Å·•ª‚ð•\\ަ‚·‚é"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Vim‚Å•ÒW‚·‚é (&V)"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "‹N“®Ï‚ÌVim‚Å•ÒW‚·‚é - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "‘I‘ð‚µ‚½ƒtƒ@ƒCƒ‹‚ðVim‚Å•ÒW‚·‚é"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "ƒvƒƒZƒX‚Ì쬂Ɏ¸”s: gvim‚ªŠÂ‹«•Ï”PATHã‚É‚ ‚é‚©Šm”F‚µ‚Ä‚­‚¾‚³‚¢!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll ƒGƒ‰["
-
-#~ msgid "Path length too long!"
-#~ msgstr "ƒpƒX‚ª’·‚·‚¬‚Ü‚·!"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: –¢’m‚̃tƒHƒ“ƒgƒZƒbƒg: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: –¢’m‚̃tƒHƒ“ƒg: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: ƒtƒHƒ“ƒg \"%s\" ‚͌Œ蕂ł͂ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: ƒ‰ƒCƒuƒ‰ƒŠ‚ÌŠÖ” %s ‚ðƒ[ƒh‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: ƒwƒuƒ‰ƒCŒê‚ÍŽg—p•s‰Â”\\‚Å‚·: ƒRƒ“ƒpƒCƒ‹Žž‚É–³Œø‚É‚³‚ê‚Ä‚¢‚Ü‚·\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: ƒyƒ‹ƒVƒAŒê‚ÍŽg—p•s‰Â”\\‚Å‚·: ƒRƒ“ƒpƒCƒ‹Žž‚É–³Œø‚É‚³‚ê‚Ä‚¢‚Ü‚·\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: ƒAƒ‰ƒrƒAŒê‚ÍŽg—p•s‰Â”\\‚Å‚·: ƒRƒ“ƒpƒCƒ‹Žž‚É–³Œø‚É‚³‚ê‚Ä‚¢‚Ü‚·\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: %s ‚Æ‚¢‚¤–¼‘O‚Ì“o˜^‚³‚ꂽƒT[ƒo‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ƒfƒBƒXƒvƒŒƒC‚ðŠJ‚¯‚Ü‚¹‚ñ"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: –³Œø‚ÈŽ®‚ðŽó‚¯Žæ‚è‚Ü‚µ‚½"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: —̈悪•ی삳‚ê‚Ä‚¢‚é‚Ì‚Å, •ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ‚͓Ǟê—pƒtƒ@ƒCƒ‹‚ð•ÏX‚·‚邱‚Æ‚ð‹–‚µ‚Ü‚¹‚ñ"
-
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "ˆÃ†ƒL[‚ª•K—v‚Å‚·: \"%s\""
-
-#~ msgid "empty keys are not allowed"
-#~ msgstr "‹ó‚̃L[‚Í‹–‰Â‚³‚ê‚Ä‚¢‚Ü‚¹‚ñ"
-
-#~ msgid "dictionary is locked"
-#~ msgstr "Ž«‘‚̓ƒbƒN‚³‚ê‚Ä‚¢‚Ü‚·"
-
-#~ msgid "list is locked"
-#~ msgstr "ƒŠƒXƒg‚̓ƒbƒN‚³‚ê‚Ä‚¢‚Ü‚·"
-
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "Ž«‘‚ɃL[ '%s' ‚ð’ljÁ‚·‚é‚̂Ɏ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "ƒCƒ“ƒfƒbƒNƒX‚Í %s ‚ł͂Ȃ­®”‚©ƒXƒ‰ƒCƒX‚É‚µ‚Ä‚­‚¾‚³‚¢"
-
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr ""
-#~ "str() ‚à‚µ‚­‚Í unicode() ‚̃Cƒ“ƒXƒ^ƒ“ƒX‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
-
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "bytes() ‚à‚µ‚­‚Í str() ‚̃Cƒ“ƒXƒ^ƒ“ƒX‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
-
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr "long() ‚©‚»‚ê‚Ö•ÏŠ·‰Â”\\‚È‚à‚Ì‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
-
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr "int() ‚©‚»‚ê‚Ö•ÏŠ·‰Â”\\‚È‚à‚Ì‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
-
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "CŒ¾Œê‚Ì int Œ^‚Æ‚µ‚Ă͒l‚ª‘å‚«‰ß‚¬‚Ü‚·"
-
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "CŒ¾Œê‚Ì int Œ^‚Æ‚µ‚Ă͒l‚ª¬‚³‰ß‚¬‚Ü‚·"
-
-#~ msgid "number must be greater then zero"
-#~ msgstr "”’l‚Í 0 ‚æ‚è‘å‚«‚­‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "”’l‚Í 0 ‚©‚»‚êˆÈã‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "OutputObject‘®«‚ðÁ‚¹‚Ü‚¹‚ñ"
-
-#~ msgid "invalid attribute: %s"
-#~ msgstr "–³Œø‚È‘®«‚Å‚·: %s"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: I/OƒIƒuƒWƒFƒNƒg‚̉Šú‰»ƒGƒ‰["
-
-#~ msgid "failed to change directory"
-#~ msgstr "Ž«‘‚Ì•ÏX‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "imp.find_module() ‚ª %s ‚ð•Ô‚µ‚Ü‚µ‚½ (Šú‘Ò’l: 2 —v‘f‚̃^ƒvƒ‹)"
-
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr "impl.find_module() ‚ª %d —v‘f‚̃^ƒvƒ‹‚ð•Ô‚µ‚Ü‚µ‚½ (Šú‘Ò’l: 2)"
-
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "“à•”ƒGƒ‰[: imp.find_module ‚ª NULL ‚ðŠÜ‚Þƒ^ƒvƒ‹‚ð•Ô‚µ‚Ü‚µ‚½"
-
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "vim.Dictionary‘®«‚ÍÁ‚¹‚Ü‚¹‚ñ"
-
-#~ msgid "cannot modify fixed dictionary"
-#~ msgstr "ŒÅ’肳‚ê‚½Ž«‘‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "cannot set attribute %s"
-#~ msgstr "‘®« %s ‚ÍÝ’è‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "ƒCƒeƒŒ[ƒVƒ‡ƒ“’†‚É hashtab ‚ª•ÏX‚³‚ê‚Ü‚µ‚½"
-
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr "ƒV[ƒPƒ“ƒX‚Ì—v‘f”‚É‚Í 2 ‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚Ü‚µ‚½‚ª %d ‚Å‚µ‚½"
-
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "ƒŠƒXƒg‚̃Rƒ“ƒXƒgƒ‰ƒNƒ^‚̓L[ƒ[ƒhˆø”‚ðŽó‚¯•t‚¯‚Ü‚¹‚ñ"
-
-#~ msgid "list index out of range"
-#~ msgstr "ƒŠƒXƒg”͈͊O‚̃Cƒ“ƒfƒbƒNƒX‚Å‚·"
-
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "“à•”ƒGƒ‰[: vim‚ÌƒŠƒXƒg—v‘f %d ‚̎擾‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "failed to add item to list"
-#~ msgstr "ƒŠƒXƒg‚Ö‚Ì—v‘f’ljÁ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "“à•”ƒGƒ‰[: vim‚ÌƒŠƒXƒg—v‘f %d ‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "“à•”ƒGƒ‰[: ƒŠƒXƒg‚Ö‚Ì—v‘f’ljÁ‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "vim.List ‘®«‚ÍÁ‚¹‚Ü‚¹‚ñ"
-
-#~ msgid "cannot modify fixed list"
-#~ msgstr "ŒÅ’肳‚ꂽƒŠƒXƒg‚Í•ÏX‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "–³–¼ŠÖ” %s ‚Í‘¶Ý‚µ‚Ü‚¹‚ñ"
-
-#~ msgid "function %s does not exist"
-#~ msgstr "ŠÖ” %s ‚ª‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "ŠÖ”‚̃Rƒ“ƒXƒgƒ‰ƒNƒ^‚̓L[ƒ[ƒhˆø”‚ðŽó‚¯•t‚¯‚Ü‚¹‚ñ"
-
-#~ msgid "failed to run function %s"
-#~ msgstr "ŠÖ” %s ‚ÌŽÀs‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "problem while switching windows"
-#~ msgstr "ƒEƒBƒ“ƒhƒE‚ðØŠ·’†‚É–â‘肪”­¶‚µ‚Ü‚µ‚½"
-
-#~ msgid "unable to unset global option %s"
-#~ msgstr "ƒOƒ[ƒoƒ‹ƒIƒvƒVƒ‡ƒ“ %s ‚ÌÝ’è‰ðœ‚͂ł«‚Ü‚¹‚ñ"
-
-#~ msgid "unable to unset option %s which does not have global value"
-#~ msgstr "ƒOƒ[ƒoƒ‹‚È’l‚Ì–³‚¢ƒIƒvƒVƒ‡ƒ“ %s ‚ÌÝ’è‰ðœ‚͂ł«‚Ü‚¹‚ñ"
-
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "휂³‚ꂽƒ^ƒu‚ðŽQÆ‚µ‚悤‚Æ‚µ‚Ü‚µ‚½"
-
-#~ msgid "no such tab page"
-#~ msgstr "‚»‚̂悤‚ȃ^ƒuƒy[ƒW‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "휂³‚ꂽƒEƒBƒ“ƒhƒE‚ðŽQÆ‚µ‚悤‚Æ‚µ‚Ü‚µ‚½"
-
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "“Çžê—p‘®«: ƒoƒbƒtƒ@["
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "ƒJ[ƒ\\ƒ‹ˆÊ’u‚ªƒoƒbƒtƒ@‚ÌŠO‘¤‚Å‚·"
-
-#~ msgid "no such window"
-#~ msgstr "‚»‚̂悤‚ȃEƒBƒ“ƒhƒE‚Í‚ ‚è‚Ü‚¹‚ñ"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "휂³‚ꂽƒoƒbƒtƒ@‚ðŽQÆ‚µ‚悤‚Æ‚µ‚Ü‚µ‚½"
-
-#~ msgid "failed to rename buffer"
-#~ msgstr "ƒoƒbƒtƒ@–¼‚Ì•ÏX‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "mark name must be a single character"
-#~ msgstr "ƒ}[ƒN–¼‚Í1•¶Žš‚̃Aƒ‹ƒtƒ@ƒxƒbƒg‚łȂ¯‚ê‚΂Ȃè‚Ü‚¹‚ñ"
-
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "vim.BufferƒIƒuƒWƒFƒNƒg‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
-
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "Žw’肳‚ꂽƒoƒbƒtƒ@ %d ‚Ö‚ÌØ‚è‘Ö‚¦‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "vim.WindowƒIƒuƒWƒFƒNƒg‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
-
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "Œ»Ý‚̃^ƒu‚ɂ͎w’肳‚ꂽƒEƒBƒ“ƒhƒE‚ª‚ ‚è‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "did not switch to the specified window"
-#~ msgstr "Žw’肳‚ꂽƒEƒBƒ“ƒhƒE‚ÉØ‚è‘Ö‚¦‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "expected vim.TabPage object, but got %s"
-#~ msgstr "vim.TabPageƒIƒuƒWƒFƒNƒg‚ªŠú‘Ò‚³‚ê‚Ä‚¢‚é‚Ì‚É %s ‚Å‚µ‚½"
-
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "Žw’肳‚ꂽƒ^ƒuƒy[ƒW‚ÉØ‚è‘Ö‚¦‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "failed to run the code"
-#~ msgstr "ƒR[ƒh‚ÌŽÀs‚ÉŽ¸”s‚µ‚Ü‚µ‚½"
-
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: Ž®•]‰¿‚Í—LŒø‚ÈpythonƒIƒuƒWƒFƒNƒg‚ð•Ô‚µ‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: •Ô‚³‚ꂽpythonƒIƒuƒWƒFƒNƒg‚ðvim‚Ì’l‚ɕϊ·‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½"
-
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "%s vim‚ÌŽ«‘Œ^‚ɕϊ·‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "unable to convert %s to vim structure"
-#~ msgstr "%s ‚ðvim‚Ì\\‘¢‘̂ɕϊ·‚Å‚«‚Ü‚¹‚ñ"
-
-#~ msgid "internal error: NULL reference passed"
-#~ msgstr "“à•”ƒGƒ‰[: NULLŽQÆ‚ª“n‚³‚ê‚Ü‚µ‚½"
-
-#~ msgid "internal error: invalid value type"
-#~ msgstr "“à•”ƒGƒ‰[: –³Œø‚È’lŒ^‚Å‚·"
-
-#~ msgid ""
-#~ "Failed to set path hook: sys.path_hooks is not a list\n"
-#~ "You should now do the following:\n"
-#~ "- append vim.path_hook to sys.path_hooks\n"
-#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
-#~ msgstr ""
-#~ "ƒpƒXƒtƒbƒN‚ÌÝ’è‚ÉŽ¸”s‚µ‚Ü‚µ‚½: sys.path_hooks ‚ªƒŠƒXƒg‚ł͂ ‚è‚Ü‚¹‚ñ\n"
-#~ "‚·‚®‚ɉº‹L‚ðŽÀŽ{‚µ‚Ä‚­‚¾‚³‚¢:\n"
-#~ "- vim.path_hooks ‚ð sys.path_hooks ‚֒ljÁ\n"
-#~ "- vim.VIM_SPECIAL_PATH ‚ð sys.path ‚֒ljÁ\n"
-
-#~ msgid ""
-#~ "Failed to set path: sys.path is not a list\n"
-#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
-#~ msgstr ""
-#~ "ƒpƒX‚ÌÝ’è‚ÉŽ¸”s‚µ‚Ü‚µ‚½: sys.path ‚ªƒŠƒXƒg‚ł͂ ‚è‚Ü‚¹‚ñ\n"
-#~ "‚·‚®‚É vim.VIM_SPECIAL_PATH ‚ð sys.path ‚ɒljÁ‚µ‚Ä‚­‚¾‚³‚¢"
diff --git a/src/nvim/po/ko.UTF-8.po b/src/nvim/po/ko.UTF-8.po
index 149286eda8..e90081bcfd 100644
--- a/src/nvim/po/ko.UTF-8.po
+++ b/src/nvim/po/ko.UTF-8.po
@@ -1111,6 +1111,10 @@ msgstr "E137: Viminfo 파ì¼ì˜ 쓰기 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤: %s"
#: ../ex_cmds.c:1626
#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: 너무 ë§Žì€ viminfo 임시 파ì¼ë“¤, 가령 %s!"
+
+#, c-format
msgid "E138: Can't write viminfo file %s!"
msgstr "E138: Viminfo íŒŒì¼ %sì„(를) 쓸 수 없습니다!"
@@ -1119,6 +1123,10 @@ msgstr "E138: Viminfo íŒŒì¼ %sì„(를) 쓸 수 없습니다!"
msgid "Writing viminfo file \"%s\""
msgstr "Viminfo íŒŒì¼ \"%s\"ì„(를) 쓰는 중"
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: viminfo 파ì¼ëª…ì„ %s(으)로 변경할 수 없습니다!"
+
#. Write the info:
#: ../ex_cmds.c:1720
#, c-format
@@ -1300,8 +1308,8 @@ msgstr "미안합니다, ë„ì›€ë§ íŒŒì¼ \"%s\"ì„(를) ì°¾ì„ ìˆ˜ 없습니다
#: ../ex_cmds.c:5323
#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: 디렉토리가 아님: %s"
+msgid "E151: No match: %s"
+msgstr "E151: ë§žì§€ 않ìŒ: %s"
#: ../ex_cmds.c:5446
#, c-format
@@ -1325,6 +1333,10 @@ msgstr "E154: \"%s\" 태그가 %s/%s 파ì¼ì—서 중복ë˜ì—ˆìŠµë‹ˆë‹¤"
#: ../ex_cmds.c:5687
#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: 디렉토리가 아님: %s"
+
+#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: 모르는 sign 명령: %s"
@@ -1452,8 +1464,16 @@ msgstr "\"%s\"ì„(를) 찾는 중"
#: ../ex_cmds2.c:2307
#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "'runtimepath'ì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: \"%s\""
+msgid "not found in '%s': \"%s\""
+msgstr "'%s'ì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: \"%s\""
+
+#, c-format
+msgid "W20: Required python version 2.x not supported, ignoring file: %s"
+msgstr "W20: 요구ë˜ëŠ” 파ì´ì„  버젼 2.x는 ì§€ì›ë˜ì§€ 않ìŒ, 파ì¼ì„ 무시: %s"
+
+#, c-format
+msgid "W21: Required python version 3.x not supported, ignoring file: %s"
+msgstr "W21: 요구ë˜ëŠ” 파ì´ì„  버젼 3.x는 ì§€ì›ë˜ì§€ 않ìŒ, 파ì¼ì„ 무시: %s"
#: ../ex_cmds2.c:2472
#, c-format
@@ -1609,10 +1629,10 @@ msgstr "E174: ëª…ë ¹ì´ ì´ë¯¸ 존재합니다: 바꾸려면 !ì„ ë”하세요"
#: ../ex_docmd.c:4432
msgid ""
"\n"
-" Name Args Range Complete Definition"
+" Name Args Address Complete Definition"
msgstr ""
"\n"
-" ì´ë¦„ ì¸ìž 범위 완성 ì •ì˜"
+" ì´ë¦„ ì¸ìž 주소 완성 ì •ì˜"
#: ../ex_docmd.c:4516
msgid "No user-defined commands found"
@@ -1662,6 +1682,10 @@ msgstr "E184: 그런 ì‚¬ìš©ìž ì •ì˜ ëª…ë ¹ ì—†ìŒ: %s"
#: ../ex_docmd.c:5219
#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: ìž˜ëª»ëœ ì£¼ì†Œ í˜•ì‹ ê°’: %s"
+
+#, c-format
msgid "E180: Invalid complete value: %s"
msgstr "E180: ìž˜ëª»ëœ ë내기 ê°’: %s"
@@ -1953,7 +1977,7 @@ msgstr ""
#: ../ex_getln.c:5047
msgid "Command Line"
-msgstr "명령 줄"
+msgstr "명령 행"
#: ../ex_getln.c:5048
msgid "Search String"
@@ -1965,7 +1989,10 @@ msgstr "표현"
#: ../ex_getln.c:5050
msgid "Input Line"
-msgstr "입력 줄"
+msgstr "ìž…ë ¥ í–‰"
+
+msgid "Debug Line"
+msgstr "디버그 행"
#: ../ex_getln.c:5117
msgid "E198: cmd_pchar beyond the command length"
@@ -2433,7 +2460,7 @@ msgstr "E216: 그런 그룹ì´ë‚˜ ì´ë²¤íЏ ì—†ìŒ: %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- ìžë™-명령 ---"
@@ -2648,11 +2675,6 @@ msgstr "E49: 스í¬ë¡¤ í¬ê¸°ê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3195,6 +3217,7 @@ msgstr "%-5s: %s%*s (사용법: %s)"
#: ../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"
@@ -3205,13 +3228,14 @@ msgid ""
" 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"
+" i: ì´ íŒŒì¼ì„ #include하는 파ì¼ë“¤ 찾기\n"
+" s: ì´ C 기호 찾기\n"
" t: ì´ ë¬¸ìžì—´ 찾기\n"
#: ../if_cscope.c:1226
@@ -3354,7 +3378,7 @@ msgstr "-q [ì—러파ì¼] 첫 번째 ì—러가 난 íŒŒì¼ ê³ ì¹˜ê¸°"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4224,10 +4248,6 @@ msgstr "%4ld 줄:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: ìž˜ëª»ëœ ë ˆì§€ìŠ¤í„° ì´ë¦„: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "메시지 관리ìž: Bram Moolenaar <Bram@vim.org>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "중단: "
@@ -4749,6 +4769,13 @@ msgstr "E447: pathì—서 \"%s\" 파ì¼ì„ ì°¾ì„ ìˆ˜ 없습니다"
#: ../quickfix.c:359
#, c-format
+msgid "shell returned %d"
+msgstr "ì‰˜ì´ %dì„(를) ëŒë ¤ì£¼ì—ˆìŠµë‹ˆë‹¤"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: í˜„ìž¬ì˜ location listê°€ 바뀌었습니다"
+
+#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: í˜•ì‹ ë¬¸ìžì—´ì— %%%cì´(ê°€) 너무 많습니다"
@@ -5256,14 +5283,9 @@ msgstr "E772: Spell 파ì¼ì´ 새 ë²„ì ¼ì˜ Vim용입니다"
msgid "E770: Unsupported section in spell file"
msgstr "E770: spell 파ì¼ì— ì§€ì›ë˜ì§€ 않는 섹션"
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "경고: %s ì˜ì—­ì€ ì§€ì›ë˜ì§€ 않습니다"
-
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
+msgid "Reading affix file %s..."
msgstr "affix íŒŒì¼ %s ì½ëŠ” 중"
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
@@ -5426,7 +5448,7 @@ msgstr "%s ê°’ì´ ë‹¤ë¥¸ .aff 파ì¼ì—서 ì‚¬ìš©ëœ ê²ƒê³¼ 다릅니다"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
+msgid "Reading dictionary file %s..."
msgstr "사전 íŒŒì¼ %s ì½ëŠ” 중 ..."
#: ../spell.c:5611
@@ -5436,8 +5458,8 @@ msgstr "E760: %sì— ë‹¨ì–´ 카운트가 없습니다"
#: ../spell.c:5669
#, 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
#, c-format
@@ -5461,7 +5483,7 @@ msgstr "ë¬´ì‹œëœ %dê°œì˜ ì•„ìŠ¤í‚¤ë¬¸ìžì—´ì´ 아닌 단어가 %sì— ìžˆìŠµë‹
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
+msgid "Reading word file %s..."
msgstr "단어 íŒŒì¼ %s ì½ëŠ” 중 ..."
#: ../spell.c:6155
@@ -5531,7 +5553,7 @@ msgstr "ì´ ë‹¨ì–´ 수: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
+msgid "Writing suggestion file %s..."
msgstr "%s 제안 파ì¼ì„ 쓰는 중 ..."
#: ../spell.c:7707 ../spell.c:7927
@@ -5558,7 +5580,7 @@ msgstr "경고: compound와 NOBREAK 둘 다 명시ë¨"
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
+msgid "Writing spell file %s..."
msgstr "spell íŒŒì¼ %s 쓰는 중 ..."
#: ../spell.c:7925
@@ -6321,7 +6343,7 @@ msgstr "by Bram Moolenaar et al."
#: ../version.c:774
msgid "Vim is open source and freely distributable"
-msgstr "ë¹”ì€ ì†ŒìŠ¤ê°€ ì—´ë ¤ 있고 공짜로 ë°°í¬ë©ë‹ˆë‹¤"
+msgstr "ë¹”ì€ ëˆ„êµ¬ë‚˜ 소스를 ë³¼ 수 있고 공짜로 ë°°í¬ë©ë‹ˆë‹¤"
#: ../version.c:776
msgid "Help poor children in Uganda!"
@@ -7487,9 +7509,6 @@ msgstr "E446: 커서 ë°‘ì— íŒŒì¼ ì´ë¦„ì´ ì—†ìŠµë‹ˆë‹¤"
#~ msgid "Could not fix up function pointers to the DLL!"
#~ msgstr "함수 í¬ì¸í„°ë¥¼ DLL로 바꿀 수 없습니다!"
-#~ msgid "shell returned %d"
-#~ msgstr "ì‰˜ì´ %dì„(를) ëŒë ¤ì£¼ì—ˆìŠµë‹ˆë‹¤"
-
#~ msgid "Vim: Caught %s event\n"
#~ msgstr "ë¹”: %s ì´ë²¤íŠ¸ë¥¼ 잡았습니다\n"
diff --git a/src/nvim/po/ko.po b/src/nvim/po/ko.po
deleted file mode 100644
index b6aaf37bbb..0000000000
--- a/src/nvim/po/ko.po
+++ /dev/null
@@ -1,7858 +0,0 @@
-# Korean translation for Vim
-#
-# FIRST AUTHOR SungHyun Nam <goweol@gmail.com>, 2000-2011
-#
-# Generated from ko.UTF-8, DO NOT EDIT.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: vim 7.3\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2010-02-18 09:49+0900\n"
-"Last-Translator: SungHyun Nam <goweol@gmail.com>\n"
-"Language-Team: GTP Korean <gnome-kr-translation@gnome.or.kr>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=euc-kr\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "¿É¼Ç ÀÎÀÚ µÚ¿¡ ¾²·¹±â °ª"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[À§Ä¡ ¸ñ·Ï]"
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[Quickfix ¸ñ·Ï]"
-
-#: ../buffer.c:94
-#, fuzzy
-msgid "E855: Autocommands caused command to abort"
-msgstr "E812: Autocommand°¡ ¹öÆÛ³ª ¹öÆÛÀ̸§À» ¹Ù²Ù¾ú½À´Ï´Ù"
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: ¹öÆÛ¸¦ ÇÒ´çÇÒ ¼ö ¾ø¾î¼­ ³¡³À´Ï´Ù..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: ¹öÆÛ¸¦ ÇÒ´çÇÒ ¼ö ¾ø¾î¼­ ´Ù¸¥ °É »ç¿ëÇÕ´Ï´Ù..."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: ³»·ÁÁø ¹öÆÛ°¡ ¾ø½À´Ï´Ù"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: Áö¿öÁø ¹öÆÛ°¡ ¾ø½À´Ï´Ù"
-
-#: ../buffer.c:767
-msgid "E517: No buffers were wiped out"
-msgstr "E517: ¿ÏÀüÈ÷ Áö¿öÁø ¹öÆÛ°¡ ¾ø½À´Ï´Ù"
-
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "¹öÆÛ ÇÑ °³°¡ ³»·ÁÁ³½À´Ï´Ù"
-
-#: ../buffer.c:774
-#, c-format
-msgid "%d buffers unloaded"
-msgstr "¹öÆÛ %d °³°¡ ³»·ÁÁ³½À´Ï´Ù"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "¹öÆÛ ÇÑ °³°¡ Áö¿öÁ³½À´Ï´Ù"
-
-#: ../buffer.c:779
-#, c-format
-msgid "%d buffers deleted"
-msgstr "¹öÆÛ %d °³°¡ Áö¿öÁ³½À´Ï´Ù"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "¹öÆÛ ÇÑ °³°¡ ¿ÏÀüÈ÷ Áö¿öÁ³½À´Ï´Ù"
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "¹öÆÛ %d°³°¡ ¿ÏÀüÈ÷ Áö¿öÁ³½À´Ï´Ù"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: ¸¶Áö¸· ¹öÆÛ¸¦ ³»¸± ¼ö ¾ø½À´Ï´Ù"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: ¹Ù²ï ¹öÆÛ¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-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
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: ¸¶Áö¸· ¹öÆÛÀÔ´Ï´Ù"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: ù ¹øÂ° ¹öÆÛÀÔ´Ï´Ù"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr ""
-"E89: ¹öÆÛ %<PRId64>À»(¸¦) ¸¶Áö¸·À¸·Î °íÄ£ µÚ ÀúÀåÇÏÁö ¾Ê¾Ò½À´Ï´Ù (µ¤¾î¾²·Á"
-"¸é ! ´õÇϱâ)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: °æ°í: ÆÄÀÏ À̸§ ¸ñ·ÏÀÌ ³ÑÃÆ½À´Ï´Ù"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: ¹öÆÛ %<PRId64>À»(¸¦) ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: %sÀ»(¸¦) Çϳª ÀÌ»ó ã¾Ò½À´Ï´Ù"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: %s¿Í ¸Â´Â ¹öÆÛ°¡ ¾ø½À´Ï´Ù"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "%<PRId64> ÁÙ"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: ÀÌ À̸§À» °¡Áø ¹öÆÛ°¡ ÀÌ¹Ì ÀÖ½À´Ï´Ù"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [¹Ù²ñ]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[°íÄ¡Áö ¾Ê¾ÒÀ½]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[»õ ÆÄÀÏ]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[Àб⠿¡·¯]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[Àбâ Àü¿ë]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-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:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "%<PRId64> / %<PRId64> ÁÙ --%d%%-- Ä­ "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-msgid "[No Name]"
-msgstr "[À̸§ ¾øÀ½]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "µµ¿ò¸»"
-
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[µµ¿ò¸»]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[¹Ì¸® º¸±â]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "¸ðµÎ"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "¹Ù´Ú"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "²À´ë±â"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# ¹öÆÛ ¸ñ·Ï:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr "[Scratch]"
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- ±âÈ£ ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "%s¿¡ ´ëÇÑ ±âÈ£:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ÁÙ=%<PRId64> id=%d À̸§=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ÄÝ·ÐÀÌ ¾ø½À´Ï´Ù"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: ÀÌ»óÇÑ ¸ðµå"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: ¼ýÀÚ°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: ÀÌ»óÇÑ ¹éºÐÀ²"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: %<PRId64>°³ ÀÌ»óÀÇ ¹öÆÛ¿¡ ´ëÇØ¼­´Â diff¸¦ ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../diff.c:753
-msgid "E810: Cannot read or write temp files"
-msgstr "E810: Àӽà ÆÄÀÏÀ» Àаųª ¾µ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: diff¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù"
-
-#: ../diff.c:966
-msgid "E816: Cannot read patch output"
-msgstr "E816: patch °á°ú¸¦ ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: diff Ãâ·ÂÀ» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: ÇöÀç ¹öÆÛ´Â diff »óŰ¡ ¾Æ´Õ´Ï´Ù"
-
-#: ../diff.c:2100
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E793: ¼öÁ¤ °¡´ÉÇÑ diff »óÅ ¹öÆÛ´Â ¾ø½À´Ï´Ù"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: ´Ù¸¥ ¹öÆÛÁß¿¡ diff »óÅÂÀÎ °Ô ¾ø½À´Ï´Ù"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr ""
-"E101: µÎ°³ ÀÌ»óÀÇ ¹öÆÛ°¡ diff »óÅ¿©¼­ ¾î¶² °ÍÀ» ½á¾ßÇÒ Áö ¾Ë ¼ö ¾ø½À´Ï´Ù"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: \"%s\" ¹öÆÛ¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: \"%s\" ¹öÆÛ´Â diff »óŰ¡ ¾Æ´Õ´Ï´Ù"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr "E787: ¹öÆÛ°¡ ¸ð¸£´Â »çÀÌ¿¡ ¹Ù²î¾ú½À´Ï´Ù"
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: digraph¿¡´Â EscapeÀ» ¾µ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: Ű¸Ê ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: ºÒ·¯µéÀÎ ÆÄÀÏ¿¡¼­ :loadkeymapÀ» »ç¿ëÇÏÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr "E791: Ű¸Ê ¿£Æ®¸®°¡ ºñ¾îÀÖÀ½"
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " ³¹¸» ¿Ï¼º (^N^P)"
-
-#. 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)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " Àüü ÁÙ ¿Ï¼º (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " ÆÄÀÏ À̸§ ¿Ï¼º (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " ÅÂ±× ¿Ï¼º (^]^N^P)"
-
-#: ../edit.c:88
-msgid " Path pattern completion (^N^P)"
-msgstr " °æ·Î ÆÐÅÏ ¿Ï¼º (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " Á¤ÀÇ ¿Ï¼º (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Dictionary ¿Ï¼º (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " ¹é°ú»çÀü ¿Ï¼º (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " ¸í·ÉÇà ¿Ï¼º (^V^N^P)"
-
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr " »ç¿ëÀÚ Á¤ÀÇ ¿Ï¼º (^U^N^P)"
-
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " Omni ¿Ï¼º (^O^N^P)"
-
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ´Ü¾î Á¦¾È (s^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " ³¹¸» ·ÎÄà ¿Ï¼º (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "´Ü¶ôÀÇ ¸¶Áö¸· ¸¸³²"
-
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr "E839: Completion ±â´ÉÀÌ Ã¢À» ¹Ù²Ù¾ú½À´Ï´Ù"
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr "E840: Completion ±â´ÉÀÌ ¹®ÀÚ¿­À» Áö¿ü½À´Ï´Ù"
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "'dictionary' ¿É¼ÇÀÌ ºñ¾ú½À´Ï´Ù"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "'thesaurus' ¿É¼ÇÀÌ ºñ¾ú½À´Ï´Ù"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "»çÀü ã´Â Áß: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (³¢¿ö³Ö±â) ½ºÅ©·Ñ (^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (¹Ù²Þ) ½ºÅ©·Ñ (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "ã´Â Áß: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "ÅÂ±× Ã£´Â Áß."
-
-#: ../edit.c:4519
-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.
-#.
-#: ../edit.c:4562
-msgid "-- Searching..."
-msgstr "-- ã´Â Áß..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "¿ø·¡´ë·Î º¹±¸"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "´Ù¸¥ ÁÙ¿¡ ³¹¸»"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "The only match"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "match %d of %d"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "match %d"
-
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: ':let'¿¡ ¸ð¸£´Â ±ÛÀÚ"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: ¸ñ·Ï ¹øÈ£°¡ ¹üÀ§¸¦ ¹þ¾î³²: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Á¤ÀÇ ¾È µÈ º¯¼ö: %s"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: ']'ÀÌ ¾ø½À´Ï´Ù"
-
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s ÀÎÀÚ´Â ListÀ̾î¾ß ÇÕ´Ï´Ù"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s ÀÎÀÚ´Â List ȤÀº Dictionary¿©¾ß ÇÕ´Ï´Ù"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Dictionary¿¡ ºó ۸¦ ¾µ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: List°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Dictionary°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: ÇÔ¼ö¿¡ ³Ê¹« ¸¹Àº ÀÎÀÚ ³Ñ±è: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Dictionary¿¡ ۰¡ ¾øÀ½: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: ÇÔ¼ö %sÀÌ(°¡) ÀÌ¹Ì ÀÖ½À´Ï´Ù, ¹Ù²Ù·Á¸é !À» ´õÇϼ¼¿ä"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: ÀÌ¹Ì Dictionary Ç׸ñÀÌ ÀÖ½À´Ï´Ù"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Funcref°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: Dictionary¿¡ [:]À» »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: %s=¿¡ ´ëÇÑ À߸øµÈ º¯¼öÇü"
-
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: ¸ð¸£´Â ÇÔ¼ö: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: ºñÁ¤»óÀûÀÎ º¯¼ö ¸í: %s"
-
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: Float¸¦ StringÀ¸·Î »ç¿ë"
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: List Ç׸ñº¸´Ù ÀûÀº ´ë»ó"
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: List Ç׸ñº¸´Ù ¸¹Àº ´ë»ó"
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "º¯¼ö ¸ñ·Ï¿¡ Áߺ¹µÈ ;"
-
-#: ../eval.c:2078
-#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: %s º¯¼ö ¸ñ·ÏÀ» ³ª¿­ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: List³ª Dictionary¸¸ »öÀÎÇÒ ¼ö ÀÖ½À´Ï´Ù"
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:]Àº ¸¶Áö¸·¿¡ À§Ä¡ÇØ¾ß ÇÕ´Ï´Ù"
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:]Àº List °ªÀÌ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: List °ªÀÌ ´ë»óº¸´Ù ¸¹Àº Ç׸ñÀ» °¡Áö°í ÀÖ½À´Ï´Ù"
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: List °ªÀÌ ÃæºÐÇÑ Ç׸ñÀ» °¡Áö°í ÀÖÁö ¾Ê½À´Ï´Ù"
-
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: :for µÚ¿¡ \"in\"°¡ ¾ø½À´Ï´Ù"
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: °ýÈ£ ¾øÀ½: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: ÀÌ·± º¯¼ö ¾øÀ½: \"%s\""
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: Àá±Ý(ÇØÁ¦)Çϱ⿡ º¯¼ö°¡ ³Ê¹« ±íÀÌ ÁßøµÇ¾ú½À´Ï´Ù"
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: '?' µÚ¿¡ ':'ÀÌ ¾ø½À´Ï´Ù"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: List´Â List¿Í¸¸ ºñ±³ÇÒ ¼ö ÀÖ½À´Ï´Ù"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: List¿¡ ´ëÇÑ À߸øµÈ µ¿ÀÛ"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: Dictionary´Â Dictionary¿Í¸¸ ºñ±³ÇÒ ¼ö ÀÖ½À´Ï´Ù"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: Dictionary¿¡ ´ëÇÑ À߸øµÈ µ¿ÀÛ"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Funcref´Â Funcref¿Í¸¸ ºñ±³ÇÒ ¼ö ÀÖ½À´Ï´Ù"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: Funcrefs¿¡ ´ëÇÑ À߸øµÈ µ¿ÀÛ"
-
-#: ../eval.c:4277
-msgid "E804: Cannot use '%' with Float"
-msgstr "E804: Float¿¡ '%'´Â »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: ')'°¡ ¾ø½À´Ï´Ù"
-
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: Funcref¸¦ »öÀÎÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: ¿É¼Ç À̸§ ¾øÀ½: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: ¸ð¸£´Â ¿É¼Ç: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: µû¿ÈÇ¥ ¾øÀ½: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: µû¿ÈÇ¥ ¾øÀ½: %s"
-
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: List¿¡ ÄÞ¸¶ ´©¶ô: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: List ³¡¿¡ ']' ´©¶ô: %s"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Dictionary¿¡ ÄÝ·Ð ´©¶ô: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Dictionary¿¡ Áߺ¹µÈ Ű: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Dictionary¿¡ ÄÞ¸¶ ´©¶ô: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Dictionary ³¡¿¡ '}' ´©¶ô: %s"
-
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: º¯¼ö°¡ Ç¥½ÃÇϱ⿡ ³Ê¹« ±íÀÌ ÁßøµÇ¾ú½À´Ï´Ù"
-
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: ÇÔ¼ö %s¿¡ ³Ê¹« ¸¹Àº ÀÎÀÚ°¡ Àü´ÞµÇ¾ú½À´Ï´Ù"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: ÇÔ¼ö %s(À¸)·Î À߸øµÈ ÀÎÀÚ°¡ ³Ñ°ÜÁ³½À´Ï´Ù"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: ¸ð¸£´Â ÇÔ¼ö: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: ÇÔ¼ö¿¡ ÀûÀº ÀÎÀÚ ³Ñ±è: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: ½ºÅ©¸³Æ® ÄÜÅØ½ºÆ® ¹Û¿¡¼­ <SID> »ç¿ë: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Dictionary¾øÀÌ »çÀüÇÔ¼ö°¡ ºÒ·ÁÁü: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Number ȤÀº Float°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../eval.c:7503
-#, fuzzy
-msgid "add() argument"
-msgstr "-c ÀÎÀÚ"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: ³Ê¹« ¸¹Àº ÀÎÀÚ"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete()Àº ÀÔ·Â ¸ðµå¿¡¼­¸¸ »ç¿ëµÉ ¼ö ÀÖ½À´Ï´Ù"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "È®ÀÎ(&O)"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: ۰¡ ÀÌ¹Ì Á¸ÀçÇÔ: %s"
-
-#: ../eval.c:8692
-#, fuzzy
-msgid "extend() argument"
-msgstr "--cmd ÀÎÀÚ"
-
-#: ../eval.c:8915
-#, fuzzy
-msgid "map() argument"
-msgstr "-c ÀÎÀÚ"
-
-#: ../eval.c:8916
-#, fuzzy
-msgid "filter() argument"
-msgstr "-c ÀÎÀÚ"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld ÁÙ: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: ¸ð¸£´Â ÇÔ¼ö: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "inputrestore()°¡ inputsave()º¸´Ù ¸¹ÀÌ ºÒ·ÁÁ³½À´Ï´Ù"
-
-#: ../eval.c:10771
-#, fuzzy
-msgid "insert() argument"
-msgstr "-c ÀÎÀÚ"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: ¹üÀ§°¡ Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: len()¿¡ À߸øµÈ Çü"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: Stride°¡ 0"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: ½ÃÀÛÀ§Ä¡°¡ ³¡À» Áö³ªÄ§"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<ºñ¾îÀÖÀ½>"
-
-#: ../eval.c:12282
-#, fuzzy
-msgid "remove() argument"
-msgstr "--cmd ÀÎÀÚ"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: ³Ê¹« ¸¹Àº ½Éº¼¸¯ ¸µÅ© (¹Ýº¹¼øÈ¯?)"
-
-#: ../eval.c:12593
-#, fuzzy
-msgid "reverse() argument"
-msgstr "-c ÀÎÀÚ"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "sort() argument"
-msgstr "-c ÀÎÀÚ"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "-c ÀÎÀÚ"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Á¤·Ä ºñ±³ ±â´ÉÀÌ ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Á¤·Ä ºñ±³ ±â´ÉÀÌ ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(À߸øµÇ¾ú½À´Ï´Ù)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Àӽà ÆÄÀÏ ¾²±â ¿¡·¯"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Float¸¦ Number·Î »ç¿ë"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Funcref¸¦ Number·Î »ç¿ë"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: List¸¦ Number·Î »ç¿ë"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Dictionary¸¦ Number·Î »ç¿ë"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: Funcref¸¦ StringÀ¸·Î »ç¿ë"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: List¸¦ StringÀ¸·Î »ç¿ë"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Dictionary¸¦ StringÀ¸·Î »ç¿ë"
-
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: º¯¼ö Çü ´Ù¸§: %s"
-
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: º¯¼ö %s¸¦ »èÁ¦ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Funcref º¯¼ö¸íÀº ´ë¹®ÀÚ·Î ½ÃÀÛÇØ¾ß ÇÔ: %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: º¯¼ö¸íÀÌ ÀÌ¹Ì ÀÖ´Â ÇÔ¼ö¸í°ú Ãæµ¹: %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: °ªÀÌ Àá°ÜÀÖÀ½: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "¸ð¸§"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: %s °ªÀ» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: º¹»çÇϱ⿡ º¯¼ö°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Á¤ÀÇ ¾È µÈ ÇÔ¼ö: %s"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: '('°¡ ¾øÀ½: %s"
-
-#: ../eval.c:17293
-#, fuzzy
-msgid "E862: Cannot use g: here"
-msgstr "E284: IC °ªÀ» ¼³Á¤ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: À߸øµÈ ÀÎÀÚ: %s"
-
-#: ../eval.c:17323
-#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "Áߺ¹µÈ ÇÊµå ¸í: %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: :endfunctionÀÌ ¾ø½À´Ï´Ù"
-
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: ÇÔ¼ö¸íÀÌ º¯¼ö¸í°ú Ãæµ¹: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: ÇÔ¼ö %sÀ»(¸¦) ´Ù½Ã Á¤ÀÇÇÒ ¼ö ¾ø½À´Ï´Ù: »ç¿ëÁßÀÔ´Ï´Ù"
-
-#: ../eval.c:17604
-#, 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.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: ÇÔ¼ö À̸§Àº ´ë¹®ÀÚ·Î ½ÃÀÛÇϰųª ÄÝ·ÐÀ» Æ÷ÇÔÇØ¾ß ÇÔ: %s"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: ÇÔ¼ö À̸§Àº ´ë¹®ÀÚ·Î ½ÃÀÛÇϰųª ÄÝ·ÐÀ» Æ÷ÇÔÇØ¾ß ÇÔ: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: ÇÔ¼ö %sÀ»(¸¦) Áö¿ï ¼ö ¾ø½À´Ï´Ù: »ç¿ëÁßÀÔ´Ï´Ù"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: ÇÔ¼ö¸¦ ºÎ¸¥ ±íÀ̰¡ 'maxfuncdepth'º¸´Ù Å®´Ï´Ù"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "%s ºÎ¸£´Â Áß"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%sÀÌ(°¡) ÁßÁöµÇ¾ú½À´Ï´Ù"
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%sÀÌ(°¡) #%<PRId64>À»(¸¦) µ¹·ÁÁÖ¾ú½À´Ï´Ù"
-
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%sÀÌ(°¡) %sÀ»(¸¦) µ¹·ÁÁÖ¾ú½À´Ï´Ù"
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "%s¿¡¼­ °è¼Ó"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :returnÀÌ ÇÔ¼ö ¾È¿¡ ÀÖÁö ¾Ê½À´Ï´Ù"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# Àü¿ª º¯¼ö:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tLast set from "
-
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "old ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, ½ÊÀ°Áø %02x, ÆÈÁø %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, ½ÊÀ°Áø %04x, ÆÈÁø %o"
-
-#: ../ex_cmds.c:146
-#, 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:747
-msgid "1 line moved"
-msgstr "1 ÁÙ ¿Å°ÜÁ³½À´Ï´Ù"
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> ÁÙ ¿Å°ÜÁ³½À´Ï´Ù"
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> ÁÙÀ» °É·¶½À´Ï´Ù"
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: *Filter* ÀÚµ¿¸í·ÉÀº ÇöÀç ¹öÆÛ¸¦ ¹Ù²Ù¾î¼­´Â ¾È µË´Ï´Ù"
-
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[¸¶Áö¸·À¸·Î °íÄ£ µÚ ÀúÀå ¾È ÇÔ]\n"
-
-#: ../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
-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
-#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "Viminfo ÆÄÀÏ \"%s\"À»(¸¦) ¾²´Â Áß"
-
-#. Write the info:
-#: ../ex_cmds.c:1720
-#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# ÀÌ viminfo ÆÄÀÏÀº ºöÀÌ ¸¸µç °ÍÀÔ´Ï´Ù Vim %s.\n"
-
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# Á¶½É¸¸ ÇÑ´Ù¸é °íÄ¥ ¼öµµ ÀÖ½À´Ï´Ù!\n"
-"\n"
-
-#: ../ex_cmds.c:1723
-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
-msgid "Write partial file?"
-msgstr "ÆÄÀÏ ÀϺθ¸ ÀúÀåÇÒ±î¿ä?"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: ¹öÆÛ ÀϺθ¸ ¾²·Á¸é !À» »ç¿ëÇϽʽÿÀ"
-
-#: ../ex_cmds.c:2281
-#, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "ÀÌ¹Ì ÀÖ´Â \"%s\" ÆÄÀÏÀ» µ¤¾î¾µ±î¿ä?"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr "½º¿Ò ÆÄÀÏ \"%s\"°¡ ÀÖ½À´Ï´Ù, µ¤¾î¾µ±î¿ä?"
-
-#: ../ex_cmds.c:2326
-#, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E768: ½º¿Ò ÆÄÀÏ ÀÖÀ½: %s (µ¤¾î¾²·Á¸é :silent! »ç¿ë)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: ¹öÆÛ %<PRId64>ÀÇ ÆÄÀÏ À̸§ÀÌ ¾ø½À´Ï´Ù"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: ÆÄÀÏÀÌ ½áÁöÁö ¾ÊÀ½: 'write' ¿É¼Ç¿¡ ÀÇÇØ ¾µ ¼ö°¡ ¾ø½À´Ï´Ù"
-
-#: ../ex_cmds.c:2434
-#, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"'readonly' ¿É¼ÇÀÌ \"%s\"¿¡ ´ëÇØ ¼³Á¤µÇ¾î ÀÖ½À´Ï´Ù.\n"
-"±×·¡µµ ¾²±â¸¦ ¿øÇϽʴϱî?"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-"ÆÄÀÏ \"%s\"°¡ ÀбâÀü¿ëÀÔ´Ï´Ù.\n"
-"±×·¡µµ ¾²±â°¡ °¡´ÉÇÒ Áöµµ ¸ð¸¨´Ï´Ù.\n"
-"ÇÑ ¹ø ½á º¼±î¿ä?"
-
-#: ../ex_cmds.c:2451
-#, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "E505: \"%s\"´Â Àбâ Àü¿ëÀÔ´Ï´Ù (µ¤¾î¾²·Á¸é ! ´õÇϱâ)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: Autocommand°¡ ¶æ ¹Û¿¡ »õ ¹öÆÛ %sÀ»(¸¦) Áö¿ü½À´Ï´Ù"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: ¼ýÀÚ°¡ ¾Æ´Ñ ÀÎÀÚ°¡ :z¿¡ ÁÖ¾îÁ³½À´Ï´Ù"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: rvim¿¡¼­´Â ½© ¸í·ÉÀ» »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: Á¤±ÔÇ¥Çö½ÄÀº ±ÛÀÚ·Î ±¸ºÐµÉ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_cmds.c:3964
-#, 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
-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:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64>°³ ¹Ù²åÀ½"
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr " ÇÑ ÁÙ¿¡¼­"
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr " %<PRId64> ÁÙ¿¡¼­"
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :globalÀº Àç±Í È£Ãâ µÉ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: global¿¡¼­ Á¤±ÔÇ¥Çö½ÄÀÌ ºüÁ³½À´Ï´Ù"
-
-#: ../ex_cmds.c:4508
-#, c-format
-msgid "Pattern found in every line: %s"
-msgstr "¿©·¯ ÁÙ¿¡¼­ ÆÐÅÏÀ» ã¾Ò½À´Ï´Ù: %s"
-
-#: ../ex_cmds.c:4510
-#, fuzzy, c-format
-msgid "Pattern not found: %s"
-msgstr "ÆÐÅÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_cmds.c:4587
-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: \"%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: ³Ê¹« ¸¹Àº signÀÌ Á¤ÀǵǾî ÀÖ½À´Ï´Ù"
-
-#: ../ex_cmds.c:5813
-#, 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"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "ÁßÁöÁ¡: \"%s%s\" %<PRId64> ÁÙ"
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: ÁßÁöÁ¡À» ãÀ» ¼ö ¾ø½À´Ï´Ù: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "ÁßÁöÁ¡ÀÌ Á¤ÀǵǾî ÀÖÁö ¾Ê½À´Ï´Ù"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s %<PRId64> ÁÙ"
-
-#: ../ex_cmds2.c:942
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: ¸ÕÀú \":profile start {fname}\"À» »ç¿ëÇϼ¼¿ä"
-
-#: ../ex_cmds2.c:1269
-#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "\"%s\"¿¡ ¹Ù²ï ³»¿ëÀ» ÀúÀåÇÒ±î¿ä?"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "Á¦¸ñ ¾øÀ½"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: ¹öÆÛ \"%s\"¿¡ ³ªÁß¿¡ ¹Ù²ï ³»¿ëÀÌ ½áÁöÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#: ../ex_cmds2.c:1480
-msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
-msgstr "°æ°í: ¶æ ¹Û¿¡ ´Ù¸¥ ¹öÆÛ·Î µé¾î°¬½À´Ï´Ù (autocommand¸¦ È®ÀÎÇϽʽÿÀ)"
-
-#: ../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
-#, 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 "µð·ºÅ丮´Â sourceÇÒ ¼ö ¾øÀ½: \"%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 ""
-
-#: ../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_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: :scriptencodingÀÌ ºÒ·¯µéÀÎ ÆÄÀÏ ¹Û¿¡¼­ »ç¿ëµÇ¾ú½À´Ï´Ù"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: :finish°¡ ºÒ·¯µéÀÎ ÆÄÀÏ ¹Û¿¡¼­ »ç¿ëµÇ¾ú½À´Ï´Ù"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "ÇöÀç %s¾ð¾î: \"%s\""
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: ¾ð¾î¸¦ \"%s\"(À¸)·Î ¼³Á¤ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "Ex »óÅ·ΠÀüȯ. Normal »óÅ·Π°¡·Á¸é \"visual\"À» ÀÔ·ÂÇϽʽÿÀ."
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: ÆÄÀÏÀÇ ¸¶Áö¸·ÀÔ´Ï´Ù"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: ¸í·ÉÀÌ ³Ê¹« ¸¹ÀÌ ´Ù½Ã ¹Ýº¹µÇ¾ú½À´Ï´Ù"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: ¿¹¿Ü°¡ ¹ß»ýÇÏÁö ¾Ê¾Ò½À´Ï´Ù: %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "ºÒ·¯µéÀÎ ÆÄÀÏÀÇ ¸¶Áö¸·"
-
-#: ../ex_docmd.c:1086
-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:1729
-msgid "E493: Backwards range given"
-msgstr "E493: ¹Ý´ë ¿µ¿ªÀÌ ÁÖ¾îÁ³½À´Ï´Ù"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "¹Ý´ë ¿µ¿ªÀÌ ÁÖ¾îÁ³½À´Ï´Ù, µÚÁýÀ»±î¿ä"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: w³ª w>>¸¦ »ç¿ëÇϽʽÿÀ"
-
-#: ../ex_docmd.c:3454
-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 "°íÄ¥ ÆÄÀÏÀÌ ÇÑ °³ ´õ ÀÖ½À´Ï´Ù. ±×·¡µµ ³¡³¾±î¿ä?"
-
-#: ../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: °íÄ¥ ÆÄÀÏÀÌ ÇÑ °³ ´õ ÀÖ½À´Ï´Ù"
-
-#: ../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
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E841: ¿¹¾àµÈ À̸§, »ç¿ëÀÚ Á¤ÀÇ ¸í·ÉÀ¸·Î »ç¿ëµÉ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_docmd.c:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: ±×·± »ç¿ëÀÚ Á¤ÀÇ ¸í·É ¾øÀ½: %s"
-
-#: ../ex_docmd.c:5219
-#, 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: ¿Ï¼º ÀÎÀÚ´Â »ç¿ëÀÚ ¿Ï¼º¿¡¼­¸¸ Çã¿ëµË´Ï´Ù"
-
-#: ../ex_docmd.c:5231
-msgid "E467: Custom completion requires a function argument"
-msgstr "E467: »ç¿ëÀÚ ¿Ï¼ºÀº ÇÔ¼ö ÀÎÀÚ°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../ex_docmd.c:5257
-#, fuzzy, c-format
-msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: »ö ½ºÅ´ %sÀ»(¸¦) ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "ºö »ç¿ëÀÚ´Ô, ȯ¿µÇÕ´Ï´Ù!"
-
-#: ../ex_docmd.c:5431
-msgid "E784: Cannot close last tab page"
-msgstr "E784: ¸¶Áö¸· ÅÇÀ» ´ÝÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_docmd.c:5462
-msgid "Already only one tab page"
-msgstr "ÀÌ¹Ì ÇϳªÀÇ ÅǸ¸ ÀÖ½À´Ï´Ù"
-
-#: ../ex_docmd.c:6004
-#, c-format
-msgid "Tab page %d"
-msgstr "ÅÇ ÆäÀÌÁö %d"
-
-#: ../ex_docmd.c:6295
-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
-msgid "E186: No previous directory"
-msgstr "E186: ÀÌÀü µð·ºÅ丮°¡ ¾ø½À´Ï´Ù"
-
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: ¸ð¸§"
-
-#: ../ex_docmd.c:6610
-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
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: \"%s\"ÀÌ(°¡) Á¸ÀçÇÕ´Ï´Ù (µ¤¾î¾²·Á¸é ! ´õÇϱâ)"
-
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: ¾²±â À§ÇÑ \"%s\"À»(¸¦) ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: ÀÎÀÚ´Â ±ÛÀÚ³ª ¾Õ/µÚ ÀÎ¿ë ºÎÈ£¿©¾ß ÇÕ´Ï´Ù"
-
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: :normalÀÇ Àç±Í È£ÃâÀÌ ³Ê¹« ¸¹ÀÌ »ý°å½À´Ï´Ù"
-
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: '#'¿¡ ´ëÇØ ġȯÇÒ ±³Ã¼ ÆÄÀÏ À̸§ÀÌ ¾ø½À´Ï´Ù"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: \"<afile>\"¿¡ ´ëÇØ ġȯÇÒ ÀÚµ¿¸í·É ÆÄÀÏ À̸§ÀÌ ¾ø½À´Ï´Ù"
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: \"<abuf>\"¿¡ ´ëÇØ ġȯÇÒ ÀÚµ¿¸í·É ¹öÆÛ ¹øÈ£°¡ ¾ø½À´Ï´Ù"
-
-#: ../ex_docmd.c:7861
-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
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E842: \"<slnum>\"¿¡ »ç¿ëµÉ ÁÙ ¹øÈ£°¡ ¾ø½À´Ï´Ù"
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: '%'³ª '#'¿¡ ´ëÇÑ ºó ÆÄÀÏ À̸§, ¿À·ÎÁö \":p:h\"¿Í¸¸ µ¿ÀÛÇÕ´Ï´Ù"
-
-#: ../ex_docmd.c:7905
-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_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: 'Vim' Á¢µÎ»ç·Î ¿¹¿Ü¸¦ :throwÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "¿¹¿Ü thrown: %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "¿¹¿Ü Á¾·áµÊ: %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "¿¹¿Ü ¹ö·ÁÁü: %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, %<PRId64> ÁÙ"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "¿¹¿Ü ¹ß»ý: %s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr "%sÀÌ(°¡) pending µÇ¾ú½À´Ï´Ù"
-
-#: ../ex_eval.c:679
-#, c-format
-msgid "%s resumed"
-msgstr "%sÀÌ(°¡) Àç°³ µÇ¾ú½À´Ï´Ù"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr "%sÀÌ(°¡) ¹ö·ÁÁ³½À´Ï´Ù"
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "¿¹¿Ü"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "¿¡·¯¿Í ÀÎÅÍ·´Æ®"
-
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "¿¡·¯"
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "ÀÎÅÍ·´Æ®"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: :if°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :if¾øÀÌ :endif°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :if¾øÀÌ :else°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :if¾øÀÌ :elseif°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: ¿©·¯°³ÀÇ :else°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :else µÚ¿¡ :elseif°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:941
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: :while/:for°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
-
-#: ../ex_eval.c:1028
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :while ȤÀº :for¾øÀÌ :continue°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:1061
-msgid "E587: :break without :while or :for"
-msgstr "E587: :while ȤÀº :for¾øÀÌ :break°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:1102
-msgid "E732: Using :endfor with :while"
-msgstr "E732: :while¿¡ :endfor°¡ »ç¿ëµÇ¾ú½À´Ï´Ù"
-
-#: ../ex_eval.c:1104
-msgid "E733: Using :endwhile with :for"
-msgstr "E733: :for¿¡ :endwhileÀÌ »ç¿ëµÇ¾ú½À´Ï´Ù"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: :try°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
-
-#: ../ex_eval.c:1317
-msgid "E603: :catch without :try"
-msgstr "E603: :try¾øÀÌ :catch°¡ ÀÖ½À´Ï´Ù"
-
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
-msgid "E604: :catch after :finally"
-msgstr "E604: :finally µÚ¿¡ :catch°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :try¾øÀÌ :finally°¡ ÀÖ½À´Ï´Ù"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: ¿©·¯°³ÀÇ :finally°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :try¾øÀÌ :endtry°¡ ÀÖ½À´Ï´Ù"
-
-#: ../ex_eval.c:2026
-msgid "E193: :endfunction not inside a function"
-msgstr "E193: :endfunctionÀÌ function ³»¿¡ ¾ø½À´Ï´Ù"
-
-#: ../ex_getln.c:1643
-msgid "E788: Not allowed to edit another buffer now"
-msgstr "E788: Áö±ÝÀº ´Ù¸¥ ¹öÆÛ¸¦ ÆíÁýÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_getln.c:1656
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E811: Áö±ÝÀº ¹öÆÛ Á¤º¸¸¦ ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
-
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "ű×À̸§"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " kind file\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "'history' ¿É¼ÇÀÌ 0ÀÔ´Ï´Ù"
-
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s È÷½ºÅ丮 (»õ°ÍºÎÅÍ ¿À·¡µÈ °Í ¼ø):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "¸í·É ÁÙ"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "ãÀ» ¹®ÀÚ¿­"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "Ç¥Çö"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "ÀÔ·Â ÁÙ"
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar°¡ ¸í·É ±æÀ̸¦ ¹þ¾î³µ½À´Ï´Ù"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: Ȱ¼ºµÈ âÀ̳ª ¹öÆÛ°¡ Áö¿öÁ³½À´Ï´Ù"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr ""
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: À߸øµÈ °æ·Î: '**[¹øÈ£]'´Â °æ·ÎÀÇ ¸¶Áö¸·¿¡ À§Ä¡Çϰųª '%s' µÚ¿¡ ÀÖ¾î¾ß "
-"ÇÕ´Ï´Ù."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpath¿¡¼­ \"%s\" µð·ºÅ丮¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: path¿¡¼­ \"%s\" ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: cdpath¿¡¼­ ´õ ÀÌ»óÀÇ \"%s\" µð·ºÅ丮¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: path¿¡¼­ ´õ ÀÌ»óÀÇ \"%s\" ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:137
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E812: Autocommand°¡ ¹öÆÛ³ª ¹öÆÛÀ̸§À» ¹Ù²Ù¾ú½À´Ï´Ù"
-
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "À߸øµÈ ÆÄÀÏ À̸§"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "Àº(´Â) µð·ºÅ丮ÀÔ´Ï´Ù"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "Àº(´Â) ÆÄÀÏÀÌ ¾Æ´Õ´Ï´Ù"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[»õ ÆÄÀÏ]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr "[»õ µð·ºÅ丮]"
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr "[ÆÄÀÏÀÌ ³Ê¹« Å­]"
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[Çã¿ë ¾È µË´Ï´Ù]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200: *ReadPre ÀÚµ¿¸í·ÉÀÌ ÆÄÀÏÀ» ÀÐÁö ¸øÇÏ°Ô ¸¸µé¾ú½À´Ï´Ù"
-
-#: ../fileio.c:655
-msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: *ReadPre ÀÚµ¿¸í·ÉÀº ÇöÀç ¹öÆÛ¸¦ ¹Ù²Ù¸é ¾È µË´Ï´Ù"
-
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "ºö: Ç¥ÁØÀԷ¿¡¼­ Àд Áß...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202: º¯È¯µÈ ÆÄÀÏÀ» ÀÐÀ» ¼ö°¡ ¾ø½À´Ï´Ù!"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[ÇÇÆ÷/¼ÒÄÏ]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[ÇÇÆ÷]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[¼ÒÄÏ]"
-
-#. or character special
-#: ../fileio.c:1801
-msgid "[character special]"
-msgstr ""
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[CR ¾øÀ½]"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[±ä ÁÙ À߸²]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[º¯È¯ ¾È µË´Ï´Ù]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[º¯È¯ µÇ¾ú½À´Ï´Ù]"
-
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[%<PRId64> ÁÙ¿¡¼­ º¯È¯ ¿¡·¯]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[%<PRId64> ÁÙ¿¡ À߸øµÈ ¹ÙÀÌÆ®]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[Àб⠿¡·¯]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "º¯È¯Çϱâ À§ÇÑ Àӽà ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "'charconvert'¸¦ »ç¿ëÇÑ º¯È¯ÀÌ ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../fileio.c:2113
-msgid "can't read output of 'charconvert'"
-msgstr "'charconvert'ÀÇ Ãâ·Â°á°ú¸¦ ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:2437
-msgid "E676: No matching autocommands for acwrite buffer"
-msgstr "E676: acwrite ¹öÆÛ¿¡ ´ëÇÑ autocommand¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr "E203: ¾µ ¹öÆÛ¸¦ ÀÚµ¿¸í·ÉÀÌ Áö¿ì°Å³ª ´Ý¾Ò½À´Ï´Ù"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: Autocommand°¡ À߸øµÈ ¹æ¹ýÀ¸·Î ÁÙÀ» ¹Ù²Ù¾ú½À´Ï´Ù"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "ÆÄÀÏ È¤Àº ¾µ ¼ö ÀÖ´Â ÀåÄ¡°¡ ¾Æ´Õ´Ï´Ù"
-
-#: ../fileio.c:2601
-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:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr "E509: ¹é¾÷ÆÄÀÏÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ù (µ¤¾î¾²·Á¸é ! ´õÇϱâ)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr "E510: ¹é¾÷ÆÄÀÏÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ù (µ¤¾î¾²·Á¸é ! ´õÇϱâ)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: ¾µ Àӽà ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr "E213: º¯È¯ÇÒ ¼ö ¾ø½À´Ï´Ù (º¯È¯ ¾øÀÌ ÀúÀåÇÏ·Á¸é ! ´õÇϱâ)"
-
-#: ../fileio.c:3169
-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: Fsync°¡ ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: ´Ý±â°¡ ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../fileio.c:3436
-msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: ¾²±â ¿¡·¯, º¯È¯ ½ÇÆÐ (¹«½ÃÇÏ·Á¸é 'fenc'¸¦ ºñ¿ì¸é µÊ)"
-
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: ¾²±â ¿¡·¯, %<PRId64> ÁÙ¿¡¼­ º¯È¯ ½ÇÆÐ (¹«½ÃÇÏ·Á¸é 'fenc'¸¦ ºñ¿ì¸é µÊ)"
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: ¾²±â ¿¡·¯ (ÆÄÀÏ ½Ã½ºÅÛÀÌ ²Ëᳪ¿ä?)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr " º¯È¯ ¿¡·¯"
-
-#: ../fileio.c:3509
-#, c-format
-msgid " in line %<PRId64>;"
-msgstr "%<PRId64> ÁÙ¿¡¼­;"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[ÀåÄ¡]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[»õ·Î¿î]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr " [a]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " ´õÇß½À´Ï´Ù"
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr " [w]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " ÀúÀå Çß½À´Ï´Ù"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: ÆÐÄ¡ »óÅÂ: ¿ø·¡ ÆÄÀÏÀ» ÀúÀåÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: ÆÐÄ¡ »óÅÂ: ºó ¿ø·¡ ÆÄÀÏÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: ¹é¾÷ ÆÄÀÏÀ» Áö¿ï ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"°æ°í: ¿ø·¡ ÆÄÀÏÀÌ ¾ø¾îÁ³°Å³ª ±úÁ³À» ¼ö ÀÖ½À´Ï´Ù\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "ÆÄÀÏÀÌ ¼º°øÀûÀ¸·Î ÀúÀåµÉ ¶§±îÁö ÆíÁý±â¸¦ ³¡³»Áö ¸¶½Ê½Ã¿À!"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[µµ½º]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[µµ½º Çü½Ä]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[¸Æ]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[¸Æ Çü½Ä]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[À¯´Ð½º]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[À¯´Ð½º Çü½Ä]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 ÁÙ, "
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> ÁÙ, "
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 ±ÛÀÚ"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> ±ÛÀÚ"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-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
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "°æ°í: ÆÄÀÏÀÌ ÀÐÀº µÚ¿¡ ¹Ù²î¾ú½À´Ï´Ù!!!"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "Á¤¸»·Î ¾²±â¸¦ ¿øÇϽʴϱî"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: \"%s\"¿¡ ¾²±â ¿¡·¯"
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: \"%s\" ´Ý±â ¿¡·¯"
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: \"%s\" Àб⠿¡·¯"
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: FileChangedShell ÀÚµ¿¸í·ÉÀÌ ¹öÆÛ¸¦ Áö¿ü½À´Ï´Ù"
-
-#: ../fileio.c:4894
-#, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: ÆÄÀÏ \"%s\"À»(¸¦) ´õ ÀÌ»ó »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:4906
-#, c-format
-msgid ""
-"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
-"well"
-msgstr ""
-"W12: °æ°í: ÆÄÀÏ \"%s\"ÀÌ(°¡) ¹Ù²î¾ú°í ¸¶Âù°¡Áö·Î ºöÀÇ ¹öÆÛµµ ¹Ù²î¾ú½À´Ï´Ù"
-
-#: ../fileio.c:4907
-msgid "See \":help W12\" for more info."
-msgstr "´õ ¸¹Àº Á¤º¸¸¦ º¸·Á¸é \":help W12\"À» ÀÔ·ÂÇϼ¼¿ä."
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: °æ°í: ÆÄÀÏ \"%s\"ÀÌ(°¡) °íÄ¡±â ½ÃÀÛÇÑ µÚ¿¡ ¹Ù²î¾ú½À´Ï´Ù"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "´õ ¸¹Àº Á¤º¸¸¦ º¸·Á¸é \":help W11\"À» ÀÔ·ÂÇϼ¼¿ä."
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr "W16: °æ°í: ÆÄÀÏ \"%s\"ÀÇ »óŰ¡ °íÄ¡±â ½ÃÀÛÇÑ µÚ¿¡ ¹Ù²î¾ú½À´Ï´Ù"
-
-#: ../fileio.c:4915
-msgid "See \":help W16\" for more info."
-msgstr "´õ ¸¹Àº Á¤º¸¸¦ º¸·Á¸é \":help W16\"À» ÀÔ·ÂÇϼ¼¿ä."
-
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: °æ°í: ÆÄÀÏ \"%s\"ÀÌ(°¡) °íÄ¡±â ½ÃÀÛÇÑ µÚ¿¡ ¸¸µé¾ú½À´Ï´Ù"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "°æ°í"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"È®ÀÎ(&O)\n"
-"ÆÄÀÏ ºÒ·¯¿À±â(&L)"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: \"%s\"ÀÇ Àç·Îµå¸¦ ÁغñÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fileio.c:5078
-#, 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 "autocommand ÀÚµ¿»èÁ¦: %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"
-"--- Auto-Commands ---"
-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: ALL À̺¥Æ®¿¡ ´ëÇØ ÀÚµ¿¸í·ÉÀ» ½ÇÇàÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../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 Auto commands for \"%s\""
-msgstr ""
-
-#: ../fileio.c:7149
-#, c-format
-msgid "Executing %s"
-msgstr "%s ½ÇÇàÁß"
-
-#: ../fileio.c:7211
-#, c-format
-msgid "autocommand %s"
-msgstr "ÀÚµ¿¸í·É %s"
-
-#: ../fileio.c:7795
-msgid "E219: Missing {."
-msgstr "E219: {°¡ ¾ø½À´Ï´Ù."
-
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: }°¡ ¾ø½À´Ï´Ù."
-
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: fold°¡ ¾ø½À´Ï´Ù"
-
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: ÇöÀçÀÇ 'foldmethod'À¸·Î Á¢±â¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: ÇöÀçÀÇ 'foldmethod'À¸·Î Á¢±â¸¦ Áö¿ï ¼ö ¾ø½À´Ï´Ù"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld ÁÙ Á¢Èû "
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: ÀÐÇôÁø ¹öÆÛ¿¡ ´õÇϱâ"
-
-#: ../getchar.c:2040
-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
-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
-msgid "E470: Command aborted"
-msgstr "E470: ¸í·ÉÀÌ ÁßÁöµÇ¾ú½À´Ï´Ù"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: ÀÎÀÚ°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: /, ? ȤÀº &´Â \\ µÚ¿¡ ¿Í¾ß ÇÕ´Ï´Ù"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: ¸í·ÉÁ٠â¿¡ À߸øµÊ; <CR> ½ÇÇà, CTRL-C ³¡³»±â"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: ÇöÀç µð·ºÅ丮 ¶Ç´Â ÅÂ±× Ã£±â¿¡¼­ exrc/vimrc¿¡¼­ÀÇ ¸í·ÉÀº Çã¿ë ¾È µË´Ï´Ù"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: :endif°¡ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: :endtry°¡ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: :endwhileÀÌ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: :endfor ´©¶ô"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :while¾øÀÌ :endwhileÀÌ ÀÖ½À´Ï´Ù"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :for ¾ø´Â :endfor"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: ÆÄÀÏÀÌ ÀÖ½À´Ï´Ù (µ¤¾î¾²·Á¸é ! »ç¿ë)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: ¸í·ÉÀÌ ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: ³»ºÎ ¿¡·¯"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "ÁߴܵǾú½À´Ï´Ù"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: À߸øµÈ ÁÖ¼Ò"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: À߸øµÈ ÀÎÀÚ"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: À߸øµÈ ÀÎÀÚ: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: À߸øµÈ Ç¥Çö½Ä: %s"
-
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: À߸øµÈ ¹üÀ§"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: À߸øµÈ ¸í·É"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\"Àº(´Â) µð·ºÅ丮ÀÔ´Ï´Ù"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: ½ºÅ©·Ñ Å©±â°¡ À߸øµÇ¾ú½À´Ï´Ù"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: ¶óÀ̺귯¸® \"%s()\" ºÎ¸£±â ½ÇÆÐ"
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: ¸¶Å©°¡ À߸øµÈ ÁÙ ¹øÈ£¸¦ °¡Áö°í ÀÖ½À´Ï´Ù"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: ¸¶Å©°¡ ¼³Á¤µÇ¾î ÀÖÁö ¾Ê½À´Ï´Ù"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: ¹Ù²Ü ¼ö ¾øÀ½, 'modifiable'ÀÌ ²¨Á®ÀÖ½À´Ï´Ù"
-
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: ½ºÅ©¸³Æ®°¡ ³Ê¹« ±í°Ô ÁßøµÇ¾ú½À´Ï´Ù"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: ´Ù¸¥ ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ±×·± ¾à¾î´Â ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: !Àº Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUI´Â »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù: ÄÄÆÄÀÏ ¶§ Æ÷ÇÔµÇÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ÀÌ·± ÇÏÀ̶óÀÌÆ® ±×·ì À̸§Àº ¾ø½À´Ï´Ù: %s"
-
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ÀÔ·ÂµÈ ÅØ½ºÆ®°¡ ¾ÆÁ÷ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: ÀÌÀü ¸í·É ÁÙÀÌ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ±×·± ¸ÊÇÎÀÌ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: ¸ÂÁö ¾Ê½À´Ï´Ù"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: ¸ÂÁö ¾ÊÀ½: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ÆÄÀÏ À̸§ÀÌ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: ÀÌÀü ¹Ù²Ù±â Á¤±Ô Ç¥Çö½ÄÀÌ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: ÀÌÀü ¸í·ÉÀÌ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: ÀÌÀü Á¤±ÔÇ¥Çö½ÄÀÌ ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: ¹üÀ§´Â Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
-
-#: ../globals.h:1048
-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
-msgid "E483: Can't get temp file name"
-msgstr "E483: Àӽà ÆÄÀÏ À̸§À» ¾òÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: %s ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1052
-#, 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
-msgid "E38: Null argument"
-msgstr "E38: ³Î ÀÎÀÚ"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: ¼ýÀÚ°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: ¿¡·¯ÆÄÀÏ %sÀ»(¸¦) ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: ¸Þ¸ð¸®°¡ ¹Ù´Ú³µ½À´Ï´Ù!"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "ÆÐÅÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: ÆÐÅÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: ÀÎÀÚ´Â ¾ç¼öÀ̾î¾ß ÇÕ´Ï´Ù"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: ÀÌÀü µð·ºÅ丮·Î °¥ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: ¿¡·¯ ¾øÀ½"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: À§Ä¡ ¸ñ·Ï ¾øÀ½"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: ±úÁø ¸Â´Â ¹®ÀÚ¿­"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: ±úÁø Á¤±ÔÇ¥Çö½Ä ÇÁ·Î±×·¥"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: 'readonly' ¿É¼ÇÀÌ ¼³Á¤µÇ¾î ÀÖ½À´Ï´Ù (µ¤¾î¾²·Á¸é ! ´õÇϱâ)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Àбâ Àü¿ë º¯¼ö \"%s\"À»(¸¦) ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: sandbox ¾È¿¡¼­´Â º¯¼ö¸¦ ¼³Á¤ÇÒ ¼ö ¾øÀ½: \"%s\""
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: ¿¡·¯ÆÄÀÏ Àд µµÁß¿¡ ¿¡·¯"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: sandbox¿¡¼­´Â Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ¿©±â¿¡¼­ Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ½ºÅ©¸° »óÅ ¼³Á¤Àº Áö¿øµÇÁö ¾Ê½À´Ï´Ù"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: ½ºÅ©·Ñ Å©±â°¡ À߸øµÇ¾ú½À´Ï´Ù"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: 'shell' ¿É¼ÇÀÌ ºñ¾ú½À´Ï´Ù"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: sign ÀڷḦ ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: ½º¿Ò ÆÄÀÏÀ» ´ÝÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: ÅÂ±× ½ºÅÃÀÌ ºñ¾ú½À´Ï´Ù"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: ¸í·ÉÀÌ ³Ê¹« º¹ÀâÇÕ´Ï´Ù"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: À̸§ÀÌ ³Ê¹« ±é´Ï´Ù"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: [°¡ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ÆÄÀÏ À̸§ÀÌ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: ³¡¿¡ ¹®ÀÚ°¡ ´õ ÀÖ½À´Ï´Ù"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: ¸ð¸£´Â ¸¶Å©"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: ¸¸´É ±ÛÀÚ¸¦ È®ÀåÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight'´Â 'winminheight'º¸´Ù Ä¿¾ß ÇÕ´Ï´Ù"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth'´Â 'winminwidth'º¸´Ù Ä¿¾ß ÇÕ´Ï´Ù"
-
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: ¾²´Â Áß¿¡ ¿¡·¯"
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Zero count"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: ½ºÅ©¸³Æ® ÄÜÅØ½ºÆ® ¹Û¿¡¼­ <SID> »ç¿ë"
-
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: ³»ºÎ ¿¡·¯: %s"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: ÆÐÅÏÀÌ 'maxmempattern'º¸´Ù ¸¹Àº ¸Þ¸ð¸®¸¦ »ç¿ëÇÕ´Ï´Ù"
-
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: ºó ¹öÆÛ"
-
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: À߸øµÈ ã±â ÆÐÅÏ È¤Àº ±¸ºÐÀÚ"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: ÆÄÀÏÀÌ ´Ù¸¥ ¹öÆÛ¿¡ ·ÎµùµÇ¾î ÀÖ½À´Ï´Ù"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: ¿É¼Ç '%s'ÀÌ(°¡) ¼³Á¤µÇ¾î ÀÖÁö ¾Ê½À´Ï´Ù"
-
-#: ../globals.h:1111
-#, fuzzy
-msgid "E850: Invalid register name"
-msgstr "E354: À߸øµÈ ·¹Áö½ºÅÍ À̸§: '%s'"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "óÀ½±îÁö ã¾ÒÀ½, ³¡¿¡¼­ °è¼Ó"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "³¡±îÁö ã¾ÒÀ½, óÀ½ºÎÅÍ °è¼Ó"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: ÄÝ·ÐÀÌ ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: ÀÌ»óÇÑ ÄÄÆ÷³ÍÆ®"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: ¼ýÀÚ°¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "ÆäÀÌÁö %d"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "ÀμâµÉ ÅØ½ºÆ®°¡ ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "ÆäÀÌÁö %d ÀμâÁß (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr " º¹»ç %d / %d"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "ÀμâµÊ: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "ÀμⰡ Ãë¼ÒµÇ¾ú½À´Ï´Ù."
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: Æ÷½ºÆ®½ºÅ©¸³Æ® Ãâ·ÂÆÄÀÏ¿¡ ¾µ ¼ö ¾ø½À´Ï´Ù."
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: \"%s\" ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏ \"%s\"À»(¸¦) ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:1772
-#, c-format
-msgid "E618: file \"%s\" is not a PostScript resource file"
-msgstr "E618: ÆÄÀÏ \"%s\"Àº(´Â) Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏÀÌ ¾Æ´Õ´Ï´Ù"
-
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: ÆÄÀÏ \"%s\"Àº(´Â) Áö¿øµÇ´Â Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏÀÌ ¾Æ´Õ´Ï´Ù"
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: \"%s\" ¸®¼Ò½º ÆÄÀÏÀº ¹öÀüÀÌ À߸øµÇ¾ú½À´Ï´Ù"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: ȣȯµÇÁö ¾Ê´Â ´ÙÁß¹®ÀÚ ÀÎÄÚµù°ú ¹®ÀÚ¼Â."
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: printmbcharset´Â ´ÙÁß¹®ÀÚ ÀÎÄÚµù¿¡¼­ ¹Ýµå½Ã ¼³Á¤µÇ¾î¾ß ÇÕ´Ï´Ù."
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr "E675: ´ÙÁß¹®ÀÚ Àμ⸦ À§ÇÑ ±Û²ÃÀÌ ¼³Á¤µÇ¾î ÀÖÁö ¾Ê½À´Ï´Ù"
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: Æ÷½ºÆ®½ºÅ©¸³Æ® Ãâ·ÂÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: \"%s\" ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏ \"prolog.ps\"¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:2593
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏ \"cidfont.ps\"¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: Æ÷½ºÆ®½ºÅ©¸³Æ® ¸®¼Ò½º ÆÄÀÏ \"%s.ps\"¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:2654
-#, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: \"%s\" Àμâ ÀÎÄÚµùÀ¸·Î º¯È¯ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "ÇÁ¸°ÅÍ·Î º¸³»´Â Áß..."
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: Æ÷½ºÆ®½ºÅ©¸³Æ® ÆÄÀÏÀ» ÀμâÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "ÀμâÀÛ¾÷ÀÌ ³¡³µ½À´Ï´Ù."
-
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "»õ µ¥ÀÌÅͺ£À̽º ´õÇϱâ"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr ""
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "ÀÌ ¸Þ½ÃÁö º¸À̱â"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "¿¬°á ²÷±â"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "¸ðµç ¿¬°á ´Ù½Ã ÃʱâÈ­"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "¿¬°á º¸¿©ÁÖ±â"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: »ç¿ë¹ý: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "ÀÌ cscope ¸í·ÉÀº â ³ª´©±â¸¦ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù.\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: »ç¿ë¹ý: cstag <ident>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: ű׸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) ¿¡·¯: %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %sÀº(´Â) µð·ºÅ丮µµ ȤÀº cscope µ¥ÀÌÅͺ£À̽º°¡ ¾Æ´Õ´Ï´Ù"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "cscope µ¥ÀÌÅͺ£À̽º %s¿¡ ´õÇß½À´Ï´Ù."
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: cscope ¿¬°á %<PRId64> Àб⠿¡·¯"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: ¸ð¸£´Â cscope ã±â Çü½Ä"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: cscope ÆÄÀÌÇÁ¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: cscope¸¦ forkÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../if_cscope.c:849
-#, fuzzy
-msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection ½ÇÇàÀÌ ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection ½ÇÇàÀÌ ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: to_fp¿¡ ´ëÇÑ fdopen ½ÇÆÐ"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fr_fp¿¡ ´ëÇÑ fdopen ½ÇÆÐ"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: cscope ÇÁ·Î¼¼½º¸¦ spawnÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: cscope ¿¬°áÀÌ ¾ø½À´Ï´Ù"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr ""
-
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr ""
-
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "cscope ¸í·É:\n"
-
-#: ../if_cscope.c:1150
-#, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %s%*s (»ç¿ë¹ý: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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"
-" c: ÀÌ ÇÔ¼ö¸¦ ºÎ¸£´Â ÇÔ¼öµé ã±â\n"
-" d: ÀÌ ÇÔ¼ö¿¡ ÀÇÇØ ºÒ·ÁÁö´Â ÇÔ¼öµé ã±â\n"
-" e: ÀÌ egrep ÆÐÅÏ Ã£±â\n"
-" f: ÀÌ ÆÄÀÏ Ã£±â\n"
-" g: ÀÌ Á¤ÀÇ Ã£±â\n"
-" i: ÀÌ ÆÄÀÏÀ» Æ÷ÇÔÇÏ´Â ÆÄÀϵé ã±â\n"
-" s: ÀÌ C ½Éº¼ ã±â\n"
-" t: ÀÌ ¹®ÀÚ¿­ ã±â\n"
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: Áߺ¹µÈ cscope µ¥ÀÌÅͺ£À̽º´Â ´õÇØÁöÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: cscope ¿¬°á %sÀ»(¸¦) ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "cscope ¿¬°á %sÀÌ(°¡) ´ÝÇû½À´Ï´Ù"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: cs_manage_matches¿¡ ½É°¢ÇÑ ¿¡·¯"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Cscope ű×: %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # ÁÙ"
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "ÆÄÀÏ À̸§ / ÄÜÅØ½ºÆ® / ÁÙ\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: Cscope ¿¡·¯: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "¸ðµç cscope µ¥ÀÌÅͺ£À̽º ¸®¼Â"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "cscope ¿¬°áÀÌ ¾ø½À´Ï´Ù\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid µ¥ÀÌÅͺ£À̽º À̸§ prepend path\n"
-
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "¸ð¸£´Â ¿É¼Ç ÀÎÀÚ"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "³Ê¹« ¸¹Àº ÆíÁý ÀÎÀÚ"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "µÚ¿¡ ÀÎÀÚ°¡ ¾øÀ½"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "¿É¼Ç ÀÎÀÚ µÚ¿¡ ¾²·¹±â °ª"
-
-#: ../main.c:152
-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
-#, c-format
-msgid "%d files to edit\n"
-msgstr "%d ÆÄÀÏÀ» °íÄ¡±â\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "½ºÅ©¸³Æ® ÆÄÀÏÀ» ´Ù½Ã ¿­·Á°í ½Ãµµ: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "Àбâ À§ÇØ ¿­ ¼ö ¾øÀ½: \""
-
-#: ../main.c:1393
-msgid "Cannot open for script output: \""
-msgstr "½ºÅ©¸³Æ® Ãâ·ÂÀ» ¿­ ¼ö ¾øÀ½: \""
-
-#: ../main.c:1622
-msgid "Vim: Warning: Output is not to a terminal\n"
-msgstr "ºö: °æ°í: Å͹̳ηΠÃâ·ÂÇÒ ¼ö ¾ø½À´Ï´Ù\n"
-
-#: ../main.c:1624
-msgid "Vim: Warning: Input is not from a terminal\n"
-msgstr "ºö: °æ°í: Å͹̳ηΠºÎÅÍ ÀԷ¹ÞÀ» ¼ö ¾ø½À´Ï´Ù\n"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "pre-vimrc ¸í·É Çà"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: \"%s\"¿¡¼­ ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"´õ ¸¹Àº Á¤º¸¸¦ ¿øÇϽøé: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[ÆÄÀÏ ..] ÁÖ¾îÁø ÆÄÀÏ °íÄ¡±â"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- Ç¥ÁØÀԷ¿¡¼­ ÅØ½ºÆ® Àбâ"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t tag űװ¡ Á¤ÀÇµÈ À§Ä¡¿¡¼­ ÆÄÀÏ °íÄ¡±â"
-
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [¿¡·¯ÆÄÀÏ] ù ¹øÂ° ¿¡·¯°¡ ³­ ÆÄÀÏ °íÄ¡±â"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"»ç¿ë¹ý:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [ÀÎÀÚ] "
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" ȤÀº:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"ÀÎÀÚ:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tÀÌ µÚ¿¡´Â ÆÄÀÏ À̸§¸¸"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\t¿ÍÀϵåÄ«µå¸¦ È®ÀåÇÏÁö ¾ÊÀ½"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tVi »óÅ (\"vi\"¿Í °°À½)"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tEx »óÅ (\"ex\"¿Í °°À½)"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tÁ¶¿ëÇÑ (¹èÄ¡) »óÅ (\"ex\"¸¸)"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tDiff »óÅ (\"vimdiff\"¿Í °°À½)"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\t½¬¿î »óÅ (\"evim\"°ú °°À½, modeless)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tÀбâ Àü¿ë »óÅ (\"view\"¿Í °°À½)"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tÁ¦ÇÑµÈ »óÅ (\"rvim\"°ú °°À½)"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\t¼öÁ¤(ÆÄÀÏ ¾²±â)ÀÌ Çã¿ëµÇÁö ¾ÊÀ½"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tÅØ½ºÆ® ¼öÁ¤ÀÌ Çã¿ëµÇÁö ¾ÊÀ½"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tÀÌÁø »óÅÂ"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\t¸®½ºÇÁ »óÅÂ"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tVi ȣȯ: 'compatible'"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tVi¿Í ȣȯµÇÁö ¾ÊÀ½: 'nocompatible'"
-
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr ""
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tµð¹ö±ë »óÅÂ"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\t½º¿Ò ÆÄÀÏ ¾øÀÌ ¸Þ¸ð¸®¸¸ »ç¿ë"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\t½º¿Ò ÆÄÀÏ ¸ñ·ÏÀ» Ç¥½ÃÇÑ µÚ ³¡³»±â"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (ÆÄÀÏ À̸§°ú ÇÔ²²)\tÆÄ¼ÕµÇ¾ú´ø ¼¼¼Ç º¹±¸"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\t-r°ú °°À½"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tArabic ¸ðµå·Î ½ÃÀÛ"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tHebrew ¸ðµå·Î ½ÃÀÛ"
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tFarsi ¸ðµå·Î ½ÃÀÛ"
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminal>\tÅ͹̳ΠÁ¾·ù¸¦ <terminal>·Î ¼³Á¤"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\t.vimrc ´ë½Å <vimrc>¸¦ »ç¿ë"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tÇ÷¯±×ÀÎ ½ºÅ©¸³Æ®¸¦ ºÒ·¯µéÀÌÁö ¾ÊÀ½"
-
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tN°³ÀÇ ÅÇ ¿­±â (±âº»: ÆÄÀϺ°·Î Çϳª)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\tN°³ÀÇ Ã¢ ¿­±â (±âº»: ÆÄÀϺ°·Î Çϳª)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\t-o¿Í °°Áö¸¸ âÀ» ¼öÁ÷À¸·Î ³ª´©±â"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tÆÄÀÏ ¸¶Áö¸·¿¡¼­ ½ÃÀÛ"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\t<lnum> ÁÙ¿¡¼­ ½ÃÀÛ"
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <¸í·É>\tvimrc ÆÄÀÏÀ» Àбâ Àü¿¡ <¸í·É>À» ½ÇÇà"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <¸í·É>\t\tù° ÆÄÀÏÀ» ÀÐÀº µÚ <¸í·É>À» ½ÇÇà"
-
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <¼¼¼Ç>\t\tù° ÆÄÀÏÀ» ÀÐÀº µÚ <¼¼¼Ç> ÆÄÀÏ ºÒ·¯ µéÀ̱â"
-
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <scriptin>\t<scriptin> ÆÄÀÏ¿¡¼­ Normal »óÅ ¸í·É Àбâ"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <scriptout>\t¸ðµç ÀÔ·ÂµÈ ¸í·ÉÀ» <scriptout> ÆÄÀÏ¿¡ Ãß°¡"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <scriptout>\t¸ðµç ÀÔ·ÂµÈ ¸í·ÉÀ» <scriptout> ÆÄÀÏ¿¡ ÀúÀå"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr "--startuptime <file>\tstartup timing ¸Þ½ÃÁö¸¦ <file>¿¡ ÀúÀå"
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\t.viminfo ´ë½Å <viminfo>¸¦ »ç¿ë"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h ȤÀº --help\tµµ¿ò¸»(ÀÌ ¸Þ½ÃÁö)À» Ãâ·ÂÇÑ µÚ ³¡³»±â"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\tÆÇ Á¤º¸¸¦ Ãâ·ÂÇÑ µÚ ³¡³»±â"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "¼³Á¤µÈ ¸¶Å©°¡ ¾ø½À´Ï´Ù"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: \"%s\"¿¡ ¸Â´Â ¸¶Å©°¡ ¾ø½À´Ï´Ù"
-
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"¸¶Å© ¶óÀÎ col ÆÄÀÏ/ÅØ½ºÆ®"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-" Á¡ÇÁ ¶óÀÎ col ÆÄÀÏ/ÅØ½ºÆ®"
-
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# ÆÄÀÏ ¸¶Å©:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Á¡ÇÁ¸ñ·Ï (»õ°ÍÀÌ ¸ÕÀú):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# ÆÄÀϳ»ÀÇ ¸¶Å© È÷½ºÅ丮 (»õ°ÍºÎÅÍ ¿À·¡µÈ ¼ø):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "'>'ÀÌ ¾ø½À´Ï´Ù"
-
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: ±¸¿ªÀÌ Àá±ÅÁöÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: ½º¿Ò ÆÄÀÏÀ» Àбâ À§ÇØ Æ¯Á¤ À§Ä¡·Î °¥ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: ½º¿Ò ÆÄÀÏÀ» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: ½º¿Ò ÆÄÀÏÀ» ¾²±â À§ÇØ Æ¯Á¤ À§Ä¡·Î °¥ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: ½º¿Ò ÆÄÀÏÀ» ¾µ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: ½º¿Ò ÆÄÀÏÀÌ ÀÌ¹Ì Á¸ÀçÇÕ´Ï´Ù (symlink °ø°Ý?)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: ±¸¿ª ¹øÈ£ 0À» ¾òÁö ¸øÇß³ª¿ä?"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: ±¸¿ª ¹øÈ£ 1À» ¾òÁö ¸øÇß³ª¿ä?"
-
-#: ../memline.c:377
-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
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: À¸À¹, ½º¿Ò ÆÄÀÏÀ» ÀÒ¾î¹ö·È½À´Ï´Ù!!!"
-
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: ½º¿Ò ÆÄÀÏ À̸§À» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr "E303: \"%s\"ÀÇ ½º¿Ò ÆÄÀÏÀ» ¿­ ¼ö ¾ø¾î¼­ º¹±¸´Â ºÒ°¡´ÉÇÕ´Ï´Ù"
-
-#: ../memline.c:666
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_upd_block0(): ±¸¿ª 0À» ¾òÁö ¸øÇß³ª¿ä??"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: %sÀÇ ½º¿Ò ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr "»ç¿ëÇÒ ½º¿Ò ÆÄÀÏ ¹øÈ£¸¦ ÀÔ·ÂÇϽʽÿÀ (0Àº ³¡³»±â): "
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: %sÀ»(¸¦) ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "Unable to read block 0 from "
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"¾î¶² ¼öÁ¤µµ ¾ø¾ú°Å³ª ºöÀÌ ½º¿Ò ÆÄÀÏÀ» °»½ÅÇÏÁö ¾ÊÀº °Í °°½À´Ï´Ù."
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " cannot be used with this version of Vim.\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "ºö 3.0 ÆÇÀ» »ç¿ëÇϽʽÿÀ.\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %sÀº(´Â) ºö ½º¿Ò ÆÄÀÏÀÌ ¾Æ´Ñ °Í °°½À´Ï´Ù"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " ÀÌ ÄÄÇ»ÅÍ¿¡¼­´Â »ç¿ëµÉ ¼ö ¾ø½À´Ï´Ù.\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr ""
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr ""
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "½º¿Ò ÆÄÀÏ \"%s\"À»(¸¦) »ç¿ëÇÕ´Ï´Ù"
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "¿ø·¡ ÆÄÀÏ \"%s\""
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: °æ°í: ¿ø·¡ ÆÄÀÏÀÌ ¹Ù²î¾ú½À´Ï´Ù"
-
-#: ../memline.c:1061
-#, c-format
-msgid "E309: Unable to read block 1 from %s"
-msgstr "E309: %sÀÇ ±¸¿ª 1À» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memline.c:1065
-msgid "???MANY LINES MISSING"
-msgstr "???¸¹Àº ÁÙÀ» ÀÒ¾î¹ö¸²"
-
-#: ../memline.c:1076
-msgid "???LINE COUNT WRONG"
-msgstr "???ÁÙ ¹øÈ£°¡ À߸øµÇ¾ú½À´Ï´Ù"
-
-#: ../memline.c:1082
-msgid "???EMPTY BLOCK"
-msgstr "???ºó ±¸¿ª"
-
-#: ../memline.c:1103
-msgid "???LINES MISSING"
-msgstr "???ÁÙÀ» ÀÒ¾î¹ö¸²"
-
-#: ../memline.c:1128
-#, c-format
-msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: ±¸¿ª 1ÀÇ ID°¡ À߸øµÇ¾ú½À´Ï´Ù (%sÀÌ(°¡) .swp ÆÄÀÏÀÌ ¾Æ´Ñ°¡?)"
-
-#: ../memline.c:1133
-msgid "???BLOCK MISSING"
-msgstr "???±¸¿ª ÀÒ¾î¹ö¸²"
-
-#: ../memline.c:1147
-msgid "??? from here until ???END lines may be messed up"
-msgstr "??? ¿©±âºÎÅÍ ???³¡±îÁöÀÇ ÁÙÀÌ ¼¯¿´½À´Ï´Ù"
-
-#: ../memline.c:1164
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? ¿©±âºÎÅÍ ???³¡±îÁöÀÇ ÁÙÀÌ ³¢¿öÁö°Å³ª Áö¿öÁ® ¹ö¸° °Í °°½À´Ï´Ù"
-
-#: ../memline.c:1181
-msgid "???END"
-msgstr "???³¡"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: º¹±¸ ÁߴܵǾú½À´Ï´Ù"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr "E312: º¹±¸ µµÁß ¿¡·¯ »ý°å½À´Ï´Ù; ???·Î ½ÃÀÛÇÏ´Â ÁÙÀ» ã¾Æº¸½Ê½Ã¿À"
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "´õ ¸¹Àº Á¤º¸¸¦ º¸·Á¸é \":help E312\"¸¦ ÀÔ·ÂÇϼ¼¿ä."
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr "º¹±¸°¡ ³¡³µ½À´Ï´Ù. ¸ðµç °Ô Á¤»óÀÎ Áö È®ÀÎÇØ º¸¼Å¾ß¸¸ ÇÕ´Ï´Ù."
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(¾î¼¸é ´Ù¸¥ À̸§À¸·Î ÀúÀåÇÏ°í ½ÍÀ¸½Ç Áöµµ ¸ð¸£°Ú½À´Ï´Ù\n"
-
-#: ../memline.c:1252
-msgid "and run diff with the original file to check for changes)"
-msgstr "±×¸®°í ¹Ù²ï ³»¿ëÀ» È®ÀÎÇÏ·Á¸é ¿ø·¡ ÆÄÀÏ¿¡ ´ëÇØ diff¸¦ ½ÇÇàÇϼ¼¿ä)"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr "º¹±¸°¡ ³¡³µ½À´Ï´Ù. ¹öÆÛÀÇ ³»¿ëÀÌ ÆÄÀÏ ³»¿ë°ú °°½À´Ï´Ù."
-
-#: ../memline.c:1255
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"\n"
-"ÀÌÁ¦ .swp ÆÄÀÏÀ» Áö¿ì¼Åµµ µË´Ï´Ù.\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "½º¿Ò ÆÄÀÏÀ» ã¾ÒÀ½:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr " ÇöÀç µð·ºÅ丮¿¡:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " ¸í½ÃµÈ À̸§À» »ç¿ë:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " In directory "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- ¾øÀ½ --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " ¼ÒÀ¯ÀÚ: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " ³¯Â¥: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " ³¯Â¥: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [ºö 3.0 ÆÇÀÇ °Í]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [ºö ½º¿Ò ÆÄÀÏ·Î º¸ÀÌÁö ¾Ê½À´Ï´Ù]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " ÆÄÀÏ À̸§: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" ¼öÁ¤: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "¿¹"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "¾Æ´Ï¿À"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" »ç¿ëÀÚ À̸§: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " È£½ºÆ® À̸§: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" È£½ºÆ® À̸§: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" ÇÁ·Î¼¼½º ID: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (¾ÆÁ÷ ½ÇÇàÁß)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [ÀÌ ÄÄÇ»ÅÍ¿¡¼­´Â »ç¿ëÇÒ ¼ö ¾øÀ½]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [ÀÐÀ» ¼ö ¾øÀ½]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [¿­ ¼ö ¾øÀ½]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: º¸Á¸ÇÒ ¼ö ¾ø½À´Ï´Ù, ½º¿Ò ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
-
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "ÆÄÀÏÀÌ º¸Á¸µÇ¾ú½À´Ï´Ù"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: ÆÄÀÏ º¸Á¸À» ½ÇÆÐÇß½À´Ï´Ù"
-
-#: ../memline.c:1819
-#, 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>"
-msgstr "E316: ml_get: %<PRId64> ÁÙÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: À߸øµÈ Æ÷ÀÎÅÍ ±¸¿ª id 3"
-
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "stack_idx´Â 0¿©¾ß¸¸ ÇÕ´Ï´Ù"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: ³Ê¹« ¸¹Àº ±¸¿ªÀÌ °»½ÅµÇ¾ú³ª¿ä?"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: À߸øµÈ Æ÷ÀÎÅÍ ±¸¿ª id 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "±¸¿ª 1ÀÌ Áö¿öÁ³³ª¿ä?"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: %<PRId64> ÁÙÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: À߸øµÈ Æ÷ÀÎÅÍ ±¸¿ª id"
-
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "pe_line_count°¡ 0ÀÔ´Ï´Ù"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: ÁÙ ¹øÈ£°¡ ¹üÀ§¸¦ ¹þ¾î³µ½À´Ï´Ù: ¸¶Áö¸·¿¡¼­ %<PRId64> ¸¸Å­"
-
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ±¸¿ª %<PRId64>ÀÇ ÁÙ °¹¼ö°¡ Ʋ·È½À´Ï´Ù"
-
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "½ºÅà ũ±â Áõ°¡"
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: À߸øµÈ Æ÷ÀÎÅÍ ±¸¿ª id 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr ""
-
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: ÁÖ¸ñ"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"Found a swap file by the name \""
-
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "While opening file \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " NEWER than swap file!\n"
-
-#: ../memline.c:3244
-#, fuzzy
-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."
-msgstr ""
-"\n"
-"(1) ´Ù¸¥ ÇÁ·Î±×·¥ÀÌ °°Àº ÆÄÀÏÀ» °íÄ¡°í ÀÖ´ÂÁßÀÏ ¼ö ÀÖ½À´Ï´Ù.\n"
-" ¸¸¾à ±×·¸´Ù¸é °°Àº ÆÄÀÏÀ» µÎ °³ÀÇ ÇÁ·Î±×·¥¿¡¼­ °íÄ¡Áö\n"
-" ¾Êµµ·Ï Á¶½ÉÇϽñ⠹ٶø´Ï´Ù.\n"
-
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " ³¡³»°Å³ª À§ÇèÀ» °¨¼öÇϽ÷Á¸é °è¼ÓÇϽʽÿÀ.\n"
-
-#: ../memline.c:3246
-#, fuzzy
-msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) ÆÄÀÏÀ» °íÄ¡´Ù°¡ Á×¾ú¾ú½À´Ï´Ù.\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " ¸¸¾à ±×·¸´Ù¸é \":recover\" ȤÀº \"vim -r "
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"\"\n"
-" À» »ç¿ëÇÏ¿© º¹±¸ÇϽʽÿÀ (\":help recovery\" Âü°í).\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " ÀÌ¹Ì º¹±¸Çϼ̾ú´Ù¸é ½º¿ÒÆÄÀÏ \""
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"\"\n"
-" À»(¸¦) Áö¿ì¼Å¾ß ÀÌ ¸Þ½ÃÁö°¡ »ç¶óÁý´Ï´Ù.\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "½º¿Ò ÆÄÀÏ \""
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "\"ÀÌ ÀÌ¹Ì Á¸ÀçÇÕ´Ï´Ù!"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "ºö - ÁÖ¸ñ"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "½º¿Ò ÆÄÀÏÀÌ ÀÌ¹Ì Á¸ÀçÇÕ´Ï´Ù!"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"Àбâ Àü¿ëÀ¸·Î ¿­±â(&O)\n"
-"±×³É °íÄ¡±â(&E)\n"
-"º¹±¸(&R)\n"
-"³¡³»±â(&Q)\n"
-"¹ö¸®±â(&A)"
-
-#: ../memline.c:3467
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"Àбâ Àü¿ëÀ¸·Î ¿­±â(&O)\n"
-"¹«Á¶°Ç ÆíÁý(&E)\n"
-"º¹±¸(&R)\n"
-"»èÁ¦(&D)\n"
-"³¡³»±â(&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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
-msgid "E326: Too many swap files found"
-msgstr "E326: ³Ê¹« ¸¹Àº ½º¿Ò ÆÄÀÏÀÌ ¹ß°ßµÇ¾ú½À´Ï´Ù"
-
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: ¸Þ¸ð¸® ºÎÁ·! (%<PRIu64> ¹ÙÀÌÆ®¸¦ ÇÒ´ç)"
-
-#: ../menu.c:62
-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
-#, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: \"%s\" ¸Þ´º ¾øÀ½"
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-msgid "E792: Empty menu name"
-msgstr "E792: ¸Þ´º À̸§ ¾øÀ½"
-
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: ÇÏÀ§ ¸Þ´º ¾Õ¿¡´Â ¸Þ´º °æ·Î°¡ ºÙÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: ¸Þ´º¹Ù¿¡ °ð¹Ù·Î ¸Þ´º Ç׸ñÀ» ´õÇÒ ¼ö´Â ¾ø½À´Ï´Ù"
-
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: ±¸ºÐÀÚ´Â ¸Þ´º °æ·ÎÀÇ ºÎºÐÀÌ µÉ ¼ö ¾ø½À´Ï´Ù"
-
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- ¸Þ´º ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: ¸Þ´º Ç׸ñ ¾Õ¿¡´Â ¸Þ´º °æ·Î°¡ ÀÖ¾î¾ß ÇÕ´Ï´Ù"
-
-#: ../menu.c:1330
-#, 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
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: ÇÏÀ§ ¸Þ´º ¾Õ¿¡ ¸Þ´º °æ·Î°¡ ÀÖ¾î¾ß ÇÕ´Ï´Ù"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: ¸Þ´º¸¦ ãÀ» ¼ö ¾øÀ½ - ¸Þ´º À̸§À» È®ÀÎÇϽʽÿÀ"
-
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "%s ¼öÇàÁß ¿¡·¯ ¹ß°ß:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "%4ld ÁÙ:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: À߸øµÈ ·¹Áö½ºÅÍ À̸§: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "¸Þ½ÃÁö °ü¸®ÀÚ: Bram Moolenaar <Bram@vim.org>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "Áß´Ü: "
-
-#: ../message.c:988
-msgid "Press ENTER or type command to continue"
-msgstr "°è¼ÓÇÏ·Á¸é ¿£ÅÍ È¤Àº ¸í·ÉÀ» ÀÔ·ÂÇϽʽÿÀ"
-
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s ÁÙ %<PRId64>"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- ´õ --"
-
-#: ../message.c:2398
-msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr " SPACE/d/j: È­¸é/ÆäÀÌÁö/¶óÀÎ ¾Æ·¡·Î, b/u/k: À§·Î, q: Á¾·á "
-
-#: ../message.c:3021 ../message.c:3031
-msgid "Question"
-msgstr "Áú¹®"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"¿¹(&Y)\n"
-"¾Æ´Ï¿À(&N)"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"¿¹(&Y)\n"
-"¾Æ´Ï¿À(&N)\n"
-"Ãë¼Ò(&C)"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"¿¹(&Y)\n"
-"¾Æ´Ï¿À(&N)\n"
-"¸ðµÎ ÀúÀå(&A)\n"
-"¸ðµÎ ¹ö¸²(&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()¿¡ ¿¹»ó¸øÇÑ Float ÀÎÀÚ"
-
-#: ../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
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr "¼ýÀÚ ÀÔ·ÂÈÄ <¿£ÅÍ>³ª ¸¶¿ì½º Ŭ¸¯ (¼ýÀÚ¾øÀ¸¸é Ãë¼Ò): "
-
-#: ../misc1.c:2539
-msgid "Type number and <Enter> (empty cancels): "
-msgstr "¼ýÀÚ ÀÔ·ÂÈÄ <¿£ÅÍ> (¼ýÀÚ¾øÀ¸¸é Ãë¼Ò): "
-
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "ÇÑ ÁÙ ÀÌ»ó"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "ÇÑ ÁÙ ÀÌÇÏ"
-
-#: ../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 "Ȉ!"
-
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "½ÇÇàÇÏ·Á°í ½© ºÎ¸§: \"%s\""
-
-#: ../normal.c:183
-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
-msgid "E348: No string under cursor"
-msgstr "E348: Ä¿¼­ ¹Ø¿¡ ¹®ÀÚ¿­ÀÌ ¾ø½À´Ï´Ù"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: ÇöÀçÀÇ 'foldmethod'À¸·Î Á¢±â¸¦ Áö¿ï ¼ö ¾ø½À´Ï´Ù"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: changelist°¡ ºñ¾ú½À´Ï´Ù"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr ""
-
-#: ../normal.c:5901
-msgid "E663: At end of changelist"
-msgstr ""
-
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "VIMÀ» ¸¶Ä¡·Á¸é :quit<Enter> ÀÔ·Â"
-
-#: ../ops.c:248
-#, c-format
-msgid "1 line %sed 1 time"
-msgstr "1 line %sed 1 time"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 line %sed %d times"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> lines %sed 1 time"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> lines %sed %d times"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> lines to indent... "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "1 line indented "
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> lines indented "
-
-#: ../ops.c:938
-msgid "E748: No previously used register"
-msgstr ""
-
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "cannot yank; delete anyway"
-
-#: ../ops.c:1929
-msgid "1 line changed"
-msgstr "1 line changed"
-
-#: ../ops.c:1931
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> lines changed"
-
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "block of 1 line yanked"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "1 line yanked"
-
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "block of %<PRId64> lines yanked"
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> lines yanked"
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353: %s ·¹Áö½ºÅÍ¿¡ ¾Æ¹« °Íµµ ¾ø½À´Ï´Ù"
-
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- ·¹Áö½ºÅÍ ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "ÀÌ»óÇÑ ·¹Áö½ºÅÍ À̸§"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# ·¹Áö½ºÅÍ:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: ¸ð¸£´Â ·¹Áö½ºÅÍ Çü½Ä %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> ¿­; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Selected %s%<PRId64> of %<PRId64> ¶óÀÎ; %<PRId64> of %<PRId64> ´Ü¾î; "
-"%<PRId64> of %<PRId64> ¹ÙÀÌÆ®"
-
-#: ../ops.c:5105
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Selected %s%<PRId64> of %<PRId64> ¶óÀÎ; %<PRId64> of %<PRId64> ´Ü¾î; "
-"%<PRId64> of %<PRId64> ¹®ÀÚ; %<PRId64> of %<PRId64> ¹ÙÀÌÆ®"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Col %s of %s; ¶óÀÎ %<PRId64> of %<PRId64>; ´Ü¾î %<PRId64> of %<PRId64>; ¹ÙÀÌ"
-"Æ® %<PRId64> of %<PRId64>"
-
-#: ../ops.c:5133
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"Col %s of %s; ¶óÀÎ %<PRId64> of %<PRId64>; ´Ü¾î %<PRId64> of %<PRId64>; ¹®ÀÚ "
-"%<PRId64> of %<PRId64>; ¹ÙÀÌÆ® %<PRId64> of %<PRId64>"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> for BOM)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=ÆäÀÌÁö %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "ºöÀ» ³¯°Ô ÇØ Áּż­ °í¸¿½À´Ï´Ù"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: ¸ð¸£´Â ¿É¼Ç"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: Áö¿øµÇÁö ¾Ê´Â ¿É¼ÇÀÔ´Ï´Ù"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: ¸ðµå¶óÀο¡¼­ »ç¿ëµÉ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr ""
-
-#: ../option.c:2924
-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
-msgid "E590: A preview window already exists"
-msgstr "E590: ¹Ì¸® º¸±â âÀÌ ÀÌ¹Ì Á¸ÀçÇÕ´Ï´Ù"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: ArabicÀº UTF-8 ÀÎÄÚµù ÇÊ¿ä, ':set encoding=utf-8' Çϼ¼¿ä"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: Àû¾îµµ %d ÁÙÀÌ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: Àû¾îµµ %d Ä­ÀÌ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../option.c:6011
-#, 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
-#, c-format
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: ¼ýÀÚ°¡ ÇÊ¿ä: &%s = '%s'"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- Å͹̳ΠÄÚµå ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- Àü¿ª ¿É¼Ç °ª ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- Áö¿ª ¿É¼Ç °ª ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- ¿É¼Ç ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: get_varp ¿¡·¯"
-
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': %s¿¡ ´ëÇÑ ¸Â´Â ±ÛÀÚ°¡ ¾ø½À´Ï´Ù"
-
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': ¼¼¹ÌÄÝ·Ð µÚ¿¡ ±ÛÀÚ°¡ ´õ ÀÖÀ½: %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Cannot execute shell "
-
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"shell returned "
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-"\n"
-"Could not get security context for "
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-"\n"
-"Could not set security context for "
-
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = \"%s\""
-
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: path¿¡¼­ \"%s\" ÆÄÀÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: Çü½Ä ¹®ÀÚ¿­¿¡ %%%cÀÌ(°¡) ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: Çü½Ä ¹®ÀÚ¿­¿¡ %%%cÀÌ(°¡) À߸øµÇ¾ú½À´Ï´Ù"
-
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: Çü½Ä ¹®ÀÚ¿­¿¡ ]°¡ ¾ø½À´Ï´Ù"
-
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: Çü½Ä ¹®ÀÚ¿­¿¡ Áö¿øµÇÁö ¾Ê´Â %%%cÀÌ(°¡) ÀÖ½À´Ï´Ù"
-
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: Çü½Ä ¹®ÀÚ¿­ ¼­µÎ¿¡ À߸øµÈ %%%cÀÌ(°¡) ÀÖ½À´Ï´Ù"
-
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: Çü½Ä ¹®ÀÚ¿­¿¡ À߸øµÈ %%%cÀÌ(°¡) ÀÖ½À´Ï´Ù"
-
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: 'errorformat'ÀÌ ¾î¶² ÆÐÅϵµ Æ÷ÇÔÇϰí ÀÖÁö ¾Ê½À´Ï´Ù"
-
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: ºüÁ³°Å³ª ºó µð·ºÅ丮 À̸§"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: ´õ ÀÌ»óÀÇ Ç׸ñÀÌ ¾ø½À´Ï´Ù"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d of %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (ÁÙÀ» Áö¿üÀ½)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: ÄüÇȽº ½ºÅÃÀÇ ¹Ù´ÚÀÔ´Ï´Ù"
-
-#: ../quickfix.c:1869
-msgid "E381: At top of quickfix stack"
-msgstr "E381: ÄüÇȽº ½ºÅÃÀÇ ²À´ë±âÀÔ´Ï´Ù"
-
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "error list %d of %d; %d errors"
-
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: ¾µ ¼ö ¾øÀ½, 'buftype' ¿É¼ÇÀÌ ¼³Á¤µÇ¾î ÀÖ½À´Ï´Ù"
-
-#: ../quickfix.c:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr "E683: ÆÄÀÏ¸í ´©¶ô ȤÀº À߸øµÈ ÆÐÅÏ"
-
-#: ../quickfix.c:2911
-#, c-format
-msgid "Cannot open file \"%s\""
-msgstr "\"%s\" ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../quickfix.c:3429
-msgid "E681: Buffer is not loaded"
-msgstr "E681: ¹öÆÛ°¡ ·ÎµåµÇÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#: ../quickfix.c:3487
-msgid "E777: String or List expected"
-msgstr "E777: StringÀ̳ª List°¡ ÀÖ¾î¾ß ÇÔ"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: %s%%[]¿¡ À߸øµÈ Ç׸ñ"
-
-#: ../regexp.c:374
-#, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E769: %s[ µÚ¿¡ ]°¡ ¾ø½À´Ï´Ù"
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: ¸ÂÁö ¾Ê´Â %s%%("
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: ¸ÂÁö ¾Ê´Â %s("
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: ¸ÂÁö ¾Ê´Â %s)"
-
-#: ../regexp.c:378
-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:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: %s%%[ µÚ¿¡ ]°¡ ¾ø½À´Ï´Ù"
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: ºó %s%%[]"
-
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: ÆÐÅÏÀÌ ³Ê¹« ±é´Ï´Ù"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: \\z(°¡ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: %s(°¡ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: ¸ÂÁö ¾Ê´Â \\z("
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: %s@ µÚ¿¡ À߸øµÈ ¹®ÀÚ"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: %s{...}s°¡ ³Ê¹« ¸¹À½"
-
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: Nested %s*"
-
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: Nested %s%c"
-
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: \\_¸¦ Àß ¸ø »ç¿ë"
-
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c µÚ¿¡ ¾Æ¹«°Íµµ ¾ø½À´Ï´Ù"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: ÀÌ»óÇÑ ÈÄÀ§ ÂüÁ¶"
-
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: \\z µÚ¿¡ ÀÌ»óÇÑ ¹®ÀÚ"
-
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: %s%%[dxouU] µÚ¿¡ ÀÌ»óÇÑ ¹®ÀÚ"
-
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: %s%% µÚ¿¡ ÀÌ»óÇÑ ¹®ÀÚ"
-
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: %s{...}¿¡ ±¸¹® ¿¡·¯"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "¿ÜºÎ submatches:\n"
-
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr ""
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-
-#. 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 ""
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
-
-#: ../regexp_nfa.c:2042
-#, fuzzy
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: \\z(°¡ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr ""
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
-
-#: ../regexp_nfa.c:6049
-#, fuzzy
-msgid "Could not open temporary log file for writing "
-msgstr "E828: ¾²±â À§ÇØ undoÀ» ¿­ ¼ö ¾ø½À´Ï´Ù: %s"
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " ¼±ÅÃġȯ"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " ¹Ù²Ù±â"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " ¹Ý´ë"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " ³¢¿ö³Ö±â"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (³¢¿ö³Ö±â)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (¹Ù²Ù±â)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (¼±ÅÃġȯ)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " Çìºê·ç"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " ¾Æ¶óºñ¾Æ"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (¾ð¾î)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (ºÙÀ̱â)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " ºñÁÖ¾ó"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " ºñÁÖ¾ó ¶óÀÎ"
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " ºñÁÖ¾ó ºí·Ï"
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " °í¸£±â"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " ¶óÀÎ °í¸£±â"
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " ºí·Ï °í¸£±â"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "±â·ÏÁß"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: À߸øµÈ ã±â ¹®ÀÚ¿­: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: óÀ½±îÁö ¸Â´Â ¹®ÀÚ¿­ÀÌ ¾ø½À´Ï´Ù: %s"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: ³¡±îÁö ¸Â´Â ¹®ÀÚ¿­ÀÌ ¾ø½À´Ï´Ù: %s"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: ';' µÚ¿¡´Â '?'³ª '/'°¡ ¿Í¾ß ÇÕ´Ï´Ù"
-
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (ÀÌÀü¿¡ ¸Â¾Ò´ø ¸ñ·Ï Æ÷ÇÔ)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- Included files "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "not found "
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "in path ---\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (Already listed)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " ¸ø ã¾ÒÀ½"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "Æ÷ÇÔµÈ ÆÄÀÏ Ã£´Â Áß: %s"
-
-#: ../search.c:4216
-#, c-format
-msgid "Searching included file %s"
-msgstr "Æ÷ÇÔµÈ ÆÄÀÏ %s ã´Â Áß"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: ¸Â´Â °Ô ÇöÀç ÁÙ¿¡ ÀÖ½À´Ï´Ù"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "¸ðµç Æ÷ÇÔµÈ ÆÄÀÏÀ» ã¾Ò½À´Ï´Ù"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "Æ÷ÇÔµÈ ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: Á¤ÀǸ¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: ÆÐÅÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Substitute "
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: spell ÆÄÀÏ Çü½Ä ¿¡·¯"
-
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr "E758: À߸° spell ÆÄÀÏ"
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr "Trailing text in %s line %d: %s"
-
-#: ../spell.c:954
-#, c-format
-msgid "Affix name too long in %s line %d: %s"
-msgstr "Affix name too long in %s line %d: %s"
-
-#: ../spell.c:955
-msgid "E761: Format error in affix file FOL, LOW or UPP"
-msgstr "E761: affix ÆÄÀÏ 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
-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\" ȤÀº \"%s.ascii.spl\"À» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../spell.c:2473
-#, c-format
-msgid "Reading spell file \"%s\""
-msgstr "spell ÆÄÀÏ \"%s\"À»(¸¦) Àаí ÀÖ½À´Ï´Ù"
-
-#: ../spell.c:2496
-msgid "E757: This does not look like a spell file"
-msgstr "E757: spell ÆÄÀÏÀÌ ¾Æ´Ñ °Í °°½À´Ï´Ù"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: ¿À·¡µÈ spell ÆÄÀÏ, °»½ÅÀÌ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr "E772: Spell ÆÄÀÏÀÌ »õ ¹öÁ¯ÀÇ Vim¿ëÀÔ´Ï´Ù"
-
-#: ../spell.c:2602
-msgid "E770: Unsupported section in spell file"
-msgstr "E770: spell ÆÄÀÏ¿¡ Áö¿øµÇÁö ¾Ê´Â ¼½¼Ç"
-
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "°æ°í: %s ¿µ¿ªÀº Áö¿øµÇÁö ¾Ê½À´Ï´Ù"
-
-#: ../spell.c:4550
-#, c-format
-msgid "Reading affix file %s ..."
-msgstr "affix ÆÄÀÏ %s Àд Áß"
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ ÀÖ´Â ´Ü¾î º¯È¯ ½ÇÆÐ: %s"
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr "%sÀÇ º¯È¯ÀÌ Áö¿øµÇÁö ¾Ê½À´Ï´Ù: %s¿¡¼­ %s·Î"
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ FLAG¿¡ ´ëÇÑ À߸øµÈ °ª: %s"
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ Ç÷¡±×°¡ »ç¿ëµÈ ÈÄ FLAG: %s"
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"%s ¶óÀÎ %d¿¡ PFX µÚ¿¡ COMPOUNDFORBIDFLAGÀ» Á¤ÀÇÇÑ °ÍÀº À߸øµÈ °á°ú¸¦ ÃÊ·¡ÇÒ "
-"¼ö ÀÖ½À´Ï´Ù"
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"%s ¶óÀÎ %d¿¡ PFX µÚ¿¡ COMPOUNDPERMITFLAGÀ» Á¤ÀÇÇÑ °ÍÀº À߸øµÈ °á°ú¸¦ ÃÊ·¡ÇÒ "
-"¼ö ÀÖ½À´Ï´Ù"
-
-#: ../spell.c:4747
-#, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ COMPOUNDRULES °ª: %s"
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ COMPOUNDWORDMAX °ª: %s"
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ COMPOUNDMIN °ª: %s"
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ COMPOUNDSYLMAX °ª: %s"
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ CHECKCOMPOUNDPATTERN °ª: %s"
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ ¿¬¼ÓµÈ affix ºí·Ï¿¡ ´Ù¸¥ °áÇÕ Ç÷¡±×: %s"
-
-#: ../spell.c:4850
-#, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ Áߺ¹µÈ affix: %s"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-"%s ¶óÀÎ %d¿¡ BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST¿¡ ´ëÇØ¼­µµ "
-"affix°¡ »ç¿ëµÊ: %s"
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ Y³ª NÀÌ ±â´ëµÊ: %s"
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d°¡ ¸Á°¡Áø »óÅÂ: %s"
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr "%s ¶óÀÎ %d¿¡ REP(SAL) Ä«¿îÆ®°¡ ±â´ëµÊ"
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr "%s ¶óÀÎ %d¿¡ MAP Ä«¿îÆ®°¡ ±â´ëµÊ"
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr "%s ¶óÀÎ %dÀÇ MAP¿¡ Áߺ¹µÈ ¹®ÀÚ"
-
-#: ../spell.c:5176
-#, 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
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr "COMPOUNDSYLMAXÀÌ SYLLABLE¾øÀÌ »ç¿ëµÊ"
-
-#: ../spell.c:5236
-msgid "Too many postponed prefixes"
-msgstr "postponed Á¢µÎ»ç°¡ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../spell.c:5238
-msgid "Too many compound flags"
-msgstr "compound Ç÷¡±×°¡ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr "postponed Á¢µÎ»ç¿Í(³ª) compound Ç÷¡±×°¡ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr "SOFO%s°¡ ´©¶ôµÈ ¶óÀÎÀÌ %s¿¡ ÀÖ½À´Ï´Ù"
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr "%s¿¡ SAL°ú SOFO ¶óÀÎÀÌ µÑ ´Ù ÀÖ½À´Ï´Ù"
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ ¼ýÀÚ°¡ ¾Æ´Ñ Ç÷¡±×: %s"
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ Ç÷¡±×: %s"
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr "%s °ªÀÌ ´Ù¸¥ .aff ÆÄÀÏ¿¡¼­ »ç¿ëµÈ °Í°ú ´Ù¸¨´Ï´Ù"
-
-#: ../spell.c:5602
-#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "»çÀü ÆÄÀÏ %s Àд Áß ..."
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr "E760: %s¿¡ ´Ü¾î Ä«¿îÆ®°¡ ¾ø½À´Ï´Ù"
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "¶óÀÎ %6d, ´Ü¾î %6d - %s"
-
-#: ../spell.c:5691
-#, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ Áߺ¹µÈ ´Ü¾î: %s"
-
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ óÀ½ Áߺ¹µÈ ´Ü¾î: %s"
-
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr "%d°³ÀÇ Áߺ¹µÈ ´Ü¾î°¡ %s¿¡ ÀÖ½À´Ï´Ù"
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr "¹«½ÃµÈ %d°³ÀÇ ¾Æ½ºÅ°¹®ÀÚ¿­ÀÌ ¾Æ´Ñ ´Ü¾î°¡ %s¿¡ ÀÖ½À´Ï´Ù"
-
-#: ../spell.c:6115
-#, c-format
-msgid "Reading word file %s ..."
-msgstr "´Ü¾î ÆÄÀÏ %s Àд Áß ..."
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "%s ¶óÀÎ %dÀÇ Áߺ¹µÈ /encoding= ¶óÀÎ ¹«½ÃµÊ: %s"
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "%s ¶óÀÎ %dÀÇ ´Ü¾î µÚÀÇ /encoding= ¶óÀÎ ¹«½ÃµÊ: %s"
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "%s ¶óÀÎ %dÀÇ Áߺ¹µÈ /regions= ¶óÀÎ ¹«½ÃµÊ: %s"
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ ³Ê¹« ¸¹Àº ¿µ¿ª: %s"
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "%s ¶óÀÎ %dÀÇ / ¶óÀÎ ¹«½ÃµÊ: %s"
-
-#: ../spell.c:6224
-#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ À߸øµÈ ¿µ¿ª ¹øÈ£: %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "%s ¶óÀÎ %d¿¡ ¸ð¸£´Â Ç÷¡±×: %s"
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr "¾Æ½ºÅ° ¹®ÀÚ¿­ÀÌ ¾Æ´Ñ %d°³ÀÇ ´Ü¾î°¡ ¹«½ÃµÇ¾ú½À´Ï´Ù"
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "%d/%d ³ëµå°¡ ¾ÐÃàµÊ; %d (%d%%)°¡ ³²À½"
-
-#: ../spell.c:7340
-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
-msgid "Performing soundfolding..."
-msgstr "soundfold ¼öÇàÁß..."
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "soundfold ¼öÇà ÈÄÀÇ ´Ü¾î ¼ö: %<PRId64>"
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr "ÃÑ ´Ü¾î ¼ö: %d"
-
-#: ../spell.c:7655
-#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "%s Á¦¾È ÆÄÀÏÀ» ¾²´Â Áß ..."
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr "ÃßÁ¤µÈ ·±Å¸ÀÓ ¸Þ¸ð¸® »ç¿ë·®: %d ¹ÙÀÌÆ®"
-
-#: ../spell.c:7820
-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°³ÀÇ ¿µ¿ªÀÌ Áö¿øµË´Ï´Ù"
-
-#: ../spell.c:7846
-#, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E755: %s¿¡ À߸øµÈ ¿µ¿ª"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr "°æ°í: compound¿Í NOBREAK µÑ ´Ù ¸í½ÃµÊ"
-
-#: ../spell.c:7920
-#, c-format
-msgid "Writing spell file %s ..."
-msgstr "spell ÆÄÀÏ %s ¾²´Â Áß ..."
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr "³¡!"
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile'¿¡ %<PRId64> Ç׸ñÀÌ ¾ø½À´Ï´Ù"
-
-#: ../spell.c:8074
-#, fuzzy, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "%s¿¡¼­ ´Ü¾î »èÁ¦µÊ"
-
-#: ../spell.c:8117
-#, fuzzy, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "%s¿¡ ´Ü¾î Ãß°¡µÊ"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: ´Ü¾î°¡ spell ÆÄÀÏ °£¿¡ ´Ù¸¨´Ï´Ù"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Á˼Û, Á¦¾ÈÇÒ °Ô ¾ø½À´Ï´Ù"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Á˼Û, %<PRId64>°³¸¸ Á¦¾È"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Change \"%.*s\" to:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: öÀÚ°¡ ¹Ù²ïÀûÀÌ ¾ø½À´Ï´Ù"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: ãÀ» ¼ö ¾øÀ½: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: .sug ÆÄÀÏÀÌ ¾Æ´Ñ °Í °°À½: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: ¿À·¡µÈ .sug ÆÄÀÏ, °»½Å ÇÊ¿ä: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: .sug ÆÄÀÏÀÌ »õ ¹öÁ¯ÀÇ Vim¿ëÀÓ: %s"
-
-#: ../spell.c:9295
-#, 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 ÆÄÀÏ Àб⠿¡·¯: %s"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: MAP Ç׸ñ¿¡ Áߺ¹µÈ ¹®ÀÚ"
-
-#: ../syntax.c:266
-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:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: ÀÌ·± ±¸¹® Ŭ·¯½ºÅÍ´Â ¾ø½À´Ï´Ù: %s"
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "C-Çü½Ä ÁÖ¼®¹®¿¡ µ¿±â¸ÂÃã"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "µ¿±â¸ÂÃã ¾øÀ½"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "syncing starts "
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr " lines before top line"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- Syntax sync Ç׸ñµé ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"syncing on items"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- Syntax Ç׸ñ ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: ÀÌ·± ±¸¹® Ŭ·¯½ºÅÍ´Â ¾ø½À´Ï´Ù: %s"
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "minimal "
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "maximal "
-
-#: ../syntax.c:3513
-msgid "; match "
-msgstr "; match "
-
-#: ../syntax.c:3515
-msgid " line breaks"
-msgstr " line breaks"
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: contains ÀÎÀÚ´Â ¿©±â¿¡ ¾µ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../syntax.c:4096
-msgid "E844: invalid cchar value"
-msgstr "E844: À߸øµÈ cchar °ª"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: group[t]here´Â ¿©±â¿¡¼­ »ç¿ëµÉ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: %s¿¡ ´ëÇÑ region Ç׸ñÀ» ãÁö ¸øÇß½À´Ï´Ù"
-
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: ÆÄÀÏÀ̸§ÀÌ ÇÊ¿äÇÕ´Ï´Ù"
-
-#: ../syntax.c:4221
-#, fuzzy
-msgid "E847: Too many syntax includes"
-msgstr "E77: ÆÄÀÏ À̸§ÀÌ ³Ê¹« ¸¹½À´Ï´Ù"
-
-#: ../syntax.c:4303
-#, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E789: ']' ´©¶ô: %s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: '=' ´©¶ô: %s"
-
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: ÃæºÐÄ¡ ¾ÊÀº ÀÎÀÚ: ±¸¹® ¿µ¿ª %s"
-
-#: ../syntax.c:4870
-#, fuzzy
-msgid "E848: Too many syntax clusters"
-msgstr "E391: ÀÌ·± ±¸¹® Ŭ·¯½ºÅÍ´Â ¾ø½À´Ï´Ù: %s"
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: Ŭ·¯½ºÅͰ¡ ¸í½ÃµÇÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: ÆÐÅÏ ±¸ºÐÀÚ¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: ÆÐÅÏ µÚ¿¡ ¾²·¹±â: %s"
-
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: syntax sync: ÁÙ ¿¬¼Ó ÆÐÅÏÀÌ µÎ ¹ø »ç¿ëµÇ¾ú½À´Ï´Ù"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: ºñÁ¤»óÀûÀÎ ÀÎÀÚ: %s"
-
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: ÀÌÄ÷ ±âÈ£°¡ ºüÁ³À½: %s"
-
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: ºó ÀÎÀÚ: %s"
-
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %sÀº(´Â) ¿©±â¿¡¼­ Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %sÀº(´Â) contains ¸ñ·ÏÀÇ Ã¹ ¹øÂ°¿©¾ß ÇÕ´Ï´Ù"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: ¸ð¸£´Â ±×·ì À̸§: %s"
-
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: À߸øµÈ :syntax ÇÏÀ§ ¸í·É: %s"
-
-#: ../syntax.c:5854
-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: ÇÏÀ̶óÀÌÆ® ±×·ìÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù: %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: groupÀÌ ¼³Á¤°ªÀÌ ÀÖ½À´Ï´Ù, 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: ¸ð¸£´Â FG »ö»ó"
-
-#: ../syntax.c:6504
-msgid "E420: BG color unknown"
-msgstr "E420: ¸ð¸£´Â BG »ö»ó"
-
-#: ../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: ±×·ì À̸§¿¡ Ãâ·ÂÇÒ ¼ö ¾ø´Â ¹®ÀÚ°¡ ÀÖ½À´Ï´Ù"
-
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: ±×·ì À̸§¿¡ ÀÌ»óÇÑ ¹®ÀÚ"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr ""
-
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: ÅÂ±× ½ºÅÃÀÇ ³¡ÀÔ´Ï´Ù"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: ÅÂ±× ½ºÅÃÀÇ Ã³À½ÀÔ´Ï´Ù"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: ù ¹øÂ° ¸Â´Â ÅÂ±× ÀÌÀüÀ¸·Î´Â °¥ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../tag.c:504
-#, c-format
-msgid "E426: tag not found: %s"
-msgstr "E426: ű׸¦ ãÀ» ¼ö ¾øÀ½: %s"
-
-#: ../tag.c:528
-msgid " # pri kind tag"
-msgstr " # pri kind tag"
-
-#: ../tag.c:531
-msgid "file\n"
-msgstr "ÆÄÀÏ\n"
-
-#: ../tag.c:829
-msgid "E427: There is only one matching tag"
-msgstr "E427: ¸Â´Â űװ¡ Çϳª ¹Û¿¡ ¾ø½À´Ï´Ù"
-
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: ¸¶Áö¸· ¸Â´Â ÅÂ±× µÚ·Î´Â °¥ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "ÆÄÀÏ \"%s\"ÀÌ(°¡) Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "tag %d of %d%s"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " or more"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " Using tag with different case!"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: ÆÄÀÏ \"%s\"ÀÌ(°¡) Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù"
-
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # TO tag FROM line in file/text"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "ÅÂ±× ÆÄÀÏ %s ã´Â Áß"
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr "ÅÂ±× ÆÄÀÏÀÇ ³Ê¹« ±ä ¶óÀÎÀ» ¹«½ÃÇÕ´Ï´Ù"
-
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: ÅÂ±× ÆÄÀÏ \"%s\"¿¡ Çü½Ä ¿¡·¯°¡ ÀÖ½À´Ï´Ù"
-
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Before byte %<PRId64>"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: ÅÂ±× ÆÄÀÏÀÌ Á¤·ÄµÇ¾î ÀÖÁö ¾ÊÀ½: %s"
-
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: ÅÂ±× ÆÄÀÏÀÌ ¾ø½À´Ï´Ù"
-
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: ÅÂ±× ÆÐÅÏÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: ű׸¦ ãÀ» ¼ö ¾øÁö¸¸ À̰а°½À´Ï´Ù!"
-
-#: ../tag.c:2797
-#, c-format
-msgid "Duplicate field name: %s"
-msgstr "Áߺ¹µÈ ÇÊµå ¸í: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' not known. Available builtin terminals are:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "defaulting to '"
-
-#: ../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¿¡¼­ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: termcap¿¡ \"%s\" Ç׸ñÀÌ ¾ø½À´Ï´Ù"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: Å͹̳ÎÀÌ \"cm\" ±â´ÉÀ» Áö¿øÇØ¾ß ÇÕ´Ï´Ù"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Å͹̳ΠŰ ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "ºö: ÀÔ·Â Àд Áß ¿¡·¯, ³¡³»´ÂÁß...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
-msgid "E881: Line count changed unexpectedly"
-msgstr "E834: ÁÙ °¹¼ö°¡ ¸ð¸£´Â »çÀÌ¿¡ ¹Ù²î¾ú½À´Ï´Ù"
-
-#: ../undo.c:627
-#, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E828: ¾²±â À§ÇØ undoÀ» ¿­ ¼ö ¾ø½À´Ï´Ù: %s"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr "E825: ±úÁø undo ÆÄÀÏ (%s): %s"
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr "'undodir'¿¡ ÀÖ´Â ¾î¶² µð·ºÅ丮¿¡µµ undo ÆÄÀÏÀ» ¾µ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr "ÀÐÀ» ¼ö°¡ ¾ø¾î¼­ undo ÆÄÀÏ¿¡ µ¤¾î¾µ ¼ö ¾ø½À´Ï´Ù: %s"
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr "undo ÆÄÀÏÀÌ ¾Æ´Ï¾î¼­ µ¤¾î¾µ ¼ö ¾ø½À´Ï´Ù: %s"
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr "undoÇÒ ³»¿ëÀÌ ¾ø¾î¼­ undo ÆÄÀÏ ÀúÀåÀ» °Ç³Ê¶Ý´Ï´Ù"
-
-#: ../undo.c:1121
-#, c-format
-msgid "Writing undo file: %s"
-msgstr "undo ÆÄÀÏ ¾²´Â Áß: %s"
-
-#: ../undo.c:1213
-#, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E829: undo ÆÄÀÏ ¾²±â ¿¡·¯: %s"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr "¼ÒÀ¯ÀÚ°¡ ´Þ¶ó¼­ undo ÆÄÀÏÀ» ÀÐÁö ¾Ê½À´Ï´Ù: %s"
-
-#: ../undo.c:1292
-#, c-format
-msgid "Reading undo file: %s"
-msgstr "undo ÆÄÀÏ Àд Áß: %s"
-
-#: ../undo.c:1299
-#, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E822: Àбâ À§ÇØ undo ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù: %s"
-
-#: ../undo.c:1308
-#, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E823: undo ÆÄÀÏÀÌ ¾Æ´Õ´Ï´Ù: %s"
-
-#: ../undo.c:1313
-#, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E824: ȣȯµÇÁö ¾Ê´Â undo ÆÄÀÏ: %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr "ÆÄÀÏ ³»¿ëÀÌ ¹Ù²î¾î¼­, undo Á¤º¸¸¦ »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../undo.c:1497
-#, c-format
-msgid "Finished reading undo file %s"
-msgstr "undo ÆÄÀÏ %sÀ»(¸¦) Àоîµé¿´½À´Ï´Ù"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr "´õ ÀÌ»óÀÇ ¼öÁ¤ÀÌ ¾ø¾ú½À´Ï´Ù"
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr "´õ ÀÌ»óÀÇ ¼öÁ¤Àº ¾ø¾ú½À´Ï´Ù"
-
-#: ../undo.c:1806
-#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Undo ¹øÈ£ %<PRId64>¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: À߸øµÈ ÁÙ ¹øÈ£"
-
-#: ../undo.c:2183
-msgid "more line"
-msgstr "more line"
-
-#: ../undo.c:2185
-msgid "more lines"
-msgstr "more lines"
-
-#: ../undo.c:2187
-msgid "line less"
-msgstr "line less"
-
-#: ../undo.c:2189
-msgid "fewer lines"
-msgstr "fewer lines"
-
-#: ../undo.c:2193
-msgid "change"
-msgstr "change"
-
-#: ../undo.c:2195
-msgid "changes"
-msgstr "changes"
-
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr "before"
-
-#: ../undo.c:2228
-msgid "after"
-msgstr "after"
-
-#: ../undo.c:2325
-msgid "Nothing to undo"
-msgstr "Ãë¼ÒÇÒ °Ô ¾ø½À´Ï´Ù"
-
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr ""
-
-#: ../undo.c:2360
-#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> seconds ago"
-
-#: ../undo.c:2372
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E790: undo µÚ¿¡ undojoinÀº ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: undo ¸ñ·ÏÀÌ ±úÁ³½À´Ï´Ù"
-
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: undo ÁÙÀÌ ¾ø½À´Ï´Ù"
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Æ÷ÇÔµÈ ÆÐÄ¡: "
-
-#: ../version.c:627
-msgid ""
-"\n"
-"Extra patches: "
-msgstr ""
-"\n"
-"º°µµÀÇ ÆÐÄ¡: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Modified by "
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"Compiled "
-
-#: ../version.c:649
-msgid "by "
-msgstr "by "
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"Huge ¹öÁ¯ "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "GUI ¾øÀ½."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " ±â´É (+: Æ÷ÇÔµÊ, -: Æ÷ÇÔ ¾È µÊ):\n"
-
-#: ../version.c:667
-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
-msgid " fall-back for $VIM: \""
-msgstr " fall-back for $VIM: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr " f-b for $VIMRUNTIME: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "ÄÄÆÄÀÏ: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "¸µÅ©: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " µð¹ö±× ºôµå"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "ºö - Çâ»óµÈ Vi"
-
-#: ../version.c:769
-msgid "version "
-msgstr "ÆÇ "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "by Bram Moolenaar et al."
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "ºöÀº ¼Ò½º°¡ ¿­·Á ÀÖ°í °øÂ¥·Î ¹èÆ÷µË´Ï´Ù"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "¿ì°£´Ù¿¡ »ç´Â °¡³­ÇÑ ¾ÆÀ̸¦ µµ¿ÍÁÖ¼¼¿ä!"
-
-#: ../version.c:777
-msgid "type :help iccf<Enter> for information "
-msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help iccf<¿£ÅÍ> ÀÔ·Â"
-
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr "³¡³»·Á¸é :q<¿£ÅÍ> ÀÔ·Â"
-
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "¿Â¶óÀÎ µµ¿ò¸»À» º¸·Á¸é :help<¿£ÅÍ> ¶Ç´Â <F1> ÀÔ·Â"
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "ÆÇ Á¤º¸¸¦ º¸·Á¸é :help version7<¿£ÅÍ> ÀÔ·Â"
-
-#: ../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<¿£ÅÍ> ÀÔ·Â"
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help cp-default<¿£ÅÍ> ÀÔ·Â"
-
-#: ../version.c:827
-msgid "Sponsor Vim development!"
-msgstr "ºö °³¹ßÀ» ÈÄ¿øÇØ ÁÖ¼¼¿ä!"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "ºö »ç¿ëÀÚ·Î µî·ÏÇϼ¼¿ä!"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help sponsor<¿£ÅÍ> ÀÔ·Â"
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help register<¿£ÅÍ> ÀÔ·Â"
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é ¸Þ´º µµ¿ò¸»->Sponsor/Register"
-
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "ÀÌ¹Ì ÇϳªÀÇ Ã¢¸¸ ÀÖ½À´Ï´Ù"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: ¹Ì¸® º¸±â âÀÌ ¾ø½À´Ï´Ù"
-
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: À§ ¿ÞÂʰú ¾Æ·¡ ¿À¸¥ÂÊÀ» µ¿½Ã¿¡ ³ª´­ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: ´Ù¸¥ âÀÌ ³ª´²Á³À» ¶§¿¡´Â ȸÀüÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: ¸¶Áö¸· âÀ» ´ÝÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../window.c:1810
-msgid "E813: Cannot close autocmd window"
-msgstr "E813: autocmd âÀ» ´ÝÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#: ../window.c:1814
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: âÀ» ´ÝÀ» ¼ö ¾øÀ½, autocmd ⸸ ³²À½"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: ´Ù¸¥ âÀÌ ¹Ù²î¾ú½À´Ï´Ù"
-
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: Ä¿¼­ ¹Ø¿¡ ÆÄÀÏ À̸§ÀÌ ¾ø½À´Ï´Ù"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: ºó ºñ¹Ð¹øÈ£·Î bf_key_init() ÇÔ¼ö°¡ ºÒ·ÁÁ³½À´Ï´Ù"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfish big/little endian use wrong"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: sha256 ½ÃÇèÀÌ ½ÇÆÐÇß½À´Ï´Ù."
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Blowfish ½ÃÇèÀÌ ½ÇÆÐÇß½À´Ï´Ù."
-
-#~ msgid "Patch file"
-#~ msgstr "ÆÐŰ ÆÄÀÏ"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "È®ÀÎ(&O)\n"
-#~ "Ãë¼Ò(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Vim ¼­¹ö¿¡ ¿¬°áµÇ¾î ÀÖÁö ¾Ê½À´Ï´Ù"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: %s(À¸)·Î º¸³¾ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: ¼­¹öÀÇ ÀÀ´äÀ» ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Ŭ¶óÀÌ¾ðÆ®·Î º¸³¾ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Save As"
-#~ msgstr "´Ù¸¥ À̸§À¸·Î ÀúÀå"
-
-#~ msgid "Edit File"
-#~ msgstr "ÆÄÀÏ °íÄ¡±â"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (¸ø ã¾ÒÀ½)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "ºö ½ºÅ©¸³Æ® ·Îµå"
-
-#~ msgid "unknown"
-#~ msgstr "¸ð¸§"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "»õ â¿¡¼­ ÆÄÀÏ °íÄ¡±â"
-
-#~ msgid "Append File"
-#~ msgstr "ÆÄÀÏ Ãß°¡"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "â À§Ä¡: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "¸®µð·º¼Ç ÀúÀå"
-
-#~ msgid "Save View"
-#~ msgstr "º¸±â ÀúÀå"
-
-#~ msgid "Save Session"
-#~ msgstr "¼¼¼Ç ÀúÀå"
-
-#~ msgid "Save Setup"
-#~ msgstr "¼³Á¤ ÀúÀå"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #<´Â +eval ±â´ÉÀÌ Æ÷ÇԵǾî¾ß »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ÀÌ ÆÇ¿¡´Â digraph°¡ ¾ø½À´Ï´Ù"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "Àº(´Â) ÀåÄ¡°¡ ¾Æ´Õ´Ï´Ù ('opendevice' ¿É¼ÇÀ¸·Î ¸·Èû)"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "Ç¥ÁØÀԷ¿¡¼­ Àд Áß..."
-
-#~ msgid "[crypted]"
-#~ msgstr "[¾Ïȣȭ µÇ¾ú½À´Ï´Ù]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: ÆÄÀÏÀÌ ¸ð¸£´Â ¹æ¹ýÀ¸·Î ¾ÏȣȭµÇ¾î ÀÖ½À´Ï´Ù"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans¿¡¼­´Â ¹Ù²îÁö ¾ÊÀº ¹öÆÛ¸¦ ¾µ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeans ¹öÆÛ¿¡ ´ëÇØ¼­´Â ºÎºÐ ÀúÀåÀ» ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "ÀåÄ¡ ¾²±â°¡ 'opendevice' ¿É¼ÇÀ¸·Î ¸·Èû"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: The resource fork will be lost (µ¤¾î¾²·Á¸é ! ´õÇϱâ)"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: GUI¸¦ ½ÃÀÛÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: \"%s\"¿¡¼­ ÀÐÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: ¾µ¸¸ÇÑ ±Û²ÃÀ» ãÀ» ¼ö ¾ø¾î¼­ GUI¸¦ ½ÇÇàÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: 'guifontwide'°¡ ÀÌ»óÇÕ´Ï´Ù"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' °ªÀÌ ÀÌ»óÇÕ´Ï´Ù"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: »ö %sÀ»(¸¦) ÇÒ´çÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<¿­ ¼ö ¾øÀ½> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ±Û²Ã %sÀ»(¸¦) ¾òÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ÇöÀç µð·ºÅ丮·Î µ¹¾Æ°¥ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Pathname:"
-#~ msgstr "°æ·Î À̸§:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ÇöÀç µð·ºÅ丮¸¦ ¾òÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "OK"
-#~ msgstr "È®ÀÎ"
-
-#~ msgid "Cancel"
-#~ msgstr "Ãë¼Ò"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "½ºÅ©·Ñ¹Ù À§Á¬: ½æ ÇȽº¸ÊÀÇ Áö¿À¹ÌÆ®¸®¸¦ ¾òÀ» ¼ö ¾ø½À´Ï´Ù."
-
-#~ msgid "Vim dialog"
-#~ msgstr "ºö ´ëÈ­»óÀÚ"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr ""
-#~ "E232: ¸Þ½ÃÁö¿Í ÄÝ¹é ¸ðµÎ¸¦ »ç¿ëÇØ¼­´Â BalloonEvalÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Input _Methods"
-#~ msgstr "ÀÔ·Â ¹æ¹ý(_M)"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "ºö - ã¾Æ¼­ ¹Ù²Ù±â..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "ºö - ã±â..."
-
-#~ msgid "Find what:"
-#~ msgstr "¹«¾ó ãÀ»±î¿ä:"
-
-#~ msgid "Replace with:"
-#~ msgstr "¹Ù²Ü ¹®ÀÚ¿­:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "¶È°°Àº ³¹¸»¸¸"
-
-#~ msgid "Direction"
-#~ msgstr "¹æÇâ"
-
-#~ msgid "Up"
-#~ msgstr "À§·Î"
-
-#~ msgid "Down"
-#~ msgstr "¾Æ·¡·Î"
-
-#~ msgid "Find Next"
-#~ msgstr "´ÙÀ½ ã±â"
-
-#~ msgid "Replace"
-#~ msgstr "¹Ù²Ù±â"
-
-#~ msgid "Replace All"
-#~ msgstr "¸ðµÎ ¹Ù²Ù±â"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "ºö: ¼¼¼Ç °ü¸®ÀڷκÎÅÍ \"die\" ¿äûÀ» ¹Þ¾Ò½À´Ï´Ù\n"
-
-#~ msgid "Close"
-#~ msgstr "´Ý±â"
-
-#~ msgid "New tab"
-#~ msgstr "»õ ÅÇ"
-
-#~ msgid "Open Tab..."
-#~ msgstr "ÅÇ ¿­±â..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "ºö: ¸ÞÀΠâÀÌ Á×°Ô µÉ °ÍÀÔ´Ï´Ù\n"
-
-#~ msgid "&Filter"
-#~ msgstr "°Å¸£°³(&F)"
-
-#~ msgid "&Cancel"
-#~ msgstr "Ãë¼Ò(&C)"
-
-#~ msgid "Directories"
-#~ msgstr "µð·ºÅ丮"
-
-#~ msgid "Filter"
-#~ msgstr "°Å¸£°³"
-
-#~ msgid "&Help"
-#~ msgstr "µµ¿ò¸»(&H)"
-
-#~ msgid "Files"
-#~ msgstr "ÆÄÀÏ"
-
-#~ msgid "&OK"
-#~ msgstr "È®ÀÎ(&O)"
-
-#~ msgid "Selection"
-#~ msgstr "°í¸£±â"
-
-#~ msgid "Find &Next"
-#~ msgstr "´ÙÀ½ ã±â(&N)"
-
-#~ msgid "&Replace"
-#~ msgstr "¹Ù²Ù±â(&R)"
-
-#~ msgid "Replace &All"
-#~ msgstr "¸ðµÎ ¹Ù²Ù±â(&A)"
-
-#~ msgid "&Undo"
-#~ msgstr "Ãë¼Ò(&U)"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: â Á¦¸ñ \"%s\"À»(¸¦) ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Áö¿øµÇÁö ¾Ê´Â ÀÎÀÚ: \"-%s\": OLE ÆÇÀ» »ç¿ëÇϽʽÿÀ."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: MDI ÀÀ¿ëÇÁ·Î±×·¥ ¾È¿¡¼­ âÀ» ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Close tab"
-#~ msgstr "ÅÇ ´Ý±â"
-
-#~ msgid "Open tab..."
-#~ msgstr "ÅÇ ¿­±â..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "¹®ÀÚ¿­ ã±â ('\\'¸¦ ãÀ¸·Á¸é '\\\\' »ç¿ë)"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "¹®ÀÚ¿­ ã¾Æ ¹Ù²Ù±â ('\\'¸¦ ãÀ¸·Á¸é '\\\\' »ç¿ë)"
-
-#~ msgid "Not Used"
-#~ msgstr "»ç¿ë ¾ÊµÊ"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "µð·ºÅ丮\t*.nothing\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "ºö E458: »ö»ó¸Ê ¿£Æ®¸®¸¦ ÇÒ´çÇÒ ¼ö ¾ø½À´Ï´Ù, ¸î¸î »öÀÌ À߸øµÉ ¼ö ÀÖ½À´Ï´Ù"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: ´ÙÀ½ ±ÛÀÚ¼ÂÀÇ ±Û²ÃÀÌ ±Û²Ã¼Â %s¿¡ ¾ø½À´Ï´Ù:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: ±Û²Ã¼Â À̸§: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "±Û²Ã '%s'Àº(´Â) °íÁ¤³ÐÀ̰¡ ¾Æ´Õ´Ï´Ù"
-
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: ±Û²Ã¼Â À̸§: %s\n"
-
-#~ msgid "Font0: %s\n"
-#~ msgstr "±Û²Ã0: %s\n"
-
-#~ msgid "Font1: %s\n"
-#~ msgstr "±Û²Ã1: %s\n"
-
-#~ 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 ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "±Û²Ã1 ³Êºñ: %<PRId64>\n"
-#~ "\n"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - ±Û²Ã ¼±Åñâ"
-
-#~ msgid "Name:"
-#~ msgstr "À̸§:"
-
-#~ msgid "Encoding:"
-#~ msgstr "ÀÎÄÚµù:"
-
-#~ msgid "Font:"
-#~ msgstr "±Û²Ã:"
-
-#~ msgid "Style:"
-#~ msgstr "½ºÅ¸ÀÏ:"
-
-#~ msgid "Size:"
-#~ msgstr "Å©±â:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ÇÑ±Û ¿ÀÅ丶Ÿ ¿¡·¯"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat ¿¡·¯"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: cscope µ¥ÀÌÅͺ£À̽º¸¦ ¿­ ¼ö ¾øÀ½: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: cscope µ¥ÀÌÅͺ£À̽º Á¤º¸¸¦ ¾òÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "cannot save undo information"
-#~ msgstr "undo Á¤º¸¸¦ ÀúÀåÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: ¹Ì¾ÈÇÕ´Ï´Ù, ÀÌ ¸í·ÉÀº »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù, MzScheme ¶óÀ̺귯¸®¸¦ ·Îµù"
-#~ "ÇÒ ¼ö ¾ø½À´Ï´Ù."
-
-#~ msgid "invalid expression"
-#~ msgstr "À߸øµÈ Ç¥Çö½Ä"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "Ç¥Çö½ÄÀ» Áö¿øÇÏÁö ¾Êµµ·Ï ÄÄÆÄÀÏ µÇ¾ú½À´Ï´Ù"
-
-#~ msgid "unknown option"
-#~ msgstr "¸ð¸£´Â ¿É¼Ç"
-
-#~ msgid "window index is out of range"
-#~ msgstr "â ¹øÈ£°¡ ¹üÀ§¸¦ ¹þ¾î³µ½À´Ï´Ù"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "¹öÆÛ¸¦ ¿­ ¼ö ¾ø¾ú½À´Ï´Ù"
-
-#~ msgid "cannot delete line"
-#~ msgstr "ÁÙÀ» Áö¿ï ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "cannot replace line"
-#~ msgstr "ÁÙÀ» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "cannot insert line"
-#~ msgstr "ÁÙÀ» ³¢¿ö³ÖÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "¹®ÀÚ¿­Àº newlineÀ» Æ÷ÇÔÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim ¿¡·¯: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Vim ¿¡·¯"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "¹öÆÛ°¡ ÀÌ»óÇÕ´Ï´Ù"
-
-#~ msgid "window is invalid"
-#~ msgstr "âÀÌ ÀÌ»óÇÕ´Ï´Ù"
-
-#~ msgid "linenr out of range"
-#~ msgstr "ÁÙ ¹øÈ£°¡ ¹üÀ§¸¦ ¹þ¾î³µ½À´Ï´Ù"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "Vim sandbox¿¡¼­´Â Çã¿ëµÇÁö ¾Ê½À´Ï´Ù"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: ÀÌ VimÀº :py3À» »ç¿ëÇÑ ÈÄ¿¡ :pythonÀ» »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: ¹Ì¾ÈÇÕ´Ï´Ù, ÀÌ ¸í·ÉÀº »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù, ÆÄÀ̽㠶óÀ̺귯¸®¸¦ ·Îµù"
-#~ "ÇÒ ¼ö ¾ø½À´Ï´Ù."
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: PythonÀ» Àç±ÍÈ£ÃâÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "OutputObject ¼Ó¼ºÀ» Áö¿ï ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspace´Â Á¤¼ö¿©¾ß¸¸ ÇÕ´Ï´Ù"
-
-#~ msgid "invalid attribute"
-#~ msgstr "À߸øµÈ ¼Ó¼º"
-
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<%p¿¡ ¹öÆÛ °´Ã¼ (»èÁ¦µÊ)>"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: ÀÌ VimÀº :pythonÀ» »ç¿ëÇÑ ÈÄ¿¡ :py3À» »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: ¹Ì¾ÈÇÕ´Ï´Ù, ÀÌ ¸í·ÉÀº »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù, ·çºñ ¶óÀ̺귯¸®¸¦ ·ÎµùÇÒ "
-#~ "¼ö ¾ø½À´Ï´Ù."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: ¶æ¹ÛÀÇ return"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: ¶æ¹ÛÀÇ next"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: ¶æ¹ÛÀÇ break"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: ¶æ¹ÛÀÇ redo"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: ó¸®¾ÊµÈ ¿¹¿Ü"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: ¸ð¸£´Â longjmp »óÅ %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Åä±Û ±¸Çö/Á¤ÀÇ"
-
-#~ msgid "Show base class of"
-#~ msgstr "...ÀÇ ±âº» Ŭ·¡½º º¸¿©ÁÖ±â"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "SNiFF+·Î ¿¬°áÇÒ ¼ö ¾ø½À´Ï´Ù. ȯ°æÀ» È®ÀÎÇϽʽÿÀ (sniffemacs°¡ $PATH¿¡¼­ "
-#~ "ã¾ÆÁ®¾ß ÇÕ´Ï´Ù).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Àд Áß ¿¡·¯. ²÷±è"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ is currently "
-
-#~ msgid "not "
-#~ msgstr "not "
-
-#~ msgid "connected"
-#~ msgstr "connected"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: ¸ð¸£´Â SNiFF+ ¿äû: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: SNiFF+¿¡ ¿¬°á ¿¡·¯"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SniFF+°¡ ¿¬°áµÇÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: SniFF+ ¹öÆÛ°¡ ¾Æ´Õ´Ï´Ù"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: ¾²´Â µµÁß ¿¡·¯. ²÷°å½À´Ï´Ù"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "À߸øµÈ ¹öÆÛ ¹øÈ£"
-
-#~ msgid "not implemented yet"
-#~ msgstr "¾ÆÁ÷ ±¸ÇöµÇÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "ÁÙÀ» ¼³Á¤ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "invalid mark name"
-#~ msgstr "À߸øµÈ ¸¶Å© À̸§"
-
-#~ msgid "mark not set"
-#~ msgstr "¸¶Å©°¡ ¼³Á¤µÇÁö ¾Ê¾Ò½À´Ï´Ù"
-
-#~ msgid "row %d column %d"
-#~ msgstr "Çà %d ¿­ %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "ÁÙÀ» ³¢¿ö³Ö°Å³ª ´õÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "line number out of range"
-#~ msgstr "ÁÙ ¹øÈ£°¡ ¹üÀ§¸¦ ¹þ¾î³µ½À´Ï´Ù"
-
-#~ msgid "unknown flag: "
-#~ msgstr "¸ð¸£´Â Ç÷¡±×: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "¸ð¸£´Â ºö ¿É¼Ç"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "Űº¸µå ÀÎÅÍ·´Æ®"
-
-#~ msgid "vim error"
-#~ msgstr "ºö ¿¡·¯"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "¹öÆÛ/â ¸í·ÉÀ» ¸¸µé ¼ö ¾ø½À´Ï´Ù: °´Ã¼°¡ Áö¿öÁý´Ï´Ù"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "ÄÝ¹é ¸í·ÉÀ» µî·ÏÇÒ ¼ö ¾ø½À´Ï´Ù: ¹öÆÛ/âÀÌ ÀÌ¹Ì Áö¿öÁ³½À´Ï´Ù"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL ½É°¢ÇÑ ¿¡·¯: reflist°¡ ±úÁ³³ª!? ÀÌ ¹®Á¦¸¦ vim-dev@vim.org·Î ¾Ë·Á"
-#~ "ÁֽʽÿÀ"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr "ÄÝ¹é ¸í·ÉÀ» µî·ÏÇÒ ¼ö ¾ø½À´Ï´Ù: ¹öÆÛ/â ÂüÁ¶¸¦ ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: ¹Ì¾ÈÇÕ´Ï´Ù, ÀÌ ¸í·ÉÀº »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù, Tcl ¶óÀ̺귯¸®¸¦ ·ÎµùÇÒ "
-#~ "¼ö ¾ø½À´Ï´Ù."
-
-#~ 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 "E572: exit code %d"
-#~ msgstr "E572: Á¾·á ÄÚµå %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "ÁÙÀ» ¾òÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "¸í·É ¼­¹ö À̸§À» µî·ÏÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: ´ë»óÇÁ·Î±×·¥À¸·Î ¸í·É º¸³»±â°¡ ½ÇÆÐÇß½À´Ï´Ù"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: À߸øµÈ ¼­¹ö id »ç¿ëµÊ: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: ºö ÀνºÅϽº ·¹Áö½ºÆ®¸® ¼Ó¼ºÀÌ À߸øµÇ¾î ÀÖ½À´Ï´Ù. Áö¿ü½À´Ï´Ù!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "ÀÌ GUI´Â netbeans¸¦ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "ÀÌ ºöÀº diff ±â´É ¾øÀÌ ÄÄÆÄÀÏ µÇ¾ú½À´Ï´Ù."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb'´Â »ç¿ëÇÒ ¼ö ¾øÀ½: ÄÄÆÄÀÏÇÒ ¶§ Æ÷ÇÔµÇÁö ¾ÊÀ½\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: ¿¡·¯: NetBeans¿¡¼­ gvim ½ÃÀÛ ½ÇÆÐ\n"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tÀÌ gvim OLE¿¡ µî·Ï"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tgvimÀ» OLE¿¡¼­ µî·ÏÃë¼Ò"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tGUI·Î ½ÇÇà (\"gvim\"°ú °°À½)"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f ȤÀº --nofork\tÆ÷±×¶ó¿îµå: GUI·Î ½ÃÀÛÇÒ ¶§ forkÇÏÁö ¸» °Í"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tâÀ» ¿­ ¶§ newcli »ç¿ëÇÏÁö ¾ÊÀ½"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <ÀåÄ¡>\t\tI/O¿¡ <ÀåÄ¡> »ç¿ë"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\t.gvimrc ´ë½Å <gvimrc>¸¦ »ç¿ë"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\t¾ÏȣȭµÈ ÆÄÀÏ °íÄ¡±â"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tºöÀ» ƯÁ¤ X-¼­¹ö¿Í ¿¬°á"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tX ¼­¹ö¿¡ ¿¬°áÇÏÁö ¾ÊÀ½"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\t°¡´ÉÇÏ¸é ºö ¼­¹ö¿¡¼­ <files> ÆíÁý"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> °°À½, ¼­¹ö°¡ ¾ø´Ù°í ºÒÆòÇÏÁö ¾ÊÀ½"
-
-#~ 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 ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <files> --remote¿Í °°Áö¸¸ ÆÄÀϺ°·Î ÅÇ ÆäÀÌ"
-#~ "Áö »ç¿ë"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\tºö ¼­¹ö·Î <keys>¸¦ º¸³»°í ³¡³»±â"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\tºö ¼­¹ö¿¡¼­ <expr> ½ÇÇàÇÏ°í °á°ú Ãâ·Â"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\t»ç¿ë °¡´ÉÇÑ ºö ¼­¹ö À̸§À» Ç¥½ÃÇÏ°í ³¡³»±â"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <name>\tºö ¼­¹ö <name>ÀÌ µÇ°Å³ª ¼­¹ö·Î º¸³»±â"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimÀÌ ¾Ë°í ÀÖ´Â ÀÎÀÚ (¸ðƼÇÁ ÆÇ):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimÀÌ ¾Ë°í ÀÖ´Â ÀÎÀÚ (neXtaw ÆÇ):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimÀÌ ¾Ë°í ÀÖ´Â ÀÎÀÚ (¾ÆÅ׳ª ÆÇ):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\tºöÀ» <display>¿¡¼­ ½ÇÇà"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\t¾ÆÀÌÄÜ »óÅ·Πºö ½ÃÀÛ"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\t¹ÙÅÁ »öÀ¸·Î <color> »ç¿ë (also: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\tÀÏ¹Ý »ö¿¡ <color> »ç¿ë (also: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\tÀÏ¹Ý ÅØ½ºÆ®¿¡ <font> »ç¿ë (also: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\t±½Àº ÅØ½ºÆ®¿¡ <font> »ç¿ë"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <font>\t±â¿ïÀÓ ÅØ½ºÆ®¿¡ <font> »ç¿ë"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\tÃʱâ Áö¿À¹ÌÆ®¸®¿¡ <geom> »ç¿ë (also: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\t°¡ÀåÀÚ¸® ³ÐÀÌ¿¡ <width> »ç¿ë (also: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr "-scrollbarwidth <width> ½ºÅ©·Ñ¹Ù ³ÐÀÌ¿¡ <width> »ç¿ë (also: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <height>\t¸Þ´º¹Ù ³ôÀÌ¿¡ <height> »ç¿ë (also: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\t¹ÝÀü ºñµð¿À »ç¿ë (also: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\t¹ÝÀü ºñµð¿À »ç¿ë ¾È ÇÔ (also: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\t¸í½ÃµÈ ¸®¼Ò½º ¼³Á¤"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimÀÌ ¾Ë°íÀÖ´Â ÀÎÀÚ (RISC OS ÆÇ):\n"
-
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <¼ýÀÚ>\tÄ­¿¡¼­ â Ãʱ⠳ʺñ"
-
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <¼ýÀÚ>\tÁÙ¿¡¼­ â Ãʱ⠳ôÀÌ"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvimÀÌ ¾Ë°íÀÖ´Â ÀÎÀÚ (GTK+ ÆÇ):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\tºöÀ» <display>¿¡¼­ ½ÇÇà (also: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\t¸ÞÀΠâ ±¸ºÐÀ» À§ÇØ À¯ÀÏÇÑ ¿ªÇÒ ¼³Á¤"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tºöÀ» ´Ù¸¥ GTK À§Á¬ ¾È¿¡¼­ ¿­À½"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <parent title>\tVimÀ» ºÎ¸ð ÀÀ¿ë ÇÁ·Î±×·¥ ³»¿¡¼­ ¿­±â"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\t´Ù¸¥ win32 À§Á¬ ¾È¿¡¼­ Vim ¿­±â"
-
-#~ msgid "No display"
-#~ msgstr "µð½ºÇ÷¹À̰¡ ¾ø½À´Ï´Ù"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": º¸³»±â°¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": º¸³»±â ½ÇÆÐ. ·ÎÄÿ¡¼­ ½ÇÇàµË´Ï´Ù\n"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "µð½ºÇ÷¹ÀÌ ¾øÀ½: Ç¥Çö½Ä º¸³»±â°¡ ½ÇÆÐÇß½À´Ï´Ù.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Ç¥Çö½Ä º¸³»±â°¡ ½ÇÆÐÇß½À´Ï´Ù.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Á¤»óÀûÀÎ ÄÚµåÆäÀÌÁö°¡ ¾Æ´Õ´Ï´Ù"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: ÀÔ·Â ÄÜÅØ½ºÆ®¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: ÀÔ·Â ¹æ½ÄÀ» ¿­´Ù°¡ ½ÇÆÐÇß½À´Ï´Ù"
-
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: °æ°í: IM¿¡ ÆÄ±« ÄݹéÀ» ¼³Á¤ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: ÀÔ·Â ¹æ½ÄÀÌ ¾î¶² Çü½Äµµ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù"
-
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: ÀÔ·Â ¹æ½ÄÀÌ ³» preedit Çü½ÄÀ» Áö¿øÇÏÁö ¾Ê½À´Ï´Ù"
-
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: ½º¿Ò ÆÄÀÏÀ» ¾ÏȣȭÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr ""
-#~ "E833: %sÀÌ(°¡) ¾ÏȣȭµÇ¾î ÀÖ´Â µ¥, ÀÌ VimÀº ¾Ïȣȭ¸¦ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "½º¿Ò ÆÄÀÏÀÌ ¾ÏȣȭµÊ: \"%s\""
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "»õ·Î¿î ¾ÏÈ£ ۸¦ ÀÔ·ÂÇß´Â µ¥, ÆÄÀÏÀ» ÀúÀåÇÏÁö ¾Ê¾Ò¾ú´Ù¸é,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "»õ·Î¿î ¾ÏÈ£ ۸¦ ÀÔ·ÂÇϼ¼¿ä."
-
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "¾ÏÈ£ ۸¦ ¹Ù²Û ÈÄ¿¡ ÆÄÀÏÀ» ÀúÀåÇß¾ú´Ù¸é °°Àº Ű·Î ÅØ½ºÆ® ÆÄÀϰú"
-
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "½º¿ÒÆÄÀÏÀ» ÀúÀåÇÏ·Á¸é ¿£Å͸¦ ´©¸£¼¼¿ä"
-
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "ÅØ½ºÆ® ÆÄÀÏ¿¡ ½º¿ÒÆÄÀÏ¿¡¼­ °¡Á®¿Â ¾ÏÈ£ ۸¦ »ç¿ëÇÕ´Ï´Ù.\n"
-
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [ºö À̹ø ÆÇ¿¡¼­´Â »ç¿ëÇÒ ¼ö ¾øÀ½]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "ÀÌ ¸Þ´º¸¦ ¶¼¾î³¿"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "µð·ºÅ丮 ¼±Åà ´ëÈ­»óÀÚ"
-
-#~ msgid "Save File dialog"
-#~ msgstr "ÆÄÀÏ ÀúÀå ´ëÈ­»óÀÚ"
-
-#~ msgid "Open File dialog"
-#~ msgstr "ÆÄÀÏ ¿­±â ´ëÈ­»óÀÚ"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: ¹Ì¾ÈÇÕ´Ï´Ù, ÄÜ¼Ö »óÅ¿¡´Â ÆÄÀÏ ºê¶ó¿ìÀú°¡ ¾ø½À´Ï´Ù"
-
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "ºö: ÆÄÀÏ º¸Á¸Áß...\n"
-
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "ºö: ²ø³µ½À´Ï´Ù.\n"
-
-#~ msgid "ERROR: "
-#~ msgstr "¿¡·¯: "
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: ÁÙÀÌ ³Ê¹« ±æ¾îÁ³½À´Ï´Ù"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: ³»ºÎ ¿¡·¯: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: ÀÌ»óÇÑ ¸¶¿ì½º¸ð¾ç"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "¾ÏÈ£ Ű ÀÔ·Â: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "°°Àº ۸¦ ´Ù½Ã ÀÔ·Â: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "۰¡ ¸ÂÁö ¾Ê½À´Ï´Ù!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Netbeans #2¿¡ ¿¬°áÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Netbeans¿¡ ¿¬°áÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: NetBeans ¿¬°á Á¤º¸ ÆÄÀÏÀÌ Á¢±Ù ¸ðµå°¡ À߸øµÊ: \"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "Netbeans ¼ÒÄÏ¿¡¼­ Àбâ"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: ¹öÆÛ %<PRId64>¿¡ ´ëÇÑ NetBeans ¿¬°áÀ» ÀÒ¾î¹ö·È½À´Ï´Ù"
-
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: ÀÌ GUI´Â netbeans¸¦ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù"
-
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans°¡ ÀÌ¹Ì ¿¬°áµÇ¾î ÀÖ½À´Ï´Ù"
-
-#~ msgid "E505: "
-#~ msgstr "E505: "
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Eval ±â´ÉÀÌ ºüÁ®ÀÖ½À´Ï´Ù"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "freeing %<PRId64> lines"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: GUI¿¡¼­´Â termÀ» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: GUI¸¦ ½ÃÀÛÇÏ·Á¸é \":gui\"¸¦ »ç¿ëÇϽʽÿÀ"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: GTK+ 2 GUI¿¡¼­´Â ¹Ù²ð ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: À߸øµÈ ±Û²Ã(µé)"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ±Û²Ã¼ÂÀ» °í¸¦ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: À߸øµÈ ±Û²Ã¼Â"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ¿ÍÀÌµå ±Û²ÃÀ» °í¸¦ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: À߸øµÈ ¿ÍÀÌµå ±Û²Ã"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: ¸¶¿ì½º¸¦ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù"
-
-#~ msgid "cannot open "
-#~ msgstr "cannot open "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "ºö: âÀ» ¿­ ¼ö ¾ø½À´Ï´Ù!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "¾Æ¹Ì°¡µµ½º 2.04³ª ´õ ³ôÀº ÆÇÀÌ ÇÊ¿äÇÕ´Ï´Ù\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Need %s version %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "NILÀ» ¿­ ¼ö ¾øÀ½:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "Cannot create "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "ºöÀÌ %d °ªÀ¸·Î ³¡³À´Ï´Ù\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "ÄÜ¼Ö »óŸ¦ ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù ?!\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ÄܼÖÀÌ ¾Æ´Ñ°¡??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: -f ¿É¼ÇÀÌ »ç¿ëµÈ °æ¿ì ½©À» ½ÇÇàÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Cannot execute "
-#~ msgstr "Cannot execute "
-
-#~ msgid "shell "
-#~ msgstr "shell "
-
-#~ msgid " returned\n"
-#~ msgstr " returned\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE°¡ ³Ê¹« ÀÛ½À´Ï´Ù."
-
-#~ msgid "I/O ERROR"
-#~ msgstr "I/O ¿¡·¯"
-
-#~ msgid "Message"
-#~ msgstr "¸Þ½ÃÁö"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns'ÀÌ 80ÀÌ ¾Æ´Ï¾î¼­, ¿ÜºÎ ¸í·ÉÀ» ½ÇÇàÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: ÇÁ¸°Å͸¦ °í¸£Áö ¸øÇß½À´Ï´Ù"
-
-#~ msgid "to %s on %s"
-#~ msgstr "to %s on %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: ¸ð¸£´Â ÇÁ¸°ÅÍ ±Û²Ã: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Àμ⠿¡·¯: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "'%s' ÀμâÁß"
-
-#~ 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 "Vim: Double signal, exiting\n"
-#~ msgstr "ºö: °°Àº ½Ã±×³Î µÎ ¹ø, ³¡³À´Ï´Ù\n"
-
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "ºö: %s ½Ã±×³ÎÀ» Àâ¾Ò½À´Ï´Ù\n"
-
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "ºö: Á×À» ½Ã±×³ÎÀ» Àâ¾Ò½À´Ï´Ù\n"
-
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "X µð½ºÇ÷¹À̸¦ ¿©´Â µ¥ %<PRId64> msecÀÌ °É·È½À´Ï´Ù"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ºö: X ¿¡·¯°¡ »ý°å½À´Ï´Ù\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "X µð½ºÇ÷¹ÀÌ ½ÃÇèÀÌ ½ÇÆÐÇß½À´Ï´Ù"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "X µð½ºÇ÷¹À̸¦ ¿­´Ù°¡ ½Ã°£ÀÌ ÃʰúµÇ¾ú½À´Ï´Ù"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "½© sh¸¦ ½ÇÇàÇÒ ¼ö ¾ø½À´Ï´Ù\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÆÄÀÌÇÁ¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÀÚ½Ä ÇÁ·Î¼¼½º¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¸í·ÉÀÌ ³¡¸¶ÃÄÁ³½À´Ï´Ù\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP°¡ ICE ¿¬°áÀ» ÀÒ¾î¹ö·È½À´Ï´Ù"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "X µð½ºÇ÷¹ÀÌ ¿­±â°¡ ½ÇÆÐÇß½À´Ï´Ù"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP°¡ save-yourself ¿äûÀ» ½ÇÇàÇϰí ÀÖ½À´Ï´Ù"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP°¡ ¿¬°áÀ» ¿©´Â ÁßÀÔ´Ï´Ù"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP°¡ ICE ¿¬°á °¨½Ã¸¦ ½ÇÆÐÇß½À´Ï´Ù"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection ½ÇÆÐ: %s"
-
-#~ msgid "At line"
-#~ msgstr "At line"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "vim32.dllÀ» ºÒ·¯ µéÀÏ ¼ö ¾ø½À´Ï´Ù!"
-
-#~ msgid "VIM Error"
-#~ msgstr "ºö ¿¡·¯"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "ÇÔ¼ö Æ÷ÀÎÅ͸¦ DLL·Î ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "½©ÀÌ %dÀ»(¸¦) µ¹·ÁÁÖ¾ú½À´Ï´Ù"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "ºö: %s À̺¥Æ®¸¦ Àâ¾Ò½À´Ï´Ù\n"
-
-#~ msgid "close"
-#~ msgstr "´Ý±â"
-
-#~ msgid "logoff"
-#~ msgstr "·Î±×¾Æ¿ô"
-
-#~ msgid "shutdown"
-#~ msgstr "¼Ë´Ù¿î"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: ¸í·ÉÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ 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 ""
-#~ "VIMRUN.EXE¸¦ $PATH¿¡¼­ ãÀ» ¼ö ¾ø½À´Ï´Ù.\n"
-#~ "¿ÜºÎ ¸í·ÉÀÌ ³¡³­ µÚ ¸ØÃâ ¼ö ¾ø½À´Ï´Ù.\n"
-#~ "´Ù ¸¹Àº Á¤º¸¸¦ º¸½Ã·Á¸é :help win32-vimrunÀ» º¸½Ê½Ã¿À."
-
-#~ msgid "Vim Warning"
-#~ msgstr "ºö °æ°í"
-
-#~ msgid "Error file"
-#~ msgstr "¿¡·¯ ÆÄÀÏ"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "°æ°í: ´Ü¾î ¸ñ·Ï \"%s_%s.spl\" ȤÀº \"%s_ascii.spl\"À» ãÀ» ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "%sÀÇ º¯È¯ÀÌ Áö¿øµÇÁö ¾Ê½À´Ï´Ù"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: %s¿¡ ´ëÇÑ ÅÂ±× ÆÄÀÏ °æ·Î°¡ À߷ȽÀ´Ï´Ù\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "»õ ½©ÀÌ ½ÃÀ۵Ǿú½À´Ï´Ù\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "ºó °í¸£±â ´ë½Å CUT_BUFFER0À» »ç¿ëÇß½À´Ï´Ù"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Ãë¼Ò ºÒ°¡´É; ¾î·µç °è¼ÓÇÕ´Ï´Ù"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr ""
-#~ "E832: ¾ÏȣȭµÇÁö ¾ÊÀº ÆÄÀÏÀÌ ¾ÏȣȭµÈ undo ÆÄÀÏÀ» °¡Áö°í ÀÖ½À´Ï´Ù: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Undo ÆÄÀÏÀ» ÇØµ¶ÇÒ ¼ö ¾ø½À´Ï´Ù: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Undo ÆÄÀÏÀÌ ¾ÏȣȭµÇ¾ú½À´Ï´Ù: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 ºñÆ® GUI ÆÇ"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64ºñÆ® GUI ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32ºñÆ® GUI ¹öÁ¯"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " Win32s »óÅÂ"
-
-#~ msgid " with OLE support"
-#~ msgstr " OLE Áö¿ø"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 64ºñÆ® ÄÜ¼Ö ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32ºñÆ® ÄÜ¼Ö ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16ºñÆ® ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32ºñÆ® MS-DOS ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16ºñÆ® MS-DOS ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (À¯´Ð½º) ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
-#~ msgstr ""
-#~ "\n"
-#~ "RISC OS ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "OpenVMS ¹öÁ¯"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Big ¹öÁ¯ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Normal ¹öÁ¯ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Small ¹öÁ¯ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Tiny ¹öÁ¯ "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "GTK2-GNOME GUI."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "GTK2 GUI."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "X11-Motif GUI."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "X11-neXtaw GUI."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "X11-Athena GUI."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "Photon GUI."
-
-#~ msgid "with GUI."
-#~ msgstr "GUI."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "Carbon GUI."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "Cocoa GUI."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "(Ŭ·¡½Ä) GUI."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ½Ã½ºÅÛ gvimrc ÆÄÀÏ: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " »ç¿ëÀÚ gvimrc ÆÄÀÏ: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "»ç¿ëÀÚ µÎ ¹øÂ° gvimrc ÆÄÀÏ: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "»ç¿ëÀÚ ¼¼ ¹øÂ° gvimrc ÆÄÀÏ: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " ½Ã½ºÅÛ ¸Þ´º ÆÄÀÏ: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "ÄÄÆÄÀÏ·¯: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é ¸Þ´º¿¡¼­ µµ¿ò¸»->°í¾Æ ¼±ÅÃ"
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "¸ðµå¾øÀÌ ¼öÇàÁßÀ̸ç, ÀÔ·ÂµÈ ¹®ÀÚ´Â »ðÀԵ˴ϴÙ"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "¸Þ´º¿¡¼­ ÆíÁý->Àü¿ª ¼³Á¤->»ðÀÔ ¸ðµå Åä±ÛÀ» ¼±ÅÃÇϽøé "
-
-#~ msgid " for two modes "
-#~ msgstr " µÎ ¸ðµå¸¦ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù "
-
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "¸Þ´º¿¡¼­ ÆíÁý->Àü¿ª ¼³Á¤->Vi ȣȯ Åä±ÛÀ» ¼±ÅÃÇϽøé "
-
-#~ msgid " for Vim defaults "
-#~ msgstr " VimÀÌ ±âº»°ªÀ¸·Î µ¿ÀÛÇÕ´Ï´Ù "
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "°æ°í: À©µµ¿ìÁî 95/98/ME¸¦ ã¾ÒÀ½"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "ÀÌ¿¡ ´ëÇÑ Á¤º¸¸¦ º¸·Á¸é :help windows95<¿£ÅÍ> ÀÔ·Â"
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: %s ¶óÀ̺귯¸®¸¦ ·ÎµåÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "¹Ì¾ÈÇÕ´Ï´Ù, ÀÌ ¸í·ÉÀº »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù, Perl ¶óÀ̺귯¸®¸¦ ·ÎµùÇÒ ¼ö ¾ø½À"
-#~ "´Ï´Ù."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr "E299: Safe ¸ðµâ¾øÀÌ´Â sandbox¿¡¼­ Perl evaluationÀÌ Á¦Çѵ˴ϴÙ"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "¿©·¯ ºöÀ¸·Î ÆíÁý(&M)"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "ÇϳªÀÇ ºöÀ¸·Î¸¸ ÆíÁý(&V)"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "ºöÀ¸·Î Diff"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "ºöÀ¸·Î ÆíÁý(&V)"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "ÇϳªÀÇ ºöÀ¸·Î¸¸ ÆíÁý - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "¼±ÅÃµÈ ÆÄÀÏ(µé)À» ºöÀ¸·Î ÆíÁý"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "ÇÁ·Î¼¼½º »ý¼º ¿¡·¯: gvimÀÌ path¿¡ ÀÖ´Â Áö È®ÀÎÇϼ¼¿ä!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll ¿¡·¯"
-
-#~ msgid "Path length too long!"
-#~ msgstr "°æ·Î°¡ ³Ê¹« ±é´Ï´Ù"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: ¸ð¸£´Â ±Û²Ã¼Â: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: ¸ð¸£´Â ±Û²Ã: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: ±Û²Ã \"%s\"Àº(´Â) °íÁ¤³ÐÀ̰¡ ¾Æ´Õ´Ï´Ù"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: %s ¶óÀ̺귯¸® ÇÔ¼ö¸¦ ·ÎµåÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: Hebrew´Â »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù: ÄÄÆÄÀÏ ¶§ Æ÷ÇÔµÇÁö ¾Ê¾Ò½À´Ï´Ù\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Farsi´Â »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù: ÄÄÆÄÀÏ ¶§ Æ÷ÇÔµÇÁö ¾Ê¾Ò½À´Ï´Ù\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: ArabicÀº »ç¿ëÇÒ ¼ö ¾ø½À´Ï´Ù: ÄÄÆÄÀÏ ¶§ Æ÷ÇÔµÇÁö ¾Ê¾Ò½À´Ï´Ù\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: \"%s\"Àº(´Â) µî·ÏµÈ ¼­¹ö¸íÀÌ ¾Æ´Õ´Ï´Ù"
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: µð½ºÇ÷¹À̸¦ ¿­ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: À߸øµÈ Ç¥Çö½ÄÀÌ ¹Þ¾ÆÁ³½À´Ï´Ù"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: ¿µ¿ªÀÌ º¸È£µÇ°í À־ ¼öÁ¤ÇÒ ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans´Â Àбâ Àü¿ë ÆÄÀÏÀ» ¹Ù²Ü ¼ö ¾ø½À´Ï´Ù"
-
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "\"%s\"¿¡ ´ëÇÑ ¾ÏÈ£ ۰¡ ÇÊ¿äÇÕ´Ï´Ù"
-
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines()´Â ¹®ÀÚ¿­ ¸ñ·ÏÀÌ ÇÊ¿äÇÕ´Ï´Ù"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: ÆÄÀ̽ã: I/O °´Ã¼ ÃʱâÈ­Áß ¿¡·¯°¡ »ý°å½À´Ï´Ù"
-
-#~ msgid "no such buffer"
-#~ msgstr "±×·± ¹öÆÛ´Â ¾ø½À´Ï´Ù"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "Áö¿öÁø âÀ» ÂüÁ¶ÇÏ·Á°í ÇÏ¿´½À´Ï´Ù"
-
-#~ msgid "readonly attribute"
-#~ msgstr "Àбâ Àü¿ë ¼Ó¼º"
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "ÆÛ¼­ À§Ä¡°¡ ¹öÆÛ ¹Û¿¡ ÀÖ½À´Ï´Ù"
-
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<%p¿¡ â °´Ã¼ (»èÁ¦µÊ)>"
-
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<%p¿¡ â °´Ã¼ (¸ð¸§)>"
-
-#~ msgid "<window %d>"
-#~ msgstr "<â %d>"
-
-#~ msgid "no such window"
-#~ msgstr "±×·± âÀº ¾ø½À´Ï´Ù"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "Áö¿öÁø ¹öÆÛ¸¦ ÂüÁ¶ÇÏ·Á°í ÇÏ¿´½À´Ï´Ù"
diff --git a/src/nvim/po/nb.po b/src/nvim/po/nb.po
index ce635e098c..b99e8ce465 100644
--- a/src/nvim/po/nb.po
+++ b/src/nvim/po/nb.po
@@ -2483,7 +2483,7 @@ msgstr "E216: Gruppen eller handlingen finnes ikke: %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Autokommandoer ---"
@@ -2507,7 +2507,7 @@ msgstr "E218: Nøsting av autokommandoer for dyp"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Autokommandoer for \"%s\""
#: ../fileio.c:7149
@@ -2699,11 +2699,6 @@ msgstr "E49: Ugyldig \"scroll\"-verdi"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3397,7 +3392,7 @@ msgstr "-q [feilfil] rediger fil med første feil"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4275,11 +4270,6 @@ msgstr "linje %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Ugyldig registernavn: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr ""
-"Vedlikeholder for norsk oversettelse: Øyvind A. Holm <sunny@sunbase.org>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Avbryt: "
@@ -5312,8 +5302,8 @@ msgstr "Advarsel: Region %s ikke støttet"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Leser affiksfil %s ..."
+msgid "Reading affix file %s..."
+msgstr "Leser affiksfil %s..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
@@ -5472,8 +5462,8 @@ msgstr "%s-verdi er forskjellig fra det som er bruk i en annen .aff-fil"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Leser ordlistefil %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Leser ordlistefil %s..."
#: ../spell.c:5611
#, c-format
@@ -5507,8 +5497,8 @@ msgstr "Ignorerte %d ord med ikke-ASCII-tegn i %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Leser ordfil %s ..."
+msgid "Reading word file %s..."
+msgstr "Leser ordfil %s..."
#: ../spell.c:6155
#, c-format
@@ -5578,8 +5568,8 @@ msgstr "Totalt antall ord: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Skriver forslagsfil %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "Skriver forslagsfil %s..."
#: ../spell.c:7707 ../spell.c:7927
#, c-format
@@ -5605,8 +5595,8 @@ msgstr ""
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Lagrer stavefil %s ..."
+msgid "Writing spell file %s..."
+msgstr "Lagrer stavefil %s..."
#: ../spell.c:7925
msgid "Done!"
diff --git a/src/nvim/po/nl.po b/src/nvim/po/nl.po
index ea609c0f69..56bcd94e79 100644
--- a/src/nvim/po/nl.po
+++ b/src/nvim/po/nl.po
@@ -2471,10 +2471,10 @@ msgstr "E216: onbekende groep of 'event': %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
#: ../fileio.c:6293
#, c-format
@@ -2495,8 +2495,8 @@ msgstr "E218: hierarchie van aanroepen autocommands te diep"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "%s 'Auto commands' voor \"%s\""
+msgid "%s Autocommands for \"%s\""
+msgstr "%s 'Autocommands' voor \"%s\""
#: ../fileio.c:7149
#, c-format
@@ -2685,11 +2685,6 @@ msgstr "E49: ongeldige scroll-grootte"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3394,7 +3389,7 @@ msgstr "-q [foutbestand] bewerk bestand dat eerste fout bevat"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4282,10 +4277,6 @@ msgstr "regel %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr ""
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Vertaald door: Erwin Poeze <erwin.poeze@gmail.com>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr ""
diff --git a/src/nvim/po/no.po b/src/nvim/po/no.po
index ce635e098c..b99e8ce465 100644
--- a/src/nvim/po/no.po
+++ b/src/nvim/po/no.po
@@ -2483,7 +2483,7 @@ msgstr "E216: Gruppen eller handlingen finnes ikke: %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Autokommandoer ---"
@@ -2507,7 +2507,7 @@ msgstr "E218: Nøsting av autokommandoer for dyp"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Autokommandoer for \"%s\""
#: ../fileio.c:7149
@@ -2699,11 +2699,6 @@ msgstr "E49: Ugyldig \"scroll\"-verdi"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3397,7 +3392,7 @@ msgstr "-q [feilfil] rediger fil med første feil"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4275,11 +4270,6 @@ msgstr "linje %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Ugyldig registernavn: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr ""
-"Vedlikeholder for norsk oversettelse: Øyvind A. Holm <sunny@sunbase.org>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Avbryt: "
@@ -5312,8 +5302,8 @@ msgstr "Advarsel: Region %s ikke støttet"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Leser affiksfil %s ..."
+msgid "Reading affix file %s..."
+msgstr "Leser affiksfil %s..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
@@ -5472,8 +5462,8 @@ msgstr "%s-verdi er forskjellig fra det som er bruk i en annen .aff-fil"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Leser ordlistefil %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Leser ordlistefil %s..."
#: ../spell.c:5611
#, c-format
@@ -5507,8 +5497,8 @@ msgstr "Ignorerte %d ord med ikke-ASCII-tegn i %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Leser ordfil %s ..."
+msgid "Reading word file %s..."
+msgstr "Leser ordfil %s..."
#: ../spell.c:6155
#, c-format
@@ -5578,8 +5568,8 @@ msgstr "Totalt antall ord: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Skriver forslagsfil %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "Skriver forslagsfil %s..."
#: ../spell.c:7707 ../spell.c:7927
#, c-format
@@ -5605,8 +5595,8 @@ msgstr ""
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Lagrer stavefil %s ..."
+msgid "Writing spell file %s..."
+msgstr "Lagrer stavefil %s..."
#: ../spell.c:7925
msgid "Done!"
diff --git a/src/nvim/po/pl.UTF-8.po b/src/nvim/po/pl.UTF-8.po
index 68cb9e72d5..a348bf6203 100644
--- a/src/nvim/po/pl.UTF-8.po
+++ b/src/nvim/po/pl.UTF-8.po
@@ -1,5 +1,4 @@
-# translation of pl.po to Polish
-# Polish Translation for Vim
+# Polish translation for Vim
#
# updated 2013 for vim-7.4
#
@@ -14,7 +13,7 @@ msgstr ""
"Last-Translator: Mikolaj Machowski <mikmach@wp.pl>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.0\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
@@ -2441,7 +2440,7 @@ msgstr "E216: Nie ma takiej grupy lub wydarzenia: %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Autokomendy ---"
@@ -2465,7 +2464,7 @@ msgstr "E218: zbyt głębokie zagnieżdżenie autokomend"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Autokomend dla \"%s\""
#: ../fileio.c:7149
@@ -2658,11 +2657,6 @@ msgstr "E49: Niewłaściwa wielkość przewinięcia"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3363,7 +3357,7 @@ msgstr "-q [errorfile] edytuj plik, zawierający pierwszy błąd"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -3555,7 +3549,7 @@ msgstr ""
#: ../main.c:2240
msgid "--startuptime <file>\tWrite startup timing messages to <file>"
msgstr ""
-"--startuptime <plik>\n"
+"--startuptime <plik> "
"Zapisz wiadomości o długości startu do <plik>"
#: ../main.c:2242
@@ -4243,10 +4237,6 @@ msgstr "wiersz %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Niewłaściwa nazwa rejestru: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Opiekun komunikatów: Mikołaj Machowski <mikmach@wp.pl>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Przerwanie: "
@@ -5288,8 +5278,8 @@ msgstr "Ostrzeżenie: region %s nie jest wspierany"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Czytam plik afiksów %s ..."
+msgid "Reading affix file %s..."
+msgstr "Czytam plik afiksów %s..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
@@ -5451,8 +5441,8 @@ msgstr "Wartość %s różni się od tej użytej w innym pliku .aff"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Czytam plik słownika %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Czytam plik słownika %s..."
#: ../spell.c:5611
#, c-format
@@ -5489,8 +5479,8 @@ msgstr "Zignorowałem %d słów ze znakami nie ASCII w %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Odczytuję plik wyrazów %s ..."
+msgid "Reading word file %s..."
+msgstr "Odczytuję plik wyrazów %s..."
#: ../spell.c:6155
#, c-format
@@ -5559,8 +5549,8 @@ msgstr "Całkowita liczba słów: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "ZapisujÄ™ plik sugestii %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "ZapisujÄ™ plik sugestii %s..."
#: ../spell.c:7707 ../spell.c:7927
#, c-format
@@ -5586,8 +5576,8 @@ msgstr "Ostrzeżenie: określono zarówno złożenia jak i NOBREAK"
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "ZapisujÄ™ plik sprawdzania pisowni %s ..."
+msgid "Writing spell file %s..."
+msgstr "ZapisujÄ™ plik sprawdzania pisowni %s..."
#: ../spell.c:7925
msgid "Done!"
diff --git a/src/nvim/po/pl.cp1250.po b/src/nvim/po/pl.cp1250.po
deleted file mode 100644
index 3fcdbfb87d..0000000000
--- a/src/nvim/po/pl.cp1250.po
+++ /dev/null
@@ -1,8264 +0,0 @@
-# translation of pl.po to Polish
-# Polish Translation for Vim
-#
-# updated 2013 for vim-7.4
-#
-# FIRST AUTHOR Marcin Dalecki <martin@dalecki.de>, 2000.
-# Mikolaj Machowski <mikmach@wp.pl>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013.
-msgid ""
-msgstr ""
-"Project-Id-Version: pl\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2010-08-10 18:15+0200\n"
-"Last-Translator: Mikolaj Machowski <mikmach@wp.pl>\n"
-"Language: pl\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=cp1250\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Lokalize 1.0\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
-"|| n%100>=20) ? 1 : 2);\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "nie mogê pobraæ wartoœci opcji"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "b³¹d wewnêtrzny: nieznany typ opcji"
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[Lista lokacji]"
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[Lista quickfix]"
-
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr "E855: Autokomendy spowodowa³y porzucenie komendy"
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: Nie mogê zarezerwowaæ bufora; zakoñczenie..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: Nie mogê zarezerwowaæ bufora; u¿ywam innego..."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: Nie wy³adowano ¿adnego bufora"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: Nie skasowano ¿adnego bufora"
-
-#: ../buffer.c:767
-msgid "E517: No buffers were wiped out"
-msgstr "E517: Nie wyrzucono ¿adnego bufora"
-
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "1 bufor wy³adowany"
-
-#: ../buffer.c:774
-#, c-format
-msgid "%d buffers unloaded"
-msgstr "wy³adowano %d buforów"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "1 bufor skasowany"
-
-#: ../buffer.c:779
-#, c-format
-msgid "%d buffers deleted"
-msgstr "%d buforów skasowano"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "wyrzucono 1 bufor "
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "wyrzucono %d buforów"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: Nie mogê wy³adowaæ ostatniego bufora"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: Nie znaleziono zmienionych buforów"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-msgid "E85: There is no listed buffer"
-msgstr "E85: Nie ma wylistowanych buforów"
-
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Bufor \"%<PRId64>\" nie istnieje"
-
-#: ../buffer.c:915
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: Nie mogê przejœæ poza ostatni bufor"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: Nie mogê przejœæ przed pierwszy bufor"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: Nie zapisano zmian w buforze %<PRId64> (wymuœ przez !)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: OSTRZE¯ENIE: Przepe³nienie listy nazw plików"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Nie znaleziono bufora %<PRId64>"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: Wielokrotne dopasowania dla %s"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: ¯aden bufor nie pasuje do %s"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "wiersz %<PRId64>"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: Bufor o tej nazwie ju¿ istnieje"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [Zmieniony]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[Nie edytowany]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[Nowy Plik]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[B³¹d odczytu]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[RO]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-msgid "[readonly]"
-msgstr "[tylko odczyt]"
-
-#: ../buffer.c:2524
-#, c-format
-msgid "1 line --%d%%--"
-msgstr "1 wiersz --%d%%--"
-
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> wiersze --%d%%--"
-
-#: ../buffer.c:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "wiersz %<PRId64> z %<PRId64> --%d%%-- kol "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-msgid "[No Name]"
-msgstr "[Bez nazwy]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "pomoc"
-
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[Pomoc]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[Podgl¹d]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "Wszystko"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "Dó³"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "Góra"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# Lista buforów:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr "[Notka]"
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- Znaki ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "Znaki dla %s:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " wiersz=%<PRId64> id=%d nazwa=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: Brak dwukropka"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: Niedozwolony tryb"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: oczekiwa³em na cyfrê"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Niedozwolony procent"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Nie mogê zró¿nicowaæ wiêcej ni¿ %<PRId64> buforów"
-
-#: ../diff.c:753
-msgid "E810: Cannot read or write temp files"
-msgstr "E810: Nie mogê otworzyæ lub zapisaæ plików tymczasowych"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: Nie mogê stworzyæ ró¿nic"
-
-#: ../diff.c:966
-msgid "E816: Cannot read patch output"
-msgstr "E816: Nie mogê odczytaæ wyjœcia pliku ³aty"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: Nie mogê wczytaæ wyjœcia ró¿nicy"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: Bie¿¹cy bufor nie jest w trybie ró¿nic"
-
-#: ../diff.c:2100
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E793: ¯aden inny bufor w trybie diff nie jest modyfikowalny"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: Brak innego bufora w trybie ró¿nic"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr ""
-"E101: Wiêcej ni¿ jeden bufor w trybie ró¿nicowania, nie wiem którego u¿yæ"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: Nie mogê znaleŸæ bufora \"%s\""
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: Bufor \"%s\" nie jest w trybie ró¿nicowania"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr "E787: Nieoczekiwana zmiana bufora"
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: Escape jest niedozwolone w dwugrafie"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: Nie znaleziono pliku rozk³adu klawiszy"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: Zastosowano :loadkeymap w niewczytanym pliku"
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr "E791: Pusty wpis keymap"
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " Dope³nianie s³ów kluczowych (^N^P)"
-
-#. 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 tryb (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " Dope³nianie pe³nych wierszy (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " Dope³nianie nazw plików (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " Dope³nianie znaczników (^]^N^P)"
-
-#: ../edit.c:88
-msgid " Path pattern completion (^N^P)"
-msgstr " Dope³nianie wzorców tropów (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " Dope³nianie definicji (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Dope³nianie ze s³owników (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " Dope³nianie z tezaurusa (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " Dope³nianie wiersza poleceñ (^V^N^P)"
-
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr "Dope³nianie zdefiniowane przez u¿ytkownika (^U^N^P)"
-
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " Omni uzupe³nianie (^O^N^P)"
-
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr "Propozycja pisowni (^L^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " Lokalne dope³nianie s³ów kluczowych (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "Dobi³em do koñca akapitu"
-
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr "E839: Funkcja uzupe³niania zmieni³a okno"
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr "E840: Funkcja uzupe³nania usunê³a tekst"
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "opcja 'dictionary' jest pusta"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "opcja 'thesaurus' jest pusta"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "Przegl¹dam s³ownik: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (wprowadzanie) Przewijanie (^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (zamiana) Przewijanie (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "Przegl¹dam: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "Przegl¹dam znaczniki."
-
-#: ../edit.c:4519
-msgid " Adding"
-msgstr " Dodajê"
-
-#. 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 "-- Szukam..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "Z powrotem na pierwotnym"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "Wyraz z innego wiersza"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "Jedyne dopasowanie"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "pasuje %d z %d"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "pasuje %d"
-
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: Nieoczekiwane znaki w :let"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: Indeks listy poza zakresem: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Nieokreœlona zmienna: %s"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: Brak ']'"
-
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: Argument %s musi byæ List¹"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Argument %s musi byæ List¹ lub S³ownikiem"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Nie mo¿na u¿yæ pustego klucza dla S³ownika"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: wymagana Lista"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: wymagany S³ownik"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: Zbyt wiele argumentów dla funkcji: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Klucz nie istnieje w S³owniku: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: Funkcja %s ju¿ istnieje; aby j¹ zamieniæ u¿yj !"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: istnieje ju¿ taki element S³ownika"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: wymagana Funcref"
-
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: Nie mo¿na u¿yæ [:] przy S³owniku"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: Z³y typ zmiennej dla %s="
-
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Nieznana funkcja: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: Niedozwolona nazwa zmiennej: %s"
-
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: U¿ycie Zmiennoprzecinkowej jako £añcucha"
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: Mniej celów ni¿ elementów Listy"
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: Wiêcej celów ni¿ elementów Listy"
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "Podwójny ; w liœcie zmiennych"
-
-#: ../eval.c:2078
-#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: Nie mogê wypisaæ zmiennych dla %s"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: Indeks mo¿e istnieæ tylko dla Listy lub S³ownika"
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:] musi byæ ostatnie"
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:] wymaga wartoœci listy"
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: Lista ma wiêcej elementów ni¿ cel"
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: Lista nie ma wystarczaj¹cej iloœci elementów"
-
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: Brak \"in\" po :for"
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Brak nawiasów: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: Nie istnieje zmienna: \"%s\""
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: zmienna zagnie¿d¿ona zbyt g³êboko dla (un)lock"
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: Brak ':' po '?'"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: Listê mogê porównaæ tylko z List¹"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: Nieprawid³owa operacja dla Listy"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: S³ownik mogê porównaæ tylko ze S³ownikiem"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: Nieprawid³owa operacja dla S³ownika"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Funcref mogê porównaæ tylko z Funcref"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: Nieprawid³owa operacja dla Funcref"
-
-#: ../eval.c:4277
-msgid "E804: Cannot use '%' with Float"
-msgstr "E804: Nie mogê u¿yæ '%' w Zmiennoprzecinkowej"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: Brak ')'"
-
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: Nie mo¿na zindeksowaæ Funcref"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: Brak nazwy opcji: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: Nieznana opcja: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: Brak cudzys³owu: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: Brak cudzys³owu: %s"
-
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Brakuj¹cy przecinek w Liœcie: '%s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: Brak zakoñczenia Listy ']': %s"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Brak dwukropka w S³owniku: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Powtórzony klucz w S³owniku: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Brakuj¹cy przecinek w S³owniku: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Brak koñca w S³owniku '}': %s"
-
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: Zmienna zagnie¿d¿ona zbyt g³êboko by pokazaæ"
-
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: Zbyt wiele argumentów dla funkcji %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Zbyt wiele argumentów dla funkcji %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Nieznana funkcja: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Za ma³o argumentów dla funkcji: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: U¿ycie <SID> poza kontekstem skryptu: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Wywo³anie funkcji \"dict\" bez S³ownika: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Wymagana Liczba lub Zmiennoprzecinkowa"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "argument add()"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: Za du¿o argumentów"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() mo¿e byæ u¿yte tylko w trybie Wprowadzania"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Klucz ju¿ istnieje: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "argument extend()"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "argument map()"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "argument filter()"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld wierszy: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: Nieznana funkcja: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "wywo³ano inputrestore() wiêcej razy ni¿ inputsave()"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "argument insert()"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: Zakres niedozwolony"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: Nieprawid³owy typ dla len()"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: Skok to zero"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: Pocz¹tek po koñcu"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<pusty>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "argument remove()"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: Za du¿o dowi¹zañ symbolicznych (pêtla?)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "argument reverse()"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "argument sort()"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "argument add()"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Funkcja porównywania w sort nie powiod³a siê"
-
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Funkcja porównywania w sort nie powiod³a siê"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(Niew³aœciwe)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: B³¹d zapisywania pliku tymczasowego"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: U¿ycie Zmiennoprzecinkowej jako Liczby"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: U¿ycie Funcref jako Liczby"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: U¿ycie Listy jako Liczby"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: U¿ycie S³ownika jako Liczby"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: U¿ycie Funcref jako £añcucha"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: U¿ycie Listy jako £añcucha"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: U¿ycie S³ownika jako £añcucha"
-
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Nieprawid³owy typ zmiennej dla: %s"
-
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Nie mogê usun¹æ zmiennej %s"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Nazwa Funcref musi siê zaczynaæ wielk¹ liter¹: %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: Nazwa zmiennej jest w konflikcie z istniej¹c¹ funkcj¹: %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: WartoϾ jest zablokowana: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Nieznane"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Nie mogê zmieniæ wartoœci %s"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: Zmienna zagnie¿d¿ona zbyt g³êboko by zrobiæ kopiê"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Nieznana funkcja: %s"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: Brak '(': %s"
-
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: Nie mo¿na tutaj u¿yæ g:"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Niedozwolony argument: %s"
-
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Powtórzona nazwa argumentu: %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: Brak :endfunction"
-
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Nazwa funkcji jest w konflikcie ze zmienn¹: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Nie mogê redefiniowaæ funkcji %s: jest w u¿yciu"
-
-#: ../eval.c:17604
-#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: Nazwa funkcji nie pasuje do nazwy skryptu: %s"
-
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: Wymagana jest nazwa funkcji"
-
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Nazwa funkcji musi rozpoczynaæ siê wielk¹ liter¹ lub zawieraæ "
-"dwukropek: %s"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr ""
-"E128: Nazwa funkcji musi rozpoczynaæ siê wielk¹ liter¹ lub zawieraæ "
-"dwukropek: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Nie mogê skasowaæ funkcji %s: jest w u¿yciu"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Zagnie¿d¿enie wywo³añ funkcji ponad 'maxfuncdepth'"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "wywo³ujê %s"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "porzucono %s"
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s zwraca #%<PRId64>"
-
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%s zwraca %s"
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "kontynuacja w %s"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return poza funkcj¹"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# zmienne globalne:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tOstatnie ustawienie przez "
-
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Brak starych plików"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, Hex %02x, Oktal %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, Hex %04x, Oktal %o"
-
-#: ../ex_cmds.c:146
-#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, Hex %08x, Oktal %o"
-
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: Przeniesienie wierszy na siebie samych"
-
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "1 wiersz przeniesiony"
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> wiersze przeniesione"
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> wierszy przefiltrowanych"
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: Autokomendy *Filter* nie mog¹ zmieniaæ bie¿¹cego bufora"
-
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[Brak zapisu od czasu ostatniej zmiany]\n"
-
-#: ../ex_cmds.c:1424
-#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s w wierszu: "
-
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: Zbyt wiele b³êdów; pomijam resztê pliku"
-
-#: ../ex_cmds.c:1458
-#, c-format
-msgid "Reading viminfo file \"%s\"%s%s%s"
-msgstr "Wczytujê plik viminfo \"%s\"%s%s%s"
-
-#: ../ex_cmds.c:1460
-msgid " info"
-msgstr " informacja"
-
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " zak³adki"
-
-#: ../ex_cmds.c:1462
-msgid " oldfiles"
-msgstr " stare pliki"
-
-#: ../ex_cmds.c:1463
-msgid " FAILED"
-msgstr " NIE POWIOD£O SIÊ"
-
-#. 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: Plik viminfo jest niezapisywalny: %s"
-
-#: ../ex_cmds.c:1626
-#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: Nie mogê zapisaæ pliku viminfo %s!"
-
-#: ../ex_cmds.c:1635
-#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "Zapisujê plik viminfo \"%s\""
-
-#. Write the info:
-#: ../ex_cmds.c:1720
-#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# Ten plik viminfo zosta³ wygenerowany przez Vima %s.\n"
-
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# Mo¿esz go ostro¿nie edytowaæ!\n"
-"\n"
-
-#: ../ex_cmds.c:1723
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# WartoϾ 'encoding' w czasie zapisu tego pliku\n"
-
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "Niedopuszczalny pocz¹tkowy znak"
-
-#: ../ex_cmds.c:2162
-msgid "Write partial file?"
-msgstr "Zapisaæ czêœciowo plik?"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: Stosuj ! do zapisania czêœciowo bufora"
-
-#: ../ex_cmds.c:2281
-#, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "Nadpisaæ istniej¹cy plik \"%s\"?"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr "Plik wymiany \"%s\" istnieje, czy go nadpisaæ?"
-
-#: ../ex_cmds.c:2326
-#, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E768: Plik wymiany istnieje: %s (wymuœ poprzez :silent!)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Brak nazwy pliku dla bufora %<PRId64>"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: Plik niezapisany: Zapis jest wy³¹czony opcj¹ 'write'"
-
-#: ../ex_cmds.c:2434
-#, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"opcja 'readonly' nastawiona dla \"%s\".\n"
-"Czy chcesz go pomimo tego zapisaæ?"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-"Prawa pliku \"%s\" s¹ tylko do odczytu.\n"
-"Mimo to byæ mo¿e uda siê zmieniæ ten plik.\n"
-"Chcesz spróbowaæ?"
-
-#: ../ex_cmds.c:2451
-#, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "E505: \"%s\" jest tylko do odczytu (dodaj ! aby wymusiæ)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: Autokomendy nieoczekiwanie skasowa³y nowy bufor %s"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: nienumeryczny argument dla :z"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: Komendy pow³oki s¹ niedozwolone w rvim"
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: Wzorce regularne nie mog¹ byæ rozgraniczane literami"
-
-#: ../ex_cmds.c:3964
-#, c-format
-msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
-msgstr "zamieñ na %s (y/n/a/q/l/^E/^Y)?"
-
-#: ../ex_cmds.c:4379
-msgid "(Interrupted) "
-msgstr "(Przerwane) "
-
-#: ../ex_cmds.c:4384
-msgid "1 match"
-msgstr "1 pasuje"
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "1 podstawienie "
-
-#: ../ex_cmds.c:4387
-#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> dopasowañ"
-
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> podstawieñ"
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr " w 1 wierszu"
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr " w %<PRId64> wierszach"
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: Nie mogê wykonaæ :global rekursywnie"
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: Brak wzorca regularnego w :global"
-
-# c-format
-#: ../ex_cmds.c:4508
-#, c-format
-msgid "Pattern found in every line: %s"
-msgstr "Wzorzec znaleziono w ka¿dym wierszu: %s"
-
-#: ../ex_cmds.c:4510
-#, c-format
-msgid "Pattern not found: %s"
-msgstr "Nie znaleziono wzorca: %s"
-
-#: ../ex_cmds.c:4587
-msgid ""
-"\n"
-"# Last Substitute String:\n"
-"$"
-msgstr ""
-"\n"
-"# Ostatni podstawiany ci¹g:\n"
-"$"
-
-#: ../ex_cmds.c:4679
-msgid "E478: Don't panic!"
-msgstr "E478: Nie panikuj!"
-
-#: ../ex_cmds.c:4717
-#, c-format
-msgid "E661: Sorry, no '%s' help for %s"
-msgstr "E661: Przykro mi, brak '%s' pomocy dla %s"
-
-#: ../ex_cmds.c:4719
-#, c-format
-msgid "E149: Sorry, no help for %s"
-msgstr "E149: Przykro mi, ale brak pomocy o %s"
-
-#: ../ex_cmds.c:4751
-#, c-format
-msgid "Sorry, help file \"%s\" not found"
-msgstr "Przykro mi, nie ma pliku pomocy \"%s\""
-
-#: ../ex_cmds.c:5323
-#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Nie jest katalogiem: %s"
-
-#: ../ex_cmds.c:5446
-#, c-format
-msgid "E152: Cannot open %s for writing"
-msgstr "E152: Nie mogê otworzyæ %s do zapisu"
-
-#: ../ex_cmds.c:5471
-#, c-format
-msgid "E153: Unable to open %s for reading"
-msgstr "E153: Nie mogê otworzyæ %s do odczytu"
-
-#: ../ex_cmds.c:5500
-#, c-format
-msgid "E670: Mix of help file encodings within a language: %s"
-msgstr "E670: Mieszanka kodowañ w pliku pomocy w ramach jêzyka: %s"
-
-#: ../ex_cmds.c:5565
-#, c-format
-msgid "E154: Duplicate tag \"%s\" in file %s/%s"
-msgstr "E154: Powtórzony znacznik \"%s\" w pliku %s/%s"
-
-#: ../ex_cmds.c:5687
-#, c-format
-msgid "E160: Unknown sign command: %s"
-msgstr "E160: Nieznana komenda znaku: %s"
-
-#: ../ex_cmds.c:5704
-msgid "E156: Missing sign name"
-msgstr "E156: Brak nazwy znaku"
-
-#: ../ex_cmds.c:5746
-msgid "E612: Too many signs defined"
-msgstr "E612: Zbyt wiele nazw znaków"
-
-#: ../ex_cmds.c:5813
-#, c-format
-msgid "E239: Invalid sign text: %s"
-msgstr "E239: Niew³aœciwy tekst znaku: %s"
-
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
-#, c-format
-msgid "E155: Unknown sign: %s"
-msgstr "E155: Nieznany znak: %s"
-
-#: ../ex_cmds.c:5877
-msgid "E159: Missing sign number"
-msgstr "E159: Brak numeru znaku"
-
-#: ../ex_cmds.c:5971
-#, c-format
-msgid "E158: Invalid buffer name: %s"
-msgstr "E158: Niew³aœciwa nazwa bufora: %s"
-
-#: ../ex_cmds.c:6008
-#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: Niew³aœciwe ID znaku: %<PRId64>"
-
-#: ../ex_cmds.c:6066
-msgid " (not supported)"
-msgstr "(nie wspomagane)"
-
-#: ../ex_cmds.c:6169
-msgid "[Deleted]"
-msgstr "[Skasowano]"
-
-#: ../ex_cmds2.c:139
-msgid "Entering Debug mode. Type \"cont\" to continue."
-msgstr "Wchodzê w tryb odpluskwiania. WprowadŸ \"cont\" aby kontynuowaæ."
-
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
-#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "wiersz %<PRId64>: %s"
-
-#: ../ex_cmds2.c:145
-#, c-format
-msgid "cmd: %s"
-msgstr "cmd: %s"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Punkt kontrolny w \"%s%s\" wiersz %<PRId64>"
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: Nie znaleziono punktu kontrolnego: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "Nie okreœlono ¿adnych punktów kontrolnych"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s wiersz %<PRId64>"
-
-#: ../ex_cmds2.c:942
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: Pierwsze u¿ycie \":profile start {fname}\""
-
-#: ../ex_cmds2.c:1269
-#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "Zachowaæ zmiany w \"%s\"?"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "Bez Tytu³u"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: Nie zapisano zmian w buforze \"%s\""
-
-#: ../ex_cmds2.c:1480
-msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
-msgstr "OSTRZE¯ENIE: Nieoczekiwane wejœcie w inny bufor (sprawdŸ autokomendy)"
-
-#: ../ex_cmds2.c:1826
-msgid "E163: There is only one file to edit"
-msgstr "E163: Tylko jeden plik w edycji"
-
-#: ../ex_cmds2.c:1828
-msgid "E164: Cannot go before first file"
-msgstr "E164: Nie mo¿na przejœæ przed pierwszy plik"
-
-#: ../ex_cmds2.c:1830
-msgid "E165: Cannot go beyond last file"
-msgstr "E165: Nie mo¿na przejœæ za ostatni plik"
-
-#: ../ex_cmds2.c:2175
-#, c-format
-msgid "E666: compiler not supported: %s"
-msgstr "E666: nie wspierany kompilator: %s"
-
-#: ../ex_cmds2.c:2257
-#, c-format
-msgid "Searching for \"%s\" in \"%s\""
-msgstr "Szukanie \"%s\" w \"%s\""
-
-#: ../ex_cmds2.c:2284
-#, c-format
-msgid "Searching for \"%s\""
-msgstr "Szukanie \"%s\""
-
-#: ../ex_cmds2.c:2307
-#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "nie znaleziono w 'runtimepath': \"%s\""
-
-#: ../ex_cmds2.c:2472
-#, c-format
-msgid "Cannot source a directory: \"%s\""
-msgstr "Nie mo¿na wczytaæ katalogu: \"%s\""
-
-#: ../ex_cmds2.c:2518
-#, c-format
-msgid "could not source \"%s\""
-msgstr "nie mog³em wczytaæ \"%s\""
-
-#: ../ex_cmds2.c:2520
-#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "wiersz: %<PRId64> nie mog³em wczytaæ \"%s\""
-
-#: ../ex_cmds2.c:2535
-#, c-format
-msgid "sourcing \"%s\""
-msgstr "wczytywanie \"%s\""
-
-#: ../ex_cmds2.c:2537
-#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "wiersz %<PRId64>: wczytywanie \"%s\""
-
-#: ../ex_cmds2.c:2693
-#, c-format
-msgid "finished sourcing %s"
-msgstr "skoñczono wczytywanie %s"
-
-#: ../ex_cmds2.c:2765
-msgid "modeline"
-msgstr "modeline"
-
-#: ../ex_cmds2.c:2767
-msgid "--cmd argument"
-msgstr "--cmd argument"
-
-#: ../ex_cmds2.c:2769
-msgid "-c argument"
-msgstr "-c argument"
-
-#: ../ex_cmds2.c:2771
-msgid "environment variable"
-msgstr "zmienna œrodowiskowa"
-
-#: ../ex_cmds2.c:2773
-msgid "error handler"
-msgstr "obs³uga b³êdu"
-
-#: ../ex_cmds2.c:3020
-msgid "W15: Warning: Wrong line separator, ^M may be missing"
-msgstr "W15: OSTRZE¯ENIE: Niew³aœciwy separator wierszy, pewnie brak ^M"
-
-#: ../ex_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: u¿yto :scriptencoding poza wczytywanym plikiem"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: u¿yto :finish poza wczytywanym plikiem"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "Bie¿¹cy %sjêzyk: \"%s\""
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: Nie mogê ustawiæ jêzyka na \"%s\""
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "Wchodzê w tryb Ex. WprowadŸ \"visual\" aby przejœæ do trybu Normal."
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: Na koñcu pliku"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: Komenda zbyt rekursywna"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: Nie znaleziono wyj¹tku: %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "Koniec wczytywanego pliku"
-
-#: ../ex_docmd.c:1086
-msgid "End of function"
-msgstr "Koniec funkcji"
-
-#: ../ex_docmd.c:1628
-msgid "E464: Ambiguous use of user-defined command"
-msgstr ""
-"E464: Niejednoznaczne zastosowanie komendy zdefiniowanej przez u¿ytkownika"
-
-#: ../ex_docmd.c:1638
-msgid "E492: Not an editor command"
-msgstr "E492: Nie jest komend¹ edytora"
-
-#: ../ex_docmd.c:1729
-msgid "E493: Backwards range given"
-msgstr "E493: Dano wsteczny zakres"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "Dano wsteczny zakres; zamiana jest mo¿liwa"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: Stosuj w lub w>>"
-
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: Przykro mi, ale ta komenda nie jest dostêpna w tej wersji"
-
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: Tylko pojedyncza nazwa pliku dozwolona"
-
-#: ../ex_docmd.c:4238
-msgid "1 more file to edit. Quit anyway?"
-msgstr "1 wiêcej plik do edycji. Mimo to wyjœæ?"
-
-#: ../ex_docmd.c:4242
-#, c-format
-msgid "%d more files to edit. Quit anyway?"
-msgstr "jeszcze %d plików do edycji. Mimo to wyjœæ?"
-
-#: ../ex_docmd.c:4248
-msgid "E173: 1 more file to edit"
-msgstr "E173: 1 wiêcej plik do edycji"
-
-#: ../ex_docmd.c:4250
-#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: jeszcze %<PRId64> plików do edycji"
-
-#: ../ex_docmd.c:4320
-msgid "E174: Command already exists: add ! to replace it"
-msgstr "E174: Komenda ju¿ istnieje; aby j¹ przedefiniowaæ stosuj !"
-
-#: ../ex_docmd.c:4432
-msgid ""
-"\n"
-" Name Args Range Complete Definition"
-msgstr ""
-"\n"
-" Nazwa Arg. Zak. GotowoϾ Definicja"
-
-#: ../ex_docmd.c:4516
-msgid "No user-defined commands found"
-msgstr "Nie znaleziono komend zdefiniowanych przez u¿ytkownika"
-
-#: ../ex_docmd.c:4538
-msgid "E175: No attribute specified"
-msgstr "E175: Nie okreœlono atrybutu"
-
-#: ../ex_docmd.c:4583
-msgid "E176: Invalid number of arguments"
-msgstr "E176: Niew³aœciwa iloœæ argumentów"
-
-#: ../ex_docmd.c:4594
-msgid "E177: Count cannot be specified twice"
-msgstr "E177: Mno¿nik nie mo¿e byæ podany dwukrotnie"
-
-#: ../ex_docmd.c:4603
-msgid "E178: Invalid default value for count"
-msgstr "E178: Niew³aœciwa domyœlna wartoœæ mno¿nika"
-
-#: ../ex_docmd.c:4625
-msgid "E179: argument required for -complete"
-msgstr "E179: -complete wymaga argumentu"
-
-#: ../ex_docmd.c:4635
-#, c-format
-msgid "E181: Invalid attribute: %s"
-msgstr "E181: Niew³aœciwy atrybut: %s"
-
-#: ../ex_docmd.c:4678
-msgid "E182: Invalid command name"
-msgstr "E182: Niew³aœciwa nazwa komendy"
-
-#: ../ex_docmd.c:4691
-msgid "E183: User defined commands must start with an uppercase letter"
-msgstr ""
-"E183: Komendy zdefiniowane przez u¿ytkownika musz¹ rozpoczynaæ siê du¿¹ "
-"liter¹"
-
-#: ../ex_docmd.c:4696
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E841: Nazwa zastrze¿ona, nie mo¿na jej u¿yæ w komendzie u¿ytkownika"
-
-#: ../ex_docmd.c:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: Nie ma takiej komendy u¿ytkownika: %s"
-
-#: ../ex_docmd.c:5219
-#, c-format
-msgid "E180: Invalid complete value: %s"
-msgstr "E180: Niew³aœciwa wartoœæ dope³niania: %s"
-
-#: ../ex_docmd.c:5225
-msgid "E468: Completion argument only allowed for custom completion"
-msgstr ""
-"E468: Argument depe³niania dozwolony wy³¹cznie dla dope³niania u¿ytkownika"
-
-#: ../ex_docmd.c:5231
-msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Dope³nianie u¿ytkownika wymaga funkcji jako argumentu"
-
-#: ../ex_docmd.c:5257
-#, c-format
-msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Nie mogê znaleŸæ zestawu kolorów '%s'"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "Witaj u¿ytkowniku Vima!"
-
-#: ../ex_docmd.c:5431
-msgid "E784: Cannot close last tab page"
-msgstr "E784: Nie mogê zamkn¹æ ostatniej karty"
-
-#: ../ex_docmd.c:5462
-msgid "Already only one tab page"
-msgstr "Jest ju¿ tylko jedna karta"
-
-#: ../ex_docmd.c:6004
-#, c-format
-msgid "Tab page %d"
-msgstr "Karta %d"
-
-#: ../ex_docmd.c:6295
-msgid "No swap file"
-msgstr "Brak pliku wymiany"
-
-#: ../ex_docmd.c:6478
-msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
-msgstr ""
-"E747: Nie mogê zmieniæ katalogu, bufor zosta³ zmodyfikowany (dodaj ! aby "
-"wymusiæ)"
-
-#: ../ex_docmd.c:6485
-msgid "E186: No previous directory"
-msgstr "E186: Nie ma poprzedniego katalogu"
-
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: Nieznany"
-
-#: ../ex_docmd.c:6610
-msgid "E465: :winsize requires two number arguments"
-msgstr "E465: :winsize wymaga dwóch argumentów numerycznych"
-
-#: ../ex_docmd.c:6655
-msgid "E188: Obtaining window position not implemented for this platform"
-msgstr ""
-"E188: Pozyskiwanie pozycji okna nie jest zaimplementowane dla tego systemu"
-
-#: ../ex_docmd.c:6662
-msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos wymaga dwóch argumentów numerycznych"
-
-#: ../ex_docmd.c:7241
-#, c-format
-msgid "E739: Cannot create directory: %s"
-msgstr "E739: Nie mogê utworzyæ katalogu: %s"
-
-#: ../ex_docmd.c:7268
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: \"%s\" istnieje (wymuœ poprzez !)"
-
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: Nie mogê otworzyæ \"%s\" do zapisu"
-
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: Argument musi byæ liter¹ albo cudzys³owem w przód/ty³"
-
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: Rekursywne zastosowanie :normal za g³êbokie"
-
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: Brak nazwy zamiennego pliku do podstawienia pod '#'"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: brak nazwy pliku autokomend do podstawienia pod \"<afile>\""
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: brak numeru bufora autokomend do podstawienia pod \"<abuf>\""
-
-#: ../ex_docmd.c:7861
-msgid "E497: no autocommand match name to substitute for \"<amatch>\""
-msgstr "E497: brak nazwy dopasowania autokomend pod \"<amatch>\""
-
-#: ../ex_docmd.c:7870
-msgid "E498: no :source file name to substitute for \"<sfile>\""
-msgstr "E498: brak nazwy pliku :source do postawienia pod \"<sfile>\""
-
-#: ../ex_docmd.c:7876
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E842: brak numeru linii by u¿yæ z \"<slnum>\""
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: Pusta nazwa pliku dla '%' lub '#', dzia³a tylko z \":p:h\""
-
-#: ../ex_docmd.c:7905
-msgid "E500: Evaluates to an empty string"
-msgstr "E500: Wynikiem jest pusty ci¹g"
-
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: Nie mogê otworzyæ pliku viminfo do odczytu"
-
-#: ../ex_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: Nie mo¿na ':throw' wyj¹tków z prefiksem 'Vim'"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "Wyj¹tek: %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "Wyj¹tek zakoñczony: %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "Wyj¹tek odrzucony: %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, wiersz %<PRId64>"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "Wyj¹tek przechwycony: %s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr "%s zosta³ zawieszony"
-
-#: ../ex_eval.c:679
-#, c-format
-msgid "%s resumed"
-msgstr "%s przywrócony"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr "%s odrzucony"
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "Wyj¹tek"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "B³¹d i przerwanie"
-
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "B³¹d"
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "Przerwanie"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: zbyt g³êbokie zagnie¿d¿enie :if"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :endif bez :if"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :else bez :if"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :elseif bez :if"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: wielokrotne :else"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :elseif po :else"
-
-#: ../ex_eval.c:941
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: zbyt g³êbokie zagnie¿d¿enie :while/:for"
-
-#: ../ex_eval.c:1028
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :continue bez :while lub :for"
-
-#: ../ex_eval.c:1061
-msgid "E587: :break without :while or :for"
-msgstr "E587: :break bez :while lub :for"
-
-#: ../ex_eval.c:1102
-msgid "E732: Using :endfor with :while"
-msgstr "E732: U¿ycie :endfor z :while"
-
-#: ../ex_eval.c:1104
-msgid "E733: Using :endwhile with :for"
-msgstr "E733: U¿ycie :endwhile z :for"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: zbyt g³êbokie zagnie¿d¿enie :try"
-
-#: ../ex_eval.c:1317
-msgid "E603: :catch without :try"
-msgstr "E603: :catch bez :try"
-
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
-msgid "E604: :catch after :finally"
-msgstr "E604: :catch za :finally"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :finally bez :try"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: wielokrotne :finally"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :endtry bez :try"
-
-#: ../ex_eval.c:2026
-msgid "E193: :endfunction not inside a function"
-msgstr "E193: :endfunction poza funkcj¹"
-
-#: ../ex_getln.c:1643
-msgid "E788: Not allowed to edit another buffer now"
-msgstr "E788: Nie mo¿na teraz edytowaæ innego bufora"
-
-#: ../ex_getln.c:1656
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E811: Nie mo¿na teraz zmieniaæ informacji o buforze"
-
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "nazwa znacznika"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " pokrewny plik\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "opcja 'history' jest zerowa"
-
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s Historia (od najnowszych po najstarsze):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "Wiersz poleceñ"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "Szukany ci¹g"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "Wyra¿enie"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "Wiersz wprowadzeñ"
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar przekracza d³ugoœæ polecenia"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: Aktywny widok lub bufor skasowany"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: œcie¿ka za d³uga by uzupe³niæ"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Niew³aœciwy trop: '**[numer]' musi byæ na koñcu tropu lub po nim musi "
-"byæ '%s'."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Nie mogê znaleŸæ katalogu \"%s\" w cdpath"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Nie mogê znaleŸæ pliku \"%s\" w tropie"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Katalogu \"%s\" nie ma wiêcej w cdpath"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Pliku \"%s\" nie ma wiêcej w tropie"
-
-#: ../fileio.c:137
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E812: Autokomendy zmieni³y bufor lub jego nazwê"
-
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "Niedopuszczalna nazwa pliku"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "jest katalogiem"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "nie jest plikiem"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[Nowy Plik]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr "[Nowy KATALOG]"
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr "[Za du¿y plik]"
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[Nie dozwolono]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200: Autokomendy *ReadPre zrobi³y plik nieodczytywalnym"
-
-#: ../fileio.c:655
-msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: Autokomendy *ReadPre nie mog¹ zmieniaæ bie¿¹cego bufora"
-
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: Wczytywanie ze stdin...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202: Nie mo¿na otworzyæ pliku utworzonego przez przemianê!"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[fifo/socket]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[fifo]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[socket]"
-
-#. or character special
-#: ../fileio.c:1801
-msgid "[character special]"
-msgstr "[specjalny znak]"
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[brak CR]'"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[d³ugie wiersze rozdzielane]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[NIE przemienione]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[przemienione]"
-
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[B£¥D W PRZEMIANIE w linii %<PRId64>]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[NIEDOZWOLONY BAJT w wierszu %<PRId64>]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[B£ÊDY W ODCZYCIE]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "Nie mogê znaleŸæ pliku tymczasowego w celu przemiany"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "Nieudana przemiana z 'charconvert'"
-
-#: ../fileio.c:2113
-msgid "can't read output of 'charconvert'"
-msgstr "nie mogê odczytaæ wyjœcia z 'charconvert'"
-
-#: ../fileio.c:2437
-msgid "E676: No matching autocommands for acwrite buffer"
-msgstr "E676: Brak pasuj¹cych autokomend dla bufora acwrite"
-
-#: ../fileio.c:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr ""
-"E203: Autokomendy skasowa³y lub wy³adowa³y bufor przeznaczony do zapisu"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: Autokomenda zmieni³a liczbê wierszy w nieoczekiwany sposób"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "nie jest plikiem lub zapisywalnym przyrz¹dem"
-
-#: ../fileio.c:2601
-msgid "is read-only (add ! to override)"
-msgstr "jest tylko do odczytu (wymuœ poprzez !)"
-
-#: ../fileio.c:2886
-msgid "E506: Can't write to backup file (add ! to override)"
-msgstr "E506: Nie mogê zapisaæ do pliku zabezpieczenia (wymuœ przez !)"
-
-#: ../fileio.c:2898
-msgid "E507: Close error for backup file (add ! to override)"
-msgstr "E507: B³¹d podczas zamykania pliku zabezpieczenia (wymuœ przez !)"
-
-#: ../fileio.c:2901
-msgid "E508: Can't read file for backup (add ! to override)"
-msgstr "E508: Nie mogê odczytaæ pliku w celu zabezpieczenia (wymuœ przez !)"
-
-#: ../fileio.c:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr "E509: Nie mogê stworzyæ pliku zabezpieczenia (wymuœ przez !)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr "E510: Nie mogê zrobiæ pliku zabezpieczenia (wymuœ przez !)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: Nie mogê znaleŸæ pliku tymczasowego do zapisania"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr "E213: Nie mogê przemieniæ (u¿yj ! by zapisaæ bez przemiany)"
-
-#: ../fileio.c:3169
-msgid "E166: Can't open linked file for writing"
-msgstr "E166: Nie mogê otworzyæ pod³¹czonego pliku do zapisu"
-
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: Nie mogê otworzyæ pliku do zapisu"
-
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: Fsync nie powiód³ siê"
-
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Zamkniêcie siê nie powiod³o"
-
-#: ../fileio.c:3436
-msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr ""
-"E513: B³¹d zapisu, przemiana siê nie powiod³a (opró¿nij 'fenc' aby wymusiæ)"
-
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: B³¹d zapisu, przemiana siê nie powiod³a w wierszu %<PRId64> (opró¿nij "
-"'fenc' by wymusiæ)"
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: b³¹d w zapisie (mo¿e system plików jest przepe³niony?)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr " B£¥D W PRZEMIANIE"
-
-#: ../fileio.c:3509
-#, c-format
-msgid " in line %<PRId64>;"
-msgstr " w wierszu %<PRId64>;"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[Urz¹dzenie]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[Nowy]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr " [a]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " do³¹czono"
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr " [w]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " zapisano"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Patchmode: nie mogê zapisaæ oryginalnego pliku"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: patchmode: nie mogê stworzyæ pustego oryginalnego pliku"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: Nie mogê skasowaæ pliku zabezpieczenia"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"OSTRZE¯ENIE: Oryginalny plik mo¿e zostaæ utracony lub uszkodzony\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "nie wychodŸ edytora, dopóki plik nie zosta³ poprawnie zapisany!"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[format dos-a]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[format maca]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[format unixa]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 wiersz, "
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> wierszy, "
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 znak"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> znaków"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-msgid "[Incomplete last line]"
-msgstr "[Niekompletny ostatni wiersz]"
-
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "OSTRZE¯ENIE: Plik zmieni³ siê od czasu ostatniego odczytu!!!"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "Czy naprawdê chcesz go zapisaæ"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: B³¹d zapisywania do \"%s\""
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: B³¹d w trakcie zamykania \"%s\""
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: B³¹d odczytu \"%s\""
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: Autokomenda FileChangedShell skasowa³a bufor"
-
-#: ../fileio.c:4894
-#, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Plik \"%s\" nie jest d³u¿ej dostêpny"
-
-#: ../fileio.c:4906
-#, c-format
-msgid ""
-"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
-"well"
-msgstr ""
-"W12: OSTRZE¯ENIE: Plik \"%s\" zmieni³ siê od czasu rozpoczêcia edycji, bufor "
-"w Vimie równie¿ zosta³ zmieniony"
-
-#: ../fileio.c:4907
-msgid "See \":help W12\" for more info."
-msgstr "Zobacz \":help W12\" dla dalszych informacji."
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: OSTRZE¯ENIE: Plik \"%s\" zmieni³ siê od czasu rozpoczêcia edycji"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "Zobacz \":help W11\" dla dalszych informacji."
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr ""
-"W16: OSTRZE¯ENIE: Tryb pliku \"%s\" zmieni³ siê od czasu rozpoczêcia edycji"
-
-#: ../fileio.c:4915
-msgid "See \":help W16\" for more info."
-msgstr "Zobacz \":help W16\" dla dalszych informacji."
-
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: OSTRZE¯ENIE: Plik \"%s\" zosta³ stworzony po rozpoczêciu edycji"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "OSTRZE¯ENIE"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"&OK\n"
-"&Za³aduj Plik"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: Nie mo¿na przygotowaæ prze³adowania \"%s\""
-
-#: ../fileio.c:5078
-#, c-format
-msgid "E321: Could not reload \"%s\""
-msgstr "E321: Nie mo¿na prze³adowaæ \"%s\""
-
-#: ../fileio.c:5601
-msgid "--Deleted--"
-msgstr "--Skasowano--"
-
-#: ../fileio.c:5732
-#, c-format
-msgid "auto-removing autocommand: %s <buffer=%d>"
-msgstr "auto-usuwanie autokomendy: %s <buffer=%d>"
-
-#. the group doesn't exist
-#: ../fileio.c:5772
-#, c-format
-msgid "E367: No such group: \"%s\""
-msgstr "E367: Nie ma takiej grupy: \"%s\""
-
-#: ../fileio.c:5897
-#, c-format
-msgid "E215: Illegal character after *: %s"
-msgstr "E215: Niedopuszczalny znak po *: %s"
-
-#: ../fileio.c:5905
-#, c-format
-msgid "E216: No such event: %s"
-msgstr "E216: Nie ma takiego wydarzenia: %s"
-
-#: ../fileio.c:5907
-#, c-format
-msgid "E216: No such group or event: %s"
-msgstr "E216: Nie ma takiej grupy lub wydarzenia: %s"
-
-#. Highlight title
-#: ../fileio.c:6090
-msgid ""
-"\n"
-"--- Auto-Commands ---"
-msgstr ""
-"\n"
-"--- Autokomendy ---"
-
-#: ../fileio.c:6293
-#, c-format
-msgid "E680: <buffer=%d>: invalid buffer number "
-msgstr "E680: <buffer=%d>: niew³aœciwy numer bufora"
-
-#: ../fileio.c:6370
-msgid "E217: Can't execute autocommands for ALL events"
-msgstr "E217: Nie mo¿na wykonywaæ autokomend dla wydarzeñ ALL"
-
-#: ../fileio.c:6393
-msgid "No matching autocommands"
-msgstr "Brak pasuj¹cych autokomend"
-
-#: ../fileio.c:6831
-msgid "E218: autocommand nesting too deep"
-msgstr "E218: zbyt g³êbokie zagnie¿d¿enie autokomend"
-
-#: ../fileio.c:7143
-#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "%s Autokomend dla \"%s\""
-
-#: ../fileio.c:7149
-#, c-format
-msgid "Executing %s"
-msgstr "Wykonujê %s"
-
-#: ../fileio.c:7211
-#, c-format
-msgid "autocommand %s"
-msgstr "autokomenda %s"
-
-#: ../fileio.c:7795
-msgid "E219: Missing {."
-msgstr "E219: Brak {."
-
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: Brak }."
-
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: Nie znaleziono zwiniêcia"
-
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: Nie mo¿na utworzyæ zwiniêcia przy bie¿¹cej 'foldmethod'"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: Nie mo¿na skasowaæ zwiniêcia przy bie¿¹cej 'foldmethod'"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld wierszy zwiniêto "
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: Dodaj do bufora odczytu"
-
-#: ../getchar.c:2040
-msgid "E223: recursive mapping"
-msgstr "E223: rekursywne przyporz¹dkowanie"
-
-#: ../getchar.c:2849
-#, c-format
-msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: istnieje ju¿ globalny skrót dla %s"
-
-#: ../getchar.c:2852
-#, c-format
-msgid "E225: global mapping already exists for %s"
-msgstr "E225: istnieje ju¿ globalne przyporz¹dkowanie dla %s"
-
-#: ../getchar.c:2952
-#, c-format
-msgid "E226: abbreviation already exists for %s"
-msgstr "E226: istnieje ju¿ skrót dla %s"
-
-#: ../getchar.c:2955
-#, c-format
-msgid "E227: mapping already exists for %s"
-msgstr "E227: istnieje ju¿ przyporz¹dkowanie dla %s"
-
-#: ../getchar.c:3008
-msgid "No abbreviation found"
-msgstr "Nie znaleziono skrótu"
-
-#: ../getchar.c:3010
-msgid "No mapping found"
-msgstr "Nie znaleziono przyporz¹dkowania"
-
-#: ../getchar.c:3974
-msgid "E228: makemap: Illegal mode"
-msgstr "E228: makemap: Niedopuszczalny tryb"
-
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--Brak wierszy w buforze--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: Przerwanie komendy"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: wymagany argument"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: po \\ powinno byæ /, ? lub &"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr ""
-"E11: Niedozwolone w oknie wiersza poleceñ; <CR> wykonuje, CTRL-C opuszcza"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: Komenda niedozwolona z exrc/vimrc w bie¿¹cym szukaniu katalogu lub "
-"znacznika"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: Brak :endif"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: Brak :endtry"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: Brak :endwhile"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: Brak :endfor"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile bez :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor bez :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Plik istnieje (wymuœ poprzez !)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: Komenda nie powiod³a siê"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: B³¹d wewnêtrzny"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Przerwane"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Niew³aœciwy adres"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Niew³aœciwy argument"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Niew³aœciwy argument: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Niew³aœciwe wyra¿enie: %s"
-
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Niew³aœciwy zakres"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Niew³aœciwa komenda"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" jest katalogiem"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Niew³aœciwa wielkoœæ przewiniêcia"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Wywo³anie z biblioteki nie powiod³o siê dla \"%s()\""
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: Zak³adka ma niew³aœciwy numer wiersza"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Zak³adka nienastawiona"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Nie mogê wykonaæ zmian, 'modifiable' jest wy³¹czone"
-
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Zbyt g³êbokie zagnie¿d¿enie skryptów"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Brak pliku zamiany"
-
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Nie ma takiego skrótu"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: Niedozwolone !"
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUI nie mo¿e byæ u¿yte: Nie w³¹czono podczas kompilacji"
-
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Brak takiej nazwy grupy podœwietlania: %s"
-
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: Nie wprowadzono jeszcze ¿adnego tekstu"
-
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Nie ma poprzedniego wiersza poleceñ"
-
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Nie ma takiego przyporz¹dkowania"
-
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Brak dopasowañ"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Brak dopasowañ: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Brak nazwy pliku"
-
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Brak poprzedniego podstawieniowego wyra¿enia regularnego"
-
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Brak poprzedniej komendy"
-
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Brak poprzedniego wyra¿enia regularnego"
-
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Zakres niedozwolony"
-
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: Brak miejsca"
-
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Nie mogê stworzyæ pliku %s"
-
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Nie mogê pobraæ nazwy pliku tymczasowego"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Nie mogê otworzyæ pliku %s"
-
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: Nie mogê odczytaæ pliku %s"
-
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: Nie zapisano od ostatniej zmiany (wymuœ przez !)"
-
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Brak zapisu od czasu ostatniej zmiany]\n"
-
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: Zerowy argument"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Oczekujê liczby"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Nie mogê otworzyæ pliku b³êdów %s"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Pamiêæ wyczerpana!"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Nie znaleziono wzorca"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Nie znaleziono wzorca: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: Argument musi byæ dodatni"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Nie mo¿na przejœæ do poprzedniego katalogu"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Brak B³êdów"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Brak listy lokacji"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: Popsuty ci¹g wzorca"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: Zepsuty program wyra¿eñ regularnych"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: opcja 'readonly' jest ustawiona (wymuœ poprzez !)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Nie mogê zmieniæ zmiennej tylko do odczytu \"%s\""
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Nie mogê ustawiæ zmiennej w piaskownicy: \"%s\""
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: B³¹d w trakcie czytania pliku b³êdów"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Niedozwolone w piaskownicy"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Niedozwolone w tym miejscu"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: Ustawianie trybu ekranu niewspomagane"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Niew³aœciwa wielkoœæ przewiniêcia"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: opcja 'shell' jest pusta"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Nie mog³em wczytaæ danych znaku!"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: B³¹d podczas zamykania pliku wymiany"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: stos znaczników jest pusty"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Komenda jest zbyt skomplikowana"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Zbyt d³uga nazwa"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: Zbyt wiele ["
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: Zbyt wiele nazw plików"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Nadstêpne znaczki"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Nieznana zak³adka"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Nie mog¹ rozwin¹æ znaków wieloznacznych"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' nie mo¿e byæ mniejsze ni¿ 'winminheight'"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' nie mo¿e byæ mniejsze ni¿ 'winminwidth'"
-
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: B³¹d w trakcie zapisu"
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Zerowy licznik"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: U¿ycie <SID> poza kontekstem skryptu"
-
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: B³¹d wewnêtrzny: %s"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: Wzorzec u¿ywa wiêcej pamiêci ni¿ 'maxmempattern'"
-
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: pusty bufor"
-
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Niew³aœciwy wzorzec wyszukiwania lub delimiter"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Plik jest za³adowany w innym buforze"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: Nie ustawiono opcji '%s'"
-
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: Niew³aœciwa nazwa rejestru"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "szukanie dobi³o GÓRY; kontynuacja od KOÑCA"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "szukanie dobi³o KOÑCA; kontynuacja od GÓRY"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: Brak dwukropka"
-
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: Niedozwolona czêœæ"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: oczekiwa³em na cyfrê"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "Strona %d"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "Brak tekstu do drukowania"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "Drukujê stronê %d (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr " Kopia %d z %d"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "Wydrukowano: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "Drukowanie odwo³ane"
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: Nie mo¿na zapisaæ do wyjœciowego pliku PostScriptu"
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: Nie mogê otworzyæ pliku \"%s\""
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: Nie mo¿na odczytaæ pliku zasobów PostScriptu \"%s\""
-
-#: ../hardcopy.c:1772
-#, c-format
-msgid "E618: file \"%s\" is not a PostScript resource file"
-msgstr "E618: plik \"%s\" nie jest plikiem zasobów PostScriptu"
-
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: plik \"%s\" nie jest wspieranym plikiem zasobów PostScriptu"
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: \"%s\" nieprawid³owa wersja pliku zasobów"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: Niekompatybilne kodowanie wielobajtowe i zestaw znaków."
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: printmbcharset nie mo¿e byæ pusty przy kodowaniu wielobajtowym."
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr "E675: Nie okreœlono domyœlnej czcionki dla drukowania wielobajtowego."
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: Nie mo¿na otworzyæ pliku PostScript do wyjœcia"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: Nie mogê otworzyæ pliku \"%s\""
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: Nie mo¿na znaleŸæ pliku zasobów PostScriptu \"prolog.ps\""
-
-#: ../hardcopy.c:2593
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: Nie mo¿na znaleŸæ pliku zasobów PostScriptu \"cidfont.ps\""
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: Nie mo¿na znaleŸæ pliku zasobów PostScriptu \"%s.ps\""
-
-#: ../hardcopy.c:2654
-#, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: Nie mo¿na przekonwertowaæ by drukowaæ kodowanie \"%s\""
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "Przesy³am do drukarki..."
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: Drukowanie pliku PostScript nie powiod³o siê"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "Zadanie drukowanie przes³ane."
-
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "Dodaj now¹ bazê danych"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "Zapytane o wzorzec"
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "Poka¿ ten komunikat"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "Zabij po³¹czenie"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "Ponów wszelkie po³¹czenia"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "Poka¿ po³¹czenia"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Zastosowanie: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "Ta komenda cscope nie wspomaga podzielenia okna.\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Zastosowanie: cstag <ident>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: nie znaleziono znacznika"
-
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) b³¹d: %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s nie jest katalogiem lub poprawn¹ baz¹ danych cscope"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "Dodano bazê danych cscope %s"
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: b³¹d odczytu po³¹czenia z cscope %<PRId64>"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: nieznany typ szukania cscope"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: Nie mog³em stworzyæ potoku do cscope"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: Nie mog³em utworzyæ rozwidlenia dla cscope"
-
-#: ../if_cscope.c:849
-msgid "cs_create_connection setpgid failed"
-msgstr "nie powiod³o siê setpgid cs_create_connection"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "wykonanie cs_create_connection nie powiod³o siê"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen dla to_fp nie powiod³o siê"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen dla fr_fp nie powiod³o siê"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: Nie mog³em stworzyæ procesu cscope"
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: brak po³¹czenia z cscope"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: nieprawid³owa flaga cscopequickfix %c dla %c"
-
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: brak dopasowañ dla zapytania cscope %s o %s"
-
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "komendy cscope:\n"
-
-#: ../if_cscope.c:1150
-#, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %s%*s (U¿ycie: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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"
-" c: znajdŸ funkcje wywo³uj¹ce tê funkcjê\n"
-" d: znajdŸ funkcje wywo³ywane przez tê funkcjê\n"
-" e: znajdŸ ten wzorzec egrep\n"
-" f: znajdŸ ten plik\n"
-" g: znajdŸ tê definicjê\n"
-" i: znajdŸ pliki w³¹czaj¹ce (#include) ten plik\n"
-" s: znajdŸ ten symbol C\n"
-" t: znajdŸ ten ³añcuch znaków\n"
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: nie dodano duplikatu bazy danych cscope"
-
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: nie ma po³¹czenia %s z cscope"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "po³¹czenie %s z cscope zosta³o zamkniête"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: b³¹d krytyczny w cs_manage_matches"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Znacznik cscope: %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # wiersz"
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "nazwa pliku / kontekst / wiersz\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: B³¹d cscope: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "Wszystkie bazy danych cscope prze³adowano"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "brak po³¹czeñ z cscope\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid nazwa bazy danych przedsionek tropu\n"
-
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "Nieznany argument opcji"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "Zbyt wiele argumentów"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "Brak argumentu po"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "Œmiecie po argumencie opcji"
-
-#: ../main.c:152
-msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
-msgstr ""
-"Zbyt wiele argumentów \"+komenda\", \"-c komenda\" lub \"--cmd komenda\""
-
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "Niew³aœciwy argument dla"
-
-#: ../main.c:294
-#, c-format
-msgid "%d files to edit\n"
-msgstr "%d plików do edycji\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "Próba ponownego otworzenia pliku skryptu: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "Nie mogê otworzyæ do odczytu: \""
-
-#: ../main.c:1393
-msgid "Cannot open for script output: \""
-msgstr "Nie mogê otworzyæ dla wyjœcia skryptu: \""
-
-#: ../main.c:1622
-msgid "Vim: Warning: Output is not to a terminal\n"
-msgstr "Vim: OSTRZE¯ENIE: Wyjœcie nie jest terminalem\n"
-
-#: ../main.c:1624
-msgid "Vim: Warning: Input is not from a terminal\n"
-msgstr "Vim: OSTRZE¯ENIE: Wejœcie nie pochodzi z terminala\n"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "linia poleceñ pre-vimrc"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: Nie mogê czytaæ z \"%s\""
-
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"Dalsze informacje poprzez: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[plik ..] edytuj zadane pliki"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- czytaj tekst ze stdin"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t znacznik edytuj plik, w którym dany znacznik jest zdefiniowany"
-
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [errorfile] edytuj plik, zawieraj¹cy pierwszy b³¹d"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"u¿ycie:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [argumenty]"
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" lub:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"Argumenty:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tTylko nazwy plików po tym"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tNie rozwijaj znaków specjalnych"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tTryb vi (jak \"vi\")"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tTryb ex (jak \"ex\")"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr "-E\t\t\tUsprawniony tryb Ex"
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tCichy tryb (t³a) (tylko dla \"ex\")"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tTryb ró¿nic (jak \"vimdiff\")"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tTryb ³atwy (jak \"evim\", bez trybów)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tTryb wy³¹cznie do odczytu (jak \"view\")"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tTryb ograniczenia (jak \"rvim\")"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\tModyfikacje (zapisywanie plików) niedozwolone"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tZakaz modyfikacji tekstu"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tTryb binarny"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tTryb lisp"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tB¹dŸ zgodny z Vi: 'compatible'"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tB¹dŸ niezupe³nie zgodny z Vi: 'nocompatible'"
-
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr "-V[N][nazwap]\t\tGadatliwy [poziom N] [zapisuj wiadomoœci do nazwap]"
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tTryb odpluskwiania"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tZamiast pliku wymiany, u¿ywaj tylko pamiêci"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tWylicz pliki wymiany i zakoñcz"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (z nazw¹ pliku)\tOdtwórz za³aman¹ sesjê"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tTo¿same z -r"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\trozpocznij w trybie arabskim"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\trozpocznij w trybie hebrajskim"
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\trozpocznij w trybie farsi"
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminal>\tUstaw typ terminala na <terminal>"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tU¿yj <vimrc> zamiast jakiegokolwiek .vimrc"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tNie ³aduj skryptów wtyczek"
-
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tOtwórz N kart (domyœlnie: po jednej dla ka¿dego pliku)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\tOtwórz N okien (domyœlnie: po jednym dla ka¿dego pliku)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\ttak samo jak -o tylko dziel okno pionowo"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tZacznij na koñcu pliku"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\tZacznij w wierszu <lnum>"
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr ""
-"-cmd <command>\t\tWykonaj komendê <command> przed za³adowaniem "
-"jakiegokolwiek pliku vimrc"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr ""
-"-c <command>\t\tWykonaj komendê <command> po za³adowaniu pierwszego pliku"
-
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <sesja>\t\tWczytaj plik <sesja> po za³adowaniu pierwszego pliku"
-
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <scriptin>\tWczytuj komendy trybu normalnego z pliku <scriptin>"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr ""
-"-w <scriptout>\tDo³¹cz wszystkie wprowadzane komendy do pliku <scriptout>"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr ""
-"-W <scriptout>\tZapisuj wszystkie wprowadzane komendy do pliku <scriptout>"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr ""
-"--startuptime <plik>\n"
-"Zapisz wiadomoœci o d³ugoœci startu do <plik>"
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tU¿ywaj <viminfo> zamiast .viminfo"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h lub --help\twyœwietl Pomoc (czyli tê wiadomoœæ) i zakoñcz"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\twyœwietl informacjê o wersji i zakoñcz"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "Brak zak³adek"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: ¯adna zak³adka nie pasuje do \"%s\""
-
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"zak³. wiersz kol plik/tekst"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-" skok wiersz kol plik/tekst"
-
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-"\n"
-"zmieñ wrsz. kol tekst"
-
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Zak³adki w plikach:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Lista odniesieñ (pocz¹wszy od najnowszych):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Historia zak³adek w plikach (od najnowszych po najstarsze):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "Brak '>'"
-
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: blok nie by³ zablokowany"
-
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: B³¹d w trakcie czytania pliku wymiany"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: B³¹d odczytu pliku wymiany"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: B³¹d szukania w pliku wymiany"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: B³¹d zapisu w pliku wymiany"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: Plik wymiany ju¿ istnieje (atak symlink?)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: Nie otrzyma³em bloku nr 0?"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: Nie otrzyma³em bloku nr 1?"
-
-#: ../memline.c:377
-msgid "E298: Didn't get block nr 2?"
-msgstr "E298: Nie otrzyma³em bloku nr 2?"
-
-#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: Ojej, zgubi³em plik wymiany!!!"
-
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: Nie mog³em zmieniæ nazwy pliku wymiany"
-
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr ""
-"E303: Nie mogê otworzyæ pliku wymiany dla \"%s\"; odtworzenie niemo¿liwe"
-
-#: ../memline.c:666
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_upd_block(): Nie otrzyma³em bloku 0??"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: Nie znaleziono pliku wymiany dla %s"
-
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr "WprowadŸ numer pliku wymiany, którego u¿yæ (0 by wyjœæ): "
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: Nie mogê otworzyæ %s"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "Nie mogê odczytaæ bloku 0 z "
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"Mo¿e nie wykonano zmian albo Vim nie zaktualizowa³ pliku wymiany."
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " nie mo¿e byæ stosowany z t¹ wersj¹ Vima.\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "U¿yj Vima w wersji 3.0.\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %s nie wygl¹da na plik wymiany Vima"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " nie mo¿e byæ stosowany na tym komputerze.\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr "Ten plik zosta³ stworzony na "
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-",\n"
-"lub plik zosta³ uszkodzony."
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr ""
-" zosta³ uszkodzony (wielkoœæ strony jest mniejsza ni¿ najmniejsza wartoœæ).\n"
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "U¿ywam pliku wymiany \"%s\""
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "Oryginalny plik \"%s\""
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: OSTRZE¯ENIE: Oryginalny plik móg³ byæ zmieniony"
-
-#: ../memline.c:1061
-#, c-format
-msgid "E309: Unable to read block 1 from %s"
-msgstr "E309: Nie mogê odczytaæ bloku 1 z %s"
-
-#: ../memline.c:1065
-msgid "???MANY LINES MISSING"
-msgstr "???BRAKUJE WIELU WIERSZY"
-
-#: ../memline.c:1076
-msgid "???LINE COUNT WRONG"
-msgstr "???LICZNIK WIERSZY NIEZGODNY"
-
-#: ../memline.c:1082
-msgid "???EMPTY BLOCK"
-msgstr "???PUSTY BLOK"
-
-#: ../memline.c:1103
-msgid "???LINES MISSING"
-msgstr "???BRAKUJE WIERSZY"
-
-#: ../memline.c:1128
-#, c-format
-msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: Niew³aœciwe ID bloku 1 (mo¿e %s nie jest plikiem .swp?)"
-
-#: ../memline.c:1133
-msgid "???BLOCK MISSING"
-msgstr "???BRAK BLOKU"
-
-#: ../memline.c:1147
-msgid "??? from here until ???END lines may be messed up"
-msgstr "??? od tego miejsca po ???KONIEC wiersze mog¹ byæ pomieszane"
-
-#: ../memline.c:1164
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? od tego miejsca po ???KONIEC wiersze mog¹ byæ w³o¿one/skasowane"
-
-#: ../memline.c:1181
-msgid "???END"
-msgstr "???KONIEC"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: Przerwanie odtwarzania"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr "E312: Wykryto b³êdy podczas odtwarzania; od których wierszy zacz¹æ ???"
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "Zobacz \":help E312\" dla dalszych informacji."
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr ""
-"Odtwarzanie zakoñczono. Powinieneœ sprawdziæ czy wszystko jest w porz¹dku."
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(Mo¿esz chcieæ zapisaæ ten plik pod inn¹ nazw¹\n"
-
-#: ../memline.c:1252
-msgid "and run diff with the original file to check for changes)"
-msgstr "i wykonaæ diff z oryginalnym plikiem aby sprawdziæ zmiany)"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr "Odzyskiwanie zakoñczone. Zawartoœæ bufora jest równa zawartoœci pliku."
-
-#: ../memline.c:1255
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"\n"
-"Mo¿esz teraz chcieæ usun¹æ plik .swp.\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "Znalezione pliki wymiany:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr " W bie¿¹cym katalogu:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " U¿ywam podanej nazwy:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " W katalogu "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- ¿aden --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " posiadany przez: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " data: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " data: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [po Vimie wersja 3.0]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [nie wygl¹da na plik wymiany Vima]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " nazwa pliku: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" zmieniono: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "TAK"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "nie"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" u¿ytkownik: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " nazwa hosta: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" nazwa hosta: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" ID procesu: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (dalej dzia³a)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [nie do u¿ytku na tym komputerze]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [nieodczytywalny]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [nieotwieralny]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: Nie mogê zabezpieczyæ, bo brak pliku wymiany"
-
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "Plik zabezpieczono"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: Nieudane zabezpieczenie"
-
-#: ../memline.c:1819
-#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: niew³aœciwy lnum: %<PRId64>"
-
-#: ../memline.c:1851
-#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: nie znaleziono wiersza %<PRId64>"
-
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: niepoprawne id wskaŸnika bloku 3"
-
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "stack_idx powinien byæ 0"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: Zaktualizowano zbyt wiele bloków?"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: niepoprawne id wskaŸnika bloku 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "blok nr 1 skasowany?"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Nie mogê znaleŸæ wiersza %<PRId64>"
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: niepoprawne id bloku odniesienia"
-
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "pe_line_count wynosi zero"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: numer wiersza poza zakresem: %<PRId64> jest poza koñcem"
-
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: liczba wierszy niepoprawna w bloku %<PRId64>"
-
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "WielkoϾ stosu wzrasta"
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: niepoprawne id bloku odniesienia 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr "E773: Pêtla dowi¹zañ dla \"%s\""
-
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: UWAGA"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"Znalaz³em plik wymiany o nazwie \""
-
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "Podczas otwierania pliku \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " NOWSZE od pliku wymiany!\n"
-
-#: ../memline.c:3244
-#, fuzzy
-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."
-msgstr ""
-"\n"
-"(1) Pewnie inny program obrabia ten sam plik.\n"
-" Jeœli tak, b¹dŸ ostro¿ny, aby nie skoñczyæ z dwoma\n"
-" ró¿nymi wersjami tego samego pliku po zmianach.\n"
-
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " Zakoñcz lub ostro¿nie kontynuuj.\n"
-
-#: ../memline.c:3246
-msgid "(2) An edit session for this file crashed.\n"
-msgstr "(2) Sesja edycji dla pliku za³ama³a siê.\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " Jeœli tak, to u¿yj \":recover\" lub \"vim -r "
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"\"\n"
-" aby odzyskaæ zmiany (zobacz \":help recovery)\").\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " Jeœli ju¿ to zrobi³eœ, usuñ plik wymiany \""
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"\"\n"
-" aby unikn¹æ tej wiadomoœci.\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "Plik wymiany \""
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "\" ju¿ istnieje!"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "VIM - UWAGA"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "Plik wymiany ju¿ istnieje!"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"&Otwórz Read-Only\n"
-"&Edytuj pomimo\n"
-"O&dtwórz\n"
-"&Zakoñcz\n"
-"&Porzuæ"
-
-#: ../memline.c:3467
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"&Otwórz Read-Only\n"
-"&Edytuj pomimo\n"
-"O&dtwórz\n"
-"&Usuñ\n"
-"&Zakoñcz\n"
-"&Porzuæ"
-
-#.
-#. * 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
-msgid "E326: Too many swap files found"
-msgstr "E326: Znaleziono zbyt wiele plików wymiany"
-
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Brak pamiêci! (rezerwacja %<PRIu64> bajtów)"
-
-#: ../menu.c:62
-msgid "E327: Part of menu-item path is not sub-menu"
-msgstr "E327: Czêœæ tropu punktu menu nie okreœla podmenu"
-
-#: ../menu.c:63
-msgid "E328: Menu only exists in another mode"
-msgstr "E328: Menu istnieje tylko w innym trybie"
-
-#: ../menu.c:64
-#, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: Nie ma menu \"%s\""
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-msgid "E792: Empty menu name"
-msgstr "E792: Pusta nazwa menu"
-
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: Trop menu nie mo¿e prowadziæ do podmenu"
-
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: Nie wolno dodawaæ punktów menu wprost do paska menu"
-
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: Separator nie mo¿e byæ czêœci¹ tropu menu"
-
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- Menu ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: Trop menu musi prowadziæ do punktu menu"
-
-#: ../menu.c:1330
-#, c-format
-msgid "E334: Menu not found: %s"
-msgstr "E334: Nie znaleziono menu: %s"
-
-#: ../menu.c:1396
-#, c-format
-msgid "E335: Menu not defined for %s mode"
-msgstr "E335: Menu nie jest zdefiniowane dla trybu %s"
-
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: Trop menu musi prowadziæ do podmenu"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: Nie znaleziono menu - sprawdŸ nazwy menu"
-
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "Wykryto b³¹d podczas przetwarzania %s:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "wiersz %4ld:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: Niew³aœciwa nazwa rejestru: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Opiekun komunikatów: Miko³aj Machowski <mikmach@wp.pl>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "Przerwanie: "
-
-#: ../message.c:988
-msgid "Press ENTER or type command to continue"
-msgstr "Naciœnij ENTER lub wprowadŸ komendê aby kontynuowaæ"
-
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s wiersz %<PRId64>"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- Wiêcej --"
-
-#: ../message.c:2398
-msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr " SPACE/d/j: ekran/strona/wiersz w dó³, b/u/k: do góry, q: zakoñcz"
-
-#: ../message.c:3021 ../message.c:3031
-msgid "Question"
-msgstr "Pytanie"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"&Tak\n"
-"&Nie"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Tak\n"
-"&Nie\n"
-"&Zakoñcz"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"&Tak\n"
-"&Nie\n"
-"Zapisz &wszystkie\n"
-"&Odrzuæ wszystkie\n"
-"&Zakoñcz"
-
-#: ../message.c:3058
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: Za ma³o argumentów dla printf()"
-
-#: ../message.c:3119
-msgid "E807: Expected Float argument for printf()"
-msgstr "E807: Spodziewany argument Zmiennoprzecinkowy w printf()"
-
-#: ../message.c:3873
-msgid "E767: Too many arguments to printf()"
-msgstr "E767: Za du¿o argumentów dla printf()"
-
-#: ../misc1.c:2256
-msgid "W10: Warning: Changing a readonly file"
-msgstr "W10: OSTRZE¯ENIE: Zmiany w pliku tylko do odczytu"
-
-#: ../misc1.c:2537
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr "Wpisz numer i <Enter> lub wybierz mysz¹ (pusta wartoœæ anuluje): "
-
-#: ../misc1.c:2539
-msgid "Type number and <Enter> (empty cancels): "
-msgstr "Wpisz numer i <Enter> (puste anuluje): "
-
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "1 wiersz wiêcej"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "1 wiersz mniej"
-
-#: ../misc1.c:2593
-#, c-format
-msgid "%<PRId64> more lines"
-msgstr "dodano %<PRId64> wierszy"
-
-#: ../misc1.c:2596
-#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "usuniêto %<PRId64> wierszy"
-
-#: ../misc1.c:2599
-msgid " (Interrupted)"
-msgstr " (Przerwane)"
-
-#: ../misc1.c:2635
-msgid "Beep!"
-msgstr "Biiip!"
-
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "Wywo³ujê pow³okê do wykonania: \"%s\""
-
-#: ../normal.c:183
-msgid "E349: No identifier under cursor"
-msgstr "E349: Brak identyfikatora pod kursorem"
-
-#: ../normal.c:1866
-msgid "E774: 'operatorfunc' is empty"
-msgstr "E774: 'operatorfunc' jest pusta"
-
-#: ../normal.c:2637
-msgid "Warning: terminal cannot highlight"
-msgstr "OSTRZE¯ENIE: terminal nie wykonuje podœwietlania"
-
-#: ../normal.c:2807
-msgid "E348: No string under cursor"
-msgstr "E348: Brak ci¹gu pod kursorem"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: Nie mogê skasowaæ zwiniêcia z bie¿¹c¹ 'foldmethod'"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: lista zmian (changelist) jest pusta"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr "E662: Na pocz¹tku listy zmian"
-
-#: ../normal.c:5901
-msgid "E663: At end of changelist"
-msgstr "E663: Na koñcu listy zmian"
-
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "wprowadŸ :quit<Enter> zakoñczenie programu"
-
-#: ../ops.c:248
-#, c-format
-msgid "1 line %sed 1 time"
-msgstr "1 wiersz %sed 1 raz"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 wiersz %sed %d razy"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> wierszy %sed 1 raz"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> wierszy %sed %d razy"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> wierszy do wciêcia... "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "1 wiersz wciêty "
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> wierszy wciêtych "
-
-#: ../ops.c:938
-msgid "E748: No previously used register"
-msgstr "E748: Brak poprzednio u¿ytego rejestru"
-
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "nie mogê skopiowaæ, mimo to kasujê"
-
-#: ../ops.c:1929
-msgid "1 line changed"
-msgstr "1 wiersz zmieniono"
-
-#: ../ops.c:1931
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> wierszy zmieniono"
-
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "skopiowano blok 1 wiersza"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "1 wiersz skopiowano"
-
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "%<PRId64> wierszy skopiowanych"
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> wierszy skopiowanych"
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353: Pusty rejestr %s"
-
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- Rejestry ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "Niedozwolona nazwa rejestru"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# Rejestry:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: Nieznany typ rejestru %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Kolumn; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Wybrano %s%<PRId64> z %<PRId64> Wierszy; %<PRId64> z %<PRId64> S³ów; "
-"%<PRId64> z %<PRId64> Bajtów"
-
-#: ../ops.c:5105
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Wybrano %s%<PRId64> z %<PRId64> Wierszy; %<PRId64> z %<PRId64> S³ów; "
-"%<PRId64> z %<PRId64> Znaków; %<PRId64> z %<PRId64> Bajtów"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Kol %s z %s; Wiersz %<PRId64> z %<PRId64>; S³owo %<PRId64> z %<PRId64>; Bajt "
-"%<PRId64> z %<PRId64>"
-
-#: ../ops.c:5133
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"Kol %s z %s; Wiersz %<PRId64> z %<PRId64>; S³owo %<PRId64> z %<PRId64>; Znak "
-"%<PRId64> z %<PRId64>; Bajt %<PRId64> z %<PRId64>"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> dla BOM)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Strona %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "Dziêki za lot Vimem"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: Nieznana opcja"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: Opcja nie jest wspomagana"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: Niedozwolone w modeline"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr "E846: Kod klucza nie jest ustawiony"
-
-#: ../option.c:2924
-msgid "E521: Number required after ="
-msgstr "E521: Po = wymagany jest numer"
-
-#: ../option.c:3226 ../option.c:3864
-msgid "E522: Not found in termcap"
-msgstr "E522: Nie znaleziono w termcap"
-
-#: ../option.c:3335
-#, c-format
-msgid "E539: Illegal character <%s>"
-msgstr "E539: Niedozwolony znak <%s>"
-
-#: ../option.c:3862
-msgid "E529: Cannot set 'term' to empty string"
-msgstr "E529: Nie mogê ustawiæ 'term' na pusty ci¹g"
-
-#: ../option.c:3885
-msgid "E589: 'backupext' and 'patchmode' are equal"
-msgstr "E589: 'backupext' i 'patchmode' s¹ to¿same"
-
-#: ../option.c:3964
-msgid "E834: Conflicts with value of 'listchars'"
-msgstr "E834: Konflikty wartoœci 'listchars'"
-
-#: ../option.c:3966
-msgid "E835: Conflicts with value of 'fillchars'"
-msgstr "E835: Konflikty wartoœci 'fillchars'"
-
-#: ../option.c:4163
-msgid "E524: Missing colon"
-msgstr "E524: Brak dwukropka"
-
-#: ../option.c:4165
-msgid "E525: Zero length string"
-msgstr "E525: Ci¹g o zerowej d³ugoœci"
-
-#: ../option.c:4220
-#, c-format
-msgid "E526: Missing number after <%s>"
-msgstr "E526: Brak numeru po <%s>"
-
-#: ../option.c:4232
-msgid "E527: Missing comma"
-msgstr "E527: Brak przecinka"
-
-#: ../option.c:4239
-msgid "E528: Must specify a ' value"
-msgstr "E528: Musi okreœlaæ wartoœæ '"
-
-#: ../option.c:4271
-msgid "E595: contains unprintable or wide character"
-msgstr "E595: zawiera niewyœwietlalny lub szeroki znak"
-
-#: ../option.c:4469
-#, c-format
-msgid "E535: Illegal character after <%c>"
-msgstr "E535: Niedozwolony znak po <%c>"
-
-#: ../option.c:4534
-msgid "E536: comma required"
-msgstr "E536: wymagany przecinek"
-
-#: ../option.c:4543
-#, c-format
-msgid "E537: 'commentstring' must be empty or contain %s"
-msgstr "E537: 'commentstring' musi byæ pusty lub zawieraæ %s"
-
-#: ../option.c:4928
-msgid "E540: Unclosed expression sequence"
-msgstr "E540: Niedomkniêty ci¹g wyra¿eñ"
-
-#: ../option.c:4932
-msgid "E541: too many items"
-msgstr "E541: zbyt wiele elementów"
-
-#: ../option.c:4934
-msgid "E542: unbalanced groups"
-msgstr "E542: niezbalansowane grupy"
-
-#: ../option.c:5148
-msgid "E590: A preview window already exists"
-msgstr "E590: okno podgl¹du ju¿ istnieje"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: Arabski wymaga UTF-8, zrób ':set encoding=utf-8'"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: Potrzebujê przynajmniej %d wierszy"
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: Potrzebujê przynajmniej %d kolumn"
-
-#: ../option.c:6011
-#, c-format
-msgid "E355: Unknown option: %s"
-msgstr "E355: Nieznana opcja: %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
-#, c-format
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: Wymagana Liczba: &%s = '%s'"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- Kody terminala ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- Globalne wartoœci opcji ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- Lokalne wartoœci opcji ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- Opcje ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: B£¥D get_varp"
-
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': Brak pasuj¹cego znaku dla %s"
-
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': Dodatkowe znaki po œredniku: %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Nie mogê wykonaæ pow³oki "
-
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"pow³oka zwróci³a "
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-"\n"
-"Nie mogê uzyskaæ kontekstu bezpieczeñstwa dla"
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-"\n"
-"Nie mo¿na uzyskaæ kontekstu bezpieczeñstwa dla"
-
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = \"%s\""
-
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Nie mogê znaleŸæ pliku \"%s\" w tropie"
-
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: Zbyt wiele %%%c w ci¹gu formatuj¹cym"
-
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: Nieoczekiwane %%%c w ci¹gu formatuj¹cym"
-
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: Brak ] w ci¹gu formatuj¹cym"
-
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: Niewspomagane %%%c w ci¹gu formatuj¹cym"
-
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: Niepoprawne %%%c w prefiksie ci¹gu formatuj¹cego"
-
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: Niepoprawne %%%c w ci¹gu formatuj¹cym"
-
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: 'errorformat' nie zawiera wzorca"
-
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: Pusta nazwa katalogu lub jej brak"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: Nie ma wiêcej elementów"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d z %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (wiersz skasowany)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: Na dole stosu quickfix"
-
-#: ../quickfix.c:1869
-msgid "E381: At top of quickfix stack"
-msgstr "E381: Na górze stosu quickfix"
-
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "lista b³êdów %d z %d; %d b³êdów"
-
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: Nie mogê zapisaæ, opcja 'buftype' jest ustawiona"
-
-#: ../quickfix.c:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr "E683: Brak nazwy pliku lub niew³aœciwa œcie¿ka"
-
-#: ../quickfix.c:2911
-#, c-format
-msgid "Cannot open file \"%s\""
-msgstr "Nie mogê otworzyæ pliku \"%s\""
-
-#: ../quickfix.c:3429
-msgid "E681: Buffer is not loaded"
-msgstr "E681: Bufor nie jest za³adowany"
-
-#: ../quickfix.c:3487
-msgid "E777: String or List expected"
-msgstr "E777: Oczekiwa³em na ³añcuch lub listê"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: Niew³aœciwy element w %s%%[]"
-
-#: ../regexp.c:374
-#, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E769: Brak ] po %s["
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: Niesparowany %s%%("
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: Niesparowany %s("
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: Niesparowany %s)"
-
-#: ../regexp.c:378
-msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( jest niedozwolone w tym miejscu"
-
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 i podobne s¹ niedozwolone w tym miejscu"
-
-#: ../regexp.c:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: Brak ] po %s%%["
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: Pusty %s%%[]"
-
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: Zbyt d³ugi wzorzec"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: Zbyt wiele \\z("
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: Zbyt wiele %s("
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: Niesparowany \\z("
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: niedozwolony znak po %s@"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: Zbyt wiele z³o¿onych %s{...}"
-
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: Zagnie¿d¿one %s*"
-
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: Zagnie¿d¿one %s%c"
-
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: Niedozwolone u¿ycie \\_"
-
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c po niczym"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: Niew³aœciwe odwo³anie wsteczne"
-
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: niedopuszczalny znak po \\z"
-
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: Niedozwolony znak po %s%%[dxouU]"
-
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: Niedozwolony znak po %s%%"
-
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: B³¹d sk³adni w %s{...}"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "Zewnêtrzne poddopasowania:\n"
-
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-"E:864: \\%#= mo¿e byæ tylko przed 0, 1 lub 2. Zostanie u¿yty silnik "
-"automatyczny"
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr "E865: (NFA) przedwczesny koniec wyra¿enia regularnego"
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr "E866: (wyra¿enie regularne NFA) Niepoprawnie umieszczone %c"
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr "E867: (NFA) Nieznany operator '\\z%c'"
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) Nieznany operator '\\%%%c'"
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr "E869: (NFA) Nieznany operator '\\@%c'"
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-"E870: (wyra¿enie regularne NFA) B³¹d przy odczytywaniu limitów powtórzeñ"
-
-#. 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: (wyra¿enie regularne NFA) wielokrotne nie mo¿e byæ po wielokrotnym!"
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr "E872: (wyra¿enie regularne NFA) Zbyt du¿o '('"
-
-#: ../regexp_nfa.c:2042
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E879: (wyra¿enie regularne NFA) Za du¿o \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr "E873: (wyra¿enie regularne NFA) b³¹d poprawnego zakoñczenia"
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr "E874: (NFA) Nie mo¿na zdj¹æ elementu ze stosu!"
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-"E875: (wyra¿enie regularne NFA) (w trakcie konwersji postfix do NFA), za "
-"wiele stanów na stosie"
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr "E876: (wyra¿enie regularne NFA) Nie ma miejsca na ca³e NFA "
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"Nie mo¿na otworzyæ do zapisu tymczasowego pliku, pokazujê na stderr... "
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) NIE MO¯NA OTWORZYÆ %s !"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "Nie mo¿na otworzyæ do zapisu tymczasowego pliku logowania"
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " V-ZAMIANA"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " ZAMIANA"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " NEGATYW"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " WPROWADZANIE"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (wprowadzanie)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (zamiana)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (v-zamiana)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " Hebrajski"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " Arabski"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (jêzyk)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (wklejanie)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " WIZUALNY"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " WIZUALNY LINIOWY"
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " WIZUALNY BLOKOWY"
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " ZAZNACZANIE"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " ZAZNACZANIE LINIOWE"
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " ZAZNACZANIE BLOKOWE"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "zapis"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: Niew³aœciwy ci¹g do szukania: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: szukanie dobi³o GÓRY bez znalezienia: %s"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: szukanie dobi³o KOÑCA bez znalezienia : %s"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: Oczekujê '?' lub '/' po ';'"
-
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (zawiera poprzednio wymienione dopasowanie)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- Zawarte pliki "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "nie znaleziono"
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "w tropie ---\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (Ju¿ wymienione)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " NIE ZNALEZIONO"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "Przegl¹d w³¹czonego pliku: %s"
-
-#: ../search.c:4216
-#, c-format
-msgid "Searching included file %s"
-msgstr "Przeszukiwanie w³¹czonego pliku %s"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: Wzorzec pasuje w bie¿¹cym wierszu"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "Wszelkie w³¹czane pliki odnaleziono"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "Brak w³¹czanych plików"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: Nie znalaz³em definicji"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: Nie znalaz³em wzorca"
-
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Podstawienie "
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-"\n"
-"# Ostatni %sWyszukiwany wzorzec:\n"
-"~"
-
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Nieprawid³owy format pliku sprawdzania pisowni"
-
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr "E758: Obciêty plik sprawdzania pisowni"
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr "Zbêdny tekst w %s wiersz %d: %s"
-
-#: ../spell.c:954
-#, c-format
-msgid "Affix name too long in %s line %d: %s"
-msgstr "Za d³uga nazwa afiksu w %s wiersz %d: %s"
-
-#: ../spell.c:955
-msgid "E761: Format error in affix file FOL, LOW or UPP"
-msgstr "E761: B³¹d formatu w pliku afiksów FOL, LOW lub UPP"
-
-#: ../spell.c:957
-msgid "E762: Character in FOL, LOW or UPP is out of range"
-msgstr "E762: Znak w FOL, LOW lub UPP jest poza zasiêgiem"
-
-#: ../spell.c:958
-msgid "Compressing word tree..."
-msgstr "Kompresja drzewa s³ów..."
-
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: Sprawdzanie pisowni nie jest w³¹czone"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
-"Ostrze¿enie: Nie mogê znaleŸæ listy s³ów \"%s.%s.spl\" lub \"%s.ascii.spl\""
-
-#: ../spell.c:2473
-#, c-format
-msgid "Reading spell file \"%s\""
-msgstr "Odczytujê plik sprawdzania pisowni \"%s\""
-
-#: ../spell.c:2496
-msgid "E757: This does not look like a spell file"
-msgstr "E757: To nie wygl¹da na plik sprawdzania pisowni"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: Stary plik sprawdzania pisowni, wymagane uaktualnienie"
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr "E772: Plik sprawdzania pisowni dla nowszej wersji Vima"
-
-#: ../spell.c:2602
-msgid "E770: Unsupported section in spell file"
-msgstr "E770: Niewspierana sekcja w pliku sprawdzania pisowni"
-
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Ostrze¿enie: region %s nie jest wspierany"
-
-#: ../spell.c:4550
-#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Czytam plik afiksów %s ..."
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr "Konwersja nie powiod³a siê dla wyrazu w %s wierszu %d: %s"
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr "Konwersja w %s nie jest wspierana: od %s do %s"
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "Nieprawid³owa wartoœæ FLAG w %s wierz %d: %s"
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr "FLAG po u¿yciu flag w %s wiersz %d: %s"
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"Definiowanie COMPOUNDFORBIDFLAG po PFX mo¿e skutkowaæ z³ym wynikiem w %s "
-"wiersz %d"
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"Definiowanie COMPOUNDPERMITFLAG po PFX mo¿e skutkowaæ z³ym wynikiem w %s "
-"wiersz %d"
-
-#: ../spell.c:4747
-#, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "Z³a wartoœæ COMPOUNDRULES w %s wiersz %d: %s"
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "Z³a wartoœæ COMPOUNDWORDMAX w %s wiersz %d: %s"
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "Z³a wartoœæ COMPOUNDMIM w %s wiersz %d: %s"
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "Z³a wartoœæ COMPOUNDSYLMAX w %s wiersz %d: %s"
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "Z³a wartoœæ CHECKCOMPOUNDPATTERN w %s wiersz %d: %s"
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr "Ró¿ne flagi z³o¿eñ w kontynuowanym bloku afiksu w %s wiersz %d: %s"
-
-#: ../spell.c:4850
-#, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "Powtórzony afiks w %s wiersz %d: %s"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-"Afiks u¿yty tak¿e dla BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST w "
-"%s wiersz %d: %s"
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr "Oczekiwano Y lub N w %s wierszu %d: %s"
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr "B³êdny warunek w %s wiersz %d: %s"
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr "Oczekiwano iloœci REP(SAL) w %s wierszu %d"
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr "Oczekiwano iloœci MAP w %s wierszu %d"
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr "Powtórzony znak w MAP w %s wierszu %d"
-
-#: ../spell.c:5176
-#, c-format
-msgid "Unrecognized or duplicate item in %s line %d: %s"
-msgstr "Nieznany lub powtórzony element w %s wierszu %d: %s"
-
-#: ../spell.c:5197
-#, c-format
-msgid "Missing FOL/LOW/UPP line in %s"
-msgstr "Brak wiersza FOL/LOW/UPP w %s"
-
-#: ../spell.c:5220
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr "COMPOUNDSYLMAX u¿yty bez SYLLABLE"
-
-#: ../spell.c:5236
-msgid "Too many postponed prefixes"
-msgstr "Zbyt wiele opóŸnionych prefiksów"
-
-#: ../spell.c:5238
-msgid "Too many compound flags"
-msgstr "Zbyt wiele flag z³o¿eñ"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr "Zbyt wiele opóŸnionych prefiksów i/lub flag z³o¿eñ"
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr "Brak wiersza SOFO%s wiersz w %s"
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr "Wiersze SAL i SOFO w %s"
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr "Flaga nie jest liczb¹ w %s wiersz %d: %s"
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr "Nieprawid³owa flaga w %s wiersz %d: %s"
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr "Wartoœæ %s ró¿ni siê od tej u¿ytej w innym pliku .aff"
-
-#: ../spell.c:5602
-#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Czytam plik s³ownika %s ..."
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr "E760: Brak iloœci s³ów w %s"
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "wiersz %6d, s³owo %6d - %s"
-
-# c-format
-#: ../spell.c:5691
-#, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "Powtórzony wyraz w %s wierszu %d: %s"
-
-# c-format
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr "Pierwszy powtórzony wyraz w %s wiersz %d: %s"
-
-# c-format
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr "%d powtórzony(ch) wyraz(ów) w %s"
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr "Zignorowa³em %d s³ów ze znakami nie ASCII w %s"
-
-#: ../spell.c:6115
-#, c-format
-msgid "Reading word file %s ..."
-msgstr "Odczytujê plik wyrazów %s ..."
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "Zignorowano powtórzony wiersz /encoding= w %s wierszu %d: %s"
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "Zignorowano wiersz /encoding= po wyrazie w %s wierszu %d: %s"
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "Powtórzony wiersz /regions= zignorowano w %s wierszu %d: %s"
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "Za du¿o regionów w %s wiersz %d: %s"
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "wiersz / zignorowano w %s wierszu %d: %s"
-
-#: ../spell.c:6224
-#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "Nieprawid³owy numer regionu w %s wierszu %d: %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "Nieznane flagi w %s wiersz %d: %s"
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr "Zignorowa³em %d s³ów ze znakami nie ASCII"
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "Skompresowano %d z %d wêz³ów; pozostaje %d (%d%%)"
-
-#: ../spell.c:7340
-msgid "Reading back spell file..."
-msgstr "Odczytujê plik sprawdzania pisowni..."
-
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
-msgid "Performing soundfolding..."
-msgstr "Wykonujê kompresjê dŸwiêkow¹..."
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Liczba s³ów po kompresji dŸwiêkowej: %<PRId64>"
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr "Ca³kowita liczba s³ów: %d"
-
-#: ../spell.c:7655
-#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Zapisujê plik sugestii %s ..."
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr "Oczekiwane zu¿ycie pamiêci: %d bajtów"
-
-#: ../spell.c:7820
-msgid "E751: Output file name must not have region name"
-msgstr "E751: Nazwa pliku wynikowego nie mo¿e byæ nazw¹ regionu"
-
-#: ../spell.c:7822
-msgid "E754: Only up to 8 regions supported"
-msgstr "E754: Wspieram tylko 8 regionów"
-
-#: ../spell.c:7846
-#, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E755: Nieprawid³owy region w %s"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr "Ostrze¿enie: okreœlono zarówno z³o¿enia jak i NOBREAK"
-
-#: ../spell.c:7920
-#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Zapisujê plik sprawdzania pisowni %s ..."
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr "Zrobione!"
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' nie posiada wpisów %<PRId64>"
-
-#: ../spell.c:8074
-#, fuzzy, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "Usuniêto s³owo z %s"
-
-#: ../spell.c:8117
-#, fuzzy, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "Dodano s³owo do %s"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: Znaki wyrazów ró¿ni¹ siê miêdzy plikami sprawdzania pisowni"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Przykro mi, brak podpowiedzi"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Przykro mi, tylko %<PRId64> podpowiedzi"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Zmieñ \"%.*s\" na:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Brak poprzednich podmian sprawdzania pisowni"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Nie znaleziono: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Ten plik nie wygl¹da na plik .sug: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Stary plik .sug, konieczne jest uaktualnienie: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Plik .sug dla nowszej wersji Vima: %s"
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Plik .sug nie pasuje do pliku .spl: %s"
-
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: B³¹d w czasie odczytu pliku .sug: %s"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: Podwojony znak we wpisie MAP"
-
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "Brak elementów sk³adni okreœlonych dla tego bufora"
-
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: Niedozwolony argument: %s"
-
-#: ../syntax.c:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: Nie ma takiego klastra sk³adni: %s"
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "synchronizacja komentarzy w stylu C"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "brak synchronizacji"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "pocz¹tek synchronizacji"
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr " wierszy przed górn¹ lini¹"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- Elementy synchronizacji sk³adni ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"synchronizujê na elementach"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- Elementy sk³adni ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: Nie ma takiego klastra sk³adni: %s"
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "minimalnie "
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "maksymalnie "
-
-#: ../syntax.c:3513
-msgid "; match "
-msgstr "; pasuje "
-
-#: ../syntax.c:3515
-msgid " line breaks"
-msgstr "znaków nowego wiersza"
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: argument contains niedozwolony w tym miejscu"
-
-#: ../syntax.c:4096
-msgid "E844: invalid cchar value"
-msgstr "E844: Niew³aœciwa wartoœæ cchar"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: group[t]here niedozwolone w tym miejscu"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: Nie znalaz³em elementów regionu dla %s"
-
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: Wymagana nazwa pliku"
-
-#: ../syntax.c:4221
-msgid "E847: Too many syntax includes"
-msgstr "E847: Za du¿o w³¹czonych sk³adni"
-
-#: ../syntax.c:4303
-#, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E789: Brak ']': %s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: Brak '=': %s"
-
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: Za ma³o argumentów: syntax region %s"
-
-#: ../syntax.c:4870
-msgid "E848: Too many syntax clusters"
-msgstr "E848: Za du¿o klastrów sk³adni"
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: Brak specyfikacji klastra"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: Brak ogranicznika wzorca: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: Œmieci po wzorcu: %s"
-
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: syntax sync: wielokrotnie podane wzorce kontynuacji wiersza"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: Niedozwolone argumenty: %s"
-
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: Brak znaku równoœci: %s"
-
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: Pusty argument: %s"
-
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %s jest niedozwolone w tym miejscu"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %s musi byæ pierwsze w liœcie contains"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: Nieznana nazwa grupy: %s"
-
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: Niew³aœciwa podkomenda :syntax : %s"
-
-#: ../syntax.c:5854
-msgid ""
-" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-msgstr ""
-" WSZYTKO ILOŒÆ PASUJE NAJWOLN. ŒREDNIO NAZWA WZORZEC"
-
-#: ../syntax.c:6146
-msgid "E679: recursive loop loading syncolor.vim"
-msgstr "E679: rekursywna pêtla wczytuj¹ca syncolor.vim"
-
-#: ../syntax.c:6256
-#, c-format
-msgid "E411: highlight group not found: %s"
-msgstr "E411: nie znaleziono grupy podœwietlania: %s"
-
-#: ../syntax.c:6278
-#, c-format
-msgid "E412: Not enough arguments: \":highlight link %s\""
-msgstr "E412: Zbyt ma³o argumentów: \":highlight link %s\""
-
-#: ../syntax.c:6284
-#, c-format
-msgid "E413: Too many arguments: \":highlight link %s\""
-msgstr "E413: Zbyt wiele argumentów: \":highlight link %s\""
-
-#: ../syntax.c:6302
-msgid "E414: group has settings, highlight link ignored"
-msgstr "E414: grupa ma ustawienia; zignorowane pod³¹czenie podœwietlania"
-
-#: ../syntax.c:6367
-#, c-format
-msgid "E415: unexpected equal sign: %s"
-msgstr "E415: nieoczekiwany znak równoœci: %s"
-
-#: ../syntax.c:6395
-#, c-format
-msgid "E416: missing equal sign: %s"
-msgstr "E416: brak znaku równoœci: %s"
-
-#: ../syntax.c:6418
-#, c-format
-msgid "E417: missing argument: %s"
-msgstr "E417: brak argumentu: %s"
-
-#: ../syntax.c:6446
-#, c-format
-msgid "E418: Illegal value: %s"
-msgstr "E418: Niedozwolona wartoϾ: %s"
-
-#: ../syntax.c:6496
-msgid "E419: FG color unknown"
-msgstr "E419: Kolor FG nieznany"
-
-#: ../syntax.c:6504
-msgid "E420: BG color unknown"
-msgstr "E420: Kolor BG nieznany"
-
-#: ../syntax.c:6564
-#, c-format
-msgid "E421: Color name or number not recognized: %s"
-msgstr "E421: Nazwa lub liczba koloru nierozpoznana: %s"
-
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: za d³ugi kod terminala: %s"
-
-#: ../syntax.c:6753
-#, c-format
-msgid "E423: Illegal argument: %s"
-msgstr "E423: Niedozwolony argument: %s"
-
-#: ../syntax.c:6925
-msgid "E424: Too many different highlighting attributes in use"
-msgstr "E424: Zbyt wiele ró¿nych atrybutów podkreœlania w u¿yciu"
-
-#: ../syntax.c:7427
-msgid "E669: Unprintable character in group name"
-msgstr "E669: Niedrukowalny znak w nazwie grupy"
-
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: nieprawid³owy znak w nazwie grupy"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr "E849: Za du¿o grup podœwietlania i sk³adni"
-
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: na dole stosu znaczników"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: na górze stosu znaczników"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Nie mo¿na przejœæ przed pierwszy pasuj¹cy znacznik"
-
-#: ../tag.c:504
-#, c-format
-msgid "E426: tag not found: %s"
-msgstr "E426: nie znaleziono znacznika: %s"
-
-#: ../tag.c:528
-msgid " # pri kind tag"
-msgstr " # pri rodzaj znacznik"
-
-#: ../tag.c:531
-msgid "file\n"
-msgstr "plik\n"
-
-#: ../tag.c:829
-msgid "E427: There is only one matching tag"
-msgstr "E427: Pasuje tylko jeden znacznik"
-
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: Nie mo¿na przejœæ za ostatni pasuj¹cy znacznik"
-
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "Plik \"%s\" nie istnieje"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "znacznik %d z %d%s"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " lub wiêcej"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " U¿ywam znacznika o odmiennej wielkoœci liter!"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: Plik \"%s\" nie istnieje"
-
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # DO znacznik OD wiersza w pliku/tekœcie"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "Szukam w pliku znaczników %s"
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr "Ignorujê d³ugie wiersze w pliku znaczników"
-
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: B³¹d formatu w pliku znaczników \"%s\""
-
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Przed bajtem %<PRId64>"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Plik znaczników nieuporz¹dkowany: %s"
-
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: Brak pliku znaczników"
-
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: Nie mogê znaleŸæ wzorca znacznika"
-
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: Nie znalaz³em znacznika - tylko zgadujê!"
-
-#: ../tag.c:2797
-#, c-format
-msgid "Duplicate field name: %s"
-msgstr "Powtórzona nazwa pola: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' nieznany. Mo¿liwe typy wbudowanych terminali:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "domyœlnie jest '"
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: Nie mogê otworzyæ pliku termcap"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: Nie ma opisu takiego terminala w terminfo"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: Nie ma opisu takiego terminala w termcap"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: Brak opisu \"%s\" w termcap"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: wymagana zdolnoϾ \"cm\" terminala"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Klawisze terminala ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: B³¹d podczas wczytywania wejœcia, koñczê...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
-msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Niespodziewana zmiana iloœci linii"
-
-#: ../undo.c:627
-#, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E828: Nie mogê otworzyæ do zapisu pliku undo: %s"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr "E825: Uszkodzony plik undo (%s): %s"
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr "Nie mo¿na zapisaæ pliku undo w ¿adnym katalogu z 'undodir'"
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr "Nie nadpiszê plikiem undo, nie mogê odczytaæ: %s"
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr "Nie nadpiszê, to nie jest plik undo: %s"
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr "Pomijam zapis pliku undo, nic do cofniêcia"
-
-#: ../undo.c:1121
-#, c-format
-msgid "Writing undo file: %s"
-msgstr "Zapisujê plik undo: %s"
-
-#: ../undo.c:1213
-#, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E829: B³¹d zapisu w pliku undo: %s"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr "Nie wczytujê pliku undo, inny w³aœciciel: %s"
-
-#: ../undo.c:1292
-#, c-format
-msgid "Reading undo file: %s"
-msgstr "Wczytujê plik undo: %s"
-
-#: ../undo.c:1299
-#, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E822: Nie mogê otworzyæ pliku undo do odczytu: %s"
-
-#: ../undo.c:1308
-#, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E823: To nie jest plik undo: %s"
-
-#: ../undo.c:1313
-#, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E824: Niekompatybilny plik undo: %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr "Zawartoœæ pliku siê zmieni³a, nie mogê u¿yæ pliku undo"
-
-#: ../undo.c:1497
-#, c-format
-msgid "Finished reading undo file %s"
-msgstr "Skoñczono wczytywanie pliku undo %s"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr "Ju¿ w miejscu ostatniej zmiany"
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr "Ju¿ w miejscu najnowszej zmiany"
-
-#: ../undo.c:1806
-#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Nie znaleziono numeru cofniêcia %<PRId64>"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: niew³aœciwe numery wierszy"
-
-#: ../undo.c:2183
-msgid "more line"
-msgstr "1 wiersz wiêcej"
-
-#: ../undo.c:2185
-msgid "more lines"
-msgstr "wiêcej wierszy"
-
-#: ../undo.c:2187
-msgid "line less"
-msgstr "1 wiersz mniej"
-
-#: ../undo.c:2189
-msgid "fewer lines"
-msgstr "mniej wierszy"
-
-#: ../undo.c:2193
-msgid "change"
-msgstr "1 zmiana"
-
-#: ../undo.c:2195
-msgid "changes"
-msgstr "zmiany"
-
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr "przed"
-
-#: ../undo.c:2228
-msgid "after"
-msgstr "za"
-
-#: ../undo.c:2325
-msgid "Nothing to undo"
-msgstr "Nie ma zmian do cofniêcia"
-
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr "liczba zmiany kiedy zapisano"
-
-#: ../undo.c:2360
-#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> sekund temu"
-
-#: ../undo.c:2372
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E790: undojoin nie jest dozwolone po undo"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: uszkodzona lista cofania"
-
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: brak wiersza cofania"
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Zadane ³aty: "
-
-#: ../version.c:627
-msgid ""
-"\n"
-"Extra patches: "
-msgstr ""
-"\n"
-"Ekstra ³aty: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Zmieniony przez "
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"Skompilowany "
-
-#: ../version.c:649
-msgid "by "
-msgstr "przez "
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"Olbrzymia wersja "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "bez GUI."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " Opcje w³¹czone (+) lub nie (-):\n"
-
-#: ../version.c:667
-msgid " system vimrc file: \""
-msgstr " vimrc systemu: \""
-
-#: ../version.c:672
-msgid " user vimrc file: \""
-msgstr " vimrc u¿ytkownika: \""
-
-#: ../version.c:677
-msgid " 2nd user vimrc file: \""
-msgstr " 2-gi plik vimrc u¿ytkownika: \""
-
-#: ../version.c:682
-msgid " 3rd user vimrc file: \""
-msgstr " 3-ci plik vimrc u¿ytkownika: \""
-
-#: ../version.c:687
-msgid " user exrc file: \""
-msgstr " exrc u¿ytkownika: \""
-
-#: ../version.c:692
-msgid " 2nd user exrc file: \""
-msgstr " 2-gi plik exrc u¿ytkownika: \""
-
-#: ../version.c:699
-msgid " fall-back for $VIM: \""
-msgstr " odwet dla $VIM-a: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr "f-b dla $VIMRUNTIME: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "Kompilacja: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Konsolidacja: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " KOMPILACJA DEBUG"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi rozbudowany"
-
-#: ../version.c:769
-msgid "version "
-msgstr "wersja "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "Autor: Bram Moolenaar i Inni."
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim jest open source i rozprowadzany darmowo"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "Pomó¿ biednym dzieciom w Ugandzie!"
-
-#: ../version.c:777
-msgid "type :help iccf<Enter> for information "
-msgstr "wprowadŸ :help iccf<Enter> dla informacji o tym "
-
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr "wprowadŸ :q<Enter> zakoñczenie programu "
-
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "wprowadŸ :help<Enter> lub <F1> pomoc na bie¿¹co "
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "wprowadŸ :help version7<Enter> dla informacji o wersji"
-
-#: ../version.c:784
-msgid "Running in Vi compatible mode"
-msgstr "Dzia³am w trybie zgodnoœci z Vi"
-
-#: ../version.c:785
-msgid "type :set nocp<Enter> for Vim defaults"
-msgstr "wprowadŸ :set nocp<Enter> wartoœci domyœlne Vim-a"
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "wprowadŸ :help cp-default<Enter> dla informacji to tym "
-
-#: ../version.c:827
-msgid "Sponsor Vim development!"
-msgstr "Sponsoruj rozwój Vima!"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "Zostañ zarejestrowanym u¿ytkownikiem Vima!"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr "wprowadŸ :help sponsor<Enter> dla informacji"
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr "wprowadŸ :help register<Enter> dla informacji"
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "menu Pomoc->Sponsoruj/Zarejestruj siê dla informacji"
-
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "Ju¿ jest tylko jeden widok"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: Nie ma okna podgl¹du"
-
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: Nie mogê rozdzieliæ lewo-górnego i prawo-dolnego jednoczeœnie"
-
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: Nie mogê przekrêciæ, gdy inne okno jest rozdzielone"
-
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: Nie mogê zamkn¹æ ostatniego okna"
-
-#: ../window.c:1810
-msgid "E813: Cannot close autocmd window"
-msgstr "E813: Nie mo¿na zamkn¹æ okna autocmd"
-
-#: ../window.c:1814
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: Nie mo¿na zamkn¹æ okna, zosta³oby tylko okno autocmd"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: Inne okno zawiera zmiany"
-
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: Brak nazwy pliku pod kursorem"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() wywo³any z pustym has³em"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfish u¿ywa b³êdnej kolejnoœci bajtów"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: test sha256 nie powiód³ siê"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: test Blowfisha nie powiód³ siê"
-
-#~ msgid "Patch file"
-#~ msgstr "Plik ³ata"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&OK\n"
-#~ "&Zakoñcz"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Brak po³¹czenia z serwerem Vim"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Nie mogê wys³aæ do %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Nie mogê czytaæ odpowiedzi serwera"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Nie mogê wys³aæ do klienta"
-
-#~ msgid "Save As"
-#~ msgstr "Zapisz jako"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Wczytaj skrypt Vima"
-
-#~ msgid "Edit File"
-#~ msgstr "Edytuj Plik"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (NIE ZNALEZIONO)"
-
-#~ msgid "unknown"
-#~ msgstr "nieznany"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "Edytuj plik w nowym oknie"
-
-#~ msgid "Append File"
-#~ msgstr "Do³¹cz plik"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Pozycja okna: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "Zapisz przekierowanie"
-
-#~ msgid "Save View"
-#~ msgstr "Zapisz widok"
-
-#~ msgid "Save Session"
-#~ msgstr "Zapisz sesjê"
-
-#~ msgid "Save Setup"
-#~ msgstr "Zapisz ustawienia"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< nie jest dostêpne bez w³aœciwoœci +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Brak dwugrafów w tej wersji"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "jest urz¹dzeniem (wy³¹czonym w opcji 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "Wczytywanie ze stdin..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfish]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[zakodowane]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Plik zaszyfrowano w nieznany sposób"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans nie pozwala na zapis niezmodyfikowanych buforów"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Czêœciowy zapis niemo¿liwy dla buforów NetBeans"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "zapisywanie do urz¹dzenia wy³¹czone w opcji 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Rozdzia³ zasobów zostanie utracony (wymuœ przez !)"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<nie mogê otworzyæ> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: nie mogê otrzymaæ czcionki %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: nie mogê powróciæ do bie¿¹cego katalogu"
-
-#~ msgid "Pathname:"
-#~ msgstr "Trop:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: nie mogê otrzymaæ bie¿¹cego katalogu"
-
-#~ msgid "OK"
-#~ msgstr "OK"
-
-#~ msgid "Cancel"
-#~ msgstr "Zakoñcz"
-
-#~ msgid "Vim dialog"
-#~ msgstr "VIM - Dialog"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Scrollbar Widget: Nie mog³em otrzymaæ rozmiarów rysunku na przycisku."
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Nie mogê stworzyæ BalloonEval z powiadomieniem i wywo³aniem"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: Nie mog³em stworzyæ nowego procesu dla GUI"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: Proces potomny nie móg³ uruchomiæ GUI"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Nie mogê odpaliæ GUI"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Nie mogê czytaæ z \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Nie mo¿na uruchomiæ GUI, brak prawid³owej czcionki"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: Niew³aœciwe 'guifontwide'"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Nieprawid³owa wartoœæ 'imactivatekey'"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Nie mogê zarezerwowaæ koloru %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Brak dopasowania przy kursorze, szukam dalej"
-
-#~ msgid "Input _Methods"
-#~ msgstr "Input _Methods"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Szukaj i Zamieñ..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Szukaj..."
-
-#~ msgid "Find what:"
-#~ msgstr "ZnajdŸ:"
-
-#~ msgid "Replace with:"
-#~ msgstr "Zamieñ na:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Dopasuj tylko ca³e wyrazy"
-
-#~ msgid "Match case"
-#~ msgstr "Dopasuj wielkoϾ liter"
-
-#~ msgid "Direction"
-#~ msgstr "Kierunek"
-
-#~ msgid "Up"
-#~ msgstr "W górê"
-
-#~ msgid "Down"
-#~ msgstr "W dó³"
-
-#~ msgid "Find Next"
-#~ msgstr "ZnajdŸ nastêpne"
-
-#~ msgid "Replace"
-#~ msgstr "Zamieñ"
-
-#~ msgid "Replace All"
-#~ msgstr "Zamieñ wszystkie"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: otrzymano ¿¹danie \"die\" od mened¿era sesji\n"
-
-#~ msgid "Close"
-#~ msgstr "Zamknij"
-
-#~ msgid "New tab"
-#~ msgstr "Nowa karta"
-
-#~ msgid "Open Tab..."
-#~ msgstr "Otwórz kartê..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: G³ówne okno nieoczekiwanie zniszczone\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&Filtr"
-
-#~ msgid "&Cancel"
-#~ msgstr "&Anuluj"
-
-#~ msgid "Directories"
-#~ msgstr "Katalogi"
-
-#~ msgid "Filter"
-#~ msgstr "Filtr"
-
-#~ msgid "&Help"
-#~ msgstr "&Pomoc"
-
-#~ msgid "Files"
-#~ msgstr "Pliki"
-
-#~ msgid "&OK"
-#~ msgstr "&OK"
-
-#~ msgid "Selection"
-#~ msgstr "Wybór"
-
-#~ msgid "Find &Next"
-#~ msgstr "ZnajdŸ &nastêpne"
-
-#~ msgid "&Replace"
-#~ msgstr "&Zamieñ"
-
-#~ msgid "Replace &All"
-#~ msgstr "Zamieñ &wszystko"
-
-#~ msgid "&Undo"
-#~ msgstr "&Cofnij"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Nie mogê znaleŸæ tytu³u okna \"%s\""
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Argument nie jest wspomagany: \"-%s\"; U¿ywaj wersji OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Nie mo¿na otworzyæ okna wewn¹trz aplikacji MDI"
-
-#~ msgid "Close tab"
-#~ msgstr "Zamknij kartê"
-
-#~ msgid "Open tab..."
-#~ msgstr "Otwórz kartê..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "ZnajdŸ ci¹g (u¿yj '\\\\' do szukania '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Szukanie i Zamiana (u¿yj '\\\\' do szukania '\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "Nie u¿ywany"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Katalog\t*.nic\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Nie mogê zarezerwowaæ mapy kolorów, pewne kolory mog¹ byæ "
-#~ "nieprawid³owe"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr ""
-#~ "E250: Brak czcionek dla nastêpuj¹cych zestawów znaków w zestawie czcionek "
-#~ "%s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Nazwa zestawu czcionek: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Czcionka '%s' nie posiada znaków jednolitej szerokoœci"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: Nazwa zestawu czcionek: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "Font0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "Font1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "Szerokoœæ font%<PRId64> nie jest podwójn¹ szerokoœci¹ font0"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "SzerokoϾ font0: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "SzerokoϾ font1: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Nieprawid³owy opis czcionki"
-
-#~ msgid "&Dismiss"
-#~ msgstr "&Anuluj"
-
-#~ msgid "no specific match"
-#~ msgstr "brak okreœlonego dopasowania"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - wybór czcionki"
-
-#~ msgid "Name:"
-#~ msgstr "Nazwa:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Poka¿ wielkoœæ w punktach"
-
-#~ msgid "Encoding:"
-#~ msgstr "Kodowanie:"
-
-#~ msgid "Font:"
-#~ msgstr "Czcionka:"
-
-#~ msgid "Style:"
-#~ msgstr "Styl:"
-
-#~ msgid "Size:"
-#~ msgstr "WielkoϾ:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: B£¥D w automacie Hangul"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: b³¹d stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: nie mogê otworzyæ bazy danych cscope: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: nie mogê uzyskaæ informacji z bazy danych cscope"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Nie mo¿na wczytaæ biblioteki Lua."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "nie mogê zachowaæ informacji cofania"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: Przykro mi, ta komenda jest wy³¹czona, biblioteka MzScheme nie mo¿e "
-#~ "byæ za³adowana."
-
-#~ msgid "invalid expression"
-#~ msgstr "niepoprawne wyra¿enie"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "wyra¿enia wy³¹czone podczas kompilacji"
-
-#~ msgid "hidden option"
-#~ msgstr "ukryta opcja"
-
-#~ msgid "unknown option"
-#~ msgstr "nieznana opcja"
-
-#~ msgid "window index is out of range"
-#~ msgstr "indeks okna poza zakresem"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "nie mogê otworzyæ bufora"
-
-#~ msgid "cannot delete line"
-#~ msgstr "nie mogê skasowaæ wiersza"
-
-#~ msgid "cannot replace line"
-#~ msgstr "nie mogê zamieniæ wiersza"
-
-#~ msgid "cannot insert line"
-#~ msgstr "nie mogê wprowadziæ wiersza"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ci¹g nie mo¿e zawieraæ znaków nowego wiersza"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "b³¹d przy konwersji wartoœci Scheme do Vima"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "B³¹d vima: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "B³¹d Vima"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "bufor jest niewa¿ny"
-
-#~ msgid "window is invalid"
-#~ msgstr "okno jest niewa¿ne"
-
-#~ msgid "linenr out of range"
-#~ msgstr "numer wiersza poza zakresem"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "Niedozwolone w piaskownicy Vima"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: Python: nie mo¿na u¿ywaæ :py i :py3 w czasie jednej sesji"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: Przykro mi, ta komenda jest wy³¹czona, bo nie mo¿na za³adowaæ "
-#~ "biblioteki Pythona"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: Python: nie mo¿na u¿ywaæ :py i :py3 w czasie jednej sesji"
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Nie mo¿na wywo³aæ Pythona rekursywnie"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ musi byæ reprezentacj¹ £añcucha"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Przykro mi, ta komenda jest wy³¹czona, bo nie mo¿na za³adowaæ "
-#~ "biblioteki Ruby."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: nieoczekiwany return"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: nieoczekiwany next"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: nieoczekiwany break"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: nieoczekiwane redo"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: ponowna próba poza klauzul¹ ratunku"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: nieobs³ugiwany wyj¹tek"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: Nieznany status longjmp %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Prze³¹cz miêdzy implementacj¹/okreœleniem"
-
-#~ msgid "Show base class of"
-#~ msgstr "Poka¿ bazê klasy"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Poka¿ przepisan¹ funkcjê cz³onow¹"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Pobieraj z pliku"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Pobieraj z projektu"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Pobieraj z wszystkich projektów"
-
-#~ msgid "Retrieve"
-#~ msgstr "Pobierz"
-
-#~ msgid "Show source of"
-#~ msgstr "Poka¿ Ÿród³o dla"
-
-#~ msgid "Find symbol"
-#~ msgstr "ZnajdŸ symbol"
-
-#~ msgid "Browse class"
-#~ msgstr "Przejrzyj klasê"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Poka¿ klasê w hierarchii"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Poka¿ klasê w ograniczonej hierarchii"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref odnosi siê do"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ma odniesienia od"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ma"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref u¿yte przez"
-
-#~ msgid "Show docu of"
-#~ msgstr "Poka¿ dokumentacjê dla"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Utwórz dokumentacjê dla"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Nie mogê pod³¹czyæ do SNiFF+. SprawdŸ œrodowisko (sniffemacs musi byæ "
-#~ "odnaleziony w $PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: B³¹d podczas czytania. Roz³¹czenie"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ jest obecnie "
-
-#~ msgid "not "
-#~ msgstr "nie "
-
-#~ msgid "connected"
-#~ msgstr "pod³¹czony"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Nieznane zapytanie SNiFF+: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: B³¹d w trakcie pod³¹czania do SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ niepod³¹czony"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Nie jest buforem SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: B³¹d w trakcie zapisu. Roz³¹czony"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "niew³aœciwy numer bufora"
-
-#~ msgid "not implemented yet"
-#~ msgstr "obecnie nie zaimplementowano"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "nie mogê ustawiæ wiersza(y)"
-
-#~ msgid "invalid mark name"
-#~ msgstr "niepoprawna nazwa zak³adki"
-
-#~ msgid "mark not set"
-#~ msgstr "zak³adka nie ustawiona"
-
-#~ msgid "row %d column %d"
-#~ msgstr "wiersz %d kolumna %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "nie mogê wprowadziæ/do³¹czyæ wiersza"
-
-#~ msgid "line number out of range"
-#~ msgstr "numer wiersza poza zakresem"
-
-#~ msgid "unknown flag: "
-#~ msgstr "nieznana flaga: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "nieznane vimOption"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "przerwanie klawiatury"
-
-#~ msgid "vim error"
-#~ msgstr "b³¹d vima"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "nie mogê stworzyæ bufora/okna komendy: obiekt jest kasowany"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "nie mogê zarejestrowaæ wstecznego wywo³ania komendy: bufor/okno ju¿ "
-#~ "zosta³a skasowana"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL FATALNY B£¥D: reflist zepsuta!? Proszê z³o¿yæ raport o tym na "
-#~ "vim-dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "nie mogê zarejestrowaæ wstecznego wywo³ania komendy: brak odniesienia do "
-#~ "bufora/okna"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: Przykro mi, ta komenda jest wy³¹czona, bo nie mo¿na za³adowaæ "
-#~ "biblioteki Tcl."
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: kod wyjœcia %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "nie mogê dostaæ wiersza"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Nie mogê zarejestrowaæ nazwy serwera komend"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Wys³anie komendy do programu docelowego nie powiod³o siê"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: U¿yto niew³aœciwego id serwera: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: wcielenia instancji rejestru Vima jest Ÿle sformowane. Skasowano!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans nie s¹ obs³ugiwane przez to GUI\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Ta wersja Vima nie by³a skompilowanego z opcj¹ ró¿nic (diff)."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' - nie mo¿e byæ u¿yte: nie w³¹czone przy kompilacji\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: B³¹d: Nie mo¿na uruchomiæ gvim z NetBeans\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "gdzie wielkoœæ znaków jest ignorowana dodaj na pocz¹tku / by flaga by³a "
-#~ "wielk¹ liter¹"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tZarejestruj tego gvima w OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tWyrejestruj gvima z OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tStartuj w GUI (tak jak \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f lub --nofork\tPierwszy plan: Nie wydzielaj przy odpalaniu GUI"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tNie stosuj newcli do otwierania okien"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tU¿ywaj <device> do I/O"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tU¿yj <gvimrc> zamiast jakiegokolwiek .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tEdytuj zakodowane pliki"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tPod³¹cz vima to danego X-serwera"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tNie ³¹cz z serwerem X"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <pliki>\tEdytuj pliki w serwerze Vima jeœli mo¿liwe"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <pliki> To samo, nie narzekaj jeœli nie ma serwera"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <pliki>\tTak jak --remote, lecz czekaj na pliki przed edycj¹"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <pliki> To samo, nie narzekaj jeœli nie ma serwera"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <pliki> tak jak --remote ale u¿ywa jednej "
-#~ "karty na plik"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <klawisze>\tWyœlij <klawisze> do serwera Vima i zakoñcz"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <wyr>\tWykonaj <wyra¿enie> w serwerze i wypisz wynik"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tWymieñ nazwy dostêpnych serwerów Vima i zakoñcz"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <nazwa>\t\tOdsy³aj do/stañ siê serwerem Vim <nazwa>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja Motif):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja neXtaw):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja Athena):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\tZa³aduj vim na <display>"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tZacznij Vim jako ikonê"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <kolor>\tU¿ywaj <kolor> dla t³a (równie¿: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <kolor>\tU¿ywaj <kolor> dla normalnego tekstu (równie¿: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\tU¿ywaj <font> dla normalnego tekstu (równie¿: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\tU¿ywaj <font> dla wyt³uszczonego tekstu"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <font>\tU¿ywaj <font> dla pochy³ego"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr ""
-#~ "-geometry <geom>\tU¿ywaj <geom> dla pocz¹tkowych rozmiarów (równie¿: -"
-#~ "geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <szer>\tU¿yj ramki o gruboœci <szer> (równie¿: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <szer> U¿ywaj przewijacza o szerokoœci <szer> (równie¿: -"
-#~ "sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <height>\tStosuj belkê menu o wysokoœci <height> (równie¿: -"
-#~ "mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tStosuj negatyw kolorów (równie¿: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tNie stosuj negatywu kolorów (równie¿: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\tUstaw okreœlony zasób"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja GTK+):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\tZastartuj vim na <display> (równie¿: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\tUstaw unikatow¹ rolê do identyfikacji g³ównego okna"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tOtwórz Vim wewn¹trz innego widgetu GTK"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "-echo-wid\t\tGvim wypisze Window ID na wyjœcie standardowe"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <tytu³ rodzica>\tOtwórz Vima wewn¹trz rodzicielskiej aplikacji"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tOtwórz Vima wewn¹trz innego elementu win32"
-
-#~ msgid "No display"
-#~ msgstr "Brak display"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Wys³anie nie powiod³o siê.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Wys³anie nie powiod³o siê. Próbujê wykonaæ na miejscu\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "otworzono %d z %d"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Brak terminala: Wys³anie wyra¿enia nie powiod³o siê.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Wys³anie wyra¿enia nie powiod³o siê.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: To nie jest wa¿na strona kodowa"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: Nie mogê nastawiæ wartoœci IC"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Nie mog³em stworzyæ kontekstu wprowadzeñ"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Nie mog³em otworzyæ sposobu wprowadzeñ"
-
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: OSTRZE¯ENIE: Nie mog³em zlikwidowaæ wywo³ania dla IM"
-
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: metoda wprowadzeñ nie wspomaga ¿adnego stylu"
-
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: metoda wprowadzeñ nie wspomaga mojego typu preedit"
-
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: B³¹d w czasie uaktualniania szyfrowania pliku wymiany"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s jest zaszyfrowany a ta wersja Vima nie wspiera szyfrowania"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Zaszyfrowany plik wymiany: \"%s\""
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "Jeœli podano nowy klucz szyfruj¹cy, ale nie zapisano pliku tekstowego,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "wprowadŸ nowy klucz szyfruj¹cy."
-
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "Jeœli zapisano plik tekstowy po zmianie klucza szyfruj¹cego wciœnij Enter"
-
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "aby u¿yæ tego samego klucza dla pliku tekstowego i wymiany"
-
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "U¿ywam klucza szyfruj¹cego z pliku wymiany do pliku tekstowego.\n"
-
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [nie nadaje siê dla tej wersji Vima]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "Oderwij to menu"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Dialog wyboru katalogu"
-
-#~ msgid "Save File dialog"
-#~ msgstr "Dialog zapisywania pliku"
-
-#~ msgid "Open File dialog"
-#~ msgstr "Dialog otwierania pliku"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Przykro mi, nie ma przegl¹darki plików w trybie konsoli"
-
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: zachowujê plik...\n"
-
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: Zakoñczono.\n"
-
-#~ msgid "ERROR: "
-#~ msgstr "B£¥D: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[bajtów] totalne alokacje-zwolnienia %<PRIu64>-%<PRIu64>, w u¿ytku "
-#~ "%<PRIu64>, maksymalne u¿ycie %<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[wywo³ania] wszystkich re/malloc()-ów %<PRIu64>, wszystkich free()-ów "
-#~ "%<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Wiersz staje siê zbyt d³ugi"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Wewnêtrzny b³¹d: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Niedozwolony obrys myszki"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "WprowadŸ klucz do odkodowania: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "WprowadŸ ponownie ten sam klucz: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Klucze nie pasuj¹ do siebie!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Nie mo¿na po³¹czyæ z Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Nie mo¿na po³¹czyæ z Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: B³êdny tryb dostêpu pliku info po³¹czenia NetBeans: \"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "odczyt z gniazda Netbeans"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Bufor %<PRId64> utraci³ po³¹czenie z NetBeans"
-
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: netbeans nie s¹ obs³ugiwane przez to GUI"
-
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans ju¿ pod³¹czone"
-
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s jest tylko do odczytu (dodaj ! aby wymusiæ)"
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Funkcjonalnoœæ eval nie jest dostêpna"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "zwalniam %<PRId64> wierszy"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Nie mogê zmieniæ term w GUI"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: U¿yj \":gui\" do odpalenia GUI"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Nie mogê zmieniæ w GTK+2 GUI"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Niedozwolona czcionka/ki"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: nie mogê wybraæ zestawu czcionek"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Niedozwolony zestaw czcionek"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: nie mogê wybraæ szerokiej czcionki"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Niedozwolona szeroka czcionka"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Brak wspomagania myszki"
-
-#~ msgid "cannot open "
-#~ msgstr "nie mogê otworzyæ "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Nie mogê otworzyæ okna!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Potrzebujê Amigados w wersji 2.04 lub póŸniejsz¹\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Potrzebujê %s w wersji %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Nie mogê otworzyæ NIL:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "Nie mogê stworzyæ "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim koñczy pracê z %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "nie mogê zmieniæ trybu konsoli ?!\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: nie jest konsol¹??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Nie mogê wykonaæ pow³oki z opcj¹ -f"
-
-#~ msgid "Cannot execute "
-#~ msgstr "Nie mogê wykonaæ "
-
-#~ msgid "shell "
-#~ msgstr "pow³oka "
-
-#~ msgid " returned\n"
-#~ msgstr " zwróci³\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE zbyt niskie."
-
-#~ msgid "I/O ERROR"
-#~ msgstr "B£¥D I/O"
-
-#~ msgid "Message"
-#~ msgstr "WiadomoϾ"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' nie wynosi 80, nie mogê wykonaæ zewnêtrznych komend"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Wybór drukarki nie powiód³ siê"
-
-#~ msgid "to %s on %s"
-#~ msgstr "do %s z %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Nieznana czcionka drukarki: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: B³¹d drukarki: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "Wydrukowano '%s'"
-
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr ""
-#~ "E244: Niedozwolona nazwa zestawu znaków \"%s\" w nazwie czcionki \"%s\""
-
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Niedozwolony znak '%c' w nazwie czcionki \"%s\""
-
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Podwójny sygna³, wychodzê\n"
-
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Za³apa³ œmiertelny sygna³ %s\n"
-
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Za³apa³ œmiertelny sygna³\n"
-
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Otwieranie ekranu X trwa³o %<PRId64> msec"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Dosta³ b³¹d X\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "Test ekranu X nie powiód³ siê"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Próba otwarcia ekranu X trwa³a zbyt d³ugo"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Nie mogê wykonaæ pow³oki sh\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Nie mogê stworzyæ potoków\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Nie mogê rozdzieliæ siê\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Komenda zakoñczona\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP straci³ po³¹czenie ICE"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "Otwarcie ekranu X nie powiod³o siê"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP obs³uguje ¿¹danie samozapisu"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP otwiera po³¹czenie"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "Obserwacja po³¹czenia XSMP ICE nie powiod³a siê"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection nie powiod³o siê: %s"
-
-#~ msgid "At line"
-#~ msgstr "W wierszu"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Nie mogê za³adowaæ vim32.dll!"
-
-#~ msgid "VIM Error"
-#~ msgstr "B³¹d VIM"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Nie zdo³a³em poprawiæ wskaŸników funkcji w DLL!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "pow³oka zwróci³a %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Za³apa³ wydarzenie %s\n"
-
-#~ msgid "close"
-#~ msgstr "zamknij"
-
-#~ msgid "logoff"
-#~ msgstr "wyloguj"
-
-#~ msgid "shutdown"
-#~ msgstr "zakoñcz"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Nie znaleziono komendy"
-
-#~ 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 ""
-#~ "VIMRUN.EXE nie znaleziono w twoim $PATH.\n"
-#~ "Zewnêtrzne komendy nie bêd¹ wstrzymane po wykonaniu.\n"
-#~ "Zobacz :help wim32-vimrun aby otrzymaæ wiêcej informacji."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Vim Ostrze¿enie"
-
-#~ msgid "Error file"
-#~ msgstr "Plik b³êdu"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: B³¹d przy budowwaniu NFA z klas¹ ekwiwalencji"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr ""
-#~ "E878: (NFA) Nie mo¿na przydzieliæ pamiêci do przejœcia przez ga³êzie!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "Ostrze¿enie: Nie mogê znaleŸæ listy s³ów \"%s_%s.spl\" lub \"%s_ascii.spl"
-#~ "\""
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Konwersja w %s nie jest wspierana"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr ""
-#~ "E845: Nie wystarczaj¹ca iloœæ pamiêci, lista s³ów bêdzie niekompletna"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Trop szukania pliku znaczników obciêty dla %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "uruchomiono now¹ pow³okê\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "U¿ywam CUT_BUFFER0 zamiast pustego wyboru"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Cofniêcie niemo¿liwe; mimo to kontynuujê"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Nie zaszyfrowany plik ma zaszyfrowany plik undo: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Nie powiod³o siê odszyfrowywanie pliku undo: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Plik undo jest zaszyfrowany: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "16/32-bit wersja GUI dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "64 bitowa wersja GUI dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 bitowa wersja GUI dla MS-Windows"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " w trybie Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " ze wspomaganiem OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 bitowa wersja na konsolê dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 bitowa wersja na konsolê dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 bitowa wersja dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 bitowa wersja dla MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 bitowa wersja dla MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla MacOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla MacOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Du¿a wersja "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Normalna wersja "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Ma³a wersja "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Malutka wersja "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "z GTK2-GNOME GUI."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "z GTK2 GUI."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "z X11-Motif GUI."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "z X11-neXtaw GUI."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "z X11-Athena GUI."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "z Photon GUI."
-
-#~ msgid "with GUI."
-#~ msgstr "z GUI."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "z Carbon GUI."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "z Cocoa GUI."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "z (klasycznym) GUI."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " gvimrc systemu: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " gvimrc u¿ytkownika: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "2-gi plik gvimrc u¿ytkownika: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "3-ci plik gvimrc u¿ytkownika: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " systemowy plik menu: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Kompilator: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "menu Pomoc->Sieroty dla informacji to tym "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Uruchomiony bez trybów, wpisany tekst jest wprowadzany"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "menu Edytuj->Ustawienia globalne->Tryb wstawiania"
-
-#~ msgid " for two modes "
-#~ msgstr " dla dwóch trybów "
-
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "menu Edytuj->Ustawienia globalne->KompatybilnoϾ z Vi"
-
-#~ msgid " for Vim defaults "
-#~ msgstr " dla domyœlnych ustawieñ Vima "
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "OSTRZE¯ENIE: wykryto Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "wprowadŸ :help windows95<Enter> dla informacji to tym "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Nie mog³em za³adowaæ biblioteki %s"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "Przykro mi, ta komenda jest wy³¹czona: nie mog³em za³adowaæ biblioteki "
-#~ "Perla."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr "E299: wyliczenie Perla zabronione w piaskownicy bez modu³u Safe"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Edytuj w &wielu Vimach"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Edytuj w pojedynczym &Vimie"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Diff z Vimem"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Edytuj w &Vimie"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Edytuj z istniej¹cym Vimem - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Edytuj wybrane pliki w Vimie"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "B³¹d tworzenia procesu: SprawdŸ czy gvim jest w twojej œcie¿ce!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "b³¹d gvimext.dll"
-
-#~ msgid "Path length too long!"
-#~ msgstr "Za d³uga œcie¿ka!"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Nieznany zestaw czcionek: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Nieznana czcionka: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Czcionka \"%s\" nie ma sta³ej szerokoœci znaków"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Nie mo¿na za³adowaæ funkcji biblioteki %s"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E26: Hebrajski nie mo¿e byæ u¿yty: Nie w³¹czono podczas kompilacji\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Farsi nie mo¿e byæ u¿yty: Nie w³¹czono podczas kompilacji\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: Arabski nie mo¿e byæ u¿yty: Nie w³¹czono podczas kompilacji\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: brak zarejestrowanego serwera o nazwie \"%s\""
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: nie mogê otworzyæ ekranu"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Odebra³em niew³aœciwe wyra¿enie"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Region jest chroniony, nie mogê zmieniæ"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans nie zezwala na zmiany w plikach tylko do odczytu"
-
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Potrzebujê klucza szyfrowania dla \"%s\""
-
-#~ msgid "empty keys are not allowed"
-#~ msgstr "puste klucze nie s¹ dozwolone"
-
-#~ msgid "dictionary is locked"
-#~ msgstr "s³ownik jest zablokowany"
-
-#~ msgid "list is locked"
-#~ msgstr "lista jest zablokowana"
-
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "nie powiod³o siê dodanie klucza '%s' do s³ownika"
-
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "indeks musi byæ liczb¹ lub wycinkiem, nie %s"
-
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr "czeka³em na str() lub unicode(), a dosta³em %s"
-
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "czeka³em na bytes() lub str(), a dosta³em %s"
-
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr ""
-#~ "czeka³em na int(), long() lub coœ co mo¿na zmieniæ na long(), ale "
-#~ "dosta³em %s"
-
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr ""
-#~ "czeka³em na int() lub coœ co mo¿na zmieniæ na int(), ale dosta³em %s"
-
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "wartoœæ zbyt du¿a by zmieœci³a siê w typie int C"
-
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "wartoœæ jest zbyt ma³a by zmieœci³a siê w typie int C"
-
-#~ msgid "number must be greater then zero"
-#~ msgstr "liczba musi byæ wiêksza ni¿ zero"
-
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "liczba musi byæ wiêksza lub mniejsza ni¿ zero"
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "nie mogê skasowaæ atrybutów OutputObject"
-
-#~ msgid "invalid attribute: %s"
-#~ msgstr "niepoprawny atrybut: %s"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: B³¹d w uruchomieniu obiektów I/O"
-
-#~ msgid "failed to change directory"
-#~ msgstr "nie powiod³a siê zmiana katalogu"
-
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "czeka³em na 3-krotkê jako wynik imp.find_module(), a dosta³em %s"
-
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr ""
-#~ "czeka³em na 3-krotkê jako wynik imp.find_module(), a dosta³em krotkê o "
-#~ "wielkoœci %d"
-
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "wewnêtrzny b³¹d: imp.find_module zwróci³ krotkê z NULL"
-
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "nie mogê usun¹æ atrybutów vim.Dictionary"
-
-#~ msgid "cannot modify fixed dictionary"
-#~ msgstr "nie mogê zmieniæ zablokowanego s³ownika"
-
-#~ msgid "cannot set attribute %s"
-#~ msgstr "nie mogê ustawiæ atrybutu %s"
-
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "hashtab zmieni³ siê w czasie iteracji"
-
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr ""
-#~ "czeka³em na element sekwencyjny od d³ugoœci 2, a dosta³em sekwencjê o "
-#~ "d³ugoœci %d"
-
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "konstruktor listy nie akceptuje s³ów kluczowych jako argumentów"
-
-#~ msgid "list index out of range"
-#~ msgstr "indeks listy poza zakresem"
-
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "b³¹d wewnêtrzny: nie powiod³o siê pobranie z listy Vima elementu %d"
-
-#~ msgid "failed to add item to list"
-#~ msgstr "nie powiod³o siê dodanie elementu do listy"
-
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "b³¹d wewnêtrzny: w liœcie Vima brak elementu %d"
-
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "b³¹d wewnêtrzny: nie powiod³o siê dodanie elementu do listy"
-
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "nie mogê usun¹æ atrybutów vim.List"
-
-#~ msgid "cannot modify fixed list"
-#~ msgstr "nie mogê zmieniæ zablokowanej listy"
-
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "nie nazwana funkcja %s nie istnieje"
-
-#~ msgid "function %s does not exist"
-#~ msgstr "funkcja %s nie istnieje"
-
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "konstruktor funkcji nie akceptuje s³ów kluczowych jako argumentów"
-
-#~ msgid "failed to run function %s"
-#~ msgstr "nie mogê uruchomiæ funkcji %s"
-
-#~ msgid "problem while switching windows"
-#~ msgstr "wyst¹pi³ problem w czasie zmiany okien"
-
-#~ msgid "unable to unset global option %s"
-#~ msgstr "nie mogê wyzerowaæ opcji globalnej %s"
-
-#~ msgid "unable to unset option %s which does not have global value"
-#~ msgstr "nie mogê wyzerowaæ opcji %s, która nie ma wartoœci globalnej"
-
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "próba odniesienia do skasowanej karty"
-
-#~ msgid "no such tab page"
-#~ msgstr "nie ma takiej karty"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "próba odniesienia do skasowanego okna"
-
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "atrybut tylko do odczytu: bufor"
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "pozycja kursora poza buforem"
-
-#~ msgid "no such window"
-#~ msgstr "nie ma takiego okna"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "próba odniesienia do skasowanego bufora"
-
-#~ msgid "failed to rename buffer"
-#~ msgstr "nie powiod³a siê zmiana nazwy bufora"
-
-#~ msgid "mark name must be a single character"
-#~ msgstr "nazwa zak³adki musi byæ pojedynczym znakiem"
-
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "oczekiwa³em na obiekt vim.Buffer, a dosta³em %s"
-
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "nie przeszed³em do bufora %d"
-
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "oczekiwa³em na obiekt vim.Window, a dosta³em %s"
-
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "nie znaleziono okna na bie¿¹cej karcie"
-
-#~ msgid "did not switch to the specified window"
-#~ msgstr "nie przeszed³em do okreœlonego okna"
-
-#~ msgid "expected vim.TabPage object, but got %s"
-#~ msgstr "oczekiwa³em na obiekt vim.TabPage, a dosta³em %s"
-
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "nie przeszed³em do okreœlonej karty"
-
-#~ msgid "failed to run the code"
-#~ msgstr "uruchomienie kodu siê nie powiod³o"
-
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: eval nie zwróci³o odpowiedniego obiektu pythona"
-
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: Nie powiod³a siê konwersja obiektu pythona do wartoœci Vima"
-
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "nie mo¿na konwertowaæ %s do s³ownika Vima"
-
-#~ msgid "unable to convert %s to vim structure"
-#~ msgstr "nie mo¿na konwertowaæ %s do struktury Vima"
-
-#~ msgid "internal error: NULL reference passed"
-#~ msgstr "b³¹d wewnêtrzny: przekazano referencjê NULL"
-
-#~ msgid "internal error: invalid value type"
-#~ msgstr "b³¹d wewnêtrzny: b³êdny typ wartoœci"
-
-#~ msgid ""
-#~ "Failed to set path hook: sys.path_hooks is not a list\n"
-#~ "You should now do the following:\n"
-#~ "- append vim.path_hook to sys.path_hooks\n"
-#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
-#~ msgstr ""
-#~ "Nie mogê ustawiæ haka œcie¿ki: sys.path_hooks nie jest list¹\n"
-#~ "Powinieneœ teraz wykonaæ nastêpuj¹ce czynnoœci:\n"
-#~ "- dodaæ vim.path_hook do sys.path_hooks\n"
-#~ "- dodaæ vim.VIM_SPECIAL_PATH do sys.path\n"
-
-#~ msgid ""
-#~ "Failed to set path: sys.path is not a list\n"
-#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
-#~ msgstr ""
-#~ "Nie mogê ustawiæ œcie¿ki: sys.path nie jest list¹\n"
-#~ "Powinno siê teraz dodaæ vim.VIM_SPECIAL_PATH do sys.path"
-
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspace musi byæ liczb¹ ca³kowit¹"
-
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<obiekt bufora (skasowany) w %p>"
-
-#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
-#~ msgstr ""
-#~ "E281: B£¥D TCL: kod zakoñczeniowy nie jest ca³kowity!? Proszê z³o¿yæ "
-#~ "raport o tym na vim-dev@vim.org"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja RISC OS):\n"
-
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <number>\tPocz¹tkowa szerokoœæ okna w kolumnach"
-
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <number>\tPocz¹tkowa wysokoœæ okna w wierszach"
-
-#~ msgid "E505: "
-#~ msgstr "E505: "
-
-#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla RISC OS"
-
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines() wymaga listy ci¹gów"
-
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<obiekt okna (skasowany) w %p>"
-
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<obiekt okna (nieznany) w %p>"
-
-#~ msgid "<window %d>"
-#~ msgstr "<okno %d>"
-
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <nazwa>\t\tU¿ywaj zasobów tak jak by Vim by³ <nazwa>"
-
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (Niezaimplementowane)\n"
-
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: argument containedin niedozwolony w tym miejscu"
-
-#~ msgid "Vim dialog..."
-#~ msgstr "Dialog Vima..."
-
-#~ msgid "Font Selection"
-#~ msgstr "Wybór czcionki"
-
-#~ msgid "E290: over-the-spot style requires fontset"
-#~ msgstr "E290: styl nadpunktowy wymaga +fontset"
-
-#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
-#~ msgstr "E291: Twój GTK+ jest starszy ni¿ 1.2.3. Pole statusu wy³¹czono"
-
-#~ msgid "E292: Input Method Server is not running"
-#~ msgstr "E292: Serwer metod wprowadzeñ nie jest uruchomiony"
-
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "z GTK-GNOME GUI."
-
-#~ msgid "with GTK GUI."
-#~ msgstr "z GTK GUI."
-
-#~ msgid "[NL found]"
-#~ msgstr "[znaleziono NL]"
-
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: wyczerpano maksymaln¹ liczbê po³¹czeñ cscope"
diff --git a/src/nvim/po/pl.po b/src/nvim/po/pl.po
deleted file mode 100644
index 2a2d12daac..0000000000
--- a/src/nvim/po/pl.po
+++ /dev/null
@@ -1,8264 +0,0 @@
-# translation of pl.po to Polish
-# Polish Translation for Vim
-#
-# updated 2013 for vim-7.4
-#
-# FIRST AUTHOR Marcin Dalecki <martin@dalecki.de>, 2000.
-# Mikolaj Machowski <mikmach@wp.pl>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013.
-msgid ""
-msgstr ""
-"Project-Id-Version: pl\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2010-08-10 18:15+0200\n"
-"Last-Translator: Mikolaj Machowski <mikmach@wp.pl>\n"
-"Language: pl\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ISO-8859-2\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Lokalize 1.0\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
-"|| n%100>=20) ? 1 : 2);\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "nie mogê pobraæ warto¶ci opcji"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "b³±d wewnêtrzny: nieznany typ opcji"
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[Lista lokacji]"
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[Lista quickfix]"
-
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr "E855: Autokomendy spowodowa³y porzucenie komendy"
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: Nie mogê zarezerwowaæ bufora; zakoñczenie..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: Nie mogê zarezerwowaæ bufora; u¿ywam innego..."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: Nie wy³adowano ¿adnego bufora"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: Nie skasowano ¿adnego bufora"
-
-#: ../buffer.c:767
-msgid "E517: No buffers were wiped out"
-msgstr "E517: Nie wyrzucono ¿adnego bufora"
-
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "1 bufor wy³adowany"
-
-#: ../buffer.c:774
-#, c-format
-msgid "%d buffers unloaded"
-msgstr "wy³adowano %d buforów"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "1 bufor skasowany"
-
-#: ../buffer.c:779
-#, c-format
-msgid "%d buffers deleted"
-msgstr "%d buforów skasowano"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "wyrzucono 1 bufor "
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "wyrzucono %d buforów"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: Nie mogê wy³adowaæ ostatniego bufora"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: Nie znaleziono zmienionych buforów"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-msgid "E85: There is no listed buffer"
-msgstr "E85: Nie ma wylistowanych buforów"
-
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: Bufor \"%<PRId64>\" nie istnieje"
-
-#: ../buffer.c:915
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: Nie mogê przej¶æ poza ostatni bufor"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: Nie mogê przej¶æ przed pierwszy bufor"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: Nie zapisano zmian w buforze %<PRId64> (wymu¶ przez !)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: OSTRZE¯ENIE: Przepe³nienie listy nazw plików"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Nie znaleziono bufora %<PRId64>"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: Wielokrotne dopasowania dla %s"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: ¯aden bufor nie pasuje do %s"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "wiersz %<PRId64>"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: Bufor o tej nazwie ju¿ istnieje"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [Zmieniony]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[Nie edytowany]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[Nowy Plik]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[B³±d odczytu]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[RO]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-msgid "[readonly]"
-msgstr "[tylko odczyt]"
-
-#: ../buffer.c:2524
-#, c-format
-msgid "1 line --%d%%--"
-msgstr "1 wiersz --%d%%--"
-
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> wiersze --%d%%--"
-
-#: ../buffer.c:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "wiersz %<PRId64> z %<PRId64> --%d%%-- kol "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-msgid "[No Name]"
-msgstr "[Bez nazwy]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "pomoc"
-
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[Pomoc]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[Podgl±d]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "Wszystko"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "Dó³"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "Góra"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# Lista buforów:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr "[Notka]"
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- Znaki ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "Znaki dla %s:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " wiersz=%<PRId64> id=%d nazwa=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: Brak dwukropka"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: Niedozwolony tryb"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: oczekiwa³em na cyfrê"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Niedozwolony procent"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Nie mogê zró¿nicowaæ wiêcej ni¿ %<PRId64> buforów"
-
-#: ../diff.c:753
-msgid "E810: Cannot read or write temp files"
-msgstr "E810: Nie mogê otworzyæ lub zapisaæ plików tymczasowych"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: Nie mogê stworzyæ ró¿nic"
-
-#: ../diff.c:966
-msgid "E816: Cannot read patch output"
-msgstr "E816: Nie mogê odczytaæ wyj¶cia pliku ³aty"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: Nie mogê wczytaæ wyj¶cia ró¿nicy"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: Bie¿±cy bufor nie jest w trybie ró¿nic"
-
-#: ../diff.c:2100
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E793: ¯aden inny bufor w trybie diff nie jest modyfikowalny"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: Brak innego bufora w trybie ró¿nic"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr ""
-"E101: Wiêcej ni¿ jeden bufor w trybie ró¿nicowania, nie wiem którego u¿yæ"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: Nie mogê znale¼æ bufora \"%s\""
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: Bufor \"%s\" nie jest w trybie ró¿nicowania"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr "E787: Nieoczekiwana zmiana bufora"
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: Escape jest niedozwolone w dwugrafie"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: Nie znaleziono pliku rozk³adu klawiszy"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: Zastosowano :loadkeymap w niewczytanym pliku"
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr "E791: Pusty wpis keymap"
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " Dope³nianie s³ów kluczowych (^N^P)"
-
-#. 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 tryb (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " Dope³nianie pe³nych wierszy (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " Dope³nianie nazw plików (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " Dope³nianie znaczników (^]^N^P)"
-
-#: ../edit.c:88
-msgid " Path pattern completion (^N^P)"
-msgstr " Dope³nianie wzorców tropów (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " Dope³nianie definicji (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Dope³nianie ze s³owników (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " Dope³nianie z tezaurusa (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " Dope³nianie wiersza poleceñ (^V^N^P)"
-
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr "Dope³nianie zdefiniowane przez u¿ytkownika (^U^N^P)"
-
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " Omni uzupe³nianie (^O^N^P)"
-
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr "Propozycja pisowni (^L^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " Lokalne dope³nianie s³ów kluczowych (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "Dobi³em do koñca akapitu"
-
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr "E839: Funkcja uzupe³niania zmieni³a okno"
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr "E840: Funkcja uzupe³nania usunê³a tekst"
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "opcja 'dictionary' jest pusta"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "opcja 'thesaurus' jest pusta"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "Przegl±dam s³ownik: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (wprowadzanie) Przewijanie (^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (zamiana) Przewijanie (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "Przegl±dam: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "Przegl±dam znaczniki."
-
-#: ../edit.c:4519
-msgid " Adding"
-msgstr " Dodajê"
-
-#. 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 "-- Szukam..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "Z powrotem na pierwotnym"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "Wyraz z innego wiersza"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "Jedyne dopasowanie"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "pasuje %d z %d"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "pasuje %d"
-
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: Nieoczekiwane znaki w :let"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: Indeks listy poza zakresem: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Nieokre¶lona zmienna: %s"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: Brak ']'"
-
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: Argument %s musi byæ List±"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Argument %s musi byæ List± lub S³ownikiem"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Nie mo¿na u¿yæ pustego klucza dla S³ownika"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: wymagana Lista"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: wymagany S³ownik"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: Zbyt wiele argumentów dla funkcji: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Klucz nie istnieje w S³owniku: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: Funkcja %s ju¿ istnieje; aby j± zamieniæ u¿yj !"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: istnieje ju¿ taki element S³ownika"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: wymagana Funcref"
-
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: Nie mo¿na u¿yæ [:] przy S³owniku"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: Z³y typ zmiennej dla %s="
-
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Nieznana funkcja: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: Niedozwolona nazwa zmiennej: %s"
-
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: U¿ycie Zmiennoprzecinkowej jako £añcucha"
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: Mniej celów ni¿ elementów Listy"
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: Wiêcej celów ni¿ elementów Listy"
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "Podwójny ; w li¶cie zmiennych"
-
-#: ../eval.c:2078
-#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: Nie mogê wypisaæ zmiennych dla %s"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: Indeks mo¿e istnieæ tylko dla Listy lub S³ownika"
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:] musi byæ ostatnie"
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:] wymaga warto¶ci listy"
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: Lista ma wiêcej elementów ni¿ cel"
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: Lista nie ma wystarczaj±cej ilo¶ci elementów"
-
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: Brak \"in\" po :for"
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Brak nawiasów: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: Nie istnieje zmienna: \"%s\""
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: zmienna zagnie¿d¿ona zbyt g³êboko dla (un)lock"
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: Brak ':' po '?'"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: Listê mogê porównaæ tylko z List±"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: Nieprawid³owa operacja dla Listy"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: S³ownik mogê porównaæ tylko ze S³ownikiem"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: Nieprawid³owa operacja dla S³ownika"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Funcref mogê porównaæ tylko z Funcref"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: Nieprawid³owa operacja dla Funcref"
-
-#: ../eval.c:4277
-msgid "E804: Cannot use '%' with Float"
-msgstr "E804: Nie mogê u¿yæ '%' w Zmiennoprzecinkowej"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: Brak ')'"
-
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: Nie mo¿na zindeksowaæ Funcref"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: Brak nazwy opcji: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: Nieznana opcja: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: Brak cudzys³owu: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: Brak cudzys³owu: %s"
-
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Brakuj±cy przecinek w Li¶cie: '%s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: Brak zakoñczenia Listy ']': %s"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Brak dwukropka w S³owniku: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Powtórzony klucz w S³owniku: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Brakuj±cy przecinek w S³owniku: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Brak koñca w S³owniku '}': %s"
-
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: Zmienna zagnie¿d¿ona zbyt g³êboko by pokazaæ"
-
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: Zbyt wiele argumentów dla funkcji %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Zbyt wiele argumentów dla funkcji %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Nieznana funkcja: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Za ma³o argumentów dla funkcji: %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: U¿ycie <SID> poza kontekstem skryptu: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Wywo³anie funkcji \"dict\" bez S³ownika: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Wymagana Liczba lub Zmiennoprzecinkowa"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "argument add()"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: Za du¿o argumentów"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() mo¿e byæ u¿yte tylko w trybie Wprowadzania"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Klucz ju¿ istnieje: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "argument extend()"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "argument map()"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "argument filter()"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld wierszy: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: Nieznana funkcja: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "wywo³ano inputrestore() wiêcej razy ni¿ inputsave()"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "argument insert()"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: Zakres niedozwolony"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: Nieprawid³owy typ dla len()"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: Skok to zero"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: Pocz±tek po koñcu"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<pusty>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "argument remove()"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: Za du¿o dowi±zañ symbolicznych (pêtla?)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "argument reverse()"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "argument sort()"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "argument add()"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Funkcja porównywania w sort nie powiod³a siê"
-
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Funkcja porównywania w sort nie powiod³a siê"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(Niew³a¶ciwe)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: B³±d zapisywania pliku tymczasowego"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: U¿ycie Zmiennoprzecinkowej jako Liczby"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: U¿ycie Funcref jako Liczby"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: U¿ycie Listy jako Liczby"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: U¿ycie S³ownika jako Liczby"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: U¿ycie Funcref jako £añcucha"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: U¿ycie Listy jako £añcucha"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: U¿ycie S³ownika jako £añcucha"
-
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Nieprawid³owy typ zmiennej dla: %s"
-
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Nie mogê usun±æ zmiennej %s"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Nazwa Funcref musi siê zaczynaæ wielk± liter±: %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: Nazwa zmiennej jest w konflikcie z istniej±c± funkcj±: %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: Warto¶æ jest zablokowana: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Nieznane"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Nie mogê zmieniæ warto¶ci %s"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: Zmienna zagnie¿d¿ona zbyt g³êboko by zrobiæ kopiê"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Nieznana funkcja: %s"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: Brak '(': %s"
-
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: Nie mo¿na tutaj u¿yæ g:"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Niedozwolony argument: %s"
-
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Powtórzona nazwa argumentu: %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: Brak :endfunction"
-
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Nazwa funkcji jest w konflikcie ze zmienn±: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Nie mogê redefiniowaæ funkcji %s: jest w u¿yciu"
-
-#: ../eval.c:17604
-#, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E746: Nazwa funkcji nie pasuje do nazwy skryptu: %s"
-
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: Wymagana jest nazwa funkcji"
-
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Nazwa funkcji musi rozpoczynaæ siê wielk± liter± lub zawieraæ "
-"dwukropek: %s"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr ""
-"E128: Nazwa funkcji musi rozpoczynaæ siê wielk± liter± lub zawieraæ "
-"dwukropek: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Nie mogê skasowaæ funkcji %s: jest w u¿yciu"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Zagnie¿d¿enie wywo³añ funkcji ponad 'maxfuncdepth'"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "wywo³ujê %s"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "porzucono %s"
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s zwraca #%<PRId64>"
-
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%s zwraca %s"
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "kontynuacja w %s"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return poza funkcj±"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# zmienne globalne:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tOstatnie ustawienie przez "
-
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Brak starych plików"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, Hex %02x, Oktal %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, Hex %04x, Oktal %o"
-
-#: ../ex_cmds.c:146
-#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, Hex %08x, Oktal %o"
-
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: Przeniesienie wierszy na siebie samych"
-
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "1 wiersz przeniesiony"
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "%<PRId64> wiersze przeniesione"
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "%<PRId64> wierszy przefiltrowanych"
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: Autokomendy *Filter* nie mog± zmieniaæ bie¿±cego bufora"
-
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[Brak zapisu od czasu ostatniej zmiany]\n"
-
-#: ../ex_cmds.c:1424
-#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s w wierszu: "
-
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: Zbyt wiele b³êdów; pomijam resztê pliku"
-
-#: ../ex_cmds.c:1458
-#, c-format
-msgid "Reading viminfo file \"%s\"%s%s%s"
-msgstr "Wczytujê plik viminfo \"%s\"%s%s%s"
-
-#: ../ex_cmds.c:1460
-msgid " info"
-msgstr " informacja"
-
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " zak³adki"
-
-#: ../ex_cmds.c:1462
-msgid " oldfiles"
-msgstr " stare pliki"
-
-#: ../ex_cmds.c:1463
-msgid " FAILED"
-msgstr " NIE POWIOD£O SIÊ"
-
-#. 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: Plik viminfo jest niezapisywalny: %s"
-
-#: ../ex_cmds.c:1626
-#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: Nie mogê zapisaæ pliku viminfo %s!"
-
-#: ../ex_cmds.c:1635
-#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "Zapisujê plik viminfo \"%s\""
-
-#. Write the info:
-#: ../ex_cmds.c:1720
-#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# Ten plik viminfo zosta³ wygenerowany przez Vima %s.\n"
-
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# Mo¿esz go ostro¿nie edytowaæ!\n"
-"\n"
-
-#: ../ex_cmds.c:1723
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# Warto¶æ 'encoding' w czasie zapisu tego pliku\n"
-
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "Niedopuszczalny pocz±tkowy znak"
-
-#: ../ex_cmds.c:2162
-msgid "Write partial file?"
-msgstr "Zapisaæ czê¶ciowo plik?"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: Stosuj ! do zapisania czê¶ciowo bufora"
-
-#: ../ex_cmds.c:2281
-#, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "Nadpisaæ istniej±cy plik \"%s\"?"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr "Plik wymiany \"%s\" istnieje, czy go nadpisaæ?"
-
-#: ../ex_cmds.c:2326
-#, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E768: Plik wymiany istnieje: %s (wymu¶ poprzez :silent!)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Brak nazwy pliku dla bufora %<PRId64>"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: Plik niezapisany: Zapis jest wy³±czony opcj± 'write'"
-
-#: ../ex_cmds.c:2434
-#, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"opcja 'readonly' nastawiona dla \"%s\".\n"
-"Czy chcesz go pomimo tego zapisaæ?"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-"Prawa pliku \"%s\" s± tylko do odczytu.\n"
-"Mimo to byæ mo¿e uda siê zmieniæ ten plik.\n"
-"Chcesz spróbowaæ?"
-
-#: ../ex_cmds.c:2451
-#, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "E505: \"%s\" jest tylko do odczytu (dodaj ! aby wymusiæ)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: Autokomendy nieoczekiwanie skasowa³y nowy bufor %s"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: nienumeryczny argument dla :z"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: Komendy pow³oki s± niedozwolone w rvim"
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: Wzorce regularne nie mog± byæ rozgraniczane literami"
-
-#: ../ex_cmds.c:3964
-#, c-format
-msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
-msgstr "zamieñ na %s (y/n/a/q/l/^E/^Y)?"
-
-#: ../ex_cmds.c:4379
-msgid "(Interrupted) "
-msgstr "(Przerwane) "
-
-#: ../ex_cmds.c:4384
-msgid "1 match"
-msgstr "1 pasuje"
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "1 podstawienie "
-
-#: ../ex_cmds.c:4387
-#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> dopasowañ"
-
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> podstawieñ"
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr " w 1 wierszu"
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr " w %<PRId64> wierszach"
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: Nie mogê wykonaæ :global rekursywnie"
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: Brak wzorca regularnego w :global"
-
-# c-format
-#: ../ex_cmds.c:4508
-#, c-format
-msgid "Pattern found in every line: %s"
-msgstr "Wzorzec znaleziono w ka¿dym wierszu: %s"
-
-#: ../ex_cmds.c:4510
-#, c-format
-msgid "Pattern not found: %s"
-msgstr "Nie znaleziono wzorca: %s"
-
-#: ../ex_cmds.c:4587
-msgid ""
-"\n"
-"# Last Substitute String:\n"
-"$"
-msgstr ""
-"\n"
-"# Ostatni podstawiany ci±g:\n"
-"$"
-
-#: ../ex_cmds.c:4679
-msgid "E478: Don't panic!"
-msgstr "E478: Nie panikuj!"
-
-#: ../ex_cmds.c:4717
-#, c-format
-msgid "E661: Sorry, no '%s' help for %s"
-msgstr "E661: Przykro mi, brak '%s' pomocy dla %s"
-
-#: ../ex_cmds.c:4719
-#, c-format
-msgid "E149: Sorry, no help for %s"
-msgstr "E149: Przykro mi, ale brak pomocy o %s"
-
-#: ../ex_cmds.c:4751
-#, c-format
-msgid "Sorry, help file \"%s\" not found"
-msgstr "Przykro mi, nie ma pliku pomocy \"%s\""
-
-#: ../ex_cmds.c:5323
-#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: Nie jest katalogiem: %s"
-
-#: ../ex_cmds.c:5446
-#, c-format
-msgid "E152: Cannot open %s for writing"
-msgstr "E152: Nie mogê otworzyæ %s do zapisu"
-
-#: ../ex_cmds.c:5471
-#, c-format
-msgid "E153: Unable to open %s for reading"
-msgstr "E153: Nie mogê otworzyæ %s do odczytu"
-
-#: ../ex_cmds.c:5500
-#, c-format
-msgid "E670: Mix of help file encodings within a language: %s"
-msgstr "E670: Mieszanka kodowañ w pliku pomocy w ramach jêzyka: %s"
-
-#: ../ex_cmds.c:5565
-#, c-format
-msgid "E154: Duplicate tag \"%s\" in file %s/%s"
-msgstr "E154: Powtórzony znacznik \"%s\" w pliku %s/%s"
-
-#: ../ex_cmds.c:5687
-#, c-format
-msgid "E160: Unknown sign command: %s"
-msgstr "E160: Nieznana komenda znaku: %s"
-
-#: ../ex_cmds.c:5704
-msgid "E156: Missing sign name"
-msgstr "E156: Brak nazwy znaku"
-
-#: ../ex_cmds.c:5746
-msgid "E612: Too many signs defined"
-msgstr "E612: Zbyt wiele nazw znaków"
-
-#: ../ex_cmds.c:5813
-#, c-format
-msgid "E239: Invalid sign text: %s"
-msgstr "E239: Niew³a¶ciwy tekst znaku: %s"
-
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
-#, c-format
-msgid "E155: Unknown sign: %s"
-msgstr "E155: Nieznany znak: %s"
-
-#: ../ex_cmds.c:5877
-msgid "E159: Missing sign number"
-msgstr "E159: Brak numeru znaku"
-
-#: ../ex_cmds.c:5971
-#, c-format
-msgid "E158: Invalid buffer name: %s"
-msgstr "E158: Niew³a¶ciwa nazwa bufora: %s"
-
-#: ../ex_cmds.c:6008
-#, c-format
-msgid "E157: Invalid sign ID: %<PRId64>"
-msgstr "E157: Niew³a¶ciwe ID znaku: %<PRId64>"
-
-#: ../ex_cmds.c:6066
-msgid " (not supported)"
-msgstr "(nie wspomagane)"
-
-#: ../ex_cmds.c:6169
-msgid "[Deleted]"
-msgstr "[Skasowano]"
-
-#: ../ex_cmds2.c:139
-msgid "Entering Debug mode. Type \"cont\" to continue."
-msgstr "Wchodzê w tryb odpluskwiania. Wprowad¼ \"cont\" aby kontynuowaæ."
-
-#: ../ex_cmds2.c:143 ../ex_docmd.c:759
-#, c-format
-msgid "line %<PRId64>: %s"
-msgstr "wiersz %<PRId64>: %s"
-
-#: ../ex_cmds2.c:145
-#, c-format
-msgid "cmd: %s"
-msgstr "cmd: %s"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Punkt kontrolny w \"%s%s\" wiersz %<PRId64>"
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: Nie znaleziono punktu kontrolnego: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "Nie okre¶lono ¿adnych punktów kontrolnych"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s wiersz %<PRId64>"
-
-#: ../ex_cmds2.c:942
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: Pierwsze u¿ycie \":profile start {fname}\""
-
-#: ../ex_cmds2.c:1269
-#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "Zachowaæ zmiany w \"%s\"?"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "Bez Tytu³u"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: Nie zapisano zmian w buforze \"%s\""
-
-#: ../ex_cmds2.c:1480
-msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
-msgstr "OSTRZE¯ENIE: Nieoczekiwane wej¶cie w inny bufor (sprawd¼ autokomendy)"
-
-#: ../ex_cmds2.c:1826
-msgid "E163: There is only one file to edit"
-msgstr "E163: Tylko jeden plik w edycji"
-
-#: ../ex_cmds2.c:1828
-msgid "E164: Cannot go before first file"
-msgstr "E164: Nie mo¿na przej¶æ przed pierwszy plik"
-
-#: ../ex_cmds2.c:1830
-msgid "E165: Cannot go beyond last file"
-msgstr "E165: Nie mo¿na przej¶æ za ostatni plik"
-
-#: ../ex_cmds2.c:2175
-#, c-format
-msgid "E666: compiler not supported: %s"
-msgstr "E666: nie wspierany kompilator: %s"
-
-#: ../ex_cmds2.c:2257
-#, c-format
-msgid "Searching for \"%s\" in \"%s\""
-msgstr "Szukanie \"%s\" w \"%s\""
-
-#: ../ex_cmds2.c:2284
-#, c-format
-msgid "Searching for \"%s\""
-msgstr "Szukanie \"%s\""
-
-#: ../ex_cmds2.c:2307
-#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "nie znaleziono w 'runtimepath': \"%s\""
-
-#: ../ex_cmds2.c:2472
-#, c-format
-msgid "Cannot source a directory: \"%s\""
-msgstr "Nie mo¿na wczytaæ katalogu: \"%s\""
-
-#: ../ex_cmds2.c:2518
-#, c-format
-msgid "could not source \"%s\""
-msgstr "nie mog³em wczytaæ \"%s\""
-
-#: ../ex_cmds2.c:2520
-#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "wiersz: %<PRId64> nie mog³em wczytaæ \"%s\""
-
-#: ../ex_cmds2.c:2535
-#, c-format
-msgid "sourcing \"%s\""
-msgstr "wczytywanie \"%s\""
-
-#: ../ex_cmds2.c:2537
-#, c-format
-msgid "line %<PRId64>: sourcing \"%s\""
-msgstr "wiersz %<PRId64>: wczytywanie \"%s\""
-
-#: ../ex_cmds2.c:2693
-#, c-format
-msgid "finished sourcing %s"
-msgstr "skoñczono wczytywanie %s"
-
-#: ../ex_cmds2.c:2765
-msgid "modeline"
-msgstr "modeline"
-
-#: ../ex_cmds2.c:2767
-msgid "--cmd argument"
-msgstr "--cmd argument"
-
-#: ../ex_cmds2.c:2769
-msgid "-c argument"
-msgstr "-c argument"
-
-#: ../ex_cmds2.c:2771
-msgid "environment variable"
-msgstr "zmienna ¶rodowiskowa"
-
-#: ../ex_cmds2.c:2773
-msgid "error handler"
-msgstr "obs³uga b³êdu"
-
-#: ../ex_cmds2.c:3020
-msgid "W15: Warning: Wrong line separator, ^M may be missing"
-msgstr "W15: OSTRZE¯ENIE: Niew³a¶ciwy separator wierszy, pewnie brak ^M"
-
-#: ../ex_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: u¿yto :scriptencoding poza wczytywanym plikiem"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: u¿yto :finish poza wczytywanym plikiem"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "Bie¿±cy %sjêzyk: \"%s\""
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: Nie mogê ustawiæ jêzyka na \"%s\""
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "Wchodzê w tryb Ex. Wprowad¼ \"visual\" aby przej¶æ do trybu Normal."
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: Na koñcu pliku"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: Komenda zbyt rekursywna"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: Nie znaleziono wyj±tku: %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "Koniec wczytywanego pliku"
-
-#: ../ex_docmd.c:1086
-msgid "End of function"
-msgstr "Koniec funkcji"
-
-#: ../ex_docmd.c:1628
-msgid "E464: Ambiguous use of user-defined command"
-msgstr ""
-"E464: Niejednoznaczne zastosowanie komendy zdefiniowanej przez u¿ytkownika"
-
-#: ../ex_docmd.c:1638
-msgid "E492: Not an editor command"
-msgstr "E492: Nie jest komend± edytora"
-
-#: ../ex_docmd.c:1729
-msgid "E493: Backwards range given"
-msgstr "E493: Dano wsteczny zakres"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "Dano wsteczny zakres; zamiana jest mo¿liwa"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: Stosuj w lub w>>"
-
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: Przykro mi, ale ta komenda nie jest dostêpna w tej wersji"
-
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: Tylko pojedyncza nazwa pliku dozwolona"
-
-#: ../ex_docmd.c:4238
-msgid "1 more file to edit. Quit anyway?"
-msgstr "1 wiêcej plik do edycji. Mimo to wyj¶æ?"
-
-#: ../ex_docmd.c:4242
-#, c-format
-msgid "%d more files to edit. Quit anyway?"
-msgstr "jeszcze %d plików do edycji. Mimo to wyj¶æ?"
-
-#: ../ex_docmd.c:4248
-msgid "E173: 1 more file to edit"
-msgstr "E173: 1 wiêcej plik do edycji"
-
-#: ../ex_docmd.c:4250
-#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: jeszcze %<PRId64> plików do edycji"
-
-#: ../ex_docmd.c:4320
-msgid "E174: Command already exists: add ! to replace it"
-msgstr "E174: Komenda ju¿ istnieje; aby j± przedefiniowaæ stosuj !"
-
-#: ../ex_docmd.c:4432
-msgid ""
-"\n"
-" Name Args Range Complete Definition"
-msgstr ""
-"\n"
-" Nazwa Arg. Zak. Gotowo¶æ Definicja"
-
-#: ../ex_docmd.c:4516
-msgid "No user-defined commands found"
-msgstr "Nie znaleziono komend zdefiniowanych przez u¿ytkownika"
-
-#: ../ex_docmd.c:4538
-msgid "E175: No attribute specified"
-msgstr "E175: Nie okre¶lono atrybutu"
-
-#: ../ex_docmd.c:4583
-msgid "E176: Invalid number of arguments"
-msgstr "E176: Niew³a¶ciwa ilo¶æ argumentów"
-
-#: ../ex_docmd.c:4594
-msgid "E177: Count cannot be specified twice"
-msgstr "E177: Mno¿nik nie mo¿e byæ podany dwukrotnie"
-
-#: ../ex_docmd.c:4603
-msgid "E178: Invalid default value for count"
-msgstr "E178: Niew³a¶ciwa domy¶lna warto¶æ mno¿nika"
-
-#: ../ex_docmd.c:4625
-msgid "E179: argument required for -complete"
-msgstr "E179: -complete wymaga argumentu"
-
-#: ../ex_docmd.c:4635
-#, c-format
-msgid "E181: Invalid attribute: %s"
-msgstr "E181: Niew³a¶ciwy atrybut: %s"
-
-#: ../ex_docmd.c:4678
-msgid "E182: Invalid command name"
-msgstr "E182: Niew³a¶ciwa nazwa komendy"
-
-#: ../ex_docmd.c:4691
-msgid "E183: User defined commands must start with an uppercase letter"
-msgstr ""
-"E183: Komendy zdefiniowane przez u¿ytkownika musz± rozpoczynaæ siê du¿± "
-"liter±"
-
-#: ../ex_docmd.c:4696
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E841: Nazwa zastrze¿ona, nie mo¿na jej u¿yæ w komendzie u¿ytkownika"
-
-#: ../ex_docmd.c:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: Nie ma takiej komendy u¿ytkownika: %s"
-
-#: ../ex_docmd.c:5219
-#, c-format
-msgid "E180: Invalid complete value: %s"
-msgstr "E180: Niew³a¶ciwa warto¶æ dope³niania: %s"
-
-#: ../ex_docmd.c:5225
-msgid "E468: Completion argument only allowed for custom completion"
-msgstr ""
-"E468: Argument depe³niania dozwolony wy³±cznie dla dope³niania u¿ytkownika"
-
-#: ../ex_docmd.c:5231
-msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Dope³nianie u¿ytkownika wymaga funkcji jako argumentu"
-
-#: ../ex_docmd.c:5257
-#, c-format
-msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Nie mogê znale¼æ zestawu kolorów '%s'"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "Witaj u¿ytkowniku Vima!"
-
-#: ../ex_docmd.c:5431
-msgid "E784: Cannot close last tab page"
-msgstr "E784: Nie mogê zamkn±æ ostatniej karty"
-
-#: ../ex_docmd.c:5462
-msgid "Already only one tab page"
-msgstr "Jest ju¿ tylko jedna karta"
-
-#: ../ex_docmd.c:6004
-#, c-format
-msgid "Tab page %d"
-msgstr "Karta %d"
-
-#: ../ex_docmd.c:6295
-msgid "No swap file"
-msgstr "Brak pliku wymiany"
-
-#: ../ex_docmd.c:6478
-msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
-msgstr ""
-"E747: Nie mogê zmieniæ katalogu, bufor zosta³ zmodyfikowany (dodaj ! aby "
-"wymusiæ)"
-
-#: ../ex_docmd.c:6485
-msgid "E186: No previous directory"
-msgstr "E186: Nie ma poprzedniego katalogu"
-
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: Nieznany"
-
-#: ../ex_docmd.c:6610
-msgid "E465: :winsize requires two number arguments"
-msgstr "E465: :winsize wymaga dwóch argumentów numerycznych"
-
-#: ../ex_docmd.c:6655
-msgid "E188: Obtaining window position not implemented for this platform"
-msgstr ""
-"E188: Pozyskiwanie pozycji okna nie jest zaimplementowane dla tego systemu"
-
-#: ../ex_docmd.c:6662
-msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos wymaga dwóch argumentów numerycznych"
-
-#: ../ex_docmd.c:7241
-#, c-format
-msgid "E739: Cannot create directory: %s"
-msgstr "E739: Nie mogê utworzyæ katalogu: %s"
-
-#: ../ex_docmd.c:7268
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: \"%s\" istnieje (wymu¶ poprzez !)"
-
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: Nie mogê otworzyæ \"%s\" do zapisu"
-
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: Argument musi byæ liter± albo cudzys³owem w przód/ty³"
-
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: Rekursywne zastosowanie :normal za g³êbokie"
-
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: Brak nazwy zamiennego pliku do podstawienia pod '#'"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: brak nazwy pliku autokomend do podstawienia pod \"<afile>\""
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: brak numeru bufora autokomend do podstawienia pod \"<abuf>\""
-
-#: ../ex_docmd.c:7861
-msgid "E497: no autocommand match name to substitute for \"<amatch>\""
-msgstr "E497: brak nazwy dopasowania autokomend pod \"<amatch>\""
-
-#: ../ex_docmd.c:7870
-msgid "E498: no :source file name to substitute for \"<sfile>\""
-msgstr "E498: brak nazwy pliku :source do postawienia pod \"<sfile>\""
-
-#: ../ex_docmd.c:7876
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E842: brak numeru linii by u¿yæ z \"<slnum>\""
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: Pusta nazwa pliku dla '%' lub '#', dzia³a tylko z \":p:h\""
-
-#: ../ex_docmd.c:7905
-msgid "E500: Evaluates to an empty string"
-msgstr "E500: Wynikiem jest pusty ci±g"
-
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: Nie mogê otworzyæ pliku viminfo do odczytu"
-
-#: ../ex_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: Nie mo¿na ':throw' wyj±tków z prefiksem 'Vim'"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "Wyj±tek: %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "Wyj±tek zakoñczony: %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "Wyj±tek odrzucony: %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, wiersz %<PRId64>"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "Wyj±tek przechwycony: %s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr "%s zosta³ zawieszony"
-
-#: ../ex_eval.c:679
-#, c-format
-msgid "%s resumed"
-msgstr "%s przywrócony"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr "%s odrzucony"
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "Wyj±tek"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "B³±d i przerwanie"
-
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "B³±d"
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "Przerwanie"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: zbyt g³êbokie zagnie¿d¿enie :if"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :endif bez :if"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :else bez :if"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :elseif bez :if"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: wielokrotne :else"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :elseif po :else"
-
-#: ../ex_eval.c:941
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: zbyt g³êbokie zagnie¿d¿enie :while/:for"
-
-#: ../ex_eval.c:1028
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :continue bez :while lub :for"
-
-#: ../ex_eval.c:1061
-msgid "E587: :break without :while or :for"
-msgstr "E587: :break bez :while lub :for"
-
-#: ../ex_eval.c:1102
-msgid "E732: Using :endfor with :while"
-msgstr "E732: U¿ycie :endfor z :while"
-
-#: ../ex_eval.c:1104
-msgid "E733: Using :endwhile with :for"
-msgstr "E733: U¿ycie :endwhile z :for"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: zbyt g³êbokie zagnie¿d¿enie :try"
-
-#: ../ex_eval.c:1317
-msgid "E603: :catch without :try"
-msgstr "E603: :catch bez :try"
-
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
-msgid "E604: :catch after :finally"
-msgstr "E604: :catch za :finally"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :finally bez :try"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: wielokrotne :finally"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :endtry bez :try"
-
-#: ../ex_eval.c:2026
-msgid "E193: :endfunction not inside a function"
-msgstr "E193: :endfunction poza funkcj±"
-
-#: ../ex_getln.c:1643
-msgid "E788: Not allowed to edit another buffer now"
-msgstr "E788: Nie mo¿na teraz edytowaæ innego bufora"
-
-#: ../ex_getln.c:1656
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E811: Nie mo¿na teraz zmieniaæ informacji o buforze"
-
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "nazwa znacznika"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " pokrewny plik\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "opcja 'history' jest zerowa"
-
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s Historia (od najnowszych po najstarsze):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "Wiersz poleceñ"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "Szukany ci±g"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "Wyra¿enie"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "Wiersz wprowadzeñ"
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar przekracza d³ugo¶æ polecenia"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: Aktywny widok lub bufor skasowany"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: ¶cie¿ka za d³uga by uzupe³niæ"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Niew³a¶ciwy trop: '**[numer]' musi byæ na koñcu tropu lub po nim musi "
-"byæ '%s'."
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Nie mogê znale¼æ katalogu \"%s\" w cdpath"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Nie mogê znale¼æ pliku \"%s\" w tropie"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Katalogu \"%s\" nie ma wiêcej w cdpath"
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Pliku \"%s\" nie ma wiêcej w tropie"
-
-#: ../fileio.c:137
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E812: Autokomendy zmieni³y bufor lub jego nazwê"
-
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "Niedopuszczalna nazwa pliku"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "jest katalogiem"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "nie jest plikiem"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[Nowy Plik]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr "[Nowy KATALOG]"
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr "[Za du¿y plik]"
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[Nie dozwolono]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200: Autokomendy *ReadPre zrobi³y plik nieodczytywalnym"
-
-#: ../fileio.c:655
-msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: Autokomendy *ReadPre nie mog± zmieniaæ bie¿±cego bufora"
-
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: Wczytywanie ze stdin...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202: Nie mo¿na otworzyæ pliku utworzonego przez przemianê!"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[fifo/socket]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[fifo]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[socket]"
-
-#. or character special
-#: ../fileio.c:1801
-msgid "[character special]"
-msgstr "[specjalny znak]"
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[brak CR]'"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[d³ugie wiersze rozdzielane]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[NIE przemienione]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[przemienione]"
-
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[B£¡D W PRZEMIANIE w linii %<PRId64>]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[NIEDOZWOLONY BAJT w wierszu %<PRId64>]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[B£ÊDY W ODCZYCIE]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "Nie mogê znale¼æ pliku tymczasowego w celu przemiany"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "Nieudana przemiana z 'charconvert'"
-
-#: ../fileio.c:2113
-msgid "can't read output of 'charconvert'"
-msgstr "nie mogê odczytaæ wyj¶cia z 'charconvert'"
-
-#: ../fileio.c:2437
-msgid "E676: No matching autocommands for acwrite buffer"
-msgstr "E676: Brak pasuj±cych autokomend dla bufora acwrite"
-
-#: ../fileio.c:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr ""
-"E203: Autokomendy skasowa³y lub wy³adowa³y bufor przeznaczony do zapisu"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: Autokomenda zmieni³a liczbê wierszy w nieoczekiwany sposób"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "nie jest plikiem lub zapisywalnym przyrz±dem"
-
-#: ../fileio.c:2601
-msgid "is read-only (add ! to override)"
-msgstr "jest tylko do odczytu (wymu¶ poprzez !)"
-
-#: ../fileio.c:2886
-msgid "E506: Can't write to backup file (add ! to override)"
-msgstr "E506: Nie mogê zapisaæ do pliku zabezpieczenia (wymu¶ przez !)"
-
-#: ../fileio.c:2898
-msgid "E507: Close error for backup file (add ! to override)"
-msgstr "E507: B³±d podczas zamykania pliku zabezpieczenia (wymu¶ przez !)"
-
-#: ../fileio.c:2901
-msgid "E508: Can't read file for backup (add ! to override)"
-msgstr "E508: Nie mogê odczytaæ pliku w celu zabezpieczenia (wymu¶ przez !)"
-
-#: ../fileio.c:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr "E509: Nie mogê stworzyæ pliku zabezpieczenia (wymu¶ przez !)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr "E510: Nie mogê zrobiæ pliku zabezpieczenia (wymu¶ przez !)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: Nie mogê znale¼æ pliku tymczasowego do zapisania"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr "E213: Nie mogê przemieniæ (u¿yj ! by zapisaæ bez przemiany)"
-
-#: ../fileio.c:3169
-msgid "E166: Can't open linked file for writing"
-msgstr "E166: Nie mogê otworzyæ pod³±czonego pliku do zapisu"
-
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: Nie mogê otworzyæ pliku do zapisu"
-
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: Fsync nie powiód³ siê"
-
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Zamkniêcie siê nie powiod³o"
-
-#: ../fileio.c:3436
-msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr ""
-"E513: B³±d zapisu, przemiana siê nie powiod³a (opró¿nij 'fenc' aby wymusiæ)"
-
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: B³±d zapisu, przemiana siê nie powiod³a w wierszu %<PRId64> (opró¿nij "
-"'fenc' by wymusiæ)"
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: b³±d w zapisie (mo¿e system plików jest przepe³niony?)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr " B£¡D W PRZEMIANIE"
-
-#: ../fileio.c:3509
-#, c-format
-msgid " in line %<PRId64>;"
-msgstr " w wierszu %<PRId64>;"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[Urz±dzenie]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[Nowy]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr " [a]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " do³±czono"
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr " [w]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " zapisano"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Patchmode: nie mogê zapisaæ oryginalnego pliku"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: patchmode: nie mogê stworzyæ pustego oryginalnego pliku"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: Nie mogê skasowaæ pliku zabezpieczenia"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"OSTRZE¯ENIE: Oryginalny plik mo¿e zostaæ utracony lub uszkodzony\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "nie wychod¼ edytora, dopóki plik nie zosta³ poprawnie zapisany!"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[format dos-a]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[format maca]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[format unixa]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 wiersz, "
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> wierszy, "
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 znak"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> znaków"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-msgid "[Incomplete last line]"
-msgstr "[Niekompletny ostatni wiersz]"
-
-#. don't overwrite messages here
-#. must give this prompt
-#. don't use emsg() here, don't want to flush the buffers
-#: ../fileio.c:3865
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "OSTRZE¯ENIE: Plik zmieni³ siê od czasu ostatniego odczytu!!!"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "Czy naprawdê chcesz go zapisaæ"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: B³±d zapisywania do \"%s\""
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: B³±d w trakcie zamykania \"%s\""
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: B³±d odczytu \"%s\""
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: Autokomenda FileChangedShell skasowa³a bufor"
-
-#: ../fileio.c:4894
-#, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Plik \"%s\" nie jest d³u¿ej dostêpny"
-
-#: ../fileio.c:4906
-#, c-format
-msgid ""
-"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
-"well"
-msgstr ""
-"W12: OSTRZE¯ENIE: Plik \"%s\" zmieni³ siê od czasu rozpoczêcia edycji, bufor "
-"w Vimie równie¿ zosta³ zmieniony"
-
-#: ../fileio.c:4907
-msgid "See \":help W12\" for more info."
-msgstr "Zobacz \":help W12\" dla dalszych informacji."
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: OSTRZE¯ENIE: Plik \"%s\" zmieni³ siê od czasu rozpoczêcia edycji"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "Zobacz \":help W11\" dla dalszych informacji."
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr ""
-"W16: OSTRZE¯ENIE: Tryb pliku \"%s\" zmieni³ siê od czasu rozpoczêcia edycji"
-
-#: ../fileio.c:4915
-msgid "See \":help W16\" for more info."
-msgstr "Zobacz \":help W16\" dla dalszych informacji."
-
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: OSTRZE¯ENIE: Plik \"%s\" zosta³ stworzony po rozpoczêciu edycji"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "OSTRZE¯ENIE"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"&OK\n"
-"&Za³aduj Plik"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: Nie mo¿na przygotowaæ prze³adowania \"%s\""
-
-#: ../fileio.c:5078
-#, c-format
-msgid "E321: Could not reload \"%s\""
-msgstr "E321: Nie mo¿na prze³adowaæ \"%s\""
-
-#: ../fileio.c:5601
-msgid "--Deleted--"
-msgstr "--Skasowano--"
-
-#: ../fileio.c:5732
-#, c-format
-msgid "auto-removing autocommand: %s <buffer=%d>"
-msgstr "auto-usuwanie autokomendy: %s <buffer=%d>"
-
-#. the group doesn't exist
-#: ../fileio.c:5772
-#, c-format
-msgid "E367: No such group: \"%s\""
-msgstr "E367: Nie ma takiej grupy: \"%s\""
-
-#: ../fileio.c:5897
-#, c-format
-msgid "E215: Illegal character after *: %s"
-msgstr "E215: Niedopuszczalny znak po *: %s"
-
-#: ../fileio.c:5905
-#, c-format
-msgid "E216: No such event: %s"
-msgstr "E216: Nie ma takiego wydarzenia: %s"
-
-#: ../fileio.c:5907
-#, c-format
-msgid "E216: No such group or event: %s"
-msgstr "E216: Nie ma takiej grupy lub wydarzenia: %s"
-
-#. Highlight title
-#: ../fileio.c:6090
-msgid ""
-"\n"
-"--- Auto-Commands ---"
-msgstr ""
-"\n"
-"--- Autokomendy ---"
-
-#: ../fileio.c:6293
-#, c-format
-msgid "E680: <buffer=%d>: invalid buffer number "
-msgstr "E680: <buffer=%d>: niew³a¶ciwy numer bufora"
-
-#: ../fileio.c:6370
-msgid "E217: Can't execute autocommands for ALL events"
-msgstr "E217: Nie mo¿na wykonywaæ autokomend dla wydarzeñ ALL"
-
-#: ../fileio.c:6393
-msgid "No matching autocommands"
-msgstr "Brak pasuj±cych autokomend"
-
-#: ../fileio.c:6831
-msgid "E218: autocommand nesting too deep"
-msgstr "E218: zbyt g³êbokie zagnie¿d¿enie autokomend"
-
-#: ../fileio.c:7143
-#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "%s Autokomend dla \"%s\""
-
-#: ../fileio.c:7149
-#, c-format
-msgid "Executing %s"
-msgstr "Wykonujê %s"
-
-#: ../fileio.c:7211
-#, c-format
-msgid "autocommand %s"
-msgstr "autokomenda %s"
-
-#: ../fileio.c:7795
-msgid "E219: Missing {."
-msgstr "E219: Brak {."
-
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: Brak }."
-
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: Nie znaleziono zwiniêcia"
-
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: Nie mo¿na utworzyæ zwiniêcia przy bie¿±cej 'foldmethod'"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: Nie mo¿na skasowaæ zwiniêcia przy bie¿±cej 'foldmethod'"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld wierszy zwiniêto "
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: Dodaj do bufora odczytu"
-
-#: ../getchar.c:2040
-msgid "E223: recursive mapping"
-msgstr "E223: rekursywne przyporz±dkowanie"
-
-#: ../getchar.c:2849
-#, c-format
-msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: istnieje ju¿ globalny skrót dla %s"
-
-#: ../getchar.c:2852
-#, c-format
-msgid "E225: global mapping already exists for %s"
-msgstr "E225: istnieje ju¿ globalne przyporz±dkowanie dla %s"
-
-#: ../getchar.c:2952
-#, c-format
-msgid "E226: abbreviation already exists for %s"
-msgstr "E226: istnieje ju¿ skrót dla %s"
-
-#: ../getchar.c:2955
-#, c-format
-msgid "E227: mapping already exists for %s"
-msgstr "E227: istnieje ju¿ przyporz±dkowanie dla %s"
-
-#: ../getchar.c:3008
-msgid "No abbreviation found"
-msgstr "Nie znaleziono skrótu"
-
-#: ../getchar.c:3010
-msgid "No mapping found"
-msgstr "Nie znaleziono przyporz±dkowania"
-
-#: ../getchar.c:3974
-msgid "E228: makemap: Illegal mode"
-msgstr "E228: makemap: Niedopuszczalny tryb"
-
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--Brak wierszy w buforze--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: Przerwanie komendy"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: wymagany argument"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: po \\ powinno byæ /, ? lub &"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr ""
-"E11: Niedozwolone w oknie wiersza poleceñ; <CR> wykonuje, CTRL-C opuszcza"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: Komenda niedozwolona z exrc/vimrc w bie¿±cym szukaniu katalogu lub "
-"znacznika"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: Brak :endif"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: Brak :endtry"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: Brak :endwhile"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: Brak :endfor"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile bez :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor bez :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Plik istnieje (wymu¶ poprzez !)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: Komenda nie powiod³a siê"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: B³±d wewnêtrzny"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Przerwane"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Niew³a¶ciwy adres"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Niew³a¶ciwy argument"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Niew³a¶ciwy argument: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Niew³a¶ciwe wyra¿enie: %s"
-
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Niew³a¶ciwy zakres"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Niew³a¶ciwa komenda"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" jest katalogiem"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Niew³a¶ciwa wielko¶æ przewiniêcia"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Wywo³anie z biblioteki nie powiod³o siê dla \"%s()\""
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: Zak³adka ma niew³a¶ciwy numer wiersza"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Zak³adka nienastawiona"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Nie mogê wykonaæ zmian, 'modifiable' jest wy³±czone"
-
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Zbyt g³êbokie zagnie¿d¿enie skryptów"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Brak pliku zamiany"
-
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Nie ma takiego skrótu"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: Niedozwolone !"
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: GUI nie mo¿e byæ u¿yte: Nie w³±czono podczas kompilacji"
-
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Brak takiej nazwy grupy pod¶wietlania: %s"
-
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: Nie wprowadzono jeszcze ¿adnego tekstu"
-
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Nie ma poprzedniego wiersza poleceñ"
-
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Nie ma takiego przyporz±dkowania"
-
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Brak dopasowañ"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Brak dopasowañ: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Brak nazwy pliku"
-
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Brak poprzedniego podstawieniowego wyra¿enia regularnego"
-
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Brak poprzedniej komendy"
-
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Brak poprzedniego wyra¿enia regularnego"
-
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Zakres niedozwolony"
-
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: Brak miejsca"
-
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Nie mogê stworzyæ pliku %s"
-
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Nie mogê pobraæ nazwy pliku tymczasowego"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Nie mogê otworzyæ pliku %s"
-
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: Nie mogê odczytaæ pliku %s"
-
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: Nie zapisano od ostatniej zmiany (wymu¶ przez !)"
-
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[Brak zapisu od czasu ostatniej zmiany]\n"
-
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: Zerowy argument"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Oczekujê liczby"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Nie mogê otworzyæ pliku b³êdów %s"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Pamiêæ wyczerpana!"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Nie znaleziono wzorca"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Nie znaleziono wzorca: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: Argument musi byæ dodatni"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Nie mo¿na przej¶æ do poprzedniego katalogu"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Brak B³êdów"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Brak listy lokacji"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: Popsuty ci±g wzorca"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: Zepsuty program wyra¿eñ regularnych"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: opcja 'readonly' jest ustawiona (wymu¶ poprzez !)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Nie mogê zmieniæ zmiennej tylko do odczytu \"%s\""
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Nie mogê ustawiæ zmiennej w piaskownicy: \"%s\""
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: B³±d w trakcie czytania pliku b³êdów"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Niedozwolone w piaskownicy"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Niedozwolone w tym miejscu"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: Ustawianie trybu ekranu niewspomagane"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Niew³a¶ciwa wielko¶æ przewiniêcia"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: opcja 'shell' jest pusta"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Nie mog³em wczytaæ danych znaku!"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: B³±d podczas zamykania pliku wymiany"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: stos znaczników jest pusty"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Komenda jest zbyt skomplikowana"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Zbyt d³uga nazwa"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: Zbyt wiele ["
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: Zbyt wiele nazw plików"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Nadstêpne znaczki"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Nieznana zak³adka"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Nie mog± rozwin±æ znaków wieloznacznych"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' nie mo¿e byæ mniejsze ni¿ 'winminheight'"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' nie mo¿e byæ mniejsze ni¿ 'winminwidth'"
-
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: B³±d w trakcie zapisu"
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Zerowy licznik"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: U¿ycie <SID> poza kontekstem skryptu"
-
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: B³±d wewnêtrzny: %s"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: Wzorzec u¿ywa wiêcej pamiêci ni¿ 'maxmempattern'"
-
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: pusty bufor"
-
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Niew³a¶ciwy wzorzec wyszukiwania lub delimiter"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Plik jest za³adowany w innym buforze"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: Nie ustawiono opcji '%s'"
-
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: Niew³a¶ciwa nazwa rejestru"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "szukanie dobi³o GÓRY; kontynuacja od KOÑCA"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "szukanie dobi³o KOÑCA; kontynuacja od GÓRY"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: Brak dwukropka"
-
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: Niedozwolona czê¶æ"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: oczekiwa³em na cyfrê"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "Strona %d"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "Brak tekstu do drukowania"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "Drukujê stronê %d (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr " Kopia %d z %d"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "Wydrukowano: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "Drukowanie odwo³ane"
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: Nie mo¿na zapisaæ do wyj¶ciowego pliku PostScriptu"
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: Nie mogê otworzyæ pliku \"%s\""
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: Nie mo¿na odczytaæ pliku zasobów PostScriptu \"%s\""
-
-#: ../hardcopy.c:1772
-#, c-format
-msgid "E618: file \"%s\" is not a PostScript resource file"
-msgstr "E618: plik \"%s\" nie jest plikiem zasobów PostScriptu"
-
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: plik \"%s\" nie jest wspieranym plikiem zasobów PostScriptu"
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: \"%s\" nieprawid³owa wersja pliku zasobów"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: Niekompatybilne kodowanie wielobajtowe i zestaw znaków."
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: printmbcharset nie mo¿e byæ pusty przy kodowaniu wielobajtowym."
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr "E675: Nie okre¶lono domy¶lnej czcionki dla drukowania wielobajtowego."
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: Nie mo¿na otworzyæ pliku PostScript do wyj¶cia"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: Nie mogê otworzyæ pliku \"%s\""
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: Nie mo¿na znale¼æ pliku zasobów PostScriptu \"prolog.ps\""
-
-#: ../hardcopy.c:2593
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: Nie mo¿na znale¼æ pliku zasobów PostScriptu \"cidfont.ps\""
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: Nie mo¿na znale¼æ pliku zasobów PostScriptu \"%s.ps\""
-
-#: ../hardcopy.c:2654
-#, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: Nie mo¿na przekonwertowaæ by drukowaæ kodowanie \"%s\""
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "Przesy³am do drukarki..."
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: Drukowanie pliku PostScript nie powiod³o siê"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "Zadanie drukowanie przes³ane."
-
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "Dodaj now± bazê danych"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "Zapytane o wzorzec"
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "Poka¿ ten komunikat"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "Zabij po³±czenie"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "Ponów wszelkie po³±czenia"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "Poka¿ po³±czenia"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Zastosowanie: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "Ta komenda cscope nie wspomaga podzielenia okna.\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Zastosowanie: cstag <ident>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: nie znaleziono znacznika"
-
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) b³±d: %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s nie jest katalogiem lub poprawn± baz± danych cscope"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "Dodano bazê danych cscope %s"
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: b³±d odczytu po³±czenia z cscope %<PRId64>"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: nieznany typ szukania cscope"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: Nie mog³em stworzyæ potoku do cscope"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: Nie mog³em utworzyæ rozwidlenia dla cscope"
-
-#: ../if_cscope.c:849
-msgid "cs_create_connection setpgid failed"
-msgstr "nie powiod³o siê setpgid cs_create_connection"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "wykonanie cs_create_connection nie powiod³o siê"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen dla to_fp nie powiod³o siê"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen dla fr_fp nie powiod³o siê"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: Nie mog³em stworzyæ procesu cscope"
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: brak po³±czenia z cscope"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: nieprawid³owa flaga cscopequickfix %c dla %c"
-
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: brak dopasowañ dla zapytania cscope %s o %s"
-
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "komendy cscope:\n"
-
-#: ../if_cscope.c:1150
-#, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %s%*s (U¿ycie: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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"
-" c: znajd¼ funkcje wywo³uj±ce tê funkcjê\n"
-" d: znajd¼ funkcje wywo³ywane przez tê funkcjê\n"
-" e: znajd¼ ten wzorzec egrep\n"
-" f: znajd¼ ten plik\n"
-" g: znajd¼ tê definicjê\n"
-" i: znajd¼ pliki w³±czaj±ce (#include) ten plik\n"
-" s: znajd¼ ten symbol C\n"
-" t: znajd¼ ten ³añcuch znaków\n"
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: nie dodano duplikatu bazy danych cscope"
-
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: nie ma po³±czenia %s z cscope"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "po³±czenie %s z cscope zosta³o zamkniête"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: b³±d krytyczny w cs_manage_matches"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Znacznik cscope: %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # wiersz"
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "nazwa pliku / kontekst / wiersz\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: B³±d cscope: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "Wszystkie bazy danych cscope prze³adowano"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "brak po³±czeñ z cscope\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid nazwa bazy danych przedsionek tropu\n"
-
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "Nieznany argument opcji"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "Zbyt wiele argumentów"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "Brak argumentu po"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "¦miecie po argumencie opcji"
-
-#: ../main.c:152
-msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
-msgstr ""
-"Zbyt wiele argumentów \"+komenda\", \"-c komenda\" lub \"--cmd komenda\""
-
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "Niew³a¶ciwy argument dla"
-
-#: ../main.c:294
-#, c-format
-msgid "%d files to edit\n"
-msgstr "%d plików do edycji\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "Próba ponownego otworzenia pliku skryptu: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "Nie mogê otworzyæ do odczytu: \""
-
-#: ../main.c:1393
-msgid "Cannot open for script output: \""
-msgstr "Nie mogê otworzyæ dla wyj¶cia skryptu: \""
-
-#: ../main.c:1622
-msgid "Vim: Warning: Output is not to a terminal\n"
-msgstr "Vim: OSTRZE¯ENIE: Wyj¶cie nie jest terminalem\n"
-
-#: ../main.c:1624
-msgid "Vim: Warning: Input is not from a terminal\n"
-msgstr "Vim: OSTRZE¯ENIE: Wej¶cie nie pochodzi z terminala\n"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "linia poleceñ pre-vimrc"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: Nie mogê czytaæ z \"%s\""
-
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"Dalsze informacje poprzez: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[plik ..] edytuj zadane pliki"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- czytaj tekst ze stdin"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t znacznik edytuj plik, w którym dany znacznik jest zdefiniowany"
-
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [errorfile] edytuj plik, zawieraj±cy pierwszy b³±d"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"u¿ycie:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [argumenty]"
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" lub:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"Argumenty:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tTylko nazwy plików po tym"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tNie rozwijaj znaków specjalnych"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tTryb vi (jak \"vi\")"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tTryb ex (jak \"ex\")"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr "-E\t\t\tUsprawniony tryb Ex"
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tCichy tryb (t³a) (tylko dla \"ex\")"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tTryb ró¿nic (jak \"vimdiff\")"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tTryb ³atwy (jak \"evim\", bez trybów)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tTryb wy³±cznie do odczytu (jak \"view\")"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tTryb ograniczenia (jak \"rvim\")"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\tModyfikacje (zapisywanie plików) niedozwolone"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tZakaz modyfikacji tekstu"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tTryb binarny"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tTryb lisp"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tB±d¼ zgodny z Vi: 'compatible'"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tB±d¼ niezupe³nie zgodny z Vi: 'nocompatible'"
-
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr "-V[N][nazwap]\t\tGadatliwy [poziom N] [zapisuj wiadomo¶ci do nazwap]"
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tTryb odpluskwiania"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tZamiast pliku wymiany, u¿ywaj tylko pamiêci"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tWylicz pliki wymiany i zakoñcz"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (z nazw± pliku)\tOdtwórz za³aman± sesjê"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tTo¿same z -r"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\trozpocznij w trybie arabskim"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\trozpocznij w trybie hebrajskim"
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\trozpocznij w trybie farsi"
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminal>\tUstaw typ terminala na <terminal>"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tU¿yj <vimrc> zamiast jakiegokolwiek .vimrc"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tNie ³aduj skryptów wtyczek"
-
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tOtwórz N kart (domy¶lnie: po jednej dla ka¿dego pliku)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\tOtwórz N okien (domy¶lnie: po jednym dla ka¿dego pliku)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\ttak samo jak -o tylko dziel okno pionowo"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tZacznij na koñcu pliku"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\tZacznij w wierszu <lnum>"
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr ""
-"-cmd <command>\t\tWykonaj komendê <command> przed za³adowaniem "
-"jakiegokolwiek pliku vimrc"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr ""
-"-c <command>\t\tWykonaj komendê <command> po za³adowaniu pierwszego pliku"
-
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <sesja>\t\tWczytaj plik <sesja> po za³adowaniu pierwszego pliku"
-
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <scriptin>\tWczytuj komendy trybu normalnego z pliku <scriptin>"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr ""
-"-w <scriptout>\tDo³±cz wszystkie wprowadzane komendy do pliku <scriptout>"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr ""
-"-W <scriptout>\tZapisuj wszystkie wprowadzane komendy do pliku <scriptout>"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr ""
-"--startuptime <plik>\n"
-"Zapisz wiadomo¶ci o d³ugo¶ci startu do <plik>"
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tU¿ywaj <viminfo> zamiast .viminfo"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h lub --help\twy¶wietl Pomoc (czyli tê wiadomo¶æ) i zakoñcz"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\twy¶wietl informacjê o wersji i zakoñcz"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "Brak zak³adek"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: ¯adna zak³adka nie pasuje do \"%s\""
-
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"zak³. wiersz kol plik/tekst"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-" skok wiersz kol plik/tekst"
-
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-"\n"
-"zmieñ wrsz. kol tekst"
-
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Zak³adki w plikach:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Lista odniesieñ (pocz±wszy od najnowszych):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Historia zak³adek w plikach (od najnowszych po najstarsze):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "Brak '>'"
-
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: blok nie by³ zablokowany"
-
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: B³±d w trakcie czytania pliku wymiany"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: B³±d odczytu pliku wymiany"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: B³±d szukania w pliku wymiany"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: B³±d zapisu w pliku wymiany"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: Plik wymiany ju¿ istnieje (atak symlink?)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: Nie otrzyma³em bloku nr 0?"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: Nie otrzyma³em bloku nr 1?"
-
-#: ../memline.c:377
-msgid "E298: Didn't get block nr 2?"
-msgstr "E298: Nie otrzyma³em bloku nr 2?"
-
-#. could not (re)open the swap file, what can we do????
-#: ../memline.c:465
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: Ojej, zgubi³em plik wymiany!!!"
-
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: Nie mog³em zmieniæ nazwy pliku wymiany"
-
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr ""
-"E303: Nie mogê otworzyæ pliku wymiany dla \"%s\"; odtworzenie niemo¿liwe"
-
-#: ../memline.c:666
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_upd_block(): Nie otrzyma³em bloku 0??"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: Nie znaleziono pliku wymiany dla %s"
-
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr "Wprowad¼ numer pliku wymiany, którego u¿yæ (0 by wyj¶æ): "
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: Nie mogê otworzyæ %s"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "Nie mogê odczytaæ bloku 0 z "
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"Mo¿e nie wykonano zmian albo Vim nie zaktualizowa³ pliku wymiany."
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " nie mo¿e byæ stosowany z t± wersj± Vima.\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "U¿yj Vima w wersji 3.0.\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %s nie wygl±da na plik wymiany Vima"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " nie mo¿e byæ stosowany na tym komputerze.\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr "Ten plik zosta³ stworzony na "
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-",\n"
-"lub plik zosta³ uszkodzony."
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr ""
-" zosta³ uszkodzony (wielko¶æ strony jest mniejsza ni¿ najmniejsza warto¶æ).\n"
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "U¿ywam pliku wymiany \"%s\""
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "Oryginalny plik \"%s\""
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: OSTRZE¯ENIE: Oryginalny plik móg³ byæ zmieniony"
-
-#: ../memline.c:1061
-#, c-format
-msgid "E309: Unable to read block 1 from %s"
-msgstr "E309: Nie mogê odczytaæ bloku 1 z %s"
-
-#: ../memline.c:1065
-msgid "???MANY LINES MISSING"
-msgstr "???BRAKUJE WIELU WIERSZY"
-
-#: ../memline.c:1076
-msgid "???LINE COUNT WRONG"
-msgstr "???LICZNIK WIERSZY NIEZGODNY"
-
-#: ../memline.c:1082
-msgid "???EMPTY BLOCK"
-msgstr "???PUSTY BLOK"
-
-#: ../memline.c:1103
-msgid "???LINES MISSING"
-msgstr "???BRAKUJE WIERSZY"
-
-#: ../memline.c:1128
-#, c-format
-msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: Niew³a¶ciwe ID bloku 1 (mo¿e %s nie jest plikiem .swp?)"
-
-#: ../memline.c:1133
-msgid "???BLOCK MISSING"
-msgstr "???BRAK BLOKU"
-
-#: ../memline.c:1147
-msgid "??? from here until ???END lines may be messed up"
-msgstr "??? od tego miejsca po ???KONIEC wiersze mog± byæ pomieszane"
-
-#: ../memline.c:1164
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? od tego miejsca po ???KONIEC wiersze mog± byæ w³o¿one/skasowane"
-
-#: ../memline.c:1181
-msgid "???END"
-msgstr "???KONIEC"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: Przerwanie odtwarzania"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr "E312: Wykryto b³êdy podczas odtwarzania; od których wierszy zacz±æ ???"
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "Zobacz \":help E312\" dla dalszych informacji."
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr ""
-"Odtwarzanie zakoñczono. Powiniene¶ sprawdziæ czy wszystko jest w porz±dku."
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(Mo¿esz chcieæ zapisaæ ten plik pod inn± nazw±\n"
-
-#: ../memline.c:1252
-msgid "and run diff with the original file to check for changes)"
-msgstr "i wykonaæ diff z oryginalnym plikiem aby sprawdziæ zmiany)"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr "Odzyskiwanie zakoñczone. Zawarto¶æ bufora jest równa zawarto¶ci pliku."
-
-#: ../memline.c:1255
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"\n"
-"Mo¿esz teraz chcieæ usun±æ plik .swp.\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "Znalezione pliki wymiany:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr " W bie¿±cym katalogu:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " U¿ywam podanej nazwy:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " W katalogu "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- ¿aden --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " posiadany przez: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " data: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " data: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [po Vimie wersja 3.0]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [nie wygl±da na plik wymiany Vima]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " nazwa pliku: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" zmieniono: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "TAK"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "nie"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" u¿ytkownik: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " nazwa hosta: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" nazwa hosta: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" ID procesu: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (dalej dzia³a)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [nie do u¿ytku na tym komputerze]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [nieodczytywalny]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [nieotwieralny]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: Nie mogê zabezpieczyæ, bo brak pliku wymiany"
-
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "Plik zabezpieczono"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: Nieudane zabezpieczenie"
-
-#: ../memline.c:1819
-#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: niew³a¶ciwy lnum: %<PRId64>"
-
-#: ../memline.c:1851
-#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: nie znaleziono wiersza %<PRId64>"
-
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: niepoprawne id wska¼nika bloku 3"
-
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "stack_idx powinien byæ 0"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: Zaktualizowano zbyt wiele bloków?"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: niepoprawne id wska¼nika bloku 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "blok nr 1 skasowany?"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Nie mogê znale¼æ wiersza %<PRId64>"
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: niepoprawne id bloku odniesienia"
-
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "pe_line_count wynosi zero"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: numer wiersza poza zakresem: %<PRId64> jest poza koñcem"
-
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: liczba wierszy niepoprawna w bloku %<PRId64>"
-
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "Wielko¶æ stosu wzrasta"
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: niepoprawne id bloku odniesienia 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr "E773: Pêtla dowi±zañ dla \"%s\""
-
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: UWAGA"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"Znalaz³em plik wymiany o nazwie \""
-
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "Podczas otwierania pliku \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " NOWSZE od pliku wymiany!\n"
-
-#: ../memline.c:3244
-#, fuzzy
-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."
-msgstr ""
-"\n"
-"(1) Pewnie inny program obrabia ten sam plik.\n"
-" Je¶li tak, b±d¼ ostro¿ny, aby nie skoñczyæ z dwoma\n"
-" ró¿nymi wersjami tego samego pliku po zmianach.\n"
-
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " Zakoñcz lub ostro¿nie kontynuuj.\n"
-
-#: ../memline.c:3246
-msgid "(2) An edit session for this file crashed.\n"
-msgstr "(2) Sesja edycji dla pliku za³ama³a siê.\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " Je¶li tak, to u¿yj \":recover\" lub \"vim -r "
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"\"\n"
-" aby odzyskaæ zmiany (zobacz \":help recovery)\").\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " Je¶li ju¿ to zrobi³e¶, usuñ plik wymiany \""
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"\"\n"
-" aby unikn±æ tej wiadomo¶ci.\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "Plik wymiany \""
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "\" ju¿ istnieje!"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "VIM - UWAGA"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "Plik wymiany ju¿ istnieje!"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"&Otwórz Read-Only\n"
-"&Edytuj pomimo\n"
-"O&dtwórz\n"
-"&Zakoñcz\n"
-"&Porzuæ"
-
-#: ../memline.c:3467
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"&Otwórz Read-Only\n"
-"&Edytuj pomimo\n"
-"O&dtwórz\n"
-"&Usuñ\n"
-"&Zakoñcz\n"
-"&Porzuæ"
-
-#.
-#. * 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
-msgid "E326: Too many swap files found"
-msgstr "E326: Znaleziono zbyt wiele plików wymiany"
-
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Brak pamiêci! (rezerwacja %<PRIu64> bajtów)"
-
-#: ../menu.c:62
-msgid "E327: Part of menu-item path is not sub-menu"
-msgstr "E327: Czê¶æ tropu punktu menu nie okre¶la podmenu"
-
-#: ../menu.c:63
-msgid "E328: Menu only exists in another mode"
-msgstr "E328: Menu istnieje tylko w innym trybie"
-
-#: ../menu.c:64
-#, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: Nie ma menu \"%s\""
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-msgid "E792: Empty menu name"
-msgstr "E792: Pusta nazwa menu"
-
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: Trop menu nie mo¿e prowadziæ do podmenu"
-
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: Nie wolno dodawaæ punktów menu wprost do paska menu"
-
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: Separator nie mo¿e byæ czê¶ci± tropu menu"
-
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- Menu ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: Trop menu musi prowadziæ do punktu menu"
-
-#: ../menu.c:1330
-#, c-format
-msgid "E334: Menu not found: %s"
-msgstr "E334: Nie znaleziono menu: %s"
-
-#: ../menu.c:1396
-#, c-format
-msgid "E335: Menu not defined for %s mode"
-msgstr "E335: Menu nie jest zdefiniowane dla trybu %s"
-
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: Trop menu musi prowadziæ do podmenu"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: Nie znaleziono menu - sprawd¼ nazwy menu"
-
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "Wykryto b³±d podczas przetwarzania %s:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "wiersz %4ld:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: Niew³a¶ciwa nazwa rejestru: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Opiekun komunikatów: Miko³aj Machowski <mikmach@wp.pl>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "Przerwanie: "
-
-#: ../message.c:988
-msgid "Press ENTER or type command to continue"
-msgstr "Naci¶nij ENTER lub wprowad¼ komendê aby kontynuowaæ"
-
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s wiersz %<PRId64>"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- Wiêcej --"
-
-#: ../message.c:2398
-msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr " SPACE/d/j: ekran/strona/wiersz w dó³, b/u/k: do góry, q: zakoñcz"
-
-#: ../message.c:3021 ../message.c:3031
-msgid "Question"
-msgstr "Pytanie"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"&Tak\n"
-"&Nie"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Tak\n"
-"&Nie\n"
-"&Zakoñcz"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"&Tak\n"
-"&Nie\n"
-"Zapisz &wszystkie\n"
-"&Odrzuæ wszystkie\n"
-"&Zakoñcz"
-
-#: ../message.c:3058
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: Za ma³o argumentów dla printf()"
-
-#: ../message.c:3119
-msgid "E807: Expected Float argument for printf()"
-msgstr "E807: Spodziewany argument Zmiennoprzecinkowy w printf()"
-
-#: ../message.c:3873
-msgid "E767: Too many arguments to printf()"
-msgstr "E767: Za du¿o argumentów dla printf()"
-
-#: ../misc1.c:2256
-msgid "W10: Warning: Changing a readonly file"
-msgstr "W10: OSTRZE¯ENIE: Zmiany w pliku tylko do odczytu"
-
-#: ../misc1.c:2537
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr "Wpisz numer i <Enter> lub wybierz mysz± (pusta warto¶æ anuluje): "
-
-#: ../misc1.c:2539
-msgid "Type number and <Enter> (empty cancels): "
-msgstr "Wpisz numer i <Enter> (puste anuluje): "
-
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "1 wiersz wiêcej"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "1 wiersz mniej"
-
-#: ../misc1.c:2593
-#, c-format
-msgid "%<PRId64> more lines"
-msgstr "dodano %<PRId64> wierszy"
-
-#: ../misc1.c:2596
-#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "usuniêto %<PRId64> wierszy"
-
-#: ../misc1.c:2599
-msgid " (Interrupted)"
-msgstr " (Przerwane)"
-
-#: ../misc1.c:2635
-msgid "Beep!"
-msgstr "Biiip!"
-
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "Wywo³ujê pow³okê do wykonania: \"%s\""
-
-#: ../normal.c:183
-msgid "E349: No identifier under cursor"
-msgstr "E349: Brak identyfikatora pod kursorem"
-
-#: ../normal.c:1866
-msgid "E774: 'operatorfunc' is empty"
-msgstr "E774: 'operatorfunc' jest pusta"
-
-#: ../normal.c:2637
-msgid "Warning: terminal cannot highlight"
-msgstr "OSTRZE¯ENIE: terminal nie wykonuje pod¶wietlania"
-
-#: ../normal.c:2807
-msgid "E348: No string under cursor"
-msgstr "E348: Brak ci±gu pod kursorem"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: Nie mogê skasowaæ zwiniêcia z bie¿±c± 'foldmethod'"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: lista zmian (changelist) jest pusta"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr "E662: Na pocz±tku listy zmian"
-
-#: ../normal.c:5901
-msgid "E663: At end of changelist"
-msgstr "E663: Na koñcu listy zmian"
-
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "wprowad¼ :quit<Enter> zakoñczenie programu"
-
-#: ../ops.c:248
-#, c-format
-msgid "1 line %sed 1 time"
-msgstr "1 wiersz %sed 1 raz"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 wiersz %sed %d razy"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> wierszy %sed 1 raz"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> wierszy %sed %d razy"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "%<PRId64> wierszy do wciêcia... "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "1 wiersz wciêty "
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "%<PRId64> wierszy wciêtych "
-
-#: ../ops.c:938
-msgid "E748: No previously used register"
-msgstr "E748: Brak poprzednio u¿ytego rejestru"
-
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "nie mogê skopiowaæ, mimo to kasujê"
-
-#: ../ops.c:1929
-msgid "1 line changed"
-msgstr "1 wiersz zmieniono"
-
-#: ../ops.c:1931
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "%<PRId64> wierszy zmieniono"
-
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "skopiowano blok 1 wiersza"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "1 wiersz skopiowano"
-
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "%<PRId64> wierszy skopiowanych"
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "%<PRId64> wierszy skopiowanych"
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353: Pusty rejestr %s"
-
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- Rejestry ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "Niedozwolona nazwa rejestru"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# Rejestry:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: Nieznany typ rejestru %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Kolumn; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Wybrano %s%<PRId64> z %<PRId64> Wierszy; %<PRId64> z %<PRId64> S³ów; "
-"%<PRId64> z %<PRId64> Bajtów"
-
-#: ../ops.c:5105
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Wybrano %s%<PRId64> z %<PRId64> Wierszy; %<PRId64> z %<PRId64> S³ów; "
-"%<PRId64> z %<PRId64> Znaków; %<PRId64> z %<PRId64> Bajtów"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Kol %s z %s; Wiersz %<PRId64> z %<PRId64>; S³owo %<PRId64> z %<PRId64>; Bajt "
-"%<PRId64> z %<PRId64>"
-
-#: ../ops.c:5133
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"Kol %s z %s; Wiersz %<PRId64> z %<PRId64>; S³owo %<PRId64> z %<PRId64>; Znak "
-"%<PRId64> z %<PRId64>; Bajt %<PRId64> z %<PRId64>"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> dla BOM)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Strona %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "Dziêki za lot Vimem"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: Nieznana opcja"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: Opcja nie jest wspomagana"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: Niedozwolone w modeline"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr "E846: Kod klucza nie jest ustawiony"
-
-#: ../option.c:2924
-msgid "E521: Number required after ="
-msgstr "E521: Po = wymagany jest numer"
-
-#: ../option.c:3226 ../option.c:3864
-msgid "E522: Not found in termcap"
-msgstr "E522: Nie znaleziono w termcap"
-
-#: ../option.c:3335
-#, c-format
-msgid "E539: Illegal character <%s>"
-msgstr "E539: Niedozwolony znak <%s>"
-
-#: ../option.c:3862
-msgid "E529: Cannot set 'term' to empty string"
-msgstr "E529: Nie mogê ustawiæ 'term' na pusty ci±g"
-
-#: ../option.c:3885
-msgid "E589: 'backupext' and 'patchmode' are equal"
-msgstr "E589: 'backupext' i 'patchmode' s± to¿same"
-
-#: ../option.c:3964
-msgid "E834: Conflicts with value of 'listchars'"
-msgstr "E834: Konflikty warto¶ci 'listchars'"
-
-#: ../option.c:3966
-msgid "E835: Conflicts with value of 'fillchars'"
-msgstr "E835: Konflikty warto¶ci 'fillchars'"
-
-#: ../option.c:4163
-msgid "E524: Missing colon"
-msgstr "E524: Brak dwukropka"
-
-#: ../option.c:4165
-msgid "E525: Zero length string"
-msgstr "E525: Ci±g o zerowej d³ugo¶ci"
-
-#: ../option.c:4220
-#, c-format
-msgid "E526: Missing number after <%s>"
-msgstr "E526: Brak numeru po <%s>"
-
-#: ../option.c:4232
-msgid "E527: Missing comma"
-msgstr "E527: Brak przecinka"
-
-#: ../option.c:4239
-msgid "E528: Must specify a ' value"
-msgstr "E528: Musi okre¶laæ warto¶æ '"
-
-#: ../option.c:4271
-msgid "E595: contains unprintable or wide character"
-msgstr "E595: zawiera niewy¶wietlalny lub szeroki znak"
-
-#: ../option.c:4469
-#, c-format
-msgid "E535: Illegal character after <%c>"
-msgstr "E535: Niedozwolony znak po <%c>"
-
-#: ../option.c:4534
-msgid "E536: comma required"
-msgstr "E536: wymagany przecinek"
-
-#: ../option.c:4543
-#, c-format
-msgid "E537: 'commentstring' must be empty or contain %s"
-msgstr "E537: 'commentstring' musi byæ pusty lub zawieraæ %s"
-
-#: ../option.c:4928
-msgid "E540: Unclosed expression sequence"
-msgstr "E540: Niedomkniêty ci±g wyra¿eñ"
-
-#: ../option.c:4932
-msgid "E541: too many items"
-msgstr "E541: zbyt wiele elementów"
-
-#: ../option.c:4934
-msgid "E542: unbalanced groups"
-msgstr "E542: niezbalansowane grupy"
-
-#: ../option.c:5148
-msgid "E590: A preview window already exists"
-msgstr "E590: okno podgl±du ju¿ istnieje"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: Arabski wymaga UTF-8, zrób ':set encoding=utf-8'"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: Potrzebujê przynajmniej %d wierszy"
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: Potrzebujê przynajmniej %d kolumn"
-
-#: ../option.c:6011
-#, c-format
-msgid "E355: Unknown option: %s"
-msgstr "E355: Nieznana opcja: %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
-#, c-format
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: Wymagana Liczba: &%s = '%s'"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- Kody terminala ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- Globalne warto¶ci opcji ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- Lokalne warto¶ci opcji ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- Opcje ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: B£¡D get_varp"
-
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': Brak pasuj±cego znaku dla %s"
-
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': Dodatkowe znaki po ¶redniku: %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Nie mogê wykonaæ pow³oki "
-
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"pow³oka zwróci³a "
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-"\n"
-"Nie mogê uzyskaæ kontekstu bezpieczeñstwa dla"
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-"\n"
-"Nie mo¿na uzyskaæ kontekstu bezpieczeñstwa dla"
-
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = \"%s\""
-
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Nie mogê znale¼æ pliku \"%s\" w tropie"
-
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: Zbyt wiele %%%c w ci±gu formatuj±cym"
-
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: Nieoczekiwane %%%c w ci±gu formatuj±cym"
-
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: Brak ] w ci±gu formatuj±cym"
-
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: Niewspomagane %%%c w ci±gu formatuj±cym"
-
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: Niepoprawne %%%c w prefiksie ci±gu formatuj±cego"
-
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: Niepoprawne %%%c w ci±gu formatuj±cym"
-
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: 'errorformat' nie zawiera wzorca"
-
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: Pusta nazwa katalogu lub jej brak"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: Nie ma wiêcej elementów"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d z %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (wiersz skasowany)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: Na dole stosu quickfix"
-
-#: ../quickfix.c:1869
-msgid "E381: At top of quickfix stack"
-msgstr "E381: Na górze stosu quickfix"
-
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "lista b³êdów %d z %d; %d b³êdów"
-
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: Nie mogê zapisaæ, opcja 'buftype' jest ustawiona"
-
-#: ../quickfix.c:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr "E683: Brak nazwy pliku lub niew³a¶ciwa ¶cie¿ka"
-
-#: ../quickfix.c:2911
-#, c-format
-msgid "Cannot open file \"%s\""
-msgstr "Nie mogê otworzyæ pliku \"%s\""
-
-#: ../quickfix.c:3429
-msgid "E681: Buffer is not loaded"
-msgstr "E681: Bufor nie jest za³adowany"
-
-#: ../quickfix.c:3487
-msgid "E777: String or List expected"
-msgstr "E777: Oczekiwa³em na ³añcuch lub listê"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: Niew³a¶ciwy element w %s%%[]"
-
-#: ../regexp.c:374
-#, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E769: Brak ] po %s["
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: Niesparowany %s%%("
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: Niesparowany %s("
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: Niesparowany %s)"
-
-#: ../regexp.c:378
-msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( jest niedozwolone w tym miejscu"
-
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 i podobne s± niedozwolone w tym miejscu"
-
-#: ../regexp.c:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: Brak ] po %s%%["
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: Pusty %s%%[]"
-
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: Zbyt d³ugi wzorzec"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: Zbyt wiele \\z("
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: Zbyt wiele %s("
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: Niesparowany \\z("
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: niedozwolony znak po %s@"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: Zbyt wiele z³o¿onych %s{...}"
-
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: Zagnie¿d¿one %s*"
-
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: Zagnie¿d¿one %s%c"
-
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: Niedozwolone u¿ycie \\_"
-
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c po niczym"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: Niew³a¶ciwe odwo³anie wsteczne"
-
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: niedopuszczalny znak po \\z"
-
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: Niedozwolony znak po %s%%[dxouU]"
-
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: Niedozwolony znak po %s%%"
-
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: B³±d sk³adni w %s{...}"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "Zewnêtrzne poddopasowania:\n"
-
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-"E:864: \\%#= mo¿e byæ tylko przed 0, 1 lub 2. Zostanie u¿yty silnik "
-"automatyczny"
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr "E865: (NFA) przedwczesny koniec wyra¿enia regularnego"
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr "E866: (wyra¿enie regularne NFA) Niepoprawnie umieszczone %c"
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr "E867: (NFA) Nieznany operator '\\z%c'"
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) Nieznany operator '\\%%%c'"
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr "E869: (NFA) Nieznany operator '\\@%c'"
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-"E870: (wyra¿enie regularne NFA) B³±d przy odczytywaniu limitów powtórzeñ"
-
-#. 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: (wyra¿enie regularne NFA) wielokrotne nie mo¿e byæ po wielokrotnym!"
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr "E872: (wyra¿enie regularne NFA) Zbyt du¿o '('"
-
-#: ../regexp_nfa.c:2042
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E879: (wyra¿enie regularne NFA) Za du¿o \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr "E873: (wyra¿enie regularne NFA) b³±d poprawnego zakoñczenia"
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr "E874: (NFA) Nie mo¿na zdj±æ elementu ze stosu!"
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-"E875: (wyra¿enie regularne NFA) (w trakcie konwersji postfix do NFA), za "
-"wiele stanów na stosie"
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr "E876: (wyra¿enie regularne NFA) Nie ma miejsca na ca³e NFA "
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"Nie mo¿na otworzyæ do zapisu tymczasowego pliku, pokazujê na stderr... "
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) NIE MO¯NA OTWORZYÆ %s !"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "Nie mo¿na otworzyæ do zapisu tymczasowego pliku logowania"
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " V-ZAMIANA"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " ZAMIANA"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " NEGATYW"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " WPROWADZANIE"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (wprowadzanie)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (zamiana)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (v-zamiana)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " Hebrajski"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " Arabski"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (jêzyk)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (wklejanie)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " WIZUALNY"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " WIZUALNY LINIOWY"
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " WIZUALNY BLOKOWY"
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " ZAZNACZANIE"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " ZAZNACZANIE LINIOWE"
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " ZAZNACZANIE BLOKOWE"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "zapis"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: Niew³a¶ciwy ci±g do szukania: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: szukanie dobi³o GÓRY bez znalezienia: %s"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: szukanie dobi³o KOÑCA bez znalezienia : %s"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: Oczekujê '?' lub '/' po ';'"
-
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (zawiera poprzednio wymienione dopasowanie)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- Zawarte pliki "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "nie znaleziono"
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "w tropie ---\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (Ju¿ wymienione)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " NIE ZNALEZIONO"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "Przegl±d w³±czonego pliku: %s"
-
-#: ../search.c:4216
-#, c-format
-msgid "Searching included file %s"
-msgstr "Przeszukiwanie w³±czonego pliku %s"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: Wzorzec pasuje w bie¿±cym wierszu"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "Wszelkie w³±czane pliki odnaleziono"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "Brak w³±czanych plików"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: Nie znalaz³em definicji"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: Nie znalaz³em wzorca"
-
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Podstawienie "
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-"\n"
-"# Ostatni %sWyszukiwany wzorzec:\n"
-"~"
-
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Nieprawid³owy format pliku sprawdzania pisowni"
-
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr "E758: Obciêty plik sprawdzania pisowni"
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr "Zbêdny tekst w %s wiersz %d: %s"
-
-#: ../spell.c:954
-#, c-format
-msgid "Affix name too long in %s line %d: %s"
-msgstr "Za d³uga nazwa afiksu w %s wiersz %d: %s"
-
-#: ../spell.c:955
-msgid "E761: Format error in affix file FOL, LOW or UPP"
-msgstr "E761: B³±d formatu w pliku afiksów FOL, LOW lub UPP"
-
-#: ../spell.c:957
-msgid "E762: Character in FOL, LOW or UPP is out of range"
-msgstr "E762: Znak w FOL, LOW lub UPP jest poza zasiêgiem"
-
-#: ../spell.c:958
-msgid "Compressing word tree..."
-msgstr "Kompresja drzewa s³ów..."
-
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr "E756: Sprawdzanie pisowni nie jest w³±czone"
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
-"Ostrze¿enie: Nie mogê znale¼æ listy s³ów \"%s.%s.spl\" lub \"%s.ascii.spl\""
-
-#: ../spell.c:2473
-#, c-format
-msgid "Reading spell file \"%s\""
-msgstr "Odczytujê plik sprawdzania pisowni \"%s\""
-
-#: ../spell.c:2496
-msgid "E757: This does not look like a spell file"
-msgstr "E757: To nie wygl±da na plik sprawdzania pisowni"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: Stary plik sprawdzania pisowni, wymagane uaktualnienie"
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr "E772: Plik sprawdzania pisowni dla nowszej wersji Vima"
-
-#: ../spell.c:2602
-msgid "E770: Unsupported section in spell file"
-msgstr "E770: Niewspierana sekcja w pliku sprawdzania pisowni"
-
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Ostrze¿enie: region %s nie jest wspierany"
-
-#: ../spell.c:4550
-#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Czytam plik afiksów %s ..."
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr "Konwersja nie powiod³a siê dla wyrazu w %s wierszu %d: %s"
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr "Konwersja w %s nie jest wspierana: od %s do %s"
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "Nieprawid³owa warto¶æ FLAG w %s wierz %d: %s"
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr "FLAG po u¿yciu flag w %s wiersz %d: %s"
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"Definiowanie COMPOUNDFORBIDFLAG po PFX mo¿e skutkowaæ z³ym wynikiem w %s "
-"wiersz %d"
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"Definiowanie COMPOUNDPERMITFLAG po PFX mo¿e skutkowaæ z³ym wynikiem w %s "
-"wiersz %d"
-
-#: ../spell.c:4747
-#, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "Z³a warto¶æ COMPOUNDRULES w %s wiersz %d: %s"
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "Z³a warto¶æ COMPOUNDWORDMAX w %s wiersz %d: %s"
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "Z³a warto¶æ COMPOUNDMIM w %s wiersz %d: %s"
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "Z³a warto¶æ COMPOUNDSYLMAX w %s wiersz %d: %s"
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "Z³a warto¶æ CHECKCOMPOUNDPATTERN w %s wiersz %d: %s"
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr "Ró¿ne flagi z³o¿eñ w kontynuowanym bloku afiksu w %s wiersz %d: %s"
-
-#: ../spell.c:4850
-#, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "Powtórzony afiks w %s wiersz %d: %s"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-"Afiks u¿yty tak¿e dla BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST w "
-"%s wiersz %d: %s"
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr "Oczekiwano Y lub N w %s wierszu %d: %s"
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr "B³êdny warunek w %s wiersz %d: %s"
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr "Oczekiwano ilo¶ci REP(SAL) w %s wierszu %d"
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr "Oczekiwano ilo¶ci MAP w %s wierszu %d"
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr "Powtórzony znak w MAP w %s wierszu %d"
-
-#: ../spell.c:5176
-#, c-format
-msgid "Unrecognized or duplicate item in %s line %d: %s"
-msgstr "Nieznany lub powtórzony element w %s wierszu %d: %s"
-
-#: ../spell.c:5197
-#, c-format
-msgid "Missing FOL/LOW/UPP line in %s"
-msgstr "Brak wiersza FOL/LOW/UPP w %s"
-
-#: ../spell.c:5220
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr "COMPOUNDSYLMAX u¿yty bez SYLLABLE"
-
-#: ../spell.c:5236
-msgid "Too many postponed prefixes"
-msgstr "Zbyt wiele opó¼nionych prefiksów"
-
-#: ../spell.c:5238
-msgid "Too many compound flags"
-msgstr "Zbyt wiele flag z³o¿eñ"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr "Zbyt wiele opó¼nionych prefiksów i/lub flag z³o¿eñ"
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr "Brak wiersza SOFO%s wiersz w %s"
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr "Wiersze SAL i SOFO w %s"
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr "Flaga nie jest liczb± w %s wiersz %d: %s"
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr "Nieprawid³owa flaga w %s wiersz %d: %s"
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr "Warto¶æ %s ró¿ni siê od tej u¿ytej w innym pliku .aff"
-
-#: ../spell.c:5602
-#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Czytam plik s³ownika %s ..."
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr "E760: Brak ilo¶ci s³ów w %s"
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "wiersz %6d, s³owo %6d - %s"
-
-# c-format
-#: ../spell.c:5691
-#, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "Powtórzony wyraz w %s wierszu %d: %s"
-
-# c-format
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr "Pierwszy powtórzony wyraz w %s wiersz %d: %s"
-
-# c-format
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr "%d powtórzony(ch) wyraz(ów) w %s"
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr "Zignorowa³em %d s³ów ze znakami nie ASCII w %s"
-
-#: ../spell.c:6115
-#, c-format
-msgid "Reading word file %s ..."
-msgstr "Odczytujê plik wyrazów %s ..."
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "Zignorowano powtórzony wiersz /encoding= w %s wierszu %d: %s"
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "Zignorowano wiersz /encoding= po wyrazie w %s wierszu %d: %s"
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "Powtórzony wiersz /regions= zignorowano w %s wierszu %d: %s"
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "Za du¿o regionów w %s wiersz %d: %s"
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "wiersz / zignorowano w %s wierszu %d: %s"
-
-#: ../spell.c:6224
-#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "Nieprawid³owy numer regionu w %s wierszu %d: %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "Nieznane flagi w %s wiersz %d: %s"
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr "Zignorowa³em %d s³ów ze znakami nie ASCII"
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "Skompresowano %d z %d wêz³ów; pozostaje %d (%d%%)"
-
-#: ../spell.c:7340
-msgid "Reading back spell file..."
-msgstr "Odczytujê plik sprawdzania pisowni..."
-
-#. Go through the trie of good words, soundfold each word and add it to
-#. the soundfold trie.
-#: ../spell.c:7357
-msgid "Performing soundfolding..."
-msgstr "Wykonujê kompresjê d¼wiêkow±..."
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Liczba s³ów po kompresji d¼wiêkowej: %<PRId64>"
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr "Ca³kowita liczba s³ów: %d"
-
-#: ../spell.c:7655
-#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Zapisujê plik sugestii %s ..."
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr "Oczekiwane zu¿ycie pamiêci: %d bajtów"
-
-#: ../spell.c:7820
-msgid "E751: Output file name must not have region name"
-msgstr "E751: Nazwa pliku wynikowego nie mo¿e byæ nazw± regionu"
-
-#: ../spell.c:7822
-msgid "E754: Only up to 8 regions supported"
-msgstr "E754: Wspieram tylko 8 regionów"
-
-#: ../spell.c:7846
-#, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E755: Nieprawid³owy region w %s"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr "Ostrze¿enie: okre¶lono zarówno z³o¿enia jak i NOBREAK"
-
-#: ../spell.c:7920
-#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Zapisujê plik sprawdzania pisowni %s ..."
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr "Zrobione!"
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' nie posiada wpisów %<PRId64>"
-
-#: ../spell.c:8074
-#, fuzzy, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "Usuniêto s³owo z %s"
-
-#: ../spell.c:8117
-#, fuzzy, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "Dodano s³owo do %s"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: Znaki wyrazów ró¿ni± siê miêdzy plikami sprawdzania pisowni"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Przykro mi, brak podpowiedzi"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Przykro mi, tylko %<PRId64> podpowiedzi"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Zmieñ \"%.*s\" na:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Brak poprzednich podmian sprawdzania pisowni"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Nie znaleziono: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Ten plik nie wygl±da na plik .sug: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Stary plik .sug, konieczne jest uaktualnienie: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Plik .sug dla nowszej wersji Vima: %s"
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Plik .sug nie pasuje do pliku .spl: %s"
-
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: B³±d w czasie odczytu pliku .sug: %s"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: Podwojony znak we wpisie MAP"
-
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "Brak elementów sk³adni okre¶lonych dla tego bufora"
-
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: Niedozwolony argument: %s"
-
-#: ../syntax.c:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: Nie ma takiego klastra sk³adni: %s"
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "synchronizacja komentarzy w stylu C"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "brak synchronizacji"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "pocz±tek synchronizacji"
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr " wierszy przed górn± lini±"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- Elementy synchronizacji sk³adni ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"synchronizujê na elementach"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- Elementy sk³adni ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: Nie ma takiego klastra sk³adni: %s"
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "minimalnie "
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "maksymalnie "
-
-#: ../syntax.c:3513
-msgid "; match "
-msgstr "; pasuje "
-
-#: ../syntax.c:3515
-msgid " line breaks"
-msgstr "znaków nowego wiersza"
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: argument contains niedozwolony w tym miejscu"
-
-#: ../syntax.c:4096
-msgid "E844: invalid cchar value"
-msgstr "E844: Niew³a¶ciwa warto¶æ cchar"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: group[t]here niedozwolone w tym miejscu"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: Nie znalaz³em elementów regionu dla %s"
-
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: Wymagana nazwa pliku"
-
-#: ../syntax.c:4221
-msgid "E847: Too many syntax includes"
-msgstr "E847: Za du¿o w³±czonych sk³adni"
-
-#: ../syntax.c:4303
-#, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E789: Brak ']': %s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: Brak '=': %s"
-
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: Za ma³o argumentów: syntax region %s"
-
-#: ../syntax.c:4870
-msgid "E848: Too many syntax clusters"
-msgstr "E848: Za du¿o klastrów sk³adni"
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: Brak specyfikacji klastra"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: Brak ogranicznika wzorca: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: ¦mieci po wzorcu: %s"
-
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: syntax sync: wielokrotnie podane wzorce kontynuacji wiersza"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: Niedozwolone argumenty: %s"
-
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: Brak znaku równo¶ci: %s"
-
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: Pusty argument: %s"
-
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %s jest niedozwolone w tym miejscu"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %s musi byæ pierwsze w li¶cie contains"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: Nieznana nazwa grupy: %s"
-
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: Niew³a¶ciwa podkomenda :syntax : %s"
-
-#: ../syntax.c:5854
-msgid ""
-" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-msgstr ""
-" WSZYTKO ILO¦Æ PASUJE NAJWOLN. ¦REDNIO NAZWA WZORZEC"
-
-#: ../syntax.c:6146
-msgid "E679: recursive loop loading syncolor.vim"
-msgstr "E679: rekursywna pêtla wczytuj±ca syncolor.vim"
-
-#: ../syntax.c:6256
-#, c-format
-msgid "E411: highlight group not found: %s"
-msgstr "E411: nie znaleziono grupy pod¶wietlania: %s"
-
-#: ../syntax.c:6278
-#, c-format
-msgid "E412: Not enough arguments: \":highlight link %s\""
-msgstr "E412: Zbyt ma³o argumentów: \":highlight link %s\""
-
-#: ../syntax.c:6284
-#, c-format
-msgid "E413: Too many arguments: \":highlight link %s\""
-msgstr "E413: Zbyt wiele argumentów: \":highlight link %s\""
-
-#: ../syntax.c:6302
-msgid "E414: group has settings, highlight link ignored"
-msgstr "E414: grupa ma ustawienia; zignorowane pod³±czenie pod¶wietlania"
-
-#: ../syntax.c:6367
-#, c-format
-msgid "E415: unexpected equal sign: %s"
-msgstr "E415: nieoczekiwany znak równo¶ci: %s"
-
-#: ../syntax.c:6395
-#, c-format
-msgid "E416: missing equal sign: %s"
-msgstr "E416: brak znaku równo¶ci: %s"
-
-#: ../syntax.c:6418
-#, c-format
-msgid "E417: missing argument: %s"
-msgstr "E417: brak argumentu: %s"
-
-#: ../syntax.c:6446
-#, c-format
-msgid "E418: Illegal value: %s"
-msgstr "E418: Niedozwolona warto¶æ: %s"
-
-#: ../syntax.c:6496
-msgid "E419: FG color unknown"
-msgstr "E419: Kolor FG nieznany"
-
-#: ../syntax.c:6504
-msgid "E420: BG color unknown"
-msgstr "E420: Kolor BG nieznany"
-
-#: ../syntax.c:6564
-#, c-format
-msgid "E421: Color name or number not recognized: %s"
-msgstr "E421: Nazwa lub liczba koloru nierozpoznana: %s"
-
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: za d³ugi kod terminala: %s"
-
-#: ../syntax.c:6753
-#, c-format
-msgid "E423: Illegal argument: %s"
-msgstr "E423: Niedozwolony argument: %s"
-
-#: ../syntax.c:6925
-msgid "E424: Too many different highlighting attributes in use"
-msgstr "E424: Zbyt wiele ró¿nych atrybutów podkre¶lania w u¿yciu"
-
-#: ../syntax.c:7427
-msgid "E669: Unprintable character in group name"
-msgstr "E669: Niedrukowalny znak w nazwie grupy"
-
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: nieprawid³owy znak w nazwie grupy"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr "E849: Za du¿o grup pod¶wietlania i sk³adni"
-
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: na dole stosu znaczników"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: na górze stosu znaczników"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Nie mo¿na przej¶æ przed pierwszy pasuj±cy znacznik"
-
-#: ../tag.c:504
-#, c-format
-msgid "E426: tag not found: %s"
-msgstr "E426: nie znaleziono znacznika: %s"
-
-#: ../tag.c:528
-msgid " # pri kind tag"
-msgstr " # pri rodzaj znacznik"
-
-#: ../tag.c:531
-msgid "file\n"
-msgstr "plik\n"
-
-#: ../tag.c:829
-msgid "E427: There is only one matching tag"
-msgstr "E427: Pasuje tylko jeden znacznik"
-
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: Nie mo¿na przej¶æ za ostatni pasuj±cy znacznik"
-
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "Plik \"%s\" nie istnieje"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "znacznik %d z %d%s"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " lub wiêcej"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " U¿ywam znacznika o odmiennej wielko¶ci liter!"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: Plik \"%s\" nie istnieje"
-
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # DO znacznik OD wiersza w pliku/tek¶cie"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "Szukam w pliku znaczników %s"
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr "Ignorujê d³ugie wiersze w pliku znaczników"
-
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: B³±d formatu w pliku znaczników \"%s\""
-
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Przed bajtem %<PRId64>"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Plik znaczników nieuporz±dkowany: %s"
-
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: Brak pliku znaczników"
-
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: Nie mogê znale¼æ wzorca znacznika"
-
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: Nie znalaz³em znacznika - tylko zgadujê!"
-
-#: ../tag.c:2797
-#, c-format
-msgid "Duplicate field name: %s"
-msgstr "Powtórzona nazwa pola: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' nieznany. Mo¿liwe typy wbudowanych terminali:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "domy¶lnie jest '"
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: Nie mogê otworzyæ pliku termcap"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: Nie ma opisu takiego terminala w terminfo"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: Nie ma opisu takiego terminala w termcap"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: Brak opisu \"%s\" w termcap"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: wymagana zdolno¶æ \"cm\" terminala"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Klawisze terminala ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: B³±d podczas wczytywania wej¶cia, koñczê...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
-msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Niespodziewana zmiana ilo¶ci linii"
-
-#: ../undo.c:627
-#, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E828: Nie mogê otworzyæ do zapisu pliku undo: %s"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr "E825: Uszkodzony plik undo (%s): %s"
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr "Nie mo¿na zapisaæ pliku undo w ¿adnym katalogu z 'undodir'"
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr "Nie nadpiszê plikiem undo, nie mogê odczytaæ: %s"
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr "Nie nadpiszê, to nie jest plik undo: %s"
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr "Pomijam zapis pliku undo, nic do cofniêcia"
-
-#: ../undo.c:1121
-#, c-format
-msgid "Writing undo file: %s"
-msgstr "Zapisujê plik undo: %s"
-
-#: ../undo.c:1213
-#, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E829: B³±d zapisu w pliku undo: %s"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr "Nie wczytujê pliku undo, inny w³a¶ciciel: %s"
-
-#: ../undo.c:1292
-#, c-format
-msgid "Reading undo file: %s"
-msgstr "Wczytujê plik undo: %s"
-
-#: ../undo.c:1299
-#, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E822: Nie mogê otworzyæ pliku undo do odczytu: %s"
-
-#: ../undo.c:1308
-#, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E823: To nie jest plik undo: %s"
-
-#: ../undo.c:1313
-#, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E824: Niekompatybilny plik undo: %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr "Zawarto¶æ pliku siê zmieni³a, nie mogê u¿yæ pliku undo"
-
-#: ../undo.c:1497
-#, c-format
-msgid "Finished reading undo file %s"
-msgstr "Skoñczono wczytywanie pliku undo %s"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr "Ju¿ w miejscu ostatniej zmiany"
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr "Ju¿ w miejscu najnowszej zmiany"
-
-#: ../undo.c:1806
-#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Nie znaleziono numeru cofniêcia %<PRId64>"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: niew³a¶ciwe numery wierszy"
-
-#: ../undo.c:2183
-msgid "more line"
-msgstr "1 wiersz wiêcej"
-
-#: ../undo.c:2185
-msgid "more lines"
-msgstr "wiêcej wierszy"
-
-#: ../undo.c:2187
-msgid "line less"
-msgstr "1 wiersz mniej"
-
-#: ../undo.c:2189
-msgid "fewer lines"
-msgstr "mniej wierszy"
-
-#: ../undo.c:2193
-msgid "change"
-msgstr "1 zmiana"
-
-#: ../undo.c:2195
-msgid "changes"
-msgstr "zmiany"
-
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr "przed"
-
-#: ../undo.c:2228
-msgid "after"
-msgstr "za"
-
-#: ../undo.c:2325
-msgid "Nothing to undo"
-msgstr "Nie ma zmian do cofniêcia"
-
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr "liczba zmiany kiedy zapisano"
-
-#: ../undo.c:2360
-#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> sekund temu"
-
-#: ../undo.c:2372
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E790: undojoin nie jest dozwolone po undo"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: uszkodzona lista cofania"
-
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: brak wiersza cofania"
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Zadane ³aty: "
-
-#: ../version.c:627
-msgid ""
-"\n"
-"Extra patches: "
-msgstr ""
-"\n"
-"Ekstra ³aty: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Zmieniony przez "
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"Skompilowany "
-
-#: ../version.c:649
-msgid "by "
-msgstr "przez "
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"Olbrzymia wersja "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "bez GUI."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " Opcje w³±czone (+) lub nie (-):\n"
-
-#: ../version.c:667
-msgid " system vimrc file: \""
-msgstr " vimrc systemu: \""
-
-#: ../version.c:672
-msgid " user vimrc file: \""
-msgstr " vimrc u¿ytkownika: \""
-
-#: ../version.c:677
-msgid " 2nd user vimrc file: \""
-msgstr " 2-gi plik vimrc u¿ytkownika: \""
-
-#: ../version.c:682
-msgid " 3rd user vimrc file: \""
-msgstr " 3-ci plik vimrc u¿ytkownika: \""
-
-#: ../version.c:687
-msgid " user exrc file: \""
-msgstr " exrc u¿ytkownika: \""
-
-#: ../version.c:692
-msgid " 2nd user exrc file: \""
-msgstr " 2-gi plik exrc u¿ytkownika: \""
-
-#: ../version.c:699
-msgid " fall-back for $VIM: \""
-msgstr " odwet dla $VIM-a: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr "f-b dla $VIMRUNTIME: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "Kompilacja: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Konsolidacja: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " KOMPILACJA DEBUG"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi rozbudowany"
-
-#: ../version.c:769
-msgid "version "
-msgstr "wersja "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "Autor: Bram Moolenaar i Inni."
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim jest open source i rozprowadzany darmowo"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "Pomó¿ biednym dzieciom w Ugandzie!"
-
-#: ../version.c:777
-msgid "type :help iccf<Enter> for information "
-msgstr "wprowad¼ :help iccf<Enter> dla informacji o tym "
-
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr "wprowad¼ :q<Enter> zakoñczenie programu "
-
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "wprowad¼ :help<Enter> lub <F1> pomoc na bie¿±co "
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "wprowad¼ :help version7<Enter> dla informacji o wersji"
-
-#: ../version.c:784
-msgid "Running in Vi compatible mode"
-msgstr "Dzia³am w trybie zgodno¶ci z Vi"
-
-#: ../version.c:785
-msgid "type :set nocp<Enter> for Vim defaults"
-msgstr "wprowad¼ :set nocp<Enter> warto¶ci domy¶lne Vim-a"
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "wprowad¼ :help cp-default<Enter> dla informacji to tym "
-
-#: ../version.c:827
-msgid "Sponsor Vim development!"
-msgstr "Sponsoruj rozwój Vima!"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "Zostañ zarejestrowanym u¿ytkownikiem Vima!"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr "wprowad¼ :help sponsor<Enter> dla informacji"
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr "wprowad¼ :help register<Enter> dla informacji"
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "menu Pomoc->Sponsoruj/Zarejestruj siê dla informacji"
-
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "Ju¿ jest tylko jeden widok"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: Nie ma okna podgl±du"
-
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: Nie mogê rozdzieliæ lewo-górnego i prawo-dolnego jednocze¶nie"
-
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: Nie mogê przekrêciæ, gdy inne okno jest rozdzielone"
-
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: Nie mogê zamkn±æ ostatniego okna"
-
-#: ../window.c:1810
-msgid "E813: Cannot close autocmd window"
-msgstr "E813: Nie mo¿na zamkn±æ okna autocmd"
-
-#: ../window.c:1814
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: Nie mo¿na zamkn±æ okna, zosta³oby tylko okno autocmd"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: Inne okno zawiera zmiany"
-
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: Brak nazwy pliku pod kursorem"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() wywo³any z pustym has³em"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Blowfish u¿ywa b³êdnej kolejno¶ci bajtów"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: test sha256 nie powiód³ siê"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: test Blowfisha nie powiód³ siê"
-
-#~ msgid "Patch file"
-#~ msgstr "Plik ³ata"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&OK\n"
-#~ "&Zakoñcz"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Brak po³±czenia z serwerem Vim"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Nie mogê wys³aæ do %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Nie mogê czytaæ odpowiedzi serwera"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Nie mogê wys³aæ do klienta"
-
-#~ msgid "Save As"
-#~ msgstr "Zapisz jako"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Wczytaj skrypt Vima"
-
-#~ msgid "Edit File"
-#~ msgstr "Edytuj Plik"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (NIE ZNALEZIONO)"
-
-#~ msgid "unknown"
-#~ msgstr "nieznany"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "Edytuj plik w nowym oknie"
-
-#~ msgid "Append File"
-#~ msgstr "Do³±cz plik"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Pozycja okna: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "Zapisz przekierowanie"
-
-#~ msgid "Save View"
-#~ msgstr "Zapisz widok"
-
-#~ msgid "Save Session"
-#~ msgstr "Zapisz sesjê"
-
-#~ msgid "Save Setup"
-#~ msgstr "Zapisz ustawienia"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< nie jest dostêpne bez w³a¶ciwo¶ci +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Brak dwugrafów w tej wersji"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "jest urz±dzeniem (wy³±czonym w opcji 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "Wczytywanie ze stdin..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfish]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[zakodowane]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Plik zaszyfrowano w nieznany sposób"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans nie pozwala na zapis niezmodyfikowanych buforów"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "Czê¶ciowy zapis niemo¿liwy dla buforów NetBeans"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "zapisywanie do urz±dzenia wy³±czone w opcji 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Rozdzia³ zasobów zostanie utracony (wymu¶ przez !)"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<nie mogê otworzyæ> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: nie mogê otrzymaæ czcionki %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: nie mogê powróciæ do bie¿±cego katalogu"
-
-#~ msgid "Pathname:"
-#~ msgstr "Trop:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: nie mogê otrzymaæ bie¿±cego katalogu"
-
-#~ msgid "OK"
-#~ msgstr "OK"
-
-#~ msgid "Cancel"
-#~ msgstr "Zakoñcz"
-
-#~ msgid "Vim dialog"
-#~ msgstr "VIM - Dialog"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr ""
-#~ "Scrollbar Widget: Nie mog³em otrzymaæ rozmiarów rysunku na przycisku."
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Nie mogê stworzyæ BalloonEval z powiadomieniem i wywo³aniem"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: Nie mog³em stworzyæ nowego procesu dla GUI"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: Proces potomny nie móg³ uruchomiæ GUI"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Nie mogê odpaliæ GUI"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Nie mogê czytaæ z \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Nie mo¿na uruchomiæ GUI, brak prawid³owej czcionki"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: Niew³a¶ciwe 'guifontwide'"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Nieprawid³owa warto¶æ 'imactivatekey'"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Nie mogê zarezerwowaæ koloru %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Brak dopasowania przy kursorze, szukam dalej"
-
-#~ msgid "Input _Methods"
-#~ msgstr "Input _Methods"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Szukaj i Zamieñ..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Szukaj..."
-
-#~ msgid "Find what:"
-#~ msgstr "Znajd¼:"
-
-#~ msgid "Replace with:"
-#~ msgstr "Zamieñ na:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Dopasuj tylko ca³e wyrazy"
-
-#~ msgid "Match case"
-#~ msgstr "Dopasuj wielko¶æ liter"
-
-#~ msgid "Direction"
-#~ msgstr "Kierunek"
-
-#~ msgid "Up"
-#~ msgstr "W górê"
-
-#~ msgid "Down"
-#~ msgstr "W dó³"
-
-#~ msgid "Find Next"
-#~ msgstr "Znajd¼ nastêpne"
-
-#~ msgid "Replace"
-#~ msgstr "Zamieñ"
-
-#~ msgid "Replace All"
-#~ msgstr "Zamieñ wszystkie"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: otrzymano ¿±danie \"die\" od mened¿era sesji\n"
-
-#~ msgid "Close"
-#~ msgstr "Zamknij"
-
-#~ msgid "New tab"
-#~ msgstr "Nowa karta"
-
-#~ msgid "Open Tab..."
-#~ msgstr "Otwórz kartê..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: G³ówne okno nieoczekiwanie zniszczone\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&Filtr"
-
-#~ msgid "&Cancel"
-#~ msgstr "&Anuluj"
-
-#~ msgid "Directories"
-#~ msgstr "Katalogi"
-
-#~ msgid "Filter"
-#~ msgstr "Filtr"
-
-#~ msgid "&Help"
-#~ msgstr "&Pomoc"
-
-#~ msgid "Files"
-#~ msgstr "Pliki"
-
-#~ msgid "&OK"
-#~ msgstr "&OK"
-
-#~ msgid "Selection"
-#~ msgstr "Wybór"
-
-#~ msgid "Find &Next"
-#~ msgstr "Znajd¼ &nastêpne"
-
-#~ msgid "&Replace"
-#~ msgstr "&Zamieñ"
-
-#~ msgid "Replace &All"
-#~ msgstr "Zamieñ &wszystko"
-
-#~ msgid "&Undo"
-#~ msgstr "&Cofnij"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Nie mogê znale¼æ tytu³u okna \"%s\""
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Argument nie jest wspomagany: \"-%s\"; U¿ywaj wersji OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Nie mo¿na otworzyæ okna wewn±trz aplikacji MDI"
-
-#~ msgid "Close tab"
-#~ msgstr "Zamknij kartê"
-
-#~ msgid "Open tab..."
-#~ msgstr "Otwórz kartê..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Znajd¼ ci±g (u¿yj '\\\\' do szukania '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Szukanie i Zamiana (u¿yj '\\\\' do szukania '\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "Nie u¿ywany"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Katalog\t*.nic\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Nie mogê zarezerwowaæ mapy kolorów, pewne kolory mog± byæ "
-#~ "nieprawid³owe"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr ""
-#~ "E250: Brak czcionek dla nastêpuj±cych zestawów znaków w zestawie czcionek "
-#~ "%s:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Nazwa zestawu czcionek: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Czcionka '%s' nie posiada znaków jednolitej szeroko¶ci"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: Nazwa zestawu czcionek: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "Font0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "Font1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "Szeroko¶æ font%<PRId64> nie jest podwójn± szeroko¶ci± font0"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "Szeroko¶æ font0: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "Szeroko¶æ font1: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Nieprawid³owy opis czcionki"
-
-#~ msgid "&Dismiss"
-#~ msgstr "&Anuluj"
-
-#~ msgid "no specific match"
-#~ msgstr "brak okre¶lonego dopasowania"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - wybór czcionki"
-
-#~ msgid "Name:"
-#~ msgstr "Nazwa:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Poka¿ wielko¶æ w punktach"
-
-#~ msgid "Encoding:"
-#~ msgstr "Kodowanie:"
-
-#~ msgid "Font:"
-#~ msgstr "Czcionka:"
-
-#~ msgid "Style:"
-#~ msgstr "Styl:"
-
-#~ msgid "Size:"
-#~ msgstr "Wielko¶æ:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: B£¡D w automacie Hangul"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: b³±d stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: nie mogê otworzyæ bazy danych cscope: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: nie mogê uzyskaæ informacji z bazy danych cscope"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Nie mo¿na wczytaæ biblioteki Lua."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "nie mogê zachowaæ informacji cofania"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: Przykro mi, ta komenda jest wy³±czona, biblioteka MzScheme nie mo¿e "
-#~ "byæ za³adowana."
-
-#~ msgid "invalid expression"
-#~ msgstr "niepoprawne wyra¿enie"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "wyra¿enia wy³±czone podczas kompilacji"
-
-#~ msgid "hidden option"
-#~ msgstr "ukryta opcja"
-
-#~ msgid "unknown option"
-#~ msgstr "nieznana opcja"
-
-#~ msgid "window index is out of range"
-#~ msgstr "indeks okna poza zakresem"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "nie mogê otworzyæ bufora"
-
-#~ msgid "cannot delete line"
-#~ msgstr "nie mogê skasowaæ wiersza"
-
-#~ msgid "cannot replace line"
-#~ msgstr "nie mogê zamieniæ wiersza"
-
-#~ msgid "cannot insert line"
-#~ msgstr "nie mogê wprowadziæ wiersza"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ci±g nie mo¿e zawieraæ znaków nowego wiersza"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "b³±d przy konwersji warto¶ci Scheme do Vima"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "B³±d vima: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "B³±d Vima"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "bufor jest niewa¿ny"
-
-#~ msgid "window is invalid"
-#~ msgstr "okno jest niewa¿ne"
-
-#~ msgid "linenr out of range"
-#~ msgstr "numer wiersza poza zakresem"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "Niedozwolone w piaskownicy Vima"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: Python: nie mo¿na u¿ywaæ :py i :py3 w czasie jednej sesji"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: Przykro mi, ta komenda jest wy³±czona, bo nie mo¿na za³adowaæ "
-#~ "biblioteki Pythona"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: Python: nie mo¿na u¿ywaæ :py i :py3 w czasie jednej sesji"
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Nie mo¿na wywo³aæ Pythona rekursywnie"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ musi byæ reprezentacj± £añcucha"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Przykro mi, ta komenda jest wy³±czona, bo nie mo¿na za³adowaæ "
-#~ "biblioteki Ruby."
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: nieoczekiwany return"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: nieoczekiwany next"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: nieoczekiwany break"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: nieoczekiwane redo"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: ponowna próba poza klauzul± ratunku"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: nieobs³ugiwany wyj±tek"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: Nieznany status longjmp %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Prze³±cz miêdzy implementacj±/okre¶leniem"
-
-#~ msgid "Show base class of"
-#~ msgstr "Poka¿ bazê klasy"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Poka¿ przepisan± funkcjê cz³onow±"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Pobieraj z pliku"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Pobieraj z projektu"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Pobieraj z wszystkich projektów"
-
-#~ msgid "Retrieve"
-#~ msgstr "Pobierz"
-
-#~ msgid "Show source of"
-#~ msgstr "Poka¿ ¼ród³o dla"
-
-#~ msgid "Find symbol"
-#~ msgstr "Znajd¼ symbol"
-
-#~ msgid "Browse class"
-#~ msgstr "Przejrzyj klasê"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Poka¿ klasê w hierarchii"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Poka¿ klasê w ograniczonej hierarchii"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref odnosi siê do"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ma odniesienia od"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ma"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref u¿yte przez"
-
-#~ msgid "Show docu of"
-#~ msgstr "Poka¿ dokumentacjê dla"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Utwórz dokumentacjê dla"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Nie mogê pod³±czyæ do SNiFF+. Sprawd¼ ¶rodowisko (sniffemacs musi byæ "
-#~ "odnaleziony w $PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: B³±d podczas czytania. Roz³±czenie"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ jest obecnie "
-
-#~ msgid "not "
-#~ msgstr "nie "
-
-#~ msgid "connected"
-#~ msgstr "pod³±czony"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Nieznane zapytanie SNiFF+: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: B³±d w trakcie pod³±czania do SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ niepod³±czony"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Nie jest buforem SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: B³±d w trakcie zapisu. Roz³±czony"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "niew³a¶ciwy numer bufora"
-
-#~ msgid "not implemented yet"
-#~ msgstr "obecnie nie zaimplementowano"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "nie mogê ustawiæ wiersza(y)"
-
-#~ msgid "invalid mark name"
-#~ msgstr "niepoprawna nazwa zak³adki"
-
-#~ msgid "mark not set"
-#~ msgstr "zak³adka nie ustawiona"
-
-#~ msgid "row %d column %d"
-#~ msgstr "wiersz %d kolumna %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "nie mogê wprowadziæ/do³±czyæ wiersza"
-
-#~ msgid "line number out of range"
-#~ msgstr "numer wiersza poza zakresem"
-
-#~ msgid "unknown flag: "
-#~ msgstr "nieznana flaga: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "nieznane vimOption"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "przerwanie klawiatury"
-
-#~ msgid "vim error"
-#~ msgstr "b³±d vima"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "nie mogê stworzyæ bufora/okna komendy: obiekt jest kasowany"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "nie mogê zarejestrowaæ wstecznego wywo³ania komendy: bufor/okno ju¿ "
-#~ "zosta³a skasowana"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: TCL FATALNY B£¡D: reflist zepsuta!? Proszê z³o¿yæ raport o tym na "
-#~ "vim-dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "nie mogê zarejestrowaæ wstecznego wywo³ania komendy: brak odniesienia do "
-#~ "bufora/okna"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E571: Przykro mi, ta komenda jest wy³±czona, bo nie mo¿na za³adowaæ "
-#~ "biblioteki Tcl."
-
-#~ msgid "E572: exit code %d"
-#~ msgstr "E572: kod wyj¶cia %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "nie mogê dostaæ wiersza"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Nie mogê zarejestrowaæ nazwy serwera komend"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Wys³anie komendy do programu docelowego nie powiod³o siê"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: U¿yto niew³a¶ciwego id serwera: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: wcielenia instancji rejestru Vima jest ¼le sformowane. Skasowano!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans nie s± obs³ugiwane przez to GUI\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Ta wersja Vima nie by³a skompilowanego z opcj± ró¿nic (diff)."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "'-nb' - nie mo¿e byæ u¿yte: nie w³±czone przy kompilacji\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: B³±d: Nie mo¿na uruchomiæ gvim z NetBeans\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "gdzie wielko¶æ znaków jest ignorowana dodaj na pocz±tku / by flaga by³a "
-#~ "wielk± liter±"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tZarejestruj tego gvima w OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tWyrejestruj gvima z OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tStartuj w GUI (tak jak \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f lub --nofork\tPierwszy plan: Nie wydzielaj przy odpalaniu GUI"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tNie stosuj newcli do otwierania okien"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tU¿ywaj <device> do I/O"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tU¿yj <gvimrc> zamiast jakiegokolwiek .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tEdytuj zakodowane pliki"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\tPod³±cz vima to danego X-serwera"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tNie ³±cz z serwerem X"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <pliki>\tEdytuj pliki w serwerze Vima je¶li mo¿liwe"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <pliki> To samo, nie narzekaj je¶li nie ma serwera"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <pliki>\tTak jak --remote, lecz czekaj na pliki przed edycj±"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <pliki> To samo, nie narzekaj je¶li nie ma serwera"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <pliki> tak jak --remote ale u¿ywa jednej "
-#~ "karty na plik"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <klawisze>\tWy¶lij <klawisze> do serwera Vima i zakoñcz"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <wyr>\tWykonaj <wyra¿enie> w serwerze i wypisz wynik"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\tWymieñ nazwy dostêpnych serwerów Vima i zakoñcz"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <nazwa>\t\tOdsy³aj do/stañ siê serwerem Vim <nazwa>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja Motif):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja neXtaw):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja Athena):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\tZa³aduj vim na <display>"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tZacznij Vim jako ikonê"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <kolor>\tU¿ywaj <kolor> dla t³a (równie¿: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <kolor>\tU¿ywaj <kolor> dla normalnego tekstu (równie¿: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t\tU¿ywaj <font> dla normalnego tekstu (równie¿: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\tU¿ywaj <font> dla wyt³uszczonego tekstu"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <font>\tU¿ywaj <font> dla pochy³ego"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr ""
-#~ "-geometry <geom>\tU¿ywaj <geom> dla pocz±tkowych rozmiarów (równie¿: -"
-#~ "geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <szer>\tU¿yj ramki o grubo¶ci <szer> (równie¿: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <szer> U¿ywaj przewijacza o szeroko¶ci <szer> (równie¿: -"
-#~ "sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr ""
-#~ "-menuheight <height>\tStosuj belkê menu o wysoko¶ci <height> (równie¿: -"
-#~ "mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tStosuj negatyw kolorów (równie¿: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tNie stosuj negatywu kolorów (równie¿: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\tUstaw okre¶lony zasób"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja GTK+):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\tZastartuj vim na <display> (równie¿: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\tUstaw unikatow± rolê do identyfikacji g³ównego okna"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tOtwórz Vim wewn±trz innego widgetu GTK"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "-echo-wid\t\tGvim wypisze Window ID na wyj¶cie standardowe"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <tytu³ rodzica>\tOtwórz Vima wewn±trz rodzicielskiej aplikacji"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tOtwórz Vima wewn±trz innego elementu win32"
-
-#~ msgid "No display"
-#~ msgstr "Brak display"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Wys³anie nie powiod³o siê.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Wys³anie nie powiod³o siê. Próbujê wykonaæ na miejscu\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "otworzono %d z %d"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Brak terminala: Wys³anie wyra¿enia nie powiod³o siê.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Wys³anie wyra¿enia nie powiod³o siê.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: To nie jest wa¿na strona kodowa"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: Nie mogê nastawiæ warto¶ci IC"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Nie mog³em stworzyæ kontekstu wprowadzeñ"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Nie mog³em otworzyæ sposobu wprowadzeñ"
-
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: OSTRZE¯ENIE: Nie mog³em zlikwidowaæ wywo³ania dla IM"
-
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: metoda wprowadzeñ nie wspomaga ¿adnego stylu"
-
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: metoda wprowadzeñ nie wspomaga mojego typu preedit"
-
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: B³±d w czasie uaktualniania szyfrowania pliku wymiany"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s jest zaszyfrowany a ta wersja Vima nie wspiera szyfrowania"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Zaszyfrowany plik wymiany: \"%s\""
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "Je¶li podano nowy klucz szyfruj±cy, ale nie zapisano pliku tekstowego,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "wprowad¼ nowy klucz szyfruj±cy."
-
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "Je¶li zapisano plik tekstowy po zmianie klucza szyfruj±cego wci¶nij Enter"
-
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "aby u¿yæ tego samego klucza dla pliku tekstowego i wymiany"
-
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "U¿ywam klucza szyfruj±cego z pliku wymiany do pliku tekstowego.\n"
-
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [nie nadaje siê dla tej wersji Vima]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "Oderwij to menu"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Dialog wyboru katalogu"
-
-#~ msgid "Save File dialog"
-#~ msgstr "Dialog zapisywania pliku"
-
-#~ msgid "Open File dialog"
-#~ msgstr "Dialog otwierania pliku"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Przykro mi, nie ma przegl±darki plików w trybie konsoli"
-
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: zachowujê plik...\n"
-
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: Zakoñczono.\n"
-
-#~ msgid "ERROR: "
-#~ msgstr "B£¡D: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[bajtów] totalne alokacje-zwolnienia %<PRIu64>-%<PRIu64>, w u¿ytku "
-#~ "%<PRIu64>, maksymalne u¿ycie %<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[wywo³ania] wszystkich re/malloc()-ów %<PRIu64>, wszystkich free()-ów "
-#~ "%<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Wiersz staje siê zbyt d³ugi"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Wewnêtrzny b³±d: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Niedozwolony obrys myszki"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "Wprowad¼ klucz do odkodowania: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "Wprowad¼ ponownie ten sam klucz: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Klucze nie pasuj± do siebie!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Nie mo¿na po³±czyæ z Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Nie mo¿na po³±czyæ z Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: B³êdny tryb dostêpu pliku info po³±czenia NetBeans: \"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "odczyt z gniazda Netbeans"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Bufor %<PRId64> utraci³ po³±czenie z NetBeans"
-
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: netbeans nie s± obs³ugiwane przez to GUI"
-
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans ju¿ pod³±czone"
-
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s jest tylko do odczytu (dodaj ! aby wymusiæ)"
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Funkcjonalno¶æ eval nie jest dostêpna"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "zwalniam %<PRId64> wierszy"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Nie mogê zmieniæ term w GUI"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: U¿yj \":gui\" do odpalenia GUI"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Nie mogê zmieniæ w GTK+2 GUI"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Niedozwolona czcionka/ki"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: nie mogê wybraæ zestawu czcionek"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Niedozwolony zestaw czcionek"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: nie mogê wybraæ szerokiej czcionki"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Niedozwolona szeroka czcionka"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Brak wspomagania myszki"
-
-#~ msgid "cannot open "
-#~ msgstr "nie mogê otworzyæ "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Nie mogê otworzyæ okna!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Potrzebujê Amigados w wersji 2.04 lub pó¼niejsz±\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Potrzebujê %s w wersji %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Nie mogê otworzyæ NIL:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "Nie mogê stworzyæ "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim koñczy pracê z %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "nie mogê zmieniæ trybu konsoli ?!\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: nie jest konsol±??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Nie mogê wykonaæ pow³oki z opcj± -f"
-
-#~ msgid "Cannot execute "
-#~ msgstr "Nie mogê wykonaæ "
-
-#~ msgid "shell "
-#~ msgstr "pow³oka "
-
-#~ msgid " returned\n"
-#~ msgstr " zwróci³\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE zbyt niskie."
-
-#~ msgid "I/O ERROR"
-#~ msgstr "B£¡D I/O"
-
-#~ msgid "Message"
-#~ msgstr "Wiadomo¶æ"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' nie wynosi 80, nie mogê wykonaæ zewnêtrznych komend"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Wybór drukarki nie powiód³ siê"
-
-#~ msgid "to %s on %s"
-#~ msgstr "do %s z %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Nieznana czcionka drukarki: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: B³±d drukarki: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "Wydrukowano '%s'"
-
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr ""
-#~ "E244: Niedozwolona nazwa zestawu znaków \"%s\" w nazwie czcionki \"%s\""
-
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: Niedozwolony znak '%c' w nazwie czcionki \"%s\""
-
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Podwójny sygna³, wychodzê\n"
-
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Za³apa³ ¶miertelny sygna³ %s\n"
-
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Za³apa³ ¶miertelny sygna³\n"
-
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Otwieranie ekranu X trwa³o %<PRId64> msec"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Dosta³ b³±d X\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "Test ekranu X nie powiód³ siê"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Próba otwarcia ekranu X trwa³a zbyt d³ugo"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Nie mogê wykonaæ pow³oki sh\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Nie mogê stworzyæ potoków\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Nie mogê rozdzieliæ siê\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Komenda zakoñczona\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP straci³ po³±czenie ICE"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "Otwarcie ekranu X nie powiod³o siê"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP obs³uguje ¿±danie samozapisu"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP otwiera po³±czenie"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "Obserwacja po³±czenia XSMP ICE nie powiod³a siê"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection nie powiod³o siê: %s"
-
-#~ msgid "At line"
-#~ msgstr "W wierszu"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Nie mogê za³adowaæ vim32.dll!"
-
-#~ msgid "VIM Error"
-#~ msgstr "B³±d VIM"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Nie zdo³a³em poprawiæ wska¼ników funkcji w DLL!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "pow³oka zwróci³a %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Za³apa³ wydarzenie %s\n"
-
-#~ msgid "close"
-#~ msgstr "zamknij"
-
-#~ msgid "logoff"
-#~ msgstr "wyloguj"
-
-#~ msgid "shutdown"
-#~ msgstr "zakoñcz"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Nie znaleziono komendy"
-
-#~ 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 ""
-#~ "VIMRUN.EXE nie znaleziono w twoim $PATH.\n"
-#~ "Zewnêtrzne komendy nie bêd± wstrzymane po wykonaniu.\n"
-#~ "Zobacz :help wim32-vimrun aby otrzymaæ wiêcej informacji."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Vim Ostrze¿enie"
-
-#~ msgid "Error file"
-#~ msgstr "Plik b³êdu"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: B³±d przy budowwaniu NFA z klas± ekwiwalencji"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr ""
-#~ "E878: (NFA) Nie mo¿na przydzieliæ pamiêci do przej¶cia przez ga³êzie!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "Ostrze¿enie: Nie mogê znale¼æ listy s³ów \"%s_%s.spl\" lub \"%s_ascii.spl"
-#~ "\""
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Konwersja w %s nie jest wspierana"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr ""
-#~ "E845: Nie wystarczaj±ca ilo¶æ pamiêci, lista s³ów bêdzie niekompletna"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Trop szukania pliku znaczników obciêty dla %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "uruchomiono now± pow³okê\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "U¿ywam CUT_BUFFER0 zamiast pustego wyboru"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Cofniêcie niemo¿liwe; mimo to kontynuujê"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Nie zaszyfrowany plik ma zaszyfrowany plik undo: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Nie powiod³o siê odszyfrowywanie pliku undo: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Plik undo jest zaszyfrowany: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "16/32-bit wersja GUI dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "64 bitowa wersja GUI dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 bitowa wersja GUI dla MS-Windows"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " w trybie Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " ze wspomaganiem OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 bitowa wersja na konsolê dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 bitowa wersja na konsolê dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 bitowa wersja dla MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 bitowa wersja dla MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 bitowa wersja dla MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla MacOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla MacOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Du¿a wersja "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Normalna wersja "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Ma³a wersja "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Malutka wersja "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "z GTK2-GNOME GUI."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "z GTK2 GUI."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "z X11-Motif GUI."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "z X11-neXtaw GUI."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "z X11-Athena GUI."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "z Photon GUI."
-
-#~ msgid "with GUI."
-#~ msgstr "z GUI."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "z Carbon GUI."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "z Cocoa GUI."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "z (klasycznym) GUI."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " gvimrc systemu: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " gvimrc u¿ytkownika: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "2-gi plik gvimrc u¿ytkownika: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "3-ci plik gvimrc u¿ytkownika: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " systemowy plik menu: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Kompilator: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "menu Pomoc->Sieroty dla informacji to tym "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Uruchomiony bez trybów, wpisany tekst jest wprowadzany"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "menu Edytuj->Ustawienia globalne->Tryb wstawiania"
-
-#~ msgid " for two modes "
-#~ msgstr " dla dwóch trybów "
-
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "menu Edytuj->Ustawienia globalne->Kompatybilno¶æ z Vi"
-
-#~ msgid " for Vim defaults "
-#~ msgstr " dla domy¶lnych ustawieñ Vima "
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "OSTRZE¯ENIE: wykryto Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "wprowad¼ :help windows95<Enter> dla informacji to tym "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Nie mog³em za³adowaæ biblioteki %s"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "Przykro mi, ta komenda jest wy³±czona: nie mog³em za³adowaæ biblioteki "
-#~ "Perla."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr "E299: wyliczenie Perla zabronione w piaskownicy bez modu³u Safe"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Edytuj w &wielu Vimach"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Edytuj w pojedynczym &Vimie"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Diff z Vimem"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Edytuj w &Vimie"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Edytuj z istniej±cym Vimem - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Edytuj wybrane pliki w Vimie"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "B³±d tworzenia procesu: Sprawd¼ czy gvim jest w twojej ¶cie¿ce!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "b³±d gvimext.dll"
-
-#~ msgid "Path length too long!"
-#~ msgstr "Za d³uga ¶cie¿ka!"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Nieznany zestaw czcionek: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Nieznana czcionka: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Czcionka \"%s\" nie ma sta³ej szeroko¶ci znaków"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Nie mo¿na za³adowaæ funkcji biblioteki %s"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E26: Hebrajski nie mo¿e byæ u¿yty: Nie w³±czono podczas kompilacji\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Farsi nie mo¿e byæ u¿yty: Nie w³±czono podczas kompilacji\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: Arabski nie mo¿e byæ u¿yty: Nie w³±czono podczas kompilacji\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: brak zarejestrowanego serwera o nazwie \"%s\""
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: nie mogê otworzyæ ekranu"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Odebra³em niew³a¶ciwe wyra¿enie"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Region jest chroniony, nie mogê zmieniæ"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans nie zezwala na zmiany w plikach tylko do odczytu"
-
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Potrzebujê klucza szyfrowania dla \"%s\""
-
-#~ msgid "empty keys are not allowed"
-#~ msgstr "puste klucze nie s± dozwolone"
-
-#~ msgid "dictionary is locked"
-#~ msgstr "s³ownik jest zablokowany"
-
-#~ msgid "list is locked"
-#~ msgstr "lista jest zablokowana"
-
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "nie powiod³o siê dodanie klucza '%s' do s³ownika"
-
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "indeks musi byæ liczb± lub wycinkiem, nie %s"
-
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr "czeka³em na str() lub unicode(), a dosta³em %s"
-
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "czeka³em na bytes() lub str(), a dosta³em %s"
-
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr ""
-#~ "czeka³em na int(), long() lub co¶ co mo¿na zmieniæ na long(), ale "
-#~ "dosta³em %s"
-
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr ""
-#~ "czeka³em na int() lub co¶ co mo¿na zmieniæ na int(), ale dosta³em %s"
-
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "warto¶æ zbyt du¿a by zmie¶ci³a siê w typie int C"
-
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "warto¶æ jest zbyt ma³a by zmie¶ci³a siê w typie int C"
-
-#~ msgid "number must be greater then zero"
-#~ msgstr "liczba musi byæ wiêksza ni¿ zero"
-
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "liczba musi byæ wiêksza lub mniejsza ni¿ zero"
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "nie mogê skasowaæ atrybutów OutputObject"
-
-#~ msgid "invalid attribute: %s"
-#~ msgstr "niepoprawny atrybut: %s"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: B³±d w uruchomieniu obiektów I/O"
-
-#~ msgid "failed to change directory"
-#~ msgstr "nie powiod³a siê zmiana katalogu"
-
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "czeka³em na 3-krotkê jako wynik imp.find_module(), a dosta³em %s"
-
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr ""
-#~ "czeka³em na 3-krotkê jako wynik imp.find_module(), a dosta³em krotkê o "
-#~ "wielko¶ci %d"
-
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "wewnêtrzny b³±d: imp.find_module zwróci³ krotkê z NULL"
-
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "nie mogê usun±æ atrybutów vim.Dictionary"
-
-#~ msgid "cannot modify fixed dictionary"
-#~ msgstr "nie mogê zmieniæ zablokowanego s³ownika"
-
-#~ msgid "cannot set attribute %s"
-#~ msgstr "nie mogê ustawiæ atrybutu %s"
-
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "hashtab zmieni³ siê w czasie iteracji"
-
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr ""
-#~ "czeka³em na element sekwencyjny od d³ugo¶ci 2, a dosta³em sekwencjê o "
-#~ "d³ugo¶ci %d"
-
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "konstruktor listy nie akceptuje s³ów kluczowych jako argumentów"
-
-#~ msgid "list index out of range"
-#~ msgstr "indeks listy poza zakresem"
-
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "b³±d wewnêtrzny: nie powiod³o siê pobranie z listy Vima elementu %d"
-
-#~ msgid "failed to add item to list"
-#~ msgstr "nie powiod³o siê dodanie elementu do listy"
-
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "b³±d wewnêtrzny: w li¶cie Vima brak elementu %d"
-
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "b³±d wewnêtrzny: nie powiod³o siê dodanie elementu do listy"
-
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "nie mogê usun±æ atrybutów vim.List"
-
-#~ msgid "cannot modify fixed list"
-#~ msgstr "nie mogê zmieniæ zablokowanej listy"
-
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "nie nazwana funkcja %s nie istnieje"
-
-#~ msgid "function %s does not exist"
-#~ msgstr "funkcja %s nie istnieje"
-
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "konstruktor funkcji nie akceptuje s³ów kluczowych jako argumentów"
-
-#~ msgid "failed to run function %s"
-#~ msgstr "nie mogê uruchomiæ funkcji %s"
-
-#~ msgid "problem while switching windows"
-#~ msgstr "wyst±pi³ problem w czasie zmiany okien"
-
-#~ msgid "unable to unset global option %s"
-#~ msgstr "nie mogê wyzerowaæ opcji globalnej %s"
-
-#~ msgid "unable to unset option %s which does not have global value"
-#~ msgstr "nie mogê wyzerowaæ opcji %s, która nie ma warto¶ci globalnej"
-
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "próba odniesienia do skasowanej karty"
-
-#~ msgid "no such tab page"
-#~ msgstr "nie ma takiej karty"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "próba odniesienia do skasowanego okna"
-
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "atrybut tylko do odczytu: bufor"
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "pozycja kursora poza buforem"
-
-#~ msgid "no such window"
-#~ msgstr "nie ma takiego okna"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "próba odniesienia do skasowanego bufora"
-
-#~ msgid "failed to rename buffer"
-#~ msgstr "nie powiod³a siê zmiana nazwy bufora"
-
-#~ msgid "mark name must be a single character"
-#~ msgstr "nazwa zak³adki musi byæ pojedynczym znakiem"
-
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "oczekiwa³em na obiekt vim.Buffer, a dosta³em %s"
-
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "nie przeszed³em do bufora %d"
-
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "oczekiwa³em na obiekt vim.Window, a dosta³em %s"
-
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "nie znaleziono okna na bie¿±cej karcie"
-
-#~ msgid "did not switch to the specified window"
-#~ msgstr "nie przeszed³em do okre¶lonego okna"
-
-#~ msgid "expected vim.TabPage object, but got %s"
-#~ msgstr "oczekiwa³em na obiekt vim.TabPage, a dosta³em %s"
-
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "nie przeszed³em do okre¶lonej karty"
-
-#~ msgid "failed to run the code"
-#~ msgstr "uruchomienie kodu siê nie powiod³o"
-
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: eval nie zwróci³o odpowiedniego obiektu pythona"
-
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: Nie powiod³a siê konwersja obiektu pythona do warto¶ci Vima"
-
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "nie mo¿na konwertowaæ %s do s³ownika Vima"
-
-#~ msgid "unable to convert %s to vim structure"
-#~ msgstr "nie mo¿na konwertowaæ %s do struktury Vima"
-
-#~ msgid "internal error: NULL reference passed"
-#~ msgstr "b³±d wewnêtrzny: przekazano referencjê NULL"
-
-#~ msgid "internal error: invalid value type"
-#~ msgstr "b³±d wewnêtrzny: b³êdny typ warto¶ci"
-
-#~ msgid ""
-#~ "Failed to set path hook: sys.path_hooks is not a list\n"
-#~ "You should now do the following:\n"
-#~ "- append vim.path_hook to sys.path_hooks\n"
-#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
-#~ msgstr ""
-#~ "Nie mogê ustawiæ haka ¶cie¿ki: sys.path_hooks nie jest list±\n"
-#~ "Powiniene¶ teraz wykonaæ nastêpuj±ce czynno¶ci:\n"
-#~ "- dodaæ vim.path_hook do sys.path_hooks\n"
-#~ "- dodaæ vim.VIM_SPECIAL_PATH do sys.path\n"
-
-#~ msgid ""
-#~ "Failed to set path: sys.path is not a list\n"
-#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
-#~ msgstr ""
-#~ "Nie mogê ustawiæ ¶cie¿ki: sys.path nie jest list±\n"
-#~ "Powinno siê teraz dodaæ vim.VIM_SPECIAL_PATH do sys.path"
-
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspace musi byæ liczb± ca³kowit±"
-
-#~ msgid "<buffer object (deleted) at %p>"
-#~ msgstr "<obiekt bufora (skasowany) w %p>"
-
-#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
-#~ msgstr ""
-#~ "E281: B£¡D TCL: kod zakoñczeniowy nie jest ca³kowity!? Proszê z³o¿yæ "
-#~ "raport o tym na vim-dev@vim.org"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Argumenty rozpoznawane przez gvim (wersja RISC OS):\n"
-
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <number>\tPocz±tkowa szeroko¶æ okna w kolumnach"
-
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <number>\tPocz±tkowa wysoko¶æ okna w wierszach"
-
-#~ msgid "E505: "
-#~ msgstr "E505: "
-
-#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
-#~ msgstr ""
-#~ "\n"
-#~ "wersja dla RISC OS"
-
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines() wymaga listy ci±gów"
-
-#~ msgid "<window object (deleted) at %p>"
-#~ msgstr "<obiekt okna (skasowany) w %p>"
-
-#~ msgid "<window object (unknown) at %p>"
-#~ msgstr "<obiekt okna (nieznany) w %p>"
-
-#~ msgid "<window %d>"
-#~ msgstr "<okno %d>"
-
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <nazwa>\t\tU¿ywaj zasobów tak jak by Vim by³ <nazwa>"
-
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (Niezaimplementowane)\n"
-
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: argument containedin niedozwolony w tym miejscu"
-
-#~ msgid "Vim dialog..."
-#~ msgstr "Dialog Vima..."
-
-#~ msgid "Font Selection"
-#~ msgstr "Wybór czcionki"
-
-#~ msgid "E290: over-the-spot style requires fontset"
-#~ msgstr "E290: styl nadpunktowy wymaga +fontset"
-
-#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
-#~ msgstr "E291: Twój GTK+ jest starszy ni¿ 1.2.3. Pole statusu wy³±czono"
-
-#~ msgid "E292: Input Method Server is not running"
-#~ msgstr "E292: Serwer metod wprowadzeñ nie jest uruchomiony"
-
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "z GTK-GNOME GUI."
-
-#~ msgid "with GTK GUI."
-#~ msgstr "z GTK GUI."
-
-#~ msgid "[NL found]"
-#~ msgstr "[znaleziono NL]"
-
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: wyczerpano maksymaln± liczbê po³±czeñ cscope"
diff --git a/src/nvim/po/pt_BR.po b/src/nvim/po/pt_BR.po
index 60c11d4b5a..543f0bce27 100644
--- a/src/nvim/po/pt_BR.po
+++ b/src/nvim/po/pt_BR.po
@@ -24,7 +24,7 @@ msgstr "[Ajuda]"
#: ../screen.c:4815 ../buffer.c:3244
msgid "[Preview]"
-msgstr "[Visualização]"
+msgstr "[Visualização]"
#: ../screen.c:4823 ../fileio.c:1855 ../buffer.c:2496 ../buffer.c:3207
msgid "[RO]"
@@ -2478,11 +2478,6 @@ msgstr "E900: Id do job é inválido"
msgid "E901: Job table is full"
msgstr "E901: Tabela de jobs está cheia"
-#: ../globals.h:1021
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr "E902: \"%s\" não é um executável"
-
#: ../globals.h:1023
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3217,7 +3212,7 @@ msgstr "E216: Grupo ou evento inexistente: %s"
#: ../fileio.c:6002
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Autocomandos ---"
@@ -4864,7 +4859,7 @@ msgstr " tipo arquivo\n"
#: ../ex_getln.c:4762
msgid "'history' option is zero"
-msgstr "opção 'history' vale zero"
+msgstr "opção 'history' vale zero"
#: ../ex_getln.c:5008
#, c-format
@@ -5311,7 +5306,7 @@ msgstr "Aviso: região %s não é suportada"
#: ../spell.c:4366
#, c-format
-msgid "Reading affix file %s ..."
+msgid "Reading affix file %s..."
msgstr "Lendo arquivo de afixos %s..."
#: ../spell.c:4405 ../spell.c:5451 ../spell.c:5956
@@ -5511,8 +5506,8 @@ msgstr "Foram ignoradas %d palavra(s) com caracteres não-ASCII em %s"
#: ../spell.c:5931
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Lendo arquivo de palavras %s ..."
+msgid "Reading word file %s..."
+msgstr "Lendo arquivo de palavras %s..."
#: ../spell.c:5971
#, c-format
@@ -6174,7 +6169,7 @@ msgstr "-q [arq.erro] editar arquivo e abrir no primeiro erro"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -6208,7 +6203,7 @@ msgstr "--\t\t\tApenas nomes de arquivo depois daqui"
#: ../main.c:2177
msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tNão expandir caracteres-curinga"
+msgstr "--literal\t\tNão expandir caracteres-curinga"
#: ../main.c:2179
msgid "-v\t\t\tVi mode (like \"vi\")"
@@ -6232,7 +6227,7 @@ msgstr "-d\t\t\tModo diff (como \"vimdiff\")"
#: ../main.c:2184
msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tModo fácil (como \"evim\", o Vim não modal)"
+msgstr "-y\t\t\tModo fácil (como \"evim\", o Vim não modal)"
#: ../main.c:2185
msgid "-R\t\t\tReadonly mode (like \"view\")"
@@ -6346,8 +6341,8 @@ msgstr ""
#: ../main.c:2213
msgid "-S <session>\t\tSource file <session> after loading the first file"
msgstr ""
-"-S <sessão>\t\tExecutar o arquivo <sessão> depois de carregar o\n"
-"\t\t\tprimeiro arquivo"
+"-S <sessão>\t\tExecutar o arquivo <sessão> depois de carregar o "
+"primeiro arquivo"
#: ../main.c:2214
msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
diff --git a/src/nvim/po/ru.cp1251.po b/src/nvim/po/ru.cp1251.po
deleted file mode 100644
index 29e8c83ee6..0000000000
--- a/src/nvim/po/ru.cp1251.po
+++ /dev/null
@@ -1,8282 +0,0 @@
-# Russian translation for Vim
-#
-# Îá óñëîâèÿõ èñïîëüçîâàíèÿ ÷èòàéòå â ðåäàêòîðå Vim ":help uganda"
-#
-# vassily "vr" ragosin <vrr@users.sourceforge.net>, 2004
-# Sergey Alyoshin <alyoshin.s@gmail.com>, 2013
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: vim_ru\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2014-10-10 12:00+0400\n"
-"Last-Translator: Sergey Alyoshin <alyoshin.s@gmail.com>\n"
-"Language-Team: \n"
-"Language: Russian\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=cp1251\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "Íåâîçìîæíî ïîëó÷èòü çíà÷åíèå îïöèè"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "Âíóòðåííÿÿ îøèáêà: íåèçâåñòíûé òèï îïöèè"
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[Ñïèñîê ðàñïîëîæåíèé]"
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[Ñïèñîê áûñòðûõ èñïðàâëåíèé]"
-
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr "E855: Àâòîêîìàíäû âûçâàëè ïðåêðàùåíèå êîìàíäû"
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: Íåâîçìîæíî âûäåëèòü ïàìÿòü äàæå äëÿ îäíîãî áóôåðà, âûõîä..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: Íåâîçìîæíî âûäåëèòü ïàìÿòü äëÿ áóôåðà, èñïîëüçóåì äðóãîé áóôåð..."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: Íè îäèí áóôåð íå áûë âûãðóæåí èç ïàìÿòè"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: Íè îäèí áóôåð íå áûë óäàë¸í"
-
-#: ../buffer.c:767
-msgid "E517: No buffers were wiped out"
-msgstr "E517: Íè îäèí áóôåð íå áûë î÷èùåí"
-
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "Îäèí áóôåð âûãðóæåí èç ïàìÿòè"
-
-#: ../buffer.c:774
-#, c-format
-msgid "%d buffers unloaded"
-msgstr "Âñåãî âûãðóæåíî áóôåðîâ èç ïàìÿòè: %d"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "Îäèí áóôåð óäàë¸í"
-
-#: ../buffer.c:779
-#, c-format
-msgid "%d buffers deleted"
-msgstr "Âñåãî óäàëåíî áóôåðîâ: %d"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "Îäèí áóôåð î÷èùåí"
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "Âñåãî î÷èùåíî áóôåðîâ: %d"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: Íåâîçìîæíî âûãðóçèòü èç ïàìÿòè ïîñëåäíèé áóôåð"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: Èçìåí¸ííûõ áóôåðîâ íå îáíàðóæåíî"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-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
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: Ýòî ïîñëåäíèé áóôåð"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: Ýòî ïåðâûé áóôåð"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr ""
-"E89: Èçìåíåíèÿ â áóôåðå %<PRId64> íå ñîõðàíåíû (äîáàâüòå !, ÷òîáû îáîéòè "
-"ïðîâåðêó)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: Ïðåäóïðåæäåíèå: ïåðåïîëíåíèå ñïèñêà èì¸í ôàéëîâ"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Áóôåð %<PRId64> íå íàéäåí"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: Íåñêîëüêî ñîîòâåòñòâèé äëÿ %s"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: Íåò ñîîòâåòñòâóþùåãî %s áóôåðà"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "ñòðîêà %<PRId64>"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: Áóôåð ñ òàêèì èìåíåì óæå ñóùåñòâóåò"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [Èçìåí¸í]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[Íå ðåäàêòèðîâàëñÿ]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[Íîâûé ôàéë]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[Îøèáêè ÷òåíèÿ]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[Ò×]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-msgid "[readonly]"
-msgstr "[òîëüêî äëÿ ÷òåíèÿ]"
-
-#: ../buffer.c:2524
-#, c-format
-msgid "1 line --%d%%--"
-msgstr "Îäíà ñòðîêà --%d%%--"
-
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> ñòð. --%d%%--"
-
-#: ../buffer.c:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "ñòð. %<PRId64> èç %<PRId64> --%d%%-- êîë. "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-msgid "[No Name]"
-msgstr "[Íåò èìåíè]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "ñïðàâêà"
-
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[Ñïðàâêà]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[Ïðåäïðîñìîòð]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "Âåñü"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "Âíèçó"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "Íàâåðõó"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# Ñïèñîê áóôåðîâ:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr "[Âðåìåííûé]"
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- Çíà÷êè ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "Çíà÷êè äëÿ %s:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ñòðîêà=%<PRId64> id=%d èìÿ=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: Ïðîïóùåíî äâîåòî÷èå"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: Íåäîïóñòèìûé ðåæèì"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: Òðåáóåòñÿ ââåñòè öèôðó"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Íåäîïóñòèìîå çíà÷åíèå ïðîöåíòîâ"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Ñëåäèòü çà îòëè÷èÿìè ìîæíî íå áîëåå ÷åì â %<PRId64> áóôåðàõ"
-
-#: ../diff.c:753
-msgid "E810: Cannot read or write temp files"
-msgstr "E810: Íåâîçìîæíî ïðî÷èòàòü èëè çàïèñàòü âðåìåííûå ôàéëû"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: Íåâîçìîæíî ñîçäàòü ôàéëû îòëè÷èé"
-
-#: ../diff.c:966
-msgid "E816: Cannot read patch output"
-msgstr "E816: Íåâîçìîæíî ïðî÷èòàòü âûâîä patch"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: Íåâîçìîæíî ïðî÷èòàòü âûâîä diff"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: Àêòèâíûé áóôåð íå íàõîäèòñÿ â ðåæèìå îòëè÷èé"
-
-#: ../diff.c:2100
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E793: Áîëüøå íåò èçìåíÿåìûõ áóôåðîâ â ðåæèìå îòëè÷èé"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: Áîëüøå íåò áóôåðîâ â ðåæèìå îòëè÷èé"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr "E101:  ðåæèìå îòëè÷èé áîëåå äâóõ áóôåðîâ, íå ìîãó âûáðàòü"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: Íå ìîãó íàéòè áóôåð \"%s\""
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: Áóôåð \"%s\" íå íàõîäèòñÿ â ðåæèìå îòëè÷èé"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr "E787: Áóôåð íåîæèäàííî èçìåíèëñÿ"
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: Ýêðàíèðóþùèé ñèìâîë Escape íåëüçÿ èñïîëüçîâàòü â äèãðàôå"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: Ôàéë ñ ðàñêëàäêîé êëàâèàòóðû íå íàéäåí"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: Êîìàíäà :loadkeymap ïðèìåíåíà âíå ôàéëà ñöåíàðèÿ"
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr "E791: ïóñòàÿ çàïèñü ðàñêëàäêè êëàâèàòóðû"
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " Àâòîäîïîëíåíèå êëþ÷åâîãî ñëîâà (^N^P)"
-
-#. 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)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " Àâòîäîïîëíåíèå öåëîé ñòðîêè (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " Àâòîäîïîëíåíèå èìåíè ôàéëà (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " Àâòîäîïîëíåíèå ìåòêè (^]^N^P)"
-
-#: ../edit.c:88
-msgid " Path pattern completion (^N^P)"
-msgstr " Àâòîäîïîëíåíèå øàáëîíà ïóòè (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " Àâòîäîïîëíåíèå îïðåäåëåíèÿ (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Àâòîäîïîëíåíèå ïî ñëîâàðþ (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " Àâòîäîïîëíåíèå ñèíîíèìîâ (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " Àâòîäîïîëíåíèå êîìàíäíîé ñòðîêè (^V^N^P)"
-
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr " Ïîëüçîâàòåëüñêîå àâòîäîïîëíåíèå (^U^N^P)"
-
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " Omni-äîïîëíåíèå (^O^N^P)"
-
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Ïðåäëîæåíèå èñïðàâëåíèÿ ïðàâîïèñàíèÿ (s^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " Ìåñòíîå àâòîäîïîëíåíèå êëþ÷åâîãî ñëîâà (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "Êîíåö àáçàöà"
-
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr "E839: Ôóíêöèÿ àâòîäîïîëíåíèÿ èçìåíèëà îêíî"
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr "E840: Ôóíêöèÿ àâòîäîïîëíåíèÿ óäàëèëà òåêñò"
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "Íå çàäàíî çíà÷åíèå îïöèè 'dictionary'"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "Íå çàäàíî çíà÷åíèå îïöèè 'thesaurus'"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "Ïðîñìîòð ñëîâàðÿ: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (âñòàâêà) Ïðîêðóòêà (^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (çàìåíà) Ïðîêðóòêà (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "Ïðîñìîòð: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "Âûïîëíÿåòñÿ ïîèñê ñðåäè ìåòîê."
-
-#: ../edit.c:4519
-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.
-#.
-#: ../edit.c:4562
-msgid "-- Searching..."
-msgstr "-- Ïîèñê..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "Èñõîäíîå ñëîâî"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "Ñëîâî èç äðóãîé ñòðîêè"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "Åäèíñòâåííîå ñîîòâåòñòâèå"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "ñîîòâåòñòâèå %d èç %d"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "ñîîòâåòñòâèå %d"
-
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: Íåîæèäàííûå ñèìâîëû â :let"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: Èíäåêñ ñïèñêà çà ïðåäåëàìè äèàïàçîíà: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Íåîïðåäåë¸ííàÿ ïåðåìåííàÿ: %s"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: Ïðîïóùåíà ']'"
-
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: Ïàðàìåòð %s äîëæåí áûòü ñïèñêîì"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Ïàðàìåòð %s äîëæåí áûòü ñïèñêîì èëè ñëîâàð¸ì"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Íåâîçìîæíî èñïîëüçîâàòü ïóñòîé êëþ÷ äëÿ ñëîâàðÿ"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: Òðåáóåòñÿ ñïèñîê"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Òðåáóåòñÿ ñëîâàðü"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: Ñëèøêîì ìíîãî ïàðàìåòðîâ äëÿ ôóíêöèè %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Íåò êëþ÷à â ñëîâàðå: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: Ôóíêöèÿ %s óæå ñóùåñòâóåò. Äîáàâüòå !, ÷òîáû çàìåíèòü å¸."
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Çàïèñü óæå ñóùåñòâóåò â ñëîâàðå"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Òðåáóåòñÿ ññûëêà íà ôóíêöèþ"
-
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: Íåâîçìîæíî èñïîëüçîâàòü [:] ñî ñëîâàð¸ì"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: Íåïðàâèëüíûé òèï ïåðåìåííîé äëÿ %s="
-
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Íåèçâåñòíàÿ ôóíêöèÿ: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: Íåäîïóñòèìîå èìÿ ïåðåìåííîé: %s"
-
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: Èñïîëüçîâàíèå ÷èñëà ñ ïëàâàþùåé òî÷êîé êàê ñòðîêè"
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: Öåëåé ìåíüøå ÷åì ýëåìåíòîâ ñïèñêà"
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: Öåëåé áîëüøå ÷åì ýëåìåíòîâ ñïèñêà"
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "Äâîéíàÿ ; â ñïèñêå ïåðåìåííûõ"
-
-#: ../eval.c:2078
-#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: Íåâîçìîæíî îòîáðàçèòü ïåðåìåííûå äëÿ %s"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: Èíäåêñèðîâàíèå âîçìîæíî òîëüêî ñïèñêà èëè ñëîâàðÿ"
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:] äîëæíî áûòü ïîñëåäíèì"
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:] òðåáóåò çíà÷åíèåì ñïèñîê"
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: Ýëåìåíòîâ ñïèñêà-çíà÷åíèÿ áîëüøå ÷åì â öåëè"
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: Ñïèñîê-çíà÷åíèå íå ñîäåðæèò äîñòàòî÷íî ýëåìåíòîâ"
-
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: Ïðîïóùåíî \"in\" ïîñëå :for"
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Ïðîïóùåíû ñêîáêè: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: Íåò òàêîé ïåðåìåííîé: \"%s\""
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: Ñëèøêîì ãëóáîêî âëîæåííûå ïåðåìåííûå äëÿ (ðàç)áëîêèðîâêè"
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: Ïðîïóùåíî ':' ïîñëå '?'"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: Ñïèñîê ìîæíî ñðàâíèâàòü òîëüêî ñî ñïèñêîì"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: Íåäîïóñòèìàÿ îïåðàöèÿ äëÿ ñïèñêîâ"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: Ñëîâàðü ìîæíî ñðàâíèâàòü òîëüêî ñî ñëîâàð¸ì"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: Íåäîïóñòèìàÿ îïåðàöèÿ äëÿ ñëîâàðÿ"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Ññûëêó íà ôóíêöèþ ìîæíî ñðàâíèâàòü òîëüêî ñ ññûëêîé íà ôóíêöèþ"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: Íåäîïóñòèìàÿ îïåðàöèÿ äëÿ ññûëêè íà ôóíêöèþ"
-
-#: ../eval.c:4277
-msgid "E804: Cannot use '%' with Float"
-msgstr "E804: Íåâîçìîæíî èñïîëüçîâàòü '%' ñ ÷èñëîì ñ ïëàâàþùåé òî÷êîé"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: Ïðîïóùåíà ')'"
-
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: Íåâîçìîæíî èíäåêñèðîâàòü ññûëêó íà ôóíêöèþ"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: Íå óêàçàíî èìÿ îïöèè: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: Íåèçâåñòíàÿ îïöèÿ: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: Ïðîïóùåíà êàâû÷êà: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: Ïðîïóùåíà êàâû÷êà: %s"
-
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Ïðîïóùåíà çàïÿòàÿ â ñïèñêå: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: Ïðîïóùåíî îêîí÷àíèå ñïèñêà ']': %s"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Ïðîïóùåíî äâîåòî÷èå â ñëîâàðå: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Ïîâòîð êëþ÷à â ñëîâàðå: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Ïðîïóùåíà çàïÿòàÿ â ñëîâàðå: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Ïðîïóùåíî îêîí÷àíèå ñëîâàðÿ '}': %s"
-
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: Ñëèøêîì ãëóáîêî âëîæåííûå ïåðåìåííûå äëÿ îòîáðàæåíèÿ"
-
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: Ñëèøêîì ìíîãî ïàðàìåòðîâ äëÿ ôóíêöèè %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Ïàðàìåòðû äëÿ ôóíêöèè %s çàäàíû íåâåðíî"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Íåèçâåñòíàÿ ôóíêöèÿ: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Íåäîñòàòî÷íî ïàðàìåòðîâ äëÿ ôóíêöèè %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> èñïîëüçóåòñÿ âíå ñöåíàðèÿ: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Âûçîâ ôóíêöèè dict áåç ñëîâàðÿ: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Òðåáóåòñÿ öåëîå ÷èñëî èëè ñ ïëàâàþùåé òî÷êîé"
-
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "ïàðàìåòðà add()"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: Ñëèøêîì ìíîãî ïàðàìåòðîâ"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() ìîæåò èñïîëüçîâàòüñÿ òîëüêî â ðåæèìå Âñòàâêè"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&Ok"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Êëþ÷ óæå ñóùåñòâóåò: %s"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "ïàðàìåòðà extend()"
-
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "ïàðàìåòðà map()"
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "ïàðàìåòðà filter()"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld ñòðîê: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: Íåèçâåñòíàÿ ôóíêöèÿ: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "Ôóíêöèÿ inputrestore() âûçûâàåòñÿ ÷àùå, ÷åì ôóíêöèÿ inputsave()"
-
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "ïàðàìåòðà insert()"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: Äèàïàçîí íå äîïóñêàåòñÿ"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: Íåïðàâèëüíûå òèï äëÿ len()"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: Íóëåâîé øàã"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: Íà÷àëî ïîñëå êîíöà"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<ïóñòî>"
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "ïàðàìåòðà remove()"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: Ñëèøêîì ìíîãî ñèìâîëè÷åñêèõ ññûëîê (öèêë?)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "ïàðàìåòðà reverse()"
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "ïàðàìåòðà sort()"
-
-#: ../eval.c:13721
-msgid "uniq() argument"
-msgstr "ïàðàìåòðà uniq()"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Íåóäà÷íîå çàâåðøåíèå ôóíêöèè ñðàâíåíèÿ ïðè ñîðòèðîâêå"
-
-#: ../eval.c:13806
-msgid "E882: Uniq compare function failed"
-msgstr ""
-"E882: Íåóäà÷íîå çàâåðøåíèå ôóíêöèè ñðàâíåíèÿ ïðè ïðîâåðêå åäèíñòâåííîñòè"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(Íåïðàâèëüíî)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Îøèáêà çàïèñè âî âðåìåííûé ôàéë"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Èñïîëüçîâàíèå ÷èñëà ñ ïëàâàþùåé òî÷êîé êàê öåëîãî"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Èñïîëüçîâàíèå ññûëêè íà ôóíêöèþ êàê ÷èñëà"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: Èñïîëüçîâàíèå ñïèñêà êàê ÷èñëà"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Èñïîëüçîâàíèå ñëîâàðÿ êàê ÷èñëà"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: Èñïîëüçîâàíèå ññûëêè íà ôóíêöèþ êàê ñòðîêè"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: Èñïîëüçîâàíèå ñïèñêà êàê ñòðîêè"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Èñïîëüçîâàíèå ñëîâàðÿ êàê ñòðîêè"
-
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Íåñîîòâåòñòâèå òèïà ïåðåìåííîé äëÿ: %s"
-
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Íåâîçìîæíî óäàëèòü ïåðåìåííóþ %s"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr ""
-"E704: Èìÿ ïåðåìåííîé ññûëêè íà ôóíêöèþ äîëæíî íà÷èíàòüñÿ ñ çàãëàâíîé áóêâû: "
-"%s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: Èìÿ ïåðåìåííîé êîíôëèêòóåò ñ ñóùåñòâóþùåé ôóíêöèåé: %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: Çíà÷åíèå %s çàáëîêèðîâàíî"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Íåèçâåñòíî"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Íåâîçìîæíî èçìåíèòü çíà÷åíèå %s"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: Ñëèøêîì ãëóáîêî âëîæåííûå ïåðåìåííûå äëÿ êîïèðîâàíèÿ"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Íåîïðåäåë¸ííàÿ ôóíêöèÿ: %s"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: Ïðîïóùåíà '(': %s"
-
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: Çäåñü íåâîçìîæíî èñïîëüçîâàòü g:"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Íåäîïóñòèìûé ïàðàìåòð: %s"
-
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Ïîâòîðÿþùååñÿ èìÿ ïàðàìåòðà: %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: Ïðîïóùåíà êîìàíäà :endfunction"
-
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Èìÿ ôóíêöèè êîíôëèêòóåò ñ ïåðåìåííîé: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Íåâîçìîæíî ïåðåîïðåäåëèòü ôóíêöèþ %s, îíà èñïîëüçóåòñÿ"
-
-#: ../eval.c:17604
-#, 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.c:17824
-#, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: Èìÿ ôóíêöèè äîëæíî íà÷èíàòüñÿ ñ çàãëàâíîé áóêâû èëè \"s:\": %s"
-
-#: ../eval.c:17833
-#, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E884: Èìÿ ôóíêöèè íå ìîæåò ñîäåðæàòü äâîåòî÷èå: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Íåâîçìîæíî óäàëèòü ôóíêöèþ %s, îíà èñïîëüçóåòñÿ"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Ãëóáèíà âûçîâà ôóíêöèè áîëüøå, ÷åì çíà÷åíèå 'maxfuncdepth'"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "âûçîâ %s"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ïðåðâàíà"
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s âîçâðàùàåò #%<PRId64>"
-
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%s âîçâðàùàåò %s"
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "ïðîäîëæåíèå â %s"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: êîìàíäà :return âíå ôóíêöèè"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# ãëîáàëüíûå ïåðåìåííûå:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\t ïîñëåäíèé ðàç îïöèÿ èçìåíåíà â "
-
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Íåò ñòàðûõ ôàéëîâ"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, Hex %02x, Octal %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, Hex %04x, Octal %o"
-
-#: ../ex_cmds.c:146
-#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, Hex %08x, Octal %o"
-
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: Ñòðîêè ïåðåìåùàþòñÿ ñàìè íà ñåáÿ"
-
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "Ïåðåìåùåíà îäíà ñòðîêà"
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "Ïåðåìåùåíî ñòðîê: %<PRId64>"
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "Ïðîïóùåíî ÷åðåç ôèëüòð ñòðîê: %<PRId64>"
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: Àâòîêîìàíäû *Filter* íå äîëæíû èçìåíÿòü àêòèâíûé áóôåð"
-
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[Èçìåíåíèÿ íå ñîõðàíåíû]\n"
-
-#: ../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
-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
-#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "Çàïèñü ôàéëà viminfo \"%s\""
-
-#, c-format
-msgid "E886: Can't rename viminfo file to %s!"
-msgstr "E886: Íåâîçìîæíî ïåðåèìåíîâàòü ôàéë viminfo â %s!"
-
-#. Write the info:
-#: ../ex_cmds.c:1720
-#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# Ýòîò ôàéë viminfo àâòîìàòè÷åñêè ñîçäàí Vim %s.\n"
-
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# Åãî ìîæíî (îñòîðîæíî!) ðåäàêòèðîâàòü.\n"
-"\n"
-
-#: ../ex_cmds.c:1723
-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
-msgid "Write partial file?"
-msgstr "Çàïèñàòü ôàéë ÷àñòè÷íî?"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: Äëÿ çàïèñè ÷àñòè áóôåðà èñïîëüçóéòå !"
-
-#: ../ex_cmds.c:2281
-#, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "Ïåðåçàïèñàòü ñóùåñòâóþùèé ôàéë \"%s\"?"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr "Ñâîï-ôàéë \"%s\" ñóùåñòâóåò, ïåðåçàïèñàòü?"
-
-#: ../ex_cmds.c:2326
-#, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E768: Ñâîï-ôàéë ñóùåñòâóåò: %s (:silent! ÷òîáû îáîéòè ïðîâåðêó)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Áóôåð %<PRId64> íå ñâÿçàí ñ èìåíåì ôàéëà"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: Ôàéë íå ñîõðàí¸í: çàïèñü îòêëþ÷åíà îïöèåé 'write'"
-
-#: ../ex_cmds.c:2434
-#, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"Äëÿ \"%s\" âêëþ÷åíà îïöèÿ 'readonly'.\n"
-"Çàïèñàòü?"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-"Ôàéë \"%s\" èìååò ðåæèì äîñòóïà òîëüêî äëÿ ÷òåíèÿ.\n"
-"Íî, âîçìîæíî, ôàéë óäàñòñÿ çàïèñàòü.\n"
-"Õîòèòå ïîïðîáîâàòü?"
-
-#: ../ex_cmds.c:2451
-#, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr ""
-"E505: \"%s\" îòêðûò òîëüêî äëÿ ÷òåíèÿ (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: Àâòîêîìàíäû íåîæèäàííî óáèëè íîâûé áóôåð %s"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: Ïàðàìåòð êîìàíäû :z äîëæåí áûòü ÷èñëîì"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: Èñïîëüçîâàíèå êîìàíä îáîëî÷êè íå äîïóñêàåòñÿ â rvim."
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: Ðåãóëÿðíûå âûðàæåíèÿ íå ìîãóò ðàçäåëÿòüñÿ áóêâàìè"
-
-#: ../ex_cmds.c:3964
-#, 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
-msgid "(Interrupted) "
-msgstr "(Ïðåðâàíî)"
-
-#: ../ex_cmds.c:4384
-msgid "1 match"
-msgstr "Îäíî ñîîòâåòñòâèå"
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "Îäíà çàìåíà"
-
-#: ../ex_cmds.c:4387
-#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> ñîîòâåòñòâèé"
-
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> çàìåí"
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr " â îäíîé ñòðîêå"
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr " â %<PRId64> ñòð."
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: Êîìàíäà :global íå ìîæåò áûòü ðåêóðñèâíîé"
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: Â êîìàíäå :global ïðîïóùåíî ðåãóëÿðíîå âûðàæåíèå"
-
-#: ../ex_cmds.c:4508
-#, c-format
-msgid "Pattern found in every line: %s"
-msgstr "Ñîîòâåòñòâèå øàáëîíó íàéäåíî íà êàæäîé ñòðîêå: %s"
-
-#: ../ex_cmds.c:4510
-#, c-format
-msgid "Pattern not found: %s"
-msgstr "Øàáëîí íå íàéäåí: %s"
-
-#: ../ex_cmds.c:4587
-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: Ïîâòîðÿþùàÿñÿ ìåòêà \"%s\" â ôàéëå %s/%s"
-
-#: ../ex_cmds.c:5687
-#, c-format
-msgid "E160: Unknown sign command: %s"
-msgstr "E160: Íåèçâåñòíàÿ êîìàíäà çíà÷êà %s"
-
-#: ../ex_cmds.c:5704
-msgid "E156: Missing sign name"
-msgstr "E156: Ïðîïóùåíî èìÿ çíà÷êà"
-
-#: ../ex_cmds.c:5746
-msgid "E612: Too many signs defined"
-msgstr "E612: Îïðåäåëåíî ñëèøêîì ìíîãî çíà÷êîâ"
-
-#: ../ex_cmds.c:5813
-#, c-format
-msgid "E239: Invalid sign text: %s"
-msgstr "E239: Íåïðàâèëüíûé òåêñò çíà÷êà: %s"
-
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
-#, c-format
-msgid "E155: Unknown sign: %s"
-msgstr "E155: Íåèçâåñòíûé çíà÷îê: %s"
-
-#: ../ex_cmds.c:5877
-msgid "E159: Missing sign number"
-msgstr "E159: Ïðîïóùåí íîìåð çíà÷êà"
-
-#: ../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: Íåïðàâèëüíûé ID çíà÷êà: %<PRId64>"
-
-#, c-format
-msgid "E885: Not possible to change sign %s"
-msgstr "E885: Íåâîçìîæíî èçìåíèòü çíà÷îê %s"
-
-#: ../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"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Òî÷êà îñòàíîâêè â \"%s%s\" ñòð. %<PRId64>"
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: Òî÷êà îñòàíîâêè íå íàéäåíà: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "Òî÷êè îñòàíîâêè íå îïðåäåëåíû"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s ñòð. %<PRId64>"
-
-#: ../ex_cmds2.c:942
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: Ïåðâîå èñïîëüçîâàíèå \":profile start {èìÿ-ôàéëà}\""
-
-#: ../ex_cmds2.c:1269
-#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "Ñîõðàíèòü èçìåíåíèÿ â \"%s\"?"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "Áåç èìåíè"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: Íåñîõðàí¸ííûå èçìåíåíèÿ â áóôåðå \"%s\""
-
-#: ../ex_cmds2.c:1480
-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
-#, 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 "ðåæèìíàÿ ñòðîêà"
-
-#: ../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_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: Êîìàíäà :scriptencoding èñïîëüçóåòñÿ âíå ôàéëà ñöåíàðèÿ"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: Êîìàíäà :finish èñïîëüçóåòñÿ âíå ôàéëà ñöåíàðèÿ"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "Àêòèâíûé %sÿçûê: \"%s\""
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: Íåâîçìîæíî ñìåíèòü ÿçûê íà \"%s\""
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "Ïåðåõîä â ðåæèì Ex. Äëÿ ïåðåõîäà â Îáû÷íûé ðåæèì íàáåðèòå \"visual\""
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: Â êîíöå ôàéëà"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: Ñëèøêîì ðåêóðñèâíàÿ êîìàíäà"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: Èñêëþ÷èòåëüíàÿ ñèòóàöèÿ íå îáðàáîòàíà: %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "Êîíåö ñ÷èòàííîãî ôàéëà"
-
-#: ../ex_docmd.c:1086
-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:1729
-msgid "E493: Backwards range given"
-msgstr "E493: Çàäàí îáðàòíûé äèàïàçîí"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "Çàäàí îáðàòíûé äèàïàçîí, ìåíÿåì ãðàíèöû ìåñòàìè"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: Èñïîëüçóéòå w èëè w>>"
-
-#: ../ex_docmd.c:3454
-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
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr ""
-"E841: Çàðåçåðâèðîâàííîå èìÿ íå ìîæåò èñïîëüçîâàòüñÿ äëÿ êîìàíä ïîëüçîâàòåëÿ"
-
-#: ../ex_docmd.c:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: Íåò òàêîé êîìàíäû ïîëüçîâàòåëÿ: %s"
-
-#: ../ex_docmd.c:5219
-#, 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: Ïàðàìåòð àâòîäîïîëíåíèÿ ìîæíî èñïîëüçîâàòü òîëüêî ñ îñîáûì äîïîëíåíèåì"
-
-#: ../ex_docmd.c:5231
-msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Îñîáîå äîïîëíåíèå òðåáóåò óêàçàíèÿ ïàðàìåòðà ôóíêöèè"
-
-#: ../ex_docmd.c:5257
-#, c-format
-msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Íåâîçìîæíî íàéòè öâåòîâóþ ñõåìó '%s'"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "Ïðèâåòñòâóåì âàñ, ïîëüçîâàòåëü Vim!"
-
-#: ../ex_docmd.c:5431
-msgid "E784: Cannot close last tab page"
-msgstr "E784: Íåëüçÿ çàêðûòü ïîñëåäíþþ âêëàäêó"
-
-#: ../ex_docmd.c:5462
-msgid "Already only one tab page"
-msgstr "Íà ýêðàíå âñåãî îäíà âêëàäêà"
-
-#: ../ex_docmd.c:6004
-#, c-format
-msgid "Tab page %d"
-msgstr "Âêëàäêà %d"
-
-#: ../ex_docmd.c:6295
-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
-msgid "E186: No previous directory"
-msgstr "E186: Íåò ïðåäûäóùåãî êàòàëîãà"
-
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: Íåèçâåñòíî"
-
-#: ../ex_docmd.c:6610
-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
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: \"%s\" ñóùåñòâóåò (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
-
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: Íåâîçìîæíî îòêðûòü äëÿ çàïèñè \"%s\""
-
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: Ïàðàìåòð äîëæåí áûòü ïðÿìîé/îáðàòíîé êàâû÷êîé èëè áóêâîé"
-
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: Ñëèøêîì ãëóáîêàÿ ðåêóðñèÿ ïðè èñïîëüçîâàíèè êîìàíäû :normal"
-
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: Íåò ñîñåäíåãî èìåíè ôàéëà äëÿ çàìåíû '#'"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: Íåò àâòîêîìàíäíîãî èìåíè ôàéëà äëÿ çàìåíû \"<afile>\""
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: Íåò àâòîêîìàíäíîãî íîìåðà áóôåðà äëÿ çàìåíû \"<abuf>\""
-
-#: ../ex_docmd.c:7861
-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: Íåò èìåíè ôàéëà :source äëÿ çàìåíû \"<sfile>\""
-
-#: ../ex_docmd.c:7876
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E842: Íåò íîìåðà ñòðîêè äëÿ èñïîëüçîâàíèÿ \"<slnum>\""
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: Ïóñòîå èìÿ ôàéëà äëÿ '%' èëè '#', âîçìîæíî òîëüêî c \":p:h\""
-
-#: ../ex_docmd.c:7905
-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_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr ""
-"E608: Íåâîçìîæíî âûïîëíèòü êîìàíäó :throw äëÿ èñêëþ÷åíèé ñ ïðèñòàâêîé 'Vim'"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "Èñêëþ÷èòåëüíàÿ ñèòóàöèÿ: %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "Çàâåðøåíà îáðàáîòêà èñêëþ÷èòåëüíîé ñèòóàöèè: %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "Èñêëþ÷èòåëüíàÿ ñèòóàöèÿ ïðîèãíîðèðîâàíà: %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, ñòðîêà %<PRId64>"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "Îáðàáîòêà èñêëþ÷èòåëüíîé ñèòóàöèè: %s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr "%s âûïîëíÿåò îæèäàíèå"
-
-#: ../ex_eval.c:679
-#, c-format
-msgid "%s resumed"
-msgstr "%s âîçîáíîâëåíî"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr "%s ïðîïóùåíî"
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "Èñêëþ÷èòåëüíàÿ ñèòóàöèÿ"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "Îøèáêà è ïðåðûâàíèå"
-
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "Îøèáêà"
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "Ïðåðûâàíèå"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: Ñëèøêîì ãëóáîêî âëîæåííûé :if"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :endif áåç :if"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :else áåç :if"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :elseif áåç :if"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: Îáíàðóæåíî íåñêîëüêî :else"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :elseif ïîñëå :else"
-
-#: ../ex_eval.c:941
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: Ñëèøêîì ãëóáîêîå âëîæåíèå :while èëè :for"
-
-#: ../ex_eval.c:1028
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :continue áåç :while èëè :for"
-
-#: ../ex_eval.c:1061
-msgid "E587: :break without :while or :for"
-msgstr "E587: :break áåç :while èëè :for"
-
-#: ../ex_eval.c:1102
-msgid "E732: Using :endfor with :while"
-msgstr "E732: Èñïîëüçîâàíèå :endfor ñ :while"
-
-#: ../ex_eval.c:1104
-msgid "E733: Using :endwhile with :for"
-msgstr "E733: Èñïîëüçîâàíèå :endwhile ñ :for"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: Ñëèøêîì ãëóáîêî âëîæåííûé :try"
-
-#: ../ex_eval.c:1317
-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
-msgid "E604: :catch after :finally"
-msgstr "E604: :catch áåç :finally"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :finally áåç :try"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: Îáíàðóæåíî íåñêîëüêî :finally"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :endtry áåç :try"
-
-#: ../ex_eval.c:2026
-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
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E811: Ñåé÷àñ íå äîïóñêàåòñÿ èçìåíåíèå èíôîðìàöèè î áóôåðå"
-
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "èìÿ ìåòêè"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " òèï ôàéëà\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "çíà÷åíèå îïöèè 'history' ðàâíî íóëþ"
-
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s, èñòîðèÿ (íà÷èíàÿ îò ñâåæåãî ê ñòàðîìó):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "Êîìàíäíàÿ ñòðîêà"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "Ñòðîêà ïîèñêà"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "Âûðàæåíèå"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "Ñòðîêà ââîäà"
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar áîëüøå äëèíû êîìàíäû"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: Óäàëåíî àêòèâíîå îêíî èëè áóôåð"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: ñëèøêîì áîëüøîé ïóòü äëÿ àâòîäîïîëíåíèÿ"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Íåïðàâèëüíî çàäàí ïóòü: '**[÷èñëî]' äîëæíî áûòü ëèáî â êîíöå ïóòè, "
-"ëèáî çà íèì äîëæíî ñëåäîâàòü '%s'"
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Êàòàëîã \"%s\" íå íàéäåí â ïóòè äëÿ ñìåíû êàòàëîãà"
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Ôàéë \"%s\" â èçâåñòíûõ êàòàëîãàõ íå íàéäåí"
-
-msgid "List or number required"
-msgstr "Òðåáóåòñÿ ñïèñîê èëè ÷èñëî"
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Â ïóòè ñìåíû êàòàëîãà áîëüøå íåò êàòàëîãîâ \"%s\""
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Â èçâåñòíûõ êàòàëîãàõ áîëüøå íåò ôàéëîâ \"%s\""
-
-#: ../fileio.c:137
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E812: Àâòîêîìàíäû èçìåíèëè áóôåð èëè èìÿ áóôåðà"
-
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "Íåäîïóñòèìîå èìÿ ôàéëà"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "ÿâëÿåòñÿ êàòàëîãîì"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "íå ÿâëÿåòñÿ ôàéëîì"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[Íîâûé ôàéë]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr "[Íîâûé ÊÀÒÀËÎÃ]"
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr "[Ôàéë ñëèøêîì áîëüøîé]"
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[Äîñòóï çàïðåù¸í]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200:  ðåçóëüòàòå âûïîëíåíèÿ àâòîêîìàíä *ReadPre ôàéë ñòàë íå÷èòàåìûì"
-
-#: ../fileio.c:655
-msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: Àâòîêîìàíäû *ReadPre íå äîëæíû èçìåíÿòü àêòèâíûé áóôåð"
-
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: ×òåíèå èç ñòàíäàðòíîãî ïîòîêà ââîäà stdin...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202:  ðåçóëüòàòå ïðåîáðàçîâàíèÿ ôàéë ñòàë íå÷èòàåìûì!"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[fifo/ãíåçäî]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[fifo]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[ãíåçäî]"
-
-#. or character special
-#: ../fileio.c:1801
-msgid "[character special]"
-msgstr "[ñïåöèàëüíûé ñèìâîëüíûé]"
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[ïðîïóùåíû ñèìâîëû CR]"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[äëèííûå ñòðîêè ðàçáèòû]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[ÁÅÇ ïðåîáðàçîâàíèé]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[ïåðåêîäèðîâàíî]"
-
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[ÎØÈÁÊÀ ÏÐÅÎÁÐÀÇÎÂÀÍÈß â ñòðîêå %<PRId64>]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[ÍÅÄÎÏÓÑÒÈÌÛÉ ÁÀÉÒ â ñòðîêå %<PRId64>]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[ÎØÈÁÊÈ ×ÒÅÍÈß]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "Âðåìåííûé ôàéë äëÿ ïåðåêîäèðîâàíèÿ íå íàéäåí"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "Ïðåîáðàçîâàíèå ñ ïîìîùüþ 'charconvert' íå âûïîëíåíî"
-
-#: ../fileio.c:2113
-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:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr ""
-"E203: Áóôåð, êîòîðûé òðåáîâàëîñü çàïèñàòü, óäàë¸í èëè âûãðóæåí àâòîêîìàíäîé"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: Êîëè÷åñòâî ñòðîê èçìåíåíî àâòîêîìàíäîé íåîæèäàííûì îáðàçîì"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "íå ÿâëÿåòñÿ ôàéëîì èëè óñòðîéñòâîì, äîñòóïíûì äëÿ çàïèñè"
-
-#: ../fileio.c:2601
-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:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr ""
-"E509: Íåâîçìîæíî ñîçäàòü ðåçåðâíûé ôàéë (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr ""
-"E510: Íåâîçìîæíî ñîçäàòü ðåçåðâíûé ôàéë (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: Âðåìåííûé ôàéë äëÿ çàïèñè íå íàéäåí"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr ""
-"E213: Ïåðåêîäèðîâêà íåâîçìîæíà (äîáàâüòå ! äëÿ çàïèñè áåç ïåðåêîäèðîâêè)"
-
-#: ../fileio.c:3169
-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: Íå óäàëîñü âûïîëíèòü ôóíêöèþ fsync()"
-
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Îïåðàöèÿ çàêðûòèÿ íå óäàëàñü"
-
-#: ../fileio.c:3436
-msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr ""
-"E513: Îøèáêà çàïèñè, ïðåîáðàçîâàíèå íå óäàëîñü (î÷èñòèòå 'fenc', ÷òîáû "
-"îáîéòè)"
-
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: Îøèáêà çàïèñè, ïðåîáðàçîâàíèå íå óäàëîñü íà ñòðîêå %<PRId64> (î÷èñòèòå "
-"'fenc', ÷òîáû îáîéòè)"
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: Îøèáêà çàïèñè (íåò ñâîáîäíîãî ìåñòà?)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr " ÎØÈÁÊÀ ÏÐÅÎÁÐÀÇÎÂÀÍÈß"
-
-#: ../fileio.c:3509
-#, c-format
-msgid " in line %<PRId64>;"
-msgstr " íà ñòðîêå %<PRId64>;"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[Óñòðîéñòâî]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[Íîâûé]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr " [ä]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " äîáàâëåíî"
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr " [ç]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " çàïèñàíî"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Ðåæèì çàïëàòêè: íåâîçìîæíî ñîõðàíåíèå èñõîäíîãî ôàéëà"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr ""
-"E206: Ðåæèì çàïëàòêè: íåâîçìîæíî ñìåíèòü ïàðàìåòðû ïóñòîãî èñõîäíîãî ôàéëà"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: Íåâîçìîæíî óäàëèòü ðåçåðâíûé ôàéë"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"ÏÐÅÄÓÏÐÅÆÄÅÍÈÅ: Èñõîäíûé ôàéë ìîæåò áûòü óòðà÷åí èëè ïîâðåæä¸í\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "íå âûõîäèòå èç ðåäàêòîðà, ïîêà ôàéë íå áóäåò óñïåøíî çàïèñàí!"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[ôîðìàò dos]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[ôîðìàò mac]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[ôîðìàò unix]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 ñòðîêà, "
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "ñòðîê: %<PRId64>, "
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 ñèìâîë"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "ñèìâîëîâ: %<PRId64>"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-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
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "ÏÐÅÄÓÏÐÅÆÄÅÍÈÅ: Ôàéë èçìåí¸í ñ ìîìåíòà ÷òåíèÿ!!!"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "Ñåðü¸çíî õîòèòå çàïèñàòü â ýòîò ôàéë"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: Îøèáêà çàïèñè â \"%s\""
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: Îøèáêà çàêðûòèÿ \"%s\""
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: Îøèáêà ÷òåíèÿ \"%s\""
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: Áóôåð óäàë¸í ïðè âûïîëíåíèè àâòîêîìàíäû FileChangedShell"
-
-#: ../fileio.c:4894
-#, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Ôàéë \"%s\" áîëüøå íå äîñòóïåí"
-
-#: ../fileio.c:4906
-#, 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
-msgid "See \":help W12\" for more info."
-msgstr "Ñì. \":help W12\" äëÿ äîïîëíèòåëüíîé èíôîðìàöèè."
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr ""
-"W11: Ïðåäóïðåæäåíèå: ôàéë \"%s\" áûë èçìåí¸í ïîñëå íà÷àëà ðåäàêòèðîâàíèÿ"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "Ñì. \":help W11\" äëÿ äîïîëíèòåëüíîé èíôîðìàöèè."
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr ""
-"W16: Ïðåäóïðåæäåíèå: ðåæèì äîñòóïà ê ôàéëó \"%s\" áûë èçìåí¸í ïîñëå íà÷àëà "
-"ðåäàêòèðîâàíèÿ"
-
-#: ../fileio.c:4915
-msgid "See \":help W16\" for more info."
-msgstr "Ñì. \":help W16\" äëÿ äîïîëíèòåëüíîé èíôîðìàöèè."
-
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr ""
-"W13: Ïðåäóïðåæäåíèå: ôàéë \"%s\" áûë ñîçäàí ïîñëå íà÷àëà ðåäàêòèðîâàíèÿ"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "Ïðåäóïðåæäåíèå"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"&OK\n"
-"&L Çàãðóçèòü ôàéë"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: Íåâîçìîæíî ïîäãîòîâèòüñÿ ê ïåðåçàãðóçêå \"%s\""
-
-#: ../fileio.c:5078
-#, 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 <áóôôåð=%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"
-"--- Auto-Commands ---"
-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 Auto commands 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
-msgid "E219: Missing {."
-msgstr "E219: Ïðîïóùåíà {."
-
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: Ïðîïóùåíà }."
-
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: Ñêëàäîê íå îáíàðóæåíî"
-
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr ""
-"E350: Ñêëàäêà íå ìîæåò áûòü ñîçäàíà ñ òåêóùèì çíà÷åíèåì îïöèè 'foldmethod'"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr ""
-"E351: Ñêëàäêà íå ìîæåò áûòü óäàëåíà ñ òåêóùèì çíà÷åíèåì îïöèè 'foldmethod'"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--%3ld ñòðîê â ñêëàäêå"
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: Äîáàâëåíèå â áóôåð ÷òåíèÿ"
-
-#: ../getchar.c:2040
-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
-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
-msgid "E470: Command aborted"
-msgstr "E470: Âûïîëíåíèå êîìàíäû ïðåðâàíî"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: Òðåáóåòñÿ óêàçàòü ïàðàìåòð"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: Ïîñëå \\ äîëæåí èäòè ñèìâîë /, ? èëè &"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr ""
-"E11: Íåäîïóñòèìî â îêíå êîìàíäíîé ñòðîêè; <CR> âûïîëíåíèå, CTRL-C âûõîä"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: Êîìàíäà íå äîïóñêàåòñÿ â exrc/vimrc â òåêóùåì êàòàëîãå èëè ïîèñêå ìåòîê"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: Îòñóòñòâóåò êîìàíäà :endif"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: Îòñóòñòâóåò êîìàíäà :endtry"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: Îòñóòñòâóåò êîìàíäà :endwhile"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: Îòñóòñòâóåò êîìàíäà :endfor"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: Êîìàíäà :endwhile áåç ïàðíîé êîìàíäû :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor áåç :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Ôàéë ñóùåñòâóåò (äîáàâüòå !, ÷òîáû ïåðåçàïèñàòü)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: Íå óäàëîñü âûïîëíèòü êîìàíäó"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: Âíóòðåííÿÿ îøèáêà"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Ïðåðâàíî"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Íåäîïóñòèìûé àäðåñ"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Íåäîïóñòèìûé ïàðàìåòð"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Íåäîïóñòèìûé ïàðàìåòð: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Íåäîïóñòèìîå âûðàæåíèå: %s"
-
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Íåäîïóñòèìûé äèàïàçîí"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Íåäîïóñòèìàÿ êîìàíäà"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ÿâëÿåòñÿ êàòàëîãîì"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Íåäîïóñòèìûé ðàçìåð ïðîêðóòêè"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Íåóäà÷íûé âûçîâ ôóíêöèè \"%s()\" èç áèáëèîòåêè"
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: Îòìåòêà óêàçûâàåò íà íåïðàâèëüíûé íîìåð ñòðîêè"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Îòìåòêà íå îïðåäåëåíà"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Èçìåíåíèÿ íåâîçìîæíû, òàê êàê îòêëþ÷åíà îïöèÿ 'modifiable'"
-
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Ñëèøêîì ãëóáîêî âëîæåííûå ñöåíàðèè"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Ñîñåäíèé ôàéë íå ñóùåñòâóåò"
-
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Íåò òàêîãî ñîêðàùåíèÿ"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ! íå äîïóñêàåòñÿ"
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr ""
-"E25: Âîçìîæíîñòü èñïîëüçîâàíèÿ ãðàôè÷åñêîãî èíòåðôåéñà âûêëþ÷åíà ïðè "
-"êîìïèëÿöèè"
-
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Ãðóïïà ïîäñâåòêè ñèíòàêñèñà %s íå ñóùåñòâóåò"
-
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: Ïîêà íåò âñòàâëåííîãî òåêñòà"
-
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Ïðåäûäóùåé êîìàíäíîé ñòðîêè íåò"
-
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Òàêîé ïðèâÿçêè íå ñóùåñòâóåò"
-
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Íåò ñîîòâåòñòâèÿ"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Íåò ñîîòâåòñòâèÿ: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Íåò èìåíè ôàéëà"
-
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Íåò ïðåäûäóùåãî ðåãóëÿðíîãî âûðàæåíèÿ äëÿ çàìåíû"
-
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Íåò ïðåäûäóùåé êîìàíäû"
-
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Íåò ïðåäûäóùåãî ðåãóëÿðíîãî âûðàæåíèÿ"
-
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Èñïîëüçîâàíèå äèàïàçîíà íå äîïóñêàåòñÿ"
-
-#: ../globals.h:1048
-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
-msgid "E483: Can't get temp file name"
-msgstr "E483: Íåâîçìîæíî ïîëó÷èòü èìÿ âðåìåííîãî ôàéëà"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Íåâîçìîæíî îòêðûòü ôàéë %s"
-
-#: ../globals.h:1052
-#, 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
-msgid "E38: Null argument"
-msgstr "E38: Íóëåâîé ïàðàìåòð"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Òðåáóåòñÿ ÷èñëî"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Íå óäàëîñü îòêðûòü ôàéë îøèáîê %s"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Íå õâàòàåò ïàìÿòè!"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Øàáëîí íå íàéäåí"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Øàáëîí íå íàéäåí: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: Ïàðàìåòð äîëæåí áûòü ïîëîæèòåëüíûì ÷èñëîì"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Âîçâðàò â ïðåäûäóùèé êàòàëîã íåâîçìîæåí"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Íåò îøèáîê"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Íåò ñïèñêà ðàñïîëîæåíèé"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: Ïîâðåæäåíà ñòðîêà ñîîòâåòñòâèÿ"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: Ïðîãðàììà îáðàáîòêè ðåãóëÿðíûõ âûðàæåíèé ïîâðåæäåíà"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: Âêëþ÷åíà îïöèÿ 'readonly' (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Íåâîçìîæíî èçìåíèòü ïåðåìåííóþ òîëüêî äëÿ ÷òåíèÿ \"%s\""
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Íåâîçìîæíî èçìåíèòü ïåðåìåííóþ â ïåñî÷íèöå: \"%s\""
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Îøèáêà ïðè ÷òåíèè ôàéëà îøèáîê"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Íå äîïóñêàåòñÿ â ïåñî÷íèöå"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Çäåñü íå ðàçðåøåíî"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: Äàííûé ðåæèì ýêðàíà íå ïîääåðæèâàåòñÿ"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Íåäîïóñòèìûé ðàçìåð ïðîêðóòêè"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: Çíà÷åíèåì îïöèè 'shell' ÿâëÿåòñÿ ïóñòàÿ ñòðîêà"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Íåâîçìîæíî ïðî÷èòàòü äàííûå î çíà÷êàõ!"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: Îøèáêà çàêðûòèÿ ñâîï-ôàéëà"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: Ñòåê ìåòîê ïóñòîé"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Ñëèøêîì ñëîæíàÿ êîìàíäà"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Ñëèøêîì äëèííîå èìÿ"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: Ñëèøêîì ìíîãî ñèìâîëîâ ["
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: Ñëèøêîì ìíîãî èì¸í ôàéëîâ"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Ëèøíèå ñèìâîëû íà õâîñòå"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Íåèçâåñòíàÿ îòìåòêà"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Íåâîçìîæíî âûïîëíèòü ïîäñòàíîâêó ïî ìàñêå"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr ""
-"E591: Çíà÷åíèå îïöèè 'winheight' íå ìîæåò áûòü ìåíüøå çíà÷åíèÿ 'winminheight'"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr ""
-"E592: Çíà÷åíèå îïöèè 'winwidth' íå ìîæåò áûòü ìåíüøå çíà÷åíèÿ 'winminwidth'"
-
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: Îøèáêà ïðè çàïèñè"
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Íóëåâîå çíà÷åíèå ñ÷¸ò÷èêà"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: Èñïîëüçîâàíèå <SID> âíå êîíòåêñòà ñöåíàðèÿ"
-
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Âíóòðåííÿÿ îøèáêà: %s"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: Øàáëîí èñïîëüçóåò áîëüøå ïàìÿòè ÷åì 'maxmempattern'"
-
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: Ïóñòîé áóôåð"
-
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Íåïðàâèëüíàÿ ñòðîêà ïîèñêà èëè ðàçäåëèòåëü"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Ôàéë çàãðóæåí â äðóãîì áóôåðå"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: Îïöèÿ '%s' íå óñòàíîâëåíà"
-
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: Íåäîïóñòèìîå èìÿ ðåãèñòðà"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "Ïîèñê áóäåò ïðîäîëæåí ñ ÊÎÍÖÀ äîêóìåíòà"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "Ïîèñê áóäåò ïðîäîëæåí ñ ÍÀ×ÀËÀ äîêóìåíòà"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: Ïðîïóùåíî äâîåòî÷èå"
-
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: Íåäîïóñòèìûé êîìïîíåíò"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: Òðåáóåòñÿ óêàçàòü öèôðó"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "Ñòðàíèöà %d"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "Ïå÷àòàòü íå÷åãî"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "Ïå÷àòü ñòð. %d (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr " Êîïèÿ %d èç %d"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "Íàïå÷àòàíî: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "Ïå÷àòü ïðåêðàùåíà"
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: Îøèáêà çàïèñè â ôàéë PostScript"
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: Íåâîçìîæíî îòêðûòü ôàéë \"%s\""
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: Íåâîçìîæíî ïðî÷èòàòü ôàéë ðåñóðñîâ PostScript \"%s\""
-
-#: ../hardcopy.c:1772
-#, 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
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: Ôàéë \"%s\" íå ÿâëÿåòñÿ äîïóñòèìûì ôàéëîì ðåñóðñîâ PostScript"
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: Ôàéë ðåñóðñîâ \"%s\" íåèçâåñòíîé âåðñèè"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: Íåñîâìåñòèìûå ìíîãîáàéòîâàÿ êîäèðîâêà è íàáîð ñèìâîëîâ."
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: printmbcharset íå ìîæåò áûòü ïóñòûì ïðè ìíîãîáàéòîâîé êîäèðîâêå."
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr "E675: Íåò îïðåäåëåíèÿ øðèôòà ïî óìîë÷àíèþ äëÿ ìíîãîáàéòîâîé ïå÷àòè."
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: Íåâîçìîæíî îòêðûòü ôàéë PostScript"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: Íåâîçìîæíî îòêðûòü ôàéë \"%s\""
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: Ôàéë ðåñóðñîâ PostScript \"prolog.ps\" íå íàéäåí"
-
-#: ../hardcopy.c:2593
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: Ôàéë ðåñóðñîâ PostScript \"cidfont.ps\" íå íàéäåí"
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: Ôàéë ðåñóðñîâ PostScript \"%s.ps\" íå íàéäåí"
-
-#: ../hardcopy.c:2654
-#, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: Íåâîçìîæíî ïðåîáðàçîâàòü â êîäèðîâêó ïå÷àòü \"%s\""
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "Îòïðàâêà íà ïå÷àòü..."
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: Íå óäàëîñü âûïîëíèòü ïå÷àòü ôàéëà PostScript"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "Çàäàíèå íà ïå÷àòü îòïðàâëåíî."
-
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "Äîáàâèòü íîâóþ áàçó äàííûõ"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "Çàïðîñ ïî øàáëîíó"
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "Ïîêàçàòü ýòî ñîîáùåíèå"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "Óáèòü ñîåäèíåíèå"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "Çàíîâî èíèöèàëèçèðîâàòü âñå ñîåäèíåíèÿ"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "Ïîêàçàòü ñîåäèíåíèÿ"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Èñïîëüçîâàíèå: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "Ýòà êîìàíäà cscope íå ïîääåðæèâàåò ðàçäåëåíèå îêíà.\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Èñïîëüçîâàíèå: cstag <èìÿ>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: ìåòêà íå íàéäåíà"
-
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: Îøèáêà stat(%s): %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s íå ÿâëÿåòñÿ êàòàëîãîì èëè èìåíåì áàçû cscope"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "Äîáàâëåíà áàçà äàííûõ cscope %s"
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: Îøèáêà ïîëó÷åíèÿ èíôîðìàöèè îò ñîåäèíåíèÿ cscope %<PRId64>"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: Íåèçâåñòíûé òèï ïîèñêà cscope"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: Íåâîçìîæíî ñîçäàòü òðóáó äëÿ cscope"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: Íåâîçìîæíî âûïîëíèòü fork() äëÿ cscope"
-
-#: ../if_cscope.c:849
-msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection: íå óäàëîñü âûïîëíèòü setpgid"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection: íå óäàëîñü âûïîëíèòü exec"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: íå óäàëîñü âûïîëíèòü fdopen äëÿ to_fp"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: íå óäàëîñü âûïîëíèòü fdopen äëÿ fr_fp"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: Íå óäàëîñü çàïóñòèòü ïðîöåññ cscope"
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: Ñîåäèíåíèé ñ cscope íå ñîçäàíî"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: Íåïðàâèëüíûé ôëàã cscopequickfix %c äëÿ %c"
-
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: Íå íàéäåíî ñîîòâåòñòâèé ïî çàïðîñó cscope %s äëÿ %s"
-
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "Êîìàíäû cscope:\n"
-
-#: ../if_cscope.c:1150
-#, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %s%*s (èñïîëüçîâàíèå: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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"
-" c: Íàéòè ôóíêöèè âûçûâàþùèå ýòó ôóíêöèþ\n"
-" d: Íàéòè ôóíêöèè âûçûâàåìûå ýòîé ôóíêöèåé\n"
-" e: Íàéòè ýòîò øàáëîí egrep\n"
-" f: Íàéòè ýòîò ôàéë\n"
-" g: Íàéòè ýòî îïðåäåëåíèå\n"
-" i: Íàéòè ôàéëû âêëþ÷àþùèå (#include) ýòîò ôàéë\n"
-" s: Íàéòè ýòîò C-ñèìâîë\n"
-" t: Íàéòè ýòó òåêñòîâóþ ñòðîêó\n"
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: Äàííàÿ áàçà äàííûõ cscope óæå ïîäñîåäèíåíà"
-
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: Ñîåäèíåíèå ñ cscope %s íå îáíàðóæåíî"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "ñîåäèíåíèå ñ cscope %s çàêðûòî"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: Êðèòè÷åñêàÿ îøèáêà â cs_manage_matches"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Ìåòêà cscope: %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # ñòðîêà"
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "èìÿ ôàéëà / êîíòåêñò / ñòðîêà\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: Îøèáêà cscope: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "Ïåðåçàãðóçêà âñåõ áàç äàííûõ cscope"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "ñîåäèíåíèÿ ñ cscope îòñóòñòâóþò\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid áàçà äàííûõ íà÷àëüíûé ïóòü\n"
-
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "Íåèçâåñòíûé íåîáÿçàòåëüíûé ïàðàìåòð"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "Ñëèøêîì ìíîãî ïàðàìåòðîâ ðåäàêòèðîâàíèÿ"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "Ïðîïóùåí ïàðàìåòð ïîñëå"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "Ìóñîð ïîñëå íåîáÿçàòåëüíîãî ïàðàìåòðà"
-
-#: ../main.c:152
-msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
-msgstr ""
-"Ñëèøêîì ìíîãî ïàðàìåòðîâ \"+êîìàíäà\", \"-c êîìàíäà\" èëè \"--cmd êîìàíäà\""
-
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "Íåäîïóñòèìûé ïàðàìåòð äëÿ"
-
-#: ../main.c:294
-#, c-format
-msgid "%d files to edit\n"
-msgstr "Ôàéëîâ äëÿ ðåäàêòèðîâàíèÿ: %d\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "Ïîïûòêà ïîâòîðíîãî îòêðûòèÿ ôàéëà ñöåíàðèÿ: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "Íåâîçìîæíî îòêðûòü äëÿ ÷òåíèÿ: \""
-
-#: ../main.c:1393
-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"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "êîìàíäíàÿ ñòðîêà ïåðåä âûïîëíåíèåì vimrc"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: Íåâîçìîæíî âûïîëíèòü ÷òåíèå èç \"%s\""
-
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"Äîïîëíèòåëüíàÿ èíôîðìàöèÿ: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[ôàéë ..] ðåäàêòèðîâàíèå óêàçàííûõ ôàéëîâ"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- ÷òåíèå òåêñòà èç ïîòîêà ââîäà stdin"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t ìåòêà ðåäàêòèðîâàíèå ôàéëà ñ óêàçàííîé ìåòêîé"
-
-# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr ""
-"-q [ôàéë-îøèáîê]\n"
-"\t\t\t\t ðåäàêòèðîâàíèå ôàéëà ñ ïåðâîé îøèáêîé"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"Èñïîëüçîâàíèå:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [ïàðàìåòðû] "
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" èëè:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"Ïàðàìåòðû:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tÄàëåå óêàçûâàþòñÿ òîëüêî èìåíà ôàéëîâ"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tÍå âûïîëíÿòü ïîäñòàíîâêó ïî ìàñêå"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tÐåæèì Vi (êàê \"vi\")"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tÐåæèì Ex (êàê \"ex\")"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr "-E\t\t\tÓëó÷øåííûé ðåæèì Ex"
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tÒèõèé (ïàêåòíûé) ðåæèì (òîëüêî äëÿ \"ex\")"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tÐåæèì îòëè÷èé (êàê \"vimdiff\")"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tÏðîñòîé ðåæèì (êàê \"evim\", áåçðåæèìíûé)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tÒîëüêî äëÿ ÷òåíèÿ (êàê \"view\")"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tÎãðàíè÷åííûé ðåæèì (êàê \"rvim\")"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\tÁåç âîçìîæíîñòè ñîõðàíåíèÿ èçìåíåíèé (çàïèñè ôàéëîâ)"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tÁåç âîçìîæíîñòè âíåñåíèÿ èçìåíåíèé â òåêñò"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tÄâîè÷íûé ðåæèì"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tÐåæèì Lisp"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tÐåæèì ñîâìåñòèìîñòè ñ Vi: 'compatible'"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tÐåæèì íåïîëíîé ñîâìåñòèìîñòè ñ Vi: 'nocompatible'"
-
-# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr ""
-"-V[N][ôàéë]\t\tÂûâîäèòü äîïîëíèòåëüíûå ñîîáùåíèÿ\n"
-"\t\t\t\t[óðîâåíü N] [çàïèñûâàòü â ôàéë]"
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tÐåæèì îòëàäêè"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tÁåç ñâîï-ôàéëà, èñïîëüçóåòñÿ òîëüêî ïàìÿòü"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tÂûâåñòè ñïèñîê ñâîï-ôàéëîâ è çàâåðøèòü ðàáîòó"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (ñ èìåíåì ôàéëà)\tÂîññòàíîâèòü àâàðèéíî çàâåðø¸ííûé ñåàíñ"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tÒî æå, ÷òî è -r"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tÇàïóñê â Àðàáñêîì ðåæèìå"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tÇàïóñê â ðåæèìå \"Èâðèò\""
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tÇàïóñê â ðåæèìå \"Ôàðñè\""
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <òåðìèíàë>\tÍàçíà÷èòü óêàçàííûé òèï <òåðìèíàëà>"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tÈñïîëüçîâàòü <vimrc> âìåñòî ëþáûõ ôàéëîâ .vimrc"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tÍå çàãðóæàòü ñöåíàðèè ìîäóëåé"
-
-# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr ""
-"-p[N]\t\tÎòêðûòü N âêëàäîê (ïî óìîë÷àíèþ: ïî îäíîé\n"
-"\t\t\t\tíà êàæäûé ôàéë)"
-
-# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr ""
-"-o[N]\t\tÎòêðûòü N îêîí (ïî óìîë÷àíèþ: ïî îäíîìó\n"
-"\t\t\t\tíà êàæäûé ôàéë)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tÒî æå, ÷òî è -o, íî ñ âåðòèêàëüíûì ðàçäåëåíèåì îêîí"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tÍà÷àòü ðåäàêòèðîâàíèå â êîíöå ôàéëà"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\tÍà÷àòü ðåäàêòèðîâàíèå â ñòðîêå ñ íîìåðîì <lnum>"
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <êîìàíäà>\tÂûïîëíèòü <êîìàíäó> ïåðåä çàãðóçêîé ôàéëà vimrc"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <êîìàíäà>\t\tÂûïîëíèòü <êîìàíäó> ïîñëå çàãðóçêè ïåðâîãî ôàéëà"
-
-# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr ""
-"-S <ñåàíñ>\t\tÏðî÷èòàòü ñöåíàðèé <ñåàíñà> ïîñëå çàãðóçêè\n"
-"\t\t\t\tïåðâîãî ôàéëà"
-
-# \n\t\t.. äëÿ óìåùåíèÿ â 80 ñòîëáöîâ
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr ""
-"-s <ñöåíàðèé>\tÏðî÷èòàòü êîìàíäû Îáû÷íîãî ðåæèìà èç\n"
-"\t\t\t\tôàéëà <ñöåíàðèÿ>"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <ñöåíàðèé>\tÄîáàâëÿòü âñå ââåä¸ííûå êîìàíäû â ôàéë <ñöåíàðèÿ>"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <ñöåíàðèé>\tÇàïèñàòü âñå ââåä¸ííûå êîìàíäû â ôàéë <ñöåíàðèÿ>"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr "--startuptime <ôàéë>\tÇàïèñàòü âðåìåííóþ ìåòêó î çàïóñêå â <ôàéë>"
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tÈñïîëüçîâàòü âìåñòî .viminfo ôàéë <viminfo>"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h èëè --help\tÂûâåñòè ñïðàâêó (ýòî ñîîáùåíèå) è çàâåðøèòü ðàáîòó"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\tÂûâåñòè èíôîðìàöèþ î âåðñèè Vim è çàâåðøèòü ðàáîòó"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "Íåò óñòàíîâëåííûõ îòìåòîê"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: Íåò îòìåòîê, ñîâïàäàþùèõ ñ \"%s\""
-
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"îòìåò ñòð êîë ôàéë/òåêñò"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-"ïðûæîê ñòð êîë ôàéë/òåêñò"
-
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-"\n"
-"èçìåí. ñòð êîë òåêñò"
-
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Ãëîáàëüíûå îòìåòêè:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Ñïèñîê ïðûæêîâ (ñíà÷àëà áîëåå ñâåæèå):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Èñòîðèÿ ìåñòíûõ îòìåòîê (îò áîëåå ñâåæèõ ê ñòàðûì):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "Ïðîïóùåíà '>'"
-
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: Áëîê íå çàáëîêèðîâàí"
-
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: Îøèáêà ïîèñêà ïðè ÷òåíèè ñâîï-ôàéëà"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: Îøèáêà ÷òåíèÿ ñâîï-ôàéëà"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: Îøèáêà ïîèñêà ïðè çàïèñè ñâîï-ôàéëà"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: Îøèáêà ïðè çàïèñè ñâîï-ôàéëà"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr ""
-"E300: Ñâîï-ôàéë óæå ñóùåñòâóåò (àòàêà ñ èñïîëüçîâàíèåì ñèìâîëüíîé ññûëêè?)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: Íå ïîëó÷åí áëîê íîìåð 0?"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: Íå ïîëó÷åí áëîê íîìåð 1?"
-
-#: ../memline.c:377
-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
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: Îé, ïîòåðÿëñÿ ñâîï-ôàéë!!!"
-
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: Íåâîçìîæíî ïåðåèìåíîâàòü ñâîï-ôàéë"
-
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr ""
-"E303: Íå óäàëîñü îòêðûòü ñâîï-ôàéë äëÿ \"%s\", âîññòàíîâëåíèå íåâîçìîæíî"
-
-#: ../memline.c:666
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_upd_block0(): Íå ïîëó÷åí áëîê 0??"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: Ñâîï-ôàéë äëÿ %s íå íàéäåí"
-
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr ""
-"Ââåäèòå íîìåð ñâîï-ôàéëà, êîòîðûé ñëåäóåò èñïîëüçîâàòü (0 äëÿ âûõîäà): "
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: Íå ìîãó îòêðûòü %s"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "Íåâîçìîæíî ïðî÷èòàòü áëîê 0 èç "
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"Íåò èçìåíåíèé, èëè Vim íå ñìîã îáíîâèòü ñâîï-ôàéë"
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " íåëüçÿ èñïîëüçîâàòü â äàííîé âåðñèè Vim.\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "Èñïîëüçóéòå Vim âåðñèè 3.0.\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %s íå ÿâëÿåòñÿ ñâîï-ôàéëîì Vim"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " íåëüçÿ èñïîëüçîâàòü íà ýòîì êîìïüþòåðå.\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr "Ôàéë áûë ñîçäàí "
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-",\n"
-"ëèáî ôàéë áûë ïîâðåæä¸í."
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr " áûë ïîâðåæä¸í (ðàçìåð ñòðàíèöû ìåíüøå ìèíèìàëüíîãî çíà÷åíèÿ).\n"
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "Èñïîëüçóåòñÿ ñâîï-ôàéë \"%s\""
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "Èñõîäíûé ôàéë \"%s\""
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: Ïðåäóïðåæäåíèå: èñõîäíûé ôàéë ìîã áûòü èçìåí¸í"
-
-#: ../memline.c:1061
-#, c-format
-msgid "E309: Unable to read block 1 from %s"
-msgstr "E309: Íåâîçìîæíî ïðî÷èòàòü áëîê 1 èç %s"
-
-#: ../memline.c:1065
-msgid "???MANY LINES MISSING"
-msgstr "???ÎÒÑÓÒÑÒÂÓÅÒ ÌÍÎÃÎ ÑÒÐÎÊ"
-
-#: ../memline.c:1076
-msgid "???LINE COUNT WRONG"
-msgstr "???ÍÅÏÐÀÂÈËÜÍÎÅ ÇÍÀ×ÅÍÈÅ ÑרÒ×ÈÊÀ ÑÒÐÎÊ"
-
-#: ../memline.c:1082
-msgid "???EMPTY BLOCK"
-msgstr "???ÏÓÑÒÎÉ ÁËÎÊ"
-
-#: ../memline.c:1103
-msgid "???LINES MISSING"
-msgstr "???ÎÒÑÓÒÑÒÂÓÞÒ ÑÒÐÎÊÈ"
-
-#: ../memline.c:1128
-#, c-format
-msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: Íåïðàâèëüíûé áëîê 1 ID (%s íå ÿâëÿåòñÿ ôàéëîì .swp?)"
-
-#: ../memline.c:1133
-msgid "???BLOCK MISSING"
-msgstr "???ÏÐÎÏÓÙÅÍ ÁËÎÊ"
-
-#: ../memline.c:1147
-msgid "??? from here until ???END lines may be messed up"
-msgstr "???ñòðîêè ìîãóò áûòü èñïîð÷åíû îòñþäà äî ???ÊÎÍÖÀ"
-
-#: ../memline.c:1164
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "???ñòðîêè ìîãëè áûòü âñòàâëåíû èëè óäàëåíû îòñþäà äî ???ÊÎÍÖÀ"
-
-#: ../memline.c:1181
-msgid "???END"
-msgstr "???ÊÎÍÅÖ"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: Âîññòàíîâëåíèå ïðåðâàíî"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr ""
-"E312: Âî âðåìÿ âîññòàíîâëåíèÿ îáíàðóæåíû îøèáêè; ñì. ñòðîêè, íà÷èíàþùèåñÿ "
-"ñ ???"
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "Ñì. \":help E312\" äëÿ äîïîëíèòåëüíîé èíôîðìàöèè."
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr "Âîññòàíîâëåíèå çàâåðøåíî. Ïðîâåðüòå, âñ¸ ëè â ïîðÿäêå."
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(Ìîæåòå çàïèñàòü ôàéë ïîä äðóãèì èìåíåì è ñðàâíèòü åãî ñ èñõîäíûì\n"
-
-#: ../memline.c:1252
-msgid "and run diff with the original file to check for changes)"
-msgstr "ôàéëîì ïðè ïîìîùè ïðîãðàììû diff)"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr "Âîññòàíîâëåíèå çàâåðøåíî. Ñîäåðæèìîå áóôåðîâ è ôàéëîâ ýêâèâàëåíòíî."
-
-#: ../memline.c:1255
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"\n"
-"Âåðîÿòíî, ñåé÷àñ âû çàõîòèòå óäàëèòü ôàéë .swp.\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "Îáíàðóæåíû ñâîï-ôàéëû:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr " Â òåêóùåì êàòàëîãå:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " Ñ óêàçàííûì èìåíåì:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " Â êàòàëîãå "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- íåò --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " âëàäåëåö: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " äàòà: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " äàòà: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [îò Vim âåðñèè 3.0]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [íå ÿâëÿåòñÿ ñâîï-ôàéëîì Vim]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " èìÿ ôàéëà: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" èçìåí¸í: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "ÄÀ"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "íåò"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" ïîëüçîâàòåëü: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " êîìïüþòåð: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" êîìïüþòåð: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" ïðîöåññ: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (åù¸ âûïîëíÿåòñÿ)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [íå ïðèãîäåí äëÿ èñïîëüçîâàíèÿ íà ýòîì êîìïüþòåðå]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [íå ÷èòàåòñÿ]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [íå îòêðûâàåòñÿ]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: Íåâîçìîæíî îáíîâèòü ñâîï-ôàéë, ïîñêîëüêó îí íå îáíàðóæåí"
-
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "Ñâîï-ôàéë îáíîâë¸í"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: Íåóäà÷íàÿ ïîïûòêà îáíîâëåíèÿ ñâîï-ôàéëà"
-
-#: ../memline.c:1819
-#, 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>"
-msgstr "E316: ml_get: íåâîçìîæíî íàéòè ñòðîêó %<PRId64>"
-
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: Íåïðàâèëüíîå çíà÷åíèå óêàçàòåëÿ áëîêà 3"
-
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "çíà÷åíèå stack_idx äîëæíî áûòü ðàâíî 0"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: Îáíîâëåíî ñëèøêîì ìíîãî áëîêîâ?"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: Íåïðàâèëüíîå çíà÷åíèå óêàçàòåëÿ áëîêà 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "óäàë¸í áëîê 1?"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Ñòðîêà %<PRId64> íå îáíàðóæåíà"
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: Íåïðàâèëüíîå çíà÷åíèå óêàçàòåëÿ áëîêà"
-
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "çíà÷åíèå pe_line_count ðàâíî íóëþ"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: Íîìåð ñòðîêè çà ïðåäåëàìè äèàïàçîíà: %<PRId64>"
-
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: Íåïðàâèëüíîå çíà÷åíèå ñ÷¸ò÷èêà ñòðîê â áëîêå %<PRId64>"
-
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "Ðàçìåð ñòåêà óâåëè÷åí"
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: Íåïðàâèëüíîå çíà÷åíèå óêàçàòåëÿ áëîêà 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr "E773: Ïåòëÿ ñèìâîëüíûõ ññûëîê äëÿ \"%s\""
-
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: ÂÍÈÌÀÍÈÅ"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"Îáíàðóæåí ñâîï-ôàéë ñ èìåíåì \""
-
-# Ñ ìàëåíüêîé áóêâû, ÷òîáû ñîîòâåòñòâîâàëî ïî ñòèëþ ñîñåäíèì ñîîáùåíèÿì.
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "ïðè îòêðûòèè ôàéëà: \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " Áîëåå ÑÂÅÆÈÉ, ÷åì ñâîï-ôàéë!\n"
-
-#: ../memline.c:3244
-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."
-msgstr ""
-"\n"
-"(1) Âîçìîæíî, ðåäàêòèðîâàíèå ýòîãî æå ôàéëà âûïîëíÿåòñÿ â äðóãîé ïðîãðàììå.\n"
-" Åñëè ýòî òàê, òî áóäüòå âíèìàòåëüíû ïðè âíåñåíèè èçìåíåíèé, ÷òîáû\n"
-" ó âàñ íå ïîÿâèëîñü äâà ðàçíûõ âàðèàíòà îäíîãî è òîãî æå ôàéëà."
-
-# Ñîîáùåíèå ðàçäåëåíî, " \n" äîáàâëåíî ò.ê. ñòðîêà íå ïîìåùàåòñÿ.
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr ""
-" \n"
-" Çàâåðøèòå ðàáîòó èëè ïðîäîëæàéòå ñ îñòîðîæíîñòüþ.\n"
-
-#: ../memline.c:3246
-msgid "(2) An edit session for this file crashed.\n"
-msgstr "(2) Ñåàíñ ðåäàêòèðîâàíèÿ ýòîãî ôàéëà çàâåðø¸í àâàðèéíî.\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr "  ýòîì ñëó÷àå, èñïîëüçóéòå êîìàíäó \":recover\" èëè \"vim -r "
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"\"\n"
-" äëÿ âîññòàíîâëåíèÿ èçìåíåíèé (ñì. \":help recovery\").\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " Åñëè âû óæå âûïîëíÿëè ýòó îïåðàöèþ, óäàëèòå ñâîï-ôàéë \""
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"\"\n"
-" ÷òîáû èçáåæàòü ïîÿâëåíèÿ ýòîãî ñîîáùåíèÿ â áóäóùåì.\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "Ñâîï-ôàéë \""
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "\" óæå ñóùåñòâóåò!"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "VIM — ÂÍÈÌÀÍÈÅ"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "Ñâîï-ôàéë óæå ñóùåñòâóåò!"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"&O Îòêðûòü äëÿ ÷òåíèÿ\n"
-"&E Ðåäàêòèðîâàòü\n"
-"&R Âîññòàíîâèòü\n"
-"&Q Âûõîä\n"
-"&A Ïðåðâàòü"
-
-#: ../memline.c:3467
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"&O Îòêðûòü äëÿ ÷òåíèÿ\n"
-"&E Ðåäàêòèðîâàòü\n"
-"&R Âîññòàíîâèòü\n"
-"&D Óäàëèòü\n"
-"&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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
-msgid "E326: Too many swap files found"
-msgstr "E326: Îáíàðóæåíî ñëèøêîì ìíîãî ñâîï-ôàéëîâ"
-
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Íå õâàòàåò ïàìÿòè! (âûäåëÿåòñÿ %<PRIu64> áàéò)"
-
-#: ../menu.c:62
-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
-#, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: Íåò ìåíþ %s"
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-msgid "E792: Empty menu name"
-msgstr "E792: Ïóñòîå èìÿ ìåíþ"
-
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: Ïóòü ê ìåíþ íå äîëæåí âåñòè ê ïîäìåíþ"
-
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: Ýëåìåíòû ìåíþ íåëüçÿ äîáàâëÿòü íåïîñðåäñòâåííî â ïîëîñêó ìåíþ"
-
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: Ðàçäåëèòåëè íå ìîãóò áûòü êîìïîíåíòîì ïóòè ê ìåíþ"
-
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- Ìåíþ ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: Ïóòü ê ìåíþ äîëæåí âåñòè ê ýëåìåíòó ìåíþ"
-
-#: ../menu.c:1330
-#, 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
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: Ïóòü ê ìåíþ äîëæåí âåñòè ê ïîäìåíþ"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: Ìåíþ íå íàéäåíî — ïðîâåðüòå èìåíà ìåíþ"
-
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "Îáíàðóæåíà îøèáêà ïðè îáðàáîòêå %s:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "ñòðîêà %4ld:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: Íåäîïóñòèìîå èìÿ ðåãèñòðà: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr ""
-"Ïåðåâîä ñîîáùåíèé íà ðóññêèé ÿçûê: Âàñèëèé Ðàãîçèí <vrr@users.sourceforge."
-"net>, Ñåðãåé Àë¸øèí <alyoshin.s@gmail.com>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "Ïðåðûâàíèå: "
-
-#: ../message.c:988
-msgid "Press ENTER or type command to continue"
-msgstr "Íàæìèòå ENTER èëè ââåäèòå êîìàíäó äëÿ ïðîäîëæåíèÿ"
-
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s ñòðîêà %<PRId64>"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- Ïðîäîëæåíèå ñëåäóåò --"
-
-#: ../message.c:2398
-msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr " SPACE/d/j: ýêðàí/ñòðàíèöà/ñòðîêà âíèç, b/u/k: ââåðõ, q: âûõîä "
-
-#: ../message.c:3021 ../message.c:3031
-msgid "Question"
-msgstr "Âîïðîñ"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"&Y Äà\n"
-"&N Íåò"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Äà\n"
-"&Íåò\n"
-"Î&òìåíà"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"&Y Äà\n"
-"&N Íåò\n"
-"&A Ñîõðàíèòü âñå\n"
-"&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
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr "Ââåäèòå íîìåð è <Enter> èëè ù¸ëêíèòå ìûøüþ (ïóñòî äëÿ îòìåíû): "
-
-#: ../misc1.c:2539
-msgid "Type number and <Enter> (empty cancels): "
-msgstr "Ââåäèòå íîìåð è <Enter> (ïóñòî äëÿ îòìåíû): "
-
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "Äîáàâëåíà îäíà ñòðîêà"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "Óáðàíà îäíà ñòðîêà"
-
-#: ../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 "Áè-áè!"
-
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "Âûçîâ îáîëî÷êè äëÿ èñïîëíåíèÿ: \"%s\""
-
-#: ../normal.c:183
-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
-msgid "E348: No string under cursor"
-msgstr "E348: Íåò ñòðîêè â ïîçèöèè êóðñîðà"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr ""
-"E352: Íåâîçìîæíî ñòåðåòü ñêëàäêè ñ òåêóùèì çíà÷åíèåì îïöèè 'foldmethod'"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: Ñïèñîê èçìåíåíèé ïóñòîé"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr "E662:  íà÷àëå ñïèñêà èçìåíåíèé"
-
-#: ../normal.c:5901
-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 ðàç)"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "Èçìåíåíû îòñòóïû â 1 ñòðîêå (%s %d ðàç)"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "Èçìåíåíû îòñòóïû, %<PRId64> ñòðîê (%s 1 ðàç)"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "Èçìåíåíû îòñòóïû, %<PRId64> ñòðîê (%s %d ðàç)"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "Èçìåíÿþòñÿ îòñòóïû ñòðîêàõ (%<PRId64>)..."
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "Èçìåí¸í îòñòóï â îäíîé ñòðîêå "
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "Èçìåíåíû îòñòóïû â ñòðîêàõ (%<PRId64>) "
-
-#: ../ops.c:938
-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
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "èçìåíåíî ñòðîê: %<PRId64>"
-
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "ñêîïèðîâàí áëîê èç îäíîé ñòðîêè"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "ñêîïèðîâàíà îäíà ñòðîêà"
-
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "ñêîïèðîâàí áëîê èç ñòðîê: %<PRId64>"
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "ñêîïèðîâàíî ñòðîê: %<PRId64>"
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353:  ðåãèñòðå %s íè÷åãî íåò"
-
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- Ðåãèñòðû ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "Íåäîïóñòèìîå èìÿ ðåãèñòðà"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# Ðåãèñòðû:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: Íåèçâåñòíûé òèï ðåãèñòðà %d"
-
-msgid ""
-"E883: search pattern and expression register may not contain two or more "
-"lines"
-msgstr ""
-"E883: øàáëîí ïîèñêà è ðåãèñòð âûðàæåíèÿ íå ìîãóò ñîäåðæàòü äâóõ èëè áîëåå "
-"ñòðîê"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "Êîëîíîê: %<PRId64>; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Âûäåëåíî %s%<PRId64> èç %<PRId64> ñòðîê; %<PRId64> èç %<PRId64> ñëîâ; "
-"%<PRId64> èç %<PRId64> áàéò"
-
-#: ../ops.c:5105
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Âûäåëåíî %s%<PRId64> èç %<PRId64> ñòð.; %<PRId64> èç %<PRId64> ñëîâ; "
-"%<PRId64> èç %<PRId64> ñèìâ.; %<PRId64> èç %<PRId64> áàéò"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Êîë. %s èç %s; ñòð. %<PRId64> èç %<PRId64>; ñë. %<PRId64> èç %<PRId64>; áàéò "
-"%<PRId64> èç %<PRId64>"
-
-#: ../ops.c:5133
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"Êîë. %s èç %s; ñòð. %<PRId64> èç %<PRId64>; ñë. %<PRId64> èç %<PRId64>; "
-"ñèìâ. %<PRId64> èç %<PRId64>; áàéò %<PRId64> èç %<PRId64>"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> ñ ó÷¸òîì BOM)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Ñòð. %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "Áëàãîäàðèì çà èñïîëüçîâàíèå Vim"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: Íåèçâåñòíàÿ îïöèÿ"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: Îïöèÿ íå ïîääåðæèâàåòñÿ"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: Íå äîïóñêàåòñÿ â ðåæèìíîé ñòðîêå"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr "E846: Êîä êëàâèøè íå óñòàíîâëåí"
-
-#: ../option.c:2924
-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
-msgid "E590: A preview window already exists"
-msgstr "E590: Îêíî ïðåäïðîñìîòðà óæå åñòü"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr ""
-"W17: Àðàáñêèé òðåáóåò èñïîëüçîâàíèÿ UTF-8, ââåäèòå ':set encoding=utf-8'"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: Íóæíî õîòÿ áû %d ñòðîê"
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: Íóæíî õîòÿ áû %d êîëîíîê"
-
-#: ../option.c:6011
-#, 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
-#, c-format
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: Òðåáóåòñÿ óêàçàòü ÷èñëî: &%s = '%s'"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- Òåðìèíàëüíûå êîäû ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- Ãëîáàëüíûå çíà÷åíèÿ îïöèé ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- Ìåñòíûå çíà÷åíèÿ îïöèé ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- Îïöèè ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: ÎØÈÁÊÀ get_varp"
-
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': Íåò ñîîòâåòñòâóþùåãî ñèìâîëà äëÿ %s"
-
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': Ëèøíèå ñèìâîëû ïîñëå òî÷êè ñ çàïÿòîé: %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Íåâîçìîæíî çàïóñòèòü îáîëî÷êó "
-
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"Îáîëî÷êà çàâåðøèëà ðàáîòó "
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-"\n"
-"Íåâîçìîæíî ïîëó÷èòü êîíòåêñò áåçîïàñíîñòè äëÿ "
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-"\n"
-"Íåâîçìîæíî óñòàíîâèòü êîíòåêñò áåçîïàñíîñòè äëÿ "
-
-msgid "Could not set security context "
-msgstr "Íåâîçìîæíî óñòàíîâèòü êîíòåêñò áåçîïàñíîñòè "
-
-msgid " for "
-msgstr " äëÿ "
-
-#. no enough size OR unexpected error
-msgid "Could not get security context "
-msgstr "Íåâîçìîæíî ïîëó÷èòü êîíòåêñò áåçîïàñíîñòè "
-
-msgid ". Removing it!\n"
-msgstr ". Áóäåò óäàë¸í!\n"
-
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = \"%s\""
-
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Ôàéë \"%s\" íå íàéäåí ïî èçâåñòíûì ïóòÿì"
-
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: Â ñòðîêå ôîðìàòà ñëèøêîì ìíîãî %%%c"
-
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: Íåîæèäàííûé ýëåìåíò %%%c â ñòðîêå ôîðìàòà"
-
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: Â ñòðîêå ôîðìàòà ïðîïóùåíà ]"
-
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: %%%c íå ïîääåðæèâàåòñÿ â ñòðîêå ôîðìàòà"
-
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: Íåäîïóñòèìûé %%%c â ïðèñòàâêå â ñòðîêå ôîðìàòà"
-
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: Íåäîïóñòèìûé %%%c â ñòðîêå ôîðìàòà"
-
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378:  çíà÷åíèè îïöèè 'errorformat' îòñóòñòâóåò øàáëîí"
-
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: Èìÿ êàòàëîãà íå çàäàíî èëè ðàâíî ïóñòîé ñòðîêå"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: Áîëüøå íåò ýëåìåíòîâ"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d èç %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (ñòðîêà óäàëåíà)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: Âíèçó ñòåêà áûñòðûõ èñïðàâëåíèé"
-
-#: ../quickfix.c:1869
-msgid "E381: At top of quickfix stack"
-msgstr "E381: Íàâåðõó ñòåêà áûñòðûõ èñïðàâëåíèé"
-
-#: ../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:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr "E683: Íåò èìåíè ôàéëà èëè íåïðàâèëüíûé øàáëîí"
-
-#: ../quickfix.c:2911
-#, c-format
-msgid "Cannot open file \"%s\""
-msgstr "Íåâîçìîæíî îòêðûòü ôàéë \"%s\""
-
-#: ../quickfix.c:3429
-msgid "E681: Buffer is not loaded"
-msgstr "E681: Áóôåð íå âûãðóæåí"
-
-#: ../quickfix.c:3487
-msgid "E777: String or List expected"
-msgstr "E777: Òðåáóåòñÿ ñòðîêà èëè ñïèñîê"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: Íåäîïóñòèìûé ýëåìåíò â %s%%[]"
-
-#: ../regexp.c:374
-#, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E769: Ïðîïóùåíà ] ïîñëå %s["
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: Íåò ïàðû äëÿ %s%%("
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: Íåò ïàðû äëÿ %s("
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: Íåò ïàðû äëÿ %s)"
-
-#: ../regexp.c:378
-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:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: Ïðîïóùåíà ] ïîñëå %s%%["
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: Ïóñòîå %s%%[]"
-
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: Ñëèøêîì äëèííûé øàáëîí"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: Ñëèøêîì ìíîãî \\z("
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: Ñëèøêîì ìíîãî %s("
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: Íåò ïàðû äëÿ \\z("
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: Íåäîïóñòèìûé ñèìâîë ïîñëå %s@"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: Ñëèøêîì ìíîãî ñëîæíûõ êîíñòðóêöèé %s{...}"
-
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: Âëîæåííûå %s*"
-
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: Âëîæåííûå %s%c"
-
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: Íåäîïóñòèìîå èñïîëüçîâàíèå \\_"
-
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c íè çà ÷åì íå ñëåäóåò"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: Íåäîïóñòèìàÿ îáðàòíàÿ ññûëêà"
-
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: Íåäîïóñòèìûé ñèìâîë ïîñëå \\z"
-
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: Íåäîïóñòèìûé ñèìâîë ïîñëå %s%%[dxouU]"
-
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: Íåäîïóñòèìûé ñèìâîë ïîñëå %s%%"
-
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: Ñèíòàêñè÷åñêàÿ îøèáêà â %s{...}"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "Âíåøíèå ïîäñîîòâåòñòâèÿ:\n"
-
-#, c-format
-msgid "E888: (NFA regexp) cannot repeat %s"
-msgstr "E888: (ðåã. âûðàæåíèå ÍÊÀ) íåâîçìîæíî ïîâòîðèòü %s"
-
-#: ../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. Áóäåò èñïîëüçîâàòüñÿ "
-"àâòîìàòè÷åñêàÿ ìàøèíà"
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr "E865: (ÍÊÀ) íåîæèäàííûé êîíåö ðåãóëÿðíîãî âûðàæåíèÿ"
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr "E866: (ðåã. âûðàæåíèå ÍÊÀ) íåîæèäàííûé %c"
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr "E867: (ÍÊÀ) íåèçâåñòíûé îïåðàòîð '\\z%c'"
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (ÍÊÀ) íåèçâåñòíûé îïåðàòîð '\\%%%c'"
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr "E869: (ÍÊÀ) íåèçâåñòíûé îïåðàòîð '\\@%c'"
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr "E870: (ðåã. âûðàæåíèå ÍÊÀ) îøèáêà ïðè ÷òåíèè ãðàíèö ïîâòîðåíèÿ"
-
-#. 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: (ðåã. âûðàæåíèå ÍÊÀ) ìíîæåñòâî íå ìîæåò ñëåäîâàòü çà ìíîæåñòâîì!"
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr "E872: (ðåã. âûðàæåíèå ÍÊÀ) ñëèøêîì ìíîãî '('"
-
-#: ../regexp_nfa.c:2042
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E879: (ðåã. âûðàæåíèå ÍÊÀ) ñëèøêîì ìíîãî \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr "E873: (ðåã. âûðàæåíèå ÍÊÀ) îøèáêà êîððåêòíîãî çàâåðøåíèÿ"
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr "E874: (ðåã. âûðàæåíèå ÍÊÀ) íåâîçìîæíî âçÿòü èç ñòåêà!"
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-"E875: (ðåã. âûðàæåíèå ÍÊÀ) â ñòåêå îñòàëîñü ñëèøêîì ìíîãî ñîñòîÿíèé (ïðè "
-"ïðåîáðàçîâàíèè èç postfix â ÍÊÀ)"
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr "E876: (ðåã. âûðàæåíèå ÍÊÀ) íåäîñòàòî÷íî ìåñòà äëÿ õðàíåíèÿ âñåãî ÍÊÀ"
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"Íåâîçìîæíî îòêðûòü ôàéë âðåìåííîãî æóðíàëà äëÿ çàïèñè, âûâîä íà stderr..."
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(ÍÊÀ) íåâîçìîæíî îòêðûòü %s!"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "Íåâîçìîæíî îòêðûòü ôàéë âðåìåííîãî æóðíàëà äëÿ çàïèñè"
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " ÂÈÐÒÓÀËÜÍÀß ÇÀÌÅÍÀ"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " ÇÀÌÅÍÀ"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " ÎÁÐÀÒÍÀß"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " ÂÑÒÀÂÊÀ"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (âñòàâêà)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (çàìåíà)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (âèðòóàëüíàÿ çàìåíà)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " Èâðèò"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " Àðàáñêèé"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (ÿçûê)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (âêëåéêà)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " ÂÈÇÓÀËÜÍÛÉ ÐÅÆÈÌ"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " ÂÈÇÓÀËÜÍÀß ÑÒÐÎÊÀ"
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " ÂÈÇÓÀËÜÍÛÉ ÁËÎÊ"
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " ÂÛÄÅËÅÍÈÅ"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " ÂÛÄÅËÅÍÈÅ ÑÒÐÎÊÈ"
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " ÂÛÄÅËÅÍÈÅ ÁËÎÊÀ"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "çàïèñü"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: Íåïðàâèëüíàÿ ñòðîêà ïîèñêà: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: Ïîèñê çàêîí÷åí â ÍÀ×ÀËÅ äîêóìåíòà; %s íå íàéäåíî"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: Ïîèñê çàêîí÷åí â ÊÎÍÖÅ äîêóìåíòà; %s íå íàéäåíî"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: Ïîñëå ';' îæèäàåòñÿ ââîä '?' èëè '/'"
-
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (âêëþ÷àåò ðàííåå ïîêàçàííûå ñîîòâåòñòâèÿ)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- Âêëþ÷¸ííûå ôàéëû "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "íå íàéäåíî "
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "ïî ïóòè ---\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (Óæå ïîêàçàíî)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " ÍÅ ÍÀÉÄÅÍÎ"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "Ïðîñìîòð âêëþ÷¸ííûõ ôàéëîâ: %s"
-
-#: ../search.c:4216
-#, c-format
-msgid "Searching included file %s"
-msgstr "Ïîèñê âêëþ÷¸ííîãî ôàéëà %s"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: Ñîîòâåòñòâèå â òåêóùåé ñòðîêå"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "Íàéäåíû âñå âêëþ÷¸ííûå ôàéëû"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "Âêëþ÷¸ííûõ ôàéëîâ íåò"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: Îïðåäåëåíèå íå íàéäåíî"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: Øàáëîí íå íàéäåí"
-
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Çàìåíà "
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-"\n"
-"# Ïîñëåäíèé %sØàáëîí ïîèñêà:\n"
-"~"
-
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Îøèáêà ôîðìàòà â ôàéëå ïðàâîïèñàíèÿ"
-
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr "E758: Ôàéë ïðàâîïèñàíèÿ îáðåçàí"
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr "Ëèøíèé òåêñò íà õâîñòå â %s ñòð. %d: %s"
-
-#: ../spell.c:954
-#, 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
-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\" èëè \"%s.ascii.spl"
-"\""
-
-#: ../spell.c:2473
-#, c-format
-msgid "Reading spell file \"%s\""
-msgstr "×òåíèå ôàéëà ïðàâîïèñàíèÿ \"%s\""
-
-#: ../spell.c:2496
-msgid "E757: This does not look like a spell file"
-msgstr "E757: Ýòî íå ïîõîæå íà ôàéë ïðàâîïèñàíèÿ"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: Ñòàðûé ôàéë ïðàâîïèñàíèÿ, òðåáóåòñÿ åãî îáíîâëåíèå"
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr "E772: Ôàéë ïðàâîïèñàíèÿ ïðåäíàçíà÷åí äëÿ áîëåå íîâîé âåðñèè Vim"
-
-#: ../spell.c:2602
-msgid "E770: Unsupported section in spell file"
-msgstr "E770: Íåïîääåðæèâàåìûé ðàçäåë â ôàéëå ïðàâîïèñàíèÿ"
-
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Ïðåäóïðåæäåíèå: ðåãèîí %s íå ïîääåðæèâàåòñÿ"
-
-#: ../spell.c:4550
-#, c-format
-msgid "Reading affix file %s ..."
-msgstr "×òåíèå ôàéëà àôôèêñîâ %s ..."
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr "Íå óäàëîñü ïðåîáðàçîâàòü ñëîâî â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr "Ïðåîáðàçîâàíèå â %s íå ïîääåðæèâàåòñÿ: èç %s â %s"
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "Íåïðàâèëüíîå çíà÷åíèå FLAG â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr "FLAG ïîñëå èñïîëüçîâàíèÿ ôëàãîâ â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"Îïðåäåëåíèå COMPOUNDFORBIDFLAG ïîñëå ýëåìåíòà PFX ìîæåò äàòü íåïðàâèëüíûå "
-"ðåçóëüòàòû â %s, ñòðîêà %d"
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"Îïðåäåëåíèå COMPOUNDPERMITFLAG ïîñëå ýëåìåíòà PFX ìîæåò äàòü íåïðàâèëüíûå "
-"ðåçóëüòàòû â %s, ñòðîêà %d"
-
-#: ../spell.c:4747
-#, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "Íåïðàâèëüíîå çíà÷åíèå COMPOUNDRULES â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "Íåïðàâèëüíîå çíà÷åíèå COMPOUNDWORDMAX â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "Íåïðàâèëüíîå çíà÷åíèå COMPOUNDMIN â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "Íåïðàâèëüíîå çíà÷åíèå COMPOUNDSYLMAX â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "Íåïðàâèëüíîå çíà÷åíèå CHECKCOMPOUNDPATTERN â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr ""
-"Äðóãîé îáúåäèíÿþùèé ôëàã â ïðîäîëæàþùåì áëîêå àôôèêñà â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4850
-#, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "Ïîâòîðÿþùèéñÿ àôôèêñ â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-"Àôôèêñ òàêæå èñïîëüçóåòñÿ äëÿ BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
-"NOSUGGEST â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr "Îæèäàëîñü Y èëè N â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr "Íàðóøåííîå óñëîâèå â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr "Îæèäàëñÿ ñ÷¸ò÷èê REP(SAL) â %s, ñòðîêà %d"
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr "Îæèäàëñÿ ñ÷¸ò÷èê MAP â %s, ñòðîêà %d"
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr "Ïîâòîðÿþùèéñÿ ñèìâîë â MAP â %s, ñòðîêà %d"
-
-#: ../spell.c:5176
-#, 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 "Ïðîïóùåíà ñòðîêà FOL/LOW/UPP â %s"
-
-#: ../spell.c:5220
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr "COMPOUNDSYLMAX èñïîëüçóåòñÿ áåç SYLLABLE"
-
-#: ../spell.c:5236
-msgid "Too many postponed prefixes"
-msgstr "Ñëèøêîì ìíîãî îòëîæåííûõ ïðåôèêñîâ"
-
-#: ../spell.c:5238
-msgid "Too many compound flags"
-msgstr "Ñëèøêîì ìíîãî ñîñòàâíûõ ôëàãîâ"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr "Ñëèøêîì ìíîãî îòëîæåííûõ ïðåôèêñîâ è/èëè ñîñòàâíûõ ôëàãîâ"
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr "Ïðîïóùåíà ñòðîêà SOFO%s â %s"
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr "Îáå ñòðîêè SAL è SOFO â %s"
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr "Ôëàã íå ÿâëÿåòñÿ ÷èñëîì â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr "Íåäîïóñòèìûé ôëàã â %s íà ñòðîêå %d: %s"
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr "%s èìååò äðóãîå çíà÷åíèå, ÷åì â ôàéëå .aff"
-
-#: ../spell.c:5602
-#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "×òåíèå ôàéëà ñëîâàðÿ %s ..."
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr "E760: Êîëè÷åñòâî ñëîâ íå óêàçàíî â %s"
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "ñòðîêà %6d, ñëîâî %6d — %s"
-
-#: ../spell.c:5691
-#, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "Ïîâòîð ñëîâà â %s íà ñòðîêå %d: %s "
-
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr "Ïåðâûé ïîâòîð ñëîâà â %s íà ñòðîêå %d: %s"
-
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr "%d ïîâòîðÿþùèõñÿ ñëîâ â %s"
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr "Ïðîïóùåíî %d ñëîâ ñ íå ASCII ñèìâîëàìè â %s"
-
-#: ../spell.c:6115
-#, c-format
-msgid "Reading word file %s ..."
-msgstr "×òåíèå ôàéëà ñëîâ %s ..."
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "Ïðîèãíîðèðîâàíà ïîâòîðÿþùàÿñÿ ñòðîêà /encoding= â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "Ïðîèãíîðèðîâàíà ñòðîêà /encoding= ïîñëå ñëîâà â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "Ïðîïóñêàåòñÿ ïîâòîð ñòðîêè /regions= â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "Ñëèøêîì ìíîãî ðåãèîíîâ â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "/ ñòðîêà ïðîïóñêàåòñÿ â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:6224
-#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "Íåäîïóñòèìûé íîìåð ðåãèîíà â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "Íåðàñïîçíàííûå ôëàãè â %s, ñòðîêà %d: %s"
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr "Ïðîïóùåíî %d ñëîâ ñ íå ASCII ñèìâîëàìè"
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "Ñæàòî %d èç %d óçëîâ; îñòàëîñü %d (%d%%)"
-
-#: ../spell.c:7340
-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
-msgid "Performing soundfolding..."
-msgstr "Âûïîëíåíèå çâóêîâîé ñâ¸ðòêè..."
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "Êîëè÷åñòâî ñëîâ ïîñëå çâóêîâîé ñâ¸ðòêè: %<PRId64>"
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr "Îáùåå êîëè÷åñòâî ñëîâ: %d"
-
-#: ../spell.c:7655
-#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Çàïèñü ôàéëà ïðåäëîæåíèÿ èñïðàâëåíèé ïðàâîïèñàíèÿ %s"
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr "Îöåíêà èñïîëüçîâàíèÿ ïàìÿòè ïðè âûïîëíåíèè: %d áàéò"
-
-#: ../spell.c:7820
-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-ìè ðåãèîíîâ"
-
-#: ../spell.c:7846
-#, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E755: Íåäîïóñòèìûé ðåãèîí â %s"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr "Ïðåäóïðåæäåíèå: îáà ñîñòàâíûå è óêàçàíî NOBREAK"
-
-#: ../spell.c:7920
-#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Çàïèñü ôàéëà ïðàâîïèñàíèÿ %s ..."
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr "Çàâåðøåíî!"
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' íå ñîäåðæèò %<PRId64> ýëåìåíòîâ"
-
-#: ../spell.c:8074
-#, fuzzy, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "Ñëîâî óäàëåíî èç %s"
-
-#: ../spell.c:8117
-#, fuzzy, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "Ñëîâî äîáàâëåíî â %s"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: Ñèìâîëû ñëîâ îòëè÷àþòñÿ â ôàéëàõ ïðàâîïèñàíèÿ"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Èçâèíèòå, íåò ïðåäïîëîæåíèé"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Èçâèíèòå, òîëüêî %<PRId64> ïðåäïîëîæåíèé"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Çàìåíèòü \"%.*s\" íà:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Íåò ïðåäûäóùåé çàìåíû ïðàâîïèñàíèÿ"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Íå íàéäåíî: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Ýòî íå ïîõîæå íà ôàéë .sug: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Ñòàðûé ôàéë .sug, òðåáóåò îáíîâëåíèÿ: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Ôàéë .sug äëÿ áîëåå íîâîé âåðñèè Vim: %s"
-
-#: ../spell.c:9295
-#, 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: %s"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: Ïîâòîðÿþùèéñÿ ñèìâîë â ýëåìåíòå MAP"
-
-#: ../syntax.c:266
-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:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: Ñèíòàêñè÷åñêèé êëàñòåð %s íå íàéäåí"
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "Ñèíõðîíèçàöèÿ ïî êîììåíòàðèÿì â ñòèëå ÿçûêà C"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "áåç ñèíõðîíèçàöèè"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "ñèíõðîíèçàöèÿ íà÷àòà "
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr " ñòðîê ïåðåä âåðõíåé ñòðîêîé"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- Ýëåìåíòû ñèíõðîíèçàöèè ñèíòàêñèñà ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"ñèíõðîíèçàöèÿ ïî ýëåìåíòàì"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- Ñèíòàêñè÷åñêèå ýëåìåíòû ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: Ñèíòàêñè÷åñêèé êëàñòåð %s íå íàéäåí"
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "ìèíèìóì "
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "ìàêñèìóì "
-
-#: ../syntax.c:3513
-msgid "; match "
-msgstr "; ñîîòâåòñòâèå "
-
-#: ../syntax.c:3515
-msgid " line breaks"
-msgstr " ïåðåíîñîâ ñòðîê"
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: Çäåñü íåëüçÿ èñïîëüçîâàòü ïàðàìåòð contains"
-
-#: ../syntax.c:4096
-msgid "E844: invalid cchar value"
-msgstr "E844: Íåäîïóñòèìîå çíà÷åíèå cchar"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: Çäåñü íåëüçÿ èñïîëüçîâàòü group[t]here"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: Ýëåìåíò îáëàñòè äëÿ %s íå íàéäåí"
-
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: Òðåáóåòñÿ óêàçàòü èìÿ ôàéëà"
-
-#: ../syntax.c:4221
-msgid "E847: Too many syntax includes"
-msgstr "E847: Ñëèøêîì ìíîãî ñèíòàêñè÷åñêèõ âêëþ÷åíèé"
-
-#: ../syntax.c:4303
-#, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E789: Ïðîïóùåíî ']': %s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: Ïðîïóùåíî '=': %s"
-
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: Íå õâàòàåò ïàðàìåòðîâ: ñèíòàêñè÷åñêèé ðåãèîí %s"
-
-#: ../syntax.c:4870
-msgid "E848: Too many syntax clusters"
-msgstr "E848: Ñëèøêîì ìíîãî ñèíòàêñè÷åñêèõ êëàñòåðîâ"
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: Êëàñòåð íå óêàçàí"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: Íå íàéäåí ðàçäåëèòåëü øàáëîíîâ: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: Ìóñîð ïîñëå øàáëîíà: %s"
-
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr ""
-"E403: Ñèíõðîíèçàöèÿ ñèíòàêñèñà: øàáëîí ïðîäîëæåíèé ñòðîêè óêàçàí äâàæäû"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: Íåäîïóñòèìûå ïàðàìåòðû: %s"
-
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: Ïðîïóùåí çíàê ðàâåíñòâà: %s"
-
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: Ïóñòîé ïàðàìåòð: %s"
-
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %s íå äîïóñêàåòñÿ â ýòîì ìåñòå"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %s äîëæíî áûòü ïåðâûì â ñïèñêå contains"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: Íåèçâåñòíàÿ ãðóïïà: %s"
-
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: Íåïðàâèëüíàÿ ïîäêîìàíäà :syntax: %s"
-
-#: ../syntax.c:5854
-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: Ãðóïïà ïîäñâåòêè ñèíòàêñèñà %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: Íåïå÷àòíûé ñèìâîë â èìåíè ãðóïïû"
-
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: Íåäîïóñòèìûé ñèìâîë â èìåíè ãðóïïû"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr "E849: Ñëèøêîì ìíîãî ãðóïï ïîäñâåòêè è ñèíòàêñèñà"
-
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: Âíèçó ñòåêà ìåòîê"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: Íàâåðõó ñòåêà ìåòîê"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Íåâîçìîæíî ïåðåéòè â ïîçèöèþ äî ïåðâîé ñîâïàäàþùåé ìåòêè"
-
-#: ../tag.c:504
-#, c-format
-msgid "E426: tag not found: %s"
-msgstr "E426: Ìåòêà íå íàéäåíà: %s"
-
-#: ../tag.c:528
-msgid " # pri kind tag"
-msgstr " # ïðè òèï ìåòêà"
-
-#: ../tag.c:531
-msgid "file\n"
-msgstr "ôàéë\n"
-
-#: ../tag.c:829
-msgid "E427: There is only one matching tag"
-msgstr "E427: Åñòü òîëüêî îäíà ñîâïàäàþùàÿ ìåòêà"
-
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: Íåâîçìîæíî ïåðåéòè â ïîçèöèþ çà ïîñëåäíåé ñîâïàäàþùåé ìåòêîé"
-
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "Ôàéë \"%s\" íå ñóùåñòâóåò"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "ìåòêà %d èç %d%s"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " è áîëåå"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " Èñïîëüçóåòñÿ ìåòêà ñ ñèìâîëàìè â äðóãîì ðåãèñòðå!"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: Ôàéë \"%s\" íå ñóùåñòâóåò"
-
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # Ê ìåòêå ÎÒ ñòð. â ôàéëå/òåêñòå"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "Ïîèñê â ôàéëå ìåòîê %s"
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr "Èãíîðèðîâàíèå äëèííîé ñòðîêè â ôàéëå tags"
-
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: Îøèáêà ôîðìàòà â ôàéëå ìåòîê \"%s\""
-
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Ïåðåä áàéòîì %<PRId64>"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Ôàéë ìåòîê íå îòñîðòèðîâàí: %s"
-
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: Ôàéë ìåòîê íå îáíàðóæåí"
-
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: Íå íàéäåí øàáëîí ìåòêè"
-
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: Ìåòêà íå íàéäåíà, ïûòàåìñÿ óãàäàòü!"
-
-#: ../tag.c:2797
-#, c-format
-msgid "Duplicate field name: %s"
-msgstr "Ïîâòîðÿþùååñÿ èìÿ ïîëÿ: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' íå èçâåñòåí. Äîñòóïíû âñòðîåííûå òåðìèíàëû:"
-
-#: ../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 íåò çàïèñè îá ýòîì òåðìèíàëå"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: Â termcap íåò çàïèñè \"%s\""
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: Òðåáóåòñÿ ñïîñîáíîñòü òåðìèíàëà \"cm\""
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Êíîïêè òåðìèíàëà ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: Îøèáêà ÷òåíèÿ ââîäà, âûõîä...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
-msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Íåîæèäàííî èçìåíèëñÿ ñ÷¸ò÷èê ñòðîê"
-
-#: ../undo.c:627
-#, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E828: Íåâîçìîæíî îòêðûòü ôàéë îòìåí äëÿ çàïèñè: %s"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr "E825: Ôàéë îòìåí ïîâðåæä¸í (%s): %s"
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr "Íåâîçìîæíî çàïèñàòü ôàéë îòìåí â êàêîì-ëèáî êàòàëîãå èç 'undodir'"
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr "Ôàéë îòìåí íå ïåðåçàïèñàí, íåâîçìîæíî ïðî÷èòàòü: %s"
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr "Ïåðåçàïèñü íå âûïîëíåíà, ýòî íå ôàéë îòìåí: %s"
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr "Ïðîïóùåíà çàïèñü ôàéëà îòìåí, íå÷åãî îòìåíÿòü"
-
-#: ../undo.c:1121
-#, c-format
-msgid "Writing undo file: %s"
-msgstr "Çàïèñü ôàéëà îòìåí: %s"
-
-#: ../undo.c:1213
-#, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E829: Îøèáêà ïðè çàïèñè ôàéëà îòìåí: %s"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr "Ôàéë îòìåí íå ïðî÷èòàí, äðóãîé âëàäåëåö: %s"
-
-#: ../undo.c:1292
-#, c-format
-msgid "Reading undo file: %s"
-msgstr "×òåíèå ôàéëà îòìåí: %s"
-
-#: ../undo.c:1299
-#, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E822: Íåâîçìîæíî îòêðûòü ôàéë îòìåí äëÿ ÷òåíèÿ: %s"
-
-#: ../undo.c:1308
-#, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E823: Ýòî íå ôàéë îòìåí: %s"
-
-#: ../undo.c:1313
-#, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E824: Íåñîâìåñòèìûé ôàéë îòìåí: %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr "Èçìåíèëîñü ñîäåðæèìîå ôàéëà, íåâîçìîæíî èñïîëüçîâàòü èíôîðìàöèþ îòìåí"
-
-#: ../undo.c:1497
-#, c-format
-msgid "Finished reading undo file %s"
-msgstr "Çàâåðøåíî ÷òåíèå ôàéëà îòìåí %s"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr "Óæå íà ñàìîì ïåðâîì èçìåíåíèè"
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr "Óæå íà ñàìîì ïîñëåäíåì èçìåíåíèè"
-
-#: ../undo.c:1806
-#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Íå íàéäåíà îòìåíà íîìåð %<PRId64>"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: íåïðàâèëüíûå íîìåðà ñòðîê"
-
-#: ../undo.c:2183
-msgid "more line"
-msgstr "ñòð. äîáàâëåíà"
-
-#: ../undo.c:2185
-msgid "more lines"
-msgstr "ñòð. äîáàâëåíî"
-
-#: ../undo.c:2187
-msgid "line less"
-msgstr "ñòð. óäàëåíà"
-
-#: ../undo.c:2189
-msgid "fewer lines"
-msgstr "ñòð. óäàëåíî"
-
-#: ../undo.c:2193
-msgid "change"
-msgstr "èçì."
-
-#: ../undo.c:2195
-msgid "changes"
-msgstr "èçì."
-
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr "ïåðåä"
-
-#: ../undo.c:2228
-msgid "after"
-msgstr "ïîñëå"
-
-#: ../undo.c:2325
-msgid "Nothing to undo"
-msgstr "Íå÷åãî îòìåíÿòü"
-
-# Çàãîëîâîê òàáëèöû :undolist
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr " íîìåð èçìåí. êîãäà ñîõðàíåíî"
-
-#: ../undo.c:2360
-#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> ñ íàçàä"
-
-#: ../undo.c:2372
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E790: Îáúåäèíåíèå îòìåí íå äîïóñêàåòñÿ ïîñëå îòìåíû"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: Ïîâðåæä¸í ñïèñîê îòìåíû"
-
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: Ïîòåðÿíà ñòðîêà îòìåíû"
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Çàïëàòêè: "
-
-#: ../version.c:627
-msgid ""
-"\n"
-"Extra patches: "
-msgstr ""
-"\n"
-"Äîïîëíèòåëüíûå çàïëàòêè: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Ñ èçìåíåíèÿìè, âíåñ¸ííûìè "
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"Ñêîìïèëèðîâàí "
-
-#: ../version.c:649
-msgid "by "
-msgstr " "
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"Îãðîìíàÿ âåðñèÿ "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "áåç ãðàôè÷åñêîãî èíòåðôåéñà."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " Âêëþ÷¸ííûå (+) è îòêëþ÷¸ííûå (-) îñîáåííîñòè:\n"
-
-#: ../version.c:667
-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
-msgid " fall-back for $VIM: \""
-msgstr " çíà÷åíèå $VIM ïî óìîë÷àíèþ: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr " çíà÷åíèå $VIMRUNTIME ïî óìîë÷àíèþ: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "Ïàðàìåòðû êîìïèëÿöèè: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Ñáîðêà: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " ÎÒËÀÄÎ×ÍÀß ÑÁÎÐÊÀ"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM — Vi IMproved (óëó÷øåííûé Vi)"
-
-#: ../version.c:769
-msgid "version "
-msgstr "âåðñèÿ "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "Áðàì Ìîîëåíààð è äðóãèå"
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim ýòî ñâîáîäíî ðàñïðîñòðàíÿåìàÿ ïðîãðàììà ñ îòêðûòûì êîäîì"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "Áåäíûì äåòÿì â Óãàíäå íóæíà âàøà ïîìîùü!"
-
-#: ../version.c:777
-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
-msgid "Sponsor Vim development!"
-msgstr "Ïîìîãèòå â ðàçðàáîòêå Vim!"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "Ñòàíüòå çàðåãèñòðèðîâàííûì ïîëüçîâàòåëåì Vim!"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr "íàáåðèòå :help sponsor<Enter> äëÿ ïîëó÷åíèÿ èíôîðìàöèè "
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr "íàáåðèòå :help register<Enter> äëÿ ïîëó÷åíèÿ èíôîðìàöèè "
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "ìåíþ Ñïðàâêà->Ïîìîùü/Ðåãèñòðàöèÿ äëÿ ïîëó÷åíèÿ èíôîðìàöèè "
-
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "Íà ýêðàíå âñåãî îäíî îêíî"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: Îêíî ïðåäïðîñìîòðà îòñóòñòâóåò"
-
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: Îêíî íå ìîæåò áûòü îäíîâðåìåííî ñëåâà ââåðõó è ñïðàâà âíèçó"
-
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: Íåâîçìîæíî ïîìåíÿòü ìåñòàìè, ïîêà äðóãîå îêíî ðàçäåëåíî"
-
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: Íåëüçÿ çàêðûòü ïîñëåäíåå îêíî"
-
-#: ../window.c:1810
-msgid "E813: Cannot close autocmd window"
-msgstr "E813: Íåëüçÿ çàêðûòü îêíî àâòîêîìàíä"
-
-#: ../window.c:1814
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: Íåëüçÿ çàêðûòü îêíî, îñòàíåòñÿ òîëüêî îêíî àâòîêîìàíä"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445:  äðóãîì îêíå åñòü íåñîõðàí¸ííûå èçìåíåíèÿ"
-
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: Íåò èìåíè ôàéëà â ïîçèöèè êóðñîðà"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: bf_key_init() âûçâàí ñ ïóñòûì ïàðîëåì"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr ""
-#~ "E817: Íåïðàâèëüíîå èñïîëüçîâàíèå îáðàòíîãî/ïðÿìîãî ïîðÿäêà áàéò â Blowfish"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: Íå óäàëîñü âûïîëíèòü òåñò sha256"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Íå óäàëîñü âûïîëíèòü òåñò Blowfish"
-
-#~ msgid "Patch file"
-#~ msgstr "Ôàéë-çàïëàòêà"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&OK\n"
-#~ "&C Îòìåíà"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Íåò ñâÿçè ñ ñåðâåðîì Vim"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Íå ìîãó îòïðàâèòü ñîîáùåíèå äëÿ %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Ñåðâåð íå îòâå÷àåò"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Íå ìîãó îòâåòèòü êëèåíòó"
-
-#~ msgid "Save As"
-#~ msgstr "Ñîõðàíèòü êàê"
-
-#~ msgid "Edit File"
-#~ msgstr "Ðåäàêòèðîâàíèå ôàéëà"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (ÍÅ ÍÀÉÄÅÍÎ)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Âûïîëíèòü ñöåíàðèé Vim"
-
-#~ msgid "unknown"
-#~ msgstr "íåèçâåñòíî"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "Ðåäàêòèðîâàòü ôàéë â íîâîì îêíå"
-
-#~ msgid "Append File"
-#~ msgstr "Äîáàâèòü ôàéë"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Ïîëîæåíèå îêíà: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "Ïåðåíàïðàâëåíèå çàïèñè"
-
-#~ msgid "Save View"
-#~ msgstr "Ñîõðàíåíèå âèäà"
-
-#~ msgid "Save Session"
-#~ msgstr "Ñîõðàíåíèå ñåàíñà"
-
-#~ msgid "Save Setup"
-#~ msgstr "Ñîõðàíåíèå íàñòðîåê"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< íå äîñòóïíî áåç îñîáåííîñòè +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Â ýòîé âåðñèè äèãðàôû íå ðàáîòàþò"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "ÿâëÿåòñÿ óñòðîéñòâîì (îòêëþ÷åíî ïðè îïöèè 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "×òåíèå èç ñòàíäàðòíîãî ïîòîêà ââîäà stdin..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfish]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[çàøèôðîâàíî]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Ôàéë çàøèôðîâàí íåèçâåñòíûì ìåòîäîì"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans íå ïîçâîëÿåò âûïîëíÿòü çàïèñü íåèçìåí¸ííûõ áóôåðîâ"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "×àñòè÷íàÿ çàïèñü áóôåðîâ NetBeans íå äîïóñêàåòñÿ"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "çàïèñü â óñòðîéñòâî îòêëþ÷åíà ïðè îïöèè 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr ""
-#~ "E460: Âåòâü ðåñóðñà áóäåò ïîòåðÿíà (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: Íåâîçìîæíî ñîçäàòü íîâûé ïðîöåññ äëÿ ãðàô. èíòåðôåéñà"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: Ïðîöåññó-ïîòîìêó íå óäàëîñü çàïóñòèòü ãðàô. èíòåðôåéñ"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Íåâîçìîæíî ïåðåéòè â ðåæèì ãðàôè÷åñêîãî èíòåðôåéñà"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Íåâîçìîæíî âûïîëíèòü ÷òåíèå \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr ""
-#~ "E665: Íåâîçìîæíî ïåðåéòè â ðåæèì ãðàô. èíòåðôåéñà, íåïðàâèëüíî çàäàíû "
-#~ "øðèôòû"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: Íåïðàâèëüíîå çíà÷åíèå îïöèè 'guifontwide'"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Íåïðàâèëüíîå çíà÷åíèå îïöèè 'imactivatekey'"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Íåâîçìîæíî íàçíà÷èòü öâåò %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Íåò ñîâïàäåíèÿ ïîä êóðñîðîì, ïîèñê ñëåäóþùåãî"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<íåëüçÿ îòêðûòü> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: øðèôò %s íå íàéäåí"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: âîçâðàò â òåêóùèé êàòàëîã íåâîçìîæåí"
-
-#~ msgid "Pathname:"
-#~ msgstr "Ïóòü ê ôàéëó:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: íå ìîãó íàéòè òåêóùèé êàòàëîã"
-
-#~ msgid "OK"
-#~ msgstr "Äà"
-
-#~ msgid "Cancel"
-#~ msgstr "Îòìåíà"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "Ïîëîñà ïðîêðóòêè: íå ìîãó îïðåäåëèòü ãåîìåòðèþ ïîëçóíêà"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Äèàëîãîâîå îêíî Vim"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr ""
-#~ "E232: \"Ïóçûðü\" äëÿ âû÷èñëåíèé, âêëþ÷àþùèé è ñîîáùåíèå, è îáðàòíûé "
-#~ "âûçîâ, íå ìîæåò áûòü ñîçäàí"
-
-#~ msgid "Input _Methods"
-#~ msgstr "Ìåòîäû Ââîäà"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM — Ïîèñê è çàìåíà..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM — Ïîèñê..."
-
-#~ msgid "Find what:"
-#~ msgstr "×òî èùåì:"
-
-#~ msgid "Replace with:"
-#~ msgstr "Íà ÷òî çàìåíÿåì:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Òîëüêî òî÷íûå ñîîòâåòñòâèÿ"
-
-#~ msgid "Match case"
-#~ msgstr "Ðåãèñòðîçàâèñèìûå ñîîòâåòñòâèÿ"
-
-#~ msgid "Direction"
-#~ msgstr "Íàïðàâëåíèå"
-
-#~ msgid "Up"
-#~ msgstr "Ââåðõ"
-
-#~ msgid "Down"
-#~ msgstr "Âíèç"
-
-#~ msgid "Find Next"
-#~ msgstr "Íàéòè ñëåäóþùåå"
-
-#~ msgid "Replace"
-#~ msgstr "Çàìåíà"
-
-#~ msgid "Replace All"
-#~ msgstr "Çàìåíèòü âñå"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: Ïîëó÷åí çàïðîñ íà ïðåêðàùåíèå ðàáîòû îò äèñïåò÷åðà ñåàíñîâ\n"
-
-#~ msgid "Close"
-#~ msgstr "Çàêðûòü"
-
-#~ msgid "New tab"
-#~ msgstr "Íîâàÿ âêëàäêà"
-
-#~ msgid "Open Tab..."
-#~ msgstr "Îòêðûòü âêëàäêó..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Îñíîâíîå îêíî áûëî íåîæèäàííî çàêðûòî\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&Ôèëüòð"
-
-#~ msgid "&Cancel"
-#~ msgstr "Î&òìåíà"
-
-#~ msgid "Directories"
-#~ msgstr "Êàòàëîãè"
-
-#~ msgid "Filter"
-#~ msgstr "Ôèëüòð"
-
-#~ msgid "&Help"
-#~ msgstr "&Ñïðàâêà"
-
-#~ msgid "Files"
-#~ msgstr "Ôàéëû"
-
-#~ msgid "&OK"
-#~ msgstr "&Äà"
-
-#~ msgid "Selection"
-#~ msgstr "Âûäåëåíèå"
-
-#~ msgid "Find &Next"
-#~ msgstr "Íàéòè &ñëåäóþùåå"
-
-#~ msgid "&Replace"
-#~ msgstr "Çà&ìåíà"
-
-#~ msgid "Replace &All"
-#~ msgstr "Çàìåíèòü &âñå"
-
-#~ msgid "&Undo"
-#~ msgstr "Î&òìåíà"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Îêíî ñ çàãîëîâêîì \"%s\" íå îáíàðóæåíî"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Ïàðàìåòð íå ïîääåðæèâàåòñÿ: \"-%s\"; èñïîëüçóéòå âåðñèþ OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Íåâîçìîæíî îòêðûòü îêíî âíóòðè ïðèëîæåíèÿ MDI"
-
-#~ msgid "Close tab"
-#~ msgstr "Çàêðûòü âêëàäêó"
-
-#~ msgid "Open tab..."
-#~ msgstr "Îòêðûòü âêëàäêó..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Ïîèñê ñòðîêè (èñïîëüçóéòå '\\\\' äëÿ ïîèñêà '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Ïîèñê è çàìåíà (èñïîëüçóéòå '\\\\' äëÿ ïîèñêà '\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "Íå èñïîëüçóåòñÿ"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Êàòàëîã\t*.íè÷åãî\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Íåâîçìîæíî âûäåëèòü çàïèñü â òàáëèöå öâåòà, íåêîòîðûå öâåòà "
-#~ "ìîãóò îòîáðàæàòüñÿ íåïðàâèëüíî"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr ""
-#~ "E250: Â íàáîðå øðèôòîâ %s îòñóòñòâóþò øðèôòû äëÿ ñëåäóþùèõ êîäèðîâîê:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Íàáîð øðèôòîâ: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Øðèôò '%s' íå ÿâëÿåòñÿ ìîíîøèðèííûì"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: Íàáîð øðèôòîâ: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "Font0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "Font1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr ""
-#~ "Øèðèíà øðèôòà font%<PRId64> äîëæíà áûòü âäâîå áîëüøå øèðèíû øðèôòà font0"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "Øèðèíà øðèôòà font0: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "Øèðèíà øðèôòà font1: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Íåïðàâèëüíîå îïðåäåëåíèå øðèôòà"
-
-#~ msgid "&Dismiss"
-#~ msgstr "Î&òêëîíèòü"
-
-#~ msgid "no specific match"
-#~ msgstr "íåò ñïåöèàëüíîãî ñîâïàäåíèÿ"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim — Âûáîð øðèôòà"
-
-#~ msgid "Name:"
-#~ msgstr "Íàçâàíèå:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Ïîêàçûâàòü ðàçìåð â ïóíêòàõ"
-
-#~ msgid "Encoding:"
-#~ msgstr "Êîäèðîâêà:"
-
-#~ msgid "Font:"
-#~ msgstr "Øðèôò:"
-
-#~ msgid "Style:"
-#~ msgstr "Ñòèëü:"
-
-#~ msgid "Size:"
-#~ msgstr "Ðàçìåð:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: ÎØÈÁÊÀ àâòîìàòèêè Õàíãûë"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: Îøèáêà stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: Íåâîçìîæíî îòêðûòü áàçó äàííûõ cscope: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: Èíôîðìàöèÿ î áàçå äàííûõ cscope íå äîñòóïíà"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Áèáëèîòåêà Lua íå ìîæåò áûòü çàãðóæåíà."
-
-#~ msgid "cannot save undo information"
-#~ msgstr "íåâîçìîæíî ñîõðàíèòü èíôîðìàöèþ îá îòìåíå îïåðàöèè"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: Ê ñîæàëåíèþ ýòà êîìàíäà íå ðàáîòàåò, ïîñêîëüêó íå çàãðóæåíà "
-#~ "áèáëèîòåêà MzScheme"
-
-#~ msgid "invalid expression"
-#~ msgstr "íåïðàâèëüíîå âûðàæåíèå"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "âûðàæåíèÿ îòêëþ÷åíû ïðè êîìïèëÿöèè"
-
-#~ msgid "hidden option"
-#~ msgstr "ñêðûòàÿ îïöèÿ"
-
-#~ msgid "unknown option"
-#~ msgstr "íåèçâåñòíàÿ îïöèÿ"
-
-#~ msgid "window index is out of range"
-#~ msgstr "èíäåêñ îêíà çà ïðåäåëàìè äèàïàçîíà"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "íåâîçìîæíî îòêðûòü áóôåð"
-
-#~ msgid "cannot delete line"
-#~ msgstr "íåâîçìîæíî óäàëèòü ñòðîêó"
-
-#~ msgid "cannot replace line"
-#~ msgstr "íåâîçìîæíî çàìåíèòü ñòðîêó"
-
-#~ msgid "cannot insert line"
-#~ msgstr "íåâîçìîæíî âñòàâèòü ñòðîêó"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "ñòðîêà íå ìîæåò ñîäåðæàòü ñèìâîë íîâîé ñòðîêè"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "íåâîçìîæíî ïðåîáðàçîâàòü çíà÷åíèÿ Scheme â Vim"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "îøèáêà Vim: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "îøèáêà Vim"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "íåïðàâèëüíûé áóôåð"
-
-#~ msgid "window is invalid"
-#~ msgstr "íåïðàâèëüíîå îêíî"
-
-#~ msgid "linenr out of range"
-#~ msgstr "íîìåð ñòðîêè çà ïðåäåëàìè äèàïàçîíà"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "íå äîïóñêàåòñÿ â ïåñî÷íèöå Vim"
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr ""
-#~ "E836: Äàííûé Vim íå ìîæåò âûïîëíèòü :python ïîñëå èñïîëüçîâàíèÿ :py3"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: Ê ñîæàëåíèþ ýòà êîìàíäà íå ðàáîòàåò, ïîñêîëüêó íå çàãðóæåíà "
-#~ "áèáëèîòåêà Python"
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Íåâîçìîæíî âûïîëíèòü ðåêóðñèâíûé âûçîâ Python"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr ""
-#~ "E837: Äàííûé Vim íå ìîæåò âûïîëíèòü :py3 ïîñëå èñïîëüçîâàíèÿ :python"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ äîëæåí áûòü ýêçåìïëÿðîì èëè ñòðîêîé"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Ê ñîæàëåíèþ ýòà êîìàíäà íå ðàáîòàåò, ïîñêîëüêó íå çàãðóæåíà "
-#~ "áèáëèîòåêà Ruby"
-
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: Íåîæèäàííûé return"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: Íåîæèäàííûé next"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: Íåîæèäàííûé break"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: Íåîæèäàííûé redo"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: retry âíå îïåðàòîðà rescue"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: Íåîáðàáîòàííîå èñêëþ÷åíèå"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: Íåèçâåñòíîå ñîñòîÿíèå longjmp %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Ïåðåêëþ÷åíèå ìåæäó ðåàëèçàöèåé/îïðåäåëåíèåì"
-
-#~ msgid "Show base class of"
-#~ msgstr "Ïîêàçàòü îñíîâíîé êëàññ"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Ïîêàçàòü ïåðåãðóæåííûå ôóíêöèè"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Ïîëó÷èòü èç ôàéëà"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Ïîëó÷èòü èç ïðîåêòà"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Ïîëó÷èòü èç âñåõ ïðîåêòîâ"
-
-#~ msgid "Retrieve"
-#~ msgstr "Ïîëó÷èòü"
-
-#~ msgid "Show source of"
-#~ msgstr "Ïîêàçàòü èñõîäíûé êîä"
-
-#~ msgid "Find symbol"
-#~ msgstr "Íàéòè ñèìâîë"
-
-#~ msgid "Browse class"
-#~ msgstr "Ïðîñìîòð êëàññà"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Ïîêàçàòü êëàññ â èåðàðõèè"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Ïîêàçàòü êëàññ â îãðàíè÷åííîé èåðàðõèè"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ññûëàåòñÿ íà"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Ññûëêà íà xref èç"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref èìååò"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref èñïîëüçóåòñÿ"
-
-#~ msgid "Show docu of"
-#~ msgstr "Ïîêàçàòü docu"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Ñîçäàòü docu"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Íåâîçìîæíî ïîäñîåäèíèòüñÿ ê SNiFF+. Ïðîâåðüòå íàñòðîéêè îêðóæåíèÿ."
-#~ "(sniffemacs äîëæíû áûòü óêàçàíû â ïåðåìåííîé $PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Îøèáêà âî âðåìÿ ÷òåíèÿ. Îòñîåäèíåíèå"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "Â íàñòîÿùèé ìîìåíò SNiFF+ "
-
-#~ msgid "not "
-#~ msgstr "íå "
-
-#~ msgid "connected"
-#~ msgstr "ïîäñîåäèí¸í"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Íåèçâåñòíûé çàïðîñ SNiFF+: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Îøèáêà ñîåäèíåíèÿ ñî SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ íå ïîäñîåäèí¸í"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Ýòî íå áóôåð SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: Îøèáêà âî âðåìÿ çàïèñè. Îòñîåäèíåíèå"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "íåïðàâèëüíûé íîìåð áóôåðà"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ïîêà íå ðåàëèçîâàíî"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "íåâîçìîæíî íàçíà÷èòü ñòðîêó èëè ñòðîêè"
-
-#~ msgid "invalid mark name"
-#~ msgstr "íåïðàâèëüíîå èìÿ îòìåòêè"
-
-#~ msgid "mark not set"
-#~ msgstr "îòìåòêà íå óñòàíîâëåíà"
-
-#~ msgid "row %d column %d"
-#~ msgstr "ðÿä %d êîëîíêà %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "íåâîçìîæíî âñòàâèòü èëè äîáàâèòü ñòðîêó"
-
-#~ msgid "line number out of range"
-#~ msgstr "íîìåð ñòðîêè çà ïðåäåëàìè äèàïàçîíà"
-
-#~ msgid "unknown flag: "
-#~ msgstr "íåèçâåñòíûé ôëàã: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "íåèçâåñòíàÿ vimOption"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "êëàâèàòóðíîå ïðåðûâàíèå"
-
-#~ msgid "vim error"
-#~ msgstr "îøèáêà VIM"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr ""
-#~ "íåâîçìîæíî ñîçäàòü êîìàíäó áóôåðà èëè îêíà: îáúåêò â ïðîöåññå óäàëåíèÿ"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr ""
-#~ "íåâîçìîæíî çàðåãèñòðèðîâàòü êîìàíäó ñ îáðàòíûì âûçîâîì: áóôåð èëè îêíî â "
-#~ "ïðîöåññå óäàëåíèÿ"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: ÊÐÈÒÈ×ÅÑÊÀß ÎØÈÁÊÀ TCL: ïîâðåæä¸í ñïèñîê ññûëîê?! Ñîîáùèòå îá ýòîì "
-#~ "ïî àäðåñó vim-dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "íåâîçìîæíî çàðåãèñòðèðîâàòü êîìàíäó ñ îáðàòíûì âûçîâîì: ññûëêà íà áóôåð "
-#~ "èëè îêíî íå îáíàðóæåíà"
-
-#~ 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 "cannot get line"
-#~ msgstr "íåâîçìîæíî ïîëó÷èòü ñòðîêó"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Íåâîçìîæíî çàðåãèñòðèðîâàòü èìÿ ñåðâåðà êîìàíä"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Íå óäàëàñü îòïðàâêà êîìàíäû â äðóãóþ ïðîãðàììó"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Èñïîëüçóåòñÿ íåïðàâèëüíûé id ñåðâåðà: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: Íåïðàâèëüíî ñôîðìèðîâàíî çíà÷åíèå äàííîãî ïðîöåññà VIM â ðååñòðå. "
-#~ "Óäàëåíî!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "NetBeans íå ïîääåðæèâàåòñÿ ñ ýòèì ãðàôè÷åñêèì èíòåðôåéñîì\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr ""
-#~ "Äàííûé Vim áûë ñêîìïèëèðîâàí ñ âûêëþ÷åííîé îñîáåííîñòüþ ïðîñìîòðà îòëè÷èé"
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "Íåâîçìîæíî èñïîëüçîâàòü '-nb': íå âêëþ÷åíî ïðè êîìïèëÿöèè\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Îøèáêà: Íå óäàëîñü çàïóñòèòü gvim èç NetBeans\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "Åñëè ðåãèñòð èãíîðèðóåòñÿ, äîáàâüòå ïåðåä ôëàãîì / äëÿ âåðõíåãî ðåãèñòðà"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tÇàðåãèñòðèðîâàòü ýòîò gvim äëÿ OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tÎòêëþ÷èòü ðåãèñòðàöèþ äàííîãî gvim äëÿ OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tÇàïóñòèòü ñ ãðàôè÷åñêèì èíòåðôåéñîì (êàê \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr ""
-#~ "-f èëè --nofork\t àêòèâíîé çàäà÷å: Íå âûïîëíÿòü fork ïðè çàïóñêå GUI"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tÍå èñïîëüçîâàòü newcli äëÿ îòêðûòèÿ îêíà"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <óñòðîéñòâî>\t\tÈñïîëüçîâàòü äëÿ I/O óêàçàííîå <óñòðîéñòâî>"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tÈñïîëüçîâàòü <gvimrc> âìåñòî ëþáûõ ôàéëîâ .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tÐåäàêòèðîâàíèå çàøèôðîâàííûõ ôàéëîâ"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <ýêðàí>\tÏîäñîåäèíèòü VIM ê óêàçàííîìó X-ñåðâåðó"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tÍå âûïîëíÿòü ñîåäèíåíèå ñ ñåðâåðîì X"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <ôàéëû>\tÏî âîçìîæíîñòè ðåäàêòèðîâàòü <ôàéëû> íà ñåðâåðå Vim"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <ôàéëû> Òî æå, íî áåç æàëîá íà îòñóòñòâèå ñåðâåðà"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <ôàéëû> Òî æå, ÷òî è --remote, íî ñ îæèäàíèåì çàâåðøåíèÿ"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <ôàéëû> Òî æå, íî áåç æàëîá íà îòñóòñòâèå ñåðâåðà"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <ôàéëû> Òî æå, ÷òî è --remote, íî ñ "
-#~ "âêëàäêàìè"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <êíîïêè>\tÎòïðàâèòü <êíîïêè> íà ñåðâåð Vim è âûéòè"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <âûðàæ>\tÂû÷èñëèòü <âûðàæ> íà ñåðâåðå Vim è íàïå÷àòàòü"
-
-#~ 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 <èìÿ>\tÎòïðàâèòü íà/ñòàòü ñåðâåðîì Vim ñ óêàçàííûì <èìåíåì>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ïàðàìåòðû äëÿ gvim (âåðñèÿ Motif):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ïàðàìåòðû äëÿ gvim (âåðñèÿ neXtaw):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ïàðàìåòðû äëÿ gvim (âåðñèÿ Athena):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <äèñïëåé>\tÇàïóñòèòü VIM íà óêàçàííîì <äèñïëåå>"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tÇàïóñòèòü VIM â ñâ¸ðíóòîì âèäå"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr ""
-#~ "-background <öâåò>\tÈñïîëüçîâàòü óêàçàííûé <öâåò> äëÿ ôîíà (òàêæå: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <öâåò>\tÈñïîëüçîâàòü <öâåò> äëÿ îáû÷íîãî òåêñòà (òàêæå: -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr ""
-#~ "-font <øðèôò>\t\tÈñïîëüçîâàòü <øðèôò> äëÿ îáû÷íîãî òåêñòà (òàêæå: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <øðèôò>\tÈñïîëüçîâàòü <øðèôò> äëÿ æèðíîãî òåêñòà"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <øðèôò>\tÈñïîëüçîâàòü <øðèôò> äëÿ íàêëîííîãî òåêñòà"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr ""
-#~ "-geometry <ãåîìåòðèÿ>\tÈñïîëüçîâàòü íà÷àëüíóþ <ãåîìåòðèþ> (òàêæå: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <øèðèíà>\tÈñïîëüçîâàòü <øèðèíó> áîðäþðà (òàêæå: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <øèðèíà> Èñïîëüçîâàòü øèðèíó ïîëîñû ïðîêðóòêè (òàêæå: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <âûñîòà>\tÈñïîëüçîâàòü <âûñîòó> ìåíþ (òàêæå: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tÈñïîëüçîâàòü èíâåðñíûé âèäåîðåæèì (òàêæå: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tÍå èñïîëüçîâàòü èíâåðñíûé âèäåîðåæèì (òàêæå: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <ðåñóðñ>\tÓñòàíîâèòü óêàçàííûé <ðåñóðñ>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ïàðàìåòðû äëÿ gvim (âåðñèÿ GTK+):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr ""
-#~ "-display <äèñïëåé>\tÇàïóñòèòü VIM íà óêàçàííîì <äèñïëåå> (òàêæå: --"
-#~ "display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr ""
-#~ "--role <ðîëü>\tÓñòàíîâèòü óíèêàëüíóþ <ðîëü> äëÿ èäåíòèôèêàöèè ãëàâíîãî "
-#~ "îêíà"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tÎòêðûòü Vim âíóòðè äðóãîãî êîìïîíåíòà GTK"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr ""
-#~ "--echo-wid\t\tÂûâåñòè Window ID äëÿ gvim íà ñòàíäàðòíûé ïîòîê âûâîäà"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <çàãîëîâîê ðîäèòåëÿ>\tÎòêðûòü Vim â ðîäèòåëüñêîì ïðèëîæåíèè"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tÎòêðûòü Vim âíóòðè äðóãîãî êîìïîíåíòà win32"
-
-#~ msgid "No display"
-#~ msgstr "Íåò äèñïëåÿ"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Îòïðàâêà íå óäàëàñü.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Îòïðàâêà íå óäàëàñü. Ïîïûòêà ìåñòíîãî âûïîëíåíèÿ\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "îòðåäàêòèðîâàíî %d èç %d"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Íåò äèñïëåÿ: îòïðàâêà âûðàæåíèÿ íå óäàëàñü.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": Îòïðàâêà âûðàæåíèÿ íå óäàëàñü.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Íåäîïóñòèìîå èìÿ êîäèðîâêè"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: Íåâîçìîæíî íàçíà÷èòü çíà÷åíèÿ êîíòåêñòà ââîäà"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Íåâîçìîæíî ñîçäàòü êîíòåêñò ââîäà"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Íåóäà÷íàÿ ïîïûòêà îòêðûòü ìåòîä ââîäà"
-
-#~ 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 "E843: Error while updating swap file crypt"
-#~ msgstr "E843: Îøèáêà ïðè îáíîâëåíèè øèôðîâàíèÿ ñâîï-ôàéëà"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s çàøèôðîâàí, à ýòà âåðñèÿ Vim íå ïîääåðæèâàåò øèôðîâàíèå"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Ñâîï-ôàéë çàøèôðîâàí: \"%s\""
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "Åñëè âû ââåëè íîâûé ïàðîëü äëÿ øèôðîâàíèÿ, íî íå çàïèñàëè òåêñòîâûé ôàéë,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "òî ââåäèòå íîâûé ïàðîëü äëÿ øèôðîâàíèÿ."
-
-# Ïåðåâîä ñîîáùåíèÿ ðàçäåë¸í íà äâå ÷àñòè, ÷àñòü ïåðâàÿ
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "Åñëè âû çàïèñàëè òåêñòîâûé ôàéë ïîñëå èçìåíåíèÿ ïàðîëÿ øèôðîâàíèÿ, òî "
-#~ "íàæìèòå"
-
-# Ïåðåâîä ñîîáùåíèÿ ðàçäåë¸í íà äâå ÷àñòè, ÷àñòü âòîðàÿ
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "Enter äëÿ èñïîëüçîâàíèÿ îäíîãî êëþ÷à äëÿ òåêñòîâîãî ôàéëà è ñâîï-ôàéëà"
-
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr ""
-#~ "Èñïîëüçîâàíèå êëþ÷à øèôðîâàíèÿ èç ñâîï-ôàéëà äëÿ òåêñòîâîãî ôàéëà.\n"
-
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [íå ïðèãîäåí äëÿ èñïîëüçîâàíèÿ ñ äàííîé âåðñèåé Vim]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "Îòîðâàòü ýòî ìåíþ"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Âûáîð êàòàëîãà"
-
-#~ msgid "Save File dialog"
-#~ msgstr "Ñîõðàíåíèå ôàéëà"
-
-#~ msgid "Open File dialog"
-#~ msgstr "Îòêðûòèå ôàéëà"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr ""
-#~ "E338: Èçâèíèòå, íî â êîíñîëüíîì ðåæèìå íåò ïðîâîäíèêà ïî ôàéëîâîé ñèñòåìå"
-
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: ñîõðàíåíèå ôàéëîâ...\n"
-
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: Ãîòîâî.\n"
-
-#~ msgid "ERROR: "
-#~ msgstr "ÎØÈÁÊÀ: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[áàéò] âñåãî âûäåë.-îñâîá. %<PRIu64>-%<PRIu64>, èñïîëüç. %<PRIu64>, ìàêñ. "
-#~ "èñïîëüç. %<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[âûçîâû] re/malloc() âñåãî %<PRIu64>, free() âñåãî %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Ñòðîêà ñòàíîâèòñÿ ñëèøêîì äëèííîé"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Âíóòðåííÿÿ îøèáêà: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Íåäîïóñòèìàÿ ôîðìà êóðñîðà"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "Ââåäèòå ïàðîëü äëÿ øèôðîâàíèÿ: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "Ïîâòîðèòå ââîä ïàðîëÿ: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Ââåä¸ííûå ïàðîëè íå ñîâïàäàþò!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Íåâîçìîæíî ñîåäèíèòüñÿ ñ NetBeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Íåâîçìîæíî ñîåäèíèòüñÿ ñ NetBeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Íåïðàâèëüíûé ðåæèì äîñòóïà ê èíôîðìàöèè î ñîåäèíåíèè ñ NetBeans: "
-#~ "\"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "÷òåíèå èç ãíåçäà NetBeans"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Ïîòåðÿíî ñîåäèíåíèå ñ NetBeans äëÿ áóôåðà %<PRId64>"
-
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: NetBeans íå ïîääåðæèâàåòñÿ ñ ýòèì ãðàôè÷åñêèì èíòåðôåéñîì"
-
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: óæå ñîåäèí¸í ñ NetBeans"
-
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr ""
-#~ "E505: %s îòêðûò òîëüêî äëÿ ÷òåíèÿ (äîáàâüòå !, ÷òîáû îáîéòè ïðîâåðêó)"
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: eval íå äîñòóïíà"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "î÷èùåíî ñòðîê: %<PRId64>"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530:  ãðàôè÷åñêîì èíòåðôåéñå èçìåíÿòü òåðìèíàë íåâîçìîæíî"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Äëÿ çàïóñêà ãðàôè÷åñêîãî èíòåðôåéñà èñïîëüçóéòå \":gui\""
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Íå ìîæåò áûòü èçìåíåíî â ãðàôè÷åñêîì èíòåðôåéñå GTK+ 2"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Íåïðàâèëüíûå øðèôòû"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: Íåâîçìîæíî âûáðàòü øðèôòîâîé íàáîð"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Íåïðàâèëüíûé øðèôòîâîé íàáîð"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: Íåâîçìîæíî âûáðàòü øðèôò ñ ñèìâîëàìè äâîéíîé øèðèíû"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Íåïðàâèëüíûé øðèôò ñ ñèìâîëàìè äâîéíîé øèðèíû"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Ìûøü íå ïîääåðæèâàåòñÿ"
-
-#~ msgid "cannot open "
-#~ msgstr "íåâîçìîæíî îòêðûòü "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Íåâîçìîæíî îòêðûòü îêíî!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Íåîáõîäèìà Amigados âåðñèè 2.04 èëè áîëåå ïîçäíåé\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Íåîáõîäèìà %s âåðñèè %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Íåâîçìîæíî îòêðûòü NIL:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "Íåâîçìîæíî ñîçäàòü "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Ïðåêðàùåíèå ðàáîòû Vim ñ êîäîì %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "íåâîçìîæíî ñìåíèòü ðåæèì êîíñîëè?!\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: íå â êîíñîëè??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Íåâîçìîæíî âûïîëíèòü îáîëî÷êó ñ ïàðàìåòðîì -f"
-
-#~ msgid "Cannot execute "
-#~ msgstr "Íåâîçìîæíî âûïîëíèòü "
-
-#~ msgid "shell "
-#~ msgstr "îáîëî÷êà "
-
-#~ msgid " returned\n"
-#~ msgstr " çàâåðøèëà ðàáîòó\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ñëèøêîì ìàëàÿ âåëè÷èíà ANCHOR_BUF_SIZE."
-
-#~ msgid "I/O ERROR"
-#~ msgstr "ÎØÈÁÊÀ ÂÂÎÄÀ/ÂÛÂÎÄÀ"
-
-#~ msgid "Message"
-#~ msgstr "Ñîîáùåíèå"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr ""
-#~ "Çíà÷åíèå îïöèè 'columns' íå ðàâíî 80, âíåøíèå ïðîãðàììû íå âûïîëíÿþòñÿ"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Íåóäà÷íîå çàâåðøåíèå âûáîðà ïðèíòåðà"
-
-#~ msgid "to %s on %s"
-#~ msgstr "â %s íà %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Íåèçâåñòíûé øðèôò ïðèíòåðà: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Îøèáêà ïå÷àòè: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "Ïå÷àòü '%s'"
-
-#~ 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 "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Äâîéíîé ñèãíàë, çàâåðøåíèå ðàáîòû\n"
-
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: Ïîëó÷åí óáèéñòâåííûé ñèãíàë %s\n"
-
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: Ïîëó÷åí óáèéñòâåííûé ñèãíàë\n"
-
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "Îòêðûòèå äèñïëåÿ X çàíÿëî %<PRId64> msec"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Îøèáêà X\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "Ïðîâåðêà äèñïëåÿ X çàâåðøåíà íåóäà÷íî"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Îòêðûòèå äèñïëåÿ X íå âûïîëíåíî â îòâåä¸ííîå âðåìÿ"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Íåâîçìîæíî çàïóñòèòü îáîëî÷êó sh\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Íåâîçìîæíî ñîçäàòü òðóáû\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Íåâîçìîæíî âûïîëíèòü fork()\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Âûïîëíåíèå êîìàíäû ïðåðâàíî\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP óòåðÿíî ñîåäèíåíèå ICE"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "Íåóäà÷íîå îòêðûòèå äèñïëåÿ X"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP îáðàáàòûâàåò çàïðîñ ñàìîñîõðàíåíèÿ"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP îòêðûâàåò ñîåäèíåíèå"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ïîòåðÿíî ñëåæåíèå çà ñîåäèíåíèåì ICE"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP íåóäà÷íî âûïîëíåíî SmcOpenConnection: %s"
-
-#~ msgid "At line"
-#~ msgstr "Â ñòðîêå"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Íåâîçìîæíî çàãðóçèòü vim32.dll!"
-
-#~ msgid "VIM Error"
-#~ msgstr "Îøèáêà VIM"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Íåâîçìîæíî èñïðàâèòü óêàçàòåëè ôóíêöèé äëÿ DLL!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "çàâåðøåíèå ðàáîòû îáîëî÷êè ñ êîäîì %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Ïåðåõâà÷åíî ñîáûòèå %s\n"
-
-#~ msgid "close"
-#~ msgstr "çàêðûòèå"
-
-#~ msgid "logoff"
-#~ msgstr "îòêëþ÷åíèå"
-
-#~ msgid "shutdown"
-#~ msgstr "çàâåðøåíèå"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Êîìàíäà íå íàéäåíà"
-
-#~ 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 ""
-#~ "VIMRUN.EXE íå íàéäåí â ïóòè, çàäàííîì â $PATH.\n"
-#~ "Âíåøíèå êîìàíäû íå áóäóò îñòàíàâëèâàòüñÿ ïîñëå âûïîëíåíèÿ.\n"
-#~ "Äîïîëíèòåëüíàÿ èíôîðìàöèÿ â :help win32-vimrun"
-
-#~ msgid "Vim Warning"
-#~ msgstr "Ïðåäóïðåæäåíèå Vim"
-
-#~ msgid "Error file"
-#~ msgstr "Ôàéë îøèáîê"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: îøèáêà ïðè ñîçäàíèè ÍÊÀ ñ êëàññîì ýêâèâàëåíòíîñòè!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (ÍÊÀ) íåâîçìîæíî âûäåëèòü ïàìÿòü äëÿ ïðîõîäà âåòâè!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "Ïðåäóïðåæäåíèå: Íåâîçìîæíî íàéòè ñïèñîê ñëîâ \"%s_%s.spl\" èëè \"%s_ascii."
-#~ "spl\""
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Ïðåîáðàçîâàíèå â %s íå ïîääåðæèâàåòñÿ"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: Íåäîñòàòî÷íî îïåðàòèâíîé ïàìÿòè, ñïèñîê ñëîâ áóäåò íå ïîëîí"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Ïóòü ê ôàéëó ìåòîê %s îáðåçàí\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "çàïóñê íîâîé îáîëî÷êè\n"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "Âìåñòî ïóñòîãî âûäåëåíèÿ èñïîëüçóåòñÿ CUT_BUFFER0"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Îòìåíà íåâîçìîæíà; ïðîäîëæàòü âûïîëíåíèå"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Íå çàøèôðîâàííûé ôàéë èìååò çàøèôðîâàííûé ôàéë îòìåí: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Íå óäàëîñü äåøèôðîâàòü ôàéë îòìåí: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Ôàéë îòìåí çàøèôðîâàí: %s"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ ñ ãðàôè÷åñêèì èíòåðôåéñîì äëÿ MS-Windows 16/32 áèò"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ ñ ãðàôè÷åñêèì èíòåðôåéñîì äëÿ MS-Windows 64 áèò"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ ñ ãðàôè÷åñêèì èíòåðôåéñîì äëÿ MS-Windows 32 áèò"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " â ðåæèìå Win32"
-
-#~ msgid " with OLE support"
-#~ msgstr " ñ ïîääåðæêîé OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Êîíñîëüíàÿ âåðñèÿ äëÿ MS-Windows 64 áèò"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Êîíñîëüíàÿ âåðñèÿ äëÿ MS-Windows 32 áèò"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ äëÿ MS-Windows 16 áèò"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ äëÿ MS-DOS 32 áèò"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ äëÿ MS-DOS 16 áèò"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ äëÿ MacOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ äëÿ MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ äëÿ MacOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ äëÿ OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Áîëüøàÿ âåðñèÿ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Îáû÷íàÿ âåðñèÿ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Ìàëàÿ âåðñèÿ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñèÿ \"Êðîõà\" "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì GTK2-GNOME."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì GTK2."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "ñ ãðàôè÷åñêèì èíòåðôåéñîì Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "ñ êëàññè÷åñêèì ãðàôè÷åñêèì èíòåðôåéñîì."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " îáùåñèñòåìíûé ôàéë gvimrc: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " ïîëüçîâàòåëüñêèé ôàéë gvimrc: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " âòîðîé ïîëüçîâàòåëüñêèé ôàéë gvimrc: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " òðåòèé ïîëüçîâàòåëüñêèé ôàéë gvimrc: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " îáùåñèñòåìíûé ôàéë ìåíþ: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Êîìïèëÿòîð: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "ìåíþ Ñïðàâêà->Ñèðîòû äëÿ ïîëó÷åíèÿ èíôîðìàöèè "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Áåçðåæèìíàÿ ðàáîòà, âñòàâêà ââåä¸ííîãî òåêñòà"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr ""
-#~ "ìåíþ Ïðàâêà->Ãëîáàëüíûå íàñòðîéêè->Ðåæèì Âñòàâêè "
-
-#~ msgid " for two modes "
-#~ msgstr " äëÿ äâóõ ðåæèìîâ "
-
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr ""
-#~ "ìåíþ Ïðàâêà->Ãëîáàëüíûå íàñòðîéêè->Ñîâìåñòèìîñòü ñ Vi "
-
-#~ msgid " for Vim defaults "
-#~ msgstr " äëÿ ïåðåõîäà â ðåæèì Vim "
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "ÏÐÅÄÓÏÐÅÆÄÅÍÈÅ: îáíàðóæåíà Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "íàáåðèòå :help windows95<Enter> äëÿ ïîëó÷åíèÿ èíôîðìàöèè "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Íåâîçìîæíî çàãðóçèòü áèáëèîòåêó %s"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "Èçâèíèòå, äàííàÿ êîìàíäà îòêëþ÷åíà: íåâîçìîæíî çàãðóçèòü áèáëèîòåêó Perl"
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Íå äîïóñêàåòñÿ âû÷èñëåíèå Perl â ïåñî÷íèöå áåç ìîäóëÿ áåçîïàñíîñòè"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Ðåäàêòèðîâàòü â &ðàçíûõ Vim-àõ"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Ðåäàêòèðîâàòü â &îäíîì Vim"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Ñðàâíèòü ñ ïîìîùüþ Vim"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Ðå&äàêòèðîâàòü ñ ïîìîùüþ Vim"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Ðåäàêòèðîâàòü â çàïóùåííîì Vim — "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Ðåäàêòèðîâàòü âûäåëåííûå ôàéëû ñ ïîìîùüþ Vim"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "Îøèáêà ñîçäàíèÿ ïðîöåññà: ïðîâåðüòå äîñòóïíîñòü gvim â ïóòè!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "îøèáêà gvimext.dll"
-
-#~ msgid "Path length too long!"
-#~ msgstr "Ñëèøêîì äëèííûé ïóòü!"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Íåèçâåñòíûé øðèôòîâîé íàáîð: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Íåèçâåñòíûé øðèôò: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Øðèôò \"%s\" íå ÿâëÿåòñÿ ìîíîøèðèííûì"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Íå óäàëîñü çàãðóçèòü ôóíêöèþ %s èç áèáëèîòåêè"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: Èâðèò âûêëþ÷åí ïðè êîìïèëÿöèè\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Ôàðñè âûêëþ÷åíî ïðè êîìïèëÿöèè\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: Àðàáñêèé âûêëþ÷åí ïðè êîìïèëÿöèè\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: Ñåðâåð \"%s\" íå çàðåãèñòðèðîâàí"
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: Íåâîçìîæíî îòêðûòü äèñïëåé"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Ïîëó÷åíî íåäîïóñòèìîå âûðàæåíèå"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Íåâîçìîæíî èçìåíèòü îõðàíÿåìóþ îáëàñòü"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans íå äîïóñêàåò èçìåíåíèé â ôàéëàõ òîëüêî äëÿ ÷òåíèÿ"
-
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Òðåáóåòñÿ êëþ÷ øèôðîâàíèÿ äëÿ \"%s\""
-
-#~ msgid "empty keys are not allowed"
-#~ msgstr "Ïóñòûå êëþ÷è íå äîïóñòèìû"
-
-#~ msgid "dictionary is locked"
-#~ msgstr "Ñëîâàðü çàáëîêèðîâàí"
-
-#~ msgid "list is locked"
-#~ msgstr "Ñïèñîê çàáëîêèðîâàí"
-
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "Íåâîçìîæíî äîáàâèòü êëþ÷ '%s' ê ñëîâàðþ"
-
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "Èíäåêñ äîëæåí áûòü öåëûì ÷èñëîì èëè âûáîðêîé, à íå %s"
-
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr "Îæèäàëñÿ ýêçåìïëÿð str() èëè unicode(), íî ïîëó÷åí %s"
-
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "Îæèäàëñÿ ýêçåìïëÿð bytes() èëè str(), íî ïîëó÷åí %s"
-
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr ""
-#~ "Îæèäàëîñü int(), long() èëè ÷òî-òî ïðèâîäèìîå ê long(), íî ïîëó÷åíî %s"
-
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr "Îæèäàëîñü int() èëè ÷òî-òî ïðèâîäèìîå ê int(), íî ïîëó÷åíî %s"
-
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "Çíà÷åíèå ñëèøêîì âåëèêî äëÿ öåëî÷èñëåííîãî òèïà C"
-
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "Çíà÷åíèå ñëèøêîì ìàëî äëÿ öåëî÷èñëåííîãî òèïà C"
-
-#~ msgid "number must be greater then zero"
-#~ msgstr "Íîìåð äîëæåí áûòü áîëüøå íóëÿ"
-
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "Íîìåð äîëæåí áûòü áîëüøå èëè ðàâåí íóëþ"
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "Íåâîçìîæíî óäàëèòü àòðèáóòû OutputObject"
-
-#~ msgid "invalid attribute: %s"
-#~ msgstr "Íåïðàâèëüíûé àòðèáóò: %s"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: Îøèáêà èíèöèàëèçàöèè îáúåêòîâ I/O"
-
-#~ msgid "failed to change directory"
-#~ msgstr "Íåâîçìîæíî ñìåíèòü êàòàëîã"
-
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "Îæèäàëñÿ 3-êîðòåæ êàê ðåçóëüòàò imp.find_module(), íî ïîëó÷åí %s"
-
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr ""
-#~ "Îæèäàëñÿ 3-êîðòåæ êàê ðåçóëüòàò imp.find_module(), íî ïîëó÷åí êîðòåæ ñ "
-#~ "ðàçìåðîì %d"
-
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "Âíóòðåííÿÿ îøèáêà: imp.find_module âîçâðàòèë "
-
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "Íåâîçìîæíî óäàëèòü àòðèáóòû vim.Dictionary"
-
-#~ msgid "cannot modify fixed dictionary"
-#~ msgstr "Íåâîçìîæíî èçìåíèòü ôèêñèðîâàííûé ñëîâàðü"
-
-#~ msgid "cannot set attribute %s"
-#~ msgstr "Íåâîçìîæíî óñòàíîâèòü àòðèáóò %s"
-
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "Õýø-òàáëèöà èçìåíèëàñü ïðè èòåðàöèè"
-
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr ""
-#~ "Îæèäàëñÿ ýëåìåíò-ïîñëåäîâàòåëüíîñòü ðàçìåðà 2, à ðàçìåð ïîëó÷åííîé "
-#~ "ïîñëåäîâàòåëüíîñòè %d"
-
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "Êîíñòðóêòîð ñïèñêà íå äîïóñêàåò êëþ÷åâûå ñëîâà êàê àðãóìåíòû"
-
-#~ msgid "list index out of range"
-#~ msgstr "Èíäåêñ ñïèñêà çà ïðåäåëàìè äèàïàçîíà"
-
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "Âíóòðåííÿÿ îøèáêà: íå óäàëîñü ïîëó÷èòü ýëåìåíò VIM-ñïèñêà %d"
-
-#~ msgid "failed to add item to list"
-#~ msgstr "Íåâîçìîæíî äîáàâèòü ýëåìåíò â ñïèñîê"
-
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "Âíóòðåííÿÿ îøèáêà: íåò ýëåìåíòà VIM-ñïèñêà %d"
-
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "Âíóòðåííÿÿ îøèáêà: íå óäàëîñü äîáàâèòü ýëåìåíò â ñïèñîê"
-
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "Íåâîçìîæíî óäàëèòü àòðèáóòû vim.List"
-
-#~ msgid "cannot modify fixed list"
-#~ msgstr "Íåâîçìîæíî èçìåíèòü ôèêñèðîâàííûé ñïèñîê"
-
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "Íå ñóùåñòâóåò áåçûìÿííîé ôóíêöèè %s"
-
-#~ msgid "function %s does not exist"
-#~ msgstr "Ôóíêöèÿ %s íå ñóùåñòâóåò"
-
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "Êîíñòðóêòîð ôóíêöèè íå äîïóñêàåò êëþ÷åâûå ñëîâà êàê àðãóìåíòû"
-
-#~ msgid "failed to run function %s"
-#~ msgstr "Íåâîçìîæíî âûïîëíèòü ôóíêöèþ %s"
-
-#~ msgid "problem while switching windows"
-#~ msgstr "Ïðîáëåìà ïðè ïåðåêëþ÷åíèè îêîí"
-
-#~ msgid "unable to unset global option %s"
-#~ msgstr "Íåâîçìîæíî ñáðîñèòü ãëîáàëüíóþ îïöèþ %s"
-
-#~ msgid "unable to unset option %s which does not have global value"
-#~ msgstr "Íåâîçìîæíî ñáðîñèòü îïöèþ %s áåç ãëîáàëüíîãî çíà÷åíèÿ"
-
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "Ïîïûòêà ñîñëàòüñÿ íà óäàë¸ííóþ âêëàäêó"
-
-#~ msgid "no such tab page"
-#~ msgstr "Íåò òàêîé âêëàäêè"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "Ïîïûòêà ñîñëàòüñÿ íà çàêðûòîå îêíî"
-
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "Àòðèáóò òîëüêî äëÿ ÷òåíèÿ: áóôåð"
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "Ïîçèöèÿ êóðñîðà íàõîäèòñÿ âíå áóôåðà"
-
-#~ msgid "no such window"
-#~ msgstr "Íåò òàêîãî îêíà"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "Ïîïûòêà ñîñëàòüñÿ íà óíè÷òîæåííûé áóôåð"
-
-#~ msgid "failed to rename buffer"
-#~ msgstr "Íåâîçìîæíî ïåðåèìåíîâàòü áóôåð"
-
-#~ msgid "mark name must be a single character"
-#~ msgstr "Íàçâàíèå îòìåòêè äîëæíî áûòü îäíèì ñèìâîëîì"
-
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "Îæèäàëñÿ îáúåêò vim.Buffer, íî ïîëó÷åí %s"
-
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "Íåâîçìîæíî ïåðåêëþ÷èòüñÿ íà áóôåð %d"
-
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "Îæèäàëñÿ îáúåêò vim.Window, íî ïîëó÷åí %s"
-
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "Íåâîçìîæíî íàéòè îêíî â òåêóùåé âêëàäêå"
-
-#~ msgid "did not switch to the specified window"
-#~ msgstr "Íåâîçìîæíî ïåðåêëþ÷èòüñÿ íà óêàçàííîå îêíî"
-
-#~ msgid "expected vim.TabPage object, but got %s"
-#~ msgstr "Îæèäàëñÿ îáúåêò vim.TabPage, íî ïîëó÷åí %s"
-
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "Íåâîçìîæíî ïåðåêëþ÷èòüñÿ íà óêàçàííóþ âêëàäêó"
-
-#~ msgid "failed to run the code"
-#~ msgstr "Íåâîçìîæíî âûïîëíèòü êîä"
-
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: Eval íå âîçâðàòèë äîïóñòèìîãî îáúåêòà Python"
-
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr ""
-#~ "E859: Íå óäàëîñü ïðåîáðàçîâàòü âîçâðàù¸ííûé îáúåêò Python â çíà÷åíèå VIM"
-
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "Íåâîçìîæíî ïðåîáðàçîâàòü %s â ñëîâàðü VIM"
-
-#~ msgid "unable to convert %s to vim structure"
-#~ msgstr "Íåâîçìîæíî ïðåîáðàçîâàòü %s â ñòðóêòóðó VIM"
-
-#~ msgid "internal error: NULL reference passed"
-#~ msgstr "Âíóòðåííÿÿ îøèáêà: ïåðåäàíà ññûëêà íà NULL"
-
-#~ msgid "internal error: invalid value type"
-#~ msgstr "Âíóòðåííÿÿ îøèáêà: íåïðàâèëüíûé òèï çíà÷åíèÿ"
-
-#~ msgid ""
-#~ "Failed to set path hook: sys.path_hooks is not a list\n"
-#~ "You should now do the following:\n"
-#~ "- append vim.path_hook to sys.path_hooks\n"
-#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
-#~ msgstr ""
-#~ "Îøèáêà ïðè óñòàíîâêå ïåðåõâàò÷èêà ïóòè: sys.path_hooks íå ÿâëÿåòñÿ "
-#~ "ñïèñêîì\n"
-#~ "Ñëåäóåò ñäåëàòü ñëåäóþùåå:\n"
-#~ "— Äîáàâèòü vim.path_hook â sys.path_hooks\n"
-#~ "— Äîáàâèòü vim.VIM_SPECIAL_PATH â sys.path\n"
-
-#~ msgid ""
-#~ "Failed to set path: sys.path is not a list\n"
-#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
-#~ msgstr ""
-#~ "Îøèáêà ïðè óñòàíîâêå ïóòè: sys.path íå ÿâëÿåòñÿ ñïèñêîì\n"
-#~ "Ñëåäóåò äîáàâèòü vim.VIM_SPECIAL_PATH â sys.path"
-
-#~ msgid ""
-#~ "E887: Sorry, this command is disabled, the Python's site module could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E887: Ê ñîæàëåíèþ ýòà êîìàíäà íå ðàáîòàåò, ïîñêîëüêó íå çàãðóæåí ìîäóëü "
-#~ "Python site."
diff --git a/src/nvim/po/ru.po b/src/nvim/po/ru.po
index c8146e8c47..e5be489d72 100644
--- a/src/nvim/po/ru.po
+++ b/src/nvim/po/ru.po
@@ -2458,7 +2458,7 @@ msgstr "E216: ÐеÑущеÑÑ‚Ð²ÑƒÑŽÑ‰Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð° или Ñобытие: %
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Ðвтокоманды ---"
@@ -2482,7 +2482,7 @@ msgstr "E218: Ñлишком глубоко вложенные автокомаÐ
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Ðвтокоманды Ð´Ð»Ñ \"%s\""
#: ../fileio.c:7149
@@ -2676,11 +2676,6 @@ msgstr "E49: ÐедопуÑтимый размер прокрутки"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3381,14 +3376,13 @@ msgstr "-t метка редактирование файла Ñ ÑƒÐºÐ°Ð·Ð°Ð½
#: ../main.c:2181
msgid "-q [errorfile] edit file with first error"
msgstr ""
-"-q [файл-ошибок]\n"
-"\t\t\t\t редактирование файла Ñ Ð¿ÐµÑ€Ð²Ð¾Ð¹ ошибкой"
+"-q [файл-ошибок] редактирование файла Ñ Ð¿ÐµÑ€Ð²Ð¾Ð¹ ошибкой"
#: ../main.c:2187
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -3484,8 +3478,8 @@ msgstr "-N\t\t\tРежим неполной ÑовмеÑтимоÑти Ñ Vi: 'n
#: ../main.c:2215
msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
msgstr ""
-"-V[N][файл]\t\tВыводить дополнительные ÑообщениÑ\n"
-"\t\t\t\t[уровень N] [запиÑывать в файл]"
+"-V[N][файл]\t\tВыводить дополнительные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ "
+"[уровень N] [запиÑывать в файл]"
#: ../main.c:2216
msgid "-D\t\t\tDebugging mode"
@@ -4110,7 +4104,6 @@ msgstr ""
#: ../memline.c:3245
msgid " Quit, or continue with caution.\n"
msgstr ""
-" \n"
" Завершите работу или продолжайте Ñ Ð¾ÑторожноÑтью.\n"
#: ../memline.c:3246
@@ -4281,12 +4274,6 @@ msgstr "Ñтрока %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: ÐедопуÑтимое Ð¸Ð¼Ñ Ñ€ÐµÐ³Ð¸Ñтра: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr ""
-"Перевод Ñообщений на руÑÑкий Ñзык: ВаÑилий Рагозин <vrr@users.sourceforge."
-"net>, Сергей Ðлёшин <alyoshin.s@gmail.com>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Прерывание: "
@@ -5115,7 +5102,7 @@ msgstr "E876: (рег. выражение ÐКÐ) недоÑтаточно меÑ
#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
+"Could not open temporary log file for writing, displaying on stderr... "
msgstr ""
"Ðевозможно открыть файл временного журнала Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи, вывод на stderr..."
@@ -5358,8 +5345,8 @@ msgstr "Предупреждение: регион %s не поддерживаÐ
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Чтение файла аффикÑов %s ..."
+msgid "Reading affix file %s..."
+msgstr "Чтение файла аффикÑов %s..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
@@ -5522,8 +5509,8 @@ msgstr "%s имеет другое значение, чем в файле .aff"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Чтение файла ÑÐ»Ð¾Ð²Ð°Ñ€Ñ %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Чтение файла ÑÐ»Ð¾Ð²Ð°Ñ€Ñ %s..."
#: ../spell.c:5611
#, c-format
@@ -5557,8 +5544,8 @@ msgstr "Пропущено %d Ñлов Ñ Ð½Ðµ ASCII Ñимволами в %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Чтение файла Ñлов %s ..."
+msgid "Reading word file %s..."
+msgstr "Чтение файла Ñлов %s..."
#: ../spell.c:6155
#, c-format
@@ -5627,7 +5614,7 @@ msgstr "Общее количеÑтво Ñлов: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
+msgid "Writing suggestion file %s..."
msgstr "ЗапиÑÑŒ файла Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸Ñправлений правопиÑÐ°Ð½Ð¸Ñ %s"
#: ../spell.c:7707 ../spell.c:7927
@@ -5654,8 +5641,8 @@ msgstr "Предупреждение: оба ÑоÑтавные и указанÐ
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "ЗапиÑÑŒ файла правопиÑÐ°Ð½Ð¸Ñ %s ..."
+msgid "Writing spell file %s..."
+msgstr "ЗапиÑÑŒ файла правопиÑÐ°Ð½Ð¸Ñ %s..."
#: ../spell.c:7925
msgid "Done!"
diff --git a/src/nvim/po/sjiscorr.c b/src/nvim/po/sjiscorr.c
deleted file mode 100644
index ebcbe16dee..0000000000
--- a/src/nvim/po/sjiscorr.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// Simplistic program to correct SJIS inside strings.
-// When a trail byte is a backslash it needs to be doubled.
-// Public domain.
-
-#include <stdio.h>
-#include <string.h>
-
-int main(int argc, char **argv)
-{
- char buffer[BUFSIZ];
- char *p;
-
- while (fgets(buffer, BUFSIZ, stdin) != NULL)
- {
- for (p = buffer; *p != 0; p++)
- {
- if (strncmp(p, "charset=utf-8", 13) == 0)
- {
- fputs("charset=cp932", stdout);
- p += 12;
- }
- else if (strncmp(p, "# Original translations", 23) == 0)
- {
- fputs("# generated from ja.po, DO NOT EDIT", stdout);
- while (p[1] != '\n')
- ++p;
- }
- else if (*(unsigned char *)p == 0x81 && p[1] == '_')
- {
- putchar('\\');
- ++p;
- }
- else
- {
- if (*p & 0x80)
- {
- putchar(*p++);
- if (*p == '\\')
- putchar(*p);
- }
- putchar(*p);
- }
- }
- }
-}
diff --git a/src/nvim/po/sk.cp1250.po b/src/nvim/po/sk.cp1250.po
index e3b7508cdc..74b8e1039c 100644
--- a/src/nvim/po/sk.cp1250.po
+++ b/src/nvim/po/sk.cp1250.po
@@ -2472,7 +2472,7 @@ msgstr "E216: Udalos alebo skupina %s neexistuje"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Automatické príkazy ---"
@@ -2496,7 +2496,7 @@ msgstr "E218: vnorenia automatického príkazu sú príliš hlboké"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Automatické príkazy pre \"%s\""
#: ../fileio.c:7149
@@ -2689,11 +2689,6 @@ msgstr "E49: Chybná hodnota ve¾kosti rolovania"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3395,7 +3390,7 @@ msgstr "-q [chybový súbor] upravi súbor na mieste výskytu prvej chyby"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -3875,6 +3870,7 @@ msgid ""
"You may want to delete the .swp file now.\n"
"\n"
msgstr "Potom vymažte odkladací súbor s príponou .swp.\n"
+"\n"
#. use msg() to start the scrolling properly
#: ../memline.c:1327
@@ -4273,10 +4269,6 @@ msgstr "riadok %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: '%s' nie je prístupné meno registru"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Správca prekladu: Lubomir Host <rajo@platon.sk>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Prerušenie: "
@@ -5322,8 +5314,8 @@ msgstr "Varovanie: región %s nie je podporovaný"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Naèítavam súbor s príponami %s ..."
+msgid "Reading affix file %s..."
+msgstr "Naèítavam súbor s príponami %s..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
@@ -5481,8 +5473,8 @@ msgstr "Hodnota %s sa odlišuje od hodnoty použitej v inom .aff súbore"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Naèítavam slovník %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Naèítavam slovník %s..."
#: ../spell.c:5611
#, c-format
@@ -5516,8 +5508,8 @@ msgstr "Ignorovaných %d slov s nepísmennými znakmi v %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Naèítavam súbor so slovami %s ..."
+msgid "Reading word file %s..."
+msgstr "Naèítavam súbor so slovami %s..."
#: ../spell.c:6155
#, c-format
@@ -5614,8 +5606,8 @@ msgstr "Varovanie: špecifikované spájanie a nezalamovanie"
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Ukládám slovníkový súbor %s ..."
+msgid "Writing spell file %s..."
+msgstr "Ukládám slovníkový súbor %s..."
#: ../spell.c:7925
msgid "Done!"
diff --git a/src/nvim/po/sk.po b/src/nvim/po/sk.po
index 53f8a7b911..d3f954f6d8 100644
--- a/src/nvim/po/sk.po
+++ b/src/nvim/po/sk.po
@@ -2472,7 +2472,7 @@ msgstr "E216: Udalos» alebo skupina %s neexistuje"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Automatické príkazy ---"
@@ -2496,7 +2496,7 @@ msgstr "E218: vnorenia automatického príkazu sú príli¹ hlboké"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Automatické príkazy pre \"%s\""
#: ../fileio.c:7149
@@ -2689,11 +2689,6 @@ msgstr "E49: Chybná hodnota veµkosti rolovania"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3395,7 +3390,7 @@ msgstr "-q [chybový súbor] upravi» súbor na mieste výskytu prvej chyby"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -3875,6 +3870,7 @@ msgid ""
"You may want to delete the .swp file now.\n"
"\n"
msgstr "Potom vyma¾te odkladací súbor s príponou .swp.\n"
+"\n"
#. use msg() to start the scrolling properly
#: ../memline.c:1327
@@ -4273,10 +4269,6 @@ msgstr "riadok %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: '%s' nie je prístupné meno registru"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Správca prekladu: Lubomir Host <rajo@platon.sk>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Preru¹enie: "
@@ -5322,8 +5314,8 @@ msgstr "Varovanie: región %s nie je podporovaný"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Naèítavam súbor s príponami %s ..."
+msgid "Reading affix file %s..."
+msgstr "Naèítavam súbor s príponami %s..."
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
@@ -5481,8 +5473,8 @@ msgstr "Hodnota %s sa odli¹uje od hodnoty pou¾itej v inom .aff súbore"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Naèítavam slovník %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Naèítavam slovník %s..."
#: ../spell.c:5611
#, c-format
@@ -5516,8 +5508,8 @@ msgstr "Ignorovaných %d slov s nepísmennými znakmi v %s"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Naèítavam súbor so slovami %s ..."
+msgid "Reading word file %s..."
+msgstr "Naèítavam súbor so slovami %s..."
#: ../spell.c:6155
#, c-format
@@ -5614,8 +5606,8 @@ msgstr "Varovanie: ¹pecifikované spájanie a nezalamovanie"
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Ukládám slovníkový súbor %s ..."
+msgid "Writing spell file %s..."
+msgstr "Ukládám slovníkový súbor %s..."
#: ../spell.c:7925
msgid "Done!"
diff --git a/src/nvim/po/sr.po b/src/nvim/po/sr.po
new file mode 100644
index 0000000000..88c5d18866
--- /dev/null
+++ b/src/nvim/po/sr.po
@@ -0,0 +1,7115 @@
+# Serbian Cyrillic translation for Vim
+#
+# Do ":help uganda" in Vim to read copying and usage conditions.
+# Do ":help credits" in Vim to see a list of people who contributed.
+# Copyright (C) 2017
+# This file is distributed under the same license as the Vim package.
+# FIRST AUTHOR Ivan Pešić <ivan.pesic@gmail.com>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Vim(Serbian)\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2018-05-15 11:55+0400\n"
+"PO-Revision-Date: 2018-05-15 10:50+0400\n"
+"Last-Translator: Ivan Pešić <ivan.pesic@gmail.com>\n"
+"Language-Team: Serbian\n"
+"Language: sr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgid "E831: bf_key_init() called with empty password"
+msgstr "E831: bf_key_init() је позвана Ñа празном лозинком"
+
+msgid "E820: sizeof(uint32_t) != 4"
+msgstr "E820: sizeof(uint32_t) != 4"
+
+msgid "E817: Blowfish big/little endian use wrong"
+msgstr "E817: Blowfish употреба big/little endian је погрешна"
+
+msgid "E818: sha256 test failed"
+msgstr "E818: sha256 теÑÑ‚ није уÑпео"
+
+msgid "E819: Blowfish test failed"
+msgstr "E819: Blowfish теÑÑ‚ није уÑпео"
+
+msgid "[Location List]"
+msgstr "[ЛиÑта локација]"
+
+msgid "[Quickfix List]"
+msgstr "[Quickfix лиÑта]"
+
+msgid "E855: Autocommands caused command to abort"
+msgstr "E855: Ðутокоманде Ñу изазвале прекид команде"
+
+msgid "E82: Cannot allocate any buffer, exiting..."
+msgstr "E82: Ðе може да Ñе резервише меморија ни за један бафер, излазак..."
+
+msgid "E83: Cannot allocate buffer, using other one..."
+msgstr "E83: Ðе може да Ñе резервише меморија за бафер, кориÑти Ñе други..."
+
+msgid "E931: Buffer cannot be registered"
+msgstr "E931: Бафер не може да Ñе региÑтрује"
+
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Покушај бриÑања бафера који је у употреби"
+
+msgid "E515: No buffers were unloaded"
+msgstr "E515: Ðиједан бафер није уклоњен из меморије"
+
+msgid "E516: No buffers were deleted"
+msgstr "E516: Ðиједан бафер није обриÑан"
+
+msgid "E517: No buffers were wiped out"
+msgstr "E517: Ðиједан бафер није очишћен"
+
+msgid "1 buffer unloaded"
+msgstr "1 бафер је уклоњен из меморије"
+
+#, c-format
+msgid "%d buffers unloaded"
+msgstr "%d бафера је уклоњено из меморије"
+
+msgid "1 buffer deleted"
+msgstr "1 бафер је обриÑан"
+
+#, c-format
+msgid "%d buffers deleted"
+msgstr "%d бафера је обриÑано"
+
+msgid "1 buffer wiped out"
+msgstr "1 бафер је очишћен"
+
+#, c-format
+msgid "%d buffers wiped out"
+msgstr "%d бафера је очишћено"
+
+msgid "E90: Cannot unload last buffer"
+msgstr "E90: ПоÑледњи бафер не може да Ñе уклони из меморије"
+
+msgid "E84: No modified buffer found"
+msgstr "E84: Ðије пронађен измењени бафер"
+
+msgid "E85: There is no listed buffer"
+msgstr "E85: Ðема бафера на лиÑти"
+
+msgid "E87: Cannot go beyond last buffer"
+msgstr "E87: Ðе може да Ñе иде иза поÑледњег бафера"
+
+msgid "E88: Cannot go before first buffer"
+msgstr "E88: Ðе може да Ñе иде иÑпред првог бафера"
+
+#, c-format
+msgid "E89: No write since last change for buffer %ld (add ! to override)"
+msgstr ""
+"E89: Од поÑледње измене није било упиÑа за бафер %ld (додајте ! да "
+"премоÑтите)"
+
+msgid "E948: Job still running (add ! to end the job)"
+msgstr "E948: Задатак Ñе још извршава (додајте ! да зауÑтавите задатак)"
+
+msgid "E37: No write since last change (add ! to override)"
+msgstr "E37: Ðије било упиÑа од поÑледње промене (додајте ! да премоÑтите)"
+
+msgid "E948: Job still running"
+msgstr "E948: Задатак Ñе и даље извршава"
+
+msgid "E37: No write since last change"
+msgstr "E37: Ðије било упиÑа од поÑледње промене"
+
+msgid "W14: Warning: List of file names overflow"
+msgstr ""
+"W14: Упозорење: Прекорачена је макÑимална величина лиÑте имена датотека"
+
+#, c-format
+msgid "E92: Buffer %ld not found"
+msgstr "E92: Бафер %ld није пронађен"
+
+#, c-format
+msgid "E93: More than one match for %s"
+msgstr "E93: Више од једног подударања Ñа %s"
+
+#, c-format
+msgid "E94: No matching buffer for %s"
+msgstr "E94: Ðиједан бафер Ñе не подудара Ñа %s"
+
+#, c-format
+msgid "line %ld"
+msgstr "линија %ld"
+
+msgid "E95: Buffer with this name already exists"
+msgstr "E95: Бафер Ñа овим именом већ поÑтоји"
+
+msgid " [Modified]"
+msgstr "[Измењено]"
+
+msgid "[Not edited]"
+msgstr "[Ðије уређивано]"
+
+msgid "[New file]"
+msgstr "[Ðова датотека]"
+
+msgid "[Read errors]"
+msgstr "[Грешке при читању]"
+
+msgid "[RO]"
+msgstr "[СЧ]"
+
+msgid "[readonly]"
+msgstr "[Ñамо за читање]"
+
+#, c-format
+msgid "1 line --%d%%--"
+msgstr "1 линија --%d%%--"
+
+#, c-format
+msgid "%ld lines --%d%%--"
+msgstr "%ld линија --%d%%--"
+
+#, c-format
+msgid "line %ld of %ld --%d%%-- col "
+msgstr "линија %ld од %ld --%d%%-- кол "
+
+msgid "[No Name]"
+msgstr "[Без имена]"
+
+msgid "help"
+msgstr "помоћ"
+
+msgid "[Help]"
+msgstr "[Помоћ]"
+
+msgid "[Preview]"
+msgstr "[Преглед]"
+
+msgid "All"
+msgstr "Све"
+
+msgid "Bot"
+msgstr "Дно"
+
+msgid "Top"
+msgstr "Врх"
+
+msgid ""
+"\n"
+"# Buffer list:\n"
+msgstr ""
+"\n"
+"# ЛиÑта бафера:\n"
+
+msgid "E382: Cannot write, 'buftype' option is set"
+msgstr "E382: Ð£Ð¿Ð¸Ñ Ð½Ð¸Ñ˜Ðµ могућ, поÑтављена је 'buftype' опција"
+
+msgid "[Scratch]"
+msgstr "[Празно]"
+
+msgid ""
+"\n"
+"--- Signs ---"
+msgstr ""
+"\n"
+"--- Знаци ---"
+
+#, c-format
+msgid "Signs for %s:"
+msgstr "Знаци за %s:"
+
+#, c-format
+msgid " line=%ld id=%d name=%s"
+msgstr " линија=%ld ид=%d име=%s"
+
+msgid "E902: Cannot connect to port"
+msgstr "E902: Повезивање на порт није могуће"
+
+msgid "E901: gethostbyname() in channel_open()"
+msgstr "E901: gethostbyname() у channel_open()"
+
+msgid "E898: socket() in channel_open()"
+msgstr "E898: socket() у channel_open()"
+
+msgid "E903: received command with non-string argument"
+msgstr "E903: примњена команда Ñа аргуменом који није Ñтринг"
+
+msgid "E904: last argument for expr/call must be a number"
+msgstr "E904: поÑледњи аргумент за expr/call мора бити број"
+
+msgid "E904: third argument for call must be a list"
+msgstr "E904: трећи аргумент за call мора бити лиÑта"
+
+#, c-format
+msgid "E905: received unknown command: %s"
+msgstr "E905: примљена непозната команда: %s"
+
+#, c-format
+msgid "E630: %s(): write while not connected"
+msgstr "E630: %s(): ÑƒÐ¿Ð¸Ñ Ð´Ð¾Ðº није уÑпоÑтављена веза"
+
+#, c-format
+msgid "E631: %s(): write failed"
+msgstr "E631: %s(): ÑƒÐ¿Ð¸Ñ Ð½Ð¸Ñ˜Ðµ уÑпео"
+
+#, c-format
+msgid "E917: Cannot use a callback with %s()"
+msgstr "E917: Callback не може да Ñе кориÑти Ñа %s()"
+
+msgid "E912: cannot use ch_evalexpr()/ch_sendexpr() with a raw or nl channel"
+msgstr ""
+"E912: ch_evalexpr()/ch_sendexpr() не може да Ñе кориÑти Ñа raw или nl каналом"
+
+msgid "E906: not an open channel"
+msgstr "E906: није отворен канал"
+
+msgid "E920: _io file requires _name to be set"
+msgstr "E920: _io датотека захтева да _name буде поÑтављено"
+
+msgid "E915: in_io buffer requires in_buf or in_name to be set"
+msgstr "E915: in_io бафер захтева да in_buf или in_name буде поÑтављено"
+
+#, c-format
+msgid "E918: buffer must be loaded: %s"
+msgstr "E918: бафер мора бити учитан: %s"
+
+msgid "E821: File is encrypted with unknown method"
+msgstr "E821: Датотека је шифрована непознатом методом"
+
+msgid "Warning: Using a weak encryption method; see :help 'cm'"
+msgstr "Упозорење: КориÑти Ñе Ñлаба метода шифрирања; погледајте :help 'cm'"
+
+msgid "Enter encryption key: "
+msgstr "УнеÑите кључ за шифрирање: "
+
+msgid "Enter same key again: "
+msgstr "УнеÑите иÑти кључ поново: "
+
+msgid "Keys don't match!"
+msgstr "Кључеви ниÑу иÑти!"
+
+msgid "[crypted]"
+msgstr "[шифровано]"
+
+#, c-format
+msgid "E720: Missing colon in Dictionary: %s"
+msgstr "E720: ÐедоÑтаје тачка-зарез у Речнику: %s"
+
+#, c-format
+msgid "E721: Duplicate key in Dictionary: \"%s\""
+msgstr "E721: Дупликат кључа у Речнику: \"%s\""
+
+#, c-format
+msgid "E722: Missing comma in Dictionary: %s"
+msgstr "E722: ÐедоÑтаје зарез у Речнику: %s"
+
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %s"
+msgstr "E723: ÐедоÑтаје крај Речника '}': %s"
+
+msgid "extend() argument"
+msgstr "extend() аргумент"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Кључ већ поÑтоји: %s"
+
+#, c-format
+msgid "E96: Cannot diff more than %ld buffers"
+msgstr "E96: Ðе може да Ñе упоређује више од %ld бафера"
+
+msgid "E810: Cannot read or write temp files"
+msgstr "E810: Ðије могуће читање или ÑƒÐ¿Ð¸Ñ Ñƒ привремене датотеке"
+
+msgid "E97: Cannot create diffs"
+msgstr "E97: Ðије могуће креирање diff-ова"
+
+msgid "Patch file"
+msgstr "Patch датотека"
+
+msgid "E816: Cannot read patch output"
+msgstr "E816: Ðије могуће читање patch излаза"
+
+msgid "E98: Cannot read diff output"
+msgstr "E98: Ðије могуће читање diff излаза"
+
+msgid "E99: Current buffer is not in diff mode"
+msgstr "E99: Текући бафер није у diff режиму"
+
+msgid "E793: No other buffer in diff mode is modifiable"
+msgstr "E793: Ðиједан други бафер у diff режиму није измењив"
+
+msgid "E100: No other buffer in diff mode"
+msgstr "E100: ниједан други бафер није у diff режиму"
+
+msgid "E101: More than two buffers in diff mode, don't know which one to use"
+msgstr "E101: Више од два бафера Ñу у diff режиму, не знам који да кориÑтим"
+
+#, c-format
+msgid "E102: Can't find buffer \"%s\""
+msgstr "E102: Бафер \"%s\" не може да Ñе пронађе"
+
+#, c-format
+msgid "E103: Buffer \"%s\" is not in diff mode"
+msgstr "E103: Бафер \"%s\" није у diff режиму"
+
+msgid "E787: Buffer changed unexpectedly"
+msgstr "E787: Бафер је неочекивано измењен"
+
+msgid "E104: Escape not allowed in digraph"
+msgstr "E104: Escape није дозвољен у digraph"
+
+msgid "E544: Keymap file not found"
+msgstr "E544: Keymap датотека није пронађена"
+
+msgid "E105: Using :loadkeymap not in a sourced file"
+msgstr "E105: Коришћење :loadkeymap ван датотеке која Ñе учитава као Ñкрипта"
+
+msgid "E791: Empty keymap entry"
+msgstr "E791: Празна keymap Ñтавка"
+
+msgid " Keyword completion (^N^P)"
+msgstr " Довршавање кључне речи (^N^P)"
+
+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)"
+
+msgid " Whole line completion (^L^N^P)"
+msgstr " Довршавање целе линије (^L^N^P)"
+
+msgid " File name completion (^F^N^P)"
+msgstr " Довршавање имена датотеке (^F^N^P)"
+
+msgid " Tag completion (^]^N^P)"
+msgstr " Довршавање ознаке (^]^N^P)"
+
+msgid " Path pattern completion (^N^P)"
+msgstr " Довршавање шаблона путање (^N^P)"
+
+msgid " Definition completion (^D^N^P)"
+msgstr " Довршавање дефиниције (^D^N^P)"
+
+msgid " Dictionary completion (^K^N^P)"
+msgstr " Довршавање речника (^K^N^P)"
+
+msgid " Thesaurus completion (^T^N^P)"
+msgstr " Довршавање речника Ñинонима (^T^N^P)"
+
+msgid " Command-line completion (^V^N^P)"
+msgstr " Довршавање командне линије (^V^N^P)"
+
+msgid " User defined completion (^U^N^P)"
+msgstr " КориÑнички дефиниÑано довршавање (^U^N^P)"
+
+msgid " Omni completion (^O^N^P)"
+msgstr " Omni довршавање (^O^N^P)"
+
+msgid " Spelling suggestion (s^N^P)"
+msgstr " ПравопиÑни предлог (s^N^P)"
+
+msgid " Keyword Local completion (^N^P)"
+msgstr " Довршавање локалне кључне речи (^N^P)"
+
+msgid "Hit end of paragraph"
+msgstr "ДоÑтигнут крај паÑуÑа"
+
+msgid "E839: Completion function changed window"
+msgstr "E839: Функција довршавања је променила прозор"
+
+msgid "E840: Completion function deleted text"
+msgstr "E840: Функција довршавања је обриÑала текÑÑ‚"
+
+msgid "'dictionary' option is empty"
+msgstr "Опција 'dictionary' је празна"
+
+msgid "'thesaurus' option is empty"
+msgstr "Опција 'thesaurus' је празна"
+
+#, c-format
+msgid "Scanning dictionary: %s"
+msgstr "Скенирање речника: %s"
+
+msgid " (insert) Scroll (^E/^Y)"
+msgstr " (уметање) Скроловање (^E/^Y)"
+
+msgid " (replace) Scroll (^E/^Y)"
+msgstr " (замена) Скроловање (^E/^Y)"
+
+#, c-format
+msgid "Scanning: %s"
+msgstr "Скенирање: %s"
+
+msgid "Scanning tags."
+msgstr "Скенирање ознака."
+
+msgid "match in file"
+msgstr "подударање у датотеци"
+
+msgid " Adding"
+msgstr " Додавање"
+
+msgid "-- Searching..."
+msgstr "-- Претрага..."
+
+msgid "Back at original"
+msgstr "Ðазад на оригинал"
+
+msgid "Word from other line"
+msgstr "Реч из друге линије"
+
+msgid "The only match"
+msgstr "Једино подударање"
+
+#, c-format
+msgid "match %d of %d"
+msgstr "подударање %d од %d"
+
+#, c-format
+msgid "match %d"
+msgstr "подударање %d"
+
+msgid "E18: Unexpected characters in :let"
+msgstr "E18: Ðеочекивани карактери у :let"
+
+#, c-format
+msgid "E121: Undefined variable: %s"
+msgstr "E121: ÐедефиниÑана променљива: %s"
+
+msgid "E111: Missing ']'"
+msgstr "E111: ÐедоÑтаје ']'"
+
+msgid "E719: Cannot use [:] with a Dictionary"
+msgstr "E719: Ðе може да Ñе кориÑти [:] Ñа Речником"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Погрешан тип променљиве за %s="
+
+#, c-format
+msgid "E461: Illegal variable name: %s"
+msgstr "E461: Ðедозвољено име променљиве: %s"
+
+msgid "E806: using Float as a String"
+msgstr "E806: коришћење Float као String"
+
+msgid "E687: Less targets than List items"
+msgstr "E687: Мање одредишта него Ñтавки ЛиÑте"
+
+msgid "E688: More targets than List items"
+msgstr "E688: Више одредишта него Ñтавки ЛиÑте"
+
+msgid "Double ; in list of variables"
+msgstr "Дупле ; у лиÑти променљивих"
+
+#, c-format
+msgid "E738: Can't list variables for %s"
+msgstr "E738: Ðе може да Ñе прикаже лиÑта променљивих за %s"
+
+msgid "E689: Can only index a List or Dictionary"
+msgstr "E689: Само ЛиÑта или Речник могу да Ñе индекÑирају"
+
+msgid "E708: [:] must come last"
+msgstr "E708: [:] мора да буде поÑледња"
+
+msgid "E709: [:] requires a List value"
+msgstr "E709: [:] захтева вредноÑÑ‚ типа List"
+
+msgid "E710: List value has more items than target"
+msgstr "E710: ВредноÑÑ‚ типа List има више Ñтавки него одредиште"
+
+msgid "E711: List value has not enough items"
+msgstr "E711: ВредноÑÑ‚ типа List нема довољно Ñтавки"
+
+msgid "E690: Missing \"in\" after :for"
+msgstr "E690: ÐедоÑтаје \"in\" након :for"
+
+#, c-format
+msgid "E108: No such variable: \"%s\""
+msgstr "E108: Ðе поÑтоји таква променљива: \"%s\""
+
+#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: Ðе може да Ñе откључа или закључа променљива %s"
+
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: променљива је угњеждена Ñувише дубоко да би Ñе за(от)кључала"
+
+msgid "E109: Missing ':' after '?'"
+msgstr "E109: ÐедоÑтаје ':' након '?'"
+
+msgid "E804: Cannot use '%' with Float"
+msgstr "E804: '%' не може да Ñе кориÑти Ñа Float"
+
+msgid "E110: Missing ')'"
+msgstr "E110: ÐедоÑтаје ')'"
+
+msgid "E695: Cannot index a Funcref"
+msgstr "E695: Funcref не може да Ñе индекÑира"
+
+msgid "E909: Cannot index a special variable"
+msgstr "E909: Специјална променљива не може да Ñе индекÑира"
+
+#, c-format
+msgid "E112: Option name missing: %s"
+msgstr "E112: ÐедоÑтаје име опције: %s"
+
+#, c-format
+msgid "E113: Unknown option: %s"
+msgstr "E113: Ðепозната опција: %s"
+
+#, c-format
+msgid "E114: Missing quote: %s"
+msgstr "E114: ÐедоÑтаје наводник: %s"
+
+#, c-format
+msgid "E115: Missing quote: %s"
+msgstr "E115: ÐедоÑтаје наводник: %s"
+
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"Ðема довољно меморије за поÑтављање референци, прекинуто је Ñкупљање отпада"
+
+msgid "E724: variable nested too deep for displaying"
+msgstr "E724: променљива је угњеждена предубоко да би Ñе приказала"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: КориÑти Ñе Float као Number"
+
+msgid "E703: Using a Funcref as a Number"
+msgstr "E703: КориÑти Ñе Funcref као Number"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: КориÑти Ñе List као Number"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: КориÑти Ñе Dictionary као Number"
+
+msgid "E910: Using a Job as a Number"
+msgstr "E910: КориÑти Ñе Job као Number"
+
+msgid "E913: Using a Channel as a Number"
+msgstr "E913: КориÑти Ñе Channel као Number"
+
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: КориÑти Ñе Funcref као Float"
+
+msgid "E892: Using a String as a Float"
+msgstr "E892: КориÑти Ñе String као Float"
+
+msgid "E893: Using a List as a Float"
+msgstr "E893: КориÑти Ñе List као Float"
+
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: КориÑти Ñе Dictionary као Float"
+
+msgid "E907: Using a special value as a Float"
+msgstr "E907: КориÑти Ñе Ñпецијална вредноÑÑ‚ као Float"
+
+msgid "E911: Using a Job as a Float"
+msgstr "E911: КориÑти Ñе Job као Float"
+
+msgid "E914: Using a Channel as a Float"
+msgstr "E914: КориÑти Ñе Channel као Float"
+
+msgid "E729: using Funcref as a String"
+msgstr "E729: кориÑти Ñе Funcref као String"
+
+msgid "E730: using List as a String"
+msgstr "E730: кориÑти Ñе List као String"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: кориÑти Ñе Dictionary као String"
+
+msgid "E908: using an invalid value as a String"
+msgstr "E908: кориÑти Ñе недозвољена вредноÑÑ‚ као String"
+
+#, c-format
+msgid "E795: Cannot delete variable %s"
+msgstr "E795: Променљива %s не може да Ñе обрише"
+
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Име Funcref мора да почне великим Ñловом: %s"
+
+#, c-format
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Име променљиве је у конфликту Ñа поÑтојећом функцијом: %s"
+
+#, c-format
+msgid "E741: Value is locked: %s"
+msgstr "E741: ВредноÑÑ‚ је закључана: %s"
+
+msgid "Unknown"
+msgstr "Ðепознато"
+
+#, c-format
+msgid "E742: Cannot change value of %s"
+msgstr "E742: ВредноÑÑ‚ %s не може да Ñе промени"
+
+msgid "E698: variable nested too deep for making a copy"
+msgstr "E698: променљива је предубоко угњеждена да би Ñе направила копија"
+
+msgid ""
+"\n"
+"# global variables:\n"
+msgstr ""
+"\n"
+"# глобалне променљиве:\n"
+
+msgid ""
+"\n"
+"\tLast set from "
+msgstr ""
+"\n"
+"\tПоÑледњи Ñет од "
+
+msgid "E691: Can only compare List with List"
+msgstr "E691: List може да Ñе пореди Ñамо Ñа List"
+
+msgid "E692: Invalid operation for List"
+msgstr "E692: ÐеиÑправна операција за List"
+
+msgid "E735: Can only compare Dictionary with Dictionary"
+msgstr "E735: Dictionary може да Ñе пореди Ñамо Ñа Dictionary"
+
+msgid "E736: Invalid operation for Dictionary"
+msgstr "E736: ÐеиÑправна операција за Dictionary"
+
+msgid "E694: Invalid operation for Funcrefs"
+msgstr "E694: ÐеиÑправна операција за Funcrefs"
+
+msgid "map() argument"
+msgstr "map() аргумент"
+
+msgid "filter() argument"
+msgstr "filter() аргумент"
+
+#, c-format
+msgid "E686: Argument of %s must be a List"
+msgstr "E686: Ðргумент за %s мора бити List"
+
+msgid "E928: String required"
+msgstr "E928: Захтева Ñе String"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Захтева Ñе Number или Float"
+
+msgid "add() argument"
+msgstr "add() аргумент"
+
+msgid "E785: complete() can only be used in Insert mode"
+msgstr "E785: complete() може да Ñе кориÑти Ñамо у режиму Уметање"
+
+msgid "&Ok"
+msgstr "&Ок"
+
+#, c-format
+msgid "+-%s%3ld line: "
+msgid_plural "+-%s%3ld lines: "
+msgstr[0] "+-%s%3ld линија: "
+msgstr[1] "+-%s%3ld линија: "
+
+#, c-format
+msgid "E700: Unknown function: %s"
+msgstr "E700: Ðепозната функција: %s"
+
+msgid "E922: expected a dict"
+msgstr "E922: очекивао Ñе dict"
+
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: Други аргумент function() мора бити list или dict"
+
+msgid ""
+"&OK\n"
+"&Cancel"
+msgstr ""
+"&OK\n"
+"О&ткажи"
+
+msgid "called inputrestore() more often than inputsave()"
+msgstr "inputrestore() је позвана више пута него inputsave()"
+
+msgid "insert() argument"
+msgstr "insert() аргумент"
+
+msgid "E786: Range not allowed"
+msgstr "E786: ОпÑег није дозвољен"
+
+msgid "E916: not a valid job"
+msgstr "E916: није валидан job"
+
+msgid "E701: Invalid type for len()"
+msgstr "E701: ÐеиÑправан тип за len()"
+
+#, c-format
+msgid "E798: ID is reserved for \":match\": %ld"
+msgstr "E798: ИД је резервиÑан за \":match\": %ld"
+
+msgid "E726: Stride is zero"
+msgstr "E726: Корак је нула"
+
+msgid "E727: Start past end"
+msgstr "E727: Почетак иза краја"
+
+msgid "<empty>"
+msgstr "<празно>"
+
+msgid "E240: No connection to the X server"
+msgstr "E240: Ðема везе Ñа X Ñервером"
+
+#, c-format
+msgid "E241: Unable to send to %s"
+msgstr "E241: Слање ка %s није могуће"
+
+msgid "E277: Unable to read a server reply"
+msgstr "E277: Ðе може да Ñе прочита одговор Ñервера"
+
+msgid "E941: already started a server"
+msgstr "E941: Ñервер је већ покренут"
+
+msgid "E942: +clientserver feature not available"
+msgstr "E942: МогућноÑÑ‚ +clientserver није доÑтупна"
+
+msgid "remove() argument"
+msgstr "remove() аргумент"
+
+msgid "E655: Too many symbolic links (cycle?)"
+msgstr "E655: Превише Ñимболичких веза (циклуÑ?)"
+
+msgid "reverse() argument"
+msgstr "reverse() аргумент"
+
+msgid "E258: Unable to send to client"
+msgstr "E258: Слање ка клијенту није могуће"
+
+#, c-format
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: ÐеиÑправна акција: '%s'"
+
+msgid "sort() argument"
+msgstr "sort() аргумент"
+
+msgid "uniq() argument"
+msgstr "uniq() аргумент"
+
+msgid "E702: Sort compare function failed"
+msgstr "E702: Sort функција поређења није уÑпела"
+
+msgid "E882: Uniq compare function failed"
+msgstr "E882: Uniq функција поређења није уÑпела"
+
+msgid "(Invalid)"
+msgstr "(ÐеиÑправно)"
+
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: неиÑправан број подпоклапања: %d"
+
+msgid "E677: Error writing temp file"
+msgstr "E677: Грешка при упиÑу temp датотеке"
+
+msgid "E921: Invalid callback argument"
+msgstr "E921: ÐеиÑправан callback аргумент"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"
+msgstr "<%s>%s%s %d, Ð¥ÐµÐºÑ %02x, Окт %03o, Дигр %s"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, Ð¥ÐµÐºÑ %02x, Октално %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Oct %o, Digr %s"
+msgstr "> %d, Ð¥ÐµÐºÑ %04x, Окт %o, Дигр %s"
+
+#, c-format
+msgid "> %d, Hex %08x, Oct %o, Digr %s"
+msgstr "> %d, Ð¥ÐµÐºÑ %08x, Окт %o, Дигр %s"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, Ð¥ÐµÐºÑ %04x, Октално %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, Ð¥ÐµÐºÑ %08x, Октално %o"
+
+msgid "E134: Move lines into themselves"
+msgstr "E134: Премештање линија у Ñаме Ñебе"
+
+msgid "1 line moved"
+msgstr "1 линија премештена"
+
+#, c-format
+msgid "%ld lines moved"
+msgstr "%ld линија премештено"
+
+#, c-format
+msgid "%ld lines filtered"
+msgstr "%ld линија филтрирано"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: *Филтер* Ðутокоманде не Ñмеју да мењају текући бафер"
+
+msgid "[No write since last change]\n"
+msgstr "[Ðема упиÑа од поÑледње промене]\n"
+
+#, c-format
+msgid "%sviminfo: %s in line: "
+msgstr "%sviminfo: %s у линији: "
+
+msgid "E136: viminfo: Too many errors, skipping rest of file"
+msgstr "E136: viminfo: Превише грешака, оÑтатак датотеке Ñе преÑкаче"
+
+#, c-format
+msgid "Reading viminfo file \"%s\"%s%s%s"
+msgstr "Читање viminfo датотеке \"%s\"%s%s%s"
+
+msgid " info"
+msgstr " инфо"
+
+msgid " marks"
+msgstr " маркера"
+
+msgid " oldfiles"
+msgstr " Ñтарихдатотека"
+
+msgid " FAILED"
+msgstr " ÐЕУСПЕЛО"
+
+#, c-format
+msgid "E137: Viminfo file is not writable: %s"
+msgstr "E137: Viminfo датотека није упиÑива: %s"
+
+#, c-format
+msgid "E929: Too many viminfo temp files, like %s!"
+msgstr "E929: Превише viminfo temp датотека, као %s!"
+
+#, c-format
+msgid "E138: Can't write viminfo file %s!"
+msgstr "E138: Viminfo датотека %s не може да Ñе упише!"
+
+#, c-format
+msgid "Writing viminfo file \"%s\""
+msgstr "УпиÑивање viminfo датотеке \"%s\""
+
+#, c-format
+msgid "E886: Can't rename viminfo file to %s!"
+msgstr "E886: Viminfo датотека не може да Ñе преименује у %s!"
+
+#, c-format
+msgid "# This viminfo file was generated by Vim %s.\n"
+msgstr "# Ову viminfo датотеку је генериÑао Vim %s.\n"
+
+msgid ""
+"# You may edit it if you're careful!\n"
+"\n"
+msgstr ""
+"# Можете да је уређујете ако Ñте опрезни!\n"
+"\n"
+
+msgid "# Value of 'encoding' when this file was written\n"
+msgstr "# ВредноÑÑ‚ опције 'encoding' када је ова датотека напиÑана\n"
+
+msgid "Illegal starting char"
+msgstr "ÐеиÑправан почетни карактер"
+
+msgid ""
+"\n"
+"# Bar lines, copied verbatim:\n"
+msgstr ""
+"\n"
+"# Преградне линије, копиране доÑловно:\n"
+
+msgid "Save As"
+msgstr "Сачувај као"
+
+msgid "Write partial file?"
+msgstr "Да упишем парцијалну датотеку?"
+
+msgid "E140: Use ! to write partial buffer"
+msgstr "E140: КориÑтите ! да биÑте упиÑали парцијални бафер"
+
+#, c-format
+msgid "Overwrite existing file \"%s\"?"
+msgstr "Да препишем поÑтојећи датотеку \"%s\"?"
+
+#, c-format
+msgid "Swap file \"%s\" exists, overwrite anyway?"
+msgstr "Swap датотека \"%s\" поÑтоји, да је препишем у Ñваком Ñлучају?"
+
+#, c-format
+msgid "E768: Swap file exists: %s (:silent! overrides)"
+msgstr "E768: Swap датотека поÑтоји: %s (:silent! премошћава)"
+
+#, c-format
+msgid "E141: No file name for buffer %ld"
+msgstr "E141: Ðема имена датотеке за бафер %ld"
+
+msgid "E142: File not written: Writing is disabled by 'write' option"
+msgstr "E142: Датотека није упиÑана: УпиÑивање је онемогућено опцијом 'write'"
+
+#, c-format
+msgid ""
+"'readonly' option is set for \"%s\".\n"
+"Do you wish to write anyway?"
+msgstr ""
+"'readonly' опција је поÑтављена за \"%s\".\n"
+"Да ли ипак желите да упишете?"
+
+#, c-format
+msgid ""
+"File permissions of \"%s\" are read-only.\n"
+"It may still be possible to write it.\n"
+"Do you wish to try?"
+msgstr ""
+"Дозволе датотеке \"%s\" омогућавају Ñамо читање.\n"
+"Можда је ипак могуће да Ñе упише.\n"
+"Да ли желите да покушате?"
+
+#, c-format
+msgid "E505: \"%s\" is read-only (add ! to override)"
+msgstr "E505: \"%s\" је Ñамо за читање (додајте ! за премошћавање)"
+
+msgid "Edit File"
+msgstr "Уреди датотеку"
+
+#, c-format
+msgid "E143: Autocommands unexpectedly deleted new buffer %s"
+msgstr "E143: Ðутокоманде Ñу неочекивано обриÑале нов бафер %s"
+
+msgid "E144: non-numeric argument to :z"
+msgstr "E144: ненумерички аргумент за :z"
+
+msgid "E145: Shell commands not allowed in rvim"
+msgstr "E145: Shell команде ниÑу дозвољене у rvim"
+
+msgid "E146: Regular expressions can't be delimited by letters"
+msgstr "E146: Регуларни изрази не могу да Ñе раздвајају Ñловима"
+
+#, c-format
+msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
+msgstr "заменити Ñа %s (y/n/a/q/l/^E/^Y)?"
+
+msgid "(Interrupted) "
+msgstr "(Прекинуто)"
+
+msgid "1 match"
+msgstr "1 подударање"
+
+msgid "1 substitution"
+msgstr "1 замена"
+
+#, c-format
+msgid "%ld matches"
+msgstr "%ld подударања"
+
+#, c-format
+msgid "%ld substitutions"
+msgstr "%ld замена"
+
+msgid " on 1 line"
+msgstr " у 1 линији"
+
+#, c-format
+msgid " on %ld lines"
+msgstr " у %ld линија"
+
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: :global не може да Ñе изврши рекурзивно Ñа опÑегом"
+
+msgid "E148: Regular expression missing from global"
+msgstr "E148: У global недоÑтаје регуларни израз"
+
+#, c-format
+msgid "Pattern found in every line: %s"
+msgstr "Шаблон је пронаћен у Ñвакој линији: %s"
+
+#, c-format
+msgid "Pattern not found: %s"
+msgstr "Шаблон није пронађен: %s"
+
+msgid ""
+"\n"
+"# Last Substitute String:\n"
+"$"
+msgstr ""
+"\n"
+"# ПоÑледњи Стринг за замену:\n"
+"$"
+
+msgid "E478: Don't panic!"
+msgstr "E478: Ðе паничите!"
+
+#, c-format
+msgid "E661: Sorry, no '%s' help for %s"
+msgstr "E661: Жао нам је, нема '%s' помоћи за %s"
+
+#, c-format
+msgid "E149: Sorry, no help for %s"
+msgstr "E149: Жао нам је, нема помоћи за %s"
+
+#, c-format
+msgid "Sorry, help file \"%s\" not found"
+msgstr "Жао нам је, датотека помоћи \"%s\" није пронађена"
+
+#, c-format
+msgid "E151: No match: %s"
+msgstr "E151: Ðема подударања: %s"
+
+#, c-format
+msgid "E152: Cannot open %s for writing"
+msgstr "E152: %s не може да Ñе отвори за упиÑ"
+
+#, c-format
+msgid "E153: Unable to open %s for reading"
+msgstr "E153: %s не може да Ñе отвори за читање"
+
+#, c-format
+msgid "E670: Mix of help file encodings within a language: %s"
+msgstr "E670: Помешано је више кодирања фајлова помоћи за језик: %s"
+
+#, c-format
+msgid "E154: Duplicate tag \"%s\" in file %s/%s"
+msgstr "E154: Дуплирана ознака \"%s\" у датотеци %s/%s"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ðије директоријум: %s"
+
+#, c-format
+msgid "E160: Unknown sign command: %s"
+msgstr "E160: Ðепозната знак команда: %s"
+
+msgid "E156: Missing sign name"
+msgstr "E156: ÐедоÑтаје име знака"
+
+msgid "E612: Too many signs defined"
+msgstr "E612: ДефиниÑано је превише знакова"
+
+#, c-format
+msgid "E239: Invalid sign text: %s"
+msgstr "E239: ÐеиÑправан текÑÑ‚ знака: %s"
+
+#, c-format
+msgid "E155: Unknown sign: %s"
+msgstr "E155: Ðепознат знак: %s"
+
+msgid "E159: Missing sign number"
+msgstr "E159: ÐедоÑтаје број знака"
+
+#, c-format
+msgid "E158: Invalid buffer name: %s"
+msgstr "E158: ÐеиÑправно име бафера: %s"
+
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Ðе може да Ñе Ñкочи на бафер који нема име`"
+
+#, c-format
+msgid "E157: Invalid sign ID: %ld"
+msgstr "E157: ÐеиÑправан ИД знака: %ld"
+
+#, c-format
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Знак %s не може да Ñе промени"
+
+msgid " (NOT FOUND)"
+msgstr " (ÐИЈЕ ПРОÐÐЂЕÐО)"
+
+msgid " (not supported)"
+msgstr " (није подржано)"
+
+msgid "[Deleted]"
+msgstr "[ОбриÑано]"
+
+msgid "No old files"
+msgstr "Ðема Ñтарих датотека"
+
+msgid "Entering Debug mode. Type \"cont\" to continue."
+msgstr "Улазак у Debug режим. Откуцајте \"cont\" за наÑтавак."
+
+#, c-format
+msgid "Oldval = \"%s\""
+msgstr "Старавред = \"%s\""
+
+#, c-format
+msgid "Newval = \"%s\""
+msgstr "Ðоваавред = \"%s\""
+
+#, c-format
+msgid "line %ld: %s"
+msgstr "линија %ld: %s"
+
+#, c-format
+msgid "cmd: %s"
+msgstr "ком: %s"
+
+msgid "frame is zero"
+msgstr "оквир је нула"
+
+#, c-format
+msgid "frame at highest level: %d"
+msgstr "оквир је на највишем нивоу: %d"
+
+#, c-format
+msgid "Breakpoint in \"%s%s\" line %ld"
+msgstr "Прекидна тачка у \"%s%s\" линија %ld"
+
+#, c-format
+msgid "E161: Breakpoint not found: %s"
+msgstr "E161: Прекидна тачка није пронађена: %s"
+
+msgid "No breakpoints defined"
+msgstr "Ðије дефиниÑана ниједна прекидна тачка"
+
+#, c-format
+msgid "%3d %s %s line %ld"
+msgstr "%3d %s %s линија %ld"
+
+#, c-format
+msgid "%3d expr %s"
+msgstr "%3d израз %s"
+
+msgid "E750: First use \":profile start {fname}\""
+msgstr "E750: Ðајпре кориÑтите \":profile start {fname}\""
+
+#, c-format
+msgid "Save changes to \"%s\"?"
+msgstr "Да Ñачувам промене у \"%s\"?"
+
+#, c-format
+msgid "E947: Job still running in buffer \"%s\""
+msgstr "E947: Задатак Ñе и даље извршава у баферу \"%s\""
+
+#, c-format
+msgid "E162: No write since last change for buffer \"%s\""
+msgstr "E162: Ðије било упиÑа од поÑледње промене за бафер \"%s\""
+
+msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
+msgstr "Упозорење: Ðеочекивано Ñе прешло у други бафер (проверите аутокоманде)"
+
+msgid "E163: There is only one file to edit"
+msgstr "E163: ПоÑтоји Ñамо једна датотека за уређивање"
+
+msgid "E164: Cannot go before first file"
+msgstr "E164: Ðе може да Ñе иде иÑпред прве датотеке"
+
+msgid "E165: Cannot go beyond last file"
+msgstr "E165: Ðе може да Ñе иде иÑпред прве датотеке"
+
+#, c-format
+msgid "E666: compiler not supported: %s"
+msgstr "E666: компајлер није подржан: %s"
+
+#, c-format
+msgid "Searching for \"%s\" in \"%s\""
+msgstr "Тражи Ñе \"%s\" у \"%s\""
+
+#, c-format
+msgid "Searching for \"%s\""
+msgstr "Тражи Ñе\"%s\""
+
+#, c-format
+msgid "not found in '%s': \"%s\""
+msgstr "није пронађено у '%s': \"%s\""
+
+#, c-format
+msgid "W20: Required python version 2.x not supported, ignoring file: %s"
+msgstr ""
+"W20: Захтевани python version 2.x није подржан, датотека: %s Ñе игнорише"
+
+#, c-format
+msgid "W21: Required python version 3.x not supported, ignoring file: %s"
+msgstr ""
+"W21: Захтевани python version 3.x није подржан, датотека: %s Ñе игнорише"
+
+msgid "Source Vim script"
+msgstr "Изворна Vim Ñкрипта"
+
+#, c-format
+msgid "Cannot source a directory: \"%s\""
+msgstr "Директоријум не може да буде извор: \"%s\""
+
+#, c-format
+msgid "could not source \"%s\""
+msgstr "не може бити извор \"%s\""
+
+#, c-format
+msgid "line %ld: could not source \"%s\""
+msgstr "линија %ld: не може бити извор \"%s\""
+
+#, c-format
+msgid "sourcing \"%s\""
+msgstr "прибављање \"%s\""
+
+#, c-format
+msgid "line %ld: sourcing \"%s\""
+msgstr "линија %ld: прибављање \"%s\""
+
+#, c-format
+msgid "finished sourcing %s"
+msgstr "завршено прибављање %s"
+
+#, c-format
+msgid "continuing in %s"
+msgstr "наÑтавља Ñе у %s"
+
+msgid "modeline"
+msgstr "режимÑка линија (modeline)"
+
+msgid "--cmd argument"
+msgstr "--cmd аргумент"
+
+msgid "-c argument"
+msgstr "-c аргумент"
+
+msgid "environment variable"
+msgstr "променљива окружења"
+
+msgid "error handler"
+msgstr "процедура за обраду грешке"
+
+msgid "W15: Warning: Wrong line separator, ^M may be missing"
+msgstr "W15: Упозорење: Погрешан Ñепаратор линије, можда недоÑтаје ^M"
+
+msgid "E167: :scriptencoding used outside of a sourced file"
+msgstr "E167: :scriptencoding Ñе кориÑти ван изворишне датотеке"
+
+msgid "E168: :finish used outside of a sourced file"
+msgstr "E168: :finish Ñе кориÑти ван изворишне датотеке"
+
+#, c-format
+msgid "Current %slanguage: \"%s\""
+msgstr "Текући %sјезик: \"%s\""
+
+#, c-format
+msgid "E197: Cannot set language to \"%s\""
+msgstr "E197: Језик не може да Ñе поÑтави на \"%s\""
+
+msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
+msgstr ""
+"Улазак у Ex режим. Откуцајте \"visual\" да биÑте прешли у Ðормални режим."
+
+msgid "E501: At end-of-file"
+msgstr "E501: Ðа крају-датотеке"
+
+msgid "E169: Command too recursive"
+msgstr "E169: Команда је Ñувише рекурзивна"
+
+#, c-format
+msgid "E605: Exception not caught: %s"
+msgstr "E605: Изузетак није ухваћен: %s"
+
+msgid "End of sourced file"
+msgstr "Крај изворишне датотеке"
+
+msgid "End of function"
+msgstr "Крај функције"
+
+msgid "E464: Ambiguous use of user-defined command"
+msgstr "E464: ДвоÑмиÑлена употреба кориÑнички дефиниÑане команде"
+
+msgid "E492: Not an editor command"
+msgstr "E492: Ðије команда едитора"
+
+msgid "E493: Backwards range given"
+msgstr "E493: Задат је опÑег уназад"
+
+msgid "Backwards range given, OK to swap"
+msgstr "Задат је опÑег уназад, ОК да Ñе замени"
+
+msgid "E494: Use w or w>>"
+msgstr "E494: КориÑтите w или w>>"
+
+msgid "E943: Command table needs to be updated, run 'make cmdidxs'"
+msgstr "E943: Табела команди мора да Ñе оÑвежи, покрените 'make cmdidxs'"
+
+msgid "E319: Sorry, the command is not available in this version"
+msgstr "E319: Жао нам је, та команда није доÑтупна у овој верзији"
+
+msgid "1 more file to edit. Quit anyway?"
+msgstr "Још 1 датотека за уређивање. Ипак желите да напуÑтите програм?"
+
+#, c-format
+msgid "%d more files to edit. Quit anyway?"
+msgstr "Још %d датотека за уређивање. Ипак желите да напуÑтите програм?"
+
+msgid "E173: 1 more file to edit"
+msgstr "E173: Још 1 датотека за уређивање"
+
+#, c-format
+msgid "E173: %ld more files to edit"
+msgstr "E173: Још %ld датотека за уређивање"
+
+msgid "E174: Command already exists: add ! to replace it"
+msgstr "E174: Команда већ поÑтоји: додајте ! да је замените"
+
+msgid ""
+"\n"
+" Name Args Address Complete Definition"
+msgstr ""
+"\n"
+" Име Ðргум ÐдреÑа Довршење Дефиниција"
+
+msgid "No user-defined commands found"
+msgstr "ÐиÑу пронађене кориÑнички дефиниÑане команде"
+
+msgid "E175: No attribute specified"
+msgstr "E175: Ðије наведен ни један атрибут"
+
+msgid "E176: Invalid number of arguments"
+msgstr "E176: ÐеиÑправан број аргумената"
+
+msgid "E177: Count cannot be specified twice"
+msgstr "E177: Бројач не може да Ñе наведе два пута"
+
+msgid "E178: Invalid default value for count"
+msgstr "E178: ÐеÑправна подразумевана вредноÑÑ‚ за бројач"
+
+msgid "E179: argument required for -complete"
+msgstr "E179: потребан је аргумент за -complete"
+
+msgid "E179: argument required for -addr"
+msgstr "E179: потребан је аргумент за -addr"
+
+#, c-format
+msgid "E181: Invalid attribute: %s"
+msgstr "E181: ÐеиÑправан атрибут: %s"
+
+msgid "E182: Invalid command name"
+msgstr "E182: ÐеиÑправно име команде"
+
+msgid "E183: User defined commands must start with an uppercase letter"
+msgstr "E183: КориÑнички дефиниÑане команде морају да почну великим Ñловом"
+
+msgid "E841: Reserved name, cannot be used for user defined command"
+msgstr ""
+"E841: РезервиÑано име, не може да Ñе кориÑти за кориÑнички дефиниÑану команду"
+
+#, c-format
+msgid "E184: No such user-defined command: %s"
+msgstr "E184: Ðе поÑтоји таква кориÑнички дефиниÑана команда: %s"
+
+#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: ÐеиÑправна вредноÑÑ‚ адреÑног типа: %s"
+
+#, c-format
+msgid "E180: Invalid complete value: %s"
+msgstr "E180: ÐеиÑправна вредноÑÑ‚ довршавања: %s"
+
+msgid "E468: Completion argument only allowed for custom completion"
+msgstr "E468: Ðргумент довршавања је дозвољен Ñамо за прилагођена довршавања"
+
+msgid "E467: Custom completion requires a function argument"
+msgstr "E467: Прилагођено довршавање захтева аргумент функције"
+
+msgid "unknown"
+msgstr "непознато"
+
+#, c-format
+msgid "E185: Cannot find color scheme '%s'"
+msgstr "E185: Шема боја '%s' не може да Ñе пронађе"
+
+msgid "Greetings, Vim user!"
+msgstr "Поздрав, кориÑниче Vim-a"
+
+msgid "E784: Cannot close last tab page"
+msgstr "E784: ПоÑледња картица не може да Ñе затвори"
+
+msgid "Already only one tab page"
+msgstr "Већ Ñте на Ñамо једној картици"
+
+msgid "Edit File in new window"
+msgstr "Уређивање Датотеке у новом прозору"
+
+#, c-format
+msgid "Tab page %d"
+msgstr "Картица %d"
+
+msgid "No swap file"
+msgstr "Ðема swap датотеке"
+
+msgid "Append File"
+msgstr "Додавање на крај Датотеке"
+
+msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
+msgstr ""
+"E747: Директоријум не може да Ñе промени, бафер је измењен (додајте ! за "
+"премошћавање)"
+
+msgid "E186: No previous directory"
+msgstr "E186: Ðема претгодног директоријума"
+
+msgid "E187: Unknown"
+msgstr "E187: Ðепознато"
+
+msgid "E465: :winsize requires two number arguments"
+msgstr "E465: :winsize захтева два бројчана аргумента"
+
+#, c-format
+msgid "Window position: X %d, Y %d"
+msgstr "Позиција прозора: X %d, Y %d"
+
+msgid "E188: Obtaining window position not implemented for this platform"
+msgstr "E188: Добављање позиције прозора није имплементирано за ову платформу"
+
+msgid "E466: :winpos requires two number arguments"
+msgstr "E466: :winpos захтева два бројчана аргумента"
+
+msgid "E930: Cannot use :redir inside execute()"
+msgstr "E930: :redir не може да Ñе кориÑти унутар execute()"
+
+msgid "Save Redirection"
+msgstr "Сачувај Редирекцију"
+
+msgid "Save View"
+msgstr "Сачувај Поглед"
+
+msgid "Save Session"
+msgstr "Сачувај СеÑију"
+
+msgid "Save Setup"
+msgstr "Сачувај Подешавање"
+
+#, c-format
+msgid "E739: Cannot create directory: %s"
+msgstr "E739: Директоријум не може да Ñе креира: %s"
+
+#, c-format
+msgid "E189: \"%s\" exists (add ! to override)"
+msgstr "E189: \"%s\" поÑтоји (додајте ! за премошћавање)"
+
+#, c-format
+msgid "E190: Cannot open \"%s\" for writing"
+msgstr "E190: \"%s\" не може да Ñе отвори за упиÑ"
+
+msgid "E191: Argument must be a letter or forward/backward quote"
+msgstr "E191: Ðргумент мора бити Ñлово или апоÑтроф/обрнути апоÑтроф"
+
+msgid "E192: Recursive use of :normal too deep"
+msgstr "E192: Рекурзивно коришћење :normal је Ñувише дубоко"
+
+msgid "E809: #< is not available without the +eval feature"
+msgstr "E809: #< није доÑтупно без +eval могућноÑти"
+
+msgid "E194: No alternate file name to substitute for '#'"
+msgstr "E194: Ðема алтернативног имена које би заменило '#'"
+
+msgid "E495: no autocommand file name to substitute for \"<afile>\""
+msgstr "E495: нема имена датотеке за аутокоманде које би заменило \"<afile>\""
+
+msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
+msgstr "E496: нема броја бафера за аутокоманду који би заменио \"<abuf>\""
+
+msgid "E497: no autocommand match name to substitute for \"<amatch>\""
+msgstr "E497: нема имена подударања аутокоманде које би заменило \"<amatch>\""
+
+msgid "E498: no :source file name to substitute for \"<sfile>\""
+msgstr "E498: нема имена :source датотеке које би заменило \"<sfile>\""
+
+msgid "E842: no line number to use for \"<slnum>\""
+msgstr "E842: нема броја линије који би Ñе кориÑтио за \"<slnum>\""
+
+#, no-c-format
+msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
+msgstr "E499: Празно име датотеке за'%' or '#', функционише Ñамо Ñа \":p:h\""
+
+msgid "E500: Evaluates to an empty string"
+msgstr "E500: Резултат израчунавања је празан Ñтринг"
+
+msgid "E195: Cannot open viminfo file for reading"
+msgstr "E195: viminfo датотека не може да Ñе отвори за читање"
+
+msgid "Untitled"
+msgstr "Без наÑлова"
+
+msgid "E196: No digraphs in this version"
+msgstr "E196: У овој верзији нема диграфа"
+
+msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
+msgstr "E608: :throw изузетка Ñа 'Vim' префикÑом није дозвољен"
+
+#, c-format
+msgid "Exception thrown: %s"
+msgstr "Бачен је изузетак: %s"
+
+#, c-format
+msgid "Exception finished: %s"
+msgstr "Изузетак је завршен: %s"
+
+#, c-format
+msgid "Exception discarded: %s"
+msgstr "Изузетак је одбачен: %s"
+
+#, c-format
+msgid "%s, line %ld"
+msgstr "%s, линија %ld"
+
+#, c-format
+msgid "Exception caught: %s"
+msgstr "Изузетак је ухваћен: %s"
+
+#, c-format
+msgid "%s made pending"
+msgstr "%s је Ñтављен на чекање"
+
+#, c-format
+msgid "%s resumed"
+msgstr "%s је поново активан"
+
+#, c-format
+msgid "%s discarded"
+msgstr "%s је одбачен"
+
+msgid "Exception"
+msgstr "Изузетак"
+
+msgid "Error and interrupt"
+msgstr "Грешка и прекид"
+
+msgid "Error"
+msgstr "Грешка"
+
+msgid "Interrupt"
+msgstr "Прекид"
+
+msgid "E579: :if nesting too deep"
+msgstr "E579: :if угњеждавање је Ñувише дубоко"
+
+msgid "E580: :endif without :if"
+msgstr "E580: :endif без :if"
+
+msgid "E581: :else without :if"
+msgstr "E581: :else без :if"
+
+msgid "E582: :elseif without :if"
+msgstr "E582: :elseif без :if"
+
+msgid "E583: multiple :else"
+msgstr "E583: вишеÑтруко :else"
+
+msgid "E584: :elseif after :else"
+msgstr "E584: :elseif након :else"
+
+msgid "E585: :while/:for nesting too deep"
+msgstr "E585: :while/:for угњеждавање је Ñувише дубоко"
+
+msgid "E586: :continue without :while or :for"
+msgstr "E586: :continue без :while или :for"
+
+msgid "E587: :break without :while or :for"
+msgstr "E587: :break без :while или :for"
+
+msgid "E732: Using :endfor with :while"
+msgstr "E732: Коришћење :endfor Ñа :while"
+
+msgid "E733: Using :endwhile with :for"
+msgstr "E733: Коришћење :endwhile Ñа :for"
+
+msgid "E601: :try nesting too deep"
+msgstr "E601: :try угњеждавање је Ñувише дубоко"
+
+msgid "E603: :catch without :try"
+msgstr "E603: :catch без :try"
+
+msgid "E604: :catch after :finally"
+msgstr "E604: :catch након :finally"
+
+msgid "E606: :finally without :try"
+msgstr "E606: :finally без :try"
+
+msgid "E607: multiple :finally"
+msgstr "E607: вишеÑтруко :finally"
+
+msgid "E602: :endtry without :try"
+msgstr "E602: :endtry без :try"
+
+msgid "E193: :endfunction not inside a function"
+msgstr "E193: :endfunction није унутар функције"
+
+msgid "E788: Not allowed to edit another buffer now"
+msgstr "E788: Уређивање другог бафера тренутно није дозвољено"
+
+msgid "E811: Not allowed to change buffer information now"
+msgstr "E811: Мењање информација о баферу тренутно није дозвољено"
+
+msgid "tagname"
+msgstr "ознака"
+
+msgid " kind file\n"
+msgstr " врÑта датотеке\n"
+
+msgid "'history' option is zero"
+msgstr "опција 'history' је нула"
+
+#, c-format
+msgid ""
+"\n"
+"# %s History (newest to oldest):\n"
+msgstr ""
+"\n"
+"# %s ИÑторија (од најновијег ка најÑтаријем):\n"
+
+msgid "Command Line"
+msgstr "Командна линија"
+
+msgid "Search String"
+msgstr "Стринг за претрагу"
+
+msgid "Expression"
+msgstr "Израз"
+
+msgid "Input Line"
+msgstr "Линија за уноÑ"
+
+msgid "Debug Line"
+msgstr "Debug линија"
+
+msgid "E198: cmd_pchar beyond the command length"
+msgstr "E198: cmd_pchar је иза дужине команде"
+
+msgid "E199: Active window or buffer deleted"
+msgstr "E199: Active window or buffer deleted"
+
+msgid "E812: Autocommands changed buffer or buffer name"
+msgstr "E812: Ðутокоманде Ñу промениле багер или име бафера"
+
+msgid "Illegal file name"
+msgstr "Ðедозвољено име датотеке"
+
+msgid "is a directory"
+msgstr "је директоријум"
+
+msgid "is not a file"
+msgstr "није датотека"
+
+msgid "is a device (disabled with 'opendevice' option)"
+msgstr "је уређај (онемогућен опцијом 'opendevice')"
+
+msgid "[New File]"
+msgstr "[Ðова датотека]"
+
+msgid "[New DIRECTORY]"
+msgstr "[Ðов ДИРЕКТОРИЈУМ]"
+
+msgid "[File too big]"
+msgstr "[Датотека је Ñувише велика]"
+
+msgid "[Permission Denied]"
+msgstr "[Дозвола одбијена]"
+
+msgid "E200: *ReadPre autocommands made the file unreadable"
+msgstr "E200: *ReadPre аутокоманде Ñу учиниле датотеку нечитљивом"
+
+msgid "E201: *ReadPre autocommands must not change current buffer"
+msgstr "E201: *ReadPre аутокоманде не Ñмеју да измене текући бафер"
+
+msgid "Vim: Reading from stdin...\n"
+msgstr "Vim: Читање Ñа stdin...\n"
+
+msgid "Reading from stdin..."
+msgstr "Читање Ñа stdin..."
+
+msgid "E202: Conversion made file unreadable!"
+msgstr "E202: Конверзија је учинила датотеку нечитљивом!"
+
+msgid "[fifo/socket]"
+msgstr "[fifo/утичница]"
+
+msgid "[fifo]"
+msgstr "[fifo]"
+
+msgid "[socket]"
+msgstr "[утичница]"
+
+msgid "[character special]"
+msgstr "[Ñпецијални карактер]"
+
+msgid "[CR missing]"
+msgstr "[недоÑтаје CR]"
+
+msgid "[long lines split]"
+msgstr "[дуге линије преломљене]"
+
+msgid "[NOT converted]"
+msgstr "[ÐИЈЕ конвертовано]"
+
+msgid "[converted]"
+msgstr "[конвертовано]"
+
+#, c-format
+msgid "[CONVERSION ERROR in line %ld]"
+msgstr "[ГРЕШКРКОÐВЕРЗИЈЕ у линији %ld]"
+
+#, c-format
+msgid "[ILLEGAL BYTE in line %ld]"
+msgstr "[ÐЕДОЗВОЉЕРБÐЈТ у линији %ld]"
+
+msgid "[READ ERRORS]"
+msgstr "[ГРЕШКЕ ПРИ ЧИТÐЊУ]"
+
+msgid "Can't find temp file for conversion"
+msgstr "Привремена датотека за конверзију не може да Ñе пронађе"
+
+msgid "Conversion with 'charconvert' failed"
+msgstr "Конверзија Ñа 'charconvert' није уÑпела"
+
+msgid "can't read output of 'charconvert'"
+msgstr "излаз 'charconvert' не може да Ñе прочита"
+
+msgid "E676: No matching autocommands for acwrite buffer"
+msgstr "E676: Ðема одговарајућих аутокоманди за acwrite бафер"
+
+msgid "E203: Autocommands deleted or unloaded buffer to be written"
+msgstr ""
+"E203: Ðутокоманде Ñу обриÑале или уклониле из меморије бафер који требало да "
+"буде упиÑан"
+
+msgid "E204: Autocommand changed number of lines in unexpected way"
+msgstr "E204: Ðутокоманде Ñу на неочекиван начин промениле број линија"
+
+msgid "NetBeans disallows writes of unmodified buffers"
+msgstr "NetBeans не дозвољава ÑƒÐ¿Ð¸Ñ Ð½ÐµÐ¸Ð·Ð¼ÐµÑšÐµÐ½Ð¸Ñ… бафера"
+
+msgid "Partial writes disallowed for NetBeans buffers"
+msgstr "Парцијални упиÑи ниÑу дозвољени за NetBeans бафере"
+
+msgid "is not a file or writable device"
+msgstr "није датотека или уређај на који може да Ñе упиÑује"
+
+msgid "writing to device disabled with 'opendevice' option"
+msgstr "ÑƒÐ¿Ð¸Ñ Ð½Ð° уређај је онемогућен опцијом 'opendevice'"
+
+msgid "is read-only (add ! to override)"
+msgstr "је Ñамо за читање (додајте ! за премошћавање)"
+
+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 "E509: Cannot create backup file (add ! to override)"
+msgstr ""
+"E509: Резервна датотека не може да Ñе креира (додајте ! за премошћавање)"
+
+msgid "E510: Can't make backup file (add ! to override)"
+msgstr ""
+"E510: Резервна датотека не може да Ñе направи (додајте ! за премошћавање)"
+
+msgid "E214: Can't find temp file for writing"
+msgstr "E214: Привремена датотека за ÑƒÐ¿Ð¸Ñ Ð½Ðµ може да Ñе пронађе"
+
+msgid "E213: Cannot convert (add ! to write without conversion)"
+msgstr "E213: Конверзија није могућа (додајте ! за ÑƒÐ¿Ð¸Ñ Ð±ÐµÐ· конверзије)"
+
+msgid "E166: Can't open linked file for writing"
+msgstr "E166: Повезана датотека не може да Ñе отвори за упиÑ"
+
+msgid "E212: Can't open file for writing"
+msgstr "E212: Датотека не може да Ñе отвори за упиÑ"
+
+msgid "E949: File changed while writing"
+msgstr "E949: Датотека је промењена током упиÑа"
+
+msgid "E512: Close failed"
+msgstr "E512: Затварање није уÑпело"
+
+msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
+msgstr ""
+"E513: грешка при упиÑу, конверзија није уÑпела (оÑтавите 'fenc' празно да "
+"премоÑтите)"
+
+#, c-format
+msgid ""
+"E513: write error, conversion failed in line %ld (make 'fenc' empty to "
+"override)"
+msgstr ""
+"E513: грешка при упиÑу, конверзија није уÑпела у линији %ld (оÑтавите 'fenc' "
+"празно да премоÑтите)"
+
+msgid "E514: write error (file system full?)"
+msgstr "E514: грешка при упиÑу (ÑиÑтем датотека је пун?)"
+
+msgid " CONVERSION ERROR"
+msgstr " ГРЕШКРКОÐВЕРЗИЈЕ"
+
+#, c-format
+msgid " in line %ld;"
+msgstr " у линији %ld;"
+
+msgid "[Device]"
+msgstr "[Уређај]"
+
+msgid "[New]"
+msgstr "[Ðово]"
+
+msgid " [a]"
+msgstr " [н]"
+
+msgid " appended"
+msgstr " наÑтављено"
+
+msgid " [w]"
+msgstr " [у]"
+
+msgid " written"
+msgstr " упиÑано"
+
+msgid "E205: Patchmode: can't save original file"
+msgstr "E205: Patch режим: оригинална датотека не може да Ñе Ñачува"
+
+msgid "E206: patchmode: can't touch empty original file"
+msgstr "E206: Patch режим: не може да Ñе креира празна оригинална датотека"
+
+msgid "E207: Can't delete backup file"
+msgstr "E207: Резервна датотека не може да Ñе обрише"
+
+msgid ""
+"\n"
+"WARNING: Original file may be lost or damaged\n"
+msgstr ""
+"\n"
+"УПОЗОРЕЊЕ: Оригинална датотека је можда изгубљена или оштећена\n"
+
+msgid "don't quit the editor until the file is successfully written!"
+msgstr "не напуштајте едитор док Ñе датотека уÑпешно не упише!"
+
+msgid "[dos]"
+msgstr "[dos]"
+
+msgid "[dos format]"
+msgstr "[dos формат]"
+
+msgid "[mac]"
+msgstr "[mac]"
+
+msgid "[mac format]"
+msgstr "[mac формат]"
+
+msgid "[unix]"
+msgstr "[unix]"
+
+msgid "[unix format]"
+msgstr "[unix формат]"
+
+msgid "1 line, "
+msgstr "1 линија, "
+
+#, c-format
+msgid "%ld lines, "
+msgstr "%ld линија, "
+
+msgid "1 character"
+msgstr "1 карактер"
+
+#, c-format
+msgid "%lld characters"
+msgstr "%lld карактера"
+
+msgid "[noeol]"
+msgstr "[noeol]"
+
+msgid "[Incomplete last line]"
+msgstr "[ПоÑледња линија није комплетна]"
+
+msgid "WARNING: The file has been changed since reading it!!!"
+msgstr "УПОЗОРЕЊЕ: Ова датотека је промењена од кад је прочитана!!!"
+
+msgid "Do you really want to write to it"
+msgstr "Да ли заиÑта желите да пишете у њу"
+
+#, c-format
+msgid "E208: Error writing to \"%s\""
+msgstr "E208: Грешка при упиÑу у \"%s\""
+
+#, c-format
+msgid "E209: Error closing \"%s\""
+msgstr "E209: Грешка при затварању \"%s\""
+
+#, c-format
+msgid "E210: Error reading \"%s\""
+msgstr "E210: Грешка при читању \"%s\""
+
+msgid "E246: FileChangedShell autocommand deleted buffer"
+msgstr "E246: FileChangedShell аутокоманда је обриÑала бафер"
+
+#, c-format
+msgid "E211: File \"%s\" no longer available"
+msgstr "E211: Датотека \"%s\" више није доÑтупна"
+
+#, c-format
+msgid ""
+"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
+"well"
+msgstr ""
+"W12: Упозорење: Датотека \"%s\" је измењена и бафер у програму Vim је такође "
+"измењен"
+
+msgid "See \":help W12\" for more info."
+msgstr "Погледајте \":help W12\" за више информација."
+
+#, c-format
+msgid "W11: Warning: File \"%s\" has changed since editing started"
+msgstr ""
+"W11: Упозорење: Датотека \"%s\" је измењена откад је започето уређивање"
+
+msgid "See \":help W11\" for more info."
+msgstr "Погледајте \":help W11\" за више информација."
+
+#, c-format
+msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
+msgstr ""
+"W16: Упозорење: Режим датотеке \"%s\" је измењен откад је започето уређивање"
+
+msgid "See \":help W16\" for more info."
+msgstr "Погледајте \":help W16\" за више информација."
+
+#, c-format
+msgid "W13: Warning: File \"%s\" has been created after editing started"
+msgstr "W13: Упозорење: Датотека \"%s\" је креирана након почетка уређивања"
+
+msgid "Warning"
+msgstr "Упозорење"
+
+msgid ""
+"&OK\n"
+"&Load File"
+msgstr ""
+"&OK\n"
+"&Учитај датотеку"
+
+#, c-format
+msgid "E462: Could not prepare for reloading \"%s\""
+msgstr "E462: Припрема за поновно учитавање \"%s\" није била могућа"
+
+#, c-format
+msgid "E321: Could not reload \"%s\""
+msgstr "E321: \"%s\" не може поново да Ñе учита"
+
+msgid "--Deleted--"
+msgstr "--ОбриÑано--"
+
+#, c-format
+msgid "auto-removing autocommand: %s <buffer=%d>"
+msgstr "ауто-уклањајућа аутокоманда: %s <бафер=%d>"
+
+#, c-format
+msgid "E367: No such group: \"%s\""
+msgstr "E367: Ðема такве групе: \"%s\""
+
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Текућа група не може да Ñе обрише"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: БриÑање augroup која је још у употреби"
+
+#, c-format
+msgid "E215: Illegal character after *: %s"
+msgstr "E215: Ðедозвољени карактер након *: %s"
+
+#, c-format
+msgid "E216: No such event: %s"
+msgstr "E216: Ðема таквог догађаја: %s"
+
+#, c-format
+msgid "E216: No such group or event: %s"
+msgstr "E216: Ðема такве групе или догађаја: %s"
+
+msgid ""
+"\n"
+"--- Autocommands ---"
+msgstr ""
+"\n"
+"--- Ðутокоманде ---"
+
+#, c-format
+msgid "E680: <buffer=%d>: invalid buffer number "
+msgstr "E680: <бафер=%d>: неиÑправан број бафера "
+
+msgid "E217: Can't execute autocommands for ALL events"
+msgstr "E217: Ðутокоманде за СВЕ догађаје не могу да Ñе изврше"
+
+msgid "No matching autocommands"
+msgstr "Ðема подударајућих аутокоманди"
+
+msgid "E218: autocommand nesting too deep"
+msgstr "E218: Угњеждавање аутокоманде је Ñувише дубоко"
+
+#, c-format
+msgid "%s Autocommands for \"%s\""
+msgstr "%s Ðутокоманде за \"%s\""
+
+#, c-format
+msgid "Executing %s"
+msgstr "Извршавање %s"
+
+#, c-format
+msgid "autocommand %s"
+msgstr "аутокоманда %s"
+
+msgid "E219: Missing {."
+msgstr "E219: ÐедоÑтаје {."
+
+msgid "E220: Missing }."
+msgstr "E220: ÐедоÑтаје }."
+
+msgid "E490: No fold found"
+msgstr "E490: Ðије пронађено ниједно Ñклапање"
+
+msgid "E350: Cannot create fold with current 'foldmethod'"
+msgstr "E350: Склапање не може да Ñе креира Ñа текућим 'foldmethod'"
+
+msgid "E351: Cannot delete fold with current 'foldmethod'"
+msgstr "E351: Склапање не може да Ñе обрише Ñа текћим 'foldmethod'"
+
+#, c-format
+msgid "+--%3ld line folded "
+msgid_plural "+--%3ld lines folded "
+msgstr[0] "+--%3ld линија подвијена"
+msgstr[1] "+--%3ld линија подвијено"
+
+msgid "E222: Add to read buffer"
+msgstr "E222: Додавање у бафер читања"
+
+msgid "E223: recursive mapping"
+msgstr "E223: рекурзивно мапирање"
+
+#, c-format
+msgid "E224: global abbreviation already exists for %s"
+msgstr "E224: глобална Ñкраћеница за %s већ поÑтоји"
+
+#, c-format
+msgid "E225: global mapping already exists for %s"
+msgstr "E225: глобално мапирање за %s већ поÑтоји"
+
+#, c-format
+msgid "E226: abbreviation already exists for %s"
+msgstr "E226: Ñкраћеница за %s већ поÑтоји"
+
+#, c-format
+msgid "E227: mapping already exists for %s"
+msgstr "E227: мапирање за %s већ поÑтоји"
+
+msgid "No abbreviation found"
+msgstr "Скраћеница није пронађена"
+
+msgid "No mapping found"
+msgstr "Мапирање није пронађено"
+
+msgid "E228: makemap: Illegal mode"
+msgstr "E228: makemap: Ðедозвољен режим"
+
+msgid "E851: Failed to create a new process for the GUI"
+msgstr "E851: Креирање новог процеÑа за GUI није уÑпело"
+
+msgid "E852: The child process failed to start the GUI"
+msgstr "E852: ÐŸÑ€Ð¾Ñ†ÐµÑ Ð¿Ð¾Ñ‚Ð¾Ð¼Ð°Ðº није уÑпео да покрене GUI"
+
+msgid "E229: Cannot start the GUI"
+msgstr "E229: GUI не може да Ñе покрене"
+
+#, c-format
+msgid "E230: Cannot read from \"%s\""
+msgstr "E230: Из \"%s\" не може да Ñе чита"
+
+msgid "E665: Cannot start GUI, no valid font found"
+msgstr "E665: GUI не може да Ñе покрене, није пронађен валидан фонт"
+
+msgid "E231: 'guifontwide' invalid"
+msgstr "E231: 'guifontwide' неиÑправан"
+
+msgid "E599: Value of 'imactivatekey' is invalid"
+msgstr "E599: ВредноÑÑ‚ 'imactivatekey' није иÑправна"
+
+#, c-format
+msgid "E254: Cannot allocate color %s"
+msgstr "E254: Боја %s не може да Ñе алоцира"
+
+msgid "No match at cursor, finding next"
+msgstr "Ðема подударања на меÑту курÑора, тражи Ñе даље"
+
+msgid "<cannot open> "
+msgstr "<не може да Ñе отвори> "
+
+#, c-format
+msgid "E616: vim_SelFile: can't get font %s"
+msgstr "E616: vim_SelFile: не може да Ñе добије фонт %s"
+
+msgid "E614: vim_SelFile: can't return to current directory"
+msgstr "E614: vim_SelFile: повратак у текући директоријум није могућ"
+
+msgid "Pathname:"
+msgstr "Име путање:"
+
+msgid "E615: vim_SelFile: can't get current directory"
+msgstr "E615: vim_SelFile: не може да Ñе добије текући директоријум"
+
+msgid "OK"
+msgstr "ОК"
+
+msgid "Cancel"
+msgstr "Откажи"
+
+msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
+msgstr "Scrollbar Widget: Ðе може да Ñе добије геометрија thumb pixmap."
+
+msgid "Vim dialog"
+msgstr "Vim дијалог"
+
+msgid "E232: Cannot create BalloonEval with both message and callback"
+msgstr ""
+"E232: Ðе може да Ñе креира BalloonEval и Ñа поруком и Ñа повратним позивом"
+
+msgid "_Cancel"
+msgstr "_Откажи"
+
+msgid "_Save"
+msgstr "_Сачувај"
+
+msgid "_Open"
+msgstr "_Отвори"
+
+msgid "_OK"
+msgstr "_OK"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"&Cancel"
+msgstr ""
+"&Да\n"
+"&Ðе\n"
+"&Откажи"
+
+msgid "Yes"
+msgstr "Да"
+
+msgid "No"
+msgstr "Ðе"
+
+msgid "Input _Methods"
+msgstr "_Методе уноÑа"
+
+msgid "VIM - Search and Replace..."
+msgstr "VIM - Претрага and Замена..."
+
+msgid "VIM - Search..."
+msgstr "VIM - Претрага..."
+
+msgid "Find what:"
+msgstr "Пронађи:"
+
+msgid "Replace with:"
+msgstr "Замени Ñа:"
+
+msgid "Match whole word only"
+msgstr "Само целе речи подударају"
+
+msgid "Match case"
+msgstr "Мала/велика Ñлова"
+
+msgid "Direction"
+msgstr "Смер"
+
+msgid "Up"
+msgstr "Горе"
+
+msgid "Down"
+msgstr "Доле"
+
+msgid "Find Next"
+msgstr "Пронађи наредно"
+
+msgid "Replace"
+msgstr "Замени"
+
+msgid "Replace All"
+msgstr "Замени Ñве"
+
+msgid "_Close"
+msgstr "_Затвори"
+
+msgid "Vim: Received \"die\" request from session manager\n"
+msgstr "Vim: Примљен је \"die\" захтев од менаџера ÑеÑије\n"
+
+msgid "Close tab"
+msgstr "Затвори картицу"
+
+msgid "New tab"
+msgstr "Ðова картица"
+
+msgid "Open Tab..."
+msgstr "Отвори картицу..."
+
+msgid "Vim: Main window unexpectedly destroyed\n"
+msgstr "Vim: Главни прозор је неочекивано уништен\n"
+
+msgid "&Filter"
+msgstr "&Филтер"
+
+msgid "&Cancel"
+msgstr "&Откажи"
+
+msgid "Directories"
+msgstr "Директоријуми"
+
+msgid "Filter"
+msgstr "Филтер"
+
+msgid "&Help"
+msgstr "&Помоћ"
+
+msgid "Files"
+msgstr "Датотеке"
+
+msgid "&OK"
+msgstr "&ОК"
+
+msgid "Selection"
+msgstr "Селекција"
+
+msgid "Find &Next"
+msgstr "Пронађи &Следеће"
+
+msgid "&Replace"
+msgstr "&Замени"
+
+msgid "Replace &All"
+msgstr "Замени Ñ&Ве"
+
+msgid "&Undo"
+msgstr "О&позови"
+
+msgid "Open tab..."
+msgstr "Отвори картицу"
+
+msgid "Find string (use '\\\\' to find a '\\')"
+msgstr "Пронађи Ñтринг (кориÑтите '\\\\' да пронађете '\\')"
+
+msgid "Find & Replace (use '\\\\' to find a '\\')"
+msgstr "Пронађи & Замени (кориÑтите '\\\\' да пронађете '\\')"
+
+msgid "Not Used"
+msgstr "Ðе кориÑти Ñе"
+
+msgid "Directory\t*.nothing\n"
+msgstr "Директоријум\t*.ништа\n"
+
+#, c-format
+msgid "E671: Cannot find window title \"%s\""
+msgstr "E671: ÐаÑлов прозора \"%s\" не може да Ñе пронађе"
+
+#, c-format
+msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
+msgstr "E243: Ðргумент није подржан: \"-%s\"; КориÑтите OLE верзију."
+
+msgid "E672: Unable to open window inside MDI application"
+msgstr "E672: Ðије могуће отварање прозора унутар MDI апликације"
+
+msgid "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
+msgstr ""
+"Vim E458: colormap ÑƒÐ½Ð¾Ñ Ð½Ðµ може да Ñе алоцира, неке боје Ñу можда неиÑправне"
+
+#, c-format
+msgid "E250: Fonts for the following charsets are missing in fontset %s:"
+msgstr "E250: Фонтови за Ñледеће Ñетове карактера недоÑтају у фонтÑету %s:"
+
+#, c-format
+msgid "E252: Fontset name: %s"
+msgstr "E252: Име фонтÑета: %s"
+
+#, c-format
+msgid "Font '%s' is not fixed-width"
+msgstr "Фонт %s' није фикÑне ширине"
+
+#, c-format
+msgid "E253: Fontset name: %s"
+msgstr "E253: Име фонтÑета: %s"
+
+#, c-format
+msgid "Font0: %s"
+msgstr "Фонт0: %s"
+
+#, c-format
+msgid "Font1: %s"
+msgstr "Фонт1: %s"
+
+#, c-format
+msgid "Font%ld width is not twice that of font0"
+msgstr "Ширина фонт%ld није двоÑтрука од ширине фонт0"
+
+#, c-format
+msgid "Font0 width: %ld"
+msgstr "Фонт0 ширина: %ld"
+
+#, c-format
+msgid "Font1 width: %ld"
+msgstr "Фонт1 ширина: %ld"
+
+msgid "Invalid font specification"
+msgstr "ÐеиÑправна Ñпецификација фонта"
+
+msgid "&Dismiss"
+msgstr "О&дбаци"
+
+msgid "no specific match"
+msgstr "нема поÑебног подударања"
+
+msgid "Vim - Font Selector"
+msgstr "Vim - Фонт Ñелектор"
+
+msgid "Name:"
+msgstr "Име:"
+
+msgid "Show size in Points"
+msgstr "Прикажи величину у Тачкама"
+
+msgid "Encoding:"
+msgstr "Кодирање:"
+
+msgid "Font:"
+msgstr "Фонт:"
+
+msgid "Style:"
+msgstr "Стил:"
+
+msgid "Size:"
+msgstr "Величина:"
+
+msgid "E256: Hangul automata ERROR"
+msgstr "E256: ГРЕШКРHangul аутомата"
+
+msgid "E550: Missing colon"
+msgstr "E550: ÐедоÑтаје двотачка"
+
+msgid "E551: Illegal component"
+msgstr "E551: ÐеиÑправна компонента"
+
+msgid "E552: digit expected"
+msgstr "E552: очекује Ñе цифра"
+
+#, c-format
+msgid "Page %d"
+msgstr "Страна %d"
+
+msgid "No text to be printed"
+msgstr "Ðема текÑта за штампу"
+
+#, c-format
+msgid "Printing page %d (%d%%)"
+msgstr "Штампање Ñтране %d (%d%%)"
+
+#, c-format
+msgid " Copy %d of %d"
+msgstr " Копија %d од %d"
+
+#, c-format
+msgid "Printed: %s"
+msgstr "Одштампано: %s"
+
+msgid "Printing aborted"
+msgstr "Штампање прекинуто"
+
+msgid "E455: Error writing to PostScript output file"
+msgstr "E455: Грешка приликом упиÑа у PostScript излазну датотеку"
+
+#, c-format
+msgid "E624: Can't open file \"%s\""
+msgstr "E624: Датотека \"%s\" не може да Ñе отвори"
+
+#, c-format
+msgid "E457: Can't read PostScript resource file \"%s\""
+msgstr "E457: PostScript resource датотека \"%s\" не може да Ñе чита"
+
+#, c-format
+msgid "E618: file \"%s\" is not a PostScript resource file"
+msgstr "E618: датотека \"%s\" није PostScript resource датотека"
+
+#, c-format
+msgid "E619: file \"%s\" is not a supported PostScript resource file"
+msgstr "E619: датотека \"%s\" није подржана PostScript resource датотека"
+
+#, c-format
+msgid "E621: \"%s\" resource file has wrong version"
+msgstr "E621: \"%s\" resource датотека је погрешне верзије"
+
+msgid "E673: Incompatible multi-byte encoding and character set."
+msgstr "E673: Вишебајтно кодирање и Ñкуп карактера ниÑу компатибилни."
+
+msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
+msgstr "E674: printmbcharset не може бити празно Ñа вишебајтним кодирањем."
+
+msgid "E675: No default font specified for multi-byte printing."
+msgstr "E675: Ðије наведен подразумевани фонт за вишебајтно штампање."
+
+msgid "E324: Can't open PostScript output file"
+msgstr "E324: PostScript излазна датотека не може да Ñе отвори"
+
+#, c-format
+msgid "E456: Can't open file \"%s\""
+msgstr "E456: Датотека \"%s\" не може да Ñе отвори"
+
+msgid "E456: Can't find PostScript resource file \"prolog.ps\""
+msgstr "E456: PostScript resource датотека \"prolog.ps\" не може да Ñе пронађе"
+
+msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
+msgstr ""
+"E456: PostScript resource датотека \"cidfont.ps\" не може да Ñе пронађе"
+
+#, c-format
+msgid "E456: Can't find PostScript resource file \"%s.ps\""
+msgstr "E456: PostScript resource датотека \"%s.ps\" не може да Ñе пронађе"
+
+#, c-format
+msgid "E620: Unable to convert to print encoding \"%s\""
+msgstr "E620: Ðије могућа конверзија у кодирање за штампу \"%s\""
+
+msgid "Sending to printer..."
+msgstr "Слање штампачу..."
+
+msgid "E365: Failed to print PostScript file"
+msgstr "E365: PostScript датотека није уÑпела да Ñе одштампа"
+
+msgid "Print job sent."
+msgstr "Задатак штампе је поÑлат"
+
+msgid "Add a new database"
+msgstr "Додај нову базу"
+
+msgid "Query for a pattern"
+msgstr "Упит за шаблон"
+
+msgid "Show this message"
+msgstr "Прикажи ову поруку"
+
+msgid "Kill a connection"
+msgstr "Затвори везу"
+
+msgid "Reinit all connections"
+msgstr "Поново иницијализуј Ñве везе"
+
+msgid "Show connections"
+msgstr "Прикажи везе"
+
+#, c-format
+msgid "E560: Usage: cs[cope] %s"
+msgstr "E560: Употреба: cs[cope] %s"
+
+msgid "This cscope command does not support splitting the window.\n"
+msgstr "Ова cscope команда не подржава поделу прозора.\n"
+
+msgid "E562: Usage: cstag <ident>"
+msgstr "E562: Употреба: cstag <ident>"
+
+msgid "E257: cstag: tag not found"
+msgstr "E257: cstag: ознака није пронађена"
+
+#, c-format
+msgid "E563: stat(%s) error: %d"
+msgstr "E563: stat(%s) грешка: %d"
+
+msgid "E563: stat error"
+msgstr "E563: stat грешка"
+
+#, c-format
+msgid "E564: %s is not a directory or a valid cscope database"
+msgstr "E564: %s није директоријум или валидна cscope база података"
+
+#, c-format
+msgid "Added cscope database %s"
+msgstr "cscope база података %s је додата"
+
+#, c-format
+msgid "E262: error reading cscope connection %ld"
+msgstr "E262: грешка код читања cscope везе %ld"
+
+msgid "E561: unknown cscope search type"
+msgstr "E561: непознат cscope тип претраге"
+
+msgid "E566: Could not create cscope pipes"
+msgstr "E566: cscope процеÑни токови ниÑу могли да Ñе креирају"
+
+msgid "E622: Could not fork for cscope"
+msgstr "E622: Рачвање за cscope није уÑпело"
+
+msgid "cs_create_connection setpgid failed"
+msgstr "cs_create_connection setpgid није уÑпео"
+
+msgid "cs_create_connection exec failed"
+msgstr "cs_create_connection exec није уÑпео"
+
+msgid "cs_create_connection: fdopen for to_fp failed"
+msgstr "cs_create_connection: fdopen за to_fp није уÑпео"
+
+msgid "cs_create_connection: fdopen for fr_fp failed"
+msgstr "cs_create_connection: fdopen за fr_fp није уÑпео"
+
+msgid "E623: Could not spawn cscope process"
+msgstr "E623: Мрешћење cscope процеÑа није уÑпело"
+
+msgid "E567: no cscope connections"
+msgstr "E567: нема cscope веза"
+
+#, c-format
+msgid "E469: invalid cscopequickfix flag %c for %c"
+msgstr "E469: неиÑправан cscopequickfix индикатор %c за %c"
+
+#, c-format
+msgid "E259: no matches found for cscope query %s of %s"
+msgstr "E259: ниÑу пронађена подударања за cscope упит %s на %s"
+
+msgid "cscope commands:\n"
+msgstr "cscope команде:\n"
+
+#, c-format
+msgid "%-5s: %s%*s (Usage: %s)"
+msgstr "%-5s: %s%*s (Употреба: %s)"
+
+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: Пронађи датотеке које #includе ову датотеку\n"
+" s: Пронађи овај C Ñимбол\n"
+" t: Пронађи овај текÑÑ‚ Ñтринг\n"
+
+#, c-format
+msgid "E625: cannot open cscope database: %s"
+msgstr "E625: cscope database: %s не може да Ñе отвори"
+
+msgid "E626: cannot get cscope database information"
+msgstr "E626: Инфорамције о cscope бази података не могу да Ñе добију"
+
+msgid "E568: duplicate cscope database not added"
+msgstr "E568: Дупликат cscope база података није додата"
+
+#, c-format
+msgid "E261: cscope connection %s not found"
+msgstr "E261: cscope веза %s није пронађена"
+
+#, c-format
+msgid "cscope connection %s closed"
+msgstr "cscope веза %s је затворена"
+
+msgid "E570: fatal error in cs_manage_matches"
+msgstr "E570: фатална грешка у cs_manage_matches"
+
+#, c-format
+msgid "Cscope tag: %s"
+msgstr "Cscope ознака: %s"
+
+msgid ""
+"\n"
+" # line"
+msgstr ""
+"\n"
+" # линија"
+
+msgid "filename / context / line\n"
+msgstr "датотека / контекÑÑ‚ / линија\n"
+
+#, c-format
+msgid "E609: Cscope error: %s"
+msgstr "E609: Cscope грешка: %s"
+
+msgid "All cscope databases reset"
+msgstr "Све cscope базе података реÑетоване"
+
+msgid "no cscope connections\n"
+msgstr "нема cscope веза\n"
+
+msgid " # pid database name prepend path\n"
+msgstr " # pid име базе података додај путању иÑпред\n"
+
+msgid "Lua library cannot be loaded."
+msgstr "Lua библиотека не може да Ñе учита"
+
+msgid "cannot save undo information"
+msgstr "инфорамције за опозив не могу да Ñе Ñачувају"
+
+msgid ""
+"E815: Sorry, this command is disabled, the MzScheme libraries could not be "
+"loaded."
+msgstr ""
+"E815: Жао нам је, ова команда је онемогућена, MzScheme библиотеке ниÑу могле "
+"да Ñе учитају."
+
+msgid ""
+"E895: Sorry, this command is disabled, the MzScheme's racket/base module "
+"could not be loaded."
+msgstr ""
+"E895: Жао нам је, ова команда је онемогућена, MzScheme-ов racket/base модул "
+"није могао да Ñе учита."
+
+msgid "invalid expression"
+msgstr "неиÑправан израз"
+
+msgid "expressions disabled at compile time"
+msgstr "изрази Ñу онемогућени у време компилације"
+
+msgid "hidden option"
+msgstr "Ñкривена опција"
+
+msgid "unknown option"
+msgstr "непозната опција"
+
+msgid "window index is out of range"
+msgstr "Ð¸Ð½Ð´ÐµÐºÑ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€Ð° је ван опÑега"
+
+msgid "couldn't open buffer"
+msgstr "бафер не може да Ñе отвори"
+
+msgid "cannot delete line"
+msgstr "линија не може да Ñе обрише"
+
+msgid "cannot replace line"
+msgstr "линија не може да Ñе замени"
+
+msgid "cannot insert line"
+msgstr "линија не може да Ñе уметне"
+
+msgid "string cannot contain newlines"
+msgstr "Ñтринг не може да Ñадржи нове редове"
+
+msgid "error converting Scheme values to Vim"
+msgstr "грешка при конверзији Scheme вредноÑти у Vim"
+
+msgid "Vim error: ~a"
+msgstr "Vim грешка: ~a"
+
+msgid "Vim error"
+msgstr "Vim грешка"
+
+msgid "buffer is invalid"
+msgstr "бафер је неважећи"
+
+msgid "window is invalid"
+msgstr "прозор је неважећи"
+
+msgid "linenr out of range"
+msgstr "linenr је ван опÑега"
+
+msgid "not allowed in the Vim sandbox"
+msgstr "није дозвољено у Vim sandbox-у"
+
+#, c-format
+msgid "E370: Could not load library %s"
+msgstr "E370: Библиотека %s није могла да Ñе учита"
+
+msgid "Sorry, this command is disabled: the Perl library could not be loaded."
+msgstr ""
+"Жао нам је, ова команда је онемогућена: Perl библиотека није могла да "
+"Ñе учита."
+
+msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
+msgstr "E299: Perl одређивање вредноÑти у sandbox-у је забрањено без Safe модула"
+
+msgid "E836: This Vim cannot execute :python after using :py3"
+msgstr "E836: Овај Vim не може да изврши :python након коришћења :py3"
+
+msgid ""
+"E263: Sorry, this command is disabled, the Python library could not be "
+"loaded."
+msgstr ""
+"E263: Жао нам је, ова команда је онемогућена, Python библиотека није могла "
+"да Ñе учита."
+
+msgid ""
+"E887: Sorry, this command is disabled, the Python's site module could not be "
+"loaded."
+msgstr ""
+"E887: Жао нам је, ова команда је онемогућена, Python-ов site модул није "
+"могао да Ñе учита."
+
+msgid "E659: Cannot invoke Python recursively"
+msgstr "E659: Python не може да Ñе позива рекурзивно"
+
+msgid "E837: This Vim cannot execute :py3 after using :python"
+msgstr "E837: Овај Vim не може да изврши :py3 након коришћења :python"
+
+msgid "E265: $_ must be an instance of String"
+msgstr "E265: $_ мора да буде инÑтанца String-а"
+
+msgid ""
+"E266: Sorry, this command is disabled, the Ruby library could not be loaded."
+msgstr ""
+"E266: Жао нам је, ова команда је онемогућена, Ruby библиотека није могла да "
+"Ñе учита."
+
+msgid "E267: unexpected return"
+msgstr "E267: неочекиван return"
+
+msgid "E268: unexpected next"
+msgstr "E268: неочекивано next"
+
+msgid "E269: unexpected break"
+msgstr "E269: неочекивано break"
+
+msgid "E270: unexpected redo"
+msgstr "E270: неочекивано redo"
+
+msgid "E271: retry outside of rescue clause"
+msgstr "E271: retry ван rescue клаузуле"
+
+msgid "E272: unhandled exception"
+msgstr "E272: необрађени изузетак"
+
+#, c-format
+msgid "E273: unknown longjmp status %d"
+msgstr "E273: непознат longjmp ÑÑ‚Ð°Ñ‚ÑƒÑ %d"
+
+msgid "invalid buffer number"
+msgstr "неиÑправан број бафера"
+
+msgid "not implemented yet"
+msgstr "још није имплементирано"
+
+msgid "cannot set line(s)"
+msgstr "линија(е) не може да Ñе поÑтави"
+
+msgid "invalid mark name"
+msgstr "неиÑправно име маркера"
+
+msgid "mark not set"
+msgstr "маркер није поÑтављен"
+
+#, c-format
+msgid "row %d column %d"
+msgstr "ред %d колона %d"
+
+msgid "cannot insert/append line"
+msgstr "линија не може да Ñе уметне/дода на крај"
+
+msgid "line number out of range"
+msgstr "број линије је ван опÑега"
+
+msgid "unknown flag: "
+msgstr "непознат индикатор"
+
+msgid "unknown vimOption"
+msgstr "непозната vimОпција"
+
+msgid "keyboard interrupt"
+msgstr "прекид таÑтатуре"
+
+msgid "vim error"
+msgstr "vim грешка"
+
+msgid "cannot create buffer/window command: object is being deleted"
+msgstr "бафер/прозор команда не може да Ñе креира: објекат Ñе брише"
+
+msgid ""
+"cannot register callback command: buffer/window is already being deleted"
+msgstr ""
+"команда повратног позива не може да Ñе региÑтрује: бафер/прозор је већ "
+"обриÑан"
+
+msgid ""
+"E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim."
+"org"
+msgstr ""
+"E280: TCL ФÐТÐЛÐРГРЕШКÐ: reflist је оштећена!? Молимо пријавите ово на "
+"vim-dev@vim.org"
+
+msgid "cannot register callback command: buffer/window reference not found"
+msgstr ""
+"команда повратног позива не може да Ñе региÑтрује: референца бафера/прозора "
+"није пронађена"
+
+msgid ""
+"E571: Sorry, this command is disabled: the Tcl library could not be loaded."
+msgstr ""
+"E571: Жао нам је, ова команда је онемогућена: Tcl библиотека није могла да "
+"Ñе учита."
+
+#, c-format
+msgid "E572: exit code %d"
+msgstr "E572: излазни код %d"
+
+msgid "cannot get line"
+msgstr "линија не може да Ñе добије"
+
+msgid "Unable to register a command server name"
+msgstr "Име Ñервера команди није могло да Ñе региÑтрује"
+
+msgid "E248: Failed to send command to the destination program"
+msgstr "E248: Слање команде циљном програму није уÑпело"
+
+#, c-format
+msgid "E573: Invalid server id used: %s"
+msgstr "E573: КориÑти Ñе неÑправан ид Ñервера: %s"
+
+msgid "E251: VIM instance registry property is badly formed. Deleted!"
+msgstr "E251: registry ÑвојÑтво VIM инÑтанце је лоше формирано. ОбриÑано!"
+
+#, c-format
+msgid "E938: Duplicate key in JSON: \"%s\""
+msgstr "E938: Дупли кључ у JSON: \"%s\""
+
+#, c-format
+msgid "E696: Missing comma in List: %s"
+msgstr "E696: У ЛиÑти недоÑтаје зарез: %s"
+
+#, c-format
+msgid "E697: Missing end of List ']': %s"
+msgstr "E697: ÐедоÑтаје крај ЛиÑте ']': %s"
+
+msgid "Unknown option argument"
+msgstr "Ðепознат аргумент опције"
+
+msgid "Too many edit arguments"
+msgstr "Сувише аргумента уређивања"
+
+msgid "Argument missing after"
+msgstr "Ðргумент недоÑтаје након"
+
+msgid "Garbage after option argument"
+msgstr "Смеће након аргумента опције"
+
+msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
+msgstr "Сувише \"+command\", \"-c command\" или \"--cmd command\" аргумената"
+
+msgid "Invalid argument for"
+msgstr "ÐеиÑправан аргумент for"
+
+#, c-format
+msgid "%d files to edit\n"
+msgstr "%d датотека за уређивање\n"
+
+msgid "netbeans is not supported with this GUI\n"
+msgstr "NetBeans није подржан Ñа овим GUI\n"
+
+msgid "'-nb' cannot be used: not enabled at compile time\n"
+msgstr "'-nb' не може да Ñе кориÑти: није омогућено у време компилације\n"
+
+msgid "This Vim was not compiled with the diff feature."
+msgstr "Овај Vim није компајлиран Ñа diff могућношћу."
+
+msgid "Attempt to open script file again: \""
+msgstr "Покушај да Ñе поново отвори Ñкрипт датотека: \""
+
+msgid "Cannot open for reading: \""
+msgstr "Ðе може да Ñе отвори за читање: \""
+
+msgid "Cannot open for script output: \""
+msgstr "Ðе може да Ñе отвори за излаз Ñкрипте: \""
+
+msgid "Vim: Error: Failure to start gvim from NetBeans\n"
+msgstr "Vim: Грешка: Покретање gvim из NetBeans није уÑпело\n"
+
+msgid "Vim: Error: This version of Vim does not run in a Cygwin terminal\n"
+msgstr ""
+"Vim: Грешка: Ова верзија Vim не може да Ñе покрене из Cygwin терминала\n"
+
+msgid "Vim: Warning: Output is not to a terminal\n"
+msgstr "Vim: Упозорење: Излаз није у терминал\n"
+
+msgid "Vim: Warning: Input is not from a terminal\n"
+msgstr "Vim: Упозорење: Улаз није из терминала\n"
+
+msgid "pre-vimrc command line"
+msgstr "pre-vimrc командна линија"
+
+#, c-format
+msgid "E282: Cannot read from \"%s\""
+msgstr "E282: Ðе може да Ñе чита из \"%s\""
+
+msgid ""
+"\n"
+"More info with: \"vim -h\"\n"
+msgstr ""
+"\n"
+"Више инфо Ñа: \"vim -h\"\n"
+
+msgid "[file ..] edit specified file(s)"
+msgstr "[датотека ..] уређуј наведену(е) датотеку(е)"
+
+msgid "- read text from stdin"
+msgstr "- читај текÑÑ‚ Ñа stdin"
+
+msgid "-t tag edit file where tag is defined"
+msgstr "-t tag уређуј датотеку где је дефиниÑана ознака"
+
+msgid "-q [errorfile] edit file with first error"
+msgstr "-q [дат.грешке] уређуј датотеку Ñа првом грешком"
+
+msgid ""
+"\n"
+"\n"
+"Usage:"
+msgstr ""
+"\n"
+"\n"
+"Употреба:"
+
+msgid " vim [arguments] "
+msgstr " vim [аргументи] "
+
+msgid ""
+"\n"
+" or:"
+msgstr ""
+"\n"
+" или:"
+
+msgid ""
+"\n"
+"Where case is ignored prepend / to make flag upper case"
+msgstr ""
+"\n"
+"Где Ñе мала/велика Ñлова игноришу Ñтавите иÑпред / како би претворили "
+"индикатор у велика Ñлова"
+
+msgid ""
+"\n"
+"\n"
+"Arguments:\n"
+msgstr ""
+"\n"
+"\n"
+"Ðргументи:\n"
+
+msgid "--\t\t\tOnly file names after this"
+msgstr "--\t\t\tСамо имена датотека након овога"
+
+msgid "--literal\t\tDon't expand wildcards"
+msgstr "--literal\t\tÐе развијај џокере"
+
+msgid "-register\t\tRegister this gvim for OLE"
+msgstr "-register\t\tРегиÑтруј овај gvim за OLE"
+
+msgid "-unregister\t\tUnregister gvim for OLE"
+msgstr "-unregister\t\tУклони региÑтрацију gvim за OLE"
+
+msgid "-g\t\t\tRun using GUI (like \"gvim\")"
+msgstr "-g\t\t\tПокрени кориÑтећи GUI (као \"gvim\")"
+
+msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
+msgstr "-f или --nofork\tУ предњем плану: немој да рачваш кад Ñе покреће GUI"
+
+msgid "-v\t\t\tVi mode (like \"vi\")"
+msgstr "-v\t\t\tVi режим (као \"vi\")"
+
+msgid "-e\t\t\tEx mode (like \"ex\")"
+msgstr "-e\t\t\tEx режим (као \"ex\")"
+
+msgid "-E\t\t\tImproved Ex mode"
+msgstr "-E\t\t\tУнапређен Ex режим"
+
+msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
+msgstr "-s\t\t\tÐечујни (batch) режим (Ñамо за \"ex\")"
+
+msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
+msgstr "-d\t\t\tDiff режим (као \"vimdiff\")"
+
+msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
+msgstr "-y\t\t\tEasy режим (као \"evim\", безрежимни)"
+
+msgid "-R\t\t\tReadonly mode (like \"view\")"
+msgstr "-R\t\t\tReadonly режим (као \"view\")"
+
+msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
+msgstr "-Z\t\t\tRestricted режим (као \"rvim\")"
+
+msgid "-m\t\t\tModifications (writing files) not allowed"
+msgstr "-m\t\t\tИзмене (упиÑивање датотека) ниÑу дозвољене"
+
+msgid "-M\t\t\tModifications in text not allowed"
+msgstr "-M\t\t\tИзмене у текÑту ниÑу дозвољене"
+
+msgid "-b\t\t\tBinary mode"
+msgstr "-b\t\t\tБинарни режим"
+
+msgid "-l\t\t\tLisp mode"
+msgstr "-l\t\t\tLisp режим"
+
+msgid "-C\t\t\tCompatible with Vi: 'compatible'"
+msgstr "-C\t\t\tКомпатибилан Ñа Vi: 'compatible'"
+
+msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
+msgstr "-N\t\t\tÐе потпуно Vi компатибилан: 'nocompatible'"
+
+msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
+msgstr "-V[N][fname]\t\tБуди опширан [ниво N] [бележи поруке у fname]"
+
+msgid "-D\t\t\tDebugging mode"
+msgstr "-D\t\t\tDebugging режим"
+
+msgid "-n\t\t\tNo swap file, use memory only"
+msgstr "-n\t\t\tБез swap датотеке, кориÑти Ñамо меморију"
+
+msgid "-r\t\t\tList swap files and exit"
+msgstr "-r\t\t\tИзлиÑтај swap датотеке и изађи"
+
+msgid "-r (with file name)\tRecover crashed session"
+msgstr "-r (Ñа именом датотеке)\tОбнови Ñрушену ÑеÑију"
+
+msgid "-L\t\t\tSame as -r"
+msgstr "-L\t\t\tИÑто као -r"
+
+msgid "-f\t\t\tDon't use newcli to open window"
+msgstr "-f\t\t\tÐемој да кориÑтиш нов cli да отвориш прозор"
+
+msgid "-dev <device>\t\tUse <device> for I/O"
+msgstr "-dev <уређај>\t\tКориÑти <уређај> за У/И"
+
+msgid "-A\t\t\tStart in Arabic mode"
+msgstr "-A\t\t\tПокрени у ÐрапÑком режиму"
+
+msgid "-H\t\t\tStart in Hebrew mode"
+msgstr "-H\t\t\tПокрени у ХебрејÑком режиму"
+
+msgid "-F\t\t\tStart in Farsi mode"
+msgstr "-F\t\t\tПокрени у ФарÑи режиму"
+
+msgid "-T <terminal>\tSet terminal type to <terminal>"
+msgstr "-T <терминал>\tПоÑтави тип терминала на <терминал>"
+
+msgid "--not-a-term\t\tSkip warning for input/output not being a terminal"
+msgstr "--not-a-term\t\tПреÑкочи упозорење да улаз/излаз није терминал"
+
+msgid "--ttyfail\t\tExit if input or output is not a terminal"
+msgstr "--ttyfail\t\tИзађи ако улаз или излаз ниÑу терминал"
+
+msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
+msgstr "-u <vimrc>\t\tКориÑти <vimrc> умеÑто било ког .vimrc"
+
+msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
+msgstr "-U <gvimrc>\t\tКориÑти <gvimrc> умеÑто било ког .gvimrc"
+
+msgid "--noplugin\t\tDon't load plugin scripts"
+msgstr "--noplugin\t\tÐе учитавај Ñкрипте додатака"
+
+msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
+msgstr "-p[N]\t\tОтвори N картица (подразумевано: по једну за Ñваку датотеку)"
+
+msgid "-o[N]\t\tOpen N windows (default: one for each file)"
+msgstr "-o[N]\t\tОтвори N прозора (подразумевано: по један за Ñваку датотеку)"
+
+msgid "-O[N]\t\tLike -o but split vertically"
+msgstr "-O[N]\t\tКао -o али подели по вертикали"
+
+msgid "+\t\t\tStart at end of file"
+msgstr "+\t\t\tПочни на крају датотеке"
+
+msgid "+<lnum>\t\tStart at line <lnum>"
+msgstr "+<бројл>\t\tПочни на линији <бројл>"
+
+msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
+msgstr ""
+"--cmd <команда>\tИзврши <команда> пре учитавања било које vimrc датотеке"
+
+msgid "-c <command>\t\tExecute <command> after loading the first file"
+msgstr "-c <команда>\t\tИзврши <команда> након учитавања прве датотеке"
+
+msgid "-S <session>\t\tSource file <session> after loading the first file"
+msgstr ""
+"-S <ÑеÑија>\t\tИзворна датотека <ÑеÑија> након учитавања прве "
+"датотеке"
+
+msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
+msgstr ""
+"-s <Ñкриптулаз>\tЧитај команде Ðормалног режима из датотеке <Ñкриптулаз>"
+
+msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
+msgstr ""
+"-w <Ñкриптизлаз>\tÐадовежи Ñве откуцане команде на крај датотеке "
+"<Ñкриптизлаз>"
+
+msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
+msgstr "-W <Ñкриптизлаз>\tУпиÑуј Ñве откуцане команде у датотеку <Ñкриптизлаз>"
+
+msgid "-x\t\t\tEdit encrypted files"
+msgstr "-x\t\t\tУређуј шифроване датотеке"
+
+msgid "-display <display>\tConnect vim to this particular X-server"
+msgstr "-display <диÑплеј>\tПовежи vim на овај X-Ñервер"
+
+msgid "-X\t\t\tDo not connect to X server"
+msgstr "-X\t\t\tÐе повезуј Ñе на X Ñервер"
+
+msgid "--remote <files>\tEdit <files> in a Vim server if possible"
+msgstr "--remote <датотеке>\tУређуј <датотеке> у Vim Ñерверу ако је могуће"
+
+msgid "--remote-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-silent <датотеке> ИÑто, не буни Ñе ако нема Ñервера"
+
+msgid ""
+"--remote-wait <files> As --remote but wait for files to have been edited"
+msgstr ""
+"--remote-wait <датотеке> Као --remote али чекај да датотеке буду уређене"
+
+msgid ""
+"--remote-wait-silent <files> Same, don't complain if there is no server"
+msgstr "--remote-wait-silent <датотеке> ИÑто, не буни Ñе ако нема Ñервера"
+
+msgid ""
+"--remote-tab[-wait][-silent] <files> As --remote but use tab page per file"
+msgstr ""
+"--remote-tab[-wait][-silent] <датотеке> Као --remote али кориÑти једну "
+"картицу по датотеци"
+
+msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
+msgstr "--remote-send <таÑтери>\tПошаљи <таÑтери> Vim Ñерверу и изађи"
+
+msgid "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
+msgstr ""
+"--remote-expr <израз>\tИзрачунај <израз> у Vim Ñерверу и одштампај резултат"
+
+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 <име>\tПошаљи/поÑтани Vim Ñервер <име>"
+
+msgid "--startuptime <file>\tWrite startup timing messages to <file>"
+msgstr "--startuptime <датотека>\tУпиши поруке о дужини покретања у <датотеку>"
+
+msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
+msgstr "-i <viminfo>\t\tКориÑти <viminfo> умеÑто .viminfo"
+
+msgid "--clean\t\t'nocompatible', Vim defaults, no plugins, no viminfo"
+msgstr ""
+"--clean\t\t'nocompatible', Vim подразумеване вредноÑти, без додатака, без "
+"viminfo"
+
+msgid "-h or --help\tPrint Help (this message) and exit"
+msgstr "-h or --help\tИÑпиши Помоћ (ову поруку) и изађи"
+
+msgid "--version\t\tPrint version information and exit"
+msgstr "--version\t\tИÑпиши информације о верзији и изађи"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Motif version):\n"
+msgstr ""
+"\n"
+"Ðргументи које препознаје gvim (Motif верзија):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (neXtaw version):\n"
+msgstr ""
+"\n"
+"Ðргументи које препознаје gvim (neXtaw верзија):\n"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (Athena version):\n"
+msgstr ""
+"\n"
+"Ðргументи које препознаје gvim (Athena верзија):\n"
+
+msgid "-display <display>\tRun vim on <display>"
+msgstr "-display <диÑплеј>\tПокрени vim на <диÑплеј>"
+
+msgid "-iconic\t\tStart vim iconified"
+msgstr "-iconic\t\tПокрени vim као икону"
+
+msgid "-background <color>\tUse <color> for the background (also: -bg)"
+msgstr "-background <боја>\tКориÑти <боја> за позадину (такође: -bg)"
+
+msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
+msgstr "-foreground <боја>\tКориÑти <боја> за нормални текÑÑ‚ (такође: -fg)"
+
+msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
+msgstr "-font <фонт>\t\tКориÑти <фонт> за нормални текÑÑ‚ (такође: -fn)"
+
+msgid "-boldfont <font>\tUse <font> for bold text"
+msgstr "-boldfont <фонт>\tКориÑти <фонт> за подебљани текÑÑ‚"
+
+msgid "-italicfont <font>\tUse <font> for italic text"
+msgstr "-italicfont <фонт>\tКориÑти <фонт> за курзивни текÑÑ‚"
+
+msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
+msgstr "-geometry <геом>\tКориÑти <геом> за почетну геометрију (такође: -geom)"
+
+msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
+msgstr "-borderwidth <ширина>\tКориÑти оквир ширине <ширина> (такође: -bw)"
+
+msgid "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
+msgstr ""
+"-scrollbarwidth <ширина> КориÑти Линију за Ñкроловање ширине <ширина> "
+"(такође: -sw)"
+
+msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
+msgstr ""
+"-menuheight <ширина>\tКориÑти линију менија виÑине <виÑина> (такође: -mh)"
+
+msgid "-reverse\t\tUse reverse video (also: -rv)"
+msgstr "-reverse\t\tКориÑти обрнути видео (такође: -rv)"
+
+msgid "+reverse\t\tDon't use reverse video (also: +rv)"
+msgstr "+reverse\t\tÐемој да кориÑтиш обрнути видео (такође: +rv)"
+
+msgid "-xrm <resource>\tSet the specified resource"
+msgstr "-xrm <реÑурÑ>\tПоÑтави наведени реÑурÑ"
+
+msgid ""
+"\n"
+"Arguments recognised by gvim (GTK+ version):\n"
+msgstr ""
+"\n"
+"Ðргументи које препознаје gvim (GTK+ верзија):\n"
+
+msgid "-display <display>\tRun vim on <display> (also: --display)"
+msgstr "-display <диÑплеј>\tПокрени vim на <диÑплеј> (такође: --display)"
+
+msgid "--role <role>\tSet a unique role to identify the main window"
+msgstr ""
+"--role <улога>\tПоÑтави јединÑтвену улогу да би Ñе идентификовао главни "
+"прозор"
+
+msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
+msgstr "--socketid <xid>\tОтвори Vim унутар другог GTK виџета"
+
+msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
+msgstr "--echo-wid\t\tÐека gvim иÑпише Window ID на stdout"
+
+msgid "-P <parent title>\tOpen Vim inside parent application"
+msgstr "-P <назив родитеља>\tОтвори Vim унутар родитељÑке апликације"
+
+msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
+msgstr "--windowid <HWND>\tОтвори Vim унутар другог win32 виџета"
+
+msgid "No display"
+msgstr "Ðема приказа"
+
+msgid ": Send failed.\n"
+msgstr ": Слање није уÑпело.\n"
+
+msgid ": Send failed. Trying to execute locally\n"
+msgstr ": Слање није уÑпело. Покушава Ñе локално извршавање\n"
+
+#, c-format
+msgid "%d of %d edited"
+msgstr "%d од %d уређено"
+
+msgid "No display: Send expression failed.\n"
+msgstr "Ðема приказа: Израз Ñлања није уÑпео.\n"
+
+msgid ": Send expression failed.\n"
+msgstr ": Израз Ñлања није уÑпео.\n"
+
+msgid "No marks set"
+msgstr "Ðема поÑтављених маркера"
+
+#, c-format
+msgid "E283: No marks matching \"%s\""
+msgstr "E283: Ðема маркера који Ñе подударају Ñа \"%s\""
+
+msgid ""
+"\n"
+"mark line col file/text"
+msgstr ""
+"\n"
+"линија маркера кол датотека/текÑÑ‚"
+
+msgid ""
+"\n"
+" jump line col file/text"
+msgstr ""
+"\n"
+" линија Ñкока кол датотека/текÑÑ‚"
+
+msgid ""
+"\n"
+"change line col text"
+msgstr ""
+"\n"
+"линија промене кол текÑÑ‚"
+
+msgid ""
+"\n"
+"# File marks:\n"
+msgstr ""
+"\n"
+"# Маркери датотеке:\n"
+
+msgid ""
+"\n"
+"# Jumplist (newest first):\n"
+msgstr ""
+"\n"
+"# Скок-лиÑта (прво најновији):\n"
+
+msgid ""
+"\n"
+"# History of marks within files (newest to oldest):\n"
+msgstr ""
+"\n"
+"# ИÑторија маркера унутар датотека (ок најновијег до најÑтаријег):\n"
+
+msgid "Missing '>'"
+msgstr "ÐедоÑтаје '>'"
+
+msgid "E543: Not a valid codepage"
+msgstr "E543: Ðеважећа кодна Ñтрана"
+
+msgid "E284: Cannot set IC values"
+msgstr "E284: IC вредноÑти не могу да Ñе поÑтаве"
+
+msgid "E285: Failed to create input context"
+msgstr "E285: Креирање контекÑта уноÑа није уÑпело"
+
+msgid "E286: Failed to open input method"
+msgstr "E286: Отварање методе уноÑа није уÑпело"
+
+msgid "E287: Warning: Could not set destroy callback to IM"
+msgstr ""
+"E287: Упозорење: ПоÑтављање повратне функције за уништење IM није уÑпело"
+
+msgid "E288: input method doesn't support any style"
+msgstr "E288: метод уноÑа не подржава ниједан Ñтил"
+
+msgid "E289: input method doesn't support my preedit type"
+msgstr "E289: метод уноÑа не подржава мој preedit тип"
+
+msgid "E293: block was not locked"
+msgstr "E293: блок није закључан"
+
+msgid "E294: Seek error in swap file read"
+msgstr "E294: Грешка код поÑтављања показивача за читање swap датотеке"
+
+msgid "E295: Read error in swap file"
+msgstr "E295: Грешка при читању swap датотеке"
+
+msgid "E296: Seek error in swap file write"
+msgstr "E296: Грешка код поÑтављања показивача за ÑƒÐ¿Ð¸Ñ swap датотеке"
+
+msgid "E297: Write error in swap file"
+msgstr "E297: Грешка при упиÑу swap датотеке"
+
+msgid "E300: Swap file already exists (symlink attack?)"
+msgstr "E300: Swap датотека већ поÑтоји (symlink напад?)"
+
+msgid "E298: Didn't get block nr 0?"
+msgstr "E298: Блок бр 0 није добављен?"
+
+msgid "E298: Didn't get block nr 1?"
+msgstr "E298: Блок бр 1 није добављен?"
+
+msgid "E298: Didn't get block nr 2?"
+msgstr "E298: Блок бр 2 није добављен?"
+
+msgid "E843: Error while updating swap file crypt"
+msgstr "E843: Грешка приликом оÑважавања криптовања swap датотеке"
+
+msgid "E301: Oops, lost the swap file!!!"
+msgstr "E301: УупÑ, swap датотека је изгубљена!!!"
+
+msgid "E302: Could not rename swap file"
+msgstr "E302: Промена имена swap датотеке није уÑпела"
+
+#, c-format
+msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
+msgstr ""
+"E303: Отварање swap датотеке за \"%s\" није уÑпело, опоравак је немогућ"
+
+msgid "E304: ml_upd_block0(): Didn't get block 0??"
+msgstr "E304: ml_upd_block0(): Блок бр 0 није добављен??"
+
+#, c-format
+msgid "E305: No swap file found for %s"
+msgstr "E305: За %s није пронађена swap датотека"
+
+msgid "Enter number of swap file to use (0 to quit): "
+msgstr "УнеÑите број swap датотеке која ће да Ñе кориÑти (0 за отказивање): "
+
+#, c-format
+msgid "E306: Cannot open %s"
+msgstr "E306: %s не може да Ñе отвори"
+
+msgid "Unable to read block 0 from "
+msgstr "Ðије могуће литање блока 0 из "
+
+msgid ""
+"\n"
+"Maybe no changes were made or Vim did not update the swap file."
+msgstr ""
+"\n"
+"Можда ниÑу направљене никакве измене или Vim није оÑвежио swap датотеку."
+
+msgid " cannot be used with this version of Vim.\n"
+msgstr " не може да Ñе кориÑти Ñа овом верзијом Vim-а.\n"
+
+msgid "Use Vim version 3.0.\n"
+msgstr "КориÑтите Vim верзијe 3.0.\n"
+
+#, c-format
+msgid "E307: %s does not look like a Vim swap file"
+msgstr "E307: %s не изгледа као Vim swap датотека"
+
+msgid " cannot be used on this computer.\n"
+msgstr " не може да Ñе кориÑти на овом компјутеру.\n"
+
+msgid "The file was created on "
+msgstr "Ова датотека је креирана Ñа "
+
+msgid ""
+",\n"
+"or the file has been damaged."
+msgstr ""
+",\n"
+"или је датотека оштећена."
+
+#, c-format
+msgid ""
+"E833: %s is encrypted and this version of Vim does not support encryption"
+msgstr "E833: %s је шифрована и ова верзија Vim-а не подржава шифровање"
+
+msgid " has been damaged (page size is smaller than minimum value).\n"
+msgstr " је оштећена (величина Ñтранице је маља од минималне вредноÑти).\n"
+
+#, c-format
+msgid "Using swap file \"%s\""
+msgstr "КориÑти Ñе swap датотека \"%s\""
+
+#, c-format
+msgid "Original file \"%s\""
+msgstr "Оригинална датотека \"%s\""
+
+msgid "E308: Warning: Original file may have been changed"
+msgstr "E308: Упозорење: Можда је промењена оригинална датотека"
+
+#, c-format
+msgid "Swap file is encrypted: \"%s\""
+msgstr "Swap датотека је шифрована: \"%s\""
+
+msgid ""
+"\n"
+"If you entered a new crypt key but did not write the text file,"
+msgstr ""
+"\n"
+"Ðко Ñте унели нов кључ за шифрирање али ниÑте упиÑали текÑÑ‚ датотеку,"
+
+msgid ""
+"\n"
+"enter the new crypt key."
+msgstr ""
+"\n"
+"унеÑите нови кључ за шифрирање."
+
+msgid ""
+"\n"
+"If you wrote the text file after changing the crypt key press enter"
+msgstr ""
+"\n"
+"Ðко Ñте упиÑали текÑÑ‚ датотеку на диÑк након промене кључа за шифрирање "
+"притиÑните ентер"
+
+msgid ""
+"\n"
+"to use the same key for text file and swap file"
+msgstr ""
+"\n"
+"да биÑте кориÑтили иÑти кључ за текÑÑ‚ датотеку и swap датотеку"
+
+#, c-format
+msgid "E309: Unable to read block 1 from %s"
+msgstr "E309: Блок 1 из %s не може да Ñе прочита"
+
+msgid "???MANY LINES MISSING"
+msgstr "??ÐЕДОСТÐЈЕ МÐОГО ЛИÐИЈÐ"
+
+msgid "???LINE COUNT WRONG"
+msgstr "???БРОЈ ЛИÐИЈРЈЕ ПОГРЕШÐÐ"
+
+msgid "???EMPTY BLOCK"
+msgstr "???ПРÐЗÐРБЛОК"
+
+msgid "???LINES MISSING"
+msgstr "???ÐЕДОСТÐЈУ ЛИÐИЈЕ"
+
+#, c-format
+msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
+msgstr "E310: ID блока 1 је погрешан (%s није .swp датотека?)"
+
+msgid "???BLOCK MISSING"
+msgstr "???ÐЕДОСТÐЈЕ БЛОК"
+
+msgid "??? from here until ???END lines may be messed up"
+msgstr "??? одавде па до ???КРÐЈ линије Ñу можда забрљане"
+
+msgid "??? from here until ???END lines may have been inserted/deleted"
+msgstr "??? одавде па до ???КРÐЈ линије Ñу можда уметане/бриÑане"
+
+msgid "???END"
+msgstr "???КРÐЈ"
+
+msgid "E311: Recovery Interrupted"
+msgstr "E311: Опоравак је прекинут"
+
+msgid ""
+"E312: Errors detected while recovering; look for lines starting with ???"
+msgstr ""
+"E312: Откривене Ñу грешке приликом опоравка; потражите линије које почињу "
+"Ñа ???"
+
+msgid "See \":help E312\" for more information."
+msgstr "Погледајте \":help E312\" за више информација."
+
+msgid "Recovery completed. You should check if everything is OK."
+msgstr "Опоравак је завршен. Требало би да проверите да ли је Ñве OK."
+
+msgid ""
+"\n"
+"(You might want to write out this file under another name\n"
+msgstr ""
+"\n"
+"(Можда биÑте хтели да запишете ову датотеку под другим именом\n"
+
+msgid "and run diff with the original file to check for changes)"
+msgstr "и покренете diff Ñа оригиналном датотеком да провелите има ли измена)"
+
+msgid "Recovery completed. Buffer contents equals file contents."
+msgstr "Опоравак је завршен. Садржај бафера је иÑтоветан Ñадржају датотеке."
+
+msgid ""
+"\n"
+"You may want to delete the .swp file now.\n"
+"\n"
+msgstr ""
+"\n"
+"Сада можда желите да обришете .swp датотеку.\n"
+"\n"
+
+msgid "Using crypt key from swap file for the text file.\n"
+msgstr "За текÑÑ‚ датотеку Ñе кориÑти кључ за шифрирање из swap датотеке.\n"
+
+msgid "Swap files found:"
+msgstr "Пронађене Ñу swap датотеке:"
+
+msgid " In current directory:\n"
+msgstr " У текућем директоријуму:\n"
+
+msgid " Using specified name:\n"
+msgstr " КориÑтећи наведено име:\n"
+
+msgid " In directory "
+msgstr " У директоријуму "
+
+msgid " -- none --\n"
+msgstr " -- ниједна --\n"
+
+msgid " owned by: "
+msgstr " које поÑедује: "
+
+msgid " dated: "
+msgstr " датиране: "
+
+msgid " dated: "
+msgstr " датиране: "
+
+msgid " [from Vim version 3.0]"
+msgstr " [од Vim верзије 3.0]"
+
+msgid " [does not look like a Vim swap file]"
+msgstr " [не изгледа као Vim swap датотека]"
+
+msgid " file name: "
+msgstr " име датотеке: "
+
+msgid ""
+"\n"
+" modified: "
+msgstr ""
+"\n"
+" измењено: "
+
+msgid "YES"
+msgstr "ДÐ"
+
+msgid "no"
+msgstr "не"
+
+msgid ""
+"\n"
+" user name: "
+msgstr ""
+"\n"
+" кориÑничко име: "
+
+msgid " host name: "
+msgstr " име хоÑта: "
+
+msgid ""
+"\n"
+" host name: "
+msgstr ""
+"\n"
+" име хоÑта: "
+
+msgid ""
+"\n"
+" process ID: "
+msgstr ""
+"\n"
+" ИД процеÑа: "
+
+msgid " (still running)"
+msgstr " (још Ñе извршава)"
+
+msgid ""
+"\n"
+" [not usable with this version of Vim]"
+msgstr ""
+"\n"
+" [није употребљива Ñа овом верзијом Vim-а]"
+
+msgid ""
+"\n"
+" [not usable on this computer]"
+msgstr ""
+"\n"
+" [није употребљива на овом компјутеру]"
+
+msgid " [cannot be read]"
+msgstr " [не може да Ñе прочита]"
+
+msgid " [cannot be opened]"
+msgstr " [не може да Ñе отвори]"
+
+msgid "E313: Cannot preserve, there is no swap file"
+msgstr "E313: Ðе може да Ñе презервира, нема swap датотеке"
+
+msgid "File preserved"
+msgstr "Датотека је презервирана"
+
+msgid "E314: Preserve failed"
+msgstr "E314: Презервација није уÑпела"
+
+#, c-format
+msgid "E315: ml_get: invalid lnum: %ld"
+msgstr "E315: ml_get: неиÑправан lnum: %ld"
+
+#, c-format
+msgid "E316: ml_get: cannot find line %ld"
+msgstr "E316: ml_get: линија %ld не може да Ñе пронађе"
+
+msgid "E317: pointer block id wrong 3"
+msgstr "E317: ид показивача блока је погрешан 3"
+
+msgid "stack_idx should be 0"
+msgstr "stack_idx би требало да је 0"
+
+msgid "E318: Updated too many blocks?"
+msgstr "E318: ОÑвежено превише блокова?"
+
+msgid "E317: pointer block id wrong 4"
+msgstr "E317: ид показивача блока је погрешан 4"
+
+msgid "deleted block 1?"
+msgstr "блок 1 обриÑан?"
+
+#, c-format
+msgid "E320: Cannot find line %ld"
+msgstr "E320: Линија %ld не може да Ñе пронађе"
+
+msgid "E317: pointer block id wrong"
+msgstr "E317: ид показивача блока је погрешан"
+
+msgid "pe_line_count is zero"
+msgstr "pe_line_count је нула"
+
+#, c-format
+msgid "E322: line number out of range: %ld past the end"
+msgstr "E322: број линије је ван опÑега: %ld иза краја"
+
+#, c-format
+msgid "E323: line count wrong in block %ld"
+msgstr "E323: број линија је погрешан у блоку %ld"
+
+msgid "Stack size increases"
+msgstr "Величина Ñтека Ñе повећава"
+
+msgid "E317: pointer block id wrong 2"
+msgstr "E317: ид показивача блока је погрешан 2"
+
+#, c-format
+msgid "E773: Symlink loop for \"%s\""
+msgstr "E773: Symlink петља за \"%s\""
+
+msgid "E325: ATTENTION"
+msgstr "E325: ПÐЖЊÐ"
+
+msgid ""
+"\n"
+"Found a swap file by the name \""
+msgstr ""
+"\n"
+"Пронађена је swap датотека под именом \""
+
+msgid "While opening file \""
+msgstr "Док Ñе отварала датотекa \""
+
+msgid " NEWER than swap file!\n"
+msgstr " ÐОВИЈРод swap датотеке!\n"
+
+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. Quit, or continue with caution.\n"
+msgstr ""
+"\n"
+"(1) Можда други програм уређује иÑту датотеку. Ðко је ово Ñлучај,\n"
+" кад правите измене, пазите да не завршите Ñа две различите\n"
+" инÑтанце иÑте датотеке. Изађите, или опрезно наÑтавите.\n"
+
+msgid "(2) An edit session for this file crashed.\n"
+msgstr "(2) СеÑија уређивања ове датотеке Ñе Ñрушила.\n"
+
+msgid " If this is the case, use \":recover\" or \"vim -r "
+msgstr " Ðко је ово Ñлучај, кориÑтите \":recover\" или \"vim -r "
+
+msgid ""
+"\"\n"
+" to recover the changes (see \":help recovery\").\n"
+msgstr ""
+"\"\n"
+" да опоравите измене (погледајте \":help recovery\").\n"
+
+msgid " If you did this already, delete the swap file \""
+msgstr " Ðко Ñте ово већ учинили, обришите swap датотеку \""
+
+msgid ""
+"\"\n"
+" to avoid this message.\n"
+msgstr ""
+"\"\n"
+" како би избегли ову поруку.\n"
+
+msgid "Swap file \""
+msgstr "Swap датотека \""
+
+msgid "\" already exists!"
+msgstr "\" већ поÑтоји!"
+
+msgid "VIM - ATTENTION"
+msgstr "VIM - ПÐЖЊÐ"
+
+msgid "Swap file already exists!"
+msgstr "Swap датотека већ поÑтоји!"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"Отвори &Само за читање\n"
+"Ипак &Уређуј\n"
+"&Опорави\n"
+"&Изађи\n"
+"&Прекини"
+
+msgid ""
+"&Open Read-Only\n"
+"&Edit anyway\n"
+"&Recover\n"
+"&Delete it\n"
+"&Quit\n"
+"&Abort"
+msgstr ""
+"Отвори &Само за читање\n"
+"Ипак &Уређуј\n"
+"&Опорави\n"
+"&Изађи\n"
+"&Прекини"
+
+msgid "E326: Too many swap files found"
+msgstr "E326: Пронађено је превише swap датотека"
+
+msgid "E327: Part of menu-item path is not sub-menu"
+msgstr "E327: Део путање Ñтавке менија није подмени"
+
+msgid "E328: Menu only exists in another mode"
+msgstr "E328: Мени поÑтоји Ñамо у другом режиму"
+
+#, c-format
+msgid "E329: No menu \"%s\""
+msgstr "E329: Ðема менија \"%s\""
+
+msgid "E792: Empty menu name"
+msgstr "E792: Празно име менија"
+
+msgid "E330: Menu path must not lead to a sub-menu"
+msgstr "E330: Путања менија не Ñме да води у подмени"
+
+msgid "E331: Must not add menu items directly to menu bar"
+msgstr "E331: Ставке менија не Ñмеју да Ñе додају директно у линију менија"
+
+msgid "E332: Separator cannot be part of a menu path"
+msgstr "E332: Сепаратор не може да буде део путање менија"
+
+msgid ""
+"\n"
+"--- Menus ---"
+msgstr ""
+"\n"
+"--- Менији ---"
+
+msgid "Tear off this menu"
+msgstr "Отцепи овај мени"
+
+#, c-format
+msgid "E335: Menu not defined for %s mode"
+msgstr "E335: Мени није дефиниÑан за %s Ñ€eжим"
+
+msgid "E333: Menu path must lead to a menu item"
+msgstr "E333: Путања менија мора да води у Ñтавку менија"
+
+#, c-format
+msgid "E334: Menu not found: %s"
+msgstr "E334: Мени није пронађен: %s"
+
+msgid "E336: Menu path must lead to a sub-menu"
+msgstr "E336: Путања менија мора да води у подмени"
+
+msgid "E337: Menu not found - check menu names"
+msgstr "E337: Мени није пронађен - проверите имена менија"
+
+#, c-format
+msgid "Error detected while processing %s:"
+msgstr "Откривена је грешка током обраде %s:"
+
+#, c-format
+msgid "line %4ld:"
+msgstr "линија %4ld:"
+
+#, c-format
+msgid "E354: Invalid register name: '%s'"
+msgstr "E354: ÐеиÑправно име региÑтра: '%s'"
+
+msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
+msgstr "Поруке одржава: Иван Пешић <ivan.pesic@gmail.com>"
+
+msgid "Interrupt: "
+msgstr "Прекид: "
+
+msgid "Press ENTER or type command to continue"
+msgstr "Да биÑте наÑтавили, притиÑните ЕÐТЕР или откуцајте команду"
+
+#, c-format
+msgid "%s line %ld"
+msgstr "%s линија %ld"
+
+msgid "-- More --"
+msgstr "-- Још --"
+
+msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
+msgstr " РÐЗМÐКÐИЦÐ/d/j: екран/Ñтрана/линија наниже, b/u/k: навише, q: излаз "
+
+msgid "Question"
+msgstr "Питање"
+
+msgid ""
+"&Yes\n"
+"&No"
+msgstr ""
+"&Да\n"
+"&Ðе"
+
+msgid ""
+"&Yes\n"
+"&No\n"
+"Save &All\n"
+"&Discard All\n"
+"&Cancel"
+msgstr ""
+"&Да\n"
+"&Ðе\n"
+"Сачувај &Све\n"
+"о&Дбаци Ñве\n"
+"&Откажи"
+
+msgid "Select Directory dialog"
+msgstr "Дијалог избора директоријума"
+
+msgid "Save File dialog"
+msgstr "Дијалог чувања датотеке"
+
+msgid "Open File dialog"
+msgstr "Дијалог отварања датотеке"
+
+msgid "E338: Sorry, no file browser in console mode"
+msgstr "E338: Жао нам је, нема претраживача датотека у конзолном режиму"
+
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: Ðедовољно аргумената за printf()"
+
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: Очекује Ñе Float аргумент за printf()"
+
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Сувише аргумената за printf()"
+
+msgid "W10: Warning: Changing a readonly file"
+msgstr "W10: Упозорење: Мења Ñе датотека која може Ñамо да Ñе чита"
+
+msgid "Type number and <Enter> or click with mouse (empty cancels): "
+msgstr "УнеÑите број и <Enter> или кликните мишем (ништа за отказ): "
+
+msgid "Type number and <Enter> (empty cancels): "
+msgstr "УнеÑите број и <Enter> (ништа за отказ): "
+
+msgid "1 more line"
+msgstr "1 линија више"
+
+msgid "1 line less"
+msgstr "1 линија мање"
+
+#, c-format
+msgid "%ld more lines"
+msgstr "%ld линија више"
+
+#, c-format
+msgid "%ld fewer lines"
+msgstr "%ld линија мање"
+
+msgid " (Interrupted)"
+msgstr " (Прекинуто)"
+
+msgid "Beep!"
+msgstr "Биип!"
+
+msgid "ERROR: "
+msgstr "ГРЕШКÐ: "
+
+#, c-format
+msgid ""
+"\n"
+"[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"
+msgstr ""
+"\n"
+"[бајтова] укупно алоц-оÑлоб %lu-%lu, у употр %lu, вршна употр %lu\n"
+
+#, c-format
+msgid ""
+"[calls] total re/malloc()'s %lu, total free()'s %lu\n"
+"\n"
+msgstr ""
+"[позива] укупно re/malloc()-а %lu, укупно free()-ова %lu\n"
+"\n"
+
+msgid "E340: Line is becoming too long"
+msgstr "E340: Линија поÑтаје предугачка"
+
+#, c-format
+msgid "E341: Internal error: lalloc(%ld, )"
+msgstr "E341: Интерна грешка: lalloc(%ld, )"
+
+#, c-format
+msgid "E342: Out of memory! (allocating %lu bytes)"
+msgstr "E342: Ðема више меморије! (код алокације %lu бајтова)"
+
+#, c-format
+msgid "Calling shell to execute: \"%s\""
+msgstr "Позива Ñе командно окружење да изврши: \"%s\""
+
+msgid "E545: Missing colon"
+msgstr "E545: ÐедоÑтаје двотачка"
+
+msgid "E546: Illegal mode"
+msgstr "E546: Ðедозвољени режим"
+
+msgid "E547: Illegal mouseshape"
+msgstr "E547: Ðедозвољени mouseshape"
+
+msgid "E548: digit expected"
+msgstr "E548: очекује Ñе цифра"
+
+msgid "E549: Illegal percentage"
+msgstr "E549: Ðедозвољени проценат"
+
+msgid "E854: path too long for completion"
+msgstr "E854: путања је Ñувише дугачка да би Ñе довршила"
+
+#, c-format
+msgid ""
+"E343: Invalid path: '**[number]' must be at the end of the path or be "
+"followed by '%s'."
+msgstr ""
+"E343: ÐеиÑправна путања: '**[број]' мора бити на крају путање или да иза "
+"њега Ñледи '%s'."
+
+#, c-format
+msgid "E344: Can't find directory \"%s\" in cdpath"
+msgstr "E344: Директоријум \"%s\" не може да Ñе пронађе у cdpath"
+
+#, c-format
+msgid "E345: Can't find file \"%s\" in path"
+msgstr "E345: Датотека \"%s\" не може да Ñе пронађе у path"
+
+#, c-format
+msgid "E346: No more directory \"%s\" found in cdpath"
+msgstr "E346: Директоријум \"%s\" више не може да Ñе пронађе у cdpath"
+
+#, c-format
+msgid "E347: No more file \"%s\" found in path"
+msgstr "E347: Датотека \"%s\" више не може да Ñе пронађе у path"
+
+#, c-format
+msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
+msgstr "E668: Погрешан режим приÑтупа за инфо датотеку NetBeans везе: \"%s\""
+
+#, c-format
+msgid "E658: NetBeans connection lost for buffer %ld"
+msgstr "E658: NetBeans веза је изгубљена за бафер %ld"
+
+msgid "E838: netbeans is not supported with this GUI"
+msgstr "E838: netbeans није подржан Ñа овим GUI"
+
+msgid "E511: netbeans already connected"
+msgstr "E511: netbeans је већ повезан"
+
+#, c-format
+msgid "E505: %s is read-only (add ! to override)"
+msgstr "E505: %s је Ñамо за читање (додајте ! за премошћавање)"
+
+msgid "E349: No identifier under cursor"
+msgstr "E349: Под курÑором није идентификатор"
+
+msgid "E774: 'operatorfunc' is empty"
+msgstr "E774: 'operatorfunc' је празна"
+
+msgid "E775: Eval feature not available"
+msgstr "E775: Eval могућноÑÑ‚ није доÑтупна"
+
+msgid "Warning: terminal cannot highlight"
+msgstr "Упозорење: терминал не може да иÑтакне текÑÑ‚"
+
+msgid "E348: No string under cursor"
+msgstr "E348: Под курÑором нема Ñтринга"
+
+msgid "E352: Cannot erase folds with current 'foldmethod'"
+msgstr "E352: Са текућим 'foldmethod' не могу да Ñе обришу Ñклапања"
+
+msgid "E664: changelist is empty"
+msgstr "E664: лиÑта промена је празна"
+
+msgid "E662: At start of changelist"
+msgstr "E662: Ðа почетку лиÑте промена"
+
+msgid "E663: At end of changelist"
+msgstr "E663: Ðа крају лиÑте промена"
+
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Vim"
+msgstr ""
+"Откуцајте :qa! и притиÑните <Ентер> да одбаците Ñве измене и напуÑтите Vim"
+
+#, c-format
+msgid "1 line %sed 1 time"
+msgstr "1 линија %sрана 1 пут"
+
+#, c-format
+msgid "1 line %sed %d times"
+msgstr "1 линија %sрана %d пута"
+
+#, c-format
+msgid "%ld lines %sed 1 time"
+msgstr "%ld линија %sрано 1 пут"
+
+#, c-format
+msgid "%ld lines %sed %d times"
+msgstr "%ld линија %sрано %d пута"
+
+#, c-format
+msgid "%ld lines to indent... "
+msgstr "%ld за увлачење... "
+
+msgid "1 line indented "
+msgstr "1 линија увучена "
+
+#, c-format
+msgid "%ld lines indented "
+msgstr "%ld инија увучено "
+
+msgid "E748: No previously used register"
+msgstr "E748: Ðема претходно коришћеног региÑтра"
+
+msgid "cannot yank; delete anyway"
+msgstr "не може да Ñе тргне; ипак обриÑати"
+
+msgid "1 line changed"
+msgstr "1 линија је промењена"
+
+#, c-format
+msgid "%ld lines changed"
+msgstr "%ld линија је промењено"
+
+#, c-format
+msgid "freeing %ld lines"
+msgstr "оÑлобађа Ñе %ld линија"
+
+#, c-format
+msgid " into \"%c"
+msgstr " у \"%c"
+
+#, c-format
+msgid "block of 1 line yanked%s"
+msgstr "блок од 1 линије је тргнут%s"
+
+#, c-format
+msgid "1 line yanked%s"
+msgstr "1 линија је тргнута%s"
+
+#, c-format
+msgid "block of %ld lines yanked%s"
+msgstr "блок од %ld линија је тргнут%s"
+
+#, c-format
+msgid "%ld lines yanked%s"
+msgstr "%ld линија је тргнуто%s"
+
+#, c-format
+msgid "E353: Nothing in register %s"
+msgstr "E353: РегиÑтар %s је празан"
+
+msgid ""
+"\n"
+"--- Registers ---"
+msgstr ""
+"\n"
+"--- РегиÑтри ---"
+
+msgid "Illegal register name"
+msgstr "Ðеважеће име региÑтра"
+
+msgid ""
+"\n"
+"# Registers:\n"
+msgstr ""
+"\n"
+"# РегиÑтри:\n"
+
+#, c-format
+msgid "E574: Unknown register type %d"
+msgstr "E574: Ðепознат тип региÑтра %d"
+
+msgid ""
+"E883: search pattern and expression register may not contain two or more "
+"lines"
+msgstr ""
+"E883: региÑтар за шаблон претраге и израз не може да Ñадржи две или више "
+"линија"
+
+#, c-format
+msgid "%ld Cols; "
+msgstr "%ld Кол; "
+
+#, c-format
+msgid "Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"
+msgstr "Изабрано %s%ld од %ld Линија; %lld од %lld Речи; %lld од %lld Бајтова"
+
+#, c-format
+msgid ""
+"Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of "
+"%lld Bytes"
+msgstr ""
+"Изабрано %s%ld од %ld Линија; %lld од %lld Речи; %lld од %lld Знака; %lld од "
+"%lld Бајтова"
+
+#, c-format
+msgid "Col %s of %s; Line %ld of %ld; Word %lld of %lld; Byte %lld of %lld"
+msgstr "Кол %s од %s; Линија %ld од %ld; Реч %lld од %lld; Бајт %lld од %lld"
+
+#, c-format
+msgid ""
+"Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte %"
+"lld of %lld"
+msgstr ""
+"Кол %s од %s; Линија %ld од %ld; Реч %lld од %lld; Знак %lld од %lld; Бајт %"
+"lld од %lld"
+
+#, c-format
+msgid "(+%lld for BOM)"
+msgstr "(+%lld за BOM)"
+
+msgid "Thanks for flying Vim"
+msgstr "Хвала што летите Ñа Vim"
+
+msgid "E518: Unknown option"
+msgstr "E518: Ðепозната опција"
+
+msgid "E519: Option not supported"
+msgstr "E519: Опција није подржана"
+
+msgid "E520: Not allowed in a modeline"
+msgstr "E520: Ðије довољено у режимÑкој линији"
+
+msgid "E846: Key code not set"
+msgstr "E846: Ðије поÑтављрн код таÑтера"
+
+msgid "E521: Number required after ="
+msgstr "E521: Потребан је број након ="
+
+msgid "E522: Not found in termcap"
+msgstr "E522: Ðије пронађено у termcap"
+
+#, c-format
+msgid "E539: Illegal character <%s>"
+msgstr "E539: Ðедозвољен карактер <%s>"
+
+#, c-format
+msgid "For option %s"
+msgstr "За опцију %s"
+
+msgid "E529: Cannot set 'term' to empty string"
+msgstr "E529: 'term' не може да Ñе поÑтави на празан Ñтринг"
+
+msgid "E530: Cannot change term in GUI"
+msgstr "E530: term не може да Ñе промени из GUI"
+
+msgid "E531: Use \":gui\" to start the GUI"
+msgstr "E531: КориÑтите \":gui\" да покренете GUI"
+
+msgid "E589: 'backupext' and 'patchmode' are equal"
+msgstr "E589: 'backupext' и 'patchmode' Ñу иÑтоветни"
+
+msgid "E834: Conflicts with value of 'listchars'"
+msgstr "E834: У конфликту Ñа вредношћу 'listchars'"
+
+msgid "E835: Conflicts with value of 'fillchars'"
+msgstr "E835: У конфликту Ñа вредношћу 'fillchars'"
+
+msgid "E617: Cannot be changed in the GTK+ 2 GUI"
+msgstr "E617: Ðе може да Ñе промени у GTK+ 2 GUI"
+
+#, c-format
+msgid "E950: Cannot convert between %s and %s"
+msgstr "E950: Ðе може да Ñе конвертује између %s и %s"
+
+msgid "E524: Missing colon"
+msgstr "E524: ÐедоÑтаје двотачка"
+
+msgid "E525: Zero length string"
+msgstr "E525: Стринг дужине нула"
+
+#, c-format
+msgid "E526: Missing number after <%s>"
+msgstr "E526: ÐедоÑтаје број након <%s>"
+
+msgid "E527: Missing comma"
+msgstr "E527: ÐедоÑтаје зарез"
+
+msgid "E528: Must specify a ' value"
+msgstr "E528: Мора да Ñе наведе ' вредноÑÑ‚"
+
+msgid "E595: contains unprintable or wide character"
+msgstr "E595: Ñадржи карактер који не може да Ñе одштампа, или широки карактер"
+
+msgid "E596: Invalid font(s)"
+msgstr "E596: ÐеиÑправни фонт(ови)"
+
+msgid "E597: can't select fontset"
+msgstr "E597: fontset не може да Ñе изабере"
+
+msgid "E598: Invalid fontset"
+msgstr "E598: ÐеиÑправан fontset"
+
+msgid "E533: can't select wide font"
+msgstr "E533: широки фонт не може да Ñе изабере"
+
+msgid "E534: Invalid wide font"
+msgstr "E534: ÐеиÑправан широки фонт"
+
+#, c-format
+msgid "E535: Illegal character after <%c>"
+msgstr "E535: Ðеважећи карактер након <%c>"
+
+msgid "E536: comma required"
+msgstr "E536: потребан зарез"
+
+#, c-format
+msgid "E537: 'commentstring' must be empty or contain %s"
+msgstr "E537: 'commentstring' мора бити празно или да Ñадржи %s"
+
+msgid "E538: No mouse support"
+msgstr "E538: Ðема подршке за миша"
+
+msgid "E540: Unclosed expression sequence"
+msgstr "E540: Ðиз израза није затворен"
+
+msgid "E541: too many items"
+msgstr "E541: превише Ñтавки"
+
+msgid "E542: unbalanced groups"
+msgstr "E542: неуравнотежене групе"
+
+msgid "E946: Cannot make a terminal with running job modifiable"
+msgstr ""
+"E946: Терминал Ñа задатком који Ñе извршава не може да Ñе учини измењивим"
+
+msgid "E590: A preview window already exists"
+msgstr "E590: Прозор за преглед већ поÑтоји"
+
+msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
+msgstr "W17: ÐрапÑки захтева UTF-8, извршите ':set encoding=utf-8'"
+
+msgid "E954: 24-bit colors are not supported on this environment"
+msgstr "E954: Ово окружење не подржава 24-битне боје"
+
+#, c-format
+msgid "E593: Need at least %d lines"
+msgstr "E593: Потребно је најмање %d линија"
+
+#, c-format
+msgid "E594: Need at least %d columns"
+msgstr "E594: Потребно је најмање %d колона"
+
+#, c-format
+msgid "E355: Unknown option: %s"
+msgstr "E355: Ðепозната опција: %s"
+
+#, c-format
+msgid "E521: Number required: &%s = '%s'"
+msgstr "E521: Захтева Ñе број: &%s = '%s'"
+
+msgid ""
+"\n"
+"--- Terminal codes ---"
+msgstr ""
+"\n"
+"--- Кодови терминала ---"
+
+msgid ""
+"\n"
+"--- Global option values ---"
+msgstr ""
+"\n"
+"--- ВредноÑти глобалних опција ---"
+
+msgid ""
+"\n"
+"--- Local option values ---"
+msgstr ""
+"\n"
+"--- ВредноÑти локалних опција ---"
+
+msgid ""
+"\n"
+"--- Options ---"
+msgstr ""
+"\n"
+"--- Опције ---"
+
+msgid "E356: get_varp ERROR"
+msgstr "E356: get_varp ГРЕШКÐ"
+
+#, c-format
+msgid "E357: 'langmap': Matching character missing for %s"
+msgstr "E357: 'langmap': ÐедоÑтаје одговарајући карактер за %s"
+
+#, c-format
+msgid "E358: 'langmap': Extra characters after semicolon: %s"
+msgstr "E358: 'langmap': Има још карактера након тачказареза: %s"
+
+msgid "cannot open "
+msgstr "не може да Ñе отвори "
+
+msgid "VIM: Can't open window!\n"
+msgstr "VIM: Прозор не може да Ñе отвори!\n"
+
+msgid "Need Amigados version 2.04 or later\n"
+msgstr "Потребан је Amigados верзија 2.04 или каÑнији\n"
+
+#, c-format
+msgid "Need %s version %ld\n"
+msgstr "Потребан је %s верзија %ld\n"
+
+msgid "Cannot open NIL:\n"
+msgstr "Ðе може да Ñе отвори NIL:\n"
+
+msgid "Cannot create "
+msgstr "Ðе може да Ñе креира "
+
+#, c-format
+msgid "Vim exiting with %d\n"
+msgstr "Vim излази Ñа %d\n"
+
+msgid "cannot change console mode ?!\n"
+msgstr "конзолни режим не може да Ñе промени ?!\n"
+
+msgid "mch_get_shellsize: not a console??\n"
+msgstr "mch_get_shellsize: није конзола??\n"
+
+msgid "E360: Cannot execute shell with -f option"
+msgstr "E360: Командно окружење не може да Ñе изврши Ñа -f опцијом"
+
+msgid "Cannot execute "
+msgstr "Ðе може да Ñе изврши "
+
+msgid "shell "
+msgstr "командно окружење "
+
+msgid " returned\n"
+msgstr " вратило\n"
+
+msgid "ANCHOR_BUF_SIZE too small."
+msgstr "ANCHOR_BUF_SIZE Ñувише мали."
+
+msgid "I/O ERROR"
+msgstr "У/И ГРЕШКÐ"
+
+msgid "Message"
+msgstr "Порука"
+
+msgid "E237: Printer selection failed"
+msgstr "E237: Избор штампача није уÑпео"
+
+#, c-format
+msgid "to %s on %s"
+msgstr "у %s на %s"
+
+#, c-format
+msgid "E613: Unknown printer font: %s"
+msgstr "E613: Ðепознат фонт штампача: %s"
+
+#, c-format
+msgid "E238: Print error: %s"
+msgstr "E238: Грешка код штампања: %s"
+
+#, c-format
+msgid "Printing '%s'"
+msgstr "Штампа Ñе '%s'"
+
+#, c-format
+msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
+msgstr "E244: Ðедозвољено име Ñета карактера \"%s\" у имену фонту \"%s\""
+
+#, c-format
+msgid "E244: Illegal quality name \"%s\" in font name \"%s\""
+msgstr "E244: Ðедозвољено име варијанте \"%s\" у имену фонту \"%s\""
+
+#, c-format
+msgid "E245: Illegal char '%c' in font name \"%s\""
+msgstr "E245: ÐеиÑправан карактер '%c' у имену фонта \"%s\""
+
+#, c-format
+msgid "Opening the X display took %ld msec"
+msgstr "Отварање X приказа је трајало %ld мÑек"
+
+msgid ""
+"\n"
+"Vim: Got X error\n"
+msgstr ""
+"\n"
+"Vim: Дошло је до X грешке\n"
+
+msgid "Testing the X display failed"
+msgstr "ТеÑтирање X приказа није уÑпело"
+
+msgid "Opening the X display timed out"
+msgstr "ИÑтекло је макÑимално време за отварање X приказа"
+
+msgid ""
+"\n"
+"Could not get security context for "
+msgstr ""
+"\n"
+"Ðије могао да Ñе очита безбедноÑни контекÑÑ‚ за "
+
+msgid ""
+"\n"
+"Could not set security context for "
+msgstr ""
+"\n"
+"Ðије могао да Ñе поÑтави безбедноÑни контекÑÑ‚ за "
+
+#, c-format
+msgid "Could not set security context %s for %s"
+msgstr "БезбедноÑни контекÑÑ‚ %s за %s није могао да Ñе поÑтави"
+
+#, c-format
+msgid "Could not get security context %s for %s. Removing it!"
+msgstr "БезбедноÑни контекÑÑ‚ %s за %s није могао да Ñе очита. Уклања Ñе!"
+
+msgid ""
+"\n"
+"Cannot execute shell sh\n"
+msgstr ""
+"\n"
+"Командно окружење sh не може да Ñе изврши\n"
+
+msgid ""
+"\n"
+"shell returned "
+msgstr ""
+"\n"
+"командно окружење је вратило "
+
+msgid ""
+"\n"
+"Cannot create pipes\n"
+msgstr ""
+"\n"
+"Токови података не могу да Ñе креирају\n"
+
+msgid ""
+"\n"
+"Cannot fork\n"
+msgstr ""
+"\n"
+"Рачвање није могуће\n"
+
+msgid ""
+"\n"
+"Cannot execute shell "
+msgstr ""
+"\n"
+"Командно окружење не може да Ñе изврши "
+
+msgid ""
+"\n"
+"Command terminated\n"
+msgstr ""
+"\n"
+"Команда је прекинута\n"
+
+msgid "XSMP lost ICE connection"
+msgstr "XSMP је изгубио ICE везу"
+
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = \"%s\""
+
+msgid "Opening the X display failed"
+msgstr "Отварање X приказа није уÑпело"
+
+msgid "XSMP handling save-yourself request"
+msgstr "XSMP опÑлужује Ñачувај-Ñе захтев"
+
+msgid "XSMP opening connection"
+msgstr "XSMP отвара везу"
+
+msgid "XSMP ICE connection watch failed"
+msgstr "XSMP ICE надгледање везе није уÑпело"
+
+#, c-format
+msgid "XSMP SmcOpenConnection failed: %s"
+msgstr "XSMP SmcOpenConnection није уÑпело: %s"
+
+msgid "At line"
+msgstr "Код линије"
+
+msgid "Could not load vim32.dll!"
+msgstr "vim32.dll није могла да Ñе учита!"
+
+msgid "VIM Error"
+msgstr "VIM Грешка"
+
+msgid "Could not fix up function pointers to the DLL!"
+msgstr "Показивачи на функције у DLL-у ниÑу могли да Ñе поправе!"
+
+#, c-format
+msgid "Vim: Caught %s event\n"
+msgstr "Vim: Ухваћен је %s догађај\n"
+
+msgid "close"
+msgstr "затварање"
+
+msgid "logoff"
+msgstr "одјављивање"
+
+msgid "shutdown"
+msgstr "иÑкључивање"
+
+msgid "E371: Command not found"
+msgstr "E371: Команда није пронађена"
+
+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 ""
+"VIMRUN.EXE није пронађен у вашем $PATH.\n"
+"ЕкÑтерне команде неће моћи да Ñе паузирају након завршетка.\n"
+"Погледајте :help win32-vimrun за више информација."
+
+msgid "Vim Warning"
+msgstr "Vim Упозорење"
+
+#, c-format
+msgid "shell returned %d"
+msgstr "командно окружење је вратило %d"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Текућа лиÑта локација је промењена"
+
+#, c-format
+msgid "E372: Too many %%%c in format string"
+msgstr "E372: Превише %%%c Ñтрингу формата"
+
+#, c-format
+msgid "E373: Unexpected %%%c in format string"
+msgstr "E373: Ðеочекивано %%%c Ñтрингу формата"
+
+msgid "E374: Missing ] in format string"
+msgstr "E374: ÐедоÑтаје ] у Ñтрингу формата"
+
+#, c-format
+msgid "E375: Unsupported %%%c in format string"
+msgstr "E375: Ðеподржано %%%c у Ñтрингу формата"
+
+#, c-format
+msgid "E376: Invalid %%%c in format string prefix"
+msgstr "E376: Ðеважеће %%%c у префикÑу Ñтринга формата"
+
+#, c-format
+msgid "E377: Invalid %%%c in format string"
+msgstr "E377: Ðеважеће %%%c у Ñтрингу формата"
+
+msgid "E378: 'errorformat' contains no pattern"
+msgstr "E378: 'errorformat' не Ñадржи шаблон"
+
+msgid "E379: Missing or empty directory name"
+msgstr "E379: Име директоријума недоÑтаје или је празно"
+
+msgid "E553: No more items"
+msgstr "E553: Ðема више Ñтавки"
+
+msgid "E924: Current window was closed"
+msgstr "E924: Текући прозор је затворен"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Текући quickfix је промењен"
+
+#, c-format
+msgid "(%d of %d)%s%s: "
+msgstr "(%d од %d)%s%s: "
+
+msgid " (line deleted)"
+msgstr " (линија обриÑана)"
+
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%sлиÑта грешака %d од %d; %d грешака "
+
+msgid "E380: At bottom of quickfix stack"
+msgstr "E380: Ðа дну quickfix Ñтека"
+
+msgid "E381: At top of quickfix stack"
+msgstr "E381: Ðа врху quickfix Ñтека"
+
+msgid "No entries"
+msgstr "Ðема уноÑа"
+
+msgid "Error file"
+msgstr "Датотека грешака"
+
+msgid "E683: File name missing or invalid pattern"
+msgstr "E683: ÐедоÑтаје име датотеке или неважећи шаблон"
+
+#, c-format
+msgid "Cannot open file \"%s\""
+msgstr "Датотека \"%s\" не може да Ñе отвори"
+
+msgid "E681: Buffer is not loaded"
+msgstr "E681: Бафер није учитан"
+
+msgid "E777: String or List expected"
+msgstr "E777: Очекује Ñе String или List"
+
+#, c-format
+msgid "E369: invalid item in %s%%[]"
+msgstr "E369: неважећа Ñтавка у %s%%[]"
+
+#, c-format
+msgid "E769: Missing ] after %s["
+msgstr "E769: ÐедоÑтаје ] након %s["
+
+msgid "E944: Reverse range in character class"
+msgstr "E944: Обрнути опÑег у карактер клаÑи"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: Превелики опÑег у карактер клаÑи"
+
+#, c-format
+msgid "E53: Unmatched %s%%("
+msgstr "E53: Ðеупарена %s%%("
+
+#, c-format
+msgid "E54: Unmatched %s("
+msgstr "E54: Ðеупарена %s("
+
+#, c-format
+msgid "E55: Unmatched %s)"
+msgstr "E55: Ðеупарена %s)"
+
+msgid "E66: \\z( not allowed here"
+msgstr "E66: \\z( овде није дозвољено"
+
+msgid "E67: \\z1 - \\z9 not allowed here"
+msgstr "E67: \\z1 - \\z9 овде ниÑу дозвољени"
+
+#, c-format
+msgid "E69: Missing ] after %s%%["
+msgstr "E69: ÐедоÑтаје ] након %s%%["
+
+#, c-format
+msgid "E70: Empty %s%%[]"
+msgstr "E70: Празан %s%%[]"
+
+msgid "E65: Illegal back reference"
+msgstr "E65: Ðеважећа повратна референца"
+
+msgid "E339: Pattern too long"
+msgstr "E339: Шаблон је предугачак"
+
+msgid "E50: Too many \\z("
+msgstr "E50: Превише \\z("
+
+#, c-format
+msgid "E51: Too many %s("
+msgstr "E51: Превише %s("
+
+msgid "E52: Unmatched \\z("
+msgstr "E52: Ðеупарено \\z("
+
+#, c-format
+msgid "E59: invalid character after %s@"
+msgstr "E59: неважећи карактер након %s@"
+
+#, c-format
+msgid "E60: Too many complex %s{...}s"
+msgstr "E60: Превише комплекÑних %s{...}s"
+
+#, c-format
+msgid "E61: Nested %s*"
+msgstr "E61: Угњеждено %s*"
+
+#, 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 je иза ничега"
+
+msgid "E68: Invalid character after \\z"
+msgstr "E68: Ðеважећи карактер након \\z"
+
+#, c-format
+msgid "E678: Invalid character after %s%%[dxouU]"
+msgstr "E678: Ðеважећи карактер након %s%%[dxouU]"
+
+#, c-format
+msgid "E71: Invalid character after %s%%"
+msgstr "E71: Ðеважећи карактер након %s%%"
+
+#, c-format
+msgid "E554: Syntax error in %s{...}"
+msgstr "E554: СинтакÑна грешка у %s{...}"
+
+msgid "External submatches:\n"
+msgstr "Спољна подпоклапања:\n"
+
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (NFA regexp) не може да Ñе понови %s"
+
+msgid ""
+"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
+"used "
+msgstr ""
+"E864: Иза \\%#= може да Ñледи једино 0, 1, или 2. КориÑтиће Ñе аутоматÑки "
+"енџин "
+
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "Пребацивање на backtracking RE енџин за шаблон: "
+
+msgid "E865: (NFA) Regexp end encountered prematurely"
+msgstr "E865: Крај (NFA) Regexp израза је доÑтигнут прерано"
+
+#, c-format
+msgid "E866: (NFA regexp) Misplaced %c"
+msgstr "E866: (NFA regexp) %c је на погрешном меÑту"
+
+#, c-format
+msgid "E877: (NFA regexp) Invalid character class: %ld"
+msgstr "E877: (NFA regexp) Ðеважећа карактер клаÑа: %ld"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\z%c'"
+msgstr "E867: (NFA) Ðепознати оператор '\\z%c'"
+
+msgid "E951: \\% value too large"
+msgstr "E951: ВредноÑÑ‚ \\% је предугачка"
+
+#, c-format
+msgid "E867: (NFA) Unknown operator '\\%%%c'"
+msgstr "E867: (NFA) Ðепознати оператор '\\%%%c'"
+
+msgid "E868: Error building NFA with equivalence class!"
+msgstr "E868: Грешка при грађењу NFA Ñа клаÑом еквиваленције!"
+
+#, 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 "E879: (NFA regexp) Too many \\z("
+msgstr "E879: (NFA regexp) Превише \\z("
+
+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) (Док је вршена конверзија из postfix у NFA), превише "
+"Ñтања је оÑтало на Ñтеку"
+
+msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
+msgstr ""
+"E876: (NFA regexp) Ðема довољно проÑтора да Ñе уÑкладишти комплетан NFA "
+
+msgid "E878: (NFA) Could not allocate memory for branch traversal!"
+msgstr "E878: (NFA) Ðије могла да Ñе алоцира меморија за обилазак грана!"
+
+msgid ""
+"Could not open temporary log file for writing, displaying on stderr... "
+msgstr ""
+"Привремена лог датотека није могла да Ñе отвори за упиÑ, приказује Ñе на "
+"stderr... "
+
+#, c-format
+msgid "(NFA) COULD NOT OPEN %s !"
+msgstr "(NFA) %s ÐЕ МОЖЕ ДРСЕ ОТВОРИ !"
+
+msgid "Could not open temporary log file for writing "
+msgstr "Привремена лог датотека није могла да Ñе отвори за ÑƒÐ¿Ð¸Ñ "
+
+msgid " VREPLACE"
+msgstr "ВЗÐМЕÐÐ"
+
+msgid " REPLACE"
+msgstr " ЗÐМЕÐÐ"
+
+msgid " REVERSE"
+msgstr " ОБРÐУТО"
+
+msgid " INSERT"
+msgstr " УМЕТÐЊЕ"
+
+msgid " (insert)"
+msgstr " (уметање)"
+
+msgid " (replace)"
+msgstr " (замена)"
+
+msgid " (vreplace)"
+msgstr " (взамена)"
+
+msgid " Hebrew"
+msgstr " хебрејÑки"
+
+msgid " Arabic"
+msgstr " арапÑки"
+
+msgid " (paste)"
+msgstr " (налепи)"
+
+msgid " VISUAL"
+msgstr " ВИЗУЕЛÐО"
+
+msgid " VISUAL LINE"
+msgstr " ВИЗУЕЛÐРЛИÐИЈÐ"
+
+msgid " VISUAL BLOCK"
+msgstr " ВИЗУЕЛÐИ БЛОК"
+
+msgid " SELECT"
+msgstr " ИЗБОР"
+
+msgid " SELECT LINE"
+msgstr " ИЗБОР ЛИÐИЈÐ"
+
+msgid " SELECT BLOCK"
+msgstr " ИЗБОР БЛОКÐ"
+
+msgid "recording"
+msgstr "Ñнимање"
+
+#, c-format
+msgid "E383: Invalid search string: %s"
+msgstr "E383: ÐеиÑправан Ñтринг за претрагу: %s"
+
+#, c-format
+msgid "E384: search hit TOP without match for: %s"
+msgstr "E384: претрага је доÑтигла ВРХ без подударања за: %s"
+
+#, c-format
+msgid "E385: search hit BOTTOM without match for: %s"
+msgstr "E385: претрага је доÑтигла ДÐО без подударања за: %s"
+
+msgid "E386: Expected '?' or '/' after ';'"
+msgstr "E386: Ðакон ';' Ñе очекује '?' или '/'"
+
+msgid " (includes previously listed match)"
+msgstr " (укључује претходно наведена подударања)"
+
+msgid "--- Included files "
+msgstr "--- Прикључене датотеке "
+
+msgid "not found "
+msgstr "ниÑу пронађене "
+
+msgid "in path ---\n"
+msgstr "у путањи ---\n"
+
+msgid " (Already listed)"
+msgstr " (Већ наведено)"
+
+msgid " NOT FOUND"
+msgstr " ÐИЈЕ ПРОÐÐЂЕÐО"
+
+#, c-format
+msgid "Scanning included file: %s"
+msgstr "Прегледање уметнуте датотеке: %s"
+
+#, c-format
+msgid "Searching included file %s"
+msgstr "Претраживање уметнуте датотеке %s"
+
+msgid "E387: Match is on current line"
+msgstr "E387: Подударање је у текућој линији"
+
+msgid "All included files were found"
+msgstr "Све уметнуте датотеке Ñу пронађене"
+
+msgid "No included files"
+msgstr "Ðема уметнутих датотека"
+
+msgid "E388: Couldn't find definition"
+msgstr "E388: Дефиниција не може да Ñе пронађе"
+
+msgid "E389: Couldn't find pattern"
+msgstr "E389: Шаблон за претрагу није пронађен"
+
+msgid "Substitute "
+msgstr "Замена "
+
+#, c-format
+msgid ""
+"\n"
+"# Last %sSearch Pattern:\n"
+"~"
+msgstr ""
+"\n"
+"# ПоÑледњи %sШаблон Претраге:\n"
+"~"
+
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Провера правопиÑа није омогућена"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
+msgstr ""
+"Упозорење: ЛиÑта речи \"%s_%s.spl\" или \"%s_ascii.spl\" не може да Ñе "
+"пронађе"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr ""
+"Упозорење: ЛиÑта речи \"%s.%s.spl\" или \"%s.ascii.spl\" не може да Ñе "
+"пронађе"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: SpellFileMissing аутокоманда је обриÑала бафер"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "Упозорење: регион %s није подржан"
+
+msgid "Sorry, no suggestions"
+msgstr "Жао нам је, нема ÑугеÑтија"
+
+#, c-format
+msgid "Sorry, only %ld suggestions"
+msgstr "Жао нам је, Ñамо %ld ÑугеÑтија"
+
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Променити \"%.*s\" у:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < \"%.*s\""
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Ðема претходне правопиÑне замене"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Ðије пронађено: %s"
+
+msgid "E758: Truncated spell file"
+msgstr "E758: ПравопиÑна датотека је прекраћена"
+
+#, c-format
+msgid "Trailing text in %s line %d: %s"
+msgstr "ТекÑÑ‚ вишак у %s линија %d: %s"
+
+#, c-format
+msgid "Affix name too long in %s line %d: %s"
+msgstr "Име наÑтавка је предугачко у %s линија %d: %s"
+
+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 "Compressing word tree..."
+msgstr "Стабло речи Ñе компреÑује..."
+
+#, c-format
+msgid "Reading spell file \"%s\""
+msgstr "Читање правопиÑне датотеке \"%s\""
+
+msgid "E757: This does not look like a spell file"
+msgstr "E757: Ово не изгледа као правопиÑна датотека"
+
+msgid "E771: Old spell file, needs to be updated"
+msgstr "E771: Стара правопиÑна датотека, потребно је да Ñе оÑвежи"
+
+msgid "E772: Spell file is for newer version of Vim"
+msgstr "E772: ПравопиÑна датотека је за новију верзију Vim-а"
+
+msgid "E770: Unsupported section in spell file"
+msgstr "E770: Ðеподржана Ñекција у правопиÑној датотеци"
+
+#, c-format
+msgid "E778: This does not look like a .sug file: %s"
+msgstr "E778: Ово не изгледа као .sug датотека: %s"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: Стара .sug датотека, потребно је да Ñе оÑвежи: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: .sug датотека је за новију верзију Vim-а: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: .sug датотека не одговара .spl датотеци: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: грешка приликом читања .sug датотеке: %s"
+
+#, c-format
+msgid "Reading affix file %s..."
+msgstr "Читање датотеке наÑтавака %s..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %d: %s"
+msgstr "ÐеуÑпешна конверзија за реч у %s линија %d: %s"
+
+#, c-format
+msgid "Conversion in %s not supported: from %s to %s"
+msgstr "Конверзија у %s није подржана: из %s у %s"
+
+#, c-format
+msgid "Conversion in %s not supported"
+msgstr "Конверзија у %s није подржана"
+
+#, c-format
+msgid "Invalid value for FLAG in %s line %d: %s"
+msgstr "Ðеважећа вредноÑÑ‚ за FLAG у %s линија %d: %s"
+
+#, c-format
+msgid "FLAG after using flags in %s line %d: %s"
+msgstr "FLAG након коришћења индикатора у %s линија %d: %s"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"ДефиниÑање COMPOUNDFORBIDFLAG након PFX Ñтавке може да дâ погрешне резултате "
+"у %s line %d"
+
+#, c-format
+msgid ""
+"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
+"%d"
+msgstr ""
+"ДефиниÑање COMPOUNDPERMITFLAG након PFX Ñтавке може да дâ погрешне резултате "
+"у %s line %d"
+
+#, c-format
+msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
+msgstr "Погрешна COMPOUNDRULES вредноÑÑ‚ у %s линија %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
+msgstr "Погрешна COMPOUNDWORDMAX вредноÑÑ‚ у %s линија %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
+msgstr "Погрешна COMPOUNDMIN вредноÑÑ‚ у %s линија %d: %s"
+
+#, c-format
+msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
+msgstr "Погрешна COMPOUNDSYLMAX вредноÑÑ‚ у %s линија %d: %s"
+
+#, c-format
+msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
+msgstr "Погрешна CHECKCOMPOUNDPATTERN вредноÑÑ‚ у %s линија %d: %s"
+
+#, c-format
+msgid "Different combining flag in continued affix block in %s line %d: %s"
+msgstr ""
+"Различит индикатор комбиновања у наÑтављеном блоку наÑтавака у %s линија %d: "
+"%s"
+
+#, c-format
+msgid "Duplicate affix in %s line %d: %s"
+msgstr "Дупликат наÑтавка у %s линија %d: %s"
+
+#, c-format
+msgid ""
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"line %d: %s"
+msgstr ""
+"ÐаÑтавак Ñе такође кориÑти за BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST у %s"
+"линија %d: %s"
+
+#, c-format
+msgid "Expected Y or N in %s line %d: %s"
+msgstr "Очекује Ñе Y или N у %s линија %d: %s"
+
+#, c-format
+msgid "Broken condition in %s line %d: %s"
+msgstr "Ðеправилан уÑлов у %s линија %d: %s"
+
+#, c-format
+msgid "Expected REP(SAL) count in %s line %d"
+msgstr "Очекује Ñе број REP(SAL) у %s линија %d"
+
+#, c-format
+msgid "Expected MAP count in %s line %d"
+msgstr "Очекује Ñе број MAP у %s линија %d"
+
+#, c-format
+msgid "Duplicate character in MAP in %s line %d"
+msgstr "Дупликат карактера у MAP у %s линија %d"
+
+#, c-format
+msgid "Unrecognized or duplicate item in %s line %d: %s"
+msgstr "ÐепрепоÑната или дупла Ñтавка у %s линија %d: %s"
+
+#, c-format
+msgid "Missing FOL/LOW/UPP line in %s"
+msgstr "ÐедоÑтаје FOL/LOW/UPP линија у %s"
+
+msgid "COMPOUNDSYLMAX used without SYLLABLE"
+msgstr "COMPOUNDSYLMAX Ñе кориÑти без SYLLABLE"
+
+msgid "Too many postponed prefixes"
+msgstr "Превише закашњених префикÑа"
+
+msgid "Too many compound flags"
+msgstr "Превише индикатора Ñложеница"
+
+msgid "Too many postponed prefixes and/or compound flags"
+msgstr "Превише закашњених префикÑа и/или индикатора Ñложеница"
+
+#, c-format
+msgid "Missing SOFO%s line in %s"
+msgstr "ÐедоÑтаје SOFO%s линија у %s"
+
+#, c-format
+msgid "Both SAL and SOFO lines in %s"
+msgstr "И SAL и SOFO линије у %s"
+
+#, c-format
+msgid "Flag is not a number in %s line %d: %s"
+msgstr "Индикатор није број у %s линија %d: %s"
+
+#, c-format
+msgid "Illegal flag in %s line %d: %s"
+msgstr "Ðеважећи индикатор у %s линија %d: %s"
+
+#, c-format
+msgid "%s value differs from what is used in another .aff file"
+msgstr ""
+"%s вредноÑÑ‚ Ñе разликује од онога што је коришћено у другој .aff датотеци"
+
+#, c-format
+msgid "Reading dictionary file %s..."
+msgstr "Читање датотеке речника %s..."
+
+#, c-format
+msgid "E760: No word count in %s"
+msgstr "E760: Ðема броја речи у %s"
+
+#, c-format
+msgid "line %6d, word %6ld - %s"
+msgstr "линија %6d, реч %6ld - %s"
+
+#, c-format
+msgid "Duplicate word in %s line %d: %s"
+msgstr "Дупликат речи у %s линија %d: %s"
+
+#, c-format
+msgid "First duplicate word in %s line %d: %s"
+msgstr "Прва реч дупликат у %s линија %d: %s"
+
+#, c-format
+msgid "%d duplicate word(s) in %s"
+msgstr "%d реч(и) дупликат(а) у %s"
+
+#, c-format
+msgid "Ignored %d word(s) with non-ASCII characters in %s"
+msgstr "ИгнориÑана/о %d реч(и) Ñа не-ASCII карактерима у %s"
+
+#, c-format
+msgid "Reading word file %s..."
+msgstr "Читање датотеке речи %s..."
+
+#, c-format
+msgid "Duplicate /encoding= line ignored in %s line %d: %s"
+msgstr "Дупликат /encoding= линија је игнориÑана у %s линија %d: %s"
+
+#, c-format
+msgid "/encoding= line after word ignored in %s line %d: %s"
+msgstr "/encoding= линија након речи је игнориÑана у %s линија %d: %s"
+
+#, c-format
+msgid "Duplicate /regions= line ignored in %s line %d: %s"
+msgstr "Дупликат /regions= линија је игнориÑана у %s линија %d: %s"
+
+#, c-format
+msgid "Too many regions in %s line %d: %s"
+msgstr "Превише региона у %s линија %d: %s"
+
+#, c-format
+msgid "/ line ignored in %s line %d: %s"
+msgstr "/ линија игнориÑана у %s линија %d: %s"
+
+#, c-format
+msgid "Invalid region nr in %s line %d: %s"
+msgstr "Ðеважећи број региона у %s линија %d: %s"
+
+#, c-format
+msgid "Unrecognized flags in %s line %d: %s"
+msgstr "Ðепрепознати индикатори у %s линија %d: %s"
+
+#, c-format
+msgid "Ignored %d words with non-ASCII characters"
+msgstr "ИгнориÑано је %d рћи Ñа не-ASCII карактерима"
+
+msgid "E845: Insufficient memory, word list will be incomplete"
+msgstr "E845: Ðедовољно меморије, лиÑта речи неће бити комплетна"
+
+#, c-format
+msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
+msgstr "КомпреÑовано је %d од %d чворова; преоÑтало је још %d (%d%%)"
+
+msgid "Reading back spell file..."
+msgstr "Читање правопиÑне датотеке..."
+
+msgid "Performing soundfolding..."
+msgstr "Извођење Ñклапања по звучноÑти..."
+
+#, c-format
+msgid "Number of words after soundfolding: %ld"
+msgstr "Број речи након Ñклапања по звучноÑти: %ld"
+
+#, c-format
+msgid "Total number of words: %d"
+msgstr "Укупан број речи: %d"
+
+#, c-format
+msgid "Writing suggestion file %s..."
+msgstr "УпиÑивање датотеке предлога %s..."
+
+#, c-format
+msgid "Estimated runtime memory use: %d bytes"
+msgstr "Процењена потребна величина меморије у време извршавања: %d бајтова"
+
+msgid "E751: Output file name must not have region name"
+msgstr "E751: Име излазне датотеке не Ñме да има име региона"
+
+#, c-format
+msgid "E754: Only up to %ld regions supported"
+msgstr "E754: Подржано је Ñамо до %ld региона"
+
+#, c-format
+msgid "E755: Invalid region in %s"
+msgstr "E755: Ðеважећи регион у %s"
+
+msgid "Warning: both compounding and NOBREAK specified"
+msgstr "Упозорење: наведени Ñу и Ñлагање и NOBREAK"
+
+#, c-format
+msgid "Writing spell file %s..."
+msgstr "УпиÑивање правопиÑне датотеке %s..."
+
+msgid "Done!"
+msgstr "Завршено!"
+
+#, c-format
+msgid "E765: 'spellfile' does not have %ld entries"
+msgstr "E765: 'spellfile' не Ñадржи %ld Ñтавке"
+
+#, c-format
+msgid "Word '%.*s' removed from %s"
+msgstr "Реч '%.*s' је уклоњена из %s"
+
+#, c-format
+msgid "Word '%.*s' added to %s"
+msgstr "Реч '%.*s' је додата у %s"
+
+msgid "E763: Word characters differ between spell files"
+msgstr "E763: Карактери у речи Ñе разликују између правопиÑних датотека"
+
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: карактер дупликат у MAP Ñтавци"
+
+msgid "No Syntax items defined for this buffer"
+msgstr "За оба јбафер ниÑу дефиниÑане ÑинтакÑне Ñтавке"
+
+msgid "syntax conceal on"
+msgstr "Ñкривање ÑинтакÑе укључено"
+
+msgid "syntax conceal off"
+msgstr "Ñкривање ÑинтакÑе иÑкључено"
+
+#, c-format
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Ðеважећи аргумент: %s"
+
+msgid "syntax case ignore"
+msgstr "мала/велика Ñлова Ñе не разликују у ÑинтакÑи"
+
+msgid "syntax case match"
+msgstr "мала/велика Ñлова Ñе разликују у ÑинтакÑи"
+
+msgid "syntax spell toplevel"
+msgstr "ÑинтакÑа правопиÑа toplevel"
+
+msgid "syntax spell notoplevel"
+msgstr "ÑинтакÑа правопиÑа notoplevel"
+
+msgid "syntax spell default"
+msgstr "ÑинтакÑа правопиÑа подразумевано"
+
+msgid "syntax iskeyword "
+msgstr "ÑинтакÑа iskeyword "
+
+#, c-format
+msgid "E391: No such syntax cluster: %s"
+msgstr "E391: Ðе поÑтоји такав ÑинтакÑни клаÑтер: %s"
+
+msgid "syncing on C-style comments"
+msgstr "Ñинхронизација на коментарима C-Ñтила"
+
+msgid "no syncing"
+msgstr "без Ñинхронизације"
+
+msgid "syncing starts "
+msgstr "Ñинхронизација почиње "
+
+msgid " lines before top line"
+msgstr " линија пре линије на врху"
+
+msgid ""
+"\n"
+"--- Syntax sync items ---"
+msgstr ""
+"\n"
+"--- Ставке Ñинхро ÑинтакÑе ---"
+
+msgid ""
+"\n"
+"syncing on items"
+msgstr ""
+"\n"
+"Ñинхро на Ñтавкама"
+
+msgid ""
+"\n"
+"--- Syntax items ---"
+msgstr ""
+"\n"
+"--- Ставке ÑинтакÑе ---"
+
+#, c-format
+msgid "E392: No such syntax cluster: %s"
+msgstr "E392: не поÑтоји такав ÑинтакÑни клаÑтер: %s"
+
+msgid "minimal "
+msgstr "минимално "
+
+msgid "maximal "
+msgstr "макÑимално "
+
+msgid "; match "
+msgstr "; подударања "
+
+msgid " line breaks"
+msgstr " прелома линије"
+
+msgid "E395: contains argument not accepted here"
+msgstr "E395: Ñадржи аргумент који Ñе овде не прихвата"
+
+msgid "E844: invalid cchar value"
+msgstr "E844: неважећа cchar вредноÑÑ‚"
+
+msgid "E393: group[t]here not accepted here"
+msgstr "E393: group[t]here Ñе овде не прихвата"
+
+#, c-format
+msgid "E394: Didn't find region item for %s"
+msgstr "E394: Ставка региона није пронађена за %s"
+
+msgid "E397: Filename required"
+msgstr "E397: Потребно име датотеке"
+
+msgid "E847: Too many syntax includes"
+msgstr "E847: Превише ÑинтакÑних уметања"
+
+#, c-format
+msgid "E789: Missing ']': %s"
+msgstr "E789: ÐедоÑтаје ']': %s"
+
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: карактер вишка након ']': %s]%s"
+
+#, c-format
+msgid "E398: Missing '=': %s"
+msgstr "E398: ÐедоÑтаје '=': %s"
+
+#, c-format
+msgid "E399: Not enough arguments: syntax region %s"
+msgstr "E399: Ðема довољно аргумената: ÑинтакÑни регион %s"
+
+msgid "E848: Too many syntax clusters"
+msgstr "E848: Превише ÑинтакÑних клаÑтера"
+
+msgid "E400: No cluster specified"
+msgstr "E400: Ðије наведен ниједан клаÑтер"
+
+#, c-format
+msgid "E401: Pattern delimiter not found: %s"
+msgstr "E401: Ðије пронађен граничник шаблона: %s"
+
+#, c-format
+msgid "E402: Garbage after pattern: %s"
+msgstr "E402: Смеће након шаблона: %s"
+
+msgid "E403: syntax sync: line continuations pattern specified twice"
+msgstr "E403: ÑинтакÑна Ñинхро: шаблон наÑтављања линије је наведен двапут"
+
+#, c-format
+msgid "E404: Illegal arguments: %s"
+msgstr "E404: Ðеважећи аргументи: %s"
+
+#, c-format
+msgid "E405: Missing equal sign: %s"
+msgstr "E405: недоÑтаје знак једнакоÑти: %s"
+
+#, c-format
+msgid "E406: Empty argument: %s"
+msgstr "E406: Празан аргумент: %s"
+
+#, c-format
+msgid "E407: %s not allowed here"
+msgstr "E407: %s овде није дозвољено"
+
+#, c-format
+msgid "E408: %s must be first in contains list"
+msgstr "E408: %s мора да буде прво у contains лиÑти"
+
+#, c-format
+msgid "E409: Unknown group name: %s"
+msgstr "E409: Ðепознато име групе: %s"
+
+#, c-format
+msgid "E410: Invalid :syntax subcommand: %s"
+msgstr "E410: Ðеважећа :syntax подкоманда: %s"
+
+msgid ""
+" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
+msgstr ""
+" УКУПÐО БРОЈ ПОДУД ÐÐЈСПОРИЈЕ ПРОСЕК ИМЕ ШÐБЛОÐ"
+
+msgid "E679: recursive loop loading syncolor.vim"
+msgstr "E679: Рекурзивна петља код учитавања syncolor.vim"
+
+#, c-format
+msgid "E411: highlight group not found: %s"
+msgstr "E411: група иÑтицања није пронађена: %s"
+
+#, c-format
+msgid "E412: Not enough arguments: \":highlight link %s\""
+msgstr "E412: Ðема довољно аргумената: \":highlight link %s\""
+
+#, c-format
+msgid "E413: Too many arguments: \":highlight link %s\""
+msgstr "E413: Сувише аргумената: \":highlight link %s\""
+
+msgid "E414: group has settings, highlight link ignored"
+msgstr "E414: група има поÑтавке, highlight link Ñе игнорише"
+
+#, c-format
+msgid "E415: unexpected equal sign: %s"
+msgstr "E415: неочкиван знак једнакоÑти: %s"
+
+#, c-format
+msgid "E416: missing equal sign: %s"
+msgstr "E416: недоÑтаје знак једнакоÑти: %s"
+
+#, c-format
+msgid "E417: missing argument: %s"
+msgstr "E417: недоÑтаје аргумент: %s"
+
+#, c-format
+msgid "E418: Illegal value: %s"
+msgstr "E418: Ðеважећа вредноÑÑ‚: %s"
+
+msgid "E419: FG color unknown"
+msgstr "E419: Ðепозната FG боја"
+
+msgid "E420: BG color unknown"
+msgstr "E420: Ðепозната BG боја"
+
+#, c-format
+msgid "E421: Color name or number not recognized: %s"
+msgstr "E421: Име боје или број ниÑу препознати: %s"
+
+#, c-format
+msgid "E422: terminal code too long: %s"
+msgstr "E422: код терминала је предугачак: %s"
+
+#, c-format
+msgid "E423: Illegal argument: %s"
+msgstr "E423: Ðеважећи аргумент: %s"
+
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: У употреби је превише различитих атрибута иÑтицања"
+
+msgid "E669: Unprintable character in group name"
+msgstr "E669: У имену групе је карактер који не може да Ñе штампа"
+
+msgid "W18: Invalid character in group name"
+msgstr "W18: Ðеважећи карактер у имену групе"
+
+msgid "E849: Too many highlight and syntax groups"
+msgstr "E849: Превише ÑинтакÑних и група иÑтицања"
+
+msgid "E555: at bottom of tag stack"
+msgstr "E555: на дну Ñтека ознака"
+
+msgid "E556: at top of tag stack"
+msgstr "E556: на врху Ñтека ознака"
+
+msgid "E425: Cannot go before first matching tag"
+msgstr "E425: Ðе може да Ñе иде иÑпред прве подударајуће ознаке"
+
+#, c-format
+msgid "E426: tag not found: %s"
+msgstr "E426: ознака није пронађена: %s"
+
+msgid " # pri kind tag"
+msgstr " # ознака pri врÑте"
+
+msgid "file\n"
+msgstr "датотека\n"
+
+msgid "E427: There is only one matching tag"
+msgstr "E427: ПоÑтоји Ñамо једна подударајућа ознака"
+
+msgid "E428: Cannot go beyond last matching tag"
+msgstr "E428: Ðе може да Ñе иде иза поÑледње подударајуће ознаке"
+
+#, c-format
+msgid "File \"%s\" does not exist"
+msgstr "Датотека \"%s\" не поÑтоји"
+
+#, c-format
+msgid "tag %d of %d%s"
+msgstr "ознака %d од %d%s"
+
+msgid " or more"
+msgstr " или више"
+
+msgid " Using tag with different case!"
+msgstr " КориÑти Ñе ознака за другом врÑтом Ñлова (мала/велика)!"
+
+#, c-format
+msgid "E429: File \"%s\" does not exist"
+msgstr "E429: Датотека \"%s\" не поÑтоји"
+
+msgid ""
+"\n"
+" # TO tag FROM line in file/text"
+msgstr ""
+"\n"
+" # ÐРознака ОД линије у датот/текÑÑ‚"
+
+#, c-format
+msgid "Searching tags file %s"
+msgstr "Претраживање датотеке ознака %s"
+
+#, c-format
+msgid "E430: Tag file path truncated for %s\n"
+msgstr "E430: Путања датотеке ознака је прекинута за %s\n"
+
+msgid "Ignoring long line in tags file"
+msgstr "Дугачка линија у датотеци ознака Ñе игнорише"
+
+#, c-format
+msgid "E431: Format error in tags file \"%s\""
+msgstr "E431: Грешка формата у датотеци ознака \"%s\""
+
+#, c-format
+msgid "Before byte %ld"
+msgstr "Пре бајта %ld"
+
+#, c-format
+msgid "E432: Tags file not sorted: %s"
+msgstr "E432: Датотека ознака није Ñортирана: %s"
+
+msgid "E433: No tags file"
+msgstr "E433: Ðема датотеке ознака"
+
+msgid "E434: Can't find tag pattern"
+msgstr "E434: Ðе може да Ñе пронађе шаблон ознаке"
+
+msgid "E435: Couldn't find tag, just guessing!"
+msgstr "E435: Ознака није могла да Ñе пронађе, Ñамо нагађам!"
+
+#, c-format
+msgid "Duplicate field name: %s"
+msgstr "Дупло име поља: %s"
+
+msgid "' not known. Available builtin terminals are:"
+msgstr "' није познат. ДоÑтупни уграђени терминали Ñу:"
+
+msgid "defaulting to '"
+msgstr "подразумева Ñе '"
+
+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 "E436: No \"%s\" entry in termcap"
+msgstr "E436: Ðема \"%s\" Ñтавке у termcap"
+
+msgid "E437: terminal capability \"cm\" required"
+msgstr "E437: потребна је могућноÑÑ‚ терминала \"cm\""
+
+msgid ""
+"\n"
+"--- Terminal keys ---"
+msgstr ""
+"\n"
+"--- ТаÑтери терминала ---"
+
+msgid "Cannot open $VIMRUNTIME/rgb.txt"
+msgstr "Ðе може да Ñе отвори $VIMRUNTIME/rgb.txt"
+
+#, c-format
+msgid "Kill job in \"%s\"?"
+msgstr "Да ли да Ñе уништи задатак у \"%s\"?"
+
+msgid "Terminal"
+msgstr "Терминал"
+
+msgid "Terminal-finished"
+msgstr "Терминал-завршен"
+
+msgid "active"
+msgstr "aktivan"
+
+msgid "running"
+msgstr "ради"
+
+msgid "finished"
+msgstr "завршен"
+
+#, c-format
+msgid "E953: File exists: %s"
+msgstr "E953: Датотека већ поÑтоји: %s"
+
+msgid "E955: Not a terminal buffer"
+msgstr "E955: Ðије терминалÑки бафер"
+
+msgid "new shell started\n"
+msgstr "покренуто ново командно окружење\n"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Грешка при читању улаза, излазак...\n"
+
+msgid "Used CUT_BUFFER0 instead of empty selection"
+msgstr "УмеÑто празне Ñелекције корићен је CUT_BUFFER0"
+
+msgid "E881: Line count changed unexpectedly"
+msgstr "E881: Број линија Ñе неочекивано променио"
+
+msgid "No undo possible; continue anyway"
+msgstr "Ðије могућ опозив; ипак наÑтави"
+
+#, c-format
+msgid "E828: Cannot open undo file for writing: %s"
+msgstr "E828: Датотека опозива не може да Ñе отвори за упиÑ: %s"
+
+#, c-format
+msgid "E825: Corrupted undo file (%s): %s"
+msgstr "E825: ИÑкварена датотека за опозив (%s): %s"
+
+msgid "Cannot write undo file in any directory in 'undodir'"
+msgstr ""
+"Датотека за опозив не може да Ñе упише ни у један директоријум из 'undodir'"
+
+#, c-format
+msgid "Will not overwrite with undo file, cannot read: %s"
+msgstr ""
+"Ðеће Ñе вршити препиÑивање Ñа датотеком опозива, читање није могуће: %s"
+
+#, c-format
+msgid "Will not overwrite, this is not an undo file: %s"
+msgstr "Ðеће Ñе цршити препиÑивање, ово није датотека за опозив: %s"
+
+msgid "Skipping undo file write, nothing to undo"
+msgstr "ПреÑкакање упиÑа у датотеку за опозив, нема шта да Ñе опозове"
+
+#, c-format
+msgid "Writing undo file: %s"
+msgstr "Ð£Ð¿Ð¸Ñ Ð´Ð°Ñ‚Ð¾Ñ‚ÐµÐºÐµ за опозив: %s"
+
+#, c-format
+msgid "E829: write error in undo file: %s"
+msgstr "E829: грешка код упиÑа у датотеку за опозив: %s"
+
+#, c-format
+msgid "Not reading undo file, owner differs: %s"
+msgstr "Датотека за опозив Ñе не чита, влаÑник Ñе разликује: %s"
+
+#, c-format
+msgid "Reading undo file: %s"
+msgstr "Читање датотеке за опозив: %s"
+
+#, c-format
+msgid "E822: Cannot open undo file for reading: %s"
+msgstr "E822: Датотека за опозив не може да Ñе отвори за читање: %s"
+
+#, c-format
+msgid "E823: Not an undo file: %s"
+msgstr "E823: Ðије датотека за опозив: %s"
+
+#, c-format
+msgid "E832: Non-encrypted file has encrypted undo file: %s"
+msgstr ""
+"E832: Датотека која није шифрована има шифровану датотеку за опозив: %s"
+
+#, c-format
+msgid "E826: Undo file decryption failed: %s"
+msgstr "E826: Дешифровање датотеке за опозив није уÑпело: %s"
+
+#, c-format
+msgid "E827: Undo file is encrypted: %s"
+msgstr "E827: Датотека за опозив је шифрована: %s"
+
+#, c-format
+msgid "E824: Incompatible undo file: %s"
+msgstr "E824: Ðекомпатибилна датотека за опозив: %s"
+
+msgid "File contents changed, cannot use undo info"
+msgstr ""
+"Садржај датотеке је промењен, информације за опозив не могу да Ñе кориÑте"
+
+#, c-format
+msgid "Finished reading undo file %s"
+msgstr "Тавршено је читање датотеке за опозив %s"
+
+msgid "Already at oldest change"
+msgstr "Већ Ñте на најÑтаријој измени"
+
+msgid "Already at newest change"
+msgstr "Већ Ñте на најновијој измени"
+
+#, c-format
+msgid "E830: Undo number %ld not found"
+msgstr "E830: Број опозива %ld није пронађен"
+
+msgid "E438: u_undo: line numbers wrong"
+msgstr "E438: u_undo: погрешни бројеви линије"
+
+msgid "more line"
+msgstr "линија више"
+
+msgid "more lines"
+msgstr "линија више"
+
+msgid "line less"
+msgstr "линија мање"
+
+msgid "fewer lines"
+msgstr "линија мање"
+
+msgid "change"
+msgstr "измена"
+
+msgid "changes"
+msgstr "измена"
+
+#, c-format
+msgid "%ld %s; %s #%ld %s"
+msgstr "%ld %s; %s #%ld %s"
+
+msgid "before"
+msgstr "пре"
+
+msgid "after"
+msgstr "након"
+
+msgid "Nothing to undo"
+msgstr "Ðишта за опозив"
+
+msgid "number changes when saved"
+msgstr "број измене када Ñачувано"
+
+#, c-format
+msgid "%ld seconds ago"
+msgstr "пре %ld Ñекунди"
+
+msgid "E790: undojoin is not allowed after undo"
+msgstr "E790: undojoin ије дозвољен након undo"
+
+msgid "E439: undo list corrupt"
+msgstr "E439: лиÑта опозива је иÑкварена"
+
+msgid "E440: undo line missing"
+msgstr "E440: недоÑтаје линија опозива"
+
+#, c-format
+msgid "E122: Function %s already exists, add ! to replace it"
+msgstr "E122: Функција %s већ поÑтоји, додајте ! да је замените"
+
+msgid "E717: Dictionary entry already exists"
+msgstr "E717: Ð£Ð½Ð¾Ñ Ð²ÐµÑ› поÑтоји у речнику"
+
+msgid "E718: Funcref required"
+msgstr "E718: Потребна funcref"
+
+#, c-format
+msgid "E130: Unknown function: %s"
+msgstr "E130: Ðепозната функција: %s"
+
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Ðеважећи аргумент: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Име аргумента је дуплирано: %s"
+
+#, c-format
+msgid "E740: Too many arguments for function %s"
+msgstr "E740: Превише аргумената за функцију %s"
+
+#, c-format
+msgid "E116: Invalid arguments for function %s"
+msgstr "E116: Ðеважећи аргументи за функцију %s"
+
+msgid "E132: Function call depth is higher than 'maxfuncdepth'"
+msgstr "E132: Дубина позива функције је већа од 'maxfuncdepth'"
+
+#, c-format
+msgid "calling %s"
+msgstr "позива Ñе %s"
+
+#, c-format
+msgid "%s aborted"
+msgstr "%s је прекинута"
+
+#, c-format
+msgid "%s returning #%ld"
+msgstr "%s враћа #%ld"
+
+#, c-format
+msgid "%s returning %s"
+msgstr "%s враћа %s"
+
+msgid "E699: Too many arguments"
+msgstr "E699: Сувише аргумената"
+
+#, c-format
+msgid "E117: Unknown function: %s"
+msgstr "E117: Ðепозната функција: %s"
+
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: Функција је обриÑана: %s"
+
+#, c-format
+msgid "E119: Not enough arguments for function: %s"
+msgstr "E119: Ðема довољно аргумената за функцију: %s"
+
+#, c-format
+msgid "E120: Using <SID> not in a script context: %s"
+msgstr "E120: Коришћење <SID> ван Ñкрипт контекÑта: %s"
+
+#, c-format
+msgid "E725: Calling dict function without Dictionary: %s"
+msgstr "E725: Позивање dict функције без Речника: %s"
+
+msgid "E129: Function name required"
+msgstr "E129: Потребно је име функције"
+
+#, c-format
+msgid "E128: Function name must start with a capital or \"s:\": %s"
+msgstr "E128: Име функције мора да почне великим Ñловом или \"s:\": %s"
+
+#, c-format
+msgid "E884: Function name cannot contain a colon: %s"
+msgstr "E884: Име функције не може да Ñадржи двотачку: %s"
+
+#, c-format
+msgid "E123: Undefined function: %s"
+msgstr "E123: ÐедефиниÑана функција: %s"
+
+#, c-format
+msgid "E124: Missing '(': %s"
+msgstr "E124: ÐедоÑтаје '(': %s"
+
+msgid "E862: Cannot use g: here"
+msgstr "E862: g: не може овде да Ñе кориÑти"
+
+#, c-format
+msgid "E932: Closure function should not be at top level: %s"
+msgstr "E932: Затварајућа функција не би требало да буде на највишем нивоу: %s"
+
+msgid "E126: Missing :endfunction"
+msgstr "E126: ÐедоÑтаје :endfunction"
+
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: Пронађен текÑÑ‚ након :endfunction: %s"
+
+#, c-format
+msgid "E707: Function name conflicts with variable: %s"
+msgstr "E707: Име функције је у конфликту Ñа променљивом: %s"
+
+#, c-format
+msgid "E127: Cannot redefine function %s: It is in use"
+msgstr "E127: Функција %s не може да Ñе редефинише: Тренутно Ñе кориÑти"
+
+#, c-format
+msgid "E746: Function name does not match script file name: %s"
+msgstr "E746: Име функције Ñе не поклапа Ñа именом Ñкрипт датотеке: %s"
+
+#, c-format
+msgid "E131: Cannot delete function %s: It is in use"
+msgstr "E131: Функција %s не може да Ñе обрише: Тренутно Ñе кориÑти"
+
+msgid "E133: :return not inside a function"
+msgstr "E133: :return није унутар функције"
+
+#, c-format
+msgid "E107: Missing parentheses: %s"
+msgstr "E107: ÐедоÑтају заграде: %s"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 64-битна GUI верзија"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit GUI version"
+msgstr ""
+"\n"
+"MS-Windows 32-битна GUI верзија"
+
+msgid " with OLE support"
+msgstr " Ñа OLE подршком"
+
+msgid ""
+"\n"
+"MS-Windows 64-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 64-битна конзолна верзија"
+
+msgid ""
+"\n"
+"MS-Windows 32-bit console version"
+msgstr ""
+"\n"
+"MS-Windows 32-битна конзолна верзија"
+
+msgid ""
+"\n"
+"macOS version"
+msgstr ""
+"\n"
+"macOS верзија"
+
+msgid ""
+"\n"
+"macOS version w/o darwin feat."
+msgstr ""
+"\n"
+"macOS верзија без darwin могућ."
+
+msgid ""
+"\n"
+"OpenVMS version"
+msgstr ""
+"\n"
+"OpenVMS верзија"
+
+msgid ""
+"\n"
+"Included patches: "
+msgstr ""
+"\n"
+"Укључене иÑправке: "
+
+msgid ""
+"\n"
+"Extra patches: "
+msgstr ""
+"\n"
+"ЕкÑтра иÑправке: "
+
+msgid "Modified by "
+msgstr "Модификовао "
+
+msgid ""
+"\n"
+"Compiled "
+msgstr ""
+"\n"
+"Компајлирао"
+
+msgid "by "
+msgstr " "
+
+msgid ""
+"\n"
+"Huge version "
+msgstr ""
+"\n"
+"Огромна верзија "
+
+msgid ""
+"\n"
+"Big version "
+msgstr ""
+"\n"
+"Велика верзија "
+
+msgid ""
+"\n"
+"Normal version "
+msgstr ""
+"\n"
+"Ðормална верзија "
+
+msgid ""
+"\n"
+"Small version "
+msgstr ""
+"\n"
+"Мала верзија "
+
+msgid ""
+"\n"
+"Tiny version "
+msgstr ""
+"\n"
+"Сићушна верзија "
+
+msgid "without GUI."
+msgstr "без GUI."
+
+msgid "with GTK3 GUI."
+msgstr "Ñа GTK3 GUI."
+
+msgid "with GTK2-GNOME GUI."
+msgstr "Ñа GTK2-GNOME GUI."
+
+msgid "with GTK2 GUI."
+msgstr "Ñа GTK2 GUI."
+
+msgid "with X11-Motif GUI."
+msgstr "Ñа X11-Motif GUI."
+
+msgid "with X11-neXtaw GUI."
+msgstr "Ñа X11-neXtaw GUI."
+
+msgid "with X11-Athena GUI."
+msgstr "Ñа X11-Athena GUI."
+
+msgid "with Photon GUI."
+msgstr "Ñа Photon GUI."
+
+msgid "with GUI."
+msgstr "Ñа GUI."
+
+msgid "with Carbon GUI."
+msgstr "Ñа Carbon GUI."
+
+msgid "with Cocoa GUI."
+msgstr "Ñа Cocoa GUI."
+
+msgid " Features included (+) or not (-):\n"
+msgstr " МогућноÑти укључене (+) или не (-):\n"
+
+msgid " system vimrc file: \""
+msgstr " ÑиÑтемÑкa vimrc датотека: \""
+
+msgid " user vimrc file: \""
+msgstr " кориÑничка vimrc датотека: \""
+
+msgid " 2nd user vimrc file: \""
+msgstr " 2га кориÑничка vimrc датотека: \""
+
+msgid " 3rd user vimrc file: \""
+msgstr " 3ћа кориÑничка vimrc датотека: \""
+
+msgid " user exrc file: \""
+msgstr " кориÑничка exrc датотека: \""
+
+msgid " 2nd user exrc file: \""
+msgstr " 2га кориÑничка exrc датотека: \""
+
+msgid " system gvimrc file: \""
+msgstr " ÑиÑтемÑка gvimrc датотека: \""
+
+msgid " user gvimrc file: \""
+msgstr " кориÑничка gvimrc датотека: \""
+
+msgid "2nd user gvimrc file: \""
+msgstr "2га кориÑничка gvimrc датотека: \""
+
+msgid "3rd user gvimrc file: \""
+msgstr "3ћа кориÑничка gvimrc датотека: \""
+
+msgid " defaults file: \""
+msgstr " датотека Ñа подраз. опцијама: \""
+
+msgid " system menu file: \""
+msgstr " ÑиÑтемÑка датотека менија: \""
+
+msgid " fall-back for $VIM: \""
+msgstr " резервна вредноÑÑ‚ за $VIM: \""
+
+msgid " f-b for $VIMRUNTIME: \""
+msgstr "резервна вредн. за $VIMRUNTIME: \""
+
+msgid "Compilation: "
+msgstr "Компилација: "
+
+msgid "Compiler: "
+msgstr "Компајлер: "
+
+msgid "Linking: "
+msgstr "Повезивање: "
+
+msgid " DEBUG BUILD"
+msgstr " DEBUG ИЗДÐЊЕ"
+
+msgid "VIM - Vi IMproved"
+msgstr "VIM - Vi IMproved"
+
+msgid "version "
+msgstr "верзија "
+
+msgid "by Bram Moolenaar et al."
+msgstr "напиÑали Bram Moolenaar et al."
+
+msgid "Vim is open source and freely distributable"
+msgstr "Vim је отвореног кода и може Ñлободно да Ñе диÑтрибуира"
+
+msgid "Help poor children in Uganda!"
+msgstr "Помозите Ñиромашној деци у Уганди!"
+
+msgid "type :help iccf<Enter> for information "
+msgstr "откуцајте :help iccf<Enter> за информације "
+
+msgid "type :q<Enter> to exit "
+msgstr "откуцајте :q<Enter> за излаз "
+
+msgid "type :help<Enter> or <F1> for on-line help"
+msgstr "откуцајте :help<Enter> или <F1> за on-line помоћ "
+
+msgid "type :help version8<Enter> for version info"
+msgstr "откуцајте :help version8<Enter> за инфо о верзији"
+
+msgid "Running in Vi compatible mode"
+msgstr "Рад у Vi компатибилном режиму"
+
+msgid "type :set nocp<Enter> for Vim defaults"
+msgstr "откуцајте :set nocp<Enter> за Vim подразумевано"
+
+msgid "type :help cp-default<Enter> for info on this"
+msgstr "откуцајте :help cp-default<Enter> за инфо о овоме"
+
+msgid "menu Help->Orphans for information "
+msgstr "мени Помоћ->Сирочићи за информације "
+
+msgid "Running modeless, typed text is inserted"
+msgstr "БезрежимÑки рад, умеће Ñе откуцани текÑÑ‚"
+
+msgid "menu Edit->Global Settings->Toggle Insert Mode "
+msgstr "мени Уређивање->Глобална подешавања->Преклапај режим Уметање "
+
+msgid " for two modes "
+msgstr " за два режима "
+
+msgid "menu Edit->Global Settings->Toggle Vi Compatible"
+msgstr "мени Уређивање->Глобална подешавања->Преклапај Vi Компатибилно"
+
+msgid " for Vim defaults "
+msgstr " за Vim подразумевано "
+
+msgid "Sponsor Vim development!"
+msgstr "Спонзоришите Vim развој!"
+
+msgid "Become a registered Vim user!"
+msgstr "ПоÑтаните региÑтровани Vim кориÑник!"
+
+msgid "type :help sponsor<Enter> for information "
+msgstr "откуцајте :help sponsor<Enter> за информације "
+
+msgid "type :help register<Enter> for information "
+msgstr "откуцајте :help register<Enter> за информације "
+
+msgid "menu Help->Sponsor/Register for information "
+msgstr "мени Помоћ->Спонзор/РегиÑтруј Ñе за информације "
+
+msgid "Already only one window"
+msgstr "Већ поÑтоји Ñамо један прозор"
+
+msgid "E441: There is no preview window"
+msgstr "E441: Ðема прозора за преглед"
+
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: topleft и botright не могу да Ñе поделе у иÑто време"
+
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Ðе може да Ñе ротира када је подељен други прозор"
+
+msgid "E444: Cannot close last window"
+msgstr "E444: ПоÑледњи прозор не може да Ñе затвори"
+
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: autocmd прозор не може да Ñе затвори"
+
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Прозор не може да Ñе затвори, преоÑтао би једино autocmd прозор"
+
+msgid "E445: Other window contains changes"
+msgstr "E445: Други прозори Ñадрже измене"
+
+msgid "E446: No file name under cursor"
+msgstr "E446: Под курÑором Ñе не налази име датотеке"
+
+#, c-format
+msgid "E447: Can't find file \"%s\" in path"
+msgstr "E447: Датотека \"%s\" не може да Ñе пронађе у путањи"
+
+#, c-format
+msgid "E799: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E799: Ðеважећи ИД: %ld (мора бити већи од или једнак 1)"
+
+#, c-format
+msgid "E801: ID already taken: %ld"
+msgstr "E801: ИД је већ заузет: %ld"
+
+msgid "List or number required"
+msgstr "Захтева Ñе лиÑта или број"
+
+#, c-format
+msgid "E802: Invalid ID: %ld (must be greater than or equal to 1)"
+msgstr "E802: Ðеважећи ИД: %ld (мора бити већи од или једнак 1)"
+
+#, c-format
+msgid "E803: ID not found: %ld"
+msgstr "E803: ИД није пронађен: %ld"
+
+msgid "Edit with &multiple Vims"
+msgstr "Уређуј Ñа &више Vim-ова"
+
+msgid "Edit with single &Vim"
+msgstr "Уређуј Ñа једним &Vim-ом"
+
+msgid "Diff with Vim"
+msgstr "Diff Ñа Vim"
+
+msgid "Edit with &Vim"
+msgstr "Уређуј Ñа &Vim-ом"
+
+msgid "Edit with existing Vim - "
+msgstr "Уређуј Ñа поÑтојећим Vim - "
+
+msgid "Edits the selected file(s) with Vim"
+msgstr "Уређује Ñелектовауе датотеку(е) Ñа Vim-ом"
+
+msgid "Error creating process: Check if gvim is in your path!"
+msgstr ""
+"Грешка приликом креирања процеÑа: Проверите да ли је gvim у вашој путањи!"
+
+msgid "gvimext.dll error"
+msgstr "gvimext.dll грешка"
+
+msgid "Path length too long!"
+msgstr "Путања је предугачка!"
+
+msgid "--No lines in buffer--"
+msgstr "--У баферу нема линија--"
+
+msgid "E470: Command aborted"
+msgstr "E470: Команда прекинута"
+
+msgid "E471: Argument required"
+msgstr "E471: Потребан је аргумент"
+
+msgid "E10: \\ should be followed by /, ? or &"
+msgstr "E10: Иза \\ треба да је /, ? или &"
+
+msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
+msgstr ""
+"E11: Ðеважеће у прозору командне линије; <CR> извршава, CTRL-C отказује"
+
+msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
+msgstr ""
+"E12: ПоÑтоји забрана за команду у exrc/vimrc у текућој претрази "
+"директоријума или ознаке"
+
+msgid "E171: Missing :endif"
+msgstr "E171: ÐедоÑтаје :endif"
+
+msgid "E600: Missing :endtry"
+msgstr "E600: ÐедоÑтаје :endtry"
+
+msgid "E170: Missing :endwhile"
+msgstr "E170: ÐедоÑтаје :endwhile"
+
+msgid "E170: Missing :endfor"
+msgstr "E170: ÐедоÑтаје :endfor"
+
+msgid "E588: :endwhile without :while"
+msgstr "E588: :endwhile без :while"
+
+msgid "E588: :endfor without :for"
+msgstr "E588: :endfor без :for"
+
+msgid "E13: File exists (add ! to override)"
+msgstr "E13: Датотека поÑтоји (додајте ! за премошћавање)"
+
+msgid "E472: Command failed"
+msgstr "E472: Команда није уÑпела"
+
+#, c-format
+msgid "E234: Unknown fontset: %s"
+msgstr "E234: Ðепознат fontset: %s"
+
+#, c-format
+msgid "E235: Unknown font: %s"
+msgstr "E235: Ðепознат фонт: %s"
+
+#, c-format
+msgid "E236: Font \"%s\" is not fixed-width"
+msgstr "E236: Фонт \"%s\" није фикÑне ширине"
+
+msgid "E473: Internal error"
+msgstr "E473: Интерна грешка"
+
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Интерна грешка: %s"
+
+msgid "Interrupted"
+msgstr "Прекинуто"
+
+msgid "E14: Invalid address"
+msgstr "E14: Ðеважећа адреÑа"
+
+msgid "E474: Invalid argument"
+msgstr "E474: Ðеважећи аргумент"
+
+#, c-format
+msgid "E475: Invalid argument: %s"
+msgstr "E475: Ðеважећи аргумент: %s"
+
+#, c-format
+msgid "E475: Invalid value for argument %s"
+msgstr "E475: Ðеважећa вредноÑÑ‚ за аргумент: %s"
+
+#, c-format
+msgid "E475: Invalid value for argument %s: %s"
+msgstr "E475: Ðеважећa вредноÑÑ‚ за аргумент %s: %s"
+
+#, c-format
+msgid "E15: Invalid expression: %s"
+msgstr "E15: Ðеважећи израз: %s"
+
+msgid "E16: Invalid range"
+msgstr "E16: Ðеважећи опÑег"
+
+msgid "E476: Invalid command"
+msgstr "E476: Ðеважећа команда"
+
+#, c-format
+msgid "E17: \"%s\" is a directory"
+msgstr "E17: \"%s\" је директоријум"
+
+#, c-format
+msgid "E364: Library call failed for \"%s()\""
+msgstr "E364: Позив библиотеке није уÑпео за \"%s()\""
+
+msgid "E667: Fsync failed"
+msgstr "E667: Fsync није уÑпео"
+
+#, c-format
+msgid "E448: Could not load library function %s"
+msgstr "E448: Библиотечка функција %s није могла да Ñе учита"
+
+msgid "E19: Mark has invalid line number"
+msgstr "E19: Маркер Ñадржи неиÑправан број линије"
+
+msgid "E20: Mark not set"
+msgstr "E20: Маркер није поÑтављен"
+
+msgid "E21: Cannot make changes, 'modifiable' is off"
+msgstr "E21: Измене не могу да Ñе учине, опција 'modifiable' је иÑкључена"
+
+msgid "E22: Scripts nested too deep"
+msgstr "E22: Скрипте Ñу предубоко угњеждене"
+
+msgid "E23: No alternate file"
+msgstr "E23: Ðема алтернативне датотеке"
+
+msgid "E24: No such abbreviation"
+msgstr "E24: Таква Ñкраћеница не поÑтоји"
+
+msgid "E477: No ! allowed"
+msgstr "E477: ! није дозвољен"
+
+msgid "E25: GUI cannot be used: Not enabled at compile time"
+msgstr "E25: GUI не може да Ñе кориÑти: Ðије омогућен у време компилације"
+
+msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E26: хебрејÑки не може да Ñе кориÑти: Ðије омогућен у време компилације\n"
+
+msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
+msgstr "E27: фарÑи не може да Ñе кориÑти: Ðије омогућен у време компилације\n"
+
+msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
+msgstr ""
+"E800: арапÑки не може да Ñе кориÑти: Ðије омогућен у време компилације\n"
+
+#, c-format
+msgid "E28: No such highlight group name: %s"
+msgstr "E28: Ðема групе иÑтицања Ñа таквим именом: %s"
+
+msgid "E29: No inserted text yet"
+msgstr "E29: ТекÑÑ‚ још није унет"
+
+msgid "E30: No previous command line"
+msgstr "E30: Ðема претходне командне линије"
+
+msgid "E31: No such mapping"
+msgstr "E31: Такво мапирање не поÑтоји"
+
+msgid "E479: No match"
+msgstr "E479: Ðема подударања"
+
+#, c-format
+msgid "E480: No match: %s"
+msgstr "E480: Ðема подударања: %s"
+
+msgid "E32: No file name"
+msgstr "E32: Ðема имена датотеке"
+
+msgid "E33: No previous substitute regular expression"
+msgstr "E33: Ðема претходног регуларног израза за замену"
+
+msgid "E34: No previous command"
+msgstr "E34: Ðема претходне команде"
+
+msgid "E35: No previous regular expression"
+msgstr "E35: Ðема претходног регуларног израза"
+
+msgid "E481: No range allowed"
+msgstr "E481: ОпÑег није дозвољен"
+
+msgid "E36: Not enough room"
+msgstr "E36: Ðема довољно проÑтора"
+
+#, c-format
+msgid "E247: no registered server named \"%s\""
+msgstr "E247: нема региÑтованог Ñервера под именом \"%s\""
+
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Датотека %s не може да Ñе креира"
+
+msgid "E483: Can't get temp file name"
+msgstr "E483: Име привремене датотке не може да Ñе добије"
+
+#, c-format
+msgid "E484: Can't open file %s"
+msgstr "E484: Датотека %s не може да Ñе отвори"
+
+#, c-format
+msgid "E485: Can't read file %s"
+msgstr "E485: Датотека %s не може да Ñе прочита"
+
+msgid "E38: Null argument"
+msgstr "E38: Празан аргумент"
+
+msgid "E39: Number expected"
+msgstr "E39: Очекује Ñе број"
+
+#, c-format
+msgid "E40: Can't open errorfile %s"
+msgstr "E40: Датотека грешке %s не може да Ñе отвори"
+
+msgid "E233: cannot open display"
+msgstr "E233: проказ не може да Ñе отвори"
+
+msgid "E41: Out of memory!"
+msgstr "E41: Ðема више меморије!"
+
+msgid "Pattern not found"
+msgstr "Шаблон није пронађен"
+
+#, c-format
+msgid "E486: Pattern not found: %s"
+msgstr "E486: Шаблон није пронађен: %s"
+
+msgid "E487: Argument must be positive"
+msgstr "E487: Ðргумент мора бити позитиван"
+
+msgid "E459: Cannot go back to previous directory"
+msgstr "E459: Ðе може да Ñе оде назад на претходни директоријум"
+
+msgid "E42: No Errors"
+msgstr "E42: Ðема грешака"
+
+msgid "E776: No location list"
+msgstr "E776: Ðема лиÑте локација"
+
+msgid "E43: Damaged match string"
+msgstr "E43: Оштећен Ñтринг за подударање"
+
+msgid "E44: Corrupted regexp program"
+msgstr "E44: regexp програм је покварен"
+
+msgid "E45: 'readonly' option is set (add ! to override)"
+msgstr "E45: ПоÑтављена је 'readonly' опција (додајте ! за премошћавање)"
+
+#, c-format
+msgid "E46: Cannot change read-only variable \"%s\""
+msgstr "E46: Променљива Ñамо за читање \"%s\" не може да Ñе измени"
+
+#, c-format
+msgid "E794: Cannot set variable in the sandbox: \"%s\""
+msgstr "E794: Ðе може да Ñе поÑтави променљива у sandbox-у: \"%s\""
+
+msgid "E713: Cannot use empty key for Dictionary"
+msgstr "E713: Ðе може да Ñе кориÑти празан кључ за Речник"
+
+msgid "E715: Dictionary required"
+msgstr "E715: Потребан Речник"
+
+#, c-format
+msgid "E684: list index out of range: %ld"
+msgstr "E684: Ð¸Ð½Ð´ÐµÐºÑ Ð»Ð¸Ñте је ван опÑега: %ld"
+
+#, c-format
+msgid "E118: Too many arguments for function: %s"
+msgstr "E118: Превише аргумената за функцију: %s"
+
+#, c-format
+msgid "E716: Key not present in Dictionary: %s"
+msgstr "E716: У Речнику нема кључа: %s"
+
+msgid "E714: List required"
+msgstr "E714: Потребна ЛиÑта"
+
+#, c-format
+msgid "E712: Argument of %s must be a List or Dictionary"
+msgstr "E712: Ðргумент за %s мора бити ЛиÑта или Речник"
+
+msgid "E47: Error while reading errorfile"
+msgstr "E47: Грешка приликом читаља датотеке грешке"
+
+msgid "E48: Not allowed in sandbox"
+msgstr "E48: Ðије дозвољено у sandbox-у"
+
+msgid "E523: Not allowed here"
+msgstr "E523: Ðије дозвољено овде"
+
+msgid "E359: Screen mode setting not supported"
+msgstr "E359: Подешавање режима екрана није подржано"
+
+msgid "E49: Invalid scroll size"
+msgstr "E49: Ðеважећа величина линије за Ñкроловање"
+
+msgid "E91: 'shell' option is empty"
+msgstr "E91: Опција 'shell' је празна"
+
+msgid "E255: Couldn't read in sign data!"
+msgstr "E255: Подаци за знак ниÑу могли да Ñе прочитају!"
+
+msgid "E72: Close error on swap file"
+msgstr "E72: Грешка код затвањара swap датотеке"
+
+msgid "E73: tag stack empty"
+msgstr "E73: Ñтек ознака је празан"
+
+msgid "E74: Command too complex"
+msgstr "E74: Команда је Ñувише комплекÑна"
+
+msgid "E75: Name too long"
+msgstr "E75: Име је предугачко"
+
+msgid "E76: Too many ["
+msgstr "E76: Превише ["
+
+msgid "E77: Too many file names"
+msgstr "E77: Превише имена датотека"
+
+msgid "E488: Trailing characters"
+msgstr "E488: Карактери вишка на крају"
+
+msgid "E78: Unknown mark"
+msgstr "E78: Ðепознат маркер"
+
+msgid "E79: Cannot expand wildcards"
+msgstr "E79: Ðокери не могу да Ñе развију"
+
+msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
+msgstr "E591: 'winheight' не може да буде мање од 'winminheight'"
+
+msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
+msgstr "E592: 'winwidth' не може да буде мање од 'winminwidth'"
+
+msgid "E80: Error while writing"
+msgstr "E80: Грешка приликом упиÑа"
+
+msgid "E939: Positive count required"
+msgstr "E939: Потребан је позитиван број"
+
+msgid "E81: Using <SID> not in a script context"
+msgstr "E81: <SID> Ñе кориÑти ван Ñкрипт контекÑта"
+
+msgid "E449: Invalid expression received"
+msgstr "E449: Примљен је неважећи израз"
+
+msgid "E463: Region is guarded, cannot modify"
+msgstr "E463: Регион је чуван, измена није могућа"
+
+msgid "E744: NetBeans does not allow changes in read-only files"
+msgstr ""
+"E744: NetBeans не дозвољава измене датотека које Ñмеју Ñамо да Ñе читају"
+
+msgid "E363: pattern uses more memory than 'maxmempattern'"
+msgstr "E363: шаблон кориÑти више меморије од 'maxmempattern'"
+
+msgid "E749: empty buffer"
+msgstr "E749: празан бафер"
+
+#, c-format
+msgid "E86: Buffer %ld does not exist"
+msgstr "E86: Бафер %ld не поÑтоји"
+
+msgid "E682: Invalid search pattern or delimiter"
+msgstr "E682: Ðеважећи шаблон претраге или раздвојни карактер"
+
+msgid "E139: File is loaded in another buffer"
+msgstr "E139: Датотека је учитана у други бафер"
+
+#, c-format
+msgid "E764: Option '%s' is not set"
+msgstr "E764: Опција '%s' није поÑтављена"
+
+msgid "E850: Invalid register name"
+msgstr "E850: Ðеважеће име региÑтра"
+
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Ðије пронађен директоријум у '%s': \"%s\""
+
+msgid "E952: Autocommand caused recursive behavior"
+msgstr "E952: Ðутокомандa je изазвала рекурзивно понашање"
+
+msgid "search hit TOP, continuing at BOTTOM"
+msgstr "претрага је доÑтигла ВРХ, наÑтавља Ñе на ДÐУ"
+
+msgid "search hit BOTTOM, continuing at TOP"
+msgstr "претрага је доÑтигла ДÐО, наÑтавља Ñе на ВРХУ"
+
+#, c-format
+msgid "Need encryption key for \"%s\""
+msgstr "Потребан је кључ за шифровање \"%s\""
+
+msgid "empty keys are not allowed"
+msgstr "празни кључеви ниÑу дозвољени"
+
+msgid "dictionary is locked"
+msgstr "речник је закључан"
+
+msgid "list is locked"
+msgstr "лиÑта је закључана"
+
+#, c-format
+msgid "failed to add key '%s' to dictionary"
+msgstr "кључ '%s' није могао да Ñе дода у речник"
+
+#, c-format
+msgid "index must be int or slice, not %s"
+msgstr "index мора бити типа int или slice, не %s"
+
+#, c-format
+msgid "expected str() or unicode() instance, but got %s"
+msgstr "очекивала Ñе инÑтанца str() или unicode(), али је добијена %s"
+
+#, c-format
+msgid "expected bytes() or str() instance, but got %s"
+msgstr "очекивала Ñе инÑтанца bytes() или str(), али је добијена %s"
+
+#, c-format
+msgid ""
+"expected int(), long() or something supporting coercing to long(), but got %s"
+msgstr ""
+"очекивало Ñе int(), long() или нешто што подржава Ñпајање Ñа long(), али је "
+"добијено %s"
+
+#, c-format
+msgid "expected int() or something supporting coercing to int(), but got %s"
+msgstr ""
+"очекивало Ñе int() или нешто што подржава Ñпајање Ñа int(), али је добијено %"
+"s"
+
+msgid "value is too large to fit into C int type"
+msgstr "вредноÑÑ‚ је Ñувише велика да Ñе ÑмеÑти у C int тип"
+
+msgid "value is too small to fit into C int type"
+msgstr "вредноÑÑ‚ је Ñувише мала да Ñе ÑмеÑти у C int тип"
+
+msgid "number must be greater than zero"
+msgstr "број мора бити већи од нуле"
+
+msgid "number must be greater or equal to zero"
+msgstr "број мора бити већи од или једнак нули"
+
+msgid "can't delete OutputObject attributes"
+msgstr "атрибути OutputObject не могу да Ñе обришу"
+
+#, c-format
+msgid "invalid attribute: %s"
+msgstr "неважећи атрибут: %s"
+
+msgid "E264: Python: Error initialising I/O objects"
+msgstr "E264: Python: Грешка код иницијализације У/И објеката"
+
+msgid "failed to change directory"
+msgstr "не може да Ñе промени директоријум"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got %s"
+msgstr "Као резултат imp.find_module() очекује Ñе триплет, али је добијено %s"
+
+#, c-format
+msgid "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
+msgstr ""
+"Као резултат imp.find_module() очекује Ñе триплет, али је добијена н-торка "
+"величине %d"
+
+msgid "internal error: imp.find_module returned tuple with NULL"
+msgstr "интерна грешка: imp.find_module је вратио н-торку Ñа NULL"
+
+msgid "cannot delete vim.Dictionary attributes"
+msgstr "vim.Dictionary атрибути не могу да Ñе обришу"
+
+msgid "cannot modify fixed dictionary"
+msgstr "фикÑни речник не може да Ñе измени"
+
+#, c-format
+msgid "cannot set attribute %s"
+msgstr "атрибут %s не може да Ñе поÑтави"
+
+msgid "hashtab changed during iteration"
+msgstr "hashtab је промењен током итерације"
+
+#, c-format
+msgid "expected sequence element of size 2, but got sequence of size %d"
+msgstr ""
+"очекивао Ñе елемент Ñеквенце величине 2, али је добијена Ñеквенца "
+"величине %d"
+
+msgid "list constructor does not accept keyword arguments"
+msgstr "конÑтруктор лиÑте не прихвата кључне речи за аргументе"
+
+msgid "list index out of range"
+msgstr "Ð¸Ð½Ð´ÐµÐºÑ Ð»Ð¸Ñте је ван опÑега"
+
+#, c-format
+msgid "internal error: failed to get vim list item %d"
+msgstr "интерна грешка: Ñтавка %d vim лиÑте није могла да Ñе добије"
+
+msgid "slice step cannot be zero"
+msgstr "slice корак не може да буде нула"
+
+#, c-format
+msgid "attempt to assign sequence of size greater than %d to extended slice"
+msgstr "покушај доделе Ñеквенце величине веће од %d како би Ñе продужио slice"
+
+#, c-format
+msgid "internal error: no vim list item %d"
+msgstr "интерна грешка: нема Ñтавке %d у vim лиÑти"
+
+msgid "internal error: not enough list items"
+msgstr "интерна грешка: нема довољно Ñтавки лиÑте"
+
+msgid "internal error: failed to add item to list"
+msgstr "интерна грешка: Ñтавка није могла да Ñе дода лиÑти"
+
+#, c-format
+msgid "attempt to assign sequence of size %d to extended slice of size %d"
+msgstr ""
+"покушај доделе Ñеквенце величине %d како би Ñе продужио slice величине %d"
+
+msgid "failed to add item to list"
+msgstr "Ñтавка није могла да Ñе дода лиÑти"
+
+msgid "cannot delete vim.List attributes"
+msgstr "vim.List атрибути не могу да Ñе обришу"
+
+msgid "cannot modify fixed list"
+msgstr "фикÑна лиÑта не може да Ñе измени"
+
+#, c-format
+msgid "unnamed function %s does not exist"
+msgstr "неименована функција %s не поÑтоји"
+
+#, c-format
+msgid "function %s does not exist"
+msgstr "функција %s не поÑтоји"
+
+#, c-format
+msgid "failed to run function %s"
+msgstr "функција %s није могла да Ñе покрене"
+
+msgid "unable to get option value"
+msgstr "вредноÑÑ‚ опције није могла да Ñе добије"
+
+msgid "internal error: unknown option type"
+msgstr "интерна грешка: непознат тип опције"
+
+msgid "problem while switching windows"
+msgstr "проблем код пребацивања прозора"
+
+#, c-format
+msgid "unable to unset global option %s"
+msgstr "глобална опција %s није могла да Ñе иÑкључи"
+
+#, c-format
+msgid "unable to unset option %s which does not have global value"
+msgstr "опција %s која нема глобалну вредноÑÑ‚ није могла да Ñе иÑкључи"
+
+msgid "attempt to refer to deleted tab page"
+msgstr "покушај рефериÑања на обриÑану картицу"
+
+msgid "no such tab page"
+msgstr "не поÑтоји таква картица"
+
+msgid "attempt to refer to deleted window"
+msgstr "покушај рефериÑања на обриÑан прозор"
+
+msgid "readonly attribute: buffer"
+msgstr "атрибут Ñамо за читање: бафер"
+
+msgid "cursor position outside buffer"
+msgstr "позиција курÑора је ван бафера"
+
+msgid "no such window"
+msgstr "нема таквог прозора"
+
+msgid "attempt to refer to deleted buffer"
+msgstr "покушај рефериÑања на обриÑан бафер"
+
+msgid "failed to rename buffer"
+msgstr "име бафера није могло да Ñе промени"
+
+msgid "mark name must be a single character"
+msgstr "име маркера мора бити Ñамо један карактер"
+
+#, c-format
+msgid "expected vim.Buffer object, but got %s"
+msgstr "очекивао Ñе vim.Buffer објекат, али је добијен %s"
+
+#, c-format
+msgid "failed to switch to buffer %d"
+msgstr "прелазак на бафер %d није био могућ"
+
+#, c-format
+msgid "expected vim.Window object, but got %s"
+msgstr "очекивао Ñе vim.Window објекат, али је добијен %s"
+
+msgid "failed to find window in the current tab page"
+msgstr "прозор није пронађен у текућој картици"
+
+msgid "did not switch to the specified window"
+msgstr "није Ñе прешло у наведени прозор"
+
+#, c-format
+msgid "expected vim.TabPage object, but got %s"
+msgstr "очекивао Ñе vim.TabPage објекат, али је добијен %s"
+
+msgid "did not switch to the specified tab page"
+msgstr "није Ñе прешло у наведену картицу"
+
+msgid "failed to run the code"
+msgstr "кôд није могао да Ñе покрене"
+
+msgid "E858: Eval did not return a valid python object"
+msgstr "E858: Eval није вратио важећи python објекат"
+
+msgid "E859: Failed to convert returned python object to vim value"
+msgstr "E859: Конверзија враћеног python објекта у vim вредноÑÑ‚ није уÑпела"
+
+#, c-format
+msgid "unable to convert %s to vim dictionary"
+msgstr "%s не може да Ñе конвертује у vim речник"
+
+#, c-format
+msgid "unable to convert %s to vim list"
+msgstr "%s не може да Ñе конвертује у vim лиÑту"
+
+#, c-format
+msgid "unable to convert %s to vim structure"
+msgstr "%s не може да Ñе конвертује у vim Ñтруктуру"
+
+msgid "internal error: NULL reference passed"
+msgstr "интерна грешка: проÑлеђена је NULL референца"
+
+msgid "internal error: invalid value type"
+msgstr "интерна грешка: вредноÑÑ‚ неважећег типа"
+
+msgid ""
+"Failed to set path hook: sys.path_hooks is not a list\n"
+"You should now do the following:\n"
+"- append vim.path_hook to sys.path_hooks\n"
+"- append vim.VIM_SPECIAL_PATH to sys.path\n"
+msgstr ""
+"Кука за путању није могла да Ñе поÑтави: sys.path_hooks није у лиÑти\n"
+"Сада би требало да урадите Ñледеће:\n"
+"- додајте vim.path_hook на крај sys.path_hooks\n"
+"- додајте vim.VIM_SPECIAL_PATH на крај sys.path\n"
+
+msgid ""
+"Failed to set path: sys.path is not a list\n"
+"You should now append vim.VIM_SPECIAL_PATH to sys.path"
+msgstr ""
+"Путања није могла да Ñе поÑтави: sys.path није у лиÑти\n"
+"Сада би требало да додате vim.VIM_SPECIAL_PATH на крај sys.path"
+
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*.*)\t*.*\n"
+msgstr ""
+"Vim макро датотеке (*.vim)\t*.vim\n"
+"Све датотеке (*.*)\t*.*\n"
+
+msgid "All Files (*.*)\t*.*\n"
+msgstr "Све датотеке (*.*)\t*.*\n"
+
+msgid ""
+"All Files (*.*)\t*.*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VB code (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"Све датотеке (*.*)\t*.*\n"
+"C изворни код (*.c, *.h)\t*.c;*.h\n"
+"C++ изворни код (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"VB код (*.bas, *.frm)\t*.bas;*.frm\n"
+"Vim датотеке (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+
+msgid ""
+"Vim macro files (*.vim)\t*.vim\n"
+"All Files (*)\t*\n"
+msgstr ""
+"Vim макро датотеке (*.vim)\t*.vim\n"
+"Све датотеке (*)\t*\n"
+
+msgid "All Files (*)\t*\n"
+msgstr "Све датотеке (*)\t*\n"
+
+msgid ""
+"All Files (*)\t*\n"
+"C source (*.c, *.h)\t*.c;*.h\n"
+"C++ source (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vim files (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
+msgstr ""
+"Све датотеке (*)\t*\n"
+"C изворни код (*.c, *.h)\t*.c;*.h\n"
+"C++ изворни код (*.cpp, *.hpp)\t*.cpp;*.hpp\n"
+"Vim датотеке (*.vim, _vimrc, _gvimrc)\t*.vim;_vimrc;_gvimrc\n"
diff --git a/src/nvim/po/sv.po b/src/nvim/po/sv.po
index eedaecd1e7..4770db15de 100644
--- a/src/nvim/po/sv.po
+++ b/src/nvim/po/sv.po
@@ -818,7 +818,7 @@ msgstr "E216: Ingen sådan grupp eller händelse: %s"
#: ../fileio.c:5994
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Autokommandon ---"
@@ -842,7 +842,7 @@ msgstr "E218: autokommando nästlad för djupt"
#: ../fileio.c:7043
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s Autokommandon för \"%s\""
#: ../fileio.c:7049
@@ -3792,8 +3792,8 @@ msgstr "Varning: region %s stöds inte"
#: ../spell.c:4362
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "Läser affix-fil %s ..."
+msgid "Reading affix file %s..."
+msgstr "Läser affix-fil %s..."
#: ../spell.c:4401 ../spell.c:5439 ../spell.c:5944
#, c-format
@@ -3953,8 +3953,8 @@ msgstr "%s värde skiljer sig från vad som används i en annan .aff-fil."
#: ../spell.c:5406
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Läser ordboksfil %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "Läser ordboksfil %s..."
#: ../spell.c:5415
#, c-format
@@ -3988,8 +3988,8 @@ msgstr "Ignorerade %d ord med icke-ASCII tecken i %s"
#: ../spell.c:5919
#, c-format
-msgid "Reading word file %s ..."
-msgstr "Läser ordfil %s ..."
+msgid "Reading word file %s..."
+msgstr "Läser ordfil %s..."
#: ../spell.c:5959
#, c-format
@@ -4058,8 +4058,8 @@ msgstr "Totalt antal ord: %d"
#: ../spell.c:7458
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Skriver förslagsfil %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "Skriver förslagsfil %s..."
#: ../spell.c:7510 ../spell.c:7730
#, c-format
@@ -4085,8 +4085,8 @@ msgstr "Varning: både sammansättning och NOBREAK specifierad"
#: ../spell.c:7723
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Skriver stavningsfil %s ..."
+msgid "Writing spell file %s..."
+msgstr "Skriver stavningsfil %s..."
#: ../spell.c:7728
msgid "Done!"
@@ -4742,11 +4742,6 @@ msgstr "E900: Ogiltigt jobb-id"
msgid "E901: Job table is full"
msgstr "E901: Jobbtabellen är full"
-#: ../globals.h:1008
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr "E902: \"%s\" är inte körbar"
-
#: ../globals.h:1009
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -5680,7 +5675,7 @@ msgstr "-q [felfil] redigera fil med första fel"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
diff --git a/src/nvim/po/uk.cp1251.po b/src/nvim/po/uk.cp1251.po
deleted file mode 100644
index 2c6f3423ae..0000000000
--- a/src/nvim/po/uk.cp1251.po
+++ /dev/null
@@ -1,8388 +0,0 @@
-#
-# Ukrainian Vim translation [uk]
-#
-# Copyright (C) 2001 Bohdan Vlasyuk <bohdan@vstu.edu.ua>
-# Bohdan donated this work to be distributed with Vim under the Vim license.
-#
-# Thanks to:
-# Dmytro Kovalov <dmytro.kovalov@nssmb.com> for useful suggestions
-# Dmytro O. Redchuk <dor@kiev-online.net> for viminfo bug
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: vim 7.4\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2010-06-18 21:53+0300\n"
-"Last-Translator: Àíàòîë³é Ñàõí³ê <sakhnik@gmail.com>\n"
-"Language-Team: Bohdan Vlasyuk <bohdan@vstu.edu.ua>\n"
-"Language: uk\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=cp1251\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "íå âäàëîñÿ îòðèìàòè çíà÷åííÿ îïö³¿"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "âíóòð³øíÿ ïîìèëêà: íåâ³äîìèé òèï îïö³¿"
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[Ñïèñîê ì³ñöü]"
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[Ñïèñîê âèïðàâëåíü]"
-
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr "E855: Àâòîêîìàíäè ïðèçâåëè äî ñêàñóâàííÿ êîìàíäè"
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: Íåìຠìîæëèâîñò³ ðîçì³ñòèòè õî÷ îäèí áóôåð, çàâåðøåííÿ ðîáîòè..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: Íåìຠìîæëèâîñò³ ðîçì³ñòèòè áóôåð, áóäå âèêîðèñòàíî ³íøèé..."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: Æîäåí ç áóôåð³â íå áóâ âèâàíòàæåíèé"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: Æîäåí ç áóôåð³â íå çíèùåíî"
-
-#: ../buffer.c:767
-msgid "E517: No buffers were wiped out"
-msgstr "E517: Æîäåí ç áóôåð³â íå âèòåðòî"
-
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "Âèâàíòàæåíî îäèí áóôåð"
-
-#: ../buffer.c:774
-#, c-format
-msgid "%d buffers unloaded"
-msgstr "Âèâàíòàæåíî %d áóôåðè(³â)"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "Çíèùåíî îäèí áóôåð"
-
-#: ../buffer.c:779
-#, c-format
-msgid "%d buffers deleted"
-msgstr "Çíèùåíî %d áóôåðè(³â)"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "Âèòåðòî îäèí áóôåð"
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "Âèòåðòî %d áóôåðè(³â)"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: Íå ìîæó âèâàíòàæèòè îñòàíí³é áóôåð"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: Æîäåí áóôåð íå çì³íåíî"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-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
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: Öå âæå îñòàíí³é áóôåð"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: Öå âæå íàéïåðøèé áóôåð"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: Áóôåð %<PRId64> ìຠçì³íè (! ùîá íå çâàæàòè)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: Îáåðåæíî: Ñïèñîê íàçâ ôàéë³â ïåðåïîâíåíî"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: Áóôåð %<PRId64> íå çíàéäåíî"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: Çíàéäåíî ê³ëüêà çá³ã³â ç %s"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: Íå çíàéäåíî áóôåð, ñõîæèé íà %s"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "ðÿäîê %<PRId64>"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: Áóôåð ç òàêîþ íàçâîþ âæå ³ñíóº"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [Çì³íåíî]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[Íå ðåäàãîâàíî]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[Íîâèé ôàéë]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[Ïîìèëêè ÷èòàííÿ]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[RO]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-msgid "[readonly]"
-msgstr "[ëèøå ÷èòàòè]"
-
-#: ../buffer.c:2524
-#, c-format
-msgid "1 line --%d%%--"
-msgstr "îäèí ðÿäîê --%d%%--"
-
-#: ../buffer.c:2526
-#, c-format
-msgid "%<PRId64> lines --%d%%--"
-msgstr "%<PRId64> ðÿäêè(³â) --%d%%--"
-
-#: ../buffer.c:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "ðÿäîê %<PRId64> ç %<PRId64> --%d%%-- êîëîíêà "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-msgid "[No Name]"
-msgstr "[Áåç íàçâè]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "äîïîìîãà"
-
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[Äîïîìîãà]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[Ïåðåãëÿä]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "Óñå"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "Çíèçó"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "Âãîð³"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# Ñïèñîê áóôåð³â:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr "[Ç íóëÿ]"
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- Ïîçíà÷êè ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "Ïîçíà÷êè äëÿ %s:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ðÿäîê=%<PRId64> id=%d íàçâà=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: Ïðîïóùåíî äâîêðàïêó"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: Íåïðàâèëüíèé ðåæèì"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: Ïîòð³áíà öèôðà"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: Íåïðàâèëüíèé â³äñîòîê"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: Íå ìîæíà ïîð³âíþâàòè ïîíàä %<PRId64> áóôåðè(³â)"
-
-#: ../diff.c:753
-msgid "E810: Cannot read or write temp files"
-msgstr "E810: Íå ìîæíà ÷èòàòè ÷è çàïèñóâàòè òèì÷àñîâ³ ôàéëè"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: Íå âäàëîñÿ ñòâîðèòè ïîð³âíÿííÿ"
-
-#: ../diff.c:966
-msgid "E816: Cannot read patch output"
-msgstr "E816: Íå âäàëîñÿ ïðî÷èòàòè ðåçóëüòàò patch"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: Íå âäàëîñÿ ïðî÷èòàòè ðåçóëüòàò diff"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: Öåé áóôåð íå â ðåæèì³ ïîð³âíÿííÿ"
-
-#: ../diff.c:2100
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E793: Íåìຠá³ëüøå ìîäèô³êîâíèõ áóôåð³â â ðåæèì³ ïîð³âíÿííÿ"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: Íåìຠ³íøèõ áóôåð³â â ðåæèì³ ïîð³âíÿííÿ"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr ""
-"E101: Ïîíàä äâà áóôåðè ó ðåæèì³ ïîð³âíÿííÿ, íå çðîçóì³ëî, êîòðèé ³ç íèõ "
-"âèêîðèñòàòè"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: Íå âäàëîñÿ çíàéòè áóôåð «%s»"
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: Áóôåð «%s» íå â ðåæèì³ ïîð³âíÿííÿ"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr "E787: Áóôåð íåñïîä³âàíî çì³íèâñÿ"
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: Ó äèãðàôàõ íå ìîæå ì³ñòèòèñÿ escape"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: Íå çíàéäåíî ôàéë ðîçêëàäêè"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: :loadkeymap âèêîðèñòàíî íå ó ôàéë³ êîìàíä"
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr "E791: Åëåìåíò ðîçêëàäêè ïîðîæí³é"
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " Äîïîâíåííÿ êëþ÷îâèõ ñë³â (^N^P)"
-
-#. 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)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " Äîïîâíåííÿ óñüîãî ðÿäêà (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " Äîïîâíåííÿ íàçâè ôàéëó (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " Äîïîâíåííÿ òå´³â (^]^N^P)"
-
-#: ../edit.c:88
-msgid " Path pattern completion (^N^P)"
-msgstr " Äîïîâíåííÿ øëÿõó çà çðàçêîì (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " Äîïîâíåííÿ âèçíà÷åííÿ (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Äîïîâíåííÿ ç³ ñëîâíèêà (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " Äîïîâíåííÿ ç òåçàóðóñó (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " Äîïîâíåííÿ êîìàíä (^V^N^P)"
-
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr " Êîðèñòóâàöüêå äîïîâíåííÿ (^U^N^P)"
-
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " Êì³òëèâå äîïîâíåííÿ (^O^N^P)"
-
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr " Îðôîãðàô³÷íà ï³äêàçêà (s^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " Äîïîâíåííÿ ì³ñöåâèõ êëþ÷îâèõ ñë³â (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "Òðàïèâñÿ ê³íåöü ïàðàãðàôà"
-
-# msgstr "E443: "
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr "E839: Ôóíêö³ÿ äîïîâíåííÿ çì³íèëà â³êíî"
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr "E840: Ôóíêö³ÿ äîïîâíåííÿ çíèùèëà òåêñò"
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "Îïö³ÿ 'dictionary' ïîðîæíÿ"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "Îïö³ÿ 'thesaurus' ïîðîæíÿ"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "Ñêàíóºòüñÿ ñëîâíèê: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (âñòàâêà) Ïðîãîðíóòè (^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (çàì³íà) Ïðîãîðíóòè (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "Ïîøóê ó: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "Ïîøóê ñåðåä òå´³â."
-
-#: ../edit.c:4519
-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.
-#.
-#: ../edit.c:4562
-msgid "-- Searching..."
-msgstr "-- Ïîøóê..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "Ïî÷àòêîâèé âàð³àíò"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "Ñëîâî ç ³íøîãî ðÿäêà"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "ªäèíèé çá³ã"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "çá³ã %d ç %d"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "çá³ã %d"
-
-# msgstr "E17: "
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: Íåî÷³êóâàí³ ñèìâîëè ó :let"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: ²íäåêñ ñïèñêó ïîçà ìåæàìè: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Íåâèçíà÷åíà çì³ííà: %s"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: Áðàêóº ']'"
-
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: Àðãóìåíò ó %s ìຠáóòè ñïèñêîì"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: Àðãóìåíò ó %s ìຠáóòè ñïèñêîì ÷è ñëîâíèêîì"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Êëþ÷ ñëîâíèêà íå ìîæå áóòè ïîðîæí³ì"
-
-# msgstr "E396: "
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: Ïîòð³áåí ñïèñîê"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: Ïîòð³áåí ñëîâíèê"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: Çàáàãàòî àðãóìåíò³â äëÿ ôóíêö³¿: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Íåìຠòàêîãî êëþ÷à ó ñëîâíèêó: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: Ôóíêö³ÿ %s óæå ³ñíóº, ! ùîá çàì³íèòè"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Çàïèñ ó ñëîâíèêó âæå ³ñíóº"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: Òðåáà ïîñèëàííÿ íà ôóíêö³þ"
-
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: Íå ìîæíà âèêîðèñòàòè [:] ç³ ñëîâíèêîì"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: Íåïðàâèëüíèé òèï çì³ííî¿ äëÿ %s="
-
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: Íåâ³äîìà ôóíêö³ÿ: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: Íåïðèïóñòèìà íàçâà çì³ííî¿: %s"
-
-# msgstr "E373: "
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: Float âæèòî ÿê String"
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: Ö³ëåé ìåíøå, í³æ åëåìåíò³â ñïèñêó"
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: Ö³ëåé á³ëüøå, í³æ åëåìåíò³â ñïèñêó"
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "Äðóãà ; ó ñïèñêó çì³ííèõ"
-
-# msgstr "E235: "
-#: ../eval.c:2078
-#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: Íå ìîæíà ïåðåðàõóâàòè çì³íí³ ó %s"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: ²íäåêñíèé äîñòóï ìîæå áóòè ò³ëüêè äî ñïèñêó ÷è ñëîâíèêà"
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:] ìຠáóòè îñòàííüîþ"
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:] âèìàãຠñïèñîê"
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: Ñïèñîê ìຠá³ëüøå åëåìåíò³â, í³æ ö³ëü"
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: Ñïèñîê ìຠíåäîñòàòíüî åëåìåíò³â"
-
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: Ïðîïóùåíî «in» ï³ñëÿ :for"
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: Ïðîïóùåíî äóæêè: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: Çì³ííî¿ íåìàº: «%s»"
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: Çì³ííà ìຠçàáàãàòî âêëàäåíü ùîá áóòè çà-/â³äêðèòîþ."
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: Áðàêóº ':' ï³ñëÿ '?'"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: Ñïèñîê ìîæíà ïîð³âíÿòè ò³ëüêè ç³ ñïèñêîì"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: Íåêîðåêòíà îïåðàö³ÿ íàä ñïèñêîì"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: Ñëîâíèê ìîæíà ïîð³âíÿòè ò³ëüêè ³ç ñëîâíèêîì"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: Íåêîðåêòíà îïåðàö³ÿ íàä ñëîâíèêîì"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Ôóíêö³þ ìîæíà ïîð³âíÿòè ò³ëüêè ç ôóíêö³ºþ"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: Íåêîðåêòíà îïåðàö³ÿ íàä ôóíêö³ºþ"
-
-#: ../eval.c:4277
-msgid "E804: Cannot use '%' with Float"
-msgstr "E804: Íå ìîæíà âèêîíàòè '%' íàä Float"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: Ïðîïóùåíî ')'"
-
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: Ôóíêö³ÿ íå ìຠ³íäåêñàö³¿"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: Áðàêóº íàçâè îïö³¿: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: Íåâ³äîìà îïö³ÿ: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: Áðàêóº ëàïêè: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: Áðàêóº ëàïêè: %s"
-
-# msgstr "E404: "
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: Áðàêóº êîìè ó ñïèñêó: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: Íåìຠê³íö³âêè ñïèñêó ']': %s"
-
-# msgstr "E235: "
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Áðàêóº äâîêðàïêè ó ñëîâíèêó: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Ïîâòîðåííÿ êëþ÷à â ñëîâíèêó: «%s»"
-
-# msgstr "E235: "
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Áðàêóº êîìè ó ñëîâíèêó: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Íåìຠê³íö³âêè ñëîâíèêà '}': %s"
-
-# msgstr "E21: "
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: Ó çì³íí³é çàáàãàòî âêëàäåíü ùîá ¿¿ ïîêàçàòè"
-
-#: ../eval.c:7188
-#, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E740: Çàáàãàòî àðãóìåíò³â äëÿ ôóíêö³¿ %s"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: Íåïðàâèëüí³ àðãóìåíòè ôóíêö³¿ %s"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: Íåâ³äîìà ôóíêö³ÿ: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: Çàìàëî àðãóìåíò³â äëÿ ôóíêö³¿ %s"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> âèêîðèñòîâóºòüñÿ íå ó êîíòåêñò³ ñêðèïòó: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E725: Âèêëèê dict-ôóíêö³¿ áåç ñëîâíèêà: %s"
-
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Òðåáà âêàçàòè Number ÷è Float"
-
-# msgstr "E14: "
-#: ../eval.c:7503
-msgid "add() argument"
-msgstr "àðãóìåíò add()"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: Çàáàãàòî àðãóìåíò³â"
-
-# msgstr "E327: "
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() ìîæíà âæèâàòè ò³ëüêè â ðåæèì³ âñòàâêè"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "&O:Ãàðàçä"
-
-# msgstr "E226: "
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Êëþ÷ âæå ³ñíóº: %s"
-
-# msgstr "E14: "
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr "àðãóìåíò extend()"
-
-# msgstr "E14: "
-#: ../eval.c:8915
-msgid "map() argument"
-msgstr "àðãóìåíò map()"
-
-# msgstr "E14: "
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr "àðãóìåíò filter()"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld ðÿäê³â: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: Íåâ³äîìà ôóíêö³ÿ: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "Âèêëèêè äî inputrestore() ÷àñò³øå, í³æ äî inputsave()"
-
-# msgstr "E14: "
-#: ../eval.c:10771
-msgid "insert() argument"
-msgstr "àðãóìåíò insert()"
-
-# msgstr "E406: "
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: ²íòåðâàë íå äîçâîëåíî"
-
-# msgstr "E177: "
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: Íåêîðåêòíèé òèï äëÿ len()"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: Êðîê íóëüîâèé"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: Ïî÷àòîê çà ê³íöåì"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<í³÷îãî>"
-
-# msgstr "E14: "
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr "àðãóìåíò remove()"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: Çàáàãàòî ñèìâîëüíèõ ïîñèëàíü (öèêë?)"
-
-# msgstr "E14: "
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr "àðãóìåíò reverse()"
-
-# msgstr "E14: "
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr "àðãóìåíò sort()"
-
-# msgstr "E14: "
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "àðãóìåíò add()"
-
-# msgstr "E364: "
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Ïîìèëêà ó ôóíêö³¿ ïîð³âíÿííÿ"
-
-# msgstr "E364: "
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Ïîìèëêà ó ôóíêö³¿ ïîð³âíÿííÿ"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(Íåìîæëèâî)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Íå âäàëîñÿ çàïèñàòè òèì÷àñîâèé ôàéë"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Float âæèòî ÿê Number"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Funcref âæèòî ÿê Number"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: List âæèòî ÿê Number"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Dictionary âæèòî ÿê Number"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: Funcref âæèòî ÿê String"
-
-# msgstr "E373: "
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: List âæèòî ÿê String"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Dictionary âæèòî ÿê String"
-
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Íåïðàâèëüíèé òèï çì³ííî¿: %s"
-
-#: ../eval.c:16705
-#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Íå ìîæíà çíèùèòè çì³ííó %s"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Íàçâà çì³ííî¿ Funcref ìຠïî÷èíàòèñÿ ç âåëèêî¿ ë³òåðè: %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: Íàçâà çì³ííî¿ ñï³âïàäàº ç ³ñíóþ÷îþ ôóíêö³ºþ: %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: Çíà÷åííÿ çàõèùåíå: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Íåâ³äîìî"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Íå ìîæíà çì³íèòè çíà÷åííÿ %s"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: Çì³ííà âêëàäåíà çàíàäòî ãëèáîêî ùîá çðîáèòè ¿¿ êîï³þ"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: Íåâèçíà÷åíà ôóíêö³ÿ: %s"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: Áðàêóº '(': %s"
-
-#: ../eval.c:17293
-msgid "E862: Cannot use g: here"
-msgstr "E862: Òóò íå ìîæíà âèêîðèñòàòè g:"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: Íåäîçâîëåíèé àðãóìåíò: %s"
-
-#: ../eval.c:17323
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Íàçâà àðãóìåíòó ïîâòîðþºòüñÿ: %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: Áðàêóº :endfunction"
-
-#: ../eval.c:17537
-#, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E707: Íàçâà ôóíêö³¿ ñï³âïàäàº ç³ çì³ííîþ: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: Íå âäàëîñÿ ïåðåâèçíà÷èòè ôóíêö³þ %s: âîíà âèêîðèñòîâóºòüñÿ"
-
-#: ../eval.c:17604
-#, 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.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Íàçâà ôóíêö³¿ ìຠïî÷èíàòèñÿ ç âåëèêî¿ ë³òåðè àáî ì³ñòèòè äâîêðàïêó: %s"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr ""
-"E128: Íàçâà ôóíêö³¿ ìຠïî÷èíàòèñÿ ç âåëèêî¿ ë³òåðè àáî ì³ñòèòè äâîêðàïêó: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: Íå âäàëîñÿ çíèùèòè ôóíêö³þ %s: Âîíà âèêîðèñòîâóºòüñÿ"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: Ãëèáèíà âèêëèê³â ôóíêö³¿ ïåðåâèùóº 'maxfuncdepth'"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "âèêëèêàºòüñÿ %s"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ïðèïèíåíî"
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ïîâåðòຠ#%<PRId64>"
-
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%s ïîâåðòຠ%s"
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "ïðîäîâæåííÿ â %s"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return ïîçà ìåæàìè ôóíêö³¿"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# ãëîáàëüí³ çì³íí³:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\tÂîñòàííº çì³íåíà ó "
-
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Æîäíîãî ñòàðîãî ôàéëó"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, ø³ñò %02x, â³ñ %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, ø³ñò %04x, â³ñ %o"
-
-#: ../ex_cmds.c:146
-#, 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:747
-msgid "1 line moved"
-msgstr "Ïåðåì³ùåíî îäèí ðÿäîê"
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "Ïåðåì³ùåíî %<PRId64> ðÿäêè(³â)"
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "³äô³ëüòðîâàíî %<PRId64> ðÿäêè(³â)"
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: Àâòîêîìàíäè *Filter* íå ïîâèíí³ çì³íþâàòè ïîòî÷íèé áóôåð"
-
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[Çì³íè íå çàïèñàíî]\n"
-
-#: ../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
-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
-#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "Çàïèñóºòüñÿ ôàéë viminfo «%s»"
-
-#. Write the info:
-#: ../ex_cmds.c:1720
-#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# Öåé ôàéë àâòîìàòè÷íî ñòâîðåíèé Vim %s.\n"
-
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# Ìîæåòå ðåäàãóâàòè, àëå ÎÁÅÐÅÆÍÎ!\n"
-"\n"
-
-#: ../ex_cmds.c:1723
-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
-msgid "Write partial file?"
-msgstr "Çàïèñàòè ÷àñòèíó ôàéëó?"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: Âèêîðèñòàéòå ! äëÿ çàïèñó ÷àñòèíè áóôåðà"
-
-#: ../ex_cmds.c:2281
-#, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "Ïåðåïèñàòè ³ñíóþ÷èé ôàéë «%s»?"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr "Ôàéë îáì³íó «%s» ³ñíóº, ïåðåçàïèñàòè?"
-
-#: ../ex_cmds.c:2326
-#, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E768: Ôàéë îáì³íó ³ñíóº: %s (:silent! ïåðåâàæóº)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: Íåìຠâõ³äíîãî ôàéëó äëÿ áóôåðà %<PRId64>"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: Ôàéë íå çàïèñàíî: çàïèñ çàáîðîíåíî îïö³ºþ 'write'"
-
-#: ../ex_cmds.c:2434
-#, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"Äëÿ «%s» âñòàíîâëåíî 'readonly'.\n"
-"Áàæàºòå âñå îäíî ïðîäîâæèòè çàïèñ?"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-"Ôàéë «%s» äîçâîëåíî ò³ëüêè ÷èòàòè.\n"
-"Ïðîòå, ìîæëèâî, éîãî ìîæíà çàïèñàòè.\n"
-"Õî÷åòå ñïðîáóâàòè?"
-
-#: ../ex_cmds.c:2451
-#, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "E505: «%s» ò³ëüêè äëÿ ÷èòàííÿ (! ùîá íå çâàæàòè)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: Àâòîêîìàíäè íåñïîä³âàíî çíèùèëè íîâèé áóôåð %s"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: íå÷èñëîâèé àðãóìåíò äëÿ :z"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: Ó rvim íå äîçâîëåí³ êîìàíäè îáîëîíêè"
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: Ðåãóëÿðí³ âèðàçè íå ìîæíà ðîçä³ëÿòè ë³òåðàìè"
-
-#: ../ex_cmds.c:3964
-#, 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
-msgid "(Interrupted) "
-msgstr "(Ïåðåðâàíî) "
-
-# msgstr "E31: "
-#: ../ex_cmds.c:4384
-msgid "1 match"
-msgstr "Îäèí çá³ã"
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "Îäíà çàì³íà"
-
-#: ../ex_cmds.c:4387
-#, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> çá³ãè(³â)"
-
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> çàì³í(è)"
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr " â îäíîìó ðÿäêó"
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr " â %<PRId64> ðÿäêàõ"
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global íå ìîæíà âæèâàòè ðåêóðñèâíî"
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: Ó global áðàêóº çðàçêà"
-
-#: ../ex_cmds.c:4508
-#, c-format
-msgid "Pattern found in every line: %s"
-msgstr "Çðàçîê çíàéäåíî ó êîæíîìó ðÿäêó: %s"
-
-#: ../ex_cmds.c:4510
-#, c-format
-msgid "Pattern not found: %s"
-msgstr "Çðàçîê íå çíàéäåíî: %s"
-
-#: ../ex_cmds.c:4587
-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: Ïîâòîðåííÿ òå´ó «%s» ó ôàéë³ %s/%s"
-
-#: ../ex_cmds.c:5687
-#, c-format
-msgid "E160: Unknown sign command: %s"
-msgstr "E160: Íåâ³äîìà êîìàíäà íàäïèñó: %s"
-
-#: ../ex_cmds.c:5704
-msgid "E156: Missing sign name"
-msgstr "E156: Ïðîïóùåíî íàçâó íàäïèñó"
-
-#: ../ex_cmds.c:5746
-msgid "E612: Too many signs defined"
-msgstr "E612: Âèçíà÷åíî çàáàãàòî íàäïèñ³â"
-
-#: ../ex_cmds.c:5813
-#, c-format
-msgid "E239: Invalid sign text: %s"
-msgstr "E239: Íåêîðåêòíèé íàäïèñ: %s"
-
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
-#, c-format
-msgid "E155: Unknown sign: %s"
-msgstr "E155: Íåâ³äîìèé íàäïèñ: %s"
-
-#: ../ex_cmds.c:5877
-msgid "E159: Missing sign number"
-msgstr "E159: Ïðîïóùåíî íîìåð íàäïèñó"
-
-#: ../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: Íåïðàâèëüíèé 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"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "Òî÷êà çóïèíêè â «%s%s» ðÿäîê %<PRId64>"
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: Òî÷êó çóïèíêè íå çíàéäåíî: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "Íå âèçíà÷åíî æîäíî¿ òî÷êè çóïèíêè"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s ðÿäîê %<PRId64>"
-
-#: ../ex_cmds2.c:942
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: Ñïî÷àòêó çðîá³òü «:profile start {ôàéë}»"
-
-#: ../ex_cmds2.c:1269
-#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "Çáåðåãòè çì³íè â «%s»?"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "Íåíàçâàíèé"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: Áóôåð «%s» ìຠíåçáåðåæåí³ çì³íè"
-
-#: ../ex_cmds2.c:1480
-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
-#, c-format
-msgid "E666: compiler not supported: %s"
-msgstr "E666: Êîìï³ëÿòîð íå ï³äòðèìóºòüñÿ: %s"
-
-# msgstr "E195: "
-#: ../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"
-
-# msgstr "E14: "
-#: ../ex_cmds2.c:2767
-msgid "--cmd argument"
-msgstr "--cmd àðãóìåíò"
-
-# msgstr "E14: "
-#: ../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_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: :scriptencoding âèêîðèñòàíî ïîçà âèêîíóâàíèì ôàéëîì"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: :finish âèêîðèñòàíî ïîçà âèêîíóâàíèì ôàéëîì"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "Ìîâà (%s): «%s»"
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: Íå âäàëîñÿ âñòàíîâèòè ìîâó «%s»"
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "Ðåæèì Ex. Äëÿ ïîâåðíåííÿ äî íîðìàëüíîãî ðåæèìó âèêîíàéòå «visual»"
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: ʳíåöü ôàéëó"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: Êîìàíäà çàíàäòî ðåêóðñèâíà"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: Âèíÿòêîâà ñèòóàö³ÿ íå îáðîáëåíà: %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "ʳíåöü âèêîíóâàíîãî ôàéëó"
-
-#: ../ex_docmd.c:1086
-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:1729
-msgid "E493: Backwards range given"
-msgstr "E493: ²íòåðâàë çàäàíî íàâèâîð³ò"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "²íòåðâàë çàäàíî íàâèâîð³ò, ùîá ïîì³íÿòè ì³ñöÿìè — ÃÀÐÀÇÄ"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: Ñïðîáóéòå w àáî w>>"
-
-#: ../ex_docmd.c:3454
-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 "Çàëèøèëîñÿ â³äðåäàãóâàòè ùå îäèí ôàéë. Âñå îäíî âèéòè?"
-
-#: ../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: Çàëèøèëîñÿ â³äðåäàãóâàòè ùå îäèí ôàéë"
-
-#: ../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: ˳÷èëüíèê íå ìîæå áóòè âêàçàíî äâ³÷³"
-
-# msgstr "E177: "
-#: ../ex_docmd.c:4603
-msgid "E178: Invalid default value for count"
-msgstr "E178: Íåïðàâèëüíå ïî÷àòêîâå çíà÷åííÿ ë³÷èëüíèêà"
-
-# msgstr "E178: "
-#: ../ex_docmd.c:4625
-msgid "E179: argument required for -complete"
-msgstr "E179: äëÿ -complete ïîòð³áíèé àðãóìåíò"
-
-# msgstr "E180: "
-#: ../ex_docmd.c:4635
-#, c-format
-msgid "E181: Invalid attribute: %s"
-msgstr "E181: Íåïðàâèëüíèé àòðèáóò: %s"
-
-# msgstr "E181: "
-#: ../ex_docmd.c:4678
-msgid "E182: Invalid command name"
-msgstr "E182: Íåïðàâèëüíà íàçâà êîìàíäè"
-
-# msgstr "E182: "
-#: ../ex_docmd.c:4691
-msgid "E183: User defined commands must start with an uppercase letter"
-msgstr "E183: Êîìàíäè êîðèñòóâà÷à ïîâèíí³ ïî÷èíàòèñÿ ç âåëèêî¿ ë³òåðè"
-
-#: ../ex_docmd.c:4696
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr ""
-"E841: Çàðåçåðâîâàíà íàçâà, íå ìîæíà âèêîðèñòàòè äëÿ êîðèñòóâàöüêî¿ êîìàíäè"
-
-# msgstr "E183: "
-#: ../ex_docmd.c:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: Êîìàíäó êîðèñòóâà÷à íå çíàéäåíî: %s"
-
-# msgstr "E179: "
-#: ../ex_docmd.c:5219
-#, 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: Àðãóìåíò äîçâîëåíèé ò³ëüêè äëÿ êîðèñòóâàöüêîãî äîïîâíåííÿ"
-
-#: ../ex_docmd.c:5231
-msgid "E467: Custom completion requires a function argument"
-msgstr "E467: Êîðèñòóâàöüêå äîïîâíåííÿ âèìàãຠàðãóìåíò-ôóíêö³þ"
-
-# msgstr "E184: "
-#: ../ex_docmd.c:5257
-#, c-format
-msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: Íå âäàëîñÿ çíàéòè ñõåìó êîëüîð³â «%s»"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "³òàííÿ, êîðèñòóâà÷ó Vim!"
-
-# msgstr "E443: "
-#: ../ex_docmd.c:5431
-msgid "E784: Cannot close last tab page"
-msgstr "E784: Íå ìîæíà çàêðèòè îñòàííþ âêëàäêó"
-
-# msgstr "E444: "
-#: ../ex_docmd.c:5462
-msgid "Already only one tab page"
-msgstr "Âæå é òàê ëèøå îäíà âêëàäêà"
-
-#: ../ex_docmd.c:6004
-#, c-format
-msgid "Tab page %d"
-msgstr "Âêëàäêà %d"
-
-#: ../ex_docmd.c:6295
-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
-msgid "E186: No previous directory"
-msgstr "E186: Öå âæå íàéïåðøèé êàòàëîã"
-
-# msgstr "E186: "
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: Íåâ³äîìî"
-
-#: ../ex_docmd.c:6610
-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
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: Ôàéë «%s» ³ñíóº (! ùîá íå çâàæàòè)"
-
-# msgstr "E189: "
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: Íå âäàëîñÿ â³äêðèòè «%s» äëÿ çàïèñó"
-
-# msgstr "E190: "
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: Àðãóìåíò ìຠáóòè ë³òåðîþ, ` àáî '"
-
-# msgstr "E191: "
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: Çàáàãàòî âêëàäåíèõ :normal"
-
-# msgstr "E193: "
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: Íåìຠíàçâè âòîðèííîãî ôàéëó äëÿ çàì³íè '#'"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: Íåìຠíàçâè ôàéëó àâòîêîìàíäè äëÿ çàì³íè «<afile>»"
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: Íåìຠíîìåðà áóôåðà àâòîêîìàíäè äëÿ çàì³íè «<abuf>»"
-
-#: ../ex_docmd.c:7861
-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: Íåìຠíàçâè ôàéëó :source äëÿ çàì³íè «<sfile>»"
-
-#: ../ex_docmd.c:7876
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E842: íåìຠíîìåðà ðÿäêà, ùîá âèêîðèñòàòè ç «<sfile>»"
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: Íàçâà ôàéëó äëÿ '%' ÷è '#' ïîðîæíÿ, ïðàöþº ëèøå ç «:p:h»"
-
-#: ../ex_docmd.c:7905
-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_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: Íå ìîæíà âèêèäàòè (:throw) âèíÿòêè ç ïðåô³êñîì 'Vim'"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "Âèíÿòêîâà ñèòóàö³ÿ: %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "Âèíÿòîê çàê³í÷åíî: %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "Âèíÿòîê ñêèíóòî: %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, ðÿäîê %<PRId64>"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "Ñï³éìàíî âèíÿòêîâó ñèòóàö³þ: %s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr "Î÷³êóºòüñÿ %s"
-
-#: ../ex_eval.c:679
-#, c-format
-msgid "%s resumed"
-msgstr "³äíîâëåíî %s"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr "Ñêèíóòî %s"
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "Âèíÿòîê"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "Ïîìèëêà, ïåðåðâàíî"
-
-# msgstr "E231: "
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "Ïîìèëêà"
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "Ïåðåðâàíî"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: Çàíàäòî áàãàòî âêëàäåíèõ :if"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :endif áåç :if"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :else áåç :if"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :elseif áåç :if"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: Íå îäíå :else"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :elseif ï³ñëÿ :else"
-
-#: ../ex_eval.c:941
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: Çàáàãàòî âêëàäåíèõ :while/:for"
-
-#: ../ex_eval.c:1028
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :continue áåç :while ÷è :for"
-
-#: ../ex_eval.c:1061
-msgid "E587: :break without :while or :for"
-msgstr "E587: :break áåç :while ÷è :for"
-
-#: ../ex_eval.c:1102
-msgid "E732: Using :endfor with :while"
-msgstr "E732: Âæèòî :endfor ³ç :while"
-
-#: ../ex_eval.c:1104
-msgid "E733: Using :endwhile with :for"
-msgstr "E733: Âæèòî :endwhile ³ç :for"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: Çàáàãàòî âêëàäåíèõ :try"
-
-#: ../ex_eval.c:1317
-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
-msgid "E604: :catch after :finally"
-msgstr "E604: :catch ï³ñëÿ :finally"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :finally áåç :try"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: Íå îäíå :finally"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :entry áåç :try"
-
-#: ../ex_eval.c:2026
-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
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E811: Çàðàç íå ìîæíà çì³íþâàòè ³íôîðìàö³þ áóôåðà"
-
-# msgstr "E197: "
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "íàçâà òå´ó"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " òèï ôàéëó\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "Îïö³ÿ 'history' ïîðîæíÿ"
-
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Ïîïåðåäí³ %s (â³ä íàéíîâ³øèõ):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "êîìàíäè"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "øóêàí³ ðÿäêè"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "âèðàçè"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "ââåäåí³ ðÿäêè"
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar ïîçà ìåæàìè êîìàíäè"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: Àêòèâíå â³êíî àáî áóôåð áóëî çíèùåíî"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr "E854: øëÿõ çàíàäòî äîâãèé äëÿ äîïîâíåííÿ"
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr ""
-"E343: Íåêîðåêòíèé øëÿõ: `**[÷èñëî]' ïîâèííå áóòè íàïðèê³íö³ øëÿõó àáî ïåðåä "
-"'%s'."
-
-# msgstr "E343: "
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: Íå âäàëîñÿ çíàéòè êàòàëîã «%s» ó cdpath"
-
-# msgstr "E344: "
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: Íå âäàëîñÿ çíàéòè ôàéë «%s» ó path"
-
-# msgstr "E345: "
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: Ó cdpath íåìຠá³ëüøå êàòàëîãó «%s»"
-
-# msgstr "E346: "
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: Ó øëÿõó ïîøóêó á³ëüøå íåìຠôàéë³â «%s»"
-
-#: ../fileio.c:137
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E812: Àâòîêîìàíäè çì³íèëè áóôåð ÷è éîãî íàçâó"
-
-# msgstr "E199: "
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "Íåäîçâîëåíà íàçâà ôàéëó"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "êàòàëîã"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "íå ôàéë"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[Íîâèé ôàéë]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr "[Íîâèé êàòàëîã]"
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr "[Ôàéë çàâåëèêèé]"
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[³äìîâëåíî]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200: Àâòîêîìàíäè *ReadPre óíåìîæëèâèëè ÷èòàííÿ ôàéëó"
-
-# msgstr "E200: "
-#: ../fileio.c:655
-msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: Àâòîêîìàíäè *ReadPre íå ïîâèíí³ çì³íþâàòè öåé áóôåð"
-
-# msgstr "E201: "
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: ×èòàºòüñÿ ç stdin...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202: Êîíâåðòàö³ÿ óíåìîæëèâèëà ÷èòàííÿ ôàéëó!"
-
-# msgstr "E202: "
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[êàíàë/ñîêåò]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[êàíàë]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[ñîêåò]"
-
-#. or character special
-#: ../fileio.c:1801
-msgid "[character special]"
-msgstr "[ñïåö. ñèìâîëüíèé]"
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[Áðàêóº CR]"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[Ðîçáèòî äîâã³ ðÿäêè]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[ÍÅ êîíâåðòîâàíî]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[êîíâåðòîâàíî]"
-
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[ÏÎÌÈËÊÀ ÊÎÍÂÅÐÒÀÖ²¯ ó ðÿäêó %<PRId64>]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[ÍÅÊÎÐÅÊÒÍÈÉ ÁÀÉÒ ó ðÿäêó %<PRId64>]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[ÏÎÌÈËÊÀ ×ÈÒÀÍÍß]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "Íå âäàëîñÿ ï³äøóêàòè òèì÷àñîâèé ôàéë äëÿ êîíâåðòàö³¿"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "Êîíâåðòàö³ÿ ç 'charconvert' íå âäàëàñÿ"
-
-#: ../fileio.c:2113
-msgid "can't read output of 'charconvert'"
-msgstr "íå âäàëîñÿ ïðî÷èòàòè âèâ³ä 'charconvert'"
-
-# msgstr "E217: "
-#: ../fileio.c:2437
-msgid "E676: No matching autocommands for acwrite buffer"
-msgstr "E676: Íåìຠâ³äïîâ³äíèõ àâòîêîìàíä"
-
-#: ../fileio.c:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr "E203: Àâòîêîìàíäà çíèùèëà àáî âèâàíòàæèëà áóôåð, ùî ìàâ áóòè çàïèñàíèé"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: Àâòîêîìàíäà íåñïîä³âàíèì ÷èíîì çì³íèëà ê³ëüê³ñòü ðÿäê³â"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "Íå ïðèäàòíèé äëÿ çàïèñó"
-
-#: ../fileio.c:2601
-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:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr "E509: Íå âäàëîñÿ ñòâîðèòè ðåçåðâíó êîï³þ (! ùîá íå çâàæàòè)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr "E510: Íå âäàëîñÿ çðîáèòè ðåçåðâíó êîï³þ (! ùîá íå çâàæàòè)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: Íå âäàëîñÿ ï³äøóêàòè òèì÷àñîâèé ôàéë äëÿ çàïèñó"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr "E213: Íå âäàëîñÿ ïåðåòâîðèòè (! ùîá çàïèñàòè áåç êîíâåðòàö³¿)"
-
-#: ../fileio.c:3169
-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: Íå âäàëîñÿ âèêîíàòè fsync"
-
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Íå âäàëîñÿ çàêðèòè"
-
-#: ../fileio.c:3436
-msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: Ïîìèëêà çàïèñó, êîíâåðòàö³ÿ íå âäàëàñÿ (ñêèíüòå 'fenc')"
-
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: Ïîìèëêà çàïèñó, êîíâåðòàö³ÿ íå âäàëàñÿ ó ðÿäêó %<PRId64> (ñêèíüòå "
-"'fenc')"
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: Ïîìèëêà çàïèñó (ñê³í÷èëîñü â³ëüíå ì³ñöå?)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr " ÏÎÌÈËÊÀ ÊÎÍÂÅÐÒÀÖ²¯"
-
-#: ../fileio.c:3509
-#, c-format
-msgid " in line %<PRId64>;"
-msgstr " ó ðÿäêó %<PRId64>;"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[Ïðèñòð³é]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[Íîâèé]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr "[ä]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " äîïèñàíèé"
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr "[ç]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " çàïèñàíèé"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Ëàòàííÿ: íå âäàëîñÿ çáåðåãòè îðèã³íàë"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: Ëàòàííÿ: íå âäàëîñÿ ñòâîðèòè îðèã³íàë"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: Íå âäàëîñÿ çíèùèòè ðåçåðâíèé ôàéë"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"ÇÀÑÒÅÐÅÆÅÍÍß: Îðèã³íàë, ìàáóòü, âòðà÷åíèé ÷è ïîøêîäæåíèé\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "Íå âèõîäüòå ç ðåäàêòîðà, äîêè ôàéë íå çàïèñàíî!"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[ôîðìàò dos]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[ôîðìàò mac]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[ôîðìàò unix]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "îäèí ðÿäîê, "
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> ðÿäê³â, "
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "îäèí ñèìâîë"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> ñèìâîë³â"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-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
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "ÇÀÑÒÅÐÅÆÅÍÍß: Ôàéë çì³íèâñÿ ç ÷àñó îñòàííüîãî ÷èòàííÿ!!!"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "Âè ñïðàâä³ õî÷åòå éîãî ïåðåïèñàòè??"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: Ïîìèëêà çàïèñó ó «%s»"
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: Ïîìèëêà çàêðèòòÿ «%s»"
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: Ïîìèëêà ÷èòàííÿ «%s»"
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: Àâòîêîìàíäà FileChangedShell çíèùèëà áóôåð"
-
-#: ../fileio.c:4894
-#, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Ôàéë «%s» á³ëüøå íå äîñÿæíèé"
-
-#: ../fileio.c:4906
-#, 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
-msgid "See \":help W12\" for more info."
-msgstr "Äèâ. «:help W12» äëÿ óòî÷íåííÿ."
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: Çàñòåðåæåííÿ: Ôàéë «%s» çì³íèâñÿ ï³ñëÿ ïî÷àòêó ðåäàãóâàííÿ"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "Äèâ. «:help W11» äëÿ óòî÷íåííÿ."
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr "W16: Çàñòåðåæåííÿ: Ðåæèì ôàéëó «%s» çì³íèâñÿ ï³ñëÿ ïî÷àòêó ðåäàãóâàííÿ"
-
-#: ../fileio.c:4915
-msgid "See \":help W16\" for more info."
-msgstr "Äèâ. «:help W16» äëÿ óòî÷íåííÿ."
-
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: Çàñòåðåæåííÿ: Ôàéë «%s» áóëî ñòâîðåíî ï³ñëÿ ïî÷àòêó ðåäàãóâàííÿ"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "Çàñòåðåæåííÿ"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"&O:Ãàðàçä\n"
-"&L:Çàâàíòàæèòè"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: Íå âäàëîñÿ ï³äãîòóâàòè «%s», ùîá ïåðå÷èòàòè"
-
-#: ../fileio.c:5078
-#, 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 <áóôåð=%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"
-
-# msgstr "E215: "
-#: ../fileio.c:5905
-#, c-format
-msgid "E216: No such event: %s"
-msgstr "E216: Íåìຠòàêî¿ ïî䳿: %s"
-
-# msgstr "E215: "
-#: ../fileio.c:5907
-#, c-format
-msgid "E216: No such group or event: %s"
-msgstr "E216: Íåìຠòàêî¿ ãðóïè ÷è ïî䳿: %s"
-
-# msgstr "E216: "
-#. Highlight title
-#: ../fileio.c:6090
-msgid ""
-"\n"
-"--- Auto-Commands ---"
-msgstr ""
-"\n"
-"--- Àâòîêîìàíäè ---"
-
-#: ../fileio.c:6293
-#, c-format
-msgid "E680: <buffer=%d>: invalid buffer number "
-msgstr "E680: <áóôåð=%d>: íåêîðåêòíèé íîìåð áóôåðà "
-
-#: ../fileio.c:6370
-msgid "E217: Can't execute autocommands for ALL events"
-msgstr "E217: Íå ìîæó âèêîíóâàòè àâòîêîìàíäè äëÿ ÓÑ²Õ ïîä³é"
-
-# msgstr "E217: "
-#: ../fileio.c:6393
-msgid "No matching autocommands"
-msgstr "Íåìຠâ³äïîâ³äíèõ àâòîêîìàíä"
-
-#: ../fileio.c:6831
-msgid "E218: autocommand nesting too deep"
-msgstr "E218: Çàáàãàòî âêëàäåíèõ àâòîêîìàíä"
-
-# msgstr "E218: "
-#: ../fileio.c:7143
-#, c-format
-msgid "%s Auto commands 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
-msgid "E219: Missing {."
-msgstr "E219: Áðàêóº {."
-
-# msgstr "E219: "
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: Áðàêóº }."
-
-# msgstr "E220: "
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: Çãîðòîê íå çíàéäåíî"
-
-# msgstr "E349: "
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: Íå âäàëîñÿ ñòâîðèòè çãîðòêó ìåòîäîì 'foldmethod'"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: Íå âäàëîñÿ çíèùèòè çãîðòêó ìåòîäîì 'foldmethod'"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+-- çãîðíóòî %3ld ðÿäê³â "
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: Äîäàòè äî áóôåðà ÷èòàííÿ"
-
-#: ../getchar.c:2040
-msgid "E223: recursive mapping"
-msgstr "E223: Çàì³íà ðåêóðñèâíà"
-
-# msgstr "E223: "
-#: ../getchar.c:2849
-#, c-format
-msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: Çàãàëüíå ñêîðî÷åííÿ äëÿ %s âæå ³ñíóº"
-
-# msgstr "E224: "
-#: ../getchar.c:2852
-#, c-format
-msgid "E225: global mapping already exists for %s"
-msgstr "E225: Çàãàëüíà çàì³íà äëÿ %s âæå ³ñíóº"
-
-# msgstr "E225: "
-#: ../getchar.c:2952
-#, c-format
-msgid "E226: abbreviation already exists for %s"
-msgstr "E226: Âæå º ñêîðî÷åííÿ äëÿ %s"
-
-# msgstr "E226: "
-#: ../getchar.c:2955
-#, c-format
-msgid "E227: mapping already exists for %s"
-msgstr "E227: Âæå º çàì³íà äëÿ %s"
-
-# msgstr "E227: "
-#: ../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: Íåïðèïóñòèìèé ðåæèì"
-
-# msgstr "E447: "
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-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
-msgid "E470: Command aborted"
-msgstr "E470: Êîìàíäó ïåðåðâàíî"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: Íåîáõ³äíî âêàçàòè àðãóìåíò"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: Çà \\ ìຠéòè /, ? àáî &"
-
-# msgstr "E10: "
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: Íåïðèïóñòèìî ó â³êí³ êîìàíä, <CR> âèêîíóº, CTRL-C âèõîäèòü"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr ""
-"E12: Êîìàíäà íå äîçâîëåíà ó exrc/vimrc ó ïîøóêó ïîòî÷íîãî êàòàëîãó ÷è òå´ó"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: Áðàêóº :endif"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: Áðàêóº :endtry"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: Áðàêóº :endwhile"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: Áðàêóº :endfor"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile áåç :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor áåç :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Ôàéë ³ñíóº (! ùîá íå çâàæàòè)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: Êîìàíäà íà âäàëàñü"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: Âíóòð³øíÿ ïîìèëêà"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "Ïåðåðâàíî"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: Íåïðàâèëüíà àäðåñà"
-
-# msgstr "E14: "
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: Íåêîðåêòíèé àðãóìåíò"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: Íåêîðåêòíèé àðãóìåíò: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: Íåïðàâèëüíèé âèðàç: %s"
-
-# msgstr "E15: "
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: Íåïðàâèëüí³ ìåæ³"
-
-# msgstr "E16: "
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: Íåêîðåêòíà êîìàíäà"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: «%s» — öå êàòàëîã"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Íåêîðåêòíèé ðîçì³ð çñóâó"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: Á³áë³îòå÷íèé âèêëèê äî «%s()» íå âäàâñÿ"
-
-# msgstr "E18: "
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: Ó ïîì³òêè íåêîðåêòíèé íîìåð ðÿäêà"
-
-# msgstr "E19: "
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: Ïîì³òêó íå âñòàíîâëåíî"
-
-# msgstr "E20: "
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: Çì³íè íå äîçâîëåí³: âèìêíåíî 'modifiable'"
-
-# msgstr "E21: "
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: Çàáàãàòî âêëàäåíèõ ñêðèïò³â"
-
-# msgstr "E22: "
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: Íåìຠâòîðèííîãî ôàéëó"
-
-# msgstr "E23: "
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: Òàêîãî ñêîðî÷åííÿ íåìàº"
-
-# msgstr "E24: "
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ! íå äîçâîëåíî"
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: Íå ìîæíà âèêîðèñòàòè GUI: Íå ââ³ìêíåíî ï³ä ÷àñ êîìï³ëÿö³¿"
-
-# msgstr "E25: "
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: Íåìຠòàêî¿ ãðóïè ï³äñâ³÷óâàííÿ: %s"
-
-# msgstr "E28: "
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: Òåêñò ùå íå áóëî äîäàíî"
-
-# msgstr "E29: "
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: Ùå íå áóëî êîìàíä"
-
-# msgstr "E30: "
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: Íåìຠòàêî¿ çàì³íè"
-
-# msgstr "E31: "
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: Æîäíîãî çá³ãó"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: Æîäíîãî çá³ãó: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: Áðàêóº íàçâè ôàéëó"
-
-# msgstr "E32: "
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: Çàì³íà çðàçê³â ùå íå âèêîðèñòîâóâàëàñü"
-
-# msgstr "E33: "
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: Êîìàíä ùå íå áóëî"
-
-# msgstr "E34: "
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: Çðàçê³â ïîøóêó ùå íå áóëî"
-
-# msgstr "E35: "
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: Íå äîçâîëåíî âêàçóâàòè ìåæ³"
-
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: ̳ñöÿ íå âèñòà÷èòü"
-
-# msgstr "E36: "
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Íå âäàëîñÿ ñòâîðèòè ôàéë %s"
-
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: Íå âäàëîñÿ ñôîðìóâàòè íàçâó òèì÷àñîâîãî ôàéëó"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: Íå âäàëîñÿ â³äêðèòè ôàéë %s"
-
-#: ../globals.h:1052
-#, 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
-msgid "E38: Null argument"
-msgstr "E38: ³äñóòí³é àðãóìåíò"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: Î÷³êóºòüñÿ ÷èñëî"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: Íå âäàëîñÿ â³äêðèòè ôàéë ïîìèëîê %s"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: Çàáðàêëî ïàì'ÿò³!"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "Çðàçîê íå çíàéäåíî"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: Çðàçîê íå çíàéäåíî: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: Àðãóìåíò ìຠáóòè äîäàòíèé"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: Íå âäàëîñÿ ïåðåéòè äî ïîïåðåäíüîãî êàòàëîãó"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: Æîäíî¿ ïîìèëêè"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: Íåìຠñïèñêó ì³ñöü"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: Òåêñò çá³ãó ïîøêîäæåíî"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: dzïñîâàíà ïðîãðàìà ðåãóëÿðíèõ âèðàç³â"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: Âñòàíîâëåíî îïö³þ 'readonly' (! ùîá íå çâàæàòè)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Çì³ííà ò³ëüêè äëÿ ÷èòàííÿ: «%s»"
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Íå ìîæíà âñòàíîâèòè çì³ííó ó ï³ñî÷íèö³: «%s»"
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Ïîìèëêà ÷èòàííÿ ôàéëó ïîìèëîê"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: Íà äîçâîëåíî ó ï³ñî÷íèö³"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: Íå äîçâîëåíî òóò"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: Ðåæèì åêðàíó íå ï³äòðèìóºòüñÿ"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: Íåêîðåêòíèé ðîçì³ð çñóâó"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: Îïö³ÿ 'shell' ïîðîæíÿ"
-
-# msgstr "E254: "
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: Íå ìîæíà ç÷èòàòè äàí³ íàïèñó!"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: Ïîìèëêà ï³ä ÷àñ çàêðèòòÿ ôàéëó îáì³íó"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: Ñòåê òå´³â ïîðîæí³é"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: Çàíàäòî ñêëàäíà êîìàíäà"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Çàäîâãå ³ì'ÿ"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: Çàáàãàòî '['"
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: Çàáàãàòî íàçâ ôàéë³â"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: Íàäëèøêîâ³ ñèìâîëè"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: Íåâ³äîìà ïîì³òêà"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: Íå âäàëîñÿ ðîçêðèòè øàáëîí"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' íå ìîæå áóòè ìåíøèì çà 'winminheight'"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' íå ìîæå áóòè ìåíøèì çà 'winminwidth'"
-
-# msgstr "E79: "
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: Ïîìèëêà ï³ä ÷àñ çàïèñó"
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Íóëüîâà ê³ëüê³ñòü"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: <SID> âèêîðèñòîâóºòüñÿ íå â êîíòåêñò³ ñêðèïòó"
-
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Âíóòð³øíÿ ïîìèëêà: %s"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: Çðàçîê âèêîðèñòîâóº á³ëüøå, í³æ 'maxmempattern', ïàì'ÿò³"
-
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: Ïîðîæí³é áóôåð"
-
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: Íåêîðåêòíèé çðàçîê äëÿ ïîøóêó ÷è ðîçä³ëüíèê"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: Ôàéë óæå çàâàíòàæåíî â ³íøèé áóôåð"
-
-# msgstr "E235: "
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: Îïö³ÿ '%s' íå âñòàíîâëåíà"
-
-#: ../globals.h:1111
-msgid "E850: Invalid register name"
-msgstr "E850: Íåïðàâèëüíà íàçâà ðåã³ñòðó"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "Ïîøóê ä³éøîâ äî ÏÎ×ÀÒÊÓ, ïðîäîâæóºòüñÿ ç ʲÍÖß"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "Ïîøóê ä³éøîâ äî ʲÍÖß, ïðîäîâæóºòüñÿ ç ÏÎ×ÀÒÊÓ"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: Ïðîïóùåíî äâîêðàïêó"
-
-# msgstr "E347: "
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: Íåêîðåêòíèé êîìïîíåíò"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: î÷³êóºòüñÿ öèôðà"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "Ñòîð³íêà %d"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "ͳ÷îãî äðóêóâàòè"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "Äðóêóºòüñÿ ñòîð³íêà %d (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr " Êîï³ÿ %d ç %d"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "Íàäðóêîâàíî: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "Äðóê ïåðåðâàíî"
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: Íå âäàëîñÿ çàïèñàòè âèõ³äíèé ôàéë PostScript"
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: Íå âäàëîñÿ â³äêðèòè ôàéë «%s»"
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: Íå âäàëîñÿ ïðî÷èòàòè ôàéë ðåñóðñ³â PostScript «%s»"
-
-#: ../hardcopy.c:1772
-#, 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
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: «%s» íå º ï³äòðèìóâàíèì ôàéëîì ðåñóðñ³â PostScript"
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: Íåïðàâèëüíà âåðñ³ÿ ôàéëó ðåñóðñ³â «%s»"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: Íåñóì³ñí³ áàãàòîáàéòîâå êîäóâàííÿ é íàá³ð ñèìâîë³â."
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr ""
-"E674: printmbcharset íå ìîæå áóòè ïîðîæí³ì ç áàãàòîáàéòîâèì êîäóâàííÿì."
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr "E675: Íå çàçíà÷åíî øðèôò äëÿ áàãàòîáàéòîâîãî äðóêó."
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: Íå âäàëîñÿ â³äêðèòè ôàéë PostScript äëÿ âèâîäó"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: Íå âäàëîñÿ â³äêðèòè ôàéë «%s»"
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: Íå âäàëîñÿ çíàéòè ôàéë ðåñóðñ³â PostScript «prolog.ps»"
-
-#: ../hardcopy.c:2593
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: Íå âäàëîñÿ çíàéòè ôàéë ðåñóðñ³â PostScript «cidfont.ps»"
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: Íå âäàëîñÿ çíàéòè ôàéë ðåñóðñ³â PostScript «%s.ps»"
-
-#: ../hardcopy.c:2654
-#, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: Íå âäàëîñÿ ïåðåòâîðèòè äî êîäóâàííÿ äðóêó «%s»"
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "³äñèëàºòüñÿ íà ïðèíòåð..."
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: Íå âäàëîñÿ íàäðóêóâàòè ôàéë PostScript"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "Çàâäàííÿ äðóêó â³ä³ñëàíî."
-
-# msgstr "E255: "
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "Äîäàòè íîâó áàçó äàíèõ"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "Çàïèò çà çðàçêîì"
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "Ïîêàçàòè öå ïîâ³äîìëåííÿ"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "Çíèùèòè ç'ºäíàííÿ"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "Ïåðåçàïóñòèòè óñ³ ç'ºäíàííÿ"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "Ïîêàçàòè ç'ºäíàííÿ"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Âèêîðèñòàííÿ: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "Öÿ êîìàíäà cscope íå â쳺 ä³ëèòè â³êíî.\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Âèêîðèñòàííÿ: cstag <³äåíòèô-îð>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: òå´ íå çíàéäåíî"
-
-# msgstr "E257: "
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) ïîìèëêà: %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s íå º í³ êàòàëîãîì, í³ áàçîþ äàíèõ cscope"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "Äîäàíî áàçó äàíèõ cscope %s"
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: Ïîìèëêà ÷èòàííÿ ç³ ç'ºäíàííÿ cscope %<PRId64>"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: Íåâ³äîìèé òèï ïîøóêó cscope"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: Íå âäàëîñÿ ñòâîðèòè êàíàëè äî cscope"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: Íå âäàëîñÿ ðîçä³ëèòè ïðîöåñ äëÿ cscope"
-
-#: ../if_cscope.c:849
-msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection: ïîìèëêà setpgid"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection: ïîìèëêà ï³ä ÷àñ âèêîíàííÿ"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen äëÿ to_fp íå âäàâñÿ"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen äëÿ fr_fp íå âäàâñÿ"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: Íå âäàëîñÿ ñòâîðèòè ïðîöåñ cscope"
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: æîäíîãî ç'ºäíàííÿ ³ç cscope"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: Íåêîðåêòíèé ïðàïîðåöü cscopequickfix %c äëÿ %c"
-
-# msgstr "E258: "
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: Äëÿ çàïèòó cscope %s ç %s í³÷îãî íå çíàéäåíî"
-
-# msgstr "E259: "
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "Êîìàíäè cscope:\n"
-
-#: ../if_cscope.c:1150
-#, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %s%*s (Âèêîðèñòàííÿ: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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"
-" c: Çíàéòè ôóíêö³¿, ùî âèêëèêàþòü öþ ôóíêö³þ\n"
-" d: Çíàéòè ôóíêö³¿, ùî âèêëèêàþòüñÿ ö³ºþ ôóíêö³ºþ\n"
-" e: Çíàéòè öåé øàáëîí egrep\n"
-" f: Çíàéòè öåé ôàéë\n"
-" g: Çíàéòè öå âèçíà÷åííÿ\n"
-" i: Çíàéòè ôàéëè, ÿê³ âêëþ÷àþòü â ñåáå öåé ôàéë\n"
-" s: Çíàéòè öåé ñèìâîë C\n"
-" t: Çíàéòè öåé òåêñò\n"
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: Ïîâòîðíà áàçà äàíèõ cscope íå äîäàíà"
-
-# msgstr "E260: "
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: Ç'ºäíàííÿ ç cscope %s íå çíàéäåíî"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "Ç'ºäíàííÿ ç cscope %s çàê³í÷åíî"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: Ôàòàëüíà ïîìèëêà â cs_manage_matches"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Òå´ cscope: %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # ðÿäîê"
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "ôàéë / êîíòåêñò / ðÿäîê\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: Ïîìèëêà cscope: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "Óñ³ áàçè äàíèõ cscope ïåðåçàâàíòàæåíî"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "Æîäíîãî ç'ºäíàííÿ ç cscope\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid íàçâà áàçè äàíèõ øëÿõ\n"
-
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "Íåâ³äîìèé àðãóìåíò îïö³¿"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "Çàáàãàòî àðãóìåíò³â"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "Ïðîïóùåíî àðãóìåíò ï³ñëÿ"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "Ñì³òòÿ ï³ñëÿ àðãóìåíòó îïö³¿"
-
-#: ../main.c:152
-msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
-msgstr "Çàáàãàòî àðãóìåíò³â ó «+êîìàíäà», «-c êîìàíäà» àáî «--cmd êîìàíäà»"
-
-# msgstr "E14: "
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "Íåïðàâèëüíèé àðãóìåíò ó"
-
-#: ../main.c:294
-#, c-format
-msgid "%d files to edit\n"
-msgstr "%d ôàéëè(³â)\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "Ñïðîáà ïîâòîðíî â³äêðèòè ñêðèïò: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "Íå âäàëîñÿ ïðî÷èòàòè: \""
-
-#: ../main.c:1393
-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"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "êîìàíäè ïåðåä vimrc"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: Íå âäàëîñÿ ïðî÷èòàòè ç «%s»"
-
-# msgstr "E282: "
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"ijçíàéòåñÿ á³ëüøå: «vim -h»\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[ôàéë ..] ðåäàãóâàòè âêàçàí³ ôàéëè"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- ÷èòàòè òåêñò ç stdin"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t ïîì³òêà ïåðåéòè äî òå´ó"
-
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [ôàéë] ïåðåéòè äî ïåðøî¿ ïîìèëêè"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"Âæèòîê:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [àðãóìåíòè] "
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" àáî:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"Àðãóìåíòè:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tËèøå íàçâè ôàéë³â ï³ñëÿ öüîãî"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tÍå ðîçêðèâàòè øàáëîíè"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tÐåæèì Vi (í³áè «vi»)"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tÐåæèì Ex (í³áè «ex»)"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr "-E\t\t\tÏîêðàùåíèé ðåæèì Ex"
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tÌîâ÷àçíèé (ïàêåòíèé) ðåæèì (ëèøå äëÿ «ex»)"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tÐåæèì ïîð³âíÿííÿ (í³áè «vimdiff»)"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tÏðîñòèé ðåæèì (í³áè «evim», áåç ðåæèì³â)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tÐåæèì ïåðåãëÿäó (í³áè «view»)"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tÎáìåæåíèé ðåæèì (í³áè «rvim»)"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\tÇì³íè (çàïèñ ôàéë³â) íå äîçâîëåíî"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tÇì³íè â òåêñò³ ôàéë³â íå äîçâîëåíî"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tÄâ³éêîâèé ðåæèì"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tÐåæèì lisp"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tÑóì³ñíèé ç Vi ðåæèì: 'compatible'"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tÍå çîâñ³ì ñóì³ñíèé ç Vi ðåæèì: 'nocompatible'"
-
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr "-V[N][ôàéë]\t\tÁ³ëüøå ïîâ³äîìëåíü [ð³âåíü N] [ôàéë æóðí. ïîâ³äîìëåíü]"
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tÐåæèì íàëàãîäæåííÿ"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tÍå âèêîðèñòîâóâàòè ôàéë îáì³íó, òðèìàòè óñå â ïàì'ÿò³"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tÏîêàçàòè ôàéëè îáì³íó ³ âèéòè"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (íàçâà ôàéëó)\t³äíîâèòè àâàð³éíî çàê³í÷åíèé ñåàíñ"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tÒå ñàìå, ùî é -r"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tÇàïóñòèòè â ðåæèì³ àðàáñüêî¿ ìîâè"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tÇàïóñòèòè â ðåæèì³ ³âðèòó"
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tÇàïóñòèòè â ðåæèì³ ïåðñüêî¿ ìîâè"
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <òåðì³íàë>\tÂñòàíîâèòè òèï òåðì³íàëó ó <òåðì³íàë>"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tÂèêîðèñòàòè ïîäàíèé ôàéë çàì³ñòü .vimrc"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tÍå âàíòàæèòè ñêðèïòè äîïîâíåííÿ"
-
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\t³äêðèòè N âêëàäîê (àáî ïî îäí³é äëÿ êîæíîãî ôàéëó)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\t³äêðèòè N â³êîí (àáî ïî îäíîìó äëÿ êîæíîãî ôàéëó)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tͳáè -o, àëå ïîä³ëèòè â³êíà âåðòèêàëüíî"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tÐîçïî÷àòè â ê³íö³ ôàéëó"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<ðÿäîê>\t\tÐîçïî÷àòè ó âêàçàíîìó <ðÿäêó>"
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <êîìàíäà>\tÂèêîíàòè <êîìàíäó> ïåðåä çàâàíòàæåííÿì vimrc"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <êîìàíäà>\t\tÂèêîíàòè <êîìàíäó> ï³ñëÿ çàâàíòàæåííÿ ïåðøîãî ôàéëó"
-
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <ñåàíñ>\t\tÂèêîíàòè ïîäàíèé ôàéë ï³ñëÿ ïåðøîãî çàâàíòàæåíîãî ôàéëó"
-
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <ñêðèïò>\t\tÇ÷èòàòè êîìàíäè íîðìàëüíîãî ðåæèìó ç ôàéëó <ñêðèïò>"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <ñêðèïò>\t\tÄîïèñàòè óñ³ íàáðàí³ êîìàíäè äî ôàéëó <ñêðèïò>"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-w <ñêðèïò>\t\tÇàïèñàòè óñ³ íàáðàí³ êîìàíäè ó ôàéë <ñêðèïò>"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr ""
-"--startuptime <ôàéë>\tÇàïèñàòè çàïóñêí³ ïîâ³äîìëåííÿ ç ÷àñîâèìè â³äì³òêàìè "
-"äî <ôàéëó>"
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tÂèêîðèñòàòè <viminfo> çàì³ñòü .viminfo"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h ÷è --help\tÍàäðóêóâàòè öå ïîâ³äîìëåííÿ ³ âèéòè"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\tÍàäðóêóâàòè ³íôîðìàö³þ ïðî âåðñ³þ ïðîãðàìè ³ âèéòè"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "Íå âñòàíîâëåíî æîäíî¿ ïîì³òêè"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: Ïîì³òêó «%s» íå çíàéäåíî"
-
-# msgstr "E283: "
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"ïîì. ðÿä. êîë. ôàéë/òåêñò"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-" òî÷êà ðÿä. ñòîâï. ôàéë/òåêñò"
-
-# msgstr "E283: "
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-"\n"
-"çì³íèòè ðÿä. ñòîâï. òåêñò"
-
-# TODO
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Ïîì³òêè:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Ñïèñîê ïåðåõîä³â (â³ä íàéíîâ³øèõ):\n"
-
-# TODO
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Ïîïåðåäí³ ïîì³òêè â ôàéëàõ (â³ä íàéíîâ³øèõ):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "Ïðîïóùåíî '>'"
-
-# msgstr "E292: "
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: Áëîê íå áóëî çàô³êñîâàíî"
-
-# msgstr "E293: "
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: Ïîìèëêà çì³íè ïîçèö³¿ ó ôàéë³ îáì³íó"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: Ïîìèëêà ç÷èòóâàííÿ ôàéëó îáì³íó"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: Ïîìèëêà çì³íè ïîçèö³¿ ï³ä ÷àñ çàïèñó ó ôàéë îáì³íó"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: Ïîìèëêà çàïèñó ôàéëó îáì³íó"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: Ôàéë îáì³íó âæå ³ñíóº (àòàêà ñèìâîëüíèì ïîñèëàííÿì?)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: Íåìຠáëîêó 0?"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: Íåìຠáëîêó 1?"
-
-# msgstr "E298: "
-#: ../memline.c:377
-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
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: Îé, âòðà÷åíî ôàéë îáì³íó!!!"
-
-# msgstr "E301: "
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: Íå âäàëîñÿ ïåðåéìåíóâàòè ôàéëó îáì³íó"
-
-# msgstr "E302: "
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr "E303: Íå âäàëîñÿ ïðî÷èòàòè ôàéë îáì³íó äëÿ «%s», â³äíîâëåííÿ íåìîæëèâå"
-
-#: ../memline.c:666
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_upd_block0(): Íåìຠáëîêó 0??"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: Íå çíàéäåíî ôàéëó îáì³íó äëÿ %s"
-
-# msgstr "E305: "
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr "Ââåä³òü íîìåð ôàéëó îáì³íó, êîòðèé âèêîðèñòàòè, (0 äëÿ âèõîäó):"
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: Íå âäàëîñÿ â³äêðèòè %s"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "Íå âäàëîñÿ ïðî÷èòàòè áëîê 0 ç "
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"Íàïåâíî, çì³í íå áóëî, àáî Vim íå ïîíîâèâ ôàéë îáì³íó."
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " íå ìîæíà âèêîðèñòàòè ç ö³ºþ âåðñ³ºþ Vim.\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "Çíàéä³òü Vim 3.0\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %s íå ñõîæå íà ôàéë îáì³íó Vim"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " íå ìîæíà âèêîðèñòàòè íà öüîìó êîìï'þòåð³.\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr "Ôàéë áóëî ñòâîðåíî íà "
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-",\n"
-"àáî ôàéë áóëî ïîøêîäæåíî."
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr " ïîøêîäæåíèé (ðîçì³ð ñòîð³íêè ìåíøèé ì³í³ìàëüíîãî çíà÷åííÿ).\n"
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "Âèêîðèñòîâóºòüñÿ ôàéë îáì³íó «%s»"
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "Ïî÷àòêîâèé ôàéë «%s»"
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: Çàñòåðåæåííÿ: Ìîæëèâî, ïî÷àòêîâèé ôàéë áóëî çì³íåíî"
-
-# msgstr "E308: "
-#: ../memline.c:1061
-#, c-format
-msgid "E309: Unable to read block 1 from %s"
-msgstr "E309: Íå âäàëîñÿ ïðî÷èòàòè áëîê 1 ç %s"
-
-# msgstr "E309: "
-#: ../memline.c:1065
-msgid "???MANY LINES MISSING"
-msgstr "??? ÁÐÀÊÓª ÁÀÃÀÒÜÎÕ ÐßÄʲÂ"
-
-#: ../memline.c:1076
-msgid "???LINE COUNT WRONG"
-msgstr "??? ÍÅÏÐÀÂÈËÜÍÀ ʲËÜʲÑÒÜ ÐßÄʲÂ"
-
-#: ../memline.c:1082
-msgid "???EMPTY BLOCK"
-msgstr "??? ÏÎÐÎÆÍ²É ÁËÎÊ"
-
-#: ../memline.c:1103
-msgid "???LINES MISSING"
-msgstr "??? ÏÐÎÏÓÙÅͲ ÐßÄÊÈ"
-
-#: ../memline.c:1128
-#, c-format
-msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: ²äåíòèô³êàòîð áëîêó 1 íåïðàâèëüíèé (%s íå º ôàéëîì îáì³íó?)"
-
-# msgstr "E310: "
-#: ../memline.c:1133
-msgid "???BLOCK MISSING"
-msgstr "??? ÏÐÎÏÓÙÅÍÎ ÁËÎÊ"
-
-#: ../memline.c:1147
-msgid "??? from here until ???END lines may be messed up"
-msgstr "??? çâ³äñè ³ äî `??? ʲÍÅÖÜ' ðÿäêè, ìîæëèâî, ñïëóòàí³"
-
-#: ../memline.c:1164
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? çâ³äñè ³ äî `??? ʲÍÅÖÜ' ðÿäêè, ìîæëèâî, áóëè äîäàí³/çíèùåí³"
-
-#: ../memline.c:1181
-msgid "???END"
-msgstr "??? ʲÍÅÖÜ"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: ³äíîâëåííÿ ïåðåðâàíî"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr ""
-"E312: ϳä ÷àñ â³äíîâëåííÿ çíàéäåíî ïîìèëêè. Ïåðåãëÿíüòå ðÿäêè, ùî "
-"ïî÷èíàþòüñÿ ç ???"
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "Äèâ. «:help E312» äëÿ óòî÷íåííÿ."
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr "³äíîâëåííÿ çàê³í÷åíî, ïåðåâ³ðòå ÷è âñå ãàðàçä."
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(Ìîæëèâî, ïîòð³áíî çàïèñàòè öåé ôàéë ï³ä ³íøîþ íàçâîþ\n"
-
-#: ../memline.c:1252
-msgid "and run diff with the original file to check for changes)"
-msgstr "³ çàïóñòèòè diff ç îðèã³íàëîì ùîá ïåðåâ³ðèòè çì³íè)"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr "³äíîâëåííÿ çàê³í÷åíî. Âì³ñò áóôåðà ñï³âïàäàº ç³ âì³ñòîì ôàéëó."
-
-#: ../memline.c:1255
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"\n"
-"Ìîæëèâî, òåïåð âè õî÷åòå çíèùèòè ôàéë îáì³íó .swp.\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "Çíàéäåíî ôàéëè îáì³íó:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr "  ïîòî÷íîìó êàòàëîç³:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " Âèêîðèñòîâóþ÷è âêàçàíó íàçâó:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " Ó êàòàëîç³ "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- æîäíîãî --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " âëàñíèê: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " äàòà: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " äàòà: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [â³ä Vim 3.0]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [íå ñõîæå íà ôàéë îáì³íó]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " íàçâà ôàéëó: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" çì³íåíî: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "ÒÀÊ"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "í³"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" êîðèñòóâà÷: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " íàçâà âóçëà: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" íàçâà âóçëà: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" ID ïðîöåñó: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (âèêîíóºòüñÿ)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [íåïðèäàòíèé íà öüîìó êîìï'þòåð³]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [íå ìîæíà ïðî÷èòàòè]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [íå ìîæíà â³äêðèòè]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: Íå âäàëîñÿ çàãîòîâèòè, íåìຠôàéëó îáì³íó"
-
-# msgstr "E313: "
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "Ôàéë çáåðåæåíî"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: Çáåðåæåííÿ íå âäàëîñÿ"
-
-# msgstr "E314: "
-#: ../memline.c:1819
-#, c-format
-msgid "E315: ml_get: invalid lnum: %<PRId64>"
-msgstr "E315: ml_get: íåïðàâèëüíèé lnum: %<PRId64>"
-
-# msgstr "E315: "
-#: ../memline.c:1851
-#, c-format
-msgid "E316: ml_get: cannot find line %<PRId64>"
-msgstr "E316: ml_get: íå çíàéøîâ ðÿäîê %<PRId64>"
-
-# msgstr "E316: "
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: Âêàç³âíèê áëîêó ïîìèëêîâèé 3"
-
-# msgstr "E317: "
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "stack_idx ìຠáóòè ð³âíèì 0"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: Ïîíîâëåíî çàáàãàòî áëîê³â?"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: Âêàç³âíèê áëîêó ïîìèëêîâèé 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "áëîê 1 çíèùåíî?"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: Íå âäàëîñÿ çíàéòè ðÿäîê %<PRId64>"
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: Âêàç³âíèê áëîêó ïîìèëêîâèé"
-
-# msgstr "E317: "
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "pe_line_count äîð³âíþº 0"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: Íîìåð ðÿäêà âèéøîâ çà ìåæ³: %<PRId64> çà ê³íöåì"
-
-# msgstr "E322: "
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ʳëüê³ñòü ðÿäê³â ó áëîö³ %<PRId64>"
-
-# msgstr "E323: "
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "Ðîçì³ð ñòåêó çá³ëüøóºòüñÿ"
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: Âêàç³âíèê áëîêó ïîìèëêîâèé 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr "E773: Öèêë³÷í³ ñèìâîëüí³ ïîñèëàííÿ «%s»"
-
-# msgstr "E317: "
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: ÓÂÀÃÀ"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"Çíàéäåíî ôàéë îáì³íó ç íàçâîþ \""
-
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "Ïðè â³äêðèòò³ ôàéëó \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " ÍβØÈÉ çà ôàéë îáì³íó!\n"
-
-#: ../memline.c:3244
-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."
-msgstr ""
-"\n"
-"(1) Ìîæëèâî, ³íøà ïðîãðàìà âæå ðåäàãóº öåé ñàìèé ôàéë. ßêùî öå òàê,\n"
-" áóäüòå îáåðåæí³, ùîá íå çàëèøèëèñÿ äâà ð³çí³ åêçåìïëÿðè\n"
-" îäíîãî é òîãî ñàìîãî ôàéëó ï³ñëÿ çì³í."
-
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " Âèéä³òü àáî ïðîäîâæóéòå îáåðåæíî.\n"
-
-#: ../memline.c:3246
-msgid "(2) An edit session for this file crashed.\n"
-msgstr "(2) Ñåàíñ ðåäàãóâàííÿ öüîãî ôàéëó çàçíàâ êðàõó.\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " ßêùî öå ñïðàâä³ òðàïèëîñÿ, ñïðîáóéòå «:recover» àáî «vim -r "
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"»\n"
-" ùîá â³äíîâèòè çì³íè (äèâ. «:help recovery»).\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " ßêùî âè âæå öå çðîáèëè, çíèù³òü ôàéë îáì³íó «"
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"»,\n"
-" ùîá ïîçáóòèñÿ öüîãî ïîâ³äîìëåííÿ.\n"
-"\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "Ôàéë îáì³íó «"
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "» âæå ³ñíóº!"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "VIM — ÓÂÀÃÀ"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "Ôàéë îáì³íó âæå ³ñíóº!"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"&O:³äêðèòè ëèøå äëÿ ÷èòàííÿ\n"
-"&E:Âñå îäíî ðåäàãóâàòè\n"
-"&R:³äíîâèòè\n"
-"&Q:Âèéòè\n"
-"&A:Ïåðåðâàòè"
-
-#: ../memline.c:3467
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"&O:³äêðèòè ëèøå äëÿ ÷èòàííÿ\n"
-"&E:Óñå îäíî ðåäàãóâàòè\n"
-"&R:³äíîâèòè\n"
-"&D:Çíèùèòè éîãî\n"
-"&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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
-msgid "E326: Too many swap files found"
-msgstr "E326: Çíàéäåíî çàáàãàòî ôàéë³â îáì³íó"
-
-# msgstr "E341: "
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: Çàáðàêëî ïàì'ÿò³! (ïîòð³áíî áóëî %<PRIu64> áàéò³â)"
-
-# msgstr "E326: "
-#: ../menu.c:62
-msgid "E327: Part of menu-item path is not sub-menu"
-msgstr "E327: ×àñòèíà øëÿõó äî åëåìåíòà ìåíþ íå º ï³äìåíþ"
-
-# msgstr "E327: "
-#: ../menu.c:63
-msgid "E328: Menu only exists in another mode"
-msgstr "E328: Ìåíþ ìîæå áóòè ò³ëüêè â ³íøîìó ðåæèì³"
-
-# msgstr "E328: "
-#: ../menu.c:64
-#, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: Íåìຠìåíþ «%s»"
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-msgid "E792: Empty menu name"
-msgstr "E792: Ïîðîæíÿ íàçâà ìåíþ"
-
-# msgstr "E329: "
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: Øëÿõ äî ìåíþ íå ïîâèíåí âåñòè äî ï³äìåíþ"
-
-# msgstr "E330: "
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: Íå ìîæíà äîäàâàòè åëåìåíòè ìåíþ ïðîñòî äî âåðõíüîãî ìåíþ"
-
-# msgstr "E331: "
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: Ðîçä³ëüíèê íå ìîæå áóòè ÷àñòèíîþ øëÿõó ìåíþ"
-
-# msgstr "E332: "
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- Ìåíþ ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: Øëÿõ ïîâèíåí âåñòè äî åëåìåíòà ìåíþ"
-
-# msgstr "E333: "
-#: ../menu.c:1330
-#, c-format
-msgid "E334: Menu not found: %s"
-msgstr "E334: Ìåíþ íå çíàéäåíî: %s"
-
-# msgstr "E334: "
-#: ../menu.c:1396
-#, c-format
-msgid "E335: Menu not defined for %s mode"
-msgstr "E335: Äëÿ ðåæèìó %s ìåíþ íå âèçíà÷åíî"
-
-# msgstr "E335: "
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: Øëÿõ ïîâèíåí âåñòè äî ï³äìåíþ"
-
-# msgstr "E336: "
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: Ìåíþ íå çíàéäåíî — ïåðåâ³ðòå íàçâó"
-
-# msgstr "E337: "
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "Âèÿâëåíî ïîìèëêó ï³ä ÷àñ âèêîíàííÿ %s:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "ðÿäîê %4ld:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: Íåïðàâèëüíà íàçâà ðåã³ñòðó: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "Óêðà¿í³çàö³ÿ: Àíàòîë³é Ñàõí³ê <sakhnik@gmail.com>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "Ïåðåðâàíî: "
-
-#: ../message.c:988
-msgid "Press ENTER or type command to continue"
-msgstr "Íàòèñí³òü ENTER àáî ââåä³òü êîìàíäó äëÿ ïðîäîâæåííÿ"
-
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s ðÿäîê %<PRId64>"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- Ùå --"
-
-#: ../message.c:2398
-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
-msgid "Question"
-msgstr "Çàïèòàííÿ"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"&Y:Òàê\n"
-"&N:ͳ"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Y:Òàê\n"
-"&N:ͳ\n"
-"&C:Ñêàñóâàòè"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"&Y:Òàê\n"
-"&N:ͳ\n"
-"&A:Óñ³\n"
-"&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: Î÷³êóºòüñÿ àðãóìåíò Float äëÿ printf()"
-
-#: ../message.c:3873
-msgid "E767: Too many arguments to printf()"
-msgstr "E767: Çàáàãàòî àðãóìåíò³â äëÿ printf()"
-
-# msgstr "E338: "
-#: ../misc1.c:2256
-msgid "W10: Warning: Changing a readonly file"
-msgstr "W10: Çàñòåðåæåííÿ: Çì³íþºòüñÿ ôàéë ïðèçíà÷åíèé ëèøå äëÿ ÷èòàííÿ"
-
-#: ../misc1.c:2537
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr "Íàáåð³òü ÷èñëî é <Enter> ÷è êëàöí³òü ìèøêîþ (ïîðîæíº ñêàñîâóº): "
-
-#: ../misc1.c:2539
-msgid "Type number and <Enter> (empty cancels): "
-msgstr "Íàáåð³òü ÷èñëî é <Enter> (ïîðîæíº ñêàñîâóº): "
-
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "äîäàíî îäèí ðÿäîê"
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "çíèùåíî îäèí ðÿäîê"
-
-#: ../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 "Äçåíü!"
-
-# msgstr "E342: "
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "Âèêëèêàºòüñÿ îáîëîíêà ùîá âèêîíàòè: «%s»"
-
-# msgstr "E348: "
-#: ../normal.c:183
-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
-msgid "E348: No string under cursor"
-msgstr "E348: Íåìຠðÿäêà íà êóðñîð³"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: Íå âäàëîñÿ çíèùèòè çãîðòêè ïîòî÷íèì ìåòîäîì 'foldmethod'"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: Ñïèñîê çì³í ïîðîæí³é"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr "E662: Ïî÷àòîê ñïèñêó çì³í"
-
-#: ../normal.c:5901
-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 "Îäèí ðÿäîê %s-íî"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "Îäèí ðÿäîê %s-íî %d ðàç³â"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> ðÿäê³â %s-íî"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> ðÿäê³â %s-íî %d ðàç³â"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "Çàëèøèëîñÿ âèð³âíÿòè %<PRId64> ðÿäê³â..."
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "Âèð³âíÿíî îäèí ðÿäîê"
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "Âèð³âíÿíî ðÿäê³â: %<PRId64>"
-
-#: ../ops.c:938
-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 "Îäèí ðÿäîê çì³íåíî"
-
-#: ../ops.c:1931
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "Çì³íåíî ðÿäê³â: %<PRId64>"
-
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "Çàïàì'ÿòàâ áëîê ç îäíîãî ðÿäêà"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "Çàïàì'ÿòàâ îäèí ðÿäîê"
-
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "Çàïàì'ÿòàâ áëîê ³ç %<PRId64> ðÿäê³â"
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "Çàïàì'ÿòàâ ðÿäê³â: %<PRId64>"
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353: Ó ðåã³ñòð³ %s í³÷îãî íåìàº"
-
-# msgstr "E353: "
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- Ðåã³ñòðè ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "Íåïðàâèëüíà íàçâà ðåã³ñòðó"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# Ðåã³ñòðè:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: Íåâ³äîìèé òèï ðåã³ñòðó %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "äîâæ.: %<PRId64>; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Âèáðàíî %s%<PRId64> ç %<PRId64> ðÿäê³â; %<PRId64> ç %<PRId64> ñë³â; "
-"%<PRId64> ç %<PRId64> áàéò³â"
-
-#: ../ops.c:5105
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Âèáðàíî %s%<PRId64> ç %<PRId64> ðÿäê³â; %<PRId64> ç %<PRId64> ñë³â; "
-"%<PRId64> of %<PRId64> ñèìâîë³â; %<PRId64> ç %<PRId64> áàéò³â"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Êîëîíêà %s ç %s; ðÿäîê %<PRId64> ç %<PRId64>; ñëîâî %<PRId64> ç %<PRId64>; "
-"áàéò %<PRId64> ç %<PRId64>"
-
-#: ../ops.c:5133
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"Êîëîíêà %s ç %s; ðÿäîê %<PRId64> ç %<PRId64>; ñëîâî %<PRId64> ç %<PRId64>; "
-"ñèìâîë %<PRId64> of %<PRId64>; áàéò %<PRId64> ç %<PRId64>"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> äëÿ BOM)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Ñòîð. %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "Äÿêóºìî çà âèá³ð Vim"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: Íåâ³äîìà îïö³ÿ"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: Îïö³ÿ íå ï³äòðèìóºòüñÿ"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: Íå äîçâîëåíî ó modeline"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr "E846: Êîä êëþ÷à íå âñòàíîâëåíî"
-
-#: ../option.c:2924
-msgid "E521: Number required after ="
-msgstr "E521: ϳñëÿ = ïîòð³áíî âêàçàòè ÷èñëî"
-
-#: ../option.c:3226 ../option.c:3864
-msgid "E522: Not found in termcap"
-msgstr "E522: Íå çíàéäåíî ñåðåä ìîæëèâîñòåé òåðì³íàë³â"
-
-#: ../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
-msgid "E590: A preview window already exists"
-msgstr "E590: ³êíî ïåðåãëÿäó âæå ³ñíóº"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr ""
-"W17: Äëÿ àðàáñüêî¿ ìîâè ïîòð³áíå UTF-8, âèêîíàéòå ':set encoding=utf-8'"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: Ïîòð³áíî ùîíàéìåíøå %d ðÿäê³â"
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: Ïîòð³áíî ùîíàéìåíøå %d ñòîâïö³â"
-
-#: ../option.c:6011
-#, 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
-#, c-format
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: Ïîòð³áíî âêàçàòè Number: &%s = '%s'"
-
-# msgstr "E355: "
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- Êîäè òåðì³íàëó ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- Çíà÷åííÿ çàãàëüíèõ îïö³é ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- Çíà÷åííÿ ëîêàëüíèõ îïö³é ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- Îïö³¿ ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: Ïîìèëêà get_varp"
-
-# msgstr "E356: "
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': Äëÿ ñèìâîëó %s íåìຠïàðè"
-
-# msgstr "E357: "
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': Çàéâ³ ñèìâîëè ï³ñëÿ `;': %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"Íå âäàëîñÿ çàïóñòèòè îáîëîíêó"
-
-# msgstr "E362: "
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"îáîëîíêà ïîâåðíóëà: "
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-"\n"
-"Íå âäàëîñÿ îòðèìàòè êîíòåêñò áåçïåêè äëÿ "
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-"\n"
-"Íå âäàëîñÿ âñòàíîâèòè êîíòåêñò áåçïåêè äëÿ "
-
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = «%s»"
-
-# msgstr "E446: "
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: Ôàéë «%s» íå çíàéäåíî ó øëÿõó ïîøóêó"
-
-# msgstr "E371: "
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: Çàáàãàòî %%%c ó ðÿäêó ôîðìàòó"
-
-# msgstr "E372: "
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: Íåî÷³êóâàíèé `%%%c' ó ðÿäêó ôîðìàòó"
-
-# msgstr "E373: "
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: Ïðîïóùåíî ] ó ðÿäêó ôîðìàòó"
-
-# msgstr "E374: "
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: %%%c ó ðÿäêó ôîðìàòó íå ï³äòðèìóºòüñÿ"
-
-# msgstr "E375: "
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: Ïîìèëêîâèé `%%%c' ó ïðåô³êñ³ ðÿäêó ôîðìàòó"
-
-# msgstr "E376: "
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: Ïîìèëêîâèé `%%%c' ó ðÿäêó ôîðìàòó"
-
-# msgstr "E377: "
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: 'errorformat' íå ì³ñòèòü çðàçîê"
-
-# msgstr "E378: "
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: Ïðîïóùåíà ÷è ïîðîæíÿ íàçâà êàòàëîãó"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: Íåìຠá³ëüøå åëåìåíò³â"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d ç %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (ðÿäîê çíèùåíî)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: Äíî ñòåêó âèïðàâëåíü"
-
-#: ../quickfix.c:1869
-msgid "E381: At top of quickfix stack"
-msgstr "E381: Âåðøèíà ñòåêó âèïðàâëåíü"
-
-#: ../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:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr "E683: Ïðîïóùåíî íàçâó ôàéëó ÷è íåêîðåêòíèé øàáëîí"
-
-#: ../quickfix.c:2911
-#, c-format
-msgid "Cannot open file \"%s\""
-msgstr "Íå âäàëîñÿ â³äêðèòè ôàéë «%s»"
-
-#: ../quickfix.c:3429
-msgid "E681: Buffer is not loaded"
-msgstr "E681: Áóôåð íå çàâàíòàæåíî"
-
-#: ../quickfix.c:3487
-msgid "E777: String or List expected"
-msgstr "E777: Î÷³êóºòüñÿ String ÷è List"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: Íåêîðåêòíèé åëåìåíò ó %s%%[]"
-
-#: ../regexp.c:374
-#, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E769: Áðàêóº ] ï³ñëÿ %s["
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: Íåìຠïàðè %s%%("
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: Íåìຠïàðè %s("
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: Íåìຠïàðè %s)"
-
-# msgstr "E406: "
-#: ../regexp.c:378
-msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( òóò íå äîçâîëåíî"
-
-# msgstr "E406: "
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 òà ³í. òóò íå äîçâîëåíî"
-
-#: ../regexp.c:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: Ïðîïóùåíî ] ï³ñëÿ %s%%["
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: %s%%[] ïîðîæí³é"
-
-# msgstr "E382: "
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: Çðàçîê çàíàäòî äîâãèé"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: Çàáàãàòî \\z("
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: Çàáàãàòî %s("
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: Íåìຠïàðè \\z("
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: Íåäîçâîëåíèé ñèìâîë ï³ñëÿ %s@"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: Çàáàãàòî ñêëàäíèõ %s{...}"
-
-# msgstr "E339: "
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: Âêëàäåí³ %s*"
-
-# msgstr "E61: "
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: Âêëàäåí³ %s%c"
-
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: Íåêîðåêòíî âæèòî \\_"
-
-# msgstr "E62: "
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: ϳñëÿ %s%c í³÷îãî íåìàº"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: Íåêîðåêòíå çâîðîòíº ïîñèëàííÿ"
-
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: Íåïðàâèëüíèé ñèìâîë ï³ñëÿ \\z"
-
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: Íåäîçâîëåíèé ñèìâîë ï³ñëÿ %s%%[dxouU]"
-
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: Íåäîçâîëåíèé ñèìâîë ï³ñëÿ %s%%"
-
-# msgstr "E64: "
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: Ñèíòàêñè÷íà ïîìèëêà â %s{...}"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "Çîâí³øí³ ï³ä-çá³ãè:\n"
-
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-"E864: ï³ñëÿ \\%#= ìîæå áóòè ò³ëüêè 0, 1, or 2. Áóäå âèêîðèñòàíî àâòîìàòè÷íèé "
-"ìåõàí³çì "
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr "E865: (NFA) Çàðàíî òðàïèâñÿ ê³íåöü ðåãóëÿðíîãî âèðàçó"
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr "E866: (NFA regexp) Íå íà ì³ñö³ %c"
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr "E867: (NFA) Íåâ³äîìèé îïåðàòîð '\\z%c'"
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) Íåâ³äîìèé îïåðàòîð '\\%%%c'"
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr "E869: (NFA) Íåâ³äîìèé îïåðàòîð '\\@%c'"
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr "E870: (NFA regexp) Íå âäàëîñÿ ïðî÷èòàòè ìåæ³ ïîâòîðåííÿ"
-
-#. 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) Ìóëüòè íå ìîæå áóòè çà ìóëüòè!"
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr "E872: (NFA regexp) Çàáàãàòî '('"
-
-#: ../regexp_nfa.c:2042
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E879: (NFA regexp) Çàáàãàòî \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr "E873: (NFA regexp) ïîìèëêà íàëåæíîãî ïðèïèíåííÿ"
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr "E874: (NFA) Ñòåê ïîðîæí³é!"
-
-#: ../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) çàëèøèëîñÿ "
-"çàáàãàòî ñòàí³â ó ñòåêó"
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr "E876: (NFA regexp) Íåäîñòàòíüî ïàì’ÿò³, ùîá çáåðåãòè âåñü NFA "
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"Íå âäàëîñÿ â³äêðèòè òèì÷àñîâèé ôàéë æóðíàëó äëÿ çàïèñó, ïîêàçóºòüñÿ íà "
-"stderr ... "
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) ÍÅ ÂÄÀËÎÑß Â²ÄÊÐÈÒÈ %s!"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "Íå âäàëîñÿ â³äêðèòè òèì÷àñîâèé ôàéë æóðíàëó äëÿ çàïèñó "
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " ²ÐÒ ÇÀ̲ÍÀ"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " ÇÀ̲ÍÀ"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " ÍÀÂÈÂÎвÒ"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " ÂÑÒÀÂÊÀ"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (âñòàâêà)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (çàì³íà)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (â³ðò çàì³íà)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " ²âðèò"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " Àðàáñüêà"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (ìîâà)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (êëåé)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " ÂÈÁ²Ð"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " ÂÈÁ²Ð ÐßÄʲÂ"
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " ÂÈÁ²Ð ÁËÎÊÓ"
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " ÂÈIJËÅÍÍß"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " ÂÈIJËÅÍÍß ÐßÄʲÂ"
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " ÂÈIJËÅÍÍß ÁËÎÊÓ"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "éäå çàïèñ"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: Íåïðàâèëüíèé çðàçîê äëÿ ïîøóêó: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: Ïîøóê ä³éøîâ äî ÏÎ×ÀÒÊÓ áåç çá³ã³â ç %s"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: Ïîøóê ä³éøîâ äî ʲÍÖß áåç çá³ã³â ç %s"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: ϳñëÿ `;' ìຠáóòè `?' àáî `/'"
-
-# msgstr "E386: "
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (ðàçîì ç ïîïåðåäí³ìè çá³ãàìè)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- Âêëþ÷åí³ ôàéëè "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "íå çíàéäåíî "
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "ó øëÿõó ïîøóêó ---\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (Óæå ó ñïèñêó)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " ÍÅ ÇÍÀÉÄÅÍÎ"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "Ïîøóê ó âêëþ÷åíîìó ôàéë³: %s"
-
-#: ../search.c:4216
-#, c-format
-msgid "Searching included file %s"
-msgstr "Øóêàºòüñÿ ó âêëþ÷åíîìó ôàéë³ %s"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: Çá³ã ó ïîòî÷íîìó ðÿäêó"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "Áóëè çíàéäåí³ âñ³ âêëþ÷åí³ ôàéëè"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "Æîäíîãî âêëþ÷åíîãî ôàéëó"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: Âèçíà÷åííÿ íå çíàéäåíî"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: Çðàçîê íå çíàéäåíî"
-
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Çàì³íà "
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-"\n"
-"# Îñò. %sÇðàçîê ïîøóêó:\n"
-"~"
-
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: Ïîìèëêà ôîðìàòó ó ôàéë³ îðôîãðàô³¿"
-
-# msgstr "E364: "
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr "E758: Îá³ðâàíèé ôàéë îðôîãðàô³¿"
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr "Çàéâèé òåêñò ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:954
-#, c-format
-msgid "Affix name too long in %s line %d: %s"
-msgstr "Íàçâà àô³êñó çàâåëèêà ó %s ó ðÿäêó %d: %s"
-
-# msgstr "E430: "
-#: ../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
-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» ÷è «%s.ascii.spl»"
-
-#: ../spell.c:2473
-#, c-format
-msgid "Reading spell file \"%s\""
-msgstr "×èòàºòüñÿ ôàéë îðôîãðàô³¿ «%s»"
-
-#: ../spell.c:2496
-msgid "E757: This does not look like a spell file"
-msgstr "E757: Íå ñõîæå íà ôàéë îðôîãðàô³¿"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: Ôàéë îðôîãðàô³¿ ñòàðèé, òðåáà ïîíîâèòè"
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr "E772: Ôàéë îðôîãðàô³¿ ïðèçíà÷åíèé äëÿ á³ëüø íîâî¿ âåðñ³¿ Vim"
-
-#: ../spell.c:2602
-msgid "E770: Unsupported section in spell file"
-msgstr "E770: Íåäîçâîëåíà ñåêö³ÿ ó ôàéë³ îðôîãðàô³¿"
-
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "Çàñòåðåæåííÿ: ðåã³îí %s íå ï³äòðèìóºòüñÿ"
-
-#: ../spell.c:4550
-#, c-format
-msgid "Reading affix file %s ..."
-msgstr "×èòàºòüñÿ ôàéë àô³êñ³â %s ..."
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr "Ïîìèëêà ïåðåòâîðåííÿ ñëîâà ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr "Ïåðåòâîðåííÿ ó %s íå ï³äòðèìóºòüñÿ: ç %s äî %s"
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "Íåêîðåêòíå çíà÷åííÿ FLAG ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr "FLAG ï³ñëÿ âèêîðèñòàííÿ ïðàïîðö³â ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"Âèçíà÷åííÿ COMPOUNDFORBIDFLAG ï³ñëÿ åëåìåíòó PFX ìîæå äàòè íåïðàâèëüíèé "
-"ðåçóëüòàò ó %s ó ðÿäêó %d"
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-"Âèçíà÷åííÿ COMPOUNDPERMITFLAG ï³ñëÿ åëåìåíòó PFX ìîæó äàòè íåïðàâèëüíèé "
-"ðåçóëüòàò ó %s ó ðÿäêó %d"
-
-#: ../spell.c:4747
-#, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "Íåïðàâèëüíå çíà÷åííÿ COMPOUNDRULES ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "Íåïðàâèëüíå çíà÷åííÿ COMPOUNDWORDMAX ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "Íåïðàâèëüíå çíà÷åííÿ COMPOUNDMIN ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "Íåïðàâèëüíå çíà÷åííÿ COMPOUNDSYLMAX ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "Íåïðàâèëüíå çíà÷åííÿ CHECKCOMPOUNDPATTERN ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr ""
-"²íøèé ïðàïîðåöü êîìá³íàö³¿ ó ïðîäîâæåíí³ áëîêó àô³êñ³â ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4850
-#, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "Ïîäâ³éíèé àô³êñ ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-"Àô³êñ òàêîæ âèêîðèñòîâóºòüñÿ äëÿ BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
-"NOSUGGEST ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr "Òðåáà Y ÷è N ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr "Íåïðèäàòíà óìîâà ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr "Òðåáà ê³ëüê³ñòü REP(SAL) ó %s ó ðÿäêó %d"
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr "Òðåáà ê³ëüê³ñòü MAP ó %s ó ðÿäêó %d"
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr "Ïîâòîðåííÿ ñèìâîëó ó MAP ó %s ó ðÿäêó %d"
-
-#: ../spell.c:5176
-#, 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 "Ïðîïóùåíî ðÿäîê FOL/LOW/UPP ó %s"
-
-#: ../spell.c:5220
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr "Âæèòî COMPOUNDSYLMAX áåç SYLLABLE"
-
-#: ../spell.c:5236
-msgid "Too many postponed prefixes"
-msgstr "Çàáàãàòî â³äêëàäåíèõ ïðåô³êñ³â"
-
-#: ../spell.c:5238
-msgid "Too many compound flags"
-msgstr "Çàáàãàòî ñêëàäíèõ ïðàïîðö³â"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr "Çàáàãàòî â³äêëàäåíèõ ïðåô³êñ³â ³/àáî ñêëàäíèõ ïðàïîðö³â"
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr "Ïðîïóùåíî ðÿäîê SOFO%s ó %s"
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr "Îáèäâà ðÿäêè SAL ³ SOFO ó %s"
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr "Ïðàïîðåöü íå º ÷èñëîì ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr "Íåïðàâèëüíèé ïðàïîðåöü ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr "Çíà÷åííÿ %s â³äð³çíÿºòüñÿ â³ä òîãî, ùî âæèòî ó ³íøîìó ôàéë³ .aff"
-
-#: ../spell.c:5602
-#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "Ç÷èòóºòüñÿ ñëîâíèêîâèé ôàéë %s ..."
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr "E760: Íåìຠê³ëüêîñò³ ñë³â ó %s"
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "ðÿäîê %6d, ñëîâî %6d - %s"
-
-#: ../spell.c:5691
-#, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "Ïîâòîðåííÿ ñëîâà ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr "Ïåðøå ïîâòîðåííÿ ñëîâà ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr "%d ïîâòîðþâàíèõ ñë³â ó %s"
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr "Ïðîïóùåíî %d ñë³â(~) ³ç íå-ASCII ñèìâîëàìè ó %s"
-
-#: ../spell.c:6115
-#, c-format
-msgid "Reading word file %s ..."
-msgstr "×èòàºòüñÿ ôàéë ñë³â %s ..."
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "Ïîâòîðåííÿ ðÿäêà /encoding= ïðî³ãíîðîâàíî ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "Ðÿäîê /encoding= ï³ñëÿ ñëîâà ïðî³ãíîðîâàíî ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "Ïîâòîðåííÿ ðÿäêà /regions= ïðî³ãíîðîâàíî ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "Çàáàãàòî ðåã³îí³â ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "Ðÿäîê / ïðî³ãíîðîâàíî ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:6224
-#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "Íåêîðåêòíèé íîìåð ðåã³îíó ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "Íåðîçï³çíàí³ ïðàïîðö³ ó %s ó ðÿäêó %d: %s"
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr "Ïðî³ãíîðîâàíî %d ñë³â ³ç íå-ASCII ñèìâîëàìè"
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "Ñòèñíåíî %d ç %d âóçë³â; çàëèøèëîñÿ %d (%d%%)"
-
-#: ../spell.c:7340
-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
-msgid "Performing soundfolding..."
-msgstr "Âèêîíóºòüñÿ çãîðòàííÿ çâóê³â..."
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "ʳëüê³ñòü ñë³â ï³ñëÿ çãîðòàííÿ çâóê³â: %<PRId64>"
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr "Ïîâíà ê³ëüê³ñòü ñë³â: %d"
-
-#: ../spell.c:7655
-#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "Çàïèñóºòüñÿ ôàéë ïðèïóùåíü %s ..."
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr "Îö³íêà ñïîæèâàííÿ ïàì'ÿò³: %d áàéò"
-
-#: ../spell.c:7820
-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: ϳäòðèìóºòüñÿ ò³ëüêè äî âîñüìè ðåã³îí³â"
-
-#: ../spell.c:7846
-#, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E755: Íåêîðåêòíèé ðåã³îí ó %s"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr "Çàñòåðåæåííÿ: çàçíà÷åíî îáèäâà `ñêëàäí³ ñëîâà' ³ NOBREAK"
-
-#: ../spell.c:7920
-#, c-format
-msgid "Writing spell file %s ..."
-msgstr "Çàïèñóºòüñÿ ôàéë îðôîãðàô³¿ %s ..."
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr "Çðîáëåíî!"
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' íå ì³ñòèòü %<PRId64> åëåìåíò³â"
-
-#: ../spell.c:8074
-#, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "Ñëîâî '%.*s' çíèùåíî ç %s"
-
-#: ../spell.c:8117
-#, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "Ñëîâî '%.*s' äîäàíî äî %s"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: Ñèìâîëè ó ñëîâ³ â³äð³çíÿþòüñÿ ó ôàéëàõ îðôîãðàô³¿"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Ïðîáà÷òå, íåìຠïðîïîçèö³é"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Ïðîáà÷òå, ò³ëüêè %<PRId64> ïðîïîçèö³é"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Çàì³íèòè «%.*s» íà:"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < «%.*s»"
-
-# msgstr "E34: "
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Íåìຠïîïåðåäíüî¿ çàì³íè"
-
-# msgstr "E333: "
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Íå çíàéäåíî: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Íå ñõîæå íà ôàéë .sug: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: Çàñòàð³ëèé ôàéë .sug, òðåáà ïîíîâèòè: %s"
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Ôàéë .sug äëÿ á³ëüø íîâî¿ âåðñ³¿ Vim: %s"
-
-#: ../spell.c:9295
-#, 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: %s"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: Ïîâòîðåíî ñèìâîë ó åëåìåíò³ MAP"
-
-# msgstr "E391: "
-#: ../syntax.c:266
-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:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: Íåìຠòàêîãî ñèíòàêñè÷íîãî êëàñòåðà: %s"
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "ñèíõðîí³çóºòüñÿ ïî êîìåíòàðÿõ ñòèëþ Ñ"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "áåç ñèíõðîí³çàö³¿"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "ïî÷èíàºòüñÿ ñèíõðîí³çàö³ÿ çà "
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr " ðÿäê³â ïåðåä ïåðøèì ðÿäêîì"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- Åëåìåíòè ñèíõðîí³çàö³¿ ñèíòàêñèñó ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"ñèíõðîí³çàö³ÿ ïî åëåìåíòàõ"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- Åëåìåíòè ñèíòàêñèñó ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: Íåìຠòàêîãî ñèíòàêñè÷íîãî êëàñòåðà: %s"
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "ì³í³ìàëüíèé "
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "ìàêñèìàëüíèé "
-
-#: ../syntax.c:3513
-msgid "; match "
-msgstr "; çá³ã "
-
-#: ../syntax.c:3515
-msgid " line breaks"
-msgstr " ðîçðèâè ðÿäê³â"
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: ̳ñòèòü íåïðèéíÿòí³ òóò àðãóìåíòè"
-
-# msgstr "E14: "
-#: ../syntax.c:4096
-msgid "E844: invalid cchar value"
-msgstr "E844: Íåêîðåêòíå çíà÷åííÿ cchar"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: group[t]hete òóò íåïðèéíÿòíèé"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: Íå çíàéäåíî åëåìåíò ðåã³îíó äëÿ %s"
-
-# msgstr "E396: "
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: Ïîòð³áíà íàçâà ôàéëó"
-
-#: ../syntax.c:4221
-msgid "E847: Too many syntax includes"
-msgstr "E847: Çàáàãàòî ñèíòàêñè÷íèõ âêëþ÷åíü"
-
-#: ../syntax.c:4303
-#, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E789: Ïðîïóùåíî ']': %s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: Ïðîïóùåíî `=': %s"
-
-# ---------------------------------------
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: Áðàêóº àðãóìåíò³â: ñèíòàêñè÷íèé ðåã³îí %s"
-
-#: ../syntax.c:4870
-msgid "E848: Too many syntax clusters"
-msgstr "E848: Çàáàãàòî ñèíòàêñè÷íèõ êëàñòåð³â"
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: Êëàñòåð íå âêàçàíî"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: ʳíåöü çðàçêó íå çíàéäåíî: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: Ñì³òòÿ ï³ñëÿ çðàçêó: %s"
-
-# msgstr "E402: "
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr ""
-"E403: Ñèíòàêñè÷íà ñèíõðîí³çàö³ÿ: çðàçîê äëÿ ïðîäîâæåííÿ ðÿäêà âêàçàíî äâ³÷³"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: Íåïðàâèëüí³ àðãóìåíòè: %s"
-
-# msgstr "E404: "
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: Ïðîïóùåíî çíàê ð³âíîñò³: %s"
-
-# msgstr "E405: "
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: Ïîðîæí³é àðãóìåíò: %s"
-
-# msgstr "E406: "
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %s òóò íå äîçâîëåíî"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %s ìຠáóòè ïåðøèì ðÿäêîì ó ñïèñêó contains"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: Íåâ³äîìà íàçâà ãðóïè: %s"
-
-# msgstr "E409: "
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: Íåïðàâèëüíà ï³äêîìàíäà :syntax: %s"
-
-#: ../syntax.c:5854
-msgid ""
-" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-msgstr ""
-" ÂÑÜÎÃÎ Ê-ÒÜ ÑϲÂÏ. ÍÀÉÏβË. ÑÅÐÅÄÍ. ÍÀÇÂÀ ØÀÁËÎÍ"
-
-#: ../syntax.c:6146
-msgid "E679: recursive loop loading syncolor.vim"
-msgstr "E679: Ðåêóðñèâíèé öèêë ÷èòàííÿ syncolor.vim"
-
-# msgstr "E410: "
-#: ../syntax.c:6256
-#, c-format
-msgid "E411: highlight group not found: %s"
-msgstr "E411: Ãðóïó ï³äñâ³÷óâàííÿ íå çíàéäåíî: %s"
-
-# msgstr "E411: "
-#: ../syntax.c:6278
-#, c-format
-msgid "E412: Not enough arguments: \":highlight link %s\""
-msgstr "E412: Íåäîñòàòíüî àðãóìåíò³â: «:highlight link %s»"
-
-# msgstr "E412: "
-#: ../syntax.c:6284
-#, c-format
-msgid "E413: Too many arguments: \":highlight link %s\""
-msgstr "E413: Çàáàãàòî àðãóìåíò³â: «:highlight link %s»"
-
-# msgstr "E413: "
-#: ../syntax.c:6302
-msgid "E414: group has settings, highlight link ignored"
-msgstr "E414: Ãðóìà ìຠsettings, highlight link ïðî³ãíîðîâàíî"
-
-# msgstr "E414: "
-#: ../syntax.c:6367
-#, c-format
-msgid "E415: unexpected equal sign: %s"
-msgstr "E415: Íåñïîä³âàíèé çíàê ð³âíîñò³: %s"
-
-# msgstr "E415: "
-#: ../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"
-
-# msgstr "E418: "
-#: ../syntax.c:6496
-msgid "E419: FG color unknown"
-msgstr "E419: Íåâ³äîìèé êîë³ð òåêñòó"
-
-# msgstr "E419: "
-#: ../syntax.c:6504
-msgid "E420: BG color unknown"
-msgstr "E420: Íåâ³äîìèé êîë³ð ôîíó"
-
-# msgstr "E420: "
-#: ../syntax.c:6564
-#, c-format
-msgid "E421: Color name or number not recognized: %s"
-msgstr "E421: Íåðîçï³çíàíà íàçâà àáî íîìåð êîëüîðó: %s"
-
-# msgstr "E421: "
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: Çàíàäòî äîâãèé êîä òåðì³íàëó: %s"
-
-# msgstr "E422: "
-#: ../syntax.c:6753
-#, c-format
-msgid "E423: Illegal argument: %s"
-msgstr "E423: Íåïðàâèëüíèé àðãóìåíò: %s"
-
-# msgstr "E423: "
-#: ../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: Íåäðóêîâíèé ñèìâîë ó íàçâ³ ãðóïè"
-
-# msgstr "E181: "
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: Íåêîðåêòíèé ñèìâîë ó íàçâ³ ãðóïè"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr "E849: Çàáàãàòî ãðóï ï³äñâ³÷óâàííÿ ³ ñèíòàêñèñó"
-
-# msgstr "E424: "
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: ʳíåöü ñòåêó òå´³â"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: Âåðøèíà ñòåêó òå´³â"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Öå âæå íàéïåðøèé â³äïîâ³äíèé òå´"
-
-# msgstr "E425: "
-#: ../tag.c:504
-#, c-format
-msgid "E426: tag not found: %s"
-msgstr "E426: Òå´ íå çíàéäåíî: %s"
-
-# msgstr "E426: "
-#: ../tag.c:528
-msgid " # pri kind tag"
-msgstr " # ïð³ òèï òå´"
-
-#: ../tag.c:531
-msgid "file\n"
-msgstr "ôàéë\n"
-
-#: ../tag.c:829
-msgid "E427: There is only one matching tag"
-msgstr "E427: Ëèøå îäèí â³äïîâ³äíèé òå´"
-
-# msgstr "E427: "
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: Öå âæå îñòàíí³é â³äïîâ³äíèé òå´"
-
-# msgstr "E428: "
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "Ôàéë «%s» íå ³ñíóº"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "òå´ %d ç %d%s"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " àáî á³ëüøå"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " Âèêîðèñòàíî òå´, íå ðîçð³çíÿþ÷è âåëèê³ é ìàë³ ë³òåðè"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: Ôàéë «%s» íå ³ñíóº"
-
-# msgstr "E429: "
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # ÄÎ òå´ó Ç ðÿäêà ó ôàéë³/òåêñò³"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "Øóêàºòüñÿ ó ôàéë³ òå´³â %s"
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr "²ãíîðóºòüñÿ äîâãèé ðÿäîê ó ôàéë³ ç ïîçíà÷êàìè"
-
-# msgstr "E430: "
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: Ïîìèëêà ôîðìàòó ó ôàéë³ ò崳⠫%s»"
-
-# msgstr "E431: "
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "Ïåðåä áàéòîì %<PRId64>"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Ôàéë òå´³â íå âïîðÿäêîâàíèé: %s"
-
-# msgstr "E432: "
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: Íåìຠôàéëó òå´³â"
-
-# msgstr "E433: "
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: Íå âäàëîñÿ çíàéòè çðàçîê òå´ó"
-
-# msgstr "E434: "
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: Íå âäàëîñÿ çíàéòè òå´, ò³ëüêè ïðèïóùåííÿ!"
-
-#: ../tag.c:2797
-#, c-format
-msgid "Duplicate field name: %s"
-msgstr "Íàçâà ïîëÿ ïîâòîðþºòüñÿ: %s"
-
-# msgstr "E435: "
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' íå â³äîìèé. Âáóäîâàí³ òåðì³íàëè:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "ïî÷àòêîâî '"
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: Íå âäàëîñÿ â³äêðèòè ôàéë ìîæëèâîñòåé òåðì³íàë³â"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: Íåìຠ³íôîðìàö³¿ ïðî òåðì³íàë"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: Íåìຠ³íôîðìàö³¿ ïðî ìîæëèâîñò³ òåðì³íàëó"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: Íåìຠçàïèñó «%s» ïðî ìîæëèâîñò³ òåðì³íàëó"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: Ïîòð³áíà ìîæëèâ³ñòü òåðì³íàëó «cm»"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Êëàâ³ø³ òåðì³íàëó ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: Ïîìèëêà ÷èòàííÿ ââîäó, ðîáîòà çàâåðøóºòüñÿ...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
-msgid "E881: Line count changed unexpectedly"
-msgstr "E834: ʳëüê³ñòü ðÿäê³â íåñïîä³âàíî çì³íèëàñÿ"
-
-#: ../undo.c:627
-#, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E828: Íå âäàëîñÿ â³äêðèòè ôàéë ³ñòî𳿠äëÿ çàïèñó: %s"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr "E825: Ôàéë ³ñòî𳿠ïîøêîäæåíî (%s): %s"
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr "Íå âäàëîñÿ çàïèñàòè ôàéë ³ñòî𳿠ó æîäíó ç äèðåêòîð³é ó 'undodir'"
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr "Will not overwrite with undo file, cannot read: %s"
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr "Íå ìîæíà ïåðåçàïèñàòè, öå íå ôàéë ³ñòîð³¿: %s"
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr "Ôàéë ³ñòî𳿠íå çàïèñóºòüñÿ, í³÷îãî ïîâåðòàòè"
-
-#: ../undo.c:1121
-#, c-format
-msgid "Writing undo file: %s"
-msgstr "Çàïèñóºòüñÿ ôàéë ³ñòîð³¿: %s"
-
-#: ../undo.c:1213
-#, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E829: Ïîìèëêà çàïèñó ó ôàéë³ ³ñòîð³¿: %s"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr "Ôàéë ³ñòî𳿠ïðî÷èòàíî íå áóäå, âëàñíèê ³íøèé: %s"
-
-#: ../undo.c:1292
-#, c-format
-msgid "Reading undo file: %s"
-msgstr "×èòàºòüñÿ ôàéë ³ñòîð³¿: %s"
-
-#: ../undo.c:1299
-#, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E822: Íå âäàëîñÿ â³äêðèòè ôàéë äëÿ ÷èòàííÿ: %s"
-
-# msgstr "E333: "
-#: ../undo.c:1308
-#, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E823: Íå ôàéë ³ñòîð³¿: %s"
-
-#: ../undo.c:1313
-#, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E824: Íåñóì³ñíèé ôàéë ³ñòîð³¿: %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr "Âì³ñò ôàéëó çì³íèâñÿ, íå ìîæíà âèêîðèñòàòè ³íôîðìàö³þ ïðî ³ñòîð³þ"
-
-#: ../undo.c:1497
-#, c-format
-msgid "Finished reading undo file %s"
-msgstr "Çàê³í÷åíî ÷èòàííÿ ôàéëó ³ñòî𳿠%s"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr "Âæå íà íàéñòàðø³é çì³í³"
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr "Âæå íà íàéíîâ³ø³é çì³í³"
-
-#: ../undo.c:1806
-#, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E830: Çì³íó %<PRId64> íå çíàéäåíî â ³ñòîð³¿"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: íåïðàâèëüí³ íîìåðè ðÿäê³â"
-
-#: ../undo.c:2183
-msgid "more line"
-msgstr "äîäàíî ðÿäîê"
-
-#: ../undo.c:2185
-msgid "more lines"
-msgstr "ðÿäê³â äîäàíî"
-
-#: ../undo.c:2187
-msgid "line less"
-msgstr "çíèùåíî ðÿäîê"
-
-#: ../undo.c:2189
-msgid "fewer lines"
-msgstr "ðÿäê³â çíèùåíî"
-
-# msgstr "E438: "
-#: ../undo.c:2193
-msgid "change"
-msgstr "çì³íà"
-
-# msgstr "E438: "
-#: ../undo.c:2195
-msgid "changes"
-msgstr "çì³í"
-
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s; %s #%<PRId64> %s"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr "ïåðåä"
-
-#: ../undo.c:2228
-msgid "after"
-msgstr "ï³ñëÿ"
-
-#: ../undo.c:2325
-msgid "Nothing to undo"
-msgstr "Íåìຠí³÷îãî ñêàñîâóâàòè"
-
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr "íîìåð çì³íè ÷àñ çáåðåæåíî"
-
-#: ../undo.c:2360
-#, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> ñåêóíä òîìó"
-
-# msgstr "E406: "
-#: ../undo.c:2372
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E790: Íå ìîæíà âèêîíàòè undojoin ï³ñëÿ undo"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: Ñïèñîê ñêàñóâàííÿ ïîøêîäæåíî"
-
-# msgstr "E439: "
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: ³äñóòí³é ðÿäîê ñêàñóâàííÿ"
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Âêëþ÷åí³ ëàòêè: "
-
-#: ../version.c:627
-msgid ""
-"\n"
-"Extra patches: "
-msgstr ""
-"\n"
-"Äîäàòêîâ³ ëàòêè: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Çì³íèâ "
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"Ñêîìï³ëþâàâ "
-
-#: ../version.c:649
-msgid "by "
-msgstr " "
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"óãàíòñüêà âåðñ³ÿ "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "áåç GUI."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " Âêëþ÷åí³ (+) àáî íå âêëþ÷åí³ (-) êîìïîíåíòè:\n"
-
-#: ../version.c:667
-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
-msgid " fall-back for $VIM: \""
-msgstr " çàì³íà äëÿ $VIM: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr " çàì³íà äëÿ $VIMRUNTIME: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "Ñêîìï³ëüîâàíî: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Ñêîìïîíîâàíî: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " ÂÅÐÑ²ß ÄËß ÍÀËÀÃÎÄÆÅÍÍß"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Ïîêðàùåíèé Vi"
-
-#: ../version.c:769
-msgid "version "
-msgstr "âåðñ³ÿ "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "àâòîð: Bram Moolenaar òà ³í."
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim — öå â³äêðèòà é â³ëüíî ðîçïîâñþäæóâàíà ïðîãðàìà"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "Äîïîìîæ³òü ñèðîòàì ç Óãàíäè!"
-
-#: ../version.c:777
-msgid "type :help iccf<Enter> for information "
-msgstr ":help iccf<Enter> ïîäðîáèö³ "
-
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr ":q<Enter> âèõ³ä ç Vim "
-
-#: ../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> ðåæèì íåñóì³ñíèé ç Vi "
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr ":help cp-default<Enter> ³íôîðìàö³ÿ ïðî ñóì³ñí³ñòü"
-
-#: ../version.c:827
-msgid "Sponsor Vim development!"
-msgstr "ϳäòðèìàéòå ðîçðîáêó ðåäàêòîðà Vim!"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "Ñòàíüòå çàðåºñòðîâàíèì êîðèñòóâà÷åì Vim!"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr ":help sponsor<Enter> ïîäàëüøà ³íôîðìàö³ÿ "
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr ":help register<Enter> ïîäàëüøà ³íôîðìàö³ÿ "
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "ìåíþ Äîïîìîãà->Ñïîíñîð/Ðåºñòðàö³ÿ ïîäðîáèö³ "
-
-# msgstr "E444: "
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "Öå âæå ºäèíå â³êíî"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: Íåìຠâ³êíà ïåðåãëÿäó"
-
-# msgstr "E441: "
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: Íå âäàëîñÿ îäíî÷àñíî ðîçáèòè topleft ³ botright"
-
-# msgstr "E442: "
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: Íå âäàëîñÿ ïåðåì³ñòèòè â³êíî, çàâàæàþòü ³íø³"
-
-# msgstr "E443: "
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: Íå âäàëîñÿ çàêðèòè îñòàííº â³êíî"
-
-# msgstr "E443: "
-#: ../window.c:1810
-msgid "E813: Cannot close autocmd window"
-msgstr "E813: Íå âäàëîñÿ çàêðèòè â³êíî autocmd"
-
-# msgstr "E443: "
-#: ../window.c:1814
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: Íå âäàëîñÿ çàêðèòè â³êíî, çàëèøèëîñÿ á ò³ëüêè â³êíî autocmd"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: Ó ³íøîìó â³êí³ º çì³íè"
-
-# msgstr "E445: "
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: Íåìຠíàçâè ôàéëó íàä êóðñîðîì"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: Âèêëèêàíî bf_key_init() ç ïîðîæí³ì ïàðîëåì"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Íåïðàâèëüíå âèêîðèñòàííÿ ïîðÿäêó áàéò³â Blowfish (BE/LE)"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: Íå ïðîéøëà ïåðåâ³ðêà sha256"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Íå ïðîéøëà ïåðåâ³ðêà Blowfish"
-
-#~ msgid "Patch file"
-#~ msgstr "Ëàòêà"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&O:Ãàðàçä\n"
-#~ "&C:Ñêàñóâàòè"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Íåìຠç'ºäíàííÿ ³ç ñåðâåðîì Vim"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Íå âäàëîñÿ â³ä³ñëàòè äî %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Íå âäàëîñÿ ïðî÷èòàòè â³äïîâ³äü ñåðâåðà"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Íå âäàëîñÿ íàä³ñëàòè ê볺íòó"
-
-#~ msgid "Save As"
-#~ msgstr "Çáåðåãòè ÿê"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Ïðî÷èòàòè ñêðèïò Vim"
-
-#~ msgid "Edit File"
-#~ msgstr "Ðåäàãóâàòè Ôàéë"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (ÍÅ ÇÍÀÉÄÅÍÎ)"
-
-#~ msgid "unknown"
-#~ msgstr "Íåâ³äîìî"
-
-# msgstr "E185: "
-#~ msgid "Edit File in new window"
-#~ msgstr "Ðåäàãóâàòè ôàéë ó íîâîìó â³êí³"
-
-#~ msgid "Append File"
-#~ msgstr "Äîïèñàòè ôàéë"
-
-# msgstr "E187: "
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "Ïîçèö³ÿ â³êíà: X %d, Y %d"
-
-# msgstr "E188: "
-#~ msgid "Save Redirection"
-#~ msgstr "Çáåðåãòè ïåðåàäðåñîâàíèé âèâ³ä"
-
-#~ msgid "Save View"
-#~ msgstr "Çáåðåãòè âèãëÿä"
-
-#~ msgid "Save Session"
-#~ msgstr "Çáåðåãòè ñåàíñ"
-
-#~ msgid "Save Setup"
-#~ msgstr "Çáåðåãòè íàëàøòóâàííÿ"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< íå äîñòóïíà áåç ìîæëèâîñò³ +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: Ó ö³é âåðñ³¿ íåìຠäèãðàô³â"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "º ïðèñòðîºì (âèìêíåíî îïö³ºþ 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "×èòàºòüñÿ ç stdin..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfish]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[çàøèôðîâàíî]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Ôàéë çàøèôðîâàíî íåâ³äîìèì ìåòîäîì"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans íå äîçâîëÿº çàïèñóâàòè ó íåçì³íåí³ áóôåðè"
-
-# msgstr "E391: "
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "×àñòêîâ³ çàïèñè çàáîðîíåí³ äëÿ áóôåð³â NetBeans"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "Çàïèñ äî ïðèñòðîþ çàáîðîíåíî îïö³ºþ 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: óëêó ðåñóðñ³â ìîæíà âòðàòèòè (! ùîá íå çâàæàòè)"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<íå â³äêðèâàºòüñÿ> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: íå âäàëîñÿ îòðèìàòè øðèôò %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: íå âäàëîñÿ ïîâåðíóòèñÿ â ïîòî÷íèé êàòàëîã"
-
-#~ msgid "Pathname:"
-#~ msgstr "Øëÿõ:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: íå âäàëîñÿ îòðèìàòè ïîòî÷íèé êàòàëîã"
-
-#~ msgid "OK"
-#~ msgstr "Ãàðàçä"
-
-#~ msgid "Cancel"
-#~ msgstr "Ñêàñóâàòè"
-
-#~ msgid "Vim dialog"
-#~ msgstr "ijàëîã Vim"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "Scrollbar Widget: Íå âäàëîñÿ âèçíà÷èòè ðîçì³ð ñêîðî÷åíî¿ êàðòèíêè."
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Íå âäàëîñÿ ñòâîðèòè BalloonEval ç ïîâ³äîìëåííÿì ³ ôóíêö³ºþ"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: Íå âäàëîñÿ ñòâîðèòè íîâèé ïðîöåñ äëÿ GUI"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: Äî÷³ðí³é ïðîöåñ íå çì³ã çàïóñòèòè GUI"
-
-# msgstr "E228: "
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Íå âäàëîñÿ çàïóñòèòè GUI"
-
-# msgstr "E229: "
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Íå âäàëîñÿ ïðî÷èòàòè ç «%s»"
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Íå âäàëîñÿ çàïóñòèòè GUI, íå çíàéäåíî øðèôò"
-
-# msgstr "E230: "
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: Íåêîðåêòíèé 'guifontwide'"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Çíà÷åííÿ 'imactivatekey' íåêîðåêòíå"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Íå âäàëîñÿ îòðèìàòè êîë³ð %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Íåìຠíàä êóðñîðîì, ïîøóê òðèâàº"
-
-#~ msgid "Input _Methods"
-#~ msgstr "Ìåòîäè ââåäåííÿ"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Çíàéòè é çàì³íèòè..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Ïîøóê..."
-
-#~ msgid "Find what:"
-#~ msgstr "Çíàéòè:"
-
-#~ msgid "Replace with:"
-#~ msgstr "Çàì³íèòè íà:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Ëèøå ïîâíå ñëîâî"
-
-#~ msgid "Match case"
-#~ msgstr "Çâàæàòè íà ðåã³ñòð"
-
-#~ msgid "Direction"
-#~ msgstr "Íàïðÿì"
-
-#~ msgid "Up"
-#~ msgstr "Âãîðó"
-
-#~ msgid "Down"
-#~ msgstr "Óíèç"
-
-#~ msgid "Find Next"
-#~ msgstr "Íàñòóïíå"
-
-#~ msgid "Replace"
-#~ msgstr "Çàì³íèòè"
-
-#~ msgid "Replace All"
-#~ msgstr "Çàì³íèòè óñ³"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: Îòðèìàâ çàïèò «die» â³ä ìåíåäæåðà ñåñ³é\n"
-
-#~ msgid "Close"
-#~ msgstr "Çàêðèòè"
-
-#~ msgid "New tab"
-#~ msgstr "Íîâà âêëàäêà"
-
-#~ msgid "Open Tab..."
-#~ msgstr "³äêðèòè âêëàäêó..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Íåñïîä³âàíî çíèùèëîñÿ ãîëîâíå â³êíî\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&F:Ô³ëüòðóâàòè"
-
-#~ msgid "&Cancel"
-#~ msgstr "&C:Ñêàñóâàòè"
-
-#~ msgid "Directories"
-#~ msgstr "Êàòàëîãè"
-
-#~ msgid "Filter"
-#~ msgstr "Ô³ëüòð"
-
-#~ msgid "&Help"
-#~ msgstr "&H:Äîïîìîãà"
-
-#~ msgid "Files"
-#~ msgstr "Ôàéëè"
-
-#~ msgid "&OK"
-#~ msgstr "&O:Ãàðàçä"
-
-#~ msgid "Selection"
-#~ msgstr "Âèä³ëåííÿ"
-
-#~ msgid "Find &Next"
-#~ msgstr "&N:Çíàéòè äàë³"
-
-#~ msgid "&Replace"
-#~ msgstr "&R:Çàì³íèòè"
-
-#~ msgid "Replace &All"
-#~ msgstr "&A:Çàì³íèòè óñ³"
-
-#~ msgid "&Undo"
-#~ msgstr "&U:Ñêàñóâàòè"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Íå âäàëîñÿ çíàéòè â³êíî «%s»"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Àðãóìåíò íå ï³äòðèìóºòüñÿ: «-%s»; êîðèñòóéòåñü âåðñ³ºþ ç OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Íå âäàëîñÿ â³äêðèòè â³êíî âñåðåäèí³ ïðîãðàìè MDI"
-
-#~ msgid "Close tab"
-#~ msgstr "Çàêðèòè âêëàäêó"
-
-#~ msgid "Open tab..."
-#~ msgstr "³äêðèòè âêëàäêó..."
-
-# msgstr "E245: "
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Çíàéòè ðÿäîê ('\\\\' ùîá çíàéòè '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Çíàéòè ³ çàì³íèòè ('\\\\' ùîá çíàéòè '\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "Íåìàº"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Êàòàëîã\t*.í³÷îãî\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Íåìຠâ³ëüíèõ êîì³ðîê ó ïàë³òð³, äåÿê³ êîëüîðè ìîæóòü áóòè "
-#~ "íåïðàâèëüí³"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Øðèôòè äëÿ öèõ ñèìâîë³â â³äñóòí³ ó íàáîð³ %s:"
-
-# msgstr "E250: "
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Íàçâà íàáîðó øðèôò³â: %s"
-
-# msgstr "E252: "
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Øðèôò '%s' íå º ìîíîøèðèííèì"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: Íàçâà íàáîðó øðèôò³â: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "Øðèôò0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "Øðèôò1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "Øèðèíà øðèôòó%<PRId64> íå á³ëüøà óäâ³÷³ çà øèðèíó øðèôòó0"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "Øèðèíà øðèôòó0: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "Øèðèíà øðèôòó1: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Íåêîðåêòíà ñïåöèô³êàö³ÿ øðèôòó"
-
-#~ msgid "&Dismiss"
-#~ msgstr "&D:Ïðèïèíèòè"
-
-#~ msgid "no specific match"
-#~ msgstr "íåìຠêîíêðåòíîãî çá³ãó"
-
-# msgstr "E234: "
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - Âèá³ð øðèôòó"
-
-#~ msgid "Name:"
-#~ msgstr "Íàçâà:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Ïîêàçàòè ðîçì³ð ó ïóíêòàõ"
-
-#~ msgid "Encoding:"
-#~ msgstr "Êîäóâàííÿ:"
-
-#~ msgid "Font:"
-#~ msgstr "Øðèôò:"
-
-#~ msgid "Style:"
-#~ msgstr "Ñòèëü:"
-
-#~ msgid "Size:"
-#~ msgstr "Ðîçì³ð:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Ïîìèëêà àâòîìàòó Hangul"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: ïîìèëêà stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: Íå âäàëîñÿ â³äêðèòè áàçó äàíèõ cscope: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: Íå âäàëîñÿ îòðèìàòè ³íôîðìàö³þ ç áàçè äàíèõ cscope"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Íå âäàëîñÿ çàâàíòàæèòè á³áë³îòåêó Lua"
-
-#~ msgid "cannot save undo information"
-#~ msgstr "íå âäàëîñÿ çáåðåãòè ³íôîðìàö³þ äëÿ ñêàñóâàííÿ"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: Âèáà÷òå, öÿ êîìàíäà âèìêíåíà, á³áë³îòåêè MzScheme íå ìîæóòü áóòè "
-#~ "çàâàíòàæåí³."
-
-#~ msgid "invalid expression"
-#~ msgstr "íåêîðåêòíèé âèðàç"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "îáðîáêó âèðàç³â âèìêíåíî ï³ä ÷àñ êîìï³ëÿö³¿"
-
-#~ msgid "hidden option"
-#~ msgstr "ïðèõîâàíà îïö³ÿ"
-
-#~ msgid "unknown option"
-#~ msgstr "íåâ³äîìà îïö³ÿ"
-
-#~ msgid "window index is out of range"
-#~ msgstr "íåêîðåêòíèé íîìåð â³êíà"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "íå âäàëîñÿ â³äêðèòè áóôåð"
-
-#~ msgid "cannot delete line"
-#~ msgstr "íåìîæëèâî çíèùèòè ðÿäîê"
-
-#~ msgid "cannot replace line"
-#~ msgstr "íåìîæëèâî çàì³íèòè ðÿäîê"
-
-#~ msgid "cannot insert line"
-#~ msgstr "íå âäàëîñÿ âñòàâèòè ðÿäîê"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "á³ëüøå í³æ îäèí ðÿäîê"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "íå âäàëîñÿ ïåðåòâîðèòè çíà÷åííÿ Scheme ó Vim"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Ïîìèëêà Vim: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Ïîìèëêà Vim"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "áóôåð íåïðèäàòíèé"
-
-#~ msgid "window is invalid"
-#~ msgstr "â³êíî íåïðèäàòíå"
-
-#~ msgid "linenr out of range"
-#~ msgstr "íîìåð ðÿäêà çà ìåæàìè ôàéëó"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "íå äîçâîëåíî ó ï³ñî÷íèö³ Vim"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: Python: Íå ìîæíà âèêîðèñòàòè :py ³ :py3 â îäíîìó ñåàíñ³"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: Âèáà÷òå, öÿ êîìàíäà âèìêíåíà, á³áë³îòåêà Python íå ìîæå áóòè "
-#~ "çàâàíòàæåíà."
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: Python: Íå ìîæíà âèêîðèñòàòè :py ³ :py3 â îäíîìó ñåàíñ³"
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Íå ìîæíà ðåêóðñèâíî âèêëèêàòè Python"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ ìຠáóòè åêçåìïëÿðîì String"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Âèáà÷òå, öÿ êîìàíäà âèìêíåíà, á³áë³îòåêà Ruby íå ìîæå áóòè "
-#~ "çàâàíòàæåíà."
-
-# msgstr "E414: "
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: íåñïîä³âàíèé return"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: íåñïîä³âàíèé next"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: íåñïîä³âàíèé break"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: íåñïîä³âàíèé redo"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: retry ïîçà rescue"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: Íåîáðîáëåíèé âèíÿòîê"
-
-# msgstr "E233: "
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: Íåâ³äîìèé ñòàòóñ longjmp: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Ïåðåìêíóòè ðåàë³çàö³þ/âèçíà÷åííÿ"
-
-#~ msgid "Show base class of"
-#~ msgstr "Çíàéòè áàçîâèé êëàñ"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Ïîêàçàòè çàì³íåí³ ôóíêö³¿-÷ëåíè"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Ïðî÷èòàòè ç ôàéëó"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Îòðèìàòè ç ïðîåêòó"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Îòðèìàòè ç óñ³õ ïðîåêò³â"
-
-#~ msgid "Retrieve"
-#~ msgstr "Îòðèìàòè"
-
-#~ msgid "Show source of"
-#~ msgstr "Äæåðåëî"
-
-#~ msgid "Find symbol"
-#~ msgstr "Çíàéòè ñèìâîë"
-
-#~ msgid "Browse class"
-#~ msgstr "Ïåðåãëÿíóòè êëàñ"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Ïîêàçàòè êëàñ â ³ºðàðõ³¿"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Ïîêàçàòè êëàñ â îáìåæåí³é ³ºðàðõ³¿"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref âêàçóº íà"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Íà Xref âêàçàíî ç"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ìàº"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref âèêîðèñòàíî"
-
-#~ msgid "Show docu of"
-#~ msgstr "Ïîêàçàòè docu"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Ñòâîðèòè docu äëÿ"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Íå âäàëîñÿ ç'ºäíàòèñÿ ç³ SNiFF+. Ïåðåâ³ðòå îòî÷åííÿ (sniffemacs ìຠáóòè "
-#~ "ó $PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Ïîìèëêà ï³ä ÷àñ ÷èòàííÿ. ³ä'ºäíàíî"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ çàðàç "
-
-#~ msgid "not "
-#~ msgstr "íå "
-
-#~ msgid "connected"
-#~ msgstr "ï³ä'ºäíàíèé"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Íåâ³äîìèé çàïèò äî SNiFF+: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Ïîìèëêà ç'ºäíàííÿ äî SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ íå ï³ä'ºäíàíî"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Íå º áóôåðîì SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: Ïîìèëêà çàïèñó. ³ä'ºäíàíî"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "íåïðàâèëüíà íàçâà áóôåðà"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ùå íå ðåàë³çîâàíî"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "íå âäàëîñÿ âñòàíîâèòè ðÿäêè"
-
-#~ msgid "invalid mark name"
-#~ msgstr "íåïðàâèëüíà íàçâà ïîçíà÷êè"
-
-# msgstr "E19: "
-#~ msgid "mark not set"
-#~ msgstr "ïîì³òêó íå âêàçàíî"
-
-#~ msgid "row %d column %d"
-#~ msgstr "ðÿäîê %d êîëîíêà %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "Íå âäàëîñÿ âñòàâèòè/äîäàòè ðÿäîê"
-
-#~ msgid "line number out of range"
-#~ msgstr "íîìåð ðÿäêà çà ìåæàìè ôàéëó"
-
-#~ msgid "unknown flag: "
-#~ msgstr "íåâ³äîìèé ïðàïîðåöü: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "Íåâ³äîìà vimOption"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "ïåðåðâàíî ç êëàâ³àòóðè"
-
-#~ msgid "vim error"
-#~ msgstr "ïîìèëêà Vim"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "íå âäàëîñÿ ñòâîðèòè êîìàíäó â³êíà/áóôåðà: îá'ºêò çíèùóºòüñÿ"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "Íå âäàëîñÿ çàðåºñòðóâàòè ïîä³þ: áóôåð/â³êíî óæå çíèùóºòüñÿ"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: ÔÀÒÀËÜÍÀ ÏÎÌÈËÊÀ TCL: ìîæëèâî ïîøêîäæåíî ñïèñîê ïîñèëàíü!? Áóäü "
-#~ "ëàñêà, ïîâ³äîìòå ó vim-dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "Íå âäàëîñÿ çàðåºñòðóâàòè êîìàíäó ïî䳿: ïîñèëàííÿ íà áóôåð/â³êíî íå "
-#~ "çíàéäåíî"
-
-#~ 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 "cannot get line"
-#~ msgstr "íå âäàëîñÿ ä³ñòàòè ðÿäîê"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Íå âäàëîñÿ çàðåºñòðóâàòè íàçâó ñåðâåðà êîìàíä"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Íå âäàëîñÿ â³ä³ñëàòè êîìàíäó äî ïðîãðàìè-ö³ë³"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: Âèêîðèñòàíî íåêîðåêòíèé ³äåíòèô³êàòîð ñåðâåðà: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: Ðåêâ³çèò ðåºñòðó çðàçêó VIM ñôîðìîâàíèé íåïðàâèëüíî. Çíèùåíî!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans íå ï³äòðèìóºòüñÿ ç öèì GUI\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Öÿ âåðñ³ÿ Vim íå áóëà ñêîìï³ëüîâàíà ç ï³äòðèìêîþ ïîð³âíÿííÿ."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "Íå ìîæíà âèêîðèñòàòè '-nb': íå äîçâîëåíî ï³ä ÷àñ êîìï³ëÿö³¿\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Ïîìèëêà: Íå âäàëîñÿ çàïóñòèòè gvim äëÿ NetBeans\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "ßêùî ðåã³ñòð ³ãíîðóºòüñÿ, äîäàéòå / ñïåðåäó ùîá ïðàïîðåöü áóâ ó âåðõíüîìó "
-#~ "ðåã³ñòð³."
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tÇàðåºñòðóâàòè öåé gvim äëÿ OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tÑêàñóâàòè ðåºñòðàö³þ öüîãî gvim äëÿ OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tÇàïóñòèòè GUI (í³áè «gvim»)"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f ÷è --nofork\tÏåðåäí³é ïëàí: òðèìàòè òåðì³íàë ï³ñëÿ çàïóñêó GUI"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tÍå âèêîðèñòîâóâàòè newcli äëÿ â³äêðèòòÿ â³êíà"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <ïðèñòð³é>\t\t\tÂèêîðèñòîâóâàòè <ïðèñòð³é> äëÿ ââîäó/âèâîäó"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-u <gvimrc>\t\tÂèêîðèñòàòè ïîäàíèé ôàéë çàì³ñòü .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tÐåäàãóâàòè çàøèôðîâàí³ ôàéëè"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <äèñïëåé>\tϳä'ºäíàòè vim äî çàäàíîãî äèñïëåþ ñåðâåðà X"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tÍå ç'ºäíóâàòèñÿ ç X ñåðâåðîì"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <ôàéëè>\tÐåäàãóâàòè <ôàéëè> íà ñåðâåð³ Vim, ÿêùî öå ìîæëèâî"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent <ôàéëè> Òå ñàìå, ò³ëüêè íå ñêàðæèòèñÿ íà â³äñóòí³ñòü "
-#~ "ñåðâåðà"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <ôàéëè> ..., àëå çà÷åêàòè ïîêè óñ³ ôàéëè áóäóòü "
-#~ "â³äðåäàãîâàí³"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <ôàéëè> Òå ñàìå, ò³ëüêè íå ñêàðæèòèñÿ, ÿêùî ñåðâåðà "
-#~ "íåìàº"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <ôàéëè> Òàê ñàìî, ÿê --remote, àëå ïî "
-#~ "âêëàäö³ íà ôàéë"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <ñèìâîëè> ³ä³ñëàòè <ñèìâîëè> ñåðâåðó ³ çàâåðøèòè ðîáîòó"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <âèðàç> Âèêîíàòè <âèðàç> ó ñåðâåð³ Vim ³ íàäðóêóâàòè "
-#~ "ðåçóëüòàò"
-
-#~ 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 <íàçâà>\tÍàä³ñëàòè äî/ñòàòè Vim ñåðâåðîì ç <íàçâîþ>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Àðãóìåíòè äëÿ gvim (âåðñ³ÿ Motif)\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Àðãóìåíòè äëÿ gvim (âåðñ³ÿ neXtaw):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Àðãóìåíòè äëÿ gvim (âåðñ³ÿ Athena)\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <äèñïëåé>\tÂèêîíàòè vim íà çàäàíîìó <äèñïëå¿>"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tÇàïóñòèòè Vim ³ çãîðíóòè éîãî â³êíî"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <êîë³ð>\tÂèêîðèñòàòè <êîë³ð> äëÿ ôîíó (òàêîæ: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <êîë³ð>\tÂèêîðèñòàòè <êîë³ð> äëÿ çâè÷àéíîãî òåêñòó (òàêîæ: -"
-#~ "fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr ""
-#~ "-font <øðèôò>\tÂèêîðèñòàòè <øðèôò> äëÿ çâè÷àéíîãî òåêñòó (òàêîæ: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <øðèôò>\tÂèêîðèñòàòè <øðèôò> äëÿ æèðíîãî òåêñòó"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <øðèôò>\tÂèêîðèñòàòè <øðèôò> äëÿ ïîõèëîãî òåêñòó"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <ãåîì>\tÇàäàòè ðîçì³ðè é ïîëîæåííÿ (òàêîæ: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <òîâù>\tÂñòàíîâèòè òîâùèíó ìåæ <òîâù> (òàêîæ: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <òîâù> Âñòàíîâèòè òîâùèíó ë³í³éêè çñóâó (òàêîæ: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <âèñîòà>\tÂñòàíîâèòè âèñîòó ìåíþ <âèñîòà> (òàêîæ: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tÎáåðíóòè êîëüîðè (òàêîæ: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tÍå îáåðòàòè êîëüîðè (òàêîæ: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <ðåñóðñ>\t\tÂñòàíîâèòè çàçíà÷åíèé ðåñóðñ"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Àðãóìåíòè gvim (âåðñ³ÿ GTK+)\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <äèñïëåé>\tÂèêîíàòè vim íà <äèñïëå¿> (òàêîæ: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr ""
-#~ "--role <ðîëü>\tÂñòàíîâèòè óí³êàëüíó ðîëü äëÿ ³äåíòèô³êàö³¿ ãîëîâíîãî â³êíà"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\t³äêðèòè Vim â ³íøîìó åëåìåíò³ ³íòåðôåéñó GTK"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tÕàé gvim íàäðóêóº ³äåíòèô³êàòîð â³êíà íà stdout"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <çàãîëîâîê áàòüêà>\t³äêðèòè Vim âñåðåäèí³ áàòüê³âñüêîãî â³êíà"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\t³äêðèòè Vim âñåðåäèí³ ³íøîãî åëåìåíòó win32"
-
-#~ msgid "No display"
-#~ msgstr "Íåìຠäèñïëåþ"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Íå âäàëîñÿ â³ä³ñëàòè.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Íå âäàëîñÿ â³ä³ñëàòè. Ñïðîáà âèêîíàòè íà ì³ñö³\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "â³äðåäàãîâàíî %d ç %d"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Íåìຠäèñïëåþ: ³ä³ñëàòè âèðàç íå âäàëîñÿ.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": ³ä³ñëàòè âèðàç íå âäàëîñÿ.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Íåêîðåêòíà êîäîâà ñòîð³íêà"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: Íå âäàëîñÿ âñòàíîâèòè çíà÷åííÿ êîíòåêñòó ââîäó"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Íå âäàëîñÿ ñòâîðèòè êîíòåêñò ââîäó"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Íå âäàëîñÿ ñòâîðèòè ìåòîä ââîäó"
-
-# msgstr "E286: "
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr ""
-#~ "E287: Çàñòåðåæåííÿ: Íå âäàëîñÿ âñòàíîâèòè â ìåòîä³ ââîäó ïîä³þ çíèùåííÿ"
-
-# msgstr "E287: "
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: Ìåòîä ââîäó íå ï³äòðèìóº ñòèë³"
-
-# msgstr "E288: "
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: Ìåòîä ââîäó íå ï³äòðèìóº â³äðåäàãîâàí³ òèïè"
-
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: Ïîìèëêà ïîíîâëåííÿ øèôðóâàííÿ ôàéëó îáì³íó"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s çàøèôðîâàíî, à öÿ âåðñ³ÿ Vim íå ï³äòðèìóº øèôðóâàííÿ"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Ôàéë îáì³íó çàøèôðîâàíèé: «%s»"
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "ßêùî âè çàäàëè íîâèé êëþ÷ øèôðó, àëå íå çàïèñàëè òåêñòîâèé ôàéë,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "ââåä³òü íîâèé êëþ÷ øèôðó."
-
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "ßêùî âè çàïèñàëè òåêñòîâèé ôàéë ï³ñëÿ çì³íè êëþ÷à øèôðó, íàòèñí³òü enter"
-
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "ùîá âèêîðèñòàòè îäíàêîâèé êëþ÷ äëÿ òåêñòîâîãî ôàéëó òà ôàéëó îáì³íó"
-
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "Äëÿ òåêñòîâîãî ôàéëó âèêîðèñòîâóºòüñÿ êëþ÷ øèôðó ç ôàéëó îáì³íó.\n"
-
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [íå ïðèäàòíèé äëÿ ö³º¿ âåðñ³¿ Vim]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "³ä³ðâàòè öå ìåíþ"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Âèáðàòè êàòàëîã"
-
-#~ msgid "Save File dialog"
-#~ msgstr "Çàïàì'ÿòàòè ôàéë"
-
-#~ msgid "Open File dialog"
-#~ msgstr "³äêðèòè ôàéë"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Âèáà÷òå, àëå â êîíñîë³ íåìຠä³àëîãó âèáîðó ôàéëó"
-
-#~ msgid "ERROR: "
-#~ msgstr "ÏÎÌÈËÊÀ: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[áàéò] âñüîãî ðîçì/çíèù. %<PRIu64>/%<PRIu64>, âèêîð. %<PRIu64>, ìàêñ. "
-#~ "%<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[âèêëèêè] óñüîãî re/malloc() - %<PRIu64>, óñüîãî free() - %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: Ðÿäîê ñòຠçàíàäòî äîâãèì"
-
-# msgstr "E340: "
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Âíóòð³øíÿ ïîìèëêà: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Íåïðàâèëüíèé âèãëÿä ìèø³"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "Âêàæ³òü êëþ÷ øèôðó: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "Ïîâòîð³òü êëþ÷: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Êëþ÷³ íå îäíàêîâ³!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Íå âäàëîñÿ ç'ºäíàòèñÿ ³ç Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Íå âäàëîñÿ ç'ºäíàòèñÿ ³ç Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Íåïðàâèëüíèé ðåæèì äîñòóïó äî ôàéëó ³íôîðìàö³¿ ïðî ç'ºäíàííÿ ç "
-#~ "NetBenans: «%s»"
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "÷èòàºòüñÿ ç ñîêåòà Netbeans"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Âòðà÷åíî çâ'ÿçîê ³ç NetBeans äëÿ áóôåðà %<PRId64>"
-
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: netbeans íå ï³äòðèìóºòüñÿ ç öèì GUI"
-
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans âæå ï³ä'ºäíàíî"
-
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s ò³ëüêè äëÿ ÷èòàííÿ (! ùîá íå çâàæàòè)"
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: Ìîæëèâ³ñòü eval íåäîñòóïíà"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "Çâ³ëüíåíî ðÿäê³â: %<PRId64>"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Íå âäàëîñÿ çì³íèòè term â GUI"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: Çàñòîñóéòå «:gui» äëÿ çàïóñêó GUI"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Íå ìîæíà çì³íèòè â GUI GTK+ 2"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Íåêîðåêòíèé(³) øðèôò(è)"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: Íå âäàëîñÿ âèáðàòè íàá³ð øðèôò³â"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Íåïðàâèëüíèé íàá³ð øðèôò³â"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: Íå âäàëîñÿ âèêîðèñòàòè ðîçøèðåíèé øðèôò"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Íåêîðåêòíèé ðîçøèðåíèé øðèôò"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Ìèøà íå ï³äòðèìóºòüñÿ"
-
-# msgstr "E358: "
-#~ msgid "cannot open "
-#~ msgstr "íå âäàëîñÿ â³äêðèòè "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Íå âäàëîñÿ â³äêðèòè â³êíî!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Ïîòð³áíà Amigados 2.04 àáî ï³çí³øà\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Ïîòð³áíî %s âåðñ³¿ %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Íå âäàëîñÿ â³äêðèòè NIL:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "Íå âäàëîñÿ ñòâîðèòè "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim çàâåðøóº ðîáîòó ç %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "íå ìîæó çì³íèòè ðåæèì êîíñîë³ ?!\n"
-
-# msgstr "E359: "
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: íå êîíñîëü??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Íå âäàëîñÿ çàïóñòèòè îáîëîíêó ç îïö³ºþ -f"
-
-# msgstr "E360: "
-#~ msgid "Cannot execute "
-#~ msgstr "Íå âäàëîñÿ âèêîíàòè "
-
-#~ msgid "shell "
-#~ msgstr "îáîëîíêó "
-
-#~ msgid " returned\n"
-#~ msgstr " ïîâåðíóòî\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE çàìàëèé"
-
-#~ msgid "I/O ERROR"
-#~ msgstr "Ïîìèëêà ââîäó/âèâîäó"
-
-#~ msgid "Message"
-#~ msgstr "Ïîâ³äîìëåííÿ"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' íå 80, íå ìîæíà âèêîíóâàòè çîâí³øí³ êîìàíäè"
-
-# msgstr "E364: "
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Íå âäàëîñÿ âèáðàòè ïðèíòåð"
-
-#~ msgid "to %s on %s"
-#~ msgstr "íà %s ç %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Íåâ³äîìèé øðèôò ïðèíòåðà: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Ïîìèëêà äðóêó: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "Äðóêóºòüñÿ '%s'"
-
-#~ 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 "Opening the X display took %<PRId64> msec"
-#~ msgstr "Íà â³äêðèòòÿ äèñïëåþ X ï³øëî %<PRId64> ì³ë³ñåêóíä"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Ïîìèëêà X\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "Äèñïëåé Õ íå ïðîéøîâ ïåðåâ³ðêó"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Ñïëèâ ÷àñ î÷³êóâàííÿ â³äêðèòòÿ äèñïëåþ Õ"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Íå âäàëîñÿ çàïóñòèòè îáîëîíêó `sh'\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Íå ìîæíà ñòâîðèòè êàíàëè\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Íå âäàëîñÿ ðîçäâî¿òèñÿ\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Êîìàíäà çàê³í÷èëà âèêîíàííÿ\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP âòðàòèâ ç'ºäíàííÿ ICE"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "Íå âäàëîñÿ â³äêðèòè äèñïëåé X"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP îáðîáëÿºòüñÿ çàïèò 'çáåðåæè ñåáå'"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP â³äêðèâàºòüñÿ ç'ºäíàííÿ"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ñïîñòåðåæåííÿ çà ç'ºäíàííÿì ç ICE íå âäàëîñÿ"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP íå âäàëîñÿ SmcOpenConnection: %s"
-
-#~ msgid "At line"
-#~ msgstr "Ðÿäîê:"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Íå âäàëîñÿ çàâàíòàæèòè vim32.dll"
-
-#~ msgid "VIM Error"
-#~ msgstr "Ïîìèëêà VIM"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Íå âäàëîñÿ âèïðàâèòè âêàç³âíèêè íà ôóíêö³¿ DLL!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "îáîëîíêà ïîâåðíóëà %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: Âèÿâëåíî ïîä³þ %s\n"
-
-#~ msgid "close"
-#~ msgstr "close"
-
-#~ msgid "logoff"
-#~ msgstr "logoff"
-
-#~ msgid "shutdown"
-#~ msgstr "shutdown"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Êîìàíäó íå çíàéäåíî"
-
-#~ 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 ""
-#~ "Ôàéë VIMRUN.EXE íå çíàéäåíî ó øëÿõó ïîøóêó.\n"
-#~ "Çîâí³øí³ êîìàíäè íå áóäóòü ïðèçóïèíåí³ ï³ñëÿ âèêîíàííÿ.\n"
-#~ "Ãëÿíüòå :help win32-vimrun ùîá îòðèìàòè ïîäðîáèö³."
-
-#~ msgid "Vim Warning"
-#~ msgstr "Çàñòåðåæåííÿ Vim"
-
-# msgstr "E231: "
-#~ msgid "Error file"
-#~ msgstr "Ôàéë ïîìèëîê"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: Íå âäàëîñÿ ïîáóäóâàòè NFA ç êëàñîì åêâ³âàëåíòíîñò³!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) Íå âäàëîñÿ îòðèìàòè ïàì’ÿòü äëÿ îáõîäó ã³ëîê!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "Çàñòåðåæåííÿ: Íå âäàëîñÿ çíàéòè ñïèñîê ñë³â «%s_%s.spl» ÷è «%s_ascii.spl»"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "Ïåðåòâîðåííÿ ó %s íå ï³äòðèìóºòüñÿ"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: Íåäîñòàòíüî ïàì’ÿò³, ñïèñîê ñë³â áóäå íåïîâíèì"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Øëÿõ ôàéëó òå´³â ñêîðî÷åíî äî %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "çàïóùåíî íîâó îáîëîíêó\n"
-
-# msgstr "E242: "
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "Âèêîðèñòàíî CUT_BUFFER0 çàì³ñòü ïîðîæíüîãî âèä³ëåííÿ"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "Ñêàñóâàííÿ áóäå íåìîæëèâå, âñå îäíî ïðîäîâæèòè"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Íåçàøèôðîâàíèé ôàéë ìຠçàøèôðîâàíèé ôàéë ³ñòîð³¿: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Íå âäàëîñÿ ðîçøèôðóâàòè ôàéë ³ñòîð³¿: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Ôàéë ³ñòî𳿠çàøèôðîâàíèé: %s"
-
-# msgstr "E440: "
-# ---------------------------------------
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ ç GUI äëÿ 16/32-ðîçðÿäíî¿ Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ ç GUI äëÿ 64-ðîçðÿäíî¿ MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ ç GUI äëÿ 32-ðîçðÿäíî¿ Windows"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " â ðåæèì³ Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " ç ï³äòðèìêîþ OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Êîíñîëüíà âåðñ³ÿ äëÿ 64-ðîçðÿäíî¿ Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "Êîíñîëüíà âåðñ³ÿ äëÿ 32-ðîçðÿäíî¿ Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ äëÿ 16-ðîçðÿäíî¿ Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ äëÿ 32-ðîçðÿäíî¿ MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ äëÿ 16-ðîçðÿäíî¿ MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ äëÿ MacOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ äëÿ MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ äëÿ MacOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "Âåðñ³ÿ äëÿ OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Âåëèêà âåðñ³ÿ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Íîðìàëüíà âåðñ³ÿ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Ìàëà âåðñ³ÿ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Êðèõ³òíà âåðñ³ÿ "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "ç GUI GTK2-GNOME."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "ç GUI GTK2."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "ç GUI X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "ç GUI X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "ç GUI X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "ç GUI Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "ç GUI."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "ç GUI Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "ç GUI Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "ç (êëàñè÷íèì) GUI."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ñèñòåìíèé gvimrc: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " gvimrc êîðèñòóâà÷à: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "äðóãèé gvimrc êîðèñòóâà÷à: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "òðåò³é gvimrc êîðèñòóâà÷à: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " ñèñòåìíå ìåíþ: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "Êîìï³ëÿòîð: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "ìåíþ Help->Orphans ïîäàëüøà ³íôîðìàö³ÿ "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Áåç ðåæèì³â, òåêñò ùî íàáðàíî âñòàâëÿºòüñÿ"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "ìåíþ Edit->Global Settings->Toggle Insert Mode "
-
-#~ msgid " for two modes "
-#~ msgstr " äëÿ äâîõ ðåæèì³â "
-
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "ìåíþ Edit->Global Settings->Toggle Vi Compatible "
-
-#~ msgid " for Vim defaults "
-#~ msgstr " ùîá ïî÷èíàòè â ðåæèì³ ñóì³ñíîñò³ ç Vi"
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "ÇÀÑÒÅÐÅÆÅÍÍß: Âè êîðèñòóºòåñÿ Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr ":help windows95<Enter> ³íôîðìàö³ÿ ïðî öå "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Íå âäàëîñÿ çàâàíòàæèòè á³áë³îòåêó %s"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "Âèáà÷òå, öÿ êîìàíäà âèìêíåíà, á³áë³îòåêà Perl íå ìîæå áóòè çàâàíòàæåíà."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: Îá÷èñëåííÿ âèðàç³â Perl çàáîðîíåíå ó ï³ñî÷íèö³ áåç ìîäóëÿ Safe"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Ðåäàãóâàòè ó (&m)ð³çíèõ Vim"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Ðåäàãóâàòè ó îäíîìó &Vim"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Ïîð³âíÿòè ç äîïîìîãîþ Vim"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Ðåäàãóâàòè çà äîïîìîãîþ &Vim"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Ðåäàãóâàòè ó âæå çàïóùåíîìó Vim - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Ðåäàãóº âèáðàí³ ôàéëè ç äîïîìîãîþ Vim"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "Ïîìèëêà ñòâîðåííÿ ïðîöåñó, ïåðåâ³ðòå ÷è º gvim ó øëÿõó ïîøóêó!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "ïîìèëêà gvimext.dll"
-
-#~ msgid "Path length too long!"
-#~ msgstr "Øëÿõ çàíàäòî äîâãèé!"
-
-# msgstr "E233: "
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Íåâ³äîìèé íàá³ð øðèôò³â: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Íåâ³äîìèé øðèôò: %s"
-
-# msgstr "E235: "
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Øðèôò «%s» íå ìîíîøèðèííèé"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Íå âäàëîñÿ çàâàíòàæèòè á³áë³îòå÷íó ôóíêö³þ %s"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: Íå ìîæíà âèêîðèñòàòè ³âðèò: Íå ââ³ìêíåíî ï³ä ÷àñ êîìï³ëÿö³¿\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Íå ìîæíà âèêîðèñòàòè ôàðñ³: Íå ââ³ìêíåíî ï³ä ÷àñ êîìï³ëÿö³¿\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: Íå ìîæíà âèêîðèñòàòè àðàáñüêó ìîâó: Íå ââ³ìêíåíî ï³ä ÷àñ "
-#~ "êîìï³ëÿö³¿\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: Íåìຠçàðåºñòðîâàíèõ ñåðâåð³â ç íàçâîþ «%s»"
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: Íå âäàëîñÿ â³äêðèòè äèñïëåé"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Îòðèìàíî íåêîðåêòíèé âèðàç"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Íå ìîæíà çì³íèòè çàõèùåíèé ðåã³îí"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans íå äîçâîëÿº çì³íþâàòè çàõèùåí³ â³ä çàïèñó ôàéëè"
-
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Äëÿ «%s» ïîòð³áåí êëþ÷: "
-
-# msgstr "E406: "
-#~ msgid "empty keys are not allowed"
-#~ msgstr "ïîðîæí³ êëþ÷³ íå äîçâîëåí³"
-
-#~ msgid "dictionary is locked"
-#~ msgstr "ñëîâíèê çàáëîêîâàíî"
-
-#~ msgid "list is locked"
-#~ msgstr "ñïèñîê çàáëîêîâàíî"
-
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "íå âäàëîñÿ äîäàòè êëþ÷ '%s' äî ñëîâíèêà"
-
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "³íäåêñ ìຠáóòè ö³ëèé ÷è çð³ç, íå %s"
-
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr "î÷³êóâàâñÿ åêçåìïëÿð str() ÷è unicode(), àëå îòðèìàíî %s"
-
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "î÷³êóâàâñÿ åêçåìïëÿð bytes() ÷è str(), àëå îòðèìàíî %s"
-
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr ""
-#~ "î÷³êóâàâñÿ int(), long() ÷è ùîñü, ùî ìîæå áóòè âì³ùåíå long(), àëå "
-#~ "îòðèìàíî %s"
-
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr ""
-#~ "î÷³êóâàâñÿ int() ÷è ùîñü, ùî ìîæå áóòè âì³ùåíå int(), àëå îòðèìàíî %s"
-
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "çíà÷åííÿ çàâåëèêå, ùîá âì³ñòèòèñÿ ó òèï C int"
-
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "çíà÷åííÿ çàìàëå, ùîá âì³ñòèòèñÿ ó òèï C int"
-
-#~ msgid "number must be greater then zero"
-#~ msgstr "÷èñëî ìຠáóòè á³ëüøå, í³æ íóëü"
-
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "÷èñëî ìຠáóòè íå ìåíøå, í³æ íóëü"
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "íå âäàëîñÿ çíèùèòè àòðèáóòè OutputObject"
-
-# msgstr "E180: "
-#~ msgid "invalid attribute: %s"
-#~ msgstr "íåïðàâèëüíèé àòðèáóò: %s"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: Ïîìèëêà ³í³ö³àë³çàö³¿ îá'ºêò³â ââîäó/âèâîäó"
-
-#~ msgid "failed to change directory"
-#~ msgstr "íå âäàëîñÿ çì³íèòè äèðåêòîð³þ"
-
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "î÷³êóâàâñÿ 3-êîðòåæ ÿê ðåçóëüòàò imp.find_module(), àëå îòðèìàíî %s"
-
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr "î÷³êóâàâñÿ 3-êîðòåæ ÿê ðåçóëüòàò imp.find_module(), àëå îòðèìàíî %d"
-
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "âíóòð³øíÿ ïîìèëêà: imp.find_module ïîâåðíóëà êîðòåæ ç NULL"
-
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "íå âäàëîñÿ çíèùèòè àòðèáóòè vim.Dictionary"
-
-#~ msgid "cannot modify fixed dictionary"
-#~ msgstr "íå ìîæíà çì³íèòè ô³êñîâàíèé ñëîâíèê"
-
-#~ msgid "cannot set attribute %s"
-#~ msgstr "íå ìîæíà âñòàíîâèòè àòðèáóò %s"
-
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "õåø-òàáëèöÿ çì³íèëàñÿ ï³ä ÷àñ ïåðåáèðàííÿ"
-
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr ""
-#~ "î÷³êóâàëàñü ïîñë³äîâí³ñòü ðîçì³ðîì 2, àëå îòðèìàíî ïîñë³äîâí³ñòü ðîçì³ðó "
-#~ "%d"
-
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "ñïèñêîâèé êîíñòðóêòîð íå ïðèéìຠ³ìåíîâàí³ àðãóìåíòè"
-
-#~ msgid "list index out of range"
-#~ msgstr "³íäåêñ ñïèñêó çà ìåæàìè"
-
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "âíóòð³øíÿ ïîìèëêà: íå âäàëîñÿ îòðèìàòè åëåìåíò ñïèñêó vim %d"
-
-#~ msgid "failed to add item to list"
-#~ msgstr "íå âäàëîñÿ äîäàòè åëåìåíò äî ñïèñêó"
-
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "âíóòð³øíÿ ïîìèëêà: íåìຠåëåìåíòà ñïèñêó vim %d"
-
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "âíóòð³øíÿ ïîìèëêà: íå âäàëîñÿ äîäàòè åëåìåíò äî ñïèñêó"
-
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "íå âäàëîñÿ çíèùèòè àòðèáóòè vim.List"
-
-#~ msgid "cannot modify fixed list"
-#~ msgstr "íå ìîæíà çì³íèòè ô³êñîâàíèé ñïèñîê"
-
-# msgstr "E428: "
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "áåç³ìåííî¿ ôóíêö³¿ %s íå ³ñíóº"
-
-# msgstr "E428: "
-#~ msgid "function %s does not exist"
-#~ msgstr "ôóíêö³¿ %s íå ³ñíóº"
-
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "êîíñòðóêòîð ôóíêö³¿ íå ïðèéìຠ³ìåíîâàí³ àðãóìåíòè"
-
-#~ msgid "failed to run function %s"
-#~ msgstr "íå âäàëîñÿ âèêîíàòè ôóíêö³þ %s"
-
-#~ msgid "problem while switching windows"
-#~ msgstr "íå âäàëîñÿ ïåðåìêíóòè â³êíà"
-
-#~ msgid "unable to unset global option %s"
-#~ msgstr "íå âäàëîñÿ ñêèíóòè ãëîáàëüíó îïö³þ %s"
-
-#~ msgid "unable to unset option %s which does not have global value"
-#~ msgstr "íå âäàëîñÿ ñêèíóòè îïö³þ %s, ÿêà íå ìຠãëîáàëüíîãî çíà÷åííÿ"
-
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "ñïðîáà çâåðíåííÿ äî çíèùåíî¿ âêëàäêè"
-
-#~ msgid "no such tab page"
-#~ msgstr "òàêî¿ âêëàäêè íåìàº"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "ñïðîáà çâåðíóòèñÿ äî çíèùåíîãî â³êíà"
-
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "àòðèáóò ëèøå äëÿ ÷èòàííÿ: áóôåð"
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "êóðñîð çà ìåæàìè áóôåðà"
-
-#~ msgid "no such window"
-#~ msgstr "òàêîãî â³êíà íåìàº"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "ñïðîáà çâåðíåííÿ äî çíèùåíîãî áóôåðà"
-
-#~ msgid "failed to rename buffer"
-#~ msgstr "íå âäàëîñÿ ïåðåéìåíóâàòè áóôåð"
-
-#~ msgid "mark name must be a single character"
-#~ msgstr "íàçâîþ ì³òêè ìຠáóòè îäèí ñèìâîë"
-
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "î÷³êóâàâñÿ îá’ºêò vim.Buffer, àëå îòðèìàíî %s"
-
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "íå âäàëîñÿ ïåðåìêíóòèñÿ äî áóôåðà %d"
-
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "î÷³êóâàâñÿ îá’ºêò vim.Window, àëå îòðèìàíî %s"
-
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "íå âäàëîñÿ çíàéòè â³êíî ó ïîòî÷í³é âêëàäö³"
-
-#~ msgid "did not switch to the specified window"
-#~ msgstr "íå ïåðåìêíóâñÿ äî âêàçàíîãî â³êíà"
-
-#~ msgid "expected vim.TabPage object, but got %s"
-#~ msgstr "î÷³êóâàâñÿ îá’ºêò vim.TabPage, àëå îòðèìàíî %s"
-
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "íå ïåðåìêíóâñÿ äî âêàçàíî¿ âêëàäêè"
-
-#~ msgid "failed to run the code"
-#~ msgstr "íå âäàëîñÿ âèêîíàòè êîä"
-
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: Eval íå ïîâåðíóâ ä³éñíèé îá’ºêò python"
-
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: Íå âäàëîñÿ ïåðåòâîðèòè îá’ºêò python ó çíà÷åííÿ vim"
-
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "íå âäàëîñÿ ïåðåòâîðèòè %s ó ñëîâíèê vim"
-
-#~ msgid "unable to convert %s to vim structure"
-#~ msgstr "íå âäàëîñÿ ïåðåòâîðèòè %s ó ñòðóêòóðó vim"
-
-#~ msgid "internal error: NULL reference passed"
-#~ msgstr "âíóòð³øíÿ ïîìèëêà: ïåðåäàíî ïîñèëàííÿ NULL"
-
-#~ msgid "internal error: invalid value type"
-#~ msgstr "âíóòð³øíÿ ïîìèëêà: íåïðàâèëüíèé òèï çíà÷åííÿ"
-
-#~ msgid ""
-#~ "Failed to set path hook: sys.path_hooks is not a list\n"
-#~ "You should now do the following:\n"
-#~ "- append vim.path_hook to sys.path_hooks\n"
-#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
-#~ msgstr ""
-#~ "Íå âäàëîñÿ âñòàíîâèòè îáðîáíèê øëÿõó: sys.path_hooks íå ñïèñîê\n"
-#~ "Âàì ñë³ä â÷èíèòè òàê:\n"
-#~ "- äîäàéòå vim.path_hook äî sys.path_hooks\n"
-#~ "- äîäàéòå vim.VIM_SPECIAL_PATH äî sys.path\n"
-
-#~ msgid ""
-#~ "Failed to set path: sys.path is not a list\n"
-#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
-#~ msgstr ""
-#~ "Íå âäàëîñÿ âñòàíîâèòè øëÿõ: sys.path íå ñïèñîê\n"
-#~ "Âàñ ñë³ä äîäàòè vim.VIM_SPECIAL_PATH äî sys.path"
diff --git a/src/nvim/po/uk.po b/src/nvim/po/uk.po
index eaa3a5bfa9..211d38e53a 100644
--- a/src/nvim/po/uk.po
+++ b/src/nvim/po/uk.po
@@ -1,5 +1,7 @@
#
-# Ukrainian Vim translation [uk]
+# Ukrainian translation for Vim
+#
+# Original translations
#
# Copyright (C) 2001 Bohdan Vlasyuk <bohdan@vstu.edu.ua>
# Bohdan donated this work to be distributed with Vim under the Vim license.
@@ -12,225 +14,163 @@ msgid ""
msgstr ""
"Project-Id-Version: vim 7.4\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: 2010-06-18 21:53+0300\n"
+"POT-Creation-Date: 2018-12-18 22:42+0200\n"
+"PO-Revision-Date: 2018-12-18 22:42+0200\n"
"Last-Translator: Ðнатолій Сахнік <sakhnik@gmail.com>\n"
-"Language-Team: Bohdan Vlasyuk <bohdan@vstu.edu.ua>\n"
+"Language-Team: Ukrainian\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¾Ð¿Ñ†Ñ–Ñ—"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: невідомий тип опції"
-
-#: ../buffer.c:92
msgid "[Location List]"
msgstr "[СпиÑок міÑць]"
-#: ../buffer.c:93
msgid "[Quickfix List]"
msgstr "[СпиÑок виправлень]"
-#: ../buffer.c:94
msgid "E855: Autocommands caused command to abort"
msgstr "E855: Ðвтокоманди призвели до ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸"
-#: ../buffer.c:135
msgid "E82: Cannot allocate any buffer, exiting..."
msgstr "E82: Ðемає можливоÑті розміÑтити хоч один буфер, Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸..."
-#: ../buffer.c:138
msgid "E83: Cannot allocate buffer, using other one..."
msgstr "E83: Ðемає можливоÑті розміÑтити буфер, буде викориÑтано інший..."
-#: ../buffer.c:763
+msgid "E937: Attempt to delete a buffer that is in use"
+msgstr "E937: Спроба Ð·Ð½Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð±ÑƒÑ„ÐµÑ€Ñƒ, Ñкий викориÑтовуєтьÑÑ"
+
msgid "E515: No buffers were unloaded"
msgstr "E515: Жоден з буферів не був вивантажений"
-#: ../buffer.c:765
msgid "E516: No buffers were deleted"
msgstr "E516: Жоден з буферів не знищено"
-#: ../buffer.c:767
msgid "E517: No buffers were wiped out"
msgstr "E517: Жоден з буферів не витерто"
-#: ../buffer.c:772
msgid "1 buffer unloaded"
msgstr "Вивантажено один буфер"
-#: ../buffer.c:774
#, c-format
msgid "%d buffers unloaded"
msgstr "Вивантажено %d буфери(ів)"
-#: ../buffer.c:777
msgid "1 buffer deleted"
msgstr "Знищено один буфер"
-#: ../buffer.c:779
#, c-format
msgid "%d buffers deleted"
msgstr "Знищено %d буфери(ів)"
-#: ../buffer.c:782
msgid "1 buffer wiped out"
msgstr "Витерто один буфер"
-#: ../buffer.c:784
#, c-format
msgid "%d buffers wiped out"
msgstr "Витерто %d буфери(ів)"
-#: ../buffer.c:806
msgid "E90: Cannot unload last buffer"
msgstr "E90: Ðе можу вивантажити оÑтанній буфер"
-#: ../buffer.c:874
msgid "E84: No modified buffer found"
msgstr "E84: Жоден буфер не змінено"
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
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
msgid "E87: Cannot go beyond last buffer"
msgstr "E87: Це вже оÑтанній буфер"
-#: ../buffer.c:917
msgid "E88: Cannot go before first buffer"
msgstr "E88: Це вже найперший буфер"
-#: ../buffer.c:945
+#, c-format
+msgid "E89: %s will be killed(add ! to override)"
+msgstr "E89: «%s» буде вбито(! щоб не зважати)"
+
#, c-format
msgid ""
"E89: No write since last change for buffer %<PRId64> (add ! to override)"
msgstr "E89: Буфер %<PRId64> має зміни (! щоб не зважати)"
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
msgid "W14: Warning: List of file names overflow"
msgstr "W14: Обережно: СпиÑок назв файлів переповнено"
-#: ../buffer.c:1555 ../quickfix.c:3361
#, c-format
msgid "E92: Buffer %<PRId64> not found"
msgstr "E92: Буфер %<PRId64> не знайдено"
-#: ../buffer.c:1798
#, c-format
msgid "E93: More than one match for %s"
msgstr "E93: Знайдено кілька збігів з %s"
-#: ../buffer.c:1800
#, c-format
msgid "E94: No matching buffer for %s"
msgstr "E94: Ðе знайдено буфер, Ñхожий на %s"
-#: ../buffer.c:2161
#, c-format
msgid "line %<PRId64>"
msgstr "Ñ€Ñдок %<PRId64>"
-#: ../buffer.c:2233
msgid "E95: Buffer with this name already exists"
msgstr "E95: Буфер з такою назвою вже Ñ–Ñнує"
-#: ../buffer.c:2498
msgid " [Modified]"
msgstr " [Змінено]"
-#: ../buffer.c:2501
msgid "[Not edited]"
msgstr "[Ðе редаговано]"
-#: ../buffer.c:2504
msgid "[New file]"
msgstr "[Ðовий файл]"
-#: ../buffer.c:2505
msgid "[Read errors]"
msgstr "[Помилки читаннÑ]"
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
msgid "[RO]"
msgstr "[RO]"
-#: ../buffer.c:2507 ../fileio.c:1807
msgid "[readonly]"
msgstr "[лише читати]"
-#: ../buffer.c:2524
#, c-format
msgid "1 line --%d%%--"
msgstr "один Ñ€Ñдок --%d%%--"
-#: ../buffer.c:2526
#, c-format
msgid "%<PRId64> lines --%d%%--"
msgstr "%<PRId64> Ñ€Ñдки(ів) --%d%%--"
-#: ../buffer.c:2530
#, c-format
msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
msgstr "Ñ€Ñдок %<PRId64> з %<PRId64> --%d%%-- колонка "
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
msgid "[No Name]"
msgstr "[Без назви]"
-#. must be a help buffer
-#: ../buffer.c:2667
msgid "help"
msgstr "допомога"
-#: ../buffer.c:3225 ../screen.c:4883
msgid "[Help]"
msgstr "[Допомога]"
-#: ../buffer.c:3254 ../screen.c:4887
msgid "[Preview]"
msgstr "[ПереглÑд]"
-#: ../buffer.c:3528
msgid "All"
msgstr "УÑе"
-#: ../buffer.c:3528
msgid "Bot"
msgstr "Знизу"
-#: ../buffer.c:3531
msgid "Top"
msgstr "Вгорі"
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# СпиÑок буферів:\n"
-
-#: ../buffer.c:4289
msgid "[Scratch]"
msgstr "[З нулÑ]"
-#: ../buffer.c:4529
msgid ""
"\n"
"--- Signs ---"
@@ -238,962 +178,1151 @@ msgstr ""
"\n"
"--- Позначки ---"
-#: ../buffer.c:4538
#, c-format
msgid "Signs for %s:"
msgstr "Позначки Ð´Ð»Ñ %s:"
-#: ../buffer.c:4543
#, c-format
msgid " line=%<PRId64> id=%d name=%s"
msgstr " Ñ€Ñдок=%<PRId64> id=%d назва=%s"
-#: ../cursor_shape.c:68
+msgid "can only be opened in headless mode"
+msgstr "можна відкрити тільки без інтерфейÑу кориÑтувача"
+
+msgid "channel was already open"
+msgstr "канал вже був відкритий"
+
+msgid "Can't send data to closed stream"
+msgstr "Ðеможливо надіÑлати дані у закритий потік"
+
+msgid "Can't send raw data to rpc channel"
+msgstr "Ðеможливо надіÑлати дані у канал завданнÑ"
+
msgid "E545: Missing colon"
msgstr "E545: Пропущено двокрапку"
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
msgid "E546: Illegal mode"
msgstr "E546: Ðеправильний режим"
-#: ../cursor_shape.c:134
msgid "E548: digit expected"
msgstr "E548: Потрібна цифра"
-#: ../cursor_shape.c:138
msgid "E549: Illegal percentage"
msgstr "E549: Ðеправильний відÑоток"
-#: ../diff.c:146
#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
+msgid "E96: Cannot diff more than %<PRId64> buffers"
msgstr "E96: Ðе можна порівнювати понад %<PRId64> буфери(ів)"
-#: ../diff.c:753
+#, c-format
+msgid "Not enough memory to use internal diff for buffer \"%s\""
+msgstr "ÐедоÑтатньо пам’Ñті Ð´Ð»Ñ Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ порівнÑÐ½Ð½Ñ Ñƒ буфері \"%s\""
+
msgid "E810: Cannot read or write temp files"
msgstr "E810: Ðе можна читати чи запиÑувати тимчаÑові файли"
-#: ../diff.c:755
msgid "E97: Cannot create diffs"
msgstr "E97: Ðе вдалоÑÑ Ñтворити порівнÑннÑ"
-#: ../diff.c:966
+msgid "E960: Problem creating the internal diff"
+msgstr "E960: Ðе вдалоÑÑ Ñтворити внутрішнє порівнÑннÑ"
+
msgid "E816: Cannot read patch output"
msgstr "E816: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ результат patch"
-#: ../diff.c:1220
msgid "E98: Cannot read diff output"
msgstr "E98: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ результат diff"
-#: ../diff.c:2081
+msgid "E959: Invalid diff format."
+msgstr "E959: Ðеправильний формат порівнÑннÑ."
+
msgid "E99: Current buffer is not in diff mode"
msgstr "E99: Цей буфер не в режимі порівнÑннÑ"
-#: ../diff.c:2100
msgid "E793: No other buffer in diff mode is modifiable"
msgstr "E793: Ðемає більше модифіковних буферів в режимі порівнÑннÑ"
-#: ../diff.c:2102
msgid "E100: No other buffer in diff mode"
msgstr "E100: Ðемає інших буферів в режимі порівнÑннÑ"
-#: ../diff.c:2112
msgid "E101: More than two buffers in diff mode, don't know which one to use"
msgstr ""
"E101: Понад два буфери у режимі порівнÑннÑ, не зрозуміло, котрий із них "
"викориÑтати"
-#: ../diff.c:2141
#, c-format
msgid "E102: Can't find buffer \"%s\""
msgstr "E102: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ буфер «%s»"
-#: ../diff.c:2152
#, c-format
msgid "E103: Buffer \"%s\" is not in diff mode"
msgstr "E103: Буфер «%s» не в режимі порівнÑннÑ"
-#: ../diff.c:2193
msgid "E787: Buffer changed unexpectedly"
msgstr "E787: Буфер неÑподівано змінивÑÑ"
-#: ../digraph.c:1598
msgid "E104: Escape not allowed in digraph"
msgstr "E104: У диграфах не може міÑтитиÑÑ escape"
-#: ../digraph.c:1760
msgid "E544: Keymap file not found"
msgstr "E544: Ðе знайдено файл розкладки"
-#: ../digraph.c:1785
msgid "E105: Using :loadkeymap not in a sourced file"
msgstr "E105: :loadkeymap викориÑтано не у файлі команд"
-#: ../digraph.c:1821
msgid "E791: Empty keymap entry"
msgstr "E791: Елемент розкладки порожній"
-#: ../edit.c:82
msgid " Keyword completion (^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð²Ð¸Ñ… Ñлів (^N^P)"
-#. 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)"
-#: ../edit.c:85
msgid " Whole line completion (^L^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÑƒÑього Ñ€Ñдка (^L^N^P)"
-#: ../edit.c:86
msgid " File name completion (^F^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð½Ð°Ð·Ð²Ð¸ файлу (^F^N^P)"
-#: ../edit.c:87
msgid " Tag completion (^]^N^P)"
-msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ñ‚ÐµÒ‘Ñ–Ð² (^]^N^P)"
+msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð· міток (^]^N^P)"
-#: ../edit.c:88
msgid " Path pattern completion (^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÑˆÐ»Ñху за зразком (^N^P)"
-#: ../edit.c:89
msgid " Definition completion (^D^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ (^D^N^P)"
-#: ../edit.c:91
msgid " Dictionary completion (^K^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð·Ñ– Ñловника (^K^N^P)"
-#: ../edit.c:92
msgid " Thesaurus completion (^T^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð· тезауруÑу (^T^N^P)"
-#: ../edit.c:93
msgid " Command-line completion (^V^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´ (^V^N^P)"
-#: ../edit.c:94
msgid " User defined completion (^U^N^P)"
msgstr " КориÑтувацьке Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ (^U^N^P)"
-#: ../edit.c:95
msgid " Omni completion (^O^N^P)"
msgstr " Кмітливе Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ (^O^N^P)"
-#: ../edit.c:96
msgid " Spelling suggestion (s^N^P)"
msgstr " Орфографічна підказка (s^N^P)"
-#: ../edit.c:97
msgid " Keyword Local completion (^N^P)"
msgstr " Ð”Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¼Ñ–Ñцевих ключових Ñлів (^N^P)"
-#: ../edit.c:100
msgid "Hit end of paragraph"
msgstr "ТрапивÑÑ ÐºÑ–Ð½ÐµÑ†ÑŒ параграфа"
-# msgstr "E443: "
-#: ../edit.c:101
msgid "E839: Completion function changed window"
msgstr "E839: Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½Ð¸Ð»Ð° вікно"
-#: ../edit.c:102
msgid "E840: Completion function deleted text"
msgstr "E840: Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð·Ð½Ð¸Ñ‰Ð¸Ð»Ð° текÑÑ‚"
-#: ../edit.c:1847
msgid "'dictionary' option is empty"
msgstr "ÐžÐ¿Ñ†Ñ–Ñ 'dictionary' порожнÑ"
-#: ../edit.c:1848
msgid "'thesaurus' option is empty"
msgstr "ÐžÐ¿Ñ†Ñ–Ñ 'thesaurus' порожнÑ"
-#: ../edit.c:2655
#, c-format
msgid "Scanning dictionary: %s"
msgstr "СкануєтьÑÑ Ñловник: %s"
-#: ../edit.c:3079
msgid " (insert) Scroll (^E/^Y)"
-msgstr " (вÑтавка) Прогорнути (^E/^Y)"
+msgstr " (вÑтавити) Прогорнути (^E/^Y)"
-#: ../edit.c:3081
msgid " (replace) Scroll (^E/^Y)"
msgstr " (заміна) Прогорнути (^E/^Y)"
-#: ../edit.c:3587
#, c-format
msgid "Scanning: %s"
msgstr "Пошук у: %s"
-#: ../edit.c:3614
msgid "Scanning tags."
msgstr "Пошук Ñеред теґів."
-#: ../edit.c:4519
+msgid "match in file"
+msgstr "збіг у файлі"
+
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.
-#.
-#: ../edit.c:4562
msgid "-- Searching..."
msgstr "-- Пошук..."
-#: ../edit.c:4618
msgid "Back at original"
msgstr "Початковий варіант"
-#: ../edit.c:4621
msgid "Word from other line"
msgstr "Слово з іншого Ñ€Ñдка"
-#: ../edit.c:4624
msgid "The only match"
msgstr "Єдиний збіг"
-#: ../edit.c:4680
#, c-format
msgid "match %d of %d"
msgstr "збіг %d з %d"
-#: ../edit.c:4684
#, c-format
msgid "match %d"
msgstr "збіг %d"
-# msgstr "E17: "
-#: ../eval.c:137
msgid "E18: Unexpected characters in :let"
msgstr "E18: Ðеочікувані Ñимволи у :let"
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: Ð†Ð½Ð´ÐµÐºÑ ÑпиÑку поза межами: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: Ðевизначена змінна: %s"
-
-#: ../eval.c:140
msgid "E111: Missing ']'"
msgstr "E111: Бракує ']'"
-#: ../eval.c:141
#, c-format
msgid "E686: Argument of %s must be a List"
msgstr "E686: Ðргумент у %s має бути ÑпиÑком"
-#: ../eval.c:143
#, c-format
msgid "E712: Argument of %s must be a List or Dictionary"
msgstr "E712: Ðргумент у %s має бути ÑпиÑком чи Ñловником"
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Ключ Ñловника не може бути порожнім"
-
-# msgstr "E396: "
-#: ../eval.c:145
msgid "E714: List required"
msgstr "E714: Потрібен ÑпиÑок"
-#: ../eval.c:146
msgid "E715: Dictionary required"
msgstr "E715: Потрібен Ñловник"
-#: ../eval.c:147
+msgid "E928: String required"
+msgstr "E928: Потрібен String"
+
#, c-format
msgid "E118: Too many arguments for function: %s"
msgstr "E118: Забагато аргументів Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ—: %s"
-#: ../eval.c:148
#, c-format
msgid "E716: Key not present in Dictionary: %s"
msgstr "E716: Ðемає такого ключа у Ñловнику: %s"
-#: ../eval.c:150
#, c-format
msgid "E122: Function %s already exists, add ! to replace it"
msgstr "E122: Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ %s уже Ñ–Ñнує, ! щоб замінити"
-#: ../eval.c:151
msgid "E717: Dictionary entry already exists"
msgstr "E717: Ð—Ð°Ð¿Ð¸Ñ Ñƒ Ñловнику вже Ñ–Ñнує"
-#: ../eval.c:152
msgid "E718: Funcref required"
msgstr "E718: Треба поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° функцію"
-#: ../eval.c:153
msgid "E719: Cannot use [:] with a Dictionary"
msgstr "E719: Ðе можна викориÑтати [:] зі Ñловником"
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: Ðеправильний тип змінної Ð´Ð»Ñ %s="
-
-#: ../eval.c:155
#, c-format
msgid "E130: Unknown function: %s"
msgstr "E130: Ðевідома функціÑ: %s"
-#: ../eval.c:156
#, c-format
msgid "E461: Illegal variable name: %s"
msgstr "E461: ÐеприпуÑтима назва змінної: %s"
-# msgstr "E373: "
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr "E806: Float вжито Ñк String"
+#, c-format
+msgid "E46: Cannot change read-only variable \"%.*s\""
+msgstr "E46: Змінна тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ: «%.*s»"
+
+#, c-format
+msgid "E734: Wrong variable type for %s="
+msgstr "E734: Ðеправильний тип змінної Ð´Ð»Ñ %s="
+
+msgid ""
+"E5700: Expression from 'spellsuggest' must yield lists with exactly two "
+"values"
+msgstr ""
+"E5700: Вираз із 'spellsuggest' має повертати ÑпиÑок із рівно двома елементами"
-#: ../eval.c:1830
msgid "E687: Less targets than List items"
msgstr "E687: Цілей менше, ніж елементів ÑпиÑку"
-#: ../eval.c:1834
msgid "E688: More targets than List items"
msgstr "E688: Цілей більше, ніж елементів ÑпиÑку"
-#: ../eval.c:1906
msgid "Double ; in list of variables"
msgstr "Друга ; у ÑпиÑку змінних"
-# msgstr "E235: "
-#: ../eval.c:2078
#, c-format
msgid "E738: Can't list variables for %s"
msgstr "E738: Ðе можна перерахувати змінні у %s"
-#: ../eval.c:2391
+#, c-format
+msgid "E121: Undefined variable: %.*s"
+msgstr "E121: Ðевизначена змінна: %.*s"
+
msgid "E689: Can only index a List or Dictionary"
msgstr "E689: ІндекÑний доÑтуп може бути тільки до ÑпиÑку чи Ñловника"
-#: ../eval.c:2396
msgid "E708: [:] must come last"
msgstr "E708: [:] має бути оÑтанньою"
-#: ../eval.c:2439
+msgid "E713: Cannot use empty key after ."
+msgstr "E713: Ðеможливо вжити порожній ключ піÑÐ»Ñ ."
+
msgid "E709: [:] requires a List value"
msgstr "E709: [:] вимагає ÑпиÑок"
-#: ../eval.c:2674
msgid "E710: List value has more items than target"
msgstr "E710: СпиÑок має більше елементів, ніж ціль"
-#: ../eval.c:2678
msgid "E711: List value has not enough items"
msgstr "E711: СпиÑок має недоÑтатньо елементів"
-#: ../eval.c:2867
msgid "E690: Missing \"in\" after :for"
msgstr "E690: Пропущено «in» піÑÐ»Ñ :for"
-#: ../eval.c:3063
#, c-format
msgid "E107: Missing parentheses: %s"
msgstr "E107: Пропущено дужки: %s"
-#: ../eval.c:3263
#, c-format
msgid "E108: No such variable: \"%s\""
msgstr "E108: Змінної немає: «%s»"
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: Змінна має забагато вкладень щоб бути за-/відкритою."
+#, c-format
+msgid "E940: Cannot lock or unlock variable %s"
+msgstr "E940: Ðеможливо заблокувати чи розблокувати змінну %s"
-#: ../eval.c:3630
msgid "E109: Missing ':' after '?'"
msgstr "E109: Бракує ':' піÑÐ»Ñ '?'"
-#: ../eval.c:3893
msgid "E691: Can only compare List with List"
msgstr "E691: СпиÑок можна порівнÑти тільки зі ÑпиÑком"
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
+msgid "E692: Invalid operation for List"
msgstr "E692: Ðекоректна Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ð°Ð´ ÑпиÑком"
-#: ../eval.c:3915
msgid "E735: Can only compare Dictionary with Dictionary"
msgstr "E735: Словник можна порівнÑти тільки із Ñловником"
-#: ../eval.c:3917
msgid "E736: Invalid operation for Dictionary"
msgstr "E736: Ðекоректна Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ð°Ð´ Ñловником"
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Функцію можна порівнÑти тільки з функцією"
-
-#: ../eval.c:3934
msgid "E694: Invalid operation for Funcrefs"
msgstr "E694: Ðекоректна Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð½Ð°Ð´ функцією"
-#: ../eval.c:4277
msgid "E804: Cannot use '%' with Float"
msgstr "E804: Ðе можна виконати '%' над Float"
-#: ../eval.c:4478
msgid "E110: Missing ')'"
msgstr "E110: Пропущено ')'"
-#: ../eval.c:4609
msgid "E695: Cannot index a Funcref"
msgstr "E695: Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð½Ðµ має індекÑації"
-#: ../eval.c:4839
+msgid "E909: Cannot index a special variable"
+msgstr "E909: Спеціальна змінна не має індекÑації"
+
#, c-format
msgid "E112: Option name missing: %s"
msgstr "E112: Бракує назви опції: %s"
-#: ../eval.c:4855
#, c-format
msgid "E113: Unknown option: %s"
msgstr "E113: Ðевідома опціÑ: %s"
-#: ../eval.c:4904
#, c-format
msgid "E114: Missing quote: %s"
msgstr "E114: Бракує лапки: %s"
-#: ../eval.c:5020
#, c-format
msgid "E115: Missing quote: %s"
msgstr "E115: Бракує лапки: %s"
-# msgstr "E404: "
-#: ../eval.c:5084
#, c-format
msgid "E696: Missing comma in List: %s"
msgstr "E696: Бракує коми у ÑпиÑку: %s"
-#: ../eval.c:5091
#, c-format
msgid "E697: Missing end of List ']': %s"
msgstr "E697: Ðемає кінцівки ÑпиÑку ']': %s"
-# msgstr "E235: "
-#: ../eval.c:6475
+msgid "Not enough memory to set references, garbage collection aborted!"
+msgstr ""
+"ÐедоÑтатньо пам’Ñті Ð´Ð»Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ñилань, Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ ÑÐ¼Ñ–Ñ‚Ñ‚Ñ Ð¿Ñ€Ð¸Ð¿Ð¸Ð½ÐµÐ½Ð¾!"
+
#, c-format
msgid "E720: Missing colon in Dictionary: %s"
msgstr "E720: Бракує двокрапки у Ñловнику: %s"
-#: ../eval.c:6499
#, c-format
msgid "E721: Duplicate key in Dictionary: \"%s\""
msgstr "E721: ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ð° в Ñловнику: «%s»"
-# msgstr "E235: "
-#: ../eval.c:6517
#, c-format
msgid "E722: Missing comma in Dictionary: %s"
msgstr "E722: Бракує коми у Ñловнику: %s"
-#: ../eval.c:6524
#, c-format
msgid "E723: Missing end of Dictionary '}': %s"
msgstr "E723: Ðемає кінцівки Ñловника '}': %s"
-# msgstr "E21: "
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: У змінній забагато вкладень щоб її показати"
+#, c-format
+msgid "E125: Illegal argument: %s"
+msgstr "E125: Ðедозволений аргумент: %s"
+
+#, c-format
+msgid "E853: Duplicate argument name: %s"
+msgstr "E853: Ðазва аргументу повторюєтьÑÑ: %s"
-#: ../eval.c:7188
#, c-format
msgid "E740: Too many arguments for function %s"
msgstr "E740: Забагато аргументів Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ— %s"
-#: ../eval.c:7190
#, c-format
msgid "E116: Invalid arguments for function %s"
msgstr "E116: Ðеправильні аргументи функції %s"
-#: ../eval.c:7377
#, c-format
msgid "E117: Unknown function: %s"
msgstr "E117: Ðевідома функціÑ: %s"
-#: ../eval.c:7383
+#, c-format
+msgid "E933: Function was deleted: %s"
+msgstr "E933: Функцію було видалено: %s"
+
#, c-format
msgid "E119: Not enough arguments for function: %s"
msgstr "E119: Замало аргументів Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ— %s"
-#: ../eval.c:7387
#, c-format
msgid "E120: Using <SID> not in a script context: %s"
msgstr "E120: <SID> викориÑтовуєтьÑÑ Ð½Ðµ у контекÑті Ñкрипту: %s"
-#: ../eval.c:7391
#, c-format
msgid "E725: Calling dict function without Dictionary: %s"
msgstr "E725: Виклик dict-функції без Ñловника: %s"
-#: ../eval.c:7453
-msgid "E808: Number or Float required"
-msgstr "E808: Треба вказати Number чи Float"
+#, c-format
+msgid "Error converting the call result: %s"
+msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ результат виклику: %s"
-# msgstr "E14: "
-#: ../eval.c:7503
msgid "add() argument"
msgstr "аргумент add()"
-#: ../eval.c:7907
msgid "E699: Too many arguments"
msgstr "E699: Забагато аргументів"
-# msgstr "E327: "
-#: ../eval.c:8073
+#, c-format
+msgid "Invalid channel stream \"%s\""
+msgstr "Ðекоректний потік Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Â«%s»"
+
msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() можна вживати тільки в режимі вÑтавки"
+msgstr "E785: complete() можна вживати тільки в режимі вÑтавлÑннÑ"
-#: ../eval.c:8156
msgid "&Ok"
msgstr "&O:Гаразд"
-# msgstr "E226: "
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: Ключ вже Ñ–Ñнує: %s"
+msgid "dictwatcheradd() argument"
+msgstr "аргумент dictwatcheradd()"
-# msgstr "E14: "
-#: ../eval.c:8692
msgid "extend() argument"
msgstr "аргумент extend()"
-# msgstr "E14: "
-#: ../eval.c:8915
msgid "map() argument"
msgstr "аргумент map()"
-# msgstr "E14: "
-#: ../eval.c:8916
msgid "filter() argument"
msgstr "аргумент filter()"
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld Ñ€Ñдків: "
-
-#: ../eval.c:9291
#, c-format
msgid "E700: Unknown function: %s"
msgstr "E700: Ðевідома функціÑ: %s"
-#: ../eval.c:10729
+msgid "E922: expected a dict"
+msgstr "E922: очікуєтьÑÑ Ñловник"
+
+msgid "E923: Second argument of function() must be a list or a dict"
+msgstr "E923: Другий аргумент function() має бути ÑпиÑком чи Ñловником"
+
+msgid "E5000: Cannot find tab number."
+msgstr "E5000: Ðе можна знайти номер вкладки."
+
+msgid "E5001: Higher scope cannot be -1 if lower scope is >= 0."
+msgstr "E5001: Вища облаÑть не може бути -1, Ñкщо нижча облаÑть >= 0."
+
+msgid "E5002: Cannot find window number."
+msgstr "E5002: Ðеможливо знайти номер вікна."
+
+msgid "E5050: {opts} must be the only argument"
+msgstr "E5050: {opts} має бути єдиним аргументом"
+
msgid "called inputrestore() more often than inputsave()"
msgstr "Виклики до inputrestore() чаÑтіше, ніж до inputsave()"
-# msgstr "E14: "
-#: ../eval.c:10771
msgid "insert() argument"
msgstr "аргумент insert()"
-# msgstr "E406: "
-#: ../eval.c:10841
msgid "E786: Range not allowed"
msgstr "E786: Інтервал не дозволено"
-# msgstr "E177: "
-#: ../eval.c:11140
+msgid "E474: Failed to convert list to string"
+msgstr "E474: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ ÑпиÑок у текÑÑ‚"
+
+#, c-format
+msgid "E474: Failed to parse %.*s"
+msgstr "E474: Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ %.*s"
+
msgid "E701: Invalid type for len()"
msgstr "E701: Ðекоректний тип Ð´Ð»Ñ len()"
-#: ../eval.c:11980
+#, c-format
+msgid "E798: ID is reserved for \":match\": %<PRId64>"
+msgstr "E798: ID зарезервовано Ð´Ð»Ñ \":match\": %<PRId64>"
+
+#, c-format
+msgid "E798: ID is reserved for \"match\": %<PRId64>"
+msgstr "E798: ID зарезервовано Ð´Ð»Ñ \"match\": %<PRId64>"
+
+#, c-format
+msgid "msgpackdump() argument, index %i"
+msgstr "аргумент msgpackdump(), Ñ–Ð½Ð´ÐµÐºÑ %i"
+
+msgid "E5070: Character number must not be less than zero"
+msgstr "E5070: Ðомер Ñимвола має бути невід’ємним"
+
+#, c-format
+msgid "E5071: Character number must not be greater than INT_MAX (%i)"
+msgstr "E5071: Ðомер Ñимвола не може бути більшим, ніж INT_MAX (%i)"
+
msgid "E726: Stride is zero"
msgstr "E726: Крок нульовий"
-#: ../eval.c:11982
msgid "E727: Start past end"
msgstr "E727: Початок за кінцем"
-#: ../eval.c:12024 ../eval.c:15297
msgid "<empty>"
msgstr "<нічого>"
-# msgstr "E14: "
-#: ../eval.c:12282
msgid "remove() argument"
msgstr "аргумент remove()"
-#: ../eval.c:12466
msgid "E655: Too many symbolic links (cycle?)"
msgstr "E655: Забагато Ñимвольних поÑилань (цикл?)"
-# msgstr "E14: "
-#: ../eval.c:12593
msgid "reverse() argument"
msgstr "аргумент reverse()"
-# msgstr "E14: "
-#: ../eval.c:13721
+#, c-format
+msgid "E5010: List item %d of the second argument is not a string"
+msgstr "E5010: Елемент ÑпиÑку %d другого аргументу не текÑÑ‚"
+
+#, c-format
+msgid "E927: Invalid action: '%s'"
+msgstr "E927: Ðеправильна діÑ: «%s»"
+
+#, c-format
+msgid "E474: List item %d is either not a dictionary or an empty one"
+msgstr "E474: Елемент ÑпиÑку %d або не Ñловник або порожній"
+
+#, c-format
+msgid "E474: List item %d is missing one of the required keys"
+msgstr "E474: Елемент ÑпиÑку %d немає одного з обов’Ñзкових ключів"
+
+#, c-format
+msgid "connection failed: %s"
+msgstr "Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½Ðµ вдалоÑÑ: %s"
+
msgid "sort() argument"
msgstr "аргумент sort()"
-# msgstr "E14: "
-#: ../eval.c:13721
-#, fuzzy
msgid "uniq() argument"
-msgstr "аргумент add()"
+msgstr "аргумент uniq()"
-# msgstr "E364: "
-#: ../eval.c:13776
msgid "E702: Sort compare function failed"
msgstr "E702: Помилка у функції порівнÑннÑ"
-# msgstr "E364: "
-#: ../eval.c:13806
-#, fuzzy
msgid "E882: Uniq compare function failed"
-msgstr "E702: Помилка у функції порівнÑннÑ"
+msgstr "E882: Помилка у функції порівнÑÐ½Ð½Ñ uniq"
+
+#, c-format
+msgid "E6100: \"%s\" is not a valid stdpath"
+msgstr "E6100: \"%s\" — некоректний stdpath"
-#: ../eval.c:14085
msgid "(Invalid)"
msgstr "(Ðеможливо)"
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати тимчаÑовий файл"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr "E805: Float вжито Ñк Number"
+#, c-format
+msgid "E935: invalid submatch number: %d"
+msgstr "E935: неправильний номер групи ÑпівпадіннÑ: %d"
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: Funcref вжито Ñк Number"
+#, c-format
+msgid "Executing command: \"%s\""
+msgstr "ВиконуєтьÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°: «%s»"
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: List вжито Ñк Number"
+msgid "Can only call this function in an unmodified buffer"
+msgstr "Цю функцію можна викликати тільки у незміненому буфері"
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: Dictionary вжито Ñк Number"
+msgid "E921: Invalid callback argument"
+msgstr "E921: Ðекоректний аргумент функції зворотнього виклику"
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: Funcref вжито Ñк String"
+#, c-format
+msgid "E80: Error while writing: %s"
+msgstr "E80: Помилка під Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñу: %s"
-# msgstr "E373: "
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: List вжито Ñк String"
+#, c-format
+msgid "E5060: Unknown flag: %s"
+msgstr "E5060: Ðевідомий прапорець: %s"
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: Dictionary вжито Ñк String"
+msgid "E482: Can't open file with an empty name"
+msgstr "E482: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл з порожнім ім’Ñм"
-#: ../eval.c:16619
#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: Ðеправильний тип змінної: %s"
+msgid "E482: Can't open file %s for writing: %s"
+msgstr "E482: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл %s Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу: %s"
-#: ../eval.c:16705
#, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E795: Ðе можна знищити змінну %s"
+msgid "E80: Error when closing file %s: %s"
+msgstr "E80: Помилка при закритті файлу %s: %s"
-#: ../eval.c:16724
#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Ðазва змінної Funcref має починатиÑÑ Ð· великої літери: %s"
+msgid "E963: setting %s to value with wrong type"
+msgstr "E963: вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ %s до Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð· неправильним типом"
-#: ../eval.c:16732
#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: Ðазва змінної Ñпівпадає з Ñ–Ñнуючою функцією: %s"
+msgid "E794: Cannot set variable in the sandbox: \"%.*s\""
+msgstr "E794: Ðе можна вÑтановити змінну у піÑочниці: «%.*s»"
-#: ../eval.c:16763
#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð°Ñ…Ð¸Ñ‰ÐµÐ½Ðµ: %s"
+msgid "E795: Cannot delete variable %.*s"
+msgstr "E795: Ðе можна знищити змінну %.*s"
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "Ðевідомо"
+#, c-format
+msgid "E704: Funcref variable name must start with a capital: %s"
+msgstr "E704: Ðазва змінної Funcref має починатиÑÑ Ð· великої літери: %s"
-#: ../eval.c:16768
#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: Ðе можна змінити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s"
+msgid "E705: Variable name conflicts with existing function: %s"
+msgstr "E705: Ðазва змінної Ñпівпадає з Ñ–Ñнуючою функцією: %s"
-#: ../eval.c:16838
msgid "E698: variable nested too deep for making a copy"
msgstr "E698: Змінна вкладена занадто глибоко щоб зробити її копію"
-#: ../eval.c:17249
#, c-format
msgid "E123: Undefined function: %s"
msgstr "E123: Ðевизначена функціÑ: %s"
-#: ../eval.c:17260
#, c-format
msgid "E124: Missing '(': %s"
msgstr "E124: Бракує '(': %s"
-#: ../eval.c:17293
msgid "E862: Cannot use g: here"
msgstr "E862: Тут не можна викориÑтати g:"
-#: ../eval.c:17312
#, 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
-#, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E853: Ðазва аргументу повторюєтьÑÑ: %s"
-
-#: ../eval.c:17416
msgid "E126: Missing :endfunction"
msgstr "E126: Бракує :endfunction"
-#: ../eval.c:17537
+#, c-format
+msgid "W22: Text found after :endfunction: %s"
+msgstr "W22: ТрапивÑÑ Ñ‚ÐµÐºÑÑ‚ піÑÐ»Ñ :endfunction: %s"
+
#, c-format
msgid "E707: Function name conflicts with variable: %s"
msgstr "E707: Ðазва функції Ñпівпадає зі змінною: %s"
-#: ../eval.c:17549
#, c-format
msgid "E127: Cannot redefine function %s: It is in use"
msgstr "E127: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ функцію %s: вона викориÑтовуєтьÑÑ"
-#: ../eval.c:17604
#, 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.c:17824
-#, fuzzy, c-format
+#, c-format
msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Ðазва функції має починатиÑÑ Ð· великої літери або міÑтити двокрапку: %s"
+msgstr "E128: Ðазва функції має починатиÑÑ Ð· великої літери або \"s:\": %s"
-#: ../eval.c:17833
-#, fuzzy, c-format
+#, c-format
msgid "E884: Function name cannot contain a colon: %s"
-msgstr ""
-"E128: Ðазва функції має починатиÑÑ Ð· великої літери або міÑтити двокрапку: %s"
+msgstr "E884: Ðазва функції не може міÑтити двокрапку: %s"
-#: ../eval.c:18336
#, c-format
msgid "E131: Cannot delete function %s: It is in use"
msgstr "E131: Ðе вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ функцію %s: Вона викориÑтовуєтьÑÑ"
-#: ../eval.c:18441
+#, c-format
+msgid "Cannot delete function %s: It is being used internally"
+msgstr "Ðе вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ функцію %s: Вона викориÑтовуєтьÑÑ"
+
msgid "E132: Function call depth is higher than 'maxfuncdepth'"
msgstr "E132: Глибина викликів функції перевищує 'maxfuncdepth'"
-#: ../eval.c:18568
#, c-format
msgid "calling %s"
msgstr "викликаєтьÑÑ %s"
-#: ../eval.c:18651
#, c-format
msgid "%s aborted"
msgstr "%s припинено"
-#: ../eval.c:18653
#, c-format
msgid "%s returning #%<PRId64>"
msgstr "%s повертає #%<PRId64>"
-#: ../eval.c:18670
#, c-format
msgid "%s returning %s"
msgstr "%s повертає %s"
-#: ../eval.c:18691 ../ex_cmds2.c:2695
#, c-format
msgid "continuing in %s"
msgstr "Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ Ð² %s"
-#: ../eval.c:18795
msgid "E133: :return not inside a function"
msgstr "E133: :return поза межами функції"
-#: ../eval.c:19159
msgid ""
"\n"
-"# global variables:\n"
+"\tLast set from "
msgstr ""
"\n"
-"# глобальні змінні:\n"
+"\tВоÑтаннє змінена у "
+
+msgid "E5009: $VIMRUNTIME is empty or unset"
+msgstr "E5009: $VIMRUNTIME Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ Ñ‡Ð¸ не вÑтановлена"
+
+#, c-format
+msgid "E5009: Invalid $VIMRUNTIME: %s"
+msgstr "E5009: Ðекоректна $VIMRUNTIME: %s"
+
+msgid "E5009: Invalid 'runtimepath'"
+msgstr "E5009: Ðекоректний 'runtimepath'"
+
+#, c-format
+msgid "E474: Expected comma before list item: %s"
+msgstr "E474: ОчікуєтьÑÑ ÐºÐ¾Ð¼Ð° перед елементом ÑпиÑка: %s"
+
+#, c-format
+msgid "E474: Expected colon before dictionary value: %s"
+msgstr "E474: ОчікуєтьÑÑ Ð´Ð²Ð¾ÐºÑ€Ð°Ð¿ÐºÐ° перед значеннÑм у Ñловнику: %s"
+
+#, c-format
+msgid "E474: Expected string key: %s"
+msgstr "E474: ОчікуєтьÑÑ Ñ‚ÐµÐºÑтовий ключ: %s"
+
+#, c-format
+msgid "E474: Expected comma before dictionary key: %s"
+msgstr "E474: ОчікуєтьÑÑ ÐºÐ¾Ð¼Ð° перед Ñловниковим ключем: %s"
+
+#, c-format
+msgid "E474: Unfinished escape sequence: %.*s"
+msgstr "E474: Ðе закінчено поÑлідовніÑть escape: %.*s"
+
+#, c-format
+msgid "E474: Unfinished unicode escape sequence: %.*s"
+msgstr "E474: Ðе закінчено escape-поÑлідовніÑть юнікоду: %.*s"
-#: ../eval.c:19254
+#, c-format
+msgid "E474: Expected four hex digits after \\u: %.*s"
+msgstr "E474: ОчікуєтьÑÑ Ñ‡Ð¾Ñ‚Ð¸Ñ€Ð¸ шіÑтнадцÑткові цифри піÑÐ»Ñ \\u: %.*s"
+
+#, c-format
+msgid "E474: Unknown escape sequence: %.*s"
+msgstr "E474: Ðевідома поÑлідовніÑть escape: %.*s"
+
+#, c-format
+msgid "E474: ASCII control characters cannot be present inside string: %.*s"
+msgstr "E474: Керуючі Ñимволи ASCII не можуть бути вÑередині текÑту: %.*s"
+
+#, c-format
+msgid "E474: Only UTF-8 strings allowed: %.*s"
+msgstr "E474: Дозволено тільки текÑÑ‚ UTF-8: %.*s"
+
+#, c-format
msgid ""
-"\n"
-"\tLast set from "
+"E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: "
+"%.*s"
msgstr ""
-"\n"
-"\tВоÑтаннє змінена у "
+"E474: Тільки точки коду UTF-8 до U+10FFFF можуть бути приÑутні без escape: "
+"%.*s"
-#: ../eval.c:19272
-msgid "No old files"
-msgstr "Жодного Ñтарого файлу"
+#, c-format
+msgid "E474: Expected string end: %.*s"
+msgstr "E474: ОчікувавÑÑ ÐºÑ–Ð½ÐµÑ†ÑŒ Ñ€Ñдка: %.*s"
-#: ../ex_cmds.c:122
#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, шіÑÑ‚ %02x, Ð²Ñ–Ñ %03o"
+msgid "E474: Leading zeroes are not allowed: %.*s"
+msgstr "E474: Початкові нулі не дозволено: %.*s"
-#: ../ex_cmds.c:145
#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, шіÑÑ‚ %04x, Ð²Ñ–Ñ %o"
+msgid "E474: Missing number after minus sign: %.*s"
+msgstr "E474: Бракує чиÑла піÑÐ»Ñ Ð·Ð½Ð°ÐºÑƒ: %.*s"
-#: ../ex_cmds.c:146
#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, шіÑÑ‚ %08x, Ð²Ñ–Ñ %o"
+msgid "E474: Missing number after decimal dot: %.*s"
+msgstr "E474: Бракує чиÑла піÑÐ»Ñ Ð´ÐµÑÑткової крапки: %.*s"
+
+#, c-format
+msgid "E474: Missing exponent: %.*s"
+msgstr "E474: Бракує екÑпоненти: %.*s"
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: Ðеможливо переміÑтити Ñ€Ñдки Ñамі в Ñебе"
+#, c-format
+msgid ""
+"E685: internal error: while converting number \"%.*s\" to float string2float "
+"consumed %zu bytes in place of %zu"
+msgstr ""
+"E685: Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: при перетворенні чиÑла «%.*s» у float, string2float "
+"Ñпожив %zu байтів заміÑть %zu"
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "Переміщено один Ñ€Ñдок"
+#, c-format
+msgid ""
+"E685: internal error: while converting number \"%.*s\" to integer vim_str2nr "
+"consumed %i bytes in place of %zu"
+msgstr ""
+"E685: Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: при перетворенні чиÑла «%.*s» у ціле, vim_str2nr "
+"Ñпожив %i байтів заміÑть %zu"
+
+msgid "E474: Attempt to decode a blank string"
+msgstr "E474: Спроба Ð´ÐµÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ€Ð¾Ð¶Ð½ÑŒÐ¾Ð³Ð¾ текÑту"
-#: ../ex_cmds.c:749
#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "Переміщено %<PRId64> Ñ€Ñдки(ів)"
+msgid "E474: No container to close: %.*s"
+msgstr "E474: Ðемає контейнера щоб закрити: %.*s"
-#: ../ex_cmds.c:1175
#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "Відфільтровано %<PRId64> Ñ€Ñдки(ів)"
+msgid "E474: Closing list with curly bracket: %.*s"
+msgstr "E474: ЗакриваєтьÑÑ ÑпиÑок фігурною дужкою: %.*s"
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: Ðвтокоманди *Filter* не повинні змінювати поточний буфер"
+#, c-format
+msgid "E474: Closing dictionary with square bracket: %.*s"
+msgstr "E474: Ð—Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñловника квадратною дужкою: %.*s"
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[Зміни не запиÑано]\n"
+#, c-format
+msgid "E474: Trailing comma: %.*s"
+msgstr "E474: Зайва кома: %.*s"
-#: ../ex_cmds.c:1424
#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s в Ñ€Ñдку: "
+msgid "E474: Expected value after colon: %.*s"
+msgstr "E474: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ–ÑÐ»Ñ Ð´Ð²Ð¾ÐºÑ€Ð°Ð¿ÐºÐ¸: %.*s"
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: Забагато помилок, решта файлу буде пропущено"
+#, c-format
+msgid "E474: Expected value: %.*s"
+msgstr "E474: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ: %.*s"
-#: ../ex_cmds.c:1458
#, c-format
-msgid "Reading viminfo file \"%s\"%s%s%s"
-msgstr "ЗчитуєтьÑÑ Ñ„Ð°Ð¹Ð» viminfo: «%s»%s%s%s"
+msgid "E474: Comma not inside container: %.*s"
+msgstr "E474: Кома поза контейнером: %.*s"
-#: ../ex_cmds.c:1460
-msgid " info"
-msgstr " інформаціÑ"
+#, c-format
+msgid "E474: Duplicate comma: %.*s"
+msgstr "E474: Зайва кома: %.*s"
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " позначки"
+#, c-format
+msgid "E474: Comma after colon: %.*s"
+msgstr "E474: Кома піÑÐ»Ñ Ð´Ð²Ð¾ÐºÑ€Ð°Ð¿ÐºÐ¸: %.*s"
-#: ../ex_cmds.c:1462
-msgid " oldfiles"
-msgstr " Ñтарі файли"
+#, c-format
+msgid "E474: Using comma in place of colon: %.*s"
+msgstr "E474: Кома заміÑть двокрапки: %.*s"
-#: ../ex_cmds.c:1463
-msgid " FAILED"
-msgstr " ÐЕ ВДÐЛОСЯ"
+#, c-format
+msgid "E474: Leading comma: %.*s"
+msgstr "E474: Кома на початку: %.*s"
+
+#, c-format
+msgid "E474: Colon not inside container: %.*s"
+msgstr "E474: Двокрапка не вÑередині контейнера: %.*s"
+
+#, c-format
+msgid "E474: Using colon not in dictionary: %.*s"
+msgstr "E474: Двокрапка не в Ñловнику: %.*s"
+
+#, c-format
+msgid "E474: Unexpected colon: %.*s"
+msgstr "E474: ÐеÑподівана двокрапка: %.*s"
+
+#, c-format
+msgid "E474: Colon after comma: %.*s"
+msgstr "E474: Двокрапка піÑÐ»Ñ ÐºÐ¾Ð¼Ð¸: %.*s"
+
+#, c-format
+msgid "E474: Duplicate colon: %.*s"
+msgstr "E474: Зайва двокрапка: %.*s"
+
+#, c-format
+msgid "E474: Expected null: %.*s"
+msgstr "E474: ÐеÑподіваний null: %.*s"
+
+#, c-format
+msgid "E474: Expected true: %.*s"
+msgstr "E474: ОчікуєтьÑÑ true: %.*s"
-#. 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"
+msgid "E474: Expected false: %.*s"
+msgstr "E474: ОчікуєтьÑÑ false: %.*s"
-#: ../ex_cmds.c:1626
#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати файл viminfo %s!"
+msgid "E474: Unidentified byte: %.*s"
+msgstr "E474: Ðевизначений байт: %.*s"
-#: ../ex_cmds.c:1635
#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» viminfo «%s»"
+msgid "E474: Trailing characters: %.*s"
+msgstr "E474: Ðадлишкові Ñимволи: %.*s"
-#. Write the info:
-#: ../ex_cmds.c:1720
#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# Цей файл автоматично Ñтворений Vim %s.\n"
+msgid "E474: Unexpected end of input: %.*s"
+msgstr "E474: ÐеÑподіваний кінець: %.*s"
-#: ../ex_cmds.c:1722
+#, c-format
+msgid "key %s"
+msgstr "ключ %s"
+
+#, c-format
+msgid "key %s at index %i from special map"
+msgstr "ключ %s за індекÑом %i із Ñпеціальної мапи"
+
+#, c-format
+msgid "index %i"
+msgstr "Ñ–Ð½Ð´ÐµÐºÑ %i"
+
+msgid "partial"
+msgstr "чаÑтковий"
+
+#, c-format
+msgid "argument %i"
+msgstr "аргумент %i"
+
+msgid "partial self dictionary"
+msgstr "чаÑтковий Ñловник self"
+
+msgid "itself"
+msgstr "Ñам Ñебе"
+
+msgid "E724: unable to correctly dump variable with self-referencing container"
+msgstr ""
+"E724: не вдалоÑÑ ÐºÐ¾Ñ€ÐµÐºÑ‚Ð½Ð¾ злити змінну з контейнером, Ñкий Ñам на Ñебе "
+"поÑилаєтьÑÑ"
+
+msgid "E474: Unable to represent NaN value in JSON"
+msgstr "E474: Ðеможливо предÑтавити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ NaN у JSON"
+
+msgid "E474: Unable to represent infinity in JSON"
+msgstr "E474: Ðеможливо предÑтавити неÑкінченніÑть у JSON"
+
+#, c-format
msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
+"E474: String \"%.*s\" contains byte that does not start any UTF-8 character"
+msgstr "E474: ТекÑÑ‚ \"%.*s\" міÑтить байт, що не починає жодного Ñимволу UTF-8"
+
+#, c-format
+msgid ""
+"E474: UTF-8 string contains code point which belongs to a surrogate pair: "
+"%.*s"
msgstr ""
-"# Можете редагувати, але ОБЕРЕЖÐО!\n"
-"\n"
+"E474: текÑÑ‚ UTF-8 міÑтить точку кодуваннÑ, Ñка належить Ñурогатній парі: %.*s"
+
+msgid "E474: Unable to convert EXT string to JSON"
+msgstr "E474: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ Ñ€Ñдок EXT у JSON"
+
+#, c-format
+msgid "E474: Error while dumping %s, %s: attempt to dump function reference"
+msgstr "E474: Помилка при злитті %s, %s: Ñпроба злити поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° функцію"
+
+msgid "E474: Invalid key in special dictionary"
+msgstr "E474: Ðеправильний ключ у Ñпеціальному Ñловнику"
+
+msgid "encode_tv2string() argument"
+msgstr "аргумент encode_tv2string()"
+
+msgid ":echo argument"
+msgstr "аргумент :echo"
+
+msgid "encode_tv2json() argument"
+msgstr "аргумент encode_tv2json()"
+
+#, c-format
+msgid "E5004: Error while dumping %s, %s: attempt to dump function reference"
+msgstr "E5004: Помилка при злитті %s, %s: Ñпроба злити поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° функцію"
+
+#, c-format
+msgid "E5005: Unable to dump %s: container references itself in %s"
+msgstr "E5005: Ðеможливо злити %s: контейнер поÑилаєтьÑÑ Ð½Ð° Ñамого Ñебе у %s"
+
+#, c-format
+msgid "E684: list index out of range: %<PRId64>"
+msgstr "E684: Ð†Ð½Ð´ÐµÐºÑ ÑпиÑку поза межами: %<PRId64>"
+
+#, c-format
+msgid "E5142: Failed to open file %s: %s"
+msgstr "E5142: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл %s: %s"
+
+#, c-format
+msgid "E5143: Failed to write to file %s: %s"
+msgstr "E5143: Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати у файл %s: %s"
+
+#, c-format
+msgid "E5144: Failed to close file %s: %s"
+msgstr "E5144: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ файл %s: %s"
+
+msgid "E6000: Argument is not a function or function name"
+msgstr "E6000: Ðргумент не Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ñ‡Ð¸ назва функції"
+
+#, c-format
+msgid "E737: Key already exists: %s"
+msgstr "E737: Ключ вже Ñ–Ñнує: %s"
-#: ../ex_cmds.c:1723
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ 'encoding' під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файлу\n"
+msgid "E743: variable nested too deep for (un)lock"
+msgstr "E743: Змінна має забагато вкладень щоб бути за-/відкритою."
+
+#, c-format
+msgid "E741: Value is locked: %.*s"
+msgstr "E741: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð°Ñ…Ð¸Ñ‰ÐµÐ½Ðµ: %.*s"
+
+#, c-format
+msgid "E742: Cannot change value of %.*s"
+msgstr "E742: Ðе можна змінити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %.*s"
+
+msgid "Unknown"
+msgstr "Ðевідомо"
+
+msgid "E805: Expected a Number or a String, Float found"
+msgstr "E805: ОчікуєтьÑÑ Number чи String, трапивÑÑ Float"
+
+msgid "E703: Expected a Number or a String, Funcref found"
+msgstr "E703: ОчікуєтьÑÑ Number чи String, трапивÑÑ Funcref"
+
+msgid "E745: Expected a Number or a String, List found"
+msgstr "E745: ОчікуєтьÑÑ Number чи String, трапивÑÑ List"
+
+msgid "E728: Expected a Number or a String, Dictionary found"
+msgstr "E728: ОчікуєтьÑÑ Number чи String, трапивÑÑ Dictionary"
+
+msgid "E5300: Expected a Number or a String"
+msgstr "E5300: ОчікуєтьÑÑ Number чи String"
+
+msgid "E745: Using a List as a Number"
+msgstr "E745: List вжито Ñк Number"
+
+msgid "E728: Using a Dictionary as a Number"
+msgstr "E728: Dictionary вжито Ñк Number"
+
+msgid "E805: Using a Float as a Number"
+msgstr "E805: Float вжито Ñк Number"
+
+msgid "E685: using an invalid value as a Number"
+msgstr "E685: некоректне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð¶Ð¸Ñ‚Ð¾ Ñк Number"
+
+msgid "E730: using List as a String"
+msgstr "E730: List вжито Ñк String"
+
+msgid "E731: using Dictionary as a String"
+msgstr "E731: Dictionary вжито Ñк String"
+
+msgid "E908: using an invalid value as a String"
+msgstr "E908: некоректне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ð¶Ð¸Ñ‚Ð¾ Ñк String"
+
+msgid "E891: Using a Funcref as a Float"
+msgstr "E891: Funcref вжито Ñк Float"
+
+msgid "E892: Using a String as a Float"
+msgstr "E892: String вжито Ñк Float"
+
+msgid "E893: Using a List as a Float"
+msgstr "E893: List вжито Ñк Float"
+
+msgid "E894: Using a Dictionary as a Float"
+msgstr "E894: Dictionary вжито Ñк Float"
+
+msgid "E907: Using a special value as a Float"
+msgstr "E907: ВикориÑтано Ñпеціальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñк Float"
+
+msgid "E808: Number or Float required"
+msgstr "E808: Треба вказати Number чи Float"
+
+msgid "tcp address must be host:port"
+msgstr "адреÑа tcp має бути вузол:порт"
+
+msgid "failed to lookup host or port"
+msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ вузол чи порт"
+
+msgid "connection refused"
+msgstr "з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¼Ð¾Ð²Ð»ÐµÐ½Ð¾"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Oct %03o, Digr %s"
+msgstr "<%s>%s%s %d, шіÑÑ‚ %02x, Ð²Ñ–Ñ %03o, дигр %s"
+
+#, c-format
+msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
+msgstr "<%s>%s%s %d, шіÑÑ‚ %02x, Ð²Ñ–Ñ %03o"
+
+#, c-format
+msgid "> %d, Hex %04x, Oct %o, Digr %s"
+msgstr "> %d, шіÑÑ‚ %04x, Ð²Ñ–Ñ %o, дигр %s"
+
+#, c-format
+msgid "> %d, Hex %08x, Oct %o, Digr %s"
+msgstr "> %d, шіÑÑ‚ %08x, Ð²Ñ–Ñ %o, дигр %s"
+
+#, c-format
+msgid "> %d, Hex %04x, Octal %o"
+msgstr "> %d, шіÑÑ‚ %04x, Ð²Ñ–Ñ %o"
+
+#, c-format
+msgid "> %d, Hex %08x, Octal %o"
+msgstr "> %d, шіÑÑ‚ %08x, Ð²Ñ–Ñ %o"
+
+msgid "E134: Cannot move a range of lines into itself"
+msgstr "E134: Ðеможливо переміÑтити діапазон Ñ€Ñдків Ñам у Ñебе"
+
+msgid "1 line moved"
+msgstr "Переміщено один Ñ€Ñдок"
+
+#, c-format
+msgid "%<PRId64> lines moved"
+msgstr "Переміщено %<PRId64> Ñ€Ñдки(ів)"
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "Ðедозволений Ñимвол на початку Ñ€Ñдка"
+#, c-format
+msgid "E482: Can't create file %s"
+msgstr "E482: Ðе вдалоÑÑ Ñтворити файл %s"
+
+#, c-format
+msgid "%<PRId64> lines filtered"
+msgstr "Відфільтровано %<PRId64> Ñ€Ñдки(ів)"
+
+msgid "E135: *Filter* Autocommands must not change current buffer"
+msgstr "E135: Ðвтокоманди *Filter* не повинні змінювати поточний буфер"
+
+msgid "[No write since last change]\n"
+msgstr "[Зміни не запиÑано]\n"
-#: ../ex_cmds.c:2162
msgid "Write partial file?"
msgstr "ЗапиÑати чаÑтину файлу?"
-#: ../ex_cmds.c:2166
msgid "E140: Use ! to write partial buffer"
msgstr "E140: ВикориÑтайте ! Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу чаÑтини буфера"
-#: ../ex_cmds.c:2281
#, c-format
msgid "Overwrite existing file \"%s\"?"
msgstr "ПерепиÑати Ñ–Ñнуючий файл «%s»?"
-#: ../ex_cmds.c:2317
#, c-format
msgid "Swap file \"%s\" exists, overwrite anyway?"
msgstr "Файл обміну «%s» Ñ–Ñнує, перезапиÑати?"
-#: ../ex_cmds.c:2326
#, c-format
msgid "E768: Swap file exists: %s (:silent! overrides)"
msgstr "E768: Файл обміну Ñ–Ñнує: %s (:silent! переважує)"
-#: ../ex_cmds.c:2381
#, c-format
msgid "E141: No file name for buffer %<PRId64>"
msgstr "E141: Ðемає вхідного файлу Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° %<PRId64>"
-#: ../ex_cmds.c:2412
msgid "E142: File not written: Writing is disabled by 'write' option"
msgstr "E142: Файл не запиÑано: Ð·Ð°Ð¿Ð¸Ñ Ð·Ð°Ð±Ð¾Ñ€Ð¾Ð½ÐµÐ½Ð¾ опцією 'write'"
-#: ../ex_cmds.c:2434
#, c-format
msgid ""
"'readonly' option is set for \"%s\".\n"
@@ -1202,7 +1331,6 @@ msgstr ""
"Ð”Ð»Ñ Â«%s» вÑтановлено 'readonly'.\n"
"Бажаєте вÑе одно продовжити запиÑ?"
-#: ../ex_cmds.c:2439
#, c-format
msgid ""
"File permissions of \"%s\" are read-only.\n"
@@ -1213,816 +1341,636 @@ msgstr ""
"Проте, можливо, його можна запиÑати.\n"
"Хочете Ñпробувати?"
-#: ../ex_cmds.c:2451
#, c-format
msgid "E505: \"%s\" is read-only (add ! to override)"
msgstr "E505: «%s» тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ (! щоб не зважати)"
-#: ../ex_cmds.c:3120
#, c-format
msgid "E143: Autocommands unexpectedly deleted new buffer %s"
msgstr "E143: Ðвтокоманди неÑподівано знищили новий буфер %s"
-#: ../ex_cmds.c:3313
msgid "E144: non-numeric argument to :z"
msgstr "E144: нечиÑловий аргумент Ð´Ð»Ñ :z"
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: У rvim не дозволені команди оболонки"
+msgid "E145: Shell commands not allowed in restricted mode"
+msgstr "E145: У обмеженому режимі не дозволені команди оболонки"
-#: ../ex_cmds.c:3498
msgid "E146: Regular expressions can't be delimited by letters"
msgstr "E146: РегулÑрні вирази не можна розділÑти літерами"
-#: ../ex_cmds.c:3964
#, 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
msgid "(Interrupted) "
msgstr "(Перервано) "
-# msgstr "E31: "
-#: ../ex_cmds.c:4384
msgid "1 match"
msgstr "Один збіг"
-#: ../ex_cmds.c:4384
msgid "1 substitution"
msgstr "Одна заміна"
-#: ../ex_cmds.c:4387
#, c-format
msgid "%<PRId64> matches"
msgstr "%<PRId64> збіги(ів)"
-#: ../ex_cmds.c:4388
#, c-format
msgid "%<PRId64> substitutions"
msgstr "%<PRId64> замін(и)"
-#: ../ex_cmds.c:4392
msgid " on 1 line"
msgstr " в одному Ñ€Ñдку"
-#: ../ex_cmds.c:4395
#, c-format
msgid " on %<PRId64> lines"
msgstr " в %<PRId64> Ñ€Ñдках"
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global не можна вживати рекурÑивно"
+msgid "E147: Cannot do :global recursive with a range"
+msgstr "E147: :global не можна рекурÑивно з діапазоном"
-#: ../ex_cmds.c:4467
msgid "E148: Regular expression missing from global"
msgstr "E148: У global бракує зразка"
-#: ../ex_cmds.c:4508
#, c-format
msgid "Pattern found in every line: %s"
msgstr "Зразок знайдено у кожному Ñ€Ñдку: %s"
-#: ../ex_cmds.c:4510
#, c-format
msgid "Pattern not found: %s"
msgstr "Зразок не знайдено: %s"
-#: ../ex_cmds.c:4587
-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"
+msgid "E151: No match: %s"
+msgstr "E151: Жодного збігу: %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: ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚ÐµÒ‘Ñƒ «%s» у файлі %s/%s"
+msgstr "E154: ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼Ñ–Ñ‚ÐºÐ¸ «%s» у файлі %s/%s"
+
+#, c-format
+msgid "E150: Not a directory: %s"
+msgstr "E150: Ðе Ñ” каталогом: %s"
-#: ../ex_cmds.c:5687
#, c-format
msgid "E160: Unknown sign command: %s"
msgstr "E160: Ðевідома команда надпиÑу: %s"
-#: ../ex_cmds.c:5704
msgid "E156: Missing sign name"
msgstr "E156: Пропущено назву надпиÑу"
-#: ../ex_cmds.c:5746
msgid "E612: Too many signs defined"
msgstr "E612: Визначено забагато надпиÑів"
-#: ../ex_cmds.c:5813
#, c-format
msgid "E239: Invalid sign text: %s"
msgstr "E239: Ðекоректний надпиÑ: %s"
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
#, c-format
msgid "E155: Unknown sign: %s"
msgstr "E155: Ðевідомий надпиÑ: %s"
-#: ../ex_cmds.c:5877
msgid "E159: Missing sign number"
msgstr "E159: Пропущено номер надпиÑу"
-#: ../ex_cmds.c:5971
#, c-format
msgid "E158: Invalid buffer name: %s"
msgstr "E158: Ðекоректна назва буфера: %s"
-#: ../ex_cmds.c:6008
+msgid "E934: Cannot jump to a buffer that does not have a name"
+msgstr "E934: Ðе можна перейти до буфера без назви"
+
#, c-format
msgid "E157: Invalid sign ID: %<PRId64>"
msgstr "E157: Ðеправильний ID надпиÑу: %<PRId64>"
-#: ../ex_cmds.c:6066
+#, c-format
+msgid "E885: Not possible to change sign %s"
+msgstr "E885: Ðеможливо змінити знак %s"
+
msgid " (not supported)"
msgstr " (не підтримуєтьÑÑ)"
-#: ../ex_cmds.c:6169
msgid "[Deleted]"
msgstr "[Знищено]"
-#: ../ex_cmds2.c:139
+msgid "No old files"
+msgstr "Жодного Ñтарого файлу"
+
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"
-#: ../ex_cmds2.c:322
+msgid "frame is zero"
+msgstr "кадр нульовий"
+
+#, c-format
+msgid "frame at highest level: %d"
+msgstr "кадр на найвищому рівні: %d"
+
#, c-format
msgid "Breakpoint in \"%s%s\" line %<PRId64>"
msgstr "Точка зупинки в «%s%s» Ñ€Ñдок %<PRId64>"
-#: ../ex_cmds2.c:581
#, c-format
msgid "E161: Breakpoint not found: %s"
msgstr "E161: Точку зупинки не знайдено: %s"
-#: ../ex_cmds2.c:611
msgid "No breakpoints defined"
msgstr "Ðе визначено жодної точки зупинки"
-#: ../ex_cmds2.c:617
#, c-format
msgid "%3d %s %s line %<PRId64>"
msgstr "%3d %s %s Ñ€Ñдок %<PRId64>"
-#: ../ex_cmds2.c:942
msgid "E750: First use \":profile start {fname}\""
msgstr "E750: Спочатку зробіть «:profile start {файл}»"
-#: ../ex_cmds2.c:1269
#, c-format
msgid "Save changes to \"%s\"?"
msgstr "Зберегти зміни в «%s»?"
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "Ðеназваний"
+#, c-format
+msgid "Close \"%s\"?"
+msgstr "Закрити «%s»?"
-#: ../ex_cmds2.c:1421
#, c-format
msgid "E162: No write since last change for buffer \"%s\""
msgstr "E162: Буфер «%s» має незбережені зміни"
-#: ../ex_cmds2.c:1480
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
#, c-format
msgid "E666: compiler not supported: %s"
msgstr "E666: КомпілÑтор не підтримуєтьÑÑ: %s"
-# msgstr "E195: "
-#: ../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»"
+msgid "not found in '%s': \"%s\""
+msgstr "не знайдено в '%s': «%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"
-# msgstr "E14: "
-#: ../ex_cmds2.c:2767
msgid "--cmd argument"
msgstr "--cmd аргумент"
-# msgstr "E14: "
-#: ../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 "Lua"
+msgstr "Lua"
+
+#, c-format
+msgid "API client (channel id %<PRIu64>)"
+msgstr "Клієнт API (канал «%<PRIu64>»)"
+
msgid "W15: Warning: Wrong line separator, ^M may be missing"
msgstr "W15: ЗаÑтереженнÑ: Ðеправильний роздільник Ñ€Ñдків, можливо, бракує ^M"
-#: ../ex_cmds2.c:3139
msgid "E167: :scriptencoding used outside of a sourced file"
msgstr "E167: :scriptencoding викориÑтано поза виконуваним файлом"
-#: ../ex_cmds2.c:3166
msgid "E168: :finish used outside of a sourced file"
msgstr "E168: :finish викориÑтано поза виконуваним файлом"
-#: ../ex_cmds2.c:3389
#, c-format
msgid "Current %slanguage: \"%s\""
msgstr "Мова (%s): «%s»"
-#: ../ex_cmds2.c:3404
#, c-format
msgid "E197: Cannot set language to \"%s\""
msgstr "E197: Ðе вдалоÑÑ Ð²Ñтановити мову «%s»"
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
msgstr "Режим Ex. Ð”Ð»Ñ Ð¿Ð¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð´Ð¾ нормального режиму виконайте «visual»"
-#: ../ex_docmd.c:428
msgid "E501: At end-of-file"
msgstr "E501: Кінець файлу"
-#: ../ex_docmd.c:513
msgid "E169: Command too recursive"
msgstr "E169: Команда занадто рекурÑивна"
-#: ../ex_docmd.c:1006
+msgid "line %"
+msgstr "Ñ€Ñдок %"
+
#, c-format
msgid "E605: Exception not caught: %s"
msgstr "E605: ВинÑткова ÑÐ¸Ñ‚ÑƒÐ°Ñ†Ñ–Ñ Ð½Ðµ оброблена: %s"
-#: ../ex_docmd.c:1085
msgid "End of sourced file"
msgstr "Кінець виконуваного файлу"
-#: ../ex_docmd.c:1086
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:1729
msgid "E493: Backwards range given"
msgstr "E493: Інтервал задано навиворіт"
-#: ../ex_docmd.c:1733
msgid "Backwards range given, OK to swap"
msgstr "Інтервал задано навиворіт, щоб помінÑти міÑцÑми — ГÐРÐЗД"
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
msgid "E494: Use w or w>>"
msgstr "E494: Спробуйте w або w>>"
-#: ../ex_docmd.c:3454
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 "ЗалишилоÑÑ Ð²Ñ–Ð´Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ ще один файл. Ð’Ñе одно вийти?"
-#: ../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: ЗалишилоÑÑ Ð²Ñ–Ð´Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ ще один файл"
-#: ../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"
+" Name Args Address 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: Лічильник не може бути вказано двічі"
-# msgstr "E177: "
-#: ../ex_docmd.c:4603
msgid "E178: Invalid default value for count"
msgstr "E178: Ðеправильне початкове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ°"
-# msgstr "E178: "
-#: ../ex_docmd.c:4625
msgid "E179: argument required for -complete"
msgstr "E179: Ð´Ð»Ñ -complete потрібний аргумент"
-# msgstr "E180: "
-#: ../ex_docmd.c:4635
+msgid "E179: argument required for -addr"
+msgstr "E179: Ð´Ð»Ñ -addr потрібний аргумент"
+
#, c-format
msgid "E181: Invalid attribute: %s"
msgstr "E181: Ðеправильний атрибут: %s"
-# msgstr "E181: "
-#: ../ex_docmd.c:4678
msgid "E182: Invalid command name"
msgstr "E182: Ðеправильна назва команди"
-# msgstr "E182: "
-#: ../ex_docmd.c:4691
msgid "E183: User defined commands must start with an uppercase letter"
msgstr "E183: Команди кориÑтувача повинні починатиÑÑ Ð· великої літери"
-#: ../ex_docmd.c:4696
msgid "E841: Reserved name, cannot be used for user defined command"
msgstr ""
"E841: Зарезервована назва, не можна викориÑтати Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувацької команди"
-# msgstr "E183: "
-#: ../ex_docmd.c:4751
#, c-format
msgid "E184: No such user-defined command: %s"
msgstr "E184: Команду кориÑтувача не знайдено: %s"
-# msgstr "E179: "
-#: ../ex_docmd.c:5219
+#, c-format
+msgid "E180: Invalid address type value: %s"
+msgstr "E180: Ðеправильне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð¸Ð¿Ñƒ адреÑи: %s"
+
#, 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: Ðргумент дозволений тільки Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувацького доповненнÑ"
-#: ../ex_docmd.c:5231
msgid "E467: Custom completion requires a function argument"
msgstr "E467: КориÑтувацьке Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ” аргумент-функцію"
-# msgstr "E184: "
-#: ../ex_docmd.c:5257
#, c-format
msgid "E185: Cannot find color scheme '%s'"
msgstr "E185: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñхему кольорів «%s»"
-#: ../ex_docmd.c:5263
msgid "Greetings, Vim user!"
msgstr "ВітаннÑ, кориÑтувачу Vim!"
-# msgstr "E443: "
-#: ../ex_docmd.c:5431
msgid "E784: Cannot close last tab page"
msgstr "E784: Ðе можна закрити оÑтанню вкладку"
-# msgstr "E444: "
-#: ../ex_docmd.c:5462
msgid "Already only one tab page"
msgstr "Вже й так лише одна вкладка"
-#: ../ex_docmd.c:6004
#, c-format
msgid "Tab page %d"
msgstr "Вкладка %d"
-#: ../ex_docmd.c:6295
+msgid "E25: Nvim does not have a built-in GUI"
+msgstr "E25: Ðе можна викориÑтати GUI: Ðе ввімкнено під Ñ‡Ð°Ñ ÐºÐ¾Ð¼Ð¿Ñ–Ð»Ñції"
+
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
msgid "E186: No previous directory"
msgstr "E186: Це вже найперший каталог"
-# msgstr "E186: "
-#: ../ex_docmd.c:6530
msgid "E187: Unknown"
msgstr "E187: Ðевідомо"
-#: ../ex_docmd.c:6610
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
#, c-format
msgid "E189: \"%s\" exists (add ! to override)"
msgstr "E189: Файл «%s» Ñ–Ñнує (! щоб не зважати)"
-# msgstr "E189: "
-#: ../ex_docmd.c:7273
#, c-format
msgid "E190: Cannot open \"%s\" for writing"
msgstr "E190: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ «%s» Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу"
-# msgstr "E190: "
-#. set mark
-#: ../ex_docmd.c:7294
msgid "E191: Argument must be a letter or forward/backward quote"
msgstr "E191: Ðргумент має бути літерою, ` або '"
-# msgstr "E191: "
-#: ../ex_docmd.c:7333
msgid "E192: Recursive use of :normal too deep"
msgstr "E192: Забагато вкладених :normal"
-# msgstr "E193: "
-#: ../ex_docmd.c:7807
msgid "E194: No alternate file name to substitute for '#'"
msgstr "E194: Ðемає назви вторинного файлу Ð´Ð»Ñ Ð·Ð°Ð¼Ñ–Ð½Ð¸ '#'"
-#: ../ex_docmd.c:7841
msgid "E495: no autocommand file name to substitute for \"<afile>\""
msgstr "E495: Ðемає назви файлу автокоманди Ð´Ð»Ñ Ð·Ð°Ð¼Ñ–Ð½Ð¸ «<afile>»"
-#: ../ex_docmd.c:7850
msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
msgstr "E496: Ðемає номера буфера автокоманди Ð´Ð»Ñ Ð·Ð°Ð¼Ñ–Ð½Ð¸ «<abuf>»"
-#: ../ex_docmd.c:7861
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: Ðемає назви файлу :source Ð´Ð»Ñ Ð·Ð°Ð¼Ñ–Ð½Ð¸ «<sfile>»"
-#: ../ex_docmd.c:7876
msgid "E842: no line number to use for \"<slnum>\""
msgstr "E842: немає номера Ñ€Ñдка, щоб викориÑтати з «<sfile>»"
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
+#, c-format
msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
msgstr "E499: Ðазва файлу Ð´Ð»Ñ '%' чи '#' порожнÑ, працює лише з «:p:h»"
-#: ../ex_docmd.c:7905
msgid "E500: Evaluates to an empty string"
msgstr "E500: Результат — порожній Ñ€Ñдок"
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ файл viminfo"
+msgid "Untitled"
+msgstr "Ðеназваний"
-#: ../ex_eval.c:464
msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
msgstr "E608: Ðе можна викидати (:throw) винÑтки з префікÑом 'Vim'"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
#, c-format
msgid "Exception thrown: %s"
msgstr "ВинÑткова ÑитуаціÑ: %s"
-#: ../ex_eval.c:545
#, c-format
msgid "Exception finished: %s"
msgstr "ВинÑток закінчено: %s"
-#: ../ex_eval.c:546
#, c-format
msgid "Exception discarded: %s"
msgstr "ВинÑток Ñкинуто: %s"
-#: ../ex_eval.c:588 ../ex_eval.c:634
#, c-format
msgid "%s, line %<PRId64>"
msgstr "%s, Ñ€Ñдок %<PRId64>"
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
#, c-format
msgid "Exception caught: %s"
msgstr "Спіймано винÑткову Ñитуацію: %s"
-#: ../ex_eval.c:676
#, c-format
msgid "%s made pending"
msgstr "ОчікуєтьÑÑ %s"
-#: ../ex_eval.c:679
#, c-format
msgid "%s resumed"
msgstr "Відновлено %s"
-#: ../ex_eval.c:683
#, c-format
msgid "%s discarded"
msgstr "Скинуто %s"
-#: ../ex_eval.c:708
msgid "Exception"
msgstr "ВинÑток"
-#: ../ex_eval.c:713
msgid "Error and interrupt"
msgstr "Помилка, перервано"
-# msgstr "E231: "
-#: ../ex_eval.c:715
msgid "Error"
msgstr "Помилка"
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
msgid "Interrupt"
msgstr "Перервано"
-#: ../ex_eval.c:795
msgid "E579: :if nesting too deep"
msgstr "E579: Занадто багато вкладених :if"
-#: ../ex_eval.c:830
msgid "E580: :endif without :if"
msgstr "E580: :endif без :if"
-#: ../ex_eval.c:873
msgid "E581: :else without :if"
msgstr "E581: :else без :if"
-#: ../ex_eval.c:876
msgid "E582: :elseif without :if"
msgstr "E582: :elseif без :if"
-#: ../ex_eval.c:880
msgid "E583: multiple :else"
msgstr "E583: Ðе одне :else"
-#: ../ex_eval.c:883
msgid "E584: :elseif after :else"
msgstr "E584: :elseif піÑÐ»Ñ :else"
-#: ../ex_eval.c:941
msgid "E585: :while/:for nesting too deep"
msgstr "E585: Забагато вкладених :while/:for"
-#: ../ex_eval.c:1028
msgid "E586: :continue without :while or :for"
msgstr "E586: :continue без :while чи :for"
-#: ../ex_eval.c:1061
msgid "E587: :break without :while or :for"
msgstr "E587: :break без :while чи :for"
-#: ../ex_eval.c:1102
msgid "E732: Using :endfor with :while"
msgstr "E732: Вжито :endfor із :while"
-#: ../ex_eval.c:1104
msgid "E733: Using :endwhile with :for"
msgstr "E733: Вжито :endwhile із :for"
-#: ../ex_eval.c:1247
msgid "E601: :try nesting too deep"
msgstr "E601: Забагато вкладених :try"
-#: ../ex_eval.c:1317
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
msgid "E604: :catch after :finally"
msgstr "E604: :catch піÑÐ»Ñ :finally"
-#: ../ex_eval.c:1451
msgid "E606: :finally without :try"
msgstr "E606: :finally без :try"
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
msgid "E607: multiple :finally"
msgstr "E607: Ðе одне :finally"
-#: ../ex_eval.c:1571
msgid "E602: :endtry without :try"
msgstr "E602: :entry без :try"
-#: ../ex_eval.c:2026
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
msgid "E811: Not allowed to change buffer information now"
msgstr "E811: Зараз не можна змінювати інформацію буфера"
-# msgstr "E197: "
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "назва теґу"
+#, c-format
+msgid "E5408: Unable to get g:Nvim_color_cmdline callback: %s"
+msgstr "E5408: Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ g:Nvim_color_cmdline callback: %s"
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " тип файлу\n"
+#, c-format
+msgid "E5407: Callback has thrown an exception: %s"
+msgstr "E5407: У зворотньому виклику ÑталаÑÑ Ð²Ð¸Ð½Ñткова ÑитуаціÑ: %s"
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "ÐžÐ¿Ñ†Ñ–Ñ 'history' порожнÑ"
+msgid "E5400: Callback should return list"
+msgstr "E5400: Зворотній виклик має повертати ÑпиÑок"
-#: ../ex_getln.c:5046
#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Попередні %s (від найновіших):\n"
+msgid "E5401: List item %i is not a List"
+msgstr "E5401: Елемент ÑпиÑку %i не List"
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "команди"
+#, c-format
+msgid "E5402: List item %i has incorrect length: %d /= 3"
+msgstr "E5402: Елемент ÑпиÑку %i має неправильну довжину: %d /= 3"
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "шукані Ñ€Ñдки"
+msgid "E5403: Chunk %i start %"
+msgstr "E5403: Початок шматка %i %"
+
+msgid "E5405: Chunk %i start %"
+msgstr "E5405: Початок шматка %i %"
+
+msgid "E5404: Chunk %i end %"
+msgstr "E5404: Кінець шматка %i %"
+
+msgid "E5406: Chunk %i end %"
+msgstr "E5406: Кінець шматка %i %"
+
+msgid "tagname"
+msgstr "назва теґу"
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "вирази"
+msgid " kind file\n"
+msgstr " тип файлу\n"
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "введені Ñ€Ñдки"
+msgid "'history' option is zero"
+msgstr "ÐžÐ¿Ñ†Ñ–Ñ 'history' порожнÑ"
-#: ../ex_getln.c:5117
msgid "E198: cmd_pchar beyond the command length"
msgstr "E198: cmd_pchar поза межами команди"
-#: ../ex_getln.c:5279
msgid "E199: Active window or buffer deleted"
msgstr "E199: Ðктивне вікно або буфер було знищено"
-#: ../file_search.c:203
msgid "E854: path too long for completion"
msgstr "E854: шлÑÑ… занадто довгий Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ"
-#: ../file_search.c:446
#, c-format
msgid ""
"E343: Invalid path: '**[number]' must be at the end of the path or be "
@@ -2031,276 +1979,193 @@ msgstr ""
"E343: Ðекоректний шлÑÑ…: `**[чиÑло]' повинне бути наприкінці шлÑху або перед "
"'%s'."
-# msgstr "E343: "
-#: ../file_search.c:1505
#, c-format
msgid "E344: Can't find directory \"%s\" in cdpath"
msgstr "E344: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ каталог «%s» у cdpath"
-# msgstr "E344: "
-#: ../file_search.c:1508
#, c-format
msgid "E345: Can't find file \"%s\" in path"
msgstr "E345: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файл «%s» у path"
-# msgstr "E345: "
-#: ../file_search.c:1512
#, c-format
msgid "E346: No more directory \"%s\" found in cdpath"
msgstr "E346: У cdpath немає більше каталогу «%s»"
-# msgstr "E346: "
-#: ../file_search.c:1515
#, c-format
msgid "E347: No more file \"%s\" found in path"
msgstr "E347: У шлÑху пошуку більше немає файлів «%s»"
-#: ../fileio.c:137
msgid "E812: Autocommands changed buffer or buffer name"
msgstr "E812: Ðвтокоманди змінили буфер чи його назву"
-# msgstr "E199: "
-#: ../fileio.c:368
msgid "Illegal file name"
msgstr "Ðедозволена назва файлу"
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
msgid "is a directory"
msgstr "каталог"
-#: ../fileio.c:397
msgid "is not a file"
msgstr "не файл"
-#: ../fileio.c:508 ../fileio.c:3522
msgid "[New File]"
msgstr "[Ðовий файл]"
-#: ../fileio.c:511
msgid "[New DIRECTORY]"
msgstr "[Ðовий каталог]"
-#: ../fileio.c:529 ../fileio.c:532
msgid "[File too big]"
msgstr "[Файл завеликий]"
-#: ../fileio.c:534
msgid "[Permission Denied]"
msgstr "[Відмовлено]"
-#: ../fileio.c:653
msgid "E200: *ReadPre autocommands made the file unreadable"
msgstr "E200: Ðвтокоманди *ReadPre унеможливили Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ"
-# msgstr "E200: "
-#: ../fileio.c:655
msgid "E201: *ReadPre autocommands must not change current buffer"
msgstr "E201: Ðвтокоманди *ReadPre не повинні змінювати цей буфер"
-# msgstr "E201: "
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: ЧитаєтьÑÑ Ð· stdin...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
msgid "E202: Conversion made file unreadable!"
msgstr "E202: ÐšÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ñ–Ñ ÑƒÐ½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð¸Ð»Ð° Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ!"
-# msgstr "E202: "
-#. fifo or socket
-#: ../fileio.c:1782
msgid "[fifo/socket]"
msgstr "[канал/Ñокет]"
-#. fifo
-#: ../fileio.c:1788
msgid "[fifo]"
msgstr "[канал]"
-#. or socket
-#: ../fileio.c:1794
msgid "[socket]"
msgstr "[Ñокет]"
-#. or character special
-#: ../fileio.c:1801
msgid "[character special]"
msgstr "[Ñпец. Ñимвольний]"
-#: ../fileio.c:1815
msgid "[CR missing]"
msgstr "[Бракує CR]"
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[Розбито довгі Ñ€Ñдки]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
msgid "[NOT converted]"
msgstr "[ÐЕ конвертовано]"
-#: ../fileio.c:1826 ../fileio.c:3515
msgid "[converted]"
msgstr "[конвертовано]"
-#: ../fileio.c:1831
#, c-format
msgid "[CONVERSION ERROR in line %<PRId64>]"
msgstr "[ПОМИЛКРКОÐВЕРТÐЦІЇ у Ñ€Ñдку %<PRId64>]"
-#: ../fileio.c:1835
#, c-format
msgid "[ILLEGAL BYTE in line %<PRId64>]"
msgstr "[ÐЕКОРЕКТÐИЙ БÐЙТ у Ñ€Ñдку %<PRId64>]"
-#: ../fileio.c:1838
msgid "[READ ERRORS]"
msgstr "[ПОМИЛКРЧИТÐÐÐЯ]"
-#: ../fileio.c:2104
msgid "Can't find temp file for conversion"
msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´ÑˆÑƒÐºÐ°Ñ‚Ð¸ тимчаÑовий файл Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ñ–Ñ—"
-#: ../fileio.c:2110
msgid "Conversion with 'charconvert' failed"
msgstr "ÐšÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ñ–Ñ Ð· 'charconvert' не вдалаÑÑ"
-#: ../fileio.c:2113
msgid "can't read output of 'charconvert'"
msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ вивід 'charconvert'"
-# msgstr "E217: "
-#: ../fileio.c:2437
msgid "E676: No matching autocommands for acwrite buffer"
msgstr "E676: Ðемає відповідних автокоманд"
-#: ../fileio.c:2466
msgid "E203: Autocommands deleted or unloaded buffer to be written"
msgstr "E203: Ðвтокоманда знищила або вивантажила буфер, що мав бути запиÑаний"
-#: ../fileio.c:2486
msgid "E204: Autocommand changed number of lines in unexpected way"
msgstr "E204: Ðвтокоманда неÑподіваним чином змінила кількіÑть Ñ€Ñдків"
-#: ../fileio.c:2548 ../fileio.c:2565
msgid "is not a file or writable device"
msgstr "Ðе придатний Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу"
-#: ../fileio.c:2601
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: Помилка Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð³Ð¾ файлу (! щоб не зважати)"
+#, c-format
+msgid "E507: Close error for backup file (add ! to override): %s"
+msgstr "E507: Помилка Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð³Ð¾ файлу (! щоб не зважати): %s"
-#: ../fileio.c:2901
msgid "E508: Can't read file for backup (add ! to override)"
msgstr ""
"E508: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ файл щоб Ñтворити резервну копію (! щоб не "
"зважати)"
-#: ../fileio.c:2923
msgid "E509: Cannot create backup file (add ! to override)"
msgstr "E509: Ðе вдалоÑÑ Ñтворити резервну копію (! щоб не зважати)"
-#: ../fileio.c:3008
msgid "E510: Can't make backup file (add ! to override)"
msgstr "E510: Ðе вдалоÑÑ Ð·Ñ€Ð¾Ð±Ð¸Ñ‚Ð¸ резервну копію (! щоб не зважати)"
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
msgid "E214: Can't find temp file for writing"
msgstr "E214: Ðе вдалоÑÑ Ð¿Ñ–Ð´ÑˆÑƒÐºÐ°Ñ‚Ð¸ тимчаÑовий файл Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу"
-#: ../fileio.c:3134
msgid "E213: Cannot convert (add ! to write without conversion)"
msgstr "E213: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ (! щоб запиÑати без конвертації)"
-#: ../fileio.c:3169
msgid "E166: Can't open linked file for writing"
msgstr "E166: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу зв'Ñзаний файл"
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу"
+#, c-format
+msgid "E212: Can't open file for writing: %s"
+msgstr "E212: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу: %s"
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ fsync"
+#, c-format
+msgid "E667: Fsync failed: %s"
+msgstr "E667: Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ fsync: %s"
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸"
+#, c-format
+msgid "E512: Close failed: %s"
+msgstr "E512: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸: %s"
-#: ../fileio.c:3436
msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
msgstr "E513: Помилка запиÑу, ÐºÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑ (Ñкиньте 'fenc')"
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-"E513: Помилка запиÑу, ÐºÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑ Ñƒ Ñ€Ñдку %<PRId64> (Ñкиньте "
-"'fenc')"
+msgid "E513: write error, conversion failed in line %"
+msgstr "E513: Помилка запиÑу, Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ðµ вдалаÑÑ Ñƒ Ñ€Ñдку %"
-#: ../fileio.c:3448
msgid "E514: write error (file system full?)"
msgstr "E514: Помилка запиÑу (ÑкінчилоÑÑŒ вільне міÑце?)"
-#: ../fileio.c:3506
msgid " CONVERSION ERROR"
msgstr " ПОМИЛКРКОÐВЕРТÐЦІЇ"
-#: ../fileio.c:3509
#, c-format
msgid " in line %<PRId64>;"
msgstr " у Ñ€Ñдку %<PRId64>;"
-#: ../fileio.c:3519
msgid "[Device]"
msgstr "[ПриÑтрій]"
-#: ../fileio.c:3522
msgid "[New]"
msgstr "[Ðовий]"
-#: ../fileio.c:3535
msgid " [a]"
msgstr "[д]"
-#: ../fileio.c:3535
msgid " appended"
msgstr " допиÑаний"
-#: ../fileio.c:3537
msgid " [w]"
msgstr "[з]"
-#: ../fileio.c:3537
msgid " written"
msgstr " запиÑаний"
-#: ../fileio.c:3579
msgid "E205: Patchmode: can't save original file"
msgstr "E205: ЛатаннÑ: не вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ оригінал"
-#: ../fileio.c:3602
msgid "E206: patchmode: can't touch empty original file"
msgstr "E206: ЛатаннÑ: не вдалоÑÑ Ñтворити оригінал"
-#: ../fileio.c:3616
msgid "E207: Can't delete backup file"
msgstr "E207: Ðе вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ резервний файл"
-#: ../fileio.c:3672
msgid ""
"\n"
"WARNING: Original file may be lost or damaged\n"
@@ -2308,134 +2173,102 @@ msgstr ""
"\n"
"ЗÐСТЕРЕЖЕÐÐЯ: Оригінал, мабуть, втрачений чи пошкоджений\n"
-#: ../fileio.c:3675
msgid "don't quit the editor until the file is successfully written!"
msgstr "Ðе виходьте з редактора, доки файл не запиÑано!"
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
msgid "[dos format]"
msgstr "[формат dos]"
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
+msgid "[dos]"
+msgstr "[dos]"
-#: ../fileio.c:3801
msgid "[mac format]"
msgstr "[формат mac]"
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
+msgid "[mac]"
+msgstr "[mac]"
-#: ../fileio.c:3807
msgid "[unix format]"
msgstr "[формат unix]"
-#: ../fileio.c:3831
+msgid "[unix]"
+msgstr "[unix]"
+
msgid "1 line, "
msgstr "один Ñ€Ñдок, "
-#: ../fileio.c:3833
#, c-format
msgid "%<PRId64> lines, "
msgstr "%<PRId64> Ñ€Ñдків, "
-#: ../fileio.c:3836
msgid "1 character"
msgstr "один Ñимвол"
-#: ../fileio.c:3838
#, c-format
msgid "%<PRId64> characters"
msgstr "%<PRId64> Ñимволів"
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
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
+msgid "[noeol]"
+msgstr "[noeol]"
+
msgid "WARNING: The file has been changed since reading it!!!"
msgstr "ЗÐСТЕРЕЖЕÐÐЯ: Файл змінивÑÑ Ð· чаÑу оÑтаннього читаннÑ!!!"
-#: ../fileio.c:3867
msgid "Do you really want to write to it"
msgstr "Ви Ñправді хочете його перепиÑати??"
-#: ../fileio.c:4648
#, c-format
msgid "E208: Error writing to \"%s\""
msgstr "E208: Помилка запиÑу у «%s»"
-#: ../fileio.c:4655
#, c-format
msgid "E209: Error closing \"%s\""
msgstr "E209: Помилка Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Â«%s»"
-#: ../fileio.c:4657
#, c-format
msgid "E210: Error reading \"%s\""
msgstr "E210: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Â«%s»"
-#: ../fileio.c:4883
msgid "E246: FileChangedShell autocommand deleted buffer"
msgstr "E246: Ðвтокоманда FileChangedShell знищила буфер"
-#: ../fileio.c:4894
#, c-format
msgid "E211: File \"%s\" no longer available"
msgstr "E211: Файл «%s» більше не доÑÑжний"
-#: ../fileio.c:4906
#, 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
msgid "See \":help W12\" for more info."
msgstr "Див. «:help W12» Ð´Ð»Ñ ÑƒÑ‚Ð¾Ñ‡Ð½ÐµÐ½Ð½Ñ."
-#: ../fileio.c:4910
#, c-format
msgid "W11: Warning: File \"%s\" has changed since editing started"
msgstr "W11: ЗаÑтереженнÑ: Файл «%s» змінивÑÑ Ð¿Ñ–ÑÐ»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ редагуваннÑ"
-#: ../fileio.c:4911
msgid "See \":help W11\" for more info."
msgstr "Див. «:help W11» Ð´Ð»Ñ ÑƒÑ‚Ð¾Ñ‡Ð½ÐµÐ½Ð½Ñ."
-#: ../fileio.c:4914
#, c-format
msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
msgstr "W16: ЗаÑтереженнÑ: Режим файлу «%s» змінивÑÑ Ð¿Ñ–ÑÐ»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ редагуваннÑ"
-#: ../fileio.c:4915
msgid "See \":help W16\" for more info."
msgstr "Див. «:help W16» Ð´Ð»Ñ ÑƒÑ‚Ð¾Ñ‡Ð½ÐµÐ½Ð½Ñ."
-#: ../fileio.c:4927
#, c-format
msgid "W13: Warning: File \"%s\" has been created after editing started"
msgstr "W13: ЗаÑтереженнÑ: Файл «%s» було Ñтворено піÑÐ»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ редагуваннÑ"
-#: ../fileio.c:4947
msgid "Warning"
msgstr "ЗаÑтереженнÑ"
-#: ../fileio.c:4948
msgid ""
"&OK\n"
"&Load File"
@@ -2443,854 +2276,681 @@ msgstr ""
"&O:Гаразд\n"
"&L:Завантажити"
-#: ../fileio.c:5065
#, c-format
msgid "E462: Could not prepare for reloading \"%s\""
msgstr "E462: Ðе вдалоÑÑ Ð¿Ñ–Ð´Ð³Ð¾Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ «%s», щоб перечитати"
-#: ../fileio.c:5078
#, 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 <буфер=%d>"
-#. the group doesn't exist
-#: ../fileio.c:5772
#, c-format
msgid "E367: No such group: \"%s\""
msgstr "E367: Ðемає такої групи: «%s»"
-#: ../fileio.c:5897
+msgid "E936: Cannot delete the current group"
+msgstr "E936: Ðе вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ цю групу"
+
+msgid "W19: Deleting augroup that is still in use"
+msgstr "W19: Ð—Ð½Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ð³Ñ€ÑƒÐ¿Ð¸, Ñка вÑе ще викориÑтовуєтьÑÑ"
+
#, c-format
msgid "E215: Illegal character after *: %s"
msgstr "E215: Ðедозволений Ñимвол піÑÐ»Ñ *: %s"
-# msgstr "E215: "
-#: ../fileio.c:5905
#, c-format
msgid "E216: No such event: %s"
msgstr "E216: Ðемає такої події: %s"
-# msgstr "E215: "
-#: ../fileio.c:5907
#, c-format
msgid "E216: No such group or event: %s"
msgstr "E216: Ðемає такої групи чи події: %s"
-# msgstr "E216: "
-#. Highlight title
-#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Ðвтокоманди ---"
-#: ../fileio.c:6293
#, c-format
msgid "E680: <buffer=%d>: invalid buffer number "
msgstr "E680: <буфер=%d>: некоректний номер буфера "
-#: ../fileio.c:6370
msgid "E217: Can't execute autocommands for ALL events"
msgstr "E217: Ðе можу виконувати автокоманди Ð´Ð»Ñ Ð£Ð¡Ð†Ð¥ подій"
-# msgstr "E217: "
-#: ../fileio.c:6393
msgid "No matching autocommands"
msgstr "Ðемає відповідних автокоманд"
-#: ../fileio.c:6831
msgid "E218: autocommand nesting too deep"
msgstr "E218: Забагато вкладених автокоманд"
-# msgstr "E218: "
-#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "Ðвтокоманди %s Ð´Ð»Ñ Â«%s»"
+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
msgid "E219: Missing {."
msgstr "E219: Бракує {."
-# msgstr "E219: "
-#: ../fileio.c:7797
msgid "E220: Missing }."
msgstr "E220: Бракує }."
-# msgstr "E220: "
-#: ../fold.c:93
msgid "E490: No fold found"
msgstr "E490: Згорток не знайдено"
-# msgstr "E349: "
-#: ../fold.c:544
msgid "E350: Cannot create fold with current 'foldmethod'"
msgstr "E350: Ðе вдалоÑÑ Ñтворити згортку методом 'foldmethod'"
-#: ../fold.c:546
msgid "E351: Cannot delete fold with current 'foldmethod'"
msgstr "E351: Ðе вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ згортку методом 'foldmethod'"
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+-- згорнуто %3ld Ñ€Ñдків "
-
-#. buffer has already been read
-#: ../getchar.c:273
msgid "E222: Add to read buffer"
msgstr "E222: Додати до буфера читаннÑ"
-#: ../getchar.c:2040
msgid "E223: recursive mapping"
-msgstr "E223: Заміна рекурÑивна"
+msgstr "E223: Заміна клавіш рекурÑивна"
-# msgstr "E223: "
-#: ../getchar.c:2849
#, c-format
msgid "E224: global abbreviation already exists for %s"
msgstr "E224: Загальне ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s вже Ñ–Ñнує"
-# msgstr "E224: "
-#: ../getchar.c:2852
#, c-format
msgid "E225: global mapping already exists for %s"
-msgstr "E225: Загальна заміна Ð´Ð»Ñ %s вже Ñ–Ñнує"
+msgstr "E225: Глобальна заміна клавіш Ð´Ð»Ñ %s вже Ñ–Ñнує"
-# msgstr "E225: "
-#: ../getchar.c:2952
#, c-format
msgid "E226: abbreviation already exists for %s"
msgstr "E226: Вже Ñ” ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s"
-# msgstr "E226: "
-#: ../getchar.c:2955
#, c-format
msgid "E227: mapping already exists for %s"
-msgstr "E227: Вже Ñ” заміна Ð´Ð»Ñ %s"
+msgstr "E227: Вже Ñ” заміна клавіш Ð´Ð»Ñ %s"
-# msgstr "E227: "
-#: ../getchar.c:3008
msgid "No abbreviation found"
msgstr "Ð¡ÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ знайдено"
-#: ../getchar.c:3010
msgid "No mapping found"
-msgstr "Заміни не знайдено"
+msgstr "Заміни клавіш не знайдено"
-#: ../getchar.c:3974
msgid "E228: makemap: Illegal mode"
msgstr "E228: makemap: ÐеприпуÑтимий режим"
-# msgstr "E447: "
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
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
msgid "E470: Command aborted"
msgstr "E470: Команду перервано"
-#: ../globals.h:997
+msgid "E905: Cannot set this option after startup"
+msgstr "E905: Ðе вдалоÑÑ Ð²Ñтановити цю опцію піÑÐ»Ñ Ð·Ð°Ð¿ÑƒÑку"
+
+msgid "E903: Could not spawn API job"
+msgstr "E903: Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити задачу"
+
msgid "E471: Argument required"
msgstr "E471: Ðеобхідно вказати аргумент"
-#: ../globals.h:998
msgid "E10: \\ should be followed by /, ? or &"
msgstr "E10: За \\ має йти /, ? або &"
-# msgstr "E10: "
-#: ../globals.h:1000
msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
msgstr "E11: ÐеприпуÑтимо у вікні команд, <CR> виконує, CTRL-C виходить"
-#: ../globals.h:1002
msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
msgstr ""
-"E12: Команда не дозволена у exrc/vimrc у пошуку поточного каталогу чи теґу"
+"E12: Команда не дозволена у exrc/vimrc у пошуку поточного каталогу чи мітки"
-#: ../globals.h:1003
msgid "E171: Missing :endif"
msgstr "E171: Бракує :endif"
-#: ../globals.h:1004
msgid "E600: Missing :endtry"
msgstr "E600: Бракує :endtry"
-#: ../globals.h:1005
msgid "E170: Missing :endwhile"
msgstr "E170: Бракує :endwhile"
-#: ../globals.h:1006
msgid "E170: Missing :endfor"
msgstr "E170: Бракує :endfor"
-#: ../globals.h:1007
msgid "E588: :endwhile without :while"
msgstr "E588: :endwhile без :while"
-#: ../globals.h:1008
msgid "E588: :endfor without :for"
msgstr "E588: :endfor без :for"
-#: ../globals.h:1009
msgid "E13: File exists (add ! to override)"
msgstr "E13: Файл Ñ–Ñнує (! щоб не зважати)"
-#: ../globals.h:1010
msgid "E472: Command failed"
msgstr "E472: Команда на вдалаÑÑŒ"
-#: ../globals.h:1011
msgid "E473: Internal error"
msgstr "E473: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°"
-#: ../globals.h:1012
+#, c-format
+msgid "E685: Internal error: %s"
+msgstr "E685: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: %s"
+
msgid "Interrupted"
msgstr "Перервано"
-#: ../globals.h:1013
msgid "E14: Invalid address"
msgstr "E14: Ðеправильна адреÑа"
-# msgstr "E14: "
-#: ../globals.h:1014
msgid "E474: Invalid argument"
msgstr "E474: Ðекоректний аргумент"
-#: ../globals.h:1015
#, c-format
msgid "E475: Invalid argument: %s"
msgstr "E475: Ðекоректний аргумент: %s"
-#: ../globals.h:1016
#, c-format
msgid "E15: Invalid expression: %s"
msgstr "E15: Ðеправильний вираз: %s"
-# msgstr "E15: "
-#: ../globals.h:1017
msgid "E16: Invalid range"
msgstr "E16: Ðеправильні межі"
-# msgstr "E16: "
-#: ../globals.h:1018
msgid "E476: Invalid command"
msgstr "E476: Ðекоректна команда"
-#: ../globals.h:1019
#, c-format
msgid "E17: \"%s\" is a directory"
msgstr "E17: «%s» — це каталог"
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: Ðекоректний розмір зÑуву"
+msgid "E900: Invalid channel id"
+msgstr "E900: Ðекоректний канал"
+
+msgid "E900: Invalid channel id: not a job"
+msgstr "E900: Ðекоректний канал: не завданнÑ"
-#: ../globals.h:1021
msgid "E901: Job table is full"
-msgstr ""
+msgstr "E901: Ð¢Ð°Ð±Ð»Ð¸Ñ†Ñ Ð·Ð°Ð²Ð´Ð°Ð½ÑŒ заповнена"
-#: ../globals.h:1022
#, c-format
-msgid "E902: \"%s\" is not an executable"
+msgid "E903: Process failed to start: %s: \"%s\""
+msgstr "E903: Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити процеÑ: %s: \"%s\""
+
+msgid "E904: channel is not a pty"
+msgstr "E904: канал не пÑевдотермінал"
+
+#, c-format
+msgid "E905: Couldn't open stdio channel: %s"
+msgstr "E905: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ канал stdio: «%s»"
+
+msgid "E906: invalid stream for channel"
+msgstr "E906: Ðекоректний потік Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ"
+
+msgid "E906: invalid stream for rpc channel, use 'rpc'"
+msgstr "E906: Ðекоректний потік Ð´Ð»Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ rpc, use 'rpc'"
+
+#, c-format
+msgid ""
+"E5210: dict key '%s' already set for buffered stream in channel %<PRIu64>"
msgstr ""
+"E5210: ключ Ñловника '%s' вже вÑтановлено Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð¸Ð·Ð¾Ð²Ð°Ð½Ð¾Ð³Ð¾ потоку у каналі "
+"%<PRIu64>"
-#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
msgstr "E364: Бібліотечний виклик до «%s()» не вдавÑÑ"
-# msgstr "E18: "
-#: ../globals.h:1026
+#, c-format
+msgid "E739: Cannot create directory %s: %s"
+msgstr "E739: Ðе вдалоÑÑ Ñтворити каталог %s: %s"
+
msgid "E19: Mark has invalid line number"
msgstr "E19: У помітки некоректний номер Ñ€Ñдка"
-# msgstr "E19: "
-#: ../globals.h:1027
msgid "E20: Mark not set"
msgstr "E20: Помітку не вÑтановлено"
-# msgstr "E20: "
-#: ../globals.h:1029
msgid "E21: Cannot make changes, 'modifiable' is off"
msgstr "E21: Зміни не дозволені: вимкнено 'modifiable'"
-# msgstr "E21: "
-#: ../globals.h:1030
msgid "E22: Scripts nested too deep"
msgstr "E22: Забагато вкладених Ñкриптів"
-# msgstr "E22: "
-#: ../globals.h:1031
msgid "E23: No alternate file"
msgstr "E23: Ðемає вторинного файлу"
-# msgstr "E23: "
-#: ../globals.h:1032
msgid "E24: No such abbreviation"
msgstr "E24: Такого ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð½ÐµÐ¼Ð°Ñ”"
-# msgstr "E24: "
-#: ../globals.h:1033
msgid "E477: No ! allowed"
msgstr "E477: ! не дозволено"
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: Ðе можна викориÑтати GUI: Ðе ввімкнено під Ñ‡Ð°Ñ ÐºÐ¾Ð¼Ð¿Ñ–Ð»Ñції"
-
-# msgstr "E25: "
-#: ../globals.h:1036
#, c-format
msgid "E28: No such highlight group name: %s"
msgstr "E28: Ðемає такої групи підÑвічуваннÑ: %s"
-# msgstr "E28: "
-#: ../globals.h:1037
msgid "E29: No inserted text yet"
msgstr "E29: ТекÑÑ‚ ще не було додано"
-# msgstr "E29: "
-#: ../globals.h:1038
msgid "E30: No previous command line"
msgstr "E30: Ще не було команд"
-# msgstr "E30: "
-#: ../globals.h:1039
msgid "E31: No such mapping"
-msgstr "E31: Ðемає такої заміни"
+msgstr "E31: Ðемає такої заміни клавіш"
-# msgstr "E31: "
-#: ../globals.h:1040
msgid "E479: No match"
msgstr "E479: Жодного збігу"
-#: ../globals.h:1041
#, c-format
msgid "E480: No match: %s"
msgstr "E480: Жодного збігу: %s"
-#: ../globals.h:1042
msgid "E32: No file name"
msgstr "E32: Бракує назви файлу"
-# msgstr "E32: "
-#: ../globals.h:1044
msgid "E33: No previous substitute regular expression"
msgstr "E33: Заміна зразків ще не викориÑтовувалаÑÑŒ"
-# msgstr "E33: "
-#: ../globals.h:1045
msgid "E34: No previous command"
msgstr "E34: Команд ще не було"
-# msgstr "E34: "
-#: ../globals.h:1046
msgid "E35: No previous regular expression"
msgstr "E35: Зразків пошуку ще не було"
-# msgstr "E35: "
-#: ../globals.h:1047
msgid "E481: No range allowed"
msgstr "E481: Ðе дозволено вказувати межі"
-#: ../globals.h:1048
msgid "E36: Not enough room"
msgstr "E36: МіÑÑ†Ñ Ð½Ðµ виÑтачить"
-# msgstr "E36: "
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: Ðе вдалоÑÑ Ñтворити файл %s"
-
-#: ../globals.h:1050
msgid "E483: Can't get temp file name"
msgstr "E483: Ðе вдалоÑÑ Ñформувати назву тимчаÑового файлу"
-#: ../globals.h:1051
#, c-format
msgid "E484: Can't open file %s"
msgstr "E484: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл %s"
-#: ../globals.h:1052
+#, c-format
+msgid "E484: Can't open file %s: %s"
+msgstr "E484: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл %s: %s"
+
#, 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"
+msgstr "E37: Ðе запиÑано піÑÐ»Ñ Ð¾Ñтанніх змін"
-#: ../globals.h:1056
msgid "E38: Null argument"
msgstr "E38: ВідÑутній аргумент"
-#: ../globals.h:1057
msgid "E39: Number expected"
msgstr "E39: ОчікуєтьÑÑ Ñ‡Ð¸Ñло"
-#: ../globals.h:1058
#, c-format
msgid "E40: Can't open errorfile %s"
msgstr "E40: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл помилок %s"
-#: ../globals.h:1059
msgid "E41: Out of memory!"
msgstr "E41: Забракло пам'Ñті!"
-#: ../globals.h:1060
msgid "Pattern not found"
msgstr "Зразок не знайдено"
-#: ../globals.h:1061
#, c-format
msgid "E486: Pattern not found: %s"
msgstr "E486: Зразок не знайдено: %s"
-#: ../globals.h:1062
msgid "E487: Argument must be positive"
msgstr "E487: Ðргумент має бути додатний"
-#: ../globals.h:1064
msgid "E459: Cannot go back to previous directory"
msgstr "E459: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ñ‚Ð¸ до попереднього каталогу"
-#: ../globals.h:1066
msgid "E42: No Errors"
msgstr "E42: Жодної помилки"
-#: ../globals.h:1067
msgid "E776: No location list"
msgstr "E776: Ðемає ÑпиÑку міÑць"
-#: ../globals.h:1068
msgid "E43: Damaged match string"
msgstr "E43: ТекÑÑ‚ збігу пошкоджено"
-#: ../globals.h:1069
msgid "E44: Corrupted regexp program"
msgstr "E44: ЗіпÑована програма регулÑрних виразів"
-#: ../globals.h:1071
msgid "E45: 'readonly' option is set (add ! to override)"
msgstr "E45: Ð’Ñтановлено опцію 'readonly' (! щоб не зважати)"
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: Змінна тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ: «%s»"
-
-#: ../globals.h:1075
-#, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E794: Ðе можна вÑтановити змінну у піÑочниці: «%s»"
-
-#: ../globals.h:1076
msgid "E47: Error while reading errorfile"
msgstr "E47: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ помилок"
-#: ../globals.h:1078
msgid "E48: Not allowed in sandbox"
msgstr "E48: Ðа дозволено у піÑочниці"
-#: ../globals.h:1080
msgid "E523: Not allowed here"
msgstr "E523: Ðе дозволено тут"
-#: ../globals.h:1082
msgid "E359: Screen mode setting not supported"
msgstr "E359: Режим екрану не підтримуєтьÑÑ"
-#: ../globals.h:1083
msgid "E49: Invalid scroll size"
msgstr "E49: Ðекоректний розмір зÑуву"
-#: ../globals.h:1084
msgid "E91: 'shell' option is empty"
msgstr "E91: ÐžÐ¿Ñ†Ñ–Ñ 'shell' порожнÑ"
-# msgstr "E254: "
-#: ../globals.h:1085
msgid "E255: Couldn't read in sign data!"
msgstr "E255: Ðе можна зчитати дані напиÑу!"
-#: ../globals.h:1086
msgid "E72: Close error on swap file"
msgstr "E72: Помилка під Ñ‡Ð°Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ„Ð°Ð¹Ð»Ñƒ обміну"
-#: ../globals.h:1087
msgid "E73: tag stack empty"
-msgstr "E73: Стек теґів порожній"
+msgstr "E73: Стек міток порожній"
-#: ../globals.h:1088
msgid "E74: Command too complex"
msgstr "E74: Занадто Ñкладна команда"
-#: ../globals.h:1089
msgid "E75: Name too long"
msgstr "E75: Задовге ім'Ñ"
-#: ../globals.h:1090
msgid "E76: Too many ["
msgstr "E76: Забагато '['"
-#: ../globals.h:1091
msgid "E77: Too many file names"
msgstr "E77: Забагато назв файлів"
-#: ../globals.h:1092
msgid "E488: Trailing characters"
msgstr "E488: Ðадлишкові Ñимволи"
-#: ../globals.h:1093
+#, c-format
+msgid "E488: Trailing characters: %s"
+msgstr "E488: Ðадлишкові Ñимволи: %s"
+
msgid "E78: Unknown mark"
msgstr "E78: Ðевідома помітка"
-#: ../globals.h:1094
msgid "E79: Cannot expand wildcards"
msgstr "E79: Ðе вдалоÑÑ Ñ€Ð¾Ð·ÐºÑ€Ð¸Ñ‚Ð¸ шаблон"
-#: ../globals.h:1096
msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
msgstr "E591: 'winheight' не може бути меншим за 'winminheight'"
-#: ../globals.h:1098
msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
msgstr "E592: 'winwidth' не може бути меншим за 'winminwidth'"
-# msgstr "E79: "
-#: ../globals.h:1099
msgid "E80: Error while writing"
msgstr "E80: Помилка під Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñу"
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "Ðульова кількіÑть"
+msgid "E939: Positive count required"
+msgstr "E939: Потрібна додана кількіÑть"
-#: ../globals.h:1101
msgid "E81: Using <SID> not in a script context"
msgstr "E81: <SID> викориÑтовуєтьÑÑ Ð½Ðµ в контекÑті Ñкрипту"
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: %s"
-
-#: ../globals.h:1104
msgid "E363: pattern uses more memory than 'maxmempattern'"
msgstr "E363: Зразок викориÑтовує більше, ніж 'maxmempattern', пам'Ñті"
-#: ../globals.h:1105
msgid "E749: empty buffer"
msgstr "E749: Порожній буфер"
-#: ../globals.h:1108
+#, c-format
+msgid "E86: Buffer %<PRId64> does not exist"
+msgstr "E86: Буфера %<PRId64> немає"
+
msgid "E682: Invalid search pattern or delimiter"
msgstr "E682: Ðекоректний зразок Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ чи роздільник"
-#: ../globals.h:1109
msgid "E139: File is loaded in another buffer"
msgstr "E139: Файл уже завантажено в інший буфер"
-# msgstr "E235: "
-#: ../globals.h:1110
#, c-format
msgid "E764: Option '%s' is not set"
msgstr "E764: ÐžÐ¿Ñ†Ñ–Ñ '%s' не вÑтановлена"
-#: ../globals.h:1111
msgid "E850: Invalid register name"
msgstr "E850: Ðеправильна назва регіÑтру"
-#: ../globals.h:1114
+#, c-format
+msgid "E919: Directory not found in '%s': \"%s\""
+msgstr "E919: Каталог не знайдено у '%s': «%s»"
+
+msgid "E952: Autocommand caused recursive behavior"
+msgstr "E952: Ðвтокоманди призвели до рекурÑÑ–Ñ—"
+
+msgid "E519: Option not supported"
+msgstr "E519: ÐžÐ¿Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ"
+
+msgid "E856: Filename too long"
+msgstr "E856: Задовга назва файлу"
+
+msgid "E806: using Float as a String"
+msgstr "E806: Float вжито Ñк String"
+
+#, c-format
+msgid "E5500: autocmd has thrown an exception: %s"
+msgstr "E5500: автокоманда викинула винÑткову Ñитуацію: %s"
+
+msgid "E5520: <Cmd> mapping must end with <CR>"
+msgstr "E5520: Заміна клавіш <Cmd> має закінчуватиÑÑ <CR>"
+
+msgid "E5521: <Cmd> mapping must end with <CR> before second <Cmd>"
+msgstr "E5521: Заміна клавіш <Cmd> має закінчуватиÑÑ <CR> перед другою <Cmd>"
+
+#, c-format
+msgid "E5522: <Cmd> mapping must not include %s key"
+msgstr "E5522: Заміна клавіш <Cmd> не може міÑтити ключ %s"
+
msgid "search hit TOP, continuing at BOTTOM"
msgstr "Пошук дійшов до ПОЧÐТКУ, продовжуєтьÑÑ Ð· КІÐЦЯ"
-#: ../globals.h:1115
msgid "search hit BOTTOM, continuing at TOP"
msgstr "Пошук дійшов до КІÐЦЯ, продовжуєтьÑÑ Ð· ПОЧÐТКУ"
-#: ../hardcopy.c:240
msgid "E550: Missing colon"
msgstr "E550: Пропущено двокрапку"
-# msgstr "E347: "
-#: ../hardcopy.c:252
msgid "E551: Illegal component"
msgstr "E551: Ðекоректний компонент"
-#: ../hardcopy.c:259
msgid "E552: digit expected"
msgstr "E552: очікуєтьÑÑ Ñ†Ð¸Ñ„Ñ€Ð°"
-#: ../hardcopy.c:473
#, c-format
msgid "Page %d"
msgstr "Сторінка %d"
-#: ../hardcopy.c:597
msgid "No text to be printed"
msgstr "Ðічого друкувати"
-#: ../hardcopy.c:668
#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "ДрукуєтьÑÑ Ñторінка %d (%d%%)"
+msgid "Printing page %d (%zu%%)"
+msgstr "ДрукуєтьÑÑ Ñторінка %d (%zu%%)"
-#: ../hardcopy.c:680
#, c-format
msgid " Copy %d of %d"
msgstr " ÐšÐ¾Ð¿Ñ–Ñ %d з %d"
-#: ../hardcopy.c:733
#, c-format
msgid "Printed: %s"
msgstr "Ðадруковано: %s"
-#: ../hardcopy.c:740
msgid "Printing aborted"
msgstr "Друк перервано"
-#: ../hardcopy.c:1365
msgid "E455: Error writing to PostScript output file"
msgstr "E455: Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати вихідний файл PostScript"
-#: ../hardcopy.c:1747
#, c-format
msgid "E624: Can't open file \"%s\""
msgstr "E624: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл «%s»"
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
#, c-format
msgid "E457: Can't read PostScript resource file \"%s\""
msgstr "E457: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ файл реÑурÑів PostScript «%s»"
-#: ../hardcopy.c:1772
#, 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
#, c-format
msgid "E619: file \"%s\" is not a supported PostScript resource file"
msgstr "E619: «%s» не Ñ” підтримуваним файлом реÑурÑів PostScript"
-#: ../hardcopy.c:1856
#, c-format
msgid "E621: \"%s\" resource file has wrong version"
msgstr "E621: Ðеправильна верÑÑ–Ñ Ñ„Ð°Ð¹Ð»Ñƒ реÑурÑів «%s»"
-#: ../hardcopy.c:2225
msgid "E673: Incompatible multi-byte encoding and character set."
msgstr "E673: ÐеÑуміÑні багатобайтове ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð¹ набір Ñимволів."
-#: ../hardcopy.c:2238
msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
msgstr ""
"E674: printmbcharset не може бути порожнім з багатобайтовим кодуваннÑм."
-#: ../hardcopy.c:2254
msgid "E675: No default font specified for multi-byte printing."
msgstr "E675: Ðе зазначено шрифт Ð´Ð»Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾Ð±Ð°Ð¹Ñ‚Ð¾Ð²Ð¾Ð³Ð¾ друку."
-#: ../hardcopy.c:2426
msgid "E324: Can't open PostScript output file"
msgstr "E324: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл PostScript Ð´Ð»Ñ Ð²Ð¸Ð²Ð¾Ð´Ñƒ"
-#: ../hardcopy.c:2458
#, c-format
msgid "E456: Can't open file \"%s\""
msgstr "E456: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл «%s»"
-#: ../hardcopy.c:2583
msgid "E456: Can't find PostScript resource file \"prolog.ps\""
msgstr "E456: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файл реÑурÑів PostScript «prolog.ps»"
-#: ../hardcopy.c:2593
msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
msgstr "E456: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файл реÑурÑів PostScript «cidfont.ps»"
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
#, c-format
msgid "E456: Can't find PostScript resource file \"%s.ps\""
msgstr "E456: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ файл реÑурÑів PostScript «%s.ps»"
-#: ../hardcopy.c:2654
#, c-format
msgid "E620: Unable to convert to print encoding \"%s\""
msgstr "E620: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ до ÐºÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ñ€ÑƒÐºÑƒ «%s»"
-#: ../hardcopy.c:2877
msgid "Sending to printer..."
msgstr "ВідÑилаєтьÑÑ Ð½Ð° принтер..."
-#: ../hardcopy.c:2881
msgid "E365: Failed to print PostScript file"
msgstr "E365: Ðе вдалоÑÑ Ð½Ð°Ð´Ñ€ÑƒÐºÑƒÐ²Ð°Ñ‚Ð¸ файл PostScript"
-#: ../hardcopy.c:2883
msgid "Print job sent."
msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð´Ñ€ÑƒÐºÑƒ відіÑлано."
-# msgstr "E255: "
-#: ../if_cscope.c:85
+msgid "E424: Too many different highlighting attributes in use"
+msgstr "E424: ВикориÑтано забагато різних атрибутів кольору"
+
msgid "Add a new database"
msgstr "Додати нову базу даних"
-#: ../if_cscope.c:87
msgid "Query for a pattern"
msgstr "Запит за зразком"
-#: ../if_cscope.c:89
msgid "Show this message"
msgstr "Показати це повідомленнÑ"
-#: ../if_cscope.c:91
msgid "Kill a connection"
msgstr "Знищити з'єднаннÑ"
-#: ../if_cscope.c:93
msgid "Reinit all connections"
msgstr "ПерезапуÑтити уÑÑ– з'єднаннÑ"
-#: ../if_cscope.c:95
msgid "Show connections"
msgstr "Показати з'єднаннÑ"
-#: ../if_cscope.c:101
#, c-format
msgid "E560: Usage: cs[cope] %s"
msgstr "E560: ВикориÑтаннÑ: cs[cope] %s"
-#: ../if_cscope.c:225
msgid "This cscope command does not support splitting the window.\n"
msgstr "Ð¦Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° cscope не вміє ділити вікно.\n"
-#: ../if_cscope.c:266
msgid "E562: Usage: cstag <ident>"
msgstr "E562: ВикориÑтаннÑ: cstag <ідентиф-ор>"
-#: ../if_cscope.c:313
msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: теґ не знайдено"
+msgstr "E257: cstag: мітку не знайдено"
-# msgstr "E257: "
-#: ../if_cscope.c:461
#, c-format
msgid "E563: stat(%s) error: %d"
msgstr "E563: stat(%s) помилка: %d"
-#: ../if_cscope.c:551
#, c-format
msgid "E564: %s is not a directory or a valid cscope database"
msgstr "E564: %s не є ні каталогом, ні базою даних cscope"
-#: ../if_cscope.c:566
#, c-format
msgid "Added cscope database %s"
msgstr "Додано базу даних cscope %s"
-#: ../if_cscope.c:616
#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ñ– з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ cscope %<PRId64>"
+msgid "E262: error reading cscope connection %<PRIu64>"
+msgstr "E262: помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ñ– з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ cscope %<PRIu64>"
-#: ../if_cscope.c:711
msgid "E561: unknown cscope search type"
msgstr "E561: Ðевідомий тип пошуку cscope"
-#: ../if_cscope.c:752 ../if_cscope.c:789
msgid "E566: Could not create cscope pipes"
msgstr "E566: Ðе вдалоÑÑ Ñтворити канали до cscope"
-#: ../if_cscope.c:767
msgid "E622: Could not fork for cscope"
msgstr "E622: Ðе вдалоÑÑ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ð¸Ñ‚Ð¸ Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð´Ð»Ñ cscope"
-#: ../if_cscope.c:849
msgid "cs_create_connection setpgid failed"
msgstr "cs_create_connection: помилка setpgid"
-#: ../if_cscope.c:853 ../if_cscope.c:889
msgid "cs_create_connection exec failed"
msgstr "cs_create_connection: помилка під Ñ‡Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ"
-#: ../if_cscope.c:863 ../if_cscope.c:902
msgid "cs_create_connection: fdopen for to_fp failed"
msgstr "cs_create_connection: fdopen Ð´Ð»Ñ to_fp не вдавÑÑ"
-#: ../if_cscope.c:865 ../if_cscope.c:906
msgid "cs_create_connection: fdopen for fr_fp failed"
msgstr "cs_create_connection: fdopen Ð´Ð»Ñ fr_fp не вдавÑÑ"
-#: ../if_cscope.c:890
msgid "E623: Could not spawn cscope process"
msgstr "E623: Ðе вдалоÑÑ Ñтворити Ð¿Ñ€Ð¾Ñ†ÐµÑ cscope"
-#: ../if_cscope.c:932
msgid "E567: no cscope connections"
msgstr "E567: жодного з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ–Ð· cscope"
-#: ../if_cscope.c:1009
#, c-format
msgid "E469: invalid cscopequickfix flag %c for %c"
msgstr "E469: Ðекоректний прапорець cscopequickfix %c Ð´Ð»Ñ %c"
-# msgstr "E258: "
-#: ../if_cscope.c:1058
#, c-format
msgid "E259: no matches found for cscope query %s of %s"
msgstr "E259: Ð”Ð»Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ cscope %s з %s нічого не знайдено"
-# msgstr "E259: "
-#: ../if_cscope.c:1142
msgid "cscope commands:\n"
msgstr "Команди cscope:\n"
-#: ../if_cscope.c:1150
#, c-format
msgid "%-5s: %s%*s (Usage: %s)"
msgstr "%-5s: %s%*s (ВикориÑтаннÑ: %s)"
-#: ../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"
@@ -3301,6 +2961,8 @@ msgid ""
" t: Find this text string\n"
msgstr ""
"\n"
+" a: Знайти приÑÐ²Ð¾Ñ”Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñимволу\n"
+" a: Знайти приÑÐ²Ð¾Ñ”Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñимволу\n"
" c: Знайти функції, що викликають цю функцію\n"
" d: Знайти функції, що викликаютьÑÑ Ñ†Ñ–Ñ”ÑŽ функцією\n"
" e: Знайти цей шаблон egrep\n"
@@ -3310,32 +2972,24 @@ msgstr ""
" s: Знайти цей Ñимвол C\n"
" t: Знайти цей текÑÑ‚\n"
-#: ../if_cscope.c:1226
msgid "E568: duplicate cscope database not added"
msgstr "E568: Повторна база даних cscope не додана"
-# msgstr "E260: "
-#: ../if_cscope.c:1335
#, c-format
msgid "E261: cscope connection %s not found"
msgstr "E261: З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· cscope %s не знайдено"
-#: ../if_cscope.c:1364
#, c-format
msgid "cscope connection %s closed"
msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· cscope %s закінчено"
-#. should not reach here
-#: ../if_cscope.c:1486
msgid "E570: fatal error in cs_manage_matches"
msgstr "E570: Фатальна помилка в cs_manage_matches"
-#: ../if_cscope.c:1693
#, c-format
msgid "Cscope tag: %s"
-msgstr "Теґ cscope: %s"
+msgstr "Мітка cscope: %s"
-#: ../if_cscope.c:1711
msgid ""
"\n"
" # line"
@@ -3343,330 +2997,285 @@ msgstr ""
"\n"
" # Ñ€Ñдок"
-#: ../if_cscope.c:1713
msgid "filename / context / line\n"
msgstr "файл / контекÑÑ‚ / Ñ€Ñдок\n"
-#: ../if_cscope.c:1809
#, c-format
msgid "E609: Cscope error: %s"
msgstr "E609: Помилка cscope: %s"
-#: ../if_cscope.c:2053
msgid "All cscope databases reset"
msgstr "УÑÑ– бази даних cscope перезавантажено"
-#: ../if_cscope.c:2123
msgid "no cscope connections\n"
msgstr "Жодного з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· cscope\n"
-#: ../if_cscope.c:2126
msgid " # pid database name prepend path\n"
msgstr " # pid назва бази даних шлÑÑ…\n"
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "Ðевідомий аргумент опції"
+#, c-format
+msgid "E1502: Lua failed to grow stack to %i"
+msgstr "E1502: Lua не вдалоÑÑ Ð·Ð±Ñ–Ð»ÑŒÑˆÐ¸Ñ‚Ð¸ Ñтек до %i"
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "Забагато аргументів"
+msgid ""
+"E5100: Cannot convert given lua table: table should either have a sequence "
+"of positive integer keys or contain only string keys"
+msgstr ""
+"E5100: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ таблицю lua: Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ð° мати "
+"поÑлідовніÑть додатних чиÑел Ñк ключі або текÑтові ключі"
+
+msgid "E5101: Cannot convert given lua type"
+msgstr "E5101: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ тип lua"
+
+#, c-format
+msgid "E5102: Lua failed to grow stack to %i"
+msgstr "E5102: Lua не вдалоÑÑ Ð·Ð±Ñ–Ð»ÑŒÑˆÐ¸Ñ‚Ð¸ Ñтек до %i"
+
+#, c-format
+msgid "E5106: Error while creating vim module: %.*s"
+msgstr "E5106: Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ vim: %.*s"
+
+msgid "E970: Failed to initialize lua interpreter"
+msgstr "E970: Ðе вдалоÑÑ Ñ–Ð½Ñ–Ñ†Ñ–Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ інтерпретатор lua"
+
+#, c-format
+msgid "E5117: Error while updating package paths: %.*s"
+msgstr "E5117: Помилка Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑˆÐ»Ñхів пакунку: %.*s"
+
+#, c-format
+msgid "E5104: Error while creating lua chunk: %.*s"
+msgstr "E5104: Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÑˆÐ¼Ð°Ñ‚ÐºÑƒ lua: %.*s"
+
+#, c-format
+msgid "E5105: Error while calling lua chunk: %.*s"
+msgstr "E5105: Помилка виклику шматку lua: %.*s"
+
+#, c-format
+msgid "E5114: Error while converting print argument #%i: %.*s"
+msgstr "E5114: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ аргумент #%i друку: %.*s"
+
+#, c-format
+msgid "E5115: Error while loading debug string: %.*s"
+msgstr "E5115: Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ: %.*s"
+
+#, c-format
+msgid "E5116: Error while calling debug string: %.*s"
+msgstr "E5116: Помилка виклику налагодженнÑ: %.*s"
+
+#, c-format
+msgid "E5107: Error while creating lua chunk for luaeval(): %.*s"
+msgstr "E5107: Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÑˆÐ¼Ð°Ñ‚ÐºÑƒ lua Ð´Ð»Ñ luaeval(): %.*s"
+
+#, c-format
+msgid "E5108: Error while calling lua chunk for luaeval(): %.*s"
+msgstr "E5108: Помилка виклику шматку lua Ð´Ð»Ñ luaeval(): %.*s"
+
+msgid "cannot save undo information"
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати інформацію поверненнÑ"
+
+#, c-format
+msgid "E5109: Error while creating lua chunk: %.*s"
+msgstr "E5109: Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÑˆÐ¼Ð°Ñ‚ÐºÑƒ lua: %.*s"
+
+#, c-format
+msgid "E5110: Error while creating lua function: %.*s"
+msgstr "E5110: Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ— lua: %.*s"
+
+#, c-format
+msgid "E5111: Error while calling lua function: %.*s"
+msgstr "E5111: Помилка виклику функції lua: %.*s"
+
+#, c-format
+msgid "E5112: Error while creating lua chunk: %.*s"
+msgstr "E5112: Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÑˆÐ¼Ð°Ñ‚ÐºÑƒ lua: %.*s"
+
+#, c-format
+msgid "E5113: Error while calling lua chunk: %.*s"
+msgstr "E5113: Помилка виклику шматку lua: %.*s"
-#: ../main.c:148
msgid "Argument missing after"
msgstr "Пропущено аргумент піÑлÑ"
-#: ../main.c:150
msgid "Garbage after option argument"
msgstr "Ð¡Ð¼Ñ–Ñ‚Ñ‚Ñ Ð¿Ñ–ÑÐ»Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñƒ опції"
-#: ../main.c:152
+msgid "Unknown option argument"
+msgstr "Ðевідомий аргумент опції"
+
+msgid "Too many edit arguments"
+msgstr "Забагато аргументів"
+
msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
msgstr "Забагато аргументів у «+команда», «-c команда» або «--cmd команда»"
-# msgstr "E14: "
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "Ðеправильний аргумент у"
-
-#: ../main.c:294
#, c-format
-msgid "%d files to edit\n"
-msgstr "%d файли(ів)\n"
+msgid "E5421: Failed to open stdin: %s"
+msgstr "E5421: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ stdin: %s"
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "Спроба повторно відкрити Ñкрипт: \""
+#, 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 "Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸: \""
+#, c-format
+msgid "Cannot open for reading: \"%s\": %s\n"
+msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ: \"%s\": %s\n"
-#: ../main.c:1393
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"
-
-#. just in case..
-#: ../main.c:1891
msgid "pre-vimrc command line"
msgstr "команди перед vimrc"
-#: ../main.c:1964
#, c-format
msgid "E282: Cannot read from \"%s\""
msgstr "E282: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ з «%s»"
-# msgstr "E282: "
-#: ../main.c:2149
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 "[файл ..] редагувати вказані файли"
+msgid "Usage:\n"
+msgstr "Вжиток:\n"
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- читати текÑÑ‚ з stdin"
+msgid " nvim [options] [file ...] Edit file(s)\n"
+msgstr " nvim [опції] [файл ...] Редагувати файли\n"
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t помітка перейти до теґу"
+msgid " nvim [options] -t <tag> Edit file where tag is defined\n"
+msgstr " nvim [опції] -t <мітка> Редагувати файл, де визначено мітку\n"
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [файл] перейти до першої помилки"
+msgid " nvim [options] -q [errorfile] Edit file with first error\n"
+msgstr " nvim [опції] -q [ф.помилки] Редагувати файл з першою помилкою\n"
-#: ../main.c:2187
msgid ""
"\n"
-"\n"
-"usage:"
+"Options:\n"
msgstr ""
"\n"
-"\n"
-"Вжиток:"
+"Опції:\n"
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [аргументи] "
+msgid " -- Only file names after this\n"
+msgstr " -- Лише назви файлів піÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾\n"
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" або:"
+msgid " + Start at end of file\n"
+msgstr " + Розпочати в кінці файлу\n"
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
+msgid " --cmd <cmd> Execute <cmd> before any config\n"
msgstr ""
-"\n"
-"\n"
-"Ðргументи:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tЛише назви файлів піÑÐ»Ñ Ñ†ÑŒÐ¾Ð³Ð¾"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\tÐе розкривати шаблони"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tРежим Vi (ніби «vi»)"
+" --cmd <команда> Виконати <команду> перед будь-Ñкою конфігурацією\n"
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tРежим Ex (ніби «ex»)"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr "-E\t\t\tПокращений режим Ex"
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\tМовчазний (пакетний) режим (лише Ð´Ð»Ñ Â«ex»)"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tРежим порівнÑÐ½Ð½Ñ (ніби «vimdiff»)"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tПроÑтий режим (ніби «evim», без режимів)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tРежим переглÑду (ніби «view»)"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tОбмежений режим (ніби «rvim»)"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\tЗміни (Ð·Ð°Ð¿Ð¸Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²) не дозволено"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tЗміни в текÑті файлів не дозволено"
+msgid " +<cmd>, -c <cmd> Execute <cmd> after config and first file\n"
+msgstr ""
+" +<cmd>, -c <команда> Виконати <команду> піÑÐ»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ файлу\n"
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\tДвійковий режим"
+msgid " -b Binary mode\n"
+msgstr " -b Двійковий режим\n"
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tРежим lisp"
+msgid " -d Diff mode\n"
+msgstr " -d Режим порівнÑннÑ\n"
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\tСуміÑний з Vi режим: 'compatible'"
+msgid " -e, -E Ex mode\n"
+msgstr " -e, -E Режим Ex\n"
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\tÐе зовÑім ÑуміÑний з Vi режим: 'nocompatible'"
+msgid " -es, -Es Silent (batch) mode\n"
+msgstr " -es, -Es Мовчазний (пакетний) режим\n"
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr "-V[N][файл]\t\tБільше повідомлень [рівень N] [файл журн. повідомлень]"
+msgid " -h, --help Print this help message\n"
+msgstr " -h, --help Ðадрукувати це повідомленнÑ\n"
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tРежим налагодженнÑ"
+msgid " -i <shada> Use this shada file\n"
+msgstr " -i <shada> Вжити цей файл shada\n"
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\tÐе викориÑтовувати файл обміну, тримати уÑе в пам'Ñті"
+msgid " -m Modifications (writing files) not allowed\n"
+msgstr " -m Зміни (Ð·Ð°Ð¿Ð¸Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²) не дозволено\n"
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tПоказати файли обміну і вийти"
+msgid " -M Modifications in text not allowed\n"
+msgstr " -M Зміни в текÑті файлів не дозволено\n"
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (назва файлу)\tВідновити аварійно закінчений ÑеанÑ"
+msgid " -n No swap file, use memory only\n"
+msgstr ""
+" -n Ðе викориÑтовувати файл обміну, тримати уÑе в "
+"пам'Ñті\n"
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tТе Ñаме, що й -r"
+msgid " -o[N] Open N windows (default: one per file)\n"
+msgstr " -o[N] Відкрити N вікон (Ñтандартно: одне на файл)\n"
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tЗапуÑтити в режимі арабÑької мови"
+msgid ""
+" -O[N] Open N vertical windows (default: one per file)\n"
+msgstr ""
+" -o[N] Відкрити N вертикальних вікон (Ñтандартно: одне на "
+"файл)\n"
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tЗапуÑтити в режимі івриту"
+msgid " -p[N] Open N tab pages (default: one per file)\n"
+msgstr ""
+" -p[N] Відкрити N вкладок (Ñтандартно: одна на файл)\n"
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tЗапуÑтити в режимі перÑької мови"
+msgid " -r, -L List swap files\n"
+msgstr " -r, -L Показати файли обміну\n"
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <термінал>\tÐ’Ñтановити тип терміналу у <термінал>"
+msgid " -r <file> Recover edit state for this file\n"
+msgstr " -r <файл> Відновити Ñтан Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файлу\n"
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tВикориÑтати поданий файл заміÑть .vimrc"
+msgid " -R Read-only mode\n"
+msgstr " -R Режим тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ\n"
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\tÐе вантажити Ñкрипти доповненнÑ"
+msgid " -S <session> Source <session> after loading the first file\n"
+msgstr ""
+" -S <ÑеанÑ> Виконати <ÑеанÑ> піÑÐ»Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ завантаженого файлу\n"
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-p[N]\t\tВідкрити N вкладок (або по одній Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ файлу)"
+msgid " -s <scriptin> Read Normal mode commands from <scriptin>\n"
+msgstr ""
+" -s <Ñкрипт> Зчитати команди нормального режиму з файлу <Ñкрипт>\n"
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\tВідкрити N вікон (або по одному Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ файлу)"
+msgid " -u <config> Use this config file\n"
+msgstr " -u <config> Вжити цей файл конфігурації\n"
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tÐіби -o, але поділити вікна вертикально"
+msgid " -v, --version Print version information\n"
+msgstr " -v, --version Ðадрукувати інформацію про верÑÑ–ÑŽ програми\n"
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tРозпочати в кінці файлу"
+msgid " -V[N][file] Verbose [level][file]\n"
+msgstr " -V[N][файл] Більше повідомлень [рівень][файл]\n"
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<Ñ€Ñдок>\t\tРозпочати у вказаному <Ñ€Ñдку>"
+msgid " -Z Restricted mode\n"
+msgstr " -Z Обмежений режим\n"
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <команда>\tВиконати <команду> перед завантаженнÑм vimrc"
+msgid " --api-info Write msgpack-encoded API metadata to stdout\n"
+msgstr ""
+" --api-info ЗапиÑати метадані API, Ñеріалізовані у msgpack, у "
+"stdout\n"
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <команда>\t\tВиконати <команду> піÑÐ»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ файлу"
+msgid " --embed Use stdin/stdout as a msgpack-rpc channel\n"
+msgstr ""
+" --embed ВикориÑтати stdin/stdout, Ñк канал msgpack-rpc\n"
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <ÑеанÑ>\t\tВиконати поданий файл піÑÐ»Ñ Ð¿ÐµÑ€ÑˆÐ¾Ð³Ð¾ завантаженого файлу"
+msgid " --headless Don't start a user interface\n"
+msgstr " --headless Ðе запуÑкати Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÐ¾Ñ€Ð¸Ñтувача\n"
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <Ñкрипт>\t\tЗчитати команди нормального режиму з файлу <Ñкрипт>"
+msgid " --listen <address> Serve RPC API from this address\n"
+msgstr " --listen <адреÑа> ОбÑлуговувати RPC API за цією адреÑою\n"
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <Ñкрипт>\t\tДопиÑати уÑÑ– набрані команди до файлу <Ñкрипт>"
+msgid " --noplugin Don't load plugins\n"
+msgstr " --noplugin Ðе завантажувати доповненнÑ\n"
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-w <Ñкрипт>\t\tЗапиÑати уÑÑ– набрані команди у файл <Ñкрипт>"
+msgid " --startuptime <file> Write startup timing messages to <file>\n"
+msgstr " --startuptime <файл> ЗапиÑати профіль запуÑку до <файлу>\n"
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
+msgid ""
+"\n"
+"See \":help startup-options\" for all options.\n"
msgstr ""
-"--startuptime <файл>\tЗапиÑати запуÑкні Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· чаÑовими відмітками "
-"до <файлу>"
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tВикориÑтати <viminfo> заміÑть .viminfo"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h чи --help\tÐадрукувати це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ– вийти"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\tÐадрукувати інформацію про верÑÑ–ÑŽ програми Ñ– вийти"
+"\n"
+"Див \":help startup-options\" щоб побачити вÑÑ– опції.\n"
-#: ../mark.c:676
msgid "No marks set"
msgstr "Ðе вÑтановлено жодної помітки"
-#: ../mark.c:678
#, c-format
msgid "E283: No marks matching \"%s\""
msgstr "E283: Помітку «%s» не знайдено"
-# msgstr "E283: "
-#. Highlight title
-#: ../mark.c:687
msgid ""
"\n"
"mark line col file/text"
@@ -3674,8 +3283,6 @@ msgstr ""
"\n"
"пом. Ñ€Ñд. кол. файл/текÑÑ‚"
-#. Highlight title
-#: ../mark.c:789
msgid ""
"\n"
" jump line col file/text"
@@ -3683,9 +3290,6 @@ msgstr ""
"\n"
" точка Ñ€Ñд. Ñтовп. файл/текÑÑ‚"
-# msgstr "E283: "
-#. Highlight title
-#: ../mark.c:831
msgid ""
"\n"
"change line col text"
@@ -3693,117 +3297,60 @@ msgstr ""
"\n"
"змінити Ñ€Ñд. Ñтовп. текÑÑ‚"
-# TODO
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Помітки:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# СпиÑок переходів (від найновіших):\n"
-
-# TODO
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Попередні помітки в файлах (від найновіших):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "Пропущено '>'"
-
-# msgstr "E292: "
-#: ../memfile.c:426
msgid "E293: block was not locked"
msgstr "E293: Блок не було зафікÑовано"
-# msgstr "E293: "
-#: ../memfile.c:799
msgid "E294: Seek error in swap file read"
msgstr "E294: Помилка зміни позиції у файлі обміну"
-#: ../memfile.c:803
msgid "E295: Read error in swap file"
msgstr "E295: Помилка Ð·Ñ‡Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ обміну"
-#: ../memfile.c:849
msgid "E296: Seek error in swap file write"
msgstr "E296: Помилка зміни позиції під Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñу у файл обміну"
-#: ../memfile.c:865
msgid "E297: Write error in swap file"
msgstr "E297: Помилка запиÑу файлу обміну"
-#: ../memfile.c:1036
msgid "E300: Swap file already exists (symlink attack?)"
msgstr "E300: Файл обміну вже Ñ–Ñнує (атака Ñимвольним поÑиланнÑм?)"
-#: ../memline.c:318
msgid "E298: Didn't get block nr 0?"
msgstr "E298: Ðемає блоку 0?"
-#: ../memline.c:361
msgid "E298: Didn't get block nr 1?"
msgstr "E298: Ðемає блоку 1?"
-# msgstr "E298: "
-#: ../memline.c:377
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
msgid "E301: Oops, lost the swap file!!!"
msgstr "E301: Ой, втрачено файл обміну!!!"
-# msgstr "E301: "
-#: ../memline.c:477
msgid "E302: Could not rename swap file"
msgstr "E302: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ файлу обміну"
-# msgstr "E302: "
-#: ../memline.c:554
#, c-format
msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
msgstr "E303: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ файл обміну Ð´Ð»Ñ Â«%s», Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ðµ"
-#: ../memline.c:666
msgid "E304: ml_upd_block0(): Didn't get block 0??"
msgstr "E304: ml_upd_block0(): Ðемає блоку 0??"
-#. no swap files found
-#: ../memline.c:830
#, c-format
msgid "E305: No swap file found for %s"
msgstr "E305: Ðе знайдено файлу обміну Ð´Ð»Ñ %s"
-# msgstr "E305: "
-#: ../memline.c:839
msgid "Enter number of swap file to use (0 to quit): "
msgstr "Введіть номер файлу обміну, котрий викориÑтати, (0 Ð´Ð»Ñ Ð²Ð¸Ñ…Ð¾Ð´Ñƒ):"
-#: ../memline.c:879
#, c-format
msgid "E306: Cannot open %s"
msgstr "E306: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ %s"
-#: ../memline.c:897
msgid "Unable to read block 0 from "
msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ блок 0 з "
-#: ../memline.c:900
msgid ""
"\n"
"Maybe no changes were made or Vim did not update the swap file."
@@ -3811,28 +3358,22 @@ msgstr ""
"\n"
"Ðапевно, змін не було, або Vim не поновив файл обміну."
-#: ../memline.c:909
msgid " cannot be used with this version of Vim.\n"
msgstr " не можна викориÑтати з цією верÑією Vim.\n"
-#: ../memline.c:911
msgid "Use Vim version 3.0.\n"
msgstr "Знайдіть Vim 3.0\n"
-#: ../memline.c:916
#, c-format
msgid "E307: %s does not look like a Vim swap file"
msgstr "E307: %s не Ñхоже на файл обміну Vim"
-#: ../memline.c:922
msgid " cannot be used on this computer.\n"
msgstr " не можна викориÑтати на цьому комп'ютері.\n"
-#: ../memline.c:924
msgid "The file was created on "
msgstr "Файл було Ñтворено на "
-#: ../memline.c:928
msgid ""
",\n"
"or the file has been damaged."
@@ -3840,89 +3381,67 @@ msgstr ""
",\n"
"або файл було пошкоджено."
-#: ../memline.c:945
msgid " has been damaged (page size is smaller than minimum value).\n"
msgstr " пошкоджений (розмір Ñторінки менший мінімального значеннÑ).\n"
-#: ../memline.c:974
#, c-format
msgid "Using swap file \"%s\""
msgstr "ВикориÑтовуєтьÑÑ Ñ„Ð°Ð¹Ð» обміну «%s»"
-#: ../memline.c:980
#, c-format
msgid "Original file \"%s\""
msgstr "Початковий файл «%s»"
-#: ../memline.c:995
msgid "E308: Warning: Original file may have been changed"
msgstr "E308: ЗаÑтереженнÑ: Можливо, початковий файл було змінено"
-# msgstr "E308: "
-#: ../memline.c:1061
#, c-format
msgid "E309: Unable to read block 1 from %s"
msgstr "E309: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ блок 1 з %s"
-# msgstr "E309: "
-#: ../memline.c:1065
msgid "???MANY LINES MISSING"
msgstr "??? БРÐКУЄ БÐГÐТЬОХ РЯДКІВ"
-#: ../memline.c:1076
msgid "???LINE COUNT WRONG"
msgstr "??? ÐЕПРÐВИЛЬÐРКІЛЬКІСТЬ РЯДКІВ"
-#: ../memline.c:1082
msgid "???EMPTY BLOCK"
msgstr "??? ПОРОЖÐІЙ БЛОК"
-#: ../memline.c:1103
msgid "???LINES MISSING"
msgstr "??? ПРОПУЩЕÐІ РЯДКИ"
-#: ../memline.c:1128
#, c-format
msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
msgstr "E310: Ідентифікатор блоку 1 неправильний (%s не є файлом обміну?)"
-# msgstr "E310: "
-#: ../memline.c:1133
msgid "???BLOCK MISSING"
msgstr "??? ПРОПУЩЕÐО БЛОК"
-#: ../memline.c:1147
msgid "??? from here until ???END lines may be messed up"
msgstr "??? звідÑи Ñ– до `??? КІÐЕЦЬ' Ñ€Ñдки, можливо, Ñплутані"
-#: ../memline.c:1164
msgid "??? from here until ???END lines may have been inserted/deleted"
msgstr "??? звідÑи Ñ– до `??? КІÐЕЦЬ' Ñ€Ñдки, можливо, були додані/знищені"
-#: ../memline.c:1181
msgid "???END"
msgstr "??? КІÐЕЦЬ"
-#: ../memline.c:1238
msgid "E311: Recovery Interrupted"
msgstr "E311: Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÑ€Ð²Ð°Ð½Ð¾"
-#: ../memline.c:1243
msgid ""
"E312: Errors detected while recovering; look for lines starting with ???"
msgstr ""
"E312: Під Ñ‡Ð°Ñ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ð¹Ð´ÐµÐ½Ð¾ помилки. ПереглÑньте Ñ€Ñдки, що "
"починаютьÑÑ Ð· ???"
-#: ../memline.c:1245
msgid "See \":help E312\" for more information."
msgstr "Див. «:help E312» Ð´Ð»Ñ ÑƒÑ‚Ð¾Ñ‡Ð½ÐµÐ½Ð½Ñ."
-#: ../memline.c:1249
msgid "Recovery completed. You should check if everything is OK."
msgstr "Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð¾, перевірте чи вÑе гаразд."
-#: ../memline.c:1251
msgid ""
"\n"
"(You might want to write out this file under another name\n"
@@ -3930,15 +3449,12 @@ msgstr ""
"\n"
"(Можливо, потрібно запиÑати цей файл під іншою назвою\n"
-#: ../memline.c:1252
msgid "and run diff with the original file to check for changes)"
msgstr "Ñ– запуÑтити diff з оригіналом щоб перевірити зміни)"
-#: ../memline.c:1254
msgid "Recovery completed. Buffer contents equals file contents."
msgstr "Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð¾. ВміÑÑ‚ буфера Ñпівпадає зі вміÑтом файлу."
-#: ../memline.c:1255
msgid ""
"\n"
"You may want to delete the .swp file now.\n"
@@ -3948,52 +3464,42 @@ msgstr ""
"Можливо, тепер ви хочете знищити файл обміну .swp.\n"
"\n"
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
msgid "Swap files found:"
msgstr "Знайдено файли обміну:"
-#: ../memline.c:1446
msgid " In current directory:\n"
msgstr " В поточному каталозі:\n"
-#: ../memline.c:1448
msgid " Using specified name:\n"
msgstr " ВикориÑтовуючи вказану назву:\n"
-#: ../memline.c:1450
msgid " In directory "
msgstr " У каталозі "
-#: ../memline.c:1465
msgid " -- none --\n"
msgstr " -- жодного --\n"
-#: ../memline.c:1527
msgid " owned by: "
msgstr " влаÑник: "
-#: ../memline.c:1529
msgid " dated: "
msgstr " дата: "
-#: ../memline.c:1532 ../memline.c:3231
msgid " dated: "
msgstr " дата: "
-#: ../memline.c:1548
msgid " [from Vim version 3.0]"
msgstr " [від Vim 3.0]"
-#: ../memline.c:1550
msgid " [does not look like a Vim swap file]"
msgstr " [не Ñхоже на файл обміну]"
-#: ../memline.c:1552
+msgid " [garbled strings (not nul terminated)]"
+msgstr " [пошкоджений текÑÑ‚ (не закінчуєтьÑÑ nul)]"
+
msgid " file name: "
msgstr " назва файлу: "
-#: ../memline.c:1558
msgid ""
"\n"
" modified: "
@@ -4001,15 +3507,12 @@ msgstr ""
"\n"
" змінено: "
-#: ../memline.c:1559
msgid "YES"
msgstr "ТÐК"
-#: ../memline.c:1559
msgid "no"
msgstr "ні"
-#: ../memline.c:1562
msgid ""
"\n"
" user name: "
@@ -4017,11 +3520,9 @@ msgstr ""
"\n"
" кориÑтувач: "
-#: ../memline.c:1568
msgid " host name: "
msgstr " назва вузла: "
-#: ../memline.c:1570
msgid ""
"\n"
" host name: "
@@ -4029,7 +3530,6 @@ msgstr ""
"\n"
" назва вузла: "
-#: ../memline.c:1575
msgid ""
"\n"
" process ID: "
@@ -4037,11 +3537,9 @@ msgstr ""
"\n"
" ID процеÑу: "
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (виконуєтьÑÑ)"
+msgid " (STILL RUNNING)"
+msgstr " (ЩЕ ВИКОÐУЄТЬСЯ)"
-#: ../memline.c:1586
msgid ""
"\n"
" [not usable on this computer]"
@@ -4049,106 +3547,75 @@ msgstr ""
"\n"
" [непридатний на цьому комп'ютері]"
-#: ../memline.c:1590
msgid " [cannot be read]"
msgstr " [не можна прочитати]"
-#: ../memline.c:1593
msgid " [cannot be opened]"
msgstr " [не можна відкрити]"
-#: ../memline.c:1698
msgid "E313: Cannot preserve, there is no swap file"
msgstr "E313: Ðе вдалоÑÑ Ð·Ð°Ð³Ð¾Ñ‚Ð¾Ð²Ð¸Ñ‚Ð¸, немає файлу обміну"
-# msgstr "E313: "
-#: ../memline.c:1747
msgid "File preserved"
msgstr "Файл збережено"
-#: ../memline.c:1749
msgid "E314: Preserve failed"
msgstr "E314: Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð½Ðµ вдалоÑÑ"
-# msgstr "E314: "
-#: ../memline.c:1819
#, c-format
msgid "E315: ml_get: invalid lnum: %<PRId64>"
msgstr "E315: ml_get: неправильний lnum: %<PRId64>"
-# msgstr "E315: "
-#: ../memline.c:1851
#, c-format
msgid "E316: ml_get: cannot find line %<PRId64>"
msgstr "E316: ml_get: не знайшов Ñ€Ñдок %<PRId64>"
-# msgstr "E316: "
-#: ../memline.c:2236
msgid "E317: pointer block id wrong 3"
msgstr "E317: Вказівник блоку помилковий 3"
-# msgstr "E317: "
-#: ../memline.c:2311
msgid "stack_idx should be 0"
msgstr "stack_idx має бути рівним 0"
-#: ../memline.c:2369
msgid "E318: Updated too many blocks?"
msgstr "E318: Поновлено забагато блоків?"
-#: ../memline.c:2511
msgid "E317: pointer block id wrong 4"
msgstr "E317: Вказівник блоку помилковий 4"
-#: ../memline.c:2536
msgid "deleted block 1?"
msgstr "блок 1 знищено?"
-#: ../memline.c:2707
#, c-format
msgid "E320: Cannot find line %<PRId64>"
msgstr "E320: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ñ€Ñдок %<PRId64>"
-#: ../memline.c:2916
msgid "E317: pointer block id wrong"
msgstr "E317: Вказівник блоку помилковий"
-# msgstr "E317: "
-#: ../memline.c:2930
msgid "pe_line_count is zero"
msgstr "pe_line_count дорівнює 0"
-#: ../memline.c:2955
#, c-format
msgid "E322: line number out of range: %<PRId64> past the end"
msgstr "E322: Ðомер Ñ€Ñдка вийшов за межі: %<PRId64> за кінцем"
-# msgstr "E322: "
-#: ../memline.c:2959
#, c-format
msgid "E323: line count wrong in block %<PRId64>"
msgstr "E323: КількіÑть Ñ€Ñдків у блоці %<PRId64>"
-# msgstr "E323: "
-#: ../memline.c:2999
msgid "Stack size increases"
msgstr "Розмір Ñтеку збільшуєтьÑÑ"
-#: ../memline.c:3038
msgid "E317: pointer block id wrong 2"
msgstr "E317: Вказівник блоку помилковий 2"
-#: ../memline.c:3070
#, c-format
msgid "E773: Symlink loop for \"%s\""
msgstr "E773: Циклічні Ñимвольні поÑÐ¸Ð»Ð°Ð½Ð½Ñ Â«%s»"
-# msgstr "E317: "
-#: ../memline.c:3221
msgid "E325: ATTENTION"
msgstr "E325: УВÐГÐ"
-#: ../memline.c:3222
msgid ""
"\n"
"Found a swap file by the name \""
@@ -4156,39 +3623,32 @@ msgstr ""
"\n"
"Знайдено файл обміну з назвою \""
-#: ../memline.c:3226
msgid "While opening file \""
msgstr "При відкритті файлу \""
-#: ../memline.c:3239
+msgid " CANNOT BE FOUND"
+msgstr " ÐЕ ЗÐÐЙДЕÐО"
+
msgid " NEWER than swap file!\n"
msgstr " ÐОВІШИЙ за файл обміну!\n"
-#: ../memline.c:3244
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"
+" Ñамого файлу піÑÐ»Ñ Ð·Ð¼Ñ–Ð½. Вийдіть чи продовжуйте обережно.\n"
-#: ../memline.c:3245
-msgid " Quit, or continue with caution.\n"
-msgstr " Вийдіть або продовжуйте обережно.\n"
-
-#: ../memline.c:3246
msgid "(2) An edit session for this file crashed.\n"
msgstr "(2) Ð¡ÐµÐ°Ð½Ñ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файлу зазнав краху.\n"
-#: ../memline.c:3247
msgid " If this is the case, use \":recover\" or \"vim -r "
msgstr " Якщо це Ñправді трапилоÑÑ, Ñпробуйте «:recover» або «vim -r "
-#: ../memline.c:3249
msgid ""
"\"\n"
" to recover the changes (see \":help recovery\").\n"
@@ -4196,36 +3656,25 @@ msgstr ""
"»\n"
" щоб відновити зміни (див. «:help recovery»).\n"
-#: ../memline.c:3250
msgid " If you did this already, delete the swap file \""
msgstr " Якщо ви вже це зробили, знищіть файл обміну «"
-#: ../memline.c:3252
msgid ""
"\"\n"
" to avoid this message.\n"
msgstr ""
"»,\n"
" щоб позбутиÑÑ Ñ†ÑŒÐ¾Ð³Ð¾ повідомленнÑ.\n"
-"\n"
-#: ../memline.c:3450 ../memline.c:3452
msgid "Swap file \""
msgstr "Файл обміну «"
-#: ../memline.c:3451 ../memline.c:3455
msgid "\" already exists!"
msgstr "» вже Ñ–Ñнує!"
-#: ../memline.c:3457
msgid "VIM - ATTENTION"
msgstr "VIM — УВÐГÐ"
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "Файл обміну вже Ñ–Ñнує!"
-
-#: ../memline.c:3464
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4239,7 +3688,6 @@ msgstr ""
"&Q:Вийти\n"
"&A:Перервати"
-#: ../memline.c:3467
msgid ""
"&Open Read-Only\n"
"&Edit anyway\n"
@@ -4255,64 +3703,46 @@ 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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
msgid "E326: Too many swap files found"
msgstr "E326: Знайдено забагато файлів обміну"
-# msgstr "E341: "
-#: ../memory.c:227
+#, c-format
+msgid ""
+"E303: Unable to create directory \"%s\" for swap file, recovery impossible: "
+"%s"
+msgstr ""
+"E303: Ðе вдалоÑÑ Ñтворити каталог «%s» Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñƒ обміну, Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ "
+"неможливе: %s"
+
+msgid "Vim: Data too large to fit into virtual memory space\n"
+msgstr "Vim: Даних забагато щоб влізти у віртуальний адреÑний проÑтір\n"
+
#, c-format
msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
msgstr "E342: Забракло пам'Ñті! (потрібно було %<PRIu64> байтів)"
-# msgstr "E326: "
-#: ../menu.c:62
msgid "E327: Part of menu-item path is not sub-menu"
msgstr "E327: ЧаÑтина шлÑху до елемента меню не Ñ” підменю"
-# msgstr "E327: "
-#: ../menu.c:63
msgid "E328: Menu only exists in another mode"
msgstr "E328: Меню може бути тільки в іншому режимі"
-# msgstr "E328: "
-#: ../menu.c:64
#, c-format
msgid "E329: No menu \"%s\""
msgstr "E329: Ðемає меню «%s»"
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
msgid "E792: Empty menu name"
msgstr "E792: ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° меню"
-# msgstr "E329: "
-#: ../menu.c:340
msgid "E330: Menu path must not lead to a sub-menu"
msgstr "E330: ШлÑÑ… до меню не повинен веÑти до підменю"
-# msgstr "E330: "
-#: ../menu.c:365
msgid "E331: Must not add menu items directly to menu bar"
msgstr "E331: Ðе можна додавати елементи меню проÑто до верхнього меню"
-# msgstr "E331: "
-#: ../menu.c:370
msgid "E332: Separator cannot be part of a menu path"
msgstr "E332: Роздільник не може бути чаÑтиною шлÑху меню"
-# msgstr "E332: "
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
msgid ""
"\n"
"--- Menus ---"
@@ -4320,78 +3750,48 @@ msgstr ""
"\n"
"--- Меню ---"
-#: ../menu.c:1313
msgid "E333: Menu path must lead to a menu item"
msgstr "E333: ШлÑÑ… повинен веÑти до елемента меню"
-# msgstr "E333: "
-#: ../menu.c:1330
#, c-format
msgid "E334: Menu not found: %s"
msgstr "E334: Меню не знайдено: %s"
-# msgstr "E334: "
-#: ../menu.c:1396
#, c-format
msgid "E335: Menu not defined for %s mode"
msgstr "E335: Ð”Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ %s меню не визначено"
-# msgstr "E335: "
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: ШлÑÑ… повинен веÑти до підменю"
-
-# msgstr "E336: "
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: Меню не знайдено — перевірте назву"
-
-# msgstr "E337: "
-#: ../message.c:423
#, c-format
msgid "Error detected while processing %s:"
msgstr "ВиÑвлено помилку під Ñ‡Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ %s:"
-#: ../message.c:445
#, c-format
msgid "line %4ld:"
msgstr "Ñ€Ñдок %4ld:"
-#: ../message.c:617
#, c-format
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Ðеправильна назва регіÑтру: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "УкраїнізаціÑ: Ðнатолій Сахнік <sakhnik@gmail.com>"
-
-#: ../message.c:986
msgid "Interrupt: "
msgstr "Перервано: "
-#: ../message.c:988
msgid "Press ENTER or type command to continue"
msgstr "ÐатиÑніть ENTER або введіть команду Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ"
-#: ../message.c:1843
#, c-format
msgid "%s line %<PRId64>"
msgstr "%s Ñ€Ñдок %<PRId64>"
-#: ../message.c:2392
msgid "-- More --"
msgstr "-- Ще --"
-#: ../message.c:2398
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
msgid "Question"
msgstr "ЗапитаннÑ"
-#: ../message.c:3023
msgid ""
"&Yes\n"
"&No"
@@ -4399,7 +3799,6 @@ msgstr ""
"&Y:Так\n"
"&N:ÐÑ–"
-#: ../message.c:3033
msgid ""
"&Yes\n"
"&No\n"
@@ -4409,7 +3808,6 @@ msgstr ""
"&N:ÐÑ–\n"
"&C:СкаÑувати"
-#: ../message.c:3045
msgid ""
"&Yes\n"
"&No\n"
@@ -4423,178 +3821,124 @@ 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: ОчікуєтьÑÑ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚ Float Ð´Ð»Ñ printf()"
-
-#: ../message.c:3873
-msgid "E767: Too many arguments to printf()"
-msgstr "E767: Забагато аргументів Ð´Ð»Ñ printf()"
-
-# msgstr "E338: "
-#: ../misc1.c:2256
msgid "W10: Warning: Changing a readonly file"
msgstr "W10: ЗаÑтереженнÑ: ЗмінюєтьÑÑ Ñ„Ð°Ð¹Ð» призначений лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ"
-#: ../misc1.c:2537
msgid "Type number and <Enter> or click with mouse (empty cancels): "
msgstr "Ðаберіть чиÑло й <Enter> чи клацніть мишкою (порожнє ÑкаÑовує): "
-#: ../misc1.c:2539
msgid "Type number and <Enter> (empty cancels): "
msgstr "Ðаберіть чиÑло й <Enter> (порожнє ÑкаÑовує): "
-#: ../misc1.c:2585
msgid "1 more line"
msgstr "додано один Ñ€Ñдок"
-#: ../misc1.c:2588
msgid "1 line less"
msgstr "знищено один Ñ€Ñдок"
-#: ../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 "Дзень!"
-# msgstr "E342: "
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "ВикликаєтьÑÑ Ð¾Ð±Ð¾Ð»Ð¾Ð½ÐºÐ° щоб виконати: «%s»"
-
-# msgstr "E348: "
-#: ../normal.c:183
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
msgid "E348: No string under cursor"
msgstr "E348: Ðемає Ñ€Ñдка на курÑорі"
-#: ../normal.c:3937
msgid "E352: Cannot erase folds with current 'foldmethod'"
msgstr "E352: Ðе вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ згортки поточним методом 'foldmethod'"
-#: ../normal.c:5897
msgid "E664: changelist is empty"
msgstr "E664: СпиÑок змін порожній"
-#: ../normal.c:5899
msgid "E662: At start of changelist"
msgstr "E662: Початок ÑпиÑку змін"
-#: ../normal.c:5901
msgid "E663: At end of changelist"
msgstr "E663: Кінець ÑпиÑку змін"
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "Уведіть :quit<Enter> щоб вийти з Vim"
+msgid "Type :qa! and press <Enter> to abandon all changes and exit Nvim"
+msgstr ""
+"Введіть :qa! Ñ– натиÑніÑть <Enter> щоб відкинути вÑÑ– зміни Ñ– вийти Nvim"
-#: ../ops.c:248
#, c-format
msgid "1 line %sed 1 time"
msgstr "Один Ñ€Ñдок %s-но"
-#: ../ops.c:250
#, c-format
msgid "1 line %sed %d times"
msgstr "Один Ñ€Ñдок %s-но %d разів"
-#: ../ops.c:253
#, c-format
msgid "%<PRId64> lines %sed 1 time"
msgstr "%<PRId64> Ñ€Ñдків %s-но"
-#: ../ops.c:256
#, c-format
msgid "%<PRId64> lines %sed %d times"
msgstr "%<PRId64> Ñ€Ñдків %s-но %d разів"
-#: ../ops.c:592
#, c-format
msgid "%<PRId64> lines to indent... "
msgstr "ЗалишилоÑÑ Ð²Ð¸Ñ€Ñ–Ð²Ð½Ñти %<PRId64> Ñ€Ñдків..."
-#: ../ops.c:634
msgid "1 line indented "
msgstr "ВирівнÑно один Ñ€Ñдок"
-#: ../ops.c:636
#, c-format
msgid "%<PRId64> lines indented "
msgstr "ВирівнÑно Ñ€Ñдків: %<PRId64>"
-#: ../ops.c:938
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 "Один Ñ€Ñдок змінено"
-#: ../ops.c:1931
#, c-format
msgid "%<PRId64> lines changed"
msgstr "Змінено Ñ€Ñдків: %<PRId64>"
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "Запам'Ñтав блок з одного Ñ€Ñдка"
+#, c-format
+msgid " into \"%c"
+msgstr " у \"%c"
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "Запам'Ñтав один Ñ€Ñдок"
+#, c-format
+msgid "block of 1 line yanked%s"
+msgstr "Запам'Ñтав блок з одного Ñ€Ñдка%s"
-#: ../ops.c:2525
#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "Запам'Ñтав блок із %<PRId64> Ñ€Ñдків"
+msgid "1 line yanked%s"
+msgstr "Запам'Ñтав один Ñ€Ñдок%s"
-#: ../ops.c:2528
#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "Запам'Ñтав Ñ€Ñдків: %<PRId64>"
+msgid "block of %<PRId64> lines yanked%s"
+msgstr "Запам'Ñтав блок із %<PRId64> Ñ€Ñдків%s"
+
+#, c-format
+msgid "%<PRId64> lines yanked%s"
+msgstr "Запам'Ñтав Ñ€Ñдків: %<PRId64>%s"
-#: ../ops.c:2710
#, c-format
msgid "E353: Nothing in register %s"
msgstr "E353: У регіÑтрі %s нічого немає"
-# msgstr "E353: "
-#. Highlight title
-#: ../ops.c:3185
msgid ""
"\n"
"--- Registers ---"
@@ -4602,29 +3946,16 @@ msgstr ""
"\n"
"--- РегіÑтри ---"
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "Ðеправильна назва регіÑтру"
-
-#: ../ops.c:4533
msgid ""
-"\n"
-"# Registers:\n"
+"E883: search pattern and expression register may not contain two or more "
+"lines"
msgstr ""
-"\n"
-"# РегіÑтри:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: Ðевідомий тип регіÑтру %d"
+"E883: шаблон пошуку Ñ– реєÑтр виразу не можуть міÑтити два чи більше Ñ€Ñдків"
-#: ../ops.c:5089
#, c-format
msgid "%<PRId64> Cols; "
msgstr "довж.: %<PRId64>; "
-#: ../ops.c:5097
#, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
@@ -4633,7 +3964,6 @@ msgstr ""
"Вибрано %s%<PRId64> з %<PRId64> Ñ€Ñдків; %<PRId64> з %<PRId64> Ñлів; "
"%<PRId64> з %<PRId64> байтів"
-#: ../ops.c:5105
#, c-format
msgid ""
"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
@@ -4642,7 +3972,6 @@ msgstr ""
"Вибрано %s%<PRId64> з %<PRId64> Ñ€Ñдків; %<PRId64> з %<PRId64> Ñлів; "
"%<PRId64> of %<PRId64> Ñимволів; %<PRId64> з %<PRId64> байтів"
-#: ../ops.c:5123
#, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
@@ -4651,7 +3980,6 @@ msgstr ""
"Колонка %s з %s; Ñ€Ñдок %<PRId64> з %<PRId64>; Ñлово %<PRId64> з %<PRId64>; "
"байт %<PRId64> з %<PRId64>"
-#: ../ops.c:5133
#, c-format
msgid ""
"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
@@ -4660,158 +3988,101 @@ msgstr ""
"Колонка %s з %s; Ñ€Ñдок %<PRId64> з %<PRId64>; Ñлово %<PRId64> з %<PRId64>; "
"Ñимвол %<PRId64> of %<PRId64>; байт %<PRId64> з %<PRId64>"
-#: ../ops.c:5146
#, c-format
msgid "(+%<PRId64> for BOM)"
msgstr "(+%<PRId64> Ð´Ð»Ñ BOM)"
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=Стор. %N"
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "ДÑкуємо за вибір Vim"
-
-#. found a mismatch: skip
-#: ../option.c:2698
msgid "E518: Unknown option"
msgstr "E518: Ðевідома опціÑ"
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: ÐžÐ¿Ñ†Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ"
-
-#: ../option.c:2740
msgid "E520: Not allowed in a modeline"
msgstr "E520: Ðе дозволено у modeline"
-#: ../option.c:2815
msgid "E846: Key code not set"
msgstr "E846: Код ключа не вÑтановлено"
-#: ../option.c:2924
msgid "E521: Number required after ="
msgstr "E521: ПіÑÐ»Ñ = потрібно вказати чиÑло"
-#: ../option.c:3226 ../option.c:3864
-msgid "E522: Not found in termcap"
-msgstr "E522: Ðе знайдено Ñеред можливоÑтей терміналів"
-
-#: ../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'"
+#, c-format
+msgid "For option %s"
+msgstr "Ð”Ð»Ñ Ð¾Ð¿Ñ†Ñ–Ñ— %s"
-#: ../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
msgid "E590: A preview window already exists"
msgstr "E590: Вікно переглÑду вже Ñ–Ñнує"
-#: ../option.c:5311
msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
msgstr ""
"W17: Ð”Ð»Ñ Ð°Ñ€Ð°Ð±Ñької мови потрібне UTF-8, виконайте ':set encoding=utf-8'"
-#: ../option.c:5623
#, c-format
msgid "E593: Need at least %d lines"
msgstr "E593: Потрібно щонайменше %d Ñ€Ñдків"
-#: ../option.c:5631
#, c-format
msgid "E594: Need at least %d columns"
msgstr "E594: Потрібно щонайменше %d Ñтовпців"
-#: ../option.c:6011
#, 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
#, c-format
msgid "E521: Number required: &%s = '%s'"
msgstr "E521: Потрібно вказати Number: &%s = '%s'"
-# msgstr "E355: "
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- Коди терміналу ---"
-
-#: ../option.c:6151
msgid ""
"\n"
"--- Global option values ---"
@@ -4819,7 +4090,6 @@ msgstr ""
"\n"
"--- Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¸Ñ… опцій ---"
-#: ../option.c:6153
msgid ""
"\n"
"--- Local option values ---"
@@ -4827,7 +4097,6 @@ msgstr ""
"\n"
"--- Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¸Ñ… опцій ---"
-#: ../option.c:6155
msgid ""
"\n"
"--- Options ---"
@@ -4835,40 +4104,46 @@ msgstr ""
"\n"
"--- Опції ---"
-#: ../option.c:6816
msgid "E356: get_varp ERROR"
msgstr "E356: Помилка get_varp"
-# msgstr "E356: "
-#: ../option.c:7696
#, c-format
msgid "E357: 'langmap': Matching character missing for %s"
msgstr "E357: 'langmap': Ð”Ð»Ñ Ñимволу %s немає пари"
-# msgstr "E357: "
-#: ../option.c:7715
#, c-format
msgid "E358: 'langmap': Extra characters after semicolon: %s"
msgstr "E358: 'langmap': Зайві Ñимволи піÑÐ»Ñ `;': %s"
-#: ../os/shell.c:194
+#, c-format
+msgid "dlerror = \"%s\""
+msgstr "dlerror = «%s»"
+
+#, c-format
+msgid "E5420: Failed to write to file: %s"
+msgstr "E5420: Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати у файл: %s"
+
+msgid "Vim: Error reading input, exiting...\n"
+msgstr "Vim: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð²Ð²Ð¾Ð´Ñƒ, робота завершуєтьÑÑ...\n"
+
msgid ""
"\n"
-"Cannot execute shell "
+"shell returned "
msgstr ""
"\n"
-"Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити оболонку"
+"оболонка повернула: "
-# msgstr "E362: "
-#: ../os/shell.c:439
msgid ""
"\n"
-"shell returned "
+"shell failed to start: "
msgstr ""
"\n"
-"оболонка повернула: "
+"не вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити оболонку: "
+
+#, c-format
+msgid "E5677: Error writing input to shell-command: %s"
+msgstr "E5677: Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати на вхід команди оболонки: %s"
-#: ../os_unix.c:465 ../os_unix.c:471
msgid ""
"\n"
"Could not get security context for "
@@ -4876,7 +4151,6 @@ msgstr ""
"\n"
"Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ контекÑÑ‚ безпеки Ð´Ð»Ñ "
-#: ../os_unix.c:479
msgid ""
"\n"
"Could not set security context for "
@@ -4884,234 +4158,188 @@ msgstr ""
"\n"
"Ðе вдалоÑÑ Ð²Ñтановити контекÑÑ‚ безпеки Ð´Ð»Ñ "
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = «%s»"
-
-# msgstr "E446: "
-#: ../path.c:1449
#, c-format
msgid "E447: Can't find file \"%s\" in path"
msgstr "E447: Файл «%s» не знайдено у шлÑху пошуку"
-# msgstr "E371: "
-#: ../quickfix.c:359
#, c-format
msgid "E372: Too many %%%c in format string"
msgstr "E372: Забагато %%%c у Ñ€Ñдку формату"
-# msgstr "E372: "
-#: ../quickfix.c:371
#, c-format
msgid "E373: Unexpected %%%c in format string"
msgstr "E373: Ðеочікуваний `%%%c' у Ñ€Ñдку формату"
-# msgstr "E373: "
-#: ../quickfix.c:420
msgid "E374: Missing ] in format string"
msgstr "E374: Пропущено ] у Ñ€Ñдку формату"
-# msgstr "E374: "
-#: ../quickfix.c:431
#, c-format
msgid "E375: Unsupported %%%c in format string"
msgstr "E375: %%%c у Ñ€Ñдку формату не підтримуєтьÑÑ"
-# msgstr "E375: "
-#: ../quickfix.c:448
#, c-format
msgid "E376: Invalid %%%c in format string prefix"
msgstr "E376: Помилковий `%%%c' у префікÑÑ– Ñ€Ñдку формату"
-# msgstr "E376: "
-#: ../quickfix.c:454
#, c-format
msgid "E377: Invalid %%%c in format string"
msgstr "E377: Помилковий `%%%c' у Ñ€Ñдку формату"
-# msgstr "E377: "
-#. nothing found
-#: ../quickfix.c:477
msgid "E378: 'errorformat' contains no pattern"
msgstr "E378: 'errorformat' не міÑтить зразок"
-# msgstr "E378: "
-#: ../quickfix.c:695
msgid "E379: Missing or empty directory name"
msgstr "E379: Пропущена чи Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° каталогу"
-#: ../quickfix.c:1305
msgid "E553: No more items"
msgstr "E553: Ðемає більше елементів"
-#: ../quickfix.c:1674
+msgid "E924: Current window was closed"
+msgstr "E924: Ðктивне вікно було закрито"
+
+msgid "E925: Current quickfix was changed"
+msgstr "E925: Цей quickfix було змінено"
+
+msgid "E926: Current location list was changed"
+msgstr "E926: Цей ÑпиÑок міÑць було змінено"
+
#, c-format
msgid "(%d of %d)%s%s: "
msgstr "(%d з %d)%s%s: "
-#: ../quickfix.c:1676
msgid " (line deleted)"
msgstr " (Ñ€Ñдок знищено)"
-#: ../quickfix.c:1863
+#, c-format
+msgid "%serror list %d of %d; %d errors "
+msgstr "%sÑпиÑок помилок %d з %d; %d помилок "
+
msgid "E380: At bottom of quickfix stack"
msgstr "E380: Дно Ñтеку виправлень"
-#: ../quickfix.c:1869
msgid "E381: At top of quickfix stack"
msgstr "E381: Вершина Ñтеку виправлень"
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "ÑпиÑок помилок %d з %d; %d помилок"
+msgid "No entries"
+msgstr "Ðічого"
-#: ../quickfix.c:2427
msgid "E382: Cannot write, 'buftype' option is set"
msgstr "E382: Ðе можу запиÑати, вказана Ð¾Ð¿Ñ†Ñ–Ñ 'buftype'"
-#: ../quickfix.c:2812
msgid "E683: File name missing or invalid pattern"
msgstr "E683: Пропущено назву файлу чи некоректний шаблон"
-#: ../quickfix.c:2911
#, c-format
msgid "Cannot open file \"%s\""
msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл «%s»"
-#: ../quickfix.c:3429
msgid "E681: Buffer is not loaded"
msgstr "E681: Буфер не завантажено"
-#: ../quickfix.c:3487
msgid "E777: String or List expected"
msgstr "E777: ОчікуєтьÑÑ String чи List"
-#: ../regexp.c:359
#, c-format
msgid "E369: invalid item in %s%%[]"
msgstr "E369: Ðекоректний елемент у %s%%[]"
-#: ../regexp.c:374
#, c-format
msgid "E769: Missing ] after %s["
msgstr "E769: Бракує ] піÑÐ»Ñ %s["
-#: ../regexp.c:375
+msgid "E944: Reverse range in character class"
+msgstr "E944: Зворотній діапазон у клаÑÑ– Ñимволів"
+
+msgid "E945: Range too large in character class"
+msgstr "E945: Завеликий діапазон у клаÑÑ– Ñимволів"
+
#, c-format
msgid "E53: Unmatched %s%%("
msgstr "E53: Ðемає пари %s%%("
-#: ../regexp.c:376
#, c-format
msgid "E54: Unmatched %s("
msgstr "E54: Ðемає пари %s("
-#: ../regexp.c:377
#, c-format
msgid "E55: Unmatched %s)"
msgstr "E55: Ðемає пари %s)"
-# msgstr "E406: "
-#: ../regexp.c:378
msgid "E66: \\z( not allowed here"
msgstr "E66: \\z( тут не дозволено"
-# msgstr "E406: "
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 та ін. тут не дозволено"
+msgid "E67: \\z1 - \\z9 not allowed here"
+msgstr "E67: \\z1 - \\z9 тут не дозволено"
-#: ../regexp.c:380
#, c-format
msgid "E69: Missing ] after %s%%["
msgstr "E69: Пропущено ] піÑÐ»Ñ %s%%["
-#: ../regexp.c:381
#, c-format
msgid "E70: Empty %s%%[]"
msgstr "E70: %s%%[] порожній"
-# msgstr "E382: "
-#: ../regexp.c:1209 ../regexp.c:1224
msgid "E339: Pattern too long"
msgstr "E339: Зразок занадто довгий"
-#: ../regexp.c:1371
msgid "E50: Too many \\z("
msgstr "E50: Забагато \\z("
-#: ../regexp.c:1378
#, c-format
msgid "E51: Too many %s("
msgstr "E51: Забагато %s("
-#: ../regexp.c:1427
msgid "E52: Unmatched \\z("
msgstr "E52: Ðемає пари \\z("
-#: ../regexp.c:1637
#, c-format
msgid "E59: invalid character after %s@"
msgstr "E59: Ðедозволений Ñимвол піÑÐ»Ñ %s@"
-#: ../regexp.c:1672
#, c-format
msgid "E60: Too many complex %s{...}s"
msgstr "E60: Забагато Ñкладних %s{...}"
-# msgstr "E339: "
-#: ../regexp.c:1687
#, c-format
msgid "E61: Nested %s*"
msgstr "E61: Вкладені %s*"
-# msgstr "E61: "
-#: ../regexp.c:1690
#, c-format
msgid "E62: Nested %s%c"
msgstr "E62: Вкладені %s%c"
-#: ../regexp.c:1800
msgid "E63: invalid use of \\_"
msgstr "E63: Ðекоректно вжито \\_"
-# msgstr "E62: "
-#: ../regexp.c:1850
#, c-format
msgid "E64: %s%c follows nothing"
msgstr "E64: ПіÑÐ»Ñ %s%c нічого немає"
-#: ../regexp.c:1902
msgid "E65: Illegal back reference"
msgstr "E65: Ðекоректне зворотнє поÑиланнÑ"
-#: ../regexp.c:1943
msgid "E68: Invalid character after \\z"
msgstr "E68: Ðеправильний Ñимвол піÑÐ»Ñ \\z"
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
#, c-format
msgid "E678: Invalid character after %s%%[dxouU]"
msgstr "E678: Ðедозволений Ñимвол піÑÐ»Ñ %s%%[dxouU]"
-#: ../regexp.c:2107
#, c-format
msgid "E71: Invalid character after %s%%"
msgstr "E71: Ðедозволений Ñимвол піÑÐ»Ñ %s%%"
-# msgstr "E64: "
-#: ../regexp.c:3017
+#, c-format
+msgid "E888: (NFA regexp) cannot repeat %s"
+msgstr "E888: (NFA regexp) неможливо повторити %s"
+
#, c-format
msgid "E554: Syntax error in %s{...}"
msgstr "E554: СинтакÑична помилка в %s{...}"
-#: ../regexp.c:3805
msgid "External submatches:\n"
msgstr "Зовнішні під-збіги:\n"
-#: ../regexp.c:7022
msgid ""
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
"used "
@@ -5119,345 +4347,437 @@ msgstr ""
"E864: піÑÐ»Ñ \\%#= може бути тільки 0, 1, or 2. Буде викориÑтано автоматичний "
"механізм "
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr "E865: (NFA) Зарано трапивÑÑ ÐºÑ–Ð½ÐµÑ†ÑŒ регулÑрного виразу"
+msgid "Switching to backtracking RE engine for pattern: "
+msgstr "ÐŸÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð´Ð¾ проÑтого Ñ€ÑƒÑˆÑ–Ñ Ñ€ÐµÐ³ÑƒÐ»Ñрних виразів: "
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr "E866: (NFA regexp) Ðе на міÑці %c"
+msgid " TERMINAL"
+msgstr " ТЕРМІÐÐЛ"
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr "E867: (NFA) Ðевідомий оператор '\\z%c'"
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr "E867: (NFA) Ðевідомий оператор '\\%%%c'"
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr "E869: (NFA) Ðевідомий оператор '\\@%c'"
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr "E870: (NFA regexp) Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ межі повтореннÑ"
-
-#. 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) Мульти не може бути за мульти!"
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr "E872: (NFA regexp) Забагато '('"
-
-#: ../regexp_nfa.c:2042
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E879: (NFA regexp) Забагато \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr "E873: (NFA regexp) помилка належного припиненнÑ"
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr "E874: (NFA) Стек порожній!"
-
-#: ../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) залишилоÑÑ "
-"забагато Ñтанів у Ñтеку"
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr "E876: (NFA regexp) ÐедоÑтатньо пам’Ñті, щоб зберегти веÑÑŒ NFA "
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-"Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ тимчаÑовий файл журналу Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу, показуєтьÑÑ Ð½Ð° "
-"stderr ... "
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr "(NFA) ÐЕ ВДÐЛОСЯ ВІДКРИТИ %s!"
-
-#: ../regexp_nfa.c:6049
-msgid "Could not open temporary log file for writing "
-msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ тимчаÑовий файл журналу Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу "
-
-#: ../screen.c:7435
msgid " VREPLACE"
msgstr " ВІРТ ЗÐМІÐÐ"
-#: ../screen.c:7437
msgid " REPLACE"
msgstr " ЗÐМІÐÐ"
-#: ../screen.c:7440
msgid " REVERSE"
msgstr " ÐÐВИВОРІТ"
-#: ../screen.c:7441
msgid " INSERT"
-msgstr " ВСТÐВКÐ"
+msgstr " ВСТÐВИТИ"
-#: ../screen.c:7443
msgid " (insert)"
-msgstr " (вÑтавка)"
+msgstr " (вÑтавити)"
-#: ../screen.c:7445
msgid " (replace)"
msgstr " (заміна)"
-#: ../screen.c:7447
msgid " (vreplace)"
msgstr " (вірт заміна)"
-#: ../screen.c:7449
msgid " Hebrew"
msgstr " Іврит"
-#: ../screen.c:7454
msgid " Arabic"
msgstr " ÐрабÑька"
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (мова)"
-
-#: ../screen.c:7459
msgid " (paste)"
msgstr " (клей)"
-#: ../screen.c:7469
msgid " VISUAL"
msgstr " ВИБІР"
-#: ../screen.c:7470
msgid " VISUAL LINE"
msgstr " ВИБІР РЯДКІВ"
-#: ../screen.c:7471
msgid " VISUAL BLOCK"
msgstr " ВИБІР БЛОКУ"
-#: ../screen.c:7472
msgid " SELECT"
msgstr " ВИДІЛЕÐÐЯ"
-#: ../screen.c:7473
msgid " SELECT LINE"
msgstr " ВИДІЛЕÐÐЯ РЯДКІВ"
-#: ../screen.c:7474
msgid " SELECT BLOCK"
msgstr " ВИДІЛЕÐÐЯ БЛОКУ"
-#: ../screen.c:7486 ../screen.c:7541
msgid "recording"
msgstr "йде запиÑ"
-#: ../search.c:487
#, c-format
msgid "E383: Invalid search string: %s"
msgstr "E383: Ðеправильний зразок Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ: %s"
-#: ../search.c:832
#, c-format
msgid "E384: search hit TOP without match for: %s"
msgstr "E384: Пошук дійшов до ПОЧÐТКУ без збігів з %s"
-#: ../search.c:835
#, c-format
msgid "E385: search hit BOTTOM without match for: %s"
msgstr "E385: Пошук дійшов до КІÐЦЯ без збігів з %s"
-#: ../search.c:1200
msgid "E386: Expected '?' or '/' after ';'"
msgstr "E386: ПіÑÐ»Ñ `;' має бути `?' або `/'"
-# msgstr "E386: "
-#: ../search.c:4085
msgid " (includes previously listed match)"
msgstr " (разом з попередніми збігами)"
-#. cursor at status line
-#: ../search.c:4104
msgid "--- Included files "
msgstr "--- Включені файли "
-#: ../search.c:4106
msgid "not found "
msgstr "не знайдено "
-#: ../search.c:4107
msgid "in path ---\n"
msgstr "у шлÑху пошуку ---\n"
-#: ../search.c:4168
msgid " (Already listed)"
msgstr " (Уже у ÑпиÑку)"
-#: ../search.c:4170
msgid " NOT FOUND"
msgstr " ÐЕ ЗÐÐЙДЕÐО"
-#: ../search.c:4211
#, c-format
msgid "Scanning included file: %s"
msgstr "Пошук у включеному файлі: %s"
-#: ../search.c:4216
#, c-format
msgid "Searching included file %s"
msgstr "ШукаєтьÑÑ Ñƒ включеному файлі %s"
-#: ../search.c:4405
msgid "E387: Match is on current line"
msgstr "E387: Збіг у поточному Ñ€Ñдку"
-#: ../search.c:4517
msgid "All included files were found"
msgstr "Були знайдені вÑÑ– включені файли"
-#: ../search.c:4519
msgid "No included files"
msgstr "Жодного включеного файлу"
-#: ../search.c:4527
msgid "E388: Couldn't find definition"
msgstr "E388: Ð’Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ знайдено"
-#: ../search.c:4529
msgid "E389: Couldn't find pattern"
msgstr "E389: Зразок не знайдено"
-#: ../search.c:4668
-msgid "Substitute "
-msgstr "Заміна "
+msgid "too few bytes read"
+msgstr "прочитано замало байтів"
+
+#, c-format
+msgid "System error while skipping in ShaDa file: %s"
+msgstr "СиÑтемна помилка при пропуÑканні у файлі ShaDa: %s"
-#: ../search.c:4681
#, c-format
msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
+"Error while reading ShaDa file: last entry specified that it occupies "
+"%<PRIu64> bytes, but file ended earlier"
msgstr ""
-"\n"
-"# ОÑÑ‚. %sЗразок пошуку:\n"
-"~"
+"Помилка при читанні файлу ShaDa: оÑтаннє поле зазначило, що воно займає "
+"%<PRIu64> байтів, але файл закінчивÑÑ Ñ€Ð°Ð½Ñ–ÑˆÐµ"
+
+#, c-format
+msgid "System error while closing ShaDa file: %s"
+msgstr "СиÑтемна помилка при закритті файлу ShaDa: %s"
+
+#, c-format
+msgid "System error while writing ShaDa file: %s"
+msgstr "СиÑтемна помилка при читанні з файлу ShaDa: %s"
+
+#, c-format
+msgid "Reading ShaDa file \"%s\"%s%s%s%s"
+msgstr "ЗчитуєтьÑÑ Ñ„Ð°Ð¹Ð» ShaDa: «%s»%s%s%s%s"
+
+msgid " info"
+msgstr " інформаціÑ"
+
+msgid " marks"
+msgstr " позначки"
+
+msgid " oldfiles"
+msgstr " Ñтарі файли"
+
+msgid " FAILED"
+msgstr " ÐЕ ВДÐЛОСЯ"
+
+#, c-format
+msgid "System error while opening ShaDa file %s for reading: %s"
+msgstr "СиÑтемна помилка при відкритті файлу ShaDa %s Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ: %s"
+
+msgid "additional elements of ShaDa "
+msgstr "додаткові елементи ShaDa "
+
+msgid "additional data of ShaDa "
+msgstr "додаткові дані ShaDa "
+
+#, c-format
+msgid "Failed to write variable %s"
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати змінну %s"
+
+#, c-format
+msgid ""
+"Failed to parse ShaDa file due to a msgpack parser error at position "
+"%<PRIu64>"
+msgstr ""
+"Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ файл ShaDa через помилку розбору msgpack у позиції "
+"%<PRIu64>"
+
+#, c-format
+msgid ""
+"Failed to parse ShaDa file: incomplete msgpack string at position %<PRIu64>"
+msgstr ""
+"Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ файл ShaDa: неповний текÑÑ‚ msgpack у позиції %<PRIu64>"
+
+#, c-format
+msgid ""
+"Failed to parse ShaDa file: extra bytes in msgpack string at position "
+"%<PRIu64>"
+msgstr ""
+"Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ файл ShaDa: зайві байти у текÑті msgpack у позиції "
+"%<PRIu64>"
+
+#, c-format
+msgid ""
+"System error while opening ShaDa file %s for reading to merge before writing "
+"it: %s"
+msgstr ""
+"СиÑтемна помилка при відкритті файлу ShaDa %s Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð± виконати "
+"Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð¿ÐµÑ€ÐµÐ´ запиÑом: %s"
+
+#, c-format
+msgid "E138: All %s.tmp.X files exist, cannot write ShaDa file!"
+msgstr "E138: УÑÑ– файли %s.tmp.X зайнÑто, неможливо запиÑати файл ShaDa!"
+
+#, c-format
+msgid "System error while opening temporary ShaDa file %s for writing: %s"
+msgstr ""
+"СиÑтемна помилка при відкритті тимчаÑового файлу ShaDa %s Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу: %s"
+
+#, c-format
+msgid "Failed to create directory %s for writing ShaDa file: %s"
+msgstr "Ðе вдалоÑÑ Ñтворити каталог %s Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу файлу ShaDa: %s"
+
+#, c-format
+msgid "System error while opening ShaDa file %s for writing: %s"
+msgstr "СиÑтемна помилка при відкритті файлу ShaDa %s Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу: %s"
+
+#, c-format
+msgid "Writing ShaDa file \"%s\""
+msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» ShaDa «%s»"
+
+#, c-format
+msgid "Failed setting uid and gid for file %s: %s"
+msgstr "Ðе вдалоÑÑ Ð²Ñтановити uid Ñ– gid Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñƒ %s: %s"
+
+#, c-format
+msgid "E137: ShaDa file is not writable: %s"
+msgstr "E137: Ðе дозволено Ð·Ð°Ð¿Ð¸Ñ Ñƒ файл ShaDa: %s"
+
+#, c-format
+msgid "Can't rename ShaDa file from %s to %s!"
+msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ файл ShaDa з %s у %s!"
+
+#, c-format
+msgid "Did not rename %s because %s does not look like a ShaDa file"
+msgstr "Ðе перейменував %s, тому що %s не Ñхожий на файл ShaDa"
+
+#, c-format
+msgid "Did not rename %s to %s because there were errors during writing it"
+msgstr "Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ %s у %s через помилки під Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñу"
+
+#, c-format
+msgid "Do not forget to remove %s or rename it manually to %s."
+msgstr "Ðе забудьте знищити %s чи перейменувати його ÑамоÑтійно у %s."
+
+#, c-format
+msgid "System error while reading ShaDa file: %s"
+msgstr "СиÑтемна помилка при читанні файлу ShaDa: %s"
+
+#, c-format
+msgid "System error while reading integer from ShaDa file: %s"
+msgstr "СиÑтемна помилка при читанні цілого чиÑла з файлу ShaDa: %s"
+
+#, c-format
+msgid ""
+"Error while reading ShaDa file: expected positive integer at position "
+"%<PRIu64>, but got nothing"
+msgstr ""
+"Помилка при читанні файлу ShaDa: очікувалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð½Ðµ чиÑло у позиції "
+"%<PRIu64>, але нічого немає"
+
+#, c-format
+msgid ""
+"Error while reading ShaDa file: expected positive integer at position "
+"%<PRIu64>"
+msgstr ""
+"Помилка при читанні файлу ShaDa: очікувалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð½Ðµ чиÑло у позиції "
+"%<PRIu64>"
+
+#, c-format
+msgid ""
+"Error while reading ShaDa file: there is an item at position %<PRIu64> that "
+"is stated to be too long"
+msgstr "Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ ShaDa: Ñ” задовгий елемент у позиції %<PRIu64>"
+
+#, 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: неочікуваний елемент у позиції %<PRIu64>: "
+"Пропущені елементи тільки Ð´Ð»Ñ Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ вжитку"
+
+#, c-format
+msgid ""
+"Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+"entry that is not a dictionary"
+msgstr ""
+"Помилка при читанні файлу ShaDa: ÑпиÑок буферів у позиції %<PRIu64> міÑтить "
+"поле, Ñке не Ñ” Ñловником"
+
+#, c-format
+msgid ""
+"Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+"entry with invalid line number"
+msgstr ""
+"Помилка при читанні файлу ShaDa: ÑпиÑок буферів у позиції %<PRIu64> міÑтить "
+"поле з некоректним номером Ñ€Ñдка"
+
+#, c-format
+msgid ""
+"Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+"entry with invalid column number"
+msgstr ""
+"Помилка при читанні файлу ShaDa: ÑпиÑок буферів у позиції %<PRIu64> міÑтить "
+"поле з некоректним номером ÑтовпцÑ"
+
+#, c-format
+msgid ""
+"Error while reading ShaDa file: buffer list at position %<PRIu64> contains "
+"entry that does not have a file name"
+msgstr ""
+"Помилка при читанні файлу ShaDa: ÑпиÑок буферів у позиції %<PRIu64> міÑтить "
+"поле, Ñке не має назву файлу"
-#: ../spell.c:951
msgid "E759: Format error in spell file"
msgstr "E759: Помилка формату у файлі орфографії"
-# msgstr "E364: "
-#: ../spell.c:952
+msgid "E756: Spell checking is not enabled"
+msgstr "E756: Перевірка орфографії не дозволена"
+
+#, c-format
+msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
+msgstr ""
+"ЗаÑтереженнÑ: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ ÑпиÑок Ñлів «%s.%s.spl» чи «%s.ascii.spl»"
+
+msgid "E797: SpellFileMissing autocommand deleted buffer"
+msgstr "E797: Ðвтокоманда SpellFileMissing знищила буфер"
+
+#, c-format
+msgid "Warning: region %s not supported"
+msgstr "ЗаÑтереженнÑ: регіон %s не підтримуєтьÑÑ"
+
+msgid "Sorry, no suggestions"
+msgstr "Пробачте, немає пропозицій"
+
+#, c-format
+msgid "Sorry, only %<PRId64> suggestions"
+msgstr "Пробачте, тільки %<PRId64> пропозицій"
+
+#, c-format
+msgid "Change \"%.*s\" to:"
+msgstr "Замінити «%.*s» на:"
+
+#, c-format
+msgid " < \"%.*s\""
+msgstr " < «%.*s»"
+
+msgid "E752: No previous spell replacement"
+msgstr "E752: Ðемає попередньої заміни"
+
+#, c-format
+msgid "E753: Not found: %s"
+msgstr "E753: Ðе знайдено: %s"
+
msgid "E758: Truncated spell file"
msgstr "E758: Обірваний файл орфографії"
-#: ../spell.c:953
#, c-format
msgid "Trailing text in %s line %d: %s"
msgstr "Зайвий текÑÑ‚ у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:954
#, c-format
msgid "Affix name too long in %s line %d: %s"
msgstr "Ðазва афікÑу завелика у %s у Ñ€Ñдку %d: %s"
-# msgstr "E430: "
-#: ../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
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» чи «%s.ascii.spl»"
-
-#: ../spell.c:2473
#, c-format
msgid "Reading spell file \"%s\""
msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» орфографії «%s»"
-#: ../spell.c:2496
msgid "E757: This does not look like a spell file"
msgstr "E757: Ðе Ñхоже на файл орфографії"
-#: ../spell.c:2501
+#, c-format
+msgid "E5042: Failed to read spell file %s: %s"
+msgstr "E5042: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ файл правопиÑу %s: %s"
+
msgid "E771: Old spell file, needs to be updated"
msgstr "E771: Файл орфографії Ñтарий, треба поновити"
-#: ../spell.c:2504
msgid "E772: Spell file is for newer version of Vim"
msgstr "E772: Файл орфографії призначений Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ нової верÑÑ–Ñ— Vim"
-#: ../spell.c:2602
msgid "E770: Unsupported section in spell file"
msgstr "E770: Ðедозволена ÑÐµÐºÑ†Ñ–Ñ Ñƒ файлі орфографії"
-#: ../spell.c:3762
#, 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"
+
+#, c-format
+msgid "E779: Old .sug file, needs to be updated: %s"
+msgstr "E779: ЗаÑтарілий файл .sug, треба поновити: %s"
+
+#, c-format
+msgid "E780: .sug file is for newer version of Vim: %s"
+msgstr "E780: Файл .sug Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ нової верÑÑ–Ñ— Vim: %s"
+
+#, c-format
+msgid "E781: .sug file doesn't match .spl file: %s"
+msgstr "E781: Файл .sug не відповідає файлу .spl: %s"
+
+#, c-format
+msgid "E782: error while reading .sug file: %s"
+msgstr "E782: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ .sug: %s"
-#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
-msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» афікÑів %s ..."
+msgid "Reading affix file %s..."
+msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» афікÑів %s..."
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
#, c-format
msgid "Conversion failure for word in %s line %d: %s"
msgstr "Помилка Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñлова у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4630 ../spell.c:6170
#, c-format
msgid "Conversion in %s not supported: from %s to %s"
msgstr "ÐŸÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñƒ %s не підтримуєтьÑÑ: з %s до %s"
-#: ../spell.c:4642
#, c-format
msgid "Invalid value for FLAG in %s line %d: %s"
msgstr "Ðекоректне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ FLAG у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4655
#, c-format
msgid "FLAG after using flags in %s line %d: %s"
msgstr "FLAG піÑÐ»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ð¿Ð¾Ñ€Ñ†Ñ–Ð² у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4723
#, c-format
msgid ""
"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
@@ -5466,7 +4786,6 @@ msgstr ""
"Ð’Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ COMPOUNDFORBIDFLAG піÑÐ»Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚Ñƒ PFX може дати неправильний "
"результат у %s у Ñ€Ñдку %d"
-#: ../spell.c:4731
#, c-format
msgid ""
"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
@@ -5475,382 +4794,292 @@ msgstr ""
"Ð’Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ COMPOUNDPERMITFLAG піÑÐ»Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚Ñƒ PFX можу дати неправильний "
"результат у %s у Ñ€Ñдку %d"
-#: ../spell.c:4747
#, c-format
msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
msgstr "Ðеправильне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ COMPOUNDRULES у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4771
#, c-format
msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
msgstr "Ðеправильне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ COMPOUNDWORDMAX у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4777
#, c-format
msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
msgstr "Ðеправильне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ COMPOUNDMIN у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4783
#, c-format
msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
msgstr "Ðеправильне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ COMPOUNDSYLMAX у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4795
#, c-format
msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
msgstr "Ðеправильне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ CHECKCOMPOUNDPATTERN у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4847
#, c-format
msgid "Different combining flag in continued affix block in %s line %d: %s"
msgstr ""
"Інший прапорець комбінації у продовженні блоку афікÑів у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4850
#, c-format
msgid "Duplicate affix in %s line %d: %s"
msgstr "Подвійний Ð°Ñ„Ñ–ÐºÑ Ñƒ %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4871
#, c-format
msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
+"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGESTin %s "
"line %d: %s"
msgstr ""
-"ÐÑ„Ñ–ÐºÑ Ñ‚Ð°ÐºÐ¾Ð¶ викориÑтовуєтьÑÑ Ð´Ð»Ñ BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
-"NOSUGGEST у %s у Ñ€Ñдку %d: %s"
+"ÐÑ„Ñ–ÐºÑ Ñ‚Ð°ÐºÐ¾Ð¶ вживаєтьÑÑ Ð´Ð»Ñ BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/"
+"NOSUGGEST у %s Ñ€Ñдок %d: %s"
-#: ../spell.c:4893
#, c-format
msgid "Expected Y or N in %s line %d: %s"
msgstr "Треба Y чи N у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:4968
#, c-format
msgid "Broken condition in %s line %d: %s"
msgstr "Ðепридатна умова у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:5091
#, c-format
msgid "Expected REP(SAL) count in %s line %d"
msgstr "Треба кількіÑть REP(SAL) у %s у Ñ€Ñдку %d"
-#: ../spell.c:5120
#, c-format
msgid "Expected MAP count in %s line %d"
msgstr "Треба кількіÑть MAP у %s у Ñ€Ñдку %d"
-#: ../spell.c:5132
#, c-format
msgid "Duplicate character in MAP in %s line %d"
msgstr "ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ñимволу у MAP у %s у Ñ€Ñдку %d"
-#: ../spell.c:5176
#, 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 "Пропущено Ñ€Ñдок FOL/LOW/UPP у %s"
-#: ../spell.c:5220
msgid "COMPOUNDSYLMAX used without SYLLABLE"
msgstr "Вжито COMPOUNDSYLMAX без SYLLABLE"
-#: ../spell.c:5236
msgid "Too many postponed prefixes"
msgstr "Забагато відкладених префікÑів"
-#: ../spell.c:5238
msgid "Too many compound flags"
msgstr "Забагато Ñкладних прапорців"
-#: ../spell.c:5240
msgid "Too many postponed prefixes and/or compound flags"
msgstr "Забагато відкладених префікÑів Ñ–/або Ñкладних прапорців"
-#: ../spell.c:5250
#, c-format
msgid "Missing SOFO%s line in %s"
msgstr "Пропущено Ñ€Ñдок SOFO%s у %s"
-#: ../spell.c:5253
#, c-format
msgid "Both SAL and SOFO lines in %s"
msgstr "Обидва Ñ€Ñдки SAL Ñ– SOFO у %s"
-#: ../spell.c:5331
#, c-format
msgid "Flag is not a number in %s line %d: %s"
msgstr "Прапорець не Ñ” чиÑлом у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:5334
#, c-format
msgid "Illegal flag in %s line %d: %s"
msgstr "Ðеправильний прапорець у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:5493 ../spell.c:5501
#, c-format
msgid "%s value differs from what is used in another .aff file"
msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s відрізнÑєтьÑÑ Ð²Ñ–Ð´ того, що вжито у іншому файлі .aff"
-#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "ЗчитуєтьÑÑ Ñловниковий файл %s ..."
+msgid "Reading dictionary file %s..."
+msgstr "ЗчитуєтьÑÑ Ñловниковий файл %s..."
-#: ../spell.c:5611
#, c-format
msgid "E760: No word count in %s"
msgstr "E760: Ðемає кількоÑті Ñлів у %s"
-#: ../spell.c:5669
#, 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
#, c-format
msgid "Duplicate word in %s line %d: %s"
msgstr "ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ñлова у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:5694
#, c-format
msgid "First duplicate word in %s line %d: %s"
msgstr "Перше Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ñлова у %s у Ñ€Ñдку %d: %s"
-#: ../spell.c:5746
#, c-format
msgid "%d duplicate word(s) in %s"
msgstr "%d повторюваних Ñлів у %s"
-#: ../spell.c:5748
#, c-format
msgid "Ignored %d word(s) with non-ASCII characters in %s"
msgstr "Пропущено %d Ñлів(~) із не-ASCII Ñимволами у %s"
-#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
-msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» Ñлів %s ..."
+msgid "Reading word file %s..."
+msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» Ñлів %s..."
+
+#, c-format
+msgid "Conversion failure for word in %s line %ld: %s"
+msgstr "Помилка Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñлова у %s у Ñ€Ñдку %ld: %s"
-#: ../spell.c:6155
#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr "ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ñдка /encoding= проігноровано у %s у Ñ€Ñдку %d: %s"
+msgid "Duplicate /encoding= line ignored in %s line %ld: %s"
+msgstr "ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ñдка /encoding= проігноровано у %s у Ñ€Ñдку %ld: %s"
-#: ../spell.c:6159
#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "РÑдок /encoding= піÑÐ»Ñ Ñлова проігноровано у %s у Ñ€Ñдку %d: %s"
+msgid "/encoding= line after word ignored in %s line %ld: %s"
+msgstr "РÑдок /encoding= піÑÐ»Ñ Ñлова проігноровано у %s у Ñ€Ñдку %ld: %s"
-#: ../spell.c:6180
#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ñдка /regions= проігноровано у %s у Ñ€Ñдку %d: %s"
+msgid "Duplicate /regions= line ignored in %s line %ld: %s"
+msgstr "ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ñдка /regions= проігноровано у %s у Ñ€Ñдку %ld: %s"
-#: ../spell.c:6185
#, 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
#, 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
#, 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
#, 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
#, c-format
msgid "Ignored %d words with non-ASCII characters"
msgstr "Проігноровано %d Ñлів із не-ASCII Ñимволами"
-#: ../spell.c:6656
#, c-format
msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
msgstr "СтиÑнено %d з %d вузлів; залишилоÑÑ %d (%d%%)"
-#: ../spell.c:7340
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
msgid "Performing soundfolding..."
msgstr "ВиконуєтьÑÑ Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð·Ð²ÑƒÐºÑ–Ð²..."
-#: ../spell.c:7368
#, c-format
msgid "Number of words after soundfolding: %<PRId64>"
msgstr "КількіÑть Ñлів піÑÐ»Ñ Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð·Ð²ÑƒÐºÑ–Ð²: %<PRId64>"
-#: ../spell.c:7476
#, c-format
msgid "Total number of words: %d"
msgstr "Повна кількіÑть Ñлів: %d"
-#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» припущень %s ..."
+msgid "Writing suggestion file %s..."
+msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» припущень %s..."
-#: ../spell.c:7707 ../spell.c:7927
#, c-format
msgid "Estimated runtime memory use: %d bytes"
msgstr "Оцінка ÑÐ¿Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті: %d байт"
-#: ../spell.c:7820
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: ПідтримуєтьÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ до воÑьми регіонів"
+#, c-format
+msgid "E754: Only up to %d regions supported"
+msgstr "E754: ПідтримуєтьÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ до %d регіонів"
-#: ../spell.c:7846
#, c-format
msgid "E755: Invalid region in %s"
msgstr "E755: Ðекоректний регіон у %s"
-#: ../spell.c:7907
msgid "Warning: both compounding and NOBREAK specified"
msgstr "ЗаÑтереженнÑ: зазначено обидва `Ñкладні Ñлова' Ñ– NOBREAK"
-#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
-msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» орфографії %s ..."
+msgid "Writing spell file %s..."
+msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» орфографії %s..."
-#: ../spell.c:7925
msgid "Done!"
msgstr "Зроблено!"
-#: ../spell.c:8034
#, c-format
msgid "E765: 'spellfile' does not have %<PRId64> entries"
msgstr "E765: 'spellfile' не міÑтить %<PRId64> елементів"
-#: ../spell.c:8074
#, c-format
msgid "Word '%.*s' removed from %s"
msgstr "Слово '%.*s' знищено з %s"
-#: ../spell.c:8117
#, c-format
msgid "Word '%.*s' added to %s"
msgstr "Слово '%.*s' додано до %s"
-#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
msgstr "E763: Символи у Ñлові відрізнÑютьÑÑ Ñƒ файлах орфографії"
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "Пробачте, немає пропозицій"
+msgid "E783: duplicate char in MAP entry"
+msgstr "E783: Повторено Ñимвол у елементі MAP"
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "Пробачте, тільки %<PRId64> пропозицій"
+msgid "E766: Insufficient arguments for printf()"
+msgstr "E766: ÐедоÑтатньо аргументів Ð´Ð»Ñ printf()"
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "Замінити «%.*s» на:"
+msgid "E807: Expected Float argument for printf()"
+msgstr "E807: ОчікуєтьÑÑ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚ Float Ð´Ð»Ñ printf()"
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < «%.*s»"
+msgid "E767: Too many arguments to printf()"
+msgstr "E767: Забагато аргументів Ð´Ð»Ñ printf()"
-# msgstr "E34: "
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: Ðемає попередньої заміни"
+msgid "No Syntax items defined for this buffer"
+msgstr "Ð”Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° не визначено елементів ÑинтакÑиÑу"
-# msgstr "E333: "
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: Ðе знайдено: %s"
+msgid "syntax conceal on"
+msgstr "ÑинтакÑичне Ð¿Ñ€Ð¸Ñ…Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÐ²Ñ–Ð¼Ðº"
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: Ðе Ñхоже на файл .sug: %s"
+msgid "syntax conceal off"
+msgstr "ÑинтакÑичне Ð¿Ñ€Ð¸Ñ…Ð¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð¼Ðº"
-#: ../spell.c:9282
#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr "E779: ЗаÑтарілий файл .sug, треба поновити: %s"
+msgid "E390: Illegal argument: %s"
+msgstr "E390: Ðеправильний аргумент: %s"
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr "E780: Файл .sug Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ нової верÑÑ–Ñ— Vim: %s"
+msgid "syntax case ignore"
+msgstr "ÑинтакÑÐ¸Ñ Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ñ‚Ð¸ регіÑтр"
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr "E781: Файл .sug не відповідає файлу .spl: %s"
+msgid "syntax case match"
+msgstr "ÑинтакÑÐ¸Ñ Ð´Ð¾Ñ‚Ñ€Ð¸Ð¼ÑƒÐ²Ð°Ñ‚Ð¸ÑÑ Ñ€ÐµÐ³Ñ–Ñтру"
-#: ../spell.c:9305
-#, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E782: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ .sug: %s"
+msgid "syntax spell toplevel"
+msgstr "ÑинтакÑÐ¸Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€Ñти вÑюди"
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr "E783: Повторено Ñимвол у елементі MAP"
+msgid "syntax spell notoplevel"
+msgstr "ÑинтакÑÐ¸Ñ Ð½Ðµ перевірÑти"
-# msgstr "E391: "
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "Ð”Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° не визначено елементів ÑинтакÑиÑу"
+msgid "syntax spell default"
+msgstr "ÑинтакÑÐ¸Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÐ¾Ð²Ð¾"
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: Ðеправильний аргумент: %s"
+msgid "syntax iskeyword "
+msgstr "ÑинтакÑÐ¸Ñ iskeyword "
-#: ../syntax.c:3299
#, c-format
msgid "E391: No such syntax cluster: %s"
msgstr "E391: Ðемає такого ÑинтакÑичного клаÑтера: %s"
-#: ../syntax.c:3433
msgid "syncing on C-style comments"
msgstr "ÑинхронізуєтьÑÑ Ð¿Ð¾ коментарÑÑ… Ñтилю С"
-#: ../syntax.c:3439
msgid "no syncing"
msgstr "без Ñинхронізації"
-#: ../syntax.c:3441
msgid "syncing starts "
msgstr "починаєтьÑÑ ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð·Ð° "
-#: ../syntax.c:3443 ../syntax.c:3506
msgid " lines before top line"
msgstr " Ñ€Ñдків перед першим Ñ€Ñдком"
-#: ../syntax.c:3448
msgid ""
"\n"
"--- Syntax sync items ---"
@@ -5858,7 +5087,6 @@ msgstr ""
"\n"
"--- Елементи Ñинхронізації ÑинтакÑиÑу ---"
-#: ../syntax.c:3452
msgid ""
"\n"
"syncing on items"
@@ -5866,7 +5094,6 @@ msgstr ""
"\n"
"ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ Ð¿Ð¾ елементах"
-#: ../syntax.c:3457
msgid ""
"\n"
"--- Syntax items ---"
@@ -5874,581 +5101,371 @@ msgstr ""
"\n"
"--- Елементи ÑинтакÑиÑу ---"
-#: ../syntax.c:3475
#, c-format
msgid "E392: No such syntax cluster: %s"
msgstr "E392: Ðемає такого ÑинтакÑичного клаÑтера: %s"
-#: ../syntax.c:3497
msgid "minimal "
msgstr "мінімальний "
-#: ../syntax.c:3503
msgid "maximal "
msgstr "макÑимальний "
-#: ../syntax.c:3513
msgid "; match "
msgstr "; збіг "
-#: ../syntax.c:3515
msgid " line breaks"
msgstr " розриви Ñ€Ñдків"
-#: ../syntax.c:4076
msgid "E395: contains argument not accepted here"
msgstr "E395: МіÑтить неприйнÑтні тут аргументи"
-# msgstr "E14: "
-#: ../syntax.c:4096
msgid "E844: invalid cchar value"
msgstr "E844: Ðекоректне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ cchar"
-#: ../syntax.c:4107
msgid "E393: group[t]here not accepted here"
msgstr "E393: group[t]hete тут неприйнÑтний"
-#: ../syntax.c:4126
#, c-format
msgid "E394: Didn't find region item for %s"
msgstr "E394: Ðе знайдено елемент регіону Ð´Ð»Ñ %s"
-# msgstr "E396: "
-#: ../syntax.c:4188
msgid "E397: Filename required"
msgstr "E397: Потрібна назва файлу"
-#: ../syntax.c:4221
msgid "E847: Too many syntax includes"
msgstr "E847: Забагато ÑинтакÑичних включень"
-#: ../syntax.c:4303
#, c-format
msgid "E789: Missing ']': %s"
msgstr "E789: Пропущено ']': %s"
-#: ../syntax.c:4531
+#, c-format
+msgid "E890: trailing char after ']': %s]%s"
+msgstr "E890: Зайвий Ñимвол піÑÐ»Ñ ']': %s]%s"
+
#, c-format
msgid "E398: Missing '=': %s"
msgstr "E398: Пропущено `=': %s"
-# ---------------------------------------
-#: ../syntax.c:4666
#, c-format
msgid "E399: Not enough arguments: syntax region %s"
msgstr "E399: Бракує аргументів: ÑинтакÑичний регіон %s"
-#: ../syntax.c:4870
msgid "E848: Too many syntax clusters"
msgstr "E848: Забагато ÑинтакÑичних клаÑтерів"
-#: ../syntax.c:4954
msgid "E400: No cluster specified"
msgstr "E400: КлаÑтер не вказано"
-#. end delimiter not found
-#: ../syntax.c:4986
#, c-format
msgid "E401: Pattern delimiter not found: %s"
msgstr "E401: Кінець зразку не знайдено: %s"
-#: ../syntax.c:5049
#, c-format
msgid "E402: Garbage after pattern: %s"
msgstr "E402: Ð¡Ð¼Ñ–Ñ‚Ñ‚Ñ Ð¿Ñ–ÑÐ»Ñ Ð·Ñ€Ð°Ð·ÐºÑƒ: %s"
-# msgstr "E402: "
-#: ../syntax.c:5120
msgid "E403: syntax sync: line continuations pattern specified twice"
msgstr ""
"E403: СинтакÑична ÑинхронізаціÑ: зразок Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ Ñ€Ñдка вказано двічі"
-#: ../syntax.c:5169
#, c-format
msgid "E404: Illegal arguments: %s"
msgstr "E404: Ðеправильні аргументи: %s"
-# msgstr "E404: "
-#: ../syntax.c:5217
#, c-format
msgid "E405: Missing equal sign: %s"
msgstr "E405: Пропущено знак рівноÑті: %s"
-# msgstr "E405: "
-#: ../syntax.c:5222
#, c-format
msgid "E406: Empty argument: %s"
msgstr "E406: Порожній аргумент: %s"
-# msgstr "E406: "
-#: ../syntax.c:5240
#, c-format
msgid "E407: %s not allowed here"
msgstr "E407: %s тут не дозволено"
-#: ../syntax.c:5246
#, c-format
msgid "E408: %s must be first in contains list"
msgstr "E408: %s має бути першим Ñ€Ñдком у ÑпиÑку contains"
-#: ../syntax.c:5304
#, c-format
msgid "E409: Unknown group name: %s"
msgstr "E409: Ðевідома назва групи: %s"
-# msgstr "E409: "
-#: ../syntax.c:5512
#, c-format
msgid "E410: Invalid :syntax subcommand: %s"
msgstr "E410: Ðеправильна підкоманда :syntax: %s"
-#: ../syntax.c:5854
msgid ""
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
msgstr ""
" ВСЬОГО К-ТЬ СПІВП. ÐÐЙПОВІЛ. СЕРЕДÐ. ÐÐЗВРШÐБЛОÐ"
-#: ../syntax.c:6146
msgid "E679: recursive loop loading syncolor.vim"
msgstr "E679: РекурÑивний цикл Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ syncolor.vim"
-# msgstr "E410: "
-#: ../syntax.c:6256
#, c-format
msgid "E411: highlight group not found: %s"
msgstr "E411: Групу підÑÐ²Ñ–Ñ‡ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ знайдено: %s"
-# msgstr "E411: "
-#: ../syntax.c:6278
#, c-format
msgid "E412: Not enough arguments: \":highlight link %s\""
msgstr "E412: ÐедоÑтатньо аргументів: «:highlight link %s»"
-# msgstr "E412: "
-#: ../syntax.c:6284
#, c-format
msgid "E413: Too many arguments: \":highlight link %s\""
msgstr "E413: Забагато аргументів: «:highlight link %s»"
-# msgstr "E413: "
-#: ../syntax.c:6302
msgid "E414: group has settings, highlight link ignored"
msgstr "E414: Грума має settings, highlight link проігноровано"
-# msgstr "E414: "
-#: ../syntax.c:6367
#, c-format
msgid "E415: unexpected equal sign: %s"
msgstr "E415: ÐеÑподіваний знак рівноÑті: %s"
-# msgstr "E415: "
-#: ../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"
-# msgstr "E418: "
-#: ../syntax.c:6496
msgid "E419: FG color unknown"
msgstr "E419: Ðевідомий колір текÑту"
-# msgstr "E419: "
-#: ../syntax.c:6504
msgid "E420: BG color unknown"
msgstr "E420: Ðевідомий колір фону"
-# msgstr "E420: "
-#: ../syntax.c:6564
#, c-format
msgid "E421: Color name or number not recognized: %s"
msgstr "E421: Ðерозпізнана назва або номер кольору: %s"
-# msgstr "E421: "
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: Занадто довгий код терміналу: %s"
-
-# msgstr "E422: "
-#: ../syntax.c:6753
#, c-format
msgid "E423: Illegal argument: %s"
msgstr "E423: Ðеправильний аргумент: %s"
-# msgstr "E423: "
-#: ../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: Ðедруковний Ñимвол у назві групи"
-# msgstr "E181: "
-#: ../syntax.c:7434
msgid "W18: Invalid character in group name"
msgstr "W18: Ðекоректний Ñимвол у назві групи"
-#: ../syntax.c:7448
msgid "E849: Too many highlight and syntax groups"
msgstr "E849: Забагато груп підÑÐ²Ñ–Ñ‡ÑƒÐ²Ð°Ð½Ð½Ñ Ñ– ÑинтакÑиÑу"
-# msgstr "E424: "
-#: ../tag.c:104
msgid "E555: at bottom of tag stack"
-msgstr "E555: Кінець Ñтеку теґів"
+msgstr "E555: Кінець Ñтеку міток"
-#: ../tag.c:105
msgid "E556: at top of tag stack"
-msgstr "E556: Вершина Ñтеку теґів"
+msgstr "E556: Вершина Ñтеку міток"
-#: ../tag.c:380
msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Це вже найперший відповідний теґ"
+msgstr "E425: Це вже найперша відповідна мітка"
-# msgstr "E425: "
-#: ../tag.c:504
#, c-format
msgid "E426: tag not found: %s"
-msgstr "E426: Теґ не знайдено: %s"
+msgstr "E426: Мітку не знайдено: %s"
-# msgstr "E426: "
-#: ../tag.c:528
msgid " # pri kind tag"
-msgstr " # прі тип теґ"
+msgstr " # прі тип мітка"
-#: ../tag.c:531
msgid "file\n"
msgstr "файл\n"
-#: ../tag.c:829
msgid "E427: There is only one matching tag"
-msgstr "E427: Лише один відповідний теґ"
+msgstr "E427: Лише одна відповідна мітка"
-# msgstr "E427: "
-#: ../tag.c:831
msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: Це вже оÑтанній відповідний теґ"
+msgstr "E428: Це вже оÑÑ‚Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð° мітка"
-# msgstr "E428: "
-#: ../tag.c:850
#, c-format
msgid "File \"%s\" does not exist"
msgstr "Файл «%s» не Ñ–Ñнує"
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
#, c-format
msgid "tag %d of %d%s"
-msgstr "теґ %d з %d%s"
+msgstr "мітка %d з %d%s"
-#: ../tag.c:862
msgid " or more"
msgstr " або більше"
-#: ../tag.c:864
msgid " Using tag with different case!"
-msgstr " ВикориÑтано теґ, не розрізнÑючи великі й малі літери"
+msgstr " ВикориÑтано мітку, не розрізнÑючи великі й малі літери!"
-#: ../tag.c:909
#, c-format
msgid "E429: File \"%s\" does not exist"
msgstr "E429: Файл «%s» не Ñ–Ñнує"
-# msgstr "E429: "
-#. Highlight title
-#: ../tag.c:960
msgid ""
"\n"
" # TO tag FROM line in file/text"
msgstr ""
"\n"
-" # ДО теґу З Ñ€Ñдка у файлі/текÑті"
+" # ДО мітки З Ñ€Ñдка у файлі/текÑті"
-#: ../tag.c:1303
#, c-format
msgid "Searching tags file %s"
msgstr "ШукаєтьÑÑ Ñƒ файлі теґів %s"
-#: ../tag.c:1545
msgid "Ignoring long line in tags file"
msgstr "ІгноруєтьÑÑ Ð´Ð¾Ð²Ð³Ð¸Ð¹ Ñ€Ñдок у файлі з позначками"
-# msgstr "E430: "
-#: ../tag.c:1915
#, c-format
msgid "E431: Format error in tags file \"%s\""
msgstr "E431: Помилка формату у файлі теґів «%s»"
-# msgstr "E431: "
-#: ../tag.c:1917
#, c-format
msgid "Before byte %<PRId64>"
msgstr "Перед байтом %<PRId64>"
-#: ../tag.c:1929
#, c-format
msgid "E432: Tags file not sorted: %s"
msgstr "E432: Файл теґів не впорÑдкований: %s"
-# msgstr "E432: "
-#. never opened any tags file
-#: ../tag.c:1960
msgid "E433: No tags file"
msgstr "E433: Ðемає файлу теґів"
-# msgstr "E433: "
-#: ../tag.c:2536
msgid "E434: Can't find tag pattern"
-msgstr "E434: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ зразок теґу"
+msgstr "E434: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ зразок мітки"
-# msgstr "E434: "
-#: ../tag.c:2544
msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ теґ, тільки припущеннÑ!"
+msgstr "E435: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ мітку, тільки припущеннÑ!"
-#: ../tag.c:2797
#, c-format
msgid "Duplicate field name: %s"
msgstr "Ðазва Ð¿Ð¾Ð»Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÑŽÑ”Ñ‚ÑŒÑÑ: %s"
-# msgstr "E435: "
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' не відомий. Вбудовані термінали:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "початково '"
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл можливоÑтей терміналів"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: Ðемає інформації про термінал"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: Ðемає інформації про можливоÑті терміналу"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: Ðемає запиÑу «%s» про можливоÑті терміналу"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: Потрібна можливіÑть терміналу «cm»"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Клавіші терміналу ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: Помилка Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð²Ð²Ð¾Ð´Ñƒ, робота завершуєтьÑÑ...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: КількіÑть Ñ€Ñдків неÑподівано змінилаÑÑ"
+msgstr "E881: КількіÑть Ñ€Ñдків неÑподівано змінилаÑÑ"
-#: ../undo.c:627
#, c-format
msgid "E828: Cannot open undo file for writing: %s"
msgstr "E828: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл Ñ–Ñторії Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу: %s"
-#: ../undo.c:717
+#, c-format
+msgid "E5003: Unable to create directory \"%s\" for undo file: %s"
+msgstr "E5003: Ðе вдалоÑÑ Ñтворити каталог «%s» Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñƒ Ð¿Ð¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½: %s"
+
#, c-format
msgid "E825: Corrupted undo file (%s): %s"
msgstr "E825: Файл Ñ–Ñторії пошкоджено (%s): %s"
-#: ../undo.c:1039
msgid "Cannot write undo file in any directory in 'undodir'"
msgstr "Ðе вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати файл Ñ–Ñторії у жодну з директорій у 'undodir'"
-#: ../undo.c:1074
#, c-format
msgid "Will not overwrite with undo file, cannot read: %s"
msgstr "Will not overwrite with undo file, cannot read: %s"
-#: ../undo.c:1092
#, c-format
msgid "Will not overwrite, this is not an undo file: %s"
msgstr "Ðе можна перезапиÑати, це не файл Ñ–Ñторії: %s"
-#: ../undo.c:1108
msgid "Skipping undo file write, nothing to undo"
msgstr "Файл Ñ–Ñторії не запиÑуєтьÑÑ, нічого повертати"
-#: ../undo.c:1121
#, c-format
msgid "Writing undo file: %s"
msgstr "ЗапиÑуєтьÑÑ Ñ„Ð°Ð¹Ð» Ñ–Ñторії: %s"
-#: ../undo.c:1213
#, c-format
msgid "E829: write error in undo file: %s"
msgstr "E829: Помилка запиÑу у файлі Ñ–Ñторії: %s"
-#: ../undo.c:1280
#, c-format
msgid "Not reading undo file, owner differs: %s"
msgstr "Файл Ñ–Ñторії прочитано не буде, влаÑник інший: %s"
-#: ../undo.c:1292
#, c-format
msgid "Reading undo file: %s"
msgstr "ЧитаєтьÑÑ Ñ„Ð°Ð¹Ð» Ñ–Ñторії: %s"
-#: ../undo.c:1299
#, c-format
msgid "E822: Cannot open undo file for reading: %s"
msgstr "E822: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ: %s"
-# msgstr "E333: "
-#: ../undo.c:1308
#, c-format
msgid "E823: Not an undo file: %s"
msgstr "E823: Ðе файл Ñ–Ñторії: %s"
-#: ../undo.c:1313
#, c-format
msgid "E824: Incompatible undo file: %s"
msgstr "E824: ÐеÑуміÑний файл Ñ–Ñторії: %s"
-#: ../undo.c:1328
msgid "File contents changed, cannot use undo info"
msgstr "ВміÑÑ‚ файлу змінивÑÑ, не можна викориÑтати інформацію про Ñ–Ñторію"
-#: ../undo.c:1497
#, c-format
msgid "Finished reading undo file %s"
msgstr "Закінчено Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ Ñ–Ñторії %s"
-#: ../undo.c:1586 ../undo.c:1812
msgid "Already at oldest change"
msgstr "Вже на найÑтаршій зміні"
-#: ../undo.c:1597 ../undo.c:1814
msgid "Already at newest change"
msgstr "Вже на найновішій зміні"
-#: ../undo.c:1806
#, c-format
msgid "E830: Undo number %<PRId64> not found"
msgstr "E830: Зміну %<PRId64> не знайдено в Ñ–Ñторії"
-#: ../undo.c:1979
msgid "E438: u_undo: line numbers wrong"
msgstr "E438: u_undo: неправильні номери Ñ€Ñдків"
-#: ../undo.c:2183
msgid "more line"
msgstr "додано Ñ€Ñдок"
-#: ../undo.c:2185
msgid "more lines"
msgstr "Ñ€Ñдків додано"
-#: ../undo.c:2187
msgid "line less"
msgstr "знищено Ñ€Ñдок"
-#: ../undo.c:2189
msgid "fewer lines"
msgstr "Ñ€Ñдків знищено"
-# msgstr "E438: "
-#: ../undo.c:2193
msgid "change"
msgstr "зміна"
-# msgstr "E438: "
-#: ../undo.c:2195
msgid "changes"
msgstr "змін"
-#: ../undo.c:2225
#, c-format
msgid "%<PRId64> %s; %s #%<PRId64> %s"
msgstr "%<PRId64> %s; %s #%<PRId64> %s"
-#: ../undo.c:2228
-msgid "before"
-msgstr "перед"
-
-#: ../undo.c:2228
msgid "after"
msgstr "піÑлÑ"
-#: ../undo.c:2325
+msgid "before"
+msgstr "перед"
+
msgid "Nothing to undo"
msgstr "Ðемає нічого ÑкаÑовувати"
-#: ../undo.c:2330
msgid "number changes when saved"
msgstr "номер зміни Ñ‡Ð°Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð¾"
-#: ../undo.c:2360
#, c-format
msgid "%<PRId64> seconds ago"
msgstr "%<PRId64> Ñекунд тому"
-# msgstr "E406: "
-#: ../undo.c:2372
msgid "E790: undojoin is not allowed after undo"
msgstr "E790: Ðе можна виконати undojoin піÑÐ»Ñ undo"
-#: ../undo.c:2466
msgid "E439: undo list corrupt"
msgstr "E439: СпиÑок ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾ÑˆÐºÐ¾Ð´Ð¶ÐµÐ½Ð¾"
-# msgstr "E439: "
-#: ../undo.c:2495
msgid "E440: undo line missing"
msgstr "E440: ВідÑутній Ñ€Ñдок ÑкаÑуваннÑ"
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"Включені латки: "
-
-#: ../version.c:627
-msgid ""
-"\n"
-"Extra patches: "
-msgstr ""
-"\n"
-"Додаткові латки: "
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "Змінив "
-
-#: ../version.c:646
msgid ""
"\n"
"Compiled "
@@ -6456,1933 +5473,280 @@ msgstr ""
"\n"
"Скомпілював "
-#: ../version.c:649
msgid "by "
msgstr " "
-#: ../version.c:660
msgid ""
"\n"
-"Huge version "
+"\n"
+"Features: "
msgstr ""
"\n"
-"ГігантÑька верÑÑ–Ñ "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "без GUI."
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " Включені (+) або не включені (-) компоненти:\n"
+"\n"
+"ХарактериÑтики: "
-#: ../version.c:667
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
msgid " fall-back for $VIM: \""
msgstr " заміна Ð´Ð»Ñ $VIM: \""
-#: ../version.c:705
msgid " f-b for $VIMRUNTIME: \""
msgstr " заміна Ð´Ð»Ñ $VIMRUNTIME: \""
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "Скомпільовано: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Скомпоновано: "
+msgid "Nvim is open source and freely distributable"
+msgstr "Nvim — це відкрита й вільно розповÑюджувана програма"
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " ВЕРСІЯ ДЛЯ ÐÐЛÐГОДЖЕÐÐЯ"
+msgid "https://neovim.io/#chat"
+msgstr "https://neovim.io/#chat"
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Покращений Vi"
+msgid "type :help nvim<Enter> if you are new! "
+msgstr ":help nvim<Enter> Ñкщо ви вперше! "
-#: ../version.c:769
-msgid "version "
-msgstr "верÑÑ–Ñ "
+msgid "type :checkhealth<Enter> to optimize Nvim"
+msgstr ":checkhealth<Enter> щоб оптимізувати Nvim "
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "автор: Bram Moolenaar та ін."
+msgid "type :q<Enter> to exit "
+msgstr ":q<Enter> вихід з Vim "
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim — це відкрита й вільно розповÑюджувана програма"
+msgid "type :help<Enter> for help "
+msgstr ":help<Enter> щоб отримати допомогу "
-#: ../version.c:776
msgid "Help poor children in Uganda!"
msgstr "Допоможіть Ñиротам з Уганди!"
-#: ../version.c:777
msgid "type :help iccf<Enter> for information "
-msgstr ":help iccf<Enter> подробиці "
-
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr ":q<Enter> вихід з Vim "
+msgstr ":help iccf<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> режим неÑуміÑний з Vi "
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr ":help cp-default<Enter> Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ ÑуміÑніÑть"
-
-#: ../version.c:827
msgid "Sponsor Vim development!"
msgstr "Підтримайте розробку редактора Vim!"
-#: ../version.c:828
msgid "Become a registered Vim user!"
msgstr "Станьте зареєÑтрованим кориÑтувачем Vim!"
-#: ../version.c:831
msgid "type :help sponsor<Enter> for information "
-msgstr ":help sponsor<Enter> подальша Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ "
+msgstr ":help sponsor<Enter> подальша Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ "
-#: ../version.c:832
msgid "type :help register<Enter> for information "
-msgstr ":help register<Enter> подальша Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ "
+msgstr ":help register<Enter> подальша Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ "
-#: ../version.c:834
msgid "menu Help->Sponsor/Register for information "
-msgstr "меню Допомога->СпонÑор/РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†Ñ– "
-
-# msgstr "E444: "
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "Це вже єдине вікно"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: Ðемає вікна переглÑду"
-
-# msgstr "E441: "
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: Ðе вдалоÑÑ Ð¾Ð´Ð½Ð¾Ñ‡Ð°Ñно розбити topleft Ñ– botright"
-
-# msgstr "E442: "
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити вікно, заважають інші"
-
-# msgstr "E443: "
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ оÑтаннє вікно"
-
-# msgstr "E443: "
-#: ../window.c:1810
-msgid "E813: Cannot close autocmd window"
-msgstr "E813: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ вікно autocmd"
-
-# msgstr "E443: "
-#: ../window.c:1814
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E814: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ вікно, залишилоÑÑ Ð± тільки вікно autocmd"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: У іншому вікні є зміни"
-
-# msgstr "E445: "
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: Ðемає назви файлу над курÑором"
-
-#~ msgid "E831: bf_key_init() called with empty password"
-#~ msgstr "E831: Викликано bf_key_init() з порожнім паролем"
-
-#~ msgid "E820: sizeof(uint32_t) != 4"
-#~ msgstr "E820: sizeof(uint32_t) != 4"
-
-#~ msgid "E817: Blowfish big/little endian use wrong"
-#~ msgstr "E817: Ðеправильне викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ€Ñдку байтів Blowfish (BE/LE)"
-
-#~ msgid "E818: sha256 test failed"
-#~ msgstr "E818: Ðе пройшла перевірка sha256"
-
-#~ msgid "E819: Blowfish test failed"
-#~ msgstr "E819: Ðе пройшла перевірка Blowfish"
-
-#~ msgid "Patch file"
-#~ msgstr "Латка"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "&O:Гаразд\n"
-#~ "&C:СкаÑувати"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: Ðемає з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ñ–Ð· Ñервером Vim"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: Ðе вдалоÑÑ Ð²Ñ–Ð´Ñ–Ñлати до %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ відповідь Ñервера"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: Ðе вдалоÑÑ Ð½Ð°Ð´Ñ–Ñлати клієнту"
-
-#~ msgid "Save As"
-#~ msgstr "Зберегти Ñк"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Прочитати Ñкрипт Vim"
-
-#~ msgid "Edit File"
-#~ msgstr "Редагувати Файл"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (ÐЕ ЗÐÐЙДЕÐО)"
-
-#~ msgid "unknown"
-#~ msgstr "Ðевідомо"
-
-# msgstr "E185: "
-#~ msgid "Edit File in new window"
-#~ msgstr "Редагувати файл у новому вікні"
-
-#~ msgid "Append File"
-#~ msgstr "ДопиÑати файл"
-
-# msgstr "E187: "
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "ÐŸÐ¾Ð·Ð¸Ñ†Ñ–Ñ Ð²Ñ–ÐºÐ½Ð°: X %d, Y %d"
-
-# msgstr "E188: "
-#~ msgid "Save Redirection"
-#~ msgstr "Зберегти переадреÑований вивід"
-
-#~ msgid "Save View"
-#~ msgstr "Зберегти виглÑд"
-
-#~ msgid "Save Session"
-#~ msgstr "Зберегти ÑеанÑ"
-
-#~ msgid "Save Setup"
-#~ msgstr "Зберегти налаштуваннÑ"
-
-#~ msgid "E809: #< is not available without the +eval feature"
-#~ msgstr "E809: #< не доÑтупна без можливоÑті +eval"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: У цій верÑÑ–Ñ— немає диграфів"
-
-#~ msgid "is a device (disabled with 'opendevice' option)"
-#~ msgstr "Ñ” приÑтроєм (вимкнено опцією 'opendevice')"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "ЧитаєтьÑÑ Ð· stdin..."
-
-#~ msgid "[blowfish]"
-#~ msgstr "[blowfish]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[зашифровано]"
-
-#~ msgid "E821: File is encrypted with unknown method"
-#~ msgstr "E821: Файл зашифровано невідомим методом"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans не дозволÑÑ” запиÑувати у незмінені буфери"
-
-# msgstr "E391: "
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "ЧаÑткові запиÑи заборонені Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ñ–Ð² NetBeans"
-
-#~ msgid "writing to device disabled with 'opendevice' option"
-#~ msgstr "Ð—Ð°Ð¿Ð¸Ñ Ð´Ð¾ приÑтрою заборонено опцією 'opendevice'"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Гілку реÑурÑів можна втратити (! щоб не зважати)"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<не відкриваєтьÑÑ> "
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ шрифт %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: не вдалоÑÑ Ð¿Ð¾Ð²ÐµÑ€Ð½ÑƒÑ‚Ð¸ÑÑ Ð² поточний каталог"
-
-#~ msgid "Pathname:"
-#~ msgstr "ШлÑÑ…:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ поточний каталог"
-
-#~ msgid "OK"
-#~ msgstr "Гаразд"
-
-#~ msgid "Cancel"
-#~ msgstr "СкаÑувати"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Діалог Vim"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "Scrollbar Widget: Ðе вдалоÑÑ Ð²Ð¸Ð·Ð½Ð°Ñ‡Ð¸Ñ‚Ð¸ розмір Ñкороченої картинки."
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: Ðе вдалоÑÑ Ñтворити BalloonEval з повідомленнÑм Ñ– функцією"
-
-#~ msgid "E851: Failed to create a new process for the GUI"
-#~ msgstr "E851: Ðе вдалоÑÑ Ñтворити новий Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð´Ð»Ñ GUI"
-
-#~ msgid "E852: The child process failed to start the GUI"
-#~ msgstr "E852: Дочірній Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð½Ðµ зміг запуÑтити GUI"
-
-# msgstr "E228: "
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити GUI"
-
-# msgstr "E229: "
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: Ðе вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ з «%s»"
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити GUI, не знайдено шрифт"
-
-# msgstr "E230: "
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: Ðекоректний 'guifontwide'"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ 'imactivatekey' некоректне"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ колір %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "Ðемає над курÑором, пошук триває"
-
-#~ msgid "Input _Methods"
-#~ msgstr "Методи введеннÑ"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - Знайти й замінити..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - Пошук..."
-
-#~ msgid "Find what:"
-#~ msgstr "Знайти:"
-
-#~ msgid "Replace with:"
-#~ msgstr "Замінити на:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Лише повне Ñлово"
-
-#~ msgid "Match case"
-#~ msgstr "Зважати на регіÑтр"
-
-#~ msgid "Direction"
-#~ msgstr "ÐапрÑм"
-
-#~ msgid "Up"
-#~ msgstr "Вгору"
-
-#~ msgid "Down"
-#~ msgstr "Униз"
-
-#~ msgid "Find Next"
-#~ msgstr "ÐаÑтупне"
-
-#~ msgid "Replace"
-#~ msgstr "Замінити"
-
-#~ msgid "Replace All"
-#~ msgstr "Замінити уÑÑ–"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: Отримав запит «die» від менеджера ÑеÑій\n"
-
-#~ msgid "Close"
-#~ msgstr "Закрити"
-
-#~ msgid "New tab"
-#~ msgstr "Ðова вкладка"
-
-#~ msgid "Open Tab..."
-#~ msgstr "Відкрити вкладку..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: ÐеÑподівано знищилоÑÑ Ð³Ð¾Ð»Ð¾Ð²Ð½Ðµ вікно\n"
-
-#~ msgid "&Filter"
-#~ msgstr "&F:Фільтрувати"
-
-#~ msgid "&Cancel"
-#~ msgstr "&C:СкаÑувати"
-
-#~ msgid "Directories"
-#~ msgstr "Каталоги"
-
-#~ msgid "Filter"
-#~ msgstr "Фільтр"
-
-#~ msgid "&Help"
-#~ msgstr "&H:Допомога"
-
-#~ msgid "Files"
-#~ msgstr "Файли"
-
-#~ msgid "&OK"
-#~ msgstr "&O:Гаразд"
-
-#~ msgid "Selection"
-#~ msgstr "ВиділеннÑ"
-
-#~ msgid "Find &Next"
-#~ msgstr "&N:Знайти далі"
-
-#~ msgid "&Replace"
-#~ msgstr "&R:Замінити"
-
-#~ msgid "Replace &All"
-#~ msgstr "&A:Замінити уÑÑ–"
-
-#~ msgid "&Undo"
-#~ msgstr "&U:СкаÑувати"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ вікно «%s»"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: Ðргумент не підтримуєтьÑÑ: «-%s»; кориÑтуйтеÑÑŒ верÑією з OLE."
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ вікно вÑередині програми MDI"
-
-#~ msgid "Close tab"
-#~ msgstr "Закрити вкладку"
-
-#~ msgid "Open tab..."
-#~ msgstr "Відкрити вкладку..."
-
-# msgstr "E245: "
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "Знайти Ñ€Ñдок ('\\\\' щоб знайти '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "Знайти і замінити ('\\\\' щоб знайти '\\')"
+msgstr "меню Допомога->СпонÑор/РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð¸Ñ†Ñ– "
-#~ msgid "Not Used"
-#~ msgstr "Ðемає"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Каталог\t*.нічого\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr ""
-#~ "Vim E458: Ðемає вільних комірок у палітрі, деÑкі кольори можуть бути "
-#~ "неправильні"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Шрифти Ð´Ð»Ñ Ñ†Ð¸Ñ… Ñимволів відÑутні у наборі %s:"
-
-# msgstr "E250: "
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Ðазва набору шрифтів: %s"
-
-# msgstr "E252: "
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "Шрифт '%s' не є моноширинним"
-
-#~ msgid "E253: Fontset name: %s"
-#~ msgstr "E253: Ðазва набору шрифтів: %s"
-
-#~ msgid "Font0: %s"
-#~ msgstr "Шрифт0: %s"
-
-#~ msgid "Font1: %s"
-#~ msgstr "Шрифт1: %s"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0"
-#~ msgstr "Ширина шрифту%<PRId64> не більша удвічі за ширину шрифту0"
-
-#~ msgid "Font0 width: %<PRId64>"
-#~ msgstr "Ширина шрифту0: %<PRId64>"
-
-#~ msgid "Font1 width: %<PRId64>"
-#~ msgstr "Ширина шрифту1: %<PRId64>"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Ðекоректна ÑÐ¿ÐµÑ†Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ ÑˆÑ€Ð¸Ñ„Ñ‚Ñƒ"
-
-#~ msgid "&Dismiss"
-#~ msgstr "&D:Припинити"
-
-#~ msgid "no specific match"
-#~ msgstr "немає конкретного збігу"
-
-# msgstr "E234: "
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - Вибір шрифту"
-
-#~ msgid "Name:"
-#~ msgstr "Ðазва:"
-
-#~ msgid "Show size in Points"
-#~ msgstr "Показати розмір у пунктах"
-
-#~ msgid "Encoding:"
-#~ msgstr "КодуваннÑ:"
-
-#~ msgid "Font:"
-#~ msgstr "Шрифт:"
-
-#~ msgid "Style:"
-#~ msgstr "Стиль:"
-
-#~ msgid "Size:"
-#~ msgstr "Розмір:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Помилка автомату Hangul"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: помилка stat"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ базу даних cscope: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ інформацію з бази даних cscope"
-
-#~ msgid "Lua library cannot be loaded."
-#~ msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ бібліотеку Lua"
-
-#~ msgid "cannot save undo information"
-#~ msgstr "не вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ інформацію Ð´Ð»Ñ ÑкаÑуваннÑ"
-
-#~ msgid ""
-#~ "E815: Sorry, this command is disabled, the MzScheme libraries could not "
-#~ "be loaded."
-#~ msgstr ""
-#~ "E815: Вибачте, Ñ†Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° вимкнена, бібліотеки MzScheme не можуть бути "
-#~ "завантажені."
-
-#~ msgid "invalid expression"
-#~ msgstr "некоректний вираз"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "обробку виразів вимкнено під Ñ‡Ð°Ñ ÐºÐ¾Ð¼Ð¿Ñ–Ð»Ñції"
-
-#~ msgid "hidden option"
-#~ msgstr "прихована опціÑ"
-
-#~ msgid "unknown option"
-#~ msgstr "невідома опціÑ"
-
-#~ msgid "window index is out of range"
-#~ msgstr "некоректний номер вікна"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "не вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ буфер"
-
-#~ msgid "cannot delete line"
-#~ msgstr "неможливо знищити Ñ€Ñдок"
-
-#~ msgid "cannot replace line"
-#~ msgstr "неможливо замінити Ñ€Ñдок"
-
-#~ msgid "cannot insert line"
-#~ msgstr "не вдалоÑÑ Ð²Ñтавити Ñ€Ñдок"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "більше ніж один Ñ€Ñдок"
-
-#~ msgid "error converting Scheme values to Vim"
-#~ msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Scheme у Vim"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Помилка Vim: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Помилка Vim"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "буфер непридатний"
-
-#~ msgid "window is invalid"
-#~ msgstr "вікно непридатне"
-
-#~ msgid "linenr out of range"
-#~ msgstr "номер Ñ€Ñдка за межами файлу"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "не дозволено у піÑочниці Vim"
-
-#~ msgid "E837: This Vim cannot execute :py3 after using :python"
-#~ msgstr "E837: Python: Ðе можна викориÑтати :py Ñ– :py3 в одному ÑеанÑÑ–"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E263: Вибачте, Ñ†Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° вимкнена, бібліотека Python не може бути "
-#~ "завантажена."
-
-#~ msgid "E836: This Vim cannot execute :python after using :py3"
-#~ msgstr "E836: Python: Ðе можна викориÑтати :py Ñ– :py3 в одному ÑеанÑÑ–"
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: Ðе можна рекурÑивно викликати Python"
-
-#~ msgid "E265: $_ must be an instance of String"
-#~ msgstr "E265: $_ має бути екземплÑром String"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr ""
-#~ "E266: Вибачте, Ñ†Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° вимкнена, бібліотека Ruby не може бути "
-#~ "завантажена."
-
-# msgstr "E414: "
-#~ msgid "E267: unexpected return"
-#~ msgstr "E267: неÑподіваний return"
-
-#~ msgid "E268: unexpected next"
-#~ msgstr "E268: неÑподіваний next"
-
-#~ msgid "E269: unexpected break"
-#~ msgstr "E269: неÑподіваний break"
-
-#~ msgid "E270: unexpected redo"
-#~ msgstr "E270: неÑподіваний redo"
-
-#~ msgid "E271: retry outside of rescue clause"
-#~ msgstr "E271: retry поза rescue"
-
-#~ msgid "E272: unhandled exception"
-#~ msgstr "E272: Ðеоброблений винÑток"
-
-# msgstr "E233: "
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: Ðевідомий ÑÑ‚Ð°Ñ‚ÑƒÑ longjmp: %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Перемкнути реалізацію/визначеннÑ"
-
-#~ msgid "Show base class of"
-#~ msgstr "Знайти базовий клаÑ"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Показати замінені функції-члени"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Прочитати з файлу"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Отримати з проекту"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Отримати з уÑÑ–Ñ… проектів"
-
-#~ msgid "Retrieve"
-#~ msgstr "Отримати"
-
-#~ msgid "Show source of"
-#~ msgstr "Джерело"
-
-#~ msgid "Find symbol"
-#~ msgstr "Знайти Ñимвол"
-
-#~ msgid "Browse class"
-#~ msgstr "ПереглÑнути клаÑ"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Показати ÐºÐ»Ð°Ñ Ð² ієрархії"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Показати ÐºÐ»Ð°Ñ Ð² обмеженій ієрархії"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref вказує на"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Ðа Xref вказано з"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref має"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref викориÑтано"
-
-#~ msgid "Show docu of"
-#~ msgstr "Показати docu"
-
-#~ msgid "Generate docu for"
-#~ msgstr "Створити docu длÑ"
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "Ðе вдалоÑÑ Ð·'єднатиÑÑ Ð·Ñ– SNiFF+. Перевірте Ð¾Ñ‚Ð¾Ñ‡ÐµÐ½Ð½Ñ (sniffemacs має бути "
-#~ "у $PATH).\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Помилка під Ñ‡Ð°Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ. Від'єднано"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ зараз "
-
-#~ msgid "not "
-#~ msgstr "не "
-
-#~ msgid "connected"
-#~ msgstr "під'єднаний"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: Ðевідомий запит до SNiFF+: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Помилка з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ SNiFF+"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: SNiFF+ не під'єднано"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: Ðе Ñ” буфером SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: Помилка запиÑу. Від'єднано"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "неправильна назва буфера"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ще не реалізовано"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "не вдалоÑÑ Ð²Ñтановити Ñ€Ñдки"
-
-#~ msgid "invalid mark name"
-#~ msgstr "неправильна назва позначки"
-
-# msgstr "E19: "
-#~ msgid "mark not set"
-#~ msgstr "помітку не вказано"
-
-#~ msgid "row %d column %d"
-#~ msgstr "Ñ€Ñдок %d колонка %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "Ðе вдалоÑÑ Ð²Ñтавити/додати Ñ€Ñдок"
-
-#~ msgid "line number out of range"
-#~ msgstr "номер Ñ€Ñдка за межами файлу"
-
-#~ msgid "unknown flag: "
-#~ msgstr "невідомий прапорець: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "Ðевідома vimOption"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "перервано з клавіатури"
-
-#~ msgid "vim error"
-#~ msgstr "помилка Vim"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "не вдалоÑÑ Ñтворити команду вікна/буфера: об'єкт знищуєтьÑÑ"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "Ðе вдалоÑÑ Ð·Ð°Ñ€ÐµÑ”Ñтрувати подію: буфер/вікно уже знищуєтьÑÑ"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr ""
-#~ "E280: ФÐТÐЛЬÐРПОМИЛКРTCL: можливо пошкоджено ÑпиÑок поÑилань!? Будь "
-#~ "лаÑка, повідомте у vim-dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr ""
-#~ "Ðе вдалоÑÑ Ð·Ð°Ñ€ÐµÑ”Ñтрувати команду події: поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° буфер/вікно не "
-#~ "знайдено"
-
-#~ 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 "cannot get line"
-#~ msgstr "не вдалоÑÑ Ð´Ñ–Ñтати Ñ€Ñдок"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "Ðе вдалоÑÑ Ð·Ð°Ñ€ÐµÑ”Ñтрувати назву Ñервера команд"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: Ðе вдалоÑÑ Ð²Ñ–Ð´Ñ–Ñлати команду до програми-цілі"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: ВикориÑтано некоректний ідентифікатор Ñервера: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr ""
-#~ "E251: Реквізит реєÑтру зразку VIM Ñформований неправильно. Знищено!"
-
-#~ msgid "netbeans is not supported with this GUI\n"
-#~ msgstr "netbeans не підтримуєтьÑÑ Ð· цим GUI\n"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "Ð¦Ñ Ð²ÐµÑ€ÑÑ–Ñ Vim не була Ñкомпільована з підтримкою порівнÑннÑ."
-
-#~ msgid "'-nb' cannot be used: not enabled at compile time\n"
-#~ msgstr "Ðе можна викориÑтати '-nb': не дозволено під Ñ‡Ð°Ñ ÐºÐ¾Ð¼Ð¿Ñ–Ð»Ñції\n"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: Помилка: Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити gvim Ð´Ð»Ñ NetBeans\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Where case is ignored prepend / to make flag upper case"
-#~ msgstr ""
-#~ "\n"
-#~ "Якщо регіÑтр ігноруєтьÑÑ, додайте / Ñпереду щоб прапорець був у верхньому "
-#~ "регіÑтрі."
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tЗареєÑтрувати цей gvim Ð´Ð»Ñ OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tСкаÑувати реєÑтрацію цього gvim Ð´Ð»Ñ OLE"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tЗапуÑтити GUI (ніби «gvim»)"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f чи --nofork\tПередній план: тримати термінал піÑÐ»Ñ Ð·Ð°Ð¿ÑƒÑку GUI"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\tÐе викориÑтовувати newcli Ð´Ð»Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð²Ñ–ÐºÐ½Ð°"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <приÑтрій>\t\t\tВикориÑтовувати <приÑтрій> Ð´Ð»Ñ Ð²Ð²Ð¾Ð´Ñƒ/виводу"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-u <gvimrc>\t\tВикориÑтати поданий файл заміÑть .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\tРедагувати зашифровані файли"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <диÑплей>\tПід'єднати vim до заданого диÑплею Ñервера X"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\tÐе з'єднуватиÑÑ Ð· X Ñервером"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr ""
-#~ "--remote <файли>\tРедагувати <файли> на Ñервері Vim, Ñкщо це можливо"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-silent <файли> Те Ñаме, тільки не ÑкаржитиÑÑ Ð½Ð° відÑутніÑть "
-#~ "Ñервера"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr ""
-#~ "--remote-wait <файли> ..., але зачекати поки уÑÑ– файли будуть "
-#~ "відредаговані"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr ""
-#~ "--remote-wait-silent <файли> Те Ñаме, тільки не ÑкаржитиÑÑ, Ñкщо Ñервера "
-#~ "немає"
-
-#~ msgid ""
-#~ "--remote-tab[-wait][-silent] <files> As --remote but use tab page per "
-#~ "file"
-#~ msgstr ""
-#~ "--remote-tab[-wait][-silent] <файли> Так Ñамо, Ñк --remote, але по "
-#~ "вкладці на файл"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr ""
-#~ "--remote-send <Ñимволи> ВідіÑлати <Ñимволи> Ñерверу Ñ– завершити роботу"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr ""
-#~ "--remote-expr <вираз> Виконати <вираз> у Ñервері Vim Ñ– надрукувати "
-#~ "результат"
-
-#~ 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 <назва>\tÐадіÑлати до/Ñтати Vim Ñервером з <назвою>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ðргументи Ð´Ð»Ñ gvim (верÑÑ–Ñ Motif)\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ðргументи Ð´Ð»Ñ gvim (верÑÑ–Ñ neXtaw):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ðргументи Ð´Ð»Ñ gvim (верÑÑ–Ñ Athena)\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <диÑплей>\tВиконати vim на заданому <диÑплеї>"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tЗапуÑтити Vim Ñ– згорнути його вікно"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <колір>\tВикориÑтати <колір> Ð´Ð»Ñ Ñ„Ð¾Ð½Ñƒ (також: -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr ""
-#~ "-foreground <колір>\tВикориÑтати <колір> Ð´Ð»Ñ Ð·Ð²Ð¸Ñ‡Ð°Ð¹Ð½Ð¾Ð³Ð¾ текÑту (також: -"
-#~ "fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr ""
-#~ "-font <шрифт>\tВикориÑтати <шрифт> Ð´Ð»Ñ Ð·Ð²Ð¸Ñ‡Ð°Ð¹Ð½Ð¾Ð³Ð¾ текÑту (також: -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <шрифт>\tВикориÑтати <шрифт> Ð´Ð»Ñ Ð¶Ð¸Ñ€Ð½Ð¾Ð³Ð¾ текÑту"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <шрифт>\tВикориÑтати <шрифт> Ð´Ð»Ñ Ð¿Ð¾Ñ…Ð¸Ð»Ð¾Ð³Ð¾ текÑту"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <геом>\tЗадати розміри й Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ (також: -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <товщ>\tÐ’Ñтановити товщину меж <товщ> (також: -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr ""
-#~ "-scrollbarwidth <товщ> Ð’Ñтановити товщину лінійки зÑуву (також: -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <виÑота>\tÐ’Ñтановити виÑоту меню <виÑота> (також: -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tОбернути кольори (також: -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\tÐе обертати кольори (також: +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <реÑурÑ>\t\tÐ’Ñтановити зазначений реÑурÑ"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ðргументи gvim (верÑÑ–Ñ GTK+)\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <диÑплей>\tВиконати vim на <диÑплеї> (також: --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr ""
-#~ "--role <роль>\tÐ’Ñтановити унікальну роль Ð´Ð»Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— головного вікна"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tВідкрити Vim в іншому елементі інтерфейÑу GTK"
-
-#~ msgid "--echo-wid\t\tMake gvim echo the Window ID on stdout"
-#~ msgstr "--echo-wid\t\tХай gvim надрукує ідентифікатор вікна на stdout"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <заголовок батька>\tВідкрити Vim вÑередині батьківÑького вікна"
-
-#~ msgid "--windowid <HWND>\tOpen Vim inside another win32 widget"
-#~ msgstr "--windowid <HWND>\tВідкрити Vim вÑередині іншого елементу win32"
-
-#~ msgid "No display"
-#~ msgstr "Ðемає диÑплею"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": Ðе вдалоÑÑ Ð²Ñ–Ð´Ñ–Ñлати.\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": Ðе вдалоÑÑ Ð²Ñ–Ð´Ñ–Ñлати. Спроба виконати на міÑці\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "відредаговано %d з %d"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "Ðемає диÑплею: ВідіÑлати вираз не вдалоÑÑ.\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": ВідіÑлати вираз не вдалоÑÑ.\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: Ðекоректна кодова Ñторінка"
-
-#~ msgid "E284: Cannot set IC values"
-#~ msgstr "E284: Ðе вдалоÑÑ Ð²Ñтановити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ‚ÐµÐºÑту вводу"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: Ðе вдалоÑÑ Ñтворити контекÑÑ‚ вводу"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: Ðе вдалоÑÑ Ñтворити метод вводу"
-
-# msgstr "E286: "
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr ""
-#~ "E287: ЗаÑтереженнÑ: Ðе вдалоÑÑ Ð²Ñтановити в методі вводу подію знищеннÑ"
-
-# msgstr "E287: "
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: Метод вводу не підтримує Ñтилі"
-
-# msgstr "E288: "
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: Метод вводу не підтримує відредаговані типи"
-
-#~ msgid "E843: Error while updating swap file crypt"
-#~ msgstr "E843: Помилка Ð¿Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ обміну"
-
-#~ msgid ""
-#~ "E833: %s is encrypted and this version of Vim does not support encryption"
-#~ msgstr "E833: %s зашифровано, а Ñ†Ñ Ð²ÐµÑ€ÑÑ–Ñ Vim не підтримує шифруваннÑ"
-
-#~ msgid "Swap file is encrypted: \"%s\""
-#~ msgstr "Файл обміну зашифрований: «%s»"
-
-#~ msgid ""
-#~ "\n"
-#~ "If you entered a new crypt key but did not write the text file,"
-#~ msgstr ""
-#~ "\n"
-#~ "Якщо ви задали новий ключ шифру, але не запиÑали текÑтовий файл,"
-
-#~ msgid ""
-#~ "\n"
-#~ "enter the new crypt key."
-#~ msgstr ""
-#~ "\n"
-#~ "введіть новий ключ шифру."
-
-#~ msgid ""
-#~ "\n"
-#~ "If you wrote the text file after changing the crypt key press enter"
-#~ msgstr ""
-#~ "\n"
-#~ "Якщо ви запиÑали текÑтовий файл піÑÐ»Ñ Ð·Ð¼Ñ–Ð½Ð¸ ключа шифру, натиÑніть enter"
-
-#~ msgid ""
-#~ "\n"
-#~ "to use the same key for text file and swap file"
-#~ msgstr ""
-#~ "\n"
-#~ "щоб викориÑтати однаковий ключ Ð´Ð»Ñ Ñ‚ÐµÐºÑтового файлу та файлу обміну"
-
-#~ msgid "Using crypt key from swap file for the text file.\n"
-#~ msgstr "Ð”Ð»Ñ Ñ‚ÐµÐºÑтового файлу викориÑтовуєтьÑÑ ÐºÐ»ÑŽÑ‡ шифру з файлу обміну.\n"
-
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [не придатний Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— верÑÑ–Ñ— Vim]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "Відірвати це меню"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Вибрати каталог"
-
-#~ msgid "Save File dialog"
-#~ msgstr "Запам'Ñтати файл"
-
-#~ msgid "Open File dialog"
-#~ msgstr "Відкрити файл"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: Вибачте, але в конÑолі немає діалогу вибору файлу"
-
-#~ msgid "ERROR: "
-#~ msgstr "ПОМИЛКÐ: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[байт] вÑього розм/знищ. %<PRIu64>/%<PRIu64>, викор. %<PRIu64>, макÑ. "
-#~ "%<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[виклики] уÑього re/malloc() - %<PRIu64>, уÑього free() - %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: РÑдок Ñтає занадто довгим"
-
-# msgstr "E340: "
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: Ðеправильний виглÑд миші"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "Вкажіть ключ шифру: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "Повторіть ключ: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Ключі не однакові!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "Ðе вдалоÑÑ Ð·'єднатиÑÑ Ñ–Ð· Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "Ðе вдалоÑÑ Ð·'єднатиÑÑ Ñ–Ð· Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr ""
-#~ "E668: Ðеправильний режим доÑтупу до файлу інформації про з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· "
-#~ "NetBenans: «%s»"
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "читаєтьÑÑ Ð· Ñокета Netbeans"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: Втрачено зв'Ñзок із NetBeans Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° %<PRId64>"
-
-#~ msgid "E838: netbeans is not supported with this GUI"
-#~ msgstr "E838: netbeans не підтримуєтьÑÑ Ð· цим GUI"
-
-#~ msgid "E511: netbeans already connected"
-#~ msgstr "E511: netbeans вже під'єднано"
-
-#~ msgid "E505: %s is read-only (add ! to override)"
-#~ msgstr "E505: %s тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ (! щоб не зважати)"
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: МожливіÑть eval недоÑтупна"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "Звільнено Ñ€Ñдків: %<PRId64>"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: Ðе вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ term в GUI"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: ЗаÑтоÑуйте «:gui» Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑку GUI"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: Ðе можна змінити в GUI GTK+ 2"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: Ðекоректний(Ñ–) шрифт(и)"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: Ðе вдалоÑÑ Ð²Ð¸Ð±Ñ€Ð°Ñ‚Ð¸ набір шрифтів"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: Ðеправильний набір шрифтів"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ñ€Ð¸Ñтати розширений шрифт"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: Ðекоректний розширений шрифт"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: Миша не підтримуєтьÑÑ"
-
-# msgstr "E358: "
-#~ msgid "cannot open "
-#~ msgstr "не вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ "
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ вікно!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "Потрібна Amigados 2.04 або пізніша\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "Потрібно %s верÑÑ–Ñ— %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ NIL:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "Ðе вдалоÑÑ Ñтворити "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim завершує роботу з %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "не можу змінити режим конÑолі ?!\n"
-
-# msgstr "E359: "
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: не конÑоль??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити оболонку з опцією -f"
-
-# msgstr "E360: "
-#~ msgid "Cannot execute "
-#~ msgstr "Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ "
-
-#~ msgid "shell "
-#~ msgstr "оболонку "
-
-#~ msgid " returned\n"
-#~ msgstr " повернуто\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE замалий"
-
-#~ msgid "I/O ERROR"
-#~ msgstr "Помилка вводу/виводу"
-
-#~ msgid "Message"
-#~ msgstr "ПовідомленнÑ"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' не 80, не можна виконувати зовнішні команди"
-
-# msgstr "E364: "
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Ðе вдалоÑÑ Ð²Ð¸Ð±Ñ€Ð°Ñ‚Ð¸ принтер"
-
-#~ msgid "to %s on %s"
-#~ msgstr "на %s з %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: Ðевідомий шрифт принтера: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: Помилка друку: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "ДрукуєтьÑÑ '%s'"
-
-#~ 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 "Opening the X display took %<PRId64> msec"
-#~ msgstr "Ðа Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð´Ð¸Ñплею X пішло %<PRId64> міліÑекунд"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: Помилка X\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "ДиÑплей Ð¥ не пройшов перевірку"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "Сплив Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð´Ð¸Ñплею Ð¥"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити оболонку `sh'\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ðе можна Ñтворити канали\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Ðе вдалоÑÑ Ñ€Ð¾Ð·Ð´Ð²Ð¾Ñ—Ñ‚Ð¸ÑÑ\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Команда закінчила виконаннÑ\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP втратив з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ ICE"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ диÑплей X"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP оброблÑєтьÑÑ Ð·Ð°Ð¿Ð¸Ñ‚ 'збережи Ñебе'"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP відкриваєтьÑÑ Ð·'єднаннÑ"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ÑпоÑÑ‚ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð° з'єднаннÑм з ICE не вдалоÑÑ"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP не вдалоÑÑ SmcOpenConnection: %s"
-
-#~ msgid "At line"
-#~ msgstr "РÑдок:"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ vim32.dll"
-
-#~ msgid "VIM Error"
-#~ msgstr "Помилка VIM"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð¸Ñ‚Ð¸ вказівники на функції DLL!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "оболонка повернула %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: ВиÑвлено подію %s\n"
-
-#~ msgid "close"
-#~ msgstr "close"
-
-#~ msgid "logoff"
-#~ msgstr "logoff"
-
-#~ msgid "shutdown"
-#~ msgstr "shutdown"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: Команду не знайдено"
-
-#~ 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 ""
-#~ "Файл VIMRUN.EXE не знайдено у шлÑху пошуку.\n"
-#~ "Зовнішні команди не будуть призупинені піÑÐ»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ.\n"
-#~ "ГлÑньте :help win32-vimrun щоб отримати подробиці."
-
-#~ msgid "Vim Warning"
-#~ msgstr "ЗаÑÑ‚ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Vim"
-
-# msgstr "E231: "
-#~ msgid "Error file"
-#~ msgstr "Файл помилок"
-
-#~ msgid "E868: Error building NFA with equivalence class!"
-#~ msgstr "E868: Ðе вдалоÑÑ Ð¿Ð¾Ð±ÑƒÐ´ÑƒÐ²Ð°Ñ‚Ð¸ NFA з клаÑом еквівалентноÑті!"
-
-#~ msgid "E878: (NFA) Could not allocate memory for branch traversal!"
-#~ msgstr "E878: (NFA) Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ пам’Ñть Ð´Ð»Ñ Ð¾Ð±Ñ…Ð¾Ð´Ñƒ гілок!"
-
-#~ msgid "Warning: Cannot find word list \"%s_%s.spl\" or \"%s_ascii.spl\""
-#~ msgstr ""
-#~ "ЗаÑтереженнÑ: Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ ÑпиÑок Ñлів «%s_%s.spl» чи «%s_ascii.spl»"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "ÐŸÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñƒ %s не підтримуєтьÑÑ"
-
-#~ msgid "E845: Insufficient memory, word list will be incomplete"
-#~ msgstr "E845: ÐедоÑтатньо пам’Ñті, ÑпиÑок Ñлів буде неповним"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: ШлÑÑ… файлу теґів Ñкорочено до %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "запущено нову оболонку\n"
-
-# msgstr "E242: "
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "ВикориÑтано CUT_BUFFER0 заміÑть порожнього виділеннÑ"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "СкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ неможливе, вÑе одно продовжити"
-
-#~ msgid "E832: Non-encrypted file has encrypted undo file: %s"
-#~ msgstr "E832: Ðезашифрований файл має зашифрований файл Ñ–Ñторії: %s"
-
-#~ msgid "E826: Undo file decryption failed: %s"
-#~ msgstr "E826: Ðе вдалоÑÑ Ñ€Ð¾Ð·ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ñ‚Ð¸ файл Ñ–Ñторії: %s"
-
-#~ msgid "E827: Undo file is encrypted: %s"
-#~ msgstr "E827: Файл Ñ–Ñторії зашифрований: %s"
-
-# msgstr "E440: "
-# ---------------------------------------
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð· GUI Ð´Ð»Ñ 16/32-розрÑдної Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð· GUI Ð´Ð»Ñ 64-розрÑдної MS-Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð· GUI Ð´Ð»Ñ 32-розрÑдної Windows"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " в режимі Win32s"
-
-#~ msgid " with OLE support"
-#~ msgstr " з підтримкою OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 64-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "КонÑольна верÑÑ–Ñ Ð´Ð»Ñ 64-розрÑдної Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "КонÑольна верÑÑ–Ñ Ð´Ð»Ñ 32-розрÑдної Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð´Ð»Ñ 16-розрÑдної Windows"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð´Ð»Ñ 32-розрÑдної MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð´Ð»Ñ 16-розрÑдної MS-DOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð´Ð»Ñ MacOS X (unix)"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð´Ð»Ñ MacOS X"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð´Ð»Ñ MacOS"
-
-#~ msgid ""
-#~ "\n"
-#~ "OpenVMS version"
-#~ msgstr ""
-#~ "\n"
-#~ "ВерÑÑ–Ñ Ð´Ð»Ñ OpenVMS"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "Велика верÑÑ–Ñ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Ðормальна верÑÑ–Ñ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "Мала верÑÑ–Ñ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "Крихітна верÑÑ–Ñ "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "з GUI GTK2-GNOME."
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "з GUI GTK2."
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "з GUI X11-Motif."
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "з GUI X11-neXtaw."
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "з GUI X11-Athena."
-
-#~ msgid "with Photon GUI."
-#~ msgstr "з GUI Photon."
-
-#~ msgid "with GUI."
-#~ msgstr "з GUI."
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "з GUI Carbon."
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "з GUI Cocoa."
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "з (клаÑичним) GUI."
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ÑиÑтемний gvimrc: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " gvimrc кориÑтувача: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "другий gvimrc кориÑтувача: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "третій gvimrc кориÑтувача: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " ÑиÑтемне меню: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "КомпілÑтор: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "меню Help->Orphans подальша Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "Без режимів, текÑÑ‚ що набрано вÑтавлÑєтьÑÑ"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "меню Edit->Global Settings->Toggle Insert Mode "
-
-#~ msgid " for two modes "
-#~ msgstr " Ð´Ð»Ñ Ð´Ð²Ð¾Ñ… режимів "
-
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "меню Edit->Global Settings->Toggle Vi Compatible "
-
-#~ msgid " for Vim defaults "
-#~ msgstr " щоб починати в режимі ÑуміÑноÑті з Vi"
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "ЗÐСТЕРЕЖЕÐÐЯ: Ви кориÑтуєтеÑÑ Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr ":help windows95<Enter> Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ це "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ бібліотеку %s"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr ""
-#~ "Вибачте, Ñ†Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° вимкнена, бібліотека Perl не може бути завантажена."
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr ""
-#~ "E299: ОбчиÑÐ»ÐµÐ½Ð½Ñ Ð²Ð¸Ñ€Ð°Ð·Ñ–Ð² Perl заборонене у піÑочниці без Ð¼Ð¾Ð´ÑƒÐ»Ñ Safe"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Редагувати у (&m)різних Vim"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Редагувати у одному &Vim"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "ПорівнÑти з допомогою Vim"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Редагувати за допомогою &Vim"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Редагувати у вже запущеному Vim - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Редагує вибрані файли з допомогою Vim"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "Помилка ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу, перевірте чи Ñ” gvim у шлÑху пошуку!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "помилка gvimext.dll"
-
-#~ msgid "Path length too long!"
-#~ msgstr "ШлÑÑ… занадто довгий!"
-
-# msgstr "E233: "
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: Ðевідомий набір шрифтів: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: Ðевідомий шрифт: %s"
-
-# msgstr "E235: "
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: Шрифт «%s» не моноширинний"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ бібліотечну функцію %s"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: Ðе можна викориÑтати іврит: Ðе ввімкнено під Ñ‡Ð°Ñ ÐºÐ¾Ð¼Ð¿Ñ–Ð»Ñції\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: Ðе можна викориÑтати фарÑÑ–: Ðе ввімкнено під Ñ‡Ð°Ñ ÐºÐ¾Ð¼Ð¿Ñ–Ð»Ñції\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr ""
-#~ "E800: Ðе можна викориÑтати арабÑьку мову: Ðе ввімкнено під Ñ‡Ð°Ñ "
-#~ "компілÑції\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: Ðемає зареєÑтрованих Ñерверів з назвою «%s»"
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ диÑплей"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: Отримано некоректний вираз"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: Ðе можна змінити захищений регіон"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans не дозволÑÑ” змінювати захищені від запиÑу файли"
-
-#~ msgid "Need encryption key for \"%s\""
-#~ msgstr "Ð”Ð»Ñ Â«%s» потрібен ключ: "
-
-# msgstr "E406: "
-#~ msgid "empty keys are not allowed"
-#~ msgstr "порожні ключі не дозволені"
-
-#~ msgid "dictionary is locked"
-#~ msgstr "Ñловник заблоковано"
-
-#~ msgid "list is locked"
-#~ msgstr "ÑпиÑок заблоковано"
-
-#~ msgid "failed to add key '%s' to dictionary"
-#~ msgstr "не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ ключ '%s' до Ñловника"
-
-#~ msgid "index must be int or slice, not %s"
-#~ msgstr "Ñ–Ð½Ð´ÐµÐºÑ Ð¼Ð°Ñ” бути цілий чи зріз, не %s"
-
-#~ msgid "expected str() or unicode() instance, but got %s"
-#~ msgstr "очікувавÑÑ ÐµÐºÐ·ÐµÐ¼Ð¿Ð»ÑÑ€ str() чи unicode(), але отримано %s"
-
-#~ msgid "expected bytes() or str() instance, but got %s"
-#~ msgstr "очікувавÑÑ ÐµÐºÐ·ÐµÐ¼Ð¿Ð»ÑÑ€ bytes() чи str(), але отримано %s"
-
-#~ msgid ""
-#~ "expected int(), long() or something supporting coercing to long(), but "
-#~ "got %s"
-#~ msgstr ""
-#~ "очікувавÑÑ int(), long() чи щоÑÑŒ, що може бути вміщене long(), але "
-#~ "отримано %s"
-
-#~ msgid "expected int() or something supporting coercing to int(), but got %s"
-#~ msgstr ""
-#~ "очікувавÑÑ int() чи щоÑÑŒ, що може бути вміщене int(), але отримано %s"
+#, c-format
+msgid "E15: Invalid control character present in input: %.*s"
+msgstr "E15: Ðекоректні керівні Ñимволи на вході: %.*s"
-#~ msgid "value is too large to fit into C int type"
-#~ msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð°Ð²ÐµÐ»Ð¸ÐºÐµ, щоб вміÑтитиÑÑ Ñƒ тип C int"
+#, c-format
+msgid "E112: Option name missing: %.*s"
+msgstr "E112: Бракує назви опції: %.*s"
-#~ msgid "value is too small to fit into C int type"
-#~ msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð°Ð¼Ð°Ð»Ðµ, щоб вміÑтитиÑÑ Ñƒ тип C int"
+#, c-format
+msgid "E15: Unexpected EOC character: %.*s"
+msgstr "E15: ÐеÑподіваний Ñимвол EOC: %.*s"
-#~ msgid "number must be greater then zero"
-#~ msgstr "чиÑло має бути більше, ніж нуль"
+#, c-format
+msgid "E15: Unidentified character: %.*s"
+msgstr "E15: Ðерозпізнаний Ñимвол: %.*s"
-#~ msgid "number must be greater or equal to zero"
-#~ msgstr "чиÑло має бути не менше, ніж нуль"
+#, c-format
+msgid "E15: Operator is not associative: %.*s"
+msgstr "E15: Оператор не аÑоціативний: %.*s"
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "не вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ атрибути OutputObject"
+#, c-format
+msgid "E15: Missing operator: %.*s"
+msgstr "E15: Бракує оператора: %.*s"
-# msgstr "E180: "
-#~ msgid "invalid attribute: %s"
-#~ msgstr "неправильний атрибут: %s"
+#, c-format
+msgid "E15: Expected lambda arguments list or arrow: %.*s"
+msgstr "E15: ОчікуєтьÑÑ ÑпиÑок аргументів лÑмбда чи Ñтрілка: %.*s"
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: Помилка ініціалізації об'єктів вводу/виводу"
+#, c-format
+msgid "E15: Expected value part of assignment lvalue: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸ÑÐ²Ð¾Ñ”Ð½Ð½Ñ lvalue: %.*s"
-#~ msgid "failed to change directory"
-#~ msgstr "не вдалоÑÑ Ð·Ð¼Ñ–Ð½Ð¸Ñ‚Ð¸ директорію"
+#, c-format
+msgid "E15: Expected assignment operator or subscript: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€ приÑÐ²Ð¾ÑŽÐ²Ð°Ð½Ð½Ñ Ñ‡Ð¸ індекÑ: %.*s"
-#~ msgid "expected 3-tuple as imp.find_module() result, but got %s"
-#~ msgstr "очікувавÑÑ 3-кортеж Ñк результат imp.find_module(), але отримано %s"
+msgid "E15: Unexpected "
+msgstr "E15: ÐеÑподівано "
-#~ msgid ""
-#~ "expected 3-tuple as imp.find_module() result, but got tuple of size %d"
-#~ msgstr "очікувавÑÑ 3-кортеж Ñк результат imp.find_module(), але отримано %d"
+#, c-format
+msgid "E15: Unexpected multiplication-like operator: %.*s"
+msgstr "E15: ÐеÑподівано оператор на зразок множеннÑ: %.*s"
-#~ msgid "internal error: imp.find_module returned tuple with NULL"
-#~ msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: imp.find_module повернула кортеж з NULL"
+msgid "E15: Environment variable name missing"
+msgstr "E15: Бракує змінної оточеннÑ"
-#~ msgid "cannot delete vim.Dictionary attributes"
-#~ msgstr "не вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ атрибути vim.Dictionary"
+#, c-format
+msgid "E15: Expected value, got comparison operator: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, отримано оператор порівнÑннÑ: %.*s"
-#~ msgid "cannot modify fixed dictionary"
-#~ msgstr "не можна змінити фікÑований Ñловник"
+#, c-format
+msgid "E15: Expected value, got comma: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, отримано кому: %.*s"
-#~ msgid "cannot set attribute %s"
-#~ msgstr "не можна вÑтановити атрибут %s"
+#, c-format
+msgid "E15: Comma outside of call, lambda or literal: %.*s"
+msgstr "E15: Кома поза викликом, лÑмбдою чи літералом: %.*s"
-#~ msgid "hashtab changed during iteration"
-#~ msgstr "хеш-Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ Ð·Ð¼Ñ–Ð½Ð¸Ð»Ð°ÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð¿ÐµÑ€ÐµÐ±Ð¸Ñ€Ð°Ð½Ð½Ñ"
+#, c-format
+msgid "E15: Colon outside of dictionary or ternary operator: %.*s"
+msgstr "E15: Двокрапка поза Ñловником чи тернарним оператором: %.*s"
-#~ msgid "expected sequence element of size 2, but got sequence of size %d"
-#~ msgstr ""
-#~ "очікувалаÑÑŒ поÑлідовніÑть розміром 2, але отримано поÑлідовніÑть розміру "
-#~ "%d"
+#, c-format
+msgid "E15: Expected value, got closing bracket: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, отримано праву дужку: %.*s"
-#~ msgid "list constructor does not accept keyword arguments"
-#~ msgstr "ÑпиÑковий конÑтруктор не приймає іменовані аргументи"
+#, c-format
+msgid "E475: Unable to assign to empty list: %.*s"
+msgstr "E475: Ðе можна приÑвоїти порожній ÑпиÑок: %.*s"
-#~ msgid "list index out of range"
-#~ msgstr "Ñ–Ð½Ð´ÐµÐºÑ ÑпиÑку за межами"
+#, c-format
+msgid "E15: Unexpected closing figure brace: %.*s"
+msgstr "E15: ÐеÑподівано права фігурна дужка: %.*s"
-#~ msgid "internal error: failed to get vim list item %d"
-#~ msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ елемент ÑпиÑку vim %d"
+#, c-format
+msgid "E475: Nested lists not allowed when assigning: %.*s"
+msgstr "E475: Вкладені ÑпиÑки не можна приÑвоювати: %.*s"
-#~ msgid "failed to add item to list"
-#~ msgstr "не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ елемент до ÑпиÑку"
+#, c-format
+msgid "E15: Expected value, got closing figure brace: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, отримано праву фігурну дужку: %.*s"
-#~ msgid "internal error: no vim list item %d"
-#~ msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: немає елемента ÑпиÑку vim %d"
+#, c-format
+msgid "E15: Don't know what figure brace means: %.*s"
+msgstr "E15: Ðе знаю, що означає фігурна дужка: %.*s"
-#~ msgid "internal error: failed to add item to list"
-#~ msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ елемент до ÑпиÑку"
+#, c-format
+msgid "E15: Unexpected arrow: %.*s"
+msgstr "E15: Ðеочікувано Ñтрілка: %.*s"
-#~ msgid "cannot delete vim.List attributes"
-#~ msgstr "не вдалоÑÑ Ð·Ð½Ð¸Ñ‰Ð¸Ñ‚Ð¸ атрибути vim.List"
+#, c-format
+msgid "E15: Arrow outside of lambda: %.*s"
+msgstr "E15: Стрілка поза лÑмбдою: %.*s"
-#~ msgid "cannot modify fixed list"
-#~ msgstr "не можна змінити фікÑований ÑпиÑок"
+#, c-format
+msgid "E15: Unexpected dot: %.*s"
+msgstr "E15: ÐеÑподівано крапка: %.*s"
-# msgstr "E428: "
-#~ msgid "unnamed function %s does not exist"
-#~ msgstr "безіменної функції %s не Ñ–Ñнує"
+#, c-format
+msgid "E15: Cannot concatenate in assignments: %.*s"
+msgstr "E15: Ðе можна Ñклеювати у приÑвоєннÑÑ…: %.*s"
-# msgstr "E428: "
-#~ msgid "function %s does not exist"
-#~ msgstr "функції %s не Ñ–Ñнує"
+#, c-format
+msgid "E15: Expected value, got parenthesis: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, отримано дужки: %.*s"
-#~ msgid "function constructor does not accept keyword arguments"
-#~ msgstr "конÑтруктор функції не приймає іменовані аргументи"
+#, c-format
+msgid "E15: Unexpected closing parenthesis: %.*s"
+msgstr "E15: ÐеÑподівано права дужка: %.*s"
-#~ msgid "failed to run function %s"
-#~ msgstr "не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ функцію %s"
+#, c-format
+msgid "E15: Expected value, got question mark: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, отримано знак питаннÑ: %.*s"
-#~ msgid "problem while switching windows"
-#~ msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼ÐºÐ½ÑƒÑ‚Ð¸ вікна"
+#, c-format
+msgid "E114: Missing double quote: %.*s"
+msgstr "E114: Бракує подвійних лапок: %.*s"
-#~ msgid "unable to unset global option %s"
-#~ msgstr "не вдалоÑÑ Ñкинути глобальну опцію %s"
+#, c-format
+msgid "E115: Missing single quote: %.*s"
+msgstr "E115: Бракує одинарних лапок: %.*s"
-#~ msgid "unable to unset option %s which does not have global value"
-#~ msgstr "не вдалоÑÑ Ñкинути опцію %s, Ñка не має глобального значеннÑ"
+#, c-format
+msgid "E475: Expected closing bracket to end list assignment lvalue: %.*s"
+msgstr ""
+"E475: ОчікуєтьÑÑ Ð¿Ñ€Ð°Ð²Ð° квадратна дужка щоб закінчити приÑÐ²Ð¾Ñ”Ð½Ð½Ñ ÑпиÑку: %.*s"
-#~ msgid "attempt to refer to deleted tab page"
-#~ msgstr "Ñпроба Ð·Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð´Ð¾ знищеної вкладки"
+#, c-format
+msgid "E15: Misplaced assignment: %.*s"
+msgstr "E15: ПриÑÐ²Ð¾Ñ”Ð½Ð½Ñ Ð½Ðµ на міÑці: %.*s"
-#~ msgid "no such tab page"
-#~ msgstr "такої вкладки немає"
+#, c-format
+msgid "E15: Unexpected assignment: %.*s"
+msgstr "E15: ÐеÑподівано приÑвоєннÑ: %.*s"
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "Ñпроба звернутиÑÑ Ð´Ð¾ знищеного вікна"
+#, c-format
+msgid "E15: Expected value, got EOC: %.*s"
+msgstr "E15: ОчікуєтьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, отримано EOC: %.*s"
-#~ msgid "readonly attribute: buffer"
-#~ msgstr "атрибут лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ: буфер"
+#, c-format
+msgid "E116: Missing closing parenthesis for function call: %.*s"
+msgstr "E116: Бракує правої дужки у виклику функції: %.*s"
-#~ msgid "cursor position outside buffer"
-#~ msgstr "курÑор за межами буфера"
+#, c-format
+msgid "E110: Missing closing parenthesis for nested expression: %.*s"
+msgstr "E110: Пропущено праву дужку у вкладеному виразі: %.*s"
-#~ msgid "no such window"
-#~ msgstr "такого вікна немає"
+#, c-format
+msgid "E697: Missing end of List ']': %.*s"
+msgstr "E697: Ðемає кінцівки ÑпиÑку ']': %.*s"
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "Ñпроба Ð·Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð´Ð¾ знищеного буфера"
+#, c-format
+msgid "E723: Missing end of Dictionary '}': %.*s"
+msgstr "E723: Ðемає кінцівки Ñловника '}': %.*s"
-#~ msgid "failed to rename buffer"
-#~ msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ буфер"
+#, c-format
+msgid "E15: Missing closing figure brace: %.*s"
+msgstr "E15: Ðемає правої фігурної дужки: %.*s"
-#~ msgid "mark name must be a single character"
-#~ msgstr "назвою мітки має бути один Ñимвол"
+#, c-format
+msgid "E15: Missing closing figure brace for lambda: %.*s"
+msgstr "E15: Бракує правої фігурної дужки у лÑмбді: %.*s"
-#~ msgid "expected vim.Buffer object, but got %s"
-#~ msgstr "очікувавÑÑ Ð¾Ð±â€™Ñ”ÐºÑ‚ vim.Buffer, але отримано %s"
+#, c-format
+msgid "E109: Missing ':' after '?': %.*s"
+msgstr "E109: Бракує ':' піÑÐ»Ñ '?': %.*s"
-#~ msgid "failed to switch to buffer %d"
-#~ msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼ÐºÐ½ÑƒÑ‚Ð¸ÑÑ Ð´Ð¾ буфера %d"
+msgid "Already only one window"
+msgstr "Це вже єдине вікно"
-#~ msgid "expected vim.Window object, but got %s"
-#~ msgstr "очікувавÑÑ Ð¾Ð±â€™Ñ”ÐºÑ‚ vim.Window, але отримано %s"
+msgid "E441: There is no preview window"
+msgstr "E441: Ðемає вікна переглÑду"
-#~ msgid "failed to find window in the current tab page"
-#~ msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ вікно у поточній вкладці"
+msgid "E442: Can't split topleft and botright at the same time"
+msgstr "E442: Ðе вдалоÑÑ Ð¾Ð´Ð½Ð¾Ñ‡Ð°Ñно розбити topleft Ñ– botright"
-#~ msgid "did not switch to the specified window"
-#~ msgstr "не перемкнувÑÑ Ð´Ð¾ вказаного вікна"
+msgid "E443: Cannot rotate when another window is split"
+msgstr "E443: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñтити вікно, заважають інші"
-#~ msgid "expected vim.TabPage object, but got %s"
-#~ msgstr "очікувавÑÑ Ð¾Ð±â€™Ñ”ÐºÑ‚ vim.TabPage, але отримано %s"
+msgid "E444: Cannot close last window"
+msgstr "E444: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ оÑтаннє вікно"
-#~ msgid "did not switch to the specified tab page"
-#~ msgstr "не перемкнувÑÑ Ð´Ð¾ вказаної вкладки"
+msgid "E813: Cannot close autocmd window"
+msgstr "E813: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ вікно autocmd"
-#~ msgid "failed to run the code"
-#~ msgstr "не вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ код"
+msgid "E814: Cannot close window, only autocmd window would remain"
+msgstr "E814: Ðе вдалоÑÑ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¸ вікно, залишилоÑÑ Ð± тільки вікно autocmd"
-#~ msgid "E858: Eval did not return a valid python object"
-#~ msgstr "E858: Eval не повернув дійÑний об’єкт python"
+msgid "E445: Other window contains changes"
+msgstr "E445: У іншому вікні є зміни"
-#~ msgid "E859: Failed to convert returned python object to vim value"
-#~ msgstr "E859: Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ об’єкт python у Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ vim"
+msgid "E446: No file name under cursor"
+msgstr "E446: Ðемає назви файлу над курÑором"
-#~ msgid "unable to convert %s to vim dictionary"
-#~ msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ %s у Ñловник vim"
+#, c-format
+msgid "E799: Invalid ID: %<PRId64> (must be greater than or equal to 1)"
+msgstr "E799: Ðеправильний ID: %<PRId64> (має бути не меншим 1)"
-#~ msgid "unable to convert %s to vim structure"
-#~ msgstr "не вдалоÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ %s у Ñтруктуру vim"
+#, c-format
+msgid "E801: ID already taken: %<PRId64>"
+msgstr "E801: ID вже зайнÑто: %<PRId64>"
-#~ msgid "internal error: NULL reference passed"
-#~ msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: передано поÑÐ¸Ð»Ð°Ð½Ð½Ñ NULL"
+#, c-format
+msgid "E5030: Empty list at position %d"
+msgstr "E5030: Порожній ÑпиÑок у позиції %d"
-#~ msgid "internal error: invalid value type"
-#~ msgstr "Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°: неправильний тип значеннÑ"
+#, c-format
+msgid "E5031: List or number required at position %d"
+msgstr "E5031: ОчікуєтьÑÑ ÑпиÑок чи чиÑло у позиції %d"
-#~ msgid ""
-#~ "Failed to set path hook: sys.path_hooks is not a list\n"
-#~ "You should now do the following:\n"
-#~ "- append vim.path_hook to sys.path_hooks\n"
-#~ "- append vim.VIM_SPECIAL_PATH to sys.path\n"
-#~ msgstr ""
-#~ "Ðе вдалоÑÑ Ð²Ñтановити обробник шлÑху: sys.path_hooks не ÑпиÑок\n"
-#~ "Вам Ñлід вчинити так:\n"
-#~ "- додайте vim.path_hook до sys.path_hooks\n"
-#~ "- додайте vim.VIM_SPECIAL_PATH до sys.path\n"
+#, c-format
+msgid "E802: Invalid ID: %<PRId64> (must be greater than or equal to 1)"
+msgstr "E802: Ðеправильний ID: %<PRId64> (має бути не меншим 1)"
-#~ msgid ""
-#~ "Failed to set path: sys.path is not a list\n"
-#~ "You should now append vim.VIM_SPECIAL_PATH to sys.path"
-#~ msgstr ""
-#~ "Ðе вдалоÑÑ Ð²Ñтановити шлÑÑ…: sys.path не ÑпиÑок\n"
-#~ "Ð’Ð°Ñ Ñлід додати vim.VIM_SPECIAL_PATH до sys.path"
+#, c-format
+msgid "E803: ID not found: %<PRId64>"
+msgstr "E803: ID не знайдено: %<PRId64>"
diff --git a/src/nvim/po/vi.po b/src/nvim/po/vi.po
index a720510426..7dbf19c263 100644
--- a/src/nvim/po/vi.po
+++ b/src/nvim/po/vi.po
@@ -2500,7 +2500,7 @@ msgstr "E216: Nhóm hoặc sự kiện không có thật: %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- Câu lệnh tự động ---"
@@ -2524,7 +2524,7 @@ msgstr "E218: câu lệnh tự động xếp lồng vào nhau quá xâu"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s câu lệnh tự động cho \"%s\""
#: ../fileio.c:7149
@@ -2720,11 +2720,6 @@ msgstr "E49: Kích thước thanh cuộn không cho phép"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3424,7 +3419,7 @@ msgstr "-q [tập tin lỗi] soạn thảo tập tin với lỗi đầu tiên"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4311,11 +4306,6 @@ msgstr "dòng %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: Tên sổ đăng ký không cho phép: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr ""
-"Bản dịch các thông báo sang tiếng Việt: Phan Vĩnh Thịnh <teppi@vnlinux.org>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "Gián đoạn: "
diff --git a/src/nvim/po/zh_CN.UTF-8.po b/src/nvim/po/zh_CN.UTF-8.po
index 82b895d9d6..76204a43a8 100644
--- a/src/nvim/po/zh_CN.UTF-8.po
+++ b/src/nvim/po/zh_CN.UTF-8.po
@@ -2461,7 +2461,7 @@ msgstr "E216: 无此组或事件: %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
"--- 自动命令 ---"
@@ -2485,7 +2485,7 @@ msgstr "E218: 自动命令嵌套层数过深"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
+msgid "%s Autocommands for \"%s\""
msgstr "%s 自动命令 \"%s\""
#: ../fileio.c:7149
@@ -2675,11 +2675,6 @@ msgstr "E49: 无效的滚动大å°"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3372,7 +3367,7 @@ msgstr "-q [errorfile] 编辑第一个出错处的文件"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4264,10 +4259,6 @@ msgstr "第 %4ld 行:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: 无效的寄存器å: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "简体中文消æ¯ç»´æŠ¤è€…: Yuheng Xie <elephant@linux.net.cn>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "已中断: "
@@ -5301,7 +5292,7 @@ msgstr "警告: 区域 %s 䏿”¯æŒ"
#: ../spell.c:4550
#, c-format
-msgid "Reading affix file %s ..."
+msgid "Reading affix file %s..."
msgstr "读å–附加文件 %s ……"
#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
@@ -5460,7 +5451,7 @@ msgstr "%s 的值与å¦ä¸€ä¸ª .aff 文件中使用的值ä¸ç›¸åŒ"
#: ../spell.c:5602
#, c-format
-msgid "Reading dictionary file %s ..."
+msgid "Reading dictionary file %s..."
msgstr "读å–字典文件 %s ……"
#: ../spell.c:5611
@@ -5495,7 +5486,7 @@ msgstr "å¿½ç•¥äº†å«æœ‰éž ASCII 字符的 %d 个å•è¯ï¼Œåœ¨ %s 中"
#: ../spell.c:6115
#, c-format
-msgid "Reading word file %s ..."
+msgid "Reading word file %s..."
msgstr "读å–å•è¯æ–‡ä»¶ %s ……"
#: ../spell.c:6155
@@ -5565,7 +5556,7 @@ msgstr "å•è¯æ€»æ•°: %d"
#: ../spell.c:7655
#, c-format
-msgid "Writing suggestion file %s ..."
+msgid "Writing suggestion file %s..."
msgstr "写入建议文件 %s ……"
#: ../spell.c:7707 ../spell.c:7927
@@ -5592,7 +5583,7 @@ msgstr "警告: åŒæ—¶æŒ‡å®šäº† compounding å’Œ NOBREAK"
#: ../spell.c:7920
#, c-format
-msgid "Writing spell file %s ..."
+msgid "Writing spell file %s..."
msgstr "写入拼写文件 %s ……"
#: ../spell.c:7925
diff --git a/src/nvim/po/zh_CN.cp936.po b/src/nvim/po/zh_CN.cp936.po
deleted file mode 100644
index cf66010c71..0000000000
--- a/src/nvim/po/zh_CN.cp936.po
+++ /dev/null
@@ -1,7932 +0,0 @@
-# Chinese (simplified) Translation for Vim
-#
-# Do ":help uganda" in Vim to read copying and usage conditions.
-# Do ":help credits" in Vim to see a list of people who contributed.
-#
-# FIRST AUTHOR Wang Jun <junw@turbolinux.com.cn>
-#
-# TRANSLATORS
-# Edyfox <edyfox@gmail.com>
-# Yuheng Xie <elephant@linux.net.cn>
-#
-# Generated from zh_CN.po, DO NOT EDIT.
-#
-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"
-"Language-Team: Simplified Chinese <i18n-translation@lists.linux.net.cn>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=gbk\n"
-"Content-Transfer-Encoding: 8-bit\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "Ñ¡Ïî²ÎÊýºóµÄÄÚÈÝÎÞЧ"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[Location Áбí]"
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[Quickfix Áбí]"
-
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr ""
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: ÎÞ·¨·ÖÅäÈκλº³åÇø£¬Í˳ö³ÌÐò..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: ÎÞ·¨·ÖÅ仺³åÇø£¬Ê¹ÓÃÁíÒ»¸ö»º³åÇø..."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: ûÓÐÊÍ·ÅÈκλº³åÇø"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: ûÓÐɾ³ýÈκλº³åÇø"
-
-#: ../buffer.c:767
-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:782
-msgid "1 buffer wiped out"
-msgstr "Çå³ýÁË 1 ¸ö»º³åÇø"
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "Çå³ýÁË %d ¸ö»º³åÇø"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: ÎÞ·¨ÊÍ·Å×îºóÒ»¸ö»º³åÇø"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: ûÓÐÐ޸ĹýµÄ»º³åÇø"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-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
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: ÎÞ·¨Çл»£¬ÒÑÊÇ×îºóÒ»¸ö»º³åÇø"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: ÎÞ·¨Çл»£¬ÒÑÊǵÚÒ»¸ö»º³åÇø"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: »º³åÇø %<PRId64> ÒÑÐ޸ĵ«ÉÐδ±£´æ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: ¾¯¸æ: ÎļþÃû¹ý¶à"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: ÕÒ²»µ½»º³åÇø %<PRId64>"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: ÕÒµ½²»Ö¹Ò»¸ö %s"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: ûÓÐÆ¥ÅäµÄ»º³åÇø %s"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "µÚ %<PRId64> ÐÐ"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: ÒÑÓлº³åÇøÊ¹ÓøÃÃû³Æ"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [ÒÑÐÞ¸Ä]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[δ±à¼­]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[ÐÂÎļþ]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[¶Á´íÎó]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[Ö»¶Á]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-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:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "ÐÐ %<PRId64> / %<PRId64> --%d%%-- ÁÐ "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-msgid "[No Name]"
-msgstr "[δÃüÃû]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "°ïÖú"
-
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[°ïÖú]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[Ô¤ÀÀ]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "È«²¿"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "µ×¶Ë"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "¶¥¶Ë"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# »º³åÇøÁбí:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr ""
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- Signs ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "%s µÄ Signs:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ÐÐ=%<PRId64> id=%d Ãû³Æ=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ȱÉÙðºÅ"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: ÎÞЧµÄģʽ"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: ´Ë´¦ÐèÒªÊý×Ö"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: ÎÞЧµÄ°Ù·Ö±È"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: ²»ÄܱȽÏ(diff) %<PRId64> ¸öÒÔÉϵĻº³åÇø"
-
-#: ../diff.c:753
-#, fuzzy
-msgid "E810: Cannot read or write temp files"
-msgstr "E557: ÎÞ·¨´ò¿ª termcap Îļþ"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: ÎÞ·¨´´½¨ diff"
-
-#: ../diff.c:966
-#, fuzzy
-msgid "E816: Cannot read patch output"
-msgstr "E98: ÎÞ·¨¶ÁÈ¡ diff µÄÊä³ö"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: ÎÞ·¨¶ÁÈ¡ diff µÄÊä³ö"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: µ±Ç°»º³åÇø²»ÔÚ diff ģʽ"
-
-#: ../diff.c:2100
-#, fuzzy
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E100: ûÓÐÆäËü´¦ÓÚ diff ģʽµÄ»º³åÇø"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: ûÓÐÆäËü´¦ÓÚ diff ģʽµÄ»º³åÇø"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr "E101: ÓÐÁ½¸öÒÔÉϵĻº³åÇø´¦ÓÚ diff ģʽ£¬²»Äܾö¶¨ÓÃÄÄÒ»¸ö"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: ÕÒ²»µ½»º³åÇø \"%s\""
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: »º³åÇø \"%s\" ²»ÔÚ diff ģʽ"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr "E787: ÒâÍâµØ¸Ä±äÁË»º³åÇø"
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: ¸´ºÏ×Ö·û(digraph)Öв»ÄÜʹÓà Escape"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: ÕÒ²»µ½ Keymap Îļþ"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: ²»ÊÇÔڽű¾ÎļþÖÐʹÓà :loadkeymap "
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr ""
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " ¹Ø¼ü×Ö²¹È« (^N^P)"
-
-#. 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)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " ÕûÐв¹È« (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " ÎļþÃû²¹È« (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " Tag ²¹È« (^]^N^P)"
-
-#: ../edit.c:88
-#, fuzzy
-msgid " Path pattern completion (^N^P)"
-msgstr " ·¾¶Ä£Ê½²¹È« (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " ¶¨Ò岹ȫ (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Dictionary ²¹È« (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " Thesaurus ²¹È« (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " ÃüÁîÐв¹È« (^V^N^P)"
-
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr " Óû§×Ô¶¨Ò岹ȫ (^U^N^P)"
-
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " È«Äܲ¹È« (^O^N^P)"
-
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ƴд½¨Òé (s^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " ¹Ø¼ü×Ö¾Ö²¿²¹È« (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "Òѵ½¶ÎÂä½áβ"
-
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr ""
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr ""
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "Ñ¡Ïî 'dictionary' Ϊ¿Õ"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "Ñ¡Ïî 'thesaurus' Ϊ¿Õ"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "ÕýÔÚɨÃè dictionary: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (²åÈë) Scroll (^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (Ìæ»») Scroll (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "ÕýÔÚɨÃè: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "ɨÃè±êÇ©."
-
-#: ../edit.c:4519
-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.
-#.
-#: ../edit.c:4562
-msgid "-- Searching..."
-msgstr "-- ²éÕÒÖÐ..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "»Øµ½Æðµã"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "ÁíÒ»ÐеĴÊ"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "ΨһƥÅä"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "Æ¥Åä %d / %d"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "Æ¥Åä %d"
-
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: :let ÖгöÏÖÒì³£×Ö·û"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: List Ë÷Òý³¬³ö·¶Î§: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: 䶨ÒåµÄ±äÁ¿: %s"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: ȱÉÙ ']'"
-
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s µÄ²ÎÊý±ØÐëÊÇ List"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s µÄ²ÎÊý±ØÐëÊÇ List »òÕß Dictionary"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Dictionary µÄ¼ü²»ÄÜΪ¿Õ"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: ÐèÒª List"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: ÐèÒª Dictionary"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: º¯ÊýµÄ²ÎÊý¹ý¶à: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Dictionary Öв»´æÔÚ¼ü: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: º¯Êý %s ÒÑ´æÔÚ£¬Çë¼Ó ! Ç¿ÖÆÌæ»»"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Dictionary ÏîÒÑ´æÔÚ"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: ÐèÒª Funcref"
-
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: ²»ÄÜ¶Ô Dictionary ʹÓà [:]"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: %s= µÄ±äÁ¿ÀàÐͲ»ÕýÈ·"
-
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: δ֪µÄº¯Êý: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: ÎÞЧµÄ±äÁ¿Ãû: %s"
-
-#: ../eval.c:157
-#, fuzzy
-msgid "E806: using Float as a String"
-msgstr "E730: ½« List ×÷ String ʹÓÃ"
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: Ä¿±ê±È List ÏîÊýÉÙ"
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: Ä¿±ê±È List ÏîÊý¶à"
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "±äÁ¿ÁбíÖгöÏÖÁ½¸ö ;"
-
-#: ../eval.c:2078
-#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: ÎÞ·¨Áгö %s µÄ±äÁ¿"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: Ö»ÄÜË÷Òý List »ò Dictionary"
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:] ±ØÐëÔÚ×îºó"
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:] ÐèÒªÒ»¸ö List Öµ"
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: List ÖµµÄÏî±ÈÄ¿±ê¶à"
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: List ֵûÓÐ×ã¹»¶àµÄÏî"
-
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: :for ºóȱÉÙ \"in\""
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: ȱÉÙÀ¨ºÅ: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: Î޴˱äÁ¿: \"%s\""
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: (un)lock µÄ±äÁ¿Ç¶Ì×¹ýÉî"
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: '?' ºóȱÉÙ ':'"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: Ö»ÄÜ±È½Ï List ºÍ List"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: ¶Ô List ÎÞЧµÄ²Ù×÷"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: Ö»ÄÜ±È½Ï Dictionary ºÍ Dictionary"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: ¶Ô Dictionary ÎÞЧµÄ²Ù×÷"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Ö»ÄÜ±È½Ï Funcref ºÍ Funcref"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: ¶Ô Funcrefs ÎÞЧµÄ²Ù×÷"
-
-#: ../eval.c:4277
-#, fuzzy
-msgid "E804: Cannot use '%' with Float"
-msgstr "E719: ²»ÄÜ¶Ô Dictionary ʹÓà [:]"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: ȱÉÙ ')'"
-
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: ²»ÄÜË÷ÒýÒ»¸ö Funcref"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: ȱÉÙÑ¡ÏîÃû³Æ: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: δ֪µÄÑ¡Ïî: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: ȱÉÙÒýºÅ: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: ȱÉÙÒýºÅ: %s"
-
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: List ÖÐȱÉÙ¶ººÅ: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: List ȱÉÙ½áÊø·û ']': %s"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Dictionary ÖÐȱÉÙðºÅ: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Dictionary ÖгöÏÖÖØ¸´µÄ¼ü: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Dictionary ÖÐȱÉÙ¶ººÅ: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Dictionary ȱÉÙ½áÊø·û '}': %s"
-
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: ±äÁ¿Ç¶Ì×¹ýÉîÎÞ·¨ÏÔʾ"
-
-#: ../eval.c:7188
-#, fuzzy, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E118: º¯ÊýµÄ²ÎÊý¹ý¶à: %s"
-
-#: ../eval.c:7190
-#, fuzzy, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E118: º¯ÊýµÄ²ÎÊý¹ý¶à: %s"
-
-#: ../eval.c:7377
-#, fuzzy, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E130: δ֪µÄº¯Êý: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: º¯Êý %s µÄ²ÎÊýÌ«ÉÙ"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> ²»ÄÜÔÚ script ÉÏÏÂÎÄÍâʹÓÃ: %s"
-
-#: ../eval.c:7391
-#, fuzzy, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E720: Dictionary ÖÐȱÉÙðºÅ: %s"
-
-#: ../eval.c:7453
-#, fuzzy
-msgid "E808: Number or Float required"
-msgstr "E521: = ºóÃæÐèÒªÊý×Ö"
-
-#: ../eval.c:7503
-#, fuzzy
-msgid "add() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: ²ÎÊý¹ý¶à"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() Ö»ÄÜÔÚ²åÈëģʽÖÐʹÓÃ"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "È·¶¨(&O)"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: ¼üÒÑ´æÔÚ: %s"
-
-#: ../eval.c:8692
-#, fuzzy
-msgid "extend() argument"
-msgstr "--cmd ²ÎÊý"
-
-#: ../eval.c:8915
-#, fuzzy
-msgid "map() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:8916
-#, fuzzy
-msgid "filter() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld ÐÐ: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: δ֪µÄº¯Êý: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "inputrestore() µÄµ÷ÓôÎÊý¶àÓÚ inputsave()"
-
-#: ../eval.c:10771
-#, fuzzy
-msgid "insert() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: ²»ÔÊÐíµÄ·¶Î§"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: len() µÄÀàÐÍÎÞЧ"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: ²½³¤ÎªÁã"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: ÆðʼֵÔÚÖÕÖ¹Öµºó"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<¿Õ>"
-
-#: ../eval.c:12282
-#, fuzzy
-msgid "remove() argument"
-msgstr "--cmd ²ÎÊý"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: ·ûºÅÁ¬½Ó¹ý¶à(Ñ­»·£¿)"
-
-#: ../eval.c:12593
-#, fuzzy
-msgid "reverse() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "sort() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Sort ±È½Ïº¯Êýʧ°Ü"
-
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Sort ±È½Ïº¯Êýʧ°Ü"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(ÎÞЧ)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: дÁÙʱÎļþ³ö´í"
-
-#: ../eval.c:16159
-#, fuzzy
-msgid "E805: Using a Float as a Number"
-msgstr "E745: ½« List ×÷Êý×ÖʹÓÃ"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: ½« Funcref ×÷Êý×ÖʹÓÃ"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: ½« List ×÷Êý×ÖʹÓÃ"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: ½« Dictionary ×÷Êý×ÖʹÓÃ"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: ½« Funcref ×÷ String ʹÓÃ"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: ½« List ×÷ String ʹÓÃ"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: ½« Dictionary ×÷ String ʹÓÃ"
-
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: ±äÁ¿ÀàÐͲ»Æ¥Åä: %s"
-
-#: ../eval.c:16705
-#, fuzzy, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E738: ÎÞ·¨Áгö %s µÄ±äÁ¿"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Funcref ±äÁ¿Ãû±ØÐëÒÔ´óд×Öĸ¿ªÍ·: %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: ±äÁ¿ÃûÓëÒÑÓк¯ÊýÃû³åÍ»: %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: ÖµÒÑËø¶¨: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "δ֪"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: ÎÞ·¨¸Ä±ä %s µÄÖµ"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: ±äÁ¿Ç¶Ì×¹ýÉîÎÞ·¨¸´ÖÆ"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: º¯Êý %s ÉÐ䶨Òå"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: ȱÉÙ '(': %s"
-
-#: ../eval.c:17293
-#, fuzzy
-msgid "E862: Cannot use g: here"
-msgstr "E284: ²»ÄÜÉ趨 IC Öµ"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: ÎÞЧµÄ²ÎÊý: %s"
-
-#: ../eval.c:17323
-#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E125: ÎÞЧµÄ²ÎÊý: %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: ȱÉÙ :endfunction"
-
-#: ../eval.c:17537
-#, fuzzy, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E746: º¯ÊýÃûÓë½Å±¾ÎļþÃû²»Æ¥Åä: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: º¯Êý %s ÕýÔÚʹÓÃÖУ¬²»ÄÜÖØÐ¶¨Òå"
-
-#: ../eval.c:17604
-#, 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.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: º¯ÊýÃû±ØÐëÒÔ´óд×Öĸ¿ªÍ·»òÕß°üº¬Ã°ºÅ: %s"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: º¯ÊýÃû±ØÐëÒÔ´óд×Öĸ¿ªÍ·»òÕß°üº¬Ã°ºÅ: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: ÎÞ·¨É¾³ýº¯Êý %s: ÕýÔÚʹÓÃÖÐ"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: º¯Êýµ÷ÓÃÉî¶È³¬³ö 'maxfuncdepth'"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "µ÷ÓÃ %s"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ÒÑÖÐÖ¹"
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ·µ»Ø #%<PRId64> "
-
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%s ·µ»Ø %s"
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "ÔÚ %s ÖмÌÐø"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return ²»ÔÚº¯ÊýÖÐ"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# È«¾Ö±äÁ¿:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\t×î½üÐÞ¸ÄÓÚ "
-
-#: ../eval.c:19272
-#, fuzzy
-msgid "No old files"
-msgstr "ûÓаüº¬Îļþ"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, Ê®Áù½øÖÆ %02x, °Ë½øÖÆ %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, Ê®Áù½øÖÆ %04x, °Ë½øÖÆ %o"
-
-#: ../ex_cmds.c:146
-#, 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:747
-msgid "1 line moved"
-msgstr "ÒÆ¶¯ÁË 1 ÐÐ"
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "ÒÆ¶¯ÁË %<PRId64> ÐÐ"
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "¹ýÂËÁË %<PRId64> ÐÐ"
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: *Filter* ×Ô¶¯ÃüÁî²»¿ÉÒԸı䵱ǰ»º³åÇø"
-
-#: ../ex_cmds.c:1244
-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
-#, 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"
-
-# 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
-msgid "Write partial file?"
-msgstr "ҪдÈ벿·ÖÎļþÂð£¿"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: ÇëʹÓà ! À´Ð´È벿·Ö»º³åÇø"
-
-#: ../ex_cmds.c:2281
-#, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "¸²¸ÇÒÑ´æÔÚµÄÎļþ \"%s\" Âð£¿"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr "½»»»Îļþ \"%s\" ÒÑ´æÔÚ£¬È·ÊµÒª¸²¸ÇÂð£¿"
-
-#: ../ex_cmds.c:2326
-#, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E768: ½»»»ÎļþÒÑ´æÔÚ: %s (:silent! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: »º³åÇø %<PRId64> ûÓÐÎļþÃû"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: ÎļþδдÈë: дÈë±» 'write' Ñ¡Ïî½ûÓÃ"
-
-#: ../ex_cmds.c:2434
-#, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"\"%s\" ÒÑÉ趨 'readonly' Ñ¡Ïî¡£\n"
-"ȷʵҪ¸²¸ÇÂð£¿"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-
-#: ../ex_cmds.c:2451
-#, fuzzy, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "Ö»¶Á (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: ×Ô¶¯ÃüÁîÒâÍâµØÉ¾³ýÁËлº³åÇø %s"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: :z ²»½ÓÊÜ·ÇÊý×ֵIJÎÊý"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: rvim ÖнûֹʹÓà shell ÃüÁî"
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: ÕýÔò±í´ïʽ²»ÄÜÓÃ×Öĸ×÷·Ö½ç"
-
-#: ../ex_cmds.c:3964
-#, 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
-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:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> ´ÎÌæ»»£¬"
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr "¹² 1 ÐÐ"
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr "¹² %<PRId64> ÐÐ"
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global ²»ÄܵݹéÖ´ÐÐ"
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: global ȱÉÙÕýÔò±í´ïʽ"
-
-#: ../ex_cmds.c:4508
-#, 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
-#, 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"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "¶Ïµã \"%s%s\" µÚ %<PRId64> ÐÐ"
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: ÕÒ²»µ½¶Ïµã: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "ûÓж¨Òå¶Ïµã"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s µÚ %<PRId64> ÐÐ"
-
-#: ../ex_cmds2.c:942
-#, fuzzy
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: ÇëÏÈʹÓà :profile start <fname>"
-
-#: ../ex_cmds2.c:1269
-#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "½«¸Ä±ä±£´æµ½ \"%s\" Âð£¿"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "δÃüÃû"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: »º³åÇø \"%s\" ÒÑÐ޸ĵ«ÉÐδ±£´æ"
-
-#: ../ex_cmds2.c:1480
-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
-#, 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_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: Ôڽű¾ÎļþÍâʹÓÃÁË :scriptencoding"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: Ôڽű¾ÎļþÍâʹÓÃÁË :finish"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "µ±Ç°µÄ %sÓïÑÔ: \"%s\""
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: ²»ÄÜÉ趨ÓïÑÔΪ \"%s\""
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "½øÈë Ex ģʽ¡£ÊäÈë \"visual\" »Øµ½Õý³£Ä£Ê½¡£"
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: Òѵ½Îļþĩβ"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: ÃüÁîµÝ¹é²ãÊý¹ý¶à"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: Ò쳣ûÓб»²¶»ñ: %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "½Å±¾Îļþ½áÊø"
-
-#: ../ex_docmd.c:1086
-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: ²»ÊDZ༭Æ÷µÄÃüÁî"
-
-#: ../ex_docmd.c:1729
-msgid "E493: Backwards range given"
-msgstr "E493: ʹÓÃÁËÄæÏòµÄ·¶Î§"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "ʹÓÃÁËÄæÏòµÄ·¶Î§£¬È·¶¨½»»»Âð"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: ÇëʹÓà w »ò w>>"
-
-#: ../ex_docmd.c:3454
-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:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: ûÓÐÕâ¸öÓû§×Ô¶¨ÒåÃüÁî: %s"
-
-#: ../ex_docmd.c:5219
-#, 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"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "ÄúºÃ£¬Vim Óû§£¡"
-
-#: ../ex_docmd.c:5431
-msgid "E784: Cannot close last tab page"
-msgstr "E784: ²»ÄܹرÕ×îºóÒ»¸ö tab Ò³"
-
-#: ../ex_docmd.c:5462
-msgid "Already only one tab page"
-msgstr "ÒѾ­Ö»Ê£Ò»¸ö tab Ò³ÁË"
-
-#: ../ex_docmd.c:6004
-#, c-format
-msgid "Tab page %d"
-msgstr "Tab Ò³ %d"
-
-#: ../ex_docmd.c:6295
-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
-msgid "E186: No previous directory"
-msgstr "E186: ǰһ¸öĿ¼²»´æÔÚ"
-
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: δ֪"
-
-#: ../ex_docmd.c:6610
-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
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: \"%s\" ÒÑ´æÔÚ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: ÎÞ·¨´ò¿ª²¢Ð´Èë \"%s\""
-
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: ²ÎÊý±ØÐëÊÇÒ»¸ö×Öĸ»òÕßÕý/·´ÒýºÅ"
-
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: :normal µÝ¹é²ãÊý¹ýÉî"
-
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: ûÓÐÓÃÓÚÌæ»» '#' µÄ½»ÌæÎļþÃû"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: ûÓÐÓÃÓÚÌæ»» \"<afile>\" µÄ×Ô¶¯ÃüÁîÎļþÃû"
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: ûÓÐÓÃÓÚÌæ»» \"<abuf>\" µÄ×Ô¶¯ÃüÁ³åÇøºÅ"
-
-#: ../ex_docmd.c:7861
-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
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: ûÓÐÓÃÓÚÌæ»» \"<sfile>\" µÄ :source ÎļþÃû"
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: '%' »ò '#' Ϊ¿ÕÎļþÃû£¬Ö»ÄÜÓÃÓÚ \":p:h\""
-
-#: ../ex_docmd.c:7905
-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_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: ²»ÄÜ :throw ǰ׺Ϊ 'Vim' µÄÒì³£"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "Å׳öÒì³£: %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "Íê³ÉÒì³£: %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "¶ªÆúÒì³£: %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s£¬µÚ %<PRId64> ÐÐ"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "²¶»ñÒì³£: %s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr ""
-
-#: ../ex_eval.c:679
-#, fuzzy, c-format
-msgid "%s resumed"
-msgstr " ÒÑ·µ»Ø\n"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr ""
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "Òì³£"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "´íÎóºÍÖжÏ"
-
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "´íÎó"
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "ÖжÏ"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: :if ǶÌײãÊý¹ýÉî"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :endif ȱÉÙ¶ÔÓ¦µÄ :if"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :else ȱÉÙ¶ÔÓ¦µÄ :if"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :elseif ȱÉÙ¶ÔÓ¦µÄ :if"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: ¶à¸ö :else"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :elseif ÔÚ :else ºóÃæ"
-
-#: ../ex_eval.c:941
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: :while/:for ǶÌײãÊý¹ýÉî"
-
-#: ../ex_eval.c:1028
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :continue ȱÉÙ¶ÔÓ¦µÄ :while »ò :for"
-
-#: ../ex_eval.c:1061
-msgid "E587: :break without :while or :for"
-msgstr "E587: :break ȱÉÙ¶ÔÓ¦µÄ :while »ò :for"
-
-#: ../ex_eval.c:1102
-msgid "E732: Using :endfor with :while"
-msgstr "E732: :while ÒÔ :endfor ½áβ"
-
-#: ../ex_eval.c:1104
-msgid "E733: Using :endwhile with :for"
-msgstr "E733: :for ÒÔ :endwhile ½áβ"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: :try ǶÌײãÊý¹ýÉî"
-
-#: ../ex_eval.c:1317
-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
-msgid "E604: :catch after :finally"
-msgstr "E604: :catch ÔÚ :finally ºóÃæ"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :finally ȱÉÙ¶ÔÓ¦µÄ :try"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: ¶à¸ö :finally"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :endtry ȱÉÙ¶ÔÓ¦µÄ :try"
-
-#: ../ex_eval.c:2026
-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
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E788: Ŀǰ²»ÔÊÐí±à¼­±ðµÄ»º³åÇø"
-
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "tag Ãû"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " ÀàÐÍ Îļþ\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "Ñ¡Ïî 'history' ΪÁã"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5046
-#, fuzzy, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s ÀúÊ·¼Ç¼ (´Óе½¾É):\n"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5047
-#, fuzzy
-msgid "Command Line"
-msgstr "ÃüÁîÐÐ"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5048
-#, fuzzy
-msgid "Search String"
-msgstr "²éÕÒ×Ö·û´®"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5049
-#, fuzzy
-msgid "Expression"
-msgstr "±í´ïʽ"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5050
-#, fuzzy
-msgid "Input Line"
-msgstr "ÊäÈëÐÐ"
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar ³¬¹ýÃüÁ¶È"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: »î¶¯´°¿Ú»ò»º³åÇøÒѱ»É¾³ý"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr ""
-
-#: ../file_search.c:446
-#, 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
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpath ÖÐÕÒ²»µ½Ä¿Â¼ \"%s\""
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: ÔÚ·¾¶ÖÐÕÒ²»µ½Îļþ \"%s\""
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: ÔÚ·¾¶ÖÐÕÒ²»µ½¸ü¶àµÄÎļþ \"%s\""
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: ÔÚ·¾¶ÖÐÕÒ²»µ½¸ü¶àµÄÎļþ \"%s\""
-
-#: ../fileio.c:137
-#, fuzzy
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E135: *Filter* ×Ô¶¯ÃüÁî²»¿ÉÒԸı䵱ǰ»º³åÇø"
-
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "ÎÞЧµÄÎļþÃû"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "ÊÇĿ¼"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "²»ÊÇÎļþ"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[ÐÂÎļþ]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr "[ÐÂĿ¼]"
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr "[Îļþ¹ý´ó]"
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[ȨÏÞ²»×ã]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200: *ReadPre ×Ô¶¯ÃüÁîµ¼ÖÂÎļþ²»¿É¶Á"
-
-#: ../fileio.c:655
-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
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202: ת»»µ¼ÖÂÎļþ²»¿É¶Á"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[fifo/socket]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[fifo]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[socket]"
-
-#. or character special
-#: ../fileio.c:1801
-#, fuzzy
-msgid "[character special]"
-msgstr "1 ¸ö×Ö·û"
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[ȱÉÙ CR]'"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[³¤Ðзָî]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[δת»»]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[ÒÑת»»]"
-
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[µÚ %<PRId64> ÐÐת»»´íÎó]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[µÚ %<PRId64> ÐÐÎÞЧ×Ö·û]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[¶Á´íÎó]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "ÕÒ²»µ½ÓÃÓÚת»»µÄÁÙʱÎļþ"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "'charconvert' ת»»Ê§°Ü"
-
-#: ../fileio.c:2113
-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:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr "E203: ×Ô¶¯ÃüÁîɾ³ý»òÊÍ·ÅÁËҪдÈëµÄ»º³åÇø"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: ×Ô¶¯ÃüÁîÒâÍâµØ¸Ä±äÁËÐÐÊý"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "²»ÊÇÎļþ»ò¿ÉдµÄÉ豸"
-
-#: ../fileio.c:2601
-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:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr "E509: ÎÞ·¨´´½¨±¸·ÝÎļþ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr "E510: ÎÞ·¨Éú³É±¸·ÝÎļþ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: ÕÒ²»µ½ÓÃÓÚдÈëµÄÁÙʱÎļþ"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr "E213: ÎÞ·¨×ª»» (Çë¼Ó ! Ç¿ÖÆ²»×ª»»Ð´Èë)"
-
-#: ../fileio.c:3169
-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:3398
-msgid "E512: Close failed"
-msgstr "E512: ¹Ø±Õʧ°Ü"
-
-#: ../fileio.c:3436
-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' ÖÿÕÒÔÇ¿ÖÆÖ´ÐÐ)"
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: дÈë´íÎó (ÎļþϵͳÒÑÂú£¿)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr " ת»»´íÎó"
-
-#: ../fileio.c:3509
-#, fuzzy, c-format
-msgid " in line %<PRId64>;"
-msgstr "µÚ %<PRId64> ÐÐ"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[É豸]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[ÐÂ]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr " [a]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " ÒÑ×·¼Ó"
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr " [w]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " ÒÑдÈë"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Patchmode: ÎÞ·¨±£´æÔ­Ê¼Îļþ"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: Patchmode: ÎÞ·¨Éú³É¿ÕµÄԭʼÎļþ"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: ÎÞ·¨É¾³ý±¸·ÝÎļþ"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"¾¯¸æ: ԭʼÎļþ¿ÉÄÜÒѶªÊ§»òËð»µ\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "ÔÚÎļþÕýȷдÈëǰÇëÎðÍ˳ö±à¼­Æ÷£¡"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[dos ¸ñʽ]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[mac ¸ñʽ]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[unix ¸ñʽ]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 ÐУ¬"
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> ÐУ¬"
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 ¸ö×Ö·û"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> ¸ö×Ö·û"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-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
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "¾¯¸æ: ´ËÎļþ×Ô¶ÁÈëºóÒÑ·¢Éú±ä¶¯£¡£¡£¡"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "ȷʵҪдÈëÂð"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: дÈëÎļþ \"%s\" ³ö´í"
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: ¹Ø±ÕÎļþ \"%s\" ³ö´í"
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: ¶ÁÈ¡Îļþ \"%s\" ³ö´í"
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: FileChangedShell ×Ô¶¯ÃüÁîɾ³ýÁË»º³åÇø"
-
-#: ../fileio.c:4894
-#, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Îļþ \"%s\" ÒѾ­²»´æÔÚ"
-
-#: ../fileio.c:4906
-#, 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
-msgid "See \":help W12\" for more info."
-msgstr "½øÒ»²½ËµÃ÷Çë¼û \":help W12\""
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: ¾¯¸æ: ±à¼­¿ªÊ¼ºó£¬Îļþ \"%s\" Òѱ䶯"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "½øÒ»²½ËµÃ÷Çë¼û \":help W11\""
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr "W16: ¾¯¸æ: ±à¼­¿ªÊ¼ºó£¬Îļþ \"%s\" µÄģʽÒѱ䶯"
-
-#: ../fileio.c:4915
-msgid "See \":help W16\" for more info."
-msgstr "½øÒ»²½ËµÃ÷Çë¼û \":help W16\""
-
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: ¾¯¸æ: ±à¼­¿ªÊ¼ºó£¬Îļþ \"%s\" Òѱ»´´½¨"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "¾¯¸æ"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"È·¶¨(&O)\n"
-"¼ÓÔØÎļþ(&L)"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: ÎÞ·¨ÎªÖØÐ¼ÓÔØ \"%s\" ×ö×¼±¸"
-
-#: ../fileio.c:5078
-#, 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 ""
-
-#. 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"
-"--- Auto-Commands ---"
-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 Auto commands 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
-msgid "E219: Missing {."
-msgstr "E219: ȱÉÙ {¡£"
-
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: ȱÉÙ }¡£"
-
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: ÕÒ²»µ½ÕÛµþ"
-
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: ²»ÄÜÔÚµ±Ç°µÄ 'foldmethod' Ï´´½¨ÕÛµþ"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: ²»ÄÜÔÚµ±Ç°µÄ 'foldmethod' ÏÂɾ³ýÕÛµþ"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--ÒÑÕÛµþ %3ld ÐÐ"
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: Ìí¼Óµ½ÒѶÁ»º³åÇøÖÐ"
-
-#: ../getchar.c:2040
-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
-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
-msgid "E470: Command aborted"
-msgstr "E470: ÃüÁî±»ÖÐÖ¹"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: ÐèÒª²ÎÊý"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ ºóÃæÓ¦¸Ã¸úÓÐ /¡¢? »ò &"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: ÔÚÃüÁîÐд°¿ÚÖÐÎÞЧ£»<CR> Ö´ÐУ¬CTRL-C Í˳ö"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr "E12: µ±Ç°Ä¿Â¼ÖÐµÄ exrc/vimrc »ò tag ²éÕÒÖв»ÔÊÐí´ËÃüÁî"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: ȱÉÙ :endif"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: ȱÉÙ :endtry"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: ȱÉÙ :endwhile"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: ȱÉÙ :endfor"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile ȱÉÙ¶ÔÓ¦µÄ :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor ȱÉÙ¶ÔÓ¦µÄ :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: ÎļþÒÑ´æÔÚ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: ÃüÁîÖ´ÐÐʧ°Ü"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: ÄÚ²¿´íÎó"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "ÒÑÖжÏ"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: ÎÞЧµÄµØÖ·"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: ÎÞЧµÄ²ÎÊý"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: ÎÞЧµÄ²ÎÊý: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: ÎÞЧµÄ±í´ïʽ: %s"
-
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: ÎÞЧµÄ·¶Î§"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: ÎÞЧµÄÃüÁî"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ÊÇĿ¼"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: ÎÞЧµÄ¹ö¶¯´óС"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: µ÷Óú¯Êý¿â \"%s()\" ʧ°Ü"
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: ±ê¼ÇµÄÐкÅÎÞЧ"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: ûÓÐÉ趨±ê¼Ç"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: ²»ÄÜÐ޸ģ¬ÒòΪѡÏî 'modifiable' ÊǹصÄ"
-
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: ½Å±¾Ç¶Ì×¹ýÉî"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: ûÓн»ÌæÎļþ"
-
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ûÓÐÕâ¸öËõд"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ²»ÄÜʹÓà \"!\""
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: ÎÞ·¨Ê¹ÓÃͼÐνçÃæ: ±àÒëʱûÓÐÆôÓÃ"
-
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ûÓÐÕâ¸ö¸ßÁÁȺ×éÃû: %s"
-
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ûÓвåÈë¹ýÎÄ×Ö"
-
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: ûÓÐǰһ¸öÃüÁîÐÐ"
-
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ûÓÐÕâ¸öÓ³Éä"
-
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: ûÓÐÆ¥Åä"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: ûÓÐÆ¥Åä: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ûÓÐÎļþÃû"
-
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: ûÓÐǰһ¸öÌæ»»ÕýÔò±í´ïʽ"
-
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: ûÓÐǰһ¸öÃüÁî"
-
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: ûÓÐǰһ¸öÕýÔò±í´ïʽ"
-
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: ²»ÄÜʹÓ÷¶Î§"
-
-#: ../globals.h:1048
-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
-msgid "E483: Can't get temp file name"
-msgstr "E483: ÎÞ·¨»ñÈ¡ÁÙʱÎļþÃû"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: ÎÞ·¨´ò¿ªÎļþ %s"
-
-#: ../globals.h:1052
-#, 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
-msgid "E38: Null argument"
-msgstr "E38: ¿ÕµÄ²ÎÊý"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: ´Ë´¦ÐèÒªÊý×Ö"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: ÎÞ·¨´ò¿ª´íÎóÎļþ %s"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: ÄÚ´æ²»×㣡"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "ÕÒ²»µ½Ä£Ê½"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: ÕÒ²»µ½Ä£Ê½: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: ²ÎÊý±ØÐëÊÇÕýÊý"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: ÎÞ·¨»Øµ½Ç°Ò»¸öĿ¼"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: ûÓдíÎó"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: ûÓÐ location Áбí"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: ÒÑËð»µµÄÆ¥Åä×Ö·û´®"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: ÒÑË𻵵ÄÕýÔò±í´ïʽ³ÌÐò"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: ÒÑÉ趨ѡÏî 'readonly' (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: ²»ÄܸıäÖ»¶Á±äÁ¿ \"%s\""
-
-#: ../globals.h:1075
-#, fuzzy, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E46: ²»ÄÜÔÚ sandbox ÖÐÉ趨±äÁ¿: \"%s\""
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: ¶ÁÈ¡´íÎóÎļþʧ°Ü"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: ²»ÔÊÐíÔÚ sandbox ÖÐʹÓÃ"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ²»ÔÊÐíÔÚ´ËʹÓÃ"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ²»Ö§³ÖÉ趨ÆÁĻģʽ"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: ÎÞЧµÄ¹ö¶¯´óС"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: Ñ¡Ïî 'shell' Ϊ¿Õ"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: ÎÞ·¨¶ÁÈ¡ sign Êý¾Ý£¡"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: ½»»»Îļþ¹Ø±Õ´íÎó"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: tag ¶ÑջΪ¿Õ"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: ÃüÁî¹ý¸´ÔÓ"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Ãû×Ö¹ý³¤"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: [ ¹ý¶à"
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ÎļþÃû¹ý¶à"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: ¶àÓàµÄβ²¿×Ö·û"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: δ֪µÄ±ê¼Ç"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: ÎÞ·¨À©Õ¹Í¨Åä·û"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ²»ÄÜСÓÚ 'winminheight'"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ²»ÄÜСÓÚ 'winminwidth'"
-
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: дÈë³ö´í"
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "¼ÆÊýΪÁã"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: Ôڽű¾»·¾³ÍâʹÓÃÁË <SID>"
-
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: ÄÚ²¿´íÎó: %s"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: ±í´ïʽµÄÄÚ´æÊ¹Óó¬³ö 'maxmempattern'"
-
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: ¿ÕµÄ»º³åÇø"
-
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: ÎÞЧµÄËÑË÷±í´ïʽ»ò·Ö¸ô·û"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: ÎļþÒÑÔÚÁíÒ»¸ö»º³åÇøÖб»¼ÓÔØ"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: ûÓÐÉ趨ѡÏî '%s'"
-
-#: ../globals.h:1111
-#, fuzzy
-msgid "E850: Invalid register name"
-msgstr "E354: ÎÞЧµÄ¼Ä´æÆ÷Ãû: '%s'"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "ÒѲéÕÒµ½Îļþ¿ªÍ·£¬ÔÙ´Ó½áβ¼ÌÐø²éÕÒ"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "ÒѲéÕÒµ½Îļþ½á⣬ÔÙ´Ó¿ªÍ·¼ÌÐø²éÕÒ"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: ȱÉÙðºÅ"
-
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: ÎÞЧµÄ²¿·Ö"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: Ó¦¸ÃÒªÓÐÊý×Ö"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "µÚ %d Ò³"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "ûÓÐÒª´òÓ¡µÄÎÄ×Ö"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "ÕýÔÚ´òÓ¡µÚ %d Ò³ (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr "¸´ÖÆ %d / %d"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "ÒÑ´òÓ¡: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "´òÓ¡ÖÐÖ¹"
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: дÈë PostScript Êä³öÎļþ³ö´í"
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: ÎÞ·¨´ò¿ªÎļþ \"%s\""
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: ÎÞ·¨¶ÁÈ¡ PostScript ×ÊÔ´Îļþ \"%s\""
-
-#: ../hardcopy.c:1772
-#, 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
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: Îļþ \"%s\" ²»ÊÇÒÑÖ§³ÖµÄ PostScript ×ÊÔ´Îļþ"
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: \"%s\" ×ÊÔ´Îļþ°æ±¾²»ÕýÈ·"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: ²»¼æÈݵĶà×Ö½Ú±àÂëºÍ×Ö·û¼¯¡£"
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: printmbcharset ÔÚ¶à×Ö½Ú±àÂëϲ»ÄÜΪ¿Õ¡£"
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr "E675: ûÓÐÖ¸¶¨¶à×Ö½Ú´òÓ¡µÄĬÈÏ×ÖÌå¡£"
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: ÎÞ·¨´ò¿ª PostScript Êä³öÎļþ"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: ÎÞ·¨´ò¿ªÎļþ \"%s\""
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"prolog.ps\""
-
-#: ../hardcopy.c:2593
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"cidfont.ps\""
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"%s.ps\""
-
-#: ../hardcopy.c:2654
-#, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: ÎÞ·¨×ª»»ÖÁ´òÓ¡±àÂë \"%s\""
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "·¢Ë͵½´òÓ¡»ú¡­¡­"
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: ÎÞ·¨´òÓ¡ PostScript Îļþ"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "´òÓ¡ÈÎÎñÒѱ»·¢ËÍ¡£"
-
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "Ìí¼ÓÒ»¸öеÄÊý¾Ý¿â"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "²éѯһ¸öģʽ"
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "ÏÔʾ´ËÐÅÏ¢"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "½áÊøÒ»¸öÁ¬½Ó"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "ÖØÖÃËùÓÐÁ¬½Ó"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "ÏÔʾÁ¬½Ó"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Ó÷¨: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "Õâ¸ö cscope ÃüÁî²»Ö§³Ö·Ö¸î´°¿Ú¡£\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Ó÷¨: cstag <ident>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: ÕÒ²»µ½ tag"
-
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) ´íÎó: %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s ²»ÊÇĿ¼»òÓÐЧµÄ cscope Êý¾Ý¿â"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "Ìí¼ÓÁË cscope Êý¾Ý¿â %s"
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: ¶ÁÈ¡ cscope Á¬½Ó %<PRId64> ³ö´í"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: δ֪µÄ cscope ²éÕÒÀàÐÍ"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: ÎÞ·¨´´½¨ cscope ¹ÜµÀ"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: ÎÞ·¨¶Ô cscope ½øÐÐ fork"
-
-#: ../if_cscope.c:849
-#, fuzzy
-msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection Ö´ÐÐʧ°Ü"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection Ö´ÐÐʧ°Ü"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen to_fp ʧ°Ü"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen fr_fp ʧ°Ü"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: ÎÞ·¨Éú³É cscope ½ø³Ì"
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: ûÓÐ cscope Á¬½Ó"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: cscopequickfix ±êÖ¾ %c ¶Ô %c ÎÞЧ"
-
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: cscope ²éѯ %s %s ûÓÐÕÒµ½Æ¥ÅäµÄ½á¹û"
-
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "cscope ÃüÁî:\n"
-
-#: ../if_cscope.c:1150
-#, fuzzy, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %-30s (Ó÷¨: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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 ""
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: ÖØ¸´µÄ cscope Êý¾Ý¿âδ±»¼ÓÈë"
-
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: ÕÒ²»µ½ cscope Á¬½Ó %s"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "cscope Á¬½Ó %s ÒѹرÕ"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: cs_manage_matches ÑÏÖØ´íÎó"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Cscope tag: %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # ÐÐ "
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "ÎļþÃû / ÉÏÏÂÎÄ / ÐÐ\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: Cscope ´íÎó: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "ËùÓÐ cscope Êý¾Ý¿âÒѱ»ÖØÖÃ"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "ûÓÐ cscope Á¬½Ó\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid Êý¾Ý¿âÃû prepend path\n"
-
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "δ֪µÄÑ¡Ïî²ÎÊý"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "±à¼­²ÎÊý¹ý¶à"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "ȱÉÙ±ØÒªµÄ²ÎÊý"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "Ñ¡Ïî²ÎÊýºóµÄÄÚÈÝÎÞЧ"
-
-#: ../main.c:152
-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
-#, c-format
-msgid "%d files to edit\n"
-msgstr "»¹ÓÐ %d ¸öÎļþµÈ´ý±à¼­\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "ÊÔͼÔٴδò¿ª½Å±¾Îļþ: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "ÎÞ·¨´ò¿ª²¢¶ÁÈ¡: \""
-
-#: ../main.c:1393
-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"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "pre-vimrc ÃüÁîÐÐ"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: ÎÞ·¨¶ÁÈ¡ \"%s\""
-
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"¸ü¶àÐÅÏ¢Çë¼û: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[Îļþ ..] ±à¼­Ö¸¶¨µÄÎļþ"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- ´Ó±ê×¼ÊäÈë(stdin)¶ÁÈ¡Îı¾"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t tag ±à¼­ tag ¶¨Òå´¦µÄÎļþ"
-
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [errorfile] ±à¼­µÚÒ»¸ö³ö´í´¦µÄÎļþ"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"Ó÷¨:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [²ÎÊý] "
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" »ò:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"²ÎÊý:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tÔÚÕâÒÔºóÖ»ÓÐÎļþÃû"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\t²»À©Õ¹Í¨Åä·û"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tVi ģʽ (ͬ \"vi\")"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tEx ģʽ (ͬ \"ex\")"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\t°²¾²(Åú´¦Àí)ģʽ (Ö»ÄÜÓë \"ex\" Ò»ÆðʹÓÃ)"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tDiff ģʽ (ͬ \"vimdiff\")"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tÈÝÒ×ģʽ (ͬ \"evim\"£¬ÎÞģʽ)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tÖ»¶Áģʽ (ͬ \"view\")"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tÏÞÖÆÄ£Ê½ (ͬ \"rvim\")"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\t²»¿ÉÐÞ¸Ä(дÈëÎļþ)"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tÎı¾²»¿ÉÐÞ¸Ä"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\t¶þ½øÖÆÄ£Ê½"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tLisp ģʽ"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\t¼æÈÝ´«Í³µÄ Vi: 'compatible'"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\t²»ÍêÈ«¼æÈÝ´«Í³µÄ Vi: 'nocompatible'"
-
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr ""
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tµ÷ÊÔģʽ"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\t²»Ê¹Óý»»»Îļþ£¬Ö»Ê¹ÓÃÄÚ´æ"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tÁгö½»»»Îļþ²¢Í˳ö"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (¸úÎļþÃû)\t\t»Ö¸´±ÀÀ£µÄ»á»°"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tͬ -r"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tÒÔ Arabic ģʽÆô¶¯"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tÒÔ Hebrew ģʽÆô¶¯"
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tÒÔ Farsi ģʽÆô¶¯"
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminal>\tÉ趨ÖÕ¶ËÀàÐÍΪ <terminal>"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tʹÓà <vimrc> Ìæ´úÈκΠ.vimrc"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\t²»¼ÓÔØ plugin ½Å±¾"
-
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-P[N]\t\t´ò¿ª N ¸ö±êǩҳ (ĬÈÏÖµ: ÿ¸öÎļþÒ»¸ö)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\t´ò¿ª N ¸ö´°¿Ú (ĬÈÏÖµ: ÿ¸öÎļþÒ»¸ö)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tͬ -o µ«´¹Ö±·Ö¸î"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tÆô¶¯ºóÌøµ½Îļþĩβ"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\tÆô¶¯ºóÌøµ½µÚ <lnum> ÐÐ"
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <command>\t¼ÓÔØÈκΠvimrc ÎļþǰִÐÐ <command>"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <command>\t\t¼ÓÔØµÚÒ»¸öÎļþºóÖ´ÐÐ <command>"
-
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <session>\t\t¼ÓÔØµÚÒ»¸öÎļþºóÖ´ÐÐÎļþ <session>"
-
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <scriptin>\t´ÓÎļþ <scriptin> ¶ÁÈëÕý³£Ä£Ê½µÄÃüÁî"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <scriptout>\t½«ËùÓÐÊäÈëµÄÃüÁî×·¼Óµ½Îļþ <scriptout>"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <scriptout>\t½«ËùÓÐÊäÈëµÄÃüÁîдÈëµ½Îļþ <scriptout>"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr ""
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tʹÓà <viminfo> È¡´ú .viminfo"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h »ò --help\t´òÓ¡°ïÖú(±¾ÐÅÏ¢)²¢Í˳ö"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\t´òÓ¡°æ±¾ÐÅÏ¢²¢Í˳ö"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "ûÓÐÉ趨±ê¼Ç"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: ûÓÐÆ¥Åä \"%s\" µÄ±ê¼Ç"
-
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"±ê¼Ç ÐÐ ÁÐ Îļþ/Îı¾"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-" Ìø×ª ÐÐ ÁÐ Îļþ/Îı¾"
-
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-"\n"
-" ¸Ä±ä ÐÐ ÁÐ Îı¾"
-
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Îļþ±ê¼Ç:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Ìø×ªÁбí (´Óе½¾É):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# ÎļþÄڵıê¼ÇÀúÊ·¼Ç¼ (´Óе½¾É):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "ȱÉÙ '>'"
-
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: ¿éδ±»Ëø¶¨"
-
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: ½»»»Îļþ¶ÁÈ¡¶¨Î»´íÎó"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: ½»»»Îļþ¶ÁÈ¡´íÎó"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: ½»»»ÎļþдÈ붨λ´íÎó"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: ½»»»ÎļþдÈë´íÎó"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: ½»»»ÎļþÒÑ´æÔÚ (·ûºÅÁ¬½Ó¹¥»÷£¿)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: ÕÒ²»µ½¿é 0£¿"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: ÕÒ²»µ½¿é 1£¿"
-
-#: ../memline.c:377
-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
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: àÞ£¬½»»»Îļþ²»¼ûÁË£¡£¡£¡"
-
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: ÎÞ·¨ÖØÃüÃû½»»»Îļþ"
-
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr "E303: ÎÞ·¨´ò¿ª \"%s\" µÄ½»»»Îļþ£¬»Ö¸´½«²»¿ÉÄÜ"
-
-#: ../memline.c:666
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_upd_block0(): ÕÒ²»µ½¿é 0£¿"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: ÕÒ²»µ½ %s µÄ½»»»Îļþ"
-
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr "ÇëÊäÈëҪʹÓõĽ»»»Îļþ±àºÅ (0 Í˳ö): "
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: ÎÞ·¨´ò¿ª %s"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "ÎÞ·¨¶ÁÈ¡¿é 0: "
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"¿ÉÄÜÄãû×ö¹ýÈκÎÐ޸ĻòÊÇ Vim »¹À´²»¼°¸üн»»»Îļþ¡£"
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " ²»ÄÜÔڸð汾µÄ Vim ÖÐʹÓá£\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "ʹÓà Vim 3.0¡£\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %s ¿´ÆðÀ´²»ÏñÊÇ Vim ½»»»Îļþ"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " ²»ÄÜÔÚÕą̂µçÄÔÉÏʹÓá£\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr "´ËÎļþ´´½¨ÓÚ "
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-"£¬\n"
-"»òÊÇ´ËÎļþÒÑË𻵡£"
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr ""
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "ʹÓý»»»Îļþ \"%s\""
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "ԭʼÎļþ \"%s\""
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: ¾¯¸æ: ԭʼÎļþ¿ÉÄÜÒѱ»ÐÞ¸Ä"
-
-#: ../memline.c:1061
-#, 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
-msgid "???MANY LINES MISSING"
-msgstr "???ȱÉÙÁËÌ«¶àÐÐ"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1076
-#, fuzzy
-msgid "???LINE COUNT WRONG"
-msgstr "???ÐÐÊý´íÎó"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1082
-#, fuzzy
-msgid "???EMPTY BLOCK"
-msgstr "???¿ÕµÄ¿é"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1103
-#, fuzzy
-msgid "???LINES MISSING"
-msgstr "???ȱÉÙÁËһЩÐÐ"
-
-#: ../memline.c:1128
-#, 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
-msgid "???BLOCK MISSING"
-msgstr "???ȱÉÙ¿é"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1147
-#, fuzzy
-msgid "??? from here until ???END lines may be messed up"
-msgstr "??? ´ÓÕâÀïµ½ ???END µÄÐпÉÄÜÒÑ»ìÂÒ"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1164
-#, fuzzy
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? ´ÓÕâÀïµ½ ???END µÄÐпÉÄÜÒѱ»²åÈë/ɾ³ý¹ý"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1181
-#, fuzzy
-msgid "???END"
-msgstr "???END"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: »Ö¸´Òѱ»ÖжÏ"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr "E312: »Ö¸´Ê±·¢Éú´íÎó£»Çë×¢Ò⿪ͷΪ ??? µÄÐÐ"
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "¸ü¶àÐÅÏ¢Çë¼û \":help E312\""
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr "»Ö¸´Íê±Ï¡£ÇëÈ·¶¨Ò»ÇÐÕý³£¡£"
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(Äã¿ÉÄÜÏëÒª½«Õâ¸öÎļþÁí´æÎª±ðµÄÎļþÃû\n"
-
-#: ../memline.c:1252
-#, fuzzy
-msgid "and run diff with the original file to check for changes)"
-msgstr "ÔÙÔËÐÐ diff ÓëÔ­Îļþ±È½ÏÒÔ¼ì²éÊÇ·ñÓиıä)\n"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr ""
-
-#: ../memline.c:1255
-#, fuzzy
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"È»ºó°Ñ .swp Îļþɾµô¡£\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "ÕÒµ½½»»»Îļþ:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr " λÓÚµ±Ç°Ä¿Â¼:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " ʹÓÃÖ¸¶¨µÄÃû×Ö:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " λÓÚĿ¼ "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- ÎÞ --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " ËùÓÐÕß: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " ÈÕÆÚ: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " ÈÕÆÚ: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [À´×Ô Vim °æ±¾ 3.0]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [²»ÏñÊÇ Vim ½»»»Îļþ]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " ÎļþÃû: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" Ð޸Ĺý: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "ÊÇ"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "·ñ"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" Óû§Ãû: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " Ö÷»úÃû: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" Ö÷»úÃû: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" ½ø³Ì ID: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (ÈÔÔÚÔËÐÐ)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [²»ÄÜÔÚ±¾»úÉÏʹÓÃ]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [ÎÞ·¨¶ÁÈ¡]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [ÎÞ·¨´ò¿ª]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: ÎÞ·¨±£Áô£¬Ã»Óн»»»Îļþ"
-
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "ÎļþÒѱ£Áô"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: ±£Áôʧ°Ü"
-
-#: ../memline.c:1819
-#, 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>"
-msgstr "E316: ml_get: ÕÒ²»µ½µÚ %<PRId64> ÐÐ"
-
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: Ö¸Õë¿é id ´íÎó 3"
-
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "stack_idx Ó¦¸ÃÊÇ 0"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: ¸üÐÂÁËÌ«¶àµÄ¿é£¿"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: Ö¸Õë¿é id ´íÎó 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "ɾ³ýÁË¿é 1£¿"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: ÕÒ²»µ½µÚ %<PRId64> ÐÐ"
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: Ö¸Õë¿é id ´íÎó"
-
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "pe_line_count ΪÁã"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: Ðкų¬³ö·¶Î§: %<PRId64> ³¬³ö½áβ"
-
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ¿é %<PRId64> ÐÐÊý´íÎó"
-
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "¶ÑÕ»´óСÔö¼Ó"
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: Ö¸Õë¿é id ´íÎó 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr "E773: \"%s\" ·ûºÅÁ¬½Ó³öÏÖÑ­»·"
-
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: ×¢Òâ"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"·¢ÏÖ½»»»Îļþ \""
-
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "ÕýÔÚ´ò¿ªÎļþ \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " ±È½»»»ÎļþУ¡\n"
-
-#: ../memline.c:3244
-#, fuzzy
-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."
-msgstr ""
-"\n"
-"(1) ÁíÒ»¸ö³ÌÐò¿ÉÄÜÒ²Ôڱ༭ͬһ¸öÎļþ¡£\n"
-" Èç¹ûÊÇÕâÑù£¬ÐÞ¸ÄʱÇë×¢Òâ±ÜÃâͬһ¸öÎļþ²úÉúÁ½¸ö²»Í¬µÄ°æ±¾¡£\n"
-"\n"
-
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " Í˳ö£¬»òСÐĵؼÌÐø¡£\n"
-
-#: ../memline.c:3246
-#, fuzzy
-msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) Éϴα༭´ËÎļþʱ±ÀÀ£¡£\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " Èç¹ûÊÇÕâÑù£¬ÇëÓà \":recover\" »ò \"vim -r "
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"\"\n"
-" »Ö¸´Ð޸ĵÄÄÚÈÝ (Çë¼û \":help recovery\")¡£\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " Èç¹ûÄãÒѾ­½øÐÐÁ˻ָ´£¬Çëɾ³ý½»»»Îļþ \""
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"\"\n"
-" ÒÔ±ÜÃâÔÙ¿´µ½´ËÏûÏ¢¡£\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "½»»»Îļþ \""
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "\" ÒÑ´æÔÚ£¡"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "VIM - ×¢Òâ"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "½»»»ÎļþÒÑ´æÔÚ£¡"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"ÒÔÖ»¶Á·½Ê½´ò¿ª(&O)\n"
-"Ö±½Ó±à¼­(&E)\n"
-"»Ö¸´(&R)\n"
-"Í˳ö(&Q)\n"
-"ÖÐÖ¹(&A)"
-
-#: ../memline.c:3467
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"ÒÔÖ»¶Á·½Ê½´ò¿ª(&O)\n"
-"Ö±½Ó±à¼­(&E)\n"
-"»Ö¸´(&R)\n"
-"ɾ³ý½»»»Îļþ(&D)\n"
-"Í˳ö(&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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
-msgid "E326: Too many swap files found"
-msgstr "E326: ÕÒµ½Ì«¶à½»»»Îļþ"
-
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: ÄÚ´æ²»×㣡(·ÖÅä %<PRIu64> ×Ö½Ú)"
-
-#: ../menu.c:62
-msgid "E327: Part of menu-item path is not sub-menu"
-msgstr "E327: ²Ëµ¥ÏîµÄij²¿·Ö·¾¶²»ÊÇ×Ӳ˵¥"
-
-#: ../menu.c:63
-msgid "E328: Menu only exists in another mode"
-msgstr "E328: ²Ëµ¥Ö»ÔÚÆäËüģʽÖдæÔÚ"
-
-#: ../menu.c:64
-#, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: ûÓв˵¥ \"%s\""
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-#, fuzzy
-msgid "E792: Empty menu name"
-msgstr "E749: ¿ÕµÄ»º³åÇø"
-
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: ²Ëµ¥Â·¾¶²»ÄÜÖ¸Ïò×Ӳ˵¥"
-
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: ²»ÄܰѲ˵¥ÏîÖ±½Ó¼Óµ½²Ëµ¥À¸ÖÐ"
-
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: ·Ö¸ôÏß²»ÄÜÊDz˵¥Â·¾¶µÄÒ»²¿·Ö"
-
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- ²Ëµ¥ ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: ²Ëµ¥Â·¾¶±ØÐëÖ¸Ïò²Ëµ¥Ïî"
-
-#: ../menu.c:1330
-#, 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
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: ²Ëµ¥Â·¾¶±ØÐëÖ¸Ïò×Ӳ˵¥"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: ÕÒ²»µ½²Ëµ¥ - Çë¼ì²é²Ëµ¥Ãû³Æ"
-
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "´¦Àí %s ʱ·¢Éú´íÎó:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "µÚ %4ld ÐÐ:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: ÎÞЧµÄ¼Ä´æÆ÷Ãû: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "¼òÌåÖÐÎÄÏûϢά»¤Õß: Yuheng Xie <elephant@linux.net.cn>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "ÒÑÖжÏ: "
-
-#: ../message.c:988
-msgid "Press ENTER or type command to continue"
-msgstr "Çë°´ ENTER »òÆäËüÃüÁî¼ÌÐø"
-
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s µÚ %<PRId64> ÐÐ"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- ¸ü¶à --"
-
-#: ../message.c:2398
-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
-msgid "Question"
-msgstr "ÎÊÌâ"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"ÊÇ(&Y)\n"
-"·ñ(&N)"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"ÊÇ(&Y)\n"
-"·ñ(&N)\n"
-"È¡Ïû(&C)"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"ÊÇ(&Y)\n"
-"·ñ(&N)\n"
-"È«²¿±£´æ(&A)\n"
-"È«²¿¶ªÆú(&D)\n"
-"È¡Ïû(&C)"
-
-#: ../message.c:3058
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: printf() µÄ²ÎÊý²»×ã"
-
-#: ../message.c:3119
-#, fuzzy
-msgid "E807: Expected Float argument for printf()"
-msgstr "E766: 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
-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
-msgid "E348: No string under cursor"
-msgstr "E348: ¹â±ê´¦Ã»ÓÐ×Ö·û´®"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: ²»ÄÜÔÚµ±Ç°µÄ 'foldmethod' ÏÂɾ³ý fold"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: ¸Ä±äÁбíΪ¿Õ"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr "E662: ÒÑÔڸıäÁбíµÄ¿ªÊ¼´¦"
-
-#: ../normal.c:5901
-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 ´Î"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 ÐÐ %s ÁË %d ´Î"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> ÐÐ %s ÁË 1 ´Î"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> ÐÐ %s ÁË %d ´Î"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "Ëõ½ø %<PRId64> ÐС­¡­ "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "Ëõ½øÁË 1 ÐÐ "
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "Ëõ½øÁË %<PRId64> ÐÐ "
-
-#: ../ops.c:938
-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
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "¸Ä±äÁË %<PRId64> ÐÐ"
-
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "¸´ÖÆÁË 1 ÐеĿé"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "¸´ÖÆÁË 1 ÐÐ"
-
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "¸´ÖÆÁË %<PRId64> ÐеĿé"
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "¸´ÖÆÁË %<PRId64> ÐÐ"
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353: ¼Ä´æÆ÷ %s ÀïûÓж«Î÷"
-
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- ¼Ä´æÆ÷ ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "ÎÞЧµÄ¼Ä´æÆ÷Ãû"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# ¼Ä´æÆ÷:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: δ֪µÄ¼Ä´æÆ÷ÀàÐÍ %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> ÁÐ; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Ñ¡ÔñÁË %s%<PRId64>/%<PRId64> ÐÐ; %<PRId64>/%<PRId64> ¸ö´Ê; %<PRId64>/"
-"%<PRId64> ¸ö×Ö½Ú"
-
-#: ../ops.c:5105
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Ñ¡ÔñÁË %s%<PRId64>/%<PRId64> ÐÐ; %<PRId64>/%<PRId64> ¸ö´Ê; %<PRId64>/"
-"%<PRId64> ¸ö×Ö·û; %<PRId64>/%<PRId64> ¸ö×Ö½Ú"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"µÚ %s/%s ÁÐ; µÚ %<PRId64>/%<PRId64> ÐÐ; µÚ %<PRId64>/%<PRId64> ¸ö´Ê; µÚ "
-"%<PRId64>/%<PRId64> ¸ö×Ö½Ú"
-
-#: ../ops.c:5133
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"µÚ %s/%s ÁÐ; µÚ %<PRId64>/%<PRId64> ÐÐ; µÚ %<PRId64>/%<PRId64> ¸ö´Ê; µÚ "
-"%<PRId64>/%<PRId64> ¸ö×Ö·û; µÚ %<PRId64>/%<PRId64> ¸ö×Ö½Ú"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr ""
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr ""
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "¸ÐлÄúÑ¡Ôñ Vim"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: δ֪µÄÑ¡Ïî"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: ²»Ö§³Ö¸ÃÑ¡Ïî"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: ²»ÔÊÐíÔÚ modeline ÖÐʹÓÃ"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr ""
-
-#: ../option.c:2924
-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 ""
-
-#: ../option.c:3966
-msgid "E835: Conflicts with value of 'fillchars'"
-msgstr ""
-
-#: ../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
-msgid "E590: A preview window already exists"
-msgstr "E590: Ô¤ÀÀ´°¿ÚÒÑ´æÔÚ"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: Arabic ÐèÒª UTF-8£¬ÇëÖ´ÐÐ ':set encoding=utf-8'"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: ÖÁÉÙÐèÒª %d ÐÐ"
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: ÖÁÉÙÐèÒª %d ÁÐ"
-
-#: ../option.c:6011
-#, 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
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: = ºóÃæÐèÒªÊý×Ö"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- Öն˱àÂë ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- È«¾ÖÑ¡ÏîÖµ ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- ¾Ö²¿Ñ¡ÏîÖµ ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- Ñ¡Ïî ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: get_varp ´íÎó"
-
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': ÕÒ²»µ½ %s ¶ÔÓ¦µÄ×Ö·û"
-
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': ·ÖºÅºóÓжàÓàµÄ×Ö·û: %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"ÎÞ·¨Ö´ÐÐ shell"
-
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"Shell ÒÑ·µ»Ø"
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-
-# do not translate
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = \"%s\""
-
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: ÔÚ·¾¶ÖÐÕÒ²»µ½Îļþ \"%s\""
-
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: ¸ñʽ»¯×Ö·û´®ÀïÓÐÌ«¶à %%%c "
-
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: ¸ñʽ»¯×Ö·û´®²»Ó¦¸Ã³öÏÖ %%%c "
-
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: ¸ñʽ»¯×Ö·û´®ÀïÉÙÁË ]"
-
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: ¸ñʽ»¯×Ö·û´®ÀïÓв»Ö§³ÖµÄ %%%c "
-
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: ¸ñʽ»¯×Ö·û´®¿ªÍ·ÀïÓв»ÕýÈ·µÄ %%%c "
-
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: ¸ñʽ»¯×Ö·û´®ÀïÓв»ÕýÈ·µÄ %%%c "
-
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: 'errorformat' δÉ趨"
-
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: ÕÒ²»µ½Ä¿Â¼Ãû³Æ»òÊǿյÄĿ¼Ãû³Æ"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: ûÓиü¶àµÄÏî"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d / %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (ÐÐÒÑɾ³ý)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: Quickfix ¶ÑÕ»µ×¶Ë"
-
-#: ../quickfix.c:1869
-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:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr "E683: ȱÉÙÎļþÃû»òģʽÎÞЧ"
-
-#: ../quickfix.c:2911
-#, c-format
-msgid "Cannot open file \"%s\""
-msgstr "ÎÞ·¨´ò¿ªÎļþ \"%s\""
-
-#: ../quickfix.c:3429
-msgid "E681: Buffer is not loaded"
-msgstr "E681: »º³åÇøÎ´¼ÓÔØ"
-
-#: ../quickfix.c:3487
-msgid "E777: String or List expected"
-msgstr "E777: ´Ë´¦ÐèÒª String »òÕß List"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: %s%%[] ÖÐÓÐÎÞЧµÄÏî"
-
-#: ../regexp.c:374
-#, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E769: %s[ ºóȱÉÙ ]"
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: ²»Æ¥ÅäµÄ %s%%("
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: ²»Æ¥ÅäµÄ %s("
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: ²»Æ¥ÅäµÄ %s)"
-
-#: ../regexp.c:378
-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:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: %s%%[ ºóȱÉÙ ]"
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: ¿ÕµÄ %s%%[]"
-
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: ģʽ̫³¤"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: Ì«¶à \\z("
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: Ì«¶à %s("
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: ²»Æ¥ÅäµÄ \\z("
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: %s@ ºóÃæÓÐÎÞЧµÄ×Ö·û"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: Ì«¶à¸´Ô %s{...}s"
-
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: ǶÌ×µÄ %s*"
-
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: ǶÌ×µÄ %s%c"
-
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: ²»ÕýÈ·µØÊ¹Óà \\_"
-
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c Ç°ÃæÎÞÄÚÈÝ"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: ÎÞЧµÄ»ØÒý"
-
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: \\z ºóÃæÓÐÎÞЧµÄ×Ö·û"
-
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: %s%%[dxouU] ºóÃæÓÐÎÞЧµÄ×Ö·û"
-
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: %s%% ºóÃæÓÐÎÞЧµÄ×Ö·û"
-
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: %s{...} ÖÐÓï·¨´íÎó"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "Íⲿ·ûºÏ:\n"
-
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr ""
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-
-#. 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 ""
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
-
-#: ../regexp_nfa.c:2042
-#, fuzzy
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: Ì«¶à \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr ""
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
-
-#: ../regexp_nfa.c:6049
-#, fuzzy
-msgid "Could not open temporary log file for writing "
-msgstr "E214: ÕÒ²»µ½ÓÃÓÚдÈëµÄÁÙʱÎļþ"
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " V-Ìæ»»"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " Ìæ»»"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " ·´Ïò"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " ²åÈë"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (²åÈë)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (Ìæ»»)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (V-Ìæ»»)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " Hebrew"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " Arabic"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (ÓïÑÔ)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (Õ³Ìû)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " ¿ÉÊÓ"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " ¿ÉÊÓ ÐÐ"
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " ¿ÉÊÓ ¿é"
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " Ñ¡Ôñ"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " Ñ¡Ôñ ÐÐ"
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " Ñ¡Ôñ ¿é"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "¼Ç¼ÖÐ"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: ÎÞЧµÄ²éÕÒ×Ö·û´®: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: ÒѲéÕÒµ½Îļþ¿ªÍ·ÈÔÕÒ²»µ½ %s"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: ÒѲéÕÒµ½Îļþ½áβÈÔÕÒ²»µ½ %s"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: ÔÚ ';' ºóÃæÓ¦¸ÃÓÐ '?' »ò '/'"
-
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (°üÀ¨ÉÏ´ÎÁгö·ûºÏÏî)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- °üº¬Îļþ "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "ÕÒ²»µ½ "
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "ÔÚ·¾¶ ---\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (ÒÑÁгö)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " ÕÒ²»µ½"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "²éÕÒ°üº¬Îļþ: %s"
-
-#: ../search.c:4216
-#, c-format
-msgid "Searching included file %s"
-msgstr "²éÕÒ°üº¬µÄÎļþ %s"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: µ±Ç°ÐÐÆ¥Åä"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "ËùÓаüº¬Îļþ¶¼ÒÑÕÒµ½"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "ûÓаüº¬Îļþ"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: ÕÒ²»µ½¶¨Òå"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: ÕÒ²»µ½ pattern"
-
-#: ../search.c:4668
-#, fuzzy
-msgid "Substitute "
-msgstr "1 ´ÎÌæ»»£¬"
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: ƴдÎļþ¸ñʽ´íÎó"
-
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr "E758: ÒÑ½Ø¶ÏµÄÆ´Ð´Îļþ"
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬¶àÓàµÄºóÐø×Ö·û: %s"
-
-#: ../spell.c:954
-#, 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
-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
-#, c-format
-msgid "Reading spell file \"%s\""
-msgstr "¶ÁȡƴдÎļþ \"%s\""
-
-#: ../spell.c:2496
-msgid "E757: This does not look like a spell file"
-msgstr "E757: Õâ¿´ÆðÀ´²»ÏñÊÇÆ´Ð´Îļþ"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: ¾É°æ±¾µÄƴдÎļþ£¬ÐèÒª¸üÐÂ"
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr "E772: Ϊ¸ü¸ß°æ±¾µÄ Vim ËùÓÃµÄÆ´Ð´Îļþ"
-
-#: ../spell.c:2602
-msgid "E770: Unsupported section in spell file"
-msgstr "E770: ƴдÎļþÖдæÔÚ²»Ö§³ÖµÄ½Ú"
-
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "¾¯¸æ: ÇøÓò %s ²»Ö§³Ö"
-
-#: ../spell.c:4550
-#, c-format
-msgid "Reading affix file %s ..."
-msgstr "¶ÁÈ¡¸½¼ÓÎļþ %s ¡­¡­"
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr "µ¥´Ê %s ת»»Ê§°Ü£¬µÚ %d ÐÐ: %s"
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr "²»Ö§³Ö %s ÖеÄת»»: ´Ó %s µ½ %s"
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬FLAG µÄÖµÎÞЧ: %s"
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬ÔÚʹÓñêÖ¾ºó³öÏÖ FLAG: %s"
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-
-#: ../spell.c:4747
-#, fuzzy, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDMIN Öµ: %s"
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDWORDMAX Öµ: %s"
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDMIN Öµ: %s"
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDSYLMAX Öµ: %s"
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ CHECKCOMPOUNDPATTERN Öµ: %s"
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬ÔÚÁ¬ÐøµÄ¸½¼Ó¿éÖгöÏÖ²»Í¬µÄ×éºÏ±êÖ¾: %s"
-
-#: ../spell.c:4850
-#, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Öظ´µÄ¸½¼ÓÏî: %s"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-"%s µÚ %d ÐУ¬¸½¼ÓÏî±» BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST ʹ"
-"ÓÃ: %s"
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª Y »ò N: %s"
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄÌõ¼þ: %s"
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª REP(SAL) ¼ÆÊý"
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª MAP ¼ÆÊý"
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr "%s µÚ %d ÐУ¬MAP ÖдæÔÚÖØ¸´µÄ×Ö·û"
-
-#: ../spell.c:5176
-#, 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
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr "ÔÚûÓÐ SYLLABLE µÄÇé¿öÏÂʹÓÃÁË COMPOUNDSYLMAX"
-
-#: ../spell.c:5236
-msgid "Too many postponed prefixes"
-msgstr "Ì«¶àÑÓ³Ùǰ׺"
-
-#: ../spell.c:5238
-msgid "Too many compound flags"
-msgstr "Ì«¶à×éºÏ±êÖ¾"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr "Ì«¶àÑÓ³Ùǰ׺ºÍ/»ò×éºÏ±êÖ¾"
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr "%s ÖÐȱÉÙ SOFO%s ÐÐ"
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr "%s ͬʱ³öÏÖ SQL ºÍ SOFO ÐÐ"
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬±êÖ¾²»ÊÇÊý×Ö: %s"
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬ÎÞЧµÄ±êÖ¾: %s"
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr "%s µÄÖµÓëÁíÒ»¸ö .aff ÎļþÖÐʹÓõÄÖµ²»Ïàͬ"
-
-#: ../spell.c:5602
-#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "¶ÁÈ¡×ÖµäÎļþ %s ¡­¡­"
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr "E760: %s ÖÐûÓе¥´Ê¼ÆÊý"
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "µÚ %6d ÐУ¬µÚ %6d ¸öµ¥´Ê - %s"
-
-#: ../spell.c:5691
-#, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Öظ´µÄµ¥´Ê: %s"
-
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Ê×´ÎÖØ¸´µÄµ¥´Ê: %s"
-
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr "´æÔÚ %d ¸öÖØ¸´µÄµ¥´Ê£¬ÔÚ %s ÖÐ"
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr "ºöÂÔÁ˺¬ÓÐ·Ç ASCII ×Ö·ûµÄ %d ¸öµ¥´Ê£¬ÔÚ %s ÖÐ"
-
-#: ../spell.c:6115
-#, c-format
-msgid "Reading word file %s ..."
-msgstr "¶ÁÈ¡µ¥´ÊÎļþ %s ¡­¡­"
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬µ¥´ÊºóµÄ /encoding= ÐÐÒѱ»ºöÂÔ: %s"
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Öظ´µÄ /regions= ÐÐÒѱ»ºöÂÔ: %s"
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Ì«¶àÇøÓò: %s"
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬/ ÐÐÒѱ»ºöÂÔ: %s"
-
-#: ../spell.c:6224
-#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬ÎÞЧµÄÇøÓòºÅ: %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬²»¿Éʶ±ðµÄ±êÖ¾: %s"
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr "ºöÂÔÁ˺¬ÓÐ·Ç ASCII ×Ö·ûµÄ %d ¸öµ¥´Ê"
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "ѹËõÁË %d/%d ¸ö½Úµã£»Ê£Óà %d (%d%%)"
-
-#: ../spell.c:7340
-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
-msgid "Performing soundfolding..."
-msgstr "ÕýÔÚ soundfolding¡­¡­"
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "soundfolding ºóµÄµ¥´ÊÊý: %<PRId64>"
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr "µ¥´Ê×ÜÊý: %d"
-
-#: ../spell.c:7655
-#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "дÈ뽨ÒéÎļþ %s ¡­¡­"
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr "¹À¼ÆÔËÐÐʱÄÚ´æÓÃÁ¿: %d ×Ö½Ú"
-
-#: ../spell.c:7820
-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 ¸öÇøÓò"
-
-#: ../spell.c:7846
-#, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E755: %s ³öÏÖÎÞЧµÄ·¶Î§"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr "¾¯¸æ: ͬʱָ¶¨ÁË compounding ºÍ NOBREAK"
-
-#: ../spell.c:7920
-#, c-format
-msgid "Writing spell file %s ..."
-msgstr "дÈëÆ´Ð´Îļþ %s ¡­¡­"
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr "Íê³É£¡"
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ûÓÐ %<PRId64> Ïî"
-
-#: ../spell.c:8074
-#, fuzzy, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "´Ó %s ÖÐɾ³ýÁ˵¥´Ê"
-
-#: ../spell.c:8117
-#, fuzzy, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "Ïò %s ÖÐÌí¼ÓÁ˵¥´Ê"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: ƴдÎļþÖ®¼äµÄ×Ö·û²»Ïàͬ"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "±§Ç¸£¬Ã»Óн¨Òé"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "±§Ç¸£¬Ö»ÓÐ %<PRId64> Ìõ½¨Òé"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "½« \"%.*s\" ¸ÄΪ£º"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: ֮ǰûÓÐÆ´Ð´Ìæ»»"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: ÕÒ²»µ½: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: ¿´ÆðÀ´²»ÏñÊÇ .sug Îļþ: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr ""
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr ""
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr ""
-
-#: ../spell.c:9305
-#, fuzzy, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E47: ¶ÁÈ¡´íÎóÎļþʧ°Ü"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr ""
-
-#: ../syntax.c:266
-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:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: ÎÞ´ËÓï·¨ cluster: \"%s\""
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "C·ç¸ñ×¢ÊÍͬ²½ÖÐ"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "ûÓÐͬ²½"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "ͬ²½¿ªÊ¼"
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr "Ðкų¬³ö·¶Î§"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- Ó﷨ͬ²½ÏîÄ¿ (Syntax sync items) ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"ͬ²½ÖÐ:"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- Óï·¨ÏîÄ¿ ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: ÎÞ´ËÓï·¨ cluster: \"%s\""
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "×îС"
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "×î´ó"
-
-#: ../syntax.c:3513
-#, fuzzy
-msgid "; match "
-msgstr "Æ¥Åä %d"
-
-#: ../syntax.c:3515
-#, fuzzy
-msgid " line breaks"
-msgstr "ÉÙÓÚÒ»ÐÐ"
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
-
-#: ../syntax.c:4096
-#, fuzzy
-msgid "E844: invalid cchar value"
-msgstr "E474: ÎÞЧµÄ²ÎÊý"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: ÕÒ²»µ½ %s µÄ region item"
-
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: ÐèÒªÎļþÃû³Æ"
-
-#: ../syntax.c:4221
-#, fuzzy
-msgid "E847: Too many syntax includes"
-msgstr "E77: ÎļþÃû¹ý¶à"
-
-#: ../syntax.c:4303
-#, fuzzy, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E747: ȱÉÙ ']': %s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: ȱÉÙ '=': %s"
-
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: syntax region %s µÄ²ÎÊýÌ«ÉÙ"
-
-#: ../syntax.c:4870
-#, fuzzy
-msgid "E848: Too many syntax clusters"
-msgstr "E391: ÎÞ´ËÓï·¨ cluster: \"%s\""
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: ûÓÐÖ¸¶¨µÄÊôÐÔ"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: ÕÒ²»µ½·Ö¸ô·ûºÅ: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: '%s' ºóÃæµÄ¶«Î÷²»ÄÜʶ±ð"
-
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: Ó﷨ͬ²½: Á¬½ÓÐзûºÅÖ¸¶¨ÁËÁ½´Î"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: ÎÞЧµÄ²ÎÊý: %s"
-
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: ȱÉٵȺÅ: %s"
-
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: ¿ÕµÄ²ÎÊý: %s"
-
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %s ²»ÄÜÔڴ˳öÏÖ"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %s ±ØÐëÊÇÁбíÀïµÄµÚÒ»¸ö"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: ²»ÕýÈ·µÄ×éÃû: %s"
-
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: ²»ÕýÈ·µÄ :syntax ×ÓÃüÁî: %s"
-
-#: ../syntax.c:5854
-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: ×éÃûÖдæÔÚ²»¿ÉÏÔʾ×Ö·û"
-
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: ×éÃûÖк¬ÓÐÎÞЧ×Ö·û"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr ""
-
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: ÒÑÔÚ tag ¶ÑÕ»µ×²¿"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: ÒÑÔÚ tag ¶ÑÕ»¶¥²¿"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Òѵ½µÚÒ»¸öÆ¥ÅäµÄ tag"
-
-#: ../tag.c:504
-#, 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
-msgid "E427: There is only one matching tag"
-msgstr "E427: Ö»ÓÐÒ»¸öÆ¥ÅäµÄ tag"
-
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: ¼ºµ½×îºóÒ»¸öÆ¥ÅäµÄ tag"
-
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "Îļþ \"%s\" ²»´æÔÚ"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "ÕÒµ½ tag: %d / %d%s"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " »ò¸ü¶à"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " ÒÔ²»Í¬´óСдÀ´Ê¹Óà tag£¡"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: Îļþ \"%s\" ²»´æÔÚ"
-
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # µ½ tag ´Ó ÐÐ ÔÚ Îļþ/Îı¾"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "²éÕÒ tag Îļþ %s"
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr ""
-
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: Tag Îļþ \"%s\" ¸ñʽ´íÎó"
-
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "ÔÚµÚ %<PRId64> ×Ö½Ú֮ǰ"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Tag ÎļþδÅÅÐò: %s"
-
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: ûÓÐ tag Îļþ"
-
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: ÕÒ²»µ½ tag ģʽ"
-
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: ÕÒ²»µ½ tag£¬ÊÔ×Ų£¡"
-
-#: ../tag.c:2797
-#, fuzzy, c-format
-msgid "Duplicate field name: %s"
-msgstr "%s µÚ %d ÐУ¬Öظ´µÄ¸½¼ÓÏî: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' δ֪¡£¿ÉÓõÄÄÚ½¨ÖÕ¶ËÓÐ:"
-
-#: ../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 ÖÐÕÒ²»µ½ÖÕ¶ËÏî"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: termcap ÖÐûÓÐ \"%s\" Ïî"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: ÖÕ¶ËÐèÒªÄÜÁ¦ \"cm\""
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Öն˰´¼ü ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: ¶Á´íÎó£¬Í˳öÖÐ...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
-msgid "E881: Line count changed unexpectedly"
-msgstr "E787: ÒâÍâµØ¸Ä±äÁË»º³åÇø"
-
-#: ../undo.c:627
-#, fuzzy, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E212: ÎÞ·¨´ò¿ª²¢Ð´ÈëÎļþ"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr ""
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr ""
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr ""
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr ""
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr ""
-
-#: ../undo.c:1121
-#, fuzzy, c-format
-msgid "Writing undo file: %s"
-msgstr "дÈë viminfo Îļþ \"%s\""
-
-#: ../undo.c:1213
-#, fuzzy, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E297: ½»»»ÎļþдÈë´íÎó"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr ""
-
-#: ../undo.c:1292
-#, fuzzy, c-format
-msgid "Reading undo file: %s"
-msgstr "¶ÁÈ¡µ¥´ÊÎļþ %s ¡­¡­"
-
-#: ../undo.c:1299
-#, fuzzy, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E195: ÎÞ·¨´ò¿ª²¢¶ÁÈ¡ viminfo Îļþ"
-
-#: ../undo.c:1308
-#, fuzzy, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E753: ÕÒ²»µ½: %s"
-
-#: ../undo.c:1313
-#, fuzzy, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E484: ÎÞ·¨´ò¿ªÎļþ %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr ""
-
-#: ../undo.c:1497
-#, fuzzy, c-format
-msgid "Finished reading undo file %s"
-msgstr "½áÊøÖ´ÐÐ %s"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr "ÒÑλÓÚ×î¾ÉµÄ¸Ä±ä"
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr "ÒÑλÓÚ×îеĸıä"
-
-#: ../undo.c:1806
-#, fuzzy, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "ÕÒ²»µ½³·ÏúºÅ %<PRId64>"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: ÐкŴíÎó"
-
-#: ../undo.c:2183
-msgid "more line"
-msgstr "Ðб»¼ÓÈë"
-
-#: ../undo.c:2185
-msgid "more lines"
-msgstr "Ðб»¼ÓÈë"
-
-#: ../undo.c:2187
-msgid "line less"
-msgstr "Ðб»È¥µô"
-
-#: ../undo.c:2189
-msgid "fewer lines"
-msgstr "Ðб»È¥µô"
-
-#: ../undo.c:2193
-msgid "change"
-msgstr "Ðз¢Éú¸Ä±ä"
-
-#: ../undo.c:2195
-msgid "changes"
-msgstr "Ðз¢Éú¸Ä±ä"
-
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s£»%s #%<PRId64> %s"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr "before"
-
-#: ../undo.c:2228
-msgid "after"
-msgstr "after"
-
-#: ../undo.c:2325
-msgid "Nothing to undo"
-msgstr "Î޿ɳ·Ïú"
-
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr ""
-
-#: ../undo.c:2360
-#, fuzzy, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> ÁÐ; "
-
-#: ../undo.c:2372
-#, fuzzy
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E407: %s ²»ÄÜÔڴ˳öÏÖ"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: ³·ÏúÁбíËð»µ"
-
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: ÕÒ²»µ½Òª³·ÏúµÄÐÐ"
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"°üº¬²¹¶¡: "
-
-#: ../version.c:627
-#, fuzzy
-msgid ""
-"\n"
-"Extra patches: "
-msgstr "Íⲿ·ûºÏ:\n"
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "ÐÞ¸ÄÕß "
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"±àÒë"
-
-#: ../version.c:649
-msgid "by "
-msgstr "Õß "
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"¾ÞÐͰ汾 "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "ÎÞͼÐνçÃæ¡£"
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " ¿ÉʹÓÃ(+)Óë²»¿ÉʹÓÃ(-)µÄ¹¦ÄÜ:\n"
-
-#: ../version.c:667
-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
-msgid " fall-back for $VIM: \""
-msgstr " $VIM Ô¤ÉèÖµ: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr " $VIMRUNTIME Ô¤ÉèÖµ: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "±àÒ뷽ʽ: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Á´½Ó·½Ê½: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " µ÷ÊÔ°æ±¾"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi IMproved"
-
-#: ../version.c:769
-msgid "version "
-msgstr "°æ±¾ "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "ά»¤ÈË Bram Moolenaar µÈ"
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim ÊÇ¿É×ÔÓÉ·Ö·¢µÄ¿ª·ÅÔ´´úÂëÈí¼þ"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "°ïÖúÎڸɴïµÄ¿ÉÁ¯¶ùͯ£¡"
-
-#: ../version.c:777
-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
-msgid "Sponsor Vim development!"
-msgstr "ÔÞÖú Vim µÄ¿ª·¢£¡"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "³ÉΪ Vim µÄ×¢²áÓû§£¡"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr "ÊäÈë :help sponsor<Enter> ²é¿´ËµÃ÷ "
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr "ÊäÈë :help register<Enter> ²é¿´ËµÃ÷ "
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "²Ëµ¥ Help->Sponsor/Register ²é¿´ËµÃ÷ "
-
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "ÒѾ­Ö»Ê£Ò»¸ö´°¿ÚÁË"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: ûÓÐÔ¤ÀÀ´°¿Ú"
-
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: ²»ÄÜͬʱ½øÐÐ topleft ºÍ botright ·Ö¸î"
-
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: ÓÐÆäËü·Ö¸î´°¿Úʱ²»ÄÜÐýת"
-
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: ²»ÄܹرÕ×îºóÒ»¸ö´°¿Ú"
-
-#: ../window.c:1810
-#, fuzzy
-msgid "E813: Cannot close autocmd window"
-msgstr "E444: ²»ÄܹرÕ×îºóÒ»¸ö´°¿Ú"
-
-#: ../window.c:1814
-#, fuzzy
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E444: ²»ÄܹرÕ×îºóÒ»¸ö´°¿Ú"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: ÆäËü´°¿ÚÓиıäµÄÄÚÈÝ"
-
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: ¹â±ê´¦Ã»ÓÐÎļþÃû"
-
-#~ msgid "Patch file"
-#~ msgstr "Patch Îļþ"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "È·¶¨(&O)\n"
-#~ "È¡Ïû(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: ûÓе½ Vim ·þÎñÆ÷µÄÁ¬½Ó"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: ÎÞ·¨·¢Ë͵½ %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: ÎÞ·¨¶ÁÈ¡·þÎñÆ÷ÏìÓ¦"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: ÎÞ·¨·¢Ë͵½¿Í»§¶Ë"
-
-#~ msgid "Save As"
-#~ msgstr "Áí´æÎª"
-
-#~ msgid "Edit File"
-#~ msgstr "±à¼­Îļþ"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (ÕÒ²»µ½)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Ö´ÐÐ Vim ½Å±¾"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "ÔÚд°¿Ú±à¼­Îļþ"
-
-#~ msgid "Append File"
-#~ msgstr "×·¼ÓÎļþ"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "´°¿ÚλÖÃ: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "±£´æÖض¨Ïò"
-
-#~ msgid "Save View"
-#~ msgstr "±£´æÊÓͼ"
-
-#~ msgid "Save Session"
-#~ msgstr "±£´æ»á»°"
-
-#~ msgid "Save Setup"
-#~ msgstr "±£´æÉ趨"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ´Ë°æ±¾ÎÞ¸´ºÏ×Ö·û(digraph)"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "´Ó±ê×¼ÊäÈë¶ÁÈ¡..."
-
-#~ msgid "[NL found]"
-#~ msgstr "[ÕÒµ½ NL]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[ÒѼÓÃÜ]"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans ²»ÔÊÐíδÐ޸ĵĻº³åÇøÐ´Èë"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeans ²»ÔÊÐí»º³åÇø²¿·ÖдÈë"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Resource fork »á¶ªÊ§ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: ÎÞ·¨Æô¶¯Í¼ÐνçÃæ"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: ÎÞ·¨¶ÁÈ¡Îļþ \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: ÎÞ·¨Æô¶¯Í¼ÐνçÃæ£¬ÕÒ²»µ½ÓÐЧµÄ×ÖÌå"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: ÎÞЧµÄ 'guifontwide'"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' µÄÖµÎÞЧ"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: ÎÞ·¨·ÖÅäÑÕÉ« %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "ÔÚ¹â±ê´¦Ã»ÓÐÆ¥Å䣬²éÕÒÏÂÒ»¸ö"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<ÎÞ·¨´ò¿ª>"
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ÎÞ·¨»ñÈ¡×ÖÌå %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ÎÞ·¨·µ»Øµ±Ç°Ä¿Â¼"
-
-#~ msgid "Pathname:"
-#~ msgstr "·¾¶:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ÎÞ·¨»ñÈ¡µ±Ç°Ä¿Â¼"
-
-#~ msgid "OK"
-#~ msgstr "È·¶¨"
-
-#~ msgid "Cancel"
-#~ msgstr "È¡Ïû"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "¹ö¶¯Ìõ²¿¼þ: ÎÞ·¨»ñÈ¡»¬¿éͼÏñµÄ¼¸ºÎ´óС"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim ¶Ô»°¿ò"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: ²»ÄÜͬʱʹÓÃÏûÏ¢ºÍ»Øµ÷º¯ÊýÀ´´´½¨ BalloonEval"
-
-#~ msgid "Vim dialog..."
-#~ msgstr "Vim ¶Ô»°¿ò..."
-
-#~ msgid "Input _Methods"
-#~ msgstr "ÊäÈë·¨(_M)"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - ²éÕÒºÍÌæ»»..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - ²éÕÒ..."
-
-#~ msgid "Find what:"
-#~ msgstr "²éÕÒÄÚÈÝ:"
-
-#~ msgid "Replace with:"
-#~ msgstr "Ìæ»»Îª:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Æ¥ÅäÍêÕûµÄ´Ê"
-
-#~ msgid "Match case"
-#~ msgstr "Æ¥Åä´óСд"
-
-#~ msgid "Direction"
-#~ msgstr "·½Ïò"
-
-#~ msgid "Up"
-#~ msgstr "ÏòÉÏ"
-
-#~ msgid "Down"
-#~ msgstr "ÏòÏÂ"
-
-#~ msgid "Find Next"
-#~ msgstr "²éÕÒÏÂÒ»¸ö"
-
-#~ msgid "Replace"
-#~ msgstr "Ìæ»»"
-
-#~ msgid "Replace All"
-#~ msgstr "È«²¿Ìæ»»"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: ´Ó»á»°¹ÜÀíÆ÷ÊÕµ½ \"die\" ÇëÇó\n"
-
-#~ msgid "Close"
-#~ msgstr "¹Ø±Õ"
-
-#~ msgid "New tab"
-#~ msgstr "н¨±êÇ©"
-
-#~ msgid "Open Tab..."
-#~ msgstr "´ò¿ª±êÇ©..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Ö÷´°¿Ú±»ÒâÍâµØ´Ý»Ù\n"
-
-#~ msgid "Font Selection"
-#~ msgstr "Ñ¡Ôñ×ÖÌå"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "ʹÓà CUT_BUFFER0 À´È¡´ú¿ÕÑ¡Ôñ"
-
-#~ msgid "&Filter"
-#~ msgstr "¹ýÂË(&F)"
-
-#~ msgid "&Cancel"
-#~ msgstr "È¡Ïû(&C)"
-
-#~ msgid "Directories"
-#~ msgstr "Ŀ¼"
-
-#~ msgid "Filter"
-#~ msgstr "¹ýÂËÆ÷"
-
-#~ msgid "&Help"
-#~ msgstr "°ïÖú(&H)"
-
-#~ msgid "Files"
-#~ msgstr "Îļþ"
-
-#~ msgid "&OK"
-#~ msgstr "È·¶¨(&O)"
-
-#~ msgid "Selection"
-#~ msgstr "Ñ¡Ôñ"
-
-#~ msgid "Find &Next"
-#~ msgstr "²éÕÒÏÂÒ»¸ö(&N)"
-
-#~ msgid "&Replace"
-#~ msgstr "Ìæ»»(&R)"
-
-#~ msgid "Replace &All"
-#~ msgstr "È«²¿Ìæ»»(&A)"
-
-#~ msgid "&Undo"
-#~ msgstr "³·Ïú(&U)"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: ÕÒ²»µ½´°¿Ú±êÌâ \"%s\""
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: ²»Ö§³ÖµÄ²ÎÊý: \"-%s\"£»ÇëʹÓà OLE °æ±¾¡£"
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: ÎÞ·¨ÔÚ MDI Ó¦ÓóÌÐòÖдò¿ª´°¿Ú"
-
-#~ msgid "Close tab"
-#~ msgstr "¹Ø±Õ±êÇ©"
-
-#~ msgid "Open tab..."
-#~ msgstr "´ò¿ª±êÇ©..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "²éÕÒ×Ö·û´® (ʹÓà '\\\\' À´²éÕÒ '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "²éÕÒºÍÌæ»»×Ö·û´® (ʹÓà '\\\\' À´²éÕÒ '\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "δʹÓÃ"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Ŀ¼\t*.nothing\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: ÎÞ·¨·ÖÅäÑÕÉ«±íÏijЩÑÕÉ«¿ÉÄܲ»ÕýÈ·"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Fontset %s ȱÉÙÏÂÁÐ×Ö·û¼¯µÄ×ÖÌå:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Fontset Ãû³Æ: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "'%s' ²»Êǹ̶¨¿í¶ÈµÄ×ÖÌå"
-
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Fontset Ãû³Æ: %s\n"
-
-#~ msgid "Font0: %s\n"
-#~ msgstr "×ÖÌå0: %s\n"
-
-#~ msgid "Font1: %s\n"
-#~ msgstr "×ÖÌå1: %s\n"
-
-#~ 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 ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "×ÖÌå1µÄ¿í¶È: %<PRId64>\n"
-#~ "\n"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Ö¸¶¨ÁËÎÞЧµÄ×ÖÌå"
-
-#~ msgid "&Dismiss"
-#~ msgstr "È¡Ïû(&D)"
-
-#~ msgid "no specific match"
-#~ msgstr "ÕÒ²»µ½Æ¥ÅäµÄÏî"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - ×ÖÌåÑ¡ÔñÆ÷"
-
-#~ msgid "Name:"
-#~ msgstr "Ãû³Æ:"
-
-#~ msgid "Encoding:"
-#~ msgstr "±àÂë:"
-
-#~ msgid "Font:"
-#~ msgstr "×ÖÌå:"
-
-#~ msgid "Style:"
-#~ msgstr "·ç¸ñ:"
-
-#~ msgid "Size:"
-#~ msgstr "³ß´ç:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Hangul automata ´íÎó"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat ´íÎó"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: ÎÞ·¨´ò¿ª cscope Êý¾Ý¿â: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: ÎÞ·¨»ñÈ¡ cscope Êý¾Ý¿âÐÅÏ¢"
-
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: ÒÑ´ïµ½ cscope µÄ×î´óÁ¬½ÓÊý"
-
-#~ msgid ""
-#~ "???: Sorry, this command is disabled, the MzScheme library could not be "
-#~ "loaded."
-#~ msgstr "???: ±§Ç¸£¬´ËÃüÁî²»¿ÉÓã¬ÎÞ·¨¼ÓÔØ MzScheme ¿â"
-
-#~ msgid "invalid expression"
-#~ msgstr "ÎÞЧµÄ±í´ïʽ"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "±àÒëʱûÓÐÆôÓñí´ïʽ"
-
-#~ msgid "hidden option"
-#~ msgstr "Òþ²ØµÄÑ¡Ïî"
-
-#~ msgid "unknown option"
-#~ msgstr "δ֪µÄÑ¡Ïî"
-
-#~ msgid "window index is out of range"
-#~ msgstr "´°¿ÚË÷Òý³¬³ö·¶Î§"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "ÎÞ·¨´ò¿ª»º³åÇø"
-
-#~ msgid "cannot save undo information"
-#~ msgstr "ÎÞ·¨±£´æ³·ÏúÐÅÏ¢"
-
-#~ msgid "cannot delete line"
-#~ msgstr "ÎÞ·¨É¾³ýÐÐ"
-
-#~ msgid "cannot replace line"
-#~ msgstr "ÎÞ·¨Ìæ»»ÐÐ"
-
-#~ msgid "cannot insert line"
-#~ msgstr "ÎÞ·¨²åÈëÐÐ"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "×Ö·û´®²»Äܰüº¬»»ÐÐ(NL)"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim ´íÎó: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Vim ´íÎó"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "»º³åÇøÎÞЧ"
-
-#~ msgid "window is invalid"
-#~ msgstr "´°¿ÚÎÞЧ"
-
-#~ msgid "linenr out of range"
-#~ msgstr "Ðкų¬³ö·¶Î§"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "²»ÔÊÐíÔÚ sandbox ÖÐʹÓÃ"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr "E263: ±§Ç¸£¬´ËÃüÁî²»¿ÉÓã¬ÎÞ·¨¼ÓÔØ Python ¿â¡£"
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: ²»Äܵݹéµ÷Óà Python"
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "²»ÄÜɾ³ý OutputObject ÊôÐÔ"
-
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspace ±ØÐëÊÇÕûÊý"
-
-#~ msgid "invalid attribute"
-#~ msgstr "ÎÞЧµÄÊôÐÔ"
-
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines() ÐèÒª×Ö·û´®Áбí×÷²ÎÊý"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: ³õʼ»¯ I/O ¶ÔÏó³ö´í"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "ÊÔͼÒýÓÃÒѱ»É¾³ýµÄ»º³åÇø"
-
-#~ msgid "line number out of range"
-#~ msgstr "Ðкų¬³ö·¶Î§"
-
-#~ msgid "<buffer object (deleted) at %8lX>"
-#~ msgstr "<»º³åÇø¶ÔÏó(ÒÑɾ³ý): %8lX>"
-
-#~ msgid "invalid mark name"
-#~ msgstr "ÎÞЧµÄ±ê¼ÇÃû³Æ"
-
-#~ msgid "no such buffer"
-#~ msgstr "ÎÞ´Ë»º³åÇø"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "ÊÔͼÒýÓÃÒѱ»É¾³ýµÄ´°¿Ú"
-
-#~ msgid "readonly attribute"
-#~ msgstr "Ö»¶ÁÊôÐÔ"
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "¹â±êλÖÃÔÚ»º³åÇøÍâ"
-
-#~ msgid "<window object (deleted) at %.8lX>"
-#~ msgstr "<´°¿Ú¶ÔÏó(ÒÑɾ³ý): %.8lX>"
-
-#~ msgid "<window object (unknown) at %.8lX>"
-#~ msgstr "<´°¿Ú¶ÔÏó(δ֪): %.8lX>"
-
-#~ msgid "<window %d>"
-#~ msgstr "<´°¿Ú %d>"
-
-#~ msgid "no such window"
-#~ msgstr "ÎÞ´Ë´°¿Ú"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr "E266: ±§Ç¸£¬´ËÃüÁî²»¿ÉÓã¬ÎÞ·¨¼ÓÔØ Ruby ¿â"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: δ֪µÄ longjmp ״̬ %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Çл»ÊµÏÖ/¶¨Òå"
-
-#~ msgid "Show base class of"
-#~ msgstr "ÏÔʾ base class of:"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "ÏÔʾ±»¸²¸ÇµÄ³ÉÔ±º¯Êý"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "»Ö¸´: ´ÓÎļþ"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "»Ö¸´: ´Ó¶ÔÏó"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "»Ö¸´: ´ÓËùÓÐÏîÄ¿"
-
-#~ msgid "Retrieve"
-#~ msgstr "»Ö¸´"
-
-#~ msgid "Show source of"
-#~ msgstr "ÏÔʾԴ´úÂë: "
-
-#~ msgid "Find symbol"
-#~ msgstr "²éÕÒ symbol"
-
-#~ msgid "Browse class"
-#~ msgstr "ä¯ÀÀ class"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "ÏÔʾ²ã´Î¹ØÏµµÄÀà"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "ÏÔʾ restricted ²ã´Î¹ØÏµµÄ class"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ²Î¿¼µ½"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ±»Ë­²Î¿¼:"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ÓÐ"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref ±»Ë­Ê¹ÓÃ:"
-
-#~ msgid "Show docu of"
-#~ msgstr "ÏÔʾÎļþ: "
-
-#~ msgid "Generate docu for"
-#~ msgstr "²úÉúÎļþ: "
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "²»ÄÜÁ¬½Óµ½ SNiFF+¡£Çë¼ì²é»·¾³±äÁ¿ ($PATH Àï±ØÐè¿ÉÒÔÕÒµ½ sniffemacs)\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: ¶ÁÈ¡´íÎó. È¡ÏûÁ¬½Ó"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ Ŀǰ"
-
-#~ msgid "not "
-#~ msgstr "δ"
-
-#~ msgid "connected"
-#~ msgstr "Á¬½ÓÖÐ"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: ²»ÕýÈ·µÄ SNiff+ µ÷ÓÃ: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Á¬½Óµ½ SNiFF+ ʧ°Ü"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: δÁ¬½Óµ½ SNiFF+"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: ²»ÊÇ SNiFF+ µÄ»º³åÇø"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: дÈë´íÎó¡£½áÊøÁ¬½Ó"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "ÎÞЧµÄ»º³åÇøºÅ"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ÉÐδʵÏÖ"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "ÎÞ·¨É趨ÐÐ"
-
-#~ msgid "mark not set"
-#~ msgstr "ûÓÐÉ趨±ê¼Ç"
-
-#~ msgid "row %d column %d"
-#~ msgstr "µÚ %d ÐÐ µÚ %d ÁÐ"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "ÎÞ·¨²åÈë/×·¼ÓÐÐ"
-
-#~ msgid "unknown flag: "
-#~ msgstr "δ֪µÄ±êÖ¾: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "δ֪µÄ vim Ñ¡Ïî"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "¼üÅÌÖжÏ"
-
-#~ msgid "vim error"
-#~ msgstr "vim ´íÎó"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "ÎÞ·¨´´½¨»º³åÇø/´°¿ÚÃüÁî: ¶ÔÏ󽫱»É¾³ý"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "ÎÞ·¨×¢²á»Øµ÷ÃüÁî: »º³åÇø/´°¿ÚÒѱ»É¾³ý"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr "E280: TCL ÑÏÖØ´íÎó: reflist Ë𻵣¡£¿Ç뱨¸æ¸ø vim-dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr "ÎÞ·¨×¢²á»Øµ÷ÃüÁî: ÕÒ²»µ½»º³åÇø/´°¿ÚÒýÓÃ"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr "E571: ±§Ç¸£¬´ËÃüÁî²»¿ÉÓã¬ÎÞ·¨¼ÓÔØ Tcl ¿â"
-
-#~ 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 "E572: exit code %d"
-#~ msgstr "E572: Í˳ö·µ»ØÖµ %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "ÎÞ·¨»ñÈ¡ÐÐ"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "ÎÞ·¨×¢²áÃüÁî·þÎñÆ÷Ãû"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: ÎÞ·¨·¢ËÍÃüÁĿµÄ³ÌÐò"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: ʹÓÃÁËÎÞЧµÄ·þÎñÆ÷ id: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM ʵÀý×¢²áÊôÐÔÓÐÎó¡£ÒÑɾ³ý£¡"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "´Ë Vim ±àÒëʱûÓмÓÈë diff ¹¦ÄÜ"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: ´íÎó: ÎÞ·¨´Ó NetBeans ÖÐÆô¶¯ gvim\n"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\t×¢²á´Ë gvim µ½ OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tÈ¡Ïû OLE ÖÐµÄ gvim ×¢²á"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tʹÓÃͼÐνçÃæ (ͬ \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f »ò --nofork\tǰ̨: Æô¶¯Í¼ÐνçÃæÊ±²» fork"
-
-#~ msgid "-V[N]\t\tVerbose level"
-#~ msgstr "-V[N]\t\tVerbose µÈ¼¶"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\t²»Ê¹Óà newcli À´´ò¿ª´°¿Ú"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tʹÓà <device> ½øÐÐÊäÈëÊä³ö"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tʹÓà <gvimrc> Ìæ´úÈκΠ.gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\t±à¼­¼ÓÃܵÄÎļþ"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\t½« vim ÓëÖ¸¶¨µÄ X-server Á¬½Ó"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\t²»Á¬½Óµ½ X Server"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\tÈçÓпÉÄÜ£¬ÔÚ Vim ·þÎñÆ÷Éϱ༭Îļþ <files>"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> ͬÉÏ£¬ÕÒ²»µ½·þÎñÆ÷ʱ²»±§Ô¹"
-
-#~ 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 "--remote-tab <files> As --remote but open tab page for each file"
-#~ msgstr "--remote-tab <files> ͬ --remote µ«¶Ôÿ¸öÎļþ´ò¿ªÒ»¸ö±êǩҳ"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\tËͳö <keys> µ½ Vim ·þÎñÆ÷²¢Í˳ö"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\tÔÚ Vim ·þÎñÆ÷ÉÏÇó <expr> µÄÖµ²¢´òÓ¡½á¹û"
-
-#~ 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 ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (Motif °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (neXtaw °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (Athena °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\tÔÚ <display> ÉÏÔËÐÐ vim"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tÆô¶¯ºó×îС»¯"
-
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <name>\t\t¶ÁÈ¡ Resource ʱ°Ñ vim ÊÓΪ <name>"
-
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (ÉÐδʵÏÖ)\n"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\tʹÓà <color> ×÷Ϊ±³¾°É« (Ò²¿ÉÓà -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\tʹÓà <color> ×÷Ϊһ°ãÎÄ×ÖÑÕÉ« (Ò²¿ÉÓà -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\tʹÓà <font> ×÷Ϊһ°ã×ÖÌå (Ò²¿ÉÓà -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\tʹÓà <font> ×÷Ϊ´ÖÌå×ÖÌå"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <font>\tʹÓà <font> ×÷ΪбÌå×ÖÌå"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\tʹÓà <geom> ×÷Ϊ³õʼλÖà (Ò²¿ÉÓà -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\tÉ趨±ß¿ò¿í¶ÈΪ <width> (Ò²¿ÉÓà -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr "-scrollbarwidth <width> É趨¹ö¶¯Ìõ¿í¶ÈΪ <width> (Ò²¿ÉÓà -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <height>\tÉ趨²Ëµ¥À¸¸ß¶ÈΪ <height> (Ò²¿ÉÓà -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tʹÓ÷´ÏÔ (Ò²¿ÉÓà -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\t²»Ê¹Ó÷´ÏÔ (Ò²¿ÉÓà +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\tÉ趨ָ¶¨µÄ×ÊÔ´"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (RISC OS °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <number>\t´°¿Ú³õʼ¿í¶È"
-
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <number>\t´°¿Ú³õʼ¸ß¶È"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (GTK+ °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\tÔÚ <display> ÉÏÔËÐÐ vim (Ò²¿ÉÓà --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\tÉèÖÃÓÃÓÚÇø·ÖÖ÷´°¿ÚµÄ´°¿Ú½ÇÉ«Ãû"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tÔÚÁíÒ»¸ö GTK ²¿¼þÖдò¿ª Vim"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <parent title>\tÔÚ¸¸Ó¦ÓóÌÐòÖдò¿ª Vim"
-
-#~ msgid "No display"
-#~ msgstr "ûÓÐ display"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": ·¢ËÍʧ°Ü¡£\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": ·¢ËÍʧ°Ü¡£³¢ÊÔ±¾µØÖ´ÐÐ\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d ÖÐ %d Òѱ༭"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "ûÓÐ display: ·¢Ëͱí´ïʽʧ°Ü¡£\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": ·¢Ëͱí´ïʽʧ°Ü¡£\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: ÎÞЧµÄ´úÂëÒ³"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: ÎÞ·¨´´½¨ÊäÈëÉÏÏÂÎÄ"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: ÎÞ·¨´ò¿ªÊäÈë·¨"
-
-#~ 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 ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [²»ÄÜÔڸð汾µÄ Vim ÉÏʹÓÃ]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "˺Ï´˲˵¥"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Ñ¡ÔñĿ¼¶Ô»°¿ò"
-
-#~ msgid "Save File dialog"
-#~ msgstr "±£´æÎļþ¶Ô»°¿ò"
-
-#~ msgid "Open File dialog"
-#~ msgstr "´ò¿ªÎļþ¶Ô»°¿ò"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: ±§Ç¸£¬¿ØÖÆÌ¨Ä£Ê½ÏÂûÓÐÎļþä¯ÀÀÆ÷"
-
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: ÕýÔÚ±£ÁôÎļþ¡­¡­\n"
-
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: ½áÊø¡£\n"
-
-#~ msgid "ERROR: "
-#~ msgstr "´íÎó: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[×Ö½Ú] ×ܹ² alloc-free %<PRIu64>-%<PRIu64>£¬Ê¹ÓÃÖÐ %<PRIu64>£¬¸ß·åʹÓà "
-#~ "%<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[µ÷ÓÃ] ×ܹ² re/malloc(): %<PRIu64>£¬×ܹ² free()': %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: ´ËÐйý³¤"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: ÄÚ²¿´íÎó: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: ÎÞЧµÄÊó±êÐÎ×´"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "ÊäÈëÃÜÂë: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "ÇëÔÙÊäÈëÒ»´Î: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Á½´ÎÃÜÂ벻ƥÅ䣡"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "ÎÞ·¨Á¬½Óµ½ Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "ÎÞ·¨Á¬½Óµ½ Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: NetBeans Á¬½ÓÐÅÏ¢ÎļþÖдíÎóµÄ·ÃÎÊģʽ: \"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "´Ó Netbeans Ì×½Ó×Ö¶ÁÈ¡"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: »º³åÇø %<PRId64> ¶ªÊ§ NetBeans Á¬½Ó"
-
-#~ msgid "E505: "
-#~ msgstr "E505: "
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: ÇóÖµ¹¦Äܲ»¿ÉÓÃ"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "ÊÍ·ÅÁË %<PRId64> ÐÐ"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: ÔÚͼÐνçÃæÖв»ÄܸıäÖÕ¶Ë"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: ÇëÓà \":gui\" Æô¶¯Í¼ÐνçÃæ"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: ÔÚ GTK+ 2 ͼÐνçÃæÖв»Äܸü¸Ä"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: ÎÞЧµÄ×ÖÌå"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ÎÞ·¨Ñ¡Ôñ Fontset"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: ÎÞЧµÄ Fontset"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ÎÞ·¨Ñ¡Ôñ¿í×ÖÌå"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: ÎÞЧµÄ¿í×ÖÌå"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: ²»Ö§³ÖÊó±ê"
-
-#~ msgid "cannot open "
-#~ msgstr "²»ÄÜ´ò¿ª"
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: ²»ÄÜ´ò¿ª´°¿Ú!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "ÐèÒª Amigados °æ±¾ 2.04 ÒÔÉÏ\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "ÐèÒª %s °æ±¾ %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "²»ÄÜ´ò¿ª NIL:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "²»ÄÜ´´½¨ "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim ·µ»ØÖµ: %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "²»ÄÜÇл»Ö÷¿ØÌ¨(console)ģʽ !?\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ²»ÊÇÖ÷¿ØÌ¨(console)??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: ²»ÄÜÓà -f Ñ¡ÏîÖ´ÐÐ shell"
-
-#~ msgid "Cannot execute "
-#~ msgstr "²»ÄÜÖ´ÐÐ "
-
-#~ msgid "shell "
-#~ msgstr "shell "
-
-#~ msgid " returned\n"
-#~ msgstr " ÒÑ·µ»Ø\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE ̫С"
-
-#~ msgid "I/O ERROR"
-#~ msgstr "I/O ´íÎó"
-
-#~ msgid "Message"
-#~ msgstr "ÏûÏ¢"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ²»ÊÇ 80, ²»ÄÜÖ´ÐÐÍⲿÃüÁî"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Ñ¡Ôñ´òÓ¡»úʧ°Ü"
-
-#~ msgid "to %s on %s"
-#~ msgstr "´Ó %s µ½ %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: δ֪µÄ´òÓ¡»ú×ÖÌå: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: ´òÓ¡´íÎó: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "´òÓ¡ '%s'"
-
-#~ 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 "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Ë«ÖØÐźţ¬Í˳öÖÐ\n"
-
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: À¹½Øµ½ÖÂÃüÐźÅ(deadly signal) %s\n"
-
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: À¹½Øµ½ÖÂÃüÐźÅ(deadly signal)\n"
-
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "´ò¿ª X display ÓÃʱ %<PRId64> Ãë"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\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 ³¬Ê±"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÎÞ·¨Ö´ÐÐ shell sh\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÎÞ·¨½¨Á¢¹ÜµÀ\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÎÞ·¨ fork\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÃüÁîÒѽáÊø\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP ¶ªÊ§Á˵½ ICE µÄÁ¬½Ó"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "´ò¿ª X display ʧ°Ü"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP ´¦Àí save-yourself ÇëÇó"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP ´ò¿ªÁ¬½Ó"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICE Á¬½Ó¼àÊÓʧ°Ü"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection µ÷ÓÃʧ°Ü: %s"
-
-#~ msgid "At line"
-#~ msgstr "ÔÚÐкŠ"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "ÎÞ·¨¼ÓÔØ vim32.dll£¡"
-
-#~ msgid "VIM Error"
-#~ msgstr "VIM ´íÎó"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "ÎÞ·¨ÐÞÕýµ½ DLL µÄº¯ÊýÖ¸Õë!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "Shell ·µ»Ø %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: À¹½Øµ½ %s ʼþ\n"
-
-#~ msgid "close"
-#~ msgstr "¹Ø±Õ"
-
-#~ msgid "logoff"
-#~ msgstr "×¢Ïû"
-
-#~ msgid "shutdown"
-#~ msgstr "¹Ø»ú"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: ÕÒ²»µ½ÃüÁî"
-
-#~ 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 Warning"
-#~ msgstr "Vim ¾¯¸æ"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "²»Ö§³Ö %s ÖеÄת»»"
-
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Tag Îļþ·¾¶±»½Ø¶ÏΪ %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "Æô¶¯Ð shell\n"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "ÎÞ·¨³·Ïú£»Çë¼ÌÐø"
-
-#~ msgid "number changes time"
-#~ msgstr " ±àºÅ ¸Ä±ä ʱ¼ä"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 λͼÐνçÃæ°æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 λͼÐνçÃæ°æ±¾"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " Win32s ģʽ"
-
-#~ msgid " with OLE support"
-#~ msgstr " ´ø OLE Ö§³Ö"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 λ¿ØÖÆÌ¨°æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16 λ¿ØÖÆÌ¨°æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 λ MS-DOS °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 λ MS-DOS °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
-#~ msgstr ""
-#~ "\n"
-#~ "RISC OS °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "´óÐͰ汾 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Õý³£°æ±¾ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "СÐͰ汾 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "΢ÐͰ汾 "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "´ø GTK2-GNOME ͼÐνçÃæ¡£"
-
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "´ø GTK-GNOME ͼÐνçÃæ¡£"
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "´ø GTK2 ͼÐνçÃæ¡£"
-
-#~ msgid "with GTK GUI."
-#~ msgstr "´ø GTK ͼÐνçÃæ¡£"
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "´ø X11-Motif ͼÐνçÃæ¡£"
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "´ø X11-neXtaw ͼÐνçÃæ¡£"
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "´ø X11-Athena ͼÐνçÃæ¡£"
-
-#~ msgid "with Photon GUI."
-#~ msgstr "´ø Photon ͼÐνçÃæ¡£"
-
-#~ msgid "with GUI."
-#~ msgstr "´øÍ¼ÐνçÃæ¡£"
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "´ø Carbon ͼÐνçÃæ¡£"
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "´ø Cocoa ͼÐνçÃæ¡£"
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "´ø(´«Í³)ͼÐνçÃæ¡£"
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ϵͳ gvimrc Îļþ: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " Óû§ gvimrc Îļþ: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "µÚ¶þÓû§ gvimrc Îļþ: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "µÚÈýÓû§ gvimrc Îļþ: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " ϵͳ²Ëµ¥Îļþ: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "±àÒëÆ÷: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "²Ëµ¥ Help->Orphans ²é¿´ËµÃ÷ "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "ÎÞģʽÔËÐУ¬ÊäÈëÎÄ×Ö¼´²åÈë"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "²Ëµ¥ Edit->Global Settings->Toggle Insert Mode "
-
-#, fuzzy
-#~ msgid " for two modes "
-#~ msgstr " # pid Êý¾Ý¿âÃû³Æ prepend path\n"
-
-#, fuzzy
-#~ msgid " for Vim defaults "
-#~ msgstr " # pid Êý¾Ý¿âÃû³Æ prepend path\n"
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "¾¯¸æ: ¼ì²âµ½ Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "ÊäÈë :help windows95<Enter> ²é¿´Ïà¹ØËµÃ÷ "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: ÎÞ·¨¼ÓÔØ¿â %s"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr "±§Ç¸£¬´ËÃüÁî²»¿ÉÓÃ: ÎÞ·¨¼ÓÔØ Perl ¿â¡£"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Óöà¸ö Vim ±à¼­(&M)"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Óõ¥¸ö Vim ±à¼­(&V)"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Óà Vim ±È½Ï(diff)"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Óà Vim ±à¼­(&V)"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Óõ±Ç°µÄ Vim ±à¼­ - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Óà Vim ±à¼­Ñ¡ÖеÄÎļþ"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "´´½¨½ø³Ìʧ°Ü: Çë¼ì²é gvim ÊÇ·ñÔÚ·¾¶ÖУ¡"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll ´íÎó"
-
-#~ msgid "Path length too long!"
-#~ msgstr "·¾¶Ì«³¤£¡"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: δ֪µÄ Fontset: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: δ֪µÄ×ÖÌå: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: ×ÖÌå \"%s\" ²»Êǵȿí×ÖÌå"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: ÎÞ·¨¼ÓÔØ¿âº¯Êý %s"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: ÎÞ·¨Ê¹Óà Hebrew: ±àÒëʱûÓÐÆôÓÃ\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: ÎÞ·¨Ê¹Óà Farsi: ±àÒëʱûÓÐÆôÓÃ\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: ÎÞ·¨Ê¹Óà Arabic: ±àÒëʱûÓÐÆôÓÃ\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: ûÓÐÃû½Ð \"%s\" µÄÒÑ×¢²áµÄ·þÎñÆ÷"
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ÎÞ·¨´ò¿ª display"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: ÊÕµ½ÎÞЧµÄ±í´ïʽ"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ²»ÔÊÐí¸Ä±äÖ»¶ÁÎļþ"
-
-#~ msgid "Affix flags ignored when PFXPOSTPONE used in %s line %d: %s"
-#~ msgstr "%s µÚ %d ÐУ¬Ê¹Óà PFXPOSTPONE ʱ¸½¼Ó±êÖ¾±»ºöÂÔ: %s"
-
-#~ msgid "[No file]"
-#~ msgstr "[δÃüÃû]"
-
-#~ msgid "[Error List]"
-#~ msgstr "[´íÎóÁбí]"
-
-#~ msgid "E106: Unknown variable: \"%s\""
-#~ msgstr "E106: 䶨ÒåµÄ±äÁ¿: \"%s\""
-
-#~ msgid "function "
-#~ msgstr "º¯Êý "
-
-#~ msgid "E130: Undefined function: %s"
-#~ msgstr "E130: º¯Êý %s ÉÐ䶨Òå"
-
-#~ msgid "Run Macro"
-#~ msgstr "Ö´Ðкê"
-
-#~ msgid "E242: Color name not recognized: %s"
-#~ msgstr "E242: %s Ϊ²»ÄÜʶ±ðµÄÑÕÉ«Ãû³Æ"
-
-#~ msgid "error reading cscope connection %d"
-#~ msgstr "¶ÁÈ¡ cscope Á¬½Ó %d ʱ´íÎó"
-
-#~ msgid "E260: cscope connection not found"
-#~ msgstr "E260: ÕÒ²»µ½ cscope Á¬½Ó"
-
-#~ msgid "cscope connection closed"
-#~ msgstr "cscope Á¬½ÓÒѹرÕ"
-
-#~ msgid "couldn't malloc\n"
-#~ msgstr "²»ÄÜʹÓà malloc\n"
-
-#~ msgid "%2d %-5ld %-34s <none>\n"
-#~ msgstr "%2d %-5ld %-34s <ÎÞ>\n"
-
-#~ msgid "E249: couldn't read VIM instance registry property"
-#~ msgstr "E249: ²»ÄܶÁÈ¡ VIM µÄ ×¢²á±íÊôÐÔ"
-
-#~ msgid "\"\n"
-#~ msgstr "\"\n"
-
-#~ msgid "--help\t\tShow Gnome arguments"
-#~ msgstr "--help\t\tÏÔʾ Gnome Ïà¹Ø²ÎÊý"
-
-#~ msgid "[string too long]"
-#~ msgstr "[×Ö·û´®Ì«³¤]"
-
-#~ msgid "Hit ENTER to continue"
-#~ msgstr "Çë°´ ENTER ¼ÌÐø"
-
-#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
-#~ msgstr " (RET/BS: ÏòÏÂ/ÏòÉÏÒ»ÐÐ, ¿Õ¸ñ/b: Ò»Ò³, d/u: °ëÒ³, q: Í˳ö)"
-
-#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
-#~ msgstr " (RET: ÏòÏÂÒ»ÐÐ, ¿Õ°×¼ü: Ò»Ò³, d: °ëÒ³, q: Í˳ö)"
-
-#~ msgid "E361: Crash intercepted; regexp too complex?"
-#~ msgstr "E361: ²»ÄÜÖ´ÐÐ; regular expression Ì«¸´ÔÓ?"
-
-#~ msgid "E363: pattern caused out-of-stack error"
-#~ msgstr "E363: regular expression Ôì³É¶ÑÕ»ÓùâµÄ´íÎó"
-
-#~ msgid " BLOCK"
-#~ msgstr " ¿é"
-
-#~ msgid " LINE"
-#~ msgstr " ÐÐ"
-
-#~ msgid "Enter nr of choice (<CR> to abort): "
-#~ msgstr "ÊäÈë nr »òÑ¡Ôñ (<CR> Í˳ö): "
-
-#~ msgid "Linear tag search"
-#~ msgstr "ÏßÐÔ²éÕÒ±êÇ© (Tags)"
-
-#~ msgid "Binary tag search"
-#~ msgstr "¶þ½øÖƲéÕÒ(Binary search) ±êÇ©(Tags)"
-
-#~ msgid "with BeOS GUI."
-#~ msgstr "ʹÓà BeOS ͼÐνçÃæ¡£"
diff --git a/src/nvim/po/zh_CN.po b/src/nvim/po/zh_CN.po
deleted file mode 100644
index 254ebbce6b..0000000000
--- a/src/nvim/po/zh_CN.po
+++ /dev/null
@@ -1,7932 +0,0 @@
-# Chinese (simplified) Translation for Vim
-#
-# Do ":help uganda" in Vim to read copying and usage conditions.
-# Do ":help credits" in Vim to see a list of people who contributed.
-#
-# FIRST AUTHOR Wang Jun <junw@turbolinux.com.cn>
-#
-# TRANSLATORS
-# Edyfox <edyfox@gmail.com>
-# Yuheng Xie <elephant@linux.net.cn>
-#
-# Original translations.
-#
-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"
-"Language-Team: Simplified Chinese <i18n-translation@lists.linux.net.cn>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=gb2312\n"
-"Content-Transfer-Encoding: 8-bit\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "Ñ¡Ïî²ÎÊýºóµÄÄÚÈÝÎÞЧ"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr "[Location Áбí]"
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr "[Quickfix Áбí]"
-
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr ""
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: ÎÞ·¨·ÖÅäÈκλº³åÇø£¬Í˳ö³ÌÐò..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: ÎÞ·¨·ÖÅ仺³åÇø£¬Ê¹ÓÃÁíÒ»¸ö»º³åÇø..."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: ûÓÐÊÍ·ÅÈκλº³åÇø"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: ûÓÐɾ³ýÈκλº³åÇø"
-
-#: ../buffer.c:767
-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:782
-msgid "1 buffer wiped out"
-msgstr "Çå³ýÁË 1 ¸ö»º³åÇø"
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "Çå³ýÁË %d ¸ö»º³åÇø"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: ÎÞ·¨ÊÍ·Å×îºóÒ»¸ö»º³åÇø"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: ûÓÐÐ޸ĹýµÄ»º³åÇø"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-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
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: ÎÞ·¨Çл»£¬ÒÑÊÇ×îºóÒ»¸ö»º³åÇø"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: ÎÞ·¨Çл»£¬ÒÑÊǵÚÒ»¸ö»º³åÇø"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: »º³åÇø %<PRId64> ÒÑÐ޸ĵ«ÉÐδ±£´æ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: ¾¯¸æ: ÎļþÃû¹ý¶à"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: ÕÒ²»µ½»º³åÇø %<PRId64>"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: ÕÒµ½²»Ö¹Ò»¸ö %s"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: ûÓÐÆ¥ÅäµÄ»º³åÇø %s"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "µÚ %<PRId64> ÐÐ"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: ÒÑÓлº³åÇøÊ¹ÓøÃÃû³Æ"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [ÒÑÐÞ¸Ä]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[δ±à¼­]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[ÐÂÎļþ]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[¶Á´íÎó]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[Ö»¶Á]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-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:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "ÐÐ %<PRId64> / %<PRId64> --%d%%-- ÁÐ "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-msgid "[No Name]"
-msgstr "[δÃüÃû]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "°ïÖú"
-
-#: ../buffer.c:3225 ../screen.c:4883
-msgid "[Help]"
-msgstr "[°ïÖú]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[Ô¤ÀÀ]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "È«²¿"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "µ×¶Ë"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "¶¥¶Ë"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# »º³åÇøÁбí:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr ""
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- Signs ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "%s µÄ Signs:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ÐÐ=%<PRId64> id=%d Ãû³Æ=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ȱÉÙðºÅ"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: ÎÞЧµÄģʽ"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: ´Ë´¦ÐèÒªÊý×Ö"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: ÎÞЧµÄ°Ù·Ö±È"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: ²»ÄܱȽÏ(diff) %<PRId64> ¸öÒÔÉϵĻº³åÇø"
-
-#: ../diff.c:753
-#, fuzzy
-msgid "E810: Cannot read or write temp files"
-msgstr "E557: ÎÞ·¨´ò¿ª termcap Îļþ"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: ÎÞ·¨´´½¨ diff"
-
-#: ../diff.c:966
-#, fuzzy
-msgid "E816: Cannot read patch output"
-msgstr "E98: ÎÞ·¨¶ÁÈ¡ diff µÄÊä³ö"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: ÎÞ·¨¶ÁÈ¡ diff µÄÊä³ö"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: µ±Ç°»º³åÇø²»ÔÚ diff ģʽ"
-
-#: ../diff.c:2100
-#, fuzzy
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E100: ûÓÐÆäËü´¦ÓÚ diff ģʽµÄ»º³åÇø"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: ûÓÐÆäËü´¦ÓÚ diff ģʽµÄ»º³åÇø"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr "E101: ÓÐÁ½¸öÒÔÉϵĻº³åÇø´¦ÓÚ diff ģʽ£¬²»Äܾö¶¨ÓÃÄÄÒ»¸ö"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: ÕÒ²»µ½»º³åÇø \"%s\""
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: »º³åÇø \"%s\" ²»ÔÚ diff ģʽ"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr "E787: ÒâÍâµØ¸Ä±äÁË»º³åÇø"
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: ¸´ºÏ×Ö·û(digraph)Öв»ÄÜʹÓà Escape"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: ÕÒ²»µ½ Keymap Îļþ"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: ²»ÊÇÔڽű¾ÎļþÖÐʹÓà :loadkeymap "
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr ""
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " ¹Ø¼ü×Ö²¹È« (^N^P)"
-
-#. 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)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " ÕûÐв¹È« (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " ÎļþÃû²¹È« (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " Tag ²¹È« (^]^N^P)"
-
-#: ../edit.c:88
-#, fuzzy
-msgid " Path pattern completion (^N^P)"
-msgstr " ·¾¶Ä£Ê½²¹È« (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " ¶¨Ò岹ȫ (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " Dictionary ²¹È« (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " Thesaurus ²¹È« (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " ÃüÁîÐв¹È« (^V^N^P)"
-
-#: ../edit.c:94
-msgid " User defined completion (^U^N^P)"
-msgstr " Óû§×Ô¶¨Ò岹ȫ (^U^N^P)"
-
-#: ../edit.c:95
-msgid " Omni completion (^O^N^P)"
-msgstr " È«Äܲ¹È« (^O^N^P)"
-
-#: ../edit.c:96
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ƴд½¨Òé (s^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " ¹Ø¼ü×Ö¾Ö²¿²¹È« (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "Òѵ½¶ÎÂä½áβ"
-
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr ""
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr ""
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "Ñ¡Ïî 'dictionary' Ϊ¿Õ"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "Ñ¡Ïî 'thesaurus' Ϊ¿Õ"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "ÕýÔÚɨÃè dictionary: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (²åÈë) Scroll (^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (Ìæ»») Scroll (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "ÕýÔÚɨÃè: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "ɨÃè±êÇ©."
-
-#: ../edit.c:4519
-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.
-#.
-#: ../edit.c:4562
-msgid "-- Searching..."
-msgstr "-- ²éÕÒÖÐ..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "»Øµ½Æðµã"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "ÁíÒ»ÐеĴÊ"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "ΨһƥÅä"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "Æ¥Åä %d / %d"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "Æ¥Åä %d"
-
-#: ../eval.c:137
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: :let ÖгöÏÖÒì³£×Ö·û"
-
-#: ../eval.c:138
-#, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E684: List Ë÷Òý³¬³ö·¶Î§: %<PRId64>"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: 䶨ÒåµÄ±äÁ¿: %s"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: ȱÉÙ ']'"
-
-#: ../eval.c:141
-#, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E686: %s µÄ²ÎÊý±ØÐëÊÇ List"
-
-#: ../eval.c:143
-#, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E712: %s µÄ²ÎÊý±ØÐëÊÇ List »òÕß Dictionary"
-
-#: ../eval.c:144
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E713: Dictionary µÄ¼ü²»ÄÜΪ¿Õ"
-
-#: ../eval.c:145
-msgid "E714: List required"
-msgstr "E714: ÐèÒª List"
-
-#: ../eval.c:146
-msgid "E715: Dictionary required"
-msgstr "E715: ÐèÒª Dictionary"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: º¯ÊýµÄ²ÎÊý¹ý¶à: %s"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr "E716: Dictionary Öв»´æÔÚ¼ü: %s"
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: º¯Êý %s ÒÑ´æÔÚ£¬Çë¼Ó ! Ç¿ÖÆÌæ»»"
-
-#: ../eval.c:151
-msgid "E717: Dictionary entry already exists"
-msgstr "E717: Dictionary ÏîÒÑ´æÔÚ"
-
-#: ../eval.c:152
-msgid "E718: Funcref required"
-msgstr "E718: ÐèÒª Funcref"
-
-#: ../eval.c:153
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E719: ²»ÄÜ¶Ô Dictionary ʹÓà [:]"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr "E734: %s= µÄ±äÁ¿ÀàÐͲ»ÕýÈ·"
-
-#: ../eval.c:155
-#, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E130: δ֪µÄº¯Êý: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: ÎÞЧµÄ±äÁ¿Ãû: %s"
-
-#: ../eval.c:157
-#, fuzzy
-msgid "E806: using Float as a String"
-msgstr "E730: ½« List ×÷ String ʹÓÃ"
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr "E687: Ä¿±ê±È List ÏîÊýÉÙ"
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr "E688: Ä¿±ê±È List ÏîÊý¶à"
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr "±äÁ¿ÁбíÖгöÏÖÁ½¸ö ;"
-
-#: ../eval.c:2078
-#, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E738: ÎÞ·¨Áгö %s µÄ±äÁ¿"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr "E689: Ö»ÄÜË÷Òý List »ò Dictionary"
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr "E708: [:] ±ØÐëÔÚ×îºó"
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr "E709: [:] ÐèÒªÒ»¸ö List Öµ"
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr "E710: List ÖµµÄÏî±ÈÄ¿±ê¶à"
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr "E711: List ֵûÓÐ×ã¹»¶àµÄÏî"
-
-#: ../eval.c:2867
-msgid "E690: Missing \"in\" after :for"
-msgstr "E690: :for ºóȱÉÙ \"in\""
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: ȱÉÙÀ¨ºÅ: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: Î޴˱äÁ¿: \"%s\""
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr "E743: (un)lock µÄ±äÁ¿Ç¶Ì×¹ýÉî"
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: '?' ºóȱÉÙ ':'"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr "E691: Ö»ÄÜ±È½Ï List ºÍ List"
-
-#: ../eval.c:3895
-msgid "E692: Invalid operation for Lists"
-msgstr "E692: ¶Ô List ÎÞЧµÄ²Ù×÷"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr "E735: Ö»ÄÜ±È½Ï Dictionary ºÍ Dictionary"
-
-#: ../eval.c:3917
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E736: ¶Ô Dictionary ÎÞЧµÄ²Ù×÷"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr "E693: Ö»ÄÜ±È½Ï Funcref ºÍ Funcref"
-
-#: ../eval.c:3934
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E694: ¶Ô Funcrefs ÎÞЧµÄ²Ù×÷"
-
-#: ../eval.c:4277
-#, fuzzy
-msgid "E804: Cannot use '%' with Float"
-msgstr "E719: ²»ÄÜ¶Ô Dictionary ʹÓà [:]"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: ȱÉÙ ')'"
-
-#: ../eval.c:4609
-msgid "E695: Cannot index a Funcref"
-msgstr "E695: ²»ÄÜË÷ÒýÒ»¸ö Funcref"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: ȱÉÙÑ¡ÏîÃû³Æ: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: δ֪µÄÑ¡Ïî: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: ȱÉÙÒýºÅ: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: ȱÉÙÒýºÅ: %s"
-
-#: ../eval.c:5084
-#, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E696: List ÖÐȱÉÙ¶ººÅ: %s"
-
-#: ../eval.c:5091
-#, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E697: List ȱÉÙ½áÊø·û ']': %s"
-
-#: ../eval.c:6475
-#, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E720: Dictionary ÖÐȱÉÙðºÅ: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr "E721: Dictionary ÖгöÏÖÖØ¸´µÄ¼ü: \"%s\""
-
-#: ../eval.c:6517
-#, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E722: Dictionary ÖÐȱÉÙ¶ººÅ: %s"
-
-#: ../eval.c:6524
-#, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E723: Dictionary ȱÉÙ½áÊø·û '}': %s"
-
-#: ../eval.c:6555
-msgid "E724: variable nested too deep for displaying"
-msgstr "E724: ±äÁ¿Ç¶Ì×¹ýÉîÎÞ·¨ÏÔʾ"
-
-#: ../eval.c:7188
-#, fuzzy, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E118: º¯ÊýµÄ²ÎÊý¹ý¶à: %s"
-
-#: ../eval.c:7190
-#, fuzzy, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E118: º¯ÊýµÄ²ÎÊý¹ý¶à: %s"
-
-#: ../eval.c:7377
-#, fuzzy, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E130: δ֪µÄº¯Êý: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: º¯Êý %s µÄ²ÎÊýÌ«ÉÙ"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> ²»ÄÜÔÚ script ÉÏÏÂÎÄÍâʹÓÃ: %s"
-
-#: ../eval.c:7391
-#, fuzzy, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr "E720: Dictionary ÖÐȱÉÙðºÅ: %s"
-
-#: ../eval.c:7453
-#, fuzzy
-msgid "E808: Number or Float required"
-msgstr "E521: = ºóÃæÐèÒªÊý×Ö"
-
-#: ../eval.c:7503
-#, fuzzy
-msgid "add() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:7907
-msgid "E699: Too many arguments"
-msgstr "E699: ²ÎÊý¹ý¶à"
-
-#: ../eval.c:8073
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E785: complete() Ö»ÄÜÔÚ²åÈëģʽÖÐʹÓÃ"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "È·¶¨(&O)"
-
-#: ../eval.c:8676
-#, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E737: ¼üÒÑ´æÔÚ: %s"
-
-#: ../eval.c:8692
-#, fuzzy
-msgid "extend() argument"
-msgstr "--cmd ²ÎÊý"
-
-#: ../eval.c:8915
-#, fuzzy
-msgid "map() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:8916
-#, fuzzy
-msgid "filter() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld ÐÐ: "
-
-#: ../eval.c:9291
-#, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E700: δ֪µÄº¯Êý: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "inputrestore() µÄµ÷ÓôÎÊý¶àÓÚ inputsave()"
-
-#: ../eval.c:10771
-#, fuzzy
-msgid "insert() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:10841
-msgid "E786: Range not allowed"
-msgstr "E786: ²»ÔÊÐíµÄ·¶Î§"
-
-#: ../eval.c:11140
-msgid "E701: Invalid type for len()"
-msgstr "E701: len() µÄÀàÐÍÎÞЧ"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr "E726: ²½³¤ÎªÁã"
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr "E727: ÆðʼֵÔÚÖÕÖ¹Öµºó"
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr "<¿Õ>"
-
-#: ../eval.c:12282
-#, fuzzy
-msgid "remove() argument"
-msgstr "--cmd ²ÎÊý"
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: ·ûºÅÁ¬½Ó¹ý¶à(Ñ­»·£¿)"
-
-#: ../eval.c:12593
-#, fuzzy
-msgid "reverse() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "sort() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "-c ²ÎÊý"
-
-#: ../eval.c:13776
-msgid "E702: Sort compare function failed"
-msgstr "E702: Sort ±È½Ïº¯Êýʧ°Ü"
-
-#: ../eval.c:13806
-#, fuzzy
-msgid "E882: Uniq compare function failed"
-msgstr "E702: Sort ±È½Ïº¯Êýʧ°Ü"
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(ÎÞЧ)"
-
-#: ../eval.c:14590
-msgid "E677: Error writing temp file"
-msgstr "E677: дÁÙʱÎļþ³ö´í"
-
-#: ../eval.c:16159
-#, fuzzy
-msgid "E805: Using a Float as a Number"
-msgstr "E745: ½« List ×÷Êý×ÖʹÓÃ"
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr "E703: ½« Funcref ×÷Êý×ÖʹÓÃ"
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr "E745: ½« List ×÷Êý×ÖʹÓÃ"
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr "E728: ½« Dictionary ×÷Êý×ÖʹÓÃ"
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr "E729: ½« Funcref ×÷ String ʹÓÃ"
-
-#: ../eval.c:16262
-msgid "E730: using List as a String"
-msgstr "E730: ½« List ×÷ String ʹÓÃ"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr "E731: ½« Dictionary ×÷ String ʹÓÃ"
-
-#: ../eval.c:16619
-#, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E706: ±äÁ¿ÀàÐͲ»Æ¥Åä: %s"
-
-#: ../eval.c:16705
-#, fuzzy, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E738: ÎÞ·¨Áгö %s µÄ±äÁ¿"
-
-#: ../eval.c:16724
-#, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E704: Funcref ±äÁ¿Ãû±ØÐëÒÔ´óд×Öĸ¿ªÍ·: %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr "E705: ±äÁ¿ÃûÓëÒÑÓк¯ÊýÃû³åÍ»: %s"
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr "E741: ÖµÒÑËø¶¨: %s"
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "δ֪"
-
-#: ../eval.c:16768
-#, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E742: ÎÞ·¨¸Ä±ä %s µÄÖµ"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr "E698: ±äÁ¿Ç¶Ì×¹ýÉîÎÞ·¨¸´ÖÆ"
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: º¯Êý %s ÉÐ䶨Òå"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: ȱÉÙ '(': %s"
-
-#: ../eval.c:17293
-#, fuzzy
-msgid "E862: Cannot use g: here"
-msgstr "E284: ²»ÄÜÉ趨 IC Öµ"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: ÎÞЧµÄ²ÎÊý: %s"
-
-#: ../eval.c:17323
-#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E125: ÎÞЧµÄ²ÎÊý: %s"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: ȱÉÙ :endfunction"
-
-#: ../eval.c:17537
-#, fuzzy, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E746: º¯ÊýÃûÓë½Å±¾ÎļþÃû²»Æ¥Åä: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: º¯Êý %s ÕýÔÚʹÓÃÖУ¬²»ÄÜÖØÐ¶¨Òå"
-
-#: ../eval.c:17604
-#, 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.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: º¯ÊýÃû±ØÐëÒÔ´óд×Öĸ¿ªÍ·»òÕß°üº¬Ã°ºÅ: %s"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: º¯ÊýÃû±ØÐëÒÔ´óд×Öĸ¿ªÍ·»òÕß°üº¬Ã°ºÅ: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: ÎÞ·¨É¾³ýº¯Êý %s: ÕýÔÚʹÓÃÖÐ"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: º¯Êýµ÷ÓÃÉî¶È³¬³ö 'maxfuncdepth'"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "µ÷ÓÃ %s"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ÒÑÖÐÖ¹"
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ·µ»Ø #%<PRId64> "
-
-#: ../eval.c:18670
-#, c-format
-msgid "%s returning %s"
-msgstr "%s ·µ»Ø %s"
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "ÔÚ %s ÖмÌÐø"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return ²»ÔÚº¯ÊýÖÐ"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# È«¾Ö±äÁ¿:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\t×î½üÐÞ¸ÄÓÚ "
-
-#: ../eval.c:19272
-#, fuzzy
-msgid "No old files"
-msgstr "ûÓаüº¬Îļþ"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, Ê®Áù½øÖÆ %02x, °Ë½øÖÆ %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, Ê®Áù½øÖÆ %04x, °Ë½øÖÆ %o"
-
-#: ../ex_cmds.c:146
-#, 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:747
-msgid "1 line moved"
-msgstr "ÒÆ¶¯ÁË 1 ÐÐ"
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "ÒÆ¶¯ÁË %<PRId64> ÐÐ"
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "¹ýÂËÁË %<PRId64> ÐÐ"
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: *Filter* ×Ô¶¯ÃüÁî²»¿ÉÒԸı䵱ǰ»º³åÇø"
-
-#: ../ex_cmds.c:1244
-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
-#, 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"
-
-# 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
-msgid "Write partial file?"
-msgstr "ҪдÈ벿·ÖÎļþÂð£¿"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: ÇëʹÓà ! À´Ð´È벿·Ö»º³åÇø"
-
-#: ../ex_cmds.c:2281
-#, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "¸²¸ÇÒÑ´æÔÚµÄÎļþ \"%s\" Âð£¿"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr "½»»»Îļþ \"%s\" ÒÑ´æÔÚ£¬È·ÊµÒª¸²¸ÇÂð£¿"
-
-#: ../ex_cmds.c:2326
-#, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E768: ½»»»ÎļþÒÑ´æÔÚ: %s (:silent! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: »º³åÇø %<PRId64> ûÓÐÎļþÃû"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: ÎļþδдÈë: дÈë±» 'write' Ñ¡Ïî½ûÓÃ"
-
-#: ../ex_cmds.c:2434
-#, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"\"%s\" ÒÑÉ趨 'readonly' Ñ¡Ïî¡£\n"
-"ȷʵҪ¸²¸ÇÂð£¿"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-
-#: ../ex_cmds.c:2451
-#, fuzzy, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "Ö»¶Á (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: ×Ô¶¯ÃüÁîÒâÍâµØÉ¾³ýÁËлº³åÇø %s"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: :z ²»½ÓÊÜ·ÇÊý×ֵIJÎÊý"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: rvim ÖнûֹʹÓà shell ÃüÁî"
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: ÕýÔò±í´ïʽ²»ÄÜÓÃ×Öĸ×÷·Ö½ç"
-
-#: ../ex_cmds.c:3964
-#, 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
-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:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "%<PRId64> ´ÎÌæ»»£¬"
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr "¹² 1 ÐÐ"
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr "¹² %<PRId64> ÐÐ"
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global ²»ÄܵݹéÖ´ÐÐ"
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: global ȱÉÙÕýÔò±í´ïʽ"
-
-#: ../ex_cmds.c:4508
-#, 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
-#, 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"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "¶Ïµã \"%s%s\" µÚ %<PRId64> ÐÐ"
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: ÕÒ²»µ½¶Ïµã: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "ûÓж¨Òå¶Ïµã"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s µÚ %<PRId64> ÐÐ"
-
-#: ../ex_cmds2.c:942
-#, fuzzy
-msgid "E750: First use \":profile start {fname}\""
-msgstr "E750: ÇëÏÈʹÓà :profile start <fname>"
-
-#: ../ex_cmds2.c:1269
-#, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "½«¸Ä±ä±£´æµ½ \"%s\" Âð£¿"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "δÃüÃû"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: »º³åÇø \"%s\" ÒÑÐ޸ĵ«ÉÐδ±£´æ"
-
-#: ../ex_cmds2.c:1480
-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
-#, 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_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: Ôڽű¾ÎļþÍâʹÓÃÁË :scriptencoding"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: Ôڽű¾ÎļþÍâʹÓÃÁË :finish"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "µ±Ç°µÄ %sÓïÑÔ: \"%s\""
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: ²»ÄÜÉ趨ÓïÑÔΪ \"%s\""
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "½øÈë Ex ģʽ¡£ÊäÈë \"visual\" »Øµ½Õý³£Ä£Ê½¡£"
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: Òѵ½Îļþĩβ"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: ÃüÁîµÝ¹é²ãÊý¹ý¶à"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: Ò쳣ûÓб»²¶»ñ: %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "½Å±¾Îļþ½áÊø"
-
-#: ../ex_docmd.c:1086
-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: ²»ÊDZ༭Æ÷µÄÃüÁî"
-
-#: ../ex_docmd.c:1729
-msgid "E493: Backwards range given"
-msgstr "E493: ʹÓÃÁËÄæÏòµÄ·¶Î§"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "ʹÓÃÁËÄæÏòµÄ·¶Î§£¬È·¶¨½»»»Âð"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: ÇëʹÓà w »ò w>>"
-
-#: ../ex_docmd.c:3454
-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:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: ûÓÐÕâ¸öÓû§×Ô¶¨ÒåÃüÁî: %s"
-
-#: ../ex_docmd.c:5219
-#, 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"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "ÄúºÃ£¬Vim Óû§£¡"
-
-#: ../ex_docmd.c:5431
-msgid "E784: Cannot close last tab page"
-msgstr "E784: ²»ÄܹرÕ×îºóÒ»¸ö tab Ò³"
-
-#: ../ex_docmd.c:5462
-msgid "Already only one tab page"
-msgstr "ÒѾ­Ö»Ê£Ò»¸ö tab Ò³ÁË"
-
-#: ../ex_docmd.c:6004
-#, c-format
-msgid "Tab page %d"
-msgstr "Tab Ò³ %d"
-
-#: ../ex_docmd.c:6295
-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
-msgid "E186: No previous directory"
-msgstr "E186: ǰһ¸öĿ¼²»´æÔÚ"
-
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: δ֪"
-
-#: ../ex_docmd.c:6610
-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
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: \"%s\" ÒÑ´æÔÚ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: ÎÞ·¨´ò¿ª²¢Ð´Èë \"%s\""
-
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: ²ÎÊý±ØÐëÊÇÒ»¸ö×Öĸ»òÕßÕý/·´ÒýºÅ"
-
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: :normal µÝ¹é²ãÊý¹ýÉî"
-
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: ûÓÐÓÃÓÚÌæ»» '#' µÄ½»ÌæÎļþÃû"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: ûÓÐÓÃÓÚÌæ»» \"<afile>\" µÄ×Ô¶¯ÃüÁîÎļþÃû"
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: ûÓÐÓÃÓÚÌæ»» \"<abuf>\" µÄ×Ô¶¯ÃüÁ³åÇøºÅ"
-
-#: ../ex_docmd.c:7861
-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
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: ûÓÐÓÃÓÚÌæ»» \"<sfile>\" µÄ :source ÎļþÃû"
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: '%' »ò '#' Ϊ¿ÕÎļþÃû£¬Ö»ÄÜÓÃÓÚ \":p:h\""
-
-#: ../ex_docmd.c:7905
-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_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: ²»ÄÜ :throw ǰ׺Ϊ 'Vim' µÄÒì³£"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "Å׳öÒì³£: %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "Íê³ÉÒì³£: %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "¶ªÆúÒì³£: %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s£¬µÚ %<PRId64> ÐÐ"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "²¶»ñÒì³£: %s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr ""
-
-#: ../ex_eval.c:679
-#, fuzzy, c-format
-msgid "%s resumed"
-msgstr " ÒÑ·µ»Ø\n"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr ""
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "Òì³£"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "´íÎóºÍÖжÏ"
-
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "´íÎó"
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "ÖжÏ"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: :if ǶÌײãÊý¹ýÉî"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :endif ȱÉÙ¶ÔÓ¦µÄ :if"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :else ȱÉÙ¶ÔÓ¦µÄ :if"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :elseif ȱÉÙ¶ÔÓ¦µÄ :if"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: ¶à¸ö :else"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :elseif ÔÚ :else ºóÃæ"
-
-#: ../ex_eval.c:941
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: :while/:for ǶÌײãÊý¹ýÉî"
-
-#: ../ex_eval.c:1028
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :continue ȱÉÙ¶ÔÓ¦µÄ :while »ò :for"
-
-#: ../ex_eval.c:1061
-msgid "E587: :break without :while or :for"
-msgstr "E587: :break ȱÉÙ¶ÔÓ¦µÄ :while »ò :for"
-
-#: ../ex_eval.c:1102
-msgid "E732: Using :endfor with :while"
-msgstr "E732: :while ÒÔ :endfor ½áβ"
-
-#: ../ex_eval.c:1104
-msgid "E733: Using :endwhile with :for"
-msgstr "E733: :for ÒÔ :endwhile ½áβ"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: :try ǶÌײãÊý¹ýÉî"
-
-#: ../ex_eval.c:1317
-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
-msgid "E604: :catch after :finally"
-msgstr "E604: :catch ÔÚ :finally ºóÃæ"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :finally ȱÉÙ¶ÔÓ¦µÄ :try"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: ¶à¸ö :finally"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :endtry ȱÉÙ¶ÔÓ¦µÄ :try"
-
-#: ../ex_eval.c:2026
-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
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E788: Ŀǰ²»ÔÊÐí±à¼­±ðµÄ»º³åÇø"
-
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "tag Ãû"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr " ÀàÐÍ Îļþ\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "Ñ¡Ïî 'history' ΪÁã"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5046
-#, fuzzy, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s ÀúÊ·¼Ç¼ (´Óе½¾É):\n"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5047
-#, fuzzy
-msgid "Command Line"
-msgstr "ÃüÁîÐÐ"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5048
-#, fuzzy
-msgid "Search String"
-msgstr "²éÕÒ×Ö·û´®"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5049
-#, fuzzy
-msgid "Expression"
-msgstr "±í´ïʽ"
-
-# do not translate to avoid writing Chinese in files
-#: ../ex_getln.c:5050
-#, fuzzy
-msgid "Input Line"
-msgstr "ÊäÈëÐÐ"
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar ³¬¹ýÃüÁ¶È"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: »î¶¯´°¿Ú»ò»º³åÇøÒѱ»É¾³ý"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr ""
-
-#: ../file_search.c:446
-#, 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
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpath ÖÐÕÒ²»µ½Ä¿Â¼ \"%s\""
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: ÔÚ·¾¶ÖÐÕÒ²»µ½Îļþ \"%s\""
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: ÔÚ·¾¶ÖÐÕÒ²»µ½¸ü¶àµÄÎļþ \"%s\""
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: ÔÚ·¾¶ÖÐÕÒ²»µ½¸ü¶àµÄÎļþ \"%s\""
-
-#: ../fileio.c:137
-#, fuzzy
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E135: *Filter* ×Ô¶¯ÃüÁî²»¿ÉÒԸı䵱ǰ»º³åÇø"
-
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "ÎÞЧµÄÎļþÃû"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "ÊÇĿ¼"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "²»ÊÇÎļþ"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[ÐÂÎļþ]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr "[ÐÂĿ¼]"
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr "[Îļþ¹ý´ó]"
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[ȨÏÞ²»×ã]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200: *ReadPre ×Ô¶¯ÃüÁîµ¼ÖÂÎļþ²»¿É¶Á"
-
-#: ../fileio.c:655
-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
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202: ת»»µ¼ÖÂÎļþ²»¿É¶Á"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[fifo/socket]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[fifo]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[socket]"
-
-#. or character special
-#: ../fileio.c:1801
-#, fuzzy
-msgid "[character special]"
-msgstr "1 ¸ö×Ö·û"
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[ȱÉÙ CR]'"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[³¤Ðзָî]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[δת»»]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[ÒÑת»»]"
-
-#: ../fileio.c:1831
-#, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[µÚ %<PRId64> ÐÐת»»´íÎó]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[µÚ %<PRId64> ÐÐÎÞЧ×Ö·û]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[¶Á´íÎó]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "ÕÒ²»µ½ÓÃÓÚת»»µÄÁÙʱÎļþ"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "'charconvert' ת»»Ê§°Ü"
-
-#: ../fileio.c:2113
-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:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr "E203: ×Ô¶¯ÃüÁîɾ³ý»òÊÍ·ÅÁËҪдÈëµÄ»º³åÇø"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: ×Ô¶¯ÃüÁîÒâÍâµØ¸Ä±äÁËÐÐÊý"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "²»ÊÇÎļþ»ò¿ÉдµÄÉ豸"
-
-#: ../fileio.c:2601
-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:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr "E509: ÎÞ·¨´´½¨±¸·ÝÎļþ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr "E510: ÎÞ·¨Éú³É±¸·ÝÎļþ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: ÕÒ²»µ½ÓÃÓÚдÈëµÄÁÙʱÎļþ"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr "E213: ÎÞ·¨×ª»» (Çë¼Ó ! Ç¿ÖÆ²»×ª»»Ð´Èë)"
-
-#: ../fileio.c:3169
-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:3398
-msgid "E512: Close failed"
-msgstr "E512: ¹Ø±Õʧ°Ü"
-
-#: ../fileio.c:3436
-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' ÖÿÕÒÔÇ¿ÖÆÖ´ÐÐ)"
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: дÈë´íÎó (ÎļþϵͳÒÑÂú£¿)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr " ת»»´íÎó"
-
-#: ../fileio.c:3509
-#, fuzzy, c-format
-msgid " in line %<PRId64>;"
-msgstr "µÚ %<PRId64> ÐÐ"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[É豸]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[ÐÂ]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr " [a]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " ÒÑ×·¼Ó"
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr " [w]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " ÒÑдÈë"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Patchmode: ÎÞ·¨±£´æÔ­Ê¼Îļþ"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: Patchmode: ÎÞ·¨Éú³É¿ÕµÄԭʼÎļþ"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: ÎÞ·¨É¾³ý±¸·ÝÎļþ"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"¾¯¸æ: ԭʼÎļþ¿ÉÄÜÒѶªÊ§»òËð»µ\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "ÔÚÎļþÕýȷдÈëǰÇëÎðÍ˳ö±à¼­Æ÷£¡"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[dos ¸ñʽ]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[mac ¸ñʽ]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[unix ¸ñʽ]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 ÐУ¬"
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> ÐУ¬"
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "1 ¸ö×Ö·û"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64> ¸ö×Ö·û"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-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
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "¾¯¸æ: ´ËÎļþ×Ô¶ÁÈëºóÒÑ·¢Éú±ä¶¯£¡£¡£¡"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "ȷʵҪдÈëÂð"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: дÈëÎļþ \"%s\" ³ö´í"
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: ¹Ø±ÕÎļþ \"%s\" ³ö´í"
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: ¶ÁÈ¡Îļþ \"%s\" ³ö´í"
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: FileChangedShell ×Ô¶¯ÃüÁîɾ³ýÁË»º³åÇø"
-
-#: ../fileio.c:4894
-#, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: Îļþ \"%s\" ÒѾ­²»´æÔÚ"
-
-#: ../fileio.c:4906
-#, 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
-msgid "See \":help W12\" for more info."
-msgstr "½øÒ»²½ËµÃ÷Çë¼û \":help W12\""
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: ¾¯¸æ: ±à¼­¿ªÊ¼ºó£¬Îļþ \"%s\" Òѱ䶯"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "½øÒ»²½ËµÃ÷Çë¼û \":help W11\""
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr "W16: ¾¯¸æ: ±à¼­¿ªÊ¼ºó£¬Îļþ \"%s\" µÄģʽÒѱ䶯"
-
-#: ../fileio.c:4915
-msgid "See \":help W16\" for more info."
-msgstr "½øÒ»²½ËµÃ÷Çë¼û \":help W16\""
-
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: ¾¯¸æ: ±à¼­¿ªÊ¼ºó£¬Îļþ \"%s\" Òѱ»´´½¨"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "¾¯¸æ"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"È·¶¨(&O)\n"
-"¼ÓÔØÎļþ(&L)"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: ÎÞ·¨ÎªÖØÐ¼ÓÔØ \"%s\" ×ö×¼±¸"
-
-#: ../fileio.c:5078
-#, 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 ""
-
-#. 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"
-"--- Auto-Commands ---"
-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 Auto commands 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
-msgid "E219: Missing {."
-msgstr "E219: ȱÉÙ {¡£"
-
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: ȱÉÙ }¡£"
-
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: ÕÒ²»µ½ÕÛµþ"
-
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: ²»ÄÜÔÚµ±Ç°µÄ 'foldmethod' Ï´´½¨ÕÛµþ"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: ²»ÄÜÔÚµ±Ç°µÄ 'foldmethod' ÏÂɾ³ýÕÛµþ"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--ÒÑÕÛµþ %3ld ÐÐ"
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: Ìí¼Óµ½ÒѶÁ»º³åÇøÖÐ"
-
-#: ../getchar.c:2040
-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
-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
-msgid "E470: Command aborted"
-msgstr "E470: ÃüÁî±»ÖÐÖ¹"
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: ÐèÒª²ÎÊý"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ ºóÃæÓ¦¸Ã¸úÓÐ /¡¢? »ò &"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: ÔÚÃüÁîÐд°¿ÚÖÐÎÞЧ£»<CR> Ö´ÐУ¬CTRL-C Í˳ö"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr "E12: µ±Ç°Ä¿Â¼ÖÐµÄ exrc/vimrc »ò tag ²éÕÒÖв»ÔÊÐí´ËÃüÁî"
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: ȱÉÙ :endif"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: ȱÉÙ :endtry"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: ȱÉÙ :endwhile"
-
-#: ../globals.h:1006
-msgid "E170: Missing :endfor"
-msgstr "E170: ȱÉÙ :endfor"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile ȱÉÙ¶ÔÓ¦µÄ :while"
-
-#: ../globals.h:1008
-msgid "E588: :endfor without :for"
-msgstr "E588: :endfor ȱÉÙ¶ÔÓ¦µÄ :for"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: ÎļþÒÑ´æÔÚ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: ÃüÁîÖ´ÐÐʧ°Ü"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: ÄÚ²¿´íÎó"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "ÒÑÖжÏ"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: ÎÞЧµÄµØÖ·"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: ÎÞЧµÄ²ÎÊý"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: ÎÞЧµÄ²ÎÊý: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: ÎÞЧµÄ±í´ïʽ: %s"
-
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: ÎÞЧµÄ·¶Î§"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: ÎÞЧµÄÃüÁî"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ÊÇĿ¼"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: ÎÞЧµÄ¹ö¶¯´óС"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: µ÷Óú¯Êý¿â \"%s()\" ʧ°Ü"
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: ±ê¼ÇµÄÐкÅÎÞЧ"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: ûÓÐÉ趨±ê¼Ç"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: ²»ÄÜÐ޸ģ¬ÒòΪѡÏî 'modifiable' ÊǹصÄ"
-
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: ½Å±¾Ç¶Ì×¹ýÉî"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: ûÓн»ÌæÎļþ"
-
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ûÓÐÕâ¸öËõд"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ²»ÄÜʹÓà \"!\""
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: ÎÞ·¨Ê¹ÓÃͼÐνçÃæ: ±àÒëʱûÓÐÆôÓÃ"
-
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ûÓÐÕâ¸ö¸ßÁÁȺ×éÃû: %s"
-
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ûÓвåÈë¹ýÎÄ×Ö"
-
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: ûÓÐǰһ¸öÃüÁîÐÐ"
-
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ûÓÐÕâ¸öÓ³Éä"
-
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: ûÓÐÆ¥Åä"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: ûÓÐÆ¥Åä: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ûÓÐÎļþÃû"
-
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: ûÓÐǰһ¸öÌæ»»ÕýÔò±í´ïʽ"
-
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: ûÓÐǰһ¸öÃüÁî"
-
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: ûÓÐǰһ¸öÕýÔò±í´ïʽ"
-
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: ²»ÄÜʹÓ÷¶Î§"
-
-#: ../globals.h:1048
-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
-msgid "E483: Can't get temp file name"
-msgstr "E483: ÎÞ·¨»ñÈ¡ÁÙʱÎļþÃû"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: ÎÞ·¨´ò¿ªÎļþ %s"
-
-#: ../globals.h:1052
-#, 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
-msgid "E38: Null argument"
-msgstr "E38: ¿ÕµÄ²ÎÊý"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: ´Ë´¦ÐèÒªÊý×Ö"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: ÎÞ·¨´ò¿ª´íÎóÎļþ %s"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: ÄÚ´æ²»×㣡"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "ÕÒ²»µ½Ä£Ê½"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: ÕÒ²»µ½Ä£Ê½: %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: ²ÎÊý±ØÐëÊÇÕýÊý"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: ÎÞ·¨»Øµ½Ç°Ò»¸öĿ¼"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: ûÓдíÎó"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr "E776: ûÓÐ location Áбí"
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: ÒÑËð»µµÄÆ¥Åä×Ö·û´®"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: ÒÑË𻵵ÄÕýÔò±í´ïʽ³ÌÐò"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: ÒÑÉ趨ѡÏî 'readonly' (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#: ../globals.h:1073
-#, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: ²»ÄܸıäÖ»¶Á±äÁ¿ \"%s\""
-
-#: ../globals.h:1075
-#, fuzzy, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E46: ²»ÄÜÔÚ sandbox ÖÐÉ趨±äÁ¿: \"%s\""
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: ¶ÁÈ¡´íÎóÎļþʧ°Ü"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: ²»ÔÊÐíÔÚ sandbox ÖÐʹÓÃ"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ²»ÔÊÐíÔÚ´ËʹÓÃ"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ²»Ö§³ÖÉ趨ÆÁĻģʽ"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: ÎÞЧµÄ¹ö¶¯´óС"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: Ñ¡Ïî 'shell' Ϊ¿Õ"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: ÎÞ·¨¶ÁÈ¡ sign Êý¾Ý£¡"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: ½»»»Îļþ¹Ø±Õ´íÎó"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: tag ¶ÑջΪ¿Õ"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: ÃüÁî¹ý¸´ÔÓ"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: Ãû×Ö¹ý³¤"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: [ ¹ý¶à"
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ÎļþÃû¹ý¶à"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: ¶àÓàµÄβ²¿×Ö·û"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: δ֪µÄ±ê¼Ç"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: ÎÞ·¨À©Õ¹Í¨Åä·û"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ²»ÄÜСÓÚ 'winminheight'"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ²»ÄÜСÓÚ 'winminwidth'"
-
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: дÈë³ö´í"
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "¼ÆÊýΪÁã"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: Ôڽű¾»·¾³ÍâʹÓÃÁË <SID>"
-
-#: ../globals.h:1102
-#, c-format
-msgid "E685: Internal error: %s"
-msgstr "E685: ÄÚ²¿´íÎó: %s"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr "E363: ±í´ïʽµÄÄÚ´æÊ¹Óó¬³ö 'maxmempattern'"
-
-#: ../globals.h:1105
-msgid "E749: empty buffer"
-msgstr "E749: ¿ÕµÄ»º³åÇø"
-
-#: ../globals.h:1108
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E682: ÎÞЧµÄËÑË÷±í´ïʽ»ò·Ö¸ô·û"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: ÎļþÒÑÔÚÁíÒ»¸ö»º³åÇøÖб»¼ÓÔØ"
-
-#: ../globals.h:1110
-#, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E764: ûÓÐÉ趨ѡÏî '%s'"
-
-#: ../globals.h:1111
-#, fuzzy
-msgid "E850: Invalid register name"
-msgstr "E354: ÎÞЧµÄ¼Ä´æÆ÷Ãû: '%s'"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "ÒѲéÕÒµ½Îļþ¿ªÍ·£¬ÔÙ´Ó½áβ¼ÌÐø²éÕÒ"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "ÒѲéÕÒµ½Îļþ½á⣬ÔÙ´Ó¿ªÍ·¼ÌÐø²éÕÒ"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: ȱÉÙðºÅ"
-
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: ÎÞЧµÄ²¿·Ö"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: Ó¦¸ÃÒªÓÐÊý×Ö"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "µÚ %d Ò³"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "ûÓÐÒª´òÓ¡µÄÎÄ×Ö"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "ÕýÔÚ´òÓ¡µÚ %d Ò³ (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr "¸´ÖÆ %d / %d"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "ÒÑ´òÓ¡: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "´òÓ¡ÖÐÖ¹"
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: дÈë PostScript Êä³öÎļþ³ö´í"
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: ÎÞ·¨´ò¿ªÎļþ \"%s\""
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: ÎÞ·¨¶ÁÈ¡ PostScript ×ÊÔ´Îļþ \"%s\""
-
-#: ../hardcopy.c:1772
-#, 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
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: Îļþ \"%s\" ²»ÊÇÒÑÖ§³ÖµÄ PostScript ×ÊÔ´Îļþ"
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: \"%s\" ×ÊÔ´Îļþ°æ±¾²»ÕýÈ·"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr "E673: ²»¼æÈݵĶà×Ö½Ú±àÂëºÍ×Ö·û¼¯¡£"
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr "E674: printmbcharset ÔÚ¶à×Ö½Ú±àÂëϲ»ÄÜΪ¿Õ¡£"
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr "E675: ûÓÐÖ¸¶¨¶à×Ö½Ú´òÓ¡µÄĬÈÏ×ÖÌå¡£"
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: ÎÞ·¨´ò¿ª PostScript Êä³öÎļþ"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: ÎÞ·¨´ò¿ªÎļþ \"%s\""
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"prolog.ps\""
-
-#: ../hardcopy.c:2593
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"cidfont.ps\""
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: ÕÒ²»µ½ PostScript ×ÊÔ´Îļþ \"%s.ps\""
-
-#: ../hardcopy.c:2654
-#, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620: ÎÞ·¨×ª»»ÖÁ´òÓ¡±àÂë \"%s\""
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "·¢Ë͵½´òÓ¡»ú¡­¡­"
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: ÎÞ·¨´òÓ¡ PostScript Îļþ"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "´òÓ¡ÈÎÎñÒѱ»·¢ËÍ¡£"
-
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "Ìí¼ÓÒ»¸öеÄÊý¾Ý¿â"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "²éѯһ¸öģʽ"
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "ÏÔʾ´ËÐÅÏ¢"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "½áÊøÒ»¸öÁ¬½Ó"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "ÖØÖÃËùÓÐÁ¬½Ó"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "ÏÔʾÁ¬½Ó"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: Ó÷¨: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "Õâ¸ö cscope ÃüÁî²»Ö§³Ö·Ö¸î´°¿Ú¡£\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: Ó÷¨: cstag <ident>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: ÕÒ²»µ½ tag"
-
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) ´íÎó: %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s ²»ÊÇĿ¼»òÓÐЧµÄ cscope Êý¾Ý¿â"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "Ìí¼ÓÁË cscope Êý¾Ý¿â %s"
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: ¶ÁÈ¡ cscope Á¬½Ó %<PRId64> ³ö´í"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: δ֪µÄ cscope ²éÕÒÀàÐÍ"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: ÎÞ·¨´´½¨ cscope ¹ÜµÀ"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: ÎÞ·¨¶Ô cscope ½øÐÐ fork"
-
-#: ../if_cscope.c:849
-#, fuzzy
-msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection Ö´ÐÐʧ°Ü"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection Ö´ÐÐʧ°Ü"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen to_fp ʧ°Ü"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen fr_fp ʧ°Ü"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: ÎÞ·¨Éú³É cscope ½ø³Ì"
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: ûÓÐ cscope Á¬½Ó"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: cscopequickfix ±êÖ¾ %c ¶Ô %c ÎÞЧ"
-
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: cscope ²éѯ %s %s ûÓÐÕÒµ½Æ¥ÅäµÄ½á¹û"
-
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "cscope ÃüÁî:\n"
-
-#: ../if_cscope.c:1150
-#, fuzzy, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %-30s (Ó÷¨: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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 ""
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: ÖØ¸´µÄ cscope Êý¾Ý¿âδ±»¼ÓÈë"
-
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: ÕÒ²»µ½ cscope Á¬½Ó %s"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "cscope Á¬½Ó %s ÒѹرÕ"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: cs_manage_matches ÑÏÖØ´íÎó"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Cscope tag: %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # ÐÐ "
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "ÎļþÃû / ÉÏÏÂÎÄ / ÐÐ\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: Cscope ´íÎó: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "ËùÓÐ cscope Êý¾Ý¿âÒѱ»ÖØÖÃ"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "ûÓÐ cscope Á¬½Ó\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid Êý¾Ý¿âÃû prepend path\n"
-
-#: ../main.c:144
-msgid "Unknown option argument"
-msgstr "δ֪µÄÑ¡Ïî²ÎÊý"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "±à¼­²ÎÊý¹ý¶à"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "ȱÉÙ±ØÒªµÄ²ÎÊý"
-
-#: ../main.c:150
-msgid "Garbage after option argument"
-msgstr "Ñ¡Ïî²ÎÊýºóµÄÄÚÈÝÎÞЧ"
-
-#: ../main.c:152
-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
-#, c-format
-msgid "%d files to edit\n"
-msgstr "»¹ÓÐ %d ¸öÎļþµÈ´ý±à¼­\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "ÊÔͼÔٴδò¿ª½Å±¾Îļþ: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "ÎÞ·¨´ò¿ª²¢¶ÁÈ¡: \""
-
-#: ../main.c:1393
-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"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "pre-vimrc ÃüÁîÐÐ"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: ÎÞ·¨¶ÁÈ¡ \"%s\""
-
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"¸ü¶àÐÅÏ¢Çë¼û: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[Îļþ ..] ±à¼­Ö¸¶¨µÄÎļþ"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- ´Ó±ê×¼ÊäÈë(stdin)¶ÁÈ¡Îı¾"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t tag ±à¼­ tag ¶¨Òå´¦µÄÎļþ"
-
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [errorfile] ±à¼­µÚÒ»¸ö³ö´í´¦µÄÎļþ"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-"Ó÷¨:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr " vim [²ÎÊý] "
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" »ò:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"²ÎÊý:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\tÔÚÕâÒÔºóÖ»ÓÐÎļþÃû"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\t²»À©Õ¹Í¨Åä·û"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tVi ģʽ (ͬ \"vi\")"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tEx ģʽ (ͬ \"ex\")"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\t°²¾²(Åú´¦Àí)ģʽ (Ö»ÄÜÓë \"ex\" Ò»ÆðʹÓÃ)"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tDiff ģʽ (ͬ \"vimdiff\")"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\tÈÝÒ×ģʽ (ͬ \"evim\"£¬ÎÞģʽ)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\tÖ»¶Áģʽ (ͬ \"view\")"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\tÏÞÖÆÄ£Ê½ (ͬ \"rvim\")"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\t²»¿ÉÐÞ¸Ä(дÈëÎļþ)"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\tÎı¾²»¿ÉÐÞ¸Ä"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\t¶þ½øÖÆÄ£Ê½"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tLisp ģʽ"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\t¼æÈÝ´«Í³µÄ Vi: 'compatible'"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\t²»ÍêÈ«¼æÈÝ´«Í³µÄ Vi: 'nocompatible'"
-
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr ""
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\tµ÷ÊÔģʽ"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\t²»Ê¹Óý»»»Îļþ£¬Ö»Ê¹ÓÃÄÚ´æ"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\tÁгö½»»»Îļþ²¢Í˳ö"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (¸úÎļþÃû)\t\t»Ö¸´±ÀÀ£µÄ»á»°"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\tͬ -r"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\tÒÔ Arabic ģʽÆô¶¯"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\tÒÔ Hebrew ģʽÆô¶¯"
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\tÒÔ Farsi ģʽÆô¶¯"
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminal>\tÉ趨ÖÕ¶ËÀàÐÍΪ <terminal>"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\tʹÓà <vimrc> Ìæ´úÈκΠ.vimrc"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\t²»¼ÓÔØ plugin ½Å±¾"
-
-#: ../main.c:2227
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-P[N]\t\t´ò¿ª N ¸ö±êǩҳ (ĬÈÏÖµ: ÿ¸öÎļþÒ»¸ö)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\t´ò¿ª N ¸ö´°¿Ú (ĬÈÏÖµ: ÿ¸öÎļþÒ»¸ö)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\tͬ -o µ«´¹Ö±·Ö¸î"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\tÆô¶¯ºóÌøµ½Îļþĩβ"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\tÆô¶¯ºóÌøµ½µÚ <lnum> ÐÐ"
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <command>\t¼ÓÔØÈκΠvimrc ÎļþǰִÐÐ <command>"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <command>\t\t¼ÓÔØµÚÒ»¸öÎļþºóÖ´ÐÐ <command>"
-
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <session>\t\t¼ÓÔØµÚÒ»¸öÎļþºóÖ´ÐÐÎļþ <session>"
-
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <scriptin>\t´ÓÎļþ <scriptin> ¶ÁÈëÕý³£Ä£Ê½µÄÃüÁî"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <scriptout>\t½«ËùÓÐÊäÈëµÄÃüÁî×·¼Óµ½Îļþ <scriptout>"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <scriptout>\t½«ËùÓÐÊäÈëµÄÃüÁîдÈëµ½Îļþ <scriptout>"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr ""
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\tʹÓà <viminfo> È¡´ú .viminfo"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h »ò --help\t´òÓ¡°ïÖú(±¾ÐÅÏ¢)²¢Í˳ö"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\t´òÓ¡°æ±¾ÐÅÏ¢²¢Í˳ö"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "ûÓÐÉ趨±ê¼Ç"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: ûÓÐÆ¥Åä \"%s\" µÄ±ê¼Ç"
-
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"±ê¼Ç ÐÐ ÁÐ Îļþ/Îı¾"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-" Ìø×ª ÐÐ ÁÐ Îļþ/Îı¾"
-
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-"\n"
-" ¸Ä±ä ÐÐ ÁÐ Îı¾"
-
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Îļþ±ê¼Ç:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Ìø×ªÁбí (´Óе½¾É):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# ÎļþÄڵıê¼ÇÀúÊ·¼Ç¼ (´Óе½¾É):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "ȱÉÙ '>'"
-
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: ¿éδ±»Ëø¶¨"
-
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: ½»»»Îļþ¶ÁÈ¡¶¨Î»´íÎó"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: ½»»»Îļþ¶ÁÈ¡´íÎó"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: ½»»»ÎļþдÈ붨λ´íÎó"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: ½»»»ÎļþдÈë´íÎó"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: ½»»»ÎļþÒÑ´æÔÚ (·ûºÅÁ¬½Ó¹¥»÷£¿)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: ÕÒ²»µ½¿é 0£¿"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: ÕÒ²»µ½¿é 1£¿"
-
-#: ../memline.c:377
-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
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: àÞ£¬½»»»Îļþ²»¼ûÁË£¡£¡£¡"
-
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: ÎÞ·¨ÖØÃüÃû½»»»Îļþ"
-
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr "E303: ÎÞ·¨´ò¿ª \"%s\" µÄ½»»»Îļþ£¬»Ö¸´½«²»¿ÉÄÜ"
-
-#: ../memline.c:666
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_upd_block0(): ÕÒ²»µ½¿é 0£¿"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: ÕÒ²»µ½ %s µÄ½»»»Îļþ"
-
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr "ÇëÊäÈëҪʹÓõĽ»»»Îļþ±àºÅ (0 Í˳ö): "
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: ÎÞ·¨´ò¿ª %s"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "ÎÞ·¨¶ÁÈ¡¿é 0: "
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"¿ÉÄÜÄãû×ö¹ýÈκÎÐ޸ĻòÊÇ Vim »¹À´²»¼°¸üн»»»Îļþ¡£"
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " ²»ÄÜÔڸð汾µÄ Vim ÖÐʹÓá£\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "ʹÓà Vim 3.0¡£\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %s ¿´ÆðÀ´²»ÏñÊÇ Vim ½»»»Îļþ"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " ²»ÄÜÔÚÕą̂µçÄÔÉÏʹÓá£\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr "´ËÎļþ´´½¨ÓÚ "
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-"£¬\n"
-"»òÊÇ´ËÎļþÒÑË𻵡£"
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr ""
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "ʹÓý»»»Îļþ \"%s\""
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "ԭʼÎļþ \"%s\""
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: ¾¯¸æ: ԭʼÎļþ¿ÉÄÜÒѱ»ÐÞ¸Ä"
-
-#: ../memline.c:1061
-#, 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
-msgid "???MANY LINES MISSING"
-msgstr "???ȱÉÙÁËÌ«¶àÐÐ"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1076
-#, fuzzy
-msgid "???LINE COUNT WRONG"
-msgstr "???ÐÐÊý´íÎó"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1082
-#, fuzzy
-msgid "???EMPTY BLOCK"
-msgstr "???¿ÕµÄ¿é"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1103
-#, fuzzy
-msgid "???LINES MISSING"
-msgstr "???ȱÉÙÁËһЩÐÐ"
-
-#: ../memline.c:1128
-#, 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
-msgid "???BLOCK MISSING"
-msgstr "???ȱÉÙ¿é"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1147
-#, fuzzy
-msgid "??? from here until ???END lines may be messed up"
-msgstr "??? ´ÓÕâÀïµ½ ???END µÄÐпÉÄÜÒÑ»ìÂÒ"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1164
-#, fuzzy
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? ´ÓÕâÀïµ½ ???END µÄÐпÉÄÜÒѱ»²åÈë/ɾ³ý¹ý"
-
-# do not translate to avoid writing Chinese in files
-#: ../memline.c:1181
-#, fuzzy
-msgid "???END"
-msgstr "???END"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: »Ö¸´Òѱ»ÖжÏ"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr "E312: »Ö¸´Ê±·¢Éú´íÎó£»Çë×¢Ò⿪ͷΪ ??? µÄÐÐ"
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "¸ü¶àÐÅÏ¢Çë¼û \":help E312\""
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr "»Ö¸´Íê±Ï¡£ÇëÈ·¶¨Ò»ÇÐÕý³£¡£"
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(Äã¿ÉÄÜÏëÒª½«Õâ¸öÎļþÁí´æÎª±ðµÄÎļþÃû\n"
-
-#: ../memline.c:1252
-#, fuzzy
-msgid "and run diff with the original file to check for changes)"
-msgstr "ÔÙÔËÐÐ diff ÓëÔ­Îļþ±È½ÏÒÔ¼ì²éÊÇ·ñÓиıä)\n"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr ""
-
-#: ../memline.c:1255
-#, fuzzy
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"È»ºó°Ñ .swp Îļþɾµô¡£\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "ÕÒµ½½»»»Îļþ:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr " λÓÚµ±Ç°Ä¿Â¼:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " ʹÓÃÖ¸¶¨µÄÃû×Ö:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " λÓÚĿ¼ "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- ÎÞ --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " ËùÓÐÕß: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " ÈÕÆÚ: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " ÈÕÆÚ: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [À´×Ô Vim °æ±¾ 3.0]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [²»ÏñÊÇ Vim ½»»»Îļþ]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " ÎļþÃû: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" Ð޸Ĺý: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "ÊÇ"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "·ñ"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" Óû§Ãû: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " Ö÷»úÃû: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" Ö÷»úÃû: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" ½ø³Ì ID: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (ÈÔÔÚÔËÐÐ)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [²»ÄÜÔÚ±¾»úÉÏʹÓÃ]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [ÎÞ·¨¶ÁÈ¡]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [ÎÞ·¨´ò¿ª]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: ÎÞ·¨±£Áô£¬Ã»Óн»»»Îļþ"
-
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "ÎļþÒѱ£Áô"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: ±£Áôʧ°Ü"
-
-#: ../memline.c:1819
-#, 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>"
-msgstr "E316: ml_get: ÕÒ²»µ½µÚ %<PRId64> ÐÐ"
-
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: Ö¸Õë¿é id ´íÎó 3"
-
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "stack_idx Ó¦¸ÃÊÇ 0"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: ¸üÐÂÁËÌ«¶àµÄ¿é£¿"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: Ö¸Õë¿é id ´íÎó 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "ɾ³ýÁË¿é 1£¿"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: ÕÒ²»µ½µÚ %<PRId64> ÐÐ"
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: Ö¸Õë¿é id ´íÎó"
-
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "pe_line_count ΪÁã"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: Ðкų¬³ö·¶Î§: %<PRId64> ³¬³ö½áβ"
-
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: ¿é %<PRId64> ÐÐÊý´íÎó"
-
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "¶ÑÕ»´óСÔö¼Ó"
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: Ö¸Õë¿é id ´íÎó 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr "E773: \"%s\" ·ûºÅÁ¬½Ó³öÏÖÑ­»·"
-
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: ×¢Òâ"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"·¢ÏÖ½»»»Îļþ \""
-
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "ÕýÔÚ´ò¿ªÎļþ \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " ±È½»»»ÎļþУ¡\n"
-
-#: ../memline.c:3244
-#, fuzzy
-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."
-msgstr ""
-"\n"
-"(1) ÁíÒ»¸ö³ÌÐò¿ÉÄÜÒ²Ôڱ༭ͬһ¸öÎļþ¡£\n"
-" Èç¹ûÊÇÕâÑù£¬ÐÞ¸ÄʱÇë×¢Òâ±ÜÃâͬһ¸öÎļþ²úÉúÁ½¸ö²»Í¬µÄ°æ±¾¡£\n"
-"\n"
-
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " Í˳ö£¬»òСÐĵؼÌÐø¡£\n"
-
-#: ../memline.c:3246
-#, fuzzy
-msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) Éϴα༭´ËÎļþʱ±ÀÀ£¡£\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " Èç¹ûÊÇÕâÑù£¬ÇëÓà \":recover\" »ò \"vim -r "
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"\"\n"
-" »Ö¸´Ð޸ĵÄÄÚÈÝ (Çë¼û \":help recovery\")¡£\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " Èç¹ûÄãÒѾ­½øÐÐÁ˻ָ´£¬Çëɾ³ý½»»»Îļþ \""
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"\"\n"
-" ÒÔ±ÜÃâÔÙ¿´µ½´ËÏûÏ¢¡£\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "½»»»Îļþ \""
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "\" ÒÑ´æÔÚ£¡"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "VIM - ×¢Òâ"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "½»»»ÎļþÒÑ´æÔÚ£¡"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"ÒÔÖ»¶Á·½Ê½´ò¿ª(&O)\n"
-"Ö±½Ó±à¼­(&E)\n"
-"»Ö¸´(&R)\n"
-"Í˳ö(&Q)\n"
-"ÖÐÖ¹(&A)"
-
-#: ../memline.c:3467
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"ÒÔÖ»¶Á·½Ê½´ò¿ª(&O)\n"
-"Ö±½Ó±à¼­(&E)\n"
-"»Ö¸´(&R)\n"
-"ɾ³ý½»»»Îļþ(&D)\n"
-"Í˳ö(&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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
-msgid "E326: Too many swap files found"
-msgstr "E326: ÕÒµ½Ì«¶à½»»»Îļþ"
-
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: ÄÚ´æ²»×㣡(·ÖÅä %<PRIu64> ×Ö½Ú)"
-
-#: ../menu.c:62
-msgid "E327: Part of menu-item path is not sub-menu"
-msgstr "E327: ²Ëµ¥ÏîµÄij²¿·Ö·¾¶²»ÊÇ×Ӳ˵¥"
-
-#: ../menu.c:63
-msgid "E328: Menu only exists in another mode"
-msgstr "E328: ²Ëµ¥Ö»ÔÚÆäËüģʽÖдæÔÚ"
-
-#: ../menu.c:64
-#, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: ûÓв˵¥ \"%s\""
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-#, fuzzy
-msgid "E792: Empty menu name"
-msgstr "E749: ¿ÕµÄ»º³åÇø"
-
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: ²Ëµ¥Â·¾¶²»ÄÜÖ¸Ïò×Ӳ˵¥"
-
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: ²»ÄܰѲ˵¥ÏîÖ±½Ó¼Óµ½²Ëµ¥À¸ÖÐ"
-
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: ·Ö¸ôÏß²»ÄÜÊDz˵¥Â·¾¶µÄÒ»²¿·Ö"
-
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- ²Ëµ¥ ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: ²Ëµ¥Â·¾¶±ØÐëÖ¸Ïò²Ëµ¥Ïî"
-
-#: ../menu.c:1330
-#, 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
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: ²Ëµ¥Â·¾¶±ØÐëÖ¸Ïò×Ӳ˵¥"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: ÕÒ²»µ½²Ëµ¥ - Çë¼ì²é²Ëµ¥Ãû³Æ"
-
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "´¦Àí %s ʱ·¢Éú´íÎó:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "µÚ %4ld ÐÐ:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: ÎÞЧµÄ¼Ä´æÆ÷Ãû: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr "¼òÌåÖÐÎÄÏûϢά»¤Õß: Yuheng Xie <elephant@linux.net.cn>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "ÒÑÖжÏ: "
-
-#: ../message.c:988
-msgid "Press ENTER or type command to continue"
-msgstr "Çë°´ ENTER »òÆäËüÃüÁî¼ÌÐø"
-
-#: ../message.c:1843
-#, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s µÚ %<PRId64> ÐÐ"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- ¸ü¶à --"
-
-#: ../message.c:2398
-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
-msgid "Question"
-msgstr "ÎÊÌâ"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"ÊÇ(&Y)\n"
-"·ñ(&N)"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"ÊÇ(&Y)\n"
-"·ñ(&N)\n"
-"È¡Ïû(&C)"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"ÊÇ(&Y)\n"
-"·ñ(&N)\n"
-"È«²¿±£´æ(&A)\n"
-"È«²¿¶ªÆú(&D)\n"
-"È¡Ïû(&C)"
-
-#: ../message.c:3058
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E766: printf() µÄ²ÎÊý²»×ã"
-
-#: ../message.c:3119
-#, fuzzy
-msgid "E807: Expected Float argument for printf()"
-msgstr "E766: 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
-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
-msgid "E348: No string under cursor"
-msgstr "E348: ¹â±ê´¦Ã»ÓÐ×Ö·û´®"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: ²»ÄÜÔÚµ±Ç°µÄ 'foldmethod' ÏÂɾ³ý fold"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: ¸Ä±äÁбíΪ¿Õ"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr "E662: ÒÑÔڸıäÁбíµÄ¿ªÊ¼´¦"
-
-#: ../normal.c:5901
-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 ´Î"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "1 ÐÐ %s ÁË %d ´Î"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> ÐÐ %s ÁË 1 ´Î"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> ÐÐ %s ÁË %d ´Î"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "Ëõ½ø %<PRId64> ÐС­¡­ "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "Ëõ½øÁË 1 ÐÐ "
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "Ëõ½øÁË %<PRId64> ÐÐ "
-
-#: ../ops.c:938
-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
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "¸Ä±äÁË %<PRId64> ÐÐ"
-
-#: ../ops.c:2521
-msgid "block of 1 line yanked"
-msgstr "¸´ÖÆÁË 1 ÐеĿé"
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "¸´ÖÆÁË 1 ÐÐ"
-
-#: ../ops.c:2525
-#, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "¸´ÖÆÁË %<PRId64> ÐеĿé"
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "¸´ÖÆÁË %<PRId64> ÐÐ"
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353: ¼Ä´æÆ÷ %s ÀïûÓж«Î÷"
-
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- ¼Ä´æÆ÷ ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "ÎÞЧµÄ¼Ä´æÆ÷Ãû"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# ¼Ä´æÆ÷:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: δ֪µÄ¼Ä´æÆ÷ÀàÐÍ %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> ÁÐ; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Ñ¡ÔñÁË %s%<PRId64>/%<PRId64> ÐÐ; %<PRId64>/%<PRId64> ¸ö´Ê; %<PRId64>/"
-"%<PRId64> ¸ö×Ö½Ú"
-
-#: ../ops.c:5105
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"Ñ¡ÔñÁË %s%<PRId64>/%<PRId64> ÐÐ; %<PRId64>/%<PRId64> ¸ö´Ê; %<PRId64>/"
-"%<PRId64> ¸ö×Ö·û; %<PRId64>/%<PRId64> ¸ö×Ö½Ú"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"µÚ %s/%s ÁÐ; µÚ %<PRId64>/%<PRId64> ÐÐ; µÚ %<PRId64>/%<PRId64> ¸ö´Ê; µÚ "
-"%<PRId64>/%<PRId64> ¸ö×Ö½Ú"
-
-#: ../ops.c:5133
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"µÚ %s/%s ÁÐ; µÚ %<PRId64>/%<PRId64> ÐÐ; µÚ %<PRId64>/%<PRId64> ¸ö´Ê; µÚ "
-"%<PRId64>/%<PRId64> ¸ö×Ö·û; µÚ %<PRId64>/%<PRId64> ¸ö×Ö½Ú"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr ""
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr ""
-
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "¸ÐлÄúÑ¡Ôñ Vim"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: δ֪µÄÑ¡Ïî"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: ²»Ö§³Ö¸ÃÑ¡Ïî"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: ²»ÔÊÐíÔÚ modeline ÖÐʹÓÃ"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr ""
-
-#: ../option.c:2924
-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 ""
-
-#: ../option.c:3966
-msgid "E835: Conflicts with value of 'fillchars'"
-msgstr ""
-
-#: ../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
-msgid "E590: A preview window already exists"
-msgstr "E590: Ô¤ÀÀ´°¿ÚÒÑ´æÔÚ"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: Arabic ÐèÒª UTF-8£¬ÇëÖ´ÐÐ ':set encoding=utf-8'"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: ÖÁÉÙÐèÒª %d ÐÐ"
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: ÖÁÉÙÐèÒª %d ÁÐ"
-
-#: ../option.c:6011
-#, 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
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: = ºóÃæÐèÒªÊý×Ö"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- Öն˱àÂë ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- È«¾ÖÑ¡ÏîÖµ ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- ¾Ö²¿Ñ¡ÏîÖµ ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- Ñ¡Ïî ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: get_varp ´íÎó"
-
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': ÕÒ²»µ½ %s ¶ÔÓ¦µÄ×Ö·û"
-
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': ·ÖºÅºóÓжàÓàµÄ×Ö·û: %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"ÎÞ·¨Ö´ÐÐ shell"
-
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"Shell ÒÑ·µ»Ø"
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-
-# do not translate
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr "dlerror = \"%s\""
-
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: ÔÚ·¾¶ÖÐÕÒ²»µ½Îļþ \"%s\""
-
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: ¸ñʽ»¯×Ö·û´®ÀïÓÐÌ«¶à %%%c "
-
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: ¸ñʽ»¯×Ö·û´®²»Ó¦¸Ã³öÏÖ %%%c "
-
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: ¸ñʽ»¯×Ö·û´®ÀïÉÙÁË ]"
-
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: ¸ñʽ»¯×Ö·û´®ÀïÓв»Ö§³ÖµÄ %%%c "
-
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: ¸ñʽ»¯×Ö·û´®¿ªÍ·ÀïÓв»ÕýÈ·µÄ %%%c "
-
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: ¸ñʽ»¯×Ö·û´®ÀïÓв»ÕýÈ·µÄ %%%c "
-
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: 'errorformat' δÉ趨"
-
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: ÕÒ²»µ½Ä¿Â¼Ãû³Æ»òÊǿյÄĿ¼Ãû³Æ"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: ûÓиü¶àµÄÏî"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d / %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (ÐÐÒÑɾ³ý)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: Quickfix ¶ÑÕ»µ×¶Ë"
-
-#: ../quickfix.c:1869
-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:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr "E683: ȱÉÙÎļþÃû»òģʽÎÞЧ"
-
-#: ../quickfix.c:2911
-#, c-format
-msgid "Cannot open file \"%s\""
-msgstr "ÎÞ·¨´ò¿ªÎļþ \"%s\""
-
-#: ../quickfix.c:3429
-msgid "E681: Buffer is not loaded"
-msgstr "E681: »º³åÇøÎ´¼ÓÔØ"
-
-#: ../quickfix.c:3487
-msgid "E777: String or List expected"
-msgstr "E777: ´Ë´¦ÐèÒª String »òÕß List"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: %s%%[] ÖÐÓÐÎÞЧµÄÏî"
-
-#: ../regexp.c:374
-#, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E769: %s[ ºóȱÉÙ ]"
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: ²»Æ¥ÅäµÄ %s%%("
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: ²»Æ¥ÅäµÄ %s("
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: ²»Æ¥ÅäµÄ %s)"
-
-#: ../regexp.c:378
-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:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: %s%%[ ºóȱÉÙ ]"
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: ¿ÕµÄ %s%%[]"
-
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: ģʽ̫³¤"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: Ì«¶à \\z("
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: Ì«¶à %s("
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: ²»Æ¥ÅäµÄ \\z("
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: %s@ ºóÃæÓÐÎÞЧµÄ×Ö·û"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: Ì«¶à¸´Ô %s{...}s"
-
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: ǶÌ×µÄ %s*"
-
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: ǶÌ×µÄ %s%c"
-
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: ²»ÕýÈ·µØÊ¹Óà \\_"
-
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c Ç°ÃæÎÞÄÚÈÝ"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: ÎÞЧµÄ»ØÒý"
-
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: \\z ºóÃæÓÐÎÞЧµÄ×Ö·û"
-
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E678: %s%%[dxouU] ºóÃæÓÐÎÞЧµÄ×Ö·û"
-
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: %s%% ºóÃæÓÐÎÞЧµÄ×Ö·û"
-
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: %s{...} ÖÐÓï·¨´íÎó"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "Íⲿ·ûºÏ:\n"
-
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr ""
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-
-#. 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 ""
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
-
-#: ../regexp_nfa.c:2042
-#, fuzzy
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: Ì«¶à \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr ""
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
-
-#: ../regexp_nfa.c:6049
-#, fuzzy
-msgid "Could not open temporary log file for writing "
-msgstr "E214: ÕÒ²»µ½ÓÃÓÚдÈëµÄÁÙʱÎļþ"
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " V-Ìæ»»"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " Ìæ»»"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " ·´Ïò"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " ²åÈë"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (²åÈë)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (Ìæ»»)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (V-Ìæ»»)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " Hebrew"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " Arabic"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (ÓïÑÔ)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (Õ³Ìû)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " ¿ÉÊÓ"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " ¿ÉÊÓ ÐÐ"
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " ¿ÉÊÓ ¿é"
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " Ñ¡Ôñ"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " Ñ¡Ôñ ÐÐ"
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " Ñ¡Ôñ ¿é"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "¼Ç¼ÖÐ"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: ÎÞЧµÄ²éÕÒ×Ö·û´®: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: ÒѲéÕÒµ½Îļþ¿ªÍ·ÈÔÕÒ²»µ½ %s"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: ÒѲéÕÒµ½Îļþ½áβÈÔÕÒ²»µ½ %s"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: ÔÚ ';' ºóÃæÓ¦¸ÃÓÐ '?' »ò '/'"
-
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (°üÀ¨ÉÏ´ÎÁгö·ûºÏÏî)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- °üº¬Îļþ "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "ÕÒ²»µ½ "
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "ÔÚ·¾¶ ---\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (ÒÑÁгö)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " ÕÒ²»µ½"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "²éÕÒ°üº¬Îļþ: %s"
-
-#: ../search.c:4216
-#, c-format
-msgid "Searching included file %s"
-msgstr "²éÕÒ°üº¬µÄÎļþ %s"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: µ±Ç°ÐÐÆ¥Åä"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "ËùÓаüº¬Îļþ¶¼ÒÑÕÒµ½"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "ûÓаüº¬Îļþ"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: ÕÒ²»µ½¶¨Òå"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: ÕÒ²»µ½ pattern"
-
-#: ../search.c:4668
-#, fuzzy
-msgid "Substitute "
-msgstr "1 ´ÎÌæ»»£¬"
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-
-#: ../spell.c:951
-msgid "E759: Format error in spell file"
-msgstr "E759: ƴдÎļþ¸ñʽ´íÎó"
-
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr "E758: ÒÑ½Ø¶ÏµÄÆ´Ð´Îļþ"
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬¶àÓàµÄºóÐø×Ö·û: %s"
-
-#: ../spell.c:954
-#, 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
-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
-#, c-format
-msgid "Reading spell file \"%s\""
-msgstr "¶ÁȡƴдÎļþ \"%s\""
-
-#: ../spell.c:2496
-msgid "E757: This does not look like a spell file"
-msgstr "E757: Õâ¿´ÆðÀ´²»ÏñÊÇÆ´Ð´Îļþ"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr "E771: ¾É°æ±¾µÄƴдÎļþ£¬ÐèÒª¸üÐÂ"
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr "E772: Ϊ¸ü¸ß°æ±¾µÄ Vim ËùÓÃµÄÆ´Ð´Îļþ"
-
-#: ../spell.c:2602
-msgid "E770: Unsupported section in spell file"
-msgstr "E770: ƴдÎļþÖдæÔÚ²»Ö§³ÖµÄ½Ú"
-
-#: ../spell.c:3762
-#, c-format
-msgid "Warning: region %s not supported"
-msgstr "¾¯¸æ: ÇøÓò %s ²»Ö§³Ö"
-
-#: ../spell.c:4550
-#, c-format
-msgid "Reading affix file %s ..."
-msgstr "¶ÁÈ¡¸½¼ÓÎļþ %s ¡­¡­"
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr "µ¥´Ê %s ת»»Ê§°Ü£¬µÚ %d ÐÐ: %s"
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr "²»Ö§³Ö %s ÖеÄת»»: ´Ó %s µ½ %s"
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬FLAG µÄÖµÎÞЧ: %s"
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬ÔÚʹÓñêÖ¾ºó³öÏÖ FLAG: %s"
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-
-#: ../spell.c:4747
-#, fuzzy, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDMIN Öµ: %s"
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDWORDMAX Öµ: %s"
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDMIN Öµ: %s"
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ COMPOUNDSYLMAX Öµ: %s"
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄ CHECKCOMPOUNDPATTERN Öµ: %s"
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬ÔÚÁ¬ÐøµÄ¸½¼Ó¿éÖгöÏÖ²»Í¬µÄ×éºÏ±êÖ¾: %s"
-
-#: ../spell.c:4850
-#, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Öظ´µÄ¸½¼ÓÏî: %s"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-"%s µÚ %d ÐУ¬¸½¼ÓÏî±» BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST ʹ"
-"ÓÃ: %s"
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª Y »ò N: %s"
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬´íÎóµÄÌõ¼þ: %s"
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª REP(SAL) ¼ÆÊý"
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr "%s µÚ %d ÐУ¬´Ë´¦ÐèÒª MAP ¼ÆÊý"
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr "%s µÚ %d ÐУ¬MAP ÖдæÔÚÖØ¸´µÄ×Ö·û"
-
-#: ../spell.c:5176
-#, 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
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr "ÔÚûÓÐ SYLLABLE µÄÇé¿öÏÂʹÓÃÁË COMPOUNDSYLMAX"
-
-#: ../spell.c:5236
-msgid "Too many postponed prefixes"
-msgstr "Ì«¶àÑÓ³Ùǰ׺"
-
-#: ../spell.c:5238
-msgid "Too many compound flags"
-msgstr "Ì«¶à×éºÏ±êÖ¾"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr "Ì«¶àÑÓ³Ùǰ׺ºÍ/»ò×éºÏ±êÖ¾"
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr "%s ÖÐȱÉÙ SOFO%s ÐÐ"
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr "%s ͬʱ³öÏÖ SQL ºÍ SOFO ÐÐ"
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬±êÖ¾²»ÊÇÊý×Ö: %s"
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬ÎÞЧµÄ±êÖ¾: %s"
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr "%s µÄÖµÓëÁíÒ»¸ö .aff ÎļþÖÐʹÓõÄÖµ²»Ïàͬ"
-
-#: ../spell.c:5602
-#, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "¶ÁÈ¡×ÖµäÎļþ %s ¡­¡­"
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr "E760: %s ÖÐûÓе¥´Ê¼ÆÊý"
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr "µÚ %6d ÐУ¬µÚ %6d ¸öµ¥´Ê - %s"
-
-#: ../spell.c:5691
-#, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Öظ´µÄµ¥´Ê: %s"
-
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Ê×´ÎÖØ¸´µÄµ¥´Ê: %s"
-
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr "´æÔÚ %d ¸öÖØ¸´µÄµ¥´Ê£¬ÔÚ %s ÖÐ"
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr "ºöÂÔÁ˺¬ÓÐ·Ç ASCII ×Ö·ûµÄ %d ¸öµ¥´Ê£¬ÔÚ %s ÖÐ"
-
-#: ../spell.c:6115
-#, c-format
-msgid "Reading word file %s ..."
-msgstr "¶ÁÈ¡µ¥´ÊÎļþ %s ¡­¡­"
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬µ¥´ÊºóµÄ /encoding= ÐÐÒѱ»ºöÂÔ: %s"
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Öظ´µÄ /regions= ÐÐÒѱ»ºöÂÔ: %s"
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬Ì«¶àÇøÓò: %s"
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬/ ÐÐÒѱ»ºöÂÔ: %s"
-
-#: ../spell.c:6224
-#, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬ÎÞЧµÄÇøÓòºÅ: %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr "%s µÚ %d ÐУ¬²»¿Éʶ±ðµÄ±êÖ¾: %s"
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr "ºöÂÔÁ˺¬ÓÐ·Ç ASCII ×Ö·ûµÄ %d ¸öµ¥´Ê"
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr "ѹËõÁË %d/%d ¸ö½Úµã£»Ê£Óà %d (%d%%)"
-
-#: ../spell.c:7340
-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
-msgid "Performing soundfolding..."
-msgstr "ÕýÔÚ soundfolding¡­¡­"
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr "soundfolding ºóµÄµ¥´ÊÊý: %<PRId64>"
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr "µ¥´Ê×ÜÊý: %d"
-
-#: ../spell.c:7655
-#, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "дÈ뽨ÒéÎļþ %s ¡­¡­"
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr "¹À¼ÆÔËÐÐʱÄÚ´æÓÃÁ¿: %d ×Ö½Ú"
-
-#: ../spell.c:7820
-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 ¸öÇøÓò"
-
-#: ../spell.c:7846
-#, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E755: %s ³öÏÖÎÞЧµÄ·¶Î§"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr "¾¯¸æ: ͬʱָ¶¨ÁË compounding ºÍ NOBREAK"
-
-#: ../spell.c:7920
-#, c-format
-msgid "Writing spell file %s ..."
-msgstr "дÈëÆ´Ð´Îļþ %s ¡­¡­"
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr "Íê³É£¡"
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr "E765: 'spellfile' ûÓÐ %<PRId64> Ïî"
-
-#: ../spell.c:8074
-#, fuzzy, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr "´Ó %s ÖÐɾ³ýÁ˵¥´Ê"
-
-#: ../spell.c:8117
-#, fuzzy, c-format
-msgid "Word '%.*s' added to %s"
-msgstr "Ïò %s ÖÐÌí¼ÓÁ˵¥´Ê"
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr "E763: ƴдÎļþÖ®¼äµÄ×Ö·û²»Ïàͬ"
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr "±§Ç¸£¬Ã»Óн¨Òé"
-
-#: ../spell.c:8687
-#, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "±§Ç¸£¬Ö»ÓÐ %<PRId64> Ìõ½¨Òé"
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "½« \"%.*s\" ¸ÄΪ£º"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr " < \"%.*s\""
-
-#: ../spell.c:8882
-msgid "E752: No previous spell replacement"
-msgstr "E752: ֮ǰûÓÐÆ´Ð´Ìæ»»"
-
-#: ../spell.c:8925
-#, c-format
-msgid "E753: Not found: %s"
-msgstr "E753: ÕÒ²»µ½: %s"
-
-#: ../spell.c:9276
-#, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E778: ¿´ÆðÀ´²»ÏñÊÇ .sug Îļþ: %s"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr ""
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr ""
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr ""
-
-#: ../spell.c:9305
-#, fuzzy, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E47: ¶ÁÈ¡´íÎóÎļþʧ°Ü"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr ""
-
-#: ../syntax.c:266
-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:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: ÎÞ´ËÓï·¨ cluster: \"%s\""
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "C·ç¸ñ×¢ÊÍͬ²½ÖÐ"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "ûÓÐͬ²½"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "ͬ²½¿ªÊ¼"
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr "Ðкų¬³ö·¶Î§"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- Ó﷨ͬ²½ÏîÄ¿ (Syntax sync items) ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"ͬ²½ÖÐ:"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- Óï·¨ÏîÄ¿ ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: ÎÞ´ËÓï·¨ cluster: \"%s\""
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "×îС"
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "×î´ó"
-
-#: ../syntax.c:3513
-#, fuzzy
-msgid "; match "
-msgstr "Æ¥Åä %d"
-
-#: ../syntax.c:3515
-#, fuzzy
-msgid " line breaks"
-msgstr "ÉÙÓÚÒ»ÐÐ"
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
-
-#: ../syntax.c:4096
-#, fuzzy
-msgid "E844: invalid cchar value"
-msgstr "E474: ÎÞЧµÄ²ÎÊý"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: ÕÒ²»µ½ %s µÄ region item"
-
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: ÐèÒªÎļþÃû³Æ"
-
-#: ../syntax.c:4221
-#, fuzzy
-msgid "E847: Too many syntax includes"
-msgstr "E77: ÎļþÃû¹ý¶à"
-
-#: ../syntax.c:4303
-#, fuzzy, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E747: ȱÉÙ ']': %s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: ȱÉÙ '=': %s"
-
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: syntax region %s µÄ²ÎÊýÌ«ÉÙ"
-
-#: ../syntax.c:4870
-#, fuzzy
-msgid "E848: Too many syntax clusters"
-msgstr "E391: ÎÞ´ËÓï·¨ cluster: \"%s\""
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: ûÓÐÖ¸¶¨µÄÊôÐÔ"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: ÕÒ²»µ½·Ö¸ô·ûºÅ: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: '%s' ºóÃæµÄ¶«Î÷²»ÄÜʶ±ð"
-
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: Ó﷨ͬ²½: Á¬½ÓÐзûºÅÖ¸¶¨ÁËÁ½´Î"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: ÎÞЧµÄ²ÎÊý: %s"
-
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: ȱÉٵȺÅ: %s"
-
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: ¿ÕµÄ²ÎÊý: %s"
-
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %s ²»ÄÜÔڴ˳öÏÖ"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %s ±ØÐëÊÇÁбíÀïµÄµÚÒ»¸ö"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: ²»ÕýÈ·µÄ×éÃû: %s"
-
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: ²»ÕýÈ·µÄ :syntax ×ÓÃüÁî: %s"
-
-#: ../syntax.c:5854
-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: ×éÃûÖдæÔÚ²»¿ÉÏÔʾ×Ö·û"
-
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: ×éÃûÖк¬ÓÐÎÞЧ×Ö·û"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr ""
-
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: ÒÑÔÚ tag ¶ÑÕ»µ×²¿"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: ÒÑÔÚ tag ¶ÑÕ»¶¥²¿"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: Òѵ½µÚÒ»¸öÆ¥ÅäµÄ tag"
-
-#: ../tag.c:504
-#, 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
-msgid "E427: There is only one matching tag"
-msgstr "E427: Ö»ÓÐÒ»¸öÆ¥ÅäµÄ tag"
-
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: ¼ºµ½×îºóÒ»¸öÆ¥ÅäµÄ tag"
-
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "Îļþ \"%s\" ²»´æÔÚ"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "ÕÒµ½ tag: %d / %d%s"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " »ò¸ü¶à"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " ÒÔ²»Í¬´óСдÀ´Ê¹Óà tag£¡"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: Îļþ \"%s\" ²»´æÔÚ"
-
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # µ½ tag ´Ó ÐÐ ÔÚ Îļþ/Îı¾"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "²éÕÒ tag Îļþ %s"
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr ""
-
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: Tag Îļþ \"%s\" ¸ñʽ´íÎó"
-
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "ÔÚµÚ %<PRId64> ×Ö½Ú֮ǰ"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Tag ÎļþδÅÅÐò: %s"
-
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: ûÓÐ tag Îļþ"
-
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: ÕÒ²»µ½ tag ģʽ"
-
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: ÕÒ²»µ½ tag£¬ÊÔ×Ų£¡"
-
-#: ../tag.c:2797
-#, fuzzy, c-format
-msgid "Duplicate field name: %s"
-msgstr "%s µÚ %d ÐУ¬Öظ´µÄ¸½¼ÓÏî: %s"
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' δ֪¡£¿ÉÓõÄÄÚ½¨ÖÕ¶ËÓÐ:"
-
-#: ../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 ÖÐÕÒ²»µ½ÖÕ¶ËÏî"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: termcap ÖÐûÓÐ \"%s\" Ïî"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: ÖÕ¶ËÐèÒªÄÜÁ¦ \"cm\""
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- Öն˰´¼ü ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: ¶Á´íÎó£¬Í˳öÖÐ...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-#, fuzzy
-msgid "E881: Line count changed unexpectedly"
-msgstr "E787: ÒâÍâµØ¸Ä±äÁË»º³åÇø"
-
-#: ../undo.c:627
-#, fuzzy, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E212: ÎÞ·¨´ò¿ª²¢Ð´ÈëÎļþ"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr ""
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr ""
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr ""
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr ""
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr ""
-
-#: ../undo.c:1121
-#, fuzzy, c-format
-msgid "Writing undo file: %s"
-msgstr "дÈë viminfo Îļþ \"%s\""
-
-#: ../undo.c:1213
-#, fuzzy, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E297: ½»»»ÎļþдÈë´íÎó"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr ""
-
-#: ../undo.c:1292
-#, fuzzy, c-format
-msgid "Reading undo file: %s"
-msgstr "¶ÁÈ¡µ¥´ÊÎļþ %s ¡­¡­"
-
-#: ../undo.c:1299
-#, fuzzy, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E195: ÎÞ·¨´ò¿ª²¢¶ÁÈ¡ viminfo Îļþ"
-
-#: ../undo.c:1308
-#, fuzzy, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E753: ÕÒ²»µ½: %s"
-
-#: ../undo.c:1313
-#, fuzzy, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E484: ÎÞ·¨´ò¿ªÎļþ %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr ""
-
-#: ../undo.c:1497
-#, fuzzy, c-format
-msgid "Finished reading undo file %s"
-msgstr "½áÊøÖ´ÐÐ %s"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr "ÒÑλÓÚ×î¾ÉµÄ¸Ä±ä"
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr "ÒÑλÓÚ×îеĸıä"
-
-#: ../undo.c:1806
-#, fuzzy, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "ÕÒ²»µ½³·ÏúºÅ %<PRId64>"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: ÐкŴíÎó"
-
-#: ../undo.c:2183
-msgid "more line"
-msgstr "Ðб»¼ÓÈë"
-
-#: ../undo.c:2185
-msgid "more lines"
-msgstr "Ðб»¼ÓÈë"
-
-#: ../undo.c:2187
-msgid "line less"
-msgstr "Ðб»È¥µô"
-
-#: ../undo.c:2189
-msgid "fewer lines"
-msgstr "Ðб»È¥µô"
-
-#: ../undo.c:2193
-msgid "change"
-msgstr "Ðз¢Éú¸Ä±ä"
-
-#: ../undo.c:2195
-msgid "changes"
-msgstr "Ðз¢Éú¸Ä±ä"
-
-#: ../undo.c:2225
-#, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> %s£»%s #%<PRId64> %s"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr "before"
-
-#: ../undo.c:2228
-msgid "after"
-msgstr "after"
-
-#: ../undo.c:2325
-msgid "Nothing to undo"
-msgstr "Î޿ɳ·Ïú"
-
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr ""
-
-#: ../undo.c:2360
-#, fuzzy, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> ÁÐ; "
-
-#: ../undo.c:2372
-#, fuzzy
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E407: %s ²»ÄÜÔڴ˳öÏÖ"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: ³·ÏúÁбíËð»µ"
-
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: ÕÒ²»µ½Òª³·ÏúµÄÐÐ"
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"°üº¬²¹¶¡: "
-
-#: ../version.c:627
-#, fuzzy
-msgid ""
-"\n"
-"Extra patches: "
-msgstr "Íⲿ·ûºÏ:\n"
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "ÐÞ¸ÄÕß "
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"±àÒë"
-
-#: ../version.c:649
-msgid "by "
-msgstr "Õß "
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"¾ÞÐͰ汾 "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "ÎÞͼÐνçÃæ¡£"
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " ¿ÉʹÓÃ(+)Óë²»¿ÉʹÓÃ(-)µÄ¹¦ÄÜ:\n"
-
-#: ../version.c:667
-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
-msgid " fall-back for $VIM: \""
-msgstr " $VIM Ô¤ÉèÖµ: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr " $VIMRUNTIME Ô¤ÉèÖµ: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "±àÒ뷽ʽ: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Á´½Ó·½Ê½: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " µ÷ÊÔ°æ±¾"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi IMproved"
-
-#: ../version.c:769
-msgid "version "
-msgstr "°æ±¾ "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "ά»¤ÈË Bram Moolenaar µÈ"
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim ÊÇ¿É×ÔÓÉ·Ö·¢µÄ¿ª·ÅÔ´´úÂëÈí¼þ"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "°ïÖúÎڸɴïµÄ¿ÉÁ¯¶ùͯ£¡"
-
-#: ../version.c:777
-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
-msgid "Sponsor Vim development!"
-msgstr "ÔÞÖú Vim µÄ¿ª·¢£¡"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "³ÉΪ Vim µÄ×¢²áÓû§£¡"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr "ÊäÈë :help sponsor<Enter> ²é¿´ËµÃ÷ "
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr "ÊäÈë :help register<Enter> ²é¿´ËµÃ÷ "
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "²Ëµ¥ Help->Sponsor/Register ²é¿´ËµÃ÷ "
-
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "ÒѾ­Ö»Ê£Ò»¸ö´°¿ÚÁË"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: ûÓÐÔ¤ÀÀ´°¿Ú"
-
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: ²»ÄÜͬʱ½øÐÐ topleft ºÍ botright ·Ö¸î"
-
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: ÓÐÆäËü·Ö¸î´°¿Úʱ²»ÄÜÐýת"
-
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: ²»ÄܹرÕ×îºóÒ»¸ö´°¿Ú"
-
-#: ../window.c:1810
-#, fuzzy
-msgid "E813: Cannot close autocmd window"
-msgstr "E444: ²»ÄܹرÕ×îºóÒ»¸ö´°¿Ú"
-
-#: ../window.c:1814
-#, fuzzy
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E444: ²»ÄܹرÕ×îºóÒ»¸ö´°¿Ú"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: ÆäËü´°¿ÚÓиıäµÄÄÚÈÝ"
-
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: ¹â±ê´¦Ã»ÓÐÎļþÃû"
-
-#~ msgid "Patch file"
-#~ msgstr "Patch Îļþ"
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "È·¶¨(&O)\n"
-#~ "È¡Ïû(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: ûÓе½ Vim ·þÎñÆ÷µÄÁ¬½Ó"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: ÎÞ·¨·¢Ë͵½ %s"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: ÎÞ·¨¶ÁÈ¡·þÎñÆ÷ÏìÓ¦"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: ÎÞ·¨·¢Ë͵½¿Í»§¶Ë"
-
-#~ msgid "Save As"
-#~ msgstr "Áí´æÎª"
-
-#~ msgid "Edit File"
-#~ msgstr "±à¼­Îļþ"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (ÕÒ²»µ½)"
-
-#~ msgid "Source Vim script"
-#~ msgstr "Ö´ÐÐ Vim ½Å±¾"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "ÔÚд°¿Ú±à¼­Îļþ"
-
-#~ msgid "Append File"
-#~ msgstr "×·¼ÓÎļþ"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "´°¿ÚλÖÃ: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "±£´æÖض¨Ïò"
-
-#~ msgid "Save View"
-#~ msgstr "±£´æÊÓͼ"
-
-#~ msgid "Save Session"
-#~ msgstr "±£´æ»á»°"
-
-#~ msgid "Save Setup"
-#~ msgstr "±£´æÉ趨"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ´Ë°æ±¾ÎÞ¸´ºÏ×Ö·û(digraph)"
-
-#~ msgid "Reading from stdin..."
-#~ msgstr "´Ó±ê×¼ÊäÈë¶ÁÈ¡..."
-
-#~ msgid "[NL found]"
-#~ msgstr "[ÕÒµ½ NL]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[ÒѼÓÃÜ]"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans ²»ÔÊÐíδÐ޸ĵĻº³åÇøÐ´Èë"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "NetBeans ²»ÔÊÐí»º³åÇø²¿·ÖдÈë"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Resource fork »á¶ªÊ§ (Çë¼Ó ! Ç¿ÖÆÖ´ÐÐ)"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: ÎÞ·¨Æô¶¯Í¼ÐνçÃæ"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: ÎÞ·¨¶ÁÈ¡Îļþ \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: ÎÞ·¨Æô¶¯Í¼ÐνçÃæ£¬ÕÒ²»µ½ÓÐЧµÄ×ÖÌå"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: ÎÞЧµÄ 'guifontwide'"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' µÄÖµÎÞЧ"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: ÎÞ·¨·ÖÅäÑÕÉ« %s"
-
-#~ msgid "No match at cursor, finding next"
-#~ msgstr "ÔÚ¹â±ê´¦Ã»ÓÐÆ¥Å䣬²éÕÒÏÂÒ»¸ö"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<ÎÞ·¨´ò¿ª>"
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ÎÞ·¨»ñÈ¡×ÖÌå %s"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: ÎÞ·¨·µ»Øµ±Ç°Ä¿Â¼"
-
-#~ msgid "Pathname:"
-#~ msgstr "·¾¶:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: ÎÞ·¨»ñÈ¡µ±Ç°Ä¿Â¼"
-
-#~ msgid "OK"
-#~ msgstr "È·¶¨"
-
-#~ msgid "Cancel"
-#~ msgstr "È¡Ïû"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "¹ö¶¯Ìõ²¿¼þ: ÎÞ·¨»ñÈ¡»¬¿éͼÏñµÄ¼¸ºÎ´óС"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim ¶Ô»°¿ò"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: ²»ÄÜͬʱʹÓÃÏûÏ¢ºÍ»Øµ÷º¯ÊýÀ´´´½¨ BalloonEval"
-
-#~ msgid "Vim dialog..."
-#~ msgstr "Vim ¶Ô»°¿ò..."
-
-#~ msgid "Input _Methods"
-#~ msgstr "ÊäÈë·¨(_M)"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - ²éÕÒºÍÌæ»»..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - ²éÕÒ..."
-
-#~ msgid "Find what:"
-#~ msgstr "²éÕÒÄÚÈÝ:"
-
-#~ msgid "Replace with:"
-#~ msgstr "Ìæ»»Îª:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "Æ¥ÅäÍêÕûµÄ´Ê"
-
-#~ msgid "Match case"
-#~ msgstr "Æ¥Åä´óСд"
-
-#~ msgid "Direction"
-#~ msgstr "·½Ïò"
-
-#~ msgid "Up"
-#~ msgstr "ÏòÉÏ"
-
-#~ msgid "Down"
-#~ msgstr "ÏòÏÂ"
-
-#~ msgid "Find Next"
-#~ msgstr "²éÕÒÏÂÒ»¸ö"
-
-#~ msgid "Replace"
-#~ msgstr "Ìæ»»"
-
-#~ msgid "Replace All"
-#~ msgstr "È«²¿Ìæ»»"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: ´Ó»á»°¹ÜÀíÆ÷ÊÕµ½ \"die\" ÇëÇó\n"
-
-#~ msgid "Close"
-#~ msgstr "¹Ø±Õ"
-
-#~ msgid "New tab"
-#~ msgstr "н¨±êÇ©"
-
-#~ msgid "Open Tab..."
-#~ msgstr "´ò¿ª±êÇ©..."
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: Ö÷´°¿Ú±»ÒâÍâµØ´Ý»Ù\n"
-
-#~ msgid "Font Selection"
-#~ msgstr "Ñ¡Ôñ×ÖÌå"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "ʹÓà CUT_BUFFER0 À´È¡´ú¿ÕÑ¡Ôñ"
-
-#~ msgid "&Filter"
-#~ msgstr "¹ýÂË(&F)"
-
-#~ msgid "&Cancel"
-#~ msgstr "È¡Ïû(&C)"
-
-#~ msgid "Directories"
-#~ msgstr "Ŀ¼"
-
-#~ msgid "Filter"
-#~ msgstr "¹ýÂËÆ÷"
-
-#~ msgid "&Help"
-#~ msgstr "°ïÖú(&H)"
-
-#~ msgid "Files"
-#~ msgstr "Îļþ"
-
-#~ msgid "&OK"
-#~ msgstr "È·¶¨(&O)"
-
-#~ msgid "Selection"
-#~ msgstr "Ñ¡Ôñ"
-
-#~ msgid "Find &Next"
-#~ msgstr "²éÕÒÏÂÒ»¸ö(&N)"
-
-#~ msgid "&Replace"
-#~ msgstr "Ìæ»»(&R)"
-
-#~ msgid "Replace &All"
-#~ msgstr "È«²¿Ìæ»»(&A)"
-
-#~ msgid "&Undo"
-#~ msgstr "³·Ïú(&U)"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: ÕÒ²»µ½´°¿Ú±êÌâ \"%s\""
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: ²»Ö§³ÖµÄ²ÎÊý: \"-%s\"£»ÇëʹÓà OLE °æ±¾¡£"
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: ÎÞ·¨ÔÚ MDI Ó¦ÓóÌÐòÖдò¿ª´°¿Ú"
-
-#~ msgid "Close tab"
-#~ msgstr "¹Ø±Õ±êÇ©"
-
-#~ msgid "Open tab..."
-#~ msgstr "´ò¿ª±êÇ©..."
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "²éÕÒ×Ö·û´® (ʹÓà '\\\\' À´²éÕÒ '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "²éÕÒºÍÌæ»»×Ö·û´® (ʹÓà '\\\\' À´²éÕÒ '\\')"
-
-#~ msgid "Not Used"
-#~ msgstr "δʹÓÃ"
-
-#~ msgid "Directory\t*.nothing\n"
-#~ msgstr "Ŀ¼\t*.nothing\n"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: ÎÞ·¨·ÖÅäÑÕÉ«±íÏijЩÑÕÉ«¿ÉÄܲ»ÕýÈ·"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Fontset %s ȱÉÙÏÂÁÐ×Ö·û¼¯µÄ×ÖÌå:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: Fontset Ãû³Æ: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "'%s' ²»Êǹ̶¨¿í¶ÈµÄ×ÖÌå"
-
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: Fontset Ãû³Æ: %s\n"
-
-#~ msgid "Font0: %s\n"
-#~ msgstr "×ÖÌå0: %s\n"
-
-#~ msgid "Font1: %s\n"
-#~ msgstr "×ÖÌå1: %s\n"
-
-#~ 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 ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "×ÖÌå1µÄ¿í¶È: %<PRId64>\n"
-#~ "\n"
-
-#~ msgid "Invalid font specification"
-#~ msgstr "Ö¸¶¨ÁËÎÞЧµÄ×ÖÌå"
-
-#~ msgid "&Dismiss"
-#~ msgstr "È¡Ïû(&D)"
-
-#~ msgid "no specific match"
-#~ msgstr "ÕÒ²»µ½Æ¥ÅäµÄÏî"
-
-#~ msgid "Vim - Font Selector"
-#~ msgstr "Vim - ×ÖÌåÑ¡ÔñÆ÷"
-
-#~ msgid "Name:"
-#~ msgstr "Ãû³Æ:"
-
-#~ msgid "Encoding:"
-#~ msgstr "±àÂë:"
-
-#~ msgid "Font:"
-#~ msgstr "×ÖÌå:"
-
-#~ msgid "Style:"
-#~ msgstr "·ç¸ñ:"
-
-#~ msgid "Size:"
-#~ msgstr "³ß´ç:"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Hangul automata ´íÎó"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat ´íÎó"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: ÎÞ·¨´ò¿ª cscope Êý¾Ý¿â: %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: ÎÞ·¨»ñÈ¡ cscope Êý¾Ý¿âÐÅÏ¢"
-
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: ÒÑ´ïµ½ cscope µÄ×î´óÁ¬½ÓÊý"
-
-#~ msgid ""
-#~ "???: Sorry, this command is disabled, the MzScheme library could not be "
-#~ "loaded."
-#~ msgstr "???: ±§Ç¸£¬´ËÃüÁî²»¿ÉÓã¬ÎÞ·¨¼ÓÔØ MzScheme ¿â"
-
-#~ msgid "invalid expression"
-#~ msgstr "ÎÞЧµÄ±í´ïʽ"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "±àÒëʱûÓÐÆôÓñí´ïʽ"
-
-#~ msgid "hidden option"
-#~ msgstr "Òþ²ØµÄÑ¡Ïî"
-
-#~ msgid "unknown option"
-#~ msgstr "δ֪µÄÑ¡Ïî"
-
-#~ msgid "window index is out of range"
-#~ msgstr "´°¿ÚË÷Òý³¬³ö·¶Î§"
-
-#~ msgid "couldn't open buffer"
-#~ msgstr "ÎÞ·¨´ò¿ª»º³åÇø"
-
-#~ msgid "cannot save undo information"
-#~ msgstr "ÎÞ·¨±£´æ³·ÏúÐÅÏ¢"
-
-#~ msgid "cannot delete line"
-#~ msgstr "ÎÞ·¨É¾³ýÐÐ"
-
-#~ msgid "cannot replace line"
-#~ msgstr "ÎÞ·¨Ìæ»»ÐÐ"
-
-#~ msgid "cannot insert line"
-#~ msgstr "ÎÞ·¨²åÈëÐÐ"
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "×Ö·û´®²»Äܰüº¬»»ÐÐ(NL)"
-
-#~ msgid "Vim error: ~a"
-#~ msgstr "Vim ´íÎó: ~a"
-
-#~ msgid "Vim error"
-#~ msgstr "Vim ´íÎó"
-
-#~ msgid "buffer is invalid"
-#~ msgstr "»º³åÇøÎÞЧ"
-
-#~ msgid "window is invalid"
-#~ msgstr "´°¿ÚÎÞЧ"
-
-#~ msgid "linenr out of range"
-#~ msgstr "Ðкų¬³ö·¶Î§"
-
-#~ msgid "not allowed in the Vim sandbox"
-#~ msgstr "²»ÔÊÐíÔÚ sandbox ÖÐʹÓÃ"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr "E263: ±§Ç¸£¬´ËÃüÁî²»¿ÉÓã¬ÎÞ·¨¼ÓÔØ Python ¿â¡£"
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: ²»Äܵݹéµ÷Óà Python"
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "²»ÄÜɾ³ý OutputObject ÊôÐÔ"
-
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspace ±ØÐëÊÇÕûÊý"
-
-#~ msgid "invalid attribute"
-#~ msgstr "ÎÞЧµÄÊôÐÔ"
-
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines() ÐèÒª×Ö·û´®Áбí×÷²ÎÊý"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: ³õʼ»¯ I/O ¶ÔÏó³ö´í"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "ÊÔͼÒýÓÃÒѱ»É¾³ýµÄ»º³åÇø"
-
-#~ msgid "line number out of range"
-#~ msgstr "Ðкų¬³ö·¶Î§"
-
-#~ msgid "<buffer object (deleted) at %8lX>"
-#~ msgstr "<»º³åÇø¶ÔÏó(ÒÑɾ³ý): %8lX>"
-
-#~ msgid "invalid mark name"
-#~ msgstr "ÎÞЧµÄ±ê¼ÇÃû³Æ"
-
-#~ msgid "no such buffer"
-#~ msgstr "ÎÞ´Ë»º³åÇø"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "ÊÔͼÒýÓÃÒѱ»É¾³ýµÄ´°¿Ú"
-
-#~ msgid "readonly attribute"
-#~ msgstr "Ö»¶ÁÊôÐÔ"
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "¹â±êλÖÃÔÚ»º³åÇøÍâ"
-
-#~ msgid "<window object (deleted) at %.8lX>"
-#~ msgstr "<´°¿Ú¶ÔÏó(ÒÑɾ³ý): %.8lX>"
-
-#~ msgid "<window object (unknown) at %.8lX>"
-#~ msgstr "<´°¿Ú¶ÔÏó(δ֪): %.8lX>"
-
-#~ msgid "<window %d>"
-#~ msgstr "<´°¿Ú %d>"
-
-#~ msgid "no such window"
-#~ msgstr "ÎÞ´Ë´°¿Ú"
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr "E266: ±§Ç¸£¬´ËÃüÁî²»¿ÉÓã¬ÎÞ·¨¼ÓÔØ Ruby ¿â"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: δ֪µÄ longjmp ״̬ %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "Çл»ÊµÏÖ/¶¨Òå"
-
-#~ msgid "Show base class of"
-#~ msgstr "ÏÔʾ base class of:"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "ÏÔʾ±»¸²¸ÇµÄ³ÉÔ±º¯Êý"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "»Ö¸´: ´ÓÎļþ"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "»Ö¸´: ´Ó¶ÔÏó"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "»Ö¸´: ´ÓËùÓÐÏîÄ¿"
-
-#~ msgid "Retrieve"
-#~ msgstr "»Ö¸´"
-
-#~ msgid "Show source of"
-#~ msgstr "ÏÔʾԴ´úÂë: "
-
-#~ msgid "Find symbol"
-#~ msgstr "²éÕÒ symbol"
-
-#~ msgid "Browse class"
-#~ msgstr "ä¯ÀÀ class"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "ÏÔʾ²ã´Î¹ØÏµµÄÀà"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "ÏÔʾ restricted ²ã´Î¹ØÏµµÄ class"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref ²Î¿¼µ½"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ±»Ë­²Î¿¼:"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ÓÐ"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref ±»Ë­Ê¹ÓÃ:"
-
-#~ msgid "Show docu of"
-#~ msgstr "ÏÔʾÎļþ: "
-
-#~ msgid "Generate docu for"
-#~ msgstr "²úÉúÎļþ: "
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "²»ÄÜÁ¬½Óµ½ SNiFF+¡£Çë¼ì²é»·¾³±äÁ¿ ($PATH Àï±ØÐè¿ÉÒÔÕÒµ½ sniffemacs)\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: ¶ÁÈ¡´íÎó. È¡ÏûÁ¬½Ó"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ Ŀǰ"
-
-#~ msgid "not "
-#~ msgstr "δ"
-
-#~ msgid "connected"
-#~ msgstr "Á¬½ÓÖÐ"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: ²»ÕýÈ·µÄ SNiff+ µ÷ÓÃ: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: Á¬½Óµ½ SNiFF+ ʧ°Ü"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: δÁ¬½Óµ½ SNiFF+"
-
-#~ msgid "E279: Not a SNiFF+ buffer"
-#~ msgstr "E279: ²»ÊÇ SNiFF+ µÄ»º³åÇø"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: дÈë´íÎó¡£½áÊøÁ¬½Ó"
-
-#~ msgid "invalid buffer number"
-#~ msgstr "ÎÞЧµÄ»º³åÇøºÅ"
-
-#~ msgid "not implemented yet"
-#~ msgstr "ÉÐδʵÏÖ"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "ÎÞ·¨É趨ÐÐ"
-
-#~ msgid "mark not set"
-#~ msgstr "ûÓÐÉ趨±ê¼Ç"
-
-#~ msgid "row %d column %d"
-#~ msgstr "µÚ %d ÐÐ µÚ %d ÁÐ"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "ÎÞ·¨²åÈë/×·¼ÓÐÐ"
-
-#~ msgid "unknown flag: "
-#~ msgstr "δ֪µÄ±êÖ¾: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "δ֪µÄ vim Ñ¡Ïî"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "¼üÅÌÖжÏ"
-
-#~ msgid "vim error"
-#~ msgstr "vim ´íÎó"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "ÎÞ·¨´´½¨»º³åÇø/´°¿ÚÃüÁî: ¶ÔÏ󽫱»É¾³ý"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "ÎÞ·¨×¢²á»Øµ÷ÃüÁî: »º³åÇø/´°¿ÚÒѱ»É¾³ý"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr "E280: TCL ÑÏÖØ´íÎó: reflist Ë𻵣¡£¿Ç뱨¸æ¸ø vim-dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr "ÎÞ·¨×¢²á»Øµ÷ÃüÁî: ÕÒ²»µ½»º³åÇø/´°¿ÚÒýÓÃ"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr "E571: ±§Ç¸£¬´ËÃüÁî²»¿ÉÓã¬ÎÞ·¨¼ÓÔØ Tcl ¿â"
-
-#~ 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 "E572: exit code %d"
-#~ msgstr "E572: Í˳ö·µ»ØÖµ %d"
-
-#~ msgid "cannot get line"
-#~ msgstr "ÎÞ·¨»ñÈ¡ÐÐ"
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "ÎÞ·¨×¢²áÃüÁî·þÎñÆ÷Ãû"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: ÎÞ·¨·¢ËÍÃüÁĿµÄ³ÌÐò"
-
-#~ msgid "E573: Invalid server id used: %s"
-#~ msgstr "E573: ʹÓÃÁËÎÞЧµÄ·þÎñÆ÷ id: %s"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM ʵÀý×¢²áÊôÐÔÓÐÎó¡£ÒÑɾ³ý£¡"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "´Ë Vim ±àÒëʱûÓмÓÈë diff ¹¦ÄÜ"
-
-#~ msgid "Vim: Error: Failure to start gvim from NetBeans\n"
-#~ msgstr "Vim: ´íÎó: ÎÞ·¨´Ó NetBeans ÖÐÆô¶¯ gvim\n"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\t×¢²á´Ë gvim µ½ OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\tÈ¡Ïû OLE ÖÐµÄ gvim ×¢²á"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\tʹÓÃͼÐνçÃæ (ͬ \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f »ò --nofork\tǰ̨: Æô¶¯Í¼ÐνçÃæÊ±²» fork"
-
-#~ msgid "-V[N]\t\tVerbose level"
-#~ msgstr "-V[N]\t\tVerbose µÈ¼¶"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\t²»Ê¹Óà newcli À´´ò¿ª´°¿Ú"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\tʹÓà <device> ½øÐÐÊäÈëÊä³ö"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\tʹÓà <gvimrc> Ìæ´úÈκΠ.gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\t±à¼­¼ÓÃܵÄÎļþ"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\t½« vim ÓëÖ¸¶¨µÄ X-server Á¬½Ó"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\t²»Á¬½Óµ½ X Server"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\tÈçÓпÉÄÜ£¬ÔÚ Vim ·þÎñÆ÷Éϱ༭Îļþ <files>"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> ͬÉÏ£¬ÕÒ²»µ½·þÎñÆ÷ʱ²»±§Ô¹"
-
-#~ 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 "--remote-tab <files> As --remote but open tab page for each file"
-#~ msgstr "--remote-tab <files> ͬ --remote µ«¶Ôÿ¸öÎļþ´ò¿ªÒ»¸ö±êǩҳ"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\tËͳö <keys> µ½ Vim ·þÎñÆ÷²¢Í˳ö"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\tÔÚ Vim ·þÎñÆ÷ÉÏÇó <expr> µÄÖµ²¢´òÓ¡½á¹û"
-
-#~ 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 ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (Motif °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (neXtaw °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (Athena °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\tÔÚ <display> ÉÏÔËÐÐ vim"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\tÆô¶¯ºó×îС»¯"
-
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <name>\t\t¶ÁÈ¡ Resource ʱ°Ñ vim ÊÓΪ <name>"
-
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (ÉÐδʵÏÖ)\n"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\tʹÓà <color> ×÷Ϊ±³¾°É« (Ò²¿ÉÓà -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\tʹÓà <color> ×÷Ϊһ°ãÎÄ×ÖÑÕÉ« (Ò²¿ÉÓà -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\tʹÓà <font> ×÷Ϊһ°ã×ÖÌå (Ò²¿ÉÓà -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\tʹÓà <font> ×÷Ϊ´ÖÌå×ÖÌå"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <font>\tʹÓà <font> ×÷ΪбÌå×ÖÌå"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\tʹÓà <geom> ×÷Ϊ³õʼλÖà (Ò²¿ÉÓà -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\tÉ趨±ß¿ò¿í¶ÈΪ <width> (Ò²¿ÉÓà -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr "-scrollbarwidth <width> É趨¹ö¶¯Ìõ¿í¶ÈΪ <width> (Ò²¿ÉÓà -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <height>\tÉ趨²Ëµ¥À¸¸ß¶ÈΪ <height> (Ò²¿ÉÓà -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\tʹÓ÷´ÏÔ (Ò²¿ÉÓà -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\t²»Ê¹Ó÷´ÏÔ (Ò²¿ÉÓà +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\tÉ趨ָ¶¨µÄ×ÊÔ´"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (RISC OS °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <number>\t´°¿Ú³õʼ¿í¶È"
-
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <number>\t´°¿Ú³õʼ¸ß¶È"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim (GTK+ °æ±¾) ¿Éʶ±ðµÄ²ÎÊý:\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\tÔÚ <display> ÉÏÔËÐÐ vim (Ò²¿ÉÓà --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\tÉèÖÃÓÃÓÚÇø·ÖÖ÷´°¿ÚµÄ´°¿Ú½ÇÉ«Ãû"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\tÔÚÁíÒ»¸ö GTK ²¿¼þÖдò¿ª Vim"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <parent title>\tÔÚ¸¸Ó¦ÓóÌÐòÖдò¿ª Vim"
-
-#~ msgid "No display"
-#~ msgstr "ûÓÐ display"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": ·¢ËÍʧ°Ü¡£\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": ·¢ËÍʧ°Ü¡£³¢ÊÔ±¾µØÖ´ÐÐ\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "%d ÖÐ %d Òѱ༭"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "ûÓÐ display: ·¢Ëͱí´ïʽʧ°Ü¡£\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": ·¢Ëͱí´ïʽʧ°Ü¡£\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: ÎÞЧµÄ´úÂëÒ³"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: ÎÞ·¨´´½¨ÊäÈëÉÏÏÂÎÄ"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: ÎÞ·¨´ò¿ªÊäÈë·¨"
-
-#~ 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 ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [²»ÄÜÔڸð汾µÄ Vim ÉÏʹÓÃ]"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "˺Ï´˲˵¥"
-
-#~ msgid "Select Directory dialog"
-#~ msgstr "Ñ¡ÔñĿ¼¶Ô»°¿ò"
-
-#~ msgid "Save File dialog"
-#~ msgstr "±£´æÎļþ¶Ô»°¿ò"
-
-#~ msgid "Open File dialog"
-#~ msgstr "´ò¿ªÎļþ¶Ô»°¿ò"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: ±§Ç¸£¬¿ØÖÆÌ¨Ä£Ê½ÏÂûÓÐÎļþä¯ÀÀÆ÷"
-
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: ÕýÔÚ±£ÁôÎļþ¡­¡­\n"
-
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: ½áÊø¡£\n"
-
-#~ msgid "ERROR: "
-#~ msgstr "´íÎó: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[×Ö½Ú] ×ܹ² alloc-free %<PRIu64>-%<PRIu64>£¬Ê¹ÓÃÖÐ %<PRIu64>£¬¸ß·åʹÓà "
-#~ "%<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[µ÷ÓÃ] ×ܹ² re/malloc(): %<PRIu64>£¬×ܹ² free()': %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: ´ËÐйý³¤"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: ÄÚ²¿´íÎó: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: ÎÞЧµÄÊó±êÐÎ×´"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "ÊäÈëÃÜÂë: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "ÇëÔÙÊäÈëÒ»´Î: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "Á½´ÎÃÜÂ벻ƥÅ䣡"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "ÎÞ·¨Á¬½Óµ½ Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "ÎÞ·¨Á¬½Óµ½ Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: NetBeans Á¬½ÓÐÅÏ¢ÎļþÖдíÎóµÄ·ÃÎÊģʽ: \"%s\""
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "´Ó Netbeans Ì×½Ó×Ö¶ÁÈ¡"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: »º³åÇø %<PRId64> ¶ªÊ§ NetBeans Á¬½Ó"
-
-#~ msgid "E505: "
-#~ msgstr "E505: "
-
-#~ msgid "E775: Eval feature not available"
-#~ msgstr "E775: ÇóÖµ¹¦Äܲ»¿ÉÓÃ"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "ÊÍ·ÅÁË %<PRId64> ÐÐ"
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: ÔÚͼÐνçÃæÖв»ÄܸıäÖÕ¶Ë"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: ÇëÓà \":gui\" Æô¶¯Í¼ÐνçÃæ"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: ÔÚ GTK+ 2 ͼÐνçÃæÖв»Äܸü¸Ä"
-
-#~ msgid "E596: Invalid font(s)"
-#~ msgstr "E596: ÎÞЧµÄ×ÖÌå"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: ÎÞ·¨Ñ¡Ôñ Fontset"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: ÎÞЧµÄ Fontset"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: ÎÞ·¨Ñ¡Ôñ¿í×ÖÌå"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: ÎÞЧµÄ¿í×ÖÌå"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: ²»Ö§³ÖÊó±ê"
-
-#~ msgid "cannot open "
-#~ msgstr "²»ÄÜ´ò¿ª"
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: ²»ÄÜ´ò¿ª´°¿Ú!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "ÐèÒª Amigados °æ±¾ 2.04 ÒÔÉÏ\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "ÐèÒª %s °æ±¾ %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "²»ÄÜ´ò¿ª NIL:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "²»ÄÜ´´½¨ "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim ·µ»ØÖµ: %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "²»ÄÜÇл»Ö÷¿ØÌ¨(console)ģʽ !?\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ²»ÊÇÖ÷¿ØÌ¨(console)??\n"
-
-#~ msgid "E360: Cannot execute shell with -f option"
-#~ msgstr "E360: ²»ÄÜÓà -f Ñ¡ÏîÖ´ÐÐ shell"
-
-#~ msgid "Cannot execute "
-#~ msgstr "²»ÄÜÖ´ÐÐ "
-
-#~ msgid "shell "
-#~ msgstr "shell "
-
-#~ msgid " returned\n"
-#~ msgstr " ÒÑ·µ»Ø\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE ̫С"
-
-#~ msgid "I/O ERROR"
-#~ msgstr "I/O ´íÎó"
-
-#~ msgid "Message"
-#~ msgstr "ÏûÏ¢"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ²»ÊÇ 80, ²»ÄÜÖ´ÐÐÍⲿÃüÁî"
-
-#~ msgid "E237: Printer selection failed"
-#~ msgstr "E237: Ñ¡Ôñ´òÓ¡»úʧ°Ü"
-
-#~ msgid "to %s on %s"
-#~ msgstr "´Ó %s µ½ %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: δ֪µÄ´òÓ¡»ú×ÖÌå: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: ´òÓ¡´íÎó: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "´òÓ¡ '%s'"
-
-#~ 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 "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Ë«ÖØÐźţ¬Í˳öÖÐ\n"
-
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: À¹½Øµ½ÖÂÃüÐźÅ(deadly signal) %s\n"
-
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: À¹½Øµ½ÖÂÃüÐźÅ(deadly signal)\n"
-
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "´ò¿ª X display ÓÃʱ %<PRId64> Ãë"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\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 ³¬Ê±"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÎÞ·¨Ö´ÐÐ shell sh\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÎÞ·¨½¨Á¢¹ÜµÀ\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÎÞ·¨ fork\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "ÃüÁîÒѽáÊø\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP ¶ªÊ§Á˵½ ICE µÄÁ¬½Ó"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "´ò¿ª X display ʧ°Ü"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP ´¦Àí save-yourself ÇëÇó"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "XSMP ´ò¿ªÁ¬½Ó"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICE Á¬½Ó¼àÊÓʧ°Ü"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection µ÷ÓÃʧ°Ü: %s"
-
-#~ msgid "At line"
-#~ msgstr "ÔÚÐкŠ"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "ÎÞ·¨¼ÓÔØ vim32.dll£¡"
-
-#~ msgid "VIM Error"
-#~ msgstr "VIM ´íÎó"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "ÎÞ·¨ÐÞÕýµ½ DLL µÄº¯ÊýÖ¸Õë!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "Shell ·µ»Ø %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: À¹½Øµ½ %s ʼþ\n"
-
-#~ msgid "close"
-#~ msgstr "¹Ø±Õ"
-
-#~ msgid "logoff"
-#~ msgstr "×¢Ïû"
-
-#~ msgid "shutdown"
-#~ msgstr "¹Ø»ú"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: ÕÒ²»µ½ÃüÁî"
-
-#~ 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 Warning"
-#~ msgstr "Vim ¾¯¸æ"
-
-#~ msgid "Conversion in %s not supported"
-#~ msgstr "²»Ö§³Ö %s ÖеÄת»»"
-
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: ʹÓÃÁ˲»ÕýÈ·µÄ²ÎÊý"
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Tag Îļþ·¾¶±»½Ø¶ÏΪ %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "Æô¶¯Ð shell\n"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "ÎÞ·¨³·Ïú£»Çë¼ÌÐø"
-
-#~ msgid "number changes time"
-#~ msgstr " ±àºÅ ¸Ä±ä ʱ¼ä"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 λͼÐνçÃæ°æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 λͼÐνçÃæ°æ±¾"
-
-#~ msgid " in Win32s mode"
-#~ msgstr " Win32s ģʽ"
-
-#~ msgid " with OLE support"
-#~ msgstr " ´ø OLE Ö§³Ö"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 λ¿ØÖÆÌ¨°æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16 λ¿ØÖÆÌ¨°æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 λ MS-DOS °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 λ MS-DOS °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
-#~ msgstr ""
-#~ "\n"
-#~ "RISC OS °æ±¾"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "´óÐͰ汾 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "Õý³£°æ±¾ "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "СÐͰ汾 "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "΢ÐͰ汾 "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "´ø GTK2-GNOME ͼÐνçÃæ¡£"
-
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "´ø GTK-GNOME ͼÐνçÃæ¡£"
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "´ø GTK2 ͼÐνçÃæ¡£"
-
-#~ msgid "with GTK GUI."
-#~ msgstr "´ø GTK ͼÐνçÃæ¡£"
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "´ø X11-Motif ͼÐνçÃæ¡£"
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "´ø X11-neXtaw ͼÐνçÃæ¡£"
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "´ø X11-Athena ͼÐνçÃæ¡£"
-
-#~ msgid "with Photon GUI."
-#~ msgstr "´ø Photon ͼÐνçÃæ¡£"
-
-#~ msgid "with GUI."
-#~ msgstr "´øÍ¼ÐνçÃæ¡£"
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "´ø Carbon ͼÐνçÃæ¡£"
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "´ø Cocoa ͼÐνçÃæ¡£"
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "´ø(´«Í³)ͼÐνçÃæ¡£"
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ϵͳ gvimrc Îļþ: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " Óû§ gvimrc Îļþ: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr "µÚ¶þÓû§ gvimrc Îļþ: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr "µÚÈýÓû§ gvimrc Îļþ: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " ϵͳ²Ëµ¥Îļþ: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "±àÒëÆ÷: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "²Ëµ¥ Help->Orphans ²é¿´ËµÃ÷ "
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "ÎÞģʽÔËÐУ¬ÊäÈëÎÄ×Ö¼´²åÈë"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "²Ëµ¥ Edit->Global Settings->Toggle Insert Mode "
-
-#, fuzzy
-#~ msgid " for two modes "
-#~ msgstr " # pid Êý¾Ý¿âÃû³Æ prepend path\n"
-
-#, fuzzy
-#~ msgid " for Vim defaults "
-#~ msgstr " # pid Êý¾Ý¿âÃû³Æ prepend path\n"
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "¾¯¸æ: ¼ì²âµ½ Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "ÊäÈë :help windows95<Enter> ²é¿´Ïà¹ØËµÃ÷ "
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: ÎÞ·¨¼ÓÔØ¿â %s"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr "±§Ç¸£¬´ËÃüÁî²»¿ÉÓÃ: ÎÞ·¨¼ÓÔØ Perl ¿â¡£"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "Óöà¸ö Vim ±à¼­(&M)"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "Óõ¥¸ö Vim ±à¼­(&V)"
-
-#~ msgid "Diff with Vim"
-#~ msgstr "Óà Vim ±È½Ï(diff)"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "Óà Vim ±à¼­(&V)"
-
-#~ msgid "Edit with existing Vim - "
-#~ msgstr "Óõ±Ç°µÄ Vim ±à¼­ - "
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "Óà Vim ±à¼­Ñ¡ÖеÄÎļþ"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "´´½¨½ø³Ìʧ°Ü: Çë¼ì²é gvim ÊÇ·ñÔÚ·¾¶ÖУ¡"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll ´íÎó"
-
-#~ msgid "Path length too long!"
-#~ msgstr "·¾¶Ì«³¤£¡"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: δ֪µÄ Fontset: %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: δ֪µÄ×ÖÌå: %s"
-
-#~ msgid "E236: Font \"%s\" is not fixed-width"
-#~ msgstr "E236: ×ÖÌå \"%s\" ²»Êǵȿí×ÖÌå"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: ÎÞ·¨¼ÓÔØ¿âº¯Êý %s"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: ÎÞ·¨Ê¹Óà Hebrew: ±àÒëʱûÓÐÆôÓÃ\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: ÎÞ·¨Ê¹Óà Farsi: ±àÒëʱûÓÐÆôÓÃ\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: ÎÞ·¨Ê¹Óà Arabic: ±àÒëʱûÓÐÆôÓÃ\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: ûÓÐÃû½Ð \"%s\" µÄÒÑ×¢²áµÄ·þÎñÆ÷"
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: ÎÞ·¨´ò¿ª display"
-
-#~ msgid "E449: Invalid expression received"
-#~ msgstr "E449: ÊÕµ½ÎÞЧµÄ±í´ïʽ"
-
-#~ msgid "E744: NetBeans does not allow changes in read-only files"
-#~ msgstr "E744: NetBeans ²»ÔÊÐí¸Ä±äÖ»¶ÁÎļþ"
-
-#~ msgid "Affix flags ignored when PFXPOSTPONE used in %s line %d: %s"
-#~ msgstr "%s µÚ %d ÐУ¬Ê¹Óà PFXPOSTPONE ʱ¸½¼Ó±êÖ¾±»ºöÂÔ: %s"
-
-#~ msgid "[No file]"
-#~ msgstr "[δÃüÃû]"
-
-#~ msgid "[Error List]"
-#~ msgstr "[´íÎóÁбí]"
-
-#~ msgid "E106: Unknown variable: \"%s\""
-#~ msgstr "E106: 䶨ÒåµÄ±äÁ¿: \"%s\""
-
-#~ msgid "function "
-#~ msgstr "º¯Êý "
-
-#~ msgid "E130: Undefined function: %s"
-#~ msgstr "E130: º¯Êý %s ÉÐ䶨Òå"
-
-#~ msgid "Run Macro"
-#~ msgstr "Ö´Ðкê"
-
-#~ msgid "E242: Color name not recognized: %s"
-#~ msgstr "E242: %s Ϊ²»ÄÜʶ±ðµÄÑÕÉ«Ãû³Æ"
-
-#~ msgid "error reading cscope connection %d"
-#~ msgstr "¶ÁÈ¡ cscope Á¬½Ó %d ʱ´íÎó"
-
-#~ msgid "E260: cscope connection not found"
-#~ msgstr "E260: ÕÒ²»µ½ cscope Á¬½Ó"
-
-#~ msgid "cscope connection closed"
-#~ msgstr "cscope Á¬½ÓÒѹرÕ"
-
-#~ msgid "couldn't malloc\n"
-#~ msgstr "²»ÄÜʹÓà malloc\n"
-
-#~ msgid "%2d %-5ld %-34s <none>\n"
-#~ msgstr "%2d %-5ld %-34s <ÎÞ>\n"
-
-#~ msgid "E249: couldn't read VIM instance registry property"
-#~ msgstr "E249: ²»ÄܶÁÈ¡ VIM µÄ ×¢²á±íÊôÐÔ"
-
-#~ msgid "\"\n"
-#~ msgstr "\"\n"
-
-#~ msgid "--help\t\tShow Gnome arguments"
-#~ msgstr "--help\t\tÏÔʾ Gnome Ïà¹Ø²ÎÊý"
-
-#~ msgid "[string too long]"
-#~ msgstr "[×Ö·û´®Ì«³¤]"
-
-#~ msgid "Hit ENTER to continue"
-#~ msgstr "Çë°´ ENTER ¼ÌÐø"
-
-#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
-#~ msgstr " (RET/BS: ÏòÏÂ/ÏòÉÏÒ»ÐÐ, ¿Õ¸ñ/b: Ò»Ò³, d/u: °ëÒ³, q: Í˳ö)"
-
-#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
-#~ msgstr " (RET: ÏòÏÂÒ»ÐÐ, ¿Õ°×¼ü: Ò»Ò³, d: °ëÒ³, q: Í˳ö)"
-
-#~ msgid "E361: Crash intercepted; regexp too complex?"
-#~ msgstr "E361: ²»ÄÜÖ´ÐÐ; regular expression Ì«¸´ÔÓ?"
-
-#~ msgid "E363: pattern caused out-of-stack error"
-#~ msgstr "E363: regular expression Ôì³É¶ÑÕ»ÓùâµÄ´íÎó"
-
-#~ msgid " BLOCK"
-#~ msgstr " ¿é"
-
-#~ msgid " LINE"
-#~ msgstr " ÐÐ"
-
-#~ msgid "Enter nr of choice (<CR> to abort): "
-#~ msgstr "ÊäÈë nr »òÑ¡Ôñ (<CR> Í˳ö): "
-
-#~ msgid "Linear tag search"
-#~ msgstr "ÏßÐÔ²éÕÒ±êÇ© (Tags)"
-
-#~ msgid "Binary tag search"
-#~ msgstr "¶þ½øÖƲéÕÒ(Binary search) ±êÇ©(Tags)"
-
-#~ msgid "with BeOS GUI."
-#~ msgstr "ʹÓà BeOS ͼÐνçÃæ¡£"
diff --git a/src/nvim/po/zh_TW.UTF-8.po b/src/nvim/po/zh_TW.UTF-8.po
index 79e09c83d1..3c1dd463b7 100644
--- a/src/nvim/po/zh_TW.UTF-8.po
+++ b/src/nvim/po/zh_TW.UTF-8.po
@@ -2509,10 +2509,10 @@ msgstr "E216: 無此群組或事件: %s"
#: ../fileio.c:6090
msgid ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
msgstr ""
"\n"
-"--- Auto-Commands ---"
+"--- Autocommands ---"
#: ../fileio.c:6293
#, fuzzy, c-format
@@ -2533,8 +2533,8 @@ msgstr "E218: autocommand å±¤æ•¸éŽæ·±"
#: ../fileio.c:7143
#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "%s Auto commands: \"%s\""
+msgid "%s Autocommands for \"%s\""
+msgstr "%s Autocommands: \"%s\""
#: ../fileio.c:7149
#, c-format
@@ -2725,11 +2725,6 @@ msgstr "E49: 錯誤的æ²å‹•大å°"
msgid "E901: Job table is full"
msgstr ""
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
#: ../globals.h:1024
#, c-format
msgid "E364: Library call failed for \"%s()\""
@@ -3427,7 +3422,7 @@ msgstr "-q [errorfile] 編輯時載入第一個錯誤"
msgid ""
"\n"
"\n"
-"usage:"
+"Usage:"
msgstr ""
"\n"
"\n"
@@ -4304,12 +4299,6 @@ msgstr "行 %4ld:"
msgid "E354: Invalid register name: '%s'"
msgstr "E354: 暫存器å稱錯誤: '%s'"
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr ""
-"正體中文訊æ¯ç¶­è­·è€…: Francis S.Lin <piaip@csie.ntu.edu."
-"tw>, Cecil Sheng <b7506022@csie.ntu.edu.tw>"
-
#: ../message.c:986
msgid "Interrupt: "
msgstr "已中斷: "
diff --git a/src/nvim/po/zh_TW.po b/src/nvim/po/zh_TW.po
deleted file mode 100644
index 07d510c0c6..0000000000
--- a/src/nvim/po/zh_TW.po
+++ /dev/null
@@ -1,7910 +0,0 @@
-# Traditional Chinese Translation for Vim vim:set foldmethod=marker:
-#
-# Do ":help uganda" in Vim to read copying and usage conditions.
-# Do ":help credits" in Vim to see a list of people who contributed.
-#
-# FIRST AUTHOR Francis S.Lin <piaip@csie.ntu.edu.tw>, 2000
-# FIRST RELEASE Thu Jun 14 14:24:17 CST 2001
-#
-# Last update: 2005/01/27 07:03 (6.3)
-#
-# To update, search pattern: /fuzzy\|^msgstr ""\(\n"\)\@!
-#
-# DO NOT USE WORDS WITH BACKSLASH ('\') AS SECOND BYTE OF BIG5 CHARS
-# EG: '¥\', # ³\¥\»# [blacklist: À\¬\¾\¯\½\¶\²\Æ\°\Â\¿\Á\Å\§\ª\«\]
-# [blacklist: ®\±\Ã\Ä\´\µ\·\¹\º\¤\¦\­\á\ä\]
-# you can replace these characters with alternative words.
-# THIS WILL CAUSE INCOMPATIBLE ON gettext 0.10.36+
-#
-# Note (2005.01.27):
-# A bug was found for UTF8 mode.
-# > msgid "%<PRId64> fewer lines" "on %<PRId64> lines"
-# If you don't put more (at least 2) spaces after %<PRId64>
-# gvim/win32 will crash (no reason).
-# So please change [¦æ"] to [¦æ "]
-#
-# Q. How to use UTF8 mode on Win32?
-# A. A simple configuration:
-# set encoding=utf-8; let $LANG='zh_TW.UTF-8';
-# (set langmenu=none or ..)
-# set fileencodings=ucs-bom,utf-8,japan,taiwan,prc
-# set fileencoding=taiwan (or utf-8)
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: Vim(Traditional Chinese)\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2014-05-26 14:21+0200\n"
-"PO-Revision-Date: Mon Feb 19 22:49:21 CST 2001\n"
-"Last-Translator: Hung-Te Lin <piaip@csie.ntu.edu.tw>\n"
-"Language-Team: Hung-Te Lin <piaip@csie.ntu.edu.tw>, Cecil Sheng "
-"<b7506022@csie.ntu.edu.tw>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=big5\n"
-"Content-Transfer-Encoding: 8-bit\n"
-
-#: ../api/private/helpers.c:201
-#, fuzzy
-msgid "Unable to get option value"
-msgstr "µLªk¶Ç°e¦^À³°T®§"
-
-#: ../api/private/helpers.c:204
-msgid "internal error: unknown option type"
-msgstr ""
-
-#: ../buffer.c:92
-msgid "[Location List]"
-msgstr ""
-
-#: ../buffer.c:93
-msgid "[Quickfix List]"
-msgstr ""
-
-#: ../buffer.c:94
-msgid "E855: Autocommands caused command to abort"
-msgstr ""
-
-#: ../buffer.c:135
-msgid "E82: Cannot allocate any buffer, exiting..."
-msgstr "E82: µLªk°t¸m¥ô¦ó½w½Ä°Ï¡AÂ÷¶}µ{¦¡..."
-
-#: ../buffer.c:138
-msgid "E83: Cannot allocate buffer, using other one..."
-msgstr "E83: µLªk°t¸m½w½Ä°Ï¡A¨Ï¥Î¥t¤@­Ó½w½Ä°Ï...."
-
-#: ../buffer.c:763
-msgid "E515: No buffers were unloaded"
-msgstr "E515: ¨S¦³ÄÀ©ñ¥ô¦ó½w½Ä°Ï"
-
-#: ../buffer.c:765
-msgid "E516: No buffers were deleted"
-msgstr "E516: ¨S¦³§R°£¥ô¦ó½w½Ä°Ï"
-
-#: ../buffer.c:767
-msgid "E517: No buffers were wiped out"
-msgstr "E517: ¨S¦³²M°£¥ô¦ó½w½Ä°Ï"
-
-#: ../buffer.c:772
-msgid "1 buffer unloaded"
-msgstr "¤wÄÀ©ñ¤@­Ó½w½Ä°Ï"
-
-#: ../buffer.c:774
-#, c-format
-msgid "%d buffers unloaded"
-msgstr "¤wÄÀ©ñ %d ­Ó½w½Ä°Ï"
-
-#: ../buffer.c:777
-msgid "1 buffer deleted"
-msgstr "¤w§R°£¤@­Ó½w½Ä°Ï"
-
-#: ../buffer.c:779
-#, c-format
-msgid "%d buffers deleted"
-msgstr "¤w§R°£ %d ­Ó½w½Ä°Ï"
-
-#: ../buffer.c:782
-msgid "1 buffer wiped out"
-msgstr "¤w§R°£¤@­Ó½w½Ä°Ï"
-
-#: ../buffer.c:784
-#, c-format
-msgid "%d buffers wiped out"
-msgstr "¤w§R°£ %d ­Ó½w½Ä°Ï"
-
-#: ../buffer.c:806
-msgid "E90: Cannot unload last buffer"
-msgstr "E90: µLªkÄÀ©ñ³Ì«á¤@­Ó½w½Ä°Ï"
-
-#: ../buffer.c:874
-msgid "E84: No modified buffer found"
-msgstr "E84: ¨S¦³­×§ï¹Lªº½w½Ä°Ï"
-
-#. back where we started, didn't find anything.
-#: ../buffer.c:903
-msgid "E85: There is no listed buffer"
-msgstr "E85: ¨S¦³¦C¥Xªº½w½Ä°Ï"
-
-#: ../buffer.c:913
-#, c-format
-msgid "E86: Buffer %<PRId64> does not exist"
-msgstr "E86: ½w½Ä°Ï %<PRId64> ¤£¦s¦b"
-
-#: ../buffer.c:915
-msgid "E87: Cannot go beyond last buffer"
-msgstr "E87: µLªk¤Á´«¨ì§ó«á­±ªº½w½Ä°Ï"
-
-#: ../buffer.c:917
-msgid "E88: Cannot go before first buffer"
-msgstr "E88: µLªk¤Á´«¨ì§ó«e­±ªº½w½Ä°Ï"
-
-#: ../buffer.c:945
-#, c-format
-msgid ""
-"E89: No write since last change for buffer %<PRId64> (add ! to override)"
-msgstr "E89: ¤w§ó§ï¹L½w½Ä°Ï %<PRId64> ¦ý©|¥¼¦sÀÉ (¥i¥Î ! ±j¨î°õ¦æ)"
-
-#. wrap around (may cause duplicates)
-#: ../buffer.c:1423
-msgid "W14: Warning: List of file names overflow"
-msgstr "W14: ĵ§i: ÀɦW¹L¦h"
-
-#: ../buffer.c:1555 ../quickfix.c:3361
-#, c-format
-msgid "E92: Buffer %<PRId64> not found"
-msgstr "E92: §ä¤£¨ì²Ä %<PRId64> ­Ó½w½Ä°Ï"
-
-#: ../buffer.c:1798
-#, c-format
-msgid "E93: More than one match for %s"
-msgstr "E93: §ä¨ì¤@­Ó¥H¤Wªº %s"
-
-#: ../buffer.c:1800
-#, c-format
-msgid "E94: No matching buffer for %s"
-msgstr "E94: §ä¤£¨ì %s"
-
-#: ../buffer.c:2161
-#, c-format
-msgid "line %<PRId64>"
-msgstr "¦æ %<PRId64>"
-
-#: ../buffer.c:2233
-msgid "E95: Buffer with this name already exists"
-msgstr "E95: ¤w¦³½w½Ä°Ï¨Ï¥Î³o­Ó¦W¦r"
-
-#: ../buffer.c:2498
-msgid " [Modified]"
-msgstr " [¤w­×§ï]"
-
-#: ../buffer.c:2501
-msgid "[Not edited]"
-msgstr "[¥¼½s¿è]"
-
-#: ../buffer.c:2504
-msgid "[New file]"
-msgstr "[·sÀÉ®×]"
-
-#: ../buffer.c:2505
-msgid "[Read errors]"
-msgstr "[Ū¨ú¿ù»~]"
-
-#: ../buffer.c:2506 ../buffer.c:3217 ../fileio.c:1807 ../screen.c:4895
-msgid "[RO]"
-msgstr "[°ßŪ]"
-
-#: ../buffer.c:2507 ../fileio.c:1807
-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:2530
-#, c-format
-msgid "line %<PRId64> of %<PRId64> --%d%%-- col "
-msgstr "¦æ %<PRId64>/%<PRId64> --%d%%-- Äæ "
-
-#: ../buffer.c:2632 ../buffer.c:4292 ../memline.c:1554
-#, fuzzy
-msgid "[No Name]"
-msgstr "[¥¼©R¦W]"
-
-#. must be a help buffer
-#: ../buffer.c:2667
-msgid "help"
-msgstr "[»²§U»¡©ú]"
-
-#: ../buffer.c:3225 ../screen.c:4883
-#, fuzzy
-msgid "[Help]"
-msgstr "[»²§U»¡©ú]"
-
-#: ../buffer.c:3254 ../screen.c:4887
-msgid "[Preview]"
-msgstr "[¹wÄý]"
-
-#: ../buffer.c:3528
-msgid "All"
-msgstr "¥þ³¡"
-
-#: ../buffer.c:3528
-msgid "Bot"
-msgstr "©³ºÝ"
-
-#: ../buffer.c:3531
-msgid "Top"
-msgstr "³»ºÝ"
-
-#: ../buffer.c:4244
-msgid ""
-"\n"
-"# Buffer list:\n"
-msgstr ""
-"\n"
-"# ½w½Ä°Ï¦Cªí:\n"
-
-#: ../buffer.c:4289
-msgid "[Scratch]"
-msgstr ""
-
-#: ../buffer.c:4529
-msgid ""
-"\n"
-"--- Signs ---"
-msgstr ""
-"\n"
-"--- ²Å¸¹ ---"
-
-#: ../buffer.c:4538
-#, c-format
-msgid "Signs for %s:"
-msgstr "%s ªº²Å¸¹:"
-
-#: ../buffer.c:4543
-#, c-format
-msgid " line=%<PRId64> id=%d name=%s"
-msgstr " ¦æ=%<PRId64> id=%d ¦WºÙ=%s"
-
-#: ../cursor_shape.c:68
-msgid "E545: Missing colon"
-msgstr "E545: ¯Ê¤Ö colon"
-
-#: ../cursor_shape.c:70 ../cursor_shape.c:94
-msgid "E546: Illegal mode"
-msgstr "E546: ¤£¥¿½Tªº¼Ò¦¡"
-
-#: ../cursor_shape.c:134
-msgid "E548: digit expected"
-msgstr "E548: À³¸Ó­n¦³¼Æ¦r"
-
-#: ../cursor_shape.c:138
-msgid "E549: Illegal percentage"
-msgstr "E549: ¤£¥¿½Tªº¦Ê¤À¤ñ"
-
-#: ../diff.c:146
-#, c-format
-msgid "E96: Can not diff more than %<PRId64> buffers"
-msgstr "E96: µLªk¤ñ¸û(diff) %<PRId64>­Ó¥H¤Wªº½w½Ä°Ï"
-
-#: ../diff.c:753
-#, fuzzy
-msgid "E810: Cannot read or write temp files"
-msgstr "E557: µLªk¶}±Ò termcap ÀÉ®×"
-
-#: ../diff.c:755
-msgid "E97: Cannot create diffs"
-msgstr "E97: ¤£¯à«Ø¥ß "
-
-#: ../diff.c:966
-#, fuzzy
-msgid "E816: Cannot read patch output"
-msgstr "E98: µLªkŪ¨ú diff ªº¿é¥X"
-
-#: ../diff.c:1220
-msgid "E98: Cannot read diff output"
-msgstr "E98: µLªkŪ¨ú diff ªº¿é¥X"
-
-#: ../diff.c:2081
-msgid "E99: Current buffer is not in diff mode"
-msgstr "E99: ¥Ø«eªº½w½Ä°Ï¤£¬O¦b diff ¼Ò¦¡"
-
-#: ../diff.c:2100
-#, fuzzy
-msgid "E793: No other buffer in diff mode is modifiable"
-msgstr "E100: ¨S¦³½w½Ä°Ï¦b diff ¼Ò¦¡"
-
-#: ../diff.c:2102
-msgid "E100: No other buffer in diff mode"
-msgstr "E100: ¨S¦³½w½Ä°Ï¦b diff ¼Ò¦¡"
-
-#: ../diff.c:2112
-msgid "E101: More than two buffers in diff mode, don't know which one to use"
-msgstr "E101: ¦³¨â­Ó¥H¤Wªº½w½Ä°Ï¦b diff ¼Ò¦¡¡AµLªk¨M©w­n¥Î­þ¤@­Ó"
-
-#: ../diff.c:2141
-#, c-format
-msgid "E102: Can't find buffer \"%s\""
-msgstr "E102: §ä¤£¨ì½w½Ä°Ï: \"%s\""
-
-#: ../diff.c:2152
-#, c-format
-msgid "E103: Buffer \"%s\" is not in diff mode"
-msgstr "E103: ½w½Ä°Ï \"%s\" ¤£¬O¦b diff ¼Ò¦¡"
-
-#: ../diff.c:2193
-msgid "E787: Buffer changed unexpectedly"
-msgstr ""
-
-#: ../digraph.c:1598
-msgid "E104: Escape not allowed in digraph"
-msgstr "E104: ½Æ¦X¦r¤¸(digraph)¤¤¤£¯à¨Ï¥Î Escape"
-
-#: ../digraph.c:1760
-msgid "E544: Keymap file not found"
-msgstr "E544: §ä¤£¨ì keymap ÀÉ"
-
-#: ../digraph.c:1785
-msgid "E105: Using :loadkeymap not in a sourced file"
-msgstr "E105: ¨Ï¥Î :loadkeymap "
-
-#: ../digraph.c:1821
-msgid "E791: Empty keymap entry"
-msgstr ""
-
-#: ../edit.c:82
-msgid " Keyword completion (^N^P)"
-msgstr " ÃöÁä¦r¦Û°Ê§¹¦¨ (^N^P)"
-
-#. ctrl_x_mode == 0, ^P/^N compl.
-#: ../edit.c:83
-#, fuzzy
-msgid " ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"
-msgstr " ^X ¼Ò¦¡ (^E^Y^L^]^F^I^K^D^N^P)"
-
-#: ../edit.c:85
-msgid " Whole line completion (^L^N^P)"
-msgstr " ¾ã¦æ¦Û°Ê§¹¦¨ (^L^N^P)"
-
-#: ../edit.c:86
-msgid " File name completion (^F^N^P)"
-msgstr " ÀɦW¦Û°Ê§¹¦¨ (^F^N^P)"
-
-#: ../edit.c:87
-msgid " Tag completion (^]^N^P)"
-msgstr " ¼ÐÅҦ۰ʧ¹¦¨ (^]^N^P)"
-
-#: ../edit.c:88
-msgid " Path pattern completion (^N^P)"
-msgstr " ¸ô®|¦Û°Ê§¹¦¨ (^N^P)"
-
-#: ../edit.c:89
-msgid " Definition completion (^D^N^P)"
-msgstr " ©w¸q¦Û°Ê§¹¦¨ (^D^N^P)"
-
-#: ../edit.c:91
-msgid " Dictionary completion (^K^N^P)"
-msgstr " ¦r¨å¦Û°Ê§¹¦¨ (^K^N^P)"
-
-#: ../edit.c:92
-msgid " Thesaurus completion (^T^N^P)"
-msgstr " Thesaurus ¦Û°Ê§¹¦¨ (^T^N^P)"
-
-#: ../edit.c:93
-msgid " Command-line completion (^V^N^P)"
-msgstr " ©R¥O¦C¦Û°Ê§¹¦¨ (^V^N^P)"
-
-#: ../edit.c:94
-#, fuzzy
-msgid " User defined completion (^U^N^P)"
-msgstr " ¾ã¦æ¦Û°Ê§¹¦¨ (^L^N^P)"
-
-#: ../edit.c:95
-#, fuzzy
-msgid " Omni completion (^O^N^P)"
-msgstr " ¼ÐÅҦ۰ʧ¹¦¨ (^]^N^P)"
-
-#: ../edit.c:96
-#, fuzzy
-msgid " Spelling suggestion (s^N^P)"
-msgstr " ¾ã¦æ¦Û°Ê§¹¦¨ (^L^N^P)"
-
-#: ../edit.c:97
-msgid " Keyword Local completion (^N^P)"
-msgstr " °Ï°ìÃöÁä¦r¦Û°Ê§¹¦¨ (^N^P)"
-
-#: ../edit.c:100
-msgid "Hit end of paragraph"
-msgstr "¤w¨ì¬q¸¨µ²§À"
-
-#: ../edit.c:101
-msgid "E839: Completion function changed window"
-msgstr ""
-
-#: ../edit.c:102
-msgid "E840: Completion function deleted text"
-msgstr ""
-
-#: ../edit.c:1847
-msgid "'dictionary' option is empty"
-msgstr "¿ï¶µ 'dictionary' ¥¼³]©w"
-
-#: ../edit.c:1848
-msgid "'thesaurus' option is empty"
-msgstr "¿ï¶µ 'thesaurus' ¥¼³]©w"
-
-#: ../edit.c:2655
-#, c-format
-msgid "Scanning dictionary: %s"
-msgstr "±½ºË¦r¨å: %s"
-
-#: ../edit.c:3079
-msgid " (insert) Scroll (^E/^Y)"
-msgstr " (´¡¤J) Scroll (^E/^Y)"
-
-#: ../edit.c:3081
-msgid " (replace) Scroll (^E/^Y)"
-msgstr " (¨ú¥N) Scroll (^E/^Y)"
-
-#: ../edit.c:3587
-#, c-format
-msgid "Scanning: %s"
-msgstr "±½ºË¤¤: %s"
-
-#: ../edit.c:3614
-msgid "Scanning tags."
-msgstr "±½ºË¼ÐÅÒ."
-
-#: ../edit.c:4519
-msgid " Adding"
-msgstr " ¼W¥["
-
-#. 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 "-- ·j´M¤¤..."
-
-#: ../edit.c:4618
-msgid "Back at original"
-msgstr "¦^¨ì°_ÂI"
-
-#: ../edit.c:4621
-msgid "Word from other line"
-msgstr "±q§O¦æ¶}©lªº¦r (?)"
-
-#: ../edit.c:4624
-msgid "The only match"
-msgstr "¥u¦³¦¹¶µ²Å¦X"
-
-#: ../edit.c:4680
-#, c-format
-msgid "match %d of %d"
-msgstr "§ä¨ì %d / %d"
-
-#: ../edit.c:4684
-#, c-format
-msgid "match %d"
-msgstr "²Å¦X %d"
-
-#: ../eval.c:137
-#, fuzzy
-msgid "E18: Unexpected characters in :let"
-msgstr "E18: '=' «e­±¥X²{¤F¿ù»~ªº¦r¤¸"
-
-#: ../eval.c:138
-#, fuzzy, c-format
-msgid "E684: list index out of range: %<PRId64>"
-msgstr "E322: ¦æ¸¹¶W¥X½d³ò: %<PRId64> ¶W¹Lµ²§À"
-
-#: ../eval.c:139
-#, c-format
-msgid "E121: Undefined variable: %s"
-msgstr "E121: ÅÜ¼Æ %s ©|¥¼©w¸q"
-
-#: ../eval.c:140
-msgid "E111: Missing ']'"
-msgstr "E111: ¯Ê¤Ö¹ïÀ³ªº \"]\""
-
-#: ../eval.c:141
-#, fuzzy, c-format
-msgid "E686: Argument of %s must be a List"
-msgstr "E487: °Ñ¼ÆÀ³¸Ó¬O¥¿¼Æ"
-
-#: ../eval.c:143
-#, fuzzy, c-format
-msgid "E712: Argument of %s must be a List or Dictionary"
-msgstr "E487: °Ñ¼ÆÀ³¸Ó¬O¥¿¼Æ"
-
-#: ../eval.c:144
-#, fuzzy
-msgid "E713: Cannot use empty key for Dictionary"
-msgstr "E214: §ä¤£¨ì¼g¤J¥Îªº¼È¦sÀÉ"
-
-#: ../eval.c:145
-#, fuzzy
-msgid "E714: List required"
-msgstr "E471: »Ý­n«ü¥O°Ñ¼Æ"
-
-#: ../eval.c:146
-#, fuzzy
-msgid "E715: Dictionary required"
-msgstr "E129: »Ý­n¨ç¦¡¦WºÙ"
-
-#: ../eval.c:147
-#, c-format
-msgid "E118: Too many arguments for function: %s"
-msgstr "E118: ¨ç¦¡ %s ªº¤Þ¼Æ¹L¦h"
-
-#: ../eval.c:148
-#, c-format
-msgid "E716: Key not present in Dictionary: %s"
-msgstr ""
-
-#: ../eval.c:150
-#, c-format
-msgid "E122: Function %s already exists, add ! to replace it"
-msgstr "E122: ¨ç¦¡ %s ¤w¸g¦s¦b, ½Ð¨Ï¥Î ! ±j¨î¨ú¥N"
-
-#: ../eval.c:151
-#, fuzzy
-msgid "E717: Dictionary entry already exists"
-msgstr "E95: ¤w¦³½w½Ä°Ï¨Ï¥Î³o­Ó¦W¦r"
-
-#: ../eval.c:152
-#, fuzzy
-msgid "E718: Funcref required"
-msgstr "E129: »Ý­n¨ç¦¡¦WºÙ"
-
-#: ../eval.c:153
-#, fuzzy
-msgid "E719: Cannot use [:] with a Dictionary"
-msgstr "E360: ¤£¯à¥Î -f ¿ï¶µ°õ¦æ shell"
-
-#: ../eval.c:154
-#, c-format
-msgid "E734: Wrong variable type for %s="
-msgstr ""
-
-#: ../eval.c:155
-#, fuzzy, c-format
-msgid "E130: Unknown function: %s"
-msgstr "E117: ¥¼©w¸qªº¨ç¦¡: %s"
-
-#: ../eval.c:156
-#, c-format
-msgid "E461: Illegal variable name: %s"
-msgstr "E461: ¤£¦XªkªºÅܼƦWºÙ: %s"
-
-#: ../eval.c:157
-msgid "E806: using Float as a String"
-msgstr ""
-
-#: ../eval.c:1830
-msgid "E687: Less targets than List items"
-msgstr ""
-
-#: ../eval.c:1834
-msgid "E688: More targets than List items"
-msgstr ""
-
-#: ../eval.c:1906
-msgid "Double ; in list of variables"
-msgstr ""
-
-#: ../eval.c:2078
-#, fuzzy, c-format
-msgid "E738: Can't list variables for %s"
-msgstr "E138: µLªk¼g¤J viminfo ÀÉ®× %s !"
-
-#: ../eval.c:2391
-msgid "E689: Can only index a List or Dictionary"
-msgstr ""
-
-#: ../eval.c:2396
-msgid "E708: [:] must come last"
-msgstr ""
-
-#: ../eval.c:2439
-msgid "E709: [:] requires a List value"
-msgstr ""
-
-#: ../eval.c:2674
-msgid "E710: List value has more items than target"
-msgstr ""
-
-#: ../eval.c:2678
-msgid "E711: List value has not enough items"
-msgstr ""
-
-#: ../eval.c:2867
-#, fuzzy
-msgid "E690: Missing \"in\" after :for"
-msgstr "E69: %s%%[ «á¯Ê¤Ö ]"
-
-#: ../eval.c:3063
-#, c-format
-msgid "E107: Missing parentheses: %s"
-msgstr "E107: ¯Ê¤Ö¹ïÀ³ªº¬A¸¹: %s"
-
-#: ../eval.c:3263
-#, c-format
-msgid "E108: No such variable: \"%s\""
-msgstr "E108: µL¦¹ÅܼÆ: \"%s\""
-
-#: ../eval.c:3333
-msgid "E743: variable nested too deep for (un)lock"
-msgstr ""
-
-#: ../eval.c:3630
-msgid "E109: Missing ':' after '?'"
-msgstr "E109: '?' «á¯Ê¤Ö ':'"
-
-#: ../eval.c:3893
-msgid "E691: Can only compare List with List"
-msgstr ""
-
-#: ../eval.c:3895
-#, fuzzy
-msgid "E692: Invalid operation for Lists"
-msgstr "E449: ¦¬¨ì¤£¥¿½Tªº¹Bºâ¦¡"
-
-#: ../eval.c:3915
-msgid "E735: Can only compare Dictionary with Dictionary"
-msgstr ""
-
-#: ../eval.c:3917
-#, fuzzy
-msgid "E736: Invalid operation for Dictionary"
-msgstr "E116: ¨ç¦¡ %s ªº¤Þ¼Æ¤£¥¿½T"
-
-#: ../eval.c:3932
-msgid "E693: Can only compare Funcref with Funcref"
-msgstr ""
-
-#: ../eval.c:3934
-#, fuzzy
-msgid "E694: Invalid operation for Funcrefs"
-msgstr "E116: ¨ç¦¡ %s ªº¤Þ¼Æ¤£¥¿½T"
-
-#: ../eval.c:4277
-#, fuzzy
-msgid "E804: Cannot use '%' with Float"
-msgstr "E360: ¤£¯à¥Î -f ¿ï¶µ°õ¦æ shell"
-
-#: ../eval.c:4478
-msgid "E110: Missing ')'"
-msgstr "E110: ¯Ê¤Ö¹ïÀ³ªº \")\""
-
-#: ../eval.c:4609
-#, fuzzy
-msgid "E695: Cannot index a Funcref"
-msgstr "E90: µLªkÄÀ©ñ³Ì«á¤@­Ó½w½Ä°Ï"
-
-#: ../eval.c:4839
-#, c-format
-msgid "E112: Option name missing: %s"
-msgstr "E112: ¯Ê¤Ö¿ï¶µ¦WºÙ: %s"
-
-#: ../eval.c:4855
-#, c-format
-msgid "E113: Unknown option: %s"
-msgstr "E113: ¤£¥¿½Tªº¿ï¶µ: %s"
-
-#: ../eval.c:4904
-#, c-format
-msgid "E114: Missing quote: %s"
-msgstr "E114: ¯Ê¤Ö¤Þ¸¹: %s"
-
-#: ../eval.c:5020
-#, c-format
-msgid "E115: Missing quote: %s"
-msgstr "E115: ¯Ê¤Ö¤Þ¸¹: %s"
-
-#: ../eval.c:5084
-#, fuzzy, c-format
-msgid "E696: Missing comma in List: %s"
-msgstr "E405: ¯Ê¤Ö¬Ûµ¥²Å¸¹: %s"
-
-#: ../eval.c:5091
-#, fuzzy, c-format
-msgid "E697: Missing end of List ']': %s"
-msgstr "E398: ¯Ê¤Ö \"=\": %s"
-
-#: ../eval.c:6475
-#, fuzzy, c-format
-msgid "E720: Missing colon in Dictionary: %s"
-msgstr "E242: §ä¤£¨ìÃC¦â: %s"
-
-#: ../eval.c:6499
-#, c-format
-msgid "E721: Duplicate key in Dictionary: \"%s\""
-msgstr ""
-
-#: ../eval.c:6517
-#, fuzzy, c-format
-msgid "E722: Missing comma in Dictionary: %s"
-msgstr "E242: §ä¤£¨ìÃC¦â: %s"
-
-#: ../eval.c:6524
-#, fuzzy, c-format
-msgid "E723: Missing end of Dictionary '}': %s"
-msgstr "E126: ¯Ê¤Ö :endfunction"
-
-#: ../eval.c:6555
-#, fuzzy
-msgid "E724: variable nested too deep for displaying"
-msgstr "E22: ±_ª¬»¼°j©I¥s¤Ó¦h¼h"
-
-#: ../eval.c:7188
-#, fuzzy, c-format
-msgid "E740: Too many arguments for function %s"
-msgstr "E118: ¨ç¦¡ %s ªº¤Þ¼Æ¹L¦h"
-
-#: ../eval.c:7190
-#, c-format
-msgid "E116: Invalid arguments for function %s"
-msgstr "E116: ¨ç¦¡ %s ªº¤Þ¼Æ¤£¥¿½T"
-
-#: ../eval.c:7377
-#, c-format
-msgid "E117: Unknown function: %s"
-msgstr "E117: ¥¼©w¸qªº¨ç¦¡: %s"
-
-#: ../eval.c:7383
-#, c-format
-msgid "E119: Not enough arguments for function: %s"
-msgstr "E119: ¨ç¦¡ %s ªº¤Þ¼Æ¤Ó¤Ö"
-
-#: ../eval.c:7387
-#, c-format
-msgid "E120: Using <SID> not in a script context: %s"
-msgstr "E120: <SID> ¤£¯à¦b script ¥»¤å¥~¨Ï¥Î: %s"
-
-#: ../eval.c:7391
-#, c-format
-msgid "E725: Calling dict function without Dictionary: %s"
-msgstr ""
-
-#: ../eval.c:7453
-#, fuzzy
-msgid "E808: Number or Float required"
-msgstr "E521: = «á»Ý­n¦³¼Æ¦r"
-
-#: ../eval.c:7503
-#, fuzzy
-msgid "add() argument"
-msgstr "¤£¥¿½Tªº°Ñ¼Æ: "
-
-#: ../eval.c:7907
-#, fuzzy
-msgid "E699: Too many arguments"
-msgstr "¤Ó¦h½s¿è°Ñ¼Æ"
-
-#: ../eval.c:8073
-#, fuzzy
-msgid "E785: complete() can only be used in Insert mode"
-msgstr "E328: ¿ï³æ¥u¯à¦b¨ä¥¦¼Ò¦¡¤¤¨Ï¥Î"
-
-#: ../eval.c:8156
-msgid "&Ok"
-msgstr "½T©w(&O)"
-
-#: ../eval.c:8676
-#, fuzzy, c-format
-msgid "E737: Key already exists: %s"
-msgstr "E227: %s ªº mapping ¤w¸g¦s¦b"
-
-#: ../eval.c:8692
-msgid "extend() argument"
-msgstr ""
-
-#: ../eval.c:8915
-#, fuzzy
-msgid "map() argument"
-msgstr "vim [°Ñ¼Æ] "
-
-#: ../eval.c:8916
-msgid "filter() argument"
-msgstr ""
-
-#: ../eval.c:9229
-#, c-format
-msgid "+-%s%3ld lines: "
-msgstr "+-%s%3ld ¦æ: "
-
-#: ../eval.c:9291
-#, fuzzy, c-format
-msgid "E700: Unknown function: %s"
-msgstr "E117: ¥¼©w¸qªº¨ç¦¡: %s"
-
-#: ../eval.c:10729
-msgid "called inputrestore() more often than inputsave()"
-msgstr "©I¥s inputrestore() ªº¦¸¼Æ¤ñ inputsave() ÁÙ¦h"
-
-#: ../eval.c:10771
-#, fuzzy
-msgid "insert() argument"
-msgstr "¤Ó¦h½s¿è°Ñ¼Æ"
-
-#: ../eval.c:10841
-#, fuzzy
-msgid "E786: Range not allowed"
-msgstr "E481: ¤£¥i¨Ï¥Î½d³ò«ü¥O"
-
-#: ../eval.c:11140
-#, fuzzy
-msgid "E701: Invalid type for len()"
-msgstr "E596: ¤£¥¿½Tªº¦r«¬"
-
-#: ../eval.c:11980
-msgid "E726: Stride is zero"
-msgstr ""
-
-#: ../eval.c:11982
-msgid "E727: Start past end"
-msgstr ""
-
-#: ../eval.c:12024 ../eval.c:15297
-msgid "<empty>"
-msgstr ""
-
-#: ../eval.c:12282
-msgid "remove() argument"
-msgstr ""
-
-#: ../eval.c:12466
-msgid "E655: Too many symbolic links (cycle?)"
-msgstr "E655: ¤Ó¦h¼hªº²Å¸¹Ãìµ²(symlink) (´`Àô?)"
-
-#: ../eval.c:12593
-msgid "reverse() argument"
-msgstr ""
-
-#: ../eval.c:13721
-msgid "sort() argument"
-msgstr ""
-
-#: ../eval.c:13721
-#, fuzzy
-msgid "uniq() argument"
-msgstr "¤£¥¿½Tªº°Ñ¼Æ: "
-
-#: ../eval.c:13776
-#, fuzzy
-msgid "E702: Sort compare function failed"
-msgstr "E237: µLªk¿ï¾Ü¦¹¦Lªí¾÷"
-
-#: ../eval.c:13806
-msgid "E882: Uniq compare function failed"
-msgstr ""
-
-#: ../eval.c:14085
-msgid "(Invalid)"
-msgstr "(¤£¥¿½T)"
-
-#: ../eval.c:14590
-#, fuzzy
-msgid "E677: Error writing temp file"
-msgstr "E208: ¼g¤JÀÉ®× \"%s\" ¿ù»~"
-
-#: ../eval.c:16159
-msgid "E805: Using a Float as a Number"
-msgstr ""
-
-#: ../eval.c:16162
-msgid "E703: Using a Funcref as a Number"
-msgstr ""
-
-#: ../eval.c:16170
-msgid "E745: Using a List as a Number"
-msgstr ""
-
-#: ../eval.c:16173
-msgid "E728: Using a Dictionary as a Number"
-msgstr ""
-
-#: ../eval.c:16259
-msgid "E729: using Funcref as a String"
-msgstr ""
-
-#: ../eval.c:16262
-#, fuzzy
-msgid "E730: using List as a String"
-msgstr "E374: ®æ¦¡¤Æ¦r¦ê¸Ì¤Ö¤F ]"
-
-#: ../eval.c:16265
-msgid "E731: using Dictionary as a String"
-msgstr ""
-
-#: ../eval.c:16619
-#, fuzzy, c-format
-msgid "E706: Variable type mismatch for: %s"
-msgstr "E93: §ä¨ì¤@­Ó¥H¤Wªº %s"
-
-#: ../eval.c:16705
-#, fuzzy, c-format
-msgid "E795: Cannot delete variable %s"
-msgstr "E46: µLªk³]©w°ßŪÅÜ¼Æ \"%s\""
-
-#: ../eval.c:16724
-#, fuzzy, c-format
-msgid "E704: Funcref variable name must start with a capital: %s"
-msgstr "E128: ¨ç¦¡¦WºÙ²Ä¤@­Ó¦r¥À¥²¶·¤j¼g: %s"
-
-#: ../eval.c:16732
-#, c-format
-msgid "E705: Variable name conflicts with existing function: %s"
-msgstr ""
-
-#: ../eval.c:16763
-#, c-format
-msgid "E741: Value is locked: %s"
-msgstr ""
-
-#: ../eval.c:16764 ../eval.c:16769 ../message.c:1839
-msgid "Unknown"
-msgstr "¥¼ª¾"
-
-#: ../eval.c:16768
-#, fuzzy, c-format
-msgid "E742: Cannot change value of %s"
-msgstr "E284: ¤£¯à³]©w IC ¼Æ­È"
-
-#: ../eval.c:16838
-msgid "E698: variable nested too deep for making a copy"
-msgstr ""
-
-#: ../eval.c:17249
-#, c-format
-msgid "E123: Undefined function: %s"
-msgstr "E123: ¨ç¦¡ %s ©|¥¼©w¸q"
-
-#: ../eval.c:17260
-#, c-format
-msgid "E124: Missing '(': %s"
-msgstr "E124: ¯Ê¤Ö \"(\": %s"
-
-#: ../eval.c:17293
-#, fuzzy
-msgid "E862: Cannot use g: here"
-msgstr "E284: ¤£¯à³]©w IC ¼Æ­È"
-
-#: ../eval.c:17312
-#, c-format
-msgid "E125: Illegal argument: %s"
-msgstr "E125: °Ñ¼Æ¤£¥¿½T: %s"
-
-#: ../eval.c:17323
-#, fuzzy, c-format
-msgid "E853: Duplicate argument name: %s"
-msgstr "E154: ¼ÐÅÒ(tag) \"%s\" ¦bÀÉ®× %s ¸Ì­«½Æ¥X²{¦h¦¸"
-
-#: ../eval.c:17416
-msgid "E126: Missing :endfunction"
-msgstr "E126: ¯Ê¤Ö :endfunction"
-
-#: ../eval.c:17537
-#, fuzzy, c-format
-msgid "E707: Function name conflicts with variable: %s"
-msgstr "E128: ¨ç¦¡¦WºÙ²Ä¤@­Ó¦r¥À¥²¶·¤j¼g: %s"
-
-#: ../eval.c:17549
-#, c-format
-msgid "E127: Cannot redefine function %s: It is in use"
-msgstr "E127: ¨ç¦¡ %s ¥¿¦b¨Ï¥Î¤¤¡AµLªk­«·s©w¸q"
-
-#: ../eval.c:17604
-#, fuzzy, c-format
-msgid "E746: Function name does not match script file name: %s"
-msgstr "E128: ¨ç¦¡¦WºÙ²Ä¤@­Ó¦r¥À¥²¶·¤j¼g: %s"
-
-#: ../eval.c:17716
-msgid "E129: Function name required"
-msgstr "E129: »Ý­n¨ç¦¡¦WºÙ"
-
-#: ../eval.c:17824
-#, fuzzy, c-format
-msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr "E128: ¨ç¦¡¦WºÙ²Ä¤@­Ó¦r¥À¥²¶·¤j¼g: %s"
-
-#: ../eval.c:17833
-#, fuzzy, c-format
-msgid "E884: Function name cannot contain a colon: %s"
-msgstr "E128: ¨ç¦¡¦WºÙ²Ä¤@­Ó¦r¥À¥²¶·¤j¼g: %s"
-
-#: ../eval.c:18336
-#, c-format
-msgid "E131: Cannot delete function %s: It is in use"
-msgstr "E131: ¨ç¦¡ %s ¥¿¦b¨Ï¥Î¤¤¡AµLªk§R°£"
-
-#: ../eval.c:18441
-msgid "E132: Function call depth is higher than 'maxfuncdepth'"
-msgstr "E132: ¨ç¦¡»¼°j©I¥s¼h¼Æ¶W¹L 'maxfuncdepth'"
-
-#: ../eval.c:18568
-#, c-format
-msgid "calling %s"
-msgstr "©I¥s %s"
-
-#: ../eval.c:18651
-#, c-format
-msgid "%s aborted"
-msgstr "%s ³Q±j¨î¤¤Â_°õ¦æ "
-
-#: ../eval.c:18653
-#, c-format
-msgid "%s returning #%<PRId64>"
-msgstr "%s ¶Ç¦^­È #%<PRId64> "
-
-#: ../eval.c:18670
-#, fuzzy, c-format
-msgid "%s returning %s"
-msgstr "%s ¶Ç¦^­È \"%s\""
-
-#: ../eval.c:18691 ../ex_cmds2.c:2695
-#, c-format
-msgid "continuing in %s"
-msgstr "Ä~Äò: %s"
-
-#: ../eval.c:18795
-msgid "E133: :return not inside a function"
-msgstr "E133: :return ¥²¶·¦b¨ç¦¡¸Ì¨Ï¥Î"
-
-#: ../eval.c:19159
-msgid ""
-"\n"
-"# global variables:\n"
-msgstr ""
-"\n"
-"# ¥þ°ìÅܼÆ:\n"
-
-#: ../eval.c:19254
-msgid ""
-"\n"
-"\tLast set from "
-msgstr ""
-"\n"
-"\t¤W¦¸³]©w: "
-
-#: ../eval.c:19272
-#, fuzzy
-msgid "No old files"
-msgstr "¨S¦³¤Þ¤JÀÉ®×"
-
-#: ../ex_cmds.c:122
-#, c-format
-msgid "<%s>%s%s %d, Hex %02x, Octal %03o"
-msgstr "<%s>%s%s %d, ¤Q¤»¶i¦ì %02x, ¤K¶i¦ì %03o"
-
-#: ../ex_cmds.c:145
-#, c-format
-msgid "> %d, Hex %04x, Octal %o"
-msgstr "> %d, ¤Q¤»¶i¦ì %04x, ¤K¶i¦ì %o"
-
-#: ../ex_cmds.c:146
-#, c-format
-msgid "> %d, Hex %08x, Octal %o"
-msgstr "> %d, ¤Q¤»¶i¦ì %08x, ¤K¶i¦ì %o"
-
-#: ../ex_cmds.c:684
-msgid "E134: Move lines into themselves"
-msgstr "E134: µLªk§â¦æ²¾¨ì¥¦¦Û¤w¤º"
-
-#: ../ex_cmds.c:747
-msgid "1 line moved"
-msgstr "¤w·h²¾ 1 ¦æ "
-
-#: ../ex_cmds.c:749
-#, c-format
-msgid "%<PRId64> lines moved"
-msgstr "¤w·h²¾ %<PRId64> ¦æ "
-
-#: ../ex_cmds.c:1175
-#, c-format
-msgid "%<PRId64> lines filtered"
-msgstr "¤w³B²z %<PRId64> ¦æ "
-
-#: ../ex_cmds.c:1194
-msgid "E135: *Filter* Autocommands must not change current buffer"
-msgstr "E135: *Filter* Autocommand ¤£¥i¥H§ó§ï½w½Ä°Ïªº¤º®e"
-
-#: ../ex_cmds.c:1244
-msgid "[No write since last change]\n"
-msgstr "[§ó·s«á©|¥¼Àx¦s]\n"
-
-#: ../ex_cmds.c:1424
-#, c-format
-msgid "%sviminfo: %s in line: "
-msgstr "%sviminfo: %s ¦b¦æ¤¤: "
-
-#: ../ex_cmds.c:1431
-msgid "E136: viminfo: Too many errors, skipping rest of file"
-msgstr "E136: viminfo: ¹L¦h¿ù»~, ©¿²¤Àɮרä¾l³¡¤À"
-
-#: ../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 " °T®§"
-
-#: ../ex_cmds.c:1461
-msgid " marks"
-msgstr " ¼Ð°O"
-
-#: ../ex_cmds.c:1462
-#, fuzzy
-msgid " oldfiles"
-msgstr "¨S¦³¤Þ¤JÀÉ®×"
-
-#: ../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 ÀÉ®×µLªk¼g¤J: %s"
-
-#: ../ex_cmds.c:1626
-#, c-format
-msgid "E138: Can't write viminfo file %s!"
-msgstr "E138: µLªk¼g¤J viminfo ÀÉ®× %s !"
-
-#: ../ex_cmds.c:1635
-#, c-format
-msgid "Writing viminfo file \"%s\""
-msgstr "¼g¤J viminfo ÀÉ®× \"%s\" ¤¤"
-
-#. Write the info:
-#: ../ex_cmds.c:1720
-#, c-format
-msgid "# This viminfo file was generated by Vim %s.\n"
-msgstr "# ¥» viminfo Àɮ׬O¥Ñ Vim %s ©Ò²£¥Í.\n"
-
-#: ../ex_cmds.c:1722
-msgid ""
-"# You may edit it if you're careful!\n"
-"\n"
-msgstr ""
-"# ¦pªG·Q­n¦Û¦æ­×§ï½Ð¯S§O¤p¤ß¡I\n"
-"\n"
-
-#: ../ex_cmds.c:1723
-msgid "# Value of 'encoding' when this file was written\n"
-msgstr "# 'encoding' ¦b¦¹Àɫإ߮ɪº­È\n"
-
-#: ../ex_cmds.c:1800
-msgid "Illegal starting char"
-msgstr "µL®Äªº°_©l¦r¤¸"
-
-#: ../ex_cmds.c:2162
-msgid "Write partial file?"
-msgstr "­n¼g¤J³¡¤ÀÀÉ®×¶Ü¡H"
-
-#: ../ex_cmds.c:2166
-msgid "E140: Use ! to write partial buffer"
-msgstr "E140: ½Ð¨Ï¥Î ! ¥H¼g¤J³¡¤À½w½Ä°Ï"
-
-#: ../ex_cmds.c:2281
-#, fuzzy, c-format
-msgid "Overwrite existing file \"%s\"?"
-msgstr "­nÂмg¤w¦s¦bªºÀÉ®× \"%.*s\"¡H"
-
-#: ../ex_cmds.c:2317
-#, c-format
-msgid "Swap file \"%s\" exists, overwrite anyway?"
-msgstr ""
-
-#: ../ex_cmds.c:2326
-#, fuzzy, c-format
-msgid "E768: Swap file exists: %s (:silent! overrides)"
-msgstr "E13: Àɮפw¸g¦s¦b (¥i¥Î ! ±j¨î¨ú¥N)"
-
-#: ../ex_cmds.c:2381
-#, c-format
-msgid "E141: No file name for buffer %<PRId64>"
-msgstr "E141: ½w½Ä°Ï %<PRId64> ¨S¦³ÀɮצWºÙ"
-
-#: ../ex_cmds.c:2412
-msgid "E142: File not written: Writing is disabled by 'write' option"
-msgstr "E142: ÀÉ®×¥¼¼g¤J¡A¦]¬° 'write' ¿ï¶µ³QÃö³¬"
-
-#: ../ex_cmds.c:2434
-#, fuzzy, c-format
-msgid ""
-"'readonly' option is set for \"%s\".\n"
-"Do you wish to write anyway?"
-msgstr ""
-"\"%.*s\" ¤w³]©w 'readonly' ¿ï¶µ.\n"
-"½T©w­nÂмg¶Ü¡H"
-
-#: ../ex_cmds.c:2439
-#, c-format
-msgid ""
-"File permissions of \"%s\" are read-only.\n"
-"It may still be possible to write it.\n"
-"Do you wish to try?"
-msgstr ""
-
-#: ../ex_cmds.c:2451
-#, fuzzy, c-format
-msgid "E505: \"%s\" is read-only (add ! to override)"
-msgstr "¬O°ßŪÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#: ../ex_cmds.c:3120
-#, c-format
-msgid "E143: Autocommands unexpectedly deleted new buffer %s"
-msgstr "E143: Autocommands ·N¥~¦a§R°£·s½w½Ä°Ï %s"
-
-#: ../ex_cmds.c:3313
-msgid "E144: non-numeric argument to :z"
-msgstr "E144: :z ¤£±µ¨ü«D¼Æ¦rªº°Ñ¼Æ"
-
-#: ../ex_cmds.c:3404
-msgid "E145: Shell commands not allowed in rvim"
-msgstr "E145: rvim ¤¤¸T¤î¨Ï¥Î shell ©R¥O"
-
-#: ../ex_cmds.c:3498
-msgid "E146: Regular expressions can't be delimited by letters"
-msgstr "E146: Regular expression µLªk¥Î¦r¥À¤À¹j (?)"
-
-#: ../ex_cmds.c:3964
-#, c-format
-msgid "replace with %s (y/n/a/q/l/^E/^Y)?"
-msgstr "¨ú¥N¬° %s (y/n/a/q/^E/^Y)?"
-
-#: ../ex_cmds.c:4379
-msgid "(Interrupted) "
-msgstr "(¤w¤¤Â_) "
-
-#: ../ex_cmds.c:4384
-#, fuzzy
-msgid "1 match"
-msgstr "; ²Å¦X "
-
-#: ../ex_cmds.c:4384
-msgid "1 substitution"
-msgstr "¨ú¥N¤@²Õ "
-
-#: ../ex_cmds.c:4387
-#, fuzzy, c-format
-msgid "%<PRId64> matches"
-msgstr "%<PRId64> ¶µ§ïÅÜ"
-
-#: ../ex_cmds.c:4388
-#, c-format
-msgid "%<PRId64> substitutions"
-msgstr "¨ú¥N %<PRId64> ²Õ "
-
-#: ../ex_cmds.c:4392
-msgid " on 1 line"
-msgstr "¡A½d³ò¡G¤@¦æ "
-
-#: ../ex_cmds.c:4395
-#, c-format
-msgid " on %<PRId64> lines"
-msgstr "¡A½d³ò¡G %<PRId64> ¦æ "
-
-#: ../ex_cmds.c:4438
-msgid "E147: Cannot do :global recursive"
-msgstr "E147: :global µLªk»¼°j°õ¦æ "
-
-#: ../ex_cmds.c:4467
-msgid "E148: Regular expression missing from global"
-msgstr "E148: ¨S¦³¨Ï¥Î¹L Regular expression (?)"
-
-#: ../ex_cmds.c:4508
-#, c-format
-msgid "Pattern found in every line: %s"
-msgstr "¨C¤@¦æ³£§ä¤£¨ì: %s"
-
-#: ../ex_cmds.c:4510
-#, fuzzy, c-format
-msgid "Pattern not found: %s"
-msgstr "§ä¤£¨ì"
-
-#: ../ex_cmds.c:4587
-msgid ""
-"\n"
-"# Last Substitute String:\n"
-"$"
-msgstr ""
-"\n"
-"# «e¤@²Õ´À¥N¦r¦ê:\n"
-"$"
-
-#: ../ex_cmds.c:4679
-msgid "E478: Don't panic!"
-msgstr "E478: ¤£­nÅå·W!"
-
-#: ../ex_cmds.c:4717
-#, c-format
-msgid "E661: Sorry, no '%s' help for %s"
-msgstr "E661: ©êºp, ¨S¦³Ãö©ó %s-%s ªº»¡©ú"
-
-#: ../ex_cmds.c:4719
-#, c-format
-msgid "E149: Sorry, no help for %s"
-msgstr "E149: ©êºp, ¨S¦³ %s ªº»¡©ú"
-
-#: ../ex_cmds.c:4751
-#, c-format
-msgid "Sorry, help file \"%s\" not found"
-msgstr "©êºp, §ä¤£¨ì»¡©úÀÉ \"%s\""
-
-#: ../ex_cmds.c:5323
-#, c-format
-msgid "E150: Not a directory: %s"
-msgstr "E150: %s ¤£¬O¥Ø¿ý"
-
-#: ../ex_cmds.c:5446
-#, c-format
-msgid "E152: Cannot open %s for writing"
-msgstr "E152: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò \"%s\""
-
-#: ../ex_cmds.c:5471
-#, c-format
-msgid "E153: Unable to open %s for reading"
-msgstr "E153: µLªkŪ¨úÀÉ®×: %s"
-
-#: ../ex_cmds.c:5500
-#, c-format
-msgid "E670: Mix of help file encodings within a language: %s"
-msgstr "E670: ¦P¤@»y¨¥ (%s) ¤¤¦³²V¦X¤£¦P¦r¤¸½s½Xªº»¡©úÀÉ"
-
-#: ../ex_cmds.c:5565
-#, fuzzy, c-format
-msgid "E154: Duplicate tag \"%s\" in file %s/%s"
-msgstr "E154: ¼ÐÅÒ(tag) \"%s\" ¦bÀÉ®× %s ¸Ì­«½Æ¥X²{¦h¦¸"
-
-#: ../ex_cmds.c:5687
-#, c-format
-msgid "E160: Unknown sign command: %s"
-msgstr "E160: ¥¼©w¸qªº sign command: %s"
-
-#: ../ex_cmds.c:5704
-msgid "E156: Missing sign name"
-msgstr "E156: ¯Ê¤Ö sign ¦WºÙ"
-
-#: ../ex_cmds.c:5746
-msgid "E612: Too many signs defined"
-msgstr "E612: ¤w©w¸q¤Ó¦h signs"
-
-#: ../ex_cmds.c:5813
-#, c-format
-msgid "E239: Invalid sign text: %s"
-msgstr "E239: ¤£¥¿½Tªº sign ¤å¦r: %s"
-
-#: ../ex_cmds.c:5844 ../ex_cmds.c:6035
-#, c-format
-msgid "E155: Unknown sign: %s"
-msgstr "E155: ¤£¥¿½Tªº sign: %s"
-
-#: ../ex_cmds.c:5877
-msgid "E159: Missing sign number"
-msgstr "E159: ¯Ê¤Ö sign number"
-
-#: ../ex_cmds.c:5971
-#, c-format
-msgid "E158: Invalid buffer name: %s"
-msgstr "E158: ½w½Ä°Ï¦WºÙ¿ù»~: %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 "[¤w§R°£]"
-
-#: ../ex_cmds2.c:139
-msgid "Entering Debug mode. Type \"cont\" to continue."
-msgstr "¶i¤J°£¿ù¼Ò¦¡. ¿é¤J \"cont\" ¥H¦^¨ì¥¿±`¼Ò¦¡."
-
-#: ../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 "cmd: %s"
-
-#: ../ex_cmds2.c:322
-#, c-format
-msgid "Breakpoint in \"%s%s\" line %<PRId64>"
-msgstr "\"%s%s\" ¤¤Â_ÂI: ²Ä %<PRId64> ¦æ "
-
-#: ../ex_cmds2.c:581
-#, c-format
-msgid "E161: Breakpoint not found: %s"
-msgstr "E161: §ä¤£¨ì¤¤Â_ÂI: %s"
-
-#: ../ex_cmds2.c:611
-msgid "No breakpoints defined"
-msgstr "¨S¦³©w¸q¤¤Â_ÂI"
-
-#: ../ex_cmds2.c:617
-#, c-format
-msgid "%3d %s %s line %<PRId64>"
-msgstr "%3d %s %s ²Ä %<PRId64> ¦æ "
-
-#: ../ex_cmds2.c:942
-msgid "E750: First use \":profile start {fname}\""
-msgstr ""
-
-#: ../ex_cmds2.c:1269
-#, fuzzy, c-format
-msgid "Save changes to \"%s\"?"
-msgstr "±NÅܰʦsÀx¦Ü \"%.*s\"?"
-
-#: ../ex_cmds2.c:1271 ../ex_docmd.c:8851
-msgid "Untitled"
-msgstr "¥¼©R¦W"
-
-#: ../ex_cmds2.c:1421
-#, c-format
-msgid "E162: No write since last change for buffer \"%s\""
-msgstr "E162: ¤w§ó§ï¹L½w½Ä°Ï \"%s\" ¦ý©|¥¼¦sÀÉ (¥i¥Î ! ±j¨î°õ¦æ)"
-
-#: ../ex_cmds2.c:1480
-msgid "Warning: Entered other buffer unexpectedly (check autocommands)"
-msgstr "ª`·N: ¤w¤Á´«¨ì¨ä¥¦½w½Ä°Ï (½ÐÀˬd Autocommands ¦³µL¿ù»~)"
-
-#: ../ex_cmds2.c:1826
-msgid "E163: There is only one file to edit"
-msgstr "E163: ¥u¦³¤@­ÓÀÉ®×¥i½s¿è"
-
-#: ../ex_cmds2.c:1828
-msgid "E164: Cannot go before first file"
-msgstr "E164: ¤w¸g¦b²Ä¤@­ÓÀɮפF"
-
-#: ../ex_cmds2.c:1830
-msgid "E165: Cannot go beyond last file"
-msgstr "E165: ¤w¸g¦b³Ì«á¤@­ÓÀɮפF"
-
-#: ../ex_cmds2.c:2175
-#, c-format
-msgid "E666: compiler not supported: %s"
-msgstr "E666: ½s;¹¤£¤ä´©: %s"
-
-#: ../ex_cmds2.c:2257
-#, c-format
-msgid "Searching for \"%s\" in \"%s\""
-msgstr "·j´M¤¤: \"%s\" -- \"%s\""
-
-#: ../ex_cmds2.c:2284
-#, c-format
-msgid "Searching for \"%s\""
-msgstr "·j´M¤¤: \"%s\""
-
-#: ../ex_cmds2.c:2307
-#, c-format
-msgid "not found in 'runtimepath': \"%s\""
-msgstr "¦b 'runtimepath' ¸Ì§ä¤£¨ì \"%s\""
-
-#: ../ex_cmds2.c:2472
-#, c-format
-msgid "Cannot source a directory: \"%s\""
-msgstr "µLªk°õ¦æ¥Ø¿ý¡G \"%s\""
-
-#: ../ex_cmds2.c:2518
-#, c-format
-msgid "could not source \"%s\""
-msgstr "µLªk°õ¦æ \"%s\""
-
-#: ../ex_cmds2.c:2520
-#, c-format
-msgid "line %<PRId64>: could not source \"%s\""
-msgstr "²Ä %<PRId64> ¦æ: µLªk°õ¦æ \"%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
-#, fuzzy
-msgid "modeline"
-msgstr "ÁÙ¦³¤@¦æ "
-
-#: ../ex_cmds2.c:2767
-#, fuzzy
-msgid "--cmd argument"
-msgstr "vim [°Ñ¼Æ] "
-
-#: ../ex_cmds2.c:2769
-#, fuzzy
-msgid "-c argument"
-msgstr "vim [°Ñ¼Æ] "
-
-#: ../ex_cmds2.c:2771
-msgid "environment variable"
-msgstr ""
-
-#: ../ex_cmds2.c:2773
-#, fuzzy
-msgid "error handler"
-msgstr "¿ù»~»P¤¤Â_"
-
-#: ../ex_cmds2.c:3020
-msgid "W15: Warning: Wrong line separator, ^M may be missing"
-msgstr "W15: ª`·N: ¿ù»~ªº¦æ¤À¹j¦r¤¸¡A¥i¯à¬O¤Ö¤F ^M"
-
-#: ../ex_cmds2.c:3139
-msgid "E167: :scriptencoding used outside of a sourced file"
-msgstr "E167: ¦b°õ¦æ script ÀÉ®×¥~¤£¥i¨Ï¥Î :scriptencoding"
-
-#: ../ex_cmds2.c:3166
-msgid "E168: :finish used outside of a sourced file"
-msgstr "E168: ¦b°õ¦æ script ÀÉ®×¥~¤£¥i¨Ï¥Î :finish"
-
-#: ../ex_cmds2.c:3389
-#, c-format
-msgid "Current %slanguage: \"%s\""
-msgstr "¥Ø«eªº %s»y¨¥: \"%s\""
-
-#: ../ex_cmds2.c:3404
-#, c-format
-msgid "E197: Cannot set language to \"%s\""
-msgstr "E197: ¤£¯à³]©w»y¨¥¦¨ \"%s\""
-
-#. don't redisplay the window
-#. don't wait for return
-#: ../ex_docmd.c:387
-msgid "Entering Ex mode. Type \"visual\" to go to Normal mode."
-msgstr "¶i¤J Ex ¼Ò¦¡. ¿é¤J \"visua\" ¥H¦^¨ì¥¿±`¼Ò¦¡."
-
-#: ../ex_docmd.c:428
-msgid "E501: At end-of-file"
-msgstr "E501: ¤w¨ìÀÉ®×µ²§À"
-
-#: ../ex_docmd.c:513
-msgid "E169: Command too recursive"
-msgstr "E169: ©R¥O»¼°j¼h¼Æ¹L¦h"
-
-#: ../ex_docmd.c:1006
-#, c-format
-msgid "E605: Exception not caught: %s"
-msgstr "E605: ¥¼ÄdºIªº¨Ò¥~¡G %s"
-
-#: ../ex_docmd.c:1085
-msgid "End of sourced file"
-msgstr "©R¥OÀɵ²§ô"
-
-#: ../ex_docmd.c:1086
-msgid "End of function"
-msgstr "¨ç¦¡µ²§À"
-
-#: ../ex_docmd.c:1628
-msgid "E464: Ambiguous use of user-defined command"
-msgstr "E464: ¨Ï¥ÎªÌ©w¸qªº©R¥O·|²V²c"
-
-#: ../ex_docmd.c:1638
-msgid "E492: Not an editor command"
-msgstr "E492: ¤£¬O½s¿è¾¹ªº©R¥O"
-
-#: ../ex_docmd.c:1729
-msgid "E493: Backwards range given"
-msgstr "E493: «ü©w¤F¦V«e°Ñ¦Òªº½d³ò"
-
-#: ../ex_docmd.c:1733
-msgid "Backwards range given, OK to swap"
-msgstr "«ü©w¤F¦V«e°Ñ¦Òªº½d³ò¡AOK to swap"
-
-#. append
-#. typed wrong
-#: ../ex_docmd.c:1787
-msgid "E494: Use w or w>>"
-msgstr "E494: ½Ð¨Ï¥Î w ©Î w>>"
-
-#: ../ex_docmd.c:3454
-msgid "E319: The command is not available in this version"
-msgstr "E319: ©êºp, ¥»©R¥O¦b¦¹ª©¥»¤¤¨S¦³¹ê§@"
-
-#: ../ex_docmd.c:3752
-msgid "E172: Only one file name allowed"
-msgstr "E172: ¥u¯à¦³¤@­ÓÀÉ"
-
-#: ../ex_docmd.c:4238
-msgid "1 more file to edit. Quit anyway?"
-msgstr "ÁÙ¦³¤@­ÓÀÉ®×¥¼½s¿è. ½T©w­nÂ÷¶}¡H"
-
-#: ../ex_docmd.c:4242
-#, c-format
-msgid "%d more files to edit. Quit anyway?"
-msgstr "ÁÙ¦³ %d ­ÓÀÉ®×¥¼½s¿è. ½T©w­nÂ÷¶}¡H"
-
-#: ../ex_docmd.c:4248
-msgid "E173: 1 more file to edit"
-msgstr "E173: ÁÙ¦³¤@­ÓÀÉ®×¥¼½s¿è "
-
-#: ../ex_docmd.c:4250
-#, c-format
-msgid "E173: %<PRId64> more files to edit"
-msgstr "E173: ÁÙ¦³ %<PRId64> ­ÓÀÉ®×¥¼½s¿è"
-
-#: ../ex_docmd.c:4320
-msgid "E174: Command already exists: add ! to replace it"
-msgstr "E174: ©R¥O¤w¸g¦s¦b, ½Ð¨Ï¥Î ! ±j¨î­«·s©w¸q"
-
-#: ../ex_docmd.c:4432
-msgid ""
-"\n"
-" Name Args Range Complete Definition"
-msgstr ""
-"\n"
-" ¦WºÙ °Ñ¼Æ ½d³ò §¹¾ã ©w¸q "
-
-#: ../ex_docmd.c:4516
-msgid "No user-defined commands found"
-msgstr "§ä¤£¨ì¨Ï¥ÎªÌ©w¸qªº©R¥O"
-
-#: ../ex_docmd.c:4538
-msgid "E175: No attribute specified"
-msgstr "E175: ¨S¦³«ü©wªºÄÝ©Ê"
-
-#: ../ex_docmd.c:4583
-msgid "E176: Invalid number of arguments"
-msgstr "E176: ¤£¥¿½Tªº°Ñ¼Æ¼Æ¥Ø"
-
-#: ../ex_docmd.c:4594
-msgid "E177: Count cannot be specified twice"
-msgstr "E177: ¤£¯à«ü©w¨â¦¸¼Æ¥Ø"
-
-#: ../ex_docmd.c:4603
-msgid "E178: Invalid default value for count"
-msgstr "E178: ¼Æ¥Øªº¹w³]°Ñ¼Æ¤£¥¿½T"
-
-#: ../ex_docmd.c:4625
-#, fuzzy
-msgid "E179: argument required for -complete"
-msgstr "E179: «ü¥O»Ý­n°Ñ¼Æ¤~¯à§¹¦¨"
-
-#: ../ex_docmd.c:4635
-#, c-format
-msgid "E181: Invalid attribute: %s"
-msgstr "E181: ¤£¥¿½TªºÄÝ©Ê: %s"
-
-#: ../ex_docmd.c:4678
-msgid "E182: Invalid command name"
-msgstr "E182: «ü¥O¦WºÙ¤£¥¿½T"
-
-#: ../ex_docmd.c:4691
-msgid "E183: User defined commands must start with an uppercase letter"
-msgstr "E183: ¨Ï¥ÎªÌ¦Û©w«ü¥O¥²¶·¥H¤j¼g¦r¥À¶}©l"
-
-#: ../ex_docmd.c:4696
-#, fuzzy
-msgid "E841: Reserved name, cannot be used for user defined command"
-msgstr "E464: ¨Ï¥ÎªÌ©w¸qªº©R¥O·|²V²c"
-
-#: ../ex_docmd.c:4751
-#, c-format
-msgid "E184: No such user-defined command: %s"
-msgstr "E184: ¨S¦³¨Ï¥ÎªÌ¦Û©wªº©R¥O¡G %s"
-
-#: ../ex_docmd.c:5219
-#, 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: ¦Û­q¸É§¹®É¤~¥i¸É§¹°Ñ¼Æ"
-
-#: ../ex_docmd.c:5231
-msgid "E467: Custom completion requires a function argument"
-msgstr "E467: ¦Û­q¸É§¹»Ý­n¨ç¦¡¬°°Ñ¼Æ"
-
-#: ../ex_docmd.c:5257
-#, fuzzy, c-format
-msgid "E185: Cannot find color scheme '%s'"
-msgstr "E185: §ä¤£¨ìÃC¦â¼Ë¦¡ %s"
-
-#: ../ex_docmd.c:5263
-msgid "Greetings, Vim user!"
-msgstr "¶Ù, Vim ¨Ï¥ÎªÌ¡I"
-
-#: ../ex_docmd.c:5431
-#, fuzzy
-msgid "E784: Cannot close last tab page"
-msgstr "E444: ¤£¯àÃö³¬³Ì«á¤@­Óµøµ¡"
-
-#: ../ex_docmd.c:5462
-#, fuzzy
-msgid "Already only one tab page"
-msgstr "¤w¸g¥u³Ñ¤@­Óµøµ¡¤F"
-
-#: ../ex_docmd.c:6004
-#, fuzzy, c-format
-msgid "Tab page %d"
-msgstr "²Ä %d ­¶"
-
-#: ../ex_docmd.c:6295
-msgid "No swap file"
-msgstr "µL¼È¦sÀÉ"
-
-#: ../ex_docmd.c:6478
-#, fuzzy
-msgid "E747: Cannot change directory, buffer is modified (add ! to override)"
-msgstr "E509: µLªk«Ø¥ß³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#: ../ex_docmd.c:6485
-msgid "E186: No previous directory"
-msgstr "E186: ¨S¦³«e¤@­Ó¥Ø¿ý"
-
-#: ../ex_docmd.c:6530
-msgid "E187: Unknown"
-msgstr "E187: µLªk¿ìÃѪº¼Ð°O"
-
-#: ../ex_docmd.c:6610
-msgid "E465: :winsize requires two number arguments"
-msgstr "E465: :winsize »Ý­n¨â­Ó°Ñ¼Æ"
-
-#: ../ex_docmd.c:6655
-msgid "E188: Obtaining window position not implemented for this platform"
-msgstr "E188: ¦b±zªº¥­¥x¤WµLªkÀò±oµøµ¡¦ì¸m"
-
-#: ../ex_docmd.c:6662
-msgid "E466: :winpos requires two number arguments"
-msgstr "E466: :winpos »Ý­n¨â­Ó°Ñ¼Æ"
-
-#: ../ex_docmd.c:7241
-#, fuzzy, c-format
-msgid "E739: Cannot create directory: %s"
-msgstr "µLªk°õ¦æ¥Ø¿ý¡G \"%s\""
-
-#: ../ex_docmd.c:7268
-#, c-format
-msgid "E189: \"%s\" exists (add ! to override)"
-msgstr "E189: \"%s\" ¤w¦s¦b (½Ð¥Î ! ±j¨î°õ¦æ)"
-
-#: ../ex_docmd.c:7273
-#, c-format
-msgid "E190: Cannot open \"%s\" for writing"
-msgstr "E190: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò \"%s\""
-
-#. set mark
-#: ../ex_docmd.c:7294
-msgid "E191: Argument must be a letter or forward/backward quote"
-msgstr "E191: °Ñ¼Æ¥²¶·¬O­^¤å¦r¥À©Î¦V«e/«áªº¤Þ¸¹"
-
-#: ../ex_docmd.c:7333
-msgid "E192: Recursive use of :normal too deep"
-msgstr "E192: :normal »¼°j¼h¼Æ¹L²`"
-
-#: ../ex_docmd.c:7807
-msgid "E194: No alternate file name to substitute for '#'"
-msgstr "E194: ¨S¦³ '#' ¥i´À¥NªºÀɦW"
-
-#: ../ex_docmd.c:7841
-msgid "E495: no autocommand file name to substitute for \"<afile>\""
-msgstr "E495: ¨S¦³ Autocommand ÀɦW¥H¨ú¥N \"<afile>\""
-
-#: ../ex_docmd.c:7850
-msgid "E496: no autocommand buffer number to substitute for \"<abuf>\""
-msgstr "E496: ¨S¦³ Autocommand ½w½Ä°Ï¦WºÙ¥H¨ú¥N \"<abuf>\""
-
-#: ../ex_docmd.c:7861
-msgid "E497: no autocommand match name to substitute for \"<amatch>\""
-msgstr "E497: ¨S¦³ Autocommand ²Å¦X¦WºÙ¥H¨ú¥N \"<amatch>\""
-
-#: ../ex_docmd.c:7870
-msgid "E498: no :source file name to substitute for \"<sfile>\""
-msgstr "E498: ¨S¦³ :source ÀɦW¥H¨ú¥N \"<sfile>\""
-
-#: ../ex_docmd.c:7876
-#, fuzzy
-msgid "E842: no line number to use for \"<slnum>\""
-msgstr "E498: ¨S¦³ :source ÀɦW¥H¨ú¥N \"<sfile>\""
-
-#: ../ex_docmd.c:7903
-#, fuzzy, c-format
-msgid "E499: Empty file name for '%' or '#', only works with \":p:h\""
-msgstr "E499: '%' ©Î '#' «ü¦VªÅÀɦW¡A¥u¯à¥Î©ó \":p:h\""
-
-#: ../ex_docmd.c:7905
-msgid "E500: Evaluates to an empty string"
-msgstr "E500: ¿é¤J¬°ªÅ¦r¦ê"
-
-#: ../ex_docmd.c:8838
-msgid "E195: Cannot open viminfo file for reading"
-msgstr "E195: µLªkŪ¨ú viminfo"
-
-#: ../ex_eval.c:464
-msgid "E608: Cannot :throw exceptions with 'Vim' prefix"
-msgstr "E608: ¤£¯à :throw ¥Î 'Vim' ¶}ÀYªº¨Ò¥~"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:496
-#, c-format
-msgid "Exception thrown: %s"
-msgstr "¥á¥X¨Ò¥~¡G %s"
-
-#: ../ex_eval.c:545
-#, c-format
-msgid "Exception finished: %s"
-msgstr "¨Ò¥~µ²§ô¡G %s"
-
-#: ../ex_eval.c:546
-#, c-format
-msgid "Exception discarded: %s"
-msgstr "¤w¥á±ó¨Ò¥~¡G %s"
-
-#: ../ex_eval.c:588 ../ex_eval.c:634
-#, c-format
-msgid "%s, line %<PRId64>"
-msgstr "%s, ¦æ %<PRId64>"
-
-#. always scroll up, don't overwrite
-#: ../ex_eval.c:608
-#, c-format
-msgid "Exception caught: %s"
-msgstr "µo¥Í¨Ò¥~¡G%s"
-
-#: ../ex_eval.c:676
-#, c-format
-msgid "%s made pending"
-msgstr "%s ³y¦¨ pending"
-
-#: ../ex_eval.c:679
-#, c-format
-msgid "%s resumed"
-msgstr "%s ¤w¦^´_"
-
-#: ../ex_eval.c:683
-#, c-format
-msgid "%s discarded"
-msgstr "%s ¤w¥á±ó"
-
-#: ../ex_eval.c:708
-msgid "Exception"
-msgstr "¨Ò¥~"
-
-#: ../ex_eval.c:713
-msgid "Error and interrupt"
-msgstr "¿ù»~»P¤¤Â_"
-
-#: ../ex_eval.c:715
-msgid "Error"
-msgstr "¿ù»~"
-
-#. if (pending & CSTP_INTERRUPT)
-#: ../ex_eval.c:717
-msgid "Interrupt"
-msgstr "¤¤Â_"
-
-#: ../ex_eval.c:795
-msgid "E579: :if nesting too deep"
-msgstr "E579: :if ¼h¼Æ¹L²`"
-
-#: ../ex_eval.c:830
-msgid "E580: :endif without :if"
-msgstr "E580: :endif ¯Ê¤Ö¹ïÀ³ªº :if"
-
-#: ../ex_eval.c:873
-msgid "E581: :else without :if"
-msgstr "E581: :else ¯Ê¤Ö¹ïÀ³ªº :if"
-
-#: ../ex_eval.c:876
-msgid "E582: :elseif without :if"
-msgstr "E582: :elseif ¯Ê¤Ö¹ïÀ³ªº :if"
-
-#: ../ex_eval.c:880
-msgid "E583: multiple :else"
-msgstr "E583: ¦h­« :else"
-
-#: ../ex_eval.c:883
-msgid "E584: :elseif after :else"
-msgstr "E584: :elseif ¦b :else ¤§«á"
-
-#: ../ex_eval.c:941
-#, fuzzy
-msgid "E585: :while/:for nesting too deep"
-msgstr "E585: :while ¼h¼Æ¹L²`"
-
-#: ../ex_eval.c:1028
-#, fuzzy
-msgid "E586: :continue without :while or :for"
-msgstr "E586: :continue ¯Ê¤Ö¹ïÀ³ªº :while"
-
-#: ../ex_eval.c:1061
-#, fuzzy
-msgid "E587: :break without :while or :for"
-msgstr "E587: :break ¯Ê¤Ö¹ïÀ³ªº :while"
-
-#: ../ex_eval.c:1102
-#, fuzzy
-msgid "E732: Using :endfor with :while"
-msgstr "E170: ¯Ê¤Ö :endwhile"
-
-#: ../ex_eval.c:1104
-#, fuzzy
-msgid "E733: Using :endwhile with :for"
-msgstr "E170: ¯Ê¤Ö :endwhile"
-
-#: ../ex_eval.c:1247
-msgid "E601: :try nesting too deep"
-msgstr "E601: :if ¼h¼Æ¹L²`"
-
-#: ../ex_eval.c:1317
-msgid "E603: :catch without :try"
-msgstr "E603: :catch ¨S¦³ :try"
-
-#. Give up for a ":catch" after ":finally" and ignore it.
-#. * Just parse.
-#: ../ex_eval.c:1332
-msgid "E604: :catch after :finally"
-msgstr "E604: :catch ¦b :finally ¤§«á"
-
-#: ../ex_eval.c:1451
-msgid "E606: :finally without :try"
-msgstr "E606: :finally ¨S¦³ :try"
-
-#. Give up for a multiple ":finally" and ignore it.
-#: ../ex_eval.c:1467
-msgid "E607: multiple :finally"
-msgstr "E607: ¦h­« :finally"
-
-#: ../ex_eval.c:1571
-msgid "E602: :endtry without :try"
-msgstr "E602: :endif ¯Ê¤Ö¹ïÀ³ªº :if"
-
-#: ../ex_eval.c:2026
-msgid "E193: :endfunction not inside a function"
-msgstr "E193: :endfunction ¥²¶·¦b¨ç¦¡¤º³¡¨Ï¥Î"
-
-#: ../ex_getln.c:1643
-#, fuzzy
-msgid "E788: Not allowed to edit another buffer now"
-msgstr "E48: ¤£¯à¦b sandbox ¸Ì¥X²{"
-
-#: ../ex_getln.c:1656
-#, fuzzy
-msgid "E811: Not allowed to change buffer information now"
-msgstr "E94: §ä¤£¨ì %s"
-
-#: ../ex_getln.c:3178
-msgid "tagname"
-msgstr "¼ÐÅÒ¦WºÙ"
-
-#: ../ex_getln.c:3181
-msgid " kind file\n"
-msgstr "ÃþÀÉ®×\n"
-
-#: ../ex_getln.c:4799
-msgid "'history' option is zero"
-msgstr "¿ï¶µ 'history' ¬O¹s"
-
-#: ../ex_getln.c:5046
-#, c-format
-msgid ""
-"\n"
-"# %s History (newest to oldest):\n"
-msgstr ""
-"\n"
-"# %s ¾ú¥v°O¿ý (·s¨ìÂÂ):\n"
-
-#: ../ex_getln.c:5047
-msgid "Command Line"
-msgstr "©R¥O¦C"
-
-#: ../ex_getln.c:5048
-msgid "Search String"
-msgstr "·j´M¦r¦ê"
-
-#: ../ex_getln.c:5049
-msgid "Expression"
-msgstr "¹Bºâ¦¡"
-
-#: ../ex_getln.c:5050
-msgid "Input Line"
-msgstr "¿é¤J¦æ "
-
-#: ../ex_getln.c:5117
-msgid "E198: cmd_pchar beyond the command length"
-msgstr "E198: cmd_pchar ¶W¹L©R¥Oªø«×"
-
-#: ../ex_getln.c:5279
-msgid "E199: Active window or buffer deleted"
-msgstr "E199: ¤w§R°£±¼§@¥Î¤¤ªºµøµ¡©Î¼È¦s°Ï"
-
-#: ../file_search.c:203
-msgid "E854: path too long for completion"
-msgstr ""
-
-#: ../file_search.c:446
-#, c-format
-msgid ""
-"E343: Invalid path: '**[number]' must be at the end of the path or be "
-"followed by '%s'."
-msgstr "E343: ¤£¥¿½Tªº¸ô®|: '**[number]' ¥²»Ý­n¦b¸ô®|µ²§À©Î­n±µµÛ '%s'"
-
-#: ../file_search.c:1505
-#, c-format
-msgid "E344: Can't find directory \"%s\" in cdpath"
-msgstr "E344: cdpath ¤¤¨S¦³¥Ø¿ý \"%s\""
-
-#: ../file_search.c:1508
-#, c-format
-msgid "E345: Can't find file \"%s\" in path"
-msgstr "E345: ¦b¸ô®|¤¤§ä¤£¨ìÀÉ®× \"%s\""
-
-#: ../file_search.c:1512
-#, c-format
-msgid "E346: No more directory \"%s\" found in cdpath"
-msgstr "E346: ¦b¸ô®|¤¤§ä¤£¨ì§ó¦hªºÀÉ®× \"%s\""
-
-#: ../file_search.c:1515
-#, c-format
-msgid "E347: No more file \"%s\" found in path"
-msgstr "E347: ¦b¸ô®|¤¤§ä¤£¨ì§ó¦hªºÀÉ®× \"%s\""
-
-#: ../fileio.c:137
-#, fuzzy
-msgid "E812: Autocommands changed buffer or buffer name"
-msgstr "E135: *Filter* Autocommand ¤£¥i¥H§ó§ï½w½Ä°Ïªº¤º®e"
-
-#: ../fileio.c:368
-msgid "Illegal file name"
-msgstr "¤£¥¿½TªºÀɦW"
-
-#: ../fileio.c:395 ../fileio.c:476 ../fileio.c:2543 ../fileio.c:2578
-msgid "is a directory"
-msgstr "¬O¥Ø¿ý"
-
-#: ../fileio.c:397
-msgid "is not a file"
-msgstr "¤£¬OÀÉ®×"
-
-#: ../fileio.c:508 ../fileio.c:3522
-msgid "[New File]"
-msgstr "[¥¼©R¦W]"
-
-#: ../fileio.c:511
-msgid "[New DIRECTORY]"
-msgstr ""
-
-#: ../fileio.c:529 ../fileio.c:532
-msgid "[File too big]"
-msgstr ""
-
-#: ../fileio.c:534
-msgid "[Permission Denied]"
-msgstr "[Åv­­¤£¨¬]"
-
-#: ../fileio.c:653
-msgid "E200: *ReadPre autocommands made the file unreadable"
-msgstr "E200: *ReadPre Autocommand ¨Ïµ{¦¡µLªkŪ¨ú¦¹ÀÉ"
-
-#: ../fileio.c:655
-msgid "E201: *ReadPre autocommands must not change current buffer"
-msgstr "E201: *Filter* Autocommand ¤£¥i¥H§ó§ï½w½Ä°Ïªº¤º®e"
-
-#: ../fileio.c:672
-msgid "Nvim: Reading from stdin...\n"
-msgstr "Vim: ±q¼Ð·Ç¿é¤JŪ¨ú...\n"
-
-#. Re-opening the original file failed!
-#: ../fileio.c:909
-msgid "E202: Conversion made file unreadable!"
-msgstr "E202: Âà´«¿ù»~"
-
-#. fifo or socket
-#: ../fileio.c:1782
-msgid "[fifo/socket]"
-msgstr "[fifo/socket]"
-
-#. fifo
-#: ../fileio.c:1788
-msgid "[fifo]"
-msgstr "[fifo]"
-
-#. or socket
-#: ../fileio.c:1794
-msgid "[socket]"
-msgstr "[socket]"
-
-#. or character special
-#: ../fileio.c:1801
-#, fuzzy
-msgid "[character special]"
-msgstr "¤@­Ó¦r¤¸"
-
-#: ../fileio.c:1815
-msgid "[CR missing]"
-msgstr "[¯Ê¤ÖCR]'"
-
-#: ../fileio.c:1819
-msgid "[long lines split]"
-msgstr "[¤À³Î¹Lªø¦æ]"
-
-#: ../fileio.c:1823 ../fileio.c:3512
-msgid "[NOT converted]"
-msgstr "[¥¼Âà´«]"
-
-#: ../fileio.c:1826 ../fileio.c:3515
-msgid "[converted]"
-msgstr "[¤wÂà´«]"
-
-#: ../fileio.c:1831
-#, fuzzy, c-format
-msgid "[CONVERSION ERROR in line %<PRId64>]"
-msgstr "[¦æ %<PRId64> ¦³¤£¥¿½Tªº¦ì¤¸]"
-
-#: ../fileio.c:1835
-#, c-format
-msgid "[ILLEGAL BYTE in line %<PRId64>]"
-msgstr "[¦æ %<PRId64> ¦³¤£¥¿½Tªº¦ì¤¸]"
-
-#: ../fileio.c:1838
-msgid "[READ ERRORS]"
-msgstr "[Ū¨ú¿ù»~]"
-
-#: ../fileio.c:2104
-msgid "Can't find temp file for conversion"
-msgstr "§ä¤£¨ìÂà´«¥Îªº¼È¦sÀÉ"
-
-#: ../fileio.c:2110
-msgid "Conversion with 'charconvert' failed"
-msgstr "¦r¤¸¶°Âà´«¿ù»~"
-
-#: ../fileio.c:2113
-msgid "can't read output of 'charconvert'"
-msgstr "µLªkŪ¨ú 'charconvert' ªº¿é¥X"
-
-#: ../fileio.c:2437
-#, fuzzy
-msgid "E676: No matching autocommands for acwrite buffer"
-msgstr "§ä¤£¨ì¹ïÀ³ªº autocommand"
-
-#: ../fileio.c:2466
-msgid "E203: Autocommands deleted or unloaded buffer to be written"
-msgstr "E203: Autocommand §R°£©ÎÄÀ©ñ¤F­n¼g¤Jªº½w½Ä°Ï"
-
-#: ../fileio.c:2486
-msgid "E204: Autocommand changed number of lines in unexpected way"
-msgstr "E204: Autocommand ·N¥~¦a§ïÅܤF¦æ¸¹"
-
-#: ../fileio.c:2548 ../fileio.c:2565
-msgid "is not a file or writable device"
-msgstr "¤£¬OÀɮשΥi¼g¤Jªº¸Ë¸m"
-
-#: ../fileio.c:2601
-msgid "is read-only (add ! to override)"
-msgstr "¬O°ßŪÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#: ../fileio.c:2886
-msgid "E506: Can't write to backup file (add ! to override)"
-msgstr "E506: µLªk¼g¤J³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#: ../fileio.c:2898
-msgid "E507: Close error for backup file (add ! to override)"
-msgstr "E507: µLªkÃö³¬³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#: ../fileio.c:2901
-msgid "E508: Can't read file for backup (add ! to override)"
-msgstr "E508: µLªkŪ¨úÀÉ®×¥H¨Ñ³Æ¥÷ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#: ../fileio.c:2923
-msgid "E509: Cannot create backup file (add ! to override)"
-msgstr "E509: µLªk«Ø¥ß³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#: ../fileio.c:3008
-msgid "E510: Can't make backup file (add ! to override)"
-msgstr "E510: µLªk»s§@³Æ¥÷ÀÉ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#. Can't write without a tempfile!
-#: ../fileio.c:3121
-msgid "E214: Can't find temp file for writing"
-msgstr "E214: §ä¤£¨ì¼g¤J¥Îªº¼È¦sÀÉ"
-
-#: ../fileio.c:3134
-msgid "E213: Cannot convert (add ! to write without conversion)"
-msgstr "E213: µLªkÂà´« (½Ð¨Ï¥Î ! ±j¨î¤£Âà´«¼g¤J)"
-
-#: ../fileio.c:3169
-msgid "E166: Can't open linked file for writing"
-msgstr "E166: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò³sµ²ÀÉ®×"
-
-#: ../fileio.c:3173
-msgid "E212: Can't open file for writing"
-msgstr "E212: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò"
-
-#: ../fileio.c:3363
-msgid "E667: Fsync failed"
-msgstr "E667: Fsync ©R¥O°õ¦æ¥¢±Ñ"
-
-#: ../fileio.c:3398
-msgid "E512: Close failed"
-msgstr "E512: Ãö³¬¥¢±Ñ"
-
-#: ../fileio.c:3436
-#, fuzzy
-msgid "E513: write error, conversion failed (make 'fenc' empty to override)"
-msgstr "E513: µLªk¼g¤J -- Âà´«¥¢±Ñ"
-
-#: ../fileio.c:3441
-#, c-format
-msgid ""
-"E513: write error, conversion failed in line %<PRId64> (make 'fenc' empty to "
-"override)"
-msgstr ""
-
-#: ../fileio.c:3448
-msgid "E514: write error (file system full?)"
-msgstr "E514: ¼g¤J¿ù»~ (Àɮרt²Î¤wº¡¡H)"
-
-#: ../fileio.c:3506
-msgid " CONVERSION ERROR"
-msgstr "Âà´«¿ù»~"
-
-#: ../fileio.c:3509
-#, fuzzy, c-format
-msgid " in line %<PRId64>;"
-msgstr "¦æ %<PRId64>"
-
-#: ../fileio.c:3519
-msgid "[Device]"
-msgstr "[¸Ë¸m]"
-
-#: ../fileio.c:3522
-msgid "[New]"
-msgstr "[·s]"
-
-#: ../fileio.c:3535
-msgid " [a]"
-msgstr "[a]"
-
-#: ../fileio.c:3535
-msgid " appended"
-msgstr " ¤wªþ¥["
-
-#: ../fileio.c:3537
-msgid " [w]"
-msgstr "[w]"
-
-#: ../fileio.c:3537
-msgid " written"
-msgstr " ¤w¼g¤J"
-
-#: ../fileio.c:3579
-msgid "E205: Patchmode: can't save original file"
-msgstr "E205: Patch ¼Ò¦¡: µLªkÀx¦s­ì©lÀÉ®×"
-
-#: ../fileio.c:3602
-msgid "E206: patchmode: can't touch empty original file"
-msgstr "E206: Patch ¼Ò¦¡: µLªkÅܧóªÅªº­ì©lÀÉ®×"
-
-#: ../fileio.c:3616
-msgid "E207: Can't delete backup file"
-msgstr "E207: µLªk§R°£³Æ¥÷ÀÉ"
-
-#: ../fileio.c:3672
-msgid ""
-"\n"
-"WARNING: Original file may be lost or damaged\n"
-msgstr ""
-"\n"
-"ĵ§i: ­ì©lÀɮ׬y¥¢©Î·lÃa\n"
-
-#: ../fileio.c:3675
-msgid "don't quit the editor until the file is successfully written!"
-msgstr "¦bÀÉ®×¥¿½T¼g¤J«e½Ð¤ÅÂ÷¶}½s¿è¾¹!"
-
-#: ../fileio.c:3795
-msgid "[dos]"
-msgstr "[dos]"
-
-#: ../fileio.c:3795
-msgid "[dos format]"
-msgstr "[dos ®æ¦¡]"
-
-#: ../fileio.c:3801
-msgid "[mac]"
-msgstr "[mac]"
-
-#: ../fileio.c:3801
-msgid "[mac format]"
-msgstr "[mac ®æ¦¡]"
-
-#: ../fileio.c:3807
-msgid "[unix]"
-msgstr "[unix]"
-
-#: ../fileio.c:3807
-msgid "[unix format]"
-msgstr "[unix ®æ¦¡]"
-
-#: ../fileio.c:3831
-msgid "1 line, "
-msgstr "1 ¦æ, "
-
-#: ../fileio.c:3833
-#, c-format
-msgid "%<PRId64> lines, "
-msgstr "%<PRId64> ¦æ, "
-
-#: ../fileio.c:3836
-msgid "1 character"
-msgstr "¤@­Ó¦r¤¸"
-
-#: ../fileio.c:3838
-#, c-format
-msgid "%<PRId64> characters"
-msgstr "%<PRId64>­Ó¦r¤¸"
-
-#: ../fileio.c:3849
-msgid "[noeol]"
-msgstr "[noeol]"
-
-#: ../fileio.c:3849
-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
-msgid "WARNING: The file has been changed since reading it!!!"
-msgstr "ĵ§i: ¥»ÀɮצۤW¦¸Åª¤J«á¤wÅܰÊ!!!"
-
-#: ../fileio.c:3867
-msgid "Do you really want to write to it"
-msgstr "½T©w­n¼g¤J¶Ü"
-
-#: ../fileio.c:4648
-#, c-format
-msgid "E208: Error writing to \"%s\""
-msgstr "E208: ¼g¤JÀÉ®× \"%s\" ¿ù»~"
-
-#: ../fileio.c:4655
-#, c-format
-msgid "E209: Error closing \"%s\""
-msgstr "E209: Ãö³¬ÀÉ®× \"%s\" ¿ù»~"
-
-#: ../fileio.c:4657
-#, c-format
-msgid "E210: Error reading \"%s\""
-msgstr "E210: Ū¨úÀÉ®× \"%s\" ¿ù»~"
-
-#: ../fileio.c:4883
-msgid "E246: FileChangedShell autocommand deleted buffer"
-msgstr "E246: FileChangedShell autocommand §R°£½w½Ä°Ï"
-
-#: ../fileio.c:4894
-#, fuzzy, c-format
-msgid "E211: File \"%s\" no longer available"
-msgstr "E211: ĵ§i: ÀÉ®× \"%s\" ¤w¸g¤£¦s¦b"
-
-#: ../fileio.c:4906
-#, c-format
-msgid ""
-"W12: Warning: File \"%s\" has changed and the buffer was changed in Vim as "
-"well"
-msgstr "W12: ĵ§i: ÀÉ®× \"%s\" ¦Û¤W¦¸Åª¤J«á¤wÅܰÊ, ¦Ó¥B½s¿è¤¤ªº½w½Ä°Ï¤]§ó°Ê¤F"
-
-#: ../fileio.c:4907
-#, fuzzy
-msgid "See \":help W12\" for more info."
-msgstr "¶i¤@¨B»¡©ú½Ð¨£ \":help W11\"¡C"
-
-#: ../fileio.c:4910
-#, c-format
-msgid "W11: Warning: File \"%s\" has changed since editing started"
-msgstr "W11: ĵ§i: ÀÉ®× \"%s\" ¦Û¤W¦¸Åª¤J«á¤wÅܰÊ"
-
-#: ../fileio.c:4911
-msgid "See \":help W11\" for more info."
-msgstr "¶i¤@¨B»¡©ú½Ð¨£ \":help W11\"¡C"
-
-#: ../fileio.c:4914
-#, c-format
-msgid "W16: Warning: Mode of file \"%s\" has changed since editing started"
-msgstr "W16: ĵ§i: ÀÉ®× \"%s\" ªºÅv­­»P¤W¦¸Åª¤J®É¤£¤@¼Ë (¦³ÅܰʹL)"
-
-#: ../fileio.c:4915
-#, fuzzy
-msgid "See \":help W16\" for more info."
-msgstr "¶i¤@¨B»¡©ú½Ð¨£ \":help W11\"¡C"
-
-# 'mode' seems better as translated to 'permission'?
-#: ../fileio.c:4927
-#, c-format
-msgid "W13: Warning: File \"%s\" has been created after editing started"
-msgstr "W13: ĵ§i: ÀÉ®× \"%s\" ¦b¶}©l½s¿è«á¤S³Q«Ø¥ß¤F"
-
-#: ../fileio.c:4947
-msgid "Warning"
-msgstr "ĵ§i"
-
-#: ../fileio.c:4948
-msgid ""
-"&OK\n"
-"&Load File"
-msgstr ""
-"½T©w(&O)\n"
-"¸ü¤JÀÉ®×(&L)"
-
-#: ../fileio.c:5065
-#, c-format
-msgid "E462: Could not prepare for reloading \"%s\""
-msgstr "E462: µLªk·Ç³Æ­«·s¸ü¤J \"%s\""
-
-#: ../fileio.c:5078
-#, c-format
-msgid "E321: Could not reload \"%s\""
-msgstr "E321: µLªk­«·s¸ü¤J \"%s\""
-
-#: ../fileio.c:5601
-msgid "--Deleted--"
-msgstr "--¤w§R°£--"
-
-#: ../fileio.c:5732
-#, c-format
-msgid "auto-removing autocommand: %s <buffer=%d>"
-msgstr ""
-
-#. the group doesn't exist
-#: ../fileio.c:5772
-#, c-format
-msgid "E367: No such group: \"%s\""
-msgstr "E367: µL¦¹¸s²Õ: \"%s\""
-
-#: ../fileio.c:5897
-#, c-format
-msgid "E215: Illegal character after *: %s"
-msgstr "E215: * «á­±¦³¤£¥¿½Tªº¦r¤¸: %s"
-
-#: ../fileio.c:5905
-#, c-format
-msgid "E216: No such event: %s"
-msgstr "E216: µL¦¹¨Æ¥ó: %s"
-
-#: ../fileio.c:5907
-#, c-format
-msgid "E216: No such group or event: %s"
-msgstr "E216: µL¦¹¸s²Õ©Î¨Æ¥ó: %s"
-
-#. Highlight title
-#: ../fileio.c:6090
-msgid ""
-"\n"
-"--- Auto-Commands ---"
-msgstr ""
-"\n"
-"--- Auto-Commands ---"
-
-#: ../fileio.c:6293
-#, fuzzy, c-format
-msgid "E680: <buffer=%d>: invalid buffer number "
-msgstr "½w½Ä°Ï¸¹½X¿ù»~"
-
-#: ../fileio.c:6370
-msgid "E217: Can't execute autocommands for ALL events"
-msgstr "E217: µLªk¹ï©Ò¦³¨Æ¥ó°õ¦æ autocommand"
-
-#: ../fileio.c:6393
-msgid "No matching autocommands"
-msgstr "§ä¤£¨ì¹ïÀ³ªº autocommand"
-
-#: ../fileio.c:6831
-msgid "E218: autocommand nesting too deep"
-msgstr "E218: autocommand ¼h¼Æ¹L²`"
-
-#: ../fileio.c:7143
-#, c-format
-msgid "%s Auto commands for \"%s\""
-msgstr "%s Auto commands: \"%s\""
-
-#: ../fileio.c:7149
-#, c-format
-msgid "Executing %s"
-msgstr "°õ¦æ %s"
-
-#: ../fileio.c:7211
-#, c-format
-msgid "autocommand %s"
-msgstr "autocommand %s"
-
-#: ../fileio.c:7795
-msgid "E219: Missing {."
-msgstr "E219: ¯Ê¤Ö {."
-
-#: ../fileio.c:7797
-msgid "E220: Missing }."
-msgstr "E220: ¯Ê¤Ö }."
-
-#: ../fold.c:93
-msgid "E490: No fold found"
-msgstr "E490: §ä¤£¨ì¥ô¦ó fold"
-
-#: ../fold.c:544
-msgid "E350: Cannot create fold with current 'foldmethod'"
-msgstr "E350: µLªk¦b¥Ø«eªº 'foldmethod' ¤U«Ø¥ß fold"
-
-#: ../fold.c:546
-msgid "E351: Cannot delete fold with current 'foldmethod'"
-msgstr "E351: µLªk¦b¥Ø«eªº 'foldmethod' ¤U§R°£ fold"
-
-#: ../fold.c:1784
-#, c-format
-msgid "+--%3ld lines folded "
-msgstr "+--¤w fold %3ld ¦æ "
-
-#. buffer has already been read
-#: ../getchar.c:273
-msgid "E222: Add to read buffer"
-msgstr "E222: ¥[¤JŪ¨ú½w½Ä°Ï¤¤"
-
-#: ../getchar.c:2040
-msgid "E223: recursive mapping"
-msgstr "E223: »¼°j mapping"
-
-#: ../getchar.c:2849
-#, c-format
-msgid "E224: global abbreviation already exists for %s"
-msgstr "E224: %s ¤w¸g¦³¥þ°ì abbreviation ¤F"
-
-#: ../getchar.c:2852
-#, c-format
-msgid "E225: global mapping already exists for %s"
-msgstr "E225: %s ¤w¸g¦³¥þ°ì mapping ¤F"
-
-#: ../getchar.c:2952
-#, c-format
-msgid "E226: abbreviation already exists for %s"
-msgstr "E226: %s ¤w¸g¦³ abbreviation ¤F"
-
-#: ../getchar.c:2955
-#, c-format
-msgid "E227: mapping already exists for %s"
-msgstr "E227: %s ªº mapping ¤w¸g¦s¦b"
-
-#: ../getchar.c:3008
-msgid "No abbreviation found"
-msgstr "§ä¤£¨ì abbreviation"
-
-#: ../getchar.c:3010
-msgid "No mapping found"
-msgstr "¨S¦³³o­Ó mapping ¹ïÀ³"
-
-#: ../getchar.c:3974
-msgid "E228: makemap: Illegal mode"
-msgstr "E228: makemap: ¤£¥¿½Tªº¼Ò¦¡"
-
-#. key value of 'cedit' option
-#. type of cmdline window or 0
-#. result of cmdline window or 0
-#: ../globals.h:924
-msgid "--No lines in buffer--"
-msgstr "--½w½Ä°ÏµL¸ê®Æ--"
-
-#.
-#. * The error messages that can be shared are included here.
-#. * Excluded are errors that are only used once and debugging messages.
-#.
-#: ../globals.h:996
-msgid "E470: Command aborted"
-msgstr "E470: ©R¥O³Q±j¨î¤¤Â_°õ¦æ "
-
-#: ../globals.h:997
-msgid "E471: Argument required"
-msgstr "E471: »Ý­n«ü¥O°Ñ¼Æ"
-
-#: ../globals.h:998
-msgid "E10: \\ should be followed by /, ? or &"
-msgstr "E10: \\ «á­±À³¸Ó¦³ / ? ©Î &"
-
-#: ../globals.h:1000
-msgid "E11: Invalid in command-line window; <CR> executes, CTRL-C quits"
-msgstr "E11: ¤£¯à¦b©R¥O¦Cµøµ¡¤¤¨Ï¥Î¡C<CR>°õ¦æ¡ACTRL-C Â÷¶}"
-
-#: ../globals.h:1002
-msgid "E12: Command not allowed from exrc/vimrc in current dir or tag search"
-msgstr "E12: exrc/vimrc ¸Ìªº«ü¥OµLªk°õ¦æ "
-
-#: ../globals.h:1003
-msgid "E171: Missing :endif"
-msgstr "E171: ¯Ê¤Ö :endif"
-
-#: ../globals.h:1004
-msgid "E600: Missing :endtry"
-msgstr "E600: ¯Ê¤Ö :endtry"
-
-#: ../globals.h:1005
-msgid "E170: Missing :endwhile"
-msgstr "E170: ¯Ê¤Ö :endwhile"
-
-#: ../globals.h:1006
-#, fuzzy
-msgid "E170: Missing :endfor"
-msgstr "E171: ¯Ê¤Ö :endif"
-
-#: ../globals.h:1007
-msgid "E588: :endwhile without :while"
-msgstr "E588: :endwhile ¯Ê¤Ö¹ïÀ³ªº :while"
-
-#: ../globals.h:1008
-#, fuzzy
-msgid "E588: :endfor without :for"
-msgstr "E580: :endif ¯Ê¤Ö¹ïÀ³ªº :if"
-
-#: ../globals.h:1009
-msgid "E13: File exists (add ! to override)"
-msgstr "E13: Àɮפw¸g¦s¦b (¥i¥Î ! ±j¨î¨ú¥N)"
-
-#: ../globals.h:1010
-msgid "E472: Command failed"
-msgstr "E472: ©R¥O°õ¦æ¥¢±Ñ"
-
-#: ../globals.h:1011
-msgid "E473: Internal error"
-msgstr "E473: ¤º³¡¿ù»~"
-
-#: ../globals.h:1012
-msgid "Interrupted"
-msgstr "¤w¤¤Â_"
-
-#: ../globals.h:1013
-msgid "E14: Invalid address"
-msgstr "E14: ¤£¥¿½Tªº¦ì§}"
-
-#: ../globals.h:1014
-msgid "E474: Invalid argument"
-msgstr "E474: ¤£¥¿½Tªº°Ñ¼Æ"
-
-#: ../globals.h:1015
-#, c-format
-msgid "E475: Invalid argument: %s"
-msgstr "E475: ¤£¥¿½Tªº°Ñ¼Æ: %s"
-
-#: ../globals.h:1016
-#, c-format
-msgid "E15: Invalid expression: %s"
-msgstr "E15: ¤£¥¿½Tªº¹Bºâ¦¡: %s"
-
-#: ../globals.h:1017
-msgid "E16: Invalid range"
-msgstr "E16: ¤£¥¿½Tªº½d³ò"
-
-#: ../globals.h:1018
-msgid "E476: Invalid command"
-msgstr "E476: ¤£¥¿½Tªº©R¥O"
-
-#: ../globals.h:1019
-#, c-format
-msgid "E17: \"%s\" is a directory"
-msgstr "E17: \"%s\" ¬O¥Ø¿ý"
-
-#: ../globals.h:1020
-#, fuzzy
-msgid "E900: Invalid job id"
-msgstr "E49: ¿ù»~ªº±²°Ê¤j¤p"
-
-#: ../globals.h:1021
-msgid "E901: Job table is full"
-msgstr ""
-
-#: ../globals.h:1022
-#, c-format
-msgid "E902: \"%s\" is not an executable"
-msgstr ""
-
-#: ../globals.h:1024
-#, c-format
-msgid "E364: Library call failed for \"%s()\""
-msgstr "E364: ©I¥s¨ç¦¡®w \"%s\"() ¥¢±Ñ"
-
-#: ../globals.h:1026
-msgid "E19: Mark has invalid line number"
-msgstr "E19: ¼Ð°Oªº¦æ¸¹¿ù»~"
-
-#: ../globals.h:1027
-msgid "E20: Mark not set"
-msgstr "E20: ¨S¦³³]©w¼Ð°O"
-
-#: ../globals.h:1029
-msgid "E21: Cannot make changes, 'modifiable' is off"
-msgstr "E21: ¦]¬° 'modifiable' ¿ï¶µ¬OÃö³¬ªº¡A©Ò¥H¤£¯à­×§ï"
-
-#: ../globals.h:1030
-msgid "E22: Scripts nested too deep"
-msgstr "E22: ±_ª¬»¼°j©I¥s¤Ó¦h¼h"
-
-#: ../globals.h:1031
-msgid "E23: No alternate file"
-msgstr "E23: ¨S¦³´À¥NªºÀÉ®×"
-
-#: ../globals.h:1032
-msgid "E24: No such abbreviation"
-msgstr "E24: ¨S¦³³o­Ó abbreviation ¹ïÀ³"
-
-#: ../globals.h:1033
-msgid "E477: No ! allowed"
-msgstr "E477: ¤£¥i¨Ï¥Î '!'"
-
-#: ../globals.h:1035
-msgid "E25: Nvim does not have a built-in GUI"
-msgstr "E25: ¦]¬°½sͮɍS¦³¥[¤J¹Ï«¬¬É­±ªºµ{¦¡½X¡A©Ò¥HµLªk¨Ï¥Î¹Ï«¬¬É­±"
-
-#: ../globals.h:1036
-#, c-format
-msgid "E28: No such highlight group name: %s"
-msgstr "E28: ¨S¦³¦W¬° '%s' ªº highlight group"
-
-#: ../globals.h:1037
-msgid "E29: No inserted text yet"
-msgstr "E29: ÁÙ¨S¦³´¡¤J¤å¦r¹L"
-
-#: ../globals.h:1038
-msgid "E30: No previous command line"
-msgstr "E30: ¨S¦³«e¤@¶µ©R¥O"
-
-#: ../globals.h:1039
-msgid "E31: No such mapping"
-msgstr "E31: ¨S¦³³o­Ó mapping ¹ïÀ³"
-
-#: ../globals.h:1040
-msgid "E479: No match"
-msgstr "E479: §ä¤£¨ì"
-
-#: ../globals.h:1041
-#, c-format
-msgid "E480: No match: %s"
-msgstr "E480: §ä¤£¨ì: %s"
-
-#: ../globals.h:1042
-msgid "E32: No file name"
-msgstr "E32: ¨S¦³ÀɦW"
-
-#: ../globals.h:1044
-msgid "E33: No previous substitute regular expression"
-msgstr "E33: ¨S¦³«e¤@­Ó·j´M/¨ú¥Nªº©R¥O"
-
-#: ../globals.h:1045
-msgid "E34: No previous command"
-msgstr "E34: ¨S¦³«e¤@­Ó©R¥O"
-
-#: ../globals.h:1046
-msgid "E35: No previous regular expression"
-msgstr "E35: ¨S¦³«e¤@­Ó·j´M«ü¥O"
-
-#: ../globals.h:1047
-msgid "E481: No range allowed"
-msgstr "E481: ¤£¥i¨Ï¥Î½d³ò«ü¥O"
-
-#: ../globals.h:1048
-msgid "E36: Not enough room"
-msgstr "E36: ¨S¦³¨¬°÷ªºªÅ¶¡"
-
-#: ../globals.h:1049
-#, c-format
-msgid "E482: Can't create file %s"
-msgstr "E482: ¤£¯à«Ø¥ßÀÉ®× %s"
-
-#: ../globals.h:1050
-msgid "E483: Can't get temp file name"
-msgstr "E483: µLªk±oª¾¼È¦sÀɦW"
-
-#: ../globals.h:1051
-#, c-format
-msgid "E484: Can't open file %s"
-msgstr "E484: µLªk¶}±ÒÀÉ®× %s"
-
-#: ../globals.h:1052
-#, c-format
-msgid "E485: Can't read file %s"
-msgstr "E485: µLªkŪ¨úÀÉ®× %s"
-
-#: ../globals.h:1054
-msgid "E37: No write since last change (add ! to override)"
-msgstr "E37: ¤w§ó§ï¹LÀɮצý©|¥¼¦sÀÉ (¥i¥Î ! ±j¨î°õ¦æ)"
-
-#: ../globals.h:1055
-#, fuzzy
-msgid "E37: No write since last change"
-msgstr "[§ó·s«á©|¥¼Àx¦s]\n"
-
-#: ../globals.h:1056
-msgid "E38: Null argument"
-msgstr "E38: ªÅªº (Null) °Ñ¼Æ"
-
-#: ../globals.h:1057
-msgid "E39: Number expected"
-msgstr "E39: À³¸Ó­n¦³¼Æ¦r"
-
-#: ../globals.h:1058
-#, c-format
-msgid "E40: Can't open errorfile %s"
-msgstr "E40: µLªk¶}±Ò¿ù»~ÀÉ®× %s"
-
-#: ../globals.h:1059
-msgid "E41: Out of memory!"
-msgstr "E41: °O¾ÐÅ餣¨¬!"
-
-#: ../globals.h:1060
-msgid "Pattern not found"
-msgstr "§ä¤£¨ì"
-
-#: ../globals.h:1061
-#, c-format
-msgid "E486: Pattern not found: %s"
-msgstr "E486: §ä¤£¨ì %s"
-
-#: ../globals.h:1062
-msgid "E487: Argument must be positive"
-msgstr "E487: °Ñ¼ÆÀ³¸Ó¬O¥¿¼Æ"
-
-#: ../globals.h:1064
-msgid "E459: Cannot go back to previous directory"
-msgstr "E459: µLªk¦^¨ì«e¤@­Ó¥Ø¿ý"
-
-#: ../globals.h:1066
-msgid "E42: No Errors"
-msgstr "E42: ¨S¦³¿ù»~"
-
-#: ../globals.h:1067
-msgid "E776: No location list"
-msgstr ""
-
-#: ../globals.h:1068
-msgid "E43: Damaged match string"
-msgstr "E43: ²Å¦X¦r¦ê¦³°ÝÃD"
-
-#: ../globals.h:1069
-msgid "E44: Corrupted regexp program"
-msgstr "E44: regexp ¦³°ÝÃD"
-
-#: ../globals.h:1071
-msgid "E45: 'readonly' option is set (add ! to override)"
-msgstr "E45: ¦³³]©w 'readonly' ¿ï¶µ(°ßŪ) (¥i¥Î ! ±j¨î°õ¦æ)"
-
-#: ../globals.h:1073
-#, fuzzy, c-format
-msgid "E46: Cannot change read-only variable \"%s\""
-msgstr "E46: µLªk³]©w°ßŪÅÜ¼Æ \"%s\""
-
-#: ../globals.h:1075
-#, fuzzy, c-format
-msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr "E46: µLªk³]©w°ßŪÅÜ¼Æ \"%s\""
-
-#: ../globals.h:1076
-msgid "E47: Error while reading errorfile"
-msgstr "E47: Ū¨ú¿ù»~ÀÉ®×¥¢±Ñ"
-
-#: ../globals.h:1078
-msgid "E48: Not allowed in sandbox"
-msgstr "E48: ¤£¯à¦b sandbox ¸Ì¥X²{"
-
-#: ../globals.h:1080
-msgid "E523: Not allowed here"
-msgstr "E523: ³o¸Ì¤£¥i¨Ï¥Î"
-
-#: ../globals.h:1082
-msgid "E359: Screen mode setting not supported"
-msgstr "E359: ¤£¤ä´©³]©w¿Ã¹õ¼Ò¦¡"
-
-#: ../globals.h:1083
-msgid "E49: Invalid scroll size"
-msgstr "E49: ¿ù»~ªº±²°Ê¤j¤p"
-
-#: ../globals.h:1084
-msgid "E91: 'shell' option is empty"
-msgstr "E91: 'E71: ¿ï¶µ 'shell' ¥¼³]©w"
-
-#: ../globals.h:1085
-msgid "E255: Couldn't read in sign data!"
-msgstr "E255: µLªkŪ¨ú sign data!"
-
-#: ../globals.h:1086
-msgid "E72: Close error on swap file"
-msgstr "E72: ¼È¦sÀÉÃö³¬¿ù»~"
-
-#: ../globals.h:1087
-msgid "E73: tag stack empty"
-msgstr "E73: ¼ÐÅÒ°ïÅ|¤wªÅ"
-
-#: ../globals.h:1088
-msgid "E74: Command too complex"
-msgstr "E74: ©R¥O¤Ó½ÆÂø"
-
-#: ../globals.h:1089
-msgid "E75: Name too long"
-msgstr "E75: ¦W¦r¤Óªø"
-
-#: ../globals.h:1090
-msgid "E76: Too many ["
-msgstr "E76: ¤Ó¦h ["
-
-#: ../globals.h:1091
-msgid "E77: Too many file names"
-msgstr "E77: ¤Ó¦hÀɦW"
-
-#: ../globals.h:1092
-msgid "E488: Trailing characters"
-msgstr "E488: §A¿é¤J¤F¦h¾lªº¦r¤¸"
-
-#: ../globals.h:1093
-msgid "E78: Unknown mark"
-msgstr "E78: µLªk¿ìÃѪº¼Ð°O"
-
-#: ../globals.h:1094
-msgid "E79: Cannot expand wildcards"
-msgstr "E79: µLªk®i¶}¸U¥Î¦r¤¸"
-
-#: ../globals.h:1096
-msgid "E591: 'winheight' cannot be smaller than 'winminheight'"
-msgstr "E591: 'winheight' ¤£¯à¤ñ 'winminheight' §ó¤Ö"
-
-#: ../globals.h:1098
-msgid "E592: 'winwidth' cannot be smaller than 'winminwidth'"
-msgstr "E592: 'winwidth' ¤£¯à¤ñ 'winminwidth' §ó¤Ö"
-
-#: ../globals.h:1099
-msgid "E80: Error while writing"
-msgstr "E80: ¼g¤J¿ù»~"
-
-#: ../globals.h:1100
-msgid "Zero count"
-msgstr "¼Æ¨ì¹s (?)"
-
-#: ../globals.h:1101
-msgid "E81: Using <SID> not in a script context"
-msgstr "E81: <SID> ¤£¯à¦b script ¥»¤å¥~¨Ï¥Î."
-
-#: ../globals.h:1102
-#, fuzzy, c-format
-msgid "E685: Internal error: %s"
-msgstr "E473: ¤º³¡¿ù»~"
-
-#: ../globals.h:1104
-msgid "E363: pattern uses more memory than 'maxmempattern'"
-msgstr ""
-
-#: ../globals.h:1105
-#, fuzzy
-msgid "E749: empty buffer"
-msgstr "E279: ¤£¬O SNiFF+ ªº½w½Ä°Ï"
-
-#: ../globals.h:1108
-#, fuzzy
-msgid "E682: Invalid search pattern or delimiter"
-msgstr "E383: ¿ù»~ªº·j´M¦r¦ê: %s"
-
-#: ../globals.h:1109
-msgid "E139: File is loaded in another buffer"
-msgstr "E139: ±z¦b¥t¤@­Ó½w½Ä°Ï¤]¸ü¤J¤F³o­ÓÀÉ®×"
-
-#: ../globals.h:1110
-#, fuzzy, c-format
-msgid "E764: Option '%s' is not set"
-msgstr "E236: \"%s\" ¤£¬O©T©w¼e«×¦r«¬"
-
-#: ../globals.h:1111
-#, fuzzy
-msgid "E850: Invalid register name"
-msgstr "E354: ¼È¦s¾¹¦WºÙ¿ù»~: '%s'"
-
-#: ../globals.h:1114
-msgid "search hit TOP, continuing at BOTTOM"
-msgstr "¤w·j´M¨ìÀÉ®×¶}ÀY¡F¦A±qµ²§ÀÄ~Äò·j´M"
-
-#: ../globals.h:1115
-msgid "search hit BOTTOM, continuing at TOP"
-msgstr "¤w·j´M¨ìÀÉ®×µ²§À¡F¦A±q¶}ÀYÄ~Äò·j´M"
-
-#: ../hardcopy.c:240
-msgid "E550: Missing colon"
-msgstr "E550: ¯Ê¤Ö colon"
-
-#: ../hardcopy.c:252
-msgid "E551: Illegal component"
-msgstr "E551: ¤£¥¿½Tªº¼Ò¦¡"
-
-#: ../hardcopy.c:259
-msgid "E552: digit expected"
-msgstr "E552: À³¸Ó­n¦³¼Æ¦r"
-
-#: ../hardcopy.c:473
-#, c-format
-msgid "Page %d"
-msgstr "²Ä %d ­¶"
-
-#: ../hardcopy.c:597
-msgid "No text to be printed"
-msgstr "¨S¦³­n¦C¦Lªº¤å¦r"
-
-#: ../hardcopy.c:668
-#, c-format
-msgid "Printing page %d (%d%%)"
-msgstr "¦C¦L¤¤: ²Ä %d ­¶ (%d%%)"
-
-#: ../hardcopy.c:680
-#, c-format
-msgid " Copy %d of %d"
-msgstr "½Æ»s %d / %d"
-
-#: ../hardcopy.c:733
-#, c-format
-msgid "Printed: %s"
-msgstr "¤w¦C¦L: %s"
-
-#: ../hardcopy.c:740
-msgid "Printing aborted"
-msgstr "¤w¨ú®ø¦C¦L"
-
-#: ../hardcopy.c:1365
-msgid "E455: Error writing to PostScript output file"
-msgstr "E455: µLªk¼g¤J PostScript ¿é¥XÀÉ"
-
-#: ../hardcopy.c:1747
-#, c-format
-msgid "E624: Can't open file \"%s\""
-msgstr "E624: µLªk¶}±ÒÀÉ®× \"%s\""
-
-#: ../hardcopy.c:1756 ../hardcopy.c:2470
-#, c-format
-msgid "E457: Can't read PostScript resource file \"%s\""
-msgstr "E457: µLªkŪ¨ú PostScript ¸ê·½ÀÉ \"%s\""
-
-#: ../hardcopy.c:1772
-#, c-format
-msgid "E618: file \"%s\" is not a PostScript resource file"
-msgstr "E618: ÀÉ®× \"%s\" ¤£¬O PostScript ¸ê·½ÀÉ "
-
-#: ../hardcopy.c:1788 ../hardcopy.c:1805 ../hardcopy.c:1844
-#, c-format
-msgid "E619: file \"%s\" is not a supported PostScript resource file"
-msgstr "E619: ¤£¤ä´© PostScript ¸ê·½ÀÉ \"%s\""
-
-#: ../hardcopy.c:1856
-#, c-format
-msgid "E621: \"%s\" resource file has wrong version"
-msgstr "E621: \"%s\" ¸ê·½Àɪ©¥»¿ù»~"
-
-#: ../hardcopy.c:2225
-msgid "E673: Incompatible multi-byte encoding and character set."
-msgstr ""
-
-#: ../hardcopy.c:2238
-msgid "E674: printmbcharset cannot be empty with multi-byte encoding."
-msgstr ""
-
-#: ../hardcopy.c:2254
-msgid "E675: No default font specified for multi-byte printing."
-msgstr ""
-
-#: ../hardcopy.c:2426
-msgid "E324: Can't open PostScript output file"
-msgstr "E324: µLªk¶}±Ò PostScript ¿é¥XÀÉ"
-
-#: ../hardcopy.c:2458
-#, c-format
-msgid "E456: Can't open file \"%s\""
-msgstr "E456: µLªk¶}±ÒÀÉ®× \"%s\""
-
-#: ../hardcopy.c:2583
-msgid "E456: Can't find PostScript resource file \"prolog.ps\""
-msgstr "E456: µLªkŪ¨ú PostScript ¸ê·½ÀÉ \"prolog.ps\""
-
-#: ../hardcopy.c:2593
-#, fuzzy
-msgid "E456: Can't find PostScript resource file \"cidfont.ps\""
-msgstr "E456: µLªkŪ¨ú PostScript ¸ê·½ÀÉ \"%s.ps\""
-
-#: ../hardcopy.c:2622 ../hardcopy.c:2639 ../hardcopy.c:2665
-#, c-format
-msgid "E456: Can't find PostScript resource file \"%s.ps\""
-msgstr "E456: µLªkŪ¨ú PostScript ¸ê·½ÀÉ \"%s.ps\""
-
-#: ../hardcopy.c:2654
-#, fuzzy, c-format
-msgid "E620: Unable to convert to print encoding \"%s\""
-msgstr "E620:µLªkÂà´«¦Ü \"%s\" ¦r¤¸½s½X"
-
-#: ../hardcopy.c:2877
-msgid "Sending to printer..."
-msgstr "¶Ç°e¸ê®Æ¨ì¦Lªí¾÷..."
-
-#: ../hardcopy.c:2881
-msgid "E365: Failed to print PostScript file"
-msgstr "E365: µLªk¦C¦L PostScript ÀÉ®×"
-
-#: ../hardcopy.c:2883
-msgid "Print job sent."
-msgstr "¤w°e¥X¦C¦L¤u§@¡C"
-
-#: ../if_cscope.c:85
-msgid "Add a new database"
-msgstr "·s¼W¸ê®Æ®w"
-
-#: ../if_cscope.c:87
-msgid "Query for a pattern"
-msgstr "¿é¤J pattern"
-
-#: ../if_cscope.c:89
-msgid "Show this message"
-msgstr "Åã¥Ü¦¹°T®§"
-
-#: ../if_cscope.c:91
-msgid "Kill a connection"
-msgstr "µ²§ô³s½u"
-
-#: ../if_cscope.c:93
-msgid "Reinit all connections"
-msgstr "­«³]©Ò¦³³s½u"
-
-#: ../if_cscope.c:95
-msgid "Show connections"
-msgstr "Åã¥Ü³s½u"
-
-#: ../if_cscope.c:101
-#, c-format
-msgid "E560: Usage: cs[cope] %s"
-msgstr "E560: ¥Îªk: cs[cope] %s"
-
-#: ../if_cscope.c:225
-msgid "This cscope command does not support splitting the window.\n"
-msgstr "³o­Ó cscope ©R¥O¤£¤ä´©¤À³Î¿Ã¹õ\n"
-
-#: ../if_cscope.c:266
-msgid "E562: Usage: cstag <ident>"
-msgstr "E562: ¥Îªk: cstag <ÃѧO¦rident>"
-
-#: ../if_cscope.c:313
-msgid "E257: cstag: tag not found"
-msgstr "E257: cstag: §ä¤£¨ì tag"
-
-#: ../if_cscope.c:461
-#, c-format
-msgid "E563: stat(%s) error: %d"
-msgstr "E563: stat(%s) ¿ù»~: %d"
-
-#: ../if_cscope.c:551
-#, c-format
-msgid "E564: %s is not a directory or a valid cscope database"
-msgstr "E564: %s ¤£¬O¥Ø¿ý©Î cscope ¸ê®Æ®w"
-
-#: ../if_cscope.c:566
-#, c-format
-msgid "Added cscope database %s"
-msgstr "·s¼W cscope ¸ê®Æ®w %s"
-
-#: ../if_cscope.c:616
-#, c-format
-msgid "E262: error reading cscope connection %<PRId64>"
-msgstr "E262: Ū¨ú cscope ³s½u %<PRId64> ¿ù»~"
-
-#: ../if_cscope.c:711
-msgid "E561: unknown cscope search type"
-msgstr "E561: ¥¼ª¾ªº cscope ·j´M§ÎºA"
-
-#: ../if_cscope.c:752 ../if_cscope.c:789
-msgid "E566: Could not create cscope pipes"
-msgstr "E566: µLªk«Ø¥ß»P cscope ªº pipe ³s½u"
-
-#: ../if_cscope.c:767
-msgid "E622: Could not fork for cscope"
-msgstr "E622: µLªk fork ¥H°õ¦æ cscope "
-
-#: ../if_cscope.c:849
-#, fuzzy
-msgid "cs_create_connection setpgid failed"
-msgstr "cs_create_connection °õ¦æ¥¢±Ñ"
-
-#: ../if_cscope.c:853 ../if_cscope.c:889
-msgid "cs_create_connection exec failed"
-msgstr "cs_create_connection °õ¦æ¥¢±Ñ"
-
-#: ../if_cscope.c:863 ../if_cscope.c:902
-msgid "cs_create_connection: fdopen for to_fp failed"
-msgstr "cs_create_connection: fdopen ¥¢±Ñ (to_fp)"
-
-#: ../if_cscope.c:865 ../if_cscope.c:906
-msgid "cs_create_connection: fdopen for fr_fp failed"
-msgstr "cs_create_connection: fdopen ¥¢±Ñ (fr_fp)"
-
-#: ../if_cscope.c:890
-msgid "E623: Could not spawn cscope process"
-msgstr "E623: µLªk°õ¦æ cscope "
-
-#: ../if_cscope.c:932
-msgid "E567: no cscope connections"
-msgstr "E567: ¨S¦³ cscope ³s½u"
-
-#: ../if_cscope.c:1009
-#, c-format
-msgid "E469: invalid cscopequickfix flag %c for %c"
-msgstr "E469: cscopequickfix ªº flac %c (%c) ¤£¥¿½T"
-
-#: ../if_cscope.c:1058
-#, c-format
-msgid "E259: no matches found for cscope query %s of %s"
-msgstr "E259: §ä¤£¨ì²Å¦X cscope ªº·j´M %s / %s"
-
-#: ../if_cscope.c:1142
-msgid "cscope commands:\n"
-msgstr "cscope ©R¥O:\n"
-
-#: ../if_cscope.c:1150
-#, fuzzy, c-format
-msgid "%-5s: %s%*s (Usage: %s)"
-msgstr "%-5s: %-30s (¥Îªk: %s)"
-
-#: ../if_cscope.c:1155
-msgid ""
-"\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 ""
-
-#: ../if_cscope.c:1226
-msgid "E568: duplicate cscope database not added"
-msgstr "E568: ­«½Æªº cscope ¸ê®Æ®w¥¼³Q¥[¤J"
-
-#: ../if_cscope.c:1335
-#, c-format
-msgid "E261: cscope connection %s not found"
-msgstr "E261: §ä¤£¨ì cscope ³s½u %s"
-
-#: ../if_cscope.c:1364
-#, c-format
-msgid "cscope connection %s closed"
-msgstr "cscope ³s½u %s ¤wÃö³¬"
-
-#. should not reach here
-#: ../if_cscope.c:1486
-msgid "E570: fatal error in cs_manage_matches"
-msgstr "E570: cs_manage_matches ÄY­«¿ù»~"
-
-#: ../if_cscope.c:1693
-#, c-format
-msgid "Cscope tag: %s"
-msgstr "Cscope ¼ÐÅÒ(tag): %s"
-
-#: ../if_cscope.c:1711
-msgid ""
-"\n"
-" # line"
-msgstr ""
-"\n"
-" # ¦æ "
-
-#: ../if_cscope.c:1713
-msgid "filename / context / line\n"
-msgstr "ÀɦW / ¤º¤å / ¦æ¸¹\n"
-
-#: ../if_cscope.c:1809
-#, c-format
-msgid "E609: Cscope error: %s"
-msgstr "E609: Csope ¿ù»~: %s"
-
-#: ../if_cscope.c:2053
-msgid "All cscope databases reset"
-msgstr "­«³]©Ò¦³ cscope ¸ê®Æ®w"
-
-#: ../if_cscope.c:2123
-msgid "no cscope connections\n"
-msgstr "¨S¦³ cscope ³s½u\n"
-
-#: ../if_cscope.c:2126
-msgid " # pid database name prepend path\n"
-msgstr " # pid ¸ê®Æ®w¦WºÙ prepend path\n"
-
-#: ../main.c:144
-#, fuzzy
-msgid "Unknown option argument"
-msgstr "¤£¥¿½Tªº¿ï¶µ"
-
-#: ../main.c:146
-msgid "Too many edit arguments"
-msgstr "¤Ó¦h½s¿è°Ñ¼Æ"
-
-#: ../main.c:148
-msgid "Argument missing after"
-msgstr "¯Ê¤Ö¥²­nªº°Ñ¼Æ:"
-
-#: ../main.c:150
-#, fuzzy
-msgid "Garbage after option argument"
-msgstr "µLªk¿ë»{¦¹¿ï¶µ«áªº©R¥O: "
-
-#: ../main.c:152
-msgid "Too many \"+command\", \"-c command\" or \"--cmd command\" arguments"
-msgstr "¤Ó¦h \"+command\" ¡B \"-c command\" ©Î \"--cmd command\" °Ñ¼Æ"
-
-#: ../main.c:154
-msgid "Invalid argument for"
-msgstr "¤£¥¿½Tªº°Ñ¼Æ: "
-
-#: ../main.c:294
-#, c-format
-msgid "%d files to edit\n"
-msgstr "ÁÙ¦³ %d ­ÓÀÉ®×µ¥«Ý½s¿è\n"
-
-#: ../main.c:1342
-msgid "Attempt to open script file again: \""
-msgstr "¸Õ¹Ï¦A¦¸¶}±Ò script ÀÉ: \""
-
-#: ../main.c:1350
-msgid "Cannot open for reading: \""
-msgstr "µLªk¶}±Ò¥HŪ¨ú: \""
-
-#: ../main.c:1393
-msgid "Cannot open for script output: \""
-msgstr "µLªk¶}±Ò¬° script ¿é¥X: \""
-
-#: ../main.c:1622
-msgid "Vim: Warning: Output is not to a terminal\n"
-msgstr "Vim: ª`·N: ¿é¥X¤£¬O²×ºÝ¾÷(¿Ã¹õ)\n"
-
-#: ../main.c:1624
-msgid "Vim: Warning: Input is not from a terminal\n"
-msgstr "Vim: ª`·N: ¿é¤J¤£¬O²×ºÝ¾÷(Áä½L)\n"
-
-#. just in case..
-#: ../main.c:1891
-msgid "pre-vimrc command line"
-msgstr "vimrc «e©R¥O¦C"
-
-#: ../main.c:1964
-#, c-format
-msgid "E282: Cannot read from \"%s\""
-msgstr "E282: µLªkŪ¨úÀÉ®× \"%s\""
-
-#: ../main.c:2149
-msgid ""
-"\n"
-"More info with: \"vim -h\"\n"
-msgstr ""
-"\n"
-"¬d¸ß§ó¦h¸ê°T½Ð°õ¦æ: \"vim -h\"\n"
-
-#: ../main.c:2178
-msgid "[file ..] edit specified file(s)"
-msgstr "[ÀÉ®× ..] ½s¿è«ü©wªºÀÉ®×"
-
-#: ../main.c:2179
-msgid "- read text from stdin"
-msgstr "- ±q¼Ð·Ç¿é¤J(stdin)Ū¨úÀÉ®×"
-
-#: ../main.c:2180
-msgid "-t tag edit file where tag is defined"
-msgstr "-t tag ½s¿è®É¨Ï¥Î«ü©wªº tag"
-
-#: ../main.c:2181
-msgid "-q [errorfile] edit file with first error"
-msgstr "-q [errorfile] ½s¿è®É¸ü¤J²Ä¤@­Ó¿ù»~"
-
-#: ../main.c:2187
-msgid ""
-"\n"
-"\n"
-"usage:"
-msgstr ""
-"\n"
-"\n"
-" ¥Îªk:"
-
-#: ../main.c:2189
-msgid " vim [arguments] "
-msgstr "vim [°Ñ¼Æ] "
-
-#: ../main.c:2193
-msgid ""
-"\n"
-" or:"
-msgstr ""
-"\n"
-" ©Î:"
-
-#: ../main.c:2196
-msgid ""
-"\n"
-"\n"
-"Arguments:\n"
-msgstr ""
-"\n"
-"\n"
-"°Ñ¼Æ:\n"
-
-#: ../main.c:2197
-msgid "--\t\t\tOnly file names after this"
-msgstr "--\t\t\t¥u¦³¦b³o¤§«áªºÀÉ®×"
-
-#: ../main.c:2199
-msgid "--literal\t\tDon't expand wildcards"
-msgstr "--literal\t\t¤£®i¶}¸U¥Î¦r¤¸"
-
-#: ../main.c:2201
-msgid "-v\t\t\tVi mode (like \"vi\")"
-msgstr "-v\t\t\tVi ¼Ò¦¡ (¦P \"vi\")"
-
-#: ../main.c:2202
-msgid "-e\t\t\tEx mode (like \"ex\")"
-msgstr "-e\t\t\tEx ¼Ò¦¡ (¦P \"ex\")"
-
-#: ../main.c:2203
-msgid "-E\t\t\tImproved Ex mode"
-msgstr ""
-
-#: ../main.c:2204
-msgid "-s\t\t\tSilent (batch) mode (only for \"ex\")"
-msgstr "-s\t\t\t¦wÀR (batch) ¼Ò¦¡ (¥u¯à»P \"ex\" ¤@°_¨Ï¥Î)"
-
-#: ../main.c:2205
-msgid "-d\t\t\tDiff mode (like \"vimdiff\")"
-msgstr "-d\t\t\tDiff ¼Ò¦¡ (¦P \"vimdiff\", ¥i¨³³t¤ñ¸û¨âÀɮפ£¦P³B)"
-
-#: ../main.c:2206
-msgid "-y\t\t\tEasy mode (like \"evim\", modeless)"
-msgstr "-y\t\t\t²©ö¼Ò¦¡ (¦P \"evim\", modeless)"
-
-#: ../main.c:2207
-msgid "-R\t\t\tReadonly mode (like \"view\")"
-msgstr "-R\t\t\t°ßŪ¼Ò¦¡ (¦P \"view\")"
-
-#: ../main.c:2208
-msgid "-Z\t\t\tRestricted mode (like \"rvim\")"
-msgstr "-Z\t\t\t­­¨î¼Ò¦¡ (¦P \"rvim\")"
-
-#: ../main.c:2209
-msgid "-m\t\t\tModifications (writing files) not allowed"
-msgstr "-m\t\t\t¤£¥i­×§ï (¼g¤JÀÉ®×)"
-
-#: ../main.c:2210
-msgid "-M\t\t\tModifications in text not allowed"
-msgstr "-M\t\t\t¤£¥i­×§ï¤å¦r"
-
-#: ../main.c:2211
-msgid "-b\t\t\tBinary mode"
-msgstr "-b\t\t\t¤G¶i¦ì¼Ò¦¡"
-
-#: ../main.c:2212
-msgid "-l\t\t\tLisp mode"
-msgstr "-l\t\t\tLisp ¼Ò¦¡"
-
-#: ../main.c:2213
-msgid "-C\t\t\tCompatible with Vi: 'compatible'"
-msgstr "-C\t\t\t'compatible' ¶Ç²Î Vi ¬Û®e¼Ò¦¡"
-
-#: ../main.c:2214
-msgid "-N\t\t\tNot fully Vi compatible: 'nocompatible'"
-msgstr "-N\t\t\t'nocompatible' ¤£§¹¥þ»P¶Ç²Î Vi ¬Û®e¡A¥i¨Ï¥Î Vim ¥[±j¯à¤O"
-
-#: ../main.c:2215
-msgid "-V[N][fname]\t\tBe verbose [level N] [log messages to fname]"
-msgstr ""
-
-#: ../main.c:2216
-msgid "-D\t\t\tDebugging mode"
-msgstr "-D\t\t\t°£¿ù¼Ò¦¡"
-
-#: ../main.c:2217
-msgid "-n\t\t\tNo swap file, use memory only"
-msgstr "-n\t\t\t¤£¨Ï¥Î¼È¦sÀÉ, ¥u¨Ï¥Î°O¾ÐÅé"
-
-#: ../main.c:2218
-msgid "-r\t\t\tList swap files and exit"
-msgstr "-r\t\t\t¦C¥X¼È¦sÀÉ«áÂ÷¶}"
-
-#: ../main.c:2219
-msgid "-r (with file name)\tRecover crashed session"
-msgstr "-r (¥[ÀɦW) \t­×´_¤W¦¸·l·´ªº¸ê®Æ(Recover crashed session)"
-
-#: ../main.c:2220
-msgid "-L\t\t\tSame as -r"
-msgstr "-L\t\t\t¦P -r"
-
-#: ../main.c:2221
-msgid "-A\t\t\tstart in Arabic mode"
-msgstr "-A\t\t\t±Ò°Ê¬° Arabic ¼Ò¦¡"
-
-#: ../main.c:2222
-msgid "-H\t\t\tStart in Hebrew mode"
-msgstr "-H\t\t\t±Ò°Ê¬° Hebrew ¼Ò¦¡"
-
-#: ../main.c:2223
-msgid "-F\t\t\tStart in Farsi mode"
-msgstr "-F\t\t\t±Ò°Ê¬° Farsi ¼Ò¦¡"
-
-#: ../main.c:2224
-msgid "-T <terminal>\tSet terminal type to <terminal>"
-msgstr "-T <terminal>\t³]©w²×ºÝ¾÷¬° <terminal>"
-
-#: ../main.c:2225
-msgid "-u <vimrc>\t\tUse <vimrc> instead of any .vimrc"
-msgstr "-u <vimrc>\t\t¨Ï¥Î <vimrc> ¨ú¥N¥ô¦ó .vimrc"
-
-#: ../main.c:2226
-msgid "--noplugin\t\tDon't load plugin scripts"
-msgstr "--noplugin\t\t¤£¸ü¤J¥ô¦ó plugin"
-
-#: ../main.c:2227
-#, fuzzy
-msgid "-p[N]\t\tOpen N tab pages (default: one for each file)"
-msgstr "-o[N]\t\t¶}±Ò N ­Óµøµ¡ (¹w³]¬O¨C­ÓÀɮפ@­Ó)"
-
-#: ../main.c:2228
-msgid "-o[N]\t\tOpen N windows (default: one for each file)"
-msgstr "-o[N]\t\t¶}±Ò N ­Óµøµ¡ (¹w³]¬O¨C­ÓÀɮפ@­Ó)"
-
-#: ../main.c:2229
-msgid "-O[N]\t\tLike -o but split vertically"
-msgstr "-O[N]\t\t¦P -o ¦ý¨Ï¥Î««ª½¤À³Î"
-
-#: ../main.c:2230
-msgid "+\t\t\tStart at end of file"
-msgstr "+\t\t\t±Ò°Ê«á¸õ¨ìÀÉ®×µ²§À"
-
-#: ../main.c:2231
-msgid "+<lnum>\t\tStart at line <lnum>"
-msgstr "+<lnum>\t\t±Ò°Ê«á¸õ¨ì²Ä <lnum> ¦æ "
-
-#: ../main.c:2232
-msgid "--cmd <command>\tExecute <command> before loading any vimrc file"
-msgstr "--cmd <command>\t¸ü¤J¥ô¦ó vimrc «e°õ¦æ <command>"
-
-#: ../main.c:2233
-msgid "-c <command>\t\tExecute <command> after loading the first file"
-msgstr "-c <command>\t\t¸ü¤J²Ä¤@­ÓÀɮ׫á°õ¦æ <command>"
-
-#: ../main.c:2235
-msgid "-S <session>\t\tSource file <session> after loading the first file"
-msgstr "-S <session>\t\t¸ü¤J²Ä¤@­ÓÀɮ׫á¸ü¤J Session ÀÉ <session>"
-
-#: ../main.c:2236
-msgid "-s <scriptin>\tRead Normal mode commands from file <scriptin>"
-msgstr "-s <scriptin>\t±q <scriptin> Ū¤J¤@¯ë¼Ò¦¡©R¥O"
-
-#: ../main.c:2237
-msgid "-w <scriptout>\tAppend all typed commands to file <scriptout>"
-msgstr "-w <scriptout>\t¹ïÀÉ®× <scriptout> ªþ¥[(append)©Ò¦³¿é¤Jªº©R¥O"
-
-#: ../main.c:2238
-msgid "-W <scriptout>\tWrite all typed commands to file <scriptout>"
-msgstr "-W <scriptout>\t¹ïÀÉ®× <scriptout> ¼g¤J©Ò¦³¿é¤Jªº©R¥O"
-
-#: ../main.c:2240
-msgid "--startuptime <file>\tWrite startup timing messages to <file>"
-msgstr ""
-
-#: ../main.c:2242
-msgid "-i <viminfo>\t\tUse <viminfo> instead of .viminfo"
-msgstr "-i <viminfo>\t\t¨Ï¥Î <viminfo> ¦Ó«D .viminfo"
-
-#: ../main.c:2243
-msgid "-h or --help\tPrint Help (this message) and exit"
-msgstr "-h ©Î --help\t¦L¥X»¡©ú(¤]´N¬O¥»°T®§)«áÂ÷¶}"
-
-#: ../main.c:2244
-msgid "--version\t\tPrint version information and exit"
-msgstr "--version\t\t¦L¥Xª©¥»¸ê°T«áÂ÷¶}"
-
-#: ../mark.c:676
-msgid "No marks set"
-msgstr "¨S¦³³]©w¼Ð°O (mark)"
-
-#: ../mark.c:678
-#, c-format
-msgid "E283: No marks matching \"%s\""
-msgstr "E283: §ä¤£¨ì²Å¦X \"%s\" ªº¼Ð°O(mark)"
-
-#. Highlight title
-#: ../mark.c:687
-msgid ""
-"\n"
-"mark line col file/text"
-msgstr ""
-"\n"
-"¼Ð°O ¦æ¸¹ Äæ ÀÉ®×/¤å¦r"
-
-#. Highlight title
-#: ../mark.c:789
-msgid ""
-"\n"
-" jump line col file/text"
-msgstr ""
-"\n"
-" jump ¦æ¸¹ Äæ ÀÉ®×/¤å¦r"
-
-#. Highlight title
-#: ../mark.c:831
-msgid ""
-"\n"
-"change line col text"
-msgstr ""
-"\n"
-"§ïÅÜ ¦æ¸¹ Äæ ¤å¦r"
-
-#: ../mark.c:1238
-msgid ""
-"\n"
-"# File marks:\n"
-msgstr ""
-"\n"
-"# Àɮ׼аO:\n"
-
-#. Write the jumplist with -'
-#: ../mark.c:1271
-msgid ""
-"\n"
-"# Jumplist (newest first):\n"
-msgstr ""
-"\n"
-"# Jumplist (¥Ñ·s¨ìÂÂ):\n"
-
-#: ../mark.c:1352
-msgid ""
-"\n"
-"# History of marks within files (newest to oldest):\n"
-msgstr ""
-"\n"
-"# Àɮפº Mark °O¿ý (¥Ñ·s¨ìÂÂ):\n"
-
-#: ../mark.c:1431
-msgid "Missing '>'"
-msgstr "¯Ê¤Ö¹ïÀ³ªº '>'"
-
-#: ../memfile.c:426
-msgid "E293: block was not locked"
-msgstr "E293: °Ï¶ô¥¼³QÂê©w"
-
-#: ../memfile.c:799
-msgid "E294: Seek error in swap file read"
-msgstr "E294: ¼È¦sÀÉŪ¨ú¿ù»~"
-
-#: ../memfile.c:803
-msgid "E295: Read error in swap file"
-msgstr "E295: ¼È¦sÀÉŪ¨ú¿ù»~"
-
-#: ../memfile.c:849
-msgid "E296: Seek error in swap file write"
-msgstr "E296: ¼È¦sÀɼg¤J¿ù»~"
-
-#: ../memfile.c:865
-msgid "E297: Write error in swap file"
-msgstr "E297: ¼È¦sÀɼg¤J¿ù»~"
-
-#: ../memfile.c:1036
-msgid "E300: Swap file already exists (symlink attack?)"
-msgstr "E300: ¼È¦sÀɤw¸g¦s¦b! (¤p¤ß²Å¸¹³sµ²ªº¦w¥þº|¬}!?)"
-
-#: ../memline.c:318
-msgid "E298: Didn't get block nr 0?"
-msgstr "E298: §ä¤£¨ì°Ï¶ô 0?"
-
-#: ../memline.c:361
-msgid "E298: Didn't get block nr 1?"
-msgstr "E298: §ä¤£¨ì°Ï¶ô 1?"
-
-#: ../memline.c:377
-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
-msgid "E301: Oops, lost the swap file!!!"
-msgstr "E301: ¾¾¾¾, ¼È¦sÀɤ£¨£¤F!!!"
-
-#: ../memline.c:477
-msgid "E302: Could not rename swap file"
-msgstr "E302: µLªk§ïÅܼȦsÀɪº¦WºÙ"
-
-#: ../memline.c:554
-#, c-format
-msgid "E303: Unable to open swap file for \"%s\", recovery impossible"
-msgstr "E303: µLªk¶}±Ò¼È¦sÀÉ \"%s\", ¤£¥i¯à­×´_¤F"
-
-#: ../memline.c:666
-#, fuzzy
-msgid "E304: ml_upd_block0(): Didn't get block 0??"
-msgstr "E304: ml_timestamp: §ä¤£¨ì°Ï¶ô 0??"
-
-#. no swap files found
-#: ../memline.c:830
-#, c-format
-msgid "E305: No swap file found for %s"
-msgstr "E305: §ä¤£¨ì %s ªº¼È¦sÀÉ"
-
-#: ../memline.c:839
-msgid "Enter number of swap file to use (0 to quit): "
-msgstr "½Ð¿ï¾Ü§A­n¨Ï¥Îªº¼È¦sÀÉ («ö0 Â÷¶}): "
-
-#: ../memline.c:879
-#, c-format
-msgid "E306: Cannot open %s"
-msgstr "E306: µLªk¶}±Ò %s"
-
-#: ../memline.c:897
-msgid "Unable to read block 0 from "
-msgstr "µLªkŪ¨ú°Ï¶ô 0:"
-
-#: ../memline.c:900
-msgid ""
-"\n"
-"Maybe no changes were made or Vim did not update the swap file."
-msgstr ""
-"\n"
-"¥i¯à¬O§A¨S°µ¹L¥ô¦ó­×§ï©Î¬O Vim ÁÙ¨Ó¤£¤Î§ó·s¼È¦sÀÉ."
-
-#: ../memline.c:909
-msgid " cannot be used with this version of Vim.\n"
-msgstr " µLªk¦b¥»ª©¥»ªº Vim ¤¤¨Ï¥Î.\n"
-
-#: ../memline.c:911
-msgid "Use Vim version 3.0.\n"
-msgstr "¨Ï¥Î Vim 3.0¡C\n"
-
-#: ../memline.c:916
-#, c-format
-msgid "E307: %s does not look like a Vim swap file"
-msgstr "E307: %s ¬Ý°_¨Ó¤£¹³¬O Vim ¼È¦sÀÉ"
-
-#: ../memline.c:922
-msgid " cannot be used on this computer.\n"
-msgstr " µLªk¦b³o»O¹q¸£¤W¨Ï¥Î.\n"
-
-#: ../memline.c:924
-msgid "The file was created on "
-msgstr "¥»Àɮ׫إߩó "
-
-#: ../memline.c:928
-msgid ""
-",\n"
-"or the file has been damaged."
-msgstr ""
-",\n"
-"©Î¬O³oÀɮפw¸g·l·´¡C"
-
-#: ../memline.c:945
-msgid " has been damaged (page size is smaller than minimum value).\n"
-msgstr ""
-
-#: ../memline.c:974
-#, c-format
-msgid "Using swap file \"%s\""
-msgstr "¨Ï¥Î¼È¦sÀÉ \"%s\""
-
-#: ../memline.c:980
-#, c-format
-msgid "Original file \"%s\""
-msgstr "­ì©lÀÉ \"%s\""
-
-#: ../memline.c:995
-msgid "E308: Warning: Original file may have been changed"
-msgstr "E308: ĵ§i: ­ì©lÀÉ®×¥i¯à¤w¸g­×§ï¹L¤F"
-
-#: ../memline.c:1061
-#, c-format
-msgid "E309: Unable to read block 1 from %s"
-msgstr "E309: µLªk±q %s Ū¨ú°Ï¶ô 1"
-
-#: ../memline.c:1065
-msgid "???MANY LINES MISSING"
-msgstr "???¯Ê¤Ö¤Ó¦h¦æ "
-
-#: ../memline.c:1076
-msgid "???LINE COUNT WRONG"
-msgstr "???¦æ¸¹¿ù»~"
-
-#: ../memline.c:1082
-msgid "???EMPTY BLOCK"
-msgstr "???ªÅªº BLOCK"
-
-#: ../memline.c:1103
-msgid "???LINES MISSING"
-msgstr "???§ä¤£¨ì¤@¨Ç¦æ "
-
-#: ../memline.c:1128
-#, c-format
-msgid "E310: Block 1 ID wrong (%s not a .swp file?)"
-msgstr "E310: °Ï¶ô 1 ID ¿ù»~ (%s ¤£¬O¼È¦sÀÉ?)"
-
-#: ../memline.c:1133
-msgid "???BLOCK MISSING"
-msgstr "???§ä¤£¨ìBLOCK"
-
-#: ../memline.c:1147
-msgid "??? from here until ???END lines may be messed up"
-msgstr "??? ±q³o¸Ì¨ì ???END ªº¤º®e¥i¯à¦³°ÝÃD"
-
-#: ../memline.c:1164
-msgid "??? from here until ???END lines may have been inserted/deleted"
-msgstr "??? ±q³o¸Ì¨ì ???END ªº¤º®e¥i¯à³Q§R°£/´¡¤J¹L"
-
-# do not translate
-#: ../memline.c:1181
-msgid "???END"
-msgstr "???END"
-
-#: ../memline.c:1238
-msgid "E311: Recovery Interrupted"
-msgstr "E311: ­×´_¤w¤¤Â_"
-
-#: ../memline.c:1243
-msgid ""
-"E312: Errors detected while recovering; look for lines starting with ???"
-msgstr "E312: ­×´_®Éµo¥Í¿ù»~; ½Ðª`·N¶}ÀY¬° ??? ªº¦æ "
-
-#: ../memline.c:1245
-msgid "See \":help E312\" for more information."
-msgstr "¸Ô²Ó»¡©ú½Ð¨£ \":help E312\""
-
-#: ../memline.c:1249
-msgid "Recovery completed. You should check if everything is OK."
-msgstr "´_­ì§¹¦¨. ½Ð½T©w¤@¤Á¥¿±`."
-
-#: ../memline.c:1251
-msgid ""
-"\n"
-"(You might want to write out this file under another name\n"
-msgstr ""
-"\n"
-"(§A¥i¯à·|·Q­n§â³o­ÓÀÉ®×¥t¦s§OªºÀɦW¡A\n"
-
-#: ../memline.c:1252
-#, fuzzy
-msgid "and run diff with the original file to check for changes)"
-msgstr "¦A°õ¦æ diff »P­ìÀɮפñ¸û¥HÀˬd¬O§_¦³§ïÅÜ)\n"
-
-#: ../memline.c:1254
-msgid "Recovery completed. Buffer contents equals file contents."
-msgstr ""
-
-#: ../memline.c:1255
-#, fuzzy
-msgid ""
-"\n"
-"You may want to delete the .swp file now.\n"
-"\n"
-msgstr ""
-"(D)ª½±µ§R°£ .swp ¼È¦sÀÉ\n"
-"\n"
-
-#. use msg() to start the scrolling properly
-#: ../memline.c:1327
-msgid "Swap files found:"
-msgstr "§ä¨ì¥H¤Uªº¼È¦sÀÉ:"
-
-#: ../memline.c:1446
-msgid " In current directory:\n"
-msgstr " ¦b¥Ø«eªº¥Ø¿ý:\n"
-
-#: ../memline.c:1448
-msgid " Using specified name:\n"
-msgstr " Using specified name:\n"
-
-#: ../memline.c:1450
-msgid " In directory "
-msgstr " ¦b¥Ø¿ý "
-
-#: ../memline.c:1465
-msgid " -- none --\n"
-msgstr " -- µL --\n"
-
-#: ../memline.c:1527
-msgid " owned by: "
-msgstr " ¾Ö¦³ªÌ: "
-
-#: ../memline.c:1529
-msgid " dated: "
-msgstr " ¤é´Á: "
-
-#: ../memline.c:1532 ../memline.c:3231
-msgid " dated: "
-msgstr " ¤é´Á: "
-
-#: ../memline.c:1548
-msgid " [from Vim version 3.0]"
-msgstr " [±q Vim ª©¥» 3.0]"
-
-#: ../memline.c:1550
-msgid " [does not look like a Vim swap file]"
-msgstr " [¤£¹³ Vim ªº¼È¦sÀÉ]"
-
-#: ../memline.c:1552
-msgid " file name: "
-msgstr " ÀɦW: "
-
-#: ../memline.c:1558
-msgid ""
-"\n"
-" modified: "
-msgstr ""
-"\n"
-" ­×§ï¹L: "
-
-#: ../memline.c:1559
-msgid "YES"
-msgstr "¬O"
-
-#: ../memline.c:1559
-msgid "no"
-msgstr "§_"
-
-#: ../memline.c:1562
-msgid ""
-"\n"
-" user name: "
-msgstr ""
-"\n"
-" ¨Ï¥ÎªÌ: "
-
-#: ../memline.c:1568
-msgid " host name: "
-msgstr " ¥D¾÷¦WºÙ: "
-
-#: ../memline.c:1570
-msgid ""
-"\n"
-" host name: "
-msgstr ""
-"\n"
-" ¥D¾÷¦WºÙ: "
-
-#: ../memline.c:1575
-msgid ""
-"\n"
-" process ID: "
-msgstr ""
-"\n"
-" process ID: "
-
-#: ../memline.c:1579
-msgid " (still running)"
-msgstr " (°õ¦æ¤¤)"
-
-#: ../memline.c:1586
-msgid ""
-"\n"
-" [not usable on this computer]"
-msgstr ""
-"\n"
-" [µLªk¦b¥»¹q¸£¤W¨Ï¥Î]"
-
-#: ../memline.c:1590
-msgid " [cannot be read]"
-msgstr " [µLªkŪ¨ú]"
-
-#: ../memline.c:1593
-msgid " [cannot be opened]"
-msgstr " [µLªk¶}±Ò]"
-
-#: ../memline.c:1698
-msgid "E313: Cannot preserve, there is no swap file"
-msgstr "E313: µLªk«O¯d, ¤£¨Ï¥Î¼È¦sÀÉ"
-
-#: ../memline.c:1747
-msgid "File preserved"
-msgstr "Àɮפw«O¯d"
-
-#: ../memline.c:1749
-msgid "E314: Preserve failed"
-msgstr "E314: «O¯d¥¢±Ñ"
-
-#: ../memline.c:1819
-#, 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>"
-msgstr "E316: ml_get: §ä¤£¨ì²Ä %<PRId64> ¦æ "
-
-#: ../memline.c:2236
-msgid "E317: pointer block id wrong 3"
-msgstr "E317: «ü¼Ð°Ï¶ô id ¿ù»~ 3"
-
-#: ../memline.c:2311
-msgid "stack_idx should be 0"
-msgstr "stack_idx À³¸Ó¬O 0"
-
-#: ../memline.c:2369
-msgid "E318: Updated too many blocks?"
-msgstr "E318: §ó·s¤Ó¦h°Ï¶ô?"
-
-#: ../memline.c:2511
-msgid "E317: pointer block id wrong 4"
-msgstr "E317: «ü¼Ð°Ï¶ô id ¿ù»~ 4"
-
-#: ../memline.c:2536
-msgid "deleted block 1?"
-msgstr "§R°£°Ï¶ô 1?"
-
-#: ../memline.c:2707
-#, c-format
-msgid "E320: Cannot find line %<PRId64>"
-msgstr "E320: §ä¤£¨ì²Ä %<PRId64> ¦æ "
-
-#: ../memline.c:2916
-msgid "E317: pointer block id wrong"
-msgstr "E317: «ü¼Ð°Ï¶ô id ¿ù»~"
-
-#: ../memline.c:2930
-msgid "pe_line_count is zero"
-msgstr "pe_line_count ¬°¹s"
-
-#: ../memline.c:2955
-#, c-format
-msgid "E322: line number out of range: %<PRId64> past the end"
-msgstr "E322: ¦æ¸¹¶W¥X½d³ò: %<PRId64> ¶W¹Lµ²§À"
-
-#: ../memline.c:2959
-#, c-format
-msgid "E323: line count wrong in block %<PRId64>"
-msgstr "E323: °Ï¶ô %<PRId64> ¦æ¼Æ¿ù»~"
-
-#: ../memline.c:2999
-msgid "Stack size increases"
-msgstr "°ïÅ|¤j¤p¼W¥["
-
-#: ../memline.c:3038
-msgid "E317: pointer block id wrong 2"
-msgstr "E317: «ü¼Ð°Ï¶ô id ¿ù 2"
-
-#: ../memline.c:3070
-#, c-format
-msgid "E773: Symlink loop for \"%s\""
-msgstr ""
-
-#: ../memline.c:3221
-msgid "E325: ATTENTION"
-msgstr "E325: ª`·N"
-
-#: ../memline.c:3222
-msgid ""
-"\n"
-"Found a swap file by the name \""
-msgstr ""
-"\n"
-"§ä¨ì¼È¦sÀÉ \""
-
-#: ../memline.c:3226
-msgid "While opening file \""
-msgstr "¦b¶}±ÒÀÉ®× \""
-
-#: ../memline.c:3239
-msgid " NEWER than swap file!\n"
-msgstr " ¤ñ¼È¦sÀɧó·s!\n"
-
-#: ../memline.c:3244
-#, fuzzy
-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."
-msgstr ""
-"\n"
-"(1) ¥i¯à¦³¥t¤@­Óµ{¦¡¤]¦b½s¿è¦P¤@­ÓÀÉ®×.\n"
-" ¦pªG¬O³o¼Ë¡A½Ð¤p¤ß¤£­n¨âÃä¤@°_¼g¤J¡A¤£µM§Aªº§V¤O³£·|­t½Ñ¬y¤ô¡C\n"
-
-#: ../memline.c:3245
-#, fuzzy
-msgid " Quit, or continue with caution.\n"
-msgstr " Â÷¶}¡A©Î¬OÄ~Äò½s¿è¡C\n"
-
-#: ../memline.c:3246
-#, fuzzy
-msgid "(2) An edit session for this file crashed.\n"
-msgstr ""
-"\n"
-"(2) «e¦¸½s¿è¦¹Àɮɷí¾÷\n"
-
-#: ../memline.c:3247
-msgid " If this is the case, use \":recover\" or \"vim -r "
-msgstr " ¦pªG¬O³o¼Ë, ½Ð¥Î \":recover\" ©Î \"vim -r"
-
-#: ../memline.c:3249
-msgid ""
-"\"\n"
-" to recover the changes (see \":help recovery\").\n"
-msgstr ""
-"\"\n"
-" ¨Ó±Ï¦^­×§ï¸ê®Æ (¸Ô²Ó»¡©ú½Ð¬Ý \":help recovery\").\n"
-
-#: ../memline.c:3250
-msgid " If you did this already, delete the swap file \""
-msgstr " ¦pªG¸Ó±Ïªº³£¤w¸g±Ï¤F, ½Ðª½±µ§R°£¦¹¼È¦sÀÉ \""
-
-#: ../memline.c:3252
-msgid ""
-"\"\n"
-" to avoid this message.\n"
-msgstr ""
-"\"\n"
-" ¥HÁ×§K¦A¬Ý¨ì¦¹°T®§.\n"
-
-#: ../memline.c:3450 ../memline.c:3452
-msgid "Swap file \""
-msgstr "¼È¦sÀÉ \""
-
-#: ../memline.c:3451 ../memline.c:3455
-msgid "\" already exists!"
-msgstr "\" ¤w¸g¦s¦b¤F!"
-
-#: ../memline.c:3457
-msgid "VIM - ATTENTION"
-msgstr "VIM - ª`·N"
-
-#: ../memline.c:3459
-msgid "Swap file already exists!"
-msgstr "¼È¦sÀɤw¸g¦s¦b!"
-
-#: ../memline.c:3464
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"¥H°ßŪ¤è¦¡¶}±Ò(&O)\n"
-"ª½±µ½s¿è(&E)\n"
-"­×´_(&R)\n"
-"Â÷¶}(&Q)\n"
-"¸õ¥X(&A)"
-
-#: ../memline.c:3467
-#, fuzzy
-msgid ""
-"&Open Read-Only\n"
-"&Edit anyway\n"
-"&Recover\n"
-"&Delete it\n"
-"&Quit\n"
-"&Abort"
-msgstr ""
-"¥H°ßŪ¤è¦¡¶}±Ò(&O)\n"
-"ª½±µ½s¿è(&E)\n"
-"­×´_(&R)\n"
-"Â÷¶}(&Q)\n"
-"¸õ¥X(&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.
-#.
-#. ".s?a"
-#. ".saa": tried enough, give up
-#: ../memline.c:3528
-msgid "E326: Too many swap files found"
-msgstr "E326: §ä¨ì¤Ó¦h¼È¦sÀÉ"
-
-#: ../memory.c:227
-#, c-format
-msgid "E342: Out of memory! (allocating %<PRIu64> bytes)"
-msgstr "E342: °O¾ÐÅ餣¨¬! (¹Á¸Õ°t¸m %<PRIu64> ¦ì¤¸²Õ)"
-
-#: ../menu.c:62
-msgid "E327: Part of menu-item path is not sub-menu"
-msgstr "E327: ³¡¥÷¿ï¶µ¸ô®|¤£¬O¤l¿ï³æ"
-
-#: ../menu.c:63
-msgid "E328: Menu only exists in another mode"
-msgstr "E328: ¿ï³æ¥u¯à¦b¨ä¥¦¼Ò¦¡¤¤¨Ï¥Î"
-
-#: ../menu.c:64
-#, fuzzy, c-format
-msgid "E329: No menu \"%s\""
-msgstr "E329: ¨S¦³¨º¼Ëªº¿ï³æ"
-
-#. Only a mnemonic or accelerator is not valid.
-#: ../menu.c:329
-msgid "E792: Empty menu name"
-msgstr ""
-
-#: ../menu.c:340
-msgid "E330: Menu path must not lead to a sub-menu"
-msgstr "E330: ¿ï³æ¸ô®|¤£¯à«ü¦V¤l¿ï³æ"
-
-#: ../menu.c:365
-msgid "E331: Must not add menu items directly to menu bar"
-msgstr "E331: ¤£¯àª½±µ§â¿ï¶µ¥[¨ì¿ï³æ¦C¤¤"
-
-#: ../menu.c:370
-msgid "E332: Separator cannot be part of a menu path"
-msgstr "E332: ¤À¹j½u¤£¯à¬O¿ï³æ¸ô®|ªº¤@³¡¥÷"
-
-#. Now we have found the matching menu, and we list the mappings
-#. Highlight title
-#: ../menu.c:762
-msgid ""
-"\n"
-"--- Menus ---"
-msgstr ""
-"\n"
-"--- ¿ï³æ ---"
-
-#: ../menu.c:1313
-msgid "E333: Menu path must lead to a menu item"
-msgstr "E333: ¿ï³æ¸ô®|¥²»Ý«ü¦V¤@­Ó¿ï¶µ"
-
-#: ../menu.c:1330
-#, 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 ¼Ò¦¡¥¼©w¸q¿ï³æ"
-
-#: ../menu.c:1426
-msgid "E336: Menu path must lead to a sub-menu"
-msgstr "E336: ¿ï³æ¸ô®|¥²»Ý«ü¦V¤l¿ï³æ"
-
-#: ../menu.c:1447
-msgid "E337: Menu not found - check menu names"
-msgstr "E337: §ä¤£¨ì¿ï³æ - ½ÐÀˬd¿ï³æ¦WºÙ"
-
-#: ../message.c:423
-#, c-format
-msgid "Error detected while processing %s:"
-msgstr "³B²z %s ®Éµo¥Í¿ù»~:"
-
-#: ../message.c:445
-#, c-format
-msgid "line %4ld:"
-msgstr "¦æ %4ld:"
-
-#: ../message.c:617
-#, c-format
-msgid "E354: Invalid register name: '%s'"
-msgstr "E354: ¼È¦s¾¹¦WºÙ¿ù»~: '%s'"
-
-#: ../message.c:745
-msgid "Messages maintainer: Bram Moolenaar <Bram@vim.org>"
-msgstr ""
-"¥¿Å餤¤å°T®§ºûÅ@ªÌ: Francis S.Lin <piaip@csie.ntu.edu."
-"tw>, Cecil Sheng <b7506022@csie.ntu.edu.tw>"
-
-#: ../message.c:986
-msgid "Interrupt: "
-msgstr "¤w¤¤Â_: "
-
-#: ../message.c:988
-#, fuzzy
-msgid "Press ENTER or type command to continue"
-msgstr "½Ð«ö ENTER ©Î¨ä¥¦©R¥O¥HÄ~Äò"
-
-#: ../message.c:1843
-#, fuzzy, c-format
-msgid "%s line %<PRId64>"
-msgstr "%s, ¦æ %<PRId64>"
-
-#: ../message.c:2392
-msgid "-- More --"
-msgstr "-- ©|¦³ --"
-
-#: ../message.c:2398
-msgid " SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "
-msgstr ""
-
-#: ../message.c:3021 ../message.c:3031
-msgid "Question"
-msgstr "°ÝÃD"
-
-#: ../message.c:3023
-msgid ""
-"&Yes\n"
-"&No"
-msgstr ""
-"&Y¬O\n"
-"&N§_"
-
-#: ../message.c:3033
-msgid ""
-"&Yes\n"
-"&No\n"
-"&Cancel"
-msgstr ""
-"&Y¬O\n"
-"&N§_\n"
-"&C¨ú®ø"
-
-#: ../message.c:3045
-msgid ""
-"&Yes\n"
-"&No\n"
-"Save &All\n"
-"&Discard All\n"
-"&Cancel"
-msgstr ""
-"&Y¬O\n"
-"&N§_\n"
-"&A¥þ³¡¦sÀÉ\n"
-"&D¥þ³¡¤£¦s\n"
-"&C¨ú®ø"
-
-#: ../message.c:3058
-#, fuzzy
-msgid "E766: Insufficient arguments for printf()"
-msgstr "E116: ¨ç¦¡ %s ªº¤Þ¼Æ¤£¥¿½T"
-
-#: ../message.c:3119
-msgid "E807: Expected Float argument for printf()"
-msgstr ""
-
-#: ../message.c:3873
-#, fuzzy
-msgid "E767: Too many arguments to printf()"
-msgstr "E118: ¨ç¦¡ %s ªº¤Þ¼Æ¹L¦h"
-
-#: ../misc1.c:2256
-msgid "W10: Warning: Changing a readonly file"
-msgstr "W10: ª`·N: §A¥¿¦b­×§ï¤@­Ó°ßŪÀÉ"
-
-#: ../misc1.c:2537
-msgid "Type number and <Enter> or click with mouse (empty cancels): "
-msgstr ""
-
-#: ../misc1.c:2539
-msgid "Type number and <Enter> (empty cancels): "
-msgstr ""
-
-#: ../misc1.c:2585
-msgid "1 more line"
-msgstr "ÁÙ¦³¤@¦æ "
-
-#: ../misc1.c:2588
-msgid "1 line less"
-msgstr "¤Ö©ó¤@¦æ "
-
-#: ../misc1.c:2593
-#, c-format
-msgid "%<PRId64> more lines"
-msgstr "ÁÙ¦³ %<PRId64> ¦æ "
-
-#: ../misc1.c:2596
-#, c-format
-msgid "%<PRId64> fewer lines"
-msgstr "¥u³Ñ %<PRId64> ¦æ "
-
-#: ../misc1.c:2599
-msgid " (Interrupted)"
-msgstr " (¤w¤¤Â_)"
-
-#: ../misc1.c:2635
-msgid "Beep!"
-msgstr ""
-
-#: ../misc2.c:738
-#, c-format
-msgid "Calling shell to execute: \"%s\""
-msgstr "©I¥s shell °õ¦æ: \"%s\""
-
-#: ../normal.c:183
-msgid "E349: No identifier under cursor"
-msgstr "E349: ´å¼Ð³B¨S¦³ÃѧO¦r"
-
-#: ../normal.c:1866
-#, fuzzy
-msgid "E774: 'operatorfunc' is empty"
-msgstr "E221: ¿ï¶µ 'commentstring' ¥¼³]©w"
-
-#: ../normal.c:2637
-msgid "Warning: terminal cannot highlight"
-msgstr "ª`·N: §Aªº²×ºÝ¾÷µLªkÅã¥Ü°ª«G«×"
-
-#: ../normal.c:2807
-msgid "E348: No string under cursor"
-msgstr "E348: ´å¼Ð³B¨S¦³¦r¦ê"
-
-#: ../normal.c:3937
-msgid "E352: Cannot erase folds with current 'foldmethod'"
-msgstr "E352: µLªk¦b¥Ø«eªº 'foldmethod' ¤U§R°£ fold"
-
-#: ../normal.c:5897
-msgid "E664: changelist is empty"
-msgstr "E664: Åܧó¦Cªí¬OªÅªº"
-
-#: ../normal.c:5899
-msgid "E662: At start of changelist"
-msgstr "E662: ¤w¦bÅܧó¦Cªíªº¶}ÀY"
-
-#: ../normal.c:5901
-msgid "E663: At end of changelist"
-msgstr "E663: ¤w¦bÅܧó¦Cªíªºµ²§À"
-
-#: ../normal.c:7053
-msgid "Type :quit<Enter> to exit Nvim"
-msgstr "­nÂ÷¶} Vim ½Ð¿é¤J :quit<Enter> "
-
-#: ../ops.c:248
-#, c-format
-msgid "1 line %sed 1 time"
-msgstr "¤@¦æ %s ¹L ¤@¦¸"
-
-#: ../ops.c:250
-#, c-format
-msgid "1 line %sed %d times"
-msgstr "¤@¦æ %s ¹L %d ¦¸"
-
-#: ../ops.c:253
-#, c-format
-msgid "%<PRId64> lines %sed 1 time"
-msgstr "%<PRId64> ¦æ %s ¹L ¤@¦¸"
-
-#: ../ops.c:256
-#, c-format
-msgid "%<PRId64> lines %sed %d times"
-msgstr "%<PRId64> ¦æ %s ¹L %d ¦¸"
-
-#: ../ops.c:592
-#, c-format
-msgid "%<PRId64> lines to indent... "
-msgstr "ÁY±Æ %<PRId64> ¦æ... "
-
-#: ../ops.c:634
-msgid "1 line indented "
-msgstr "¤@¦æ¤wÁY±Æ"
-
-#: ../ops.c:636
-#, c-format
-msgid "%<PRId64> lines indented "
-msgstr "¤wÁY±Æ %<PRId64> ¦æ "
-
-#: ../ops.c:938
-#, fuzzy
-msgid "E748: No previously used register"
-msgstr "E186: ¨S¦³«e¤@­Ó¥Ø¿ý"
-
-#. must display the prompt
-#: ../ops.c:1433
-msgid "cannot yank; delete anyway"
-msgstr "µLªk°Å¤U; ª½±µ§R°£"
-
-#: ../ops.c:1929
-msgid "1 line changed"
-msgstr " 1 ¦æ ~ed"
-
-#: ../ops.c:1931
-#, c-format
-msgid "%<PRId64> lines changed"
-msgstr "¤w§ïÅÜ %<PRId64> ¦æ "
-
-#: ../ops.c:2521
-#, fuzzy
-msgid "block of 1 line yanked"
-msgstr "¤w½Æ»s 1 ¦æ "
-
-#: ../ops.c:2523
-msgid "1 line yanked"
-msgstr "¤w½Æ»s 1 ¦æ "
-
-#: ../ops.c:2525
-#, fuzzy, c-format
-msgid "block of %<PRId64> lines yanked"
-msgstr "¤w½Æ»s %<PRId64> ¦æ "
-
-#: ../ops.c:2528
-#, c-format
-msgid "%<PRId64> lines yanked"
-msgstr "¤w½Æ»s %<PRId64> ¦æ "
-
-#: ../ops.c:2710
-#, c-format
-msgid "E353: Nothing in register %s"
-msgstr "E353: ¼È¦s¾¹ %s ¸Ì¨S¦³ªF¦è"
-
-#. Highlight title
-#: ../ops.c:3185
-msgid ""
-"\n"
-"--- Registers ---"
-msgstr ""
-"\n"
-"--- ¼È¦s¾¹ ---"
-
-#: ../ops.c:4455
-msgid "Illegal register name"
-msgstr "¤£¥¿½Tªº¼È¦s¾¹¦WºÙ"
-
-#: ../ops.c:4533
-msgid ""
-"\n"
-"# Registers:\n"
-msgstr ""
-"\n"
-"# ¼È¦s¾¹:\n"
-
-#: ../ops.c:4575
-#, c-format
-msgid "E574: Unknown register type %d"
-msgstr "E574: ¥¼ª¾ªºµù¥U«¬ºA: %d"
-
-#: ../ops.c:5089
-#, c-format
-msgid "%<PRId64> Cols; "
-msgstr "%<PRId64> Äæ; "
-
-#: ../ops.c:5097
-#, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"¿ï¾Ü¤F %s%<PRId64>/%<PRId64> ¦æ; %<PRId64>/%<PRId64> ¦r(Word); %<PRId64>/"
-"%<PRId64> ¦r¤¸(Bytes)"
-
-#: ../ops.c:5105
-#, fuzzy, c-format
-msgid ""
-"Selected %s%<PRId64> of %<PRId64> Lines; %<PRId64> of %<PRId64> Words; "
-"%<PRId64> of %<PRId64> Chars; %<PRId64> of %<PRId64> Bytes"
-msgstr ""
-"¿ï¾Ü¤F %s%<PRId64>/%<PRId64> ¦æ; %<PRId64>/%<PRId64> ¦r(Word); %<PRId64>/"
-"%<PRId64> ¦r¤¸(Bytes)"
-
-#: ../ops.c:5123
-#, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Byte "
-"%<PRId64> of %<PRId64>"
-msgstr ""
-"Äæ %s/%s; ¦æ %<PRId64>/%<PRId64>; ¦r(Word) %<PRId64>/%<PRId64>; ¦r¤¸(Byte) "
-"%<PRId64>/%<PRId64>"
-
-#: ../ops.c:5133
-#, fuzzy, c-format
-msgid ""
-"Col %s of %s; Line %<PRId64> of %<PRId64>; Word %<PRId64> of %<PRId64>; Char "
-"%<PRId64> of %<PRId64>; Byte %<PRId64> of %<PRId64>"
-msgstr ""
-"Äæ %s/%s; ¦æ %<PRId64>/%<PRId64>; ¦r(Word) %<PRId64>/%<PRId64>; ¦r¤¸(Byte) "
-"%<PRId64>/%<PRId64>"
-
-#: ../ops.c:5146
-#, c-format
-msgid "(+%<PRId64> for BOM)"
-msgstr "(+%<PRId64> for BOM)"
-
-#: ../option.c:1238
-msgid "%<%f%h%m%=Page %N"
-msgstr "%<%f%h%m%=²Ä %N ­¶"
-
-# ? what's this for?
-#: ../option.c:1574
-msgid "Thanks for flying Vim"
-msgstr "·PÁ±z·R¥Î Vim"
-
-#. found a mismatch: skip
-#: ../option.c:2698
-msgid "E518: Unknown option"
-msgstr "E518: ¤£¥¿½Tªº¿ï¶µ"
-
-#: ../option.c:2709
-msgid "E519: Option not supported"
-msgstr "E519: ¤£¤ä´©¸Ó¿ï¶µ"
-
-#: ../option.c:2740
-msgid "E520: Not allowed in a modeline"
-msgstr "E520: ¤£¯à¦b Modeline ¸Ì¥X²{"
-
-#: ../option.c:2815
-msgid "E846: Key code not set"
-msgstr ""
-
-#: ../option.c:2924
-msgid "E521: Number required after ="
-msgstr "E521: = «á»Ý­n¦³¼Æ¦r"
-
-#: ../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: ¤£¥¿½Tªº¦r¤¸ <%s>"
-
-#: ../option.c:3862
-msgid "E529: Cannot set 'term' to empty string"
-msgstr "E529: µLªk³]©w 'term' ¬°ªÅ¦r¦ê"
-
-#: ../option.c:3885
-msgid "E589: 'backupext' and 'patchmode' are equal"
-msgstr "E589: 'backupext' ¸ò 'patchmode' ¬O¤@¼Ëªº"
-
-#: ../option.c:3964
-msgid "E834: Conflicts with value of 'listchars'"
-msgstr ""
-
-#: ../option.c:3966
-msgid "E835: Conflicts with value of 'fillchars'"
-msgstr ""
-
-#: ../option.c:4163
-msgid "E524: Missing colon"
-msgstr "E524: ¯Ê¤Ö colon"
-
-#: ../option.c:4165
-msgid "E525: Zero length string"
-msgstr "E525: ¹sªø«×¦r¦ê"
-
-#: ../option.c:4220
-#, c-format
-msgid "E526: Missing number after <%s>"
-msgstr "E526: <%s> «á¯Ê¤Ö¼Æ¦r"
-
-#: ../option.c:4232
-msgid "E527: Missing comma"
-msgstr "E527: ¯Ê¤Ö³r¸¹"
-
-#: ../option.c:4239
-msgid "E528: Must specify a ' value"
-msgstr "E528: ¥²»Ý«ü©w¤@­Ó ' ­È"
-
-#: ../option.c:4271
-msgid "E595: contains unprintable or wide character"
-msgstr "E595: ¤º§tµLªkÅã¥Üªº¦r¤¸"
-
-#: ../option.c:4469
-#, c-format
-msgid "E535: Illegal character after <%c>"
-msgstr "E535: <%c> «á¦³¤£¥¿½Tªº¦r¤¸"
-
-#: ../option.c:4534
-msgid "E536: comma required"
-msgstr "E536: »Ý­n³r¸¹"
-
-#: ../option.c:4543
-#, c-format
-msgid "E537: 'commentstring' must be empty or contain %s"
-msgstr "E537: 'commentstring' ¥²»Ý¬OªÅ¥Õ©Î¥]§t %s"
-
-#: ../option.c:4928
-msgid "E540: Unclosed expression sequence"
-msgstr "E540: ¨S¦³µ²§ôªº¹Bºâ¦¡: "
-
-#: ../option.c:4932
-msgid "E541: too many items"
-msgstr "E541: ¤Ó¦h¶µ¥Ø"
-
-#: ../option.c:4934
-msgid "E542: unbalanced groups"
-msgstr "E542: ¤£¹ïºÙªº group"
-
-#: ../option.c:5148
-msgid "E590: A preview window already exists"
-msgstr "E590: ¹wµøªºµøµ¡¤w¸g¦s¦b¤F"
-
-#: ../option.c:5311
-msgid "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"
-msgstr "W17: Arabic »Ý­n UTF-8, ½Ð°õ¦æ ':set encoding=utf-8'"
-
-#: ../option.c:5623
-#, c-format
-msgid "E593: Need at least %d lines"
-msgstr "E593: ¦Ü¤Ö»Ý­n %d ¦æ "
-
-#: ../option.c:5631
-#, c-format
-msgid "E594: Need at least %d columns"
-msgstr "E594: ¦Ü¤Ö»Ý­n %d Äæ"
-
-#: ../option.c:6011
-#, c-format
-msgid "E355: Unknown option: %s"
-msgstr "E355: ¤£¥¿½Tªº¿ï¶µ: %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
-msgid "E521: Number required: &%s = '%s'"
-msgstr "E521: = «á»Ý­n¦³¼Æ¦r"
-
-#: ../option.c:6149
-msgid ""
-"\n"
-"--- Terminal codes ---"
-msgstr ""
-"\n"
-"--- ²×ºÝ¾÷½X ---"
-
-#: ../option.c:6151
-msgid ""
-"\n"
-"--- Global option values ---"
-msgstr ""
-"\n"
-"--- Global ¿ï¶µ­È ---"
-
-#: ../option.c:6153
-msgid ""
-"\n"
-"--- Local option values ---"
-msgstr ""
-"\n"
-"--- Local ¿ï¶µ­È ---"
-
-#: ../option.c:6155
-msgid ""
-"\n"
-"--- Options ---"
-msgstr ""
-"\n"
-"--- ¿ï¶µ ---"
-
-#: ../option.c:6816
-msgid "E356: get_varp ERROR"
-msgstr "E356: get_varp ¿ù»~"
-
-#: ../option.c:7696
-#, c-format
-msgid "E357: 'langmap': Matching character missing for %s"
-msgstr "E357: 'langmap': §ä¤£¨ì %s ¹ïÀ³ªº¦r¤¸"
-
-#: ../option.c:7715
-#, c-format
-msgid "E358: 'langmap': Extra characters after semicolon: %s"
-msgstr "E358: 'langmap': ¤À¸¹«á¦³¦h¾lªº¦r¤¸: %s"
-
-#: ../os/shell.c:194
-msgid ""
-"\n"
-"Cannot execute shell "
-msgstr ""
-"\n"
-"¤£¯à°õ¦æ shell"
-
-#: ../os/shell.c:439
-msgid ""
-"\n"
-"shell returned "
-msgstr ""
-"\n"
-"Shell ¤wªð¦^"
-
-#: ../os_unix.c:465 ../os_unix.c:471
-msgid ""
-"\n"
-"Could not get security context for "
-msgstr ""
-
-#: ../os_unix.c:479
-msgid ""
-"\n"
-"Could not set security context for "
-msgstr ""
-
-#: ../os_unix.c:1558 ../os_unix.c:1647
-#, c-format
-msgid "dlerror = \"%s\""
-msgstr ""
-
-#: ../path.c:1449
-#, c-format
-msgid "E447: Can't find file \"%s\" in path"
-msgstr "E447: ¦b¸ô®|¤¤§ä¤£¨ìÀÉ®× \"%s\""
-
-#: ../quickfix.c:359
-#, c-format
-msgid "E372: Too many %%%c in format string"
-msgstr "E372: ®æ¦¡¤Æ¦r¦ê¸Ì¦³¤Ó¦h %%%c "
-
-#: ../quickfix.c:371
-#, c-format
-msgid "E373: Unexpected %%%c in format string"
-msgstr "E373: ®æ¦¡¤Æ¦r¦ê¤£À³¸Ó¥X²{ %%%c "
-
-#: ../quickfix.c:420
-msgid "E374: Missing ] in format string"
-msgstr "E374: ®æ¦¡¤Æ¦r¦ê¸Ì¤Ö¤F ]"
-
-#: ../quickfix.c:431
-#, c-format
-msgid "E375: Unsupported %%%c in format string"
-msgstr "E375: ®æ¦¡¤Æ¦r¦ê¸Ì¦³¤£¤ä´©ªº %%%c "
-
-#: ../quickfix.c:448
-#, c-format
-msgid "E376: Invalid %%%c in format string prefix"
-msgstr "E376: ®æ¦¡¤Æ¦r¦ê¶}ÀY¸Ì¦³¤£¥¿½Tªº %%%c "
-
-#: ../quickfix.c:454
-#, c-format
-msgid "E377: Invalid %%%c in format string"
-msgstr "E377: ®æ¦¡¤Æ¦r¦ê¸Ì¦³¤£¥¿½Tªº %%%c "
-
-#. nothing found
-#: ../quickfix.c:477
-msgid "E378: 'errorformat' contains no pattern"
-msgstr "E378: 'errorformat' ¥¼³]©w"
-
-#: ../quickfix.c:695
-msgid "E379: Missing or empty directory name"
-msgstr "E379: §ä¤£¨ì¥Ø¿ý¦WºÙ©Î¬OªÅªº¥Ø¿ý¦WºÙ"
-
-#: ../quickfix.c:1305
-msgid "E553: No more items"
-msgstr "E553: ¨S¦³¨ä¥¦¶µ¥Ø"
-
-#: ../quickfix.c:1674
-#, c-format
-msgid "(%d of %d)%s%s: "
-msgstr "(%d / %d)%s%s: "
-
-#: ../quickfix.c:1676
-msgid " (line deleted)"
-msgstr " (¦æ¤w§R°£)"
-
-#: ../quickfix.c:1863
-msgid "E380: At bottom of quickfix stack"
-msgstr "E380: Quickfix °ïÅ|µ²§À"
-
-#: ../quickfix.c:1869
-msgid "E381: At top of quickfix stack"
-msgstr "E381: Quickfix °ïÅ|³»ºÝ"
-
-#: ../quickfix.c:1880
-#, c-format
-msgid "error list %d of %d; %d errors"
-msgstr "¿ù»~¦Cªí %d/%d; ¦@¦³ %d ¶µ¿ù»~"
-
-#: ../quickfix.c:2427
-msgid "E382: Cannot write, 'buftype' option is set"
-msgstr "E382: µLªk¼g¤J¡A'buftype' ¿ï¶µ¤w³]©w"
-
-#: ../quickfix.c:2812
-msgid "E683: File name missing or invalid pattern"
-msgstr ""
-
-#: ../quickfix.c:2911
-#, fuzzy, c-format
-msgid "Cannot open file \"%s\""
-msgstr "µLªk¶}±ÒÀÉ®× %s"
-
-#: ../quickfix.c:3429
-#, fuzzy
-msgid "E681: Buffer is not loaded"
-msgstr "¤wÄÀ©ñ¤@­Ó½w½Ä°Ï"
-
-#: ../quickfix.c:3487
-#, fuzzy
-msgid "E777: String or List expected"
-msgstr "E548: À³¸Ó­n¦³¼Æ¦r"
-
-#: ../regexp.c:359
-#, c-format
-msgid "E369: invalid item in %s%%[]"
-msgstr "E369: ¤£¥¿½Tªº¶µ¥Ø¡G %s%%[]"
-
-#: ../regexp.c:374
-#, fuzzy, c-format
-msgid "E769: Missing ] after %s["
-msgstr "E69: %s%%[ «á¯Ê¤Ö ]"
-
-#: ../regexp.c:375
-#, c-format
-msgid "E53: Unmatched %s%%("
-msgstr "E53: µL¹ïÀ³ªº %s%%("
-
-#: ../regexp.c:376
-#, c-format
-msgid "E54: Unmatched %s("
-msgstr "E54: µL¹ïÀ³ªº %s("
-
-#: ../regexp.c:377
-#, c-format
-msgid "E55: Unmatched %s)"
-msgstr "E55: µL¹ïÀ³ªº %s)"
-
-#: ../regexp.c:378
-msgid "E66: \\z( not allowed here"
-msgstr "E66: \\z( ¤£¯à¦b¦¹¥X²{"
-
-#: ../regexp.c:379
-msgid "E67: \\z1 et al. not allowed here"
-msgstr "E67: \\z1 et al. ¤£¯à¦b¦¹¥X²{"
-
-#: ../regexp.c:380
-#, c-format
-msgid "E69: Missing ] after %s%%["
-msgstr "E69: %s%%[ «á¯Ê¤Ö ]"
-
-#: ../regexp.c:381
-#, c-format
-msgid "E70: Empty %s%%[]"
-msgstr "E70: ªÅªº %s%%[]"
-
-#: ../regexp.c:1209 ../regexp.c:1224
-msgid "E339: Pattern too long"
-msgstr "E339: ¦W¦r¤Óªø"
-
-#: ../regexp.c:1371
-msgid "E50: Too many \\z("
-msgstr "E50: ¤Ó¦h \\z("
-
-#: ../regexp.c:1378
-#, c-format
-msgid "E51: Too many %s("
-msgstr "E51: ¤Ó¦h %s("
-
-#: ../regexp.c:1427
-msgid "E52: Unmatched \\z("
-msgstr "E52: µL¹ïÀ³ªº \\z("
-
-#: ../regexp.c:1637
-#, c-format
-msgid "E59: invalid character after %s@"
-msgstr "E59: «á­±¦³¤£¥¿½Tªº¦r¤¸: %s@"
-
-#: ../regexp.c:1672
-#, c-format
-msgid "E60: Too many complex %s{...}s"
-msgstr "E60: ¤Ó¦h½ÆÂøªº %s{...}s"
-
-#: ../regexp.c:1687
-#, c-format
-msgid "E61: Nested %s*"
-msgstr "E61: ±_ª¬ %s*"
-
-#: ../regexp.c:1690
-#, c-format
-msgid "E62: Nested %s%c"
-msgstr "E62: ±_ª¬ %s%c"
-
-#: ../regexp.c:1800
-msgid "E63: invalid use of \\_"
-msgstr "E63: ¤£¥¿½Tªº¨Ï¥Î \\_"
-
-#: ../regexp.c:1850
-#, c-format
-msgid "E64: %s%c follows nothing"
-msgstr "E64: %s%c ¨S¦³±µªF¦è"
-
-#: ../regexp.c:1902
-msgid "E65: Illegal back reference"
-msgstr "E65: ¤£¥¿½Tªº¤Ï¦V°Ñ¦Ò"
-
-#: ../regexp.c:1943
-msgid "E68: Invalid character after \\z"
-msgstr "E68: «á­±¦³¤£¥¿½Tªº¦r¤¸: \\z"
-
-#: ../regexp.c:2049 ../regexp_nfa.c:1296
-#, fuzzy, c-format
-msgid "E678: Invalid character after %s%%[dxouU]"
-msgstr "E71: «á­±¦³¤£¥¿½Tªº¦r¤¸: %s%%"
-
-#: ../regexp.c:2107
-#, c-format
-msgid "E71: Invalid character after %s%%"
-msgstr "E71: «á­±¦³¤£¥¿½Tªº¦r¤¸: %s%%"
-
-#: ../regexp.c:3017
-#, c-format
-msgid "E554: Syntax error in %s{...}"
-msgstr "E554: »yªk¿ù»~: %s{...}"
-
-#: ../regexp.c:3805
-msgid "External submatches:\n"
-msgstr "¥~³¡²Å¦X:\n"
-
-#: ../regexp.c:7022
-msgid ""
-"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
-"used "
-msgstr ""
-
-#: ../regexp_nfa.c:239
-msgid "E865: (NFA) Regexp end encountered prematurely"
-msgstr ""
-
-#: ../regexp_nfa.c:240
-#, c-format
-msgid "E866: (NFA regexp) Misplaced %c"
-msgstr ""
-
-#: ../regexp_nfa.c:242
-#, c-format
-msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
-
-#: ../regexp_nfa.c:1261
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\z%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1387
-#, c-format
-msgid "E867: (NFA) Unknown operator '\\%%%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1802
-#, c-format
-msgid "E869: (NFA) Unknown operator '\\@%c'"
-msgstr ""
-
-#: ../regexp_nfa.c:1831
-msgid "E870: (NFA regexp) Error reading repetition limits"
-msgstr ""
-
-#. 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 ""
-
-#. Too many `('
-#: ../regexp_nfa.c:2037
-msgid "E872: (NFA regexp) Too many '('"
-msgstr ""
-
-#: ../regexp_nfa.c:2042
-#, fuzzy
-msgid "E879: (NFA regexp) Too many \\z("
-msgstr "E50: ¤Ó¦h \\z("
-
-#: ../regexp_nfa.c:2066
-msgid "E873: (NFA regexp) proper termination error"
-msgstr ""
-
-#: ../regexp_nfa.c:2599
-msgid "E874: (NFA) Could not pop the stack !"
-msgstr ""
-
-#: ../regexp_nfa.c:3298
-msgid ""
-"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
-"left on stack"
-msgstr ""
-
-#: ../regexp_nfa.c:3302
-msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
-msgstr ""
-
-#: ../regexp_nfa.c:4571 ../regexp_nfa.c:4869
-msgid ""
-"Could not open temporary log file for writing, displaying on stderr ... "
-msgstr ""
-
-#: ../regexp_nfa.c:4840
-#, c-format
-msgid "(NFA) COULD NOT OPEN %s !"
-msgstr ""
-
-#: ../regexp_nfa.c:6049
-#, fuzzy
-msgid "Could not open temporary log file for writing "
-msgstr "E214: §ä¤£¨ì¼g¤J¥Îªº¼È¦sÀÉ"
-
-#: ../screen.c:7435
-msgid " VREPLACE"
-msgstr " V-¨ú¥N"
-
-#: ../screen.c:7437
-msgid " REPLACE"
-msgstr " ¨ú¥N"
-
-#: ../screen.c:7440
-msgid " REVERSE"
-msgstr " ¤ÏÂà"
-
-#: ../screen.c:7441
-msgid " INSERT"
-msgstr " ´¡¤J"
-
-#: ../screen.c:7443
-msgid " (insert)"
-msgstr " (´¡¤J)"
-
-#: ../screen.c:7445
-msgid " (replace)"
-msgstr " (¨ú¥N)"
-
-#: ../screen.c:7447
-msgid " (vreplace)"
-msgstr " (v-¨ú¥N)"
-
-#: ../screen.c:7449
-msgid " Hebrew"
-msgstr " Hebrew"
-
-#: ../screen.c:7454
-msgid " Arabic"
-msgstr " Arabic"
-
-#: ../screen.c:7456
-msgid " (lang)"
-msgstr " (»y¨¥)"
-
-#: ../screen.c:7459
-msgid " (paste)"
-msgstr " (¶K¤W)"
-
-#: ../screen.c:7469
-msgid " VISUAL"
-msgstr " ¿ï¨ú"
-
-#: ../screen.c:7470
-msgid " VISUAL LINE"
-msgstr " [¦æ] "
-
-#: ../screen.c:7471
-msgid " VISUAL BLOCK"
-msgstr " [°Ï¶ô] "
-
-#: ../screen.c:7472
-msgid " SELECT"
-msgstr " ¿ï¨ú"
-
-#: ../screen.c:7473
-msgid " SELECT LINE"
-msgstr " ¿ï¨ú¦æ "
-
-#: ../screen.c:7474
-msgid " SELECT BLOCK"
-msgstr " ¿ï¨ú°Ï¶ô"
-
-#: ../screen.c:7486 ../screen.c:7541
-msgid "recording"
-msgstr "°O¿ý¤¤"
-
-#: ../search.c:487
-#, c-format
-msgid "E383: Invalid search string: %s"
-msgstr "E383: ¿ù»~ªº·j´M¦r¦ê: %s"
-
-#: ../search.c:832
-#, c-format
-msgid "E384: search hit TOP without match for: %s"
-msgstr "E384: ¤w·j´M¨ìÀÉ®×¶}ÀY¤´§ä¤£¨ì %s"
-
-#: ../search.c:835
-#, c-format
-msgid "E385: search hit BOTTOM without match for: %s"
-msgstr "E385: ¤w·j´M¨ìÀÉ®×µ²§À¤´§ä¤£¨ì %s"
-
-#: ../search.c:1200
-msgid "E386: Expected '?' or '/' after ';'"
-msgstr "E386: ¦b ';' «á­±À³¸Ó¦³ '?' ©Î '/'"
-
-#: ../search.c:4085
-msgid " (includes previously listed match)"
-msgstr " (¥]¬A«e¦¸¦C¥X²Å¦X¶µ)"
-
-#. cursor at status line
-#: ../search.c:4104
-msgid "--- Included files "
-msgstr "--- ¤Þ¤JÀÉ®× "
-
-#: ../search.c:4106
-msgid "not found "
-msgstr "§ä¤£¨ì "
-
-#: ../search.c:4107
-msgid "in path ---\n"
-msgstr "---\n"
-
-#: ../search.c:4168
-msgid " (Already listed)"
-msgstr " (¤w¦C¥X)"
-
-#: ../search.c:4170
-msgid " NOT FOUND"
-msgstr " §ä¤£¨ì"
-
-#: ../search.c:4211
-#, c-format
-msgid "Scanning included file: %s"
-msgstr "·j´M¤Þ¤JÀÉ®×: %s"
-
-#: ../search.c:4216
-#, fuzzy, c-format
-msgid "Searching included file %s"
-msgstr "·j´M¤Þ¤JÀÉ®×: %s"
-
-#: ../search.c:4405
-msgid "E387: Match is on current line"
-msgstr "E387: ¥Ø«e©Ò¦b¦æ¤¤¦³¤@¤Ç°t"
-
-#: ../search.c:4517
-msgid "All included files were found"
-msgstr "©Ò¦³¤Þ¤JÀɮ׳£¤w§ä¨ì"
-
-#: ../search.c:4519
-msgid "No included files"
-msgstr "¨S¦³¤Þ¤JÀÉ®×"
-
-#: ../search.c:4527
-msgid "E388: Couldn't find definition"
-msgstr "E388: §ä¤£¨ì©w¸q"
-
-#: ../search.c:4529
-msgid "E389: Couldn't find pattern"
-msgstr "E389: §ä¤£¨ì pattern"
-
-#: ../search.c:4668
-#, fuzzy
-msgid "Substitute "
-msgstr "¨ú¥N¤@²Õ "
-
-#: ../search.c:4681
-#, c-format
-msgid ""
-"\n"
-"# Last %sSearch Pattern:\n"
-"~"
-msgstr ""
-
-#: ../spell.c:951
-#, fuzzy
-msgid "E759: Format error in spell file"
-msgstr "E297: ¼È¦sÀɼg¤J¿ù»~"
-
-#: ../spell.c:952
-msgid "E758: Truncated spell file"
-msgstr ""
-
-#: ../spell.c:953
-#, c-format
-msgid "Trailing text in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:954
-#, c-format
-msgid "Affix name too long in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:955
-#, fuzzy
-msgid "E761: Format error in affix file FOL, LOW or UPP"
-msgstr "E431: Tag ÀÉ \"%s\" ®æ¦¡¿ù»~"
-
-#: ../spell.c:957
-msgid "E762: Character in FOL, LOW or UPP is out of range"
-msgstr ""
-
-#: ../spell.c:958
-msgid "Compressing word tree..."
-msgstr ""
-
-#: ../spell.c:1951
-msgid "E756: Spell checking is not enabled"
-msgstr ""
-
-#: ../spell.c:2249
-#, c-format
-msgid "Warning: Cannot find word list \"%s.%s.spl\" or \"%s.ascii.spl\""
-msgstr ""
-
-#: ../spell.c:2473
-#, fuzzy, c-format
-msgid "Reading spell file \"%s\""
-msgstr "¨Ï¥Î¼È¦sÀÉ \"%s\""
-
-#: ../spell.c:2496
-#, fuzzy
-msgid "E757: This does not look like a spell file"
-msgstr "E307: %s ¬Ý°_¨Ó¤£¹³¬O Vim ¼È¦sÀÉ"
-
-#: ../spell.c:2501
-msgid "E771: Old spell file, needs to be updated"
-msgstr ""
-
-#: ../spell.c:2504
-msgid "E772: Spell file is for newer version of Vim"
-msgstr ""
-
-#: ../spell.c:2602
-#, fuzzy
-msgid "E770: Unsupported section in spell file"
-msgstr "E297: ¼È¦sÀɼg¤J¿ù»~"
-
-#: ../spell.c:3762
-#, fuzzy, c-format
-msgid "Warning: region %s not supported"
-msgstr "E519: ¤£¤ä´©¸Ó¿ï¶µ"
-
-#: ../spell.c:4550
-#, fuzzy, c-format
-msgid "Reading affix file %s ..."
-msgstr "·j´M tag ÀÉ®× \"%s\""
-
-#: ../spell.c:4589 ../spell.c:5635 ../spell.c:6140
-#, c-format
-msgid "Conversion failure for word in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4630 ../spell.c:6170
-#, c-format
-msgid "Conversion in %s not supported: from %s to %s"
-msgstr ""
-
-#: ../spell.c:4642
-#, c-format
-msgid "Invalid value for FLAG in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4655
-#, c-format
-msgid "FLAG after using flags in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4723
-#, c-format
-msgid ""
-"Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-
-#: ../spell.c:4731
-#, c-format
-msgid ""
-"Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line "
-"%d"
-msgstr ""
-
-#: ../spell.c:4747
-#, c-format
-msgid "Wrong COMPOUNDRULES value in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4771
-#, c-format
-msgid "Wrong COMPOUNDWORDMAX value in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4777
-#, c-format
-msgid "Wrong COMPOUNDMIN value in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4783
-#, c-format
-msgid "Wrong COMPOUNDSYLMAX value in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4795
-#, c-format
-msgid "Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4847
-#, c-format
-msgid "Different combining flag in continued affix block in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4850
-#, fuzzy, c-format
-msgid "Duplicate affix in %s line %d: %s"
-msgstr "E154: ¼ÐÅÒ(tag) \"%s\" ¦bÀÉ®× %s ¸Ì­«½Æ¥X²{¦h¦¸"
-
-#: ../spell.c:4871
-#, c-format
-msgid ""
-"Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in %s "
-"line %d: %s"
-msgstr ""
-
-#: ../spell.c:4893
-#, c-format
-msgid "Expected Y or N in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:4968
-#, c-format
-msgid "Broken condition in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:5091
-#, c-format
-msgid "Expected REP(SAL) count in %s line %d"
-msgstr ""
-
-#: ../spell.c:5120
-#, c-format
-msgid "Expected MAP count in %s line %d"
-msgstr ""
-
-#: ../spell.c:5132
-#, c-format
-msgid "Duplicate character in MAP in %s line %d"
-msgstr ""
-
-#: ../spell.c:5176
-#, c-format
-msgid "Unrecognized or duplicate item in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:5197
-#, c-format
-msgid "Missing FOL/LOW/UPP line in %s"
-msgstr ""
-
-#: ../spell.c:5220
-msgid "COMPOUNDSYLMAX used without SYLLABLE"
-msgstr ""
-
-#: ../spell.c:5236
-#, fuzzy
-msgid "Too many postponed prefixes"
-msgstr "¤Ó¦h½s¿è°Ñ¼Æ"
-
-#: ../spell.c:5238
-#, fuzzy
-msgid "Too many compound flags"
-msgstr "¤Ó¦h½s¿è°Ñ¼Æ"
-
-#: ../spell.c:5240
-msgid "Too many postponed prefixes and/or compound flags"
-msgstr ""
-
-#: ../spell.c:5250
-#, c-format
-msgid "Missing SOFO%s line in %s"
-msgstr ""
-
-#: ../spell.c:5253
-#, c-format
-msgid "Both SAL and SOFO lines in %s"
-msgstr ""
-
-#: ../spell.c:5331
-#, c-format
-msgid "Flag is not a number in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:5334
-#, c-format
-msgid "Illegal flag in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:5493 ../spell.c:5501
-#, c-format
-msgid "%s value differs from what is used in another .aff file"
-msgstr ""
-
-#: ../spell.c:5602
-#, fuzzy, c-format
-msgid "Reading dictionary file %s ..."
-msgstr "±½ºË¦r¨å: %s"
-
-#: ../spell.c:5611
-#, c-format
-msgid "E760: No word count in %s"
-msgstr ""
-
-#: ../spell.c:5669
-#, c-format
-msgid "line %6d, word %6d - %s"
-msgstr ""
-
-#: ../spell.c:5691
-#, fuzzy, c-format
-msgid "Duplicate word in %s line %d: %s"
-msgstr "¨C¤@¦æ³£§ä¤£¨ì: %s"
-
-#: ../spell.c:5694
-#, c-format
-msgid "First duplicate word in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:5746
-#, c-format
-msgid "%d duplicate word(s) in %s"
-msgstr ""
-
-#: ../spell.c:5748
-#, c-format
-msgid "Ignored %d word(s) with non-ASCII characters in %s"
-msgstr ""
-
-#: ../spell.c:6115
-#, fuzzy, c-format
-msgid "Reading word file %s ..."
-msgstr "±q¼Ð·Ç¿é¤JŪ¨ú..."
-
-#: ../spell.c:6155
-#, c-format
-msgid "Duplicate /encoding= line ignored in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:6159
-#, c-format
-msgid "/encoding= line after word ignored in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:6180
-#, c-format
-msgid "Duplicate /regions= line ignored in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:6185
-#, c-format
-msgid "Too many regions in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:6198
-#, c-format
-msgid "/ line ignored in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:6224
-#, fuzzy, c-format
-msgid "Invalid region nr in %s line %d: %s"
-msgstr "E573: ¤£¥¿½Tªº¦øªA¾¹ id : %s"
-
-#: ../spell.c:6230
-#, c-format
-msgid "Unrecognized flags in %s line %d: %s"
-msgstr ""
-
-#: ../spell.c:6257
-#, c-format
-msgid "Ignored %d words with non-ASCII characters"
-msgstr ""
-
-#: ../spell.c:6656
-#, c-format
-msgid "Compressed %d of %d nodes; %d (%d%%) remaining"
-msgstr ""
-
-#: ../spell.c:7340
-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
-msgid "Performing soundfolding..."
-msgstr ""
-
-#: ../spell.c:7368
-#, c-format
-msgid "Number of words after soundfolding: %<PRId64>"
-msgstr ""
-
-#: ../spell.c:7476
-#, c-format
-msgid "Total number of words: %d"
-msgstr ""
-
-#: ../spell.c:7655
-#, fuzzy, c-format
-msgid "Writing suggestion file %s ..."
-msgstr "¼g¤J viminfo ÀÉ®× \"%s\" ¤¤"
-
-#: ../spell.c:7707 ../spell.c:7927
-#, c-format
-msgid "Estimated runtime memory use: %d bytes"
-msgstr ""
-
-#: ../spell.c:7820
-msgid "E751: Output file name must not have region name"
-msgstr ""
-
-#: ../spell.c:7822
-#, fuzzy
-msgid "E754: Only up to 8 regions supported"
-msgstr "E519: ¤£¤ä´©¸Ó¿ï¶µ"
-
-#: ../spell.c:7846
-#, fuzzy, c-format
-msgid "E755: Invalid region in %s"
-msgstr "E15: ¤£¥¿½Tªº¹Bºâ¦¡: %s"
-
-#: ../spell.c:7907
-msgid "Warning: both compounding and NOBREAK specified"
-msgstr ""
-
-#: ../spell.c:7920
-#, fuzzy, c-format
-msgid "Writing spell file %s ..."
-msgstr "¼g¤J viminfo ÀÉ®× \"%s\" ¤¤"
-
-#: ../spell.c:7925
-msgid "Done!"
-msgstr ""
-
-#: ../spell.c:8034
-#, c-format
-msgid "E765: 'spellfile' does not have %<PRId64> entries"
-msgstr ""
-
-#: ../spell.c:8074
-#, c-format
-msgid "Word '%.*s' removed from %s"
-msgstr ""
-
-#: ../spell.c:8117
-#, c-format
-msgid "Word '%.*s' added to %s"
-msgstr ""
-
-#: ../spell.c:8381
-msgid "E763: Word characters differ between spell files"
-msgstr ""
-
-#: ../spell.c:8684
-msgid "Sorry, no suggestions"
-msgstr ""
-
-#: ../spell.c:8687
-#, fuzzy, c-format
-msgid "Sorry, only %<PRId64> suggestions"
-msgstr "¡A½d³ò¡G %<PRId64> ¦æ "
-
-#. for when 'cmdheight' > 1
-#. avoid more prompt
-#: ../spell.c:8704
-#, fuzzy, c-format
-msgid "Change \"%.*s\" to:"
-msgstr "±NÅܰʦsÀx¦Ü \"%.*s\"?"
-
-#: ../spell.c:8737
-#, c-format
-msgid " < \"%.*s\""
-msgstr ""
-
-#: ../spell.c:8882
-#, fuzzy
-msgid "E752: No previous spell replacement"
-msgstr "E35: ¨S¦³«e¤@­Ó·j´M«ü¥O"
-
-#: ../spell.c:8925
-#, fuzzy, c-format
-msgid "E753: Not found: %s"
-msgstr "E334: [¿ï³æ] §ä¤£¨ì %s"
-
-#: ../spell.c:9276
-#, fuzzy, c-format
-msgid "E778: This does not look like a .sug file: %s"
-msgstr "E307: %s ¬Ý°_¨Ó¤£¹³¬O Vim ¼È¦sÀÉ"
-
-#: ../spell.c:9282
-#, c-format
-msgid "E779: Old .sug file, needs to be updated: %s"
-msgstr ""
-
-#: ../spell.c:9286
-#, c-format
-msgid "E780: .sug file is for newer version of Vim: %s"
-msgstr ""
-
-#: ../spell.c:9295
-#, c-format
-msgid "E781: .sug file doesn't match .spl file: %s"
-msgstr ""
-
-#: ../spell.c:9305
-#, fuzzy, c-format
-msgid "E782: error while reading .sug file: %s"
-msgstr "E47: Ū¨ú¿ù»~ÀÉ®×¥¢±Ñ"
-
-#. This should have been checked when generating the .spl
-#. file.
-#: ../spell.c:11575
-msgid "E783: duplicate char in MAP entry"
-msgstr ""
-
-#: ../syntax.c:266
-msgid "No Syntax items defined for this buffer"
-msgstr "³o­Ó½w½Ä°Ï¨S¦³©w¸q¥ô¦ó»yªk"
-
-#: ../syntax.c:3083 ../syntax.c:3104 ../syntax.c:3127
-#, c-format
-msgid "E390: Illegal argument: %s"
-msgstr "E390: °Ñ¼Æ¤£¥¿½T: %s"
-
-#: ../syntax.c:3299
-#, c-format
-msgid "E391: No such syntax cluster: %s"
-msgstr "E391: µL¦¹ syntax cluster: \"%s\""
-
-#: ../syntax.c:3433
-msgid "syncing on C-style comments"
-msgstr "C»y¨¥¦¡µù¸Ñ¦P¨B¤Æ¤¤"
-
-#: ../syntax.c:3439
-msgid "no syncing"
-msgstr "¨S¦³¦P¨B¤Æ"
-
-#: ../syntax.c:3441
-msgid "syncing starts "
-msgstr "¦P¨B¤Æ¶}©l"
-
-#: ../syntax.c:3443 ../syntax.c:3506
-msgid " lines before top line"
-msgstr "¦æ¸¹¶W¥X½d³ò"
-
-#: ../syntax.c:3448
-msgid ""
-"\n"
-"--- Syntax sync items ---"
-msgstr ""
-"\n"
-"--- »yªk¦P¨Bª«¥ó (Syntax sync items) ---"
-
-#: ../syntax.c:3452
-msgid ""
-"\n"
-"syncing on items"
-msgstr ""
-"\n"
-"¦P¨B¤Æ¤¤:"
-
-#: ../syntax.c:3457
-msgid ""
-"\n"
-"--- Syntax items ---"
-msgstr ""
-"\n"
-"--- »yªk¶µ¥Ø ---"
-
-#: ../syntax.c:3475
-#, c-format
-msgid "E392: No such syntax cluster: %s"
-msgstr "E392: µL¦¹ syntax cluster: \"%s\""
-
-#: ../syntax.c:3497
-msgid "minimal "
-msgstr "³Ì¤p"
-
-#: ../syntax.c:3503
-msgid "maximal "
-msgstr "³Ì¤j"
-
-#: ../syntax.c:3513
-msgid "; match "
-msgstr "; ²Å¦X "
-
-#: ../syntax.c:3515
-msgid " line breaks"
-msgstr "Â_¦æ "
-
-#: ../syntax.c:4076
-msgid "E395: contains argument not accepted here"
-msgstr "E395: ¨Ï¥Î¤F¤£¥¿½Tªº°Ñ¼Æ"
-
-#: ../syntax.c:4096
-#, fuzzy
-msgid "E844: invalid cchar value"
-msgstr "E474: ¤£¥¿½Tªº°Ñ¼Æ"
-
-#: ../syntax.c:4107
-msgid "E393: group[t]here not accepted here"
-msgstr "E393: ¨Ï¥Î¤F¤£¥¿½Tªº°Ñ¼Æ"
-
-#: ../syntax.c:4126
-#, c-format
-msgid "E394: Didn't find region item for %s"
-msgstr "E394: §ä¤£¨ì %s ªº region item"
-
-#: ../syntax.c:4188
-msgid "E397: Filename required"
-msgstr "E397: »Ý­nÀɮצWºÙ"
-
-#: ../syntax.c:4221
-#, fuzzy
-msgid "E847: Too many syntax includes"
-msgstr "E77: ¤Ó¦hÀɦW"
-
-#: ../syntax.c:4303
-#, fuzzy, c-format
-msgid "E789: Missing ']': %s"
-msgstr "E398: ¯Ê¤Ö \"=\": %s"
-
-#: ../syntax.c:4531
-#, c-format
-msgid "E398: Missing '=': %s"
-msgstr "E398: ¯Ê¤Ö \"=\": %s"
-
-#: ../syntax.c:4666
-#, c-format
-msgid "E399: Not enough arguments: syntax region %s"
-msgstr "E399: syntax region %s ªº¤Þ¼Æ¤Ó¤Ö"
-
-#: ../syntax.c:4870
-#, fuzzy
-msgid "E848: Too many syntax clusters"
-msgstr "E391: µL¦¹ syntax cluster: \"%s\""
-
-#: ../syntax.c:4954
-msgid "E400: No cluster specified"
-msgstr "E400: ¨S¦³«ü©wªºÄÝ©Ê"
-
-#. end delimiter not found
-#: ../syntax.c:4986
-#, c-format
-msgid "E401: Pattern delimiter not found: %s"
-msgstr "E401: §ä¤£¨ì¤À¹j²Å¸¹: %s"
-
-#: ../syntax.c:5049
-#, c-format
-msgid "E402: Garbage after pattern: %s"
-msgstr "E402: '%s' «á­±ªºªF¦èµLªk¿ëÃÑ"
-
-#: ../syntax.c:5120
-msgid "E403: syntax sync: line continuations pattern specified twice"
-msgstr "E403: »yªk¦P¨B: ³s±µ¦æ²Å¸¹³Q«ü©w¤F¨â¦¸"
-
-#: ../syntax.c:5169
-#, c-format
-msgid "E404: Illegal arguments: %s"
-msgstr "E404: °Ñ¼Æ¤£¥¿½T: %s"
-
-#: ../syntax.c:5217
-#, c-format
-msgid "E405: Missing equal sign: %s"
-msgstr "E405: ¯Ê¤Ö¬Ûµ¥²Å¸¹: %s"
-
-#: ../syntax.c:5222
-#, c-format
-msgid "E406: Empty argument: %s"
-msgstr "E406: ªÅ¥Õ°Ñ¼Æ: %s"
-
-#: ../syntax.c:5240
-#, c-format
-msgid "E407: %s not allowed here"
-msgstr "E407: %s ¤£¯à¦b¦¹¥X²{"
-
-#: ../syntax.c:5246
-#, c-format
-msgid "E408: %s must be first in contains list"
-msgstr "E408: %s ¥²¶·¬O¦Cªí¸Ìªº²Ä¤@­Ó"
-
-#: ../syntax.c:5304
-#, c-format
-msgid "E409: Unknown group name: %s"
-msgstr "E409: ¤£¥¿½Tªº¸s²Õ¦WºÙ: %s"
-
-#: ../syntax.c:5512
-#, c-format
-msgid "E410: Invalid :syntax subcommand: %s"
-msgstr "E410: ¤£¥¿½Tªº :syntax ¤l©R¥O: %s"
-
-#: ../syntax.c:5854
-msgid ""
-" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"
-msgstr ""
-
-#: ../syntax.c:6146
-msgid "E679: recursive loop loading syncolor.vim"
-msgstr ""
-
-#: ../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: °Ñ¼Æ¹L¦h: \":highlight link %s\""
-
-#: ../syntax.c:6302
-msgid "E414: group has settings, highlight link ignored"
-msgstr "E414: ¤w³]©w¸s²Õ, ©¿²¤ 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: ¤£¦Xªkªº­È: %s"
-
-#: ../syntax.c:6496
-msgid "E419: FG color unknown"
-msgstr "E419: ¿ù»~ªº«e´ºÃC¦â"
-
-#: ../syntax.c:6504
-msgid "E420: BG color unknown"
-msgstr "E420: ¿ù»~ªº­I´ºÃC¦â"
-
-#: ../syntax.c:6564
-#, c-format
-msgid "E421: Color name or number not recognized: %s"
-msgstr "E421: ¿ù»~ªºÃC¦â¦WºÙ©Î¼Æ­È: %s"
-
-#: ../syntax.c:6714
-#, c-format
-msgid "E422: terminal code too long: %s"
-msgstr "E422: ²×ºÝ¾÷½X¤Óªø: %s"
-
-#: ../syntax.c:6753
-#, c-format
-msgid "E423: Illegal argument: %s"
-msgstr "E423: °Ñ¼Æ¤£¥¿½T: %s"
-
-#: ../syntax.c:6925
-msgid "E424: Too many different highlighting attributes in use"
-msgstr "E424: ¨Ï¥Î¤F¹L¦h¬Û²§ªº°ª«G«×ÄÝ©Ê"
-
-#: ../syntax.c:7427
-msgid "E669: Unprintable character in group name"
-msgstr "E669: ¸s²Õ¦WºÙ¤¤¦³µLªk¦C¦Lªº¦r¤¸"
-
-#: ../syntax.c:7434
-msgid "W18: Invalid character in group name"
-msgstr "W18: ¸s²Õ¦WºÙ¤¤¦³¤£¥¿½Tªº¦r¤¸"
-
-#: ../syntax.c:7448
-msgid "E849: Too many highlight and syntax groups"
-msgstr ""
-
-#: ../tag.c:104
-msgid "E555: at bottom of tag stack"
-msgstr "E555: ¼ÐÅÒ(tag)°ïÅ|µ²§À"
-
-#: ../tag.c:105
-msgid "E556: at top of tag stack"
-msgstr "E556: ¼ÐÅÒ(tag)°ïÅ|¶}ÀY"
-
-#: ../tag.c:380
-msgid "E425: Cannot go before first matching tag"
-msgstr "E425: ¤w¸g¦b³Ì«e­±ªº¼ÐÅÒ(tag)¤F"
-
-#: ../tag.c:504
-#, 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
-msgid "E427: There is only one matching tag"
-msgstr "E427: ¥u¦³¦¹¶µ²Å¦X"
-
-#: ../tag.c:831
-msgid "E428: Cannot go beyond last matching tag"
-msgstr "E428: ¤v¸g¦b³Ì«á¤@­Ó²Å¦Xªº tag ¤F"
-
-#: ../tag.c:850
-#, c-format
-msgid "File \"%s\" does not exist"
-msgstr "ÀÉ®× \"%s\" ¤£¦s¦b"
-
-#. Give an indication of the number of matching tags
-#: ../tag.c:859
-#, c-format
-msgid "tag %d of %d%s"
-msgstr "§ä¨ì tag: %d/%d%s"
-
-#: ../tag.c:862
-msgid " or more"
-msgstr " ©Î§ó¦h"
-
-#: ../tag.c:864
-msgid " Using tag with different case!"
-msgstr " ¥H¤£¦P¤j¤p¼g¨Ó¨Ï¥Î tag!"
-
-#: ../tag.c:909
-#, c-format
-msgid "E429: File \"%s\" does not exist"
-msgstr "E429: ÀÉ®× \"%s\" ¤£¦s¦b"
-
-#. Highlight title
-#: ../tag.c:960
-msgid ""
-"\n"
-" # TO tag FROM line in file/text"
-msgstr ""
-"\n"
-" # ¨ì tag ±q ¦æ ¦b ÀÉ®×/¤å¦r"
-
-#: ../tag.c:1303
-#, c-format
-msgid "Searching tags file %s"
-msgstr "·j´M tag ÀÉ®× \"%s\""
-
-#: ../tag.c:1545
-msgid "Ignoring long line in tags file"
-msgstr ""
-
-#: ../tag.c:1915
-#, c-format
-msgid "E431: Format error in tags file \"%s\""
-msgstr "E431: Tag ÀÉ \"%s\" ®æ¦¡¿ù»~"
-
-#: ../tag.c:1917
-#, c-format
-msgid "Before byte %<PRId64>"
-msgstr "¦b %<PRId64> ¦ì¤¸¤§«e"
-
-#: ../tag.c:1929
-#, c-format
-msgid "E432: Tags file not sorted: %s"
-msgstr "E432: Tag ÀÉ®×¥¼±Æ§Ç: %s"
-
-#. never opened any tags file
-#: ../tag.c:1960
-msgid "E433: No tags file"
-msgstr "E433: ¨S¦³ tag ÀÉ"
-
-#: ../tag.c:2536
-msgid "E434: Can't find tag pattern"
-msgstr "E434: §ä¤£¨ì tag"
-
-#: ../tag.c:2544
-msgid "E435: Couldn't find tag, just guessing!"
-msgstr "E435: §ä¤£¨ì tag, ¥Î²qªº!"
-
-#: ../tag.c:2797
-#, c-format
-msgid "Duplicate field name: %s"
-msgstr ""
-
-#: ../term.c:1442
-msgid "' not known. Available builtin terminals are:"
-msgstr "' µLªk¸ü¤J¡C¥i¥Îªº¤º«Ø²×ºÝ¾÷§Î¦¡¦³:"
-
-#: ../term.c:1463
-msgid "defaulting to '"
-msgstr "¹w³]: '"
-
-#: ../term.c:1731
-msgid "E557: Cannot open termcap file"
-msgstr "E557: µLªk¶}±Ò termcap ÀÉ®×"
-
-#: ../term.c:1735
-msgid "E558: Terminal entry not found in terminfo"
-msgstr "E558: terminfo ¤¤¨S¦³²×ºÝ¾÷¸ê®Æ¶µ"
-
-#: ../term.c:1737
-msgid "E559: Terminal entry not found in termcap"
-msgstr "E559: termcap ¤¤¨S¦³²×ºÝ¾÷¸ê®Æ¶µ"
-
-#: ../term.c:1878
-#, c-format
-msgid "E436: No \"%s\" entry in termcap"
-msgstr "E436: termcap ¨S¦³ \"%s\" entry"
-
-#: ../term.c:2249
-msgid "E437: terminal capability \"cm\" required"
-msgstr "E437: ²×ºÝ¾÷»Ý­n \"cm\" ªº¯à¤O"
-
-#. Highlight title
-#: ../term.c:4376
-msgid ""
-"\n"
-"--- Terminal keys ---"
-msgstr ""
-"\n"
-"--- ²×ºÝ¾÷«öÁä ---"
-
-#: ../ui.c:481
-msgid "Vim: Error reading input, exiting...\n"
-msgstr "Vim: Ū¨ú¿é¤J¿ù»~¡AÂ÷¶}¤¤...\n"
-
-#. This happens when the FileChangedRO autocommand changes the
-#. * file in a way it becomes shorter.
-#: ../undo.c:379
-msgid "E881: Line count changed unexpectedly"
-msgstr ""
-
-#: ../undo.c:627
-#, fuzzy, c-format
-msgid "E828: Cannot open undo file for writing: %s"
-msgstr "E212: µLªk¥H¼g¤J¼Ò¦¡¶}±Ò"
-
-#: ../undo.c:717
-#, c-format
-msgid "E825: Corrupted undo file (%s): %s"
-msgstr ""
-
-#: ../undo.c:1039
-msgid "Cannot write undo file in any directory in 'undodir'"
-msgstr ""
-
-#: ../undo.c:1074
-#, c-format
-msgid "Will not overwrite with undo file, cannot read: %s"
-msgstr ""
-
-#: ../undo.c:1092
-#, c-format
-msgid "Will not overwrite, this is not an undo file: %s"
-msgstr ""
-
-#: ../undo.c:1108
-msgid "Skipping undo file write, nothing to undo"
-msgstr ""
-
-#: ../undo.c:1121
-#, fuzzy, c-format
-msgid "Writing undo file: %s"
-msgstr "¼g¤J viminfo ÀÉ®× \"%s\" ¤¤"
-
-#: ../undo.c:1213
-#, fuzzy, c-format
-msgid "E829: write error in undo file: %s"
-msgstr "E297: ¼È¦sÀɼg¤J¿ù»~"
-
-#: ../undo.c:1280
-#, c-format
-msgid "Not reading undo file, owner differs: %s"
-msgstr ""
-
-#: ../undo.c:1292
-#, fuzzy, c-format
-msgid "Reading undo file: %s"
-msgstr "Ū¨ú viminfo ÀÉ®× \"%s\"%s%s%s"
-
-#: ../undo.c:1299
-#, fuzzy, c-format
-msgid "E822: Cannot open undo file for reading: %s"
-msgstr "E195: µLªkŪ¨ú viminfo"
-
-#: ../undo.c:1308
-#, fuzzy, c-format
-msgid "E823: Not an undo file: %s"
-msgstr "E484: µLªk¶}±ÒÀÉ®× %s"
-
-#: ../undo.c:1313
-#, fuzzy, c-format
-msgid "E824: Incompatible undo file: %s"
-msgstr "E484: µLªk¶}±ÒÀÉ®× %s"
-
-#: ../undo.c:1328
-msgid "File contents changed, cannot use undo info"
-msgstr ""
-
-#: ../undo.c:1497
-#, fuzzy, c-format
-msgid "Finished reading undo file %s"
-msgstr "µ²§ô°õ¦æ %s"
-
-#: ../undo.c:1586 ../undo.c:1812
-msgid "Already at oldest change"
-msgstr ""
-
-#: ../undo.c:1597 ../undo.c:1814
-msgid "Already at newest change"
-msgstr ""
-
-#: ../undo.c:1806
-#, fuzzy, c-format
-msgid "E830: Undo number %<PRId64> not found"
-msgstr "E92: §ä¤£¨ì²Ä %<PRId64> ­Ó½w½Ä°Ï"
-
-#: ../undo.c:1979
-msgid "E438: u_undo: line numbers wrong"
-msgstr "E438: u_undo: ¦æ¸¹¿ù»~"
-
-#: ../undo.c:2183
-#, fuzzy
-msgid "more line"
-msgstr "ÁÙ¦³¤@¦æ "
-
-#: ../undo.c:2185
-#, fuzzy
-msgid "more lines"
-msgstr "ÁÙ¦³¤@¦æ "
-
-#: ../undo.c:2187
-#, fuzzy
-msgid "line less"
-msgstr "¤Ö©ó¤@¦æ "
-
-#: ../undo.c:2189
-#, fuzzy
-msgid "fewer lines"
-msgstr "¥u³Ñ %<PRId64> ¦æ "
-
-#: ../undo.c:2193
-#, fuzzy
-msgid "change"
-msgstr "¤@¶µ§ïÅÜ"
-
-#: ../undo.c:2195
-#, fuzzy
-msgid "changes"
-msgstr "¤@¶µ§ïÅÜ"
-
-#: ../undo.c:2225
-#, fuzzy, c-format
-msgid "%<PRId64> %s; %s #%<PRId64> %s"
-msgstr "%<PRId64> ¦æ %s ¹L %d ¦¸"
-
-#: ../undo.c:2228
-msgid "before"
-msgstr ""
-
-#: ../undo.c:2228
-msgid "after"
-msgstr ""
-
-#: ../undo.c:2325
-#, fuzzy
-msgid "Nothing to undo"
-msgstr "¨S¦³³o­Ó mapping ¹ïÀ³"
-
-#: ../undo.c:2330
-msgid "number changes when saved"
-msgstr ""
-
-#: ../undo.c:2360
-#, fuzzy, c-format
-msgid "%<PRId64> seconds ago"
-msgstr "%<PRId64> Äæ; "
-
-#: ../undo.c:2372
-#, fuzzy
-msgid "E790: undojoin is not allowed after undo"
-msgstr "E407: %s ¤£¯à¦b¦¹¥X²{"
-
-#: ../undo.c:2466
-msgid "E439: undo list corrupt"
-msgstr "E439: ´_­ì¦Cªí·lÃa"
-
-#: ../undo.c:2495
-msgid "E440: undo line missing"
-msgstr "E440: §ä¤£¨ì­n undo ªº¦æ "
-
-#: ../version.c:600
-msgid ""
-"\n"
-"Included patches: "
-msgstr ""
-"\n"
-"¤Þ¤J­×¥¿: "
-
-#: ../version.c:627
-#, fuzzy
-msgid ""
-"\n"
-"Extra patches: "
-msgstr "¥~³¡²Å¦X:\n"
-
-#: ../version.c:639 ../version.c:864
-msgid "Modified by "
-msgstr "­×§ïªÌ¬°"
-
-#: ../version.c:646
-msgid ""
-"\n"
-"Compiled "
-msgstr ""
-"\n"
-"½sĶ"
-
-#: ../version.c:649
-msgid "by "
-msgstr "ªÌ:"
-
-#: ../version.c:660
-msgid ""
-"\n"
-"Huge version "
-msgstr ""
-"\n"
-"¶W±jª©¥» "
-
-#: ../version.c:661
-msgid "without GUI."
-msgstr "¤£¨Ï¥Î¹Ï«¬¬É­±¡C"
-
-#: ../version.c:662
-msgid " Features included (+) or not (-):\n"
-msgstr " ¥Ø«e¥i¨Ï¥Î(+)»P¤£¥i¨Ï¥Î(-)ªº¼Ò²Õ¦Cªí:\n"
-
-#: ../version.c:667
-msgid " system vimrc file: \""
-msgstr " ¨t²Î vimrc ³]©wÀÉ: \""
-
-#: ../version.c:672
-msgid " user vimrc file: \""
-msgstr " ¨Ï¥ÎªÌ­Ó¤H vimrc ³]©wÀÉ: \""
-
-#: ../version.c:677
-msgid " 2nd user vimrc file: \""
-msgstr " ²Ä¤G²Õ­Ó¤H vimrc ÀÉ®×: \""
-
-#: ../version.c:682
-msgid " 3rd user vimrc file: \""
-msgstr " ²Ä¤T²Õ­Ó¤H vimrc ÀÉ®×: \""
-
-#: ../version.c:687
-msgid " user exrc file: \""
-msgstr " ¨Ï¥ÎªÌ­Ó¤H exrc ³]©wÀÉ: \""
-
-#: ../version.c:692
-msgid " 2nd user exrc file: \""
-msgstr " ²Ä¤G²Õ¨Ï¥ÎªÌ exrc ÀÉ®×: \""
-
-#: ../version.c:699
-msgid " fall-back for $VIM: \""
-msgstr " $VIM ¹w³]­È: \""
-
-#: ../version.c:705
-msgid " f-b for $VIMRUNTIME: \""
-msgstr " $VIMRUNTIME ¹w³]­È: \""
-
-#: ../version.c:709
-msgid "Compilation: "
-msgstr "½sĶ¤è¦¡: "
-
-#: ../version.c:712
-msgid "Linking: "
-msgstr "Ãìµ²¤è¦¡: "
-
-#: ../version.c:717
-msgid " DEBUG BUILD"
-msgstr " °£¿ùª©¥»"
-
-#: ../version.c:767
-msgid "VIM - Vi IMproved"
-msgstr "VIM - Vi IMproved"
-
-#: ../version.c:769
-msgid "version "
-msgstr "ª©¥» "
-
-#: ../version.c:770
-msgid "by Bram Moolenaar et al."
-msgstr "ºûÅ@ªÌ: Bram Moolenaar et al."
-
-#: ../version.c:774
-msgid "Vim is open source and freely distributable"
-msgstr "Vim ¬°¥i¦Û¥Ñ´²§Gªº¶}©ñ­ì©l½X³nÅé"
-
-#: ../version.c:776
-msgid "Help poor children in Uganda!"
-msgstr "½ÐÀ°§U¯Q¤z¹Fªº¥i¼¦«Äµ£!"
-
-#: ../version.c:777
-msgid "type :help iccf<Enter> for information "
-msgstr "¶i¤@¨B»¡©ú½Ð¿é¤J :help iccf<Enter>"
-
-#: ../version.c:779
-msgid "type :q<Enter> to exit "
-msgstr "­nÂ÷¶}½Ð¿é¤J :q<Enter> "
-
-#: ../version.c:780
-msgid "type :help<Enter> or <F1> for on-line help"
-msgstr "½u¤W»¡©ú½Ð¿é¤J :help<Enter> "
-
-#: ../version.c:781
-msgid "type :help version7<Enter> for version info"
-msgstr "·sª©¥»¸ê°T½Ð¿é¤J :help version7<Enter>"
-
-#: ../version.c:784
-msgid "Running in Vi compatible mode"
-msgstr "Vi ¬Û®e¼Ò¦¡"
-
-#: ../version.c:785
-msgid "type :set nocp<Enter> for Vim defaults"
-msgstr "¦pªG­n§¹¥þ¼ÒÀÀ¶Ç²Î Vi ½Ð¿é¤J :set nocp<Enter>"
-
-#: ../version.c:786
-msgid "type :help cp-default<Enter> for info on this"
-msgstr "¦pªG»Ý­n¹ï Vi ¬Û®e¼Ò¦¡ªº¶i¤@¨B»¡©ú½Ð¿é¤J :help cp-default<Enter>"
-
-#: ../version.c:827
-msgid "Sponsor Vim development!"
-msgstr "ÃÙ§U Vim ªº¶}µo»P¦¨ªø¡I"
-
-#: ../version.c:828
-msgid "Become a registered Vim user!"
-msgstr "¦¨¬° Vim ªºµù¥U¨Ï¥ÎªÌ¡I"
-
-#: ../version.c:831
-msgid "type :help sponsor<Enter> for information "
-msgstr "¸Ô²Ó»¡©ú½Ð¿é¤J :help sponsor<Enter>"
-
-#: ../version.c:832
-msgid "type :help register<Enter> for information "
-msgstr "¸Ô²Ó»¡©ú½Ð¿é¤J :help register<Enter> "
-
-#: ../version.c:834
-msgid "menu Help->Sponsor/Register for information "
-msgstr "¸Ô²Ó»¡©ú½Ð¿ï¨ú¿ï³æªº »²§U»¡©ú->ÃÙ§U/µù¥U "
-
-#: ../window.c:119
-msgid "Already only one window"
-msgstr "¤w¸g¥u³Ñ¤@­Óµøµ¡¤F"
-
-#: ../window.c:224
-msgid "E441: There is no preview window"
-msgstr "E441: ¨S¦³¹wÄýµøµ¡"
-
-#: ../window.c:559
-msgid "E442: Can't split topleft and botright at the same time"
-msgstr "E442: ¤£¯à¦P®É¤À³Îµøµ¡¬°¥ª¤W©M¥k¤U¨¤"
-
-#: ../window.c:1228
-msgid "E443: Cannot rotate when another window is split"
-msgstr "E443: ¦³¨ä¥¦¤À³Îµøµ¡®ÉµLªk±ÛÂà"
-
-#: ../window.c:1803
-msgid "E444: Cannot close last window"
-msgstr "E444: ¤£¯àÃö³¬³Ì«á¤@­Óµøµ¡"
-
-#: ../window.c:1810
-#, fuzzy
-msgid "E813: Cannot close autocmd window"
-msgstr "E444: ¤£¯àÃö³¬³Ì«á¤@­Óµøµ¡"
-
-#: ../window.c:1814
-#, fuzzy
-msgid "E814: Cannot close window, only autocmd window would remain"
-msgstr "E444: ¤£¯àÃö³¬³Ì«á¤@­Óµøµ¡"
-
-#: ../window.c:2717
-msgid "E445: Other window contains changes"
-msgstr "E445: ¨ä¥¦µøµ¡¦³§ó°Ê¸ê®Æ"
-
-#: ../window.c:4805
-msgid "E446: No file name under cursor"
-msgstr "E446: ´å¼Ð³B¨S¦³ÀɦW"
-
-#~ msgid "[Error List]"
-#~ msgstr "[¿ù»~¦Cªí]"
-
-#~ msgid "[No File]"
-#~ msgstr "[¥¼©R¦W]"
-
-#~ msgid "Patch file"
-#~ msgstr "Patch ÀÉ®×"
-
-#~ msgid "E106: Unknown variable: \"%s\""
-#~ msgstr "E106: ¥¼©w¸qªºÅܼÆ: \"%s\""
-
-#~ msgid ""
-#~ "&OK\n"
-#~ "&Cancel"
-#~ msgstr ""
-#~ "½T©w(&O)\n"
-#~ "¨ú®ø(&C)"
-
-#~ msgid "E240: No connection to Vim server"
-#~ msgstr "E240: ¨S¦³»P Vim Server «Ø¥ß³s½u"
-
-#~ msgid "E277: Unable to read a server reply"
-#~ msgstr "E277: µLªkŪ¨ú¦øªA¾¹ªº¦^À³"
-
-#~ msgid "E258: Unable to send to client"
-#~ msgstr "E258: µLªk¶Ç°e¨ì client"
-
-#~ msgid "E241: Unable to send to %s"
-#~ msgstr "E241: µLªk¶Ç°e¨ì %s"
-
-#~ msgid "E130: Undefined function: %s"
-#~ msgstr "E130: ¨ç¦¡ %s ©|¥¼©w¸q"
-
-#~ msgid "Save As"
-#~ msgstr "¥t¦s·sÀÉ"
-
-#~ msgid "Edit File"
-#~ msgstr "½s¿èÀÉ®×"
-
-#~ msgid " (NOT FOUND)"
-#~ msgstr " (§ä¤£¨ì) "
-
-#~ msgid "Source Vim script"
-#~ msgstr "°õ¦æ Vim script"
-
-#~ msgid "Edit File in new window"
-#~ msgstr "¦b·sµøµ¡½s¿èÀÉ®×"
-
-#~ msgid "Append File"
-#~ msgstr "ªþ¥[ÀÉ®×"
-
-#~ msgid "Window position: X %d, Y %d"
-#~ msgstr "µøµ¡¦ì¸m: X %d, Y %d"
-
-#~ msgid "Save Redirection"
-#~ msgstr "Àx¦s Redirection"
-
-#~ msgid "Save View"
-#~ msgstr "Àx¦s View"
-
-#~ msgid "Save Session"
-#~ msgstr "Àx¦s Session"
-
-#~ msgid "Save Setup"
-#~ msgstr "Àx¦s³]©w"
-
-#~ msgid "E196: No digraphs in this version"
-#~ msgstr "E196: ¥»ª©¥»µL½Æ¦X¦r¤¸(digraph)"
-
-#~ msgid "[NL found]"
-#~ msgstr "[§ä¨ìNL]"
-
-#~ msgid "[crypted]"
-#~ msgstr "[¤w¥[±K]"
-
-#~ msgid "[CONVERSION ERROR]"
-#~ msgstr "Âà´«¿ù»~"
-
-#~ msgid "NetBeans disallows writes of unmodified buffers"
-#~ msgstr "NetBeans ¤£¯à¼g¥X¥¼­×§ïªº½w½Ä°Ï"
-
-#~ msgid "Partial writes disallowed for NetBeans buffers"
-#~ msgstr "³¡¥÷¤º®eµLªk¼g¤J Netbeans ½w½Ä°Ï"
-
-#~ msgid "E460: The resource fork would be lost (add ! to override)"
-#~ msgstr "E460: Resource fork ·|®ø¥¢ (½Ð¨Ï¥Î ! ±j¨î°õ¦æ)"
-
-#~ msgid "E229: Cannot start the GUI"
-#~ msgstr "E229: µLªk±Ò°Ê¹Ï«¬¬É­±"
-
-#~ msgid "E230: Cannot read from \"%s\""
-#~ msgstr "E230: µLªkŪ¨úÀÉ®× \"%s\""
-
-#~ msgid "E665: Cannot start GUI, no valid font found"
-#~ msgstr "E665: µLªk±Ò°Ê¹Ï«¬¬É­±¡A§ä¤£¨ì¥i¥Îªº¦r«¬"
-
-#~ msgid "E231: 'guifontwide' invalid"
-#~ msgstr "E231: ¤£¥¿½Tªº 'guifontwide'"
-
-#~ msgid "E599: Value of 'imactivatekey' is invalid"
-#~ msgstr "E599: 'imactivatekey' ªº­È¤£¥¿½T"
-
-#~ msgid "E254: Cannot allocate color %s"
-#~ msgstr "E254: ¤£¯à°t¸mÃC¦â %s"
-
-#~ msgid "<cannot open> "
-#~ msgstr "<¤£¯à¶}±Ò>"
-
-#~ msgid "E616: vim_SelFile: can't get font %s"
-#~ msgstr "E616: vim_SelFile: ¤£¯à¨Ï¥Î %s ¦r«¬"
-
-#~ msgid "E614: vim_SelFile: can't return to current directory"
-#~ msgstr "E614: vim_SelFile: µLªk¦^¨ì¥Ø«e¥Ø¿ý"
-
-#~ msgid "Pathname:"
-#~ msgstr "¸ô®|:"
-
-#~ msgid "E615: vim_SelFile: can't get current directory"
-#~ msgstr "E615: vim_SelFile: µLªk¨ú±o¥Ø«e¥Ø¿ý"
-
-#~ msgid "OK"
-#~ msgstr "½T©w"
-
-#~ msgid "Cancel"
-#~ msgstr "¨ú®ø"
-
-#~ msgid "Scrollbar Widget: Could not get geometry of thumb pixmap."
-#~ msgstr "±²°Ê¶b: ¤£¯à³]©w thumb pixmap ªº¦ì¸m"
-
-#~ msgid "Vim dialog"
-#~ msgstr "Vim ¹ï¸Ü²°"
-
-#~ msgid "E232: Cannot create BalloonEval with both message and callback"
-#~ msgstr "E232: ¤£¯à¹ï°T®§»P callback «Ø¥ß BallonEval"
-
-#~ msgid "Vim dialog..."
-#~ msgstr "Vim ¹ï¸Ü²°..."
-
-#~ msgid "Input _Methods"
-#~ msgstr "¿é¤Jªk"
-
-#~ msgid "VIM - Search and Replace..."
-#~ msgstr "VIM - ´M§ä»P¨ú¥N..."
-
-#~ msgid "VIM - Search..."
-#~ msgstr "VIM - ´M§ä..."
-
-#~ msgid "Find what:"
-#~ msgstr "·j´M:"
-
-#~ msgid "Replace with:"
-#~ msgstr "¨ú¥N¬°:"
-
-#~ msgid "Match whole word only"
-#~ msgstr "¥u·j´M§¹¥þ¬Û¦Pªº¦r"
-
-#~ msgid "Match case"
-#~ msgstr "²Å¦X¤j¤p¼g"
-
-#~ msgid "Direction"
-#~ msgstr "¤è¦V"
-
-#~ msgid "Up"
-#~ msgstr "¦V¤W"
-
-#~ msgid "Down"
-#~ msgstr "¦V¤U"
-
-#~ msgid "Find Next"
-#~ msgstr "§ä¤U¤@­Ó"
-
-#~ msgid "Replace"
-#~ msgstr "¨ú¥N"
-
-#~ msgid "Replace All"
-#~ msgstr "¨ú¥N¥þ³¡"
-
-#~ msgid "Vim: Received \"die\" request from session manager\n"
-#~ msgstr "Vim: ¥Ñ Session ºÞ²z­û¦¬¨ì \"die\" ­n¨D\n"
-
-#~ msgid "Vim: Main window unexpectedly destroyed\n"
-#~ msgstr "Vim: ¥Dµøµ¡Äê±¼\n"
-
-#~ msgid "Font Selection"
-#~ msgstr "¦r«¬¿ï¾Ü"
-
-#~ msgid "Used CUT_BUFFER0 instead of empty selection"
-#~ msgstr "¨Ï¥Î CUT_BUFFER0 ¨Ó¨ú¥NªÅ¿ï¾Ü"
-
-#~ msgid "Filter"
-#~ msgstr "¹LÂo¾¹"
-
-#~ msgid "Directories"
-#~ msgstr "¥Ø¿ý"
-
-#~ msgid "Help"
-#~ msgstr "»²§U»¡©ú"
-
-#~ msgid "Files"
-#~ msgstr "ÀÉ®×"
-
-#~ msgid "Selection"
-#~ msgstr "¿ï¾Ü"
-
-#~ msgid "Undo"
-#~ msgstr "´_­ì"
-
-#~ msgid "E671: Cannot find window title \"%s\""
-#~ msgstr "E671: §ä¤£¨ì¼ÐÃD¬° \"%s\" ªºµøµ¡"
-
-#~ msgid "E243: Argument not supported: \"-%s\"; Use the OLE version."
-#~ msgstr "E243: ¤£¤ä´©°Ñ¼Æ \"-%s\"¡C½Ð¥Î OLE ª©¥»¡C"
-
-#~ msgid "E672: Unable to open window inside MDI application"
-#~ msgstr "E672: µLªk¦b MDI µ{¦¡¤¤¶}±Òµøµ¡"
-
-#~ msgid "Find string (use '\\\\' to find a '\\')"
-#~ msgstr "·j´M¦r¦ê (¨Ï¥Î '\\\\' ¨Óªí¥Ü '\\')"
-
-#~ msgid "Find & Replace (use '\\\\' to find a '\\')"
-#~ msgstr "·j´M¤Î¨ú¥N¦r¦ê (¨Ï¥Î '\\\\' ¨Óªí¥Ü '\\')"
-
-#~ msgid ""
-#~ "Vim E458: Cannot allocate colormap entry, some colors may be incorrect"
-#~ msgstr "Vim E458: µLªk°t¸m color map ¶µ¥Ø¡A¦³¨ÇÃC¦â¬Ý°_¨Ó·|©Ç©Çªº"
-
-#~ msgid "E250: Fonts for the following charsets are missing in fontset %s:"
-#~ msgstr "E250: Fontset %s ¨S¦³³]©w¥¿½Tªº¦r«¬¥H¨ÑÅã¥Ü³o¨Ç¦r¤¸¶°:"
-
-#~ msgid "E252: Fontset name: %s"
-#~ msgstr "E252: ¦r«¬¶°(Fontset)¦WºÙ: %s"
-
-#~ msgid "Font '%s' is not fixed-width"
-#~ msgstr "'%s' ¤£¬O©T©w¼e«×¦r«¬"
-
-#~ msgid "E253: Fontset name: %s\n"
-#~ msgstr "E253: ¦r«¬¶°(Fontset)¦WºÙ: %s\n"
-
-#~ msgid "Font0: %s\n"
-#~ msgstr "Font0: %s\n"
-
-#~ msgid "Font1: %s\n"
-#~ msgstr "Font1: %s\n"
-
-#~ msgid "Font%<PRId64> width is not twice that of font0\n"
-#~ msgstr "¦r«¬%<PRId64> ¼e«×¤£¬O ¦r«¬0 ªº¨â­¿\n"
-
-#~ msgid "Font0 width: %<PRId64>\n"
-#~ msgstr "¦r«¬0ªº¼e«×¡G%<PRId64>\n"
-
-#~ msgid ""
-#~ "Font1 width: %<PRId64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "¦r«¬1¼e«×: %<PRId64>\n"
-#~ "\n"
-
-#~ msgid "E256: Hangul automata ERROR"
-#~ msgstr "E256: Hangul automata ¿ù»~"
-
-#~ msgid "E563: stat error"
-#~ msgstr "E563: stat ¿ù»~"
-
-#~ msgid "E625: cannot open cscope database: %s"
-#~ msgstr "E625: µLªk¶}±Ò cscope ¸ê®Æ®w %s"
-
-#~ msgid "E626: cannot get cscope database information"
-#~ msgstr "E626: µLªk¨ú±o cscope ¸ê®Æ®w¸ê°T"
-
-#~ msgid "E569: maximum number of cscope connections reached"
-#~ msgstr "E569: ¤w¹F¨ì cscope ³Ì¤j³s½u¼Æ¥Ø"
-
-#~ msgid ""
-#~ "E263: Sorry, this command is disabled, the Python library could not be "
-#~ "loaded."
-#~ msgstr "E263: ©êºp¡A³o­Ó©R¥OµLªk¨Ï¥Î¡APython µ{¦¡®w¨S¦³¸ü¤J¡C"
-
-#~ msgid "E659: Cannot invoke Python recursively"
-#~ msgstr "E659: µLªk»¼°j°õ¦æ Python "
-
-#~ msgid "can't delete OutputObject attributes"
-#~ msgstr "µLªk§R°£ OutputObject ÄÝ©Ê"
-
-#~ msgid "softspace must be an integer"
-#~ msgstr "softspace ¥²»Ý¬O¾ã¼Æ"
-
-#~ msgid "invalid attribute"
-#~ msgstr "¤£¥¿½TªºÄÝ©Ê"
-
-#~ msgid "writelines() requires list of strings"
-#~ msgstr "writelines() »Ý­n string list ·í°Ñ¼Æ"
-
-#~ msgid "E264: Python: Error initialising I/O objects"
-#~ msgstr "E264: Python: µLªkªì©l I/O ª«¥ó"
-
-#~ msgid "invalid expression"
-#~ msgstr "¤£¥¿½Tªº¹Bºâ¦¡"
-
-#~ msgid "expressions disabled at compile time"
-#~ msgstr "¦]¬°½sͮɍS¦³¥[¤J¹Bºâ¦¡(expression)ªºµ{¦¡½X¡A©Ò¥HµLªk¨Ï¥Î¹Bºâ¦¡"
-
-#~ msgid "attempt to refer to deleted buffer"
-#~ msgstr "¸Õ¹Ï¨Ï¥Î¤w³Q§R°£ªº buffer"
-
-#~ msgid "line number out of range"
-#~ msgstr "¦æ¸¹¶W¥X½d³ò"
-
-#~ msgid "<buffer object (deleted) at %8lX>"
-#~ msgstr "<buffer ª«¥ó (¤w§R°£): %8lX>"
-
-#~ msgid "invalid mark name"
-#~ msgstr "¼Ð°O¦WºÙ¤£¥¿½T"
-
-#~ msgid "no such buffer"
-#~ msgstr "µL¦¹ buffer"
-
-#~ msgid "attempt to refer to deleted window"
-#~ msgstr "¸Õ¹Ï¨Ï¥Î¤w³Q§R°£ªºµøµ¡"
-
-#~ msgid "readonly attribute"
-#~ msgstr "°ßŪÄÝ©Ê"
-
-#~ msgid "cursor position outside buffer"
-#~ msgstr "´å¼Ð©w¦ì¦b½w½Ä°Ï¤§¥~"
-
-#~ msgid "<window object (deleted) at %.8lX>"
-#~ msgstr "<µøµ¡ª«¥ó(¤w§R°£): %.8lX>"
-
-#~ msgid "<window object (unknown) at %.8lX>"
-#~ msgstr "<µøµ¡ª«¥ó(¥¼ª¾): %.8lX>"
-
-#~ msgid "<window %d>"
-#~ msgstr "<µøµ¡ %d>"
-
-#~ msgid "no such window"
-#~ msgstr "µL¦¹µøµ¡"
-
-#~ msgid "cannot save undo information"
-#~ msgstr "µLªkÀx¦s´_­ì¸ê°T"
-
-#~ msgid "cannot delete line"
-#~ msgstr "¤£¯à§R°£¦¹¦æ "
-
-#~ msgid "cannot replace line"
-#~ msgstr "¤£¯à´À¥N¦¹¦æ "
-
-#~ msgid "cannot insert line"
-#~ msgstr "¤£¯à´À¥N´¡¤J¦¹¦æ "
-
-#~ msgid "string cannot contain newlines"
-#~ msgstr "¦r¦êµLªk¥]§t·s¦æ "
-
-#~ msgid ""
-#~ "E266: Sorry, this command is disabled, the Ruby library could not be "
-#~ "loaded."
-#~ msgstr "E266: ¦¹©R¥OµLªk¨Ï¥Î¡AµLªk¸ü¤J Ruby µ{¦¡®w(Library)"
-
-#~ msgid "E273: unknown longjmp status %d"
-#~ msgstr "E273: ¥¼ª¾ªº longjmp status %d"
-
-#~ msgid "Toggle implementation/definition"
-#~ msgstr "¤Á´«¹ê§@/©w¸q"
-
-#~ msgid "Show base class of"
-#~ msgstr "Åã¥Ü base class of:"
-
-#~ msgid "Show overridden member function"
-#~ msgstr "Åã¥Ü³Q override ªº member function"
-
-#~ msgid "Retrieve from file"
-#~ msgstr "Ū¨ú: ±qÀÉ®×"
-
-#~ msgid "Retrieve from project"
-#~ msgstr "Ū¨ú: ±qª«¥ó"
-
-#~ msgid "Retrieve from all projects"
-#~ msgstr "Ū¨ú: ±q©Ò¦³ project"
-
-#~ msgid "Retrieve"
-#~ msgstr "Ū¨ú"
-
-#~ msgid "Show source of"
-#~ msgstr "Åã¥Ü­ì©l½X: "
-
-#~ msgid "Find symbol"
-#~ msgstr "·j´M symbol"
-
-#~ msgid "Browse class"
-#~ msgstr "ÂsÄý class"
-
-#~ msgid "Show class in hierarchy"
-#~ msgstr "Åã¥Ü¶¥¼h¦¡ªº class"
-
-#~ msgid "Show class in restricted hierarchy"
-#~ msgstr "Åã¥Ü restricted ¶¥¼h¦¡ªº class"
-
-#~ msgid "Xref refers to"
-#~ msgstr "Xref °Ñ¦Ò¨ì"
-
-#~ msgid "Xref referred by"
-#~ msgstr "Xref ³Q½Ö°Ñ¦Ò:"
-
-#~ msgid "Xref has a"
-#~ msgstr "Xref ¦³"
-
-#~ msgid "Xref used by"
-#~ msgstr "Xref ³Q½Ö¨Ï¥Î:"
-
-#~ msgid "Show docu of"
-#~ msgstr "Åã¥Ü¤å¥ó: "
-
-#~ msgid "Generate docu for"
-#~ msgstr "²£¥Í¤å¥ó: "
-
-#~ msgid ""
-#~ "Cannot connect to SNiFF+. Check environment (sniffemacs must be found in "
-#~ "$PATH).\n"
-#~ msgstr ""
-#~ "µLªk³s½u¨ì SNiFF+¡C½ÐÀˬdÀô¹ÒÅÜ¼Æ ($PATH ¸Ì¥²»Ý¥i¥H§ä¨ì sniffemacs)\n"
-
-#~ msgid "E274: Sniff: Error during read. Disconnected"
-#~ msgstr "E274: Sniff: Ū¨ú¿ù»~. ¨ú®ø³s½u"
-
-#~ msgid "SNiFF+ is currently "
-#~ msgstr "SNiFF+ ¥Ø«e"
-
-#~ msgid "not "
-#~ msgstr "¥¼"
-
-#~ msgid "connected"
-#~ msgstr "³s½u¤¤"
-
-#~ msgid "E275: Unknown SNiFF+ request: %s"
-#~ msgstr "E275: ¤£¥¿½Tªº SNiff+ ©I¥s: %s"
-
-#~ msgid "E276: Error connecting to SNiFF+"
-#~ msgstr "E276: ³s½u¨ì SNiFF+ ¥¢±Ñ"
-
-#~ msgid "E278: SNiFF+ not connected"
-#~ msgstr "E278: ¥¼³s½u¨ì SNiFF+"
-
-#~ msgid "Sniff: Error during write. Disconnected"
-#~ msgstr "Sniff: ¼g¤J¿ù»~¡Cµ²§ô³s½u"
-
-#~ msgid "not implemented yet"
-#~ msgstr "©|¥¼¹ê§@"
-
-#~ msgid "unknown option"
-#~ msgstr "¤£¥¿½Tªº¿ï¶µ"
-
-#~ msgid "cannot set line(s)"
-#~ msgstr "¤£¯à³]©w¦æ "
-
-#~ msgid "mark not set"
-#~ msgstr "¨S¦³³]©w¼Ð°O"
-
-#~ msgid "row %d column %d"
-#~ msgstr "¦C %d ¦æ %d"
-
-#~ msgid "cannot insert/append line"
-#~ msgstr "¤£¯à´¡¤J©Îªþ¥[¦¹¦æ "
-
-#~ msgid "unknown flag: "
-#~ msgstr "¿ù»~ªººX¼Ð: "
-
-#~ msgid "unknown vimOption"
-#~ msgstr "¤£¥¿½Tªº VIM ¿ï¶µ"
-
-#~ msgid "keyboard interrupt"
-#~ msgstr "Áä½L¤¤Â_"
-
-#~ msgid "vim error"
-#~ msgstr "vim ¿ù»~"
-
-#~ msgid "cannot create buffer/window command: object is being deleted"
-#~ msgstr "µLªk«Ø¥ß½w½Ä°Ï/µøµ¡©R¥O: ª«¥ó±N·|³Q§R°£"
-
-#~ msgid ""
-#~ "cannot register callback command: buffer/window is already being deleted"
-#~ msgstr "µLªkµù¥U callback ©R¥O: ½w½Ä°Ï/µøµ¡¤w¸g³Q§R°£¤F"
-
-#~ msgid ""
-#~ "E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-"
-#~ "dev@vim.org"
-#~ msgstr "E280: TCL ÄY­«¿ù»~: reflist Äê±¼¤F!? ½Ð³ø§iµ¹ to vim-dev@vim.org"
-
-#~ msgid "cannot register callback command: buffer/window reference not found"
-#~ msgstr "µLªkµù¥U callback ©R¥O: §ä¤£¨ì½w½Ä°Ï/µøµ¡"
-
-#~ msgid ""
-#~ "E571: Sorry, this command is disabled: the Tcl library could not be "
-#~ "loaded."
-#~ msgstr "E571: ¦¹©R¥OµLªk¨Ï¥Î, ¦]¬°µLªk¸ü¤J Tcl µ{¦¡®w(Library)"
-
-#~ msgid ""
-#~ "E281: TCL ERROR: exit code is not int!? Please report this to vim-dev@vim."
-#~ "org"
-#~ msgstr "E281: TCL ¿ù»~: µ²§ô½X¤£¬O¾ã¼Æ!? ½Ð³ø§iµ¹ to vim-dev@vim.org"
-
-#~ msgid "cannot get line"
-#~ msgstr "¤£¯à¨ú±o¦¹¦æ "
-
-#~ msgid "Unable to register a command server name"
-#~ msgstr "µLªkµù¥U©R¥O¦øªA¾¹¦WºÙ"
-
-#~ msgid "E248: Failed to send command to the destination program"
-#~ msgstr "E248: µLªk°e¥X©R¥O¨ì¥Øªº¦aµ{¦¡"
-
-#~ msgid "E251: VIM instance registry property is badly formed. Deleted!"
-#~ msgstr "E251: VIM ªº registry ³]©w¶µ¦³»~¡C¤w§R°£¡C"
-
-#~ msgid "This Vim was not compiled with the diff feature."
-#~ msgstr "±zªº Vim ½sͮɍS¦³¥[¤J diff ªº¯à¤O"
-
-#~ msgid "-register\t\tRegister this gvim for OLE"
-#~ msgstr "-register\t\tµù¥U gvim ¨ì OLE"
-
-#~ msgid "-unregister\t\tUnregister gvim for OLE"
-#~ msgstr "-unregister\t\t¨ú®ø OLE ¤¤ªº gvim µù¥U"
-
-#~ msgid "-g\t\t\tRun using GUI (like \"gvim\")"
-#~ msgstr "-g\t\t\t¨Ï¥Î¹Ï§Î¬É­± (¦P \"gvim\")"
-
-#~ msgid "-f or --nofork\tForeground: Don't fork when starting GUI"
-#~ msgstr "-f ©Î --nofork\t«e´º: °_©l¹Ï§Î¬É­±®É¤£ fork"
-
-#~ msgid "-V[N]\t\tVerbose level"
-#~ msgstr "-V[N]\t\tVerbose µ¥¯Å"
-
-#~ msgid "-f\t\t\tDon't use newcli to open window"
-#~ msgstr "-f\t\t\t¤£¨Ï¥Î newcli ¨Ó¶}±Òµøµ¡"
-
-#~ msgid "-dev <device>\t\tUse <device> for I/O"
-#~ msgstr "-dev <device>\t\t¨Ï¥Î <device> °µ¿é¥X¤J"
-
-#~ msgid "-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc"
-#~ msgstr "-U <gvimrc>\t\t¨Ï¥Î <gvimrc> ¨ú¥N¥ô¦ó .gvimrc"
-
-#~ msgid "-x\t\t\tEdit encrypted files"
-#~ msgstr "-x\t\t\t½s¿è½s½X¹LªºÀÉ®×"
-
-#~ msgid "-display <display>\tConnect vim to this particular X-server"
-#~ msgstr "-display <display>\t±N vim »P«ü©wªº X-server ³s½u"
-
-#~ msgid "-X\t\t\tDo not connect to X server"
-#~ msgstr "-X\t\t\t¤£­n³s½u¨ì X Server"
-
-#~ msgid "--remote <files>\tEdit <files> in a Vim server if possible"
-#~ msgstr "--remote <files>\t½s¿è Vim ¦øªA¾¹¤Wªº <files> «áÂ÷¶}"
-
-#~ msgid "--remote-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-silent <files> ¬Û¦P¡A¦ý¨S¦³¦øªA¾¹®É¤£Äµ§i"
-
-#~ msgid ""
-#~ "--remote-wait <files> As --remote but wait for files to have been edited"
-#~ msgstr "--remote-wait <files> ¦P --remote, ¦ý·|µ¥­ÔÀÉ®×§¹¦¨½s¿è"
-
-#~ msgid ""
-#~ "--remote-wait-silent <files> Same, don't complain if there is no server"
-#~ msgstr "--remote-wait-silent <files> ¬Û¦P¡A¦ý¨S¦øªA¾¹®É¤£Äµ§i"
-
-#~ msgid "--remote-send <keys>\tSend <keys> to a Vim server and exit"
-#~ msgstr "--remote-send <keys>\t°e¥X <keys> ¨ì Vim ¦øªA¾¹¨ÃÂ÷¶}"
-
-#~ msgid ""
-#~ "--remote-expr <expr>\tEvaluate <expr> in a Vim server and print result"
-#~ msgstr "--remote-expr <expr>\t¦b¦øªA¾¹¤W°õ¦æ <expr> ¨Ã¦L¥Xµ²ªG"
-
-#~ msgid "--serverlist\t\tList available Vim server names and exit"
-#~ msgstr "--serverlist\t\t¦C¥X¥i¥Îªº Vim ¦øªA¾¹¦WºÙ¨ÃÂ÷¶}"
-
-#~ msgid "--servername <name>\tSend to/become the Vim server <name>"
-#~ msgstr "--servername <name>\t°e¦Ü/¦¨¬° Vim ¦øªA¾¹ <name>"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Motif version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim »{±oªº°Ñ¼Æ (Motif ª©):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (neXtaw version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim »{±oªº°Ñ¼Æ (neXtaw ª©):\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (Athena version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim »{±oªº°Ñ¼Æ (Athena ª©):\n"
-
-#~ msgid "-display <display>\tRun vim on <display>"
-#~ msgstr "-display <display>\t¦bµøµ¡ <display> °õ¦æ vim"
-
-#~ msgid "-iconic\t\tStart vim iconified"
-#~ msgstr "-iconic\t\t±Ò°Ê«á¹Ï¥Ü¤Æ(iconified)"
-
-#~ msgid "-name <name>\t\tUse resource as if vim was <name>"
-#~ msgstr "-name <name>\t\tŪ¨ú Resource ®É§â vim ªº¦WºÙµø¬° <name>"
-
-#~ msgid "\t\t\t (Unimplemented)\n"
-#~ msgstr "\t\t\t (©|¥¼¹ê§@)\n"
-
-#~ msgid "-background <color>\tUse <color> for the background (also: -bg)"
-#~ msgstr "-background <color>\t³]©w <color> ¬°­I´º¦â (¤]¥i¥Î -bg)"
-
-#~ msgid "-foreground <color>\tUse <color> for normal text (also: -fg)"
-#~ msgstr "-foreground <color>\t³]©w <color> ¬°¤@¯ë¤å¦rÃC¦â (¤]¥i¥Î -fg)"
-
-#~ msgid "-font <font>\t\tUse <font> for normal text (also: -fn)"
-#~ msgstr "-font <font>\t¨Ï¥Î <font> ¬°¤@¯ë¦r«¬ (¤]¥i¥Î -fn)"
-
-#~ msgid "-boldfont <font>\tUse <font> for bold text"
-#~ msgstr "-boldfont <font>\t¨Ï¥Î <font> ¬°²ÊÅé¦r«¬"
-
-#~ msgid "-italicfont <font>\tUse <font> for italic text"
-#~ msgstr "-italicfont <font>\t¨Ï¥Î <font> ¬°±×Åé¦r«¬"
-
-#~ msgid "-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"
-#~ msgstr "-geometry <geom>\t¨Ï¥Î<geom>¬°°_©l¦ì¸m (¤]¥i¥Î -geom)"
-
-#~ msgid "-borderwidth <width>\tUse a border width of <width> (also: -bw)"
-#~ msgstr "-borderwidth <width>\t¨Ï¥Î¼e«×¬° <width> ªºÃ䮨 (¤]¥i¥Î -bw)"
-
-#~ msgid ""
-#~ "-scrollbarwidth <width> Use a scrollbar width of <width> (also: -sw)"
-#~ msgstr "-scrollbarwidth <width> ³]©w±²°Ê¶b¼e«×¬° <width> (¤]¥i¥Î -sw)"
-
-#~ msgid "-menuheight <height>\tUse a menu bar height of <height> (also: -mh)"
-#~ msgstr "-menuheight <height>\t³]©w¿ï³æ¦Cªº°ª«×¬° <height> (¤]¥i¥Î -mh)"
-
-#~ msgid "-reverse\t\tUse reverse video (also: -rv)"
-#~ msgstr "-reverse\t\t¨Ï¥Î¤Ï¬ÛÅã¥Ü (¤]¥i¥Î -rv)"
-
-#~ msgid "+reverse\t\tDon't use reverse video (also: +rv)"
-#~ msgstr "+reverse\t\t¤£¨Ï¥Î¤Ï¬ÛÅã¥Ü (¤]¥i¥Î +rv)"
-
-#~ msgid "-xrm <resource>\tSet the specified resource"
-#~ msgstr "-xrm <resource>\t³]©w«ü©wªº resource"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (RISC OS version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim »{±oªº°Ñ¼Æ (RISC OS ª©):\n"
-
-#~ msgid "--columns <number>\tInitial width of window in columns"
-#~ msgstr "--columns <number>\tµøµ¡ªì©l¤Æ¼e«×"
-
-#~ msgid "--rows <number>\tInitial height of window in rows"
-#~ msgstr "--rows <number>\tµøµ¡ªì©l¤Æ°ª«×"
-
-#~ msgid ""
-#~ "\n"
-#~ "Arguments recognised by gvim (GTK+ version):\n"
-#~ msgstr ""
-#~ "\n"
-#~ "gvim »{±oªº°Ñ¼Æ (GTK+ ª©):\n"
-
-#~ msgid "-display <display>\tRun vim on <display> (also: --display)"
-#~ msgstr "-display <display>\t¦b <display> °õ¦æ vim (¤]¥i¥Î --display)"
-
-#~ msgid "--role <role>\tSet a unique role to identify the main window"
-#~ msgstr "--role <role>\t³]©w¿W¯Sªº¨¤¦â(role)¥H°Ï¤À¥Dµøµ¡"
-
-#~ msgid "--socketid <xid>\tOpen Vim inside another GTK widget"
-#~ msgstr "--socketid <xid>\t¦b¥t¤@­Ó GTK widget ¤º¶}±Ò Vim"
-
-#~ msgid "-P <parent title>\tOpen Vim inside parent application"
-#~ msgstr "-P <parent title>\t¦b¤÷µ{¦¡¤¤¶}±Ò Vim"
-
-#~ msgid "No display"
-#~ msgstr "µLÅã¥Ü"
-
-#~ msgid ": Send failed.\n"
-#~ msgstr ": ¶Ç°e¥¢±Ñ¡C\n"
-
-#~ msgid ": Send failed. Trying to execute locally\n"
-#~ msgstr ": °e¥X¥¢±Ñ¡C¸Õ¹Ï¦b¥»¦a°õ¦æ\n"
-
-#~ msgid "%d of %d edited"
-#~ msgstr "¤w½s¿è %d/%d ­ÓÀÉ®×"
-
-#~ msgid "No display: Send expression failed.\n"
-#~ msgstr "µL Display: µLªk¶Ç°e¹Bºâ¦¡¡C\n"
-
-#~ msgid ": Send expression failed.\n"
-#~ msgstr ": µLªk¶Ç°e¹Bºâ¦¡¡C\n"
-
-#~ msgid "E543: Not a valid codepage"
-#~ msgstr "E543: ¤£¥¿½Tªº codepage"
-
-#~ msgid "E285: Failed to create input context"
-#~ msgstr "E285: µLªk«Ø¥ß input context"
-
-#~ msgid "E286: Failed to open input method"
-#~ msgstr "E286: µLªk¶}±Ò¿é¤Jªk"
-
-#~ msgid "E287: Warning: Could not set destroy callback to IM"
-#~ msgstr "E287: ĵ§i: µLªk²¾°£ IM ªº callback"
-
-#~ msgid "E288: input method doesn't support any style"
-#~ msgstr "E288: ¿é¤Jªk¤£¤ä´©¥ô¦ó style"
-
-#~ msgid "E289: input method doesn't support my preedit type"
-#~ msgstr "E289: ¿é¤Jªk¤£¤ä´©¥ô¦ó style"
-
-#~ msgid "E290: over-the-spot style requires fontset"
-#~ msgstr "E290: over-the-spot »Ý­n¦r«¬¶°(Fontset)"
-
-#~ msgid "E291: Your GTK+ is older than 1.2.3. Status area disabled"
-#~ msgstr "E291: §Aªº GTK+ ¤ñ 1.2.3 ÁÙ¡CµLªk¨Ï¥Îª¬ºA°Ï¡C"
-
-#~ msgid "E292: Input Method Server is not running"
-#~ msgstr "E292: ¨S¦³°õ¦æ¤¤ªº¿é¤JªkºÞ²zµ{¦¡(Input Method Server)"
-
-#~ msgid ""
-#~ "\n"
-#~ " [not usable with this version of Vim]"
-#~ msgstr ""
-#~ "\n"
-#~ " [µLªk¦b¥»ª©¥»ªº Vim ¤W¨Ï¥Î]"
-
-#~ msgid ""
-#~ "&Open Read-Only\n"
-#~ "&Edit anyway\n"
-#~ "&Recover\n"
-#~ "&Quit\n"
-#~ "&Abort\n"
-#~ "&Delete it"
-#~ msgstr ""
-#~ "¥H°ßŪ¤è¦¡¶}±Ò(&O)\n"
-#~ "ª½±µ½s¿è(&E)\n"
-#~ "­×´_(&R)\n"
-#~ "Â÷¶}(&Q)\n"
-#~ "¸õ¥X(&A)\n"
-#~ "§R°£¼È¦sÀÉ(&D)"
-
-#~ msgid "Tear off this menu"
-#~ msgstr "¤Á¤U¦¹¿ï³æ"
-
-#~ msgid "[string too long]"
-#~ msgstr "[¦¹¦æ¹Lªø]"
-
-#~ msgid "Hit ENTER to continue"
-#~ msgstr "½Ð«ö ENTER Ä~Äò"
-
-#~ msgid " (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)"
-#~ msgstr " (RET/BS: ¦V¤U/¦V¤W¤@¦æ, ªÅ¥ÕÁä/b: ¤@­¶, d/u: ¥b­¶, q: Â÷¶})"
-
-#~ msgid " (RET: line, SPACE: page, d: half page, q: quit)"
-#~ msgstr " (RET: ¦V¤U¤@¦æ, ªÅ¥ÕÁä: ¤@­¶, d: ¥b­¶, q: Â÷¶})"
-
-#~ msgid "Save File dialog"
-#~ msgstr "¦sÀÉ"
-
-#~ msgid "Open File dialog"
-#~ msgstr "¶}ÀÉ"
-
-#~ msgid "E338: Sorry, no file browser in console mode"
-#~ msgstr "E338: ¥D±±¥x(Console)¼Ò¦¡®É¨S¦³ÀÉ®×ÂsÄý¾¹(file browser)"
-
-#~ msgid "Vim: preserving files...\n"
-#~ msgstr "Vim: «O¯dÀɮפ¤...\n"
-
-#~ msgid "Vim: Finished.\n"
-#~ msgstr "Vim: µ²§ô.\n"
-
-#~ msgid "ERROR: "
-#~ msgstr "¿ù»~: "
-
-#~ msgid ""
-#~ "\n"
-#~ "[bytes] total alloc-freed %<PRIu64>-%<PRIu64>, in use %<PRIu64>, peak use "
-#~ "%<PRIu64>\n"
-#~ msgstr ""
-#~ "\n"
-#~ "[bytes] ¥þ³¡ alloc-freed %<PRIu64>-%<PRIu64>, ¨Ï¥Î¤¤ %<PRIu64>, peak ¨Ï¥Î "
-#~ "%<PRIu64>\n"
-
-#~ msgid ""
-#~ "[calls] total re/malloc()'s %<PRIu64>, total free()'s %<PRIu64>\n"
-#~ "\n"
-#~ msgstr ""
-#~ "[©I¥s] ¥þ³¡ re/malloc(): %<PRIu64>, ¥þ³¡ free()': %<PRIu64>\n"
-#~ "\n"
-
-#~ msgid "E340: Line is becoming too long"
-#~ msgstr "E340: ¦¹¦æ¹Lªø"
-
-#~ msgid "E341: Internal error: lalloc(%<PRId64>, )"
-#~ msgstr "E341: ¤º³¡¿ù»~: lalloc(%<PRId64>, )"
-
-#~ msgid "E547: Illegal mouseshape"
-#~ msgstr "E547: ¤£¥¿½Tªº·Æ¹«§Îª¬"
-
-#~ msgid "Enter encryption key: "
-#~ msgstr "¿é¤J±K½X: "
-
-#~ msgid "Enter same key again: "
-#~ msgstr "½Ð¦A¿é¤J¤@¦¸: "
-
-#~ msgid "Keys don't match!"
-#~ msgstr "¨â¦¸¿é¤J±K½X¤£¬Û¦P!"
-
-#~ msgid "Cannot connect to Netbeans #2"
-#~ msgstr "µLªk³s±µ¨ì Netbeans #2"
-
-#~ msgid "Cannot connect to Netbeans"
-#~ msgstr "µLªk³s±µ¨ì Netbeans"
-
-#~ msgid "E668: Wrong access mode for NetBeans connection info file: \"%s\""
-#~ msgstr "E668: NetBeans ³s½u¸ê°TÀÉ®×: \"%s\" ¦s¨ú¼Ò¦¡¤£¥¿½T"
-
-#~ msgid "read from Netbeans socket"
-#~ msgstr "¥Ñ Netbeans socket Ū¨ú"
-
-#~ msgid "E658: NetBeans connection lost for buffer %<PRId64>"
-#~ msgstr "E658: ½w½Ä°Ï %<PRId64> »P NetBeans ªº³s½u¤w¤¤Â_"
-
-#~ msgid "freeing %<PRId64> lines"
-#~ msgstr "ÄÀ©ñ %<PRId64> ¦æ¤¤ "
-
-#~ msgid "E530: Cannot change term in GUI"
-#~ msgstr "E530: ¦b¹Ï«¬¬É­±¤¤µLªk¤Á´« term"
-
-#~ msgid "E531: Use \":gui\" to start the GUI"
-#~ msgstr "E531: ¿é¤J \":gui\" ¨Ó±Ò°Ê¹Ï§Î¬É­±"
-
-#~ msgid "E617: Cannot be changed in the GTK+ 2 GUI"
-#~ msgstr "E617: ¦b¹Ï«¬¬É­±¤¤µLªk¤Á´« term"
-
-#~ msgid "E597: can't select fontset"
-#~ msgstr "E597: µLªk¨Ï¥Î¦r«¬¶°(Fontset)"
-
-#~ msgid "E598: Invalid fontset"
-#~ msgstr "E598: ¤£¥¿½Tªº¦r«¬¶°(Fontset)"
-
-#~ msgid "E533: can't select wide font"
-#~ msgstr "E533: µLªk¨Ï¥Î³]©wªº¤¤¤å¦r«¬(Widefont)"
-
-#~ msgid "E534: Invalid wide font"
-#~ msgstr "E534: ¤£¥¿½Tªº¦r«¬(Widefont)"
-
-#~ msgid "E538: No mouse support"
-#~ msgstr "E538: ¤£¤ä´©·Æ¹«"
-
-#~ msgid "cannot open "
-#~ msgstr "¤£¯à¶}±Ò"
-
-#~ msgid "VIM: Can't open window!\n"
-#~ msgstr "VIM: µLªk¶}±Òµøµ¡!\n"
-
-#~ msgid "Need Amigados version 2.04 or later\n"
-#~ msgstr "»Ý­n Amigados ª©¥» 2.04 ¥H¤W\n"
-
-#~ msgid "Need %s version %<PRId64>\n"
-#~ msgstr "»Ý­n %s ª©¥» %<PRId64>\n"
-
-#~ msgid "Cannot open NIL:\n"
-#~ msgstr "µLªk¶}±Ò NIL:\n"
-
-#~ msgid "Cannot create "
-#~ msgstr "¤£¯à«Ø¥ß "
-
-#~ msgid "Vim exiting with %d\n"
-#~ msgstr "Vim µ²§ô¶Ç¦^­È: %d\n"
-
-#~ msgid "cannot change console mode ?!\n"
-#~ msgstr "µLªk¤Á´«¥D±±¥x(console)¼Ò¦¡ !?\n"
-
-#~ msgid "mch_get_shellsize: not a console??\n"
-#~ msgstr "mch_get_shellsize: ¤£¬O¥D±±¥x(console)??\n"
-
-#~ msgid "Cannot execute "
-#~ msgstr "¤£¯à°õ¦æ "
-
-#~ msgid "shell "
-#~ msgstr "shell "
-
-#~ msgid " returned\n"
-#~ msgstr " ¤wªð¦^\n"
-
-#~ msgid "ANCHOR_BUF_SIZE too small."
-#~ msgstr "ANCHOR_BUF_SIZE ¤Ó¤p"
-
-#~ msgid "I/O ERROR"
-#~ msgstr "I/O ¿ù»~"
-
-#~ msgid "...(truncated)"
-#~ msgstr "...(¤w¤Á±¼)"
-
-#~ msgid "'columns' is not 80, cannot execute external commands"
-#~ msgstr "'columns' ¤£¬O 80, µLªk°õ¦æ¥~³¡©R¥O"
-
-#~ msgid "to %s on %s"
-#~ msgstr "¨ì %s on %s"
-
-#~ msgid "E613: Unknown printer font: %s"
-#~ msgstr "E613: ¤£¥¿½Tªº¦Lªí¾÷¦r«¬: %s"
-
-#~ msgid "E238: Print error: %s"
-#~ msgstr "E238: ¦C¦L¿ù»~: %s"
-
-#~ msgid "Printing '%s'"
-#~ msgstr "¦C¦L¤¤: '%s'"
-
-#~ msgid "E244: Illegal charset name \"%s\" in font name \"%s\""
-#~ msgstr "E244: ¦r¤¸¶° \"%s\" µLªk¹ïÀ³¦r«¬\"%s\""
-
-#~ msgid "E245: Illegal char '%c' in font name \"%s\""
-#~ msgstr "E245: ¤£¥¿½Tªº¦r¤¸ '%c' ¥X²{¦b¦r«¬¦WºÙ \"%s\" ¤º"
-
-#~ msgid "Vim: Double signal, exiting\n"
-#~ msgstr "Vim: Âù­«signal, Â÷¶}¤¤\n"
-
-#~ msgid "Vim: Caught deadly signal %s\n"
-#~ msgstr "Vim: CVim: ÄdºI¨ì«H¸¹(signal) %s\n"
-
-#~ msgid "Vim: Caught deadly signal\n"
-#~ msgstr "Vim: ÄdºI¨ì­P©Rªº«H¸¹(deadly signale)\n"
-
-#~ msgid "Opening the X display took %<PRId64> msec"
-#~ msgstr "¶}±Ò X Window ¯Ó®É %<PRId64> msec"
-
-#~ msgid ""
-#~ "\n"
-#~ "Vim: Got X error\n"
-#~ msgstr ""
-#~ "\n"
-#~ "Vim: X ¿ù»~\n"
-
-#~ msgid "Testing the X display failed"
-#~ msgstr "´ú¸Õ X Window ¥¢±Ñ"
-
-#~ msgid "Opening the X display timed out"
-#~ msgstr "¶}±Ò X Window ¹O®É"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot execute shell sh\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¤£¯à°õ¦æ shell sh\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot create pipes\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¤£¯à«Ø¥ß pipe ºÞ½u\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Cannot fork\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¤£¯à fork\n"
-
-#~ msgid ""
-#~ "\n"
-#~ "Command terminated\n"
-#~ msgstr ""
-#~ "\n"
-#~ "©R¥O¤w²×µ²\n"
-
-#~ msgid "XSMP lost ICE connection"
-#~ msgstr "XSMP ¥¢¥h ICE ³s½u"
-
-#~ msgid "Opening the X display failed"
-#~ msgstr "¶}±Ò X Window ¥¢±Ñ"
-
-#~ msgid "XSMP handling save-yourself request"
-#~ msgstr "XSMP ¥¿¦b³B²z¦Û§ÚÀx¦s­n¨D"
-
-#~ msgid "XSMP opening connection"
-#~ msgstr "¶}±Ò XSMP ³s½u¤¤"
-
-#~ msgid "XSMP ICE connection watch failed"
-#~ msgstr "XSMP ICE ³s½uºÊ¬Ý¥¢±Ñ"
-
-#~ msgid "XSMP SmcOpenConnection failed: %s"
-#~ msgstr "XSMP SmcOpenConnection ¥¢±Ñ: %s"
-
-#~ msgid "At line"
-#~ msgstr "¦b¦æ¸¹ "
-
-#~ msgid "Could not allocate memory for command line."
-#~ msgstr "µLªk¬°©R¥O¦C°t¸m°O¾ÐÅé¡C"
-
-#~ msgid "VIM Error"
-#~ msgstr "VIM ¿ù»~"
-
-#~ msgid "Could not load vim32.dll!"
-#~ msgstr "µLªk¸ü¤J vim32.dll¡I"
-
-#~ msgid "Could not fix up function pointers to the DLL!"
-#~ msgstr "¤£¯à­×¥¿¨ç¦¡«ü¼Ð¨ì DLL!"
-
-#~ msgid "shell returned %d"
-#~ msgstr "Shell ¶Ç¦^­È %d"
-
-#~ msgid "Vim: Caught %s event\n"
-#~ msgstr "Vim: ÄdºI¨ì %s \n"
-
-#~ msgid "close"
-#~ msgstr "Ãö³¬"
-
-#~ msgid "logoff"
-#~ msgstr "µn¥X"
-
-#~ msgid "shutdown"
-#~ msgstr "Ãö¾÷"
-
-#~ msgid "E371: Command not found"
-#~ msgstr "E371: §ä¤£¨ì©R¥O"
-
-#~ 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 ""
-#~ "¦b§Aªº $PATH ¤¤§ä¤£¨ì VIMRUN.EXE.\n"
-#~ "¥~³¡©R¥O°õ¦æ§¹²¦«á±N¤£·|¼È°±.\n"
-#~ "¶i¤@¨B»¡©ú½Ð°õ¦æ :help win32-vimrun "
-
-#~ msgid "Vim Warning"
-#~ msgstr "Vim ĵ§i"
-
-#~ msgid "E56: %s* operand could be empty"
-#~ msgstr "E56: %s* ¹Bºâ¤¸¥i¥H¬OªÅªº"
-
-#~ msgid "E57: %s+ operand could be empty"
-#~ msgstr "E57: %s+ ¹Bºâ¤¸¥i¥H¬OªÅªº"
-
-#~ msgid "E58: %s{ operand could be empty"
-#~ msgstr "E58: %s{ ¹Bºâ¤¸¥i¥H¬OªÅªº"
-
-#~ msgid "E361: Crash intercepted; regexp too complex?"
-#~ msgstr "E361: µLªk°õ¦æ; regular expression ¤Ó½ÆÂø?"
-
-#~ msgid "E363: pattern caused out-of-stack error"
-#~ msgstr "E363: regular expression ³y¦¨°ïÅ|¥Î¥úªº¿ù»~"
-
-#~ msgid "E396: containedin argument not accepted here"
-#~ msgstr "E396: ¨Ï¥Î¤F¤£¥¿½Tªº°Ñ¼Æ"
-
-#~ msgid "Enter nr of choice (<CR> to abort): "
-#~ msgstr "¿é¤J nr ©Î¿ï¾Ü (<CR> Â÷¶}): "
-
-#~ msgid "E430: Tag file path truncated for %s\n"
-#~ msgstr "E430: Tag Àɮ׸ô®|³QºIÂ_¬° %s\n"
-
-#~ msgid "new shell started\n"
-#~ msgstr "°_°Ê·s shell\n"
-
-#~ msgid "No undo possible; continue anyway"
-#~ msgstr "µLªkÁÙ­ì¡F½ÐÄ~Äò§V¤O"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16/32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 16/32 Bit ¹Ï«¬¬É­±ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit GUI version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 Bit ¹Ï«¬¬É­±ª©¥»"
-
-#~ msgid " in Win32s mode"
-#~ msgstr "Win32s ¼Ò¦¡"
-
-#~ msgid " with OLE support"
-#~ msgstr "¤ä´© OLE"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 32-bit console version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 Bit console ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "MS-Windows 16-bit version"
-#~ msgstr ""
-#~ "\n"
-#~ "MS-Windows 32 Bit console ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "32-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "32 Bit MS-DOS ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "16-bit MS-DOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "16 Bit MS-DOS ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X (unix) version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X (unix) ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS X version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS X ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS version"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "RISC OS version"
-#~ msgstr ""
-#~ "\n"
-#~ "RISC OS ª©¥»"
-
-#~ msgid ""
-#~ "\n"
-#~ "Big version "
-#~ msgstr ""
-#~ "\n"
-#~ "¤j«¬ª©¥» "
-
-#~ msgid ""
-#~ "\n"
-#~ "Normal version "
-#~ msgstr ""
-#~ "\n"
-#~ "¤@¯ëª©¥» "
-
-#~ msgid ""
-#~ "\n"
-#~ "Small version "
-#~ msgstr ""
-#~ "\n"
-#~ "²©öª©¥» "
-
-#~ msgid ""
-#~ "\n"
-#~ "Tiny version "
-#~ msgstr ""
-#~ "\n"
-#~ "ºë²ª©¥» "
-
-#~ msgid "with GTK2-GNOME GUI."
-#~ msgstr "¨Ï¥Î GTK2-GNOME ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with GTK-GNOME GUI."
-#~ msgstr "¨Ï¥Î GTK-GNOME ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with GTK2 GUI."
-#~ msgstr "¨Ï¥Î GTK2 ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with GTK GUI."
-#~ msgstr "¨Ï¥Î GTK ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with X11-Motif GUI."
-#~ msgstr "¨Ï¥Î X11-Motif ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with X11-neXtaw GUI."
-#~ msgstr "¨Ï¥Î X11-neXtaw ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with X11-Athena GUI."
-#~ msgstr "¨Ï¥Î X11-Athena ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with BeOS GUI."
-#~ msgstr "¨Ï¥Î BeOS ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with Photon GUI."
-#~ msgstr "¨Ï¥ÎPhoton¹Ï«¬¬É­±¡C"
-
-#~ msgid "with GUI."
-#~ msgstr "¨Ï¥Î¹Ï«¬¬É­±¡C"
-
-#~ msgid "with Carbon GUI."
-#~ msgstr "¨Ï¥Î Carbon ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with Cocoa GUI."
-#~ msgstr "¨Ï¥Î Cocoa ¹Ï«¬¬É­±¡C"
-
-#~ msgid "with (classic) GUI."
-#~ msgstr "¨Ï¥Î (¶Ç²Î) ¹Ï«¬¬É­±¡C"
-
-#~ msgid " system gvimrc file: \""
-#~ msgstr " ¨t²Î gvimrc ÀÉ®×: \""
-
-#~ msgid " user gvimrc file: \""
-#~ msgstr " ¨Ï¥ÎªÌ­Ó¤H gvimrc ÀÉ: \""
-
-#~ msgid "2nd user gvimrc file: \""
-#~ msgstr " ²Ä¤G²Õ­Ó¤H gvimrc ÀÉ®×: \""
-
-#~ msgid "3rd user gvimrc file: \""
-#~ msgstr " ²Ä¤T²Õ­Ó¤H gvimrc ÀÉ®×: \""
-
-#~ msgid " system menu file: \""
-#~ msgstr " ¨t²Î¿ï³æ³]©wÀÉ: \""
-
-#~ msgid "Compiler: "
-#~ msgstr "½s;¹: "
-
-#~ msgid "menu Help->Orphans for information "
-#~ msgstr "¶i¤@¨B»¡©ú½Ð¿ï¨ú¿ï³æªº »²§U»¡©ú->¬@±Ï©t¨à"
-
-#~ msgid "Running modeless, typed text is inserted"
-#~ msgstr "°õ¦æ Modeless ¼Ò¦¡¡A¿é¤Jªº¤å¦r·|¦Û°Ê´¡¤J"
-
-#~ msgid "menu Edit->Global Settings->Toggle Insert Mode "
-#~ msgstr "¿ï¨ú¿ï³æªº¡u½s¿è¡v¡u¥þ°ì³]©w¡v¡u¤Á´«´¡¤J¼Ò¦¡¡v"
-
-#~ msgid " for two modes "
-#~ msgstr " ¨âºØ¼Ò¦¡ "
-
-#~ msgid "menu Edit->Global Settings->Toggle Vi Compatible"
-#~ msgstr "¿ï¨ú¿ï³æªº¡u½s¿è¡v¡u¥þ°ì³]©w¡v¡u¤Á´«¶Ç²ÎVi¬Û®e¼Ò¦¡¡v"
-
-#~ msgid " for Vim defaults "
-#~ msgstr " ¥H±o Vim ¹w³]­È "
-
-#~ msgid "WARNING: Windows 95/98/ME detected"
-#~ msgstr "ª`·N: °»´ú¨ì Windows 95/98/ME"
-
-#~ msgid "type :help windows95<Enter> for info on this"
-#~ msgstr "¦pªG»Ý­n¹ï Windows 95 ¤ä´©ªº§ó¦h¸ê°T½Ð¿é¤J :help windows95<Enter>"
-
-#~ msgid "E370: Could not load library %s"
-#~ msgstr "E370: µLªk­«·s¸ü¤Jµ{¦¡®w %s"
-
-#~ msgid ""
-#~ "Sorry, this command is disabled: the Perl library could not be loaded."
-#~ msgstr "©êºp, ¦¹©R¥OµLªk¨Ï¥Î. ­ì¦]: µLªk¸ü¤J Perl µ{¦¡®w(Library)"
-
-#~ msgid "E299: Perl evaluation forbidden in sandbox without the Safe module"
-#~ msgstr "E299: ¦b sandbox ¤¤µL Safe ¼Ò²Õ®ÉµLªk°õ¦æ Perl"
-
-#~ msgid "Edit with &multiple Vims"
-#~ msgstr "¨Ï¥Î¦h­Ó Vim session ½s¿è(&M)"
-
-#~ msgid "Edit with single &Vim"
-#~ msgstr "¥u¨Ï¥Î¦P¤@­Ó Vim session ½s¿è(&V)"
-
-#~ msgid "&Diff with Vim"
-#~ msgstr "¨Ï¥Î Vim ¨Ó¤ñ¸û(&Diff)"
-
-#~ msgid "Edit with &Vim"
-#~ msgstr "¨Ï¥Î Vim ½s¿è¦¹ÀÉ(&V)"
-
-#~ msgid "Edit with existing Vim - &"
-#~ msgstr "¨Ï¥Î°õ¦æ¤¤ªº Vim session ½s¿è - &"
-
-#~ msgid "Edits the selected file(s) with Vim"
-#~ msgstr "¨Ï¥Î Vim ½s¿è¤w¿ï¨úªºÀÉ®×"
-
-#~ msgid "Error creating process: Check if gvim is in your path!"
-#~ msgstr "µLªk°õ¦æµ{¦¡: ½ÐÀˬd gvim ¦³¨S¦³¦b§Aªº PATH ÅܼƸÌ!"
-
-#~ msgid "gvimext.dll error"
-#~ msgstr "gvimext.dll ¿ù»~"
-
-#~ msgid "Path length too long!"
-#~ msgstr "¸ô®|ªø«×¤Óªø!"
-
-#~ msgid "E234: Unknown fontset: %s"
-#~ msgstr "E234: ¤£¥¿½Tªº¦r¤¸¶° (Fontset): %s"
-
-#~ msgid "E235: Unknown font: %s"
-#~ msgstr "E235: ¤£¥¿½Tªº¦r«¬¦WºÙ: %s"
-
-#~ msgid "E448: Could not load library function %s"
-#~ msgstr "E448: µLªk¸ü¤Jµ{¦¡®wªº¨ç¦¡ %s"
-
-#~ msgid "E26: Hebrew cannot be used: Not enabled at compile time\n"
-#~ msgstr "E26: ¦]¬°½sͮɍS¦³¥[¤J Hebrew ªºµ{¦¡½X¡A©Ò¥HµLªk¨Ï¥Î Hebrew\n"
-
-#~ msgid "E27: Farsi cannot be used: Not enabled at compile time\n"
-#~ msgstr "E27: ¦]¬°½sͮɍS¦³¥[¤J Farsi ªºµ{¦¡½X¡A©Ò¥HµLªk¨Ï¥Î Farsi\n"
-
-#~ msgid "E800: Arabic cannot be used: Not enabled at compile time\n"
-#~ msgstr "E800: ¦]¬°½sͮɍS¦³¥[¤J Arabic ªºµ{¦¡½X¡A©Ò¥HµLªk¨Ï¥Î\n"
-
-#~ msgid "E247: no registered server named \"%s\""
-#~ msgstr "E247: ¨S¦³µù¥U¬° \"%s\" ªº¦øªA¾¹"
-
-#~ msgid "E233: cannot open display"
-#~ msgstr "E233: <¤£¯à¶}±Ò X Server DISPLAY>"
-
-#~ msgid "E463: Region is guarded, cannot modify"
-#~ msgstr "E463: °Ï°ì³Q«OÅ@¡AµLªk­×§ï"
-
-#~ msgid "E565: error reading cscope connection %d"
-#~ msgstr "E565: Ū¨ú cscope ³s½u %d ¿ù»~"
-
-#~ msgid "E260: cscope connection not found"
-#~ msgstr "E260: §ä¤£¨ì cscope ³s½u"
-
-#~ msgid "cscope connection closed"
-#~ msgstr "cscope ³s½u¤wÃö³¬"
-
-#~ msgid "couldn't malloc\n"
-#~ msgstr "µLªk¨Ï¥Î malloc\n"
-
-#~ msgid "%2d %-5ld %-34s <none>\n"
-#~ msgstr "%2d %-5ld %-34s <µL>\n"
-
-#~ msgid "\"\n"
-#~ msgstr "\"\n"
-
-#~ msgid "--help\t\tShow Gnome arguments"
-#~ msgstr "--help\t\tÅã¥Ü Gnome ¬ÛÃö°Ñ¼Æ"
-
-#~ msgid " BLOCK"
-#~ msgstr " °Ï¶ô"
-
-#~ msgid " LINE"
-#~ msgstr " ¦æ¿ï¨ú"
-
-#~ msgid "Linear tag search"
-#~ msgstr "½u©Ê·j´M¼ÐÅÒ (Tags)"
-
-#~ msgid "Binary tag search"
-#~ msgstr "¤G¤À·j´M(Binary search) ¼ÐÅÒ(Tags)"
-
-#~ msgid "function "
-#~ msgstr "¨ç¦¡ "
-
-#~ msgid "Run Macro"
-#~ msgstr "°õ¦æ¥¨¶°"
-
-#~ msgid "E242: Color name not recognized: %s"
-#~ msgstr "E242: %s ¬°µLªkÃѧOªºÃC¦â¦WºÙ"
-
-#~ msgid "error reading cscope connection %d"
-#~ msgstr "Ū¨ú cscope ³s½u %d ®É¿ù»~"
-
-#~ msgid "E249: couldn't read VIM instance registry property"
-#~ msgstr "E249: µLªkŪ¨ú VIM ªº registry ³]©w¶µ"
-
-#~ msgid "E241: Unable to send to Vim server"
-#~ msgstr "E241: µLªk¶Ç°e¨ì Vim ¦øªA¾¹"
-
-#~ msgid ""
-#~ "\n"
-#~ "Send failed. No command server present ?\n"
-#~ msgstr ""
-#~ "\n"
-#~ "¶Ç°e¥¢±Ñ¡C¨S¦³©R¥O¦øªA¾¹¦s¦b ?\n"
-
-#~ msgid "PC (32 bits Vim)"
-#~ msgstr "PC (32 ¦ì¤¸ Vim)"
-
-#~ msgid "PC (16 bits Vim)"
-#~ msgstr "PC (16 ¦ì¤¸ Vim)"
-
-#~ msgid "E362: Unsupported screen mode"
-#~ msgstr "E362: ¿Ã¹õ¼Ò¦¡¤£¤ä´©"
-
-#~ msgid "No servers found for this display"
-#~ msgstr "¦¹Display¨S¦³¦øªA¾¹(Servers)"
-
-#~ msgid "E258: no matches found in cscope connections"
-#~ msgstr "E258: cscope ³s½u§ä¤£¨ì²Å¦Xªº"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS Carbon"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS Carbon"
-
-#~ msgid ""
-#~ "\n"
-#~ "MacOS 8"
-#~ msgstr ""
-#~ "\n"
-#~ "MacOS 8"
-
-#~ msgid "Retrieve next symbol"
-#~ msgstr "Ū¨ú: ±q¤U­Ó symbol"
-
-#~ msgid "-- SNiFF+ commands --"
-#~ msgstr "-- SNiFF+ ©R¥O --"
-
-#~ msgid "E277: Unrecognized sniff request [%s]"
-#~ msgstr "E277: µLªk¿ëÃÑ sniff ©R¥O [%s]"
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index 5ad621e666..056770f2c0 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.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
+
/// @file popupmnu.c
///
/// Popup menu (PUM)
@@ -7,12 +10,12 @@
#include <stdbool.h>
#include "nvim/vim.h"
+#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/popupmnu.h"
#include "nvim/charset.h"
#include "nvim/ex_cmds.h"
#include "nvim/memline.h"
-#include "nvim/misc2.h"
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/screen.h"
@@ -21,6 +24,7 @@
#include "nvim/memory.h"
#include "nvim/window.h"
#include "nvim/edit.h"
+#include "nvim/ui.h"
static pumitem_T *pum_array = NULL; // items of displayed pum
static int pum_size; // nr of items in "pum_array"
@@ -36,8 +40,8 @@ static int pum_scrollbar; // TRUE when scrollbar present
static int pum_row; // top row of pum
static int pum_col; // left column of pum
-static int pum_do_redraw = FALSE; // do redraw anyway
-
+static bool pum_is_visible = false;
+static bool pum_external = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "popupmnu.c.generated.h"
@@ -53,7 +57,10 @@ static int pum_do_redraw = FALSE; // do redraw anyway
/// @param array
/// @param size
/// @param selected index of initially selected item, none if out of range
-void pum_display(pumitem_T *array, int size, int selected)
+/// @param array_changed if true, array contains different items since last call
+/// if false, a new item is selected, but the array
+/// is the same
+void pum_display(pumitem_T *array, int size, int selected, bool array_changed)
{
int w;
int def_width;
@@ -61,213 +68,250 @@ void pum_display(pumitem_T *array, int size, int selected)
int kind_width;
int extra_width;
int i;
- int top_clear;
- int row;
int context_lines;
- int col;
- int above_row = cmdline_row;
+ int above_row;
+ int below_row;
int redo_count = 0;
+ int row;
+ int col;
-redo:
- def_width = PUM_DEF_WIDTH;
- max_width = 0;
- kind_width = 0;
- extra_width = 0;
-
- // Pretend the pum is already there to avoid that must_redraw is set when
- // 'cuc' is on.
- pum_array = (pumitem_T *)1;
- validate_cursor_col();
- pum_array = NULL;
-
- row = curwin->w_wrow + curwin->w_winrow;
-
- if (firstwin->w_p_pvw) {
- top_clear = firstwin->w_height;
- } else {
- top_clear = 0;
- }
-
- // When the preview window is at the bottom stop just above it. Also
- // avoid drawing over the status line so that it's clear there is a window
- // boundary.
- if (lastwin->w_p_pvw) {
- above_row -= lastwin->w_height + lastwin->w_status_height + 1;
- }
-
- // Figure out the size and position of the pum.
- if (size < PUM_DEF_HEIGHT) {
- pum_height = size;
- } else {
- pum_height = PUM_DEF_HEIGHT;
- }
-
- if ((p_ph > 0) && (pum_height > p_ph)) {
- pum_height = (int)p_ph;
+ if (!pum_is_visible) {
+ // To keep the code simple, we only allow changing the
+ // draw mode when the popup menu is not being displayed
+ pum_external = ui_is_external(kUIPopupmenu);
}
- // Put the pum below "row" if possible. If there are few lines decide on
- // where there is more room.
- if ((row + 2 >= above_row - pum_height)
- && (row > (above_row - top_clear) / 2)) {
- // pum above "row"
+ do {
+ // Mark the pum as visible already here,
+ // to avoid that must_redraw is set when 'cursorcolumn' is on.
+ pum_is_visible = true;
+ validate_cursor_col();
+ above_row = 0;
+ below_row = cmdline_row;
- // Leave two lines of context if possible
- if (curwin->w_wrow - curwin->w_cline_row >= 2) {
- context_lines = 2;
+ // anchor position: the start of the completed word
+ row = curwin->w_wrow;
+ if (curwin->w_p_rl) {
+ col = curwin->w_width - curwin->w_wcol - 1;
} else {
- context_lines = curwin->w_wrow - curwin->w_cline_row;
+ col = curwin->w_wcol;
}
- if (row >= size + context_lines) {
- pum_row = row - size - context_lines;
- pum_height = size;
- } else {
- pum_row = 0;
- pum_height = row - context_lines;
+ int grid = (int)curwin->w_grid.handle;
+ if (!ui_is_external(kUIMultigrid)) {
+ grid = (int)default_grid.handle;
+ row += curwin->w_winrow;
+ col += curwin->w_wincol;
}
- if ((p_ph > 0) && (pum_height > p_ph)) {
- pum_row += pum_height - (int)p_ph;
- pum_height = (int)p_ph;
+ if (pum_external) {
+ if (array_changed) {
+ Array arr = ARRAY_DICT_INIT;
+ for (i = 0; i < size; i++) {
+ Array item = ARRAY_DICT_INIT;
+ ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_text)));
+ ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_kind)));
+ ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_extra)));
+ ADD(item, STRING_OBJ(cstr_to_string((char *)array[i].pum_info)));
+ ADD(arr, ARRAY_OBJ(item));
+ }
+ ui_call_popupmenu_show(arr, selected, row, col, grid);
+ } else {
+ ui_call_popupmenu_select(selected);
+ }
+ return;
}
- } else {
- // pum below "row"
- // Leave two lines of context if possible
- if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) {
- context_lines = 3;
- } else {
- context_lines = curwin->w_cline_row
- + curwin->w_cline_height - curwin->w_wrow;
+ def_width = PUM_DEF_WIDTH;
+ max_width = 0;
+ kind_width = 0;
+ extra_width = 0;
+
+ win_T *pvwin = NULL;
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_p_pvw) {
+ pvwin = wp;
+ break;
+ }
}
- pum_row = row + context_lines;
- if (size > above_row - pum_row) {
- pum_height = above_row - pum_row;
- } else {
+ if (pvwin != NULL) {
+ if (pvwin->w_winrow < curwin->w_winrow) {
+ above_row = pvwin->w_winrow + pvwin->w_height;
+ } else if (pvwin->w_winrow > curwin->w_winrow + curwin->w_height) {
+ below_row = pvwin->w_winrow;
+ }
+ }
+
+ // Figure out the size and position of the pum.
+ if (size < PUM_DEF_HEIGHT) {
pum_height = size;
+ } else {
+ pum_height = PUM_DEF_HEIGHT;
}
if ((p_ph > 0) && (pum_height > p_ph)) {
pum_height = (int)p_ph;
}
- }
- // don't display when we only have room for one line
- if ((pum_height < 1) || ((pum_height == 1) && (size > 1))) {
- return;
- }
+ // Put the pum below "row" if possible. If there are few lines decide on
+ // where there is more room.
+ if (row + 2 >= below_row - pum_height
+ && row - above_row > (below_row - above_row) / 2) {
+ // pum above "row"
- // If there is a preview window at the top avoid drawing over it.
- if (firstwin->w_p_pvw
- && (pum_row < firstwin->w_height)
- && (pum_height > firstwin->w_height + 4)) {
- pum_row += firstwin->w_height;
- pum_height -= firstwin->w_height;
- }
+ // Leave two lines of context if possible
+ if (curwin->w_wrow - curwin->w_cline_row >= 2) {
+ context_lines = 2;
+ } else {
+ context_lines = curwin->w_wrow - curwin->w_cline_row;
+ }
- // Compute the width of the widest match and the widest extra.
- for (i = 0; i < size; ++i) {
- w = vim_strsize(array[i].pum_text);
+ if (row >= size + context_lines) {
+ pum_row = row - size - context_lines;
+ pum_height = size;
+ } else {
+ pum_row = 0;
+ pum_height = row - context_lines;
+ }
- if (max_width < w) {
- max_width = w;
- }
+ if ((p_ph > 0) && (pum_height > p_ph)) {
+ pum_row += pum_height - (int)p_ph;
+ pum_height = (int)p_ph;
+ }
+ } else {
+ // pum below "row"
+
+ // Leave two lines of context if possible
+ if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) {
+ context_lines = 3;
+ } else {
+ context_lines = curwin->w_cline_row
+ + curwin->w_cline_height - curwin->w_wrow;
+ }
- if (array[i].pum_kind != NULL) {
- w = vim_strsize(array[i].pum_kind) + 1;
+ pum_row = row + context_lines;
+ if (size > below_row - pum_row) {
+ pum_height = below_row - pum_row;
+ } else {
+ pum_height = size;
+ }
- if (kind_width < w) {
- kind_width = w;
+ if ((p_ph > 0) && (pum_height > p_ph)) {
+ pum_height = (int)p_ph;
}
}
- if (array[i].pum_extra != NULL) {
- w = vim_strsize(array[i].pum_extra) + 1;
+ // don't display when we only have room for one line
+ if ((pum_height < 1) || ((pum_height == 1) && (size > 1))) {
+ return;
+ }
- if (extra_width < w) {
- extra_width = w;
+ // If there is a preview window above, avoid drawing over it.
+ // Do keep at least 10 entries.
+ if (pvwin != NULL && pum_row < above_row && pum_height > 10) {
+ if (row - above_row < 10) {
+ pum_row = row - 10;
+ pum_height = 10;
+ } else {
+ pum_row = above_row;
+ pum_height = row - above_row;
}
}
- }
- pum_base_width = max_width;
- pum_kind_width = kind_width;
- // Calculate column
- if (curwin->w_p_rl) {
- col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1;
- } else {
- col = curwin->w_wincol + curwin->w_wcol;
- }
+ // Compute the width of the widest match and the widest extra.
+ for (i = 0; i < size; i++) {
+ w = vim_strsize(array[i].pum_text);
- // if there are more items than room we need a scrollbar
- if (pum_height < size) {
- pum_scrollbar = 1;
- max_width++;
- } else {
- pum_scrollbar = 0;
- }
+ if (max_width < w) {
+ max_width = w;
+ }
- if (def_width < max_width) {
- def_width = max_width;
- }
+ if (array[i].pum_kind != NULL) {
+ w = vim_strsize(array[i].pum_kind) + 1;
- if ((((col < Columns - PUM_DEF_WIDTH) || (col < Columns - max_width))
- && !curwin->w_p_rl)
- || (curwin->w_p_rl && ((col > PUM_DEF_WIDTH) || (col > max_width)))) {
- // align pum column with "col"
- pum_col = col;
- if (curwin->w_p_rl) {
- pum_width = pum_col - pum_scrollbar + 1;
- } else {
- assert(Columns - pum_col - pum_scrollbar >= INT_MIN
- && Columns - pum_col - pum_scrollbar <= INT_MAX);
- pum_width = (int)(Columns - pum_col - pum_scrollbar);
- }
+ if (kind_width < w) {
+ kind_width = w;
+ }
+ }
- if ((pum_width > max_width + kind_width + extra_width + 1)
- && (pum_width > PUM_DEF_WIDTH)) {
- pum_width = max_width + kind_width + extra_width + 1;
+ if (array[i].pum_extra != NULL) {
+ w = vim_strsize(array[i].pum_extra) + 1;
- if (pum_width < PUM_DEF_WIDTH) {
- pum_width = PUM_DEF_WIDTH;
+ if (extra_width < w) {
+ extra_width = w;
+ }
}
}
- } else if (Columns < def_width) {
- // not enough room, will use what we have
- if (curwin->w_p_rl) {
- assert(Columns - 1 >= INT_MIN);
- pum_col = (int)(Columns - 1);
+ pum_base_width = max_width;
+ pum_kind_width = kind_width;
+
+ // if there are more items than room we need a scrollbar
+ if (pum_height < size) {
+ pum_scrollbar = 1;
+ max_width++;
} else {
- pum_col = 0;
+ pum_scrollbar = 0;
}
- assert(Columns - 1 >= INT_MIN);
- pum_width = (int)(Columns - 1);
- } else {
- if (max_width > PUM_DEF_WIDTH) {
- // truncate
- max_width = PUM_DEF_WIDTH;
+
+ if (def_width < max_width) {
+ def_width = max_width;
}
- if (curwin->w_p_rl) {
- pum_col = max_width - 1;
+ if ((((col < Columns - PUM_DEF_WIDTH) || (col < Columns - max_width))
+ && !curwin->w_p_rl)
+ || (curwin->w_p_rl && ((col > PUM_DEF_WIDTH) || (col > max_width)))) {
+ // align pum column with "col"
+ pum_col = col;
+ if (curwin->w_p_rl) {
+ pum_width = pum_col - pum_scrollbar + 1;
+ } else {
+ assert(Columns - pum_col - pum_scrollbar >= INT_MIN
+ && Columns - pum_col - pum_scrollbar <= INT_MAX);
+ pum_width = (int)(Columns - pum_col - pum_scrollbar);
+ }
+
+ if ((pum_width > max_width + kind_width + extra_width + 1)
+ && (pum_width > PUM_DEF_WIDTH)) {
+ pum_width = max_width + kind_width + extra_width + 1;
+
+ if (pum_width < PUM_DEF_WIDTH) {
+ pum_width = PUM_DEF_WIDTH;
+ }
+ }
+ } else if (Columns < def_width) {
+ // not enough room, will use what we have
+ if (curwin->w_p_rl) {
+ assert(Columns - 1 >= INT_MIN);
+ pum_col = (int)(Columns - 1);
+ } else {
+ pum_col = 0;
+ }
+ assert(Columns - 1 >= INT_MIN);
+ pum_width = (int)(Columns - 1);
} else {
- assert(Columns - max_width >= INT_MIN && Columns - max_width <= INT_MAX);
- pum_col = (int)(Columns - max_width);
+ if (max_width > PUM_DEF_WIDTH) {
+ // truncate
+ max_width = PUM_DEF_WIDTH;
+ }
+
+ if (curwin->w_p_rl) {
+ pum_col = max_width - 1;
+ } else {
+ assert(Columns - max_width >= INT_MIN
+ && Columns - max_width <= INT_MAX);
+ pum_col = (int)(Columns - max_width);
+ }
+ pum_width = max_width - pum_scrollbar;
}
- pum_width = max_width - pum_scrollbar;
- }
- pum_array = array;
- pum_size = size;
+ pum_array = array;
+ pum_size = size;
- // Set selected item and redraw. If the window size changed need to redo
- // the positioning. Limit this to two times, when there is not much
- // room the window size will keep changing.
- if (pum_set_selected(selected, redo_count) && (++redo_count <= 2)) {
- goto redo;
- }
+ // Set selected item and redraw. If the window size changed need to redo
+ // the positioning. Limit this to two times, when there is not much
+ // room the window size will keep changing.
+ } while (pum_set_selected(selected, redo_count) && (++redo_count <= 2));
}
/// Redraw the popup menu, using "pum_first" and "pum_selected".
@@ -275,10 +319,10 @@ void pum_redraw(void)
{
int row = pum_row;
int col;
- int attr_norm = highlight_attr[HLF_PNI];
- int attr_select = highlight_attr[HLF_PSI];
- int attr_scroll = highlight_attr[HLF_PSB];
- int attr_thumb = highlight_attr[HLF_PST];
+ int attr_norm = win_hl_attr(curwin, HLF_PNI);
+ int attr_select = win_hl_attr(curwin, HLF_PSI);
+ int attr_scroll = win_hl_attr(curwin, HLF_PSB);
+ int attr_thumb = win_hl_attr(curwin, HLF_PST);
int attr;
int i;
int idx;
@@ -309,13 +353,15 @@ void pum_redraw(void)
idx = i + pum_first;
attr = (idx == pum_selected) ? attr_select : attr_norm;
+ screen_puts_line_start(row);
+
// prepend a space if there is room
if (curwin->w_p_rl) {
if (pum_col < curwin->w_wincol + curwin->w_width - 1) {
- screen_putchar(' ', row, pum_col + 1, attr);
+ grid_putchar(&default_grid, ' ', row, pum_col + 1, attr);
}
} else if (pum_col > 0) {
- screen_putchar(' ', row, pum_col - 1, attr);
+ grid_putchar(&default_grid, ' ', row, pum_col - 1, attr);
}
// Display each entry, use two spaces for a Tab.
@@ -342,7 +388,7 @@ void pum_redraw(void)
}
if (p != NULL) {
- for (;; mb_ptr_adv(p)) {
+ for (;; MB_PTR_ADV(p)) {
if (s == NULL) {
s = p;
}
@@ -355,7 +401,7 @@ void pum_redraw(void)
char_u saved = *p;
*p = NUL;
- st = transstr(s);
+ st = (char_u *)transstr((const char *)s);
*p = saved;
if (curwin->w_p_rl) {
@@ -365,8 +411,8 @@ void pum_redraw(void)
if (size > pum_width) {
do {
- size -= has_mbyte ? (*mb_ptr2cells)(rt) : 1;
- mb_ptr_adv(rt);
+ size -= utf_ptr2cells(rt);
+ MB_PTR_ADV(rt);
} while (size > pum_width);
if (size < pum_width) {
@@ -377,12 +423,13 @@ void pum_redraw(void)
size++;
}
}
- screen_puts_len(rt, (int)STRLEN(rt), row, col - size + 1, attr);
+ grid_puts_len(&default_grid, rt, (int)STRLEN(rt), row,
+ col - size + 1, attr);
xfree(rt_start);
xfree(st);
col -= width;
} else {
- screen_puts_len(st, (int)STRLEN(st), row, col, attr);
+ grid_puts_len(&default_grid, st, (int)STRLEN(st), row, col, attr);
xfree(st);
col += width;
}
@@ -393,10 +440,11 @@ void pum_redraw(void)
// Display two spaces for a Tab.
if (curwin->w_p_rl) {
- screen_puts_len((char_u *)" ", 2, row, col - 1, attr);
+ grid_puts_len(&default_grid, (char_u *)" ", 2, row, col - 1,
+ attr);
col -= 2;
} else {
- screen_puts_len((char_u *)" ", 2, row, col, attr);
+ grid_puts_len(&default_grid, (char_u *)" ", 2, row, col, attr);
col += 2;
}
totwidth += 2;
@@ -427,35 +475,37 @@ void pum_redraw(void)
}
if (curwin->w_p_rl) {
- screen_fill(row, row + 1, pum_col - pum_base_width - n + 1,
- col + 1, ' ', ' ', attr);
+ grid_fill(&default_grid, row, row + 1, pum_col - pum_base_width - n + 1,
+ col + 1, ' ', ' ', attr);
col = pum_col - pum_base_width - n + 1;
} else {
- screen_fill(row, row + 1, col, pum_col + pum_base_width + n,
- ' ', ' ', attr);
+ grid_fill(&default_grid, row, row + 1, col,
+ pum_col + pum_base_width + n, ' ', ' ', attr);
col = pum_col + pum_base_width + n;
}
totwidth = pum_base_width + n;
}
if (curwin->w_p_rl) {
- screen_fill(row, row + 1, pum_col - pum_width + 1, col + 1, ' ', ' ',
- attr);
+ grid_fill(&default_grid, row, row + 1, pum_col - pum_width + 1, col + 1,
+ ' ', ' ', attr);
} else {
- screen_fill(row, row + 1, col, pum_col + pum_width, ' ', ' ', attr);
+ grid_fill(&default_grid, row, row + 1, col, pum_col + pum_width, ' ', ' ',
+ attr);
}
if (pum_scrollbar > 0) {
if (curwin->w_p_rl) {
- screen_putchar(' ', row, pum_col - pum_width,
- i >= thumb_pos && i < thumb_pos + thumb_heigth
- ? attr_thumb : attr_scroll);
+ grid_putchar(&default_grid, ' ', row, pum_col - pum_width,
+ i >= thumb_pos && i < thumb_pos + thumb_heigth
+ ? attr_thumb : attr_scroll);
} else {
- screen_putchar(' ', row, pum_col + pum_width,
- i >= thumb_pos && i < thumb_pos + thumb_heigth
- ? attr_thumb : attr_scroll);
+ grid_putchar(&default_grid, ' ', row, pum_col + pum_width,
+ i >= thumb_pos && i < thumb_pos + thumb_heigth
+ ? attr_thumb : attr_scroll);
}
}
+ grid_puts_line_flush(&default_grid, false);
row++;
}
}
@@ -535,6 +585,7 @@ static int pum_set_selected(int n, int repeat)
&& (repeat <= 1)
&& (vim_strchr(p_cot, 'p') != NULL)) {
win_T *curwin_save = curwin;
+ tabpage_T *curtab_save = curtab;
int res = OK;
// Open a preview window. 3 lines by default. Prefer
@@ -554,12 +605,14 @@ static int pum_set_selected(int n, int repeat)
g_do_tagpreview = 0;
if (curwin->w_p_pvw) {
- if ((curbuf->b_fname == NULL)
+ if (!resized
+ && (curbuf->b_nwindows == 1)
+ && (curbuf->b_fname == NULL)
&& (curbuf->b_p_bt[0] == 'n')
&& (curbuf->b_p_bt[2] == 'f')
&& (curbuf->b_p_bh[0] == 'w')) {
// Already a "wipeout" buffer, make it empty.
- while (!bufempty()) {
+ while (!BUFEMPTY()) {
ml_delete((linenr_T)1, FALSE);
}
} else {
@@ -571,13 +624,10 @@ static int pum_set_selected(int n, int repeat)
if (res == OK) {
// Edit a new, empty buffer. Set options for a "wipeout"
// buffer.
- set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
- set_option_value((char_u *)"bt", 0L,
- (char_u *)"nofile", OPT_LOCAL);
- set_option_value((char_u *)"bh", 0L,
- (char_u *)"wipe", OPT_LOCAL);
- set_option_value((char_u *)"diff", 0L,
- NULL, OPT_LOCAL);
+ set_option_value("swf", 0L, NULL, OPT_LOCAL);
+ set_option_value("bt", 0L, "nofile", OPT_LOCAL);
+ set_option_value("bh", 0L, "wipe", OPT_LOCAL);
+ set_option_value("diff", 0L, NULL, OPT_LOCAL);
}
}
@@ -616,7 +666,12 @@ static int pum_set_selected(int n, int repeat)
curwin->w_cursor.lnum = 1;
curwin->w_cursor.col = 0;
- if ((curwin != curwin_save) && win_valid(curwin_save)) {
+ if ((curwin != curwin_save && win_valid(curwin_save))
+ || (curtab != curtab_save && valid_tabpage(curtab_save))) {
+ if (curtab != curtab_save && valid_tabpage(curtab_save)) {
+ goto_tabpage_tp(curtab_save, false, false);
+ }
+
// When the first completion is done and the preview
// window is not resized, skip the preview window's
// status line redrawing.
@@ -641,9 +696,9 @@ static int pum_set_selected(int n, int repeat)
// Update the screen before drawing the popup menu.
// Enable updating the status lines.
- pum_do_redraw = TRUE;
+ pum_is_visible = false;
update_screen(0);
- pum_do_redraw = FALSE;
+ pum_is_visible = true;
if (!resized && win_valid(curwin_save)) {
no_u_sync++;
@@ -653,9 +708,9 @@ static int pum_set_selected(int n, int repeat)
// May need to update the screen again when there are
// autocommands involved.
- pum_do_redraw = TRUE;
+ pum_is_visible = false;
update_screen(0);
- pum_do_redraw = FALSE;
+ pum_is_visible = true;
}
}
}
@@ -672,10 +727,16 @@ static int pum_set_selected(int n, int repeat)
/// Undisplay the popup menu (later).
void pum_undisplay(void)
{
+ pum_is_visible = false;
pum_array = NULL;
- redraw_all_later(SOME_VALID);
- redraw_tabline = TRUE;
- status_redraw_all();
+
+ if (pum_external) {
+ ui_call_popupmenu_hide();
+ } else {
+ redraw_all_later(SOME_VALID);
+ redraw_tabline = true;
+ status_redraw_all();
+ }
}
/// Clear the popup menu. Currently only resets the offset to the first
@@ -685,12 +746,16 @@ void pum_clear(void)
pum_first = 0;
}
-/// Overruled when "pum_do_redraw" is set, used to redraw the status lines.
-///
-/// @return TRUE if the popup menu is displayed.
-int pum_visible(void)
+/// @return true if the popup menu is displayed.
+bool pum_visible(void)
+{
+ return pum_is_visible;
+}
+
+/// @return true if the popup menu is displayed and drawn on the grid.
+bool pum_drawn(void)
{
- return !pum_do_redraw && pum_array != NULL;
+ return pum_visible() && !pum_external;
}
/// Gets the height of the menu.
diff --git a/src/nvim/popupmnu.h b/src/nvim/popupmnu.h
index 2b181f2c4a..7e1588dbdd 100644
--- a/src/nvim/popupmnu.h
+++ b/src/nvim/popupmnu.h
@@ -1,6 +1,8 @@
#ifndef NVIM_POPUPMNU_H
#define NVIM_POPUPMNU_H
+#include "nvim/types.h"
+
/// Used for popup menu items.
typedef struct {
char_u *pum_text; // main menu text
diff --git a/src/nvim/pos.h b/src/nvim/pos.h
index 864f3fe866..0a2afd5847 100644
--- a/src/nvim/pos.h
+++ b/src/nvim/pos.h
@@ -2,14 +2,18 @@
#define NVIM_POS_H
typedef long linenr_T; // line number type
+/// Format used to print values which have linenr_T type
+#define PRIdLINENR "ld"
/// Column number type
typedef int colnr_T;
/// Format used to print values which have colnr_T type
#define PRIdCOLNR "d"
-#define MAXLNUM 0x7fffffff // maximum (invalid) line number
-#define MAXCOL 0x7fffffff // maximum column number, 31 bits
+/// Maximal (invalid) line number
+enum { MAXLNUM = 0x7fffffff };
+/// Maximal column number, 31 bits
+enum { MAXCOL = 0x7fffffff };
/*
* position in file or buffer
diff --git a/src/nvim/profile.c b/src/nvim/profile.c
index 97d7d77359..8fb8e92add 100644
--- a/src/nvim/profile.c
+++ b/src/nvim/profile.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 <stdio.h>
#include <math.h>
#include <assert.h>
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index dfd795b0ba..4eeddf1d5a 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.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
+
/*
* quickfix.c: functions for quickfix mode, using a file with error messages
*/
@@ -27,7 +30,6 @@
#include "nvim/memline.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/normal.h"
@@ -49,8 +51,6 @@ struct dir_stack_T {
char_u *dirname;
};
-static struct dir_stack_T *dir_stack = NULL;
-
/*
* For each error the next struct is allocated and linked in a list.
*/
@@ -76,16 +76,34 @@ struct qfline_S {
*/
#define LISTCOUNT 10
+/// Quickfix/Location list definition
+///
+/// Usually the list contains one or more entries. But an empty list can be
+/// created using setqflist()/setloclist() with a title and/or user context
+/// information and entries can be added later using setqflist()/setloclist().
typedef struct qf_list_S {
- qfline_T *qf_start; /* pointer to the first error */
- qfline_T *qf_ptr; /* pointer to the current error */
- int qf_count; /* number of errors (0 means no error list) */
- int qf_index; /* current index in the error list */
- int qf_nonevalid; /* TRUE if not a single valid entry found */
- char_u *qf_title; /* title derived from the command that created
- * the error list */
+ unsigned qf_id; ///< Unique identifier for this list
+ qfline_T *qf_start; ///< pointer to the first error
+ qfline_T *qf_last; ///< pointer to the last error
+ qfline_T *qf_ptr; ///< pointer to the current error
+ int qf_count; ///< number of errors (0 means empty list)
+ int qf_index; ///< current index in the error list
+ int qf_nonevalid; ///< TRUE if not a single valid entry found
+ char_u *qf_title; ///< title derived from the command that created
+ ///< the error list or set by setqflist
+ typval_T *qf_ctx; ///< context set by setqflist/setloclist
+
+ struct dir_stack_T *qf_dir_stack;
+ char_u *qf_directory;
+ struct dir_stack_T *qf_file_stack;
+ char_u *qf_currfile;
+ bool qf_multiline;
+ bool qf_multiignore;
+ bool qf_multiscan;
} qf_list_T;
+/// Quickfix/Location list stack definition
+/// Contains a list of quickfix/location lists (qf_list_T)
struct qf_info_S {
/*
* Count of references to this list. Used only for location lists.
@@ -99,7 +117,8 @@ struct qf_info_S {
qf_list_T qf_lists[LISTCOUNT];
};
-static qf_info_T ql_info; /* global quickfix list */
+static qf_info_T ql_info; // global quickfix list
+static unsigned last_qf_id = 0; // Last Used quickfix list id
#define FMT_PATTERNS 10 /* maximum number of % recognized */
@@ -130,6 +149,42 @@ struct efm_S {
int conthere; /* %> used */
};
+enum {
+ QF_FAIL = 0,
+ QF_OK = 1,
+ QF_END_OF_INPUT = 2,
+ QF_NOMEM = 3,
+ QF_IGNORE_LINE = 4
+};
+
+typedef struct {
+ char_u *linebuf;
+ size_t linelen;
+ char_u *growbuf;
+ size_t growbufsiz;
+ FILE *fd;
+ typval_T *tv;
+ char_u *p_str;
+ list_T *p_list;
+ listitem_T *p_li;
+ buf_T *buf;
+ linenr_T buflnum;
+ linenr_T lnumlast;
+ vimconv_T vc;
+} qfstate_T;
+
+typedef struct {
+ char_u *namebuf;
+ char_u *errmsg;
+ size_t errmsglen;
+ long lnum;
+ int col;
+ bool use_viscol;
+ char_u *pattern;
+ int enr;
+ char_u type;
+ bool valid;
+} qffields_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "quickfix.c.generated.h"
@@ -144,19 +199,24 @@ struct efm_S {
*/
#define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist)
-/*
- * Read the errorfile "efile" into memory, line by line, building the error
- * list. Set the error list's title to qf_title.
- * Return -1 for error, number of errors for success.
- */
-int
-qf_init (
- win_T *wp,
- char_u *efile,
- char_u *errorformat,
- int newlist, /* TRUE: start a new error list */
- char_u *qf_title
-)
+// Looking up a buffer can be slow if there are many. Remember the last one
+// to make this a lot faster if there are multiple matches in the same file.
+static char_u *qf_last_bufname = NULL;
+static bufref_T qf_last_bufref = { NULL, 0, 0 };
+
+/// Read the errorfile "efile" into memory, line by line, building the error
+/// list. Set the error list's title to qf_title.
+///
+/// @params wp If non-NULL, make a location list
+/// @params efile If non-NULL, errorfile to parse
+/// @params errorformat 'errorformat' string used to parse the error lines
+/// @params newlist If true, create a new error list
+/// @params qf_title If non-NULL, title of the error list
+/// @params enc If non-NULL, encoding used to parse errors
+///
+/// @returns -1 for error, number of errors for success.
+int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist,
+ char_u *qf_title, char_u *enc)
{
qf_info_T *qi = &ql_info;
@@ -164,645 +224,985 @@ qf_init (
qi = ll_get_or_alloc_list(wp);
}
- return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist,
- (linenr_T)0, (linenr_T)0,
- qf_title);
+ return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat,
+ newlist, (linenr_T)0, (linenr_T)0, qf_title, enc);
}
-/*
- * Read the errorfile "efile" into memory, line by line, building the error
- * list.
- * Alternative: when "efile" is null read errors from buffer "buf".
- * Always use 'errorformat' from "buf" if there is a local value.
- * Then "lnumfirst" and "lnumlast" specify the range of lines to use.
- * Set the title of the list to "qf_title".
- * Return -1 for error, number of errors for success.
- */
-static int
-qf_init_ext (
- qf_info_T *qi,
- char_u *efile,
- buf_T *buf,
- typval_T *tv,
- char_u *errorformat,
- int newlist, /* TRUE: start a new error list */
- linenr_T lnumfirst, /* first line number to use */
- linenr_T lnumlast, /* last line number to use */
- char_u *qf_title
-)
-{
- char_u *namebuf;
- char_u *errmsg;
- char_u *pattern;
- char_u *fmtstr = NULL;
- int col = 0;
- bool use_viscol = false;
- char_u type = 0;
- linenr_T buflnum = lnumfirst;
- long lnum = 0L;
- int enr = 0;
- FILE *fd = NULL;
- qfline_T *qfprev = NULL; /* init to make SASC shut up */
- char_u *efmp;
- efm_T *fmt_first = NULL;
- efm_T *fmt_last = NULL;
- efm_T *fmt_ptr;
- efm_T *fmt_start = NULL;
- char_u *efm;
- char_u *ptr;
- char_u *srcptr;
- int len;
- int i;
- int round;
- int idx = 0;
- bool multiline = false;
- bool multiignore = false;
- bool multiscan = false;
- int retval = -1; // default: return error flag
- char_u *directory = NULL;
- char_u *currfile = NULL;
- char_u *tail = NULL;
- char_u *p_str = NULL;
- listitem_T *p_li = NULL;
- struct dir_stack_T *file_stack = NULL;
- regmatch_T regmatch;
- static struct fmtpattern {
- char_u convchar;
- char *pattern;
- } fmt_pat[FMT_PATTERNS] =
- {
- {'f', ".\\+"}, /* only used when at end */
- {'n', "\\d\\+"},
- {'l', "\\d\\+"},
- {'c', "\\d\\+"},
- {'t', "."},
- {'m', ".\\+"},
- {'r', ".*"},
- {'p', "[- .]*"},
- {'v', "\\d\\+"},
- {'s', ".\\+"}
- };
-
- namebuf = xmalloc(CMDBUFFSIZE + 1);
- errmsg = xmalloc(CMDBUFFSIZE + 1);
- pattern = xmalloc(CMDBUFFSIZE + 1);
-
- if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL) {
- EMSG2(_(e_openerrf), efile);
- goto qf_init_end;
- }
-
- if (newlist || qi->qf_curlist == qi->qf_listcount)
- /* make place for a new list */
- qf_new_list(qi, qf_title);
- else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
- /* Adding to existing list, find last entry. */
- for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
- qfprev->qf_next != qfprev; qfprev = qfprev->qf_next)
- ;
-
- /*
- * Each part of the format string is copied and modified from errorformat to
- * regex prog. Only a few % characters are allowed.
- */
- /* Use the local value of 'errorformat' if it's set. */
- if (errorformat == p_efm && tv == NULL && *buf->b_p_efm != NUL)
- efm = buf->b_p_efm;
- else
- efm = errorformat;
- /*
- * Get some space to modify the format string into.
- */
- size_t fmtstr_size = 3 * FMT_PATTERNS + 4 * STRLEN(efm);
- for (round = FMT_PATTERNS; round > 0; ) {
- fmtstr_size += STRLEN(fmt_pat[--round].pattern);
- }
-#ifdef COLON_IN_FILENAME
- fmtstr_size += 12; // "%f" can become twelve chars longer
-#else
- fmtstr_size += 2; // "%f" can become two chars longer
-#endif
- fmtstr = xmalloc(fmtstr_size);
+// Maximum number of bytes allowed per line while reading an errorfile.
+static const size_t LINE_MAXLEN = 4096;
- while (efm[0] != NUL) {
- /*
- * Allocate a new eformat structure and put it at the end of the list
- */
- fmt_ptr = xcalloc(1, sizeof(efm_T));
- if (fmt_first == NULL) /* first one */
- fmt_first = fmt_ptr;
- else
- fmt_last->next = fmt_ptr;
- fmt_last = fmt_ptr;
-
- /*
- * Isolate one part in the 'errorformat' option
- */
- for (len = 0; efm[len] != NUL && efm[len] != ','; ++len)
- if (efm[len] == '\\' && efm[len + 1] != NUL)
- ++len;
+static struct fmtpattern
+{
+ char_u convchar;
+ char *pattern;
+} fmt_pat[FMT_PATTERNS] =
+{
+ { 'f', ".\\+" }, // only used when at end
+ { 'n', "\\d\\+" },
+ { 'l', "\\d\\+" },
+ { 'c', "\\d\\+" },
+ { 't', "." },
+ { 'm', ".\\+" },
+ { 'r', ".*" },
+ { 'p', "[- .]*" }, // NOLINT(whitespace/tab)
+ { 'v', "\\d\\+" },
+ { 's', ".\\+" }
+};
- /*
- * Build regexp pattern from current 'errorformat' option
- */
- ptr = fmtstr;
- *ptr++ = '^';
- round = 0;
- for (efmp = efm; efmp < efm + len; ++efmp) {
- if (*efmp == '%') {
- ++efmp;
- for (idx = 0; idx < FMT_PATTERNS; ++idx)
- if (fmt_pat[idx].convchar == *efmp)
- break;
- if (idx < FMT_PATTERNS) {
- if (fmt_ptr->addr[idx]) {
- sprintf((char *)errmsg,
- _("E372: Too many %%%c in format string"), *efmp);
- EMSG(errmsg);
- goto error2;
- }
- if ((idx
- && idx < 6
- && vim_strchr((char_u *)"DXOPQ",
- fmt_ptr->prefix) != NULL)
- || (idx == 6
- && vim_strchr((char_u *)"OPQ",
- fmt_ptr->prefix) == NULL)) {
- sprintf((char *)errmsg,
- _("E373: Unexpected %%%c in format string"), *efmp);
- EMSG(errmsg);
- goto error2;
- }
- fmt_ptr->addr[idx] = (char_u)++ round;
- *ptr++ = '\\';
- *ptr++ = '(';
+// Converts a 'errorformat' string to regular expression pattern
+static int efm_to_regpat(char_u *efm, int len, efm_T *fmt_ptr,
+ char_u *regpat, char_u *errmsg)
+{
+ // Build regexp pattern from current 'errorformat' option
+ char_u *ptr = regpat;
+ *ptr++ = '^';
+ int round = 0;
+ for (char_u *efmp = efm; efmp < efm + len; efmp++) {
+ if (*efmp == '%') {
+ efmp++;
+ int idx;
+ for (idx = 0; idx < FMT_PATTERNS; idx++) {
+ if (fmt_pat[idx].convchar == *efmp) {
+ break;
+ }
+ }
+ if (idx < FMT_PATTERNS) {
+ if (fmt_ptr->addr[idx]) {
+ snprintf((char *)errmsg, CMDBUFFSIZE + 1,
+ _("E372: Too many %%%c in format string"), *efmp);
+ EMSG(errmsg);
+ return -1;
+ }
+ if ((idx
+ && idx < 6
+ && vim_strchr((char_u *)"DXOPQ", fmt_ptr->prefix) != NULL)
+ || (idx == 6
+ && vim_strchr((char_u *)"OPQ", fmt_ptr->prefix) == NULL)) {
+ snprintf((char *)errmsg, CMDBUFFSIZE + 1,
+ _("E373: Unexpected %%%c in format string"), *efmp);
+ EMSG(errmsg);
+ return -1;
+ }
+ round++;
+ fmt_ptr->addr[idx] = (char_u)round;
+ *ptr++ = '\\';
+ *ptr++ = '(';
#ifdef BACKSLASH_IN_FILENAME
- if (*efmp == 'f') {
- /* Also match "c:" in the file name, even when
- * checking for a colon next: "%f:".
- * "\%(\a:\)\=" */
- STRCPY(ptr, "\\%(\\a:\\)\\=");
- ptr += 10;
- }
+ if (*efmp == 'f') {
+ // Also match "c:" in the file name, even when
+ // checking for a colon next: "%f:".
+ // "\%(\a:\)\="
+ STRCPY(ptr, "\\%(\\a:\\)\\=");
+ ptr += 10;
+ }
#endif
- if (*efmp == 'f' && efmp[1] != NUL) {
- if (efmp[1] != '\\' && efmp[1] != '%') {
- /* A file name may contain spaces, but this isn't
- * in "\f". For "%f:%l:%m" there may be a ":" in
- * the file name. Use ".\{-1,}x" instead (x is
- * the next character), the requirement that :999:
- * follows should work. */
- STRCPY(ptr, ".\\{-1,}");
- ptr += 7;
- } else {
- /* File name followed by '\\' or '%': include as
- * many file name chars as possible. */
- STRCPY(ptr, "\\f\\+");
- ptr += 4;
- }
+ if (*efmp == 'f' && efmp[1] != NUL) {
+ if (efmp[1] != '\\' && efmp[1] != '%') {
+ // A file name may contain spaces, but this isn't
+ // in "\f". For "%f:%l:%m" there may be a ":" in
+ // the file name. Use ".\{-1,}x" instead (x is
+ // the next character), the requirement that :999:
+ // follows should work.
+ STRCPY(ptr, ".\\{-1,}");
+ ptr += 7;
} else {
- srcptr = (char_u *)fmt_pat[idx].pattern;
- while ((*ptr = *srcptr++) != NUL)
- ++ptr;
+ // File name followed by '\\' or '%': include as
+ // many file name chars as possible.
+ STRCPY(ptr, "\\f\\+");
+ ptr += 4;
}
- *ptr++ = '\\';
- *ptr++ = ')';
- } else if (*efmp == '*') {
- if (*++efmp == '[' || *efmp == '\\') {
- if ((*ptr++ = *efmp) == '[') { /* %*[^a-z0-9] etc. */
- if (efmp[1] == '^')
- *ptr++ = *++efmp;
- if (efmp < efm + len) {
- *ptr++ = *++efmp; /* could be ']' */
- while (efmp < efm + len
- && (*ptr++ = *++efmp) != ']')
- /* skip */;
- if (efmp == efm + len) {
- EMSG(_("E374: Missing ] in format string"));
- goto error2;
+ } else {
+ char_u *srcptr = (char_u *)fmt_pat[idx].pattern;
+ while ((*ptr = *srcptr++) != NUL) {
+ ptr++;
+ }
+ }
+ *ptr++ = '\\';
+ *ptr++ = ')';
+ } else if (*efmp == '*') {
+ if (*++efmp == '[' || *efmp == '\\') {
+ if ((*ptr++ = *efmp) == '[') { // %*[^a-z0-9] etc.
+ if (efmp[1] == '^') {
+ *ptr++ = *++efmp;
+ }
+ if (efmp < efm + len) {
+ efmp++;
+ *ptr++ = *efmp; // could be ']'
+ while (efmp < efm + len) {
+ efmp++;
+ if ((*ptr++ = *efmp) == ']') {
+ break;
}
}
- } else if (efmp < efm + len) /* %*\D, %*\s etc. */
- *ptr++ = *++efmp;
- *ptr++ = '\\';
- *ptr++ = '+';
- } else {
- /* TODO: scanf()-like: %*ud, %*3c, %*f, ... ? */
- sprintf((char *)errmsg,
- _("E375: Unsupported %%%c in format string"), *efmp);
- EMSG(errmsg);
- goto error2;
- }
- } else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL)
- *ptr++ = *efmp; /* regexp magic characters */
- else if (*efmp == '#')
- *ptr++ = '*';
- else if (*efmp == '>')
- fmt_ptr->conthere = TRUE;
- else if (efmp == efm + 1) { /* analyse prefix */
- if (vim_strchr((char_u *)"+-", *efmp) != NULL)
- fmt_ptr->flags = *efmp++;
- if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL)
- fmt_ptr->prefix = *efmp;
- else {
- sprintf((char *)errmsg,
- _("E376: Invalid %%%c in format string prefix"), *efmp);
- EMSG(errmsg);
- goto error2;
+ if (efmp == efm + len) {
+ EMSG(_("E374: Missing ] in format string"));
+ return -1;
+ }
+ }
+ } else if (efmp < efm + len) { // %*\D, %*\s etc.
+ efmp++;
+ *ptr++ = *efmp;
}
+ *ptr++ = '\\';
+ *ptr++ = '+';
+ } else {
+ // TODO(vim): scanf()-like: %*ud, %*3c, %*f, ... ?
+ snprintf((char *)errmsg, CMDBUFFSIZE + 1,
+ _("E375: Unsupported %%%c in format string"), *efmp);
+ EMSG(errmsg);
+ return -1;
+ }
+ } else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL) {
+ *ptr++ = *efmp; // regexp magic characters
+ } else if (*efmp == '#') {
+ *ptr++ = '*';
+ } else if (*efmp == '>') {
+ fmt_ptr->conthere = true;
+ } else if (efmp == efm + 1) { // analyse prefix
+ if (vim_strchr((char_u *)"+-", *efmp) != NULL) {
+ fmt_ptr->flags = *efmp++;
+ }
+ if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL) {
+ fmt_ptr->prefix = *efmp;
} else {
- sprintf((char *)errmsg,
- _("E377: Invalid %%%c in format string"), *efmp);
+ snprintf((char *)errmsg, CMDBUFFSIZE + 1,
+ _("E376: Invalid %%%c in format string prefix"), *efmp);
EMSG(errmsg);
- goto error2;
+ return -1;
}
- } else { /* copy normal character */
- if (*efmp == '\\' && efmp + 1 < efm + len)
- ++efmp;
- else if (vim_strchr((char_u *)".*^$~[", *efmp) != NULL)
- *ptr++ = '\\'; /* escape regexp atoms */
- if (*efmp)
- *ptr++ = *efmp;
+ } else {
+ snprintf((char *)errmsg, CMDBUFFSIZE + 1,
+ _("E377: Invalid %%%c in format string"), *efmp);
+ EMSG(errmsg);
+ return -1;
+ }
+ } else { // copy normal character
+ if (*efmp == '\\' && efmp + 1 < efm + len) {
+ efmp++;
+ } else if (vim_strchr((char_u *)".*^$~[", *efmp) != NULL) {
+ *ptr++ = '\\'; // escape regexp atoms
+ }
+ if (*efmp) {
+ *ptr++ = *efmp;
}
}
- *ptr++ = '$';
- *ptr = NUL;
- if ((fmt_ptr->prog = vim_regcomp(fmtstr, RE_MAGIC + RE_STRING)) == NULL)
- goto error2;
- /*
- * Advance to next part
- */
- efm = skip_to_option_part(efm + len); /* skip comma and spaces */
}
- if (fmt_first == NULL) { /* nothing found */
+ *ptr++ = '$';
+ *ptr = NUL;
+
+ return 0;
+}
+
+static efm_T *fmt_start = NULL; // cached across qf_parse_line() calls
+
+static void free_efm_list(efm_T **efm_first)
+{
+ for (efm_T *efm_ptr = *efm_first; efm_ptr != NULL; efm_ptr = *efm_first) {
+ *efm_first = efm_ptr->next;
+ vim_regfree(efm_ptr->prog);
+ xfree(efm_ptr);
+ }
+
+ fmt_start = NULL;
+}
+
+// Parse 'errorformat' option
+static efm_T * parse_efm_option(char_u *efm)
+{
+ efm_T *fmt_ptr = NULL;
+ efm_T *fmt_first = NULL;
+ efm_T *fmt_last = NULL;
+ int len;
+
+ size_t errmsglen = CMDBUFFSIZE + 1;
+ char_u *errmsg = xmalloc(errmsglen);
+
+ // Get some space to modify the format string into.
+ size_t i = (FMT_PATTERNS * 3) + (STRLEN(efm) << 2);
+ for (int round = FMT_PATTERNS - 1; round >= 0; ) {
+ i += STRLEN(fmt_pat[round--].pattern);
+ }
+ i += 2; // "%f" can become two chars longer
+ char_u *fmtstr = xmalloc(i);
+
+ while (efm[0] != NUL) {
+ // Allocate a new eformat structure and put it at the end of the list
+ fmt_ptr = (efm_T *)xcalloc(1, sizeof(efm_T));
+ if (fmt_first == NULL) { // first one
+ fmt_first = fmt_ptr;
+ } else {
+ fmt_last->next = fmt_ptr;
+ }
+ fmt_last = fmt_ptr;
+
+ // Isolate one part in the 'errorformat' option
+ for (len = 0; efm[len] != NUL && efm[len] != ','; len++) {
+ if (efm[len] == '\\' && efm[len + 1] != NUL) {
+ len++;
+ }
+ }
+
+ if (efm_to_regpat(efm, len, fmt_ptr, fmtstr, errmsg) == -1) {
+ goto parse_efm_error;
+ }
+ if ((fmt_ptr->prog = vim_regcomp(fmtstr, RE_MAGIC + RE_STRING)) == NULL) {
+ goto parse_efm_error;
+ }
+ // Advance to next part
+ efm = skip_to_option_part(efm + len); // skip comma and spaces
+ }
+
+ if (fmt_first == NULL) { // nothing found
EMSG(_("E378: 'errorformat' contains no pattern"));
- goto error2;
}
- /*
- * got_int is reset here, because it was probably set when killing the
- * ":make" command, but we still want to read the errorfile then.
- */
- got_int = FALSE;
+ goto parse_efm_end;
- /* Always ignore case when looking for a matching error. */
- regmatch.rm_ic = TRUE;
+parse_efm_error:
+ free_efm_list(&fmt_first);
- if (tv != NULL) {
- if (tv->v_type == VAR_STRING)
- p_str = tv->vval.v_string;
- else if (tv->v_type == VAR_LIST)
- p_li = tv->vval.v_list->lv_first;
+parse_efm_end:
+ xfree(fmtstr);
+ xfree(errmsg);
+
+ return fmt_first;
+}
+
+static char_u *qf_grow_linebuf(qfstate_T *state, size_t newsz)
+{
+ // If the line exceeds LINE_MAXLEN exclude the last
+ // byte since it's not a NL character.
+ state->linelen = newsz > LINE_MAXLEN ? LINE_MAXLEN - 1 : newsz;
+ if (state->growbuf == NULL) {
+ state->growbuf = xmalloc(state->linelen + 1);
+ state->growbufsiz = state->linelen;
+ } else if (state->linelen > state->growbufsiz) {
+ state->growbuf = xrealloc(state->growbuf, state->linelen + 1);
+ state->growbufsiz = state->linelen;
}
+ return state->growbuf;
+}
- /*
- * Read the lines in the error file one by one.
- * Try to recognize one of the error formats in each line.
- */
- while (!got_int) {
- /* Get the next line. */
- if (fd == NULL) {
- if (tv != NULL) {
- if (tv->v_type == VAR_STRING) {
- /* Get the next line from the supplied string */
- char_u *p;
-
- if (!*p_str) /* Reached the end of the string */
- break;
+/// Get the next string (separated by newline) from state->p_str.
+static int qf_get_next_str_line(qfstate_T *state)
+{
+ // Get the next line from the supplied string
+ char_u *p_str = state->p_str;
+ char_u *p;
+ size_t len;
- p = vim_strchr(p_str, '\n');
- if (p)
- len = (int)(p - p_str + 1);
- else
- len = (int)STRLEN(p_str);
+ if (*p_str == NUL) { // Reached the end of the string
+ return QF_END_OF_INPUT;
+ }
- if (len > CMDBUFFSIZE - 2)
- STRLCPY(IObuff, p_str, CMDBUFFSIZE - 1);
- else
- STRLCPY(IObuff, p_str, len + 1);
+ p = vim_strchr(p_str, '\n');
+ if (p != NULL) {
+ len = (size_t)(p - p_str) + 1;
+ } else {
+ len = STRLEN(p_str);
+ }
+
+ if (len > IOSIZE - 2) {
+ state->linebuf = qf_grow_linebuf(state, len);
+ } else {
+ state->linebuf = IObuff;
+ state->linelen = len;
+ }
+ STRLCPY(state->linebuf, p_str, state->linelen + 1);
- p_str += len;
- } else if (tv->v_type == VAR_LIST) {
- /* Get the next line from the supplied list */
- while (p_li && p_li->li_tv.v_type != VAR_STRING)
- p_li = p_li->li_next; /* Skip non-string items */
+ // Increment using len in order to discard the rest of the line if it
+ // exceeds LINE_MAXLEN.
+ p_str += len;
+ state->p_str = p_str;
- if (!p_li) /* End of the list */
- break;
+ return QF_OK;
+}
+
+/// Get the next string from state->p_Li.
+static int qf_get_next_list_line(qfstate_T *state)
+{
+ listitem_T *p_li = state->p_li;
+ size_t len;
+
+ // Get the next line from the supplied list
+ while (p_li != NULL
+ && (TV_LIST_ITEM_TV(p_li)->v_type != VAR_STRING
+ || TV_LIST_ITEM_TV(p_li)->vval.v_string == NULL)) {
+ p_li = TV_LIST_ITEM_NEXT(state->p_list, p_li); // Skip non-string items.
+ }
+
+ if (p_li == NULL) { // End of the list.
+ state->p_li = NULL;
+ return QF_END_OF_INPUT;
+ }
+
+ len = STRLEN(TV_LIST_ITEM_TV(p_li)->vval.v_string);
+ if (len > IOSIZE - 2) {
+ state->linebuf = qf_grow_linebuf(state, len);
+ } else {
+ state->linebuf = IObuff;
+ state->linelen = len;
+ }
+
+ STRLCPY(state->linebuf, TV_LIST_ITEM_TV(p_li)->vval.v_string,
+ state->linelen + 1);
+
+ state->p_li = TV_LIST_ITEM_NEXT(state->p_list, p_li);
+ return QF_OK;
+}
+
+/// Get the next string from state->buf.
+static int qf_get_next_buf_line(qfstate_T *state)
+{
+ char_u *p_buf = NULL;
+ size_t len;
+
+ // Get the next line from the supplied buffer
+ if (state->buflnum > state->lnumlast) {
+ return QF_END_OF_INPUT;
+ }
+ p_buf = ml_get_buf(state->buf, state->buflnum, false);
+ state->buflnum += 1;
+
+ len = STRLEN(p_buf);
+ if (len > IOSIZE - 2) {
+ state->linebuf = qf_grow_linebuf(state, len);
+ } else {
+ state->linebuf = IObuff;
+ state->linelen = len;
+ }
+ STRLCPY(state->linebuf, p_buf, state->linelen + 1);
+
+ return QF_OK;
+}
+
+/// Get the next string from file state->fd.
+static int qf_get_next_file_line(qfstate_T *state)
+{
+ size_t growbuflen;
+
+retry:
+ errno = 0;
+ if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
+ if (errno == EINTR) {
+ goto retry;
+ }
+ return QF_END_OF_INPUT;
+ }
- len = (int)STRLEN(p_li->li_tv.vval.v_string);
- if (len > CMDBUFFSIZE - 2)
- len = CMDBUFFSIZE - 2;
+ bool discard = false;
+ state->linelen = STRLEN(IObuff);
+ if (state->linelen == IOSIZE - 1
+ && !(IObuff[state->linelen - 1] == '\n')) {
+ // The current line exceeds IObuff, continue reading using growbuf
+ // until EOL or LINE_MAXLEN bytes is read.
+ if (state->growbuf == NULL) {
+ state->growbufsiz = 2 * (IOSIZE - 1);
+ state->growbuf = xmalloc(state->growbufsiz);
+ }
- STRLCPY(IObuff, p_li->li_tv.vval.v_string, len + 1);
+ // Copy the read part of the line, excluding null-terminator
+ memcpy(state->growbuf, IObuff, IOSIZE - 1);
+ growbuflen = state->linelen;
- p_li = p_li->li_next; /* next item */
+ for (;;) {
+ errno = 0;
+ if (fgets((char *)state->growbuf + growbuflen,
+ (int)(state->growbufsiz - growbuflen), state->fd) == NULL) {
+ if (errno == EINTR) {
+ continue;
+ }
+ break;
+ }
+ state->linelen = STRLEN(state->growbuf + growbuflen);
+ growbuflen += state->linelen;
+ if (state->growbuf[growbuflen - 1] == '\n') {
+ break;
+ }
+ if (state->growbufsiz == LINE_MAXLEN) {
+ discard = true;
+ break;
+ }
+
+ state->growbufsiz = (2 * state->growbufsiz < LINE_MAXLEN)
+ ? 2 * state->growbufsiz : LINE_MAXLEN;
+ state->growbuf = xrealloc(state->growbuf, state->growbufsiz);
+ }
+
+ while (discard) {
+ // The current line is longer than LINE_MAXLEN, continue reading but
+ // discard everything until EOL or EOF is reached.
+ errno = 0;
+ if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
+ if (errno == EINTR) {
+ continue;
}
+ break;
+ }
+ if (STRLEN(IObuff) < IOSIZE - 1 || IObuff[IOSIZE - 1] == '\n') {
+ break;
+ }
+ }
+
+ state->linebuf = state->growbuf;
+ state->linelen = growbuflen;
+ } else {
+ state->linebuf = IObuff;
+ }
+
+ // Convert a line if it contains a non-ASCII character
+ if (state->vc.vc_type != CONV_NONE && has_non_ascii(state->linebuf)) {
+ char_u *line = string_convert(&state->vc, state->linebuf, &state->linelen);
+ if (line != NULL) {
+ if (state->linelen < IOSIZE) {
+ STRLCPY(state->linebuf, line, state->linelen + 1);
+ xfree(line);
} else {
- /* Get the next line from the supplied buffer */
- if (buflnum > lnumlast)
- break;
- STRLCPY(IObuff, ml_get_buf(buf, buflnum++, FALSE),
- CMDBUFFSIZE - 1);
+ xfree(state->growbuf);
+ state->linebuf = state->growbuf = line;
+ state->growbufsiz = state->linelen < LINE_MAXLEN
+ ? state->linelen : LINE_MAXLEN;
}
- } else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
- break;
+ }
+ }
+ return QF_OK;
+}
- IObuff[CMDBUFFSIZE - 2] = NUL; /* for very long lines */
- remove_bom(IObuff);
+/// Get the next string from a file/buffer/list/string.
+static int qf_get_nextline(qfstate_T *state)
+{
+ int status = QF_FAIL;
+
+ if (state->fd == NULL) {
+ if (state->tv != NULL) {
+ if (state->tv->v_type == VAR_STRING) {
+ // Get the next line from the supplied string
+ status = qf_get_next_str_line(state);
+ } else if (state->tv->v_type == VAR_LIST) {
+ // Get the next line from the supplied list
+ status = qf_get_next_list_line(state);
+ }
+ } else {
+ // Get the next line from the supplied buffer
+ status = qf_get_next_buf_line(state);
+ }
+ } else {
+ // Get the next line from the supplied file
+ status = qf_get_next_file_line(state);
+ }
- if ((efmp = vim_strrchr(IObuff, '\n')) != NULL)
- *efmp = NUL;
+ if (status != QF_OK) {
+ return status;
+ }
+
+ if (state->linelen > 0 && state->linebuf[state->linelen - 1] == '\n') {
+ state->linebuf[state->linelen - 1] = NUL;
#ifdef USE_CRNL
- if ((efmp = vim_strrchr(IObuff, '\r')) != NULL)
- *efmp = NUL;
+ if (state->linelen > 1 && state->linebuf[state->linelen - 2] == '\r') {
+ state->linebuf[state->linelen - 2] = NUL;
+ }
#endif
+ }
- /* If there was no %> item start at the first pattern */
- if (fmt_start == NULL)
- fmt_ptr = fmt_first;
- else {
- fmt_ptr = fmt_start;
- fmt_start = NULL;
- }
+ remove_bom(state->linebuf);
- // Try to match each part of 'errorformat' until we find a complete
- // match or no match.
- bool valid = true;
+ return QF_OK;
+}
+
+
+/// Parse a line and get the quickfix fields.
+/// Return the QF_ status.
+static int qf_parse_line(qf_info_T *qi, int qf_idx, char_u *linebuf,
+ size_t linelen, efm_T *fmt_first, qffields_T *fields)
+{
+ efm_T *fmt_ptr;
+ size_t len;
+ int i;
+ int idx = 0;
+ char_u *tail = NULL;
+ regmatch_T regmatch;
+ qf_list_T *qfl = &qi->qf_lists[qf_idx];
+
+ // Always ignore case when looking for a matching error.
+ regmatch.rm_ic = true;
+
+ // If there was no %> item start at the first pattern
+ if (fmt_start == NULL) {
+ fmt_ptr = fmt_first;
+ } else {
+ fmt_ptr = fmt_start;
+ fmt_start = NULL;
+ }
+
+ // Try to match each part of 'errorformat' until we find a complete
+ // match or no match.
+ fields->valid = true;
restofline:
- for (; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) {
- idx = fmt_ptr->prefix;
- if (multiscan && vim_strchr((char_u *)"OPQ", idx) == NULL)
+ for (; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) {
+ idx = fmt_ptr->prefix;
+ if (qfl->qf_multiscan && vim_strchr((char_u *)"OPQ", idx) == NULL) {
+ continue;
+ }
+ fields->namebuf[0] = NUL;
+ fields->pattern[0] = NUL;
+ if (!qfl->qf_multiscan) {
+ fields->errmsg[0] = NUL;
+ }
+ fields->lnum = 0;
+ fields->col = 0;
+ fields->use_viscol = false;
+ fields->enr = -1;
+ fields->type = 0;
+ tail = NULL;
+
+ regmatch.regprog = fmt_ptr->prog;
+ int r = vim_regexec(&regmatch, linebuf, (colnr_T)0);
+ fmt_ptr->prog = regmatch.regprog;
+ if (r) {
+ if ((idx == 'C' || idx == 'Z') && !qfl->qf_multiline) {
continue;
- namebuf[0] = NUL;
- pattern[0] = NUL;
- if (!multiscan)
- errmsg[0] = NUL;
- lnum = 0;
- col = 0;
- use_viscol = false;
- enr = -1;
- type = 0;
- tail = NULL;
-
- regmatch.regprog = fmt_ptr->prog;
- int r = vim_regexec(&regmatch, IObuff, (colnr_T)0);
- fmt_ptr->prog = regmatch.regprog;
- if (r) {
- if ((idx == 'C' || idx == 'Z') && !multiline) {
+ }
+ if (vim_strchr((char_u *)"EWI", idx) != NULL) {
+ fields->type = (char_u)idx;
+ } else {
+ fields->type = 0;
+ }
+ // Extract error message data from matched line.
+ // We check for an actual submatch, because "\[" and "\]" in
+ // the 'errorformat' may cause the wrong submatch to be used.
+ if ((i = (int)fmt_ptr->addr[0]) > 0) { // %f
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
continue;
}
- if (vim_strchr((char_u *)"EWI", idx) != NULL) {
- type = (char_u)idx;
- } else {
- type = 0;
+ // Expand ~/file and $HOME/file to full path.
+ char_u c = *regmatch.endp[i];
+ *regmatch.endp[i] = NUL;
+ expand_env(regmatch.startp[i], fields->namebuf, CMDBUFFSIZE);
+ *regmatch.endp[i] = c;
+
+ if (vim_strchr((char_u *)"OPQ", idx) != NULL
+ && !os_path_exists(fields->namebuf)) {
+ continue;
}
- // Extract error message data from matched line.
- // We check for an actual submatch, because "\[" and "\]" in
- // the 'errorformat' may cause the wrong submatch to be used.
- if ((i = (int)fmt_ptr->addr[0]) > 0) { // %f
- if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
- continue;
- }
- // Expand ~/file and $HOME/file to full path.
- char_u c = *regmatch.endp[i];
- *regmatch.endp[i] = NUL;
- expand_env(regmatch.startp[i], namebuf, CMDBUFFSIZE);
- *regmatch.endp[i] = c;
-
- if (vim_strchr((char_u *)"OPQ", idx) != NULL
- && !os_path_exists(namebuf)) {
- continue;
- }
+ }
+ if ((i = (int)fmt_ptr->addr[1]) > 0) { // %n
+ if (regmatch.startp[i] == NULL) {
+ continue;
}
- if ((i = (int)fmt_ptr->addr[1]) > 0) { /* %n */
- if (regmatch.startp[i] == NULL)
- continue;
- enr = (int)atol((char *)regmatch.startp[i]);
+ fields->enr = (int)atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[2]) > 0) { // %l
+ if (regmatch.startp[i] == NULL) {
+ continue;
}
- if ((i = (int)fmt_ptr->addr[2]) > 0) { /* %l */
- if (regmatch.startp[i] == NULL)
- continue;
- lnum = atol((char *)regmatch.startp[i]);
+ fields->lnum = atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[3]) > 0) { // %c
+ if (regmatch.startp[i] == NULL) {
+ continue;
}
- if ((i = (int)fmt_ptr->addr[3]) > 0) { /* %c */
- if (regmatch.startp[i] == NULL)
- continue;
- col = (int)atol((char *)regmatch.startp[i]);
+ fields->col = (int)atol((char *)regmatch.startp[i]);
+ }
+ if ((i = (int)fmt_ptr->addr[4]) > 0) { // %t
+ if (regmatch.startp[i] == NULL) {
+ continue;
}
- if ((i = (int)fmt_ptr->addr[4]) > 0) { /* %t */
- if (regmatch.startp[i] == NULL)
- continue;
- type = *regmatch.startp[i];
+ fields->type = *regmatch.startp[i];
+ }
+ if (fmt_ptr->flags == '+' && !qfl->qf_multiscan) { // %+
+ if (linelen >= fields->errmsglen) {
+ // linelen + null terminator
+ fields->errmsg = xrealloc(fields->errmsg, linelen + 1);
+ fields->errmsglen = linelen + 1;
}
- if (fmt_ptr->flags == '+' && !multiscan) /* %+ */
- STRCPY(errmsg, IObuff);
- else if ((i = (int)fmt_ptr->addr[5]) > 0) { /* %m */
- if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
- continue;
- len = (int)(regmatch.endp[i] - regmatch.startp[i]);
- STRLCPY(errmsg, regmatch.startp[i], len + 1);
+ STRLCPY(fields->errmsg, linebuf, linelen + 1);
+ } else if ((i = (int)fmt_ptr->addr[5]) > 0) { // %m
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
+ continue;
}
- if ((i = (int)fmt_ptr->addr[6]) > 0) { /* %r */
- if (regmatch.startp[i] == NULL)
- continue;
- tail = regmatch.startp[i];
+ len = (size_t)(regmatch.endp[i] - regmatch.startp[i]);
+ if (len >= fields->errmsglen) {
+ // len + null terminator
+ fields->errmsg = xrealloc(fields->errmsg, len + 1);
+ fields->errmsglen = len + 1;
}
- if ((i = (int)fmt_ptr->addr[7]) > 0) { /* %p */
- char_u *match_ptr;
+ STRLCPY(fields->errmsg, regmatch.startp[i], len + 1);
+ }
+ if ((i = (int)fmt_ptr->addr[6]) > 0) { // %r
+ if (regmatch.startp[i] == NULL) {
+ continue;
+ }
+ tail = regmatch.startp[i];
+ }
+ if ((i = (int)fmt_ptr->addr[7]) > 0) { // %p
+ char_u *match_ptr;
- if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
- continue;
- col = 0;
- for (match_ptr = regmatch.startp[i];
- match_ptr != regmatch.endp[i]; ++match_ptr) {
- ++col;
- if (*match_ptr == TAB) {
- col += 7;
- col -= col % 8;
- }
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
+ continue;
+ }
+ fields->col = 0;
+ for (match_ptr = regmatch.startp[i];
+ match_ptr != regmatch.endp[i]; match_ptr++) {
+ fields->col++;
+ if (*match_ptr == TAB) {
+ fields->col += 7;
+ fields->col -= fields->col % 8;
}
- col++;
- use_viscol = true;
}
- if ((i = (int)fmt_ptr->addr[8]) > 0) { /* %v */
- if (regmatch.startp[i] == NULL)
- continue;
- col = (int)atol((char *)regmatch.startp[i]);
- use_viscol = true;
+ fields->col++;
+ fields->use_viscol = true;
+ }
+ if ((i = (int)fmt_ptr->addr[8]) > 0) { // %v
+ if (regmatch.startp[i] == NULL) {
+ continue;
}
- if ((i = (int)fmt_ptr->addr[9]) > 0) { /* %s */
- if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL)
- continue;
- len = (int)(regmatch.endp[i] - regmatch.startp[i]);
- if (len > CMDBUFFSIZE - 5)
- len = CMDBUFFSIZE - 5;
- STRCPY(pattern, "^\\V");
- STRNCAT(pattern, regmatch.startp[i], len);
- pattern[len + 3] = '\\';
- pattern[len + 4] = '$';
- pattern[len + 5] = NUL;
+ fields->col = (int)atol((char *)regmatch.startp[i]);
+ fields->use_viscol = true;
+ }
+ if ((i = (int)fmt_ptr->addr[9]) > 0) { // %s
+ if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) {
+ continue;
}
- break;
+ len = (size_t)(regmatch.endp[i] - regmatch.startp[i]);
+ if (len > CMDBUFFSIZE - 5) {
+ len = CMDBUFFSIZE - 5;
+ }
+ STRCPY(fields->pattern, "^\\V");
+ xstrlcat((char *)fields->pattern, (char *)regmatch.startp[i],
+ CMDBUFFSIZE+1);
+ fields->pattern[len + 3] = '\\';
+ fields->pattern[len + 4] = '$';
+ fields->pattern[len + 5] = NUL;
}
+ break;
}
- multiscan = false;
-
- if (fmt_ptr == NULL || idx == 'D' || idx == 'X') {
- if (fmt_ptr != NULL) {
- if (idx == 'D') { /* enter directory */
- if (*namebuf == NUL) {
- EMSG(_("E379: Missing or empty directory name"));
- goto error2;
- }
- if ((directory = qf_push_dir(namebuf, &dir_stack)) == NULL)
- goto error2;
- } else if (idx == 'X') /* leave directory */
- directory = qf_pop_dir(&dir_stack);
+ }
+ qfl->qf_multiscan = false;
+
+ if (fmt_ptr == NULL || idx == 'D' || idx == 'X') {
+ if (fmt_ptr != NULL) {
+ if (idx == 'D') { // enter directory
+ if (*fields->namebuf == NUL) {
+ EMSG(_("E379: Missing or empty directory name"));
+ return QF_FAIL;
+ }
+ qfl->qf_directory = qf_push_dir(fields->namebuf, &qfl->qf_dir_stack,
+ false);
+ if (qfl->qf_directory == NULL) {
+ return QF_FAIL;
+ }
+ } else if (idx == 'X') { // leave directory
+ qfl->qf_directory = qf_pop_dir(&qfl->qf_dir_stack);
}
- namebuf[0] = NUL; // no match found, remove file name
- lnum = 0; // don't jump to this line
- valid = false;
- STRCPY(errmsg, IObuff); // copy whole line to error message
- if (fmt_ptr == NULL) {
- multiline = multiignore = false;
- }
- } else if (fmt_ptr != NULL) {
- /* honor %> item */
- if (fmt_ptr->conthere)
- fmt_start = fmt_ptr;
-
- if (vim_strchr((char_u *)"AEWI", idx) != NULL) {
- multiline = true; // start of a multi-line message
- multiignore = false; // reset continuation
- } else if (vim_strchr((char_u *)"CZ", idx)
- != NULL) { /* continuation of multi-line msg */
- if (qfprev == NULL)
- goto error2;
- if (*errmsg && !multiignore) {
- size_t len = STRLEN(qfprev->qf_text);
- qfprev->qf_text = xrealloc(qfprev->qf_text, len + STRLEN(errmsg) + 2);
- qfprev->qf_text[len] = '\n';
- STRCPY(qfprev->qf_text + len + 1, errmsg);
- }
- if (qfprev->qf_nr == -1)
- qfprev->qf_nr = enr;
- if (vim_isprintc(type) && !qfprev->qf_type)
- qfprev->qf_type = type; /* only printable chars allowed */
- if (!qfprev->qf_lnum)
- qfprev->qf_lnum = lnum;
- if (!qfprev->qf_col)
- qfprev->qf_col = col;
- qfprev->qf_viscol = use_viscol;
- if (!qfprev->qf_fnum)
- qfprev->qf_fnum = qf_get_fnum(directory,
- *namebuf
- || directory ? namebuf : currfile
- && valid ? currfile : 0);
- if (idx == 'Z') {
- multiline = multiignore = false;
+ }
+ 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);
+ if (fmt_ptr == NULL) {
+ qfl->qf_multiline = qfl->qf_multiignore = false;
+ }
+ } else {
+ // honor %> item
+ if (fmt_ptr->conthere) {
+ fmt_start = fmt_ptr;
+ }
+
+ if (vim_strchr((char_u *)"AEWI", idx) != NULL) {
+ qfl->qf_multiline = true; // start of a multi-line message
+ qfl->qf_multiignore = false; // reset continuation
+ } else if (vim_strchr((char_u *)"CZ", idx)
+ != NULL) { // continuation of multi-line msg
+ if (!qfl->qf_multiignore) {
+ qfline_T *qfprev = qfl->qf_last;
+ if (qfprev == NULL) {
+ return QF_FAIL;
}
- line_breakcheck();
- continue;
- } else if (vim_strchr((char_u *)"OPQ", idx) != NULL) {
- // global file names
- valid = false;
- if (*namebuf == NUL || os_path_exists(namebuf)) {
- if (*namebuf && idx == 'P') {
- currfile = qf_push_dir(namebuf, &file_stack);
- } else if (idx == 'Q') {
- currfile = qf_pop_dir(&file_stack);
- }
- *namebuf = NUL;
- if (tail && *tail) {
- STRMOVE(IObuff, skipwhite(tail));
- multiscan = true;
- goto restofline;
- }
+ if (*fields->errmsg) {
+ size_t textlen = STRLEN(qfprev->qf_text);
+ qfprev->qf_text = xrealloc(qfprev->qf_text,
+ textlen + STRLEN(fields->errmsg) + 2);
+ qfprev->qf_text[textlen] = '\n';
+ STRCPY(qfprev->qf_text + textlen + 1, fields->errmsg);
+ }
+ if (qfprev->qf_nr == -1) {
+ qfprev->qf_nr = fields->enr;
+ }
+ if (vim_isprintc(fields->type) && !qfprev->qf_type) {
+ qfprev->qf_type = fields->type; // only printable chars allowed
+ }
+ if (!qfprev->qf_lnum) {
+ qfprev->qf_lnum = fields->lnum;
+ }
+ if (!qfprev->qf_col) {
+ qfprev->qf_col = fields->col;
}
+ qfprev->qf_viscol = fields->use_viscol;
+ if (!qfprev->qf_fnum) {
+ qfprev->qf_fnum = qf_get_fnum(qi, qf_idx, qfl->qf_directory,
+ *fields->namebuf || qfl->qf_directory
+ ? fields->namebuf
+ : qfl->qf_currfile && fields->valid
+ ? qfl->qf_currfile : 0);
+ }
+ }
+ if (idx == 'Z') {
+ qfl->qf_multiline = qfl->qf_multiignore = false;
}
- if (fmt_ptr->flags == '-') { // generally exclude this line
- if (multiline) {
- multiignore = true; // also exclude continuation lines
+
+ line_breakcheck();
+ return QF_IGNORE_LINE;
+ } else if (vim_strchr((char_u *)"OPQ", idx) != NULL) {
+ // global file names
+ fields->valid = false;
+ if (*fields->namebuf == NUL || os_path_exists(fields->namebuf)) {
+ if (*fields->namebuf && idx == 'P') {
+ qfl->qf_currfile = qf_push_dir(fields->namebuf, &qfl->qf_file_stack,
+ true);
+ } else if (idx == 'Q') {
+ qfl->qf_currfile = qf_pop_dir(&qfl->qf_file_stack);
}
- continue;
+ *fields->namebuf = NUL;
+ if (tail && *tail) {
+ STRMOVE(IObuff, skipwhite(tail));
+ qfl->qf_multiscan = true;
+ goto restofline;
+ }
+ }
+ }
+ if (fmt_ptr->flags == '-') { // generally exclude this line
+ if (qfl->qf_multiline) {
+ // also exclude continuation lines
+ qfl->qf_multiignore = true;
}
+ return QF_IGNORE_LINE;
+ }
+ }
+
+ return QF_OK;
+}
+
+// Read the errorfile "efile" into memory, line by line, building the error
+// list.
+// Alternative: when "efile" is NULL read errors from buffer "buf".
+// Alternative: when "tv" is not NULL get errors from the string or list.
+// Always use 'errorformat' from "buf" if there is a local value.
+// Then "lnumfirst" and "lnumlast" specify the range of lines to use.
+// Set the title of the list to "qf_title".
+// Return -1 for error, number of errors for success.
+static int
+qf_init_ext(
+ qf_info_T *qi,
+ int qf_idx,
+ char_u *efile,
+ buf_T *buf,
+ typval_T *tv,
+ char_u *errorformat,
+ int newlist, // TRUE: start a new error list
+ linenr_T lnumfirst, // first line number to use
+ linenr_T lnumlast, // last line number to use
+ char_u *qf_title,
+ char_u *enc
+)
+{
+ qfstate_T state;
+ qffields_T fields;
+ qfline_T *old_last = NULL;
+ bool adding = false;
+ static efm_T *fmt_first = NULL;
+ char_u *efm;
+ static char_u *last_efm = NULL;
+ int retval = -1; // default: return error flag
+ int status;
+
+ // Do not used the cached buffer, it may have been wiped out.
+ xfree(qf_last_bufname);
+ qf_last_bufname = NULL;
+
+ memset(&state, 0, sizeof(state));
+ memset(&fields, 0, sizeof(fields));
+ state.vc.vc_type = CONV_NONE;
+ if (enc != NULL && *enc != NUL) {
+ convert_setup(&state.vc, enc, p_enc);
+ }
+
+ fields.namebuf = xmalloc(CMDBUFFSIZE + 1);
+ fields.errmsglen = CMDBUFFSIZE + 1;
+ fields.errmsg = xmalloc(fields.errmsglen);
+ fields.pattern = xmalloc(CMDBUFFSIZE + 1);
+
+ if (efile != NULL && (state.fd = mch_fopen((char *)efile, "r")) == NULL) {
+ EMSG2(_(e_openerrf), efile);
+ goto qf_init_end;
+ }
+
+ if (newlist || qf_idx == qi->qf_listcount) {
+ // make place for a new list
+ qf_new_list(qi, qf_title);
+ qf_idx = qi->qf_curlist;
+ } else {
+ // Adding to existing list, use last entry.
+ adding = true;
+ if (qi->qf_lists[qf_idx].qf_count > 0) {
+ old_last = qi->qf_lists[qf_idx].qf_last;
+ }
+ }
+
+ qf_list_T *qfl = &qi->qf_lists[qf_idx];
+
+ // Use the local value of 'errorformat' if it's set.
+ if (errorformat == p_efm && tv == NULL && buf && *buf->b_p_efm != NUL) {
+ efm = buf->b_p_efm;
+ } else {
+ efm = errorformat;
+ }
+
+ // If the errorformat didn't change between calls, then reuse the previously
+ // parsed values.
+ if (last_efm == NULL || (STRCMP(last_efm, efm) != 0)) {
+ // free the previously parsed data
+ xfree(last_efm);
+ last_efm = NULL;
+ free_efm_list(&fmt_first);
+
+ // parse the current 'efm'
+ fmt_first = parse_efm_option(efm);
+ if (fmt_first != NULL) {
+ last_efm = vim_strsave(efm);
+ }
+ }
+
+ if (fmt_first == NULL) { // nothing found
+ goto error2;
+ }
+
+ /*
+ * got_int is reset here, because it was probably set when killing the
+ * ":make" command, but we still want to read the errorfile then.
+ */
+ got_int = FALSE;
+
+ if (tv != NULL) {
+ if (tv->v_type == VAR_STRING) {
+ state.p_str = tv->vval.v_string;
+ } else if (tv->v_type == VAR_LIST) {
+ state.p_list = tv->vval.v_list;
+ state.p_li = tv_list_first(tv->vval.v_list);
+ }
+ state.tv = tv;
+ }
+ state.buf = buf;
+ state.buflnum = lnumfirst;
+ state.lnumlast = lnumlast;
+
+ /*
+ * Read the lines in the error file one by one.
+ * Try to recognize one of the error formats in each line.
+ */
+ while (!got_int) {
+ // Get the next line from a file/buffer/list/string
+ status = qf_get_nextline(&state);
+ if (status == QF_END_OF_INPUT) { // end of input
+ break;
+ }
+
+ status = qf_parse_line(qi, qf_idx, state.linebuf, state.linelen,
+ fmt_first, &fields);
+ if (status == QF_FAIL) {
+ goto error2;
+ }
+ if (status == QF_IGNORE_LINE) {
+ continue;
}
- if (qf_add_entry(qi, &qfprev,
- directory,
- (*namebuf || directory)
- ? namebuf
- : ((currfile && valid) ? currfile : (char_u *)NULL),
- 0,
- errmsg,
- lnum,
- col,
- use_viscol,
- pattern,
- enr,
- type,
- valid) == FAIL)
+ if (qf_add_entry(qi,
+ qf_idx,
+ qfl->qf_directory,
+ (*fields.namebuf || qfl->qf_directory)
+ ? fields.namebuf : ((qfl->qf_currfile && fields.valid)
+ ? qfl->qf_currfile : (char_u *)NULL),
+ 0,
+ fields.errmsg,
+ fields.lnum,
+ fields.col,
+ fields.use_viscol,
+ fields.pattern,
+ fields.enr,
+ fields.type,
+ fields.valid) == FAIL) {
goto error2;
+ }
line_breakcheck();
}
- if (fd == NULL || !ferror(fd)) {
- if (qi->qf_lists[qi->qf_curlist].qf_index == 0) {
- /* no valid entry found */
- qi->qf_lists[qi->qf_curlist].qf_ptr =
- qi->qf_lists[qi->qf_curlist].qf_start;
- qi->qf_lists[qi->qf_curlist].qf_index = 1;
- qi->qf_lists[qi->qf_curlist].qf_nonevalid = TRUE;
+ if (state.fd == NULL || !ferror(state.fd)) {
+ if (qfl->qf_index == 0) {
+ // no valid entry found
+ qfl->qf_ptr = qfl->qf_start;
+ qfl->qf_index = 1;
+ qfl->qf_nonevalid = true;
} else {
- qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
- if (qi->qf_lists[qi->qf_curlist].qf_ptr == NULL)
- qi->qf_lists[qi->qf_curlist].qf_ptr =
- qi->qf_lists[qi->qf_curlist].qf_start;
+ qfl->qf_nonevalid = false;
+ if (qfl->qf_ptr == NULL) {
+ qfl->qf_ptr = qfl->qf_start;
+ }
}
- /* return number of matches */
- retval = qi->qf_lists[qi->qf_curlist].qf_count;
- goto qf_init_ok;
+ // return number of matches
+ retval = qfl->qf_count;
+ goto qf_init_end;
}
EMSG(_(e_readerrf));
error2:
- qf_free(qi, qi->qf_curlist);
- qi->qf_listcount--;
- if (qi->qf_curlist > 0)
- --qi->qf_curlist;
-qf_init_ok:
- if (fd != NULL)
- fclose(fd);
- for (fmt_ptr = fmt_first; fmt_ptr != NULL; fmt_ptr = fmt_first) {
- fmt_first = fmt_ptr->next;
- vim_regfree(fmt_ptr->prog);
- xfree(fmt_ptr);
- }
- qf_clean_dir_stack(&dir_stack);
- qf_clean_dir_stack(&file_stack);
+ if (!adding) {
+ // Error when creating a new list. Free the new list
+ qf_free(qi, qi->qf_curlist);
+ qi->qf_listcount--;
+ if (qi->qf_curlist > 0) {
+ qi->qf_curlist--;
+ }
+ }
qf_init_end:
- xfree(namebuf);
- xfree(errmsg);
- xfree(pattern);
- xfree(fmtstr);
+ if (state.fd != NULL) {
+ fclose(state.fd);
+ }
+ xfree(fields.namebuf);
+ xfree(fields.errmsg);
+ xfree(fields.pattern);
+ xfree(state.growbuf);
- qf_update_buffer(qi);
+ if (qf_idx == qi->qf_curlist) {
+ qf_update_buffer(qi, old_last);
+ }
+
+ if (state.vc.vc_type != CONV_NONE) {
+ convert_setup(&state.vc, NULL, NULL);
+ }
return retval;
}
-static void qf_store_title(qf_info_T *qi, char_u *title)
+static void qf_store_title(qf_info_T *qi, int qf_idx, char_u *title)
{
+ xfree(qi->qf_lists[qf_idx].qf_title);
+ qi->qf_lists[qf_idx].qf_title = NULL;
+
if (title != NULL) {
- char_u *p = xmalloc(STRLEN(title) + 2);
+ size_t len = STRLEN(title) + 1;
+ char_u *p = xmallocz(len);
- qi->qf_lists[qi->qf_curlist].qf_title = p;
- sprintf((char *)p, ":%s", (char *)title);
+ qi->qf_lists[qf_idx].qf_title = p;
+ snprintf((char *)p, len + 1, ":%s", (char *)title);
}
}
-/*
- * Prepare for adding a new quickfix list.
- */
+// Prepare for adding a new quickfix list. If the current list is in the
+// middle of the stack, then all the following lists are freed and then
+// the new list is added.
static void qf_new_list(qf_info_T *qi, char_u *qf_title)
{
int i;
@@ -825,7 +1225,8 @@ static void qf_new_list(qf_info_T *qi, char_u *qf_title)
} else
qi->qf_curlist = qi->qf_listcount++;
memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T)));
- qf_store_title(qi, qf_title);
+ qf_store_title(qi, qi->qf_curlist, qf_title);
+ qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id;
}
/*
@@ -868,7 +1269,7 @@ void qf_free_all(win_T *wp)
/// Add an entry to the end of the list of errors.
///
/// @param qi quickfix list
-/// @param prevp nonnull pointer (to previously added entry or NULL)
+/// @param qf_idx list index
/// @param dir optional directory name
/// @param fname file name or NULL
/// @param bufnum buffer number or zero
@@ -882,17 +1283,25 @@ void qf_free_all(win_T *wp)
/// @param valid valid entry
///
/// @returns OK or FAIL.
-static int qf_add_entry(qf_info_T *qi, qfline_T **prevp, char_u *dir,
- char_u *fname, int bufnum, char_u *mesg, long lnum,
- int col, char_u vis_col, char_u *pattern, int nr,
- char_u type, char_u valid)
+static int qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u *fname,
+ int bufnum, char_u *mesg, long lnum, int col,
+ char_u vis_col, char_u *pattern, int nr, char_u type,
+ char_u valid)
{
qfline_T *qfp = xmalloc(sizeof(qfline_T));
+ qfline_T **lastp; // pointer to qf_last or NULL
+
+ if (bufnum != 0) {
+ buf_T *buf = buflist_findnr(bufnum);
- if (bufnum != 0)
qfp->qf_fnum = bufnum;
- else
- qfp->qf_fnum = qf_get_fnum(dir, fname);
+ if (buf != NULL) {
+ buf->b_has_qf_entry |=
+ (qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
+ }
+ } else {
+ qfp->qf_fnum = qf_get_fnum(qi, qf_idx, dir, fname);
+ }
qfp->qf_text = vim_strsave(mesg);
qfp->qf_lnum = lnum;
qfp->qf_col = col;
@@ -905,27 +1314,29 @@ static int qf_add_entry(qf_info_T *qi, qfline_T **prevp, char_u *dir,
qfp->qf_nr = nr;
if (type != 1 && !vim_isprintc(type)) /* only printable chars allowed */
type = 0;
- qfp->qf_type = type;
+ qfp->qf_type = (char_u)type;
qfp->qf_valid = valid;
- if (qi->qf_lists[qi->qf_curlist].qf_count == 0) {
- /* first element in the list */
- qi->qf_lists[qi->qf_curlist].qf_start = qfp;
- qfp->qf_prev = qfp; /* first element points to itself */
+ lastp = &qi->qf_lists[qf_idx].qf_last;
+ if (qi->qf_lists[qf_idx].qf_count == 0) {
+ // first element in the list
+ qi->qf_lists[qf_idx].qf_start = qfp;
+ qi->qf_lists[qf_idx].qf_ptr = qfp;
+ qi->qf_lists[qf_idx].qf_index = 0;
+ qfp->qf_prev = NULL;
} else {
- assert(*prevp);
- qfp->qf_prev = *prevp;
- (*prevp)->qf_next = qfp;
+ assert(*lastp);
+ qfp->qf_prev = *lastp;
+ (*lastp)->qf_next = qfp;
}
- qfp->qf_next = qfp; /* last element points to itself */
- qfp->qf_cleared = FALSE;
- *prevp = qfp;
- ++qi->qf_lists[qi->qf_curlist].qf_count;
- if (qi->qf_lists[qi->qf_curlist].qf_index == 0 && qfp->qf_valid) {
- /* first valid entry */
- qi->qf_lists[qi->qf_curlist].qf_index =
- qi->qf_lists[qi->qf_curlist].qf_count;
- qi->qf_lists[qi->qf_curlist].qf_ptr = qfp;
+ qfp->qf_next = NULL;
+ qfp->qf_cleared = false;
+ *lastp = qfp;
+ qi->qf_lists[qf_idx].qf_count++;
+ if (qi->qf_lists[qf_idx].qf_index == 0 && qfp->qf_valid) {
+ // first valid entry
+ qi->qf_lists[qf_idx].qf_index = qi->qf_lists[qf_idx].qf_count;
+ qi->qf_lists[qf_idx].qf_ptr = qfp;
}
return OK;
@@ -1005,31 +1416,41 @@ void copy_loclist(win_T *from, win_T *to)
to_qfl->qf_count = 0;
to_qfl->qf_index = 0;
to_qfl->qf_start = NULL;
+ to_qfl->qf_last = NULL;
to_qfl->qf_ptr = NULL;
if (from_qfl->qf_title != NULL)
to_qfl->qf_title = vim_strsave(from_qfl->qf_title);
else
to_qfl->qf_title = NULL;
+ if (from_qfl->qf_ctx != NULL) {
+ to_qfl->qf_ctx = xcalloc(1, sizeof(typval_T));
+ tv_copy(from_qfl->qf_ctx, to_qfl->qf_ctx);
+ } else {
+ to_qfl->qf_ctx = NULL;
+ }
+
if (from_qfl->qf_count) {
qfline_T *from_qfp;
- qfline_T *prevp = NULL;
-
- /* copy all the location entries in this list */
- for (i = 0, from_qfp = from_qfl->qf_start; i < from_qfl->qf_count;
- ++i, from_qfp = from_qfp->qf_next) {
- if (qf_add_entry(to->w_llist, &prevp,
- NULL,
- NULL,
- 0,
- from_qfp->qf_text,
- from_qfp->qf_lnum,
- from_qfp->qf_col,
- from_qfp->qf_viscol,
- from_qfp->qf_pattern,
- from_qfp->qf_nr,
- 0,
- from_qfp->qf_valid) == FAIL) {
+ qfline_T *prevp;
+
+ // copy all the location entries in this list
+ for (i = 0, from_qfp = from_qfl->qf_start;
+ i < from_qfl->qf_count && from_qfp != NULL;
+ i++, from_qfp = from_qfp->qf_next) {
+ if (qf_add_entry(to->w_llist,
+ to->w_llist->qf_curlist,
+ NULL,
+ NULL,
+ 0,
+ from_qfp->qf_text,
+ from_qfp->qf_lnum,
+ from_qfp->qf_col,
+ from_qfp->qf_viscol,
+ from_qfp->qf_pattern,
+ from_qfp->qf_nr,
+ 0,
+ from_qfp->qf_valid) == FAIL) {
qf_free_all(to);
return;
}
@@ -1038,15 +1459,20 @@ void copy_loclist(win_T *from, win_T *to)
* directory and file names are not supplied. So the qf_fnum
* field is copied here.
*/
- prevp->qf_fnum = from_qfp->qf_fnum; /* file number */
- prevp->qf_type = from_qfp->qf_type; /* error type */
- if (from_qfl->qf_ptr == from_qfp)
- to_qfl->qf_ptr = prevp; /* current location */
+ prevp = to->w_llist->qf_lists[to->w_llist->qf_curlist].qf_last;
+ prevp->qf_fnum = from_qfp->qf_fnum; // file number
+ prevp->qf_type = from_qfp->qf_type; // error type
+ if (from_qfl->qf_ptr == from_qfp) {
+ to_qfl->qf_ptr = prevp; // current location
+ }
}
}
to_qfl->qf_index = from_qfl->qf_index; /* current index in the list */
+ // Assign a new ID for the location list
+ to_qfl->qf_id = ++last_qf_id;
+
/* When no valid entries are present in the list, qf_ptr points to
* the first item in the list */
if (to_qfl->qf_nonevalid) {
@@ -1058,52 +1484,68 @@ void copy_loclist(win_T *from, win_T *to)
to->w_llist->qf_curlist = qi->qf_curlist; /* current list */
}
-/*
- * get buffer number for file "dir.name"
- */
-static int qf_get_fnum(char_u *directory, char_u *fname)
+// Get buffer number for file "directory/fname".
+// Also sets the b_has_qf_entry flag.
+static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *directory,
+ char_u *fname)
{
- if (fname == NULL || *fname == NUL) /* no file name */
+ char_u *ptr = NULL;
+ char_u *bufname;
+ buf_T *buf;
+ if (fname == NULL || *fname == NUL) { // no file name
return 0;
- {
- char_u *ptr;
- int fnum;
+ }
#ifdef BACKSLASH_IN_FILENAME
- if (directory != NULL)
- slash_adjust(directory);
- slash_adjust(fname);
+ if (directory != NULL) {
+ slash_adjust(directory);
+ }
+ slash_adjust(fname);
#endif
- if (directory != NULL && !vim_isAbsName(fname)) {
- ptr = (char_u *)concat_fnames((char *)directory, (char *)fname, TRUE);
- /*
- * Here we check if the file really exists.
- * This should normally be true, but if make works without
- * "leaving directory"-messages we might have missed a
- * directory change.
- */
- if (!os_path_exists(ptr)) {
- xfree(ptr);
- directory = qf_guess_filepath(fname);
- if (directory)
- ptr = (char_u *)concat_fnames((char *)directory, (char *)fname, TRUE);
- else
- ptr = vim_strsave(fname);
- }
- /* Use concatenated directory name and file name */
- fnum = buflist_add(ptr, 0);
+ if (directory != NULL && !vim_isAbsName(fname)) {
+ ptr = (char_u *)concat_fnames((char *)directory, (char *)fname, true);
+ // Here we check if the file really exists.
+ // This should normally be true, but if make works without
+ // "leaving directory"-messages we might have missed a
+ // directory change.
+ if (!os_path_exists(ptr)) {
xfree(ptr);
- return fnum;
+ directory = qf_guess_filepath(qi, qf_idx, fname);
+ if (directory) {
+ ptr = (char_u *)concat_fnames((char *)directory, (char *)fname, true);
+ } else {
+ ptr = vim_strsave(fname);
+ }
}
- return buflist_add(fname, 0);
+ // Use concatenated directory name and file name.
+ bufname = ptr;
+ } else {
+ bufname = fname;
+ }
+
+ if (qf_last_bufname != NULL
+ && STRCMP(bufname, qf_last_bufname) == 0
+ && bufref_valid(&qf_last_bufref)) {
+ buf = qf_last_bufref.br_buf;
+ xfree(ptr);
+ } else {
+ xfree(qf_last_bufname);
+ buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT);
+ qf_last_bufname = (bufname == ptr) ? bufname : vim_strsave(bufname);
+ set_bufref(&qf_last_bufref, buf);
+ }
+ if (buf == NULL) {
+ return 0;
}
+ buf->b_has_qf_entry =
+ (qi == &ql_info) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
+ return buf->b_fnum;
}
-/*
- * push dirbuf onto the directory stack and return pointer to actual dir or
- * NULL on error
- */
-static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr)
+// Push dirbuf onto the directory stack and return pointer to actual dir or
+// NULL on error.
+static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr,
+ bool is_file_stack)
{
struct dir_stack_T *ds_ptr;
@@ -1116,7 +1558,7 @@ static char_u *qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr)
/* store directory on the stack */
if (vim_isAbsName(dirbuf)
|| (*stackptr)->next == NULL
- || (*stackptr && dir_stack != *stackptr))
+ || (*stackptr && is_file_stack))
(*stackptr)->dirname = vim_strsave(dirbuf);
else {
/* Okay we don't have an absolute path.
@@ -1218,17 +1660,19 @@ static void qf_clean_dir_stack(struct dir_stack_T **stackptr)
* Then qf_push_dir thinks we are in ./aa/bb, but we are in ./bb.
* qf_guess_filepath will return NULL.
*/
-static char_u *qf_guess_filepath(char_u *filename)
+static char_u *qf_guess_filepath(qf_info_T *qi, int qf_idx, char_u *filename)
{
struct dir_stack_T *ds_ptr;
struct dir_stack_T *ds_tmp;
char_u *fullname;
+ qf_list_T *qfl = &qi->qf_lists[qf_idx];
- /* no dirs on the stack - there's nothing we can do */
- if (dir_stack == NULL)
+ // no dirs on the stack - there's nothing we can do
+ if (qfl->qf_dir_stack == NULL) {
return NULL;
+ }
- ds_ptr = dir_stack->next;
+ ds_ptr = qfl->qf_dir_stack->next;
fullname = NULL;
while (ds_ptr) {
xfree(fullname);
@@ -1243,16 +1687,41 @@ static char_u *qf_guess_filepath(char_u *filename)
xfree(fullname);
- /* clean up all dirs we already left */
- while (dir_stack->next != ds_ptr) {
- ds_tmp = dir_stack->next;
- dir_stack->next = dir_stack->next->next;
+ // clean up all dirs we already left
+ while (qfl->qf_dir_stack->next != ds_ptr) {
+ ds_tmp = qfl->qf_dir_stack->next;
+ qfl->qf_dir_stack->next = qfl->qf_dir_stack->next->next;
xfree(ds_tmp->dirname);
xfree(ds_tmp);
}
- return ds_ptr==NULL ? NULL : ds_ptr->dirname;
+ return ds_ptr == NULL ? NULL : ds_ptr->dirname;
+}
+
+/// When loading a file from the quickfix, the auto commands may modify it.
+/// This may invalidate the current quickfix entry. This function checks
+/// whether a entry is still present in the quickfix.
+/// Similar to location list.
+static bool is_qf_entry_present(qf_info_T *qi, qfline_T *qf_ptr)
+{
+ qf_list_T *qfl;
+ qfline_T *qfp;
+ int i;
+
+ qfl = &qi->qf_lists[qi->qf_curlist];
+ // Search for the entry in the current list
+ for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count; i++, qfp = qfp->qf_next) {
+ if (qfp == NULL || qfp == qf_ptr) {
+ break;
+ }
+ }
+
+ if (i == qfl->qf_count) { // Entry is not found
+ return false;
+ }
+
+ return true;
}
/*
@@ -1290,7 +1759,7 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
win_T *oldwin = curwin;
int print_message = TRUE;
int len;
- int old_KeyTyped = KeyTyped; /* getting file may reset it */
+ const bool old_KeyTyped = KeyTyped; // getting file may reset it
int ok = OK;
bool usable_win;
@@ -1376,12 +1845,12 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
/*
* For ":helpgrep" find a help window or open one.
*/
- if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0)) {
+ if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) {
win_T *wp = NULL;
if (cmdmod.tab == 0) {
FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
- if (wp2->w_buffer != NULL && wp2->w_buffer->b_help) {
+ if (bt_help(wp2->w_buffer)) {
wp = wp2;
break;
}
@@ -1478,7 +1947,7 @@ win_found:
* If there is only one window and it is the quickfix window, create a
* new one above the quickfix window.
*/
- if (((firstwin == lastwin) && bt_quickfix(curbuf)) || !usable_win) {
+ if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win) {
flags = WSP_ABOVE;
if (ll_ref != NULL)
flags |= WSP_NEWLOC;
@@ -1586,14 +2055,29 @@ win_found:
oldwin == curwin ? curwin : NULL);
}
} else {
+ int old_qf_curlist = qi->qf_curlist;
+ bool is_abort = false;
+
ok = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1,
GETF_SETMARK | GETF_SWITCH, forceit);
- if (qi != &ql_info && !win_valid(oldwin)) {
+ if (qi != &ql_info && !win_valid_any_tab(oldwin)) {
EMSG(_("E924: Current window was closed"));
+ is_abort = true;
+ opened_window = false;
+ } else if (old_qf_curlist != qi->qf_curlist // -V560
+ || !is_qf_entry_present(qi, qf_ptr)) {
+ if (qi == &ql_info) {
+ EMSG(_("E925: Current quickfix was changed"));
+ } else {
+ EMSG(_("E926: Current location list was changed"));
+ }
+ is_abort = true;
+ }
+
+ if (is_abort) {
ok = false;
qi = NULL;
qf_ptr = NULL;
- opened_window = false;
}
}
}
@@ -1732,18 +2216,36 @@ void qf_list(exarg_T *eap)
EMSG(_(e_quickfix));
return;
}
+
+ bool plus = false;
+ if (*arg == '+') {
+ arg++;
+ plus = true;
+ }
if (!get_list_range(&arg, &idx1, &idx2) || *arg != NUL) {
EMSG(_(e_trailing));
return;
}
- i = qi->qf_lists[qi->qf_curlist].qf_count;
- if (idx1 < 0)
- idx1 = (-idx1 > i) ? 0 : idx1 + i + 1;
- if (idx2 < 0)
- idx2 = (-idx2 > i) ? 0 : idx2 + i + 1;
+ if (plus) {
+ i = qi->qf_lists[qi->qf_curlist].qf_index;
+ idx2 = i + idx1;
+ idx1 = i;
+ } else {
+ i = qi->qf_lists[qi->qf_curlist].qf_count;
+ if (idx1 < 0) {
+ idx1 = (-idx1 > i) ? 0 : idx1 + i + 1;
+ }
+ if (idx2 < 0) {
+ idx2 = (-idx2 > i) ? 0 : idx2 + i + 1;
+ }
+ }
+
+ // Shorten all the file names, so that it is easy to read.
+ shorten_fnames(false);
- if (qi->qf_lists[qi->qf_curlist].qf_nonevalid)
- all = TRUE;
+ if (qi->qf_lists[qi->qf_curlist].qf_nonevalid) {
+ all = true;
+ }
qfp = qi->qf_lists[qi->qf_curlist].qf_start;
for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ) {
if ((qfp->qf_valid || all) && idx1 <= i && i <= idx2) {
@@ -1764,23 +2266,24 @@ void qf_list(exarg_T *eap)
vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
i, (char *)fname);
msg_outtrans_attr(IObuff, i == qi->qf_lists[qi->qf_curlist].qf_index
- ? hl_attr(HLF_L) : hl_attr(HLF_D));
- if (qfp->qf_lnum == 0)
+ ? HL_ATTR(HLF_QFL) : HL_ATTR(HLF_D));
+ if (qfp->qf_lnum == 0) {
IObuff[0] = NUL;
- else if (qfp->qf_col == 0)
- sprintf((char *)IObuff, ":%" PRId64, (int64_t)qfp->qf_lnum);
- else
- sprintf((char *)IObuff, ":%" PRId64 " col %d",
- (int64_t)qfp->qf_lnum, qfp->qf_col);
- sprintf((char *)IObuff + STRLEN(IObuff), "%s:",
- (char *)qf_types(qfp->qf_type, qfp->qf_nr));
- msg_puts_attr(IObuff, hl_attr(HLF_N));
+ } else if (qfp->qf_col == 0) {
+ vim_snprintf((char *)IObuff, IOSIZE, ":%" PRIdLINENR, qfp->qf_lnum);
+ } else {
+ vim_snprintf((char *)IObuff, IOSIZE, ":%" PRIdLINENR " col %d",
+ qfp->qf_lnum, qfp->qf_col);
+ }
+ vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s:",
+ (char *)qf_types(qfp->qf_type, qfp->qf_nr));
+ msg_puts_attr((const char *)IObuff, HL_ATTR(HLF_N));
if (qfp->qf_pattern != NULL) {
qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
- STRCAT(IObuff, ":");
- msg_puts(IObuff);
+ xstrlcat((char *)IObuff, ":", IOSIZE);
+ msg_puts((const char *)IObuff);
}
- msg_puts((char_u *)" ");
+ msg_puts(" ");
/* Remove newlines and leading whitespace from the text. For an
* unrecognized line keep the indent, the compiler may mark a word
@@ -1793,7 +2296,10 @@ void qf_list(exarg_T *eap)
}
qfp = qfp->qf_next;
- ++i;
+ if (qfp == NULL) {
+ break;
+ }
+ i++;
os_breakcheck();
}
}
@@ -1819,6 +2325,31 @@ static void qf_fmt_text(char_u *text, char_u *buf, int bufsize)
buf[i] = NUL;
}
+static void qf_msg(qf_info_T *qi, int which, char *lead)
+{
+ char *title = (char *)qi->qf_lists[which].qf_title;
+ int count = qi->qf_lists[which].qf_count;
+ char_u buf[IOSIZE];
+
+ vim_snprintf((char *)buf, IOSIZE, _("%serror list %d of %d; %d errors "),
+ lead,
+ which + 1,
+ qi->qf_listcount,
+ count);
+
+ if (title != NULL) {
+ size_t len = STRLEN(buf);
+
+ if (len < 34) {
+ memset(buf + len, ' ', 34 - len);
+ buf[34] = NUL;
+ }
+ xstrlcat((char *)buf, title, IOSIZE);
+ }
+ trunc_string(buf, buf, (int)Columns - 1, IOSIZE);
+ msg(buf);
+}
+
/*
* ":colder [count]": Up in the quickfix stack.
* ":cnewer [count]": Down in the quickfix stack.
@@ -1859,69 +2390,117 @@ void qf_age(exarg_T *eap)
++qi->qf_curlist;
}
}
- qf_msg(qi);
+ qf_msg(qi, qi->qf_curlist, "");
+ qf_update_buffer(qi, NULL);
}
-static void qf_msg(qf_info_T *qi)
+void qf_history(exarg_T *eap)
{
- smsg(_("error list %d of %d; %d errors"),
- qi->qf_curlist + 1, qi->qf_listcount,
- qi->qf_lists[qi->qf_curlist].qf_count);
- qf_update_buffer(qi);
+ qf_info_T *qi = &ql_info;
+ int i;
+
+ if (eap->cmdidx == CMD_lhistory) {
+ qi = GET_LOC_LIST(curwin);
+ }
+ if (qi == NULL || (qi->qf_listcount == 0
+ && qi->qf_lists[qi->qf_curlist].qf_count == 0)) {
+ MSG(_("No entries"));
+ } else {
+ for (i = 0; i < qi->qf_listcount; i++) {
+ qf_msg(qi, i, i == qi->qf_curlist ? "> " : " ");
+ }
+ }
}
-/*
- * Free error list "idx".
- */
-static void qf_free(qf_info_T *qi, int idx)
+/// Free all the entries in the error list "idx". Note that other information
+/// associated with the list like context and title are not freed.
+static void qf_free_items(qf_info_T *qi, int idx)
{
qfline_T *qfp;
- int stop = FALSE;
-
- while (qi->qf_lists[idx].qf_count) {
- qfp = qi->qf_lists[idx].qf_start->qf_next;
- if (qi->qf_lists[idx].qf_title != NULL && !stop) {
- xfree(qi->qf_lists[idx].qf_start->qf_text);
- stop = (qi->qf_lists[idx].qf_start == qfp);
- xfree(qi->qf_lists[idx].qf_start->qf_pattern);
- xfree(qi->qf_lists[idx].qf_start);
- if (stop)
- /* Somehow qf_count may have an incorrect value, set it to 1
- * to avoid crashing when it's wrong.
- * TODO: Avoid qf_count being incorrect. */
- qi->qf_lists[idx].qf_count = 1;
- }
- qi->qf_lists[idx].qf_start = qfp;
- --qi->qf_lists[idx].qf_count;
- }
- xfree(qi->qf_lists[idx].qf_title);
- qi->qf_lists[idx].qf_start = NULL;
- qi->qf_lists[idx].qf_ptr = NULL;
- qi->qf_lists[idx].qf_title = NULL;
- qi->qf_lists[idx].qf_index = 0;
+ qfline_T *qfpnext;
+ bool stop = false;
+ qf_list_T *qfl = &qi->qf_lists[idx];
+
+ while (qfl->qf_count && qfl->qf_start != NULL) {
+ qfp = qfl->qf_start;
+ qfpnext = qfp->qf_next;
+ if (!stop) {
+ xfree(qfp->qf_text);
+ stop = (qfp == qfpnext);
+ xfree(qfp->qf_pattern);
+ xfree(qfp);
+ if (stop) {
+ // Somehow qf_count may have an incorrect value, set it to 1
+ // to avoid crashing when it's wrong.
+ // TODO(vim): Avoid qf_count being incorrect.
+ qfl->qf_count = 1;
+ }
+ }
+ qfl->qf_start = qfpnext;
+ qfl->qf_count--;
+ }
+
+ qfl->qf_start = NULL;
+ qfl->qf_ptr = NULL;
+ qfl->qf_index = 0;
+ qfl->qf_start = NULL;
+ qfl->qf_last = NULL;
+ qfl->qf_ptr = NULL;
+ qfl->qf_nonevalid = true;
+
+ qf_clean_dir_stack(&qfl->qf_dir_stack);
+ qfl->qf_directory = NULL;
+ qf_clean_dir_stack(&qfl->qf_file_stack);
+ qfl->qf_currfile = NULL;
+ qfl->qf_multiline = false;
+ qfl->qf_multiignore = false;
+ qfl->qf_multiscan = false;
+}
+
+/// Free error list "idx". Frees all the entries in the quickfix list,
+/// associated context information and the title.
+static void qf_free(qf_info_T *qi, int idx)
+{
+ qf_list_T *qfl = &qi->qf_lists[idx];
+ qf_free_items(qi, idx);
+
+ xfree(qfl->qf_title);
+ qfl->qf_title = NULL;
+ tv_free(qfl->qf_ctx);
+ qfl->qf_ctx = NULL;
+ qfl->qf_id = 0;
}
/*
* qf_mark_adjust: adjust marks
*/
-void qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long amount_after)
+bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount,
+ long amount_after)
{
int i;
qfline_T *qfp;
int idx;
qf_info_T *qi = &ql_info;
+ bool found_one = false;
+ int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
+ if (!(curbuf->b_has_qf_entry & buf_has_flag)) {
+ return false;
+ }
if (wp != NULL) {
- if (wp->w_llist == NULL)
- return;
+ if (wp->w_llist == NULL) {
+ return false;
+ }
qi = wp->w_llist;
}
for (idx = 0; idx < qi->qf_listcount; ++idx)
if (qi->qf_lists[idx].qf_count)
for (i = 0, qfp = qi->qf_lists[idx].qf_start;
- i < qi->qf_lists[idx].qf_count; ++i, qfp = qfp->qf_next)
+ i < qi->qf_lists[idx].qf_count && qfp != NULL;
+ i++, qfp = qfp->qf_next) {
if (qfp->qf_fnum == curbuf->b_fnum) {
+ found_one = true;
if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) {
if (amount == MAXLNUM)
qfp->qf_cleared = TRUE;
@@ -1930,6 +2509,9 @@ void qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, long amount, long
} else if (amount_after && qfp->qf_lnum > line2)
qfp->qf_lnum += amount_after;
}
+ }
+
+ return found_one;
}
/*
@@ -2026,8 +2608,9 @@ void ex_cclose(exarg_T *eap)
/* Find existing quickfix window and close it. */
win = qf_find_win(qi);
- if (win != NULL)
- win_close(win, FALSE);
+ if (win != NULL) {
+ win_close(win, false);
+ }
}
/*
@@ -2078,6 +2661,8 @@ void ex_copen(exarg_T *eap)
}
}
} else {
+ int flags = 0;
+
qf_buf = qf_find_buf(qi);
/* The current window becomes the previous window afterwards. */
@@ -2085,11 +2670,17 @@ void ex_copen(exarg_T *eap)
if ((eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow)
&& cmdmod.split == 0)
- /* Create the new window at the very bottom, except when
- * :belowright or :aboveleft is used. */
+ // Create the new quickfix window at the very bottom, except when
+ // :belowright or :aboveleft is used.
win_goto(lastwin);
- if (win_split(height, WSP_BELOW | WSP_NEWLOC) == FAIL)
- return; /* not enough room for window */
+ // Default is to open the window below the current window
+ if (cmdmod.split == 0) {
+ flags = WSP_BELOW;
+ }
+ flags |= WSP_NEWLOC;
+ if (win_split(height, flags) == FAIL) {
+ return; // not enough room for window
+ }
RESET_BINDING(curwin);
if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow) {
@@ -2110,15 +2701,13 @@ void ex_copen(exarg_T *eap)
else {
/* Create a new quickfix buffer */
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, oldwin);
- /* switch off 'swapfile' */
- set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
- set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix",
- OPT_LOCAL);
- set_option_value((char_u *)"bh", 0L, (char_u *)"wipe", OPT_LOCAL);
+ // Switch off 'swapfile'.
+ set_option_value("swf", 0L, NULL, OPT_LOCAL);
+ set_option_value("bt", 0L, "quickfix", OPT_LOCAL);
+ set_option_value("bh", 0L, "wipe", OPT_LOCAL);
RESET_BINDING(curwin);
- curwin->w_p_diff = FALSE;
- set_option_value((char_u *)"fdm", 0L, (char_u *)"manual",
- OPT_LOCAL);
+ curwin->w_p_diff = false;
+ set_option_value("fdm", 0L, "manual", OPT_LOCAL);
}
/* Only set the height when still in the same tab page and there is no
@@ -2135,7 +2724,7 @@ void ex_copen(exarg_T *eap)
qf_set_title_var(qi);
// Fill the buffer with the quickfix list.
- qf_fill_buffer(qi);
+ qf_fill_buffer(qi, curbuf, NULL);
curwin->w_cursor.lnum = qi->qf_lists[qi->qf_curlist].qf_index;
curwin->w_cursor.col = 0;
@@ -2143,6 +2732,44 @@ void ex_copen(exarg_T *eap)
update_topline(); /* scroll to show the line */
}
+// Move the cursor in the quickfix window to "lnum".
+static void qf_win_goto(win_T *win, linenr_T lnum)
+{
+ win_T *old_curwin = curwin;
+
+ curwin = win;
+ curbuf = win->w_buffer;
+ curwin->w_cursor.lnum = lnum;
+ curwin->w_cursor.col = 0;
+ curwin->w_cursor.coladd = 0;
+ curwin->w_curswant = 0;
+ update_topline(); // scroll to show the line
+ redraw_later(VALID);
+ curwin->w_redr_status = true; // update ruler
+ curwin = old_curwin;
+ curbuf = curwin->w_buffer;
+}
+
+// :cbottom/:lbottom command.
+void ex_cbottom(exarg_T *eap)
+{
+ qf_info_T *qi = &ql_info;
+
+ if (eap->cmdidx == CMD_lbottom) {
+ qi = GET_LOC_LIST(curwin);
+ if (qi == NULL) {
+ EMSG(_(e_loclist));
+ return;
+ }
+ }
+
+ win_T *win = qf_find_win(qi);
+
+ if (win != NULL && win->w_cursor.lnum != win->w_buffer->b_ml.ml_line_count) {
+ qf_win_goto(win, win->w_buffer->b_ml.ml_line_count);
+ }
+}
+
/*
* Return the number of the current entry (line number in the quickfix
* window).
@@ -2179,24 +2806,14 @@ qf_win_pos_update (
if (win != NULL
&& qf_index <= win->w_buffer->b_ml.ml_line_count
&& old_qf_index != qf_index) {
- win_T *old_curwin = curwin;
-
- curwin = win;
- curbuf = win->w_buffer;
if (qf_index > old_qf_index) {
- curwin->w_redraw_top = old_qf_index;
- curwin->w_redraw_bot = qf_index;
+ win->w_redraw_top = old_qf_index;
+ win->w_redraw_bot = qf_index;
} else {
- curwin->w_redraw_top = qf_index;
- curwin->w_redraw_bot = old_qf_index;
+ win->w_redraw_top = qf_index;
+ win->w_redraw_bot = old_qf_index;
}
- curwin->w_cursor.lnum = qf_index;
- curwin->w_cursor.col = 0;
- update_topline(); /* scroll to show the line */
- redraw_later(VALID);
- curwin->w_redr_status = TRUE; /* update ruler */
- curwin = old_curwin;
- curbuf = curwin->w_buffer;
+ qf_win_goto(win, qf_index);
}
return win != NULL;
}
@@ -2251,34 +2868,55 @@ static buf_T *qf_find_buf(qf_info_T *qi)
return NULL;
}
+/// Update the w:quickfix_title variable in the quickfix/location list window
+static void qf_update_win_titlevar(qf_info_T *qi)
+{
+ win_T *win;
+
+ if ((win = qf_find_win(qi)) != NULL) {
+ win_T *curwin_save = curwin;
+ curwin = win;
+ qf_set_title_var(qi);
+ curwin = curwin_save;
+ }
+}
+
/*
* Find the quickfix buffer. If it exists, update the contents.
*/
-static void qf_update_buffer(qf_info_T *qi)
+static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
{
buf_T *buf;
win_T *win;
- win_T *curwin_save;
aco_save_T aco;
/* Check if a buffer for the quickfix list exists. Update it. */
buf = qf_find_buf(qi);
if (buf != NULL) {
- /* set curwin/curbuf to buf and save a few things */
- aucmd_prepbuf(&aco, buf);
+ linenr_T old_line_count = buf->b_ml.ml_line_count;
- if ((win = qf_find_win(qi)) != NULL) {
- curwin_save = curwin;
- curwin = win;
- qf_set_title_var(qi);
- curwin = curwin_save;
+ if (old_last == NULL) {
+ // set curwin/curbuf to buf and save a few things
+ aucmd_prepbuf(&aco, buf);
}
- qf_fill_buffer(qi);
- /* restore curwin/curbuf and a few other things */
- aucmd_restbuf(&aco);
+ qf_update_win_titlevar(qi);
- (void)qf_win_pos_update(qi, 0);
+ qf_fill_buffer(qi, buf, old_last);
+ buf_inc_changedtick(buf);
+
+ if (old_last == NULL) {
+ (void)qf_win_pos_update(qi, 0);
+
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
+ }
+
+ // Only redraw when added lines are visible. This avoids flickering when
+ // the added lines are not visible.
+ if ((win = qf_find_win(qi)) != NULL && old_line_count < win->w_botline) {
+ redraw_buf_later(buf, NOT_VALID);
+ }
}
}
@@ -2291,33 +2929,60 @@ static void qf_set_title_var(qf_info_T *qi)
}
}
-/*
- * Fill current buffer with quickfix errors, replacing any previous contents.
- * curbuf must be the quickfix buffer!
- */
-static void qf_fill_buffer(qf_info_T *qi)
+// Fill current buffer with quickfix errors, replacing any previous contents.
+// curbuf must be the quickfix buffer!
+// If "old_last" is not NULL append the items after this one.
+// When "old_last" is NULL then "buf" must equal "curbuf"! Because ml_delete()
+// is used and autocommands will be triggered.
+static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last)
{
linenr_T lnum;
qfline_T *qfp;
buf_T *errbuf;
int len;
- int old_KeyTyped = KeyTyped;
+ const bool old_KeyTyped = KeyTyped;
- /* delete all existing lines */
- while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0)
- (void)ml_delete((linenr_T)1, FALSE);
+ if (old_last == NULL) {
+ if (buf != curbuf) {
+ internal_error("qf_fill_buffer()");
+ return;
+ }
+
+ // delete all existing lines
+ while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) {
+ (void)ml_delete((linenr_T)1, false);
+ }
+ }
/* Check if there is anything to display */
if (qi->qf_curlist < qi->qf_listcount) {
- /* Add one line for each error */
- qfp = qi->qf_lists[qi->qf_curlist].qf_start;
- for (lnum = 0; lnum < qi->qf_lists[qi->qf_curlist].qf_count; ++lnum) {
+ char_u dirname[MAXPATHL];
+
+ *dirname = NUL;
+
+ // Add one line for each error
+ if (old_last == NULL) {
+ qfp = qi->qf_lists[qi->qf_curlist].qf_start;
+ lnum = 0;
+ } else {
+ qfp = old_last->qf_next;
+ lnum = buf->b_ml.ml_line_count;
+ }
+ while (lnum < qi->qf_lists[qi->qf_curlist].qf_count) {
if (qfp->qf_fnum != 0
&& (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL
&& errbuf->b_fname != NULL) {
if (qfp->qf_type == 1) { // :helpgrep
STRLCPY(IObuff, path_tail(errbuf->b_fname), sizeof(IObuff));
} else {
+ // shorten the file name if not done already
+ if (errbuf->b_sfname == NULL
+ || path_is_absolute(errbuf->b_sfname)) {
+ if (*dirname == NUL) {
+ os_dirname(dirname, MAXPATHL);
+ }
+ shorten_buf_fname(errbuf, dirname, false);
+ }
STRLCPY(IObuff, errbuf->b_fname, sizeof(IObuff));
}
len = (int)STRLEN(IObuff);
@@ -2351,33 +3016,44 @@ static void qf_fill_buffer(qf_info_T *qi)
qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text,
IObuff + len, IOSIZE - len);
- if (ml_append(lnum, IObuff, (colnr_T)STRLEN(IObuff) + 1, FALSE)
- == FAIL)
+ if (ml_append_buf(buf, lnum, IObuff, (colnr_T)STRLEN(IObuff) + 1, false)
+ == FAIL) {
break;
+ }
+ lnum++;
qfp = qfp->qf_next;
+ if (qfp == NULL) {
+ break;
+ }
+ }
+ if (old_last == NULL) {
+ // Delete the empty line which is now at the end
+ (void)ml_delete(lnum + 1, false);
}
- /* Delete the empty line which is now at the end */
- (void)ml_delete(lnum + 1, FALSE);
}
- /* correct cursor position */
- check_lnums(TRUE);
-
- /* Set the 'filetype' to "qf" each time after filling the buffer. This
- * resembles reading a file into a buffer, it's more logical when using
- * autocommands. */
- set_option_value((char_u *)"ft", 0L, (char_u *)"qf", OPT_LOCAL);
- curbuf->b_p_ma = FALSE;
-
- keep_filetype = TRUE; /* don't detect 'filetype' */
- apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL,
- FALSE, curbuf);
- apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL,
- FALSE, curbuf);
- keep_filetype = FALSE;
-
- /* make sure it will be redrawn */
- redraw_curbuf_later(NOT_VALID);
+ // Correct cursor position.
+ check_lnums(true);
+
+ if (old_last == NULL) {
+ // Set the 'filetype' to "qf" each time after filling the buffer. This
+ // resembles reading a file into a buffer, it's more logical when using
+ // autocommands.
+ curbuf_lock++;
+ set_option_value("ft", 0L, "qf", OPT_LOCAL);
+ curbuf->b_p_ma = false;
+
+ keep_filetype = true; // don't detect 'filetype'
+ apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL,
+ false, curbuf);
+ apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL,
+ false, curbuf);
+ keep_filetype = false;
+ curbuf_lock--;
+
+ // make sure it will be redrawn
+ redraw_curbuf_later(NOT_VALID);
+ }
/* Restore KeyTyped, setting 'filetype' may reset it. */
KeyTyped = old_KeyTyped;
@@ -2386,7 +3062,7 @@ static void qf_fill_buffer(qf_info_T *qi)
/*
* Return TRUE if "buf" is the quickfix buffer.
*/
-int bt_quickfix(buf_T *buf)
+int bt_quickfix(const buf_T *const buf)
{
return buf != NULL && buf->b_p_bt[0] == 'q';
}
@@ -2453,6 +3129,7 @@ void ex_make(exarg_T *eap)
qf_info_T *qi = &ql_info;
int res;
char_u *au_name = NULL;
+ char_u *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
/* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */
if (grep_internal(eap->cmdidx)) {
@@ -2469,11 +3146,11 @@ void ex_make(exarg_T *eap)
case CMD_lgrepadd: au_name = (char_u *)"lgrepadd"; break;
default: break;
}
- if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
- curbuf->b_fname, TRUE, curbuf);
- if (did_throw || force_abort)
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
return;
+ }
}
if (eap->cmdidx == CMD_lmake || eap->cmdidx == CMD_lgrep
@@ -2504,19 +3181,18 @@ void ex_make(exarg_T *eap)
}
msg_start();
MSG_PUTS(":!");
- msg_outtrans((char_u *) cmd); // show what we are doing
+ msg_outtrans((char_u *)cmd); // show what we are doing
- // let the shell know if we are redirecting output or not
- do_shell((char_u *) cmd, *p_sp != NUL ? kShellOptDoOut : 0);
+ do_shell((char_u *)cmd, 0);
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),
- *eap->cmdlinep);
- if (wp != NULL)
+ (eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd),
+ *eap->cmdlinep, enc);
+ if (wp != NULL) {
qi = GET_LOC_LIST(wp);
+ }
if (au_name != NULL) {
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
curbuf->b_fname, TRUE, curbuf);
@@ -2570,7 +3246,7 @@ static char_u *get_mef_name(void)
STRCPY(name, p_mef);
sprintf((char *)name + (p - p_mef), "%d%d", start, off);
STRCAT(name, p + 2);
- // Don't accept a symbolic link, its a security risk.
+ // Don't accept a symbolic link, it's a security risk.
FileInfo file_info;
bool file_or_link_found = os_fileinfo_link((char *)name, &file_info);
if (!file_or_link_found) {
@@ -2743,7 +3419,6 @@ void ex_cc(exarg_T *eap)
|| eap->cmdidx == CMD_lrewind
|| eap->cmdidx == CMD_lfirst
|| eap->cmdidx == CMD_llast
- || eap->cmdidx == CMD_llast
|| eap->cmdidx == CMD_ldo
|| eap->cmdidx == CMD_lfdo) {
qi = GET_LOC_LIST(curwin);
@@ -2800,7 +3475,6 @@ void ex_cnext(exarg_T *eap)
|| eap->cmdidx == CMD_lnfile
|| eap->cmdidx == CMD_lNfile
|| eap->cmdidx == CMD_lpfile
- || eap->cmdidx == CMD_lpfile
|| eap->cmdidx == CMD_ldo
|| eap->cmdidx == CMD_lfdo) {
qi = GET_LOC_LIST(curwin);
@@ -2860,19 +3534,18 @@ void ex_cfile(exarg_T *eap)
if (*eap->arg != NUL)
set_string_option_direct((char_u *)"ef", -1, eap->arg, OPT_FREE, 0);
- /*
- * This function is used by the :cfile, :cgetfile and :caddfile
- * commands.
- * :cfile always creates a new quickfix list and jumps to the
- * first error.
- * :cgetfile creates a new quickfix list but doesn't jump to the
- * first error.
- * :caddfile adds to an existing quickfix list. If there is no
- * quickfix list then a new list is created.
- */
+ char_u *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
+ // This function is used by the :cfile, :cgetfile and :caddfile
+ // commands.
+ // :cfile always creates a new quickfix list and jumps to the
+ // first error.
+ // :cgetfile creates a new quickfix list but doesn't jump to the
+ // first error.
+ // :caddfile adds to an existing quickfix list. If there is no
+ // quickfix list then a new list is created.
if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
&& eap->cmdidx != CMD_laddfile),
- *eap->cmdlinep) > 0
+ *eap->cmdlinep, enc) > 0
&& (eap->cmdidx == CMD_cfile
|| eap->cmdidx == CMD_lfile)) {
if (au_name != NULL)
@@ -2903,7 +3576,6 @@ void ex_vimgrep(exarg_T *eap)
int fi;
qf_info_T *qi = &ql_info;
qfline_T *cur_qf_start;
- qfline_T *prevp = NULL;
long lnum;
buf_T *buf;
int duplicate_name = FALSE;
@@ -2934,11 +3606,11 @@ void ex_vimgrep(exarg_T *eap)
case CMD_lgrepadd: au_name = (char_u *)"lgrepadd"; break;
default: break;
}
- if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
- curbuf->b_fname, TRUE, curbuf);
- if (did_throw || force_abort)
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
return;
+ }
}
if (eap->cmdidx == CMD_lgrep
@@ -2955,21 +3627,23 @@ void ex_vimgrep(exarg_T *eap)
/* Get the search pattern: either white-separated or enclosed in // */
regmatch.regprog = NULL;
+ char_u *title = vim_strsave(*eap->cmdlinep);
p = skip_vimgrep_pat(eap->arg, &s, &flags);
if (p == NULL) {
EMSG(_(e_invalpat));
goto theend;
}
- if (s != NULL && *s == NUL) {
- /* Pattern is empty, use last search pattern. */
+ if (s == NULL || *s == NUL) {
+ // Pattern is empty, use last search pattern.
if (last_search_pat() == NULL) {
EMSG(_(e_noprevre));
goto theend;
}
regmatch.regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
- } else
+ } else {
regmatch.regprog = vim_regcomp(s, RE_MAGIC);
+ }
if (regmatch.regprog == NULL)
goto theend;
@@ -2986,13 +3660,7 @@ void ex_vimgrep(exarg_T *eap)
&& eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
|| qi->qf_curlist == qi->qf_listcount) {
// make place for a new list
- qf_new_list(qi, *eap->cmdlinep);
- } else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) {
- // Adding to existing list, find last entry.
- for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
- prevp->qf_next != prevp;
- prevp = prevp->qf_next) {
- }
+ qf_new_list(qi, title);
}
/* parse the list of arguments */
@@ -3015,8 +3683,8 @@ void ex_vimgrep(exarg_T *eap)
cur_qf_start = qi->qf_lists[qi->qf_curlist].qf_start;
seconds = (time_t)0;
- for (fi = 0; fi < fcount && !got_int && tomatch > 0; ++fi) {
- fname = path_shorten_fname_if_possible(fnames[fi]);
+ for (fi = 0; fi < fcount && !got_int && tomatch > 0; fi++) {
+ fname = path_try_shorten_fname(fnames[fi]);
if (time(NULL) > seconds) {
/* Display the file name every second or so, show the user we are
* working on it. */
@@ -3088,23 +3756,26 @@ void ex_vimgrep(exarg_T *eap)
++lnum) {
col = 0;
while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
- col, NULL) > 0) {
- ;
- if (qf_add_entry(qi, &prevp,
- NULL, /* dir */
- fname,
- 0,
- ml_get_buf(buf,
- regmatch.startpos[0].lnum + lnum, FALSE),
- regmatch.startpos[0].lnum + lnum,
- regmatch.startpos[0].col + 1,
- FALSE, /* vis_col */
- NULL, /* search pattern */
- 0, /* nr */
- 0, /* type */
- TRUE /* valid */
- ) == FAIL) {
- got_int = TRUE;
+ col, NULL) > 0) {
+ // Pass the buffer number so that it gets used even for a
+ // dummy buffer, unless duplicate_name is set, then the
+ // buffer will be wiped out below.
+ if (qf_add_entry(qi,
+ qi->qf_curlist,
+ NULL, // dir
+ fname,
+ duplicate_name ? 0 : buf->b_fnum,
+ ml_get_buf(buf,
+ regmatch.startpos[0].lnum + lnum, false),
+ regmatch.startpos[0].lnum + lnum,
+ regmatch.startpos[0].col + 1,
+ false, // vis_col
+ NULL, // search pattern
+ 0, // nr
+ 0, // type
+ true) // valid
+ == FAIL) {
+ got_int = true;
break;
}
found_match = TRUE;
@@ -3147,17 +3818,23 @@ void ex_vimgrep(exarg_T *eap)
buf = NULL;
} else if (buf != first_match_buf || (flags & VGR_NOJUMP)) {
unload_dummy_buffer(buf, dirname_start);
+ // Keeping the buffer, remove the dummy flag.
+ buf->b_flags &= ~BF_DUMMY;
buf = NULL;
}
}
if (buf != NULL) {
- /* If the buffer is still loaded we need to use the
- * directory we jumped to below. */
+ // Keeping the buffer, remove the dummy flag.
+ buf->b_flags &= ~BF_DUMMY;
+
+ // If the buffer is still loaded we need to use the
+ // directory we jumped to below.
if (buf == first_match_buf
&& target_dir == NULL
- && STRCMP(dirname_start, dirname_now) != 0)
+ && STRCMP(dirname_start, dirname_now) != 0) {
target_dir = vim_strsave(dirname_now);
+ }
/* The buffer is still loaded, the Filetype autocommands
* need to be done now, in that buffer. And the modelines
@@ -3179,7 +3856,7 @@ void ex_vimgrep(exarg_T *eap)
qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
qi->qf_lists[qi->qf_curlist].qf_index = 1;
- qf_update_buffer(qi);
+ qf_update_buffer(qi, NULL);
if (au_name != NULL)
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
@@ -3214,6 +3891,7 @@ void ex_vimgrep(exarg_T *eap)
}
theend:
+ xfree(title);
xfree(dirname_now);
xfree(dirname_start);
xfree(target_dir);
@@ -3221,52 +3899,6 @@ theend:
}
/*
- * Skip over the pattern argument of ":vimgrep /pat/[g][j]".
- * Put the start of the pattern in "*s", unless "s" is NULL.
- * If "flags" is not NULL put the flags in it: VGR_GLOBAL, VGR_NOJUMP.
- * If "s" is not NULL terminate the pattern with a NUL.
- * Return a pointer to the char just past the pattern plus flags.
- */
-char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
-{
- int c;
-
- if (vim_isIDc(*p)) {
- /* ":vimgrep pattern fname" */
- if (s != NULL)
- *s = p;
- p = skiptowhite(p);
- if (s != NULL && *p != NUL)
- *p++ = NUL;
- } else {
- /* ":vimgrep /pattern/[g][j] fname" */
- if (s != NULL)
- *s = p + 1;
- c = *p;
- p = skip_regexp(p + 1, c, TRUE, NULL);
- if (*p != c)
- return NULL;
-
- /* Truncate the pattern. */
- if (s != NULL)
- *p = NUL;
- ++p;
-
- /* Find the flags */
- while (*p == 'g' || *p == 'j') {
- if (flags != NULL) {
- if (*p == 'g')
- *flags |= VGR_GLOBAL;
- else
- *flags |= VGR_NOJUMP;
- }
- ++p;
- }
- }
- return p;
-}
-
-/*
* Restore current working directory to "dirname_start" if they differ, taking
* into account whether it is set locally or globally.
*/
@@ -3307,21 +3939,27 @@ load_dummy_buffer (
)
{
buf_T *newbuf;
- buf_T *newbuf_to_wipe = NULL;
- int failed = TRUE;
+ bufref_T newbufref;
+ bufref_T newbuf_to_wipe;
+ int failed = true;
aco_save_T aco;
+ int readfile_result;
- /* Allocate a buffer without putting it in the buffer list. */
+ // Allocate a buffer without putting it in the buffer list.
newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY);
- if (newbuf == NULL)
+ if (newbuf == NULL) {
return NULL;
+ }
+ set_bufref(&newbufref, newbuf);
/* Init the options. */
buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP);
/* need to open the memfile before putting the buffer in a window */
if (ml_open(newbuf) == OK) {
- /* set curwin/curbuf to buf and save a few things */
+ // Make sure this buffer isn't wiped out by auto commands.
+ newbuf->b_locked++;
+ // set curwin/curbuf to buf and save a few things
aucmd_prepbuf(&aco, newbuf);
/* Need to set the filename for autocommands. */
@@ -3334,26 +3972,34 @@ load_dummy_buffer (
* work. */
curbuf->b_flags &= ~BF_DUMMY;
- if (readfile(fname, NULL,
- (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM,
- NULL, READ_NEW | READ_DUMMY) == OK
+ newbuf_to_wipe.br_buf = NULL;
+ readfile_result = readfile(fname, NULL, (linenr_T)0, (linenr_T)0,
+ (linenr_T)MAXLNUM, NULL,
+ READ_NEW | READ_DUMMY);
+ newbuf->b_locked--;
+ if (readfile_result == OK
&& !got_int
&& !(curbuf->b_flags & BF_NEW)) {
failed = FALSE;
if (curbuf != newbuf) {
- /* Bloody autocommands changed the buffer! Can happen when
- * using netrw and editing a remote file. Use the current
- * buffer instead, delete the dummy one after restoring the
- * window stuff. */
- newbuf_to_wipe = newbuf;
+ // Bloody autocommands changed the buffer! Can happen when
+ // using netrw and editing a remote file. Use the current
+ // buffer instead, delete the dummy one after restoring the
+ // window stuff.
+ set_bufref(&newbuf_to_wipe, newbuf);
newbuf = curbuf;
}
}
- /* restore curwin/curbuf and a few other things */
+ // Restore curwin/curbuf and a few other things.
aucmd_restbuf(&aco);
- if (newbuf_to_wipe != NULL && buf_valid(newbuf_to_wipe))
- wipe_buffer(newbuf_to_wipe, FALSE);
+ if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) {
+ wipe_buffer(newbuf_to_wipe.br_buf, false);
+ }
+
+ // Add back the "dummy" flag, otherwise buflist_findname_file_id()
+ // won't skip it.
+ newbuf->b_flags |= BF_DUMMY;
}
/*
@@ -3364,8 +4010,9 @@ load_dummy_buffer (
os_dirname(resulting_dir, MAXPATHL);
restore_start_dir(dirname_start);
- if (!buf_valid(newbuf))
+ if (!bufref_valid(&newbufref)) {
return NULL;
+ }
if (failed) {
wipe_dummy_buffer(newbuf, dirname_start);
return NULL;
@@ -3413,107 +4060,301 @@ static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start)
}
}
-/*
- * Add each quickfix error to list "list" as a dictionary.
- */
-int get_errorlist(win_T *wp, list_T *list)
+/// Add each quickfix error to list "list" as a dictionary.
+/// If qf_idx is -1, use the current list. Otherwise, use the specified list.
+int get_errorlist(const qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list)
{
- qf_info_T *qi = &ql_info;
- dict_T *dict;
+ const qf_info_T *qi = qi_arg;
char_u buf[2];
qfline_T *qfp;
int i;
int bufnum;
- if (wp != NULL) {
- qi = GET_LOC_LIST(wp);
- if (qi == NULL)
- return FAIL;
+ if (qi == NULL) {
+ qi = &ql_info;
+ if (wp != NULL) {
+ qi = GET_LOC_LIST(wp);
+ if (qi == NULL) {
+ return FAIL;
+ }
+ }
}
- if (qi->qf_curlist >= qi->qf_listcount
- || qi->qf_lists[qi->qf_curlist].qf_count == 0)
+ if (qf_idx == -1) {
+ qf_idx = qi->qf_curlist;
+ }
+
+ if (qf_idx >= qi->qf_listcount
+ || qi->qf_lists[qf_idx].qf_count == 0) {
return FAIL;
+ }
- qfp = qi->qf_lists[qi->qf_curlist].qf_start;
- for (i = 1; !got_int && i <= qi->qf_lists[qi->qf_curlist].qf_count; ++i) {
- /* Handle entries with a non-existing buffer number. */
+ qfp = qi->qf_lists[qf_idx].qf_start;
+ for (i = 1; !got_int && i <= qi->qf_lists[qf_idx].qf_count; i++) {
+ // Handle entries with a non-existing buffer number.
bufnum = qfp->qf_fnum;
if (bufnum != 0 && (buflist_findnr(bufnum) == NULL))
bufnum = 0;
- dict = dict_alloc();
- list_append_dict(list, dict);
+ dict_T *const dict = tv_dict_alloc();
+ tv_list_append_dict(list, dict);
buf[0] = qfp->qf_type;
buf[1] = NUL;
- if ( dict_add_nr_str(dict, "bufnr", (long)bufnum, NULL) == FAIL
- || dict_add_nr_str(dict, "lnum", (long)qfp->qf_lnum, NULL) == FAIL
- || dict_add_nr_str(dict, "col", (long)qfp->qf_col, NULL) == FAIL
- || dict_add_nr_str(dict, "vcol", (long)qfp->qf_viscol, NULL) == FAIL
- || dict_add_nr_str(dict, "nr", (long)qfp->qf_nr, NULL) == FAIL
- || dict_add_nr_str(dict, "pattern", 0L,
- qfp->qf_pattern == NULL ? (char_u *)"" : qfp->qf_pattern) == FAIL
- || dict_add_nr_str(dict, "text", 0L,
- qfp->qf_text == NULL ? (char_u *)"" : qfp->qf_text) == FAIL
- || dict_add_nr_str(dict, "type", 0L, buf) == FAIL
- || dict_add_nr_str(dict, "valid", (long)qfp->qf_valid, NULL) == FAIL)
- return FAIL;
+ if (tv_dict_add_nr(dict, S_LEN("bufnr"), (varnumber_T)bufnum) == FAIL
+ || (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum)
+ == FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)qfp->qf_col)
+ == FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol)
+ == FAIL)
+ || (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL)
+ || tv_dict_add_str(dict, S_LEN("pattern"),
+ (qfp->qf_pattern == NULL
+ ? ""
+ : (const char *)qfp->qf_pattern)) == FAIL
+ || tv_dict_add_str(dict, S_LEN("text"),
+ (qfp->qf_text == NULL
+ ? ""
+ : (const char *)qfp->qf_text)) == FAIL
+ || tv_dict_add_str(dict, S_LEN("type"), (const char *)buf) == FAIL
+ || (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid)
+ == FAIL)) {
+ // tv_dict_add* fail only if key already exist, but this is a newly
+ // allocated dictionary which is thus guaranteed to have no existing keys.
+ assert(false);
+ }
qfp = qfp->qf_next;
+ if (qfp == NULL) {
+ break;
+ }
}
return OK;
}
-/*
- * Populate the quickfix list with the items supplied in the list
- * of dictionaries. "title" will be copied to w:quickfix_title
- */
-int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
+/// Flags used by getqflist()/getloclist() to determine which fields to return.
+enum {
+ QF_GETLIST_NONE = 0x0,
+ QF_GETLIST_TITLE = 0x1,
+ QF_GETLIST_ITEMS = 0x2,
+ QF_GETLIST_NR = 0x4,
+ QF_GETLIST_WINID = 0x8,
+ QF_GETLIST_CONTEXT = 0x10,
+ QF_GETLIST_ID = 0x20,
+ QF_GETLIST_ALL = 0xFF
+};
+
+// Parse text from 'di' and return the quickfix list items
+static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
+{
+ int status = FAIL;
+ char_u *errorformat = p_efm;
+ dictitem_T *efm_di;
+
+ // Only a List value is supported
+ if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) {
+ // If errorformat is supplied then use it, otherwise use the 'efm'
+ // option setting
+ if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) {
+ if (efm_di->di_tv.v_type != VAR_STRING
+ || efm_di->di_tv.vval.v_string == NULL) {
+ return FAIL;
+ }
+ errorformat = efm_di->di_tv.vval.v_string;
+ }
+
+ list_T *l = tv_list_alloc(kListLenMayKnow);
+ qf_info_T *qi = xmalloc(sizeof(*qi));
+ memset(qi, 0, sizeof(*qi));
+ qi->qf_refcount++;
+
+ if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
+ true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) {
+ (void)get_errorlist(qi, NULL, 0, l);
+ qf_free(qi, 0);
+ }
+ xfree(qi);
+
+ tv_dict_add_list(retdict, S_LEN("items"), l);
+ status = OK;
+ }
+
+ return status;
+}
+
+/// Return quickfix/location list details (title) as a
+/// dictionary. 'what' contains the details to return. If 'list_idx' is -1,
+/// then current list is used. Otherwise the specified list is used.
+int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
{
- listitem_T *li;
- dict_T *d;
- qfline_T *prevp = NULL;
- int retval = OK;
qf_info_T *qi = &ql_info;
- bool did_bufnr_emsg = false;
+ dictitem_T *di;
+
+ if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) {
+ return qf_get_list_from_lines(what, di, retdict);
+ }
if (wp != NULL) {
- qi = ll_get_or_alloc_list(wp);
+ qi = GET_LOC_LIST(wp);
+ }
+ // List is not present or is empty
+ if (qi == NULL || qi->qf_listcount == 0) {
+ // If querying for the size of the list, return 0
+ if (((di = tv_dict_find(what, S_LEN("nr"))) != NULL)
+ && (di->di_tv.v_type == VAR_STRING)
+ && (STRCMP(di->di_tv.vval.v_string, "$") == 0)) {
+ return tv_dict_add_nr(retdict, S_LEN("nr"), 0);
+ }
+ return FAIL;
+ }
+
+ int status = OK;
+ int flags = QF_GETLIST_NONE;
+
+ int qf_idx = qi->qf_curlist; // default is the current list
+ if ((di = tv_dict_find(what, S_LEN("nr"))) != NULL) {
+ // Use the specified quickfix/location list
+ if (di->di_tv.v_type == VAR_NUMBER) {
+ // for zero use the current list
+ if (di->di_tv.vval.v_number != 0) {
+ qf_idx = (int)di->di_tv.vval.v_number - 1;
+ if (qf_idx < 0 || qf_idx >= qi->qf_listcount) {
+ return FAIL;
+ }
+ }
+ } else if (di->di_tv.v_type == VAR_STRING
+ && strequal((const char *)di->di_tv.vval.v_string, "$")) {
+ // Get the last quickfix list number
+ qf_idx = qi->qf_listcount - 1;
+ } else {
+ return FAIL;
+ }
+ flags |= QF_GETLIST_NR;
+ }
+
+ if ((di = tv_dict_find(what, S_LEN("id"))) != NULL) {
+ // Look for a list with the specified id
+ if (di->di_tv.v_type == VAR_NUMBER) {
+ // For zero, use the current list or the list specifed by 'nr'
+ if (di->di_tv.vval.v_number != 0) {
+ for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++) {
+ if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number) {
+ break;
+ }
+ }
+ if (qf_idx == qi->qf_listcount) {
+ return FAIL; // List not found
+ }
+ }
+ flags |= QF_GETLIST_ID;
+ } else {
+ return FAIL;
+ }
+ }
+
+ if (tv_dict_find(what, S_LEN("all")) != NULL) {
+ flags |= QF_GETLIST_ALL;
+ }
+ if (tv_dict_find(what, S_LEN("title")) != NULL) {
+ flags |= QF_GETLIST_TITLE;
+ }
+ if (tv_dict_find(what, S_LEN("winid")) != NULL) {
+ flags |= QF_GETLIST_WINID;
+ }
+ if (tv_dict_find(what, S_LEN("context")) != NULL) {
+ flags |= QF_GETLIST_CONTEXT;
+ }
+ if (tv_dict_find(what, S_LEN("items")) != NULL) {
+ flags |= QF_GETLIST_ITEMS;
+ }
+
+ if (flags & QF_GETLIST_TITLE) {
+ char_u *t = qi->qf_lists[qf_idx].qf_title;
+ if (t == NULL) {
+ t = (char_u *)"";
+ }
+ status = tv_dict_add_str(retdict, S_LEN("title"), (const char *)t);
+ }
+ if ((status == OK) && (flags & QF_GETLIST_NR)) {
+ status = tv_dict_add_nr(retdict, S_LEN("nr"), qf_idx + 1);
+ }
+ if ((status == OK) && (flags & QF_GETLIST_WINID)) {
+ win_T *win = qf_find_win(qi);
+ if (win != NULL) {
+ status = tv_dict_add_nr(retdict, S_LEN("winid"), win->handle);
+ }
+ }
+ if ((status == OK) && (flags & QF_GETLIST_ITEMS)) {
+ list_T *l = tv_list_alloc(kListLenMayKnow);
+ (void)get_errorlist(qi, NULL, qf_idx, l);
+ tv_dict_add_list(retdict, S_LEN("items"), l);
+ }
+
+ if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) {
+ if (qi->qf_lists[qf_idx].qf_ctx != NULL) {
+ di = tv_dict_item_alloc_len(S_LEN("context"));
+ tv_copy(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
+ status = tv_dict_add(retdict, di);
+ if (status == FAIL) {
+ tv_dict_item_free(di);
+ }
+ } else {
+ status = tv_dict_add_str(retdict, S_LEN("context"), "");
+ }
+ }
+
+ if ((status == OK) && (flags & QF_GETLIST_ID)) {
+ status = tv_dict_add_nr(retdict, S_LEN("id"), qi->qf_lists[qf_idx].qf_id);
}
- if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
- /* make place for a new list */
+ return status;
+}
+
+/// Add list of entries to quickfix/location list. Each list entry is
+/// a dictionary with item information.
+static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list,
+ char_u *title, int action)
+{
+ dict_T *d;
+ qfline_T *old_last = NULL;
+ int retval = OK;
+ bool did_bufnr_emsg = false;
+
+ if (action == ' ' || qf_idx == qi->qf_listcount) {
+ // make place for a new list
qf_new_list(qi, title);
- else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
- /* Adding to existing list, find last entry. */
- for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
- prevp->qf_next != prevp; prevp = prevp->qf_next)
- ;
- else if (action == 'r') {
- qf_free(qi, qi->qf_curlist);
- qf_store_title(qi, title);
+ qf_idx = qi->qf_curlist;
+ } else if (action == 'a' && qi->qf_lists[qf_idx].qf_count > 0) {
+ // Adding to existing list, use last entry.
+ old_last = qi->qf_lists[qf_idx].qf_last;
+ } else if (action == 'r') {
+ qf_free_items(qi, qf_idx);
+ qf_store_title(qi, qf_idx, title);
}
- for (li = list->lv_first; li != NULL; li = li->li_next) {
- if (li->li_tv.v_type != VAR_DICT)
- continue; /* Skip non-dict items */
+ TV_LIST_ITER_CONST(list, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type != VAR_DICT) {
+ continue; // Skip non-dict items.
+ }
- d = li->li_tv.vval.v_dict;
- if (d == NULL)
+ d = TV_LIST_ITEM_TV(li)->vval.v_dict;
+ if (d == NULL) {
continue;
+ }
- char_u *filename = get_dict_string(d, (char_u *)"filename", true);
- int bufnum = (int)get_dict_number(d, (char_u *)"bufnr");
- long lnum = get_dict_number(d, (char_u *)"lnum");
- int col = (int)get_dict_number(d, (char_u *)"col");
- char_u vcol = (char_u)get_dict_number(d, (char_u *)"vcol");
- int nr = (int)get_dict_number(d, (char_u *)"nr");
- char_u *type = get_dict_string(d, (char_u *)"type", true);
- char_u *pattern = get_dict_string(d, (char_u *)"pattern", true);
- char_u *text = get_dict_string(d, (char_u *)"text", true);
+ char *const filename = tv_dict_get_string(d, "filename", true);
+ int bufnum = (int)tv_dict_get_number(d, "bufnr");
+ long lnum = (long)tv_dict_get_number(d, "lnum");
+ int col = (int)tv_dict_get_number(d, "col");
+ char_u vcol = (char_u)tv_dict_get_number(d, "vcol");
+ int nr = (int)tv_dict_get_number(d, "nr");
+ const char *type_str = tv_dict_get_string(d, "type", false);
+ const char_u type = (char_u)(uint8_t)(type_str == NULL ? NUL : *type_str);
+ char *const pattern = tv_dict_get_string(d, "pattern", true);
+ char *text = tv_dict_get_string(d, "text", true);
if (text == NULL) {
- text = vim_strsave((char_u *)"");
+ text = xcalloc(1, 1);
}
bool valid = true;
if ((filename == NULL && bufnum == 0) || (lnum == 0 && pattern == NULL)) {
@@ -3531,44 +4372,296 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
bufnum = 0;
}
+ // If the 'valid' field is present it overrules the detected value.
+ if (tv_dict_find(d, "valid", -1) != NULL) {
+ valid = (int)tv_dict_get_number(d, "valid");
+ }
+
int status = qf_add_entry(qi,
- &prevp,
+ qf_idx,
NULL, // dir
- filename,
+ (char_u *)filename,
bufnum,
- text,
+ (char_u *)text,
lnum,
col,
vcol, // vis_col
- pattern, // search pattern
+ (char_u *)pattern, // search pattern
nr,
- (char_u)(type == NULL ? NUL : *type),
+ type,
valid);
xfree(filename);
xfree(pattern);
xfree(text);
- xfree(type);
if (status == FAIL) {
retval = FAIL;
break;
}
+ });
+
+ if (qi->qf_lists[qf_idx].qf_index == 0) {
+ // no valid entry
+ qi->qf_lists[qf_idx].qf_nonevalid = true;
+ } else {
+ qi->qf_lists[qf_idx].qf_nonevalid = false;
+ }
+ if (action != 'a') {
+ qi->qf_lists[qf_idx].qf_ptr = qi->qf_lists[qf_idx].qf_start;
+ if (qi->qf_lists[qf_idx].qf_count > 0) {
+ qi->qf_lists[qf_idx].qf_index = 1;
+ }
}
- if (qi->qf_lists[qi->qf_curlist].qf_index == 0)
- /* no valid entry */
- qi->qf_lists[qi->qf_curlist].qf_nonevalid = TRUE;
- else
- qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
- qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start;
- qi->qf_lists[qi->qf_curlist].qf_index = 1;
+ // Don't update the cursor in quickfix window when appending entries
+ qf_update_buffer(qi, old_last);
+
+ return retval;
+}
+
+static int qf_set_properties(qf_info_T *qi, dict_T *what, int action,
+ char_u *title)
+{
+ dictitem_T *di;
+ int retval = FAIL;
+ int newlist = false;
+ char_u *errorformat = p_efm;
+
+ if (action == ' ' || qi->qf_curlist == qi->qf_listcount) {
+ newlist = true;
+ }
+ int qf_idx = qi->qf_curlist; // default is the current list
+ if ((di = tv_dict_find(what, S_LEN("nr"))) != NULL) {
+ // Use the specified quickfix/location list
+ if (di->di_tv.v_type == VAR_NUMBER) {
+ // for zero use the current list
+ if (di->di_tv.vval.v_number != 0) {
+ qf_idx = (int)di->di_tv.vval.v_number - 1;
+ }
+
+ if ((action == ' ' || action == 'a') && qf_idx == qi->qf_listcount) {
+ // When creating a new list, accept qf_idx pointing to the next
+ // non-available list and add the new list at the end of the
+ // stack.
+ newlist = true;
+ qf_idx = qi->qf_listcount - 1;
+ } else if (qf_idx < 0 || qf_idx >= qi->qf_listcount) {
+ return FAIL;
+ } else if (action != ' ') {
+ newlist = false; // use the specified list
+ }
+ } else if (di->di_tv.v_type == VAR_STRING
+ && strequal((const char *)di->di_tv.vval.v_string, "$")) {
+ if (qi->qf_listcount > 0) {
+ qf_idx = qi->qf_listcount - 1;
+ } else if (newlist) {
+ qf_idx = 0;
+ } else {
+ return FAIL;
+ }
+ } else {
+ return FAIL;
+ }
+ }
+
+ if (!newlist && (di = tv_dict_find(what, S_LEN("id"))) != NULL) {
+ // Use the quickfix/location list with the specified id
+ if (di->di_tv.v_type == VAR_NUMBER) {
+ for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++) {
+ if (qi->qf_lists[qf_idx].qf_id == di->di_tv.vval.v_number) {
+ break;
+ }
+ }
+ if (qf_idx == qi->qf_listcount) {
+ return FAIL; // List not found
+ }
+ } else {
+ return FAIL;
+ }
+ }
+
+ if (newlist) {
+ qi->qf_curlist = qf_idx;
+ qf_new_list(qi, title);
+ qf_idx = qi->qf_curlist;
+ }
+
+ if ((di = tv_dict_find(what, S_LEN("title"))) != NULL) {
+ if (di->di_tv.v_type == VAR_STRING) {
+ xfree(qi->qf_lists[qf_idx].qf_title);
+ qi->qf_lists[qf_idx].qf_title = (char_u *)tv_dict_get_string(
+ what, "title", true);
+ if (qf_idx == qi->qf_curlist) {
+ qf_update_win_titlevar(qi);
+ }
+ retval = OK;
+ }
+ }
+ if ((di = tv_dict_find(what, S_LEN("items"))) != NULL) {
+ if (di->di_tv.v_type == VAR_LIST) {
+ assert(qi->qf_lists[qf_idx].qf_title != NULL);
+ char_u *title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title);
+
+ retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list,
+ title_save, action == ' ' ? 'a' : action);
+ xfree(title_save);
+ }
+ }
+
+ if ((di = tv_dict_find(what, S_LEN("efm"))) != NULL) {
+ if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL) {
+ return FAIL;
+ }
+ errorformat = di->di_tv.vval.v_string;
+ }
+
+ if ((di = tv_dict_find(what, S_LEN("lines"))) != NULL) {
+ // Only a List value is supported
+ if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) {
+ if (action == 'r') {
+ qf_free_items(qi, qf_idx);
+ }
+ if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat,
+ false, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) {
+ retval = OK;
+ }
+ } else {
+ return FAIL;
+ }
+ }
+
+ if ((di = tv_dict_find(what, S_LEN("context"))) != NULL) {
+ tv_free(qi->qf_lists[qf_idx].qf_ctx);
+
+ typval_T *ctx = xcalloc(1, sizeof(typval_T));
+ tv_copy(&di->di_tv, ctx);
+ qi->qf_lists[qf_idx].qf_ctx = ctx;
+ retval = OK;
+ }
+
+ return retval;
+}
+
+// Find the non-location list window with the specified location list.
+static win_T * find_win_with_ll(qf_info_T *qi)
+{
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if ((wp->w_llist == qi) && !bt_quickfix(wp->w_buffer)) {
+ return wp;
+ }
+ }
+
+ return NULL;
+}
+
+// Free the entire quickfix/location list stack.
+// If the quickfix/location list window is open, then clear it.
+static void qf_free_stack(win_T *wp, qf_info_T *qi)
+{
+ win_T *qfwin = qf_find_win(qi);
+
+ if (qfwin != NULL) {
+ // If the quickfix/location list window is open, then clear it
+ if (qi->qf_curlist < qi->qf_listcount) {
+ qf_free(qi, qi->qf_curlist);
+ }
+ qf_update_buffer(qi, NULL);
+ }
+
+ win_T *llwin = NULL;
+ win_T *orig_wp = wp;
+ if (wp != NULL && IS_LL_WINDOW(wp)) {
+ // If in the location list window, then use the non-location list
+ // window with this location list (if present)
+ llwin = find_win_with_ll(qi);
+ if (llwin != NULL) {
+ wp = llwin;
+ }
+ }
+
+ qf_free_all(wp);
+ if (wp == NULL) {
+ // quickfix list
+ qi->qf_curlist = 0;
+ qi->qf_listcount = 0;
+ } else if (IS_LL_WINDOW(orig_wp)) {
+ // If the location list window is open, then create a new empty location
+ // list
+ qf_info_T *new_ll = ll_new_list();
+
+ // first free the list reference in the location list window
+ ll_free_all(&orig_wp->w_llist_ref);
+
+ orig_wp->w_llist_ref = new_ll;
+ if (llwin != NULL) {
+ llwin->w_llist = new_ll;
+ new_ll->qf_refcount++;
+ }
+ }
+}
+
+// Populate the quickfix list with the items supplied in the list
+// of dictionaries. "title" will be copied to w:quickfix_title
+// "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
+int set_errorlist(win_T *wp, list_T *list, int action, char_u *title,
+ dict_T *what)
+{
+ qf_info_T *qi = &ql_info;
+ int retval = OK;
- qf_update_buffer(qi);
+ if (wp != NULL) {
+ qi = ll_get_or_alloc_list(wp);
+ }
+
+ if (action == 'f') {
+ // Free the entire quickfix or location list stack
+ qf_free_stack(wp, qi);
+ } else if (what != NULL) {
+ retval = qf_set_properties(qi, what, action, title);
+ } else {
+ retval = qf_add_entries(qi, qi->qf_curlist, list, title, action);
+ }
return retval;
}
+static bool mark_quickfix_ctx(qf_info_T *qi, int copyID)
+{
+ bool abort = false;
+
+ for (int i = 0; i < LISTCOUNT && !abort; i++) {
+ 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 = set_ref_in_item(ctx, copyID, NULL, NULL);
+ }
+ }
+
+ return abort;
+}
+
+/// Mark the context of the quickfix list and the location lists (if present) as
+/// "in use". So that garabage collection doesn't free the context.
+bool set_ref_in_quickfix(int copyID)
+{
+ bool abort = mark_quickfix_ctx(&ql_info, copyID);
+ if (abort) {
+ return abort;
+ }
+
+ FOR_ALL_TAB_WINDOWS(tp, win) {
+ if (win->w_llist != NULL) {
+ abort = mark_quickfix_ctx(win->w_llist, copyID);
+ if (abort) {
+ return abort;
+ }
+ }
+ }
+
+ return abort;
+}
+
/*
* ":[range]cbuffer [bufnr]" command.
* ":[range]caddbuffer [bufnr]" command.
@@ -3579,10 +4672,43 @@ int set_errorlist(win_T *wp, list_T *list, int action, char_u *title)
*/
void ex_cbuffer(exarg_T *eap)
{
- buf_T *buf = NULL;
- qf_info_T *qi = &ql_info;
+ buf_T *buf = NULL;
+ qf_info_T *qi = &ql_info;
+ const char *au_name = NULL;
+
+ switch (eap->cmdidx) {
+ case CMD_cbuffer:
+ au_name = "cbuffer";
+ break;
+ case CMD_cgetbuffer:
+ au_name = "cgetbuffer";
+ break;
+ case CMD_caddbuffer:
+ au_name = "caddbuffer";
+ break;
+ case CMD_lbuffer:
+ au_name = "lbuffer";
+ break;
+ case CMD_lgetbuffer:
+ au_name = "lgetbuffer";
+ break;
+ case CMD_laddbuffer:
+ au_name = "laddbuffer";
+ break;
+ default:
+ break;
+ }
+
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
+ return;
+ }
+ }
- if (eap->cmdidx == CMD_lbuffer || eap->cmdidx == CMD_lgetbuffer
+ // Must come after autocommands.
+ if (eap->cmdidx == CMD_lbuffer
+ || eap->cmdidx == CMD_lgetbuffer
|| eap->cmdidx == CMD_laddbuffer) {
qi = ll_get_or_alloc_list(curwin);
}
@@ -3612,14 +4738,18 @@ void ex_cbuffer(exarg_T *eap)
qf_title = IObuff;
}
- if (qf_init_ext(qi, NULL, buf, NULL, p_efm,
- (eap->cmdidx != CMD_caddbuffer
- && eap->cmdidx != CMD_laddbuffer),
- eap->line1, eap->line2,
- qf_title) > 0
- && (eap->cmdidx == CMD_cbuffer
- || eap->cmdidx == CMD_lbuffer))
- qf_jump(qi, 0, 0, eap->forceit); /* display first error */
+ if (qf_init_ext(qi, qi->qf_curlist, NULL, buf, NULL, p_efm,
+ (eap->cmdidx != CMD_caddbuffer
+ && eap->cmdidx != CMD_laddbuffer),
+ eap->line1, eap->line2, qf_title, NULL) > 0) {
+ if (au_name != NULL) {
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name,
+ curbuf->b_fname, true, curbuf);
+ }
+ if (eap->cmdidx == CMD_cbuffer || eap->cmdidx == CMD_lbuffer) {
+ qf_jump(qi, 0, 0, eap->forceit); // display first error
+ }
+ }
}
}
}
@@ -3630,30 +4760,65 @@ void ex_cbuffer(exarg_T *eap)
*/
void ex_cexpr(exarg_T *eap)
{
- typval_T *tv;
- qf_info_T *qi = &ql_info;
+ qf_info_T *qi = &ql_info;
+ const char *au_name = NULL;
if (eap->cmdidx == CMD_lexpr || eap->cmdidx == CMD_lgetexpr
|| eap->cmdidx == CMD_laddexpr) {
qi = ll_get_or_alloc_list(curwin);
}
+ switch (eap->cmdidx) {
+ case CMD_cexpr:
+ au_name = "cexpr";
+ break;
+ case CMD_cgetexpr:
+ au_name = "cgetexpr";
+ break;
+ case CMD_caddexpr:
+ au_name = "caddexpr";
+ break;
+ case CMD_lexpr:
+ au_name = "lexpr";
+ break;
+ case CMD_lgetexpr:
+ au_name = "lgetexpr";
+ break;
+ case CMD_laddexpr:
+ au_name = "laddexpr";
+ break;
+ default:
+ break;
+ }
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, (char_u *)au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
+ return;
+ }
+ }
+
/* Evaluate the expression. When the result is a string or a list we can
* use it to fill the errorlist. */
- tv = eval_expr(eap->arg, NULL);
- if (tv != NULL) {
- if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL)
- || (tv->v_type == VAR_LIST && tv->vval.v_list != NULL)) {
- if (qf_init_ext(qi, NULL, NULL, tv, p_efm,
- (eap->cmdidx != CMD_caddexpr
- && eap->cmdidx != CMD_laddexpr),
- (linenr_T)0, (linenr_T)0, *eap->cmdlinep) > 0
- && (eap->cmdidx == CMD_cexpr
- || eap->cmdidx == CMD_lexpr))
- qf_jump(qi, 0, 0, eap->forceit); /* display first error */
- } else
+ typval_T tv;
+ if (eval0(eap->arg, &tv, NULL, true) != FAIL) {
+ if ((tv.v_type == VAR_STRING && tv.vval.v_string != NULL)
+ || tv.v_type == VAR_LIST) {
+ if (qf_init_ext(qi, qi->qf_curlist, NULL, NULL, &tv, p_efm,
+ (eap->cmdidx != CMD_caddexpr
+ && eap->cmdidx != CMD_laddexpr),
+ (linenr_T)0, (linenr_T)0, *eap->cmdlinep, NULL) > 0) {
+ if (au_name != NULL) {
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name,
+ curbuf->b_fname, true, curbuf);
+ }
+ if (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr) {
+ qf_jump(qi, 0, 0, eap->forceit); // display first error
+ }
+ }
+ } else {
EMSG(_("E777: String or List expected"));
- free_tv(tv);
+ }
+ tv_clear(&tv);
}
}
@@ -3669,7 +4834,6 @@ void ex_helpgrep(exarg_T *eap)
char_u **fnames;
FILE *fd;
int fi;
- qfline_T *prevp = NULL;
long lnum;
char_u *lang;
qf_info_T *qi = &ql_info;
@@ -3684,11 +4848,11 @@ void ex_helpgrep(exarg_T *eap)
case CMD_lhelpgrep: au_name = (char_u *)"lhelpgrep"; break;
default: break;
}
- if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
- curbuf->b_fname, TRUE, curbuf);
- if (did_throw || force_abort)
+ if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name,
+ curbuf->b_fname, true, curbuf)) {
+ if (aborting()) {
return;
+ }
}
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
@@ -3696,16 +4860,26 @@ void ex_helpgrep(exarg_T *eap)
p_cpo = empty_option;
if (eap->cmdidx == CMD_lhelpgrep) {
- qi = NULL;
+ win_T *wp = NULL;
- /* Find an existing help window */
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if (wp->w_buffer != NULL && wp->w_buffer->b_help) {
- qi = wp->w_llist;
+ // If the current window is a help window, then use it
+ if (bt_help(curwin->w_buffer)) {
+ wp = curwin;
+ } else {
+ // Find an existing help window
+ FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
+ if (bt_help(wp2->w_buffer)) {
+ wp = wp2;
+ break;
+ }
}
}
- /* Help window not found */
+ if (wp == NULL) { // Help window not found
+ qi = NULL;
+ } else {
+ qi = wp->w_llist;
+ }
if (qi == NULL) {
/* Allocate a new location list for help text matches */
qi = ll_new_list();
@@ -3713,18 +4887,13 @@ void ex_helpgrep(exarg_T *eap)
}
}
+ // Autocommands may change the list. Save it for later comparison
+ qf_info_T *save_qi = qi;
+
regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING);
regmatch.rm_ic = FALSE;
if (regmatch.regprog != NULL) {
- vimconv_T vc;
-
- /* Help files are in utf-8 or latin1, convert lines when 'encoding'
- * differs. */
- vc.vc_type = CONV_NONE;
- if (!enc_utf8)
- convert_setup(&vc, (char_u *)"utf-8", p_enc);
-
- /* create a new quickfix list */
+ // Create a new quickfix list.
qf_new_list(qi, *eap->cmdlinep);
/* Go through all directories in 'runtimepath' */
@@ -3756,15 +4925,6 @@ void ex_helpgrep(exarg_T *eap)
lnum = 1;
while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {
char_u *line = IObuff;
- /* Convert a line if 'encoding' is not utf-8 and
- * the line contains a non-ASCII character. */
- if (vc.vc_type != CONV_NONE
- && has_non_ascii(IObuff)) {
- line = string_convert(&vc, IObuff, NULL);
- if (line == NULL)
- line = IObuff;
- }
-
if (vim_regexec(&regmatch, line, (colnr_T)0)) {
int l = (int)STRLEN(line);
@@ -3772,23 +4932,25 @@ void ex_helpgrep(exarg_T *eap)
while (l > 0 && line[l - 1] <= ' ')
line[--l] = NUL;
- if (qf_add_entry(qi, &prevp,
- NULL, /* dir */
- fnames[fi],
- 0,
- line,
- lnum,
- (int)(regmatch.startp[0] - line)
- + 1, /* col */
- FALSE, /* vis_col */
- NULL, /* search pattern */
- 0, /* nr */
- 1, /* type */
- TRUE /* valid */
- ) == FAIL) {
- got_int = TRUE;
- if (line != IObuff)
+ if (qf_add_entry(qi,
+ qi->qf_curlist,
+ NULL, // dir
+ fnames[fi],
+ 0,
+ line,
+ lnum,
+ (int)(regmatch.startp[0] - line)
+ + 1, // col
+ false, // vis_col
+ NULL, // search pattern
+ 0, // nr
+ 1, // type
+ true) // valid
+ == FAIL) {
+ got_int = true;
+ if (line != IObuff) {
xfree(line);
+ }
break;
}
}
@@ -3805,8 +4967,6 @@ void ex_helpgrep(exarg_T *eap)
}
vim_regfree(regmatch.regprog);
- if (vc.vc_type != CONV_NONE)
- convert_setup(&vc, NULL, NULL);
qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
qi->qf_lists[qi->qf_curlist].qf_ptr =
@@ -3820,14 +4980,15 @@ void ex_helpgrep(exarg_T *eap)
/* Darn, some plugin changed the value. */
free_string_option(save_cpo);
- qf_update_buffer(qi);
+ qf_update_buffer(qi, NULL);
if (au_name != NULL) {
apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name,
- curbuf->b_fname, TRUE, curbuf);
- if (!new_qi && qi != &ql_info && qf_find_buf(qi) == NULL)
- /* autocommands made "qi" invalid */
+ curbuf->b_fname, true, curbuf);
+ if (!new_qi && qi != save_qi && qf_find_buf(qi) == NULL) {
+ // autocommands made "qi" invalid
return;
+ }
}
/* Jump to first match. */
@@ -3839,11 +5000,13 @@ void ex_helpgrep(exarg_T *eap)
if (eap->cmdidx == CMD_lhelpgrep) {
/* If the help window is not opened or if it already points to the
* correct location list, then free the new location list. */
- if (!curwin->w_buffer->b_help || curwin->w_llist == qi) {
- if (new_qi)
+ if (!bt_help(curwin->w_buffer) || curwin->w_llist == qi) {
+ if (new_qi) {
ll_free_all(&qi);
- } else if (curwin->w_llist == NULL)
+ }
+ } else if (curwin->w_llist == NULL) {
curwin->w_llist = qi;
+ }
}
}
diff --git a/src/nvim/quickfix.h b/src/nvim/quickfix.h
index bb9c2c3193..fdeb8d1a2f 100644
--- a/src/nvim/quickfix.h
+++ b/src/nvim/quickfix.h
@@ -1,6 +1,9 @@
#ifndef NVIM_QUICKFIX_H
#define NVIM_QUICKFIX_H
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
/* flags for skip_vimgrep_pat() */
#define VGR_GLOBAL 1
#define VGR_NOJUMP 2
diff --git a/src/nvim/rbuffer.c b/src/nvim/rbuffer.c
index a2cc432eca..df9394fbb2 100644
--- a/src/nvim/rbuffer.c
+++ b/src/nvim/rbuffer.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 <stddef.h>
#include <string.h>
@@ -18,7 +21,7 @@ RBuffer *rbuffer_new(size_t capacity)
capacity = 0x10000;
}
- RBuffer *rv = xmalloc(sizeof(RBuffer) + capacity);
+ RBuffer *rv = xcalloc(1, sizeof(RBuffer) + capacity);
rv->full_cb = rv->nonfull_cb = NULL;
rv->data = NULL;
rv->size = 0;
@@ -78,7 +81,7 @@ void rbuffer_reset(RBuffer *buf) FUNC_ATTR_NONNULL_ALL
size_t temp_size;
if ((temp_size = rbuffer_size(buf))) {
if (buf->temp == NULL) {
- buf->temp = xmalloc(rbuffer_capacity(buf));
+ buf->temp = xcalloc(1, rbuffer_capacity(buf));
}
rbuffer_read(buf, buf->temp, buf->size);
}
@@ -118,7 +121,7 @@ char *rbuffer_read_ptr(RBuffer *buf, size_t *read_count) FUNC_ATTR_NONNULL_ALL
{
if (!buf->size) {
*read_count = 0;
- return NULL;
+ return buf->read_ptr;
}
if (buf->read_ptr < buf->write_ptr) {
diff --git a/src/nvim/rbuffer.h b/src/nvim/rbuffer.h
index 454972c69d..a8dfcac580 100644
--- a/src/nvim/rbuffer.h
+++ b/src/nvim/rbuffer.h
@@ -1,4 +1,4 @@
-// Ring buffer implementation. This is basically an array that wraps read/write
+// Specialized ring buffer. This is basically an array that wraps read/write
// pointers around the memory region. It should be more efficient than the old
// RBuffer which required memmove() calls to relocate read/write positions.
//
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 886a48e7c5..0b9e1cfdec 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.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
+
/*
* Handling of regular expressions: vim_regcomp(), vim_regexec(), vim_regsub()
*
@@ -59,7 +62,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/strings.h"
@@ -230,17 +232,17 @@
#define LAST_NL NUPPER + ADD_NL
#define WITH_NL(op) ((op) >= FIRST_NL && (op) <= LAST_NL)
-#define MOPEN 80 /* -89 Mark this point in input as start of
- * \( subexpr. MOPEN + 0 marks start of
- * match. */
-#define MCLOSE 90 /* -99 Analogous to MOPEN. MCLOSE + 0 marks
- * end of match. */
-#define BACKREF 100 /* -109 node Match same string again \1-\9 */
+#define MOPEN 80 // -89 Mark this point in input as start of
+ // \( … \) subexpr. MOPEN + 0 marks start of
+ // match.
+#define MCLOSE 90 // -99 Analogous to MOPEN. MCLOSE + 0 marks
+ // end of match.
+#define BACKREF 100 // -109 node Match same string again \1-\9.
-# define ZOPEN 110 /* -119 Mark this point in input as start of
- * \z( subexpr. */
-# define ZCLOSE 120 /* -129 Analogous to ZOPEN. */
-# define ZREF 130 /* -139 node Match external submatch \z1-\z9 */
+# define ZOPEN 110 // -119 Mark this point in input as start of
+ // \z( … \) subexpr.
+# define ZCLOSE 120 // -129 Analogous to ZOPEN.
+# define ZREF 130 // -139 node Match external submatch \z1-\z9
#define BRACE_COMPLEX 140 /* -149 node Match nodes between m & n times */
@@ -456,18 +458,15 @@ static int toggle_Magic(int x)
/* Used for an error (down from) vim_regcomp(): give the error message, set
* rc_did_emsg and return NULL */
-#define EMSG_RET_NULL(m) return (EMSG(m), rc_did_emsg = TRUE, (void *)NULL)
-#define EMSG_RET_FAIL(m) return (EMSG(m), rc_did_emsg = TRUE, FAIL)
-#define EMSG2_RET_NULL(m, \
- c) return (EMSG2((m), \
- (c) ? "" : "\\"), rc_did_emsg = TRUE, \
- (void *)NULL)
-#define EMSG2_RET_FAIL(m, \
- c) return (EMSG2((m), \
- (c) ? "" : "\\"), rc_did_emsg = TRUE, \
- FAIL)
+#define EMSG_RET_NULL(m) return (EMSG(m), rc_did_emsg = true, (void *)NULL)
+#define IEMSG_RET_NULL(m) return (IEMSG(m), rc_did_emsg = true, (void *)NULL)
+#define EMSG_RET_FAIL(m) return (EMSG(m), rc_did_emsg = true, FAIL)
+#define EMSG2_RET_NULL(m, c) \
+ return (EMSG2((m), (c) ? "" : "\\"), rc_did_emsg = true, (void *)NULL)
+#define EMSG2_RET_FAIL(m, c) \
+ return (EMSG2((m), (c) ? "" : "\\"), rc_did_emsg = true, FAIL)
#define EMSG_ONE_RET_NULL EMSG2_RET_NULL(_( \
- "E369: invalid item in %s%%[]"), reg_magic == MAGIC_ALL)
+ "E369: invalid item in %s%%[]"), reg_magic == MAGIC_ALL)
#define MAX_LIMIT (32767L << 16L)
@@ -480,11 +479,13 @@ static char_u *regprop(char_u *);
#endif
static char_u e_missingbracket[] = N_("E769: Missing ] after %s[");
+static char_u e_reverse_range[] = N_("E944: Reverse range in character class");
+static char_u e_large_class[] = N_("E945: Range too large in character class");
static char_u e_unmatchedpp[] = N_("E53: Unmatched %s%%(");
static char_u e_unmatchedp[] = N_("E54: Unmatched %s(");
static char_u e_unmatchedpar[] = N_("E55: Unmatched %s)");
static char_u e_z_not_allowed[] = N_("E66: \\z( not allowed here");
-static char_u e_z1_not_allowed[] = N_("E67: \\z1 et al. not allowed here");
+static char_u e_z1_not_allowed[] = N_("E67: \\z1 - \\z9 not allowed here");
static char_u e_missing_sb[] = N_("E69: Missing ] after %s%%[");
static char_u e_empty_sb[] = N_("E70: Empty %s%%[]");
#define NOT_MULTI 0
@@ -771,13 +772,9 @@ static int get_equi_class(char_u **pp)
char_u *p = *pp;
if (p[1] == '=') {
- if (has_mbyte)
- l = (*mb_ptr2len)(p + 2);
+ l = (*mb_ptr2len)(p + 2);
if (p[l + 2] == '=' && p[l + 3] == ']') {
- if (has_mbyte)
- c = mb_ptr2char(p + 2);
- else
- c = p[2];
+ c = utf_ptr2char(p + 2);
*pp += l + 4;
return c;
}
@@ -1106,13 +1103,9 @@ static int get_coll_element(char_u **pp)
char_u *p = *pp;
if (p[0] != NUL && p[1] == '.') {
- if (has_mbyte)
- l = (*mb_ptr2len)(p + 2);
+ l = utfc_ptr2len(p + 2);
if (p[l + 2] == '.' && p[l + 3] == ']') {
- if (has_mbyte)
- c = mb_ptr2char(p + 2);
- else
- c = p[2];
+ c = utf_ptr2char(p + 2);
*pp += l + 4;
return c;
}
@@ -1141,24 +1134,28 @@ static char_u *skip_anyof(char_u *p)
if (*p == ']' || *p == '-')
++p;
while (*p != NUL && *p != ']') {
- if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
+ if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
p += l;
- else if (*p == '-') {
- ++p;
- if (*p != ']' && *p != NUL)
- mb_ptr_adv(p);
+ } else if (*p == '-') {
+ p++;
+ if (*p != ']' && *p != NUL) {
+ MB_PTR_ADV(p);
+ }
} else if (*p == '\\'
&& (vim_strchr(REGEXP_INRANGE, p[1]) != NULL
- || (!reg_cpo_lit && vim_strchr(REGEXP_ABBR, p[1]) != NULL)))
+ || (!reg_cpo_lit
+ && vim_strchr(REGEXP_ABBR, p[1]) != NULL))) {
p += 2;
- else if (*p == '[') {
+ } else if (*p == '[') {
if (get_char_class(&p) == CLASS_NONE
&& get_equi_class(&p) == 0
&& get_coll_element(&p) == 0
- && *p != NUL)
- ++p; /* It is not a class name and not NUL */
- } else
- ++p;
+ && *p != NUL) {
+ p++; // It is not a class name and not NUL
+ }
+ } else {
+ p++;
+ }
}
return p;
@@ -1184,9 +1181,10 @@ char_u *skip_regexp(char_u *startp, int dirc, int magic, char_u **newp)
mymagic = MAGIC_OFF;
get_cpo_flags();
- for (; p[0] != NUL; mb_ptr_adv(p)) {
- if (p[0] == dirc) /* found end of regexp */
+ for (; p[0] != NUL; MB_PTR_ADV(p)) {
+ if (p[0] == dirc) { // found end of regexp
break;
+ }
if ((p[0] == '[' && mymagic >= MAGIC_ON)
|| (p[0] == '\\' && p[1] == '[' && mymagic <= MAGIC_OFF)) {
p = skip_anyof(p + 1);
@@ -1293,10 +1291,7 @@ static regprog_T *bt_regcomp(char_u *expr, int re_flags)
}
if (OP(scan) == EXACTLY) {
- if (has_mbyte)
- r->regstart = (*mb_ptr2char)(OPERAND(scan));
- else
- r->regstart = *OPERAND(scan);
+ r->regstart = utf_ptr2char(OPERAND(scan));
} else if (OP(scan) == BOW
|| OP(scan) == EOW
|| OP(scan) == NOTHING
@@ -1304,10 +1299,7 @@ static regprog_T *bt_regcomp(char_u *expr, int re_flags)
|| OP(scan) == MCLOSE + 0 || OP(scan) == NCLOSE) {
char_u *regnext_scan = regnext(scan);
if (OP(regnext_scan) == EXACTLY) {
- if (has_mbyte)
- r->regstart = (*mb_ptr2char)(OPERAND(regnext_scan));
- else
- r->regstart = *OPERAND(regnext_scan);
+ r->regstart = utf_ptr2char(OPERAND(regnext_scan));
}
}
@@ -1389,6 +1381,10 @@ int vim_regcomp_had_eol(void)
return had_eol;
}
+// variables for parsing reginput
+static int at_start; // True when on the first character
+static int prev_at_start; // True when on the second character
+
/*
* Parse regular expression, i.e. main body or parenthesized thing.
*
@@ -1668,9 +1664,8 @@ static char_u *regpiece(int *flagp)
case Magic('@'):
{
int lop = END;
- int nr;
+ int64_t nr = getdecchrs();
- nr = getdecchrs();
switch (no_Magic(getchr())) {
case '=': lop = MATCH; break; /* \@= */
case '!': lop = NOMATCH; break; /* \@! */
@@ -1768,6 +1763,7 @@ static char_u *regatom(int *flagp)
int c;
char_u *p;
int extra = 0;
+ int save_prev_at_start = prev_at_start;
*flagp = WORST; /* Tentatively. */
@@ -1809,8 +1805,8 @@ static char_u *regatom(int *flagp)
if (c == '[')
goto collection;
- /* "\_x" is character class plus newline */
- /*FALLTHROUGH*/
+ // "\_x" is character class plus newline
+ FALLTHROUGH;
/*
* Character classes.
@@ -1884,8 +1880,8 @@ static char_u *regatom(int *flagp)
case Magic(')'):
if (one_exactly)
EMSG_ONE_RET_NULL;
- EMSG_RET_NULL(_(e_internal)); /* Supposed to be caught earlier. */
- /* NOTREACHED */
+ IEMSG_RET_NULL(_(e_internal)); // Supposed to be caught earlier.
+ // NOTREACHED
case Magic('='):
case Magic('?'):
@@ -1956,7 +1952,7 @@ static char_u *regatom(int *flagp)
{
c = no_Magic(getchr());
switch (c) {
- case '(': if (reg_do_extmatch != REX_SET)
+ case '(': if ((reg_do_extmatch & REX_SET) == 0)
EMSG_RET_NULL(_(e_z_not_allowed));
if (one_exactly)
EMSG_ONE_RET_NULL;
@@ -1975,7 +1971,7 @@ static char_u *regatom(int *flagp)
case '6':
case '7':
case '8':
- case '9': if (reg_do_extmatch != REX_USE)
+ case '9': if ((reg_do_extmatch & REX_USE) == 0)
EMSG_RET_NULL(_(e_z1_not_allowed));
ret = regnode(ZREF + c - '0');
re_has_z = REX_USE;
@@ -2090,7 +2086,7 @@ static char_u *regatom(int *flagp)
case 'u': /* %uabcd hex 4 */
case 'U': /* %U1234abcd hex 8 */
{
- int i;
+ int64_t i;
switch (c) {
case 'd': i = getdecchrs(); break;
@@ -2143,17 +2139,21 @@ static char_u *regatom(int *flagp)
}
break;
} else if (c == 'l' || c == 'c' || c == 'v') {
- if (c == 'l')
+ if (c == 'l') {
ret = regnode(RE_LNUM);
- else if (c == 'c')
+ if (save_prev_at_start) {
+ at_start = true;
+ }
+ } else if (c == 'c') {
ret = regnode(RE_COL);
- else
+ } else {
ret = regnode(RE_VCOL);
- if (ret == JUST_CALC_SIZE)
+ }
+ if (ret == JUST_CALC_SIZE) {
regsize += 5;
- else {
- /* put the number and the optional
- * comparator after the opcode */
+ } else {
+ // put the number and the optional
+ // comparator after the opcode
regcode = re_put_uint32(regcode, n);
*regcode++ = cmp;
}
@@ -2213,25 +2213,29 @@ collection:
if (*regparse == '[')
endc = get_coll_element(&regparse);
if (endc == 0) {
- if (has_mbyte)
- endc = mb_ptr2char_adv(&regparse);
- else
+ if (has_mbyte) {
+ endc = mb_ptr2char_adv((const char_u **)&regparse);
+ } else {
endc = *regparse++;
+ }
}
/* Handle \o40, \x20 and \u20AC style sequences */
if (endc == '\\' && !reg_cpo_lit)
endc = coll_get_char();
- if (startc > endc)
- EMSG_RET_NULL(_(e_invrange));
+ if (startc > endc) {
+ EMSG_RET_NULL(_(e_reverse_range));
+ }
if (has_mbyte && ((*mb_char2len)(startc) > 1
|| (*mb_char2len)(endc) > 1)) {
- /* Limit to a range of 256 chars */
- if (endc > startc + 256)
- EMSG_RET_NULL(_(e_invrange));
- while (++startc <= endc)
+ // Limit to a range of 256 chars
+ if (endc > startc + 256) {
+ EMSG_RET_NULL(_(e_large_class));
+ }
+ while (++startc <= endc) {
regmbc(startc);
+ }
} else {
while (++startc <= endc)
regc(startc);
@@ -2301,48 +2305,64 @@ collection:
}
break;
case CLASS_ALNUM:
- for (cu = 1; cu <= 255; cu++)
- if (isalnum(cu))
- regc(cu);
+ for (cu = 1; cu < 128; cu++) {
+ if (isalnum(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_ALPHA:
- for (cu = 1; cu <= 255; cu++)
- if (isalpha(cu))
- regc(cu);
+ for (cu = 1; cu < 128; cu++) {
+ if (isalpha(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_BLANK:
regc(' ');
regc('\t');
break;
case CLASS_CNTRL:
- for (cu = 1; cu <= 255; cu++)
- if (iscntrl(cu))
- regc(cu);
+ for (cu = 1; cu <= 127; cu++) {
+ if (iscntrl(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_DIGIT:
- for (cu = 1; cu <= 255; cu++)
- if (ascii_isdigit(cu))
- regc(cu);
+ for (cu = 1; cu <= 127; cu++) {
+ if (ascii_isdigit(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_GRAPH:
- for (cu = 1; cu <= 255; cu++)
- if (isgraph(cu))
- regc(cu);
+ for (cu = 1; cu <= 127; cu++) {
+ if (isgraph(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_LOWER:
- for (cu = 1; cu <= 255; cu++)
- if (vim_islower(cu))
- regc(cu);
+ for (cu = 1; cu <= 255; cu++) {
+ if (mb_islower(cu) && cu != 170 && cu != 186) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_PRINT:
- for (cu = 1; cu <= 255; cu++)
- if (vim_isprintc(cu))
- regc(cu);
+ for (cu = 1; cu <= 255; cu++) {
+ if (vim_isprintc(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_PUNCT:
- for (cu = 1; cu <= 255; cu++)
- if (ispunct(cu))
- regc(cu);
+ for (cu = 1; cu < 128; cu++) {
+ if (ispunct(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_SPACE:
for (cu = 9; cu <= 13; cu++)
@@ -2350,14 +2370,18 @@ collection:
regc(' ');
break;
case CLASS_UPPER:
- for (cu = 1; cu <= 255; cu++)
- if (vim_isupper(cu))
- regc(cu);
+ for (cu = 1; cu <= 255; cu++) {
+ if (mb_isupper(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_XDIGIT:
- for (cu = 1; cu <= 255; cu++)
- if (ascii_isxdigit(cu))
- regc(cu);
+ for (cu = 1; cu <= 255; cu++) {
+ if (ascii_isxdigit(cu)) {
+ regmbc(cu);
+ }
+ }
break;
case CLASS_TAB:
regc('\t');
@@ -2369,24 +2393,20 @@ collection:
regc('\b');
break;
case CLASS_ESCAPE:
- regc('\033');
+ regc(ESC);
break;
}
} else {
- if (has_mbyte) {
- int len;
-
- /* produce a multibyte character, including any
- * following composing characters */
- startc = mb_ptr2char(regparse);
- len = (*mb_ptr2len)(regparse);
- if (enc_utf8 && utf_char2len(startc) != len)
- startc = -1; /* composing chars */
- while (--len >= 0)
- regc(*regparse++);
- } else {
- startc = *regparse++;
- regc(startc);
+ // produce a multibyte character, including any
+ // following composing characters.
+ startc = utf_ptr2char(regparse);
+ int len = utfc_ptr2len(regparse);
+ if (utf_char2len(startc) != len) {
+ // composing chars
+ startc = -1;
+ }
+ while (--len >= 0) {
+ regc(*regparse++);
}
}
}
@@ -2400,7 +2420,7 @@ collection:
} else if (reg_strict)
EMSG2_RET_NULL(_(e_missingbracket), reg_magic > MAGIC_OFF);
}
- /* FALLTHROUGH */
+ FALLTHROUGH;
default:
{
@@ -2518,12 +2538,11 @@ static void regc(int b)
*/
static void regmbc(int c)
{
- if (!has_mbyte && c > 0xff)
- return;
- if (regcode == JUST_CALC_SIZE)
- regsize += (*mb_char2len)(c);
- else
- regcode += (*mb_char2bytes)(c, regcode);
+ if (regcode == JUST_CALC_SIZE) {
+ regsize += utf_char2len(c);
+ } else {
+ regcode += utf_char2bytes(c, regcode);
+ }
}
/*
@@ -2679,9 +2698,6 @@ static void regoptail(char_u *p, char_u *val)
* Functions for getting characters from the regexp input.
*/
-static int at_start; /* True when on the first character */
-static int prev_at_start; /* True when on the second character */
-
/*
* Start parsing at "str".
*/
@@ -2870,17 +2886,13 @@ static int peekchr(void)
* Next character can never be (made) magic?
* Then backslashing it won't do anything.
*/
- if (has_mbyte)
- curchr = (*mb_ptr2char)(regparse + 1);
- else
- curchr = c;
+ curchr = utf_ptr2char(regparse + 1);
}
break;
}
default:
- if (has_mbyte)
- curchr = (*mb_ptr2char)(regparse);
+ curchr = utf_ptr2char(regparse);
}
return curchr;
@@ -2897,13 +2909,8 @@ static void skipchr(void)
else
prevchr_len = 0;
if (regparse[prevchr_len] != NUL) {
- if (enc_utf8)
- /* exclude composing chars that mb_ptr2len does include */
- prevchr_len += utf_ptr2len(regparse + prevchr_len);
- else if (has_mbyte)
- prevchr_len += (*mb_ptr2len)(regparse + prevchr_len);
- else
- ++prevchr_len;
+ // Exclude composing chars that utfc_ptr2len does include.
+ prevchr_len += utf_ptr2len(regparse + prevchr_len);
}
regparse += prevchr_len;
prev_at_start = at_start;
@@ -2967,9 +2974,9 @@ static void ungetchr(void)
* The parameter controls the maximum number of input characters. This will be
* 2 when reading a \%x20 sequence and 4 when reading a \%u20AC sequence.
*/
-static int gethexchrs(int maxinputlen)
+static int64_t gethexchrs(int maxinputlen)
{
- int nr = 0;
+ int64_t nr = 0;
int c;
int i;
@@ -2991,9 +2998,9 @@ static int gethexchrs(int maxinputlen)
* Get and return the value of the decimal string immediately after the
* current position. Return -1 for invalid. Consumes all digits.
*/
-static int getdecchrs(void)
+static int64_t getdecchrs(void)
{
- int nr = 0;
+ int64_t nr = 0;
int c;
int i;
@@ -3020,13 +3027,13 @@ static int getdecchrs(void)
* blahblah\%o210asdf
* before-^ ^-after
*/
-static int getoctchrs(void)
+static int64_t getoctchrs(void)
{
- int nr = 0;
+ int64_t nr = 0;
int c;
int i;
- for (i = 0; i < 3 && nr < 040; ++i) {
+ for (i = 0; i < 3 && nr < 040; i++) { // -V536
c = regparse[0];
if (c < '0' || c > '7')
break;
@@ -3046,7 +3053,7 @@ static int getoctchrs(void)
*/
static int coll_get_char(void)
{
- int nr = -1;
+ int64_t nr = -1;
switch (*regparse++) {
case 'd': nr = getdecchrs(); break;
@@ -3148,61 +3155,56 @@ static int need_clear_zsubexpr = FALSE; /* extmatch subexpressions
int regnarrate = 0;
#endif
-/*
- * Internal copy of 'ignorecase'. It is set at each call to vim_regexec().
- * Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern
- * contains '\c' or '\C' the value is overruled.
- */
-static int ireg_ic;
-
-/*
- * Similar to ireg_ic, but only for 'combining' characters. Set with \Z flag
- * in the regexp. Defaults to false, always.
- */
-static int ireg_icombine;
-
-/*
- * Copy of "rmm_maxcol": maximum column to search for a match. Zero when
- * there is no maximum.
- */
-static colnr_T ireg_maxcol;
-
-/*
- * Sometimes need to save a copy of a line. Since alloc()/free() is very
- * slow, we keep one allocated piece of memory and only re-allocate it when
- * it's too small. It's freed in bt_regexec_both() when finished.
- */
+// Sometimes need to save a copy of a line. Since alloc()/free() is very
+// slow, we keep one allocated piece of memory and only re-allocate it when
+// it's too small. It's freed in bt_regexec_both() when finished.
static char_u *reg_tofree = NULL;
static unsigned reg_tofreelen;
-/*
- * These variables are set when executing a regexp to speed up the execution.
- * Which ones are set depends on whether a single-line or multi-line match is
- * done:
- * single-line multi-line
- * reg_match &regmatch_T NULL
- * reg_mmatch NULL &regmmatch_T
- * reg_startp reg_match->startp <invalid>
- * reg_endp reg_match->endp <invalid>
- * reg_startpos <invalid> reg_mmatch->startpos
- * reg_endpos <invalid> reg_mmatch->endpos
- * reg_win NULL window in which to search
- * reg_buf curbuf buffer in which to search
- * reg_firstlnum <invalid> first line in which to search
- * reg_maxline 0 last line nr
- * reg_line_lbr FALSE or TRUE FALSE
- */
-static regmatch_T *reg_match;
-static regmmatch_T *reg_mmatch;
-static char_u **reg_startp = NULL;
-static char_u **reg_endp = NULL;
-static lpos_T *reg_startpos = NULL;
-static lpos_T *reg_endpos = NULL;
-static win_T *reg_win;
-static buf_T *reg_buf;
-static linenr_T reg_firstlnum;
-static linenr_T reg_maxline;
-static int reg_line_lbr; /* "\n" in string is line break */
+// Structure used to store the execution state of the regex engine.
+// Which ones are set depends on whether a single-line or multi-line match is
+// done:
+// single-line multi-line
+// reg_match &regmatch_T NULL
+// reg_mmatch NULL &regmmatch_T
+// reg_startp reg_match->startp <invalid>
+// reg_endp reg_match->endp <invalid>
+// reg_startpos <invalid> reg_mmatch->startpos
+// reg_endpos <invalid> reg_mmatch->endpos
+// reg_win NULL window in which to search
+// reg_buf curbuf buffer in which to search
+// reg_firstlnum <invalid> first line in which to search
+// reg_maxline 0 last line nr
+// reg_line_lbr false or true false
+typedef struct {
+ regmatch_T *reg_match;
+ regmmatch_T *reg_mmatch;
+ char_u **reg_startp;
+ char_u **reg_endp;
+ lpos_T *reg_startpos;
+ lpos_T *reg_endpos;
+ win_T *reg_win;
+ buf_T *reg_buf;
+ linenr_T reg_firstlnum;
+ linenr_T reg_maxline;
+ bool reg_line_lbr; // "\n" in string is line break
+
+ // Internal copy of 'ignorecase'. It is set at each call to vim_regexec().
+ // Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern
+ // contains '\c' or '\C' the value is overruled.
+ bool reg_ic;
+
+ // Similar to rex.reg_ic, but only for 'combining' characters. Set with \Z
+ // flag in the regexp. Defaults to false, always.
+ bool reg_icombine;
+
+ // Copy of "rmm_maxcol": maximum column to search for a match. Zero when
+ // there is no maximum.
+ colnr_T reg_maxcol;
+} regexec_T;
+
+static regexec_T rex;
+static bool rex_in_use = false;
/*
* "regstack" and "backpos" are used by regmatch(). They are kept over calls
@@ -3244,14 +3246,16 @@ void free_regexp_stuff(void)
*/
static char_u *reg_getline(linenr_T lnum)
{
- /* when looking behind for a match/no-match lnum is negative. But we
- * can't go before line 1 */
- if (reg_firstlnum + lnum < 1)
+ // when looking behind for a match/no-match lnum is negative. But we
+ // can't go before line 1
+ if (rex.reg_firstlnum + lnum < 1) {
return NULL;
- if (lnum > reg_maxline)
- /* Must have matched the "\n" in the last line. */
+ }
+ if (lnum > rex.reg_maxline) {
+ // Must have matched the "\n" in the last line.
return (char_u *)"";
- return ml_get_buf(reg_buf, reg_firstlnum + lnum, FALSE);
+ }
+ return ml_get_buf(rex.reg_buf, rex.reg_firstlnum + lnum, false);
}
static regsave_T behind_pos;
@@ -3261,9 +3265,8 @@ static char_u *reg_endzp[NSUBEXP]; /* and end of \z(...\) matches */
static lpos_T reg_startzpos[NSUBEXP]; /* idem, beginning pos */
static lpos_T reg_endzpos[NSUBEXP]; /* idem, end pos */
-/* TRUE if using multi-line regexp. */
-#define REG_MULTI (reg_match == NULL)
-
+// TRUE if using multi-line regexp.
+#define REG_MULTI (rex.reg_match == NULL)
/*
* Match a regexp against a string.
@@ -3281,21 +3284,62 @@ bt_regexec_nl (
bool line_lbr
)
{
- reg_match = rmp;
- reg_mmatch = NULL;
- reg_maxline = 0;
- reg_line_lbr = line_lbr;
- reg_buf = curbuf;
- reg_win = NULL;
- ireg_ic = rmp->rm_ic;
- ireg_icombine = FALSE;
- ireg_maxcol = 0;
+ rex.reg_match = rmp;
+ rex.reg_mmatch = NULL;
+ rex.reg_maxline = 0;
+ rex.reg_line_lbr = line_lbr;
+ rex.reg_buf = curbuf;
+ rex.reg_win = NULL;
+ rex.reg_ic = rmp->rm_ic;
+ rex.reg_icombine = false;
+ rex.reg_maxcol = 0;
long r = bt_regexec_both(line, col, NULL);
assert(r <= INT_MAX);
return (int)r;
}
+/// Wrapper around strchr which accounts for case-insensitive searches and
+/// non-ASCII characters.
+///
+/// This function is used a lot for simple searches, keep it fast!
+///
+/// @param s string to search
+/// @param c character to find in @a s
+///
+/// @return NULL if no match, otherwise pointer to the position in @a s
+static inline char_u *cstrchr(const char_u *const s, const int c)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ if (!rex.reg_ic) {
+ return vim_strchr(s, c);
+ }
+
+ // Use folded case for UTF-8, slow! For ASCII use libc strpbrk which is
+ // expected to be highly optimized.
+ if (c > 0x80) {
+ const int folded_c = utf_fold(c);
+ for (const char_u *p = s; *p != NUL; p += utfc_ptr2len(p)) {
+ if (utf_fold(utf_ptr2char(p)) == folded_c) {
+ return (char_u *)p;
+ }
+ }
+ return NULL;
+ }
+
+ int cc;
+ if (ASCII_ISUPPER(c)) {
+ cc = TOLOWER_ASC(c);
+ } else if (ASCII_ISLOWER(c)) {
+ cc = TOUPPER_ASC(c);
+ } else {
+ return vim_strchr(s, c);
+ }
+
+ char tofind[] = { (char)c, (char)cc, NUL };
+ return (char_u *)strpbrk((const char *)s, tofind);
+}
/// Matches a regexp against multiple lines.
/// "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
@@ -3312,16 +3356,16 @@ bt_regexec_nl (
static long bt_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
linenr_T lnum, colnr_T col, proftime_T *tm)
{
- reg_match = NULL;
- reg_mmatch = rmp;
- reg_buf = buf;
- reg_win = win;
- reg_firstlnum = lnum;
- reg_maxline = reg_buf->b_ml.ml_line_count - lnum;
- reg_line_lbr = FALSE;
- ireg_ic = rmp->rmm_ic;
- ireg_icombine = FALSE;
- ireg_maxcol = rmp->rmm_maxcol;
+ 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;
return bt_regexec_both(NULL, col, tm);
}
@@ -3359,14 +3403,14 @@ static long bt_regexec_both(char_u *line,
}
if (REG_MULTI) {
- prog = (bt_regprog_T *)reg_mmatch->regprog;
+ prog = (bt_regprog_T *)rex.reg_mmatch->regprog;
line = reg_getline((linenr_T)0);
- reg_startpos = reg_mmatch->startpos;
- reg_endpos = reg_mmatch->endpos;
+ rex.reg_startpos = rex.reg_mmatch->startpos;
+ rex.reg_endpos = rex.reg_mmatch->endpos;
} else {
- prog = (bt_regprog_T *)reg_match->regprog;
- reg_startp = reg_match->startp;
- reg_endp = reg_match->endp;
+ prog = (bt_regprog_T *)rex.reg_match->regprog;
+ rex.reg_startp = rex.reg_match->startp;
+ rex.reg_endp = rex.reg_match->endp;
}
/* Be paranoid... */
@@ -3379,56 +3423,48 @@ static long bt_regexec_both(char_u *line,
if (prog_magic_wrong())
goto theend;
- /* If the start column is past the maximum column: no need to try. */
- if (ireg_maxcol > 0 && col >= ireg_maxcol)
+ // If the start column is past the maximum column: no need to try.
+ if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) {
goto theend;
+ }
- /* If pattern contains "\c" or "\C": overrule value of ireg_ic */
- if (prog->regflags & RF_ICASE)
- ireg_ic = TRUE;
- else if (prog->regflags & RF_NOICASE)
- ireg_ic = FALSE;
+ // If pattern contains "\c" or "\C": overrule value of rex.reg_ic
+ if (prog->regflags & RF_ICASE) {
+ rex.reg_ic = true;
+ } else if (prog->regflags & RF_NOICASE) {
+ rex.reg_ic = false;
+ }
- /* If pattern contains "\Z" overrule value of ireg_icombine */
- if (prog->regflags & RF_ICOMBINE)
- ireg_icombine = TRUE;
+ // If pattern contains "\Z" overrule value of rex.reg_icombine
+ if (prog->regflags & RF_ICOMBINE) {
+ rex.reg_icombine = true;
+ }
/* If there is a "must appear" string, look for it. */
if (prog->regmust != NULL) {
- int c;
-
- if (has_mbyte)
- c = (*mb_ptr2char)(prog->regmust);
- else
- c = *prog->regmust;
+ int c = utf_ptr2char(prog->regmust);
s = line + col;
- /*
- * This is used very often, esp. for ":global". Use three versions of
- * the loop to avoid overhead of conditions.
- */
- if (!ireg_ic
- && !has_mbyte
- )
- while ((s = vim_strbyte(s, c)) != NULL) {
- if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
- break; /* Found it. */
- ++s;
- }
- else if (!ireg_ic || (!enc_utf8 && mb_char2len(c) > 1))
+ // This is used very often, esp. for ":global". Use two versions of
+ // the loop to avoid overhead of conditions.
+ if (!rex.reg_ic) {
while ((s = vim_strchr(s, c)) != NULL) {
- if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
- break; /* Found it. */
- mb_ptr_adv(s);
+ if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0) {
+ break; // Found it.
+ }
+ MB_PTR_ADV(s);
}
- else
+ } else {
while ((s = cstrchr(s, c)) != NULL) {
- if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0)
- break; /* Found it. */
- mb_ptr_adv(s);
+ if (cstrncmp(s, prog->regmust, &prog->regmlen) == 0) {
+ break; // Found it.
+ }
+ MB_PTR_ADV(s);
}
- if (s == NULL) /* Not present. */
+ }
+ if (s == NULL) { // Not present.
goto theend;
+ }
}
regline = line;
@@ -3437,18 +3473,13 @@ static long bt_regexec_both(char_u *line,
/* Simplest case: Anchored match need be tried only once. */
if (prog->reganch) {
- int c;
-
- if (has_mbyte)
- c = (*mb_ptr2char)(regline + col);
- else
- c = regline[col];
+ int c = utf_ptr2char(regline + col);
if (prog->regstart == NUL
|| prog->regstart == c
- || (ireg_ic
- && (((enc_utf8 && utf_fold(prog->regstart) == utf_fold(c)))
+ || (rex.reg_ic
+ && (utf_fold(prog->regstart) == utf_fold(c)
|| (c < 255 && prog->regstart < 255
- && vim_tolower(prog->regstart) == vim_tolower(c))))) {
+ && mb_tolower(prog->regstart) == mb_tolower(c))))) {
retval = regtry(prog, col);
} else {
retval = 0;
@@ -3458,14 +3489,8 @@ static long bt_regexec_both(char_u *line,
/* Messy cases: unanchored match. */
while (!got_int) {
if (prog->regstart != NUL) {
- /* Skip until the char we know it must start with.
- * Used often, do some work to avoid call overhead. */
- if (!ireg_ic
- && !has_mbyte
- )
- s = vim_strbyte(regline + col, prog->regstart);
- else
- s = cstrchr(regline + col, prog->regstart);
+ // Skip until the char we know it must start with.
+ s = cstrchr(regline + col, prog->regstart);
if (s == NULL) {
retval = 0;
break;
@@ -3473,8 +3498,8 @@ static long bt_regexec_both(char_u *line,
col = (int)(s - regline);
}
- /* Check for maximum column to try. */
- if (ireg_maxcol > 0 && col >= ireg_maxcol) {
+ // Check for maximum column to try.
+ if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) {
retval = 0;
break;
}
@@ -3571,21 +3596,24 @@ static long regtry(bt_regprog_T *prog, colnr_T col)
cleanup_subexpr();
if (REG_MULTI) {
- if (reg_startpos[0].lnum < 0) {
- reg_startpos[0].lnum = 0;
- reg_startpos[0].col = col;
+ if (rex.reg_startpos[0].lnum < 0) {
+ rex.reg_startpos[0].lnum = 0;
+ rex.reg_startpos[0].col = col;
+ }
+ if (rex.reg_endpos[0].lnum < 0) {
+ rex.reg_endpos[0].lnum = reglnum;
+ rex.reg_endpos[0].col = (int)(reginput - regline);
+ } else {
+ // Use line number of "\ze".
+ reglnum = rex.reg_endpos[0].lnum;
}
- if (reg_endpos[0].lnum < 0) {
- reg_endpos[0].lnum = reglnum;
- reg_endpos[0].col = (int)(reginput - regline);
- } else
- /* Use line number of "\ze". */
- reglnum = reg_endpos[0].lnum;
} else {
- if (reg_startp[0] == NULL)
- reg_startp[0] = regline + col;
- if (reg_endp[0] == NULL)
- reg_endp[0] = reginput;
+ if (rex.reg_startp[0] == NULL) {
+ rex.reg_startp[0] = regline + col;
+ }
+ if (rex.reg_endp[0] == NULL) {
+ rex.reg_endp[0] = reginput;
+ }
}
/* Package any found \z(...\) matches for export. Default is none. */
unref_extmatch(re_extmatch_out);
@@ -3620,34 +3648,32 @@ static long regtry(bt_regprog_T *prog, colnr_T col)
}
-/*
- * Get class of previous character.
- */
+// Get class of previous character.
static int reg_prev_class(void)
{
- if (reginput > regline)
- return mb_get_class_buf(reginput - 1
- - (*mb_head_off)(regline, reginput - 1), reg_buf);
+ if (reginput > regline) {
+ return mb_get_class_tab(reginput - 1 - utf_head_off(regline, reginput - 1),
+ rex.reg_buf->b_chartab);
+ }
return -1;
}
-/*
- * Return TRUE if the current reginput position matches the Visual area.
- */
+// Return TRUE if the current reginput position matches the Visual area.
static int reg_match_visual(void)
{
pos_T top, bot;
linenr_T lnum;
colnr_T col;
- win_T *wp = reg_win == NULL ? curwin : reg_win;
+ win_T *wp = rex.reg_win == NULL ? curwin : rex.reg_win;
int mode;
colnr_T start, end;
colnr_T start2, end2;
- /* Check if the buffer is the current buffer. */
- if (reg_buf != curbuf || VIsual.lnum == 0)
- return FALSE;
+ // Check if the buffer is the current buffer.
+ if (rex.reg_buf != curbuf || VIsual.lnum == 0) {
+ return false;
+ }
if (VIsual_active) {
if (lt(VIsual, wp->w_cursor)) {
@@ -3668,9 +3694,10 @@ static int reg_match_visual(void)
}
mode = curbuf->b_visual.vi_mode;
}
- lnum = reglnum + reg_firstlnum;
- if (lnum < top.lnum || lnum > bot.lnum)
- return FALSE;
+ lnum = reglnum + rex.reg_firstlnum;
+ if (lnum < top.lnum || lnum > bot.lnum) {
+ return false;
+ }
if (mode == 'v') {
col = (colnr_T)(reginput - regline);
@@ -3696,7 +3723,7 @@ static int reg_match_visual(void)
return TRUE;
}
-#define ADVANCE_REGINPUT() mb_ptr_adv(reginput)
+#define ADVANCE_REGINPUT() MB_PTR_ADV(reginput)
/*
* The arguments from BRACE_LIMITS are stored here. They are actually local
@@ -3789,19 +3816,17 @@ regmatch (
next = regnext(scan);
op = OP(scan);
- /* Check for character class with NL added. */
- if (!reg_line_lbr && WITH_NL(op) && REG_MULTI
- && *reginput == NUL && reglnum <= reg_maxline) {
+ // Check for character class with NL added.
+ if (!rex.reg_line_lbr && WITH_NL(op) && REG_MULTI
+ && *reginput == NUL && reglnum <= rex.reg_maxline) {
reg_nextline();
- } else if (reg_line_lbr && WITH_NL(op) && *reginput == '\n') {
+ } else if (rex.reg_line_lbr && WITH_NL(op) && *reginput == '\n') {
ADVANCE_REGINPUT();
} else {
- if (WITH_NL(op))
+ if (WITH_NL(op)) {
op -= ADD_NL;
- if (has_mbyte)
- c = (*mb_ptr2char)(reginput);
- else
- c = *reginput;
+ }
+ c = utf_ptr2char(reginput);
switch (op) {
case BOL:
if (reginput != regline)
@@ -3814,26 +3839,29 @@ regmatch (
break;
case RE_BOF:
- /* We're not at the beginning of the file when below the first
- * line where we started, not at the start of the line or we
- * didn't start at the first line of the buffer. */
+ // We're not at the beginning of the file when below the first
+ // line where we started, not at the start of the line or we
+ // didn't start at the first line of the buffer.
if (reglnum != 0 || reginput != regline
- || (REG_MULTI && reg_firstlnum > 1))
+ || (REG_MULTI && rex.reg_firstlnum > 1)) {
status = RA_NOMATCH;
+ }
break;
case RE_EOF:
- if (reglnum != reg_maxline || c != NUL)
+ if (reglnum != rex.reg_maxline || c != NUL) {
status = RA_NOMATCH;
+ }
break;
case CURSOR:
- /* Check if the buffer is in a window and compare the
- * reg_win->w_cursor position to the match position. */
- if (reg_win == NULL
- || (reglnum + reg_firstlnum != reg_win->w_cursor.lnum)
- || ((colnr_T)(reginput - regline) != reg_win->w_cursor.col))
+ // Check if the buffer is in a window and compare the
+ // rex.reg_win->w_cursor position to the match position.
+ if (rex.reg_win == NULL
+ || (reglnum + rex.reg_firstlnum != rex.reg_win->w_cursor.lnum)
+ || ((colnr_T)(reginput - regline) != rex.reg_win->w_cursor.col)) {
status = RA_NOMATCH;
+ }
break;
case RE_MARK:
@@ -3843,19 +3871,20 @@ regmatch (
int cmp = OPERAND(scan)[1];
pos_T *pos;
- pos = getmark_buf(reg_buf, mark, FALSE);
- if (pos == NULL /* mark doesn't exist */
- || pos->lnum <= 0 /* mark isn't set in reg_buf */
- || (pos->lnum == reglnum + reg_firstlnum
+ pos = getmark_buf(rex.reg_buf, mark, false);
+ if (pos == NULL // mark doesn't exist
+ || pos->lnum <= 0 // mark isn't set in reg_buf
+ || (pos->lnum == reglnum + rex.reg_firstlnum
? (pos->col == (colnr_T)(reginput - regline)
? (cmp == '<' || cmp == '>')
: (pos->col < (colnr_T)(reginput - regline)
? cmp != '>'
: cmp != '<'))
- : (pos->lnum < reglnum + reg_firstlnum
+ : (pos->lnum < reglnum + rex.reg_firstlnum
? cmp != '>'
- : cmp != '<')))
+ : cmp != '<'))) {
status = RA_NOMATCH;
+ }
}
break;
@@ -3865,11 +3894,12 @@ regmatch (
break;
case RE_LNUM:
- assert(reglnum + reg_firstlnum >= 0
- && (uintmax_t)(reglnum + reg_firstlnum) <= UINT32_MAX);
- if (!REG_MULTI || !re_num_cmp((uint32_t)(reglnum + reg_firstlnum),
- scan))
+ assert(reglnum + rex.reg_firstlnum >= 0
+ && (uintmax_t)(reglnum + rex.reg_firstlnum) <= UINT32_MAX);
+ if (!REG_MULTI
+ || !re_num_cmp((uint32_t)(reglnum + rex.reg_firstlnum), scan)) {
status = RA_NOMATCH;
+ }
break;
case RE_COL:
@@ -3880,11 +3910,13 @@ regmatch (
break;
case RE_VCOL:
- if (!re_num_cmp(win_linetabsize(reg_win == NULL ? curwin : reg_win,
+ if (!re_num_cmp(win_linetabsize(rex.reg_win == NULL
+ ? curwin : rex.reg_win,
regline,
(colnr_T)(reginput - regline)) + 1,
- scan))
+ scan)) {
status = RA_NOMATCH;
+ }
break;
case BOW: /* \<word; reginput points to w */
@@ -3893,17 +3925,19 @@ regmatch (
else if (has_mbyte) {
int this_class;
- /* Get class of current and previous char (if it exists). */
- this_class = mb_get_class_buf(reginput, reg_buf);
- if (this_class <= 1)
- status = RA_NOMATCH; /* not on a word at all */
- else if (reg_prev_class() == this_class)
- status = RA_NOMATCH; /* previous char is in same word */
+ // Get class of current and previous char (if it exists).
+ this_class = mb_get_class_tab(reginput, rex.reg_buf->b_chartab);
+ if (this_class <= 1) {
+ status = RA_NOMATCH; // Not on a word at all.
+ } else if (reg_prev_class() == this_class) {
+ status = RA_NOMATCH; // Previous char is in same word.
+ }
} else {
- if (!vim_iswordc_buf(c, reg_buf) || (reginput > regline
- && vim_iswordc_buf(reginput[-1
- ], reg_buf)))
+ if (!vim_iswordc_buf(c, rex.reg_buf)
+ || (reginput > regline
+ && vim_iswordc_buf(reginput[-1], rex.reg_buf))) {
status = RA_NOMATCH;
+ }
}
break;
@@ -3913,16 +3947,17 @@ regmatch (
else if (has_mbyte) {
int this_class, prev_class;
- /* Get class of current and previous char (if it exists). */
- this_class = mb_get_class_buf(reginput, reg_buf);
+ // Get class of current and previous char (if it exists).
+ this_class = mb_get_class_tab(reginput, rex.reg_buf->b_chartab);
prev_class = reg_prev_class();
if (this_class == prev_class
|| prev_class == 0 || prev_class == 1)
status = RA_NOMATCH;
} else {
- if (!vim_iswordc_buf(reginput[-1], reg_buf)
- || (reginput[0] != NUL && vim_iswordc_buf(c, reg_buf)))
+ if (!vim_iswordc_buf(reginput[-1], rex.reg_buf)
+ || (reginput[0] != NUL && vim_iswordc_buf(c, rex.reg_buf))) {
status = RA_NOMATCH;
+ }
}
break; /* Matched with EOW */
@@ -3949,17 +3984,20 @@ regmatch (
break;
case KWORD:
- if (!vim_iswordp_buf(reginput, reg_buf))
+ if (!vim_iswordp_buf(reginput, rex.reg_buf)) {
status = RA_NOMATCH;
- else
+ } else {
ADVANCE_REGINPUT();
+ }
break;
case SKWORD:
- if (ascii_isdigit(*reginput) || !vim_iswordp_buf(reginput, reg_buf))
+ if (ascii_isdigit(*reginput)
+ || !vim_iswordp_buf(reginput, rex.reg_buf)) {
status = RA_NOMATCH;
- else
+ } else {
ADVANCE_REGINPUT();
+ }
break;
case FNAME:
@@ -4124,16 +4162,16 @@ regmatch (
opnd = OPERAND(scan);
// Inline the first byte, for speed.
if (*opnd != *reginput
- && (!ireg_ic
+ && (!rex.reg_ic
|| (!enc_utf8
- && vim_tolower(*opnd) != vim_tolower(*reginput)))) {
+ && mb_tolower(*opnd) != mb_tolower(*reginput)))) {
status = RA_NOMATCH;
} else if (*opnd == NUL) {
// match empty string always works; happens when "~" is
// empty.
} else {
- if (opnd[1] == NUL && !(enc_utf8 && ireg_ic)) {
- len = 1; /* matched a single byte above */
+ if (opnd[1] == NUL && !(enc_utf8 && rex.reg_ic)) {
+ len = 1; // matched a single byte above
} else {
// Need to match first byte again for multi-byte.
len = (int)STRLEN(opnd);
@@ -4145,7 +4183,7 @@ regmatch (
// follows (skips over all composing chars).
if (status != RA_NOMATCH && enc_utf8
&& UTF_COMPOSINGLIKE(reginput, reginput + len)
- && !ireg_icombine
+ && !rex.reg_icombine
&& OP(next) != RE_COMPOSING) {
// raaron: This code makes a composing character get
// ignored, which is the correct behavior (sometimes)
@@ -4176,26 +4214,28 @@ regmatch (
int opndc = 0, inpc;
opnd = OPERAND(scan);
- /* Safety check (just in case 'encoding' was changed since
- * compiling the program). */
+ // Safety check (just in case 'encoding' was changed since
+ // compiling the program).
if ((len = (*mb_ptr2len)(opnd)) < 2) {
status = RA_NOMATCH;
break;
}
- if (enc_utf8)
- opndc = mb_ptr2char(opnd);
+ if (enc_utf8) {
+ opndc = utf_ptr2char(opnd);
+ }
if (enc_utf8 && utf_iscomposing(opndc)) {
/* When only a composing char is given match at any
* position where that composing char appears. */
status = RA_NOMATCH;
for (i = 0; reginput[i] != NUL; i += utf_ptr2len(reginput + i)) {
- inpc = mb_ptr2char(reginput + i);
+ inpc = utf_ptr2char(reginput + i);
if (!utf_iscomposing(inpc)) {
- if (i > 0)
+ if (i > 0) {
break;
+ }
} else if (opndc == inpc) {
- /* Include all following composing chars. */
- len = i + mb_ptr2len(reginput + i);
+ // Include all following composing chars.
+ len = i + utfc_ptr2len(reginput + i);
status = RA_MATCH;
break;
}
@@ -4215,7 +4255,7 @@ regmatch (
if (enc_utf8) {
// Skip composing characters.
while (utf_iscomposing(utf_ptr2char(reginput))) {
- mb_cptr_adv(reginput);
+ MB_CPTR_ADV(reginput);
}
}
break;
@@ -4269,9 +4309,9 @@ regmatch (
status = RA_FAIL;
else {
rp->rs_no = no;
- save_se(&rp->rs_un.sesave, &reg_startpos[no],
- &reg_startp[no]);
- /* We simply continue and handle the result when done. */
+ save_se(&rp->rs_un.sesave, &rex.reg_startpos[no],
+ &rex.reg_startp[no]);
+ // We simply continue and handle the result when done.
}
}
break;
@@ -4321,12 +4361,12 @@ regmatch (
no = op - MCLOSE;
cleanup_subexpr();
rp = regstack_push(RS_MCLOSE, scan);
- if (rp == NULL)
+ if (rp == NULL) {
status = RA_FAIL;
- else {
+ } else {
rp->rs_no = no;
- save_se(&rp->rs_un.sesave, &reg_endpos[no], &reg_endp[no]);
- /* We simply continue and handle the result when done. */
+ save_se(&rp->rs_un.sesave, &rex.reg_endpos[no], &rex.reg_endp[no]);
+ // We simply continue and handle the result when done.
}
}
break;
@@ -4369,41 +4409,40 @@ regmatch (
no = op - BACKREF;
cleanup_subexpr();
- if (!REG_MULTI) { /* Single-line regexp */
- if (reg_startp[no] == NULL || reg_endp[no] == NULL) {
- /* Backref was not set: Match an empty string. */
+ if (!REG_MULTI) { // Single-line regexp
+ if (rex.reg_startp[no] == NULL || rex.reg_endp[no] == NULL) {
+ // Backref was not set: Match an empty string.
len = 0;
} else {
- /* Compare current input with back-ref in the same
- * line. */
- len = (int)(reg_endp[no] - reg_startp[no]);
- if (cstrncmp(reg_startp[no], reginput, &len) != 0)
+ // Compare current input with back-ref in the same line.
+ len = (int)(rex.reg_endp[no] - rex.reg_startp[no]);
+ if (cstrncmp(rex.reg_startp[no], reginput, &len) != 0) {
status = RA_NOMATCH;
+ }
}
- } else { /* Multi-line regexp */
- if (reg_startpos[no].lnum < 0 || reg_endpos[no].lnum < 0) {
- /* Backref was not set: Match an empty string. */
+ } else { // Multi-line regexp
+ if (rex.reg_startpos[no].lnum < 0 || rex.reg_endpos[no].lnum < 0) {
+ // Backref was not set: Match an empty string.
len = 0;
} else {
- if (reg_startpos[no].lnum == reglnum
- && reg_endpos[no].lnum == reglnum) {
- /* Compare back-ref within the current line. */
- len = reg_endpos[no].col - reg_startpos[no].col;
- if (cstrncmp(regline + reg_startpos[no].col,
- reginput, &len) != 0)
+ if (rex.reg_startpos[no].lnum == reglnum
+ && rex.reg_endpos[no].lnum == reglnum) {
+ // Compare back-ref within the current line.
+ len = rex.reg_endpos[no].col - rex.reg_startpos[no].col;
+ if (cstrncmp(regline + rex.reg_startpos[no].col,
+ reginput, &len) != 0) {
status = RA_NOMATCH;
+ }
} else {
- /* Messy situation: Need to compare between two
- * lines. */
- int r = match_with_backref(
- reg_startpos[no].lnum,
- reg_startpos[no].col,
- reg_endpos[no].lnum,
- reg_endpos[no].col,
- &len);
-
- if (r != RA_MATCH)
+ // Messy situation: Need to compare between two lines.
+ int r = match_with_backref(rex.reg_startpos[no].lnum,
+ rex.reg_startpos[no].col,
+ rex.reg_endpos[no].lnum,
+ rex.reg_endpos[no].col,
+ &len);
+ if (r != RA_MATCH) {
status = r;
+ }
}
}
}
@@ -4467,7 +4506,7 @@ regmatch (
brace_max[no] = OPERAND_MAX(scan);
brace_count[no] = 0;
} else {
- EMSG(_(e_internal)); /* Shouldn't happen */
+ internal_error("BRACE_LIMITS");
status = RA_FAIL;
}
}
@@ -4543,13 +4582,15 @@ regmatch (
*/
if (OP(next) == EXACTLY) {
rst.nextb = *OPERAND(next);
- if (ireg_ic) {
- if (vim_isupper(rst.nextb))
- rst.nextb_ic = vim_tolower(rst.nextb);
- else
- rst.nextb_ic = vim_toupper(rst.nextb);
- } else
+ if (rex.reg_ic) {
+ if (mb_isupper(rst.nextb)) {
+ rst.nextb_ic = mb_tolower(rst.nextb);
+ } else {
+ rst.nextb_ic = mb_toupper(rst.nextb);
+ }
+ } else {
rst.nextb_ic = rst.nextb;
+ }
} else {
rst.nextb = NUL;
rst.nextb_ic = NUL;
@@ -4648,13 +4689,14 @@ regmatch (
break;
case NEWL:
- if ((c != NUL || !REG_MULTI || reglnum > reg_maxline
- || reg_line_lbr) && (c != '\n' || !reg_line_lbr))
+ if ((c != NUL || !REG_MULTI || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) && (c != '\n' || !rex.reg_line_lbr)) {
status = RA_NOMATCH;
- else if (reg_line_lbr)
+ } else if (rex.reg_line_lbr) {
ADVANCE_REGINPUT();
- else
+ } else {
reg_nextline();
+ }
break;
case END:
@@ -4693,10 +4735,11 @@ regmatch (
break;
case RS_MOPEN:
- /* Pop the state. Restore pointers when there is no match. */
- if (status == RA_NOMATCH)
- restore_se(&rp->rs_un.sesave, &reg_startpos[rp->rs_no],
- &reg_startp[rp->rs_no]);
+ // Pop the state. Restore pointers when there is no match.
+ if (status == RA_NOMATCH) {
+ restore_se(&rp->rs_un.sesave, &rex.reg_startpos[rp->rs_no],
+ &rex.reg_startp[rp->rs_no]);
+ }
regstack_pop(&scan);
break;
@@ -4709,10 +4752,11 @@ regmatch (
break;
case RS_MCLOSE:
- /* Pop the state. Restore pointers when there is no match. */
- if (status == RA_NOMATCH)
- restore_se(&rp->rs_un.sesave, &reg_endpos[rp->rs_no],
- &reg_endp[rp->rs_no]);
+ // Pop the state. Restore pointers when there is no match.
+ if (status == RA_NOMATCH) {
+ restore_se(&rp->rs_un.sesave, &rex.reg_endpos[rp->rs_no],
+ &rex.reg_endp[rp->rs_no]);
+ }
regstack_pop(&scan);
break;
@@ -4875,21 +4919,24 @@ regmatch (
(colnr_T)STRLEN(regline);
}
} else {
- if (has_mbyte)
- rp->rs_un.regsave.rs_u.pos.col -=
- (*mb_head_off)(regline, regline
- + rp->rs_un.regsave.rs_u.pos.col - 1) + 1;
- else
- --rp->rs_un.regsave.rs_u.pos.col;
+ const char_u *const line =
+ reg_getline(rp->rs_un.regsave.rs_u.pos.lnum);
+
+ rp->rs_un.regsave.rs_u.pos.col -=
+ utf_head_off(line,
+ line + rp->rs_un.regsave.rs_u.pos.col - 1)
+ + 1;
}
} else {
- if (rp->rs_un.regsave.rs_u.ptr == regline)
+ if (rp->rs_un.regsave.rs_u.ptr == regline) {
no = FAIL;
- else {
- mb_ptr_back(regline, rp->rs_un.regsave.rs_u.ptr);
- if (limit > 0 && (long)(behind_pos.rs_u.ptr
- - rp->rs_un.regsave.rs_u.ptr) > limit)
+ } else {
+ MB_PTR_BACK(regline, rp->rs_un.regsave.rs_u.ptr);
+ if (limit > 0
+ && (long)(behind_pos.rs_u.ptr
+ - rp->rs_un.regsave.rs_u.ptr) > limit) {
no = FAIL;
+ }
}
}
if (no == OK) {
@@ -4949,17 +4996,18 @@ regmatch (
if (--rst->count < rst->minval)
break;
if (reginput == regline) {
- /* backup to last char of previous line */
- --reglnum;
+ // backup to last char of previous line
+ reglnum--;
regline = reg_getline(reglnum);
- /* Just in case regrepeat() didn't count
- * right. */
- if (regline == NULL)
+ // Just in case regrepeat() didn't count right.
+ if (regline == NULL) {
break;
+ }
reginput = regline + STRLEN(regline);
fast_breakcheck();
- } else
- mb_ptr_back(regline, reginput);
+ } else {
+ MB_PTR_BACK(regline, reginput);
+ }
} else {
/* Range is backwards, use shortest match first.
* Careful: maxval and minval are exchanged!
@@ -5089,13 +5137,14 @@ regrepeat (
/* Matching anything means we continue until end-of-line (or
* end-of-file for ANY + ADD_NL), only limited by maxcount. */
while (*scan != NUL && count < maxcount) {
- ++count;
- mb_ptr_adv(scan);
+ count++;
+ MB_PTR_ADV(scan);
}
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr || count == maxcount)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr || count == maxcount) {
break;
- ++count; /* count the line-break */
+ }
+ count++; // count the line-break
reg_nextline();
scan = reginput;
if (got_int)
@@ -5105,103 +5154,114 @@ regrepeat (
case IDENT:
case IDENT + ADD_NL:
- testval = TRUE;
- /*FALLTHROUGH*/
+ testval = 1;
+ FALLTHROUGH;
case SIDENT:
case SIDENT + ADD_NL:
while (count < maxcount) {
if (vim_isIDc(PTR2CHAR(scan)) && (testval || !ascii_isdigit(*scan))) {
- mb_ptr_adv(scan);
+ MB_PTR_ADV(scan);
} else if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
if (got_int)
break;
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
+ }
++count;
}
break;
case KWORD:
case KWORD + ADD_NL:
- testval = TRUE;
- /*FALLTHROUGH*/
+ testval = 1;
+ FALLTHROUGH;
case SKWORD:
case SKWORD + ADD_NL:
while (count < maxcount) {
- if (vim_iswordp_buf(scan, reg_buf)
+ if (vim_iswordp_buf(scan, rex.reg_buf)
&& (testval || !ascii_isdigit(*scan))) {
- mb_ptr_adv(scan);
+ MB_PTR_ADV(scan);
} else if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
- if (got_int)
+ if (got_int) {
break;
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ }
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
- ++count;
+ }
+ count++;
}
break;
case FNAME:
case FNAME + ADD_NL:
- testval = TRUE;
- /*FALLTHROUGH*/
+ testval = 1;
+ FALLTHROUGH;
case SFNAME:
case SFNAME + ADD_NL:
while (count < maxcount) {
if (vim_isfilec(PTR2CHAR(scan)) && (testval || !ascii_isdigit(*scan))) {
- mb_ptr_adv(scan);
+ MB_PTR_ADV(scan);
} else if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
- if (got_int)
+ if (got_int) {
break;
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ }
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
- ++count;
+ }
+ count++;
}
break;
case PRINT:
case PRINT + ADD_NL:
- testval = TRUE;
- /*FALLTHROUGH*/
+ testval = 1;
+ FALLTHROUGH;
case SPRINT:
case SPRINT + ADD_NL:
while (count < maxcount) {
if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
- if (got_int)
+ if (got_int) {
break;
+ }
} else if (vim_isprintc(PTR2CHAR(scan)) == 1
&& (testval || !ascii_isdigit(*scan))) {
- mb_ptr_adv(scan);
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ MB_PTR_ADV(scan);
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
- ++count;
+ }
+ count++;
}
break;
@@ -5212,9 +5272,10 @@ do_class:
while (count < maxcount) {
int l;
if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
if (got_int)
@@ -5223,12 +5284,13 @@ do_class:
if (testval != 0)
break;
scan += l;
- } else if ((class_tab[*scan] & mask) == testval)
- ++scan;
- else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else
+ } else if ((class_tab[*scan] & mask) == testval) {
+ scan++;
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else {
break;
+ }
++count;
}
break;
@@ -5306,12 +5368,12 @@ do_class:
{
int cu, cl;
- /* This doesn't do a multi-byte character, because a MULTIBYTECODE
- * would have been used for it. It does handle single-byte
- * characters, such as latin1. */
- if (ireg_ic) {
- cu = vim_toupper(*opnd);
- cl = vim_tolower(*opnd);
+ // This doesn't do a multi-byte character, because a MULTIBYTECODE
+ // would have been used for it. It does handle single-byte
+ // characters, such as latin1.
+ if (rex.reg_ic) {
+ cu = mb_toupper(*opnd);
+ cl = mb_tolower(*opnd);
while (count < maxcount && (*scan == cu || *scan == cl)) {
count++;
scan++;
@@ -5333,17 +5395,19 @@ do_class:
/* Safety check (just in case 'encoding' was changed since
* compiling the program). */
if ((len = (*mb_ptr2len)(opnd)) > 1) {
- if (ireg_ic && enc_utf8)
+ if (rex.reg_ic && enc_utf8) {
cf = utf_fold(utf_ptr2char(opnd));
+ }
while (count < maxcount && (*mb_ptr2len)(scan) >= len) {
for (i = 0; i < len; ++i) {
if (opnd[i] != scan[i]) {
break;
}
}
- if (i < len && (!ireg_ic || !enc_utf8
- || utf_fold(utf_ptr2char(scan)) != cf))
+ if (i < len && (!rex.reg_ic || !enc_utf8
+ || utf_fold(utf_ptr2char(scan)) != cf)) {
break;
+ }
scan += len;
++count;
}
@@ -5353,26 +5417,29 @@ do_class:
case ANYOF:
case ANYOF + ADD_NL:
- testval = TRUE;
- /*FALLTHROUGH*/
+ testval = 1;
+ FALLTHROUGH;
case ANYBUT:
case ANYBUT + ADD_NL:
while (count < maxcount) {
int len;
if (*scan == NUL) {
- if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > reg_maxline
- || reg_line_lbr)
+ if (!REG_MULTI || !WITH_NL(OP(p)) || reglnum > rex.reg_maxline
+ || rex.reg_line_lbr) {
break;
+ }
reg_nextline();
scan = reginput;
- if (got_int)
+ if (got_int) {
break;
- } else if (reg_line_lbr && *scan == '\n' && WITH_NL(OP(p)))
- ++scan;
- else if (has_mbyte && (len = (*mb_ptr2len)(scan)) > 1) {
- if ((cstrchr(opnd, (*mb_ptr2char)(scan)) == NULL) == testval)
+ }
+ } else if (rex.reg_line_lbr && *scan == '\n' && WITH_NL(OP(p))) {
+ scan++;
+ } else if ((len = utfc_ptr2len(scan)) > 1) {
+ if ((cstrchr(opnd, utf_ptr2char(scan)) == NULL) == testval) {
break;
+ }
scan += len;
} else {
if ((cstrchr(opnd, *scan) == NULL) == testval)
@@ -5385,13 +5452,14 @@ do_class:
case NEWL:
while (count < maxcount
- && ((*scan == NUL && reglnum <= reg_maxline && !reg_line_lbr
- && REG_MULTI) || (*scan == '\n' && reg_line_lbr))) {
+ && ((*scan == NUL && reglnum <= rex.reg_maxline && !rex.reg_line_lbr
+ && REG_MULTI) || (*scan == '\n' && rex.reg_line_lbr))) {
count++;
- if (reg_line_lbr)
+ if (rex.reg_line_lbr) {
ADVANCE_REGINPUT();
- else
+ } else {
reg_nextline();
+ }
scan = reginput;
if (got_int)
break;
@@ -5441,10 +5509,11 @@ static int prog_magic_wrong(void)
{
regprog_T *prog;
- prog = REG_MULTI ? reg_mmatch->regprog : reg_match->regprog;
- if (prog->engine == &nfa_regengine)
- /* For NFA matcher we don't check the magic */
- return FALSE;
+ prog = REG_MULTI ? rex.reg_mmatch->regprog : rex.reg_match->regprog;
+ if (prog->engine == &nfa_regengine) {
+ // For NFA matcher we don't check the magic
+ return false;
+ }
if (UCHARAT(((bt_regprog_T *)prog)->program) != REGMAGIC) {
EMSG(_(e_re_corr));
@@ -5462,12 +5531,12 @@ static void cleanup_subexpr(void)
{
if (need_clear_subexpr) {
if (REG_MULTI) {
- /* Use 0xff to set lnum to -1 */
- memset(reg_startpos, 0xff, sizeof(lpos_T) * NSUBEXP);
- memset(reg_endpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+ // Use 0xff to set lnum to -1
+ memset(rex.reg_startpos, 0xff, sizeof(lpos_T) * NSUBEXP);
+ memset(rex.reg_endpos, 0xff, sizeof(lpos_T) * NSUBEXP);
} else {
- memset(reg_startp, 0, sizeof(char_u *) * NSUBEXP);
- memset(reg_endp, 0, sizeof(char_u *) * NSUBEXP);
+ memset(rex.reg_startp, 0, sizeof(char_u *) * NSUBEXP);
+ memset(rex.reg_endp, 0, sizeof(char_u *) * NSUBEXP);
}
need_clear_subexpr = FALSE;
}
@@ -5496,17 +5565,17 @@ static void save_subexpr(regbehind_T *bp)
{
int i;
- /* When "need_clear_subexpr" is set we don't need to save the values, only
- * remember that this flag needs to be set again when restoring. */
+ // When "need_clear_subexpr" is set we don't need to save the values, only
+ // remember that this flag needs to be set again when restoring.
bp->save_need_clear_subexpr = need_clear_subexpr;
if (!need_clear_subexpr) {
for (i = 0; i < NSUBEXP; ++i) {
if (REG_MULTI) {
- bp->save_start[i].se_u.pos = reg_startpos[i];
- bp->save_end[i].se_u.pos = reg_endpos[i];
+ bp->save_start[i].se_u.pos = rex.reg_startpos[i];
+ bp->save_end[i].se_u.pos = rex.reg_endpos[i];
} else {
- bp->save_start[i].se_u.ptr = reg_startp[i];
- bp->save_end[i].se_u.ptr = reg_endp[i];
+ bp->save_start[i].se_u.ptr = rex.reg_startp[i];
+ bp->save_end[i].se_u.ptr = rex.reg_endp[i];
}
}
}
@@ -5524,11 +5593,11 @@ static void restore_subexpr(regbehind_T *bp)
if (!need_clear_subexpr) {
for (i = 0; i < NSUBEXP; ++i) {
if (REG_MULTI) {
- reg_startpos[i] = bp->save_start[i].se_u.pos;
- reg_endpos[i] = bp->save_end[i].se_u.pos;
+ rex.reg_startpos[i] = bp->save_start[i].se_u.pos;
+ rex.reg_endpos[i] = bp->save_end[i].se_u.pos;
} else {
- reg_startp[i] = bp->save_start[i].se_u.ptr;
- reg_endp[i] = bp->save_end[i].se_u.ptr;
+ rex.reg_startp[i] = bp->save_start[i].se_u.ptr;
+ rex.reg_endp[i] = bp->save_end[i].se_u.ptr;
}
}
}
@@ -5664,10 +5733,12 @@ static int match_with_backref(linenr_T start_lnum, colnr_T start_col, linenr_T e
return RA_NOMATCH; /* doesn't match */
if (bytelen != NULL)
*bytelen += len;
- if (clnum == end_lnum)
- break; /* match and at end! */
- if (reglnum >= reg_maxline)
- return RA_NOMATCH; /* text too short */
+ if (clnum == end_lnum) {
+ break; // match and at end!
+ }
+ if (reglnum >= rex.reg_maxline) {
+ return RA_NOMATCH; // text too short
+ }
/* Advance to next line. */
reg_nextline();
@@ -6215,24 +6286,22 @@ static void mb_decompose(int c, int *c1, int *c2, int *c3)
}
}
-/*
- * Compare two strings, ignore case if ireg_ic set.
- * Return 0 if strings match, non-zero otherwise.
- * Correct the length "*n" when composing characters are ignored.
- */
+// Compare two strings, ignore case if rex.reg_ic set.
+// Return 0 if strings match, non-zero otherwise.
+// Correct the length "*n" when composing characters are ignored.
static int cstrncmp(char_u *s1, char_u *s2, int *n)
{
int result;
- if (!ireg_ic)
+ if (!rex.reg_ic) {
result = STRNCMP(s1, s2, *n);
- else {
+ } else {
assert(*n >= 0);
result = mb_strnicmp(s1, s2, (size_t)*n);
}
- /* if it failed and it's utf8 and we want to combineignore: */
- if (result != 0 && enc_utf8 && ireg_icombine) {
+ // if it failed and it's utf8 and we want to combineignore:
+ if (result != 0 && enc_utf8 && rex.reg_icombine) {
char_u *str1, *str2;
int c1, c2, c11, c12;
int junk;
@@ -6243,20 +6312,21 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
str2 = s2;
c1 = c2 = 0;
while ((int)(str1 - s1) < *n) {
- c1 = mb_ptr2char_adv(&str1);
- c2 = mb_ptr2char_adv(&str2);
+ c1 = mb_ptr2char_adv((const char_u **)&str1);
+ c2 = mb_ptr2char_adv((const char_u **)&str2);
/* decompose the character if necessary, into 'base' characters
* because I don't care about Arabic, I will hard-code the Hebrew
* which I *do* care about! So sue me... */
- if (c1 != c2 && (!ireg_ic || utf_fold(c1) != utf_fold(c2))) {
- /* decomposition necessary? */
+ if (c1 != c2 && (!rex.reg_ic || utf_fold(c1) != utf_fold(c2))) {
+ // decomposition necessary?
mb_decompose(c1, &c11, &junk, &junk);
mb_decompose(c2, &c12, &junk, &junk);
c1 = c11;
c2 = c12;
- if (c11 != c12 && (!ireg_ic || utf_fold(c11) != utf_fold(c12)))
+ if (c11 != c12 && (!rex.reg_ic || utf_fold(c11) != utf_fold(c12))) {
break;
+ }
}
}
result = c2 - c1;
@@ -6267,48 +6337,6 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
return result;
}
-/*
- * cstrchr: This function is used a lot for simple searches, keep it fast!
- */
-static char_u *cstrchr(char_u *s, int c)
-{
- char_u *p;
- int cc;
-
- if (!ireg_ic
- || (!enc_utf8 && mb_char2len(c) > 1)
- )
- return vim_strchr(s, c);
-
- /* tolower() and toupper() can be slow, comparing twice should be a lot
- * faster (esp. when using MS Visual C++!).
- * For UTF-8 need to use folded case. */
- if (enc_utf8 && c > 0x80)
- cc = utf_fold(c);
- else if (vim_isupper(c))
- cc = vim_tolower(c);
- else if (vim_islower(c))
- cc = vim_toupper(c);
- else
- return vim_strchr(s, c);
-
- if (has_mbyte) {
- for (p = s; *p != NUL; p += (*mb_ptr2len)(p)) {
- if (enc_utf8 && c > 0x80) {
- if (utf_fold(utf_ptr2char(p)) == cc)
- return p;
- } else if (*p == c || *p == cc)
- return p;
- }
- } else
- /* Faster version for when there are no multi-byte characters. */
- for (p = s; *p != NUL; ++p)
- if (*p == c || *p == cc)
- return p;
-
- return NULL;
-}
-
/***************************************************************
* regsub stuff *
***************************************************************/
@@ -6319,28 +6347,28 @@ static char_u *cstrchr(char_u *s, int c)
static fptr_T do_upper(int *d, int c)
{
- *d = vim_toupper(c);
+ *d = mb_toupper(c);
return (fptr_T)NULL;
}
static fptr_T do_Upper(int *d, int c)
{
- *d = vim_toupper(c);
+ *d = mb_toupper(c);
return (fptr_T)do_Upper;
}
static fptr_T do_lower(int *d, int c)
{
- *d = vim_tolower(c);
+ *d = mb_tolower(c);
return (fptr_T)NULL;
}
static fptr_T do_Lower(int *d, int c)
{
- *d = vim_tolower(c);
+ *d = mb_tolower(c);
return (fptr_T)do_Lower;
}
@@ -6408,55 +6436,126 @@ char_u *regtilde(char_u *source, int magic)
static int can_f_submatch = FALSE; /* TRUE when submatch() can be used */
-/* These pointers are used instead of reg_match and reg_mmatch for
- * reg_submatch(). Needed for when the substitution string is an expression
- * that contains a call to substitute() and submatch(). */
-static regmatch_T *submatch_match;
-static regmmatch_T *submatch_mmatch;
-static linenr_T submatch_firstlnum;
-static linenr_T submatch_maxline;
-static int submatch_line_lbr;
+// These pointers are used for reg_submatch(). Needed for when the
+// substitution string is an expression that contains a call to substitute()
+// and submatch().
+typedef struct {
+ regmatch_T *sm_match;
+ regmmatch_T *sm_mmatch;
+ linenr_T sm_firstlnum;
+ linenr_T sm_maxline;
+ int sm_line_lbr;
+} regsubmatch_T;
+
+static regsubmatch_T rsm; // can only be used when can_f_submatch is true
+
+/// Put the submatches in "argv[0]" which is a list passed into call_func() by
+/// vim_regsub_both().
+static int fill_submatch_list(int argc, typval_T *argv, int argcount)
+{
+ if (argcount == 0) {
+ // called function doesn't take an argument
+ return 0;
+ }
+
+ // Relies on sl_list to be the first item in staticList10_T.
+ tv_list_init_static10((staticList10_T *)argv->vval.v_list);
-/*
- * vim_regsub() - perform substitutions after a vim_regexec() or
- * vim_regexec_multi() match.
- *
- * If "copy" is TRUE really copy into "dest".
- * If "copy" is FALSE nothing is copied, this is just to find out the length
- * of the result.
- *
- * If "backslash" is TRUE, a backslash will be removed later, need to double
- * them to keep them, and insert a backslash before a CR to avoid it being
- * replaced with a line break later.
- *
- * Note: The matched text must not change between the call of
- * vim_regexec()/vim_regexec_multi() and vim_regsub()! It would make the back
- * references invalid!
- *
- * Returns the size of the replacement, including terminating NUL.
- */
-int vim_regsub(regmatch_T *rmp, char_u *source, char_u *dest, int copy, int magic, int backslash)
+ // There are always 10 list items in staticList10_T.
+ listitem_T *li = tv_list_first(argv->vval.v_list);
+ for (int i = 0; i < 10; i++) {
+ char_u *s = rsm.sm_match->startp[i];
+ if (s == NULL || rsm.sm_match->endp[i] == NULL) {
+ s = NULL;
+ } else {
+ s = vim_strnsave(s, (int)(rsm.sm_match->endp[i] - s));
+ }
+ TV_LIST_ITEM_TV(li)->v_type = VAR_STRING;
+ TV_LIST_ITEM_TV(li)->vval.v_string = s;
+ li = TV_LIST_ITEM_NEXT(argv->vval.v_list, li);
+ }
+ return 1;
+}
+
+static void clear_submatch_list(staticList10_T *sl)
{
- reg_match = rmp;
- reg_mmatch = NULL;
- reg_maxline = 0;
- reg_buf = curbuf;
- reg_line_lbr = TRUE;
- return vim_regsub_both(source, dest, copy, magic, backslash);
+ TV_LIST_ITER(&sl->sl_list, li, {
+ xfree(TV_LIST_ITEM_TV(li)->vval.v_string);
+ });
+}
+
+/// vim_regsub() - perform substitutions after a vim_regexec() or
+/// vim_regexec_multi() match.
+///
+/// If "copy" is TRUE really copy into "dest".
+/// If "copy" is FALSE nothing is copied, this is just to find out the length
+/// of the result.
+///
+/// If "backslash" is TRUE, a backslash will be removed later, need to double
+/// them to keep them, and insert a backslash before a CR to avoid it being
+/// replaced with a line break later.
+///
+/// Note: The matched text must not change between the call of
+/// vim_regexec()/vim_regexec_multi() and vim_regsub()! It would make the back
+/// references invalid!
+///
+/// Returns the size of the replacement, including terminating NUL.
+int vim_regsub(regmatch_T *rmp, char_u *source, typval_T *expr, char_u *dest,
+ int copy, int magic, int backslash)
+{
+ regexec_T rex_save;
+ bool rex_in_use_save = rex_in_use;
+
+ if (rex_in_use) {
+ // Being called recursively, save the state.
+ rex_save = rex;
+ }
+ rex_in_use = true;
+
+ rex.reg_match = rmp;
+ rex.reg_mmatch = NULL;
+ rex.reg_maxline = 0;
+ rex.reg_buf = curbuf;
+ rex.reg_line_lbr = true;
+ int result = vim_regsub_both(source, expr, dest, copy, magic, backslash);
+
+ rex_in_use = rex_in_use_save;
+ if (rex_in_use) {
+ rex = rex_save;
+ }
+
+ return result;
}
int vim_regsub_multi(regmmatch_T *rmp, linenr_T lnum, char_u *source, char_u *dest, int copy, int magic, int backslash)
{
- reg_match = NULL;
- reg_mmatch = rmp;
- reg_buf = curbuf; /* always works on the current buffer! */
- reg_firstlnum = lnum;
- reg_maxline = curbuf->b_ml.ml_line_count - lnum;
- reg_line_lbr = FALSE;
- return vim_regsub_both(source, dest, copy, magic, backslash);
+ regexec_T rex_save;
+ bool rex_in_use_save = rex_in_use;
+
+ if (rex_in_use) {
+ // Being called recursively, save the state.
+ rex_save = rex;
+ }
+ rex_in_use = true;
+
+ rex.reg_match = NULL;
+ rex.reg_mmatch = rmp;
+ rex.reg_buf = curbuf; // always works on the current buffer!
+ rex.reg_firstlnum = lnum;
+ rex.reg_maxline = curbuf->b_ml.ml_line_count - lnum;
+ rex.reg_line_lbr = false;
+ int result = vim_regsub_both(source, NULL, dest, copy, magic, backslash);
+
+ rex_in_use = rex_in_use_save;
+ if (rex_in_use) {
+ rex = rex_save;
+ }
+
+ return result;
}
-static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, int backslash)
+static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
+ int copy, int magic, int backslash)
{
char_u *src;
char_u *dst;
@@ -6470,8 +6569,8 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
int len = 0; /* init for GCC */
static char_u *eval_result = NULL;
- /* Be paranoid... */
- if (source == NULL || dest == NULL) {
+ // Be paranoid...
+ if ((source == NULL && expr == NULL) || dest == NULL) {
EMSG(_(e_null));
return 0;
}
@@ -6480,16 +6579,12 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
src = source;
dst = dest;
- /*
- * When the substitute part starts with "\=" evaluate it as an expression.
- */
- if (source[0] == '\\' && source[1] == '='
- && !can_f_submatch /* can't do this recursively */
- ) {
- /* To make sure that the length doesn't change between checking the
- * length and copying the string, and to speed up things, the
- * resulting string is saved from the call with "copy" == FALSE to the
- * call with "copy" == TRUE. */
+ // When the substitute part starts with "\=" evaluate it as an expression.
+ if (expr != NULL || (source[0] == '\\' && source[1] == '=')) {
+ // To make sure that the length doesn't change between checking the
+ // length and copying the string, and to speed up things, the
+ // resulting string is saved from the call with "copy" == FALSE to the
+ // call with "copy" == TRUE.
if (copy) {
if (eval_result != NULL) {
STRCPY(dest, eval_result);
@@ -6498,45 +6593,82 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
eval_result = NULL;
}
} else {
- win_T *save_reg_win;
- int save_ireg_ic;
+ int prev_can_f_submatch = can_f_submatch;
+ regsubmatch_T rsm_save;
xfree(eval_result);
- /* The expression may contain substitute(), which calls us
- * recursively. Make sure submatch() gets the text from the first
- * level. Don't need to save "reg_buf", because
- * vim_regexec_multi() can't be called recursively. */
- submatch_match = reg_match;
- submatch_mmatch = reg_mmatch;
- submatch_firstlnum = reg_firstlnum;
- submatch_maxline = reg_maxline;
- submatch_line_lbr = reg_line_lbr;
- save_reg_win = reg_win;
- save_ireg_ic = ireg_ic;
- can_f_submatch = TRUE;
-
- eval_result = eval_to_string(source + 2, NULL, TRUE);
+ // The expression may contain substitute(), which calls us
+ // recursively. Make sure submatch() gets the text from the first
+ // level.
+ if (can_f_submatch) {
+ rsm_save = rsm;
+ }
+ can_f_submatch = true;
+ rsm.sm_match = rex.reg_match;
+ rsm.sm_mmatch = rex.reg_mmatch;
+ rsm.sm_firstlnum = rex.reg_firstlnum;
+ rsm.sm_maxline = rex.reg_maxline;
+ rsm.sm_line_lbr = rex.reg_line_lbr;
+
+ if (expr != NULL) {
+ typval_T argv[2];
+ int dummy;
+ typval_T rettv;
+ staticList10_T matchList = TV_LIST_STATIC10_INIT;
+
+ rettv.v_type = VAR_STRING;
+ rettv.vval.v_string = NULL;
+ argv[0].v_type = VAR_LIST;
+ argv[0].vval.v_list = &matchList.sl_list;
+ if (expr->v_type == VAR_FUNC) {
+ s = expr->vval.v_string;
+ call_func(s, (int)STRLEN(s), &rettv, 1, argv,
+ fill_submatch_list, 0L, 0L, &dummy,
+ true, NULL, NULL);
+ } else if (expr->v_type == VAR_PARTIAL) {
+ partial_T *partial = expr->vval.v_partial;
+
+ s = partial_name(partial);
+ call_func(s, (int)STRLEN(s), &rettv, 1, argv,
+ fill_submatch_list, 0L, 0L, &dummy,
+ true, partial, NULL);
+ }
+ if (tv_list_len(&matchList.sl_list) > 0) {
+ // fill_submatch_list() was called.
+ clear_submatch_list(&matchList);
+ }
+ char buf[NUMBUFLEN];
+ eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf);
+ if (eval_result != NULL) {
+ eval_result = vim_strsave(eval_result);
+ }
+ tv_clear(&rettv);
+ } else {
+ eval_result = eval_to_string(source + 2, NULL, true);
+ }
+
if (eval_result != NULL) {
int had_backslash = FALSE;
- for (s = eval_result; *s != NUL; mb_ptr_adv(s)) {
- /* Change NL to CR, so that it becomes a line break,
- * unless called from vim_regexec_nl().
- * Skip over a backslashed character. */
- if (*s == NL && !submatch_line_lbr)
+ for (s = eval_result; *s != NUL; MB_PTR_ADV(s)) {
+ // Change NL to CR, so that it becomes a line break,
+ // unless called from vim_regexec_nl().
+ // Skip over a backslashed character.
+ if (*s == NL && !rsm.sm_line_lbr) {
*s = CAR;
- else if (*s == '\\' && s[1] != NUL) {
- ++s;
+ } else if (*s == '\\' && s[1] != NUL) {
+ s++;
/* Change NL to CR here too, so that this works:
* :s/abc\\\ndef/\="aaa\\\nbbb"/ on text:
* abc\
* def
* Not when called from vim_regexec_nl().
*/
- if (*s == NL && !submatch_line_lbr)
+ if (*s == NL && !rsm.sm_line_lbr) {
*s = CAR;
- had_backslash = TRUE;
+ }
+ had_backslash = true;
}
}
if (had_backslash && backslash) {
@@ -6549,14 +6681,10 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
dst += STRLEN(eval_result);
}
- reg_match = submatch_match;
- reg_mmatch = submatch_mmatch;
- reg_firstlnum = submatch_firstlnum;
- reg_maxline = submatch_maxline;
- reg_line_lbr = submatch_line_lbr;
- reg_win = save_reg_win;
- ireg_ic = save_ireg_ic;
- can_f_submatch = FALSE;
+ can_f_submatch = prev_can_f_submatch;
+ if (can_f_submatch) {
+ rsm = rsm_save;
+ }
}
} else
while ((c = *src++) != NUL) {
@@ -6617,80 +6745,83 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
}
c = *src++;
}
- } else if (has_mbyte)
- c = mb_ptr2char(src - 1);
-
- /* Write to buffer, if copy is set. */
- if (func_one != (fptr_T)NULL)
- /* Turbo C complains without the typecast */
+ } else {
+ c = utf_ptr2char(src - 1);
+ }
+ // Write to buffer, if copy is set.
+ if (func_one != NULL) {
func_one = (fptr_T)(func_one(&cc, c));
- else if (func_all != (fptr_T)NULL)
- /* Turbo C complains without the typecast */
+ } else if (func_all != NULL) {
func_all = (fptr_T)(func_all(&cc, c));
- else /* just copy */
+ } else {
+ // just copy
cc = c;
+ }
- if (has_mbyte) {
- int totlen = mb_ptr2len(src - 1);
+ int totlen = utfc_ptr2len(src - 1);
- if (copy)
- mb_char2bytes(cc, dst);
- dst += mb_char2len(cc) - 1;
- if (enc_utf8) {
- int clen = utf_ptr2len(src - 1);
+ if (copy) {
+ utf_char2bytes(cc, dst);
+ }
+ dst += utf_char2len(cc) - 1;
+ int clen = utf_ptr2len(src - 1);
- /* If the character length is shorter than "totlen", there
- * are composing characters; copy them as-is. */
- if (clen < totlen) {
- if (copy)
- memmove(dst + 1, src - 1 + clen,
- (size_t)(totlen - clen));
- dst += totlen - clen;
- }
+ // If the character length is shorter than "totlen", there
+ // are composing characters; copy them as-is.
+ if (clen < totlen) {
+ if (copy) {
+ memmove(dst + 1, src - 1 + clen, (size_t)(totlen - clen));
}
- src += totlen - 1;
- } else if (copy)
- *dst = cc;
+ dst += totlen - clen;
+ }
+ src += totlen - 1;
dst++;
} else {
if (REG_MULTI) {
- clnum = reg_mmatch->startpos[no].lnum;
- if (clnum < 0 || reg_mmatch->endpos[no].lnum < 0)
+ clnum = rex.reg_mmatch->startpos[no].lnum;
+ if (clnum < 0 || rex.reg_mmatch->endpos[no].lnum < 0) {
s = NULL;
- else {
- s = reg_getline(clnum) + reg_mmatch->startpos[no].col;
- if (reg_mmatch->endpos[no].lnum == clnum)
- len = reg_mmatch->endpos[no].col
- - reg_mmatch->startpos[no].col;
- else
+ } else {
+ s = reg_getline(clnum) + rex.reg_mmatch->startpos[no].col;
+ if (rex.reg_mmatch->endpos[no].lnum == clnum) {
+ len = rex.reg_mmatch->endpos[no].col
+ - rex.reg_mmatch->startpos[no].col;
+ } else {
len = (int)STRLEN(s);
+ }
}
} else {
- s = reg_match->startp[no];
- if (reg_match->endp[no] == NULL)
+ s = rex.reg_match->startp[no];
+ if (rex.reg_match->endp[no] == NULL) {
s = NULL;
- else
- len = (int)(reg_match->endp[no] - s);
+ } else {
+ len = (int)(rex.reg_match->endp[no] - s);
+ }
}
if (s != NULL) {
for (;; ) {
if (len == 0) {
if (REG_MULTI) {
- if (reg_mmatch->endpos[no].lnum == clnum)
+ if (rex.reg_mmatch->endpos[no].lnum == clnum) {
break;
- if (copy)
+ }
+ if (copy) {
*dst = CAR;
- ++dst;
+ }
+ dst++;
s = reg_getline(++clnum);
- if (reg_mmatch->endpos[no].lnum == clnum)
- len = reg_mmatch->endpos[no].col;
- else
+ if (rex.reg_mmatch->endpos[no].lnum == clnum) {
+ len = rex.reg_mmatch->endpos[no].col;
+ } else {
len = (int)STRLEN(s);
- } else
+ }
+ } else {
break;
- } else if (*s == NUL) { /* we hit NUL. */
- if (copy)
+ }
+ } else if (*s == NUL) { // we hit NUL.
+ if (copy) {
EMSG(_(e_re_damg));
+ }
goto exit;
} else {
if (backslash && (*s == CAR || *s == '\\')) {
@@ -6706,10 +6837,7 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
}
dst += 2;
} else {
- if (has_mbyte)
- c = mb_ptr2char(s);
- else
- c = *s;
+ c = utf_ptr2char(s);
if (func_one != (fptr_T)NULL)
/* Turbo C complains without the typecast */
@@ -6723,20 +6851,19 @@ static int vim_regsub_both(char_u *source, char_u *dest, int copy, int magic, in
if (has_mbyte) {
int l;
- /* Copy composing characters separately, one
- * at a time. */
- if (enc_utf8)
- l = utf_ptr2len(s) - 1;
- else
- l = mb_ptr2len(s) - 1;
+ // Copy composing characters separately, one
+ // at a time.
+ l = utf_ptr2len(s) - 1;
s += l;
len -= l;
- if (copy)
- mb_char2bytes(cc, dst);
- dst += mb_char2len(cc) - 1;
- } else if (copy)
+ if (copy) {
+ utf_char2bytes(cc, dst);
+ }
+ dst += utf_char2len(cc) - 1;
+ } else if (copy) {
*dst = cc;
+ }
dst++;
}
@@ -6764,16 +6891,16 @@ exit:
static char_u *reg_getline_submatch(linenr_T lnum)
{
char_u *s;
- linenr_T save_first = reg_firstlnum;
- linenr_T save_max = reg_maxline;
+ linenr_T save_first = rex.reg_firstlnum;
+ linenr_T save_max = rex.reg_maxline;
- reg_firstlnum = submatch_firstlnum;
- reg_maxline = submatch_maxline;
+ rex.reg_firstlnum = rsm.sm_firstlnum;
+ rex.reg_maxline = rsm.sm_maxline;
s = reg_getline(lnum);
- reg_firstlnum = save_first;
- reg_maxline = save_max;
+ rex.reg_firstlnum = save_first;
+ rex.reg_maxline = save_max;
return s;
}
@@ -6792,39 +6919,41 @@ char_u *reg_submatch(int no)
if (!can_f_submatch || no < 0)
return NULL;
- if (submatch_match == NULL) {
+ if (rsm.sm_match == NULL) {
ssize_t len;
/*
* First round: compute the length and allocate memory.
* Second round: copy the text.
*/
- for (round = 1; round <= 2; ++round) {
- lnum = submatch_mmatch->startpos[no].lnum;
- if (lnum < 0 || submatch_mmatch->endpos[no].lnum < 0)
+ for (round = 1; round <= 2; round++) {
+ lnum = rsm.sm_mmatch->startpos[no].lnum;
+ if (lnum < 0 || rsm.sm_mmatch->endpos[no].lnum < 0) {
return NULL;
+ }
- s = reg_getline_submatch(lnum) + submatch_mmatch->startpos[no].col;
- if (s == NULL) /* anti-crash check, cannot happen? */
+ s = reg_getline_submatch(lnum) + rsm.sm_mmatch->startpos[no].col;
+ if (s == NULL) { // anti-crash check, cannot happen?
break;
- if (submatch_mmatch->endpos[no].lnum == lnum) {
- /* Within one line: take form start to end col. */
- len = submatch_mmatch->endpos[no].col
- - submatch_mmatch->startpos[no].col;
- if (round == 2)
+ }
+ if (rsm.sm_mmatch->endpos[no].lnum == lnum) {
+ // Within one line: take form start to end col.
+ len = rsm.sm_mmatch->endpos[no].col - rsm.sm_mmatch->startpos[no].col;
+ if (round == 2) {
STRLCPY(retval, s, len + 1);
- ++len;
+ }
+ len++;
} else {
- /* Multiple lines: take start line from start col, middle
- * lines completely and end line up to end col. */
- len = STRLEN(s);
+ // Multiple lines: take start line from start col, middle
+ // lines completely and end line up to end col.
+ len = (ssize_t)STRLEN(s);
if (round == 2) {
STRCPY(retval, s);
retval[len] = '\n';
}
- ++len;
- ++lnum;
- while (lnum < submatch_mmatch->endpos[no].lnum) {
+ len++;
+ lnum++;
+ while (lnum < rsm.sm_mmatch->endpos[no].lnum) {
s = reg_getline_submatch(lnum++);
if (round == 2)
STRCPY(retval + len, s);
@@ -6833,13 +6962,15 @@ char_u *reg_submatch(int no)
retval[len] = '\n';
++len;
}
- if (round == 2)
+ if (round == 2) {
STRNCPY(retval + len, reg_getline_submatch(lnum),
- submatch_mmatch->endpos[no].col);
- len += submatch_mmatch->endpos[no].col;
- if (round == 2)
- retval[len] = NUL;
- ++len;
+ rsm.sm_mmatch->endpos[no].col);
+ }
+ len += rsm.sm_mmatch->endpos[no].col;
+ if (round == 2) {
+ retval[len] = NUL; // -V595
+ }
+ len++;
}
if (retval == NULL) {
@@ -6847,11 +6978,12 @@ char_u *reg_submatch(int no)
}
}
} else {
- s = submatch_match->startp[no];
- if (s == NULL || submatch_match->endp[no] == NULL)
+ s = rsm.sm_match->startp[no];
+ if (s == NULL || rsm.sm_match->endp[no] == NULL) {
retval = NULL;
- else
- retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s));
+ } else {
+ retval = vim_strnsave(s, (int)(rsm.sm_match->endp[no] - s));
+ }
}
return retval;
@@ -6871,39 +7003,39 @@ list_T *reg_submatch_list(int no)
linenr_T slnum;
linenr_T elnum;
list_T *list;
- char_u *s;
+ const char *s;
- if (submatch_match == NULL) {
- slnum = submatch_mmatch->startpos[no].lnum;
- elnum = submatch_mmatch->endpos[no].lnum;
+ if (rsm.sm_match == NULL) {
+ slnum = rsm.sm_mmatch->startpos[no].lnum;
+ elnum = rsm.sm_mmatch->endpos[no].lnum;
if (slnum < 0 || elnum < 0) {
return NULL;
}
- colnr_T scol = submatch_mmatch->startpos[no].col;
- colnr_T ecol = submatch_mmatch->endpos[no].col;
+ colnr_T scol = rsm.sm_mmatch->startpos[no].col;
+ colnr_T ecol = rsm.sm_mmatch->endpos[no].col;
- list = list_alloc();
+ list = tv_list_alloc(elnum - slnum + 1);
- s = reg_getline_submatch(slnum) + scol;
+ s = (const char *)reg_getline_submatch(slnum) + scol;
if (slnum == elnum) {
- list_append_string(list, s, ecol - scol);
+ tv_list_append_string(list, s, ecol - scol);
} else {
- list_append_string(list, s, -1);
+ tv_list_append_string(list, s, -1);
for (int i = 1; i < elnum - slnum; i++) {
- s = reg_getline_submatch(slnum + i);
- list_append_string(list, s, -1);
+ s = (const char *)reg_getline_submatch(slnum + i);
+ tv_list_append_string(list, s, -1);
}
- s = reg_getline_submatch(elnum);
- list_append_string(list, s, ecol);
+ s = (const char *)reg_getline_submatch(elnum);
+ tv_list_append_string(list, s, ecol);
}
} else {
- s = submatch_match->startp[no];
- if (s == NULL || submatch_match->endp[no] == NULL) {
+ s = (const char *)rsm.sm_match->startp[no];
+ if (s == NULL || rsm.sm_match->endp[no] == NULL) {
return NULL;
}
- list = list_alloc();
- list_append_string(list, s, (int)(submatch_match->endp[no] - s));
+ list = tv_list_alloc(1);
+ tv_list_append_string(list, s, (const char *)rsm.sm_match->endp[no] - s);
}
return list;
@@ -7057,6 +7189,19 @@ static void report_re_switch(char_u *pat)
/// @return TRUE if there is a match, FALSE if not.
static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl)
{
+ regexec_T rex_save;
+ bool rex_in_use_save = rex_in_use;
+
+ if (rex_in_use) {
+ // Being called recursively, save the state.
+ rex_save = rex;
+ }
+ rex_in_use = true;
+ rex.reg_startp = NULL;
+ rex.reg_endp = NULL;
+ rex.reg_startpos = NULL;
+ rex.reg_endpos = NULL;
+
int result = rmp->regprog->engine->regexec_nl(rmp, line, col, nl);
// NFA engine aborted because it's very slow, use backtracking engine instead.
@@ -7078,6 +7223,11 @@ static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl)
p_re = save_p_re;
}
+ rex_in_use = rex_in_use_save;
+ if (rex_in_use) {
+ rex = rex_save;
+ }
+
return result > 0;
}
@@ -7107,15 +7257,13 @@ int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col)
return vim_regexec_both(rmp, line, col, true);
}
-/*
- * Match a regexp against multiple lines.
- * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
- * Note: "rmp->regprog" may be freed and changed.
- * Uses curbuf for line count and 'iskeyword'.
- *
- * Return zero if there is no match. Return number of lines contained in the
- * match otherwise.
- */
+/// Match a regexp against multiple lines.
+/// "rmp->regprog" must be a compiled regexp as returned by vim_regcomp().
+/// Note: "rmp->regprog" may be freed and changed, even set to NULL.
+/// Uses curbuf for line count and 'iskeyword'.
+///
+/// Return zero if there is no match. Return number of lines contained in the
+/// match otherwise.
long vim_regexec_multi(
regmmatch_T *rmp,
win_T *win, /* window in which to search or NULL */
@@ -7125,6 +7273,15 @@ long vim_regexec_multi(
proftime_T *tm /* timeout limit or NULL */
)
{
+ regexec_T rex_save;
+ bool rex_in_use_save = rex_in_use;
+
+ if (rex_in_use) {
+ // Being called recursively, save the state.
+ rex_save = rex;
+ }
+ rex_in_use = true;
+
int result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col,
tm);
@@ -7138,7 +7295,12 @@ long vim_regexec_multi(
p_re = BACKTRACKING_ENGINE;
vim_regfree(rmp->regprog);
report_re_switch(pat);
+ // checking for \z misuse was already done when compiling for NFA,
+ // allow all here
+ reg_do_extmatch = REX_ALL;
rmp->regprog = vim_regcomp(pat, re_flags);
+ reg_do_extmatch = 0;
+
if (rmp->regprog != NULL) {
result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col,
tm);
@@ -7148,5 +7310,10 @@ long vim_regexec_multi(
p_re = save_p_re;
}
+ rex_in_use = rex_in_use_save;
+ if (rex_in_use) {
+ rex = rex_save;
+ }
+
return result <= 0 ? 0 : result;
}
diff --git a/src/nvim/regexp.h b/src/nvim/regexp.h
index 37513d8c27..74ed34188c 100644
--- a/src/nvim/regexp.h
+++ b/src/nvim/regexp.h
@@ -1,19 +1,24 @@
#ifndef NVIM_REGEXP_H
#define NVIM_REGEXP_H
-/* Second argument for vim_regcomp(). */
-#define RE_MAGIC 1 /* 'magic' option */
-#define RE_STRING 2 /* match in string instead of buffer text */
-#define RE_STRICT 4 /* don't allow [abc] without ] */
-#define RE_AUTO 8 /* automatic engine selection */
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/regexp_defs.h"
-/* values for reg_do_extmatch */
-#define REX_SET 1 /* to allow \z\(...\), */
-#define REX_USE 2 /* to allow \z\1 et al. */
+// Second argument for vim_regcomp().
+#define RE_MAGIC 1 ///< 'magic' option
+#define RE_STRING 2 ///< match in string instead of buffer text
+#define RE_STRICT 4 ///< don't allow [abc] without ]
+#define RE_AUTO 8 ///< automatic engine selection
-/* regexp.c */
+// values for reg_do_extmatch
+#define REX_SET 1 ///< to allow \z\(...\),
+#define REX_USE 2 ///< to allow \z\1 et al.
+#define REX_ALL (REX_SET | REX_USE)
+
+// regexp.c
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "regexp.h.generated.h"
#endif
-#endif /* NVIM_REGEXP_H */
+#endif // NVIM_REGEXP_H
diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h
index 6426ee441b..b5d56e07fc 100644
--- a/src/nvim/regexp_defs.h
+++ b/src/nvim/regexp_defs.h
@@ -15,6 +15,8 @@
#include <stdbool.h>
#include "nvim/pos.h"
+#include "nvim/types.h"
+#include "nvim/profile.h"
/*
* The number of sub-matches is limited to 10.
@@ -41,18 +43,36 @@
#define NFA_ENGINE 2
typedef struct regengine regengine_T;
+typedef struct regprog regprog_T;
+typedef struct reg_extmatch reg_extmatch_T;
+
+/// Structure to be used for multi-line matching.
+/// Sub-match "no" starts in line "startpos[no].lnum" column "startpos[no].col"
+/// and ends in line "endpos[no].lnum" just before column "endpos[no].col".
+/// The line numbers are relative to the first line, thus startpos[0].lnum is
+/// always 0.
+/// When there is no match, the line number is -1.
+typedef struct {
+ regprog_T *regprog;
+ lpos_T startpos[NSUBEXP];
+ lpos_T endpos[NSUBEXP];
+ int rmm_ic;
+ colnr_T rmm_maxcol; /// when not zero: maximum column
+} regmmatch_T;
+
+#include "nvim/buffer_defs.h"
/*
* Structure returned by vim_regcomp() to pass on to vim_regexec().
* This is the general structure. For the actual matcher, two specific
* structures are used. See code below.
*/
-typedef struct regprog {
+struct regprog {
regengine_T *engine;
unsigned regflags;
unsigned re_engine; ///< Automatic, backtracking or NFA engine.
unsigned re_flags; ///< Second argument for vim_regcomp().
-} regprog_T;
+};
/*
* Structure used by the back track matcher.
@@ -126,30 +146,14 @@ typedef struct {
} regmatch_T;
/*
- * Structure to be used for multi-line matching.
- * Sub-match "no" starts in line "startpos[no].lnum" column "startpos[no].col"
- * and ends in line "endpos[no].lnum" just before column "endpos[no].col".
- * The line numbers are relative to the first line, thus startpos[0].lnum is
- * always 0.
- * When there is no match, the line number is -1.
- */
-typedef struct {
- regprog_T *regprog;
- lpos_T startpos[NSUBEXP];
- lpos_T endpos[NSUBEXP];
- int rmm_ic;
- colnr_T rmm_maxcol; /* when not zero: maximum column */
-} regmmatch_T;
-
-/*
* Structure used to store external references: "\z\(\)" to "\z\1".
* Use a reference count to avoid the need to copy this around. When it goes
* from 1 to zero the matches need to be freed.
*/
-typedef struct {
- short refcnt;
+struct reg_extmatch {
+ int16_t refcnt;
char_u *matches[NSUBEXP];
-} reg_extmatch_T;
+};
struct regengine {
regprog_T *(*regcomp)(char_u*, int);
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index f97dce9e0d..08ef7da9c1 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.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
+
/*
* NFA regular expression implementation.
*
@@ -11,7 +14,6 @@
#include <limits.h>
#include "nvim/ascii.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
/*
@@ -54,13 +56,13 @@ enum {
NFA_RANGE_MIN, /* low end of a range */
NFA_RANGE_MAX, /* high end of a range */
- NFA_CONCAT, /* concatenate two previous items (postfix
- * only) */
- NFA_OR, /* \| (postfix only) */
- NFA_STAR, /* greedy * (posfix only) */
- NFA_STAR_NONGREEDY, /* non-greedy * (postfix only) */
- NFA_QUEST, /* greedy \? (postfix only) */
- NFA_QUEST_NONGREEDY, /* non-greedy \? (postfix only) */
+ NFA_CONCAT, // concatenate two previous items (postfix
+ // only)
+ NFA_OR, // \| (postfix only)
+ NFA_STAR, // greedy * (postfix only)
+ NFA_STAR_NONGREEDY, // non-greedy * (postfix only)
+ NFA_QUEST, // greedy \? (postfix only)
+ NFA_QUEST_NONGREEDY, // non-greedy \? (postfix only)
NFA_BOL, /* ^ Begin line */
NFA_EOL, /* $ End line */
@@ -561,10 +563,7 @@ static char_u *nfa_get_match_text(nfa_state_T *start)
p = start->out->out; /* skip first char, it goes into regstart */
s = ret;
while (p->c > 0) {
- if (has_mbyte)
- s += (*mb_char2bytes)(p->c, s);
- else
- *s++ = p->c;
+ s += utf_char2bytes(p->c, s);
p = p->out;
}
*s = NUL;
@@ -632,6 +631,7 @@ static int nfa_recognize_char_class(char_u *start, char_u *end, int extra_newl)
config |= CLASS_o7;
break;
}
+ return FAIL;
case 'a':
if (*(p + 2) == 'z') {
config |= CLASS_az;
@@ -640,6 +640,7 @@ static int nfa_recognize_char_class(char_u *start, char_u *end, int extra_newl)
config |= CLASS_af;
break;
}
+ return FAIL;
case 'A':
if (*(p + 2) == 'Z') {
config |= CLASS_AZ;
@@ -648,7 +649,7 @@ static int nfa_recognize_char_class(char_u *start, char_u *end, int extra_newl)
config |= CLASS_AF;
break;
}
- /* FALLTHROUGH */
+ return FAIL;
default:
return FAIL;
}
@@ -724,13 +725,70 @@ static void nfa_emit_equi_class(int c)
if (enc_utf8 || STRCMP(p_enc, "latin1") == 0
|| STRCMP(p_enc, "iso-8859-15") == 0) {
+#define A_grave 0xc0
+#define A_acute 0xc1
+#define A_circumflex 0xc2
+#define A_virguilla 0xc3
+#define A_diaeresis 0xc4
+#define A_ring 0xc5
+#define C_cedilla 0xc7
+#define E_grave 0xc8
+#define E_acute 0xc9
+#define E_circumflex 0xca
+#define E_diaeresis 0xcb
+#define I_grave 0xcc
+#define I_acute 0xcd
+#define I_circumflex 0xce
+#define I_diaeresis 0xcf
+#define N_virguilla 0xd1
+#define O_grave 0xd2
+#define O_acute 0xd3
+#define O_circumflex 0xd4
+#define O_virguilla 0xd5
+#define O_diaeresis 0xd6
+#define O_slash 0xd8
+#define U_grave 0xd9
+#define U_acute 0xda
+#define U_circumflex 0xdb
+#define U_diaeresis 0xdc
+#define Y_acute 0xdd
+#define a_grave 0xe0
+#define a_acute 0xe1
+#define a_circumflex 0xe2
+#define a_virguilla 0xe3
+#define a_diaeresis 0xe4
+#define a_ring 0xe5
+#define c_cedilla 0xe7
+#define e_grave 0xe8
+#define e_acute 0xe9
+#define e_circumflex 0xea
+#define e_diaeresis 0xeb
+#define i_grave 0xec
+#define i_acute 0xed
+#define i_circumflex 0xee
+#define i_diaeresis 0xef
+#define n_virguilla 0xf1
+#define o_grave 0xf2
+#define o_acute 0xf3
+#define o_circumflex 0xf4
+#define o_virguilla 0xf5
+#define o_diaeresis 0xf6
+#define o_slash 0xf8
+#define u_grave 0xf9
+#define u_acute 0xfa
+#define u_circumflex 0xfb
+#define u_diaeresis 0xfc
+#define y_acute 0xfd
+#define y_diaeresis 0xff
switch (c) {
- case 'A': case 0300: case 0301: case 0302:
- case 0303: case 0304: case 0305:
- CASEMBC(0x100) CASEMBC(0x102) CASEMBC(0x104) CASEMBC(0x1cd)
- CASEMBC(0x1de) CASEMBC(0x1e0) CASEMBC(0x1ea2)
- EMIT2('A'); EMIT2(0300); EMIT2(0301); EMIT2(0302);
- EMIT2(0303); EMIT2(0304); EMIT2(0305);
+ case 'A': case A_grave: case A_acute: case A_circumflex:
+ case A_virguilla: case A_diaeresis: case A_ring:
+ CASEMBC(0x100) CASEMBC(0x102) CASEMBC(0x104)
+ CASEMBC(0x1cd) CASEMBC(0x1de) CASEMBC(0x1e0)
+ CASEMBC(0x1ea2)
+ EMIT2('A'); EMIT2(A_grave); EMIT2(A_acute);
+ EMIT2(A_circumflex); EMIT2(A_virguilla);
+ EMIT2(A_diaeresis); EMIT2(A_ring);
EMITMBC(0x100) EMITMBC(0x102) EMITMBC(0x104)
EMITMBC(0x1cd) EMITMBC(0x1de) EMITMBC(0x1e0)
EMITMBC(0x1ea2)
@@ -740,23 +798,24 @@ static void nfa_emit_equi_class(int c)
EMIT2('B'); EMITMBC(0x1e02) EMITMBC(0x1e06)
return;
- case 'C': case 0307:
- CASEMBC(0x106) CASEMBC(0x108) CASEMBC(0x10a) CASEMBC(0x10c)
- EMIT2('C'); EMIT2(0307); EMITMBC(0x106) EMITMBC(0x108)
+ case 'C': case C_cedilla: CASEMBC(0x106) CASEMBC(0x108) CASEMBC(0x10a)
+ CASEMBC(0x10c)
+ EMIT2('C'); EMIT2(C_cedilla); EMITMBC(0x106) EMITMBC(0x108)
EMITMBC(0x10a) EMITMBC(0x10c)
return;
case 'D': CASEMBC(0x10e) CASEMBC(0x110) CASEMBC(0x1e0a)
- CASEMBC(0x1e0e) CASEMBC(0x1e10)
+ CASEMBC(0x1e0e) CASEMBC(0x1e10)
EMIT2('D'); EMITMBC(0x10e) EMITMBC(0x110) EMITMBC(0x1e0a)
EMITMBC(0x1e0e) EMITMBC(0x1e10)
return;
- case 'E': case 0310: case 0311: case 0312: case 0313:
- CASEMBC(0x112) CASEMBC(0x114) CASEMBC(0x116) CASEMBC(0x118)
- CASEMBC(0x11a) CASEMBC(0x1eba) CASEMBC(0x1ebc)
- EMIT2('E'); EMIT2(0310); EMIT2(0311); EMIT2(0312);
- EMIT2(0313);
+ case 'E': case E_grave: case E_acute: case E_circumflex:
+ case E_diaeresis: CASEMBC(0x112) CASEMBC(0x114)
+ CASEMBC(0x116) CASEMBC(0x118) CASEMBC(0x11a)
+ CASEMBC(0x1eba) CASEMBC(0x1ebc)
+ EMIT2('E'); EMIT2(E_grave); EMIT2(E_acute);
+ EMIT2(E_circumflex); EMIT2(E_diaeresis);
EMITMBC(0x112) EMITMBC(0x114) EMITMBC(0x116)
EMITMBC(0x118) EMITMBC(0x11a) EMITMBC(0x1eba)
EMITMBC(0x1ebc)
@@ -767,24 +826,26 @@ static void nfa_emit_equi_class(int c)
return;
case 'G': CASEMBC(0x11c) CASEMBC(0x11e) CASEMBC(0x120)
- CASEMBC(0x122) CASEMBC(0x1e4) CASEMBC(0x1e6) CASEMBC(0x1f4)
- CASEMBC(0x1e20)
+ CASEMBC(0x122) CASEMBC(0x1e4) CASEMBC(0x1e6)
+ CASEMBC(0x1f4) CASEMBC(0x1e20)
EMIT2('G'); EMITMBC(0x11c) EMITMBC(0x11e) EMITMBC(0x120)
EMITMBC(0x122) EMITMBC(0x1e4) EMITMBC(0x1e6)
EMITMBC(0x1f4) EMITMBC(0x1e20)
return;
case 'H': CASEMBC(0x124) CASEMBC(0x126) CASEMBC(0x1e22)
- CASEMBC(0x1e26) CASEMBC(0x1e28)
+ CASEMBC(0x1e26) CASEMBC(0x1e28)
EMIT2('H'); EMITMBC(0x124) EMITMBC(0x126) EMITMBC(0x1e22)
EMITMBC(0x1e26) EMITMBC(0x1e28)
return;
- case 'I': case 0314: case 0315: case 0316: case 0317:
- CASEMBC(0x128) CASEMBC(0x12a) CASEMBC(0x12c) CASEMBC(0x12e)
- CASEMBC(0x130) CASEMBC(0x1cf) CASEMBC(0x1ec8)
- EMIT2('I'); EMIT2(0314); EMIT2(0315); EMIT2(0316);
- EMIT2(0317); EMITMBC(0x128) EMITMBC(0x12a)
+ case 'I': case I_grave: case I_acute: case I_circumflex:
+ case I_diaeresis: CASEMBC(0x128) CASEMBC(0x12a)
+ CASEMBC(0x12c) CASEMBC(0x12e) CASEMBC(0x130)
+ CASEMBC(0x1cf) CASEMBC(0x1ec8)
+ EMIT2('I'); EMIT2(I_grave); EMIT2(I_acute);
+ EMIT2(I_circumflex); EMIT2(I_diaeresis);
+ EMITMBC(0x128) EMITMBC(0x12a)
EMITMBC(0x12c) EMITMBC(0x12e) EMITMBC(0x130)
EMITMBC(0x1cf) EMITMBC(0x1ec8)
return;
@@ -794,13 +855,13 @@ static void nfa_emit_equi_class(int c)
return;
case 'K': CASEMBC(0x136) CASEMBC(0x1e8) CASEMBC(0x1e30)
- CASEMBC(0x1e34)
+ CASEMBC(0x1e34)
EMIT2('K'); EMITMBC(0x136) EMITMBC(0x1e8) EMITMBC(0x1e30)
EMITMBC(0x1e34)
return;
case 'L': CASEMBC(0x139) CASEMBC(0x13b) CASEMBC(0x13d)
- CASEMBC(0x13f) CASEMBC(0x141) CASEMBC(0x1e3a)
+ CASEMBC(0x13f) CASEMBC(0x141) CASEMBC(0x1e3a)
EMIT2('L'); EMITMBC(0x139) EMITMBC(0x13b) EMITMBC(0x13d)
EMITMBC(0x13f) EMITMBC(0x141) EMITMBC(0x1e3a)
return;
@@ -809,19 +870,21 @@ static void nfa_emit_equi_class(int c)
EMIT2('M'); EMITMBC(0x1e3e) EMITMBC(0x1e40)
return;
- case 'N': case 0321:
- CASEMBC(0x143) CASEMBC(0x145) CASEMBC(0x147) CASEMBC(0x1e44)
- CASEMBC(0x1e48)
- EMIT2('N'); EMIT2(0321); EMITMBC(0x143) EMITMBC(0x145)
+ case 'N': case N_virguilla: CASEMBC(0x143) CASEMBC(0x145)
+ CASEMBC(0x147) CASEMBC(0x1e44) CASEMBC(0x1e48)
+ EMIT2('N'); EMIT2(N_virguilla);
+ EMITMBC(0x143) EMITMBC(0x145)
EMITMBC(0x147) EMITMBC(0x1e44) EMITMBC(0x1e48)
return;
- case 'O': case 0322: case 0323: case 0324: case 0325:
- case 0326: case 0330:
- CASEMBC(0x14c) CASEMBC(0x14e) CASEMBC(0x150) CASEMBC(0x1a0)
- CASEMBC(0x1d1) CASEMBC(0x1ea) CASEMBC(0x1ec) CASEMBC(0x1ece)
- EMIT2('O'); EMIT2(0322); EMIT2(0323); EMIT2(0324);
- EMIT2(0325); EMIT2(0326); EMIT2(0330);
+ case 'O': case O_grave: case O_acute: case O_circumflex:
+ case O_virguilla: case O_diaeresis: case O_slash:
+ CASEMBC(0x14c) CASEMBC(0x14e) CASEMBC(0x150)
+ CASEMBC(0x1a0) CASEMBC(0x1d1) CASEMBC(0x1ea)
+ CASEMBC(0x1ec) CASEMBC(0x1ece)
+ EMIT2('O'); EMIT2(O_grave); EMIT2(O_acute);
+ EMIT2(O_circumflex); EMIT2(O_virguilla);
+ EMIT2(O_diaeresis); EMIT2(O_slash);
EMITMBC(0x14c) EMITMBC(0x14e) EMITMBC(0x150)
EMITMBC(0x1a0) EMITMBC(0x1d1) EMITMBC(0x1ea)
EMITMBC(0x1ec) EMITMBC(0x1ece)
@@ -832,29 +895,31 @@ static void nfa_emit_equi_class(int c)
return;
case 'R': CASEMBC(0x154) CASEMBC(0x156) CASEMBC(0x158)
- CASEMBC(0x1e58) CASEMBC(0x1e5e)
+ CASEMBC(0x1e58) CASEMBC(0x1e5e)
EMIT2('R'); EMITMBC(0x154) EMITMBC(0x156) EMITMBC(0x158)
EMITMBC(0x1e58) EMITMBC(0x1e5e)
return;
case 'S': CASEMBC(0x15a) CASEMBC(0x15c) CASEMBC(0x15e)
- CASEMBC(0x160) CASEMBC(0x1e60)
+ CASEMBC(0x160) CASEMBC(0x1e60)
EMIT2('S'); EMITMBC(0x15a) EMITMBC(0x15c) EMITMBC(0x15e)
EMITMBC(0x160) EMITMBC(0x1e60)
return;
case 'T': CASEMBC(0x162) CASEMBC(0x164) CASEMBC(0x166)
- CASEMBC(0x1e6a) CASEMBC(0x1e6e)
+ CASEMBC(0x1e6a) CASEMBC(0x1e6e)
EMIT2('T'); EMITMBC(0x162) EMITMBC(0x164) EMITMBC(0x166)
EMITMBC(0x1e6a) EMITMBC(0x1e6e)
return;
- case 'U': case 0331: case 0332: case 0333: case 0334:
- CASEMBC(0x168) CASEMBC(0x16a) CASEMBC(0x16c) CASEMBC(0x16e)
- CASEMBC(0x170) CASEMBC(0x172) CASEMBC(0x1af) CASEMBC(0x1d3)
- CASEMBC(0x1ee6)
- EMIT2('U'); EMIT2(0331); EMIT2(0332); EMIT2(0333);
- EMIT2(0334); EMITMBC(0x168) EMITMBC(0x16a)
+ case 'U': case U_grave: case U_acute: case U_diaeresis:
+ case U_circumflex: CASEMBC(0x168) CASEMBC(0x16a)
+ CASEMBC(0x16c) CASEMBC(0x16e) CASEMBC(0x170)
+ CASEMBC(0x172) CASEMBC(0x1af) CASEMBC(0x1d3)
+ CASEMBC(0x1ee6)
+ EMIT2('U'); EMIT2(U_grave); EMIT2(U_acute);
+ EMIT2(U_diaeresis); EMIT2(U_circumflex);
+ EMITMBC(0x168) EMITMBC(0x16a)
EMITMBC(0x16c) EMITMBC(0x16e) EMITMBC(0x170)
EMITMBC(0x172) EMITMBC(0x1af) EMITMBC(0x1d3)
EMITMBC(0x1ee6)
@@ -865,7 +930,7 @@ static void nfa_emit_equi_class(int c)
return;
case 'W': CASEMBC(0x174) CASEMBC(0x1e80) CASEMBC(0x1e82)
- CASEMBC(0x1e84) CASEMBC(0x1e86)
+ CASEMBC(0x1e84) CASEMBC(0x1e86)
EMIT2('W'); EMITMBC(0x174) EMITMBC(0x1e80) EMITMBC(0x1e82)
EMITMBC(0x1e84) EMITMBC(0x1e86)
return;
@@ -874,26 +939,29 @@ static void nfa_emit_equi_class(int c)
EMIT2('X'); EMITMBC(0x1e8a) EMITMBC(0x1e8c)
return;
- case 'Y': case 0335:
- CASEMBC(0x176) CASEMBC(0x178) CASEMBC(0x1e8e) CASEMBC(0x1ef2)
- CASEMBC(0x1ef6) CASEMBC(0x1ef8)
- EMIT2('Y'); EMIT2(0335); EMITMBC(0x176) EMITMBC(0x178)
+ case 'Y': case Y_acute: CASEMBC(0x176) CASEMBC(0x178)
+ CASEMBC(0x1e8e) CASEMBC(0x1ef2) CASEMBC(0x1ef6)
+ CASEMBC(0x1ef8)
+ EMIT2('Y'); EMIT2(Y_acute);
+ EMITMBC(0x176) EMITMBC(0x178)
EMITMBC(0x1e8e) EMITMBC(0x1ef2) EMITMBC(0x1ef6)
EMITMBC(0x1ef8)
return;
case 'Z': CASEMBC(0x179) CASEMBC(0x17b) CASEMBC(0x17d)
- CASEMBC(0x1b5) CASEMBC(0x1e90) CASEMBC(0x1e94)
+ CASEMBC(0x1b5) CASEMBC(0x1e90) CASEMBC(0x1e94)
EMIT2('Z'); EMITMBC(0x179) EMITMBC(0x17b) EMITMBC(0x17d)
EMITMBC(0x1b5) EMITMBC(0x1e90) EMITMBC(0x1e94)
return;
- case 'a': case 0340: case 0341: case 0342:
- case 0343: case 0344: case 0345:
- CASEMBC(0x101) CASEMBC(0x103) CASEMBC(0x105) CASEMBC(0x1ce)
- CASEMBC(0x1df) CASEMBC(0x1e1) CASEMBC(0x1ea3)
- EMIT2('a'); EMIT2(0340); EMIT2(0341); EMIT2(0342);
- EMIT2(0343); EMIT2(0344); EMIT2(0345);
+ case 'a': case a_grave: case a_acute: case a_circumflex:
+ case a_virguilla: case a_diaeresis: case a_ring:
+ CASEMBC(0x101) CASEMBC(0x103) CASEMBC(0x105)
+ CASEMBC(0x1ce) CASEMBC(0x1df) CASEMBC(0x1e1)
+ CASEMBC(0x1ea3)
+ EMIT2('a'); EMIT2(a_grave); EMIT2(a_acute);
+ EMIT2(a_circumflex); EMIT2(a_virguilla);
+ EMIT2(a_diaeresis); EMIT2(a_ring);
EMITMBC(0x101) EMITMBC(0x103) EMITMBC(0x105)
EMITMBC(0x1ce) EMITMBC(0x1df) EMITMBC(0x1e1)
EMITMBC(0x1ea3)
@@ -903,23 +971,26 @@ static void nfa_emit_equi_class(int c)
EMIT2('b'); EMITMBC(0x1e03) EMITMBC(0x1e07)
return;
- case 'c': case 0347:
- CASEMBC(0x107) CASEMBC(0x109) CASEMBC(0x10b) CASEMBC(0x10d)
- EMIT2('c'); EMIT2(0347); EMITMBC(0x107) EMITMBC(0x109)
+ case 'c': case c_cedilla: CASEMBC(0x107) CASEMBC(0x109)
+ CASEMBC(0x10b) CASEMBC(0x10d)
+ EMIT2('c'); EMIT2(c_cedilla);
+ EMITMBC(0x107) EMITMBC(0x109)
EMITMBC(0x10b) EMITMBC(0x10d)
return;
case 'd': CASEMBC(0x10f) CASEMBC(0x111) CASEMBC(0x1e0b)
- CASEMBC(0x1e0f) CASEMBC(0x1e11)
+ CASEMBC(0x1e0f) CASEMBC(0x1e11)
EMIT2('d'); EMITMBC(0x10f) EMITMBC(0x111) EMITMBC(0x1e0b)
EMITMBC(0x1e0f) EMITMBC(0x1e11)
return;
- case 'e': case 0350: case 0351: case 0352: case 0353:
- CASEMBC(0x113) CASEMBC(0x115) CASEMBC(0x117) CASEMBC(0x119)
- CASEMBC(0x11b) CASEMBC(0x1ebb) CASEMBC(0x1ebd)
- EMIT2('e'); EMIT2(0350); EMIT2(0351); EMIT2(0352);
- EMIT2(0353); EMITMBC(0x113) EMITMBC(0x115)
+ case 'e': case e_grave: case e_acute: case e_circumflex:
+ case e_diaeresis: CASEMBC(0x113) CASEMBC(0x115)
+ CASEMBC(0x117) CASEMBC(0x119) CASEMBC(0x11b)
+ CASEMBC(0x1ebb) CASEMBC(0x1ebd)
+ EMIT2('e'); EMIT2(e_grave); EMIT2(e_acute);
+ EMIT2(e_circumflex); EMIT2(e_diaeresis);
+ EMITMBC(0x113) EMITMBC(0x115)
EMITMBC(0x117) EMITMBC(0x119) EMITMBC(0x11b)
EMITMBC(0x1ebb) EMITMBC(0x1ebd)
return;
@@ -929,24 +1000,26 @@ static void nfa_emit_equi_class(int c)
return;
case 'g': CASEMBC(0x11d) CASEMBC(0x11f) CASEMBC(0x121)
- CASEMBC(0x123) CASEMBC(0x1e5) CASEMBC(0x1e7) CASEMBC(0x1f5)
- CASEMBC(0x1e21)
+ CASEMBC(0x123) CASEMBC(0x1e5) CASEMBC(0x1e7)
+ CASEMBC(0x1f5) CASEMBC(0x1e21)
EMIT2('g'); EMITMBC(0x11d) EMITMBC(0x11f) EMITMBC(0x121)
EMITMBC(0x123) EMITMBC(0x1e5) EMITMBC(0x1e7)
EMITMBC(0x1f5) EMITMBC(0x1e21)
return;
case 'h': CASEMBC(0x125) CASEMBC(0x127) CASEMBC(0x1e23)
- CASEMBC(0x1e27) CASEMBC(0x1e29) CASEMBC(0x1e96)
+ CASEMBC(0x1e27) CASEMBC(0x1e29) CASEMBC(0x1e96)
EMIT2('h'); EMITMBC(0x125) EMITMBC(0x127) EMITMBC(0x1e23)
EMITMBC(0x1e27) EMITMBC(0x1e29) EMITMBC(0x1e96)
return;
- case 'i': case 0354: case 0355: case 0356: case 0357:
- CASEMBC(0x129) CASEMBC(0x12b) CASEMBC(0x12d) CASEMBC(0x12f)
- CASEMBC(0x1d0) CASEMBC(0x1ec9)
- EMIT2('i'); EMIT2(0354); EMIT2(0355); EMIT2(0356);
- EMIT2(0357); EMITMBC(0x129) EMITMBC(0x12b)
+ case 'i': case i_grave: case i_acute: case i_circumflex:
+ case i_diaeresis: CASEMBC(0x129) CASEMBC(0x12b)
+ CASEMBC(0x12d) CASEMBC(0x12f) CASEMBC(0x1d0)
+ CASEMBC(0x1ec9)
+ EMIT2('i'); EMIT2(i_grave); EMIT2(i_acute);
+ EMIT2(i_circumflex); EMIT2(i_diaeresis);
+ EMITMBC(0x129) EMITMBC(0x12b)
EMITMBC(0x12d) EMITMBC(0x12f) EMITMBC(0x1d0)
EMITMBC(0x1ec9)
return;
@@ -956,13 +1029,13 @@ static void nfa_emit_equi_class(int c)
return;
case 'k': CASEMBC(0x137) CASEMBC(0x1e9) CASEMBC(0x1e31)
- CASEMBC(0x1e35)
+ CASEMBC(0x1e35)
EMIT2('k'); EMITMBC(0x137) EMITMBC(0x1e9) EMITMBC(0x1e31)
EMITMBC(0x1e35)
return;
case 'l': CASEMBC(0x13a) CASEMBC(0x13c) CASEMBC(0x13e)
- CASEMBC(0x140) CASEMBC(0x142) CASEMBC(0x1e3b)
+ CASEMBC(0x140) CASEMBC(0x142) CASEMBC(0x1e3b)
EMIT2('l'); EMITMBC(0x13a) EMITMBC(0x13c) EMITMBC(0x13e)
EMITMBC(0x140) EMITMBC(0x142) EMITMBC(0x1e3b)
return;
@@ -971,20 +1044,23 @@ static void nfa_emit_equi_class(int c)
EMIT2('m'); EMITMBC(0x1e3f) EMITMBC(0x1e41)
return;
- case 'n': case 0361:
- CASEMBC(0x144) CASEMBC(0x146) CASEMBC(0x148) CASEMBC(0x149)
- CASEMBC(0x1e45) CASEMBC(0x1e49)
- EMIT2('n'); EMIT2(0361); EMITMBC(0x144) EMITMBC(0x146)
+ case 'n': case n_virguilla: CASEMBC(0x144) CASEMBC(0x146)
+ CASEMBC(0x148) CASEMBC(0x149) CASEMBC(0x1e45)
+ CASEMBC(0x1e49)
+ EMIT2('n'); EMIT2(n_virguilla);
+ EMITMBC(0x144) EMITMBC(0x146)
EMITMBC(0x148) EMITMBC(0x149) EMITMBC(0x1e45)
EMITMBC(0x1e49)
return;
- case 'o': case 0362: case 0363: case 0364: case 0365:
- case 0366: case 0370:
- CASEMBC(0x14d) CASEMBC(0x14f) CASEMBC(0x151) CASEMBC(0x1a1)
- CASEMBC(0x1d2) CASEMBC(0x1eb) CASEMBC(0x1ed) CASEMBC(0x1ecf)
- EMIT2('o'); EMIT2(0362); EMIT2(0363); EMIT2(0364);
- EMIT2(0365); EMIT2(0366); EMIT2(0370);
+ case 'o': case o_grave: case o_acute: case o_circumflex:
+ case o_virguilla: case o_diaeresis: case o_slash:
+ CASEMBC(0x14d) CASEMBC(0x14f) CASEMBC(0x151)
+ CASEMBC(0x1a1) CASEMBC(0x1d2) CASEMBC(0x1eb)
+ CASEMBC(0x1ed) CASEMBC(0x1ecf)
+ EMIT2('o'); EMIT2(o_grave); EMIT2(o_acute);
+ EMIT2(o_circumflex); EMIT2(o_virguilla);
+ EMIT2(o_diaeresis); EMIT2(o_slash);
EMITMBC(0x14d) EMITMBC(0x14f) EMITMBC(0x151)
EMITMBC(0x1a1) EMITMBC(0x1d2) EMITMBC(0x1eb)
EMITMBC(0x1ed) EMITMBC(0x1ecf)
@@ -995,29 +1071,31 @@ static void nfa_emit_equi_class(int c)
return;
case 'r': CASEMBC(0x155) CASEMBC(0x157) CASEMBC(0x159)
- CASEMBC(0x1e59) CASEMBC(0x1e5f)
+ CASEMBC(0x1e59) CASEMBC(0x1e5f)
EMIT2('r'); EMITMBC(0x155) EMITMBC(0x157) EMITMBC(0x159)
EMITMBC(0x1e59) EMITMBC(0x1e5f)
return;
case 's': CASEMBC(0x15b) CASEMBC(0x15d) CASEMBC(0x15f)
- CASEMBC(0x161) CASEMBC(0x1e61)
+ CASEMBC(0x161) CASEMBC(0x1e61)
EMIT2('s'); EMITMBC(0x15b) EMITMBC(0x15d) EMITMBC(0x15f)
EMITMBC(0x161) EMITMBC(0x1e61)
return;
case 't': CASEMBC(0x163) CASEMBC(0x165) CASEMBC(0x167)
- CASEMBC(0x1e6b) CASEMBC(0x1e6f) CASEMBC(0x1e97)
+ CASEMBC(0x1e6b) CASEMBC(0x1e6f) CASEMBC(0x1e97)
EMIT2('t'); EMITMBC(0x163) EMITMBC(0x165) EMITMBC(0x167)
EMITMBC(0x1e6b) EMITMBC(0x1e6f) EMITMBC(0x1e97)
return;
- case 'u': case 0371: case 0372: case 0373: case 0374:
- CASEMBC(0x169) CASEMBC(0x16b) CASEMBC(0x16d) CASEMBC(0x16f)
- CASEMBC(0x171) CASEMBC(0x173) CASEMBC(0x1b0) CASEMBC(0x1d4)
- CASEMBC(0x1ee7)
- EMIT2('u'); EMIT2(0371); EMIT2(0372); EMIT2(0373);
- EMIT2(0374); EMITMBC(0x169) EMITMBC(0x16b)
+ case 'u': case u_grave: case u_acute: case u_circumflex:
+ case u_diaeresis: CASEMBC(0x169) CASEMBC(0x16b)
+ CASEMBC(0x16d) CASEMBC(0x16f) CASEMBC(0x171)
+ CASEMBC(0x173) CASEMBC(0x1b0) CASEMBC(0x1d4)
+ CASEMBC(0x1ee7)
+ EMIT2('u'); EMIT2(u_grave); EMIT2(u_acute);
+ EMIT2(u_circumflex); EMIT2(u_diaeresis);
+ EMITMBC(0x169) EMITMBC(0x16b)
EMITMBC(0x16d) EMITMBC(0x16f) EMITMBC(0x171)
EMITMBC(0x173) EMITMBC(0x1b0) EMITMBC(0x1d4)
EMITMBC(0x1ee7)
@@ -1028,7 +1106,7 @@ static void nfa_emit_equi_class(int c)
return;
case 'w': CASEMBC(0x175) CASEMBC(0x1e81) CASEMBC(0x1e83)
- CASEMBC(0x1e85) CASEMBC(0x1e87) CASEMBC(0x1e98)
+ CASEMBC(0x1e85) CASEMBC(0x1e87) CASEMBC(0x1e98)
EMIT2('w'); EMITMBC(0x175) EMITMBC(0x1e81) EMITMBC(0x1e83)
EMITMBC(0x1e85) EMITMBC(0x1e87) EMITMBC(0x1e98)
return;
@@ -1037,16 +1115,17 @@ static void nfa_emit_equi_class(int c)
EMIT2('x'); EMITMBC(0x1e8b) EMITMBC(0x1e8d)
return;
- case 'y': case 0375: case 0377:
- CASEMBC(0x177) CASEMBC(0x1e8f) CASEMBC(0x1e99)
- CASEMBC(0x1ef3) CASEMBC(0x1ef7) CASEMBC(0x1ef9)
- EMIT2('y'); EMIT2(0375); EMIT2(0377); EMITMBC(0x177)
+ case 'y': case y_acute: case y_diaeresis: CASEMBC(0x177)
+ CASEMBC(0x1e8f) CASEMBC(0x1e99) CASEMBC(0x1ef3)
+ CASEMBC(0x1ef7) CASEMBC(0x1ef9)
+ EMIT2('y'); EMIT2(y_acute); EMIT2(y_diaeresis);
+ EMITMBC(0x177)
EMITMBC(0x1e8f) EMITMBC(0x1e99) EMITMBC(0x1ef3)
EMITMBC(0x1ef7) EMITMBC(0x1ef9)
return;
case 'z': CASEMBC(0x17a) CASEMBC(0x17c) CASEMBC(0x17e)
- CASEMBC(0x1b6) CASEMBC(0x1e91) CASEMBC(0x1e95)
+ CASEMBC(0x1b6) CASEMBC(0x1e91) CASEMBC(0x1e95)
EMIT2('z'); EMITMBC(0x17a) EMITMBC(0x17c) EMITMBC(0x17e)
EMITMBC(0x1b6) EMITMBC(0x1e91) EMITMBC(0x1e95)
return;
@@ -1096,6 +1175,7 @@ static int nfa_regatom(void)
int startc = -1;
int endc = -1;
int oldstartc = -1;
+ int save_prev_at_start = prev_at_start;
c = getchr();
switch (c) {
@@ -1140,8 +1220,8 @@ static int nfa_regatom(void)
if (c == '[')
goto collection;
- /* "\_x" is character class plus newline */
- /*FALLTHROUGH*/
+ // "\_x" is character class plus newline
+ FALLTHROUGH;
/*
* Character classes.
@@ -1180,7 +1260,7 @@ static int nfa_regatom(void)
rc_did_emsg = TRUE;
return FAIL;
}
- EMSGN("INTERNAL: Unknown character class char: %" PRId64, c);
+ IEMSGN("INTERNAL: Unknown character class char: %" PRId64, c);
return FAIL;
}
/* When '.' is followed by a composing char ignore the dot, so that
@@ -1240,7 +1320,7 @@ static int nfa_regatom(void)
EMSG(_(e_nopresub));
return FAIL;
}
- for (lp = reg_prev_sub; *lp != NUL; mb_cptr_adv(lp)) {
+ for (lp = reg_prev_sub; *lp != NUL; MB_CPTR_ADV(lp)) {
EMIT(PTR2CHAR(lp));
if (lp != reg_prev_sub)
EMIT(NFA_CONCAT);
@@ -1287,25 +1367,28 @@ static int nfa_regatom(void)
case '7':
case '8':
case '9':
- /* \z1...\z9 */
- if (reg_do_extmatch != REX_USE)
+ // \z1...\z9
+ if ((reg_do_extmatch & REX_USE) == 0) {
EMSG_RET_FAIL(_(e_z1_not_allowed));
+ }
EMIT(NFA_ZREF1 + (no_Magic(c) - '1'));
/* No need to set nfa_has_backref, the sub-matches don't
* change when \z1 .. \z9 matches or not. */
re_has_z = REX_USE;
break;
case '(':
- /* \z( */
- if (reg_do_extmatch != REX_SET)
+ // \z(
+ if (reg_do_extmatch != REX_SET) {
EMSG_RET_FAIL(_(e_z_not_allowed));
- if (nfa_reg(REG_ZPAREN) == FAIL)
- return FAIL; /* cascaded error */
+ }
+ if (nfa_reg(REG_ZPAREN) == FAIL) {
+ return FAIL; // cascaded error
+ }
re_has_z = REX_SET;
break;
default:
- EMSGN(_("E867: (NFA) Unknown operator '\\z%c'"),
- no_Magic(c));
+ emsgf(_("E867: (NFA) Unknown operator '\\z%c'"),
+ no_Magic(c));
return FAIL;
}
break;
@@ -1326,7 +1409,7 @@ static int nfa_regatom(void)
case 'u': /* %uabcd hex 4 */
case 'U': /* %U1234abcd hex 8 */
{
- int nr;
+ int64_t nr;
switch (c) {
case 'd': nr = getdecchrs(); break;
@@ -1402,7 +1485,7 @@ static int nfa_regatom(void)
default:
{
- int n = 0;
+ long n = 0;
int cmp = c;
if (c == '<' || c == '>')
@@ -1412,19 +1495,29 @@ static int nfa_regatom(void)
c = getchr();
}
if (c == 'l' || c == 'c' || c == 'v') {
- if (c == 'l')
- /* \%{n}l \%{n}<l \%{n}>l */
+ if (c == 'l') {
+ // \%{n}l \%{n}<l \%{n}>l
EMIT(cmp == '<' ? NFA_LNUM_LT :
- cmp == '>' ? NFA_LNUM_GT : NFA_LNUM);
- else if (c == 'c')
- /* \%{n}c \%{n}<c \%{n}>c */
+ cmp == '>' ? NFA_LNUM_GT : NFA_LNUM);
+ if (save_prev_at_start) {
+ at_start = true;
+ }
+ } else if (c == 'c') {
+ // \%{n}c \%{n}<c \%{n}>c
EMIT(cmp == '<' ? NFA_COL_LT :
- cmp == '>' ? NFA_COL_GT : NFA_COL);
- else
- /* \%{n}v \%{n}<v \%{n}>v */
+ cmp == '>' ? NFA_COL_GT : NFA_COL);
+ } else {
+ // \%{n}v \%{n}<v \%{n}>v
EMIT(cmp == '<' ? NFA_VCOL_LT :
- cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
- EMIT(n);
+ cmp == '>' ? NFA_VCOL_GT : NFA_VCOL);
+ }
+#if SIZEOF_INT < SIZEOF_LONG
+ if (n > INT_MAX) {
+ EMSG(_("E951: \\% value too large"));
+ return FAIL;
+ }
+#endif
+ EMIT((int)n);
break;
} else if (c == '\'' && n == 0) {
/* \%'m \%<'m \%>'m */
@@ -1434,8 +1527,8 @@ static int nfa_regatom(void)
break;
}
}
- EMSGN(_("E867: (NFA) Unknown operator '\\%%%c'"),
- no_Magic(c));
+ emsgf(_("E867: (NFA) Unknown operator '\\%%%c'"),
+ no_Magic(c));
return FAIL;
}
break;
@@ -1470,7 +1563,7 @@ collection:
} else
EMIT(result);
regparse = endp;
- mb_ptr_adv(regparse);
+ MB_PTR_ADV(regparse);
return OK;
}
/*
@@ -1478,10 +1571,10 @@ collection:
* version that turns [abc] into 'a' OR 'b' OR 'c'
*/
startc = endc = oldstartc = -1;
- negated = FALSE;
- if (*regparse == '^') { /* negated range */
- negated = TRUE;
- mb_ptr_adv(regparse);
+ negated = false;
+ if (*regparse == '^') { // negated range
+ negated = true;
+ MB_PTR_ADV(regparse);
EMIT(NFA_START_NEG_COLL);
} else
EMIT(NFA_START_COLL);
@@ -1489,7 +1582,7 @@ collection:
startc = '-';
EMIT(startc);
EMIT(NFA_CONCAT);
- mb_ptr_adv(regparse);
+ MB_PTR_ADV(regparse);
}
/* Emit the OR branches for each character in the [] */
emit_range = FALSE;
@@ -1579,8 +1672,8 @@ collection:
if (*regparse == '-' && oldstartc != -1) {
emit_range = TRUE;
startc = oldstartc;
- mb_ptr_adv(regparse);
- continue; /* reading the end of the range */
+ MB_PTR_ADV(regparse);
+ continue; // reading the end of the range
}
/* Now handle simple and escaped characters.
@@ -1596,7 +1689,7 @@ collection:
!= NULL)
)
) {
- mb_ptr_adv(regparse);
+ MB_PTR_ADV(regparse);
if (*regparse == 'n')
startc = reg_string ? NL : NFA_NEWL;
@@ -1608,8 +1701,8 @@ collection:
) {
/* TODO(RE) This needs more testing */
startc = coll_get_char();
- got_coll_char = TRUE;
- mb_ptr_back(old_regparse, regparse);
+ got_coll_char = true;
+ MB_PTR_BACK(old_regparse, regparse);
} else {
/* \r,\t,\e,\b */
startc = backslash_trans(*regparse);
@@ -1624,8 +1717,9 @@ collection:
if (emit_range) {
endc = startc;
startc = oldstartc;
- if (startc > endc)
- EMSG_RET_FAIL(_(e_invrange));
+ if (startc > endc) {
+ EMSG_RET_FAIL(_(e_reverse_range));
+ }
if (endc > startc + 2) {
/* Emit a range instead of the sequence of
@@ -1680,18 +1774,18 @@ collection:
}
}
- mb_ptr_adv(regparse);
- } /* while (p < endp) */
+ MB_PTR_ADV(regparse);
+ } // while (p < endp)
- mb_ptr_back(old_regparse, regparse);
- if (*regparse == '-') { /* if last, '-' is just a char */
+ MB_PTR_BACK(old_regparse, regparse);
+ if (*regparse == '-') { // if last, '-' is just a char
EMIT('-');
EMIT(NFA_CONCAT);
}
/* skip the trailing ] */
regparse = endp;
- mb_ptr_adv(regparse);
+ MB_PTR_ADV(regparse);
/* Mark end of the collection. */
if (negated == TRUE)
@@ -1710,16 +1804,16 @@ collection:
if (reg_strict)
EMSG_RET_FAIL(_(e_missingbracket));
- /* FALLTHROUGH */
+ FALLTHROUGH;
default:
{
int plen;
nfa_do_multibyte:
- /* plen is length of current char with composing chars */
+ // plen is length of current char with composing chars
if (enc_utf8 && ((*mb_char2len)(c)
- != (plen = (*mb_ptr2len)(old_regparse))
+ != (plen = utfc_ptr2len(old_regparse))
|| utf_iscomposing(c))) {
int i = 0;
@@ -1771,7 +1865,7 @@ static int nfa_regpiece(void)
int greedy = TRUE; /* Braces are prefixed with '-' ? */
parse_state_T old_state;
parse_state_T new_state;
- int c2;
+ int64_t c2;
int old_post_pos;
int my_post_start;
int quest;
@@ -1846,7 +1940,7 @@ static int nfa_regpiece(void)
break;
}
if (i == 0) {
- EMSGN(_("E869: (NFA) Unknown operator '\\@%c'"), op);
+ emsgf(_("E869: (NFA) Unknown operator '\\@%c'"), op);
return FAIL;
}
EMIT(i);
@@ -1901,7 +1995,7 @@ static int nfa_regpiece(void)
// The engine is very inefficient (uses too many states) when the maximum
// is much larger than the minimum and when the maximum is large. Bail out
// if we can use the other engine.
- if ((nfa_re_flags & RE_AUTO) && (maxval > minval + 200 || maxval > 500)) {
+ if ((nfa_re_flags & RE_AUTO) && (maxval > 500 || maxval > minval + 200)) {
return FAIL;
}
@@ -1944,9 +2038,10 @@ static int nfa_regpiece(void)
break;
} /* end switch */
- if (re_multi_type(peekchr()) != NOT_MULTI)
- /* Can't have a multi follow a multi. */
- EMSG_RET_FAIL(_("E871: (NFA regexp) Can't have a multi follow a multi !"));
+ if (re_multi_type(peekchr()) != NOT_MULTI) {
+ // Can't have a multi follow a multi.
+ EMSG_RET_FAIL(_("E871: (NFA regexp) Can't have a multi follow a multi"));
+ }
return OK;
}
@@ -2036,7 +2131,6 @@ static int nfa_regconcat(void)
*/
static int nfa_regbranch(void)
{
- int ch;
int old_post_pos;
old_post_pos = (int)(post_ptr - post_start);
@@ -2045,10 +2139,13 @@ static int nfa_regbranch(void)
if (nfa_regconcat() == FAIL)
return FAIL;
- ch = peekchr();
- /* Try next concats */
- while (ch == Magic('&')) {
+ // Try next concats
+ while (peekchr() == Magic('&')) {
skipchr();
+ // if concat is empty do emit a node
+ if (old_post_pos == (int)(post_ptr - post_start)) {
+ EMIT(NFA_EMPTY);
+ }
EMIT(NFA_NOPEN);
EMIT(NFA_PREV_ATOM_NO_WIDTH);
old_post_pos = (int)(post_ptr - post_start);
@@ -2058,7 +2155,6 @@ static int nfa_regbranch(void)
if (old_post_pos == (int)(post_ptr - post_start))
EMIT(NFA_EMPTY);
EMIT(NFA_CONCAT);
- ch = peekchr();
}
/* if a branch is empty, emit one node for it */
@@ -2359,6 +2455,8 @@ static void nfa_set_code(int c)
}
static FILE *log_fd;
+static char_u e_log_open_failed[] = N_(
+ "Could not open temporary log file for writing, displaying on stderr... ");
/*
* Print the postfix notation of the current regexp.
@@ -2371,10 +2469,11 @@ static void nfa_postfix_dump(char_u *expr, int retval)
f = fopen(NFA_REGEXP_DUMP_LOG, "a");
if (f != NULL) {
fprintf(f, "\n-------------------------\n");
- if (retval == FAIL)
- fprintf(f, ">>> NFA engine failed ... \n");
- else if (retval == OK)
+ if (retval == FAIL) {
+ fprintf(f, ">>> NFA engine failed... \n");
+ } else if (retval == OK) {
fprintf(f, ">>> NFA engine succeeded !\n");
+ }
fprintf(f, "Regexp: \"%s\"\nPostfix notation (char): \"", expr);
for (p = post_start; *p && p < post_ptr; p++) {
nfa_set_code(*p);
@@ -2628,7 +2727,7 @@ static void st_error(int *postfix, int *end, int *p)
fclose(df);
}
#endif
- EMSG(_("E874: (NFA) Could not pop the stack !"));
+ EMSG(_("E874: (NFA) Could not pop the stack!"));
}
/*
@@ -2690,15 +2789,10 @@ static int nfa_max_width(nfa_state_T *startstate, int depth)
case NFA_ANY:
case NFA_START_COLL:
case NFA_START_NEG_COLL:
- /* matches some character, including composing chars */
- if (enc_utf8)
- len += MB_MAXBYTES;
- else if (has_mbyte)
- len += 2;
- else
- ++len;
+ // Matches some character, including composing chars.
+ len += MB_MAXBYTES;
if (state->c != NFA_ANY) {
- /* skip over the characters */
+ // Skip over the characters.
state = state->out1->out;
continue;
}
@@ -3141,7 +3235,13 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size)
if (pattern) {
/* NFA_ZEND -> NFA_END_PATTERN -> NFA_SKIP -> what follows. */
skip = alloc_state(NFA_SKIP, NULL, NULL);
+ if (skip == NULL) {
+ goto theend;
+ }
zend = alloc_state(NFA_ZEND, s1, NULL);
+ if (zend == NULL) {
+ goto theend;
+ }
s1->out= skip;
patch(e.out, zend);
PUSH(frag(s, list1(&skip->out)));
@@ -3159,8 +3259,8 @@ static nfa_state_T *post2nfa(int *postfix, int *end, int nfa_calc_size)
break;
}
- case NFA_COMPOSING: /* char with composing char */
- /* FALLTHROUGH */
+ case NFA_COMPOSING: // char with composing char
+ FALLTHROUGH;
case NFA_MOPEN: /* \( \) Submatch */
case NFA_MOPEN1:
@@ -3811,23 +3911,27 @@ state_in_list (
return FALSE;
}
-/*
- * Add "state" and possibly what follows to state list ".".
- * Returns "subs_arg", possibly copied into temp_subs.
- */
+// Offset used for "off" by addstate_here().
+#define ADDSTATE_HERE_OFFSET 10
+// Add "state" and possibly what follows to state list ".".
+// Returns "subs_arg", possibly copied into temp_subs.
static regsubs_T *
addstate (
nfa_list_T *l, /* runtime state list */
nfa_state_T *state, /* state to update */
regsubs_T *subs_arg, /* pointers to subexpressions */
nfa_pim_T *pim, /* postponed look-behind match */
- int off /* byte offset, when -1 go to next line */
-)
+ int off_arg) /* byte offset, when -1 go to next line */
{
int subidx;
+ int off = off_arg;
+ int add_here = FALSE;
+ int listindex = 0;
+ int k;
+ int found = FALSE;
nfa_thread_T *thread;
- lpos_T save_lpos;
+ struct multipos save_multipos;
int save_in_use;
char_u *save_ptr;
int i;
@@ -3838,6 +3942,12 @@ addstate (
int did_print = FALSE;
#endif
+ if (off_arg <= -ADDSTATE_HERE_OFFSET) {
+ add_here = true;
+ off = 0;
+ listindex = -(off_arg + ADDSTATE_HERE_OFFSET);
+ }
+
switch (state->c) {
case NFA_NCLOSE:
case NFA_MCLOSE:
@@ -3879,7 +3989,7 @@ addstate (
|| !REG_MULTI
|| reglnum == nfa_endp->se_u.pos.lnum))
goto skip_add;
- /* FALLTHROUGH */
+ FALLTHROUGH;
case NFA_MOPEN1:
case NFA_MOPEN2:
@@ -3914,13 +4024,28 @@ addstate (
* lower position is preferred. */
if (!nfa_has_backref && pim == NULL && !l->has_pim
&& state->c != NFA_MATCH) {
+
+ /* When called from addstate_here() do insert before
+ * existing states. */
+ if (add_here) {
+ for (k = 0; k < l->n && k < listindex; ++k) {
+ if (l->t[k].state->id == state->id) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!add_here || found) {
skip_add:
#ifdef REGEXP_DEBUG
- nfa_set_code(state->c);
- fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n",
- abs(state->id), l->id, state->c, code);
+ nfa_set_code(state->c);
+ fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s pim: %s has_pim: %d found: %d\n",
+ abs(state->id), l->id, state->c, code,
+ pim == NULL ? "NULL" : "yes", l->has_pim, found);
#endif
return subs;
+ }
}
/* Do not add the state again when it exists with the same
@@ -3976,14 +4101,14 @@ skip_add:
case NFA_SPLIT:
/* order matters here */
- subs = addstate(l, state->out, subs, pim, off);
- subs = addstate(l, state->out1, subs, pim, off);
+ subs = addstate(l, state->out, subs, pim, off_arg);
+ subs = addstate(l, state->out1, subs, pim, off_arg);
break;
case NFA_EMPTY:
case NFA_NOPEN:
case NFA_NCLOSE:
- subs = addstate(l, state->out, subs, pim, off);
+ subs = addstate(l, state->out, subs, pim, off_arg);
break;
case NFA_MOPEN:
@@ -4010,7 +4135,7 @@ skip_add:
if (state->c == NFA_ZSTART) {
subidx = 0;
sub = &subs->norm;
- } else if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) {
+ } else if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) { // -V560
subidx = state->c - NFA_ZOPEN;
sub = &subs->synt;
} else {
@@ -4020,15 +4145,13 @@ skip_add:
/* avoid compiler warnings */
save_ptr = NULL;
- save_lpos.lnum = 0;
- save_lpos.col = 0;
+ memset(&save_multipos, 0, sizeof(save_multipos));
/* Set the position (with "off" added) in the subexpression. Save
* and restore it when it was in use. Otherwise fill any gap. */
if (REG_MULTI) {
if (subidx < sub->in_use) {
- save_lpos.lnum = sub->list.multi[subidx].start_lnum;
- save_lpos.col = sub->list.multi[subidx].start_col;
+ save_multipos = sub->list.multi[subidx];
save_in_use = -1;
} else {
save_in_use = sub->in_use;
@@ -4063,17 +4186,17 @@ skip_add:
sub->list.line[subidx].start = reginput + off;
}
- subs = addstate(l, state->out, subs, pim, off);
- /* "subs" may have changed, need to set "sub" again */
- if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9)
+ subs = addstate(l, state->out, subs, pim, off_arg);
+ // "subs" may have changed, need to set "sub" again.
+ if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) { // -V560
sub = &subs->synt;
- else
+ } else {
sub = &subs->norm;
+ }
if (save_in_use == -1) {
- if (REG_MULTI){
- sub->list.multi[subidx].start_lnum = save_lpos.lnum;
- sub->list.multi[subidx].start_col = save_lpos.col;
+ if (REG_MULTI) {
+ sub->list.multi[subidx] = save_multipos;
}
else
sub->list.line[subidx].start = save_ptr;
@@ -4086,9 +4209,10 @@ skip_add:
? subs->norm.list.multi[0].end_lnum >= 0
: subs->norm.list.line[0].end != NULL)) {
/* Do not overwrite the position set by \ze. */
- subs = addstate(l, state->out, subs, pim, off);
+ subs = addstate(l, state->out, subs, pim, off_arg);
break;
}
+ FALLTHROUGH;
case NFA_MCLOSE1:
case NFA_MCLOSE2:
case NFA_MCLOSE3:
@@ -4112,7 +4236,7 @@ skip_add:
if (state->c == NFA_ZEND) {
subidx = 0;
sub = &subs->norm;
- } else if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) {
+ } else if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) { // -V560
subidx = state->c - NFA_ZCLOSE;
sub = &subs->synt;
} else {
@@ -4126,8 +4250,7 @@ skip_add:
if (sub->in_use <= subidx)
sub->in_use = subidx + 1;
if (REG_MULTI) {
- save_lpos.lnum = sub->list.multi[subidx].end_lnum;
- save_lpos.col = sub->list.multi[subidx].end_col;
+ save_multipos = sub->list.multi[subidx];
if (off == -1) {
sub->list.multi[subidx].end_lnum = reglnum + 1;
sub->list.multi[subidx].end_col = 0;
@@ -4141,21 +4264,20 @@ skip_add:
} else {
save_ptr = sub->list.line[subidx].end;
sub->list.line[subidx].end = reginput + off;
- /* avoid compiler warnings */
- save_lpos.lnum = 0;
- save_lpos.col = 0;
+ // avoid compiler warnings
+ memset(&save_multipos, 0, sizeof(save_multipos));
}
- subs = addstate(l, state->out, subs, pim, off);
- /* "subs" may have changed, need to set "sub" again */
- if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9)
+ subs = addstate(l, state->out, subs, pim, off_arg);
+ // "subs" may have changed, need to set "sub" again.
+ if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) { // -V560
sub = &subs->synt;
- else
+ } else {
sub = &subs->norm;
+ }
- if (REG_MULTI){
- sub->list.multi[subidx].end_lnum = save_lpos.lnum;
- sub->list.multi[subidx].end_col = save_lpos.col;
+ if (REG_MULTI) {
+ sub->list.multi[subidx] = save_multipos;
}
else
sub->list.line[subidx].end = save_ptr;
@@ -4184,8 +4306,10 @@ addstate_here (
int count;
int listidx = *ip;
- /* first add the state(s) at the end, so that we know how many there are */
- addstate(l, state, subs, pim, 0);
+ /* First add the state(s) at the end, so that we know how many there are.
+ * Pass the listidx as offset (avoids adding another argument to
+ * addstate(). */
+ addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET);
/* when "*ip" was at the end of the list, nothing to do */
if (listidx + 1 == tlen)
@@ -4238,48 +4362,55 @@ static int check_char_class(int class, int c)
{
switch (class) {
case NFA_CLASS_ALNUM:
- if (c >= 1 && c <= 255 && isalnum(c))
+ if (c >= 1 && c < 128 && isalnum(c)) {
return OK;
+ }
break;
case NFA_CLASS_ALPHA:
- if (c >= 1 && c <= 255 && isalpha(c))
+ if (c >= 1 && c < 128 && isalpha(c)) {
return OK;
+ }
break;
case NFA_CLASS_BLANK:
if (c == ' ' || c == '\t')
return OK;
break;
case NFA_CLASS_CNTRL:
- if (c >= 1 && c <= 255 && iscntrl(c))
+ if (c >= 1 && c <= 127 && iscntrl(c)) {
return OK;
+ }
break;
case NFA_CLASS_DIGIT:
if (ascii_isdigit(c))
return OK;
break;
case NFA_CLASS_GRAPH:
- if (c >= 1 && c <= 255 && isgraph(c))
+ if (c >= 1 && c <= 127 && isgraph(c)) {
return OK;
+ }
break;
case NFA_CLASS_LOWER:
- if (vim_islower(c))
+ if (mb_islower(c) && c != 170 && c != 186) {
return OK;
+ }
break;
case NFA_CLASS_PRINT:
if (vim_isprintc(c))
return OK;
break;
case NFA_CLASS_PUNCT:
- if (c >= 1 && c <= 255 && ispunct(c))
+ if (c >= 1 && c < 128 && ispunct(c)) {
return OK;
+ }
break;
case NFA_CLASS_SPACE:
if ((c >= 9 && c <= 13) || (c == ' '))
return OK;
break;
case NFA_CLASS_UPPER:
- if (vim_isupper(c))
+ if (mb_isupper(c)) {
return OK;
+ }
break;
case NFA_CLASS_XDIGIT:
if (ascii_isxdigit(c))
@@ -4298,13 +4429,14 @@ static int check_char_class(int class, int c)
return OK;
break;
case NFA_CLASS_ESCAPE:
- if (c == '\033')
+ if (c == ESC) {
return OK;
+ }
break;
default:
- /* should not be here :P */
- EMSGN(_(e_ill_char_class), class);
+ // should not be here :P
+ IEMSGN(_(e_ill_char_class), class);
return FAIL;
}
return FAIL;
@@ -4507,10 +4639,10 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T
}
if ((int)(reginput - regline) >= state->val) {
reginput -= state->val;
- if (has_mbyte)
- reginput -= mb_head_off(regline, reginput);
- } else
+ reginput -= utf_head_off(regline, reginput);
+ } else {
reginput = regline;
+ }
}
}
@@ -4556,9 +4688,11 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T
if (REG_MULTI)
regline = reg_getline(reglnum);
reginput = regline + save_reginput_col;
- nfa_match = save_nfa_match;
+ if (result != NFA_TOO_EXPENSIVE) {
+ nfa_match = save_nfa_match;
+ nfa_listid = save_nfa_listid;
+ }
nfa_endp = save_nfa_endp;
- nfa_listid = save_nfa_listid;
#ifdef REGEXP_DEBUG
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
@@ -4568,8 +4702,7 @@ static int recursive_regmatch(nfa_state_T *state, nfa_pim_T *pim, nfa_regprog_T
fprintf(log_fd, "MATCH = %s\n", !result ? "FALSE" : "OK");
fprintf(log_fd, "****************************\n");
} else {
- EMSG(_(
- "Could not open temporary log file for writing, displaying on stderr ... "));
+ EMSG(_(e_log_open_failed));
log_fd = stderr;
}
#endif
@@ -4740,17 +4873,10 @@ static int failure_chance(nfa_state_T *state, int depth)
*/
static int skip_to_start(int c, colnr_T *colp)
{
- char_u *s;
-
- /* Used often, do some work to avoid call overhead. */
- if (!ireg_ic
- && !has_mbyte
- )
- s = vim_strbyte(regline + *colp, c);
- else
- s = cstrchr(regline + *colp, c);
- if (s == NULL)
+ const char_u *const s = cstrchr(regline + *colp, c);
+ if (s == NULL) {
return FAIL;
+ }
*colp = (int)(s - regline);
return OK;
}
@@ -4777,7 +4903,7 @@ static long find_match_text(colnr_T startcol, int regstart, char_u *match_text)
int c2_len = PTR2LEN(s2);
int c2 = PTR2CHAR(s2);
- if ((c1 != c2 && (!ireg_ic || vim_tolower(c1) != vim_tolower(c2)))
+ if ((c1 != c2 && (!rex.reg_ic || mb_tolower(c1) != mb_tolower(c2)))
|| c1_len != c2_len) {
match = false;
break;
@@ -4790,13 +4916,13 @@ static long find_match_text(colnr_T startcol, int regstart, char_u *match_text)
&& !(enc_utf8 && utf_iscomposing(PTR2CHAR(s2)))) {
cleanup_subexpr();
if (REG_MULTI) {
- reg_startpos[0].lnum = reglnum;
- reg_startpos[0].col = col;
- reg_endpos[0].lnum = reglnum;
- reg_endpos[0].col = s2 - regline;
+ rex.reg_startpos[0].lnum = reglnum;
+ rex.reg_startpos[0].col = col;
+ rex.reg_endpos[0].lnum = reglnum;
+ rex.reg_endpos[0].col = s2 - regline;
} else {
- reg_startp[0] = regline + col;
- reg_endp[0] = s2;
+ rex.reg_startp[0] = regline + col;
+ rex.reg_endp[0] = s2;
}
return 1L;
}
@@ -4842,7 +4968,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
FILE *debug = fopen(NFA_REGEXP_DEBUG_LOG, "a");
if (debug == NULL) {
- EMSG2(_("(NFA) COULD NOT OPEN %s !"), NFA_REGEXP_DEBUG_LOG);
+ EMSG2("(NFA) COULD NOT OPEN %s!", NFA_REGEXP_DEBUG_LOG);
return false;
}
#endif
@@ -4850,9 +4976,15 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
// recursive_regmatch(). Allow interrupting them with CTRL-C.
fast_breakcheck();
if (got_int) {
+#ifdef NFA_REGEXP_DEBUG_LOG
+ fclose(debug);
+#endif
return false;
}
if (nfa_time_limit != NULL && profile_passed_limit(*nfa_time_limit)) {
+#ifdef NFA_REGEXP_DEBUG_LOG
+ fclose(debug);
+#endif
return false;
}
@@ -4874,8 +5006,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
abs(start->id), code);
fprintf(log_fd, "**********************************\n");
} else {
- EMSG(_(
- "Could not open temporary log file for writing, displaying on stderr ... "));
+ EMSG(_(e_log_open_failed));
log_fd = stderr;
}
#endif
@@ -4914,16 +5045,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
* Run for each character.
*/
for (;; ) {
- int curc;
- int clen;
-
- if (has_mbyte) {
- curc = (*mb_ptr2char)(reginput);
- clen = (*mb_ptr2len)(reginput);
- } else {
- curc = *reginput;
- clen = 1;
- }
+ int curc = utf_ptr2char(reginput);
+ int clen = utfc_ptr2len(reginput);
if (curc == NUL) {
clen = 0;
go_to_nextline = false;
@@ -4932,10 +5055,11 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
/* swap lists */
thislist = &list[flag];
nextlist = &list[flag ^= 1];
- nextlist->n = 0; /* clear nextlist */
- nextlist->has_pim = FALSE;
- ++nfa_listid;
- if (prog->re_engine == AUTOMATIC_ENGINE && nfa_listid >= NFA_MAX_STATES) {
+ nextlist->n = 0; // clear nextlist
+ nextlist->has_pim = false;
+ nfa_listid++;
+ if (prog->re_engine == AUTOMATIC_ENGINE
+ && (nfa_listid >= NFA_MAX_STATES)) {
// Too many states, retry with old engine.
nfa_match = NFA_TOO_EXPENSIVE;
goto theend;
@@ -4948,8 +5072,9 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
fprintf(log_fd, "------------------------------------------\n");
fprintf(log_fd, ">>> Reginput is \"%s\"\n", reginput);
fprintf(log_fd,
- ">>> Advanced one character ... Current char is %c (code %d) \n", curc,
- (int)curc);
+ ">>> Advanced one character... Current char is %c (code %d) \n",
+ curc,
+ (int)curc);
fprintf(log_fd, ">>> Thislist has %d states available: ", thislist->n);
{
int i;
@@ -4981,16 +5106,17 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
{
int col;
- if (t->subs.norm.in_use <= 0)
+ if (t->subs.norm.in_use <= 0) {
col = -1;
- else if (REG_MULTI)
+ } else if (REG_MULTI) {
col = t->subs.norm.list.multi[0].start_col;
- else
+ } else {
col = (int)(t->subs.norm.list.line[0].start - regline);
+ }
nfa_set_code(t->state->c);
- fprintf(log_fd, "(%d) char %d %s (start col %d)%s ... \n",
- abs(t->state->id), (int)t->state->c, code, col,
- pim_info(&t->pim));
+ fprintf(log_fd, "(%d) char %d %s (start col %d)%s... \n",
+ abs(t->state->id), (int)t->state->c, code, col,
+ pim_info(&t->pim));
}
#endif
@@ -5005,8 +5131,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
case NFA_MATCH:
{
// If the match ends before a composing characters and
- // ireg_icombine is not set, that is not really a match.
- if (enc_utf8 && !ireg_icombine && utf_iscomposing(curc)) {
+ // rex.reg_icombine is not set, that is not really a match.
+ if (enc_utf8 && !rex.reg_icombine && utf_iscomposing(curc)) {
break;
}
nfa_match = true;
@@ -5289,15 +5415,15 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
int this_class;
// Get class of current and previous char (if it exists).
- this_class = mb_get_class_buf(reginput, reg_buf);
+ this_class = mb_get_class_tab(reginput, rex.reg_buf->b_chartab);
if (this_class <= 1) {
result = false;
} else if (reg_prev_class() == this_class) {
result = false;
}
- } else if (!vim_iswordc_buf(curc, reg_buf)
+ } else if (!vim_iswordc_buf(curc, rex.reg_buf)
|| (reginput > regline
- && vim_iswordc_buf(reginput[-1], reg_buf))) {
+ && vim_iswordc_buf(reginput[-1], rex.reg_buf))) {
result = false;
}
if (result) {
@@ -5314,15 +5440,15 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
int this_class, prev_class;
// Get class of current and previous char (if it exists).
- this_class = mb_get_class_buf(reginput, reg_buf);
+ this_class = mb_get_class_tab(reginput, rex.reg_buf->b_chartab);
prev_class = reg_prev_class();
if (this_class == prev_class
|| prev_class == 0 || prev_class == 1) {
result = false;
}
- } else if (!vim_iswordc_buf(reginput[-1], reg_buf)
+ } else if (!vim_iswordc_buf(reginput[-1], rex.reg_buf)
|| (reginput[0] != NUL
- && vim_iswordc_buf(curc, reg_buf))) {
+ && vim_iswordc_buf(curc, rex.reg_buf))) {
result = false;
}
if (result) {
@@ -5333,14 +5459,14 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
case NFA_BOF:
if (reglnum == 0 && reginput == regline
- && (!REG_MULTI || reg_firstlnum == 1)) {
+ && (!REG_MULTI || rex.reg_firstlnum == 1)) {
add_here = true;
add_state = t->state->out;
}
break;
case NFA_EOF:
- if (reglnum == reg_maxline && curc == NUL) {
+ if (reglnum == rex.reg_maxline && curc == NUL) {
add_here = true;
add_state = t->state->out;
}
@@ -5364,7 +5490,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
// (no preceding character).
len += mb_char2len(mc);
}
- if (ireg_icombine && len == 0) {
+ if (rex.reg_icombine && len == 0) {
// If \Z was present, then ignore composing characters.
// When ignoring the base character this always matches.
if (sta->c != curc) {
@@ -5385,7 +5511,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
// We don't care about the order of composing characters.
// Get them into cchars[] first.
while (len < clen) {
- mc = mb_ptr2char(reginput + len);
+ mc = utf_ptr2char(reginput + len);
cchars[ccount++] = mc;
len += mb_char2len(mc);
if (ccount == MAX_MCO)
@@ -5415,14 +5541,14 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
}
case NFA_NEWL:
- if (curc == NUL && !reg_line_lbr && REG_MULTI
- && reglnum <= reg_maxline) {
+ if (curc == NUL && !rex.reg_line_lbr && REG_MULTI
+ && reglnum <= rex.reg_maxline) {
go_to_nextline = true;
// Pass -1 for the offset, which means taking the position
// at the start of the next line.
add_state = t->state->out;
add_off = -1;
- } else if (curc == '\n' && reg_line_lbr) {
+ } else if (curc == '\n' && rex.reg_line_lbr) {
// match \n as if it is an ordinary character
add_state = t->state->out;
add_off = 1;
@@ -5463,23 +5589,25 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
result = result_if_matched;
break;
}
- if (ireg_ic) {
- int curc_low = vim_tolower(curc);
- int done = FALSE;
+ if (rex.reg_ic) {
+ int curc_low = mb_tolower(curc);
+ int done = false;
- for (; c1 <= c2; ++c1)
- if (vim_tolower(c1) == curc_low) {
+ for (; c1 <= c2; c1++) {
+ if (mb_tolower(c1) == curc_low) {
result = result_if_matched;
done = TRUE;
break;
}
- if (done)
+ }
+ if (done) {
break;
+ }
}
} else if (state->c < 0 ? check_char_class(state->c, curc)
: (curc == state->c
- || (ireg_ic && vim_tolower(curc)
- == vim_tolower(state->c)))) {
+ || (rex.reg_ic && mb_tolower(curc)
+ == mb_tolower(state->c)))) {
result = result_if_matched;
break;
}
@@ -5526,13 +5654,13 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
break;
case NFA_KWORD: // \k
- result = vim_iswordp_buf(reginput, reg_buf);
+ result = vim_iswordp_buf(reginput, rex.reg_buf);
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_SKWORD: // \K
result = !ascii_isdigit(curc)
- && vim_iswordp_buf(reginput, reg_buf);
+ && vim_iswordp_buf(reginput, rex.reg_buf);
ADD_STATE_IF_MATCH(t->state);
break;
@@ -5647,24 +5775,24 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
break;
case NFA_LOWER_IC: // [a-z]
- result = ri_lower(curc) || (ireg_ic && ri_upper(curc));
+ result = ri_lower(curc) || (rex.reg_ic && ri_upper(curc));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_NLOWER_IC: // [^a-z]
result = curc != NUL
- && !(ri_lower(curc) || (ireg_ic && ri_upper(curc)));
+ && !(ri_lower(curc) || (rex.reg_ic && ri_upper(curc)));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_UPPER_IC: // [A-Z]
- result = ri_upper(curc) || (ireg_ic && ri_lower(curc));
+ result = ri_upper(curc) || (rex.reg_ic && ri_lower(curc));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_NUPPER_IC: // [^A-Z]
result = curc != NUL
- && !(ri_upper(curc) || (ireg_ic && ri_lower(curc)));
+ && !(ri_upper(curc) || (rex.reg_ic && ri_lower(curc)));
ADD_STATE_IF_MATCH(t->state);
break;
@@ -5738,13 +5866,15 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
case NFA_LNUM_GT:
case NFA_LNUM_LT:
assert(t->state->val >= 0
- && !((reg_firstlnum > 0 && reglnum > LONG_MAX - reg_firstlnum)
- || (reg_firstlnum <0 && reglnum < LONG_MIN + reg_firstlnum))
- && reglnum + reg_firstlnum >= 0);
+ && !((rex.reg_firstlnum > 0
+ && reglnum > LONG_MAX - rex.reg_firstlnum)
+ || (rex.reg_firstlnum < 0
+ && reglnum < LONG_MIN + rex.reg_firstlnum))
+ && reglnum + rex.reg_firstlnum >= 0);
result = (REG_MULTI
&& nfa_re_num_cmp((uintmax_t)t->state->val,
t->state->c - NFA_LNUM,
- (uintmax_t)(reglnum + reg_firstlnum)));
+ (uintmax_t)(reglnum + rex.reg_firstlnum)));
if (result) {
add_here = true;
add_state = t->state->out;
@@ -5780,7 +5910,7 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
}
result = false;
- win_T *wp = reg_win == NULL ? curwin : reg_win;
+ win_T *wp = rex.reg_win == NULL ? curwin : rex.reg_win;
if (op == 1 && col - 1 > t->state->val && col > 100) {
long ts = wp->w_buffer->b_p_ts;
@@ -5807,18 +5937,18 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
case NFA_MARK_GT:
case NFA_MARK_LT:
{
- pos_T *pos = getmark_buf(reg_buf, t->state->val, FALSE);
+ pos_T *pos = getmark_buf(rex.reg_buf, t->state->val, false);
// Compare the mark position to the match position.
result = (pos != NULL // mark doesn't exist
&& pos->lnum > 0 // mark isn't set in reg_buf
- && (pos->lnum == reglnum + reg_firstlnum
+ && (pos->lnum == reglnum + rex.reg_firstlnum
? (pos->col == (colnr_T)(reginput - regline)
? t->state->c == NFA_MARK
: (pos->col < (colnr_T)(reginput - regline)
? t->state->c == NFA_MARK_GT
: t->state->c == NFA_MARK_LT))
- : (pos->lnum < reglnum + reg_firstlnum
+ : (pos->lnum < reglnum + rex.reg_firstlnum
? t->state->c == NFA_MARK_GT
: t->state->c == NFA_MARK_LT)));
if (result) {
@@ -5829,10 +5959,10 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
}
case NFA_CURSOR:
- result = (reg_win != NULL
- && (reglnum + reg_firstlnum == reg_win->w_cursor.lnum)
+ result = (rex.reg_win != NULL
+ && (reglnum + rex.reg_firstlnum == rex.reg_win->w_cursor.lnum)
&& ((colnr_T)(reginput - regline)
- == reg_win->w_cursor.col));
+ == rex.reg_win->w_cursor.col));
if (result) {
add_here = true;
add_state = t->state->out;
@@ -5877,17 +6007,19 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
int c = t->state->c;
#ifdef REGEXP_DEBUG
- if (c < 0)
- EMSGN("INTERNAL: Negative state char: %" PRId64, c);
+ if (c < 0) {
+ IEMSGN("INTERNAL: Negative state char: %" PRId64, c);
+ }
#endif
result = (c == curc);
- if (!result && ireg_ic)
- result = vim_tolower(c) == vim_tolower(curc);
+ if (!result && rex.reg_ic) {
+ result = mb_tolower(c) == mb_tolower(curc);
+ }
- // If ireg_icombine is not set only skip over the character
+ // If rex.reg_icombine is not set only skip over the character
// itself. When it is set skip over composing characters.
- if (result && enc_utf8 && !ireg_icombine) {
+ if (result && enc_utf8 && !rex.reg_icombine) {
clen = utf_ptr2len(reginput);
}
@@ -5995,8 +6127,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
&& ((toplevel
&& reglnum == 0
&& clen != 0
- && (ireg_maxcol == 0
- || (colnr_T)(reginput - regline) < ireg_maxcol))
+ && (rex.reg_maxcol == 0
+ || (colnr_T)(reginput - regline) < rex.reg_maxcol))
|| (nfa_endp != NULL
&& (REG_MULTI
? (reglnum < nfa_endp->se_u.pos.lnum
@@ -6031,8 +6163,8 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start,
// Checking if the required start character matches is
// cheaper than adding a state that won't match.
c = PTR2CHAR(reginput + clen);
- if (c != prog->regstart && (!ireg_ic || vim_tolower(c)
- != vim_tolower(prog->regstart))) {
+ if (c != prog->regstart && (!rex.reg_ic || mb_tolower(c)
+ != mb_tolower(prog->regstart))) {
#ifdef REGEXP_DEBUG
fprintf(log_fd,
" Skipping start state, regstart does not match\n");
@@ -6138,8 +6270,9 @@ static long nfa_regtry(nfa_regprog_T *prog, colnr_T col, proftime_T *tm)
nfa_print_state(f, start);
fprintf(f, "\n\n");
fclose(f);
- } else
- EMSG(_("Could not open temporary log file for writing "));
+ } else {
+ EMSG("Could not open temporary log file for writing");
+ }
#endif
clear_sub(&subs.norm);
@@ -6157,34 +6290,37 @@ static long nfa_regtry(nfa_regprog_T *prog, colnr_T col, proftime_T *tm)
cleanup_subexpr();
if (REG_MULTI) {
for (i = 0; i < subs.norm.in_use; i++) {
- reg_startpos[i].lnum = subs.norm.list.multi[i].start_lnum;
- reg_startpos[i].col = subs.norm.list.multi[i].start_col;
+ rex.reg_startpos[i].lnum = subs.norm.list.multi[i].start_lnum;
+ rex.reg_startpos[i].col = subs.norm.list.multi[i].start_col;
- reg_endpos[i].lnum = subs.norm.list.multi[i].end_lnum;
- reg_endpos[i].col = subs.norm.list.multi[i].end_col;
+ rex.reg_endpos[i].lnum = subs.norm.list.multi[i].end_lnum;
+ rex.reg_endpos[i].col = subs.norm.list.multi[i].end_col;
}
- if (reg_startpos[0].lnum < 0) {
- reg_startpos[0].lnum = 0;
- reg_startpos[0].col = col;
+ if (rex.reg_startpos[0].lnum < 0) {
+ rex.reg_startpos[0].lnum = 0;
+ rex.reg_startpos[0].col = col;
+ }
+ if (rex.reg_endpos[0].lnum < 0) {
+ // pattern has a \ze but it didn't match, use current end
+ rex.reg_endpos[0].lnum = reglnum;
+ rex.reg_endpos[0].col = (int)(reginput - regline);
+ } else {
+ // Use line number of "\ze".
+ reglnum = rex.reg_endpos[0].lnum;
}
- if (reg_endpos[0].lnum < 0) {
- /* pattern has a \ze but it didn't match, use current end */
- reg_endpos[0].lnum = reglnum;
- reg_endpos[0].col = (int)(reginput - regline);
- } else
- /* Use line number of "\ze". */
- reglnum = reg_endpos[0].lnum;
} else {
for (i = 0; i < subs.norm.in_use; i++) {
- reg_startp[i] = subs.norm.list.line[i].start;
- reg_endp[i] = subs.norm.list.line[i].end;
+ rex.reg_startp[i] = subs.norm.list.line[i].start;
+ rex.reg_endp[i] = subs.norm.list.line[i].end;
}
- if (reg_startp[0] == NULL)
- reg_startp[0] = regline + col;
- if (reg_endp[0] == NULL)
- reg_endp[0] = reginput;
+ if (rex.reg_startp[0] == NULL) {
+ rex.reg_startp[0] = regline + col;
+ }
+ if (rex.reg_endp[0] == NULL) {
+ rex.reg_endp[0] = reginput;
+ }
}
/* Package any found \z(...\) matches for export. Default is none. */
@@ -6238,14 +6374,14 @@ static long nfa_regexec_both(char_u *line, colnr_T startcol, proftime_T *tm)
colnr_T col = startcol;
if (REG_MULTI) {
- prog = (nfa_regprog_T *)reg_mmatch->regprog;
- line = reg_getline((linenr_T)0); /* relative to the cursor */
- reg_startpos = reg_mmatch->startpos;
- reg_endpos = reg_mmatch->endpos;
+ prog = (nfa_regprog_T *)rex.reg_mmatch->regprog;
+ line = reg_getline((linenr_T)0); // relative to the cursor
+ rex.reg_startpos = rex.reg_mmatch->startpos;
+ rex.reg_endpos = rex.reg_mmatch->endpos;
} else {
- prog = (nfa_regprog_T *)reg_match->regprog;
- reg_startp = reg_match->startp;
- reg_endp = reg_match->endp;
+ prog = (nfa_regprog_T *)rex.reg_match->regprog;
+ rex.reg_startp = rex.reg_match->startp;
+ rex.reg_endp = rex.reg_match->endp;
}
/* Be paranoid... */
@@ -6254,15 +6390,17 @@ static long nfa_regexec_both(char_u *line, colnr_T startcol, proftime_T *tm)
goto theend;
}
- /* If pattern contains "\c" or "\C": overrule value of ireg_ic */
- if (prog->regflags & RF_ICASE)
- ireg_ic = TRUE;
- else if (prog->regflags & RF_NOICASE)
- ireg_ic = FALSE;
+ // If pattern contains "\c" or "\C": overrule value of rex.reg_ic
+ if (prog->regflags & RF_ICASE) {
+ rex.reg_ic = true;
+ } else if (prog->regflags & RF_NOICASE) {
+ rex.reg_ic = false;
+ }
- /* If pattern contains "\Z" overrule value of ireg_icombine */
- if (prog->regflags & RF_ICOMBINE)
- ireg_icombine = TRUE;
+ // If pattern contains "\Z" overrule value of rex.reg_icombine
+ if (prog->regflags & RF_ICOMBINE) {
+ rex.reg_icombine = true;
+ }
regline = line;
reglnum = 0; /* relative to line */
@@ -6291,17 +6429,17 @@ static long nfa_regexec_both(char_u *line, colnr_T startcol, proftime_T *tm)
if (skip_to_start(prog->regstart, &col) == FAIL)
return 0L;
- /* If match_text is set it contains the full text that must match.
- * Nothing else to try. Doesn't handle combining chars well. */
- if (prog->match_text != NULL
- && !ireg_icombine
- )
+ // If match_text is set it contains the full text that must match.
+ // Nothing else to try. Doesn't handle combining chars well.
+ if (prog->match_text != NULL && !rex.reg_icombine) {
return find_match_text(col, prog->regstart, prog->match_text);
+ }
}
- /* If the start column is past the maximum column: no need to try. */
- if (ireg_maxcol > 0 && col >= ireg_maxcol)
+ // If the start column is past the maximum column: no need to try.
+ if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) {
goto theend;
+ }
nstate = prog->nstate;
for (i = 0; i < nstate; ++i) {
@@ -6341,12 +6479,13 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags)
* (and count its size). */
postfix = re2post();
if (postfix == NULL) {
- /* TODO: only give this error for debugging? */
- if (post_ptr >= post_end)
- EMSGN("Internal error: estimated max number "
- "of states insufficient: %" PRId64,
- post_end - post_start);
- goto fail; /* Cascaded (syntax?) error */
+ // TODO(vim): only give this error for debugging?
+ if (post_ptr >= post_end) {
+ IEMSGN("Internal error: estimated max number "
+ "of states insufficient: %" PRId64,
+ post_end - post_start);
+ }
+ goto fail; // Cascaded (syntax?) error
}
/*
@@ -6359,10 +6498,10 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags)
FILE *f = fopen(NFA_REGEXP_RUN_LOG, "a");
if (f != NULL) {
- fprintf(
- f,
- "\n*****************************\n\n\n\n\tCompiling regexp \"%s\" ... hold on !\n",
- expr);
+ fprintf(f,
+ "\n*****************************\n\n\n\n\t"
+ "Compiling regexp \"%s\"... hold on !\n",
+ expr);
fclose(f);
}
}
@@ -6453,15 +6592,15 @@ nfa_regexec_nl (
bool line_lbr
)
{
- reg_match = rmp;
- reg_mmatch = NULL;
- reg_maxline = 0;
- reg_line_lbr = line_lbr;
- reg_buf = curbuf;
- reg_win = NULL;
- ireg_ic = rmp->rm_ic;
- ireg_icombine = FALSE;
- ireg_maxcol = 0;
+ rex.reg_match = rmp;
+ rex.reg_mmatch = NULL;
+ rex.reg_maxline = 0;
+ rex.reg_line_lbr = line_lbr;
+ rex.reg_buf = curbuf;
+ rex.reg_win = NULL;
+ rex.reg_ic = rmp->rm_ic;
+ rex.reg_icombine = false;
+ rex.reg_maxcol = 0;
return nfa_regexec_both(line, col, NULL);
}
@@ -6502,16 +6641,16 @@ nfa_regexec_nl (
static long nfa_regexec_multi(regmmatch_T *rmp, win_T *win, buf_T *buf,
linenr_T lnum, colnr_T col, proftime_T *tm)
{
- reg_match = NULL;
- reg_mmatch = rmp;
- reg_buf = buf;
- reg_win = win;
- reg_firstlnum = lnum;
- reg_maxline = reg_buf->b_ml.ml_line_count - lnum;
- reg_line_lbr = FALSE;
- ireg_ic = rmp->rmm_ic;
- ireg_icombine = FALSE;
- ireg_maxcol = rmp->rmm_maxcol;
+ 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;
return nfa_regexec_both(NULL, col, tm);
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 34eef83164..2467cf192f 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -1,88 +1,71 @@
-/*
- * screen.c: code for displaying on the screen
- *
- * Output to the screen (console, terminal emulator or GUI window) is minimized
- * by remembering what is already on the screen, and only updating the parts
- * that changed.
- *
- * ScreenLines[off] Contains a copy of the whole screen, as it is currently
- * displayed (excluding text written by external commands).
- * ScreenAttrs[off] Contains the associated attributes.
- * LineOffset[row] Contains the offset into ScreenLines*[] and ScreenAttrs[]
- * for each line.
- * LineWraps[row] Flag for each line whether it wraps to the next line.
- *
- * For double-byte characters, two consecutive bytes in ScreenLines[] can form
- * one character which occupies two display cells.
- * For UTF-8 a multi-byte character is converted to Unicode and stored in
- * ScreenLinesUC[]. ScreenLines[] contains the first byte only. For an ASCII
- * character without composing chars ScreenLinesUC[] will be 0 and
- * ScreenLinesC[][] is not used. When the character occupies two display
- * cells the next byte in ScreenLines[] is 0.
- * ScreenLinesC[][] contain up to 'maxcombine' composing characters
- * (drawn on top of the first character). There is 0 after the last one used.
- * ScreenLines2[] is only used for euc-jp to store the second byte if the
- * first byte is 0x8e (single-width character).
- *
- * The screen_*() functions write to the screen and handle updating
- * ScreenLines[].
- *
- * update_screen() is the function that updates all windows and status lines.
- * It is called form the main loop when must_redraw is non-zero. It may be
- * called from other places when an immediate screen update is needed.
- *
- * The part of the buffer that is displayed in a window is set with:
- * - w_topline (first buffer line in window)
- * - w_topfill (filler lines above the first line)
- * - w_leftcol (leftmost window cell in window),
- * - w_skipcol (skipped window cells of first line)
- *
- * Commands that only move the cursor around in a window, do not need to take
- * action to update the display. The main loop will check if w_topline is
- * valid and update it (scroll the window) when needed.
- *
- * Commands that scroll a window change w_topline and must call
- * check_cursor() to move the cursor into the visible part of the window, and
- * call redraw_later(VALID) to have the window displayed by update_screen()
- * later.
- *
- * Commands that change text in the buffer must call changed_bytes() or
- * changed_lines() to mark the area that changed and will require updating
- * later. The main loop will call update_screen(), which will update each
- * window that shows the changed buffer. This assumes text above the change
- * can remain displayed as it is. Text after the change may need updating for
- * scrolling, folding and syntax highlighting.
- *
- * Commands that change how a window is displayed (e.g., setting 'list') or
- * invalidate the contents of a window in another way (e.g., change fold
- * settings), must call redraw_later(NOT_VALID) to have the whole window
- * redisplayed by update_screen() later.
- *
- * Commands that change how a buffer is displayed (e.g., setting 'tabstop')
- * must call redraw_curbuf_later(NOT_VALID) to have all the windows for the
- * buffer redisplayed by update_screen() later.
- *
- * Commands that change highlighting and possibly cause a scroll too must call
- * redraw_later(SOME_VALID) to update the whole window but still use scrolling
- * to avoid redrawing everything. But the length of displayed lines must not
- * change, use NOT_VALID then.
- *
- * Commands that move the window position must call redraw_later(NOT_VALID).
- * TODO: should minimize redrawing by scrolling when possible.
- *
- * Commands that change everything (e.g., resizing the screen) must call
- * redraw_all_later(NOT_VALID) or redraw_all_later(CLEAR).
- *
- * Things that are handled indirectly:
- * - When messages scroll the screen up, msg_scrolled will be set and
- * update_screen() called to redraw.
- */
+// 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
+
+// screen.c: code for displaying on the screen
+//
+// Output to the screen (console, terminal emulator or GUI window) is minimized
+// by remembering what is already on the screen, and only updating the parts
+// that changed.
+//
+// The grid_*() functions write to the screen and handle updating grid->lines[].
+//
+// update_screen() is the function that updates all windows and status lines.
+// It is called from the main loop when must_redraw is non-zero. It may be
+// called from other places when an immediate screen update is needed.
+//
+// The part of the buffer that is displayed in a window is set with:
+// - w_topline (first buffer line in window)
+// - w_topfill (filler lines above the first line)
+// - w_leftcol (leftmost window cell in window),
+// - w_skipcol (skipped window cells of first line)
+//
+// Commands that only move the cursor around in a window, do not need to take
+// action to update the display. The main loop will check if w_topline is
+// valid and update it (scroll the window) when needed.
+//
+// Commands that scroll a window change w_topline and must call
+// check_cursor() to move the cursor into the visible part of the window, and
+// call redraw_later(VALID) to have the window displayed by update_screen()
+// later.
+//
+// Commands that change text in the buffer must call changed_bytes() or
+// changed_lines() to mark the area that changed and will require updating
+// later. The main loop will call update_screen(), which will update each
+// window that shows the changed buffer. This assumes text above the change
+// can remain displayed as it is. Text after the change may need updating for
+// scrolling, folding and syntax highlighting.
+//
+// Commands that change how a window is displayed (e.g., setting 'list') or
+// invalidate the contents of a window in another way (e.g., change fold
+// settings), must call redraw_later(NOT_VALID) to have the whole window
+// redisplayed by update_screen() later.
+//
+// Commands that change how a buffer is displayed (e.g., setting 'tabstop')
+// must call redraw_curbuf_later(NOT_VALID) to have all the windows for the
+// buffer redisplayed by update_screen() later.
+//
+// Commands that change highlighting and possibly cause a scroll too must call
+// redraw_later(SOME_VALID) to update the whole window but still use scrolling
+// to avoid redrawing everything. But the length of displayed lines must not
+// change, use NOT_VALID then.
+//
+// Commands that move the window position must call redraw_later(NOT_VALID).
+// TODO(neovim): should minimize redrawing by scrolling when possible.
+//
+// Commands that change everything (e.g., resizing the screen) must call
+// redraw_all_later(NOT_VALID) or redraw_all_later(CLEAR).
+//
+// Things that are handled indirectly:
+// - When messages scroll the screen up, msg_scrolled will be set and
+// update_screen() called to redraw.
+///
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/arabic.h"
@@ -90,6 +73,7 @@
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/cursor_shape.h"
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
@@ -101,14 +85,15 @@
#include "nvim/fold.h"
#include "nvim/indent.h"
#include "nvim/getchar.h"
+#include "nvim/highlight.h"
#include "nvim/main.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/move.h"
#include "nvim/normal.h"
@@ -120,6 +105,7 @@
#include "nvim/regexp.h"
#include "nvim/search.h"
#include "nvim/spell.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/terminal.h"
@@ -128,29 +114,45 @@
#include "nvim/version.h"
#include "nvim/window.h"
#include "nvim/os/time.h"
+#include "nvim/api/private/helpers.h"
#define MB_FILLER_CHAR '<' /* character used when a double-width character
* doesn't fit. */
#define W_ENDCOL(wp) (wp->w_wincol + wp->w_width)
+#define W_ENDROW(wp) (wp->w_winrow + wp->w_height)
-/*
- * The attributes that are actually active for writing to the screen.
- */
-static int screen_attr = 0;
+
+// temporary buffer for rendering a single screenline, so it can be
+// comparared with previous contents to calulate smallest delta.
+static size_t linebuf_size = 0;
+static schar_T *linebuf_char = NULL;
+static sattr_T *linebuf_attr = NULL;
static match_T search_hl; /* used for 'hlsearch' highlight matching */
static foldinfo_T win_foldinfo; /* info for 'foldcolumn' */
-/*
- * Buffer for one screen line (characters and attributes).
- */
-static schar_T *current_ScreenLine;
-
StlClickDefinition *tab_page_click_defs = NULL;
+
long tab_page_click_defs_size = 0;
-# define SCREEN_LINE(r, o, e, c, rl) screen_line((r), (o), (e), (c), (rl))
+// for line_putchar. Contains the state that needs to be remembered from
+// putting one character to the next.
+typedef struct {
+ const char_u *p;
+ int prev_c; // previous Arabic character
+ int prev_c1; // first composing char for prev_c
+} LineState;
+#define LINE_STATE(p) { p, 0, 0 }
+
+/// Whether to call "ui_call_grid_resize" in win_grid_alloc
+static bool send_grid_resize = false;
+
+/// Highlight ids are no longer valid. Force retransmission
+static bool highlights_invalid = false;
+
+static bool conceal_cursor_used = false;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "screen.c.generated.h"
#endif
@@ -168,7 +170,7 @@ void redraw_later(int type)
void redraw_win_later(win_T *wp, int type)
{
- if (wp->w_redr_type < type) {
+ if (!exiting && wp->w_redr_type < type) {
wp->w_redr_type = type;
if (type >= NOT_VALID)
wp->w_lines_valid = 0;
@@ -178,17 +180,6 @@ void redraw_win_later(win_T *wp, int type)
}
/*
- * Force a complete redraw later. Also resets the highlighting. To be used
- * after executing a shell command that messes up the screen.
- */
-void redraw_later_clear(void)
-{
- redraw_all_later(CLEAR);
- /* Use attributes that is very unlikely to appear in text. */
- screen_attr = HL_BOLD | HL_UNDERLINE | HL_INVERSE;
-}
-
-/*
* Mark all windows to be redrawn later.
*/
void redraw_all_later(int type)
@@ -196,6 +187,16 @@ void redraw_all_later(int type)
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
redraw_win_later(wp, type);
}
+ // This may be needed when switching tabs.
+ if (must_redraw < type) {
+ must_redraw = type;
+ }
+}
+
+void screen_invalidate_highlights(void)
+{
+ redraw_all_later(NOT_VALID);
+ highlights_invalid = true;
}
/*
@@ -215,6 +216,15 @@ void redraw_buf_later(buf_T *buf, int type)
}
}
+void redraw_buf_line_later(buf_T *buf, linenr_T line)
+{
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_buffer == buf) {
+ redrawWinline(wp, line);
+ }
+ }
+}
+
/*
* Changed something in the current window, at buffer line "lnum", that
* requires that line and possibly other lines to be redrawn.
@@ -224,24 +234,20 @@ void redraw_buf_later(buf_T *buf, int type)
* may become invalid and the whole window will have to be redrawn.
*/
void
-redrawWinline (
- linenr_T lnum,
- int invalid /* window line height is invalid now */
+redrawWinline(
+ win_T *wp,
+ linenr_T lnum
)
{
- int i;
-
- if (curwin->w_redraw_top == 0 || curwin->w_redraw_top > lnum)
- curwin->w_redraw_top = lnum;
- if (curwin->w_redraw_bot == 0 || curwin->w_redraw_bot < lnum)
- curwin->w_redraw_bot = lnum;
- redraw_later(VALID);
-
- if (invalid) {
- /* A w_lines[] entry for this lnum has become invalid. */
- i = find_wl_entry(curwin, lnum);
- if (i >= 0)
- curwin->w_lines[i].wl_valid = FALSE;
+ if (lnum >= wp->w_topline
+ && lnum < wp->w_botline) {
+ if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum) {
+ wp->w_redraw_top = lnum;
+ }
+ if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum) {
+ wp->w_redraw_bot = lnum;
+ }
+ redraw_win_later(wp, VALID);
}
}
@@ -254,12 +260,12 @@ void update_curbuf(int type)
update_screen(type);
}
-/*
- * update_screen()
- *
- * Based on the current value of curwin->w_topline, transfer a screenfull
- * of stuff from Filemem to ScreenLines[], and update curwin->w_botline.
- */
+/// Redraw the parts of the screen that is marked for redraw.
+///
+/// Most code shouldn't call this directly, rather use redraw_later() and
+/// and redraw_all_later() to mark parts of the screen as needing a redraw.
+///
+/// @param type set to a NOT_VALID to force redraw of entire screen
void update_screen(int type)
{
static int did_intro = FALSE;
@@ -302,16 +308,33 @@ void update_screen(int type)
* if the screen was scrolled up when displaying a message, scroll it down
*/
if (msg_scrolled) {
- clear_cmdline = TRUE;
- if (msg_scrolled > Rows - 5) /* clearing is faster */
+ ui_call_win_scroll_over_reset();
+ clear_cmdline = true;
+ if (dy_flags & DY_MSGSEP) {
+ int valid = MAX(Rows - msg_scrollsize(), 0);
+ if (valid == 0) {
+ redraw_tabline = true;
+ }
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (W_ENDROW(wp) > valid) {
+ wp->w_redr_type = NOT_VALID;
+ wp->w_lines_valid = 0;
+ }
+ if (W_ENDROW(wp) + wp->w_status_height > valid) {
+ wp->w_redr_status = true;
+ }
+ }
+ } else if (msg_scrolled > default_grid.Rows - 5) { // clearing is faster
type = CLEAR;
- else if (type != CLEAR) {
- check_for_delay(FALSE);
- if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows, NULL) == FAIL)
+ } else if (type != CLEAR) {
+ check_for_delay(false);
+ if (grid_ins_lines(&default_grid, 0, msg_scrolled, (int)Rows,
+ 0, (int)Columns) == FAIL) {
type = CLEAR;
+ }
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_winrow < msg_scrolled) {
- if (wp->w_winrow + wp->w_height > msg_scrolled
+ if (W_ENDROW(wp) > msg_scrolled
&& wp->w_redr_type < REDRAW_TOP
&& wp->w_lines_valid > 0
&& wp->w_topline == wp->w_lines[0].wl_lnum) {
@@ -319,7 +342,7 @@ void update_screen(int type)
wp->w_redr_type = REDRAW_TOP;
} else {
wp->w_redr_type = NOT_VALID;
- if (wp->w_winrow + wp->w_height + wp->w_status_height
+ if (W_ENDROW(wp) + wp->w_status_height
<= msg_scrolled) {
wp->w_redr_status = TRUE;
}
@@ -340,9 +363,14 @@ void update_screen(int type)
if (need_highlight_changed)
highlight_changed();
- if (type == CLEAR) { /* first clear screen */
- screenclear(); /* will reset clear_cmdline */
+ if (type == CLEAR) { // first clear screen
+ screenclear(); // will reset clear_cmdline
+ cmdline_screen_cleared(); // clear external cmdline state
type = NOT_VALID;
+ // must_redraw may be set indirectly, avoid another redraw later
+ must_redraw = 0;
+ } else if (highlights_invalid) {
+ grid_invalidate(&default_grid);
}
if (clear_cmdline) /* going to clear cmdline (done below) */
@@ -375,15 +403,24 @@ void update_screen(int type)
))
curwin->w_redr_type = type;
- /* Redraw the tab pages line if needed. */
- if (redraw_tabline || type >= NOT_VALID)
+ // Redraw the tab pages line if needed.
+ if (redraw_tabline || type >= NOT_VALID) {
+ update_window_hl(curwin, type >= NOT_VALID);
+ FOR_ALL_TABS(tp) {
+ if (tp != curtab) {
+ update_window_hl(tp->tp_curwin, type >= NOT_VALID);
+ }
+ }
draw_tabline();
+ }
/*
* Correct stored syntax highlighting info for changes in each displayed
* buffer. Each buffer must only be done once.
*/
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ update_window_hl(wp, type >= NOT_VALID);
+
if (wp->w_buffer->b_mod_set) {
win_T *wwp;
@@ -416,13 +453,16 @@ void update_screen(int type)
/* redraw status line after the window to minimize cursor movement */
if (wp->w_redr_status) {
- win_redr_status(wp);
+ win_redr_status(wp, true); // any popup menu will be redrawn below
}
}
+ send_grid_resize = false;
+ highlights_invalid = false;
end_search_hl();
- /* May need to redraw the popup menu. */
- if (pum_visible())
+ // May need to redraw the popup menu.
+ if (pum_drawn()) {
pum_redraw();
+ }
/* Reset b_mod_set flags. Going through all windows is probably faster
* than going through all buffers (there could be many buffers). */
@@ -467,122 +507,29 @@ int conceal_cursor_line(win_T *wp)
return vim_strchr(wp->w_p_cocu, c) != NULL;
}
-/*
- * Check if the cursor line needs to be redrawn because of 'concealcursor'.
- */
-void conceal_check_cursur_line(void)
+// Check if the cursor line needs to be redrawn because of 'concealcursor'.
+//
+// When cursor is moved at the same time, both lines will be redrawn regardless.
+void conceal_check_cursor_line(void)
{
- if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)) {
- need_cursor_line_redraw = TRUE;
- /* Need to recompute cursor column, e.g., when starting Visual mode
- * without concealing. */
- curs_columns(TRUE);
+ bool should_conceal = conceal_cursor_line(curwin);
+ if (curwin->w_p_cole > 0 && (conceal_cursor_used != should_conceal)) {
+ redrawWinline(curwin, curwin->w_cursor.lnum);
+ // Need to recompute cursor column, e.g., when starting Visual mode
+ // without concealing. */
+ curs_columns(true);
}
}
-void update_single_line(win_T *wp, linenr_T lnum)
-{
- int row;
- int j;
-
- if (lnum >= wp->w_topline && lnum < wp->w_botline
- && foldedCount(wp, lnum, &win_foldinfo) == 0) {
- row = 0;
- for (j = 0; j < wp->w_lines_valid; ++j) {
- if (lnum == wp->w_lines[j].wl_lnum) {
- init_search_hl(wp);
- start_search_hl();
- prepare_search_hl(wp, lnum);
- win_line(wp, lnum, row, row + wp->w_lines[j].wl_size, false);
- end_search_hl();
- break;
- }
- row += wp->w_lines[j].wl_size;
- }
- }
- need_cursor_line_redraw = FALSE;
-}
-
-
-/*
- * Prepare for updating one or more windows.
- * Caller must check for "updating_screen" already set to avoid recursiveness.
- */
-static void update_prepare(void)
-{
- updating_screen = TRUE;
- start_search_hl();
-}
-
-/*
- * Finish updating one or more windows.
- */
-static void update_finish(void)
-{
- if (redraw_cmdline) {
- showmode();
- }
-
- end_search_hl();
- updating_screen = FALSE;
-}
-
-void update_debug_sign(buf_T *buf, linenr_T lnum)
-{
- int doit = FALSE;
- win_foldinfo.fi_level = 0;
-
- /* update/delete a specific mark */
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if (buf != NULL && lnum > 0) {
- if (wp->w_buffer == buf && lnum >= wp->w_topline
- && lnum < wp->w_botline) {
- if (wp->w_redraw_top == 0 || wp->w_redraw_top > lnum) {
- wp->w_redraw_top = lnum;
- }
- if (wp->w_redraw_bot == 0 || wp->w_redraw_bot < lnum) {
- wp->w_redraw_bot = lnum;
- }
- redraw_win_later(wp, VALID);
- }
- } else {
- redraw_win_later(wp, VALID);
- }
- if (wp->w_redr_type != 0) {
- doit = TRUE;
- }
- }
-
- /* Return when there is nothing to do, screen updating is already
- * happening (recursive call) or still starting up. */
- if (!doit || updating_screen || starting) {
- return;
- }
-
- /* update all windows that need updating */
- update_prepare();
-
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if (wp->w_redr_type != 0) {
- win_update(wp);
- }
- if (wp->w_redr_status) {
- win_redr_status(wp);
- }
- }
-
- update_finish();
-}
-
-/*
- * Return TRUE when window "wp" has a column to draw signs in.
- */
-static int draw_signcolumn(win_T *wp)
+/// Whether cursorline is drawn in a special way
+///
+/// If true, both old and new cursorline will need
+/// need to be redrawn when moving cursor within windows.
+bool win_cursorline_standout(win_T *wp)
{
- return (wp->w_buffer->b_signlist != NULL);
+ return wp->w_p_cul || (wp->w_p_cole > 0 && !conceal_cursor_line(wp));
}
-
/*
* Update a single window.
*
@@ -639,11 +586,10 @@ static void win_update(win_T *wp)
static int recursive = FALSE; /* being called recursively */
int old_botline = wp->w_botline;
long fold_count;
- /* remember what happened to the previous line, to know if
- * check_visual_highlight() can be used */
-#define DID_NONE 1 /* didn't update a line */
-#define DID_LINE 2 /* updated a normal line */
-#define DID_FOLD 3 /* updated a folded line */
+ // Remember what happened to the previous line.
+#define DID_NONE 1 // didn't update a line
+#define DID_LINE 2 // updated a normal line
+#define DID_FOLD 3 // updated a folded line
int did_update = DID_NONE;
linenr_T syntax_last_parsed = 0; /* last parsed text line */
linenr_T mod_top = 0;
@@ -652,20 +598,22 @@ static void win_update(win_T *wp)
type = wp->w_redr_type;
- if (type == NOT_VALID) {
- wp->w_redr_status = TRUE;
+ win_grid_alloc(wp);
+
+ if (type >= NOT_VALID) {
+ wp->w_redr_status = true;
wp->w_lines_valid = 0;
}
- /* Window is zero-height: nothing to draw. */
- if (wp->w_height == 0) {
+ // Window is zero-height: nothing to draw.
+ if (wp->w_grid.Rows == 0) {
wp->w_redr_type = 0;
return;
}
- /* Window is zero-width: Only need to draw the separator. */
- if (wp->w_width == 0) {
- /* draw the vertical separator right of this window */
+ // Window is zero-width: Only need to draw the separator.
+ if (wp->w_grid.Columns == 0) {
+ // draw the vertical separator right of this window
draw_vsep_win(wp, 0);
wp->w_redr_type = 0;
return;
@@ -679,12 +627,18 @@ static void win_update(win_T *wp)
if (wp->w_nrwidth != i) {
type = NOT_VALID;
wp->w_nrwidth = i;
- } else if (buf->b_mod_set && buf->b_mod_xlines != 0 && wp->w_redraw_top != 0) {
- /*
- * When there are both inserted/deleted lines and specific lines to be
- * redrawn, w_redraw_top and w_redraw_bot may be invalid, just redraw
- * everything (only happens when redrawing is off for while).
- */
+
+ if (buf->terminal) {
+ terminal_resize(buf->terminal,
+ (uint16_t)(MAX(0, wp->w_grid.Columns - win_col_off(wp))),
+ (uint16_t)wp->w_grid.Rows);
+ }
+ } else if (buf->b_mod_set
+ && buf->b_mod_xlines != 0
+ && wp->w_redraw_top != 0) {
+ // When there are both inserted/deleted lines and specific lines to be
+ // redrawn, w_redraw_top and w_redraw_bot may be invalid, just redraw
+ // everything (only happens when redrawing is off for while).
type = NOT_VALID;
} else {
/*
@@ -764,16 +718,18 @@ static void win_update(win_T *wp)
}
}
- (void)hasFoldingWin(wp, mod_top, &mod_top, NULL, TRUE, NULL);
- if (mod_top > lnumt)
+ (void)hasFoldingWin(wp, mod_top, &mod_top, NULL, true, NULL);
+ if (mod_top > lnumt) {
mod_top = lnumt;
+ }
- /* Now do the same for the bottom line (one above mod_bot). */
- --mod_bot;
- (void)hasFoldingWin(wp, mod_bot, NULL, &mod_bot, TRUE, NULL);
- ++mod_bot;
- if (mod_bot < lnumb)
+ // Now do the same for the bottom line (one above mod_bot).
+ mod_bot--;
+ (void)hasFoldingWin(wp, mod_bot, NULL, &mod_bot, true, NULL);
+ mod_bot++;
+ if (mod_bot < lnumb) {
mod_bot = lnumb;
+ }
}
/* When a change starts above w_topline and the end is below
@@ -814,13 +770,6 @@ static void win_update(win_T *wp)
type = VALID;
}
- /* Trick: we want to avoid clearing the screen twice. screenclear() will
- * set "screen_cleared" to TRUE. The special value MAYBE (which is still
- * non-zero and thus not FALSE) will indicate that screenclear() was not
- * called. */
- if (screen_cleared)
- screen_cleared = MAYBE;
-
/*
* If there are no changes on the screen that require a complete redraw,
* handle three cases:
@@ -852,29 +801,26 @@ static void win_update(win_T *wp)
/* count the number of lines we are off, counting a sequence
* of folded lines as one */
j = 0;
- for (ln = wp->w_topline; ln < wp->w_lines[0].wl_lnum; ++ln) {
- ++j;
- if (j >= wp->w_height - 2)
+ for (ln = wp->w_topline; ln < wp->w_lines[0].wl_lnum; ln++) {
+ j++;
+ if (j >= wp->w_grid.Rows - 2) {
break;
- (void)hasFoldingWin(wp, ln, NULL, &ln, TRUE, NULL);
+ }
+ (void)hasFoldingWin(wp, ln, NULL, &ln, true, NULL);
}
} else
j = wp->w_lines[0].wl_lnum - wp->w_topline;
- if (j < wp->w_height - 2) { /* not too far off */
+ if (j < wp->w_grid.Rows - 2) { // not too far off
i = plines_m_win(wp, wp->w_topline, wp->w_lines[0].wl_lnum - 1);
/* insert extra lines for previously invisible filler lines */
if (wp->w_lines[0].wl_lnum != wp->w_topline)
i += diff_check_fill(wp, wp->w_lines[0].wl_lnum)
- wp->w_old_topfill;
- if (i < wp->w_height - 2) { /* less than a screen off */
- /*
- * Try to insert the correct number of lines.
- * If not the last window, delete the lines at the bottom.
- * win_ins_lines may fail when the terminal can't do it.
- */
- if (i > 0)
- check_for_delay(FALSE);
- if (win_ins_lines(wp, 0, i, FALSE, wp == firstwin) == OK) {
+ if (i < wp->w_grid.Rows - 2) { // less than a screen off
+ // Try to insert the correct number of lines.
+ // If not the last window, delete the lines at the bottom.
+ // win_ins_lines may fail when the terminal can't do it.
+ if (win_ins_lines(wp, 0, i) == OK) {
if (wp->w_lines_valid != 0) {
/* Need to update rows that are new, stop at the
* first one that scrolled down. */
@@ -883,12 +829,15 @@ static void win_update(win_T *wp)
/* Move the entries that were scrolled, disable
* the entries for the lines to be redrawn. */
- if ((wp->w_lines_valid += j) > wp->w_height)
- wp->w_lines_valid = wp->w_height;
- for (idx = wp->w_lines_valid; idx - j >= 0; idx--)
+ if ((wp->w_lines_valid += j) > wp->w_grid.Rows) {
+ wp->w_lines_valid = wp->w_grid.Rows;
+ }
+ for (idx = wp->w_lines_valid; idx - j >= 0; idx--) {
wp->w_lines[idx] = wp->w_lines[idx - j];
- while (idx >= 0)
- wp->w_lines[idx--].wl_valid = FALSE;
+ }
+ while (idx >= 0) {
+ wp->w_lines[idx--].wl_valid = false;
+ }
}
} else
mid_start = 0; /* redraw all lines */
@@ -932,11 +881,11 @@ static void win_update(win_T *wp)
/* ... but don't delete new filler lines. */
row -= wp->w_topfill;
if (row > 0) {
- check_for_delay(FALSE);
- if (win_del_lines(wp, 0, row, FALSE, wp == firstwin) == OK)
- bot_start = wp->w_height - row;
- else
- mid_start = 0; /* redraw all lines */
+ if (win_del_lines(wp, 0, row) == OK) {
+ bot_start = wp->w_grid.Rows - row;
+ } else {
+ mid_start = 0; // redraw all lines
+ }
}
if ((row == 0 || bot_start < 999) && wp->w_lines_valid != 0) {
/*
@@ -952,7 +901,7 @@ static void win_update(win_T *wp)
/* stop at line that didn't fit, unless it is still
* valid (no lines deleted) */
if (row > 0 && bot_start + row
- + (int)wp->w_lines[j].wl_size > wp->w_height) {
+ + (int)wp->w_lines[j].wl_size > wp->w_grid.Rows) {
wp->w_lines_valid = idx + 1;
break;
}
@@ -968,45 +917,26 @@ static void win_update(win_T *wp)
* when it won't get updated below. */
if (wp->w_p_diff && bot_start > 0)
wp->w_lines[0].wl_size =
- plines_win_nofill(wp, wp->w_topline, TRUE)
+ plines_win_nofill(wp, wp->w_topline, true)
+ wp->w_topfill;
}
}
}
- /* When starting redraw in the first line, redraw all lines. When
- * there is only one window it's probably faster to clear the screen
- * first. */
+ // When starting redraw in the first line, redraw all lines.
if (mid_start == 0) {
- mid_end = wp->w_height;
- if (lastwin == firstwin) {
- /* Clear the screen when it was not done by win_del_lines() or
- * win_ins_lines() above, "screen_cleared" is FALSE or MAYBE
- * then. */
- if (screen_cleared != TRUE)
- screenclear();
- /* The screen was cleared, redraw the tab pages line. */
- if (redraw_tabline)
- draw_tabline();
- }
- }
-
- /* When win_del_lines() or win_ins_lines() caused the screen to be
- * cleared (only happens for the first window) or when screenclear()
- * was called directly above, "must_redraw" will have been set to
- * NOT_VALID, need to reset it here to avoid redrawing twice. */
- if (screen_cleared == TRUE)
- must_redraw = 0;
+ mid_end = wp->w_grid.Rows;
+ }
} else {
/* Not VALID or INVERTED: redraw all lines. */
mid_start = 0;
- mid_end = wp->w_height;
+ mid_end = wp->w_grid.Rows;
}
if (type == SOME_VALID) {
/* SOME_VALID: redraw all lines. */
mid_start = 0;
- mid_end = wp->w_height;
+ mid_end = wp->w_grid.Rows;
type = NOT_VALID;
}
@@ -1016,14 +946,10 @@ static void win_update(win_T *wp)
linenr_T from, to;
if (VIsual_active) {
- if (VIsual_active
- && (VIsual_mode != wp->w_old_visual_mode
- || type == INVERTED_ALL)) {
- /*
- * If the type of Visual selection changed, redraw the whole
- * selection. Also when the ownership of the X selection is
- * gained or lost.
- */
+ if (VIsual_mode != wp->w_old_visual_mode || type == INVERTED_ALL) {
+ // If the type of Visual selection changed, redraw the whole
+ // selection. Also when the ownership of the X selection is
+ // gained or lost.
if (curwin->w_cursor.lnum < VIsual.lnum) {
from = curwin->w_cursor.lnum;
to = VIsual.lnum;
@@ -1155,8 +1081,8 @@ static void win_update(win_T *wp)
++lnum;
}
srow += mid_start;
- mid_end = wp->w_height;
- for (; idx < wp->w_lines_valid; ++idx) { /* find end */
+ mid_end = wp->w_grid.Rows;
+ for (; idx < wp->w_lines_valid; idx++) { // find end
if (wp->w_lines[idx].wl_valid
&& wp->w_lines[idx].wl_lnum >= to + 1) {
/* Only update until first row of this line */
@@ -1196,8 +1122,8 @@ static void win_update(win_T *wp)
for (;; ) {
/* stop updating when reached the end of the window (check for _past_
* the end of the window is at the end of the loop) */
- if (row == wp->w_height) {
- didline = TRUE;
+ if (row == wp->w_grid.Rows) {
+ didline = true;
break;
}
@@ -1211,15 +1137,13 @@ static void win_update(win_T *wp)
* with. It is used further down when the line doesn't fit. */
srow = row;
- /*
- * Update a line when it is in an area that needs updating, when it
- * has changes or w_lines[idx] is invalid.
- * bot_start may be halfway through a wrapped line after using
- * win_del_lines(), check if the current line includes it.
- * When syntax folding is being used, the saved syntax states will
- * already have been updated, we can't see where the syntax state is
- * the same again, just update until the end of the window.
- */
+ // Update a line when it is in an area that needs updating, when it
+ // has changes or w_lines[idx] is invalid.
+ // "bot_start" may be halfway a wrapped line after using
+ // win_del_lines(), check if the current line includes it.
+ // When syntax folding is being used, the saved syntax states will
+ // already have been updated, we can't see where the syntax state is
+ // the same again, just update until the end of the window.
if (row < top_end
|| (row >= mid_start && row < mid_end)
|| top_to_mod
@@ -1288,17 +1212,17 @@ static void win_update(win_T *wp)
/* Able to count old number of rows: Count new window
* rows, and may insert/delete lines */
j = idx;
- for (l = lnum; l < mod_bot; ++l) {
- if (hasFoldingWin(wp, l, NULL, &l, TRUE, NULL))
- ++new_rows;
- else if (l == wp->w_topline)
- new_rows += plines_win_nofill(wp, l, TRUE)
- + wp->w_topfill;
- else
- new_rows += plines_win(wp, l, TRUE);
- ++j;
- if (new_rows > wp->w_height - row - 2) {
- /* it's getting too much, must redraw the rest */
+ for (l = lnum; l < mod_bot; l++) {
+ if (hasFoldingWin(wp, l, NULL, &l, true, NULL)) {
+ new_rows++;
+ } else if (l == wp->w_topline) {
+ new_rows += plines_win_nofill(wp, l, true) + wp->w_topfill;
+ } else {
+ new_rows += plines_win(wp, l, true);
+ }
+ j++;
+ if (new_rows > wp->w_grid.Rows - row - 2) {
+ // it's getting too much, must redraw the rest
new_rows = 9999;
break;
}
@@ -1309,31 +1233,29 @@ static void win_update(win_T *wp)
* remaining text or scrolling fails, must redraw the
* rest. If scrolling works, must redraw the text
* below the scrolled text. */
- if (row - xtra_rows >= wp->w_height - 2)
+ if (row - xtra_rows >= wp->w_grid.Rows - 2) {
mod_bot = MAXLNUM;
- else {
- check_for_delay(FALSE);
- if (win_del_lines(wp, row,
- -xtra_rows, FALSE, FALSE) == FAIL)
+ } else {
+ if (win_del_lines(wp, row, -xtra_rows) == FAIL) {
mod_bot = MAXLNUM;
- else
- bot_start = wp->w_height + xtra_rows;
+ } else {
+ bot_start = wp->w_grid.Rows + xtra_rows;
+ }
}
} else if (xtra_rows > 0) {
/* May scroll text down. If there is not enough
* remaining text of scrolling fails, must redraw the
* rest. */
- if (row + xtra_rows >= wp->w_height - 2)
+ if (row + xtra_rows >= wp->w_grid.Rows - 2) {
mod_bot = MAXLNUM;
- else {
- check_for_delay(FALSE);
- if (win_ins_lines(wp, row + old_rows,
- xtra_rows, FALSE, FALSE) == FAIL)
+ } else {
+ if (win_ins_lines(wp, row + old_rows, xtra_rows) == FAIL) {
mod_bot = MAXLNUM;
- else if (top_end > row + old_rows)
- /* Scrolled the part at the top that requires
- * updating down. */
+ } else if (top_end > row + old_rows) {
+ // Scrolled the part at the top that requires
+ // updating down.
top_end += xtra_rows;
+ }
}
}
@@ -1353,7 +1275,7 @@ static void win_update(win_T *wp)
wp->w_lines[j] = wp->w_lines[i];
/* stop at a line that won't fit */
if (x + (int)wp->w_lines[j].wl_size
- > wp->w_height) {
+ > wp->w_grid.Rows) {
wp->w_lines_valid = j + 1;
break;
}
@@ -1366,10 +1288,12 @@ static void win_update(win_T *wp)
/* move entries in w_lines[] downwards */
j -= i;
wp->w_lines_valid += j;
- if (wp->w_lines_valid > wp->w_height)
- wp->w_lines_valid = wp->w_height;
- for (i = wp->w_lines_valid; i - j >= idx; --i)
+ if (wp->w_lines_valid > wp->w_grid.Rows) {
+ wp->w_lines_valid = wp->w_grid.Rows;
+ }
+ for (i = wp->w_lines_valid; i - j >= idx; i--) {
wp->w_lines[i] = wp->w_lines[i - j];
+ }
/* The w_lines[] entries for inserted lines are
* now invalid, but wl_size may be used above.
@@ -1400,13 +1324,13 @@ static void win_update(win_T *wp)
&& wp->w_lines[idx].wl_valid
&& wp->w_lines[idx].wl_lnum == lnum
&& lnum > wp->w_topline
- && !(dy_flags & DY_LASTLINE)
- && srow + wp->w_lines[idx].wl_size > wp->w_height
+ && !(dy_flags & (DY_LASTLINE | DY_TRUNCATE))
+ && srow + wp->w_lines[idx].wl_size > wp->w_grid.Rows
&& diff_check_fill(wp, lnum) == 0
) {
/* This line is not going to fit. Don't draw anything here,
* will draw "@ " lines below. */
- row = wp->w_height + 1;
+ row = wp->w_grid.Rows + 1;
} else {
prepare_search_hl(wp, lnum);
/* Let the syntax stuff know we skipped a few lines. */
@@ -1417,7 +1341,7 @@ static void win_update(win_T *wp)
/*
* Display one line.
*/
- row = win_line(wp, lnum, srow, wp->w_height, mod_top == 0);
+ row = win_line(wp, lnum, srow, wp->w_grid.Rows, mod_top == 0, false);
wp->w_lines[idx].wl_folded = FALSE;
wp->w_lines[idx].wl_lastlnum = lnum;
@@ -1426,12 +1350,14 @@ static void win_update(win_T *wp)
}
wp->w_lines[idx].wl_lnum = lnum;
- wp->w_lines[idx].wl_valid = TRUE;
- if (row > wp->w_height) { /* past end of screen */
- /* we may need the size of that too long line later on */
- if (dollar_vcol == -1)
- wp->w_lines[idx].wl_size = plines_win(wp, lnum, TRUE);
- ++idx;
+ wp->w_lines[idx].wl_valid = true;
+
+ if (row > wp->w_grid.Rows) { // past end of grid
+ // we may need the size of that too long line later on
+ if (dollar_vcol == -1) {
+ wp->w_lines[idx].wl_size = plines_win(wp, lnum, true);
+ }
+ idx++;
break;
}
if (dollar_vcol == -1)
@@ -1439,10 +1365,22 @@ static void win_update(win_T *wp)
++idx;
lnum += fold_count + 1;
} else {
- /* This line does not need updating, advance to the next one */
+ if (wp->w_p_rnu) {
+ // 'relativenumber' set: The text doesn't need to be drawn, but
+ // the number column nearly always does.
+ fold_count = foldedCount(wp, lnum, &win_foldinfo);
+ if (fold_count != 0) {
+ fold_line(wp, fold_count, &win_foldinfo, lnum, row);
+ } else {
+ (void)win_line(wp, lnum, srow, wp->w_grid.Rows, true, true);
+ }
+ }
+
+ // This line does not need to be drawn, advance to the next one.
row += wp->w_lines[idx++].wl_size;
- if (row > wp->w_height) /* past end of screen */
+ if (row > wp->w_grid.Rows) { // past end of screen
break;
+ }
lnum = wp->w_lines[idx - 1].wl_lastlnum + 1;
did_update = DID_NONE;
}
@@ -1473,33 +1411,40 @@ static void win_update(win_T *wp)
wp->w_empty_rows = 0;
wp->w_filler_rows = 0;
if (!eof && !didline) {
+ int at_attr = hl_combine_attr(wp->w_hl_attr_normal,
+ win_hl_attr(wp, HLF_AT));
if (lnum == wp->w_topline) {
/*
* Single line that does not fit!
* Don't overwrite it, it can be edited.
*/
wp->w_botline = lnum + 1;
- } else if (diff_check_fill(wp, lnum) >= wp->w_height - srow) {
- /* Window ends in filler lines. */
+ } else if (diff_check_fill(wp, lnum) >= wp->w_grid.Rows - srow) {
+ // Window ends in filler lines.
wp->w_botline = lnum;
- wp->w_filler_rows = wp->w_height - srow;
- } else if (dy_flags & DY_LASTLINE) { /* 'display' has "lastline" */
- /*
- * Last line isn't finished: Display "@@@" at the end.
- */
- screen_fill(wp->w_winrow + wp->w_height - 1,
- wp->w_winrow + wp->w_height,
- W_ENDCOL(wp) - 3, W_ENDCOL(wp),
- '@', '@', hl_attr(HLF_AT));
+ wp->w_filler_rows = wp->w_grid.Rows - srow;
+ } else if (dy_flags & DY_TRUNCATE) { // 'display' has "truncate"
+ int scr_row = wp->w_grid.Rows - 1;
+
+ // Last line isn't finished: Display "@@@" in the last screen line.
+ grid_puts_len(&wp->w_grid, (char_u *)"@@", 2, scr_row, 0, at_attr);
+
+ grid_fill(&wp->w_grid, scr_row, scr_row + 1, 2, (int)wp->w_grid.Columns,
+ '@', ' ', at_attr);
+ set_empty_rows(wp, srow);
+ wp->w_botline = lnum;
+ } else if (dy_flags & DY_LASTLINE) { // 'display' has "lastline"
+ // Last line isn't finished: Display "@@@" at the end.
+ grid_fill(&wp->w_grid, wp->w_grid.Rows - 1, wp->w_grid.Rows,
+ wp->w_grid.Columns - 3, wp->w_grid.Columns, '@', '@', at_attr);
set_empty_rows(wp, srow);
wp->w_botline = lnum;
} else {
- win_draw_end(wp, '@', ' ', srow, wp->w_height, HLF_AT);
+ win_draw_end(wp, '@', ' ', srow, wp->w_grid.Rows, HLF_AT);
wp->w_botline = lnum;
}
} else {
- draw_vsep_win(wp, row);
- if (eof) { /* we hit the end of the file */
+ if (eof) { // we hit the end of the file
wp->w_botline = buf->b_ml.ml_line_count + 1;
j = diff_check_fill(wp, wp->w_botline);
if (j > 0 && !wp->w_botfill) {
@@ -1510,17 +1455,22 @@ static void win_update(win_T *wp)
i = '-';
else
i = fill_diff;
- if (row + j > wp->w_height)
- j = wp->w_height - row;
+ if (row + j > wp->w_grid.Rows) {
+ j = wp->w_grid.Rows - row;
+ }
win_draw_end(wp, i, i, row, row + (int)j, HLF_DED);
row += j;
}
} else if (dollar_vcol == -1)
wp->w_botline = lnum;
- /* make sure the rest of the screen is blank */
- /* put '~'s on rows that aren't part of the file. */
- win_draw_end(wp, '~', ' ', row, wp->w_height, HLF_EOB);
+ // make sure the rest of the screen is blank
+ // write the 'fill_eob' character to rows that aren't part of the file.
+ win_draw_end(wp, fill_eob, ' ', row, wp->w_grid.Rows, HLF_EOB);
+ }
+
+ if (wp->w_redr_type >= REDRAW_TOP) {
+ draw_vsep_win(wp, 0);
}
/* Reset the type of redrawing required, the window has been updated. */
@@ -1563,6 +1513,20 @@ static void win_update(win_T *wp)
got_int = save_got_int;
}
+/// Returns width of the signcolumn that should be used for the whole window
+///
+/// @param wp window we want signcolumn width from
+/// @return max width of signcolumn (cell unit)
+///
+/// @note Returns a constant for now but hopefully we can improve neovim so that
+/// the returned value width adapts to the maximum number of marks to draw
+/// for the window
+/// TODO(teto)
+int win_signcol_width(win_T *wp)
+{
+ // 2 is vim default value
+ return 2;
+}
/*
* Clear the rest of the window and mark the unused lines with "c1". use "c2"
@@ -1574,77 +1538,74 @@ static void win_draw_end(win_T *wp, int c1, int c2, int row, int endrow, hlf_T h
# define FDC_OFF n
int fdc = compute_foldcolumn(wp, 0);
+ int attr = hl_combine_attr(wp->w_hl_attr_normal, win_hl_attr(wp, hl));
+
if (wp->w_p_rl) {
// No check for cmdline window: should never be right-left.
n = fdc;
if (n > 0) {
- /* draw the fold column at the right */
- if (n > wp->w_width)
- n = wp->w_width;
- screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
- W_ENDCOL(wp) - n, W_ENDCOL(wp),
- ' ', ' ', hl_attr(HLF_FC));
+ // draw the fold column at the right
+ if (n > wp->w_grid.Columns) {
+ n = wp->w_grid.Columns;
+ }
+ grid_fill(&wp->w_grid, row, endrow, wp->w_grid.Columns - n,
+ wp->w_grid.Columns, ' ', ' ', win_hl_attr(wp, HLF_FC));
}
- if (draw_signcolumn(wp)) {
- int nn = n + 2;
+ if (signcolumn_on(wp)) {
+ int nn = n + win_signcol_width(wp);
- /* draw the sign column left of the fold column */
- if (nn > wp->w_width) {
- nn = wp->w_width;
+ // draw the sign column left of the fold column
+ if (nn > wp->w_grid.Columns) {
+ nn = wp->w_grid.Columns;
}
- screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
- W_ENDCOL(wp) - nn, W_ENDCOL(wp) - n,
- ' ', ' ', hl_attr(HLF_SC));
+ grid_fill(&wp->w_grid, row, endrow, wp->w_grid.Columns - nn,
+ wp->w_grid.Columns - n, ' ', ' ', win_hl_attr(wp, HLF_SC));
n = nn;
}
- screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
- wp->w_wincol, W_ENDCOL(wp) - 1 - FDC_OFF,
- c2, c2, hl_attr(hl));
- screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
- W_ENDCOL(wp) - 1 - FDC_OFF, W_ENDCOL(wp) - FDC_OFF,
- c1, c2, hl_attr(hl));
+ grid_fill(&wp->w_grid, row, endrow, 0, wp->w_grid.Columns - 1 - FDC_OFF,
+ c2, c2, attr);
+ grid_fill(&wp->w_grid, row, endrow,
+ wp->w_grid.Columns - 1 - FDC_OFF, wp->w_grid.Columns - FDC_OFF,
+ c1, c2, attr);
} else {
if (cmdwin_type != 0 && wp == curwin) {
/* draw the cmdline character in the leftmost column */
n = 1;
- if (n > wp->w_width)
- n = wp->w_width;
- screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
- wp->w_wincol, wp->w_wincol + n,
- cmdwin_type, ' ', hl_attr(HLF_AT));
+ if (n > wp->w_grid.Columns) {
+ n = wp->w_grid.Columns;
+ }
+ grid_fill(&wp->w_grid, row, endrow, 0, n, cmdwin_type, ' ',
+ win_hl_attr(wp, HLF_AT));
}
if (fdc > 0) {
int nn = n + fdc;
- /* draw the fold column at the left */
- if (nn > wp->w_width)
- nn = wp->w_width;
- screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
- wp->w_wincol + n, wp->w_wincol + nn,
- ' ', ' ', hl_attr(HLF_FC));
+ // draw the fold column at the left
+ if (nn > wp->w_grid.Columns) {
+ nn = wp->w_grid.Columns;
+ }
+ grid_fill(&wp->w_grid, row, endrow, n, nn, ' ', ' ',
+ win_hl_attr(wp, HLF_FC));
n = nn;
}
- if (draw_signcolumn(wp))
- {
- int nn = n + 2;
+ if (signcolumn_on(wp)) {
+ int nn = n + win_signcol_width(wp);
- /* draw the sign column after the fold column */
- if (nn > wp->w_width) {
- nn = wp->w_width;
+ // draw the sign column after the fold column
+ if (nn > wp->w_grid.Columns) {
+ nn = wp->w_grid.Columns;
}
- screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
- wp->w_wincol + n, wp->w_wincol + nn,
- ' ', ' ', hl_attr(HLF_SC));
+ grid_fill(&wp->w_grid, row, endrow, n, nn, ' ', ' ',
+ win_hl_attr(wp, HLF_SC));
n = nn;
}
- screen_fill(wp->w_winrow + row, wp->w_winrow + endrow,
- wp->w_wincol + FDC_OFF, W_ENDCOL(wp),
- c1, c2, hl_attr(hl));
+ grid_fill(&wp->w_grid, row, endrow, FDC_OFF, wp->w_grid.Columns, c1, c2,
+ attr);
}
set_empty_rows(wp, row);
}
@@ -1666,7 +1627,7 @@ static int compute_foldcolumn(win_T *wp, int col)
{
int fdc = wp->w_p_fdc;
int wmw = wp == curwin && p_wmw == 0 ? 1 : p_wmw;
- int wwidth = wp->w_width;
+ int wwidth = wp->w_grid.Columns;
if (fdc > wwidth - (col + wmw)) {
fdc = wwidth - (col + wmw);
@@ -1674,12 +1635,62 @@ static int compute_foldcolumn(win_T *wp, int col)
return fdc;
}
+/// Put a single char from an UTF-8 buffer into a line buffer.
+///
+/// Handles composing chars and arabic shaping state.
+static int line_putchar(LineState *s, schar_T *dest, int maxcells, bool rl)
+{
+ const char_u *p = s->p;
+ int cells = utf_ptr2cells(p);
+ int c_len = utfc_ptr2len(p);
+ int u8c, u8cc[MAX_MCO];
+ if (cells > maxcells) {
+ return -1;
+ }
+ u8c = utfc_ptr2char(p, u8cc);
+ if (*p < 0x80 && u8cc[0] == 0) {
+ schar_from_ascii(dest[0], *p);
+ s->prev_c = u8c;
+ } else {
+ if (p_arshape && !p_tbidi && arabic_char(u8c)) {
+ // Do Arabic shaping.
+ int pc, pc1, nc;
+ int pcc[MAX_MCO];
+ int firstbyte = *p;
+
+ // The idea of what is the previous and next
+ // character depends on 'rightleft'.
+ if (rl) {
+ pc = s->prev_c;
+ pc1 = s->prev_c1;
+ nc = utf_ptr2char(p + c_len);
+ s->prev_c1 = u8cc[0];
+ } else {
+ pc = utfc_ptr2char(p + c_len, pcc);
+ nc = s->prev_c;
+ pc1 = pcc[0];
+ }
+ s->prev_c = u8c;
+
+ u8c = arabic_shape(u8c, &firstbyte, &u8cc[0], pc, pc1, nc);
+ } else {
+ s->prev_c = u8c;
+ }
+ schar_from_cc(dest[0], u8c, u8cc);
+ }
+ if (cells > 1) {
+ dest[1][0] = 0;
+ }
+ s->p += c_len;
+ return cells;
+}
+
/*
* Display one folded line.
*/
static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T lnum, int row)
{
- char_u buf[51];
+ char_u buf[FOLD_TEXT_LEN];
pos_T *top, *bot;
linenr_T lnume = lnum + fold_count - 1;
int len;
@@ -1687,7 +1698,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
int fdc;
int col;
int txtcol;
- int off = (int)(current_ScreenLine - ScreenLines);
+ int off;
int ri;
/* Build the fold line:
@@ -1699,17 +1710,16 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
* 6. set highlighting for the Visual area an other text
*/
col = 0;
+ off = 0;
/*
* 1. Add the cmdwin_type for the command-line window
* Ignores 'rightleft', this window is never right-left.
*/
if (cmdwin_type != 0 && wp == curwin) {
- ScreenLines[off] = cmdwin_type;
- ScreenAttrs[off] = hl_attr(HLF_AT);
- if (enc_utf8)
- ScreenLinesUC[off] = 0;
- ++col;
+ schar_from_ascii(linebuf_char[off], cmdwin_type);
+ linebuf_attr[off] = win_hl_attr(wp, HLF_AT);
+ col++;
}
// 2. Add the 'foldcolumn'
@@ -1720,35 +1730,43 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
if (wp->w_p_rl) {
int i;
- copy_text_attr(off + wp->w_width - fdc - col, buf, fdc,
- hl_attr(HLF_FC));
- /* reverse the fold column */
- for (i = 0; i < fdc; ++i)
- ScreenLines[off + wp->w_width - i - 1 - col] = buf[i];
- } else
- copy_text_attr(off + col, buf, fdc, hl_attr(HLF_FC));
+ copy_text_attr(off + wp->w_grid.Columns - fdc - col, buf, fdc,
+ win_hl_attr(wp, HLF_FC));
+ // reverse the fold column
+ for (i = 0; i < fdc; i++) {
+ schar_from_ascii(linebuf_char[off + wp->w_grid.Columns - i - 1 - col],
+ buf[i]);
+ }
+ } else {
+ copy_text_attr(off + col, buf, fdc, win_hl_attr(wp, HLF_FC));
+ }
col += fdc;
}
-# define RL_MEMSET(p, v, l) if (wp->w_p_rl) \
- for (ri = 0; ri < l; ++ri) \
- ScreenAttrs[off + (wp->w_width - (p) - (l)) + ri] = v; \
- else \
- for (ri = 0; ri < l; ++ri) \
- ScreenAttrs[off + (p) + ri] = v
+# define RL_MEMSET(p, v, l) if (wp->w_p_rl) { \
+ for (ri = 0; ri < l; ri++) { \
+ linebuf_attr[off + (wp->w_grid.Columns - (p) - (l)) + ri] = v; \
+ } \
+ } else { \
+ for (ri = 0; ri < l; ri++) { \
+ linebuf_attr[off + (p) + ri] = v; \
+ } \
+ }
/* Set all attributes of the 'number' or 'relativenumber' column and the
* text */
- RL_MEMSET(col, hl_attr(HLF_FL), wp->w_width - col);
+ RL_MEMSET(col, win_hl_attr(wp, HLF_FL), wp->w_grid.Columns - col);
- /* If signs are being displayed, add two spaces. */
- if (draw_signcolumn(wp)) {
- len = wp->w_width - col;
+ // If signs are being displayed, add spaces.
+ if (signcolumn_on(wp)) {
+ len = wp->w_grid.Columns - col;
if (len > 0) {
- if (len > 2) {
- len = 2;
+ int len_max = win_signcol_width(wp);
+ if (len > len_max) {
+ len = len_max;
}
- copy_text_attr(off + col, (char_u *)" ", len, hl_attr(HLF_FL));
+ copy_text_attr(off + col, (char_u *)" ", len,
+ win_hl_attr(wp, HLF_FL));
col += len;
}
}
@@ -1757,7 +1775,7 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
* 3. Add the 'number' or 'relativenumber' column
*/
if (wp->w_p_nu || wp->w_p_rnu) {
- len = wp->w_width - col;
+ len = wp->w_grid.Columns - col;
if (len > 0) {
int w = number_width(wp);
long num;
@@ -1780,13 +1798,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
}
}
- sprintf((char *)buf, fmt, w, num);
- if (wp->w_p_rl)
- /* the line number isn't reversed */
- copy_text_attr(off + wp->w_width - len - col, buf, len,
- hl_attr(HLF_FL));
- else
- copy_text_attr(off + col, buf, len, hl_attr(HLF_FL));
+ snprintf((char *)buf, FOLD_TEXT_LEN, fmt, w, num);
+ if (wp->w_p_rl) {
+ // the line number isn't reversed
+ copy_text_attr(off + wp->w_grid.Columns - len - col, buf, len,
+ win_hl_attr(wp, HLF_FL));
+ } else {
+ copy_text_attr(off + col, buf, len, win_hl_attr(wp, HLF_FL));
+ }
col += len;
}
}
@@ -1798,113 +1817,43 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
txtcol = col; /* remember where text starts */
- /*
- * 5. move the text to current_ScreenLine. Fill up with "fill_fold".
- * Right-left text is put in columns 0 - number-col, normal text is put
- * in columns number-col - window-width.
- */
- if (has_mbyte) {
- int cells;
- int u8c, u8cc[MAX_MCO];
- int i;
- int idx;
- int c_len;
- char_u *p;
- int prev_c = 0; /* previous Arabic character */
- int prev_c1 = 0; /* first composing char for prev_c */
-
- if (wp->w_p_rl)
- idx = off;
- else
- idx = off + col;
-
- /* Store multibyte characters in ScreenLines[] et al. correctly. */
- for (p = text; *p != NUL; ) {
- cells = (*mb_ptr2cells)(p);
- c_len = (*mb_ptr2len)(p);
- if (col + cells > wp->w_width
- - (wp->w_p_rl ? col : 0)
- )
- break;
- ScreenLines[idx] = *p;
- if (enc_utf8) {
- u8c = utfc_ptr2char(p, u8cc);
- if (*p < 0x80 && u8cc[0] == 0) {
- ScreenLinesUC[idx] = 0;
- prev_c = u8c;
- } else {
- if (p_arshape && !p_tbidi && arabic_char(u8c)) {
- /* Do Arabic shaping. */
- int pc, pc1, nc;
- int pcc[MAX_MCO];
- int firstbyte = *p;
-
- /* The idea of what is the previous and next
- * character depends on 'rightleft'. */
- if (wp->w_p_rl) {
- pc = prev_c;
- pc1 = prev_c1;
- nc = utf_ptr2char(p + c_len);
- prev_c1 = u8cc[0];
- } else {
- pc = utfc_ptr2char(p + c_len, pcc);
- nc = prev_c;
- pc1 = pcc[0];
- }
- prev_c = u8c;
+ // 5. move the text to linebuf_char[off]. Fill up with "fill_fold".
+ // Right-left text is put in columns 0 - number-col, normal text is put
+ // in columns number-col - window-width.
+ int idx;
- u8c = arabic_shape(u8c, &firstbyte, &u8cc[0],
- pc, pc1, nc);
- ScreenLines[idx] = firstbyte;
- } else
- prev_c = u8c;
- /* Non-BMP character: display as ? or fullwidth ?. */
- ScreenLinesUC[idx] = u8c;
- for (i = 0; i < Screen_mco; ++i) {
- ScreenLinesC[i][idx] = u8cc[i];
- if (u8cc[i] == 0)
- break;
- }
- }
- if (cells > 1)
- ScreenLines[idx + 1] = 0;
- } else if (enc_dbcs == DBCS_JPNU && *p == 0x8e)
- /* double-byte single width character */
- ScreenLines2[idx] = p[1];
- else if (cells > 1)
- /* double-width character */
- ScreenLines[idx + 1] = p[1];
- col += cells;
- idx += cells;
- p += c_len;
- }
+ if (wp->w_p_rl) {
+ idx = off;
} else {
- len = (int)STRLEN(text);
- if (len > wp->w_width - col)
- len = wp->w_width - col;
- if (len > 0) {
- if (wp->w_p_rl)
- STRNCPY(current_ScreenLine, text, len);
- else
- STRNCPY(current_ScreenLine + col, text, len);
- col += len;
+ idx = off + col;
+ }
+
+ LineState s = LINE_STATE(text);
+
+ while (*s.p != NUL) {
+ // TODO(bfredl): cargo-culted from the old Vim code:
+ // if(col + cells > wp->w_width - (wp->w_p_rl ? col : 0)) { break; }
+ // This is obvious wrong. If Vim ever fixes this, solve for "cells" again
+ // in the correct condition.
+ int maxcells = wp->w_grid.Columns - col - (wp->w_p_rl ? col : 0);
+ int cells = line_putchar(&s, &linebuf_char[idx], maxcells, wp->w_p_rl);
+ if (cells == -1) {
+ break;
}
+ col += cells;
+ idx += cells;
}
/* Fill the rest of the line with the fold filler */
if (wp->w_p_rl)
col -= txtcol;
- while (col < wp->w_width
+
+ schar_T sc;
+ schar_from_char(sc, fill_fold);
+ while (col < wp->w_grid.Columns
- (wp->w_p_rl ? txtcol : 0)
) {
- if (enc_utf8) {
- if (fill_fold >= 0x80) {
- ScreenLinesUC[off + col] = fill_fold;
- ScreenLinesC[0][off + col] = 0;
- } else
- ScreenLinesUC[off + col] = 0;
- }
- ScreenLines[off + col++] = fill_fold;
+ schar_copy(linebuf_char[off+col++], sc);
}
if (text != buf)
@@ -1936,20 +1885,21 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
>= (colnr_T)STRLEN(ml_get_buf(wp->w_buffer, lnume,
FALSE))))))) {
if (VIsual_mode == Ctrl_V) {
- /* Visual block mode: highlight the chars part of the block */
- if (wp->w_old_cursor_fcol + txtcol < (colnr_T)wp->w_width) {
+ // Visual block mode: highlight the chars part of the block
+ if (wp->w_old_cursor_fcol + txtcol < (colnr_T)wp->w_grid.Columns) {
if (wp->w_old_cursor_lcol != MAXCOL
&& wp->w_old_cursor_lcol + txtcol
- < (colnr_T)wp->w_width)
+ < (colnr_T)wp->w_grid.Columns) {
len = wp->w_old_cursor_lcol;
- else
- len = wp->w_width - txtcol;
- RL_MEMSET(wp->w_old_cursor_fcol + txtcol, hl_attr(HLF_V),
- len - (int)wp->w_old_cursor_fcol);
+ } else {
+ len = wp->w_grid.Columns - txtcol;
+ }
+ RL_MEMSET(wp->w_old_cursor_fcol + txtcol, win_hl_attr(wp, HLF_V),
+ len - (int)wp->w_old_cursor_fcol);
}
} else {
- /* Set all attributes of the text */
- RL_MEMSET(txtcol, hl_attr(HLF_V), wp->w_width - txtcol);
+ // Set all attributes of the text
+ RL_MEMSET(txtcol, win_hl_attr(wp, HLF_V), wp->w_grid.Columns - txtcol);
}
}
}
@@ -1967,9 +1917,9 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
} else {
txtcol -= wp->w_leftcol;
}
- if (txtcol >= 0 && txtcol < wp->w_width) {
- ScreenAttrs[off + txtcol] =
- hl_combine_attr(ScreenAttrs[off + txtcol], hl_attr(HLF_MC));
+ if (txtcol >= 0 && txtcol < wp->w_grid.Columns) {
+ linebuf_attr[off + txtcol] =
+ hl_combine_attr(linebuf_attr[off + txtcol], win_hl_attr(wp, HLF_MC));
}
txtcol = old_txtcol;
j = wp->w_p_cc_cols[++i];
@@ -1983,13 +1933,14 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
txtcol -= wp->w_skipcol;
else
txtcol -= wp->w_leftcol;
- if (txtcol >= 0 && txtcol < wp->w_width)
- ScreenAttrs[off + txtcol] = hl_combine_attr(
- ScreenAttrs[off + txtcol], hl_attr(HLF_CUC));
+ if (txtcol >= 0 && txtcol < wp->w_grid.Columns) {
+ linebuf_attr[off + txtcol] = hl_combine_attr(
+ linebuf_attr[off + txtcol], win_hl_attr(wp, HLF_CUC));
+ }
}
- SCREEN_LINE(row + wp->w_winrow, wp->w_wincol, wp->w_width,
- wp->w_width, FALSE);
+ grid_put_linebuf(&wp->w_grid, row, 0, wp->w_grid.Columns, wp->w_grid.Columns,
+ false, wp, wp->w_hl_attr_normal, false);
/*
* Update w_cline_height and w_cline_folded if the cursor line was
@@ -2002,21 +1953,22 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
curwin->w_cline_height = 1;
curwin->w_cline_folded = true;
curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
+ conceal_cursor_used = conceal_cursor_line(curwin);
}
}
-/*
- * Copy "buf[len]" to ScreenLines["off"] and set attributes to "attr".
- */
+
+/// Copy "buf[len]" to linebuf_char["off"] and set attributes to "attr".
+///
+/// Only works for ASCII text!
static void copy_text_attr(int off, char_u *buf, int len, int attr)
{
int i;
- memmove(ScreenLines + off, buf, (size_t)len);
- if (enc_utf8)
- memset(ScreenLinesUC + off, 0, sizeof(u8char_T) * (size_t)len);
- for (i = 0; i < len; ++i)
- ScreenAttrs[off + i] = attr;
+ for (i = 0; i < len; i++) {
+ schar_from_ascii(linebuf_char[off + i], buf[i]);
+ linebuf_attr[off + i] = attr;
+ }
}
/*
@@ -2086,19 +2038,18 @@ win_line (
linenr_T lnum,
int startrow,
int endrow,
- bool nochange /* not updating for changed text */
+ bool nochange, // not updating for changed text
+ bool number_only // only update the number column
)
{
- int col; /* visual column on screen */
- unsigned off; /* offset in ScreenLines/ScreenAttrs */
- int c = 0; /* init for GCC */
- long vcol = 0; /* virtual column (for tabs) */
+ int c = 0; // init for GCC
+ long vcol = 0; // virtual column (for tabs)
long vcol_sbr = -1; // virtual column after showbreak
- long vcol_prev = -1; /* "vcol" of previous character */
- char_u *line; /* current line */
- char_u *ptr; /* current position in "line" */
- int row; /* row in the window, excl w_winrow */
- int screen_row; /* row on the screen, incl w_winrow */
+ long vcol_prev = -1; // "vcol" of previous character
+ char_u *line; // current line
+ char_u *ptr; // current position in "line"
+ int row; // row in the window, excl w_winrow
+ ScreenGrid *grid = &wp->w_grid; // grid specfic to the window
char_u extra[18]; /* line number and 'fdc' must fit in here */
int n_extra = 0; /* number of extra chars */
@@ -2124,11 +2075,11 @@ win_line (
int n_skip = 0; /* nr of chars to skip for 'nowrap' */
- int fromcol, tocol; /* start/end of inverting */
- int fromcol_prev = -2; /* start of inverting after cursor */
- int noinvcur = FALSE; /* don't invert the cursor */
- pos_T *top, *bot;
- int lnum_in_visual_area = FALSE;
+ int fromcol = 0, tocol = 0; // start/end of inverting
+ int fromcol_prev = -2; // start of inverting after cursor
+ int noinvcur = false; // don't invert the cursor
+ pos_T *top, *bot;
+ int lnum_in_visual_area = false;
pos_T pos;
long v;
@@ -2143,10 +2094,10 @@ win_line (
int syntax_attr = 0; /* attributes desired by syntax */
int has_syntax = FALSE; /* this buffer has syntax highl. */
int save_did_emsg;
- int eol_hl_off = 0; /* 1 if highlighted char after EOL */
- int draw_color_col = FALSE; /* highlight colorcolumn */
- int *color_cols = NULL; /* pointer to according columns array */
- bool has_spell = false; /* this buffer has spell checking */
+ int eol_hl_off = 0; // 1 if highlighted char after EOL
+ int draw_color_col = false; // highlight colorcolumn
+ int *color_cols = NULL; // pointer to according columns array
+ bool has_spell = false; // this buffer has spell checking
# define SPWORDLEN 150
char_u nextline[SPWORDLEN * 2]; /* text with start of the next line */
int nextlinecol = 0; /* column where nextline[] starts */
@@ -2157,37 +2108,38 @@ win_line (
static linenr_T checked_lnum = 0; /* line number for "checked_col" */
static int checked_col = 0; /* column in "checked_lnum" up to which
* there are no spell errors */
- static int cap_col = -1; /* column to check for Cap word */
- static linenr_T capcol_lnum = 0; /* line number where "cap_col" used */
- int cur_checked_col = 0; /* checked column for current line */
- int extra_check; /* has syntax or linebreak */
- int multi_attr = 0; /* attributes desired by multibyte */
- int mb_l = 1; /* multi-byte byte length */
- int mb_c = 0; /* decoded multi-byte character */
- int mb_utf8 = FALSE; /* screen char is UTF-8 char */
- int u8cc[MAX_MCO]; /* composing UTF-8 chars */
- int filler_lines; /* nr of filler lines to be drawn */
- int filler_todo; /* nr of filler lines still to do + 1 */
- hlf_T diff_hlf = (hlf_T)0; /* type of diff highlighting */
- int change_start = MAXCOL; /* first col of changed area */
- int change_end = -1; /* last col of changed area */
- colnr_T trailcol = MAXCOL; /* start of trailing spaces */
- int need_showbreak = FALSE;
- int line_attr = 0; /* attribute for the whole line */
- matchitem_T *cur; /* points to the match list */
- match_T *shl; /* points to search_hl or a match */
- int shl_flag; /* flag to indicate whether search_hl
- has been processed or not */
- int prevcol_hl_flag; /* flag to indicate whether prevcol
- equals startcol of search_hl or one
- of the matches */
- int prev_c = 0; /* previous Arabic character */
- int prev_c1 = 0; /* first composing char for prev_c */
- int did_line_attr = 0;
-
- bool has_bufhl = false; // this buffer has highlight matches
- int bufhl_attr = 0; // attributes desired by bufhl
- bufhl_lineinfo_T bufhl_info; // bufhl data for this line
+ static int cap_col = -1; // column to check for Cap word
+ static linenr_T capcol_lnum = 0; // line number where "cap_col"
+ int cur_checked_col = 0; // checked column for current line
+ int extra_check = 0; // has syntax or linebreak
+ int multi_attr = 0; // attributes desired by multibyte
+ int mb_l = 1; // multi-byte byte length
+ int mb_c = 0; // decoded multi-byte character
+ bool mb_utf8 = false; // screen char is UTF-8 char
+ int u8cc[MAX_MCO]; // composing UTF-8 chars
+ int filler_lines; // nr of filler lines to be drawn
+ int filler_todo; // nr of filler lines still to do + 1
+ hlf_T diff_hlf = (hlf_T)0; // type of diff highlighting
+ int change_start = MAXCOL; // first col of changed area
+ int change_end = -1; // last col of changed area
+ colnr_T trailcol = MAXCOL; // start of trailing spaces
+ int need_showbreak = false; // overlong line, skip first x chars
+ int line_attr = 0; // attribute for the whole line
+ int line_attr_lowprio = 0; // low-priority attribute for the line
+ matchitem_T *cur; // points to the match list
+ match_T *shl; // points to search_hl or a match
+ int shl_flag; // flag to indicate whether search_hl
+ // has been processed or not
+ bool prevcol_hl_flag; // flag to indicate whether prevcol
+ // equals startcol of search_hl or one
+ // of the matches
+ int prev_c = 0; // previous Arabic character
+ int prev_c1 = 0; // first composing char for prev_c
+
+ bool search_attr_from_match = false; // if search_attr is from :match
+ BufhlLineInfo bufhl_info; // bufhl data for this line
+ bool has_bufhl = false; // this buffer has highlight matches
+ bool do_virttext = false; // draw virtual text for this line
/* draw_state: items that are drawn in sequence: */
#define WL_START 0 /* nothing done yet */
@@ -2203,14 +2155,14 @@ win_line (
int syntax_flags = 0;
int syntax_seqnr = 0;
int prev_syntax_id = 0;
- int conceal_attr = hl_attr(HLF_CONCEAL);
+ int conceal_attr = win_hl_attr(wp, HLF_CONCEAL);
int is_concealing = false;
int boguscols = 0; ///< nonexistent columns added to
///< force wrapping
int vcol_off = 0; ///< offset for concealed characters
int did_wcol = false;
- int match_conc = false; ///< cchar for match functions
- int has_match_conc = false; ///< match wants to conceal
+ int match_conc = 0; ///< cchar for match functions
+ int has_match_conc = 0; ///< match wants to conceal
int old_boguscols = 0;
# define VCOL_HLC (vcol - vcol_off)
# define FIX_FOR_BOGUSCOLS \
@@ -2227,158 +2179,167 @@ win_line (
return startrow;
row = startrow;
- screen_row = row + wp->w_winrow;
- /*
- * To speed up the loop below, set extra_check when there is linebreak,
- * trailing white space and/or syntax processing to be done.
- */
- extra_check = wp->w_p_lbr;
- if (syntax_present(wp) && !wp->w_s->b_syn_error) {
- /* Prepare for syntax highlighting in this line. When there is an
- * error, stop syntax highlighting. */
- save_did_emsg = did_emsg;
- did_emsg = FALSE;
- syntax_start(wp, lnum);
- if (did_emsg)
- wp->w_s->b_syn_error = TRUE;
- else {
- did_emsg = save_did_emsg;
- has_syntax = TRUE;
- extra_check = TRUE;
- }
- }
-
- if (bufhl_start_line(wp->w_buffer, lnum, &bufhl_info)) {
- has_bufhl = true;
- extra_check = true;
- }
+ if (!number_only) {
+ // To speed up the loop below, set extra_check when there is linebreak,
+ // trailing white space and/or syntax processing to be done.
+ extra_check = wp->w_p_lbr;
+ if (syntax_present(wp) && !wp->w_s->b_syn_error) {
+ // Prepare for syntax highlighting in this line. When there is an
+ // error, stop syntax highlighting.
+ save_did_emsg = did_emsg;
+ did_emsg = false;
+ syntax_start(wp, lnum);
+ if (did_emsg) {
+ wp->w_s->b_syn_error = true;
+ } else {
+ did_emsg = save_did_emsg;
+ has_syntax = true;
+ extra_check = true;
+ }
+ }
- /* Check for columns to display for 'colorcolumn'. */
- color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols;
- if (color_cols != NULL)
- draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
-
- if (wp->w_p_spell
- && *wp->w_s->b_p_spl != NUL
- && !GA_EMPTY(&wp->w_s->b_langp)
- && *(char **)(wp->w_s->b_langp.ga_data) != NULL) {
- /* Prepare for spell checking. */
- has_spell = true;
- extra_check = TRUE;
-
- /* Get the start of the next line, so that words that wrap to the next
- * line are found too: "et<line-break>al.".
- * Trick: skip a few chars for C/shell/Vim comments */
- nextline[SPWORDLEN] = NUL;
- if (lnum < wp->w_buffer->b_ml.ml_line_count) {
- line = ml_get_buf(wp->w_buffer, lnum + 1, FALSE);
- spell_cat_line(nextline + SPWORDLEN, line, SPWORDLEN);
- }
-
- /* When a word wrapped from the previous line the start of the current
- * line is valid. */
- if (lnum == checked_lnum)
- cur_checked_col = checked_col;
- checked_lnum = 0;
-
- /* When there was a sentence end in the previous line may require a
- * word starting with capital in this line. In line 1 always check
- * the first word. */
- if (lnum != capcol_lnum)
- cap_col = -1;
- if (lnum == 1)
- cap_col = 0;
- capcol_lnum = 0;
- }
+ if (bufhl_start_line(wp->w_buffer, lnum, &bufhl_info)) {
+ if (kv_size(bufhl_info.line->items)) {
+ has_bufhl = true;
+ extra_check = true;
+ }
+ if (kv_size(bufhl_info.line->virt_text)) {
+ do_virttext = true;
+ }
+ }
- /*
- * handle visual active in this window
- */
- fromcol = -10;
- tocol = MAXCOL;
- if (VIsual_active && wp->w_buffer == curwin->w_buffer) {
- /* Visual is after curwin->w_cursor */
- if (ltoreq(curwin->w_cursor, VIsual)) {
- top = &curwin->w_cursor;
- bot = &VIsual;
- } else { /* Visual is before curwin->w_cursor */
- top = &VIsual;
- bot = &curwin->w_cursor;
+ // Check for columns to display for 'colorcolumn'.
+ color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols;
+ if (color_cols != NULL) {
+ draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
}
- lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum);
- if (VIsual_mode == Ctrl_V) { /* block mode */
- if (lnum_in_visual_area) {
- fromcol = wp->w_old_cursor_fcol;
- tocol = wp->w_old_cursor_lcol;
+
+ if (wp->w_p_spell
+ && *wp->w_s->b_p_spl != NUL
+ && !GA_EMPTY(&wp->w_s->b_langp)
+ && *(char **)(wp->w_s->b_langp.ga_data) != NULL) {
+ // Prepare for spell checking.
+ has_spell = true;
+ extra_check = true;
+
+ // Get the start of the next line, so that words that wrap to the next
+ // line are found too: "et<line-break>al.".
+ // Trick: skip a few chars for C/shell/Vim comments
+ nextline[SPWORDLEN] = NUL;
+ if (lnum < wp->w_buffer->b_ml.ml_line_count) {
+ line = ml_get_buf(wp->w_buffer, lnum + 1, false);
+ spell_cat_line(nextline + SPWORDLEN, line, SPWORDLEN);
}
- } else { /* non-block mode */
- if (lnum > top->lnum && lnum <= bot->lnum)
- fromcol = 0;
- else if (lnum == top->lnum) {
- if (VIsual_mode == 'V') /* linewise */
+
+ // When a word wrapped from the previous line the start of the current
+ // line is valid.
+ if (lnum == checked_lnum) {
+ cur_checked_col = checked_col;
+ }
+ checked_lnum = 0;
+
+ // When there was a sentence end in the previous line may require a
+ // word starting with capital in this line. In line 1 always check
+ // the first word.
+ if (lnum != capcol_lnum) {
+ cap_col = -1;
+ }
+ if (lnum == 1) {
+ cap_col = 0;
+ }
+ capcol_lnum = 0;
+ }
+
+ //
+ // handle visual active in this window
+ //
+ fromcol = -10;
+ tocol = MAXCOL;
+ if (VIsual_active && wp->w_buffer == curwin->w_buffer) {
+ // Visual is after curwin->w_cursor
+ if (ltoreq(curwin->w_cursor, VIsual)) {
+ top = &curwin->w_cursor;
+ bot = &VIsual;
+ } else { // Visual is before curwin->w_cursor
+ top = &VIsual;
+ bot = &curwin->w_cursor;
+ }
+ lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum);
+ if (VIsual_mode == Ctrl_V) { // block mode
+ if (lnum_in_visual_area) {
+ fromcol = wp->w_old_cursor_fcol;
+ tocol = wp->w_old_cursor_lcol;
+ }
+ } else { // non-block mode
+ if (lnum > top->lnum && lnum <= bot->lnum) {
fromcol = 0;
- else {
- getvvcol(wp, top, (colnr_T *)&fromcol, NULL, NULL);
- if (gchar_pos(top) == NUL)
- tocol = fromcol + 1;
+ } else if (lnum == top->lnum) {
+ if (VIsual_mode == 'V') { // linewise
+ fromcol = 0;
+ } else {
+ getvvcol(wp, top, (colnr_T *)&fromcol, NULL, NULL);
+ if (gchar_pos(top) == NUL) {
+ tocol = fromcol + 1;
+ }
+ }
}
- }
- if (VIsual_mode != 'V' && lnum == bot->lnum) {
- if (*p_sel == 'e' && bot->col == 0
- && bot->coladd == 0
- ) {
- fromcol = -10;
- tocol = MAXCOL;
- } else if (bot->col == MAXCOL)
- tocol = MAXCOL;
- else {
- pos = *bot;
- if (*p_sel == 'e')
- getvvcol(wp, &pos, (colnr_T *)&tocol, NULL, NULL);
- else {
- getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&tocol);
- ++tocol;
+ if (VIsual_mode != 'V' && lnum == bot->lnum) {
+ if (*p_sel == 'e' && bot->col == 0
+ && bot->coladd == 0) {
+ fromcol = -10;
+ tocol = MAXCOL;
+ } else if (bot->col == MAXCOL) {
+ tocol = MAXCOL;
+ } else {
+ pos = *bot;
+ if (*p_sel == 'e') {
+ getvvcol(wp, &pos, (colnr_T *)&tocol, NULL, NULL);
+ } else {
+ getvvcol(wp, &pos, NULL, NULL, (colnr_T *)&tocol);
+ tocol++;
+ }
}
}
}
- }
- /* Check if the character under the cursor should not be inverted */
- if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin
- )
- noinvcur = TRUE;
+ // Check if the char under the cursor should be inverted (highlighted).
+ if (!highlight_match && lnum == curwin->w_cursor.lnum && wp == curwin
+ && cursor_is_block_during_visual(*p_sel == 'e')) {
+ noinvcur = true;
+ }
- /* if inverting in this line set area_highlighting */
- if (fromcol >= 0) {
- area_highlighting = TRUE;
- attr = hl_attr(HLF_V);
+ // if inverting in this line set area_highlighting
+ if (fromcol >= 0) {
+ area_highlighting = true;
+ attr = win_hl_attr(wp, HLF_V);
+ }
+ // handle 'incsearch' and ":s///c" highlighting
+ } else if (highlight_match
+ && wp == curwin
+ && lnum >= curwin->w_cursor.lnum
+ && lnum <= curwin->w_cursor.lnum + search_match_lines) {
+ if (lnum == curwin->w_cursor.lnum) {
+ getvcol(curwin, &(curwin->w_cursor),
+ (colnr_T *)&fromcol, NULL, NULL);
+ } else {
+ fromcol = 0;
+ }
+ if (lnum == curwin->w_cursor.lnum + search_match_lines) {
+ pos.lnum = lnum;
+ pos.col = search_match_endcol;
+ getvcol(curwin, &pos, (colnr_T *)&tocol, NULL, NULL);
+ } else {
+ tocol = MAXCOL;
+ }
+ // do at least one character; happens when past end of line
+ if (fromcol == tocol) {
+ tocol = fromcol + 1;
+ }
+ area_highlighting = true;
+ attr = win_hl_attr(wp, HLF_I);
}
}
- /*
- * handle 'incsearch' and ":s///c" highlighting
- */
- else if (highlight_match
- && wp == curwin
- && lnum >= curwin->w_cursor.lnum
- && lnum <= curwin->w_cursor.lnum + search_match_lines) {
- if (lnum == curwin->w_cursor.lnum)
- getvcol(curwin, &(curwin->w_cursor),
- (colnr_T *)&fromcol, NULL, NULL);
- else
- fromcol = 0;
- if (lnum == curwin->w_cursor.lnum + search_match_lines) {
- pos.lnum = lnum;
- pos.col = search_match_endcol;
- getvcol(curwin, &pos, (colnr_T *)&tocol, NULL, NULL);
- } else
- tocol = MAXCOL;
- /* do at least one character; happens when past end of line */
- if (fromcol == tocol)
- tocol = fromcol + 1;
- area_highlighting = TRUE;
- attr = hl_attr(HLF_I);
- }
filler_lines = diff_check(wp, lnum);
if (filler_lines < 0) {
@@ -2398,24 +2359,52 @@ win_line (
filler_lines = wp->w_topfill;
filler_todo = filler_lines;
- /* If this line has a sign with line highlighting set line_attr. */
+ // Cursor line highlighting for 'cursorline' in the current window. Not
+ // when Visual mode is active, because it's not clear what is selected
+ // then.
+ if (wp->w_p_cul && lnum == wp->w_cursor.lnum
+ && !(wp == curwin && VIsual_active)) {
+ int cul_attr = win_hl_attr(wp, HLF_CUL);
+ HlAttrs ae = syn_attr2entry(cul_attr);
+
+ // We make a compromise here (#7383):
+ // * low-priority CursorLine if fg is not set
+ // * high-priority ("same as Vim" priority) CursorLine if fg is set
+ if (ae.rgb_fg_color == -1 && ae.cterm_fg_color == 0) {
+ line_attr_lowprio = cul_attr;
+ } else {
+ if (!(State & INSERT) && bt_quickfix(wp->w_buffer)
+ && qf_current_entry(wp) == lnum) {
+ line_attr = hl_combine_attr(cul_attr, line_attr);
+ } else {
+ line_attr = cul_attr;
+ }
+ }
+ }
+
+ // If this line has a sign with line highlighting set line_attr.
v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL);
- if (v != 0)
- line_attr = sign_get_attr((int)v, TRUE);
+ if (v != 0) {
+ line_attr = sign_get_attr((int)v, SIGN_LINEHL);
+ }
- /* Highlight the current line in the quickfix window. */
- if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum)
- line_attr = hl_attr(HLF_L);
- if (line_attr != 0)
- area_highlighting = TRUE;
+ // Highlight the current line in the quickfix window.
+ if (bt_quickfix(wp->w_buffer) && qf_current_entry(wp) == lnum) {
+ line_attr = win_hl_attr(wp, HLF_QFL);
+ }
+
+ if (line_attr_lowprio || line_attr) {
+ area_highlighting = true;
+ }
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
ptr = line;
- if (has_spell) {
- /* For checking first word with a capital skip white space. */
- if (cap_col == 0)
- cap_col = (int)(skipwhite(line) - line);
+ if (has_spell && !number_only) {
+ // For checking first word with a capital skip white space.
+ if (cap_col == 0) {
+ cap_col = (int)getwhitecols(line);
+ }
/* To be able to spell-check over line boundaries copy the end of the
* current line into nextline[]. Above the start of the next line was
@@ -2436,7 +2425,7 @@ win_line (
} else {
/* Long line, use only the last SPWORDLEN bytes. */
nextlinecol = v - SPWORDLEN;
- memmove(nextline, line + nextlinecol, SPWORDLEN);
+ memmove(nextline, line + nextlinecol, SPWORDLEN); // -V512
nextline_idx = SPWORDLEN + 1;
}
}
@@ -2464,13 +2453,13 @@ win_line (
v = wp->w_skipcol;
else
v = wp->w_leftcol;
- if (v > 0) {
+ if (v > 0 && !number_only) {
char_u *prev_ptr = ptr;
while (vcol < v && *ptr != NUL) {
c = win_lbr_chartabsize(wp, line, ptr, (colnr_T)vcol, NULL);
vcol += c;
prev_ptr = ptr;
- mb_ptr_adv(ptr);
+ MB_PTR_ADV(ptr);
}
// When:
@@ -2491,7 +2480,11 @@ win_line (
if (vcol > v) {
vcol -= c;
ptr = prev_ptr;
- n_skip = v - vcol;
+ // If the character fits on the screen, don't need to skip it.
+ // Except for a TAB.
+ if (utf_ptr2cells(ptr) >= c || *ptr == TAB) {
+ n_skip = v - vcol;
+ }
}
/*
@@ -2568,21 +2561,24 @@ win_line (
* Do this for both search_hl and the match list.
*/
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE) {
+ shl_flag = false;
+ while ((cur != NULL || !shl_flag) && !number_only) {
+ if (!shl_flag) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
- shl = &cur->hl;
+ shl_flag = true;
+ } else {
+ shl = &cur->hl; // -V595
+ }
shl->startcol = MAXCOL;
shl->endcol = MAXCOL;
shl->attr_cur = 0;
+ shl->is_addpos = false;
v = (long)(ptr - line);
if (cur != NULL) {
cur->pos.cur = 0;
}
- next_search_hl(wp, shl, lnum, (colnr_T)v, cur);
+ next_search_hl(wp, shl, lnum, (colnr_T)v,
+ shl == &search_hl ? NULL : cur);
// Need to get the line again, a multi-line regexp may have made it
// invalid.
@@ -2612,6 +2608,7 @@ win_line (
if ((long)shl->startcol < v) { // match at leftcol
shl->attr_cur = shl->attr;
search_attr = shl->attr;
+ search_attr_from_match = shl != &search_hl;
}
area_highlighting = true;
}
@@ -2619,22 +2616,13 @@ win_line (
cur = cur->next;
}
- /* Cursor line highlighting for 'cursorline' in the current window. Not
- * when Visual mode is active, because it's not clear what is selected
- * then. */
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum
- && !(wp == curwin && VIsual_active)) {
- line_attr = hl_attr(HLF_CUL);
- area_highlighting = true;
- }
-
- off = (unsigned)(current_ScreenLine - ScreenLines);
- col = 0;
+ unsigned off = 0; // Offset relative start of line
+ int col = 0; // Visual column on screen.
if (wp->w_p_rl) {
- /* Rightleft window: process the text in the normal direction, but put
- * it in current_ScreenLine[] from right to left. Start at the
- * rightmost column of the window. */
- col = wp->w_width - 1;
+ // Rightleft window: process the text in the normal direction, but put
+ // it in linebuf_char[off] from right to left. Start at the
+ // rightmost column of the window.
+ col = grid->Columns - 1;
off += col;
}
@@ -2647,7 +2635,7 @@ win_line (
// Repeat for the whole displayed line.
for (;; ) {
- has_match_conc = false;
+ has_match_conc = 0;
// Skip this quickly when working on the text.
if (draw_state != WL_LINE) {
if (draw_state == WL_CMDLINE - 1 && n_extra == 0) {
@@ -2656,7 +2644,7 @@ win_line (
/* Draw the cmdline character. */
n_extra = 1;
c_extra = cmdwin_type;
- char_attr = hl_attr(HLF_AT);
+ char_attr = win_hl_attr(wp, HLF_AT);
}
}
@@ -2665,13 +2653,16 @@ win_line (
draw_state = WL_FOLD;
if (fdc > 0) {
- // Draw the 'foldcolumn'.
- fill_foldcolumn(extra, wp, false, lnum);
+ // Draw the 'foldcolumn'. Allocate a buffer, "extra" may
+ // already be in use.
+ xfree(p_extra_free);
+ p_extra_free = xmalloc(12 + 1);
+ fill_foldcolumn(p_extra_free, wp, false, lnum);
n_extra = fdc;
- p_extra = extra;
- p_extra[n_extra] = NUL;
+ p_extra_free[n_extra] = NUL;
+ p_extra = p_extra_free;
c_extra = NUL;
- char_attr = hl_attr(HLF_FC);
+ char_attr = win_hl_attr(wp, HLF_FC);
}
}
@@ -2680,22 +2671,29 @@ win_line (
draw_state = WL_SIGN;
/* Show the sign column when there are any signs in this
* buffer or when using Netbeans. */
- if (draw_signcolumn(wp)) {
+ if (signcolumn_on(wp)) {
int text_sign;
- /* Draw two cells with the sign value or blank. */
+ // Draw cells with the sign value or blank.
c_extra = ' ';
- char_attr = hl_attr(HLF_SC);
- n_extra = 2;
+ char_attr = win_hl_attr(wp, HLF_SC);
+ n_extra = win_signcol_width(wp);
if (row == startrow + filler_lines && filler_todo <= 0) {
text_sign = buf_getsigntype(wp->w_buffer, lnum, SIGN_TEXT);
if (text_sign != 0) {
p_extra = sign_get_text(text_sign);
+ int symbol_blen = (int)STRLEN(p_extra);
if (p_extra != NULL) {
c_extra = NUL;
- n_extra = (int)STRLEN(p_extra);
+ // symbol(s) bytes + (filling spaces) (one byte each)
+ n_extra = symbol_blen +
+ (win_signcol_width(wp) - mb_string2cells(p_extra));
+ memset(extra, ' ', sizeof(extra));
+ STRNCPY(extra, p_extra, STRLEN(p_extra));
+ p_extra = extra;
+ p_extra[n_extra] = NUL;
}
- char_attr = sign_get_attr(text_sign, FALSE);
+ char_attr = sign_get_attr(text_sign, SIGN_TEXT);
}
}
}
@@ -2741,14 +2739,20 @@ win_line (
} else
c_extra = ' ';
n_extra = number_width(wp) + 1;
- char_attr = hl_attr(HLF_N);
- /* When 'cursorline' is set highlight the line number of
- * the current line differently.
- * TODO: Can we use CursorLine instead of CursorLineNr
- * when CursorLineNr isn't set? */
- if ((wp->w_p_cul || wp->w_p_rnu)
- && lnum == wp->w_cursor.lnum)
- char_attr = hl_attr(HLF_CLN);
+ char_attr = win_hl_attr(wp, HLF_N);
+
+ int num_sign = buf_getsigntype(wp->w_buffer, lnum, SIGN_NUMHL);
+ if (num_sign != 0) {
+ // :sign defined with "numhl" highlight.
+ char_attr = sign_get_attr(num_sign, SIGN_NUMHL);
+ } else if ((wp->w_p_cul || wp->w_p_rnu)
+ && lnum == wp->w_cursor.lnum) {
+ // When 'cursorline' is set highlight the line number of
+ // the current line differently.
+ // TODO(vim): Can we use CursorLine instead of CursorLineNr
+ // when CursorLineNr isn't set?
+ char_attr = win_hl_attr(wp, HLF_CLN);
+ }
}
}
@@ -2761,16 +2765,18 @@ win_line (
draw_state = WL_BRI - 1;
}
- // draw 'breakindent': indent wrapped text accodringly
+ // draw 'breakindent': indent wrapped text accordingly
if (draw_state == WL_BRI - 1 && n_extra == 0) {
draw_state = WL_BRI;
- if (wp->w_p_bri && n_extra == 0 && row != startrow && filler_lines == 0) {
- char_attr = 0; // was: hl_attr(HLF_AT);
+ // if need_showbreak is set, breakindent also applies
+ if (wp->w_p_bri && (row != startrow || need_showbreak)
+ && filler_lines == 0) {
+ char_attr = 0;
if (diff_hlf != (hlf_T)0) {
- char_attr = hl_attr(diff_hlf);
+ char_attr = win_hl_attr(wp, diff_hlf);
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
+ char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
}
}
p_extra = NULL;
@@ -2791,19 +2797,20 @@ win_line (
c_extra = '-';
else
c_extra = fill_diff;
- if (wp->w_p_rl)
+ if (wp->w_p_rl) {
n_extra = col + 1;
- else
- n_extra = wp->w_width - col;
- char_attr = hl_attr(HLF_DED);
+ } else {
+ n_extra = grid->Columns - col;
+ }
+ char_attr = win_hl_attr(wp, HLF_DED);
}
if (*p_sbr != NUL && need_showbreak) {
/* Draw 'showbreak' at the start of each broken line. */
p_extra = p_sbr;
c_extra = NUL;
n_extra = (int)STRLEN(p_sbr);
- char_attr = hl_attr(HLF_AT);
- need_showbreak = FALSE;
+ char_attr = win_hl_attr(wp, HLF_AT);
+ need_showbreak = false;
vcol_sbr = vcol + MB_CHARLEN(p_sbr);
/* Correct end of highlighted area for 'showbreak',
* required when 'linebreak' is also set. */
@@ -2811,7 +2818,7 @@ win_line (
tocol += n_extra;
/* combine 'showbreak' with 'cursorline' */
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
+ char_attr = hl_combine_attr(char_attr, win_hl_attr(wp, HLF_CUL));
}
}
}
@@ -2824,39 +2831,43 @@ win_line (
c_extra = saved_c_extra;
p_extra = saved_p_extra;
char_attr = saved_char_attr;
- } else
+ } else {
char_attr = 0;
+ }
}
}
- /* When still displaying '$' of change command, stop at cursor */
- if (dollar_vcol >= 0 && wp == curwin
- && lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol
- && filler_todo <= 0
- ) {
- SCREEN_LINE(screen_row, wp->w_wincol, col, -wp->w_width, wp->w_p_rl);
- /* Pretend we have finished updating the window. Except when
- * 'cursorcolumn' is set. */
- if (wp->w_p_cuc)
+ // When still displaying '$' of change command, stop at cursor
+ if ((dollar_vcol >= 0 && wp == curwin
+ && lnum == wp->w_cursor.lnum && vcol >= (long)wp->w_virtcol
+ && filler_todo <= 0)
+ || (number_only && draw_state > WL_NR)) {
+ grid_put_linebuf(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp,
+ wp->w_hl_attr_normal, false);
+ // Pretend we have finished updating the window. Except when
+ // 'cursorcolumn' is set.
+ if (wp->w_p_cuc) {
row = wp->w_cline_row + wp->w_cline_height;
- else
- row = wp->w_height;
+ } else {
+ row = grid->Rows;
+ }
break;
}
- if (draw_state == WL_LINE && area_highlighting) {
- /* handle Visual or match highlighting in this line */
+ if (draw_state == WL_LINE && (area_highlighting || has_spell)) {
+ // handle Visual or match highlighting in this line
if (vcol == fromcol
- || (has_mbyte && vcol + 1 == fromcol && n_extra == 0
- && (*mb_ptr2cells)(ptr) > 1)
+ || (vcol + 1 == fromcol && n_extra == 0
+ && utf_ptr2cells(ptr) > 1)
|| ((int)vcol_prev == fromcol_prev
- && vcol_prev < vcol /* not at margin */
- && vcol < tocol))
- area_attr = attr; /* start highlighting */
- else if (area_attr != 0
- && (vcol == tocol
- || (noinvcur && (colnr_T)vcol == wp->w_virtcol)))
- area_attr = 0; /* stop highlighting */
+ && vcol_prev < vcol // not at margin
+ && vcol < tocol)) {
+ area_attr = attr; // start highlighting
+ } else if (area_attr != 0 && (vcol == tocol
+ || (noinvcur
+ && (colnr_T)vcol == wp->w_virtcol))) {
+ area_attr = 0; // stop highlighting
+ }
if (!n_extra) {
/*
@@ -2897,16 +2908,16 @@ win_line (
shl->attr_cur = shl->attr;
if (cur != NULL && syn_name2id((char_u *)"Conceal")
== cur->hlg_id) {
- has_match_conc = true;
+ has_match_conc = v == (long)shl->startcol ? 2 : 1;
match_conc = cur->conceal_char;
} else {
- has_match_conc = match_conc = false;
+ has_match_conc = match_conc = 0;
}
} else if (v == (long)shl->endcol) {
shl->attr_cur = 0;
- prev_syntax_id = 0;
- next_search_hl(wp, shl, lnum, (colnr_T)v, cur);
+ next_search_hl(wp, shl, lnum, (colnr_T)v,
+ shl == &search_hl ? NULL : cur);
pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
/* Need to get the line again, a multi-line regexp
@@ -2944,6 +2955,7 @@ win_line (
/* Use attributes from match with highest priority among
* 'search_hl' and the match list. */
+ search_attr_from_match = false;
search_attr = search_hl.attr_cur;
cur = wp->w_match_head;
shl_flag = FALSE;
@@ -2956,23 +2968,37 @@ win_line (
shl_flag = TRUE;
} else
shl = &cur->hl;
- if (shl->attr_cur != 0)
+ if (shl->attr_cur != 0) {
search_attr = shl->attr_cur;
+ search_attr_from_match = shl != &search_hl;
+ }
if (shl != &search_hl && cur != NULL)
cur = cur->next;
}
+ // Only highlight one character after the last column.
+ if (*ptr == NUL
+ && (wp->w_p_list && lcs_eol_one == -1)) {
+ search_attr = 0;
+ }
}
if (diff_hlf != (hlf_T)0) {
if (diff_hlf == HLF_CHD && ptr - line >= change_start
- && n_extra == 0)
- diff_hlf = HLF_TXD; /* changed text */
+ && n_extra == 0) {
+ diff_hlf = HLF_TXD; // changed text
+ }
if (diff_hlf == HLF_TXD && ptr - line > change_end
- && n_extra == 0)
- diff_hlf = HLF_CHD; /* changed line */
- line_attr = hl_attr(diff_hlf);
+ && n_extra == 0) {
+ diff_hlf = HLF_CHD; // changed line
+ }
+ line_attr = win_hl_attr(wp, diff_hlf);
+ // Overlay CursorLine onto diff-mode highlight.
if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- line_attr = hl_combine_attr(line_attr, hl_attr(HLF_CUL));
+ line_attr = 0 != line_attr_lowprio // Low-priority CursorLine
+ ? hl_combine_attr(hl_combine_attr(win_hl_attr(wp, HLF_CUL),
+ line_attr),
+ hl_get_underline())
+ : hl_combine_attr(line_attr, win_hl_attr(wp, HLF_CUL));
}
}
@@ -2988,14 +3014,15 @@ win_line (
// (area_attr may be 0 when "noinvcur" is set).
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|| vcol < fromcol || vcol_prev < fromcol_prev
- || vcol >= tocol))
+ || vcol >= tocol)) {
char_attr = line_attr;
- else {
- attr_pri = FALSE;
- if (has_syntax)
+ } else {
+ attr_pri = false;
+ if (has_syntax) {
char_attr = syntax_attr;
- else
+ } else {
char_attr = 0;
+ }
}
}
@@ -3013,55 +3040,49 @@ win_line (
if (n_extra > 0) {
if (c_extra != NUL) {
c = c_extra;
- mb_c = c; /* doesn't handle non-utf-8 multi-byte! */
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
- mb_utf8 = TRUE;
+ mb_c = c; // doesn't handle non-utf-8 multi-byte!
+ if (enc_utf8 && utf_char2len(c) > 1) {
+ mb_utf8 = true;
u8cc[0] = 0;
c = 0xc0;
- } else
- mb_utf8 = FALSE;
+ } else {
+ mb_utf8 = false;
+ }
} else {
c = *p_extra;
if (has_mbyte) {
mb_c = c;
if (enc_utf8) {
- /* If the UTF-8 character is more than one byte:
- * Decode it into "mb_c". */
- mb_l = (*mb_ptr2len)(p_extra);
- mb_utf8 = FALSE;
- if (mb_l > n_extra)
+ // If the UTF-8 character is more than one byte:
+ // Decode it into "mb_c".
+ mb_l = utfc_ptr2len(p_extra);
+ mb_utf8 = false;
+ if (mb_l > n_extra) {
mb_l = 1;
- else if (mb_l > 1) {
+ } else if (mb_l > 1) {
mb_c = utfc_ptr2char(p_extra, u8cc);
- mb_utf8 = TRUE;
+ mb_utf8 = true;
c = 0xc0;
}
- } else {
- /* if this is a DBCS character, put it in "mb_c" */
- mb_l = MB_BYTE2LEN(c);
- if (mb_l >= n_extra)
- mb_l = 1;
- else if (mb_l > 1)
- mb_c = (c << 8) + p_extra[1];
}
if (mb_l == 0) /* at the NUL at end-of-line */
mb_l = 1;
/* If a double-width char doesn't fit display a '>' in the
* last column. */
- if ((
- wp->w_p_rl ? (col <= 0) :
- (col >= wp->w_width - 1))
+ if ((wp->w_p_rl ? (col <= 0) :
+ (col >= grid->Columns - 1))
&& (*mb_char2cells)(mb_c) == 2) {
c = '>';
mb_c = c;
mb_l = 1;
- mb_utf8 = FALSE;
- multi_attr = hl_attr(HLF_AT);
- /* put the pointer back to output the double-width
- * character at the start of the next line. */
- ++n_extra;
- --p_extra;
+ mb_utf8 = false;
+ multi_attr = win_hl_attr(wp, HLF_AT);
+
+ // put the pointer back to output the double-width
+ // character at the start of the next line.
+ n_extra++;
+ p_extra--;
} else {
n_extra -= mb_l - 1;
p_extra += mb_l - 1;
@@ -3071,36 +3092,39 @@ win_line (
}
--n_extra;
} else {
+ int c0;
+
if (p_extra_free != NULL) {
xfree(p_extra_free);
p_extra_free = NULL;
}
- /*
- * Get a character from the line itself.
- */
- c = *ptr;
+
+ // Get a character from the line itself.
+ c0 = c = *ptr;
if (has_mbyte) {
mb_c = c;
if (enc_utf8) {
- /* If the UTF-8 character is more than one byte: Decode it
- * into "mb_c". */
- mb_l = (*mb_ptr2len)(ptr);
- mb_utf8 = FALSE;
+ // If the UTF-8 character is more than one byte: Decode it
+ // into "mb_c".
+ mb_l = utfc_ptr2len(ptr);
+ mb_utf8 = false;
if (mb_l > 1) {
mb_c = utfc_ptr2char(ptr, u8cc);
- /* Overlong encoded ASCII or ASCII with composing char
- * is displayed normally, except a NUL. */
- if (mb_c < 0x80)
- c = mb_c;
- mb_utf8 = TRUE;
+ // Overlong encoded ASCII or ASCII with composing char
+ // is displayed normally, except a NUL.
+ if (mb_c < 0x80) {
+ c0 = c = mb_c;
+ }
+ mb_utf8 = true;
/* At start of the line we can have a composing char.
* Draw it as a space with a composing char. */
if (utf_iscomposing(mb_c)) {
int i;
- for (i = Screen_mco - 1; i > 0; --i)
+ for (i = MAX_MCO - 1; i > 0; i--) {
u8cc[i] = u8cc[i - 1];
+ }
u8cc[0] = mb_c;
mb_c = ' ';
}
@@ -3111,21 +3135,21 @@ win_line (
|| (mb_l > 1 && (!vim_isprintc(mb_c)))) {
// Illegal UTF-8 byte: display as <xx>.
// Non-BMP character : display as ? or fullwidth ?.
- transchar_hex(extra, mb_c);
- if (wp->w_p_rl) { // reverse
- rl_mirror(extra);
+ transchar_hex((char *)extra, mb_c);
+ if (wp->w_p_rl) { // reverse
+ rl_mirror(extra);
}
p_extra = extra;
c = *p_extra;
- mb_c = mb_ptr2char_adv(&p_extra);
+ mb_c = mb_ptr2char_adv((const char_u **)&p_extra);
mb_utf8 = (c >= 0x80);
n_extra = (int)STRLEN(p_extra);
c_extra = NUL;
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_8);
+ saved_attr2 = char_attr; // save current attr
}
} else if (mb_l == 0) /* at the NUL at end-of-line */
mb_l = 1;
@@ -3177,8 +3201,8 @@ win_line (
c = *p_extra++;
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_8);
+ saved_attr2 = char_attr; // save current attr
}
mb_c = c;
}
@@ -3187,20 +3211,20 @@ win_line (
/* If a double-width char doesn't fit display a '>' in the
* last column; the character is displayed at the start of the
* next line. */
- if ((
- wp->w_p_rl ? (col <= 0) :
- (col >= wp->w_width - 1))
+ if ((wp->w_p_rl ? (col <= 0) :
+ (col >= grid->Columns - 1))
&& (*mb_char2cells)(mb_c) == 2) {
c = '>';
mb_c = c;
- mb_utf8 = FALSE;
+ mb_utf8 = false;
mb_l = 1;
- multi_attr = hl_attr(HLF_AT);
- /* Put pointer back so that the character will be
- * displayed at the start of the next line. */
- --ptr;
- } else if (*ptr != NUL)
+ multi_attr = win_hl_attr(wp, HLF_AT);
+ // Put pointer back so that the character will be
+ // displayed at the start of the next line.
+ ptr--;
+ } else if (*ptr != NUL) {
ptr += mb_l - 1;
+ }
/* If a double-width char doesn't fit at the left side display
* a '<' in the first column. Don't do this for unprintable
@@ -3211,11 +3235,11 @@ win_line (
c = ' ';
if (area_attr == 0 && search_attr == 0) {
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_AT);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_AT);
+ saved_attr2 = char_attr; // save current attr
}
mb_c = c;
- mb_utf8 = FALSE;
+ mb_utf8 = false;
mb_l = 1;
}
@@ -3235,8 +3259,7 @@ win_line (
did_emsg = FALSE;
syntax_attr = get_syntax_attr((colnr_T)v - 1,
- has_spell ? &can_spell :
- NULL, FALSE);
+ has_spell ? &can_spell : NULL, false);
if (did_emsg) {
wp->w_s->b_syn_error = TRUE;
@@ -3285,10 +3308,11 @@ win_line (
/* Use nextline[] if possible, it has the start of the
* next line concatenated. */
- if ((prev_ptr - line) - nextlinecol >= 0)
- p = nextline + (prev_ptr - line) - nextlinecol;
- else
+ if ((prev_ptr - line) - nextlinecol >= 0) {
+ p = nextline + ((prev_ptr - line) - nextlinecol);
+ } else {
p = prev_ptr;
+ }
cap_col -= (int)(prev_ptr - line);
size_t tmplen = spell_check(wp, p, &spell_hlf, &cap_col, nochange);
assert(tmplen <= INT_MAX);
@@ -3341,7 +3365,7 @@ win_line (
}
if (has_bufhl && v > 0) {
- bufhl_attr = bufhl_get_attr(&bufhl_info, (colnr_T)v);
+ int bufhl_attr = bufhl_get_attr(&bufhl_info, (colnr_T)v);
if (bufhl_attr != 0) {
if (!attr_pri) {
char_attr = hl_combine_attr(char_attr, bufhl_attr);
@@ -3355,15 +3379,14 @@ win_line (
char_attr = hl_combine_attr(char_attr, term_attrs[vcol]);
}
- /*
- * Found last space before word: check for line break.
- */
- if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)) {
- int mb_off = has_mbyte ? (*mb_head_off)(line, ptr - 1) : 0;
+ // Found last space before word: check for line break.
+ if (wp->w_p_lbr && c0 == c && vim_isbreak(c)
+ && !vim_isbreak((int)(*ptr))) {
+ int mb_off = utf_head_off(line, ptr - 1);
char_u *p = ptr - (mb_off + 1);
// TODO: is passing p for start of the line OK?
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol, NULL) - 1;
- if (c == TAB && n_extra + col > wp->w_width) {
+ if (c == TAB && n_extra + col > grid->Columns) {
n_extra = (int)wp->w_buffer->b_p_ts
- vcol % (int)wp->w_buffer->b_p_ts - 1;
}
@@ -3386,10 +3409,10 @@ win_line (
|| (c == ' ' && lcs_space && ptr - line <= trailcol))) {
c = (c == ' ') ? lcs_space : lcs_nbsp;
n_attr = 1;
- extra_attr = hl_attr(HLF_8);
+ extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = char_attr; // save current attr
mb_c = c;
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
+ if (enc_utf8 && utf_char2len(c) > 1) {
mb_utf8 = true;
u8cc[0] = 0;
c = 0xc0;
@@ -3401,27 +3424,25 @@ win_line (
if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ') {
c = lcs_trail;
n_attr = 1;
- extra_attr = hl_attr(HLF_8);
+ extra_attr = win_hl_attr(wp, HLF_0);
saved_attr2 = char_attr; // save current attr
mb_c = c;
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
- mb_utf8 = TRUE;
+ if (enc_utf8 && utf_char2len(c) > 1) {
+ mb_utf8 = true;
u8cc[0] = 0;
c = 0xc0;
- } else
- mb_utf8 = FALSE;
+ } else {
+ mb_utf8 = false;
+ }
}
}
/*
* Handling of non-printable characters.
*/
- if (!(chartab[c & 0xff] & CT_PRINT_CHAR)) {
- /*
- * when getting a character from the file, we may have to
- * turn it into something else on the way to putting it
- * into "ScreenLines".
- */
+ if (!vim_isprintc(c)) {
+ // when getting a character from the file, we may have to
+ // turn it into something else on the way to putting it on the screen.
if (c == TAB && (!wp->w_p_list || lcs_tab1)) {
int tab_len = 0;
long vcol_adjusted = vcol; // removed showbreak length
@@ -3446,8 +3467,7 @@ win_line (
tab_len += vcol_off;
}
// boguscols before FIX_FOR_BOGUSCOLS macro from above.
- if (wp->w_p_list && lcs_tab1 && old_boguscols > 0
- && n_extra > tab_len) {
+ if (lcs_tab1 && old_boguscols > 0 && n_extra > tab_len) {
tab_len += n_extra - tab_len;
}
@@ -3461,9 +3481,10 @@ win_line (
p = xmalloc(len + 1);
memset(p, ' ', len);
p[len] = NUL;
+ xfree(p_extra_free);
p_extra_free = p;
for (i = 0; i < tab_len; i++) {
- mb_char2bytes(lcs_tab2, p);
+ utf_char2bytes(lcs_tab2, p);
p += mb_char2len(lcs_tab2);
n_extra += mb_char2len(lcs_tab2) - (saved_nextra > 0 ? 1: 0);
}
@@ -3495,7 +3516,7 @@ win_line (
}
}
- mb_utf8 = (int)false; // don't draw as UTF-8
+ mb_utf8 = false; // don't draw as UTF-8
if (wp->w_p_list) {
c = lcs_tab1;
if (wp->w_p_lbr) {
@@ -3504,11 +3525,11 @@ win_line (
c_extra = lcs_tab2;
}
n_attr = tab_len + 1;
- extra_attr = hl_attr(HLF_8);
- saved_attr2 = char_attr; /* save current attr */
+ extra_attr = win_hl_attr(wp, HLF_0);
+ saved_attr2 = char_attr; // save current attr
mb_c = c;
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
- mb_utf8 = TRUE;
+ if (enc_utf8 && utf_char2len(c) > 1) {
+ mb_utf8 = true;
u8cc[0] = 0;
c = 0xc0;
}
@@ -3521,24 +3542,22 @@ win_line (
|| ((fromcol >= 0 || fromcol_prev >= 0)
&& tocol > vcol
&& VIsual_mode != Ctrl_V
- && (
- wp->w_p_rl ? (col >= 0) :
- (col < wp->w_width))
+ && (wp->w_p_rl ? (col >= 0) : (col < grid->Columns))
&& !(noinvcur
&& lnum == wp->w_cursor.lnum
&& (colnr_T)vcol == wp->w_virtcol)))
&& lcs_eol_one > 0) {
// Display a '$' after the line or highlight an extra
// character if the line break is included.
- // For a diff line the highlighting continues after the
- // "$".
- if (diff_hlf == (hlf_T)0 && line_attr == 0) {
- /* In virtualedit, visual selections may extend
- * beyond end of line. */
+ // For a diff line the highlighting continues after the "$".
+ if (diff_hlf == (hlf_T)0
+ && line_attr == 0
+ && line_attr_lowprio == 0) {
+ // In virtualedit, visual selections may extend beyond end of line
if (area_highlighting && virtual_active()
- && tocol != MAXCOL && vcol < tocol)
+ && tocol != MAXCOL && vcol < tocol) {
n_extra = 0;
- else {
+ } else {
p_extra = at_end_str;
n_extra = 1;
c_extra = NUL;
@@ -3551,15 +3570,16 @@ win_line (
}
lcs_eol_one = -1;
ptr--; // put it back at the NUL
- extra_attr = hl_attr(HLF_AT);
+ extra_attr = win_hl_attr(wp, HLF_AT);
n_attr = 1;
mb_c = c;
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
- mb_utf8 = TRUE;
+ if (enc_utf8 && utf_char2len(c) > 1) {
+ mb_utf8 = true;
u8cc[0] = 0;
c = 0xc0;
- } else
- mb_utf8 = FALSE; /* don't draw as UTF-8 */
+ } else {
+ mb_utf8 = false; // don't draw as UTF-8
+ }
} else if (c != NUL) {
p_extra = transchar(c);
if (n_extra == 0) {
@@ -3576,61 +3596,35 @@ win_line (
memset(p, ' ', n_extra);
STRNCPY(p, p_extra + 1, STRLEN(p_extra) - 1);
p[n_extra] = NUL;
+ xfree(p_extra_free);
p_extra_free = p_extra = p;
} else {
n_extra = byte2cells(c) - 1;
c = *p_extra++;
}
n_attr = n_extra + 1;
- extra_attr = hl_attr(HLF_8);
+ extra_attr = win_hl_attr(wp, HLF_8);
saved_attr2 = char_attr; // save current attr
mb_utf8 = false; // don't draw as UTF-8
} else if (VIsual_active
- && (VIsual_mode == Ctrl_V
- || VIsual_mode == 'v')
+ && (VIsual_mode == Ctrl_V || VIsual_mode == 'v')
&& virtual_active()
&& tocol != MAXCOL
&& vcol < tocol
- && (
- wp->w_p_rl ? (col >= 0) :
- (col < wp->w_width))) {
+ && (wp->w_p_rl ? (col >= 0) : (col < grid->Columns))) {
c = ' ';
ptr--; // put it back at the NUL
- } else if ((diff_hlf != (hlf_T)0 || line_attr != 0)
- && (wp->w_p_rl
- ? (col >= 0)
- : (col - boguscols < wp->w_width))) {
- // Highlight until the right side of the window
- c = ' ';
- ptr--; // put it back at the NUL
-
- // Remember we do the char for line highlighting.
- did_line_attr++;
-
- // don't do search HL for the rest of the line
- if (line_attr != 0 && char_attr == search_attr && col > 0) {
- char_attr = line_attr;
- }
- if (diff_hlf == HLF_TXD) {
- diff_hlf = HLF_CHD;
- if (attr == 0 || char_attr != attr) {
- char_attr = hl_attr(diff_hlf);
- if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUL));
- }
- }
- }
}
}
if (wp->w_p_cole > 0
&& (wp != curwin || lnum != wp->w_cursor.lnum
|| conceal_cursor_line(wp))
- && ((syntax_flags & HL_CONCEAL) != 0 || has_match_conc)
+ && ((syntax_flags & HL_CONCEAL) != 0 || has_match_conc > 0)
&& !(lnum_in_visual_area
&& vim_strchr(wp->w_p_cocu, 'v') == NULL)) {
char_attr = conceal_attr;
- if (prev_syntax_id != syntax_seqnr
+ if ((prev_syntax_id != syntax_seqnr || has_match_conc > 1)
&& (syn_get_sub_char() != NUL || match_conc
|| wp->w_p_cole == 1)
&& wp->w_p_cole != 3) {
@@ -3667,12 +3661,13 @@ win_line (
n_skip = 1;
}
mb_c = c;
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
- mb_utf8 = TRUE;
+ if (enc_utf8 && utf_char2len(c) > 1) {
+ mb_utf8 = true;
u8cc[0] = 0;
c = 0xc0;
- } else
- mb_utf8 = FALSE; /* don't draw as UTF-8 */
+ } else {
+ mb_utf8 = false; // don't draw as UTF-8
+ }
} else {
prev_syntax_id = 0;
is_concealing = FALSE;
@@ -3686,7 +3681,7 @@ win_line (
&& conceal_cursor_line(wp)
&& (int)wp->w_virtcol <= vcol + n_skip) {
if (wp->w_p_rl) {
- wp->w_wcol = wp->w_width - col + boguscols - 1;
+ wp->w_wcol = grid->Columns - col + boguscols - 1;
} else {
wp->w_wcol = col - boguscols;
}
@@ -3695,7 +3690,7 @@ win_line (
}
// Don't override visual selection highlighting.
- if (n_attr > 0 && draw_state == WL_LINE) {
+ if (n_attr > 0 && draw_state == WL_LINE && !search_attr_from_match) {
char_attr = hl_combine_attr(char_attr, extra_attr);
}
@@ -3718,43 +3713,43 @@ win_line (
c_extra = MB_FILLER_CHAR;
n_extra = 1;
n_attr = 2;
- extra_attr = hl_attr(HLF_AT);
+ extra_attr = win_hl_attr(wp, HLF_AT);
}
mb_c = c;
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
- mb_utf8 = TRUE;
+ if (enc_utf8 && utf_char2len(c) > 1) {
+ mb_utf8 = true;
u8cc[0] = 0;
c = 0xc0;
} else {
mb_utf8 = false; // don't draw as UTF-8
}
saved_attr3 = char_attr; // save current attr
- char_attr = hl_attr(HLF_AT); // later copied to char_attr
+ char_attr = win_hl_attr(wp, HLF_AT); // overwriting char_attr
n_attr3 = 1;
}
/*
* At end of the text line or just after the last character.
*/
- if (c == NUL || did_line_attr == 1) {
+ if (c == NUL) {
long prevcol = (long)(ptr - line) - (c == NUL);
/* we're not really at that column when skipping some text */
if ((long)(wp->w_p_wrap ? wp->w_skipcol : wp->w_leftcol) > prevcol)
++prevcol;
- /* Invert at least one char, used for Visual and empty line or
- * highlight match at end of line. If it's beyond the last
- * char on the screen, just overwrite that one (tricky!) Not
- * needed when a '$' was displayed for 'list'. */
- prevcol_hl_flag = FALSE;
- if (prevcol == (long)search_hl.startcol)
- prevcol_hl_flag = TRUE;
- else {
+ // Invert at least one char, used for Visual and empty line or
+ // highlight match at end of line. If it's beyond the last
+ // char on the screen, just overwrite that one (tricky!) Not
+ // needed when a '$' was displayed for 'list'.
+ prevcol_hl_flag = false;
+ if (!search_hl.is_addpos && prevcol == (long)search_hl.startcol) {
+ prevcol_hl_flag = true;
+ } else {
cur = wp->w_match_head;
while (cur != NULL) {
- if (prevcol == (long)cur->hl.startcol) {
- prevcol_hl_flag = TRUE;
+ if (!cur->hl.is_addpos && prevcol == (long)cur->hl.startcol) {
+ prevcol_hl_flag = true;
break;
}
cur = cur->next;
@@ -3766,17 +3761,17 @@ win_line (
|| lnum == VIsual.lnum
|| lnum == curwin->w_cursor.lnum)
&& c == NUL)
- /* highlight 'hlsearch' match at end of line */
- || (prevcol_hl_flag == TRUE && did_line_attr <= 1)
- )) {
+ // highlight 'hlsearch' match at end of line
+ || prevcol_hl_flag)) {
int n = 0;
if (wp->w_p_rl) {
if (col < 0)
n = 1;
} else {
- if (col >= wp->w_width)
+ if (col >= grid->Columns) {
n = -1;
+ }
}
if (n != 0) {
/* At the window boundary, highlight the last character
@@ -3784,10 +3779,8 @@ win_line (
off += n;
col += n;
} else {
- /* Add a blank character to highlight. */
- ScreenLines[off] = ' ';
- if (enc_utf8)
- ScreenLinesUC[off] = 0;
+ // Add a blank character to highlight.
+ schar_from_ascii(linebuf_char[off], ' ');
}
if (area_attr == 0) {
/* Use attributes from match with highest priority among
@@ -3804,13 +3797,21 @@ win_line (
shl_flag = TRUE;
} else
shl = &cur->hl;
- if ((ptr - line) - 1 == (long)shl->startcol)
+ if ((ptr - line) - 1 == (long)shl->startcol
+ && (shl == &search_hl || !shl->is_addpos)) {
char_attr = shl->attr;
- if (shl != &search_hl && cur != NULL)
+ }
+ if (shl != &search_hl && cur != NULL) {
cur = cur->next;
+ }
}
}
- ScreenAttrs[off] = char_attr;
+
+ int eol_attr = char_attr;
+ if (wp->w_p_cul && lnum == wp->w_cursor.lnum) {
+ eol_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUL), eol_attr);
+ }
+ linebuf_attr[off] = eol_attr;
if (wp->w_p_rl) {
--col;
--off;
@@ -3821,25 +3822,12 @@ win_line (
++vcol;
eol_hl_off = 1;
}
- }
-
- /*
- * At end of the text line.
- */
- if (c == NUL) {
- if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol
- && lnum == wp->w_cursor.lnum) {
- /* highlight last char after line */
- --col;
- --off;
- --vcol;
- }
-
- /* Highlight 'cursorcolumn' & 'colorcolumn' past end of the line. */
- if (wp->w_p_wrap)
+ // Highlight 'cursorcolumn' & 'colorcolumn' past end of the line.
+ if (wp->w_p_wrap) {
v = wp->w_skipcol;
- else
+ } else {
v = wp->w_leftcol;
+ }
/* check if line ends before left margin */
if (vcol < v + col - win_col_off(wp))
@@ -3855,58 +3843,124 @@ win_line (
if (((wp->w_p_cuc
&& (int)wp->w_virtcol >= VCOL_HLC - eol_hl_off
&& (int)wp->w_virtcol <
- wp->w_width * (row - startrow + 1) + v
+ grid->Columns * (row - startrow + 1) + v
&& lnum != wp->w_cursor.lnum)
- || draw_color_col)
- && !wp->w_p_rl
- ) {
+ || draw_color_col || line_attr_lowprio || line_attr
+ || diff_hlf != (hlf_T)0 || do_virttext)) {
int rightmost_vcol = 0;
int i;
- if (wp->w_p_cuc)
+ VirtText virt_text = do_virttext ? bufhl_info.line->virt_text
+ : (VirtText)KV_INITIAL_VALUE;
+ size_t virt_pos = 0;
+ LineState s = LINE_STATE((char_u *)"");
+ int virt_attr = 0;
+
+ // Make sure alignment is the same regardless
+ // if listchars=eol:X is used or not.
+ bool delay_virttext = lcs_eol == lcs_eol_one && eol_hl_off == 0;
+
+ if (wp->w_p_cuc) {
rightmost_vcol = wp->w_virtcol;
- if (draw_color_col)
- /* determine rightmost colorcolumn to possibly draw */
- for (i = 0; color_cols[i] >= 0; ++i)
- if (rightmost_vcol < color_cols[i])
+ }
+
+ if (draw_color_col) {
+ // determine rightmost colorcolumn to possibly draw
+ for (i = 0; color_cols[i] >= 0; i++) {
+ if (rightmost_vcol < color_cols[i]) {
rightmost_vcol = color_cols[i];
+ }
+ }
+ }
- while (col < wp->w_width) {
- ScreenLines[off] = ' ';
- if (enc_utf8)
- ScreenLinesUC[off] = 0;
- ++col;
- if (draw_color_col)
- draw_color_col = advance_color_col(VCOL_HLC,
- &color_cols);
-
- if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol)
- ScreenAttrs[off++] = hl_attr(HLF_CUC);
- else if (draw_color_col && VCOL_HLC == *color_cols)
- ScreenAttrs[off++] = hl_attr(HLF_MC);
- else
- ScreenAttrs[off++] = 0;
+ int cuc_attr = win_hl_attr(wp, HLF_CUC);
+ int mc_attr = win_hl_attr(wp, HLF_MC);
+
+ int diff_attr = 0;
+ if (diff_hlf == HLF_TXD) {
+ diff_hlf = HLF_CHD;
+ }
+ if (diff_hlf != 0) {
+ diff_attr = win_hl_attr(wp, diff_hlf);
+ }
+
+ int base_attr = hl_combine_attr(line_attr_lowprio, diff_attr);
+ if (base_attr || line_attr) {
+ rightmost_vcol = INT_MAX;
+ }
+
+ int col_stride = wp->w_p_rl ? -1 : 1;
+
+ while (wp->w_p_rl ? col >= 0 : col < grid->Columns) {
+ int cells = -1;
+ if (do_virttext && !delay_virttext) {
+ if (*s.p == NUL) {
+ if (virt_pos < virt_text.size) {
+ s.p = (char_u *)kv_A(virt_text, virt_pos).text;
+ int hl_id = kv_A(virt_text, virt_pos).hl_id;
+ virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
+ virt_pos++;
+ } else {
+ do_virttext = false;
+ }
+ }
+ if (*s.p != NUL) {
+ cells = line_putchar(&s, &linebuf_char[off], grid->Columns - col,
+ false);
+ }
+ }
+ delay_virttext = false;
+
+ if (cells == -1) {
+ schar_from_ascii(linebuf_char[off], ' ');
+ cells = 1;
+ }
+ col += cells * col_stride;
+ if (draw_color_col) {
+ draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
+ }
- if (VCOL_HLC >= rightmost_vcol)
+ int col_attr = base_attr;
+
+ if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol) {
+ col_attr = cuc_attr;
+ } else if (draw_color_col && VCOL_HLC == *color_cols) {
+ col_attr = mc_attr;
+ }
+
+ if (do_virttext) {
+ col_attr = hl_combine_attr(col_attr, virt_attr);
+ }
+
+ col_attr = hl_combine_attr(col_attr, line_attr);
+
+ linebuf_attr[off] = col_attr;
+ if (cells == 2) {
+ linebuf_attr[off+1] = col_attr;
+ }
+ off += cells * col_stride;
+
+ if (VCOL_HLC >= rightmost_vcol && *s.p == NUL
+ && virt_pos >= virt_text.size) {
break;
+ }
++vcol;
}
}
+ // TODO(bfredl): integrate with the common beyond-the-end-loop
if (wp->w_buffer->terminal) {
// terminal buffers may need to highlight beyond the end of the
// logical line
- while (col < wp->w_width) {
- ScreenLines[off] = ' ';
- if (enc_utf8) {
- ScreenLinesUC[off] = 0;
- }
- ScreenAttrs[off++] = term_attrs[vcol++];
+ while (col < grid->Columns) {
+ schar_from_ascii(linebuf_char[off], ' ');
+ linebuf_attr[off++] = term_attrs[vcol++];
col++;
}
}
- SCREEN_LINE(screen_row, wp->w_wincol, col, wp->w_width, wp->w_p_rl);
+ grid_put_linebuf(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp,
+ wp->w_hl_attr_normal, false);
row++;
/*
@@ -3918,6 +3972,7 @@ win_line (
curwin->w_cline_height = row - startrow;
curwin->w_cline_folded = false;
curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
+ conceal_cursor_used = conceal_cursor_line(curwin);
}
break;
@@ -3927,21 +3982,20 @@ win_line (
if (lcs_ext
&& !wp->w_p_wrap
&& filler_todo <= 0
- && (
- wp->w_p_rl ? col == 0 :
- col == wp->w_width - 1)
+ && (wp->w_p_rl ? col == 0 : col == grid->Columns - 1)
&& (*ptr != NUL
|| (wp->w_p_list && lcs_eol_one > 0)
|| (n_extra && (c_extra != NUL || *p_extra != NUL)))) {
c = lcs_ext;
- char_attr = hl_attr(HLF_AT);
+ char_attr = win_hl_attr(wp, HLF_AT);
mb_c = c;
- if (enc_utf8 && (*mb_char2len)(c) > 1) {
- mb_utf8 = TRUE;
+ if (enc_utf8 && utf_char2len(c) > 1) {
+ mb_utf8 = true;
u8cc[0] = 0;
c = 0xc0;
- } else
- mb_utf8 = FALSE;
+ } else {
+ mb_utf8 = false;
+ }
}
/* advance to the next 'colorcolumn' */
@@ -3953,17 +4007,23 @@ win_line (
* Also highlight the 'colorcolumn' if it is different than
* 'cursorcolumn' */
vcol_save_attr = -1;
- if (draw_state == WL_LINE && !lnum_in_visual_area) {
+ if (draw_state == WL_LINE && !lnum_in_visual_area
+ && search_attr == 0 && area_attr == 0) {
if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol
&& lnum != wp->w_cursor.lnum) {
vcol_save_attr = char_attr;
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
+ char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUC), char_attr);
} else if (draw_color_col && VCOL_HLC == *color_cols) {
vcol_save_attr = char_attr;
- char_attr = hl_combine_attr(char_attr, hl_attr(HLF_MC));
+ char_attr = hl_combine_attr(win_hl_attr(wp, HLF_MC), char_attr);
}
}
+ // Apply lowest-priority line attr now, so everything can override it.
+ if (draw_state == WL_LINE) {
+ char_attr = hl_combine_attr(line_attr_lowprio, char_attr);
+ }
+
/*
* Store character to be displayed.
* Skip characters that are left of the screen for 'nowrap'.
@@ -3978,43 +4038,24 @@ win_line (
--off;
--col;
}
- ScreenLines[off] = c;
- if (enc_dbcs == DBCS_JPNU) {
- if ((mb_c & 0xff00) == 0x8e00)
- ScreenLines[off] = 0x8e;
- ScreenLines2[off] = mb_c & 0xff;
- } else if (enc_utf8) {
- if (mb_utf8) {
- int i;
-
- ScreenLinesUC[off] = mb_c;
- if ((c & 0xff) == 0)
- ScreenLines[off] = 0x80; /* avoid storing zero */
- for (i = 0; i < Screen_mco; ++i) {
- ScreenLinesC[i][off] = u8cc[i];
- if (u8cc[i] == 0)
- break;
- }
- } else
- ScreenLinesUC[off] = 0;
+ if (mb_utf8) {
+ schar_from_cc(linebuf_char[off], mb_c, u8cc);
+ } else {
+ schar_from_ascii(linebuf_char[off], c);
}
if (multi_attr) {
- ScreenAttrs[off] = multi_attr;
+ linebuf_attr[off] = multi_attr;
multi_attr = 0;
- } else
- ScreenAttrs[off] = char_attr;
+ } else {
+ linebuf_attr[off] = char_attr;
+ }
if (has_mbyte && (*mb_char2cells)(mb_c) > 1) {
// Need to fill two screen columns.
off++;
col++;
- if (enc_utf8) {
- // UTF-8: Put a 0 in the second screen char.
- ScreenLines[off] = 0;
- } else {
- // DBCS: Put second byte in the second screen char.
- ScreenLines[off] = mb_c & 0xff;
- }
+ // UTF-8: Put a 0 in the second screen char.
+ linebuf_char[off][0] = 0;
if (draw_state > WL_NR && filler_todo <= 0) {
vcol++;
}
@@ -4120,19 +4161,35 @@ win_line (
* At end of screen line and there is more to come: Display the line
* so far. If there is no more to display it is caught above.
*/
- if ((
- wp->w_p_rl ? (col < 0) :
- (col >= wp->w_width))
+ if ((wp->w_p_rl ? (col < 0) : (col >= grid->Columns))
&& (*ptr != NUL
|| filler_todo > 0
|| (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str)
|| (n_extra != 0 && (c_extra != NUL || *p_extra != NUL)))
) {
- SCREEN_LINE(screen_row, wp->w_wincol, col - boguscols,
- wp->w_width, wp->w_p_rl);
+ bool wrap = wp->w_p_wrap // Wrapping enabled.
+ && filler_todo <= 0 // Not drawing diff filler lines.
+ && lcs_eol_one != -1 // Haven't printed the lcs_eol character.
+ && row != endrow - 1 // Not the last line being displayed.
+ && (grid->Columns == Columns // Window spans the width of the screen,
+ || ui_is_external(kUIMultigrid)) // or has dedicated grid.
+ && !wp->w_p_rl; // Not right-to-left.
+ grid_put_linebuf(grid, row, 0, col - boguscols, grid->Columns, wp->w_p_rl,
+ wp, wp->w_hl_attr_normal, wrap);
+ if (wrap) {
+ ScreenGrid *current_grid = grid;
+ int current_row = row, dummy_col = 0; // dummy_col unused
+ screen_adjust_grid(&current_grid, &current_row, &dummy_col);
+
+ // Force a redraw of the first column of the next line.
+ current_grid->attrs[current_grid->line_offset[current_row+1]] = -1;
+
+ // Remember that the line wraps, used for modeless copy.
+ current_grid->line_wraps[current_row] = true;
+ }
+
boguscols = 0;
- ++row;
- ++screen_row;
+ row++;
/* When not wrapping and finished diff lines, or when displayed
* '$' and highlighting until last column, break here. */
@@ -4145,8 +4202,7 @@ win_line (
if (draw_state != WL_LINE
&& filler_todo <= 0
) {
- win_draw_end(wp, '@', ' ', row, wp->w_height, HLF_AT);
- draw_vsep_win(wp, row);
+ win_draw_end(wp, '@', ' ', row, wp->w_grid.Rows, HLF_AT);
row = endrow;
}
@@ -4156,59 +4212,10 @@ win_line (
break;
}
- if (ui_current_row() == screen_row - 1
- && filler_todo <= 0
- && wp->w_width == Columns) {
- /* Remember that the line wraps, used for modeless copy. */
- LineWraps[screen_row - 1] = TRUE;
-
- /*
- * Special trick to make copy/paste of wrapped lines work with
- * xterm/screen: write an extra character beyond the end of
- * the line. This will work with all terminal types
- * (regardless of the xn,am settings).
- * Only do this if the cursor is on the current line
- * (something has been written in it).
- * Don't do this for the GUI.
- * Don't do this for double-width characters.
- * Don't do this for a window not at the right screen border.
- */
- if (!(has_mbyte
- && ((*mb_off2cells)(LineOffset[screen_row],
- LineOffset[screen_row] + screen_Columns)
- == 2
- || (*mb_off2cells)(LineOffset[screen_row - 1]
- + (int)Columns - 2,
- LineOffset[screen_row] + screen_Columns)
- == 2))
- ) {
- /* First make sure we are at the end of the screen line,
- * then output the same character again to let the
- * terminal know about the wrap. If the terminal doesn't
- * auto-wrap, we overwrite the character. */
- if (ui_current_col() != wp->w_width)
- screen_char(LineOffset[screen_row - 1]
- + (unsigned)Columns - 1,
- screen_row - 1, (int)(Columns - 1));
-
- /* When there is a multi-byte character, just output a
- * space to keep it simple. */
- if (has_mbyte && MB_BYTE2LEN(ScreenLines[LineOffset[
- screen_row -
- 1] + (Columns - 1)]) > 1) {
- ui_putc(' ');
- } else {
- ui_putc(ScreenLines[LineOffset[screen_row - 1] + (Columns - 1)]);
- }
- /* force a redraw of the first char on the next line */
- ScreenAttrs[LineOffset[screen_row]] = (sattr_T)-1;
- }
- }
-
col = 0;
- off = (unsigned)(current_ScreenLine - ScreenLines);
+ off = 0;
if (wp->w_p_rl) {
- col = wp->w_width - 1; /* col is not used if breaking! */
+ col = grid->Columns - 1; // col is not used if breaking!
off += col;
}
@@ -4237,27 +4244,27 @@ win_line (
cap_col = 0;
}
+ xfree(p_extra_free);
return row;
}
-
-/*
- * Return if the composing characters at "off_from" and "off_to" differ.
- * Only to be used when ScreenLinesUC[off_from] != 0.
- */
-static int comp_char_differs(int off_from, int off_to)
+/// Determine if dedicated window grid should be used or the default_grid
+///
+/// If UI did not request multigrid support, draw all windows on the
+/// default_grid.
+///
+/// If the default_grid is used, adjust window relative positions to global
+/// screen positions.
+static void screen_adjust_grid(ScreenGrid **grid, int *row_off, int *col_off)
{
- int i;
-
- for (i = 0; i < Screen_mco; ++i) {
- if (ScreenLinesC[i][off_from] != ScreenLinesC[i][off_to])
- return TRUE;
- if (ScreenLinesC[i][off_from] == 0)
- break;
+ if (!ui_is_external(kUIMultigrid) && *grid != &default_grid) {
+ *row_off += (*grid)->row_offset;
+ *col_off += (*grid)->col_offset;
+ *grid = &default_grid;
}
- return FALSE;
}
+
/*
* Check whether the given character needs redrawing:
* - the (first byte of the) character is different
@@ -4265,222 +4272,184 @@ static int comp_char_differs(int off_from, int off_to)
* - the character is multi-byte and the next byte is different
* - the character is two cells wide and the second cell differs.
*/
-static int char_needs_redraw(int off_from, int off_to, int cols)
+static int grid_char_needs_redraw(ScreenGrid *grid, int off_from, int off_to,
+ int cols)
{
return (cols > 0
- && ((ScreenLines[off_from] != ScreenLines[off_to]
- || ScreenAttrs[off_from] != ScreenAttrs[off_to])
-
- || (enc_dbcs != 0
- && MB_BYTE2LEN(ScreenLines[off_from]) > 1
- && (enc_dbcs == DBCS_JPNU && ScreenLines[off_from] == 0x8e
- ? ScreenLines2[off_from] != ScreenLines2[off_to]
- : (cols > 1 && ScreenLines[off_from + 1]
- != ScreenLines[off_to + 1])))
- || (enc_utf8
- && (ScreenLinesUC[off_from] != ScreenLinesUC[off_to]
- || (ScreenLinesUC[off_from] != 0
- && comp_char_differs(off_from, off_to))
- || ((*mb_off2cells)(off_from, off_from + cols) > 1
- && ScreenLines[off_from + 1]
- != ScreenLines[off_to + 1])))));
+ && ((schar_cmp(linebuf_char[off_from], grid->chars[off_to])
+ || linebuf_attr[off_from] != grid->attrs[off_to]
+ || (line_off2cells(linebuf_char, off_from, off_from + cols) > 1
+ && schar_cmp(linebuf_char[off_from + 1],
+ grid->chars[off_to + 1])))
+ || p_wd < 0));
}
-/*
- * Move one "cooked" screen line to the screen, but only the characters that
- * have actually changed. Handle insert/delete character.
- * "coloff" gives the first column on the screen for this line.
- * "endcol" gives the columns where valid characters are.
- * "clear_width" is the width of the window. It's > 0 if the rest of the line
- * needs to be cleared, negative otherwise.
- * "rlflag" is TRUE in a rightleft window:
- * When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
- * When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
- */
-static void screen_line(int row, int coloff, int endcol, int clear_width, int rlflag)
+/// Move one buffered line to the window grid, but only the characters that
+/// have actually changed. Handle insert/delete character.
+/// "coloff" gives the first column on the grid for this line.
+/// "endcol" gives the columns where valid characters are.
+/// "clear_width" is the width of the window. It's > 0 if the rest of the line
+/// needs to be cleared, negative otherwise.
+/// "rlflag" is TRUE in a rightleft window:
+/// When TRUE and "clear_width" > 0, clear columns 0 to "endcol"
+/// When FALSE and "clear_width" > 0, clear columns "endcol" to "clear_width"
+/// If "wrap" is true, then hint to the UI that "row" contains a line
+/// which has wrapped into the next row.
+static void grid_put_linebuf(ScreenGrid *grid, int row, int coloff, int endcol,
+ int clear_width, int rlflag, win_T *wp,
+ int bg_attr, bool wrap)
{
unsigned off_from;
unsigned off_to;
unsigned max_off_from;
unsigned max_off_to;
int col = 0;
- int hl;
- int force = FALSE; /* force update rest of the line */
- int redraw_this /* bool: does character need redraw? */
- ;
- int redraw_next; /* redraw_this for next character */
- int clear_next = FALSE;
- int char_cells; /* 1: normal char */
- /* 2: occupies two display cells */
-# define CHAR_CELLS char_cells
-
- /* Check for illegal row and col, just in case. */
- if (row >= Rows)
- row = Rows - 1;
- if (endcol > Columns)
- endcol = Columns;
-
-
- off_from = (unsigned)(current_ScreenLine - ScreenLines);
- off_to = LineOffset[row] + coloff;
- max_off_from = off_from + screen_Columns;
- max_off_to = LineOffset[row] + screen_Columns;
+ bool redraw_this; // Does character need redraw?
+ bool redraw_next; // redraw_this for next character
+ bool clear_next = false;
+ int char_cells; // 1: normal char
+ // 2: occupies two display cells
+ int start_dirty = -1, end_dirty = 0;
+
+ // TODO(bfredl): check all callsites and eliminate
+ // Check for illegal row and col, just in case
+ if (row >= grid->Rows) {
+ row = grid->Rows - 1;
+ }
+ if (endcol > grid->Columns) {
+ endcol = grid->Columns;
+ }
+
+ screen_adjust_grid(&grid, &row, &coloff);
+
+ off_from = 0;
+ off_to = grid->line_offset[row] + coloff;
+ max_off_from = linebuf_size;
+ max_off_to = grid->line_offset[row] + grid->Columns;
if (rlflag) {
/* Clear rest first, because it's left of the text. */
if (clear_width > 0) {
- while (col <= endcol && ScreenLines[off_to] == ' '
- && ScreenAttrs[off_to] == 0
- && (!enc_utf8 || ScreenLinesUC[off_to] == 0)
+ while (col <= endcol && grid->chars[off_to][0] == ' '
+ && grid->chars[off_to][1] == NUL
+ && grid->attrs[off_to] == bg_attr
) {
++off_to;
++col;
}
- if (col <= endcol)
- screen_fill(row, row + 1, col + coloff,
- endcol + coloff + 1, ' ', ' ', 0);
+ if (col <= endcol) {
+ grid_fill(grid, row, row + 1, col + coloff, endcol + coloff + 1,
+ ' ', ' ', bg_attr);
+ }
}
col = endcol + 1;
- off_to = LineOffset[row] + col + coloff;
+ off_to = grid->line_offset[row] + col + coloff;
off_from += col;
endcol = (clear_width > 0 ? clear_width : -clear_width);
}
- redraw_next = char_needs_redraw(off_from, off_to, endcol - col);
+ if (bg_attr) {
+ for (int c = col; c < endcol; c++) {
+ linebuf_attr[off_from+c] =
+ hl_combine_attr(bg_attr, linebuf_attr[off_from+c]);
+ }
+ }
- while (col < endcol) {
- if (has_mbyte && (col + 1 < endcol))
- char_cells = (*mb_off2cells)(off_from, max_off_from);
- else
- char_cells = 1;
+ redraw_next = grid_char_needs_redraw(grid, off_from, off_to, endcol - col);
+ while (col < endcol) {
+ char_cells = 1;
+ if (col + 1 < endcol) {
+ char_cells = line_off2cells(linebuf_char, off_from, max_off_from);
+ }
redraw_this = redraw_next;
- redraw_next = force || char_needs_redraw(off_from + CHAR_CELLS,
- off_to + CHAR_CELLS, endcol - col - CHAR_CELLS);
-
+ redraw_next = grid_char_needs_redraw(grid, off_from + char_cells,
+ off_to + char_cells,
+ endcol - col - char_cells);
if (redraw_this) {
- if (enc_dbcs != 0) {
- /* Check if overwriting a double-byte with a single-byte or
- * the other way around requires another character to be
- * redrawn. For UTF-8 this isn't needed, because comparing
- * ScreenLinesUC[] is sufficient. */
- if (char_cells == 1
- && col + 1 < endcol
- && (*mb_off2cells)(off_to, max_off_to) > 1) {
- /* Writing a single-cell character over a double-cell
- * character: need to redraw the next cell. */
- ScreenLines[off_to + 1] = 0;
- redraw_next = TRUE;
- } else if (char_cells == 2
- && col + 2 < endcol
- && (*mb_off2cells)(off_to, max_off_to) == 1
- && (*mb_off2cells)(off_to + 1, max_off_to) > 1) {
- /* Writing the second half of a double-cell character over
- * a double-cell character: need to redraw the second
- * cell. */
- ScreenLines[off_to + 2] = 0;
- redraw_next = TRUE;
- }
-
- if (enc_dbcs == DBCS_JPNU)
- ScreenLines2[off_to] = ScreenLines2[off_from];
+ if (start_dirty == -1) {
+ start_dirty = col;
}
- /* When writing a single-width character over a double-width
- * character and at the end of the redrawn text, need to clear out
- * the right halve of the old character.
- * Also required when writing the right halve of a double-width
- * char over the left halve of an existing one. */
- if (has_mbyte && col + char_cells == endcol
+ end_dirty = col + char_cells;
+ // When writing a single-width character over a double-width
+ // character and at the end of the redrawn text, need to clear out
+ // the right halve of the old character.
+ // Also required when writing the right halve of a double-width
+ // char over the left halve of an existing one
+ if (col + char_cells == endcol
&& ((char_cells == 1
- && (*mb_off2cells)(off_to, max_off_to) > 1)
+ && grid_off2cells(grid, off_to, max_off_to) > 1)
|| (char_cells == 2
- && (*mb_off2cells)(off_to, max_off_to) == 1
- && (*mb_off2cells)(off_to + 1, max_off_to) > 1)))
- clear_next = TRUE;
-
- ScreenLines[off_to] = ScreenLines[off_from];
- if (enc_utf8) {
- ScreenLinesUC[off_to] = ScreenLinesUC[off_from];
- if (ScreenLinesUC[off_from] != 0) {
- int i;
-
- for (i = 0; i < Screen_mco; ++i)
- ScreenLinesC[i][off_to] = ScreenLinesC[i][off_from];
- }
+ && grid_off2cells(grid, off_to, max_off_to) == 1
+ && grid_off2cells(grid, off_to + 1, max_off_to) > 1))) {
+ clear_next = true;
}
- if (char_cells == 2)
- ScreenLines[off_to + 1] = ScreenLines[off_from + 1];
- ScreenAttrs[off_to] = ScreenAttrs[off_from];
- /* For simplicity set the attributes of second half of a
- * double-wide character equal to the first half. */
- if (char_cells == 2)
- ScreenAttrs[off_to + 1] = ScreenAttrs[off_from];
+ schar_copy(grid->chars[off_to], linebuf_char[off_from]);
+ if (char_cells == 2) {
+ schar_copy(grid->chars[off_to+1], linebuf_char[off_from+1]);
+ }
- if (enc_dbcs != 0 && char_cells == 2)
- screen_char_2(off_to, row, col + coloff);
- else
- screen_char(off_to, row, col + coloff);
+ grid->attrs[off_to] = linebuf_attr[off_from];
+ // For simplicity set the attributes of second half of a
+ // double-wide character equal to the first half.
+ if (char_cells == 2) {
+ grid->attrs[off_to + 1] = linebuf_attr[off_from];
+ }
}
- off_to += CHAR_CELLS;
- off_from += CHAR_CELLS;
- col += CHAR_CELLS;
+ off_to += char_cells;
+ off_from += char_cells;
+ col += char_cells;
}
if (clear_next) {
/* Clear the second half of a double-wide character of which the left
* half was overwritten with a single-wide character. */
- ScreenLines[off_to] = ' ';
- if (enc_utf8)
- ScreenLinesUC[off_to] = 0;
- screen_char(off_to, row, col + coloff);
+ schar_from_ascii(grid->chars[off_to], ' ');
+ end_dirty++;
+ }
+
+ int clear_end = -1;
+ if (clear_width > 0 && !rlflag) {
+ // blank out the rest of the line
+ // TODO(bfredl): we could cache winline widths
+ while (col < clear_width) {
+ if (grid->chars[off_to][0] != ' '
+ || grid->chars[off_to][1] != NUL
+ || grid->attrs[off_to] != bg_attr) {
+ grid->chars[off_to][0] = ' ';
+ grid->chars[off_to][1] = NUL;
+ grid->attrs[off_to] = bg_attr;
+ if (start_dirty == -1) {
+ start_dirty = col;
+ end_dirty = col;
+ } else if (clear_end == -1) {
+ end_dirty = endcol;
+ }
+ clear_end = col+1;
+ }
+ col++;
+ off_to++;
+ }
}
- if (clear_width > 0
- && !rlflag
- ) {
+ if (clear_width > 0 || wp->w_width != grid->Columns) {
+ // If we cleared after the end of the line, it did not wrap.
+ // For vsplit, line wrapping is not possible.
+ grid->line_wraps[row] = false;
+ }
- /* blank out the rest of the line */
- while (col < clear_width && ScreenLines[off_to] == ' '
- && ScreenAttrs[off_to] == 0
- && (!enc_utf8 || ScreenLinesUC[off_to] == 0)
- ) {
- ++off_to;
- ++col;
- }
- if (col < clear_width) {
- screen_fill(row, row + 1, col + coloff, clear_width + coloff,
- ' ', ' ', 0);
- off_to += clear_width - col;
- col = clear_width;
- }
- }
-
- if (clear_width > 0) {
- /* For a window that's left of another, draw the separator char. */
- if (col + coloff < Columns) {
- int c;
-
- c = fillchar_vsep(&hl);
- if (ScreenLines[off_to] != (schar_T)c
- || (enc_utf8 && (int)ScreenLinesUC[off_to]
- != (c >= 0x80 ? c : 0))
- || ScreenAttrs[off_to] != hl) {
- ScreenLines[off_to] = c;
- ScreenAttrs[off_to] = hl;
- if (enc_utf8) {
- if (c >= 0x80) {
- ScreenLinesUC[off_to] = c;
- ScreenLinesC[0][off_to] = 0;
- } else
- ScreenLinesUC[off_to] = 0;
- }
- screen_char(off_to, row, col + coloff);
- }
- } else
- LineWraps[row] = FALSE;
+ if (clear_end < end_dirty) {
+ clear_end = end_dirty;
+ }
+ if (start_dirty == -1) {
+ start_dirty = end_dirty;
+ }
+ if (clear_end > start_dirty) {
+ ui_line(grid, row, coloff+start_dirty, coloff+end_dirty, coloff+clear_end,
+ bg_attr, wrap);
}
}
@@ -4514,14 +4483,18 @@ void status_redraw_all(void)
}
}
-/*
- * mark all status lines of the current buffer for redraw
- */
+/// Marks all status lines of the current buffer for redraw.
void status_redraw_curbuf(void)
{
+ status_redraw_buf(curbuf);
+}
+
+/// Marks all status lines of the specified buffer for redraw.
+void status_redraw_buf(buf_T *buf)
+{
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if (wp->w_status_height != 0 && wp->w_buffer == curbuf) {
- wp->w_redr_status = TRUE;
+ if (wp->w_status_height != 0 && wp->w_buffer == buf) {
+ wp->w_redr_status = true;
redraw_later(VALID);
}
}
@@ -4534,7 +4507,7 @@ void redraw_statuslines(void)
{
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_redr_status) {
- win_redr_status(wp);
+ win_redr_status(wp, false);
}
}
if (redraw_tabline)
@@ -4568,11 +4541,10 @@ static void draw_vsep_win(win_T *wp, int row)
int c;
if (wp->w_vsep_width) {
- /* draw the vertical separator right of this window */
- c = fillchar_vsep(&hl);
- screen_fill(wp->w_winrow + row, wp->w_winrow + wp->w_height,
- W_ENDCOL(wp), W_ENDCOL(wp) + 1,
- c, ' ', hl);
+ // draw the vertical separator right of this window
+ c = fillchar_vsep(wp, &hl);
+ grid_fill(&default_grid, wp->w_winrow + row, W_ENDROW(wp),
+ W_ENDCOL(wp), W_ENDCOL(wp) + 1, c, ' ', hl);
}
}
@@ -4594,7 +4566,7 @@ static int status_match_len(expand_T *xp, char_u *s)
while (*s != NUL) {
s += skip_status_match_char(xp, s);
len += ptr2cells(s);
- mb_ptr_adv(s);
+ MB_PTR_ADV(s);
}
return len;
@@ -4657,7 +4629,8 @@ win_redr_status_matches (
if (matches == NULL) /* interrupted completion? */
return;
- buf = xmalloc(has_mbyte ? Columns * MB_MAXBYTES + 1 : Columns + 1);
+ buf = xmalloc(has_mbyte ? default_grid.Columns * MB_MAXBYTES + 1
+ : default_grid.Columns + 1);
if (match == -1) { /* don't show match but original text */
match = 0;
@@ -4677,15 +4650,16 @@ win_redr_status_matches (
clen += status_match_len(xp, L_MATCH(i)) + 2;
if (first_match > 0)
clen += 2;
- /* jumping right, put match at the left */
- if ((long)clen > Columns) {
+ // jumping right, put match at the left
+ if ((long)clen > default_grid.Columns) {
first_match = match;
/* if showing the last match, we can add some on the left */
clen = 2;
for (i = match; i < num_matches; ++i) {
clen += status_match_len(xp, L_MATCH(i)) + 2;
- if ((long)clen >= Columns)
+ if ((long)clen >= default_grid.Columns) {
break;
+ }
}
if (i == num_matches)
add_left = TRUE;
@@ -4694,12 +4668,13 @@ win_redr_status_matches (
if (add_left)
while (first_match > 0) {
clen += status_match_len(xp, L_MATCH(first_match - 1)) + 2;
- if ((long)clen >= Columns)
+ if ((long)clen >= default_grid.Columns) {
break;
- --first_match;
+ }
+ first_match--;
}
- fillchar = fillchar_status(&attr, TRUE);
+ fillchar = fillchar_status(&attr, curwin);
if (first_match == 0) {
*buf = NUL;
@@ -4711,7 +4686,8 @@ win_redr_status_matches (
clen = len;
i = first_match;
- while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2) < Columns) {
+ while ((long)(clen + status_match_len(xp, L_MATCH(i)) + 2)
+ < default_grid.Columns) {
if (i == match) {
selstart = buf + len;
selstart_col = clen;
@@ -4762,12 +4738,12 @@ win_redr_status_matches (
if (msg_scrolled > 0) {
/* Put the wildmenu just above the command line. If there is
* no room, scroll the screen one line up. */
- if (cmdline_row == Rows - 1) {
- screen_del_lines(0, 0, 1, (int)Rows, NULL);
- ++msg_scrolled;
+ if (cmdline_row == default_grid.Rows - 1) {
+ grid_del_lines(&default_grid, 0, 1, (int)Rows, 0, (int)Columns);
+ msg_scrolled++;
} else {
- ++cmdline_row;
- ++row;
+ cmdline_row++;
+ row++;
}
wild_menu_showing = WM_SCROLLED;
} else {
@@ -4785,25 +4761,26 @@ win_redr_status_matches (
}
}
- screen_puts(buf, row, 0, attr);
+ grid_puts(&default_grid, buf, row, 0, attr);
if (selstart != NULL && highlight) {
*selend = NUL;
- screen_puts(selstart, row, selstart_col, hl_attr(HLF_WM));
+ grid_puts(&default_grid, selstart, row, selstart_col, HL_ATTR(HLF_WM));
}
- screen_fill(row, row + 1, clen, (int)Columns, fillchar, fillchar, attr);
+ grid_fill(&default_grid, row, row + 1, clen, (int)default_grid.Columns,
+ fillchar, fillchar, attr);
}
win_redraw_last_status(topframe);
xfree(buf);
}
-/*
- * Redraw the status line of window wp.
- *
- * If inversion is possible we use it. Else '=' characters are used.
- */
-void win_redr_status(win_T *wp)
+/// Redraw the status line of window `wp`.
+///
+/// If inversion is possible we use it. Else '=' characters are used.
+/// If "ignore_pum" is true, also redraw statusline when the popup menu is
+/// displayed.
+static void win_redr_status(win_T *wp, int ignore_pum)
{
int row;
char_u *p;
@@ -4813,28 +4790,28 @@ void win_redr_status(win_T *wp)
int this_ru_col;
static int busy = FALSE;
- /* It's possible to get here recursively when 'statusline' (indirectly)
- * invokes ":redrawstatus". Simply ignore the call then. */
- if (busy)
+ // May get here recursively when 'statusline' (indirectly)
+ // invokes ":redrawstatus". Simply ignore the call then.
+ if (busy
+ // Also ignore if wildmenu is showing.
+ || (wild_menu_showing != 0 && !ui_is_external(kUIWildmenu))) {
return;
- busy = TRUE;
+ }
+ busy = true;
wp->w_redr_status = FALSE;
if (wp->w_status_height == 0) {
- /* no status line, can only be last window */
- redraw_cmdline = TRUE;
- } else if (!redrawing()
- /* don't update status line when popup menu is visible and may be
- * drawn over it */
- || pum_visible()
- ) {
- /* Don't redraw right now, do it later. */
- wp->w_redr_status = TRUE;
+ // no status line, can only be last window
+ redraw_cmdline = true;
+ } else if (!redrawing() || (!ignore_pum && pum_drawn())) {
+ // Don't redraw right now, do it later. Don't update status line when
+ // popup menu is visible and may be drawn over it
+ wp->w_redr_status = true;
} else if (*p_stl != NUL || *wp->w_p_stl != NUL) {
/* redraw custom status line */
redraw_custom_statusline(wp);
} else {
- fillchar = fillchar_status(&attr, wp == curwin);
+ fillchar = fillchar_status(&attr, wp);
get_trans_bufname(wp->w_buffer);
p = NameBuff;
@@ -4843,8 +4820,9 @@ void win_redr_status(win_T *wp)
if (wp->w_buffer->b_help
|| wp->w_p_pvw
|| bufIsChanged(wp->w_buffer)
- || wp->w_buffer->b_p_ro)
+ || wp->w_buffer->b_p_ro) {
*(p + len++) = ' ';
+ }
if (wp->w_buffer->b_help) {
STRCPY(p + len, _("[Help]"));
len += (int)STRLEN(p + len);
@@ -4859,48 +4837,45 @@ void win_redr_status(win_T *wp)
}
if (wp->w_buffer->b_p_ro) {
STRCPY(p + len, _("[RO]"));
- len += 4;
+ // len += (int)STRLEN(p + len); // dead assignment
}
this_ru_col = ru_col - (Columns - wp->w_width);
- if (this_ru_col < (wp->w_width + 1) / 2)
+ if (this_ru_col < (wp->w_width + 1) / 2) {
this_ru_col = (wp->w_width + 1) / 2;
+ }
if (this_ru_col <= 1) {
- p = (char_u *)"<"; /* No room for file name! */
+ p = (char_u *)"<"; // No room for file name!
len = 1;
- } else if (has_mbyte) {
+ } else {
int clen = 0, i;
- /* Count total number of display cells. */
- clen = (int) mb_string2cells(p);
+ // Count total number of display cells.
+ clen = (int)mb_string2cells(p);
- /* Find first character that will fit.
- * Going from start to end is much faster for DBCS. */
+ // Find first character that will fit.
+ // Going from start to end is much faster for DBCS.
for (i = 0; p[i] != NUL && clen >= this_ru_col - 1;
- i += (*mb_ptr2len)(p + i))
- clen -= (*mb_ptr2cells)(p + i);
+ i += utfc_ptr2len(p + i)) {
+ clen -= utf_ptr2cells(p + i);
+ }
len = clen;
if (i > 0) {
p = p + i - 1;
*p = '<';
++len;
}
-
- } else if (len > this_ru_col - 1) {
- p += len - (this_ru_col - 1);
- *p = '<';
- len = this_ru_col - 1;
}
- row = wp->w_winrow + wp->w_height;
- screen_puts(p, row, wp->w_wincol, attr);
- screen_fill(row, row + 1, len + wp->w_wincol,
- this_ru_col + wp->w_wincol, fillchar, fillchar, attr);
+ row = W_ENDROW(wp);
+ grid_puts(&default_grid, p, row, wp->w_wincol, attr);
+ grid_fill(&default_grid, row, row + 1, len + wp->w_wincol,
+ this_ru_col + wp->w_wincol, fillchar, fillchar, attr);
- if (get_keymap_str(wp, NameBuff, MAXPATHL)
+ if (get_keymap_str(wp, (char_u *)"<%s>", NameBuff, MAXPATHL)
&& this_ru_col - len > (int)(STRLEN(NameBuff) + 1))
- screen_puts(NameBuff, row, (int)(this_ru_col - STRLEN(NameBuff)
- - 1 + wp->w_wincol), attr);
+ grid_puts(&default_grid, NameBuff, row,
+ (int)(this_ru_col - STRLEN(NameBuff) - 1), attr);
win_redr_ruler(wp, TRUE);
}
@@ -4909,12 +4884,12 @@ void win_redr_status(win_T *wp)
* May need to draw the character below the vertical separator.
*/
if (wp->w_vsep_width != 0 && wp->w_status_height != 0 && redrawing()) {
- if (stl_connected(wp))
- fillchar = fillchar_status(&attr, wp == curwin);
- else
- fillchar = fillchar_vsep(&attr);
- screen_putchar(fillchar, wp->w_winrow + wp->w_height,
- W_ENDCOL(wp), attr);
+ if (stl_connected(wp)) {
+ fillchar = fillchar_status(&attr, wp);
+ } else {
+ fillchar = fillchar_vsep(wp, &attr);
+ }
+ grid_putchar(&default_grid, fillchar, W_ENDROW(wp), W_ENDCOL(wp), attr);
}
busy = FALSE;
}
@@ -4925,8 +4900,8 @@ void win_redr_status(win_T *wp)
*/
static void redraw_custom_statusline(win_T *wp)
{
- static int entered = FALSE;
- int save_called_emsg = called_emsg;
+ static int entered = false;
+ int saved_did_emsg = did_emsg;
/* When called recursively return. This can happen when the statusline
* contains an expression that triggers a redraw. */
@@ -4934,18 +4909,18 @@ static void redraw_custom_statusline(win_T *wp)
return;
entered = TRUE;
- called_emsg = FALSE;
- win_redr_custom(wp, FALSE);
- if (called_emsg) {
- /* When there is an error disable the statusline, otherwise the
- * display is messed up with errors and a redraw triggers the problem
- * again and again. */
+ did_emsg = false;
+ win_redr_custom(wp, false);
+ if (did_emsg) {
+ // When there is an error disable the statusline, otherwise the
+ // display is messed up with errors and a redraw triggers the problem
+ // again and again.
set_string_option_direct((char_u *)"statusline", -1,
(char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL
? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
}
- called_emsg |= save_called_emsg;
- entered = FALSE;
+ did_emsg |= saved_did_emsg;
+ entered = false;
}
/*
@@ -4978,8 +4953,9 @@ int stl_connected(win_T *wp)
int
get_keymap_str (
win_T *wp,
- char_u *buf, /* buffer for the result */
- int len /* length of buffer */
+ char_u *fmt, // format string containing one %s item
+ char_u *buf, // buffer for the result
+ int len // length of buffer
)
{
char_u *p;
@@ -5006,10 +4982,9 @@ get_keymap_str (
else
p = (char_u *)"lang";
}
- if ((int)(STRLEN(p) + 3) < len)
- sprintf((char *)buf, "<%s>", p);
- else
+ if (vim_snprintf((char *)buf, len, (char *)fmt, p) > len - 1) {
buf[0] = NUL;
+ }
xfree(s);
}
return buf[0] != NUL;
@@ -5057,12 +5032,12 @@ win_redr_custom (
stl = p_tal;
row = 0;
fillchar = ' ';
- attr = hl_attr(HLF_TPF);
- maxwidth = Columns;
+ attr = HL_ATTR(HLF_TPF);
+ maxwidth = default_grid.Columns;
use_sandbox = was_set_insecurely((char_u *)"tabline", 0);
} else {
- row = wp->w_winrow + wp->w_height;
- fillchar = fillchar_status(&attr, wp == curwin);
+ row = W_ENDROW(wp);
+ fillchar = fillchar_status(&attr, wp);
maxwidth = wp->w_width;
if (draw_ruler) {
@@ -5077,13 +5052,14 @@ win_redr_custom (
if (*stl++ != '(')
stl = p_ruf;
}
- col = ru_col - (Columns - wp->w_width);
- if (col < (wp->w_width + 1) / 2)
+ col = ru_col - (default_grid.Columns - wp->w_width);
+ if (col < (wp->w_width + 1) / 2) {
col = (wp->w_width + 1) / 2;
+ }
maxwidth = wp->w_width - col;
if (!wp->w_status_height) {
- row = Rows - 1;
- --maxwidth; /* writing in last column may cause scrolling */
+ row = default_grid.Rows - 1;
+ maxwidth--; // writing in last column may cause scrolling
fillchar = ' ';
attr = 0;
}
@@ -5119,28 +5095,30 @@ win_redr_custom (
xfree(stl);
ewp->w_p_crb = p_crb_save;
- /* Make all characters printable. */
- p = transstr(buf);
+ // Make all characters printable.
+ p = (char_u *)transstr((const char *)buf);
len = STRLCPY(buf, p, sizeof(buf));
len = (size_t)len < sizeof(buf) ? len : (int)sizeof(buf) - 1;
xfree(p);
/* fill up with "fillchar" */
while (width < maxwidth && len < (int)sizeof(buf) - 1) {
- len += (*mb_char2bytes)(fillchar, buf + len);
- ++width;
+ len += utf_char2bytes(fillchar, buf + len);
+ width++;
}
buf[len] = NUL;
/*
* Draw each snippet with the specified highlighting.
*/
+ screen_puts_line_start(row);
+
curattr = attr;
p = buf;
for (n = 0; hltab[n].start != NULL; n++) {
- int len = (int)(hltab[n].start - p);
- screen_puts_len(p, len, row, col, curattr);
- col += vim_strnsize(p, len);
+ int textlen = (int)(hltab[n].start - p);
+ grid_puts_len(&default_grid, p, textlen, row, col, curattr);
+ col += vim_strnsize(p, textlen);
p = hltab[n].start;
if (hltab[n].userhl == 0)
@@ -5153,7 +5131,10 @@ win_redr_custom (
curattr = highlight_user[hltab[n].userhl - 1];
}
// Make sure to use an empty string instead of p, if p is beyond buf + len.
- screen_puts(p >= buf + len ? (char_u *)"" : p, row, col, curattr);
+ grid_puts(&default_grid, p >= buf + len ? (char_u *)"" : p, row, col,
+ curattr);
+
+ grid_puts_line_flush(&default_grid, false);
if (wp == NULL) {
// Fill the tab_page_click_defs array for clicking in the tab pages line.
@@ -5171,7 +5152,7 @@ win_redr_custom (
p = (char_u *) tabtab[n].start;
cur_click_def = tabtab[n].def;
}
- while (col < Columns) {
+ while (col < default_grid.Columns) {
tab_page_click_defs[col++] = cur_click_def;
}
}
@@ -5180,86 +5161,144 @@ theend:
entered = FALSE;
}
+// Low-level functions to manipulate invidual character cells on the
+// screen grid.
-/*
- * Output a single character directly to the screen and update ScreenLines.
- */
-void screen_putchar(int c, int row, int col, int attr)
+/// Put a ASCII character in a screen cell.
+static void schar_from_ascii(char_u *p, const char c)
{
- char_u buf[MB_MAXBYTES + 1];
+ p[0] = c;
+ p[1] = 0;
+}
+
+/// Put a unicode character in a screen cell.
+static int schar_from_char(char_u *p, int c)
+{
+ int len = utf_char2bytes(c, p);
+ p[len] = NUL;
+ return len;
+}
- if (has_mbyte)
- buf[(*mb_char2bytes)(c, buf)] = NUL;
- else {
- buf[0] = c;
- buf[1] = NUL;
+/// Put a unicode char, and up to MAX_MCO composing chars, in a screen cell.
+static int schar_from_cc(char_u *p, int c, int u8cc[MAX_MCO])
+{
+ int len = utf_char2bytes(c, p);
+ for (int i = 0; i < MAX_MCO; i++) {
+ if (u8cc[i] == 0) {
+ break;
+ }
+ len += utf_char2bytes(u8cc[i], p + len);
}
- screen_puts(buf, row, col, attr);
+ p[len] = 0;
+ return len;
}
-/*
- * Get a single character directly from ScreenLines into "bytes[]".
- * Also return its attribute in *attrp;
- */
-void screen_getbytes(int row, int col, char_u *bytes, int *attrp)
+/// compare the contents of two screen cells.
+static int schar_cmp(char_u *sc1, char_u *sc2)
{
- unsigned off;
+ return STRNCMP(sc1, sc2, sizeof(schar_T));
+}
- /* safety check */
- if (ScreenLines != NULL && row < screen_Rows && col < screen_Columns) {
- off = LineOffset[row] + col;
- *attrp = ScreenAttrs[off];
- bytes[0] = ScreenLines[off];
- bytes[1] = NUL;
+/// copy the contents of screen cell `sc2` into cell `sc1`
+static void schar_copy(char_u *sc1, char_u *sc2)
+{
+ STRLCPY(sc1, sc2, sizeof(schar_T));
+}
- if (enc_utf8 && ScreenLinesUC[off] != 0)
- bytes[utfc_char2bytes(off, bytes)] = NUL;
- else if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e) {
- bytes[0] = ScreenLines[off];
- bytes[1] = ScreenLines2[off];
- bytes[2] = NUL;
- } else if (enc_dbcs && MB_BYTE2LEN(bytes[0]) > 1) {
- bytes[1] = ScreenLines[off + 1];
- bytes[2] = NUL;
- }
+static int line_off2cells(schar_T *line, size_t off, size_t max_off)
+{
+ return (off + 1 < max_off && line[off + 1][0] == 0) ? 2 : 1;
+}
+
+/// Return number of display cells for char at grid->chars[off].
+/// We make sure that the offset used is less than "max_off".
+static int grid_off2cells(ScreenGrid *grid, size_t off, size_t max_off)
+{
+ return line_off2cells(grid->chars, off, max_off);
+}
+
+/// Return true if the character at "row"/"col" on the screen is the left side
+/// of a double-width character.
+///
+/// Caller must make sure "row" and "col" are not invalid!
+bool grid_lefthalve(ScreenGrid *grid, int row, int col)
+{
+ screen_adjust_grid(&grid, &row, &col);
+
+ return grid_off2cells(grid, grid->line_offset[row] + col,
+ grid->line_offset[row] + grid->Columns) > 1;
+}
+
+/// Correct a position on the screen, if it's the right half of a double-wide
+/// char move it to the left half. Returns the corrected column.
+int grid_fix_col(ScreenGrid *grid, int col, int row)
+{
+ int coloff = 0;
+ screen_adjust_grid(&grid, &row, &coloff);
+
+ col += coloff;
+ if (grid->chars != NULL && col > 0
+ && grid->chars[grid->line_offset[row] + col][0] == 0) {
+ return col - 1 - coloff;
}
+ return col - coloff;
}
+/// output a single character directly to the grid
+void grid_putchar(ScreenGrid *grid, int c, int row, int col, int attr)
+{
+ char_u buf[MB_MAXBYTES + 1];
-/*
- * Return TRUE if composing characters for screen posn "off" differs from
- * composing characters in "u8cc".
- * Only to be used when ScreenLinesUC[off] != 0.
- */
-static int screen_comp_differs(int off, int *u8cc)
+ buf[utf_char2bytes(c, buf)] = NUL;
+ grid_puts(grid, buf, row, col, attr);
+}
+
+/// get a single character directly from grid.chars into "bytes[]".
+/// Also return its attribute in *attrp;
+void grid_getbytes(ScreenGrid *grid, int row, int col, char_u *bytes,
+ int *attrp)
{
- int i;
+ unsigned off;
- for (i = 0; i < Screen_mco; ++i) {
- if (ScreenLinesC[i][off] != (u8char_T)u8cc[i])
- return TRUE;
- if (u8cc[i] == 0)
- break;
+ screen_adjust_grid(&grid, &row, &col);
+
+
+ // safety check
+ if (grid->chars != NULL && row < grid->Rows && col < grid->Columns) {
+ off = grid->line_offset[row] + col;
+ *attrp = grid->attrs[off];
+ schar_copy(bytes, grid->chars[off]);
}
- return FALSE;
}
-/*
- * Put string '*text' on the screen at position 'row' and 'col', with
- * attributes 'attr', and update ScreenLines[] and ScreenAttrs[].
- * Note: only outputs within one row, message is truncated at screen boundary!
- * Note: if ScreenLines[], row and/or col is invalid, nothing is done.
- */
-void screen_puts(char_u *text, int row, int col, int attr)
+
+/// put string '*text' on the window grid at position 'row' and 'col', with
+/// attributes 'attr', and update chars[] and attrs[].
+/// Note: only outputs within one row, message is truncated at grid boundary!
+/// Note: if grid, row and/or col is invalid, nothing is done.
+void grid_puts(ScreenGrid *grid, char_u *text, int row, int col, int attr)
{
- screen_puts_len(text, -1, row, col, attr);
+ grid_puts_len(grid, text, -1, row, col, attr);
}
-/*
- * Like screen_puts(), but output "text[len]". When "len" is -1 output up to
- * a NUL.
- */
-void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
+static int put_dirty_row = -1;
+static int put_dirty_first = -1;
+static int put_dirty_last = 0;
+
+/// Start a group of screen_puts_len calls that builds a single screen line.
+///
+/// Must be matched with a screen_puts_line_flush call before moving to
+/// another line.
+void screen_puts_line_start(int row)
+{
+ assert(put_dirty_row == -1);
+ put_dirty_row = row;
+}
+
+/// like grid_puts(), but output "text[len]". When "len" is -1 output up to
+/// a NUL.
+void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
+ int col, int attr)
{
unsigned off;
char_u *ptr = text;
@@ -5277,181 +5316,160 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
int force_redraw_this;
int force_redraw_next = FALSE;
int need_redraw;
+ bool do_flush = false;
- const int l_has_mbyte = has_mbyte;
- const bool l_enc_utf8 = enc_utf8;
- const int l_enc_dbcs = enc_dbcs;
+ screen_adjust_grid(&grid, &row, &col);
- assert((l_has_mbyte == (l_enc_utf8 || l_enc_dbcs))
- && !(l_enc_utf8 && l_enc_dbcs));
-
- if (ScreenLines == NULL || row >= screen_Rows) /* safety check */
+ // safety check
+ if (grid->chars == NULL || row >= grid->Rows || col >= grid->Columns) {
return;
- off = LineOffset[row] + col;
+ }
+
+ if (put_dirty_row == -1) {
+ screen_puts_line_start(row);
+ do_flush = true;
+ } else {
+ if (row != put_dirty_row) {
+ abort();
+ }
+ }
+ off = grid->line_offset[row] + col;
/* When drawing over the right halve of a double-wide char clear out the
* left halve. Only needed in a terminal. */
- if (l_has_mbyte && col > 0 && col < screen_Columns
- && mb_fix_col(col, row) != col) {
- ScreenLines[off - 1] = ' ';
- ScreenAttrs[off - 1] = 0;
- if (l_enc_utf8) {
- ScreenLinesUC[off - 1] = 0;
- ScreenLinesC[0][off - 1] = 0;
- }
- /* redraw the previous cell, make it empty */
- screen_char(off - 1, row, col - 1);
- /* force the cell at "col" to be redrawn */
- force_redraw_next = TRUE;
- }
-
- max_off = LineOffset[row] + screen_Columns;
- while (col < screen_Columns
+ if (col > 0 && col < grid->Columns && grid_fix_col(grid, col, row) != col) {
+ schar_from_ascii(grid->chars[off - 1], ' ');
+ grid->attrs[off - 1] = 0;
+ // redraw the previous cell, make it empty
+ if (put_dirty_first == -1) {
+ put_dirty_first = col-1;
+ }
+ put_dirty_last = col+1;
+ // force the cell at "col" to be redrawn
+ force_redraw_next = true;
+ }
+
+ max_off = grid->line_offset[row] + grid->Columns;
+ while (col < grid->Columns
&& (len < 0 || (int)(ptr - text) < len)
&& *ptr != NUL) {
c = *ptr;
- /* check if this is the first byte of a multibyte */
- if (l_has_mbyte) {
- if (l_enc_utf8 && len > 0)
- mbyte_blen = utfc_ptr2len_len(ptr, (int)((text + len) - ptr));
- else
- mbyte_blen = (*mb_ptr2len)(ptr);
- if (l_enc_dbcs == DBCS_JPNU && c == 0x8e)
- mbyte_cells = 1;
- else if (l_enc_dbcs != 0)
- mbyte_cells = mbyte_blen;
- else { /* enc_utf8 */
- if (len >= 0)
- u8c = utfc_ptr2char_len(ptr, u8cc,
- (int)((text + len) - ptr));
- else
- u8c = utfc_ptr2char(ptr, u8cc);
- mbyte_cells = utf_char2cells(u8c);
- if (p_arshape && !p_tbidi && arabic_char(u8c)) {
- /* Do Arabic shaping. */
- if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) {
- /* Past end of string to be displayed. */
- nc = NUL;
- nc1 = NUL;
- } else {
- nc = utfc_ptr2char_len(ptr + mbyte_blen, pcc,
- (int)((text + len) - ptr - mbyte_blen));
- nc1 = pcc[0];
- }
- pc = prev_c;
- prev_c = u8c;
- u8c = arabic_shape(u8c, &c, &u8cc[0], nc, nc1, pc);
- } else
- prev_c = u8c;
- if (col + mbyte_cells > screen_Columns) {
- /* Only 1 cell left, but character requires 2 cells:
- * display a '>' in the last column to avoid wrapping. */
- c = '>';
- mbyte_cells = 1;
- }
+ // check if this is the first byte of a multibyte
+ if (len > 0) {
+ mbyte_blen = utfc_ptr2len_len(ptr, (int)((text + len) - ptr));
+ } else {
+ mbyte_blen = utfc_ptr2len(ptr);
+ }
+ if (len >= 0) {
+ u8c = utfc_ptr2char_len(ptr, u8cc, (int)((text + len) - ptr));
+ } else {
+ u8c = utfc_ptr2char(ptr, u8cc);
+ }
+ mbyte_cells = utf_char2cells(u8c);
+ if (p_arshape && !p_tbidi && arabic_char(u8c)) {
+ // Do Arabic shaping.
+ if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) {
+ // Past end of string to be displayed.
+ nc = NUL;
+ nc1 = NUL;
+ } else {
+ nc = utfc_ptr2char_len(ptr + mbyte_blen, pcc,
+ (int)((text + len) - ptr - mbyte_blen));
+ nc1 = pcc[0];
}
+ pc = prev_c;
+ prev_c = u8c;
+ u8c = arabic_shape(u8c, &c, &u8cc[0], nc, nc1, pc);
+ } else {
+ prev_c = u8c;
+ }
+ if (col + mbyte_cells > grid->Columns) {
+ // Only 1 cell left, but character requires 2 cells:
+ // display a '>' in the last column to avoid wrapping. */
+ c = '>';
+ mbyte_cells = 1;
}
+ schar_T buf;
+ schar_from_cc(buf, u8c, u8cc);
+
+
force_redraw_this = force_redraw_next;
force_redraw_next = FALSE;
- need_redraw = ScreenLines[off] != c
- || (mbyte_cells == 2
- && ScreenLines[off + 1] != (l_enc_dbcs ? ptr[1] : 0))
- || (l_enc_dbcs == DBCS_JPNU
- && c == 0x8e
- && ScreenLines2[off] != ptr[1])
- || (l_enc_utf8
- && (ScreenLinesUC[off] !=
- (u8char_T)(c < 0x80 && u8cc[0] == 0 ? 0 : u8c)
- || (ScreenLinesUC[off] != 0
- && screen_comp_differs(off, u8cc))))
- || ScreenAttrs[off] != attr
+ need_redraw = schar_cmp(grid->chars[off], buf)
+ || (mbyte_cells == 2 && grid->chars[off + 1][0] != 0)
+ || grid->attrs[off] != attr
|| exmode_active;
- if (need_redraw
- || force_redraw_this
- ) {
- /* When at the end of the text and overwriting a two-cell
- * character with a one-cell character, need to clear the next
- * cell. Also when overwriting the left halve of a two-cell char
- * with the right halve of a two-cell char. Do this only once
- * (mb_off2cells() may return 2 on the right halve). */
- if (clear_next_cell)
- clear_next_cell = FALSE;
- else if (l_has_mbyte
- && (len < 0 ? ptr[mbyte_blen] == NUL
- : ptr + mbyte_blen >= text + len)
- && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
- || (mbyte_cells == 2
- && (*mb_off2cells)(off, max_off) == 1
- && (*mb_off2cells)(off + 1, max_off) > 1)))
- clear_next_cell = TRUE;
-
- /* Make sure we never leave a second byte of a double-byte behind,
- * it confuses mb_off2cells(). */
- if (l_enc_dbcs
- && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1)
- || (mbyte_cells == 2
- && (*mb_off2cells)(off, max_off) == 1
- && (*mb_off2cells)(off + 1, max_off) > 1)))
- ScreenLines[off + mbyte_blen] = 0;
- ScreenLines[off] = c;
- ScreenAttrs[off] = attr;
- if (l_enc_utf8) {
- if (c < 0x80 && u8cc[0] == 0)
- ScreenLinesUC[off] = 0;
- else {
- int i;
-
- ScreenLinesUC[off] = u8c;
- for (i = 0; i < Screen_mco; ++i) {
- ScreenLinesC[i][off] = u8cc[i];
- if (u8cc[i] == 0)
- break;
- }
- }
- if (mbyte_cells == 2) {
- ScreenLines[off + 1] = 0;
- ScreenAttrs[off + 1] = attr;
- }
- screen_char(off, row, col);
- } else if (mbyte_cells == 2) {
- ScreenLines[off + 1] = ptr[1];
- ScreenAttrs[off + 1] = attr;
- screen_char_2(off, row, col);
- } else if (l_enc_dbcs == DBCS_JPNU && c == 0x8e) {
- ScreenLines2[off] = ptr[1];
- screen_char(off, row, col);
- } else
- screen_char(off, row, col);
- }
- if (l_has_mbyte) {
- off += mbyte_cells;
- col += mbyte_cells;
- ptr += mbyte_blen;
+ if (need_redraw || force_redraw_this) {
+ // When at the end of the text and overwriting a two-cell
+ // character with a one-cell character, need to clear the next
+ // cell. Also when overwriting the left halve of a two-cell char
+ // with the right halve of a two-cell char. Do this only once
+ // (utf8_off2cells() may return 2 on the right halve).
if (clear_next_cell) {
- // This only happens at the end, display one space next.
- ptr = (char_u *)" ";
- len = -1;
+ clear_next_cell = false;
+ } else if ((len < 0 ? ptr[mbyte_blen] == NUL
+ : ptr + mbyte_blen >= text + len)
+ && ((mbyte_cells == 1
+ && grid_off2cells(grid, off, max_off) > 1)
+ || (mbyte_cells == 2
+ && grid_off2cells(grid, off, max_off) == 1
+ && grid_off2cells(grid, off + 1, max_off) > 1))) {
+ clear_next_cell = true;
}
- } else {
- ++off;
- ++col;
- ++ptr;
+
+ schar_copy(grid->chars[off], buf);
+ grid->attrs[off] = attr;
+ if (mbyte_cells == 2) {
+ grid->chars[off + 1][0] = 0;
+ grid->attrs[off + 1] = attr;
+ }
+ if (put_dirty_first == -1) {
+ put_dirty_first = col;
+ }
+ put_dirty_last = col+mbyte_cells;
+ }
+
+ off += mbyte_cells;
+ col += mbyte_cells;
+ ptr += mbyte_blen;
+ if (clear_next_cell) {
+ // This only happens at the end, display one space next.
+ ptr = (char_u *)" ";
+ len = -1;
}
}
- /* If we detected the next character needs to be redrawn, but the text
- * doesn't extend up to there, update the character here. */
- if (force_redraw_next && col < screen_Columns) {
- if (l_enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1)
- screen_char_2(off, row, col);
- else
- screen_char(off, row, col);
+ if (do_flush) {
+ grid_puts_line_flush(grid, true);
}
}
+/// End a group of screen_puts_len calls and send the screen buffer to the UI
+/// layer.
+///
+/// @param grid The grid which contains the buffer.
+/// @param set_cursor Move the visible cursor to the end of the changed region.
+/// This is a workaround for not yet refactored code paths
+/// and shouldn't be used in new code.
+void grid_puts_line_flush(ScreenGrid *grid, bool set_cursor)
+{
+ assert(put_dirty_row != -1);
+ if (put_dirty_first != -1) {
+ if (set_cursor) {
+ ui_grid_cursor_goto(grid->handle, put_dirty_row,
+ MIN(put_dirty_last, grid->Columns-1));
+ }
+ ui_line(grid, put_dirty_row, put_dirty_first, put_dirty_last,
+ put_dirty_last, 0, false);
+ put_dirty_first = -1;
+ put_dirty_last = 0;
+ }
+ put_dirty_row = -1;
+}
+
/*
* Prepare for 'hlsearch' highlighting.
*/
@@ -5459,8 +5477,7 @@ static void start_search_hl(void)
{
if (p_hls && !no_hlsearch) {
last_pat_prog(&search_hl.rm);
- search_hl.attr = hl_attr(HLF_L);
- /* Set the time limit to 'redrawtime'. */
+ // Set the time limit to 'redrawtime'.
search_hl.tm = profile_setlimit(p_rdt);
}
}
@@ -5476,6 +5493,7 @@ static void end_search_hl(void)
}
}
+
/*
* Init for calling prepare_search_hl().
*/
@@ -5502,7 +5520,9 @@ static void init_search_hl(win_T *wp)
search_hl.buf = wp->w_buffer;
search_hl.lnum = 0;
search_hl.first_lnum = 0;
- /* time limit is set at the toplevel, for all windows */
+ search_hl.attr = win_hl_attr(wp, HLF_L);
+
+ // time limit is set at the toplevel, for all windows
}
/*
@@ -5522,22 +5542,25 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
* Do this both for search_hl and the match list.
*/
cur = wp->w_match_head;
- shl_flag = FALSE;
- while (cur != NULL || shl_flag == FALSE) {
- if (shl_flag == FALSE) {
+ shl_flag = false;
+ while (cur != NULL || shl_flag == false) {
+ if (shl_flag == false) {
shl = &search_hl;
- shl_flag = TRUE;
- } else
- shl = &cur->hl;
+ shl_flag = true;
+ } else {
+ shl = &cur->hl; // -V595
+ }
if (shl->rm.regprog != NULL
&& shl->lnum == 0
&& re_multiline(shl->rm.regprog)) {
if (shl->first_lnum == 0) {
for (shl->first_lnum = lnum;
- shl->first_lnum > wp->w_topline; --shl->first_lnum)
- if (hasFoldingWin(wp, shl->first_lnum - 1,
- NULL, NULL, TRUE, NULL))
+ shl->first_lnum > wp->w_topline;
+ shl->first_lnum--) {
+ if (hasFoldingWin(wp, shl->first_lnum - 1, NULL, NULL, true, NULL)) {
break;
+ }
+ }
}
if (cur != NULL) {
cur->pos.cur = 0;
@@ -5546,8 +5569,9 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
// in progress
n = 0;
while (shl->first_lnum < lnum && (shl->rm.regprog != NULL
- || (cur != NULL && pos_inprogress))) {
- next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n, cur);
+ || (cur != NULL && pos_inprogress))) {
+ next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n,
+ shl == &search_hl ? NULL : cur);
pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
if (shl->lnum != 0) {
shl->first_lnum = shl->lnum
@@ -5585,6 +5609,7 @@ next_search_hl (
linenr_T l;
colnr_T matchcol;
long nmatched = 0;
+ int save_called_emsg = called_emsg;
if (shl->lnum != 0) {
/* Check for three situations:
@@ -5677,9 +5702,14 @@ next_search_hl (
shl->lnum += shl->rm.startpos[0].lnum;
break; /* useful match found */
}
+
+ // Restore called_emsg for assert_fails().
+ called_emsg = save_called_emsg;
}
}
+/// If there is a match fill "shl" and return one.
+/// Return zero otherwise.
static int
next_search_hl_pos(
match_T *shl, // points to a match
@@ -5689,254 +5719,148 @@ next_search_hl_pos(
)
{
int i;
- int bot = -1;
+ int found = -1;
shl->lnum = 0;
for (i = posmatch->cur; i < MAXPOSMATCH; i++) {
- if (posmatch->pos[i].lnum == 0) {
+ llpos_T *pos = &posmatch->pos[i];
+
+ if (pos->lnum == 0) {
break;
}
- if (posmatch->pos[i].col < mincol) {
+ if (pos->len == 0 && pos->col < mincol) {
continue;
}
- if (posmatch->pos[i].lnum == lnum) {
- if (bot != -1) {
- // partially sort positions by column numbers
- // on the same line
- if (posmatch->pos[i].col < posmatch->pos[bot].col) {
- llpos_T tmp = posmatch->pos[i];
+ if (pos->lnum == lnum) {
+ if (found >= 0) {
+ // if this match comes before the one at "found" then swap
+ // them
+ if (pos->col < posmatch->pos[found].col) {
+ llpos_T tmp = *pos;
- posmatch->pos[i] = posmatch->pos[bot];
- posmatch->pos[bot] = tmp;
+ *pos = posmatch->pos[found];
+ posmatch->pos[found] = tmp;
}
} else {
- bot = i;
- shl->lnum = lnum;
+ found = i;
}
}
}
posmatch->cur = 0;
- if (bot != -1) {
- colnr_T start = posmatch->pos[bot].col == 0
- ? 0: posmatch->pos[bot].col - 1;
- colnr_T end = posmatch->pos[bot].col == 0
- ? MAXCOL : start + posmatch->pos[bot].len;
+ if (found >= 0) {
+ colnr_T start = posmatch->pos[found].col == 0
+ ? 0: posmatch->pos[found].col - 1;
+ colnr_T end = posmatch->pos[found].col == 0
+ ? MAXCOL : start + posmatch->pos[found].len;
+ shl->lnum = lnum;
shl->rm.startpos[0].lnum = 0;
shl->rm.startpos[0].col = start;
shl->rm.endpos[0].lnum = 0;
shl->rm.endpos[0].col = end;
- posmatch->cur = bot + 1;
- return true;
+ shl->is_addpos = true;
+ posmatch->cur = found + 1;
+ return 1;
}
- return false;
+ return 0;
}
-static void screen_start_highlight(int attr)
-{
- screen_attr = attr;
- ui_start_highlight(attr);
-}
-void screen_stop_highlight(void)
+/// Fill the grid from 'start_row' to 'end_row', from 'start_col' to 'end_col'
+/// with character 'c1' in first column followed by 'c2' in the other columns.
+/// Use attributes 'attr'.
+void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
+ int end_col, int c1, int c2, int attr)
{
- ui_stop_highlight();
- screen_attr = 0;
-}
+ schar_T sc;
-/*
- * Put character ScreenLines["off"] on the screen at position "row" and "col",
- * using the attributes from ScreenAttrs["off"].
- */
-static void screen_char(unsigned off, int row, int col)
-{
- int attr;
-
- /* Check for illegal values, just in case (could happen just after
- * resizing). */
- if (row >= screen_Rows || col >= screen_Columns)
- return;
+ int row_off = 0, col_off = 0;
+ screen_adjust_grid(&grid, &row_off, &col_off);
+ start_row += row_off;
+ end_row += row_off;
+ start_col += col_off;
+ end_col += col_off;
- /* Outputting the last character on the screen may scrollup the screen.
- * Don't to it! Mark the character invalid (update it when scrolled up) */
- if (row == screen_Rows - 1 && col == screen_Columns - 1
- /* account for first command-line character in rightleft mode */
- && !cmdmsg_rl
- ) {
- ScreenAttrs[off] = (sattr_T)-1;
- return;
+ // safety check
+ if (end_row > grid->Rows) {
+ end_row = grid->Rows;
}
-
- /*
- * Stop highlighting first, so it's easier to move the cursor.
- */
- attr = ScreenAttrs[off];
- if (screen_attr != attr)
- screen_stop_highlight();
-
- ui_cursor_goto(row, col);
-
- if (screen_attr != attr)
- screen_start_highlight(attr);
-
- if (enc_utf8 && ScreenLinesUC[off] != 0) {
- char_u buf[MB_MAXBYTES + 1];
-
- // Convert UTF-8 character to bytes and write it.
- buf[utfc_char2bytes(off, buf)] = NUL;
- ui_puts(buf);
- } else {
- ui_putc(ScreenLines[off]);
- // double-byte character in single-width cell
- if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e) {
- ui_putc(ScreenLines2[off]);
- }
+ if (end_col > grid->Columns) {
+ end_col = grid->Columns;
}
-}
-
-/*
- * Used for enc_dbcs only: Put one double-wide character at ScreenLines["off"]
- * on the screen at position 'row' and 'col'.
- * The attributes of the first byte is used for all. This is required to
- * output the two bytes of a double-byte character with nothing in between.
- */
-static void screen_char_2(unsigned off, int row, int col)
-{
- /* Check for illegal values (could be wrong when screen was resized). */
- if (off + 1 >= (unsigned)(screen_Rows * screen_Columns))
- return;
- /* Outputting the last character on the screen may scrollup the screen.
- * Don't to it! Mark the character invalid (update it when scrolled up) */
- if (row == screen_Rows - 1 && col >= screen_Columns - 2) {
- ScreenAttrs[off] = (sattr_T)-1;
+ // nothing to do
+ if (grid->chars == NULL || start_row >= end_row || start_col >= end_col) {
return;
}
- /* Output the first byte normally (positions the cursor), then write the
- * second byte directly. */
- screen_char(off, row, col);
- ui_putc(ScreenLines[off + 1]);
-}
-
-/*
- * Fill the screen from 'start_row' to 'end_row', from 'start_col' to 'end_col'
- * with character 'c1' in first column followed by 'c2' in the other columns.
- * Use attributes 'attr'.
- */
-void screen_fill(int start_row, int end_row, int start_col, int end_col, int c1, int c2, int attr)
-{
- int row;
- int col;
- int off;
- int end_off;
- int did_delete;
- int c;
-
- if (end_row > screen_Rows) /* safety check */
- end_row = screen_Rows;
- if (end_col > screen_Columns) /* safety check */
- end_col = screen_Columns;
- if (ScreenLines == NULL
- || start_row >= end_row
- || start_col >= end_col) /* nothing to do */
- return;
-
- /* it's a "normal" terminal when not in a GUI or cterm */
- for (row = start_row; row < end_row; ++row) {
+ for (int row = start_row; row < end_row; row++) {
if (has_mbyte) {
// When drawing over the right halve of a double-wide char clear
// out the left halve. When drawing over the left halve of a
// double wide-char clear out the right halve. Only needed in a
// terminal.
- if (start_col > 0 && mb_fix_col(start_col, row) != start_col) {
- screen_puts_len((char_u *)" ", 1, row, start_col - 1, 0);
+ if (start_col > 0 && grid_fix_col(grid, start_col, row) != start_col) {
+ grid_puts_len(grid, (char_u *)" ", 1, row, start_col - 1, 0);
}
- if (end_col < screen_Columns && mb_fix_col(end_col, row) != end_col) {
- screen_puts_len((char_u *)" ", 1, row, end_col, 0);
+ if (end_col < grid->Columns
+ && grid_fix_col(grid, end_col, row) != end_col) {
+ grid_puts_len(grid, (char_u *)" ", 1, row, end_col, 0);
}
}
- /*
- * Try to use delete-line termcap code, when no attributes or in a
- * "normal" terminal, where a bold/italic space is just a
- * space.
- */
- did_delete = FALSE;
- if (c2 == ' '
- && end_col == Columns
- && attr == 0) {
- /*
- * check if we really need to clear something
- */
- col = start_col;
- if (c1 != ' ') /* don't clear first char */
- ++col;
-
- off = LineOffset[row] + col;
- end_off = LineOffset[row] + end_col;
- /* skip blanks (used often, keep it fast!) */
- if (enc_utf8)
- while (off < end_off && ScreenLines[off] == ' '
- && ScreenAttrs[off] == 0 && ScreenLinesUC[off] == 0)
- ++off;
- else
- while (off < end_off && ScreenLines[off] == ' '
- && ScreenAttrs[off] == 0)
- ++off;
- if (off < end_off) { /* something to be cleared */
- col = off - LineOffset[row];
- screen_stop_highlight();
- ui_cursor_goto(row, col); // clear rest of this screen line
- ui_eol_clear();
- col = end_col - col;
- while (col--) { /* clear chars in ScreenLines */
- ScreenLines[off] = ' ';
- if (enc_utf8)
- ScreenLinesUC[off] = 0;
- ScreenAttrs[off] = 0;
- ++off;
+ // if grid was resized (in ext_multigrid mode), the UI has no redraw updates
+ // for the newly resized grid. It is better mark everything as dirty and
+ // send all the updates.
+ int dirty_first = INT_MAX;
+ int dirty_last = 0;
+
+ int col = start_col;
+ schar_from_char(sc, c1);
+ int lineoff = grid->line_offset[row];
+ for (col = start_col; col < end_col; col++) {
+ int off = lineoff + col;
+ if (schar_cmp(grid->chars[off], sc)
+ || grid->attrs[off] != attr) {
+ schar_copy(grid->chars[off], sc);
+ grid->attrs[off] = attr;
+ if (dirty_first == INT_MAX) {
+ dirty_first = col;
+ }
+ dirty_last = col+1;
+ }
+ if (col == start_col) {
+ schar_from_char(sc, c2);
+ }
+ }
+ if (dirty_last > dirty_first) {
+ // TODO(bfredl): support a cleared suffix even with a batched line?
+ if (put_dirty_row == row) {
+ if (put_dirty_first == -1) {
+ put_dirty_first = dirty_first;
}
+ put_dirty_last = MAX(put_dirty_last, dirty_last);
+ } else {
+ int last = c2 != ' ' ? dirty_last : dirty_first + (c1 != ' ');
+ ui_line(grid, row, dirty_first, last, dirty_last, attr, false);
}
- did_delete = TRUE; /* the chars are cleared now */
}
- off = LineOffset[row] + start_col;
- c = c1;
- for (col = start_col; col < end_col; ++col) {
- if (ScreenLines[off] != c
- || (enc_utf8 && (int)ScreenLinesUC[off]
- != (c >= 0x80 ? c : 0))
- || ScreenAttrs[off] != attr
- ) {
- ScreenLines[off] = c;
- if (enc_utf8) {
- if (c >= 0x80) {
- ScreenLinesUC[off] = c;
- ScreenLinesC[0][off] = 0;
- } else
- ScreenLinesUC[off] = 0;
- }
- ScreenAttrs[off] = attr;
- if (!did_delete || c != ' ')
- screen_char(off, row, col);
+ if (end_col == grid->Columns) {
+ grid->line_wraps[row] = false;
+ }
+
+ // TODO(bfredl): The relevant caller should do this
+ if (row == default_grid.Rows - 1) { // overwritten the command line
+ redraw_cmdline = true;
+ if (start_col == 0 && end_col == Columns
+ && c1 == ' ' && c2 == ' ' && attr == 0) {
+ clear_cmdline = false; // command line has been cleared
}
- ++off;
- if (col == start_col) {
- if (did_delete)
- break;
- c = c2;
+ if (start_col == 0) {
+ mode_displayed = false; // mode cleared or overwritten
}
}
- if (end_col == Columns)
- LineWraps[row] = FALSE;
- if (row == Rows - 1) { /* overwritten the command line */
- redraw_cmdline = TRUE;
- if (c1 == ' ' && c2 == ' ')
- clear_cmdline = FALSE; /* command line has been cleared */
- if (start_col == 0)
- mode_displayed = FALSE; /* mode cleared or overwritten */
- }
}
}
@@ -5965,57 +5889,106 @@ void check_for_delay(int check_msg_scroll)
*/
int screen_valid(int doclear)
{
- screenalloc(doclear); /* allocate screen buffers if size changed */
- return ScreenLines != NULL;
+ screenalloc(doclear); // allocate screen buffers if size changed
+ return default_grid.chars != NULL;
}
-/*
- * Resize the shell to Rows and Columns.
- * Allocate ScreenLines[] and associated items.
- *
- * There may be some time between setting Rows and Columns and (re)allocating
- * ScreenLines[]. This happens when starting up and when (manually) changing
- * the shell size. Always use screen_Rows and screen_Columns to access items
- * in ScreenLines[]. Use Rows and Columns for positioning text etc. where the
- * final size of the shell is needed.
- */
+/// (Re)allocates a window grid if size changed while in ext_multigrid mode.
+/// Updates size, offsets and handle for the grid regardless.
+///
+/// If "doclear" is true, don't try to copy from the old grid rather clear the
+/// resized grid.
+void win_grid_alloc(win_T *wp)
+{
+ ScreenGrid *grid = &wp->w_grid;
+
+ int rows = grid->requested_rows;
+ if (rows == 0) {
+ rows = wp->w_height;
+ }
+
+ int columns = grid->requested_cols;
+ if (columns == 0) {
+ columns = wp->w_width;
+ }
+
+ // TODO(bfredl): floating windows should force this to true
+ bool want_allocation = ui_is_external(kUIMultigrid);
+ bool has_allocation = (grid->chars != NULL);
+
+ if (want_allocation && has_allocation && highlights_invalid) {
+ grid_invalidate(grid);
+ }
+
+ int was_resized = false;
+ if ((has_allocation != want_allocation)
+ || grid->Rows != rows
+ || grid->Columns != columns) {
+ if (want_allocation) {
+ grid_alloc(grid, rows, columns, true);
+ win_free_lsize(wp);
+ win_alloc_lines(wp);
+ } else {
+ // Single grid mode, all rendering will be redirected to default_grid.
+ // Only keep track of the size and offset of the window.
+ grid_free(grid);
+ grid->Rows = rows;
+ grid->Columns = columns;
+ }
+ was_resized = true;
+ }
+
+ grid->row_offset = wp->w_winrow;
+ grid->col_offset = wp->w_wincol;
+
+ // send grid resize event if:
+ // - a grid was just resized
+ // - screen_resize was called and all grid sizes must be sent
+ // - the UI wants multigrid event (necessary)
+ if ((send_grid_resize || was_resized) && ui_is_external(kUIMultigrid)) {
+ ui_call_grid_resize(grid->handle, grid->Columns, grid->Rows);
+ }
+}
+
+/// assign a handle to the grid. The grid need not be allocated.
+void grid_assign_handle(ScreenGrid *grid)
+{
+ static int last_grid_handle = DEFAULT_GRID_HANDLE;
+
+ // only assign a grid handle if not already
+ if (grid->handle == 0) {
+ grid->handle = ++last_grid_handle;
+ }
+}
+
+/// Resize the screen to Rows and Columns.
+///
+/// Allocate default_grid.chars[] and other grid arrays.
+///
+/// There may be some time between setting Rows and Columns and (re)allocating
+/// default_grid arrays. This happens when starting up and when
+/// (manually) changing the shell size. Always use default_grid.Rows and
+/// default_grid.Columns to access items in default_grid.chars[]. Use Rows
+/// and Columns for positioning text etc. where the final size of the shell is
+/// needed.
void screenalloc(bool doclear)
{
- int new_row, old_row;
- int outofmem = FALSE;
- int len;
- schar_T *new_ScreenLines;
- u8char_T *new_ScreenLinesUC = NULL;
- u8char_T *new_ScreenLinesC[MAX_MCO];
- schar_T *new_ScreenLines2 = NULL;
- int i;
- sattr_T *new_ScreenAttrs;
- unsigned *new_LineOffset;
- char_u *new_LineWraps;
- StlClickDefinition *new_tab_page_click_defs;
static bool entered = false; // avoid recursiveness
- static bool done_outofmem_msg = false;
int retry_count = 0;
- const bool l_enc_utf8 = enc_utf8;
- const int l_enc_dbcs = enc_dbcs;
retry:
- /*
- * Allocation of the screen buffers is done only when the size changes and
- * when Rows and Columns have been set and we have started doing full
- * screen stuff.
- */
- if ((ScreenLines != NULL
- && Rows == screen_Rows
- && Columns == screen_Columns
- && l_enc_utf8 == (ScreenLinesUC != NULL)
- && (l_enc_dbcs == DBCS_JPNU) == (ScreenLines2 != NULL)
- && p_mco == Screen_mco
+ // Allocation of the screen buffers is done only when the size changes and
+ // when Rows and Columns have been set and we have started doing full
+ // screen stuff.
+ if ((default_grid.chars != NULL
+ && Rows == default_grid.Rows
+ && Columns == default_grid.Columns
)
|| Rows == 0
|| Columns == 0
- || (!full_screen && ScreenLines == NULL))
+ || (!full_screen && default_grid.chars == NULL)) {
return;
+ }
/*
* It's possible that we produce an out-of-memory message below, which
@@ -6036,39 +6009,24 @@ retry:
comp_col(); /* recompute columns for shown command and ruler */
- /*
- * We're changing the size of the screen.
- * - Allocate new arrays for ScreenLines and ScreenAttrs.
- * - Move lines from the old arrays into the new arrays, clear extra
- * lines (unless the screen is going to be cleared).
- * - Free the old arrays.
- *
- * If anything fails, make ScreenLines NULL, so we don't do anything!
- * Continuing with the old ScreenLines may result in a crash, because the
- * size is wrong.
- */
+ // We're changing the size of the screen.
+ // - Allocate new arrays for default_grid
+ // - Move lines from the old arrays into the new arrays, clear extra
+ // lines (unless the screen is going to be cleared).
+ // - Free the old arrays.
+ //
+ // If anything fails, make grid arrays NULL, so we don't do anything!
+ // Continuing with the old arrays may result in a crash, because the
+ // size is wrong.
FOR_ALL_TAB_WINDOWS(tp, wp) {
win_free_lsize(wp);
}
if (aucmd_win != NULL)
win_free_lsize(aucmd_win);
- new_ScreenLines = xmalloc((size_t)((Rows + 1) * Columns * sizeof(schar_T)));
- memset(new_ScreenLinesC, 0, sizeof(u8char_T *) * MAX_MCO);
- if (l_enc_utf8) {
- new_ScreenLinesUC = xmalloc(
- (size_t)((Rows + 1) * Columns * sizeof(u8char_T)));
- for (i = 0; i < p_mco; ++i)
- new_ScreenLinesC[i] = xcalloc((Rows + 1) * Columns, sizeof(u8char_T));
- }
- if (l_enc_dbcs == DBCS_JPNU)
- new_ScreenLines2 = xmalloc(
- (size_t)((Rows + 1) * Columns * sizeof(schar_T)));
- new_ScreenAttrs = xmalloc((size_t)((Rows + 1) * Columns * sizeof(sattr_T)));
- new_LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned)));
- new_LineWraps = xmalloc((size_t)(Rows * sizeof(char_u)));
- new_tab_page_click_defs = xcalloc(
- (size_t) Columns, sizeof(*new_tab_page_click_defs));
+ grid_alloc(&default_grid, Rows, Columns, !doclear);
+ StlClickDefinition *new_tab_page_click_defs = xcalloc(
+ (size_t)Columns, sizeof(*new_tab_page_click_defs));
FOR_ALL_TAB_WINDOWS(tp, wp) {
win_alloc_lines(wp);
@@ -6077,128 +6035,15 @@ retry:
win_alloc_lines(aucmd_win);
}
- for (i = 0; i < p_mco; ++i)
- if (new_ScreenLinesC[i] == NULL)
- break;
- if (new_ScreenLines == NULL
- || (l_enc_utf8 && (new_ScreenLinesUC == NULL || i != p_mco))
- || (l_enc_dbcs == DBCS_JPNU && new_ScreenLines2 == NULL)
- || new_ScreenAttrs == NULL
- || new_LineOffset == NULL
- || new_LineWraps == NULL
- || new_tab_page_click_defs == NULL
- || outofmem) {
- if (ScreenLines != NULL || !done_outofmem_msg) {
- /* guess the size */
- do_outofmem_msg((Rows + 1) * Columns);
-
- /* Remember we did this to avoid getting outofmem messages over
- * and over again. */
- done_outofmem_msg = TRUE;
- }
- xfree(new_ScreenLines);
- new_ScreenLines = NULL;
- xfree(new_ScreenLinesUC);
- new_ScreenLinesUC = NULL;
- for (i = 0; i < p_mco; ++i) {
- xfree(new_ScreenLinesC[i]);
- new_ScreenLinesC[i] = NULL;
- }
- xfree(new_ScreenLines2);
- new_ScreenLines2 = NULL;
- xfree(new_ScreenAttrs);
- new_ScreenAttrs = NULL;
- xfree(new_LineOffset);
- new_LineOffset = NULL;
- xfree(new_LineWraps);
- new_LineWraps = NULL;
- xfree(new_tab_page_click_defs);
- new_tab_page_click_defs = NULL;
- } else {
- done_outofmem_msg = FALSE;
-
- for (new_row = 0; new_row < Rows; ++new_row) {
- new_LineOffset[new_row] = new_row * Columns;
- new_LineWraps[new_row] = FALSE;
-
- /*
- * If the screen is not going to be cleared, copy as much as
- * possible from the old screen to the new one and clear the rest
- * (used when resizing the window at the "--more--" prompt or when
- * executing an external command, for the GUI).
- */
- if (!doclear) {
- (void)memset(new_ScreenLines + new_row * Columns,
- ' ', (size_t)Columns * sizeof(schar_T));
- if (l_enc_utf8) {
- (void)memset(new_ScreenLinesUC + new_row * Columns,
- 0, (size_t)Columns * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- (void)memset(new_ScreenLinesC[i]
- + new_row * Columns,
- 0, (size_t)Columns * sizeof(u8char_T));
- }
- if (l_enc_dbcs == DBCS_JPNU)
- (void)memset(new_ScreenLines2 + new_row * Columns,
- 0, (size_t)Columns * sizeof(schar_T));
- (void)memset(new_ScreenAttrs + new_row * Columns,
- 0, (size_t)Columns * sizeof(sattr_T));
- old_row = new_row + (screen_Rows - Rows);
- if (old_row >= 0 && ScreenLines != NULL) {
- if (screen_Columns < Columns)
- len = screen_Columns;
- else
- len = Columns;
- /* When switching to utf-8 don't copy characters, they
- * may be invalid now. Also when p_mco changes. */
- if (!(l_enc_utf8 && ScreenLinesUC == NULL)
- && p_mco == Screen_mco)
- memmove(new_ScreenLines + new_LineOffset[new_row],
- ScreenLines + LineOffset[old_row],
- (size_t)len * sizeof(schar_T));
- if (l_enc_utf8 && ScreenLinesUC != NULL
- && p_mco == Screen_mco) {
- memmove(new_ScreenLinesUC + new_LineOffset[new_row],
- ScreenLinesUC + LineOffset[old_row],
- (size_t)len * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- memmove(new_ScreenLinesC[i]
- + new_LineOffset[new_row],
- ScreenLinesC[i] + LineOffset[old_row],
- (size_t)len * sizeof(u8char_T));
- }
- if (l_enc_dbcs == DBCS_JPNU && ScreenLines2 != NULL)
- memmove(new_ScreenLines2 + new_LineOffset[new_row],
- ScreenLines2 + LineOffset[old_row],
- (size_t)len * sizeof(schar_T));
- memmove(new_ScreenAttrs + new_LineOffset[new_row],
- ScreenAttrs + LineOffset[old_row],
- (size_t)len * sizeof(sattr_T));
- }
- }
- }
- /* Use the last line of the screen for the current line. */
- current_ScreenLine = new_ScreenLines + Rows * Columns;
- }
-
- free_screenlines();
+ clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
+ xfree(tab_page_click_defs);
- ScreenLines = new_ScreenLines;
- ScreenLinesUC = new_ScreenLinesUC;
- for (i = 0; i < p_mco; ++i)
- ScreenLinesC[i] = new_ScreenLinesC[i];
- Screen_mco = p_mco;
- ScreenLines2 = new_ScreenLines2;
- ScreenAttrs = new_ScreenAttrs;
- LineOffset = new_LineOffset;
- LineWraps = new_LineWraps;
tab_page_click_defs = new_tab_page_click_defs;
- tab_page_click_defs_size = Columns;
+ tab_page_click_defs_size = default_grid.Columns;
- /* It's important that screen_Rows and screen_Columns reflect the actual
- * size of ScreenLines[]. Set them before calling anything. */
- screen_Rows = Rows;
- screen_Columns = Columns;
+ default_grid.row_offset = 0;
+ default_grid.col_offset = 0;
+ default_grid.handle = DEFAULT_GRID_HANDLE;
must_redraw = CLEAR; /* need to clear the screen later */
if (doclear)
@@ -6220,20 +6065,75 @@ retry:
}
}
-void free_screenlines(void)
+void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy)
{
- int i;
+ int new_row;
+ ScreenGrid new = *grid;
+
+ size_t ncells = (size_t)((rows+1) * columns);
+ new.chars = xmalloc(ncells * sizeof(schar_T));
+ new.attrs = xmalloc(ncells * sizeof(sattr_T));
+ new.line_offset = xmalloc((size_t)(rows * sizeof(unsigned)));
+ new.line_wraps = xmalloc((size_t)(rows * sizeof(char_u)));
+
+ new.Rows = rows;
+ new.Columns = columns;
+
+ for (new_row = 0; new_row < new.Rows; new_row++) {
+ new.line_offset[new_row] = new_row * new.Columns;
+ new.line_wraps[new_row] = false;
+
+ grid_clear_line(&new, new.line_offset[new_row], columns, true);
+
+ if (copy) {
+ // If the screen is not going to be cleared, copy as much as
+ // possible from the old screen to the new one and clear the rest
+ // (used when resizing the window at the "--more--" prompt or when
+ // executing an external command, for the GUI).
+ if (new_row < grid->Rows && grid->chars != NULL) {
+ int len = MIN(grid->Columns, new.Columns);
+ memmove(new.chars + new.line_offset[new_row],
+ grid->chars + grid->line_offset[new_row],
+ (size_t)len * sizeof(schar_T));
+ memmove(new.attrs + new.line_offset[new_row],
+ grid->attrs + grid->line_offset[new_row],
+ (size_t)len * sizeof(sattr_T));
+ }
+ }
+ }
+ grid_free(grid);
+ *grid = new;
- xfree(ScreenLinesUC);
- for (i = 0; i < Screen_mco; ++i)
- xfree(ScreenLinesC[i]);
- xfree(ScreenLines2);
- xfree(ScreenLines);
- xfree(ScreenAttrs);
- xfree(LineOffset);
- xfree(LineWraps);
- clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
- xfree(tab_page_click_defs);
+ // Share a single scratch buffer for all grids, by
+ // ensuring it is as wide as the widest grid.
+ if (linebuf_size < (size_t)columns) {
+ xfree(linebuf_char);
+ xfree(linebuf_attr);
+ linebuf_char = xmalloc(columns * sizeof(schar_T));
+ linebuf_attr = xmalloc(columns * sizeof(sattr_T));
+ linebuf_size = columns;
+ }
+}
+
+void grid_free(ScreenGrid *grid)
+{
+ xfree(grid->chars);
+ xfree(grid->attrs);
+ xfree(grid->line_offset);
+ xfree(grid->line_wraps);
+
+ grid->chars = NULL;
+ grid->attrs = NULL;
+ grid->line_offset = NULL;
+ grid->line_wraps = NULL;
+}
+
+/// Doesn't allow reinit, so must only be called by free_all_mem!
+void screen_free_all_mem(void)
+{
+ grid_free(&default_grid);
+ xfree(linebuf_char);
+ xfree(linebuf_attr);
}
/// Clear tab_page_click_defs table
@@ -6264,73 +6164,63 @@ static void screenclear2(void)
{
int i;
- if (starting == NO_SCREEN || ScreenLines == NULL) {
+ if (starting == NO_SCREEN || default_grid.chars == NULL) {
return;
}
- screen_stop_highlight(); /* don't want highlighting here */
+ // blank out the default grid
+ for (i = 0; i < default_grid.Rows; i++) {
+ grid_clear_line(&default_grid, default_grid.line_offset[i],
+ (int)default_grid.Columns, true);
+ default_grid.line_wraps[i] = false;
+ }
+ ui_call_grid_clear(1); // clear the display
+ clear_cmdline = false;
+ mode_displayed = false;
- /* blank out ScreenLines */
- for (i = 0; i < Rows; ++i) {
- lineclear(LineOffset[i], (int)Columns);
- LineWraps[i] = FALSE;
+ redraw_all_later(NOT_VALID);
+ redraw_cmdline = true;
+ redraw_tabline = true;
+ if (must_redraw == CLEAR) {
+ must_redraw = NOT_VALID; // no need to clear again
}
-
- ui_clear(); // clear the display
- clear_cmdline = FALSE;
- mode_displayed = FALSE;
- screen_cleared = TRUE; /* can use contents of ScreenLines now */
-
- win_rest_invalid(firstwin);
- redraw_cmdline = TRUE;
- redraw_tabline = TRUE;
- if (must_redraw == CLEAR) /* no need to clear again */
- must_redraw = NOT_VALID;
compute_cmdrow();
- msg_row = cmdline_row; /* put cursor on last line for messages */
+ msg_row = cmdline_row; // put cursor on last line for messages
msg_col = 0;
- msg_scrolled = 0; /* can't scroll back */
- msg_didany = FALSE;
- msg_didout = FALSE;
+ msg_scrolled = 0; // can't scroll back
+ msg_didany = false;
+ msg_didout = false;
}
-/*
- * Clear one line in ScreenLines.
- */
-static void lineclear(unsigned off, int width)
+/// clear a line in the grid starting at "off" until "width" characters
+/// are cleared.
+static void grid_clear_line(ScreenGrid *grid, unsigned off, int width,
+ bool valid)
{
- (void)memset(ScreenLines + off, ' ', (size_t)width * sizeof(schar_T));
- if (enc_utf8)
- (void)memset(ScreenLinesUC + off, 0,
- (size_t)width * sizeof(u8char_T));
- (void)memset(ScreenAttrs + off, 0, (size_t)width * sizeof(sattr_T));
+ for (int col = 0; col < width; col++) {
+ schar_from_ascii(grid->chars[off + col], ' ');
+ }
+ int fill = valid ? 0 : -1;
+ (void)memset(grid->attrs + off, fill, (size_t)width * sizeof(sattr_T));
}
-/*
- * Copy part of a Screenline for vertically split window "wp".
- */
-static void linecopy(int to, int from, win_T *wp)
+static void grid_invalidate(ScreenGrid *grid)
{
- unsigned off_to = LineOffset[to] + wp->w_wincol;
- unsigned off_from = LineOffset[from] + wp->w_wincol;
-
- memmove(ScreenLines + off_to, ScreenLines + off_from,
- wp->w_width * sizeof(schar_T));
- if (enc_utf8) {
- int i;
-
- memmove(ScreenLinesUC + off_to, ScreenLinesUC + off_from,
- wp->w_width * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- memmove(ScreenLinesC[i] + off_to, ScreenLinesC[i] + off_from,
- wp->w_width * sizeof(u8char_T));
- }
- if (enc_dbcs == DBCS_JPNU)
- memmove(ScreenLines2 + off_to, ScreenLines2 + off_from,
- wp->w_width * sizeof(schar_T));
- memmove(ScreenAttrs + off_to, ScreenAttrs + off_from,
- wp->w_width * sizeof(sattr_T));
+ (void)memset(grid->attrs, -1, grid->Rows * grid->Columns * sizeof(sattr_T));
+}
+
+
+/// Copy part of a grid line for vertically split window.
+static void linecopy(ScreenGrid *grid, int to, int from, int col, int width)
+{
+ unsigned off_to = grid->line_offset[to] + col;
+ unsigned off_from = grid->line_offset[from] + col;
+
+ memmove(grid->chars + off_to, grid->chars + off_from,
+ width * sizeof(schar_T));
+ memmove(grid->attrs + off_to, grid->attrs + off_from,
+ width * sizeof(sattr_T));
}
/*
@@ -6340,186 +6230,62 @@ void setcursor(void)
{
if (redrawing()) {
validate_cursor();
- ui_cursor_goto(curwin->w_winrow + curwin->w_wrow,
- curwin->w_wincol + (
- /* With 'rightleft' set and the cursor on a double-wide
- * character, position it on the leftmost column. */
- curwin->w_p_rl ? (curwin->w_width - curwin->w_wcol - (
- (has_mbyte
- && (*mb_ptr2cells)(get_cursor_pos_ptr()) == 2
- && vim_isprintc(gchar_cursor())) ? 2 :
- 1)) :
- curwin->w_wcol));
- }
-}
-
-/*
- * insert 'line_count' lines at 'row' in window 'wp'
- * if 'invalid' is TRUE the wp->w_lines[].wl_lnum is invalidated.
- * if 'mayclear' is TRUE the screen will be cleared if it is faster than
- * scrolling.
- * Returns FAIL if the lines are not inserted, OK for success.
- */
-int win_ins_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
-{
- int did_delete;
- int nextrow;
- int lastrow;
- int retval;
-
- if (invalid)
- wp->w_lines_valid = 0;
-
- if (wp->w_height < 5)
- return FAIL;
-
- if (line_count > wp->w_height - row)
- line_count = wp->w_height - row;
-
- retval = win_do_lines(wp, row, line_count, mayclear, FALSE);
- if (retval != MAYBE)
- return retval;
- /*
- * If there is a next window or a status line, we first try to delete the
- * lines at the bottom to avoid messing what is after the window.
- * If this fails and there are following windows, don't do anything to avoid
- * messing up those windows, better just redraw.
- */
- did_delete = FALSE;
- if (wp->w_next != NULL || wp->w_status_height) {
- if (screen_del_lines(0, wp->w_winrow + wp->w_height - line_count,
- line_count, (int)Rows, NULL) == OK)
- did_delete = TRUE;
- else if (wp->w_next)
- return FAIL;
- }
- /*
- * if no lines deleted, blank the lines that will end up below the window
- */
- if (!did_delete) {
- wp->w_redr_status = TRUE;
- redraw_cmdline = TRUE;
- nextrow = wp->w_winrow + wp->w_height + wp->w_status_height;
- lastrow = nextrow + line_count;
- if (lastrow > Rows)
- lastrow = Rows;
- screen_fill(nextrow - line_count, lastrow - line_count,
- wp->w_wincol, W_ENDCOL(wp),
- ' ', ' ', 0);
- }
-
- if (screen_ins_lines(0, wp->w_winrow + row, line_count, (int)Rows, NULL)
- == FAIL) {
- /* deletion will have messed up other windows */
- if (did_delete) {
- wp->w_redr_status = TRUE;
- win_rest_invalid(wp->w_next);
+ ScreenGrid *grid = &curwin->w_grid;
+ int row = curwin->w_wrow;
+ int col = curwin->w_wcol;
+ if (curwin->w_p_rl) {
+ // With 'rightleft' set and the cursor on a double-wide character,
+ // position it on the leftmost column.
+ col = curwin->w_grid.Columns - curwin->w_wcol
+ - ((utf_ptr2cells(get_cursor_pos_ptr()) == 2
+ && vim_isprintc(gchar_cursor())) ? 2 : 1);
}
- return FAIL;
- }
- return OK;
+ screen_adjust_grid(&grid, &row, &col);
+ ui_grid_cursor_goto(grid->handle, row, col);
+ }
}
-/*
- * delete "line_count" window lines at "row" in window "wp"
- * If "invalid" is TRUE curwin->w_lines[] is invalidated.
- * If "mayclear" is TRUE the screen will be cleared if it is faster than
- * scrolling
- * Return OK for success, FAIL if the lines are not deleted.
- */
-int win_del_lines(win_T *wp, int row, int line_count, int invalid, int mayclear)
+/// Insert 'line_count' lines at 'row' in window 'wp'.
+/// Returns FAIL if the lines are not inserted, OK for success.
+int win_ins_lines(win_T *wp, int row, int line_count)
{
- int retval;
-
- if (invalid)
- wp->w_lines_valid = 0;
-
- if (line_count > wp->w_height - row)
- line_count = wp->w_height - row;
-
- retval = win_do_lines(wp, row, line_count, mayclear, TRUE);
- if (retval != MAYBE)
- return retval;
-
- if (screen_del_lines(0, wp->w_winrow + row, line_count,
- (int)Rows, NULL) == FAIL) {
- return FAIL;
- }
+ return win_do_lines(wp, row, line_count, false);
+}
- /*
- * If there are windows or status lines below, try to put them at the
- * correct place. If we can't do that, they have to be redrawn.
- */
- if (wp->w_next || wp->w_status_height || cmdline_row < Rows - 1) {
- if (screen_ins_lines(0, wp->w_winrow + wp->w_height - line_count,
- line_count, (int)Rows, NULL) == FAIL) {
- wp->w_redr_status = TRUE;
- win_rest_invalid(wp->w_next);
- }
- }
- /*
- * If this is the last window and there is no status line, redraw the
- * command line later.
- */
- else
- redraw_cmdline = TRUE;
- return OK;
+/// Delete "line_count" window lines at "row" in window "wp".
+/// Return OK for success, FAIL if the lines are not deleted.
+int win_del_lines(win_T *wp, int row, int line_count)
+{
+ return win_do_lines(wp, row, line_count, true);
}
// Common code for win_ins_lines() and win_del_lines().
// Returns OK or FAIL when the work has been done.
-static int win_do_lines(win_T *wp, int row, int line_count, int mayclear, int del)
+static int win_do_lines(win_T *wp, int row, int line_count, int del)
{
if (!redrawing() || line_count <= 0) {
return FAIL;
}
- // only a few lines left: redraw is faster
- if (mayclear && Rows - line_count < 5 && wp->w_width == Columns) {
- screenclear(); /* will set wp->w_lines_valid to 0 */
- return FAIL;
- }
-
- // Delete all remaining lines
- if (row + line_count >= wp->w_height) {
- screen_fill(wp->w_winrow + row, wp->w_winrow + wp->w_height,
- wp->w_wincol, W_ENDCOL(wp),
- ' ', ' ', 0);
+ // No lines are being moved, just draw over the entire area
+ if (row + line_count >= wp->w_grid.Rows) {
return OK;
}
- // when scrolling, the message on the command line should be cleared,
- // otherwise it will stay there forever.
- clear_cmdline = TRUE;
int retval;
- ui_set_scroll_region(wp, row);
if (del) {
- retval = screen_del_lines(wp->w_winrow + row, 0, line_count,
- wp->w_height - row, wp);
+ retval = grid_del_lines(&wp->w_grid, row, line_count,
+ wp->w_grid.Rows, 0, wp->w_grid.Columns);
} else {
- retval = screen_ins_lines(wp->w_winrow + row, 0, line_count,
- wp->w_height - row, wp);
+ retval = grid_ins_lines(&wp->w_grid, row, line_count,
+ wp->w_grid.Rows, 0, wp->w_grid.Columns);
}
- ui_reset_scroll_region();
return retval;
}
/*
- * window 'wp' and everything after it is messed up, mark it for redraw
- */
-static void win_rest_invalid(win_T *wp)
-{
- while (wp != NULL) {
- redraw_win_later(wp, NOT_VALID);
- wp->w_redr_status = TRUE;
- wp = wp->w_next;
- }
- redraw_cmdline = TRUE;
-}
-
-/*
* The rest of the routines in this file perform screen manipulations. The
* given operation is performed physically on the screen. The corresponding
* change is also made to the internal screen image. In this way, the editor
@@ -6530,115 +6296,114 @@ static void win_rest_invalid(win_T *wp)
*/
-// insert lines on the screen and update ScreenLines[]
-// 'end' is the line after the scrolled part. Normally it is Rows.
-// When scrolling region used 'off' is the offset from the top for the region.
-// 'row' and 'end' are relative to the start of the region.
+/// insert lines on the screen and move the existing lines down
+/// 'line_count' is the number of lines to be inserted.
+/// 'end' is the line after the scrolled part. Normally it is Rows.
+/// 'col' is the column from with we start inserting.
//
-// return FAIL for failure, OK for success.
-int screen_ins_lines (
- int off,
- int row,
- int line_count,
- int end,
- win_T *wp /* NULL or window to use width from */
-)
+/// 'row', 'col' and 'end' are relative to the start of the region.
+///
+/// @return FAIL for failure, OK for success.
+int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
+ int width)
{
int i;
int j;
unsigned temp;
+ int row_off = 0;
+ screen_adjust_grid(&grid, &row_off, &col);
+ row += row_off;
+ end += row_off;
+
if (!screen_valid(TRUE) || line_count <= 0) {
return FAIL;
}
- // Shift LineOffset[] line_count down to reflect the inserted lines.
- // Clear the inserted lines in ScreenLines[].
- row += off;
- end += off;
- for (i = 0; i < line_count; ++i) {
- if (wp != NULL && wp->w_width != Columns) {
+ // Shift line_offset[] line_count down to reflect the inserted lines.
+ // Clear the inserted lines.
+ for (i = 0; i < line_count; i++) {
+ if (width != grid->Columns) {
// need to copy part of a line
j = end - 1 - i;
while ((j -= line_count) >= row) {
- linecopy(j + line_count, j, wp);
+ linecopy(grid, j + line_count, j, col, width);
}
j += line_count;
- lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
- LineWraps[j] = FALSE;
+ grid_clear_line(grid, grid->line_offset[j] + col, width, false);
+ grid->line_wraps[j] = false;
} else {
j = end - 1 - i;
- temp = LineOffset[j];
+ temp = grid->line_offset[j];
while ((j -= line_count) >= row) {
- LineOffset[j + line_count] = LineOffset[j];
- LineWraps[j + line_count] = LineWraps[j];
+ grid->line_offset[j + line_count] = grid->line_offset[j];
+ grid->line_wraps[j + line_count] = grid->line_wraps[j];
}
- LineOffset[j + line_count] = temp;
- LineWraps[j + line_count] = FALSE;
- lineclear(temp, (int)Columns);
+ grid->line_offset[j + line_count] = temp;
+ grid->line_wraps[j + line_count] = false;
+ grid_clear_line(grid, temp, (int)grid->Columns, false);
}
}
- ui_append_lines(line_count);
+ ui_call_grid_scroll(grid->handle, row, end, col, col+width, -line_count, 0);
return OK;
}
-// delete lines on the screen and update ScreenLines[]
-// 'end' is the line after the scrolled part. Normally it is Rows.
-// When scrolling region used 'off' is the offset from the top for the region.
-// 'row' and 'end' are relative to the start of the region.
-//
-// Return OK for success, FAIL if the lines are not deleted.
-int screen_del_lines (
- int off,
- int row,
- int line_count,
- int end,
- win_T *wp /* NULL or window to use width from */
-)
+/// delete lines on the screen and move lines up.
+/// 'end' is the line after the scrolled part. Normally it is Rows.
+/// When scrolling region used 'off' is the offset from the top for the region.
+/// 'row' and 'end' are relative to the start of the region.
+///
+/// Return OK for success, FAIL if the lines are not deleted.
+int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, int col,
+ int width)
{
int j;
int i;
unsigned temp;
+ int row_off = 0;
+ screen_adjust_grid(&grid, &row_off, &col);
+ row += row_off;
+ end += row_off;
+
if (!screen_valid(TRUE) || line_count <= 0) {
return FAIL;
}
- // Now shift LineOffset[] line_count up to reflect the deleted lines.
- // Clear the inserted lines in ScreenLines[].
- row += off;
- end += off;
- for (i = 0; i < line_count; ++i) {
- if (wp != NULL && wp->w_width != Columns) {
+ // Now shift line_offset[] line_count up to reflect the deleted lines.
+ // Clear the inserted lines.
+ for (i = 0; i < line_count; i++) {
+ if (width != grid->Columns) {
// need to copy part of a line
j = row + i;
while ((j += line_count) <= end - 1) {
- linecopy(j - line_count, j, wp);
+ linecopy(grid, j - line_count, j, col, width);
}
j -= line_count;
- lineclear(LineOffset[j] + wp->w_wincol, wp->w_width);
- LineWraps[j] = FALSE;
+ grid_clear_line(grid, grid->line_offset[j] + col, width, false);
+ grid->line_wraps[j] = false;
} else {
// whole width, moving the line pointers is faster
j = row + i;
- temp = LineOffset[j];
+ temp = grid->line_offset[j];
while ((j += line_count) <= end - 1) {
- LineOffset[j - line_count] = LineOffset[j];
- LineWraps[j - line_count] = LineWraps[j];
+ grid->line_offset[j - line_count] = grid->line_offset[j];
+ grid->line_wraps[j - line_count] = grid->line_wraps[j];
}
- LineOffset[j - line_count] = temp;
- LineWraps[j - line_count] = FALSE;
- lineclear(temp, (int)Columns);
+ grid->line_offset[j - line_count] = temp;
+ grid->line_wraps[j - line_count] = false;
+ grid_clear_line(grid, temp, (int)grid->Columns, false);
}
}
- ui_delete_lines(line_count);
+ ui_call_grid_scroll(grid->handle, row, end, col, col+width, line_count, 0);
return OK;
}
+
/*
* show the current mode and ruler
*
@@ -6680,36 +6445,47 @@ int showmode(void)
/* if the cmdline is more than one line high, erase top lines */
need_clear = clear_cmdline;
- if (clear_cmdline && cmdline_row < Rows - 1)
- msg_clr_cmdline(); /* will reset clear_cmdline */
+ if (clear_cmdline && cmdline_row < default_grid.Rows - 1) {
+ msg_clr_cmdline(); // will reset clear_cmdline
+ }
/* Position on the last line in the window, column 0 */
msg_pos_mode();
- attr = hl_attr(HLF_CM); /* Highlight mode */
+ attr = HL_ATTR(HLF_CM); // Highlight mode
+
+ // When the screen is too narrow to show the entire mode messsage,
+ // avoid scrolling and truncate instead.
+ msg_no_more = true;
+ int save_lines_left = lines_left;
+ lines_left = 0;
+
if (do_mode) {
MSG_PUTS_ATTR("--", attr);
// CTRL-X in Insert mode
if (edit_submode != NULL && !shortmess(SHM_COMPLETIONMENU)) {
/* These messages can get long, avoid a wrap in a narrow
* window. Prefer showing edit_submode_extra. */
- length = (Rows - msg_row) * Columns - 3;
- if (edit_submode_extra != NULL)
+ length = (default_grid.Rows - msg_row) * default_grid.Columns - 3;
+ if (edit_submode_extra != NULL) {
length -= vim_strsize(edit_submode_extra);
+ }
if (length > 0) {
if (edit_submode_pre != NULL)
length -= vim_strsize(edit_submode_pre);
if (length - vim_strsize(edit_submode) > 0) {
- if (edit_submode_pre != NULL)
- msg_puts_attr(edit_submode_pre, attr);
- msg_puts_attr(edit_submode, attr);
+ if (edit_submode_pre != NULL) {
+ msg_puts_attr((const char *)edit_submode_pre, attr);
+ }
+ msg_puts_attr((const char *)edit_submode, attr);
}
if (edit_submode_extra != NULL) {
- MSG_PUTS_ATTR(" ", attr); /* add a space in between */
- if ((int)edit_submode_highl < (int)HLF_COUNT)
- sub_attr = hl_attr(edit_submode_highl);
- else
+ MSG_PUTS_ATTR(" ", attr); // Add a space in between.
+ if ((int)edit_submode_highl < (int)HLF_COUNT) {
+ sub_attr = win_hl_attr(curwin, edit_submode_highl);
+ } else {
sub_attr = attr;
- msg_puts_attr(edit_submode_extra, sub_attr);
+ }
+ msg_puts_attr((const char *)edit_submode_extra, sub_attr);
}
}
} else {
@@ -6723,21 +6499,27 @@ int showmode(void)
if (p_ri)
MSG_PUTS_ATTR(_(" REVERSE"), attr);
MSG_PUTS_ATTR(_(" INSERT"), attr);
- } else if (restart_edit == 'I')
+ } else if (restart_edit == 'I' || restart_edit == 'i'
+ || restart_edit == 'a') {
MSG_PUTS_ATTR(_(" (insert)"), attr);
- else if (restart_edit == 'R')
+ } else if (restart_edit == 'R') {
MSG_PUTS_ATTR(_(" (replace)"), attr);
- else if (restart_edit == 'V')
+ } else if (restart_edit == 'V') {
MSG_PUTS_ATTR(_(" (vreplace)"), attr);
- if (p_hkmap)
+ }
+ if (p_hkmap) {
MSG_PUTS_ATTR(_(" Hebrew"), attr);
- if (p_fkmap)
+ }
+ if (p_fkmap) {
MSG_PUTS_ATTR(farsi_text_5, attr);
+ }
if (State & LANGMAP) {
- if (curwin->w_p_arab)
+ if (curwin->w_p_arab) {
MSG_PUTS_ATTR(_(" Arabic"), attr);
- else
- MSG_PUTS_ATTR(_(" (lang)"), attr);
+ } else if (get_keymap_str(curwin, (char_u *)" (%s)",
+ NameBuff, MAXPATHL)) {
+ MSG_PUTS_ATTR(NameBuff, attr);
+ }
}
if ((State & INSERT) && p_paste)
MSG_PUTS_ATTR(_(" (paste)"), attr);
@@ -6777,10 +6559,13 @@ int showmode(void)
msg_didout = FALSE; /* overwrite this message */
length = msg_col;
msg_col = 0;
- need_wait_return = nwr_save; /* never ask for hit-return for this */
- } else if (clear_cmdline && msg_silent == 0)
- /* Clear the whole command line. Will reset "clear_cmdline". */
+ msg_no_more = false;
+ lines_left = save_lines_left;
+ need_wait_return = nwr_save; // never ask for hit-return for this
+ } else if (clear_cmdline && msg_silent == 0) {
+ // Clear the whole command line. Will reset "clear_cmdline".
msg_clr_cmdline();
+ }
/* In Visual mode the size of the selected area must be redrawn. */
if (VIsual_active)
@@ -6804,7 +6589,7 @@ int showmode(void)
static void msg_pos_mode(void)
{
msg_col = 0;
- msg_row = Rows - 1;
+ msg_row = default_grid.Rows - 1;
}
/// Delete mode message. Used when ESC is typed which is expected to end
@@ -6816,12 +6601,18 @@ void unshowmode(bool force)
if (!redrawing() || (!force && char_avail() && !KeyTyped)) {
redraw_cmdline = true; // delete mode later
} else {
+ clearmode();
+ }
+}
+
+// Clear the mode message.
+void clearmode(void)
+{
msg_pos_mode();
if (Recording) {
- recording_mode(hl_attr(HLF_CM));
+ recording_mode(HL_ATTR(HLF_CM));
}
msg_clr_eos();
- }
}
static void recording_mode(int attr)
@@ -6850,44 +6641,51 @@ static void draw_tabline(void)
int modified;
int c;
int len;
- int attr_sel = hl_attr(HLF_TPS);
- int attr_nosel = hl_attr(HLF_TP);
- int attr_fill = hl_attr(HLF_TPF);
+ int attr_nosel = HL_ATTR(HLF_TP);
+ int attr_fill = HL_ATTR(HLF_TPF);
char_u *p;
int room;
int use_sep_chars = (t_colors < 8
);
- redraw_tabline = FALSE;
+ if (default_grid.chars == NULL) {
+ return;
+ }
+ redraw_tabline = false;
+ if (ui_is_external(kUITabline)) {
+ ui_ext_tabline_update();
+ return;
+ }
if (tabline_height() < 1)
return;
// Init TabPageIdxs[] to zero: Clicking outside of tabs has no effect.
- assert(Columns == tab_page_click_defs_size);
+ assert(default_grid.Columns == tab_page_click_defs_size);
clear_tab_page_click_defs(tab_page_click_defs, tab_page_click_defs_size);
/* Use the 'tabline' option if it's set. */
if (*p_tal != NUL) {
- int save_called_emsg = called_emsg;
+ int saved_did_emsg = did_emsg;
- /* Check for an error. If there is one we would loop in redrawing the
- * screen. Avoid that by making 'tabline' empty. */
- called_emsg = FALSE;
- win_redr_custom(NULL, FALSE);
- if (called_emsg)
+ // Check for an error. If there is one we would loop in redrawing the
+ // screen. Avoid that by making 'tabline' empty.
+ did_emsg = false;
+ win_redr_custom(NULL, false);
+ if (did_emsg) {
set_string_option_direct((char_u *)"tabline", -1,
- (char_u *)"", OPT_FREE, SID_ERROR);
- called_emsg |= save_called_emsg;
+ (char_u *)"", OPT_FREE, SID_ERROR);
+ }
+ did_emsg |= saved_did_emsg;
} else {
FOR_ALL_TABS(tp) {
++tabcount;
}
if (tabcount > 0) {
- tabwidth = (Columns - 1 + tabcount / 2) / tabcount;
+ tabwidth = (default_grid.Columns - 1 + tabcount / 2) / tabcount;
}
if (tabwidth < 6) {
@@ -6898,22 +6696,12 @@ static void draw_tabline(void)
tabcount = 0;
FOR_ALL_TABS(tp) {
- if (col >= Columns - 4) {
+ if (col >= default_grid.Columns - 4) {
break;
}
scol = col;
- if (tp->tp_topframe == topframe)
- attr = attr_sel;
- if (use_sep_chars && col > 0)
- screen_putchar('|', 0, col++, attr);
-
- if (tp->tp_topframe != topframe)
- attr = attr_nosel;
-
- screen_putchar(' ', 0, col++, attr);
-
if (tp == curtab) {
cwp = curwin;
wp = firstwin;
@@ -6922,23 +6710,44 @@ static void draw_tabline(void)
wp = tp->tp_firstwin;
}
- modified = FALSE;
- for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount)
- if (bufIsChanged(wp->w_buffer))
- modified = TRUE;
+
+ if (tp->tp_topframe == topframe) {
+ attr = win_hl_attr(cwp, HLF_TPS);
+ }
+ if (use_sep_chars && col > 0) {
+ grid_putchar(&default_grid, '|', 0, col++, attr);
+ }
+
+ if (tp->tp_topframe != topframe) {
+ attr = win_hl_attr(cwp, HLF_TP);
+ }
+
+ grid_putchar(&default_grid, ' ', 0, col++, attr);
+
+ modified = false;
+
+ for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount) {
+ if (bufIsChanged(wp->w_buffer)) {
+ modified = true;
+ }
+ }
+
+
if (modified || wincount > 1) {
if (wincount > 1) {
vim_snprintf((char *)NameBuff, MAXPATHL, "%d", wincount);
len = (int)STRLEN(NameBuff);
- if (col + len >= Columns - 3)
+ if (col + len >= default_grid.Columns - 3) {
break;
- screen_puts_len(NameBuff, len, 0, col,
- hl_combine_attr(attr, hl_attr(HLF_T)));
+ }
+ grid_puts_len(&default_grid, NameBuff, len, 0, col,
+ hl_combine_attr(attr, win_hl_attr(cwp, HLF_T)));
col += len;
}
- if (modified)
- screen_puts_len((char_u *)"+", 1, 0, col++, attr);
- screen_putchar(' ', 0, col++, attr);
+ if (modified) {
+ grid_puts_len(&default_grid, (char_u *)"+", 1, 0, col++, attr);
+ }
+ grid_putchar(&default_grid, ' ', 0, col++, attr);
}
room = scol - col + tabwidth - 1;
@@ -6951,19 +6760,20 @@ static void draw_tabline(void)
if (has_mbyte)
while (len > room) {
len -= ptr2cells(p);
- mb_ptr_adv(p);
+ MB_PTR_ADV(p);
}
else if (len > room) {
p += len - room;
len = room;
}
- if (len > Columns - col - 1)
- len = Columns - col - 1;
+ if (len > default_grid.Columns - col - 1) {
+ len = default_grid.Columns - col - 1;
+ }
- screen_puts_len(p, (int)STRLEN(p), 0, col, attr);
+ grid_puts_len(&default_grid, p, (int)STRLEN(p), 0, col, attr);
col += len;
}
- screen_putchar(' ', 0, col++, attr);
+ grid_putchar(&default_grid, ' ', 0, col++, attr);
// Store the tab page number in tab_page_click_defs[], so that
// jump_to_mouse() knows where each one is.
@@ -6981,12 +6791,14 @@ static void draw_tabline(void)
c = '_';
else
c = ' ';
- screen_fill(0, 1, col, (int)Columns, c, c, attr_fill);
+ grid_fill(&default_grid, 0, 1, col, (int)default_grid.Columns, c, c,
+ attr_fill);
/* Put an "X" for closing the current tab if there are several. */
if (first_tabpage->tp_next != NULL) {
- screen_putchar('X', 0, (int)Columns - 1, attr_nosel);
- tab_page_click_defs[Columns - 1] = (StlClickDefinition) {
+ grid_putchar(&default_grid, 'X', 0, (int)default_grid.Columns - 1,
+ attr_nosel);
+ tab_page_click_defs[default_grid.Columns - 1] = (StlClickDefinition) {
.type = kStlClickTabClose,
.tabnr = 999,
.func = NULL,
@@ -6999,6 +6811,22 @@ static void draw_tabline(void)
redraw_tabline = FALSE;
}
+void ui_ext_tabline_update(void)
+{
+ Array tabs = ARRAY_DICT_INIT;
+ FOR_ALL_TABS(tp) {
+ Dictionary tab_info = ARRAY_DICT_INIT;
+ PUT(tab_info, "tab", TABPAGE_OBJ(tp->handle));
+
+ win_T *cwp = (tp == curtab) ? curwin : tp->tp_curwin;
+ get_trans_bufname(cwp->w_buffer);
+ PUT(tab_info, "name", STRING_OBJ(cstr_to_string((char *)NameBuff)));
+
+ ADD(tabs, DICTIONARY_OBJ(tab_info));
+ }
+ ui_call_tabline_update(curtab->handle, tabs);
+}
+
/*
* Get buffer name for "buf" into NameBuff[].
* Takes care of special buffer names and translates special characters.
@@ -7015,25 +6843,28 @@ void get_trans_bufname(buf_T *buf)
/*
* Get the character to use in a status line. Get its attributes in "*attr".
*/
-static int fillchar_status(int *attr, int is_curwin)
+static int fillchar_status(int *attr, win_T *wp)
{
int fill;
+ bool is_curwin = (wp == curwin);
if (is_curwin) {
- *attr = hl_attr(HLF_S);
+ *attr = win_hl_attr(wp, HLF_S);
fill = fill_stl;
} else {
- *attr = hl_attr(HLF_SNC);
+ *attr = win_hl_attr(wp, HLF_SNC);
fill = fill_stlnc;
}
/* Use fill when there is highlighting, and highlighting of current
* window differs, or the fillchars differ, or this is not the
* current window */
- if (*attr != 0 && ((hl_attr(HLF_S) != hl_attr(HLF_SNC)
- || !is_curwin || firstwin == lastwin)
- || (fill_stl != fill_stlnc)))
+ if (*attr != 0 && ((win_hl_attr(wp, HLF_S) != win_hl_attr(wp, HLF_SNC)
+ || !is_curwin || ONE_WINDOW)
+ || (fill_stl != fill_stlnc))) {
return fill;
- if (is_curwin)
+ }
+ if (is_curwin) {
return '^';
+ }
return '=';
}
@@ -7041,13 +6872,10 @@ static int fillchar_status(int *attr, int is_curwin)
* Get the character to use in a separator between vertically split windows.
* Get its attributes in "*attr".
*/
-static int fillchar_vsep(int *attr)
+static int fillchar_vsep(win_T *wp, int *attr)
{
- *attr = hl_attr(HLF_C);
- if (*attr == 0 && fill_vert == ' ')
- return '|';
- else
- return fill_vert;
+ *attr = win_hl_attr(wp, HLF_C);
+ return fill_vert;
}
/*
@@ -7075,15 +6903,16 @@ void showruler(int always)
{
if (!always && !redrawing())
return;
- if (pum_visible()) {
- /* Don't redraw right now, do it later. */
- curwin->w_redr_status = TRUE;
+ if (pum_drawn()) {
+ // Don't redraw right now, do it later.
+ curwin->w_redr_status = true;
return;
}
if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height) {
redraw_custom_statusline(curwin);
- } else
+ } else {
win_redr_ruler(curwin, always);
+ }
if (need_maketitle
|| (p_icon && (stl_syntax & STL_IN_ICON))
@@ -7113,9 +6942,10 @@ static void win_redr_ruler(win_T *wp, int always)
if (wp == lastwin && lastwin->w_status_height == 0)
if (edit_submode != NULL)
return;
- /* Don't draw the ruler when the popup menu is visible, it may overlap. */
- if (pum_visible())
+ // Don't draw the ruler when the popup menu is visible, it may overlap.
+ if (pum_drawn()) {
return;
+ }
if (*p_ruf) {
int save_called_emsg = called_emsg;
@@ -7159,15 +6989,15 @@ static void win_redr_ruler(win_T *wp, int always)
int off;
if (wp->w_status_height) {
- row = wp->w_winrow + wp->w_height;
- fillchar = fillchar_status(&attr, wp == curwin);
+ row = W_ENDROW(wp);
+ fillchar = fillchar_status(&attr, wp);
off = wp->w_wincol;
width = wp->w_width;
} else {
- row = Rows - 1;
+ row = default_grid.Rows - 1;
fillchar = ' ';
attr = 0;
- width = Columns;
+ width = default_grid.Columns;
off = 0;
}
@@ -7202,46 +7032,42 @@ static void win_redr_ruler(win_T *wp, int always)
int i = (int)STRLEN(buffer);
get_rel_pos(wp, buffer + i + 1, RULER_BUF_LEN - i - 1);
int o = i + vim_strsize(buffer + i + 1);
- if (wp->w_status_height == 0) /* can't use last char of screen */
- ++o;
- int this_ru_col = ru_col - (Columns - width);
- if (this_ru_col < 0)
+ if (wp->w_status_height == 0) { // can't use last char of screen
+ o++;
+ }
+ int this_ru_col = ru_col - (default_grid.Columns - width);
+ if (this_ru_col < 0) {
this_ru_col = 0;
- /* Never use more than half the window/screen width, leave the other
- * half for the filename. */
- if (this_ru_col < (width + 1) / 2)
+ }
+ // Never use more than half the window/screen width, leave the other half
+ // for the filename.
+ if (this_ru_col < (width + 1) / 2) {
this_ru_col = (width + 1) / 2;
+ }
if (this_ru_col + o < width) {
// Need at least 3 chars left for get_rel_pos() + NUL.
while (this_ru_col + o < width && RULER_BUF_LEN > i + 4) {
- if (has_mbyte)
- i += (*mb_char2bytes)(fillchar, buffer + i);
- else
- buffer[i++] = fillchar;
- ++o;
+ i += utf_char2bytes(fillchar, buffer + i);
+ o++;
}
get_rel_pos(wp, buffer + i, RULER_BUF_LEN - i);
}
- /* Truncate at window boundary. */
- if (has_mbyte) {
- o = 0;
- for (i = 0; buffer[i] != NUL; i += (*mb_ptr2len)(buffer + i)) {
- o += (*mb_ptr2cells)(buffer + i);
- if (this_ru_col + o > width) {
- buffer[i] = NUL;
- break;
- }
+ // Truncate at window boundary.
+ o = 0;
+ for (i = 0; buffer[i] != NUL; i += utfc_ptr2len(buffer + i)) {
+ o += utf_ptr2cells(buffer + i);
+ if (this_ru_col + o > width) {
+ buffer[i] = NUL;
+ break;
}
- } else if (this_ru_col + (int)STRLEN(buffer) > width)
- buffer[width - this_ru_col] = NUL;
+ }
- screen_puts(buffer, row, this_ru_col + off, attr);
+ grid_puts(&default_grid, buffer, row, this_ru_col + off, attr);
i = redraw_cmdline;
- screen_fill(row, row + 1,
- this_ru_col + off + (int)STRLEN(buffer),
- off + width,
- fillchar, fillchar, attr);
- /* don't redraw the cmdline because of showing the ruler */
+ grid_fill(&default_grid, row, row + 1,
+ this_ru_col + off + (int)STRLEN(buffer), off + width, fillchar,
+ fillchar, attr);
+ // don't redraw the cmdline because of showing the ruler
redraw_cmdline = i;
wp->w_ru_cursor = wp->w_cursor;
wp->w_ru_virtcol = wp->w_virtcol;
@@ -7262,12 +7088,13 @@ int number_width(win_T *wp)
int n;
linenr_T lnum;
- if (wp->w_p_rnu && !wp->w_p_nu)
- /* cursor line shows "0" */
- lnum = wp->w_height;
- else
- /* cursor line shows absolute line number */
+ if (wp->w_p_rnu && !wp->w_p_nu) {
+ // cursor line shows "0"
+ lnum = wp->w_grid.Rows;
+ } else {
+ // cursor line shows absolute line number
lnum = wp->w_buffer->b_ml.ml_line_count;
+ }
if (lnum == wp->w_nrwidth_line_count)
return wp->w_nrwidth_width;
@@ -7287,23 +7114,16 @@ int number_width(win_T *wp)
return n;
}
-/*
- * Set size of the Vim shell.
- * If 'mustset' is TRUE, we must set Rows and Columns, do not get the real
- * window size (this is used for the :win command).
- * If 'mustset' is FALSE, we may try to get the real window size and if
- * it fails use 'width' and 'height'.
- */
+/// Set dimensions of the Nvim application "shell".
void screen_resize(int width, int height)
{
static int busy = FALSE;
- /*
- * Avoid recursiveness, can happen when setting the window size causes
- * another window-changed signal.
- */
- if (busy)
+ // Avoid recursiveness, can happen when setting the window size causes
+ // another window-changed signal.
+ if (updating_screen || busy) {
return;
+ }
if (width < 0 || height < 0) /* just checking... */
return;
@@ -7330,6 +7150,8 @@ void screen_resize(int width, int height)
width = Columns;
ui_resize(width, height);
+ send_grid_resize = true;
+
/* The window layout used to be adjusted here, but it now happens in
* screenalloc() (also invoked from screenclear()). That is because the
* "busy" check above may skip this, but not screenalloc(). */
@@ -7351,7 +7173,7 @@ void screen_resize(int width, int height)
* - in Ex mode, don't redraw anything.
* - Otherwise, redraw right now, and position the cursor.
* Always need to call update_screen() or screenalloc(), to make
- * sure Rows/Columns and the size of ScreenLines[] is correct!
+ * sure Rows/Columns and the size of the screen is correct!
*/
if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
|| exmode_active) {
@@ -7365,13 +7187,14 @@ void screen_resize(int width, int height)
redrawcmdline();
} else {
update_topline();
- if (pum_visible()) {
+ if (pum_drawn()) {
redraw_later(NOT_VALID);
- ins_compl_show_pum(); /* This includes the redraw. */
- } else
- update_screen(NOT_VALID);
- if (redrawing())
+ ins_compl_show_pum();
+ }
+ update_screen(NOT_VALID);
+ if (redrawing()) {
setcursor();
+ }
}
}
}
@@ -7379,8 +7202,8 @@ void screen_resize(int width, int height)
--busy;
}
-// Check if the new shell size is valid, correct it if it's too small or way
-// too big.
+/// Check if the new Nvim application "shell" dimensions are valid.
+/// Correct it if it's too small or way too big.
void check_shellsize(void)
{
if (Rows < min_rows()) {
@@ -7422,3 +7245,13 @@ void win_new_shellsize(void)
shell_new_columns(); // update window sizes
}
}
+
+win_T *get_win_by_grid_handle(handle_T handle)
+{
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_grid.handle == handle) {
+ return wp;
+ }
+ }
+ return NULL;
+}
diff --git a/src/nvim/screen.h b/src/nvim/screen.h
index 81a8b9ed4c..109541ef07 100644
--- a/src/nvim/screen.h
+++ b/src/nvim/screen.h
@@ -3,6 +3,11 @@
#include <stdbool.h>
+#include "nvim/types.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/grid_defs.h"
+#include "nvim/pos.h"
+
/*
* flags for update_screen()
* The higher the value, the higher the priority
@@ -16,6 +21,18 @@
#define NOT_VALID 40 /* buffer needs complete redraw */
#define CLEAR 50 /* screen messed up, clear it */
+/// By default, all widows are draw on a single rectangular grid, represented by
+/// this ScreenGrid instance. In multigrid mode each window will have its own
+/// grid, then this is only used for global screen elements that hasn't been
+/// externalized.
+///
+/// Note: before the screen is initialized and when out of memory these can be
+/// NULL.
+EXTERN ScreenGrid default_grid INIT(= { 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
+ 0, 0, 0 });
+
+#define DEFAULT_GRID_HANDLE 1 // handle for the default_grid
+
/// Status line click definition
typedef struct {
enum {
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 6e2b69fff7..cf0f1ea287 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.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
+
/*
* search.c: code for normal mode searching commands
*/
@@ -31,7 +34,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/move.h"
#include "nvim/mouse.h"
#include "nvim/normal.h"
@@ -94,6 +96,9 @@ static int lastc_bytelen = 1; /* >1 for multi-byte char */
/* copy of spats[], for keeping the search patterns while executing autocmds */
static struct spat saved_spats[2];
+// copy of spats[RE_SEARCH], for keeping the search patterns while incremental
+// searching
+static struct spat saved_last_search_spat;
static int saved_last_idx = 0;
static int saved_no_hlsearch = 0;
@@ -125,8 +130,8 @@ typedef struct SearchedFile {
*
* returns FAIL if failed, OK otherwise.
*/
-int
-search_regcomp (
+int
+search_regcomp(
char_u *pat,
int pat_save,
int pat_use,
@@ -283,7 +288,7 @@ void restore_search_patterns(void)
static inline void free_spat(struct spat *const spat)
{
xfree(spat->pat);
- dict_unref(spat->additional_data);
+ tv_dict_unref(spat->additional_data);
}
#if defined(EXITFREE)
@@ -303,19 +308,55 @@ void free_search_patterns(void)
#endif
+/// Save and restore the search pattern for incremental highlight search
+/// feature.
+///
+/// It's similar but different from save_search_patterns() and
+/// restore_search_patterns(), because the search pattern must be restored when
+/// cancelling incremental searching even if it's called inside user functions.
+void save_last_search_pattern(void)
+{
+ saved_last_search_spat = spats[RE_SEARCH];
+ if (spats[RE_SEARCH].pat != NULL) {
+ saved_last_search_spat.pat = vim_strsave(spats[RE_SEARCH].pat);
+ }
+ saved_last_idx = last_idx;
+ saved_no_hlsearch = no_hlsearch;
+}
+
+void restore_last_search_pattern(void)
+{
+ xfree(spats[RE_SEARCH].pat);
+ spats[RE_SEARCH] = saved_last_search_spat;
+ set_vv_searchforward();
+ last_idx = saved_last_idx;
+ SET_NO_HLSEARCH(saved_no_hlsearch);
+}
+
+char_u *last_search_pattern(void)
+{
+ return spats[RE_SEARCH].pat;
+}
+
/*
* Return TRUE when case should be ignored for search pattern "pat".
* Uses the 'ignorecase' and 'smartcase' options.
*/
int ignorecase(char_u *pat)
{
- int ic = p_ic;
+ return ignorecase_opt(pat, p_ic, p_scs);
+}
- if (ic && !no_smartcase && p_scs
+/// As ignorecase() put pass the "ic" and "scs" flags.
+int ignorecase_opt(char_u *pat, int ic_in, int scs)
+{
+ int ic = ic_in;
+ if (ic && !no_smartcase && scs
&& !(ctrl_x_mode && curbuf->b_p_inf)
- )
+ ) {
ic = !pat_has_uppercase(pat);
- no_smartcase = FALSE;
+ }
+ no_smartcase = false;
return ic;
}
@@ -330,30 +371,34 @@ int pat_has_uppercase(char_u *pat)
while (*p != NUL) {
int l;
- if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) {
- if (enc_utf8 && utf_isupper(utf_ptr2char(p)))
- return TRUE;
+ if ((l = mb_ptr2len(p)) > 1) {
+ if (mb_isupper(utf_ptr2char(p))) {
+ return true;
+ }
p += l;
} else if (*p == '\\') {
- if (p[1] == '_' && p[2] != NUL) /* skip "\_X" */
+ if (p[1] == '_' && p[2] != NUL) { // skip "\_X"
p += 3;
- else if (p[1] == '%' && p[2] != NUL) /* skip "\%X" */
+ } else if (p[1] == '%' && p[2] != NUL) { // skip "\%X"
p += 3;
- else if (p[1] != NUL) /* skip "\X" */
+ } else if (p[1] != NUL) { // skip "\X"
p += 2;
- else
+ } else {
p += 1;
- } else if (vim_isupper(*p))
- return TRUE;
- else
- ++p;
+ }
+ } else if (mb_isupper(*p)) {
+ return true;
+ } else {
+ p++;
+ }
}
return FALSE;
}
-char_u *last_csearch(void)
+const char *last_csearch(void)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- return lastc_bytes;
+ return (const char *)lastc_bytes;
}
int last_csearch_forward(void)
@@ -476,7 +521,7 @@ int searchit(
buffer without a window! */
buf_T *buf,
pos_T *pos,
- int dir,
+ Direction dir,
char_u *pat,
long count,
int options,
@@ -525,8 +570,12 @@ int searchit(
&& pos->lnum >= 1 && 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 = ml_get_buf(buf, pos->lnum, false) + pos->col;
- start_char_len = *ptr == NUL ? 1 : (*mb_ptr2len)(ptr);
+ ptr = ml_get_buf(buf, pos->lnum, false);
+ if ((int)STRLEN(ptr) <= pos->col) {
+ start_char_len = 1;
+ } else {
+ start_char_len = utfc_ptr2len(ptr + pos->col);
+ }
} else {
start_char_len = 1;
}
@@ -604,7 +653,7 @@ int searchit(
* otherwise "/$" will get stuck on end of line.
*/
while (matchpos.lnum == 0
- && ((options & SEARCH_END) && first_match
+ && (((options & SEARCH_END) && first_match)
? (nmatched == 1
&& (int)endpos.col - 1
< (int)start_pos.col + extra_col)
@@ -730,12 +779,17 @@ int searchit(
}
}
if (ptr[matchcol] == NUL
- || (nmatched = vim_regexec_multi(&regmatch,
- win, buf, lnum + matchpos.lnum,
- matchcol,
- tm
- )) == 0)
- break;
+ || (nmatched = vim_regexec_multi(
+ &regmatch, win, buf, lnum + matchpos.lnum, matchcol,
+ tm)) == 0) {
+ // If the search timed out, we did find a match
+ // but it might be the wrong one, so that's not
+ // OK.
+ if (tm != NULL && profile_passed_limit(*tm)) {
+ match_ok = false;
+ }
+ break;
+ }
/* Need to get the line pointer again, a
* multi-line search may have made it invalid. */
@@ -767,11 +821,10 @@ int searchit(
pos->lnum, FALSE));
}
} else {
- --pos->col;
- if (has_mbyte
- && pos->lnum <= buf->b_ml.ml_line_count) {
- ptr = ml_get_buf(buf, pos->lnum, FALSE);
- pos->col -= (*mb_head_off)(ptr, ptr + pos->col);
+ pos->col--;
+ if (pos->lnum <= buf->b_ml.ml_line_count) {
+ ptr = ml_get_buf(buf, pos->lnum, false);
+ pos->col -= utf_head_off(ptr, ptr + pos->col);
}
}
} else {
@@ -993,14 +1046,13 @@ int do_search(
dircp = NULL;
/* use previous pattern */
if (pat == NULL || *pat == NUL || *pat == dirc) {
- if (spats[RE_SEARCH].pat == NULL) { /* no previous pattern */
- pat = spats[RE_SUBST].pat;
- if (pat == NULL) {
+ if (spats[RE_SEARCH].pat == NULL) { // no previous pattern
+ searchstr = spats[RE_SUBST].pat;
+ if (searchstr == NULL) {
EMSG(_(e_noprevre));
retval = 0;
goto end_do_search;
}
- searchstr = pat;
} else {
/* make search_regcomp() use spats[RE_SEARCH].pat */
searchstr = (char_u *)"";
@@ -1071,8 +1123,8 @@ int do_search(
msgbuf = xmalloc(STRLEN(p) + 40);
{
msgbuf[0] = dirc;
- if (enc_utf8 && utf_iscomposing(utf_ptr2char(p))) {
- /* Use a space to draw the composing char on. */
+ if (utf_iscomposing(utf_ptr2char(p))) {
+ // Use a space to draw the composing char on.
msgbuf[1] = ' ';
STRCPY(msgbuf + 2, p);
} else
@@ -1239,9 +1291,9 @@ end_do_search:
* search_for_exact_line(buf, pos, dir, pat)
*
* Search for a line starting with the given pattern (ignoring leading
- * white-space), starting from pos and going in direction dir. pos will
+ * white-space), starting from pos and going in direction "dir". "pos" will
* contain the position of the match found. Blank lines match only if
- * ADDING is set. if p_ic is set then the pattern must be in lowercase.
+ * ADDING is set. If p_ic is set then the pattern must be in lowercase.
* Return OK for success, or FAIL if no line found.
*/
int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat)
@@ -1285,10 +1337,11 @@ int search_for_exact_line(buf_T *buf, pos_T *pos, int dir, char_u *pat)
* ignored because we are interested in the next line -- Acevedo */
if ((compl_cont_status & CONT_ADDING)
&& !(compl_cont_status & CONT_SOL)) {
- if ((p_ic ? mb_stricmp(p, pat) : STRCMP(p, pat)) == 0)
+ if (mb_strcmp_ic((bool)p_ic, (const char *)p, (const char *)pat) == 0) {
return OK;
- } else if (*p != NUL) { /* ignore empty lines */
- /* expanding lines or words */
+ }
+ } else if (*p != NUL) { // Ignore empty lines.
+ // Expanding lines or words.
assert(compl_length >= 0);
if ((p_ic ? mb_strnicmp(p, pat, (size_t)compl_length)
: STRNCMP(p, pat, compl_length)) == 0)
@@ -1323,20 +1376,25 @@ int searchc(cmdarg_T *cap, int t_cmd)
*lastc = c;
set_csearch_direction(dir);
set_csearch_until(t_cmd);
- lastc_bytelen = (*mb_char2bytes)(c, lastc_bytes);
+ lastc_bytelen = utf_char2bytes(c, lastc_bytes);
if (cap->ncharC1 != 0) {
- lastc_bytelen += (*mb_char2bytes)(cap->ncharC1, lastc_bytes + lastc_bytelen);
- if (cap->ncharC2 != 0)
- lastc_bytelen += (*mb_char2bytes)(cap->ncharC2, lastc_bytes + lastc_bytelen);
+ lastc_bytelen += utf_char2bytes(cap->ncharC1,
+ lastc_bytes + lastc_bytelen);
+ if (cap->ncharC2 != 0) {
+ lastc_bytelen += utf_char2bytes(cap->ncharC2,
+ lastc_bytes + lastc_bytelen);
+ }
}
}
- } else { /* repeat previous search */
- if (*lastc == NUL)
+ } else { // repeat previous search
+ if (*lastc == NUL && lastc_bytelen == 1) {
return FAIL;
- if (dir) /* repeat in opposite direction */
+ }
+ if (dir) { // repeat in opposite direction
dir = -lastcdir;
- else
+ } else {
dir = lastcdir;
+ }
t_cmd = last_t_cmd;
c = *lastc;
/* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */
@@ -1367,16 +1425,16 @@ int searchc(cmdarg_T *cap, int t_cmd)
} else {
if (col == 0)
return FAIL;
- col -= (*mb_head_off)(p, p + col - 1) + 1;
+ col -= utf_head_off(p, p + col - 1) + 1;
}
if (lastc_bytelen == 1) {
- if (p[col] == c && stop)
+ if (p[col] == c && stop) {
break;
- } else {
- if (memcmp(p + col, lastc_bytes, lastc_bytelen) == 0 && stop)
+ }
+ } else if (STRNCMP(p + col, lastc_bytes, lastc_bytelen) == 0 && stop) {
break;
}
- stop = TRUE;
+ stop = true;
}
} else {
for (;; ) {
@@ -1390,15 +1448,14 @@ int searchc(cmdarg_T *cap, int t_cmd)
}
if (t_cmd) {
- /* backup to before the character (possibly double-byte) */
+ // Backup to before the character (possibly double-byte).
col -= dir;
- if (has_mbyte) {
- if (dir < 0)
- /* Landed on the search char which is lastc_bytelen long */
- col += lastc_bytelen - 1;
- else
- /* To previous char, which may be multi-byte. */
- col -= (*mb_head_off)(p, p + col);
+ if (dir < 0) {
+ // Landed on the search char which is lastc_bytelen long.
+ col += lastc_bytelen - 1;
+ } else {
+ // To previous char, which may be multi-byte.
+ col -= utf_head_off(p, p + col);
}
}
curwin->w_cursor.col = col;
@@ -1420,59 +1477,55 @@ pos_T *findmatch(oparg_T *oap, int initc)
return findmatchlimit(oap, initc, 0, 0);
}
-/*
- * Return TRUE if the character before "linep[col]" equals "ch".
- * Return FALSE if "col" is zero.
- * Update "*prevcol" to the column of the previous character, unless "prevcol"
- * is NULL.
- * Handles multibyte string correctly.
- */
-static int check_prevcol(char_u *linep, int col, int ch, int *prevcol)
+// Return true if the character before "linep[col]" equals "ch".
+// Return false if "col" is zero.
+// Update "*prevcol" to the column of the previous character, unless "prevcol"
+// is NULL.
+// Handles multibyte string correctly.
+static bool check_prevcol(char_u *linep, int col, int ch, int *prevcol)
{
- --col;
- if (col > 0 && has_mbyte)
- col -= (*mb_head_off)(linep, linep + col);
- if (prevcol)
+ col--;
+ if (col > 0) {
+ col -= utf_head_off(linep, linep + col);
+ }
+ if (prevcol) {
*prevcol = col;
- return (col >= 0 && linep[col] == ch) ? TRUE : FALSE;
+ }
+ return (col >= 0 && linep[col] == ch) ? true : false;
}
/*
* Raw string start is found at linep[startpos.col - 1].
* Return true if the matching end can be found between startpos and endpos.
*/
-static int find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
+static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
{
char_u *p;
char_u *delim_copy;
size_t delim_len;
linenr_T lnum;
- int found = false;
- for (p = linep + startpos->col + 1; *p && *p != '('; ++p) {}
+ for (p = linep + startpos->col + 1; *p && *p != '('; p++) {}
delim_len = (p - linep) - startpos->col - 1;
delim_copy = vim_strnsave(linep + startpos->col + 1, delim_len);
- if (delim_copy == NULL)
- return false;
- for (lnum = startpos->lnum; lnum <= endpos->lnum; ++lnum)
- {
+ bool found = false;
+ for (lnum = startpos->lnum; lnum <= endpos->lnum; lnum++) {
char_u *line = ml_get(lnum);
- for (p = line + (lnum == startpos->lnum
- ? startpos->col + 1 : 0); *p; ++p)
- {
- if (lnum == endpos->lnum && (colnr_T)(p - line) >= endpos->col)
+ for (p = line + (lnum == startpos->lnum ? startpos->col + 1 : 0); *p; p++) {
+ if (lnum == endpos->lnum && (colnr_T)(p - line) >= endpos->col) {
break;
+ }
if (*p == ')' && p[delim_len + 1] == '"'
- && STRNCMP(delim_copy, p + 1, delim_len) == 0)
- {
+ && STRNCMP(delim_copy, p + 1, delim_len) == 0) {
found = true;
break;
}
}
- if (found)
+ if (found) {
break;
+ }
}
xfree(delim_copy);
return found;
@@ -1501,37 +1554,31 @@ static int find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
{
- static pos_T pos; /* current search position */
- int findc = 0; /* matching brace */
- int c;
- int count = 0; /* cumulative number of braces */
- int backwards = false; /* init for gcc */
- int raw_string = false; /* search for raw string */
- int inquote = false; /* true when inside quotes */
- char_u *linep; /* pointer to current line */
+ static pos_T pos; // current search position
+ int findc = 0; // matching brace
+ int count = 0; // cumulative number of braces
+ int backwards = false; // init for gcc
+ bool raw_string = false; // search for raw string
+ bool inquote = false; // true when inside quotes
char_u *ptr;
- int do_quotes; /* check for quotes in current line */
- int at_start; /* do_quotes value at start position */
- int hash_dir = 0; /* Direction searched for # things */
- int comment_dir = 0; /* Direction searched for comments */
- pos_T match_pos; /* Where last slash-star was found */
- int start_in_quotes; /* start position is in quotes */
- int traveled = 0; /* how far we've searched so far */
- int ignore_cend = FALSE; /* ignore comment end */
- int cpo_match; /* vi compatible matching */
- int cpo_bsl; /* don't recognize backslashes */
- int match_escaped = 0; /* search for escaped match */
- int dir; /* Direction to search */
- int comment_col = MAXCOL; /* start of / / comment */
- int lispcomm = FALSE; /* inside of Lisp-style comment */
- int lisp = curbuf->b_p_lisp; /* engage Lisp-specific hacks ;) */
+ 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
+ bool ignore_cend = false; // ignore comment end
+ int match_escaped = 0; // search for escaped match
+ int dir; // Direction to search
+ int comment_col = MAXCOL; // start of / / comment
+ bool lispcomm = false; // inside of Lisp-style comment
+ bool lisp = curbuf->b_p_lisp; // engage Lisp-specific hacks ;)
pos = curwin->w_cursor;
pos.coladd = 0;
- linep = ml_get(pos.lnum);
+ char_u *linep = ml_get(pos.lnum); // pointer to current line
- cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL);
- cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL);
+ // vi compatible matching
+ bool cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL);
+ // don't recognize backslashes
+ bool cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL);
/* Direction to search when initc is '/', '*' or '#' */
if (flags & FM_BACKWARD)
@@ -1700,13 +1747,16 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
}
- /* This is just guessing: when 'rightleft' is set, search for a matching
- * paren/brace in the other direction. */
- if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL)
+ // This is just guessing: when 'rightleft' is set, search for a matching
+ // paren/brace in the other direction.
+ if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL) {
backwards = !backwards;
+ }
- do_quotes = -1;
- start_in_quotes = MAYBE;
+ int do_quotes = -1; // check for quotes in current line
+ int at_start; // do_quotes value at start position
+ TriState start_in_quotes = kNone; // start position is in quotes
+ pos_T match_pos; // Where last slash-star was found
clearpos(&match_pos);
/* backward search: Check if this line contains a single-line comment */
@@ -1714,8 +1764,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
|| lisp
)
comment_col = check_linecomment(linep);
- if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col)
- lispcomm = TRUE; /* find match inside this comment */
+ if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) {
+ lispcomm = true; // find match inside this comment
+ }
while (!got_int) {
/*
* Go to the next position, forward or backward. We could use
@@ -1747,9 +1798,8 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
if (lisp && comment_col != MAXCOL)
pos.col = comment_col;
} else {
- --pos.col;
- if (has_mbyte)
- pos.col -= (*mb_head_off)(linep, linep + pos.col);
+ pos.col--;
+ pos.col -= utf_head_off(linep, linep + pos.col);
}
} else { /* forward search */
if (linep[pos.col] == NUL
@@ -1803,7 +1853,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
} else { /* Searching backwards */
/*
* A comment may contain / * or / /, it may also start or end
- * with / * /. Ignore a / * after / /.
+ * with / * /. Ignore a / * after / / and after *.
*/
if (pos.col == 0)
continue;
@@ -1828,6 +1878,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
} else if ( linep[pos.col - 1] == '/'
&& linep[pos.col] == '*'
+ && (pos.col == 1 || linep[pos.col - 2] != '*')
&& (int)pos.col < comment_col) {
count++;
match_pos = pos;
@@ -1877,26 +1928,29 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* one for a '\' at the end.
*/
if (!do_quotes) {
- inquote = FALSE;
+ inquote = false;
if (ptr[-1] == '\\') {
do_quotes = 1;
- if (start_in_quotes == MAYBE) {
- /* Do we need to use at_start here? */
- inquote = TRUE;
- start_in_quotes = TRUE;
- } else if (backwards)
- inquote = TRUE;
+ if (start_in_quotes == kNone) {
+ // Do we need to use at_start here?
+ inquote = true;
+ start_in_quotes = kTrue;
+ } else if (backwards) {
+ inquote = true;
+ }
}
if (pos.lnum > 1) {
ptr = ml_get(pos.lnum - 1);
if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\\') {
do_quotes = 1;
- if (start_in_quotes == MAYBE) {
+ if (start_in_quotes == kNone) {
inquote = at_start;
- if (inquote)
- start_in_quotes = TRUE;
- } else if (!backwards)
- inquote = TRUE;
+ if (inquote) {
+ start_in_quotes = kTrue;
+ }
+ } else if (!backwards) {
+ inquote = true;
+ }
}
/* ml_get() only keeps one line, need to get linep again */
@@ -1904,8 +1958,9 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
}
}
- if (start_in_quotes == MAYBE)
- start_in_quotes = FALSE;
+ if (start_in_quotes == kNone) {
+ start_in_quotes = kFalse;
+ }
/*
* If 'smartmatch' is set:
@@ -1918,13 +1973,13 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
* 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?
*/
- c = PTR2CHAR(linep + pos.col);
+ const int c = PTR2CHAR(linep + pos.col);
switch (c) {
case NUL:
/* at end of line without trailing backslash, reset inquote */
if (pos.col == 0 || linep[pos.col - 1] != '\\') {
- inquote = FALSE;
- start_in_quotes = FALSE;
+ inquote = false;
+ start_in_quotes = kFalse;
}
break;
@@ -1939,7 +1994,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
break;
if ((((int)pos.col - 1 - col) & 1) == 0) {
inquote = !inquote;
- start_in_quotes = FALSE;
+ start_in_quotes = kFalse;
}
}
break;
@@ -1975,7 +2030,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
}
}
}
- /* FALLTHROUGH */
+ FALLTHROUGH;
default:
/*
@@ -1991,7 +2046,7 @@ pos_T *findmatchlimit(oparg_T *oap, int initc, int flags, int64_t maxtravel)
/* Check for match outside of quotes, and inside of
* quotes when the start is also inside of quotes. */
- if ((!inquote || start_in_quotes == TRUE)
+ if ((!inquote || start_in_quotes == kTrue)
&& (c == initc || c == findc)) {
int col, bslcnt = 0;
@@ -2073,9 +2128,9 @@ static int check_linecomment(char_u *line)
* Show the match only if it is visible on the screen.
* If there isn't a match, then beep.
*/
-void
-showmatch (
- int c /* char to show match for */
+void
+showmatch(
+ int c // char to show match for
)
{
pos_T *lpos, save_cursor;
@@ -2111,9 +2166,10 @@ showmatch (
if (!curwin->w_p_wrap) {
getvcol(curwin, lpos, NULL, &vcol, NULL);
}
- if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol
- && vcol < curwin->w_leftcol + curwin->w_width)) {
- mpos = *lpos; /* save the pos, update_screen() may change it */
+ if (curwin->w_p_wrap
+ || (vcol >= curwin->w_leftcol
+ && vcol < curwin->w_leftcol + curwin->w_grid.Columns)) {
+ mpos = *lpos; // save the pos, update_screen() may change it
save_cursor = curwin->w_cursor;
save_so = p_so;
save_siso = p_siso;
@@ -2156,21 +2212,17 @@ showmatch (
}
}
-/*
- * findsent(dir, count) - Find the start of the next sentence in direction
- * "dir" Sentences are supposed to end in ".", "!" or "?" followed by white
- * space or a line break. Also stop at an empty line.
- * Return OK if the next sentence was found.
- */
-int findsent(int dir, long count)
+// Find the start of the next sentence, searching in the direction specified
+// by the "dir" argument. The cursor is positioned on the start of the next
+// sentence when found. If the next sentence is found, return OK. Return FAIL
+// otherwise. See ":h sentence" for the precise definition of a "sentence"
+// text object.
+int findsent(Direction dir, long count)
{
pos_T pos, tpos;
int c;
int (*func)(pos_T *);
- int startlnum;
- int noskip = FALSE; /* do not skip blanks */
- int cpo_J;
- int found_dot;
+ bool noskip = false; // do not skip blanks
pos = curwin->w_cursor;
if (dir == FORWARD)
@@ -2204,29 +2256,30 @@ int findsent(int dir, long count)
decl(&pos);
}
- // go back to the previous non-blank char
- found_dot = false;
- while ((c = gchar_pos(&pos)) == ' ' || c == '\t'
- || (dir == BACKWARD
- && vim_strchr((char_u *)".!?)]\"'", c) != NULL)) {
- if (vim_strchr((char_u *)".!?", c) != NULL) {
- /* Only skip over a '.', '!' and '?' once. */
- if (found_dot)
- break;
- found_dot = TRUE;
+ // go back to the previous non-white non-punctuation character
+ bool found_dot = false;
+ while (c = gchar_pos(&pos), ascii_iswhite(c)
+ || vim_strchr((char_u *)".!?)]\"'", c) != NULL) {
+ tpos = pos;
+ if (decl(&tpos) == -1 || (LINEEMPTY(tpos.lnum) && dir == FORWARD)) {
+ break;
}
- if (decl(&pos) == -1)
+ if (found_dot) {
+ break;
+ }
+ if (vim_strchr((char_u *) ".!?", c) != NULL) {
+ found_dot = true;
+ }
+ if (vim_strchr((char_u *) ")]\"'", c) != NULL
+ && vim_strchr((char_u *) ".!?)]\"'", gchar_pos(&tpos)) == NULL) {
break;
- /* when going forward: Stop in front of empty line */
- if (lineempty(pos.lnum) && dir == FORWARD) {
- incl(&pos);
- goto found;
}
+ decl(&pos);
}
- /* remember the line where the search started */
- startlnum = pos.lnum;
- cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL;
+ // remember the line where the search started
+ const int startlnum = pos.lnum;
+ const bool cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL;
for (;; ) { /* find end of sentence */
c = gchar_pos(&pos);
@@ -2254,7 +2307,7 @@ int findsent(int dir, long count)
if ((*func)(&pos) == -1) {
if (count)
return FAIL;
- noskip = TRUE;
+ noskip = true;
break;
}
}
@@ -2328,8 +2381,13 @@ findpar (
++curr;
curwin->w_cursor.lnum = curr;
if (curr == curbuf->b_ml.ml_line_count && what != '}') {
- if ((curwin->w_cursor.col = (colnr_T)STRLEN(ml_get(curr))) != 0) {
- --curwin->w_cursor.col;
+ char_u *line = ml_get(curr);
+
+ // Put the cursor on the last character in the last line and make the
+ // motion inclusive.
+ if ((curwin->w_cursor.col = (colnr_T)STRLEN(line)) != 0) {
+ curwin->w_cursor.col--;
+ curwin->w_cursor.col -= utf_head_off(line, line + curwin->w_cursor.col);
*pincl = true;
}
} else
@@ -2412,32 +2470,20 @@ static int cls(void)
int c;
c = gchar_cursor();
- if (p_altkeymap && c == F_BLANK)
+ if (p_altkeymap && c == F_BLANK) {
return 0;
- if (c == ' ' || c == '\t' || c == NUL)
- return 0;
- if (enc_dbcs != 0 && c > 0xFF) {
- /* If cls_bigword, report multi-byte chars as class 1. */
- if (enc_dbcs == DBCS_KOR && cls_bigword)
- return 1;
-
- /* process code leading/trailing bytes */
- return dbcs_class(((unsigned)c >> 8), (c & 0xFF));
}
- if (enc_utf8) {
- c = utf_class(c);
- if (c != 0 && cls_bigword)
- return 1;
- return c;
+ if (c == ' ' || c == '\t' || c == NUL) {
+ return 0;
}
- /* If cls_bigword is TRUE, report all non-blanks as class 1. */
- if (cls_bigword)
- return 1;
+ c = utf_class(c);
- if (vim_iswordc(c))
- return 2;
- return 1;
+ // If cls_bigword is TRUE, report all non-blanks as class 1.
+ if (c != 0 && cls_bigword) {
+ return 1;
+ }
+ return c;
}
/*
@@ -2446,8 +2492,8 @@ static int cls(void)
* Returns FAIL if the cursor was already at the end of the file.
* If eol is TRUE, last word stops at end of line (for operators).
*/
-int
-fwd_word (
+int
+fwd_word(
long count,
int bigword, /* "W", "E" or "B" */
int eol
@@ -2534,10 +2580,12 @@ int bck_word(long count, int bigword, int stop)
*/
while (cls() == 0) {
if (curwin->w_cursor.col == 0
- && lineempty(curwin->w_cursor.lnum))
+ && LINEEMPTY(curwin->w_cursor.lnum)) {
goto finished;
- if (dec_cursor() == -1) /* hit start of file, stop here */
+ }
+ if (dec_cursor() == -1) { // hit start of file, stop here
return OK;
+ }
}
/*
@@ -2601,10 +2649,12 @@ int end_word(long count, int bigword, int stop, int empty)
*/
while (cls() == 0) {
if (empty && curwin->w_cursor.col == 0
- && lineempty(curwin->w_cursor.lnum))
+ && LINEEMPTY(curwin->w_cursor.lnum)) {
goto finished;
- if (inc_cursor() == -1) /* hit end of file, stop here */
+ }
+ if (inc_cursor() == -1) { // hit end of file, stop here
return FAIL;
+ }
}
/*
@@ -2625,8 +2675,8 @@ finished:
*
* Returns FAIL if start of the file was reached.
*/
-int
-bckend_word (
+int
+bckend_word(
long count,
int bigword, /* TRUE for "B" */
int eol /* TRUE: stop at end of line. */
@@ -2657,10 +2707,12 @@ bckend_word (
* Move backward to end of the previous word
*/
while (cls() == 0) {
- if (curwin->w_cursor.col == 0 && lineempty(curwin->w_cursor.lnum))
+ if (curwin->w_cursor.col == 0 && LINEEMPTY(curwin->w_cursor.lnum)) {
break;
- if ((i = dec_cursor()) == -1 || (eol && i == 1))
+ }
+ if ((i = dec_cursor()) == -1 || (eol && i == 1)) {
return OK;
+ }
}
}
return OK;
@@ -2713,8 +2765,8 @@ static void find_first_blank(pos_T *posp)
/*
* Skip count/2 sentences and count/2 separating white spaces.
*/
-static void
-findsent_forward (
+static void
+findsent_forward(
long count,
int at_start_sent /* cursor is at start of sentence */
)
@@ -2733,8 +2785,8 @@ findsent_forward (
* Find word under cursor, cursor at end.
* Used while an operator is pending, and in Visual mode.
*/
-int
-current_word (
+int
+current_word(
oparg_T *oap,
long count,
int include, /* TRUE: include word and white space */
@@ -3023,7 +3075,8 @@ extend:
++curwin->w_cursor.col;
VIsual = start_pos;
VIsual_mode = 'v';
- redraw_curbuf_later(INVERTED); /* update the inversion */
+ redraw_cmdline = true; // show mode later
+ redraw_curbuf_later(INVERTED); // update the inversion
} else {
/* include a newline after the sentence, if there is one */
if (incl(&curwin->w_cursor) == -1)
@@ -3040,8 +3093,8 @@ extend:
* Find block under the cursor, cursor at end.
* "what" and "other" are two matching parenthesis/brace/etc.
*/
-int
-current_block (
+int
+current_block(
oparg_T *oap,
long count,
int include, /* TRUE == include white space */
@@ -3189,35 +3242,41 @@ static int in_html_tag(int end_tag)
/* We search forward until the cursor, because searching backwards is
* very slow for DBCS encodings. */
- for (p = line; p < line + curwin->w_cursor.col; mb_ptr_adv(p))
+ for (p = line; p < line + curwin->w_cursor.col; MB_PTR_ADV(p)) {
if (*p == '>' || *p == '<') {
lc = *p;
lp = p;
}
- if (*p != '<') { /* check for '<' under cursor */
- if (lc != '<')
- return FALSE;
+ }
+ if (*p != '<') { // check for '<' under cursor
+ if (lc != '<') {
+ return false;
+ }
p = lp;
}
} else {
for (p = line + curwin->w_cursor.col; p > line; ) {
- if (*p == '<') /* find '<' under/before cursor */
+ if (*p == '<') { // find '<' under/before cursor
break;
- mb_ptr_back(line, p);
- if (*p == '>') /* find '>' before cursor */
+ }
+ MB_PTR_BACK(line, p);
+ if (*p == '>') { // find '>' before cursor
break;
+ }
+ }
+ if (*p != '<') {
+ return false;
}
- if (*p != '<')
- return FALSE;
}
pos.lnum = curwin->w_cursor.lnum;
pos.col = (colnr_T)(p - line);
- mb_ptr_adv(p);
- if (end_tag)
- /* check that there is a '/' after the '<' */
+ MB_PTR_ADV(p);
+ if (end_tag) {
+ // check that there is a '/' after the '<'
return *p == '/';
+ }
/* check that there is no '/' after the '<' */
if (*p == '/')
@@ -3238,11 +3297,11 @@ static int in_html_tag(int end_tag)
/*
* Find tag block under the cursor, cursor at end.
*/
-int
-current_tagblock (
+int
+current_tagblock(
oparg_T *oap,
long count_arg,
- int include /* TRUE == include white space */
+ bool include // true == include white space
)
{
long count = count_arg;
@@ -3256,7 +3315,7 @@ current_tagblock (
char_u *cp;
int len;
int r;
- int do_include = include;
+ bool do_include = include;
bool save_p_ws = p_ws;
int retval = FAIL;
int is_inclusive = true;
@@ -3321,8 +3380,10 @@ again:
*/
inc_cursor();
p = get_cursor_pos_ptr();
- for (cp = p; *cp != NUL && *cp != '>' && !ascii_iswhite(*cp); mb_ptr_adv(cp))
- ;
+ for (cp = p;
+ *cp != NUL && *cp != '>' && !ascii_iswhite(*cp);
+ MB_PTR_ADV(cp)) {
+ }
len = (int)(cp - p);
if (len == 0) {
curwin->w_cursor = old_pos;
@@ -3348,11 +3409,13 @@ again:
goto again;
}
- if (do_include || r < 1) {
- /* Include up to the '>'. */
- while (*get_cursor_pos_ptr() != '>')
- if (inc_cursor() < 0)
+ if (do_include) {
+ // Include up to the '>'.
+ while (*get_cursor_pos_ptr() != '>') {
+ if (inc_cursor() < 0) {
break;
+ }
+ }
} else {
char_u *c = get_cursor_pos_ptr();
// Exclude the '<' of the end tag.
@@ -3378,10 +3441,12 @@ again:
}
curwin->w_cursor = end_pos;
- /* If we now have the same text as before reset "do_include" and try
- * again. */
- if (equalpos(start_pos, old_start) && equalpos(end_pos, old_end)) {
- do_include = TRUE;
+ // If we are in Visual mode and now have the same text as before set
+ // "do_include" and try again.
+ if (VIsual_active
+ && equalpos(start_pos, old_start)
+ && equalpos(end_pos, old_end)) {
+ do_include = true;
curwin->w_cursor = old_start;
count = count_arg;
goto again;
@@ -3419,8 +3484,8 @@ theend:
return retval;
}
-int
-current_par (
+int
+current_par(
oparg_T *oap,
long count,
int include, /* TRUE == include white space */
@@ -3556,11 +3621,15 @@ extend:
--start_lnum;
if (VIsual_active) {
- /* Problem: when doing "Vipipip" nothing happens in a single white
- * line, we get stuck there. Trap this here. */
- if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum)
+ // Problem: when doing "Vipipip" nothing happens in a single white
+ // line, we get stuck there. Trap this here.
+ if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum) {
goto extend;
- VIsual.lnum = start_lnum;
+ }
+ if (VIsual.lnum != start_lnum) {
+ VIsual.lnum = start_lnum;
+ VIsual.col = 0;
+ }
VIsual_mode = 'V';
redraw_curbuf_later(INVERTED); /* update the inversion */
showmode();
@@ -3582,8 +3651,8 @@ extend:
* as a quote.
* Returns column number of "quotechar" or -1 when not found.
*/
-static int
-find_next_quote (
+static int
+find_next_quote(
char_u *line,
int col,
int quotechar,
@@ -3614,8 +3683,8 @@ find_next_quote (
* as a quote.
* Return the found column or zero.
*/
-static int
-find_prev_quote (
+static int
+find_prev_quote(
char_u *line,
int col_start,
int quotechar,
@@ -3625,8 +3694,8 @@ find_prev_quote (
int n;
while (col_start > 0) {
- --col_start;
- col_start -= (*mb_head_off)(line, line + col_start);
+ col_start--;
+ col_start -= utf_head_off(line, line + col_start);
n = 0;
if (escape != NULL)
while (col_start - n > 0 && vim_strchr(escape,
@@ -3644,8 +3713,8 @@ find_prev_quote (
* Find quote under the cursor, cursor at end.
* Returns TRUE if found, else FALSE.
*/
-int
-current_quote (
+int
+current_quote(
oparg_T *oap,
long count,
int include, /* TRUE == include quote char */
@@ -3662,11 +3731,25 @@ current_quote (
int selected_quote = FALSE; /* Has quote inside selection */
int i;
- /* Correct cursor when 'selection' is exclusive */
+ // Correct cursor when 'selection' is "exclusive".
if (VIsual_active) {
+ // this only works within one line
+ if (VIsual.lnum != curwin->w_cursor.lnum) {
+ return false;
+ }
+
vis_bef_curs = lt(VIsual, curwin->w_cursor);
- if (*p_sel == 'e' && vis_bef_curs)
+ if (*p_sel == 'e') {
+ if (!vis_bef_curs) {
+ // VIsual needs to be start of Visual selection.
+ pos_T t = curwin->w_cursor;
+
+ curwin->w_cursor = VIsual;
+ VIsual = t;
+ vis_bef_curs = true;
+ }
dec_cursor();
+ }
vis_empty = equalpos(VIsual, curwin->w_cursor);
}
@@ -3856,8 +3939,8 @@ current_quote (
* Find next search match under cursor, cursor at end.
* Used while an operator is pending, and in Visual mode.
*/
-int
-current_search (
+int
+current_search(
long count,
int forward /* move forward or backwards */
)
@@ -3872,24 +3955,27 @@ current_search (
if (VIsual_active && *p_sel == 'e' && lt(VIsual, curwin->w_cursor))
dec_cursor();
- pos_T orig_pos; /* position of the cursor at beginning */
- pos_T pos; /* position after the pattern */
+ pos_T orig_pos; // position of the cursor at beginning
+ pos_T first_match; // position of first match
+ pos_T pos; // position after the pattern
+ int result; // result of various function calls
if (VIsual_active) {
orig_pos = pos = curwin->w_cursor;
- /* make sure, searching further will extend the match */
- if (VIsual_active) {
- if (forward)
- incl(&pos);
- else
- decl(&pos);
+ // Searching further will extend the match.
+ if (forward) {
+ incl(&pos);
+ } else {
+ decl(&pos);
}
- } else
+ } else {
orig_pos = pos = curwin->w_cursor;
+ }
- /* Is the pattern is zero-width? */
- int one_char = is_one_char(spats[last_idx].pat, true);
+ // Is the pattern is zero-width?, this time, don't care about the direction
+ int one_char = is_one_char(spats[last_idx].pat, true, &curwin->w_cursor,
+ FORWARD);
if (one_char == -1) {
p_ws = old_p_ws;
return FAIL; /* pattern not found */
@@ -3907,9 +3993,9 @@ current_search (
if (!dir && !one_char)
flags = SEARCH_END;
- int result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD),
- spats[last_idx].pat, i ? count : 1,
- SEARCH_KEEP | flags, RE_SEARCH, 0, NULL);
+ result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD),
+ spats[last_idx].pat, i ? count : 1,
+ SEARCH_KEEP | flags, RE_SEARCH, 0, NULL);
/* First search may fail, but then start searching from the
* beginning of the file (cursor might be on the search match)
@@ -3931,43 +4017,67 @@ current_search (
ml_get(curwin->w_buffer->b_ml.ml_line_count));
}
}
+ if (i == 0) {
+ first_match = pos;
+ }
p_ws = old_p_ws;
}
- int flags = forward ? SEARCH_END : 0;
+ const int flags = forward ? SEARCH_END : SEARCH_START;
pos_T start_pos = pos;
+ const Direction direction = forward ? FORWARD : BACKWARD;
- /* Check again from the current cursor position,
- * since the next match might actually be only one char wide */
- one_char = is_one_char(spats[last_idx].pat, false);
+ // Check again from the current cursor position,
+ // since the next match might actually be only one char wide
+ one_char = is_one_char(spats[last_idx].pat, false, &pos, direction);
+ if (one_char < 0) {
+ // search failed, abort
+ return FAIL;
+ }
/* move to match, except for zero-width matches, in which case, we are
* already on the next match */
- if (!one_char)
- searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD),
- spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL);
+ if (!one_char) {
+ p_ws = false;
+ for (int i = 0; i < 2; i++) {
+ result = searchit(curwin, curbuf, &pos, direction,
+ spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH,
+ 0, NULL);
+ // Search successfull, break out from the loop
+ if (result) {
+ break;
+ }
+ // search failed, try again from the last search position match
+ pos = first_match;
+ }
+ }
+
+ p_ws = old_p_ws;
+ // not found
+ if (!result) {
+ return FAIL;
+ }
if (!VIsual_active)
VIsual = start_pos;
curwin->w_cursor = pos;
- VIsual_active = TRUE;
+ VIsual_active = true;
VIsual_mode = 'v';
- if (VIsual_active) {
- redraw_curbuf_later(INVERTED); /* update the inversion */
- if (*p_sel == 'e') {
- /* Correction for exclusive selection depends on the direction. */
- if (forward && ltoreq(VIsual, curwin->w_cursor))
- inc_cursor();
- else if (!forward && ltoreq(curwin->w_cursor, VIsual))
- inc(&VIsual);
+ redraw_curbuf_later(INVERTED); // Update the inversion.
+ if (*p_sel == 'e') {
+ // Correction for exclusive selection depends on the direction.
+ if (forward && ltoreq(VIsual, curwin->w_cursor)) {
+ inc_cursor();
+ } else if (!forward && ltoreq(curwin->w_cursor, VIsual)) {
+ inc(&VIsual);
}
-
}
- if (fdo_flags & FDO_SEARCH && KeyTyped)
+ if (fdo_flags & FDO_SEARCH && KeyTyped) {
foldOpenCursor();
+ }
may_start_select('c');
setmouse();
@@ -3977,13 +4087,13 @@ current_search (
return OK;
}
-/*
- * Check if the pattern is one character or zero-width.
- * If move is true, check from the beginning of the buffer,
- * else from the current cursor position.
- * Returns TRUE, FALSE or -1 for failure.
- */
-static int is_one_char(char_u *pattern, bool move)
+/// Check if the pattern is one character long or zero-width.
+/// If move is true, check from the beginning of the buffer,
+/// else from position "cur".
+/// "direction" is FORWARD or BACKWARD.
+/// Returns TRUE, FALSE or -1 for failure.
+static int is_one_char(char_u *pattern, bool move, pos_T *cur,
+ Direction direction)
{
regmmatch_T regmatch;
int nmatched = 0;
@@ -3992,33 +4102,49 @@ static int is_one_char(char_u *pattern, bool move)
int save_called_emsg = called_emsg;
int flag = 0;
+ if (pattern == NULL) {
+ pattern = spats[last_idx].pat;
+ }
+
if (search_regcomp(pattern, RE_SEARCH, RE_SEARCH,
SEARCH_KEEP, &regmatch) == FAIL)
return -1;
- /* move to match */
+ // init startcol correctly
+ regmatch.startpos[0].col = -1;
+ // move to match
if (move) {
clearpos(&pos);
} else {
- pos = curwin->w_cursor;
- /* accept a match at the cursor position */
+ pos = *cur;
+ // accept a match at the cursor position
flag = SEARCH_START;
}
- if (searchit(curwin, curbuf, &pos, FORWARD, spats[last_idx].pat, 1,
- SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL) {
- /* Zero-width pattern should match somewhere, then we can check if
- * start and end are in the same position. */
- called_emsg = FALSE;
- nmatched = vim_regexec_multi(&regmatch, curwin, curbuf,
- pos.lnum, (colnr_T)0, NULL);
-
- if (!called_emsg)
+ if (searchit(curwin, curbuf, &pos, direction, pattern, 1,
+ SEARCH_KEEP + flag, RE_SEARCH, 0, NULL) != FAIL) {
+ // Zero-width pattern should match somewhere, then we can check if
+ // start and end are in the same position.
+ called_emsg = false;
+ do {
+ regmatch.startpos[0].col++;
+ nmatched = vim_regexec_multi(&regmatch, curwin, curbuf,
+ pos.lnum, regmatch.startpos[0].col, NULL);
+ if (!nmatched) {
+ break;
+ }
+ } while (direction == FORWARD
+ ? regmatch.startpos[0].col < pos.col
+ : regmatch.startpos[0].col > pos.col);
+
+ if (!called_emsg) {
result = (nmatched != 0
&& regmatch.startpos[0].lnum == regmatch.endpos[0].lnum
&& regmatch.startpos[0].col == regmatch.endpos[0].col);
-
- if (!result && inc(&pos) >= 0 && pos.col == regmatch.endpos[0].col)
- result = TRUE;
+ // one char width
+ if (!result && inc(&pos) >= 0 && pos.col == regmatch.endpos[0].col) {
+ result = true;
+ }
+ }
}
called_emsg |= save_called_emsg;
@@ -4041,19 +4167,19 @@ int linewhite(linenr_T lnum)
* Find identifiers or defines in included files.
* If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase.
*/
-void
-find_pattern_in_path (
- char_u *ptr, /* pointer to search pattern */
- int dir, /* direction of expansion */
- size_t len, /* length of search pattern */
- int whole, /* match whole words only */
- int skip_comments, /* don't match inside comments */
- int type, /* Type of search; are we looking for a type?
- a macro? */
+void
+find_pattern_in_path(
+ char_u *ptr, // pointer to search pattern
+ int dir, // direction of expansion
+ size_t len, // length of search pattern
+ int whole, // match whole words only
+ int skip_comments, // don't match inside comments
+ int type, // Type of search; are we looking for a type?
+ // a macro?
long count,
- int action, /* What to do when we find it */
- linenr_T start_lnum, /* first line to start searching */
- linenr_T end_lnum /* last line for searching */
+ int action, // What to do when we find it
+ linenr_T start_lnum, // first line to start searching
+ linenr_T end_lnum // last line for searching
)
{
SearchedFile *files; /* Stack of included files */
@@ -4207,7 +4333,7 @@ find_pattern_in_path (
if (new_fname != NULL) {
/* using "new_fname" is more reliable, e.g., when
* 'includeexpr' is set. */
- msg_outtrans_attr(new_fname, hl_attr(HLF_D));
+ msg_outtrans_attr(new_fname, HL_ATTR(HLF_D));
} else {
/*
* Isolate the file name.
@@ -4245,7 +4371,7 @@ find_pattern_in_path (
}
save_char = p[i];
p[i] = NUL;
- msg_outtrans_attr(p, hl_attr(HLF_D));
+ msg_outtrans_attr(p, HL_ATTR(HLF_D));
p[i] = save_char;
}
@@ -4292,11 +4418,11 @@ find_pattern_in_path (
files[depth].lnum = 0;
files[depth].matched = FALSE;
if (action == ACTION_EXPAND) {
- msg_hist_off = TRUE; /* reset in msg_trunc_attr() */
- vim_snprintf((char*)IObuff, IOSIZE,
- _("Scanning included file: %s"),
- (char *)new_fname);
- msg_trunc_attr(IObuff, TRUE, hl_attr(HLF_R));
+ msg_hist_off = true; // reset in msg_trunc_attr()
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Scanning included file: %s"),
+ (char *)new_fname);
+ msg_trunc_attr(IObuff, true, HL_ATTR(HLF_R));
} else if (p_verbose >= 5) {
verbose_enter();
smsg(_("Searching included file %s"),
@@ -4506,20 +4632,24 @@ search_line:
RESET_BINDING(curwin);
}
if (depth == -1) {
- /* match in current file */
+ // match in current file
if (l_g_do_tagpreview != 0) {
- if (getfile(0, curwin_save->w_buffer->b_fname,
- NULL, TRUE, lnum, FALSE) > 0)
- break; /* failed to jump to file */
- } else
+ if (!GETFILE_SUCCESS(getfile(curwin_save->w_buffer->b_fnum, NULL,
+ NULL, true, lnum, false))) {
+ break; // failed to jump to file
+ }
+ } else {
setpcmark();
+ }
curwin->w_cursor.lnum = lnum;
+ check_cursor();
} else {
- if (getfile(0, files[depth].name, NULL, TRUE,
- files[depth].lnum, FALSE) > 0)
- break; /* failed to jump to file */
- /* autocommands may have changed the lnum, we don't
- * want that here */
+ if (!GETFILE_SUCCESS(getfile(0, files[depth].name, NULL, true,
+ files[depth].lnum, false))) {
+ break; // failed to jump to file
+ }
+ // autocommands may have changed the lnum, we don't
+ // want that here
curwin->w_cursor.lnum = files[depth].lnum;
}
}
@@ -4550,7 +4680,7 @@ exit_matched:
}
line_breakcheck();
if (action == ACTION_EXPAND)
- ins_compl_check_keys(30);
+ ins_compl_check_keys(30, false);
if (got_int || compl_interrupted)
break;
@@ -4645,12 +4775,12 @@ static void show_pat_in_path(char_u *line, int type, int did_show, int action, F
*(p + 1) = NUL;
}
if (action == ACTION_SHOW_ALL) {
- sprintf((char *)IObuff, "%3ld: ", count); /* show match nr */
- msg_puts(IObuff);
- sprintf((char *)IObuff, "%4ld", *lnum); /* show line nr */
- /* Highlight line numbers */
- msg_puts_attr(IObuff, hl_attr(HLF_N));
- MSG_PUTS(" ");
+ snprintf((char *)IObuff, IOSIZE, "%3ld: ", count); // Show match nr.
+ msg_puts((const char *)IObuff);
+ snprintf((char *)IObuff, IOSIZE, "%4ld", *lnum); // Show line nr.
+ // Highlight line numbers.
+ msg_puts_attr((const char *)IObuff, HL_ATTR(HLF_N));
+ msg_puts(" ");
}
msg_prt_line(line, FALSE);
ui_flush(); /* show one line at a time */
diff --git a/src/nvim/search.h b/src/nvim/search.h
index d4e40cb287..cb094aab8c 100644
--- a/src/nvim/search.h
+++ b/src/nvim/search.h
@@ -4,6 +4,12 @@
#include <stdbool.h>
#include <stdint.h>
+#include "nvim/vim.h"
+#include "nvim/buffer_defs.h"
+#include "nvim/eval/typval.h"
+#include "nvim/normal.h"
+#include "nvim/os/time.h"
+
/* Values for the find_pattern_in_path() function args 'type' and 'action': */
#define FIND_ANY 1
#define FIND_DEFINE 2
diff --git a/src/nvim/sha256.c b/src/nvim/sha256.c
index 7670b64468..a2378cc202 100644
--- a/src/nvim/sha256.c
+++ b/src/nvim/sha256.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
+
/// @file sha256.c
///
/// FIPS-180-2 compliant SHA-256 implementation
@@ -259,11 +262,11 @@ void sha256_finish(context_sha256_T *ctx, char_u digest[SHA256_SUM_SIZE])
///
/// @returns hex digest of "buf[buf_len]" in a static array.
/// if "salt" is not NULL also do "salt[salt_len]".
-char_u *sha256_bytes(const char_u *restrict buf, size_t buf_len,
- const char_u *restrict salt, size_t salt_len)
+const char *sha256_bytes(const uint8_t *restrict buf, size_t buf_len,
+ const uint8_t *restrict salt, size_t salt_len)
{
char_u sha256sum[SHA256_SUM_SIZE];
- static char_u hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
+ static char hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
context_sha256_T ctx;
sha256_self_test();
@@ -277,7 +280,7 @@ char_u *sha256_bytes(const char_u *restrict buf, size_t buf_len,
sha256_finish(&ctx, sha256sum);
for (size_t j = 0; j < SHA256_SUM_SIZE; j++) {
- snprintf((char *) hexit + j * SHA_STEP, SHA_STEP+1, "%02x", sha256sum[j]);
+ snprintf(hexit + j * SHA_STEP, SHA_STEP + 1, "%02x", sha256sum[j]);
}
hexit[sizeof(hexit) - 1] = '\0';
return hexit;
@@ -308,7 +311,7 @@ bool sha256_self_test(void)
context_sha256_T ctx;
char_u buf[1000];
char_u sha256sum[SHA256_SUM_SIZE];
- char_u *hexit;
+ const char *hexit;
static bool sha256_self_tested = false;
static bool failures = false;
@@ -320,8 +323,8 @@ bool sha256_self_test(void)
for (size_t i = 0; i < 3; i++) {
if (i < 2) {
- hexit = sha256_bytes((char_u *) sha_self_test_msg[i],
- STRLEN(sha_self_test_msg[i]),
+ hexit = sha256_bytes((uint8_t *)sha_self_test_msg[i],
+ strlen(sha_self_test_msg[i]),
NULL, 0);
STRCPY(output, hexit);
} else {
diff --git a/src/nvim/sha256.h b/src/nvim/sha256.h
index a118826542..deb881a288 100644
--- a/src/nvim/sha256.h
+++ b/src/nvim/sha256.h
@@ -2,6 +2,7 @@
#define NVIM_SHA256_H
#include <stdint.h> // for uint32_t
+#include <stddef.h>
#include "nvim/types.h" // for char_u
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index b5921eb810..8864301e4c 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.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 <stdlib.h>
#include <stddef.h>
#include <stdbool.h>
@@ -13,12 +16,14 @@
#include "nvim/os/os.h"
#include "nvim/os/time.h"
#include "nvim/vim.h"
+#include "nvim/pos.h"
#include "nvim/ascii.h"
#include "nvim/shada.h"
#include "nvim/message.h"
#include "nvim/globals.h"
#include "nvim/memory.h"
#include "nvim/mark.h"
+#include "nvim/macros.h"
#include "nvim/ops.h"
#include "nvim/garray.h"
#include "nvim/option.h"
@@ -27,11 +32,10 @@
#include "nvim/api/private/helpers.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
-#include "nvim/misc2.h"
#include "nvim/ex_getln.h"
#include "nvim/search.h"
#include "nvim/regexp.h"
-#include "nvim/eval_defs.h"
+#include "nvim/eval/typval.h"
#include "nvim/version.h"
#include "nvim/path.h"
#include "nvim/fileio.h"
@@ -74,17 +78,10 @@ KHASH_SET_INIT_STR(strset)
(vim_rename((char_u *)a, (char_u *)b))
#define mb_strnicmp(a, b, c) \
(mb_strnicmp((char_u *)a, (char_u *)b, c))
-#define has_non_ascii(a) (has_non_ascii((char_u *)a))
-#define string_convert(a, b, c) \
- ((char *)string_convert((vimconv_T *)a, (char_u *)b, c))
-#define path_shorten_fname_if_possible(b) \
- ((char *)path_shorten_fname_if_possible((char_u *)b))
+#define path_try_shorten_fname(b) \
+ ((char *)path_try_shorten_fname((char_u *)b))
#define buflist_new(ffname, sfname, ...) \
(buflist_new((char_u *)ffname, (char_u *)sfname, __VA_ARGS__))
-#define convert_setup(vcp, from, to) \
- (convert_setup(vcp, (char_u *)from, (char_u *)to))
-#define os_getperm(f) \
- (os_getperm((char_u *) f))
#define os_isdir(f) (os_isdir((char_u *) f))
#define regtilde(s, m) ((char *) regtilde((char_u *) s, m))
#define path_tail_with_sep(f) ((char *) path_tail_with_sep((char_u *)f))
@@ -103,6 +100,7 @@ KHASH_SET_INIT_STR(strset)
#define REG_KEY_TYPE "rt"
#define REG_KEY_WIDTH "rw"
#define REG_KEY_CONTENTS "rc"
+#define REG_KEY_UNNAMED "ru"
#define KEY_LNUM "l"
#define KEY_COL "c"
@@ -119,9 +117,10 @@ KHASH_SET_INIT_STR(strset)
// E576: Missing '>'
// E577: Illegal register name
// E886: Can't rename viminfo file to %s!
+// E929: Too many viminfo temp files, like %s!
// Now only six of them are used:
// E137: ShaDa file is not writeable (for pre-open checks)
-// E138: All %s.tmp.X files exist, cannot write ShaDa file!
+// E929: All %s.tmp.X files exist, cannot write ShaDa file!
// RCERR (E576) for critical read errors.
// RNERR (E136) for various errors when renaming.
// RERR (E575) for various errors inside read ShaDa file.
@@ -149,6 +148,9 @@ KHASH_SET_INIT_STR(strset)
/// Common prefix for all ignorable “write†errors
#define WERR "E574: "
+/// Callback function for add_search_pattern
+typedef void (*SearchPatternGetter)(SearchPattern *);
+
/// Flags for shada_read_file and children
typedef enum {
kShaDaWantInfo = 1, ///< Load non-mark information
@@ -285,6 +287,7 @@ typedef struct {
char name;
MotionType type;
char **contents;
+ bool is_unnamed;
size_t contents_size;
size_t width;
dict_T *additional_data;
@@ -374,7 +377,8 @@ KHASH_MAP_INIT_STR(file_marks, FileMarks)
/// Before actually writing most of the data is read to this structure.
typedef struct {
HistoryMergerState hms[HIST_COUNT]; ///< Structures for history merging.
- PossiblyFreedShadaEntry global_marks[NGLOBALMARKS]; ///< All global marks.
+ PossiblyFreedShadaEntry global_marks[NMARKS]; ///< Named global marks.
+ PossiblyFreedShadaEntry numbered_marks[EXTRA_MARKS]; ///< Numbered marks.
PossiblyFreedShadaEntry registers[NUM_SAVED_REGISTERS]; ///< All registers.
PossiblyFreedShadaEntry jumps[JUMPLISTSIZE]; ///< All dumped jumps.
size_t jumps_size; ///< Number of jumps occupied.
@@ -412,8 +416,6 @@ typedef struct sd_read_def {
const char *error; ///< Error message in case of error.
uintmax_t fpos; ///< Current position (amount of bytes read since
///< reader structure initialization). May overflow.
- vimconv_T sd_conv; ///< Structure used for converting encodings of some
- ///< items.
} ShaDaReadDef;
struct sd_write_def;
@@ -434,8 +436,6 @@ typedef struct sd_write_def {
ShaDaWriteCloser close; ///< Close function.
void *cookie; ///< Data describing object written to.
const char *error; ///< Error message in case of error.
- vimconv_T sd_conv; ///< Structure used for converting encodings of some
- ///< items.
} ShaDaWriteDef;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -478,6 +478,7 @@ static const ShadaEntry sd_default_values[] = {
.type = kMTCharWise,
.contents = NULL,
.contents_size = 0,
+ .is_unnamed = false,
.width = 0,
.additional_data = NULL),
DEF_SDE(Variable, global_var,
@@ -598,6 +599,7 @@ static inline void hmll_insert(HMLList *const hmll,
if (hmll_entry == hmll->first) {
hmll_entry = NULL;
}
+ assert(hmll->first != NULL);
hmll_remove(hmll, hmll->first);
}
HMLListEntry *target_entry;
@@ -802,7 +804,7 @@ static int open_shada_file_for_reading(const char *const fname,
return error;
}
- convert_setup(&sd_reader->sd_conv, "utf-8", p_enc);
+ assert(STRCMP(p_enc, "utf-8") == 0);
return 0;
}
@@ -810,7 +812,7 @@ static int open_shada_file_for_reading(const char *const fname,
/// Wrapper for closing file descriptors
static void close_file(void *cookie)
{
- const int error = file_free(cookie);
+ const int error = file_free(cookie, !!p_fs);
if (error != 0) {
emsgf(_(SERR "System error while closing ShaDa file: %s"),
os_strerror(error));
@@ -883,7 +885,7 @@ static int shada_read_file(const char *const file, const int flags)
if (p_verbose > 0) {
verbose_enter();
- smsg(_("Reading ShaDa file \"%s\"%s%s%s"),
+ smsg(_("Reading ShaDa file \"%s\"%s%s%s%s"),
fname,
(flags & kShaDaWantInfo) ? _(" info") : "",
(flags & kShaDaWantMarks) ? _(" marks") : "",
@@ -1182,8 +1184,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
list_T *oldfiles_list = get_vim_var_list(VV_OLDFILES);
const bool force = flags & kShaDaForceit;
const bool get_old_files = (flags & (kShaDaGetOldfiles | kShaDaForceit)
- && (force || oldfiles_list == NULL
- || oldfiles_list->lv_len == 0));
+ && (force || tv_list_len(oldfiles_list) == 0));
const bool want_marks = flags & kShaDaWantMarks;
const unsigned srni_flags = (unsigned) (
(flags & kShaDaWantInfo
@@ -1220,7 +1221,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
khash_t(fnamebufs) fname_bufs = KHASH_EMPTY_TABLE(fnamebufs);
khash_t(strset) oldfiles_set = KHASH_EMPTY_TABLE(strset);
if (get_old_files && (oldfiles_list == NULL || force)) {
- oldfiles_list = list_alloc();
+ oldfiles_list = tv_list_alloc(kListLenUnknown);
set_vim_var_list(VV_OLDFILES, oldfiles_list);
}
ShaDaReadResult srni_ret;
@@ -1282,8 +1283,6 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
if (cur_entry.data.search_pattern.is_last_used) {
set_last_used_pattern(
cur_entry.data.search_pattern.is_substitute_pattern);
- }
- if (cur_entry.data.search_pattern.is_last_used) {
SET_NO_HLSEARCH(!cur_entry.data.search_pattern.highlighted);
}
// Do not free shada entry: its allocated memory was saved above.
@@ -1342,7 +1341,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
.y_width = (colnr_T) cur_entry.data.reg.width,
.timestamp = cur_entry.timestamp,
.additional_data = cur_entry.data.reg.additional_data,
- })) {
+ }, cur_entry.data.reg.is_unnamed)) {
shada_free_shada_entry(&cur_entry);
}
// Do not free shada entry: its allocated memory was saved above.
@@ -1402,7 +1401,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
}
case kSDItemBufferList: {
for (size_t i = 0; i < cur_entry.data.buffer_list.size; i++) {
- char *const sfname = path_shorten_fname_if_possible(
+ char *const sfname = path_try_shorten_fname(
cur_entry.data.buffer_list.buffers[i].fname);
buf_T *const buf = buflist_new(
cur_entry.data.buffer_list.buffers[i].fname, sfname, 0,
@@ -1432,8 +1431,8 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
fname = xstrdup(fname);
}
int kh_ret;
- (void) kh_put(strset, &oldfiles_set, fname, &kh_ret);
- list_append_allocated_string(oldfiles_list, fname);
+ (void)kh_put(strset, &oldfiles_set, fname, &kh_ret);
+ tv_list_append_allocated_string(oldfiles_list, fname);
if (!want_marks) {
// Avoid free because this string was already used.
cur_entry.data.filemark.fname = NULL;
@@ -1524,7 +1523,7 @@ static const char *shada_get_default_file(void)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (default_shada_file == NULL) {
- char *shada_dir = stdpaths_user_data_subpath("shada", 0);
+ char *shada_dir = stdpaths_user_data_subpath("shada", 0, false);
default_shada_file = concat_fnames_realloc(shada_dir, "main.shada", true);
}
return default_shada_file;
@@ -1570,13 +1569,17 @@ static char *shada_filename(const char *file)
do { \
const String s_ = (s); \
msgpack_pack_str(spacker, s_.size); \
- msgpack_pack_str_body(spacker, s_.data, s_.size); \
+ if (s_.size) { \
+ msgpack_pack_str_body(spacker, s_.data, s_.size); \
+ } \
} while (0)
#define PACK_BIN(s) \
do { \
const String s_ = (s); \
msgpack_pack_bin(spacker, s_.size); \
- msgpack_pack_bin_body(spacker, s_.data, s_.size); \
+ if (s_.size > 0) { \
+ msgpack_pack_bin_body(spacker, s_.data, s_.size); \
+ } \
} while (0)
/// Write single ShaDa entry
@@ -1599,13 +1602,13 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
#define DUMP_ADDITIONAL_ELEMENTS(src, what) \
do { \
if ((src) != NULL) { \
- for (listitem_T *li = (src)->lv_first; li != NULL; li = li->li_next) { \
- if (encode_vim_to_msgpack(spacker, &li->li_tv, \
+ TV_LIST_ITER((src), li, { \
+ if (encode_vim_to_msgpack(spacker, TV_LIST_ITEM_TV(li), \
_("additional elements of ShaDa " what)) \
== FAIL) { \
goto shada_pack_entry_error; \
} \
- } \
+ }); \
} \
} while (0)
#define DUMP_ADDITIONAL_DATA(src, what) \
@@ -1616,10 +1619,10 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
for (const hashitem_T *hi= d->dv_hashtab.ht_array; todo; hi++) { \
if (!HASHITEM_EMPTY(hi)) { \
todo--; \
- dictitem_T *const di = HI2DI(hi); \
- const size_t key_len = strlen((const char *) hi->hi_key); \
+ dictitem_T *const di = TV_DICT_HI2DI(hi); \
+ const size_t key_len = strlen((const char *)hi->hi_key); \
msgpack_pack_str(spacker, key_len); \
- msgpack_pack_str_body(spacker, (const char *) hi->hi_key, key_len); \
+ msgpack_pack_str_body(spacker, (const char *)hi->hi_key, key_len); \
if (encode_vim_to_msgpack(spacker, &di->di_tv, \
_("additional data of ShaDa " what)) \
== FAIL) { \
@@ -1647,25 +1650,21 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
case kSDItemHistoryEntry: {
const bool is_hist_search =
entry.data.history_item.histtype == HIST_SEARCH;
- const size_t arr_size = 2 + (size_t) is_hist_search + (size_t) (
- entry.data.history_item.additional_elements == NULL
- ? 0
- : entry.data.history_item.additional_elements->lv_len);
+ const size_t arr_size = 2 + (size_t)is_hist_search + (size_t)(
+ tv_list_len(entry.data.history_item.additional_elements));
msgpack_pack_array(spacker, arr_size);
msgpack_pack_uint8(spacker, entry.data.history_item.histtype);
PACK_BIN(cstr_as_string(entry.data.history_item.string));
if (is_hist_search) {
- msgpack_pack_uint8(spacker, (uint8_t) entry.data.history_item.sep);
+ msgpack_pack_uint8(spacker, (uint8_t)entry.data.history_item.sep);
}
DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements,
"history entry item");
break;
}
case kSDItemVariable: {
- const size_t arr_size = 2 + (size_t) (
- entry.data.global_var.additional_elements == NULL
- ? 0
- : entry.data.global_var.additional_elements->lv_len);
+ const size_t arr_size = 2 + (size_t)(
+ tv_list_len(entry.data.global_var.additional_elements));
msgpack_pack_array(spacker, arr_size);
const String varname = cstr_as_string(entry.data.global_var.name);
PACK_BIN(varname);
@@ -1684,10 +1683,8 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
break;
}
case kSDItemSubString: {
- const size_t arr_size = 1 + (size_t) (
- entry.data.sub_string.additional_elements == NULL
- ? 0
- : entry.data.sub_string.additional_elements->lv_len);
+ const size_t arr_size = 1 + (size_t)(
+ tv_list_len(entry.data.sub_string.additional_elements));
msgpack_pack_array(spacker, arr_size);
PACK_BIN(cstr_as_string(entry.data.sub_string.sub));
DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements,
@@ -1783,6 +1780,7 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
2 // Register contents and name
+ ONE_IF_NOT_DEFAULT(entry, reg.type)
+ ONE_IF_NOT_DEFAULT(entry, reg.width)
+ + ONE_IF_NOT_DEFAULT(entry, reg.is_unnamed)
// Additional entries, if any:
+ (size_t) (entry.data.reg.additional_data == NULL
? 0
@@ -1803,6 +1801,14 @@ static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer,
PACK_STATIC_STR(REG_KEY_WIDTH);
msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width);
}
+ if (!CHECK_DEFAULT(entry, reg.is_unnamed)) {
+ PACK_STATIC_STR(REG_KEY_UNNAMED);
+ if (entry.data.reg.is_unnamed) {
+ msgpack_pack_true(spacker);
+ } else {
+ msgpack_pack_false(spacker);
+ }
+ }
DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item");
break;
}
@@ -1894,127 +1900,24 @@ shada_pack_entry_error:
}
#undef PACK_STRING
-/// Write single ShaDa entry, converting it if needed
+/// Write single ShaDa entry and free it afterwards
///
-/// @warning Frees entry after packing.
+/// Will not free if entry could not be freed.
///
/// @param[in] packer Packer used to write entry.
-/// @param[in] sd_conv Conversion definitions.
-/// @param[in] entry Entry written. If entry.can_free_entry is false then
-/// it assumes that entry was not converted, otherwise it
-/// is assumed that entry was already converted.
+/// @param[in] entry Entry written.
/// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no
/// restrictions.
-static ShaDaWriteResult shada_pack_encoded_entry(msgpack_packer *const packer,
- const vimconv_T *const sd_conv,
- PossiblyFreedShadaEntry entry,
- const size_t max_kbyte)
- FUNC_ATTR_NONNULL_ALL
+static inline ShaDaWriteResult shada_pack_pfreed_entry(
+ msgpack_packer *const packer, PossiblyFreedShadaEntry entry,
+ const size_t max_kbyte)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
{
ShaDaWriteResult ret = kSDWriteSuccessfull;
+ ret = shada_pack_entry(packer, entry.data, max_kbyte);
if (entry.can_free_entry) {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
shada_free_shada_entry(&entry.data);
- return ret;
}
-#define RUN_WITH_CONVERTED_STRING(cstr, code) \
- do { \
- bool did_convert = false; \
- if (sd_conv->vc_type != CONV_NONE && has_non_ascii((cstr))) { \
- char *const converted_string = string_convert(sd_conv, (cstr), NULL); \
- if (converted_string != NULL) { \
- (cstr) = converted_string; \
- did_convert = true; \
- } \
- } \
- code \
- if (did_convert) { \
- xfree((cstr)); \
- } \
- } while (0)
- switch (entry.data.type) {
- case kSDItemUnknown:
- case kSDItemMissing: {
- assert(false);
- }
- case kSDItemSearchPattern: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.search_pattern.pat, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemHistoryEntry: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.history_item.string, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemSubString: {
- RUN_WITH_CONVERTED_STRING(entry.data.data.sub_string.sub, {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- });
- break;
- }
- case kSDItemVariable: {
- if (sd_conv->vc_type != CONV_NONE) {
- typval_T tgttv;
- var_item_copy(sd_conv, &entry.data.data.global_var.value, &tgttv,
- true, 0);
- clear_tv(&entry.data.data.global_var.value);
- entry.data.data.global_var.value = tgttv;
- }
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- break;
- }
- case kSDItemRegister: {
- bool did_convert = false;
- if (sd_conv->vc_type != CONV_NONE) {
- size_t first_non_ascii = 0;
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- if (has_non_ascii(entry.data.data.reg.contents[i])) {
- first_non_ascii = i;
- did_convert = true;
- break;
- }
- }
- if (did_convert) {
- entry.data.data.reg.contents =
- xmemdup(entry.data.data.reg.contents,
- (entry.data.data.reg.contents_size
- * sizeof(entry.data.data.reg.contents)));
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- if (i >= first_non_ascii) {
- entry.data.data.reg.contents[i] = get_converted_string(
- sd_conv,
- entry.data.data.reg.contents[i],
- strlen(entry.data.data.reg.contents[i]));
- } else {
- entry.data.data.reg.contents[i] =
- xstrdup(entry.data.data.reg.contents[i]);
- }
- }
- }
- }
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- if (did_convert) {
- for (size_t i = 0; i < entry.data.data.reg.contents_size; i++) {
- xfree(entry.data.data.reg.contents[i]);
- }
- xfree(entry.data.data.reg.contents);
- }
- break;
- }
- case kSDItemHeader:
- case kSDItemGlobalMark:
- case kSDItemJump:
- case kSDItemBufferList:
- case kSDItemLocalMark:
- case kSDItemChange: {
- ret = shada_pack_entry(packer, entry.data, max_kbyte);
- break;
- }
- }
-#undef RUN_WITH_CONVERTED_STRING
return ret;
}
@@ -2121,6 +2024,113 @@ shada_parse_msgpack_extra_bytes:
return ret;
}
+/// Format shada entry for debugging purposes
+///
+/// @param[in] entry ShaDa entry to format.
+///
+/// @return string representing ShaDa entry in a static buffer.
+static const char *shada_format_entry(const ShadaEntry entry)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_UNUSED FUNC_ATTR_NONNULL_RET
+{
+ static char ret[1024];
+ ret[0] = 0;
+ vim_snprintf(S_LEN(ret), "%s", "[ ] ts=%" PRIu64 " ");
+ // ^ Space for `can_free_entry`
+ switch (entry.type) {
+ case kSDItemMissing: {
+ vim_snprintf_add(S_LEN(ret), "Missing");
+ break;
+ }
+ case kSDItemHeader: {
+ vim_snprintf_add(S_LEN(ret), "Header { TODO }");
+ break;
+ }
+ case kSDItemBufferList: {
+ vim_snprintf_add(S_LEN(ret), "BufferList { TODO }");
+ break;
+ }
+ case kSDItemUnknown: {
+ vim_snprintf_add(S_LEN(ret), "Unknown { TODO }");
+ break;
+ }
+ case kSDItemSearchPattern: {
+ vim_snprintf_add(S_LEN(ret), "SearchPattern { TODO }");
+ break;
+ }
+ case kSDItemSubString: {
+ vim_snprintf_add(S_LEN(ret), "SubString { TODO }");
+ break;
+ }
+ case kSDItemHistoryEntry: {
+ vim_snprintf_add(S_LEN(ret), "HistoryEntry { TODO }");
+ break;
+ }
+ case kSDItemRegister: {
+ vim_snprintf_add(S_LEN(ret), "Register { TODO }");
+ break;
+ }
+ case kSDItemVariable: {
+ vim_snprintf_add(S_LEN(ret), "Variable { TODO }");
+ break;
+ }
+#define FORMAT_MARK_ENTRY(entry_name, name_fmt, name_fmt_arg) \
+ do { \
+ typval_T ad_tv = { \
+ .v_type = VAR_DICT, \
+ .vval.v_dict = entry.data.filemark.additional_data \
+ }; \
+ size_t ad_len; \
+ char *const ad = encode_tv2string(&ad_tv, &ad_len); \
+ vim_snprintf_add( \
+ S_LEN(ret), \
+ entry_name " {" name_fmt " file=[%zu]\"%.512s\", " \
+ "pos={l=%" PRIdLINENR ",c=%" PRIdCOLNR ",a=%" PRIdCOLNR "}, " \
+ "ad={%p:[%zu]%.64s} }", \
+ name_fmt_arg, \
+ strlen(entry.data.filemark.fname), \
+ entry.data.filemark.fname, \
+ entry.data.filemark.mark.lnum, \
+ entry.data.filemark.mark.col, \
+ entry.data.filemark.mark.coladd, \
+ (void *)entry.data.filemark.additional_data, \
+ ad_len, \
+ ad); \
+ } while (0)
+ case kSDItemGlobalMark: {
+ FORMAT_MARK_ENTRY("GlobalMark", " name='%c',", entry.data.filemark.name);
+ break;
+ }
+ case kSDItemChange: {
+ FORMAT_MARK_ENTRY("Change", "%s", "");
+ break;
+ }
+ case kSDItemLocalMark: {
+ FORMAT_MARK_ENTRY("LocalMark", " name='%c',", entry.data.filemark.name);
+ break;
+ }
+ case kSDItemJump: {
+ FORMAT_MARK_ENTRY("Jump", "%s", "");
+ break;
+ }
+#undef FORMAT_MARK_ENTRY
+ }
+ return ret;
+}
+
+/// Format possibly freed shada entry for debugging purposes
+///
+/// @param[in] entry ShaDa entry to format.
+///
+/// @return string representing ShaDa entry in a static buffer.
+static const char *shada_format_pfreed_entry(
+ const PossiblyFreedShadaEntry pfs_entry)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_UNUSED FUNC_ATTR_NONNULL_RET
+{
+ char *ret = (char *)shada_format_entry(pfs_entry.data);
+ ret[1] = (pfs_entry.can_free_entry ? 'T' : 'F');
+ return ret;
+}
+
/// Read and merge in ShaDa file, used when writing
///
/// @param[in] sd_reader Structure containing file reader definition.
@@ -2151,7 +2161,7 @@ static inline ShaDaWriteResult shada_read_when_writing(
}
case kSDReadStatusNotShaDa: {
ret = kSDWriteReadNotShada;
- // fallthrough
+ FALLTHROUGH;
}
case kSDReadStatusReadError: {
return ret;
@@ -2172,9 +2182,12 @@ static inline ShaDaWriteResult shada_read_when_writing(
shada_free_shada_entry(&wms_entry->data); \
} \
} \
- wms_entry->can_free_entry = true; \
- wms_entry->data = (entry); \
+ *wms_entry = pfs_entry; \
} while (0)
+ const PossiblyFreedShadaEntry pfs_entry = {
+ .can_free_entry = true,
+ .data = entry,
+ };
switch (entry.type) {
case kSDItemMissing: {
break;
@@ -2226,13 +2239,49 @@ static inline ShaDaWriteResult shada_read_when_writing(
break;
}
case kSDItemGlobalMark: {
- const int idx = mark_global_index(entry.data.filemark.name);
- if (idx < 0) {
- ret = shada_pack_entry(packer, entry, 0);
- shada_free_shada_entry(&entry);
- break;
+ if (ascii_isdigit(entry.data.filemark.name)) {
+ bool processed_mark = false;
+ // Completely ignore numbered mark names, make a list sorted by
+ // timestamp.
+ for (size_t i = ARRAY_SIZE(wms->numbered_marks); i > 0; i--) {
+ ShadaEntry wms_entry = wms->numbered_marks[i - 1].data;
+ if (wms_entry.type != kSDItemGlobalMark) {
+ continue;
+ }
+ // Ignore duplicates.
+ if (wms_entry.timestamp == entry.timestamp
+ && (wms_entry.data.filemark.additional_data == NULL
+ && entry.data.filemark.additional_data == NULL)
+ && marks_equal(wms_entry.data.filemark.mark,
+ entry.data.filemark.mark)
+ && strcmp(wms_entry.data.filemark.fname,
+ entry.data.filemark.fname) == 0) {
+ shada_free_shada_entry(&entry);
+ processed_mark = true;
+ break;
+ }
+ if (wms_entry.timestamp >= entry.timestamp) {
+ processed_mark = true;
+ if (i < ARRAY_SIZE(wms->numbered_marks)) {
+ replace_numbered_mark(wms, i, pfs_entry);
+ } else {
+ shada_free_shada_entry(&entry);
+ }
+ break;
+ }
+ }
+ if (!processed_mark) {
+ replace_numbered_mark(wms, 0, pfs_entry);
+ }
+ } else {
+ const int idx = mark_global_index(entry.data.filemark.name);
+ if (idx < 0) {
+ ret = shada_pack_entry(packer, entry, 0);
+ shada_free_shada_entry(&entry);
+ break;
+ }
+ COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry);
}
- COMPARE_WITH_ENTRY(&wms->global_marks[idx], entry);
break;
}
case kSDItemChange:
@@ -2276,8 +2325,7 @@ static inline ShaDaWriteResult shada_read_when_writing(
shada_free_shada_entry(&wms_entry->data);
}
}
- wms_entry->can_free_entry = true;
- wms_entry->data = entry;
+ *wms_entry = pfs_entry;
}
} else {
#define FREE_POSSIBLY_FREED_SHADA_ENTRY(entry) \
@@ -2317,6 +2365,194 @@ static inline ShaDaWriteResult shada_read_when_writing(
return ret;
}
+/// Check whether buffer should be ignored
+///
+/// @param[in] buf buf_T* to check.
+/// @param[in] removable_bufs Cache of buffers ignored due to their location.
+///
+/// @return true or false.
+static inline bool ignore_buf(const buf_T *const buf,
+ khash_t(bufset) *const removable_bufs)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
+{
+ return (buf->b_ffname == NULL || !buf->b_p_bl || bt_quickfix(buf) \
+ || in_bufset(removable_bufs, buf));
+}
+
+/// Get list of buffers to write to the shada file
+///
+/// @param[in] removable_bufs Buffers which are ignored
+///
+/// @return ShadaEntry List of buffers to save, kSDItemBufferList entry.
+static inline ShadaEntry shada_get_buflist(
+ khash_t(bufset) *const removable_bufs)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
+{
+ int max_bufs = get_shada_parameter('%');
+ size_t buf_count = 0;
+ FOR_ALL_BUFFERS(buf) {
+ if (!ignore_buf(buf, removable_bufs)
+ && (max_bufs < 0 || buf_count < (size_t)max_bufs)) {
+ buf_count++;
+ }
+ }
+
+ ShadaEntry buflist_entry = (ShadaEntry) {
+ .type = kSDItemBufferList,
+ .timestamp = os_time(),
+ .data = {
+ .buffer_list = {
+ .size = buf_count,
+ .buffers = xmalloc(buf_count
+ * sizeof(*buflist_entry.data.buffer_list.buffers)),
+ },
+ },
+ };
+ size_t i = 0;
+ FOR_ALL_BUFFERS(buf) {
+ if (ignore_buf(buf, removable_bufs)) {
+ continue;
+ }
+ if (i >= buf_count) {
+ break;
+ }
+ buflist_entry.data.buffer_list.buffers[i] = (struct buffer_list_buffer) {
+ .pos = buf->b_last_cursor.mark,
+ .fname = (char *)buf->b_ffname,
+ .additional_data = buf->additional_data,
+ };
+ i++;
+ }
+
+ return buflist_entry;
+}
+
+/// Save search pattern to PossiblyFreedShadaEntry
+///
+/// @param[out] ret_pse Location where result will be saved.
+/// @param[in] get_pattern Function used to get pattern.
+/// @param[in] is_substitute_pattern True if pattern in question is substitute
+/// pattern. Also controls whether some
+/// fields should be initialized to default
+/// or values from get_pattern.
+/// @param[in] search_last_used Result of search_was_last_used().
+/// @param[in] search_highlighted True if search pattern was highlighted by
+/// &hlsearch and this information should be
+/// saved.
+static inline void add_search_pattern(PossiblyFreedShadaEntry *const ret_pse,
+ const SearchPatternGetter get_pattern,
+ const bool is_substitute_pattern,
+ const bool search_last_used,
+ const bool search_highlighted)
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ const ShadaEntry defaults = sd_default_values[kSDItemSearchPattern];
+ SearchPattern pat;
+ get_pattern(&pat);
+ if (pat.pat != NULL) {
+ *ret_pse = (PossiblyFreedShadaEntry) {
+ .can_free_entry = false,
+ .data = {
+ .type = kSDItemSearchPattern,
+ .timestamp = pat.timestamp,
+ .data = {
+ .search_pattern = {
+ .magic = pat.magic,
+ .smartcase = !pat.no_scs,
+ .has_line_offset = (is_substitute_pattern
+ ? defaults.data.search_pattern.has_line_offset
+ : pat.off.line),
+ .place_cursor_at_end = (
+ is_substitute_pattern
+ ? defaults.data.search_pattern.place_cursor_at_end
+ : pat.off.end),
+ .offset = (is_substitute_pattern
+ ? defaults.data.search_pattern.offset
+ : pat.off.off),
+ .is_last_used = (is_substitute_pattern ^ search_last_used),
+ .is_substitute_pattern = is_substitute_pattern,
+ .highlighted = ((is_substitute_pattern ^ search_last_used)
+ && search_highlighted),
+ .pat = (char *)pat.pat,
+ .additional_data = pat.additional_data,
+ .search_backward = (!is_substitute_pattern && pat.off.dir == '?'),
+ }
+ }
+ }
+ };
+ }
+}
+
+/// Initialize registers for writing to the ShaDa file
+///
+/// @param[in] wms The WriteMergerState used when writing.
+/// @param[in] max_reg_lines The maximum number of register lines.
+static inline void shada_initialize_registers(WriteMergerState *const wms,
+ int max_reg_lines)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
+{
+ const void *reg_iter = NULL;
+ const bool limit_reg_lines = max_reg_lines >= 0;
+ do {
+ yankreg_T reg;
+ char name = NUL;
+ bool is_unnamed = false;
+ reg_iter = op_register_iter(reg_iter, &name, &reg, &is_unnamed);
+ if (name == NUL) {
+ break;
+ }
+ if (limit_reg_lines && reg.y_size > (size_t)max_reg_lines) {
+ continue;
+ }
+ wms->registers[op_reg_index(name)] = (PossiblyFreedShadaEntry) {
+ .can_free_entry = false,
+ .data = {
+ .type = kSDItemRegister,
+ .timestamp = reg.timestamp,
+ .data = {
+ .reg = {
+ .contents = (char **)reg.y_array,
+ .contents_size = (size_t)reg.y_size,
+ .type = reg.y_type,
+ .width = (size_t)(reg.y_type == kMTBlockWise ? reg.y_width : 0),
+ .additional_data = reg.additional_data,
+ .name = name,
+ .is_unnamed = is_unnamed,
+ }
+ }
+ }
+ };
+ } while (reg_iter != NULL);
+}
+
+/// Replace numbered mark in WriteMergerState
+///
+/// Frees the last mark, moves (including adjusting mark names) marks from idx
+/// to the last-but-one one and saves the new mark at given index.
+///
+/// @param[out] wms Merger state to adjust.
+/// @param[in] idx Index at which new mark should be placed.
+/// @param[in] entry New mark.
+static inline void replace_numbered_mark(WriteMergerState *const wms,
+ const size_t idx,
+ const PossiblyFreedShadaEntry entry)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
+{
+ if (ARRAY_LAST_ENTRY(wms->numbered_marks).can_free_entry) {
+ shada_free_shada_entry(&ARRAY_LAST_ENTRY(wms->numbered_marks).data);
+ }
+ for (size_t i = idx; i < ARRAY_SIZE(wms->numbered_marks) - 1; i++) {
+ if (wms->numbered_marks[i].data.type == kSDItemGlobalMark) {
+ wms->numbered_marks[i].data.data.filemark.name = (char)('0' + (int)i + 1);
+ }
+ }
+ memmove(wms->numbered_marks + idx + 1, wms->numbered_marks + idx,
+ sizeof(wms->numbered_marks[0])
+ * (ARRAY_SIZE(wms->numbered_marks) - 1 - idx));
+ wms->numbered_marks[idx] = entry;
+ wms->numbered_marks[idx].data.data.filemark.name = (char)('0' + (int)idx);
+}
+
/// Write ShaDa file
///
/// @param[in] sd_writer Structure containing file writer definition.
@@ -2343,7 +2579,6 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (max_reg_lines < 0) {
max_reg_lines = get_shada_parameter('"');
}
- const bool limit_reg_lines = max_reg_lines >= 0;
const bool dump_registers = (max_reg_lines != 0);
khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
const size_t max_kbyte = (size_t) max_kbyte_i;
@@ -2423,46 +2658,13 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
// Write buffer list
if (find_shada_parameter('%') != NULL) {
- size_t buf_count = 0;
-#define IGNORE_BUF(buf)\
- (buf->b_ffname == NULL || !buf->b_p_bl || bt_quickfix(buf) \
- || in_bufset(&removable_bufs, buf))
- FOR_ALL_BUFFERS(buf) {
- if (!IGNORE_BUF(buf)) {
- buf_count++;
- }
- }
-
- ShadaEntry buflist_entry = (ShadaEntry) {
- .type = kSDItemBufferList,
- .timestamp = os_time(),
- .data = {
- .buffer_list = {
- .size = buf_count,
- .buffers = xmalloc(buf_count
- * sizeof(*buflist_entry.data.buffer_list.buffers)),
- },
- },
- };
- size_t i = 0;
- FOR_ALL_BUFFERS(buf) {
- if (IGNORE_BUF(buf)) {
- continue;
- }
- buflist_entry.data.buffer_list.buffers[i] = (struct buffer_list_buffer) {
- .pos = buf->b_last_cursor.mark,
- .fname = (char *) buf->b_ffname,
- .additional_data = buf->additional_data,
- };
- i++;
- }
+ ShadaEntry buflist_entry = shada_get_buflist(&removable_bufs);
if (shada_pack_entry(packer, buflist_entry, 0) == kSDWriteFailed) {
xfree(buflist_entry.data.buffer_list.buffers);
ret = kSDWriteFailed;
goto shada_write_exit;
}
xfree(buflist_entry.data.buffer_list.buffers);
-#undef IGNORE_BUF
}
// Write some of the variables
@@ -2477,11 +2679,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
break;
}
typval_T tgttv;
- if (sd_writer->sd_conv.vc_type != CONV_NONE) {
- var_item_copy(&sd_writer->sd_conv, &vartv, &tgttv, true, 0);
- } else {
- copy_tv(&vartv, &tgttv);
- }
+ tv_copy(&vartv, &tgttv);
ShaDaWriteResult spe_ret;
if ((spe_ret = shada_pack_entry(packer, (ShadaEntry) {
.type = kSDItemVariable,
@@ -2494,13 +2692,13 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
}
}, max_kbyte)) == kSDWriteFailed) {
- clear_tv(&vartv);
- clear_tv(&tgttv);
+ tv_clear(&vartv);
+ tv_clear(&tgttv);
ret = kSDWriteFailed;
goto shada_write_exit;
}
- clear_tv(&vartv);
- clear_tv(&tgttv);
+ tv_clear(&vartv);
+ tv_clear(&tgttv);
if (spe_ret == kSDWriteSuccessfull) {
int kh_ret;
(void) kh_put(strset, &wms->dumped_variables, name, &kh_ret);
@@ -2511,45 +2709,14 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
const bool search_highlighted = !(no_hlsearch
|| find_shada_parameter('h') != NULL);
const bool search_last_used = search_was_last_used();
-#define ADD_SEARCH_PAT(func, wms_attr, hlo, pcae, o, is_sub) \
- do { \
- SearchPattern pat; \
- func(&pat); \
- if (pat.pat != NULL) { \
- wms->wms_attr = (PossiblyFreedShadaEntry) { \
- .can_free_entry = false, \
- .data = { \
- .type = kSDItemSearchPattern, \
- .timestamp = pat.timestamp, \
- .data = { \
- .search_pattern = { \
- .magic = pat.magic, \
- .smartcase = !pat.no_scs, \
- .has_line_offset = hlo, \
- .place_cursor_at_end = pcae, \
- .offset = o, \
- .is_last_used = (is_sub ^ search_last_used), \
- .is_substitute_pattern = is_sub, \
- .highlighted = ((is_sub ^ search_last_used) \
- && search_highlighted), \
- .pat = (char *) pat.pat, \
- .additional_data = pat.additional_data, \
- .search_backward = (!is_sub && pat.off.dir == '?'), \
- } \
- } \
- } \
- }; \
- } \
- } while (0)
// Initialize search pattern
- ADD_SEARCH_PAT(get_search_pattern, search_pattern, pat.off.line, \
- pat.off.end, pat.off.off, false);
+ add_search_pattern(&wms->search_pattern, &get_search_pattern, false,
+ search_last_used, search_highlighted);
// Initialize substitute search pattern
- ADD_SEARCH_PAT(get_substitute_pattern, sub_search_pattern, false, false, 0,
- true);
-#undef ADD_SEARCH_PAT
+ add_search_pattern(&wms->sub_search_pattern, &get_substitute_pattern, true,
+ search_last_used, search_highlighted);
// Initialize substitute replacement string
{
@@ -2572,10 +2739,18 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
// Initialize jump list
const void *jump_iter = NULL;
+ setpcmark();
+ cleanup_jumplist();
do {
xfmark_T fm;
- cleanup_jumplist();
jump_iter = mark_jumplist_iter(jump_iter, curwin, &fm);
+
+ if (fm.fmark.mark.lnum == 0) {
+ iemsgf("ShaDa: mark lnum zero (ji:%p, js:%p, len:%i)",
+ (void *)jump_iter, (void *)&curwin->w_jumplist[0],
+ curwin->w_jumplistlen);
+ continue;
+ }
const buf_T *const buf = (fm.fmark.fnum == 0
? NULL
: buflist_findnr(fm.fmark.fnum));
@@ -2610,6 +2785,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
// Initialize global marks
if (dump_global_marks) {
const void *global_mark_iter = NULL;
+ size_t digit_mark_idx = 0;
do {
char name = NUL;
xfmark_T fm;
@@ -2632,7 +2808,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
fname = (const char *) buf->b_ffname;
}
- wms->global_marks[mark_global_index(name)] = (PossiblyFreedShadaEntry) {
+ const PossiblyFreedShadaEntry pf_entry = {
.can_free_entry = false,
.data = {
.type = kSDItemGlobalMark,
@@ -2642,45 +2818,22 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
.mark = fm.fmark.mark,
.name = name,
.additional_data = fm.fmark.additional_data,
- .fname = (char *) fname,
+ .fname = (char *)fname,
}
}
},
};
+ if (ascii_isdigit(name)) {
+ replace_numbered_mark(wms, digit_mark_idx++, pf_entry);
+ } else {
+ wms->global_marks[mark_global_index(name)] = pf_entry;
+ }
} while (global_mark_iter != NULL);
}
// Initialize registers
if (dump_registers) {
- const void *reg_iter = NULL;
- do {
- yankreg_T reg;
- char name = NUL;
- reg_iter = op_register_iter(reg_iter, &name, &reg);
- if (name == NUL) {
- break;
- }
- if (limit_reg_lines && reg.y_size > (size_t)max_reg_lines) {
- continue;
- }
- wms->registers[op_reg_index(name)] = (PossiblyFreedShadaEntry) {
- .can_free_entry = false,
- .data = {
- .type = kSDItemRegister,
- .timestamp = reg.timestamp,
- .data = {
- .reg = {
- .contents = (char **) reg.y_array,
- .contents_size = (size_t) reg.y_size,
- .type = reg.y_type,
- .width = (size_t) (reg.y_type == kMTBlockWise ? reg.y_width : 0),
- .additional_data = reg.additional_data,
- .name = name,
- }
- }
- }
- };
- } while (reg_iter != NULL);
+ shada_initialize_registers(wms, max_reg_lines);
}
// Initialize buffers
@@ -2756,14 +2909,33 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
}
+ // Update numbered marks: '0' should be replaced with the current position,
+ // '9' should be removed and all other marks shifted.
+ if (!ignore_buf(curbuf, &removable_bufs) && curwin->w_cursor.lnum != 0) {
+ replace_numbered_mark(wms, 0, (PossiblyFreedShadaEntry) {
+ .can_free_entry = false,
+ .data = {
+ .type = kSDItemGlobalMark,
+ .timestamp = os_time(),
+ .data = {
+ .filemark = {
+ .mark = curwin->w_cursor,
+ .name = '0',
+ .additional_data = NULL,
+ .fname = (char *)curbuf->b_ffname,
+ }
+ }
+ },
+ });
+ }
+
// Write the rest
#define PACK_WMS_ARRAY(wms_array) \
do { \
for (size_t i_ = 0; i_ < ARRAY_SIZE(wms_array); i_++) { \
if (wms_array[i_].data.type != kSDItemMissing) { \
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, \
- wms_array[i_], \
- max_kbyte) == kSDWriteFailed) { \
+ if (shada_pack_pfreed_entry(packer, wms_array[i_], max_kbyte) \
+ == kSDWriteFailed) { \
ret = kSDWriteFailed; \
goto shada_write_exit; \
} \
@@ -2771,10 +2943,11 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
} \
} while (0)
PACK_WMS_ARRAY(wms->global_marks);
+ PACK_WMS_ARRAY(wms->numbered_marks);
PACK_WMS_ARRAY(wms->registers);
for (size_t i = 0; i < wms->jumps_size; i++) {
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms->jumps[i],
- max_kbyte) == kSDWriteFailed) {
+ if (shada_pack_pfreed_entry(packer, wms->jumps[i], max_kbyte)
+ == kSDWriteFailed) {
ret = kSDWriteFailed;
goto shada_write_exit;
}
@@ -2782,8 +2955,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
#define PACK_WMS_ENTRY(wms_entry) \
do { \
if (wms_entry.data.type != kSDItemMissing) { \
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms_entry, \
- max_kbyte) == kSDWriteFailed) { \
+ if (shada_pack_pfreed_entry(packer, wms_entry, max_kbyte) \
+ == kSDWriteFailed) { \
ret = kSDWriteFailed; \
goto shada_write_exit; \
} \
@@ -2810,9 +2983,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
for (size_t i = 0; i < file_markss_to_dump; i++) {
PACK_WMS_ARRAY(all_file_markss[i]->marks);
for (size_t j = 0; j < all_file_markss[i]->changes_size; j++) {
- if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv,
- all_file_markss[i]->changes[j],
- max_kbyte) == kSDWriteFailed) {
+ if (shada_pack_pfreed_entry(packer, all_file_markss[i]->changes[j],
+ max_kbyte) == kSDWriteFailed) {
ret = kSDWriteFailed;
goto shada_write_exit;
}
@@ -2836,8 +3008,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
if (dump_one_history[i]) {
hms_insert_whole_neovim_history(&wms->hms[i]);
HMS_ITER(&wms->hms[i], cur_entry, {
- if (shada_pack_encoded_entry(
- packer, &sd_writer->sd_conv, (PossiblyFreedShadaEntry) {
+ if (shada_pack_pfreed_entry(
+ packer, (PossiblyFreedShadaEntry) {
.data = cur_entry->data,
.can_free_entry = cur_entry->can_free_entry,
}, max_kbyte) == kSDWriteFailed) {
@@ -2866,6 +3038,7 @@ shada_write_exit:
return ret;
}
+#undef IGNORE_BUF
#undef PACK_STATIC_STR
/// Write ShaDa file to a given location
@@ -2976,7 +3149,7 @@ shada_write_file_nomerge: {}
if (sd_writer.cookie == NULL) {
xfree(fname);
xfree(tempname);
- if (sd_reader.close != NULL) {
+ if (sd_reader.cookie != NULL) {
sd_reader.close(&sd_reader);
}
return FAIL;
@@ -2988,8 +3161,6 @@ shada_write_file_nomerge: {}
verbose_leave();
}
- convert_setup(&sd_writer.sd_conv, p_enc, "utf-8");
-
const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge
? NULL
: &sd_reader));
@@ -3037,7 +3208,7 @@ shada_write_file_nomerge: {}
} else {
if (sw_ret == kSDWriteReadNotShada) {
EMSG3(_(RNERR "Did not rename %s because %s "
- "does not looks like a ShaDa file"), tempname, fname);
+ "does not look like a ShaDa file"), tempname, fname);
} else {
EMSG3(_(RNERR "Did not rename %s to %s because there were errors "
"during writing it"), tempname, fname);
@@ -3104,17 +3275,17 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
case kSDItemJump:
case kSDItemGlobalMark:
case kSDItemLocalMark: {
- dict_unref(entry->data.filemark.additional_data);
+ tv_dict_unref(entry->data.filemark.additional_data);
xfree(entry->data.filemark.fname);
break;
}
case kSDItemSearchPattern: {
- dict_unref(entry->data.search_pattern.additional_data);
+ tv_dict_unref(entry->data.search_pattern.additional_data);
xfree(entry->data.search_pattern.pat);
break;
}
case kSDItemRegister: {
- dict_unref(entry->data.reg.additional_data);
+ tv_dict_unref(entry->data.reg.additional_data);
for (size_t i = 0; i < entry->data.reg.contents_size; i++) {
xfree(entry->data.reg.contents[i]);
}
@@ -3122,25 +3293,25 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
break;
}
case kSDItemHistoryEntry: {
- list_unref(entry->data.history_item.additional_elements);
+ tv_list_unref(entry->data.history_item.additional_elements);
xfree(entry->data.history_item.string);
break;
}
case kSDItemVariable: {
- list_unref(entry->data.global_var.additional_elements);
+ tv_list_unref(entry->data.global_var.additional_elements);
xfree(entry->data.global_var.name);
- clear_tv(&entry->data.global_var.value);
+ tv_clear(&entry->data.global_var.value);
break;
}
case kSDItemSubString: {
- list_unref(entry->data.sub_string.additional_elements);
+ tv_list_unref(entry->data.sub_string.additional_elements);
xfree(entry->data.sub_string.sub);
break;
}
case kSDItemBufferList: {
for (size_t i = 0; i < entry->data.buffer_list.size; i++) {
xfree(entry->data.buffer_list.buffers[i].fname);
- dict_unref(entry->data.buffer_list.buffers[i].additional_data);
+ tv_dict_unref(entry->data.buffer_list.buffers[i].additional_data);
}
xfree(entry->data.buffer_list.buffers);
break;
@@ -3277,29 +3448,6 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
return kSDReadStatusSuccess;
}
-/// Convert or copy and return a string
-///
-/// @param[in] sd_conv Conversion definition.
-/// @param[in] str String to convert.
-/// @param[in] len String length.
-///
-/// @return [allocated] converted string or copy of the original string.
-static inline char *get_converted_string(const vimconv_T *const sd_conv,
- const char *const str,
- const size_t len)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (!has_non_ascii_len(str, len)) {
- return xmemdupz(str, len);
- }
- size_t new_len = len;
- char *const new_str = string_convert(sd_conv, str, &new_len);
- if (new_str == NULL) {
- return xmemdupz(str, len);
- }
- return new_str;
-}
-
#define READERR(entry_name, error_desc) \
RERR "Error while reading ShaDa file: " \
entry_name " entry at position %" PRIu64 " " \
@@ -3328,59 +3476,58 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
} \
tgt = proc(obj.via.attr); \
} while (0)
-#define CHECK_KEY_IS_STR(entry_name) \
- if (unpacked.data.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR) { \
+#define CHECK_KEY_IS_STR(un, entry_name) \
+ if (un.data.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR) { \
emsgf(_(READERR(entry_name, "has key which is not a string")), \
initial_fpos); \
CLEAR_GA_AND_ERROR_OUT(ad_ga); \
- } else if (unpacked.data.via.map.ptr[i].key.via.str.size == 0) { \
+ } else if (un.data.via.map.ptr[i].key.via.str.size == 0) { \
emsgf(_(READERR(entry_name, "has empty key")), initial_fpos); \
CLEAR_GA_AND_ERROR_OUT(ad_ga); \
}
-#define CHECKED_KEY(entry_name, name, error_desc, tgt, condition, attr, proc) \
+#define CHECKED_KEY(un, entry_name, name, error_desc, tgt, condition, attr, \
+ proc) \
else if (CHECK_KEY( /* NOLINT(readability/braces) */ \
- unpacked.data.via.map.ptr[i].key, name)) { \
+ un.data.via.map.ptr[i].key, name)) { \
CHECKED_ENTRY( \
condition, "has " name " key value " error_desc, \
- entry_name, unpacked.data.via.map.ptr[i].val, \
+ entry_name, un.data.via.map.ptr[i].val, \
tgt, attr, proc); \
}
-#define TYPED_KEY(entry_name, name, type_name, tgt, objtype, attr, proc) \
+#define TYPED_KEY(un, entry_name, name, type_name, tgt, objtype, attr, proc) \
CHECKED_KEY( \
- entry_name, name, "which is not " type_name, tgt, \
- unpacked.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \
+ un, entry_name, name, "which is not " type_name, tgt, \
+ un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \
attr, proc)
-#define BOOLEAN_KEY(entry_name, name, tgt) \
- TYPED_KEY(entry_name, name, "a boolean", tgt, BOOLEAN, boolean, ID)
-#define STRING_KEY(entry_name, name, tgt) \
- TYPED_KEY(entry_name, name, "a binary", tgt, BIN, bin, BINDUP)
-#define CONVERTED_STRING_KEY(entry_name, name, tgt) \
- TYPED_KEY(entry_name, name, "a binary", tgt, BIN, bin, BIN_CONVERTED)
-#define INT_KEY(entry_name, name, tgt, proc) \
+#define BOOLEAN_KEY(un, entry_name, name, tgt) \
+ TYPED_KEY(un, entry_name, name, "a boolean", tgt, BOOLEAN, boolean, ID)
+#define STRING_KEY(un, entry_name, name, tgt) \
+ TYPED_KEY(un, entry_name, name, "a binary", tgt, BIN, bin, BINDUP)
+#define CONVERTED_STRING_KEY(un, entry_name, name, tgt) \
+ TYPED_KEY(un, entry_name, name, "a binary", tgt, BIN, bin, \
+ BIN_CONVERTED)
+#define INT_KEY(un, entry_name, name, tgt, proc) \
CHECKED_KEY( \
- entry_name, name, "which is not an integer", tgt, \
- ((unpacked.data.via.map.ptr[i].val.type \
+ un, entry_name, name, "which is not an integer", tgt, \
+ ((un.data.via.map.ptr[i].val.type \
== MSGPACK_OBJECT_POSITIVE_INTEGER) \
- || (unpacked.data.via.map.ptr[i].val.type \
+ || (un.data.via.map.ptr[i].val.type \
== MSGPACK_OBJECT_NEGATIVE_INTEGER)), \
i64, proc)
-#define INTEGER_KEY(entry_name, name, tgt) \
- INT_KEY(entry_name, name, tgt, TOINT)
-#define LONG_KEY(entry_name, name, tgt) \
- INT_KEY(entry_name, name, tgt, TOLONG)
-#define ADDITIONAL_KEY \
+#define INTEGER_KEY(un, entry_name, name, tgt) \
+ INT_KEY(un, entry_name, name, tgt, TOINT)
+#define LONG_KEY(un, entry_name, name, tgt) \
+ INT_KEY(un, entry_name, name, tgt, TOLONG)
+#define ADDITIONAL_KEY(un) \
else { /* NOLINT(readability/braces) */ \
ga_grow(&ad_ga, 1); \
- memcpy(((char *)ad_ga.ga_data) + ((size_t) ad_ga.ga_len \
- * sizeof(*unpacked.data.via.map.ptr)), \
- unpacked.data.via.map.ptr + i, \
- sizeof(*unpacked.data.via.map.ptr)); \
+ memcpy(((char *)ad_ga.ga_data) + ((size_t)ad_ga.ga_len \
+ * sizeof(*un.data.via.map.ptr)), \
+ un.data.via.map.ptr + i, \
+ sizeof(*un.data.via.map.ptr)); \
ad_ga.ga_len++; \
}
-#define CONVERTED(str, len) ( \
- sd_reader->sd_conv.vc_type != CONV_NONE \
- ? get_converted_string(&sd_reader->sd_conv, (str), (len)) \
- : xmemdupz((str), (len)))
+#define CONVERTED(str, len) (xmemdupz((str), (len)))
#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size)
#define SET_ADDITIONAL_DATA(tgt, name) \
do { \
@@ -3401,7 +3548,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
"cannot be converted to a VimL dictionary")), \
initial_fpos); \
ga_clear(&ad_ga); \
- clear_tv(&adtv); \
+ tv_clear(&adtv); \
goto shada_read_next_item_error; \
} \
tgt = adtv.vval.v_dict; \
@@ -3424,7 +3571,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
if (msgpack_to_vim(obj, &aetv) == FAIL) { \
emsgf(_(READERR(name, "cannot be converted to a VimL list")), \
initial_fpos); \
- clear_tv(&aetv); \
+ tv_clear(&aetv); \
goto shada_read_next_item_error; \
} \
assert(aetv.v_type == VAR_LIST); \
@@ -3483,8 +3630,16 @@ shada_read_next_item_start:
return mru_ret;
}
- const size_t length = (size_t) length_u64;
- entry->timestamp = (Timestamp) timestamp_u64;
+ if (length_u64 > PTRDIFF_MAX) {
+ emsgf(_(RCERR "Error while reading ShaDa file: "
+ "there is an item at position %" PRIu64 " "
+ "that is stated to be too long"),
+ initial_fpos);
+ return kSDReadStatusNotShaDa;
+ }
+
+ const size_t length = (size_t)length_u64;
+ entry->timestamp = (Timestamp)timestamp_u64;
if (type_u64 == 0) {
// kSDItemUnknown cannot possibly pass that far because it is -1 and that
@@ -3574,28 +3729,29 @@ shada_read_next_item_start:
garray_T ad_ga;
ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR("search pattern")
- BOOLEAN_KEY("search pattern", SEARCH_KEY_MAGIC,
+ CHECK_KEY_IS_STR(unpacked, "search pattern")
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_MAGIC,
entry->data.search_pattern.magic)
- BOOLEAN_KEY("search pattern", SEARCH_KEY_SMARTCASE,
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_SMARTCASE,
entry->data.search_pattern.smartcase)
- BOOLEAN_KEY("search pattern", SEARCH_KEY_HAS_LINE_OFFSET,
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HAS_LINE_OFFSET,
entry->data.search_pattern.has_line_offset)
- BOOLEAN_KEY("search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END,
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END,
entry->data.search_pattern.place_cursor_at_end)
- BOOLEAN_KEY("search pattern", SEARCH_KEY_IS_LAST_USED,
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_IS_LAST_USED,
entry->data.search_pattern.is_last_used)
- BOOLEAN_KEY("search pattern", SEARCH_KEY_IS_SUBSTITUTE_PATTERN,
+ BOOLEAN_KEY(unpacked, "search pattern",
+ SEARCH_KEY_IS_SUBSTITUTE_PATTERN,
entry->data.search_pattern.is_substitute_pattern)
- BOOLEAN_KEY("search pattern", SEARCH_KEY_HIGHLIGHTED,
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_HIGHLIGHTED,
entry->data.search_pattern.highlighted)
- BOOLEAN_KEY("search pattern", SEARCH_KEY_BACKWARD,
+ BOOLEAN_KEY(unpacked, "search pattern", SEARCH_KEY_BACKWARD,
entry->data.search_pattern.search_backward)
- INTEGER_KEY("search pattern", SEARCH_KEY_OFFSET,
+ INTEGER_KEY(unpacked, "search pattern", SEARCH_KEY_OFFSET,
entry->data.search_pattern.offset)
- CONVERTED_STRING_KEY("search pattern", SEARCH_KEY_PAT,
+ CONVERTED_STRING_KEY(unpacked, "search pattern", SEARCH_KEY_PAT,
entry->data.search_pattern.pat)
- ADDITIONAL_KEY
+ ADDITIONAL_KEY(unpacked)
}
if (entry->data.search_pattern.pat == NULL) {
emsgf(_(READERR("search pattern", "has no pattern")), initial_fpos);
@@ -3616,7 +3772,7 @@ shada_read_next_item_start:
garray_T ad_ga;
ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR("mark")
+ CHECK_KEY_IS_STR(unpacked, "mark")
if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) {
if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) {
emsgf(_(READERR("mark", "has n key which is only valid for "
@@ -3630,10 +3786,10 @@ shada_read_next_item_start:
"mark", unpacked.data.via.map.ptr[i].val,
entry->data.filemark.name, u64, TOCHAR);
}
- LONG_KEY("mark", KEY_LNUM, entry->data.filemark.mark.lnum)
- INTEGER_KEY("mark", KEY_COL, entry->data.filemark.mark.col)
- STRING_KEY("mark", KEY_FILE, entry->data.filemark.fname)
- ADDITIONAL_KEY
+ LONG_KEY(unpacked, "mark", KEY_LNUM, entry->data.filemark.mark.lnum)
+ INTEGER_KEY(unpacked, "mark", KEY_COL, entry->data.filemark.mark.col)
+ STRING_KEY(unpacked, "mark", KEY_FILE, entry->data.filemark.fname)
+ ADDITIONAL_KEY(unpacked)
}
if (entry->data.filemark.fname == NULL) {
emsgf(_(READERR("mark", "is missing file name")), initial_fpos);
@@ -3658,7 +3814,7 @@ shada_read_next_item_start:
garray_T ad_ga;
ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR("register")
+ CHECK_KEY_IS_STR(unpacked, "register")
if (CHECK_KEY(unpacked.data.via.map.ptr[i].key,
REG_KEY_CONTENTS)) {
if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) {
@@ -3676,8 +3832,8 @@ shada_read_next_item_start:
}
const msgpack_object_array arr =
unpacked.data.via.map.ptr[i].val.via.array;
- for (size_t i = 0; i < arr.size; i++) {
- if (arr.ptr[i].type != MSGPACK_OBJECT_BIN) {
+ for (size_t j = 0; j < arr.size; j++) {
+ if (arr.ptr[j].type != MSGPACK_OBJECT_BIN) {
emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " array "
"with non-binary value")), initial_fpos);
CLEAR_GA_AND_ERROR_OUT(ad_ga);
@@ -3685,17 +3841,19 @@ shada_read_next_item_start:
}
entry->data.reg.contents_size = arr.size;
entry->data.reg.contents = xmalloc(arr.size * sizeof(char *));
- for (size_t i = 0; i < arr.size; i++) {
- entry->data.reg.contents[i] = BIN_CONVERTED(arr.ptr[i].via.bin);
+ for (size_t j = 0; j < arr.size; j++) {
+ entry->data.reg.contents[j] = BIN_CONVERTED(arr.ptr[j].via.bin);
}
}
- TYPED_KEY("register", REG_KEY_TYPE, "an unsigned integer",
+ BOOLEAN_KEY(unpacked, "register", REG_KEY_UNNAMED,
+ entry->data.reg.is_unnamed)
+ TYPED_KEY(unpacked, "register", REG_KEY_TYPE, "an unsigned integer",
entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
- TYPED_KEY("register", KEY_NAME_CHAR, "an unsigned integer",
+ TYPED_KEY(unpacked, "register", KEY_NAME_CHAR, "an unsigned integer",
entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR)
- TYPED_KEY("register", REG_KEY_WIDTH, "an unsigned integer",
+ TYPED_KEY(unpacked, "register", REG_KEY_WIDTH, "an unsigned integer",
entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE)
- ADDITIONAL_KEY
+ ADDITIONAL_KEY(unpacked)
}
if (entry->data.reg.contents == NULL) {
emsgf(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")),
@@ -3753,30 +3911,14 @@ shada_read_next_item_start:
(char) unpacked.data.via.array.ptr[2].via.u64;
}
size_t strsize;
- if (sd_reader->sd_conv.vc_type == CONV_NONE
- || !has_non_ascii_len(unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size)) {
-shada_read_next_item_hist_no_conv:
- strsize = (
- unpacked.data.via.array.ptr[1].via.bin.size
- + 1 // Zero byte
- + 1); // Separator character
- entry->data.history_item.string = xmalloc(strsize);
- memcpy(entry->data.history_item.string,
- unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size);
- } else {
- size_t len = unpacked.data.via.array.ptr[1].via.bin.size;
- char *const converted = string_convert(
- &sd_reader->sd_conv, unpacked.data.via.array.ptr[1].via.bin.ptr,
- &len);
- if (converted != NULL) {
- strsize = len + 2;
- entry->data.history_item.string = xrealloc(converted, strsize);
- } else {
- goto shada_read_next_item_hist_no_conv;
- }
- }
+ strsize = (
+ unpacked.data.via.array.ptr[1].via.bin.size
+ + 1 // Zero byte
+ + 1); // Separator character
+ entry->data.history_item.string = xmalloc(strsize);
+ memcpy(entry->data.history_item.string,
+ unpacked.data.via.array.ptr[1].via.bin.ptr,
+ unpacked.data.via.array.ptr[1].via.bin.size);
entry->data.history_item.string[strsize - 2] = 0;
entry->data.history_item.string[strsize - 1] =
entry->data.history_item.sep;
@@ -3809,16 +3951,6 @@ shada_read_next_item_hist_no_conv:
"be converted to the VimL value")), initial_fpos);
goto shada_read_next_item_error;
}
- if (sd_reader->sd_conv.vc_type != CONV_NONE) {
- typval_T tgttv;
- var_item_copy(&sd_reader->sd_conv,
- &entry->data.global_var.value,
- &tgttv,
- true,
- 0);
- clear_tv(&entry->data.global_var.value);
- entry->data.global_var.value = tgttv;
- }
SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
entry->data.global_var.additional_elements,
"variable");
@@ -3863,8 +3995,7 @@ shada_read_next_item_hist_no_conv:
.data = unpacked.data.via.array.ptr[i],
};
{
- msgpack_unpacked unpacked = unpacked_2;
- if (unpacked.data.type != MSGPACK_OBJECT_MAP) {
+ if (unpacked_2.data.type != MSGPACK_OBJECT_MAP) {
emsgf(_(RERR "Error while reading ShaDa file: "
"buffer list at position %" PRIu64 " "
"contains entry that is not a dictionary"),
@@ -3873,21 +4004,23 @@ shada_read_next_item_hist_no_conv:
}
entry->data.buffer_list.buffers[i].pos = default_pos;
garray_T ad_ga;
- ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
+ ga_init(&ad_ga, sizeof(*(unpacked_2.data.via.map.ptr)), 1);
{
+ // XXX: Temporarily reassign `i` because the macros depend on it.
const size_t j = i;
{
- for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR("buffer list entry")
- LONG_KEY("buffer list entry", KEY_LNUM,
+ for (i = 0; i < unpacked_2.data.via.map.size; i++) { // -V535
+ CHECK_KEY_IS_STR(unpacked_2, "buffer list entry")
+ LONG_KEY(unpacked_2, "buffer list entry", KEY_LNUM,
entry->data.buffer_list.buffers[j].pos.lnum)
- INTEGER_KEY("buffer list entry", KEY_COL,
+ INTEGER_KEY(unpacked_2, "buffer list entry", KEY_COL,
entry->data.buffer_list.buffers[j].pos.col)
- STRING_KEY("buffer list entry", KEY_FILE,
+ STRING_KEY(unpacked_2, "buffer list entry", KEY_FILE,
entry->data.buffer_list.buffers[j].fname)
- ADDITIONAL_KEY
+ ADDITIONAL_KEY(unpacked_2)
}
}
+ i = j; // XXX: Restore `i`.
}
if (entry->data.buffer_list.buffers[i].pos.lnum <= 0) {
emsgf(_(RERR "Error while reading ShaDa file: "
diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h
index 7288a48e21..4443fd8a2e 100644
--- a/src/nvim/sign_defs.h
+++ b/src/nvim/sign_defs.h
@@ -1,23 +1,28 @@
#ifndef NVIM_SIGN_DEFS_H
#define NVIM_SIGN_DEFS_H
+#include "nvim/pos.h"
+
// signs: line annotations
typedef struct signlist signlist_T;
struct signlist
{
- int id; /* unique identifier for each placed sign */
- linenr_T lnum; /* line number which has this sign */
- int typenr; /* typenr of sign */
- signlist_T *next; /* next signlist entry */
+ int id; // unique identifier for each placed sign
+ linenr_T lnum; // line number which has this sign
+ int typenr; // typenr of sign
+ signlist_T *next; // next signlist entry
};
-/* type argument for buf_getsigntype() */
-#define SIGN_ANY 0
-#define SIGN_LINEHL 1
-#define SIGN_ICON 2
-#define SIGN_TEXT 3
+// type argument for buf_getsigntype() and sign_get_attr()
+typedef enum {
+ SIGN_ANY,
+ SIGN_LINEHL,
+ SIGN_ICON,
+ SIGN_TEXT,
+ SIGN_NUMHL,
+} SignType;
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 610fb660e7..ff61c2e5de 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -1,5 +1,10 @@
+// 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
+
// spell.c: code for spell checking
//
+// See spellfile.c for the Vim spell file format.
+//
// The spell checking mechanism uses a tree (aka trie). Each node in the tree
// has a list of bytes that can appear (siblings). For each byte there is a
// pointer to the node with the byte that follows in the word (child).
@@ -63,226 +68,6 @@
// compute the maximum word score that can be used.
#define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3)
-// Vim spell file format: <HEADER>
-// <SECTIONS>
-// <LWORDTREE>
-// <KWORDTREE>
-// <PREFIXTREE>
-//
-// <HEADER>: <fileID> <versionnr>
-//
-// <fileID> 8 bytes "VIMspell"
-// <versionnr> 1 byte VIMSPELLVERSION
-//
-//
-// Sections make it possible to add information to the .spl file without
-// making it incompatible with previous versions. There are two kinds of
-// sections:
-// 1. Not essential for correct spell checking. E.g. for making suggestions.
-// These are skipped when not supported.
-// 2. Optional information, but essential for spell checking when present.
-// E.g. conditions for affixes. When this section is present but not
-// supported an error message is given.
-//
-// <SECTIONS>: <section> ... <sectionend>
-//
-// <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
-//
-// <sectionID> 1 byte number from 0 to 254 identifying the section
-//
-// <sectionflags> 1 byte SNF_REQUIRED: this section is required for correct
-// spell checking
-//
-// <sectionlen> 4 bytes length of section contents, MSB first
-//
-// <sectionend> 1 byte SN_END
-//
-//
-// sectionID == SN_INFO: <infotext>
-// <infotext> N bytes free format text with spell file info (version,
-// website, etc)
-//
-// sectionID == SN_REGION: <regionname> ...
-// <regionname> 2 bytes Up to 8 region names: ca, au, etc. Lower case.
-// First <regionname> is region 1.
-//
-// sectionID == SN_CHARFLAGS: <charflagslen> <charflags>
-// <folcharslen> <folchars>
-// <charflagslen> 1 byte Number of bytes in <charflags> (should be 128).
-// <charflags> N bytes List of flags (first one is for character 128):
-// 0x01 word character CF_WORD
-// 0x02 upper-case character CF_UPPER
-// <folcharslen> 2 bytes Number of bytes in <folchars>.
-// <folchars> N bytes Folded characters, first one is for character 128.
-//
-// sectionID == SN_MIDWORD: <midword>
-// <midword> N bytes Characters that are word characters only when used
-// in the middle of a word.
-//
-// sectionID == SN_PREFCOND: <prefcondcnt> <prefcond> ...
-// <prefcondcnt> 2 bytes Number of <prefcond> items following.
-// <prefcond> : <condlen> <condstr>
-// <condlen> 1 byte Length of <condstr>.
-// <condstr> N bytes Condition for the prefix.
-//
-// sectionID == SN_REP: <repcount> <rep> ...
-// <repcount> 2 bytes number of <rep> items, MSB first.
-// <rep> : <repfromlen> <repfrom> <reptolen> <repto>
-// <repfromlen> 1 byte length of <repfrom>
-// <repfrom> N bytes "from" part of replacement
-// <reptolen> 1 byte length of <repto>
-// <repto> N bytes "to" part of replacement
-//
-// sectionID == SN_REPSAL: <repcount> <rep> ...
-// just like SN_REP but for soundfolded words
-//
-// sectionID == SN_SAL: <salflags> <salcount> <sal> ...
-// <salflags> 1 byte flags for soundsalike conversion:
-// SAL_F0LLOWUP
-// SAL_COLLAPSE
-// SAL_REM_ACCENTS
-// <salcount> 2 bytes number of <sal> items following
-// <sal> : <salfromlen> <salfrom> <saltolen> <salto>
-// <salfromlen> 1 byte length of <salfrom>
-// <salfrom> N bytes "from" part of soundsalike
-// <saltolen> 1 byte length of <salto>
-// <salto> N bytes "to" part of soundsalike
-//
-// sectionID == SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
-// <sofofromlen> 2 bytes length of <sofofrom>
-// <sofofrom> N bytes "from" part of soundfold
-// <sofotolen> 2 bytes length of <sofoto>
-// <sofoto> N bytes "to" part of soundfold
-//
-// sectionID == SN_SUGFILE: <timestamp>
-// <timestamp> 8 bytes time in seconds that must match with .sug file
-//
-// sectionID == SN_NOSPLITSUGS: nothing
-//
-// sectionID == SN_NOCOMPOUNDSUGS: nothing
-//
-// sectionID == SN_WORDS: <word> ...
-// <word> N bytes NUL terminated common word
-//
-// sectionID == SN_MAP: <mapstr>
-// <mapstr> N bytes String with sequences of similar characters,
-// separated by slashes.
-//
-// sectionID == SN_COMPOUND: <compmax> <compminlen> <compsylmax> <compoptions>
-// <comppatcount> <comppattern> ... <compflags>
-// <compmax> 1 byte Maximum nr of words in compound word.
-// <compminlen> 1 byte Minimal word length for compounding.
-// <compsylmax> 1 byte Maximum nr of syllables in compound word.
-// <compoptions> 2 bytes COMP_ flags.
-// <comppatcount> 2 bytes number of <comppattern> following
-// <compflags> N bytes Flags from COMPOUNDRULE items, separated by
-// slashes.
-//
-// <comppattern>: <comppatlen> <comppattext>
-// <comppatlen> 1 byte length of <comppattext>
-// <comppattext> N bytes end or begin chars from CHECKCOMPOUNDPATTERN
-//
-// sectionID == SN_NOBREAK: (empty, its presence is what matters)
-//
-// sectionID == SN_SYLLABLE: <syllable>
-// <syllable> N bytes String from SYLLABLE item.
-//
-// <LWORDTREE>: <wordtree>
-//
-// <KWORDTREE>: <wordtree>
-//
-// <PREFIXTREE>: <wordtree>
-//
-//
-// <wordtree>: <nodecount> <nodedata> ...
-//
-// <nodecount> 4 bytes Number of nodes following. MSB first.
-//
-// <nodedata>: <siblingcount> <sibling> ...
-//
-// <siblingcount> 1 byte Number of siblings in this node. The siblings
-// follow in sorted order.
-//
-// <sibling>: <byte> [ <nodeidx> <xbyte>
-// | <flags> [<flags2>] [<region>] [<affixID>]
-// | [<pflags>] <affixID> <prefcondnr> ]
-//
-// <byte> 1 byte Byte value of the sibling. Special cases:
-// BY_NOFLAGS: End of word without flags and for all
-// regions.
-// For PREFIXTREE <affixID> and
-// <prefcondnr> follow.
-// BY_FLAGS: End of word, <flags> follow.
-// For PREFIXTREE <pflags>, <affixID>
-// and <prefcondnr> follow.
-// BY_FLAGS2: End of word, <flags> and <flags2>
-// follow. Not used in PREFIXTREE.
-// BY_INDEX: Child of sibling is shared, <nodeidx>
-// and <xbyte> follow.
-//
-// <nodeidx> 3 bytes Index of child for this sibling, MSB first.
-//
-// <xbyte> 1 byte Byte value of the sibling.
-//
-// <flags> 1 byte Bitmask of:
-// WF_ALLCAP word must have only capitals
-// WF_ONECAP first char of word must be capital
-// WF_KEEPCAP keep-case word
-// WF_FIXCAP keep-case word, all caps not allowed
-// WF_RARE rare word
-// WF_BANNED bad word
-// WF_REGION <region> follows
-// WF_AFX <affixID> follows
-//
-// <flags2> 1 byte Bitmask of:
-// WF_HAS_AFF >> 8 word includes affix
-// WF_NEEDCOMP >> 8 word only valid in compound
-// WF_NOSUGGEST >> 8 word not used for suggestions
-// WF_COMPROOT >> 8 word already a compound
-// WF_NOCOMPBEF >> 8 no compounding before this word
-// WF_NOCOMPAFT >> 8 no compounding after this word
-//
-// <pflags> 1 byte Bitmask of:
-// WFP_RARE rare prefix
-// WFP_NC non-combining prefix
-// WFP_UP letter after prefix made upper case
-//
-// <region> 1 byte Bitmask for regions in which word is valid. When
-// omitted it's valid in all regions.
-// Lowest bit is for region 1.
-//
-// <affixID> 1 byte ID of affix that can be used with this word. In
-// PREFIXTREE used for the required prefix ID.
-//
-// <prefcondnr> 2 bytes Prefix condition number, index in <prefcond> list
-// from HEADER.
-//
-// All text characters are in 'encoding', but stored as single bytes.
-
-// Vim .sug file format: <SUGHEADER>
-// <SUGWORDTREE>
-// <SUGTABLE>
-//
-// <SUGHEADER>: <fileID> <versionnr> <timestamp>
-//
-// <fileID> 6 bytes "VIMsug"
-// <versionnr> 1 byte VIMSUGVERSION
-// <timestamp> 8 bytes timestamp that must match with .spl file
-//
-//
-// <SUGWORDTREE>: <wordtree> (see above, no flags or region used)
-//
-//
-// <SUGTABLE>: <sugwcount> <sugline> ...
-//
-// <sugwcount> 4 bytes number of <sugline> following
-//
-// <sugline>: <sugnr> ... NUL
-//
-// <sugnr>: X bytes word number that results in this soundfolded word,
-// stored as an offset to the previous number in as
-// few bytes as possible, see offset2bytes())
-
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
@@ -292,6 +77,9 @@
#include <stdlib.h>
#include <wctype.h>
+/* for offsetof() */
+#include <stddef.h>
+
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/spell.h"
@@ -307,12 +95,12 @@
#include "nvim/func_attr.h"
#include "nvim/getchar.h"
#include "nvim/hashtab.h"
+#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/garray.h"
#include "nvim/normal.h"
#include "nvim/option.h"
@@ -321,254 +109,18 @@
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/spellfile.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
-#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
-#ifndef UNIX // it's in os/unix_defs.h for Unix
-# include <time.h> // for time_t
-#endif
-
-#define MAXWLEN 254 // Assume max. word len is this many bytes.
- // Some places assume a word length fits in a
- // byte, thus it can't be above 255.
-
-// Type used for indexes in the word tree need to be at least 4 bytes. If int
-// is 8 bytes we could use something smaller, but what?
-typedef int idx_T;
-
-# define SPL_FNAME_TMPL "%s.%s.spl"
-# define SPL_FNAME_ADD ".add."
-# define SPL_FNAME_ASCII ".ascii."
-
-// Flags used for a word. Only the lowest byte can be used, the region byte
-// comes above it.
-#define WF_REGION 0x01 // region byte follows
-#define WF_ONECAP 0x02 // word with one capital (or all capitals)
-#define WF_ALLCAP 0x04 // word must be all capitals
-#define WF_RARE 0x08 // rare word
-#define WF_BANNED 0x10 // bad word
-#define WF_AFX 0x20 // affix ID follows
-#define WF_FIXCAP 0x40 // keep-case word, allcap not allowed
-#define WF_KEEPCAP 0x80 // keep-case word
-
-// for <flags2>, shifted up one byte to be used in wn_flags
-#define WF_HAS_AFF 0x0100 // word includes affix
-#define WF_NEEDCOMP 0x0200 // word only valid in compound
-#define WF_NOSUGGEST 0x0400 // word not to be suggested
-#define WF_COMPROOT 0x0800 // already compounded word, COMPOUNDROOT
-#define WF_NOCOMPBEF 0x1000 // no compounding before this word
-#define WF_NOCOMPAFT 0x2000 // no compounding after this word
-
// only used for su_badflags
#define WF_MIXCAP 0x20 // mix of upper and lower case: macaRONI
#define WF_CAPMASK (WF_ONECAP | WF_ALLCAP | WF_KEEPCAP | WF_FIXCAP)
-// flags for <pflags>
-#define WFP_RARE 0x01 // rare prefix
-#define WFP_NC 0x02 // prefix is not combining
-#define WFP_UP 0x04 // to-upper prefix
-#define WFP_COMPPERMIT 0x08 // prefix with COMPOUNDPERMITFLAG
-#define WFP_COMPFORBID 0x10 // prefix with COMPOUNDFORBIDFLAG
-
-// Flags for postponed prefixes in "sl_pidxs". Must be above affixID (one
-// byte) and prefcondnr (two bytes).
-#define WF_RAREPFX (WFP_RARE << 24) // rare postponed prefix
-#define WF_PFX_NC (WFP_NC << 24) // non-combining postponed prefix
-#define WF_PFX_UP (WFP_UP << 24) // to-upper postponed prefix
-#define WF_PFX_COMPPERMIT (WFP_COMPPERMIT << 24) // postponed prefix with
- // COMPOUNDPERMITFLAG
-#define WF_PFX_COMPFORBID (WFP_COMPFORBID << 24) // postponed prefix with
- // COMPOUNDFORBIDFLAG
-
-
-// flags for <compoptions>
-#define COMP_CHECKDUP 1 // CHECKCOMPOUNDDUP
-#define COMP_CHECKREP 2 // CHECKCOMPOUNDREP
-#define COMP_CHECKCASE 4 // CHECKCOMPOUNDCASE
-#define COMP_CHECKTRIPLE 8 // CHECKCOMPOUNDTRIPLE
-
-// Special byte values for <byte>. Some are only used in the tree for
-// postponed prefixes, some only in the other trees. This is a bit messy...
-#define BY_NOFLAGS 0 // end of word without flags or region; for
- // postponed prefix: no <pflags>
-#define BY_INDEX 1 // child is shared, index follows
-#define BY_FLAGS 2 // end of word, <flags> byte follows; for
- // postponed prefix: <pflags> follows
-#define BY_FLAGS2 3 // end of word, <flags> and <flags2> bytes
- // follow; never used in prefix tree
-#define BY_SPECIAL BY_FLAGS2 // highest special byte value
-
-// Info from "REP", "REPSAL" and "SAL" entries in ".aff" file used in si_rep,
-// si_repsal, sl_rep, and si_sal. Not for sl_sal!
-// One replacement: from "ft_from" to "ft_to".
-typedef struct fromto_S {
- char_u *ft_from;
- char_u *ft_to;
-} fromto_T;
-
-// Info from "SAL" entries in ".aff" file used in sl_sal.
-// The info is split for quick processing by spell_soundfold().
-// Note that "sm_oneof" and "sm_rules" point into sm_lead.
-typedef struct salitem_S {
- char_u *sm_lead; // leading letters
- int sm_leadlen; // length of "sm_lead"
- char_u *sm_oneof; // letters from () or NULL
- char_u *sm_rules; // rules like ^, $, priority
- char_u *sm_to; // replacement.
- int *sm_lead_w; // wide character copy of "sm_lead"
- int *sm_oneof_w; // wide character copy of "sm_oneof"
- int *sm_to_w; // wide character copy of "sm_to"
-} salitem_T;
-
-typedef int salfirst_T;
-
-// Values for SP_*ERROR are negative, positive values are used by
-// read_cnt_string().
-#define SP_TRUNCERROR -1 // spell file truncated error
-#define SP_FORMERROR -2 // format error in spell file
-#define SP_OTHERERROR -3 // other error while reading spell file
-
-// Structure used to store words and other info for one language, loaded from
-// a .spl file.
-// The main access is through the tree in "sl_fbyts/sl_fidxs", storing the
-// case-folded words. "sl_kbyts/sl_kidxs" is for keep-case words.
-//
-// The "byts" array stores the possible bytes in each tree node, preceded by
-// the number of possible bytes, sorted on byte value:
-// <len> <byte1> <byte2> ...
-// The "idxs" array stores the index of the child node corresponding to the
-// byte in "byts".
-// Exception: when the byte is zero, the word may end here and "idxs" holds
-// the flags, region mask and affixID for the word. There may be several
-// zeros in sequence for alternative flag/region/affixID combinations.
-typedef struct slang_S slang_T;
-
-struct slang_S {
- slang_T *sl_next; // next language
- char_u *sl_name; // language name "en", "en.rare", "nl", etc.
- char_u *sl_fname; // name of .spl file
- bool sl_add; // true if it's a .add file.
-
- char_u *sl_fbyts; // case-folded word bytes
- idx_T *sl_fidxs; // case-folded word indexes
- char_u *sl_kbyts; // keep-case word bytes
- idx_T *sl_kidxs; // keep-case word indexes
- char_u *sl_pbyts; // prefix tree word bytes
- idx_T *sl_pidxs; // prefix tree word indexes
-
- char_u *sl_info; // infotext string or NULL
-
- char_u sl_regions[17]; // table with up to 8 region names plus NUL
-
- char_u *sl_midword; // MIDWORD string or NULL
-
- hashtab_T sl_wordcount; // hashtable with word count, wordcount_T
-
- int sl_compmax; // COMPOUNDWORDMAX (default: MAXWLEN)
- int sl_compminlen; // COMPOUNDMIN (default: 0)
- int sl_compsylmax; // COMPOUNDSYLMAX (default: MAXWLEN)
- int sl_compoptions; // COMP_* flags
- garray_T sl_comppat; // CHECKCOMPOUNDPATTERN items
- regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm
- // (NULL when no compounding)
- char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL)
- char_u *sl_compstartflags; // flags for first compound word
- char_u *sl_compallflags; // all flags for compound words
- bool sl_nobreak; // When true: no spaces between words
- char_u *sl_syllable; // SYLLABLE repeatable chars or NULL
- garray_T sl_syl_items; // syllable items
-
- int sl_prefixcnt; // number of items in "sl_prefprog"
- regprog_T **sl_prefprog; // table with regprogs for prefixes
-
- garray_T sl_rep; // list of fromto_T entries from REP lines
- int16_t sl_rep_first[256]; // indexes where byte first appears, -1 if
- // there is none
- garray_T sl_sal; // list of salitem_T entries from SAL lines
- salfirst_T sl_sal_first[256]; // indexes where byte first appears, -1 if
- // there is none
- bool sl_followup; // SAL followup
- bool sl_collapse; // SAL collapse_result
- bool sl_rem_accents; // SAL remove_accents
- bool sl_sofo; // SOFOFROM and SOFOTO instead of SAL items:
- // "sl_sal_first" maps chars, when has_mbyte
- // "sl_sal" is a list of wide char lists.
- garray_T sl_repsal; // list of fromto_T entries from REPSAL lines
- int16_t sl_repsal_first[256]; // sl_rep_first for REPSAL lines
- bool sl_nosplitsugs; // don't suggest splitting a word
- bool sl_nocompoundsugs; // don't suggest compounding
-
- // Info from the .sug file. Loaded on demand.
- time_t sl_sugtime; // timestamp for .sug file
- char_u *sl_sbyts; // soundfolded word bytes
- idx_T *sl_sidxs; // soundfolded word indexes
- buf_T *sl_sugbuf; // buffer with word number table
- bool sl_sugloaded; // true when .sug file was loaded or failed to
- // load
-
- bool sl_has_map; // true, if there is a MAP line
- hashtab_T sl_map_hash; // MAP for multi-byte chars
- int sl_map_array[256]; // MAP for first 256 chars
- hashtab_T sl_sounddone; // table with soundfolded words that have
- // handled, see add_sound_suggest()
-};
-
-// First language that is loaded, start of the linked list of loaded
-// languages.
-static slang_T *first_lang = NULL;
-
-// Flags used in .spl file for soundsalike flags.
-#define SAL_F0LLOWUP 1
-#define SAL_COLLAPSE 2
-#define SAL_REM_ACCENTS 4
-
-// Structure used in "b_langp", filled from 'spelllang'.
-typedef struct langp_S {
- slang_T *lp_slang; // info for this language
- slang_T *lp_sallang; // language used for sound folding or NULL
- slang_T *lp_replang; // language used for REP items or NULL
- int lp_region; // bitmask for region or REGION_ALL
-} langp_T;
-
-#define LANGP_ENTRY(ga, i) (((langp_T *)(ga).ga_data) + (i))
-
-#define REGION_ALL 0xff // word valid in all regions
-
-#define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file
-#define VIMSPELLMAGICL 8
-#define VIMSPELLVERSION 50
-
-#define VIMSUGMAGIC "VIMsug" // string at start of Vim .sug file
-#define VIMSUGMAGICL 6
-#define VIMSUGVERSION 1
-
-// Section IDs. Only renumber them when VIMSPELLVERSION changes!
-#define SN_REGION 0 // <regionname> section
-#define SN_CHARFLAGS 1 // charflags section
-#define SN_MIDWORD 2 // <midword> section
-#define SN_PREFCOND 3 // <prefcond> section
-#define SN_REP 4 // REP items section
-#define SN_SAL 5 // SAL items section
-#define SN_SOFO 6 // soundfolding section
-#define SN_MAP 7 // MAP items section
-#define SN_COMPOUND 8 // compound words section
-#define SN_SYLLABLE 9 // syllable section
-#define SN_NOBREAK 10 // NOBREAK section
-#define SN_SUGFILE 11 // timestamp for .sug file
-#define SN_REPSAL 12 // REPSAL items section
-#define SN_WORDS 13 // common words
-#define SN_NOSPLITSUGS 14 // don't split word for suggestions
-#define SN_INFO 15 // info section
-#define SN_NOCOMPOUNDSUGS 16 // don't compound for suggestions
-#define SN_END 255 // end of sections
-
-#define SNF_REQUIRED 1 // <sectionflags>: required section
-
// Result values. Lower number is accepted over higher one.
#define SP_BANNED -1
#define SP_RARE 0
@@ -576,17 +128,20 @@ typedef struct langp_S {
#define SP_LOCAL 2
#define SP_BAD 3
+// First language that is loaded, start of the linked list of loaded
+// languages.
+slang_T *first_lang = NULL;
+
// file used for "zG" and "zW"
-static char_u *int_wordlist = NULL;
+char_u *int_wordlist = NULL;
typedef struct wordcount_S {
uint16_t wc_count; // nr of times word was seen
char_u wc_word[1]; // word, actually longer
} wordcount_T;
-static wordcount_T dumwc;
-#define WC_KEY_OFF (unsigned)(dumwc.wc_word - (char_u *)&dumwc)
-#define HI2WC(hi) ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF))
+#define WC_KEY_OFF offsetof(wordcount_T, wc_word)
+#define HI2WC(hi) ((wordcount_T *)((hi)->hi_key - WC_KEY_OFF))
#define MAXWORDCOUNT 0xffff
// Information used when looking for suggestions.
@@ -717,65 +272,6 @@ typedef struct matchinf_S {
char_u *mi_end2; // "mi_end" without following word
} matchinf_T;
-// The tables used for recognizing word characters according to spelling.
-// These are only used for the first 256 characters of 'encoding'.
-typedef struct {
- bool st_isw[256]; // flags: is word char
- bool st_isu[256]; // flags: is uppercase char
- char_u st_fold[256]; // chars: folded case
- char_u st_upper[256]; // chars: upper case
-} spelltab_T;
-
-// For finding suggestions: At each node in the tree these states are tried:
-typedef enum {
- STATE_START = 0, // At start of node check for NUL bytes (goodword
- // ends); if badword ends there is a match, otherwise
- // try splitting word.
- STATE_NOPREFIX, // try without prefix
- STATE_SPLITUNDO, // Undo splitting.
- STATE_ENDNUL, // Past NUL bytes at start of the node.
- STATE_PLAIN, // Use each byte of the node.
- STATE_DEL, // Delete a byte from the bad word.
- STATE_INS_PREP, // Prepare for inserting bytes.
- STATE_INS, // Insert a byte in the bad word.
- STATE_SWAP, // Swap two bytes.
- STATE_UNSWAP, // Undo swap two characters.
- STATE_SWAP3, // Swap two characters over three.
- STATE_UNSWAP3, // Undo Swap two characters over three.
- STATE_UNROT3L, // Undo rotate three characters left
- STATE_UNROT3R, // Undo rotate three characters right
- STATE_REP_INI, // Prepare for using REP items.
- STATE_REP, // Use matching REP items from the .aff file.
- STATE_REP_UNDO, // Undo a REP item replacement.
- STATE_FINAL // End of this node.
-} state_T;
-
-// Struct to keep the state at each level in suggest_try_change().
-typedef struct trystate_S {
- state_T ts_state; // state at this level, STATE_
- int ts_score; // score
- idx_T ts_arridx; // index in tree array, start of node
- short ts_curi; // index in list of child nodes
- char_u ts_fidx; // index in fword[], case-folded bad word
- char_u ts_fidxtry; // ts_fidx at which bytes may be changed
- char_u ts_twordlen; // valid length of tword[]
- char_u ts_prefixdepth; // stack depth for end of prefix or
- // PFD_PREFIXTREE or PFD_NOPREFIX
- char_u ts_flags; // TSF_ flags
- char_u ts_tcharlen; // number of bytes in tword character
- char_u ts_tcharidx; // current byte index in tword character
- char_u ts_isdiff; // DIFF_ values
- char_u ts_fcharstart; // index in fword where badword char started
- char_u ts_prewordlen; // length of word in "preword[]"
- char_u ts_splitoff; // index in "tword" after last split
- char_u ts_splitfidx; // "ts_fidx" at word split
- char_u ts_complen; // nr of compound words used
- char_u ts_compsplit; // index for "compflags" where word was spit
- char_u ts_save_badflags; // su_badflags saved here
- char_u ts_delidx; // index in fword for char that was deleted,
- // valid when "ts_flags" has TSF_DIDDEL
-} trystate_T;
-
// Structure used for the cookie argument of do_in_runtimepath().
typedef struct spelload_S {
char_u sl_lang[MAXWLEN + 1]; // language name
@@ -789,200 +285,8 @@ typedef struct syl_item_S {
int sy_len;
} syl_item_T;
-#define MAXLINELEN 500 // Maximum length in bytes of a line in a .aff
- // and .dic file.
-// Main structure to store the contents of a ".aff" file.
-typedef struct afffile_S {
- char_u *af_enc; // "SET", normalized, alloc'ed string or NULL
- int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG
- unsigned af_rare; // RARE ID for rare word
- unsigned af_keepcase; // KEEPCASE ID for keep-case word
- unsigned af_bad; // BAD ID for banned word
- unsigned af_needaffix; // NEEDAFFIX ID
- unsigned af_circumfix; // CIRCUMFIX ID
- unsigned af_needcomp; // NEEDCOMPOUND ID
- unsigned af_comproot; // COMPOUNDROOT ID
- unsigned af_compforbid; // COMPOUNDFORBIDFLAG ID
- unsigned af_comppermit; // COMPOUNDPERMITFLAG ID
- unsigned af_nosuggest; // NOSUGGEST ID
- int af_pfxpostpone; // postpone prefixes without chop string and
- // without flags
- bool af_ignoreextra; // IGNOREEXTRA present
- hashtab_T af_pref; // hashtable for prefixes, affheader_T
- hashtab_T af_suff; // hashtable for suffixes, affheader_T
- hashtab_T af_comp; // hashtable for compound flags, compitem_T
-} afffile_T;
-
-#define AFT_CHAR 0 // flags are one character
-#define AFT_LONG 1 // flags are two characters
-#define AFT_CAPLONG 2 // flags are one or two characters
-#define AFT_NUM 3 // flags are numbers, comma separated
-
-typedef struct affentry_S affentry_T;
-// Affix entry from ".aff" file. Used for prefixes and suffixes.
-struct affentry_S {
- affentry_T *ae_next; // next affix with same name/number
- char_u *ae_chop; // text to chop off basic word (can be NULL)
- char_u *ae_add; // text to add to basic word (can be NULL)
- char_u *ae_flags; // flags on the affix (can be NULL)
- char_u *ae_cond; // condition (NULL for ".")
- regprog_T *ae_prog; // regexp program for ae_cond or NULL
- char ae_compforbid; // COMPOUNDFORBIDFLAG found
- char ae_comppermit; // COMPOUNDPERMITFLAG found
-};
-
-# define AH_KEY_LEN 17 // 2 x 8 bytes + NUL
-
-// Affix header from ".aff" file. Used for af_pref and af_suff.
-typedef struct affheader_S {
- char_u ah_key[AH_KEY_LEN]; // key for hashtab == name of affix
- unsigned ah_flag; // affix name as number, uses "af_flagtype"
- int ah_newID; // prefix ID after renumbering; 0 if not used
- int ah_combine; // suffix may combine with prefix
- int ah_follows; // another affix block should be following
- affentry_T *ah_first; // first affix entry
-} affheader_T;
-
-#define HI2AH(hi) ((affheader_T *)(hi)->hi_key)
-
-// Flag used in compound items.
-typedef struct compitem_S {
- char_u ci_key[AH_KEY_LEN]; // key for hashtab == name of compound
- unsigned ci_flag; // affix name as number, uses "af_flagtype"
- int ci_newID; // affix ID after renumbering.
-} compitem_T;
-
-#define HI2CI(hi) ((compitem_T *)(hi)->hi_key)
-
-// Structure that is used to store the items in the word tree. This avoids
-// the need to keep track of each allocated thing, everything is freed all at
-// once after ":mkspell" is done.
-// Note: "sb_next" must be just before "sb_data" to make sure the alignment of
-// "sb_data" is correct for systems where pointers must be aligned on
-// pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc).
-#define SBLOCKSIZE 16000 // size of sb_data
-typedef struct sblock_S sblock_T;
-struct sblock_S {
- int sb_used; // nr of bytes already in use
- sblock_T *sb_next; // next block in list
- char_u sb_data[1]; // data, actually longer
-};
-
-// A node in the tree.
-typedef struct wordnode_S wordnode_T;
-struct wordnode_S {
- union // shared to save space
- {
- char_u hashkey[6]; // the hash key, only used while compressing
- int index; // index in written nodes (valid after first
- // round)
- } wn_u1;
- union // shared to save space
- {
- wordnode_T *next; // next node with same hash key
- wordnode_T *wnode; // parent node that will write this node
- } wn_u2;
- wordnode_T *wn_child; // child (next byte in word)
- wordnode_T *wn_sibling; // next sibling (alternate byte in word,
- // always sorted)
- int wn_refs; // Nr. of references to this node. Only
- // relevant for first node in a list of
- // siblings, in following siblings it is
- // always one.
- char_u wn_byte; // Byte for this node. NUL for word end
-
- // Info for when "wn_byte" is NUL.
- // In PREFIXTREE "wn_region" is used for the prefcondnr.
- // In the soundfolded word tree "wn_flags" has the MSW of the wordnr and
- // "wn_region" the LSW of the wordnr.
- char_u wn_affixID; // supported/required prefix ID or 0
- uint16_t wn_flags; // WF_ flags
- short wn_region; // region mask
-
-#ifdef SPELL_PRINTTREE
- int wn_nr; // sequence nr for printing
-#endif
-};
-
-#define WN_MASK 0xffff // mask relevant bits of "wn_flags"
-
-#define HI2WN(hi) (wordnode_T *)((hi)->hi_key)
-
-// Info used while reading the spell files.
-typedef struct spellinfo_S {
- wordnode_T *si_foldroot; // tree with case-folded words
- long si_foldwcount; // nr of words in si_foldroot
-
- wordnode_T *si_keeproot; // tree with keep-case words
- long si_keepwcount; // nr of words in si_keeproot
-
- wordnode_T *si_prefroot; // tree with postponed prefixes
-
- long si_sugtree; // creating the soundfolding trie
-
- sblock_T *si_blocks; // memory blocks used
- long si_blocks_cnt; // memory blocks allocated
- int si_did_emsg; // TRUE when ran out of memory
-
- long si_compress_cnt; // words to add before lowering
- // compression limit
- wordnode_T *si_first_free; // List of nodes that have been freed during
- // compression, linked by "wn_child" field.
- long si_free_count; // number of nodes in si_first_free
-#ifdef SPELL_PRINTTREE
- int si_wordnode_nr; // sequence nr for nodes
-#endif
- buf_T *si_spellbuf; // buffer used to store soundfold word table
-
- int si_ascii; // handling only ASCII words
- int si_add; // addition file
- int si_clear_chartab; // when TRUE clear char tables
- int si_region; // region mask
- vimconv_T si_conv; // for conversion to 'encoding'
- int si_memtot; // runtime memory used
- int si_verbose; // verbose messages
- int si_msg_count; // number of words added since last message
- char_u *si_info; // info text chars or NULL
- int si_region_count; // number of regions supported (1 when there
- // are no regions)
- char_u si_region_name[17]; // region names; used only if
- // si_region_count > 1)
-
- garray_T si_rep; // list of fromto_T entries from REP lines
- garray_T si_repsal; // list of fromto_T entries from REPSAL lines
- garray_T si_sal; // list of fromto_T entries from SAL lines
- char_u *si_sofofr; // SOFOFROM text
- char_u *si_sofoto; // SOFOTO text
- int si_nosugfile; // NOSUGFILE item found
- int si_nosplitsugs; // NOSPLITSUGS item found
- int si_nocompoundsugs; // NOCOMPOUNDSUGS item found
- int si_followup; // soundsalike: ?
- int si_collapse; // soundsalike: ?
- hashtab_T si_commonwords; // hashtable for common words
- time_t si_sugtime; // timestamp for .sug file
- int si_rem_accents; // soundsalike: remove accents
- garray_T si_map; // MAP info concatenated
- char_u *si_midword; // MIDWORD chars or NULL
- int si_compmax; // max nr of words for compounding
- int si_compminlen; // minimal length for compounding
- int si_compsylmax; // max nr of syllables for compounding
- int si_compoptions; // COMP_ flags
- garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as
- // a string
- char_u *si_compflags; // flags used for compounding
- char_u si_nobreak; // NOBREAK
- char_u *si_syllable; // syllable string
- garray_T si_prefcond; // table with conditions for postponed
- // prefixes, each stored as a string
- int si_newprefID; // current value for ah_newID
- int si_newcompID; // current value for compound ID
-} spellinfo_T;
-
-static spelltab_T spelltab;
-static int did_set_spelltab;
-
-#define CF_WORD 0x01
-#define CF_UPPER 0x02
+spelltab_T spelltab;
+int did_set_spelltab;
// structure used to store soundfolded words that add_sound_suggest() has
// handled already.
@@ -1024,34 +328,7 @@ typedef struct {
#define FIND_COMPOUND 3 // find case-folded compound word
#define FIND_KEEPCOMPOUND 4 // find keep-case compound word
-
-// Use our own character-case definitions, because the current locale may
-// differ from what the .spl file uses.
-// These must not be called with negative number!
-#include <wchar.h> // for towupper() and towlower()
-// Multi-byte implementation. For Unicode we can call utf_*(), but don't do
-// that for ASCII, because we don't want to use 'casemap' here. Otherwise use
-// the "w" library function for characters above 255.
-#define SPELL_TOFOLD(c) (enc_utf8 && (c) >= 128 ? utf_fold(c) \
- : (c) < \
- 256 ? (int)spelltab.st_fold[c] : (int)towlower(c))
-
-#define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? utf_toupper(c) \
- : (c) < \
- 256 ? (int)spelltab.st_upper[c] : (int)towupper(c))
-
-#define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? utf_isupper(c) \
- : (c) < 256 ? spelltab.st_isu[c] : iswupper(c))
-
-
-static char *e_format = N_("E759: Format error in spell file");
-static char *e_spell_trunc = N_("E758: Truncated spell file");
-static char *e_afftrailing = N_("Trailing text in %s line %d: %s");
-static char *e_affname = N_("Affix name too long in %s line %d: %s");
-static char *e_affform = N_("E761: Format error in affix file FOL, LOW or UPP");
-static char *e_affrange = N_(
- "E762: Character in FOL, LOW or UPP is out of range");
-static char *msg_compressing = N_("Compressing word tree...");
+char *e_format = N_("E759: Format error in spell file");
// Remember what "z?" replaced.
static char_u *repl_from = NULL;
@@ -1118,7 +395,7 @@ size_t spell_check(
mi.mi_fend = ptr;
if (spell_iswordp(mi.mi_fend, wp)) {
do {
- mb_ptr_adv(mi.mi_fend);
+ MB_PTR_ADV(mi.mi_fend);
} while (*mi.mi_fend != NUL && spell_iswordp(mi.mi_fend, wp));
if (capcol != NULL && *capcol == 0 && wp->w_s->b_cap_prog != NULL) {
@@ -1145,7 +422,7 @@ size_t spell_check(
// case-fold the word with one non-word character, so that we can check
// for the word end.
if (*mi.mi_fend != NUL) {
- mb_ptr_adv(mi.mi_fend);
+ MB_PTR_ADV(mi.mi_fend);
}
(void)spell_casefold(ptr, (int)(mi.mi_fend - ptr), mi.mi_fword, MAXWLEN + 1);
@@ -1222,7 +499,7 @@ size_t spell_check(
} else if (mi.mi_end == ptr) {
// Always include at least one character. Required for when there
// is a mixup in "midword".
- mb_ptr_adv(mi.mi_end);
+ MB_PTR_ADV(mi.mi_end);
} else if (mi.mi_result == SP_BAD
&& LANGP_ENTRY(wp->w_s->b_langp, 0)->lp_slang->sl_nobreak) {
char_u *p, *fp;
@@ -1235,8 +512,8 @@ size_t spell_check(
p = mi.mi_word;
fp = mi.mi_fword;
for (;;) {
- mb_ptr_adv(p);
- mb_ptr_adv(fp);
+ MB_PTR_ADV(p);
+ MB_PTR_ADV(fp);
if (p >= mi.mi_end) {
break;
}
@@ -1411,8 +688,9 @@ static void find_word(matchinf_T *mip, int mode)
arridx = endidx[endidxcnt];
wlen = endlen[endidxcnt];
- if ((*mb_head_off)(ptr, ptr + wlen) > 0)
+ if (utf_head_off(ptr, ptr + wlen) > 0) {
continue; // not at first byte of character
+ }
if (spell_iswordp(ptr + wlen, mip->mi_win)) {
if (slang->sl_compprog == NULL && !slang->sl_nobreak)
continue; // next char is a word character
@@ -1429,8 +707,9 @@ static void find_word(matchinf_T *mip, int mode)
// case-folded word is equal to the keep-case word.
p = mip->mi_word;
if (STRNCMP(ptr, p, wlen) != 0) {
- for (char_u *s = ptr; s < ptr + wlen; mb_ptr_adv(s))
- mb_ptr_adv(p);
+ for (char_u *s = ptr; s < ptr + wlen; MB_PTR_ADV(s)) {
+ MB_PTR_ADV(p);
+ }
wlen = (int)(p - mip->mi_word);
}
}
@@ -1537,10 +816,12 @@ static void find_word(matchinf_T *mip, int mode)
mip->mi_compoff) != 0) {
// case folding may have changed the length
p = mip->mi_word;
- for (char_u *s = ptr; s < ptr + mip->mi_compoff; mb_ptr_adv(s))
- mb_ptr_adv(p);
- } else
+ for (char_u *s = ptr; s < ptr + mip->mi_compoff; MB_PTR_ADV(s)) {
+ MB_PTR_ADV(p);
+ }
+ } else {
p = mip->mi_word + mip->mi_compoff;
+ }
capflags = captype(p, mip->mi_word + wlen);
if (capflags == WF_KEEPCAP || (capflags == WF_ALLCAP
&& (flags & WF_FIXCAP) != 0))
@@ -1551,12 +832,13 @@ static void find_word(matchinf_T *mip, int mode)
// character we do not accept a Onecap word. We do
// accept a no-caps word, even when the dictionary
// word specifies ONECAP.
- mb_ptr_back(mip->mi_word, p);
+ MB_PTR_BACK(mip->mi_word, p);
if (spell_iswordp_nmw(p, mip->mi_win)
? capflags == WF_ONECAP
: (flags & WF_ONECAP) != 0
- && capflags != WF_ONECAP)
+ && capflags != WF_ONECAP) {
continue;
+ }
}
}
@@ -1611,8 +893,9 @@ static void find_word(matchinf_T *mip, int mode)
// the case-folded word is equal to the keep-case word.
p = mip->mi_fword;
if (STRNCMP(ptr, p, wlen) != 0) {
- for (char_u *s = ptr; s < ptr + wlen; mb_ptr_adv(s))
- mb_ptr_adv(p);
+ for (char_u *s = ptr; s < ptr + wlen; MB_PTR_ADV(s)) {
+ MB_PTR_ADV(p);
+ }
mip->mi_compoff = (int)(p - mip->mi_fword);
}
}
@@ -1754,8 +1037,9 @@ static bool can_compound(slang_T *slang, char_u *word, char_u *flags)
if (enc_utf8) {
// Need to convert the single byte flags to utf8 characters.
p = uflags;
- for (i = 0; flags[i] != NUL; ++i)
- p += mb_char2bytes(flags[i], p);
+ for (i = 0; flags[i] != NUL; i++) {
+ p += utf_char2bytes(flags[i], p);
+ }
*p = NUL;
p = uflags;
} else
@@ -2010,12 +1294,13 @@ static int fold_more(matchinf_T *mip)
p = mip->mi_fend;
do {
- mb_ptr_adv(mip->mi_fend);
+ MB_PTR_ADV(mip->mi_fend);
} while (*mip->mi_fend != NUL && spell_iswordp(mip->mi_fend, mip->mi_win));
// Include the non-word character so that we can check for the word end.
- if (*mip->mi_fend != NUL)
- mb_ptr_adv(mip->mi_fend);
+ if (*mip->mi_fend != NUL) {
+ MB_PTR_ADV(mip->mi_fend);
+ }
(void)spell_casefold(p, (int)(mip->mi_fend - p),
mip->mi_fword + mip->mi_fwordlen,
@@ -2114,13 +1399,14 @@ spell_move_to (
capcol = 0;
// For checking first word with a capital skip white space.
- if (capcol == 0)
- capcol = (int)(skipwhite(line) - line);
- else if (curline && wp == curwin) {
+ if (capcol == 0) {
+ capcol = (int)getwhitecols(line);
+ } else if (curline && wp == curwin) {
// For spellbadword(): check if first word needs a capital.
- col = (int)(skipwhite(line) - line);
- if (check_need_cap(lnum, col))
+ col = (int)getwhitecols(line);
+ if (check_need_cap(lnum, col)) {
capcol = col;
+ }
// Need to get the line again, may have looked at the previous
// one.
@@ -2156,12 +1442,10 @@ spell_move_to (
// the cursor.
if (dir == BACKWARD
|| lnum != wp->w_cursor.lnum
- || (lnum == wp->w_cursor.lnum
- && (wrapped
- || ((colnr_T)(curline
- ? p - buf + (ptrdiff_t)len
- : p - buf)
- > wp->w_cursor.col)))) {
+ || wrapped
+ || ((colnr_T)(curline
+ ? p - buf + (ptrdiff_t)len
+ : p - buf) > wp->w_cursor.col)) {
if (has_syntax) {
col = (int)(p - buf);
(void)syn_get_id(wp, lnum, (colnr_T)col,
@@ -2209,21 +1493,23 @@ spell_move_to (
return found_len;
}
- if (curline)
+ if (curline) {
break; // only check cursor line
+ }
+
+ // If we are back at the starting line and searched it again there
+ // is no match, give up.
+ if (lnum == wp->w_cursor.lnum && wrapped) {
+ break;
+ }
// Advance to next line.
if (dir == BACKWARD) {
- // If we are back at the starting line and searched it again there
- // is no match, give up.
- if (lnum == wp->w_cursor.lnum && wrapped)
- break;
-
- if (lnum > 1)
- --lnum;
- else if (!p_ws)
+ if (lnum > 1) {
+ lnum--;
+ } else if (!p_ws) {
break; // at first line and 'nowrapscan'
- else {
+ } else {
// Wrap around to the end of the buffer. May search the
// starting line again and accept the last match.
lnum = wp->w_buffer->b_ml.ml_line_count;
@@ -2248,8 +1534,9 @@ spell_move_to (
// If we are back at the starting line and there is no match then
// give up.
- if (lnum == wp->w_cursor.lnum && (!found_one || wrapped))
+ if (lnum == wp->w_cursor.lnum && !found_one) {
break;
+ }
// Skip the characters at the start of the next line that were
// included in a match crossing line boundaries.
@@ -2358,7 +1645,7 @@ static void spell_load_lang(char_u *lang)
// Return the encoding used for spell checking: Use 'encoding', except that we
// use "latin1" for "latin9". And limit to 60 characters (just in case).
-static char_u *spell_enc(void)
+char_u *spell_enc(void)
{
if (STRLEN(p_enc) < 60 && STRCMP(p_enc, "iso-8859-15") != 0)
@@ -2376,7 +1663,7 @@ static void int_wordlist_spl(char_u *fname)
// Allocate a new slang_T for language "lang". "lang" can be NULL.
// Caller must fill "sl_next".
-static slang_T *slang_alloc(char_u *lang)
+slang_T *slang_alloc(char_u *lang)
{
slang_T *lp = xcalloc(1, sizeof(slang_T));
@@ -2392,7 +1679,7 @@ static slang_T *slang_alloc(char_u *lang)
}
// Free the contents of an slang_T and the structure itself.
-static void slang_free(slang_T *lp)
+void slang_free(slang_T *lp)
{
xfree(lp->sl_name);
xfree(lp->sl_fname);
@@ -2417,7 +1704,7 @@ static void free_fromto(fromto_T *ftp) {
}
// Clear an slang_T so that the file can be reloaded.
-static void slang_clear(slang_T *lp)
+void slang_clear(slang_T *lp)
{
garray_T *gap;
@@ -2490,7 +1777,7 @@ static void slang_clear(slang_T *lp)
}
// Clear the info from the .sug file in "lp".
-static void slang_clear_sug(slang_T *lp)
+void slang_clear_sug(slang_T *lp)
{
xfree(lp->sl_sbyts);
lp->sl_sbyts = NULL;
@@ -2522,562 +1809,14 @@ static void spell_load_cb(char_u *fname, void *cookie)
}
}
-// Load one spell file and store the info into a slang_T.
-//
-// This is invoked in three ways:
-// - From spell_load_cb() to load a spell file for the first time. "lang" is
-// the language name, "old_lp" is NULL. Will allocate an slang_T.
-// - To reload a spell file that was changed. "lang" is NULL and "old_lp"
-// points to the existing slang_T.
-// - Just after writing a .spl file; it's read back to produce the .sug file.
-// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T.
-//
-// Returns the slang_T the spell file was loaded into. NULL for error.
-static slang_T *
-spell_load_file (
- char_u *fname,
- char_u *lang,
- slang_T *old_lp,
- bool silent // no error if file doesn't exist
-)
-{
- FILE *fd;
- char_u buf[VIMSPELLMAGICL];
- char_u *p;
- int i;
- int n;
- int len;
- char_u *save_sourcing_name = sourcing_name;
- linenr_T save_sourcing_lnum = sourcing_lnum;
- slang_T *lp = NULL;
- int c = 0;
- int res;
-
- fd = mch_fopen((char *)fname, "r");
- if (fd == NULL) {
- if (!silent)
- EMSG2(_(e_notopen), fname);
- else if (p_verbose > 2) {
- verbose_enter();
- smsg((char *)e_notopen, fname);
- verbose_leave();
- }
- goto endFAIL;
- }
- if (p_verbose > 2) {
- verbose_enter();
- smsg(_("Reading spell file \"%s\""), fname);
- verbose_leave();
- }
-
- if (old_lp == NULL) {
- lp = slang_alloc(lang);
-
- // Remember the file name, used to reload the file when it's updated.
- lp->sl_fname = vim_strsave(fname);
-
- // Check for .add.spl.
- lp->sl_add = strstr((char *)path_tail(fname), SPL_FNAME_ADD) != NULL;
- } else
- lp = old_lp;
-
- // Set sourcing_name, so that error messages mention the file name.
- sourcing_name = fname;
- sourcing_lnum = 0;
-
- // <HEADER>: <fileID>
- for (i = 0; i < VIMSPELLMAGICL; ++i)
- buf[i] = getc(fd); // <fileID>
- if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) {
- EMSG(_("E757: This does not look like a spell file"));
- goto endFAIL;
- }
- c = getc(fd); // <versionnr>
- if (c < VIMSPELLVERSION) {
- EMSG(_("E771: Old spell file, needs to be updated"));
- goto endFAIL;
- } else if (c > VIMSPELLVERSION) {
- EMSG(_("E772: Spell file is for newer version of Vim"));
- goto endFAIL;
- }
-
-
- // <SECTIONS>: <section> ... <sectionend>
- // <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
- for (;; ) {
- n = getc(fd); // <sectionID> or <sectionend>
- if (n == SN_END)
- break;
- c = getc(fd); // <sectionflags>
- len = get4c(fd); // <sectionlen>
- if (len < 0)
- goto truncerr;
-
- res = 0;
- switch (n) {
- case SN_INFO:
- lp->sl_info = READ_STRING(fd, len); // <infotext>
- if (lp->sl_info == NULL)
- goto endFAIL;
- break;
-
- case SN_REGION:
- res = read_region_section(fd, lp, len);
- break;
-
- case SN_CHARFLAGS:
- res = read_charflags_section(fd);
- break;
-
- case SN_MIDWORD:
- lp->sl_midword = READ_STRING(fd, len); // <midword>
- if (lp->sl_midword == NULL)
- goto endFAIL;
- break;
-
- case SN_PREFCOND:
- res = read_prefcond_section(fd, lp);
- break;
-
- case SN_REP:
- res = read_rep_section(fd, &lp->sl_rep, lp->sl_rep_first);
- break;
-
- case SN_REPSAL:
- res = read_rep_section(fd, &lp->sl_repsal, lp->sl_repsal_first);
- break;
-
- case SN_SAL:
- res = read_sal_section(fd, lp);
- break;
-
- case SN_SOFO:
- res = read_sofo_section(fd, lp);
- break;
-
- case SN_MAP:
- p = READ_STRING(fd, len); // <mapstr>
- if (p == NULL)
- goto endFAIL;
- set_map_str(lp, p);
- xfree(p);
- break;
-
- case SN_WORDS:
- res = read_words_section(fd, lp, len);
- break;
-
- case SN_SUGFILE:
- lp->sl_sugtime = get8ctime(fd); // <timestamp>
- break;
-
- case SN_NOSPLITSUGS:
- lp->sl_nosplitsugs = true;
- break;
-
- case SN_NOCOMPOUNDSUGS:
- lp->sl_nocompoundsugs = true;
- break;
-
- case SN_COMPOUND:
- res = read_compound(fd, lp, len);
- break;
-
- case SN_NOBREAK:
- lp->sl_nobreak = true;
- break;
-
- case SN_SYLLABLE:
- lp->sl_syllable = READ_STRING(fd, len); // <syllable>
- if (lp->sl_syllable == NULL)
- goto endFAIL;
- if (init_syl_tab(lp) == FAIL)
- goto endFAIL;
- break;
-
- default:
- // Unsupported section. When it's required give an error
- // message. When it's not required skip the contents.
- if (c & SNF_REQUIRED) {
- EMSG(_("E770: Unsupported section in spell file"));
- goto endFAIL;
- }
- while (--len >= 0)
- if (getc(fd) < 0)
- goto truncerr;
- break;
- }
-someerror:
- if (res == SP_FORMERROR) {
- EMSG(_(e_format));
- goto endFAIL;
- }
- if (res == SP_TRUNCERROR) {
-truncerr:
- EMSG(_(e_spell_trunc));
- goto endFAIL;
- }
- if (res == SP_OTHERERROR)
- goto endFAIL;
- }
-
- // <LWORDTREE>
- res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, false, 0);
- if (res != 0)
- goto someerror;
-
- // <KWORDTREE>
- res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, false, 0);
- if (res != 0)
- goto someerror;
-
- // <PREFIXTREE>
- res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, true,
- lp->sl_prefixcnt);
- if (res != 0)
- goto someerror;
-
- // For a new file link it in the list of spell files.
- if (old_lp == NULL && lang != NULL) {
- lp->sl_next = first_lang;
- first_lang = lp;
- }
-
- goto endOK;
-
-endFAIL:
- if (lang != NULL)
- // truncating the name signals the error to spell_load_lang()
- *lang = NUL;
- if (lp != NULL && old_lp == NULL)
- slang_free(lp);
- lp = NULL;
-
-endOK:
- if (fd != NULL)
- fclose(fd);
- sourcing_name = save_sourcing_name;
- sourcing_lnum = save_sourcing_lnum;
-
- return lp;
-}
-
-// Read a length field from "fd" in "cnt_bytes" bytes.
-// Allocate memory, read the string into it and add a NUL at the end.
-// Returns NULL when the count is zero.
-// Sets "*cntp" to SP_*ERROR when there is an error, length of the result
-// otherwise.
-static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
-{
- int cnt = 0;
- int i;
- char_u *str;
-
- // read the length bytes, MSB first
- for (i = 0; i < cnt_bytes; ++i)
- cnt = (cnt << 8) + getc(fd);
- if (cnt < 0) {
- *cntp = SP_TRUNCERROR;
- return NULL;
- }
- *cntp = cnt;
- if (cnt == 0)
- return NULL; // nothing to read, return NULL
-
- str = READ_STRING(fd, cnt);
- if (str == NULL)
- *cntp = SP_OTHERERROR;
- return str;
-}
-
-// Read SN_REGION: <regionname> ...
-// Return SP_*ERROR flags.
-static int read_region_section(FILE *fd, slang_T *lp, int len)
-{
- int i;
-
- if (len > 16)
- return SP_FORMERROR;
- for (i = 0; i < len; ++i)
- lp->sl_regions[i] = getc(fd); // <regionname>
- lp->sl_regions[len] = NUL;
- return 0;
-}
-
-// Read SN_CHARFLAGS section: <charflagslen> <charflags>
-// <folcharslen> <folchars>
-// Return SP_*ERROR flags.
-static int read_charflags_section(FILE *fd)
-{
- char_u *flags;
- char_u *fol;
- int flagslen, follen;
-
- // <charflagslen> <charflags>
- flags = read_cnt_string(fd, 1, &flagslen);
- if (flagslen < 0)
- return flagslen;
-
- // <folcharslen> <folchars>
- fol = read_cnt_string(fd, 2, &follen);
- if (follen < 0) {
- xfree(flags);
- return follen;
- }
-
- // Set the word-char flags and fill SPELL_ISUPPER() table.
- if (flags != NULL && fol != NULL)
- set_spell_charflags(flags, flagslen, fol);
-
- xfree(flags);
- xfree(fol);
-
- // When <charflagslen> is zero then <fcharlen> must also be zero.
- if ((flags == NULL) != (fol == NULL))
- return SP_FORMERROR;
- return 0;
-}
-
-// Read SN_PREFCOND section.
-// Return SP_*ERROR flags.
-static int read_prefcond_section(FILE *fd, slang_T *lp)
-{
- int cnt;
- int i;
- int n;
- char_u *p;
- char_u buf[MAXWLEN + 1];
-
- // <prefcondcnt> <prefcond> ...
- cnt = get2c(fd); // <prefcondcnt>
- if (cnt <= 0)
- return SP_FORMERROR;
-
- lp->sl_prefprog = xcalloc(cnt, sizeof(regprog_T *));
- lp->sl_prefixcnt = cnt;
-
- for (i = 0; i < cnt; ++i) {
- // <prefcond> : <condlen> <condstr>
- n = getc(fd); // <condlen>
- if (n < 0 || n >= MAXWLEN)
- return SP_FORMERROR;
-
- // When <condlen> is zero we have an empty condition. Otherwise
- // compile the regexp program used to check for the condition.
- if (n > 0) {
- buf[0] = '^'; // always match at one position only
- p = buf + 1;
- while (n-- > 0)
- *p++ = getc(fd); // <condstr>
- *p = NUL;
- lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING);
- }
- }
- return 0;
-}
-
-// Read REP or REPSAL items section from "fd": <repcount> <rep> ...
-// Return SP_*ERROR flags.
-static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
-{
- int cnt;
- fromto_T *ftp;
-
- cnt = get2c(fd); // <repcount>
- if (cnt < 0)
- return SP_TRUNCERROR;
-
- ga_grow(gap, cnt);
-
- // <rep> : <repfromlen> <repfrom> <reptolen> <repto>
- for (; gap->ga_len < cnt; ++gap->ga_len) {
- int c;
- ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
- ftp->ft_from = read_cnt_string(fd, 1, &c);
- if (c < 0)
- return c;
- if (c == 0)
- return SP_FORMERROR;
- ftp->ft_to = read_cnt_string(fd, 1, &c);
- if (c <= 0) {
- xfree(ftp->ft_from);
- if (c < 0)
- return c;
- return SP_FORMERROR;
- }
- }
-
- // Fill the first-index table.
- for (int i = 0; i < 256; ++i) {
- first[i] = -1;
- }
- for (int i = 0; i < gap->ga_len; ++i) {
- ftp = &((fromto_T *)gap->ga_data)[i];
- if (first[*ftp->ft_from] == -1)
- first[*ftp->ft_from] = i;
- }
- return 0;
-}
-
-// Read SN_SAL section: <salflags> <salcount> <sal> ...
-// Return SP_*ERROR flags.
-static int read_sal_section(FILE *fd, slang_T *slang)
-{
- int i;
- int cnt;
- garray_T *gap;
- salitem_T *smp;
- int ccnt;
- char_u *p;
- int c = NUL;
-
- slang->sl_sofo = false;
-
- i = getc(fd); // <salflags>
- if (i & SAL_F0LLOWUP)
- slang->sl_followup = true;
- if (i & SAL_COLLAPSE)
- slang->sl_collapse = true;
- if (i & SAL_REM_ACCENTS)
- slang->sl_rem_accents = true;
-
- cnt = get2c(fd); // <salcount>
- if (cnt < 0)
- return SP_TRUNCERROR;
-
- gap = &slang->sl_sal;
- ga_init(gap, sizeof(salitem_T), 10);
- ga_grow(gap, cnt + 1);
-
- // <sal> : <salfromlen> <salfrom> <saltolen> <salto>
- for (; gap->ga_len < cnt; ++gap->ga_len) {
- smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
- ccnt = getc(fd); // <salfromlen>
- if (ccnt < 0)
- return SP_TRUNCERROR;
- p = xmalloc(ccnt + 2);
- smp->sm_lead = p;
-
- // Read up to the first special char into sm_lead.
- for (i = 0; i < ccnt; ++i) {
- c = getc(fd); // <salfrom>
- if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
- break;
- *p++ = c;
- }
- smp->sm_leadlen = (int)(p - smp->sm_lead);
- *p++ = NUL;
-
- // Put (abc) chars in sm_oneof, if any.
- if (c == '(') {
- smp->sm_oneof = p;
- for (++i; i < ccnt; ++i) {
- c = getc(fd); // <salfrom>
- if (c == ')')
- break;
- *p++ = c;
- }
- *p++ = NUL;
- if (++i < ccnt)
- c = getc(fd);
- } else
- smp->sm_oneof = NULL;
-
- // Any following chars go in sm_rules.
- smp->sm_rules = p;
- if (i < ccnt)
- // store the char we got while checking for end of sm_lead
- *p++ = c;
- for (++i; i < ccnt; ++i)
- *p++ = getc(fd); // <salfrom>
- *p++ = NUL;
-
- // <saltolen> <salto>
- smp->sm_to = read_cnt_string(fd, 1, &ccnt);
- if (ccnt < 0) {
- xfree(smp->sm_lead);
- return ccnt;
- }
-
- if (has_mbyte) {
- // convert the multi-byte strings to wide char strings
- smp->sm_lead_w = mb_str2wide(smp->sm_lead);
- smp->sm_leadlen = mb_charlen(smp->sm_lead);
- if (smp->sm_oneof == NULL)
- smp->sm_oneof_w = NULL;
- else
- smp->sm_oneof_w = mb_str2wide(smp->sm_oneof);
- if (smp->sm_to == NULL)
- smp->sm_to_w = NULL;
- else
- smp->sm_to_w = mb_str2wide(smp->sm_to);
- }
- }
-
- if (!GA_EMPTY(gap)) {
- // Add one extra entry to mark the end with an empty sm_lead. Avoids
- // that we need to check the index every time.
- smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
- p = xmalloc(1);
- p[0] = NUL;
- smp->sm_lead = p;
- smp->sm_leadlen = 0;
- smp->sm_oneof = NULL;
- smp->sm_rules = p;
- smp->sm_to = NULL;
- if (has_mbyte) {
- smp->sm_lead_w = mb_str2wide(smp->sm_lead);
- smp->sm_leadlen = 0;
- smp->sm_oneof_w = NULL;
- smp->sm_to_w = NULL;
- }
- ++gap->ga_len;
- }
-
- // Fill the first-index table.
- set_sal_first(slang);
-
- return 0;
-}
-
-// Read SN_WORDS: <word> ...
-// Return SP_*ERROR flags.
-static int read_words_section(FILE *fd, slang_T *lp, int len)
-{
- int done = 0;
- int i;
- int c;
- char_u word[MAXWLEN];
-
- while (done < len) {
- // Read one word at a time.
- for (i = 0;; ++i) {
- c = getc(fd);
- if (c == EOF)
- return SP_TRUNCERROR;
- word[i] = c;
- if (word[i] == NUL)
- break;
- if (i == MAXWLEN - 1)
- return SP_FORMERROR;
- }
-
- // Init the count to 10.
- count_common_word(lp, word, -1, 10);
- done += i + 1;
- }
- return 0;
-}
-
-// Add a word to the hashtable of common words.
-// If it's already there then the counter is increased.
-static void
-count_common_word (
- slang_T *lp,
- char_u *word,
- int len, // word length, -1 for upto NUL
- int count // 1 to count once, 10 to init
-)
+/// Add a word to the hashtable of common words.
+/// If it's already there then the counter is increased.
+///
+/// @param[in] lp
+/// @param[in] word added to common words hashtable
+/// @param[in] len length of word or -1 for NUL terminated
+/// @param[in] count 1 to count once, 10 to init
+void count_common_word(slang_T *lp, char_u *word, int len, int count)
{
hash_T hash;
hashitem_T *hi;
@@ -3093,10 +1832,11 @@ count_common_word (
}
hash = hash_hash(p);
- hi = hash_lookup(&lp->sl_wordcount, p, hash);
+ const size_t p_len = STRLEN(p);
+ hi = hash_lookup(&lp->sl_wordcount, (const char *)p, p_len, hash);
if (HASHITEM_EMPTY(hi)) {
- wc = xmalloc(sizeof(wordcount_T) + STRLEN(p));
- STRCPY(wc->wc_word, p);
+ wc = xmalloc(sizeof(wordcount_T) + p_len);
+ memcpy(wc->wc_word, p, p_len + 1);
wc->wc_count = count;
hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash);
} else {
@@ -3140,209 +1880,9 @@ score_wordcount_adj (
return score;
}
-// SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
-// Return SP_*ERROR flags.
-static int read_sofo_section(FILE *fd, slang_T *slang)
-{
- int cnt;
- char_u *from, *to;
- int res;
-
- slang->sl_sofo = true;
-
- // <sofofromlen> <sofofrom>
- from = read_cnt_string(fd, 2, &cnt);
- if (cnt < 0)
- return cnt;
-
- // <sofotolen> <sofoto>
- to = read_cnt_string(fd, 2, &cnt);
- if (cnt < 0) {
- xfree(from);
- return cnt;
- }
-
- // Store the info in slang->sl_sal and/or slang->sl_sal_first.
- if (from != NULL && to != NULL)
- res = set_sofo(slang, from, to);
- else if (from != NULL || to != NULL)
- res = SP_FORMERROR; // only one of two strings is an error
- else
- res = 0;
-
- xfree(from);
- xfree(to);
- return res;
-}
-
-// Read the compound section from the .spl file:
-// <compmax> <compminlen> <compsylmax> <compoptions> <compflags>
-// Returns SP_*ERROR flags.
-static int read_compound(FILE *fd, slang_T *slang, int len)
-{
- int todo = len;
- int c;
- int atstart;
- char_u *pat;
- char_u *pp;
- char_u *cp;
- char_u *ap;
- char_u *crp;
- int cnt;
- garray_T *gap;
-
- if (todo < 2)
- return SP_FORMERROR; // need at least two bytes
-
- --todo;
- c = getc(fd); // <compmax>
- if (c < 2)
- c = MAXWLEN;
- slang->sl_compmax = c;
-
- --todo;
- c = getc(fd); // <compminlen>
- if (c < 1)
- c = 0;
- slang->sl_compminlen = c;
-
- --todo;
- c = getc(fd); // <compsylmax>
- if (c < 1)
- c = MAXWLEN;
- slang->sl_compsylmax = c;
-
- c = getc(fd); // <compoptions>
- if (c != 0)
- ungetc(c, fd); // be backwards compatible with Vim 7.0b
- else {
- --todo;
- c = getc(fd); // only use the lower byte for now
- --todo;
- slang->sl_compoptions = c;
-
- gap = &slang->sl_comppat;
- c = get2c(fd); // <comppatcount>
- todo -= 2;
- ga_init(gap, sizeof(char_u *), c);
- ga_grow(gap, c);
- while (--c >= 0) {
- ((char_u **)(gap->ga_data))[gap->ga_len++] =
- read_cnt_string(fd, 1, &cnt);
- // <comppatlen> <comppattext>
- if (cnt < 0)
- return cnt;
- todo -= cnt + 1;
- }
- }
- if (todo < 0)
- return SP_FORMERROR;
-
- // Turn the COMPOUNDRULE items into a regexp pattern:
- // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$".
- // Inserting backslashes may double the length, "^\(\)$<Nul>" is 7 bytes.
- // Conversion to utf-8 may double the size.
- c = todo * 2 + 7;
- if (enc_utf8)
- c += todo * 2;
- pat = xmalloc(c);
-
- // We also need a list of all flags that can appear at the start and one
- // for all flags.
- cp = xmalloc(todo + 1);
- slang->sl_compstartflags = cp;
- *cp = NUL;
-
- ap = xmalloc(todo + 1);
- slang->sl_compallflags = ap;
- *ap = NUL;
-
- // And a list of all patterns in their original form, for checking whether
- // compounding may work in match_compoundrule(). This is freed when we
- // encounter a wildcard, the check doesn't work then.
- crp = xmalloc(todo + 1);
- slang->sl_comprules = crp;
-
- pp = pat;
- *pp++ = '^';
- *pp++ = '\\';
- *pp++ = '(';
-
- atstart = 1;
- while (todo-- > 0) {
- c = getc(fd); // <compflags>
- if (c == EOF) {
- xfree(pat);
- return SP_TRUNCERROR;
- }
-
- // Add all flags to "sl_compallflags".
- if (vim_strchr((char_u *)"?*+[]/", c) == NULL
- && !byte_in_str(slang->sl_compallflags, c)) {
- *ap++ = c;
- *ap = NUL;
- }
-
- if (atstart != 0) {
- // At start of item: copy flags to "sl_compstartflags". For a
- // [abc] item set "atstart" to 2 and copy up to the ']'.
- if (c == '[')
- atstart = 2;
- else if (c == ']')
- atstart = 0;
- else {
- if (!byte_in_str(slang->sl_compstartflags, c)) {
- *cp++ = c;
- *cp = NUL;
- }
- if (atstart == 1)
- atstart = 0;
- }
- }
-
- // Copy flag to "sl_comprules", unless we run into a wildcard.
- if (crp != NULL) {
- if (c == '?' || c == '+' || c == '*') {
- xfree(slang->sl_comprules);
- slang->sl_comprules = NULL;
- crp = NULL;
- } else
- *crp++ = c;
- }
-
- if (c == '/') { // slash separates two items
- *pp++ = '\\';
- *pp++ = '|';
- atstart = 1;
- } else { // normal char, "[abc]" and '*' are copied as-is
- if (c == '?' || c == '+' || c == '~')
- *pp++ = '\\'; // "a?" becomes "a\?", "a+" becomes "a\+"
- if (enc_utf8)
- pp += mb_char2bytes(c, pp);
- else
- *pp++ = c;
- }
- }
-
- *pp++ = '\\';
- *pp++ = ')';
- *pp++ = '$';
- *pp = NUL;
-
- if (crp != NULL)
- *crp = NUL;
-
- slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
- xfree(pat);
- if (slang->sl_compprog == NULL)
- return SP_FORMERROR;
-
- return 0;
-}
-
// Returns true if byte "n" appears in "str".
// Like strchr() but independent of locale.
-static bool byte_in_str(char_u *str, int n)
+bool byte_in_str(char_u *str, int n)
{
char_u *p;
@@ -3354,7 +1894,7 @@ static bool byte_in_str(char_u *str, int n)
// Truncate "slang->sl_syllable" at the first slash and put the following items
// in "slang->sl_syl_items".
-static int init_syl_tab(slang_T *slang)
+int init_syl_tab(slang_T *slang)
{
char_u *p;
char_u *s;
@@ -3418,7 +1958,7 @@ static int count_syllables(slang_T *slang, char_u *word)
skip = false;
} else {
// No recognized syllable item, at least a syllable char then?
- c = mb_ptr2char(p);
+ c = utf_ptr2char(p);
len = (*mb_ptr2len)(p);
if (vim_strchr(slang->sl_syllable, c) == NULL)
skip = false; // No, search for next syllable
@@ -3431,294 +1971,6 @@ static int count_syllables(slang_T *slang, char_u *word)
return cnt;
}
-// Set the SOFOFROM and SOFOTO items in language "lp".
-// Returns SP_*ERROR flags when there is something wrong.
-static int set_sofo(slang_T *lp, char_u *from, char_u *to)
-{
- int i;
-
- garray_T *gap;
- char_u *s;
- char_u *p;
- int c;
- int *inp;
-
- if (has_mbyte) {
- // Use "sl_sal" as an array with 256 pointers to a list of wide
- // characters. The index is the low byte of the character.
- // The list contains from-to pairs with a terminating NUL.
- // sl_sal_first[] is used for latin1 "from" characters.
- gap = &lp->sl_sal;
- ga_init(gap, sizeof(int *), 1);
- ga_grow(gap, 256);
- memset(gap->ga_data, 0, sizeof(int *) * 256);
- gap->ga_len = 256;
-
- // First count the number of items for each list. Temporarily use
- // sl_sal_first[] for this.
- for (p = from, s = to; *p != NUL && *s != NUL; ) {
- c = mb_cptr2char_adv(&p);
- mb_cptr_adv(s);
- if (c >= 256)
- ++lp->sl_sal_first[c & 0xff];
- }
- if (*p != NUL || *s != NUL) // lengths differ
- return SP_FORMERROR;
-
- // Allocate the lists.
- for (i = 0; i < 256; ++i)
- if (lp->sl_sal_first[i] > 0) {
- p = xmalloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
- ((int **)gap->ga_data)[i] = (int *)p;
- *(int *)p = 0;
- }
-
- // Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal
- // list.
- memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
- for (p = from, s = to; *p != NUL && *s != NUL; ) {
- c = mb_cptr2char_adv(&p);
- i = mb_cptr2char_adv(&s);
- if (c >= 256) {
- // Append the from-to chars at the end of the list with
- // the low byte.
- inp = ((int **)gap->ga_data)[c & 0xff];
- while (*inp != 0)
- ++inp;
- *inp++ = c; // from char
- *inp++ = i; // to char
- *inp++ = NUL; // NUL at the end
- } else
- // mapping byte to char is done in sl_sal_first[]
- lp->sl_sal_first[c] = i;
- }
- } else {
- // mapping bytes to bytes is done in sl_sal_first[]
- if (STRLEN(from) != STRLEN(to))
- return SP_FORMERROR;
-
- for (i = 0; to[i] != NUL; ++i)
- lp->sl_sal_first[from[i]] = to[i];
- lp->sl_sal.ga_len = 1; // indicates we have soundfolding
- }
-
- return 0;
-}
-
-// Fill the first-index table for "lp".
-static void set_sal_first(slang_T *lp)
-{
- salfirst_T *sfirst;
- salitem_T *smp;
- int c;
- garray_T *gap = &lp->sl_sal;
-
- sfirst = lp->sl_sal_first;
- for (int i = 0; i < 256; ++i) {
- sfirst[i] = -1;
- }
- smp = (salitem_T *)gap->ga_data;
- for (int i = 0; i < gap->ga_len; ++i) {
- if (has_mbyte)
- // Use the lowest byte of the first character. For latin1 it's
- // the character, for other encodings it should differ for most
- // characters.
- c = *smp[i].sm_lead_w & 0xff;
- else
- c = *smp[i].sm_lead;
- if (sfirst[c] == -1) {
- sfirst[c] = i;
- if (has_mbyte) {
- int n;
-
- // Make sure all entries with this byte are following each
- // other. Move the ones that are in the wrong position. Do
- // keep the same ordering!
- while (i + 1 < gap->ga_len
- && (*smp[i + 1].sm_lead_w & 0xff) == c)
- // Skip over entry with same index byte.
- ++i;
-
- for (n = 1; i + n < gap->ga_len; ++n)
- if ((*smp[i + n].sm_lead_w & 0xff) == c) {
- salitem_T tsal;
-
- // Move entry with same index byte after the entries
- // we already found.
- ++i;
- --n;
- tsal = smp[i + n];
- memmove(smp + i + 1, smp + i,
- sizeof(salitem_T) * n);
- smp[i] = tsal;
- }
- }
- }
- }
-}
-
-// Turn a multi-byte string into a wide character string.
-// Return it in allocated memory.
-static int *mb_str2wide(char_u *s)
-{
- int i = 0;
-
- int *res = xmalloc((mb_charlen(s) + 1) * sizeof(int));
- for (char_u *p = s; *p != NUL; )
- res[i++] = mb_ptr2char_adv(&p);
- res[i] = NUL;
-
- return res;
-}
-
-// Reads a tree from the .spl or .sug file.
-// Allocates the memory and stores pointers in "bytsp" and "idxsp".
-// This is skipped when the tree has zero length.
-// Returns zero when OK, SP_ value for an error.
-static int
-spell_read_tree (
- FILE *fd,
- char_u **bytsp,
- idx_T **idxsp,
- bool prefixtree, // true for the prefix tree
- int prefixcnt // when "prefixtree" is true: prefix count
-)
-{
- int idx;
- char_u *bp;
- idx_T *ip;
-
- // The tree size was computed when writing the file, so that we can
- // allocate it as one long block. <nodecount>
- int len = get4c(fd);
- if (len < 0)
- return SP_TRUNCERROR;
- if (len > 0) {
- // Allocate the byte array.
- bp = xmalloc(len);
- *bytsp = bp;
-
- // Allocate the index array.
- ip = xcalloc(len, sizeof(*ip));
- *idxsp = ip;
-
- // Recursively read the tree and store it in the array.
- idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
- if (idx < 0)
- return idx;
- }
- return 0;
-}
-
-// Read one row of siblings from the spell file and store it in the byte array
-// "byts" and index array "idxs". Recursively read the children.
-//
-// NOTE: The code here must match put_node()!
-//
-// Returns the index (>= 0) following the siblings.
-// Returns SP_TRUNCERROR if the file is shorter than expected.
-// Returns SP_FORMERROR if there is a format error.
-static idx_T
-read_tree_node (
- FILE *fd,
- char_u *byts,
- idx_T *idxs,
- int maxidx, // size of arrays
- idx_T startidx, // current index in "byts" and "idxs"
- bool prefixtree, // true for reading PREFIXTREE
- int maxprefcondnr // maximum for <prefcondnr>
-)
-{
- int len;
- int i;
- int n;
- idx_T idx = startidx;
- int c;
- int c2;
-#define SHARED_MASK 0x8000000
-
- len = getc(fd); // <siblingcount>
- if (len <= 0)
- return SP_TRUNCERROR;
-
- if (startidx + len >= maxidx)
- return SP_FORMERROR;
- byts[idx++] = len;
-
- // Read the byte values, flag/region bytes and shared indexes.
- for (i = 1; i <= len; ++i) {
- c = getc(fd); // <byte>
- if (c < 0)
- return SP_TRUNCERROR;
- if (c <= BY_SPECIAL) {
- if (c == BY_NOFLAGS && !prefixtree) {
- // No flags, all regions.
- idxs[idx] = 0;
- c = 0;
- } else if (c != BY_INDEX) {
- if (prefixtree) {
- // Read the optional pflags byte, the prefix ID and the
- // condition nr. In idxs[] store the prefix ID in the low
- // byte, the condition index shifted up 8 bits, the flags
- // shifted up 24 bits.
- if (c == BY_FLAGS)
- c = getc(fd) << 24; // <pflags>
- else
- c = 0;
-
- c |= getc(fd); // <affixID>
-
- n = get2c(fd); // <prefcondnr>
- if (n >= maxprefcondnr)
- return SP_FORMERROR;
- c |= (n << 8);
- } else { // c must be BY_FLAGS or BY_FLAGS2
- // Read flags and optional region and prefix ID. In
- // idxs[] the flags go in the low two bytes, region above
- // that and prefix ID above the region.
- c2 = c;
- c = getc(fd); // <flags>
- if (c2 == BY_FLAGS2)
- c = (getc(fd) << 8) + c; // <flags2>
- if (c & WF_REGION)
- c = (getc(fd) << 16) + c; // <region>
- if (c & WF_AFX)
- c = (getc(fd) << 24) + c; // <affixID>
- }
-
- idxs[idx] = c;
- c = 0;
- } else { // c == BY_INDEX
- // <nodeidx>
- n = get3c(fd);
- if (n < 0 || n >= maxidx)
- return SP_FORMERROR;
- idxs[idx] = n + SHARED_MASK;
- c = getc(fd); // <xbyte>
- }
- }
- byts[idx++] = c;
- }
-
- // Recursively read the children for non-shared siblings.
- // Skip the end-of-word ones (zero byte value) and the shared ones (and
- // remove SHARED_MASK)
- for (i = 1; i <= len; ++i)
- if (byts[startidx + i] != 0) {
- if (idxs[startidx + i] & SHARED_MASK)
- idxs[startidx + i] &= ~SHARED_MASK;
- else {
- idxs[startidx + i] = idx;
- idx = read_tree_node(fd, byts, idxs, maxidx, idx,
- prefixtree, maxprefcondnr);
- if (idx < 0)
- break;
- }
- }
-
- return idx;
-}
-
// Parse 'spelllang' and set w_s->b_langp accordingly.
// Returns NULL if it's OK, an error message otherwise.
char_u *did_set_spelllang(win_T *wp)
@@ -3745,6 +1997,9 @@ char_u *did_set_spelllang(win_T *wp)
char_u *ret_msg = NULL;
char_u *spl_copy;
+ bufref_T bufref;
+ set_bufref(&bufref, wp->w_buffer);
+
// We don't want to do this recursively. May happen when a language is
// not available and the SpellFileMissing autocommand opens a new buffer
// in which 'spell' is set.
@@ -3790,9 +2045,11 @@ char_u *did_set_spelllang(win_T *wp)
dont_use_region = true;
// Check if we loaded this language before.
- for (slang = first_lang; slang != NULL; slang = slang->sl_next)
- if (path_full_compare(lang, slang->sl_fname, FALSE) == kEqualFiles)
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (path_full_compare(lang, slang->sl_fname, false) == kEqualFiles) {
break;
+ }
+ }
} else {
filename = false;
if (len > 3 && lang[len - 3] == '_') {
@@ -3823,17 +2080,18 @@ char_u *did_set_spelllang(win_T *wp)
spell_load_lang(lang);
// SpellFileMissing autocommands may do anything, including
// destroying the buffer we are using...
- if (!buf_valid(wp->w_buffer)) {
+ if (!bufref_valid(&bufref)) {
ret_msg =
- (char_u *)"E797: SpellFileMissing autocommand deleted buffer";
+ (char_u *)N_("E797: SpellFileMissing autocommand deleted buffer");
goto theend;
}
}
}
// Loop over the languages, there can be several files for "lang".
- for (slang = first_lang; slang != NULL; slang = slang->sl_next)
- if (filename ? path_full_compare(lang, slang->sl_fname, FALSE) == kEqualFiles
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (filename
+ ? path_full_compare(lang, slang->sl_fname, false) == kEqualFiles
: STRICMP(lang, slang->sl_name) == 0) {
region_mask = REGION_ALL;
if (!filename && region != NULL) {
@@ -3854,15 +2112,16 @@ char_u *did_set_spelllang(win_T *wp)
}
if (region_mask != 0) {
- langp_T *p = GA_APPEND_VIA_PTR(langp_T, &ga);
- p->lp_slang = slang;
- p->lp_region = region_mask;
+ langp_T *p_ = GA_APPEND_VIA_PTR(langp_T, &ga);
+ p_->lp_slang = slang;
+ p_->lp_region = region_mask;
use_midword(slang, wp);
if (slang->sl_nobreak)
nobreak = true;
}
}
+ }
}
// round 0: load int_wordlist, if possible.
@@ -3884,17 +2143,21 @@ char_u *did_set_spelllang(win_T *wp)
// If it was already found above then skip it.
for (c = 0; c < ga.ga_len; ++c) {
p = LANGP_ENTRY(ga, c)->lp_slang->sl_fname;
- if (p != NULL && path_full_compare(spf_name, p, FALSE) == kEqualFiles)
+ if (p != NULL
+ && path_full_compare(spf_name, p, false) == kEqualFiles) {
break;
+ }
}
if (c < ga.ga_len)
continue;
}
// Check if it was loaded already.
- for (slang = first_lang; slang != NULL; slang = slang->sl_next)
- if (path_full_compare(spf_name, slang->sl_fname, FALSE) == kEqualFiles)
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (path_full_compare(spf_name, slang->sl_fname, false) == kEqualFiles) {
break;
+ }
+ }
if (slang == NULL) {
// Not loaded, try loading it now. The language name includes the
// region name, the region is ignored otherwise. for int_wordlist
@@ -3927,11 +2190,11 @@ char_u *did_set_spelllang(win_T *wp)
}
if (region_mask != 0) {
- langp_T *p = GA_APPEND_VIA_PTR(langp_T, &ga);
- p->lp_slang = slang;
- p->lp_sallang = NULL;
- p->lp_replang = NULL;
- p->lp_region = region_mask;
+ langp_T *p_ = GA_APPEND_VIA_PTR(langp_T, &ga);
+ p_->lp_slang = slang;
+ p_->lp_sallang = NULL;
+ p_->lp_replang = NULL;
+ p_->lp_region = region_mask;
use_midword(slang, wp);
}
@@ -4010,7 +2273,7 @@ static void use_midword(slang_T *lp, win_T *wp)
int c, l, n;
char_u *bp;
- c = mb_ptr2char(p);
+ c = utf_ptr2char(p);
l = (*mb_ptr2len)(p);
if (c < 256 && l <= 2)
wp->w_s->b_spell_ismw[c] = true;
@@ -4046,16 +2309,17 @@ static int find_region(char_u *rp, char_u *region)
return i / 2;
}
-// Return case type of word:
-// w word 0
-// Word WF_ONECAP
-// W WORD WF_ALLCAP
-// WoRd wOrd WF_KEEPCAP
-static int
-captype (
- char_u *word,
- char_u *end // When NULL use up to NUL byte.
-)
+/// Return case type of word:
+/// w word 0
+/// Word WF_ONECAP
+/// W WORD WF_ALLCAP
+/// WoRd wOrd WF_KEEPCAP
+///
+/// @param[in] word
+/// @param[in] end End of word or NULL for NUL delimited string
+///
+/// @returns Case type of word
+int captype(char_u *word, char_u *end)
{
char_u *p;
int c;
@@ -4064,30 +2328,36 @@ captype (
bool past_second = false; // past second word char
// find first letter
- for (p = word; !spell_iswordp_nmw(p, curwin); mb_ptr_adv(p))
- if (end == NULL ? *p == NUL : p >= end)
+ for (p = word; !spell_iswordp_nmw(p, curwin); MB_PTR_ADV(p)) {
+ if (end == NULL ? *p == NUL : p >= end) {
return 0; // only non-word characters, illegal word
- if (has_mbyte)
- c = mb_ptr2char_adv(&p);
- else
+ }
+ }
+ if (has_mbyte) {
+ c = mb_ptr2char_adv((const char_u **)&p);
+ } else {
c = *p++;
+ }
firstcap = allcap = SPELL_ISUPPER(c);
// Need to check all letters to find a word with mixed upper/lower.
// But a word with an upper char only at start is a ONECAP.
- for (; end == NULL ? *p != NUL : p < end; mb_ptr_adv(p))
+ for (; end == NULL ? *p != NUL : p < end; MB_PTR_ADV(p)) {
if (spell_iswordp_nmw(p, curwin)) {
c = PTR2CHAR(p);
if (!SPELL_ISUPPER(c)) {
// UUl -> KEEPCAP
- if (past_second && allcap)
+ if (past_second && allcap) {
return WF_KEEPCAP;
+ }
allcap = false;
- } else if (!allcap)
+ } else if (!allcap) {
// UlU -> KEEPCAP
return WF_KEEPCAP;
+ }
past_second = true;
}
+ }
if (allcap)
return WF_ALLCAP;
@@ -4111,7 +2381,7 @@ static int badword_captype(char_u *word, char_u *end)
// Count the number of UPPER and lower case letters.
l = u = 0;
first = false;
- for (p = word; p < end; mb_ptr_adv(p)) {
+ for (p = word; p < end; MB_PTR_ADV(p)) {
c = PTR2CHAR(p);
if (SPELL_ISUPPER(c)) {
++u;
@@ -4197,3221 +2467,6 @@ void spell_reload(void)
}
}
-// Reload the spell file "fname" if it's loaded.
-static void
-spell_reload_one (
- char_u *fname,
- bool added_word // invoked through "zg"
-)
-{
- slang_T *slang;
- bool didit = false;
-
- for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
- if (path_full_compare(fname, slang->sl_fname, FALSE) == kEqualFiles) {
- slang_clear(slang);
- if (spell_load_file(fname, NULL, slang, false) == NULL)
- // reloading failed, clear the language
- slang_clear(slang);
- redraw_all_later(SOME_VALID);
- didit = true;
- }
- }
-
- // When "zg" was used and the file wasn't loaded yet, should redo
- // 'spelllang' to load it now.
- if (added_word && !didit)
- did_set_spelllang(curwin);
-}
-
-
-// Functions for ":mkspell".
-
-
-// In the postponed prefixes tree wn_flags is used to store the WFP_ flags,
-// but it must be negative to indicate the prefix tree to tree_add_word().
-// Use a negative number with the lower 8 bits zero.
-#define PFX_FLAGS -256
-
-// flags for "condit" argument of store_aff_word()
-#define CONDIT_COMB 1 // affix must combine
-#define CONDIT_CFIX 2 // affix must have CIRCUMFIX flag
-#define CONDIT_SUF 4 // add a suffix for matching flags
-#define CONDIT_AFF 8 // word already has an affix
-
-// Tunable parameters for when the tree is compressed. See 'mkspellmem'.
-static long compress_start = 30000; // memory / SBLOCKSIZE
-static long compress_inc = 100; // memory / SBLOCKSIZE
-static long compress_added = 500000; // word count
-
-#ifdef SPELL_PRINTTREE
-// For debugging the tree code: print the current tree in a (more or less)
-// readable format, so that we can see what happens when adding a word and/or
-// compressing the tree.
-// Based on code from Olaf Seibert.
-#define PRINTLINESIZE 1000
-#define PRINTWIDTH 6
-
-#define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
- PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, a2)
-
-static char line1[PRINTLINESIZE];
-static char line2[PRINTLINESIZE];
-static char line3[PRINTLINESIZE];
-
-static void spell_clear_flags(wordnode_T *node)
-{
- wordnode_T *np;
-
- for (np = node; np != NULL; np = np->wn_sibling) {
- np->wn_u1.index = FALSE;
- spell_clear_flags(np->wn_child);
- }
-}
-
-static void spell_print_node(wordnode_T *node, int depth)
-{
- if (node->wn_u1.index) {
- // Done this node before, print the reference.
- PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0);
- PRINTSOME(line2, depth, " ", 0, 0);
- PRINTSOME(line3, depth, " ", 0, 0);
- msg((char_u *)line1);
- msg((char_u *)line2);
- msg((char_u *)line3);
- } else {
- node->wn_u1.index = TRUE;
-
- if (node->wn_byte != NUL) {
- if (node->wn_child != NULL)
- PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0);
- else
- // Cannot happen?
- PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0);
- } else
- PRINTSOME(line1, depth, " $ ", 0, 0);
-
- PRINTSOME(line2, depth, "%d/%d ", node->wn_nr, node->wn_refs);
-
- if (node->wn_sibling != NULL)
- PRINTSOME(line3, depth, " | ", 0, 0);
- else
- PRINTSOME(line3, depth, " ", 0, 0);
-
- if (node->wn_byte == NUL) {
- msg((char_u *)line1);
- msg((char_u *)line2);
- msg((char_u *)line3);
- }
-
- // do the children
- if (node->wn_byte != NUL && node->wn_child != NULL)
- spell_print_node(node->wn_child, depth + 1);
-
- // do the siblings
- if (node->wn_sibling != NULL) {
- // get rid of all parent details except |
- STRCPY(line1, line3);
- STRCPY(line2, line3);
- spell_print_node(node->wn_sibling, depth);
- }
- }
-}
-
-static void spell_print_tree(wordnode_T *root)
-{
- if (root != NULL) {
- // Clear the "wn_u1.index" fields, used to remember what has been
- // done.
- spell_clear_flags(root);
-
- // Recursively print the tree.
- spell_print_node(root, 0);
- }
-}
-
-#endif // SPELL_PRINTTREE
-
-// Reads the affix file "fname".
-// Returns an afffile_T, NULL for complete failure.
-static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
-{
- FILE *fd;
- afffile_T *aff;
- char_u rline[MAXLINELEN];
- char_u *line;
- char_u *pc = NULL;
-#define MAXITEMCNT 30
- char_u *(items[MAXITEMCNT]);
- int itemcnt;
- char_u *p;
- int lnum = 0;
- affheader_T *cur_aff = NULL;
- bool did_postpone_prefix = false;
- int aff_todo = 0;
- hashtab_T *tp;
- char_u *low = NULL;
- char_u *fol = NULL;
- char_u *upp = NULL;
- int do_rep;
- int do_repsal;
- int do_sal;
- int do_mapline;
- bool found_map = false;
- hashitem_T *hi;
- int l;
- int compminlen = 0; // COMPOUNDMIN value
- int compsylmax = 0; // COMPOUNDSYLMAX value
- int compoptions = 0; // COMP_ flags
- int compmax = 0; // COMPOUNDWORDMAX value
- char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE
- // concatenated
- char_u *midword = NULL; // MIDWORD value
- char_u *syllable = NULL; // SYLLABLE value
- char_u *sofofrom = NULL; // SOFOFROM value
- char_u *sofoto = NULL; // SOFOTO value
-
- // Open the file.
- fd = mch_fopen((char *)fname, "r");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return NULL;
- }
-
- vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s ..."), fname);
- spell_message(spin, IObuff);
-
- // Only do REP lines when not done in another .aff file already.
- do_rep = GA_EMPTY(&spin->si_rep);
-
- // Only do REPSAL lines when not done in another .aff file already.
- do_repsal = GA_EMPTY(&spin->si_repsal);
-
- // Only do SAL lines when not done in another .aff file already.
- do_sal = GA_EMPTY(&spin->si_sal);
-
- // Only do MAP lines when not done in another .aff file already.
- do_mapline = GA_EMPTY(&spin->si_map);
-
- // Allocate and init the afffile_T structure.
- aff = (afffile_T *)getroom(spin, sizeof(afffile_T), true);
- if (aff == NULL) {
- fclose(fd);
- return NULL;
- }
- hash_init(&aff->af_pref);
- hash_init(&aff->af_suff);
- hash_init(&aff->af_comp);
-
- // Read all the lines in the file one by one.
- while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
- line_breakcheck();
- ++lnum;
-
- // Skip comment lines.
- if (*rline == '#')
- continue;
-
- // Convert from "SET" to 'encoding' when needed.
- xfree(pc);
- if (spin->si_conv.vc_type != CONV_NONE) {
- pc = string_convert(&spin->si_conv, rline, NULL);
- if (pc == NULL) {
- smsg(_("Conversion failure for word in %s line %d: %s"),
- fname, lnum, rline);
- continue;
- }
- line = pc;
- } else {
- pc = NULL;
- line = rline;
- }
-
- // Split the line up in white separated items. Put a NUL after each
- // item.
- itemcnt = 0;
- for (p = line;; ) {
- while (*p != NUL && *p <= ' ') // skip white space and CR/NL
- ++p;
- if (*p == NUL)
- break;
- if (itemcnt == MAXITEMCNT) // too many items
- break;
- items[itemcnt++] = p;
- // A few items have arbitrary text argument, don't split them.
- if (itemcnt == 2 && spell_info_item(items[0]))
- while (*p >= ' ' || *p == TAB) // skip until CR/NL
- ++p;
- else
- while (*p > ' ') // skip until white space or CR/NL
- ++p;
- if (*p == NUL)
- break;
- *p++ = NUL;
- }
-
- // Handle non-empty lines.
- if (itemcnt > 0) {
- if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) {
- // Setup for conversion from "ENC" to 'encoding'.
- aff->af_enc = enc_canonize(items[1]);
- if (!spin->si_ascii
- && convert_setup(&spin->si_conv, aff->af_enc,
- p_enc) == FAIL)
- smsg(_("Conversion in %s not supported: from %s to %s"),
- fname, aff->af_enc, p_enc);
- spin->si_conv.vc_fail = true;
- } else if (is_aff_rule(items, itemcnt, "FLAG", 2)
- && aff->af_flagtype == AFT_CHAR) {
- if (STRCMP(items[1], "long") == 0)
- aff->af_flagtype = AFT_LONG;
- else if (STRCMP(items[1], "num") == 0)
- aff->af_flagtype = AFT_NUM;
- else if (STRCMP(items[1], "caplong") == 0)
- aff->af_flagtype = AFT_CAPLONG;
- else
- smsg(_("Invalid value for FLAG in %s line %d: %s"),
- fname, lnum, items[1]);
- if (aff->af_rare != 0
- || aff->af_keepcase != 0
- || aff->af_bad != 0
- || aff->af_needaffix != 0
- || aff->af_circumfix != 0
- || aff->af_needcomp != 0
- || aff->af_comproot != 0
- || aff->af_nosuggest != 0
- || compflags != NULL
- || aff->af_suff.ht_used > 0
- || aff->af_pref.ht_used > 0)
- smsg(_("FLAG after using flags in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (spell_info_item(items[0]) && itemcnt > 1) {
- p = (char_u *)getroom(spin,
- (spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
- + STRLEN(items[0])
- + STRLEN(items[1]) + 3, false);
- if (p != NULL) {
- if (spin->si_info != NULL) {
- STRCPY(p, spin->si_info);
- STRCAT(p, "\n");
- }
- STRCAT(p, items[0]);
- STRCAT(p, " ");
- STRCAT(p, items[1]);
- spin->si_info = p;
- }
- } else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
- && midword == NULL) {
- midword = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "TRY", 2)) {
- // ignored, we look in the tree for what chars may appear
- }
- // TODO: remove "RAR" later
- else if ((is_aff_rule(items, itemcnt, "RAR", 2)
- || is_aff_rule(items, itemcnt, "RARE", 2))
- && aff->af_rare == 0) {
- aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- }
- // TODO: remove "KEP" later
- else if ((is_aff_rule(items, itemcnt, "KEP", 2)
- || is_aff_rule(items, itemcnt, "KEEPCASE", 2))
- && aff->af_keepcase == 0) {
- aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if ((is_aff_rule(items, itemcnt, "BAD", 2)
- || is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2))
- && aff->af_bad == 0) {
- aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2)
- && aff->af_needaffix == 0) {
- aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2)
- && aff->af_circumfix == 0) {
- aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2)
- && aff->af_nosuggest == 0) {
- aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2)
- || is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2))
- && aff->af_needcomp == 0) {
- aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2)
- && aff->af_comproot == 0) {
- aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2)
- && aff->af_compforbid == 0) {
- aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (aff->af_pref.ht_used > 0)
- smsg(_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2)
- && aff->af_comppermit == 0) {
- aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (aff->af_pref.ht_used > 0)
- smsg(_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
- fname, lnum);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2)
- && compflags == NULL) {
- // Turn flag "c" into COMPOUNDRULE compatible string "c+",
- // "Na" into "Na+", "1234" into "1234+".
- p = getroom(spin, STRLEN(items[1]) + 2, false);
- STRCPY(p, items[1]);
- STRCAT(p, "+");
- compflags = p;
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) {
- // We don't use the count, but do check that it's a number and
- // not COMPOUNDRULE mistyped.
- if (atoi((char *)items[1]) == 0)
- smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) {
- // Don't use the first rule if it is a number.
- if (compflags != NULL || *skipdigits(items[1]) != NUL) {
- // Concatenate this string to previously defined ones,
- // using a slash to separate them.
- l = (int)STRLEN(items[1]) + 1;
- if (compflags != NULL)
- l += (int)STRLEN(compflags) + 1;
- p = getroom(spin, l, false);
- if (compflags != NULL) {
- STRCPY(p, compflags);
- STRCAT(p, "/");
- }
- STRCAT(p, items[1]);
- compflags = p;
- }
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
- && compmax == 0) {
- compmax = atoi((char *)items[1]);
- if (compmax == 0)
- smsg(_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2)
- && compminlen == 0) {
- compminlen = atoi((char *)items[1]);
- if (compminlen == 0)
- smsg(_("Wrong COMPOUNDMIN value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2)
- && compsylmax == 0) {
- compsylmax = atoi((char *)items[1]);
- if (compsylmax == 0)
- smsg(_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) {
- compoptions |= COMP_CHECKDUP;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) {
- compoptions |= COMP_CHECKREP;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) {
- compoptions |= COMP_CHECKCASE;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) {
- compoptions |= COMP_CHECKTRIPLE;
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) {
- if (atoi((char *)items[1]) == 0)
- smsg(_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
- fname, lnum, items[1]);
- } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) {
- garray_T *gap = &spin->si_comppat;
- int i;
-
- // Only add the couple if it isn't already there.
- for (i = 0; i < gap->ga_len - 1; i += 2)
- if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0
- && STRCMP(((char_u **)(gap->ga_data))[i + 1],
- items[2]) == 0)
- break;
- if (i >= gap->ga_len) {
- ga_grow(gap, 2);
- ((char_u **)(gap->ga_data))[gap->ga_len++]
- = getroom_save(spin, items[1]);
- ((char_u **)(gap->ga_data))[gap->ga_len++]
- = getroom_save(spin, items[2]);
- }
- } else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2)
- && syllable == NULL) {
- syllable = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) {
- spin->si_nobreak = true;
- } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
- spin->si_nosplitsugs = true;
- } else if (is_aff_rule(items, itemcnt, "NOCOMPOUNDSUGS", 1)) {
- spin->si_nocompoundsugs = true;
- } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
- spin->si_nosugfile = true;
- } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
- aff->af_pfxpostpone = true;
- } else if (is_aff_rule(items, itemcnt, "IGNOREEXTRA", 1)) {
- aff->af_ignoreextra = true;
- } else if ((STRCMP(items[0], "PFX") == 0
- || STRCMP(items[0], "SFX") == 0)
- && aff_todo == 0
- && itemcnt >= 4) {
- int lasti = 4;
- char_u key[AH_KEY_LEN];
-
- if (*items[0] == 'P')
- tp = &aff->af_pref;
- else
- tp = &aff->af_suff;
-
- // Myspell allows the same affix name to be used multiple
- // times. The affix files that do this have an undocumented
- // "S" flag on all but the last block, thus we check for that
- // and store it in ah_follows.
- STRLCPY(key, items[1], AH_KEY_LEN);
- hi = hash_find(tp, key);
- if (!HASHITEM_EMPTY(hi)) {
- cur_aff = HI2AH(hi);
- if (cur_aff->ah_combine != (*items[2] == 'Y'))
- smsg(_("Different combining flag in continued affix block in %s line %d: %s"),
- fname, lnum, items[1]);
- if (!cur_aff->ah_follows)
- smsg(_("Duplicate affix in %s line %d: %s"),
- fname, lnum, items[1]);
- } else {
- // New affix letter.
- cur_aff = (affheader_T *)getroom(spin,
- sizeof(affheader_T), true);
- if (cur_aff == NULL)
- break;
- cur_aff->ah_flag = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (cur_aff->ah_flag == 0 || STRLEN(items[1]) >= AH_KEY_LEN)
- break;
- if (cur_aff->ah_flag == aff->af_bad
- || cur_aff->ah_flag == aff->af_rare
- || cur_aff->ah_flag == aff->af_keepcase
- || cur_aff->ah_flag == aff->af_needaffix
- || cur_aff->ah_flag == aff->af_circumfix
- || cur_aff->ah_flag == aff->af_nosuggest
- || cur_aff->ah_flag == aff->af_needcomp
- || cur_aff->ah_flag == aff->af_comproot)
- smsg(_("Affix also used for "
- "BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST"
- "in %s line %d: %s"),
- fname, lnum, items[1]);
- STRCPY(cur_aff->ah_key, items[1]);
- hash_add(tp, cur_aff->ah_key);
-
- cur_aff->ah_combine = (*items[2] == 'Y');
- }
-
- // Check for the "S" flag, which apparently means that another
- // block with the same affix name is following.
- if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) {
- ++lasti;
- cur_aff->ah_follows = true;
- } else
- cur_aff->ah_follows = false;
-
- // Myspell allows extra text after the item, but that might
- // mean mistakes go unnoticed. Require a comment-starter,
- // unless IGNOREEXTRA is used. Hunspell uses a "-" item.
- if (itemcnt > lasti
- && !aff->af_ignoreextra
- && *items[lasti] != '#')
- smsg(_(e_afftrailing), fname, lnum, items[lasti]);
-
- if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0)
- smsg(_("Expected Y or N in %s line %d: %s"),
- fname, lnum, items[2]);
-
- if (*items[0] == 'P' && aff->af_pfxpostpone) {
- if (cur_aff->ah_newID == 0) {
- // Use a new number in the .spl file later, to be able
- // to handle multiple .aff files.
- check_renumber(spin);
- cur_aff->ah_newID = ++spin->si_newprefID;
-
- // We only really use ah_newID if the prefix is
- // postponed. We know that only after handling all
- // the items.
- did_postpone_prefix = false;
- } else
- // Did use the ID in a previous block.
- did_postpone_prefix = true;
- }
-
- aff_todo = atoi((char *)items[3]);
- } else if ((STRCMP(items[0], "PFX") == 0
- || STRCMP(items[0], "SFX") == 0)
- && aff_todo > 0
- && STRCMP(cur_aff->ah_key, items[1]) == 0
- && itemcnt >= 5) {
- affentry_T *aff_entry;
- bool upper = false;
- int lasti = 5;
-
- // Myspell allows extra text after the item, but that might
- // mean mistakes go unnoticed. Require a comment-starter.
- // Hunspell uses a "-" item.
- if (itemcnt > lasti && *items[lasti] != '#'
- && (STRCMP(items[lasti], "-") != 0
- || itemcnt != lasti + 1))
- smsg(_(e_afftrailing), fname, lnum, items[lasti]);
-
- // New item for an affix letter.
- --aff_todo;
- aff_entry = (affentry_T *)getroom(spin,
- sizeof(affentry_T), true);
- if (aff_entry == NULL)
- break;
-
- if (STRCMP(items[2], "0") != 0)
- aff_entry->ae_chop = getroom_save(spin, items[2]);
- if (STRCMP(items[3], "0") != 0) {
- aff_entry->ae_add = getroom_save(spin, items[3]);
-
- // Recognize flags on the affix: abcd/XYZ
- aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/');
- if (aff_entry->ae_flags != NULL) {
- *aff_entry->ae_flags++ = NUL;
- aff_process_flags(aff, aff_entry);
- }
- }
-
- // Don't use an affix entry with non-ASCII characters when
- // "spin->si_ascii" is true.
- if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop)
- || has_non_ascii(aff_entry->ae_add))) {
- aff_entry->ae_next = cur_aff->ah_first;
- cur_aff->ah_first = aff_entry;
-
- if (STRCMP(items[4], ".") != 0) {
- char_u buf[MAXLINELEN];
-
- aff_entry->ae_cond = getroom_save(spin, items[4]);
- if (*items[0] == 'P')
- sprintf((char *)buf, "^%s", items[4]);
- else
- sprintf((char *)buf, "%s$", items[4]);
- aff_entry->ae_prog = vim_regcomp(buf,
- RE_MAGIC + RE_STRING + RE_STRICT);
- if (aff_entry->ae_prog == NULL)
- smsg(_("Broken condition in %s line %d: %s"),
- fname, lnum, items[4]);
- }
-
- // For postponed prefixes we need an entry in si_prefcond
- // for the condition. Use an existing one if possible.
- // Can't be done for an affix with flags, ignoring
- // COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG.
- if (*items[0] == 'P' && aff->af_pfxpostpone
- && aff_entry->ae_flags == NULL) {
- // When the chop string is one lower-case letter and
- // the add string ends in the upper-case letter we set
- // the "upper" flag, clear "ae_chop" and remove the
- // letters from "ae_add". The condition must either
- // be empty or start with the same letter.
- if (aff_entry->ae_chop != NULL
- && aff_entry->ae_add != NULL
- && aff_entry->ae_chop[(*mb_ptr2len)(
- aff_entry->ae_chop)] == NUL
- ) {
- int c, c_up;
-
- c = PTR2CHAR(aff_entry->ae_chop);
- c_up = SPELL_TOUPPER(c);
- if (c_up != c
- && (aff_entry->ae_cond == NULL
- || PTR2CHAR(aff_entry->ae_cond) == c)) {
- p = aff_entry->ae_add
- + STRLEN(aff_entry->ae_add);
- mb_ptr_back(aff_entry->ae_add, p);
- if (PTR2CHAR(p) == c_up) {
- upper = true;
- aff_entry->ae_chop = NULL;
- *p = NUL;
-
- // The condition is matched with the
- // actual word, thus must check for the
- // upper-case letter.
- if (aff_entry->ae_cond != NULL) {
- char_u buf[MAXLINELEN];
- if (has_mbyte) {
- onecap_copy(items[4], buf, true);
- aff_entry->ae_cond = getroom_save(
- spin, buf);
- } else
- *aff_entry->ae_cond = c_up;
- if (aff_entry->ae_cond != NULL) {
- sprintf((char *)buf, "^%s",
- aff_entry->ae_cond);
- vim_regfree(aff_entry->ae_prog);
- aff_entry->ae_prog = vim_regcomp(
- buf, RE_MAGIC + RE_STRING);
- }
- }
- }
- }
- }
-
- if (aff_entry->ae_chop == NULL
- && aff_entry->ae_flags == NULL) {
- int idx;
- char_u **pp;
- int n;
-
- // Find a previously used condition.
- for (idx = spin->si_prefcond.ga_len - 1; idx >= 0;
- --idx) {
- p = ((char_u **)spin->si_prefcond.ga_data)[idx];
- if (str_equal(p, aff_entry->ae_cond))
- break;
- }
- if (idx < 0) {
- // Not found, add a new condition.
- idx = spin->si_prefcond.ga_len;
- pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond);
- *pp = (aff_entry->ae_cond == NULL) ?
- NULL : getroom_save(spin, aff_entry->ae_cond);
- }
-
- // Add the prefix to the prefix tree.
- if (aff_entry->ae_add == NULL)
- p = (char_u *)"";
- else
- p = aff_entry->ae_add;
-
- // PFX_FLAGS is a negative number, so that
- // tree_add_word() knows this is the prefix tree.
- n = PFX_FLAGS;
- if (!cur_aff->ah_combine)
- n |= WFP_NC;
- if (upper)
- n |= WFP_UP;
- if (aff_entry->ae_comppermit)
- n |= WFP_COMPPERMIT;
- if (aff_entry->ae_compforbid)
- n |= WFP_COMPFORBID;
- tree_add_word(spin, p, spin->si_prefroot, n,
- idx, cur_aff->ah_newID);
- did_postpone_prefix = true;
- }
-
- // Didn't actually use ah_newID, backup si_newprefID.
- if (aff_todo == 0 && !did_postpone_prefix) {
- --spin->si_newprefID;
- cur_aff->ah_newID = 0;
- }
- }
- }
- } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) {
- fol = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) {
- low = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) {
- upp = vim_strsave(items[1]);
- } else if (is_aff_rule(items, itemcnt, "REP", 2)
- || is_aff_rule(items, itemcnt, "REPSAL", 2)) {
- /* Ignore REP/REPSAL count */;
- if (!isdigit(*items[1]))
- smsg(_("Expected REP(SAL) count in %s line %d"),
- fname, lnum);
- } else if ((STRCMP(items[0], "REP") == 0
- || STRCMP(items[0], "REPSAL") == 0)
- && itemcnt >= 3) {
- // REP/REPSAL item
- // Myspell ignores extra arguments, we require it starts with
- // # to detect mistakes.
- if (itemcnt > 3 && items[3][0] != '#')
- smsg(_(e_afftrailing), fname, lnum, items[3]);
- if (items[0][3] == 'S' ? do_repsal : do_rep) {
- // Replace underscore with space (can't include a space
- // directly).
- for (p = items[1]; *p != NUL; mb_ptr_adv(p))
- if (*p == '_')
- *p = ' ';
- for (p = items[2]; *p != NUL; mb_ptr_adv(p))
- if (*p == '_')
- *p = ' ';
- add_fromto(spin, items[0][3] == 'S'
- ? &spin->si_repsal
- : &spin->si_rep, items[1], items[2]);
- }
- } else if (is_aff_rule(items, itemcnt, "MAP", 2)) {
- // MAP item or count
- if (!found_map) {
- // First line contains the count.
- found_map = true;
- if (!isdigit(*items[1]))
- smsg(_("Expected MAP count in %s line %d"),
- fname, lnum);
- } else if (do_mapline) {
- int c;
-
- // Check that every character appears only once.
- for (p = items[1]; *p != NUL; ) {
- c = mb_ptr2char_adv(&p);
- if ((!GA_EMPTY(&spin->si_map)
- && vim_strchr(spin->si_map.ga_data, c)
- != NULL)
- || vim_strchr(p, c) != NULL)
- smsg(_("Duplicate character in MAP in %s line %d"),
- fname, lnum);
- }
-
- // We simply concatenate all the MAP strings, separated by
- // slashes.
- ga_concat(&spin->si_map, items[1]);
- ga_append(&spin->si_map, '/');
- }
- }
- // Accept "SAL from to" and "SAL from to #comment".
- else if (is_aff_rule(items, itemcnt, "SAL", 3)) {
- if (do_sal) {
- // SAL item (sounds-a-like)
- // Either one of the known keys or a from-to pair.
- if (STRCMP(items[1], "followup") == 0)
- spin->si_followup = sal_to_bool(items[2]);
- else if (STRCMP(items[1], "collapse_result") == 0)
- spin->si_collapse = sal_to_bool(items[2]);
- else if (STRCMP(items[1], "remove_accents") == 0)
- spin->si_rem_accents = sal_to_bool(items[2]);
- else
- // when "to" is "_" it means empty
- add_fromto(spin, &spin->si_sal, items[1],
- STRCMP(items[2], "_") == 0 ? (char_u *)""
- : items[2]);
- }
- } else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2)
- && sofofrom == NULL) {
- sofofrom = getroom_save(spin, items[1]);
- } else if (is_aff_rule(items, itemcnt, "SOFOTO", 2)
- && sofoto == NULL) {
- sofoto = getroom_save(spin, items[1]);
- } else if (STRCMP(items[0], "COMMON") == 0) {
- int i;
-
- for (i = 1; i < itemcnt; ++i) {
- if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords,
- items[i]))) {
- p = vim_strsave(items[i]);
- hash_add(&spin->si_commonwords, p);
- }
- }
- } else
- smsg(_("Unrecognized or duplicate item in %s line %d: %s"),
- fname, lnum, items[0]);
- }
- }
-
- if (fol != NULL || low != NULL || upp != NULL) {
- if (spin->si_clear_chartab) {
- // Clear the char type tables, don't want to use any of the
- // currently used spell properties.
- init_spell_chartab();
- spin->si_clear_chartab = false;
- }
-
- // Don't write a word table for an ASCII file, so that we don't check
- // for conflicts with a word table that matches 'encoding'.
- // Don't write one for utf-8 either, we use utf_*() and
- // mb_get_class(), the list of chars in the file will be incomplete.
- if (!spin->si_ascii
- && !enc_utf8
- ) {
- if (fol == NULL || low == NULL || upp == NULL)
- smsg(_("Missing FOL/LOW/UPP line in %s"), fname);
- else
- (void)set_spell_chartab(fol, low, upp);
- }
-
- xfree(fol);
- xfree(low);
- xfree(upp);
- }
-
- // Use compound specifications of the .aff file for the spell info.
- if (compmax != 0) {
- aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX");
- spin->si_compmax = compmax;
- }
-
- if (compminlen != 0) {
- aff_check_number(spin->si_compminlen, compminlen, "COMPOUNDMIN");
- spin->si_compminlen = compminlen;
- }
-
- if (compsylmax != 0) {
- if (syllable == NULL)
- smsg(_("COMPOUNDSYLMAX used without SYLLABLE"));
- aff_check_number(spin->si_compsylmax, compsylmax, "COMPOUNDSYLMAX");
- spin->si_compsylmax = compsylmax;
- }
-
- if (compoptions != 0) {
- aff_check_number(spin->si_compoptions, compoptions, "COMPOUND options");
- spin->si_compoptions |= compoptions;
- }
-
- if (compflags != NULL)
- process_compflags(spin, aff, compflags);
-
- // Check that we didn't use too many renumbered flags.
- if (spin->si_newcompID < spin->si_newprefID) {
- if (spin->si_newcompID == 127 || spin->si_newcompID == 255)
- MSG(_("Too many postponed prefixes"));
- else if (spin->si_newprefID == 0 || spin->si_newprefID == 127)
- MSG(_("Too many compound flags"));
- else
- MSG(_("Too many postponed prefixes and/or compound flags"));
- }
-
- if (syllable != NULL) {
- aff_check_string(spin->si_syllable, syllable, "SYLLABLE");
- spin->si_syllable = syllable;
- }
-
- if (sofofrom != NULL || sofoto != NULL) {
- if (sofofrom == NULL || sofoto == NULL)
- smsg(_("Missing SOFO%s line in %s"),
- sofofrom == NULL ? "FROM" : "TO", fname);
- else if (!GA_EMPTY(&spin->si_sal))
- smsg(_("Both SAL and SOFO lines in %s"), fname);
- else {
- aff_check_string(spin->si_sofofr, sofofrom, "SOFOFROM");
- aff_check_string(spin->si_sofoto, sofoto, "SOFOTO");
- spin->si_sofofr = sofofrom;
- spin->si_sofoto = sofoto;
- }
- }
-
- if (midword != NULL) {
- aff_check_string(spin->si_midword, midword, "MIDWORD");
- spin->si_midword = midword;
- }
-
- xfree(pc);
- fclose(fd);
- return aff;
-}
-
-// Returns true when items[0] equals "rulename", there are "mincount" items or
-// a comment is following after item "mincount".
-static bool is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount)
-{
- return STRCMP(items[0], rulename) == 0
- && (itemcnt == mincount
- || (itemcnt > mincount && items[mincount][0] == '#'));
-}
-
-// For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from
-// ae_flags to ae_comppermit and ae_compforbid.
-static void aff_process_flags(afffile_T *affile, affentry_T *entry)
-{
- char_u *p;
- char_u *prevp;
- unsigned flag;
-
- if (entry->ae_flags != NULL
- && (affile->af_compforbid != 0 || affile->af_comppermit != 0)) {
- for (p = entry->ae_flags; *p != NUL; ) {
- prevp = p;
- flag = get_affitem(affile->af_flagtype, &p);
- if (flag == affile->af_comppermit || flag == affile->af_compforbid) {
- STRMOVE(prevp, p);
- p = prevp;
- if (flag == affile->af_comppermit)
- entry->ae_comppermit = true;
- else
- entry->ae_compforbid = true;
- }
- if (affile->af_flagtype == AFT_NUM && *p == ',')
- ++p;
- }
- if (*entry->ae_flags == NUL)
- entry->ae_flags = NULL; // nothing left
- }
-}
-
-// Returns true if "s" is the name of an info item in the affix file.
-static bool spell_info_item(char_u *s)
-{
- return STRCMP(s, "NAME") == 0
- || STRCMP(s, "HOME") == 0
- || STRCMP(s, "VERSION") == 0
- || STRCMP(s, "AUTHOR") == 0
- || STRCMP(s, "EMAIL") == 0
- || STRCMP(s, "COPYRIGHT") == 0;
-}
-
-// Turn an affix flag name into a number, according to the FLAG type.
-// returns zero for failure.
-static unsigned affitem2flag(int flagtype, char_u *item, char_u *fname, int lnum)
-{
- unsigned res;
- char_u *p = item;
-
- res = get_affitem(flagtype, &p);
- if (res == 0) {
- if (flagtype == AFT_NUM)
- smsg(_("Flag is not a number in %s line %d: %s"),
- fname, lnum, item);
- else
- smsg(_("Illegal flag in %s line %d: %s"),
- fname, lnum, item);
- }
- if (*p != NUL) {
- smsg(_(e_affname), fname, lnum, item);
- return 0;
- }
-
- return res;
-}
-
-// Get one affix name from "*pp" and advance the pointer.
-// Returns zero for an error, still advances the pointer then.
-static unsigned get_affitem(int flagtype, char_u **pp)
-{
- int res;
-
- if (flagtype == AFT_NUM) {
- if (!ascii_isdigit(**pp)) {
- ++*pp; // always advance, avoid getting stuck
- return 0;
- }
- res = getdigits_int(pp);
- } else {
- res = mb_ptr2char_adv(pp);
- if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
- && res >= 'A' && res <= 'Z')) {
- if (**pp == NUL)
- return 0;
- res = mb_ptr2char_adv(pp) + (res << 16);
- }
- }
- return res;
-}
-
-// Process the "compflags" string used in an affix file and append it to
-// spin->si_compflags.
-// The processing involves changing the affix names to ID numbers, so that
-// they fit in one byte.
-static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compflags)
-{
- char_u *p;
- char_u *prevp;
- unsigned flag;
- compitem_T *ci;
- int id;
- int len;
- char_u *tp;
- char_u key[AH_KEY_LEN];
- hashitem_T *hi;
-
- // Make room for the old and the new compflags, concatenated with a / in
- // between. Processing it makes it shorter, but we don't know by how
- // much, thus allocate the maximum.
- len = (int)STRLEN(compflags) + 1;
- if (spin->si_compflags != NULL)
- len += (int)STRLEN(spin->si_compflags) + 1;
- p = getroom(spin, len, false);
- if (spin->si_compflags != NULL) {
- STRCPY(p, spin->si_compflags);
- STRCAT(p, "/");
- }
- spin->si_compflags = p;
- tp = p + STRLEN(p);
-
- for (p = compflags; *p != NUL; ) {
- if (vim_strchr((char_u *)"/?*+[]", *p) != NULL)
- // Copy non-flag characters directly.
- *tp++ = *p++;
- else {
- // First get the flag number, also checks validity.
- prevp = p;
- flag = get_affitem(aff->af_flagtype, &p);
- if (flag != 0) {
- // Find the flag in the hashtable. If it was used before, use
- // the existing ID. Otherwise add a new entry.
- STRLCPY(key, prevp, p - prevp + 1);
- hi = hash_find(&aff->af_comp, key);
- if (!HASHITEM_EMPTY(hi))
- id = HI2CI(hi)->ci_newID;
- else {
- ci = (compitem_T *)getroom(spin, sizeof(compitem_T), true);
- if (ci == NULL)
- break;
- STRCPY(ci->ci_key, key);
- ci->ci_flag = flag;
- // Avoid using a flag ID that has a special meaning in a
- // regexp (also inside []).
- do {
- check_renumber(spin);
- id = spin->si_newcompID--;
- } while (vim_strchr((char_u *)"/?*+[]\\-^", id) != NULL);
- ci->ci_newID = id;
- hash_add(&aff->af_comp, ci->ci_key);
- }
- *tp++ = id;
- }
- if (aff->af_flagtype == AFT_NUM && *p == ',')
- ++p;
- }
- }
-
- *tp = NUL;
-}
-
-// Check that the new IDs for postponed affixes and compounding don't overrun
-// each other. We have almost 255 available, but start at 0-127 to avoid
-// using two bytes for utf-8. When the 0-127 range is used up go to 128-255.
-// When that is used up an error message is given.
-static void check_renumber(spellinfo_T *spin)
-{
- if (spin->si_newprefID == spin->si_newcompID && spin->si_newcompID < 128) {
- spin->si_newprefID = 127;
- spin->si_newcompID = 255;
- }
-}
-
-// Returns true if flag "flag" appears in affix list "afflist".
-static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
-{
- char_u *p;
- unsigned n;
-
- switch (flagtype) {
- case AFT_CHAR:
- return vim_strchr(afflist, flag) != NULL;
-
- case AFT_CAPLONG:
- case AFT_LONG:
- for (p = afflist; *p != NUL; ) {
- n = mb_ptr2char_adv(&p);
- if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z'))
- && *p != NUL)
- n = mb_ptr2char_adv(&p) + (n << 16);
- if (n == flag)
- return true;
- }
- break;
-
- case AFT_NUM:
- for (p = afflist; *p != NUL; ) {
- int digits = getdigits_int(&p);
- assert(digits >= 0);
- n = (unsigned int)digits;
- if (n == flag)
- return true;
- if (*p != NUL) // skip over comma
- ++p;
- }
- break;
- }
- return false;
-}
-
-// Give a warning when "spinval" and "affval" numbers are set and not the same.
-static void aff_check_number(int spinval, int affval, char *name)
-{
- if (spinval != 0 && spinval != affval)
- smsg(_("%s value differs from what is used in another .aff file"),
- name);
-}
-
-// Give a warning when "spinval" and "affval" strings are set and not the same.
-static void aff_check_string(char_u *spinval, char_u *affval, char *name)
-{
- if (spinval != NULL && STRCMP(spinval, affval) != 0)
- smsg(_("%s value differs from what is used in another .aff file"),
- name);
-}
-
-// Returns true if strings "s1" and "s2" are equal. Also consider both being
-// NULL as equal.
-static bool str_equal(char_u *s1, char_u *s2)
-{
- if (s1 == NULL || s2 == NULL)
- return s1 == s2;
- return STRCMP(s1, s2) == 0;
-}
-
-// Add a from-to item to "gap". Used for REP and SAL items.
-// They are stored case-folded.
-static void add_fromto(spellinfo_T *spin, garray_T *gap, char_u *from, char_u *to)
-{
- char_u word[MAXWLEN];
-
- fromto_T *ftp = GA_APPEND_VIA_PTR(fromto_T, gap);
- (void)spell_casefold(from, (int)STRLEN(from), word, MAXWLEN);
- ftp->ft_from = getroom_save(spin, word);
- (void)spell_casefold(to, (int)STRLEN(to), word, MAXWLEN);
- ftp->ft_to = getroom_save(spin, word);
-}
-
-// Converts a boolean argument in a SAL line to true or false;
-static bool sal_to_bool(char_u *s)
-{
- return STRCMP(s, "1") == 0 || STRCMP(s, "true") == 0;
-}
-
-// Free the structure filled by spell_read_aff().
-static void spell_free_aff(afffile_T *aff)
-{
- hashtab_T *ht;
- hashitem_T *hi;
- int todo;
- affheader_T *ah;
- affentry_T *ae;
-
- xfree(aff->af_enc);
-
- // All this trouble to free the "ae_prog" items...
- for (ht = &aff->af_pref;; ht = &aff->af_suff) {
- todo = (int)ht->ht_used;
- for (hi = ht->ht_array; todo > 0; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- ah = HI2AH(hi);
- for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
- vim_regfree(ae->ae_prog);
- }
- }
- if (ht == &aff->af_suff)
- break;
- }
-
- hash_clear(&aff->af_pref);
- hash_clear(&aff->af_suff);
- hash_clear(&aff->af_comp);
-}
-
-// Read dictionary file "fname".
-// Returns OK or FAIL;
-static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
-{
- hashtab_T ht;
- char_u line[MAXLINELEN];
- char_u *p;
- char_u *afflist;
- char_u store_afflist[MAXWLEN];
- int pfxlen;
- bool need_affix;
- char_u *dw;
- char_u *pc;
- char_u *w;
- int l;
- hash_T hash;
- hashitem_T *hi;
- FILE *fd;
- int lnum = 1;
- int non_ascii = 0;
- int retval = OK;
- char_u message[MAXLINELEN + MAXWLEN];
- int flags;
- int duplicate = 0;
-
- // Open the file.
- fd = mch_fopen((char *)fname, "r");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return FAIL;
- }
-
- // The hashtable is only used to detect duplicated words.
- hash_init(&ht);
-
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Reading dictionary file %s ..."), fname);
- spell_message(spin, IObuff);
-
- // start with a message for the first line
- spin->si_msg_count = 999999;
-
- // Read and ignore the first line: word count.
- (void)vim_fgets(line, MAXLINELEN, fd);
- if (!ascii_isdigit(*skipwhite(line)))
- EMSG2(_("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) {
- line_breakcheck();
- ++lnum;
- if (line[0] == '#' || line[0] == '/')
- continue; // comment line
-
- // Remove CR, LF and white space from the end. White space halfway through
- // the word is kept to allow multi-word terms like "et al.".
- l = (int)STRLEN(line);
- while (l > 0 && line[l - 1] <= ' ')
- --l;
- if (l == 0)
- continue; // empty line
- line[l] = NUL;
-
- // Convert from "SET" to 'encoding' when needed.
- if (spin->si_conv.vc_type != CONV_NONE) {
- pc = string_convert(&spin->si_conv, line, NULL);
- if (pc == NULL) {
- smsg(_("Conversion failure for word in %s line %d: %s"),
- fname, lnum, line);
- continue;
- }
- w = pc;
- } else {
- pc = NULL;
- w = line;
- }
-
- // Truncate the word at the "/", set "afflist" to what follows.
- // Replace "\/" by "/" and "\\" by "\".
- afflist = NULL;
- for (p = w; *p != NUL; mb_ptr_adv(p)) {
- if (*p == '\\' && (p[1] == '\\' || p[1] == '/'))
- STRMOVE(p, p + 1);
- else if (*p == '/') {
- *p = NUL;
- afflist = p + 1;
- break;
- }
- }
-
- // Skip non-ASCII words when "spin->si_ascii" is true.
- if (spin->si_ascii && has_non_ascii(w)) {
- ++non_ascii;
- xfree(pc);
- continue;
- }
-
- // This takes time, print a message every 10000 words.
- if (spin->si_verbose && spin->si_msg_count > 10000) {
- spin->si_msg_count = 0;
- vim_snprintf((char *)message, sizeof(message),
- _("line %6d, word %6d - %s"),
- lnum, spin->si_foldwcount + spin->si_keepwcount, w);
- msg_start();
- msg_puts_long_attr(message, 0);
- msg_clr_eos();
- msg_didout = FALSE;
- msg_col = 0;
- ui_flush();
- }
-
- // Store the word in the hashtable to be able to find duplicates.
- dw = getroom_save(spin, w);
- if (dw == NULL) {
- retval = FAIL;
- xfree(pc);
- break;
- }
-
- hash = hash_hash(dw);
- hi = hash_lookup(&ht, dw, hash);
- if (!HASHITEM_EMPTY(hi)) {
- if (p_verbose > 0)
- smsg(_("Duplicate word in %s line %d: %s"),
- fname, lnum, dw);
- else if (duplicate == 0)
- smsg(_("First duplicate word in %s line %d: %s"),
- fname, lnum, dw);
- ++duplicate;
- } else
- hash_add_item(&ht, hi, dw, hash);
-
- flags = 0;
- store_afflist[0] = NUL;
- pfxlen = 0;
- need_affix = false;
- if (afflist != NULL) {
- // Extract flags from the affix list.
- flags |= get_affix_flags(affile, afflist);
-
- if (affile->af_needaffix != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needaffix))
- need_affix = true;
-
- if (affile->af_pfxpostpone)
- // Need to store the list of prefix IDs with the word.
- pfxlen = get_pfxlist(affile, afflist, store_afflist);
-
- if (spin->si_compflags != NULL)
- // Need to store the list of compound flags with the word.
- // Concatenate them to the list of prefix IDs.
- get_compflags(affile, afflist, store_afflist + pfxlen);
- }
-
- // Add the word to the word tree(s).
- if (store_word(spin, dw, flags, spin->si_region,
- store_afflist, need_affix) == FAIL)
- retval = FAIL;
-
- if (afflist != NULL) {
- // Find all matching suffixes and add the resulting words.
- // Additionally do matching prefixes that combine.
- if (store_aff_word(spin, dw, afflist, affile,
- &affile->af_suff, &affile->af_pref,
- CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
- retval = FAIL;
-
- // Find all matching prefixes and add the resulting words.
- if (store_aff_word(spin, dw, afflist, affile,
- &affile->af_pref, NULL,
- CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
- retval = FAIL;
- }
-
- xfree(pc);
- }
-
- if (duplicate > 0)
- smsg(_("%d duplicate word(s) in %s"), duplicate, fname);
- if (spin->si_ascii && non_ascii > 0)
- smsg(_("Ignored %d word(s) with non-ASCII characters in %s"),
- non_ascii, fname);
- hash_clear(&ht);
-
- fclose(fd);
- return retval;
-}
-
-// Check for affix flags in "afflist" that are turned into word flags.
-// Return WF_ flags.
-static int get_affix_flags(afffile_T *affile, char_u *afflist)
-{
- int flags = 0;
-
- if (affile->af_keepcase != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_keepcase))
- flags |= WF_KEEPCAP | WF_FIXCAP;
- if (affile->af_rare != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_rare))
- flags |= WF_RARE;
- if (affile->af_bad != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_bad))
- flags |= WF_BANNED;
- if (affile->af_needcomp != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_needcomp))
- flags |= WF_NEEDCOMP;
- if (affile->af_comproot != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_comproot))
- flags |= WF_COMPROOT;
- if (affile->af_nosuggest != 0 && flag_in_afflist(
- affile->af_flagtype, afflist, affile->af_nosuggest))
- flags |= WF_NOSUGGEST;
- return flags;
-}
-
-// Get the list of prefix IDs from the affix list "afflist".
-// Used for PFXPOSTPONE.
-// Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL
-// and return the number of affixes.
-static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist)
-{
- char_u *p;
- char_u *prevp;
- int cnt = 0;
- int id;
- char_u key[AH_KEY_LEN];
- hashitem_T *hi;
-
- for (p = afflist; *p != NUL; ) {
- prevp = p;
- if (get_affitem(affile->af_flagtype, &p) != 0) {
- // A flag is a postponed prefix flag if it appears in "af_pref"
- // and it's ID is not zero.
- STRLCPY(key, prevp, p - prevp + 1);
- hi = hash_find(&affile->af_pref, key);
- if (!HASHITEM_EMPTY(hi)) {
- id = HI2AH(hi)->ah_newID;
- if (id != 0)
- store_afflist[cnt++] = id;
- }
- }
- if (affile->af_flagtype == AFT_NUM && *p == ',')
- ++p;
- }
-
- store_afflist[cnt] = NUL;
- return cnt;
-}
-
-// Get the list of compound IDs from the affix list "afflist" that are used
-// for compound words.
-// Puts the flags in "store_afflist[]".
-static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist)
-{
- char_u *p;
- char_u *prevp;
- int cnt = 0;
- char_u key[AH_KEY_LEN];
- hashitem_T *hi;
-
- for (p = afflist; *p != NUL; ) {
- prevp = p;
- if (get_affitem(affile->af_flagtype, &p) != 0) {
- // A flag is a compound flag if it appears in "af_comp".
- STRLCPY(key, prevp, p - prevp + 1);
- hi = hash_find(&affile->af_comp, key);
- if (!HASHITEM_EMPTY(hi))
- store_afflist[cnt++] = HI2CI(hi)->ci_newID;
- }
- if (affile->af_flagtype == AFT_NUM && *p == ',')
- ++p;
- }
-
- store_afflist[cnt] = NUL;
-}
-
-// Apply affixes to a word and store the resulting words.
-// "ht" is the hashtable with affentry_T that need to be applied, either
-// prefixes or suffixes.
-// "xht", when not NULL, is the prefix hashtable, to be used additionally on
-// the resulting words for combining affixes.
-//
-// Returns FAIL when out of memory.
-static int
-store_aff_word (
- spellinfo_T *spin, // spell info
- char_u *word, // basic word start
- char_u *afflist, // list of names of supported affixes
- afffile_T *affile,
- hashtab_T *ht,
- hashtab_T *xht,
- int condit, // CONDIT_SUF et al.
- int flags, // flags for the word
- char_u *pfxlist, // list of prefix IDs
- int pfxlen // nr of flags in "pfxlist" for prefixes, rest
- // is compound flags
-)
-{
- int todo;
- hashitem_T *hi;
- affheader_T *ah;
- affentry_T *ae;
- char_u newword[MAXWLEN];
- int retval = OK;
- int i, j;
- char_u *p;
- int use_flags;
- char_u *use_pfxlist;
- int use_pfxlen;
- bool need_affix;
- char_u store_afflist[MAXWLEN];
- char_u pfx_pfxlist[MAXWLEN];
- size_t wordlen = STRLEN(word);
- int use_condit;
-
- todo = (int)ht->ht_used;
- for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi) {
- if (!HASHITEM_EMPTY(hi)) {
- --todo;
- ah = HI2AH(hi);
-
- // Check that the affix combines, if required, and that the word
- // supports this affix.
- if (((condit & CONDIT_COMB) == 0 || ah->ah_combine)
- && flag_in_afflist(affile->af_flagtype, afflist,
- ah->ah_flag)) {
- // Loop over all affix entries with this name.
- for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) {
- // Check the condition. It's not logical to match case
- // here, but it is required for compatibility with
- // Myspell.
- // Another requirement from Myspell is that the chop
- // string is shorter than the word itself.
- // For prefixes, when "PFXPOSTPONE" was used, only do
- // prefixes with a chop string and/or flags.
- // When a previously added affix had CIRCUMFIX this one
- // must have it too, if it had not then this one must not
- // have one either.
- if ((xht != NULL || !affile->af_pfxpostpone
- || ae->ae_chop != NULL
- || ae->ae_flags != NULL)
- && (ae->ae_chop == NULL
- || STRLEN(ae->ae_chop) < wordlen)
- && (ae->ae_prog == NULL
- || vim_regexec_prog(&ae->ae_prog, false, word, (colnr_T)0))
- && (((condit & CONDIT_CFIX) == 0)
- == ((condit & CONDIT_AFF) == 0
- || ae->ae_flags == NULL
- || !flag_in_afflist(affile->af_flagtype,
- ae->ae_flags, affile->af_circumfix)))) {
- // Match. Remove the chop and add the affix.
- if (xht == NULL) {
- // prefix: chop/add at the start of the word
- if (ae->ae_add == NULL)
- *newword = NUL;
- else
- STRLCPY(newword, ae->ae_add, MAXWLEN);
- p = word;
- if (ae->ae_chop != NULL) {
- // Skip chop string.
- if (has_mbyte) {
- i = mb_charlen(ae->ae_chop);
- for (; i > 0; --i)
- mb_ptr_adv(p);
- } else
- p += STRLEN(ae->ae_chop);
- }
- STRCAT(newword, p);
- } else {
- // suffix: chop/add at the end of the word
- STRLCPY(newword, word, MAXWLEN);
- if (ae->ae_chop != NULL) {
- // Remove chop string.
- p = newword + STRLEN(newword);
- i = (int)MB_CHARLEN(ae->ae_chop);
- for (; i > 0; --i)
- mb_ptr_back(newword, p);
- *p = NUL;
- }
- if (ae->ae_add != NULL)
- STRCAT(newword, ae->ae_add);
- }
-
- use_flags = flags;
- use_pfxlist = pfxlist;
- use_pfxlen = pfxlen;
- need_affix = false;
- use_condit = condit | CONDIT_COMB | CONDIT_AFF;
- if (ae->ae_flags != NULL) {
- // Extract flags from the affix list.
- use_flags |= get_affix_flags(affile, ae->ae_flags);
-
- if (affile->af_needaffix != 0 && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_needaffix))
- need_affix = true;
-
- // When there is a CIRCUMFIX flag the other affix
- // must also have it and we don't add the word
- // with one affix.
- if (affile->af_circumfix != 0 && flag_in_afflist(
- affile->af_flagtype, ae->ae_flags,
- affile->af_circumfix)) {
- use_condit |= CONDIT_CFIX;
- if ((condit & CONDIT_CFIX) == 0)
- need_affix = true;
- }
-
- if (affile->af_pfxpostpone
- || spin->si_compflags != NULL) {
- if (affile->af_pfxpostpone)
- // Get prefix IDS from the affix list.
- use_pfxlen = get_pfxlist(affile,
- ae->ae_flags, store_afflist);
- else
- use_pfxlen = 0;
- use_pfxlist = store_afflist;
-
- // Combine the prefix IDs. Avoid adding the
- // same ID twice.
- for (i = 0; i < pfxlen; ++i) {
- for (j = 0; j < use_pfxlen; ++j)
- if (pfxlist[i] == use_pfxlist[j])
- break;
- if (j == use_pfxlen)
- use_pfxlist[use_pfxlen++] = pfxlist[i];
- }
-
- if (spin->si_compflags != NULL)
- // Get compound IDS from the affix list.
- get_compflags(affile, ae->ae_flags,
- use_pfxlist + use_pfxlen);
- else
- use_pfxlist[use_pfxlen] = NUL;
-
- // Combine the list of compound flags.
- // Concatenate them to the prefix IDs list.
- // Avoid adding the same ID twice.
- for (i = pfxlen; pfxlist[i] != NUL; ++i) {
- for (j = use_pfxlen;
- use_pfxlist[j] != NUL; ++j)
- if (pfxlist[i] == use_pfxlist[j])
- break;
- if (use_pfxlist[j] == NUL) {
- use_pfxlist[j++] = pfxlist[i];
- use_pfxlist[j] = NUL;
- }
- }
- }
- }
-
- // Obey a "COMPOUNDFORBIDFLAG" of the affix: don't
- // use the compound flags.
- if (use_pfxlist != NULL && ae->ae_compforbid) {
- STRLCPY(pfx_pfxlist, use_pfxlist, use_pfxlen + 1);
- use_pfxlist = pfx_pfxlist;
- }
-
- // When there are postponed prefixes...
- if (spin->si_prefroot != NULL
- && spin->si_prefroot->wn_sibling != NULL) {
- // ... add a flag to indicate an affix was used.
- use_flags |= WF_HAS_AFF;
-
- // ... don't use a prefix list if combining
- // affixes is not allowed. But do use the
- // compound flags after them.
- if (!ah->ah_combine && use_pfxlist != NULL)
- use_pfxlist += use_pfxlen;
- }
-
- // When compounding is supported and there is no
- // "COMPOUNDPERMITFLAG" then forbid compounding on the
- // side where the affix is applied.
- if (spin->si_compflags != NULL && !ae->ae_comppermit) {
- if (xht != NULL)
- use_flags |= WF_NOCOMPAFT;
- else
- use_flags |= WF_NOCOMPBEF;
- }
-
- // Store the modified word.
- if (store_word(spin, newword, use_flags,
- spin->si_region, use_pfxlist,
- need_affix) == FAIL)
- retval = FAIL;
-
- // When added a prefix or a first suffix and the affix
- // has flags may add a(nother) suffix. RECURSIVE!
- if ((condit & CONDIT_SUF) && ae->ae_flags != NULL)
- if (store_aff_word(spin, newword, ae->ae_flags,
- affile, &affile->af_suff, xht,
- use_condit & (xht == NULL
- ? ~0 : ~CONDIT_SUF),
- use_flags, use_pfxlist, pfxlen) == FAIL)
- retval = FAIL;
-
- // When added a suffix and combining is allowed also
- // try adding a prefix additionally. Both for the
- // word flags and for the affix flags. RECURSIVE!
- if (xht != NULL && ah->ah_combine) {
- if (store_aff_word(spin, newword,
- afflist, affile,
- xht, NULL, use_condit,
- use_flags, use_pfxlist,
- pfxlen) == FAIL
- || (ae->ae_flags != NULL
- && store_aff_word(spin, newword,
- ae->ae_flags, affile,
- xht, NULL, use_condit,
- use_flags, use_pfxlist,
- pfxlen) == FAIL))
- retval = FAIL;
- }
- }
- }
- }
- }
- }
-
- return retval;
-}
-
-// Read a file with a list of words.
-static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
-{
- FILE *fd;
- long lnum = 0;
- char_u rline[MAXLINELEN];
- char_u *line;
- char_u *pc = NULL;
- char_u *p;
- int l;
- int retval = OK;
- bool did_word = false;
- int non_ascii = 0;
- int flags;
- int regionmask;
-
- // Open the file.
- fd = mch_fopen((char *)fname, "r");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return FAIL;
- }
-
- vim_snprintf((char *)IObuff, IOSIZE, _("Reading word file %s ..."), fname);
- spell_message(spin, IObuff);
-
- // Read all the lines in the file one by one.
- while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
- line_breakcheck();
- ++lnum;
-
- // Skip comment lines.
- if (*rline == '#')
- continue;
-
- // Remove CR, LF and white space from the end.
- l = (int)STRLEN(rline);
- while (l > 0 && rline[l - 1] <= ' ')
- --l;
- if (l == 0)
- continue; // empty or blank line
- rline[l] = NUL;
-
- // Convert from "/encoding={encoding}" to 'encoding' when needed.
- xfree(pc);
- if (spin->si_conv.vc_type != CONV_NONE) {
- pc = string_convert(&spin->si_conv, rline, NULL);
- if (pc == NULL) {
- smsg(_("Conversion failure for word in %s line %d: %s"),
- fname, lnum, rline);
- continue;
- }
- line = pc;
- } else {
- pc = NULL;
- line = rline;
- }
-
- if (*line == '/') {
- ++line;
- if (STRNCMP(line, "encoding=", 9) == 0) {
- if (spin->si_conv.vc_type != CONV_NONE)
- smsg(_("Duplicate /encoding= line ignored in %s line %d: %s"),
- fname, lnum, line - 1);
- else if (did_word)
- smsg(_("/encoding= line after word ignored in %s line %d: %s"),
- fname, lnum, line - 1);
- else {
- char_u *enc;
-
- // Setup for conversion to 'encoding'.
- line += 9;
- enc = enc_canonize(line);
- if (!spin->si_ascii
- && convert_setup(&spin->si_conv, enc,
- p_enc) == FAIL)
- smsg(_("Conversion in %s not supported: from %s to %s"),
- fname, line, p_enc);
- xfree(enc);
- spin->si_conv.vc_fail = true;
- }
- continue;
- }
-
- if (STRNCMP(line, "regions=", 8) == 0) {
- if (spin->si_region_count > 1)
- smsg(_("Duplicate /regions= line ignored in %s line %d: %s"),
- fname, lnum, line);
- else {
- line += 8;
- if (STRLEN(line) > 16)
- smsg(_("Too many regions in %s line %d: %s"),
- fname, lnum, line);
- else {
- spin->si_region_count = (int)STRLEN(line) / 2;
- STRCPY(spin->si_region_name, line);
-
- // Adjust the mask for a word valid in all regions.
- spin->si_region = (1 << spin->si_region_count) - 1;
- }
- }
- continue;
- }
-
- smsg(_("/ line ignored in %s line %d: %s"),
- fname, lnum, line - 1);
- continue;
- }
-
- flags = 0;
- regionmask = spin->si_region;
-
- // Check for flags and region after a slash.
- p = vim_strchr(line, '/');
- if (p != NULL) {
- *p++ = NUL;
- while (*p != NUL) {
- if (*p == '=') // keep-case word
- flags |= WF_KEEPCAP | WF_FIXCAP;
- else if (*p == '!') // Bad, bad, wicked word.
- flags |= WF_BANNED;
- else if (*p == '?') // Rare word.
- flags |= WF_RARE;
- else if (ascii_isdigit(*p)) { // region number(s)
- if ((flags & WF_REGION) == 0) // first one
- regionmask = 0;
- flags |= WF_REGION;
-
- l = *p - '0';
- if (l > spin->si_region_count) {
- smsg(_("Invalid region nr in %s line %d: %s"),
- fname, lnum, p);
- break;
- }
- regionmask |= 1 << (l - 1);
- } else {
- smsg(_("Unrecognized flags in %s line %d: %s"),
- fname, lnum, p);
- break;
- }
- ++p;
- }
- }
-
- // Skip non-ASCII words when "spin->si_ascii" is true.
- if (spin->si_ascii && has_non_ascii(line)) {
- ++non_ascii;
- continue;
- }
-
- // Normal word: store it.
- if (store_word(spin, line, flags, regionmask, NULL, false) == FAIL) {
- retval = FAIL;
- break;
- }
- did_word = true;
- }
-
- xfree(pc);
- fclose(fd);
-
- if (spin->si_ascii && non_ascii > 0) {
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Ignored %d words with non-ASCII characters"), non_ascii);
- spell_message(spin, IObuff);
- }
-
- return retval;
-}
-
-/// Get part of an sblock_T, "len" bytes long.
-/// This avoids calling free() for every little struct we use (and keeping
-/// track of them).
-/// The memory is cleared to all zeros.
-///
-/// @param len Length needed (<= SBLOCKSIZE).
-/// @param align Align for pointer.
-/// @return Pointer into block data.
-static void *getroom(spellinfo_T *spin, size_t len, bool align)
- FUNC_ATTR_NONNULL_RET
-{
- char_u *p;
- sblock_T *bl = spin->si_blocks;
-
- assert(len <= SBLOCKSIZE);
-
- if (align && bl != NULL)
- // Round size up for alignment. On some systems structures need to be
- // aligned to the size of a pointer (e.g., SPARC).
- bl->sb_used = (bl->sb_used + sizeof(char *) - 1)
- & ~(sizeof(char *) - 1);
-
- if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) {
- // Allocate a block of memory. It is not freed until much later.
- bl = xcalloc(1, (sizeof(sblock_T) + SBLOCKSIZE));
- bl->sb_next = spin->si_blocks;
- spin->si_blocks = bl;
- bl->sb_used = 0;
- ++spin->si_blocks_cnt;
- }
-
- p = bl->sb_data + bl->sb_used;
- bl->sb_used += (int)len;
-
- return p;
-}
-
-// Make a copy of a string into memory allocated with getroom().
-// Returns NULL when out of memory.
-static char_u *getroom_save(spellinfo_T *spin, char_u *s)
-{
- char_u *sc;
-
- sc = (char_u *)getroom(spin, STRLEN(s) + 1, false);
- if (sc != NULL)
- STRCPY(sc, s);
- return sc;
-}
-
-
-// Free the list of allocated sblock_T.
-static void free_blocks(sblock_T *bl)
-{
- sblock_T *next;
-
- while (bl != NULL) {
- next = bl->sb_next;
- xfree(bl);
- bl = next;
- }
-}
-
-// Allocate the root of a word tree.
-// Returns NULL when out of memory.
-static wordnode_T *wordtree_alloc(spellinfo_T *spin)
-{
- return (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
-}
-
-// Store a word in the tree(s).
-// Always store it in the case-folded tree. For a keep-case word this is
-// useful when the word can also be used with all caps (no WF_FIXCAP flag) and
-// used to find suggestions.
-// For a keep-case word also store it in the keep-case tree.
-// When "pfxlist" is not NULL store the word for each postponed prefix ID and
-// compound flag.
-static int
-store_word (
- spellinfo_T *spin,
- char_u *word,
- int flags, // extra flags, WF_BANNED
- int region, // supported region(s)
- char_u *pfxlist, // list of prefix IDs or NULL
- bool need_affix // only store word with affix ID
-)
-{
- int len = (int)STRLEN(word);
- int ct = captype(word, word + len);
- char_u foldword[MAXWLEN];
- int res = OK;
- char_u *p;
-
- (void)spell_casefold(word, len, foldword, MAXWLEN);
- for (p = pfxlist; res == OK; ++p) {
- if (!need_affix || (p != NULL && *p != NUL))
- res = tree_add_word(spin, foldword, spin->si_foldroot, ct | flags,
- region, p == NULL ? 0 : *p);
- if (p == NULL || *p == NUL)
- break;
- }
- ++spin->si_foldwcount;
-
- if (res == OK && (ct == WF_KEEPCAP || (flags & WF_KEEPCAP))) {
- for (p = pfxlist; res == OK; ++p) {
- if (!need_affix || (p != NULL && *p != NUL))
- res = tree_add_word(spin, word, spin->si_keeproot, flags,
- region, p == NULL ? 0 : *p);
- if (p == NULL || *p == NUL)
- break;
- }
- ++spin->si_keepwcount;
- }
- return res;
-}
-
-// Add word "word" to a word tree at "root".
-// When "flags" < 0 we are adding to the prefix tree where "flags" is used for
-// "rare" and "region" is the condition nr.
-// Returns FAIL when out of memory.
-static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, int affixID)
-{
- wordnode_T *node = root;
- wordnode_T *np;
- wordnode_T *copyp, **copyprev;
- wordnode_T **prev = NULL;
- int i;
-
- // Add each byte of the word to the tree, including the NUL at the end.
- for (i = 0;; ++i) {
- // When there is more than one reference to this node we need to make
- // a copy, so that we can modify it. Copy the whole list of siblings
- // (we don't optimize for a partly shared list of siblings).
- if (node != NULL && node->wn_refs > 1) {
- --node->wn_refs;
- copyprev = prev;
- for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) {
- // Allocate a new node and copy the info.
- np = get_wordnode(spin);
- if (np == NULL)
- return FAIL;
- np->wn_child = copyp->wn_child;
- if (np->wn_child != NULL)
- ++np->wn_child->wn_refs; // child gets extra ref
- np->wn_byte = copyp->wn_byte;
- if (np->wn_byte == NUL) {
- np->wn_flags = copyp->wn_flags;
- np->wn_region = copyp->wn_region;
- np->wn_affixID = copyp->wn_affixID;
- }
-
- // Link the new node in the list, there will be one ref.
- np->wn_refs = 1;
- if (copyprev != NULL)
- *copyprev = np;
- copyprev = &np->wn_sibling;
-
- // Let "node" point to the head of the copied list.
- if (copyp == node)
- node = np;
- }
- }
-
- // Look for the sibling that has the same character. They are sorted
- // on byte value, thus stop searching when a sibling is found with a
- // higher byte value. For zero bytes (end of word) the sorting is
- // done on flags and then on affixID.
- while (node != NULL
- && (node->wn_byte < word[i]
- || (node->wn_byte == NUL
- && (flags < 0
- ? node->wn_affixID < (unsigned)affixID
- : (node->wn_flags < (unsigned)(flags & WN_MASK)
- || (node->wn_flags == (flags & WN_MASK)
- && (spin->si_sugtree
- ? (node->wn_region & 0xffff) < region
- : node->wn_affixID
- < (unsigned)affixID))))))) {
- prev = &node->wn_sibling;
- node = *prev;
- }
- if (node == NULL
- || node->wn_byte != word[i]
- || (word[i] == NUL
- && (flags < 0
- || spin->si_sugtree
- || node->wn_flags != (flags & WN_MASK)
- || node->wn_affixID != affixID))) {
- // Allocate a new node.
- np = get_wordnode(spin);
- if (np == NULL)
- return FAIL;
- np->wn_byte = word[i];
-
- // If "node" is NULL this is a new child or the end of the sibling
- // list: ref count is one. Otherwise use ref count of sibling and
- // make ref count of sibling one (matters when inserting in front
- // of the list of siblings).
- if (node == NULL)
- np->wn_refs = 1;
- else {
- np->wn_refs = node->wn_refs;
- node->wn_refs = 1;
- }
- if (prev != NULL)
- *prev = np;
- np->wn_sibling = node;
- node = np;
- }
-
- if (word[i] == NUL) {
- node->wn_flags = flags;
- node->wn_region |= region;
- node->wn_affixID = affixID;
- break;
- }
- prev = &node->wn_child;
- node = *prev;
- }
-#ifdef SPELL_PRINTTREE
- smsg((char_u *)"Added \"%s\"", word);
- spell_print_tree(root->wn_sibling);
-#endif
-
- // count nr of words added since last message
- ++spin->si_msg_count;
-
- if (spin->si_compress_cnt > 1) {
- if (--spin->si_compress_cnt == 1)
- // Did enough words to lower the block count limit.
- spin->si_blocks_cnt += compress_inc;
- }
-
- // When we have allocated lots of memory we need to compress the word tree
- // to free up some room. But compression is slow, and we might actually
- // need that room, thus only compress in the following situations:
- // 1. When not compressed before (si_compress_cnt == 0): when using
- // "compress_start" blocks.
- // 2. When compressed before and used "compress_inc" blocks before
- // adding "compress_added" words (si_compress_cnt > 1).
- // 3. When compressed before, added "compress_added" words
- // (si_compress_cnt == 1) and the number of free nodes drops below the
- // maximum word length.
-#ifndef SPELL_COMPRESS_ALLWAYS
- if (spin->si_compress_cnt == 1 // NOLINT(readability/braces)
- ? spin->si_free_count < MAXWLEN
- : spin->si_blocks_cnt >= compress_start)
-#endif
- {
- // Decrement the block counter. The effect is that we compress again
- // when the freed up room has been used and another "compress_inc"
- // blocks have been allocated. Unless "compress_added" words have
- // been added, then the limit is put back again.
- spin->si_blocks_cnt -= compress_inc;
- spin->si_compress_cnt = compress_added;
-
- if (spin->si_verbose) {
- msg_start();
- msg_puts((char_u *)_(msg_compressing));
- msg_clr_eos();
- msg_didout = FALSE;
- msg_col = 0;
- ui_flush();
- }
-
- // Compress both trees. Either they both have many nodes, which makes
- // compression useful, or one of them is small, which means
- // compression goes fast. But when filling the soundfold word tree
- // there is no keep-case tree.
- wordtree_compress(spin, spin->si_foldroot);
- if (affixID >= 0)
- wordtree_compress(spin, spin->si_keeproot);
- }
-
- return OK;
-}
-
-// Check the 'mkspellmem' option. Return FAIL if it's wrong.
-// Sets "sps_flags".
-int spell_check_msm(void)
-{
- char_u *p = p_msm;
- long start = 0;
- long incr = 0;
- long added = 0;
-
- if (!ascii_isdigit(*p))
- return FAIL;
- // block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)
- start = (getdigits_long(&p) * 10) / (SBLOCKSIZE / 102);
- if (*p != ',')
- return FAIL;
- ++p;
- if (!ascii_isdigit(*p))
- return FAIL;
- incr = (getdigits_long(&p) * 102) / (SBLOCKSIZE / 10);
- if (*p != ',')
- return FAIL;
- ++p;
- if (!ascii_isdigit(*p))
- return FAIL;
- added = getdigits_long(&p) * 1024;
- if (*p != NUL)
- return FAIL;
-
- if (start == 0 || incr == 0 || added == 0 || incr > start)
- return FAIL;
-
- compress_start = start;
- compress_inc = incr;
- compress_added = added;
- return OK;
-}
-
-// Get a wordnode_T, either from the list of previously freed nodes or
-// allocate a new one.
-// Returns NULL when out of memory.
-static wordnode_T *get_wordnode(spellinfo_T *spin)
-{
- wordnode_T *n;
-
- if (spin->si_first_free == NULL)
- n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
- else {
- n = spin->si_first_free;
- spin->si_first_free = n->wn_child;
- memset(n, 0, sizeof(wordnode_T));
- --spin->si_free_count;
- }
-#ifdef SPELL_PRINTTREE
- if (n != NULL)
- n->wn_nr = ++spin->si_wordnode_nr;
-#endif
- return n;
-}
-
-// Decrement the reference count on a node (which is the head of a list of
-// siblings). If the reference count becomes zero free the node and its
-// siblings.
-// Returns the number of nodes actually freed.
-static int deref_wordnode(spellinfo_T *spin, wordnode_T *node)
-{
- wordnode_T *np;
- int cnt = 0;
-
- if (--node->wn_refs == 0) {
- for (np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_child != NULL)
- cnt += deref_wordnode(spin, np->wn_child);
- free_wordnode(spin, np);
- ++cnt;
- }
- ++cnt; // length field
- }
- return cnt;
-}
-
-// Free a wordnode_T for re-use later.
-// Only the "wn_child" field becomes invalid.
-static void free_wordnode(spellinfo_T *spin, wordnode_T *n)
-{
- n->wn_child = spin->si_first_free;
- spin->si_first_free = n;
- ++spin->si_free_count;
-}
-
-// Compress a tree: find tails that are identical and can be shared.
-static void wordtree_compress(spellinfo_T *spin, wordnode_T *root)
-{
- hashtab_T ht;
- int n;
- int tot = 0;
- int perc;
-
- // Skip the root itself, it's not actually used. The first sibling is the
- // start of the tree.
- if (root->wn_sibling != NULL) {
- hash_init(&ht);
- n = node_compress(spin, root->wn_sibling, &ht, &tot);
-
-#ifndef SPELL_PRINTTREE
- if (spin->si_verbose || p_verbose > 2)
-#endif
- {
- if (tot > 1000000)
- perc = (tot - n) / (tot / 100);
- else if (tot == 0)
- perc = 0;
- else
- perc = (tot - n) * 100 / tot;
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Compressed %d of %d nodes; %d (%d%%) remaining"),
- n, tot, tot - n, perc);
- spell_message(spin, IObuff);
- }
-#ifdef SPELL_PRINTTREE
- spell_print_tree(root->wn_sibling);
-#endif
- hash_clear(&ht);
- }
-}
-
-// Compress a node, its siblings and its children, depth first.
-// Returns the number of compressed nodes.
-static int
-node_compress (
- spellinfo_T *spin,
- wordnode_T *node,
- hashtab_T *ht,
- int *tot // total count of nodes before compressing,
- // incremented while going through the tree
-)
-{
- wordnode_T *np;
- wordnode_T *tp;
- wordnode_T *child;
- hash_T hash;
- hashitem_T *hi;
- int len = 0;
- unsigned nr, n;
- int compressed = 0;
-
- // Go through the list of siblings. Compress each child and then try
- // finding an identical child to replace it.
- // Note that with "child" we mean not just the node that is pointed to,
- // but the whole list of siblings of which the child node is the first.
- for (np = node; np != NULL && !got_int; np = np->wn_sibling) {
- ++len;
- if ((child = np->wn_child) != NULL) {
- // Compress the child first. This fills hashkey.
- compressed += node_compress(spin, child, ht, tot);
-
- // Try to find an identical child.
- hash = hash_hash(child->wn_u1.hashkey);
- hi = hash_lookup(ht, child->wn_u1.hashkey, hash);
- if (!HASHITEM_EMPTY(hi)) {
- // There are children we encountered before with a hash value
- // identical to the current child. Now check if there is one
- // that is really identical.
- for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next)
- if (node_equal(child, tp)) {
- // Found one! Now use that child in place of the
- // current one. This means the current child and all
- // its siblings is unlinked from the tree.
- ++tp->wn_refs;
- compressed += deref_wordnode(spin, child);
- np->wn_child = tp;
- break;
- }
- if (tp == NULL) {
- // No other child with this hash value equals the child of
- // the node, add it to the linked list after the first
- // item.
- tp = HI2WN(hi);
- child->wn_u2.next = tp->wn_u2.next;
- tp->wn_u2.next = child;
- }
- } else
- // No other child has this hash value, add it to the
- // hashtable.
- hash_add_item(ht, hi, child->wn_u1.hashkey, hash);
- }
- }
- *tot += len + 1; // add one for the node that stores the length
-
- // Make a hash key for the node and its siblings, so that we can quickly
- // find a lookalike node. This must be done after compressing the sibling
- // list, otherwise the hash key would become invalid by the compression.
- node->wn_u1.hashkey[0] = len;
- nr = 0;
- for (np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_byte == NUL)
- // end node: use wn_flags, wn_region and wn_affixID
- n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16);
- else
- // byte node: use the byte value and the child pointer
- n = (unsigned)(np->wn_byte + ((uintptr_t)np->wn_child << 8));
- nr = nr * 101 + n;
- }
-
- // Avoid NUL bytes, it terminates the hash key.
- n = nr & 0xff;
- node->wn_u1.hashkey[1] = n == 0 ? 1 : n;
- n = (nr >> 8) & 0xff;
- node->wn_u1.hashkey[2] = n == 0 ? 1 : n;
- n = (nr >> 16) & 0xff;
- node->wn_u1.hashkey[3] = n == 0 ? 1 : n;
- n = (nr >> 24) & 0xff;
- node->wn_u1.hashkey[4] = n == 0 ? 1 : n;
- node->wn_u1.hashkey[5] = NUL;
-
- // Check for CTRL-C pressed now and then.
- fast_breakcheck();
-
- return compressed;
-}
-
-// Returns true when two nodes have identical siblings and children.
-static bool node_equal(wordnode_T *n1, wordnode_T *n2)
-{
- wordnode_T *p1;
- wordnode_T *p2;
-
- for (p1 = n1, p2 = n2; p1 != NULL && p2 != NULL;
- p1 = p1->wn_sibling, p2 = p2->wn_sibling)
- if (p1->wn_byte != p2->wn_byte
- || (p1->wn_byte == NUL
- ? (p1->wn_flags != p2->wn_flags
- || p1->wn_region != p2->wn_region
- || p1->wn_affixID != p2->wn_affixID)
- : (p1->wn_child != p2->wn_child)))
- break;
-
- return p1 == NULL && p2 == NULL;
-}
-
-
-// Function given to qsort() to sort the REP items on "from" string.
-static int rep_compare(const void *s1, const void *s2)
-{
- fromto_T *p1 = (fromto_T *)s1;
- fromto_T *p2 = (fromto_T *)s2;
-
- return STRCMP(p1->ft_from, p2->ft_from);
-}
-
-// Write the Vim .spl file "fname".
-// Return OK/FAIL.
-static int write_vim_spell(spellinfo_T *spin, char_u *fname)
-{
- int retval = OK;
- int regionmask;
-
- FILE *fd = mch_fopen((char *)fname, "w");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return FAIL;
- }
-
- // <HEADER>: <fileID> <versionnr>
- // <fileID>
- size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd);
- if (fwv != (size_t)1)
- // Catch first write error, don't try writing more.
- goto theend;
-
- putc(VIMSPELLVERSION, fd); // <versionnr>
-
- // <SECTIONS>: <section> ... <sectionend>
-
- // SN_INFO: <infotext>
- if (spin->si_info != NULL) {
- putc(SN_INFO, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- size_t i = STRLEN(spin->si_info);
- put_bytes(fd, i, 4); // <sectionlen>
- fwv &= fwrite(spin->si_info, i, 1, fd); // <infotext>
- }
-
- // SN_REGION: <regionname> ...
- // Write the region names only if there is more than one.
- if (spin->si_region_count > 1) {
- putc(SN_REGION, fd); // <sectionID>
- putc(SNF_REQUIRED, fd); // <sectionflags>
- size_t l = (size_t)spin->si_region_count * 2;
- put_bytes(fd, l, 4); // <sectionlen>
- fwv &= fwrite(spin->si_region_name, l, 1, fd);
- // <regionname> ...
- regionmask = (1 << spin->si_region_count) - 1;
- } else
- regionmask = 0;
-
- // SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars>
- //
- // The table with character flags and the table for case folding.
- // This makes sure the same characters are recognized as word characters
- // when generating an when using a spell file.
- // Skip this for ASCII, the table may conflict with the one used for
- // 'encoding'.
- // Also skip this for an .add.spl file, the main spell file must contain
- // the table (avoids that it conflicts). File is shorter too.
- if (!spin->si_ascii && !spin->si_add) {
- char_u folchars[128 * 8];
- int flags;
-
- putc(SN_CHARFLAGS, fd); // <sectionID>
- putc(SNF_REQUIRED, fd); // <sectionflags>
-
- // Form the <folchars> string first, we need to know its length.
- size_t l = 0;
- for (size_t i = 128; i < 256; ++i) {
- if (has_mbyte)
- l += (size_t)mb_char2bytes(spelltab.st_fold[i], folchars + l);
- else
- folchars[l++] = spelltab.st_fold[i];
- }
- put_bytes(fd, 1 + 128 + 2 + l, 4); // <sectionlen>
-
- fputc(128, fd); // <charflagslen>
- for (size_t i = 128; i < 256; ++i) {
- flags = 0;
- if (spelltab.st_isw[i])
- flags |= CF_WORD;
- if (spelltab.st_isu[i])
- flags |= CF_UPPER;
- fputc(flags, fd); // <charflags>
- }
-
- put_bytes(fd, l, 2); // <folcharslen>
- fwv &= fwrite(folchars, l, 1, fd); // <folchars>
- }
-
- // SN_MIDWORD: <midword>
- if (spin->si_midword != NULL) {
- putc(SN_MIDWORD, fd); // <sectionID>
- putc(SNF_REQUIRED, fd); // <sectionflags>
-
- size_t i = STRLEN(spin->si_midword);
- put_bytes(fd, i, 4); // <sectionlen>
- fwv &= fwrite(spin->si_midword, i, 1, fd);
- // <midword>
- }
-
- // SN_PREFCOND: <prefcondcnt> <prefcond> ...
- if (!GA_EMPTY(&spin->si_prefcond)) {
- putc(SN_PREFCOND, fd); // <sectionID>
- putc(SNF_REQUIRED, fd); // <sectionflags>
-
- size_t l = (size_t)write_spell_prefcond(NULL, &spin->si_prefcond);
- put_bytes(fd, l, 4); // <sectionlen>
-
- write_spell_prefcond(fd, &spin->si_prefcond);
- }
-
- // SN_REP: <repcount> <rep> ...
- // SN_SAL: <salflags> <salcount> <sal> ...
- // SN_REPSAL: <repcount> <rep> ...
-
- // round 1: SN_REP section
- // round 2: SN_SAL section (unless SN_SOFO is used)
- // round 3: SN_REPSAL section
- for (unsigned int round = 1; round <= 3; ++round) {
- garray_T *gap;
- if (round == 1)
- gap = &spin->si_rep;
- else if (round == 2) {
- // Don't write SN_SAL when using a SN_SOFO section
- if (spin->si_sofofr != NULL && spin->si_sofoto != NULL)
- continue;
- gap = &spin->si_sal;
- } else
- gap = &spin->si_repsal;
-
- // Don't write the section if there are no items.
- if (GA_EMPTY(gap))
- continue;
-
- // Sort the REP/REPSAL items.
- if (round != 2)
- qsort(gap->ga_data, (size_t)gap->ga_len,
- sizeof(fromto_T), rep_compare);
-
- int i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL);
- putc(i, fd); // <sectionID>
-
- // This is for making suggestions, section is not required.
- putc(0, fd); // <sectionflags>
-
- // Compute the length of what follows.
- size_t l = 2; // count <repcount> or <salcount>
- assert(gap->ga_len >= 0);
- for (size_t i = 0; i < (size_t)gap->ga_len; ++i) {
- fromto_T *ftp = &((fromto_T *)gap->ga_data)[i];
- l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from>
- l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to>
- }
- if (round == 2)
- ++l; // count <salflags>
- put_bytes(fd, l, 4); // <sectionlen>
-
- if (round == 2) {
- int i = 0;
- if (spin->si_followup)
- i |= SAL_F0LLOWUP;
- if (spin->si_collapse)
- i |= SAL_COLLAPSE;
- if (spin->si_rem_accents)
- i |= SAL_REM_ACCENTS;
- putc(i, fd); // <salflags>
- }
-
- put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <repcount> or <salcount>
- for (size_t i = 0; i < (size_t)gap->ga_len; ++i) {
- // <rep> : <repfromlen> <repfrom> <reptolen> <repto>
- // <sal> : <salfromlen> <salfrom> <saltolen> <salto>
- fromto_T *ftp = &((fromto_T *)gap->ga_data)[i];
- for (unsigned int rr = 1; rr <= 2; ++rr) {
- char_u *p = rr == 1 ? ftp->ft_from : ftp->ft_to;
- l = STRLEN(p);
- assert(l < INT_MAX);
- putc((int)l, fd);
- if (l > 0)
- fwv &= fwrite(p, l, 1, fd);
- }
- }
-
- }
-
- // SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
- // This is for making suggestions, section is not required.
- if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) {
- putc(SN_SOFO, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- size_t l = STRLEN(spin->si_sofofr);
- put_bytes(fd, l + STRLEN(spin->si_sofoto) + 4, 4); // <sectionlen>
-
- put_bytes(fd, l, 2); // <sofofromlen>
- fwv &= fwrite(spin->si_sofofr, l, 1, fd); // <sofofrom>
-
- l = STRLEN(spin->si_sofoto);
- put_bytes(fd, l, 2); // <sofotolen>
- fwv &= fwrite(spin->si_sofoto, l, 1, fd); // <sofoto>
- }
-
- // SN_WORDS: <word> ...
- // This is for making suggestions, section is not required.
- if (spin->si_commonwords.ht_used > 0) {
- putc(SN_WORDS, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- // round 1: count the bytes
- // round 2: write the bytes
- for (unsigned int round = 1; round <= 2; ++round) {
- size_t todo;
- size_t len = 0;
- hashitem_T *hi;
-
- todo = spin->si_commonwords.ht_used;
- for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi)
- if (!HASHITEM_EMPTY(hi)) {
- size_t l = STRLEN(hi->hi_key) + 1;
- len += l;
- if (round == 2) // <word>
- fwv &= fwrite(hi->hi_key, l, 1, fd);
- --todo;
- }
- if (round == 1)
- put_bytes(fd, len, 4); // <sectionlen>
- }
- }
-
- // SN_MAP: <mapstr>
- // This is for making suggestions, section is not required.
- if (!GA_EMPTY(&spin->si_map)) {
- putc(SN_MAP, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- size_t l = (size_t)spin->si_map.ga_len;
- put_bytes(fd, l, 4); // <sectionlen>
- fwv &= fwrite(spin->si_map.ga_data, l, 1, fd); // <mapstr>
- }
-
- // SN_SUGFILE: <timestamp>
- // This is used to notify that a .sug file may be available and at the
- // same time allows for checking that a .sug file that is found matches
- // with this .spl file. That's because the word numbers must be exactly
- // right.
- if (!spin->si_nosugfile
- && (!GA_EMPTY(&spin->si_sal)
- || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) {
- putc(SN_SUGFILE, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- put_bytes(fd, 8, 4); // <sectionlen>
-
- // Set si_sugtime and write it to the file.
- spin->si_sugtime = time(NULL);
- put_time(fd, spin->si_sugtime); // <timestamp>
- }
-
- // SN_NOSPLITSUGS: nothing
- // This is used to notify that no suggestions with word splits are to be
- // made.
- if (spin->si_nosplitsugs) {
- putc(SN_NOSPLITSUGS, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- put_bytes(fd, 0, 4); // <sectionlen>
- }
-
- // SN_NOCOMPUNDSUGS: nothing
- // This is used to notify that no suggestions with compounds are to be
- // made.
- if (spin->si_nocompoundsugs) {
- putc(SN_NOCOMPOUNDSUGS, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
- put_bytes(fd, 0, 4); // <sectionlen>
- }
-
- // SN_COMPOUND: compound info.
- // We don't mark it required, when not supported all compound words will
- // be bad words.
- if (spin->si_compflags != NULL) {
- putc(SN_COMPOUND, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- size_t l = STRLEN(spin->si_compflags);
- assert(spin->si_comppat.ga_len >= 0);
- for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) {
- l += STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1;
- }
- put_bytes(fd, l + 7, 4); // <sectionlen>
-
- putc(spin->si_compmax, fd); // <compmax>
- putc(spin->si_compminlen, fd); // <compminlen>
- putc(spin->si_compsylmax, fd); // <compsylmax>
- putc(0, fd); // for Vim 7.0b compatibility
- putc(spin->si_compoptions, fd); // <compoptions>
- put_bytes(fd, (uintmax_t)spin->si_comppat.ga_len, 2); // <comppatcount>
- for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) {
- char_u *p = ((char_u **)(spin->si_comppat.ga_data))[i];
- assert(STRLEN(p) < INT_MAX);
- putc((int)STRLEN(p), fd); // <comppatlen>
- fwv &= fwrite(p, STRLEN(p), 1, fd); // <comppattext>
- }
- // <compflags>
- fwv &= fwrite(spin->si_compflags, STRLEN(spin->si_compflags), 1, fd);
- }
-
- // SN_NOBREAK: NOBREAK flag
- if (spin->si_nobreak) {
- putc(SN_NOBREAK, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- // It's empty, the presence of the section flags the feature.
- put_bytes(fd, 0, 4); // <sectionlen>
- }
-
- // SN_SYLLABLE: syllable info.
- // We don't mark it required, when not supported syllables will not be
- // counted.
- if (spin->si_syllable != NULL) {
- putc(SN_SYLLABLE, fd); // <sectionID>
- putc(0, fd); // <sectionflags>
-
- size_t l = STRLEN(spin->si_syllable);
- put_bytes(fd, l, 4); // <sectionlen>
- fwv &= fwrite(spin->si_syllable, l, 1, fd); // <syllable>
- }
-
- // end of <SECTIONS>
- putc(SN_END, fd); // <sectionend>
-
-
- // <LWORDTREE> <KWORDTREE> <PREFIXTREE>
- spin->si_memtot = 0;
- for (unsigned int round = 1; round <= 3; ++round) {
- wordnode_T *tree;
- if (round == 1)
- tree = spin->si_foldroot->wn_sibling;
- else if (round == 2)
- tree = spin->si_keeproot->wn_sibling;
- else
- tree = spin->si_prefroot->wn_sibling;
-
- // Clear the index and wnode fields in the tree.
- clear_node(tree);
-
- // Count the number of nodes. Needed to be able to allocate the
- // memory when reading the nodes. Also fills in index for shared
- // nodes.
- size_t nodecount = (size_t)put_node(NULL, tree, 0, regionmask, round == 3);
-
- // number of nodes in 4 bytes
- put_bytes(fd, nodecount, 4); // <nodecount>
- assert(nodecount + nodecount * sizeof(int) < INT_MAX);
- spin->si_memtot += (int)(nodecount + nodecount * sizeof(int));
-
- // Write the nodes.
- (void)put_node(fd, tree, 0, regionmask, round == 3);
- }
-
- // Write another byte to check for errors (file system full).
- if (putc(0, fd) == EOF)
- retval = FAIL;
-theend:
- if (fclose(fd) == EOF)
- retval = FAIL;
-
- if (fwv != (size_t)1)
- retval = FAIL;
- if (retval == FAIL)
- EMSG(_(e_write));
-
- return retval;
-}
-
-// Clear the index and wnode fields of "node", it siblings and its
-// children. This is needed because they are a union with other items to save
-// space.
-static void clear_node(wordnode_T *node)
-{
- wordnode_T *np;
-
- if (node != NULL)
- for (np = node; np != NULL; np = np->wn_sibling) {
- np->wn_u1.index = 0;
- np->wn_u2.wnode = NULL;
-
- if (np->wn_byte != NUL)
- clear_node(np->wn_child);
- }
-}
-
-
-// Dump a word tree at node "node".
-//
-// This first writes the list of possible bytes (siblings). Then for each
-// byte recursively write the children.
-//
-// NOTE: The code here must match the code in read_tree_node(), since
-// assumptions are made about the indexes (so that we don't have to write them
-// in the file).
-//
-// Returns the number of nodes used.
-static int
-put_node (
- FILE *fd, // NULL when only counting
- wordnode_T *node,
- int idx,
- int regionmask,
- bool prefixtree // true for PREFIXTREE
-)
-{
- // If "node" is zero the tree is empty.
- if (node == NULL)
- return 0;
-
- // Store the index where this node is written.
- node->wn_u1.index = idx;
-
- // Count the number of siblings.
- int siblingcount = 0;
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
- ++siblingcount;
-
- // Write the sibling count.
- if (fd != NULL)
- putc(siblingcount, fd); // <siblingcount>
-
- // Write each sibling byte and optionally extra info.
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
- if (np->wn_byte == 0) {
- if (fd != NULL) {
- // For a NUL byte (end of word) write the flags etc.
- if (prefixtree) {
- // In PREFIXTREE write the required affixID and the
- // associated condition nr (stored in wn_region). The
- // byte value is misused to store the "rare" and "not
- // combining" flags
- if (np->wn_flags == (uint16_t)PFX_FLAGS)
- putc(BY_NOFLAGS, fd); // <byte>
- else {
- putc(BY_FLAGS, fd); // <byte>
- putc(np->wn_flags, fd); // <pflags>
- }
- putc(np->wn_affixID, fd); // <affixID>
- put_bytes(fd, (uintmax_t)np->wn_region, 2); // <prefcondnr>
- } else {
- // For word trees we write the flag/region items.
- int flags = np->wn_flags;
- if (regionmask != 0 && np->wn_region != regionmask)
- flags |= WF_REGION;
- if (np->wn_affixID != 0)
- flags |= WF_AFX;
- if (flags == 0) {
- // word without flags or region
- putc(BY_NOFLAGS, fd); // <byte>
- } else {
- if (np->wn_flags >= 0x100) {
- putc(BY_FLAGS2, fd); // <byte>
- putc(flags, fd); // <flags>
- putc((int)((unsigned)flags >> 8), fd); // <flags2>
- } else {
- putc(BY_FLAGS, fd); // <byte>
- putc(flags, fd); // <flags>
- }
- if (flags & WF_REGION)
- putc(np->wn_region, fd); // <region>
- if (flags & WF_AFX)
- putc(np->wn_affixID, fd); // <affixID>
- }
- }
- }
- } else {
- if (np->wn_child->wn_u1.index != 0
- && np->wn_child->wn_u2.wnode != node) {
- // The child is written elsewhere, write the reference.
- if (fd != NULL) {
- putc(BY_INDEX, fd); // <byte>
- put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // <nodeidx>
- }
- } else if (np->wn_child->wn_u2.wnode == NULL)
- // We will write the child below and give it an index.
- np->wn_child->wn_u2.wnode = node;
-
- if (fd != NULL)
- if (putc(np->wn_byte, fd) == EOF) { // <byte> or <xbyte>
- EMSG(_(e_write));
- return 0;
- }
- }
- }
-
- // Space used in the array when reading: one for each sibling and one for
- // the count.
- int newindex = idx + siblingcount + 1;
-
- // Recursively dump the children of each sibling.
- for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
- if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node)
- newindex = put_node(fd, np->wn_child, newindex, regionmask,
- prefixtree);
-
- return newindex;
-}
-
-
-// ":mkspell [-ascii] outfile infile ..."
-// ":mkspell [-ascii] addfile"
-void ex_mkspell(exarg_T *eap)
-{
- int fcount;
- char_u **fnames;
- char_u *arg = eap->arg;
- bool ascii = false;
-
- if (STRNCMP(arg, "-ascii", 6) == 0) {
- ascii = true;
- arg = skipwhite(arg + 6);
- }
-
- // Expand all the remaining arguments (e.g., $VIMRUNTIME).
- if (get_arglist_exp(arg, &fcount, &fnames, false) == OK) {
- mkspell(fcount, fnames, ascii, eap->forceit, false);
- FreeWild(fcount, fnames);
- }
-}
-
-// Create the .sug file.
-// Uses the soundfold info in "spin".
-// Writes the file with the name "wfname", with ".spl" changed to ".sug".
-static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
-{
- char_u *fname = NULL;
- int len;
- slang_T *slang;
- bool free_slang = false;
-
- // Read back the .spl file that was written. This fills the required
- // info for soundfolding. This also uses less memory than the
- // pointer-linked version of the trie. And it avoids having two versions
- // of the code for the soundfolding stuff.
- // It might have been done already by spell_reload_one().
- for (slang = first_lang; slang != NULL; slang = slang->sl_next)
- if (path_full_compare(wfname, slang->sl_fname, FALSE) == kEqualFiles)
- break;
- if (slang == NULL) {
- spell_message(spin, (char_u *)_("Reading back spell file..."));
- slang = spell_load_file(wfname, NULL, NULL, false);
- if (slang == NULL)
- return;
- free_slang = true;
- }
-
- // Clear the info in "spin" that is used.
- spin->si_blocks = NULL;
- spin->si_blocks_cnt = 0;
- spin->si_compress_cnt = 0; // will stay at 0 all the time
- spin->si_free_count = 0;
- spin->si_first_free = NULL;
- spin->si_foldwcount = 0;
-
- // Go through the trie of good words, soundfold each word and add it to
- // the soundfold trie.
- spell_message(spin, (char_u *)_("Performing soundfolding..."));
- if (sug_filltree(spin, slang) == FAIL)
- goto theend;
-
- // Create the table which links each soundfold word with a list of the
- // good words it may come from. Creates buffer "spin->si_spellbuf".
- // This also removes the wordnr from the NUL byte entries to make
- // compression possible.
- if (sug_maketable(spin) == FAIL)
- goto theend;
-
- smsg(_("Number of words after soundfolding: %" PRId64),
- (int64_t)spin->si_spellbuf->b_ml.ml_line_count);
-
- // Compress the soundfold trie.
- spell_message(spin, (char_u *)_(msg_compressing));
- wordtree_compress(spin, spin->si_foldroot);
-
- // Write the .sug file.
- // Make the file name by changing ".spl" to ".sug".
- fname = xmalloc(MAXPATHL);
- STRLCPY(fname, wfname, MAXPATHL);
- len = (int)STRLEN(fname);
- fname[len - 2] = 'u';
- fname[len - 1] = 'g';
- sug_write(spin, fname);
-
-theend:
- xfree(fname);
- if (free_slang)
- slang_free(slang);
- free_blocks(spin->si_blocks);
- close_spellbuf(spin->si_spellbuf);
-}
-
-// Build the soundfold trie for language "slang".
-static int sug_filltree(spellinfo_T *spin, slang_T *slang)
-{
- char_u *byts;
- idx_T *idxs;
- int depth;
- idx_T arridx[MAXWLEN];
- int curi[MAXWLEN];
- char_u tword[MAXWLEN];
- char_u tsalword[MAXWLEN];
- int c;
- idx_T n;
- unsigned words_done = 0;
- int wordcount[MAXWLEN];
-
- // We use si_foldroot for the soundfolded trie.
- spin->si_foldroot = wordtree_alloc(spin);
- if (spin->si_foldroot == NULL)
- return FAIL;
-
- // Let tree_add_word() know we're adding to the soundfolded tree
- spin->si_sugtree = true;
-
- // Go through the whole case-folded tree, soundfold each word and put it
- // in the trie.
- byts = slang->sl_fbyts;
- idxs = slang->sl_fidxs;
-
- arridx[0] = 0;
- curi[0] = 1;
- wordcount[0] = 0;
-
- depth = 0;
- while (depth >= 0 && !got_int) {
- if (curi[depth] > byts[arridx[depth]]) {
- // Done all bytes at this node, go up one level.
- idxs[arridx[depth]] = wordcount[depth];
- if (depth > 0)
- wordcount[depth - 1] += wordcount[depth];
-
- --depth;
- line_breakcheck();
- } else {
-
- // Do one more byte at this node.
- n = arridx[depth] + curi[depth];
- ++curi[depth];
-
- c = byts[n];
- if (c == 0) {
- // Sound-fold the word.
- tword[depth] = NUL;
- spell_soundfold(slang, tword, true, tsalword);
-
- // We use the "flags" field for the MSB of the wordnr,
- // "region" for the LSB of the wordnr.
- if (tree_add_word(spin, tsalword, spin->si_foldroot,
- words_done >> 16, words_done & 0xffff,
- 0) == FAIL)
- return FAIL;
-
- ++words_done;
- ++wordcount[depth];
-
- // Reset the block count each time to avoid compression
- // kicking in.
- spin->si_blocks_cnt = 0;
-
- // Skip over any other NUL bytes (same word with different
- // flags).
- while (byts[n + 1] == 0) {
- ++n;
- ++curi[depth];
- }
- } else {
- // Normal char, go one level deeper.
- tword[depth++] = c;
- arridx[depth] = idxs[n];
- curi[depth] = 1;
- wordcount[depth] = 0;
- }
- }
- }
-
- smsg(_("Total number of words: %d"), words_done);
-
- return OK;
-}
-
-// Make the table that links each word in the soundfold trie to the words it
-// can be produced from.
-// This is not unlike lines in a file, thus use a memfile to be able to access
-// the table efficiently.
-// Returns FAIL when out of memory.
-static int sug_maketable(spellinfo_T *spin)
-{
- garray_T ga;
- int res = OK;
-
- // Allocate a buffer, open a memline for it and create the swap file
- // (uses a temp file, not a .swp file).
- spin->si_spellbuf = open_spellbuf();
-
- // Use a buffer to store the line info, avoids allocating many small
- // pieces of memory.
- ga_init(&ga, 1, 100);
-
- // recursively go through the tree
- if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1)
- res = FAIL;
-
- ga_clear(&ga);
- return res;
-}
-
-// Fill the table for one node and its children.
-// Returns the wordnr at the start of the node.
-// Returns -1 when out of memory.
-static int
-sug_filltable (
- spellinfo_T *spin,
- wordnode_T *node,
- int startwordnr,
- garray_T *gap // place to store line of numbers
-)
-{
- wordnode_T *p, *np;
- int wordnr = startwordnr;
- int nr;
- int prev_nr;
-
- for (p = node; p != NULL; p = p->wn_sibling) {
- if (p->wn_byte == NUL) {
- gap->ga_len = 0;
- prev_nr = 0;
- for (np = p; np != NULL && np->wn_byte == NUL; np = np->wn_sibling) {
- ga_grow(gap, 10);
-
- nr = (np->wn_flags << 16) + (np->wn_region & 0xffff);
- // Compute the offset from the previous nr and store the
- // offset in a way that it takes a minimum number of bytes.
- // It's a bit like utf-8, but without the need to mark
- // following bytes.
- nr -= prev_nr;
- prev_nr += nr;
- gap->ga_len += offset2bytes(nr,
- (char_u *)gap->ga_data + gap->ga_len);
- }
-
- // add the NUL byte
- ((char_u *)gap->ga_data)[gap->ga_len++] = NUL;
-
- if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr,
- gap->ga_data, gap->ga_len, TRUE) == FAIL)
- return -1;
- ++wordnr;
-
- // Remove extra NUL entries, we no longer need them. We don't
- // bother freeing the nodes, the won't be reused anyway.
- while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL)
- p->wn_sibling = p->wn_sibling->wn_sibling;
-
- // Clear the flags on the remaining NUL node, so that compression
- // works a lot better.
- p->wn_flags = 0;
- p->wn_region = 0;
- } else {
- wordnr = sug_filltable(spin, p->wn_child, wordnr, gap);
- if (wordnr == -1)
- return -1;
- }
- }
- return wordnr;
-}
-
-// Convert an offset into a minimal number of bytes.
-// Similar to utf_char2byters, but use 8 bits in followup bytes and avoid NUL
-// bytes.
-static int offset2bytes(int nr, char_u *buf)
-{
- int rem;
- int b1, b2, b3, b4;
-
- // Split the number in parts of base 255. We need to avoid NUL bytes.
- b1 = nr % 255 + 1;
- rem = nr / 255;
- b2 = rem % 255 + 1;
- rem = rem / 255;
- b3 = rem % 255 + 1;
- b4 = rem / 255 + 1;
-
- if (b4 > 1 || b3 > 0x1f) { // 4 bytes
- buf[0] = 0xe0 + b4;
- buf[1] = b3;
- buf[2] = b2;
- buf[3] = b1;
- return 4;
- }
- if (b3 > 1 || b2 > 0x3f ) { // 3 bytes
- buf[0] = 0xc0 + b3;
- buf[1] = b2;
- buf[2] = b1;
- return 3;
- }
- if (b2 > 1 || b1 > 0x7f ) { // 2 bytes
- buf[0] = 0x80 + b2;
- buf[1] = b1;
- return 2;
- }
- // 1 byte
- buf[0] = b1;
- return 1;
-}
// Opposite of offset2bytes().
// "pp" points to the bytes and is advanced over it.
@@ -7443,99 +2498,27 @@ static int bytes2offset(char_u **pp)
return nr;
}
-// Write the .sug file in "fname".
-static void sug_write(spellinfo_T *spin, char_u *fname)
-{
- // Create the file. Note that an existing file is silently overwritten!
- FILE *fd = mch_fopen((char *)fname, "w");
- if (fd == NULL) {
- EMSG2(_(e_notopen), fname);
- return;
- }
-
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Writing suggestion file %s ..."), fname);
- spell_message(spin, IObuff);
-
- // <SUGHEADER>: <fileID> <versionnr> <timestamp>
- if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID>
- EMSG(_(e_write));
- goto theend;
- }
- putc(VIMSUGVERSION, fd); // <versionnr>
-
- // Write si_sugtime to the file.
- put_time(fd, spin->si_sugtime); // <timestamp>
-
- // <SUGWORDTREE>
- spin->si_memtot = 0;
- wordnode_T *tree = spin->si_foldroot->wn_sibling;
-
- // Clear the index and wnode fields in the tree.
- clear_node(tree);
-
- // Count the number of nodes. Needed to be able to allocate the
- // memory when reading the nodes. Also fills in index for shared
- // nodes.
- size_t nodecount = (size_t)put_node(NULL, tree, 0, 0, false);
-
- // number of nodes in 4 bytes
- put_bytes(fd, nodecount, 4); // <nodecount>
- assert(nodecount + nodecount * sizeof(int) < INT_MAX);
- spin->si_memtot += (int)(nodecount + nodecount * sizeof(int));
-
- // Write the nodes.
- (void)put_node(fd, tree, 0, 0, false);
-
- // <SUGTABLE>: <sugwcount> <sugline> ...
- linenr_T wcount = spin->si_spellbuf->b_ml.ml_line_count;
- assert(wcount >= 0);
- put_bytes(fd, (uintmax_t)wcount, 4); // <sugwcount>
-
- for (linenr_T lnum = 1; lnum <= wcount; ++lnum) {
- // <sugline>: <sugnr> ... NUL
- char_u *line = ml_get_buf(spin->si_spellbuf, lnum, FALSE);
- size_t len = STRLEN(line) + 1;
- if (fwrite(line, len, 1, fd) == 0) {
- EMSG(_(e_write));
- goto theend;
- }
- assert((size_t)spin->si_memtot + len <= INT_MAX);
- spin->si_memtot += (int)len;
- }
-
- // Write another byte to check for errors.
- if (putc(0, fd) == EOF)
- EMSG(_(e_write));
-
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
- spell_message(spin, IObuff);
-
-theend:
- // close the file
- fclose(fd);
-}
-
// Open a spell buffer. This is a nameless buffer that is not in the buffer
// list and only contains text lines. Can use a swapfile to reduce memory
// use.
// Most other fields are invalid! Esp. watch out for string options being
// NULL and there is no undo info.
-static buf_T *open_spellbuf(void)
+buf_T *open_spellbuf(void)
{
buf_T *buf = xcalloc(1, sizeof(buf_T));
buf->b_spell = true;
buf->b_p_swf = true; // may create a swap file
- ml_open(buf);
+ if (ml_open(buf) == FAIL) {
+ ELOG("Error opening a new memline");
+ }
ml_open_file(buf); // create swap file now
return buf;
}
// Close the buffer used for spell info.
-static void close_spellbuf(buf_T *buf)
+void close_spellbuf(buf_T *buf)
{
if (buf != NULL) {
ml_close(buf, TRUE);
@@ -7543,471 +2526,8 @@ static void close_spellbuf(buf_T *buf)
}
}
-
-// Create a Vim spell file from one or more word lists.
-// "fnames[0]" is the output file name.
-// "fnames[fcount - 1]" is the last input file name.
-// Exception: when "fnames[0]" ends in ".add" it's used as the input file name
-// and ".spl" is appended to make the output file name.
-static void
-mkspell (
- int fcount,
- char_u **fnames,
- bool ascii, // -ascii argument given
- bool over_write, // overwrite existing output file
- bool added_word // invoked through "zg"
-)
-{
- char_u *fname = NULL;
- char_u *wfname;
- char_u **innames;
- int incount;
- afffile_T *(afile[8]);
- int i;
- int len;
- bool error = false;
- spellinfo_T spin;
-
- memset(&spin, 0, sizeof(spin));
- spin.si_verbose = !added_word;
- spin.si_ascii = ascii;
- spin.si_followup = true;
- spin.si_rem_accents = true;
- ga_init(&spin.si_rep, (int)sizeof(fromto_T), 20);
- ga_init(&spin.si_repsal, (int)sizeof(fromto_T), 20);
- ga_init(&spin.si_sal, (int)sizeof(fromto_T), 20);
- ga_init(&spin.si_map, (int)sizeof(char_u), 100);
- ga_init(&spin.si_comppat, (int)sizeof(char_u *), 20);
- ga_init(&spin.si_prefcond, (int)sizeof(char_u *), 50);
- hash_init(&spin.si_commonwords);
- spin.si_newcompID = 127; // start compound ID at first maximum
-
- // default: fnames[0] is output file, following are input files
- innames = &fnames[1];
- incount = fcount - 1;
-
- wfname = xmalloc(MAXPATHL);
-
- if (fcount >= 1) {
- len = (int)STRLEN(fnames[0]);
- if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) {
- // For ":mkspell path/en.latin1.add" output file is
- // "path/en.latin1.add.spl".
- innames = &fnames[0];
- incount = 1;
- vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]);
- } else if (fcount == 1) {
- // For ":mkspell path/vim" output file is "path/vim.latin1.spl".
- innames = &fnames[0];
- incount = 1;
- vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
- fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
- } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) {
- // Name ends in ".spl", use as the file name.
- STRLCPY(wfname, fnames[0], MAXPATHL);
- } else
- // Name should be language, make the file name from it.
- vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
- fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
-
- // Check for .ascii.spl.
- if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL)
- spin.si_ascii = true;
-
- // Check for .add.spl.
- if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL)
- spin.si_add = true;
- }
-
- if (incount <= 0)
- EMSG(_(e_invarg)); // need at least output and input names
- else if (vim_strchr(path_tail(wfname), '_') != NULL)
- EMSG(_("E751: Output file name must not have region name"));
- else if (incount > 8)
- EMSG(_("E754: Only up to 8 regions supported"));
- else {
- // Check for overwriting before doing things that may take a lot of
- // time.
- if (!over_write && os_path_exists(wfname)) {
- EMSG(_(e_exists));
- goto theend;
- }
- if (os_isdir(wfname)) {
- EMSG2(_(e_isadir2), wfname);
- goto theend;
- }
-
- fname = xmalloc(MAXPATHL);
-
- // Init the aff and dic pointers.
- // Get the region names if there are more than 2 arguments.
- for (i = 0; i < incount; ++i) {
- afile[i] = NULL;
-
- if (incount > 1) {
- len = (int)STRLEN(innames[i]);
- if (STRLEN(path_tail(innames[i])) < 5
- || innames[i][len - 3] != '_') {
- EMSG2(_("E755: Invalid region in %s"), innames[i]);
- goto theend;
- }
- spin.si_region_name[i * 2] = TOLOWER_ASC(innames[i][len - 2]);
- spin.si_region_name[i * 2 + 1] =
- TOLOWER_ASC(innames[i][len - 1]);
- }
- }
- spin.si_region_count = incount;
-
- spin.si_foldroot = wordtree_alloc(&spin);
- spin.si_keeproot = wordtree_alloc(&spin);
- spin.si_prefroot = wordtree_alloc(&spin);
- if (spin.si_foldroot == NULL
- || spin.si_keeproot == NULL
- || spin.si_prefroot == NULL) {
- free_blocks(spin.si_blocks);
- goto theend;
- }
-
- // When not producing a .add.spl file clear the character table when
- // we encounter one in the .aff file. This means we dump the current
- // one in the .spl file if the .aff file doesn't define one. That's
- // better than guessing the contents, the table will match a
- // previously loaded spell file.
- if (!spin.si_add)
- spin.si_clear_chartab = true;
-
- // Read all the .aff and .dic files.
- // Text is converted to 'encoding'.
- // Words are stored in the case-folded and keep-case trees.
- for (i = 0; i < incount && !error; ++i) {
- spin.si_conv.vc_type = CONV_NONE;
- spin.si_region = 1 << i;
-
- vim_snprintf((char *)fname, MAXPATHL, "%s.aff", innames[i]);
- if (os_path_exists(fname)) {
- // Read the .aff file. Will init "spin->si_conv" based on the
- // "SET" line.
- afile[i] = spell_read_aff(&spin, fname);
- if (afile[i] == NULL)
- error = true;
- else {
- // Read the .dic file and store the words in the trees.
- vim_snprintf((char *)fname, MAXPATHL, "%s.dic",
- innames[i]);
- if (spell_read_dic(&spin, fname, afile[i]) == FAIL)
- error = true;
- }
- } else {
- // No .aff file, try reading the file as a word list. Store
- // the words in the trees.
- if (spell_read_wordfile(&spin, innames[i]) == FAIL)
- error = true;
- }
-
- // Free any conversion stuff.
- convert_setup(&spin.si_conv, NULL, NULL);
- }
-
- if (spin.si_compflags != NULL && spin.si_nobreak)
- MSG(_("Warning: both compounding and NOBREAK specified"));
-
- if (!error && !got_int) {
- // Combine tails in the tree.
- spell_message(&spin, (char_u *)_(msg_compressing));
- wordtree_compress(&spin, spin.si_foldroot);
- wordtree_compress(&spin, spin.si_keeproot);
- wordtree_compress(&spin, spin.si_prefroot);
- }
-
- if (!error && !got_int) {
- // Write the info in the spell file.
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Writing spell file %s ..."), wfname);
- spell_message(&spin, IObuff);
-
- error = write_vim_spell(&spin, wfname) == FAIL;
-
- spell_message(&spin, (char_u *)_("Done!"));
- vim_snprintf((char *)IObuff, IOSIZE,
- _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
- spell_message(&spin, IObuff);
-
- // If the file is loaded need to reload it.
- if (!error)
- spell_reload_one(wfname, added_word);
- }
-
- // Free the allocated memory.
- ga_clear(&spin.si_rep);
- ga_clear(&spin.si_repsal);
- ga_clear(&spin.si_sal);
- ga_clear(&spin.si_map);
- ga_clear(&spin.si_comppat);
- ga_clear(&spin.si_prefcond);
- hash_clear_all(&spin.si_commonwords, 0);
-
- // Free the .aff file structures.
- for (i = 0; i < incount; ++i)
- if (afile[i] != NULL)
- spell_free_aff(afile[i]);
-
- // Free all the bits and pieces at once.
- free_blocks(spin.si_blocks);
-
- // If there is soundfolding info and no NOSUGFILE item create the
- // .sug file with the soundfolded word trie.
- if (spin.si_sugtime != 0 && !error && !got_int)
- spell_make_sugfile(&spin, wfname);
-
- }
-
-theend:
- xfree(fname);
- xfree(wfname);
-}
-
-// Display a message for spell file processing when 'verbose' is set or using
-// ":mkspell". "str" can be IObuff.
-static void spell_message(spellinfo_T *spin, char_u *str)
-{
- if (spin->si_verbose || p_verbose > 2) {
- if (!spin->si_verbose)
- verbose_enter();
- MSG(str);
- ui_flush();
- if (!spin->si_verbose)
- verbose_leave();
- }
-}
-
-// ":[count]spellgood {word}"
-// ":[count]spellwrong {word}"
-// ":[count]spellundo {word}"
-void ex_spell(exarg_T *eap)
-{
- spell_add_word(eap->arg, (int)STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong,
- eap->forceit ? 0 : (int)eap->line2,
- eap->cmdidx == CMD_spellundo);
-}
-
-// Add "word[len]" to 'spellfile' as a good or bad word.
-void
-spell_add_word (
- char_u *word,
- int len,
- int bad,
- int idx, // "zG" and "zW": zero, otherwise index in
- // 'spellfile'
- bool undo // true for "zug", "zuG", "zuw" and "zuW"
-)
-{
- FILE *fd = NULL;
- buf_T *buf = NULL;
- bool new_spf = false;
- char_u *fname;
- char_u *fnamebuf = NULL;
- char_u line[MAXWLEN * 2];
- long fpos, fpos_next = 0;
- int i;
- char_u *spf;
-
- if (idx == 0) { // use internal wordlist
- if (int_wordlist == NULL) {
- int_wordlist = vim_tempname();
- if (int_wordlist == NULL)
- return;
- }
- fname = int_wordlist;
- } else {
- // If 'spellfile' isn't set figure out a good default value.
- if (*curwin->w_s->b_p_spf == NUL) {
- init_spellfile();
- new_spf = true;
- }
-
- if (*curwin->w_s->b_p_spf == NUL) {
- EMSG2(_(e_notset), "spellfile");
- return;
- }
- fnamebuf = xmalloc(MAXPATHL);
-
- for (spf = curwin->w_s->b_p_spf, i = 1; *spf != NUL; ++i) {
- copy_option_part(&spf, fnamebuf, MAXPATHL, ",");
- if (i == idx)
- break;
- if (*spf == NUL) {
- EMSGN(_("E765: 'spellfile' does not have %" PRId64 " entries"), idx);
- xfree(fnamebuf);
- return;
- }
- }
-
- // Check that the user isn't editing the .add file somewhere.
- buf = buflist_findname_exp(fnamebuf);
- if (buf != NULL && buf->b_ml.ml_mfp == NULL)
- buf = NULL;
- if (buf != NULL && bufIsChanged(buf)) {
- EMSG(_(e_bufloaded));
- xfree(fnamebuf);
- return;
- }
-
- fname = fnamebuf;
- }
-
- if (bad || undo) {
- // When the word appears as good word we need to remove that one,
- // since its flags sort before the one with WF_BANNED.
- fd = mch_fopen((char *)fname, "r");
- if (fd != NULL) {
- while (!vim_fgets(line, MAXWLEN * 2, fd)) {
- fpos = fpos_next;
- fpos_next = ftell(fd);
- if (STRNCMP(word, line, len) == 0
- && (line[len] == '/' || line[len] < ' ')) {
- // Found duplicate word. Remove it by writing a '#' at
- // the start of the line. Mixing reading and writing
- // doesn't work for all systems, close the file first.
- fclose(fd);
- fd = mch_fopen((char *)fname, "r+");
- if (fd == NULL)
- break;
- if (fseek(fd, fpos, SEEK_SET) == 0) {
- fputc('#', fd);
- if (undo) {
- home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
- smsg(_("Word '%.*s' removed from %s"),
- len, word, NameBuff);
- }
- }
- fseek(fd, fpos_next, SEEK_SET);
- }
- }
- if (fd != NULL)
- fclose(fd);
- }
- }
-
- if (!undo) {
- fd = mch_fopen((char *)fname, "a");
- if (fd == NULL && new_spf) {
- char_u *p;
-
- // We just initialized the 'spellfile' option and can't open the
- // file. We may need to create the "spell" directory first. We
- // already checked the runtime directory is writable in
- // init_spellfile().
- if (!dir_of_file_exists(fname) && (p = path_tail_with_sep(fname)) != fname) {
- int c = *p;
-
- // The directory doesn't exist. Try creating it and opening
- // the file again.
- *p = NUL;
- os_mkdir((char *)fname, 0755);
- *p = c;
- fd = mch_fopen((char *)fname, "a");
- }
- }
-
- if (fd == NULL)
- EMSG2(_(e_notopen), fname);
- else {
- if (bad)
- fprintf(fd, "%.*s/!\n", len, word);
- else
- fprintf(fd, "%.*s\n", len, word);
- fclose(fd);
-
- home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
- smsg(_("Word '%.*s' added to %s"), len, word, NameBuff);
- }
- }
-
- if (fd != NULL) {
- // Update the .add.spl file.
- mkspell(1, &fname, false, true, true);
-
- // If the .add file is edited somewhere, reload it.
- if (buf != NULL)
- buf_reload(buf, buf->b_orig_mode);
-
- redraw_all_later(SOME_VALID);
- }
- xfree(fnamebuf);
-}
-
-// Initialize 'spellfile' for the current buffer.
-static void init_spellfile(void)
-{
- char_u *buf;
- int l;
- char_u *fname;
- char_u *rtp;
- char_u *lend;
- bool aspath = false;
- char_u *lstart = curbuf->b_s.b_p_spl;
-
- if (*curwin->w_s->b_p_spl != NUL && !GA_EMPTY(&curwin->w_s->b_langp)) {
- buf = xmalloc(MAXPATHL);
-
- // Find the end of the language name. Exclude the region. If there
- // is a path separator remember the start of the tail.
- for (lend = curwin->w_s->b_p_spl; *lend != NUL
- && vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
- if (vim_ispathsep(*lend)) {
- aspath = true;
- lstart = lend + 1;
- }
-
- // Loop over all entries in 'runtimepath'. Use the first one where we
- // are allowed to write.
- rtp = p_rtp;
- while (*rtp != NUL) {
- if (aspath)
- // Use directory of an entry with path, e.g., for
- // "/dir/lg.utf-8.spl" use "/dir".
- STRLCPY(buf, curbuf->b_s.b_p_spl,
- lstart - curbuf->b_s.b_p_spl);
- else
- // Copy the path from 'runtimepath' to buf[].
- copy_option_part(&rtp, buf, MAXPATHL, ",");
- if (os_file_is_writable((char *)buf) == 2) {
- // Use the first language name from 'spelllang' and the
- // encoding used in the first loaded .spl file.
- if (aspath)
- STRLCPY(buf, curbuf->b_s.b_p_spl,
- lend - curbuf->b_s.b_p_spl + 1);
- else {
- // Create the "spell" directory if it doesn't exist yet.
- l = (int)STRLEN(buf);
- vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
- if (os_file_is_writable((char *)buf) != 2) {
- os_mkdir((char *)buf, 0755);
- }
-
- l = (int)STRLEN(buf);
- vim_snprintf((char *)buf + l, MAXPATHL - l,
- "/%.*s", (int)(lend - lstart), lstart);
- }
- l = (int)STRLEN(buf);
- fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
- ->lp_slang->sl_fname;
- vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
- fname != NULL
- && strstr((char *)path_tail(fname), ".ascii.") != NULL
- ? (char_u *)"ascii" : spell_enc());
- set_option_value((char_u *)"spellfile", 0L, buf, OPT_LOCAL);
- break;
- }
- aspath = false;
- }
-
- xfree(buf);
- }
-}
-
// Init the chartab used for spelling for ASCII.
-static void clear_spell_chartab(spelltab_T *sp)
+void clear_spell_chartab(spelltab_T *sp)
{
int i;
@@ -8035,8 +2555,7 @@ static void clear_spell_chartab(spelltab_T *sp)
}
}
-// Init the chartab used for spelling. Only depends on 'encoding'.
-// Called once while starting up and when 'encoding' changes.
+// Init the chartab used for spelling. Called once while starting up.
// The default is to use isalpha(), but the spell file should define the word
// characters to make it possible that 'encoding' differs from the current
// locale. For utf-8 we don't use isalpha() but our own functions.
@@ -8046,154 +2565,18 @@ void init_spell_chartab(void)
did_set_spelltab = false;
clear_spell_chartab(&spelltab);
- if (enc_dbcs) {
- // DBCS: assume double-wide characters are word characters.
- for (i = 128; i <= 255; ++i)
- if (MB_BYTE2LEN(i) == 2)
- spelltab.st_isw[i] = true;
- } else if (enc_utf8) {
- for (i = 128; i < 256; ++i) {
- int f = utf_fold(i);
- int u = utf_toupper(i);
-
- spelltab.st_isu[i] = utf_isupper(i);
- spelltab.st_isw[i] = spelltab.st_isu[i] || utf_islower(i);
- // The folded/upper-cased value is different between latin1 and
- // utf8 for 0xb5, causing E763 for no good reason. Use the latin1
- // value for utf-8 to avoid this.
- spelltab.st_fold[i] = (f < 256) ? f : i;
- spelltab.st_upper[i] = (u < 256) ? u : i;
- }
- } else {
- // Rough guess: use locale-dependent library functions.
- for (i = 128; i < 256; ++i) {
- if (vim_isupper(i)) {
- spelltab.st_isw[i] = true;
- spelltab.st_isu[i] = true;
- spelltab.st_fold[i] = vim_tolower(i);
- } else if (vim_islower(i)) {
- spelltab.st_isw[i] = true;
- spelltab.st_upper[i] = vim_toupper(i);
- }
- }
- }
-}
+ for (i = 128; i < 256; i++) {
+ int f = utf_fold(i);
+ int u = mb_toupper(i);
-// Set the spell character tables from strings in the affix file.
-static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp)
-{
- // We build the new tables here first, so that we can compare with the
- // previous one.
- spelltab_T new_st;
- char_u *pf = fol, *pl = low, *pu = upp;
- int f, l, u;
-
- clear_spell_chartab(&new_st);
-
- while (*pf != NUL) {
- if (*pl == NUL || *pu == NUL) {
- EMSG(_(e_affform));
- return FAIL;
- }
- f = mb_ptr2char_adv(&pf);
- l = mb_ptr2char_adv(&pl);
- u = mb_ptr2char_adv(&pu);
- // Every character that appears is a word character.
- if (f < 256)
- new_st.st_isw[f] = true;
- if (l < 256)
- new_st.st_isw[l] = true;
- if (u < 256)
- new_st.st_isw[u] = true;
-
- // if "LOW" and "FOL" are not the same the "LOW" char needs
- // case-folding
- if (l < 256 && l != f) {
- if (f >= 256) {
- EMSG(_(e_affrange));
- return FAIL;
- }
- new_st.st_fold[l] = f;
- }
-
- // if "UPP" and "FOL" are not the same the "UPP" char needs
- // case-folding, it's upper case and the "UPP" is the upper case of
- // "FOL" .
- if (u < 256 && u != f) {
- if (f >= 256) {
- EMSG(_(e_affrange));
- return FAIL;
- }
- new_st.st_fold[u] = f;
- new_st.st_isu[u] = true;
- new_st.st_upper[f] = u;
- }
- }
-
- if (*pl != NUL || *pu != NUL) {
- EMSG(_(e_affform));
- return FAIL;
- }
-
- return set_spell_finish(&new_st);
-}
-
-// Set the spell character tables from strings in the .spl file.
-static void
-set_spell_charflags (
- char_u *flags,
- int cnt, // length of "flags"
- char_u *fol
-)
-{
- // We build the new tables here first, so that we can compare with the
- // previous one.
- spelltab_T new_st;
- int i;
- char_u *p = fol;
- int c;
-
- clear_spell_chartab(&new_st);
-
- for (i = 0; i < 128; ++i) {
- if (i < cnt) {
- new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0;
- new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0;
- }
-
- if (*p != NUL) {
- c = mb_ptr2char_adv(&p);
- new_st.st_fold[i + 128] = c;
- if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
- new_st.st_upper[c] = i + 128;
- }
- }
-
- (void)set_spell_finish(&new_st);
-}
-
-static int set_spell_finish(spelltab_T *new_st)
-{
- int i;
-
- if (did_set_spelltab) {
- // check that it's the same table
- for (i = 0; i < 256; ++i) {
- if (spelltab.st_isw[i] != new_st->st_isw[i]
- || spelltab.st_isu[i] != new_st->st_isu[i]
- || spelltab.st_fold[i] != new_st->st_fold[i]
- || spelltab.st_upper[i] != new_st->st_upper[i]) {
- EMSG(_("E763: Word characters differ between spell files"));
- return FAIL;
- }
- }
- } else {
- // copy the new spelltab into the one being used
- spelltab = *new_st;
- did_set_spelltab = true;
+ spelltab.st_isu[i] = mb_isupper(i);
+ spelltab.st_isw[i] = spelltab.st_isu[i] || mb_islower(i);
+ // The folded/upper-cased value is different between latin1 and
+ // utf8 for 0xb5, causing E763 for no good reason. Use the latin1
+ // value for utf-8 to avoid this.
+ spelltab.st_fold[i] = (f < 256) ? f : i;
+ spelltab.st_upper[i] = (u < 256) ? u : i;
}
-
- return OK;
}
/// Returns true if "p" points to a word character.
@@ -8209,23 +2592,25 @@ static bool spell_iswordp(char_u *p, win_T *wp)
int c;
if (has_mbyte) {
- l = MB_BYTE2LEN(*p);
+ l = MB_PTR2LEN(p);
s = p;
if (l == 1) {
// be quick for ASCII
if (wp->w_s->b_spell_ismw[*p])
s = p + 1; // skip a mid-word character
} else {
- c = mb_ptr2char(p);
+ c = utf_ptr2char(p);
if (c < 256 ? wp->w_s->b_spell_ismw[c]
: (wp->w_s->b_spell_ismw_mb != NULL
- && vim_strchr(wp->w_s->b_spell_ismw_mb, c) != NULL))
+ && vim_strchr(wp->w_s->b_spell_ismw_mb, c) != NULL)) {
s = p + l;
+ }
}
- c = mb_ptr2char(s);
- if (c > 255)
+ c = utf_ptr2char(s);
+ if (c > 255) {
return spell_mb_isword_class(mb_get_class(s), wp);
+ }
return spelltab.st_isw[c];
}
@@ -8234,23 +2619,19 @@ static bool spell_iswordp(char_u *p, win_T *wp)
// Returns true if "p" points to a word character.
// Unlike spell_iswordp() this doesn't check for "midword" characters.
-static bool spell_iswordp_nmw(char_u *p, win_T *wp)
+bool spell_iswordp_nmw(const char_u *p, win_T *wp)
{
- int c;
-
- if (has_mbyte) {
- c = mb_ptr2char(p);
- if (c > 255)
- return spell_mb_isword_class(mb_get_class(p), wp);
- return spelltab.st_isw[c];
+ int c = utf_ptr2char(p);
+ if (c > 255) {
+ return spell_mb_isword_class(mb_get_class(p), wp);
}
- return spelltab.st_isw[*p];
+ return spelltab.st_isw[c];
}
// Returns true if word class indicates a word character.
// Only for characters above 255.
// Unicode subscript and superscript are not considered word characters.
-// See also dbcs_class() and utf_class() in mbyte.c.
+// See also utf_class() in mbyte.c.
static bool spell_mb_isword_class(int cl, win_T *wp)
{
if (wp->w_s->b_cjk)
@@ -8273,51 +2654,16 @@ static bool spell_iswordp_w(int *p, win_T *wp)
s = p;
if (*s > 255) {
- if (enc_utf8)
- return spell_mb_isword_class(utf_class(*s), wp);
- if (enc_dbcs)
- return spell_mb_isword_class(
- dbcs_class((unsigned)*s >> 8, *s & 0xff), wp);
- return false;
+ return spell_mb_isword_class(utf_class(*s), wp);
}
return spelltab.st_isw[*s];
}
-// Write the table with prefix conditions to the .spl file.
-// When "fd" is NULL only count the length of what is written.
-static int write_spell_prefcond(FILE *fd, garray_T *gap)
-{
- assert(gap->ga_len >= 0);
-
- if (fd != NULL)
- put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <prefcondcnt>
-
- size_t totlen = 2 + (size_t)gap->ga_len; // <prefcondcnt> and <condlen> bytes
- size_t x = 1; // collect return value of fwrite()
- for (int i = 0; i < gap->ga_len; ++i) {
- // <prefcond> : <condlen> <condstr>
- char_u *p = ((char_u **)gap->ga_data)[i];
- if (p != NULL) {
- size_t len = STRLEN(p);
- if (fd != NULL) {
- assert(len <= INT_MAX);
- fputc((int)len, fd);
- x &= fwrite(p, len, 1, fd);
- }
- totlen += len;
- } else if (fd != NULL)
- fputc(0, fd);
- }
-
- assert(totlen <= INT_MAX);
- return (int)totlen;
-}
-
// Case-fold "str[len]" into "buf[buflen]". The result is NUL terminated.
// Uses the character definitions from the .spl file.
// When using a multi-byte 'encoding' the length may change!
// Returns FAIL when something wrong.
-static int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
+int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
{
int i;
@@ -8337,8 +2683,8 @@ static int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
buf[outi] = NUL;
return FAIL;
}
- c = mb_cptr2char_adv(&p);
- outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
+ c = mb_cptr2char_adv((const char_u **)&p);
+ outi += utf_char2bytes(SPELL_TOFOLD(c), buf + outi);
}
buf[outi] = NUL;
} else {
@@ -8436,11 +2782,12 @@ void spell_suggest(int count)
return;
}
badlen = (int)curwin->w_cursor.col - (int)VIsual.col;
- if (badlen < 0)
+ if (badlen < 0) {
badlen = -badlen;
- else
+ } else {
curwin->w_cursor.col = VIsual.col;
- ++badlen;
+ }
+ badlen++;
end_visual_mode();
} else
// Find the start of the badly spelled word.
@@ -8452,11 +2799,13 @@ void spell_suggest(int count)
line = get_cursor_line_ptr();
p = line + curwin->w_cursor.col;
// Backup to before start of word.
- while (p > line && spell_iswordp_nmw(p, curwin))
- mb_ptr_back(line, p);
+ while (p > line && spell_iswordp_nmw(p, curwin)) {
+ MB_PTR_BACK(line, p);
+ }
// Forward to start of word.
- while (*p != NUL && !spell_iswordp_nmw(p, curwin))
- mb_ptr_adv(p);
+ while (*p != NUL && !spell_iswordp_nmw(p, curwin)) {
+ MB_PTR_ADV(p);
+ }
if (!spell_iswordp_nmw(p, curwin)) { // No word found.
beep_flush();
@@ -8511,7 +2860,7 @@ void spell_suggest(int count)
vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC",
sug.su_badlen, sug.su_badptr);
}
- msg_puts(IObuff);
+ msg_puts((const char *)IObuff);
msg_clr_eos();
msg_putchar('\n');
@@ -8527,18 +2876,19 @@ void spell_suggest(int count)
sug.su_badptr + stp->st_orglen,
sug.su_badlen - stp->st_orglen + 1);
vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1);
- if (cmdmsg_rl)
+ if (cmdmsg_rl) {
rl_mirror(IObuff);
- msg_puts(IObuff);
+ }
+ msg_puts((const char *)IObuff);
vim_snprintf((char *)IObuff, IOSIZE, " \"%s\"", wcopy);
- msg_puts(IObuff);
+ msg_puts((const char *)IObuff);
// The word may replace more than "su_badlen".
if (sug.su_badlen < stp->st_orglen) {
vim_snprintf((char *)IObuff, IOSIZE, _(" < \"%.*s\""),
- stp->st_orglen, sug.su_badptr);
- msg_puts(IObuff);
+ stp->st_orglen, sug.su_badptr);
+ msg_puts((const char *)IObuff);
}
if (p_verbose > 0) {
@@ -8554,7 +2904,7 @@ void spell_suggest(int count)
// Mirror the numbers, but keep the leading space.
rl_mirror(IObuff + 1);
msg_advance(30);
- msg_puts(IObuff);
+ msg_puts((const char *)IObuff);
}
msg_putchar('\n');
}
@@ -8593,12 +2943,12 @@ void spell_suggest(int count)
memmove(p, line, c);
STRCPY(p + c, stp->st_word);
STRCAT(p, sug.su_badptr + stp->st_orglen);
- ml_replace(curwin->w_cursor.lnum, p, FALSE);
+ ml_replace(curwin->w_cursor.lnum, p, false);
curwin->w_cursor.col = c;
// For redo we use a change-word command.
ResetRedobuff();
- AppendToRedobuff((char_u *)"ciw");
+ AppendToRedobuff("ciw");
AppendToRedobuffLit(p + c,
stp->st_wordlen + sug.su_badlen - stp->st_orglen);
AppendCharToRedobuff(ESC);
@@ -8628,7 +2978,7 @@ static bool check_need_cap(linenr_T lnum, colnr_T col)
line = get_cursor_line_ptr();
endcol = 0;
- if ((int)(skipwhite(line) - line) >= (int)col) {
+ if (getwhitecols(line) >= (int)col) {
// At start of line, check if previous line is empty or sentence
// ends there.
if (lnum == 1)
@@ -8644,8 +2994,9 @@ static bool check_need_cap(linenr_T lnum, colnr_T col)
endcol = (colnr_T)STRLEN(line);
}
}
- } else
+ } else {
endcol = col;
+ }
if (endcol > 0) {
// Check if sentence ends before the bad word.
@@ -8653,9 +3004,10 @@ static bool check_need_cap(linenr_T lnum, colnr_T col)
regmatch.rm_ic = FALSE;
p = line + endcol;
for (;; ) {
- mb_ptr_back(line, p);
- if (p == line || spell_iswordp_nmw(p, curwin))
+ MB_PTR_BACK(line, p);
+ if (p == line || spell_iswordp_nmw(p, curwin)) {
break;
+ }
if (vim_regexec(&regmatch, p, 0)
&& regmatch.endp[0] == line + endcol) {
need_cap = true;
@@ -8709,7 +3061,7 @@ void ex_spellrepall(exarg_T *eap)
memmove(p, line, curwin->w_cursor.col);
STRCPY(p + curwin->w_cursor.col, repl_to);
STRCAT(p, line + curwin->w_cursor.col + STRLEN(repl_from));
- ml_replace(curwin->w_cursor.lnum, p, FALSE);
+ ml_replace(curwin->w_cursor.lnum, p, false);
changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
if (curwin->w_cursor.lnum != prev_lnum) {
@@ -8813,8 +3165,13 @@ spell_find_suggest (
if (su->su_badlen >= MAXWLEN)
su->su_badlen = MAXWLEN - 1; // just in case
STRLCPY(su->su_badword, su->su_badptr, su->su_badlen + 1);
- (void)spell_casefold(su->su_badptr, su->su_badlen,
- su->su_fbadword, MAXWLEN);
+ (void)spell_casefold(su->su_badptr, su->su_badlen, su->su_fbadword, MAXWLEN);
+
+ // TODO(vim): make this work if the case-folded text is longer than the
+ // original text. Currently an illegal byte causes wrong pointer
+ // computations.
+ su->su_fbadword[su->su_badlen] = NUL;
+
// get caps flags for bad word
su->su_badflags = badword_captype(su->su_badptr,
su->su_badptr + su->su_badlen);
@@ -8890,26 +3247,26 @@ spell_find_suggest (
// Find suggestions by evaluating expression "expr".
static void spell_suggest_expr(suginfo_T *su, char_u *expr)
{
- list_T *list;
- listitem_T *li;
int score;
- char_u *p;
+ const char *p;
// The work is split up in a few parts to avoid having to export
// suginfo_T.
// First evaluate the expression and get the resulting list.
- list = eval_spell_expr(su->su_badword, expr);
+ list_T *const list = eval_spell_expr(su->su_badword, expr);
if (list != NULL) {
// Loop over the items in the list.
- for (li = list->lv_first; li != NULL; li = li->li_next)
- if (li->li_tv.v_type == VAR_LIST) {
+ TV_LIST_ITER(list, li, {
+ if (TV_LIST_ITEM_TV(li)->v_type == VAR_LIST) {
// Get the word and the score from the items.
- score = get_spellword(li->li_tv.vval.v_list, &p);
- if (score >= 0 && score <= su->su_maxscore)
- add_suggestion(su, &su->su_ga, p, su->su_badlen,
- score, 0, true, su->su_sallang, false);
+ score = get_spellword(TV_LIST_ITEM_TV(li)->vval.v_list, &p);
+ if (score >= 0 && score <= su->su_maxscore) {
+ add_suggestion(su, &su->su_ga, (const char_u *)p, su->su_badlen,
+ score, 0, true, su->su_sallang, false);
+ }
}
- list_unref(list);
+ });
+ tv_list_unref(list);
}
// Remove bogus suggestions, sort and truncate at "maxcount".
@@ -9040,174 +3397,6 @@ static void spell_suggest_intern(suginfo_T *su, bool interactive)
}
}
-// Load the .sug files for languages that have one and weren't loaded yet.
-static void suggest_load_files(void)
-{
- langp_T *lp;
- slang_T *slang;
- char_u *dotp;
- FILE *fd;
- char_u buf[MAXWLEN];
- int i;
- time_t timestamp;
- int wcount;
- int wordnr;
- garray_T ga;
- int c;
-
- // Do this for all languages that support sound folding.
- for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
- lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
- slang = lp->lp_slang;
- if (slang->sl_sugtime != 0 && !slang->sl_sugloaded) {
- // Change ".spl" to ".sug" and open the file. When the file isn't
- // found silently skip it. Do set "sl_sugloaded" so that we
- // don't try again and again.
- slang->sl_sugloaded = true;
-
- dotp = vim_strrchr(slang->sl_fname, '.');
- if (dotp == NULL || fnamecmp(dotp, ".spl") != 0)
- continue;
- STRCPY(dotp, ".sug");
- fd = mch_fopen((char *)slang->sl_fname, "r");
- if (fd == NULL)
- goto nextone;
-
- // <SUGHEADER>: <fileID> <versionnr> <timestamp>
- for (i = 0; i < VIMSUGMAGICL; ++i)
- buf[i] = getc(fd); // <fileID>
- if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) {
- EMSG2(_("E778: This does not look like a .sug file: %s"),
- slang->sl_fname);
- goto nextone;
- }
- c = getc(fd); // <versionnr>
- if (c < VIMSUGVERSION) {
- EMSG2(_("E779: Old .sug file, needs to be updated: %s"),
- slang->sl_fname);
- goto nextone;
- } else if (c > VIMSUGVERSION) {
- EMSG2(_("E780: .sug file is for newer version of Vim: %s"),
- slang->sl_fname);
- goto nextone;
- }
-
- // Check the timestamp, it must be exactly the same as the one in
- // the .spl file. Otherwise the word numbers won't match.
- timestamp = get8ctime(fd); // <timestamp>
- if (timestamp != slang->sl_sugtime) {
- EMSG2(_("E781: .sug file doesn't match .spl file: %s"),
- slang->sl_fname);
- goto nextone;
- }
-
- // <SUGWORDTREE>: <wordtree>
- // Read the trie with the soundfolded words.
- if (spell_read_tree(fd, &slang->sl_sbyts, &slang->sl_sidxs,
- false, 0) != 0) {
-someerror:
- EMSG2(_("E782: error while reading .sug file: %s"),
- slang->sl_fname);
- slang_clear_sug(slang);
- goto nextone;
- }
-
- // <SUGTABLE>: <sugwcount> <sugline> ...
- //
- // Read the table with word numbers. We use a file buffer for
- // this, because it's so much like a file with lines. Makes it
- // possible to swap the info and save on memory use.
- slang->sl_sugbuf = open_spellbuf();
-
- // <sugwcount>
- wcount = get4c(fd);
- if (wcount < 0)
- goto someerror;
-
- // Read all the wordnr lists into the buffer, one NUL terminated
- // list per line.
- ga_init(&ga, 1, 100);
- for (wordnr = 0; wordnr < wcount; ++wordnr) {
- ga.ga_len = 0;
- for (;; ) {
- c = getc(fd); // <sugline>
- if (c < 0) {
- goto someerror;
- }
- GA_APPEND(char_u, &ga, c);
- if (c == NUL)
- break;
- }
- if (ml_append_buf(slang->sl_sugbuf, (linenr_T)wordnr,
- ga.ga_data, ga.ga_len, TRUE) == FAIL)
- goto someerror;
- }
- ga_clear(&ga);
-
- // Need to put word counts in the word tries, so that we can find
- // a word by its number.
- tree_count_words(slang->sl_fbyts, slang->sl_fidxs);
- tree_count_words(slang->sl_sbyts, slang->sl_sidxs);
-
-nextone:
- if (fd != NULL)
- fclose(fd);
- STRCPY(dotp, ".spl");
- }
- }
-}
-
-// Fill in the wordcount fields for a trie.
-// Returns the total number of words.
-static void tree_count_words(char_u *byts, idx_T *idxs)
-{
- int depth;
- idx_T arridx[MAXWLEN];
- int curi[MAXWLEN];
- int c;
- idx_T n;
- int wordcount[MAXWLEN];
-
- arridx[0] = 0;
- curi[0] = 1;
- wordcount[0] = 0;
- depth = 0;
- while (depth >= 0 && !got_int) {
- if (curi[depth] > byts[arridx[depth]]) {
- // Done all bytes at this node, go up one level.
- idxs[arridx[depth]] = wordcount[depth];
- if (depth > 0)
- wordcount[depth - 1] += wordcount[depth];
-
- --depth;
- fast_breakcheck();
- } else {
- // Do one more byte at this node.
- n = arridx[depth] + curi[depth];
- ++curi[depth];
-
- c = byts[n];
- if (c == 0) {
- // End of word, count it.
- ++wordcount[depth];
-
- // Skip over any other NUL bytes (same word with different
- // flags).
- while (byts[n + 1] == 0) {
- ++n;
- ++curi[depth];
- }
- } else {
- // Normal char, go one level deeper to count the words.
- ++depth;
- arridx[depth] = idxs[n];
- curi[depth] = 1;
- wordcount[depth] = 0;
- }
- }
- }
-}
-
// Free the info put in "*su" by spell_find_suggest().
static void spell_find_cleanup(suginfo_T *su)
{
@@ -9220,35 +3409,31 @@ static void spell_find_cleanup(suginfo_T *su)
hash_clear_all(&su->su_banned, 0);
}
-// Make a copy of "word", with the first letter upper or lower cased, to
-// "wcopy[MAXWLEN]". "word" must not be empty.
-// The result is NUL terminated.
-static void
-onecap_copy (
- char_u *word,
- char_u *wcopy,
- bool upper // true: first letter made upper case
-)
+/// Make a copy of "word", with the first letter upper or lower cased, to
+/// "wcopy[MAXWLEN]". "word" must not be empty.
+/// The result is NUL terminated.
+///
+/// @param[in] word source string to copy
+/// @param[in,out] wcopy copied string, with case of first letter changed
+/// @param[in] upper True to upper case, otherwise lower case
+void onecap_copy(char_u *word, char_u *wcopy, bool upper)
{
char_u *p;
int c;
int l;
p = word;
- if (has_mbyte)
- c = mb_cptr2char_adv(&p);
- else
+ if (has_mbyte) {
+ c = mb_cptr2char_adv((const char_u **)&p);
+ } else {
c = *p++;
- if (upper)
+ }
+ if (upper) {
c = SPELL_TOUPPER(c);
- else
+ } else {
c = SPELL_TOFOLD(c);
- if (has_mbyte)
- l = mb_char2bytes(c, wcopy);
- else {
- l = 1;
- wcopy[0] = c;
}
+ l = utf_char2bytes(c, wcopy);
STRLCPY(wcopy + l, p, MAXWLEN - l);
}
@@ -9262,14 +3447,13 @@ static void allcap_copy(char_u *word, char_u *wcopy)
d = wcopy;
for (s = word; *s != NUL; ) {
- if (has_mbyte)
- c = mb_cptr2char_adv(&s);
- else
+ if (has_mbyte) {
+ c = mb_cptr2char_adv((const char_u **)&s);
+ } else {
c = *s++;
+ }
- // We only change 0xdf to SS when we are certain latin1 is used. It
- // would cause weird errors in other 8-bit encodings.
- if (enc_latin1like && c == 0xdf) {
+ if (c == 0xdf) {
c = 'S';
if (d - wcopy >= MAXWLEN - 1)
break;
@@ -9277,15 +3461,10 @@ static void allcap_copy(char_u *word, char_u *wcopy)
} else
c = SPELL_TOUPPER(c);
- if (has_mbyte) {
- if (d - wcopy >= MAXWLEN - MB_MAXBYTES)
- break;
- d += mb_char2bytes(c, d);
- } else {
- if (d - wcopy >= MAXWLEN - 1)
- break;
- *d++ = c;
+ if (d - wcopy >= MAXWLEN - MB_MAXBYTES) {
+ break;
}
+ d += utf_char2bytes(c, d);
}
*d = NUL;
}
@@ -9477,7 +3656,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// word).
depth = 0;
sp = &stack[0];
- memset(sp, 0, sizeof(trystate_T));
+ memset(sp, 0, sizeof(trystate_T)); // -V512
sp->ts_curi = 1;
if (soundfold) {
@@ -9695,7 +3874,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Get pointer to last char of previous word.
p = preword + sp->ts_prewordlen;
- mb_ptr_back(preword, p);
+ MB_PTR_BACK(preword, p);
}
}
@@ -9781,12 +3960,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Give a penalty when changing non-word char to word
// char, e.g., "thes," -> "these".
p = fword + sp->ts_fidx;
- mb_ptr_back(fword, p);
+ MB_PTR_BACK(fword, p);
if (!spell_iswordp(p, curwin)) {
p = preword + STRLEN(preword);
- mb_ptr_back(preword, p);
- if (spell_iswordp(p, curwin))
+ MB_PTR_BACK(preword, p);
+ if (spell_iswordp(p, curwin)) {
newscore += SCORE_NONWORD;
+ }
}
// Give a bonus to words seen before.
@@ -9952,10 +4132,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
&& goodword_ends) {
int l;
- if (has_mbyte)
- l = MB_BYTE2LEN(fword[sp->ts_fidx]);
- else
- l = 1;
+ l = MB_PTR2LEN(fword + sp->ts_fidx);
if (fword_ends) {
// Copy the skipped character to preword.
memmove(preword + sp->ts_prewordlen,
@@ -10027,7 +4204,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
}
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_PLAIN;
- // FALLTHROUGH
+ FALLTHROUGH;
case STATE_PLAIN:
// Go over all possible bytes at this node, add each to tword[]
@@ -10101,40 +4278,33 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// Correct ts_fidx for the byte length of the
// character (we didn't check that before).
sp->ts_fidx = sp->ts_fcharstart
- + MB_BYTE2LEN(
- fword[sp->ts_fcharstart]);
+ + MB_PTR2LEN(fword + sp->ts_fcharstart);
// For changing a composing character adjust
// the score from SCORE_SUBST to
// SCORE_SUBCOMP.
if (enc_utf8
- && utf_iscomposing(
- mb_ptr2char(tword
- + sp->ts_twordlen
- - sp->ts_tcharlen))
- && utf_iscomposing(
- mb_ptr2char(fword
- + sp->ts_fcharstart)))
- sp->ts_score -=
- SCORE_SUBST - SCORE_SUBCOMP;
-
- // For a similar character adjust score from
- // SCORE_SUBST to SCORE_SIMILAR.
- else if (!soundfold
- && slang->sl_has_map
- && similar_chars(slang,
- mb_ptr2char(tword
- + sp->ts_twordlen
- - sp->ts_tcharlen),
- mb_ptr2char(fword
- + sp->ts_fcharstart)))
- sp->ts_score -=
- SCORE_SUBST - SCORE_SIMILAR;
+ && utf_iscomposing(utf_ptr2char(tword + sp->ts_twordlen
+ - sp->ts_tcharlen))
+ && utf_iscomposing(utf_ptr2char(fword
+ + sp->ts_fcharstart))) {
+ sp->ts_score -= SCORE_SUBST - SCORE_SUBCOMP;
+ } else if (
+ !soundfold
+ && slang->sl_has_map
+ && similar_chars(
+ slang,
+ utf_ptr2char(tword + sp->ts_twordlen - sp->ts_tcharlen),
+ utf_ptr2char(fword + sp->ts_fcharstart))) {
+ // For a similar character adjust score from
+ // SCORE_SUBST to SCORE_SIMILAR.
+ sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
+ }
} else if (sp->ts_isdiff == DIFF_INSERT
&& sp->ts_twordlen > sp->ts_tcharlen) {
p = tword + sp->ts_twordlen - sp->ts_tcharlen;
- c = mb_ptr2char(p);
- if (enc_utf8 && utf_iscomposing(c)) {
+ c = utf_ptr2char(p);
+ if (utf_iscomposing(c)) {
// Inserting a composing char doesn't
// count that much.
sp->ts_score -= SCORE_INS - SCORE_INSCOMP;
@@ -10144,10 +4314,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// to the score. Also for the soundfold
// tree (might seem illogical but does
// give better scores).
- mb_ptr_back(tword, p);
- if (c == mb_ptr2char(p))
- sp->ts_score -= SCORE_INS
- - SCORE_INSDUP;
+ MB_PTR_BACK(tword, p);
+ if (c == utf_ptr2char(p)) {
+ sp->ts_score -= SCORE_INS - SCORE_INSDUP;
+ }
}
}
@@ -10206,21 +4376,17 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// score if the same character is following "nn" -> "n". It's
// a bit illogical for soundfold tree but it does give better
// results.
- if (has_mbyte) {
- c = mb_ptr2char(fword + sp->ts_fidx);
- stack[depth].ts_fidx += MB_BYTE2LEN(fword[sp->ts_fidx]);
- if (enc_utf8 && utf_iscomposing(c))
- stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
- else if (c == mb_ptr2char(fword + stack[depth].ts_fidx))
- stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
- } else {
- ++stack[depth].ts_fidx;
- if (fword[sp->ts_fidx] == fword[sp->ts_fidx + 1])
- stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
+ c = utf_ptr2char(fword + sp->ts_fidx);
+ stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx);
+ if (utf_iscomposing(c)) {
+ stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
+ } else if (c == utf_ptr2char(fword + stack[depth].ts_fidx)) {
+ stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
}
+
break;
}
- // FALLTHROUGH
+ FALLTHROUGH;
case STATE_INS_PREP:
if (sp->ts_flags & TSF_DIDDEL) {
@@ -10250,7 +4416,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
}
break;
- // FALLTHROUGH
+ FALLTHROUGH;
case STATE_INS:
// Insert one byte. Repeat this for each possible byte at this
@@ -10332,22 +4498,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
break;
}
- if (has_mbyte) {
- n = mb_cptr2len(p);
- c = mb_ptr2char(p);
- if (p[n] == NUL)
- c2 = NUL;
- else if (!soundfold && !spell_iswordp(p + n, curwin))
- c2 = c; // don't swap non-word char
- else
- c2 = mb_ptr2char(p + n);
+ n = MB_CPTR2LEN(p);
+ c = utf_ptr2char(p);
+ if (p[n] == NUL) {
+ c2 = NUL;
+ } else if (!soundfold && !spell_iswordp(p + n, curwin)) {
+ c2 = c; // don't swap non-word char
} else {
- if (p[1] == NUL)
- c2 = NUL;
- else if (!soundfold && !spell_iswordp(p + 1, curwin))
- c2 = c; // don't swap non-word char
- else
- c2 = p[1];
+ c2 = utf_ptr2char(p + n);
}
// When the second character is NUL we can't swap.
@@ -10367,64 +4525,47 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (c2 != NUL && TRY_DEEPER(su, stack, depth, SCORE_SWAP)) {
go_deeper(stack, depth, SCORE_SWAP);
#ifdef DEBUG_TRIEWALK
- sprintf(changename[depth], "%.*s-%s: swap %c and %c",
- sp->ts_twordlen, tword, fword + sp->ts_fidx,
- c, c2);
+ snprintf(changename[depth], sizeof(changename[0]),
+ "%.*s-%s: swap %c and %c",
+ sp->ts_twordlen, tword, fword + sp->ts_fidx,
+ c, c2);
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNSWAP;
- ++depth;
- if (has_mbyte) {
- fl = mb_char2len(c2);
- memmove(p, p + n, fl);
- mb_char2bytes(c, p + fl);
- stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
- } else {
- p[0] = c2;
- p[1] = c;
- stack[depth].ts_fidxtry = sp->ts_fidx + 2;
- }
- } else
+ depth++;
+ fl = mb_char2len(c2);
+ memmove(p, p + n, fl);
+ utf_char2bytes(c, p + fl);
+ stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
+ } else {
// If this swap doesn't work then SWAP3 won't either.
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI;
+ }
break;
case STATE_UNSWAP:
// Undo the STATE_SWAP swap: "21" -> "12".
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_BYTE2LEN(*p);
- c = mb_ptr2char(p + n);
- memmove(p + MB_BYTE2LEN(p[n]), p, n);
- mb_char2bytes(c, p);
- } else {
- c = *p;
- *p = p[1];
- p[1] = c;
- }
- // FALLTHROUGH
+ n = MB_PTR2LEN(p);
+ c = utf_ptr2char(p + n);
+ memmove(p + MB_PTR2LEN(p + n), p, n);
+ utf_char2bytes(c, p);
+
+ FALLTHROUGH;
case STATE_SWAP3:
// Swap two bytes, skipping one: "123" -> "321". We change
// "fword" here, it's changed back afterwards at STATE_UNSWAP3.
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = mb_cptr2len(p);
- c = mb_ptr2char(p);
- fl = mb_cptr2len(p + n);
- c2 = mb_ptr2char(p + n);
- if (!soundfold && !spell_iswordp(p + n + fl, curwin))
- c3 = c; // don't swap non-word char
- else
- c3 = mb_ptr2char(p + n + fl);
+ n = MB_CPTR2LEN(p);
+ c = utf_ptr2char(p);
+ fl = MB_CPTR2LEN(p + n);
+ c2 = utf_ptr2char(p + n);
+ if (!soundfold && !spell_iswordp(p + n + fl, curwin)) {
+ c3 = c; // don't swap non-word char
} else {
- c = *p;
- c2 = p[1];
- if (!soundfold && !spell_iswordp(p + 2, curwin))
- c3 = c; // don't swap non-word char
- else
- c3 = p[2];
+ c3 = utf_ptr2char(p + n + fl);
}
// When characters are identical: "121" then SWAP3 result is
@@ -10447,18 +4588,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
#endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNSWAP3;
- ++depth;
- if (has_mbyte) {
- tl = mb_char2len(c3);
- memmove(p, p + n + fl, tl);
- mb_char2bytes(c2, p + tl);
- mb_char2bytes(c, p + fl + tl);
- stack[depth].ts_fidxtry = sp->ts_fidx + n + fl + tl;
- } else {
- p[0] = p[2];
- p[2] = c;
- stack[depth].ts_fidxtry = sp->ts_fidx + 3;
- }
+ depth++;
+ tl = mb_char2len(c3);
+ memmove(p, p + n + fl, tl);
+ utf_char2bytes(c2, p + tl);
+ utf_char2bytes(c, p + fl + tl);
+ stack[depth].ts_fidxtry = sp->ts_fidx + n + fl + tl;
} else {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI;
@@ -10468,22 +4603,15 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
case STATE_UNSWAP3:
// Undo STATE_SWAP3: "321" -> "123"
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_BYTE2LEN(*p);
- c2 = mb_ptr2char(p + n);
- fl = MB_BYTE2LEN(p[n]);
- c = mb_ptr2char(p + n + fl);
- tl = MB_BYTE2LEN(p[n + fl]);
- memmove(p + fl + tl, p, n);
- mb_char2bytes(c, p);
- mb_char2bytes(c2, p + tl);
- p = p + tl;
- } else {
- c = *p;
- *p = p[2];
- p[2] = c;
- ++p;
- }
+ n = MB_PTR2LEN(p);
+ c2 = utf_ptr2char(p + n);
+ fl = MB_PTR2LEN(p + n);
+ c = utf_ptr2char(p + n + fl);
+ tl = MB_PTR2LEN(p + n + fl);
+ memmove(p + fl + tl, p, n);
+ utf_char2bytes(c, p);
+ utf_char2bytes(c2, p + tl);
+ p = p + tl;
if (!soundfold && !spell_iswordp(p, curwin)) {
// Middle char is not a word char, skip the rotate. First and
@@ -10507,21 +4635,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
sp->ts_state = STATE_UNROT3L;
++depth;
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = mb_cptr2len(p);
- c = mb_ptr2char(p);
- fl = mb_cptr2len(p + n);
- fl += mb_cptr2len(p + n + fl);
- memmove(p, p + n, fl);
- mb_char2bytes(c, p + fl);
- stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
- } else {
- c = *p;
- *p = p[1];
- p[1] = p[2];
- p[2] = c;
- stack[depth].ts_fidxtry = sp->ts_fidx + 3;
- }
+ n = MB_CPTR2LEN(p);
+ c = utf_ptr2char(p);
+ fl = MB_CPTR2LEN(p + n);
+ fl += MB_CPTR2LEN(p + n + fl);
+ memmove(p, p + n, fl);
+ utf_char2bytes(c, p + fl);
+ stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
} else {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI;
@@ -10531,19 +4651,12 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
case STATE_UNROT3L:
// Undo ROT3L: "231" -> "123"
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = MB_BYTE2LEN(*p);
- n += MB_BYTE2LEN(p[n]);
- c = mb_ptr2char(p + n);
- tl = MB_BYTE2LEN(p[n]);
- memmove(p + tl, p, n);
- mb_char2bytes(c, p);
- } else {
- c = p[2];
- p[2] = p[1];
- p[1] = *p;
- *p = c;
- }
+ n = MB_PTR2LEN(p);
+ n += MB_PTR2LEN(p + n);
+ c = utf_ptr2char(p + n);
+ tl = MB_PTR2LEN(p + n);
+ memmove(p + tl, p, n);
+ utf_char2bytes(c, p);
// Rotate three bytes right: "123" -> "312". We change "fword"
// here, it's changed back afterwards at STATE_UNROT3R.
@@ -10559,21 +4672,13 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
sp->ts_state = STATE_UNROT3R;
++depth;
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- n = mb_cptr2len(p);
- n += mb_cptr2len(p + n);
- c = mb_ptr2char(p + n);
- tl = mb_cptr2len(p + n);
- memmove(p + tl, p, n);
- mb_char2bytes(c, p);
- stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
- } else {
- c = p[2];
- p[2] = p[1];
- p[1] = *p;
- *p = c;
- stack[depth].ts_fidxtry = sp->ts_fidx + 3;
- }
+ n = MB_CPTR2LEN(p);
+ n += MB_CPTR2LEN(p + n);
+ c = utf_ptr2char(p + n);
+ tl = MB_CPTR2LEN(p + n);
+ memmove(p + tl, p, n);
+ utf_char2bytes(c, p);
+ stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
} else {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI;
@@ -10583,20 +4688,14 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
case STATE_UNROT3R:
// Undo ROT3R: "312" -> "123"
p = fword + sp->ts_fidx;
- if (has_mbyte) {
- c = mb_ptr2char(p);
- tl = MB_BYTE2LEN(*p);
- n = MB_BYTE2LEN(p[tl]);
- n += MB_BYTE2LEN(p[tl + n]);
- memmove(p, p + tl, n);
- mb_char2bytes(c, p + n);
- } else {
- c = *p;
- *p = p[1];
- p[1] = p[2];
- p[2] = c;
- }
- // FALLTHROUGH
+ c = utf_ptr2char(p);
+ tl = MB_PTR2LEN(p);
+ n = MB_PTR2LEN(p + tl);
+ n += MB_PTR2LEN(p + tl + n);
+ memmove(p, p + tl, n);
+ utf_char2bytes(c, p + n);
+
+ FALLTHROUGH;
case STATE_REP_INI:
// Check if matching with REP items from the .aff file would work.
@@ -10627,7 +4726,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP;
- // FALLTHROUGH
+ FALLTHROUGH;
case STATE_REP:
// Try matching with REP items from the .aff file. For each match
@@ -10736,10 +4835,12 @@ static int nofold_len(char_u *fword, int flen, char_u *word)
char_u *p;
int i = 0;
- for (p = fword; p < fword + flen; mb_ptr_adv(p))
- ++i;
- for (p = word; i > 0; mb_ptr_adv(p))
- --i;
+ for (p = fword; p < fword + flen; MB_PTR_ADV(p)) {
+ i++;
+ }
+ for (p = word; i > 0; MB_PTR_ADV(p)) {
+ i--;
+ }
return (int)(p - word);
}
@@ -10806,10 +4907,11 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
// round[depth] == 1: Try using the folded-case character.
// round[depth] == 2: Try using the upper-case character.
if (has_mbyte) {
- flen = mb_cptr2len(fword + fwordidx[depth]);
- ulen = mb_cptr2len(uword + uwordidx[depth]);
- } else
+ flen = MB_CPTR2LEN(fword + fwordidx[depth]);
+ ulen = MB_CPTR2LEN(uword + uwordidx[depth]);
+ } else {
ulen = flen = 1;
+ }
if (round[depth] == 1) {
p = fword + fwordidx[depth];
l = flen;
@@ -11180,11 +5282,13 @@ add_sound_suggest (
// the words that have a better score than before. Use a hashtable to
// remember the words that have been done.
hash = hash_hash(goodword);
- hi = hash_lookup(&slang->sl_sounddone, goodword, hash);
+ const size_t goodword_len = STRLEN(goodword);
+ hi = hash_lookup(&slang->sl_sounddone, (const char *)goodword, goodword_len,
+ hash);
if (HASHITEM_EMPTY(hi)) {
- sft = xmalloc(sizeof(sftword_T) + STRLEN(goodword));
+ sft = xmalloc(sizeof(sftword_T) + goodword_len);
sft->sft_score = score;
- STRCPY(sft->sft_word, goodword);
+ memcpy(sft->sft_word, goodword, goodword_len + 1);
hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash);
} else {
sft = HI2SFT(hi);
@@ -11196,7 +5300,7 @@ add_sound_suggest (
// Find the word nr in the soundfold tree.
sfwordnr = soundfold_find(slang, goodword);
if (sfwordnr < 0) {
- EMSG2(_(e_intern2), "add_sound_suggest()");
+ internal_error("add_sound_suggest()");
return;
}
@@ -11405,67 +5509,6 @@ static void make_case_word(char_u *fword, char_u *cword, int flags)
STRCPY(cword, fword);
}
-// Use map string "map" for languages "lp".
-static void set_map_str(slang_T *lp, char_u *map)
-{
- char_u *p;
- int headc = 0;
- int c;
- int i;
-
- if (*map == NUL) {
- lp->sl_has_map = false;
- return;
- }
- lp->sl_has_map = true;
-
- // Init the array and hash tables empty.
- for (i = 0; i < 256; ++i)
- lp->sl_map_array[i] = 0;
- hash_init(&lp->sl_map_hash);
-
- // The similar characters are stored separated with slashes:
- // "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and
- // before the same slash. For characters above 255 sl_map_hash is used.
- for (p = map; *p != NUL; ) {
- c = mb_cptr2char_adv(&p);
- if (c == '/')
- headc = 0;
- else {
- if (headc == 0)
- headc = c;
-
- // Characters above 255 don't fit in sl_map_array[], put them in
- // the hash table. Each entry is the char, a NUL the headchar and
- // a NUL.
- if (c >= 256) {
- int cl = mb_char2len(c);
- int headcl = mb_char2len(headc);
- char_u *b;
- hash_T hash;
- hashitem_T *hi;
-
- b = xmalloc(cl + headcl + 2);
- mb_char2bytes(c, b);
- b[cl] = NUL;
- mb_char2bytes(headc, b + cl + 1);
- b[cl + 1 + headcl] = NUL;
- hash = hash_hash(b);
- hi = hash_lookup(&lp->sl_map_hash, b, hash);
- if (HASHITEM_EMPTY(hi))
- hash_add_item(&lp->sl_map_hash, hi, b, hash);
- else {
- // This should have been checked when generating the .spl
- // file.
- EMSG(_("E783: duplicate char in MAP entry"));
- xfree(b);
- }
- } else
- lp->sl_map_array[c] = headc;
- }
- }
-}
-
// Returns true if "c1" and "c2" are similar characters according to the MAP
// lines in the .aff file.
static bool similar_chars(slang_T *slang, int c1, int c2)
@@ -11475,27 +5518,31 @@ static bool similar_chars(slang_T *slang, int c1, int c2)
hashitem_T *hi;
if (c1 >= 256) {
- buf[mb_char2bytes(c1, buf)] = 0;
+ buf[utf_char2bytes(c1, buf)] = 0;
hi = hash_find(&slang->sl_map_hash, buf);
- if (HASHITEM_EMPTY(hi))
+ if (HASHITEM_EMPTY(hi)) {
m1 = 0;
- else
- m1 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
- } else
+ } else {
+ m1 = utf_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+ }
+ } else {
m1 = slang->sl_map_array[c1];
- if (m1 == 0)
+ }
+ if (m1 == 0) {
return false;
-
+ }
if (c2 >= 256) {
- buf[mb_char2bytes(c2, buf)] = 0;
+ buf[utf_char2bytes(c2, buf)] = 0;
hi = hash_find(&slang->sl_map_hash, buf);
- if (HASHITEM_EMPTY(hi))
+ if (HASHITEM_EMPTY(hi)) {
m2 = 0;
- else
- m2 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
- } else
+ } else {
+ m2 = utf_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+ }
+ } else {
m2 = slang->sl_map_array[c2];
+ }
return m1 == m2;
}
@@ -11506,7 +5553,7 @@ static void
add_suggestion (
suginfo_T *su,
garray_T *gap, // either su_ga or su_sga
- char_u *goodword,
+ const char_u *goodword,
int badlenarg, // len of bad word replaced with "goodword"
int score,
int altscore,
@@ -11520,25 +5567,21 @@ add_suggestion (
int badlen; // len of bad word changed
suggest_T *stp;
suggest_T new_sug;
- int i;
- char_u *pgood, *pbad;
// Minimize "badlen" for consistency. Avoids that changing "the the" to
// "thee the" is added next to changing the first "the" the "thee".
- pgood = goodword + STRLEN(goodword);
- pbad = su->su_badptr + badlenarg;
+ const char_u *pgood = goodword + STRLEN(goodword);
+ char_u *pbad = su->su_badptr + badlenarg;
for (;; ) {
goodlen = (int)(pgood - goodword);
badlen = (int)(pbad - su->su_badptr);
if (goodlen <= 0 || badlen <= 0)
break;
- mb_ptr_back(goodword, pgood);
- mb_ptr_back(su->su_badptr, pbad);
- if (has_mbyte) {
- if (mb_ptr2char(pgood) != mb_ptr2char(pbad))
- break;
- } else if (*pgood != *pbad)
+ MB_PTR_BACK(goodword, pgood);
+ MB_PTR_BACK(su->su_badptr, pbad);
+ if (utf_ptr2char(pgood) != utf_ptr2char(pbad)) {
break;
+ }
}
if (badlen == 0 && goodlen == 0)
@@ -11546,9 +5589,10 @@ add_suggestion (
// the first "the" to itself.
return;
- if (GA_EMPTY(gap))
+ int i;
+ if (GA_EMPTY(gap)) {
i = -1;
- else {
+ } else {
// Check if the word is already there. Also check the length that is
// being replaced "thes," -> "these" is a different suggestion from
// "thes" -> "these".
@@ -11659,9 +5703,10 @@ static void add_banned(suginfo_T *su, char_u *word)
hashitem_T *hi;
hash = hash_hash(word);
- hi = hash_lookup(&su->su_banned, word, hash);
+ const size_t word_len = STRLEN(word);
+ hi = hash_lookup(&su->su_banned, (const char *)word, word_len, hash);
if (HASHITEM_EMPTY(hi)) {
- s = vim_strsave(word);
+ s = xmemdupz(word, word_len);
hash_add_item(&su->su_banned, hi, s, hash);
}
}
@@ -11746,46 +5791,49 @@ cleanup_suggestions (
return maxscore;
}
-// Soundfold a string, for soundfold().
-// Result is in allocated memory, NULL for an error.
-char_u *eval_soundfold(char_u *word)
+/// Soundfold a string, for soundfold()
+///
+/// @param[in] word Word to soundfold.
+///
+/// @return [allocated] soundfolded string or NULL in case of error. May return
+/// copy of the input string if soundfolding is not
+/// supported by any of the languages in &spellang.
+char *eval_soundfold(const char *const word)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- langp_T *lp;
- char_u sound[MAXWLEN];
-
if (curwin->w_p_spell && *curwin->w_s->b_p_spl != NUL) {
// Use the sound-folding of the first language that supports it.
- for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
- lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; lpi++) {
+ langp_T *const lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
if (!GA_EMPTY(&lp->lp_slang->sl_sal)) {
// soundfold the word
- spell_soundfold(lp->lp_slang, word, false, sound);
- return vim_strsave(sound);
+ char_u sound[MAXWLEN];
+ spell_soundfold(lp->lp_slang, (char_u *)word, false, sound);
+ return xstrdup((const char *)sound);
}
}
}
// No language with sound folding, return word as-is.
- return vim_strsave(word);
+ return xstrdup(word);
}
-// Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".
-//
-// There are many ways to turn a word into a sound-a-like representation. The
-// oldest is Soundex (1918!). A nice overview can be found in "Approximate
-// swedish name matching - survey and test of different algorithms" by Klas
-// Erikson.
-//
-// We support two methods:
-// 1. SOFOFROM/SOFOTO do a simple character mapping.
-// 2. SAL items define a more advanced sound-folding (and much slower).
-static void
-spell_soundfold (
- slang_T *slang,
- char_u *inword,
- bool folded, // "inword" is already case-folded
- char_u *res
-)
+/// Turn "inword" into its sound-a-like equivalent in "res[MAXWLEN]".
+///
+/// There are many ways to turn a word into a sound-a-like representation. The
+/// oldest is Soundex (1918!). A nice overview can be found in "Approximate
+/// swedish name matching - survey and test of different algorithms" by Klas
+/// Erikson.
+///
+/// We support two methods:
+/// 1. SOFOFROM/SOFOTO do a simple character mapping.
+/// 2. SAL items define a more advanced sound-folding (and much slower).
+///
+/// @param[in] slang
+/// @param[in] inword word to soundfold
+/// @param[in] folded whether inword is already case-folded
+/// @param[in,out] res destination for soundfolded word
+void spell_soundfold(slang_T *slang, char_u *inword, bool folded, char_u *res)
{
char_u fword[MAXWLEN];
char_u *word;
@@ -11824,12 +5872,12 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
// The sl_sal_first[] table contains the translation for chars up to
// 255, sl_sal the rest.
for (s = inword; *s != NUL; ) {
- c = mb_cptr2char_adv(&s);
- if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c))
+ c = mb_cptr2char_adv((const char_u **)&s);
+ if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
c = ' ';
- else if (c < 256)
+ } else if (c < 256) {
c = slang->sl_sal_first[c];
- else {
+ } else {
ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
if (ip == NULL) // empty list, can't match
c = NUL;
@@ -11848,9 +5896,10 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
}
if (c != NUL && c != prevc) {
- ri += mb_char2bytes(c, res + ri);
- if (ri + MB_MAXBYTES > MAXWLEN)
+ ri += utf_char2bytes(c, res + ri);
+ if (ri + MB_MAXBYTES > MAXWLEN) {
break;
+ }
prevc = c;
}
}
@@ -12114,9 +6163,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
int word[MAXWLEN];
int wres[MAXWLEN];
int l;
- char_u *s;
int *ws;
- char_u *t;
int *pf;
int i, j, z;
int reslen;
@@ -12136,9 +6183,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// Remove accents, if wanted. We actually remove all non-word characters.
// But keep white space.
wordlen = 0;
- for (s = inword; *s != NUL; ) {
- t = s;
- c = mb_cptr2char_adv(&s);
+ for (const char_u *s = inword; *s != NUL; ) {
+ const char_u *t = s;
+ c = mb_cptr2char_adv((const char_u **)&s);
if (slang->sl_rem_accents) {
if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
if (did_white)
@@ -12147,8 +6194,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
did_white = true;
} else {
did_white = false;
- if (!spell_iswordp_nmw(t, curwin))
+ if (!spell_iswordp_nmw(t, curwin)) {
continue;
+ }
}
}
word[wordlen++] = c;
@@ -12195,7 +6243,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
continue;
++k;
}
- s = smp[n].sm_rules;
+ char_u *s = smp[n].sm_rules;
pri = 5; // default priority
p0 = *s;
@@ -12371,10 +6419,11 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// Convert wide characters in "wres" to a multi-byte string in "res".
l = 0;
- for (n = 0; n < reslen; ++n) {
- l += mb_char2bytes(wres[n], res + l);
- if (l + MB_MAXBYTES > MAXWLEN)
+ for (n = 0; n < reslen; n++) {
+ l += utf_char2bytes(wres[n], res + l);
+ if (l + MB_MAXBYTES > MAXWLEN) {
break;
+ }
}
res[l] = NUL;
}
@@ -12594,25 +6643,30 @@ soundalike_score (
// support multi-byte characters.
static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
{
- int *cnt;
- int badlen, goodlen; // lengths including NUL
+ int *cnt;
int j, i;
int t;
int bc, gc;
int pbc, pgc;
- char_u *p;
int wbadword[MAXWLEN];
int wgoodword[MAXWLEN];
- const int l_has_mbyte = has_mbyte;
+ const bool l_has_mbyte = has_mbyte;
+ // Lengths with NUL.
+ int badlen;
+ int goodlen;
if (l_has_mbyte) {
// Get the characters from the multi-byte strings and put them in an
// int array for easy access.
- for (p = badword, badlen = 0; *p != NUL; )
+ badlen = 0;
+ for (const char_u *p = badword; *p != NUL; ) {
wbadword[badlen++] = mb_cptr2char_adv(&p);
+ }
wbadword[badlen++] = 0;
- for (p = goodword, goodlen = 0; *p != NUL; )
+ goodlen = 0;
+ for (const char_u *p = goodword; *p != NUL; ) {
wgoodword[goodlen++] = mb_cptr2char_adv(&p);
+ }
wgoodword[goodlen++] = 0;
} else {
badlen = (int)STRLEN(badword) + 1;
@@ -12846,19 +6900,20 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
int score_off;
int minscore;
int round;
- char_u *p;
int wbadword[MAXWLEN];
int wgoodword[MAXWLEN];
// Get the characters from the multi-byte strings and put them in an
// int array for easy access.
bi = 0;
- for (p = badword; *p != NUL; )
+ for (const char_u *p = badword; *p != NUL; ) {
wbadword[bi++] = mb_cptr2char_adv(&p);
+ }
wbadword[bi++] = 0;
gi = 0;
- for (p = goodword; *p != NUL; )
+ for (const char_u *p = goodword; *p != NUL; ) {
wgoodword[gi++] = mb_cptr2char_adv(&p);
+ }
wgoodword[gi++] = 0;
// The idea is to go from start to end over the words. So long as
@@ -12993,19 +7048,17 @@ pop:
// ":spellinfo"
void ex_spellinfo(exarg_T *eap)
{
- langp_T *lp;
- char_u *p;
-
- if (no_spell_checking(curwin))
+ if (no_spell_checking(curwin)) {
return;
+ }
msg_start();
- for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len && !got_int; ++lpi) {
- lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
- msg_puts((char_u *)"file: ");
- msg_puts(lp->lp_slang->sl_fname);
+ for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len && !got_int; lpi++) {
+ langp_T *const lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ msg_puts("file: ");
+ msg_puts((const char *)lp->lp_slang->sl_fname);
msg_putchar('\n');
- p = lp->lp_slang->sl_info;
+ const char *const p = (const char *)lp->lp_slang->sl_info;
if (p != NULL) {
msg_puts(p);
msg_putchar('\n');
@@ -13026,20 +7079,22 @@ void ex_spelldump(exarg_T *eap)
char_u *spl;
long dummy;
- if (no_spell_checking(curwin))
+ if (no_spell_checking(curwin)) {
return;
- get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL);
+ }
+ get_option_value((char_u *)"spl", &dummy, &spl, OPT_LOCAL);
// Create a new empty buffer in a new window.
do_cmdline_cmd("new");
// enable spelling locally in the new window
- set_option_value((char_u*)"spell", true, (char_u*)"", OPT_LOCAL);
- set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL);
+ set_option_value("spell", true, "", OPT_LOCAL);
+ set_option_value("spl", dummy, (char *)spl, OPT_LOCAL);
xfree(spl);
- if (!bufempty() || !buf_valid(curbuf))
+ if (!BUFEMPTY()) {
return;
+ }
spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0);
@@ -13163,7 +7218,7 @@ spell_dump_compl (
// Done all bytes at this node, go up one level.
--depth;
line_breakcheck();
- ins_compl_check_keys(50);
+ ins_compl_check_keys(50, false);
} else {
// Do one more byte at this node.
n = arridx[depth] + curi[depth];
@@ -13258,16 +7313,24 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat, int *dir, int d
if ((flags & (WF_BANNED | WF_RARE | WF_REGION)) || keepcap) {
STRCPY(badword, p);
STRCAT(badword, "/");
- if (keepcap)
+ if (keepcap) {
STRCAT(badword, "=");
- if (flags & WF_BANNED)
+ }
+ if (flags & WF_BANNED) {
STRCAT(badword, "!");
- else if (flags & WF_RARE)
+ } else if (flags & WF_RARE) {
STRCAT(badword, "?");
- if (flags & WF_REGION)
- for (i = 0; i < 7; ++i)
- if (flags & (0x10000 << i))
- sprintf((char *)badword + STRLEN(badword), "%d", i + 1);
+ }
+ if (flags & WF_REGION) {
+ for (i = 0; i < 7; i++) {
+ if (flags & (0x10000 << i)) {
+ const size_t badword_len = STRLEN(badword);
+ snprintf((char *)badword + badword_len,
+ sizeof(badword) - badword_len,
+ "%d", i + 1);
+ }
+ }
+ }
p = badword;
}
@@ -13401,8 +7464,9 @@ char_u *spell_to_word_end(char_u *start, win_T *win)
{
char_u *p = start;
- while (*p != NUL && spell_iswordp(p, win))
- mb_ptr_adv(p);
+ while (*p != NUL && spell_iswordp(p, win)) {
+ MB_PTR_ADV(p);
+ }
return p;
}
@@ -13417,23 +7481,26 @@ int spell_word_start(int startcol)
char_u *p;
int col = 0;
- if (no_spell_checking(curwin))
+ if (no_spell_checking(curwin)) {
return startcol;
+ }
// Find a word character before "startcol".
line = get_cursor_line_ptr();
for (p = line + startcol; p > line; ) {
- mb_ptr_back(line, p);
- if (spell_iswordp_nmw(p, curwin))
+ MB_PTR_BACK(line, p);
+ if (spell_iswordp_nmw(p, curwin)) {
break;
+ }
}
// Go back to start of the word.
while (p > line) {
col = (int)(p - line);
- mb_ptr_back(line, p);
- if (!spell_iswordp(p, curwin))
+ MB_PTR_BACK(line, p);
+ if (!spell_iswordp(p, curwin)) {
break;
+ }
col = 0;
}
@@ -13461,5 +7528,3 @@ int expand_spelling(linenr_T lnum, char_u *pat, char_u ***matchp)
*matchp = ga.ga_data;
return ga.ga_len;
}
-
-
diff --git a/src/nvim/spell.h b/src/nvim/spell.h
index 3a03cb2ef6..ad66df4c5d 100644
--- a/src/nvim/spell.h
+++ b/src/nvim/spell.h
@@ -3,6 +3,10 @@
#include <stdbool.h>
+#include "nvim/spell_defs.h"
+#include "nvim/ex_cmds_defs.h"
+#include "nvim/globals.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "spell.h.generated.h"
#endif
diff --git a/src/nvim/spell_defs.h b/src/nvim/spell_defs.h
new file mode 100644
index 0000000000..e83b21b219
--- /dev/null
+++ b/src/nvim/spell_defs.h
@@ -0,0 +1,291 @@
+#ifndef NVIM_SPELL_DEFS_H
+#define NVIM_SPELL_DEFS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nvim/buffer_defs.h"
+#include "nvim/garray.h"
+#include "nvim/regexp_defs.h"
+#include "nvim/types.h"
+
+#define MAXWLEN 254 // Assume max. word len is this many bytes.
+ // Some places assume a word length fits in a
+ // byte, thus it can't be above 255.
+
+// Number of regions supported.
+#define MAXREGIONS 8
+
+// Type used for indexes in the word tree need to be at least 4 bytes. If int
+// is 8 bytes we could use something smaller, but what?
+typedef int idx_T;
+
+# define SPL_FNAME_TMPL "%s.%s.spl"
+# define SPL_FNAME_ADD ".add."
+# define SPL_FNAME_ASCII ".ascii."
+
+// Flags used for a word. Only the lowest byte can be used, the region byte
+// comes above it.
+#define WF_REGION 0x01 // region byte follows
+#define WF_ONECAP 0x02 // word with one capital (or all capitals)
+#define WF_ALLCAP 0x04 // word must be all capitals
+#define WF_RARE 0x08 // rare word
+#define WF_BANNED 0x10 // bad word
+#define WF_AFX 0x20 // affix ID follows
+#define WF_FIXCAP 0x40 // keep-case word, allcap not allowed
+#define WF_KEEPCAP 0x80 // keep-case word
+
+// for <flags2>, shifted up one byte to be used in wn_flags
+#define WF_HAS_AFF 0x0100 // word includes affix
+#define WF_NEEDCOMP 0x0200 // word only valid in compound
+#define WF_NOSUGGEST 0x0400 // word not to be suggested
+#define WF_COMPROOT 0x0800 // already compounded word, COMPOUNDROOT
+#define WF_NOCOMPBEF 0x1000 // no compounding before this word
+#define WF_NOCOMPAFT 0x2000 // no compounding after this word
+
+// flags for <pflags>
+#define WFP_RARE 0x01 // rare prefix
+#define WFP_NC 0x02 // prefix is not combining
+#define WFP_UP 0x04 // to-upper prefix
+#define WFP_COMPPERMIT 0x08 // prefix with COMPOUNDPERMITFLAG
+#define WFP_COMPFORBID 0x10 // prefix with COMPOUNDFORBIDFLAG
+
+// Flags for postponed prefixes in "sl_pidxs". Must be above affixID (one
+// byte) and prefcondnr (two bytes).
+#define WF_RAREPFX (WFP_RARE << 24) // rare postponed prefix
+#define WF_PFX_NC (WFP_NC << 24) // non-combining postponed prefix
+#define WF_PFX_UP (WFP_UP << 24) // to-upper postponed prefix
+#define WF_PFX_COMPPERMIT (WFP_COMPPERMIT << 24) // postponed prefix with
+ // COMPOUNDPERMITFLAG
+#define WF_PFX_COMPFORBID (WFP_COMPFORBID << 24) // postponed prefix with
+ // COMPOUNDFORBIDFLAG
+
+
+// flags for <compoptions>
+#define COMP_CHECKDUP 1 // CHECKCOMPOUNDDUP
+#define COMP_CHECKREP 2 // CHECKCOMPOUNDREP
+#define COMP_CHECKCASE 4 // CHECKCOMPOUNDCASE
+#define COMP_CHECKTRIPLE 8 // CHECKCOMPOUNDTRIPLE
+
+// Info from "REP", "REPSAL" and "SAL" entries in ".aff" file used in si_rep,
+// si_repsal, sl_rep, and si_sal. Not for sl_sal!
+// One replacement: from "ft_from" to "ft_to".
+typedef struct fromto_S {
+ char_u *ft_from;
+ char_u *ft_to;
+} fromto_T;
+
+// Info from "SAL" entries in ".aff" file used in sl_sal.
+// The info is split for quick processing by spell_soundfold().
+// Note that "sm_oneof" and "sm_rules" point into sm_lead.
+typedef struct salitem_S {
+ char_u *sm_lead; // leading letters
+ int sm_leadlen; // length of "sm_lead"
+ char_u *sm_oneof; // letters from () or NULL
+ char_u *sm_rules; // rules like ^, $, priority
+ char_u *sm_to; // replacement.
+ int *sm_lead_w; // wide character copy of "sm_lead"
+ int *sm_oneof_w; // wide character copy of "sm_oneof"
+ int *sm_to_w; // wide character copy of "sm_to"
+} salitem_T;
+
+typedef int salfirst_T;
+
+// Values for SP_*ERROR are negative, positive values are used by
+// read_cnt_string().
+#define SP_TRUNCERROR -1 // spell file truncated error
+#define SP_FORMERROR -2 // format error in spell file
+#define SP_OTHERERROR -3 // other error while reading spell file
+
+// Structure used to store words and other info for one language, loaded from
+// a .spl file.
+// The main access is through the tree in "sl_fbyts/sl_fidxs", storing the
+// case-folded words. "sl_kbyts/sl_kidxs" is for keep-case words.
+//
+// The "byts" array stores the possible bytes in each tree node, preceded by
+// the number of possible bytes, sorted on byte value:
+// <len> <byte1> <byte2> ...
+// The "idxs" array stores the index of the child node corresponding to the
+// byte in "byts".
+// Exception: when the byte is zero, the word may end here and "idxs" holds
+// the flags, region mask and affixID for the word. There may be several
+// zeros in sequence for alternative flag/region/affixID combinations.
+typedef struct slang_S slang_T;
+
+struct slang_S {
+ slang_T *sl_next; // next language
+ char_u *sl_name; // language name "en", "en.rare", "nl", etc.
+ char_u *sl_fname; // name of .spl file
+ bool sl_add; // true if it's a .add file.
+
+ char_u *sl_fbyts; // case-folded word bytes
+ idx_T *sl_fidxs; // case-folded word indexes
+ char_u *sl_kbyts; // keep-case word bytes
+ idx_T *sl_kidxs; // keep-case word indexes
+ char_u *sl_pbyts; // prefix tree word bytes
+ idx_T *sl_pidxs; // prefix tree word indexes
+
+ char_u *sl_info; // infotext string or NULL
+
+ char_u sl_regions[MAXREGIONS * 2 + 1];
+ // table with up to 8 region names plus NUL
+
+ char_u *sl_midword; // MIDWORD string or NULL
+
+ hashtab_T sl_wordcount; // hashtable with word count, wordcount_T
+
+ int sl_compmax; // COMPOUNDWORDMAX (default: MAXWLEN)
+ int sl_compminlen; // COMPOUNDMIN (default: 0)
+ int sl_compsylmax; // COMPOUNDSYLMAX (default: MAXWLEN)
+ int sl_compoptions; // COMP_* flags
+ garray_T sl_comppat; // CHECKCOMPOUNDPATTERN items
+ regprog_T *sl_compprog; // COMPOUNDRULE turned into a regexp progrm
+ // (NULL when no compounding)
+ char_u *sl_comprules; // all COMPOUNDRULE concatenated (or NULL)
+ char_u *sl_compstartflags; // flags for first compound word
+ char_u *sl_compallflags; // all flags for compound words
+ bool sl_nobreak; // When true: no spaces between words
+ char_u *sl_syllable; // SYLLABLE repeatable chars or NULL
+ garray_T sl_syl_items; // syllable items
+
+ int sl_prefixcnt; // number of items in "sl_prefprog"
+ regprog_T **sl_prefprog; // table with regprogs for prefixes
+
+ garray_T sl_rep; // list of fromto_T entries from REP lines
+ int16_t sl_rep_first[256]; // indexes where byte first appears, -1 if
+ // there is none
+ garray_T sl_sal; // list of salitem_T entries from SAL lines
+ salfirst_T sl_sal_first[256]; // indexes where byte first appears, -1 if
+ // there is none
+ bool sl_followup; // SAL followup
+ bool sl_collapse; // SAL collapse_result
+ bool sl_rem_accents; // SAL remove_accents
+ bool sl_sofo; // SOFOFROM and SOFOTO instead of SAL items:
+ // "sl_sal_first" maps chars, when has_mbyte
+ // "sl_sal" is a list of wide char lists.
+ garray_T sl_repsal; // list of fromto_T entries from REPSAL lines
+ int16_t sl_repsal_first[256]; // sl_rep_first for REPSAL lines
+ bool sl_nosplitsugs; // don't suggest splitting a word
+ bool sl_nocompoundsugs; // don't suggest compounding
+
+ // Info from the .sug file. Loaded on demand.
+ time_t sl_sugtime; // timestamp for .sug file
+ char_u *sl_sbyts; // soundfolded word bytes
+ idx_T *sl_sidxs; // soundfolded word indexes
+ buf_T *sl_sugbuf; // buffer with word number table
+ bool sl_sugloaded; // true when .sug file was loaded or failed to
+ // load
+
+ bool sl_has_map; // true, if there is a MAP line
+ hashtab_T sl_map_hash; // MAP for multi-byte chars
+ int sl_map_array[256]; // MAP for first 256 chars
+ hashtab_T sl_sounddone; // table with soundfolded words that have
+ // handled, see add_sound_suggest()
+};
+
+// Structure used in "b_langp", filled from 'spelllang'.
+typedef struct langp_S {
+ slang_T *lp_slang; // info for this language
+ slang_T *lp_sallang; // language used for sound folding or NULL
+ slang_T *lp_replang; // language used for REP items or NULL
+ int lp_region; // bitmask for region or REGION_ALL
+} langp_T;
+
+#define LANGP_ENTRY(ga, i) (((langp_T *)(ga).ga_data) + (i))
+
+#define VIMSUGMAGIC "VIMsug" // string at start of Vim .sug file
+#define VIMSUGMAGICL 6
+#define VIMSUGVERSION 1
+
+#define REGION_ALL 0xff // word valid in all regions
+
+// The tables used for recognizing word characters according to spelling.
+// These are only used for the first 256 characters of 'encoding'.
+typedef struct {
+ bool st_isw[256]; // flags: is word char
+ bool st_isu[256]; // flags: is uppercase char
+ char_u st_fold[256]; // chars: folded case
+ char_u st_upper[256]; // chars: upper case
+} spelltab_T;
+
+// For finding suggestions: At each node in the tree these states are tried:
+typedef enum {
+ STATE_START = 0, // At start of node check for NUL bytes (goodword
+ // ends); if badword ends there is a match, otherwise
+ // try splitting word.
+ STATE_NOPREFIX, // try without prefix
+ STATE_SPLITUNDO, // Undo splitting.
+ STATE_ENDNUL, // Past NUL bytes at start of the node.
+ STATE_PLAIN, // Use each byte of the node.
+ STATE_DEL, // Delete a byte from the bad word.
+ STATE_INS_PREP, // Prepare for inserting bytes.
+ STATE_INS, // Insert a byte in the bad word.
+ STATE_SWAP, // Swap two bytes.
+ STATE_UNSWAP, // Undo swap two characters.
+ STATE_SWAP3, // Swap two characters over three.
+ STATE_UNSWAP3, // Undo Swap two characters over three.
+ STATE_UNROT3L, // Undo rotate three characters left
+ STATE_UNROT3R, // Undo rotate three characters right
+ STATE_REP_INI, // Prepare for using REP items.
+ STATE_REP, // Use matching REP items from the .aff file.
+ STATE_REP_UNDO, // Undo a REP item replacement.
+ STATE_FINAL // End of this node.
+} state_T;
+
+// Struct to keep the state at each level in suggest_try_change().
+typedef struct trystate_S {
+ state_T ts_state; // state at this level, STATE_
+ int ts_score; // score
+ idx_T ts_arridx; // index in tree array, start of node
+ short ts_curi; // index in list of child nodes
+ char_u ts_fidx; // index in fword[], case-folded bad word
+ char_u ts_fidxtry; // ts_fidx at which bytes may be changed
+ char_u ts_twordlen; // valid length of tword[]
+ char_u ts_prefixdepth; // stack depth for end of prefix or
+ // PFD_PREFIXTREE or PFD_NOPREFIX
+ char_u ts_flags; // TSF_ flags
+ char_u ts_tcharlen; // number of bytes in tword character
+ char_u ts_tcharidx; // current byte index in tword character
+ char_u ts_isdiff; // DIFF_ values
+ char_u ts_fcharstart; // index in fword where badword char started
+ char_u ts_prewordlen; // length of word in "preword[]"
+ char_u ts_splitoff; // index in "tword" after last split
+ char_u ts_splitfidx; // "ts_fidx" at word split
+ char_u ts_complen; // nr of compound words used
+ char_u ts_compsplit; // index for "compflags" where word was spit
+ char_u ts_save_badflags; // su_badflags saved here
+ char_u ts_delidx; // index in fword for char that was deleted,
+ // valid when "ts_flags" has TSF_DIDDEL
+} trystate_T;
+
+// Use our own character-case definitions, because the current locale may
+// differ from what the .spl file uses.
+// These must not be called with negative number!
+#include <wchar.h> // for towupper() and towlower()
+// Multi-byte implementation. For Unicode we can call utf_*(), but don't do
+// that for ASCII, because we don't want to use 'casemap' here. Otherwise use
+// the "w" library function for characters above 255.
+#define SPELL_TOFOLD(c) (enc_utf8 && (c) >= 128 ? utf_fold(c) \
+ : (c) < \
+ 256 ? (int)spelltab.st_fold[c] : (int)towlower(c))
+
+#define SPELL_TOUPPER(c) (enc_utf8 && (c) >= 128 ? mb_toupper(c) \
+ : (c) < \
+ 256 ? (int)spelltab.st_upper[c] : (int)towupper(c))
+
+#define SPELL_ISUPPER(c) (enc_utf8 && (c) >= 128 ? mb_isupper(c) \
+ : (c) < 256 ? spelltab.st_isu[c] : iswupper(c))
+
+// First language that is loaded, start of the linked list of loaded
+// languages.
+extern slang_T *first_lang;
+
+// file used for "zG" and "zW"
+extern char_u *int_wordlist;
+
+extern spelltab_T spelltab;
+extern int did_set_spelltab;
+
+extern char *e_format;
+
+#endif // NVIM_SPELL_DEFS_H
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
new file mode 100644
index 0000000000..7a6f2fce39
--- /dev/null
+++ b/src/nvim/spellfile.c
@@ -0,0 +1,5727 @@
+// 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
+
+// spellfile.c: code for reading and writing spell files.
+//
+// See spell.c for information about spell checking.
+
+// Vim spell file format: <HEADER>
+// <SECTIONS>
+// <LWORDTREE>
+// <KWORDTREE>
+// <PREFIXTREE>
+//
+// <HEADER>: <fileID> <versionnr>
+//
+// <fileID> 8 bytes "VIMspell"
+// <versionnr> 1 byte VIMSPELLVERSION
+//
+//
+// Sections make it possible to add information to the .spl file without
+// making it incompatible with previous versions. There are two kinds of
+// sections:
+// 1. Not essential for correct spell checking. E.g. for making suggestions.
+// These are skipped when not supported.
+// 2. Optional information, but essential for spell checking when present.
+// E.g. conditions for affixes. When this section is present but not
+// supported an error message is given.
+//
+// <SECTIONS>: <section> ... <sectionend>
+//
+// <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
+//
+// <sectionID> 1 byte number from 0 to 254 identifying the section
+//
+// <sectionflags> 1 byte SNF_REQUIRED: this section is required for correct
+// spell checking
+//
+// <sectionlen> 4 bytes length of section contents, MSB first
+//
+// <sectionend> 1 byte SN_END
+//
+//
+// sectionID == SN_INFO: <infotext>
+// <infotext> N bytes free format text with spell file info (version,
+// website, etc)
+//
+// sectionID == SN_REGION: <regionname> ...
+// <regionname> 2 bytes Up to MAXREGIONS region names: ca, au, etc.
+// Lower case.
+// First <regionname> is region 1.
+//
+// sectionID == SN_CHARFLAGS: <charflagslen> <charflags>
+// <folcharslen> <folchars>
+// <charflagslen> 1 byte Number of bytes in <charflags> (should be 128).
+// <charflags> N bytes List of flags (first one is for character 128):
+// 0x01 word character CF_WORD
+// 0x02 upper-case character CF_UPPER
+// <folcharslen> 2 bytes Number of bytes in <folchars>.
+// <folchars> N bytes Folded characters, first one is for character 128.
+//
+// sectionID == SN_MIDWORD: <midword>
+// <midword> N bytes Characters that are word characters only when used
+// in the middle of a word.
+//
+// sectionID == SN_PREFCOND: <prefcondcnt> <prefcond> ...
+// <prefcondcnt> 2 bytes Number of <prefcond> items following.
+// <prefcond> : <condlen> <condstr>
+// <condlen> 1 byte Length of <condstr>.
+// <condstr> N bytes Condition for the prefix.
+//
+// sectionID == SN_REP: <repcount> <rep> ...
+// <repcount> 2 bytes number of <rep> items, MSB first.
+// <rep> : <repfromlen> <repfrom> <reptolen> <repto>
+// <repfromlen> 1 byte length of <repfrom>
+// <repfrom> N bytes "from" part of replacement
+// <reptolen> 1 byte length of <repto>
+// <repto> N bytes "to" part of replacement
+//
+// sectionID == SN_REPSAL: <repcount> <rep> ...
+// just like SN_REP but for soundfolded words
+//
+// sectionID == SN_SAL: <salflags> <salcount> <sal> ...
+// <salflags> 1 byte flags for soundsalike conversion:
+// SAL_F0LLOWUP
+// SAL_COLLAPSE
+// SAL_REM_ACCENTS
+// <salcount> 2 bytes number of <sal> items following
+// <sal> : <salfromlen> <salfrom> <saltolen> <salto>
+// <salfromlen> 1 byte length of <salfrom>
+// <salfrom> N bytes "from" part of soundsalike
+// <saltolen> 1 byte length of <salto>
+// <salto> N bytes "to" part of soundsalike
+//
+// sectionID == SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+// <sofofromlen> 2 bytes length of <sofofrom>
+// <sofofrom> N bytes "from" part of soundfold
+// <sofotolen> 2 bytes length of <sofoto>
+// <sofoto> N bytes "to" part of soundfold
+//
+// sectionID == SN_SUGFILE: <timestamp>
+// <timestamp> 8 bytes time in seconds that must match with .sug file
+//
+// sectionID == SN_NOSPLITSUGS: nothing
+//
+// sectionID == SN_NOCOMPOUNDSUGS: nothing
+//
+// sectionID == SN_WORDS: <word> ...
+// <word> N bytes NUL terminated common word
+//
+// sectionID == SN_MAP: <mapstr>
+// <mapstr> N bytes String with sequences of similar characters,
+// separated by slashes.
+//
+// sectionID == SN_COMPOUND: <compmax> <compminlen> <compsylmax> <compoptions>
+// <comppatcount> <comppattern> ... <compflags>
+// <compmax> 1 byte Maximum nr of words in compound word.
+// <compminlen> 1 byte Minimal word length for compounding.
+// <compsylmax> 1 byte Maximum nr of syllables in compound word.
+// <compoptions> 2 bytes COMP_ flags.
+// <comppatcount> 2 bytes number of <comppattern> following
+// <compflags> N bytes Flags from COMPOUNDRULE items, separated by
+// slashes.
+//
+// <comppattern>: <comppatlen> <comppattext>
+// <comppatlen> 1 byte length of <comppattext>
+// <comppattext> N bytes end or begin chars from CHECKCOMPOUNDPATTERN
+//
+// sectionID == SN_NOBREAK: (empty, its presence is what matters)
+//
+// sectionID == SN_SYLLABLE: <syllable>
+// <syllable> N bytes String from SYLLABLE item.
+//
+// <LWORDTREE>: <wordtree>
+//
+// <KWORDTREE>: <wordtree>
+//
+// <PREFIXTREE>: <wordtree>
+//
+//
+// <wordtree>: <nodecount> <nodedata> ...
+//
+// <nodecount> 4 bytes Number of nodes following. MSB first.
+//
+// <nodedata>: <siblingcount> <sibling> ...
+//
+// <siblingcount> 1 byte Number of siblings in this node. The siblings
+// follow in sorted order.
+//
+// <sibling>: <byte> [ <nodeidx> <xbyte>
+// | <flags> [<flags2>] [<region>] [<affixID>]
+// | [<pflags>] <affixID> <prefcondnr> ]
+//
+// <byte> 1 byte Byte value of the sibling. Special cases:
+// BY_NOFLAGS: End of word without flags and for all
+// regions.
+// For PREFIXTREE <affixID> and
+// <prefcondnr> follow.
+// BY_FLAGS: End of word, <flags> follow.
+// For PREFIXTREE <pflags>, <affixID>
+// and <prefcondnr> follow.
+// BY_FLAGS2: End of word, <flags> and <flags2>
+// follow. Not used in PREFIXTREE.
+// BY_INDEX: Child of sibling is shared, <nodeidx>
+// and <xbyte> follow.
+//
+// <nodeidx> 3 bytes Index of child for this sibling, MSB first.
+//
+// <xbyte> 1 byte Byte value of the sibling.
+//
+// <flags> 1 byte Bitmask of:
+// WF_ALLCAP word must have only capitals
+// WF_ONECAP first char of word must be capital
+// WF_KEEPCAP keep-case word
+// WF_FIXCAP keep-case word, all caps not allowed
+// WF_RARE rare word
+// WF_BANNED bad word
+// WF_REGION <region> follows
+// WF_AFX <affixID> follows
+//
+// <flags2> 1 byte Bitmask of:
+// WF_HAS_AFF >> 8 word includes affix
+// WF_NEEDCOMP >> 8 word only valid in compound
+// WF_NOSUGGEST >> 8 word not used for suggestions
+// WF_COMPROOT >> 8 word already a compound
+// WF_NOCOMPBEF >> 8 no compounding before this word
+// WF_NOCOMPAFT >> 8 no compounding after this word
+//
+// <pflags> 1 byte Bitmask of:
+// WFP_RARE rare prefix
+// WFP_NC non-combining prefix
+// WFP_UP letter after prefix made upper case
+//
+// <region> 1 byte Bitmask for regions in which word is valid. When
+// omitted it's valid in all regions.
+// Lowest bit is for region 1.
+//
+// <affixID> 1 byte ID of affix that can be used with this word. In
+// PREFIXTREE used for the required prefix ID.
+//
+// <prefcondnr> 2 bytes Prefix condition number, index in <prefcond> list
+// from HEADER.
+//
+// All text characters are in 'encoding', but stored as single bytes.
+
+// Vim .sug file format: <SUGHEADER>
+// <SUGWORDTREE>
+// <SUGTABLE>
+//
+// <SUGHEADER>: <fileID> <versionnr> <timestamp>
+//
+// <fileID> 6 bytes "VIMsug"
+// <versionnr> 1 byte VIMSUGVERSION
+// <timestamp> 8 bytes timestamp that must match with .spl file
+//
+//
+// <SUGWORDTREE>: <wordtree> (see above, no flags or region used)
+//
+//
+// <SUGTABLE>: <sugwcount> <sugline> ...
+//
+// <sugwcount> 4 bytes number of <sugline> following
+//
+// <sugline>: <sugnr> ... NUL
+//
+// <sugnr>: X bytes word number that results in this soundfolded word,
+// stored as an offset to the previous number in as
+// few bytes as possible, see offset2bytes())
+
+#include <stdio.h>
+#include <stdint.h>
+#include <wctype.h>
+
+#include "nvim/vim.h"
+#include "nvim/spell_defs.h"
+#include "nvim/ascii.h"
+#include "nvim/buffer.h"
+#include "nvim/charset.h"
+#include "nvim/ex_cmds2.h"
+#include "nvim/fileio.h"
+#include "nvim/memory.h"
+#include "nvim/memline.h"
+#include "nvim/misc1.h"
+#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/path.h"
+#include "nvim/regexp.h"
+#include "nvim/screen.h"
+#include "nvim/spell.h"
+#include "nvim/spellfile.h"
+#include "nvim/ui.h"
+#include "nvim/undo.h"
+
+#ifndef UNIX // it's in os/unix_defs.h for Unix
+# include <time.h> // for time_t
+#endif
+
+// Special byte values for <byte>. Some are only used in the tree for
+// postponed prefixes, some only in the other trees. This is a bit messy...
+#define BY_NOFLAGS 0 // end of word without flags or region; for
+ // postponed prefix: no <pflags>
+#define BY_INDEX 1 // child is shared, index follows
+#define BY_FLAGS 2 // end of word, <flags> byte follows; for
+ // postponed prefix: <pflags> follows
+#define BY_FLAGS2 3 // end of word, <flags> and <flags2> bytes
+ // follow; never used in prefix tree
+#define BY_SPECIAL BY_FLAGS2 // highest special byte value
+
+// Flags used in .spl file for soundsalike flags.
+#define SAL_F0LLOWUP 1
+#define SAL_COLLAPSE 2
+#define SAL_REM_ACCENTS 4
+
+#define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file
+#define VIMSPELLMAGICL (sizeof(VIMSPELLMAGIC) - 1)
+#define VIMSPELLVERSION 50
+
+// Section IDs. Only renumber them when VIMSPELLVERSION changes!
+#define SN_REGION 0 // <regionname> section
+#define SN_CHARFLAGS 1 // charflags section
+#define SN_MIDWORD 2 // <midword> section
+#define SN_PREFCOND 3 // <prefcond> section
+#define SN_REP 4 // REP items section
+#define SN_SAL 5 // SAL items section
+#define SN_SOFO 6 // soundfolding section
+#define SN_MAP 7 // MAP items section
+#define SN_COMPOUND 8 // compound words section
+#define SN_SYLLABLE 9 // syllable section
+#define SN_NOBREAK 10 // NOBREAK section
+#define SN_SUGFILE 11 // timestamp for .sug file
+#define SN_REPSAL 12 // REPSAL items section
+#define SN_WORDS 13 // common words
+#define SN_NOSPLITSUGS 14 // don't split word for suggestions
+#define SN_INFO 15 // info section
+#define SN_NOCOMPOUNDSUGS 16 // don't compound for suggestions
+#define SN_END 255 // end of sections
+
+#define SNF_REQUIRED 1 // <sectionflags>: required section
+
+#define CF_WORD 0x01
+#define CF_UPPER 0x02
+
+static char *e_spell_trunc = N_("E758: Truncated spell file");
+static char *e_afftrailing = N_("Trailing text in %s line %d: %s");
+static char *e_affname = N_("Affix name too long in %s line %d: %s");
+static char *e_affform = N_("E761: Format error in affix file FOL, LOW or UPP");
+static char *e_affrange = N_(
+ "E762: Character in FOL, LOW or UPP is out of range");
+static char *msg_compressing = N_("Compressing word tree...");
+
+#define MAXLINELEN 500 // Maximum length in bytes of a line in a .aff
+ // and .dic file.
+// Main structure to store the contents of a ".aff" file.
+typedef struct afffile_S {
+ char_u *af_enc; // "SET", normalized, alloc'ed string or NULL
+ int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG
+ unsigned af_rare; // RARE ID for rare word
+ unsigned af_keepcase; // KEEPCASE ID for keep-case word
+ unsigned af_bad; // BAD ID for banned word
+ unsigned af_needaffix; // NEEDAFFIX ID
+ unsigned af_circumfix; // CIRCUMFIX ID
+ unsigned af_needcomp; // NEEDCOMPOUND ID
+ unsigned af_comproot; // COMPOUNDROOT ID
+ unsigned af_compforbid; // COMPOUNDFORBIDFLAG ID
+ unsigned af_comppermit; // COMPOUNDPERMITFLAG ID
+ unsigned af_nosuggest; // NOSUGGEST ID
+ int af_pfxpostpone; // postpone prefixes without chop string and
+ // without flags
+ bool af_ignoreextra; // IGNOREEXTRA present
+ hashtab_T af_pref; // hashtable for prefixes, affheader_T
+ hashtab_T af_suff; // hashtable for suffixes, affheader_T
+ hashtab_T af_comp; // hashtable for compound flags, compitem_T
+} afffile_T;
+
+#define AFT_CHAR 0 // flags are one character
+#define AFT_LONG 1 // flags are two characters
+#define AFT_CAPLONG 2 // flags are one or two characters
+#define AFT_NUM 3 // flags are numbers, comma separated
+
+typedef struct affentry_S affentry_T;
+// Affix entry from ".aff" file. Used for prefixes and suffixes.
+struct affentry_S {
+ affentry_T *ae_next; // next affix with same name/number
+ char_u *ae_chop; // text to chop off basic word (can be NULL)
+ char_u *ae_add; // text to add to basic word (can be NULL)
+ char_u *ae_flags; // flags on the affix (can be NULL)
+ char_u *ae_cond; // condition (NULL for ".")
+ regprog_T *ae_prog; // regexp program for ae_cond or NULL
+ char ae_compforbid; // COMPOUNDFORBIDFLAG found
+ char ae_comppermit; // COMPOUNDPERMITFLAG found
+};
+
+# define AH_KEY_LEN 17 // 2 x 8 bytes + NUL
+
+// Affix header from ".aff" file. Used for af_pref and af_suff.
+typedef struct affheader_S {
+ char_u ah_key[AH_KEY_LEN]; // key for hashtab == name of affix
+ unsigned ah_flag; // affix name as number, uses "af_flagtype"
+ int ah_newID; // prefix ID after renumbering; 0 if not used
+ int ah_combine; // suffix may combine with prefix
+ int ah_follows; // another affix block should be following
+ affentry_T *ah_first; // first affix entry
+} affheader_T;
+
+#define HI2AH(hi) ((affheader_T *)(hi)->hi_key)
+
+// Flag used in compound items.
+typedef struct compitem_S {
+ char_u ci_key[AH_KEY_LEN]; // key for hashtab == name of compound
+ unsigned ci_flag; // affix name as number, uses "af_flagtype"
+ int ci_newID; // affix ID after renumbering.
+} compitem_T;
+
+#define HI2CI(hi) ((compitem_T *)(hi)->hi_key)
+
+// Structure that is used to store the items in the word tree. This avoids
+// the need to keep track of each allocated thing, everything is freed all at
+// once after ":mkspell" is done.
+// Note: "sb_next" must be just before "sb_data" to make sure the alignment of
+// "sb_data" is correct for systems where pointers must be aligned on
+// pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc).
+#define SBLOCKSIZE 16000 // size of sb_data
+typedef struct sblock_S sblock_T;
+struct sblock_S {
+ int sb_used; // nr of bytes already in use
+ sblock_T *sb_next; // next block in list
+ char_u sb_data[1]; // data, actually longer
+};
+
+// A node in the tree.
+typedef struct wordnode_S wordnode_T;
+struct wordnode_S {
+ union { // shared to save space
+ char_u hashkey[6]; // the hash key, only used while compressing
+ int index; // index in written nodes (valid after first
+ // round)
+ } wn_u1;
+ union { // shared to save space
+ wordnode_T *next; // next node with same hash key
+ wordnode_T *wnode; // parent node that will write this node
+ } wn_u2;
+ wordnode_T *wn_child; // child (next byte in word)
+ wordnode_T *wn_sibling; // next sibling (alternate byte in word,
+ // always sorted)
+ int wn_refs; // Nr. of references to this node. Only
+ // relevant for first node in a list of
+ // siblings, in following siblings it is
+ // always one.
+ char_u wn_byte; // Byte for this node. NUL for word end
+
+ // Info for when "wn_byte" is NUL.
+ // In PREFIXTREE "wn_region" is used for the prefcondnr.
+ // In the soundfolded word tree "wn_flags" has the MSW of the wordnr and
+ // "wn_region" the LSW of the wordnr.
+ char_u wn_affixID; // supported/required prefix ID or 0
+ uint16_t wn_flags; // WF_ flags
+ short wn_region; // region mask
+
+#ifdef SPELL_PRINTTREE
+ int wn_nr; // sequence nr for printing
+#endif
+};
+
+#define WN_MASK 0xffff // mask relevant bits of "wn_flags"
+
+#define HI2WN(hi) (wordnode_T *)((hi)->hi_key)
+
+// Info used while reading the spell files.
+typedef struct spellinfo_S {
+ wordnode_T *si_foldroot; // tree with case-folded words
+ long si_foldwcount; // nr of words in si_foldroot
+
+ wordnode_T *si_keeproot; // tree with keep-case words
+ long si_keepwcount; // nr of words in si_keeproot
+
+ wordnode_T *si_prefroot; // tree with postponed prefixes
+
+ long si_sugtree; // creating the soundfolding trie
+
+ sblock_T *si_blocks; // memory blocks used
+ long si_blocks_cnt; // memory blocks allocated
+ int si_did_emsg; // TRUE when ran out of memory
+
+ long si_compress_cnt; // words to add before lowering
+ // compression limit
+ wordnode_T *si_first_free; // List of nodes that have been freed during
+ // compression, linked by "wn_child" field.
+ long si_free_count; // number of nodes in si_first_free
+#ifdef SPELL_PRINTTREE
+ int si_wordnode_nr; // sequence nr for nodes
+#endif
+ buf_T *si_spellbuf; // buffer used to store soundfold word table
+
+ int si_ascii; // handling only ASCII words
+ int si_add; // addition file
+ int si_clear_chartab; // when TRUE clear char tables
+ int si_region; // region mask
+ vimconv_T si_conv; // for conversion to 'encoding'
+ int si_memtot; // runtime memory used
+ int si_verbose; // verbose messages
+ int si_msg_count; // number of words added since last message
+ char_u *si_info; // info text chars or NULL
+ int si_region_count; // number of regions supported (1 when there
+ // are no regions)
+ char_u si_region_name[MAXREGIONS * 2 + 1];
+ // region names; used only if
+ // si_region_count > 1)
+
+ garray_T si_rep; // list of fromto_T entries from REP lines
+ garray_T si_repsal; // list of fromto_T entries from REPSAL lines
+ garray_T si_sal; // list of fromto_T entries from SAL lines
+ char_u *si_sofofr; // SOFOFROM text
+ char_u *si_sofoto; // SOFOTO text
+ int si_nosugfile; // NOSUGFILE item found
+ int si_nosplitsugs; // NOSPLITSUGS item found
+ int si_nocompoundsugs; // NOCOMPOUNDSUGS item found
+ int si_followup; // soundsalike: ?
+ int si_collapse; // soundsalike: ?
+ hashtab_T si_commonwords; // hashtable for common words
+ time_t si_sugtime; // timestamp for .sug file
+ int si_rem_accents; // soundsalike: remove accents
+ garray_T si_map; // MAP info concatenated
+ char_u *si_midword; // MIDWORD chars or NULL
+ int si_compmax; // max nr of words for compounding
+ int si_compminlen; // minimal length for compounding
+ int si_compsylmax; // max nr of syllables for compounding
+ int si_compoptions; // COMP_ flags
+ garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as
+ // a string
+ char_u *si_compflags; // flags used for compounding
+ char_u si_nobreak; // NOBREAK
+ char_u *si_syllable; // syllable string
+ garray_T si_prefcond; // table with conditions for postponed
+ // prefixes, each stored as a string
+ int si_newprefID; // current value for ah_newID
+ int si_newcompID; // current value for compound ID
+} spellinfo_T;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "spellfile.c.generated.h"
+#endif
+
+/// Read n bytes from fd to buf, returning on errors
+///
+/// @param[out] buf Buffer to read to, must be at least n bytes long.
+/// @param[in] n Amount of bytes to read.
+/// @param fd FILE* to read from.
+/// @param exit_code Code to run before returning.
+///
+/// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if
+/// there are not enough bytes, returns SP_OTHERERROR if reading failed.
+#define SPELL_READ_BYTES(buf, n, fd, exit_code) \
+ do { \
+ const size_t n__SPRB = (n); \
+ FILE *const fd__SPRB = (fd); \
+ char *const buf__SPRB = (buf); \
+ const size_t read_bytes__SPRB = fread(buf__SPRB, 1, n__SPRB, fd__SPRB); \
+ if (read_bytes__SPRB != n__SPRB) { \
+ exit_code; \
+ return feof(fd__SPRB) ? SP_TRUNCERROR : SP_OTHERERROR; \
+ } \
+ } while (0)
+
+/// Like #SPELL_READ_BYTES, but also error out if NUL byte was read
+///
+/// @return Allows to proceed if everything is OK, returns SP_TRUNCERROR if
+/// there are not enough bytes, returns SP_OTHERERROR if reading failed,
+/// returns SP_FORMERROR if read out a NUL byte.
+#define SPELL_READ_NONNUL_BYTES(buf, n, fd, exit_code) \
+ do { \
+ const size_t n__SPRNB = (n); \
+ FILE *const fd__SPRNB = (fd); \
+ char *const buf__SPRNB = (buf); \
+ SPELL_READ_BYTES(buf__SPRNB, n__SPRNB, fd__SPRNB, exit_code); \
+ if (memchr(buf__SPRNB, NUL, (size_t)n__SPRNB)) { \
+ exit_code; \
+ return SP_FORMERROR; \
+ } \
+ } while (0)
+
+/// Check that spell file starts with a magic string
+///
+/// Does not check for version of the file.
+///
+/// @param fd File to check.
+///
+/// @return 0 in case of success, SP_TRUNCERROR if file contains not enough
+/// bytes, SP_FORMERROR if it does not match magic string and
+/// SP_OTHERERROR if reading file failed.
+static inline int spell_check_magic_string(FILE *const fd)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
+{
+ char buf[VIMSPELLMAGICL];
+ SPELL_READ_BYTES(buf, VIMSPELLMAGICL, fd, ;);
+ if (memcmp(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) {
+ return SP_FORMERROR;
+ }
+ return 0;
+}
+
+// Load one spell file and store the info into a slang_T.
+//
+// This is invoked in three ways:
+// - From spell_load_cb() to load a spell file for the first time. "lang" is
+// the language name, "old_lp" is NULL. Will allocate an slang_T.
+// - To reload a spell file that was changed. "lang" is NULL and "old_lp"
+// points to the existing slang_T.
+// - Just after writing a .spl file; it's read back to produce the .sug file.
+// "old_lp" is NULL and "lang" is NULL. Will allocate an slang_T.
+//
+// Returns the slang_T the spell file was loaded into. NULL for error.
+slang_T *
+spell_load_file (
+ char_u *fname,
+ char_u *lang,
+ slang_T *old_lp,
+ bool silent // no error if file doesn't exist
+)
+{
+ FILE *fd;
+ char_u *p;
+ int n;
+ int len;
+ char_u *save_sourcing_name = sourcing_name;
+ linenr_T save_sourcing_lnum = sourcing_lnum;
+ slang_T *lp = NULL;
+ int c = 0;
+ int res;
+
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ if (!silent)
+ EMSG2(_(e_notopen), fname);
+ else if (p_verbose > 2) {
+ verbose_enter();
+ smsg((char *)e_notopen, fname);
+ verbose_leave();
+ }
+ goto endFAIL;
+ }
+ if (p_verbose > 2) {
+ verbose_enter();
+ smsg(_("Reading spell file \"%s\""), fname);
+ verbose_leave();
+ }
+
+ if (old_lp == NULL) {
+ lp = slang_alloc(lang);
+
+ // Remember the file name, used to reload the file when it's updated.
+ lp->sl_fname = vim_strsave(fname);
+
+ // Check for .add.spl.
+ lp->sl_add = strstr((char *)path_tail(fname), SPL_FNAME_ADD) != NULL;
+ } else
+ lp = old_lp;
+
+ // Set sourcing_name, so that error messages mention the file name.
+ sourcing_name = fname;
+ sourcing_lnum = 0;
+
+ // <HEADER>: <fileID>
+ const int scms_ret = spell_check_magic_string(fd);
+ switch (scms_ret) {
+ case SP_FORMERROR:
+ case SP_TRUNCERROR: {
+ emsgf(_("E757: This does not look like a spell file"));
+ goto endFAIL;
+ }
+ case SP_OTHERERROR: {
+ emsgf(_("E5042: Failed to read spell file %s: %s"),
+ fname, strerror(ferror(fd)));
+ }
+ case 0: {
+ break;
+ }
+ }
+ c = getc(fd); // <versionnr>
+ if (c < VIMSPELLVERSION) {
+ EMSG(_("E771: Old spell file, needs to be updated"));
+ goto endFAIL;
+ } else if (c > VIMSPELLVERSION) {
+ EMSG(_("E772: Spell file is for newer version of Vim"));
+ goto endFAIL;
+ }
+
+
+ // <SECTIONS>: <section> ... <sectionend>
+ // <section>: <sectionID> <sectionflags> <sectionlen> (section contents)
+ for (;; ) {
+ n = getc(fd); // <sectionID> or <sectionend>
+ if (n == SN_END)
+ break;
+ c = getc(fd); // <sectionflags>
+ len = get4c(fd); // <sectionlen>
+ if (len < 0)
+ goto truncerr;
+
+ res = 0;
+ switch (n) {
+ case SN_INFO:
+ lp->sl_info = READ_STRING(fd, len); // <infotext>
+ if (lp->sl_info == NULL)
+ goto endFAIL;
+ break;
+
+ case SN_REGION:
+ res = read_region_section(fd, lp, len);
+ break;
+
+ case SN_CHARFLAGS:
+ res = read_charflags_section(fd);
+ break;
+
+ case SN_MIDWORD:
+ lp->sl_midword = READ_STRING(fd, len); // <midword>
+ if (lp->sl_midword == NULL)
+ goto endFAIL;
+ break;
+
+ case SN_PREFCOND:
+ res = read_prefcond_section(fd, lp);
+ break;
+
+ case SN_REP:
+ res = read_rep_section(fd, &lp->sl_rep, lp->sl_rep_first);
+ break;
+
+ case SN_REPSAL:
+ res = read_rep_section(fd, &lp->sl_repsal, lp->sl_repsal_first);
+ break;
+
+ case SN_SAL:
+ res = read_sal_section(fd, lp);
+ break;
+
+ case SN_SOFO:
+ res = read_sofo_section(fd, lp);
+ break;
+
+ case SN_MAP:
+ p = READ_STRING(fd, len); // <mapstr>
+ if (p == NULL)
+ goto endFAIL;
+ set_map_str(lp, p);
+ xfree(p);
+ break;
+
+ case SN_WORDS:
+ res = read_words_section(fd, lp, len);
+ break;
+
+ case SN_SUGFILE:
+ lp->sl_sugtime = get8ctime(fd); // <timestamp>
+ break;
+
+ case SN_NOSPLITSUGS:
+ lp->sl_nosplitsugs = true;
+ break;
+
+ case SN_NOCOMPOUNDSUGS:
+ lp->sl_nocompoundsugs = true;
+ break;
+
+ case SN_COMPOUND:
+ res = read_compound(fd, lp, len);
+ break;
+
+ case SN_NOBREAK:
+ lp->sl_nobreak = true;
+ break;
+
+ case SN_SYLLABLE:
+ lp->sl_syllable = READ_STRING(fd, len); // <syllable>
+ if (lp->sl_syllable == NULL)
+ goto endFAIL;
+ if (init_syl_tab(lp) == FAIL)
+ goto endFAIL;
+ break;
+
+ default:
+ // Unsupported section. When it's required give an error
+ // message. When it's not required skip the contents.
+ if (c & SNF_REQUIRED) {
+ EMSG(_("E770: Unsupported section in spell file"));
+ goto endFAIL;
+ }
+ while (--len >= 0)
+ if (getc(fd) < 0)
+ goto truncerr;
+ break;
+ }
+someerror:
+ if (res == SP_FORMERROR) {
+ EMSG(_(e_format));
+ goto endFAIL;
+ }
+ if (res == SP_TRUNCERROR) {
+truncerr:
+ EMSG(_(e_spell_trunc));
+ goto endFAIL;
+ }
+ if (res == SP_OTHERERROR)
+ goto endFAIL;
+ }
+
+ // <LWORDTREE>
+ res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, false, 0);
+ if (res != 0)
+ goto someerror;
+
+ // <KWORDTREE>
+ res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, false, 0);
+ if (res != 0)
+ goto someerror;
+
+ // <PREFIXTREE>
+ res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, true,
+ lp->sl_prefixcnt);
+ if (res != 0)
+ goto someerror;
+
+ // For a new file link it in the list of spell files.
+ if (old_lp == NULL && lang != NULL) {
+ lp->sl_next = first_lang;
+ first_lang = lp;
+ }
+
+ goto endOK;
+
+endFAIL:
+ if (lang != NULL)
+ // truncating the name signals the error to spell_load_lang()
+ *lang = NUL;
+ if (lp != NULL && old_lp == NULL)
+ slang_free(lp);
+ lp = NULL;
+
+endOK:
+ if (fd != NULL)
+ fclose(fd);
+ sourcing_name = save_sourcing_name;
+ sourcing_lnum = save_sourcing_lnum;
+
+ return lp;
+}
+
+// Fill in the wordcount fields for a trie.
+// Returns the total number of words.
+static void tree_count_words(char_u *byts, idx_T *idxs)
+{
+ int depth;
+ idx_T arridx[MAXWLEN];
+ int curi[MAXWLEN];
+ int c;
+ idx_T n;
+ int wordcount[MAXWLEN];
+
+ arridx[0] = 0;
+ curi[0] = 1;
+ wordcount[0] = 0;
+ depth = 0;
+ while (depth >= 0 && !got_int) {
+ if (curi[depth] > byts[arridx[depth]]) {
+ // Done all bytes at this node, go up one level.
+ idxs[arridx[depth]] = wordcount[depth];
+ if (depth > 0)
+ wordcount[depth - 1] += wordcount[depth];
+
+ --depth;
+ fast_breakcheck();
+ } else {
+ // Do one more byte at this node.
+ n = arridx[depth] + curi[depth];
+ ++curi[depth];
+
+ c = byts[n];
+ if (c == 0) {
+ // End of word, count it.
+ ++wordcount[depth];
+
+ // Skip over any other NUL bytes (same word with different
+ // flags).
+ while (byts[n + 1] == 0) {
+ ++n;
+ ++curi[depth];
+ }
+ } else {
+ // Normal char, go one level deeper to count the words.
+ ++depth;
+ arridx[depth] = idxs[n];
+ curi[depth] = 1;
+ wordcount[depth] = 0;
+ }
+ }
+ }
+}
+
+// Load the .sug files for languages that have one and weren't loaded yet.
+void suggest_load_files(void)
+{
+ langp_T *lp;
+ slang_T *slang;
+ char_u *dotp;
+ FILE *fd;
+ char_u buf[MAXWLEN];
+ int i;
+ time_t timestamp;
+ int wcount;
+ int wordnr;
+ garray_T ga;
+ int c;
+
+ // Do this for all languages that support sound folding.
+ for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) {
+ lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+ slang = lp->lp_slang;
+ if (slang->sl_sugtime != 0 && !slang->sl_sugloaded) {
+ // Change ".spl" to ".sug" and open the file. When the file isn't
+ // found silently skip it. Do set "sl_sugloaded" so that we
+ // don't try again and again.
+ slang->sl_sugloaded = true;
+
+ dotp = STRRCHR(slang->sl_fname, '.');
+ if (dotp == NULL || fnamecmp(dotp, ".spl") != 0) {
+ continue;
+ }
+ STRCPY(dotp, ".sug");
+ fd = mch_fopen((char *)slang->sl_fname, "r");
+ if (fd == NULL)
+ goto nextone;
+
+ // <SUGHEADER>: <fileID> <versionnr> <timestamp>
+ for (i = 0; i < VIMSUGMAGICL; ++i)
+ buf[i] = getc(fd); // <fileID>
+ if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) {
+ EMSG2(_("E778: This does not look like a .sug file: %s"),
+ slang->sl_fname);
+ goto nextone;
+ }
+ c = getc(fd); // <versionnr>
+ if (c < VIMSUGVERSION) {
+ EMSG2(_("E779: Old .sug file, needs to be updated: %s"),
+ slang->sl_fname);
+ goto nextone;
+ } else if (c > VIMSUGVERSION) {
+ EMSG2(_("E780: .sug file is for newer version of Vim: %s"),
+ slang->sl_fname);
+ goto nextone;
+ }
+
+ // Check the timestamp, it must be exactly the same as the one in
+ // the .spl file. Otherwise the word numbers won't match.
+ timestamp = get8ctime(fd); // <timestamp>
+ if (timestamp != slang->sl_sugtime) {
+ EMSG2(_("E781: .sug file doesn't match .spl file: %s"),
+ slang->sl_fname);
+ goto nextone;
+ }
+
+ // <SUGWORDTREE>: <wordtree>
+ // Read the trie with the soundfolded words.
+ if (spell_read_tree(fd, &slang->sl_sbyts, &slang->sl_sidxs,
+ false, 0) != 0) {
+someerror:
+ EMSG2(_("E782: error while reading .sug file: %s"),
+ slang->sl_fname);
+ slang_clear_sug(slang);
+ goto nextone;
+ }
+
+ // <SUGTABLE>: <sugwcount> <sugline> ...
+ //
+ // Read the table with word numbers. We use a file buffer for
+ // this, because it's so much like a file with lines. Makes it
+ // possible to swap the info and save on memory use.
+ slang->sl_sugbuf = open_spellbuf();
+
+ // <sugwcount>
+ wcount = get4c(fd);
+ if (wcount < 0)
+ goto someerror;
+
+ // Read all the wordnr lists into the buffer, one NUL terminated
+ // list per line.
+ ga_init(&ga, 1, 100);
+ for (wordnr = 0; wordnr < wcount; ++wordnr) {
+ ga.ga_len = 0;
+ for (;; ) {
+ c = getc(fd); // <sugline>
+ if (c < 0) {
+ goto someerror;
+ }
+ GA_APPEND(char_u, &ga, c);
+ if (c == NUL)
+ break;
+ }
+ if (ml_append_buf(slang->sl_sugbuf, (linenr_T)wordnr,
+ ga.ga_data, ga.ga_len, TRUE) == FAIL)
+ goto someerror;
+ }
+ ga_clear(&ga);
+
+ // Need to put word counts in the word tries, so that we can find
+ // a word by its number.
+ tree_count_words(slang->sl_fbyts, slang->sl_fidxs);
+ tree_count_words(slang->sl_sbyts, slang->sl_sidxs);
+
+nextone:
+ if (fd != NULL)
+ fclose(fd);
+ STRCPY(dotp, ".spl");
+ }
+ }
+}
+
+
+// Read a length field from "fd" in "cnt_bytes" bytes.
+// Allocate memory, read the string into it and add a NUL at the end.
+// Returns NULL when the count is zero.
+// Sets "*cntp" to SP_*ERROR when there is an error, length of the result
+// otherwise.
+static char_u *read_cnt_string(FILE *fd, int cnt_bytes, int *cntp)
+{
+ int cnt = 0;
+ int i;
+ char_u *str;
+
+ // read the length bytes, MSB first
+ for (i = 0; i < cnt_bytes; ++i)
+ cnt = (cnt << 8) + getc(fd);
+ if (cnt < 0) {
+ *cntp = SP_TRUNCERROR;
+ return NULL;
+ }
+ *cntp = cnt;
+ if (cnt == 0)
+ return NULL; // nothing to read, return NULL
+
+ str = READ_STRING(fd, cnt);
+ if (str == NULL)
+ *cntp = SP_OTHERERROR;
+ return str;
+}
+
+// Read SN_REGION: <regionname> ...
+// Return SP_*ERROR flags.
+static int read_region_section(FILE *fd, slang_T *lp, int len)
+{
+ if (len > MAXREGIONS * 2) {
+ return SP_FORMERROR;
+ }
+ SPELL_READ_NONNUL_BYTES((char *)lp->sl_regions, (size_t)len, fd, ;);
+ lp->sl_regions[len] = NUL;
+ return 0;
+}
+
+// Read SN_CHARFLAGS section: <charflagslen> <charflags>
+// <folcharslen> <folchars>
+// Return SP_*ERROR flags.
+static int read_charflags_section(FILE *fd)
+{
+ char_u *flags;
+ char_u *fol;
+ int flagslen, follen;
+
+ // <charflagslen> <charflags>
+ flags = read_cnt_string(fd, 1, &flagslen);
+ if (flagslen < 0)
+ return flagslen;
+
+ // <folcharslen> <folchars>
+ fol = read_cnt_string(fd, 2, &follen);
+ if (follen < 0) {
+ xfree(flags);
+ return follen;
+ }
+
+ // Set the word-char flags and fill SPELL_ISUPPER() table.
+ if (flags != NULL && fol != NULL)
+ set_spell_charflags(flags, flagslen, fol);
+
+ xfree(flags);
+ xfree(fol);
+
+ // When <charflagslen> is zero then <fcharlen> must also be zero.
+ if ((flags == NULL) != (fol == NULL))
+ return SP_FORMERROR;
+ return 0;
+}
+
+// Read SN_PREFCOND section.
+// Return SP_*ERROR flags.
+static int read_prefcond_section(FILE *fd, slang_T *lp)
+{
+ // <prefcondcnt> <prefcond> ...
+ const int cnt = get2c(fd); // <prefcondcnt>
+ if (cnt <= 0) {
+ return SP_FORMERROR;
+ }
+
+ lp->sl_prefprog = xcalloc(cnt, sizeof(regprog_T *));
+ lp->sl_prefixcnt = cnt;
+
+ for (int i = 0; i < cnt; i++) {
+ // <prefcond> : <condlen> <condstr>
+ const int n = getc(fd); // <condlen>
+ if (n < 0 || n >= MAXWLEN) {
+ return SP_FORMERROR;
+ }
+
+ // When <condlen> is zero we have an empty condition. Otherwise
+ // compile the regexp program used to check for the condition.
+ if (n > 0) {
+ char buf[MAXWLEN + 1];
+ buf[0] = '^'; // always match at one position only
+ SPELL_READ_NONNUL_BYTES(buf + 1, (size_t)n, fd, ;);
+ buf[n + 1] = NUL;
+ lp->sl_prefprog[i] = vim_regcomp((char_u *)buf, RE_MAGIC | RE_STRING);
+ }
+ }
+ return 0;
+}
+
+// Read REP or REPSAL items section from "fd": <repcount> <rep> ...
+// Return SP_*ERROR flags.
+static int read_rep_section(FILE *fd, garray_T *gap, int16_t *first)
+{
+ int cnt;
+ fromto_T *ftp;
+
+ cnt = get2c(fd); // <repcount>
+ if (cnt < 0)
+ return SP_TRUNCERROR;
+
+ ga_grow(gap, cnt);
+
+ // <rep> : <repfromlen> <repfrom> <reptolen> <repto>
+ for (; gap->ga_len < cnt; ++gap->ga_len) {
+ int c;
+ ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
+ ftp->ft_from = read_cnt_string(fd, 1, &c);
+ if (c < 0)
+ return c;
+ if (c == 0)
+ return SP_FORMERROR;
+ ftp->ft_to = read_cnt_string(fd, 1, &c);
+ if (c <= 0) {
+ xfree(ftp->ft_from);
+ if (c < 0)
+ return c;
+ return SP_FORMERROR;
+ }
+ }
+
+ // Fill the first-index table.
+ for (int i = 0; i < 256; ++i) {
+ first[i] = -1;
+ }
+ for (int i = 0; i < gap->ga_len; ++i) {
+ ftp = &((fromto_T *)gap->ga_data)[i];
+ if (first[*ftp->ft_from] == -1)
+ first[*ftp->ft_from] = i;
+ }
+ return 0;
+}
+
+// Read SN_SAL section: <salflags> <salcount> <sal> ...
+// Return SP_*ERROR flags.
+static int read_sal_section(FILE *fd, slang_T *slang)
+{
+ int cnt;
+ garray_T *gap;
+ salitem_T *smp;
+ int ccnt;
+ char_u *p;
+ int c = NUL;
+
+ slang->sl_sofo = false;
+
+ const int flags = getc(fd); // <salflags>
+ if (flags & SAL_F0LLOWUP) {
+ slang->sl_followup = true;
+ }
+ if (flags & SAL_COLLAPSE) {
+ slang->sl_collapse = true;
+ }
+ if (flags & SAL_REM_ACCENTS) {
+ slang->sl_rem_accents = true;
+ }
+
+ cnt = get2c(fd); // <salcount>
+ if (cnt < 0)
+ return SP_TRUNCERROR;
+
+ gap = &slang->sl_sal;
+ ga_init(gap, sizeof(salitem_T), 10);
+ ga_grow(gap, cnt + 1);
+
+ // <sal> : <salfromlen> <salfrom> <saltolen> <salto>
+ for (; gap->ga_len < cnt; ++gap->ga_len) {
+ smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
+ ccnt = getc(fd); // <salfromlen>
+ if (ccnt < 0)
+ return SP_TRUNCERROR;
+ p = xmalloc(ccnt + 2);
+ smp->sm_lead = p;
+
+ // Read up to the first special char into sm_lead.
+ int i = 0;
+ for (; i < ccnt; ++i) {
+ c = getc(fd); // <salfrom>
+ if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
+ break;
+ *p++ = c;
+ }
+ smp->sm_leadlen = (int)(p - smp->sm_lead);
+ *p++ = NUL;
+
+ // Put (abc) chars in sm_oneof, if any.
+ if (c == '(') {
+ smp->sm_oneof = p;
+ for (++i; i < ccnt; ++i) {
+ c = getc(fd); // <salfrom>
+ if (c == ')')
+ break;
+ *p++ = c;
+ }
+ *p++ = NUL;
+ if (++i < ccnt)
+ c = getc(fd);
+ } else
+ smp->sm_oneof = NULL;
+
+ // Any following chars go in sm_rules.
+ smp->sm_rules = p;
+ if (i < ccnt) {
+ // store the char we got while checking for end of sm_lead
+ *p++ = c;
+ }
+ i++;
+ if (i < ccnt) {
+ SPELL_READ_NONNUL_BYTES( // <salfrom>
+ (char *)p, (size_t)(ccnt - i), fd, xfree(smp->sm_lead));
+ p += (ccnt - i);
+ }
+ *p++ = NUL;
+
+ // <saltolen> <salto>
+ smp->sm_to = read_cnt_string(fd, 1, &ccnt);
+ if (ccnt < 0) {
+ xfree(smp->sm_lead);
+ return ccnt;
+ }
+
+ if (has_mbyte) {
+ // convert the multi-byte strings to wide char strings
+ smp->sm_lead_w = mb_str2wide(smp->sm_lead);
+ smp->sm_leadlen = mb_charlen(smp->sm_lead);
+ if (smp->sm_oneof == NULL)
+ smp->sm_oneof_w = NULL;
+ else
+ smp->sm_oneof_w = mb_str2wide(smp->sm_oneof);
+ if (smp->sm_to == NULL)
+ smp->sm_to_w = NULL;
+ else
+ smp->sm_to_w = mb_str2wide(smp->sm_to);
+ }
+ }
+
+ if (!GA_EMPTY(gap)) {
+ // Add one extra entry to mark the end with an empty sm_lead. Avoids
+ // that we need to check the index every time.
+ smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
+ p = xmalloc(1);
+ p[0] = NUL;
+ smp->sm_lead = p;
+ smp->sm_leadlen = 0;
+ smp->sm_oneof = NULL;
+ smp->sm_rules = p;
+ smp->sm_to = NULL;
+ if (has_mbyte) {
+ smp->sm_lead_w = mb_str2wide(smp->sm_lead);
+ smp->sm_leadlen = 0;
+ smp->sm_oneof_w = NULL;
+ smp->sm_to_w = NULL;
+ }
+ ++gap->ga_len;
+ }
+
+ // Fill the first-index table.
+ set_sal_first(slang);
+
+ return 0;
+}
+
+// Read SN_WORDS: <word> ...
+// Return SP_*ERROR flags.
+static int read_words_section(FILE *fd, slang_T *lp, int len)
+{
+ int done = 0;
+ int i;
+ int c;
+ char_u word[MAXWLEN];
+
+ while (done < len) {
+ // Read one word at a time.
+ for (i = 0;; ++i) {
+ c = getc(fd);
+ if (c == EOF)
+ return SP_TRUNCERROR;
+ word[i] = c;
+ if (word[i] == NUL)
+ break;
+ if (i == MAXWLEN - 1)
+ return SP_FORMERROR;
+ }
+
+ // Init the count to 10.
+ count_common_word(lp, word, -1, 10);
+ done += i + 1;
+ }
+ return 0;
+}
+
+// SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+// Return SP_*ERROR flags.
+static int read_sofo_section(FILE *fd, slang_T *slang)
+{
+ int cnt;
+ char_u *from, *to;
+ int res;
+
+ slang->sl_sofo = true;
+
+ // <sofofromlen> <sofofrom>
+ from = read_cnt_string(fd, 2, &cnt);
+ if (cnt < 0)
+ return cnt;
+
+ // <sofotolen> <sofoto>
+ to = read_cnt_string(fd, 2, &cnt);
+ if (cnt < 0) {
+ xfree(from);
+ return cnt;
+ }
+
+ // Store the info in slang->sl_sal and/or slang->sl_sal_first.
+ if (from != NULL && to != NULL)
+ res = set_sofo(slang, from, to);
+ else if (from != NULL || to != NULL)
+ res = SP_FORMERROR; // only one of two strings is an error
+ else
+ res = 0;
+
+ xfree(from);
+ xfree(to);
+ return res;
+}
+
+// Read the compound section from the .spl file:
+// <compmax> <compminlen> <compsylmax> <compoptions> <compflags>
+// Returns SP_*ERROR flags.
+static int read_compound(FILE *fd, slang_T *slang, int len)
+{
+ int todo = len;
+ int c;
+ int atstart;
+ char_u *pat;
+ char_u *pp;
+ char_u *cp;
+ char_u *ap;
+ char_u *crp;
+ int cnt;
+ garray_T *gap;
+
+ if (todo < 2)
+ return SP_FORMERROR; // need at least two bytes
+
+ --todo;
+ c = getc(fd); // <compmax>
+ if (c < 2)
+ c = MAXWLEN;
+ slang->sl_compmax = c;
+
+ --todo;
+ c = getc(fd); // <compminlen>
+ if (c < 1)
+ c = 0;
+ slang->sl_compminlen = c;
+
+ --todo;
+ c = getc(fd); // <compsylmax>
+ if (c < 1)
+ c = MAXWLEN;
+ slang->sl_compsylmax = c;
+
+ c = getc(fd); // <compoptions>
+ if (c != 0)
+ ungetc(c, fd); // be backwards compatible with Vim 7.0b
+ else {
+ --todo;
+ c = getc(fd); // only use the lower byte for now
+ --todo;
+ slang->sl_compoptions = c;
+
+ gap = &slang->sl_comppat;
+ c = get2c(fd); // <comppatcount>
+ todo -= 2;
+ ga_init(gap, sizeof(char_u *), c);
+ ga_grow(gap, c);
+ while (--c >= 0) {
+ ((char_u **)(gap->ga_data))[gap->ga_len++] =
+ read_cnt_string(fd, 1, &cnt);
+ // <comppatlen> <comppattext>
+ if (cnt < 0)
+ return cnt;
+ todo -= cnt + 1;
+ }
+ }
+ if (todo < 0)
+ return SP_FORMERROR;
+
+ // Turn the COMPOUNDRULE items into a regexp pattern:
+ // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$".
+ // Inserting backslashes may double the length, "^\(\)$<Nul>" is 7 bytes.
+ // Conversion to utf-8 may double the size.
+ c = todo * 2 + 7;
+ if (enc_utf8)
+ c += todo * 2;
+ pat = xmalloc(c);
+
+ // We also need a list of all flags that can appear at the start and one
+ // for all flags.
+ cp = xmalloc(todo + 1);
+ slang->sl_compstartflags = cp;
+ *cp = NUL;
+
+ ap = xmalloc(todo + 1);
+ slang->sl_compallflags = ap;
+ *ap = NUL;
+
+ // And a list of all patterns in their original form, for checking whether
+ // compounding may work in match_compoundrule(). This is freed when we
+ // encounter a wildcard, the check doesn't work then.
+ crp = xmalloc(todo + 1);
+ slang->sl_comprules = crp;
+
+ pp = pat;
+ *pp++ = '^';
+ *pp++ = '\\';
+ *pp++ = '(';
+
+ atstart = 1;
+ while (todo-- > 0) {
+ c = getc(fd); // <compflags>
+ if (c == EOF) {
+ xfree(pat);
+ return SP_TRUNCERROR;
+ }
+
+ // Add all flags to "sl_compallflags".
+ if (vim_strchr((char_u *)"?*+[]/", c) == NULL
+ && !byte_in_str(slang->sl_compallflags, c)) {
+ *ap++ = c;
+ *ap = NUL;
+ }
+
+ if (atstart != 0) {
+ // At start of item: copy flags to "sl_compstartflags". For a
+ // [abc] item set "atstart" to 2 and copy up to the ']'.
+ if (c == '[')
+ atstart = 2;
+ else if (c == ']')
+ atstart = 0;
+ else {
+ if (!byte_in_str(slang->sl_compstartflags, c)) {
+ *cp++ = c;
+ *cp = NUL;
+ }
+ if (atstart == 1)
+ atstart = 0;
+ }
+ }
+
+ // Copy flag to "sl_comprules", unless we run into a wildcard.
+ if (crp != NULL) {
+ if (c == '?' || c == '+' || c == '*') {
+ xfree(slang->sl_comprules);
+ slang->sl_comprules = NULL;
+ crp = NULL;
+ } else
+ *crp++ = c;
+ }
+
+ if (c == '/') { // slash separates two items
+ *pp++ = '\\';
+ *pp++ = '|';
+ atstart = 1;
+ } else { // normal char, "[abc]" and '*' are copied as-is
+ if (c == '?' || c == '+' || c == '~') {
+ *pp++ = '\\'; // "a?" becomes "a\?", "a+" becomes "a\+"
+ }
+ pp += utf_char2bytes(c, pp);
+ }
+ }
+
+ *pp++ = '\\';
+ *pp++ = ')';
+ *pp++ = '$';
+ *pp = NUL;
+
+ if (crp != NULL)
+ *crp = NUL;
+
+ slang->sl_compprog = vim_regcomp(pat, RE_MAGIC + RE_STRING + RE_STRICT);
+ xfree(pat);
+ if (slang->sl_compprog == NULL)
+ return SP_FORMERROR;
+
+ return 0;
+}
+
+// Set the SOFOFROM and SOFOTO items in language "lp".
+// Returns SP_*ERROR flags when there is something wrong.
+static int set_sofo(slang_T *lp, char_u *from, char_u *to)
+{
+ int i;
+
+ garray_T *gap;
+ char_u *s;
+ char_u *p;
+ int c;
+ int *inp;
+
+ if (has_mbyte) {
+ // Use "sl_sal" as an array with 256 pointers to a list of wide
+ // characters. The index is the low byte of the character.
+ // The list contains from-to pairs with a terminating NUL.
+ // sl_sal_first[] is used for latin1 "from" characters.
+ gap = &lp->sl_sal;
+ ga_init(gap, sizeof(int *), 1);
+ ga_grow(gap, 256);
+ memset(gap->ga_data, 0, sizeof(int *) * 256);
+ gap->ga_len = 256;
+
+ // First count the number of items for each list. Temporarily use
+ // sl_sal_first[] for this.
+ for (p = from, s = to; *p != NUL && *s != NUL; ) {
+ c = mb_cptr2char_adv((const char_u **)&p);
+ MB_CPTR_ADV(s);
+ if (c >= 256) {
+ lp->sl_sal_first[c & 0xff]++;
+ }
+ }
+ if (*p != NUL || *s != NUL) // lengths differ
+ return SP_FORMERROR;
+
+ // Allocate the lists.
+ for (i = 0; i < 256; ++i)
+ if (lp->sl_sal_first[i] > 0) {
+ p = xmalloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1));
+ ((int **)gap->ga_data)[i] = (int *)p;
+ *(int *)p = 0;
+ }
+
+ // Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal
+ // list.
+ memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
+ for (p = from, s = to; *p != NUL && *s != NUL; ) {
+ c = mb_cptr2char_adv((const char_u **)&p);
+ i = mb_cptr2char_adv((const char_u **)&s);
+ if (c >= 256) {
+ // Append the from-to chars at the end of the list with
+ // the low byte.
+ inp = ((int **)gap->ga_data)[c & 0xff];
+ while (*inp != 0)
+ ++inp;
+ *inp++ = c; // from char
+ *inp++ = i; // to char
+ *inp++ = NUL; // NUL at the end
+ } else
+ // mapping byte to char is done in sl_sal_first[]
+ lp->sl_sal_first[c] = i;
+ }
+ } else {
+ // mapping bytes to bytes is done in sl_sal_first[]
+ if (STRLEN(from) != STRLEN(to))
+ return SP_FORMERROR;
+
+ for (i = 0; to[i] != NUL; ++i)
+ lp->sl_sal_first[from[i]] = to[i];
+ lp->sl_sal.ga_len = 1; // indicates we have soundfolding
+ }
+
+ return 0;
+}
+
+// Fill the first-index table for "lp".
+static void set_sal_first(slang_T *lp)
+{
+ salfirst_T *sfirst;
+ salitem_T *smp;
+ int c;
+ garray_T *gap = &lp->sl_sal;
+
+ sfirst = lp->sl_sal_first;
+ for (int i = 0; i < 256; ++i) {
+ sfirst[i] = -1;
+ }
+ smp = (salitem_T *)gap->ga_data;
+ for (int i = 0; i < gap->ga_len; ++i) {
+ if (has_mbyte)
+ // Use the lowest byte of the first character. For latin1 it's
+ // the character, for other encodings it should differ for most
+ // characters.
+ c = *smp[i].sm_lead_w & 0xff;
+ else
+ c = *smp[i].sm_lead;
+ if (sfirst[c] == -1) {
+ sfirst[c] = i;
+ if (has_mbyte) {
+ int n;
+
+ // Make sure all entries with this byte are following each
+ // other. Move the ones that are in the wrong position. Do
+ // keep the same ordering!
+ while (i + 1 < gap->ga_len
+ && (*smp[i + 1].sm_lead_w & 0xff) == c)
+ // Skip over entry with same index byte.
+ ++i;
+
+ for (n = 1; i + n < gap->ga_len; ++n)
+ if ((*smp[i + n].sm_lead_w & 0xff) == c) {
+ salitem_T tsal;
+
+ // Move entry with same index byte after the entries
+ // we already found.
+ ++i;
+ --n;
+ tsal = smp[i + n];
+ memmove(smp + i + 1, smp + i,
+ sizeof(salitem_T) * n);
+ smp[i] = tsal;
+ }
+ }
+ }
+ }
+}
+
+// Turn a multi-byte string into a wide character string.
+// Return it in allocated memory.
+static int *mb_str2wide(char_u *s)
+{
+ int i = 0;
+
+ int *res = xmalloc((mb_charlen(s) + 1) * sizeof(int));
+ for (char_u *p = s; *p != NUL; ) {
+ res[i++] = mb_ptr2char_adv((const char_u **)&p);
+ }
+ res[i] = NUL;
+
+ return res;
+}
+
+// Reads a tree from the .spl or .sug file.
+// Allocates the memory and stores pointers in "bytsp" and "idxsp".
+// This is skipped when the tree has zero length.
+// Returns zero when OK, SP_ value for an error.
+static int
+spell_read_tree (
+ FILE *fd,
+ char_u **bytsp,
+ idx_T **idxsp,
+ bool prefixtree, // true for the prefix tree
+ int prefixcnt // when "prefixtree" is true: prefix count
+)
+{
+ int idx;
+ char_u *bp;
+ idx_T *ip;
+
+ // The tree size was computed when writing the file, so that we can
+ // allocate it as one long block. <nodecount>
+ long len = get4c(fd);
+ if (len < 0) {
+ return SP_TRUNCERROR;
+ }
+ if ((size_t)len >= SIZE_MAX / sizeof(int)) { // -V547
+ // Invalid length, multiply with sizeof(int) would overflow.
+ return SP_FORMERROR;
+ }
+ if (len > 0) {
+ // Allocate the byte array.
+ bp = xmalloc(len);
+ *bytsp = bp;
+
+ // Allocate the index array.
+ ip = xcalloc(len, sizeof(*ip));
+ *idxsp = ip;
+
+ // Recursively read the tree and store it in the array.
+ idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt);
+ if (idx < 0)
+ return idx;
+ }
+ return 0;
+}
+
+// Read one row of siblings from the spell file and store it in the byte array
+// "byts" and index array "idxs". Recursively read the children.
+//
+// NOTE: The code here must match put_node()!
+//
+// Returns the index (>= 0) following the siblings.
+// Returns SP_TRUNCERROR if the file is shorter than expected.
+// Returns SP_FORMERROR if there is a format error.
+static idx_T
+read_tree_node (
+ FILE *fd,
+ char_u *byts,
+ idx_T *idxs,
+ int maxidx, // size of arrays
+ idx_T startidx, // current index in "byts" and "idxs"
+ bool prefixtree, // true for reading PREFIXTREE
+ int maxprefcondnr // maximum for <prefcondnr>
+)
+{
+ int len;
+ int i;
+ int n;
+ idx_T idx = startidx;
+ int c;
+ int c2;
+#define SHARED_MASK 0x8000000
+
+ len = getc(fd); // <siblingcount>
+ if (len <= 0)
+ return SP_TRUNCERROR;
+
+ if (startidx + len >= maxidx)
+ return SP_FORMERROR;
+ byts[idx++] = len;
+
+ // Read the byte values, flag/region bytes and shared indexes.
+ for (i = 1; i <= len; ++i) {
+ c = getc(fd); // <byte>
+ if (c < 0)
+ return SP_TRUNCERROR;
+ if (c <= BY_SPECIAL) {
+ if (c == BY_NOFLAGS && !prefixtree) {
+ // No flags, all regions.
+ idxs[idx] = 0;
+ c = 0;
+ } else if (c != BY_INDEX) {
+ if (prefixtree) {
+ // Read the optional pflags byte, the prefix ID and the
+ // condition nr. In idxs[] store the prefix ID in the low
+ // byte, the condition index shifted up 8 bits, the flags
+ // shifted up 24 bits.
+ if (c == BY_FLAGS)
+ c = getc(fd) << 24; // <pflags>
+ else
+ c = 0;
+
+ c |= getc(fd); // <affixID>
+
+ n = get2c(fd); // <prefcondnr>
+ if (n >= maxprefcondnr)
+ return SP_FORMERROR;
+ c |= (n << 8);
+ } else { // c must be BY_FLAGS or BY_FLAGS2
+ // Read flags and optional region and prefix ID. In
+ // idxs[] the flags go in the low two bytes, region above
+ // that and prefix ID above the region.
+ c2 = c;
+ c = getc(fd); // <flags>
+ if (c2 == BY_FLAGS2)
+ c = (getc(fd) << 8) + c; // <flags2>
+ if (c & WF_REGION)
+ c = (getc(fd) << 16) + c; // <region>
+ if (c & WF_AFX)
+ c = (getc(fd) << 24) + c; // <affixID>
+ }
+
+ idxs[idx] = c;
+ c = 0;
+ } else { // c == BY_INDEX
+ // <nodeidx>
+ n = get3c(fd);
+ if (n < 0 || n >= maxidx)
+ return SP_FORMERROR;
+ idxs[idx] = n + SHARED_MASK;
+ c = getc(fd); // <xbyte>
+ }
+ }
+ byts[idx++] = c;
+ }
+
+ // Recursively read the children for non-shared siblings.
+ // Skip the end-of-word ones (zero byte value) and the shared ones (and
+ // remove SHARED_MASK)
+ for (i = 1; i <= len; ++i)
+ if (byts[startidx + i] != 0) {
+ if (idxs[startidx + i] & SHARED_MASK)
+ idxs[startidx + i] &= ~SHARED_MASK;
+ else {
+ idxs[startidx + i] = idx;
+ idx = read_tree_node(fd, byts, idxs, maxidx, idx,
+ prefixtree, maxprefcondnr);
+ if (idx < 0)
+ break;
+ }
+ }
+
+ return idx;
+}
+
+// Reload the spell file "fname" if it's loaded.
+static void
+spell_reload_one (
+ char_u *fname,
+ bool added_word // invoked through "zg"
+)
+{
+ slang_T *slang;
+ bool didit = false;
+
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (path_full_compare(fname, slang->sl_fname, false) == kEqualFiles) {
+ slang_clear(slang);
+ if (spell_load_file(fname, NULL, slang, false) == NULL)
+ // reloading failed, clear the language
+ slang_clear(slang);
+ redraw_all_later(SOME_VALID);
+ didit = true;
+ }
+ }
+
+ // When "zg" was used and the file wasn't loaded yet, should redo
+ // 'spelllang' to load it now.
+ if (added_word && !didit)
+ did_set_spelllang(curwin);
+}
+
+// Functions for ":mkspell".
+
+// In the postponed prefixes tree wn_flags is used to store the WFP_ flags,
+// but it must be negative to indicate the prefix tree to tree_add_word().
+// Use a negative number with the lower 8 bits zero.
+#define PFX_FLAGS -256
+
+// flags for "condit" argument of store_aff_word()
+#define CONDIT_COMB 1 // affix must combine
+#define CONDIT_CFIX 2 // affix must have CIRCUMFIX flag
+#define CONDIT_SUF 4 // add a suffix for matching flags
+#define CONDIT_AFF 8 // word already has an affix
+
+// Tunable parameters for when the tree is compressed. See 'mkspellmem'.
+static long compress_start = 30000; // memory / SBLOCKSIZE
+static long compress_inc = 100; // memory / SBLOCKSIZE
+static long compress_added = 500000; // word count
+
+// Check the 'mkspellmem' option. Return FAIL if it's wrong.
+// Sets "sps_flags".
+int spell_check_msm(void)
+{
+ char_u *p = p_msm;
+ long start = 0;
+ long incr = 0;
+ long added = 0;
+
+ if (!ascii_isdigit(*p))
+ return FAIL;
+ // block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)
+ start = (getdigits_long(&p) * 10) / (SBLOCKSIZE / 102);
+ if (*p != ',')
+ return FAIL;
+ ++p;
+ if (!ascii_isdigit(*p))
+ return FAIL;
+ incr = (getdigits_long(&p) * 102) / (SBLOCKSIZE / 10);
+ if (*p != ',')
+ return FAIL;
+ ++p;
+ if (!ascii_isdigit(*p))
+ return FAIL;
+ added = getdigits_long(&p) * 1024;
+ if (*p != NUL)
+ return FAIL;
+
+ if (start == 0 || incr == 0 || added == 0 || incr > start)
+ return FAIL;
+
+ compress_start = start;
+ compress_inc = incr;
+ compress_added = added;
+ return OK;
+}
+
+#ifdef SPELL_PRINTTREE
+// For debugging the tree code: print the current tree in a (more or less)
+// readable format, so that we can see what happens when adding a word and/or
+// compressing the tree.
+// Based on code from Olaf Seibert.
+#define PRINTLINESIZE 1000
+#define PRINTWIDTH 6
+
+#define PRINTSOME(l, depth, fmt, a1, a2) vim_snprintf(l + depth * PRINTWIDTH, \
+ PRINTLINESIZE - PRINTWIDTH * depth, fmt, a1, a2)
+
+static char line1[PRINTLINESIZE];
+static char line2[PRINTLINESIZE];
+static char line3[PRINTLINESIZE];
+
+static void spell_clear_flags(wordnode_T *node)
+{
+ wordnode_T *np;
+
+ for (np = node; np != NULL; np = np->wn_sibling) {
+ np->wn_u1.index = FALSE;
+ spell_clear_flags(np->wn_child);
+ }
+}
+
+static void spell_print_node(wordnode_T *node, int depth)
+{
+ if (node->wn_u1.index) {
+ // Done this node before, print the reference.
+ PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0);
+ PRINTSOME(line2, depth, " ", 0, 0);
+ PRINTSOME(line3, depth, " ", 0, 0);
+ msg((char_u *)line1);
+ msg((char_u *)line2);
+ msg((char_u *)line3);
+ } else {
+ node->wn_u1.index = TRUE;
+
+ if (node->wn_byte != NUL) {
+ if (node->wn_child != NULL)
+ PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0);
+ else
+ // Cannot happen?
+ PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0);
+ } else
+ PRINTSOME(line1, depth, " $ ", 0, 0);
+
+ PRINTSOME(line2, depth, "%d/%d ", node->wn_nr, node->wn_refs);
+
+ if (node->wn_sibling != NULL)
+ PRINTSOME(line3, depth, " | ", 0, 0);
+ else
+ PRINTSOME(line3, depth, " ", 0, 0);
+
+ if (node->wn_byte == NUL) {
+ msg((char_u *)line1);
+ msg((char_u *)line2);
+ msg((char_u *)line3);
+ }
+
+ // do the children
+ if (node->wn_byte != NUL && node->wn_child != NULL)
+ spell_print_node(node->wn_child, depth + 1);
+
+ // do the siblings
+ if (node->wn_sibling != NULL) {
+ // get rid of all parent details except |
+ STRCPY(line1, line3);
+ STRCPY(line2, line3);
+ spell_print_node(node->wn_sibling, depth);
+ }
+ }
+}
+
+static void spell_print_tree(wordnode_T *root)
+{
+ if (root != NULL) {
+ // Clear the "wn_u1.index" fields, used to remember what has been
+ // done.
+ spell_clear_flags(root);
+
+ // Recursively print the tree.
+ spell_print_node(root, 0);
+ }
+}
+
+#endif // SPELL_PRINTTREE
+
+// Reads the affix file "fname".
+// Returns an afffile_T, NULL for complete failure.
+static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
+{
+ FILE *fd;
+ char_u rline[MAXLINELEN];
+ char_u *line;
+ char_u *pc = NULL;
+#define MAXITEMCNT 30
+ char_u *(items[MAXITEMCNT]);
+ int itemcnt;
+ char_u *p;
+ int lnum = 0;
+ affheader_T *cur_aff = NULL;
+ bool did_postpone_prefix = false;
+ int aff_todo = 0;
+ hashtab_T *tp;
+ char_u *low = NULL;
+ char_u *fol = NULL;
+ char_u *upp = NULL;
+ int do_rep;
+ int do_repsal;
+ int do_sal;
+ int do_mapline;
+ bool found_map = false;
+ hashitem_T *hi;
+ int l;
+ int compminlen = 0; // COMPOUNDMIN value
+ int compsylmax = 0; // COMPOUNDSYLMAX value
+ int compoptions = 0; // COMP_ flags
+ int compmax = 0; // COMPOUNDWORDMAX value
+ char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE
+ // concatenated
+ char_u *midword = NULL; // MIDWORD value
+ char_u *syllable = NULL; // SYLLABLE value
+ char_u *sofofrom = NULL; // SOFOFROM value
+ char_u *sofoto = NULL; // SOFOTO value
+
+ // Open the file.
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return NULL;
+ }
+
+ vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s..."), fname);
+ spell_message(spin, IObuff);
+
+ // Only do REP lines when not done in another .aff file already.
+ do_rep = GA_EMPTY(&spin->si_rep);
+
+ // Only do REPSAL lines when not done in another .aff file already.
+ do_repsal = GA_EMPTY(&spin->si_repsal);
+
+ // Only do SAL lines when not done in another .aff file already.
+ do_sal = GA_EMPTY(&spin->si_sal);
+
+ // Only do MAP lines when not done in another .aff file already.
+ do_mapline = GA_EMPTY(&spin->si_map);
+
+ // Allocate and init the afffile_T structure.
+ afffile_T *aff = getroom(spin, sizeof(*aff), true);
+ hash_init(&aff->af_pref);
+ hash_init(&aff->af_suff);
+ hash_init(&aff->af_comp);
+
+ // Read all the lines in the file one by one.
+ while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
+ line_breakcheck();
+ ++lnum;
+
+ // Skip comment lines.
+ if (*rline == '#')
+ continue;
+
+ // Convert from "SET" to 'encoding' when needed.
+ xfree(pc);
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ pc = string_convert(&spin->si_conv, rline, NULL);
+ if (pc == NULL) {
+ smsg(_("Conversion failure for word in %s line %d: %s"),
+ fname, lnum, rline);
+ continue;
+ }
+ line = pc;
+ } else {
+ pc = NULL;
+ line = rline;
+ }
+
+ // Split the line up in white separated items. Put a NUL after each
+ // item.
+ itemcnt = 0;
+ for (p = line;; ) {
+ while (*p != NUL && *p <= ' ') // skip white space and CR/NL
+ ++p;
+ if (*p == NUL)
+ break;
+ if (itemcnt == MAXITEMCNT) // too many items
+ break;
+ items[itemcnt++] = p;
+ // A few items have arbitrary text argument, don't split them.
+ if (itemcnt == 2 && spell_info_item(items[0]))
+ while (*p >= ' ' || *p == TAB) // skip until CR/NL
+ ++p;
+ else
+ while (*p > ' ') // skip until white space or CR/NL
+ ++p;
+ if (*p == NUL)
+ break;
+ *p++ = NUL;
+ }
+
+ // Handle non-empty lines.
+ if (itemcnt > 0) {
+ if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) {
+ // Setup for conversion from "ENC" to 'encoding'.
+ aff->af_enc = enc_canonize(items[1]);
+ if (!spin->si_ascii
+ && convert_setup(&spin->si_conv, aff->af_enc,
+ p_enc) == FAIL)
+ smsg(_("Conversion in %s not supported: from %s to %s"),
+ fname, aff->af_enc, p_enc);
+ spin->si_conv.vc_fail = true;
+ } else if (is_aff_rule(items, itemcnt, "FLAG", 2)
+ && aff->af_flagtype == AFT_CHAR) {
+ if (STRCMP(items[1], "long") == 0)
+ aff->af_flagtype = AFT_LONG;
+ else if (STRCMP(items[1], "num") == 0)
+ aff->af_flagtype = AFT_NUM;
+ else if (STRCMP(items[1], "caplong") == 0)
+ aff->af_flagtype = AFT_CAPLONG;
+ else
+ smsg(_("Invalid value for FLAG in %s line %d: %s"),
+ fname, lnum, items[1]);
+ if (aff->af_rare != 0
+ || aff->af_keepcase != 0
+ || aff->af_bad != 0
+ || aff->af_needaffix != 0
+ || aff->af_circumfix != 0
+ || aff->af_needcomp != 0
+ || aff->af_comproot != 0
+ || aff->af_nosuggest != 0
+ || compflags != NULL
+ || aff->af_suff.ht_used > 0
+ || aff->af_pref.ht_used > 0)
+ smsg(_("FLAG after using flags in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (spell_info_item(items[0]) && itemcnt > 1) {
+ p = getroom(spin,
+ (spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
+ + STRLEN(items[0])
+ + STRLEN(items[1]) + 3, false);
+ if (spin->si_info != NULL) {
+ STRCPY(p, spin->si_info);
+ STRCAT(p, "\n");
+ }
+ STRCAT(p, items[0]);
+ STRCAT(p, " ");
+ STRCAT(p, items[1]);
+ spin->si_info = p;
+ } else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
+ && midword == NULL) {
+ midword = getroom_save(spin, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "TRY", 2)) {
+ // ignored, we look in the tree for what chars may appear
+ }
+ // TODO: remove "RAR" later
+ else if ((is_aff_rule(items, itemcnt, "RAR", 2)
+ || is_aff_rule(items, itemcnt, "RARE", 2))
+ && aff->af_rare == 0) {
+ aff->af_rare = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ }
+ // TODO: remove "KEP" later
+ else if ((is_aff_rule(items, itemcnt, "KEP", 2)
+ || is_aff_rule(items, itemcnt, "KEEPCASE", 2))
+ && aff->af_keepcase == 0) {
+ aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if ((is_aff_rule(items, itemcnt, "BAD", 2)
+ || is_aff_rule(items, itemcnt, "FORBIDDENWORD", 2))
+ && aff->af_bad == 0) {
+ aff->af_bad = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "NEEDAFFIX", 2)
+ && aff->af_needaffix == 0) {
+ aff->af_needaffix = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "CIRCUMFIX", 2)
+ && aff->af_circumfix == 0) {
+ aff->af_circumfix = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "NOSUGGEST", 2)
+ && aff->af_nosuggest == 0) {
+ aff->af_nosuggest = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if ((is_aff_rule(items, itemcnt, "NEEDCOMPOUND", 2)
+ || is_aff_rule(items, itemcnt, "ONLYINCOMPOUND", 2))
+ && aff->af_needcomp == 0) {
+ aff->af_needcomp = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDROOT", 2)
+ && aff->af_comproot == 0) {
+ aff->af_comproot = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDFORBIDFLAG", 2)
+ && aff->af_compforbid == 0) {
+ aff->af_compforbid = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ if (aff->af_pref.ht_used > 0)
+ smsg(_("Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in %s line %d"),
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDPERMITFLAG", 2)
+ && aff->af_comppermit == 0) {
+ aff->af_comppermit = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ if (aff->af_pref.ht_used > 0)
+ smsg(_("Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in %s line %d"),
+ fname, lnum);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2)
+ && compflags == NULL) {
+ // Turn flag "c" into COMPOUNDRULE compatible string "c+",
+ // "Na" into "Na+", "1234" into "1234+".
+ p = getroom(spin, STRLEN(items[1]) + 2, false);
+ STRCPY(p, items[1]);
+ STRCAT(p, "+");
+ compflags = p;
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) {
+ // We don't use the count, but do check that it's a number and
+ // not COMPOUNDRULE mistyped.
+ if (atoi((char *)items[1]) == 0)
+ smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) {
+ // Don't use the first rule if it is a number.
+ if (compflags != NULL || *skipdigits(items[1]) != NUL) {
+ // Concatenate this string to previously defined ones,
+ // using a slash to separate them.
+ l = (int)STRLEN(items[1]) + 1;
+ if (compflags != NULL)
+ l += (int)STRLEN(compflags) + 1;
+ p = getroom(spin, l, false);
+ if (compflags != NULL) {
+ STRCPY(p, compflags);
+ STRCAT(p, "/");
+ }
+ STRCAT(p, items[1]);
+ compflags = p;
+ }
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDWORDMAX", 2)
+ && compmax == 0) {
+ compmax = atoi((char *)items[1]);
+ if (compmax == 0)
+ smsg(_("Wrong COMPOUNDWORDMAX value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDMIN", 2)
+ && compminlen == 0) {
+ compminlen = atoi((char *)items[1]);
+ if (compminlen == 0)
+ smsg(_("Wrong COMPOUNDMIN value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "COMPOUNDSYLMAX", 2)
+ && compsylmax == 0) {
+ compsylmax = atoi((char *)items[1]);
+ if (compsylmax == 0)
+ smsg(_("Wrong COMPOUNDSYLMAX value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDDUP", 1)) {
+ compoptions |= COMP_CHECKDUP;
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDREP", 1)) {
+ compoptions |= COMP_CHECKREP;
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDCASE", 1)) {
+ compoptions |= COMP_CHECKCASE;
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDTRIPLE", 1)) {
+ compoptions |= COMP_CHECKTRIPLE;
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 2)) {
+ if (atoi((char *)items[1]) == 0)
+ smsg(_("Wrong CHECKCOMPOUNDPATTERN value in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) {
+ garray_T *gap = &spin->si_comppat;
+ int i;
+
+ // Only add the couple if it isn't already there.
+ for (i = 0; i < gap->ga_len - 1; i += 2)
+ if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0
+ && STRCMP(((char_u **)(gap->ga_data))[i + 1],
+ items[2]) == 0)
+ break;
+ if (i >= gap->ga_len) {
+ ga_grow(gap, 2);
+ ((char_u **)(gap->ga_data))[gap->ga_len++]
+ = getroom_save(spin, items[1]);
+ ((char_u **)(gap->ga_data))[gap->ga_len++]
+ = getroom_save(spin, items[2]);
+ }
+ } else if (is_aff_rule(items, itemcnt, "SYLLABLE", 2)
+ && syllable == NULL) {
+ syllable = getroom_save(spin, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "NOBREAK", 1)) {
+ spin->si_nobreak = true;
+ } else if (is_aff_rule(items, itemcnt, "NOSPLITSUGS", 1)) {
+ spin->si_nosplitsugs = true;
+ } else if (is_aff_rule(items, itemcnt, "NOCOMPOUNDSUGS", 1)) {
+ spin->si_nocompoundsugs = true;
+ } else if (is_aff_rule(items, itemcnt, "NOSUGFILE", 1)) {
+ spin->si_nosugfile = true;
+ } else if (is_aff_rule(items, itemcnt, "PFXPOSTPONE", 1)) {
+ aff->af_pfxpostpone = true;
+ } else if (is_aff_rule(items, itemcnt, "IGNOREEXTRA", 1)) {
+ aff->af_ignoreextra = true;
+ } else if ((STRCMP(items[0], "PFX") == 0
+ || STRCMP(items[0], "SFX") == 0)
+ && aff_todo == 0
+ && itemcnt >= 4) {
+ int lasti = 4;
+ char_u key[AH_KEY_LEN];
+
+ if (*items[0] == 'P')
+ tp = &aff->af_pref;
+ else
+ tp = &aff->af_suff;
+
+ // Myspell allows the same affix name to be used multiple
+ // times. The affix files that do this have an undocumented
+ // "S" flag on all but the last block, thus we check for that
+ // and store it in ah_follows.
+ STRLCPY(key, items[1], AH_KEY_LEN);
+ hi = hash_find(tp, key);
+ if (!HASHITEM_EMPTY(hi)) {
+ cur_aff = HI2AH(hi);
+ if (cur_aff->ah_combine != (*items[2] == 'Y'))
+ smsg(_("Different combining flag in continued affix block in %s line %d: %s"),
+ fname, lnum, items[1]);
+ if (!cur_aff->ah_follows)
+ smsg(_("Duplicate affix in %s line %d: %s"),
+ fname, lnum, items[1]);
+ } else {
+ // New affix letter.
+ cur_aff = getroom(spin, sizeof(*cur_aff), true);
+ cur_aff->ah_flag = affitem2flag(aff->af_flagtype, items[1],
+ fname, lnum);
+ if (cur_aff->ah_flag == 0 || STRLEN(items[1]) >= AH_KEY_LEN) {
+ break;
+ }
+ if (cur_aff->ah_flag == aff->af_bad
+ || cur_aff->ah_flag == aff->af_rare
+ || cur_aff->ah_flag == aff->af_keepcase
+ || cur_aff->ah_flag == aff->af_needaffix
+ || cur_aff->ah_flag == aff->af_circumfix
+ || cur_aff->ah_flag == aff->af_nosuggest
+ || cur_aff->ah_flag == aff->af_needcomp
+ || cur_aff->ah_flag == aff->af_comproot) {
+ smsg(_("Affix also used for "
+ "BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST"
+ "in %s line %d: %s"),
+ fname, lnum, items[1]);
+ }
+ STRCPY(cur_aff->ah_key, items[1]);
+ hash_add(tp, cur_aff->ah_key);
+
+ cur_aff->ah_combine = (*items[2] == 'Y');
+ }
+
+ // Check for the "S" flag, which apparently means that another
+ // block with the same affix name is following.
+ if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) {
+ ++lasti;
+ cur_aff->ah_follows = true;
+ } else
+ cur_aff->ah_follows = false;
+
+ // Myspell allows extra text after the item, but that might
+ // mean mistakes go unnoticed. Require a comment-starter,
+ // unless IGNOREEXTRA is used. Hunspell uses a "-" item.
+ if (itemcnt > lasti
+ && !aff->af_ignoreextra
+ && *items[lasti] != '#')
+ smsg(_(e_afftrailing), fname, lnum, items[lasti]);
+
+ if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0)
+ smsg(_("Expected Y or N in %s line %d: %s"),
+ fname, lnum, items[2]);
+
+ if (*items[0] == 'P' && aff->af_pfxpostpone) {
+ if (cur_aff->ah_newID == 0) {
+ // Use a new number in the .spl file later, to be able
+ // to handle multiple .aff files.
+ check_renumber(spin);
+ cur_aff->ah_newID = ++spin->si_newprefID;
+
+ // We only really use ah_newID if the prefix is
+ // postponed. We know that only after handling all
+ // the items.
+ did_postpone_prefix = false;
+ } else
+ // Did use the ID in a previous block.
+ did_postpone_prefix = true;
+ }
+
+ aff_todo = atoi((char *)items[3]);
+ } else if ((STRCMP(items[0], "PFX") == 0
+ || STRCMP(items[0], "SFX") == 0)
+ && aff_todo > 0
+ && STRCMP(cur_aff->ah_key, items[1]) == 0
+ && itemcnt >= 5) {
+ affentry_T *aff_entry;
+ bool upper = false;
+ int lasti = 5;
+
+ // Myspell allows extra text after the item, but that might
+ // mean mistakes go unnoticed. Require a comment-starter.
+ // Hunspell uses a "-" item.
+ if (itemcnt > lasti && *items[lasti] != '#'
+ && (STRCMP(items[lasti], "-") != 0
+ || itemcnt != lasti + 1))
+ smsg(_(e_afftrailing), fname, lnum, items[lasti]);
+
+ // New item for an affix letter.
+ aff_todo--;
+ aff_entry = getroom(spin, sizeof(*aff_entry), true);
+
+ if (STRCMP(items[2], "0") != 0)
+ aff_entry->ae_chop = getroom_save(spin, items[2]);
+ if (STRCMP(items[3], "0") != 0) {
+ aff_entry->ae_add = getroom_save(spin, items[3]);
+
+ // Recognize flags on the affix: abcd/XYZ
+ aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/');
+ if (aff_entry->ae_flags != NULL) {
+ *aff_entry->ae_flags++ = NUL;
+ aff_process_flags(aff, aff_entry);
+ }
+ }
+
+ // Don't use an affix entry with non-ASCII characters when
+ // "spin->si_ascii" is true.
+ if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop)
+ || has_non_ascii(aff_entry->ae_add))) {
+ aff_entry->ae_next = cur_aff->ah_first;
+ cur_aff->ah_first = aff_entry;
+
+ if (STRCMP(items[4], ".") != 0) {
+ char_u buf[MAXLINELEN];
+
+ aff_entry->ae_cond = getroom_save(spin, items[4]);
+ if (*items[0] == 'P')
+ sprintf((char *)buf, "^%s", items[4]);
+ else
+ sprintf((char *)buf, "%s$", items[4]);
+ aff_entry->ae_prog = vim_regcomp(buf,
+ RE_MAGIC + RE_STRING + RE_STRICT);
+ if (aff_entry->ae_prog == NULL)
+ smsg(_("Broken condition in %s line %d: %s"),
+ fname, lnum, items[4]);
+ }
+
+ // For postponed prefixes we need an entry in si_prefcond
+ // for the condition. Use an existing one if possible.
+ // Can't be done for an affix with flags, ignoring
+ // COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG.
+ if (*items[0] == 'P' && aff->af_pfxpostpone
+ && aff_entry->ae_flags == NULL) {
+ // When the chop string is one lower-case letter and
+ // the add string ends in the upper-case letter we set
+ // the "upper" flag, clear "ae_chop" and remove the
+ // letters from "ae_add". The condition must either
+ // be empty or start with the same letter.
+ if (aff_entry->ae_chop != NULL
+ && aff_entry->ae_add != NULL
+ && aff_entry->ae_chop[(*mb_ptr2len)(
+ aff_entry->ae_chop)] == NUL
+ ) {
+ int c, c_up;
+
+ c = PTR2CHAR(aff_entry->ae_chop);
+ c_up = SPELL_TOUPPER(c);
+ if (c_up != c
+ && (aff_entry->ae_cond == NULL
+ || PTR2CHAR(aff_entry->ae_cond) == c)) {
+ p = aff_entry->ae_add
+ + STRLEN(aff_entry->ae_add);
+ MB_PTR_BACK(aff_entry->ae_add, p);
+ if (PTR2CHAR(p) == c_up) {
+ upper = true;
+ aff_entry->ae_chop = NULL;
+ *p = NUL;
+
+ // The condition is matched with the
+ // actual word, thus must check for the
+ // upper-case letter.
+ if (aff_entry->ae_cond != NULL) {
+ char_u buf[MAXLINELEN];
+ if (has_mbyte) {
+ onecap_copy(items[4], buf, true);
+ aff_entry->ae_cond = getroom_save(
+ spin, buf);
+ } else
+ *aff_entry->ae_cond = c_up;
+ if (aff_entry->ae_cond != NULL) {
+ sprintf((char *)buf, "^%s",
+ aff_entry->ae_cond);
+ vim_regfree(aff_entry->ae_prog);
+ aff_entry->ae_prog = vim_regcomp(
+ buf, RE_MAGIC + RE_STRING);
+ }
+ }
+ }
+ }
+ }
+
+ if (aff_entry->ae_chop == NULL) {
+ int idx;
+ char_u **pp;
+ int n;
+
+ // Find a previously used condition.
+ for (idx = spin->si_prefcond.ga_len - 1; idx >= 0;
+ --idx) {
+ p = ((char_u **)spin->si_prefcond.ga_data)[idx];
+ if (str_equal(p, aff_entry->ae_cond))
+ break;
+ }
+ if (idx < 0) {
+ // Not found, add a new condition.
+ idx = spin->si_prefcond.ga_len;
+ pp = GA_APPEND_VIA_PTR(char_u *, &spin->si_prefcond);
+ *pp = (aff_entry->ae_cond == NULL) ?
+ NULL : getroom_save(spin, aff_entry->ae_cond);
+ }
+
+ // Add the prefix to the prefix tree.
+ if (aff_entry->ae_add == NULL)
+ p = (char_u *)"";
+ else
+ p = aff_entry->ae_add;
+
+ // PFX_FLAGS is a negative number, so that
+ // tree_add_word() knows this is the prefix tree.
+ n = PFX_FLAGS;
+ if (!cur_aff->ah_combine)
+ n |= WFP_NC;
+ if (upper)
+ n |= WFP_UP;
+ if (aff_entry->ae_comppermit)
+ n |= WFP_COMPPERMIT;
+ if (aff_entry->ae_compforbid)
+ n |= WFP_COMPFORBID;
+ tree_add_word(spin, p, spin->si_prefroot, n,
+ idx, cur_aff->ah_newID);
+ did_postpone_prefix = true;
+ }
+
+ // Didn't actually use ah_newID, backup si_newprefID.
+ if (aff_todo == 0 && !did_postpone_prefix) {
+ --spin->si_newprefID;
+ cur_aff->ah_newID = 0;
+ }
+ }
+ }
+ } else if (is_aff_rule(items, itemcnt, "FOL", 2) && fol == NULL) {
+ fol = vim_strsave(items[1]);
+ } else if (is_aff_rule(items, itemcnt, "LOW", 2) && low == NULL) {
+ low = vim_strsave(items[1]);
+ } else if (is_aff_rule(items, itemcnt, "UPP", 2) && upp == NULL) {
+ upp = vim_strsave(items[1]);
+ } else if (is_aff_rule(items, itemcnt, "REP", 2)
+ || is_aff_rule(items, itemcnt, "REPSAL", 2)) {
+ /* Ignore REP/REPSAL count */;
+ if (!isdigit(*items[1]))
+ smsg(_("Expected REP(SAL) count in %s line %d"),
+ fname, lnum);
+ } else if ((STRCMP(items[0], "REP") == 0
+ || STRCMP(items[0], "REPSAL") == 0)
+ && itemcnt >= 3) {
+ // REP/REPSAL item
+ // Myspell ignores extra arguments, we require it starts with
+ // # to detect mistakes.
+ if (itemcnt > 3 && items[3][0] != '#')
+ smsg(_(e_afftrailing), fname, lnum, items[3]);
+ if (items[0][3] == 'S' ? do_repsal : do_rep) {
+ // Replace underscore with space (can't include a space
+ // directly).
+ for (p = items[1]; *p != NUL; MB_PTR_ADV(p)) {
+ if (*p == '_') {
+ *p = ' ';
+ }
+ }
+ for (p = items[2]; *p != NUL; MB_PTR_ADV(p)) {
+ if (*p == '_') {
+ *p = ' ';
+ }
+ }
+ add_fromto(spin, items[0][3] == 'S'
+ ? &spin->si_repsal
+ : &spin->si_rep, items[1], items[2]);
+ }
+ } else if (is_aff_rule(items, itemcnt, "MAP", 2)) {
+ // MAP item or count
+ if (!found_map) {
+ // First line contains the count.
+ found_map = true;
+ if (!isdigit(*items[1]))
+ smsg(_("Expected MAP count in %s line %d"),
+ fname, lnum);
+ } else if (do_mapline) {
+ int c;
+
+ // Check that every character appears only once.
+ for (p = items[1]; *p != NUL; ) {
+ c = mb_ptr2char_adv((const char_u **)&p);
+ if ((!GA_EMPTY(&spin->si_map)
+ && vim_strchr(spin->si_map.ga_data, c)
+ != NULL)
+ || vim_strchr(p, c) != NULL) {
+ smsg(_("Duplicate character in MAP in %s line %d"),
+ fname, lnum);
+ }
+ }
+
+ // We simply concatenate all the MAP strings, separated by
+ // slashes.
+ ga_concat(&spin->si_map, items[1]);
+ ga_append(&spin->si_map, '/');
+ }
+ }
+ // Accept "SAL from to" and "SAL from to #comment".
+ else if (is_aff_rule(items, itemcnt, "SAL", 3)) {
+ if (do_sal) {
+ // SAL item (sounds-a-like)
+ // Either one of the known keys or a from-to pair.
+ if (STRCMP(items[1], "followup") == 0)
+ spin->si_followup = sal_to_bool(items[2]);
+ else if (STRCMP(items[1], "collapse_result") == 0)
+ spin->si_collapse = sal_to_bool(items[2]);
+ else if (STRCMP(items[1], "remove_accents") == 0)
+ spin->si_rem_accents = sal_to_bool(items[2]);
+ else
+ // when "to" is "_" it means empty
+ add_fromto(spin, &spin->si_sal, items[1],
+ STRCMP(items[2], "_") == 0 ? (char_u *)""
+ : items[2]);
+ }
+ } else if (is_aff_rule(items, itemcnt, "SOFOFROM", 2)
+ && sofofrom == NULL) {
+ sofofrom = getroom_save(spin, items[1]);
+ } else if (is_aff_rule(items, itemcnt, "SOFOTO", 2)
+ && sofoto == NULL) {
+ sofoto = getroom_save(spin, items[1]);
+ } else if (STRCMP(items[0], "COMMON") == 0) {
+ int i;
+
+ for (i = 1; i < itemcnt; ++i) {
+ if (HASHITEM_EMPTY(hash_find(&spin->si_commonwords,
+ items[i]))) {
+ p = vim_strsave(items[i]);
+ hash_add(&spin->si_commonwords, p);
+ }
+ }
+ } else
+ smsg(_("Unrecognized or duplicate item in %s line %d: %s"),
+ fname, lnum, items[0]);
+ }
+ }
+
+ if (fol != NULL || low != NULL || upp != NULL) {
+ if (spin->si_clear_chartab) {
+ // Clear the char type tables, don't want to use any of the
+ // currently used spell properties.
+ init_spell_chartab();
+ spin->si_clear_chartab = false;
+ }
+
+ // Don't write a word table for an ASCII file, so that we don't check
+ // for conflicts with a word table that matches 'encoding'.
+ // Don't write one for utf-8 either, we use utf_*() and
+ // mb_get_class(), the list of chars in the file will be incomplete.
+ if (!spin->si_ascii
+ && !enc_utf8
+ ) {
+ if (fol == NULL || low == NULL || upp == NULL)
+ smsg(_("Missing FOL/LOW/UPP line in %s"), fname);
+ else
+ (void)set_spell_chartab(fol, low, upp);
+ }
+
+ xfree(fol);
+ xfree(low);
+ xfree(upp);
+ }
+
+ // Use compound specifications of the .aff file for the spell info.
+ if (compmax != 0) {
+ aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX");
+ spin->si_compmax = compmax;
+ }
+
+ if (compminlen != 0) {
+ aff_check_number(spin->si_compminlen, compminlen, "COMPOUNDMIN");
+ spin->si_compminlen = compminlen;
+ }
+
+ if (compsylmax != 0) {
+ if (syllable == NULL)
+ smsg(_("COMPOUNDSYLMAX used without SYLLABLE"));
+ aff_check_number(spin->si_compsylmax, compsylmax, "COMPOUNDSYLMAX");
+ spin->si_compsylmax = compsylmax;
+ }
+
+ if (compoptions != 0) {
+ aff_check_number(spin->si_compoptions, compoptions, "COMPOUND options");
+ spin->si_compoptions |= compoptions;
+ }
+
+ if (compflags != NULL)
+ process_compflags(spin, aff, compflags);
+
+ // Check that we didn't use too many renumbered flags.
+ if (spin->si_newcompID < spin->si_newprefID) {
+ if (spin->si_newcompID == 127 || spin->si_newcompID == 255)
+ MSG(_("Too many postponed prefixes"));
+ else if (spin->si_newprefID == 0 || spin->si_newprefID == 127)
+ MSG(_("Too many compound flags"));
+ else
+ MSG(_("Too many postponed prefixes and/or compound flags"));
+ }
+
+ if (syllable != NULL) {
+ aff_check_string(spin->si_syllable, syllable, "SYLLABLE");
+ spin->si_syllable = syllable;
+ }
+
+ if (sofofrom != NULL || sofoto != NULL) {
+ if (sofofrom == NULL || sofoto == NULL)
+ smsg(_("Missing SOFO%s line in %s"),
+ sofofrom == NULL ? "FROM" : "TO", fname);
+ else if (!GA_EMPTY(&spin->si_sal))
+ smsg(_("Both SAL and SOFO lines in %s"), fname);
+ else {
+ aff_check_string(spin->si_sofofr, sofofrom, "SOFOFROM");
+ aff_check_string(spin->si_sofoto, sofoto, "SOFOTO");
+ spin->si_sofofr = sofofrom;
+ spin->si_sofoto = sofoto;
+ }
+ }
+
+ if (midword != NULL) {
+ aff_check_string(spin->si_midword, midword, "MIDWORD");
+ spin->si_midword = midword;
+ }
+
+ xfree(pc);
+ fclose(fd);
+ return aff;
+}
+
+// Returns true when items[0] equals "rulename", there are "mincount" items or
+// a comment is following after item "mincount".
+static bool is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount)
+{
+ return STRCMP(items[0], rulename) == 0
+ && (itemcnt == mincount
+ || (itemcnt > mincount && items[mincount][0] == '#'));
+}
+
+// For affix "entry" move COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG from
+// ae_flags to ae_comppermit and ae_compforbid.
+static void aff_process_flags(afffile_T *affile, affentry_T *entry)
+{
+ char_u *p;
+ char_u *prevp;
+ unsigned flag;
+
+ if (entry->ae_flags != NULL
+ && (affile->af_compforbid != 0 || affile->af_comppermit != 0)) {
+ for (p = entry->ae_flags; *p != NUL; ) {
+ prevp = p;
+ flag = get_affitem(affile->af_flagtype, &p);
+ if (flag == affile->af_comppermit || flag == affile->af_compforbid) {
+ STRMOVE(prevp, p);
+ p = prevp;
+ if (flag == affile->af_comppermit)
+ entry->ae_comppermit = true;
+ else
+ entry->ae_compforbid = true;
+ }
+ if (affile->af_flagtype == AFT_NUM && *p == ',')
+ ++p;
+ }
+ if (*entry->ae_flags == NUL)
+ entry->ae_flags = NULL; // nothing left
+ }
+}
+
+// Returns true if "s" is the name of an info item in the affix file.
+static bool spell_info_item(char_u *s)
+{
+ return STRCMP(s, "NAME") == 0
+ || STRCMP(s, "HOME") == 0
+ || STRCMP(s, "VERSION") == 0
+ || STRCMP(s, "AUTHOR") == 0
+ || STRCMP(s, "EMAIL") == 0
+ || STRCMP(s, "COPYRIGHT") == 0;
+}
+
+// Turn an affix flag name into a number, according to the FLAG type.
+// returns zero for failure.
+static unsigned affitem2flag(int flagtype, char_u *item, char_u *fname, int lnum)
+{
+ unsigned res;
+ char_u *p = item;
+
+ res = get_affitem(flagtype, &p);
+ if (res == 0) {
+ if (flagtype == AFT_NUM)
+ smsg(_("Flag is not a number in %s line %d: %s"),
+ fname, lnum, item);
+ else
+ smsg(_("Illegal flag in %s line %d: %s"),
+ fname, lnum, item);
+ }
+ if (*p != NUL) {
+ smsg(_(e_affname), fname, lnum, item);
+ return 0;
+ }
+
+ return res;
+}
+
+// Get one affix name from "*pp" and advance the pointer.
+// Returns zero for an error, still advances the pointer then.
+static unsigned get_affitem(int flagtype, char_u **pp)
+{
+ int res;
+
+ if (flagtype == AFT_NUM) {
+ if (!ascii_isdigit(**pp)) {
+ ++*pp; // always advance, avoid getting stuck
+ return 0;
+ }
+ res = getdigits_int(pp);
+ } else {
+ res = mb_ptr2char_adv((const char_u **)pp);
+ if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
+ && res >= 'A' && res <= 'Z')) {
+ if (**pp == NUL)
+ return 0;
+ res = mb_ptr2char_adv((const char_u **)pp) + (res << 16);
+ }
+ }
+ return res;
+}
+
+// Process the "compflags" string used in an affix file and append it to
+// spin->si_compflags.
+// The processing involves changing the affix names to ID numbers, so that
+// they fit in one byte.
+static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compflags)
+{
+ char_u *p;
+ char_u *prevp;
+ unsigned flag;
+ compitem_T *ci;
+ int id;
+ int len;
+ char_u *tp;
+ char_u key[AH_KEY_LEN];
+ hashitem_T *hi;
+
+ // Make room for the old and the new compflags, concatenated with a / in
+ // between. Processing it makes it shorter, but we don't know by how
+ // much, thus allocate the maximum.
+ len = (int)STRLEN(compflags) + 1;
+ if (spin->si_compflags != NULL)
+ len += (int)STRLEN(spin->si_compflags) + 1;
+ p = getroom(spin, len, false);
+ if (spin->si_compflags != NULL) {
+ STRCPY(p, spin->si_compflags);
+ STRCAT(p, "/");
+ }
+ spin->si_compflags = p;
+ tp = p + STRLEN(p);
+
+ for (p = compflags; *p != NUL; ) {
+ if (vim_strchr((char_u *)"/?*+[]", *p) != NULL)
+ // Copy non-flag characters directly.
+ *tp++ = *p++;
+ else {
+ // First get the flag number, also checks validity.
+ prevp = p;
+ flag = get_affitem(aff->af_flagtype, &p);
+ if (flag != 0) {
+ // Find the flag in the hashtable. If it was used before, use
+ // the existing ID. Otherwise add a new entry.
+ STRLCPY(key, prevp, p - prevp + 1);
+ hi = hash_find(&aff->af_comp, key);
+ if (!HASHITEM_EMPTY(hi)) {
+ id = HI2CI(hi)->ci_newID;
+ } else {
+ ci = getroom(spin, sizeof(compitem_T), true);
+ STRCPY(ci->ci_key, key);
+ ci->ci_flag = flag;
+ // Avoid using a flag ID that has a special meaning in a
+ // regexp (also inside []).
+ do {
+ check_renumber(spin);
+ id = spin->si_newcompID--;
+ } while (vim_strchr((char_u *)"/?*+[]\\-^", id) != NULL);
+ ci->ci_newID = id;
+ hash_add(&aff->af_comp, ci->ci_key);
+ }
+ *tp++ = id;
+ }
+ if (aff->af_flagtype == AFT_NUM && *p == ',')
+ ++p;
+ }
+ }
+
+ *tp = NUL;
+}
+
+// Check that the new IDs for postponed affixes and compounding don't overrun
+// each other. We have almost 255 available, but start at 0-127 to avoid
+// using two bytes for utf-8. When the 0-127 range is used up go to 128-255.
+// When that is used up an error message is given.
+static void check_renumber(spellinfo_T *spin)
+{
+ if (spin->si_newprefID == spin->si_newcompID && spin->si_newcompID < 128) {
+ spin->si_newprefID = 127;
+ spin->si_newcompID = 255;
+ }
+}
+
+// Returns true if flag "flag" appears in affix list "afflist".
+static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
+{
+ char_u *p;
+ unsigned n;
+
+ switch (flagtype) {
+ case AFT_CHAR:
+ return vim_strchr(afflist, flag) != NULL;
+
+ case AFT_CAPLONG:
+ case AFT_LONG:
+ for (p = afflist; *p != NUL; ) {
+ n = mb_ptr2char_adv((const char_u **)&p);
+ if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z'))
+ && *p != NUL) {
+ n = mb_ptr2char_adv((const char_u **)&p) + (n << 16);
+ }
+ if (n == flag) {
+ return true;
+ }
+ }
+ break;
+
+ case AFT_NUM:
+ for (p = afflist; *p != NUL; ) {
+ int digits = getdigits_int(&p);
+ assert(digits >= 0);
+ n = (unsigned int)digits;
+ if (n == flag)
+ return true;
+ if (*p != NUL) // skip over comma
+ ++p;
+ }
+ break;
+ }
+ return false;
+}
+
+// Give a warning when "spinval" and "affval" numbers are set and not the same.
+static void aff_check_number(int spinval, int affval, char *name)
+{
+ if (spinval != 0 && spinval != affval)
+ smsg(_("%s value differs from what is used in another .aff file"),
+ name);
+}
+
+// Give a warning when "spinval" and "affval" strings are set and not the same.
+static void aff_check_string(char_u *spinval, char_u *affval, char *name)
+{
+ if (spinval != NULL && STRCMP(spinval, affval) != 0)
+ smsg(_("%s value differs from what is used in another .aff file"),
+ name);
+}
+
+// Returns true if strings "s1" and "s2" are equal. Also consider both being
+// NULL as equal.
+static bool str_equal(char_u *s1, char_u *s2)
+{
+ if (s1 == NULL || s2 == NULL)
+ return s1 == s2;
+ return STRCMP(s1, s2) == 0;
+}
+
+// Add a from-to item to "gap". Used for REP and SAL items.
+// They are stored case-folded.
+static void add_fromto(spellinfo_T *spin, garray_T *gap, char_u *from, char_u *to)
+{
+ char_u word[MAXWLEN];
+
+ fromto_T *ftp = GA_APPEND_VIA_PTR(fromto_T, gap);
+ (void)spell_casefold(from, (int)STRLEN(from), word, MAXWLEN);
+ ftp->ft_from = getroom_save(spin, word);
+ (void)spell_casefold(to, (int)STRLEN(to), word, MAXWLEN);
+ ftp->ft_to = getroom_save(spin, word);
+}
+
+// Converts a boolean argument in a SAL line to true or false;
+static bool sal_to_bool(char_u *s)
+{
+ return STRCMP(s, "1") == 0 || STRCMP(s, "true") == 0;
+}
+
+// Free the structure filled by spell_read_aff().
+static void spell_free_aff(afffile_T *aff)
+{
+ hashtab_T *ht;
+ hashitem_T *hi;
+ int todo;
+ affheader_T *ah;
+ affentry_T *ae;
+
+ xfree(aff->af_enc);
+
+ // All this trouble to free the "ae_prog" items...
+ for (ht = &aff->af_pref;; ht = &aff->af_suff) {
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ ah = HI2AH(hi);
+ for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next)
+ vim_regfree(ae->ae_prog);
+ }
+ }
+ if (ht == &aff->af_suff)
+ break;
+ }
+
+ hash_clear(&aff->af_pref);
+ hash_clear(&aff->af_suff);
+ hash_clear(&aff->af_comp);
+}
+
+// Read dictionary file "fname".
+// Returns OK or FAIL;
+static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile)
+{
+ hashtab_T ht;
+ char_u line[MAXLINELEN];
+ char_u *p;
+ char_u *afflist;
+ char_u store_afflist[MAXWLEN];
+ int pfxlen;
+ bool need_affix;
+ char_u *dw;
+ char_u *pc;
+ char_u *w;
+ int l;
+ hash_T hash;
+ hashitem_T *hi;
+ FILE *fd;
+ int lnum = 1;
+ int non_ascii = 0;
+ int retval = OK;
+ char_u message[MAXLINELEN + MAXWLEN];
+ int flags;
+ int duplicate = 0;
+
+ // Open the file.
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return FAIL;
+ }
+
+ // The hashtable is only used to detect duplicated words.
+ hash_init(&ht);
+
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Reading dictionary file %s..."), fname);
+ spell_message(spin, IObuff);
+
+ // start with a message for the first line
+ spin->si_msg_count = 999999;
+
+ // Read and ignore the first line: word count.
+ (void)vim_fgets(line, MAXLINELEN, fd);
+ if (!ascii_isdigit(*skipwhite(line)))
+ EMSG2(_("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) {
+ line_breakcheck();
+ ++lnum;
+ if (line[0] == '#' || line[0] == '/')
+ continue; // comment line
+
+ // Remove CR, LF and white space from the end. White space halfway through
+ // the word is kept to allow multi-word terms like "et al.".
+ l = (int)STRLEN(line);
+ while (l > 0 && line[l - 1] <= ' ')
+ --l;
+ if (l == 0)
+ continue; // empty line
+ line[l] = NUL;
+
+ // Convert from "SET" to 'encoding' when needed.
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ pc = string_convert(&spin->si_conv, line, NULL);
+ if (pc == NULL) {
+ smsg(_("Conversion failure for word in %s line %d: %s"),
+ fname, lnum, line);
+ continue;
+ }
+ w = pc;
+ } else {
+ pc = NULL;
+ w = line;
+ }
+
+ // Truncate the word at the "/", set "afflist" to what follows.
+ // Replace "\/" by "/" and "\\" by "\".
+ afflist = NULL;
+ for (p = w; *p != NUL; MB_PTR_ADV(p)) {
+ if (*p == '\\' && (p[1] == '\\' || p[1] == '/')) {
+ STRMOVE(p, p + 1);
+ } else if (*p == '/') {
+ *p = NUL;
+ afflist = p + 1;
+ break;
+ }
+ }
+
+ // Skip non-ASCII words when "spin->si_ascii" is true.
+ if (spin->si_ascii && has_non_ascii(w)) {
+ ++non_ascii;
+ xfree(pc);
+ continue;
+ }
+
+ // This takes time, print a message every 10000 words.
+ if (spin->si_verbose && spin->si_msg_count > 10000) {
+ spin->si_msg_count = 0;
+ vim_snprintf((char *)message, sizeof(message),
+ _("line %6d, word %6ld - %s"),
+ lnum, spin->si_foldwcount + spin->si_keepwcount, w);
+ msg_start();
+ msg_puts_long_attr(message, 0);
+ msg_clr_eos();
+ msg_didout = FALSE;
+ msg_col = 0;
+ ui_flush();
+ }
+
+ // Store the word in the hashtable to be able to find duplicates.
+ dw = getroom_save(spin, w);
+ if (dw == NULL) {
+ retval = FAIL;
+ xfree(pc);
+ break;
+ }
+
+ hash = hash_hash(dw);
+ hi = hash_lookup(&ht, (const char *)dw, STRLEN(dw), hash);
+ if (!HASHITEM_EMPTY(hi)) {
+ if (p_verbose > 0)
+ smsg(_("Duplicate word in %s line %d: %s"),
+ fname, lnum, dw);
+ else if (duplicate == 0)
+ smsg(_("First duplicate word in %s line %d: %s"),
+ fname, lnum, dw);
+ ++duplicate;
+ } else
+ hash_add_item(&ht, hi, dw, hash);
+
+ flags = 0;
+ store_afflist[0] = NUL;
+ pfxlen = 0;
+ need_affix = false;
+ if (afflist != NULL) {
+ // Extract flags from the affix list.
+ flags |= get_affix_flags(affile, afflist);
+
+ if (affile->af_needaffix != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_needaffix))
+ need_affix = true;
+
+ if (affile->af_pfxpostpone)
+ // Need to store the list of prefix IDs with the word.
+ pfxlen = get_pfxlist(affile, afflist, store_afflist);
+
+ if (spin->si_compflags != NULL)
+ // Need to store the list of compound flags with the word.
+ // Concatenate them to the list of prefix IDs.
+ get_compflags(affile, afflist, store_afflist + pfxlen);
+ }
+
+ // Add the word to the word tree(s).
+ if (store_word(spin, dw, flags, spin->si_region,
+ store_afflist, need_affix) == FAIL)
+ retval = FAIL;
+
+ if (afflist != NULL) {
+ // Find all matching suffixes and add the resulting words.
+ // Additionally do matching prefixes that combine.
+ if (store_aff_word(spin, dw, afflist, affile,
+ &affile->af_suff, &affile->af_pref,
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+ retval = FAIL;
+
+ // Find all matching prefixes and add the resulting words.
+ if (store_aff_word(spin, dw, afflist, affile,
+ &affile->af_pref, NULL,
+ CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL)
+ retval = FAIL;
+ }
+
+ xfree(pc);
+ }
+
+ if (duplicate > 0)
+ smsg(_("%d duplicate word(s) in %s"), duplicate, fname);
+ if (spin->si_ascii && non_ascii > 0)
+ smsg(_("Ignored %d word(s) with non-ASCII characters in %s"),
+ non_ascii, fname);
+ hash_clear(&ht);
+
+ fclose(fd);
+ return retval;
+}
+
+// Check for affix flags in "afflist" that are turned into word flags.
+// Return WF_ flags.
+static int get_affix_flags(afffile_T *affile, char_u *afflist)
+{
+ int flags = 0;
+
+ if (affile->af_keepcase != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_keepcase))
+ flags |= WF_KEEPCAP | WF_FIXCAP;
+ if (affile->af_rare != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_rare))
+ flags |= WF_RARE;
+ if (affile->af_bad != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_bad))
+ flags |= WF_BANNED;
+ if (affile->af_needcomp != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_needcomp))
+ flags |= WF_NEEDCOMP;
+ if (affile->af_comproot != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_comproot))
+ flags |= WF_COMPROOT;
+ if (affile->af_nosuggest != 0 && flag_in_afflist(
+ affile->af_flagtype, afflist, affile->af_nosuggest))
+ flags |= WF_NOSUGGEST;
+ return flags;
+}
+
+// Get the list of prefix IDs from the affix list "afflist".
+// Used for PFXPOSTPONE.
+// Put the resulting flags in "store_afflist[MAXWLEN]" with a terminating NUL
+// and return the number of affixes.
+static int get_pfxlist(afffile_T *affile, char_u *afflist, char_u *store_afflist)
+{
+ char_u *p;
+ char_u *prevp;
+ int cnt = 0;
+ int id;
+ char_u key[AH_KEY_LEN];
+ hashitem_T *hi;
+
+ for (p = afflist; *p != NUL; ) {
+ prevp = p;
+ if (get_affitem(affile->af_flagtype, &p) != 0) {
+ // A flag is a postponed prefix flag if it appears in "af_pref"
+ // and it's ID is not zero.
+ STRLCPY(key, prevp, p - prevp + 1);
+ hi = hash_find(&affile->af_pref, key);
+ if (!HASHITEM_EMPTY(hi)) {
+ id = HI2AH(hi)->ah_newID;
+ if (id != 0)
+ store_afflist[cnt++] = id;
+ }
+ }
+ if (affile->af_flagtype == AFT_NUM && *p == ',')
+ ++p;
+ }
+
+ store_afflist[cnt] = NUL;
+ return cnt;
+}
+
+// Get the list of compound IDs from the affix list "afflist" that are used
+// for compound words.
+// Puts the flags in "store_afflist[]".
+static void get_compflags(afffile_T *affile, char_u *afflist, char_u *store_afflist)
+{
+ char_u *p;
+ char_u *prevp;
+ int cnt = 0;
+ char_u key[AH_KEY_LEN];
+ hashitem_T *hi;
+
+ for (p = afflist; *p != NUL; ) {
+ prevp = p;
+ if (get_affitem(affile->af_flagtype, &p) != 0) {
+ // A flag is a compound flag if it appears in "af_comp".
+ STRLCPY(key, prevp, p - prevp + 1);
+ hi = hash_find(&affile->af_comp, key);
+ if (!HASHITEM_EMPTY(hi))
+ store_afflist[cnt++] = HI2CI(hi)->ci_newID;
+ }
+ if (affile->af_flagtype == AFT_NUM && *p == ',')
+ ++p;
+ }
+
+ store_afflist[cnt] = NUL;
+}
+
+// Apply affixes to a word and store the resulting words.
+// "ht" is the hashtable with affentry_T that need to be applied, either
+// prefixes or suffixes.
+// "xht", when not NULL, is the prefix hashtable, to be used additionally on
+// the resulting words for combining affixes.
+//
+// Returns FAIL when out of memory.
+static int
+store_aff_word (
+ spellinfo_T *spin, // spell info
+ char_u *word, // basic word start
+ char_u *afflist, // list of names of supported affixes
+ afffile_T *affile,
+ hashtab_T *ht,
+ hashtab_T *xht,
+ int condit, // CONDIT_SUF et al.
+ int flags, // flags for the word
+ char_u *pfxlist, // list of prefix IDs
+ int pfxlen // nr of flags in "pfxlist" for prefixes, rest
+ // is compound flags
+)
+{
+ int todo;
+ hashitem_T *hi;
+ affheader_T *ah;
+ affentry_T *ae;
+ char_u newword[MAXWLEN];
+ int retval = OK;
+ int i, j;
+ char_u *p;
+ int use_flags;
+ char_u *use_pfxlist;
+ int use_pfxlen;
+ bool need_affix;
+ char_u store_afflist[MAXWLEN];
+ char_u pfx_pfxlist[MAXWLEN];
+ size_t wordlen = STRLEN(word);
+ int use_condit;
+
+ todo = (int)ht->ht_used;
+ for (hi = ht->ht_array; todo > 0 && retval == OK; ++hi) {
+ if (!HASHITEM_EMPTY(hi)) {
+ --todo;
+ ah = HI2AH(hi);
+
+ // Check that the affix combines, if required, and that the word
+ // supports this affix.
+ if (((condit & CONDIT_COMB) == 0 || ah->ah_combine)
+ && flag_in_afflist(affile->af_flagtype, afflist,
+ ah->ah_flag)) {
+ // Loop over all affix entries with this name.
+ for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) {
+ // Check the condition. It's not logical to match case
+ // here, but it is required for compatibility with
+ // Myspell.
+ // Another requirement from Myspell is that the chop
+ // string is shorter than the word itself.
+ // For prefixes, when "PFXPOSTPONE" was used, only do
+ // prefixes with a chop string and/or flags.
+ // When a previously added affix had CIRCUMFIX this one
+ // must have it too, if it had not then this one must not
+ // have one either.
+ if ((xht != NULL || !affile->af_pfxpostpone
+ || ae->ae_chop != NULL
+ || ae->ae_flags != NULL)
+ && (ae->ae_chop == NULL
+ || STRLEN(ae->ae_chop) < wordlen)
+ && (ae->ae_prog == NULL
+ || vim_regexec_prog(&ae->ae_prog, false, word, (colnr_T)0))
+ && (((condit & CONDIT_CFIX) == 0)
+ == ((condit & CONDIT_AFF) == 0
+ || ae->ae_flags == NULL
+ || !flag_in_afflist(affile->af_flagtype,
+ ae->ae_flags, affile->af_circumfix)))) {
+ // Match. Remove the chop and add the affix.
+ if (xht == NULL) {
+ // prefix: chop/add at the start of the word
+ if (ae->ae_add == NULL) {
+ *newword = NUL;
+ } else {
+ STRLCPY(newword, ae->ae_add, MAXWLEN);
+ }
+ p = word;
+ if (ae->ae_chop != NULL) {
+ // Skip chop string.
+ if (has_mbyte) {
+ i = mb_charlen(ae->ae_chop);
+ for (; i > 0; i--) {
+ MB_PTR_ADV(p);
+ }
+ } else {
+ p += STRLEN(ae->ae_chop);
+ }
+ }
+ STRCAT(newword, p);
+ } else {
+ // suffix: chop/add at the end of the word
+ STRLCPY(newword, word, MAXWLEN);
+ if (ae->ae_chop != NULL) {
+ // Remove chop string.
+ p = newword + STRLEN(newword);
+ i = (int)MB_CHARLEN(ae->ae_chop);
+ for (; i > 0; i--) {
+ MB_PTR_BACK(newword, p);
+ }
+ *p = NUL;
+ }
+ if (ae->ae_add != NULL)
+ STRCAT(newword, ae->ae_add);
+ }
+
+ use_flags = flags;
+ use_pfxlist = pfxlist;
+ use_pfxlen = pfxlen;
+ need_affix = false;
+ use_condit = condit | CONDIT_COMB | CONDIT_AFF;
+ if (ae->ae_flags != NULL) {
+ // Extract flags from the affix list.
+ use_flags |= get_affix_flags(affile, ae->ae_flags);
+
+ if (affile->af_needaffix != 0 && flag_in_afflist(
+ affile->af_flagtype, ae->ae_flags,
+ affile->af_needaffix))
+ need_affix = true;
+
+ // When there is a CIRCUMFIX flag the other affix
+ // must also have it and we don't add the word
+ // with one affix.
+ if (affile->af_circumfix != 0 && flag_in_afflist(
+ affile->af_flagtype, ae->ae_flags,
+ affile->af_circumfix)) {
+ use_condit |= CONDIT_CFIX;
+ if ((condit & CONDIT_CFIX) == 0)
+ need_affix = true;
+ }
+
+ if (affile->af_pfxpostpone
+ || spin->si_compflags != NULL) {
+ if (affile->af_pfxpostpone)
+ // Get prefix IDS from the affix list.
+ use_pfxlen = get_pfxlist(affile,
+ ae->ae_flags, store_afflist);
+ else
+ use_pfxlen = 0;
+ use_pfxlist = store_afflist;
+
+ // Combine the prefix IDs. Avoid adding the
+ // same ID twice.
+ for (i = 0; i < pfxlen; ++i) {
+ for (j = 0; j < use_pfxlen; ++j)
+ if (pfxlist[i] == use_pfxlist[j])
+ break;
+ if (j == use_pfxlen)
+ use_pfxlist[use_pfxlen++] = pfxlist[i];
+ }
+
+ if (spin->si_compflags != NULL)
+ // Get compound IDS from the affix list.
+ get_compflags(affile, ae->ae_flags,
+ use_pfxlist + use_pfxlen);
+ else
+ use_pfxlist[use_pfxlen] = NUL;
+
+ // Combine the list of compound flags.
+ // Concatenate them to the prefix IDs list.
+ // Avoid adding the same ID twice.
+ for (i = pfxlen; pfxlist[i] != NUL; ++i) {
+ for (j = use_pfxlen;
+ use_pfxlist[j] != NUL; ++j)
+ if (pfxlist[i] == use_pfxlist[j])
+ break;
+ if (use_pfxlist[j] == NUL) {
+ use_pfxlist[j++] = pfxlist[i];
+ use_pfxlist[j] = NUL;
+ }
+ }
+ }
+ }
+
+ // Obey a "COMPOUNDFORBIDFLAG" of the affix: don't
+ // use the compound flags.
+ if (use_pfxlist != NULL && ae->ae_compforbid) {
+ STRLCPY(pfx_pfxlist, use_pfxlist, use_pfxlen + 1);
+ use_pfxlist = pfx_pfxlist;
+ }
+
+ // When there are postponed prefixes...
+ if (spin->si_prefroot != NULL
+ && spin->si_prefroot->wn_sibling != NULL) {
+ // ... add a flag to indicate an affix was used.
+ use_flags |= WF_HAS_AFF;
+
+ // ... don't use a prefix list if combining
+ // affixes is not allowed. But do use the
+ // compound flags after them.
+ if (!ah->ah_combine && use_pfxlist != NULL)
+ use_pfxlist += use_pfxlen;
+ }
+
+ // When compounding is supported and there is no
+ // "COMPOUNDPERMITFLAG" then forbid compounding on the
+ // side where the affix is applied.
+ if (spin->si_compflags != NULL && !ae->ae_comppermit) {
+ if (xht != NULL)
+ use_flags |= WF_NOCOMPAFT;
+ else
+ use_flags |= WF_NOCOMPBEF;
+ }
+
+ // Store the modified word.
+ if (store_word(spin, newword, use_flags,
+ spin->si_region, use_pfxlist,
+ need_affix) == FAIL)
+ retval = FAIL;
+
+ // When added a prefix or a first suffix and the affix
+ // has flags may add a(nother) suffix. RECURSIVE!
+ if ((condit & CONDIT_SUF) && ae->ae_flags != NULL)
+ if (store_aff_word(spin, newword, ae->ae_flags,
+ affile, &affile->af_suff, xht,
+ use_condit & (xht == NULL
+ ? ~0 : ~CONDIT_SUF),
+ use_flags, use_pfxlist, pfxlen) == FAIL)
+ retval = FAIL;
+
+ // When added a suffix and combining is allowed also
+ // try adding a prefix additionally. Both for the
+ // word flags and for the affix flags. RECURSIVE!
+ if (xht != NULL && ah->ah_combine) {
+ if (store_aff_word(spin, newword,
+ afflist, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL
+ || (ae->ae_flags != NULL
+ && store_aff_word(spin, newword,
+ ae->ae_flags, affile,
+ xht, NULL, use_condit,
+ use_flags, use_pfxlist,
+ pfxlen) == FAIL))
+ retval = FAIL;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return retval;
+}
+
+// Read a file with a list of words.
+static int spell_read_wordfile(spellinfo_T *spin, char_u *fname)
+{
+ FILE *fd;
+ long lnum = 0;
+ char_u rline[MAXLINELEN];
+ char_u *line;
+ char_u *pc = NULL;
+ char_u *p;
+ int l;
+ int retval = OK;
+ bool did_word = false;
+ int non_ascii = 0;
+ int flags;
+ int regionmask;
+
+ // Open the file.
+ fd = mch_fopen((char *)fname, "r");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return FAIL;
+ }
+
+ vim_snprintf((char *)IObuff, IOSIZE, _("Reading word file %s..."), fname);
+ spell_message(spin, IObuff);
+
+ // Read all the lines in the file one by one.
+ while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) {
+ line_breakcheck();
+ ++lnum;
+
+ // Skip comment lines.
+ if (*rline == '#')
+ continue;
+
+ // Remove CR, LF and white space from the end.
+ l = (int)STRLEN(rline);
+ while (l > 0 && rline[l - 1] <= ' ')
+ --l;
+ if (l == 0)
+ continue; // empty or blank line
+ rline[l] = NUL;
+
+ // Convert from "/encoding={encoding}" to 'encoding' when needed.
+ xfree(pc);
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ pc = string_convert(&spin->si_conv, rline, NULL);
+ if (pc == NULL) {
+ smsg(_("Conversion failure for word in %s line %ld: %s"),
+ fname, lnum, rline);
+ continue;
+ }
+ line = pc;
+ } else {
+ pc = NULL;
+ line = rline;
+ }
+
+ if (*line == '/') {
+ ++line;
+ if (STRNCMP(line, "encoding=", 9) == 0) {
+ if (spin->si_conv.vc_type != CONV_NONE) {
+ smsg(_("Duplicate /encoding= line ignored in %s line %ld: %s"),
+ fname, lnum, line - 1);
+ } else if (did_word) {
+ smsg(_("/encoding= line after word ignored in %s line %ld: %s"),
+ fname, lnum, line - 1);
+ } else {
+ char_u *enc;
+
+ // Setup for conversion to 'encoding'.
+ line += 9;
+ enc = enc_canonize(line);
+ if (!spin->si_ascii
+ && convert_setup(&spin->si_conv, enc,
+ p_enc) == FAIL)
+ smsg(_("Conversion in %s not supported: from %s to %s"),
+ fname, line, p_enc);
+ xfree(enc);
+ spin->si_conv.vc_fail = true;
+ }
+ continue;
+ }
+
+ if (STRNCMP(line, "regions=", 8) == 0) {
+ if (spin->si_region_count > 1) {
+ smsg(_("Duplicate /regions= line ignored in %s line %ld: %s"),
+ fname, lnum, line);
+ } else {
+ line += 8;
+ if (STRLEN(line) > MAXREGIONS * 2) {
+ smsg(_("Too many regions in %s line %ld: %s"),
+ fname, lnum, line);
+ } else {
+ spin->si_region_count = (int)STRLEN(line) / 2;
+ STRCPY(spin->si_region_name, line);
+
+ // Adjust the mask for a word valid in all regions.
+ spin->si_region = (1 << spin->si_region_count) - 1;
+ }
+ }
+ continue;
+ }
+
+ smsg(_("/ line ignored in %s line %ld: %s"),
+ fname, lnum, line - 1);
+ continue;
+ }
+
+ flags = 0;
+ regionmask = spin->si_region;
+
+ // Check for flags and region after a slash.
+ p = vim_strchr(line, '/');
+ if (p != NULL) {
+ *p++ = NUL;
+ while (*p != NUL) {
+ if (*p == '=') // keep-case word
+ flags |= WF_KEEPCAP | WF_FIXCAP;
+ else if (*p == '!') // Bad, bad, wicked word.
+ flags |= WF_BANNED;
+ else if (*p == '?') // Rare word.
+ flags |= WF_RARE;
+ else if (ascii_isdigit(*p)) { // region number(s)
+ if ((flags & WF_REGION) == 0) // first one
+ regionmask = 0;
+ flags |= WF_REGION;
+
+ l = *p - '0';
+ if (l == 0 || l > spin->si_region_count) {
+ smsg(_("Invalid region nr in %s line %ld: %s"),
+ fname, lnum, p);
+ break;
+ }
+ regionmask |= 1 << (l - 1);
+ } else {
+ smsg(_("Unrecognized flags in %s line %ld: %s"),
+ fname, lnum, p);
+ break;
+ }
+ ++p;
+ }
+ }
+
+ // Skip non-ASCII words when "spin->si_ascii" is true.
+ if (spin->si_ascii && has_non_ascii(line)) {
+ ++non_ascii;
+ continue;
+ }
+
+ // Normal word: store it.
+ if (store_word(spin, line, flags, regionmask, NULL, false) == FAIL) {
+ retval = FAIL;
+ break;
+ }
+ did_word = true;
+ }
+
+ xfree(pc);
+ fclose(fd);
+
+ if (spin->si_ascii && non_ascii > 0) {
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Ignored %d words with non-ASCII characters"), non_ascii);
+ spell_message(spin, IObuff);
+ }
+
+ return retval;
+}
+
+/// Get part of an sblock_T, "len" bytes long.
+/// This avoids calling free() for every little struct we use (and keeping
+/// track of them).
+/// The memory is cleared to all zeros.
+///
+/// @param len Length needed (<= SBLOCKSIZE).
+/// @param align Align for pointer.
+/// @return Pointer into block data.
+static void *getroom(spellinfo_T *spin, size_t len, bool align)
+ FUNC_ATTR_NONNULL_RET
+{
+ char_u *p;
+ sblock_T *bl = spin->si_blocks;
+
+ assert(len <= SBLOCKSIZE);
+
+ if (align && bl != NULL)
+ // Round size up for alignment. On some systems structures need to be
+ // aligned to the size of a pointer (e.g., SPARC).
+ bl->sb_used = (bl->sb_used + sizeof(char *) - 1)
+ & ~(sizeof(char *) - 1);
+
+ if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) {
+ // Allocate a block of memory. It is not freed until much later.
+ bl = xcalloc(1, (sizeof(sblock_T) + SBLOCKSIZE));
+ bl->sb_next = spin->si_blocks;
+ spin->si_blocks = bl;
+ bl->sb_used = 0;
+ ++spin->si_blocks_cnt;
+ }
+
+ p = bl->sb_data + bl->sb_used;
+ bl->sb_used += (int)len;
+
+ return p;
+}
+
+// Make a copy of a string into memory allocated with getroom().
+// Returns NULL when out of memory.
+static char_u *getroom_save(spellinfo_T *spin, char_u *s)
+{
+ const size_t s_size = STRLEN(s) + 1;
+ return memcpy(getroom(spin, s_size, false), s, s_size);
+}
+
+
+// Free the list of allocated sblock_T.
+static void free_blocks(sblock_T *bl)
+{
+ sblock_T *next;
+
+ while (bl != NULL) {
+ next = bl->sb_next;
+ xfree(bl);
+ bl = next;
+ }
+}
+
+// Allocate the root of a word tree.
+// Returns NULL when out of memory.
+static wordnode_T *wordtree_alloc(spellinfo_T *spin)
+ FUNC_ATTR_NONNULL_RET
+{
+ return (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
+}
+
+// Store a word in the tree(s).
+// Always store it in the case-folded tree. For a keep-case word this is
+// useful when the word can also be used with all caps (no WF_FIXCAP flag) and
+// used to find suggestions.
+// For a keep-case word also store it in the keep-case tree.
+// When "pfxlist" is not NULL store the word for each postponed prefix ID and
+// compound flag.
+static int
+store_word (
+ spellinfo_T *spin,
+ char_u *word,
+ int flags, // extra flags, WF_BANNED
+ int region, // supported region(s)
+ char_u *pfxlist, // list of prefix IDs or NULL
+ bool need_affix // only store word with affix ID
+)
+{
+ int len = (int)STRLEN(word);
+ int ct = captype(word, word + len);
+ char_u foldword[MAXWLEN];
+ int res = OK;
+ char_u *p;
+
+ (void)spell_casefold(word, len, foldword, MAXWLEN);
+ for (p = pfxlist; res == OK; ++p) {
+ if (!need_affix || (p != NULL && *p != NUL))
+ res = tree_add_word(spin, foldword, spin->si_foldroot, ct | flags,
+ region, p == NULL ? 0 : *p);
+ if (p == NULL || *p == NUL)
+ break;
+ }
+ ++spin->si_foldwcount;
+
+ if (res == OK && (ct == WF_KEEPCAP || (flags & WF_KEEPCAP))) {
+ for (p = pfxlist; res == OK; ++p) {
+ if (!need_affix || (p != NULL && *p != NUL))
+ res = tree_add_word(spin, word, spin->si_keeproot, flags,
+ region, p == NULL ? 0 : *p);
+ if (p == NULL || *p == NUL)
+ break;
+ }
+ ++spin->si_keepwcount;
+ }
+ return res;
+}
+
+// Add word "word" to a word tree at "root".
+// When "flags" < 0 we are adding to the prefix tree where "flags" is used for
+// "rare" and "region" is the condition nr.
+// Returns FAIL when out of memory.
+static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int flags, int region, int affixID)
+{
+ wordnode_T *node = root;
+ wordnode_T *np;
+ wordnode_T *copyp, **copyprev;
+ wordnode_T **prev = NULL;
+ int i;
+
+ // Add each byte of the word to the tree, including the NUL at the end.
+ for (i = 0;; ++i) {
+ // When there is more than one reference to this node we need to make
+ // a copy, so that we can modify it. Copy the whole list of siblings
+ // (we don't optimize for a partly shared list of siblings).
+ if (node != NULL && node->wn_refs > 1) {
+ --node->wn_refs;
+ copyprev = prev;
+ for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) {
+ // Allocate a new node and copy the info.
+ np = get_wordnode(spin);
+ if (np == NULL)
+ return FAIL;
+ np->wn_child = copyp->wn_child;
+ if (np->wn_child != NULL)
+ ++np->wn_child->wn_refs; // child gets extra ref
+ np->wn_byte = copyp->wn_byte;
+ if (np->wn_byte == NUL) {
+ np->wn_flags = copyp->wn_flags;
+ np->wn_region = copyp->wn_region;
+ np->wn_affixID = copyp->wn_affixID;
+ }
+
+ // Link the new node in the list, there will be one ref.
+ np->wn_refs = 1;
+ if (copyprev != NULL)
+ *copyprev = np;
+ copyprev = &np->wn_sibling;
+
+ // Let "node" point to the head of the copied list.
+ if (copyp == node)
+ node = np;
+ }
+ }
+
+ // Look for the sibling that has the same character. They are sorted
+ // on byte value, thus stop searching when a sibling is found with a
+ // higher byte value. For zero bytes (end of word) the sorting is
+ // done on flags and then on affixID.
+ while (node != NULL
+ && (node->wn_byte < word[i]
+ || (node->wn_byte == NUL
+ && (flags < 0
+ ? node->wn_affixID < (unsigned)affixID
+ : (node->wn_flags < (unsigned)(flags & WN_MASK)
+ || (node->wn_flags == (flags & WN_MASK)
+ && (spin->si_sugtree
+ ? (node->wn_region & 0xffff) < region
+ : node->wn_affixID
+ < (unsigned)affixID))))))) {
+ prev = &node->wn_sibling;
+ node = *prev;
+ }
+ if (node == NULL
+ || node->wn_byte != word[i]
+ || (word[i] == NUL
+ && (flags < 0
+ || spin->si_sugtree
+ || node->wn_flags != (flags & WN_MASK)
+ || node->wn_affixID != affixID))) {
+ // Allocate a new node.
+ np = get_wordnode(spin);
+ if (np == NULL)
+ return FAIL;
+ np->wn_byte = word[i];
+
+ // If "node" is NULL this is a new child or the end of the sibling
+ // list: ref count is one. Otherwise use ref count of sibling and
+ // make ref count of sibling one (matters when inserting in front
+ // of the list of siblings).
+ if (node == NULL)
+ np->wn_refs = 1;
+ else {
+ np->wn_refs = node->wn_refs;
+ node->wn_refs = 1;
+ }
+ if (prev != NULL)
+ *prev = np;
+ np->wn_sibling = node;
+ node = np;
+ }
+
+ if (word[i] == NUL) {
+ node->wn_flags = flags;
+ node->wn_region |= region;
+ node->wn_affixID = affixID;
+ break;
+ }
+ prev = &node->wn_child;
+ node = *prev;
+ }
+#ifdef SPELL_PRINTTREE
+ smsg((char_u *)"Added \"%s\"", word);
+ spell_print_tree(root->wn_sibling);
+#endif
+
+ // count nr of words added since last message
+ ++spin->si_msg_count;
+
+ if (spin->si_compress_cnt > 1) {
+ if (--spin->si_compress_cnt == 1)
+ // Did enough words to lower the block count limit.
+ spin->si_blocks_cnt += compress_inc;
+ }
+
+ // When we have allocated lots of memory we need to compress the word tree
+ // to free up some room. But compression is slow, and we might actually
+ // need that room, thus only compress in the following situations:
+ // 1. When not compressed before (si_compress_cnt == 0): when using
+ // "compress_start" blocks.
+ // 2. When compressed before and used "compress_inc" blocks before
+ // adding "compress_added" words (si_compress_cnt > 1).
+ // 3. When compressed before, added "compress_added" words
+ // (si_compress_cnt == 1) and the number of free nodes drops below the
+ // maximum word length.
+#ifndef SPELL_COMPRESS_ALLWAYS
+ if (spin->si_compress_cnt == 1 // NOLINT(readability/braces)
+ ? spin->si_free_count < MAXWLEN
+ : spin->si_blocks_cnt >= compress_start)
+#endif
+ {
+ // Decrement the block counter. The effect is that we compress again
+ // when the freed up room has been used and another "compress_inc"
+ // blocks have been allocated. Unless "compress_added" words have
+ // been added, then the limit is put back again.
+ spin->si_blocks_cnt -= compress_inc;
+ spin->si_compress_cnt = compress_added;
+
+ if (spin->si_verbose) {
+ msg_start();
+ msg_puts(_(msg_compressing));
+ msg_clr_eos();
+ msg_didout = FALSE;
+ msg_col = 0;
+ ui_flush();
+ }
+
+ // Compress both trees. Either they both have many nodes, which makes
+ // compression useful, or one of them is small, which means
+ // compression goes fast. But when filling the soundfold word tree
+ // there is no keep-case tree.
+ wordtree_compress(spin, spin->si_foldroot);
+ if (affixID >= 0)
+ wordtree_compress(spin, spin->si_keeproot);
+ }
+
+ return OK;
+}
+
+// Get a wordnode_T, either from the list of previously freed nodes or
+// allocate a new one.
+// Returns NULL when out of memory.
+static wordnode_T *get_wordnode(spellinfo_T *spin)
+{
+ wordnode_T *n;
+
+ if (spin->si_first_free == NULL)
+ n = (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
+ else {
+ n = spin->si_first_free;
+ spin->si_first_free = n->wn_child;
+ memset(n, 0, sizeof(wordnode_T));
+ --spin->si_free_count;
+ }
+#ifdef SPELL_PRINTTREE
+ if (n != NULL)
+ n->wn_nr = ++spin->si_wordnode_nr;
+#endif
+ return n;
+}
+
+// Decrement the reference count on a node (which is the head of a list of
+// siblings). If the reference count becomes zero free the node and its
+// siblings.
+// Returns the number of nodes actually freed.
+static int deref_wordnode(spellinfo_T *spin, wordnode_T *node)
+{
+ wordnode_T *np;
+ int cnt = 0;
+
+ if (--node->wn_refs == 0) {
+ for (np = node; np != NULL; np = np->wn_sibling) {
+ if (np->wn_child != NULL)
+ cnt += deref_wordnode(spin, np->wn_child);
+ free_wordnode(spin, np);
+ ++cnt;
+ }
+ ++cnt; // length field
+ }
+ return cnt;
+}
+
+// Free a wordnode_T for re-use later.
+// Only the "wn_child" field becomes invalid.
+static void free_wordnode(spellinfo_T *spin, wordnode_T *n)
+{
+ n->wn_child = spin->si_first_free;
+ spin->si_first_free = n;
+ ++spin->si_free_count;
+}
+
+// Compress a tree: find tails that are identical and can be shared.
+static void wordtree_compress(spellinfo_T *spin, wordnode_T *root)
+{
+ hashtab_T ht;
+ int n;
+ int tot = 0;
+ int perc;
+
+ // Skip the root itself, it's not actually used. The first sibling is the
+ // start of the tree.
+ if (root->wn_sibling != NULL) {
+ hash_init(&ht);
+ n = node_compress(spin, root->wn_sibling, &ht, &tot);
+
+#ifndef SPELL_PRINTTREE
+ if (spin->si_verbose || p_verbose > 2)
+#endif
+ {
+ if (tot > 1000000)
+ perc = (tot - n) / (tot / 100);
+ else if (tot == 0)
+ perc = 0;
+ else
+ perc = (tot - n) * 100 / tot;
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Compressed %d of %d nodes; %d (%d%%) remaining"),
+ n, tot, tot - n, perc);
+ spell_message(spin, IObuff);
+ }
+#ifdef SPELL_PRINTTREE
+ spell_print_tree(root->wn_sibling);
+#endif
+ hash_clear(&ht);
+ }
+}
+
+// Compress a node, its siblings and its children, depth first.
+// Returns the number of compressed nodes.
+static int
+node_compress (
+ spellinfo_T *spin,
+ wordnode_T *node,
+ hashtab_T *ht,
+ int *tot // total count of nodes before compressing,
+ // incremented while going through the tree
+)
+{
+ wordnode_T *np;
+ wordnode_T *tp;
+ wordnode_T *child;
+ hash_T hash;
+ hashitem_T *hi;
+ int len = 0;
+ unsigned nr, n;
+ int compressed = 0;
+
+ // Go through the list of siblings. Compress each child and then try
+ // finding an identical child to replace it.
+ // Note that with "child" we mean not just the node that is pointed to,
+ // but the whole list of siblings of which the child node is the first.
+ for (np = node; np != NULL && !got_int; np = np->wn_sibling) {
+ ++len;
+ if ((child = np->wn_child) != NULL) {
+ // Compress the child first. This fills hashkey.
+ compressed += node_compress(spin, child, ht, tot);
+
+ // Try to find an identical child.
+ hash = hash_hash(child->wn_u1.hashkey);
+ hi = hash_lookup(ht, (const char *)child->wn_u1.hashkey,
+ STRLEN(child->wn_u1.hashkey), hash);
+ if (!HASHITEM_EMPTY(hi)) {
+ // There are children we encountered before with a hash value
+ // identical to the current child. Now check if there is one
+ // that is really identical.
+ for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next)
+ if (node_equal(child, tp)) {
+ // Found one! Now use that child in place of the
+ // current one. This means the current child and all
+ // its siblings is unlinked from the tree.
+ ++tp->wn_refs;
+ compressed += deref_wordnode(spin, child);
+ np->wn_child = tp;
+ break;
+ }
+ if (tp == NULL) {
+ // No other child with this hash value equals the child of
+ // the node, add it to the linked list after the first
+ // item.
+ tp = HI2WN(hi);
+ child->wn_u2.next = tp->wn_u2.next;
+ tp->wn_u2.next = child;
+ }
+ } else
+ // No other child has this hash value, add it to the
+ // hashtable.
+ hash_add_item(ht, hi, child->wn_u1.hashkey, hash);
+ }
+ }
+ *tot += len + 1; // add one for the node that stores the length
+
+ // Make a hash key for the node and its siblings, so that we can quickly
+ // find a lookalike node. This must be done after compressing the sibling
+ // list, otherwise the hash key would become invalid by the compression.
+ node->wn_u1.hashkey[0] = len;
+ nr = 0;
+ for (np = node; np != NULL; np = np->wn_sibling) {
+ if (np->wn_byte == NUL)
+ // end node: use wn_flags, wn_region and wn_affixID
+ n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16);
+ else
+ // byte node: use the byte value and the child pointer
+ n = (unsigned)(np->wn_byte + ((uintptr_t)np->wn_child << 8));
+ nr = nr * 101 + n;
+ }
+
+ // Avoid NUL bytes, it terminates the hash key.
+ n = nr & 0xff;
+ node->wn_u1.hashkey[1] = n == 0 ? 1 : n;
+ n = (nr >> 8) & 0xff;
+ node->wn_u1.hashkey[2] = n == 0 ? 1 : n;
+ n = (nr >> 16) & 0xff;
+ node->wn_u1.hashkey[3] = n == 0 ? 1 : n;
+ n = (nr >> 24) & 0xff;
+ node->wn_u1.hashkey[4] = n == 0 ? 1 : n;
+ node->wn_u1.hashkey[5] = NUL;
+
+ // Check for CTRL-C pressed now and then.
+ fast_breakcheck();
+
+ return compressed;
+}
+
+// Returns true when two nodes have identical siblings and children.
+static bool node_equal(wordnode_T *n1, wordnode_T *n2)
+{
+ wordnode_T *p1;
+ wordnode_T *p2;
+
+ for (p1 = n1, p2 = n2; p1 != NULL && p2 != NULL;
+ p1 = p1->wn_sibling, p2 = p2->wn_sibling)
+ if (p1->wn_byte != p2->wn_byte
+ || (p1->wn_byte == NUL
+ ? (p1->wn_flags != p2->wn_flags
+ || p1->wn_region != p2->wn_region
+ || p1->wn_affixID != p2->wn_affixID)
+ : (p1->wn_child != p2->wn_child)))
+ break;
+
+ return p1 == NULL && p2 == NULL;
+}
+
+
+// Function given to qsort() to sort the REP items on "from" string.
+static int rep_compare(const void *s1, const void *s2)
+{
+ fromto_T *p1 = (fromto_T *)s1;
+ fromto_T *p2 = (fromto_T *)s2;
+
+ return STRCMP(p1->ft_from, p2->ft_from);
+}
+
+// Write the Vim .spl file "fname".
+// Return OK/FAIL.
+static int write_vim_spell(spellinfo_T *spin, char_u *fname)
+{
+ int retval = OK;
+ int regionmask;
+
+ FILE *fd = mch_fopen((char *)fname, "w");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return FAIL;
+ }
+
+ // <HEADER>: <fileID> <versionnr>
+ // <fileID>
+ size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd);
+ if (fwv != (size_t)1)
+ // Catch first write error, don't try writing more.
+ goto theend;
+
+ putc(VIMSPELLVERSION, fd); // <versionnr>
+
+ // <SECTIONS>: <section> ... <sectionend>
+
+ // SN_INFO: <infotext>
+ if (spin->si_info != NULL) {
+ putc(SN_INFO, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ size_t i = STRLEN(spin->si_info);
+ put_bytes(fd, i, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_info, i, 1, fd); // <infotext>
+ }
+
+ // SN_REGION: <regionname> ...
+ // Write the region names only if there is more than one.
+ if (spin->si_region_count > 1) {
+ putc(SN_REGION, fd); // <sectionID>
+ putc(SNF_REQUIRED, fd); // <sectionflags>
+ size_t l = (size_t)spin->si_region_count * 2;
+ put_bytes(fd, l, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_region_name, l, 1, fd);
+ // <regionname> ...
+ regionmask = (1 << spin->si_region_count) - 1;
+ } else
+ regionmask = 0;
+
+ // SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars>
+ //
+ // The table with character flags and the table for case folding.
+ // This makes sure the same characters are recognized as word characters
+ // when generating an when using a spell file.
+ // Skip this for ASCII, the table may conflict with the one used for
+ // 'encoding'.
+ // Also skip this for an .add.spl file, the main spell file must contain
+ // the table (avoids that it conflicts). File is shorter too.
+ if (!spin->si_ascii && !spin->si_add) {
+ char_u folchars[128 * 8];
+ int flags;
+
+ putc(SN_CHARFLAGS, fd); // <sectionID>
+ putc(SNF_REQUIRED, fd); // <sectionflags>
+
+ // Form the <folchars> string first, we need to know its length.
+ size_t l = 0;
+ for (size_t i = 128; i < 256; i++) {
+ l += (size_t)utf_char2bytes(spelltab.st_fold[i], folchars + l);
+ }
+ put_bytes(fd, 1 + 128 + 2 + l, 4); // <sectionlen>
+
+ fputc(128, fd); // <charflagslen>
+ for (size_t i = 128; i < 256; ++i) {
+ flags = 0;
+ if (spelltab.st_isw[i])
+ flags |= CF_WORD;
+ if (spelltab.st_isu[i])
+ flags |= CF_UPPER;
+ fputc(flags, fd); // <charflags>
+ }
+
+ put_bytes(fd, l, 2); // <folcharslen>
+ fwv &= fwrite(folchars, l, 1, fd); // <folchars>
+ }
+
+ // SN_MIDWORD: <midword>
+ if (spin->si_midword != NULL) {
+ putc(SN_MIDWORD, fd); // <sectionID>
+ putc(SNF_REQUIRED, fd); // <sectionflags>
+
+ size_t i = STRLEN(spin->si_midword);
+ put_bytes(fd, i, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_midword, i, 1, fd);
+ // <midword>
+ }
+
+ // SN_PREFCOND: <prefcondcnt> <prefcond> ...
+ if (!GA_EMPTY(&spin->si_prefcond)) {
+ putc(SN_PREFCOND, fd); // <sectionID>
+ putc(SNF_REQUIRED, fd); // <sectionflags>
+
+ size_t l = (size_t)write_spell_prefcond(NULL, &spin->si_prefcond);
+ put_bytes(fd, l, 4); // <sectionlen>
+
+ write_spell_prefcond(fd, &spin->si_prefcond);
+ }
+
+ // SN_REP: <repcount> <rep> ...
+ // SN_SAL: <salflags> <salcount> <sal> ...
+ // SN_REPSAL: <repcount> <rep> ...
+
+ // round 1: SN_REP section
+ // round 2: SN_SAL section (unless SN_SOFO is used)
+ // round 3: SN_REPSAL section
+ for (unsigned int round = 1; round <= 3; ++round) {
+ garray_T *gap;
+ if (round == 1)
+ gap = &spin->si_rep;
+ else if (round == 2) {
+ // Don't write SN_SAL when using a SN_SOFO section
+ if (spin->si_sofofr != NULL && spin->si_sofoto != NULL)
+ continue;
+ gap = &spin->si_sal;
+ } else
+ gap = &spin->si_repsal;
+
+ // Don't write the section if there are no items.
+ if (GA_EMPTY(gap))
+ continue;
+
+ // Sort the REP/REPSAL items.
+ if (round != 2)
+ qsort(gap->ga_data, (size_t)gap->ga_len,
+ sizeof(fromto_T), rep_compare);
+
+ int sect_id = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL);
+ putc(sect_id, fd); // <sectionID>
+
+ // This is for making suggestions, section is not required.
+ putc(0, fd); // <sectionflags>
+
+ // Compute the length of what follows.
+ size_t l = 2; // count <repcount> or <salcount>
+ assert(gap->ga_len >= 0);
+ for (size_t i = 0; i < (size_t)gap->ga_len; ++i) {
+ fromto_T *ftp = &((fromto_T *)gap->ga_data)[i];
+ l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from>
+ l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to>
+ }
+ if (round == 2)
+ ++l; // count <salflags>
+ put_bytes(fd, l, 4); // <sectionlen>
+
+ if (round == 2) {
+ int i = 0;
+ if (spin->si_followup)
+ i |= SAL_F0LLOWUP;
+ if (spin->si_collapse)
+ i |= SAL_COLLAPSE;
+ if (spin->si_rem_accents)
+ i |= SAL_REM_ACCENTS;
+ putc(i, fd); // <salflags>
+ }
+
+ put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <repcount> or <salcount>
+ for (size_t i = 0; i < (size_t)gap->ga_len; ++i) {
+ // <rep> : <repfromlen> <repfrom> <reptolen> <repto>
+ // <sal> : <salfromlen> <salfrom> <saltolen> <salto>
+ fromto_T *ftp = &((fromto_T *)gap->ga_data)[i];
+ for (unsigned int rr = 1; rr <= 2; ++rr) {
+ char_u *p = rr == 1 ? ftp->ft_from : ftp->ft_to;
+ l = STRLEN(p);
+ assert(l < INT_MAX);
+ putc((int)l, fd);
+ if (l > 0)
+ fwv &= fwrite(p, l, 1, fd);
+ }
+ }
+
+ }
+
+ // SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto>
+ // This is for making suggestions, section is not required.
+ if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) {
+ putc(SN_SOFO, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ size_t l = STRLEN(spin->si_sofofr);
+ put_bytes(fd, l + STRLEN(spin->si_sofoto) + 4, 4); // <sectionlen>
+
+ put_bytes(fd, l, 2); // <sofofromlen>
+ fwv &= fwrite(spin->si_sofofr, l, 1, fd); // <sofofrom>
+
+ l = STRLEN(spin->si_sofoto);
+ put_bytes(fd, l, 2); // <sofotolen>
+ fwv &= fwrite(spin->si_sofoto, l, 1, fd); // <sofoto>
+ }
+
+ // SN_WORDS: <word> ...
+ // This is for making suggestions, section is not required.
+ if (spin->si_commonwords.ht_used > 0) {
+ putc(SN_WORDS, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ // round 1: count the bytes
+ // round 2: write the bytes
+ for (unsigned int round = 1; round <= 2; ++round) {
+ size_t todo;
+ size_t len = 0;
+ hashitem_T *hi;
+
+ todo = spin->si_commonwords.ht_used;
+ for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi)
+ if (!HASHITEM_EMPTY(hi)) {
+ size_t l = STRLEN(hi->hi_key) + 1;
+ len += l;
+ if (round == 2) // <word>
+ fwv &= fwrite(hi->hi_key, l, 1, fd);
+ --todo;
+ }
+ if (round == 1)
+ put_bytes(fd, len, 4); // <sectionlen>
+ }
+ }
+
+ // SN_MAP: <mapstr>
+ // This is for making suggestions, section is not required.
+ if (!GA_EMPTY(&spin->si_map)) {
+ putc(SN_MAP, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ size_t l = (size_t)spin->si_map.ga_len;
+ put_bytes(fd, l, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_map.ga_data, l, 1, fd); // <mapstr>
+ }
+
+ // SN_SUGFILE: <timestamp>
+ // This is used to notify that a .sug file may be available and at the
+ // same time allows for checking that a .sug file that is found matches
+ // with this .spl file. That's because the word numbers must be exactly
+ // right.
+ if (!spin->si_nosugfile
+ && (!GA_EMPTY(&spin->si_sal)
+ || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) {
+ putc(SN_SUGFILE, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ put_bytes(fd, 8, 4); // <sectionlen>
+
+ // Set si_sugtime and write it to the file.
+ spin->si_sugtime = time(NULL);
+ put_time(fd, spin->si_sugtime); // <timestamp>
+ }
+
+ // SN_NOSPLITSUGS: nothing
+ // This is used to notify that no suggestions with word splits are to be
+ // made.
+ if (spin->si_nosplitsugs) {
+ putc(SN_NOSPLITSUGS, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ put_bytes(fd, 0, 4); // <sectionlen>
+ }
+
+ // SN_NOCOMPUNDSUGS: nothing
+ // This is used to notify that no suggestions with compounds are to be
+ // made.
+ if (spin->si_nocompoundsugs) {
+ putc(SN_NOCOMPOUNDSUGS, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+ put_bytes(fd, 0, 4); // <sectionlen>
+ }
+
+ // SN_COMPOUND: compound info.
+ // We don't mark it required, when not supported all compound words will
+ // be bad words.
+ if (spin->si_compflags != NULL) {
+ putc(SN_COMPOUND, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ size_t l = STRLEN(spin->si_compflags);
+ assert(spin->si_comppat.ga_len >= 0);
+ for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) {
+ l += STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1;
+ }
+ put_bytes(fd, l + 7, 4); // <sectionlen>
+
+ putc(spin->si_compmax, fd); // <compmax>
+ putc(spin->si_compminlen, fd); // <compminlen>
+ putc(spin->si_compsylmax, fd); // <compsylmax>
+ putc(0, fd); // for Vim 7.0b compatibility
+ putc(spin->si_compoptions, fd); // <compoptions>
+ put_bytes(fd, (uintmax_t)spin->si_comppat.ga_len, 2); // <comppatcount>
+ for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) {
+ char_u *p = ((char_u **)(spin->si_comppat.ga_data))[i];
+ assert(STRLEN(p) < INT_MAX);
+ putc((int)STRLEN(p), fd); // <comppatlen>
+ fwv &= fwrite(p, STRLEN(p), 1, fd); // <comppattext>
+ }
+ // <compflags>
+ fwv &= fwrite(spin->si_compflags, STRLEN(spin->si_compflags), 1, fd);
+ }
+
+ // SN_NOBREAK: NOBREAK flag
+ if (spin->si_nobreak) {
+ putc(SN_NOBREAK, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ // It's empty, the presence of the section flags the feature.
+ put_bytes(fd, 0, 4); // <sectionlen>
+ }
+
+ // SN_SYLLABLE: syllable info.
+ // We don't mark it required, when not supported syllables will not be
+ // counted.
+ if (spin->si_syllable != NULL) {
+ putc(SN_SYLLABLE, fd); // <sectionID>
+ putc(0, fd); // <sectionflags>
+
+ size_t l = STRLEN(spin->si_syllable);
+ put_bytes(fd, l, 4); // <sectionlen>
+ fwv &= fwrite(spin->si_syllable, l, 1, fd); // <syllable>
+ }
+
+ // end of <SECTIONS>
+ putc(SN_END, fd); // <sectionend>
+
+
+ // <LWORDTREE> <KWORDTREE> <PREFIXTREE>
+ spin->si_memtot = 0;
+ for (unsigned int round = 1; round <= 3; ++round) {
+ wordnode_T *tree;
+ if (round == 1)
+ tree = spin->si_foldroot->wn_sibling;
+ else if (round == 2)
+ tree = spin->si_keeproot->wn_sibling;
+ else
+ tree = spin->si_prefroot->wn_sibling;
+
+ // Clear the index and wnode fields in the tree.
+ clear_node(tree);
+
+ // Count the number of nodes. Needed to be able to allocate the
+ // memory when reading the nodes. Also fills in index for shared
+ // nodes.
+ size_t nodecount = (size_t)put_node(NULL, tree, 0, regionmask, round == 3);
+
+ // number of nodes in 4 bytes
+ put_bytes(fd, nodecount, 4); // <nodecount>
+ assert(nodecount + nodecount * sizeof(int) < INT_MAX);
+ spin->si_memtot += (int)(nodecount + nodecount * sizeof(int));
+
+ // Write the nodes.
+ (void)put_node(fd, tree, 0, regionmask, round == 3);
+ }
+
+ // Write another byte to check for errors (file system full).
+ if (putc(0, fd) == EOF)
+ retval = FAIL;
+theend:
+ if (fclose(fd) == EOF)
+ retval = FAIL;
+
+ if (fwv != (size_t)1)
+ retval = FAIL;
+ if (retval == FAIL)
+ EMSG(_(e_write));
+
+ return retval;
+}
+
+// Clear the index and wnode fields of "node", it siblings and its
+// children. This is needed because they are a union with other items to save
+// space.
+static void clear_node(wordnode_T *node)
+{
+ wordnode_T *np;
+
+ if (node != NULL)
+ for (np = node; np != NULL; np = np->wn_sibling) {
+ np->wn_u1.index = 0;
+ np->wn_u2.wnode = NULL;
+
+ if (np->wn_byte != NUL)
+ clear_node(np->wn_child);
+ }
+}
+
+
+// Dump a word tree at node "node".
+//
+// This first writes the list of possible bytes (siblings). Then for each
+// byte recursively write the children.
+//
+// NOTE: The code here must match the code in read_tree_node(), since
+// assumptions are made about the indexes (so that we don't have to write them
+// in the file).
+//
+// Returns the number of nodes used.
+static int
+put_node (
+ FILE *fd, // NULL when only counting
+ wordnode_T *node,
+ int idx,
+ int regionmask,
+ bool prefixtree // true for PREFIXTREE
+)
+{
+ // If "node" is zero the tree is empty.
+ if (node == NULL)
+ return 0;
+
+ // Store the index where this node is written.
+ node->wn_u1.index = idx;
+
+ // Count the number of siblings.
+ int siblingcount = 0;
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
+ ++siblingcount;
+
+ // Write the sibling count.
+ if (fd != NULL)
+ putc(siblingcount, fd); // <siblingcount>
+
+ // Write each sibling byte and optionally extra info.
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) {
+ if (np->wn_byte == 0) {
+ if (fd != NULL) {
+ // For a NUL byte (end of word) write the flags etc.
+ if (prefixtree) {
+ // In PREFIXTREE write the required affixID and the
+ // associated condition nr (stored in wn_region). The
+ // byte value is misused to store the "rare" and "not
+ // combining" flags
+ if (np->wn_flags == (uint16_t)PFX_FLAGS)
+ putc(BY_NOFLAGS, fd); // <byte>
+ else {
+ putc(BY_FLAGS, fd); // <byte>
+ putc(np->wn_flags, fd); // <pflags>
+ }
+ putc(np->wn_affixID, fd); // <affixID>
+ put_bytes(fd, (uintmax_t)np->wn_region, 2); // <prefcondnr>
+ } else {
+ // For word trees we write the flag/region items.
+ int flags = np->wn_flags;
+ if (regionmask != 0 && np->wn_region != regionmask)
+ flags |= WF_REGION;
+ if (np->wn_affixID != 0)
+ flags |= WF_AFX;
+ if (flags == 0) {
+ // word without flags or region
+ putc(BY_NOFLAGS, fd); // <byte>
+ } else {
+ if (np->wn_flags >= 0x100) {
+ putc(BY_FLAGS2, fd); // <byte>
+ putc(flags, fd); // <flags>
+ putc((int)((unsigned)flags >> 8), fd); // <flags2>
+ } else {
+ putc(BY_FLAGS, fd); // <byte>
+ putc(flags, fd); // <flags>
+ }
+ if (flags & WF_REGION)
+ putc(np->wn_region, fd); // <region>
+ if (flags & WF_AFX)
+ putc(np->wn_affixID, fd); // <affixID>
+ }
+ }
+ }
+ } else {
+ if (np->wn_child->wn_u1.index != 0
+ && np->wn_child->wn_u2.wnode != node) {
+ // The child is written elsewhere, write the reference.
+ if (fd != NULL) {
+ putc(BY_INDEX, fd); // <byte>
+ put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // <nodeidx>
+ }
+ } else if (np->wn_child->wn_u2.wnode == NULL)
+ // We will write the child below and give it an index.
+ np->wn_child->wn_u2.wnode = node;
+
+ if (fd != NULL)
+ if (putc(np->wn_byte, fd) == EOF) { // <byte> or <xbyte>
+ EMSG(_(e_write));
+ return 0;
+ }
+ }
+ }
+
+ // Space used in the array when reading: one for each sibling and one for
+ // the count.
+ int newindex = idx + siblingcount + 1;
+
+ // Recursively dump the children of each sibling.
+ for (wordnode_T *np = node; np != NULL; np = np->wn_sibling)
+ if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node)
+ newindex = put_node(fd, np->wn_child, newindex, regionmask,
+ prefixtree);
+
+ return newindex;
+}
+
+
+// ":mkspell [-ascii] outfile infile ..."
+// ":mkspell [-ascii] addfile"
+void ex_mkspell(exarg_T *eap)
+{
+ int fcount;
+ char_u **fnames;
+ char_u *arg = eap->arg;
+ bool ascii = false;
+
+ if (STRNCMP(arg, "-ascii", 6) == 0) {
+ ascii = true;
+ arg = skipwhite(arg + 6);
+ }
+
+ // Expand all the remaining arguments (e.g., $VIMRUNTIME).
+ if (get_arglist_exp(arg, &fcount, &fnames, false) == OK) {
+ mkspell(fcount, fnames, ascii, eap->forceit, false);
+ FreeWild(fcount, fnames);
+ }
+}
+
+// Create the .sug file.
+// Uses the soundfold info in "spin".
+// Writes the file with the name "wfname", with ".spl" changed to ".sug".
+static void spell_make_sugfile(spellinfo_T *spin, char_u *wfname)
+{
+ char_u *fname = NULL;
+ int len;
+ slang_T *slang;
+ bool free_slang = false;
+
+ // Read back the .spl file that was written. This fills the required
+ // info for soundfolding. This also uses less memory than the
+ // pointer-linked version of the trie. And it avoids having two versions
+ // of the code for the soundfolding stuff.
+ // It might have been done already by spell_reload_one().
+ for (slang = first_lang; slang != NULL; slang = slang->sl_next) {
+ if (path_full_compare(wfname, slang->sl_fname, false) == kEqualFiles) {
+ break;
+ }
+ }
+ if (slang == NULL) {
+ spell_message(spin, (char_u *)_("Reading back spell file..."));
+ slang = spell_load_file(wfname, NULL, NULL, false);
+ if (slang == NULL)
+ return;
+ free_slang = true;
+ }
+
+ // Clear the info in "spin" that is used.
+ spin->si_blocks = NULL;
+ spin->si_blocks_cnt = 0;
+ spin->si_compress_cnt = 0; // will stay at 0 all the time
+ spin->si_free_count = 0;
+ spin->si_first_free = NULL;
+ spin->si_foldwcount = 0;
+
+ // Go through the trie of good words, soundfold each word and add it to
+ // the soundfold trie.
+ spell_message(spin, (char_u *)_("Performing soundfolding..."));
+ if (sug_filltree(spin, slang) == FAIL)
+ goto theend;
+
+ // Create the table which links each soundfold word with a list of the
+ // good words it may come from. Creates buffer "spin->si_spellbuf".
+ // This also removes the wordnr from the NUL byte entries to make
+ // compression possible.
+ if (sug_maketable(spin) == FAIL)
+ goto theend;
+
+ smsg(_("Number of words after soundfolding: %" PRId64),
+ (int64_t)spin->si_spellbuf->b_ml.ml_line_count);
+
+ // Compress the soundfold trie.
+ spell_message(spin, (char_u *)_(msg_compressing));
+ wordtree_compress(spin, spin->si_foldroot);
+
+ // Write the .sug file.
+ // Make the file name by changing ".spl" to ".sug".
+ fname = xmalloc(MAXPATHL);
+ STRLCPY(fname, wfname, MAXPATHL);
+ len = (int)STRLEN(fname);
+ fname[len - 2] = 'u';
+ fname[len - 1] = 'g';
+ sug_write(spin, fname);
+
+theend:
+ xfree(fname);
+ if (free_slang)
+ slang_free(slang);
+ free_blocks(spin->si_blocks);
+ close_spellbuf(spin->si_spellbuf);
+}
+
+// Build the soundfold trie for language "slang".
+static int sug_filltree(spellinfo_T *spin, slang_T *slang)
+{
+ char_u *byts;
+ idx_T *idxs;
+ int depth;
+ idx_T arridx[MAXWLEN];
+ int curi[MAXWLEN];
+ char_u tword[MAXWLEN];
+ char_u tsalword[MAXWLEN];
+ int c;
+ idx_T n;
+ unsigned words_done = 0;
+ int wordcount[MAXWLEN];
+
+ // We use si_foldroot for the soundfolded trie.
+ spin->si_foldroot = wordtree_alloc(spin);
+
+ // Let tree_add_word() know we're adding to the soundfolded tree
+ spin->si_sugtree = true;
+
+ // Go through the whole case-folded tree, soundfold each word and put it
+ // in the trie.
+ byts = slang->sl_fbyts;
+ idxs = slang->sl_fidxs;
+
+ arridx[0] = 0;
+ curi[0] = 1;
+ wordcount[0] = 0;
+
+ depth = 0;
+ while (depth >= 0 && !got_int) {
+ if (curi[depth] > byts[arridx[depth]]) {
+ // Done all bytes at this node, go up one level.
+ idxs[arridx[depth]] = wordcount[depth];
+ if (depth > 0)
+ wordcount[depth - 1] += wordcount[depth];
+
+ --depth;
+ line_breakcheck();
+ } else {
+
+ // Do one more byte at this node.
+ n = arridx[depth] + curi[depth];
+ ++curi[depth];
+
+ c = byts[n];
+ if (c == 0) {
+ // Sound-fold the word.
+ tword[depth] = NUL;
+ spell_soundfold(slang, tword, true, tsalword);
+
+ // We use the "flags" field for the MSB of the wordnr,
+ // "region" for the LSB of the wordnr.
+ if (tree_add_word(spin, tsalword, spin->si_foldroot,
+ words_done >> 16, words_done & 0xffff,
+ 0) == FAIL)
+ return FAIL;
+
+ ++words_done;
+ ++wordcount[depth];
+
+ // Reset the block count each time to avoid compression
+ // kicking in.
+ spin->si_blocks_cnt = 0;
+
+ // Skip over any other NUL bytes (same word with different
+ // flags).
+ while (byts[n + 1] == 0) {
+ ++n;
+ ++curi[depth];
+ }
+ } else {
+ // Normal char, go one level deeper.
+ tword[depth++] = c;
+ arridx[depth] = idxs[n];
+ curi[depth] = 1;
+ wordcount[depth] = 0;
+ }
+ }
+ }
+
+ smsg(_("Total number of words: %d"), words_done);
+
+ return OK;
+}
+
+// Make the table that links each word in the soundfold trie to the words it
+// can be produced from.
+// This is not unlike lines in a file, thus use a memfile to be able to access
+// the table efficiently.
+// Returns FAIL when out of memory.
+static int sug_maketable(spellinfo_T *spin)
+{
+ garray_T ga;
+ int res = OK;
+
+ // Allocate a buffer, open a memline for it and create the swap file
+ // (uses a temp file, not a .swp file).
+ spin->si_spellbuf = open_spellbuf();
+
+ // Use a buffer to store the line info, avoids allocating many small
+ // pieces of memory.
+ ga_init(&ga, 1, 100);
+
+ // recursively go through the tree
+ if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1)
+ res = FAIL;
+
+ ga_clear(&ga);
+ return res;
+}
+
+// Fill the table for one node and its children.
+// Returns the wordnr at the start of the node.
+// Returns -1 when out of memory.
+static int
+sug_filltable (
+ spellinfo_T *spin,
+ wordnode_T *node,
+ int startwordnr,
+ garray_T *gap // place to store line of numbers
+)
+{
+ wordnode_T *p, *np;
+ int wordnr = startwordnr;
+ int nr;
+ int prev_nr;
+
+ for (p = node; p != NULL; p = p->wn_sibling) {
+ if (p->wn_byte == NUL) {
+ gap->ga_len = 0;
+ prev_nr = 0;
+ for (np = p; np != NULL && np->wn_byte == NUL; np = np->wn_sibling) {
+ ga_grow(gap, 10);
+
+ nr = (np->wn_flags << 16) + (np->wn_region & 0xffff);
+ // Compute the offset from the previous nr and store the
+ // offset in a way that it takes a minimum number of bytes.
+ // It's a bit like utf-8, but without the need to mark
+ // following bytes.
+ nr -= prev_nr;
+ prev_nr += nr;
+ gap->ga_len += offset2bytes(nr,
+ (char_u *)gap->ga_data + gap->ga_len);
+ }
+
+ // add the NUL byte
+ ((char_u *)gap->ga_data)[gap->ga_len++] = NUL;
+
+ if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr,
+ gap->ga_data, gap->ga_len, TRUE) == FAIL)
+ return -1;
+ ++wordnr;
+
+ // Remove extra NUL entries, we no longer need them. We don't
+ // bother freeing the nodes, the won't be reused anyway.
+ while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL)
+ p->wn_sibling = p->wn_sibling->wn_sibling;
+
+ // Clear the flags on the remaining NUL node, so that compression
+ // works a lot better.
+ p->wn_flags = 0;
+ p->wn_region = 0;
+ } else {
+ wordnr = sug_filltable(spin, p->wn_child, wordnr, gap);
+ if (wordnr == -1)
+ return -1;
+ }
+ }
+ return wordnr;
+}
+
+// Convert an offset into a minimal number of bytes.
+// Similar to utf_char2byters, but use 8 bits in followup bytes and avoid NUL
+// bytes.
+static int offset2bytes(int nr, char_u *buf)
+{
+ int rem;
+ int b1, b2, b3, b4;
+
+ // Split the number in parts of base 255. We need to avoid NUL bytes.
+ b1 = nr % 255 + 1;
+ rem = nr / 255;
+ b2 = rem % 255 + 1;
+ rem = rem / 255;
+ b3 = rem % 255 + 1;
+ b4 = rem / 255 + 1;
+
+ if (b4 > 1 || b3 > 0x1f) { // 4 bytes
+ buf[0] = 0xe0 + b4;
+ buf[1] = b3;
+ buf[2] = b2;
+ buf[3] = b1;
+ return 4;
+ }
+ if (b3 > 1 || b2 > 0x3f ) { // 3 bytes
+ buf[0] = 0xc0 + b3;
+ buf[1] = b2;
+ buf[2] = b1;
+ return 3;
+ }
+ if (b2 > 1 || b1 > 0x7f ) { // 2 bytes
+ buf[0] = 0x80 + b2;
+ buf[1] = b1;
+ return 2;
+ }
+ // 1 byte
+ buf[0] = b1;
+ return 1;
+}
+
+// Write the .sug file in "fname".
+static void sug_write(spellinfo_T *spin, char_u *fname)
+{
+ // Create the file. Note that an existing file is silently overwritten!
+ FILE *fd = mch_fopen((char *)fname, "w");
+ if (fd == NULL) {
+ EMSG2(_(e_notopen), fname);
+ return;
+ }
+
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Writing suggestion file %s..."), fname);
+ spell_message(spin, IObuff);
+
+ // <SUGHEADER>: <fileID> <versionnr> <timestamp>
+ if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) { // <fileID>
+ EMSG(_(e_write));
+ goto theend;
+ }
+ putc(VIMSUGVERSION, fd); // <versionnr>
+
+ // Write si_sugtime to the file.
+ put_time(fd, spin->si_sugtime); // <timestamp>
+
+ // <SUGWORDTREE>
+ spin->si_memtot = 0;
+ wordnode_T *tree = spin->si_foldroot->wn_sibling;
+
+ // Clear the index and wnode fields in the tree.
+ clear_node(tree);
+
+ // Count the number of nodes. Needed to be able to allocate the
+ // memory when reading the nodes. Also fills in index for shared
+ // nodes.
+ size_t nodecount = (size_t)put_node(NULL, tree, 0, 0, false);
+
+ // number of nodes in 4 bytes
+ put_bytes(fd, nodecount, 4); // <nodecount>
+ assert(nodecount + nodecount * sizeof(int) < INT_MAX);
+ spin->si_memtot += (int)(nodecount + nodecount * sizeof(int));
+
+ // Write the nodes.
+ (void)put_node(fd, tree, 0, 0, false);
+
+ // <SUGTABLE>: <sugwcount> <sugline> ...
+ linenr_T wcount = spin->si_spellbuf->b_ml.ml_line_count;
+ assert(wcount >= 0);
+ put_bytes(fd, (uintmax_t)wcount, 4); // <sugwcount>
+
+ for (linenr_T lnum = 1; lnum <= wcount; ++lnum) {
+ // <sugline>: <sugnr> ... NUL
+ char_u *line = ml_get_buf(spin->si_spellbuf, lnum, FALSE);
+ size_t len = STRLEN(line) + 1;
+ if (fwrite(line, len, 1, fd) == 0) {
+ EMSG(_(e_write));
+ goto theend;
+ }
+ assert((size_t)spin->si_memtot + len <= INT_MAX);
+ spin->si_memtot += (int)len;
+ }
+
+ // Write another byte to check for errors.
+ if (putc(0, fd) == EOF)
+ EMSG(_(e_write));
+
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Estimated runtime memory use: %d bytes"), spin->si_memtot);
+ spell_message(spin, IObuff);
+
+theend:
+ // close the file
+ fclose(fd);
+}
+
+
+// Create a Vim spell file from one or more word lists.
+// "fnames[0]" is the output file name.
+// "fnames[fcount - 1]" is the last input file name.
+// Exception: when "fnames[0]" ends in ".add" it's used as the input file name
+// and ".spl" is appended to make the output file name.
+static void
+mkspell (
+ int fcount,
+ char_u **fnames,
+ bool ascii, // -ascii argument given
+ bool over_write, // overwrite existing output file
+ bool added_word // invoked through "zg"
+)
+{
+ char_u *fname = NULL;
+ char_u *wfname;
+ char_u **innames;
+ int incount;
+ afffile_T *(afile[MAXREGIONS]);
+ int i;
+ int len;
+ bool error = false;
+ spellinfo_T spin;
+
+ memset(&spin, 0, sizeof(spin));
+ spin.si_verbose = !added_word;
+ spin.si_ascii = ascii;
+ spin.si_followup = true;
+ spin.si_rem_accents = true;
+ ga_init(&spin.si_rep, (int)sizeof(fromto_T), 20);
+ ga_init(&spin.si_repsal, (int)sizeof(fromto_T), 20);
+ ga_init(&spin.si_sal, (int)sizeof(fromto_T), 20);
+ ga_init(&spin.si_map, (int)sizeof(char_u), 100);
+ ga_init(&spin.si_comppat, (int)sizeof(char_u *), 20);
+ ga_init(&spin.si_prefcond, (int)sizeof(char_u *), 50);
+ hash_init(&spin.si_commonwords);
+ spin.si_newcompID = 127; // start compound ID at first maximum
+
+ // default: fnames[0] is output file, following are input files
+ innames = &fnames[1];
+ incount = fcount - 1;
+
+ wfname = xmalloc(MAXPATHL);
+
+ if (fcount >= 1) {
+ len = (int)STRLEN(fnames[0]);
+ if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) {
+ // For ":mkspell path/en.latin1.add" output file is
+ // "path/en.latin1.add.spl".
+ innames = &fnames[0];
+ incount = 1;
+ vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]);
+ } else if (fcount == 1) {
+ // For ":mkspell path/vim" output file is "path/vim.latin1.spl".
+ innames = &fnames[0];
+ incount = 1;
+ vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
+ fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+ } else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) {
+ // Name ends in ".spl", use as the file name.
+ STRLCPY(wfname, fnames[0], MAXPATHL);
+ } else
+ // Name should be language, make the file name from it.
+ vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
+ fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+
+ // Check for .ascii.spl.
+ if (strstr((char *)path_tail(wfname), SPL_FNAME_ASCII) != NULL)
+ spin.si_ascii = true;
+
+ // Check for .add.spl.
+ if (strstr((char *)path_tail(wfname), SPL_FNAME_ADD) != NULL)
+ spin.si_add = true;
+ }
+
+ if (incount <= 0) {
+ EMSG(_(e_invarg)); // need at least output and input names
+ } else if (vim_strchr(path_tail(wfname), '_') != NULL) {
+ EMSG(_("E751: Output file name must not have region name"));
+ } else if (incount > MAXREGIONS) {
+ emsgf(_("E754: Only up to %d regions supported"), MAXREGIONS);
+ } else {
+ // Check for overwriting before doing things that may take a lot of
+ // time.
+ if (!over_write && os_path_exists(wfname)) {
+ EMSG(_(e_exists));
+ goto theend;
+ }
+ if (os_isdir(wfname)) {
+ EMSG2(_(e_isadir2), wfname);
+ goto theend;
+ }
+
+ fname = xmalloc(MAXPATHL);
+
+ // Init the aff and dic pointers.
+ // Get the region names if there are more than 2 arguments.
+ for (i = 0; i < incount; ++i) {
+ afile[i] = NULL;
+
+ if (incount > 1) {
+ len = (int)STRLEN(innames[i]);
+ if (STRLEN(path_tail(innames[i])) < 5
+ || innames[i][len - 3] != '_') {
+ EMSG2(_("E755: Invalid region in %s"), innames[i]);
+ goto theend;
+ }
+ spin.si_region_name[i * 2] = TOLOWER_ASC(innames[i][len - 2]);
+ spin.si_region_name[i * 2 + 1] =
+ TOLOWER_ASC(innames[i][len - 1]);
+ }
+ }
+ spin.si_region_count = incount;
+
+ spin.si_foldroot = wordtree_alloc(&spin);
+ spin.si_keeproot = wordtree_alloc(&spin);
+ spin.si_prefroot = wordtree_alloc(&spin);
+
+ // When not producing a .add.spl file clear the character table when
+ // we encounter one in the .aff file. This means we dump the current
+ // one in the .spl file if the .aff file doesn't define one. That's
+ // better than guessing the contents, the table will match a
+ // previously loaded spell file.
+ if (!spin.si_add)
+ spin.si_clear_chartab = true;
+
+ // Read all the .aff and .dic files.
+ // Text is converted to 'encoding'.
+ // Words are stored in the case-folded and keep-case trees.
+ for (i = 0; i < incount && !error; ++i) {
+ spin.si_conv.vc_type = CONV_NONE;
+ spin.si_region = 1 << i;
+
+ vim_snprintf((char *)fname, MAXPATHL, "%s.aff", innames[i]);
+ if (os_path_exists(fname)) {
+ // Read the .aff file. Will init "spin->si_conv" based on the
+ // "SET" line.
+ afile[i] = spell_read_aff(&spin, fname);
+ if (afile[i] == NULL)
+ error = true;
+ else {
+ // Read the .dic file and store the words in the trees.
+ vim_snprintf((char *)fname, MAXPATHL, "%s.dic",
+ innames[i]);
+ if (spell_read_dic(&spin, fname, afile[i]) == FAIL)
+ error = true;
+ }
+ } else {
+ // No .aff file, try reading the file as a word list. Store
+ // the words in the trees.
+ if (spell_read_wordfile(&spin, innames[i]) == FAIL)
+ error = true;
+ }
+
+ // Free any conversion stuff.
+ convert_setup(&spin.si_conv, NULL, NULL);
+ }
+
+ if (spin.si_compflags != NULL && spin.si_nobreak)
+ MSG(_("Warning: both compounding and NOBREAK specified"));
+
+ if (!error && !got_int) {
+ // Combine tails in the tree.
+ spell_message(&spin, (char_u *)_(msg_compressing));
+ wordtree_compress(&spin, spin.si_foldroot);
+ wordtree_compress(&spin, spin.si_keeproot);
+ wordtree_compress(&spin, spin.si_prefroot);
+ }
+
+ if (!error && !got_int) {
+ // Write the info in the spell file.
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Writing spell file %s..."), wfname);
+ spell_message(&spin, IObuff);
+
+ error = write_vim_spell(&spin, wfname) == FAIL;
+
+ spell_message(&spin, (char_u *)_("Done!"));
+ vim_snprintf((char *)IObuff, IOSIZE,
+ _("Estimated runtime memory use: %d bytes"), spin.si_memtot);
+ spell_message(&spin, IObuff);
+
+ // If the file is loaded need to reload it.
+ if (!error)
+ spell_reload_one(wfname, added_word);
+ }
+
+ // Free the allocated memory.
+ ga_clear(&spin.si_rep);
+ ga_clear(&spin.si_repsal);
+ ga_clear(&spin.si_sal);
+ ga_clear(&spin.si_map);
+ ga_clear(&spin.si_comppat);
+ ga_clear(&spin.si_prefcond);
+ hash_clear_all(&spin.si_commonwords, 0);
+
+ // Free the .aff file structures.
+ for (i = 0; i < incount; ++i)
+ if (afile[i] != NULL)
+ spell_free_aff(afile[i]);
+
+ // Free all the bits and pieces at once.
+ free_blocks(spin.si_blocks);
+
+ // If there is soundfolding info and no NOSUGFILE item create the
+ // .sug file with the soundfolded word trie.
+ if (spin.si_sugtime != 0 && !error && !got_int)
+ spell_make_sugfile(&spin, wfname);
+
+ }
+
+theend:
+ xfree(fname);
+ xfree(wfname);
+}
+
+// Display a message for spell file processing when 'verbose' is set or using
+// ":mkspell". "str" can be IObuff.
+static void spell_message(spellinfo_T *spin, char_u *str)
+{
+ if (spin->si_verbose || p_verbose > 2) {
+ if (!spin->si_verbose)
+ verbose_enter();
+ MSG(str);
+ ui_flush();
+ if (!spin->si_verbose)
+ verbose_leave();
+ }
+}
+
+// ":[count]spellgood {word}"
+// ":[count]spellwrong {word}"
+// ":[count]spellundo {word}"
+void ex_spell(exarg_T *eap)
+{
+ spell_add_word(eap->arg, (int)STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong,
+ eap->forceit ? 0 : (int)eap->line2,
+ eap->cmdidx == CMD_spellundo);
+}
+
+// Add "word[len]" to 'spellfile' as a good or bad word.
+void
+spell_add_word (
+ char_u *word,
+ int len,
+ int bad,
+ int idx, // "zG" and "zW": zero, otherwise index in
+ // 'spellfile'
+ bool undo // true for "zug", "zuG", "zuw" and "zuW"
+)
+{
+ FILE *fd = NULL;
+ buf_T *buf = NULL;
+ bool new_spf = false;
+ char_u *fname;
+ char_u *fnamebuf = NULL;
+ char_u line[MAXWLEN * 2];
+ long fpos, fpos_next = 0;
+ int i;
+ char_u *spf;
+
+ if (idx == 0) { // use internal wordlist
+ if (int_wordlist == NULL) {
+ int_wordlist = vim_tempname();
+ if (int_wordlist == NULL)
+ return;
+ }
+ fname = int_wordlist;
+ } else {
+ // If 'spellfile' isn't set figure out a good default value.
+ if (*curwin->w_s->b_p_spf == NUL) {
+ init_spellfile();
+ new_spf = true;
+ }
+
+ if (*curwin->w_s->b_p_spf == NUL) {
+ EMSG2(_(e_notset), "spellfile");
+ return;
+ }
+ fnamebuf = xmalloc(MAXPATHL);
+
+ for (spf = curwin->w_s->b_p_spf, i = 1; *spf != NUL; ++i) {
+ copy_option_part(&spf, fnamebuf, MAXPATHL, ",");
+ if (i == idx)
+ break;
+ if (*spf == NUL) {
+ EMSGN(_("E765: 'spellfile' does not have %" PRId64 " entries"), idx);
+ xfree(fnamebuf);
+ return;
+ }
+ }
+
+ // Check that the user isn't editing the .add file somewhere.
+ buf = buflist_findname_exp(fnamebuf);
+ if (buf != NULL && buf->b_ml.ml_mfp == NULL)
+ buf = NULL;
+ if (buf != NULL && bufIsChanged(buf)) {
+ EMSG(_(e_bufloaded));
+ xfree(fnamebuf);
+ return;
+ }
+
+ fname = fnamebuf;
+ }
+
+ if (bad || undo) {
+ // When the word appears as good word we need to remove that one,
+ // since its flags sort before the one with WF_BANNED.
+ fd = mch_fopen((char *)fname, "r");
+ if (fd != NULL) {
+ while (!vim_fgets(line, MAXWLEN * 2, fd)) {
+ fpos = fpos_next;
+ fpos_next = ftell(fd);
+ if (STRNCMP(word, line, len) == 0
+ && (line[len] == '/' || line[len] < ' ')) {
+ // Found duplicate word. Remove it by writing a '#' at
+ // the start of the line. Mixing reading and writing
+ // doesn't work for all systems, close the file first.
+ fclose(fd);
+ fd = mch_fopen((char *)fname, "r+");
+ if (fd == NULL) {
+ break;
+ }
+ if (fseek(fd, fpos, SEEK_SET) == 0) {
+ fputc('#', fd);
+ if (undo) {
+ home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
+ smsg(_("Word '%.*s' removed from %s"),
+ len, word, NameBuff);
+ }
+ }
+ if (fseek(fd, fpos_next, SEEK_SET) <= 0) {
+ break;
+ }
+ }
+ }
+ if (fd != NULL)
+ fclose(fd);
+ }
+ }
+
+ if (!undo) {
+ fd = mch_fopen((char *)fname, "a");
+ if (fd == NULL && new_spf) {
+ char_u *p;
+
+ // We just initialized the 'spellfile' option and can't open the
+ // file. We may need to create the "spell" directory first. We
+ // already checked the runtime directory is writable in
+ // init_spellfile().
+ if (!dir_of_file_exists(fname) && (p = path_tail_with_sep(fname)) != fname) {
+ int c = *p;
+
+ // The directory doesn't exist. Try creating it and opening
+ // the file again.
+ *p = NUL;
+ os_mkdir((char *)fname, 0755);
+ *p = c;
+ fd = mch_fopen((char *)fname, "a");
+ }
+ }
+
+ if (fd == NULL)
+ EMSG2(_(e_notopen), fname);
+ else {
+ if (bad)
+ fprintf(fd, "%.*s/!\n", len, word);
+ else
+ fprintf(fd, "%.*s\n", len, word);
+ fclose(fd);
+
+ home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
+ smsg(_("Word '%.*s' added to %s"), len, word, NameBuff);
+ }
+ }
+
+ if (fd != NULL) {
+ // Update the .add.spl file.
+ mkspell(1, &fname, false, true, true);
+
+ // If the .add file is edited somewhere, reload it.
+ if (buf != NULL)
+ buf_reload(buf, buf->b_orig_mode);
+
+ redraw_all_later(SOME_VALID);
+ }
+ xfree(fnamebuf);
+}
+
+// Initialize 'spellfile' for the current buffer.
+static void init_spellfile(void)
+{
+ char_u *buf;
+ int l;
+ char_u *fname;
+ char_u *rtp;
+ char_u *lend;
+ bool aspath = false;
+ char_u *lstart = curbuf->b_s.b_p_spl;
+
+ if (*curwin->w_s->b_p_spl != NUL && !GA_EMPTY(&curwin->w_s->b_langp)) {
+ buf = xmalloc(MAXPATHL);
+
+ // Find the end of the language name. Exclude the region. If there
+ // is a path separator remember the start of the tail.
+ for (lend = curwin->w_s->b_p_spl; *lend != NUL
+ && vim_strchr((char_u *)",._", *lend) == NULL; ++lend)
+ if (vim_ispathsep(*lend)) {
+ aspath = true;
+ lstart = lend + 1;
+ }
+
+ // Loop over all entries in 'runtimepath'. Use the first one where we
+ // are allowed to write.
+ rtp = p_rtp;
+ while (*rtp != NUL) {
+ if (aspath)
+ // Use directory of an entry with path, e.g., for
+ // "/dir/lg.utf-8.spl" use "/dir".
+ STRLCPY(buf, curbuf->b_s.b_p_spl,
+ lstart - curbuf->b_s.b_p_spl);
+ else
+ // Copy the path from 'runtimepath' to buf[].
+ copy_option_part(&rtp, buf, MAXPATHL, ",");
+ if (os_file_is_writable((char *)buf) == 2) {
+ // Use the first language name from 'spelllang' and the
+ // encoding used in the first loaded .spl file.
+ if (aspath)
+ STRLCPY(buf, curbuf->b_s.b_p_spl,
+ lend - curbuf->b_s.b_p_spl + 1);
+ else {
+ // Create the "spell" directory if it doesn't exist yet.
+ l = (int)STRLEN(buf);
+ vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell");
+ if (os_file_is_writable((char *)buf) != 2) {
+ os_mkdir((char *)buf, 0755);
+ }
+
+ l = (int)STRLEN(buf);
+ vim_snprintf((char *)buf + l, MAXPATHL - l,
+ "/%.*s", (int)(lend - lstart), lstart);
+ }
+ l = (int)STRLEN(buf);
+ fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
+ ->lp_slang->sl_fname;
+ vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
+ ((fname != NULL
+ && strstr((char *)path_tail(fname), ".ascii.") != NULL)
+ ? "ascii"
+ : (const char *)spell_enc()));
+ set_option_value("spellfile", 0L, (const char *)buf, OPT_LOCAL);
+ break;
+ }
+ aspath = false;
+ }
+
+ xfree(buf);
+ }
+}
+
+// Set the spell character tables from strings in the affix file.
+static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp)
+{
+ // We build the new tables here first, so that we can compare with the
+ // previous one.
+ spelltab_T new_st;
+ char_u *pf = fol, *pl = low, *pu = upp;
+ int f, l, u;
+
+ clear_spell_chartab(&new_st);
+
+ while (*pf != NUL) {
+ if (*pl == NUL || *pu == NUL) {
+ EMSG(_(e_affform));
+ return FAIL;
+ }
+ f = mb_ptr2char_adv((const char_u **)&pf);
+ l = mb_ptr2char_adv((const char_u **)&pl);
+ u = mb_ptr2char_adv((const char_u **)&pu);
+ // Every character that appears is a word character.
+ if (f < 256)
+ new_st.st_isw[f] = true;
+ if (l < 256)
+ new_st.st_isw[l] = true;
+ if (u < 256)
+ new_st.st_isw[u] = true;
+
+ // if "LOW" and "FOL" are not the same the "LOW" char needs
+ // case-folding
+ if (l < 256 && l != f) {
+ if (f >= 256) {
+ EMSG(_(e_affrange));
+ return FAIL;
+ }
+ new_st.st_fold[l] = f;
+ }
+
+ // if "UPP" and "FOL" are not the same the "UPP" char needs
+ // case-folding, it's upper case and the "UPP" is the upper case of
+ // "FOL" .
+ if (u < 256 && u != f) {
+ if (f >= 256) {
+ EMSG(_(e_affrange));
+ return FAIL;
+ }
+ new_st.st_fold[u] = f;
+ new_st.st_isu[u] = true;
+ new_st.st_upper[f] = u;
+ }
+ }
+
+ if (*pl != NUL || *pu != NUL) {
+ EMSG(_(e_affform));
+ return FAIL;
+ }
+
+ return set_spell_finish(&new_st);
+}
+
+// Set the spell character tables from strings in the .spl file.
+static void
+set_spell_charflags (
+ char_u *flags,
+ int cnt, // length of "flags"
+ char_u *fol
+)
+{
+ // We build the new tables here first, so that we can compare with the
+ // previous one.
+ spelltab_T new_st;
+ int i;
+ char_u *p = fol;
+ int c;
+
+ clear_spell_chartab(&new_st);
+
+ for (i = 0; i < 128; ++i) {
+ if (i < cnt) {
+ new_st.st_isw[i + 128] = (flags[i] & CF_WORD) != 0;
+ new_st.st_isu[i + 128] = (flags[i] & CF_UPPER) != 0;
+ }
+
+ if (*p != NUL) {
+ c = mb_ptr2char_adv((const char_u **)&p);
+ new_st.st_fold[i + 128] = c;
+ if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
+ new_st.st_upper[c] = i + 128;
+ }
+ }
+
+ (void)set_spell_finish(&new_st);
+}
+
+static int set_spell_finish(spelltab_T *new_st)
+{
+ int i;
+
+ if (did_set_spelltab) {
+ // check that it's the same table
+ for (i = 0; i < 256; ++i) {
+ if (spelltab.st_isw[i] != new_st->st_isw[i]
+ || spelltab.st_isu[i] != new_st->st_isu[i]
+ || spelltab.st_fold[i] != new_st->st_fold[i]
+ || spelltab.st_upper[i] != new_st->st_upper[i]) {
+ EMSG(_("E763: Word characters differ between spell files"));
+ return FAIL;
+ }
+ }
+ } else {
+ // copy the new spelltab into the one being used
+ spelltab = *new_st;
+ did_set_spelltab = true;
+ }
+
+ return OK;
+}
+
+// Write the table with prefix conditions to the .spl file.
+// When "fd" is NULL only count the length of what is written.
+static int write_spell_prefcond(FILE *fd, garray_T *gap)
+{
+ assert(gap->ga_len >= 0);
+
+ if (fd != NULL)
+ put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <prefcondcnt>
+
+ size_t totlen = 2 + (size_t)gap->ga_len; // <prefcondcnt> and <condlen> bytes
+ size_t x = 1; // collect return value of fwrite()
+ for (int i = 0; i < gap->ga_len; ++i) {
+ // <prefcond> : <condlen> <condstr>
+ char_u *p = ((char_u **)gap->ga_data)[i];
+ if (p != NULL) {
+ size_t len = STRLEN(p);
+ if (fd != NULL) {
+ assert(len <= INT_MAX);
+ fputc((int)len, fd);
+ x &= fwrite(p, len, 1, fd);
+ }
+ totlen += len;
+ } else if (fd != NULL)
+ fputc(0, fd);
+ }
+
+ assert(totlen <= INT_MAX);
+ return (int)totlen;
+}
+
+// Use map string "map" for languages "lp".
+static void set_map_str(slang_T *lp, char_u *map)
+{
+ char_u *p;
+ int headc = 0;
+ int c;
+ int i;
+
+ if (*map == NUL) {
+ lp->sl_has_map = false;
+ return;
+ }
+ lp->sl_has_map = true;
+
+ // Init the array and hash tables empty.
+ for (i = 0; i < 256; ++i)
+ lp->sl_map_array[i] = 0;
+ hash_init(&lp->sl_map_hash);
+
+ // The similar characters are stored separated with slashes:
+ // "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and
+ // before the same slash. For characters above 255 sl_map_hash is used.
+ for (p = map; *p != NUL; ) {
+ c = mb_cptr2char_adv((const char_u **)&p);
+ if (c == '/') {
+ headc = 0;
+ } else {
+ if (headc == 0) {
+ headc = c;
+ }
+
+ // Characters above 255 don't fit in sl_map_array[], put them in
+ // the hash table. Each entry is the char, a NUL the headchar and
+ // a NUL.
+ if (c >= 256) {
+ int cl = mb_char2len(c);
+ int headcl = mb_char2len(headc);
+ char_u *b;
+ hash_T hash;
+ hashitem_T *hi;
+
+ b = xmalloc(cl + headcl + 2);
+ utf_char2bytes(c, b);
+ b[cl] = NUL;
+ utf_char2bytes(headc, b + cl + 1);
+ b[cl + 1 + headcl] = NUL;
+ hash = hash_hash(b);
+ hi = hash_lookup(&lp->sl_map_hash, (const char *)b, STRLEN(b), hash);
+ if (HASHITEM_EMPTY(hi)) {
+ hash_add_item(&lp->sl_map_hash, hi, b, hash);
+ } else {
+ // This should have been checked when generating the .spl
+ // file.
+ EMSG(_("E783: duplicate char in MAP entry"));
+ xfree(b);
+ }
+ } else
+ lp->sl_map_array[c] = headc;
+ }
+ }
+}
+
diff --git a/src/nvim/spellfile.h b/src/nvim/spellfile.h
new file mode 100644
index 0000000000..633ee014a7
--- /dev/null
+++ b/src/nvim/spellfile.h
@@ -0,0 +1,13 @@
+#ifndef NVIM_SPELLFILE_H
+#define NVIM_SPELLFILE_H
+
+#include <stdbool.h>
+
+#include "nvim/spell_defs.h"
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "spellfile.h.generated.h"
+#endif
+#endif // NVIM_SPELLFILE_H
diff --git a/src/nvim/state.c b/src/nvim/state.c
index 30133e2201..bfd73050c3 100644
--- a/src/nvim/state.c
+++ b/src/nvim/state.c
@@ -1,13 +1,21 @@
+// 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 "nvim/lib/kvec.h"
+#include "nvim/ascii.h"
+#include "nvim/log.h"
#include "nvim/state.h"
#include "nvim/vim.h"
#include "nvim/main.h"
#include "nvim/getchar.h"
+#include "nvim/option_defs.h"
#include "nvim/ui.h"
#include "nvim/os/input.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/edit.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "state.c.generated.h"
@@ -20,10 +28,11 @@ void state_enter(VimState *s)
int check_result = s->check ? s->check(s) : 1;
if (!check_result) {
- break;
+ break; // Terminate this state.
} else if (check_result == -1) {
- continue;
+ continue; // check() again.
}
+ // Execute this state.
int key;
@@ -33,8 +42,8 @@ getkey:
// processing. Characters can come from mappings, scripts and other
// sources, so this scenario is very common.
key = safe_vgetc();
- } else if (!queue_empty(main_loop.events)) {
- // Event was made available after the last queue_process_events call
+ } else if (!multiqueue_empty(main_loop.events)) {
+ // Event was made available after the last multiqueue_process_events call
key = K_EVENT;
} else {
input_enable_events();
@@ -42,17 +51,25 @@ getkey:
ui_flush();
// Call `os_inchar` directly to block for events or user input without
// consuming anything from `input_buffer`(os/input.c) or calling the
- // mapping engine. If an event was put into the queue, we send K_EVENT
- // directly.
+ // mapping engine.
(void)os_inchar(NULL, 0, -1, 0);
input_disable_events();
- key = !queue_empty(main_loop.events) ? K_EVENT : safe_vgetc();
+ // If an event was put into the queue, we send K_EVENT directly.
+ key = !multiqueue_empty(main_loop.events)
+ ? K_EVENT
+ : safe_vgetc();
}
if (key == K_EVENT) {
may_sync_undo();
}
+#if MIN_LOG_LEVEL <= DEBUG_LOG_LEVEL
+ char *keyname = key == K_EVENT
+ ? "K_EVENT" : (char *)get_special_key_name(key, mod_mask);
+ DLOG("input: %s", keyname);
+#endif
+
int execute_result = s->execute(s, key);
if (!execute_result) {
break;
@@ -61,3 +78,92 @@ getkey:
}
}
}
+
+/// Return true if in the current mode we need to use virtual.
+bool virtual_active(void)
+{
+ // While an operator is being executed we return "virtual_op", because
+ // VIsual_active has already been reset, thus we can't check for "block"
+ // being used.
+ if (virtual_op != kNone) {
+ return virtual_op;
+ }
+ return ve_flags == VE_ALL
+ || ((ve_flags & VE_BLOCK) && VIsual_active && VIsual_mode == Ctrl_V)
+ || ((ve_flags & VE_INSERT) && (State & INSERT));
+}
+
+/// VISUAL, SELECTMODE and OP_PENDING State are never set, they are equal to
+/// NORMAL State with a condition. This function returns the real State.
+int get_real_state(void)
+{
+ if (State & NORMAL) {
+ if (VIsual_active) {
+ if (VIsual_select) {
+ return SELECTMODE;
+ }
+ return VISUAL;
+ } else if (finish_op) {
+ return OP_PENDING;
+ }
+ }
+ return State;
+}
+
+/// @returns[allocated] mode string
+char *get_mode(void)
+{
+ char *buf = xcalloc(4, sizeof(char));
+
+ if (VIsual_active) {
+ if (VIsual_select) {
+ buf[0] = (char)(VIsual_mode + 's' - 'v');
+ } else {
+ buf[0] = (char)VIsual_mode;
+ }
+ } else if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
+ || State == CONFIRM) {
+ buf[0] = 'r';
+ if (State == ASKMORE) {
+ buf[1] = 'm';
+ } else if (State == CONFIRM) {
+ buf[1] = '?';
+ }
+ } else if (State == EXTERNCMD) {
+ buf[0] = '!';
+ } else if (State & INSERT) {
+ if (State & VREPLACE_FLAG) {
+ buf[0] = 'R';
+ buf[1] = 'v';
+ } else {
+ if (State & REPLACE_FLAG) {
+ buf[0] = 'R';
+ } else {
+ buf[0] = 'i';
+ }
+ if (ins_compl_active()) {
+ buf[1] = 'c';
+ } else if (ctrl_x_mode == 1) {
+ buf[1] = 'x';
+ }
+ }
+ } else if ((State & CMDLINE) || exmode_active) {
+ buf[0] = 'c';
+ if (exmode_active == EXMODE_VIM) {
+ buf[1] = 'v';
+ } else if (exmode_active == EXMODE_NORMAL) {
+ buf[1] = 'e';
+ }
+ } else if (State & TERM_FOCUS) {
+ buf[0] = 't';
+ } else {
+ buf[0] = 'n';
+ if (finish_op) {
+ buf[1] = 'o';
+ // to be able to detect force-linewise/blockwise/characterwise operations
+ buf[2] = (char)motion_force;
+ }
+ }
+
+ return buf;
+}
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 37a0fb82da..4921824316 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -1,11 +1,17 @@
+// 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 <inttypes.h>
+#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
+#include <math.h>
+#include <assert.h>
+#include "nvim/assert.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/strings.h"
-#include "nvim/misc2.h"
#include "nvim/file_search.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
@@ -42,6 +48,14 @@
#include "nvim/window.h"
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
+#include "nvim/eval/encode.h"
+
+#ifdef __MINGW32__
+# undef fpclassify
+# define fpclassify __fpclassify
+# undef isnan
+# define isnan _isnan
+#endif
/*
* Copy "string" into newly allocated memory.
@@ -52,15 +66,14 @@ char_u *vim_strsave(const char_u *string)
return (char_u *)xstrdup((char *)string);
}
-/*
- * Copy up to "len" bytes of "string" into newly allocated memory and
- * terminate with a NUL.
- * The allocated memory always has size "len + 1", also when "string" is
- * shorter.
- */
+/// Copy up to `len` bytes of `string` into newly allocated memory and
+/// terminate with a NUL. The allocated memory always has size `len + 1`, even
+/// when `string` is shorter.
char_u *vim_strnsave(const char_u *string, size_t len)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
+ // strncpy is intentional: some parts of Vim use `string` shorter than `len`
+ // and expect the remainder to be zeroed out.
return (char_u *)strncpy(xmallocz(len), (char *)string, len);
}
@@ -194,9 +207,17 @@ char_u *vim_strsave_shellescape(const char_u *string,
/* First count the number of extra bytes required. */
size_t length = STRLEN(string) + 3; // two quotes and a trailing NUL
- for (const char_u *p = string; *p != NUL; mb_ptr_adv(p)) {
- if (*p == '\'')
- length += 3; /* ' => '\'' */
+ for (const char_u *p = string; *p != NUL; MB_PTR_ADV(p)) {
+#ifdef WIN32
+ if (!p_ssl) {
+ if (*p == '"') {
+ length++; // " -> ""
+ }
+ } else
+#endif
+ if (*p == '\'') {
+ length += 3; // ' => '\''
+ }
if ((*p == '\n' && (csh_like || do_newline))
|| (*p == '!' && (csh_like || do_special))) {
++length; /* insert backslash */
@@ -213,10 +234,25 @@ char_u *vim_strsave_shellescape(const char_u *string,
escaped_string = xmalloc(length);
d = escaped_string;
- /* add opening quote */
+ // add opening quote
+#ifdef WIN32
+ if (!p_ssl) {
+ *d++ = '"';
+ } else
+#endif
*d++ = '\'';
for (const char_u *p = string; *p != NUL; ) {
+#ifdef WIN32
+ if (!p_ssl) {
+ if (*p == '"') {
+ *d++ = '"';
+ *d++ = '"';
+ p++;
+ continue;
+ }
+ } else
+#endif
if (*p == '\'') {
*d++ = '\'';
*d++ = '\\';
@@ -243,7 +279,12 @@ char_u *vim_strsave_shellescape(const char_u *string,
MB_COPY_CHAR(p, d);
}
- /* add terminating quote and finish with a NUL */
+ // add terminating quote and finish with a NUL
+# ifdef WIN32
+ if (!p_ssl) {
+ *d++ = '"';
+ } else
+# endif
*d++ = '\'';
*d = NUL;
@@ -288,45 +329,45 @@ void vim_strup(char_u *p)
}
}
-/*
- * Make string "s" all upper-case and return it in allocated memory.
- * Handles multi-byte characters as well as possible.
- */
-char_u *strup_save(const char_u *orig)
+/// Make given string all upper-case or all lower-case
+///
+/// Handles multi-byte characters as good as possible.
+///
+/// @param[in] orig Input string.
+/// @param[in] upper If true make uppercase, otherwise lowercase
+///
+/// @return [allocated] upper-cased string.
+char *strcase_save(const char *const orig, bool upper)
FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
{
- char_u *res = vim_strsave(orig);
+ char *res = xstrdup(orig);
- char_u *p = res;
+ char *p = res;
while (*p != NUL) {
- int l;
-
- if (enc_utf8) {
- int c = utf_ptr2char(p);
- int uc = utf_toupper(c);
-
- /* Reallocate string when byte count changes. This is rare,
- * thus it's OK to do another malloc()/free(). */
- l = utf_ptr2len(p);
- int newl = utf_char2len(uc);
- if (newl != l) {
- // TODO(philix): use xrealloc() in strup_save()
- char_u *s = xmalloc(STRLEN(res) + (size_t)(1 + newl - l));
- memcpy(s, res, (size_t)(p - res));
- STRCPY(s + (p - res) + newl, p + l);
- p = s + (p - res);
- xfree(res);
- res = s;
- }
+ int c = utf_ptr2char((const char_u *)p);
+ int l = utf_ptr2len((const char_u *)p);
+ if (c == 0) {
+ // overlong sequence, use only the first byte
+ c = *p;
+ l = 1;
+ }
+ int uc = upper ? mb_toupper(c) : mb_tolower(c);
- utf_char2bytes(uc, p);
- p += newl;
- } else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
- p += l; /* skip multi-byte character */
- else {
- *p = (char_u) TOUPPER_LOC(*p); // note that toupper() can be a macro
- p++;
+ // Reallocate string when byte count changes. This is rare,
+ // thus it's OK to do another malloc()/free().
+ int newl = utf_char2len(uc);
+ if (newl != l) {
+ // TODO(philix): use xrealloc() in strup_save()
+ char *s = xmalloc(STRLEN(res) + (size_t)(1 + newl - l));
+ memcpy(s, res, (size_t)(p - res));
+ STRCPY(s + (p - res) + newl, p + l);
+ p = s + (p - res);
+ xfree(res);
+ res = s;
}
+
+ utf_char2bytes(uc, (char_u *)p);
+ p += newl;
}
return res;
@@ -345,24 +386,6 @@ void del_trailing_spaces(char_u *ptr)
*q = NUL;
}
-/*
- * Like strcat(), but make sure the result fits in "tosize" bytes and is
- * always NUL terminated.
- */
-void vim_strcat(char_u *restrict to, const char_u *restrict from,
- size_t tosize)
- FUNC_ATTR_NONNULL_ALL
-{
- size_t tolen = STRLEN(to);
- size_t fromlen = STRLEN(from);
-
- if (tolen + fromlen + 1 > tosize) {
- memcpy(to + tolen, from, tosize - tolen - 1);
- to[tosize - 1] = NUL;
- } else
- STRCPY(to + tolen, from);
-}
-
#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP))
/*
* Compare two strings, ignoring case, using current locale.
@@ -412,91 +435,27 @@ int vim_strnicmp(const char *s1, const char *s2, size_t len)
}
#endif
-/*
- * Version of strchr() and strrchr() that handle unsigned char strings
- * with characters from 128 to 255 correctly. It also doesn't return a
- * pointer to the NUL at the end of the string.
- */
-char_u *vim_strchr(const char_u *string, int c)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
+/// strchr() version which handles multibyte strings
+///
+/// @param[in] string String to search in.
+/// @param[in] c Character to search for.
+///
+/// @return Pointer to the first byte of the found character in string or NULL
+/// if it was not found or character is invalid. NUL character is never
+/// found, use `strlen()` instead.
+char_u *vim_strchr(const char_u *const string, const int c)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- int b;
-
- const char_u *p = string;
- if (enc_utf8 && c >= 0x80) {
- while (*p != NUL) {
- int l = (*mb_ptr2len)(p);
-
- // Avoid matching an illegal byte here.
- if (l > 1 && utf_ptr2char(p) == c) {
- return (char_u *) p;
- }
- p += l;
- }
- return NULL;
- }
- if (enc_dbcs != 0 && c > 255) {
- int n2 = c & 0xff;
-
- c = ((unsigned)c >> 8) & 0xff;
- while ((b = *p) != NUL) {
- if (b == c && p[1] == n2)
- return (char_u *) p;
- p += (*mb_ptr2len)(p);
- }
- return NULL;
- }
- if (has_mbyte) {
- while ((b = *p) != NUL) {
- if (b == c)
- return (char_u *) p;
- p += (*mb_ptr2len)(p);
- }
+ if (c <= 0) {
return NULL;
+ } else if (c < 0x80) {
+ return (char_u *)strchr((const char *)string, c);
+ } else {
+ char u8char[MB_MAXBYTES + 1];
+ const int len = utf_char2bytes(c, (char_u *)u8char);
+ u8char[len] = NUL;
+ return (char_u *)strstr((const char *)string, u8char);
}
- while ((b = *p) != NUL) {
- if (b == c)
- return (char_u *) p;
- ++p;
- }
- return NULL;
-}
-
-/*
- * Version of strchr() that only works for bytes and handles unsigned char
- * strings with characters above 128 correctly. It also doesn't return a
- * pointer to the NUL at the end of the string.
- */
-char_u *vim_strbyte(const char_u *string, int c)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
-{
- const char_u *p = string;
-
- while (*p != NUL) {
- if (*p == c)
- return (char_u *) p;
- ++p;
- }
- return NULL;
-}
-
-/*
- * Search for last occurrence of "c" in "string".
- * Return NULL if not found.
- * Does not handle multi-byte char for "c"!
- */
-char_u *vim_strrchr(const char_u *string, int c)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
-{
- const char_u *retval = NULL;
- const char_u *p = string;
-
- while (*p) {
- if (*p == c)
- retval = p;
- mb_ptr_adv(p);
- }
- return (char_u *) retval;
}
/*
@@ -561,3 +520,913 @@ char_u *concat_str(const char_u *restrict str1, const char_u *restrict str2)
return dest;
}
+
+static const char *const e_printf =
+ N_("E766: Insufficient arguments for printf()");
+
+/// Get number argument from idxp entry in tvs
+///
+/// Will give an error message for VimL entry with invalid type or for
+/// insufficient entries.
+///
+/// @param[in] tvs List of VimL values. List is terminated by VAR_UNKNOWN
+/// value.
+/// @param[in,out] idxp Index in a list. Will be incremented. Indexing starts
+/// at 1.
+///
+/// @return Number value or 0 in case of error.
+static varnumber_T tv_nr(typval_T *tvs, int *idxp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int idx = *idxp - 1;
+ varnumber_T n = 0;
+
+ if (tvs[idx].v_type == VAR_UNKNOWN) {
+ EMSG(_(e_printf));
+ } else {
+ (*idxp)++;
+ bool err = false;
+ n = tv_get_number_chk(&tvs[idx], &err);
+ if (err) {
+ n = 0;
+ }
+ }
+ return n;
+}
+
+/// Get string argument from idxp entry in tvs
+///
+/// Will give an error message for VimL entry with invalid type or for
+/// insufficient entries.
+///
+/// @param[in] tvs List of VimL values. List is terminated by VAR_UNKNOWN
+/// value.
+/// @param[in,out] idxp Index in a list. Will be incremented.
+/// @param[out] tofree If the idxp entry in tvs is not a String or a Number,
+/// it will be converted to String in the same format
+/// as ":echo" and stored in "*tofree". The caller must
+/// free "*tofree".
+///
+/// @return String value or NULL in case of error.
+static const char *tv_str(typval_T *tvs, int *idxp, char **const tofree)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int idx = *idxp - 1;
+ const char *s = NULL;
+
+ if (tvs[idx].v_type == VAR_UNKNOWN) {
+ EMSG(_(e_printf));
+ } else {
+ (*idxp)++;
+ if (tvs[idx].v_type == VAR_STRING || tvs[idx].v_type == VAR_NUMBER) {
+ s = tv_get_string_chk(&tvs[idx]);
+ *tofree = NULL;
+ } else {
+ s = *tofree = encode_tv2echo(&tvs[idx], NULL);
+ }
+ }
+ return s;
+}
+
+/// Get pointer argument from the next entry in tvs
+///
+/// Will give an error message for VimL entry with invalid type or for
+/// insufficient entries.
+///
+/// @param[in] tvs List of typval_T values.
+/// @param[in,out] idxp Pointer to the index of the current value.
+///
+/// @return Pointer stored in typval_T or NULL.
+static const void *tv_ptr(const typval_T *const tvs, int *const idxp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+#define OFF(attr) offsetof(union typval_vval_union, attr)
+ STATIC_ASSERT(
+ OFF(v_string) == OFF(v_list)
+ && OFF(v_string) == OFF(v_dict)
+ && OFF(v_string) == OFF(v_partial)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_dict)
+ && sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_partial),
+ "Strings, dictionaries, lists and partials are expected to be pointers, "
+ "so that all three of them can be accessed via v_string");
+#undef OFF
+ const int idx = *idxp - 1;
+ if (tvs[idx].v_type == VAR_UNKNOWN) {
+ EMSG(_(e_printf));
+ return NULL;
+ } else {
+ (*idxp)++;
+ return tvs[idx].vval.v_string;
+ }
+}
+
+/// Get float argument from idxp entry in tvs
+///
+/// Will give an error message for VimL entry with invalid type or for
+/// insufficient entries.
+///
+/// @param[in] tvs List of VimL values. List is terminated by VAR_UNKNOWN
+/// value.
+/// @param[in,out] idxp Index in a list. Will be incremented.
+///
+/// @return Floating-point value or zero in case of error.
+static float_T tv_float(typval_T *const tvs, int *const idxp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ int idx = *idxp - 1;
+ float_T f = 0;
+
+ if (tvs[idx].v_type == VAR_UNKNOWN) {
+ EMSG(_(e_printf));
+ } else {
+ (*idxp)++;
+ if (tvs[idx].v_type == VAR_FLOAT) {
+ f = tvs[idx].vval.v_float;
+ } else if (tvs[idx].v_type == VAR_NUMBER) {
+ f = (float_T)tvs[idx].vval.v_number;
+ } else {
+ EMSG(_("E807: Expected Float argument for printf()"));
+ }
+ }
+ return f;
+}
+
+// This code was included to provide a portable vsnprintf() and snprintf().
+// Some systems may provide their own, but we always use this one for
+// consistency.
+//
+// This code is based on snprintf.c - a portable implementation of snprintf
+// by Mark Martinec <mark.martinec@ijs.si>, Version 2.2, 2000-10-06.
+// Included with permission. It was heavily modified to fit in Vim.
+// The original code, including useful comments, can be found here:
+//
+// http://www.ijs.si/software/snprintf/
+//
+// This snprintf() only supports the following conversion specifiers:
+// s, c, b, B, d, u, o, x, X, p (and synonyms: i, D, U, O - see below)
+// with flags: '-', '+', ' ', '0' and '#'.
+// An asterisk is supported for field width as well as precision.
+//
+// Limited support for floating point was added: 'f', 'e', 'E', 'g', 'G'.
+//
+// Length modifiers 'h' (short int), 'l' (long int) and "ll" (long long int) are
+// supported.
+//
+// The locale is not used, the string is used as a byte string. This is only
+// relevant for double-byte encodings where the second byte may be '%'.
+//
+// It is permitted for "str_m" to be zero, and it is permitted to specify NULL
+// pointer for resulting string argument if "str_m" is zero (as per ISO C99).
+//
+// The return value is the number of characters which would be generated
+// for the given input, excluding the trailing NUL. If this value
+// is greater or equal to "str_m", not all characters from the result
+// have been stored in str, output bytes beyond the ("str_m"-1) -th character
+// are discarded. If "str_m" is greater than zero it is guaranteed
+// the resulting string will be NUL-terminated.
+
+// vim_vsnprintf() can be invoked with either "va_list" or a list of
+// "typval_T". When the latter is not used it must be NULL.
+
+/// Append a formatted value to the string
+///
+/// @see vim_vsnprintf().
+int vim_snprintf_add(char *str, size_t str_m, char *fmt, ...)
+ FUNC_ATTR_PRINTF(3, 4)
+{
+ const size_t len = strlen(str);
+ size_t space;
+
+ if (str_m <= len) {
+ space = 0;
+ } else {
+ space = str_m - len;
+ }
+ va_list ap;
+ va_start(ap, fmt);
+ const int str_l = vim_vsnprintf(str + len, space, fmt, ap, NULL);
+ va_end(ap);
+ return str_l;
+}
+
+/// Write formatted value to the string
+///
+/// @param[out] str String to write to.
+/// @param[in] str_m String length.
+/// @param[in] fmt String format.
+///
+/// @return Number of bytes excluding NUL byte that would be written to the
+/// string if str_m was greater or equal to the return value.
+int vim_snprintf(char *str, size_t str_m, const char *fmt, ...)
+ FUNC_ATTR_PRINTF(3, 4)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ const int str_l = vim_vsnprintf(str, str_m, fmt, ap, NULL);
+ va_end(ap);
+ return str_l;
+}
+
+// Return the representation of infinity for printf() function:
+// "-inf", "inf", "+inf", " inf", "-INF", "INF", "+INF" or " INF".
+static const char *infinity_str(bool positive, char fmt_spec,
+ int force_sign, int space_for_positive)
+{
+ static const char *table[] = {
+ "-inf", "inf", "+inf", " inf",
+ "-INF", "INF", "+INF", " INF"
+ };
+ int idx = positive * (1 + force_sign + force_sign * space_for_positive);
+ if (ASCII_ISUPPER(fmt_spec)) {
+ idx += 4;
+ }
+ return table[idx];
+}
+
+
+/// Write formatted value to the string
+///
+/// @param[out] str String to write to.
+/// @param[in] str_m String length.
+/// @param[in] fmt String format.
+/// @param[in] ap Values that should be formatted. Ignored if tvs is not NULL.
+/// @param[in] tvs Values that should be formatted, for printf() VimL
+/// function. Must be NULL in other cases.
+///
+/// @return Number of bytes excluding NUL byte that would be written to the
+/// string if str_m was greater or equal to the return value.
+int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap,
+ typval_T *const tvs)
+{
+ size_t str_l = 0;
+ bool str_avail = str_l < str_m;
+ const char *p = fmt;
+ int arg_idx = 1;
+
+ if (!p) {
+ p = "";
+ }
+ while (*p) {
+ if (*p != '%') {
+ // copy up to the next '%' or NUL without any changes
+ size_t n = (size_t)(xstrchrnul(p + 1, '%') - p);
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memmove(str + str_l, p, MIN(n, avail));
+ str_avail = n < avail;
+ }
+ p += n;
+ assert(n <= SIZE_MAX - str_l);
+ str_l += n;
+ } else {
+ size_t min_field_width = 0, precision = 0;
+ int zero_padding = 0, precision_specified = 0, justify_left = 0;
+ int alternate_form = 0, force_sign = 0;
+
+ // if both ' ' and '+' flags appear, ' ' flag should be ignored
+ int space_for_positive = 1;
+
+ // allowed values: \0, h, l, 2 (for ll), z, L
+ char length_modifier = '\0';
+
+ // temporary buffer for simple numeric->string conversion
+# define TMP_LEN 350 // 1e308 seems reasonable as the maximum printable
+ char tmp[TMP_LEN];
+
+ // string address in case of string argument
+ const char *str_arg = NULL;
+
+ // natural field width of arg without padding and sign
+ size_t str_arg_l;
+
+ // unsigned char argument value (only defined for c conversion);
+ // standard explicitly states the char argument for the c
+ // conversion is unsigned
+ unsigned char uchar_arg;
+
+ // number of zeros to be inserted for numeric conversions as
+ // required by the precision or minimal field width
+ size_t number_of_zeros_to_pad = 0;
+
+ // index into tmp where zero padding is to be inserted
+ size_t zero_padding_insertion_ind = 0;
+
+ // current conversion specifier character
+ char fmt_spec = '\0';
+
+ // buffer for 's' and 'S' specs
+ char *tofree = NULL;
+
+ p++; // skip '%'
+
+ // parse flags
+ while (true) {
+ switch (*p) {
+ case '0': zero_padding = 1; p++; continue;
+ case '-': justify_left = 1; p++; continue;
+ // if both '0' and '-' flags appear, '0' should be ignored
+ case '+': force_sign = 1; space_for_positive = 0; p++; continue;
+ case ' ': force_sign = 1; p++; continue;
+ // if both ' ' and '+' flags appear, ' ' should be ignored
+ case '#': alternate_form = 1; p++; continue;
+ case '\'': p++; continue;
+ default: break;
+ }
+ break;
+ }
+
+ // parse field width
+ if (*p == '*') {
+ p++;
+ const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int);
+ if (j >= 0) {
+ min_field_width = (size_t)j;
+ } else {
+ min_field_width = (size_t)-j;
+ justify_left = 1;
+ }
+ } else if (ascii_isdigit((int)(*p))) {
+ // size_t could be wider than unsigned int; make sure we treat
+ // argument like common implementations do
+ unsigned int uj = (unsigned)(*p++ - '0');
+
+ while (ascii_isdigit((int)(*p))) {
+ uj = 10 * uj + (unsigned int)(*p++ - '0');
+ }
+ min_field_width = uj;
+ }
+
+ // parse precision
+ if (*p == '.') {
+ p++;
+ precision_specified = 1;
+ if (*p == '*') {
+ const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int);
+ p++;
+ if (j >= 0) {
+ precision = (size_t)j;
+ } else {
+ precision_specified = 0;
+ precision = 0;
+ }
+ } else if (ascii_isdigit((int)(*p))) {
+ // size_t could be wider than unsigned int; make sure we
+ // treat argument like common implementations do
+ unsigned int uj = (unsigned)(*p++ - '0');
+
+ while (ascii_isdigit((int)(*p))) {
+ uj = 10 * uj + (unsigned int)(*p++ - '0');
+ }
+ precision = uj;
+ }
+ }
+
+ // parse 'h', 'l', 'll' and 'z' length modifiers
+ if (*p == 'h' || *p == 'l' || *p == 'z') {
+ length_modifier = *p;
+ p++;
+ if (length_modifier == 'l' && *p == 'l') { // ll, encoded as 2
+ length_modifier = '2';
+ p++;
+ }
+ }
+
+ fmt_spec = *p;
+
+ // common synonyms
+ switch (fmt_spec) {
+ case 'i': fmt_spec = 'd'; break;
+ case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;
+ case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;
+ case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;
+ default: break;
+ }
+
+ switch (fmt_spec) {
+ case 'd': case 'u': case 'o': case 'x': case 'X':
+ if (tvs && length_modifier == '\0') {
+ length_modifier = '2';
+ }
+ }
+
+ // get parameter value, do initial processing
+ switch (fmt_spec) {
+ // '%' and 'c' behave similar to 's' regarding flags and field widths
+ case '%': case 'c': case 's': case 'S':
+ str_arg_l = 1;
+ switch (fmt_spec) {
+ case '%':
+ str_arg = p;
+ break;
+
+ case 'c': {
+ const int j = tvs ? (int)tv_nr(tvs, &arg_idx) : va_arg(ap, int);
+ // standard demands unsigned char
+ uchar_arg = (unsigned char)j;
+ str_arg = (char *)&uchar_arg;
+ break;
+ }
+
+ case 's':
+ case 'S':
+ str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree)
+ : va_arg(ap, const char *);
+ if (!str_arg) {
+ str_arg = "[NULL]";
+ str_arg_l = 6;
+ } else if (!precision_specified) {
+ // make sure not to address string beyond the specified
+ // precision
+ str_arg_l = strlen(str_arg);
+ } else if (precision == 0) {
+ // truncate string if necessary as requested by precision
+ str_arg_l = 0;
+ } else {
+ // memchr on HP does not like n > 2^31
+ // TODO(elmart): check if this still holds / is relevant
+ str_arg_l = (size_t)((char *)xmemscan(str_arg,
+ NUL,
+ MIN(precision,
+ 0x7fffffff))
+ - str_arg);
+ }
+ if (fmt_spec == 'S') {
+ if (min_field_width != 0) {
+ min_field_width += (strlen(str_arg)
+ - mb_string2cells((char_u *)str_arg));
+ }
+ if (precision) {
+ const char *p1 = str_arg;
+ for (size_t i = 0; i < precision && *p1; i++) {
+ p1 += mb_ptr2len((const char_u *)p1);
+ }
+ str_arg_l = precision = (size_t)(p1 - str_arg);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case 'd':
+ case 'u':
+ case 'b': case 'B':
+ case 'o':
+ case 'x': case 'X':
+ case 'p': {
+ // u, b, B, o, x, X and p conversion specifiers imply
+ // the value is unsigned; d implies a signed value
+
+ // 0 if numeric argument is zero (or if pointer is NULL for 'p'),
+ // +1 if greater than zero (or non NULL for 'p'),
+ // -1 if negative (unsigned argument is never negative)
+ int arg_sign = 0;
+
+ intmax_t arg = 0;
+ uintmax_t uarg = 0;
+
+ // only defined for p conversion
+ const void *ptr_arg = NULL;
+
+ if (fmt_spec == 'p') {
+ ptr_arg = tvs ? tv_ptr(tvs, &arg_idx) : va_arg(ap, void *);
+ if (ptr_arg) {
+ arg_sign = 1;
+ }
+ } else if (fmt_spec == 'd') {
+ // signed
+ switch (length_modifier) {
+ case '\0': {
+ arg = (int)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int));
+ break;
+ }
+ case 'h': {
+ // char and short arguments are passed as int16_t
+ arg = (int16_t)(tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int));
+ break;
+ }
+ case 'l': {
+ arg = (tvs ? (long)tv_nr(tvs, &arg_idx) : va_arg(ap, long));
+ break;
+ }
+ case '2': {
+ arg = (
+ tvs
+ ? (long long)tv_nr(tvs, &arg_idx) // NOLINT (runtime/int)
+ : va_arg(ap, long long)); // NOLINT (runtime/int)
+ break;
+ }
+ case 'z': {
+ arg = (tvs
+ ? (ptrdiff_t)tv_nr(tvs, &arg_idx)
+ : va_arg(ap, ptrdiff_t));
+ break;
+ }
+ }
+ if (arg > 0) {
+ arg_sign = 1;
+ } else if (arg < 0) {
+ arg_sign = -1;
+ }
+ } else {
+ // unsigned
+ switch (length_modifier) {
+ case '\0': {
+ uarg = (unsigned int)(tvs
+ ? tv_nr(tvs, &arg_idx)
+ : va_arg(ap, unsigned int));
+ break;
+ }
+ case 'h': {
+ uarg = (uint16_t)(tvs
+ ? tv_nr(tvs, &arg_idx)
+ : va_arg(ap, unsigned int));
+ break;
+ }
+ case 'l': {
+ uarg = (tvs
+ ? (unsigned long)tv_nr(tvs, &arg_idx)
+ : va_arg(ap, unsigned long));
+ break;
+ }
+ case '2': {
+ uarg = (uintmax_t)(unsigned long long)( // NOLINT (runtime/int)
+ tvs
+ ? ((unsigned long long) // NOLINT (runtime/int)
+ tv_nr(tvs, &arg_idx))
+ : va_arg(ap, unsigned long long)); // NOLINT (runtime/int)
+ break;
+ }
+ case 'z': {
+ uarg = (tvs
+ ? (size_t)tv_nr(tvs, &arg_idx)
+ : va_arg(ap, size_t));
+ break;
+ }
+ }
+ arg_sign = (uarg != 0);
+ }
+
+ str_arg = tmp;
+ str_arg_l = 0;
+
+ // For d, i, u, o, x, and X conversions, if precision is specified,
+ // '0' flag should be ignored. This is so with Solaris 2.6, Digital
+ // UNIX 4.0, HPUX 10, Linux, FreeBSD, NetBSD; but not with Perl.
+ if (precision_specified) {
+ zero_padding = 0;
+ }
+
+ if (fmt_spec == 'd') {
+ if (force_sign && arg_sign >= 0) {
+ tmp[str_arg_l++] = space_for_positive ? ' ' : '+';
+ }
+ // leave negative numbers for snprintf to handle, to
+ // avoid handling tricky cases like (short int)-32768
+ } else if (alternate_form) {
+ if (arg_sign != 0 && (fmt_spec == 'x' || fmt_spec == 'X'
+ || fmt_spec == 'b' || fmt_spec == 'B')) {
+ tmp[str_arg_l++] = '0';
+ tmp[str_arg_l++] = fmt_spec;
+ }
+ // alternate form should have no effect for p * conversion, but ...
+ }
+
+ zero_padding_insertion_ind = str_arg_l;
+ if (!precision_specified) {
+ precision = 1; // default precision is 1
+ }
+ if (precision == 0 && arg_sign == 0) {
+ // when zero value is formatted with an explicit precision 0,
+ // resulting formatted string is empty (d, i, u, b, B, o, x, X, p)
+ } else {
+ switch (fmt_spec) {
+ case 'p': { // pointer
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ "%p", ptr_arg);
+ break;
+ }
+ case 'd': { // signed
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ "%" PRIdMAX, arg);
+ break;
+ }
+ case 'b': case 'B': { // binary
+ size_t bits = 0;
+ for (bits = sizeof(uintmax_t) * 8; bits > 0; bits--) {
+ if ((uarg >> (bits - 1)) & 0x1) {
+ break;
+ }
+ }
+
+ while (bits > 0) {
+ tmp[str_arg_l++] = ((uarg >> --bits) & 0x1) ? '1' : '0';
+ }
+ break;
+ }
+ default: { // unsigned
+ // construct a simple format string for snprintf
+ char f[] = "%" PRIuMAX;
+ f[sizeof("%" PRIuMAX) - 1 - 1] = fmt_spec;
+ assert(PRIuMAX[sizeof(PRIuMAX) - 1 - 1] == 'u');
+ str_arg_l += (size_t)snprintf(tmp + str_arg_l,
+ sizeof(tmp) - str_arg_l,
+ f, uarg);
+ break;
+ }
+ }
+ assert(str_arg_l < sizeof(tmp));
+
+ // include the optional minus sign and possible "0x" in the region
+ // before the zero padding insertion point
+ if (zero_padding_insertion_ind < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '-') {
+ zero_padding_insertion_ind++;
+ }
+ if (zero_padding_insertion_ind + 1 < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '0'
+ && (tmp[zero_padding_insertion_ind + 1] == 'x'
+ || tmp[zero_padding_insertion_ind + 1] == 'X'
+ || tmp[zero_padding_insertion_ind + 1] == 'b'
+ || tmp[zero_padding_insertion_ind + 1] == 'B')) {
+ zero_padding_insertion_ind += 2;
+ }
+ }
+
+ {
+ size_t num_of_digits = str_arg_l - zero_padding_insertion_ind;
+
+ if (alternate_form && fmt_spec == 'o'
+ // unless zero is already the first character
+ && !(zero_padding_insertion_ind < str_arg_l
+ && tmp[zero_padding_insertion_ind] == '0')) {
+ // assure leading zero for alternate-form octal numbers
+ if (!precision_specified
+ || precision < num_of_digits + 1) {
+ // precision is increased to force the first character to be
+ // zero, except if a zero value is formatted with an explicit
+ // precision of zero
+ precision = num_of_digits + 1;
+ }
+ }
+ // zero padding to specified precision?
+ if (num_of_digits < precision) {
+ number_of_zeros_to_pad = precision - num_of_digits;
+ }
+ }
+ // zero padding to specified minimal field width?
+ if (!justify_left && zero_padding) {
+ const int n = (int)(min_field_width - (str_arg_l
+ + number_of_zeros_to_pad));
+ if (n > 0) {
+ number_of_zeros_to_pad += (size_t)n;
+ }
+ }
+ break;
+ }
+
+ case 'f':
+ case 'F':
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+ {
+ // floating point
+ char format[40];
+ int remove_trailing_zeroes = false;
+
+ double f = tvs ? tv_float(tvs, &arg_idx) : va_arg(ap, double);
+ double abs_f = f < 0 ? -f : f;
+
+ if (fmt_spec == 'g' || fmt_spec == 'G') {
+ // can't use %g directly, cause it prints "1.0" as "1"
+ if ((abs_f >= 0.001 && abs_f < 10000000.0) || abs_f == 0.0) {
+ fmt_spec = ASCII_ISUPPER(fmt_spec) ? 'F' : 'f';
+ } else {
+ fmt_spec = fmt_spec == 'g' ? 'e' : 'E';
+ }
+ remove_trailing_zeroes = true;
+ }
+
+ if (isinf(f)
+ || (strchr("fF", fmt_spec) != NULL && abs_f > 1.0e307)) {
+ xstrlcpy(tmp, infinity_str(f > 0.0, fmt_spec,
+ force_sign, space_for_positive),
+ sizeof(tmp));
+ str_arg_l = strlen(tmp);
+ zero_padding = 0;
+ } else if (isnan(f)) {
+ // Not a number: nan or NAN
+ memmove(tmp, ASCII_ISUPPER(fmt_spec) ? "NAN" : "nan", 4);
+ str_arg_l = 3;
+ zero_padding = 0;
+ } else {
+ // Regular float number
+ format[0] = '%';
+ size_t l = 1;
+ if (force_sign) {
+ format[l++] = space_for_positive ? ' ' : '+';
+ }
+ if (precision_specified) {
+ size_t max_prec = TMP_LEN - 10;
+
+ // make sure we don't get more digits than we have room for
+ if ((fmt_spec == 'f' || fmt_spec == 'F') && abs_f > 1.0) {
+ max_prec -= (size_t)log10(abs_f);
+ }
+ if (precision > max_prec) {
+ precision = max_prec;
+ }
+ l += (size_t)snprintf(format + l, sizeof(format) - l, ".%d",
+ (int)precision);
+ }
+
+ // Cast to char to avoid a conversion warning on Ubuntu 12.04.
+ assert(l + 1 < sizeof(format));
+ format[l] = (char)(fmt_spec == 'F' ? 'f' : fmt_spec);
+ format[l + 1] = NUL;
+
+ str_arg_l = (size_t)snprintf(tmp, sizeof(tmp), format, f);
+ assert(str_arg_l < sizeof(tmp));
+
+ if (remove_trailing_zeroes) {
+ int i;
+ char *tp;
+
+ // using %g or %G: remove superfluous zeroes
+ if (fmt_spec == 'f' || fmt_spec == 'F') {
+ tp = tmp + str_arg_l - 1;
+ } else {
+ tp = (char *)vim_strchr((char_u *)tmp,
+ fmt_spec == 'e' ? 'e' : 'E');
+ if (tp) {
+ // remove superfluous '+' and leading zeroes from exponent
+ if (tp[1] == '+') {
+ // change "1.0e+07" to "1.0e07"
+ STRMOVE(tp + 1, tp + 2);
+ str_arg_l--;
+ }
+ i = (tp[1] == '-') ? 2 : 1;
+ while (tp[i] == '0') {
+ // change "1.0e07" to "1.0e7"
+ STRMOVE(tp + i, tp + i + 1);
+ str_arg_l--;
+ }
+ tp--;
+ }
+ }
+
+ if (tp != NULL && !precision_specified) {
+ // remove trailing zeroes, but keep the one just after a dot
+ while (tp > tmp + 2 && *tp == '0' && tp[-1] != '.') {
+ STRMOVE(tp, tp + 1);
+ tp--;
+ str_arg_l--;
+ }
+ }
+ } else {
+ // Be consistent: some printf("%e") use 1.0e+12 and some
+ // 1.0e+012; remove one zero in the last case.
+ char *tp = (char *)vim_strchr((char_u *)tmp,
+ fmt_spec == 'e' ? 'e' : 'E');
+ if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0'
+ && ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) {
+ STRMOVE(tp + 2, tp + 3);
+ str_arg_l--;
+ }
+ }
+ }
+ if (zero_padding && min_field_width > str_arg_l
+ && (tmp[0] == '-' || force_sign)) {
+ // Padding 0's should be inserted after the sign.
+ number_of_zeros_to_pad = min_field_width - str_arg_l;
+ zero_padding_insertion_ind = 1;
+ }
+ str_arg = tmp;
+ break;
+ }
+
+ default:
+ // unrecognized conversion specifier, keep format string as-is
+ zero_padding = 0; // turn zero padding off for non-numeric conversion
+ justify_left = 1;
+ min_field_width = 0; // reset flags
+
+ // discard the unrecognized conversion, just keep
+ // the unrecognized conversion character
+ str_arg = p;
+ str_arg_l = 0;
+ if (*p) {
+ str_arg_l++; // include invalid conversion specifier
+ }
+ // unchanged if not at end-of-string
+ break;
+ }
+
+ if (*p) {
+ p++; // step over the just processed conversion specifier
+ }
+
+ // insert padding to the left as requested by min_field_width;
+ // this does not include the zero padding in case of numerical conversions
+ if (!justify_left) {
+ assert(str_arg_l <= SIZE_MAX - number_of_zeros_to_pad);
+ if (min_field_width > str_arg_l + number_of_zeros_to_pad) {
+ // left padding with blank or zero
+ size_t pn = min_field_width - (str_arg_l + number_of_zeros_to_pad);
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memset(str + str_l, zero_padding ? '0' : ' ', MIN(pn, avail));
+ str_avail = pn < avail;
+ }
+ assert(pn <= SIZE_MAX - str_l);
+ str_l += pn;
+ }
+ }
+
+ // zero padding as requested by the precision or by the minimal
+ // field width for numeric conversions required?
+ if (number_of_zeros_to_pad == 0) {
+ // will not copy first part of numeric right now,
+ // force it to be copied later in its entirety
+ zero_padding_insertion_ind = 0;
+ } else {
+ // insert first part of numerics (sign or '0x') before zero padding
+ if (zero_padding_insertion_ind > 0) {
+ size_t zn = zero_padding_insertion_ind;
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memmove(str + str_l, str_arg, MIN(zn, avail));
+ str_avail = zn < avail;
+ }
+ assert(zn <= SIZE_MAX - str_l);
+ str_l += zn;
+ }
+
+ // insert zero padding as requested by precision or min field width
+ size_t zn = number_of_zeros_to_pad;
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memset(str + str_l, '0', MIN(zn, avail));
+ str_avail = zn < avail;
+ }
+ assert(zn <= SIZE_MAX - str_l);
+ str_l += zn;
+ }
+
+ // insert formatted string
+ // (or as-is conversion specifier for unknown conversions)
+ if (str_arg_l > zero_padding_insertion_ind) {
+ size_t sn = str_arg_l - zero_padding_insertion_ind;
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memmove(str + str_l,
+ str_arg + zero_padding_insertion_ind,
+ MIN(sn, avail));
+ str_avail = sn < avail;
+ }
+ assert(sn <= SIZE_MAX - str_l);
+ str_l += sn;
+ }
+
+ // insert right padding
+ if (justify_left) {
+ assert(str_arg_l <= SIZE_MAX - number_of_zeros_to_pad);
+ if (min_field_width > str_arg_l + number_of_zeros_to_pad) {
+ // right blank padding to the field width
+ size_t pn = min_field_width - (str_arg_l + number_of_zeros_to_pad);
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memset(str + str_l, ' ', MIN(pn, avail));
+ str_avail = pn < avail;
+ }
+ assert(pn <= SIZE_MAX - str_l);
+ str_l += pn;
+ }
+ }
+
+ xfree(tofree);
+ }
+ }
+
+ if (str_m > 0) {
+ // make sure the string is nul-terminated even at the expense of
+ // overwriting the last character (shouldn't happen, but just in case)
+ str[str_l <= str_m - 1 ? str_l : str_m - 1] = '\0';
+ }
+
+ if (tvs && tvs[arg_idx - 1].v_type != VAR_UNKNOWN) {
+ EMSG(_("E767: Too many arguments to printf()"));
+ }
+
+ // return the number of characters formatted (excluding trailing nul
+ // character); that is, the number of characters that would have been
+ // written to the buffer if it were large enough.
+ return (int)str_l;
+}
diff --git a/src/nvim/strings.h b/src/nvim/strings.h
index 3f0f0c8d6a..f2876c6307 100644
--- a/src/nvim/strings.h
+++ b/src/nvim/strings.h
@@ -2,6 +2,28 @@
#define NVIM_STRINGS_H
#include <stdbool.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "nvim/types.h"
+#include "nvim/eval/typval.h"
+
+/// Append string to string and return pointer to the next byte
+///
+/// Unlike strcat, this one does *not* add NUL byte and returns pointer to the
+/// past of the added string.
+///
+/// @param[out] dst String to append to.
+/// @param[in] src String to append.
+///
+/// @return pointer to the byte just past the appended byte.
+static inline char *strappend(char *const dst, const char *const src)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_RET
+{
+ const size_t src_len = strlen(src);
+ return (char *)memmove(dst, src, src_len) + src_len;
+}
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "strings.h.generated.h"
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 27855184df..81c78ca6a9 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.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
+
/*
* syntax.c: code for syntax highlighting
*/
@@ -13,19 +16,20 @@
#include "nvim/ascii.h"
#include "nvim/syntax.h"
#include "nvim/charset.h"
+#include "nvim/cursor_shape.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/hashtab.h"
+#include "nvim/highlight.h"
#include "nvim/indent_c.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/keymap.h"
#include "nvim/garray.h"
#include "nvim/option.h"
@@ -40,42 +44,52 @@
#include "nvim/ui.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
+#include "nvim/buffer.h"
static bool did_syntax_onoff = false;
-// Structure that stores information about a highlight group.
-// The ID of a highlight group is also called group ID. It is the index in
-// the highlight_ga array PLUS ONE.
+/// Structure that stores information about a highlight group.
+/// The ID of a highlight group is also called group ID. It is the index in
+/// the highlight_ga array PLUS ONE.
struct hl_group {
- char_u *sg_name; // highlight group name
- char_u *sg_name_u; // uppercase of sg_name
- int sg_attr; // Screen attr
- int sg_link; // link to this highlight group ID
- int sg_set; // combination of SG_* flags
- scid_T sg_scriptID; // script in which the group was last set
+ char_u *sg_name; ///< highlight group name
+ char_u *sg_name_u; ///< uppercase of sg_name
+ bool sg_cleared; ///< "hi clear" was used
+ int sg_attr; ///< Screen attr @see ATTR_ENTRY
+ int sg_link; ///< link to this highlight group ID
+ int sg_set; ///< combination of flags in \ref SG_SET
+ scid_T sg_scriptID; ///< script in which the group was last set
// for terminal UIs
- int sg_cterm; // "cterm=" highlighting attr
- int sg_cterm_fg; // terminal fg color number + 1
- int sg_cterm_bg; // terminal bg color number + 1
- int sg_cterm_bold; // bold attr was set for light color
+ int sg_cterm; ///< "cterm=" highlighting attr
+ ///< (combination of \ref HlAttrFlags)
+ int sg_cterm_fg; ///< terminal fg color number + 1
+ int sg_cterm_bg; ///< terminal bg color number + 1
+ bool sg_cterm_bold; ///< bold attr was set for light color
// for RGB UIs
- int sg_gui; // "gui=" highlighting attributes
- RgbValue sg_rgb_fg; // RGB foreground color
- RgbValue sg_rgb_bg; // RGB background color
- RgbValue sg_rgb_sp; // RGB special color
- uint8_t *sg_rgb_fg_name; // RGB foreground color name
- uint8_t *sg_rgb_bg_name; // RGB background color name
- uint8_t *sg_rgb_sp_name; // RGB special color name
+ int sg_gui; ///< "gui=" highlighting attributes
+ ///< (combination of \ref HlAttrFlags)
+ RgbValue sg_rgb_fg; ///< RGB foreground color
+ RgbValue sg_rgb_bg; ///< RGB background color
+ RgbValue sg_rgb_sp; ///< RGB special color
+ uint8_t *sg_rgb_fg_name; ///< RGB foreground color name
+ uint8_t *sg_rgb_bg_name; ///< RGB background color name
+ uint8_t *sg_rgb_sp_name; ///< RGB special color name
};
+/// \addtogroup SG_SET
+/// @{
#define SG_CTERM 2 // cterm has been set
#define SG_GUI 4 // gui has been set
#define SG_LINK 8 // link has been set
+/// @}
-// highlight groups for 'highlight' option
+// builtin |highlight-groups|
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
-#define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data)))
+static inline struct hl_group * HL_TABLE(void)
+{
+ return ((struct hl_group *)((highlight_ga.ga_data)));
+}
#define MAX_HL_ID 20000 /* maximum value for a highlight ID. */
@@ -94,10 +108,8 @@ static int include_none = 0; /* when 1 include "nvim/None" */
static int include_default = 0; /* when 1 include "nvim/default" */
static int include_link = 0; /* when 2 include "nvim/link" and "clear" */
-/*
- * The "term", "cterm" and "gui" arguments can be any combination of the
- * following names, separated by commas (but no spaces!).
- */
+/// The "term", "cterm" and "gui" arguments can be any combination of the
+/// following names, separated by commas (but no spaces!).
static char *(hl_name_table[]) =
{"bold", "standout", "underline", "undercurl",
"italic", "reverse", "inverse", "NONE"};
@@ -105,42 +117,42 @@ static int hl_attr_table[] =
{HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE,
HL_INVERSE, 0};
-/*
- * The patterns that are being searched for are stored in a syn_pattern.
- * A match item consists of one pattern.
- * A start/end item consists of n start patterns and m end patterns.
- * A start/skip/end item consists of n start patterns, one skip pattern and m
- * end patterns.
- * For the latter two, the patterns are always consecutive: start-skip-end.
- *
- * A character offset can be given for the matched text (_m_start and _m_end)
- * and for the actually highlighted text (_h_start and _h_end).
- */
+// The patterns that are being searched for are stored in a syn_pattern.
+// A match item consists of one pattern.
+// A start/end item consists of n start patterns and m end patterns.
+// A start/skip/end item consists of n start patterns, one skip pattern and m
+// end patterns.
+// For the latter two, the patterns are always consecutive: start-skip-end.
+//
+// A character offset can be given for the matched text (_m_start and _m_end)
+// and for the actually highlighted text (_h_start and _h_end).
+//
+// Note that ordering of members is optimized to reduce padding.
typedef struct syn_pattern {
- char sp_type; /* see SPTYPE_ defines below */
- char sp_syncing; /* this item used for syncing */
- int sp_flags; /* see HL_ defines below */
- int sp_cchar; /* conceal substitute character */
- struct sp_syn sp_syn; /* struct passed to in_id_list() */
- short sp_syn_match_id; /* highlight group ID of pattern */
- char_u *sp_pattern; /* regexp to match, pattern */
- regprog_T *sp_prog; /* regexp to match, program */
+ char sp_type; // see SPTYPE_ defines below
+ bool sp_syncing; // this item used for syncing
+ int16_t sp_syn_match_id; // highlight group ID of pattern
+ int16_t sp_off_flags; // see below
+ int sp_offsets[SPO_COUNT]; // offsets
+ int sp_flags; // see HL_ defines below
+ int sp_cchar; // conceal substitute character
+ int sp_ic; // ignore-case flag for sp_prog
+ int sp_sync_idx; // sync item index (syncing only)
+ int sp_line_id; // ID of last line where tried
+ int sp_startcol; // next match in sp_line_id line
+ int16_t *sp_cont_list; // cont. group IDs, if non-zero
+ int16_t *sp_next_list; // next group IDs, if non-zero
+ struct sp_syn sp_syn; // struct passed to in_id_list()
+ char_u *sp_pattern; // regexp to match, pattern
+ regprog_T *sp_prog; // regexp to match, program
syn_time_T sp_time;
- int sp_ic; /* ignore-case flag for sp_prog */
- short sp_off_flags; /* see below */
- int sp_offsets[SPO_COUNT]; /* offsets */
- short *sp_cont_list; /* cont. group IDs, if non-zero */
- short *sp_next_list; /* next group IDs, if non-zero */
- int sp_sync_idx; /* sync item index (syncing only) */
- int sp_line_id; /* ID of last line where tried */
- int sp_startcol; /* next match in sp_line_id line */
} synpat_T;
typedef struct syn_cluster_S {
- char_u *scl_name; /* syntax cluster name */
- char_u *scl_name_u; /* uppercase of scl_name */
- short *scl_list; /* IDs in this syntax cluster */
+ char_u *scl_name; // syntax cluster name
+ char_u *scl_name_u; // uppercase of scl_name
+ int16_t *scl_list; // IDs in this syntax cluster
} syn_cluster_T;
/*
@@ -149,27 +161,27 @@ typedef struct syn_cluster_S {
* (The end positions have the column number of the next char)
*/
typedef struct state_item {
- int si_idx; /* index of syntax pattern or
- KEYWORD_IDX */
- int si_id; /* highlight group ID for keywords */
- int si_trans_id; /* idem, transparency removed */
- int si_m_lnum; /* lnum of the match */
- int si_m_startcol; /* starting column of the match */
- lpos_T si_m_endpos; /* just after end posn of the match */
- lpos_T si_h_startpos; /* start position of the highlighting */
- lpos_T si_h_endpos; /* end position of the highlighting */
- lpos_T si_eoe_pos; /* end position of end pattern */
- int si_end_idx; /* group ID for end pattern or zero */
- int si_ends; /* if match ends before si_m_endpos */
- int si_attr; /* attributes in this state */
- long si_flags; /* HL_HAS_EOL flag in this state, and
- * HL_SKIP* for si_next_list */
- int si_seqnr; /* sequence number */
- int si_cchar; /* substitution character for conceal */
- short *si_cont_list; /* list of contained groups */
- short *si_next_list; /* nextgroup IDs after this item ends */
- reg_extmatch_T *si_extmatch; /* \z(...\) matches from start
- * pattern */
+ int si_idx; // index of syntax pattern or
+ // KEYWORD_IDX
+ int si_id; // highlight group ID for keywords
+ int si_trans_id; // idem, transparency removed
+ int si_m_lnum; // lnum of the match
+ int si_m_startcol; // starting column of the match
+ lpos_T si_m_endpos; // just after end posn of the match
+ lpos_T si_h_startpos; // start position of the highlighting
+ lpos_T si_h_endpos; // end position of the highlighting
+ lpos_T si_eoe_pos; // end position of end pattern
+ int si_end_idx; // group ID for end pattern or zero
+ int si_ends; // if match ends before si_m_endpos
+ int si_attr; // attributes in this state
+ long si_flags; // HL_HAS_EOL flag in this state, and
+ // HL_SKIP* for si_next_list
+ int si_seqnr; // sequence number
+ int si_cchar; // substitution character for conceal
+ int16_t *si_cont_list; // list of contained groups
+ int16_t *si_next_list; // nextgroup IDs after this item ends
+ reg_extmatch_T *si_extmatch; // \z(...\) matches from start
+ // pattern
} stateitem_T;
/*
@@ -177,14 +189,14 @@ typedef struct state_item {
* very often.
*/
typedef struct {
- int flags; /* flags for contained and transparent */
- int keyword; /* TRUE for ":syn keyword" */
- int *sync_idx; /* syntax item for "grouphere" argument, NULL
- if not allowed */
- char has_cont_list; /* TRUE if "cont_list" can be used */
- short *cont_list; /* group IDs for "contains" argument */
- short *cont_in_list; /* group IDs for "containedin" argument */
- short *next_list; /* group IDs for "nextgroup" argument */
+ int flags; // flags for contained and transparent
+ bool keyword; // true for ":syn keyword"
+ int *sync_idx; // syntax item for "grouphere" argument, NULL
+ // if not allowed
+ bool has_cont_list; // true if "cont_list" can be used
+ int16_t *cont_list; // group IDs for "contains" argument
+ int16_t *cont_in_list; // group IDs for "containedin" argument
+ int16_t *next_list; // group IDs for "nextgroup" argument
} syn_opt_arg_T;
typedef struct {
@@ -206,12 +218,6 @@ struct name_list {
# include "syntax.c.generated.h"
#endif
-/*
- * An attribute number is the index in attr_table plus ATTR_OFF.
- */
-#define ATTR_OFF 1
-
-
static char *(spo_name_tab[SPO_COUNT]) =
{"ms=", "me=", "hs=", "he=", "rs=", "re=", "lc="};
@@ -303,6 +309,8 @@ static keyentry_T dumkey;
#define HIKEY2KE(p) ((keyentry_T *)((p) - (dumkey.keyword - (char_u *)&dumkey)))
#define HI2KE(hi) HIKEY2KE((hi)->hi_key)
+// -V:HI2KE:782
+
/*
* To reduce the time spent in keepend(), remember at which level in the state
* stack the first item with "keepend" is present. When "-1", there is no
@@ -312,9 +320,10 @@ static int keepend_level = -1;
static char msg_no_items[] = N_("No Syntax items defined for this buffer");
-#define KEYWORD_IDX -1 /* value of si_idx for keywords */
-#define ID_LIST_ALL (short *)-1 /* valid of si_cont_list for containing all
- but contained groups */
+// value of si_idx for keywords
+#define KEYWORD_IDX -1
+// valid of si_cont_list for containing all but contained groups
+#define ID_LIST_ALL (int16_t *)-1
static int next_seqnr = 1; /* value to use for si_seqnr */
@@ -357,9 +366,9 @@ static int current_state_stored = 0; /* TRUE if stored current state
static int current_finished = 0; /* current line has been finished */
static garray_T current_state /* current stack of state_items */
= GA_EMPTY_INIT_VALUE;
-static short *current_next_list = NULL; /* when non-zero, nextgroup list */
-static int current_next_flags = 0; /* flags for current_next_list */
-static int current_line_id = 0; /* unique number for current line */
+static int16_t *current_next_list = NULL; // when non-zero, nextgroup list
+static int current_next_flags = 0; // flags for current_next_list
+static int current_line_id = 0; // unique number for current line
#define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx]
@@ -393,12 +402,14 @@ void syntax_start(win_T *wp, linenr_T lnum)
* Also do this when a change was made, the current state may be invalid
* then.
*/
- if (syn_block != wp->w_s || changedtick != syn_buf->b_changedtick) {
+ if (syn_block != wp->w_s
+ || syn_buf != wp->w_buffer
+ || changedtick != buf_get_changedtick(syn_buf)) {
invalidate_current_state();
syn_buf = wp->w_buffer;
syn_block = wp->w_s;
}
- changedtick = syn_buf->b_changedtick;
+ changedtick = buf_get_changedtick(syn_buf);
syn_win = wp;
/*
@@ -415,7 +426,7 @@ void syntax_start(win_T *wp, linenr_T lnum)
if (VALID_STATE(&current_state)
&& current_lnum < lnum
&& current_lnum < syn_buf->b_ml.ml_line_count) {
- (void)syn_finish_line(FALSE);
+ (void)syn_finish_line(false);
if (!current_state_stored) {
++current_lnum;
(void)store_current_state();
@@ -438,9 +449,10 @@ void syntax_start(win_T *wp, linenr_T lnum)
if (INVALID_STATE(&current_state) && syn_block->b_sst_array != NULL) {
/* Find last valid saved state before start_lnum. */
for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) {
- if (p->sst_lnum > lnum)
+ if (p->sst_lnum > lnum) {
break;
- if (p->sst_lnum <= lnum && p->sst_change_lnum == 0) {
+ }
+ if (p->sst_change_lnum == 0) {
last_valid = p;
if (p->sst_lnum >= lnum - syn_block->b_syn_sync_minlines)
last_min_valid = p;
@@ -476,8 +488,8 @@ void syntax_start(win_T *wp, linenr_T lnum)
dist = syn_buf->b_ml.ml_line_count / (syn_block->b_sst_len - Rows) + 1;
while (current_lnum < lnum) {
syn_start_line();
- (void)syn_finish_line(FALSE);
- ++current_lnum;
+ (void)syn_finish_line(false);
+ current_lnum++;
/* If we parsed at least "minlines" lines or started at a valid
* state, the current state is considered valid. */
@@ -574,7 +586,7 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
linenr_T lnum;
linenr_T end_lnum;
linenr_T break_lnum;
- int had_sync_point;
+ bool had_sync_point;
stateitem_T *cur_si;
synpat_T *spp;
char_u *line;
@@ -708,11 +720,9 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
for (current_lnum = lnum; current_lnum < end_lnum; ++current_lnum) {
syn_start_line();
for (;; ) {
- had_sync_point = syn_finish_line(TRUE);
- /*
- * When a sync point has been found, remember where, and
- * continue to look for another one, further on in the line.
- */
+ had_sync_point = syn_finish_line(true);
+ // When a sync point has been found, remember where, and
+ // continue to look for another one, further on in the line.
if (had_sync_point && current_state.ga_len) {
cur_si = &CUR_STATE(current_state.ga_len - 1);
if (cur_si->si_m_endpos.lnum > start_lnum) {
@@ -790,10 +800,11 @@ static void syn_sync(win_T *wp, linenr_T start_lnum, synstate_T *last_valid)
}
current_col = found_m_endpos.col;
current_lnum = found_m_endpos.lnum;
- (void)syn_finish_line(FALSE);
- ++current_lnum;
- } else
+ (void)syn_finish_line(false);
+ current_lnum++;
+ } else {
current_lnum = start_lnum;
+ }
break;
}
@@ -868,7 +879,8 @@ static void syn_start_line(void)
}
next_match_idx = -1;
- ++current_line_id;
+ current_line_id++;
+ next_seqnr = 1;
}
/*
@@ -1405,14 +1417,14 @@ static int syn_stack_equal(synstate_T *sp)
/* If the pointer is different it can still be the
* same text. Compare the strings, ignore case when
* the start item has the sp_ic flag set. */
- if (bsx->matches[j] == NULL
- || six->matches[j] == NULL)
+ if (bsx->matches[j] == NULL || six->matches[j] == NULL) {
break;
- if ((SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_ic
- ? mb_stricmp(bsx->matches[j],
- six->matches[j]) != 0
- : STRCMP(bsx->matches[j], six->matches[j]) != 0)
+ }
+ if (mb_strcmp_ic((SYN_ITEMS(syn_block)[CUR_STATE(i).si_idx]).sp_ic,
+ (const char *)bsx->matches[j],
+ (const char *)six->matches[j]) != 0) {
break;
+ }
}
}
if (j != NSUBEXP)
@@ -1488,7 +1500,7 @@ int syntax_check_changed(linenr_T lnum)
* finish the previous line (needed when not all of the line was
* drawn)
*/
- (void)syn_finish_line(FALSE);
+ (void)syn_finish_line(false);
/*
* Compare the current state with the previously saved state of
@@ -1514,41 +1526,37 @@ int syntax_check_changed(linenr_T lnum)
* the line. It can start anywhere in the line, as long as the current state
* is valid.
*/
-static int
-syn_finish_line (
- int syncing /* called for syncing */
+static bool
+syn_finish_line(
+ const bool syncing // called for syncing
)
{
- stateitem_T *cur_si;
- colnr_T prev_current_col;
-
while (!current_finished) {
- (void)syn_current_attr(syncing, FALSE, NULL, FALSE);
- /*
- * When syncing, and found some item, need to check the item.
- */
+ (void)syn_current_attr(syncing, false, NULL, false);
+
+ // When syncing, and found some item, need to check the item.
if (syncing && current_state.ga_len) {
- /*
- * Check for match with sync item.
- */
- cur_si = &CUR_STATE(current_state.ga_len - 1);
+ // Check for match with sync item.
+ const stateitem_T *const cur_si = &CUR_STATE(current_state.ga_len - 1);
if (cur_si->si_idx >= 0
&& (SYN_ITEMS(syn_block)[cur_si->si_idx].sp_flags
- & (HL_SYNC_HERE|HL_SYNC_THERE)))
- return TRUE;
-
- /* syn_current_attr() will have skipped the check for an item
- * that ends here, need to do that now. Be careful not to go
- * past the NUL. */
- prev_current_col = current_col;
- if (syn_getcurline()[current_col] != NUL)
- ++current_col;
+ & (HL_SYNC_HERE|HL_SYNC_THERE))) {
+ return true;
+ }
+
+ // syn_current_attr() will have skipped the check for an item
+ // that ends here, need to do that now. Be careful not to go
+ // past the NUL.
+ const colnr_T prev_current_col = current_col;
+ if (syn_getcurline()[current_col] != NUL) {
+ current_col++;
+ }
check_state_ends();
current_col = prev_current_col;
}
- ++current_col;
+ current_col++;
}
- return FALSE;
+ return false;
}
/*
@@ -1560,11 +1568,11 @@ syn_finish_line (
* When "can_spell" is not NULL set it to TRUE when spell-checking should be
* done.
*/
-int
-get_syntax_attr (
- colnr_T col,
- bool *can_spell,
- int keep_state /* keep state of char at "col" */
+int
+get_syntax_attr(
+ const colnr_T col,
+ bool *const can_spell,
+ const bool keep_state // keep state of char at "col"
)
{
int attr = 0;
@@ -1586,6 +1594,7 @@ get_syntax_attr (
current_id = 0;
current_trans_id = 0;
current_flags = 0;
+ current_seqnr = 0;
return 0;
}
@@ -1597,9 +1606,9 @@ get_syntax_attr (
* Skip from the current column to "col", get the attributes for "col".
*/
while (current_col <= col) {
- attr = syn_current_attr(FALSE, TRUE, can_spell,
- current_col == col ? keep_state : FALSE);
- ++current_col;
+ attr = syn_current_attr(false, true, can_spell,
+ current_col == col ? keep_state : false);
+ current_col++;
}
return attr;
@@ -1608,42 +1617,37 @@ get_syntax_attr (
/*
* Get syntax attributes for current_lnum, current_col.
*/
-static int
-syn_current_attr (
- int syncing, /* When 1: called for syncing */
- int displaying, /* result will be displayed */
- bool *can_spell, /* return: do spell checking */
- int keep_state /* keep syntax stack afterwards */
+static int syn_current_attr(
+ const bool syncing, // When true: called for syncing
+ const bool displaying, // result will be displayed
+ bool *const can_spell, // return: do spell checking
+ const bool keep_state // keep syntax stack afterwards
)
{
- int syn_id;
- lpos_T endpos; /* was: char_u *endp; */
- lpos_T hl_startpos; /* was: int hl_startcol; */
+ lpos_T endpos; // was: char_u *endp;
+ lpos_T hl_startpos; // was: int hl_startcol;
lpos_T hl_endpos;
- lpos_T eos_pos; /* end-of-start match (start region) */
- lpos_T eoe_pos; /* end-of-end pattern */
- int end_idx; /* group ID for end pattern */
- synpat_T *spp;
+ lpos_T eos_pos; // end-of-start match (start region)
+ lpos_T eoe_pos; // end-of-end pattern
+ int end_idx; // group ID for end pattern
stateitem_T *cur_si, *sip = NULL;
int startcol;
int endcol;
long flags;
int cchar;
- short *next_list;
- int found_match; /* found usable match */
- static int try_next_column = FALSE; /* must try in next col */
- int do_keywords;
+ int16_t *next_list;
+ bool found_match; // found usable match
+ static bool try_next_column = false; // must try in next col
regmmatch_T regmatch;
lpos_T pos;
- int lc_col;
reg_extmatch_T *cur_extmatch = NULL;
char_u buf_chartab[32]; // chartab array for syn iskeyword
char_u *line; // current line. NOTE: becomes invalid after
// looking for a pattern match!
- /* variables for zero-width matches that have a "nextgroup" argument */
- int keep_next_list;
- int zero_width_next_list = FALSE;
+ // variables for zero-width matches that have a "nextgroup" argument
+ bool keep_next_list;
+ bool zero_width_next_list = false;
garray_T zero_width_next_ga;
/*
@@ -1656,8 +1660,9 @@ syn_current_attr (
* If we found a match after the last column, use it.
*/
if (next_match_idx >= 0 && next_match_col >= (int)current_col
- && next_match_col != MAXCOL)
- (void)push_next_match(NULL);
+ && next_match_col != MAXCOL) {
+ (void)push_next_match();
+ }
current_finished = TRUE;
current_state_stored = FALSE;
@@ -1677,13 +1682,13 @@ syn_current_attr (
*/
if (try_next_column) {
next_match_idx = -1;
- try_next_column = FALSE;
+ try_next_column = false;
}
- /* Only check for keywords when not syncing and there are some. */
- do_keywords = !syncing
- && (syn_block->b_keywtab.ht_used > 0
- || syn_block->b_keywtab_ic.ht_used > 0);
+ // Only check for keywords when not syncing and there are some.
+ const bool do_keywords = !syncing
+ && (syn_block->b_keywtab.ht_used > 0
+ || syn_block->b_keywtab_ic.ht_used > 0);
/* Init the list of zero-width matches with a nextlist. This is used to
* avoid matching the same item in the same position twice. */
@@ -1698,9 +1703,9 @@ syn_current_attr (
* column.
*/
do {
- found_match = FALSE;
- keep_next_list = FALSE;
- syn_id = 0;
+ found_match = false;
+ keep_next_list = false;
+ int syn_id = 0;
/*
* 1. Check for a current state.
@@ -1722,16 +1727,12 @@ syn_current_attr (
*/
if (do_keywords) {
line = syn_getcurline();
- if (vim_iswordp_buf(line + current_col, syn_buf)
- && (current_col == 0
- || !vim_iswordp_buf(line + current_col - 1
- - (has_mbyte
- ? (*mb_head_off)(line, line + current_col - 1)
- : 0)
- , syn_buf))) {
- syn_id = check_keyword_id(line, (int)current_col,
- &endcol, &flags, &next_list, cur_si,
- &cchar);
+ const char_u *cur_pos = line + current_col;
+ if (vim_iswordp_buf(cur_pos, syn_buf)
+ && (current_col == 0 || !vim_iswordp_buf(
+ cur_pos - 1 - utf_head_off(line, cur_pos - 1), syn_buf))) {
+ syn_id = check_keyword_id(line, (int)current_col, &endcol, &flags,
+ &next_list, cur_si, &cchar);
if (syn_id != 0) {
push_current_state(KEYWORD_IDX);
{
@@ -1764,8 +1765,9 @@ syn_current_attr (
cur_si->si_trans_id = CUR_STATE(
current_state.ga_len - 2).si_trans_id;
}
- } else
+ } else {
cur_si->si_attr = syn_id2attr(syn_id);
+ }
cur_si->si_cont_list = NULL;
cur_si->si_next_list = next_list;
check_keepend();
@@ -1792,7 +1794,7 @@ syn_current_attr (
next_match_idx = 0; /* no match in this line yet */
next_match_col = MAXCOL;
for (int idx = syn_block->b_syn_patterns.ga_len; --idx >= 0; ) {
- spp = &(SYN_ITEMS(syn_block)[idx]);
+ synpat_T *const spp = &(SYN_ITEMS(syn_block)[idx]);
if ( spp->sp_syncing == syncing
&& (displaying || !(spp->sp_flags & HL_DISPLAY))
&& (spp->sp_type == SPTYPE_MATCH
@@ -1813,13 +1815,14 @@ syn_current_attr (
continue;
spp->sp_line_id = current_line_id;
- lc_col = current_col - spp->sp_offsets[SPO_LC_OFF];
- if (lc_col < 0)
+ colnr_T lc_col = current_col - spp->sp_offsets[SPO_LC_OFF];
+ if (lc_col < 0) {
lc_col = 0;
+ }
regmatch.rmm_ic = spp->sp_ic;
regmatch.regprog = spp->sp_prog;
- int r = syn_regexec(&regmatch, current_lnum, (colnr_T)lc_col,
+ int r = syn_regexec(&regmatch, current_lnum, lc_col,
IF_SYN_TIME(&spp->sp_time));
spp->sp_prog = regmatch.regprog;
if (!r) {
@@ -1858,7 +1861,7 @@ syn_current_attr (
* column, because it may match from there.
*/
if (did_match_already(idx, &zero_width_next_ga)) {
- try_next_column = TRUE;
+ try_next_column = true;
continue;
}
@@ -1920,9 +1923,9 @@ syn_current_attr (
* If an empty string is matched, may need
* to try matching again at next column.
*/
- if (regmatch.startpos[0].col
- == regmatch.endpos[0].col)
- try_next_column = TRUE;
+ if (regmatch.startpos[0].col == regmatch.endpos[0].col) {
+ try_next_column = true;
+ }
continue;
}
}
@@ -1967,17 +1970,18 @@ syn_current_attr (
&& lspp->sp_next_list != NULL) {
current_next_list = lspp->sp_next_list;
current_next_flags = lspp->sp_flags;
- keep_next_list = TRUE;
- zero_width_next_list = TRUE;
+ keep_next_list = true;
+ zero_width_next_list = true;
/* Add the index to a list, so that we can check
* later that we don't match it again (and cause an
* endless loop). */
GA_APPEND(int, &zero_width_next_ga, next_match_idx);
next_match_idx = -1;
- } else
- cur_si = push_next_match(cur_si);
- found_match = TRUE;
+ } else {
+ cur_si = push_next_match();
+ }
+ found_match = true;
}
}
}
@@ -2010,8 +2014,9 @@ syn_current_attr (
*/
current_next_list = NULL;
next_match_idx = -1;
- if (!zero_width_next_list)
- found_match = TRUE;
+ if (!zero_width_next_list) {
+ found_match = true;
+ }
}
} while (found_match);
@@ -2026,6 +2031,7 @@ syn_current_attr (
current_id = 0;
current_trans_id = 0;
current_flags = 0;
+ current_seqnr = 0;
if (cur_si != NULL) {
for (int idx = current_state.ga_len - 1; idx >= 0; --idx) {
sip = &CUR_STATE(idx);
@@ -2114,9 +2120,11 @@ syn_current_attr (
/* nextgroup ends at end of line, unless "skipnl" or "skipempty" present */
if (current_next_list != NULL
- && syn_getcurline()[current_col + 1] == NUL
- && !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY)))
+ && (line = syn_getcurline())[current_col] != NUL
+ && line[current_col + 1] == NUL
+ && !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY))) {
current_next_list = NULL;
+ }
if (!GA_EMPTY(&zero_width_next_ga))
ga_clear(&zero_width_next_ga);
@@ -2157,9 +2165,10 @@ static int did_match_already(int idx, garray_T *gap)
/*
* Push the next match onto the stack.
*/
-static stateitem_T *push_next_match(stateitem_T *cur_si)
+static stateitem_T *push_next_match(void)
{
- synpat_T *spp;
+ stateitem_T *cur_si;
+ synpat_T *spp;
int save_flags;
spp = &(SYN_ITEMS(syn_block)[next_match_idx]);
@@ -2435,8 +2444,8 @@ static void check_keepend(void)
*
* Return the flags for the matched END.
*/
-static void
-update_si_end (
+static void
+update_si_end(
stateitem_T *sip,
int startcol, /* where to start searching for the end */
int force /* when TRUE overrule a previous end */
@@ -2528,16 +2537,16 @@ static void pop_current_state(void)
* If found, the end of the region and the end of the highlighting is
* computed.
*/
-static void
-find_endpos (
- int idx, /* index of the pattern */
- lpos_T *startpos, /* where to start looking for an END match */
- lpos_T *m_endpos, /* return: end of match */
- lpos_T *hl_endpos, /* return: end of highlighting */
- long *flagsp, /* return: flags of matching END */
- lpos_T *end_endpos, /* return: end of end pattern match */
- int *end_idx, /* return: group ID for end pat. match, or 0 */
- reg_extmatch_T *start_ext /* submatches from the start pattern */
+static void
+find_endpos(
+ int idx, // index of the pattern
+ lpos_T *startpos, // where to start looking for an END match
+ lpos_T *m_endpos, // return: end of match
+ lpos_T *hl_endpos, // return: end of highlighting
+ long *flagsp, // return: flags of matching END
+ lpos_T *end_endpos, // return: end of end pattern match
+ int *end_idx, // return: group ID for end pat. match, or 0
+ reg_extmatch_T *start_ext // submatches from the start pattern
)
{
colnr_T matchcol;
@@ -2770,13 +2779,13 @@ static void limit_pos_zero(lpos_T *pos, lpos_T *limit)
/*
* Add offset to matched text for end of match or highlight.
*/
-static void
-syn_add_end_off (
- lpos_T *result, /* returned position */
- regmmatch_T *regmatch, /* start/end of match */
- synpat_T *spp, /* matched pattern */
- int idx, /* index of offset */
- int extra /* extra chars for offset to start */
+static void
+syn_add_end_off(
+ lpos_T *result, // returned position
+ regmmatch_T *regmatch, // start/end of match
+ synpat_T *spp, // matched pattern
+ int idx, // index of offset
+ int extra // extra chars for offset to start
)
{
int col;
@@ -2801,11 +2810,13 @@ syn_add_end_off (
base = ml_get_buf(syn_buf, result->lnum, FALSE);
p = base + col;
if (off > 0) {
- while (off-- > 0 && *p != NUL)
- mb_ptr_adv(p);
- } else if (off < 0) {
- while (off++ < 0 && base < p)
- mb_ptr_back(base, p);
+ while (off-- > 0 && *p != NUL) {
+ MB_PTR_ADV(p);
+ }
+ } else {
+ while (off++ < 0 && base < p) {
+ MB_PTR_BACK(base, p);
+ }
}
col = (int)(p - base);
}
@@ -2816,13 +2827,13 @@ syn_add_end_off (
* Add offset to matched text for start of match or highlight.
* Avoid resulting column to become negative.
*/
-static void
-syn_add_start_off (
- lpos_T *result, /* returned position */
- regmmatch_T *regmatch, /* start/end of match */
+static void
+syn_add_start_off(
+ lpos_T *result, // returned position
+ regmmatch_T *regmatch, // start/end of match
synpat_T *spp,
int idx,
- int extra /* extra chars for offset to end */
+ int extra // extra chars for offset to end
)
{
int col;
@@ -2848,11 +2859,13 @@ syn_add_start_off (
base = ml_get_buf(syn_buf, result->lnum, FALSE);
p = base + col;
if (off > 0) {
- while (off-- && *p != NUL)
- mb_ptr_adv(p);
- } else if (off < 0) {
- while (off++ && base < p)
- mb_ptr_back(base, p);
+ while (off-- && *p != NUL) {
+ MB_PTR_ADV(p);
+ }
+ } else {
+ while (off++ && base < p) {
+ MB_PTR_BACK(base, p);
+ }
}
col = (int)(p - base);
}
@@ -2881,6 +2894,13 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T
pt = profile_start();
}
+ if (rmp->regprog == NULL) {
+ // This can happen if a previous call to vim_regexec_multi() tried to
+ // use the NFA engine, which resulted in NFA_TOO_EXPENSIVE, and
+ // compiling the pattern with the other engine fails.
+ return false;
+ }
+
rmp->rmm_maxcol = syn_buf->b_p_smc;
r = vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL);
@@ -2906,41 +2926,37 @@ static int syn_regexec(regmmatch_T *rmp, linenr_T lnum, colnr_T col, syn_time_T
/*
* Check one position in a line for a matching keyword.
* The caller must check if a keyword can start at startcol.
- * Return it's ID if found, 0 otherwise.
- */
-static int
-check_keyword_id (
- char_u *line,
- int startcol, /* position in line to check for keyword */
- int *endcolp, /* return: character after found keyword */
- long *flagsp, /* return: flags of matching keyword */
- short **next_listp, /* return: next_list of matching keyword */
- stateitem_T *cur_si, /* item at the top of the stack */
- int *ccharp /* conceal substitution char */
+ * Return its ID if found, 0 otherwise.
+ */
+static int check_keyword_id(
+ char_u *const line,
+ const int startcol, // position in line to check for keyword
+ int *const endcolp, // return: character after found keyword
+ long *const flagsp, // return: flags of matching keyword
+ int16_t **const next_listp, // return: next_list of matching keyword
+ stateitem_T *const cur_si, // item at the top of the stack
+ int *const ccharp // conceal substitution char
)
{
- char_u *kwp;
- int kwlen;
- char_u keyword[MAXKEYWLEN + 1]; /* assume max. keyword len is 80 */
-
- /* Find first character after the keyword. First character was already
- * checked. */
- kwp = line + startcol;
- kwlen = 0;
+ // Find first character after the keyword. First character was already
+ // checked.
+ char_u *const kwp = line + startcol;
+ int kwlen = 0;
do {
- if (has_mbyte)
+ if (has_mbyte) {
kwlen += (*mb_ptr2len)(kwp + kwlen);
- else
- ++kwlen;
+ } else {
+ kwlen++;
+ }
} while (vim_iswordp_buf(kwp + kwlen, syn_buf));
- if (kwlen > MAXKEYWLEN)
+ if (kwlen > MAXKEYWLEN) {
return 0;
+ }
- /*
- * Must make a copy of the keyword, so we can add a NUL and make it
- * lowercase.
- */
+ // Must make a copy of the keyword, so we can add a NUL and make it
+ // lowercase.
+ char_u keyword[MAXKEYWLEN + 1]; // assume max. keyword len is 80
STRLCPY(keyword, kwp, kwlen + 1);
keyentry_T *kp = NULL;
@@ -3003,12 +3019,19 @@ static void syn_cmd_conceal(exarg_T *eap, int syncing)
return;
next = skiptowhite(arg);
- if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2)
- curwin->w_s->b_syn_conceal = TRUE;
- else if (STRNICMP(arg, "off", 3) == 0 && next - arg == 3)
- curwin->w_s->b_syn_conceal = FALSE;
- else
+ if (*arg == NUL) {
+ if (curwin->w_s->b_syn_conceal) {
+ MSG(_("syntax conceal on"));
+ } else {
+ MSG(_("syntax conceal off"));
+ }
+ } else if (STRNICMP(arg, "on", 2) == 0 && next - arg == 2) {
+ curwin->w_s->b_syn_conceal = true;
+ } else if (STRNICMP(arg, "off", 3) == 0 && next - arg == 3) {
+ curwin->w_s->b_syn_conceal = false;
+ } else {
EMSG2(_("E390: Illegal argument: %s"), arg);
+ }
}
/*
@@ -3024,12 +3047,19 @@ static void syn_cmd_case(exarg_T *eap, int syncing)
return;
next = skiptowhite(arg);
- if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5)
- curwin->w_s->b_syn_ic = FALSE;
- else if (STRNICMP(arg, "ignore", 6) == 0 && next - arg == 6)
- curwin->w_s->b_syn_ic = TRUE;
- else
+ if (*arg == NUL) {
+ if (curwin->w_s->b_syn_ic) {
+ MSG(_("syntax case ignore"));
+ } else {
+ MSG(_("syntax case match"));
+ }
+ } else if (STRNICMP(arg, "match", 5) == 0 && next - arg == 5) {
+ curwin->w_s->b_syn_ic = false;
+ } else if (STRNICMP(arg, "ignore", 6) == 0 && next - arg == 6) {
+ curwin->w_s->b_syn_ic = true;
+ } else {
EMSG2(_("E390: Illegal argument: %s"), arg);
+ }
}
/*
@@ -3045,7 +3075,15 @@ static void syn_cmd_spell(exarg_T *eap, int syncing)
return;
next = skiptowhite(arg);
- if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8) {
+ if (*arg == NUL) {
+ if (curwin->w_s->b_syn_spell == SYNSPL_TOP) {
+ MSG(_("syntax spell toplevel"));
+ } else if (curwin->w_s->b_syn_spell == SYNSPL_NOTOP) {
+ MSG(_("syntax spell notoplevel"));
+ } else {
+ MSG(_("syntax spell default"));
+ }
+ } else if (STRNICMP(arg, "toplevel", 8) == 0 && next - arg == 8) {
curwin->w_s->b_syn_spell = SYNSPL_TOP;
} else if (STRNICMP(arg, "notoplevel", 10) == 0 && next - arg == 10) {
curwin->w_s->b_syn_spell = SYNSPL_NOTOP;
@@ -3105,10 +3143,11 @@ static void syn_cmd_iskeyword(exarg_T *eap, int syncing)
*/
void syntax_clear(synblock_T *block)
{
- block->b_syn_error = FALSE; /* clear previous error */
- block->b_syn_ic = FALSE; /* Use case, by default */
- block->b_syn_spell = SYNSPL_DEFAULT; /* default spell checking */
- block->b_syn_containedin = FALSE;
+ block->b_syn_error = false; // clear previous error
+ block->b_syn_ic = false; // Use case, by default
+ block->b_syn_spell = SYNSPL_DEFAULT; // default spell checking
+ block->b_syn_containedin = false;
+ block->b_syn_conceal = false;
/* free the keywords */
clear_keywtab(&block->b_keywtab);
@@ -3258,9 +3297,10 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
syntax_sync_clear();
else {
syntax_clear(curwin->w_s);
- if (curwin->w_s == &curwin->w_buffer->b_s)
- do_unlet((char_u *)"b:current_syntax", TRUE);
- do_unlet((char_u *)"w:current_syntax", TRUE);
+ if (curwin->w_s == &curwin->w_buffer->b_s) {
+ do_unlet(S_LEN("b:current_syntax"), true);
+ }
+ do_unlet(S_LEN("w:current_syntax"), true);
}
} else {
/*
@@ -3274,12 +3314,10 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
EMSG2(_("E391: No such syntax cluster: %s"), arg);
break;
} else {
- /*
- * We can't physically delete a cluster without changing
- * the IDs of other clusters, so we do the next best thing
- * and make it empty.
- */
- short scl_id = id - SYNID_CLUSTER;
+ // We can't physically delete a cluster without changing
+ // the IDs of other clusters, so we do the next best thing
+ // and make it empty.
+ int scl_id = id - SYNID_CLUSTER;
xfree(SYN_CLSTR(curwin->w_s)[scl_id].scl_list);
SYN_CLSTR(curwin->w_s)[scl_id].scl_list = NULL;
@@ -3302,7 +3340,7 @@ static void syn_cmd_clear(exarg_T *eap, int syncing)
/*
* Clear one syntax group for the current buffer.
*/
-static void syn_clear_one(int id, int syncing)
+static void syn_clear_one(const int id, const bool syncing)
{
synpat_T *spp;
@@ -3336,7 +3374,7 @@ static void syn_cmd_enable(exarg_T *eap, int syncing)
{
set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"enable");
syn_cmd_onoff(eap, "syntax");
- do_unlet((char_u *)"g:syntax_cmd", TRUE);
+ do_unlet(S_LEN("g:syntax_cmd"), true);
}
/*
@@ -3349,7 +3387,7 @@ static void syn_cmd_reset(exarg_T *eap, int syncing)
if (!eap->skip) {
set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset");
do_cmdline_cmd("runtime! syntax/syncolor.vim");
- do_unlet((char_u *)"g:syntax_cmd", TRUE);
+ do_unlet(S_LEN("g:syntax_cmd"), true);
}
}
@@ -3372,11 +3410,11 @@ static void syn_cmd_off(exarg_T *eap, int syncing)
static void syn_cmd_onoff(exarg_T *eap, char *name)
FUNC_ATTR_NONNULL_ALL
{
- did_syntax_onoff = true;
eap->nextcmd = check_nextcmd(eap->arg);
if (!eap->skip) {
+ did_syntax_onoff = true;
char buf[100];
- strncpy(buf, "so ", 4);
+ memcpy(buf, "so ", 4);
vim_snprintf(buf + 3, sizeof(buf) - 3, SYNTAX_FNAME, name);
do_cmdline_cmd(buf);
}
@@ -3395,8 +3433,8 @@ void syn_maybe_on(void)
/*
* Handle ":syntax [list]" command: list current syntax words.
*/
-static void
-syn_cmd_list (
+static void
+syn_cmd_list(
exarg_T *eap,
int syncing /* when TRUE: list syncing items */
)
@@ -3444,8 +3482,8 @@ syn_cmd_list (
/*
* No argument: List all group IDs and all syntax clusters.
*/
- for (int id = 1; id <= highlight_ga.ga_len && !got_int; ++id) {
- syn_list_one(id, syncing, FALSE);
+ for (int id = 1; id <= highlight_ga.ga_len && !got_int; id++) {
+ syn_list_one(id, syncing, false);
}
for (int id = 0; id < curwin->w_s->b_syn_clusters.ga_len && !got_int; ++id) {
syn_list_cluster(id);
@@ -3464,10 +3502,11 @@ syn_cmd_list (
syn_list_cluster(id - SYNID_CLUSTER);
} else {
int id = syn_namen2id(arg, (int)(arg_end - arg));
- if (id == 0)
+ if (id == 0) {
EMSG2(_(e_nogroup), arg);
- else
- syn_list_one(id, syncing, TRUE);
+ } else {
+ syn_list_one(id, syncing, true);
+ }
}
arg = skipwhite(arg_end);
}
@@ -3509,16 +3548,14 @@ static int last_matchgroup;
/*
* List one syntax item, for ":syntax" or "syntax list syntax_name".
*/
-static void
-syn_list_one (
- int id,
- int syncing, /* when TRUE: list syncing items */
- int link_only /* when TRUE; list link-only too */
+static void
+syn_list_one(
+ const int id,
+ const bool syncing, // when true: list syncing items
+ const bool link_only // when true; list link-only too
)
{
- int attr;
- int did_header = FALSE;
- synpat_T *spp;
+ bool did_header = false;
static struct name_list namelist1[] =
{
{HL_DISPLAY, "display"},
@@ -3541,23 +3578,26 @@ syn_list_one (
{0, NULL}
};
- attr = hl_attr(HLF_D); /* highlight like directories */
+ const int attr = HL_ATTR(HLF_D); // highlight like directories
- /* list the keywords for "id" */
+ // list the keywords for "id"
if (!syncing) {
- did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, FALSE, attr);
+ did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab, false, attr);
did_header = syn_list_keywords(id, &curwin->w_s->b_keywtab_ic,
- did_header, attr);
+ did_header, attr);
}
- /* list the patterns for "id" */
- for (int idx = 0; idx < curwin->w_s->b_syn_patterns.ga_len && !got_int; ++idx) {
- spp = &(SYN_ITEMS(curwin->w_s)[idx]);
- if (spp->sp_syn.id != id || spp->sp_syncing != syncing)
+ // list the patterns for "id"
+ for (int idx = 0;
+ idx < curwin->w_s->b_syn_patterns.ga_len && !got_int;
+ idx++) {
+ const synpat_T *const spp = &(SYN_ITEMS(curwin->w_s)[idx]);
+ if (spp->sp_syn.id != id || spp->sp_syncing != syncing) {
continue;
+ }
(void)syn_list_header(did_header, 999, id);
- did_header = TRUE;
+ did_header = true;
last_matchgroup = 0;
if (spp->sp_type == SPTYPE_MATCH) {
put_pattern("match", ' ', spp, attr);
@@ -3575,22 +3615,24 @@ syn_list_one (
}
syn_list_flags(namelist1, spp->sp_flags, attr);
- if (spp->sp_cont_list != NULL)
- put_id_list((char_u *)"contains", spp->sp_cont_list, attr);
+ if (spp->sp_cont_list != NULL) {
+ put_id_list("contains", spp->sp_cont_list, attr);
+ }
- if (spp->sp_syn.cont_in_list != NULL)
- put_id_list((char_u *)"containedin",
- spp->sp_syn.cont_in_list, attr);
+ if (spp->sp_syn.cont_in_list != NULL) {
+ put_id_list("containedin", spp->sp_syn.cont_in_list, attr);
+ }
if (spp->sp_next_list != NULL) {
- put_id_list((char_u *)"nextgroup", spp->sp_next_list, attr);
+ put_id_list("nextgroup", spp->sp_next_list, attr);
syn_list_flags(namelist2, spp->sp_flags, attr);
}
if (spp->sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE)) {
- if (spp->sp_flags & HL_SYNC_HERE)
- msg_puts_attr((char_u *)"grouphere", attr);
- else
- msg_puts_attr((char_u *)"groupthere", attr);
+ if (spp->sp_flags & HL_SYNC_HERE) {
+ msg_puts_attr("grouphere", attr);
+ } else {
+ msg_puts_attr("groupthere", attr);
+ }
msg_putchar(' ');
if (spp->sp_sync_idx >= 0)
msg_outtrans(HL_TABLE()[SYN_ITEMS(curwin->w_s)
@@ -3604,7 +3646,7 @@ syn_list_one (
/* list the link, if there is one */
if (HL_TABLE()[id - 1].sg_link && (did_header || link_only) && !got_int) {
(void)syn_list_header(did_header, 999, id);
- msg_puts_attr((char_u *)"links to", attr);
+ msg_puts_attr("links to", attr);
msg_putchar(' ');
msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
}
@@ -3616,7 +3658,7 @@ static void syn_list_flags(struct name_list *nlist, int flags, int attr)
for (i = 0; nlist[i].flag != 0; ++i)
if (flags & nlist[i].flag) {
- msg_puts_attr((char_u *)nlist[i].name, attr);
+ msg_puts_attr(nlist[i].name, attr);
msg_putchar(' ');
}
}
@@ -3639,32 +3681,32 @@ static void syn_list_cluster(int id)
msg_advance(endcol);
if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL) {
- put_id_list((char_u *)"cluster", SYN_CLSTR(curwin->w_s)[id].scl_list,
- hl_attr(HLF_D));
+ put_id_list("cluster", SYN_CLSTR(curwin->w_s)[id].scl_list, HL_ATTR(HLF_D));
} else {
- msg_puts_attr((char_u *)"cluster", hl_attr(HLF_D));
- msg_puts((char_u *)"=NONE");
+ msg_puts_attr("cluster", HL_ATTR(HLF_D));
+ msg_puts("=NONE");
}
}
-static void put_id_list(char_u *name, short *list, int attr)
+static void put_id_list(const char *const name,
+ const int16_t *const list,
+ const int attr)
{
- short *p;
-
msg_puts_attr(name, attr);
msg_putchar('=');
- for (p = list; *p; ++p) {
+ for (const int16_t *p = list; *p; p++) {
if (*p >= SYNID_ALLBUT && *p < SYNID_TOP) {
- if (p[1])
- MSG_PUTS("ALLBUT");
- else
- MSG_PUTS("ALL");
+ if (p[1]) {
+ msg_puts("ALLBUT");
+ } else {
+ msg_puts("ALL");
+ }
} else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED) {
- MSG_PUTS("TOP");
+ msg_puts("TOP");
} else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) {
- MSG_PUTS("CONTAINED");
+ msg_puts("CONTAINED");
} else if (*p >= SYNID_CLUSTER) {
- short scl_id = *p - SYNID_CLUSTER;
+ int scl_id = *p - SYNID_CLUSTER;
msg_putchar('@');
msg_outtrans(SYN_CLSTR(curwin->w_s)[scl_id].scl_name);
@@ -3676,18 +3718,16 @@ static void put_id_list(char_u *name, short *list, int attr)
msg_putchar(' ');
}
-static void put_pattern(char *s, int c, synpat_T *spp, int attr)
+static void put_pattern(const char *const s, const int c,
+ const synpat_T *const spp, const int attr)
{
- long n;
- int mask;
- int first;
- static char *sepchars = "/+=-#@\"|'^&";
+ static const char *const sepchars = "/+=-#@\"|'^&";
int i;
/* May have to write "matchgroup=group" */
if (last_matchgroup != spp->sp_syn_match_id) {
last_matchgroup = spp->sp_syn_match_id;
- msg_puts_attr((char_u *)"matchgroup", attr);
+ msg_puts_attr("matchgroup", attr);
msg_putchar('=');
if (last_matchgroup == 0)
msg_outtrans((char_u *)"NONE");
@@ -3696,8 +3736,8 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
msg_putchar(' ');
}
- /* output the name of the pattern and an '=' or ' ' */
- msg_puts_attr((char_u *)s, attr);
+ // Output the name of the pattern and an '=' or ' '.
+ msg_puts_attr(s, attr);
msg_putchar(c);
/* output the pattern, in between a char that is not in the pattern */
@@ -3710,17 +3750,18 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
msg_outtrans(spp->sp_pattern);
msg_putchar(sepchars[i]);
- /* output any pattern options */
- first = TRUE;
- for (i = 0; i < SPO_COUNT; ++i) {
- mask = (1 << i);
+ // output any pattern options
+ bool first = true;
+ for (i = 0; i < SPO_COUNT; i++) {
+ const int mask = (1 << i);
if (!(spp->sp_off_flags & (mask + (mask << SPO_COUNT)))) {
continue;
}
- if (!first)
- msg_putchar(','); /* separate with commas */
- msg_puts((char_u *)spo_name_tab[i]);
- n = spp->sp_offsets[i];
+ if (!first) {
+ msg_putchar(','); // Separate with commas.
+ }
+ msg_puts(spo_name_tab[i]);
+ const long n = spp->sp_offsets[i];
if (i != SPO_LC_OFF) {
if (spp->sp_off_flags & mask)
msg_putchar('s');
@@ -3729,47 +3770,40 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr)
if (n > 0)
msg_putchar('+');
}
- if (n || i == SPO_LC_OFF)
+ if (n || i == SPO_LC_OFF) {
msg_outnum(n);
- first = FALSE;
+ }
+ first = false;
}
msg_putchar(' ');
}
-/*
- * List or clear the keywords for one syntax group.
- * Return TRUE if the header has been printed.
- */
-static int
-syn_list_keywords (
- int id,
- hashtab_T *ht,
- int did_header, /* header has already been printed */
- int attr
+// List or clear the keywords for one syntax group.
+// Return true if the header has been printed.
+static bool syn_list_keywords(
+ const int id,
+ const hashtab_T *const ht,
+ bool did_header, // header has already been printed
+ const int attr
)
{
int outlen;
- hashitem_T *hi;
- keyentry_T *kp;
- int todo;
int prev_contained = 0;
- short *prev_next_list = NULL;
- short *prev_cont_in_list = NULL;
+ const int16_t *prev_next_list = NULL;
+ const int16_t *prev_cont_in_list = NULL;
int prev_skipnl = 0;
int prev_skipwhite = 0;
int prev_skipempty = 0;
- /*
- * Unfortunately, this list of keywords is not sorted on alphabet but on
- * hash value...
- */
- todo = (int)ht->ht_used;
- for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) {
+ // Unfortunately, this list of keywords is not sorted on alphabet but on
+ // hash value...
+ size_t todo = ht->ht_used;
+ for (const hashitem_T *hi = ht->ht_array; todo > 0 && !got_int; hi++) {
if (HASHITEM_EMPTY(hi)) {
continue;
}
- --todo;
- for (kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next) {
+ todo--;
+ for (keyentry_T *kp = HI2KE(hi); kp != NULL && !got_int; kp = kp->ke_next) {
if (kp->k_syn.id == id) {
if (prev_contained != (kp->flags & HL_CONTAINED)
|| prev_skipnl != (kp->flags & HL_SKIPNL)
@@ -3789,34 +3823,33 @@ syn_list_keywords (
prev_skipwhite = 0;
prev_skipempty = 0;
}
- did_header = TRUE;
+ did_header = true;
if (prev_contained != (kp->flags & HL_CONTAINED)) {
- msg_puts_attr((char_u *)"contained", attr);
+ msg_puts_attr("contained", attr);
msg_putchar(' ');
prev_contained = (kp->flags & HL_CONTAINED);
}
if (kp->k_syn.cont_in_list != prev_cont_in_list) {
- put_id_list((char_u *)"containedin",
- kp->k_syn.cont_in_list, attr);
+ put_id_list("containedin", kp->k_syn.cont_in_list, attr);
msg_putchar(' ');
prev_cont_in_list = kp->k_syn.cont_in_list;
}
if (kp->next_list != prev_next_list) {
- put_id_list((char_u *)"nextgroup", kp->next_list, attr);
+ put_id_list("nextgroup", kp->next_list, attr);
msg_putchar(' ');
prev_next_list = kp->next_list;
if (kp->flags & HL_SKIPNL) {
- msg_puts_attr((char_u *)"skipnl", attr);
+ msg_puts_attr("skipnl", attr);
msg_putchar(' ');
prev_skipnl = (kp->flags & HL_SKIPNL);
}
if (kp->flags & HL_SKIPWHITE) {
- msg_puts_attr((char_u *)"skipwhite", attr);
+ msg_puts_attr("skipwhite", attr);
msg_putchar(' ');
prev_skipwhite = (kp->flags & HL_SKIPWHITE);
}
if (kp->flags & HL_SKIPEMPTY) {
- msg_puts_attr((char_u *)"skipempty", attr);
+ msg_puts_attr("skipempty", attr);
msg_putchar(' ');
prev_skipempty = (kp->flags & HL_SKIPEMPTY);
}
@@ -3901,19 +3934,19 @@ static void clear_keywtab(hashtab_T *ht)
/// @param flags flags for this keyword
/// @param cont_in_list containedin for this keyword
/// @param next_list nextgroup for this keyword
-static void add_keyword(char_u *name,
- int id,
- int flags,
- short *cont_in_list,
- short *next_list,
- int conceal_char)
+static void add_keyword(char_u *const name,
+ const int id,
+ const int flags,
+ int16_t *const cont_in_list,
+ int16_t *const next_list,
+ const int conceal_char)
{
char_u name_folded[MAXKEYWLEN + 1];
- char_u *name_ic = (curwin->w_s->b_syn_ic)
- ? str_foldcase(name, (int)STRLEN(name), name_folded, sizeof(name_folded))
- : name;
+ const char_u *const name_ic = (curwin->w_s->b_syn_ic)
+ ? str_foldcase(name, (int)STRLEN(name), name_folded, sizeof(name_folded))
+ : name;
- keyentry_T *kp = xmalloc(sizeof(keyentry_T) + STRLEN(name_ic));
+ keyentry_T *const kp = xmalloc(sizeof(keyentry_T) + STRLEN(name_ic));
STRCPY(kp->keyword, name_ic);
kp->k_syn.id = id;
kp->k_syn.inc_tag = current_syn_inc_tag;
@@ -3925,10 +3958,12 @@ static void add_keyword(char_u *name,
}
kp->next_list = copy_id_list(next_list);
- hash_T hash = hash_hash(kp->keyword);
- hashtab_T *ht = (curwin->w_s->b_syn_ic) ? &curwin->w_s->b_keywtab_ic
- : &curwin->w_s->b_keywtab;
- hashitem_T *hi = hash_lookup(ht, kp->keyword, hash);
+ const hash_T hash = hash_hash(kp->keyword);
+ hashtab_T *const ht = (curwin->w_s->b_syn_ic)
+ ? &curwin->w_s->b_keywtab_ic
+ : &curwin->w_s->b_keywtab;
+ hashitem_T *const hi = hash_lookup(ht, (const char *)kp->keyword,
+ STRLEN(kp->keyword), hash);
// even though it looks like only the kp->keyword member is
// being used here, vim uses some pointer trickery to get the orignal
@@ -3979,18 +4014,19 @@ get_group_name (
* Return NULL for any error;
*/
static char_u *
-get_syn_options (
- char_u *arg, /* next argument to be checked */
- syn_opt_arg_T *opt, /* various things */
- int *conceal_char
+get_syn_options(
+ char_u *arg, // next argument to be checked
+ syn_opt_arg_T *opt, // various things
+ int *conceal_char,
+ int skip // TRUE if skipping over command
)
{
char_u *gname_start, *gname;
int syn_id;
- int len;
+ int len = 0;
char *p;
int fidx;
- static struct flag {
+ static const struct flag {
char *name;
int argtype;
int flags;
@@ -4013,7 +4049,7 @@ get_syn_options (
{"cCoOnNtTaAiInNsS", 1, 0},
{"cCoOnNtTaAiInNeEdDiInN", 2, 0},
{"nNeExXtTgGrRoOuUpP", 3, 0},};
- static char *first_letters = "cCoOkKeEtTsSgGdDfFnN";
+ static const char *const first_letters = "cCoOkKeEtTsSgGdDfFnN";
if (arg == NULL) /* already detected error */
return NULL;
@@ -4033,9 +4069,10 @@ get_syn_options (
for (fidx = ARRAY_SIZE(flagtab); --fidx >= 0; ) {
p = flagtab[fidx].name;
int i;
- for (i = 0, len = 0; p[i] != NUL; i += 2, ++len)
+ for (i = 0, len = 0; p[i] != NUL; i += 2, ++len) {
if (arg[len] != p[i] && arg[len] != p[i + 1])
break;
+ }
if (p[i] == NUL && (ascii_iswhite(arg[len])
|| (flagtab[fidx].argtype > 0
? arg[len] == '='
@@ -4057,22 +4094,21 @@ get_syn_options (
EMSG(_("E395: contains argument not accepted here"));
return NULL;
}
- if (get_id_list(&arg, 8, &opt->cont_list) == FAIL)
+ if (get_id_list(&arg, 8, &opt->cont_list, skip) == FAIL) {
return NULL;
+ }
} else if (flagtab[fidx].argtype == 2) {
- if (get_id_list(&arg, 11, &opt->cont_in_list) == FAIL)
+ if (get_id_list(&arg, 11, &opt->cont_in_list, skip) == FAIL) {
return NULL;
+ }
} else if (flagtab[fidx].argtype == 3) {
- if (get_id_list(&arg, 9, &opt->next_list) == FAIL)
+ if (get_id_list(&arg, 9, &opt->next_list, skip) == FAIL) {
return NULL;
- } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') {
- /* cchar=? */
- if (has_mbyte) {
- *conceal_char = mb_ptr2char(arg + 6);
- arg += mb_ptr2len(arg + 6) - 1;
- } else {
- *conceal_char = arg[6];
}
+ } else if (flagtab[fidx].argtype == 11 && arg[5] == '=') {
+ // cchar=?
+ *conceal_char = utf_ptr2char(arg + 6);
+ arg += mb_ptr2len(arg + 6) - 1;
if (!vim_isprintc_strict(*conceal_char)) {
EMSG(_("E844: invalid cchar value"));
return NULL;
@@ -4134,8 +4170,8 @@ static void syn_incl_toplevel(int id, int *flagsp)
return;
*flagsp |= HL_CONTAINED;
if (curwin->w_s->b_syn_topgrp >= SYNID_CLUSTER) {
- /* We have to alloc this, because syn_combine_list() will free it. */
- short *grp_list = xmalloc(2 * sizeof(short));
+ // We have to alloc this, because syn_combine_list() will free it.
+ int16_t *grp_list = xmalloc(2 * sizeof(*grp_list));
int tlg_id = curwin->w_s->b_syn_topgrp - SYNID_CLUSTER;
grp_list[0] = id;
@@ -4183,11 +4219,11 @@ static void syn_cmd_include(exarg_T *eap, int syncing)
*/
eap->argt |= (XFILE | NOSPC);
separate_nextcmd(eap);
- if (*eap->arg == '<' || *eap->arg == '$' || path_is_absolute_path(eap->arg)) {
- /* For an absolute path, "$VIM/..." or "<sfile>.." we ":source" the
- * file. Need to expand the file name first. In other cases
- * ":runtime!" is used. */
- source = TRUE;
+ if (*eap->arg == '<' || *eap->arg == '$' || path_is_absolute(eap->arg)) {
+ // For an absolute path, "$VIM/..." or "<sfile>.." we ":source" the
+ // file. Need to expand the file name first. In other cases
+ // ":runtime!" is used.
+ source = true;
if (expand_filename(eap, syn_cmdlinep, &errormsg) == FAIL) {
if (errormsg != NULL)
EMSG(errormsg);
@@ -4234,84 +4270,86 @@ static void syn_cmd_keyword(exarg_T *eap, int syncing)
rest = get_group_name(arg, &group_name_end);
if (rest != NULL) {
- syn_id = syn_check_group(arg, (int)(group_name_end - arg));
- if (syn_id != 0)
- /* allocate a buffer, for removing backslashes in the keyword */
+ if (eap->skip) {
+ syn_id = -1;
+ } else {
+ syn_id = syn_check_group(arg, (int)(group_name_end - arg));
+ }
+ if (syn_id != 0) {
+ // Allocate a buffer, for removing backslashes in the keyword.
keyword_copy = xmalloc(STRLEN(rest) + 1);
- syn_opt_arg.flags = 0;
- syn_opt_arg.keyword = TRUE;
- syn_opt_arg.sync_idx = NULL;
- syn_opt_arg.has_cont_list = FALSE;
- syn_opt_arg.cont_in_list = NULL;
- syn_opt_arg.next_list = NULL;
-
- /*
- * The options given apply to ALL keywords, so all options must be
- * found before keywords can be created.
- * 1: collect the options and copy the keywords to keyword_copy.
- */
- cnt = 0;
- p = keyword_copy;
- for (; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest)) {
- rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
- if (rest == NULL || ends_excmd(*rest))
- break;
- /* Copy the keyword, removing backslashes, and add a NUL. */
- while (*rest != NUL && !ascii_iswhite(*rest)) {
- if (*rest == '\\' && rest[1] != NUL)
- ++rest;
- *p++ = *rest++;
- }
- *p++ = NUL;
- ++cnt;
}
+ if (keyword_copy != NULL) {
+ syn_opt_arg.flags = 0;
+ syn_opt_arg.keyword = true;
+ syn_opt_arg.sync_idx = NULL;
+ syn_opt_arg.has_cont_list = false;
+ syn_opt_arg.cont_in_list = NULL;
+ syn_opt_arg.next_list = NULL;
+
+ // The options given apply to ALL keywords, so all options must be
+ // found before keywords can be created.
+ // 1: collect the options and copy the keywords to keyword_copy.
+ cnt = 0;
+ p = keyword_copy;
+ for (; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest)) {
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
+ if (rest == NULL || ends_excmd(*rest)) {
+ break;
+ }
+ // Copy the keyword, removing backslashes, and add a NUL.
+ while (*rest != NUL && !ascii_iswhite(*rest)) {
+ if (*rest == '\\' && rest[1] != NUL) {
+ rest++;
+ }
+ *p++ = *rest++;
+ }
+ *p++ = NUL;
+ cnt++;
+ }
- if (!eap->skip) {
- /* Adjust flags for use of ":syn include". */
- syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
+ if (!eap->skip) {
+ // Adjust flags for use of ":syn include".
+ syn_incl_toplevel(syn_id, &syn_opt_arg.flags);
- /*
- * 2: Add an entry for each keyword.
- */
- for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) {
- for (p = vim_strchr(kw, '[');; ) {
- if (p != NULL)
- *p = NUL;
- add_keyword(kw, syn_id, syn_opt_arg.flags,
- syn_opt_arg.cont_in_list,
- syn_opt_arg.next_list, conceal_char);
- if (p == NULL)
- break;
- if (p[1] == NUL) {
- EMSG2(_("E789: Missing ']': %s"), kw);
- goto error;
- }
- if (p[1] == ']') {
- if (p[2] != NUL) {
- EMSG3(_("E890: trailing char after ']': %s]%s"),
- kw, &p[2]);
+ // 2: Add an entry for each keyword.
+ for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) {
+ for (p = vim_strchr(kw, '[');; ) {
+ if (p != NULL) {
+ *p = NUL;
+ }
+ add_keyword(kw, syn_id, syn_opt_arg.flags,
+ syn_opt_arg.cont_in_list,
+ syn_opt_arg.next_list, conceal_char);
+ if (p == NULL) {
+ break;
+ }
+ if (p[1] == NUL) {
+ emsgf(_("E789: Missing ']': %s"), kw);
goto error;
}
- kw = p + 1;
- break; // skip over the "]"
- }
- if (has_mbyte) {
- int l = (*mb_ptr2len)(p + 1);
+ if (p[1] == ']') {
+ if (p[2] != NUL) {
+ emsgf(_("E890: trailing char after ']': %s]%s"),
+ kw, &p[2]);
+ goto error;
+ }
+ kw = p + 1;
+ break; // skip over the "]"
+ }
+ const int l = (*mb_ptr2len)(p + 1);
memmove(p, p + 1, l);
p += l;
- } else {
- p[0] = p[1];
- ++p;
}
}
}
- }
error:
- xfree(keyword_copy);
- xfree(syn_opt_arg.cont_in_list);
- xfree(syn_opt_arg.next_list);
+ xfree(keyword_copy);
+ xfree(syn_opt_arg.cont_in_list);
+ xfree(syn_opt_arg.next_list);
+ }
}
if (rest != NULL)
@@ -4328,8 +4366,8 @@ error:
*
* Also ":syntax sync match {name} [[grouphere | groupthere] {group-name}] .."
*/
-static void
-syn_cmd_match (
+static void
+syn_cmd_match(
exarg_T *eap,
int syncing /* TRUE for ":syntax sync match .. " */
)
@@ -4348,23 +4386,24 @@ syn_cmd_match (
/* Get options before the pattern */
syn_opt_arg.flags = 0;
- syn_opt_arg.keyword = FALSE;
+ syn_opt_arg.keyword = false;
syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL;
- syn_opt_arg.has_cont_list = TRUE;
+ syn_opt_arg.has_cont_list = true;
syn_opt_arg.cont_list = NULL;
syn_opt_arg.cont_in_list = NULL;
syn_opt_arg.next_list = NULL;
- rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
/* get the pattern. */
init_syn_patterns();
memset(&item, 0, sizeof(item));
rest = get_syn_pattern(rest, &item);
- if (vim_regcomp_had_eol() && !(syn_opt_arg.flags & HL_EXCLUDENL))
+ if (vim_regcomp_had_eol() && !(syn_opt_arg.flags & HL_EXCLUDENL)) {
syn_opt_arg.flags |= HL_HAS_EOL;
+ }
- /* Get options after the pattern */
- rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
+ // Get options after the pattern
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
if (rest != NULL) { /* all arguments are valid */
/*
@@ -4425,8 +4464,8 @@ syn_cmd_match (
* Handle ":syntax region {group-name} [matchgroup={group-name}]
* start {start} .. [skip {skip}] end {end} .. [{options}]".
*/
-static void
-syn_cmd_region (
+static void
+syn_cmd_region(
exarg_T *eap,
int syncing /* TRUE for ":syntax sync region .." */
)
@@ -4469,21 +4508,20 @@ syn_cmd_region (
init_syn_patterns();
syn_opt_arg.flags = 0;
- syn_opt_arg.keyword = FALSE;
+ syn_opt_arg.keyword = false;
syn_opt_arg.sync_idx = NULL;
- syn_opt_arg.has_cont_list = TRUE;
+ syn_opt_arg.has_cont_list = true;
syn_opt_arg.cont_list = NULL;
syn_opt_arg.cont_in_list = NULL;
syn_opt_arg.next_list = NULL;
- /*
- * get the options, patterns and matchgroup.
- */
+ // get the options, patterns and matchgroup.
while (rest != NULL && !ends_excmd(*rest)) {
- /* Check for option arguments */
- rest = get_syn_options(rest, &syn_opt_arg, &conceal_char);
- if (rest == NULL || ends_excmd(*rest))
+ // Check for option arguments
+ rest = get_syn_options(rest, &syn_opt_arg, &conceal_char, eap->skip);
+ if (rest == NULL || ends_excmd(*rest)) {
break;
+ }
/* must be a pattern or matchgroup then */
key_end = rest;
@@ -4491,20 +4529,21 @@ syn_cmd_region (
++key_end;
xfree(key);
key = vim_strnsave_up(rest, (int)(key_end - rest));
- if (STRCMP(key, "MATCHGROUP") == 0)
+ if (STRCMP(key, "MATCHGROUP") == 0) {
item = ITEM_MATCHGROUP;
- else if (STRCMP(key, "START") == 0)
+ } else if (STRCMP(key, "START") == 0) {
item = ITEM_START;
- else if (STRCMP(key, "END") == 0)
+ } else if (STRCMP(key, "END") == 0) {
item = ITEM_END;
- else if (STRCMP(key, "SKIP") == 0) {
- if (pat_ptrs[ITEM_SKIP] != NULL) { /* one skip pattern allowed */
- illegal = TRUE;
+ } else if (STRCMP(key, "SKIP") == 0) {
+ if (pat_ptrs[ITEM_SKIP] != NULL) { // One skip pattern allowed.
+ illegal = true;
break;
}
item = ITEM_SKIP;
- } else
+ } else {
break;
+ }
rest = skipwhite(key_end);
if (*rest != '=') {
rest = NULL;
@@ -4540,21 +4579,23 @@ syn_cmd_region (
pat_ptrs[item] = ppp;
ppp->pp_synp = xcalloc(1, sizeof(synpat_T));
- /*
- * Get the syntax pattern and the following offset(s).
- */
- /* Enable the appropriate \z specials. */
- if (item == ITEM_START)
+ // Get the syntax pattern and the following offset(s).
+
+ // Enable the appropriate \z specials.
+ if (item == ITEM_START) {
reg_do_extmatch = REX_SET;
- else if (item == ITEM_SKIP || item == ITEM_END)
+ } else {
+ assert(item == ITEM_SKIP || item == ITEM_END);
reg_do_extmatch = REX_USE;
+ }
rest = get_syn_pattern(rest, ppp->pp_synp);
reg_do_extmatch = 0;
if (item == ITEM_END && vim_regcomp_had_eol()
- && !(syn_opt_arg.flags & HL_EXCLUDENL))
+ && !(syn_opt_arg.flags & HL_EXCLUDENL)) {
ppp->pp_synp->sp_flags |= HL_HAS_EOL;
+ }
ppp->pp_matchgroup_id = matchgroup_id;
- ++pat_count;
+ pat_count++;
}
}
xfree(key);
@@ -4647,30 +4688,25 @@ syn_cmd_region (
}
}
-/*
- * A simple syntax group ID comparison function suitable for use in qsort()
- */
-static int syn_compare_stub(const void *v1, const void *v2)
+// A simple syntax group ID comparison function suitable for use in qsort()
+static int syn_compare_stub(const void *const v1, const void *const v2)
{
- const short *s1 = v1;
- const short *s2 = v2;
+ const int16_t *const s1 = v1;
+ const int16_t *const s2 = v2;
return *s1 > *s2 ? 1 : *s1 < *s2 ? -1 : 0;
}
-/*
- * Combines lists of syntax clusters.
- * *clstr1 and *clstr2 must both be allocated memory; they will be consumed.
- */
-static void syn_combine_list(short **clstr1, short **clstr2, int list_op)
+// Combines lists of syntax clusters.
+// *clstr1 and *clstr2 must both be allocated memory; they will be consumed.
+static void syn_combine_list(int16_t **const clstr1, int16_t **const clstr2,
+ const int list_op)
{
- int count1 = 0;
- int count2 = 0;
- short *g1;
- short *g2;
- short *clstr = NULL;
- int count;
- int round;
+ size_t count1 = 0;
+ size_t count2 = 0;
+ const int16_t *g1;
+ const int16_t *g2;
+ int16_t *clstr = NULL;
/*
* Handle degenerate cases.
@@ -4687,27 +4723,25 @@ static void syn_combine_list(short **clstr1, short **clstr2, int list_op)
return;
}
- for (g1 = *clstr1; *g1; g1++)
- ++count1;
- for (g2 = *clstr2; *g2; g2++)
- ++count2;
+ for (g1 = *clstr1; *g1; g1++) {
+ count1++;
+ }
+ for (g2 = *clstr2; *g2; g2++) {
+ count2++;
+ }
- /*
- * For speed purposes, sort both lists.
- */
- qsort(*clstr1, (size_t)count1, sizeof(short), syn_compare_stub);
- qsort(*clstr2, (size_t)count2, sizeof(short), syn_compare_stub);
+ // For speed purposes, sort both lists.
+ qsort(*clstr1, count1, sizeof(**clstr1), syn_compare_stub);
+ qsort(*clstr2, count2, sizeof(**clstr2), syn_compare_stub);
- /*
- * We proceed in two passes; in round 1, we count the elements to place
- * in the new list, and in round 2, we allocate and populate the new
- * list. For speed, we use a mergesort-like method, adding the smaller
- * of the current elements in each list to the new list.
- */
- for (round = 1; round <= 2; round++) {
+ // We proceed in two passes; in round 1, we count the elements to place
+ // in the new list, and in round 2, we allocate and populate the new
+ // list. For speed, we use a mergesort-like method, adding the smaller
+ // of the current elements in each list to the new list.
+ for (int round = 1; round <= 2; round++) {
g1 = *clstr1;
g2 = *clstr2;
- count = 0;
+ int count = 0;
/*
* First, loop through the lists until one of them is empty.
@@ -4759,7 +4793,7 @@ static void syn_combine_list(short **clstr1, short **clstr2, int list_op)
clstr = NULL;
break;
}
- clstr = xmalloc((count + 1) * sizeof(short));
+ clstr = xmalloc((count + 1) * sizeof(*clstr));
clstr[count] = 0;
}
}
@@ -4772,10 +4806,8 @@ static void syn_combine_list(short **clstr1, short **clstr2, int list_op)
*clstr1 = clstr;
}
-/*
- * Lookup a syntax cluster name and return it's ID.
- * If it is not found, 0 is returned.
- */
+// Lookup a syntax cluster name and return its ID.
+// If it is not found, 0 is returned.
static int syn_scl_name2id(char_u *name)
{
// Avoid using stricmp() too much, it's slow on some systems
@@ -4803,12 +4835,10 @@ static int syn_scl_namen2id(char_u *linep, int len)
return id;
}
-/*
- * Find syntax cluster name in the table and return it's ID.
- * The argument is a pointer to the name and the length of the name.
- * If it doesn't exist yet, a new entry is created.
- * Return 0 for failure.
- */
+// Find syntax cluster name in the table and return its ID.
+// The argument is a pointer to the name and the length of the name.
+// If it doesn't exist yet, a new entry is created.
+// Return 0 for failure.
static int syn_check_cluster(char_u *pp, int len)
{
int id;
@@ -4824,11 +4854,9 @@ static int syn_check_cluster(char_u *pp, int len)
return id;
}
-/*
- * Add new syntax cluster and return it's ID.
- * "name" must be an allocated string, it will be consumed.
- * Return 0 for failure.
- */
+// Add new syntax cluster and return its ID.
+// "name" must be an allocated string, it will be consumed.
+// Return 0 for failure.
static int syn_add_cluster(char_u *name)
{
/*
@@ -4870,9 +4898,7 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing)
char_u *arg = eap->arg;
char_u *group_name_end;
char_u *rest;
- int scl_id;
- short *clstr_list;
- int got_clstr = FALSE;
+ bool got_clstr = false;
int opt_len;
int list_op;
@@ -4883,9 +4909,10 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing)
rest = get_group_name(arg, &group_name_end);
if (rest != NULL) {
- scl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
- if (scl_id == 0)
+ int scl_id = syn_check_cluster(arg, (int)(group_name_end - arg));
+ if (scl_id == 0) {
return;
+ }
scl_id -= SYNID_CLUSTER;
for (;; ) {
@@ -4904,14 +4931,18 @@ static void syn_cmd_cluster(exarg_T *eap, int syncing)
} else
break;
- clstr_list = NULL;
- if (get_id_list(&rest, opt_len, &clstr_list) == FAIL) {
+ int16_t *clstr_list = NULL;
+ if (get_id_list(&rest, opt_len, &clstr_list, eap->skip) == FAIL) {
EMSG2(_(e_invarg2), rest);
break;
}
- syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
- &clstr_list, list_op);
- got_clstr = TRUE;
+ if (scl_id >= 0) {
+ syn_combine_list(&SYN_CLSTR(curwin->w_s)[scl_id].scl_list,
+ &clstr_list, list_op);
+ } else {
+ xfree(clstr_list);
+ }
+ got_clstr = true;
}
if (got_clstr) {
@@ -5156,36 +5187,30 @@ static void syn_cmd_sync(exarg_T *eap, int syncing)
* Careful: the argument is modified (NULs added).
* returns FAIL for some error, OK for success.
*/
-static int
-get_id_list (
- char_u **arg,
- int keylen, /* length of keyword */
- short **list /* where to store the resulting list, if not
- NULL, the list is silently skipped! */
+static int
+get_id_list(
+ char_u **const arg,
+ const int keylen, // length of keyword
+ int16_t **const list, // where to store the resulting list, if not
+ // NULL, the list is silently skipped!
+ const bool skip
)
{
char_u *p = NULL;
char_u *end;
- int round;
- int count;
int total_count = 0;
- short *retval = NULL;
- char_u *name;
+ int16_t *retval = NULL;
regmatch_T regmatch;
int id;
- int failed = FALSE;
-
- /*
- * We parse the list twice:
- * round == 1: count the number of items, allocate the array.
- * round == 2: fill the array with the items.
- * In round 1 new groups may be added, causing the number of items to
- * grow when a regexp is used. In that case round 1 is done once again.
- */
- for (round = 1; round <= 2; ++round) {
- /*
- * skip "contains"
- */
+ bool failed = false;
+
+ // We parse the list twice:
+ // round == 1: count the number of items, allocate the array.
+ // round == 2: fill the array with the items.
+ // In round 1 new groups may be added, causing the number of items to
+ // grow when a regexp is used. In that case round 1 is done once again.
+ for (int round = 1; round <= 2; round++) {
+ // skip "contains"
p = skipwhite(*arg + keylen);
if (*p != '=') {
EMSG2(_("E405: Missing equal sign: %s"), *arg);
@@ -5197,14 +5222,12 @@ get_id_list (
break;
}
- /*
- * parse the arguments after "contains"
- */
- count = 0;
+ // parse the arguments after "contains"
+ int count = 0;
do {
- for (end = p; *end && !ascii_iswhite(*end) && *end != ','; ++end)
- ;
- name = xmalloc((int)(end - p + 3)); /* leave room for "^$" */
+ for (end = p; *end && !ascii_iswhite(*end) && *end != ','; end++) {
+ }
+ char_u *const name = xmalloc((int)(end - p + 3)); // leave room for "^$"
STRLCPY(name + 1, p, end - p + 1);
if ( STRCMP(name + 1, "ALLBUT") == 0
|| STRCMP(name + 1, "ALL") == 0
@@ -5212,13 +5235,14 @@ get_id_list (
|| STRCMP(name + 1, "CONTAINED") == 0) {
if (TOUPPER_ASC(**arg) != 'C') {
EMSG2(_("E407: %s not allowed here"), name + 1);
- failed = TRUE;
+ failed = true;
xfree(name);
break;
}
if (count != 0) {
- EMSG2(_("E408: %s must be first in contains list"), name + 1);
- failed = TRUE;
+ EMSG2(_("E408: %s must be first in contains list"),
+ name + 1);
+ failed = true;
xfree(name);
break;
}
@@ -5230,22 +5254,24 @@ get_id_list (
id = SYNID_CONTAINED;
id += current_syn_inc_tag;
} else if (name[1] == '@') {
- id = syn_check_cluster(name + 2, (int)(end - p - 1));
+ if (skip) {
+ id = -1;
+ } else {
+ id = syn_check_cluster(name + 2, (int)(end - p - 1));
+ }
} else {
/*
* Handle full group name.
*/
- if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL)
+ if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) {
id = syn_check_group(name + 1, (int)(end - p));
- else {
- /*
- * Handle match of regexp with group names.
- */
+ } else {
+ // Handle match of regexp with group names.
*name = '^';
STRCAT(name, "$");
regmatch.regprog = vim_regcomp(name, RE_MAGIC);
if (regmatch.regprog == NULL) {
- failed = TRUE;
+ failed = true;
xfree(name);
break;
}
@@ -5255,18 +5281,19 @@ get_id_list (
for (int i = highlight_ga.ga_len; --i >= 0; ) {
if (vim_regexec(&regmatch, HL_TABLE()[i].sg_name, (colnr_T)0)) {
if (round == 2) {
- /* Got more items than expected; can happen
- * when adding items that match:
- * "contains=a.*b,axb".
- * Go back to first round */
+ // Got more items than expected; can happen
+ // when adding items that match:
+ // "contains=a.*b,axb".
+ // Go back to first round.
if (count >= total_count) {
xfree(retval);
round = 1;
- } else
- retval[count] = i + 1;
+ } else {
+ retval[count] = i + 1; // -V522
+ }
}
- ++count;
- id = -1; /* remember that we found one */
+ count++;
+ id = -1; // Remember that we found one.
}
}
vim_regfree(regmatch.regprog);
@@ -5275,17 +5302,18 @@ get_id_list (
xfree(name);
if (id == 0) {
EMSG2(_("E409: Unknown group name: %s"), p);
- failed = TRUE;
+ failed = true;
break;
}
if (id > 0) {
if (round == 2) {
- /* Got more items than expected, go back to first round */
+ // Got more items than expected, go back to first round.
if (count >= total_count) {
xfree(retval);
round = 1;
- } else
+ } else {
retval[count] = id;
+ }
}
++count;
}
@@ -5297,8 +5325,8 @@ get_id_list (
if (failed)
break;
if (round == 1) {
- retval = xmalloc((count + 1) * sizeof(short));
- retval[count] = 0; /* zero means end of the list */
+ retval = xmalloc((count + 1) * sizeof(*retval));
+ retval[count] = 0; // zero means end of the list
total_count = count;
}
}
@@ -5320,20 +5348,18 @@ get_id_list (
/*
* Make a copy of an ID list.
*/
-static short *copy_id_list(short *list)
+static int16_t *copy_id_list(const int16_t *const list)
{
- int len;
- int count;
- short *retval;
-
- if (list == NULL)
+ if (list == NULL) {
return NULL;
+ }
- for (count = 0; list[count]; ++count)
- ;
- len = (count + 1) * sizeof(short);
- retval = xmalloc(len);
- memmove(retval, list, (size_t)len);
+ int count;
+ for (count = 0; list[count]; count++) {
+ }
+ const size_t len = (count + 1) * sizeof(int16_t);
+ int16_t *const retval = xmalloc(len);
+ memmove(retval, list, len);
return retval;
}
@@ -5345,18 +5371,18 @@ static short *copy_id_list(short *list)
* the current item.
* This function is called very often, keep it fast!!
*/
-static int
-in_id_list (
- stateitem_T *cur_si, /* current item or NULL */
- short *list, /* id list */
- struct sp_syn *ssp, /* group id and ":syn include" tag of group */
- int contained /* group id is contained */
+static int
+in_id_list(
+ stateitem_T *cur_si, // current item or NULL
+ int16_t *list, // id list
+ struct sp_syn *ssp, // group id and ":syn include" tag of group
+ int contained // group id is contained
)
{
int retval;
- short *scl_list;
- short item;
- short id = ssp->id;
+ int16_t *scl_list;
+ int16_t item;
+ int16_t id = ssp->id;
static int depth = 0;
int r;
@@ -5515,30 +5541,32 @@ void ex_ownsyntax(exarg_T *eap)
clear_string_option(&curwin->w_s->b_syn_isk);
}
- /* save value of b:current_syntax */
- old_value = get_var_value((char_u *)"b:current_syntax");
- if (old_value != NULL)
+ // Save value of b:current_syntax.
+ old_value = get_var_value("b:current_syntax");
+ if (old_value != NULL) {
old_value = vim_strsave(old_value);
+ }
/* Apply the "syntax" autocommand event, this finds and loads the syntax
* file. */
apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf);
- /* move value of b:current_syntax to w:current_syntax */
- new_value = get_var_value((char_u *)"b:current_syntax");
- if (new_value != NULL)
+ // Move value of b:current_syntax to w:current_syntax.
+ new_value = get_var_value("b:current_syntax");
+ if (new_value != NULL) {
set_internal_string_var((char_u *)"w:current_syntax", new_value);
+ }
- /* restore value of b:current_syntax */
- if (old_value == NULL)
- do_unlet((char_u *)"b:current_syntax", TRUE);
- else {
+ // Restore value of b:current_syntax.
+ if (old_value == NULL) {
+ do_unlet(S_LEN("b:current_syntax"), true);
+ } else {
set_internal_string_var((char_u *)"b:current_syntax", old_value);
xfree(old_value);
}
}
-int syntax_present(win_T *win)
+bool syntax_present(win_T *win)
{
return win->w_s->b_syn_patterns.ga_len != 0
|| win->w_s->b_syn_clusters.ga_len != 0
@@ -5548,8 +5576,10 @@ int syntax_present(win_T *win)
static enum {
- EXP_SUBCMD, /* expand ":syn" sub-commands */
- EXP_CASE /* expand ":syn case" arguments */
+ EXP_SUBCMD, // expand ":syn" sub-commands
+ EXP_CASE, // expand ":syn case" arguments
+ EXP_SPELL, // expand ":syn spell" arguments
+ EXP_SYNC // expand ":syn sync" arguments
} expand_what;
/*
@@ -5565,58 +5595,77 @@ void reset_expand_highlight(void)
* Handle command line completion for :match and :echohl command: Add "None"
* as highlight group.
*/
-void set_context_in_echohl_cmd(expand_T *xp, char_u *arg)
+void set_context_in_echohl_cmd(expand_T *xp, const char *arg)
{
xp->xp_context = EXPAND_HIGHLIGHT;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
include_none = 1;
}
/*
* Handle command line completion for :syntax command.
*/
-void set_context_in_syntax_cmd(expand_T *xp, char_u *arg)
+void set_context_in_syntax_cmd(expand_T *xp, const char *arg)
{
- char_u *p;
-
- /* Default: expand subcommands */
+ // Default: expand subcommands.
xp->xp_context = EXPAND_SYNTAX;
expand_what = EXP_SUBCMD;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
include_link = 0;
include_default = 0;
/* (part of) subcommand already typed */
if (*arg != NUL) {
- p = skiptowhite(arg);
- if (*p != NUL) { /* past first word */
- xp->xp_pattern = skipwhite(p);
- if (*skiptowhite(xp->xp_pattern) != NUL)
+ const char *p = (const char *)skiptowhite((const char_u *)arg);
+ if (*p != NUL) { // Past first word.
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ if (*skiptowhite(xp->xp_pattern) != NUL) {
xp->xp_context = EXPAND_NOTHING;
- else if (STRNICMP(arg, "case", p - arg) == 0)
+ } else if (STRNICMP(arg, "case", p - arg) == 0) {
expand_what = EXP_CASE;
- else if ( STRNICMP(arg, "keyword", p - arg) == 0
+ } else if (STRNICMP(arg, "spell", p - arg) == 0) {
+ expand_what = EXP_SPELL;
+ } else if (STRNICMP(arg, "sync", p - arg) == 0) {
+ expand_what = EXP_SYNC;
+ } else if (STRNICMP(arg, "keyword", p - arg) == 0
|| STRNICMP(arg, "region", p - arg) == 0
|| STRNICMP(arg, "match", p - arg) == 0
- || STRNICMP(arg, "list", p - arg) == 0)
+ || STRNICMP(arg, "list", p - arg) == 0) {
xp->xp_context = EXPAND_HIGHLIGHT;
- else
+ } else {
xp->xp_context = EXPAND_NOTHING;
+ }
}
}
}
-static char *(case_args[]) = {"match", "ignore", NULL};
-
/*
* Function given to ExpandGeneric() to obtain the list syntax names for
* expansion.
*/
char_u *get_syntax_name(expand_T *xp, int idx)
{
- if (expand_what == EXP_SUBCMD)
- return (char_u *)subcommands[idx].name;
- return (char_u *)case_args[idx];
+ switch (expand_what) {
+ case EXP_SUBCMD:
+ return (char_u *)subcommands[idx].name;
+ case EXP_CASE: {
+ static char *case_args[] = { "match", "ignore", NULL };
+ return (char_u *)case_args[idx];
+ }
+ case EXP_SPELL: {
+ static char *spell_args[] =
+ { "toplevel", "notoplevel", "default", NULL };
+ return (char_u *)spell_args[idx];
+ }
+ case EXP_SYNC: {
+ static char *sync_args[] =
+ { "ccomment", "clear", "fromstart",
+ "linebreaks=", "linecont", "lines=", "match",
+ "maxlines=", "minlines=", "region", NULL };
+ return (char_u *)sync_args[idx];
+ }
+ }
+ return NULL;
}
@@ -5632,13 +5681,9 @@ int syn_get_id(
{
// When the position is not after the current position and in the same
// line of the same buffer, need to restart parsing.
- if (wp->w_buffer != syn_buf
- || lnum != current_lnum
- || col < current_col) {
+ if (wp->w_buffer != syn_buf || lnum != current_lnum || col < current_col) {
syntax_start(wp, lnum);
- } else if (wp->w_buffer == syn_buf
- && lnum == current_lnum
- && col > current_col) {
+ } else if (col > current_col) {
// next_match may not be correct when moving around, e.g. with the
// "skip" expression in searchpair()
next_match_idx = -1;
@@ -5661,6 +5706,24 @@ int get_syntax_info(int *seqnrp)
return current_flags;
}
+
+/// Get the sequence number of the concealed file position.
+///
+/// @return seqnr if the file position is concealed, 0 otherwise.
+int syn_get_concealed_id(win_T *wp, linenr_T lnum, colnr_T col)
+{
+ int seqnr;
+ int syntax_flags;
+
+ (void)syn_get_id(wp, lnum, col, false, NULL, false);
+ syntax_flags = get_syntax_info(&seqnr);
+
+ if (syntax_flags & HL_CONCEAL) {
+ return seqnr;
+ }
+ return 0;
+}
+
/*
* Return conceal substitution character
*/
@@ -5809,9 +5872,12 @@ static void syntime_report(void)
}
}
- /* sort on total time */
- qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T),
- syn_compare_syntime);
+ // Sort on total time. Skip if there are no items to avoid passing NULL
+ // pointer to qsort().
+ if (ga.ga_len > 1) {
+ qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T),
+ syn_compare_syntime);
+ }
MSG_PUTS_TITLE(_(
" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"));
@@ -5867,9 +5933,11 @@ static void syntime_report(void)
//
// When making changes here, also change runtime/colors/default.vim!
-static char *highlight_init_both[] =
-{
- "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey",
+static const char *highlight_init_both[] = {
+ "Conceal "
+ "ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey",
+ "Cursor guibg=fg guifg=bg",
+ "lCursor guibg=fg guifg=bg",
"DiffText cterm=bold ctermbg=Red gui=bold guibg=Red",
"ErrorMsg ctermbg=DarkRed ctermfg=White guibg=Red guifg=White",
"IncSearch cterm=reverse gui=reverse",
@@ -5884,11 +5952,14 @@ static char *highlight_init_both[] =
"VertSplit cterm=reverse gui=reverse",
"WildMenu ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black",
"default link EndOfBuffer NonText",
+ "default link QuickFixLine Search",
+ "default link Substitute Search",
+ "default link Whitespace NonText",
+ "default link MsgSeparator StatusLine",
NULL
};
-static char *highlight_init_light[] =
-{
+static const char *highlight_init_light[] = {
"ColorColumn ctermbg=LightRed guibg=LightRed",
"CursorColumn ctermbg=LightGrey guibg=Grey90",
"CursorLine cterm=underline guibg=Grey90",
@@ -5917,11 +5988,11 @@ static char *highlight_init_light[] =
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
"Visual guibg=LightGrey",
"WarningMsg ctermfg=DarkRed guifg=Red",
+ "Normal gui=NONE",
NULL
};
-static char *highlight_init_dark[] =
-{
+static const char *highlight_init_dark[] = {
"ColorColumn ctermbg=DarkRed guibg=DarkRed",
"CursorColumn ctermbg=DarkGrey guibg=Grey40",
"CursorLine cterm=underline guibg=Grey40",
@@ -5950,24 +6021,231 @@ static char *highlight_init_dark[] =
"Title ctermfg=LightMagenta gui=bold guifg=Magenta",
"Visual guibg=DarkGrey",
"WarningMsg ctermfg=LightRed guifg=Red",
+ "Normal gui=NONE",
NULL
};
-void
-init_highlight (
- int both, /* include groups where 'bg' doesn't matter */
- int reset /* clear group first */
-)
+const char *const highlight_init_cmdline[] = {
+ // XXX When modifying a list modify it in both valid and invalid halfs.
+ // TODO(ZyX-I): merge valid and invalid groups via a macros.
+
+ // NvimInternalError should appear only when highlighter has a bug.
+ "NvimInternalError ctermfg=Red ctermbg=Red guifg=Red guibg=Red",
+
+ // Highlight groups (links) used by parser:
+
+ "default link NvimAssignment Operator",
+ "default link NvimPlainAssignment NvimAssignment",
+ "default link NvimAugmentedAssignment NvimAssignment",
+ "default link NvimAssignmentWithAddition NvimAugmentedAssignment",
+ "default link NvimAssignmentWithSubtraction NvimAugmentedAssignment",
+ "default link NvimAssignmentWithConcatenation NvimAugmentedAssignment",
+
+ "default link NvimOperator Operator",
+
+ "default link NvimUnaryOperator NvimOperator",
+ "default link NvimUnaryPlus NvimUnaryOperator",
+ "default link NvimUnaryMinus NvimUnaryOperator",
+ "default link NvimNot NvimUnaryOperator",
+
+ "default link NvimBinaryOperator NvimOperator",
+ "default link NvimComparison NvimBinaryOperator",
+ "default link NvimComparisonModifier NvimComparison",
+ "default link NvimBinaryPlus NvimBinaryOperator",
+ "default link NvimBinaryMinus NvimBinaryOperator",
+ "default link NvimConcat NvimBinaryOperator",
+ "default link NvimConcatOrSubscript NvimConcat",
+ "default link NvimOr NvimBinaryOperator",
+ "default link NvimAnd NvimBinaryOperator",
+ "default link NvimMultiplication NvimBinaryOperator",
+ "default link NvimDivision NvimBinaryOperator",
+ "default link NvimMod NvimBinaryOperator",
+
+ "default link NvimTernary NvimOperator",
+ "default link NvimTernaryColon NvimTernary",
+
+ "default link NvimParenthesis Delimiter",
+ "default link NvimLambda NvimParenthesis",
+ "default link NvimNestingParenthesis NvimParenthesis",
+ "default link NvimCallingParenthesis NvimParenthesis",
+
+ "default link NvimSubscript NvimParenthesis",
+ "default link NvimSubscriptBracket NvimSubscript",
+ "default link NvimSubscriptColon NvimSubscript",
+ "default link NvimCurly NvimSubscript",
+
+ "default link NvimContainer NvimParenthesis",
+ "default link NvimDict NvimContainer",
+ "default link NvimList NvimContainer",
+
+ "default link NvimIdentifier Identifier",
+ "default link NvimIdentifierScope NvimIdentifier",
+ "default link NvimIdentifierScopeDelimiter NvimIdentifier",
+ "default link NvimIdentifierName NvimIdentifier",
+ "default link NvimIdentifierKey NvimIdentifier",
+
+ "default link NvimColon Delimiter",
+ "default link NvimComma Delimiter",
+ "default link NvimArrow Delimiter",
+
+ "default link NvimRegister SpecialChar",
+ "default link NvimNumber Number",
+ "default link NvimFloat NvimNumber",
+ "default link NvimNumberPrefix Type",
+
+ "default link NvimOptionSigil Type",
+ "default link NvimOptionName NvimIdentifier",
+ "default link NvimOptionScope NvimIdentifierScope",
+ "default link NvimOptionScopeDelimiter NvimIdentifierScopeDelimiter",
+
+ "default link NvimEnvironmentSigil NvimOptionSigil",
+ "default link NvimEnvironmentName NvimIdentifier",
+
+ "default link NvimString String",
+ "default link NvimStringBody NvimString",
+ "default link NvimStringQuote NvimString",
+ "default link NvimStringSpecial SpecialChar",
+
+ "default link NvimSingleQuote NvimStringQuote",
+ "default link NvimSingleQuotedBody NvimStringBody",
+ "default link NvimSingleQuotedQuote NvimStringSpecial",
+
+ "default link NvimDoubleQuote NvimStringQuote",
+ "default link NvimDoubleQuotedBody NvimStringBody",
+ "default link NvimDoubleQuotedEscape NvimStringSpecial",
+
+ "default link NvimFigureBrace NvimInternalError",
+ "default link NvimSingleQuotedUnknownEscape NvimInternalError",
+
+ "default link NvimSpacing Normal",
+
+ // NvimInvalid groups:
+
+ "default link NvimInvalidSingleQuotedUnknownEscape NvimInternalError",
+
+ "default link NvimInvalid Error",
+
+ "default link NvimInvalidAssignment NvimInvalid",
+ "default link NvimInvalidPlainAssignment NvimInvalidAssignment",
+ "default link NvimInvalidAugmentedAssignment NvimInvalidAssignment",
+ "default link NvimInvalidAssignmentWithAddition "
+ "NvimInvalidAugmentedAssignment",
+ "default link NvimInvalidAssignmentWithSubtraction "
+ "NvimInvalidAugmentedAssignment",
+ "default link NvimInvalidAssignmentWithConcatenation "
+ "NvimInvalidAugmentedAssignment",
+
+ "default link NvimInvalidOperator NvimInvalid",
+
+ "default link NvimInvalidUnaryOperator NvimInvalidOperator",
+ "default link NvimInvalidUnaryPlus NvimInvalidUnaryOperator",
+ "default link NvimInvalidUnaryMinus NvimInvalidUnaryOperator",
+ "default link NvimInvalidNot NvimInvalidUnaryOperator",
+
+ "default link NvimInvalidBinaryOperator NvimInvalidOperator",
+ "default link NvimInvalidComparison NvimInvalidBinaryOperator",
+ "default link NvimInvalidComparisonModifier NvimInvalidComparison",
+ "default link NvimInvalidBinaryPlus NvimInvalidBinaryOperator",
+ "default link NvimInvalidBinaryMinus NvimInvalidBinaryOperator",
+ "default link NvimInvalidConcat NvimInvalidBinaryOperator",
+ "default link NvimInvalidConcatOrSubscript NvimInvalidConcat",
+ "default link NvimInvalidOr NvimInvalidBinaryOperator",
+ "default link NvimInvalidAnd NvimInvalidBinaryOperator",
+ "default link NvimInvalidMultiplication NvimInvalidBinaryOperator",
+ "default link NvimInvalidDivision NvimInvalidBinaryOperator",
+ "default link NvimInvalidMod NvimInvalidBinaryOperator",
+
+ "default link NvimInvalidTernary NvimInvalidOperator",
+ "default link NvimInvalidTernaryColon NvimInvalidTernary",
+
+ "default link NvimInvalidDelimiter NvimInvalid",
+
+ "default link NvimInvalidParenthesis NvimInvalidDelimiter",
+ "default link NvimInvalidLambda NvimInvalidParenthesis",
+ "default link NvimInvalidNestingParenthesis NvimInvalidParenthesis",
+ "default link NvimInvalidCallingParenthesis NvimInvalidParenthesis",
+
+ "default link NvimInvalidSubscript NvimInvalidParenthesis",
+ "default link NvimInvalidSubscriptBracket NvimInvalidSubscript",
+ "default link NvimInvalidSubscriptColon NvimInvalidSubscript",
+ "default link NvimInvalidCurly NvimInvalidSubscript",
+
+ "default link NvimInvalidContainer NvimInvalidParenthesis",
+ "default link NvimInvalidDict NvimInvalidContainer",
+ "default link NvimInvalidList NvimInvalidContainer",
+
+ "default link NvimInvalidValue NvimInvalid",
+
+ "default link NvimInvalidIdentifier NvimInvalidValue",
+ "default link NvimInvalidIdentifierScope NvimInvalidIdentifier",
+ "default link NvimInvalidIdentifierScopeDelimiter NvimInvalidIdentifier",
+ "default link NvimInvalidIdentifierName NvimInvalidIdentifier",
+ "default link NvimInvalidIdentifierKey NvimInvalidIdentifier",
+
+ "default link NvimInvalidColon NvimInvalidDelimiter",
+ "default link NvimInvalidComma NvimInvalidDelimiter",
+ "default link NvimInvalidArrow NvimInvalidDelimiter",
+
+ "default link NvimInvalidRegister NvimInvalidValue",
+ "default link NvimInvalidNumber NvimInvalidValue",
+ "default link NvimInvalidFloat NvimInvalidNumber",
+ "default link NvimInvalidNumberPrefix NvimInvalidNumber",
+
+ "default link NvimInvalidOptionSigil NvimInvalidIdentifier",
+ "default link NvimInvalidOptionName NvimInvalidIdentifier",
+ "default link NvimInvalidOptionScope NvimInvalidIdentifierScope",
+ "default link NvimInvalidOptionScopeDelimiter "
+ "NvimInvalidIdentifierScopeDelimiter",
+
+ "default link NvimInvalidEnvironmentSigil NvimInvalidOptionSigil",
+ "default link NvimInvalidEnvironmentName NvimInvalidIdentifier",
+
+ // Invalid string bodies and specials are still highlighted as valid ones to
+ // minimize the red area.
+ "default link NvimInvalidString NvimInvalidValue",
+ "default link NvimInvalidStringBody NvimStringBody",
+ "default link NvimInvalidStringQuote NvimInvalidString",
+ "default link NvimInvalidStringSpecial NvimStringSpecial",
+
+ "default link NvimInvalidSingleQuote NvimInvalidStringQuote",
+ "default link NvimInvalidSingleQuotedBody NvimInvalidStringBody",
+ "default link NvimInvalidSingleQuotedQuote NvimInvalidStringSpecial",
+
+ "default link NvimInvalidDoubleQuote NvimInvalidStringQuote",
+ "default link NvimInvalidDoubleQuotedBody NvimInvalidStringBody",
+ "default link NvimInvalidDoubleQuotedEscape NvimInvalidStringSpecial",
+ "default link NvimInvalidDoubleQuotedUnknownEscape NvimInvalidValue",
+
+ "default link NvimInvalidFigureBrace NvimInvalidDelimiter",
+
+ "default link NvimInvalidSpacing ErrorMsg",
+
+ // Not actually invalid, but we highlight user that he is doing something
+ // wrong.
+ "default link NvimDoubleQuotedUnknownEscape NvimInvalidValue",
+ NULL,
+};
+
+/// Create default links for Nvim* highlight groups used for cmdline coloring
+void syn_init_cmdline_highlight(bool reset, bool init)
{
- int i;
- char **pp;
- static int had_both = FALSE;
+ for (size_t i = 0 ; highlight_init_cmdline[i] != NULL ; i++) {
+ do_highlight(highlight_init_cmdline[i], reset, init);
+ }
+}
- /*
- * Try finding the color scheme file. Used when a color file was loaded
- * and 'background' or 't_Co' is changed.
- */
- char_u *p = get_var_value((char_u *)"g:colors_name");
+/// Load colors from a file if "g:colors_name" is set, otherwise load builtin
+/// colors
+///
+/// @param both include groups where 'bg' doesn't matter
+/// @param reset clear groups first
+void init_highlight(bool both, bool reset)
+{
+ static int had_both = false;
+
+ // Try finding the color scheme file. Used when a color file was loaded
+ // and 'background' or 't_Co' is changed.
+ char_u *p = get_var_value("g:colors_name");
if (p != NULL) {
// Value of g:colors_name could be freed in load_colors() and make
// p invalid, so copy it.
@@ -5983,45 +6261,46 @@ init_highlight (
* Didn't use a color file, use the compiled-in colors.
*/
if (both) {
- had_both = TRUE;
- pp = highlight_init_both;
- for (i = 0; pp[i] != NULL; ++i)
- do_highlight((char_u *)pp[i], reset, TRUE);
- } else if (!had_both)
- /* Don't do anything before the call with both == TRUE from main().
- * Not everything has been setup then, and that call will overrule
- * everything anyway. */
+ had_both = true;
+ const char *const *const pp = highlight_init_both;
+ for (size_t i = 0; pp[i] != NULL; i++) {
+ do_highlight(pp[i], reset, true);
+ }
+ } else if (!had_both) {
+ // Don't do anything before the call with both == TRUE from main().
+ // Not everything has been setup then, and that call will overrule
+ // everything anyway.
return;
+ }
- if (*p_bg == 'l')
- pp = highlight_init_light;
- else
- pp = highlight_init_dark;
- for (i = 0; pp[i] != NULL; ++i)
- do_highlight((char_u *)pp[i], reset, TRUE);
+ const char *const *const pp = ((*p_bg == 'l')
+ ? highlight_init_light
+ : highlight_init_dark);
+ for (size_t i = 0; pp[i] != NULL; i++) {
+ do_highlight(pp[i], reset, true);
+ }
/* Reverse looks ugly, but grey may not work for 8 colors. Thus let it
* depend on the number of colors available.
* With 8 colors brown is equal to yellow, need to use black for Search fg
* to avoid Statement highlighted text disappears.
* Clear the attributes, needed when changing the t_Co value. */
- if (t_colors > 8)
+ if (t_colors > 8) {
do_highlight(
- (char_u *)(*p_bg == 'l'
- ? "Visual cterm=NONE ctermbg=LightGrey"
- : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE,
- TRUE);
- else {
- do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE",
- FALSE, TRUE);
- if (*p_bg == 'l')
- do_highlight((char_u *)"Search ctermfg=black", FALSE, TRUE);
+ (*p_bg == 'l'
+ ? "Visual cterm=NONE ctermbg=LightGrey"
+ : "Visual cterm=NONE ctermbg=DarkGrey"), false, true);
+ } else {
+ do_highlight("Visual cterm=reverse ctermbg=NONE", false, true);
+ if (*p_bg == 'l') {
+ do_highlight("Search ctermfg=black", false, true);
+ }
}
/*
* If syntax highlighting is enabled load the highlighting for it.
*/
- if (get_var_value((char_u *)"g:syntax_on") != NULL) {
+ if (get_var_value("g:syntax_on") != NULL) {
static int recursive = 0;
if (recursive >= 5) {
@@ -6032,6 +6311,7 @@ init_highlight (
recursive--;
}
}
+ syn_init_cmdline_highlight(false, false);
}
/*
@@ -6054,201 +6334,285 @@ int load_colors(char_u *name)
recursive = true;
size_t buflen = STRLEN(name) + 12;
buf = xmalloc(buflen);
+ apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf);
snprintf((char *)buf, buflen, "colors/%s.vim", name);
retval = source_runtime(buf, DIP_START + DIP_OPT);
xfree(buf);
apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf);
recursive = false;
- ui_refresh();
return retval;
}
-/*
- * Handle the ":highlight .." command.
- * When using ":hi clear" this is called recursively for each group with
- * "forceit" and "init" both TRUE.
- */
-void
-do_highlight (
- char_u *line,
- int forceit,
- int init /* TRUE when called for initializing */
-)
+static char *(color_names[28]) = {
+ "Black", "DarkBlue", "DarkGreen", "DarkCyan",
+ "DarkRed", "DarkMagenta", "Brown", "DarkYellow",
+ "Gray", "Grey", "LightGray", "LightGrey",
+ "DarkGray", "DarkGrey",
+ "Blue", "LightBlue", "Green", "LightGreen",
+ "Cyan", "LightCyan", "Red", "LightRed", "Magenta",
+ "LightMagenta", "Yellow", "LightYellow", "White", "NONE" };
+ // indices:
+ // 0, 1, 2, 3,
+ // 4, 5, 6, 7,
+ // 8, 9, 10, 11,
+ // 12, 13,
+ // 14, 15, 16, 17,
+ // 18, 19, 20, 21, 22,
+ // 23, 24, 25, 26, 27
+static int color_numbers_16[28] = { 0, 1, 2, 3,
+ 4, 5, 6, 6,
+ 7, 7, 7, 7,
+ 8, 8,
+ 9, 9, 10, 10,
+ 11, 11, 12, 12, 13,
+ 13, 14, 14, 15, -1 };
+// for xterm with 88 colors...
+static int color_numbers_88[28] = { 0, 4, 2, 6,
+ 1, 5, 32, 72,
+ 84, 84, 7, 7,
+ 82, 82,
+ 12, 43, 10, 61,
+ 14, 63, 9, 74, 13,
+ 75, 11, 78, 15, -1 };
+// for xterm with 256 colors...
+static int color_numbers_256[28] = { 0, 4, 2, 6,
+ 1, 5, 130, 130,
+ 248, 248, 7, 7,
+ 242, 242,
+ 12, 81, 10, 121,
+ 14, 159, 9, 224, 13,
+ 225, 11, 229, 15, -1 };
+// for terminals with less than 16 colors...
+static int color_numbers_8[28] = { 0, 4, 2, 6,
+ 1, 5, 3, 3,
+ 7, 7, 7, 7,
+ 0+8, 0+8,
+ 4+8, 4+8, 2+8, 2+8,
+ 6+8, 6+8, 1+8, 1+8, 5+8,
+ 5+8, 3+8, 3+8, 7+8, -1 };
+
+// Lookup the "cterm" value to be used for color with index "idx" in
+// color_names[].
+// "boldp" will be set to TRUE or FALSE for a foreground color when using 8
+// colors, otherwise it will be unchanged.
+int lookup_color(const int idx, const bool foreground, TriState *const boldp)
+{
+ int color = color_numbers_16[idx];
+
+ // Use the _16 table to check if it's a valid color name.
+ if (color < 0) {
+ return -1;
+ }
+
+ if (t_colors == 8) {
+ // t_Co is 8: use the 8 colors table
+ color = color_numbers_8[idx];
+ if (foreground) {
+ // set/reset bold attribute to get light foreground
+ // colors (on some terminals, e.g. "linux")
+ if (color & 8) {
+ *boldp = kTrue;
+ } else {
+ *boldp = kFalse;
+ }
+ }
+ color &= 7; // truncate to 8 colors
+ } else if (t_colors == 16) {
+ color = color_numbers_8[idx];
+ } else if (t_colors == 88) {
+ color = color_numbers_88[idx];
+ } else if (t_colors >= 256) {
+ color = color_numbers_256[idx];
+ }
+ return color;
+}
+
+
+/// Handle ":highlight" command
+///
+/// When using ":highlight clear" this is called recursively for each group with
+/// forceit and init being both true.
+///
+/// @param[in] line Command arguments.
+/// @param[in] forceit True when bang is given, allows to link group even if
+/// it has its own settings.
+/// @param[in] init True when initializing.
+void do_highlight(const char *line, const bool forceit, const bool init)
+ FUNC_ATTR_NONNULL_ALL
{
- char_u *name_end;
- char_u *linep;
- char_u *key_start;
- char_u *arg_start;
- char_u *key = NULL, *arg = NULL;
+ const char *name_end;
+ const char *linep;
+ const char *key_start;
+ const char *arg_start;
long i;
int off;
int len;
int attr;
int id;
int idx;
- int dodefault = FALSE;
- int doclear = FALSE;
- int dolink = FALSE;
- int error = FALSE;
+ struct hl_group item_before;
+ bool dodefault = false;
+ bool doclear = false;
+ bool dolink = false;
+ bool error = false;
int color;
- int is_normal_group = FALSE; /* "Normal" group */
+ bool is_normal_group = false; // "Normal" group
+ bool did_highlight_changed = false;
- /*
- * If no argument, list current highlighting.
- */
- if (ends_excmd(*line)) {
- for (int i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
- /* TODO: only call when the group has attributes set */
+ // If no argument, list current highlighting.
+ if (ends_excmd((uint8_t)(*line))) {
+ for (i = 1; i <= highlight_ga.ga_len && !got_int; i++) {
+ // TODO(brammool): only call when the group has attributes set
highlight_list_one(i);
+ }
return;
}
- /*
- * Isolate the name.
- */
- name_end = skiptowhite(line);
- linep = skipwhite(name_end);
+ // Isolate the name.
+ name_end = (const char *)skiptowhite((const char_u *)line);
+ linep = (const char *)skipwhite((const char_u *)name_end);
- /*
- * Check for "default" argument.
- */
- if (STRNCMP(line, "default", name_end - line) == 0) {
- dodefault = TRUE;
+ // Check for "default" argument.
+ if (strncmp(line, "default", name_end - line) == 0) {
+ dodefault = true;
line = linep;
- name_end = skiptowhite(line);
- linep = skipwhite(name_end);
+ name_end = (const char *)skiptowhite((const char_u *)line);
+ linep = (const char *)skipwhite((const char_u *)name_end);
}
- /*
- * Check for "clear" or "link" argument.
- */
- if (STRNCMP(line, "clear", name_end - line) == 0)
- doclear = TRUE;
- if (STRNCMP(line, "link", name_end - line) == 0)
- dolink = TRUE;
+ // Check for "clear" or "link" argument.
+ if (strncmp(line, "clear", name_end - line) == 0) {
+ doclear = true;
+ } else if (strncmp(line, "link", name_end - line) == 0) {
+ dolink = true;
+ }
- /*
- * ":highlight {group-name}": list highlighting for one group.
- */
- if (!doclear && !dolink && ends_excmd(*linep)) {
- id = syn_namen2id(line, (int)(name_end - line));
- if (id == 0)
- EMSG2(_("E411: highlight group not found: %s"), line);
- else
+ // ":highlight {group-name}": list highlighting for one group.
+ if (!doclear && !dolink && ends_excmd((uint8_t)(*linep))) {
+ id = syn_namen2id((const char_u *)line, (int)(name_end - line));
+ if (id == 0) {
+ emsgf(_("E411: highlight group not found: %s"), line);
+ } else {
highlight_list_one(id);
+ }
return;
}
- /*
- * Handle ":highlight link {from} {to}" command.
- */
+ // Handle ":highlight link {from} {to}" command.
if (dolink) {
- char_u *from_start = linep;
- char_u *from_end;
- char_u *to_start;
- char_u *to_end;
+ const char *from_start = linep;
+ const char *from_end;
+ const char *to_start;
+ const char *to_end;
int from_id;
int to_id;
- from_end = skiptowhite(from_start);
- to_start = skipwhite(from_end);
- to_end = skiptowhite(to_start);
+ from_end = (const char *)skiptowhite((const char_u *)from_start);
+ to_start = (const char *)skipwhite((const char_u *)from_end);
+ to_end = (const char *)skiptowhite((const char_u *)to_start);
- if (ends_excmd(*from_start) || ends_excmd(*to_start)) {
- EMSG2(_("E412: Not enough arguments: \":highlight link %s\""),
- from_start);
+ if (ends_excmd((uint8_t)(*from_start))
+ || ends_excmd((uint8_t)(*to_start))) {
+ emsgf(_("E412: Not enough arguments: \":highlight link %s\""),
+ from_start);
return;
}
- if (!ends_excmd(*skipwhite(to_end))) {
- EMSG2(_("E413: Too many arguments: \":highlight link %s\""), from_start);
+ if (!ends_excmd(*skipwhite((const char_u *)to_end))) {
+ emsgf(_("E413: Too many arguments: \":highlight link %s\""), from_start);
return;
}
- from_id = syn_check_group(from_start, (int)(from_end - from_start));
- if (STRNCMP(to_start, "NONE", 4) == 0)
+ from_id = syn_check_group((const char_u *)from_start,
+ (int)(from_end - from_start));
+ if (strncmp(to_start, "NONE", 4) == 0) {
to_id = 0;
- else
- to_id = syn_check_group(to_start, (int)(to_end - to_start));
+ } else {
+ to_id = syn_check_group((const char_u *)to_start,
+ (int)(to_end - to_start));
+ }
if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0)) {
- /*
- * Don't allow a link when there already is some highlighting
- * for the group, unless '!' is used
- */
+ // Don't allow a link when there already is some highlighting
+ // for the group, unless '!' is used
if (to_id > 0 && !forceit && !init
&& hl_has_settings(from_id - 1, dodefault)) {
- if (sourcing_name == NULL && !dodefault)
+ if (sourcing_name == NULL && !dodefault) {
EMSG(_("E414: group has settings, highlight link ignored"));
- } else {
- if (!init)
+ }
+ } else if (HL_TABLE()[from_id - 1].sg_link != to_id
+ || HL_TABLE()[from_id - 1].sg_scriptID != current_SID
+ || HL_TABLE()[from_id - 1].sg_cleared) {
+ if (!init) {
HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
+ }
HL_TABLE()[from_id - 1].sg_link = to_id;
HL_TABLE()[from_id - 1].sg_scriptID = current_SID;
+ HL_TABLE()[from_id - 1].sg_cleared = false;
redraw_all_later(SOME_VALID);
+
+ // Only call highlight changed() once after multiple changes
+ need_highlight_changed = true;
}
}
- /* Only call highlight_changed() once, after sourcing a syntax file */
- need_highlight_changed = TRUE;
-
return;
}
if (doclear) {
- /*
- * ":highlight clear [group]" command.
- */
+ // ":highlight clear [group]" command.
line = linep;
- if (ends_excmd(*line)) {
- do_unlet((char_u *)"colors_name", TRUE);
+ if (ends_excmd((uint8_t)(*line))) {
+ do_unlet(S_LEN("colors_name"), true);
restore_cterm_colors();
- /*
- * Clear all default highlight groups and load the defaults.
- */
- for (int idx = 0; idx < highlight_ga.ga_len; ++idx) {
- highlight_clear(idx);
+ // Clear all default highlight groups and load the defaults.
+ for (int j = 0; j < highlight_ga.ga_len; j++) {
+ highlight_clear(j);
}
- init_highlight(TRUE, TRUE);
+ init_highlight(true, true);
highlight_changed();
- redraw_later_clear();
+ redraw_all_later(NOT_VALID);
return;
}
- name_end = skiptowhite(line);
- linep = skipwhite(name_end);
+ name_end = (const char *)skiptowhite((const char_u *)line);
+ linep = (const char *)skipwhite((const char_u *)name_end);
}
- /*
- * Find the group name in the table. If it does not exist yet, add it.
- */
- id = syn_check_group(line, (int)(name_end - line));
- if (id == 0) /* failed (out of memory) */
+ // Find the group name in the table. If it does not exist yet, add it.
+ id = syn_check_group((const char_u *)line, (int)(name_end - line));
+ if (id == 0) { // Failed (out of memory).
return;
- idx = id - 1; /* index is ID minus one */
+ }
+ idx = id - 1; // Index is ID minus one.
- /* Return if "default" was used and the group already has settings. */
- if (dodefault && hl_has_settings(idx, TRUE))
+ // Return if "default" was used and the group already has settings
+ if (dodefault && hl_has_settings(idx, true)) {
return;
+ }
- if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
- is_normal_group = TRUE;
+ // Make a copy so we can check if any attribute actually changed
+ item_before = HL_TABLE()[idx];
+ is_normal_group = (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0);
- /* Clear the highlighting for ":hi clear {group}" and ":hi clear". */
+ // Clear the highlighting for ":hi clear {group}" and ":hi clear".
if (doclear || (forceit && init)) {
highlight_clear(idx);
- if (!doclear)
+ if (!doclear) {
HL_TABLE()[idx].sg_set = 0;
+ }
}
- if (!doclear)
- while (!ends_excmd(*linep)) {
+ char *key = NULL;
+ char *arg = NULL;
+ if (!doclear) {
+ while (!ends_excmd((uint8_t)(*linep))) {
key_start = linep;
if (*linep == '=') {
- EMSG2(_("E415: unexpected equal sign: %s"), key_start);
- error = TRUE;
+ emsgf(_("E415: unexpected equal sign: %s"), key_start);
+ error = true;
break;
}
@@ -6258,61 +6622,58 @@ do_highlight (
linep++;
}
xfree(key);
- key = vim_strnsave_up(key_start, (int)(linep - key_start));
- linep = skipwhite(linep);
+ key = (char *)vim_strnsave_up((const char_u *)key_start,
+ (int)(linep - key_start));
+ linep = (const char *)skipwhite((const char_u *)linep);
- if (STRCMP(key, "NONE") == 0) {
+ if (strcmp(key, "NONE") == 0) {
if (!init || HL_TABLE()[idx].sg_set == 0) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_CTERM+SG_GUI;
+ }
highlight_clear(idx);
}
continue;
}
- /*
- * Check for the equal sign.
- */
+ // Check for the equal sign.
if (*linep != '=') {
- EMSG2(_("E416: missing equal sign: %s"), key_start);
- error = TRUE;
+ emsgf(_("E416: missing equal sign: %s"), key_start);
+ error = true;
break;
}
- ++linep;
+ linep++;
- /*
- * Isolate the argument.
- */
- linep = skipwhite(linep);
- if (*linep == '\'') { /* guifg='color name' */
+ // Isolate the argument.
+ linep = (const char *)skipwhite((const char_u *)linep);
+ if (*linep == '\'') { // guifg='color name'
arg_start = ++linep;
- linep = vim_strchr(linep, '\'');
+ linep = strchr(linep, '\'');
if (linep == NULL) {
- EMSG2(_(e_invarg2), key_start);
- error = TRUE;
+ emsgf(_(e_invarg2), key_start);
+ error = true;
break;
}
} else {
arg_start = linep;
- linep = skiptowhite(linep);
+ linep = (const char *)skiptowhite((const char_u *)linep);
}
if (linep == arg_start) {
- EMSG2(_("E417: missing argument: %s"), key_start);
- error = TRUE;
+ emsgf(_("E417: missing argument: %s"), key_start);
+ error = true;
break;
}
xfree(arg);
- arg = vim_strnsave(arg_start, (int)(linep - arg_start));
+ arg = xstrndup(arg_start, (size_t)(linep - arg_start));
- if (*linep == '\'')
- ++linep;
+ if (*linep == '\'') {
+ linep++;
+ }
- /*
- * Store the argument.
- */
- if ( STRCMP(key, "TERM") == 0
- || STRCMP(key, "CTERM") == 0
- || STRCMP(key, "GUI") == 0) {
+ // Store the argument.
+ if (strcmp(key, "TERM") == 0
+ || strcmp(key, "CTERM") == 0
+ || strcmp(key, "GUI") == 0) {
attr = 0;
off = 0;
while (arg[off] != NUL) {
@@ -6325,52 +6686,56 @@ do_highlight (
}
}
if (i < 0) {
- EMSG2(_("E418: Illegal value: %s"), arg);
- error = TRUE;
+ emsgf(_("E418: Illegal value: %s"), arg);
+ error = true;
break;
}
- if (arg[off] == ',') /* another one follows */
- ++off;
+ if (arg[off] == ',') { // Another one follows.
+ off++;
+ }
}
- if (error)
+ if (error) {
break;
+ }
if (*key == 'C') {
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_CTERM;
+ }
HL_TABLE()[idx].sg_cterm = attr;
- HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ HL_TABLE()[idx].sg_cterm_bold = false;
}
} else if (*key == 'G') {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_GUI;
+ }
HL_TABLE()[idx].sg_gui = attr;
}
}
} else if (STRCMP(key, "FONT") == 0) {
- /* in non-GUI fonts are simply ignored */
- } else if (STRCMP(key,
- "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
+ // in non-GUI fonts are simply ignored
+ } else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_CTERM;
+ }
/* When setting the foreground color, and previously the "bold"
* flag was set for a light color, reset it now */
if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold) {
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
- HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ HL_TABLE()[idx].sg_cterm_bold = false;
}
- if (ascii_isdigit(*arg))
+ if (ascii_isdigit(*arg)) {
color = atoi((char *)arg);
- else if (STRICMP(arg, "fg") == 0) {
- if (cterm_normal_fg_color)
+ } else if (STRICMP(arg, "fg") == 0) {
+ if (cterm_normal_fg_color) {
color = cterm_normal_fg_color - 1;
- else {
+ } else {
EMSG(_("E419: FG color unknown"));
- error = TRUE;
+ error = true;
break;
}
} else if (STRICMP(arg, "bg") == 0) {
@@ -6378,134 +6743,81 @@ do_highlight (
color = cterm_normal_bg_color - 1;
else {
EMSG(_("E420: BG color unknown"));
- error = TRUE;
+ error = true;
break;
}
} else {
- static char *(color_names[28]) = {
- "Black", "DarkBlue", "DarkGreen", "DarkCyan",
- "DarkRed", "DarkMagenta", "Brown", "DarkYellow",
- "Gray", "Grey",
- "LightGray", "LightGrey", "DarkGray", "DarkGrey",
- "Blue", "LightBlue", "Green", "LightGreen",
- "Cyan", "LightCyan", "Red", "LightRed", "Magenta",
- "LightMagenta", "Yellow", "LightYellow", "White", "NONE"
- };
- static int color_numbers_16[28] = {0, 1, 2, 3,
- 4, 5, 6, 6,
- 7, 7,
- 7, 7, 8, 8,
- 9, 9, 10, 10,
- 11, 11, 12, 12, 13,
- 13, 14, 14, 15, -1};
- /* for xterm with 88 colors... */
- static int color_numbers_88[28] = {0, 4, 2, 6,
- 1, 5, 32, 72,
- 84, 84,
- 7, 7, 82, 82,
- 12, 43, 10, 61,
- 14, 63, 9, 74, 13,
- 75, 11, 78, 15, -1};
- /* for xterm with 256 colors... */
- static int color_numbers_256[28] = {0, 4, 2, 6,
- 1, 5, 130, 130,
- 248, 248,
- 7, 7, 242, 242,
- 12, 81, 10, 121,
- 14, 159, 9, 224, 13,
- 225, 11, 229, 15, -1};
- /* for terminals with less than 16 colors... */
- static int color_numbers_8[28] = {0, 4, 2, 6,
- 1, 5, 3, 3,
- 7, 7,
- 7, 7, 0+8, 0+8,
- 4+8, 4+8, 2+8, 2+8,
- 6+8, 6+8, 1+8, 1+8, 5+8,
- 5+8, 3+8, 3+8, 7+8, -1};
-
- /* reduce calls to STRICMP a bit, it can be slow */
+ // Reduce calls to STRICMP a bit, it can be slow.
off = TOUPPER_ASC(*arg);
- for (i = ARRAY_SIZE(color_names); --i >= 0; )
+ for (i = ARRAY_SIZE(color_names); --i >= 0; ) {
if (off == color_names[i][0]
- && STRICMP(arg + 1, color_names[i] + 1) == 0)
+ && STRICMP(arg + 1, color_names[i] + 1) == 0) {
break;
+ }
+ }
if (i < 0) {
- EMSG2(_(
- "E421: Color name or number not recognized: %s"),
- key_start);
- error = TRUE;
+ emsgf(_("E421: Color name or number not recognized: %s"),
+ key_start);
+ error = true;
break;
}
- /* Use the _16 table to check if its a valid color name. */
- color = color_numbers_16[i];
- if (color >= 0) {
- if (t_colors == 8) {
- /* t_Co is 8: use the 8 colors table */
- color = color_numbers_8[i];
- if (key[5] == 'F') {
- /* set/reset bold attribute to get light foreground
- * colors (on some terminals, e.g. "linux") */
- if (color & 8) {
- HL_TABLE()[idx].sg_cterm |= HL_BOLD;
- HL_TABLE()[idx].sg_cterm_bold = TRUE;
- } else
- HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
- }
- color &= 7; // truncate to 8 colors
- } else if (t_colors == 16 || t_colors == 88 || t_colors >= 256) {
- if (t_colors == 88) {
- color = color_numbers_88[i];
- } else if (t_colors >= 256) {
- color = color_numbers_256[i];
- } else {
- color = color_numbers_8[i];
- }
- }
+ TriState bold = kNone;
+ color = lookup_color(i, key[5] == 'F', &bold);
+
+ // set/reset bold attribute to get light foreground
+ // colors (on some terminals, e.g. "linux")
+ if (bold == kTrue) {
+ HL_TABLE()[idx].sg_cterm |= HL_BOLD;
+ HL_TABLE()[idx].sg_cterm_bold = true;
+ } else if (bold == kFalse) {
+ HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
}
}
- /* Add one to the argument, to avoid zero. Zero is used for
- * "NONE", then "color" is -1. */
+ // Add one to the argument, to avoid zero. Zero is used for
+ // "NONE", then "color" is -1.
if (key[5] == 'F') {
HL_TABLE()[idx].sg_cterm_fg = color + 1;
if (is_normal_group) {
cterm_normal_fg_color = color + 1;
- cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD);
- {
- must_redraw = CLEAR;
- }
}
} else {
HL_TABLE()[idx].sg_cterm_bg = color + 1;
if (is_normal_group) {
cterm_normal_bg_color = color + 1;
if (!ui_rgb_attached()) {
- must_redraw = CLEAR;
if (color >= 0) {
- if (t_colors < 16)
- i = (color == 0 || color == 4);
- else
- i = (color < 7 || color == 8);
- /* Set the 'background' option if the value is
- * wrong. */
- if (i != (*p_bg == 'd'))
- set_option_value((char_u *)"bg", 0L,
- i ? (char_u *)"dark"
- : (char_u *)"light", 0);
+ int dark = -1;
+
+ if (t_colors < 16) {
+ dark = (color == 0 || color == 4);
+ } else if (color < 16) {
+ // Limit the heuristic to the standard 16 colors
+ dark = (color < 7 || color == 8);
+ }
+ // Set the 'background' option if the value is
+ // wrong.
+ if (dark != -1
+ && dark != (*p_bg == 'd')
+ && !option_was_set("bg")) {
+ set_option_value("bg", 0L, (dark ? "dark" : "light"), 0);
+ reset_option_was_set("bg");
+ }
}
}
}
}
}
- } else if (STRCMP(key, "GUIFG") == 0) {
+ } else if (strcmp(key, "GUIFG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_GUI;
+ }
xfree(HL_TABLE()[idx].sg_rgb_fg_name);
- if (STRCMP(arg, "NONE")) {
- HL_TABLE()[idx].sg_rgb_fg_name = (uint8_t *)xstrdup((char *)arg);
- HL_TABLE()[idx].sg_rgb_fg = name_to_color(arg);
+ if (strcmp(arg, "NONE")) {
+ HL_TABLE()[idx].sg_rgb_fg_name = (char_u *)xstrdup((char *)arg);
+ HL_TABLE()[idx].sg_rgb_fg = name_to_color((const char_u *)arg);
} else {
HL_TABLE()[idx].sg_rgb_fg_name = NULL;
HL_TABLE()[idx].sg_rgb_fg = -1;
@@ -6517,13 +6829,14 @@ do_highlight (
}
} else if (STRCMP(key, "GUIBG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_GUI;
+ }
xfree(HL_TABLE()[idx].sg_rgb_bg_name);
if (STRCMP(arg, "NONE") != 0) {
- HL_TABLE()[idx].sg_rgb_bg_name = (uint8_t *)xstrdup((char *)arg);
- HL_TABLE()[idx].sg_rgb_bg = name_to_color(arg);
+ HL_TABLE()[idx].sg_rgb_bg_name = (char_u *)xstrdup((char *)arg);
+ HL_TABLE()[idx].sg_rgb_bg = name_to_color((const char_u *)arg);
} else {
HL_TABLE()[idx].sg_rgb_bg_name = NULL;
HL_TABLE()[idx].sg_rgb_bg = -1;
@@ -6533,15 +6846,16 @@ do_highlight (
if (is_normal_group) {
normal_bg = HL_TABLE()[idx].sg_rgb_bg;
}
- } else if (STRCMP(key, "GUISP") == 0) {
+ } else if (strcmp(key, "GUISP") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
- if (!init)
+ if (!init) {
HL_TABLE()[idx].sg_set |= SG_GUI;
+ }
xfree(HL_TABLE()[idx].sg_rgb_sp_name);
- if (STRCMP(arg, "NONE") != 0) {
- HL_TABLE()[idx].sg_rgb_sp_name = (uint8_t *)xstrdup((char *)arg);
- HL_TABLE()[idx].sg_rgb_sp = name_to_color(arg);
+ if (strcmp(arg, "NONE") != 0) {
+ HL_TABLE()[idx].sg_rgb_sp_name = (char_u *)xstrdup((char *)arg);
+ HL_TABLE()[idx].sg_rgb_sp = name_to_color((const char_u *)arg);
} else {
HL_TABLE()[idx].sg_rgb_sp_name = NULL;
HL_TABLE()[idx].sg_rgb_sp = -1;
@@ -6551,46 +6865,60 @@ do_highlight (
if (is_normal_group) {
normal_sp = HL_TABLE()[idx].sg_rgb_sp;
}
- } else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0) {
+ } else if (strcmp(key, "START") == 0 || strcmp(key, "STOP") == 0) {
// Ignored for now
} else {
- EMSG2(_("E423: Illegal argument: %s"), key_start);
- error = TRUE;
+ emsgf(_("E423: Illegal argument: %s"), key_start);
+ error = true;
break;
}
+ HL_TABLE()[idx].sg_cleared = false;
- /*
- * When highlighting has been given for a group, don't link it.
- */
- if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
+ // When highlighting has been given for a group, don't link it.
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) {
HL_TABLE()[idx].sg_link = 0;
+ }
- /*
- * Continue with next argument.
- */
- linep = skipwhite(linep);
+ // Continue with next argument.
+ linep = (const char *)skipwhite((const char_u *)linep);
}
+ }
- /*
- * If there is an error, and it's a new entry, remove it from the table.
- */
- if (error && idx == highlight_ga.ga_len)
+ // If there is an error, and it's a new entry, remove it from the table.
+ if (error && idx == highlight_ga.ga_len) {
syn_unadd_group();
- else {
- if (is_normal_group) {
- HL_TABLE()[idx].sg_attr = 0;
- // If the normal group has changed, it is simpler to refresh every UI
- ui_refresh();
- } else
+ } else {
+ if (!error && is_normal_group) {
+ // Need to update all groups, because they might be using "bg" and/or
+ // "fg", which have been changed now.
+ highlight_attr_set_all();
+
+ if (!ui_is_external(kUILinegrid) && starting == 0) {
+ // Older UIs assume that we clear the screen after normal group is
+ // changed
+ ui_refresh();
+ } else {
+ // TUI and newer UIs will repaint the screen themselves. NOT_VALID
+ // redraw below will still handle usages of guibg=fg etc.
+ ui_default_colors_set();
+ }
+ did_highlight_changed = true;
+ redraw_all_later(NOT_VALID);
+ } else {
set_hl_attr(idx);
+ }
HL_TABLE()[idx].sg_scriptID = current_SID;
- redraw_all_later(NOT_VALID);
}
xfree(key);
xfree(arg);
- /* Only call highlight_changed() once, after sourcing a syntax file */
- need_highlight_changed = TRUE;
+ // Only call highlight_changed() once, after a sequence of highlight
+ // commands, and only if an attribute actually changed
+ if (memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0
+ && !did_highlight_changed) {
+ redraw_all_later(NOT_VALID);
+ need_highlight_changed = true;
+ }
}
#if defined(EXITFREE)
@@ -6616,7 +6944,6 @@ void restore_cterm_colors(void)
normal_bg = -1;
normal_sp = -1;
cterm_normal_fg_color = 0;
- cterm_normal_fg_bold = 0;
cterm_normal_bg_color = 0;
}
@@ -6640,9 +6967,11 @@ static int hl_has_settings(int idx, int check_link)
*/
static void highlight_clear(int idx)
{
+ HL_TABLE()[idx].sg_cleared = true;
+
HL_TABLE()[idx].sg_attr = 0;
HL_TABLE()[idx].sg_cterm = 0;
- HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ HL_TABLE()[idx].sg_cterm_bold = false;
HL_TABLE()[idx].sg_cterm_fg = 0;
HL_TABLE()[idx].sg_cterm_bg = 0;
HL_TABLE()[idx].sg_gui = 0;
@@ -6663,171 +6992,17 @@ static void highlight_clear(int idx)
}
-/*
- * Table with the specifications for an attribute number.
- * Note that this table is used by ALL buffers. This is required because the
- * GUI can redraw at any time for any buffer.
- */
-static garray_T attr_table = GA_EMPTY_INIT_VALUE;
-
-#define ATTR_ENTRY(idx) ((attrentry_T *)attr_table.ga_data)[idx]
-
-
-/*
- * Return the attr number for a set of colors and font.
- * Add a new entry to the term_attr_table, attr_table or gui_attr_table
- * if the combination is new.
- * Return 0 for error.
- */
-int get_attr_entry(attrentry_T *aep)
-{
- garray_T *table = &attr_table;
- attrentry_T *taep;
- static int recursive = FALSE;
-
- /*
- * Init the table, in case it wasn't done yet.
- */
- table->ga_itemsize = sizeof(attrentry_T);
- ga_set_growsize(table, 7);
-
- /*
- * Try to find an entry with the same specifications.
- */
- for (int i = 0; i < table->ga_len; ++i) {
- taep = &(((attrentry_T *)table->ga_data)[i]);
- if (aep->cterm_ae_attr == taep->cterm_ae_attr
- && aep->cterm_fg_color == taep->cterm_fg_color
- && aep->cterm_bg_color == taep->cterm_bg_color
- && aep->rgb_ae_attr == taep->rgb_ae_attr
- && aep->rgb_fg_color == taep->rgb_fg_color
- && aep->rgb_bg_color == taep->rgb_bg_color
- && aep->rgb_sp_color == taep->rgb_sp_color) {
- return i + ATTR_OFF;
- }
- }
-
- if (table->ga_len + ATTR_OFF > MAX_TYPENR) {
- /*
- * Running out of attribute entries! remove all attributes, and
- * compute new ones for all groups.
- * When called recursively, we are really out of numbers.
- */
- if (recursive) {
- EMSG(_("E424: Too many different highlighting attributes in use"));
- return 0;
- }
- recursive = TRUE;
-
- clear_hl_tables();
-
- must_redraw = CLEAR;
-
- for (int i = 0; i < highlight_ga.ga_len; ++i) {
- set_hl_attr(i);
- }
-
- recursive = FALSE;
- }
-
-
- // This is a new combination of colors and font, add an entry.
- taep = GA_APPEND_VIA_PTR(attrentry_T, table);
- memset(taep, 0, sizeof(*taep));
- taep->cterm_ae_attr = aep->cterm_ae_attr;
- taep->cterm_fg_color = aep->cterm_fg_color;
- taep->cterm_bg_color = aep->cterm_bg_color;
- taep->rgb_ae_attr = aep->rgb_ae_attr;
- taep->rgb_fg_color = aep->rgb_fg_color;
- taep->rgb_bg_color = aep->rgb_bg_color;
- taep->rgb_sp_color = aep->rgb_sp_color;
-
- return table->ga_len - 1 + ATTR_OFF;
-}
-
-// Clear all highlight tables.
-void clear_hl_tables(void)
-{
- ga_clear(&attr_table);
-}
-
-// Combine special attributes (e.g., for spelling) with other attributes
-// (e.g., for syntax highlighting).
-// "prim_attr" overrules "char_attr".
-// This creates a new group when required.
-// Since we expect there to be few spelling mistakes we don't cache the
-// result.
-// Return the resulting attributes.
-int hl_combine_attr(int char_attr, int prim_attr)
-{
- attrentry_T *char_aep = NULL;
- attrentry_T *spell_aep;
- attrentry_T new_en;
-
- if (char_attr == 0) {
- return prim_attr;
- }
-
- if (prim_attr == 0) {
- return char_attr;
- }
-
- // Find the entry for char_attr
- char_aep = syn_cterm_attr2entry(char_attr);
-
- if (char_aep != NULL) {
- // Copy all attributes from char_aep to the new entry
- new_en = *char_aep;
- } else {
- memset(&new_en, 0, sizeof(new_en));
- }
-
- spell_aep = syn_cterm_attr2entry(prim_attr);
- if (spell_aep != NULL) {
- new_en.cterm_ae_attr |= spell_aep->cterm_ae_attr;
- new_en.rgb_ae_attr |= spell_aep->rgb_ae_attr;
-
- if (spell_aep->cterm_fg_color > 0) {
- new_en.cterm_fg_color = spell_aep->cterm_fg_color;
- }
-
- if (spell_aep->cterm_bg_color > 0) {
- new_en.cterm_bg_color = spell_aep->cterm_bg_color;
- }
-
- if (spell_aep->rgb_fg_color >= 0) {
- new_en.rgb_fg_color = spell_aep->rgb_fg_color;
- }
-
- if (spell_aep->rgb_bg_color >= 0) {
- new_en.rgb_bg_color = spell_aep->rgb_bg_color;
- }
-
- if (spell_aep->rgb_sp_color >= 0) {
- new_en.rgb_sp_color = spell_aep->rgb_sp_color;
- }
- }
- return get_attr_entry(&new_en);
-}
-
-attrentry_T *syn_cterm_attr2entry(int attr)
-{
- attr -= ATTR_OFF;
- if (attr >= attr_table.ga_len) /* did ":syntax clear" */
- return NULL;
- return &(ATTR_ENTRY(attr));
-}
-
+/// \addtogroup LIST_XXX
+/// @{
#define LIST_ATTR 1
#define LIST_STRING 2
#define LIST_INT 3
+/// @}
-static void highlight_list_one(int id)
+static void highlight_list_one(const int id)
{
- struct hl_group *sgp;
- int didh = FALSE;
-
- sgp = &HL_TABLE()[id - 1]; /* index is ID minus one */
+ struct hl_group *const sgp = &HL_TABLE()[id - 1]; // index is ID minus one
+ bool didh = false;
didh = highlight_list_arg(id, didh, LIST_ATTR,
sgp->sg_cterm, NULL, "cterm");
@@ -6847,8 +7022,8 @@ static void highlight_list_one(int id)
if (sgp->sg_link && !got_int) {
(void)syn_list_header(didh, 9999, id);
- didh = TRUE;
- msg_puts_attr((char_u *)"links to", hl_attr(HLF_D));
+ didh = true;
+ msg_puts_attr("links to", HL_ATTR(HLF_D));
msg_putchar(' ');
msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
}
@@ -6859,39 +7034,44 @@ static void highlight_list_one(int id)
last_set_msg(sgp->sg_scriptID);
}
-static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name)
+/// Outputs a highlight when doing ":hi MyHighlight"
+///
+/// @param type one of \ref LIST_XXX
+/// @param iarg integer argument used if \p type == LIST_INT
+/// @param sarg string used if \p type == LIST_STRING
+static bool highlight_list_arg(
+ const int id, bool didh, const int type, int iarg,
+ char_u *const sarg, const char *const name)
{
char_u buf[100];
- char_u *ts;
- int i;
- if (got_int)
- return FALSE;
+ if (got_int) {
+ return false;
+ }
if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0)) {
- ts = buf;
- if (type == LIST_INT)
- sprintf((char *)buf, "%d", iarg - 1);
- else if (type == LIST_STRING)
+ char_u *ts = buf;
+ if (type == LIST_INT) {
+ snprintf((char *)buf, sizeof(buf), "%d", iarg - 1);
+ } else if (type == LIST_STRING) {
ts = sarg;
- else { /* type == LIST_ATTR */
+ } else { // type == LIST_ATTR
buf[0] = NUL;
- for (i = 0; hl_attr_table[i] != 0; ++i) {
+ for (int i = 0; hl_attr_table[i] != 0; i++) {
if (iarg & hl_attr_table[i]) {
if (buf[0] != NUL)
- vim_strcat(buf, (char_u *)",", 100);
- vim_strcat(buf, (char_u *)hl_name_table[i], 100);
+ xstrlcat((char *)buf, ",", 100);
+ xstrlcat((char *)buf, hl_name_table[i], 100);
iarg &= ~hl_attr_table[i]; /* don't want "inverse" */
}
}
}
- (void)syn_list_header(didh,
- (int)(vim_strsize(ts) + STRLEN(name) + 1), id);
- didh = TRUE;
+ (void)syn_list_header(didh, (int)(vim_strsize(ts) + STRLEN(name) + 1), id);
+ didh = true;
if (!got_int) {
if (*name != NUL) {
- MSG_PUTS_ATTR(name, hl_attr(HLF_D));
- MSG_PUTS_ATTR("=", hl_attr(HLF_D));
+ MSG_PUTS_ATTR(name, HL_ATTR(HLF_D));
+ MSG_PUTS_ATTR("=", HL_ATTR(HLF_D));
}
msg_outtrans(ts);
}
@@ -6899,21 +7079,21 @@ static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg
return didh;
}
-/*
- * Return "1" if highlight group "id" has attribute "flag".
- * Return NULL otherwise.
- */
-char_u *
-highlight_has_attr (
- int id,
- int flag,
- int modec // 'g' for GUI, 'c' for cterm
-)
+/// Check whether highlight group has attribute
+///
+/// @param[in] id Highlight group to check.
+/// @param[in] flag Attribute to check.
+/// @param[in] modec 'g' for GUI, 'c' for term.
+///
+/// @return "1" if highlight group has attribute, NULL otherwise.
+const char *highlight_has_attr(const int id, const int flag, const int modec)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
int attr;
- if (id <= 0 || id > highlight_ga.ga_len)
+ if (id <= 0 || id > highlight_ga.ga_len) {
return NULL;
+ }
if (modec == 'g') {
attr = HL_TABLE()[id - 1].sg_gui;
@@ -6921,39 +7101,42 @@ highlight_has_attr (
attr = HL_TABLE()[id - 1].sg_cterm;
}
- if (attr & flag)
- return (char_u *)"1";
- return NULL;
+ return (attr & flag) ? "1" : NULL;
}
-/*
- * Return color name of highlight group "id".
- */
-char_u *
-highlight_color (
- int id,
- char_u *what, /* "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" */
- int modec /* 'g' for GUI, 'c' for cterm, 't' for term */
-)
+/// Return color name of the given highlight group
+///
+/// @param[in] id Highlight group to work with.
+/// @param[in] what What to return: one of "font", "fg", "bg", "sp", "fg#",
+/// "bg#" or "sp#".
+/// @param[in] modec 'g' for GUI, 'c' for cterm and 't' for term.
+///
+/// @return color name, possibly in a static buffer. Buffer will be overwritten
+/// on next highlight_color() call. May return NULL.
+const char *highlight_color(const int id, const char *const what,
+ const int modec)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- static char_u name[20];
+ static char name[20];
int n;
- int fg = FALSE;
- int sp = FALSE;
- int font = FALSE;
+ bool fg = false;
+ bool sp = false;
+ bool font = false;
- if (id <= 0 || id > highlight_ga.ga_len)
+ if (id <= 0 || id > highlight_ga.ga_len) {
return NULL;
+ }
- if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g')
- fg = TRUE;
- else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o'
- && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't')
- font = TRUE;
- else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p')
- sp = TRUE;
- else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g'))
+ if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g') {
+ fg = true;
+ } else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o'
+ && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') {
+ font = true;
+ } else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p') {
+ sp = true;
+ } else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g')) {
return NULL;
+ }
if (modec == 'g') {
if (what[2] == '#' && ui_rgb_attached()) {
if (fg) {
@@ -6966,58 +7149,64 @@ highlight_color (
if (n < 0 || n > 0xffffff) {
return NULL;
}
- snprintf((char *)name, sizeof(name), "#%06x", n);
+ snprintf(name, sizeof(name), "#%06x", n);
return name;
}
if (fg) {
- return HL_TABLE()[id - 1].sg_rgb_fg_name;
+ return (const char *)HL_TABLE()[id - 1].sg_rgb_fg_name;
}
if (sp) {
- return HL_TABLE()[id - 1].sg_rgb_sp_name;
+ return (const char *)HL_TABLE()[id - 1].sg_rgb_sp_name;
}
- return HL_TABLE()[id - 1].sg_rgb_bg_name;
+ return (const char *)HL_TABLE()[id - 1].sg_rgb_bg_name;
}
- if (font || sp)
+ if (font || sp) {
return NULL;
+ }
if (modec == 'c') {
- if (fg)
+ if (fg) {
n = HL_TABLE()[id - 1].sg_cterm_fg - 1;
- else
+ } else {
n = HL_TABLE()[id - 1].sg_cterm_bg - 1;
- sprintf((char *)name, "%d", n);
+ }
+ if (n < 0) {
+ return NULL;
+ }
+ snprintf(name, sizeof(name), "%d", n);
return name;
}
- /* term doesn't have color */
+ // term doesn't have color.
return NULL;
}
-/*
- * Output the syntax list header.
- * Return TRUE when started a new line.
- */
-static int
-syn_list_header (
- int did_header, /* did header already */
- int outlen, /* length of string that comes */
- int id /* highlight group id */
-)
+/// Output the syntax list header.
+///
+/// @param did_header did header already
+/// @param outlen length of string that comes
+/// @param id highlight group id
+/// @return true when started a new line.
+static bool syn_list_header(const bool did_header, const int outlen,
+ const int id)
{
int endcol = 19;
- int newline = TRUE;
+ bool newline = true;
if (!did_header) {
msg_putchar('\n');
- if (got_int)
- return TRUE;
+ if (got_int) {
+ return true;
+ }
msg_outtrans(HL_TABLE()[id - 1].sg_name);
endcol = 15;
} else if (msg_col + outlen + 1 >= Columns) {
msg_putchar('\n');
- if (got_int)
- return TRUE;
+ if (got_int) {
+ return true;
+ }
} else {
- if (msg_col >= endcol) /* wrap around is like starting a new line */
- newline = FALSE;
+ if (msg_col >= endcol) { // wrap around is like starting a new line
+ newline = false;
+ }
}
if (msg_col >= endcol) /* output at least one space */
@@ -7029,29 +7218,21 @@ syn_list_header (
/* Show "xxx" with the attributes. */
if (!did_header) {
- msg_puts_attr((char_u *)"xxx", syn_id2attr(id));
+ msg_puts_attr("xxx", syn_id2attr(id));
msg_putchar(' ');
}
return newline;
}
-/*
- * Set the attribute numbers for a highlight group.
- * Called after one of the attributes has changed.
- */
-static void
-set_hl_attr (
- int idx /* index in array */
-)
+/// Set the attribute numbers for a highlight group.
+/// Called after one of the attributes has changed.
+/// @param idx corrected highlight index
+static void set_hl_attr(int idx)
{
- attrentry_T at_en;
+ HlAttrs at_en = HLATTRS_INIT;
struct hl_group *sgp = HL_TABLE() + idx;
- /* The "Normal" group doesn't need an attribute number */
- if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0)
- return;
-
at_en.cterm_ae_attr = sgp->sg_cterm;
at_en.cterm_fg_color = sgp->sg_cterm_fg;
at_en.cterm_bg_color = sgp->sg_cterm_bg;
@@ -7063,22 +7244,19 @@ set_hl_attr (
at_en.rgb_bg_color = sgp->sg_rgb_bg_name ? sgp->sg_rgb_bg : -1;
at_en.rgb_sp_color = sgp->sg_rgb_sp_name ? sgp->sg_rgb_sp : -1;
- if (at_en.cterm_fg_color != 0 || at_en.cterm_bg_color != 0
- || at_en.rgb_fg_color != -1 || at_en.rgb_bg_color != -1
- || at_en.rgb_sp_color != -1 || at_en.cterm_ae_attr != 0
- || at_en.rgb_ae_attr != 0) {
- sgp->sg_attr = get_attr_entry(&at_en);
- } else {
- // If all the fields are cleared, clear the attr field back to default value
- sgp->sg_attr = 0;
+ sgp->sg_attr = hl_get_syn_attr(idx+1, at_en);
+
+ // a cursor style uses this syn_id, make sure its atribute is updated.
+ if (cursor_mode_uses_syn_id(idx+1)) {
+ ui_mode_info_set();
}
}
-/*
- * Lookup a highlight group name and return it's ID.
- * If it is not found, 0 is returned.
- */
-int syn_name2id(char_u *name)
+/// Lookup a highlight group name and return its ID.
+///
+/// @param highlight name e.g. 'Cursor', 'Normal'
+/// @return the highlight id, else 0 if \p name does not exist
+int syn_name2id(const char_u *name)
{
int i;
char_u name_u[200];
@@ -7098,7 +7276,7 @@ int syn_name2id(char_u *name)
/*
* Return TRUE if highlight group "name" exists.
*/
-int highlight_exists(char_u *name)
+int highlight_exists(const char_u *name)
{
return syn_name2id(name) > 0;
}
@@ -7117,7 +7295,7 @@ char_u *syn_id2name(int id)
/*
* Like syn_name2id(), but take a pointer + length argument.
*/
-int syn_namen2id(char_u *linep, int len)
+int syn_namen2id(const char_u *linep, int len)
{
char_u *name = vim_strnsave(linep, len);
int id = syn_name2id(name);
@@ -7126,32 +7304,30 @@ int syn_namen2id(char_u *linep, int len)
return id;
}
-/*
- * Find highlight group name in the table and return it's ID.
- * The argument is a pointer to the name and the length of the name.
- * If it doesn't exist yet, a new entry is created.
- * Return 0 for failure.
- */
-int syn_check_group(char_u *pp, int len)
+/// Find highlight group name in the table and return its ID.
+/// If it doesn't exist yet, a new entry is created.
+///
+/// @param pp Highlight group name
+/// @param len length of \p pp
+///
+/// @return 0 for failure else the id of the group
+int syn_check_group(const char_u *pp, int len)
{
- int id;
- char_u *name;
-
- name = vim_strnsave(pp, len);
-
- id = syn_name2id(name);
- if (id == 0) /* doesn't exist yet */
+ char_u *name = vim_strnsave(pp, len);
+ int id = syn_name2id(name);
+ if (id == 0) { // doesn't exist yet
id = syn_add_group(name);
- else
+ } else {
xfree(name);
+ }
return id;
}
-/*
- * Add new highlight group and return it's ID.
- * "name" must be an allocated string, it will be consumed.
- * Return 0 for failure.
- */
+/// Add new highlight group and return its ID.
+///
+/// @param name must be an allocated string, it will be consumed.
+/// @return 0 for failure, else the allocated group id
+/// @see syn_check_group syn_unadd_group
static int syn_add_group(char_u *name)
{
char_u *p;
@@ -7165,7 +7341,7 @@ static int syn_add_group(char_u *name)
} else if (!ASCII_ISALNUM(*p) && *p != '_') {
/* This is an error, but since there previously was no check only
* give a warning. */
- msg_source(hl_attr(HLF_W));
+ msg_source(HL_ATTR(HLF_W));
MSG(_("W18: Invalid character in group name"));
break;
}
@@ -7189,25 +7365,26 @@ static int syn_add_group(char_u *name)
struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga);
memset(hlgp, 0, sizeof(*hlgp));
hlgp->sg_name = name;
+ hlgp->sg_rgb_bg = -1;
+ hlgp->sg_rgb_fg = -1;
+ hlgp->sg_rgb_sp = -1;
hlgp->sg_name_u = vim_strsave_up(name);
return highlight_ga.ga_len; /* ID is index plus one */
}
-/*
- * When, just after calling syn_add_group(), an error is discovered, this
- * function deletes the new name.
- */
+/// When, just after calling syn_add_group(), an error is discovered, this
+/// function deletes the new name.
static void syn_unadd_group(void)
{
- --highlight_ga.ga_len;
+ highlight_ga.ga_len--;
xfree(HL_TABLE()[highlight_ga.ga_len].sg_name);
xfree(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
}
-/*
- * Translate a group ID to highlight attributes.
- */
+
+/// Translate a group ID to highlight attributes.
+/// @see syn_attr2entry
int syn_id2attr(int hl_id)
{
struct hl_group *sgp;
@@ -7243,111 +7420,53 @@ int syn_get_final_id(int hl_id)
return hl_id;
}
+/// Refresh the color attributes of all highlight groups.
+void highlight_attr_set_all(void)
+{
+ for (int idx = 0; idx < highlight_ga.ga_len; idx++) {
+ struct hl_group *sgp = &HL_TABLE()[idx];
+ if (sgp->sg_rgb_bg_name != NULL) {
+ sgp->sg_rgb_bg = name_to_color(sgp->sg_rgb_bg_name);
+ }
+ if (sgp->sg_rgb_fg_name != NULL) {
+ sgp->sg_rgb_fg = name_to_color(sgp->sg_rgb_fg_name);
+ }
+ if (sgp->sg_rgb_sp_name != NULL) {
+ sgp->sg_rgb_sp = name_to_color(sgp->sg_rgb_sp_name);
+ }
+ set_hl_attr(idx);
+ }
+}
-/*
- * Translate the 'highlight' option into attributes in highlight_attr[] and
- * set up the user highlights User1..9. A set of
- * corresponding highlights to use on top of HLF_SNC is computed.
- * Called only when the 'highlight' option has been changed and upon first
- * screen redraw after any :highlight command.
- * Return FAIL when an invalid flag is found in 'highlight'. OK otherwise.
- */
-int highlight_changed(void)
+/// Tranlate highlight groups into attributes in highlight_attr[] and set up
+/// the user highlights User1..9. A set of corresponding highlights to use on
+/// top of HLF_SNC is computed. Called only when nvim starts and upon first
+/// screen redraw after any :highlight command.
+void highlight_changed(void)
{
- int hlf;
- int i;
- char_u *p;
- int attr;
- char_u *end;
int id;
char_u userhl[10];
int id_SNC = -1;
int id_S = -1;
int hlcnt;
- static int hl_flags[HLF_COUNT] = HL_FLAGS;
need_highlight_changed = FALSE;
- /*
- * Clear all attributes.
- */
- for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
- highlight_attr[hlf] = 0;
-
- /*
- * First set all attributes to their default value.
- * Then use the attributes from the 'highlight' option.
- */
- for (i = 0; i < 2; ++i) {
- if (i)
- p = p_hl;
- else
- p = get_highlight_default();
- if (p == NULL) /* just in case */
- continue;
-
- while (*p) {
- for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
- if (hl_flags[hlf] == *p)
- break;
- ++p;
- if (hlf == (int)HLF_COUNT || *p == NUL)
- return FAIL;
-
- /*
- * Allow several hl_flags to be combined, like "bu" for
- * bold-underlined.
- */
- attr = 0;
- bool colon = false;
- for (; *p && *p != ','; ++p) { // parse upto comma
- if (ascii_iswhite(*p)) { // ignore white space
- continue;
- }
-
- if (colon) /* Combination with ':' is not allowed. */
- return FAIL;
-
- switch (*p) {
- case 'b': attr |= HL_BOLD;
- break;
- case 'i': attr |= HL_ITALIC;
- break;
- case '-':
- case 'n': /* no highlighting */
- break;
- case 'r': attr |= HL_INVERSE;
- break;
- case 's': attr |= HL_STANDOUT;
- break;
- case 'u': attr |= HL_UNDERLINE;
- break;
- case 'c': attr |= HL_UNDERCURL;
- break;
- case ':': ++p; /* highlight group name */
- if (attr || *p == NUL) /* no combinations */
- return FAIL;
- colon = true;
- end = vim_strchr(p, ',');
- if (end == NULL)
- end = p + STRLEN(p);
- id = syn_check_group(p, (int)(end - p));
- if (id == 0)
- return FAIL;
- attr = syn_id2attr(id);
- p = end - 1;
- if (hlf == (int)HLF_SNC)
- id_SNC = syn_get_final_id(id);
- else if (hlf == (int)HLF_S)
- id_S = syn_get_final_id(id);
- break;
- default: return FAIL;
- }
- }
- highlight_attr[hlf] = attr;
-
- p = skip_to_option_part(p); /* skip comma and spaces */
+ /// Translate builtin highlight groups into attributes for quick lookup.
+ for (int hlf = 0; hlf < (int)HLF_COUNT; hlf++) {
+ id = syn_check_group((char_u *)hlf_names[hlf], STRLEN(hlf_names[hlf]));
+ if (id == 0) {
+ abort();
+ }
+ int final_id = syn_get_final_id(id);
+ if (hlf == (int)HLF_SNC) {
+ id_SNC = final_id;
+ } else if (hlf == (int)HLF_S) {
+ id_S = final_id;
}
+
+ highlight_attr[hlf] = hl_get_ui_attr(hlf, final_id,
+ hlf == (int)HLF_INACTIVE);
}
/* Setup the user highlights
@@ -7412,49 +7531,47 @@ int highlight_changed(void)
}
}
highlight_ga.ga_len = hlcnt;
-
- return OK;
}
/*
* Handle command line completion for :highlight command.
*/
-void set_context_in_highlight_cmd(expand_T *xp, char_u *arg)
+void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
{
- char_u *p;
-
- /* Default: expand group names */
+ // Default: expand group names.
xp->xp_context = EXPAND_HIGHLIGHT;
- xp->xp_pattern = arg;
+ xp->xp_pattern = (char_u *)arg;
include_link = 2;
include_default = 1;
/* (part of) subcommand already typed */
if (*arg != NUL) {
- p = skiptowhite(arg);
- if (*p != NUL) { /* past "default" or group name */
+ const char *p = (const char *)skiptowhite((const char_u *)arg);
+ if (*p != NUL) { // Past "default" or group name.
include_default = 0;
- if (STRNCMP("default", arg, p - arg) == 0) {
- arg = skipwhite(p);
- xp->xp_pattern = arg;
- p = skiptowhite(arg);
+ if (strncmp("default", arg, p - arg) == 0) {
+ arg = (const char *)skipwhite((const char_u *)p);
+ xp->xp_pattern = (char_u *)arg;
+ p = (const char *)skiptowhite((const char_u *)arg);
}
if (*p != NUL) { /* past group name */
include_link = 0;
- if (arg[1] == 'i' && arg[0] == 'N')
+ if (arg[1] == 'i' && arg[0] == 'N') {
highlight_list();
- if (STRNCMP("link", arg, p - arg) == 0
- || STRNCMP("clear", arg, p - arg) == 0) {
- xp->xp_pattern = skipwhite(p);
- p = skiptowhite(xp->xp_pattern);
- if (*p != NUL) { /* past first group name */
- xp->xp_pattern = skipwhite(p);
- p = skiptowhite(xp->xp_pattern);
+ }
+ if (strncmp("link", arg, p - arg) == 0
+ || strncmp("clear", arg, p - arg) == 0) {
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ p = (const char *)skiptowhite(xp->xp_pattern);
+ if (*p != NUL) { // Past first group name.
+ xp->xp_pattern = skipwhite((const char_u *)p);
+ p = (const char *)skiptowhite(xp->xp_pattern);
}
}
- if (*p != NUL) /* past group name(s) */
+ if (*p != NUL) { // Past group name(s).
xp->xp_context = EXPAND_NOTHING;
+ }
}
}
}
@@ -7467,216 +7584,754 @@ static void highlight_list(void)
{
int i;
- for (i = 10; --i >= 0; )
- highlight_list_two(i, hl_attr(HLF_D));
- for (i = 40; --i >= 0; )
+ for (i = 10; --i >= 0; ) {
+ highlight_list_two(i, HL_ATTR(HLF_D));
+ }
+ for (i = 40; --i >= 0; ) {
highlight_list_two(99, 0);
+ }
}
static void highlight_list_two(int cnt, int attr)
{
- msg_puts_attr((char_u *)&("N \bI \b! \b"[cnt / 11]), attr);
+ msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr);
msg_clr_eos();
ui_flush();
os_delay(cnt == 99 ? 40L : (long)cnt * 50L, false);
}
-/*
- * Function given to ExpandGeneric() to obtain the list of group names.
- * Also used for synIDattr() function.
- */
-char_u *get_highlight_name(expand_T *xp, int idx)
-{
- //TODO: 'xp' is unused
- if (idx == highlight_ga.ga_len && include_none != 0)
- return (char_u *)"none";
- if (idx == highlight_ga.ga_len + include_none && include_default != 0)
- return (char_u *)"default";
- if (idx == highlight_ga.ga_len + include_none + include_default
- && include_link != 0)
- return (char_u *)"link";
- if (idx == highlight_ga.ga_len + include_none + include_default + 1
- && include_link != 0)
- return (char_u *)"clear";
- if (idx < 0 || idx >= highlight_ga.ga_len)
+/// Function given to ExpandGeneric() to obtain the list of group names.
+const char *get_highlight_name(expand_T *const xp, int idx)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return get_highlight_name_ext(xp, idx, true);
+}
+
+
+/// Obtain a highlight group name.
+/// When "skip_cleared" is TRUE don't return a cleared entry.
+const char *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (idx < 0) {
return NULL;
- return HL_TABLE()[idx].sg_name;
+ }
+
+ // Items are never removed from the table, skip the ones that were cleared.
+ if (skip_cleared && idx < highlight_ga.ga_len && HL_TABLE()[idx].sg_cleared) {
+ return "";
+ }
+
+ if (idx == highlight_ga.ga_len && include_none != 0) {
+ return "none";
+ } else if (idx == highlight_ga.ga_len + include_none
+ && include_default != 0) {
+ return "default";
+ } else if (idx == highlight_ga.ga_len + include_none + include_default
+ && include_link != 0) {
+ return "link";
+ } else if (idx == highlight_ga.ga_len + include_none + include_default + 1
+ && include_link != 0) {
+ return "clear";
+ } else if (idx >= highlight_ga.ga_len) {
+ return NULL;
+ }
+ return (const char *)HL_TABLE()[idx].sg_name;
}
color_name_table_T color_name_table[] = {
- // Color names taken from
- // http://www.rapidtables.com/web/color/RGB_Color.htm
- {"Maroon", RGB(0x80, 0x00, 0x00)},
- {"DarkRed", RGB(0x8b, 0x00, 0x00)},
- {"Brown", RGB(0xa5, 0x2a, 0x2a)},
- {"Firebrick", RGB(0xb2, 0x22, 0x22)},
- {"Crimson", RGB(0xdc, 0x14, 0x3c)},
- {"Red", RGB(0xff, 0x00, 0x00)},
- {"Tomato", RGB(0xff, 0x63, 0x47)},
- {"Coral", RGB(0xff, 0x7f, 0x50)},
- {"IndianRed", RGB(0xcd, 0x5c, 0x5c)},
- {"LightCoral", RGB(0xf0, 0x80, 0x80)},
- {"DarkSalmon", RGB(0xe9, 0x96, 0x7a)},
- {"Salmon", RGB(0xfa, 0x80, 0x72)},
- {"LightSalmon", RGB(0xff, 0xa0, 0x7a)},
- {"OrangeRed", RGB(0xff, 0x45, 0x00)},
- {"DarkOrange", RGB(0xff, 0x8c, 0x00)},
- {"Orange", RGB(0xff, 0xa5, 0x00)},
- {"Gold", RGB(0xff, 0xd7, 0x00)},
- {"DarkGoldenRod", RGB(0xb8, 0x86, 0x0b)},
- {"GoldenRod", RGB(0xda, 0xa5, 0x20)},
- {"PaleGoldenRod", RGB(0xee, 0xe8, 0xaa)},
- {"DarkKhaki", RGB(0xbd, 0xb7, 0x6b)},
- {"Khaki", RGB(0xf0, 0xe6, 0x8c)},
- {"Olive", RGB(0x80, 0x80, 0x00)},
- {"Yellow", RGB(0xff, 0xff, 0x00)},
- {"YellowGreen", RGB(0x9a, 0xcd, 0x32)},
- {"DarkOliveGreen", RGB(0x55, 0x6b, 0x2f)},
- {"OliveDrab", RGB(0x6b, 0x8e, 0x23)},
- {"LawnGreen", RGB(0x7c, 0xfc, 0x00)},
- {"ChartReuse", RGB(0x7f, 0xff, 0x00)},
- {"GreenYellow", RGB(0xad, 0xff, 0x2f)},
- {"DarkGreen", RGB(0x00, 0x64, 0x00)},
- {"Green", RGB(0x00, 0x80, 0x00)},
- {"ForestGreen", RGB(0x22, 0x8b, 0x22)},
- {"Lime", RGB(0x00, 0xff, 0x00)},
- {"LimeGreen", RGB(0x32, 0xcd, 0x32)},
- {"LightGreen", RGB(0x90, 0xee, 0x90)},
- {"PaleGreen", RGB(0x98, 0xfb, 0x98)},
- {"DarkSeaGreen", RGB(0x8f, 0xbc, 0x8f)},
- {"MediumSpringGreen", RGB(0x00, 0xfa, 0x9a)},
- {"SpringGreen", RGB(0x00, 0xff, 0x7f)},
- {"SeaGreen", RGB(0x2e, 0x8b, 0x57)},
- {"MediumAquamarine", RGB(0x66, 0xcd, 0xaa)},
- {"MediumSeaGreen", RGB(0x3c, 0xb3, 0x71)},
- {"LightSeaGreen", RGB(0x20, 0xb2, 0xaa)},
- {"DarkSlateGray", RGB(0x2f, 0x4f, 0x4f)},
- {"Teal", RGB(0x00, 0x80, 0x80)},
- {"DarkCyan", RGB(0x00, 0x8b, 0x8b)},
- {"Aqua", RGB(0x00, 0xff, 0xff)},
- {"Cyan", RGB(0x00, 0xff, 0xff)},
- {"LightCyan", RGB(0xe0, 0xff, 0xff)},
- {"DarkTurquoise", RGB(0x00, 0xce, 0xd1)},
- {"Turquoise", RGB(0x40, 0xe0, 0xd0)},
- {"MediumTurquoise", RGB(0x48, 0xd1, 0xcc)},
- {"PaleTurquoise", RGB(0xaf, 0xee, 0xee)},
- {"Aquamarine", RGB(0x7f, 0xff, 0xd4)},
- {"PowderBlue", RGB(0xb0, 0xe0, 0xe6)},
- {"CadetBlue", RGB(0x5f, 0x9e, 0xa0)},
- {"SteelBlue", RGB(0x46, 0x82, 0xb4)},
- {"CornFlowerBlue", RGB(0x64, 0x95, 0xed)},
- {"DeepSkyBlue", RGB(0x00, 0xbf, 0xff)},
- {"DodgerBlue", RGB(0x1e, 0x90, 0xff)},
- {"LightBlue", RGB(0xad, 0xd8, 0xe6)},
- {"SkyBlue", RGB(0x87, 0xce, 0xeb)},
- {"LightSkyBlue", RGB(0x87, 0xce, 0xfa)},
- {"MidnightBlue", RGB(0x19, 0x19, 0x70)},
- {"Navy", RGB(0x00, 0x00, 0x80)},
- {"DarkBlue", RGB(0x00, 0x00, 0x8b)},
- {"MediumBlue", RGB(0x00, 0x00, 0xcd)},
- {"Blue", RGB(0x00, 0x00, 0xff)},
- {"RoyalBlue", RGB(0x41, 0x69, 0xe1)},
- {"BlueViolet", RGB(0x8a, 0x2b, 0xe2)},
- {"Indigo", RGB(0x4b, 0x00, 0x82)},
- {"DarkSlateBlue", RGB(0x48, 0x3d, 0x8b)},
- {"SlateBlue", RGB(0x6a, 0x5a, 0xcd)},
- {"MediumSlateBlue", RGB(0x7b, 0x68, 0xee)},
- {"MediumPurple", RGB(0x93, 0x70, 0xdb)},
- {"DarkMagenta", RGB(0x8b, 0x00, 0x8b)},
- {"DarkViolet", RGB(0x94, 0x00, 0xd3)},
- {"DarkOrchid", RGB(0x99, 0x32, 0xcc)},
- {"MediumOrchid", RGB(0xba, 0x55, 0xd3)},
- {"Purple", RGB(0x80, 0x00, 0x80)},
- {"Thistle", RGB(0xd8, 0xbf, 0xd8)},
- {"Plum", RGB(0xdd, 0xa0, 0xdd)},
- {"Violet", RGB(0xee, 0x82, 0xee)},
- {"Magenta", RGB(0xff, 0x00, 0xff)},
- {"Fuchsia", RGB(0xff, 0x00, 0xff)},
- {"Orchid", RGB(0xda, 0x70, 0xd6)},
- {"MediumVioletRed", RGB(0xc7, 0x15, 0x85)},
- {"PaleVioletRed", RGB(0xdb, 0x70, 0x93)},
- {"DeepPink", RGB(0xff, 0x14, 0x93)},
- {"HotPink", RGB(0xff, 0x69, 0xb4)},
- {"LightPink", RGB(0xff, 0xb6, 0xc1)},
- {"Pink", RGB(0xff, 0xc0, 0xcb)},
- {"AntiqueWhite", RGB(0xfa, 0xeb, 0xd7)},
- {"Beige", RGB(0xf5, 0xf5, 0xdc)},
- {"Bisque", RGB(0xff, 0xe4, 0xc4)},
- {"BlanchedAlmond", RGB(0xff, 0xeb, 0xcd)},
- {"Wheat", RGB(0xf5, 0xde, 0xb3)},
- {"Cornsilk", RGB(0xff, 0xf8, 0xdc)},
- {"LemonChiffon", RGB(0xff, 0xfa, 0xcd)},
- {"LightGoldenRodYellow", RGB(0xfa, 0xfa, 0xd2)},
- {"LightYellow", RGB(0xff, 0xff, 0xe0)},
- {"SaddleBrown", RGB(0x8b, 0x45, 0x13)},
- {"Sienna", RGB(0xa0, 0x52, 0x2d)},
- {"Chocolate", RGB(0xd2, 0x69, 0x1e)},
- {"Peru", RGB(0xcd, 0x85, 0x3f)},
- {"SandyBrown", RGB(0xf4, 0xa4, 0x60)},
- {"BurlyWood", RGB(0xde, 0xb8, 0x87)},
- {"Tan", RGB(0xd2, 0xb4, 0x8c)},
- {"RosyBrown", RGB(0xbc, 0x8f, 0x8f)},
- {"Moccasin", RGB(0xff, 0xe4, 0xb5)},
- {"NavajoWhite", RGB(0xff, 0xde, 0xad)},
- {"PeachPuff", RGB(0xff, 0xda, 0xb9)},
- {"MistyRose", RGB(0xff, 0xe4, 0xe1)},
- {"LavenderBlush", RGB(0xff, 0xf0, 0xf5)},
- {"Linen", RGB(0xfa, 0xf0, 0xe6)},
- {"Oldlace", RGB(0xfd, 0xf5, 0xe6)},
- {"PapayaWhip", RGB(0xff, 0xef, 0xd5)},
- {"SeaShell", RGB(0xff, 0xf5, 0xee)},
- {"MintCream", RGB(0xf5, 0xff, 0xfa)},
- {"SlateGray", RGB(0x70, 0x80, 0x90)},
- {"LightSlateGray", RGB(0x77, 0x88, 0x99)},
- {"LightSteelBlue", RGB(0xb0, 0xc4, 0xde)},
- {"Lavender", RGB(0xe6, 0xe6, 0xfa)},
- {"FloralWhite", RGB(0xff, 0xfa, 0xf0)},
- {"AliceBlue", RGB(0xf0, 0xf8, 0xff)},
- {"GhostWhite", RGB(0xf8, 0xf8, 0xff)},
- {"Honeydew", RGB(0xf0, 0xff, 0xf0)},
- {"Ivory", RGB(0xff, 0xff, 0xf0)},
- {"Azure", RGB(0xf0, 0xff, 0xff)},
- {"Snow", RGB(0xff, 0xfa, 0xfa)},
- {"Black", RGB(0x00, 0x00, 0x00)},
- {"DimGray", RGB(0x69, 0x69, 0x69)},
- {"DimGrey", RGB(0x69, 0x69, 0x69)},
- {"Gray", RGB(0x80, 0x80, 0x80)},
- {"Grey", RGB(0x80, 0x80, 0x80)},
- {"DarkGray", RGB(0xa9, 0xa9, 0xa9)},
- {"DarkGrey", RGB(0xa9, 0xa9, 0xa9)},
- {"Silver", RGB(0xc0, 0xc0, 0xc0)},
- {"LightGray", RGB(0xd3, 0xd3, 0xd3)},
- {"LightGrey", RGB(0xd3, 0xd3, 0xd3)},
- {"Gainsboro", RGB(0xdc, 0xdc, 0xdc)},
- {"WhiteSmoke", RGB(0xf5, 0xf5, 0xf5)},
- {"White", RGB(0xff, 0xff, 0xff)},
- // The color names below were taken from gui_x11.c in vim source
- {"LightRed", RGB(0xff, 0xbb, 0xbb)},
- {"LightMagenta",RGB(0xff, 0xbb, 0xff)},
- {"DarkYellow", RGB(0xbb, 0xbb, 0x00)},
- {"Gray10", RGB(0x1a, 0x1a, 0x1a)},
- {"Grey10", RGB(0x1a, 0x1a, 0x1a)},
- {"Gray20", RGB(0x33, 0x33, 0x33)},
- {"Grey20", RGB(0x33, 0x33, 0x33)},
- {"Gray30", RGB(0x4d, 0x4d, 0x4d)},
- {"Grey30", RGB(0x4d, 0x4d, 0x4d)},
- {"Gray40", RGB(0x66, 0x66, 0x66)},
- {"Grey40", RGB(0x66, 0x66, 0x66)},
- {"Gray50", RGB(0x7f, 0x7f, 0x7f)},
- {"Grey50", RGB(0x7f, 0x7f, 0x7f)},
- {"Gray60", RGB(0x99, 0x99, 0x99)},
- {"Grey60", RGB(0x99, 0x99, 0x99)},
- {"Gray70", RGB(0xb3, 0xb3, 0xb3)},
- {"Grey70", RGB(0xb3, 0xb3, 0xb3)},
- {"Gray80", RGB(0xcc, 0xcc, 0xcc)},
- {"Grey80", RGB(0xcc, 0xcc, 0xcc)},
- {"Gray90", RGB(0xe5, 0xe5, 0xe5)},
- {"Grey90", RGB(0xe5, 0xe5, 0xe5)},
- {NULL, 0},
+ // Colors from rgb.txt
+ { "AliceBlue", RGB_(0xf0, 0xf8, 0xff) },
+ { "AntiqueWhite", RGB_(0xfa, 0xeb, 0xd7) },
+ { "AntiqueWhite1", RGB_(0xff, 0xef, 0xdb) },
+ { "AntiqueWhite2", RGB_(0xee, 0xdf, 0xcc) },
+ { "AntiqueWhite3", RGB_(0xcd, 0xc0, 0xb0) },
+ { "AntiqueWhite4", RGB_(0x8b, 0x83, 0x78) },
+ { "Aqua", RGB_(0x00, 0xff, 0xff) },
+ { "Aquamarine", RGB_(0x7f, 0xff, 0xd4) },
+ { "Aquamarine1", RGB_(0x7f, 0xff, 0xd4) },
+ { "Aquamarine2", RGB_(0x76, 0xee, 0xc6) },
+ { "Aquamarine3", RGB_(0x66, 0xcd, 0xaa) },
+ { "Aquamarine4", RGB_(0x45, 0x8b, 0x74) },
+ { "Azure", RGB_(0xf0, 0xff, 0xff) },
+ { "Azure1", RGB_(0xf0, 0xff, 0xff) },
+ { "Azure2", RGB_(0xe0, 0xee, 0xee) },
+ { "Azure3", RGB_(0xc1, 0xcd, 0xcd) },
+ { "Azure4", RGB_(0x83, 0x8b, 0x8b) },
+ { "Beige", RGB_(0xf5, 0xf5, 0xdc) },
+ { "Bisque", RGB_(0xff, 0xe4, 0xc4) },
+ { "Bisque1", RGB_(0xff, 0xe4, 0xc4) },
+ { "Bisque2", RGB_(0xee, 0xd5, 0xb7) },
+ { "Bisque3", RGB_(0xcd, 0xb7, 0x9e) },
+ { "Bisque4", RGB_(0x8b, 0x7d, 0x6b) },
+ { "Black", RGB_(0x00, 0x00, 0x00) },
+ { "BlanchedAlmond", RGB_(0xff, 0xeb, 0xcd) },
+ { "Blue", RGB_(0x00, 0x00, 0xff) },
+ { "Blue1", RGB_(0x0, 0x0, 0xff) },
+ { "Blue2", RGB_(0x0, 0x0, 0xee) },
+ { "Blue3", RGB_(0x0, 0x0, 0xcd) },
+ { "Blue4", RGB_(0x0, 0x0, 0x8b) },
+ { "BlueViolet", RGB_(0x8a, 0x2b, 0xe2) },
+ { "Brown", RGB_(0xa5, 0x2a, 0x2a) },
+ { "Brown1", RGB_(0xff, 0x40, 0x40) },
+ { "Brown2", RGB_(0xee, 0x3b, 0x3b) },
+ { "Brown3", RGB_(0xcd, 0x33, 0x33) },
+ { "Brown4", RGB_(0x8b, 0x23, 0x23) },
+ { "BurlyWood", RGB_(0xde, 0xb8, 0x87) },
+ { "Burlywood1", RGB_(0xff, 0xd3, 0x9b) },
+ { "Burlywood2", RGB_(0xee, 0xc5, 0x91) },
+ { "Burlywood3", RGB_(0xcd, 0xaa, 0x7d) },
+ { "Burlywood4", RGB_(0x8b, 0x73, 0x55) },
+ { "CadetBlue", RGB_(0x5f, 0x9e, 0xa0) },
+ { "CadetBlue1", RGB_(0x98, 0xf5, 0xff) },
+ { "CadetBlue2", RGB_(0x8e, 0xe5, 0xee) },
+ { "CadetBlue3", RGB_(0x7a, 0xc5, 0xcd) },
+ { "CadetBlue4", RGB_(0x53, 0x86, 0x8b) },
+ { "ChartReuse", RGB_(0x7f, 0xff, 0x00) },
+ { "Chartreuse1", RGB_(0x7f, 0xff, 0x0) },
+ { "Chartreuse2", RGB_(0x76, 0xee, 0x0) },
+ { "Chartreuse3", RGB_(0x66, 0xcd, 0x0) },
+ { "Chartreuse4", RGB_(0x45, 0x8b, 0x0) },
+ { "Chocolate", RGB_(0xd2, 0x69, 0x1e) },
+ { "Chocolate1", RGB_(0xff, 0x7f, 0x24) },
+ { "Chocolate2", RGB_(0xee, 0x76, 0x21) },
+ { "Chocolate3", RGB_(0xcd, 0x66, 0x1d) },
+ { "Chocolate4", RGB_(0x8b, 0x45, 0x13) },
+ { "Coral", RGB_(0xff, 0x7f, 0x50) },
+ { "Coral1", RGB_(0xff, 0x72, 0x56) },
+ { "Coral2", RGB_(0xee, 0x6a, 0x50) },
+ { "Coral3", RGB_(0xcd, 0x5b, 0x45) },
+ { "Coral4", RGB_(0x8b, 0x3e, 0x2f) },
+ { "CornFlowerBlue", RGB_(0x64, 0x95, 0xed) },
+ { "Cornsilk", RGB_(0xff, 0xf8, 0xdc) },
+ { "Cornsilk1", RGB_(0xff, 0xf8, 0xdc) },
+ { "Cornsilk2", RGB_(0xee, 0xe8, 0xcd) },
+ { "Cornsilk3", RGB_(0xcd, 0xc8, 0xb1) },
+ { "Cornsilk4", RGB_(0x8b, 0x88, 0x78) },
+ { "Crimson", RGB_(0xdc, 0x14, 0x3c) },
+ { "Cyan", RGB_(0x00, 0xff, 0xff) },
+ { "Cyan1", RGB_(0x0, 0xff, 0xff) },
+ { "Cyan2", RGB_(0x0, 0xee, 0xee) },
+ { "Cyan3", RGB_(0x0, 0xcd, 0xcd) },
+ { "Cyan4", RGB_(0x0, 0x8b, 0x8b) },
+ { "DarkBlue", RGB_(0x00, 0x00, 0x8b) },
+ { "DarkCyan", RGB_(0x00, 0x8b, 0x8b) },
+ { "DarkGoldenRod", RGB_(0xb8, 0x86, 0x0b) },
+ { "DarkGoldenrod1", RGB_(0xff, 0xb9, 0xf) },
+ { "DarkGoldenrod2", RGB_(0xee, 0xad, 0xe) },
+ { "DarkGoldenrod3", RGB_(0xcd, 0x95, 0xc) },
+ { "DarkGoldenrod4", RGB_(0x8b, 0x65, 0x8) },
+ { "DarkGray", RGB_(0xa9, 0xa9, 0xa9) },
+ { "DarkGreen", RGB_(0x00, 0x64, 0x00) },
+ { "DarkGrey", RGB_(0xa9, 0xa9, 0xa9) },
+ { "DarkKhaki", RGB_(0xbd, 0xb7, 0x6b) },
+ { "DarkMagenta", RGB_(0x8b, 0x00, 0x8b) },
+ { "DarkOliveGreen", RGB_(0x55, 0x6b, 0x2f) },
+ { "DarkOliveGreen1", RGB_(0xca, 0xff, 0x70) },
+ { "DarkOliveGreen2", RGB_(0xbc, 0xee, 0x68) },
+ { "DarkOliveGreen3", RGB_(0xa2, 0xcd, 0x5a) },
+ { "DarkOliveGreen4", RGB_(0x6e, 0x8b, 0x3d) },
+ { "DarkOrange", RGB_(0xff, 0x8c, 0x00) },
+ { "DarkOrange1", RGB_(0xff, 0x7f, 0x0) },
+ { "DarkOrange2", RGB_(0xee, 0x76, 0x0) },
+ { "DarkOrange3", RGB_(0xcd, 0x66, 0x0) },
+ { "DarkOrange4", RGB_(0x8b, 0x45, 0x0) },
+ { "DarkOrchid", RGB_(0x99, 0x32, 0xcc) },
+ { "DarkOrchid1", RGB_(0xbf, 0x3e, 0xff) },
+ { "DarkOrchid2", RGB_(0xb2, 0x3a, 0xee) },
+ { "DarkOrchid3", RGB_(0x9a, 0x32, 0xcd) },
+ { "DarkOrchid4", RGB_(0x68, 0x22, 0x8b) },
+ { "DarkRed", RGB_(0x8b, 0x00, 0x00) },
+ { "DarkSalmon", RGB_(0xe9, 0x96, 0x7a) },
+ { "DarkSeaGreen", RGB_(0x8f, 0xbc, 0x8f) },
+ { "DarkSeaGreen1", RGB_(0xc1, 0xff, 0xc1) },
+ { "DarkSeaGreen2", RGB_(0xb4, 0xee, 0xb4) },
+ { "DarkSeaGreen3", RGB_(0x9b, 0xcd, 0x9b) },
+ { "DarkSeaGreen4", RGB_(0x69, 0x8b, 0x69) },
+ { "DarkSlateBlue", RGB_(0x48, 0x3d, 0x8b) },
+ { "DarkSlateGray", RGB_(0x2f, 0x4f, 0x4f) },
+ { "DarkSlateGray1", RGB_(0x97, 0xff, 0xff) },
+ { "DarkSlateGray2", RGB_(0x8d, 0xee, 0xee) },
+ { "DarkSlateGray3", RGB_(0x79, 0xcd, 0xcd) },
+ { "DarkSlateGray4", RGB_(0x52, 0x8b, 0x8b) },
+ { "DarkSlateGrey", RGB_(0x2f, 0x4f, 0x4f) },
+ { "DarkTurquoise", RGB_(0x00, 0xce, 0xd1) },
+ { "DarkViolet", RGB_(0x94, 0x00, 0xd3) },
+ { "DarkYellow", RGB_(0xbb, 0xbb, 0x00) },
+ { "DeepPink", RGB_(0xff, 0x14, 0x93) },
+ { "DeepPink1", RGB_(0xff, 0x14, 0x93) },
+ { "DeepPink2", RGB_(0xee, 0x12, 0x89) },
+ { "DeepPink3", RGB_(0xcd, 0x10, 0x76) },
+ { "DeepPink4", RGB_(0x8b, 0xa, 0x50) },
+ { "DeepSkyBlue", RGB_(0x00, 0xbf, 0xff) },
+ { "DeepSkyBlue1", RGB_(0x0, 0xbf, 0xff) },
+ { "DeepSkyBlue2", RGB_(0x0, 0xb2, 0xee) },
+ { "DeepSkyBlue3", RGB_(0x0, 0x9a, 0xcd) },
+ { "DeepSkyBlue4", RGB_(0x0, 0x68, 0x8b) },
+ { "DimGray", RGB_(0x69, 0x69, 0x69) },
+ { "DimGrey", RGB_(0x69, 0x69, 0x69) },
+ { "DodgerBlue", RGB_(0x1e, 0x90, 0xff) },
+ { "DodgerBlue1", RGB_(0x1e, 0x90, 0xff) },
+ { "DodgerBlue2", RGB_(0x1c, 0x86, 0xee) },
+ { "DodgerBlue3", RGB_(0x18, 0x74, 0xcd) },
+ { "DodgerBlue4", RGB_(0x10, 0x4e, 0x8b) },
+ { "Firebrick", RGB_(0xb2, 0x22, 0x22) },
+ { "Firebrick1", RGB_(0xff, 0x30, 0x30) },
+ { "Firebrick2", RGB_(0xee, 0x2c, 0x2c) },
+ { "Firebrick3", RGB_(0xcd, 0x26, 0x26) },
+ { "Firebrick4", RGB_(0x8b, 0x1a, 0x1a) },
+ { "FloralWhite", RGB_(0xff, 0xfa, 0xf0) },
+ { "ForestGreen", RGB_(0x22, 0x8b, 0x22) },
+ { "Fuchsia", RGB_(0xff, 0x00, 0xff) },
+ { "Gainsboro", RGB_(0xdc, 0xdc, 0xdc) },
+ { "GhostWhite", RGB_(0xf8, 0xf8, 0xff) },
+ { "Gold", RGB_(0xff, 0xd7, 0x00) },
+ { "Gold1", RGB_(0xff, 0xd7, 0x0) },
+ { "Gold2", RGB_(0xee, 0xc9, 0x0) },
+ { "Gold3", RGB_(0xcd, 0xad, 0x0) },
+ { "Gold4", RGB_(0x8b, 0x75, 0x0) },
+ { "GoldenRod", RGB_(0xda, 0xa5, 0x20) },
+ { "Goldenrod1", RGB_(0xff, 0xc1, 0x25) },
+ { "Goldenrod2", RGB_(0xee, 0xb4, 0x22) },
+ { "Goldenrod3", RGB_(0xcd, 0x9b, 0x1d) },
+ { "Goldenrod4", RGB_(0x8b, 0x69, 0x14) },
+ { "Gray", RGB_(0x80, 0x80, 0x80) },
+ { "Gray0", RGB_(0x0, 0x0, 0x0) },
+ { "Gray1", RGB_(0x3, 0x3, 0x3) },
+ { "Gray10", RGB_(0x1a, 0x1a, 0x1a) },
+ { "Gray100", RGB_(0xff, 0xff, 0xff) },
+ { "Gray11", RGB_(0x1c, 0x1c, 0x1c) },
+ { "Gray12", RGB_(0x1f, 0x1f, 0x1f) },
+ { "Gray13", RGB_(0x21, 0x21, 0x21) },
+ { "Gray14", RGB_(0x24, 0x24, 0x24) },
+ { "Gray15", RGB_(0x26, 0x26, 0x26) },
+ { "Gray16", RGB_(0x29, 0x29, 0x29) },
+ { "Gray17", RGB_(0x2b, 0x2b, 0x2b) },
+ { "Gray18", RGB_(0x2e, 0x2e, 0x2e) },
+ { "Gray19", RGB_(0x30, 0x30, 0x30) },
+ { "Gray2", RGB_(0x5, 0x5, 0x5) },
+ { "Gray20", RGB_(0x33, 0x33, 0x33) },
+ { "Gray21", RGB_(0x36, 0x36, 0x36) },
+ { "Gray22", RGB_(0x38, 0x38, 0x38) },
+ { "Gray23", RGB_(0x3b, 0x3b, 0x3b) },
+ { "Gray24", RGB_(0x3d, 0x3d, 0x3d) },
+ { "Gray25", RGB_(0x40, 0x40, 0x40) },
+ { "Gray26", RGB_(0x42, 0x42, 0x42) },
+ { "Gray27", RGB_(0x45, 0x45, 0x45) },
+ { "Gray28", RGB_(0x47, 0x47, 0x47) },
+ { "Gray29", RGB_(0x4a, 0x4a, 0x4a) },
+ { "Gray3", RGB_(0x8, 0x8, 0x8) },
+ { "Gray30", RGB_(0x4d, 0x4d, 0x4d) },
+ { "Gray31", RGB_(0x4f, 0x4f, 0x4f) },
+ { "Gray32", RGB_(0x52, 0x52, 0x52) },
+ { "Gray33", RGB_(0x54, 0x54, 0x54) },
+ { "Gray34", RGB_(0x57, 0x57, 0x57) },
+ { "Gray35", RGB_(0x59, 0x59, 0x59) },
+ { "Gray36", RGB_(0x5c, 0x5c, 0x5c) },
+ { "Gray37", RGB_(0x5e, 0x5e, 0x5e) },
+ { "Gray38", RGB_(0x61, 0x61, 0x61) },
+ { "Gray39", RGB_(0x63, 0x63, 0x63) },
+ { "Gray4", RGB_(0xa, 0xa, 0xa) },
+ { "Gray40", RGB_(0x66, 0x66, 0x66) },
+ { "Gray41", RGB_(0x69, 0x69, 0x69) },
+ { "Gray42", RGB_(0x6b, 0x6b, 0x6b) },
+ { "Gray43", RGB_(0x6e, 0x6e, 0x6e) },
+ { "Gray44", RGB_(0x70, 0x70, 0x70) },
+ { "Gray45", RGB_(0x73, 0x73, 0x73) },
+ { "Gray46", RGB_(0x75, 0x75, 0x75) },
+ { "Gray47", RGB_(0x78, 0x78, 0x78) },
+ { "Gray48", RGB_(0x7a, 0x7a, 0x7a) },
+ { "Gray49", RGB_(0x7d, 0x7d, 0x7d) },
+ { "Gray5", RGB_(0xd, 0xd, 0xd) },
+ { "Gray50", RGB_(0x7f, 0x7f, 0x7f) },
+ { "Gray51", RGB_(0x82, 0x82, 0x82) },
+ { "Gray52", RGB_(0x85, 0x85, 0x85) },
+ { "Gray53", RGB_(0x87, 0x87, 0x87) },
+ { "Gray54", RGB_(0x8a, 0x8a, 0x8a) },
+ { "Gray55", RGB_(0x8c, 0x8c, 0x8c) },
+ { "Gray56", RGB_(0x8f, 0x8f, 0x8f) },
+ { "Gray57", RGB_(0x91, 0x91, 0x91) },
+ { "Gray58", RGB_(0x94, 0x94, 0x94) },
+ { "Gray59", RGB_(0x96, 0x96, 0x96) },
+ { "Gray6", RGB_(0xf, 0xf, 0xf) },
+ { "Gray60", RGB_(0x99, 0x99, 0x99) },
+ { "Gray61", RGB_(0x9c, 0x9c, 0x9c) },
+ { "Gray62", RGB_(0x9e, 0x9e, 0x9e) },
+ { "Gray63", RGB_(0xa1, 0xa1, 0xa1) },
+ { "Gray64", RGB_(0xa3, 0xa3, 0xa3) },
+ { "Gray65", RGB_(0xa6, 0xa6, 0xa6) },
+ { "Gray66", RGB_(0xa8, 0xa8, 0xa8) },
+ { "Gray67", RGB_(0xab, 0xab, 0xab) },
+ { "Gray68", RGB_(0xad, 0xad, 0xad) },
+ { "Gray69", RGB_(0xb0, 0xb0, 0xb0) },
+ { "Gray7", RGB_(0x12, 0x12, 0x12) },
+ { "Gray70", RGB_(0xb3, 0xb3, 0xb3) },
+ { "Gray71", RGB_(0xb5, 0xb5, 0xb5) },
+ { "Gray72", RGB_(0xb8, 0xb8, 0xb8) },
+ { "Gray73", RGB_(0xba, 0xba, 0xba) },
+ { "Gray74", RGB_(0xbd, 0xbd, 0xbd) },
+ { "Gray75", RGB_(0xbf, 0xbf, 0xbf) },
+ { "Gray76", RGB_(0xc2, 0xc2, 0xc2) },
+ { "Gray77", RGB_(0xc4, 0xc4, 0xc4) },
+ { "Gray78", RGB_(0xc7, 0xc7, 0xc7) },
+ { "Gray79", RGB_(0xc9, 0xc9, 0xc9) },
+ { "Gray8", RGB_(0x14, 0x14, 0x14) },
+ { "Gray80", RGB_(0xcc, 0xcc, 0xcc) },
+ { "Gray81", RGB_(0xcf, 0xcf, 0xcf) },
+ { "Gray82", RGB_(0xd1, 0xd1, 0xd1) },
+ { "Gray83", RGB_(0xd4, 0xd4, 0xd4) },
+ { "Gray84", RGB_(0xd6, 0xd6, 0xd6) },
+ { "Gray85", RGB_(0xd9, 0xd9, 0xd9) },
+ { "Gray86", RGB_(0xdb, 0xdb, 0xdb) },
+ { "Gray87", RGB_(0xde, 0xde, 0xde) },
+ { "Gray88", RGB_(0xe0, 0xe0, 0xe0) },
+ { "Gray89", RGB_(0xe3, 0xe3, 0xe3) },
+ { "Gray9", RGB_(0x17, 0x17, 0x17) },
+ { "Gray90", RGB_(0xe5, 0xe5, 0xe5) },
+ { "Gray91", RGB_(0xe8, 0xe8, 0xe8) },
+ { "Gray92", RGB_(0xeb, 0xeb, 0xeb) },
+ { "Gray93", RGB_(0xed, 0xed, 0xed) },
+ { "Gray94", RGB_(0xf0, 0xf0, 0xf0) },
+ { "Gray95", RGB_(0xf2, 0xf2, 0xf2) },
+ { "Gray96", RGB_(0xf5, 0xf5, 0xf5) },
+ { "Gray97", RGB_(0xf7, 0xf7, 0xf7) },
+ { "Gray98", RGB_(0xfa, 0xfa, 0xfa) },
+ { "Gray99", RGB_(0xfc, 0xfc, 0xfc) },
+ { "Green", RGB_(0x00, 0x80, 0x00) },
+ { "Green1", RGB_(0x0, 0xff, 0x0) },
+ { "Green2", RGB_(0x0, 0xee, 0x0) },
+ { "Green3", RGB_(0x0, 0xcd, 0x0) },
+ { "Green4", RGB_(0x0, 0x8b, 0x0) },
+ { "GreenYellow", RGB_(0xad, 0xff, 0x2f) },
+ { "Grey", RGB_(0x80, 0x80, 0x80) },
+ { "Grey0", RGB_(0x0, 0x0, 0x0) },
+ { "Grey1", RGB_(0x3, 0x3, 0x3) },
+ { "Grey10", RGB_(0x1a, 0x1a, 0x1a) },
+ { "Grey100", RGB_(0xff, 0xff, 0xff) },
+ { "Grey11", RGB_(0x1c, 0x1c, 0x1c) },
+ { "Grey12", RGB_(0x1f, 0x1f, 0x1f) },
+ { "Grey13", RGB_(0x21, 0x21, 0x21) },
+ { "Grey14", RGB_(0x24, 0x24, 0x24) },
+ { "Grey15", RGB_(0x26, 0x26, 0x26) },
+ { "Grey16", RGB_(0x29, 0x29, 0x29) },
+ { "Grey17", RGB_(0x2b, 0x2b, 0x2b) },
+ { "Grey18", RGB_(0x2e, 0x2e, 0x2e) },
+ { "Grey19", RGB_(0x30, 0x30, 0x30) },
+ { "Grey2", RGB_(0x5, 0x5, 0x5) },
+ { "Grey20", RGB_(0x33, 0x33, 0x33) },
+ { "Grey21", RGB_(0x36, 0x36, 0x36) },
+ { "Grey22", RGB_(0x38, 0x38, 0x38) },
+ { "Grey23", RGB_(0x3b, 0x3b, 0x3b) },
+ { "Grey24", RGB_(0x3d, 0x3d, 0x3d) },
+ { "Grey25", RGB_(0x40, 0x40, 0x40) },
+ { "Grey26", RGB_(0x42, 0x42, 0x42) },
+ { "Grey27", RGB_(0x45, 0x45, 0x45) },
+ { "Grey28", RGB_(0x47, 0x47, 0x47) },
+ { "Grey29", RGB_(0x4a, 0x4a, 0x4a) },
+ { "Grey3", RGB_(0x8, 0x8, 0x8) },
+ { "Grey30", RGB_(0x4d, 0x4d, 0x4d) },
+ { "Grey31", RGB_(0x4f, 0x4f, 0x4f) },
+ { "Grey32", RGB_(0x52, 0x52, 0x52) },
+ { "Grey33", RGB_(0x54, 0x54, 0x54) },
+ { "Grey34", RGB_(0x57, 0x57, 0x57) },
+ { "Grey35", RGB_(0x59, 0x59, 0x59) },
+ { "Grey36", RGB_(0x5c, 0x5c, 0x5c) },
+ { "Grey37", RGB_(0x5e, 0x5e, 0x5e) },
+ { "Grey38", RGB_(0x61, 0x61, 0x61) },
+ { "Grey39", RGB_(0x63, 0x63, 0x63) },
+ { "Grey4", RGB_(0xa, 0xa, 0xa) },
+ { "Grey40", RGB_(0x66, 0x66, 0x66) },
+ { "Grey41", RGB_(0x69, 0x69, 0x69) },
+ { "Grey42", RGB_(0x6b, 0x6b, 0x6b) },
+ { "Grey43", RGB_(0x6e, 0x6e, 0x6e) },
+ { "Grey44", RGB_(0x70, 0x70, 0x70) },
+ { "Grey45", RGB_(0x73, 0x73, 0x73) },
+ { "Grey46", RGB_(0x75, 0x75, 0x75) },
+ { "Grey47", RGB_(0x78, 0x78, 0x78) },
+ { "Grey48", RGB_(0x7a, 0x7a, 0x7a) },
+ { "Grey49", RGB_(0x7d, 0x7d, 0x7d) },
+ { "Grey5", RGB_(0xd, 0xd, 0xd) },
+ { "Grey50", RGB_(0x7f, 0x7f, 0x7f) },
+ { "Grey51", RGB_(0x82, 0x82, 0x82) },
+ { "Grey52", RGB_(0x85, 0x85, 0x85) },
+ { "Grey53", RGB_(0x87, 0x87, 0x87) },
+ { "Grey54", RGB_(0x8a, 0x8a, 0x8a) },
+ { "Grey55", RGB_(0x8c, 0x8c, 0x8c) },
+ { "Grey56", RGB_(0x8f, 0x8f, 0x8f) },
+ { "Grey57", RGB_(0x91, 0x91, 0x91) },
+ { "Grey58", RGB_(0x94, 0x94, 0x94) },
+ { "Grey59", RGB_(0x96, 0x96, 0x96) },
+ { "Grey6", RGB_(0xf, 0xf, 0xf) },
+ { "Grey60", RGB_(0x99, 0x99, 0x99) },
+ { "Grey61", RGB_(0x9c, 0x9c, 0x9c) },
+ { "Grey62", RGB_(0x9e, 0x9e, 0x9e) },
+ { "Grey63", RGB_(0xa1, 0xa1, 0xa1) },
+ { "Grey64", RGB_(0xa3, 0xa3, 0xa3) },
+ { "Grey65", RGB_(0xa6, 0xa6, 0xa6) },
+ { "Grey66", RGB_(0xa8, 0xa8, 0xa8) },
+ { "Grey67", RGB_(0xab, 0xab, 0xab) },
+ { "Grey68", RGB_(0xad, 0xad, 0xad) },
+ { "Grey69", RGB_(0xb0, 0xb0, 0xb0) },
+ { "Grey7", RGB_(0x12, 0x12, 0x12) },
+ { "Grey70", RGB_(0xb3, 0xb3, 0xb3) },
+ { "Grey71", RGB_(0xb5, 0xb5, 0xb5) },
+ { "Grey72", RGB_(0xb8, 0xb8, 0xb8) },
+ { "Grey73", RGB_(0xba, 0xba, 0xba) },
+ { "Grey74", RGB_(0xbd, 0xbd, 0xbd) },
+ { "Grey75", RGB_(0xbf, 0xbf, 0xbf) },
+ { "Grey76", RGB_(0xc2, 0xc2, 0xc2) },
+ { "Grey77", RGB_(0xc4, 0xc4, 0xc4) },
+ { "Grey78", RGB_(0xc7, 0xc7, 0xc7) },
+ { "Grey79", RGB_(0xc9, 0xc9, 0xc9) },
+ { "Grey8", RGB_(0x14, 0x14, 0x14) },
+ { "Grey80", RGB_(0xcc, 0xcc, 0xcc) },
+ { "Grey81", RGB_(0xcf, 0xcf, 0xcf) },
+ { "Grey82", RGB_(0xd1, 0xd1, 0xd1) },
+ { "Grey83", RGB_(0xd4, 0xd4, 0xd4) },
+ { "Grey84", RGB_(0xd6, 0xd6, 0xd6) },
+ { "Grey85", RGB_(0xd9, 0xd9, 0xd9) },
+ { "Grey86", RGB_(0xdb, 0xdb, 0xdb) },
+ { "Grey87", RGB_(0xde, 0xde, 0xde) },
+ { "Grey88", RGB_(0xe0, 0xe0, 0xe0) },
+ { "Grey89", RGB_(0xe3, 0xe3, 0xe3) },
+ { "Grey9", RGB_(0x17, 0x17, 0x17) },
+ { "Grey90", RGB_(0xe5, 0xe5, 0xe5) },
+ { "Grey91", RGB_(0xe8, 0xe8, 0xe8) },
+ { "Grey92", RGB_(0xeb, 0xeb, 0xeb) },
+ { "Grey93", RGB_(0xed, 0xed, 0xed) },
+ { "Grey94", RGB_(0xf0, 0xf0, 0xf0) },
+ { "Grey95", RGB_(0xf2, 0xf2, 0xf2) },
+ { "Grey96", RGB_(0xf5, 0xf5, 0xf5) },
+ { "Grey97", RGB_(0xf7, 0xf7, 0xf7) },
+ { "Grey98", RGB_(0xfa, 0xfa, 0xfa) },
+ { "Grey99", RGB_(0xfc, 0xfc, 0xfc) },
+ { "Honeydew", RGB_(0xf0, 0xff, 0xf0) },
+ { "Honeydew1", RGB_(0xf0, 0xff, 0xf0) },
+ { "Honeydew2", RGB_(0xe0, 0xee, 0xe0) },
+ { "Honeydew3", RGB_(0xc1, 0xcd, 0xc1) },
+ { "Honeydew4", RGB_(0x83, 0x8b, 0x83) },
+ { "HotPink", RGB_(0xff, 0x69, 0xb4) },
+ { "HotPink1", RGB_(0xff, 0x6e, 0xb4) },
+ { "HotPink2", RGB_(0xee, 0x6a, 0xa7) },
+ { "HotPink3", RGB_(0xcd, 0x60, 0x90) },
+ { "HotPink4", RGB_(0x8b, 0x3a, 0x62) },
+ { "IndianRed", RGB_(0xcd, 0x5c, 0x5c) },
+ { "IndianRed1", RGB_(0xff, 0x6a, 0x6a) },
+ { "IndianRed2", RGB_(0xee, 0x63, 0x63) },
+ { "IndianRed3", RGB_(0xcd, 0x55, 0x55) },
+ { "IndianRed4", RGB_(0x8b, 0x3a, 0x3a) },
+ { "Indigo", RGB_(0x4b, 0x00, 0x82) },
+ { "Ivory", RGB_(0xff, 0xff, 0xf0) },
+ { "Ivory1", RGB_(0xff, 0xff, 0xf0) },
+ { "Ivory2", RGB_(0xee, 0xee, 0xe0) },
+ { "Ivory3", RGB_(0xcd, 0xcd, 0xc1) },
+ { "Ivory4", RGB_(0x8b, 0x8b, 0x83) },
+ { "Khaki", RGB_(0xf0, 0xe6, 0x8c) },
+ { "Khaki1", RGB_(0xff, 0xf6, 0x8f) },
+ { "Khaki2", RGB_(0xee, 0xe6, 0x85) },
+ { "Khaki3", RGB_(0xcd, 0xc6, 0x73) },
+ { "Khaki4", RGB_(0x8b, 0x86, 0x4e) },
+ { "Lavender", RGB_(0xe6, 0xe6, 0xfa) },
+ { "LavenderBlush", RGB_(0xff, 0xf0, 0xf5) },
+ { "LavenderBlush1", RGB_(0xff, 0xf0, 0xf5) },
+ { "LavenderBlush2", RGB_(0xee, 0xe0, 0xe5) },
+ { "LavenderBlush3", RGB_(0xcd, 0xc1, 0xc5) },
+ { "LavenderBlush4", RGB_(0x8b, 0x83, 0x86) },
+ { "LawnGreen", RGB_(0x7c, 0xfc, 0x00) },
+ { "LemonChiffon", RGB_(0xff, 0xfa, 0xcd) },
+ { "LemonChiffon1", RGB_(0xff, 0xfa, 0xcd) },
+ { "LemonChiffon2", RGB_(0xee, 0xe9, 0xbf) },
+ { "LemonChiffon3", RGB_(0xcd, 0xc9, 0xa5) },
+ { "LemonChiffon4", RGB_(0x8b, 0x89, 0x70) },
+ { "LightBlue", RGB_(0xad, 0xd8, 0xe6) },
+ { "LightBlue1", RGB_(0xbf, 0xef, 0xff) },
+ { "LightBlue2", RGB_(0xb2, 0xdf, 0xee) },
+ { "LightBlue3", RGB_(0x9a, 0xc0, 0xcd) },
+ { "LightBlue4", RGB_(0x68, 0x83, 0x8b) },
+ { "LightCoral", RGB_(0xf0, 0x80, 0x80) },
+ { "LightCyan", RGB_(0xe0, 0xff, 0xff) },
+ { "LightCyan1", RGB_(0xe0, 0xff, 0xff) },
+ { "LightCyan2", RGB_(0xd1, 0xee, 0xee) },
+ { "LightCyan3", RGB_(0xb4, 0xcd, 0xcd) },
+ { "LightCyan4", RGB_(0x7a, 0x8b, 0x8b) },
+ { "LightGoldenrod", RGB_(0xee, 0xdd, 0x82) },
+ { "LightGoldenrod1", RGB_(0xff, 0xec, 0x8b) },
+ { "LightGoldenrod2", RGB_(0xee, 0xdc, 0x82) },
+ { "LightGoldenrod3", RGB_(0xcd, 0xbe, 0x70) },
+ { "LightGoldenrod4", RGB_(0x8b, 0x81, 0x4c) },
+ { "LightGoldenRodYellow", RGB_(0xfa, 0xfa, 0xd2) },
+ { "LightGray", RGB_(0xd3, 0xd3, 0xd3) },
+ { "LightGreen", RGB_(0x90, 0xee, 0x90) },
+ { "LightGrey", RGB_(0xd3, 0xd3, 0xd3) },
+ { "LightMagenta", RGB_(0xff, 0xbb, 0xff) },
+ { "LightPink", RGB_(0xff, 0xb6, 0xc1) },
+ { "LightPink1", RGB_(0xff, 0xae, 0xb9) },
+ { "LightPink2", RGB_(0xee, 0xa2, 0xad) },
+ { "LightPink3", RGB_(0xcd, 0x8c, 0x95) },
+ { "LightPink4", RGB_(0x8b, 0x5f, 0x65) },
+ { "LightRed", RGB_(0xff, 0xbb, 0xbb) },
+ { "LightSalmon", RGB_(0xff, 0xa0, 0x7a) },
+ { "LightSalmon1", RGB_(0xff, 0xa0, 0x7a) },
+ { "LightSalmon2", RGB_(0xee, 0x95, 0x72) },
+ { "LightSalmon3", RGB_(0xcd, 0x81, 0x62) },
+ { "LightSalmon4", RGB_(0x8b, 0x57, 0x42) },
+ { "LightSeaGreen", RGB_(0x20, 0xb2, 0xaa) },
+ { "LightSkyBlue", RGB_(0x87, 0xce, 0xfa) },
+ { "LightSkyBlue1", RGB_(0xb0, 0xe2, 0xff) },
+ { "LightSkyBlue2", RGB_(0xa4, 0xd3, 0xee) },
+ { "LightSkyBlue3", RGB_(0x8d, 0xb6, 0xcd) },
+ { "LightSkyBlue4", RGB_(0x60, 0x7b, 0x8b) },
+ { "LightSlateBlue", RGB_(0x84, 0x70, 0xff) },
+ { "LightSlateGray", RGB_(0x77, 0x88, 0x99) },
+ { "LightSlateGrey", RGB_(0x77, 0x88, 0x99) },
+ { "LightSteelBlue", RGB_(0xb0, 0xc4, 0xde) },
+ { "LightSteelBlue1", RGB_(0xca, 0xe1, 0xff) },
+ { "LightSteelBlue2", RGB_(0xbc, 0xd2, 0xee) },
+ { "LightSteelBlue3", RGB_(0xa2, 0xb5, 0xcd) },
+ { "LightSteelBlue4", RGB_(0x6e, 0x7b, 0x8b) },
+ { "LightYellow", RGB_(0xff, 0xff, 0xe0) },
+ { "LightYellow1", RGB_(0xff, 0xff, 0xe0) },
+ { "LightYellow2", RGB_(0xee, 0xee, 0xd1) },
+ { "LightYellow3", RGB_(0xcd, 0xcd, 0xb4) },
+ { "LightYellow4", RGB_(0x8b, 0x8b, 0x7a) },
+ { "Lime", RGB_(0x00, 0xff, 0x00) },
+ { "LimeGreen", RGB_(0x32, 0xcd, 0x32) },
+ { "Linen", RGB_(0xfa, 0xf0, 0xe6) },
+ { "Magenta", RGB_(0xff, 0x00, 0xff) },
+ { "Magenta1", RGB_(0xff, 0x0, 0xff) },
+ { "Magenta2", RGB_(0xee, 0x0, 0xee) },
+ { "Magenta3", RGB_(0xcd, 0x0, 0xcd) },
+ { "Magenta4", RGB_(0x8b, 0x0, 0x8b) },
+ { "Maroon", RGB_(0x80, 0x00, 0x00) },
+ { "Maroon1", RGB_(0xff, 0x34, 0xb3) },
+ { "Maroon2", RGB_(0xee, 0x30, 0xa7) },
+ { "Maroon3", RGB_(0xcd, 0x29, 0x90) },
+ { "Maroon4", RGB_(0x8b, 0x1c, 0x62) },
+ { "MediumAquamarine", RGB_(0x66, 0xcd, 0xaa) },
+ { "MediumBlue", RGB_(0x00, 0x00, 0xcd) },
+ { "MediumOrchid", RGB_(0xba, 0x55, 0xd3) },
+ { "MediumOrchid1", RGB_(0xe0, 0x66, 0xff) },
+ { "MediumOrchid2", RGB_(0xd1, 0x5f, 0xee) },
+ { "MediumOrchid3", RGB_(0xb4, 0x52, 0xcd) },
+ { "MediumOrchid4", RGB_(0x7a, 0x37, 0x8b) },
+ { "MediumPurple", RGB_(0x93, 0x70, 0xdb) },
+ { "MediumPurple1", RGB_(0xab, 0x82, 0xff) },
+ { "MediumPurple2", RGB_(0x9f, 0x79, 0xee) },
+ { "MediumPurple3", RGB_(0x89, 0x68, 0xcd) },
+ { "MediumPurple4", RGB_(0x5d, 0x47, 0x8b) },
+ { "MediumSeaGreen", RGB_(0x3c, 0xb3, 0x71) },
+ { "MediumSlateBlue", RGB_(0x7b, 0x68, 0xee) },
+ { "MediumSpringGreen", RGB_(0x00, 0xfa, 0x9a) },
+ { "MediumTurquoise", RGB_(0x48, 0xd1, 0xcc) },
+ { "MediumVioletRed", RGB_(0xc7, 0x15, 0x85) },
+ { "MidnightBlue", RGB_(0x19, 0x19, 0x70) },
+ { "MintCream", RGB_(0xf5, 0xff, 0xfa) },
+ { "MistyRose", RGB_(0xff, 0xe4, 0xe1) },
+ { "MistyRose1", RGB_(0xff, 0xe4, 0xe1) },
+ { "MistyRose2", RGB_(0xee, 0xd5, 0xd2) },
+ { "MistyRose3", RGB_(0xcd, 0xb7, 0xb5) },
+ { "MistyRose4", RGB_(0x8b, 0x7d, 0x7b) },
+ { "Moccasin", RGB_(0xff, 0xe4, 0xb5) },
+ { "NavajoWhite", RGB_(0xff, 0xde, 0xad) },
+ { "NavajoWhite1", RGB_(0xff, 0xde, 0xad) },
+ { "NavajoWhite2", RGB_(0xee, 0xcf, 0xa1) },
+ { "NavajoWhite3", RGB_(0xcd, 0xb3, 0x8b) },
+ { "NavajoWhite4", RGB_(0x8b, 0x79, 0x5e) },
+ { "Navy", RGB_(0x00, 0x00, 0x80) },
+ { "NavyBlue", RGB_(0x0, 0x0, 0x80) },
+ { "OldLace", RGB_(0xfd, 0xf5, 0xe6) },
+ { "Olive", RGB_(0x80, 0x80, 0x00) },
+ { "OliveDrab", RGB_(0x6b, 0x8e, 0x23) },
+ { "OliveDrab1", RGB_(0xc0, 0xff, 0x3e) },
+ { "OliveDrab2", RGB_(0xb3, 0xee, 0x3a) },
+ { "OliveDrab3", RGB_(0x9a, 0xcd, 0x32) },
+ { "OliveDrab4", RGB_(0x69, 0x8b, 0x22) },
+ { "Orange", RGB_(0xff, 0xa5, 0x00) },
+ { "Orange1", RGB_(0xff, 0xa5, 0x0) },
+ { "Orange2", RGB_(0xee, 0x9a, 0x0) },
+ { "Orange3", RGB_(0xcd, 0x85, 0x0) },
+ { "Orange4", RGB_(0x8b, 0x5a, 0x0) },
+ { "OrangeRed", RGB_(0xff, 0x45, 0x00) },
+ { "OrangeRed1", RGB_(0xff, 0x45, 0x0) },
+ { "OrangeRed2", RGB_(0xee, 0x40, 0x0) },
+ { "OrangeRed3", RGB_(0xcd, 0x37, 0x0) },
+ { "OrangeRed4", RGB_(0x8b, 0x25, 0x0) },
+ { "Orchid", RGB_(0xda, 0x70, 0xd6) },
+ { "Orchid1", RGB_(0xff, 0x83, 0xfa) },
+ { "Orchid2", RGB_(0xee, 0x7a, 0xe9) },
+ { "Orchid3", RGB_(0xcd, 0x69, 0xc9) },
+ { "Orchid4", RGB_(0x8b, 0x47, 0x89) },
+ { "PaleGoldenRod", RGB_(0xee, 0xe8, 0xaa) },
+ { "PaleGreen", RGB_(0x98, 0xfb, 0x98) },
+ { "PaleGreen1", RGB_(0x9a, 0xff, 0x9a) },
+ { "PaleGreen2", RGB_(0x90, 0xee, 0x90) },
+ { "PaleGreen3", RGB_(0x7c, 0xcd, 0x7c) },
+ { "PaleGreen4", RGB_(0x54, 0x8b, 0x54) },
+ { "PaleTurquoise", RGB_(0xaf, 0xee, 0xee) },
+ { "PaleTurquoise1", RGB_(0xbb, 0xff, 0xff) },
+ { "PaleTurquoise2", RGB_(0xae, 0xee, 0xee) },
+ { "PaleTurquoise3", RGB_(0x96, 0xcd, 0xcd) },
+ { "PaleTurquoise4", RGB_(0x66, 0x8b, 0x8b) },
+ { "PaleVioletRed", RGB_(0xdb, 0x70, 0x93) },
+ { "PaleVioletRed1", RGB_(0xff, 0x82, 0xab) },
+ { "PaleVioletRed2", RGB_(0xee, 0x79, 0x9f) },
+ { "PaleVioletRed3", RGB_(0xcd, 0x68, 0x89) },
+ { "PaleVioletRed4", RGB_(0x8b, 0x47, 0x5d) },
+ { "PapayaWhip", RGB_(0xff, 0xef, 0xd5) },
+ { "PeachPuff", RGB_(0xff, 0xda, 0xb9) },
+ { "PeachPuff1", RGB_(0xff, 0xda, 0xb9) },
+ { "PeachPuff2", RGB_(0xee, 0xcb, 0xad) },
+ { "PeachPuff3", RGB_(0xcd, 0xaf, 0x95) },
+ { "PeachPuff4", RGB_(0x8b, 0x77, 0x65) },
+ { "Peru", RGB_(0xcd, 0x85, 0x3f) },
+ { "Pink", RGB_(0xff, 0xc0, 0xcb) },
+ { "Pink1", RGB_(0xff, 0xb5, 0xc5) },
+ { "Pink2", RGB_(0xee, 0xa9, 0xb8) },
+ { "Pink3", RGB_(0xcd, 0x91, 0x9e) },
+ { "Pink4", RGB_(0x8b, 0x63, 0x6c) },
+ { "Plum", RGB_(0xdd, 0xa0, 0xdd) },
+ { "Plum1", RGB_(0xff, 0xbb, 0xff) },
+ { "Plum2", RGB_(0xee, 0xae, 0xee) },
+ { "Plum3", RGB_(0xcd, 0x96, 0xcd) },
+ { "Plum4", RGB_(0x8b, 0x66, 0x8b) },
+ { "PowderBlue", RGB_(0xb0, 0xe0, 0xe6) },
+ { "Purple", RGB_(0x80, 0x00, 0x80) },
+ { "Purple1", RGB_(0x9b, 0x30, 0xff) },
+ { "Purple2", RGB_(0x91, 0x2c, 0xee) },
+ { "Purple3", RGB_(0x7d, 0x26, 0xcd) },
+ { "Purple4", RGB_(0x55, 0x1a, 0x8b) },
+ { "RebeccaPurple", RGB_(0x66, 0x33, 0x99) },
+ { "Red", RGB_(0xff, 0x00, 0x00) },
+ { "Red1", RGB_(0xff, 0x0, 0x0) },
+ { "Red2", RGB_(0xee, 0x0, 0x0) },
+ { "Red3", RGB_(0xcd, 0x0, 0x0) },
+ { "Red4", RGB_(0x8b, 0x0, 0x0) },
+ { "RosyBrown", RGB_(0xbc, 0x8f, 0x8f) },
+ { "RosyBrown1", RGB_(0xff, 0xc1, 0xc1) },
+ { "RosyBrown2", RGB_(0xee, 0xb4, 0xb4) },
+ { "RosyBrown3", RGB_(0xcd, 0x9b, 0x9b) },
+ { "RosyBrown4", RGB_(0x8b, 0x69, 0x69) },
+ { "RoyalBlue", RGB_(0x41, 0x69, 0xe1) },
+ { "RoyalBlue1", RGB_(0x48, 0x76, 0xff) },
+ { "RoyalBlue2", RGB_(0x43, 0x6e, 0xee) },
+ { "RoyalBlue3", RGB_(0x3a, 0x5f, 0xcd) },
+ { "RoyalBlue4", RGB_(0x27, 0x40, 0x8b) },
+ { "SaddleBrown", RGB_(0x8b, 0x45, 0x13) },
+ { "Salmon", RGB_(0xfa, 0x80, 0x72) },
+ { "Salmon1", RGB_(0xff, 0x8c, 0x69) },
+ { "Salmon2", RGB_(0xee, 0x82, 0x62) },
+ { "Salmon3", RGB_(0xcd, 0x70, 0x54) },
+ { "Salmon4", RGB_(0x8b, 0x4c, 0x39) },
+ { "SandyBrown", RGB_(0xf4, 0xa4, 0x60) },
+ { "SeaGreen", RGB_(0x2e, 0x8b, 0x57) },
+ { "SeaGreen1", RGB_(0x54, 0xff, 0x9f) },
+ { "SeaGreen2", RGB_(0x4e, 0xee, 0x94) },
+ { "SeaGreen3", RGB_(0x43, 0xcd, 0x80) },
+ { "SeaGreen4", RGB_(0x2e, 0x8b, 0x57) },
+ { "SeaShell", RGB_(0xff, 0xf5, 0xee) },
+ { "Seashell1", RGB_(0xff, 0xf5, 0xee) },
+ { "Seashell2", RGB_(0xee, 0xe5, 0xde) },
+ { "Seashell3", RGB_(0xcd, 0xc5, 0xbf) },
+ { "Seashell4", RGB_(0x8b, 0x86, 0x82) },
+ { "Sienna", RGB_(0xa0, 0x52, 0x2d) },
+ { "Sienna1", RGB_(0xff, 0x82, 0x47) },
+ { "Sienna2", RGB_(0xee, 0x79, 0x42) },
+ { "Sienna3", RGB_(0xcd, 0x68, 0x39) },
+ { "Sienna4", RGB_(0x8b, 0x47, 0x26) },
+ { "Silver", RGB_(0xc0, 0xc0, 0xc0) },
+ { "SkyBlue", RGB_(0x87, 0xce, 0xeb) },
+ { "SkyBlue1", RGB_(0x87, 0xce, 0xff) },
+ { "SkyBlue2", RGB_(0x7e, 0xc0, 0xee) },
+ { "SkyBlue3", RGB_(0x6c, 0xa6, 0xcd) },
+ { "SkyBlue4", RGB_(0x4a, 0x70, 0x8b) },
+ { "SlateBlue", RGB_(0x6a, 0x5a, 0xcd) },
+ { "SlateBlue1", RGB_(0x83, 0x6f, 0xff) },
+ { "SlateBlue2", RGB_(0x7a, 0x67, 0xee) },
+ { "SlateBlue3", RGB_(0x69, 0x59, 0xcd) },
+ { "SlateBlue4", RGB_(0x47, 0x3c, 0x8b) },
+ { "SlateGray", RGB_(0x70, 0x80, 0x90) },
+ { "SlateGray1", RGB_(0xc6, 0xe2, 0xff) },
+ { "SlateGray2", RGB_(0xb9, 0xd3, 0xee) },
+ { "SlateGray3", RGB_(0x9f, 0xb6, 0xcd) },
+ { "SlateGray4", RGB_(0x6c, 0x7b, 0x8b) },
+ { "SlateGrey", RGB_(0x70, 0x80, 0x90) },
+ { "Snow", RGB_(0xff, 0xfa, 0xfa) },
+ { "Snow1", RGB_(0xff, 0xfa, 0xfa) },
+ { "Snow2", RGB_(0xee, 0xe9, 0xe9) },
+ { "Snow3", RGB_(0xcd, 0xc9, 0xc9) },
+ { "Snow4", RGB_(0x8b, 0x89, 0x89) },
+ { "SpringGreen", RGB_(0x00, 0xff, 0x7f) },
+ { "SpringGreen1", RGB_(0x0, 0xff, 0x7f) },
+ { "SpringGreen2", RGB_(0x0, 0xee, 0x76) },
+ { "SpringGreen3", RGB_(0x0, 0xcd, 0x66) },
+ { "SpringGreen4", RGB_(0x0, 0x8b, 0x45) },
+ { "SteelBlue", RGB_(0x46, 0x82, 0xb4) },
+ { "SteelBlue1", RGB_(0x63, 0xb8, 0xff) },
+ { "SteelBlue2", RGB_(0x5c, 0xac, 0xee) },
+ { "SteelBlue3", RGB_(0x4f, 0x94, 0xcd) },
+ { "SteelBlue4", RGB_(0x36, 0x64, 0x8b) },
+ { "Tan", RGB_(0xd2, 0xb4, 0x8c) },
+ { "Tan1", RGB_(0xff, 0xa5, 0x4f) },
+ { "Tan2", RGB_(0xee, 0x9a, 0x49) },
+ { "Tan3", RGB_(0xcd, 0x85, 0x3f) },
+ { "Tan4", RGB_(0x8b, 0x5a, 0x2b) },
+ { "Teal", RGB_(0x00, 0x80, 0x80) },
+ { "Thistle", RGB_(0xd8, 0xbf, 0xd8) },
+ { "Thistle1", RGB_(0xff, 0xe1, 0xff) },
+ { "Thistle2", RGB_(0xee, 0xd2, 0xee) },
+ { "Thistle3", RGB_(0xcd, 0xb5, 0xcd) },
+ { "Thistle4", RGB_(0x8b, 0x7b, 0x8b) },
+ { "Tomato", RGB_(0xff, 0x63, 0x47) },
+ { "Tomato1", RGB_(0xff, 0x63, 0x47) },
+ { "Tomato2", RGB_(0xee, 0x5c, 0x42) },
+ { "Tomato3", RGB_(0xcd, 0x4f, 0x39) },
+ { "Tomato4", RGB_(0x8b, 0x36, 0x26) },
+ { "Turquoise", RGB_(0x40, 0xe0, 0xd0) },
+ { "Turquoise1", RGB_(0x0, 0xf5, 0xff) },
+ { "Turquoise2", RGB_(0x0, 0xe5, 0xee) },
+ { "Turquoise3", RGB_(0x0, 0xc5, 0xcd) },
+ { "Turquoise4", RGB_(0x0, 0x86, 0x8b) },
+ { "Violet", RGB_(0xee, 0x82, 0xee) },
+ { "VioletRed", RGB_(0xd0, 0x20, 0x90) },
+ { "VioletRed1", RGB_(0xff, 0x3e, 0x96) },
+ { "VioletRed2", RGB_(0xee, 0x3a, 0x8c) },
+ { "VioletRed3", RGB_(0xcd, 0x32, 0x78) },
+ { "VioletRed4", RGB_(0x8b, 0x22, 0x52) },
+ { "WebGray", RGB_(0x80, 0x80, 0x80) },
+ { "WebGreen", RGB_(0x0, 0x80, 0x0) },
+ { "WebGrey", RGB_(0x80, 0x80, 0x80) },
+ { "WebMaroon", RGB_(0x80, 0x0, 0x0) },
+ { "WebPurple", RGB_(0x80, 0x0, 0x80) },
+ { "Wheat", RGB_(0xf5, 0xde, 0xb3) },
+ { "Wheat1", RGB_(0xff, 0xe7, 0xba) },
+ { "Wheat2", RGB_(0xee, 0xd8, 0xae) },
+ { "Wheat3", RGB_(0xcd, 0xba, 0x96) },
+ { "Wheat4", RGB_(0x8b, 0x7e, 0x66) },
+ { "White", RGB_(0xff, 0xff, 0xff) },
+ { "WhiteSmoke", RGB_(0xf5, 0xf5, 0xf5) },
+ { "X11Gray", RGB_(0xbe, 0xbe, 0xbe) },
+ { "X11Green", RGB_(0x0, 0xff, 0x0) },
+ { "X11Grey", RGB_(0xbe, 0xbe, 0xbe) },
+ { "X11Maroon", RGB_(0xb0, 0x30, 0x60) },
+ { "X11Purple", RGB_(0xa0, 0x20, 0xf0) },
+ { "Yellow", RGB_(0xff, 0xff, 0x00) },
+ { "Yellow1", RGB_(0xff, 0xff, 0x0) },
+ { "Yellow2", RGB_(0xee, 0xee, 0x0) },
+ { "Yellow3", RGB_(0xcd, 0xcd, 0x0) },
+ { "Yellow4", RGB_(0x8b, 0x8b, 0x0) },
+ { "YellowGreen", RGB_(0x9a, 0xcd, 0x32) },
+ { NULL, 0 },
};
-RgbValue name_to_color(uint8_t *name)
+
+/// Translate to RgbValue if \p name is an hex value (e.g. #XXXXXX),
+/// else look into color_name_table to translate a color name to its
+/// hex value
+///
+/// @param[in] name string value to convert to RGB
+/// return the hex value or -1 if could not find a correct value
+RgbValue name_to_color(const char_u *name)
{
if (name[0] == '#' && isxdigit(name[1]) && isxdigit(name[2])
@@ -7684,6 +8339,10 @@ RgbValue name_to_color(uint8_t *name)
&& isxdigit(name[6]) && name[7] == NUL) {
// rgb hex string
return strtol((char *)(name + 1), NULL, 16);
+ } else if (!STRICMP(name, "bg") || !STRICMP(name, "background")) {
+ return normal_bg;
+ } else if (!STRICMP(name, "fg") || !STRICMP(name, "foreground")) {
+ return normal_fg;
}
for (int i = 0; color_name_table[i].name != NULL; i++) {
@@ -7695,6 +8354,7 @@ RgbValue name_to_color(uint8_t *name)
return -1;
}
+
/**************************************
* End of Highlighting stuff *
**************************************/
diff --git a/src/nvim/syntax.h b/src/nvim/syntax.h
index af2ac719c6..9fbad74f64 100644
--- a/src/nvim/syntax.h
+++ b/src/nvim/syntax.h
@@ -3,19 +3,9 @@
#include <stdbool.h>
+#include "nvim/globals.h"
#include "nvim/buffer_defs.h"
-
-/*
- * Terminal highlighting attribute bits.
- * Attributes above HL_ALL are used for syntax highlighting.
- */
-#define HL_NORMAL 0x00
-#define HL_INVERSE 0x01
-#define HL_BOLD 0x02
-#define HL_ITALIC 0x04
-#define HL_UNDERLINE 0x08
-#define HL_UNDERCURL 0x10
-#define HL_STANDOUT 0x20
+#include "nvim/ex_cmds_defs.h"
#define HL_CONTAINED 0x01 /* not used on toplevel */
#define HL_TRANSP 0x02 /* has no highlighting */
@@ -43,6 +33,9 @@ typedef struct {
} color_name_table_T;
extern color_name_table_T color_name_table[];
+/// Array of highlight definitions, used for unit testing
+extern const char *const highlight_init_cmdline[];
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "syntax.h.generated.h"
#endif
diff --git a/src/nvim/syntax_defs.h b/src/nvim/syntax_defs.h
index 8d207e6286..5ee0611d58 100644
--- a/src/nvim/syntax_defs.h
+++ b/src/nvim/syntax_defs.h
@@ -1,9 +1,7 @@
#ifndef NVIM_SYNTAX_DEFS_H
#define NVIM_SYNTAX_DEFS_H
-#include "nvim/regexp_defs.h"
-
-typedef int32_t RgbValue;
+#include "nvim/highlight_defs.h"
# define SST_MIN_ENTRIES 150 /* minimal size for state stack array */
# define SST_MAX_ENTRIES 1000 /* maximal size for state stack array */
@@ -11,13 +9,16 @@ typedef int32_t RgbValue;
# define SST_DIST 16 /* normal distance between entries */
# define SST_INVALID (synstate_T *)-1 /* invalid syn_state pointer */
-typedef unsigned short disptick_T; /* display tick type */
+typedef struct syn_state synstate_T;
+
+#include "nvim/buffer_defs.h"
+#include "nvim/regexp_defs.h"
/* struct passed to in_id_list() */
struct sp_syn {
- int inc_tag; /* ":syn include" unique tag */
- short id; /* highlight group ID of item */
- short *cont_in_list; /* cont.in group IDs, if non-zero */
+ int inc_tag; // ":syn include" unique tag
+ int16_t id; // highlight group ID of item
+ int16_t *cont_in_list; // cont.in group IDs, if non-zero
};
/*
@@ -26,12 +27,12 @@ struct sp_syn {
typedef struct keyentry keyentry_T;
struct keyentry {
- keyentry_T *ke_next; /* next entry with identical "keyword[]" */
- struct sp_syn k_syn; /* struct passed to in_id_list() */
- short *next_list; /* ID list for next match (if non-zero) */
+ keyentry_T *ke_next; // next entry with identical "keyword[]"
+ struct sp_syn k_syn; // struct passed to in_id_list()
+ int16_t *next_list; // ID list for next match (if non-zero)
int flags;
- int k_char; /* conceal substitute character */
- char_u keyword[1]; /* actually longer */
+ int k_char; // conceal substitute character
+ char_u keyword[1]; // actually longer
};
/*
@@ -49,8 +50,6 @@ typedef struct buf_state {
* syn_state contains the syntax state stack for the start of one line.
* Used by b_sst_array[].
*/
-typedef struct syn_state synstate_T;
-
struct syn_state {
synstate_T *sst_next; /* next entry in used or free list */
linenr_T sst_lnum; /* line number for this state */
@@ -58,20 +57,13 @@ struct syn_state {
bufstate_T sst_stack[SST_FIX_STATES]; /* short state stack */
garray_T sst_ga; /* growarray for long state stack */
} sst_union;
- int sst_next_flags; /* flags for sst_next_list */
- int sst_stacksize; /* number of states on the stack */
- short *sst_next_list; /* "nextgroup" list in this state
- * (this is a copy, don't free it! */
- disptick_T sst_tick; /* tick when last displayed */
- linenr_T sst_change_lnum; /* when non-zero, change in this line
- * may have made the state invalid */
+ int sst_next_flags; // flags for sst_next_list
+ int sst_stacksize; // number of states on the stack
+ int16_t *sst_next_list; // "nextgroup" list in this state
+ // (this is a copy, don't free it!
+ disptick_T sst_tick; // tick when last displayed
+ linenr_T sst_change_lnum; // when non-zero, change in this line
+ // may have made the state invalid
};
-// Structure shared between syntax.c, screen.c
-typedef struct attr_entry {
- int16_t rgb_ae_attr, cterm_ae_attr; // HL_BOLD, etc.
- RgbValue rgb_fg_color, rgb_bg_color, rgb_sp_color;
- int cterm_fg_color, cterm_bg_color;
-} attrentry_T;
-
#endif // NVIM_SYNTAX_DEFS_H
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index dfecfb776d..50397d40e6 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.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
+
/*
* Code to handle tags and the tag stack
*/
@@ -26,7 +29,6 @@
#include "nvim/mbyte.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/file_search.h"
#include "nvim/garray.h"
#include "nvim/memory.h"
@@ -73,23 +75,18 @@ typedef struct {
regmatch_T regmatch; /* regexp program, may be NULL */
} pat_T;
-/*
- * The matching tags are first stored in ga_match[]. In which one depends on
- * the priority of the match.
- * At the end, the matches from ga_match[] are concatenated, to make a list
- * sorted on priority.
- */
-#define MT_ST_CUR 0 /* static match in current file */
-#define MT_GL_CUR 1 /* global match in current file */
-#define MT_GL_OTH 2 /* global match in other file */
-#define MT_ST_OTH 3 /* static match in other file */
-#define MT_IC_ST_CUR 4 /* icase static match in current file */
-#define MT_IC_GL_CUR 5 /* icase global match in current file */
-#define MT_IC_GL_OTH 6 /* icase global match in other file */
-#define MT_IC_ST_OTH 7 /* icase static match in other file */
-#define MT_IC_OFF 4 /* add for icase match */
-#define MT_RE_OFF 8 /* add for regexp match */
-#define MT_MASK 7 /* mask for printing priority */
+// The matching tags are first stored in one of the hash tables. In
+// which one depends on the priority of the match.
+// ht_match[] is used to find duplicates, ga_match[] to keep them in sequence.
+// At the end, the matches from ga_match[] are concatenated, to make a list
+// sorted on priority.
+#define MT_ST_CUR 0 // static match in current file
+#define MT_GL_CUR 1 // global match in current file
+#define MT_GL_OTH 2 // global match in other file
+#define MT_ST_OTH 3 // static match in other file
+#define MT_IC_OFF 4 // add for icase match
+#define MT_RE_OFF 8 // add for regexp match
+#define MT_MASK 7 // mask for printing priority
#define MT_COUNT 16
static char *mt_names[MT_COUNT/2] =
@@ -109,15 +106,6 @@ static char_u *topmsg = (char_u *)N_("E556: at top of tag stack");
static char_u *tagmatchname = NULL; /* name of last used tag */
/*
- * We use ftello() here, if available. It returns off_t instead of long,
- * which helps if long is 32 bit and off_t is 64 bit.
- * We assume that when fseeko() is available then ftello() is too.
- */
-#ifdef HAVE_FSEEKO
-# define ftell ftello
-#endif
-
-/*
* Tag for preview window is remembered separately, to avoid messing up the
* normal tagstack.
*/
@@ -211,12 +199,15 @@ do_tag (
clearpos(&saved_fmark.mark); /* shutup gcc 4.0 */
saved_fmark.fnum = 0;
- /*
- * Don't add a tag to the tagstack if 'tagstack' has been reset.
- */
- if (!p_tgst && *tag != NUL) {
- use_tagstack = FALSE;
- new_tag = TRUE;
+ // Don't add a tag to the tagstack if 'tagstack' has been reset.
+ assert(tag != NULL);
+ if (!p_tgst && *tag != NUL) { // -V522
+ use_tagstack = false;
+ new_tag = true;
+ if (g_do_tagpreview != 0) {
+ xfree(ptag_entry.tagname);
+ ptag_entry.tagname = vim_strsave(tag);
+ }
} else {
if (g_do_tagpreview != 0)
use_tagstack = FALSE;
@@ -275,8 +266,8 @@ do_tag (
goto end_do_tag;
}
- if (type == DT_POP) { /* go to older position */
- int old_KeyTyped = KeyTyped;
+ if (type == DT_POP) { // go to older position
+ const bool old_KeyTyped = KeyTyped;
if ((tagstackidx -= count) < 0) {
EMSG(_(bottommsg));
if (tagstackidx + count == 0) {
@@ -521,10 +512,10 @@ do_tag (
if (msg_col == 0)
msg_didout = FALSE; /* overwrite previous message */
msg_start();
- MSG_PUTS_ATTR(_(" # pri kind tag"), hl_attr(HLF_T));
+ MSG_PUTS_ATTR(_(" # pri kind tag"), HL_ATTR(HLF_T));
msg_clr_eos();
taglen_advance(taglen);
- MSG_PUTS_ATTR(_("file\n"), hl_attr(HLF_T));
+ MSG_PUTS_ATTR(_("file\n"), HL_ATTR(HLF_T));
for (i = 0; i < num_matches && !got_int; i++) {
parse_match(matches[i], &tagp);
@@ -537,21 +528,22 @@ do_tag (
}
vim_snprintf((char *)IObuff + 1, IOSIZE - 1, "%2d %s ", i + 1,
mt_names[matches[i][0] & MT_MASK]);
- msg_puts(IObuff);
- if (tagp.tagkind != NULL)
+ msg_puts((const char *)IObuff);
+ if (tagp.tagkind != NULL) {
msg_outtrans_len(tagp.tagkind,
- (int)(tagp.tagkind_end - tagp.tagkind));
+ (int)(tagp.tagkind_end - tagp.tagkind));
+ }
msg_advance(13);
msg_outtrans_len_attr(tagp.tagname,
- (int)(tagp.tagname_end - tagp.tagname),
- hl_attr(HLF_T));
+ (int)(tagp.tagname_end - tagp.tagname),
+ HL_ATTR(HLF_T));
msg_putchar(' ');
taglen_advance(taglen);
/* Find out the actual file name. If it is long, truncate
* it and put "..." in the middle */
p = tag_full_fname(&tagp);
- msg_puts_long_attr(p, hl_attr(HLF_D));
+ msg_puts_long_attr(p, HL_ATTR(HLF_D));
xfree(p);
if (msg_col > 0)
@@ -581,8 +573,8 @@ do_tag (
p = tagp.tagkind_end;
continue;
}
- /* print all other extra fields */
- attr = hl_attr(HLF_CM);
+ // print all other extra fields
+ attr = HL_ATTR(HLF_CM);
while (*p && *p != '\r' && *p != '\n') {
if (msg_col + ptr2cells(p) >= Columns) {
msg_putchar('\n');
@@ -592,7 +584,7 @@ do_tag (
}
p = msg_outtrans_one(p, attr);
if (*p == TAB) {
- msg_puts_attr((char_u *)" ", attr);
+ msg_puts_attr(" ", attr);
break;
}
if (*p == ':')
@@ -675,7 +667,7 @@ do_tag (
fname = xmalloc(MAXPATHL + 1);
cmd = xmalloc(CMDBUFFSIZE + 1);
- list = list_alloc();
+ list = tv_list_alloc(num_matches);
for (i = 0; i < num_matches; ++i) {
int len, cmd_len;
@@ -774,20 +766,21 @@ do_tag (
cmd[len] = NUL;
}
- dict = dict_alloc();
- list_append_dict(list, dict);
+ dict = tv_dict_alloc();
+ tv_list_append_dict(list, dict);
- dict_add_nr_str(dict, "text", 0L, tag_name);
- dict_add_nr_str(dict, "filename", 0L, fname);
- dict_add_nr_str(dict, "lnum", lnum, NULL);
- if (lnum == 0)
- dict_add_nr_str(dict, "pattern", 0L, cmd);
+ tv_dict_add_str(dict, S_LEN("text"), (const char *)tag_name);
+ tv_dict_add_str(dict, S_LEN("filename"), (const char *)fname);
+ tv_dict_add_nr(dict, S_LEN("lnum"), lnum);
+ if (lnum == 0) {
+ tv_dict_add_str(dict, S_LEN("pattern"), (const char *)cmd);
+ }
}
vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag);
- set_errorlist(curwin, list, ' ', IObuff);
+ set_errorlist(curwin, list, ' ', IObuff, NULL);
- list_free(list, TRUE);
+ tv_list_free(list);
xfree(fname);
xfree(cmd);
@@ -855,13 +848,15 @@ do_tag (
STRCAT(IObuff, _(" Using tag with different case!"));
if ((num_matches > prev_num_matches || new_tag)
&& num_matches > 1) {
- if (ic)
- msg_attr(IObuff, hl_attr(HLF_W));
- else
+ if (ic) {
+ msg_attr((const char *)IObuff, HL_ATTR(HLF_W));
+ } else {
msg(IObuff);
- msg_scroll = TRUE; /* don't overwrite this message */
- } else
+ }
+ msg_scroll = true; // Don't overwrite this message.
+ } else {
give_warning(IObuff, ic);
+ }
if (ic && !msg_scrolled && msg_silent == 0) {
ui_flush();
os_delay(1000L, true);
@@ -913,7 +908,8 @@ end_do_tag:
/* Only store the new index when using the tagstack and it's valid. */
if (use_tagstack && tagstackidx <= curwin->w_tagstacklen)
curwin->w_tagstackidx = tagstackidx;
- postponed_split = 0; /* don't split next time */
+ postponed_split = 0; // don't split next time
+ g_do_tagpreview = 0; // don't do tag preview next time
return jumped_to_tag;
}
@@ -956,15 +952,15 @@ void do_tags(exarg_T *eap)
continue;
msg_putchar('\n');
- sprintf((char *)IObuff, "%c%2d %2d %-15s %5ld ",
- i == tagstackidx ? '>' : ' ',
- i + 1,
- tagstack[i].cur_match + 1,
- tagstack[i].tagname,
- tagstack[i].fmark.mark.lnum);
+ vim_snprintf((char *)IObuff, IOSIZE, "%c%2d %2d %-15s %5ld ",
+ i == tagstackidx ? '>' : ' ',
+ i + 1,
+ tagstack[i].cur_match + 1,
+ tagstack[i].tagname,
+ tagstack[i].fmark.mark.lnum);
msg_outtrans(IObuff);
msg_outtrans_attr(name, tagstack[i].fmark.fnum == curbuf->b_fnum
- ? hl_attr(HLF_D) : 0);
+ ? HL_ATTR(HLF_D) : 0);
xfree(name);
}
ui_flush(); /* show one line at a time */
@@ -1054,6 +1050,7 @@ static void prepare_pats(pat_T *pats, int has_re)
* TAG_REGEXP use "pat" as a regexp
* TAG_NOIC don't always ignore case
* TAG_KEEP_LANG keep language
+ * TAG_CSCOPE use cscope results for tags
*/
int
find_tags (
@@ -1082,22 +1079,21 @@ find_tags (
char_u *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 */
+ 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;
- off_t filesize;
+ off_T filesize;
int tagcmp;
- off_t offset;
+ off_T offset;
int round;
enum {
TS_START, /* at start of file */
@@ -1115,19 +1111,19 @@ find_tags (
int save_emsg_off;
- struct match_found {
- int len; /* nr of chars of match[] to be compared */
- char_u match[1]; /* actually longer */
- } *mfp, *mfp2;
- garray_T ga_match[MT_COUNT];
- int match_count = 0; /* number of matches found */
+ char_u *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_u **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 */
- char_u *saved_pat = NULL; /* copy of pat[] */
+ char_u *help_lang_find = NULL; // lang to be found
+ char_u help_lang[3]; // lang of current tags file
+ char_u *saved_pat = NULL; // copy of pat[]
+ bool is_txt = false;
pat_T orgpat; /* holds unconverted pattern info */
vimconv_T vimconv;
@@ -1158,6 +1154,12 @@ find_tags (
case TC_MATCH:
p_ic = false;
break;
+ case TC_FOLLOWSCS:
+ p_ic = ignorecase(pat);
+ break;
+ case TC_SMART:
+ p_ic = ignorecase_opt(pat, true, true);
+ break;
default:
assert(false);
}
@@ -1171,16 +1173,23 @@ find_tags (
*/
lbuf = xmalloc(lbuf_size);
tag_fname = xmalloc(MAXPATHL + 1);
- for (mtt = 0; mtt < MT_COUNT; ++mtt)
- ga_init(&ga_match[mtt], (int)sizeof(struct match_found *), 100);
+ for (mtt = 0; mtt < MT_COUNT; mtt++) {
+ ga_init(&ga_match[mtt], sizeof(char_u *), 100);
+ hash_init(&ht_match[mtt]);
+ }
STRCPY(tag_fname, "from cscope"); /* for error messages */
/*
* Initialize a few variables
*/
- if (help_only) /* want tags from help file */
- curbuf->b_help = true; /* will be restored later */
+ if (help_only) { // want tags from help file
+ curbuf->b_help = true; // will be restored later
+ } else if (use_cscope) {
+ // Make sure we don't mix help and cscope, confuses Coverity.
+ help_only = false;
+ curbuf->b_help = false;
+ }
orgpat.len = (int)STRLEN(pat);
if (curbuf->b_help) {
@@ -1205,9 +1214,9 @@ find_tags (
if (has_re && orgpat.regmatch.regprog == NULL)
goto findtag_end;
- /* This is only to avoid a compiler warning for using search_info
- * uninitialised. */
- memset(&search_info, 0, (size_t)1);
+ // This is only to avoid a compiler warning for using search_info
+ // uninitialised.
+ memset(&search_info, 0, 1); // -V512
/*
* When finding a specified number of matches, first try with matching
@@ -1219,6 +1228,14 @@ find_tags (
* 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));
for (round = 1; round <= 2; ++round) {
@@ -1234,13 +1251,19 @@ find_tags (
fp = NULL; // avoid GCC warning
} else {
if (curbuf->b_help) {
- /* 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
+ // 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. */
@@ -1294,9 +1317,14 @@ find_tags (
* Read and parse the lines in the file one by one
*/
for (;; ) {
- line_breakcheck(); /* check for CTRL-C typed */
+ // 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);
+ ins_compl_check_keys(30, false);
if (got_int || compl_interrupted) {
stop_searching = TRUE;
break;
@@ -1340,36 +1368,28 @@ find_tags (
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;
-#ifdef HAVE_FSEEKO
- fseeko(fp, search_info.curr_offset, SEEK_SET);
-#else
- fseek(fp, (long)search_info.curr_offset, SEEK_SET);
-#endif
+ vim_fseek(fp, search_info.curr_offset, SEEK_SET);
eof = vim_fgets(lbuf, LSIZE, 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 = ftell(fp);
+ 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 */
-#ifdef HAVE_FSEEKO
- fseeko(fp, search_info.low_offset, SEEK_SET);
-#else
- fseek(fp, (long)search_info.low_offset, SEEK_SET);
-#endif
+ // 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(lbuf, LSIZE, fp);
}
/* skip empty and blank lines */
while (!eof && vim_isblankline(lbuf)) {
- search_info.curr_offset = ftell(fp);
+ search_info.curr_offset = vim_ftell(fp);
eof = vim_fgets(lbuf, LSIZE, fp);
}
if (eof) {
/* Hit end of file. Skip backwards. */
state = TS_SKIP_BACK;
- search_info.match_offset = ftell(fp);
+ search_info.match_offset = vim_ftell(fp);
search_info.curr_offset = search_info.curr_offset_used;
continue;
}
@@ -1485,10 +1505,10 @@ line_read_in:
*/
if (state == TS_BINARY) {
// Get the tag file size.
- if ((filesize = lseek(fileno(fp), (off_t)0L, SEEK_END)) <= 0) {
+ if ((filesize = vim_lseek(fileno(fp), (off_T)0L, SEEK_END)) <= 0) {
state = TS_LINEAR;
} else {
- lseek(fileno(fp), (off_t)0L, SEEK_SET);
+ vim_lseek(fileno(fp), (off_T)0L, SEEK_SET);
/* Calculate the first read offset in the file. Start
* the search in the middle of the file. */
@@ -1526,11 +1546,7 @@ parse_line:
/* Avoid getting stuck. */
linear = TRUE;
state = TS_LINEAR;
-# ifdef HAVE_FSEEKO
- fseeko(fp, search_info.low_offset, SEEK_SET);
-# else
- fseek(fp, (long)search_info.low_offset, SEEK_SET);
-# endif
+ vim_fseek(fp, search_info.low_offset, SEEK_SET);
}
continue;
}
@@ -1609,7 +1625,7 @@ parse_line:
continue;
}
if (tagcmp < 0) {
- search_info.curr_offset = ftell(fp);
+ 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)
@@ -1645,10 +1661,11 @@ parse_line:
} else if (state == TS_STEP_FORWARD) {
assert(cmplen >= 0);
if (mb_strnicmp(tagp.tagname, orgpat.head, (size_t)cmplen) != 0) {
- if ((off_t)ftell(fp) > search_info.match_offset)
- break; /* past last match */
- else
- continue; /* before first match */
+ 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 */
@@ -1719,10 +1736,10 @@ parse_line:
match_re = TRUE;
}
- /*
- * If a match is found, add it to ga_match[].
- */
+ // If a match is found, add it to ht_match[] and ga_match[].
if (match) {
+ int len = 0;
+
if (use_cscope) {
/* Don't change the ordering, always use the same table. */
mtt = MT_GL_OTH;
@@ -1757,116 +1774,109 @@ parse_line:
mtt += MT_RE_OFF;
}
- /*
- * Add the found match in ga_match[mtt], avoiding duplicates.
- * Store the info we need later, which depends on the kind of
- * tags we are dealing with.
- */
- ga_grow(&ga_match[mtt], 1);
- {
- int len;
-
- if (help_only) {
+ // 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.
- */
- *tagp.tagname_end = NUL;
- len = (int)(tagp.tagname_end - tagp.tagname);
- mfp = xmalloc(sizeof(struct match_found) + len + 10 + ML_EXTRA);
- /* "len" includes the language and the NUL, but
- * not the priority. */
- mfp->len = len + ML_EXTRA + 1;
-#define ML_HELP_LEN 6
- p = mfp->match;
- STRCPY(p, tagp.tagname);
- p[len] = '@';
- STRCPY(p + len + 1, help_lang);
- sprintf((char *)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 = (int)(temp_end - tagp.command - 2);
- mfp = xmalloc(sizeof(struct match_found) + len);
- mfp->len = len + 1; /* include the NUL */
- p = mfp->match;
- STRLCPY(p, tagp.command + 2, len + 1);
- } else
- mfp = NULL;
- get_it_again = FALSE;
+ // 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 = (int)(tagp.tagname_end - tagp.tagname);
+ mfp = xmalloc(sizeof(char_u) + len + 10 + ML_EXTRA + 1);
+
+ p = mfp;
+ STRCPY(p, tagp.tagname);
+ p[len] = '@';
+ STRCPY(p + len + 1, help_lang);
+ snprintf((char *)p + len + 1 + ML_EXTRA, 10, "%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 = (int)(temp_end - tagp.command - 2);
+ mfp = xmalloc(len + 2);
+ STRLCPY(mfp, tagp.command + 2, len + 1);
} else {
- len = (int)(tagp.tagname_end - tagp.tagname);
- mfp = xmalloc(sizeof(struct match_found) + len);
- mfp->len = len + 1; /* include the NUL */
- p = mfp->match;
- STRLCPY(p, tagp.tagname, len + 1);
-
- /* if wanted, re-read line to get long form too */
- if (State & INSERT)
- get_it_again = p_sft;
+ mfp = NULL;
}
+ get_it_again = false;
} else {
- /* Save the tag in a buffer.
- * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
- * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
- * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
- */
- len = (int)STRLEN(tag_fname)
- + (int)STRLEN(lbuf) + 3;
- mfp = xmalloc(sizeof(struct match_found) + len);
- mfp->len = len;
- p = mfp->match;
- p[0] = mtt;
- STRCPY(p + 1, tag_fname);
+ len = (int)(tagp.tagname_end - tagp.tagname);
+ mfp = xmalloc(sizeof(char_u) + len + 1);
+ STRLCPY(mfp, tagp.tagname, len + 1);
+
+ // if wanted, re-read line to get long form too
+ if (State & INSERT) {
+ get_it_again = p_sft;
+ }
+ }
+ } else {
+#define TAG_SEP 0x02
+ 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 = (int)tag_fname_len + (int)STRLEN(lbuf) + 3;
+ mfp = xmalloc(sizeof(char_u) + len + 1);
+ p = mfp;
+ p[0] = 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);
+ // Ignore differences in slashes, avoid adding
+ // both path/file and path\file.
+ slash_adjust(p + 1);
#endif
- s = p + 1 + STRLEN(tag_fname) + 1;
- STRCPY(s, lbuf);
- }
+ p[tag_fname_len + 1] = TAG_SEP;
+ s = p + 1 + tag_fname_len + 1;
+ STRCPY(s, lbuf);
+ }
- if (mfp != NULL) {
- /*
- * Don't add identical matches.
- * This can take a lot of time when finding many
- * matches, check for CTRL-C now and then.
- * Add all cscope tags, because they are all listed.
- */
- if (use_cscope)
- i = -1;
- else
- for (i = ga_match[mtt].ga_len; --i >= 0 && !got_int; ) {
- mfp2 = ((struct match_found **)
- (ga_match[mtt].ga_data))[i];
- if (mfp2->len == mfp->len
- && memcmp(mfp2->match, mfp->match,
- (size_t)mfp->len) == 0)
- break;
- line_breakcheck();
- }
- if (i < 0) {
- ((struct match_found **)(ga_match[mtt].ga_data))
+ if (mfp != NULL) {
+ hashitem_T *hi;
+
+ // Don't add identical matches.
+ // Add all cscope tags, because they are all listed.
+ // "mfp" is used as a hash key, there is a NUL byte to end
+ // the part matters for comparing, more bytes may follow
+ // after it. E.g. help tags store the priority after the
+ // NUL.
+ if (use_cscope) {
+ hash++;
+ } else {
+ hash = hash_hash(mfp);
+ }
+ hi = hash_lookup(&ht_match[mtt], (const char *)mfp,
+ STRLEN(mfp), hash);
+ if (HASHITEM_EMPTY(hi)) {
+ hash_add_item(&ht_match[mtt], hi, mfp, hash);
+ ga_grow(&ga_match[mtt], 1);
+ ((char_u **)(ga_match[mtt].ga_data))
[ga_match[mtt].ga_len++] = mfp;
- ++match_count;
- } else
- xfree(mfp);
+ match_count++;
+ } else {
+ // duplicate tag, drop it
+ xfree(mfp);
}
}
}
@@ -1876,10 +1886,11 @@ parse_line:
if (line_error) {
EMSG2(_("E431: Format error in tags file \"%s\""), tag_fname);
- if (!use_cscope)
- EMSGN(_("Before byte %" PRId64), ftell(fp));
- stop_searching = TRUE;
- line_error = FALSE;
+ if (!use_cscope) {
+ EMSGN(_("Before byte %" PRId64), vim_ftell(fp));
+ }
+ stop_searching = true;
+ line_error = false;
}
if (!use_cscope)
@@ -1941,21 +1952,29 @@ findtag_end:
else
matches = NULL;
match_count = 0;
- for (mtt = 0; mtt < MT_COUNT; ++mtt) {
- for (int i = 0; i < ga_match[mtt].ga_len; ++i) {
- mfp = ((struct match_found **)(ga_match[mtt].ga_data))[i];
- if (matches == NULL)
+ for (mtt = 0; mtt < MT_COUNT; mtt++) {
+ for (i = 0; i < ga_match[mtt].ga_len; i++) {
+ mfp = ((char_u **)(ga_match[mtt].ga_data))[i];
+ if (matches == NULL) {
xfree(mfp);
- else {
- /* To avoid allocating memory again we turn the struct
- * match_found into a string. For help the priority was not
- * included in the length. */
- memmove(mfp, mfp->match,
- (size_t)(mfp->len + (help_only ? ML_HELP_LEN : 0)));
+ } else {
+ if (!name_only) {
+ // Change mtt back to zero-based.
+ *mfp = *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++] = (char_u *)mfp;
}
}
+
ga_clear(&ga_match[mtt]);
+ hash_clear(&ht_match[mtt]);
}
*matchesp = matches;
@@ -2167,7 +2186,7 @@ parse_tag_line (
* Return TRUE if it is a static tag and adjust *tagname to the real tag.
* Return FALSE if it is not a static tag.
*/
-static int test_for_static(tagptrs_T *tagp)
+static bool test_for_static(tagptrs_T *tagp)
{
char_u *p;
@@ -2198,6 +2217,16 @@ static int test_for_static(tagptrs_T *tagp)
return FALSE;
}
+// Returns the length of a matching tag line.
+static size_t matching_line_len(const char_u *const lbuf)
+{
+ const char_u *p = lbuf + 1;
+
+ // does the same thing as parse_match()
+ p += STRLEN(p) + 1;
+ return (p - lbuf) + STRLEN(p);
+}
+
/*
* Parse a line from a matching tag. Does not change the line itself.
*
@@ -2270,7 +2299,7 @@ static char_u *tag_full_fname(tagptrs_T *tagp)
{
int c = *tagp->fname_end;
*tagp->fname_end = NUL;
- char_u *fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, FALSE);
+ char_u *fullname = expand_tag_fname(tagp->fname, tagp->tag_fname, false);
*tagp->fname_end = c;
return fullname;
@@ -2281,11 +2310,10 @@ static char_u *tag_full_fname(tagptrs_T *tagp)
*
* returns OK for success, NOTAGFILE when file not found, FAIL otherwise.
*/
-static int
-jumpto_tag (
- char_u *lbuf, /* line from the tags file for this tag */
- int forceit, /* :ta with ! */
- int keep_help /* keep help flag (FALSE for cscope) */
+static int jumpto_tag(
+ const char_u *lbuf_arg, // line from the tags file for this tag
+ int forceit, // :ta with !
+ int keep_help // keep help flag (FALSE for cscope)
)
{
int save_secure;
@@ -2293,7 +2321,6 @@ jumpto_tag (
bool save_p_ws;
int save_p_scs, save_p_ic;
linenr_T save_lnum;
- int csave = 0;
char_u *str;
char_u *pbuf; /* search pattern buffer */
char_u *pbuf_end;
@@ -2301,13 +2328,16 @@ jumpto_tag (
char_u *fname;
tagptrs_T tagp;
int retval = FAIL;
- int getfile_result;
+ int getfile_result = GETFILE_UNUSED;
int search_options;
int save_no_hlsearch;
win_T *curwin_save = NULL;
char_u *full_fname = NULL;
- int old_KeyTyped = KeyTyped; /* getting the file may reset it */
+ const bool old_KeyTyped = KeyTyped; // getting the file may reset it
const int l_g_do_tagpreview = g_do_tagpreview;
+ const size_t len = matching_line_len(lbuf_arg) + 1;
+ char_u *lbuf = xmalloc(len);
+ memmove(lbuf, lbuf_arg, len);
pbuf = xmalloc(LSIZE);
@@ -2317,8 +2347,7 @@ jumpto_tag (
goto erret;
}
- /* truncate the file name, so it can be used as a string */
- csave = *tagp.fname_end;
+ // truncate the file name, so it can be used as a string
*tagp.fname_end = NUL;
fname = tagp.fname;
@@ -2344,8 +2373,8 @@ jumpto_tag (
* Expand file name, when needed (for environment variables).
* If 'tagrelative' option set, may change file name.
*/
- fname = expand_tag_fname(fname, tagp.tag_fname, TRUE);
- tofree_fname = fname; /* free() it later */
+ fname = expand_tag_fname(fname, tagp.tag_fname, true);
+ tofree_fname = fname; // free() it later
/*
* Check if the file with the tag exists before abandoning the current
@@ -2385,11 +2414,38 @@ jumpto_tag (
}
}
- /* If it was a CTRL-W CTRL-] command split window now. For ":tab tag"
- * open a new tab page. */
- if (postponed_split || cmdmod.tab != 0) {
- win_split(postponed_split > 0 ? postponed_split : 0,
- postponed_split_flags);
+ // If it was a CTRL-W CTRL-] command split window now. For ":tab tag"
+ // open a new tab page.
+ if (postponed_split && (swb_flags & (SWB_USEOPEN | SWB_USETAB))) {
+ buf_T *const existing_buf = buflist_findname_exp(fname);
+
+ if (existing_buf != NULL) {
+ const win_T *wp = NULL;
+
+ if (swb_flags & SWB_USEOPEN) {
+ wp = buf_jump_open_win(existing_buf);
+ }
+
+ // If 'switchbuf' contains "usetab": jump to first window in any tab
+ // page containing "existing_buf" if one exists
+ if (wp == NULL && (swb_flags & SWB_USETAB)) {
+ wp = buf_jump_open_tab(existing_buf);
+ }
+
+ // We've switched to the buffer, the usual loading of the file must
+ // be skipped.
+ if (wp != NULL) {
+ getfile_result = GETFILE_SAME_FILE;
+ }
+ }
+ }
+ if (getfile_result == GETFILE_UNUSED
+ && (postponed_split || cmdmod.tab != 0)) {
+ if (win_split(postponed_split > 0 ? postponed_split : 0,
+ postponed_split_flags) == FAIL) {
+ RedrawingDisabled--;
+ goto erret;
+ }
RESET_BINDING(curwin);
}
@@ -2401,11 +2457,16 @@ jumpto_tag (
else
keep_help_flag = curbuf->b_help;
}
- getfile_result = getfile(0, fname, NULL, TRUE, (linenr_T)0, forceit);
- keep_help_flag = FALSE;
- if (getfile_result <= 0) { /* got to the right file */
- curwin->w_set_curswant = TRUE;
+ if (getfile_result == GETFILE_UNUSED) {
+ // Careful: getfile() may trigger autocommands and call jumpto_tag()
+ // recursively.
+ getfile_result = getfile(0, fname, NULL, true, (linenr_T)0, forceit);
+ }
+ keep_help_flag = false;
+
+ if (GETFILE_SUCCESS(getfile_result)) { // got to the right file
+ curwin->w_set_curswant = true;
postponed_split = 0;
save_secure = secure;
@@ -2497,7 +2558,7 @@ jumpto_tag (
}
}
p_ws = save_p_ws;
- p_ic = save_p_ic;
+ p_ic = save_p_ic; // -V519
p_scs = save_p_scs;
/* A search command may have positioned the cursor beyond the end
@@ -2523,9 +2584,10 @@ jumpto_tag (
SET_NO_HLSEARCH(save_no_hlsearch);
}
- /* Return OK if jumped to another file (at least we found the file!). */
- if (getfile_result == -1)
+ // Return OK if jumped to another file (at least we found the file!).
+ if (getfile_result == GETFILE_OPEN_OTHER) {
retval = OK;
+ }
if (retval == OK) {
/*
@@ -2546,19 +2608,18 @@ jumpto_tag (
win_enter(curwin_save, true);
}
- --RedrawingDisabled;
+ RedrawingDisabled--;
} else {
- --RedrawingDisabled;
- if (postponed_split) { /* close the window */
- win_close(curwin, FALSE);
+ RedrawingDisabled--;
+ if (postponed_split) { // close the window
+ win_close(curwin, false);
postponed_split = 0;
}
}
erret:
- g_do_tagpreview = 0; /* For next time */
- if (tagp.fname_end != NULL)
- *tagp.fname_end = csave;
+ g_do_tagpreview = 0; // For next time
+ xfree(lbuf);
xfree(pbuf);
xfree(tofree_fname);
xfree(full_fname);
@@ -2566,13 +2627,12 @@ erret:
return retval;
}
-/*
- * If "expand" is TRUE, expand wildcards in fname.
- * If 'tagrelative' option set, change fname (name of file containing tag)
- * according to tag_fname (name of tag file containing fname).
- * Returns a pointer to allocated memory.
- */
-static char_u *expand_tag_fname(char_u *fname, char_u *tag_fname, int expand)
+// If "expand" is true, expand wildcards in fname.
+// If 'tagrelative' option set, change fname (name of file containing tag)
+// according to tag_fname (name of tag file containing fname).
+// Returns a pointer to allocated memory.
+static char_u *expand_tag_fname(char_u *fname, char_u *const tag_fname,
+ const bool expand)
{
char_u *p;
char_u *expanded_fname = NULL;
@@ -2627,8 +2687,8 @@ static int test_for_current(char_u *fname, char_u *fname_end, char_u *tag_fname,
c = *fname_end;
*fname_end = NUL;
}
- fullname = expand_tag_fname(fname, tag_fname, TRUE);
- retval = (path_full_compare(fullname, buf_ffname, TRUE) & kEqualFiles);
+ fullname = expand_tag_fname(fname, tag_fname, true);
+ retval = (path_full_compare(fullname, buf_ffname, true) & kEqualFiles);
xfree(fullname);
*fname_end = c;
}
@@ -2732,8 +2792,8 @@ add_tag_field (
int len = 0;
int retval;
- /* check that the field name doesn't exist yet */
- if (dict_find(dict, (char_u *)field_name, -1) != NULL) {
+ // Check that the field name doesn't exist yet.
+ if (tv_dict_find(dict, field_name, -1) != NULL) {
if (p_verbose > 0) {
verbose_enter();
smsg(_("Duplicate field name: %s"), field_name);
@@ -2754,26 +2814,25 @@ add_tag_field (
STRLCPY(buf, start, len + 1);
}
buf[len] = NUL;
- retval = dict_add_nr_str(dict, field_name, 0L, buf);
+ retval = tv_dict_add_str(dict, field_name, STRLEN(field_name),
+ (const char *)buf);
xfree(buf);
return retval;
}
-/*
- * Add the tags matching the specified pattern to the list "list"
- * as a dictionary
- */
-int get_tags(list_T *list, char_u *pat)
+/// Add the tags matching the specified pattern "pat" to the list "list"
+/// as a dictionary. Use "buf_fname" for priority, unless NULL.
+int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
{
int num_matches, i, ret;
char_u **matches, *p;
char_u *full_fname;
dict_T *dict;
tagptrs_T tp;
- long is_static;
+ bool is_static;
ret = find_tags(pat, &num_matches, &matches,
- TAG_REGEXP | TAG_NOIC, (int)MAXCOL, NULL);
+ TAG_REGEXP | TAG_NOIC, (int)MAXCOL, buf_fname);
if (ret == OK && num_matches > 0) {
for (i = 0; i < num_matches; ++i) {
int parse_result = parse_match(matches[i], &tp);
@@ -2788,19 +2847,18 @@ int get_tags(list_T *list, char_u *pat)
if (STRNCMP(tp.tagname, "!_TAG_", 6) == 0)
continue;
- dict = dict_alloc();
- list_append_dict(list, dict);
+ dict = tv_dict_alloc();
+ tv_list_append_dict(list, dict);
full_fname = tag_full_fname(&tp);
if (add_tag_field(dict, "name", tp.tagname, tp.tagname_end) == FAIL
- || add_tag_field(dict, "filename", full_fname,
- NULL) == FAIL
- || add_tag_field(dict, "cmd", tp.command,
- tp.command_end) == FAIL
+ || add_tag_field(dict, "filename", full_fname, NULL) == FAIL
+ || add_tag_field(dict, "cmd", tp.command, tp.command_end) == FAIL
|| add_tag_field(dict, "kind", tp.tagkind,
- tp.tagkind ? tp.tagkind_end : NULL) == FAIL
- || dict_add_nr_str(dict, "static", is_static, NULL) == FAIL)
+ tp.tagkind ? tp.tagkind_end : NULL) == FAIL
+ || tv_dict_add_nr(dict, S_LEN("static"), is_static) == FAIL) {
ret = FAIL;
+ }
xfree(full_fname);
diff --git a/src/nvim/tag.h b/src/nvim/tag.h
index 5d4bcddf94..a8fddd05da 100644
--- a/src/nvim/tag.h
+++ b/src/nvim/tag.h
@@ -1,6 +1,9 @@
#ifndef NVIM_TAG_H
#define NVIM_TAG_H
+#include "nvim/types.h"
+#include "nvim/ex_cmds_defs.h"
+
/*
* Values for do_tag().
*/
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index fd416b3dcc..51bf22b31c 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1,18 +1,20 @@
-// VT220/xterm-like terminal emulator implementation for nvim. Powered by
-// libvterm (http://www.leonerd.org.uk/code/libvterm/).
+// 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
+
+// VT220/xterm-like terminal emulator.
+// Powered by libvterm http://www.leonerd.org.uk/code/libvterm
//
// libvterm is a pure C99 terminal emulation library with abstract input and
// display. This means that the library needs to read data from the master fd
// and feed VTerm instances, which will invoke user callbacks with screen
// update instructions that must be mirrored to the real display.
//
-// Keys are pressed in VTerm instances by calling
+// Keys are sent to VTerm instances by calling
// vterm_keyboard_key/vterm_keyboard_unichar, which generates byte streams that
// must be fed back to the master fd.
//
-// This implementation uses nvim buffers as the display mechanism for both
-// the visible screen and the scrollback buffer. When focused, the window
-// "pins" to the bottom of the buffer and mirrors libvterm screen state.
+// Nvim buffers are used as the display mechanism for both the visible screen
+// and the scrollback buffer.
//
// When a line becomes invisible due to a decrease in screen height or because
// a line was pushed up during normal terminal output, we store the line
@@ -23,18 +25,17 @@
// scrollback buffer, which is mirrored in the nvim buffer displaying lines
// that were previously invisible.
//
-// The vterm->nvim synchronization is performed in intervals of 10
-// milliseconds. This is done to minimize screen updates when receiving large
-// bursts of data.
+// The vterm->nvim synchronization is performed in intervals of 10 milliseconds,
+// to minimize screen updates when receiving large bursts of data.
//
// This module is decoupled from the processes that normally feed it data, so
// it's possible to use it as a general purpose console buffer (possibly as a
// log/display mechanism for nvim in the future)
//
-// Inspired by vimshell (http://www.wana.at/vimshell/) and
-// Conque (https://code.google.com/p/conque/). Libvterm usage instructions (plus
-// some extra code) were taken from
-// pangoterm (http://www.leonerd.org.uk/code/pangoterm/)
+// Inspired by: vimshell http://www.wana.at/vimshell
+// Conque https://code.google.com/p/conque
+// Some code from pangoterm http://www.leonerd.org.uk/code/pangoterm
+
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
@@ -42,11 +43,13 @@
#include <vterm.h>
+#include "nvim/log.h"
#include "nvim/vim.h"
#include "nvim/terminal.h"
#include "nvim/message.h"
#include "nvim/memory.h"
#include "nvim/option.h"
+#include "nvim/highlight.h"
#include "nvim/macros.h"
#include "nvim/mbyte.h"
#include "nvim/buffer.h"
@@ -59,7 +62,6 @@
#include "nvim/edit.h"
#include "nvim/mouse.h"
#include "nvim/memline.h"
-#include "nvim/mark.h"
#include "nvim/map.h"
#include "nvim/misc1.h"
#include "nvim/move.h"
@@ -80,17 +82,15 @@ typedef struct terminal_state {
Terminal *term;
int save_rd; // saved value of RedrawingDisabled
bool close;
- bool got_bs; // if the last input was <C-\>
+ bool got_bsl; // if the last input was <C-\>
} TerminalState;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "terminal.c.generated.h"
#endif
-#define SCROLLBACK_BUFFER_DEFAULT_SIZE 1000
// Delay for refreshing the terminal buffer after receiving updates from
-// libvterm. This is greatly improves performance when receiving large bursts
-// of data.
+// libvterm. Improves performance when receiving large bursts of data.
#define REFRESH_DELAY 10
static TimeWatcher refresh_timer;
@@ -102,48 +102,42 @@ typedef struct {
} ScrollbackLine;
struct terminal {
- // options passed to terminal_open
- TerminalOptions opts;
- // libvterm structures
+ TerminalOptions opts; // options passed to terminal_open
VTerm *vt;
VTermScreen *vts;
// buffer used to:
// - convert VTermScreen cell arrays into utf8 strings
// - receive data from libvterm as a result of key presses.
char textbuf[0x1fff];
- // Scrollback buffer storage for libvterm.
- // TODO(tarruda): Use a doubly-linked list
- ScrollbackLine **sb_buffer;
- // number of rows pushed to sb_buffer
- size_t sb_current;
- // sb_buffer size;
- size_t sb_size;
+
+ ScrollbackLine **sb_buffer; // Scrollback buffer storage for libvterm
+ size_t sb_current; // number of rows pushed to sb_buffer
+ size_t sb_size; // sb_buffer size
// "virtual index" that points to the first sb_buffer row that we need to
// push to the terminal buffer when refreshing the scrollback. When negative,
// it actually points to entries that are no longer in sb_buffer (because the
// window height has increased) and must be deleted from the terminal buffer
int sb_pending;
+
// buf_T instance that acts as a "drawing surface" for libvterm
// we can't store a direct reference to the buffer because the
// refresh_timer_cb may be called after the buffer was freed, and there's
// no way to know if the memory was reused.
- uint64_t buf_handle;
+ handle_T buf_handle;
// program exited
bool closed, destroy;
+
// some vterm properties
bool forward_mouse;
- // invalid rows libvterm screen
- int invalid_start, invalid_end;
+ int invalid_start, invalid_end; // invalid rows in libvterm screen
struct {
int row, col;
bool visible;
} cursor;
- // which mouse button is pressed
- int pressed_button;
- // pending width/height
- bool pending_resize;
- // With a reference count of 0 the terminal can be freed.
- size_t refcount;
+ int pressed_button; // which mouse button is pressed
+ bool pending_resize; // pending width/height
+
+ size_t refcount; // reference count
};
static VTermScreenCallbacks vterm_screen_callbacks = {
@@ -166,7 +160,7 @@ void terminal_init(void)
invalidated_terminals = pmap_new(ptr_t)();
time_watcher_init(&main_loop, &refresh_timer, NULL);
// refresh_timer_cb will redraw the screen which can call vimscript
- refresh_timer.events = queue_new_child(main_loop.events);
+ refresh_timer.events = multiqueue_new_child(main_loop.events);
// initialize a rgb->color index map for cterm attributes(VTermScreenCell
// only has RGB information and we need color indexes for terminal UIs)
@@ -174,7 +168,7 @@ void terminal_init(void)
VTerm *vt = vterm_new(24, 80);
VTermState *state = vterm_obtain_state(vt);
- for (int color_index = 0; color_index < 256; color_index++) {
+ for (int color_index = 255; color_index >= 0; color_index--) {
VTermColor color;
// Some of the default 16 colors has the same color as the later
// 240 colors. To avoid collisions, we will use the custom colors
@@ -187,13 +181,14 @@ void terminal_init(void)
vterm_state_get_palette_color(state, color_index, &color);
}
map_put(int, int)(color_indexes,
- RGB(color.red, color.green, color.blue), color_index + 1);
+ RGB_(color.red, color.green, color.blue),
+ color_index + 1);
}
VTermColor fg, bg;
vterm_state_get_default_colors(state, &fg, &bg);
- default_vt_fg = RGB(fg.red, fg.green, fg.blue);
- default_vt_bg = RGB(bg.red, bg.green, bg.blue);
+ default_vt_fg = RGB_(fg.red, fg.green, fg.blue);
+ default_vt_bg = RGB_(bg.red, bg.green, bg.blue);
default_vt_bg_rgb = bg;
vterm_free(vt);
}
@@ -201,7 +196,7 @@ void terminal_init(void)
void terminal_teardown(void)
{
time_watcher_stop(&refresh_timer);
- queue_free(refresh_timer.events);
+ multiqueue_free(refresh_timer.events);
time_watcher_close(&refresh_timer, NULL);
pmap_free(ptr_t)(invalidated_terminals);
map_free(int, int)(color_indexes);
@@ -236,25 +231,26 @@ Terminal *terminal_open(TerminalOptions opts)
rv->invalid_start = 0;
rv->invalid_end = opts.height;
refresh_screen(rv, curbuf);
- set_option_value((uint8_t *)"buftype", 0, (uint8_t *)"terminal", OPT_LOCAL);
- // some sane settings for terminal buffers
- set_option_value((uint8_t *)"wrap", false, NULL, OPT_LOCAL);
- set_option_value((uint8_t *)"number", false, NULL, OPT_LOCAL);
- set_option_value((uint8_t *)"relativenumber", false, NULL, OPT_LOCAL);
+ set_option_value("buftype", 0, "terminal", OPT_LOCAL); // -V666
+
+ // Default settings for terminal buffers
+ curbuf->b_p_ma = false; // 'nomodifiable'
+ curbuf->b_p_ul = -1; // 'undolevels'
+ curbuf->b_p_scbk = p_scbk; // 'scrollback'
+ curbuf->b_p_tw = 0; // 'textwidth'
+ set_option_value("wrap", false, NULL, OPT_LOCAL);
+ set_option_value("list", false, NULL, OPT_LOCAL);
+ buf_set_term_title(curbuf, (char *)curbuf->b_ffname);
RESET_BINDING(curwin);
- // Apply TermOpen autocmds so the user can configure the terminal
+ // Reset cursor in current window.
+ curwin->w_cursor = (pos_T){ .lnum = 1, .col = 0, .coladd = 0 };
+
+ // Apply TermOpen autocmds _before_ configuring the scrollback buffer.
apply_autocmds(EVENT_TERMOPEN, NULL, NULL, false, curbuf);
- // Configure the scrollback buffer. Try to get the size from:
- //
- // - b:terminal_scrollback_buffer_size
- // - g:terminal_scrollback_buffer_size
- // - SCROLLBACK_BUFFER_DEFAULT_SIZE
- //
- // but limit to 100k.
- int size = get_config_int("terminal_scrollback_buffer_size");
- rv->sb_size = size > 0 ? (size_t)size : SCROLLBACK_BUFFER_DEFAULT_SIZE;
- rv->sb_size = MIN(rv->sb_size, 100000);
+ // Configure the scrollback buffer.
+ rv->sb_size = curbuf->b_p_scbk < 0
+ ? SB_MAX : (size_t)MAX(1, curbuf->b_p_scbk);
rv->sb_buffer = xmalloc(sizeof(ScrollbackLine *) * rv->sb_size);
if (!true_color) {
@@ -306,8 +302,16 @@ void terminal_close(Terminal *term, char *msg)
}
term->forward_mouse = false;
- term->closed = true;
+
+ // flush any pending changes to the buffer
+ if (!exiting) {
+ block_autocmds();
+ refresh_terminal(term);
+ unblock_autocmds();
+ }
+
buf_T *buf = handle_get_buffer(term->buf_handle);
+ term->closed = true;
if (!msg || exiting) {
// If no msg was given, this was called by close_buffer(buffer.c). Or if
@@ -333,22 +337,22 @@ void terminal_close(Terminal *term, char *msg)
void terminal_resize(Terminal *term, uint16_t width, uint16_t height)
{
if (term->closed) {
- // will be called after exited if two windows display the same terminal and
- // one of the is closed as a consequence of pressing a key.
+ // If two windows display the same terminal and one is closed by keypress.
return;
}
+ bool force = width == UINT16_MAX || height == UINT16_MAX;
int curwidth, curheight;
vterm_get_size(term->vt, &curheight, &curwidth);
- if (!width) {
+ if (force || !width) {
width = (uint16_t)curwidth;
}
- if (!height) {
+ if (force || !height) {
height = (uint16_t)curheight;
}
- if (curheight == height && curwidth == width) {
+ if (!force && curheight == height && curwidth == width) {
return;
}
@@ -356,6 +360,15 @@ void terminal_resize(Terminal *term, uint16_t width, uint16_t height)
return;
}
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ if (wp->w_buffer && wp->w_buffer->terminal == term) {
+ const uint16_t win_width =
+ (uint16_t)(MAX(0, wp->w_width - win_col_off(wp)));
+ width = MAX(width, win_width);
+ height = (uint16_t)MAX(height, wp->w_height);
+ }
+ }
+
vterm_set_size(term->vt, height, width);
vterm_screen_flush_damage(term->vts);
term->pending_resize = true;
@@ -365,26 +378,33 @@ void terminal_resize(Terminal *term, uint16_t width, uint16_t height)
void terminal_enter(void)
{
buf_T *buf = curbuf;
+ assert(buf->terminal); // Should only be called when curbuf has a terminal.
TerminalState state, *s = &state;
memset(s, 0, sizeof(TerminalState));
s->term = buf->terminal;
- assert(s->term && "should only be called when curbuf has a terminal");
// Ensure the terminal is properly sized.
terminal_resize(s->term, 0, 0);
- checkpcmark();
- setpcmark();
int save_state = State;
s->save_rd = RedrawingDisabled;
State = TERM_FOCUS;
mapped_ctrl_c |= TERM_FOCUS; // Always map CTRL-C to avoid interrupt.
RedrawingDisabled = false;
- // go to the bottom when the terminal is focused
- adjust_topline(s->term, buf, false);
+
+ // Disable these options in terminal-mode. They are nonsense because cursor is
+ // placed at end of buffer to "follow" output.
+ win_T *save_curwin = curwin;
+ int save_w_p_cul = curwin->w_p_cul;
+ int save_w_p_cuc = curwin->w_p_cuc;
+ curwin->w_p_cul = false;
+ curwin->w_p_cuc = false;
+
+ adjust_topline(s->term, buf, 0); // scroll to end
// erase the unfocused cursor
invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1);
showmode();
+ curwin->w_redr_status = true; // For mode() in statusline. #8323
ui_busy_start();
redraw(false);
@@ -394,6 +414,11 @@ void terminal_enter(void)
restart_edit = 0;
State = save_state;
RedrawingDisabled = s->save_rd;
+ if (save_curwin == curwin) { // save_curwin may be invalid (window closed)!
+ curwin->w_p_cul = save_w_p_cul;
+ curwin->w_p_cuc = save_w_p_cuc;
+ }
+
// draw the unfocused cursor
invalidate_terminal(s->term, s->term->cursor.row, s->term->cursor.row + 1);
unshowmode(true);
@@ -413,14 +438,6 @@ static int terminal_execute(VimState *state, int key)
TerminalState *s = (TerminalState *)state;
switch (key) {
- case K_FOCUSGAINED: // nvim has been given focus
- apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
- break;
-
- case K_FOCUSLOST: // nvim has lost focus
- apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
- break;
-
// Temporary fix until paste events gets implemented
case K_PASTE:
break;
@@ -444,7 +461,7 @@ static int terminal_execute(VimState *state, int key)
case K_EVENT:
// We cannot let an event free the terminal yet. It is still needed.
s->term->refcount++;
- queue_process_events(main_loop.events);
+ multiqueue_process_events(main_loop.events);
s->term->refcount--;
if (s->term->buf_handle == 0) {
s->close = true;
@@ -452,15 +469,19 @@ static int terminal_execute(VimState *state, int key)
}
break;
+ case K_COMMAND:
+ do_cmdline(NULL, getcmdkeycmd, NULL, 0);
+ break;
+
case Ctrl_N:
- if (s->got_bs) {
+ if (s->got_bsl) {
return 0;
}
- // FALLTHROUGH
+ FALLTHROUGH;
default:
- if (key == Ctrl_BSL && !s->got_bs) {
- s->got_bs = true;
+ if (key == Ctrl_BSL && !s->got_bsl) {
+ s->got_bsl = true;
break;
}
if (s->term->closed) {
@@ -468,7 +489,7 @@ static int terminal_execute(VimState *state, int key)
return 0;
}
- s->got_bs = false;
+ s->got_bsl = false;
terminal_send_key(s->term, key);
}
@@ -508,9 +529,36 @@ void terminal_send(Terminal *term, char *data, size_t size)
term->opts.write_cb(data, size, term->opts.data);
}
+void terminal_paste(long count, char_u **y_array, size_t y_size)
+{
+ for (int i = 0; i < count; i++) { // -V756
+ // feed the lines to the terminal
+ for (size_t j = 0; j < y_size; j++) {
+ if (j) {
+ // terminate the previous line
+ terminal_send(curbuf->terminal, "\n", 1);
+ }
+ terminal_send(curbuf->terminal, (char *)y_array[j], STRLEN(y_array[j]));
+ }
+ }
+}
+
+void terminal_flush_output(Terminal *term)
+{
+ size_t len = vterm_output_read(term->vt, term->textbuf,
+ sizeof(term->textbuf));
+ terminal_send(term, term->textbuf, len);
+}
+
void terminal_send_key(Terminal *term, int c)
{
VTermModifier mod = VTERM_MOD_NONE;
+
+ // Convert K_ZERO back to ASCII
+ if (c == K_ZERO) {
+ c = Ctrl_AT;
+ }
+
VTermKey key = convert_key(c, &mod);
if (key) {
@@ -519,9 +567,7 @@ void terminal_send_key(Terminal *term, int c)
vterm_keyboard_unichar(term->vt, (uint32_t)c, mod);
}
- size_t len = vterm_output_read(term->vt, term->textbuf,
- sizeof(term->textbuf));
- terminal_send(term, term->textbuf, (size_t)len);
+ terminal_flush_output(term);
}
void terminal_receive(Terminal *term, char *data, size_t len)
@@ -535,7 +581,7 @@ void terminal_receive(Terminal *term, char *data, size_t len)
}
void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr,
- int *term_attrs)
+ int *term_attrs)
{
int height, width;
vterm_get_size(term->vt, &height, &width);
@@ -551,8 +597,8 @@ void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr,
VTermScreenCell cell;
fetch_cell(term, row, col, &cell);
// Get the rgb value set by libvterm.
- int vt_fg = RGB(cell.fg.red, cell.fg.green, cell.fg.blue);
- int vt_bg = RGB(cell.bg.red, cell.bg.green, cell.bg.blue);
+ int vt_fg = RGB_(cell.fg.red, cell.fg.green, cell.fg.blue);
+ int vt_bg = RGB_(cell.bg.red, cell.bg.green, cell.bg.blue);
vt_fg = vt_fg != default_vt_fg ? vt_fg : - 1;
vt_bg = vt_bg != default_vt_bg ? vt_bg : - 1;
// Since libvterm does not expose the color index used by the program, we
@@ -571,26 +617,34 @@ void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr,
int attr_id = 0;
if (hl_attrs || vt_fg != -1 || vt_bg != -1) {
- attr_id = get_attr_entry(&(attrentry_T) {
+ attr_id = hl_get_term_attr(&(HlAttrs) {
.cterm_ae_attr = (int16_t)hl_attrs,
.cterm_fg_color = vt_fg_idx,
.cterm_bg_color = vt_bg_idx,
.rgb_ae_attr = (int16_t)hl_attrs,
.rgb_fg_color = vt_fg,
.rgb_bg_color = vt_bg,
+ .rgb_sp_color = -1,
});
}
if (term->cursor.visible && term->cursor.row == row
&& term->cursor.col == col) {
- attr_id = hl_combine_attr(attr_id, is_focused(term) && wp == curwin ?
- hl_attr(HLF_TERM) : hl_attr(HLF_TERMNC));
+ attr_id = hl_combine_attr(attr_id,
+ is_focused(term) && wp == curwin
+ ? win_hl_attr(wp, HLF_TERM)
+ : win_hl_attr(wp, HLF_TERMNC));
}
term_attrs[col] = attr_id;
}
}
+Buffer terminal_buf(const Terminal *term)
+{
+ return term->buf_handle;
+}
+
// }}}
// libvterm callbacks {{{
@@ -618,6 +672,20 @@ static int term_movecursor(VTermPos new, VTermPos old, int visible,
return 1;
}
+static void buf_set_term_title(buf_T *buf, char *title)
+ FUNC_ATTR_NONNULL_ALL
+{
+ Error err = ERROR_INIT;
+ dict_set_var(buf->b_vars,
+ STATIC_CSTR_AS_STRING("term_title"),
+ STRING_OBJ(cstr_as_string(title)),
+ false,
+ false,
+ &err);
+ api_clear_error(&err);
+ status_redraw_buf(buf);
+}
+
static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
{
Terminal *term = data;
@@ -633,12 +701,7 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
case VTERM_PROP_TITLE: {
buf_T *buf = handle_get_buffer(term->buf_handle);
- Error err;
- api_free_object(dict_set_value(buf->b_vars,
- cstr_as_string("term_title"),
- STRING_OBJ(cstr_as_string(val->string)),
- false,
- &err));
+ buf_set_term_title(buf, val->string);
break;
}
@@ -655,14 +718,19 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data)
static int term_bell(void *data)
{
- ui_putc('\x07');
+ ui_call_bell();
return 1;
}
-// the scrollback push/pop handlers were copied almost verbatim from pangoterm
+// Scrollback push handler (from pangoterm).
static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
{
Terminal *term = data;
+
+ if (!term->sb_size) {
+ return 0;
+ }
+
// copy vterm cells into sb_buffer
size_t c = (size_t)cols;
ScrollbackLine *sbrow = NULL;
@@ -674,10 +742,12 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
xfree(term->sb_buffer[term->sb_current - 1]);
}
+ // Make room at the start by shifting to the right.
memmove(term->sb_buffer + 1, term->sb_buffer,
sizeof(term->sb_buffer[0]) * (term->sb_current - 1));
} else if (term->sb_current > 0) {
+ // Make room at the start by shifting to the right.
memmove(term->sb_buffer + 1, term->sb_buffer,
sizeof(term->sb_buffer[0]) * term->sb_current);
}
@@ -687,6 +757,7 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
sbrow->cols = c;
}
+ // New row is added at the start of the storage buffer.
term->sb_buffer[0] = sbrow;
if (term->sb_current < term->sb_size) {
term->sb_current++;
@@ -702,6 +773,11 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
return 1;
}
+/// Scrollback pop handler (from pangoterm).
+///
+/// @param cols
+/// @param cells VTerm state to update.
+/// @param data Terminal
static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
{
Terminal *term = data;
@@ -714,24 +790,24 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
term->sb_pending--;
}
- // restore vterm state
- size_t c = (size_t)cols;
ScrollbackLine *sbrow = term->sb_buffer[0];
term->sb_current--;
+ // Forget the "popped" row by shifting the rest onto it.
memmove(term->sb_buffer, term->sb_buffer + 1,
sizeof(term->sb_buffer[0]) * (term->sb_current));
- size_t cols_to_copy = c;
+ size_t cols_to_copy = (size_t)cols;
if (cols_to_copy > sbrow->cols) {
cols_to_copy = sbrow->cols;
}
// copy to vterm state
memcpy(cells, sbrow->cells, sizeof(cells[0]) * cols_to_copy);
- for (size_t col = cols_to_copy; col < c; col++) {
+ for (size_t col = cols_to_copy; col < (size_t)cols; col++) {
cells[col].chars[0] = 0;
cells[col].width = 1;
}
+
xfree(sbrow);
pmap_put(ptr_t)(invalidated_terminals, term, NULL);
@@ -741,26 +817,60 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
// }}}
// input handling {{{
-static void convert_modifiers(VTermModifier *statep)
+static void convert_modifiers(int key, VTermModifier *statep)
{
if (mod_mask & MOD_MASK_SHIFT) { *statep |= VTERM_MOD_SHIFT; }
if (mod_mask & MOD_MASK_CTRL) { *statep |= VTERM_MOD_CTRL; }
if (mod_mask & MOD_MASK_ALT) { *statep |= VTERM_MOD_ALT; }
+
+ switch (key) {
+ case K_S_TAB:
+ case K_S_UP:
+ case K_S_DOWN:
+ case K_S_LEFT:
+ case K_S_RIGHT:
+ case K_S_F1:
+ case K_S_F2:
+ case K_S_F3:
+ case K_S_F4:
+ case K_S_F5:
+ case K_S_F6:
+ case K_S_F7:
+ case K_S_F8:
+ case K_S_F9:
+ case K_S_F10:
+ case K_S_F11:
+ case K_S_F12:
+ *statep |= VTERM_MOD_SHIFT;
+ break;
+
+ case K_C_LEFT:
+ case K_C_RIGHT:
+ *statep |= VTERM_MOD_CTRL;
+ break;
+ }
}
static VTermKey convert_key(int key, VTermModifier *statep)
{
- convert_modifiers(statep);
+ convert_modifiers(key, statep);
switch (key) {
case K_BS: return VTERM_KEY_BACKSPACE;
+ case K_S_TAB: FALLTHROUGH;
case TAB: return VTERM_KEY_TAB;
case Ctrl_M: return VTERM_KEY_ENTER;
case ESC: return VTERM_KEY_ESCAPE;
+ case K_S_UP: FALLTHROUGH;
case K_UP: return VTERM_KEY_UP;
+ case K_S_DOWN: FALLTHROUGH;
case K_DOWN: return VTERM_KEY_DOWN;
+ case K_S_LEFT: FALLTHROUGH;
+ case K_C_LEFT: FALLTHROUGH;
case K_LEFT: return VTERM_KEY_LEFT;
+ case K_S_RIGHT: FALLTHROUGH;
+ case K_C_RIGHT: FALLTHROUGH;
case K_RIGHT: return VTERM_KEY_RIGHT;
case K_INS: return VTERM_KEY_INS;
@@ -770,22 +880,22 @@ static VTermKey convert_key(int key, VTermModifier *statep)
case K_PAGEUP: return VTERM_KEY_PAGEUP;
case K_PAGEDOWN: return VTERM_KEY_PAGEDOWN;
- case K_K0:
+ case K_K0: FALLTHROUGH;
case K_KINS: return VTERM_KEY_KP_0;
- case K_K1:
+ case K_K1: FALLTHROUGH;
case K_KEND: return VTERM_KEY_KP_1;
case K_K2: return VTERM_KEY_KP_2;
- case K_K3:
+ case K_K3: FALLTHROUGH;
case K_KPAGEDOWN: return VTERM_KEY_KP_3;
case K_K4: return VTERM_KEY_KP_4;
case K_K5: return VTERM_KEY_KP_5;
case K_K6: return VTERM_KEY_KP_6;
- case K_K7:
+ case K_K7: FALLTHROUGH;
case K_KHOME: return VTERM_KEY_KP_7;
case K_K8: return VTERM_KEY_KP_8;
- case K_K9:
+ case K_K9: FALLTHROUGH;
case K_KPAGEUP: return VTERM_KEY_KP_9;
- case K_KDEL:
+ case K_KDEL: FALLTHROUGH;
case K_KPOINT: return VTERM_KEY_KP_PERIOD;
case K_KENTER: return VTERM_KEY_KP_ENTER;
case K_KPLUS: return VTERM_KEY_KP_PLUS;
@@ -793,6 +903,57 @@ static VTermKey convert_key(int key, VTermModifier *statep)
case K_KMULTIPLY: return VTERM_KEY_KP_MULT;
case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE;
+ case K_S_F1: FALLTHROUGH;
+ case K_F1: return VTERM_KEY_FUNCTION(1);
+ case K_S_F2: FALLTHROUGH;
+ case K_F2: return VTERM_KEY_FUNCTION(2);
+ case K_S_F3: FALLTHROUGH;
+ case K_F3: return VTERM_KEY_FUNCTION(3);
+ case K_S_F4: FALLTHROUGH;
+ case K_F4: return VTERM_KEY_FUNCTION(4);
+ case K_S_F5: FALLTHROUGH;
+ case K_F5: return VTERM_KEY_FUNCTION(5);
+ case K_S_F6: FALLTHROUGH;
+ case K_F6: return VTERM_KEY_FUNCTION(6);
+ case K_S_F7: FALLTHROUGH;
+ case K_F7: return VTERM_KEY_FUNCTION(7);
+ case K_S_F8: FALLTHROUGH;
+ case K_F8: return VTERM_KEY_FUNCTION(8);
+ case K_S_F9: FALLTHROUGH;
+ case K_F9: return VTERM_KEY_FUNCTION(9);
+ case K_S_F10: FALLTHROUGH;
+ case K_F10: return VTERM_KEY_FUNCTION(10);
+ case K_S_F11: FALLTHROUGH;
+ case K_F11: return VTERM_KEY_FUNCTION(11);
+ case K_S_F12: FALLTHROUGH;
+ case K_F12: return VTERM_KEY_FUNCTION(12);
+
+ case K_F13: return VTERM_KEY_FUNCTION(13);
+ case K_F14: return VTERM_KEY_FUNCTION(14);
+ case K_F15: return VTERM_KEY_FUNCTION(15);
+ case K_F16: return VTERM_KEY_FUNCTION(16);
+ case K_F17: return VTERM_KEY_FUNCTION(17);
+ case K_F18: return VTERM_KEY_FUNCTION(18);
+ case K_F19: return VTERM_KEY_FUNCTION(19);
+ case K_F20: return VTERM_KEY_FUNCTION(20);
+ case K_F21: return VTERM_KEY_FUNCTION(21);
+ case K_F22: return VTERM_KEY_FUNCTION(22);
+ case K_F23: return VTERM_KEY_FUNCTION(23);
+ case K_F24: return VTERM_KEY_FUNCTION(24);
+ case K_F25: return VTERM_KEY_FUNCTION(25);
+ case K_F26: return VTERM_KEY_FUNCTION(26);
+ case K_F27: return VTERM_KEY_FUNCTION(27);
+ case K_F28: return VTERM_KEY_FUNCTION(28);
+ case K_F29: return VTERM_KEY_FUNCTION(29);
+ case K_F30: return VTERM_KEY_FUNCTION(30);
+ case K_F31: return VTERM_KEY_FUNCTION(31);
+ case K_F32: return VTERM_KEY_FUNCTION(32);
+ case K_F33: return VTERM_KEY_FUNCTION(33);
+ case K_F34: return VTERM_KEY_FUNCTION(34);
+ case K_F35: return VTERM_KEY_FUNCTION(35);
+ case K_F36: return VTERM_KEY_FUNCTION(36);
+ case K_F37: return VTERM_KEY_FUNCTION(37);
+
default: return VTERM_KEY_NONE;
}
}
@@ -830,11 +991,11 @@ static bool send_mouse_event(Terminal *term, int c)
bool drag = false;
switch (c) {
- case K_LEFTDRAG: drag = true; // FALLTHROUGH
+ case K_LEFTDRAG: drag = true; FALLTHROUGH;
case K_LEFTMOUSE: button = 1; break;
- case K_MIDDLEDRAG: drag = true; // FALLTHROUGH
+ case K_MIDDLEDRAG: drag = true; FALLTHROUGH;
case K_MIDDLEMOUSE: button = 2; break;
- case K_RIGHTDRAG: drag = true; // FALLTHROUGH
+ case K_RIGHTDRAG: drag = true; FALLTHROUGH;
case K_RIGHTMOUSE: button = 3; break;
case K_MOUSEDOWN: button = 4; break;
case K_MOUSEUP: button = 5; break;
@@ -843,7 +1004,7 @@ static bool send_mouse_event(Terminal *term, int c)
mouse_action(term, button, row, col, drag, 0);
size_t len = vterm_output_read(term->vt, term->textbuf,
- sizeof(term->textbuf));
+ sizeof(term->textbuf));
terminal_send(term, term->textbuf, (size_t)len);
return false;
}
@@ -877,7 +1038,7 @@ static bool send_mouse_event(Terminal *term, int c)
// terminal buffer refresh & misc {{{
-void fetch_row(Terminal *term, int row, int end_col)
+static void fetch_row(Terminal *term, int row, int end_col)
{
int col = 0;
size_t line_len = 0;
@@ -947,33 +1108,34 @@ static void invalidate_terminal(Terminal *term, int start_row, int end_row)
static void refresh_terminal(Terminal *term)
{
- // TODO(SplinterOfChaos): Find the condition that makes term->buf invalid.
buf_T *buf = handle_get_buffer(term->buf_handle);
bool valid = true;
if (!buf || !(valid = buf_valid(buf))) {
- // destroyed by `close_buffer`. Dont do anything else
+ // Destroyed by `close_buffer`. Do not do anything else.
if (!valid) {
term->buf_handle = 0;
}
return;
}
- bool pending_resize = term->pending_resize;
+ long ml_before = buf->b_ml.ml_line_count;
WITH_BUFFER(buf, {
refresh_size(term, buf);
refresh_scrollback(term, buf);
refresh_screen(term, buf);
- redraw_buf_later(buf, NOT_VALID);
});
- adjust_topline(term, buf, pending_resize);
+ long ml_added = buf->b_ml.ml_line_count - ml_before;
+ adjust_topline(term, buf, ml_added);
}
-// libuv timer callback. This will enqueue on_refresh to be processed as an
-// event.
+// Calls refresh_terminal() on all invalidated_terminals.
static void refresh_timer_cb(TimeWatcher *watcher, void *data)
{
- if (exiting) {
- // bad things can happen if we redraw when exiting, and there's no need to
- // update the buffer.
- goto end;
+ refresh_pending = false;
+ if (exiting // Cannot redraw (requires event loop) during teardown/exit.
+ || (State & CMDPREVIEW)
+ // WM_LIST (^D) is not redrawn, unlike the normal wildmenu. So we must
+ // skip redraws to keep it visible.
+ || wild_menu_showing == WM_LIST) {
+ return;
}
Terminal *term;
void *stub; (void)(stub);
@@ -982,11 +1144,12 @@ static void refresh_timer_cb(TimeWatcher *watcher, void *data)
map_foreach(invalidated_terminals, term, stub, {
refresh_terminal(term);
});
+ bool any_visible = is_term_visible();
pmap_clear(ptr_t)(invalidated_terminals);
unblock_autocmds();
- redraw(true);
-end:
- refresh_pending = false;
+ if (any_visible) {
+ redraw(true);
+ }
}
static void refresh_size(Terminal *term, buf_T *buf)
@@ -1003,7 +1166,37 @@ static void refresh_size(Terminal *term, buf_T *buf)
term->opts.resize_cb((uint16_t)width, (uint16_t)height, term->opts.data);
}
-// Refresh the scrollback of a invalidated terminal
+/// Adjusts scrollback storage after 'scrollback' option changed.
+static void on_scrollback_option_changed(Terminal *term, buf_T *buf)
+{
+ const size_t scbk = curbuf->b_p_scbk < 0
+ ? SB_MAX : (size_t)MAX(1, curbuf->b_p_scbk);
+ assert(term->sb_current < SIZE_MAX);
+ if (term->sb_pending > 0) { // Pending rows must be processed first.
+ abort();
+ }
+
+ // Delete lines exceeding the new 'scrollback' limit.
+ if (scbk < term->sb_current) {
+ size_t diff = term->sb_current - scbk;
+ for (size_t i = 0; i < diff; i++) {
+ ml_delete(1, false);
+ term->sb_current--;
+ xfree(term->sb_buffer[term->sb_current]);
+ }
+ deleted_lines(1, (long)diff);
+ }
+
+ // Resize the scrollback storage.
+ size_t sb_region = sizeof(ScrollbackLine *) * scbk;
+ if (scbk != term->sb_size) {
+ term->sb_buffer = xrealloc(term->sb_buffer, sb_region);
+ }
+
+ term->sb_size = scbk;
+}
+
+// Refresh the scrollback of an invalidated terminal.
static void refresh_scrollback(Terminal *term, buf_T *buf)
{
int width, height;
@@ -1032,9 +1225,11 @@ static void refresh_scrollback(Terminal *term, buf_T *buf)
ml_delete(buf->b_ml.ml_line_count, false);
deleted_lines(buf->b_ml.ml_line_count, 1);
}
+
+ on_scrollback_option_changed(term, buf);
}
-// Refresh the screen(visible part of the buffer when the terminal is
+// Refresh the screen (visible part of the buffer when the terminal is
// focused) of a invalidated terminal
static void refresh_screen(Terminal *term, buf_T *buf)
{
@@ -1043,8 +1238,7 @@ static void refresh_screen(Terminal *term, buf_T *buf)
int height;
int width;
vterm_get_size(term->vt, &height, &width);
- // It's possible that the terminal height decreased and `term->invalid_end`
- // doesn't reflect it yet
+ // Terminal height may have decreased before `invalid_end` reflects it.
term->invalid_end = MIN(term->invalid_end, height);
for (int r = term->invalid_start, linenr = row_to_linenr(term, r);
@@ -1062,11 +1256,23 @@ static void refresh_screen(Terminal *term, buf_T *buf)
int change_start = row_to_linenr(term, term->invalid_start);
int change_end = change_start + changed;
- changed_lines(change_start, 0, change_end, added);
+ changed_lines(change_start, 0, change_end, added, true);
term->invalid_start = INT_MAX;
term->invalid_end = -1;
}
+/// @return true if any invalidated terminal buffer is visible to the user
+static bool is_term_visible(void)
+{
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_buffer->terminal
+ && pmap_has(ptr_t)(invalidated_terminals, wp->w_buffer->terminal)) {
+ return true;
+ }
+ }
+ return false;
+}
+
static void redraw(bool restore_cursor)
{
Terminal *term = curbuf->terminal;
@@ -1074,7 +1280,8 @@ static void redraw(bool restore_cursor)
restore_cursor = true;
}
- int save_row, save_col;
+ int save_row = 0;
+ int save_col = 0;
if (restore_cursor) {
// save the current row/col to restore after updating screen when not
// focused
@@ -1082,55 +1289,51 @@ static void redraw(bool restore_cursor)
save_col = ui_current_col();
}
block_autocmds();
- validate_cursor();
if (must_redraw) {
update_screen(0);
}
- redraw_statuslines();
-
- if (need_maketitle) {
+ if (need_maketitle) { // Update title in terminal-mode. #7248
maketitle();
}
- showruler(false);
-
- if (term && is_focused(term)) {
- curwin->w_wrow = term->cursor.row;
- curwin->w_wcol = term->cursor.col + win_col_off(curwin);
- setcursor();
- } else if (restore_cursor) {
+ if (restore_cursor) {
ui_cursor_goto(save_row, save_col);
} else if (term) {
- // exiting terminal focus, put the window cursor in a valid position
- int height, width;
- vterm_get_size(term->vt, &height, &width);
- curwin->w_wrow = height - 1;
- curwin->w_wcol = 0;
- setcursor();
+ curwin->w_wrow = term->cursor.row;
+ curwin->w_wcol = term->cursor.col + win_col_off(curwin);
+ curwin->w_cursor.lnum = MIN(curbuf->b_ml.ml_line_count,
+ row_to_linenr(term, term->cursor.row));
+ // Nudge cursor when returning to normal-mode.
+ int off = is_focused(term) ? 0 : (curwin->w_p_rl ? 1 : -1);
+ curwin->w_cursor.col = MAX(0, term->cursor.col + win_col_off(curwin) + off);
+ curwin->w_cursor.coladd = 0;
+ mb_check_adjust_col(curwin);
}
unblock_autocmds();
ui_flush();
}
-static void adjust_topline(Terminal *term, buf_T *buf, bool force)
+static void adjust_topline(Terminal *term, buf_T *buf, long added)
{
int height, width;
vterm_get_size(term->vt, &height, &width);
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_buffer == buf) {
- // for every window that displays a terminal, ensure the cursor is in a
- // valid line
- wp->w_cursor.lnum = MIN(wp->w_cursor.lnum, buf->b_ml.ml_line_count);
- if (force || curbuf != buf || is_focused(term)) {
- // if the terminal is not in the current window or if it's focused,
- // adjust topline/cursor so the window will "follow" the terminal
- // output
- wp->w_cursor.lnum = buf->b_ml.ml_line_count;
+ linenr_T ml_end = buf->b_ml.ml_line_count;
+ bool following = ml_end == wp->w_cursor.lnum + added; // cursor at end?
+
+ if (following || (wp == curwin && is_focused(term))) {
+ // "Follow" the terminal output
+ wp->w_cursor.lnum = ml_end;
set_topline(wp, MAX(wp->w_cursor.lnum - height + 1, 1));
+ } else {
+ // Ensure valid cursor for each window displaying this terminal.
+ wp->w_cursor.lnum = MIN(wp->w_cursor.lnum, ml_end);
}
+ mb_check_adjust_col(wp);
}
}
}
@@ -1152,12 +1355,14 @@ static bool is_focused(Terminal *term)
#define GET_CONFIG_VALUE(k, o) \
do { \
- Error err; \
+ Error err = ERROR_INIT; \
/* Only called from terminal_open where curbuf->terminal is the */ \
/* context */ \
o = dict_get_value(curbuf->b_vars, cstr_as_string(k), &err); \
+ api_clear_error(&err); \
if (o.type == kObjectTypeNil) { \
o = dict_get_value(&globvardict, cstr_as_string(k), &err); \
+ api_clear_error(&err); \
} \
} while (0)
@@ -1172,17 +1377,6 @@ static char *get_config_string(char *key)
return NULL;
}
-static int get_config_int(char *key)
-{
- Object obj;
- GET_CONFIG_VALUE(key, obj);
- if (obj.type == kObjectTypeInteger) {
- return (int)obj.data.integer;
- }
- api_free_object(obj);
- return 0;
-}
-
// }}}
// vim: foldmethod=marker
diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h
index 25e609fb68..f2b0e232c3 100644
--- a/src/nvim/terminal.h
+++ b/src/nvim/terminal.h
@@ -10,6 +10,8 @@ typedef void (*terminal_write_cb)(char *buffer, size_t size, void *data);
typedef void (*terminal_resize_cb)(uint16_t width, uint16_t height, void *data);
typedef void (*terminal_close_cb)(void *data);
+#include "nvim/buffer_defs.h"
+
typedef struct {
void *data;
uint16_t width, height;
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 4b0b5e8d26..fac27aa346 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -1,48 +1,54 @@
-#
+# vim: noet ts=8
# Makefile to run all tests for Vim
#
+ifeq ($(OS),Windows_NT)
+ NVIM_PRG ?= ../../../build/bin/nvim.exe
+else
+ NVIM_PRG ?= ../../../build/bin/nvim
+endif
+ROOT := ../../..
+
export SHELL := sh
+export NVIM_PRG := $(NVIM_PRG)
+export TMPDIR := $(abspath ../../../Xtest-tmpdir)
+
+SCRIPTS_DEFAULT = \
+ test14.out \
+ test37.out \
+ test42.out \
+ test48.out \
+ test52.out \
+ test64.out \
+
+ifneq ($(OS),Windows_NT)
+ SCRIPTS_DEFAULTS := $(SCRIPTS_DEFAULT) \
+ test17.out \
+ test49.out \
+
+endif
-VIMPROG := ../../../build/bin/nvim
-SCRIPTSOURCE := ../../../runtime
-
-SCRIPTS := \
- test8.out \
- test12.out \
- test13.out \
- test14.out \
- test17.out \
- test24.out \
- test30.out \
- test32.out \
- test37.out \
- test40.out \
- test42.out \
- test47.out \
- test48.out \
- test49.out \
- test52.out \
- test53.out \
- test64.out \
- test69.out \
- test73.out \
- test79.out \
- test_marks.out \
-
-# Tests using runtest.vim.vim.
-# Keep test_alot*.res as the last one, sort the others.
-NEW_TESTS = \
- test_cursor_func.res \
- test_hardcopy.res \
- test_help_tagjump.res \
- test_langmap.res \
- test_menu.res \
- test_syntax.res \
- test_timers.res \
- test_unlet.res \
- test_viml.res \
- test_alot.res
+SCRIPTS ?= $(SCRIPTS_DEFAULT)
+
+# Tests using runtest.vim.
+NEW_TESTS_ALOT := test_alot_utf8 test_alot
+NEW_TESTS_IN_ALOT := $(shell sed '/^source/ s/^source //;s/\.vim$$//' test_alot*.vim)
+# Ignored tests.
+# test_alot_latin: Nvim does not allow setting encoding.
+# test_arglist: ported to Lua, but kept for easier merging.
+# test_autochdir: ported to Lua, but kept for easier merging.
+# test_eval_func: used as include in old-style test (test_eval.in).
+# test_listlbr: Nvim does not allow setting encoding.
+# test_largefile: uses too much resources to run on CI.
+NEW_TESTS_IGNORE := $(NEW_TESTS_IN_ALOT) $(NEW_TESTS_ALOT) \
+ test_alot_latin \
+ test_arglist \
+ test_autochdir \
+ test_eval_func \
+ test_listlbr \
+ test_largefile \
+
+NEW_TESTS ?= $(addsuffix .res,$(sort $(filter-out $(NEW_TESTS_IGNORE),$(basename $(notdir $(wildcard test_*.vim))))) $(NEW_TESTS_ALOT))
SCRIPTS_GUI := test16.out
@@ -62,7 +68,7 @@ ifdef USE_VALGRIND
$(VALGRIND_TOOL) \
--suppressions=../../.valgrind.supp \
--error-exitcode=123 \
- --log-file=valgrind.\%p.$* \
+ --log-file=valgrind-\%p.$* \
$(VGDB) \
--trace-children=yes
else
@@ -80,7 +86,8 @@ nongui: nolog $(SCRIPTS) newtests report
gui: nolog $(SCRIPTS) $(SCRIPTS_GUI) newtests report
.gdbinit:
- echo 'set $$_exitcode = -1\nrun\nif $$_exitcode != -1\n quit\nend' > .gdbinit
+ @echo "[OLDTEST-PREP] Setting up .gdbinit"
+ @echo 'set $$_exitcode = -1\nrun\nif $$_exitcode != -1\n quit\nend' > .gdbinit
report:
@echo
@@ -93,13 +100,13 @@ report:
echo ALL DONE; \
fi"
-test1.out: $(VIMPROG)
+test1.out: $(NVIM_PRG)
-$(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG) test1.out
+$(SCRIPTS) $(SCRIPTS_GUI): $(NVIM_PRG) test1.out
RM_ON_RUN := test.out X* viminfo
RM_ON_START := test.ok
-RUN_VIM := VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(VIMPROG) -u unix.vim -U NONE -i viminfo --noplugin -s dotest.in
+RUN_VIM := $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE -i viminfo --headless --noplugin -s dotest.in
clean:
-rm -rf *.out \
@@ -107,6 +114,7 @@ clean:
*.res \
*.rej \
*.orig \
+ *.tlog \
test.log \
messages \
$(RM_ON_RUN) \
@@ -114,60 +122,38 @@ clean:
valgrind.* \
.*.swp \
.*.swo \
+ .gdbinit \
+ $(TMPDIR) \
del
test1.out: .gdbinit test1.in
- -rm -rf $*.failed $(RM_ON_RUN) $(RM_ON_START) wrongtermsize
- $(RUN_VIM) $*.in
- @/bin/sh -c "if test -e wrongtermsize; then \
- echo; \
- echo test1 FAILED - terminal size must be 80x24 or larger; \
- echo; exit 1; \
- elif diff test.out $*.ok; then \
- mv -f test.out $*.out; \
- else \
- echo; \
- echo test1 FAILED - Something basic is wrong; \
- echo; \
- exit 1; \
- fi"
- -rm -rf X* viminfo
+ @echo "[OLDTEST-PREP] Running test1"
+ @rm -rf $*.failed $(RM_ON_RUN) $(RM_ON_START) wrongtermsize
+ @mkdir -p $(TMPDIR)
+ @/bin/sh runnvim.sh $(ROOT) $(NVIM_PRG) $* $(RUN_VIM) $*.in
+ @rm -f wrongtermsize
+ @rm -rf X* viminfo
%.out: %.in .gdbinit
- -rm -rf $*.failed test.ok $(RM_ON_RUN)
- cp $*.ok test.ok
- # Sleep a moment to avoid that the xterm title is messed up.
- # 200 msec is sufficient, but only modern sleep supports a fraction of
- # a second, fall back to a second if it fails.
- @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1"
- $(RUN_VIM) $*.in
-
- # Check if the test.out file matches test.ok.
- @/bin/sh -c "if test -f test.out; then \
- if diff -u test.out $*.ok; then \
- mv -f test.out $*.out; \
- else \
- echo $* FAILED >> test.log; \
- mv -f test.out $*.failed; \
- fi; \
- else \
- echo $* NO OUTPUT >>test.log; \
- fi"
- @/bin/sh -c "if test -f valgrind; then \
- mv -f valgrind valgrind.$*; \
- fi"
- -rm -rf X* test.ok viminfo
-
+ @echo "[OLDESTTEST] Running" $*
+ @rm -rf $*.failed test.ok $(RM_ON_RUN)
+ @mkdir -p $(TMPDIR)
+ @cp $*.ok test.ok
+ @/bin/sh runnvim.sh --oldesttest $(ROOT) $(NVIM_PRG) $* $(RUN_VIM) $*.in
+ @rm -rf X* test.ok viminfo
+
+# Explicit dependencies.
test49.out: test49.vim
nolog:
- -rm -f test.log messages
+ @echo "[OLDTEST-PREP] Removing test.log and messages"
+ @rm -f test.log messages
# New style of tests uses Vim script with assert calls. These are easier
# to write and a lot easier to read and debug.
# Limitation: Only works with the +eval feature.
-RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -u unix.vim -U NONE --noplugin
+RUN_VIMTEST = $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE -i viminfo --headless --noplugin
newtests: newtestssilent
@/bin/sh -c "if test -f messages && grep -q 'FAILED' messages; then \
@@ -177,4 +163,6 @@ newtests: newtestssilent
newtestssilent: $(NEW_TESTS)
%.res: %.vim .gdbinit
- $(RUN_VIMTEST) -u NONE -S runtest.vim $*.vim
+ @echo "[OLDTEST] Running" $*
+ @mkdir -p $(TMPDIR)
+ @/bin/sh runnvim.sh $(ROOT) $(NVIM_PRG) $* $(RUN_VIMTEST) -u NONE -S runtest.vim $*.vim
diff --git a/src/nvim/testdir/pyxfile/py2_magic.py b/src/nvim/testdir/pyxfile/py2_magic.py
new file mode 100644
index 0000000000..819892fd16
--- /dev/null
+++ b/src/nvim/testdir/pyxfile/py2_magic.py
@@ -0,0 +1,4 @@
+# requires python 2.x
+
+import sys
+print(sys.version)
diff --git a/src/nvim/testdir/pyxfile/py2_shebang.py b/src/nvim/testdir/pyxfile/py2_shebang.py
new file mode 100644
index 0000000000..13bfc491ec
--- /dev/null
+++ b/src/nvim/testdir/pyxfile/py2_shebang.py
@@ -0,0 +1,4 @@
+#!/usr/bin/python2
+
+import sys
+print(sys.version)
diff --git a/src/nvim/testdir/pyxfile/py3_magic.py b/src/nvim/testdir/pyxfile/py3_magic.py
new file mode 100644
index 0000000000..d4b7ee0071
--- /dev/null
+++ b/src/nvim/testdir/pyxfile/py3_magic.py
@@ -0,0 +1,4 @@
+# requires python 3.x
+
+import sys
+print(sys.version)
diff --git a/src/nvim/testdir/pyxfile/py3_shebang.py b/src/nvim/testdir/pyxfile/py3_shebang.py
new file mode 100644
index 0000000000..ec05808ca4
--- /dev/null
+++ b/src/nvim/testdir/pyxfile/py3_shebang.py
@@ -0,0 +1,4 @@
+#!/usr/bin/python3
+
+import sys
+print(sys.version)
diff --git a/src/nvim/testdir/pyxfile/pyx.py b/src/nvim/testdir/pyxfile/pyx.py
new file mode 100644
index 0000000000..261a6512c0
--- /dev/null
+++ b/src/nvim/testdir/pyxfile/pyx.py
@@ -0,0 +1,2 @@
+import sys
+print(sys.version)
diff --git a/src/nvim/testdir/runnvim.sh b/src/nvim/testdir/runnvim.sh
new file mode 100755
index 0000000000..43556f3ad3
--- /dev/null
+++ b/src/nvim/testdir/runnvim.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+main() {(
+ local separator="================================================================================"
+ local oldesttest=
+ if test "$1" = "--oldesttest" ; then
+ shift
+ oldesttest=1
+ fi
+ local root="$1" ; shift
+ local nvim_prg="$1" ; shift
+ local test_name="$1" ; shift
+
+ local tlog="$test_name.tlog"
+
+ export NVIM_TEST_ARGC=$#
+ local arg
+ local i=0
+ for arg ; do
+ eval "export NVIM_TEST_ARG$i=\"\$arg\""
+ i=$(( i+1 ))
+ done
+
+ export CI_DIR="$root/ci"
+ export BUILD_DIR="$(dirname "$nvim_prg")/.."
+ export FAILED=0
+
+ . "$CI_DIR/common/suite.sh"
+ . "$CI_DIR/common/test.sh"
+
+ export VIMRUNTIME="$root/runtime"
+ if ! "$nvim_prg" \
+ -u NONE -i NONE \
+ --headless \
+ --cmd 'set shortmess+=I noswapfile noundofile nomore' \
+ -S runnvim.vim \
+ "$tlog" > "out-$tlog" 2> "err-$tlog"
+ then
+ fail "$test_name" F "Nvim exited with non-zero code"
+ fi
+ echo "Stdout of :terminal runner" >> "$tlog"
+ echo "$separator" >> "$tlog"
+ cat "out-$tlog" >> "$tlog"
+ echo "$separator" >> "$tlog"
+ echo "Stderr of :terminal runner" >> "$tlog"
+ echo "$separator" >> "$tlog"
+ cat "err-$tlog" >> "$tlog"
+ echo "$separator" >> "$tlog"
+ if test "$oldesttest" = 1 ; then
+ if ! diff -q test.out "$test_name.ok" > /dev/null 2>&1 ; then
+ if test -f test.out ; then
+ fail "$test_name" F "Oldest test .out file differs from .ok file"
+ echo "Diff between test.out and $test_name.ok" >> "$tlog"
+ echo "$separator" >> "$tlog"
+ diff -a test.out "$test_name.ok" >> "$tlog"
+ echo "$separator" >> "$tlog"
+ else
+ echo "No output in test.out" >> "$tlog"
+ fi
+ fi
+ fi
+ if test "$FAILED" = 1 ; then
+ travis_fold start "$NVIM_TEST_CURRENT_SUITE/$test_name"
+ fi
+ valgrind_check .
+ if test -n "$LOG_DIR" ; then
+ asan_check "$LOG_DIR"
+ fi
+ check_core_dumps
+ if test "$FAILED" = 1 ; then
+ cat "$tlog"
+ fi
+ rm -f "$tlog"
+ if test "$FAILED" = 1 ; then
+ travis_fold end "$NVIM_TEST_CURRENT_SUITE/$test_name"
+ fi
+ if test "$FAILED" = 1 ; then
+ echo "Test $test_name failed, see output above and summary for more details" >> test.log
+ fi
+)}
+
+main "$@"
diff --git a/src/nvim/testdir/runnvim.vim b/src/nvim/testdir/runnvim.vim
new file mode 100644
index 0000000000..396a3a6477
--- /dev/null
+++ b/src/nvim/testdir/runnvim.vim
@@ -0,0 +1,55 @@
+let s:logger = {'d_events': []}
+function s:logger.on_stdout(id, data, event)
+ call add(self.d_events, [a:event, a:data])
+endfunction
+let s:logger.on_stderr = s:logger.on_stdout
+function s:logger.on_exit(id, data, event)
+ call add(self.d_events, [a:event, ['']])
+endfunction
+
+function Main()
+ let argc = +$NVIM_TEST_ARGC
+ let args = []
+ for i in range(argc)
+ call add(args, eval("$NVIM_TEST_ARG" . i))
+ endfor
+ set lines=25
+ set columns=80
+ enew
+ let job = termopen(args, s:logger)
+ let results = jobwait([job], 5 * 60 * 1000)
+ " TODO(ZyX-I): Get colors
+ let screen = getline(1, '$')
+ bwipeout!
+ let stringified_events = map(s:logger.d_events,
+ \'v:val[0] . ": " . ' .
+ \'join(map(v:val[1], '.
+ \ '''substitute(v:val, '.
+ \ '"\\v\\C(\\p@!.|\\<)", '.
+ \ '"\\=printf(\"<%x>\", '.
+ \ 'char2nr(submatch(0)))", '.
+ \ '"")''), '.
+ \ '''\n'')')
+ call setline(1, [
+ \ 'Job exited with code ' . results[0],
+ \ printf('Screen (%u lines)', len(screen)),
+ \ repeat('=', 80),
+ \] + screen + [
+ \ repeat('=', 80),
+ \ printf('Events (%u lines):', len(stringified_events)),
+ \ repeat('=', 80),
+ \] + stringified_events + [
+ \ repeat('=', 80),
+ \])
+ write
+ if results[0] != 0
+ if results[0] != -1
+ call jobstop(job)
+ endif
+ cquit
+ else
+ qall
+ endif
+endfunction
+
+call Main()
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index 1b1f5d7688..bfd6240f0c 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -2,6 +2,11 @@
" When the script is successful the .res file will be created.
" Errors are appended to the test.log file.
"
+" To execute only specific test functions, add a second argument. It will be
+" matched against the names of the Test_ function. E.g.:
+" ../vim -u NONE -S runtest.vim test_channel.vim open_delay
+" The output can be found in the "messages" file.
+"
" The test script may contain anything, only functions that start with
" "Test_" are special. These will be invoked and should contain assert
" functions. See test_assert.vim for an example.
@@ -19,6 +24,10 @@
"
" If cleanup after each Test_ function is needed, define a TearDown function.
" It will be called after each Test_ function.
+"
+" When debugging a test it can be useful to add messages to v:errors:
+" call add(v:errors, "this happened")
+
" Check that the screen size is at least 24 x 80 characters.
if &lines < 24 || &columns < 80
@@ -30,8 +39,20 @@ if &lines < 24 || &columns < 80
cquit
endif
+" Common with all tests on all systems.
+source setup.vim
+
+" For consistency run all tests with 'nocompatible' set.
" This also enables use of line continuation.
-set viminfo+=nviminfo
+set nocp viminfo+=nviminfo
+
+" Use utf-8 or latin1 by default, instead of whatever the system default
+" happens to be. Individual tests can overrule this at the top of the file.
+if has('multi_byte')
+ set encoding=utf-8
+else
+ set encoding=latin1
+endif
" Avoid stopping at the "hit enter" prompt
set nomore
@@ -40,91 +61,248 @@ set nomore
lang mess C
" Always use forward slashes.
-set shellslash
+" set shellslash
+
+" Prepare for calling test_garbagecollect_now().
+let v:testing = 1
+
+" Support function: get the alloc ID by name.
+func GetAllocId(name)
+ exe 'split ' . s:srcdir . '/alloc.h'
+ let top = search('typedef enum')
+ if top == 0
+ call add(v:errors, 'typedef not found in alloc.h')
+ endif
+ let lnum = search('aid_' . a:name . ',')
+ if lnum == 0
+ call add(v:errors, 'Alloc ID ' . a:name . ' not defined')
+ endif
+ close
+ return lnum - top - 1
+endfunc
+
+func CanRunVimInTerminal()
+ " Nvim: always false, we use Lua screen-tests instead.
+ return 0
+endfunc
+
+func RunTheTest(test)
+ echo 'Executing ' . a:test
+
+ " Avoid stopping at the "hit enter" prompt
+ set nomore
+
+ " Avoid a three second wait when a message is about to be overwritten by the
+ " mode message.
+ set noshowmode
+
+ " Some tests wipe out buffers. To be consistent, always wipe out all
+ " buffers.
+ %bwipe!
+
+ " The test may change the current directory. Save and restore the
+ " directory after executing the test.
+ let save_cwd = getcwd()
+
+ if exists("*SetUp")
+ try
+ call SetUp()
+ catch
+ call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
+ endtry
+ endif
+
+ call add(s:messages, 'Executing ' . a:test)
+ let s:done += 1
+
+ if a:test =~ 'Test_nocatch_'
+ " Function handles errors itself. This avoids skipping commands after the
+ " error.
+ exe 'call ' . a:test
+ else
+ try
+ exe 'call ' . a:test
+ catch /^\cskipped/
+ call add(s:messages, ' Skipped')
+ call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', ''))
+ catch
+ call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
+ endtry
+ endif
+
+ " In case 'insertmode' was set and something went wrong, make sure it is
+ " reset to avoid trouble with anything else.
+ set noinsertmode
+
+ if exists("*TearDown")
+ try
+ call TearDown()
+ catch
+ call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
+ endtry
+ endif
+
+ " Clear any autocommands
+ au!
+
+ " Close any extra tab pages and windows and make the current one not modified.
+ while tabpagenr('$') > 1
+ quit!
+ endwhile
+
+ while 1
+ let wincount = winnr('$')
+ if wincount == 1
+ break
+ endif
+ bwipe!
+ if wincount == winnr('$')
+ " Did not manage to close a window.
+ only!
+ break
+ endif
+ endwhile
+
+ exe 'cd ' . save_cwd
+endfunc
+
+func AfterTheTest()
+ if len(v:errors) > 0
+ let s:fail += 1
+ call add(s:errors, 'Found errors in ' . s:test . ':')
+ call extend(s:errors, v:errors)
+ let v:errors = []
+ endif
+endfunc
+
+" This function can be called by a test if it wants to abort testing.
+func FinishTesting()
+ call AfterTheTest()
+
+ " Don't write viminfo on exit.
+ set viminfo=
+
+ " Clean up files created by setup.vim
+ call delete('XfakeHOME', 'rf')
+
+ if s:fail == 0
+ " Success, create the .res file so that make knows it's done.
+ exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
+ write
+ endif
+
+ if len(s:errors) > 0
+ " Append errors to test.log
+ split test.log
+ call append(line('$'), '')
+ call append(line('$'), 'From ' . g:testname . ':')
+ call append(line('$'), s:errors)
+ write
+ endif
+
+ let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
+ echo message
+ call add(s:messages, message)
+ if s:fail > 0
+ let message = s:fail . ' FAILED:'
+ echo message
+ call add(s:messages, message)
+ call extend(s:messages, s:errors)
+ endif
+
+ " Add SKIPPED messages
+ call extend(s:messages, s:skipped)
+
+ " Append messages to the file "messages"
+ split messages
+ call append(line('$'), '')
+ call append(line('$'), 'From ' . g:testname . ':')
+ call append(line('$'), s:messages)
+ write
+
+ qall!
+endfunc
" Source the test script. First grab the file name, in case the script
-" navigates away.
-let testname = expand('%')
-let done = 0
-let fail = 0
-let errors = []
-let messages = []
-if expand('%') =~ 'test_viml.vim'
- " this test has intentional errors, don't use try/catch.
+" navigates away. g:testname can be used by the tests.
+let g:testname = expand('%')
+let s:done = 0
+let s:fail = 0
+let s:errors = []
+let s:messages = []
+let s:skipped = []
+if expand('%') =~ 'test_vimscript.vim'
+ " this test has intentional s:errors, don't use try/catch.
source %
else
try
source %
catch
- let fail += 1
- call add(errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
+ let s:fail += 1
+ call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
endtry
endif
+" Names of flaky tests.
+let s:flaky = [
+ \ 'Test_exit_callback_interval()',
+ \ 'Test_oneshot()',
+ \ 'Test_out_cb()',
+ \ 'Test_paused()',
+ \ 'Test_popup_and_window_resize()',
+ \ 'Test_quoteplus()',
+ \ 'Test_quotestar()',
+ \ 'Test_reltime()',
+ \ 'Test_repeat_three()',
+ \ 'Test_terminal_composing_unicode()',
+ \ 'Test_terminal_redir_file()',
+ \ 'Test_terminal_tmap()',
+ \ 'Test_with_partial_callback()',
+ \ 'Test_lambda_with_timer()',
+ \ ]
+
" Locate Test_ functions and execute them.
-set nomore
redir @q
silent function /^Test_
redir END
-let tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
+let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
+
+" If there is an extra argument filter the function names against it.
+if argc() > 1
+ let s:tests = filter(s:tests, 'v:val =~ argv(1)')
+endif
" Execute the tests in alphabetical order.
-for test in sort(tests)
- echo 'Executing ' . test
- if exists("*SetUp")
- call SetUp()
- endif
+for s:test in sort(s:tests)
+ " Silence, please!
+ set belloff=all
- call add(messages, 'Executing ' . test)
- let done += 1
- try
- exe 'call ' . test
- catch
- let fail += 1
- call add(v:errors, 'Caught exception in ' . test . ': ' . v:exception . ' @ ' . v:throwpoint)
- endtry
+ call RunTheTest(s:test)
+
+ if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
+ call add(s:messages, 'Found errors in ' . s:test . ':')
+ call extend(s:messages, v:errors)
+ call add(s:messages, 'Flaky test failed, running it again')
+ let first_run = v:errors
+
+ " Flakiness is often caused by the system being very busy. Sleep a couple
+ " of seconds to have a higher chance of succeeding the second time.
+ sleep 2
- if len(v:errors) > 0
- let fail += 1
- call add(errors, 'Found errors in ' . test . ':')
- call extend(errors, v:errors)
let v:errors = []
+ call RunTheTest(s:test)
+ if len(v:errors) > 0
+ let second_run = v:errors
+ let v:errors = ['First run:']
+ call extend(v:errors, first_run)
+ call add(v:errors, 'Second run:')
+ call extend(v:errors, second_run)
+ endif
endif
- if exists("*TearDown")
- call TearDown()
- endif
+ call AfterTheTest()
endfor
-if fail == 0
- " Success, create the .res file so that make knows it's done.
- exe 'split ' . fnamemodify(testname, ':r') . '.res'
- write
-endif
-
-if len(errors) > 0
- " Append errors to test.log
- split test.log
- call append(line('$'), '')
- call append(line('$'), 'From ' . testname . ':')
- call append(line('$'), errors)
- write
-endif
-
-let message = 'Executed ' . done . (done > 1 ? ' tests': ' test')
-echo message
-call add(messages, message)
-if fail > 0
- let message = fail . ' FAILED'
- echo message
- call add(messages, message)
-endif
-
-" Append messages to "messages"
-split messages
-call append(line('$'), '')
-call append(line('$'), 'From ' . testname . ':')
-call append(line('$'), messages)
-write
+call FinishTesting()
-qall!
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/samples/memfile_test.c b/src/nvim/testdir/samples/memfile_test.c
new file mode 100644
index 0000000000..3c8f108255
--- /dev/null
+++ b/src/nvim/testdir/samples/memfile_test.c
@@ -0,0 +1,146 @@
+// 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
+
+/* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * memfile_test.c: Unittests for memfile.c
+ * Mostly by Ivan Krasilnikov.
+ */
+
+#undef NDEBUG
+#include <assert.h>
+
+/* Must include main.c because it contains much more than just main() */
+#define NO_VIM_MAIN
+#include "main.c"
+
+/* This file has to be included because the tested functions are static */
+#include "memfile.c"
+
+#define index_to_key(i) ((i) ^ 15167)
+#define TEST_COUNT 50000
+
+/*
+ * Test mf_hash_*() functions.
+ */
+ static void
+test_mf_hash(void)
+{
+ mf_hashtab_T ht;
+ mf_hashitem_T *item;
+ blocknr_T key;
+ long_u i;
+ long_u num_buckets;
+
+ mf_hash_init(&ht);
+
+ /* insert some items and check invariants */
+ for (i = 0; i < TEST_COUNT; i++)
+ {
+ assert(ht.mht_count == i);
+
+ /* check that number of buckets is a power of 2 */
+ num_buckets = ht.mht_mask + 1;
+ assert(num_buckets > 0 && (num_buckets & (num_buckets - 1)) == 0);
+
+ /* check load factor */
+ assert(ht.mht_count <= (num_buckets << MHT_LOG_LOAD_FACTOR));
+
+ if (i < (MHT_INIT_SIZE << MHT_LOG_LOAD_FACTOR))
+ {
+ /* first expansion shouldn't have occurred yet */
+ assert(num_buckets == MHT_INIT_SIZE);
+ assert(ht.mht_buckets == ht.mht_small_buckets);
+ }
+ else
+ {
+ assert(num_buckets > MHT_INIT_SIZE);
+ assert(ht.mht_buckets != ht.mht_small_buckets);
+ }
+
+ key = index_to_key(i);
+ assert(mf_hash_find(&ht, key) == NULL);
+
+ /* allocate and add new item */
+ item = (mf_hashitem_T *)lalloc_clear(sizeof(mf_hashtab_T), FALSE);
+ assert(item != NULL);
+ item->mhi_key = key;
+ mf_hash_add_item(&ht, item);
+
+ assert(mf_hash_find(&ht, key) == item);
+
+ if (ht.mht_mask + 1 != num_buckets)
+ {
+ /* hash table was expanded */
+ assert(ht.mht_mask + 1 == num_buckets * MHT_GROWTH_FACTOR);
+ assert(i + 1 == (num_buckets << MHT_LOG_LOAD_FACTOR));
+ }
+ }
+
+ /* check presence of inserted items */
+ for (i = 0; i < TEST_COUNT; i++)
+ {
+ key = index_to_key(i);
+ item = mf_hash_find(&ht, key);
+ assert(item != NULL);
+ assert(item->mhi_key == key);
+ }
+
+ /* delete some items */
+ for (i = 0; i < TEST_COUNT; i++)
+ {
+ if (i % 100 < 70)
+ {
+ key = index_to_key(i);
+ item = mf_hash_find(&ht, key);
+ assert(item != NULL);
+ assert(item->mhi_key == key);
+
+ mf_hash_rem_item(&ht, item);
+ assert(mf_hash_find(&ht, key) == NULL);
+
+ mf_hash_add_item(&ht, item);
+ assert(mf_hash_find(&ht, key) == item);
+
+ mf_hash_rem_item(&ht, item);
+ assert(mf_hash_find(&ht, key) == NULL);
+
+ vim_free(item);
+ }
+ }
+
+ /* check again */
+ for (i = 0; i < TEST_COUNT; i++)
+ {
+ key = index_to_key(i);
+ item = mf_hash_find(&ht, key);
+
+ if (i % 100 < 70)
+ {
+ assert(item == NULL);
+ }
+ else
+ {
+ assert(item != NULL);
+ assert(item->mhi_key == key);
+ }
+ }
+
+ /* free hash table and all remaining items */
+ mf_hash_free_all(&ht);
+}
+
+ int
+main(void)
+{
+ test_mf_hash();
+ return 0;
+}
diff --git a/src/nvim/testdir/samples/quickfix.txt b/src/nvim/testdir/samples/quickfix.txt
new file mode 100644
index 0000000000..2de3835473
--- /dev/null
+++ b/src/nvim/testdir/samples/quickfix.txt
@@ -0,0 +1,4 @@
+samples/quickfix.txt:1:1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+samples/quickfix.txt:2:1:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+samples/quickfix.txt:3:1:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+samples/quickfix.txt:4:1:dddddddddd
diff --git a/src/nvim/testdir/sautest/autoload/foo.vim b/src/nvim/testdir/sautest/autoload/foo.vim
new file mode 100644
index 0000000000..d7dcd5ce3d
--- /dev/null
+++ b/src/nvim/testdir/sautest/autoload/foo.vim
@@ -0,0 +1,7 @@
+let g:loaded_foo_vim += 1
+
+let foo#bar = {}
+
+func foo#bar.echo()
+ let g:called_foo_bar_echo += 1
+endfunc
diff --git a/src/nvim/testdir/sautest/autoload/footest.vim b/src/nvim/testdir/sautest/autoload/footest.vim
index f467bc376d..1e78963a10 100644
--- a/src/nvim/testdir/sautest/autoload/footest.vim
+++ b/src/nvim/testdir/sautest/autoload/footest.vim
@@ -1,4 +1,4 @@
-" Autoload script used by test55 and test60
+" Autoload script used by test_listdict.vim, test_exists.vim and test_let.vim
let footest#x = 1
func footest#F()
return 0
diff --git a/src/nvim/testdir/sautest/autoload/globone.vim b/src/nvim/testdir/sautest/autoload/globone.vim
new file mode 100644
index 0000000000..98c9a10582
--- /dev/null
+++ b/src/nvim/testdir/sautest/autoload/globone.vim
@@ -0,0 +1 @@
+" used by Test_globpath()
diff --git a/src/nvim/testdir/sautest/autoload/globtwo.vim b/src/nvim/testdir/sautest/autoload/globtwo.vim
new file mode 100644
index 0000000000..98c9a10582
--- /dev/null
+++ b/src/nvim/testdir/sautest/autoload/globtwo.vim
@@ -0,0 +1 @@
+" used by Test_globpath()
diff --git a/src/nvim/testdir/sautest/autoload/sourced.vim b/src/nvim/testdir/sautest/autoload/sourced.vim
new file mode 100644
index 0000000000..f69f00cb53
--- /dev/null
+++ b/src/nvim/testdir/sautest/autoload/sourced.vim
@@ -0,0 +1,3 @@
+let g:loaded_sourced_vim += 1
+func! sourced#something()
+endfunc
diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim
new file mode 100644
index 0000000000..c7c3b378cc
--- /dev/null
+++ b/src/nvim/testdir/setup.vim
@@ -0,0 +1,40 @@
+" Common preparations for running tests.
+
+" Only load this once.
+if exists('s:did_load')
+ finish
+endif
+let s:did_load = 1
+
+" Align Nvim defaults to Vim.
+set sidescroll=0
+set directory^=.
+set undodir^=.
+set backspace=
+set nrformats+=octal
+set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd
+set listchars=eol:$
+set fillchars=vert:\|,fold:-
+set shortmess-=F
+" Prevent Nvim log from writing to stderr.
+let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log'
+
+
+" Make sure 'runtimepath' and 'packpath' does not include $HOME.
+set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after
+let &packpath = &rtp
+
+" Make sure $HOME does not get read or written.
+let $HOME = expand(getcwd() . '/XfakeHOME')
+if !isdirectory($HOME)
+ call mkdir($HOME)
+endif
+
+" Use default shell on Windows to avoid segfault, caused by TUI
+if has('win32')
+ let $SHELL = ''
+ let $TERM = ''
+ let &shell = empty($COMSPEC) ? exepath('cmd.exe') : $COMSPEC
+ set shellcmdflag=/s/c shellxquote=\" shellredir=>%s\ 2>&1
+ let &shellpipe = &shellredir
+endif
diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim
new file mode 100644
index 0000000000..eb6798f353
--- /dev/null
+++ b/src/nvim/testdir/shared.vim
@@ -0,0 +1,248 @@
+" Functions shared by several tests.
+
+" Only load this script once.
+if exists('*WaitFor')
+ finish
+endif
+
+" {Nvim}
+" Filepath captured from output may be truncated, like this:
+" /home/va...estdir/Xtest-tmpdir/nvimxbXN4i/10
+" Get last 2 segments, then combine with $TMPDIR.
+func! Fix_truncated_tmpfile(fname)
+ " sanity check
+ if $TMPDIR ==# ''
+ throw '$TMPDIR is empty'
+ endif
+ let tmpdir_tail = fnamemodify(substitute($TMPDIR, '[\/]\+$', '', 'g'), ':t')
+ if tmpdir_tail ==# ''
+ throw 'empty tmpdir_tail'
+ endif
+ if a:fname !~# tmpdir_tail
+ throw printf('$TMPDIR (%s) not in fname: %s', tmpdir_tail, a:fname)
+ endif
+ let last2segments = matchstr(a:fname, '[\/][^\/]\+[\/][^\/]\+$')
+ return $TMPDIR.last2segments
+endfunc
+
+" Get the name of the Python executable.
+" Also keeps it in s:python.
+func PythonProg()
+ " This test requires the Python command to run the test server.
+ " This most likely only works on Unix and Windows.
+ if has('unix')
+ " We also need the job feature or the pkill command to make sure the server
+ " can be stopped.
+ if !(executable('python') && (has('job') || executable('pkill')))
+ return ''
+ endif
+ let s:python = 'python'
+ elseif has('win32')
+ " Use Python Launcher for Windows (py.exe) if available.
+ if executable('py.exe')
+ let s:python = 'py.exe'
+ elseif executable('python.exe')
+ let s:python = 'python.exe'
+ else
+ return ''
+ endif
+ else
+ return ''
+ endif
+ return s:python
+endfunc
+
+" Run "cmd". Returns the job if using a job.
+func RunCommand(cmd)
+ let job = 0
+ if has('job')
+ let job = job_start(a:cmd, {"stoponexit": "hup"})
+ call job_setoptions(job, {"stoponexit": "kill"})
+ elseif has('win32')
+ exe 'silent !start cmd /c start "test_channel" ' . a:cmd
+ else
+ exe 'silent !' . a:cmd . '&'
+ endif
+ return job
+endfunc
+
+" Read the port number from the Xportnr file.
+func GetPort()
+ let l = []
+ for i in range(200)
+ try
+ let l = readfile("Xportnr")
+ catch
+ endtry
+ if len(l) >= 1
+ break
+ endif
+ sleep 10m
+ endfor
+ call delete("Xportnr")
+
+ if len(l) == 0
+ " Can't make the connection, give up.
+ return 0
+ endif
+ return l[0]
+endfunc
+
+" Run a Python server for "cmd" and call "testfunc".
+" Always kills the server before returning.
+func RunServer(cmd, testfunc, args)
+ " The Python program writes the port number in Xportnr.
+ call delete("Xportnr")
+
+ if len(a:args) == 1
+ let arg = ' ' . a:args[0]
+ else
+ let arg = ''
+ endif
+ let pycmd = s:python . " " . a:cmd . arg
+
+ try
+ let g:currentJob = RunCommand(pycmd)
+
+ " Wait for up to 2 seconds for the port number to be there.
+ let port = GetPort()
+ if port == 0
+ call assert_false(1, "Can't start " . a:cmd)
+ return
+ endif
+
+ call call(function(a:testfunc), [port])
+ catch
+ call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint)
+ finally
+ call s:kill_server(a:cmd)
+ endtry
+endfunc
+
+func s:kill_server(cmd)
+ if has('job')
+ if exists('g:currentJob')
+ call job_stop(g:currentJob)
+ unlet g:currentJob
+ endif
+ elseif has('win32')
+ let cmd = substitute(a:cmd, ".py", '', '')
+ call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . cmd . '"')
+ else
+ call system("pkill -f " . a:cmd)
+ endif
+endfunc
+
+" Wait for up to a second for "expr" to become true.
+" Return time slept in milliseconds. With the +reltime feature this can be
+" more than the actual waiting time. Without +reltime it can also be less.
+func WaitFor(expr, ...)
+ let timeout = get(a:000, 0, 1000)
+ " using reltime() is more accurate, but not always available
+ if has('reltime')
+ let start = reltime()
+ else
+ let slept = 0
+ endif
+ for i in range(timeout / 10)
+ if eval(a:expr)
+ if has('reltime')
+ return float2nr(reltimefloat(reltime(start)) * 1000)
+ endif
+ return slept
+ endif
+ if !has('reltime')
+ let slept += 10
+ endif
+ sleep 10m
+ endfor
+ return timeout
+endfunc
+
+" Wait for up to a given milliseconds.
+" With the +timers feature this waits for key-input by getchar(), Resume()
+" feeds key-input and resumes process. Return time waited in milliseconds.
+" Without +timers it uses simply :sleep.
+func Standby(msec)
+ if has('timers')
+ let start = reltime()
+ let g:_standby_timer = timer_start(a:msec, function('s:feedkeys'))
+ call getchar()
+ return float2nr(reltimefloat(reltime(start)) * 1000)
+ else
+ execute 'sleep ' a:msec . 'm'
+ return a:msec
+ endif
+endfunc
+
+func Resume()
+ if exists('g:_standby_timer')
+ call timer_stop(g:_standby_timer)
+ call s:feedkeys(0)
+ unlet g:_standby_timer
+ endif
+endfunc
+
+func s:feedkeys(timer)
+ call feedkeys('x', 'nt')
+endfunc
+
+" Get the command to run Vim, with -u NONE and --headless arguments.
+" Returns an empty string on error.
+func GetVimCommand()
+ let cmd = v:progpath
+ let cmd = substitute(cmd, '-u \f\+', '-u NONE', '')
+ if cmd !~ '-u NONE'
+ let cmd = cmd . ' -u NONE'
+ endif
+ let cmd .= ' --headless -i NONE'
+ let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '')
+ return cmd
+endfunc
+
+" Run Vim, using the "vimcmd" file and "-u NORC".
+" "before" is a list of Vim commands to be executed before loading plugins.
+" "after" is a list of Vim commands to be executed after loading plugins.
+" Plugins are not loaded, unless 'loadplugins' is set in "before".
+" Return 1 if Vim could be executed.
+func RunVim(before, after, arguments)
+ return RunVimPiped(a:before, a:after, a:arguments, '')
+endfunc
+
+func RunVimPiped(before, after, arguments, pipecmd)
+ let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log'
+ let cmd = GetVimCommand()
+ if cmd == ''
+ return 0
+ endif
+ let args = ''
+ if len(a:before) > 0
+ call writefile(a:before, 'Xbefore.vim')
+ let args .= ' --cmd "so Xbefore.vim"'
+ endif
+ if len(a:after) > 0
+ call writefile(a:after, 'Xafter.vim')
+ let args .= ' -S Xafter.vim'
+ endif
+
+ exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments
+
+ if len(a:before) > 0
+ call delete('Xbefore.vim')
+ endif
+ if len(a:after) > 0
+ call delete('Xafter.vim')
+ endif
+ return 1
+endfunc
+
+" Get line "lnum" as displayed on the screen.
+" Trailing white space is trimmed.
+func! Screenline(lnum)
+ let chars = []
+ for c in range(1, winwidth(0))
+ call add(chars, nr2char(screenchar(a:lnum, c)))
+ endfor
+ let line = join(chars, '')
+ return matchstr(line, '^.\{-}\ze\s*$')
+endfunc
diff --git a/src/nvim/testdir/test12.in b/src/nvim/testdir/test12.in
deleted file mode 100644
index 0c0623e5d4..0000000000
--- a/src/nvim/testdir/test12.in
+++ /dev/null
@@ -1,50 +0,0 @@
-Tests for 'directory' option.
-- ".", in same dir as file
-- "./dir", in directory relative to file
-- "dir", in directory relative to current dir
-
-STARTTEST
-:set dir=.,~
-:/start of testfile/,/end of testfile/w! Xtest1
-:" do an ls of the current dir to find the swap file (should not be there)
-:if has("unix")
-: !ls .X*.swp >test.out
-:else
-: r !ls X*.swp >test.out
-:endif
-:!echo first line >>test.out
-:e Xtest1
-:if has("unix")
-:" Do an ls of the current dir to find the swap file, remove the leading dot
-:" to make the result the same for all systems.
-: r!ls .X*.swp
-: s/\.*X/X/
-: .w >>test.out
-: undo
-:else
-: !ls X*.swp >>test.out
-:endif
-:!echo under Xtest1.swp >>test.out
-:!mkdir Xtest2
-:set dir=./Xtest2,.,~
-:e Xtest1
-:!ls X*.swp >>test.out
-:!echo under under >>test.out
-:!ls Xtest2 >>test.out
-:!echo under Xtest1.swp >>test.out
-:!mkdir Xtest.je
-:/start of testfile/,/end of testfile/w! Xtest2/Xtest3
-:set dir=Xtest.je,~
-:e Xtest2/Xtest3
-:swap
-:!ls Xtest2 >>test.out
-:!echo under Xtest3 >>test.out
-:!ls Xtest.je >>test.out
-:!echo under Xtest3.swp >>test.out
-:qa!
-ENDTEST
-
-start of testfile
-line 2 Abcdefghij
-line 3 Abcdefghij
-end of testfile
diff --git a/src/nvim/testdir/test12.ok b/src/nvim/testdir/test12.ok
deleted file mode 100644
index 605623b117..0000000000
--- a/src/nvim/testdir/test12.ok
+++ /dev/null
@@ -1,10 +0,0 @@
-first line
-Xtest1.swp
-under Xtest1.swp
-under under
-Xtest1.swp
-under Xtest1.swp
-Xtest3
-under Xtest3
-Xtest3.swp
-under Xtest3.swp
diff --git a/src/nvim/testdir/test13.in b/src/nvim/testdir/test13.in
deleted file mode 100644
index fa9ba312b7..0000000000
--- a/src/nvim/testdir/test13.in
+++ /dev/null
@@ -1,63 +0,0 @@
-Tests for autocommands on :close command
-
-Write three files and open them, each in a window.
-Then go to next window, with autocommand that deletes the previous one.
-Do this twice, writing the file.
-
-Also test deleting the buffer on a Unload event. If this goes wrong there
-will be the ATTENTION prompt.
-
-Also test changing buffers in a BufDel autocommand. If this goes wrong there
-are ml_line errors and/or a Crash.
-
-STARTTEST
-:/^start of testfile/,/^end of testfile/w! Xtestje1
-:/^start of testfile/,/^end of testfile/w! Xtestje2
-:/^start of testfile/,/^end of testfile/w! Xtestje3
-:e Xtestje1
-otestje1
-:w
-:sp Xtestje2
-otestje2
-:w
-:sp Xtestje3
-otestje3
-:w
-
-:au WinLeave Xtestje2 bwipe
-
-:w! test.out
-:au WinLeave Xtestje1 bwipe Xtestje3
-:close
-:w >>test.out
-:e Xtestje1
-:bwipe Xtestje2 Xtestje3 test.out
-:au!
-:au! BufUnload Xtestje1 bwipe
-:e Xtestje3
-:w >>test.out
-:e Xtestje2
-:sp Xtestje1
-:e
-:w >>test.out
-:au!
-:only
-:e Xtestje1
-:bwipe Xtestje2 Xtestje3 test.out test13.in
-:au BufWipeout Xtestje1 buf Xtestje1
-:bwipe
-:w >>test.out
-:only
-:new|set buftype=help
-:wincmd w
-:1quit
-:$put ='Final line'
-:$w >>test.out
-:qa!
-ENDTEST
-
-start of testfile
- contents
- contents
- contents
-end of testfile
diff --git a/src/nvim/testdir/test13.ok b/src/nvim/testdir/test13.ok
deleted file mode 100644
index 66ebce63f7..0000000000
--- a/src/nvim/testdir/test13.ok
+++ /dev/null
@@ -1,31 +0,0 @@
-start of testfile
-testje1
- contents
- contents
- contents
-end of testfile
-start of testfile
-testje1
- contents
- contents
- contents
-end of testfile
-start of testfile
-testje3
- contents
- contents
- contents
-end of testfile
-start of testfile
-testje2
- contents
- contents
- contents
-end of testfile
-start of testfile
-testje1
- contents
- contents
- contents
-end of testfile
-Final line
diff --git a/src/nvim/testdir/test17.in b/src/nvim/testdir/test17.in
index 83abe17770..1a4ac6b6d1 100644
--- a/src/nvim/testdir/test17.in
+++ b/src/nvim/testdir/test17.in
@@ -4,13 +4,7 @@ Tests for:
STARTTEST
:set isfname=@,48-57,/,.,-,_,+,,,$,:,~,{,}
-:function! DeleteDirectory(dir)
-: if has("win16") || has("win32") || has("win64") || has("dos16") || has("dos32")
-: exec "silent !rmdir /Q /S " . a:dir
-: else
-: exec "silent !rm -rf " . a:dir
-: endif
-:endfun
+:"
:if has("unix")
:let $CDIR = "."
/CDIR
@@ -36,7 +30,7 @@ STARTTEST
:" check for 'include' without \zs or \ze
:lang C
:call delete("./Xbase.a")
-:call DeleteDirectory("Xdir1")
+:call delete("Xdir1", "rf")
:!mkdir Xdir1
:!mkdir "Xdir1/dir2"
:e! Xdir1/dir2/foo.a
@@ -61,7 +55,7 @@ ENDTEST
STARTTEST
:" check for 'include' with \zs and \ze
:call delete("./Xbase.b")
-:call DeleteDirectory("Xdir1")
+:call delete("Xdir1", "rf")
:!mkdir Xdir1
:!mkdir "Xdir1/dir2"
:let &include='^\s*%inc\s*/\zs[^/]\+\ze'
@@ -91,7 +85,7 @@ ENDTEST
STARTTEST
:" check for 'include' with \zs and no \ze
:call delete("./Xbase.c")
-:call DeleteDirectory("Xdir1")
+:call delete("Xdir1", "rf")
:!mkdir Xdir1
:!mkdir "Xdir1/dir2"
:let &include='^\s*%inc\s*\%([[:upper:]][^[:space:]]*\s\+\)\?\zs\S\+\ze'
diff --git a/src/nvim/testdir/test24.in b/src/nvim/testdir/test24.in
deleted file mode 100644
index 292f403048..0000000000
--- a/src/nvim/testdir/test24.in
+++ /dev/null
Binary files differ
diff --git a/src/nvim/testdir/test24.ok b/src/nvim/testdir/test24.ok
deleted file mode 100644
index cd61210968..0000000000
--- a/src/nvim/testdir/test24.ok
+++ /dev/null
@@ -1,32 +0,0 @@
-start
-test text test text
-test text test text
-test text test text
-test text test text
-test text test text
-test text test text
-test text test text x61
-test text test text x60-x64
-test text test text x78 5
-test text test text o143
-test text test text o140-o144
-test text test text o41 7
-test text test text \%x42
-test text test text \%o103
-test text test text [\x00]
-test text test text [\x00-\x10]
-test text test text [\x-z]
-test text test text [\u-z]
-xx xx a
-xx aaaaa xx a
-xx aaaaa xx a
-xx Aaa xx
-xx Aaaa xx
-xx Aaa xx
-xx foobar xA xx
-xx an A xx
-XX 9;
-YY 77;
- xyz
- bcd
- BB
diff --git a/src/nvim/testdir/test30.in b/src/nvim/testdir/test30.in
deleted file mode 100644
index 56d5d5c6c2..0000000000
--- a/src/nvim/testdir/test30.in
+++ /dev/null
@@ -1,230 +0,0 @@
-Test for a lot of variations of the 'fileformats' option
-
-Note: This test will fail if "cat" is not available.
-
-STARTTEST
-:" first write three test files, one in each format
-:set fileformat=unix
-:set fileformats=
-:/^unix/;/eof/-1w! XXUnix
-:/^dos/;/eof/-1w! XXDos
-:set bin noeol
-:$w! XXMac
-Gonoeol
-:$w! XXEol
-:set nobin eol
-:enew!
-:bwipe XXUnix XXDos XXMac
-:" create mixed format files
-:if has("win32")
-: !copy /b XXUnix+XXDos XXUxDs
-: !copy /b XXUnix+XXMac XXUxMac
-: !copy /b XXDos+XXMac XXDosMac
-: !copy /b XXMac+XXEol XXMacEol
-: !copy /b XXUnix+XXDos+XXMac XXUxDsMc
-:else
-: !cat XXUnix XXDos >XXUxDs
-: !cat XXUnix XXMac >XXUxMac
-: !cat XXDos XXMac >XXDosMac
-: !cat XXMac XXEol >XXMacEol
-: !cat XXUnix XXDos XXMac >XXUxDsMc
-:endif
-:"
-:" try reading and writing with 'fileformats' empty
-:set fileformat=unix
-:e! XXUnix
-:w! test.out
-:e! XXDos
-:w! XXtt01
-:e! XXMac
-:w! XXtt02
-:bwipe XXUnix XXDos XXMac
-:set fileformat=dos
-:e! XXUnix
-:w! XXtt11
-:e! XXDos
-:w! XXtt12
-:e! XXMac
-:w! XXtt13
-:bwipe XXUnix XXDos XXMac
-:set fileformat=mac
-:e! XXUnix
-:w! XXtt21
-:e! XXDos
-:w! XXtt22
-:e! XXMac
-:w! XXtt23
-:bwipe XXUnix XXDos XXMac
-:"
-:" try reading and writing with 'fileformats' set to one format
-:set fileformats=unix
-:e! XXUxDsMc
-:w! XXtt31
-:bwipe XXUxDsMc
-:set fileformats=dos
-:e! XXUxDsMc
-:w! XXtt32
-:bwipe XXUxDsMc
-:set fileformats=mac
-:e! XXUxDsMc
-:w! XXtt33
-:bwipe XXUxDsMc
-:"
-:" try reading and writing with 'fileformats' set to two formats
-:set fileformats=unix,dos
-:e! XXUxDsMc
-:w! XXtt41
-:bwipe XXUxDsMc
-:e! XXUxMac
-:w! XXtt42
-:bwipe XXUxMac
-:e! XXDosMac
-:w! XXtt43
-:bwipe XXDosMac
-:set fileformats=unix,mac
-:e! XXUxDs
-:w! XXtt51
-:bwipe XXUxDs
-:e! XXUxDsMc
-:w! XXtt52
-:bwipe XXUxDsMc
-:e! XXDosMac
-:w! XXtt53
-:bwipe XXDosMac
-:e! XXEol
-ggO=&ffs
-:=&ff
-:w! XXtt54
-:bwipe XXEol
-:set fileformats=dos,mac
-:e! XXUxDs
-:w! XXtt61
-:bwipe XXUxDs
-:e! XXUxMac
-ggO=&ffs
-:=&ff
-:w! XXtt62
-:bwipe XXUxMac
-:e! XXUxDsMc
-:w! XXtt63
-:bwipe XXUxDsMc
-:e! XXMacEol
-ggO=&ffs
-:=&ff
-:w! XXtt64
-:bwipe XXMacEol
-:"
-:" try reading and writing with 'fileformats' set to three formats
-:set fileformats=unix,dos,mac
-:e! XXUxDsMc
-:w! XXtt71
-:bwipe XXUxDsMc
-:e! XXEol
-ggO=&ffs
-:=&ff
-:w! XXtt72
-:bwipe XXEol
-:set fileformats=mac,dos,unix
-:e! XXUxDsMc
-:w! XXtt81
-:bwipe XXUxDsMc
-:e! XXEol
-ggO=&ffs
-:=&ff
-:w! XXtt82
-:bwipe XXEol
-:" try with 'binary' set
-:set fileformats=mac,unix,dos
-:set binary
-:e! XXUxDsMc
-:w! XXtt91
-:bwipe XXUxDsMc
-:set fileformats=mac
-:e! XXUxDsMc
-:w! XXtt92
-:bwipe XXUxDsMc
-:set fileformats=dos
-:e! XXUxDsMc
-:w! XXtt93
-:"
-:" Append "END" to each file so that we can see what the last written char was.
-:set fileformat=unix nobin
-ggdGaEND:w >>XXtt01
-:w >>XXtt02
-:w >>XXtt11
-:w >>XXtt12
-:w >>XXtt13
-:w >>XXtt21
-:w >>XXtt22
-:w >>XXtt23
-:w >>XXtt31
-:w >>XXtt32
-:w >>XXtt33
-:w >>XXtt41
-:w >>XXtt42
-:w >>XXtt43
-:w >>XXtt51
-:w >>XXtt52
-:w >>XXtt53
-:w >>XXtt54
-:w >>XXtt61
-:w >>XXtt62
-:w >>XXtt63
-:w >>XXtt64
-:w >>XXtt71
-:w >>XXtt72
-:w >>XXtt81
-:w >>XXtt82
-:w >>XXtt91
-:w >>XXtt92
-:w >>XXtt93
-:"
-:" Concatenate the results.
-:" Make fileformat of test.out the native fileformat.
-:" Add a newline at the end.
-:set binary
-:e! test.out
-:$r XXtt01
-:$r XXtt02
-Go1:$r XXtt11
-:$r XXtt12
-:$r XXtt13
-Go2:$r XXtt21
-:$r XXtt22
-:$r XXtt23
-Go3:$r XXtt31
-:$r XXtt32
-:$r XXtt33
-Go4:$r XXtt41
-:$r XXtt42
-:$r XXtt43
-Go5:$r XXtt51
-:$r XXtt52
-:$r XXtt53
-:$r XXtt54
-Go6:$r XXtt61
-:$r XXtt62
-:$r XXtt63
-:$r XXtt64
-Go7:$r XXtt71
-:$r XXtt72
-Go8:$r XXtt81
-:$r XXtt82
-Go9:$r XXtt91
-:$r XXtt92
-:$r XXtt93
-Go10:$r XXUnix
-:set nobinary ff&
-:w
-:qa!
-ENDTEST
-
-unix
-unix
-eof
-
-dos
-dos
-eof
-
-mac mac
diff --git a/src/nvim/testdir/test30.ok b/src/nvim/testdir/test30.ok
deleted file mode 100644
index b35f4f5904..0000000000
--- a/src/nvim/testdir/test30.ok
+++ /dev/null
@@ -1,130 +0,0 @@
-unix
-unix
-dos
-dos
-END
-mac mac
-END
-1
-unix
-unix
-END
-dos
-dos
-END
-mac mac
-END
-2
-unix
-unix
- END
-dos
-dos
- END
-mac mac END
-3
-unix
-unix
-dos
-dos
-mac mac
-END
-unix
-unix
-dos
-dos
-mac mac
-END
-unix
-unix
-dos
-dos
-mac mac END
-4
-unix
-unix
-dos
-dos
-mac mac
-END
-unix
-unix
-mac mac
-END
-dos
-dos
-mac mac
-END
-5
-unix
-unix
-dos
-dos
-END
-unix
-unix
-dos
-dos
-mac mac
-END
-dos
-dos
-mac mac END
-unix,mac:unix
-noeol
-END
-6
-unix
-unix
-dos
-dos
-END
-dos,mac:dos
-unix
-unix
-mac mac
-END
-unix
-unix
-dos
-dos
-mac mac
-END
-dos,mac:mac mac mac noeol END
-7
-unix
-unix
-dos
-dos
-mac mac
-END
-unix,dos,mac:unix
-noeol
-END
-8
-unix
-unix
-dos
-dos
-mac mac
-END
-mac,dos,unix:mac noeol END
-9
-unix
-unix
-dos
-dos
-mac mac END
-unix
-unix
-dos
-dos
-mac mac END
-unix
-unix
-dos
-dos
-mac mac END
-10
-unix
-unix
diff --git a/src/nvim/testdir/test32.in b/src/nvim/testdir/test32.in
deleted file mode 100644
index 76bd9be889..0000000000
--- a/src/nvim/testdir/test32.in
+++ /dev/null
@@ -1,60 +0,0 @@
-Test for insert expansion
-
-:se cpt=.,w
-* add-expands (word from next line) from other window
-* add-expands (current buffer first)
-* Local expansion, ends in an empty line (unless it becomes a global expansion)
-* starts Local and switches to global add-expansion
-:se cpt=.,w,i
-* i-add-expands and switches to local
-* add-expands lines (it would end in an empty line if it didn't ignored it self)
-:se cpt=kXtestfile
-* checks k-expansion, and file expansion (use Xtest11 instead of test11,
-* because TEST11.OUT may match first on DOS)
-:se cpt=w
-* checks make_cyclic in other window
-:se cpt=u nohid
-* checks unloaded buffer expansion
-* checks adding mode abortion
-:se cpt=t,d
-* tag expansion, define add-expansion interrupted
-* t-expansion
-
-STARTTEST
-:se backspace=""
-:se cpt=.,w ff=unix | $-2,$w!Xtestfile | set ff&
-:se cot=
-nO#include "Xtestfile"
-ru
-O
-
-
-:se cpt=.,w,i
-kOM
-  
-:se cpt=kXtestfile
-:w Xtest11.one
-:w Xtest11.two
-OIXA
-:" use CTRL-X CTRL-F to complete Xtest11.one, remove it and then use
-:" CTRL-X CTRL-F again to verify this doesn't cause trouble.
-OXddk
-:se cpt=w
-OST
-:se cpt=u nohid
-oOEN
-unl
-:se cpt=t,d def=^\\k* tags=Xtestfile notagbsearch
-O
-a
-:wq! test.out
-ENDTEST
-
-start of testfile
-run1
-run2
-end of testfile
-
-test11 36Gepeto /Tag/
-asd test11file 36G
-Makefile to run
diff --git a/src/nvim/testdir/test32.ok b/src/nvim/testdir/test32.ok
deleted file mode 100644
index afc4463fac..0000000000
--- a/src/nvim/testdir/test32.ok
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "Xtestfile"
-run1 run3
-run3 run3
-
-Makefile to run3
-Makefile to run3
-Makefile to run3
-Xtest11.two
-STARTTEST
-ENDTEST
-unless
-test11file 36Gepeto /Tag/ asd
-asd
-run1 run2
-
diff --git a/src/nvim/testdir/test40.in b/src/nvim/testdir/test40.in
deleted file mode 100644
index b0285709e5..0000000000
--- a/src/nvim/testdir/test40.in
+++ /dev/null
@@ -1,63 +0,0 @@
-Test for "*Cmd" autocommands
-
-STARTTEST
-:set wildchar=^E
-:/^start/,$w! Xxx " write lines below to Xxx
-:au BufReadCmd XtestA 0r Xxx|$del
-:e XtestA " will read text of Xxd instead
-:au BufWriteCmd XtestA call append(line("$"), "write")
-:w " will append a line to the file
-:r XtestA " should not read anything
-: " now we have:
-: " 1 start of Xxx
-: " 2 test40
-: " 3 end of Xxx
-: " 4 write
-:au FileReadCmd XtestB '[r Xxx
-:2r XtestB " will read Xxx below line 2 instead
-: " 1 start of Xxx
-: " 2 test40
-: " 3 start of Xxx
-: " 4 test40
-: " 5 end of Xxx
-: " 6 end of Xxx
-: " 7 write
-:au FileWriteCmd XtestC '[,']copy $
-4GA1
-:4,5w XtestC " will copy lines 4 and 5 to the end
-:r XtestC " should not read anything
-: " 1 start of Xxx
-: " 2 test40
-: " 3 start of Xxx
-: " 4 test401
-: " 5 end of Xxx
-: " 6 end of Xxx
-: " 7 write
-: " 8 test401
-: " 9 end of Xxx
-:au FILEAppendCmd XtestD '[,']w! test.out
-:w >>XtestD " will write all lines to test.out
-:$r XtestD " should not read anything
-:$w >>test.out " append "end of Xxx" to test.out
-:au BufReadCmd XtestE 0r test.out|$del
-:sp XtestE " split window with test.out
-5Goasdf:"
-:au BufWriteCmd XtestE w! test.out
-:wall " will write other window to test.out
-: " 1 start of Xxx
-: " 2 test40
-: " 3 start of Xxx
-: " 4 test401
-: " 5 end of Xxx
-: " 6 asdf
-: " 7 end of Xxx
-: " 8 write
-: " 9 test401
-: " 10 end of Xxx
-: " 11 end of Xxx
-:qa!
-ENDTEST
-
-start of Xxx
- test40
-end of Xxx
diff --git a/src/nvim/testdir/test40.ok b/src/nvim/testdir/test40.ok
deleted file mode 100644
index b6501394f9..0000000000
--- a/src/nvim/testdir/test40.ok
+++ /dev/null
@@ -1,11 +0,0 @@
-start of Xxx
- test40
-start of Xxx
- test401
-end of Xxx
-asdf
-end of Xxx
-write
- test401
-end of Xxx
-end of Xxx
diff --git a/src/nvim/testdir/test47.in b/src/nvim/testdir/test47.in
deleted file mode 100644
index c95c6a6850..0000000000
--- a/src/nvim/testdir/test47.in
+++ /dev/null
@@ -1,102 +0,0 @@
-Tests for vertical splits and filler lines in diff mode
-
-Also tests restoration of saved options by :diffoff.
-
-STARTTEST
-:" Disable the title to avoid xterm keeping the wrong one.
-:set notitle noicon
-/^1
-yG:new
-pkdd:w! Xtest
-ddGpkkrXoxxx:w! Xtest2
-:file Nop
-ggoyyyjjjozzzz
-:set foldmethod=marker foldcolumn=4
-:redir => nodiffsettings
-:silent! :set diff? fdm? fdc? scb? crb? wrap?
-:redir END
-:vert diffsplit Xtest
-:vert diffsplit Xtest2
-:redir => diffsettings
-:silent! :set diff? fdm? fdc? scb? crb? wrap?
-:redir END
-:let diff_fdm = &fdm
-:let diff_fdc = &fdc
-:" repeat entering diff mode here to see if this saves the wrong settings
-:diffthis
-:" jump to second window for a moment to have filler line appear at start of
-:" first window
-ggpgg:let one = winline()
-j:let one = one . "-" . winline()
-j:let one = one . "-" . winline()
-j:let one = one . "-" . winline()
-j:let one = one . "-" . winline()
-j:let one = one . "-" . winline()
-gg:let two = winline()
-j:let two = two . "-" . winline()
-j:let two = two . "-" . winline()
-j:let two = two . "-" . winline()
-j:let two = two . "-" . winline()
-gg:let three = winline()
-j:let three = three . "-" . winline()
-j:let three = three . "-" . winline()
-j:let three = three . "-" . winline()
-j:let three = three . "-" . winline()
-j:let three = three . "-" . winline()
-j:let three = three . "-" . winline()
-:call append("$", one)
-:call append("$", two)
-:call append("$", three)
-:$-2,$w! test.out
-:"
-:" Test diffoff
-:diffoff!
-1
-:let &diff = 1
-:let &fdm = diff_fdm
-:let &fdc = diff_fdc
-4
-:diffoff!
-:$put =nodiffsettings
-:$put =diffsettings
-1
-:redir => nd1
-:silent! :set diff? fdm? fdc? scb? crb? wrap?
-:redir END
-
-:redir => nd2
-:silent! :set diff? fdm? fdc? scb? crb? wrap?
-:redir END
-
-:redir => nd3
-:silent! :set diff? fdm? fdc? scb? crb? wrap?
-:redir END
-
-:$put =nd1
-:$put =nd2
-:$put =nd3
-:$-39,$w >> test.out
-:"
-:" Test that diffing shows correct filler lines
-:windo :bw!
-:enew
-:put =range(4,10)
-:1d _
-:vnew
-:put =range(1,10)
-:1d _
-:windo :diffthis
-:wincmd h
-:let w0=line('w0')
-:enew
-:put =w0
-:.w >> test.out
-:unlet! one two three nodiffsettings diffsettings diff_fdm diff_fdc nd1 nd2 nd3 w0
-:qa!
-ENDTEST
-
-1 aa
-2 bb
-3 cc
-4 dd
-5 ee
diff --git a/src/nvim/testdir/test47.ok b/src/nvim/testdir/test47.ok
deleted file mode 100644
index 83e96571ad..0000000000
--- a/src/nvim/testdir/test47.ok
+++ /dev/null
@@ -1,44 +0,0 @@
-2-4-5-6-8-9
-1-2-4-5-8
-2-3-4-5-6-7-8
-
-
-nodiff
- foldmethod=marker
- foldcolumn=4
-noscrollbind
-nocursorbind
- wrap
-
-
- diff
- foldmethod=diff
- foldcolumn=2
- scrollbind
- cursorbind
-nowrap
-
-
-nodiff
- foldmethod=marker
- foldcolumn=4
-noscrollbind
-nocursorbind
- wrap
-
-
-nodiff
- foldmethod=marker
- foldcolumn=4
-noscrollbind
-nocursorbind
- wrap
-
-
-nodiff
- foldmethod=marker
- foldcolumn=4
-noscrollbind
-nocursorbind
- wrap
-1
diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim
index edd49a2b63..467abcd9b9 100644
--- a/src/nvim/testdir/test49.vim
+++ b/src/nvim/testdir/test49.vim
@@ -456,7 +456,7 @@ function! ExtraVim(...)
" messing up the user's viminfo file.
let redirect = a:0 ?
\ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : ""
- exec "!echo '" . debug_quits . "q' | ../../../build/bin/nvim -u NONE -N -es" . redirect .
+ exec "!echo '" . debug_quits . "q' | $NVIM_PRG -u NONE -N -es" . redirect .
\ " -c 'debuggreedy|set viminfo+=nviminfo'" .
\ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
\ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
@@ -608,7 +608,7 @@ com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
-" Tests 1 to 15 were moved to test_viml.vim
+" Tests 1 to 15 were moved to test_vimscript.vim
let Xtest = 16
"-------------------------------------------------------------------------------
diff --git a/src/nvim/testdir/test53.in b/src/nvim/testdir/test53.in
deleted file mode 100644
index f3778c5192..0000000000
--- a/src/nvim/testdir/test53.in
+++ /dev/null
@@ -1,133 +0,0 @@
-Tests for string and html text objects. vim: set ft=vim :
-
-Note that the end-of-line moves the cursor to the next test line.
-
-Also test match() and matchstr()
-
-Also test the gn command and repeating it.
-
-STARTTEST
-/^start:/
-da"
-0va'a'rx
-02f`da`
-0fXdi"
-03f'vi'ry
-:set quoteescape=+*-
-di`
-$F"va"oha"i"rz
-:"
-/^<begin
-jfXdit
-0fXdit
-fXdat
-0fXdat
-dit
-:"
-:put =matchstr(\"abcd\", \".\", 0, 2) " b
-:put =matchstr(\"abcd\", \"..\", 0, 2) " bc
-:put =matchstr(\"abcd\", \".\", 2, 0) " c (zero and negative -> first match)
-:put =matchstr(\"abcd\", \".\", 0, -1) " a
-:put =match(\"abcd\", \".\", 0, 5) " -1
-:put =match(\"abcd\", \".\", 0, -1) " 0
-:put =match('abc', '.', 0, 1) " 0
-:put =match('abc', '.', 0, 2) " 1
-:put =match('abc', '.', 0, 3) " 2
-:put =match('abc', '.', 0, 4) " -1
-:put =match('abc', '.', 1, 1) " 1
-:put =match('abc', '.', 2, 1) " 2
-:put =match('abc', '.', 3, 1) " -1
-:put =match('abc', '$', 0, 1) " 3
-:put =match('abc', '$', 0, 2) " -1
-:put =match('abc', '$', 1, 1) " 3
-:put =match('abc', '$', 2, 1) " 3
-:put =match('abc', '$', 3, 1) " 3
-:put =match('abc', '$', 4, 1) " -1
-:put =match('abc', '\zs', 0, 1) " 0
-:put =match('abc', '\zs', 0, 2) " 1
-:put =match('abc', '\zs', 0, 3) " 2
-:put =match('abc', '\zs', 0, 4) " 3
-:put =match('abc', '\zs', 0, 5) " -1
-:put =match('abc', '\zs', 1, 1) " 1
-:put =match('abc', '\zs', 2, 1) " 2
-:put =match('abc', '\zs', 3, 1) " 3
-:put =match('abc', '\zs', 4, 1) " -1
-/^foobar
-gncsearchmatch/one\_s*two\_s
-:1
-gnd
-/[a]bcdx
-:1
-2gnd/join
-/$
-0gnd
-/\>\zs
-0gnd/^
-gnd$h/\zs
-gnd/[u]niquepattern/s
-vlgnd
-/mother
-:set selection=exclusive
-$cgNmongoose/i
-cgnj
-:" Make sure there is no other match y uppercase.
-/x59
-gggnd
-:" test repeating dgn
-/^Johnny
-ggdgn.
-:" test repeating gUgn
-/^Depp
-gggUgn.
-gg/a:0\@!\zs\d\+
-nygnop
-:/^start:/,/^end:/wq! test.out
-ENDTEST
-
-start: "wo\"rd\\" foo
-'foo' 'bar' 'piep'
-bla bla `quote` blah
-out " in "noXno"
-"'" 'blah' rep 'buh'
-bla `s*`d-`+++`l**` b`la
-voo "nah" sdf " asdf" sdf " sdf" sd
-
-<begin>
--<b>asdf<i>Xasdf</i>asdf</b>-
--<b>asdX<i>a<i />sdf</i>asdf</b>-
--<b>asdf<i>Xasdf</i>asdf</b>-
--<b>asdX<i>as<b />df</i>asdf</b>-
--<b>
-innertext object
-</b>
-</begin>
-SEARCH:
-foobar
-one
-two
-abcdx | abcdx | abcdx
-join
-lines
-zero width pattern
-delete first and last chars
-uniquepattern uniquepattern
-my very excellent mother just served us nachos
-for (i=0; i<=10; i++)
-a:10
-
-a:1
-
-a:20
-Y
-text
-Y
---1
-Johnny
---2
-Johnny
---3
-Depp
---4
-Depp
---5
-end:
diff --git a/src/nvim/testdir/test53.ok b/src/nvim/testdir/test53.ok
deleted file mode 100644
index 05206972a4..0000000000
--- a/src/nvim/testdir/test53.ok
+++ /dev/null
@@ -1,71 +0,0 @@
-start: foo
-xxxxxxxxxxxx'piep'
-bla bla blah
-out " in ""
-"'" 'blah'yyyyy'buh'
-bla `` b`la
-voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd
-
-<begin>
--<b>asdf<i></i>asdf</b>-
--<b></b>-
--<b>asdfasdf</b>-
---
--<b></b>
-</begin>
-b
-bc
-c
-a
--1
-0
-0
-1
-2
--1
-1
-2
--1
-3
--1
-3
-3
-3
--1
-0
-1
-2
-3
--1
-1
-2
-3
--1
-SEARCH:
-searchmatch
-abcdx | | abcdx
-join lines
-zerowidth pattern
-elete first and last char
- uniquepattern
-my very excellent mongoose just served us nachos
-for (j=0; i<=10; i++)
-a:10
-
-a:1
-1
-
-a:20
-
-text
-Y
---1
-
---2
-
---3
-DEPP
---4
-DEPP
---5
-end:
diff --git a/src/nvim/testdir/test64.in b/src/nvim/testdir/test64.in
index c4585ecbce..ec11e15e35 100644
--- a/src/nvim/testdir/test64.in
+++ b/src/nvim/testdir/test64.in
@@ -20,6 +20,7 @@ STARTTEST
:"""" Previously written tests """"""""""""""""""""""""""""""""
:""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
:"
+:set noautoindent
:call add(tl, [2, 'ab', 'aab', 'ab'])
:call add(tl, [2, 'b', 'abcdef', 'b'])
:call add(tl, [2, 'bc*', 'abccccdef', 'bcccc'])
@@ -577,7 +578,7 @@ Gop:"
:" Check patterns matching cursor position.
:func! Postest()
new
- call setline(1, ['ffooooo', 'boboooo', 'zoooooo', 'koooooo', 'moooooo', "\t\t\tfoo", 'abababababababfoo', 'bababababababafoo', '********_'])
+ call setline(1, ['ffooooo', 'boboooo', 'zoooooo', 'koooooo', 'moooooo', "\t\t\tfoo", 'abababababababfoo', 'bababababababafoo', '********_', ' xxxxxxxxxxxx xxxx xxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxx xxxxx xxxxxxx xx xxxx xxxxxxxx xxxx xxxxxxxxxxx xxx xxxxxxx xxxxxxxxx xx xxxxxx xx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxx xxxxxxxx xxxxxxxxx xxxx xxx xxxx xxx xxx xxxxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxxxxxxx xx xxxxx xxx xxxxxxxx xxxxxx xxx xxx xxxxxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxx xxx xxx xxxxxxxx xxxxxxx xxxx xxx xxxxxx xxxxx xxxxx xx xxxxxx xxxxxxx xxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxx xxxxxx xxxxx xxx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxx xxxx xx xxxxxxxx xxx xxxxxxxxxxx xxxxx'])
call setpos('.', [0, 1, 0, 0])
s/\%>3c.//g
call setpos('.', [0, 2, 4, 0])
@@ -589,6 +590,7 @@ Gop:"
%s/\%>6l\%3c./!/g
%s/\%>7l\%12c./?/g
%s/\%>7l\%<9l\%>5v\%<8v./#/g
+ $s/\%(|\u.*\)\@<=[^|\t]\+$//ge
1,$yank
quit!
endfunc
diff --git a/src/nvim/testdir/test64.ok b/src/nvim/testdir/test64.ok
index 92f06ea9f3..c218f8ea17 100644
--- a/src/nvim/testdir/test64.ok
+++ b/src/nvim/testdir/test64.ok
@@ -1076,6 +1076,7 @@ moooooo
ab!babababababfoo
ba!ab##abab?bafoo
**!*****_
+ ! xxx?xxxxxxxx xxxx xxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxx xxxxx xxxxxxx xx xxxx xxxxxxxx xxxx xxxxxxxxxxx xxx xxxxxxx xxxxxxxxx xx xxxxxx xx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxx xxxxxxxx xxxxxxxxx xxxx xxx xxxx xxx xxx xxxxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxxxxxxx xx xxxxx xxx xxxxxxxx xxxxxx xxx xxx xxxxxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxx xxx xxx xxxxxxxx xxxxxxx xxxx xxx xxxxxx xxxxx xxxxx xx xxxxxx xxxxxxx xxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxx xxxxxx xxxxx xxx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxx xxxx xx xxxxxxxx xxx xxxxxxxxxxx xxxxx
-1-
ffo
bob
@@ -1086,6 +1087,7 @@ moooooo
ab!babababababfoo
ba!ab##abab?bafoo
**!*****_
+ ! xxx?xxxxxxxx xxxx xxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxx xxxxx xxxxxxx xx xxxx xxxxxxxx xxxx xxxxxxxxxxx xxx xxxxxxx xxxxxxxxx xx xxxxxx xx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxx xxxxxxxx xxxxxxxxx xxxx xxx xxxx xxx xxx xxxxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxxxxxxx xx xxxxx xxx xxxxxxxx xxxxxx xxx xxx xxxxxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxx xxx xxx xxxxxxxx xxxxxxx xxxx xxx xxxxxx xxxxx xxxxx xx xxxxxx xxxxxxx xxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxx xxxxxx xxxxx xxx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxx xxxx xx xxxxxxxx xxx xxxxxxxxxxx xxxxx
-2-
ffo
bob
@@ -1096,6 +1098,7 @@ moooooo
ab!babababababfoo
ba!ab##abab?bafoo
**!*****_
+ ! xxx?xxxxxxxx xxxx xxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxx xxxxx xxxxxxx xx xxxx xxxxxxxx xxxx xxxxxxxxxxx xxx xxxxxxx xxxxxxxxx xx xxxxxx xx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxx xxxxxxxx xxxxxxxxx xxxx xxx xxxx xxx xxx xxxxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxxxxxxx xx xxxxx xxx xxxxxxxx xxxxxx xxx xxx xxxxxxxxx xxxxxxx x xxxxxxxxx xx xxxxxx xxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxx xxxxxxx xxx xxx xxxxxxxx xxxxxxx xxxx xxx xxxxxx xxxxx xxxxx xx xxxxxx xxxxxxx xxx xxxxxxxxxxxx xxxx xxxxxxxxx xxxxxx xxxxxx xxxxx xxx xxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxx xxxxxxxxxx xxxx xx xxxxxxxx xxx xxxxxxxxxxx xxxxx
Test
Test END
EN
diff --git a/src/nvim/testdir/test69.in b/src/nvim/testdir/test69.in
deleted file mode 100644
index 39b360fc81..0000000000
--- a/src/nvim/testdir/test69.in
+++ /dev/null
@@ -1,191 +0,0 @@
-Test for multi-byte text formatting.
-Also test, that 'mps' with multibyte chars works.
-And test "ra" on multi-byte characters.
-Also test byteidx() and byteidxcomp()
-
-STARTTEST
-:
-ENDTEST
-
-Results of test69:
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=t
-gqgqjgqgqo
-XYZ
-abc XYZ
-ENDTEST
-
-{
-XYZ
-abc XYZ
-}
-
-STARTTEST
-/^{/+1
-:set tw=1 fo=tm
-gqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-X a
-XY
-X Y
-ENDTEST
-
-{
-X
-Xa
-X a
-XY
-X Y
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=tm
-gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-X a
-XY
-X Y
-aX
-abX
-abcX
-abX c
-abXY
-ENDTEST
-
-{
-X
-Xa
-X a
-XY
-X Y
-aX
-abX
-abcX
-abX c
-abXY
-}
-
-STARTTEST
-/^{/+1
-:set ai tw=2 fo=tm
-gqgqjgqgqo
-X
-Xa
-ENDTEST
-
-{
- X
- Xa
-}
-
-STARTTEST
-/^{/+1
-:set noai tw=2 fo=tm
-gqgqjgqgqo
- X
- Xa
-ENDTEST
-
-{
- X
- Xa
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=cqm comments=n:X
-gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqo
-X
-Xa
-XaY
-XY
-XYZ
-X Y
-X YZ
-XX
-XXa
-XXY
-ENDTEST
-
-{
-X
-Xa
-XaY
-XY
-XYZ
-X Y
-X YZ
-XX
-XXa
-XXY
-}
-
-STARTTEST
-/^{/+1
-:set tw=2 fo=tm
-RXa
-ENDTEST
-
-{
-
-}
-
-STARTTEST
-/^{/+1
-:set mps+=u2018:u2019
-d%
-ENDTEST
-
-{
-‘ two three ’ four
-}
-STARTTEST
-/^ra test
-jVjra
-ENDTEST
-
-ra test
-ï½bbï½
-ï½ï½b
-
-STARTTEST
-:set whichwrap+=h
-/^x
-dh
-:set whichwrap-=h
-ENDTEST
-
-á
-x
-
-STARTTEST
-:let a = '.é.' " one char of two bytes
-:let b = '.eÌ.' " normal e with composing char
-/^byteidx
-:put =string([byteidx(a, 0), byteidx(a, 1), byteidx(a, 2), byteidx(a, 3), byteidx(a, 4)])
-:put =string([byteidx(b, 0), byteidx(b, 1), byteidx(b, 2), byteidx(b, 3), byteidx(b, 4)])
-/^byteidxcomp
-:put =string([byteidxcomp(a, 0), byteidxcomp(a, 1), byteidxcomp(a, 2), byteidxcomp(a, 3), byteidxcomp(a, 4)])
-:let b = '.eÌ.'
-:put =string([byteidxcomp(b, 0), byteidxcomp(b, 1), byteidxcomp(b, 2), byteidxcomp(b, 3), byteidxcomp(b, 4), byteidxcomp(b, 5)])
-ENDTEST
-
-byteidx
-byteidxcomp
-
-STARTTEST
-/^substitute
-:let y = substitute('123', '\zs', 'a', 'g') | put =y
-ENDTEST
-
-substitute
-
-STARTTEST
-:g/^STARTTEST/.,/^ENDTEST/d
-:1;/^Results/,$wq! test.out
-ENDTEST
diff --git a/src/nvim/testdir/test69.ok b/src/nvim/testdir/test69.ok
deleted file mode 100644
index af8befb0c7..0000000000
--- a/src/nvim/testdir/test69.ok
+++ /dev/null
@@ -1,166 +0,0 @@
-Results of test69:
-
-
-{
-XYZ
-abc
-XYZ
-
-XYZ
-abc
-XYZ
-}
-
-
-{
-X
-X
-a
-X
-a
-X
-ï¼¹
-X
-ï¼¹
-
-X
-X
-a
-X
-a
-X
-ï¼¹
-X
-ï¼¹
-}
-
-
-{
-X
-X
-a
-X
-a
-X
-ï¼¹
-X
-ï¼¹
-a
-X
-ab
-X
-abc
-X
-ab
-X
-c
-ab
-X
-ï¼¹
-
-X
-X
-a
-X
-a
-X
-ï¼¹
-X
-ï¼¹
-a
-X
-ab
-X
-abc
-X
-ab
-X
-c
-ab
-X
-ï¼¹
-}
-
-
-{
- X
- X
- a
-
- X
- X
- a
-}
-
-
-{
- X
- X
-a
-
- X
- X
-a
-}
-
-
-{
-X
-Xa
-Xa
-XY
-XY
-XY
-XZ
-X Y
-X Y
-X Z
-XX
-XXa
-XXY
-
-X
-Xa
-Xa
-XY
-XY
-XY
-XZ
-X Y
-X Y
-X Z
-XX
-XXa
-XXY
-}
-
-
-{
-X
-a
-}
-
-
-{
- four
-}
-
-ra test
-aaaa
-aaa
-
-
-áx
-
-
-byteidx
-[0, 1, 3, 4, -1]
-[0, 1, 4, 5, -1]
-byteidxcomp
-[0, 1, 3, 4, -1]
-[0, 1, 2, 4, 5, -1]
-
-
-substitute
-a1a2a3a
-
diff --git a/src/nvim/testdir/test73.in b/src/nvim/testdir/test73.in
deleted file mode 100644
index 7d6c7287a5..0000000000
--- a/src/nvim/testdir/test73.in
+++ /dev/null
@@ -1,175 +0,0 @@
-Tests for find completion.
-
-STARTTEST
-:set wildmode=full
-:" Do all test in a separate window to avoid E211 when we recursively
-:" delete the Xfind directory during cleanup
-:"
-:" This will cause a few errors, do it silently.
-:set visualbell
-:"
-:function! DeleteDirectory(dir)
-: if has("win16") || has("win32") || has("win64") || has("dos16") || has("dos32")
-: exec "silent !rmdir /Q /S " . a:dir
-: else
-: exec "silent !rm -rf " . a:dir
-: endif
-:endfun
-:" On windows a stale "Xfind" directory may exist, remove it so that
-:" we start from a clean state.
-:call DeleteDirectory("Xfind")
-:new
-:let cwd=getcwd()
-:let test_out = cwd . '/test.out'
-:call mkdir('Xfind')
-:cd Xfind
-:set path=
-:find
-:exec "w! " . test_out
-:close
-:new
-:set path=.
-:find
-:exec "w >>" . test_out
-:close
-:new
-:set path=.,,
-:find
-:exec "w >>" . test_out
-:close
-:new
-:set path=./**
-:find
-:exec "w >>" . test_out
-:close
-:new
-:" We shouldn't find any file at this point, test.out must be empty.
-:call mkdir('in')
-:cd in
-:call mkdir('path')
-:exec "cd " . cwd
-:e Xfind/file.txt
-SHoly Grail:w
-:e Xfind/in/file.txt
-SJimmy Hoffa:w
-:e Xfind/in/stuff.txt
-SAnother Holy Grail:w
-:e Xfind/in/path/file.txt
-SE.T.:w
-:set path=Xfind/**
-:find file
-:exec "w >>" . test_out
-:find file
-:exec "w >>" . test_out
-:find file
-:exec "w >>" . test_out
-:" Rerun the previous three find completions, using fullpath in 'path'
-:exec "set path=" . cwd . "/Xfind/**"
-:find file
-:exec "w >>" . test_out
-:find file
-:exec "w >>" . test_out
-:find file
-:exec "w >>" . test_out
-:" Same steps again, using relative and fullpath items that point to the same
-:" recursive location.
-:" This is to test that there are no duplicates in the completion list.
-:exec "set path+=Xfind/**"
-:find file
-:exec "w >>" . test_out
-:find file
-:exec "w >>" . test_out
-:find file
-:exec "w >>" . test_out
-:find file
-:" Test find completion for directory of current buffer, which at this point
-:" is Xfind/in/file.txt.
-:set path=.
-:find st
-:exec "w >>" . test_out
-:" Test find completion for empty path item ",," which is the current directory
-:cd Xfind
-:set path=,,
-:find f
-:exec "w >>" . test_out
-:" Test shortening of
-:"
-:" foo/x/bar/voyager.txt
-:" foo/y/bar/voyager.txt
-:"
-:" When current directory is above foo/ they should be shortened to (in order
-:" of appearance):
-:"
-:" x/bar/voyager.txt
-:" y/bar/voyager.txt
-:call mkdir('foo')
-:cd foo
-:call mkdir('x')
-:call mkdir('y')
-:cd x
-:call mkdir('bar')
-:cd ..
-:cd y
-:call mkdir('bar')
-:cd ..
-:cd ..
-:" We should now be in the Xfind directory
-:e foo/x/bar/voyager.txt
-SVoyager 1:w
-:e foo/y/bar/voyager.txt
-SVoyager 2:w
-:exec "set path=" . cwd . "/Xfind/**"
-:find voyager
-:exec "w >>" . test_out
-:find voyager
-:exec "w >>" . test_out
-:"
-:" When current directory is .../foo/y/bar they should be shortened to (in
-:" order of appearance):
-:"
-:" ./voyager.txt
-:" x/bar/voyager.txt
-:cd foo
-:cd y
-:cd bar
-:find voyager
-:exec "w >> " . test_out
-:find voyager
-:exec "w >> " . test_out
-:" Check the opposite too:
-:cd ..
-:cd ..
-:cd x
-:cd bar
-:find voyager
-:exec "w >> " . test_out
-:find voyager
-:exec "w >> " . test_out
-:" Check for correct handling of shorten_fname()'s behavior on windows
-:exec "cd " . cwd . "/Xfind/in"
-:find file
-:exec "w >>" . test_out
-:" Test for relative to current buffer 'path' item
-:exec "cd " . cwd . "/Xfind/"
-:set path=./path
-:" Open the file where Jimmy Hoffa is found
-:e in/file.txt
-:" Find the file containing 'E.T.' in the Xfind/in/path directory
-:find file
-:exec "w >>" . test_out
-:"
-:" Test that completion works when path=.,,
-:"
-:set path=.,,
-:" Open Jimmy Hoffa file
-:e in/file.txt
-:exec "w >>" . test_out
-:" Search for the file containing Holy Grail in same directory as in/path.txt
-:find stu
-:exec "w >>" . test_out
-:q
-:exec "cd " . cwd
-:call DeleteDirectory("Xfind")
-:qa!
-ENDTEST
-
diff --git a/src/nvim/testdir/test73.ok b/src/nvim/testdir/test73.ok
deleted file mode 100644
index 90efab756f..0000000000
--- a/src/nvim/testdir/test73.ok
+++ /dev/null
@@ -1,21 +0,0 @@
-Holy Grail
-Jimmy Hoffa
-E.T.
-Holy Grail
-Jimmy Hoffa
-E.T.
-Holy Grail
-Jimmy Hoffa
-E.T.
-Another Holy Grail
-Holy Grail
-Voyager 1
-Voyager 2
-Voyager 2
-Voyager 1
-Voyager 1
-Voyager 2
-Jimmy Hoffa
-E.T.
-Jimmy Hoffa
-Another Holy Grail
diff --git a/src/nvim/testdir/test79.in b/src/nvim/testdir/test79.in
deleted file mode 100644
index afbf2083d2..0000000000
--- a/src/nvim/testdir/test79.in
+++ /dev/null
Binary files differ
diff --git a/src/nvim/testdir/test79.ok b/src/nvim/testdir/test79.ok
deleted file mode 100644
index d4e0ae8819..0000000000
--- a/src/nvim/testdir/test79.ok
+++ /dev/null
Binary files differ
diff --git a/src/nvim/testdir/test8.in b/src/nvim/testdir/test8.in
deleted file mode 100644
index a5e6034782..0000000000
--- a/src/nvim/testdir/test8.in
+++ /dev/null
@@ -1,43 +0,0 @@
-Test for BufWritePre autocommand that deletes or unloads the buffer.
-Test for BufUnload autocommand that unloads all other buffers.
-
-STARTTEST
-:au BufWritePre Xxx1 bunload
-:au BufWritePre Xxx2 bwipe
-/^start of
-A1:.,/end of/w! Xxx1 " write test file Xxx1
-$r2:.,/end of/w! Xxx2 " write test file Xxx2
-:e! Xxx2 " edit Xxx2
-:bdel test8.in " delete this file from the buffer list
-:e Xxx1 " edit Xxx1
-:w " write it, will unload it and give an error msg
-:w! test.out " Write contents of this file
-:e! Xxx2 " start editing Xxx2
-:bwipe test.out " remove test.out from the buffer list
-:w " write it, will delete the buffer and give an error msg
-:w >>test.out " Append contents of this file
-:au! BufWritePre
-:func CloseAll()
- let i = 0
- while i <= bufnr('$')
- if i != bufnr('%') && bufloaded(i)
- exe i . "bunload"
- endif
- let i += 1
- endwhile
-endfunc
-:func WriteToOut()
- edit! test.out
- $put ='VimLeave done'
- write
-endfunc
-:set shada='100
-:au BufUnload * call CloseAll()
-:au VimLeave * call WriteToOut()
-:q
-:qa!
-ENDTEST
-
-start of Xxx
- test
-end of Xxx
diff --git a/src/nvim/testdir/test8.ok b/src/nvim/testdir/test8.ok
deleted file mode 100644
index adecb2f4be..0000000000
--- a/src/nvim/testdir/test8.ok
+++ /dev/null
@@ -1,7 +0,0 @@
-start of Xxx2
- test
-end of Xxx
-start of Xxx1
- test
-end of Xxx
-VimLeave done
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 1d1da94bac..0602ff6a45 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -1,3 +1,53 @@
" A series of tests that can run in one Vim invocation.
" This makes testing go faster, since Vim doesn't need to restart.
+source test_assign.vim
+source test_behave.vim
+source test_cd.vim
+source test_changedtick.vim
+source test_compiler.vim
+source test_cursor_func.vim
+source test_ex_undo.vim
+source test_ex_z.vim
+source test_execute_func.vim
+source test_expr.vim
+source test_feedkeys.vim
+source test_filter_cmd.vim
+source test_filter_map.vim
+source test_findfile.vim
+source test_float_func.vim
+source test_functions.vim
+source test_ga.vim
+source test_global.vim
+source test_goto.vim
+source test_join.vim
+source test_jumps.vim
+source test_fileformat.vim
+source test_filetype.vim
+source test_lambda.vim
+source test_mapping.vim
+source test_menu.vim
+source test_messages.vim
+source test_move.vim
+source test_partial.vim
+source test_popup.vim
+source test_put.vim
+source test_recover.vim
+source test_regexp_utf8.vim
+source test_scroll_opt.vim
+source test_sort.vim
+source test_source_utf8.vim
+source test_sha256.vim
+source test_statusline.vim
+source test_suspend.vim
+source test_syn_attr.vim
+source test_tabline.vim
+" source test_tabpage.vim
+source test_tagcase.vim
+source test_tagjump.vim
+source test_taglist.vim
+source test_true_false.vim
+source test_unlet.vim
+source test_utf8.vim
+source test_virtualedit.vim
+source test_window_cmd.vim
diff --git a/src/nvim/testdir/test_alot_latin.vim b/src/nvim/testdir/test_alot_latin.vim
new file mode 100644
index 0000000000..ebb3bde4ce
--- /dev/null
+++ b/src/nvim/testdir/test_alot_latin.vim
@@ -0,0 +1,10 @@
+" A series of tests that can run in one Vim invocation.
+" This makes testing go faster, since Vim doesn't need to restart.
+
+" These tests use latin1 'encoding'. Setting 'encoding' is in the individual
+" files, so that they can be run by themselves.
+
+" Nvim does not allow setting 'encoding', so skip this test group.
+finish
+
+source test_regexp_latin.vim
diff --git a/src/nvim/testdir/test_alot_utf8.vim b/src/nvim/testdir/test_alot_utf8.vim
new file mode 100644
index 0000000000..648d806a94
--- /dev/null
+++ b/src/nvim/testdir/test_alot_utf8.vim
@@ -0,0 +1,17 @@
+" A series of tests that can run in one Vim invocation.
+" This makes testing go faster, since Vim doesn't need to restart.
+
+" These tests use utf8 'encoding'. Setting 'encoding' is already done in
+" runtest.vim. Checking for the multi_byte feature is in the individual
+" files, so that they can be run by themselves.
+
+source test_charsearch_utf8.vim
+source test_expr_utf8.vim
+source test_listlbr_utf8.vim
+source test_matchadd_conceal_utf8.vim
+source test_mksession_utf8.vim
+source test_regexp_utf8.vim
+source test_source_utf8.vim
+source test_startup_utf8.vim
+source test_utf8.vim
+source test_utf8_comparisons.vim
diff --git a/src/nvim/testdir/test_arabic.vim b/src/nvim/testdir/test_arabic.vim
new file mode 100644
index 0000000000..17e925ee7f
--- /dev/null
+++ b/src/nvim/testdir/test_arabic.vim
@@ -0,0 +1,613 @@
+" Simplistic testing of Arabic mode.
+" NOTE: This just checks if the code works. If you know Arabic please add
+" functional tests that check the shaping works with real text.
+
+if !has('arabic') || !has('multi_byte')
+ finish
+endif
+
+source view_util.vim
+
+" Return list of Unicode characters at line lnum.
+" Combining characters are treated as a single item.
+func s:get_chars(lnum)
+ call cursor(a:lnum, 1)
+ let chars = []
+ let numchars = strchars(getline('.'), 1)
+ for i in range(1, numchars)
+ exe 'norm ' i . '|'
+ let c = execute('ascii')
+ let c = substitute(c, '\n\?<.\{-}Hex\s*', 'U+', 'g')
+ let c = substitute(c, ',\s*Oct\(al\)\=\s\d*\(, Digr ..\)\=', '', 'g')
+ call add(chars, c)
+ endfor
+ return chars
+endfunc
+
+func Test_arabic_toggle()
+ set arabic
+ call assert_equal(1, &rightleft)
+ call assert_equal(1, &arabicshape)
+ call assert_equal('arabic', &keymap)
+ call assert_equal(1, &delcombine)
+
+ set iminsert=1 imsearch=1
+ set arabic&
+ call assert_equal(0, &rightleft)
+ call assert_equal(1, &arabicshape)
+ call assert_equal('arabic', &keymap)
+ call assert_equal(1, &delcombine)
+ call assert_equal(0, &iminsert)
+ call assert_equal(-1, &imsearch)
+
+ set arabicshape& keymap= delcombine&
+endfunc
+
+func Test_arabic_input()
+ new
+ set arabic
+ " Typing sghl in Arabic insert mode should show the
+ " Arabic word 'Salaam' i.e. 'peace', spelled:
+ " SEEN, LAM, ALEF, MEEM.
+ " See: https://www.mediawiki.org/wiki/VisualEditor/Typing/Right-to-left
+ call feedkeys('isghl!', 'tx')
+ call assert_match("^ *!\uFEE1\uFEFC\uFEB3$", ScreenLines(1, &columns)[0])
+ call assert_equal([
+ \ 'U+0633',
+ \ 'U+0644 U+0627',
+ \ 'U+0645',
+ \ 'U+21'], s:get_chars(1))
+
+ " Without shaping, it should give individual Arabic letters.
+ set noarabicshape
+ call assert_match("^ *!\u0645\u0627\u0644\u0633$", ScreenLines(1, &columns)[0])
+ call assert_equal([
+ \ 'U+0633',
+ \ 'U+0644',
+ \ 'U+0627',
+ \ 'U+0645',
+ \ 'U+21'], s:get_chars(1))
+
+ set arabic& arabicshape&
+ bwipe!
+endfunc
+
+func Test_arabic_toggle_keymap()
+ new
+ set arabic
+ call feedkeys("i12\<C-^>12\<C-^>12", 'tx')
+ call assert_match("^ *٢١21٢١$", ScreenLines(1, &columns)[0])
+ call assert_equal('١٢12١٢', getline('.'))
+ set arabic&
+ bwipe!
+endfunc
+
+func Test_delcombine()
+ new
+ set arabic
+ call feedkeys("isghl\<BS>\<BS>", 'tx')
+ call assert_match("^ *\uFEDE\uFEB3$", ScreenLines(1, &columns)[0])
+ call assert_equal(['U+0633', 'U+0644'], s:get_chars(1))
+
+ " Now the same with 'nodelcombine'
+ set nodelcombine
+ %d
+ call feedkeys("isghl\<BS>\<BS>", 'tx')
+ call assert_match("^ *\uFEB1$", ScreenLines(1, &columns)[0])
+ call assert_equal(['U+0633'], s:get_chars(1))
+ set arabic&
+ bwipe!
+endfunc
+
+" Values from src/arabic.h (not all used yet)
+let s:a_COMMA = "\u060C"
+let s:a_SEMICOLON = "\u061B"
+let s:a_QUESTION = "\u061F"
+let s:a_HAMZA = "\u0621"
+let s:a_ALEF_MADDA = "\u0622"
+let s:a_ALEF_HAMZA_ABOVE = "\u0623"
+let s:a_WAW_HAMZA = "\u0624"
+let s:a_ALEF_HAMZA_BELOW = "\u0625"
+let s:a_YEH_HAMZA = "\u0626"
+let s:a_ALEF = "\u0627"
+let s:a_BEH = "\u0628"
+let s:a_TEH_MARBUTA = "\u0629"
+let s:a_TEH = "\u062a"
+let s:a_THEH = "\u062b"
+let s:a_JEEM = "\u062c"
+let s:a_HAH = "\u062d"
+let s:a_KHAH = "\u062e"
+let s:a_DAL = "\u062f"
+let s:a_THAL = "\u0630"
+let s:a_REH = "\u0631"
+let s:a_ZAIN = "\u0632"
+let s:a_SEEN = "\u0633"
+let s:a_SHEEN = "\u0634"
+let s:a_SAD = "\u0635"
+let s:a_DAD = "\u0636"
+let s:a_TAH = "\u0637"
+let s:a_ZAH = "\u0638"
+let s:a_AIN = "\u0639"
+let s:a_GHAIN = "\u063a"
+let s:a_TATWEEL = "\u0640"
+let s:a_FEH = "\u0641"
+let s:a_QAF = "\u0642"
+let s:a_KAF = "\u0643"
+let s:a_LAM = "\u0644"
+let s:a_MEEM = "\u0645"
+let s:a_NOON = "\u0646"
+let s:a_HEH = "\u0647"
+let s:a_WAW = "\u0648"
+let s:a_ALEF_MAKSURA = "\u0649"
+let s:a_YEH = "\u064a"
+
+let s:a_FATHATAN = "\u064b"
+let s:a_DAMMATAN = "\u064c"
+let s:a_KASRATAN = "\u064d"
+let s:a_FATHA = "\u064e"
+let s:a_DAMMA = "\u064f"
+let s:a_KASRA = "\u0650"
+let s:a_SHADDA = "\u0651"
+let s:a_SUKUN = "\u0652"
+
+let s:a_MADDA_ABOVE = "\u0653"
+let s:a_HAMZA_ABOVE = "\u0654"
+let s:a_HAMZA_BELOW = "\u0655"
+
+let s:a_ZERO = "\u0660"
+let s:a_ONE = "\u0661"
+let s:a_TWO = "\u0662"
+let s:a_THREE = "\u0663"
+let s:a_FOUR = "\u0664"
+let s:a_FIVE = "\u0665"
+let s:a_SIX = "\u0666"
+let s:a_SEVEN = "\u0667"
+let s:a_EIGHT = "\u0668"
+let s:a_NINE = "\u0669"
+let s:a_PERCENT = "\u066a"
+let s:a_DECIMAL = "\u066b"
+let s:a_THOUSANDS = "\u066c"
+let s:a_STAR = "\u066d"
+let s:a_MINI_ALEF = "\u0670"
+
+let s:a_s_FATHATAN = "\ufe70"
+let s:a_m_TATWEEL_FATHATAN = "\ufe71"
+let s:a_s_DAMMATAN = "\ufe72"
+
+let s:a_s_KASRATAN = "\ufe74"
+
+let s:a_s_FATHA = "\ufe76"
+let s:a_m_FATHA = "\ufe77"
+let s:a_s_DAMMA = "\ufe78"
+let s:a_m_DAMMA = "\ufe79"
+let s:a_s_KASRA = "\ufe7a"
+let s:a_m_KASRA = "\ufe7b"
+let s:a_s_SHADDA = "\ufe7c"
+let s:a_m_SHADDA = "\ufe7d"
+let s:a_s_SUKUN = "\ufe7e"
+let s:a_m_SUKUN = "\ufe7f"
+
+let s:a_s_HAMZA = "\ufe80"
+let s:a_s_ALEF_MADDA = "\ufe81"
+let s:a_f_ALEF_MADDA = "\ufe82"
+let s:a_s_ALEF_HAMZA_ABOVE = "\ufe83"
+let s:a_f_ALEF_HAMZA_ABOVE = "\ufe84"
+let s:a_s_WAW_HAMZA = "\ufe85"
+let s:a_f_WAW_HAMZA = "\ufe86"
+let s:a_s_ALEF_HAMZA_BELOW = "\ufe87"
+let s:a_f_ALEF_HAMZA_BELOW = "\ufe88"
+let s:a_s_YEH_HAMZA = "\ufe89"
+let s:a_f_YEH_HAMZA = "\ufe8a"
+let s:a_i_YEH_HAMZA = "\ufe8b"
+let s:a_m_YEH_HAMZA = "\ufe8c"
+let s:a_s_ALEF = "\ufe8d"
+let s:a_f_ALEF = "\ufe8e"
+let s:a_s_BEH = "\ufe8f"
+let s:a_f_BEH = "\ufe90"
+let s:a_i_BEH = "\ufe91"
+let s:a_m_BEH = "\ufe92"
+let s:a_s_TEH_MARBUTA = "\ufe93"
+let s:a_f_TEH_MARBUTA = "\ufe94"
+let s:a_s_TEH = "\ufe95"
+let s:a_f_TEH = "\ufe96"
+let s:a_i_TEH = "\ufe97"
+let s:a_m_TEH = "\ufe98"
+let s:a_s_THEH = "\ufe99"
+let s:a_f_THEH = "\ufe9a"
+let s:a_i_THEH = "\ufe9b"
+let s:a_m_THEH = "\ufe9c"
+let s:a_s_JEEM = "\ufe9d"
+let s:a_f_JEEM = "\ufe9e"
+let s:a_i_JEEM = "\ufe9f"
+let s:a_m_JEEM = "\ufea0"
+let s:a_s_HAH = "\ufea1"
+let s:a_f_HAH = "\ufea2"
+let s:a_i_HAH = "\ufea3"
+let s:a_m_HAH = "\ufea4"
+let s:a_s_KHAH = "\ufea5"
+let s:a_f_KHAH = "\ufea6"
+let s:a_i_KHAH = "\ufea7"
+let s:a_m_KHAH = "\ufea8"
+let s:a_s_DAL = "\ufea9"
+let s:a_f_DAL = "\ufeaa"
+let s:a_s_THAL = "\ufeab"
+let s:a_f_THAL = "\ufeac"
+let s:a_s_REH = "\ufead"
+let s:a_f_REH = "\ufeae"
+let s:a_s_ZAIN = "\ufeaf"
+let s:a_f_ZAIN = "\ufeb0"
+let s:a_s_SEEN = "\ufeb1"
+let s:a_f_SEEN = "\ufeb2"
+let s:a_i_SEEN = "\ufeb3"
+let s:a_m_SEEN = "\ufeb4"
+let s:a_s_SHEEN = "\ufeb5"
+let s:a_f_SHEEN = "\ufeb6"
+let s:a_i_SHEEN = "\ufeb7"
+let s:a_m_SHEEN = "\ufeb8"
+let s:a_s_SAD = "\ufeb9"
+let s:a_f_SAD = "\ufeba"
+let s:a_i_SAD = "\ufebb"
+let s:a_m_SAD = "\ufebc"
+let s:a_s_DAD = "\ufebd"
+let s:a_f_DAD = "\ufebe"
+let s:a_i_DAD = "\ufebf"
+let s:a_m_DAD = "\ufec0"
+let s:a_s_TAH = "\ufec1"
+let s:a_f_TAH = "\ufec2"
+let s:a_i_TAH = "\ufec3"
+let s:a_m_TAH = "\ufec4"
+let s:a_s_ZAH = "\ufec5"
+let s:a_f_ZAH = "\ufec6"
+let s:a_i_ZAH = "\ufec7"
+let s:a_m_ZAH = "\ufec8"
+let s:a_s_AIN = "\ufec9"
+let s:a_f_AIN = "\ufeca"
+let s:a_i_AIN = "\ufecb"
+let s:a_m_AIN = "\ufecc"
+let s:a_s_GHAIN = "\ufecd"
+let s:a_f_GHAIN = "\ufece"
+let s:a_i_GHAIN = "\ufecf"
+let s:a_m_GHAIN = "\ufed0"
+let s:a_s_FEH = "\ufed1"
+let s:a_f_FEH = "\ufed2"
+let s:a_i_FEH = "\ufed3"
+let s:a_m_FEH = "\ufed4"
+let s:a_s_QAF = "\ufed5"
+let s:a_f_QAF = "\ufed6"
+let s:a_i_QAF = "\ufed7"
+let s:a_m_QAF = "\ufed8"
+let s:a_s_KAF = "\ufed9"
+let s:a_f_KAF = "\ufeda"
+let s:a_i_KAF = "\ufedb"
+let s:a_m_KAF = "\ufedc"
+let s:a_s_LAM = "\ufedd"
+let s:a_f_LAM = "\ufede"
+let s:a_i_LAM = "\ufedf"
+let s:a_m_LAM = "\ufee0"
+let s:a_s_MEEM = "\ufee1"
+let s:a_f_MEEM = "\ufee2"
+let s:a_i_MEEM = "\ufee3"
+let s:a_m_MEEM = "\ufee4"
+let s:a_s_NOON = "\ufee5"
+let s:a_f_NOON = "\ufee6"
+let s:a_i_NOON = "\ufee7"
+let s:a_m_NOON = "\ufee8"
+let s:a_s_HEH = "\ufee9"
+let s:a_f_HEH = "\ufeea"
+let s:a_i_HEH = "\ufeeb"
+let s:a_m_HEH = "\ufeec"
+let s:a_s_WAW = "\ufeed"
+let s:a_f_WAW = "\ufeee"
+let s:a_s_ALEF_MAKSURA = "\ufeef"
+let s:a_f_ALEF_MAKSURA = "\ufef0"
+let s:a_s_YEH = "\ufef1"
+let s:a_f_YEH = "\ufef2"
+let s:a_i_YEH = "\ufef3"
+let s:a_m_YEH = "\ufef4"
+let s:a_s_LAM_ALEF_MADDA_ABOVE = "\ufef5"
+let s:a_f_LAM_ALEF_MADDA_ABOVE = "\ufef6"
+let s:a_s_LAM_ALEF_HAMZA_ABOVE = "\ufef7"
+let s:a_f_LAM_ALEF_HAMZA_ABOVE = "\ufef8"
+let s:a_s_LAM_ALEF_HAMZA_BELOW = "\ufef9"
+let s:a_f_LAM_ALEF_HAMZA_BELOW = "\ufefa"
+let s:a_s_LAM_ALEF = "\ufefb"
+let s:a_f_LAM_ALEF = "\ufefc"
+
+let s:a_BYTE_ORDER_MARK = "\ufeff"
+
+func Test_shape_initial()
+ new
+ set arabicshape
+
+ " Shaping arabic {testchar} non-arabic Tests chg_c_a2i().
+ " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result
+ for pair in [[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_i_YEH_HAMZA],
+ \ [s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA],
+ \ [s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_s_ALEF_MADDA],
+ \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_ABOVE],
+ \ [s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_s_WAW_HAMZA],
+ \ [s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_BELOW],
+ \ [s:a_ALEF, s:a_s_GHAIN, s:a_s_ALEF],
+ \ [s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_s_TEH_MARBUTA],
+ \ [s:a_DAL, s:a_s_GHAIN, s:a_s_DAL],
+ \ [s:a_THAL, s:a_s_GHAIN, s:a_s_THAL],
+ \ [s:a_REH, s:a_s_GHAIN, s:a_s_REH],
+ \ [s:a_ZAIN, s:a_s_GHAIN, s:a_s_ZAIN],
+ \ [s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL],
+ \ [s:a_WAW, s:a_s_GHAIN, s:a_s_WAW],
+ \ [s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_s_ALEF_MAKSURA],
+ \ [s:a_BEH, s:a_f_GHAIN, s:a_i_BEH],
+ \ [s:a_TEH, s:a_f_GHAIN, s:a_i_TEH],
+ \ [s:a_THEH, s:a_f_GHAIN, s:a_i_THEH],
+ \ [s:a_JEEM, s:a_f_GHAIN, s:a_i_JEEM],
+ \ [s:a_HAH, s:a_f_GHAIN, s:a_i_HAH],
+ \ [s:a_KHAH, s:a_f_GHAIN, s:a_i_KHAH],
+ \ [s:a_SEEN, s:a_f_GHAIN, s:a_i_SEEN],
+ \ [s:a_SHEEN, s:a_f_GHAIN, s:a_i_SHEEN],
+ \ [s:a_SAD, s:a_f_GHAIN, s:a_i_SAD],
+ \ [s:a_DAD, s:a_f_GHAIN, s:a_i_DAD],
+ \ [s:a_TAH, s:a_f_GHAIN, s:a_i_TAH],
+ \ [s:a_ZAH, s:a_f_GHAIN, s:a_i_ZAH],
+ \ [s:a_AIN, s:a_f_GHAIN, s:a_i_AIN],
+ \ [s:a_GHAIN, s:a_f_GHAIN, s:a_i_GHAIN],
+ \ [s:a_FEH, s:a_f_GHAIN, s:a_i_FEH],
+ \ [s:a_QAF, s:a_f_GHAIN, s:a_i_QAF],
+ \ [s:a_KAF, s:a_f_GHAIN, s:a_i_KAF],
+ \ [s:a_LAM, s:a_f_GHAIN, s:a_i_LAM],
+ \ [s:a_MEEM, s:a_f_GHAIN, s:a_i_MEEM],
+ \ [s:a_NOON, s:a_f_GHAIN, s:a_i_NOON],
+ \ [s:a_HEH, s:a_f_GHAIN, s:a_i_HEH],
+ \ [s:a_YEH, s:a_f_GHAIN, s:a_i_YEH],
+ \ ]
+ call setline(1, s:a_GHAIN . pair[0] . ' ')
+ call assert_equal([pair[1] . pair[2] . ' '], ScreenLines(1, 3))
+ endfor
+
+ set arabicshape&
+ bwipe!
+endfunc
+
+func Test_shape_isolated()
+ new
+ set arabicshape
+
+ " Shaping non-arabic {testchar} non-arabic Tests chg_c_a2s().
+ " pair[0] = testchar, pair[1] = current-result
+ for pair in [[s:a_HAMZA, s:a_s_HAMZA],
+ \ [s:a_ALEF_MADDA, s:a_s_ALEF_MADDA],
+ \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_ALEF_HAMZA_ABOVE],
+ \ [s:a_WAW_HAMZA, s:a_s_WAW_HAMZA],
+ \ [s:a_ALEF_HAMZA_BELOW, s:a_s_ALEF_HAMZA_BELOW],
+ \ [s:a_YEH_HAMZA, s:a_s_YEH_HAMZA],
+ \ [s:a_ALEF, s:a_s_ALEF],
+ \ [s:a_TEH_MARBUTA, s:a_s_TEH_MARBUTA],
+ \ [s:a_DAL, s:a_s_DAL],
+ \ [s:a_THAL, s:a_s_THAL],
+ \ [s:a_REH, s:a_s_REH],
+ \ [s:a_ZAIN, s:a_s_ZAIN],
+ \ [s:a_TATWEEL, s:a_TATWEEL],
+ \ [s:a_WAW, s:a_s_WAW],
+ \ [s:a_ALEF_MAKSURA, s:a_s_ALEF_MAKSURA],
+ \ [s:a_BEH, s:a_s_BEH],
+ \ [s:a_TEH, s:a_s_TEH],
+ \ [s:a_THEH, s:a_s_THEH],
+ \ [s:a_JEEM, s:a_s_JEEM],
+ \ [s:a_HAH, s:a_s_HAH],
+ \ [s:a_KHAH, s:a_s_KHAH],
+ \ [s:a_SEEN, s:a_s_SEEN],
+ \ [s:a_SHEEN, s:a_s_SHEEN],
+ \ [s:a_SAD, s:a_s_SAD],
+ \ [s:a_DAD, s:a_s_DAD],
+ \ [s:a_TAH, s:a_s_TAH],
+ \ [s:a_ZAH, s:a_s_ZAH],
+ \ [s:a_AIN, s:a_s_AIN],
+ \ [s:a_GHAIN, s:a_s_GHAIN],
+ \ [s:a_FEH, s:a_s_FEH],
+ \ [s:a_QAF, s:a_s_QAF],
+ \ [s:a_KAF, s:a_s_KAF],
+ \ [s:a_LAM, s:a_s_LAM],
+ \ [s:a_MEEM, s:a_s_MEEM],
+ \ [s:a_NOON, s:a_s_NOON],
+ \ [s:a_HEH, s:a_s_HEH],
+ \ [s:a_YEH, s:a_s_YEH],
+ \ ]
+ call setline(1, ' ' . pair[0] . ' ')
+ call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3))
+ endfor
+
+ set arabicshape&
+ bwipe!
+endfunc
+
+func Test_shape_iso_to_medial()
+ new
+ set arabicshape
+
+ " Shaping arabic {testchar} arabic Tests chg_c_a2m().
+ " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result,
+ " pair[3] = previous-result
+ for pair in [[s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA, s:a_s_BEH],
+ \[s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_f_ALEF_MADDA, s:a_i_BEH],
+ \[s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH],
+ \[s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_f_WAW_HAMZA, s:a_i_BEH],
+ \[s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH],
+ \[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_m_YEH_HAMZA, s:a_i_BEH],
+ \[s:a_ALEF, s:a_s_GHAIN, s:a_f_ALEF, s:a_i_BEH],
+ \[s:a_BEH, s:a_f_GHAIN, s:a_m_BEH, s:a_i_BEH],
+ \[s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_f_TEH_MARBUTA, s:a_i_BEH],
+ \[s:a_TEH, s:a_f_GHAIN, s:a_m_TEH, s:a_i_BEH],
+ \[s:a_THEH, s:a_f_GHAIN, s:a_m_THEH, s:a_i_BEH],
+ \[s:a_JEEM, s:a_f_GHAIN, s:a_m_JEEM, s:a_i_BEH],
+ \[s:a_HAH, s:a_f_GHAIN, s:a_m_HAH, s:a_i_BEH],
+ \[s:a_KHAH, s:a_f_GHAIN, s:a_m_KHAH, s:a_i_BEH],
+ \[s:a_DAL, s:a_s_GHAIN, s:a_f_DAL, s:a_i_BEH],
+ \[s:a_THAL, s:a_s_GHAIN, s:a_f_THAL, s:a_i_BEH],
+ \[s:a_REH, s:a_s_GHAIN, s:a_f_REH, s:a_i_BEH],
+ \[s:a_ZAIN, s:a_s_GHAIN, s:a_f_ZAIN, s:a_i_BEH],
+ \[s:a_SEEN, s:a_f_GHAIN, s:a_m_SEEN, s:a_i_BEH],
+ \[s:a_SHEEN, s:a_f_GHAIN, s:a_m_SHEEN, s:a_i_BEH],
+ \[s:a_SAD, s:a_f_GHAIN, s:a_m_SAD, s:a_i_BEH],
+ \[s:a_DAD, s:a_f_GHAIN, s:a_m_DAD, s:a_i_BEH],
+ \[s:a_TAH, s:a_f_GHAIN, s:a_m_TAH, s:a_i_BEH],
+ \[s:a_ZAH, s:a_f_GHAIN, s:a_m_ZAH, s:a_i_BEH],
+ \[s:a_AIN, s:a_f_GHAIN, s:a_m_AIN, s:a_i_BEH],
+ \[s:a_GHAIN, s:a_f_GHAIN, s:a_m_GHAIN, s:a_i_BEH],
+ \[s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL, s:a_i_BEH],
+ \[s:a_FEH, s:a_f_GHAIN, s:a_m_FEH, s:a_i_BEH],
+ \[s:a_QAF, s:a_f_GHAIN, s:a_m_QAF, s:a_i_BEH],
+ \[s:a_KAF, s:a_f_GHAIN, s:a_m_KAF, s:a_i_BEH],
+ \[s:a_LAM, s:a_f_GHAIN, s:a_m_LAM, s:a_i_BEH],
+ \[s:a_MEEM, s:a_f_GHAIN, s:a_m_MEEM, s:a_i_BEH],
+ \[s:a_NOON, s:a_f_GHAIN, s:a_m_NOON, s:a_i_BEH],
+ \[s:a_HEH, s:a_f_GHAIN, s:a_m_HEH, s:a_i_BEH],
+ \[s:a_WAW, s:a_s_GHAIN, s:a_f_WAW, s:a_i_BEH],
+ \[s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_f_ALEF_MAKSURA, s:a_i_BEH],
+ \[s:a_YEH, s:a_f_GHAIN, s:a_m_YEH, s:a_i_BEH],
+ \ ]
+ call setline(1, s:a_GHAIN . pair[0] . s:a_BEH)
+ call assert_equal([pair[1] . pair[2] . pair[3]], ScreenLines(1, 3))
+ endfor
+
+ set arabicshape&
+ bwipe!
+endfunc
+
+func Test_shape_final()
+ new
+ set arabicshape
+
+ " Shaping arabic {testchar} arabic Tests chg_c_a2f().
+ " pair[0] = testchar, pair[1] = current-result, pair[2] = previous-result
+ for pair in [[s:a_HAMZA, s:a_s_HAMZA, s:a_s_BEH],
+ \[s:a_ALEF_MADDA, s:a_f_ALEF_MADDA, s:a_i_BEH],
+ \[s:a_ALEF_HAMZA_ABOVE, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH],
+ \[s:a_WAW_HAMZA, s:a_f_WAW_HAMZA, s:a_i_BEH],
+ \[s:a_ALEF_HAMZA_BELOW, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH],
+ \[s:a_YEH_HAMZA, s:a_f_YEH_HAMZA, s:a_i_BEH],
+ \[s:a_ALEF, s:a_f_ALEF, s:a_i_BEH],
+ \[s:a_BEH, s:a_f_BEH, s:a_i_BEH],
+ \[s:a_TEH_MARBUTA, s:a_f_TEH_MARBUTA, s:a_i_BEH],
+ \[s:a_TEH, s:a_f_TEH, s:a_i_BEH],
+ \[s:a_THEH, s:a_f_THEH, s:a_i_BEH],
+ \[s:a_JEEM, s:a_f_JEEM, s:a_i_BEH],
+ \[s:a_HAH, s:a_f_HAH, s:a_i_BEH],
+ \[s:a_KHAH, s:a_f_KHAH, s:a_i_BEH],
+ \[s:a_DAL, s:a_f_DAL, s:a_i_BEH],
+ \[s:a_THAL, s:a_f_THAL, s:a_i_BEH],
+ \[s:a_REH, s:a_f_REH, s:a_i_BEH],
+ \[s:a_ZAIN, s:a_f_ZAIN, s:a_i_BEH],
+ \[s:a_SEEN, s:a_f_SEEN, s:a_i_BEH],
+ \[s:a_SHEEN, s:a_f_SHEEN, s:a_i_BEH],
+ \[s:a_SAD, s:a_f_SAD, s:a_i_BEH],
+ \[s:a_DAD, s:a_f_DAD, s:a_i_BEH],
+ \[s:a_TAH, s:a_f_TAH, s:a_i_BEH],
+ \[s:a_ZAH, s:a_f_ZAH, s:a_i_BEH],
+ \[s:a_AIN, s:a_f_AIN, s:a_i_BEH],
+ \[s:a_GHAIN, s:a_f_GHAIN, s:a_i_BEH],
+ \[s:a_TATWEEL, s:a_TATWEEL, s:a_i_BEH],
+ \[s:a_FEH, s:a_f_FEH, s:a_i_BEH],
+ \[s:a_QAF, s:a_f_QAF, s:a_i_BEH],
+ \[s:a_KAF, s:a_f_KAF, s:a_i_BEH],
+ \[s:a_LAM, s:a_f_LAM, s:a_i_BEH],
+ \[s:a_MEEM, s:a_f_MEEM, s:a_i_BEH],
+ \[s:a_NOON, s:a_f_NOON, s:a_i_BEH],
+ \[s:a_HEH, s:a_f_HEH, s:a_i_BEH],
+ \[s:a_WAW, s:a_f_WAW, s:a_i_BEH],
+ \[s:a_ALEF_MAKSURA, s:a_f_ALEF_MAKSURA, s:a_i_BEH],
+ \[s:a_YEH, s:a_f_YEH, s:a_i_BEH],
+ \ ]
+ call setline(1, ' ' . pair[0] . s:a_BEH)
+ call assert_equal([' ' . pair[1] . pair[2]], ScreenLines(1, 3))
+ endfor
+
+ set arabicshape&
+ bwipe!
+endfunc
+
+func Test_shape_final_to_medial()
+ new
+ set arabicshape
+
+ " Shaping arabic {testchar} arabic Tests chg_c_f2m().
+ " This does not test much...
+ " pair[0] = testchar, pair[1] = current-result
+ for pair in [[s:a_f_YEH_HAMZA, s:a_f_BEH],
+ \[s:a_f_WAW_HAMZA, s:a_s_BEH],
+ \[s:a_f_ALEF, s:a_s_BEH],
+ \[s:a_f_TEH_MARBUTA, s:a_s_BEH],
+ \[s:a_f_DAL, s:a_s_BEH],
+ \[s:a_f_THAL, s:a_s_BEH],
+ \[s:a_f_REH, s:a_s_BEH],
+ \[s:a_f_ZAIN, s:a_s_BEH],
+ \[s:a_f_WAW, s:a_s_BEH],
+ \[s:a_f_ALEF_MAKSURA, s:a_s_BEH],
+ \[s:a_f_BEH, s:a_f_BEH],
+ \[s:a_f_TEH, s:a_f_BEH],
+ \[s:a_f_THEH, s:a_f_BEH],
+ \[s:a_f_JEEM, s:a_f_BEH],
+ \[s:a_f_HAH, s:a_f_BEH],
+ \[s:a_f_KHAH, s:a_f_BEH],
+ \[s:a_f_SEEN, s:a_f_BEH],
+ \[s:a_f_SHEEN, s:a_f_BEH],
+ \[s:a_f_SAD, s:a_f_BEH],
+ \[s:a_f_DAD, s:a_f_BEH],
+ \[s:a_f_TAH, s:a_f_BEH],
+ \[s:a_f_ZAH, s:a_f_BEH],
+ \[s:a_f_AIN, s:a_f_BEH],
+ \[s:a_f_GHAIN, s:a_f_BEH],
+ \[s:a_f_FEH, s:a_f_BEH],
+ \[s:a_f_QAF, s:a_f_BEH],
+ \[s:a_f_KAF, s:a_f_BEH],
+ \[s:a_f_LAM, s:a_f_BEH],
+ \[s:a_f_MEEM, s:a_f_BEH],
+ \[s:a_f_NOON, s:a_f_BEH],
+ \[s:a_f_HEH, s:a_f_BEH],
+ \[s:a_f_YEH, s:a_f_BEH],
+ \ ]
+ call setline(1, ' ' . s:a_BEH . pair[0])
+ call assert_equal([' ' . pair[1] . pair[0]], ScreenLines(1, 3))
+ endfor
+
+ set arabicshape&
+ bwipe!
+endfunc
+
+func Test_shape_combination_final()
+ new
+ set arabicshape
+
+ " Shaping arabic {testchar} arabic Tests chg_c_laa2f().
+ " pair[0] = testchar, pair[1] = current-result
+ for pair in [[s:a_ALEF_MADDA, s:a_f_LAM_ALEF_MADDA_ABOVE],
+ \ [s:a_ALEF_HAMZA_ABOVE, s:a_f_LAM_ALEF_HAMZA_ABOVE],
+ \ [s:a_ALEF_HAMZA_BELOW, s:a_f_LAM_ALEF_HAMZA_BELOW],
+ \ [s:a_ALEF, s:a_f_LAM_ALEF],
+ \ ]
+ " The test char is a composing char, put on s:a_LAM.
+ call setline(1, ' ' . s:a_LAM . pair[0] . s:a_BEH)
+ call assert_equal([' ' . pair[1] . s:a_i_BEH], ScreenLines(1, 3))
+ endfor
+
+ set arabicshape&
+ bwipe!
+endfunc
+
+func Test_shape_combination_isolated()
+ new
+ set arabicshape
+
+ " Shaping arabic {testchar} arabic Tests chg_c_laa2i().
+ " pair[0] = testchar, pair[1] = current-result
+ for pair in [[s:a_ALEF_MADDA, s:a_s_LAM_ALEF_MADDA_ABOVE],
+ \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_LAM_ALEF_HAMZA_ABOVE],
+ \ [s:a_ALEF_HAMZA_BELOW, s:a_s_LAM_ALEF_HAMZA_BELOW],
+ \ [s:a_ALEF, s:a_s_LAM_ALEF],
+ \ ]
+ " The test char is a composing char, put on s:a_LAM.
+ call setline(1, ' ' . s:a_LAM . pair[0] . ' ')
+ call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3))
+ endfor
+
+ set arabicshape&
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_arglist.vim b/src/nvim/testdir/test_arglist.vim
new file mode 100644
index 0000000000..368fc9810d
--- /dev/null
+++ b/src/nvim/testdir/test_arglist.vim
@@ -0,0 +1,376 @@
+" Test argument list commands
+
+func Test_argidx()
+ args a b c
+ last
+ call assert_equal(2, argidx())
+ %argdelete
+ call assert_equal(0, argidx())
+ " doing it again doesn't result in an error
+ %argdelete
+ call assert_equal(0, argidx())
+ call assert_fails('2argdelete', 'E16:')
+
+ args a b c
+ call assert_equal(0, argidx())
+ next
+ call assert_equal(1, argidx())
+ next
+ call assert_equal(2, argidx())
+ 1argdelete
+ call assert_equal(1, argidx())
+ 1argdelete
+ call assert_equal(0, argidx())
+ 1argdelete
+ call assert_equal(0, argidx())
+endfunc
+
+func Test_argadd()
+ %argdelete
+ argadd a b c
+ call assert_equal(0, argidx())
+
+ %argdelete
+ argadd a
+ call assert_equal(0, argidx())
+ argadd b c d
+ call assert_equal(0, argidx())
+
+ call Init_abc()
+ argadd x
+ call Assert_argc(['a', 'b', 'x', 'c'])
+ call assert_equal(1, argidx())
+
+ call Init_abc()
+ 0argadd x
+ call Assert_argc(['x', 'a', 'b', 'c'])
+ call assert_equal(2, argidx())
+
+ call Init_abc()
+ 1argadd x
+ call Assert_argc(['a', 'x', 'b', 'c'])
+ call assert_equal(2, argidx())
+
+ call Init_abc()
+ $argadd x
+ call Assert_argc(['a', 'b', 'c', 'x'])
+ call assert_equal(1, argidx())
+
+ call Init_abc()
+ $argadd x
+ +2argadd y
+ call Assert_argc(['a', 'b', 'c', 'x', 'y'])
+ call assert_equal(1, argidx())
+
+ %argd
+ edit d
+ arga
+ call assert_equal(1, len(argv()))
+ call assert_equal('d', get(argv(), 0, ''))
+
+ %argd
+ edit some\ file
+ arga
+ call assert_equal(1, len(argv()))
+ call assert_equal('some file', get(argv(), 0, ''))
+
+ %argd
+ new
+ arga
+ call assert_equal(0, len(argv()))
+endfunc
+
+func Init_abc()
+ args a b c
+ next
+endfunc
+
+func Assert_argc(l)
+ call assert_equal(len(a:l), argc())
+ let i = 0
+ while i < len(a:l) && i < argc()
+ call assert_equal(a:l[i], argv(i))
+ let i += 1
+ endwhile
+endfunc
+
+" Test for [count]argument and [count]argdelete commands
+" Ported from the test_argument_count.in test script
+func Test_argument()
+ " Clean the argument list
+ arga a | %argd
+
+ let save_hidden = &hidden
+ set hidden
+
+ let g:buffers = []
+ augroup TEST
+ au BufEnter * call add(buffers, expand('%:t'))
+ augroup END
+
+ argadd a b c d
+ $argu
+ $-argu
+ -argu
+ 1argu
+ +2argu
+
+ augroup TEST
+ au!
+ augroup END
+
+ call assert_equal(['d', 'c', 'b', 'a', 'c'], g:buffers)
+
+ redir => result
+ ar
+ redir END
+ call assert_true(result =~# 'a b \[c] d')
+
+ .argd
+ call assert_equal(['a', 'b', 'd'], argv())
+
+ -argd
+ call assert_equal(['a', 'd'], argv())
+
+ $argd
+ call assert_equal(['a'], argv())
+
+ 1arga c
+ 1arga b
+ $argu
+ $arga x
+ call assert_equal(['a', 'b', 'c', 'x'], argv())
+
+ 0arga y
+ call assert_equal(['y', 'a', 'b', 'c', 'x'], argv())
+
+ %argd
+ call assert_equal([], argv())
+
+ arga a b c d e f
+ 2,$-argd
+ call assert_equal(['a', 'f'], argv())
+
+ let &hidden = save_hidden
+
+ " Setting argument list should fail when the current buffer has unsaved
+ " changes
+ %argd
+ enew!
+ set modified
+ call assert_fails('args x y z', 'E37:')
+ args! x y z
+ call assert_equal(['x', 'y', 'z'], argv())
+ call assert_equal('x', expand('%:t'))
+
+ last | enew | argu
+ call assert_equal('z', expand('%:t'))
+
+ %argdelete
+ call assert_fails('argument', 'E163:')
+endfunc
+
+func Test_args_with_quote()
+ " Only on Unix can a file name include a double quote.
+ if has('unix')
+ args \"foobar
+ call assert_equal('"foobar', argv(0))
+ %argdelete
+ endif
+endfunc
+
+" Test for 0argadd and 0argedit
+" Ported from the test_argument_0count.in test script
+func Test_zero_argadd()
+ " Clean the argument list
+ arga a | %argd
+
+ arga a b c d
+ 2argu
+ 0arga added
+ call assert_equal(['added', 'a', 'b', 'c', 'd'], argv())
+
+ 2argu
+ arga third
+ call assert_equal(['added', 'a', 'third', 'b', 'c', 'd'], argv())
+
+ %argd
+ arga a b c d
+ 2argu
+ 0arge edited
+ call assert_equal(['edited', 'a', 'b', 'c', 'd'], argv())
+
+ 2argu
+ arga third
+ call assert_equal(['edited', 'a', 'third', 'b', 'c', 'd'], argv())
+
+ 2argu
+ argedit file\ with\ spaces another file
+ call assert_equal(['edited', 'a', 'file with spaces', 'another', 'file', 'third', 'b', 'c', 'd'], argv())
+ call assert_equal('file with spaces', expand('%'))
+endfunc
+
+func Reset_arglist()
+ args a | %argd
+endfunc
+
+" Test for argc()
+func Test_argc()
+ call Reset_arglist()
+ call assert_equal(0, argc())
+ argadd a b
+ call assert_equal(2, argc())
+endfunc
+
+" Test for arglistid()
+func Test_arglistid()
+ call Reset_arglist()
+ arga a b
+ call assert_equal(0, arglistid())
+ split
+ arglocal
+ call assert_equal(1, arglistid())
+ tabnew | tabfirst
+ call assert_equal(0, arglistid(2))
+ call assert_equal(1, arglistid(1, 1))
+ call assert_equal(0, arglistid(2, 1))
+ call assert_equal(1, arglistid(1, 2))
+ tabonly | only | enew!
+ argglobal
+ call assert_equal(0, arglistid())
+endfunc
+
+" Test for argv()
+func Test_argv()
+ call Reset_arglist()
+ call assert_equal([], argv())
+ call assert_equal("", argv(2))
+ argadd a b c d
+ call assert_equal('c', argv(2))
+endfunc
+
+" Test for the :argedit command
+func Test_argedit()
+ call Reset_arglist()
+ argedit a
+ call assert_equal(['a'], argv())
+ call assert_equal('a', expand('%:t'))
+ argedit b
+ call assert_equal(['a', 'b'], argv())
+ call assert_equal('b', expand('%:t'))
+ argedit a
+ call assert_equal(['a', 'b', 'a'], argv())
+ call assert_equal('a', expand('%:t'))
+ " When file name case is ignored, an existing buffer with only case
+ " difference is re-used.
+ argedit C D
+ call assert_equal('C', expand('%:t'))
+ call assert_equal(['a', 'b', 'a', 'C', 'D'], argv())
+ argedit c
+ if has('fname_case')
+ call assert_equal(['a', 'b', 'a', 'C', 'c', 'D'], argv())
+ else
+ call assert_equal(['a', 'b', 'a', 'C', 'C', 'D'], argv())
+ endif
+ 0argedit x
+ if has('fname_case')
+ call assert_equal(['x', 'a', 'b', 'a', 'C', 'c', 'D'], argv())
+ else
+ call assert_equal(['x', 'a', 'b', 'a', 'C', 'C', 'D'], argv())
+ endif
+ enew! | set modified
+ call assert_fails('argedit y', 'E37:')
+ argedit! y
+ if has('fname_case')
+ call assert_equal(['x', 'y', 'y', 'a', 'b', 'a', 'C', 'c', 'D'], argv())
+ else
+ call assert_equal(['x', 'y', 'y', 'a', 'b', 'a', 'C', 'C', 'D'], argv())
+ endif
+ %argd
+ bwipe! C
+ bwipe! D
+endfunc
+
+" Test for the :argdelete command
+func Test_argdelete()
+ call Reset_arglist()
+ args aa a aaa b bb
+ argdelete a*
+ call assert_equal(['b', 'bb'], argv())
+ call assert_equal('aa', expand('%:t'))
+ last
+ argdelete %
+ call assert_equal(['b'], argv())
+ call assert_fails('argdelete', 'E471:')
+ call assert_fails('1,100argdelete', 'E16:')
+ %argd
+endfunc
+
+func Test_argdelete_completion()
+ args foo bar
+
+ call feedkeys(":argdelete \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"argdelete bar foo', @:)
+
+ call feedkeys(":argdelete x \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"argdelete x bar foo', @:)
+
+ %argd
+endfunc
+
+" Tests for the :next, :prev, :first, :last, :rewind commands
+func Test_argpos()
+ call Reset_arglist()
+ args a b c d
+ last
+ call assert_equal(3, argidx())
+ call assert_fails('next', 'E165:')
+ prev
+ call assert_equal(2, argidx())
+ Next
+ call assert_equal(1, argidx())
+ first
+ call assert_equal(0, argidx())
+ call assert_fails('prev', 'E164:')
+ 3next
+ call assert_equal(3, argidx())
+ rewind
+ call assert_equal(0, argidx())
+ %argd
+endfunc
+
+" Test for autocommand that redefines the argument list, when doing ":all".
+func Test_arglist_autocmd()
+ autocmd BufReadPost Xxx2 next Xxx2 Xxx1
+ call writefile(['test file Xxx1'], 'Xxx1')
+ call writefile(['test file Xxx2'], 'Xxx2')
+ call writefile(['test file Xxx3'], 'Xxx3')
+
+ new
+ " redefine arglist; go to Xxx1
+ next! Xxx1 Xxx2 Xxx3
+ " open window for all args
+ all
+ call assert_equal('test file Xxx1', getline(1))
+ wincmd w
+ wincmd w
+ call assert_equal('test file Xxx1', getline(1))
+ " should now be in Xxx2
+ rewind
+ call assert_equal('test file Xxx2', getline(1))
+
+ autocmd! BufReadPost Xxx2
+ enew! | only
+ call delete('Xxx1')
+ call delete('Xxx2')
+ call delete('Xxx3')
+ argdelete Xxx*
+ bwipe! Xxx1 Xxx2 Xxx3
+endfunc
+
+func Test_arg_all_expand()
+ call writefile(['test file Xxx1'], 'Xx x')
+ next notexist Xx\ x runtest.vim
+ call assert_equal('notexist Xx\ x runtest.vim', expand('##'))
+ call delete('Xx x')
+endfunc
diff --git a/src/nvim/testdir/test_assign.vim b/src/nvim/testdir/test_assign.vim
new file mode 100644
index 0000000000..50415ad6fd
--- /dev/null
+++ b/src/nvim/testdir/test_assign.vim
@@ -0,0 +1,47 @@
+" Test for assignment
+
+func Test_no_type_checking()
+ let v = 1
+ let v = [1,2,3]
+ let v = {'a': 1, 'b': 2}
+ let v = 3.4
+ let v = 'hello'
+endfunc
+
+func Test_let_termcap()
+ " Nvim does not support `:set termcap`.
+ return
+ " Terminal code
+ let old_t_te = &t_te
+ let &t_te = "\<Esc>[yes;"
+ call assert_match('t_te.*^[[yes;', execute("set termcap"))
+ let &t_te = old_t_te
+
+ if exists("+t_k1")
+ " Key code
+ let old_t_k1 = &t_k1
+ let &t_k1 = "that"
+ call assert_match('t_k1.*that', execute("set termcap"))
+ let &t_k1 = old_t_k1
+ endif
+
+ call assert_fails('let x = &t_xx', 'E15')
+ let &t_xx = "yes"
+ call assert_equal("yes", &t_xx)
+ let &t_xx = ""
+ call assert_fails('let x = &t_xx', 'E15')
+endfunc
+
+func Test_let_option_error()
+ let _w = &tw
+ let &tw = 80
+ call assert_fails('let &tw .= 1', 'E734')
+ call assert_equal(80, &tw)
+ let &tw = _w
+
+ let _w = &fillchars
+ let &fillchars = "vert:|"
+ call assert_fails('let &fillchars += "diff:-"', 'E734')
+ call assert_equal("vert:|", &fillchars)
+ let &fillchars = _w
+endfunc
diff --git a/src/nvim/testdir/test_autochdir.vim b/src/nvim/testdir/test_autochdir.vim
new file mode 100644
index 0000000000..05d69631c4
--- /dev/null
+++ b/src/nvim/testdir/test_autochdir.vim
@@ -0,0 +1,19 @@
+" Test 'autochdir' behavior
+
+if !exists("+autochdir")
+ finish
+endif
+
+func Test_set_filename()
+ let cwd = getcwd()
+ call test_autochdir()
+ set acd
+ new
+ w samples/Xtest
+ call assert_equal("Xtest", expand('%'))
+ call assert_equal("samples", substitute(getcwd(), '.*/\(\k*\)', '\1', ''))
+ bwipe!
+ set noacd
+ exe 'cd ' . cwd
+ call delete('samples/Xtest')
+endfunc
diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim
new file mode 100644
index 0000000000..253d6750ed
--- /dev/null
+++ b/src/nvim/testdir/test_autocmd.vim
@@ -0,0 +1,1308 @@
+" Tests for autocommands
+
+source shared.vim
+
+func! s:cleanup_buffers() abort
+ for bnr in range(1, bufnr('$'))
+ if bufloaded(bnr) && bufnr('%') != bnr
+ execute 'bd! ' . bnr
+ endif
+ endfor
+endfunc
+
+func Test_vim_did_enter()
+ call assert_false(v:vim_did_enter)
+
+ " This script will never reach the main loop, can't check if v:vim_did_enter
+ " becomes one.
+endfunc
+
+if has('timers')
+ func ExitInsertMode(id)
+ call feedkeys("\<Esc>")
+ endfunc
+
+ func Test_cursorhold_insert()
+ " Need to move the cursor.
+ call feedkeys("ggG", "xt")
+
+ let g:triggered = 0
+ au CursorHoldI * let g:triggered += 1
+ set updatetime=20
+ call timer_start(100, 'ExitInsertMode')
+ call feedkeys('a', 'x!')
+ call assert_equal(1, g:triggered)
+ au! CursorHoldI
+ set updatetime&
+ endfunc
+
+ func Test_cursorhold_insert_ctrl_x()
+ let g:triggered = 0
+ au CursorHoldI * let g:triggered += 1
+ set updatetime=20
+ call timer_start(100, 'ExitInsertMode')
+ " CursorHoldI does not trigger after CTRL-X
+ call feedkeys("a\<C-X>", 'x!')
+ call assert_equal(0, g:triggered)
+ au! CursorHoldI
+ set updatetime&
+ endfunc
+endif
+
+func Test_bufunload()
+ augroup test_bufunload_group
+ autocmd!
+ autocmd BufUnload * call add(s:li, "bufunload")
+ autocmd BufDelete * call add(s:li, "bufdelete")
+ autocmd BufWipeout * call add(s:li, "bufwipeout")
+ augroup END
+
+ let s:li=[]
+ new
+ setlocal bufhidden=
+ bunload
+ call assert_equal(["bufunload", "bufdelete"], s:li)
+
+ let s:li=[]
+ new
+ setlocal bufhidden=delete
+ bunload
+ call assert_equal(["bufunload", "bufdelete"], s:li)
+
+ let s:li=[]
+ new
+ setlocal bufhidden=unload
+ bwipeout
+ call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li)
+
+ au! test_bufunload_group
+ augroup! test_bufunload_group
+endfunc
+
+" SEGV occurs in older versions. (At least 7.4.2005 or older)
+func Test_autocmd_bufunload_with_tabnext()
+ tabedit
+ tabfirst
+
+ augroup test_autocmd_bufunload_with_tabnext_group
+ autocmd!
+ autocmd BufUnload <buffer> tabnext
+ augroup END
+
+ quit
+ call assert_equal(2, tabpagenr('$'))
+
+ autocmd! test_autocmd_bufunload_with_tabnext_group
+ augroup! test_autocmd_bufunload_with_tabnext_group
+ tablast
+ quit
+endfunc
+
+func Test_autocmd_bufwinleave_with_tabfirst()
+ tabedit
+ augroup sample
+ autocmd!
+ autocmd BufWinLeave <buffer> tabfirst
+ augroup END
+ call setline(1, ['a', 'b', 'c'])
+ edit! a.txt
+ tabclose
+endfunc
+
+" SEGV occurs in older versions. (At least 7.4.2321 or older)
+func Test_autocmd_bufunload_avoiding_SEGV_01()
+ split aa.txt
+ let lastbuf = bufnr('$')
+
+ augroup test_autocmd_bufunload
+ autocmd!
+ exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
+ augroup END
+
+ call assert_fails('edit bb.txt', 'E937:')
+
+ autocmd! test_autocmd_bufunload
+ augroup! test_autocmd_bufunload
+ bwipe! aa.txt
+ bwipe! bb.txt
+endfunc
+
+" SEGV occurs in older versions. (At least 7.4.2321 or older)
+func Test_autocmd_bufunload_avoiding_SEGV_02()
+ setlocal buftype=nowrite
+ let lastbuf = bufnr('$')
+
+ augroup test_autocmd_bufunload
+ autocmd!
+ exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
+ augroup END
+
+ normal! i1
+ call assert_fails('edit a.txt', 'E517:')
+ call feedkeys("\<CR>")
+
+ autocmd! test_autocmd_bufunload
+ augroup! test_autocmd_bufunload
+ bwipe! a.txt
+endfunc
+
+func Test_win_tab_autocmd()
+ let g:record = []
+
+ augroup testing
+ au WinNew * call add(g:record, 'WinNew')
+ au WinEnter * call add(g:record, 'WinEnter')
+ au WinLeave * call add(g:record, 'WinLeave')
+ au TabNew * call add(g:record, 'TabNew')
+ au TabClosed * call add(g:record, 'TabClosed')
+ au TabEnter * call add(g:record, 'TabEnter')
+ au TabLeave * call add(g:record, 'TabLeave')
+ augroup END
+
+ split
+ tabnew
+ close
+ close
+
+ call assert_equal([
+ \ 'WinLeave', 'WinNew', 'WinEnter',
+ \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
+ \ 'WinLeave', 'TabLeave', 'TabClosed', 'WinEnter', 'TabEnter',
+ \ 'WinLeave', 'WinEnter'
+ \ ], g:record)
+
+ let g:record = []
+ tabnew somefile
+ tabnext
+ bwipe somefile
+
+ call assert_equal([
+ \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
+ \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
+ \ 'TabClosed'
+ \ ], g:record)
+
+ augroup testing
+ au!
+ augroup END
+ unlet g:record
+endfunc
+
+func s:AddAnAutocmd()
+ augroup vimBarTest
+ au BufReadCmd * echo 'hello'
+ augroup END
+ call assert_equal(3, len(split(execute('au vimBarTest'), "\n")))
+endfunc
+
+func Test_early_bar()
+ " test that a bar is recognized before the {event}
+ call s:AddAnAutocmd()
+ augroup vimBarTest | au! | augroup END
+ call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
+
+ call s:AddAnAutocmd()
+ augroup vimBarTest| au!| augroup END
+ call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
+
+ " test that a bar is recognized after the {event}
+ call s:AddAnAutocmd()
+ augroup vimBarTest| au!BufReadCmd| augroup END
+ call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
+
+ " test that a bar is recognized after the {group}
+ call s:AddAnAutocmd()
+ au! vimBarTest|echo 'hello'
+ call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
+endfunc
+
+func RemoveGroup()
+ autocmd! StartOK
+ augroup! StartOK
+endfunc
+
+func Test_augroup_warning()
+ augroup TheWarning
+ au VimEnter * echo 'entering'
+ augroup END
+ call assert_true(match(execute('au VimEnter'), "TheWarning.*VimEnter") >= 0)
+ redir => res
+ augroup! TheWarning
+ redir END
+ call assert_true(match(res, "W19:") >= 0)
+ call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
+
+ " check "Another" does not take the pace of the deleted entry
+ augroup Another
+ augroup END
+ call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
+ augroup! Another
+
+ " no warning for postpone aucmd delete
+ augroup StartOK
+ au VimEnter * call RemoveGroup()
+ augroup END
+ call assert_true(match(execute('au VimEnter'), "StartOK.*VimEnter") >= 0)
+ redir => res
+ doautocmd VimEnter
+ redir END
+ call assert_true(match(res, "W19:") < 0)
+ au! VimEnter
+endfunc
+
+func Test_BufReadCmdHelp()
+ helptags ALL
+ " This used to cause access to free memory
+ au BufReadCmd * e +h
+ help
+
+ au! BufReadCmd
+endfunc
+
+func Test_BufReadCmdHelpJump()
+ " This used to cause access to free memory
+ au BufReadCmd * e +h{
+ " } to fix highlighting
+ call assert_fails('help', 'E434:')
+
+ au! BufReadCmd
+endfunc
+
+func Test_augroup_deleted()
+ " This caused a crash before E936 was introduced
+ augroup x
+ call assert_fails('augroup! x', 'E936:')
+ au VimEnter * echo
+ augroup end
+ augroup! x
+ call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
+ au! VimEnter
+endfunc
+
+" Tests for autocommands on :close command.
+" This used to be in test13.
+func Test_three_windows()
+ " Clean up buffers, because in some cases this function fails.
+ call s:cleanup_buffers()
+
+ " Write three files and open them, each in a window.
+ " Then go to next window, with autocommand that deletes the previous one.
+ " Do this twice, writing the file.
+ e! Xtestje1
+ call setline(1, 'testje1')
+ w
+ sp Xtestje2
+ call setline(1, 'testje2')
+ w
+ sp Xtestje3
+ call setline(1, 'testje3')
+ w
+ wincmd w
+ au WinLeave Xtestje2 bwipe
+ wincmd w
+ call assert_equal('Xtestje1', expand('%'))
+
+ au WinLeave Xtestje1 bwipe Xtestje3
+ close
+ call assert_equal('Xtestje1', expand('%'))
+
+ " Test deleting the buffer on a Unload event. If this goes wrong there
+ " will be the ATTENTION prompt.
+ e Xtestje1
+ au!
+ au! BufUnload Xtestje1 bwipe
+ call assert_fails('e Xtestje3', 'E937:')
+ call assert_equal('Xtestje3', expand('%'))
+
+ e Xtestje2
+ sp Xtestje1
+ call assert_fails('e', 'E937:')
+ call assert_equal('Xtestje2', expand('%'))
+
+ " Test changing buffers in a BufWipeout autocommand. If this goes wrong
+ " there are ml_line errors and/or a Crash.
+ au!
+ only
+ e Xanother
+ e Xtestje1
+ bwipe Xtestje2
+ bwipe Xtestje3
+ au BufWipeout Xtestje1 buf Xtestje1
+ bwipe
+ call assert_equal('Xanother', expand('%'))
+
+ only
+
+ helptags ALL
+ help
+ wincmd w
+ 1quit
+ call assert_equal('Xanother', expand('%'))
+
+ au!
+ enew
+ bwipe! Xtestje1
+ call delete('Xtestje1')
+ call delete('Xtestje2')
+ call delete('Xtestje3')
+endfunc
+
+func Test_BufEnter()
+ au! BufEnter
+ au Bufenter * let val = val . '+'
+ let g:val = ''
+ split NewFile
+ call assert_equal('+', g:val)
+ bwipe!
+ call assert_equal('++', g:val)
+
+ " Also get BufEnter when editing a directory
+ call mkdir('Xdir')
+ split Xdir
+ call assert_equal('+++', g:val)
+
+ " On MS-Windows we can't edit the directory, make sure we wipe the right
+ " buffer.
+ bwipe! Xdir
+
+ call delete('Xdir', 'd')
+ au! BufEnter
+endfunc
+
+" Closing a window might cause an endless loop
+" E814 for older Vims
+func Test_autocmd_bufwipe_in_SessLoadPost()
+ edit Xtest
+ tabnew
+ file Xsomething
+ set noswapfile
+ mksession!
+
+ let content = ['set nocp noswapfile',
+ \ 'let v:swapchoice="e"',
+ \ 'augroup test_autocmd_sessionload',
+ \ 'autocmd!',
+ \ 'autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"',
+ \ 'augroup END',
+ \ '',
+ \ 'func WriteErrors()',
+ \ ' call writefile([execute("messages")], "Xerrors")',
+ \ 'endfunc',
+ \ 'au VimLeave * call WriteErrors()',
+ \ ]
+ call writefile(content, 'Xvimrc')
+ call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq')
+ let errors = join(readfile('Xerrors'))
+ call assert_match('E814', errors)
+
+ set swapfile
+ for file in ['Session.vim', 'Xvimrc', 'Xerrors']
+ call delete(file)
+ endfor
+endfunc
+
+" SEGV occurs in older versions.
+func Test_autocmd_bufwipe_in_SessLoadPost2()
+ tabnew
+ set noswapfile
+ mksession!
+
+ let content = ['set nocp noswapfile',
+ \ 'function! DeleteInactiveBufs()',
+ \ ' tabfirst',
+ \ ' let tabblist = []',
+ \ ' for i in range(1, tabpagenr(''$''))',
+ \ ' call extend(tabblist, tabpagebuflist(i))',
+ \ ' endfor',
+ \ ' for b in range(1, bufnr(''$''))',
+ \ ' if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')',
+ \ ' exec ''bwipeout '' . b',
+ \ ' endif',
+ \ ' endfor',
+ \ ' echomsg "SessionLoadPost DONE"',
+ \ 'endfunction',
+ \ 'au SessionLoadPost * call DeleteInactiveBufs()',
+ \ '',
+ \ 'func WriteErrors()',
+ \ ' call writefile([execute("messages")], "Xerrors")',
+ \ 'endfunc',
+ \ 'au VimLeave * call WriteErrors()',
+ \ ]
+ call writefile(content, 'Xvimrc')
+ call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq')
+ let errors = join(readfile('Xerrors'))
+ " This probably only ever matches on unix.
+ call assert_notmatch('Caught deadly signal SEGV', errors)
+ call assert_match('SessionLoadPost DONE', errors)
+
+ set swapfile
+ for file in ['Session.vim', 'Xvimrc', 'Xerrors']
+ call delete(file)
+ endfor
+endfunc
+
+func Test_empty_doau()
+ doau \|
+endfunc
+
+func s:AutoCommandOptionSet(match)
+ let item = remove(g:options, 0)
+ let expected = printf("Option: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", item[0], item[1], item[2], item[3])
+ let actual = printf("Option: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", a:match, v:option_old, v:option_new, v:option_type)
+ let g:opt = [expected, actual]
+ "call assert_equal(expected, actual)
+endfunc
+
+func Test_OptionSet()
+ throw 'skipped: Nvim does not support test_override()'
+ if !has("eval") || !has("autocmd") || !exists("+autochdir")
+ return
+ endif
+
+ call test_override('starting', 1)
+ set nocp
+ au OptionSet * :call s:AutoCommandOptionSet(expand("<amatch>"))
+
+ " 1: Setting number option"
+ let g:options=[['number', 0, 1, 'global']]
+ set nu
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 2: Setting local number option"
+ let g:options=[['number', 1, 0, 'local']]
+ setlocal nonu
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 3: Setting global number option"
+ let g:options=[['number', 1, 0, 'global']]
+ setglobal nonu
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 4: Setting local autoindent option"
+ let g:options=[['autoindent', 0, 1, 'local']]
+ setlocal ai
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 5: Setting global autoindent option"
+ let g:options=[['autoindent', 0, 1, 'global']]
+ setglobal ai
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 6: Setting global autoindent option"
+ let g:options=[['autoindent', 1, 0, 'global']]
+ set ai!
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " Should not print anything, use :noa
+ " 7: don't trigger OptionSet"
+ let g:options=[['invalid', 1, 1, 'invalid']]
+ noa set nonu
+ call assert_equal([['invalid', 1, 1, 'invalid']], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 8: Setting several global list and number option"
+ let g:options=[['list', 0, 1, 'global'], ['number', 0, 1, 'global']]
+ set list nu
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 9: don't trigger OptionSet"
+ let g:options=[['invalid', 1, 1, 'invalid'], ['invalid', 1, 1, 'invalid']]
+ noa set nolist nonu
+ call assert_equal([['invalid', 1, 1, 'invalid'], ['invalid', 1, 1, 'invalid']], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 10: Setting global acd"
+ let g:options=[['autochdir', 0, 1, 'local']]
+ setlocal acd
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 11: Setting global autoread (also sets local value)"
+ let g:options=[['autoread', 0, 1, 'global']]
+ set ar
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 12: Setting local autoread"
+ let g:options=[['autoread', 1, 1, 'local']]
+ setlocal ar
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 13: Setting global autoread"
+ let g:options=[['autoread', 1, 0, 'global']]
+ setglobal invar
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 14: Setting option backspace through :let"
+ let g:options=[['backspace', '', 'eol,indent,start', 'global']]
+ let &bs="eol,indent,start"
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 15: Setting option backspace through setbufvar()"
+ let g:options=[['backup', 0, 1, 'local']]
+ " try twice, first time, shouldn't trigger because option name is invalid,
+ " second time, it should trigger
+ call assert_fails("call setbufvar(1, '&l:bk', 1)", "E355")
+ " should trigger, use correct option name
+ call setbufvar(1, '&backup', 1)
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 16: Setting number option using setwinvar"
+ let g:options=[['number', 0, 1, 'local']]
+ call setwinvar(0, '&number', 1)
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 17: Setting key option, shouldn't trigger"
+ let g:options=[['key', 'invalid', 'invalid1', 'invalid']]
+ setlocal key=blah
+ setlocal key=
+ call assert_equal([['key', 'invalid', 'invalid1', 'invalid']], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 18: Setting string option"
+ let oldval = &tags
+ let g:options=[['tags', oldval, 'tagpath', 'global']]
+ set tags=tagpath
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " 1l: Resetting string option"
+ let g:options=[['tags', 'tagpath', oldval, 'global']]
+ set tags&
+ call assert_equal([], g:options)
+ call assert_equal(g:opt[0], g:opt[1])
+
+ " Cleanup
+ au! OptionSet
+ for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp']
+ exe printf(":set %s&vim", opt)
+ endfor
+ call test_override('starting', 0)
+ delfunc! AutoCommandOptionSet
+endfunc
+
+func Test_OptionSet_diffmode()
+ throw 'skipped: Nvim does not support test_override()'
+ call test_override('starting', 1)
+ " 18: Changing an option when enetering diff mode
+ new
+ au OptionSet diff :let &l:cul=v:option_new
+
+ call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
+ call assert_equal(0, &l:cul)
+ diffthis
+ call assert_equal(1, &l:cul)
+
+ vnew
+ call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
+ call assert_equal(0, &l:cul)
+ diffthis
+ call assert_equal(1, &l:cul)
+
+ diffoff
+ call assert_equal(0, &l:cul)
+ call assert_equal(1, getwinvar(2, '&l:cul'))
+ bw!
+
+ call assert_equal(1, &l:cul)
+ diffoff!
+ call assert_equal(0, &l:cul)
+ call assert_equal(0, getwinvar(1, '&l:cul'))
+ bw!
+
+ " Cleanup
+ au! OptionSet
+ call test_override('starting', 0)
+endfunc
+
+func Test_OptionSet_diffmode_close()
+ throw 'skipped: Nvim does not support test_override()'
+ call test_override('starting', 1)
+ " 19: Try to close the current window when entering diff mode
+ " should not segfault
+ new
+ au OptionSet diff close
+
+ call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
+ call assert_fails(':diffthis', 'E788')
+ call assert_equal(1, &diff)
+ vnew
+ call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
+ call assert_fails(':diffthis', 'E788')
+ call assert_equal(1, &diff)
+ bw!
+ call assert_fails(':diffoff!', 'E788')
+ bw!
+
+ " Cleanup
+ au! OptionSet
+ call test_override('starting', 0)
+ "delfunc! AutoCommandOptionSet
+endfunc
+
+" Test for Bufleave autocommand that deletes the buffer we are about to edit.
+func Test_BufleaveWithDelete()
+ new | edit Xfile1
+
+ augroup test_bufleavewithdelete
+ autocmd!
+ autocmd BufLeave Xfile1 bwipe Xfile2
+ augroup END
+
+ call assert_fails('edit Xfile2', 'E143:')
+ call assert_equal('Xfile1', bufname('%'))
+
+ autocmd! test_bufleavewithdelete BufLeave Xfile1
+ augroup! test_bufleavewithdelete
+
+ new
+ bwipe! Xfile1
+endfunc
+
+" Test for autocommand that changes the buffer list, when doing ":ball".
+func Test_Acmd_BufAll()
+ enew!
+ %bwipe!
+ call writefile(['Test file Xxx1'], 'Xxx1')
+ call writefile(['Test file Xxx2'], 'Xxx2')
+ call writefile(['Test file Xxx3'], 'Xxx3')
+
+ " Add three files to the buffer list
+ split Xxx1
+ close
+ split Xxx2
+ close
+ split Xxx3
+ close
+
+ " Wipe the buffer when the buffer is opened
+ au BufReadPost Xxx2 bwipe
+
+ call append(0, 'Test file Xxx4')
+ ball
+
+ call assert_equal(2, winnr('$'))
+ call assert_equal('Xxx1', bufname(winbufnr(winnr('$'))))
+ wincmd t
+
+ au! BufReadPost
+ %bwipe!
+ call delete('Xxx1')
+ call delete('Xxx2')
+ call delete('Xxx3')
+ enew! | only
+endfunc
+
+" Test for autocommand that changes current buffer on BufEnter event.
+" Check if modelines are interpreted for the correct buffer.
+func Test_Acmd_BufEnter()
+ %bwipe!
+ call writefile(['start of test file Xxx1',
+ \ "\<Tab>this is a test",
+ \ 'end of test file Xxx1'], 'Xxx1')
+ call writefile(['start of test file Xxx2',
+ \ 'vim: set noai :',
+ \ "\<Tab>this is a test",
+ \ 'end of test file Xxx2'], 'Xxx2')
+
+ au BufEnter Xxx2 brew
+ set ai modeline modelines=3
+ edit Xxx1
+ " edit Xxx2, autocmd will do :brew
+ edit Xxx2
+ exe "normal G?this is a\<CR>"
+ " Append text with autoindent to this file
+ normal othis should be auto-indented
+ call assert_equal("\<Tab>this should be auto-indented", getline('.'))
+ call assert_equal(3, line('.'))
+ " Remove autocmd and edit Xxx2 again
+ au! BufEnter Xxx2
+ buf! Xxx2
+ exe "normal G?this is a\<CR>"
+ " append text without autoindent to Xxx
+ normal othis should be in column 1
+ call assert_equal("this should be in column 1", getline('.'))
+ call assert_equal(4, line('.'))
+
+ %bwipe!
+ call delete('Xxx1')
+ call delete('Xxx2')
+ set ai&vim modeline&vim modelines&vim
+endfunc
+
+" Test for issue #57
+" do not move cursor on <c-o> when autoindent is set
+func Test_ai_CTRL_O()
+ enew!
+ set ai
+ let save_fo = &fo
+ set fo+=r
+ exe "normal o# abcdef\<Esc>2hi\<CR>\<C-O>d0\<Esc>"
+ exe "normal o# abcdef\<Esc>2hi\<C-O>d0\<Esc>"
+ call assert_equal(['# abc', 'def', 'def'], getline(2, 4))
+
+ set ai&vim
+ let &fo = save_fo
+ enew!
+endfunc
+
+" Test for autocommand that deletes the current buffer on BufLeave event.
+" Also test deleting the last buffer, should give a new, empty buffer.
+func Test_BufLeave_Wipe()
+ throw 'skipped: TODO: '
+ %bwipe!
+ let content = ['start of test file Xxx',
+ \ 'this is a test',
+ \ 'end of test file Xxx']
+ call writefile(content, 'Xxx1')
+ call writefile(content, 'Xxx2')
+
+ au BufLeave Xxx2 bwipe
+ edit Xxx1
+ split Xxx2
+ " delete buffer Xxx2, we should be back to Xxx1
+ bwipe
+ call assert_equal('Xxx1', bufname('%'))
+ call assert_equal(1, winnr('$'))
+
+ " Create an alternate buffer
+ %write! test.out
+ call assert_equal('test.out', bufname('#'))
+ " delete alternate buffer
+ bwipe test.out
+ call assert_equal('Xxx1', bufname('%'))
+ call assert_equal('', bufname('#'))
+
+ au BufLeave Xxx1 bwipe
+ " delete current buffer, get an empty one
+ bwipe!
+ call assert_equal(1, line('$'))
+ call assert_equal('', bufname('%'))
+ let g:bufinfo = getbufinfo()
+ call assert_equal(1, len(g:bufinfo))
+
+ call delete('Xxx1')
+ call delete('Xxx2')
+ call delete('test.out')
+ %bwipe
+ au! BufLeave
+
+ " check that bufinfo doesn't contain a pointer to freed memory
+ call test_garbagecollect_now()
+endfunc
+
+func Test_QuitPre()
+ edit Xfoo
+ let winid = win_getid(winnr())
+ split Xbar
+ au! QuitPre * let g:afile = expand('<afile>')
+ " Close the other window, <afile> should be correct.
+ exe win_id2win(winid) . 'q'
+ call assert_equal('Xfoo', g:afile)
+
+ unlet g:afile
+ bwipe Xfoo
+ bwipe Xbar
+endfunc
+
+func Test_Cmdline()
+ au! CmdlineChanged : let g:text = getcmdline()
+ let g:text = 0
+ call feedkeys(":echom 'hello'\<CR>", 'xt')
+ call assert_equal("echom 'hello'", g:text)
+ au! CmdlineChanged
+
+ au! CmdlineChanged : let g:entered = expand('<afile>')
+ let g:entered = 0
+ call feedkeys(":echom 'hello'\<CR>", 'xt')
+ call assert_equal(':', g:entered)
+ au! CmdlineChanged
+
+ au! CmdlineEnter : let g:entered = expand('<afile>')
+ au! CmdlineLeave : let g:left = expand('<afile>')
+ let g:entered = 0
+ let g:left = 0
+ call feedkeys(":echo 'hello'\<CR>", 'xt')
+ call assert_equal(':', g:entered)
+ call assert_equal(':', g:left)
+ au! CmdlineEnter
+ au! CmdlineLeave
+
+ let save_shellslash = &shellslash
+ set noshellslash
+ au! CmdlineEnter / let g:entered = expand('<afile>')
+ au! CmdlineLeave / let g:left = expand('<afile>')
+ let g:entered = 0
+ let g:left = 0
+ new
+ call setline(1, 'hello')
+ call feedkeys("/hello\<CR>", 'xt')
+ call assert_equal('/', g:entered)
+ call assert_equal('/', g:left)
+ bwipe!
+ au! CmdlineEnter
+ au! CmdlineLeave
+ let &shellslash = save_shellslash
+endfunc
+
+" Test for BufWritePre autocommand that deletes or unloads the buffer.
+func Test_BufWritePre()
+ %bwipe
+ au BufWritePre Xxx1 bunload
+ au BufWritePre Xxx2 bwipe
+
+ call writefile(['start of Xxx1', 'test', 'end of Xxx1'], 'Xxx1')
+ call writefile(['start of Xxx2', 'test', 'end of Xxx2'], 'Xxx2')
+
+ edit Xtest
+ e! Xxx2
+ bdel Xtest
+ e Xxx1
+ " write it, will unload it and give an error msg
+ call assert_fails('w', 'E203')
+ call assert_equal('Xxx2', bufname('%'))
+ edit Xtest
+ e! Xxx2
+ bwipe Xtest
+ " write it, will delete the buffer and give an error msg
+ call assert_fails('w', 'E203')
+ call assert_equal('Xxx1', bufname('%'))
+ au! BufWritePre
+ call delete('Xxx1')
+ call delete('Xxx2')
+endfunc
+
+" Test for BufUnload autocommand that unloads all the other buffers
+func Test_bufunload_all()
+ call writefile(['Test file Xxx1'], 'Xxx1')"
+ call writefile(['Test file Xxx2'], 'Xxx2')"
+
+ let content = [
+ \ "func UnloadAllBufs()",
+ \ " let i = 1",
+ \ " while i <= bufnr('$')",
+ \ " if i != bufnr('%') && bufloaded(i)",
+ \ " exe i . 'bunload'",
+ \ " endif",
+ \ " let i += 1",
+ \ " endwhile",
+ \ "endfunc",
+ \ "au BufUnload * call UnloadAllBufs()",
+ \ "au VimLeave * call writefile(['Test Finished'], 'Xout')",
+ \ "edit Xxx1",
+ \ "split Xxx2",
+ \ "q"]
+ call writefile(content, 'Xtest')
+
+ call delete('Xout')
+ call system(v:progpath. ' -u NORC -i NONE -N -S Xtest')
+ call assert_true(filereadable('Xout'))
+
+ call delete('Xxx1')
+ call delete('Xxx2')
+ call delete('Xtest')
+ call delete('Xout')
+endfunc
+
+" Some tests for buffer-local autocommands
+func Test_buflocal_autocmd()
+ let g:bname = ''
+ edit xx
+ au BufLeave <buffer> let g:bname = expand("%")
+ " here, autocommand for xx should trigger.
+ " but autocommand shall not apply to buffer named <buffer>.
+ edit somefile
+ call assert_equal('xx', g:bname)
+ let g:bname = ''
+ " here, autocommand shall be auto-deleted
+ bwipe xx
+ " autocmd should not trigger
+ edit xx
+ call assert_equal('', g:bname)
+ " autocmd should not trigger
+ edit somefile
+ call assert_equal('', g:bname)
+ enew
+ unlet g:bname
+endfunc
+
+" Test for "*Cmd" autocommands
+func Test_Cmd_Autocmds()
+ call writefile(['start of Xxx', "\tabc2", 'end of Xxx'], 'Xxx')
+
+ enew!
+ au BufReadCmd XtestA 0r Xxx|$del
+ edit XtestA " will read text of Xxd instead
+ call assert_equal('start of Xxx', getline(1))
+
+ au BufWriteCmd XtestA call append(line("$"), "write")
+ write " will append a line to the file
+ call assert_equal('write', getline('$'))
+ call assert_fails('read XtestA', 'E484') " should not read anything
+ call assert_equal('write', getline(4))
+
+ " now we have:
+ " 1 start of Xxx
+ " 2 abc2
+ " 3 end of Xxx
+ " 4 write
+
+ au FileReadCmd XtestB '[r Xxx
+ 2r XtestB " will read Xxx below line 2 instead
+ call assert_equal('start of Xxx', getline(3))
+
+ " now we have:
+ " 1 start of Xxx
+ " 2 abc2
+ " 3 start of Xxx
+ " 4 abc2
+ " 5 end of Xxx
+ " 6 end of Xxx
+ " 7 write
+
+ au FileWriteCmd XtestC '[,']copy $
+ normal 4GA1
+ 4,5w XtestC " will copy lines 4 and 5 to the end
+ call assert_equal("\tabc21", getline(8))
+ call assert_fails('r XtestC', 'E484') " should not read anything
+ call assert_equal("end of Xxx", getline(9))
+
+ " now we have:
+ " 1 start of Xxx
+ " 2 abc2
+ " 3 start of Xxx
+ " 4 abc21
+ " 5 end of Xxx
+ " 6 end of Xxx
+ " 7 write
+ " 8 abc21
+ " 9 end of Xxx
+
+ let g:lines = []
+ au FileAppendCmd XtestD call extend(g:lines, getline(line("'["), line("']")))
+ w >>XtestD " will add lines to 'lines'
+ call assert_equal(9, len(g:lines))
+ call assert_fails('$r XtestD', 'E484') " should not read anything
+ call assert_equal(9, line('$'))
+ call assert_equal('end of Xxx', getline('$'))
+
+ au BufReadCmd XtestE 0r Xxx|$del
+ sp XtestE " split window with test.out
+ call assert_equal('end of Xxx', getline(3))
+
+ let g:lines = []
+ exe "normal 2Goasdf\<Esc>\<C-W>\<C-W>"
+ au BufWriteCmd XtestE call extend(g:lines, getline(0, '$'))
+ wall " will write other window to 'lines'
+ call assert_equal(4, len(g:lines), g:lines)
+ call assert_equal("\tasdf", g:lines[2])
+
+ au! BufReadCmd
+ au! BufWriteCmd
+ au! FileReadCmd
+ au! FileWriteCmd
+ au! FileAppendCmd
+ %bwipe!
+ call delete('Xxx')
+ enew!
+endfunc
+
+func SetChangeMarks(start, end)
+ exe a:start. 'mark ['
+ exe a:end. 'mark ]'
+endfunc
+
+" Verify the effects of autocmds on '[ and ']
+func Test_change_mark_in_autocmds()
+ edit! Xtest
+ call feedkeys("ia\<CR>b\<CR>c\<CR>d\<C-g>u", 'xtn')
+
+ call SetChangeMarks(2, 3)
+ write
+ call assert_equal([1, 4], [line("'["), line("']")])
+
+ call SetChangeMarks(2, 3)
+ au BufWritePre * call assert_equal([1, 4], [line("'["), line("']")])
+ write
+ au! BufWritePre
+
+ if executable('cat')
+ write XtestFilter
+ write >> XtestFilter
+
+ call SetChangeMarks(2, 3)
+ " Marks are set to the entire range of the write
+ au FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")])
+ " '[ is adjusted to just before the line that will receive the filtered
+ " data
+ au FilterReadPre * call assert_equal([4, 4], [line("'["), line("']")])
+ " The filtered data is read into the buffer, and the source lines are
+ " still present, so the range is after the source lines
+ au FilterReadPost * call assert_equal([5, 12], [line("'["), line("']")])
+ %!cat XtestFilter
+ " After the filtered data is read, the original lines are deleted
+ call assert_equal([1, 8], [line("'["), line("']")])
+ au! FilterWritePre,FilterReadPre,FilterReadPost
+ undo
+
+ call SetChangeMarks(1, 4)
+ au FilterWritePre * call assert_equal([2, 3], [line("'["), line("']")])
+ au FilterReadPre * call assert_equal([3, 3], [line("'["), line("']")])
+ au FilterReadPost * call assert_equal([4, 11], [line("'["), line("']")])
+ 2,3!cat XtestFilter
+ call assert_equal([2, 9], [line("'["), line("']")])
+ au! FilterWritePre,FilterReadPre,FilterReadPost
+ undo
+
+ call delete('XtestFilter')
+ endif
+
+ call SetChangeMarks(1, 4)
+ au FileWritePre * call assert_equal([2, 3], [line("'["), line("']")])
+ 2,3write Xtest2
+ au! FileWritePre
+
+ call SetChangeMarks(2, 3)
+ au FileAppendPre * call assert_equal([1, 4], [line("'["), line("']")])
+ write >> Xtest2
+ au! FileAppendPre
+
+ call SetChangeMarks(1, 4)
+ au FileAppendPre * call assert_equal([2, 3], [line("'["), line("']")])
+ 2,3write >> Xtest2
+ au! FileAppendPre
+
+ call SetChangeMarks(1, 1)
+ au FileReadPre * call assert_equal([3, 1], [line("'["), line("']")])
+ au FileReadPost * call assert_equal([4, 11], [line("'["), line("']")])
+ 3read Xtest2
+ au! FileReadPre,FileReadPost
+ undo
+
+ call SetChangeMarks(4, 4)
+ " When the line is 0, it's adjusted to 1
+ au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
+ au FileReadPost * call assert_equal([1, 8], [line("'["), line("']")])
+ 0read Xtest2
+ au! FileReadPre,FileReadPost
+ undo
+
+ call SetChangeMarks(4, 4)
+ " When the line is 0, it's adjusted to 1
+ au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
+ au FileReadPost * call assert_equal([2, 9], [line("'["), line("']")])
+ 1read Xtest2
+ au! FileReadPre,FileReadPost
+ undo
+
+ bwipe!
+ call delete('Xtest')
+ call delete('Xtest2')
+endfunc
+
+func Test_Filter_noshelltemp()
+ if !executable('cat')
+ return
+ endif
+
+ enew!
+ call setline(1, ['a', 'b', 'c', 'd'])
+
+ let shelltemp = &shelltemp
+ set shelltemp
+
+ let g:filter_au = 0
+ au FilterWritePre * let g:filter_au += 1
+ au FilterReadPre * let g:filter_au += 1
+ au FilterReadPost * let g:filter_au += 1
+ %!cat
+ call assert_equal(3, g:filter_au)
+
+ if has('filterpipe')
+ set noshelltemp
+
+ let g:filter_au = 0
+ au FilterWritePre * let g:filter_au += 1
+ au FilterReadPre * let g:filter_au += 1
+ au FilterReadPost * let g:filter_au += 1
+ %!cat
+ call assert_equal(0, g:filter_au)
+ endif
+
+ au! FilterWritePre,FilterReadPre,FilterReadPost
+ let &shelltemp = shelltemp
+ bwipe!
+endfunc
+
+func Test_TextYankPost()
+ enew!
+ call setline(1, ['foo'])
+
+ let g:event = []
+ au TextYankPost * let g:event = copy(v:event)
+
+ call assert_equal({}, v:event)
+ call assert_fails('let v:event = {}', 'E46:')
+ call assert_fails('let v:event.mykey = 0', 'E742:')
+
+ norm "ayiw
+ call assert_equal(
+ \{'regcontents': ['foo'], 'regname': 'a', 'operator': 'y', 'regtype': 'v'},
+ \g:event)
+ norm y_
+ call assert_equal(
+ \{'regcontents': ['foo'], 'regname': '', 'operator': 'y', 'regtype': 'V'},
+ \g:event)
+ call feedkeys("\<C-V>y", 'x')
+ call assert_equal(
+ \{'regcontents': ['f'], 'regname': '', 'operator': 'y', 'regtype': "\x161"},
+ \g:event)
+ norm "xciwbar
+ call assert_equal(
+ \{'regcontents': ['foo'], 'regname': 'x', 'operator': 'c', 'regtype': 'v'},
+ \g:event)
+ norm "bdiw
+ call assert_equal(
+ \{'regcontents': ['bar'], 'regname': 'b', 'operator': 'd', 'regtype': 'v'},
+ \g:event)
+
+ call assert_equal({}, v:event)
+
+ au! TextYankPost
+ unlet g:event
+ bwipe!
+endfunc
+
+func Test_nocatch_wipe_all_buffers()
+ " Real nasty autocommand: wipe all buffers on any event.
+ au * * bwipe *
+ call assert_fails('next x', 'E93')
+ bwipe
+ au!
+endfunc
+
+func Test_nocatch_wipe_dummy_buffer()
+ " Nasty autocommand: wipe buffer on any event.
+ au * x bwipe
+ call assert_fails('lv½ /x', 'E480')
+ au!
+endfunc
+
+func Test_wipe_cbuffer()
+ sv x
+ au * * bw
+ lb
+ au!
+endfunc
+
+" Test TextChangedI and TextChangedP
+func Test_ChangedP()
+ " Nvim does not support test_override().
+ throw 'skipped: see test/functional/viml/completion_spec.lua'
+ new
+ call setline(1, ['foo', 'bar', 'foobar'])
+ call test_override("char_avail", 1)
+ set complete=. completeopt=menuone
+
+ func! TextChangedAutocmd(char)
+ let g:autocmd .= a:char
+ endfunc
+
+ au! TextChanged <buffer> :call TextChangedAutocmd('N')
+ au! TextChangedI <buffer> :call TextChangedAutocmd('I')
+ au! TextChangedP <buffer> :call TextChangedAutocmd('P')
+
+ call cursor(3, 1)
+ let g:autocmd = ''
+ call feedkeys("o\<esc>", 'tnix')
+ call assert_equal('I', g:autocmd)
+
+ let g:autocmd = ''
+ call feedkeys("Sf", 'tnix')
+ call assert_equal('II', g:autocmd)
+
+ let g:autocmd = ''
+ call feedkeys("Sf\<C-N>", 'tnix')
+ call assert_equal('IIP', g:autocmd)
+
+ let g:autocmd = ''
+ call feedkeys("Sf\<C-N>\<C-N>", 'tnix')
+ call assert_equal('IIPP', g:autocmd)
+
+ let g:autocmd = ''
+ call feedkeys("Sf\<C-N>\<C-N>\<C-N>", 'tnix')
+ call assert_equal('IIPPP', g:autocmd)
+
+ let g:autocmd = ''
+ call feedkeys("Sf\<C-N>\<C-N>\<C-N>\<C-N>", 'tnix')
+ call assert_equal('IIPPPP', g:autocmd)
+
+ call assert_equal(['foo', 'bar', 'foobar', 'foo'], getline(1, '$'))
+ " TODO: how should it handle completeopt=noinsert,noselect?
+
+ " CleanUp
+ call test_override("char_avail", 0)
+ au! TextChanged
+ au! TextChangedI
+ au! TextChangedP
+ delfu TextChangedAutocmd
+ unlet! g:autocmd
+ set complete&vim completeopt&vim
+
+ bw!
+endfunc
+
+let g:setline_handled = v:false
+func! SetLineOne()
+ if !g:setline_handled
+ call setline(1, "(x)")
+ let g:setline_handled = v:true
+ endif
+endfunc
+
+func Test_TextChangedI_with_setline()
+ throw 'skipped: Nvim does not support test_override()'
+ new
+ call test_override('char_avail', 1)
+ autocmd TextChangedI <buffer> call SetLineOne()
+ call feedkeys("i(\<CR>\<Esc>", 'tx')
+ call assert_equal('(', getline(1))
+ call assert_equal('x)', getline(2))
+ undo
+ call assert_equal('', getline(1))
+ call assert_equal('', getline(2))
+
+ call test_override('starting', 0)
+ bwipe!
+endfunc
+
+func Test_Changed_FirstTime()
+ if !has('terminal') || has('gui_running')
+ return
+ endif
+ " Prepare file for TextChanged event.
+ call writefile([''], 'Xchanged.txt')
+ let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
+ call assert_equal('running', term_getstatus(buf))
+ " It's only adding autocmd, so that no event occurs.
+ call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>")
+ call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
+ call WaitFor({-> term_getstatus(buf) == 'finished'})
+ call assert_equal([''], readfile('Xchanged.txt'))
+
+ " clean up
+ call delete('Xchanged.txt')
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_autoload.vim b/src/nvim/testdir/test_autoload.vim
new file mode 100644
index 0000000000..7396c227c9
--- /dev/null
+++ b/src/nvim/testdir/test_autoload.vim
@@ -0,0 +1,17 @@
+" Tests for autoload
+
+set runtimepath=./sautest
+
+func Test_autoload_dict_func()
+ let g:loaded_foo_vim = 0
+ let g:called_foo_bar_echo = 0
+ call g:foo#bar.echo()
+ call assert_equal(1, g:loaded_foo_vim)
+ call assert_equal(1, g:called_foo_bar_echo)
+endfunc
+
+func Test_source_autoload()
+ let g:loaded_sourced_vim = 0
+ source sautest/autoload/sourced.vim
+ call assert_equal(1, g:loaded_sourced_vim)
+endfunc
diff --git a/src/nvim/testdir/test_behave.vim b/src/nvim/testdir/test_behave.vim
new file mode 100644
index 0000000000..c26bfe7ce3
--- /dev/null
+++ b/src/nvim/testdir/test_behave.vim
@@ -0,0 +1,29 @@
+" Test the :behave command
+
+func Test_behave()
+ behave mswin
+ call assert_equal('mouse,key', &selectmode)
+ call assert_equal('popup', &mousemodel)
+ call assert_equal('startsel,stopsel', &keymodel)
+ call assert_equal('exclusive', &selection)
+
+ behave xterm
+ call assert_equal('', &selectmode)
+ call assert_equal('extend', &mousemodel)
+ call assert_equal('', &keymodel)
+ call assert_equal('inclusive', &selection)
+
+ set selection&
+ set mousemodel&
+ set keymodel&
+ set selection&
+endfunc
+
+func Test_behave_completion()
+ call feedkeys(":behave \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"behave mswin xterm', @:)
+endfunc
+
+func Test_behave_error()
+ call assert_fails('behave x', 'E475:')
+endfunc
diff --git a/src/nvim/testdir/test_blockedit.vim b/src/nvim/testdir/test_blockedit.vim
new file mode 100644
index 0000000000..527224ccd2
--- /dev/null
+++ b/src/nvim/testdir/test_blockedit.vim
@@ -0,0 +1,33 @@
+" Test for block inserting
+"
+" TODO: rewrite test39.in into this new style test
+
+func Test_blockinsert_indent()
+ new
+ filetype plugin indent on
+ setlocal sw=2 et ft=vim
+ call setline(1, ['let a=[', ' ''eins'',', ' ''zwei'',', ' ''drei'']'])
+ call cursor(2, 3)
+ exe "norm! \<c-v>2jI\\ \<esc>"
+ call assert_equal(['let a=[', ' \ ''eins'',', ' \ ''zwei'',', ' \ ''drei'']'],
+ \ getline(1,'$'))
+ " reset to sane state
+ filetype off
+ bwipe!
+endfunc
+
+func Test_blockinsert_delete()
+ new
+ let _bs = &bs
+ set bs=2
+ call setline(1, ['case Arg is ', ' when Name_Async,', ' when Name_Num_Gangs,', 'end if;'])
+ exe "norm! ggjVj\<c-v>$o$A\<bs>\<esc>"
+ "call feedkeys("Vj\<c-v>$o$A\<bs>\<esc>", 'ti')
+ call assert_equal(["case Arg is ", " when Name_Async", " when Name_Num_Gangs,", "end if;"],
+ \ getline(1,'$'))
+ " reset to sane state
+ let &bs = _bs
+ bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim
new file mode 100644
index 0000000000..7deffbe452
--- /dev/null
+++ b/src/nvim/testdir/test_breakindent.vim
@@ -0,0 +1,298 @@
+" Test for breakindent
+"
+" Note: if you get strange failures when adding new tests, it might be that
+" while the test is run, the breakindent cacheing gets in its way.
+" It helps to change the tabstop setting and force a redraw (e.g. see
+" Test_breakindent08())
+if !exists('+breakindent')
+ finish
+endif
+
+source view_util.vim
+
+let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP"
+
+function s:screen_lines(lnum, width) abort
+ return ScreenLines([a:lnum, a:lnum + 2], a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+ call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
+endfunction
+
+function s:test_windows(...)
+ call NewWindow(10, 20)
+ setl ts=4 sw=4 sts=4 breakindent
+ put =s:input
+ exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+ call CloseWindow()
+ exe get(a:000, 0, '')
+endfunction
+
+function Test_breakindent01()
+ " simple breakindent test
+ call s:test_windows('setl briopt=min:0')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " qrst",
+\ " GHIJ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent02()
+ " simple breakindent test with showbreak set
+ call s:test_windows('setl briopt=min:0 sbr=>>')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " >>qr",
+\ " >>EF",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent03()
+ " simple breakindent test with showbreak set and briopt including sbr
+ call s:test_windows('setl briopt=sbr,min:0 sbr=++')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ "++ qrst",
+\ "++ GHIJ",
+\ ]
+ call s:compare_lines(expect, lines)
+ " clean up
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent04()
+ " breakindent set with min width 18
+ call s:test_windows('setl sbr= briopt=min:18')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " qrstuv",
+\ " IJKLMN",
+\ ]
+ call s:compare_lines(expect, lines)
+ " clean up
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent05()
+ " breakindent set and shift by 2
+ call s:test_windows('setl briopt=shift:2,min:0')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " qr",
+\ " EF",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent06()
+ " breakindent set and shift by -1
+ call s:test_windows('setl briopt=shift:-1,min:0')
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ " abcd",
+\ " qrstu",
+\ " HIJKL",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent07()
+ " breakindent set and shift by 1, Number set sbr=? and briopt:sbr
+ call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n')
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ab",
+\ "? m",
+\ "? x",
+\ ]
+ call s:compare_lines(expect, lines)
+ " clean up
+ call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function Test_breakindent07a()
+ " breakindent set and shift by 1, Number set sbr=? and briopt:sbr
+ call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4')
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ab",
+\ " ? m",
+\ " ? x",
+\ ]
+ call s:compare_lines(expect, lines)
+ " clean up
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent08()
+ " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
+ call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4')
+ " make sure, cache is invalidated!
+ set ts=8
+ redraw!
+ set ts=4
+ redraw!
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ^Iabcd",
+\ "# opq",
+\ "# BCD",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function Test_breakindent08a()
+ " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr
+ call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list')
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ^Iabcd",
+\ " # opq",
+\ " # BCD",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent09()
+ " breakindent set and shift by 1, Number and list set sbr=#
+ call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list')
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ^Iabcd",
+\ " #op",
+\ " #AB",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent10()
+ " breakindent set, Number set sbr=~
+ call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0')
+ " make sure, cache is invalidated!
+ set ts=8
+ redraw!
+ set ts=4
+ redraw!
+ let lines=s:screen_lines(line('.'),10)
+ let expect=[
+\ " 2 ab",
+\ "~ mn",
+\ "~ yz",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set sbr= cpo-=n')
+endfunction
+
+function Test_breakindent11()
+ " test strdisplaywidth()
+ call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4')
+ let text=getline(2)
+ let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times
+ call assert_equal(width, strdisplaywidth(text))
+ call s:close_windows('set sbr=')
+endfunction
+
+function Test_breakindent12()
+ " test breakindent with long indent
+ let s:input="\t\t\t\t\t{"
+ call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-')
+ let lines=s:screen_lines(2,16)
+ let expect=[
+\ " 2 >--->--->--->",
+\ " ---{ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('set nuw=4 listchars=')
+endfunction
+
+function Test_breakindent13()
+ let s:input=""
+ call s:test_windows('setl breakindent briopt=min:10 ts=8')
+ vert resize 20
+ call setline(1, [" a\tb\tc\td\te", " z y x w v"])
+ 1
+ norm! fbgj"ayl
+ 2
+ norm! fygj"byl
+ call assert_equal('d', @a)
+ call assert_equal('w', @b)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent14()
+ let s:input=""
+ call s:test_windows('setl breakindent briopt= ts=8')
+ vert resize 30
+ norm! 3a1234567890
+ norm! a abcde
+ exec "norm! 0\<C-V>tex"
+ let lines=s:screen_lines(line('.'),8)
+ let expect=[
+\ "e ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent15()
+ let s:input=""
+ call s:test_windows('setl breakindent briopt= ts=8 sw=8')
+ vert resize 30
+ norm! 4a1234567890
+ exe "normal! >>\<C-V>3f0x"
+ let lines=s:screen_lines(line('.'),20)
+ let expect=[
+\ " 1234567890 ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
+
+function Test_breakindent16()
+ " Check that overlong lines are indented correctly.
+ let s:input=""
+ call s:test_windows('setl breakindent briopt=min:0 ts=4')
+ call setline(1, "\t".repeat("1234567890", 10))
+ resize 6
+ norm! 1gg$
+ redraw!
+ let lines=s:screen_lines(1,10)
+ let expect=[
+\ " 789012",
+\ " 345678",
+\ " 901234",
+\ ]
+ call s:compare_lines(expect, lines)
+ let lines=s:screen_lines(4,10)
+ let expect=[
+\ " 567890",
+\ " 123456",
+\ " 7890 ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunction
diff --git a/src/nvim/testdir/test_bufwintabinfo.vim b/src/nvim/testdir/test_bufwintabinfo.vim
new file mode 100644
index 0000000000..a6b4524cc0
--- /dev/null
+++ b/src/nvim/testdir/test_bufwintabinfo.vim
@@ -0,0 +1,133 @@
+" Tests for the getbufinfo(), getwininfo() and gettabinfo() functions
+
+function Test_getbufwintabinfo()
+ edit Xtestfile1
+ edit Xtestfile2
+ let buflist = getbufinfo()
+ call assert_equal(2, len(buflist))
+ call assert_match('Xtestfile1', buflist[0].name)
+ call assert_match('Xtestfile2', getbufinfo('Xtestfile2')[0].name)
+ call assert_equal([], getbufinfo(2016))
+ edit Xtestfile1
+ hide edit Xtestfile2
+ hide enew
+ call assert_equal(3, len(getbufinfo({'bufloaded':1})))
+
+ set tabstop&vim
+ let b:editor = 'vim'
+ let l = getbufinfo('%')
+ call assert_equal(bufnr('%'), l[0].bufnr)
+ call assert_equal('vim', l[0].variables.editor)
+ call assert_notequal(-1, index(l[0].windows, bufwinid('%')))
+
+ if has('signs')
+ call append(0, ['Linux', 'Windows', 'Mac'])
+ sign define Mark text=>> texthl=Search
+ exe "sign place 2 line=3 name=Mark buffer=" . bufnr('%')
+ let l = getbufinfo('%')
+ call assert_equal(2, l[0].signs[0].id)
+ call assert_equal(3, l[0].signs[0].lnum)
+ call assert_equal('Mark', l[0].signs[0].name)
+ sign unplace *
+ sign undefine Mark
+ enew!
+ endif
+
+ only
+ let w1_id = win_getid()
+ new
+ let w2_id = win_getid()
+ tabnew | let w3_id = win_getid()
+ new | let w4_id = win_getid()
+ vert new | let w5_id = win_getid()
+ call setwinvar(0, 'signal', 'green')
+ tabfirst
+ let winlist = getwininfo()
+ call assert_equal(5, len(winlist))
+ call assert_equal(winwidth(1), winlist[0].width)
+ call assert_equal(0, winlist[0].wincol)
+ let tablineheight = winlist[0].winrow == 1 ? 1 : 0
+ call assert_equal(tablineheight, winlist[0].winrow) " tabline adds one
+
+ call assert_equal(winbufnr(2), winlist[1].bufnr)
+ call assert_equal(winheight(2), winlist[1].height)
+ call assert_equal(0, winlist[1].wincol)
+ call assert_equal(tablineheight + winheight(1) + 1, winlist[1].winrow)
+
+ call assert_equal(1, winlist[2].winnr)
+ call assert_equal(tablineheight, winlist[2].winrow)
+ call assert_equal(0, winlist[2].wincol)
+
+ call assert_equal(winlist[2].width + 1, winlist[3].wincol)
+ call assert_equal(0, winlist[4].wincol)
+
+ call assert_equal(1, winlist[0].tabnr)
+ call assert_equal(1, winlist[1].tabnr)
+ call assert_equal(2, winlist[2].tabnr)
+ call assert_equal(2, winlist[3].tabnr)
+ call assert_equal(2, winlist[4].tabnr)
+
+ call assert_equal('green', winlist[2].variables.signal)
+ call assert_equal(w4_id, winlist[3].winid)
+ let winfo = getwininfo(w5_id)[0]
+ call assert_equal(2, winfo.tabnr)
+ call assert_equal([], getwininfo(3))
+
+ call settabvar(1, 'space', 'build')
+ let tablist = gettabinfo()
+ call assert_equal(2, len(tablist))
+ call assert_equal(3, len(tablist[1].windows))
+ call assert_equal(2, tablist[1].tabnr)
+ call assert_equal('build', tablist[0].variables.space)
+ call assert_equal(w2_id, tablist[0].windows[0])
+ call assert_equal([], gettabinfo(3))
+
+ tabonly | only
+
+ lexpr ''
+ lopen
+ copen
+ let winlist = getwininfo()
+ call assert_false(winlist[0].quickfix)
+ call assert_false(winlist[0].loclist)
+ call assert_true(winlist[1].quickfix)
+ call assert_true(winlist[1].loclist)
+ call assert_true(winlist[2].quickfix)
+ call assert_false(winlist[2].loclist)
+ wincmd t | only
+endfunction
+
+function Test_get_buf_options()
+ let opts = getbufvar(bufnr('%'), '&')
+ call assert_equal(v:t_dict, type(opts))
+ call assert_equal(8, opts.tabstop)
+endfunc
+
+function Test_get_win_options()
+ if has('folding')
+ set foldlevel=999
+ endif
+ set list
+ let opts = getwinvar(1, '&')
+ call assert_equal(v:t_dict, type(opts))
+ call assert_equal(0, opts.linebreak)
+ call assert_equal(1, opts.list)
+ if has('folding')
+ call assert_equal(999, opts.foldlevel)
+ endif
+ if has('signs')
+ call assert_equal('auto', opts.signcolumn)
+ endif
+
+ let opts = gettabwinvar(1, 1, '&')
+ call assert_equal(v:t_dict, type(opts))
+ call assert_equal(0, opts.linebreak)
+ call assert_equal(1, opts.list)
+ if has('signs')
+ call assert_equal('auto', opts.signcolumn)
+ endif
+ set list&
+ if has('folding')
+ set foldlevel=0
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_cd.vim b/src/nvim/testdir/test_cd.vim
new file mode 100644
index 0000000000..770ed55b8d
--- /dev/null
+++ b/src/nvim/testdir/test_cd.vim
@@ -0,0 +1,67 @@
+" Test for :cd
+
+func Test_cd_large_path()
+ " This used to crash with a heap write overflow.
+ call assert_fails('cd ' . repeat('x', 5000), 'E472:')
+endfunc
+
+func Test_cd_up_and_down()
+ let path = getcwd()
+ cd ..
+ call assert_notequal(path, getcwd())
+ exe 'cd ' . path
+ call assert_equal(path, getcwd())
+endfunc
+
+func Test_cd_no_arg()
+ if has('unix')
+ " Test that cd without argument goes to $HOME directory on Unix systems.
+ let path = getcwd()
+ cd
+ call assert_equal($HOME, getcwd())
+ call assert_notequal(path, getcwd())
+ exe 'cd ' . path
+ call assert_equal(path, getcwd())
+ else
+ " Test that cd without argument echoes cwd on non-Unix systems.
+ call assert_match(getcwd(), execute('cd'))
+ endif
+endfunc
+
+func Test_cd_minus()
+ " Test the :cd - goes back to the previous directory.
+ let path = getcwd()
+ cd ..
+ let path_dotdot = getcwd()
+ call assert_notequal(path, path_dotdot)
+ cd -
+ call assert_equal(path, getcwd())
+ cd -
+ call assert_equal(path_dotdot, getcwd())
+ cd -
+ call assert_equal(path, getcwd())
+endfunc
+
+func Test_cd_with_cpo_chdir()
+ e Xfoo
+ call setline(1, 'foo')
+ let path = getcwd()
+ " set cpo+=.
+
+ " :cd should fail when buffer is modified and 'cpo' contains dot.
+ " call assert_fails('cd ..', 'E747:')
+ call assert_equal(path, getcwd())
+
+ " :cd with exclamation mark should succeed.
+ cd! ..
+ call assert_notequal(path, getcwd())
+
+ " :cd should succeed when buffer has been written.
+ w!
+ exe 'cd ' . path
+ call assert_equal(path, getcwd())
+
+ call delete('Xfoo')
+ set cpo&
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_changedtick.vim b/src/nvim/testdir/test_changedtick.vim
new file mode 100644
index 0000000000..3a91bb54aa
--- /dev/null
+++ b/src/nvim/testdir/test_changedtick.vim
@@ -0,0 +1,57 @@
+" Tests for b:changedtick
+
+func Test_changedtick_increments()
+ new
+ " New buffer has an empty line, tick starts at 2.
+ let expected = 2
+ call assert_equal(expected, b:changedtick)
+ call assert_equal(expected, b:['changedtick'])
+ call setline(1, 'hello')
+ let expected += 1
+ call assert_equal(expected, b:changedtick)
+ call assert_equal(expected, b:['changedtick'])
+ undo
+ " Somehow undo counts as two changes.
+ let expected += 2
+ call assert_equal(expected, b:changedtick)
+ call assert_equal(expected, b:['changedtick'])
+ bwipe!
+endfunc
+
+func Test_changedtick_dict_entry()
+ let d = b:
+ call assert_equal(b:changedtick, d['changedtick'])
+endfunc
+
+func Test_changedtick_bdel()
+ new
+ let bnr = bufnr('%')
+ let v = b:changedtick
+ bdel
+ " Delete counts as a change too.
+ call assert_equal(v + 1, getbufvar(bnr, 'changedtick'))
+endfunc
+
+func Test_changedtick_islocked()
+ call assert_equal(0, islocked('b:changedtick'))
+ let d = b:
+ call assert_equal(0, islocked('d.changedtick'))
+endfunc
+
+func Test_changedtick_fixed()
+ call assert_fails('let b:changedtick = 4', 'E46:')
+ call assert_fails('let b:["changedtick"] = 4', 'E46:')
+
+ call assert_fails('lockvar b:changedtick', 'E940:')
+ call assert_fails('lockvar b:["changedtick"]', 'E46:')
+ call assert_fails('unlockvar b:changedtick', 'E940:')
+ call assert_fails('unlockvar b:["changedtick"]', 'E46:')
+ call assert_fails('unlet b:changedtick', 'E795:')
+ call assert_fails('unlet b:["changedtick"]', 'E46:')
+
+ let d = b:
+ call assert_fails('lockvar d["changedtick"]', 'E46:')
+ call assert_fails('unlockvar d["changedtick"]', 'E46:')
+ call assert_fails('unlet d["changedtick"]', 'E46:')
+
+endfunc
diff --git a/src/nvim/testdir/test_charsearch.vim b/src/nvim/testdir/test_charsearch.vim
new file mode 100644
index 0000000000..8b313b5a35
--- /dev/null
+++ b/src/nvim/testdir/test_charsearch.vim
@@ -0,0 +1,62 @@
+
+function! Test_charsearch()
+ enew!
+ call append(0, ['Xabcdefghijkemnopqretuvwxyz',
+ \ 'Yabcdefghijkemnopqretuvwxyz',
+ \ 'Zabcdefghijkemnokqretkvwxyz'])
+ " check that "fe" and ";" work
+ 1
+ normal! ylfep;;p,,p
+ call assert_equal('XabcdeXfghijkeXmnopqreXtuvwxyz', getline(1))
+ " check that save/restore works
+ 2
+ normal! ylfep
+ let csave = getcharsearch()
+ normal! fip
+ call setcharsearch(csave)
+ normal! ;p;p
+ call assert_equal('YabcdeYfghiYjkeYmnopqreYtuvwxyz', getline(2))
+
+ " check that setcharsearch() changes the settings.
+ 3
+ normal! ylfep
+ call setcharsearch({'char': 'k'})
+ normal! ;p
+ call setcharsearch({'forward': 0})
+ normal! $;p
+ call setcharsearch({'until': 1})
+ set cpo-=;
+ normal! ;;p
+ call assert_equal('ZabcdeZfghijkZZemnokqretkZvwxyz', getline(3))
+ enew!
+endfunction
+
+" Test for t,f,F,T movement commands and 'cpo-;' setting
+function! Test_search_cmds()
+ enew!
+ call append(0, ["aaa two three four", " zzz", "yyy ",
+ \ "bbb yee yoo four", "ccc two three four",
+ \ "ddd yee yoo four"])
+ set cpo-=;
+ 1
+ normal! 0tt;D
+ 2
+ normal! 0fz;D
+ 3
+ normal! $Fy;D
+ 4
+ normal! $Ty;D
+ set cpo+=;
+ 5
+ normal! 0tt;;D
+ 6
+ normal! $Ty;;D
+
+ call assert_equal('aaa two', getline(1))
+ call assert_equal(' z', getline(2))
+ call assert_equal('y', getline(3))
+ call assert_equal('bbb y', getline(4))
+ call assert_equal('ccc', getline(5))
+ call assert_equal('ddd yee y', getline(6))
+ enew!
+endfunction
diff --git a/src/nvim/testdir/test_charsearch_utf8.vim b/src/nvim/testdir/test_charsearch_utf8.vim
new file mode 100644
index 0000000000..ade7dd408c
--- /dev/null
+++ b/src/nvim/testdir/test_charsearch_utf8.vim
@@ -0,0 +1,22 @@
+" Tests for related f{char} and t{char} using utf-8.
+if !has('multi_byte')
+ finish
+endif
+
+" Test for t,f,F,T movement commands
+function! Test_search_cmds()
+ new!
+ call setline(1, "・最åˆã‹ã‚‰æœ€å¾Œã¾ã§æœ€å¼·ã®Vimã¯æœ€é«˜")
+ 1
+ normal! f最
+ call assert_equal([0, 1, 4, 0], getpos('.'))
+ normal! ;
+ call assert_equal([0, 1, 16, 0], getpos('.'))
+ normal! 2;
+ call assert_equal([0, 1, 43, 0], getpos('.'))
+ normal! ,
+ call assert_equal([0, 1, 28, 0], getpos('.'))
+ bw!
+endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_cindent.vim b/src/nvim/testdir/test_cindent.vim
new file mode 100644
index 0000000000..7c2c5e341c
--- /dev/null
+++ b/src/nvim/testdir/test_cindent.vim
@@ -0,0 +1,105 @@
+" Test for cinoptions and cindent
+"
+" TODO: rewrite test3.in into this new style test
+
+func Test_cino_hash()
+ " Test that curbuf->b_ind_hash_comment is correctly reset
+ new
+ setlocal cindent cinoptions=#1
+ setlocal cinoptions=
+ call setline(1, ["#include <iostream>"])
+ call cursor(1, 1)
+ norm! o#include
+ "call feedkeys("o#include\<esc>", 't')
+ call assert_equal(["#include <iostream>", "#include"], getline(1,2))
+ bwipe!
+endfunc
+
+func Test_cino_extern_c()
+ " Test for cino-E
+
+ let without_ind = [
+ \ '#ifdef __cplusplus',
+ \ 'extern "C" {',
+ \ '#endif',
+ \ 'int func_a(void);',
+ \ '#ifdef __cplusplus',
+ \ '}',
+ \ '#endif'
+ \ ]
+
+ let with_ind = [
+ \ '#ifdef __cplusplus',
+ \ 'extern "C" {',
+ \ '#endif',
+ \ "\tint func_a(void);",
+ \ '#ifdef __cplusplus',
+ \ '}',
+ \ '#endif'
+ \ ]
+ new
+ setlocal cindent cinoptions=E0
+ call setline(1, without_ind)
+ call feedkeys("gg=G", 'tx')
+ call assert_equal(with_ind, getline(1, '$'))
+
+ setlocal cinoptions=E-s
+ call setline(1, with_ind)
+ call feedkeys("gg=G", 'tx')
+ call assert_equal(without_ind, getline(1, '$'))
+
+ setlocal cinoptions=Es
+ let tests = [
+ \ ['recognized', ['extern "C" {'], "\t\t;"],
+ \ ['recognized', ['extern "C++" {'], "\t\t;"],
+ \ ['recognized', ['extern /* com */ "C"{'], "\t\t;"],
+ \ ['recognized', ['extern"C"{'], "\t\t;"],
+ \ ['recognized', ['extern "C"', '{'], "\t\t;"],
+ \ ['not recognized', ['extern {'], "\t;"],
+ \ ['not recognized', ['extern /*"C"*/{'], "\t;"],
+ \ ['not recognized', ['extern "C" //{'], ";"],
+ \ ['not recognized', ['extern "C" /*{*/'], ";"],
+ \ ]
+
+ for pair in tests
+ let lines = pair[1]
+ call setline(1, lines)
+ call feedkeys(len(lines) . "Go;", 'tx')
+ call assert_equal(pair[2], getline(len(lines) + 1), 'Failed for "' . string(lines) . '"')
+ endfor
+
+ bwipe!
+endfunc
+
+func Test_cindent_rawstring()
+ new
+ setl cindent
+ call feedkeys("i" .
+ \ "int main() {\<CR>" .
+ \ "R\"(\<CR>" .
+ \ ")\";\<CR>" .
+ \ "statement;\<Esc>", "x")
+ call assert_equal("\tstatement;", getline(line('.')))
+ bw!
+endfunc
+
+func Test_cindent_expr()
+ new
+ func! MyIndentFunction()
+ return v:lnum == 1 ? shiftwidth() : 0
+ endfunc
+ setl expandtab sw=8 indentkeys+=; indentexpr=MyIndentFunction()
+ call setline(1, ['var_a = something()', 'b = something()'])
+ call cursor(1, 1)
+ call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
+ call assert_equal([' var_a = something();', 'b = something();'], getline(1, '$'))
+
+ %d
+ call setline(1, [' var_a = something()', ' b = something()'])
+ call cursor(1, 1)
+ call feedkeys("^\<c-v>j$A;\<esc>", 'tnix')
+ call assert_equal([' var_a = something();', ' b = something()'], getline(1, '$'))
+ bw!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_clientserver.vim b/src/nvim/testdir/test_clientserver.vim
new file mode 100644
index 0000000000..60ef20e0b2
--- /dev/null
+++ b/src/nvim/testdir/test_clientserver.vim
@@ -0,0 +1,107 @@
+" Tests for the +clientserver feature.
+
+if !has('job') || !has('clientserver')
+ finish
+endif
+
+source shared.vim
+
+func Test_client_server()
+ let cmd = GetVimCommand()
+ if cmd == ''
+ return
+ endif
+ if has('x11')
+ if empty($DISPLAY)
+ throw 'Skipped: $DISPLAY is not set'
+ endif
+ try
+ call remote_send('xxx', '')
+ catch
+ if v:exception =~ 'E240:'
+ throw 'Skipped: no connection to the X server'
+ endif
+ " ignore other errors
+ endtry
+ endif
+
+ let name = 'XVIMTEST'
+ let cmd .= ' --servername ' . name
+ let g:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
+ call WaitFor('job_status(g:job) == "run"')
+ if job_status(g:job) != 'run'
+ call assert_report('Cannot run the Vim server')
+ return
+ endif
+
+ " Takes a short while for the server to be active.
+ call WaitFor('serverlist() =~ "' . name . '"')
+ call assert_match(name, serverlist())
+
+ call remote_foreground(name)
+
+ call remote_send(name, ":let testvar = 'yes'\<CR>")
+ call WaitFor('remote_expr("' . name . '", "exists(\"testvar\") ? testvar : \"\"", "", 1) == "yes"')
+ call assert_equal('yes', remote_expr(name, "testvar", "", 2))
+
+ if has('unix') && has('gui') && !has('gui_running')
+ " Running in a terminal and the GUI is available: Tell the server to open
+ " the GUI and check that the remote command still works.
+ " Need to wait for the GUI to start up, otherwise the send hangs in trying
+ " to send to the terminal window.
+ if has('gui_athena') || has('gui_motif')
+ " For those GUIs, ignore the 'failed to create input context' error.
+ call remote_send(name, ":call test_ignore_error('E285') | gui -f\<CR>")
+ else
+ call remote_send(name, ":gui -f\<CR>")
+ endif
+ " Wait for the server to be up and answering requests.
+ sleep 100m
+ call WaitFor('remote_expr("' . name . '", "v:version", "", 1) != ""')
+ call assert_true(remote_expr(name, "v:version", "", 1) != "")
+
+ call remote_send(name, ":let testvar = 'maybe'\<CR>")
+ call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "maybe"')
+ call assert_equal('maybe', remote_expr(name, "testvar", "", 2))
+ endif
+
+ call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\<CR>")', 'E241')
+
+ " Expression evaluated locally.
+ if v:servername == ''
+ call remote_startserver('MYSELF')
+ " May get MYSELF1 when running the test again.
+ call assert_match('MYSELF', v:servername)
+ endif
+ let g:testvar = 'myself'
+ call assert_equal('myself', remote_expr(v:servername, 'testvar'))
+
+ call remote_send(name, ":call server2client(expand('<client>'), 'got it')\<CR>", 'g:myserverid')
+ call assert_equal('got it', remote_read(g:myserverid, 2))
+
+ call remote_send(name, ":call server2client(expand('<client>'), 'another')\<CR>", 'g:myserverid')
+ let peek_result = 'nothing'
+ let r = remote_peek(g:myserverid, 'peek_result')
+ " unpredictable whether the result is already avaialble.
+ if r > 0
+ call assert_equal('another', peek_result)
+ elseif r == 0
+ call assert_equal('nothing', peek_result)
+ else
+ call assert_report('remote_peek() failed')
+ endif
+ let g:peek_result = 'empty'
+ call WaitFor('remote_peek(g:myserverid, "g:peek_result") > 0')
+ call assert_equal('another', g:peek_result)
+ call assert_equal('another', remote_read(g:myserverid, 2))
+
+ call remote_send(name, ":qa!\<CR>")
+ call WaitFor('job_status(g:job) == "dead"')
+ if job_status(g:job) != 'dead'
+ call assert_report('Server did not exit')
+ call job_stop(g:job, 'kill')
+ endif
+endfunc
+
+" Uncomment this line to get a debugging log
+" call ch_logfile('channellog', 'w')
diff --git a/src/nvim/testdir/test_close_count.vim b/src/nvim/testdir/test_close_count.vim
new file mode 100644
index 0000000000..1f9adba32d
--- /dev/null
+++ b/src/nvim/testdir/test_close_count.vim
@@ -0,0 +1,174 @@
+
+" Tests for :[count]close! command
+func Test_close_count()
+ enew! | only
+
+ let wids = [win_getid()]
+ for i in range(5)
+ new
+ call add(wids, win_getid())
+ endfor
+
+ 4wincmd w
+ close!
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[5], wids[4], wids[3], wids[1], wids[0]], ids)
+
+ 1close!
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[3], wids[1], wids[0]], ids)
+
+ $close!
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[3], wids[1]], ids)
+
+ 1wincmd w
+ 2close!
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[1]], ids)
+
+ 1wincmd w
+ new
+ call add(wids, win_getid())
+ new
+ call add(wids, win_getid())
+ 2wincmd w
+ -1close!
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[6], wids[4], wids[1]], ids)
+
+ 2wincmd w
+ +1close!
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[6], wids[4]], ids)
+
+ only!
+endfunc
+
+" Tests for :[count]hide command
+func Test_hide_count()
+ enew! | only
+
+ let wids = [win_getid()]
+ for i in range(5)
+ new
+ call add(wids, win_getid())
+ endfor
+
+ 4wincmd w
+ .hide
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[5], wids[4], wids[3], wids[1], wids[0]], ids)
+
+ 1hide
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[3], wids[1], wids[0]], ids)
+
+ $hide
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[3], wids[1]], ids)
+
+ 1wincmd w
+ 2hide
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[1]], ids)
+
+ 1wincmd w
+ new
+ call add(wids, win_getid())
+ new
+ call add(wids, win_getid())
+ 3wincmd w
+ -hide
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[7], wids[4], wids[1]], ids)
+
+ 2wincmd w
+ +hide
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[7], wids[4]], ids)
+
+ only!
+endfunc
+
+" Tests for :[count]close! command with 'hidden'
+func Test_hidden_close_count()
+ enew! | only
+
+ let wids = [win_getid()]
+ for i in range(5)
+ new
+ call add(wids, win_getid())
+ endfor
+
+ set hidden
+
+ $ hide
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[5], wids[4], wids[3], wids[2], wids[1]], ids)
+
+ $-1 close!
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[5], wids[4], wids[3], wids[1]], ids)
+
+ 1wincmd w
+ .+close!
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[5], wids[3], wids[1]], ids)
+
+ set nohidden
+ only!
+endfunc
+
+" Tests for 'CTRL-W c' command to close windows.
+func Test_winclose_command()
+ enew! | only
+
+ let wids = [win_getid()]
+ for i in range(5)
+ new
+ call add(wids, win_getid())
+ endfor
+
+ set hidden
+
+ 4wincmd w
+ exe "normal \<C-W>c"
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[5], wids[4], wids[3], wids[1], wids[0]], ids)
+
+ exe "normal 1\<C-W>c"
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[3], wids[1], wids[0]], ids)
+
+ exe "normal 9\<C-W>c"
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[3], wids[1]], ids)
+
+ 1wincmd w
+ exe "normal 2\<C-W>c"
+ let ids = []
+ windo call add(ids, win_getid())
+ call assert_equal([wids[4], wids[1]], ids)
+
+ set nohidden
+ only!
+endfunc
diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim
new file mode 100644
index 0000000000..26f1dcc333
--- /dev/null
+++ b/src/nvim/testdir/test_cmdline.vim
@@ -0,0 +1,525 @@
+" Tests for editing the command line.
+
+
+func Test_complete_tab()
+ call writefile(['testfile'], 'Xtestfile')
+ call feedkeys(":e Xtestf\t\r", "tx")
+ call assert_equal('testfile', getline(1))
+ call delete('Xtestfile')
+endfunc
+
+func Test_complete_list()
+ " We can't see the output, but at least we check the code runs properly.
+ call feedkeys(":e test\<C-D>\r", "tx")
+ call assert_equal('test', expand('%:t'))
+endfunc
+
+func Test_complete_wildmenu()
+ call writefile(['testfile1'], 'Xtestfile1')
+ call writefile(['testfile2'], 'Xtestfile2')
+ set wildmenu
+ call feedkeys(":e Xtestf\t\t\r", "tx")
+ call assert_equal('testfile2', getline(1))
+
+ call delete('Xtestfile1')
+ call delete('Xtestfile2')
+ set nowildmenu
+endfunc
+
+func Test_map_completion()
+ if !has('cmdline_compl')
+ return
+ endif
+ call feedkeys(":map <unique> <si\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"map <unique> <silent>', getreg(':'))
+ call feedkeys(":map <script> <un\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"map <script> <unique>', getreg(':'))
+ call feedkeys(":map <expr> <sc\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"map <expr> <script>', getreg(':'))
+ call feedkeys(":map <buffer> <e\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"map <buffer> <expr>', getreg(':'))
+ call feedkeys(":map <nowait> <b\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"map <nowait> <buffer>', getreg(':'))
+ call feedkeys(":map <special> <no\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"map <special> <nowait>', getreg(':'))
+ call feedkeys(":map <silent> <sp\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"map <silent> <special>', getreg(':'))
+endfunc
+
+func Test_match_completion()
+ if !has('cmdline_compl')
+ return
+ endif
+ hi Aardig ctermfg=green
+ call feedkeys(":match \<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"match Aardig', getreg(':'))
+ call feedkeys(":match \<S-Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"match none', getreg(':'))
+endfunc
+
+func Test_highlight_completion()
+ if !has('cmdline_compl')
+ return
+ endif
+ hi Aardig ctermfg=green
+ call feedkeys(":hi \<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"hi Aardig', getreg(':'))
+ call feedkeys(":hi default \<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"hi default Aardig', getreg(':'))
+ call feedkeys(":hi clear Aa\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"hi clear Aardig', getreg(':'))
+ call feedkeys(":hi li\<S-Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"hi link', getreg(':'))
+ call feedkeys(":hi d\<S-Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"hi default', getreg(':'))
+ call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"hi clear', getreg(':'))
+
+ " A cleared group does not show up in completions.
+ hi Anders ctermfg=green
+ call assert_equal(['Aardig', 'Anders'], getcompletion('A', 'highlight'))
+ hi clear Aardig
+ call assert_equal(['Anders'], getcompletion('A', 'highlight'))
+ hi clear Anders
+ call assert_equal([], getcompletion('A', 'highlight'))
+endfunc
+
+func Test_expr_completion()
+ if !has('cmdline_compl')
+ return
+ endif
+ for cmd in [
+ \ 'let a = ',
+ \ 'if',
+ \ 'elseif',
+ \ 'while',
+ \ 'for',
+ \ 'echo',
+ \ 'echon',
+ \ 'execute',
+ \ 'echomsg',
+ \ 'echoerr',
+ \ 'call',
+ \ 'return',
+ \ 'cexpr',
+ \ 'caddexpr',
+ \ 'cgetexpr',
+ \ 'lexpr',
+ \ 'laddexpr',
+ \ 'lgetexpr']
+ call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt')
+ call assert_equal('"' . cmd . ' getline(', getreg(':'))
+ endfor
+endfunc
+
+func Test_getcompletion()
+ if !has('cmdline_compl')
+ return
+ endif
+ let groupcount = len(getcompletion('', 'event'))
+ call assert_true(groupcount > 0)
+ let matchcount = len(getcompletion('File', 'event'))
+ call assert_true(matchcount > 0)
+ call assert_true(groupcount > matchcount)
+
+ if has('menu')
+ source $VIMRUNTIME/menu.vim
+ let matchcount = len(getcompletion('', 'menu'))
+ call assert_true(matchcount > 0)
+ call assert_equal(['File.'], getcompletion('File', 'menu'))
+ call assert_true(matchcount > 0)
+ let matchcount = len(getcompletion('File.', 'menu'))
+ call assert_true(matchcount > 0)
+ endif
+
+ let l = getcompletion('v:n', 'var')
+ call assert_true(index(l, 'v:null') >= 0)
+ let l = getcompletion('v:notexists', 'var')
+ call assert_equal([], l)
+
+ args a.c b.c
+ let l = getcompletion('', 'arglist')
+ call assert_equal(['a.c', 'b.c'], l)
+ %argdelete
+
+ let l = getcompletion('', 'augroup')
+ call assert_true(index(l, 'END') >= 0)
+ let l = getcompletion('blahblah', 'augroup')
+ call assert_equal([], l)
+
+ let l = getcompletion('', 'behave')
+ call assert_true(index(l, 'mswin') >= 0)
+ let l = getcompletion('not', 'behave')
+ call assert_equal([], l)
+
+ let l = getcompletion('', 'color')
+ call assert_true(index(l, 'default') >= 0)
+ let l = getcompletion('dirty', 'color')
+ call assert_equal([], l)
+
+ let l = getcompletion('', 'command')
+ call assert_true(index(l, 'sleep') >= 0)
+ let l = getcompletion('awake', 'command')
+ call assert_equal([], l)
+
+ let l = getcompletion('', 'dir')
+ call assert_true(index(l, expand('sautest/')) >= 0)
+ let l = getcompletion('NoMatch', 'dir')
+ call assert_equal([], l)
+
+ let l = getcompletion('exe', 'expression')
+ call assert_true(index(l, 'executable(') >= 0)
+ let l = getcompletion('kill', 'expression')
+ call assert_equal([], l)
+
+ let l = getcompletion('tag', 'function')
+ call assert_true(index(l, 'taglist(') >= 0)
+ let l = getcompletion('paint', 'function')
+ call assert_equal([], l)
+
+ let Flambda = {-> 'hello'}
+ let l = getcompletion('', 'function')
+ let l = filter(l, {i, v -> v =~ 'lambda'})
+ call assert_equal(0, len(l))
+
+ let l = getcompletion('run', 'file')
+ call assert_true(index(l, 'runtest.vim') >= 0)
+ let l = getcompletion('walk', 'file')
+ call assert_equal([], l)
+ set wildignore=*.vim
+ let l = getcompletion('run', 'file', 1)
+ call assert_true(index(l, 'runtest.vim') < 0)
+ set wildignore&
+
+ let l = getcompletion('ha', 'filetype')
+ call assert_true(index(l, 'hamster') >= 0)
+ let l = getcompletion('horse', 'filetype')
+ call assert_equal([], l)
+
+ let l = getcompletion('z', 'syntax')
+ call assert_true(index(l, 'zimbu') >= 0)
+ let l = getcompletion('emacs', 'syntax')
+ call assert_equal([], l)
+
+ let l = getcompletion('jikes', 'compiler')
+ call assert_true(index(l, 'jikes') >= 0)
+ let l = getcompletion('break', 'compiler')
+ call assert_equal([], l)
+
+ helptags ALL
+ let l = getcompletion('last', 'help')
+ call assert_true(index(l, ':tablast') >= 0)
+ let l = getcompletion('giveup', 'help')
+ call assert_equal([], l)
+
+ let l = getcompletion('time', 'option')
+ call assert_true(index(l, 'timeoutlen') >= 0)
+ let l = getcompletion('space', 'option')
+ call assert_equal([], l)
+
+ let l = getcompletion('er', 'highlight')
+ call assert_true(index(l, 'ErrorMsg') >= 0)
+ let l = getcompletion('dark', 'highlight')
+ call assert_equal([], l)
+
+ let l = getcompletion('', 'messages')
+ call assert_true(index(l, 'clear') >= 0)
+ let l = getcompletion('not', 'messages')
+ call assert_equal([], l)
+
+ let l = getcompletion('', 'mapclear')
+ call assert_true(index(l, '<buffer>') >= 0)
+ let l = getcompletion('not', 'mapclear')
+ call assert_equal([], l)
+
+ if has('cscope')
+ let l = getcompletion('', 'cscope')
+ let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show']
+ call assert_equal(cmds, l)
+ " using cmdline completion must not change the result
+ call feedkeys(":cscope find \<c-d>\<c-c>", 'xt')
+ let l = getcompletion('', 'cscope')
+ call assert_equal(cmds, l)
+ let keys = ['a', 'c', 'd', 'e', 'f', 'g', 'i', 's', 't']
+ let l = getcompletion('find ', 'cscope')
+ call assert_equal(keys, l)
+ endif
+
+ if has('signs')
+ sign define Testing linehl=Comment
+ let l = getcompletion('', 'sign')
+ let cmds = ['define', 'jump', 'list', 'place', 'undefine', 'unplace']
+ call assert_equal(cmds, l)
+ " using cmdline completion must not change the result
+ call feedkeys(":sign list \<c-d>\<c-c>", 'xt')
+ let l = getcompletion('', 'sign')
+ call assert_equal(cmds, l)
+ let l = getcompletion('list ', 'sign')
+ call assert_equal(['Testing'], l)
+ endif
+
+ " Command line completion tests
+ let l = getcompletion('cd ', 'cmdline')
+ call assert_true(index(l, expand('sautest/')) >= 0)
+ let l = getcompletion('cd NoMatch', 'cmdline')
+ call assert_equal([], l)
+ let l = getcompletion('let v:n', 'cmdline')
+ call assert_true(index(l, 'v:null') >= 0)
+ let l = getcompletion('let v:notexists', 'cmdline')
+ call assert_equal([], l)
+ let l = getcompletion('call tag', 'cmdline')
+ call assert_true(index(l, 'taglist(') >= 0)
+ let l = getcompletion('call paint', 'cmdline')
+ call assert_equal([], l)
+
+ " For others test if the name is recognized.
+ let names = ['buffer', 'environment', 'file_in_path',
+ \ 'mapping', 'shellcmd', 'tag', 'tag_listfiles', 'user']
+ if has('cmdline_hist')
+ call add(names, 'history')
+ endif
+ if has('gettext')
+ call add(names, 'locale')
+ endif
+ if has('profile')
+ call add(names, 'syntime')
+ endif
+
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", "word\tfile\tcmd"], 'Xtags')
+
+ for name in names
+ let matchcount = len(getcompletion('', name))
+ call assert_true(matchcount >= 0, 'No matches for ' . name)
+ endfor
+
+ call delete('Xtags')
+
+ call assert_fails('call getcompletion("", "burp")', 'E475:')
+endfunc
+
+func Test_expand_star_star()
+ call mkdir('a/b', 'p')
+ call writefile(['asdfasdf'], 'a/b/fileXname')
+ call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt')
+ call assert_equal('find '.expand('a/b/fileXname'), getreg(':'))
+ bwipe!
+ call delete('a', 'rf')
+endfunc
+
+func Test_paste_in_cmdline()
+ let @a = "def"
+ call feedkeys(":abc \<C-R>a ghi\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"abc def ghi', @:)
+
+ new
+ call setline(1, 'asdf.x /tmp/some verylongword a;b-c*d ')
+
+ call feedkeys(":aaa \<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa asdf bbb', @:)
+
+ call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa /tmp/some bbb', @:)
+
+ call feedkeys(":aaa \<C-R>\<C-L> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa '.getline(1).' bbb', @:)
+
+ set incsearch
+ call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa verylongword bbb', @:)
+
+ call feedkeys("f;:aaa \<C-R>\<C-A> bbb\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"aaa a;b-c*d bbb', @:)
+
+ call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:)
+ bwipe!
+
+ " Error while typing a command used to cause that it was not executed
+ " in the end.
+ new
+ try
+ call feedkeys(":file \<C-R>%Xtestfile\<CR>", 'tx')
+ catch /^Vim\%((\a\+)\)\=:E32/
+ " ignore error E32
+ endtry
+ call assert_equal("Xtestfile", bufname("%"))
+ bwipe!
+endfunc
+
+func Test_remove_char_in_cmdline()
+ call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"abc ef', @:)
+
+ call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"abcdef', @:)
+
+ call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"abc ghi', @:)
+
+ call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"def', @:)
+endfunc
+
+func Test_illegal_address1()
+ new
+ 2;'(
+ 2;')
+ quit
+endfunc
+
+func Test_illegal_address2()
+ call writefile(['c', 'x', ' x', '.', '1;y'], 'Xtest.vim')
+ new
+ source Xtest.vim
+ " Trigger calling validate_cursor()
+ diffsp Xtest.vim
+ quit!
+ bwipe!
+ call delete('Xtest.vim')
+endfunc
+
+func Test_cmdline_complete_wildoptions()
+ help
+ call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
+ let a = join(sort(split(@:)),' ')
+ set wildoptions=tagfile
+ call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx')
+ let b = join(sort(split(@:)),' ')
+ call assert_equal(a, b)
+ bw!
+endfunc
+
+func Test_cmdline_complete_user_cmd()
+ command! -complete=color -nargs=1 Foo :
+ call feedkeys(":Foo \<Tab>\<Home>\"\<cr>", 'tx')
+ call assert_equal('"Foo blue', @:)
+ call feedkeys(":Foo b\<Tab>\<Home>\"\<cr>", 'tx')
+ call assert_equal('"Foo blue', @:)
+ delcommand Foo
+endfunc
+
+func Test_cmdline_write_alternatefile()
+ new
+ call setline('.', ['one', 'two'])
+ f foo.txt
+ new
+ f #-A
+ call assert_equal('foo.txt-A', expand('%'))
+ f #<-B.txt
+ call assert_equal('foo-B.txt', expand('%'))
+ f %<
+ call assert_equal('foo-B', expand('%'))
+ new
+ call assert_fails('f #<', 'E95')
+ bw!
+ f foo-B.txt
+ f %<-A
+ call assert_equal('foo-B-A', expand('%'))
+ bw!
+ bw!
+endfunc
+
+" using a leading backslash here
+set cpo+=C
+
+func Test_cmdline_search_range()
+ new
+ call setline(1, ['a', 'b', 'c', 'd'])
+ /d
+ 1,\/s/b/B/
+ call assert_equal('B', getline(2))
+
+ /a
+ $
+ \?,4s/c/C/
+ call assert_equal('C', getline(3))
+
+ call setline(1, ['a', 'b', 'c', 'd'])
+ %s/c/c/
+ 1,\&s/b/B/
+ call assert_equal('B', getline(2))
+
+ bwipe!
+endfunc
+
+" Tests for getcmdline(), getcmdpos() and getcmdtype()
+func Check_cmdline(cmdtype)
+ call assert_equal('MyCmd a', getcmdline())
+ call assert_equal(8, getcmdpos())
+ call assert_equal(a:cmdtype, getcmdtype())
+ return ''
+endfunc
+
+func Test_getcmdtype()
+ call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt")
+
+ let cmdtype = ''
+ debuggreedy
+ call feedkeys(":debug echo 'test'\<CR>", "t")
+ call feedkeys("let cmdtype = \<C-R>=string(getcmdtype())\<CR>\<CR>", "t")
+ call feedkeys("cont\<CR>", "xt")
+ 0debuggreedy
+ call assert_equal('>', cmdtype)
+
+ call feedkeys("/MyCmd a\<C-R>=Check_cmdline('/')\<CR>\<Esc>", "xt")
+ call feedkeys("?MyCmd a\<C-R>=Check_cmdline('?')\<CR>\<Esc>", "xt")
+
+ call feedkeys(":call input('Answer?')\<CR>", "t")
+ call feedkeys("MyCmd a\<C-R>=Check_cmdline('@')\<CR>\<C-C>", "xt")
+
+ call feedkeys(":insert\<CR>MyCmd a\<C-R>=Check_cmdline('-')\<CR>\<Esc>", "xt")
+
+ cnoremap <expr> <F6> Check_cmdline('=')
+ call feedkeys("a\<C-R>=MyCmd a\<F6>\<Esc>\<Esc>", "xt")
+ cunmap <F6>
+endfunc
+
+func Test_getcmdwintype()
+ call feedkeys("q/:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
+ call assert_equal('/', a)
+
+ call feedkeys("q?:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
+ call assert_equal('?', a)
+
+ call feedkeys("q::let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
+ call assert_equal(':', a)
+
+ call feedkeys(":\<C-F>:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
+ call assert_equal(':', a)
+
+ call assert_equal('', getcmdwintype())
+endfunc
+
+func Test_verbosefile()
+ set verbosefile=Xlog
+ echomsg 'foo'
+ echomsg 'bar'
+ set verbosefile=
+ let log = readfile('Xlog')
+ call assert_match("foo\nbar", join(log, "\n"))
+ call delete('Xlog')
+endfunc
+
+func Test_setcmdpos()
+ func InsertTextAtPos(text, pos)
+ call assert_equal(0, setcmdpos(a:pos))
+ return a:text
+ endfunc
+
+ " setcmdpos() with position in the middle of the command line.
+ call feedkeys(":\"12\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
+ call assert_equal('"1ab2', @:)
+
+ call feedkeys(":\"12\<C-R>\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
+ call assert_equal('"1b2a', @:)
+
+ " setcmdpos() with position beyond the end of the command line.
+ call feedkeys(":\"12\<C-B>\<C-R>=InsertTextAtPos('a', 10)\<CR>b\<CR>", 'xt')
+ call assert_equal('"12ab', @:)
+
+ " setcmdpos() returns 1 when not editing the command line.
+ call assert_equal(1, setcmdpos(3))
+endfunc
+
+set cpo&
diff --git a/src/nvim/testdir/test_command_count.vim b/src/nvim/testdir/test_command_count.vim
new file mode 100644
index 0000000000..2d793ed88f
--- /dev/null
+++ b/src/nvim/testdir/test_command_count.vim
@@ -0,0 +1,195 @@
+" Test for user command counts.
+
+func Test_command_count_0()
+ let bufnr = bufnr('%')
+ set hidden
+ set noswapfile
+
+ split DoesNotExistEver
+ let lastbuf = bufnr('$')
+ call setline(1, 'asdf')
+ quit!
+
+ command! -range -addr=loaded_buffers RangeLoadedBuffers :let lines = [<line1>, <line2>]
+ command! -range=% -addr=loaded_buffers RangeLoadedBuffersAll :let lines = [<line1>, <line2>]
+ command! -range -addr=buffers RangeBuffers :let lines = [<line1>, <line2>]
+ command! -range=% -addr=buffers RangeBuffersAll :let lines = [<line1>, <line2>]
+
+ .,$RangeLoadedBuffers
+ call assert_equal([bufnr, bufnr], lines)
+ %RangeLoadedBuffers
+ call assert_equal([bufnr, bufnr], lines)
+ RangeLoadedBuffersAll
+ call assert_equal([bufnr, bufnr], lines)
+ .,$RangeBuffers
+ call assert_equal([bufnr, lastbuf], lines)
+ %RangeBuffers
+ call assert_equal([bufnr, lastbuf], lines)
+ RangeBuffersAll
+ call assert_equal([bufnr, lastbuf], lines)
+
+ delcommand RangeLoadedBuffers
+ delcommand RangeLoadedBuffersAll
+ delcommand RangeBuffers
+ delcommand RangeBuffersAll
+
+ set hidden&
+ set swapfile&
+endfunc
+
+func Test_command_count_1()
+ silent! %argd
+ arga a b c d e
+ argdo echo "loading buffers"
+ argu 3
+ command! -range -addr=arguments RangeArguments :let lines = [<line1>, <line2>]
+ command! -range=% -addr=arguments RangeArgumentsAll :let lines = [<line1>, <line2>]
+ .-,$-RangeArguments
+ call assert_equal([2, 4], lines)
+ %RangeArguments
+ call assert_equal([1, 5], lines)
+ RangeArgumentsAll
+ call assert_equal([1, 5], lines)
+ N
+ .RangeArguments
+ call assert_equal([2, 2], lines)
+ delcommand RangeArguments
+ delcommand RangeArgumentsAll
+
+ split|split|split|split
+ 3wincmd w
+ command! -range -addr=windows RangeWindows :let lines = [<line1>, <line2>]
+ .,$RangeWindows
+ call assert_equal([3, 5], lines)
+ %RangeWindows
+ call assert_equal([1, 5], lines)
+ delcommand RangeWindows
+
+ command! -range=% -addr=windows RangeWindowsAll :let lines = [<line1>, <line2>]
+ RangeWindowsAll
+ call assert_equal([1, 5], lines)
+ delcommand RangeWindowsAll
+ only
+ blast|bd
+
+ tabe|tabe|tabe|tabe
+ normal 2gt
+ command! -range -addr=tabs RangeTabs :let lines = [<line1>, <line2>]
+ .,$RangeTabs
+ call assert_equal([2, 5], lines)
+ %RangeTabs
+ call assert_equal([1, 5], lines)
+ delcommand RangeTabs
+
+ command! -range=% -addr=tabs RangeTabsAll :let lines = [<line1>, <line2>]
+ RangeTabsAll
+ call assert_equal([1, 5], lines)
+ delcommand RangeTabsAll
+ 1tabonly
+
+ s/\n/\r\r\r\r\r/
+ 2ma<
+ $-ma>
+ command! -range=% RangeLines :let lines = [<line1>, <line2>]
+ '<,'>RangeLines
+ call assert_equal([2, 5], lines)
+ delcommand RangeLines
+
+ command! -range=% -buffer LocalRangeLines :let lines = [<line1>, <line2>]
+ '<,'>LocalRangeLines
+ call assert_equal([2, 5], lines)
+ delcommand LocalRangeLines
+endfunc
+
+func Test_command_count_2()
+ silent! %argd
+ arga a b c d
+ call assert_fails('5argu', 'E16:')
+
+ $argu
+ call assert_equal('d', expand('%:t'))
+
+ 1argu
+ call assert_equal('a', expand('%:t'))
+
+ call assert_fails('300b', 'E16:')
+
+ split|split|split|split
+ 0close
+
+ $wincmd w
+ $close
+ call assert_equal(3, winnr())
+
+ call assert_fails('$+close', 'E16:')
+
+ $tabe
+ call assert_equal(2, tabpagenr())
+
+ call assert_fails('$+tabe', 'E16:')
+
+ only!
+ e x
+ 0tabm
+ normal 1gt
+ call assert_equal('x', expand('%:t'))
+
+ tabonly!
+ only!
+endfunc
+
+func Test_command_count_3()
+ let bufnr = bufnr('%')
+ se nohidden
+ e aaa
+ let buf_aaa = bufnr('%')
+ e bbb
+ let buf_bbb = bufnr('%')
+ e ccc
+ let buf_ccc = bufnr('%')
+ exe bufnr . 'buf'
+ call assert_equal([1, 1, 1], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)])
+ exe buf_bbb . "," . buf_ccc . "bdelete"
+ call assert_equal([1, 0, 0], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)])
+ exe buf_aaa . "bdelete"
+ call assert_equal([0, 0, 0], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)])
+endfunc
+
+func Test_command_count_4()
+ %argd
+ let bufnr = bufnr('$')
+ arga aa bb cc dd ee ff
+ 3argu
+ let args = []
+ .,$-argdo call add(args, expand('%'))
+ call assert_equal(['cc', 'dd', 'ee'], args)
+
+ " create windows to get 5
+ split|split|split|split
+ 2wincmd w
+ let windows = []
+ .,$-windo call add(windows, winnr())
+ call assert_equal([2, 3, 4], windows)
+ only!
+
+ exe bufnr . 'buf'
+ bnext
+ let bufnr = bufnr('%')
+ let buffers = []
+ .,$-bufdo call add(buffers, bufnr('%'))
+ call assert_equal([bufnr, bufnr + 1, bufnr + 2, bufnr + 3, bufnr + 4], buffers)
+
+ exe (bufnr + 3) . 'bdel'
+ let buffers = []
+ exe (bufnr + 2) . ',' . (bufnr + 5) . "bufdo call add(buffers, bufnr('%'))"
+ call assert_equal([bufnr + 2, bufnr + 4, bufnr + 5], buffers)
+
+ " create tabpages to get 5
+ tabe|tabe|tabe|tabe
+ normal! 2gt
+ let tabpages = []
+ .,$-tabdo call add(tabpages, tabpagenr())
+ call assert_equal([2, 3, 4], tabpages)
+ tabonly!
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_comparators.vim b/src/nvim/testdir/test_comparators.vim
new file mode 100644
index 0000000000..87be006cf2
--- /dev/null
+++ b/src/nvim/testdir/test_comparators.vim
@@ -0,0 +1,9 @@
+function Test_Comparators()
+ try
+ let oldisident=&isident
+ set isident+=#
+ call assert_equal(1, 1 is#1)
+ finally
+ let &isident=oldisident
+ endtry
+endfunction
diff --git a/src/nvim/testdir/test_compiler.vim b/src/nvim/testdir/test_compiler.vim
new file mode 100644
index 0000000000..4600a28da5
--- /dev/null
+++ b/src/nvim/testdir/test_compiler.vim
@@ -0,0 +1,54 @@
+" Test the :compiler command
+
+func Test_compiler()
+ if !executable('perl')
+ return
+ endif
+
+ " $LANG changes the output of Perl.
+ if $LANG != ''
+ unlet $LANG
+ endif
+
+ e Xfoo.pl
+ compiler perl
+ call assert_equal('perl', b:current_compiler)
+ call assert_fails('let g:current_compiler', 'E121:')
+
+ call setline(1, ['#!/usr/bin/perl -w', 'use strict;', 'my $foo=1'])
+ w!
+ call feedkeys(":make\<CR>\<CR>", 'tx')
+ call assert_fails('clist', 'E42:')
+
+ call setline(1, ['#!/usr/bin/perl -w', 'use strict;', '$foo=1'])
+ w!
+ call feedkeys(":make\<CR>\<CR>", 'tx')
+ let a=execute('clist')
+ call assert_match("\n 1 Xfoo.pl:3: Global symbol \"\$foo\" "
+ \ . "requires explicit package name", a)
+
+ call delete('Xfoo.pl')
+ bw!
+endfunc
+
+func Test_compiler_without_arg()
+ let a=split(execute('compiler'))
+ call assert_match(expand('^.*runtime/compiler/ant.vim$'), a[0])
+ call assert_match(expand('^.*runtime/compiler/bcc.vim$'), a[1])
+ call assert_match(expand('^.*runtime/compiler/xmlwf.vim$'), a[-1])
+endfunc
+
+func Test_compiler_completion()
+ call feedkeys(":compiler \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('^"compiler ant bcc .* xmlwf$', @:)
+
+ call feedkeys(":compiler p\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"compiler pbx perl php pylint pyunit', @:)
+
+ call feedkeys(":compiler! p\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"compiler! pbx perl php pylint pyunit', @:)
+endfunc
+
+func Test_compiler_error()
+ call assert_fails('compiler doesnotexist', 'E666:')
+endfunc
diff --git a/src/nvim/testdir/test_cscope.vim b/src/nvim/testdir/test_cscope.vim
new file mode 100644
index 0000000000..01a9a3f9ad
--- /dev/null
+++ b/src/nvim/testdir/test_cscope.vim
@@ -0,0 +1,279 @@
+" Test for cscope commands.
+
+if !has('cscope') || !executable('cscope') || !has('quickfix')
+ finish
+endif
+
+func CscopeSetupOrClean(setup)
+ if a:setup
+ noa sp samples/memfile_test.c
+ saveas! Xmemfile_test.c
+ call system('cscope -bk -fXcscope.out Xmemfile_test.c')
+ call system('cscope -bk -fXcscope2.out Xmemfile_test.c')
+ cscope add Xcscope.out
+ set cscopequickfix=s-,g-,d-,c-,t-,e-,f-,i-,a-
+ else
+ cscope kill -1
+ for file in ['Xcscope.out', 'Xcscope2.out', 'Xmemfile_test.c']
+ call delete(file)
+ endfo
+ endif
+endfunc
+
+func Test_cscopeWithCscopeConnections()
+ call CscopeSetupOrClean(1)
+ " Test 0: E568: duplicate cscope database not added
+ try
+ set nocscopeverbose
+ cscope add Xcscope.out
+ set cscopeverbose
+ catch
+ call assert_report('exception thrown')
+ endtry
+ call assert_fails('cscope add', 'E560')
+ call assert_fails('cscope add Xcscope.out', 'E568')
+ call assert_fails('cscope add doesnotexist.out', 'E563')
+
+ " Test 1: Find this C-Symbol
+ for cmd in ['cs find s main', 'cs find 0 main']
+ let a=execute(cmd)
+ " Test 1.1 test where it moves the cursor
+ call assert_equal('main(void)', getline('.'))
+ " Test 1.2 test the output of the :cs command
+ call assert_match('\n(1 of 1): <<main>> main(void )', a)
+ endfor
+
+ " Test 2: Find this definition
+ for cmd in ['cs find g test_mf_hash', 'cs find 1 test_mf_hash']
+ exe cmd
+ call assert_equal(['', '/*', ' * Test mf_hash_*() functions.', ' */', ' static void', 'test_mf_hash(void)', '{'], getline(line('.')-5, line('.')+1))
+ endfor
+
+ " Test 3: Find functions called by this function
+ for cmd in ['cs find d test_mf_hash', 'cs find 2 test_mf_hash']
+ let a=execute(cmd)
+ call assert_match('\n(1 of 42): <<mf_hash_init>> mf_hash_init(&ht);', a)
+ call assert_equal(' mf_hash_init(&ht);', getline('.'))
+ endfor
+
+ " Test 4: Find functions calling this function
+ for cmd in ['cs find c test_mf_hash', 'cs find 3 test_mf_hash']
+ let a=execute(cmd)
+ call assert_match('\n(1 of 1): <<main>> test_mf_hash();', a)
+ call assert_equal(' test_mf_hash();', getline('.'))
+ endfor
+
+ " Test 5: Find this text string
+ for cmd in ['cs find t Bram', 'cs find 4 Bram']
+ let a=execute(cmd)
+ call assert_match('(1 of 1): <<<unknown>>> \* VIM - Vi IMproved^Iby Bram Moolenaar', a)
+ call assert_equal(' * VIM - Vi IMproved by Bram Moolenaar', getline('.'))
+ endfor
+
+ " Test 6: Find this egrep pattern
+ " test all matches returned by cscope
+ for cmd in ['cs find e ^\#includ.', 'cs find 6 ^\#includ.']
+ let a=execute(cmd)
+ call assert_match('\n(1 of 3): <<<unknown>>> #include <assert.h>', a)
+ call assert_equal('#include <assert.h>', getline('.'))
+ cnext
+ call assert_equal('#include "main.c"', getline('.'))
+ cnext
+ call assert_equal('#include "memfile.c"', getline('.'))
+ call assert_fails('cnext', 'E553:')
+ endfor
+
+ " Test 7: Find the same egrep pattern using lcscope this time.
+ let a=execute('lcs find e ^\#includ.')
+ call assert_match('\n(1 of 3): <<<unknown>>> #include <assert.h>', a)
+ call assert_equal('#include <assert.h>', getline('.'))
+ lnext
+ call assert_equal('#include "main.c"', getline('.'))
+ lnext
+ call assert_equal('#include "memfile.c"', getline('.'))
+ call assert_fails('lnext', 'E553:')
+
+ " Test 8: Find this file
+ for cmd in ['cs find f Xmemfile_test.c', 'cs find 7 Xmemfile_test.c']
+ enew
+ let a=execute(cmd)
+ call assert_true(a =~ '"Xmemfile_test.c" \d\+L, \d\+C')
+ call assert_equal('Xmemfile_test.c', @%)
+ endfor
+
+ " Test 9: Find files #including this file
+ for cmd in ['cs find i assert.h', 'cs find 8 assert.h']
+ enew
+ let a=execute(cmd)
+ let alines = split(a, '\n', 1)
+ call assert_equal('', alines[0])
+ call assert_true(alines[1] =~ '"Xmemfile_test.c" \d\+L, \d\+C')
+ call assert_equal('(1 of 1): <<global>> #include <assert.h>', alines[2])
+ call assert_equal('#include <assert.h>', getline('.'))
+ endfor
+
+ " Test 10: Invalid find command
+ call assert_fails('cs find x', 'E560:')
+
+ " Test 11: Find places where this symbol is assigned a value
+ " this needs a cscope >= 15.8
+ " unfortunately, Travis has cscope version 15.7
+ let cscope_version=systemlist('cscope --version')[0]
+ let cs_version=str2float(matchstr(cscope_version, '\d\+\(\.\d\+\)\?'))
+ if cs_version >= 15.8
+ for cmd in ['cs find a item', 'cs find 9 item']
+ let a=execute(cmd)
+ call assert_equal(['', '(1 of 4): <<test_mf_hash>> item = (mf_hashitem_T *)lalloc_clear(sizeof(mf_hashtab_T), FALSE);'], split(a, '\n', 1))
+ call assert_equal(' item = (mf_hashitem_T *)lalloc_clear(sizeof(mf_hashtab_T), FALSE);', getline('.'))
+ cnext
+ call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
+ cnext
+ call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
+ cnext
+ call assert_equal(' item = mf_hash_find(&ht, key);', getline('.'))
+ endfor
+ endif
+
+ " Test 12: leading whitespace is not removed for cscope find text
+ let a=execute('cscope find t test_mf_hash')
+ call assert_equal(['', '(1 of 1): <<<unknown>>> test_mf_hash();'], split(a, '\n', 1))
+ call assert_equal(' test_mf_hash();', getline('.'))
+
+ " Test 13: test with scscope
+ let a=execute('scs find t Bram')
+ call assert_match('(1 of 1): <<<unknown>>> \* VIM - Vi IMproved^Iby Bram Moolenaar', a)
+ call assert_equal(' * VIM - Vi IMproved by Bram Moolenaar', getline('.'))
+
+ " Test 14: cscope help
+ for cmd in ['cs', 'cs help', 'cs xxx']
+ let a=execute(cmd)
+ call assert_match('^cscope commands:\n', a)
+ call assert_match('\nadd :', a)
+ call assert_match('\nfind :', a)
+ call assert_match('\nhelp : Show this message', a)
+ call assert_match('\nkill : Kill a connection', a)
+ call assert_match('\nreset: Reinit all connections', a)
+ call assert_match('\nshow : Show connections', a)
+ endfor
+ let a=execute('scscope help')
+ call assert_match('This cscope command does not support splitting the window\.', a)
+
+ " Test 15: reset connections
+ let a=execute('cscope reset')
+ call assert_match('\nAdded cscope database.*Xcscope.out (#0)', a)
+ call assert_match('\nAll cscope databases reset', a)
+
+ " Test 16: cscope show
+ let a=execute('cscope show')
+ call assert_match('\n 0 \d\+.*Xcscope.out\s*<none>', a)
+
+ " Test 17: cstag and 'csto' option
+ set csto=0
+ let a=execute('cstag TEST_COUNT')
+ call assert_match('(1 of 1): <<TEST_COUNT>> #define TEST_COUNT 50000', a)
+ call assert_equal('#define TEST_COUNT 50000', getline('.'))
+ set csto=1
+ let a=execute('cstag index_to_key')
+ call assert_match('(1 of 1): <<index_to_key>> #define index_to_key(i) ((i) ^ 15167)', a)
+ call assert_equal('#define index_to_key(i) ((i) ^ 15167)', getline('.'))
+ call assert_fails('cstag xxx', 'E257:')
+ call assert_fails('cstag', 'E562:')
+
+ " Test 18: 'cst' option
+ set nocst
+ call assert_fails('tag TEST_COUNT', 'E426:')
+ set cst
+ let a=execute('tag TEST_COUNT')
+ call assert_match('(1 of 1): <<TEST_COUNT>> #define TEST_COUNT 50000', a)
+ call assert_equal('#define TEST_COUNT 50000', getline('.'))
+ let a=execute('tags')
+ call assert_match('1 1 TEST_COUNT\s\+\d\+\s\+#define index_to_key', a)
+
+ " Test 19: this should trigger call to cs_print_tags()
+ " Unclear how to check result though, we just exercise the code.
+ set cst cscopequickfix=s0
+ call feedkeys(":cs find s main\<CR>", 't')
+
+ " Test 20: cscope kill
+ call assert_fails('cscope kill 2', 'E261:')
+ call assert_fails('cscope kill xxx', 'E261:')
+
+ let a=execute('cscope kill 0')
+ call assert_match('cscope connection 0 closed', a)
+
+ cscope add Xcscope.out
+ let a=execute('cscope kill Xcscope.out')
+ call assert_match('cscope connection Xcscope.out closed', a)
+
+ cscope add Xcscope.out .
+ let a=execute('cscope kill -1')
+ call assert_match('cscope connection .*Xcscope.out closed', a)
+ let a=execute('cscope kill -1')
+ call assert_equal('', a)
+
+ " Test 21: 'csprg' option
+ call assert_equal('cscope', &csprg)
+ set csprg=doesnotexist
+ call assert_fails('cscope add Xcscope2.out', 'E609:')
+ set csprg=cscope
+
+ " Test 22: multiple cscope connections
+ cscope add Xcscope.out
+ cscope add Xcscope2.out . -C
+ let a=execute('cscope show')
+ call assert_match('\n 0 \d\+.*Xcscope.out\s*<none>', a)
+ call assert_match('\n 1 \d\+.*Xcscope2.out\s*\.', a)
+
+ " Test 23: test Ex command line completion
+ call feedkeys(":cs \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"cs add find help kill reset show', @:)
+
+ call feedkeys(":scs \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"scs find', @:)
+
+ call feedkeys(":cs find \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"cs find a c d e f g i s t', @:)
+
+ call feedkeys(":cs kill \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"cs kill -1 0 1', @:)
+
+ call feedkeys(":cs add Xcscope\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"cs add Xcscope.out Xcscope2.out', @:)
+
+ " Test 24: cscope_connection()
+ call assert_equal(cscope_connection(), 1)
+ call assert_equal(cscope_connection(0, 'out'), 1)
+ call assert_equal(cscope_connection(0, 'xxx'), 1)
+ call assert_equal(cscope_connection(1, 'out'), 1)
+ call assert_equal(cscope_connection(1, 'xxx'), 0)
+ call assert_equal(cscope_connection(2, 'out'), 0)
+ call assert_equal(cscope_connection(3, 'xxx', '..'), 0)
+ call assert_equal(cscope_connection(3, 'out', 'xxx'), 0)
+ call assert_equal(cscope_connection(3, 'out', '.'), 1)
+ call assert_equal(cscope_connection(4, 'out', '.'), 0)
+
+ " CleanUp
+ call CscopeSetupOrClean(0)
+
+endfunc
+
+func Test_cscopequickfix()
+ set cscopequickfix=s-,g-,d+,c-,t+,e-,f0,i-,a-
+ call assert_equal('s-,g-,d+,c-,t+,e-,f0,i-,a-', &cscopequickfix)
+
+ call assert_fails('set cscopequickfix=x-', 'E474:')
+ call assert_fails('set cscopequickfix=s', 'E474:')
+ call assert_fails('set cscopequickfix=s7', 'E474:')
+ call assert_fails('set cscopequickfix=s-a', 'E474:')
+endfunc
+
+func Test_withoutCscopeConnection()
+ call assert_equal(cscope_connection(), 0)
+
+ call assert_fails('cscope find s main', 'E567:')
+ let a=execute('cscope show')
+ call assert_match('no cscope connections', a)
+endfunc
+
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim
index d819b7b092..e1b9651c84 100644
--- a/src/nvim/testdir/test_cursor_func.vim
+++ b/src/nvim/testdir/test_cursor_func.vim
@@ -1,13 +1,7 @@
" Tests for cursor().
func Test_wrong_arguments()
- try
- call cursor(1. 3)
- " not reached
- call assert_false(1)
- catch
- call assert_exception('E474:')
- endtry
+ call assert_fails('call cursor(1. 3)', 'E474:')
endfunc
func Test_move_cursor()
diff --git a/src/nvim/testdir/test_curswant.vim b/src/nvim/testdir/test_curswant.vim
new file mode 100644
index 0000000000..e54cd4b280
--- /dev/null
+++ b/src/nvim/testdir/test_curswant.vim
@@ -0,0 +1,23 @@
+" Tests for curswant not changing when setting an option
+
+func Test_curswant()
+ new
+ call append(0, ['1234567890', '12345'])
+
+ normal! ggf8j
+ call assert_equal(7, winsaveview().curswant)
+ let &tabstop=&tabstop
+ call assert_equal(4, winsaveview().curswant)
+
+ normal! ggf8j
+ call assert_equal(7, winsaveview().curswant)
+ let &timeoutlen=&timeoutlen
+ call assert_equal(7, winsaveview().curswant)
+
+ normal! ggf8j
+ call assert_equal(7, winsaveview().curswant)
+ let &ttimeoutlen=&ttimeoutlen
+ call assert_equal(7, winsaveview().curswant)
+
+ enew!
+endfunc
diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim
new file mode 100644
index 0000000000..ad3eec3274
--- /dev/null
+++ b/src/nvim/testdir/test_diffmode.vim
@@ -0,0 +1,740 @@
+" Tests for diff mode
+
+func Test_diff_fold_sync()
+ enew!
+ let g:update_count = 0
+ au DiffUpdated * let g:update_count += 1
+
+ let l = range(50)
+ call setline(1, l)
+ diffthis
+ let winone = win_getid()
+ new
+ let l[25] = 'diff'
+ call setline(1, l)
+ diffthis
+ let wintwo = win_getid()
+ " line 15 is inside the closed fold
+ call assert_equal(19, foldclosedend(10))
+ call win_gotoid(winone)
+ call assert_equal(19, foldclosedend(10))
+ " open the fold
+ normal zv
+ call assert_equal(-1, foldclosedend(10))
+ " fold in other window must have opened too
+ call win_gotoid(wintwo)
+ call assert_equal(-1, foldclosedend(10))
+
+ " cursor position is in sync
+ normal 23G
+ call win_gotoid(winone)
+ call assert_equal(23, getcurpos()[1])
+
+ call assert_equal(1, g:update_count)
+ au! DiffUpdated
+
+ windo diffoff
+ close!
+ set nomodified
+endfunc
+
+func Test_vert_split()
+ set diffopt=filler
+ call Common_vert_split()
+ set diffopt&
+endfunc
+
+func Test_vert_split_internal()
+ set diffopt=internal,filler
+ call Common_vert_split()
+ set diffopt&
+endfunc
+
+func Common_vert_split()
+ " Disable the title to avoid xterm keeping the wrong one.
+ set notitle noicon
+ new
+ let l = ['1 aa', '2 bb', '3 cc', '4 dd', '5 ee']
+ call setline(1, l)
+ w! Xtest
+ normal dd
+ $
+ put
+ normal kkrXoxxx
+ w! Xtest2
+ file Nop
+ normal ggoyyyjjjozzzz
+ set foldmethod=marker foldcolumn=4
+ call assert_equal(0, &diff)
+ call assert_equal('marker', &foldmethod)
+ call assert_equal(4, &foldcolumn)
+ call assert_equal(0, &scrollbind)
+ call assert_equal(0, &cursorbind)
+ call assert_equal(1, &wrap)
+
+ vert diffsplit Xtest
+ vert diffsplit Xtest2
+ call assert_equal(1, &diff)
+ call assert_equal('diff', &foldmethod)
+ call assert_equal(2, &foldcolumn)
+ call assert_equal(1, &scrollbind)
+ call assert_equal(1, &cursorbind)
+ call assert_equal(0, &wrap)
+
+ let diff_fdm = &fdm
+ let diff_fdc = &fdc
+ " repeat entering diff mode here to see if this saves the wrong settings
+ diffthis
+ " jump to second window for a moment to have filler line appear at start of
+ " first window
+ wincmd w
+ normal gg
+ wincmd p
+ normal gg
+ call assert_equal(2, winline())
+ normal j
+ call assert_equal(4, winline())
+ normal j
+ call assert_equal(5, winline())
+ normal j
+ call assert_equal(6, winline())
+ normal j
+ call assert_equal(8, winline())
+ normal j
+ call assert_equal(9, winline())
+
+ wincmd w
+ normal gg
+ call assert_equal(1, winline())
+ normal j
+ call assert_equal(2, winline())
+ normal j
+ call assert_equal(4, winline())
+ normal j
+ call assert_equal(5, winline())
+ normal j
+ call assert_equal(8, winline())
+
+ wincmd w
+ normal gg
+ call assert_equal(2, winline())
+ normal j
+ call assert_equal(3, winline())
+ normal j
+ call assert_equal(4, winline())
+ normal j
+ call assert_equal(5, winline())
+ normal j
+ call assert_equal(6, winline())
+ normal j
+ call assert_equal(7, winline())
+ normal j
+ call assert_equal(8, winline())
+
+ " Test diffoff
+ diffoff!
+ 1wincmd 2
+ let &diff = 1
+ let &fdm = diff_fdm
+ let &fdc = diff_fdc
+ 4wincmd w
+ diffoff!
+ 1wincmd w
+ call assert_equal(0, &diff)
+ call assert_equal('marker', &foldmethod)
+ call assert_equal(4, &foldcolumn)
+ call assert_equal(0, &scrollbind)
+ call assert_equal(0, &cursorbind)
+ call assert_equal(1, &wrap)
+
+ wincmd w
+ call assert_equal(0, &diff)
+ call assert_equal('marker', &foldmethod)
+ call assert_equal(4, &foldcolumn)
+ call assert_equal(0, &scrollbind)
+ call assert_equal(0, &cursorbind)
+ call assert_equal(1, &wrap)
+
+ wincmd w
+ call assert_equal(0, &diff)
+ call assert_equal('marker', &foldmethod)
+ call assert_equal(4, &foldcolumn)
+ call assert_equal(0, &scrollbind)
+ call assert_equal(0, &cursorbind)
+ call assert_equal(1, &wrap)
+
+ call delete('Xtest')
+ call delete('Xtest2')
+ windo bw!
+endfunc
+
+func Test_filler_lines()
+ " Test that diffing shows correct filler lines
+ enew!
+ put =range(4,10)
+ 1d _
+ vnew
+ put =range(1,10)
+ 1d _
+ windo diffthis
+ wincmd h
+ call assert_equal(1, line('w0'))
+ unlet! diff_fdm diff_fdc
+ windo diffoff
+ bwipe!
+ enew!
+endfunc
+
+func Test_diffget_diffput()
+ enew!
+ let l = range(50)
+ call setline(1, l)
+ call assert_fails('diffget', 'E99:')
+ diffthis
+ call assert_fails('diffget', 'E100:')
+ new
+ let l[10] = 'one'
+ let l[20] = 'two'
+ let l[30] = 'three'
+ let l[40] = 'four'
+ call setline(1, l)
+ diffthis
+ call assert_equal('one', getline(11))
+ 11diffget
+ call assert_equal('10', getline(11))
+ 21diffput
+ wincmd w
+ call assert_equal('two', getline(21))
+ normal 31Gdo
+ call assert_equal('three', getline(31))
+ call assert_equal('40', getline(41))
+ normal 41Gdp
+ wincmd w
+ call assert_equal('40', getline(41))
+ new
+ diffthis
+ call assert_fails('diffget', 'E101:')
+
+ windo diffoff
+ %bwipe!
+endfunc
+
+" Test putting two changes from one buffer to another
+func Test_diffput_two()
+ new a
+ let win_a = win_getid()
+ call setline(1, range(1, 10))
+ diffthis
+ new b
+ let win_b = win_getid()
+ call setline(1, range(1, 10))
+ 8del
+ 5del
+ diffthis
+ call win_gotoid(win_a)
+ %diffput
+ call win_gotoid(win_b)
+ call assert_equal(map(range(1, 10), 'string(v:val)'), getline(1, '$'))
+ bwipe! a
+ bwipe! b
+endfunc
+
+func Test_dp_do_buffer()
+ e! one
+ let bn1=bufnr('%')
+ let l = range(60)
+ call setline(1, l)
+ diffthis
+
+ new two
+ let l[10] = 'one'
+ let l[20] = 'two'
+ let l[30] = 'three'
+ let l[40] = 'four'
+ let l[50] = 'five'
+ call setline(1, l)
+ diffthis
+
+ " dp and do with invalid buffer number.
+ 11
+ call assert_fails('norm 99999dp', 'E102:')
+ call assert_fails('norm 99999do', 'E102:')
+ call assert_fails('diffput non_existing_buffer', 'E94:')
+ call assert_fails('diffget non_existing_buffer', 'E94:')
+
+ " dp and do with valid buffer number.
+ call assert_equal('one', getline('.'))
+ exe 'norm ' . bn1 . 'do'
+ call assert_equal('10', getline('.'))
+ 21
+ call assert_equal('two', getline('.'))
+ diffget one
+ call assert_equal('20', getline('.'))
+
+ 31
+ exe 'norm ' . bn1 . 'dp'
+ 41
+ diffput one
+ wincmd w
+ 31
+ call assert_equal('three', getline('.'))
+ 41
+ call assert_equal('four', getline('.'))
+
+ " dp and do with buffer number which is not in diff mode.
+ new not_in_diff_mode
+ let bn3=bufnr('%')
+ wincmd w
+ 51
+ call assert_fails('exe "norm" . bn3 . "dp"', 'E103:')
+ call assert_fails('exe "norm" . bn3 . "do"', 'E103:')
+ call assert_fails('diffput not_in_diff_mode', 'E94:')
+ call assert_fails('diffget not_in_diff_mode', 'E94:')
+
+ windo diffoff
+ %bwipe!
+endfunc
+
+func Test_do_lastline()
+ e! one
+ call setline(1, ['1','2','3','4','5','6'])
+ diffthis
+
+ new two
+ call setline(1, ['2','4','5'])
+ diffthis
+
+ 1
+ norm dp]c
+ norm dp]c
+ wincmd w
+ call assert_equal(4, line('$'))
+ norm G
+ norm do
+ call assert_equal(3, line('$'))
+
+ windo diffoff
+ %bwipe!
+endfunc
+
+func Test_diffoff()
+ enew!
+ call setline(1, ['Two', 'Three'])
+ redraw
+ let normattr = screenattr(1, 1)
+ diffthis
+ botright vert new
+ call setline(1, ['One', '', 'Two', 'Three'])
+ diffthis
+ redraw
+ call assert_notequal(normattr, screenattr(1, 1))
+ diffoff!
+ redraw
+ call assert_equal(normattr, screenattr(1, 1))
+ bwipe!
+ bwipe!
+endfunc
+
+func Common_icase_test()
+ edit one
+ call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve'])
+ redraw
+ let normattr = screenattr(1, 1)
+ diffthis
+
+ botright vert new two
+ call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VE'])
+ diffthis
+
+ redraw
+ call assert_equal(normattr, screenattr(1, 1))
+ call assert_equal(normattr, screenattr(2, 1))
+ call assert_notequal(normattr, screenattr(3, 1))
+ call assert_equal(normattr, screenattr(4, 1))
+
+ let dtextattr = screenattr(5, 3)
+ call assert_notequal(dtextattr, screenattr(5, 1))
+ call assert_notequal(dtextattr, screenattr(5, 5))
+
+ diffoff!
+ %bwipe!
+endfunc
+
+func Test_diffopt_icase()
+ set diffopt=icase,foldcolumn:0
+ call Common_icase_test()
+ set diffopt&
+endfunc
+
+func Test_diffopt_icase_internal()
+ set diffopt=icase,foldcolumn:0,internal
+ call Common_icase_test()
+ set diffopt&
+endfunc
+
+func Common_iwhite_test()
+ edit one
+ " Difference in trailing spaces and amount of spaces should be ignored,
+ " but not other space differences.
+ call setline(1, ["One \t", 'Two', 'Three', 'one two', 'one two', 'Four'])
+ redraw
+ let normattr = screenattr(1, 1)
+ diffthis
+
+ botright vert new two
+ call setline(1, ["One\t ", "Two\t ", 'Three', 'one two', 'onetwo', ' Four'])
+ diffthis
+
+ redraw
+ call assert_equal(normattr, screenattr(1, 1))
+ call assert_equal(normattr, screenattr(2, 1))
+ call assert_equal(normattr, screenattr(3, 1))
+ call assert_equal(normattr, screenattr(4, 1))
+ call assert_notequal(normattr, screenattr(5, 1))
+ call assert_notequal(normattr, screenattr(6, 1))
+
+ diffoff!
+ %bwipe!
+endfunc
+
+func Test_diffopt_iwhite()
+ set diffopt=iwhite,foldcolumn:0
+ call Common_iwhite_test()
+ set diffopt&
+endfunc
+
+func Test_diffopt_iwhite_internal()
+ set diffopt=internal,iwhite,foldcolumn:0
+ call Common_iwhite_test()
+ set diffopt&
+endfunc
+
+func Test_diffopt_context()
+ enew!
+ call setline(1, ['1', '2', '3', '4', '5', '6', '7'])
+ diffthis
+ new
+ call setline(1, ['1', '2', '3', '4', '5x', '6', '7'])
+ diffthis
+
+ set diffopt=context:2
+ call assert_equal('+-- 2 lines: 1', foldtextresult(1))
+ set diffopt=internal,context:2
+ call assert_equal('+-- 2 lines: 1', foldtextresult(1))
+
+ set diffopt=context:1
+ call assert_equal('+-- 3 lines: 1', foldtextresult(1))
+ set diffopt=internal,context:1
+ call assert_equal('+-- 3 lines: 1', foldtextresult(1))
+
+ diffoff!
+ %bwipe!
+ set diffopt&
+endfunc
+
+func Test_diffopt_horizontal()
+ set diffopt=internal,horizontal
+ diffsplit
+
+ call assert_equal(&columns, winwidth(1))
+ call assert_equal(&columns, winwidth(2))
+ call assert_equal(&lines, winheight(1) + winheight(2) + 3)
+ call assert_inrange(0, 1, winheight(1) - winheight(2))
+
+ set diffopt&
+ diffoff!
+ %bwipe
+endfunc
+
+func Test_diffopt_vertical()
+ set diffopt=internal,vertical
+ diffsplit
+
+ call assert_equal(&lines - 2, winheight(1))
+ call assert_equal(&lines - 2, winheight(2))
+ call assert_equal(&columns, winwidth(1) + winwidth(2) + 1)
+ call assert_inrange(0, 1, winwidth(1) - winwidth(2))
+
+ set diffopt&
+ diffoff!
+ %bwipe
+endfunc
+
+func Test_diffopt_hiddenoff()
+ set diffopt=internal,filler,foldcolumn:0,hiddenoff
+ e! one
+ call setline(1, ['Two', 'Three'])
+ redraw
+ let normattr = screenattr(1, 1)
+ diffthis
+ botright vert new two
+ call setline(1, ['One', 'Four'])
+ diffthis
+ redraw
+ call assert_notequal(normattr, screenattr(1, 1))
+ set hidden
+ close
+ redraw
+ " should not diffing with hidden buffer two while 'hiddenoff' is enabled
+ call assert_equal(normattr, screenattr(1, 1))
+
+ bwipe!
+ bwipe!
+ set hidden& diffopt&
+endfunc
+
+func Test_diffoff_hidden()
+ set diffopt=internal,filler,foldcolumn:0
+ e! one
+ call setline(1, ['Two', 'Three'])
+ redraw
+ let normattr = screenattr(1, 1)
+ diffthis
+ botright vert new two
+ call setline(1, ['One', 'Four'])
+ diffthis
+ redraw
+ call assert_notequal(normattr, screenattr(1, 1))
+ set hidden
+ close
+ redraw
+ " diffing with hidden buffer two
+ call assert_notequal(normattr, screenattr(1, 1))
+ diffoff
+ redraw
+ call assert_equal(normattr, screenattr(1, 1))
+ diffthis
+ redraw
+ " still diffing with hidden buffer two
+ call assert_notequal(normattr, screenattr(1, 1))
+ diffoff!
+ redraw
+ call assert_equal(normattr, screenattr(1, 1))
+ diffthis
+ redraw
+ " no longer diffing with hidden buffer two
+ call assert_equal(normattr, screenattr(1, 1))
+
+ bwipe!
+ bwipe!
+ set hidden& diffopt&
+endfunc
+
+func Test_setting_cursor()
+ new Xtest1
+ put =range(1,90)
+ wq
+ new Xtest2
+ put =range(1,100)
+ wq
+
+ tabe Xtest2
+ $
+ diffsp Xtest1
+ tabclose
+
+ call delete('Xtest1')
+ call delete('Xtest2')
+endfunc
+
+func Test_diff_move_to()
+ new
+ call setline(1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
+ diffthis
+ vnew
+ call setline(1, [1, '2x', 3, 4, 4, 5, '6x', 7, '8x', 9, '10x'])
+ diffthis
+ norm ]c
+ call assert_equal(2, line('.'))
+ norm 3]c
+ call assert_equal(9, line('.'))
+ norm 10]c
+ call assert_equal(11, line('.'))
+ norm [c
+ call assert_equal(9, line('.'))
+ norm 2[c
+ call assert_equal(5, line('.'))
+ norm 10[c
+ call assert_equal(2, line('.'))
+ %bwipe!
+endfunc
+
+func Test_diffexpr()
+ if !executable('diff')
+ return
+ endif
+
+ func DiffExpr()
+ " Prepend some text to check diff type detection
+ call writefile(['warning', ' message'], v:fname_out)
+ silent exe '!diff ' . v:fname_in . ' ' . v:fname_new . '>>' . v:fname_out
+ endfunc
+ set diffexpr=DiffExpr()
+ set diffopt=foldcolumn:0
+
+ enew!
+ call setline(1, ['one', 'two', 'three'])
+ redraw
+ let normattr = screenattr(1, 1)
+ diffthis
+
+ botright vert new
+ call setline(1, ['one', 'two', 'three.'])
+ diffthis
+
+ redraw
+ call assert_equal(normattr, screenattr(1, 1))
+ call assert_equal(normattr, screenattr(2, 1))
+ call assert_notequal(normattr, screenattr(3, 1))
+
+ diffoff!
+ %bwipe!
+ set diffexpr& diffopt&
+endfunc
+
+func Test_diffpatch()
+ " The patch program on MS-Windows may fail or hang.
+ if !executable('patch') || !has('unix')
+ return
+ endif
+ new
+ insert
+***************
+*** 1,3 ****
+ 1
+! 2
+ 3
+--- 1,4 ----
+ 1
+! 2x
+ 3
++ 4
+.
+ saveas! Xpatch
+ bwipe!
+ new
+ call assert_fails('diffpatch Xpatch', 'E816:')
+
+ for name in ['Xpatch', 'Xpatch$HOME', 'Xpa''tch']
+ call setline(1, ['1', '2', '3'])
+ if name != 'Xpatch'
+ call rename('Xpatch', name)
+ endif
+ exe 'diffpatch ' . escape(name, '$')
+ call assert_equal(['1', '2x', '3', '4'], getline(1, '$'))
+ if name != 'Xpatch'
+ call rename(name, 'Xpatch')
+ endif
+ bwipe!
+ endfor
+
+ call delete('Xpatch')
+ bwipe!
+endfunc
+
+func Test_diff_too_many_buffers()
+ for i in range(1, 8)
+ exe "new Xtest" . i
+ diffthis
+ endfor
+ new Xtest9
+ call assert_fails('diffthis', 'E96:')
+ %bwipe!
+endfunc
+
+func Test_diff_nomodifiable()
+ new
+ call setline(1, [1, 2, 3, 4])
+ setl nomodifiable
+ diffthis
+ vnew
+ call setline(1, ['1x', 2, 3, 3, 4])
+ diffthis
+ call assert_fails('norm dp', 'E793:')
+ setl nomodifiable
+ call assert_fails('norm do', 'E21:')
+ %bwipe!
+endfunc
+
+func Test_diff_filler()
+ new
+ call setline(1, [1, 2, 3, 'x', 4])
+ diffthis
+ vnew
+ call setline(1, [1, 2, 'y', 'y', 3, 4])
+ diffthis
+ redraw
+
+ call assert_equal([0, 0, 0, 0, 0, 0, 0, 1, 0], map(range(-1, 7), 'diff_filler(v:val)'))
+ wincmd w
+ call assert_equal([0, 0, 0, 0, 2, 0, 0, 0], map(range(-1, 6), 'diff_filler(v:val)'))
+
+ %bwipe!
+endfunc
+
+func Test_diff_lastline()
+ enew!
+ only!
+ call setline(1, ['This is a ', 'line with five ', 'rows'])
+ diffthis
+ botright vert new
+ call setline(1, ['This is', 'a line with ', 'four rows'])
+ diffthis
+ 1
+ call feedkeys("Je a\<CR>", 'tx')
+ call feedkeys("Je a\<CR>", 'tx')
+ let w1lines = winline()
+ wincmd w
+ $
+ let w2lines = winline()
+ call assert_equal(w2lines, w1lines)
+ bwipe!
+ bwipe!
+endfunc
+
+func Test_diff_with_cursorline()
+ if !CanRunVimInTerminal()
+ return
+ endif
+
+ call writefile([
+ \ 'hi CursorLine ctermbg=red ctermfg=white',
+ \ 'set cursorline',
+ \ 'call setline(1, ["foo","foo","foo","bar"])',
+ \ 'vnew',
+ \ 'call setline(1, ["bee","foo","foo","baz"])',
+ \ 'windo diffthis',
+ \ '2wincmd w',
+ \ ], 'Xtest_diff_cursorline')
+ let buf = RunVimInTerminal('-S Xtest_diff_cursorline', {})
+
+ call VerifyScreenDump(buf, 'Test_diff_with_cursorline_01', {})
+ call term_sendkeys(buf, "j")
+ call VerifyScreenDump(buf, 'Test_diff_with_cursorline_02', {})
+ call term_sendkeys(buf, "j")
+ call VerifyScreenDump(buf, 'Test_diff_with_cursorline_03', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('Xtest_diff_cursorline')
+endfunc
+
+func Test_diff_of_diff()
+ if !CanRunVimInTerminal()
+ return
+ endif
+
+ call writefile([
+ \ 'call setline(1, ["aa","bb","cc","@@ -3,2 +5,7 @@","dd","ee","ff"])',
+ \ 'vnew',
+ \ 'call setline(1, ["aa","bb","cc"])',
+ \ 'windo diffthis',
+ \ ], 'Xtest_diff_diff')
+ let buf = RunVimInTerminal('-S Xtest_diff_diff', {})
+
+ call VerifyScreenDump(buf, 'Test_diff_of_diff_01', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('Xtest_diff_diff')
+endfunc
diff --git a/src/nvim/testdir/test_digraph.vim b/src/nvim/testdir/test_digraph.vim
new file mode 100644
index 0000000000..271066df41
--- /dev/null
+++ b/src/nvim/testdir/test_digraph.vim
@@ -0,0 +1,468 @@
+" Tests for digraphs
+
+if !has("digraphs") || !has("multi_byte")
+ finish
+endif
+
+func Put_Dig(chars)
+ exe "norm! o\<c-k>".a:chars
+endfu
+
+func Put_Dig_BS(char1, char2)
+ exe "norm! o".a:char1."\<bs>".a:char2
+endfu
+
+func Test_digraphs()
+ new
+ call Put_Dig("00")
+ call assert_equal("∞", getline('.'))
+ " not a digraph
+ call Put_Dig("el")
+ call assert_equal("l", getline('.'))
+ call Put_Dig("ht")
+ call assert_equal("þ", getline('.'))
+ " digraph "ab" is the same as "ba"
+ call Put_Dig("ab")
+ call Put_Dig("ba")
+ call assert_equal(["ã°","ã°"], getline(line('.')-1,line('.')))
+ " Euro sign
+ call Put_Dig("e=")
+ call Put_Dig("=e")
+ call Put_Dig("Eu")
+ call Put_Dig("uE")
+ call assert_equal(['е']+repeat(["€"],3), getline(line('.')-3,line('.')))
+ " Rouble sign
+ call Put_Dig("R=")
+ call Put_Dig("=R")
+ call Put_Dig("=P")
+ call Put_Dig("P=")
+ call assert_equal(['Р']+repeat(["₽"],2)+['П'], getline(line('.')-3,line('.')))
+ " Not a digraph
+ call Put_Dig("a\<bs>")
+ call Put_Dig("\<bs>a")
+ call assert_equal(["<BS>", "<BS>a"], getline(line('.')-1,line('.')))
+ " Grave
+ call Put_Dig("a!")
+ call Put_Dig("!e")
+ call Put_Dig("b!") " not defined
+ call assert_equal(["à", "è", "!"], getline(line('.')-2,line('.')))
+ " Acute accent
+ call Put_Dig("a'")
+ call Put_Dig("'e")
+ call Put_Dig("b'") " not defined
+ call assert_equal(["á", "é", "'"], getline(line('.')-2,line('.')))
+ " Cicumflex
+ call Put_Dig("a>")
+ call Put_Dig(">e")
+ call Put_Dig("b>") " not defined
+ call assert_equal(['â', 'ê', '>'], getline(line('.')-2,line('.')))
+ " Tilde
+ call Put_Dig("o~")
+ call Put_Dig("~u") " not defined
+ call Put_Dig("z~") " not defined
+ call assert_equal(['õ', 'u', '~'], getline(line('.')-2,line('.')))
+ " Tilde
+ call Put_Dig("o?")
+ call Put_Dig("?u")
+ call Put_Dig("z?") " not defined
+ call assert_equal(['õ', 'ũ', '?'], getline(line('.')-2,line('.')))
+ " Macron
+ call Put_Dig("o-")
+ call Put_Dig("-u")
+ call Put_Dig("z-") " not defined
+ call assert_equal(['Å', 'Å«', '-'], getline(line('.')-2,line('.')))
+ " Breve
+ call Put_Dig("o(")
+ call Put_Dig("(u")
+ call Put_Dig("z(") " not defined
+ call assert_equal(['Å', 'Å­', '('], getline(line('.')-2,line('.')))
+ " Dot above
+ call Put_Dig("b.")
+ call Put_Dig(".e")
+ call Put_Dig("a.") " not defined
+ call assert_equal(['ḃ', 'ė', '.'], getline(line('.')-2,line('.')))
+ " Diaresis
+ call Put_Dig("a:")
+ call Put_Dig(":u")
+ call Put_Dig("b:") " not defined
+ call assert_equal(['ä', 'ü', ':'], getline(line('.')-2,line('.')))
+ " Cedilla
+ call Put_Dig("',")
+ call Put_Dig(",C")
+ call Put_Dig("b,") " not defined
+ call assert_equal(['¸', 'Ç', ','], getline(line('.')-2,line('.')))
+ " Underline
+ call Put_Dig("B_")
+ call Put_Dig("_t")
+ call Put_Dig("a_") " not defined
+ call assert_equal(['Ḇ', 'ṯ', '_'], getline(line('.')-2,line('.')))
+ " Stroke
+ call Put_Dig("j/")
+ call Put_Dig("/l")
+ call Put_Dig("b/") " not defined
+ call assert_equal(['/', 'Å‚', '/'], getline(line('.')-2,line('.')))
+ " Double acute
+ call Put_Dig('O"')
+ call Put_Dig('"y')
+ call Put_Dig('b"') " not defined
+ call assert_equal(['Å', 'ÿ', '"'], getline(line('.')-2,line('.')))
+ " Ogonek
+ call Put_Dig('u;')
+ call Put_Dig(';E')
+ call Put_Dig('b;') " not defined
+ call assert_equal(['ų', 'Ę', ';'], getline(line('.')-2,line('.')))
+ " Caron
+ call Put_Dig('u<')
+ call Put_Dig('<E')
+ call Put_Dig('b<') " not defined
+ call assert_equal(['Ç”', 'Äš', '<'], getline(line('.')-2,line('.')))
+ " Ring above
+ call Put_Dig('u0')
+ call Put_Dig('0E') " not defined
+ call Put_Dig('b0') " not defined
+ call assert_equal(['ů', 'E', '0'], getline(line('.')-2,line('.')))
+ " Hook
+ call Put_Dig('u2')
+ call Put_Dig('2E')
+ call Put_Dig('b2') " not defined
+ call assert_equal(['ủ', 'Ẻ', '2'], getline(line('.')-2,line('.')))
+ " Horn
+ call Put_Dig('u9')
+ call Put_Dig('9E') " not defined
+ call Put_Dig('b9') " not defined
+ call assert_equal(['ư', 'E', '9'], getline(line('.')-2,line('.')))
+ " Cyrillic
+ call Put_Dig('u=')
+ call Put_Dig('=b')
+ call Put_Dig('=_')
+ call assert_equal(['у', 'б', '〓'], getline(line('.')-2,line('.')))
+ " Greek
+ call Put_Dig('u*')
+ call Put_Dig('*b')
+ call Put_Dig('*_')
+ call assert_equal(['υ', 'β', '々'], getline(line('.')-2,line('.')))
+ " Greek/Cyrillic special
+ call Put_Dig('u%')
+ call Put_Dig('%b') " not defined
+ call Put_Dig('%_') " not defined
+ call assert_equal(['Ï', 'b', '_'], getline(line('.')-2,line('.')))
+ " Arabic
+ call Put_Dig('u+')
+ call Put_Dig('+b')
+ call Put_Dig('+_') " japanese industrial symbol
+ call assert_equal(['+', 'ب', '〄'], getline(line('.')-2,line('.')))
+ " Hebrew
+ call Put_Dig('Q+')
+ call Put_Dig('+B')
+ call Put_Dig('+X')
+ call assert_equal(['ק', 'ב', 'ח'], getline(line('.')-2,line('.')))
+ " Latin
+ call Put_Dig('a3')
+ call Put_Dig('A3')
+ call Put_Dig('3X')
+ call assert_equal(['Ç£', 'Ç¢', 'X'], getline(line('.')-2,line('.')))
+ " Bopomofo
+ call Put_Dig('a4')
+ call Put_Dig('A4')
+ call Put_Dig('4X')
+ call assert_equal(['ㄚ', '4', 'X'], getline(line('.')-2,line('.')))
+ " Hiragana
+ call Put_Dig('a5')
+ call Put_Dig('A5')
+ call Put_Dig('5X')
+ call assert_equal(['ã‚', 'ã', 'X'], getline(line('.')-2,line('.')))
+ " Katakana
+ call Put_Dig('a6')
+ call Put_Dig('A6')
+ call Put_Dig('6X')
+ call assert_equal(['ã‚¡', 'ã‚¢', 'X'], getline(line('.')-2,line('.')))
+ " Superscripts
+ call Put_Dig('1S')
+ call Put_Dig('2S')
+ call Put_Dig('3S')
+ call assert_equal(['¹', '²', '³'], getline(line('.')-2,line('.')))
+ " Subscripts
+ call Put_Dig('1s')
+ call Put_Dig('2s')
+ call Put_Dig('3s')
+ call assert_equal(['â‚', 'â‚‚', '₃'], getline(line('.')-2,line('.')))
+ " Eszet (only lowercase)
+ call Put_Dig("ss")
+ call Put_Dig("SS") " start of string
+ call assert_equal(["ß", "˜"], getline(line('.')-1,line('.')))
+ " High bit set
+ call Put_Dig("a ")
+ call Put_Dig(" A")
+ call assert_equal(['á', 'Ã'], getline(line('.')-1,line('.')))
+ " Escape is not part of a digraph
+ call Put_Dig("a\<esc>")
+ call Put_Dig("\<esc>A")
+ call assert_equal(['', 'A'], getline(line('.')-1,line('.')))
+ " define some custom digraphs
+ " old: 00 ∞
+ " old: el l
+ digraph 00 9216
+ digraph el 0252
+ call Put_Dig("00")
+ call Put_Dig("el")
+ " Reset digraphs
+ digraph 00 8734
+ digraph el 108
+ call Put_Dig("00")
+ call Put_Dig("el")
+ call assert_equal(['â€', 'ü', '∞', 'l'], getline(line('.')-3,line('.')))
+ bw!
+endfunc
+
+func Test_digraphs_option()
+ " reset whichwrap option, so that testing <esc><bs>A works,
+ " without moving up a line
+ set digraph ww=
+ new
+ call Put_Dig_BS("0","0")
+ call assert_equal("∞", getline('.'))
+ " not a digraph
+ call Put_Dig_BS("e","l")
+ call assert_equal("l", getline('.'))
+ call Put_Dig_BS("h","t")
+ call assert_equal("þ", getline('.'))
+ " digraph "ab" is the same as "ba"
+ call Put_Dig_BS("a","b")
+ call Put_Dig_BS("b","a")
+ call assert_equal(["ã°","ã°"], getline(line('.')-1,line('.')))
+ " Euro sign
+ call Put_Dig_BS("e","=")
+ call Put_Dig_BS("=","e")
+ call Put_Dig_BS("E","u")
+ call Put_Dig_BS("u","E")
+ call assert_equal(['е']+repeat(["€"],3), getline(line('.')-3,line('.')))
+ " Rouble sign
+ call Put_Dig_BS("R","=")
+ call Put_Dig_BS("=","R")
+ call Put_Dig_BS("=","P")
+ call Put_Dig_BS("P","=")
+ call assert_equal(['Р']+repeat(["₽"],2)+['П'], getline(line('.')-3,line('.')))
+ " Not a digraph: this is different from <c-k>!
+ call Put_Dig_BS("a","\<bs>")
+ call Put_Dig_BS("\<bs>","a")
+ call assert_equal(['','a'], getline(line('.')-1,line('.')))
+ " Grave
+ call Put_Dig_BS("a","!")
+ call Put_Dig_BS("!","e")
+ call Put_Dig_BS("b","!") " not defined
+ call assert_equal(["à", "è", "!"], getline(line('.')-2,line('.')))
+ " Acute accent
+ call Put_Dig_BS("a","'")
+ call Put_Dig_BS("'","e")
+ call Put_Dig_BS("b","'") " not defined
+ call assert_equal(["á", "é", "'"], getline(line('.')-2,line('.')))
+ " Cicumflex
+ call Put_Dig_BS("a",">")
+ call Put_Dig_BS(">","e")
+ call Put_Dig_BS("b",">") " not defined
+ call assert_equal(['â', 'ê', '>'], getline(line('.')-2,line('.')))
+ " Tilde
+ call Put_Dig_BS("o","~")
+ call Put_Dig_BS("~","u") " not defined
+ call Put_Dig_BS("z","~") " not defined
+ call assert_equal(['õ', 'u', '~'], getline(line('.')-2,line('.')))
+ " Tilde
+ call Put_Dig_BS("o","?")
+ call Put_Dig_BS("?","u")
+ call Put_Dig_BS("z","?") " not defined
+ call assert_equal(['õ', 'ũ', '?'], getline(line('.')-2,line('.')))
+ " Macron
+ call Put_Dig_BS("o","-")
+ call Put_Dig_BS("-","u")
+ call Put_Dig_BS("z","-") " not defined
+ call assert_equal(['Å', 'Å«', '-'], getline(line('.')-2,line('.')))
+ " Breve
+ call Put_Dig_BS("o","(")
+ call Put_Dig_BS("(","u")
+ call Put_Dig_BS("z","(") " not defined
+ call assert_equal(['Å', 'Å­', '('], getline(line('.')-2,line('.')))
+ " Dot above
+ call Put_Dig_BS("b",".")
+ call Put_Dig_BS(".","e")
+ call Put_Dig_BS("a",".") " not defined
+ call assert_equal(['ḃ', 'ė', '.'], getline(line('.')-2,line('.')))
+ " Diaresis
+ call Put_Dig_BS("a",":")
+ call Put_Dig_BS(":","u")
+ call Put_Dig_BS("b",":") " not defined
+ call assert_equal(['ä', 'ü', ':'], getline(line('.')-2,line('.')))
+ " Cedilla
+ call Put_Dig_BS("'",",")
+ call Put_Dig_BS(",","C")
+ call Put_Dig_BS("b",",") " not defined
+ call assert_equal(['¸', 'Ç', ','], getline(line('.')-2,line('.')))
+ " Underline
+ call Put_Dig_BS("B","_")
+ call Put_Dig_BS("_","t")
+ call Put_Dig_BS("a","_") " not defined
+ call assert_equal(['Ḇ', 'ṯ', '_'], getline(line('.')-2,line('.')))
+ " Stroke
+ call Put_Dig_BS("j","/")
+ call Put_Dig_BS("/","l")
+ call Put_Dig_BS("b","/") " not defined
+ call assert_equal(['/', 'Å‚', '/'], getline(line('.')-2,line('.')))
+ " Double acute
+ call Put_Dig_BS('O','"')
+ call Put_Dig_BS('"','y')
+ call Put_Dig_BS('b','"') " not defined
+ call assert_equal(['Å', 'ÿ', '"'], getline(line('.')-2,line('.')))
+ " Ogonek
+ call Put_Dig_BS('u',';')
+ call Put_Dig_BS(';','E')
+ call Put_Dig_BS('b',';') " not defined
+ call assert_equal(['ų', 'Ę', ';'], getline(line('.')-2,line('.')))
+ " Caron
+ call Put_Dig_BS('u','<')
+ call Put_Dig_BS('<','E')
+ call Put_Dig_BS('b','<') " not defined
+ call assert_equal(['Ç”', 'Äš', '<'], getline(line('.')-2,line('.')))
+ " Ring above
+ call Put_Dig_BS('u','0')
+ call Put_Dig_BS('0','E') " not defined
+ call Put_Dig_BS('b','0') " not defined
+ call assert_equal(['ů', 'E', '0'], getline(line('.')-2,line('.')))
+ " Hook
+ call Put_Dig_BS('u','2')
+ call Put_Dig_BS('2','E')
+ call Put_Dig_BS('b','2') " not defined
+ call assert_equal(['ủ', 'Ẻ', '2'], getline(line('.')-2,line('.')))
+ " Horn
+ call Put_Dig_BS('u','9')
+ call Put_Dig_BS('9','E') " not defined
+ call Put_Dig_BS('b','9') " not defined
+ call assert_equal(['ư', 'E', '9'], getline(line('.')-2,line('.')))
+ " Cyrillic
+ call Put_Dig_BS('u','=')
+ call Put_Dig_BS('=','b')
+ call Put_Dig_BS('=','_')
+ call assert_equal(['у', 'б', '〓'], getline(line('.')-2,line('.')))
+ " Greek
+ call Put_Dig_BS('u','*')
+ call Put_Dig_BS('*','b')
+ call Put_Dig_BS('*','_')
+ call assert_equal(['υ', 'β', '々'], getline(line('.')-2,line('.')))
+ " Greek/Cyrillic special
+ call Put_Dig_BS('u','%')
+ call Put_Dig_BS('%','b') " not defined
+ call Put_Dig_BS('%','_') " not defined
+ call assert_equal(['Ï', 'b', '_'], getline(line('.')-2,line('.')))
+ " Arabic
+ call Put_Dig_BS('u','+')
+ call Put_Dig_BS('+','b')
+ call Put_Dig_BS('+','_') " japanese industrial symbol
+ call assert_equal(['+', 'ب', '〄'], getline(line('.')-2,line('.')))
+ " Hebrew
+ call Put_Dig_BS('Q','+')
+ call Put_Dig_BS('+','B')
+ call Put_Dig_BS('+','X')
+ call assert_equal(['ק', 'ב', 'ח'], getline(line('.')-2,line('.')))
+ " Latin
+ call Put_Dig_BS('a','3')
+ call Put_Dig_BS('A','3')
+ call Put_Dig_BS('3','X')
+ call assert_equal(['Ç£', 'Ç¢', 'X'], getline(line('.')-2,line('.')))
+ " Bopomofo
+ call Put_Dig_BS('a','4')
+ call Put_Dig_BS('A','4')
+ call Put_Dig_BS('4','X')
+ call assert_equal(['ㄚ', '4', 'X'], getline(line('.')-2,line('.')))
+ " Hiragana
+ call Put_Dig_BS('a','5')
+ call Put_Dig_BS('A','5')
+ call Put_Dig_BS('5','X')
+ call assert_equal(['ã‚', 'ã', 'X'], getline(line('.')-2,line('.')))
+ " Katakana
+ call Put_Dig_BS('a','6')
+ call Put_Dig_BS('A','6')
+ call Put_Dig_BS('6','X')
+ call assert_equal(['ã‚¡', 'ã‚¢', 'X'], getline(line('.')-2,line('.')))
+ " Superscripts
+ call Put_Dig_BS('1','S')
+ call Put_Dig_BS('2','S')
+ call Put_Dig_BS('3','S')
+ call assert_equal(['¹', '²', '³'], getline(line('.')-2,line('.')))
+ " Subscripts
+ call Put_Dig_BS('1','s')
+ call Put_Dig_BS('2','s')
+ call Put_Dig_BS('3','s')
+ call assert_equal(['â‚', 'â‚‚', '₃'], getline(line('.')-2,line('.')))
+ " Eszet (only lowercase)
+ call Put_Dig_BS("s","s")
+ call Put_Dig_BS("S","S") " start of string
+ call assert_equal(["ß", "˜"], getline(line('.')-1,line('.')))
+ " High bit set (different from <c-k>)
+ call Put_Dig_BS("a"," ")
+ call Put_Dig_BS(" ","A")
+ call assert_equal([' ', 'A'], getline(line('.')-1,line('.')))
+ " Escape is not part of a digraph (different from <c-k>)
+ call Put_Dig_BS("a","\<esc>")
+ call Put_Dig_BS("\<esc>","A")
+ call assert_equal(['', ''], getline(line('.')-1,line('.')))
+ " define some custom digraphs
+ " old: 00 ∞
+ " old: el l
+ digraph 00 9216
+ digraph el 0252
+ call Put_Dig_BS("0","0")
+ call Put_Dig_BS("e","l")
+ " Reset digraphs
+ digraph 00 8734
+ digraph el 108
+ call Put_Dig_BS("0","0")
+ call Put_Dig_BS("e","l")
+ call assert_equal(['â€', 'ü', '∞', 'l'], getline(line('.')-3,line('.')))
+ set nodigraph ww&vim
+ bw!
+endfunc
+
+func Test_digraphs_output()
+ new
+ let out = execute(':digraph')
+ call assert_equal('Eu € 8364', matchstr(out, '\C\<Eu\D*8364\>'))
+ call assert_equal('=e € 8364', matchstr(out, '\C=e\D*8364\>'))
+ call assert_equal('=R ₽ 8381', matchstr(out, '\C=R\D*8381\>'))
+ call assert_equal('=P ₽ 8381', matchstr(out, '\C=P\D*8381\>'))
+ call assert_equal('o: ö 246', matchstr(out, '\C\<o:\D*246\>'))
+ call assert_equal('v4 ㄪ 12586', matchstr(out, '\C\<v4\D*12586\>'))
+ call assert_equal("'0 Ëš 730", matchstr(out, '\C''0\D*730\>'))
+ call assert_equal('Z% Ж 1046', matchstr(out, '\C\<Z%\D*1046\>'))
+ call assert_equal('u- Å« 363', matchstr(out, '\C\<u-\D*363\>'))
+ call assert_equal('SH ^A 1', matchstr(out, '\C\<SH\D*1\>'))
+ bw!
+endfunc
+
+func Test_loadkeymap()
+ if !has('keymap')
+ return
+ endif
+ new
+ set keymap=czech
+ set iminsert=0
+ call feedkeys("o|\<c-^>|01234567890|\<esc>", 'tx')
+ call assert_equal("|'é+ěšÄřžýáíé'", getline('.'))
+ " reset keymap and encoding option
+ set keymap=
+ bw!
+endfunc
+
+func Test_digraph_cmndline()
+ " Create digraph on commandline
+ " This is a hack, to let Vim create the digraph in commandline mode
+ let s = ''
+ exe "sil! norm! :let s.='\<c-k>Eu'\<cr>"
+ call assert_equal("€", s)
+endfunc
+
+func Test_show_digraph()
+ new
+ call Put_Dig("e=")
+ call assert_equal("\n<е> 1077, Hex 0435, Oct 2065, Digr e=", execute('ascii'))
+ bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim
new file mode 100644
index 0000000000..0ed672d577
--- /dev/null
+++ b/src/nvim/testdir/test_display.vim
@@ -0,0 +1,71 @@
+" Test for displaying stuff
+
+" Nvim: `:set term` is not supported.
+" if !has('gui_running') && has('unix')
+" set term=ansi
+" endif
+
+source view_util.vim
+
+func! Test_display_foldcolumn()
+ if !has("folding")
+ return
+ endif
+ new
+ vnew
+ vert resize 25
+ call assert_equal(25, winwidth(winnr()))
+ set isprint=@
+
+ 1put='e more noise blah blah‚ more stuff here'
+
+ let expect = [
+ \ "e more noise blah blah<82",
+ \ "> more stuff here "
+ \ ]
+
+ call cursor(2, 1)
+ norm! zt
+ let lines=ScreenLines([1,2], winwidth(0))
+ call assert_equal(expect, lines)
+ set fdc=2
+ let lines=ScreenLines([1,2], winwidth(0))
+ let expect = [
+ \ " e more noise blah blah<",
+ \ " 82> more stuff here "
+ \ ]
+ call assert_equal(expect, lines)
+
+ quit!
+ quit!
+endfunc
+
+func! Test_display_foldtext_mbyte()
+ if !has("folding") || !has("multi_byte")
+ return
+ endif
+ call NewWindow(10, 40)
+ call append(0, range(1,20))
+ exe "set foldmethod=manual foldtext=foldtext() fillchars=fold:\u2500,vert:\u2502 fdc=2"
+ call cursor(2, 1)
+ norm! zf13G
+ let lines=ScreenLines([1,3], winwidth(0)+1)
+ let expect=[
+ \ " 1 \u2502",
+ \ "+ +-- 12 lines: 2". repeat("\u2500", 23). "\u2502",
+ \ " 14 \u2502",
+ \ ]
+ call assert_equal(expect, lines)
+
+ set fillchars=fold:-,vert:\|
+ let lines=ScreenLines([1,3], winwidth(0)+1)
+ let expect=[
+ \ " 1 |",
+ \ "+ +-- 12 lines: 2". repeat("-", 23). "|",
+ \ " 14 |",
+ \ ]
+ call assert_equal(expect, lines)
+
+ set foldtext& fillchars& foldmethod& fdc&
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim
new file mode 100644
index 0000000000..f8946c6929
--- /dev/null
+++ b/src/nvim/testdir/test_edit.vim
@@ -0,0 +1,1445 @@
+" Test for edit functions
+"
+if exists("+t_kD")
+ let &t_kD="[3;*~"
+endif
+
+" Needed for testing basic rightleft: Test_edit_rightleft
+source view_util.vim
+
+" Needs to come first until the bug in getchar() is
+" fixed: https://groups.google.com/d/msg/vim_dev/fXL9yme4H4c/bOR-U6_bAQAJ
+func! Test_edit_00b()
+ new
+ call setline(1, ['abc '])
+ inoreabbr <buffer> h here some more
+ call cursor(1, 4)
+ " <c-l> expands the abbreviation and ends insertmode
+ call feedkeys(":set im\<cr> h\<c-l>:set noim\<cr>", 'tix')
+ call assert_equal(['abc here some more '], getline(1,'$'))
+ iunabbr <buffer> h
+ bw!
+endfunc
+
+func! Test_edit_01()
+ " set for Travis CI?
+ " set nocp noesckeys
+ new
+ " 1) empty buffer
+ call assert_equal([''], getline(1,'$'))
+ " 2) delete in an empty line
+ call feedkeys("i\<del>\<esc>", 'tnix')
+ call assert_equal([''], getline(1,'$'))
+ %d
+ " 3) delete one character
+ call setline(1, 'a')
+ call feedkeys("i\<del>\<esc>", 'tnix')
+ call assert_equal([''], getline(1,'$'))
+ %d
+ " 4) delete a multibyte character
+ if has("multi_byte")
+ call setline(1, "\u0401")
+ call feedkeys("i\<del>\<esc>", 'tnix')
+ call assert_equal([''], getline(1,'$'))
+ %d
+ endif
+ " 5.1) delete linebreak with 'bs' option containing eol
+ let _bs=&bs
+ set bs=eol
+ call setline(1, ["abc def", "ghi jkl"])
+ call cursor(1, 1)
+ call feedkeys("A\<del>\<esc>", 'tnix')
+ call assert_equal(['abc defghi jkl'], getline(1, 2))
+ %d
+ " 5.2) delete linebreak with backspace option w/out eol
+ set bs=
+ call setline(1, ["abc def", "ghi jkl"])
+ call cursor(1, 1)
+ call feedkeys("A\<del>\<esc>", 'tnix')
+ call assert_equal(["abc def", "ghi jkl"], getline(1, 2))
+ let &bs=_bs
+ bw!
+endfunc
+
+func! Test_edit_02()
+ " Change cursor position in InsertCharPre command
+ new
+ call setline(1, 'abc')
+ call cursor(1, 1)
+ fu! DoIt(...)
+ call cursor(1, 4)
+ if len(a:000)
+ let v:char=a:1
+ endif
+ endfu
+ au InsertCharPre <buffer> :call DoIt('y')
+ call feedkeys("ix\<esc>", 'tnix')
+ call assert_equal(['abcy'], getline(1, '$'))
+ " Setting <Enter> in InsertCharPre
+ au! InsertCharPre <buffer> :call DoIt("\n")
+ call setline(1, 'abc')
+ call cursor(1, 1)
+ call feedkeys("ix\<esc>", 'tnix')
+ call assert_equal(['abc', ''], getline(1, '$'))
+ %d
+ au! InsertCharPre
+ " Change cursor position in InsertEnter command
+ " 1) when setting v:char, keeps changed cursor position
+ au! InsertEnter <buffer> :call DoIt('y')
+ call setline(1, 'abc')
+ call cursor(1, 1)
+ call feedkeys("ix\<esc>", 'tnix')
+ call assert_equal(['abxc'], getline(1, '$'))
+ " 2) when not setting v:char, restores changed cursor position
+ au! InsertEnter <buffer> :call DoIt()
+ call setline(1, 'abc')
+ call cursor(1, 1)
+ call feedkeys("ix\<esc>", 'tnix')
+ call assert_equal(['xabc'], getline(1, '$'))
+ au! InsertEnter
+ delfu DoIt
+ bw!
+endfunc
+
+func! Test_edit_03()
+ " Change cursor after <c-o> command to end of line
+ new
+ call setline(1, 'abc')
+ call cursor(1, 1)
+ call feedkeys("i\<c-o>$y\<esc>", 'tnix')
+ call assert_equal(['abcy'], getline(1, '$'))
+ %d
+ call setline(1, 'abc')
+ call cursor(1, 1)
+ call feedkeys("i\<c-o>80|y\<esc>", 'tnix')
+ call assert_equal(['abcy'], getline(1, '$'))
+ %d
+ call setline(1, 'abc')
+ call feedkeys("Ad\<c-o>:s/$/efg/\<cr>hij", 'tnix')
+ call assert_equal(['hijabcdefg'], getline(1, '$'))
+ bw!
+endfunc
+
+func! Test_edit_04()
+ " test for :stopinsert
+ new
+ call setline(1, 'abc')
+ call cursor(1, 1)
+ call feedkeys("i\<c-o>:stopinsert\<cr>$", 'tnix')
+ call feedkeys("aX\<esc>", 'tnix')
+ call assert_equal(['abcX'], getline(1, '$'))
+ %d
+ bw!
+endfunc
+
+func! Test_edit_05()
+ " test for folds being opened
+ new
+ call setline(1, ['abcX', 'abcX', 'zzzZ'])
+ call cursor(1, 1)
+ set foldmethod=manual foldopen+=insert
+ " create fold for those two lines
+ norm! Vjzf
+ call feedkeys("$ay\<esc>", 'tnix')
+ call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
+ %d
+ call setline(1, ['abcX', 'abcX', 'zzzZ'])
+ call cursor(1, 1)
+ set foldmethod=manual foldopen-=insert
+ " create fold for those two lines
+ norm! Vjzf
+ call feedkeys("$ay\<esc>", 'tnix')
+ call assert_equal(['abcXy', 'abcX', 'zzzZ'], getline(1, '$'))
+ %d
+ bw!
+endfunc
+
+func! Test_edit_06()
+ " Test in diff mode
+ if !has("diff") || !executable("diff")
+ return
+ endif
+ new
+ call setline(1, ['abc', 'xxx', 'yyy'])
+ vnew
+ call setline(1, ['abc', 'zzz', 'xxx', 'yyy'])
+ wincmd p
+ diffthis
+ wincmd p
+ diffthis
+ wincmd p
+ call cursor(2, 1)
+ norm! zt
+ call feedkeys("Ozzz\<esc>", 'tnix')
+ call assert_equal(['abc', 'zzz', 'xxx', 'yyy'], getline(1,'$'))
+ bw!
+ bw!
+endfunc
+
+func! Test_edit_07()
+ " 1) Test with completion <c-l> when popupmenu is visible
+ new
+ call setline(1, 'J')
+
+ func! ListMonths()
+ call complete(col('.')-1, ['January', 'February', 'March',
+ \ 'April', 'May', 'June', 'July', 'August', 'September',
+ \ 'October', 'November', 'December'])
+ return ''
+ endfunc
+ inoremap <buffer> <F5> <C-R>=ListMonths()<CR>
+
+ call feedkeys("A\<f5>\<c-p>". repeat("\<down>", 6)."\<c-l>\<down>\<c-l>\<cr>", 'tx')
+ call assert_equal(['July'], getline(1,'$'))
+ " 1) Test completion when InsertCharPre kicks in
+ %d
+ call setline(1, 'J')
+ fu! DoIt()
+ if v:char=='u'
+ let v:char='an'
+ endif
+ endfu
+ au InsertCharPre <buffer> :call DoIt()
+ call feedkeys("A\<f5>\<c-p>u\<cr>\<c-l>\<cr>", 'tx')
+ call assert_equal(["Jan\<c-l>",''], getline(1,'$'))
+ %d
+ call setline(1, 'J')
+ call feedkeys("A\<f5>\<c-p>u\<down>\<c-l>\<cr>", 'tx')
+ call assert_equal(["January"], getline(1,'$'))
+
+ delfu ListMonths
+ delfu DoIt
+ iunmap <buffer> <f5>
+ bw!
+endfunc
+
+func! Test_edit_08()
+ throw 'skipped: moved to test/functional/legacy/edit_spec.lua'
+ " reset insertmode from i_ctrl-r_=
+ let g:bufnr = bufnr('%')
+ new
+ call setline(1, ['abc'])
+ call cursor(1, 4)
+ call feedkeys(":set im\<cr>ZZZ\<c-r>=setbufvar(g:bufnr,'&im', 0)\<cr>",'tnix')
+ call assert_equal(['abZZZc'], getline(1,'$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+ call assert_false(0, '&im')
+ bw!
+ unlet g:bufnr
+endfunc
+
+func! Test_edit_09()
+ " test i_CTRL-\ combinations
+ new
+ call setline(1, ['abc', 'def', 'ghi'])
+ call cursor(1, 1)
+ " 1) CTRL-\ CTLR-N
+ call feedkeys(":set im\<cr>\<c-\>\<c-n>ccABC\<c-l>", 'txin')
+ call assert_equal(['ABC', 'def', 'ghi'], getline(1,'$'))
+ call setline(1, ['ABC', 'def', 'ghi'])
+ " 2) CTRL-\ CTLR-G
+ call feedkeys("j0\<c-\>\<c-g>ZZZ\<cr>\<c-l>", 'txin')
+ call assert_equal(['ABC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
+ call feedkeys("I\<c-\>\<c-g>YYY\<c-l>", 'txin')
+ call assert_equal(['ABC', 'ZZZ', 'YYYdef', 'ghi'], getline(1,'$'))
+ set noinsertmode
+ " 3) CTRL-\ CTRL-O
+ call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
+ call cursor(1, 1)
+ call feedkeys("A\<c-o>ix", 'txin')
+ call assert_equal(['ABxC', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
+ call feedkeys("A\<c-\>\<c-o>ix", 'txin')
+ call assert_equal(['ABxCx', 'ZZZ', 'def', 'ghi'], getline(1,'$'))
+ " 4) CTRL-\ a (should be inserted literally, not special after <c-\>
+ call setline(1, ['ABC', 'ZZZ', 'def', 'ghi'])
+ call cursor(1, 1)
+ call feedkeys("A\<c-\>a", 'txin')
+ call assert_equal(["ABC\<c-\>a", 'ZZZ', 'def', 'ghi'], getline(1, '$'))
+ bw!
+endfunc
+
+func! Test_edit_10()
+ " Test for starting selectmode
+ new
+ set selectmode=key keymodel=startsel
+ call setline(1, ['abc', 'def', 'ghi'])
+ call cursor(1, 4)
+ call feedkeys("A\<s-home>start\<esc>", 'txin')
+ call assert_equal(['startdef', 'ghi'], getline(1, '$'))
+ set selectmode= keymodel=
+ bw!
+endfunc
+
+func! Test_edit_11()
+ " Test that indenting kicks in
+ new
+ set cindent
+ call setline(1, ['{', '', ''])
+ call cursor(2, 1)
+ call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
+ call cursor(3, 1)
+ call feedkeys("i/* comment */", 'tnix')
+ call assert_equal(['{', "\<tab>int c;", "/* comment */"], getline(1, '$'))
+ " added changed cindentkeys slightly
+ set cindent cinkeys+=*/
+ call setline(1, ['{', '', ''])
+ call cursor(2, 1)
+ call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
+ call cursor(3, 1)
+ call feedkeys("i/* comment */", 'tnix')
+ call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */"], getline(1, '$'))
+ set cindent cinkeys+==end
+ call feedkeys("oend\<cr>\<esc>", 'tnix')
+ call assert_equal(['{', "\<tab>int c;", "\<tab>/* comment */", "\tend", ''], getline(1, '$'))
+ set cinkeys-==end
+ %d
+ " Use indentexpr instead of cindenting
+ func! Do_Indent()
+ if v:lnum == 3
+ return 3*shiftwidth()
+ else
+ return 2*shiftwidth()
+ endif
+ endfunc
+ setl indentexpr=Do_Indent() indentkeys+=*/
+ call setline(1, ['{', '', ''])
+ call cursor(2, 1)
+ call feedkeys("i\<c-f>int c;\<esc>", 'tnix')
+ call cursor(3, 1)
+ call feedkeys("i/* comment */", 'tnix')
+ call assert_equal(['{', "\<tab>\<tab>int c;", "\<tab>\<tab>\<tab>/* comment */"], getline(1, '$'))
+ set cinkeys&vim indentkeys&vim
+ set nocindent indentexpr=
+ delfu Do_Indent
+ bw!
+endfunc
+
+func! Test_edit_11_indentexpr()
+ " Test that indenting kicks in
+ new
+ " Use indentexpr instead of cindenting
+ func! Do_Indent()
+ let pline=prevnonblank(v:lnum)
+ if empty(getline(v:lnum))
+ if getline(pline) =~ 'if\|then'
+ return shiftwidth()
+ else
+ return 0
+ endif
+ else
+ return 0
+ endif
+ endfunc
+ setl indentexpr=Do_Indent() indentkeys+=0=then,0=fi
+ call setline(1, ['if [ $this ]'])
+ call cursor(1, 1)
+ call feedkeys("othen\<cr>that\<cr>fi", 'tnix')
+ call assert_equal(['if [ $this ]', "then", "\<tab>that", "fi"], getline(1, '$'))
+ set cinkeys&vim indentkeys&vim
+ set nocindent indentexpr=
+ delfu Do_Indent
+ bw!
+endfunc
+
+func! Test_edit_12()
+ " Test changing indent in replace mode
+ new
+ call setline(1, ["\tabc", "\tdef"])
+ call cursor(2, 4)
+ call feedkeys("R^\<c-d>", 'tnix')
+ call assert_equal(["\tabc", "def"], getline(1, '$'))
+ call assert_equal([0, 2, 2, 0], getpos('.'))
+ %d
+ call setline(1, ["\tabc", "\t\tdef"])
+ call cursor(2, 2)
+ call feedkeys("R^\<c-d>", 'tnix')
+ call assert_equal(["\tabc", "def"], getline(1, '$'))
+ call assert_equal([0, 2, 1, 0], getpos('.'))
+ %d
+ call setline(1, ["\tabc", "\t\tdef"])
+ call cursor(2, 2)
+ call feedkeys("R\<c-t>", 'tnix')
+ call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
+ call assert_equal([0, 2, 2, 0], getpos('.'))
+ bw!
+ 10vnew
+ call setline(1, ["\tabc", "\t\tdef"])
+ call cursor(2, 2)
+ call feedkeys("R\<c-t>", 'tnix')
+ call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
+ call assert_equal([0, 2, 2, 0], getpos('.'))
+ %d
+ set sw=4
+ call setline(1, ["\tabc", "\t\tdef"])
+ call cursor(2, 2)
+ call feedkeys("R\<c-t>\<c-t>", 'tnix')
+ call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
+ call assert_equal([0, 2, 2, 0], getpos('.'))
+ %d
+ call setline(1, ["\tabc", "\t\tdef"])
+ call cursor(2, 2)
+ call feedkeys("R\<c-t>\<c-t>", 'tnix')
+ call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$'))
+ call assert_equal([0, 2, 2, 0], getpos('.'))
+ set et
+ set sw& et&
+ %d
+ call setline(1, ["\t/*"])
+ set formatoptions=croql
+ call cursor(1, 3)
+ call feedkeys("A\<cr>\<cr>/", 'tnix')
+ call assert_equal(["\t/*", " *", " */"], getline(1, '$'))
+ set formatoptions&
+ bw!
+endfunc
+
+func! Test_edit_13()
+ " Test smartindenting
+ if exists("+smartindent")
+ new
+ set smartindent autoindent
+ call setline(1, ["\tabc"])
+ call feedkeys("A {\<cr>more\<cr>}\<esc>", 'tnix')
+ call assert_equal(["\tabc {", "\t\tmore", "\t}"], getline(1, '$'))
+ set smartindent& autoindent&
+ bw!
+ endif
+endfunc
+
+func! Test_edit_CR()
+ " Test for <CR> in insert mode
+ " basically only in quickfix mode ist tested, the rest
+ " has been taken care of by other tests
+ if !has("quickfix")
+ return
+ endif
+ botright new
+ call writefile(range(1, 10), 'Xqflist.txt')
+ call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}])
+ copen
+ set modifiable
+ call feedkeys("A\<cr>", 'tnix')
+ call assert_equal('Xqflist.txt', bufname(''))
+ call assert_equal(2, line('.'))
+ cclose
+ botright new
+ call setloclist(0, [{'filename': 'Xqflist.txt', 'lnum': 10}])
+ lopen
+ set modifiable
+ call feedkeys("A\<cr>", 'tnix')
+ call assert_equal('Xqflist.txt', bufname(''))
+ call assert_equal(10, line('.'))
+ call feedkeys("A\<Enter>", 'tnix')
+ call feedkeys("A\<kEnter>", 'tnix')
+ call feedkeys("A\n", 'tnix')
+ call feedkeys("A\r", 'tnix')
+ call assert_equal(map(range(1, 10), 'string(v:val)') + ['', '', '', ''], getline(1, '$'))
+ bw!
+ lclose
+ call delete('Xqflist.txt')
+endfunc
+
+func! Test_edit_CTRL_()
+ " disabled for Windows builds, why?
+ if !has("multi_byte") || !has("rightleft") || has("win32")
+ return
+ endif
+ let _encoding=&encoding
+ set encoding=utf-8
+ " Test for CTRL-_
+ new
+ call setline(1, ['abc'])
+ call cursor(1, 1)
+ call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
+ call assert_equal(["\<C-_>xyzabc"], getline(1, '$'))
+ call assert_false(&revins)
+ set ari
+ call setline(1, ['abc'])
+ call cursor(1, 1)
+ call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
+ call assert_equal(["æèñabc"], getline(1, '$'))
+ call assert_true(&revins)
+ call setline(1, ['abc'])
+ call cursor(1, 1)
+ call feedkeys("i\<c-_>xyz\<esc>", 'tnix')
+ call assert_equal(["xyzabc"], getline(1, '$'))
+ call assert_false(&revins)
+ set noari
+ let &encoding=_encoding
+ bw!
+endfunc
+
+" needs to come first, to have the @. register empty
+func! Test_edit_00a_CTRL_A()
+ " Test pressing CTRL-A
+ new
+ call setline(1, repeat([''], 5))
+ call cursor(1, 1)
+ try
+ call feedkeys("A\<NUL>", 'tnix')
+ catch /^Vim\%((\a\+)\)\=:E29/
+ call assert_true(1, 'E29 error caught')
+ endtry
+ call cursor(1, 1)
+ call feedkeys("Afoobar \<esc>", 'tnix')
+ call cursor(2, 1)
+ call feedkeys("A\<c-a>more\<esc>", 'tnix')
+ call cursor(3, 1)
+ call feedkeys("A\<NUL>and more\<esc>", 'tnix')
+ call assert_equal(['foobar ', 'foobar more', 'foobar morend more', '', ''], getline(1, '$'))
+ bw!
+endfunc
+
+func! Test_edit_CTRL_EY()
+ " Ctrl-E/ Ctrl-Y in insert mode completion to scroll
+ 10new
+ call setline(1, range(1, 100))
+ call cursor(30, 1)
+ norm! z.
+ call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
+ call assert_equal(30, winsaveview()['topline'])
+ call assert_equal([0, 30, 2, 0], getpos('.'))
+ call feedkeys("A\<c-x>\<c-e>\<c-e>\<c-e>\<c-e>\<c-e>", 'tnix')
+ call feedkeys("A\<c-x>".repeat("\<c-y>", 10), 'tnix')
+ call assert_equal(21, winsaveview()['topline'])
+ call assert_equal([0, 30, 2, 0], getpos('.'))
+ bw!
+endfunc
+
+func! Test_edit_CTRL_G()
+ new
+ call setline(1, ['foobar', 'foobar', 'foobar'])
+ call cursor(2, 4)
+ call feedkeys("ioooooooo\<c-g>k\<c-r>.\<esc>", 'tnix')
+ call assert_equal(['foooooooooobar', 'foooooooooobar', 'foobar'], getline(1, '$'))
+ call assert_equal([0, 1, 11, 0], getpos('.'))
+ call feedkeys("i\<c-g>k\<esc>", 'tnix')
+ call assert_equal([0, 1, 10, 0], getpos('.'))
+ call cursor(2, 4)
+ call feedkeys("i\<c-g>jzzzz\<esc>", 'tnix')
+ call assert_equal(['foooooooooobar', 'foooooooooobar', 'foozzzzbar'], getline(1, '$'))
+ call assert_equal([0, 3, 7, 0], getpos('.'))
+ call feedkeys("i\<c-g>j\<esc>", 'tnix')
+ call assert_equal([0, 3, 6, 0], getpos('.'))
+ bw!
+endfunc
+
+func! Test_edit_CTRL_I()
+ " Tab in completion mode
+ let path=expand("%:p:h")
+ new
+ call setline(1, [path."/", ''])
+ call feedkeys("Arunt\<c-x>\<c-f>\<tab>\<cr>\<esc>", 'tnix')
+ call assert_match('runtest\.vim', getline(1))
+ %d
+ call writefile(['one', 'two', 'three'], 'Xinclude.txt')
+ let include='#include Xinclude.txt'
+ call setline(1, [include, ''])
+ call cursor(2, 1)
+ call feedkeys("A\<c-x>\<tab>\<cr>\<esc>", 'tnix')
+ call assert_equal([include, 'one', ''], getline(1, '$'))
+ call feedkeys("2ggC\<c-x>\<tab>\<down>\<cr>\<esc>", 'tnix')
+ call assert_equal([include, 'two', ''], getline(1, '$'))
+ call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<cr>\<esc>", 'tnix')
+ call assert_equal([include, 'three', ''], getline(1, '$'))
+ call feedkeys("2ggC\<c-x>\<tab>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
+ call assert_equal([include, '', ''], getline(1, '$'))
+ call delete("Xinclude.txt")
+ bw!
+endfunc
+
+func! Test_edit_CTRL_K()
+ " Test pressing CTRL-K (basically only dictionary completion and digraphs
+ " the rest is already covered
+ call writefile(['A', 'AA', 'AAA', 'AAAA'], 'Xdictionary.txt')
+ set dictionary=Xdictionary.txt
+ new
+ call setline(1, 'A')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-k>\<cr>\<esc>", 'tnix')
+ call assert_equal(['AA', ''], getline(1, '$'))
+ %d
+ call setline(1, 'A')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-k>\<down>\<cr>\<esc>", 'tnix')
+ call assert_equal(['AAA'], getline(1, '$'))
+ %d
+ call setline(1, 'A')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<cr>\<esc>", 'tnix')
+ call assert_equal(['AAAA'], getline(1, '$'))
+ %d
+ call setline(1, 'A')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
+ call assert_equal(['A'], getline(1, '$'))
+ %d
+ call setline(1, 'A')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-k>\<down>\<down>\<down>\<down>\<cr>\<esc>", 'tnix')
+ call assert_equal(['AA'], getline(1, '$'))
+
+ " press an unexecpted key after dictionary completion
+ %d
+ call setline(1, 'A')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-k>\<c-]>\<cr>\<esc>", 'tnix')
+ call assert_equal(['AA', ''], getline(1, '$'))
+ %d
+ call setline(1, 'A')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-k>\<c-s>\<cr>\<esc>", 'tnix')
+ call assert_equal(["AA\<c-s>", ''], getline(1, '$'))
+ %d
+ call setline(1, 'A')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-k>\<c-f>\<cr>\<esc>", 'tnix')
+ call assert_equal(["AA\<c-f>", ''], getline(1, '$'))
+
+ set dictionary=
+ %d
+ call setline(1, 'A')
+ call cursor(1, 1)
+ let v:testing = 1
+ try
+ call feedkeys("A\<c-x>\<c-k>\<esc>", 'tnix')
+ catch
+ " error sleeps 2 seconds, when v:testing is not set
+ let v:testing = 0
+ endtry
+ call delete('Xdictionary.txt')
+
+ if has("multi_byte") && !has("nvim")
+ call test_override("char_avail", 1)
+ set showcmd
+ %d
+ call feedkeys("A\<c-k>a:\<esc>", 'tnix')
+ call assert_equal(['ä'], getline(1, '$'))
+ call test_override("char_avail", 0)
+ set noshowcmd
+ endif
+ bw!
+endfunc
+
+func! Test_edit_CTRL_L()
+ " Test Ctrl-X Ctrl-L (line completion)
+ new
+ set complete=.
+ call setline(1, ['one', 'two', 'three', '', '', '', ''])
+ call cursor(4, 1)
+ call feedkeys("A\<c-x>\<c-l>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
+ call feedkeys("cct\<c-x>\<c-l>\<c-n>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
+ call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
+ call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
+ call feedkeys("cct\<c-x>\<c-l>\<c-n>\<c-n>\<c-n>\<c-n>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
+ call feedkeys("cct\<c-x>\<c-l>\<c-p>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 'two', '', '', ''], getline(1, '$'))
+ call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 't', '', '', ''], getline(1, '$'))
+ call feedkeys("cct\<c-x>\<c-l>\<c-p>\<c-p>\<c-p>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 'three', '', '', ''], getline(1, '$'))
+ set complete=
+ call cursor(5, 1)
+ call feedkeys("A\<c-x>\<c-l>\<c-p>\<c-n>\<esc>", 'tnix')
+ call assert_equal(['one', 'two', 'three', 'three', "\<c-l>\<c-p>\<c-n>", '', ''], getline(1, '$'))
+ set complete&
+ %d
+ if has("conceal") && has("syntax") && !has("nvim")
+ call setline(1, ['foo', 'bar', 'foobar'])
+ call test_override("char_avail", 1)
+ set conceallevel=2 concealcursor=n
+ syn on
+ syn match ErrorMsg "^bar"
+ call matchadd("Conceal", 'oo', 10, -1, {'conceal': 'X'})
+ func! DoIt()
+ let g:change=1
+ endfunc
+ au! TextChangedI <buffer> :call DoIt()
+
+ call cursor(2, 1)
+ call assert_false(exists("g:change"))
+ call feedkeys("A \<esc>", 'tnix')
+ call assert_equal(['foo', 'bar ', 'foobar'], getline(1, '$'))
+ call assert_equal(1, g:change)
+
+ call test_override("char_avail", 0)
+ call clearmatches()
+ syn off
+ au! TextChangedI
+ delfu DoIt
+ unlet! g:change
+ endif
+ bw!
+endfunc
+
+func! Test_edit_CTRL_N()
+ " Check keyword completion
+ new
+ set complete=.
+ call setline(1, ['INFER', 'loWER', '', '', ])
+ call cursor(3, 1)
+ call feedkeys("Ai\<c-n>\<cr>\<esc>", "tnix")
+ call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['INFER', 'loWER', 'i', 'LO', '', ''], getline(1, '$'))
+ %d
+ call setline(1, ['INFER', 'loWER', '', '', ])
+ call cursor(3, 1)
+ set ignorecase infercase
+ call feedkeys("Ii\<c-n>\<cr>\<esc>", "tnix")
+ call feedkeys("ILO\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['INFER', 'loWER', 'infer', 'LOWER', '', ''], getline(1, '$'))
+
+ set noignorecase noinfercase complete&
+ bw!
+endfunc
+
+func! Test_edit_CTRL_O()
+ " Check for CTRL-O in insert mode
+ new
+ inoreabbr <buffer> h here some more
+ call setline(1, ['abc', 'def'])
+ call cursor(1, 1)
+ " Ctrl-O after an abbreviation
+ exe "norm A h\<c-o>:set nu\<cr> text"
+ call assert_equal(['abc here some more text', 'def'], getline(1, '$'))
+ call assert_true(&nu)
+ set nonu
+ iunabbr <buffer> h
+ " Ctrl-O at end of line with 've'=onemore
+ call cursor(1, 1)
+ call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
+ call assert_equal([0, 1, 23, 0], g:a)
+ call cursor(1, 1)
+ set ve=onemore
+ call feedkeys("A\<c-o>:let g:a=getpos('.')\<cr>\<esc>", 'tnix')
+ call assert_equal([0, 1, 24, 0], g:a)
+ set ve=
+ unlet! g:a
+ bw!
+endfunc
+
+func! Test_edit_CTRL_R()
+ throw 'skipped: Nvim does not support test_override()'
+ " Insert Register
+ new
+ call test_override("ALL", 1)
+ set showcmd
+ call feedkeys("AFOOBAR eins zwei\<esc>", 'tnix')
+ call feedkeys("O\<c-r>.", 'tnix')
+ call feedkeys("O\<c-r>=10*500\<cr>\<esc>", 'tnix')
+ call feedkeys("O\<c-r>=getreg('=', 1)\<cr>\<esc>", 'tnix')
+ call assert_equal(["getreg('=', 1)", '5000', "FOOBAR eins zwei", "FOOBAR eins zwei"], getline(1, '$'))
+ call test_override("ALL", 0)
+ set noshowcmd
+ bw!
+endfunc
+
+func! Test_edit_CTRL_S()
+ " Test pressing CTRL-S (basically only spellfile completion)
+ " the rest is already covered
+ new
+ if !has("spell")
+ call setline(1, 'vim')
+ call feedkeys("A\<c-x>ss\<cr>\<esc>", 'tnix')
+ call assert_equal(['vims', ''], getline(1, '$'))
+ bw!
+ return
+ endif
+ call setline(1, 'vim')
+ " spell option not yet set
+ try
+ call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
+ catch /^Vim\%((\a\+)\)\=:E756/
+ call assert_true(1, 'error caught')
+ endtry
+ call assert_equal(['vim', ''], getline(1, '$'))
+ %d
+ setl spell spelllang=en
+ call setline(1, 'vim')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-s>\<cr>\<esc>", 'tnix')
+ call assert_equal(['Vim', ''], getline(1, '$'))
+ %d
+ call setline(1, 'vim')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-s>\<down>\<cr>\<esc>", 'tnix')
+ call assert_equal(['Aim'], getline(1, '$'))
+ %d
+ call setline(1, 'vim')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
+ call assert_equal(['vim', ''], getline(1, '$'))
+ %d
+ " empty buffer
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-s>\<c-p>\<cr>\<esc>", 'tnix')
+ call assert_equal(['', ''], getline(1, '$'))
+ setl nospell
+ bw!
+endfunc
+
+func! Test_edit_CTRL_T()
+ " Check for CTRL-T and CTRL-X CTRL-T in insert mode
+ " 1) increase indent
+ new
+ call setline(1, "abc")
+ call cursor(1, 1)
+ call feedkeys("A\<c-t>xyz", 'tnix')
+ call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
+ " 2) also when paste option is set
+ set paste
+ call setline(1, "abc")
+ call cursor(1, 1)
+ call feedkeys("A\<c-t>xyz", 'tnix')
+ call assert_equal(["\<tab>abcxyz"], getline(1, '$'))
+ set nopaste
+ " CTRL-X CTRL-T (thesaurus complete)
+ call writefile(['angry furious mad enraged'], 'Xthesaurus')
+ set thesaurus=Xthesaurus
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-t>\<cr>\<esc>", 'tnix')
+ call assert_equal(['mad', ''], getline(1, '$'))
+ %d
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['angry', ''], getline(1, '$'))
+ %d
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['furious', ''], getline(1, '$'))
+ %d
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['enraged', ''], getline(1, '$'))
+ %d
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['mad', ''], getline(1, '$'))
+ %d
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-t>\<c-n>\<c-n>\<c-n>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['mad', ''], getline(1, '$'))
+ " Using <c-p> <c-n> when 'complete' is empty
+ set complete=
+ %d
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-t>\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['angry', ''], getline(1, '$'))
+ %d
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ call feedkeys("A\<c-x>\<c-t>\<c-p>\<cr>\<esc>", 'tnix')
+ call assert_equal(['mad', ''], getline(1, '$'))
+ set complete&
+
+ set thesaurus=
+ %d
+ call setline(1, 'mad')
+ call cursor(1, 1)
+ let v:testing = 1
+ try
+ call feedkeys("A\<c-x>\<c-t>\<esc>", 'tnix')
+ catch
+ " error sleeps 2 seconds, when v:testing is not set
+ let v:testing = 0
+ endtry
+ call assert_equal(['mad'], getline(1, '$'))
+ call delete('Xthesaurus')
+ bw!
+endfunc
+
+func! Test_edit_CTRL_U()
+ " Test 'completefunc'
+ new
+ " -1, -2 and -3 are special return values
+ let g:special=0
+ fun! CompleteMonths(findstart, base)
+ if a:findstart
+ " locate the start of the word
+ return g:special
+ else
+ " find months matching with "a:base"
+ let res = []
+ for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
+ if m =~ '^\c'.a:base
+ call add(res, {'word': m, 'abbr': m.' Month', 'icase': 0})
+ endif
+ endfor
+ return {'words': res, 'refresh': 'always'}
+ endif
+ endfun
+ set completefunc=CompleteMonths
+ call setline(1, ['', ''])
+ call cursor(1, 1)
+ call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+ call assert_equal(['X', '', ''], getline(1, '$'))
+ %d
+ let g:special=-1
+ call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+ call assert_equal(['XJan', ''], getline(1, '$'))
+ %d
+ let g:special=-2
+ call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+ call assert_equal(['X', ''], getline(1, '$'))
+ %d
+ let g:special=-3
+ call feedkeys("AX\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+ call assert_equal(['X', ''], getline(1, '$'))
+ %d
+ let g:special=0
+ call feedkeys("AM\<c-x>\<c-u>\<cr>\<esc>", 'tnix')
+ call assert_equal(['Mar', ''], getline(1, '$'))
+ %d
+ call feedkeys("AM\<c-x>\<c-u>\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['May', ''], getline(1, '$'))
+ %d
+ call feedkeys("AM\<c-x>\<c-u>\<c-n>\<c-n>\<cr>\<esc>", 'tnix')
+ call assert_equal(['M', ''], getline(1, '$'))
+ delfu CompleteMonths
+ %d
+ try
+ call feedkeys("A\<c-x>\<c-u>", 'tnix')
+ call assert_fails(1, 'unknown completion function')
+ catch /^Vim\%((\a\+)\)\=:E117/
+ call assert_true(1, 'E117 error caught')
+ endtry
+ set completefunc=
+ bw!
+endfunc
+
+func! Test_edit_CTRL_Z()
+ " Ctrl-Z when insertmode is not set inserts it literally
+ new
+ call setline(1, 'abc')
+ call feedkeys("A\<c-z>\<esc>", 'tnix')
+ call assert_equal(["abc\<c-z>"], getline(1,'$'))
+ bw!
+ " TODO: How to Test Ctrl-Z in insert mode, e.g. suspend?
+endfunc
+
+func! Test_edit_DROP()
+ if !has("dnd")
+ return
+ endif
+ new
+ call setline(1, ['abc def ghi'])
+ call cursor(1, 1)
+ try
+ call feedkeys("i\<Drop>\<Esc>", 'tnix')
+ call assert_fails(1, 'Invalid register name')
+ catch /^Vim\%((\a\+)\)\=:E353/
+ call assert_true(1, 'error caught')
+ endtry
+ bw!
+endfunc
+
+func! Test_edit_CTRL_V()
+ throw 'skipped: Nvim does not support test_override()'
+ if has("ebcdic")
+ return
+ endif
+ new
+ call setline(1, ['abc'])
+ call cursor(2, 1)
+ " force some redraws
+ set showmode showcmd
+ "call test_override_char_avail(1)
+ call test_override('ALL', 1)
+ call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
+ call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
+
+ if has("rightleft") && exists("+rl")
+ set rl
+ call setline(1, ['abc'])
+ call cursor(2, 1)
+ call feedkeys("A\<c-v>\<c-n>\<c-v>\<c-l>\<c-v>\<c-b>\<esc>", 'tnix')
+ call assert_equal(["abc\x0e\x0c\x02"], getline(1, '$'))
+ set norl
+ endif
+
+ call test_override('ALL', 0)
+ set noshowmode showcmd
+ bw!
+endfunc
+
+func! Test_edit_F1()
+ " Pressing <f1>
+ new
+ call feedkeys(":set im\<cr>\<f1>\<c-l>", 'tnix')
+ set noinsertmode
+ call assert_equal('help', &buftype)
+ bw
+ bw
+endfunc
+
+func! Test_edit_F21()
+ " Pressing <f21>
+ " sends a netbeans command
+ if has("netbeans_intg")
+ new
+ " I have no idea what this is supposed to do :)
+ call feedkeys("A\<F21>\<F1>\<esc>", 'tnix')
+ bw
+ endif
+endfunc
+
+func! Test_edit_HOME_END()
+ " Test Home/End Keys
+ new
+ set foldopen+=hor
+ call setline(1, ['abc', 'def'])
+ call cursor(1, 1)
+ call feedkeys("AX\<Home>Y\<esc>", 'tnix')
+ call cursor(2, 1)
+ call feedkeys("iZ\<End>Y\<esc>", 'tnix')
+ call assert_equal(['YabcX', 'ZdefY'], getline(1, '$'))
+
+ set foldopen-=hor
+ bw!
+endfunc
+
+func! Test_edit_INS()
+ " Test for Pressing <Insert>
+ new
+ call setline(1, ['abc', 'def'])
+ call cursor(1, 1)
+ call feedkeys("i\<Insert>ZYX>", 'tnix')
+ call assert_equal(['ZYX>', 'def'], getline(1, '$'))
+ call setline(1, ['abc', 'def'])
+ call cursor(1, 1)
+ call feedkeys("i\<Insert>Z\<Insert>YX>", 'tnix')
+ call assert_equal(['ZYX>bc', 'def'], getline(1, '$'))
+ bw!
+endfunc
+
+func! Test_edit_LEFT_RIGHT()
+ " Left, Shift-Left, Right, Shift-Right
+ new
+ call setline(1, ['abc def ghi', 'ABC DEF GHI', 'ZZZ YYY XXX'])
+ let _ww=&ww
+ set ww=
+ call cursor(2, 1)
+ call feedkeys("i\<left>\<esc>", 'tnix')
+ call assert_equal([0, 2, 1, 0], getpos('.'))
+ " Is this a bug, <s-left> does not respect whichwrap option
+ call feedkeys("i\<s-left>\<esc>", 'tnix')
+ call assert_equal([0, 1, 8, 0], getpos('.'))
+ call feedkeys("i". repeat("\<s-left>", 3). "\<esc>", 'tnix')
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+ call feedkeys("i\<right>\<esc>", 'tnix')
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+ call feedkeys("i\<right>\<right>\<esc>", 'tnix')
+ call assert_equal([0, 1, 2, 0], getpos('.'))
+ call feedkeys("A\<right>\<esc>", 'tnix')
+ call assert_equal([0, 1, 11, 0], getpos('.'))
+ call feedkeys("A\<s-right>\<esc>", 'tnix')
+ call assert_equal([0, 2, 1, 0], getpos('.'))
+ call feedkeys("i\<s-right>\<esc>", 'tnix')
+ call assert_equal([0, 2, 4, 0], getpos('.'))
+ call cursor(3, 11)
+ call feedkeys("A\<right>\<esc>", 'tnix')
+ call feedkeys("A\<s-right>\<esc>", 'tnix')
+ call assert_equal([0, 3, 11, 0], getpos('.'))
+ call cursor(2, 11)
+ " <S-Right> does not respect 'whichwrap' option
+ call feedkeys("A\<s-right>\<esc>", 'tnix')
+ call assert_equal([0, 3, 1, 0], getpos('.'))
+ " Check motion when 'whichwrap' contains cursor keys for insert mode
+ set ww+=[,]
+ call cursor(2, 1)
+ call feedkeys("i\<left>\<esc>", 'tnix')
+ call assert_equal([0, 1, 11, 0], getpos('.'))
+ call cursor(2, 11)
+ call feedkeys("A\<right>\<esc>", 'tnix')
+ call assert_equal([0, 3, 1, 0], getpos('.'))
+ call cursor(2, 11)
+ call feedkeys("A\<s-right>\<esc>", 'tnix')
+ call assert_equal([0, 3, 1, 0], getpos('.'))
+ let &ww = _ww
+ bw!
+endfunc
+
+func! Test_edit_MOUSE()
+ " This is a simple test, since we not really using the mouse here
+ if !has("mouse")
+ return
+ endif
+ 10new
+ call setline(1, range(1, 100))
+ call cursor(1, 1)
+ set mouse=a
+ call feedkeys("A\<ScrollWheelDown>\<esc>", 'tnix')
+ call assert_equal([0, 4, 1, 0], getpos('.'))
+ " This should move by one pageDown, but only moves
+ " by one line when the test is run...
+ call feedkeys("A\<S-ScrollWheelDown>\<esc>", 'tnix')
+ call assert_equal([0, 5, 1, 0], getpos('.'))
+ set nostartofline
+ call feedkeys("A\<C-ScrollWheelDown>\<esc>", 'tnix')
+ call assert_equal([0, 6, 1, 0], getpos('.'))
+ call feedkeys("A\<LeftMouse>\<esc>", 'tnix')
+ call assert_equal([0, 6, 1, 0], getpos('.'))
+ call feedkeys("A\<RightMouse>\<esc>", 'tnix')
+ call assert_equal([0, 6, 1, 0], getpos('.'))
+ call cursor(1, 100)
+ norm! zt
+ " this should move by a screen up, but when the test
+ " is run, it moves up to the top of the buffer...
+ call feedkeys("A\<ScrollWheelUp>\<esc>", 'tnix')
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+ call cursor(1, 30)
+ norm! zt
+ call feedkeys("A\<S-ScrollWheelUp>\<esc>", 'tnix')
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+ call cursor(1, 30)
+ norm! zt
+ call feedkeys("A\<C-ScrollWheelUp>\<esc>", 'tnix')
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+ %d
+ call setline(1, repeat(["12345678901234567890"], 100))
+ call cursor(2, 1)
+ call feedkeys("A\<ScrollWheelRight>\<esc>", 'tnix')
+ call assert_equal([0, 2, 20, 0], getpos('.'))
+ call feedkeys("A\<ScrollWheelLeft>\<esc>", 'tnix')
+ call assert_equal([0, 2, 20, 0], getpos('.'))
+ call feedkeys("A\<S-ScrollWheelRight>\<esc>", 'tnix')
+ call assert_equal([0, 2, 20, 0], getpos('.'))
+ call feedkeys("A\<S-ScrollWheelLeft>\<esc>", 'tnix')
+ call assert_equal([0, 2, 20, 0], getpos('.'))
+ call feedkeys("A\<C-ScrollWheelRight>\<esc>", 'tnix')
+ call assert_equal([0, 2, 20, 0], getpos('.'))
+ call feedkeys("A\<C-ScrollWheelLeft>\<esc>", 'tnix')
+ call assert_equal([0, 2, 20, 0], getpos('.'))
+ set mouse& startofline
+ bw!
+endfunc
+
+func! Test_edit_PAGEUP_PAGEDOWN()
+ 10new
+ call setline(1, repeat(['abc def ghi'], 30))
+ call cursor(1, 1)
+ call feedkeys("i\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 9, 1, 0], getpos('.'))
+ call feedkeys("i\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 17, 1, 0], getpos('.'))
+ call feedkeys("i\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 25, 1, 0], getpos('.'))
+ call feedkeys("i\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 30, 1, 0], getpos('.'))
+ call feedkeys("i\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 30, 1, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 29, 1, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 21, 1, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 13, 1, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 5, 1, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 5, 11, 0], getpos('.'))
+ " <S-Up> is the same as <PageUp>
+ " <S-Down> is the same as <PageDown>
+ call cursor(1, 1)
+ call feedkeys("i\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 9, 1, 0], getpos('.'))
+ call feedkeys("i\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 17, 1, 0], getpos('.'))
+ call feedkeys("i\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 25, 1, 0], getpos('.'))
+ call feedkeys("i\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 30, 1, 0], getpos('.'))
+ call feedkeys("i\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 30, 1, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 29, 1, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 21, 1, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 13, 1, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 5, 1, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 5, 11, 0], getpos('.'))
+ set nostartofline
+ call cursor(30, 11)
+ norm! zt
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 29, 11, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 21, 11, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 13, 11, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 5, 11, 0], getpos('.'))
+ call feedkeys("A\<PageUp>\<esc>", 'tnix')
+ call assert_equal([0, 5, 11, 0], getpos('.'))
+ call cursor(1, 1)
+ call feedkeys("A\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 9, 11, 0], getpos('.'))
+ call feedkeys("A\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 17, 11, 0], getpos('.'))
+ call feedkeys("A\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 25, 11, 0], getpos('.'))
+ call feedkeys("A\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 30, 11, 0], getpos('.'))
+ call feedkeys("A\<PageDown>\<esc>", 'tnix')
+ call assert_equal([0, 30, 11, 0], getpos('.'))
+ " <S-Up> is the same as <PageUp>
+ " <S-Down> is the same as <PageDown>
+ call cursor(30, 11)
+ norm! zt
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 29, 11, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 21, 11, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 13, 11, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 5, 11, 0], getpos('.'))
+ call feedkeys("A\<S-Up>\<esc>", 'tnix')
+ call assert_equal([0, 5, 11, 0], getpos('.'))
+ call cursor(1, 1)
+ call feedkeys("A\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 9, 11, 0], getpos('.'))
+ call feedkeys("A\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 17, 11, 0], getpos('.'))
+ call feedkeys("A\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 25, 11, 0], getpos('.'))
+ call feedkeys("A\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 30, 11, 0], getpos('.'))
+ call feedkeys("A\<S-Down>\<esc>", 'tnix')
+ call assert_equal([0, 30, 11, 0], getpos('.'))
+ bw!
+endfunc
+
+func! Test_edit_forbidden()
+ new
+ " 1) edit in the sandbox is not allowed
+ call setline(1, 'a')
+ com! Sandbox :sandbox call feedkeys("i\<del>\<esc>", 'tnix')
+ call assert_fails(':Sandbox', 'E48:')
+ com! Sandbox :sandbox exe "norm! i\<del>"
+ call assert_fails(':Sandbox', 'E48:')
+ delcom Sandbox
+ call assert_equal(['a'], getline(1,'$'))
+ " 2) edit with textlock set
+ fu! DoIt()
+ call feedkeys("i\<del>\<esc>", 'tnix')
+ endfu
+ au InsertCharPre <buffer> :call DoIt()
+ try
+ call feedkeys("ix\<esc>", 'tnix')
+ call assert_fails(1, 'textlock')
+ catch /^Vim\%((\a\+)\)\=:E523/ " catch E523: not allowed here
+ endtry
+ " TODO: Might be a bug: should x really be inserted here
+ call assert_equal(['xa'], getline(1, '$'))
+ delfu DoIt
+ try
+ call feedkeys("ix\<esc>", 'tnix')
+ call assert_fails(1, 'unknown function')
+ catch /^Vim\%((\a\+)\)\=:E117/ " catch E117: unknown function
+ endtry
+ au! InsertCharPre
+ " 3) edit when completion is shown
+ fun! Complete(findstart, base)
+ if a:findstart
+ return col('.')
+ else
+ call feedkeys("i\<del>\<esc>", 'tnix')
+ return []
+ endif
+ endfun
+ set completefunc=Complete
+ try
+ call feedkeys("i\<c-x>\<c-u>\<esc>", 'tnix')
+ call assert_fails(1, 'change in complete function')
+ catch /^Vim\%((\a\+)\)\=:E523/ " catch E523
+ endtry
+ delfu Complete
+ set completefunc=
+ if has("rightleft") && exists("+fkmap")
+ " 4) 'R' when 'fkmap' and 'revins' is set.
+ set revins fkmap
+ try
+ normal Ri
+ call assert_fails(1, "R with 'fkmap' and 'ri' set")
+ catch
+ finally
+ set norevins nofkmap
+ endtry
+ endif
+ bw!
+endfunc
+
+func! Test_edit_rightleft()
+ " Cursor in rightleft mode moves differently
+ if !exists("+rightleft")
+ return
+ endif
+ call NewWindow(10, 20)
+ call setline(1, ['abc', 'def', 'ghi'])
+ call cursor(1, 2)
+ set rightleft
+ " Screen looks as expected
+ let lines = ScreenLines([1, 4], winwidth(0))
+ let expect = [
+ \" cba",
+ \" fed",
+ \" ihg",
+ \" ~"]
+ call assert_equal(join(expect, "\n"), join(lines, "\n"))
+ " 2) right moves to the left
+ call feedkeys("i\<right>\<esc>x", 'txin')
+ call assert_equal(['bc', 'def', 'ghi'], getline(1,'$'))
+ call cursor(1, 2)
+ call feedkeys("i\<s-right>\<esc>", 'txin')
+ call cursor(1, 2)
+ call feedkeys("i\<c-right>\<esc>", 'txin')
+ " Screen looks as expected
+ let lines = ScreenLines([1, 4], winwidth(0))
+ let expect = [
+ \" cb",
+ \" fed",
+ \" ihg",
+ \" ~"]
+ call assert_equal(join(expect, "\n"), join(lines, "\n"))
+ " 2) left moves to the right
+ call setline(1, ['abc', 'def', 'ghi'])
+ call cursor(1, 2)
+ call feedkeys("i\<left>\<esc>x", 'txin')
+ call assert_equal(['ac', 'def', 'ghi'], getline(1,'$'))
+ call cursor(1, 2)
+ call feedkeys("i\<s-left>\<esc>", 'txin')
+ call cursor(1, 2)
+ call feedkeys("i\<c-left>\<esc>", 'txin')
+ " Screen looks as expected
+ let lines = ScreenLines([1, 4], winwidth(0))
+ let expect = [
+ \" ca",
+ \" fed",
+ \" ihg",
+ \" ~"]
+ call assert_equal(join(expect, "\n"), join(lines, "\n"))
+ set norightleft
+ bw!
+endfunc
+
+func Test_edit_backtick()
+ next a\`b c
+ call assert_equal('a`b', expand('%'))
+ next
+ call assert_equal('c', expand('%'))
+ call assert_equal('a\`b c', expand('##'))
+endfunc
+
+func Test_edit_quit()
+ edit foo.txt
+ split
+ new
+ call setline(1, 'hello')
+ 3wincmd w
+ redraw!
+ call assert_fails('1q', 'E37:')
+ bwipe! foo.txt
+ only
+endfunc
+
+func Test_edit_complete_very_long_name()
+ if !has('unix')
+ " Long directory names only work on Unix.
+ return
+ endif
+
+ let dirname = getcwd() . "/Xdir"
+ let longdirname = dirname . repeat('/' . repeat('d', 255), 4)
+ try
+ call mkdir(longdirname, 'p')
+ catch /E739:/
+ " Long directory name probably not supported.
+ call delete(dirname, 'rf')
+ return
+ endtry
+
+ " Try to get the Vim window position before setting 'columns'.
+ let winposx = getwinposx()
+ let winposy = getwinposy()
+ let save_columns = &columns
+ " Need at least about 1100 columns to reproduce the problem.
+ set columns=2000
+ call assert_equal(2000, &columns)
+ set noswapfile
+
+ let longfilename = longdirname . '/' . repeat('a', 255)
+ call writefile(['Totum', 'Table'], longfilename)
+ new
+ exe "next Xfile " . longfilename
+ exe "normal iT\<C-N>"
+
+ bwipe!
+ exe 'bwipe! ' . longfilename
+ call delete(dirname, 'rf')
+ let &columns = save_columns
+ if winposx >= 0 && winposy >= 0
+ exe 'winpos ' . winposx . ' ' . winposy
+ endif
+ set swapfile&
+endfunc
+
+func Test_edit_alt()
+ " Keeping the cursor line didn't happen when the first line has indent.
+ new
+ call setline(1, [' one', 'two', 'three'])
+ w XAltFile
+ $
+ call assert_equal(3, line('.'))
+ e Xother
+ e #
+ call assert_equal(3, line('.'))
+
+ bwipe XAltFile
+ call delete('XAltFile')
+endfunc
+
+func Test_leave_insert_autocmd()
+ new
+ au InsertLeave * let g:did_au = 1
+ let g:did_au = 0
+ call feedkeys("afoo\<Esc>", 'tx')
+ call assert_equal(1, g:did_au)
+ call assert_equal('foo', getline(1))
+
+ let g:did_au = 0
+ call feedkeys("Sbar\<C-C>", 'tx')
+ call assert_equal(0, g:did_au)
+ call assert_equal('bar', getline(1))
+
+ inoremap x xx<Esc>
+ let g:did_au = 0
+ call feedkeys("Saax", 'tx')
+ call assert_equal(1, g:did_au)
+ call assert_equal('aaxx', getline(1))
+
+ inoremap x xx<C-C>
+ let g:did_au = 0
+ call feedkeys("Sbbx", 'tx')
+ call assert_equal(0, g:did_au)
+ call assert_equal('bbxx', getline(1))
+
+ bwipe!
+ au! InsertLeave
+ iunmap x
+endfunc
diff --git a/src/nvim/testdir/test_erasebackword.vim b/src/nvim/testdir/test_erasebackword.vim
new file mode 100644
index 0000000000..098d6edfcb
--- /dev/null
+++ b/src/nvim/testdir/test_erasebackword.vim
@@ -0,0 +1,25 @@
+
+func Test_erasebackword()
+ if !has('multi_byte')
+ return
+ endif
+
+ set encoding=utf-8
+ enew
+
+ exe "normal o wwwã“ã‚“ã«ã¡ã‚世界ワールドvim \<C-W>"
+ call assert_equal(' wwwã“ã‚“ã«ã¡ã‚世界ワールド', getline('.'))
+ exe "normal o wwwã“ã‚“ã«ã¡ã‚世界ワールドvim \<C-W>\<C-W>"
+ call assert_equal(' wwwã“ã‚“ã«ã¡ã‚世界', getline('.'))
+ exe "normal o wwwã“ã‚“ã«ã¡ã‚世界ワールドvim \<C-W>\<C-W>\<C-W>"
+ call assert_equal(' wwwã“ã‚“ã«ã¡ã‚', getline('.'))
+ exe "normal o wwwã“ã‚“ã«ã¡ã‚世界ワールドvim \<C-W>\<C-W>\<C-W>\<C-W>"
+ call assert_equal(' www', getline('.'))
+ exe "normal o wwwã“ã‚“ã«ã¡ã‚世界ワールドvim \<C-W>\<C-W>\<C-W>\<C-W>\<C-W>"
+ call assert_equal(' ', getline('.'))
+ exe "normal o wwwã“ã‚“ã«ã¡ã‚世界ワールドvim \<C-W>\<C-W>\<C-W>\<C-W>\<C-W>\<C-W>"
+ call assert_equal('', getline('.'))
+
+ enew!
+ set encoding&
+endfunc
diff --git a/src/nvim/testdir/test_escaped_glob.vim b/src/nvim/testdir/test_escaped_glob.vim
new file mode 100644
index 0000000000..aad3a1e835
--- /dev/null
+++ b/src/nvim/testdir/test_escaped_glob.vim
@@ -0,0 +1,34 @@
+" Test whether glob()/globpath() return correct results with certain escaped
+" characters.
+
+function SetUp()
+ " consistent sorting of file names
+ set nofileignorecase
+endfunction
+
+function Test_glob()
+ if !has('unix')
+ " This test fails on Windows because of the special characters in the
+ " filenames. Disable the test on non-Unix systems for now.
+ return
+ endif
+
+ " Execute these commands in the sandbox, so that using the shell fails.
+ " Setting 'shell' to an invalid name causes a memory leak.
+ sandbox call assert_equal("", glob('Xxx\{'))
+ sandbox call assert_equal("", glob('Xxx\$'))
+ w! Xxx{
+ " } to fix highlighting
+ w! Xxx\$
+ sandbox call assert_equal("Xxx{", glob('Xxx\{'))
+ sandbox call assert_equal("Xxx$", glob('Xxx\$'))
+ call delete('Xxx{')
+ call delete('Xxx$')
+endfunction
+
+function Test_globpath()
+ sandbox call assert_equal(expand("sautest/autoload/globone.vim\nsautest/autoload/globtwo.vim"),
+ \ globpath('sautest/autoload', 'glob*.vim'))
+ sandbox call assert_equal([expand('sautest/autoload/globone.vim'), expand('sautest/autoload/globtwo.vim')],
+ \ globpath('sautest/autoload', 'glob*.vim', 0, 1))
+endfunction
diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim
new file mode 100644
index 0000000000..111c85bb95
--- /dev/null
+++ b/src/nvim/testdir/test_eval_stuff.vim
@@ -0,0 +1,23 @@
+" Tests for various eval things.
+
+function s:foo() abort
+ try
+ return [] == 0
+ catch
+ return 1
+ endtry
+endfunction
+
+func Test_catch_return_with_error()
+ call assert_equal(1, s:foo())
+endfunc
+
+func Test_E963()
+ " These commands used to cause an internal error prior to vim 8.1.0563
+ let v_e = v:errors
+ let v_o = v:oldfiles
+ call assert_fails("let v:errors=''", 'E963:')
+ call assert_equal(v_e, v:errors)
+ call assert_fails("let v:oldfiles=''", 'E963:')
+ call assert_equal(v_o, v:oldfiles)
+endfunc
diff --git a/src/nvim/testdir/test_ex_undo.vim b/src/nvim/testdir/test_ex_undo.vim
new file mode 100644
index 0000000000..44feb3680a
--- /dev/null
+++ b/src/nvim/testdir/test_ex_undo.vim
@@ -0,0 +1,19 @@
+" Tests for :undo
+
+func Test_ex_undo()
+ new ex-undo
+ setlocal ul=10
+ exe "normal ione\n\<Esc>"
+ setlocal ul=10
+ exe "normal itwo\n\<Esc>"
+ setlocal ul=10
+ exe "normal ithree\n\<Esc>"
+ call assert_equal(4, line('$'))
+ undo
+ call assert_equal(3, line('$'))
+ undo 1
+ call assert_equal(2, line('$'))
+ undo 0
+ call assert_equal(1, line('$'))
+ quit!
+endfunc
diff --git a/src/nvim/testdir/test_ex_z.vim b/src/nvim/testdir/test_ex_z.vim
new file mode 100644
index 0000000000..608a36c490
--- /dev/null
+++ b/src/nvim/testdir/test_ex_z.vim
@@ -0,0 +1,78 @@
+" Test :z
+
+func Test_z()
+ call setline(1, range(1, 100))
+
+ let a = execute('20z3')
+ call assert_equal("\n20\n21\n22", a)
+ call assert_equal(22, line('.'))
+ " 'window' should be set to the {count} value.
+ call assert_equal(3, &window)
+
+ " If there is only one window, then twice the amount of 'scroll' is used.
+ set scroll=2
+ let a = execute('20z')
+ call assert_equal("\n20\n21\n22\n23", a)
+ call assert_equal(23, line('.'))
+
+ let a = execute('20z+3')
+ " FIXME: I would expect the same result as '20z3' but it
+ " gives "\n21\n22\n23" instead. Bug in Vim or in ":help :z"?
+ "call assert_equal("\n20\n21\n22", a)
+ "call assert_equal(22, line('.'))
+
+ let a = execute('20z-3')
+ call assert_equal("\n18\n19\n20", a)
+ call assert_equal(20, line('.'))
+
+ let a = execute('20z=3')
+ call assert_match("^\n18\n19\n-\\+\n20\n-\\+\n21\n22$", a)
+ call assert_equal(20, line('.'))
+
+ let a = execute('20z^3')
+ call assert_equal("\n14\n15\n16\n17", a)
+ call assert_equal(17, line('.'))
+
+ let a = execute('20z.3')
+ call assert_equal("\n19\n20\n21", a)
+ call assert_equal(21, line('.'))
+
+ let a = execute('20z#3')
+ call assert_equal("\n 20 20\n 21 21\n 22 22", a)
+ call assert_equal(22, line('.'))
+
+ let a = execute('20z#-3')
+ call assert_equal("\n 18 18\n 19 19\n 20 20", a)
+ call assert_equal(20, line('.'))
+
+ let a = execute('20z#=3')
+ call assert_match("^\n 18 18\n 19 19\n-\\+\n 20 20\n-\\+\n 21 21\n 22 22$", a)
+ call assert_equal(20, line('.'))
+
+ " Test with {count} bigger than the number of lines in buffer.
+ let a = execute('20z1000')
+ call assert_match("^\n20\n21\n.*\n99\n100$", a)
+ call assert_equal(100, line('.'))
+
+ let a = execute('20z-1000')
+ call assert_match("^\n1\n2\n.*\n19\n20$", a)
+ call assert_equal(20, line('.'))
+
+ let a = execute('20z=1000')
+ call assert_match("^\n1\n.*\n-\\+\n20\n-\\\+\n.*\n100$", a)
+ call assert_equal(20, line('.'))
+
+ call assert_fails('20z=a', 'E144:')
+
+ set window& scroll&
+ bw!
+endfunc
+
+func Test_z_bug()
+ " This used to access invalid memory as a result of an integer overflow
+ " and freeze vim.
+ normal ox
+ normal Heat
+ z777777776666666
+ ')
+endfunc
diff --git a/src/nvim/testdir/test_exec_while_if.vim b/src/nvim/testdir/test_exec_while_if.vim
new file mode 100644
index 0000000000..d6afabff45
--- /dev/null
+++ b/src/nvim/testdir/test_exec_while_if.vim
@@ -0,0 +1,53 @@
+" Test for :execute, :while and :if
+
+function Test_exec_while_if()
+ new
+
+ let i = 0
+ while i < 12
+ let i = i + 1
+ if has("ebcdic")
+ execute "normal o" . i . "\047"
+ else
+ execute "normal o" . i . "\033"
+ endif
+ if i % 2
+ normal Ax
+ if i == 9
+ break
+ endif
+ if i == 5
+ continue
+ else
+ let j = 9
+ while j > 0
+ if has("ebcdic")
+ execute "normal" j . "a" . j . "\x27"
+ else
+ execute "normal" j . "a" . j . "\x1b"
+ endif
+ let j = j - 1
+ endwhile
+ endif
+ endif
+ if i == 9
+ if has("ebcdic")
+ execute "normal Az\047"
+ else
+ execute "normal Az\033"
+ endif
+ endif
+ endwhile
+ unlet i j
+
+ call assert_equal(["",
+ \ "1x999999999888888887777777666666555554444333221",
+ \ "2",
+ \ "3x999999999888888887777777666666555554444333221",
+ \ "4",
+ \ "5x",
+ \ "6",
+ \ "7x999999999888888887777777666666555554444333221",
+ \ "8",
+ \ "9x"], getline(1, 10))
+endfunction
diff --git a/src/nvim/testdir/test_execute_func.vim b/src/nvim/testdir/test_execute_func.vim
new file mode 100644
index 0000000000..6f61bede93
--- /dev/null
+++ b/src/nvim/testdir/test_execute_func.vim
@@ -0,0 +1,55 @@
+" test execute()
+
+func NestedEval()
+ let nested = execute('echo "nested\nlines"')
+ echo 'got: "' . nested . '"'
+endfunc
+
+func NestedRedir()
+ redir => var
+ echo 'broken'
+ redir END
+endfunc
+
+func Test_execute_string()
+ call assert_equal("\nnocompatible", execute('set compatible?'))
+ call assert_equal("\nsomething\nnice", execute('echo "something\nnice"'))
+ call assert_equal("noendofline", execute('echon "noendofline"'))
+ call assert_equal("", execute(123))
+
+ call assert_equal("\ngot: \"\nnested\nlines\"", execute('call NestedEval()'))
+ redir => redired
+ echo 'this'
+ let evaled = execute('echo "that"')
+ echo 'theend'
+ redir END
+" Nvim supports execute('... :redir ...'), so this test is intentionally
+" disabled.
+" call assert_equal("\nthis\ntheend", redired)
+ call assert_equal("\nthat", evaled)
+
+ call assert_fails('call execute("doesnotexist")', 'E492:')
+ call assert_fails('call execute(3.4)', 'E806:')
+" Nvim supports execute('... :redir ...'), so this test is intentionally
+" disabled.
+" call assert_fails('call execute("call NestedRedir()")', 'E930:')
+
+ call assert_equal("\nsomething", execute('echo "something"', ''))
+ call assert_equal("\nsomething", execute('echo "something"', 'silent'))
+ call assert_equal("\nsomething", execute('echo "something"', 'silent!'))
+ call assert_equal("", execute('burp', 'silent!'))
+ call assert_fails('call execute("echo \"x\"", 3.4)', 'E806:')
+
+ call assert_equal("", execute(""))
+endfunc
+
+func Test_execute_list()
+ call assert_equal("\nsomething\nnice", execute(['echo "something"', 'echo "nice"']))
+ let l = ['for n in range(0, 3)',
+ \ 'echo n',
+ \ 'endfor']
+ call assert_equal("\n0\n1\n2\n3", execute(l))
+
+ call assert_equal("", execute([]))
+ call assert_equal("", execute(v:_null_list))
+endfunc
diff --git a/src/nvim/testdir/test_exists.vim b/src/nvim/testdir/test_exists.vim
new file mode 100644
index 0000000000..fd34be83b0
--- /dev/null
+++ b/src/nvim/testdir/test_exists.vim
@@ -0,0 +1,321 @@
+" Tests for the exists() function
+func Test_exists()
+ augroup myagroup
+ autocmd! BufEnter *.my echo "myfile edited"
+ autocmd! FuncUndefined UndefFun exec "fu UndefFun()\nendfu"
+ augroup END
+ set rtp+=./sautest
+
+ " valid autocmd group
+ call assert_equal(1, exists('#myagroup'))
+ " valid autocmd group with garbage
+ call assert_equal(0, exists('#myagroup+b'))
+ " Valid autocmd group and event
+ call assert_equal(1, exists('#myagroup#BufEnter'))
+ " Valid autocmd group, event and pattern
+ call assert_equal(1, exists('#myagroup#BufEnter#*.my'))
+ " Valid autocmd event
+ call assert_equal(1, exists('#BufEnter'))
+ " Valid autocmd event and pattern
+ call assert_equal(1, exists('#BufEnter#*.my'))
+ " Non-existing autocmd group or event
+ call assert_equal(0, exists('#xyzagroup'))
+ " Non-existing autocmd group and valid autocmd event
+ call assert_equal(0, exists('#xyzagroup#BufEnter'))
+ " Valid autocmd group and event with no matching pattern
+ call assert_equal(0, exists('#myagroup#CmdwinEnter'))
+ " Valid autocmd group and non-existing autocmd event
+ call assert_equal(0, exists('#myagroup#xyzacmd'))
+ " Valid autocmd group and event and non-matching pattern
+ call assert_equal(0, exists('#myagroup#BufEnter#xyzpat'))
+ " Valid autocmd event and non-matching pattern
+ call assert_equal(0, exists('#BufEnter#xyzpat'))
+ " Empty autocmd group, event and pattern
+ call assert_equal(0, exists('###'))
+ " Empty autocmd group and event or empty event and pattern
+ call assert_equal(0, exists('##'))
+ " Valid autocmd event
+ call assert_equal(1, exists('##FileReadCmd'))
+ " Non-existing autocmd event
+ call assert_equal(0, exists('##MySpecialCmd'))
+
+ " Existing and working option (long form)
+ call assert_equal(1, exists('&textwidth'))
+ " Existing and working option (short form)
+ call assert_equal(1, exists('&tw'))
+ " Existing and working option with garbage
+ call assert_equal(0, exists('&tw-'))
+ " Global option
+ call assert_equal(1, exists('&g:errorformat'))
+ " Local option
+ call assert_equal(1, exists('&l:errorformat'))
+ " Negative form of existing and working option (long form)
+ call assert_equal(0, exists('&nojoinspaces'))
+ " Negative form of existing and working option (short form)
+ call assert_equal(0, exists('&nojs'))
+ " Non-existing option
+ call assert_equal(0, exists('&myxyzoption'))
+
+ " Existing and working option (long form)
+ call assert_equal(1, exists('+incsearch'))
+ " Existing and working option with garbage
+ call assert_equal(0, exists('+incsearch!1'))
+ " Existing and working option (short form)
+ call assert_equal(1, exists('+is'))
+ " Existing option that is hidden.
+ call assert_equal(0, exists('+autoprint'))
+
+ " Existing environment variable
+ let $EDITOR_NAME = 'Vim Editor'
+ call assert_equal(1, exists('$EDITOR_NAME'))
+ " Non-existing environment variable
+ call assert_equal(0, exists('$NON_ENV_VAR'))
+
+ " Valid internal function
+ call assert_equal(1, exists('*bufnr'))
+ " Valid internal function with ()
+ call assert_equal(1, exists('*bufnr()'))
+ " Non-existing internal function
+ call assert_equal(0, exists('*myxyzfunc'))
+ " Valid internal function with garbage
+ call assert_equal(0, exists('*bufnr&6'))
+ " Valid user defined function
+ call assert_equal(1, exists('*Test_exists'))
+ " Non-existing user defined function
+ call assert_equal(0, exists('*MyxyzFunc'))
+ " Function that may be created by FuncUndefined event
+ call assert_equal(0, exists('*UndefFun'))
+ " Function that may be created by script autoloading
+ call assert_equal(0, exists('*footest#F'))
+
+ " Valid internal command (full match)
+ call assert_equal(2, exists(':edit'))
+ " Valid internal command (full match) with garbage
+ call assert_equal(0, exists(':edit/a'))
+ " Valid internal command (partial match)
+ call assert_equal(1, exists(':q'))
+ " Non-existing internal command
+ call assert_equal(0, exists(':invalidcmd'))
+
+ " User defined command (full match)
+ command! MyCmd :echo 'My command'
+ call assert_equal(2, exists(':MyCmd'))
+ " User defined command (partial match)
+ command! MyOtherCmd :echo 'Another command'
+ call assert_equal(3, exists(':My'))
+
+ " Command modifier
+ call assert_equal(2, exists(':rightbelow'))
+
+ " Non-existing user defined command (full match)
+ delcommand MyCmd
+ call assert_equal(0, exists(':MyCmd'))
+
+ " Non-existing user defined command (partial match)
+ delcommand MyOtherCmd
+ call assert_equal(0, exists(':My'))
+
+ " Valid local variable
+ let local_var = 1
+ call assert_equal(1, exists('local_var'))
+ " Valid local variable with garbage
+ call assert_equal(0, exists('local_var%n'))
+ " Non-existing local variable
+ unlet local_var
+ call assert_equal(0, exists('local_var'))
+
+ " Non-existing autoload variable that may be autoloaded
+ call assert_equal(0, exists('footest#x'))
+
+ " Valid local list
+ let local_list = ["blue", "orange"]
+ call assert_equal(1, exists('local_list'))
+ " Valid local list item
+ call assert_equal(1, exists('local_list[1]'))
+ " Valid local list item with garbage
+ call assert_equal(0, exists('local_list[1]+5'))
+ " Invalid local list item
+ call assert_equal(0, exists('local_list[2]'))
+ " Non-existing local list
+ unlet local_list
+ call assert_equal(0, exists('local_list'))
+ " Valid local dictionary
+ let local_dict = {"xcord":100, "ycord":2}
+ call assert_equal(1, exists('local_dict'))
+ " Non-existing local dictionary
+ unlet local_dict
+ call assert_equal(0, exists('local_dict'))
+ " Existing local curly-brace variable
+ let str = "local"
+ let curly_{str}_var = 1
+ call assert_equal(1, exists('curly_{str}_var'))
+ " Non-existing local curly-brace variable
+ unlet curly_{str}_var
+ call assert_equal(0, exists('curly_{str}_var'))
+
+ " Existing global variable
+ let g:global_var = 1
+ call assert_equal(1, exists('g:global_var'))
+ " Existing global variable with garbage
+ call assert_equal(0, exists('g:global_var-n'))
+ " Non-existing global variable
+ unlet g:global_var
+ call assert_equal(0, exists('g:global_var'))
+ " Existing global list
+ let g:global_list = ["blue", "orange"]
+ call assert_equal(1, exists('g:global_list'))
+ " Non-existing global list
+ unlet g:global_list
+ call assert_equal(0, exists('g:global_list'))
+ " Existing global dictionary
+ let g:global_dict = {"xcord":100, "ycord":2}
+ call assert_equal(1, exists('g:global_dict'))
+ " Non-existing global dictionary
+ unlet g:global_dict
+ call assert_equal(0, exists('g:global_dict'))
+ " Existing global curly-brace variable
+ let str = "global"
+ let g:curly_{str}_var = 1
+ call assert_equal(1, exists('g:curly_{str}_var'))
+ " Non-existing global curly-brace variable
+ unlet g:curly_{str}_var
+ call assert_equal(0, exists('g:curly_{str}_var'))
+
+ " Existing window variable
+ let w:window_var = 1
+ call assert_equal(1, exists('w:window_var'))
+ " Non-existing window variable
+ unlet w:window_var
+ call assert_equal(0, exists('w:window_var'))
+ " Existing window list
+ let w:window_list = ["blue", "orange"]
+ call assert_equal(1, exists('w:window_list'))
+ " Non-existing window list
+ unlet w:window_list
+ call assert_equal(0, exists('w:window_list'))
+ " Existing window dictionary
+ let w:window_dict = {"xcord":100, "ycord":2}
+ call assert_equal(1, exists('w:window_dict'))
+ " Non-existing window dictionary
+ unlet w:window_dict
+ call assert_equal(0, exists('w:window_dict'))
+ " Existing window curly-brace variable
+ let str = "window"
+ let w:curly_{str}_var = 1
+ call assert_equal(1, exists('w:curly_{str}_var'))
+ " Non-existing window curly-brace variable
+ unlet w:curly_{str}_var
+ call assert_equal(0, exists('w:curly_{str}_var'))
+
+ " Existing tab variable
+ let t:tab_var = 1
+ call assert_equal(1, exists('t:tab_var'))
+ " Non-existing tab variable
+ unlet t:tab_var
+ call assert_equal(0, exists('t:tab_var'))
+ " Existing tab list
+ let t:tab_list = ["blue", "orange"]
+ call assert_equal(1, exists('t:tab_list'))
+ " Non-existing tab list
+ unlet t:tab_list
+ call assert_equal(0, exists('t:tab_list'))
+ " Existing tab dictionary
+ let t:tab_dict = {"xcord":100, "ycord":2}
+ call assert_equal(1, exists('t:tab_dict'))
+ " Non-existing tab dictionary
+ unlet t:tab_dict
+ call assert_equal(0, exists('t:tab_dict'))
+ " Existing tab curly-brace variable
+ let str = "tab"
+ let t:curly_{str}_var = 1
+ call assert_equal(1, exists('t:curly_{str}_var'))
+ " Non-existing tab curly-brace variable
+ unlet t:curly_{str}_var
+ call assert_equal(0, exists('t:curly_{str}_var'))
+
+ " Existing buffer variable
+ let b:buffer_var = 1
+ call assert_equal(1, exists('b:buffer_var'))
+ " Non-existing buffer variable
+ unlet b:buffer_var
+ call assert_equal(0, exists('b:buffer_var'))
+ " Existing buffer list
+ let b:buffer_list = ["blue", "orange"]
+ call assert_equal(1, exists('b:buffer_list'))
+ " Non-existing buffer list
+ unlet b:buffer_list
+ call assert_equal(0, exists('b:buffer_list'))
+ " Existing buffer dictionary
+ let b:buffer_dict = {"xcord":100, "ycord":2}
+ call assert_equal(1, exists('b:buffer_dict'))
+ " Non-existing buffer dictionary
+ unlet b:buffer_dict
+ call assert_equal(0, exists('b:buffer_dict'))
+ " Existing buffer curly-brace variable
+ let str = "buffer"
+ let b:curly_{str}_var = 1
+ call assert_equal(1, exists('b:curly_{str}_var'))
+ " Non-existing buffer curly-brace variable
+ unlet b:curly_{str}_var
+ call assert_equal(0, exists('b:curly_{str}_var'))
+
+ " Existing Vim internal variable
+ call assert_equal(1, exists('v:version'))
+ " Non-existing Vim internal variable
+ call assert_equal(0, exists('v:non_exists_var'))
+
+ " Existing script-local variable
+ let s:script_var = 1
+ call assert_equal(1, exists('s:script_var'))
+ " Non-existing script-local variable
+ unlet s:script_var
+ call assert_equal(0, exists('s:script_var'))
+ " Existing script-local list
+ let s:script_list = ["blue", "orange"]
+ call assert_equal(1, exists('s:script_list'))
+ " Non-existing script-local list
+ unlet s:script_list
+ call assert_equal(0, exists('s:script_list'))
+ " Existing script-local dictionary
+ let s:script_dict = {"xcord":100, "ycord":2}
+ call assert_equal(1, exists('s:script_dict'))
+ " Non-existing script-local dictionary
+ unlet s:script_dict
+ call assert_equal(0, exists('s:script_dict'))
+ " Existing script curly-brace variable
+ let str = "script"
+ let s:curly_{str}_var = 1
+ call assert_equal(1, exists('s:curly_{str}_var'))
+ " Non-existing script-local curly-brace variable
+ unlet s:curly_{str}_var
+ call assert_equal(0, exists('s:curly_{str}_var'))
+
+ " Existing script-local function
+ function! s:my_script_func()
+ endfunction
+
+ echo '*s:my_script_func: 1'
+ call assert_equal(1, exists('*s:my_script_func'))
+
+ " Non-existing script-local function
+ delfunction s:my_script_func
+
+ call assert_equal(0, exists('*s:my_script_func'))
+ unlet str
+
+ call assert_equal(1, g:footest#x)
+ call assert_equal(0, footest#F())
+ call assert_equal(0, UndefFun())
+endfunc
+
+" exists() test for Function arguments
+func FuncArg_Tests(func_arg, ...)
+ call assert_equal(1, exists('a:func_arg'))
+ call assert_equal(0, exists('a:non_exists_arg'))
+ call assert_equal(1, exists('a:1'))
+ call assert_equal(0, exists('a:2'))
+endfunc
+
+func Test_exists_funcarg()
+ call FuncArg_Tests("arg1", "arg2")
+endfunc
diff --git a/src/nvim/testdir/test_exists_autocmd.vim b/src/nvim/testdir/test_exists_autocmd.vim
new file mode 100644
index 0000000000..7e44a72653
--- /dev/null
+++ b/src/nvim/testdir/test_exists_autocmd.vim
@@ -0,0 +1,26 @@
+" Test that groups and patterns are tested correctly when calling exists() for
+" autocommands.
+
+function Test_AutoCommands()
+ let results=[]
+ augroup auexists
+ augroup END
+ call assert_true(exists("##BufEnter"))
+ call assert_false(exists("#BufEnter"))
+ au BufEnter * let g:entered=1
+ call assert_true(exists("#BufEnter"))
+ call assert_false(exists("#auexists#BufEnter"))
+ augroup auexists
+ au BufEnter * let g:entered=1
+ augroup END
+ call assert_true(exists("#auexists#BufEnter"))
+ call assert_false(exists("#BufEnter#*.test"))
+ au BufEnter *.test let g:entered=1
+ call assert_true(exists("#BufEnter#*.test"))
+ edit testfile.test
+ call assert_false(exists("#BufEnter#<buffer>"))
+ au BufEnter <buffer> let g:entered=1
+ call assert_true(exists("#BufEnter#<buffer>"))
+ edit testfile2.test
+ call assert_false(exists("#BufEnter#<buffer>"))
+endfunction
diff --git a/src/nvim/testdir/test_exit.vim b/src/nvim/testdir/test_exit.vim
new file mode 100644
index 0000000000..8f02fd29e3
--- /dev/null
+++ b/src/nvim/testdir/test_exit.vim
@@ -0,0 +1,57 @@
+" Tests for exiting Vim.
+
+source shared.vim
+
+func Test_exiting()
+ let after = [
+ \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
+ \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
+ \ 'quit',
+ \ ]
+ if RunVim([], after, '')
+ call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
+ endif
+ call delete('Xtestout')
+
+ let after = [
+ \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
+ \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
+ \ 'help',
+ \ 'wincmd w',
+ \ 'quit',
+ \ ]
+ if RunVim([], after, '')
+ call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
+ endif
+ call delete('Xtestout')
+
+ let after = [
+ \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")',
+ \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
+ \ 'split',
+ \ 'new',
+ \ 'qall',
+ \ ]
+ if RunVim([], after, '')
+ call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout'))
+ endif
+ call delete('Xtestout')
+
+ let after = [
+ \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")',
+ \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")',
+ \ 'augroup nasty',
+ \ ' au ExitPre * split',
+ \ 'augroup END',
+ \ 'quit',
+ \ 'augroup nasty',
+ \ ' au! ExitPre',
+ \ 'augroup END',
+ \ 'quit',
+ \ ]
+ if RunVim([], after, '')
+ call assert_equal(['QuitPre', 'ExitPre', 'QuitPre', 'ExitPre'],
+ \ readfile('Xtestout'))
+ endif
+ call delete('Xtestout')
+endfunc
diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim
new file mode 100644
index 0000000000..4f99625e73
--- /dev/null
+++ b/src/nvim/testdir/test_expr.vim
@@ -0,0 +1,480 @@
+" Tests for expressions.
+
+func Test_equal()
+ let base = {}
+ func base.method()
+ return 1
+ endfunc
+ func base.other() dict
+ return 1
+ endfunc
+ let instance = copy(base)
+ call assert_true(base.method == instance.method)
+ call assert_true([base.method] == [instance.method])
+ call assert_true(base.other == instance.other)
+ call assert_true([base.other] == [instance.other])
+
+ call assert_false(base.method == base.other)
+ call assert_false([base.method] == [base.other])
+ call assert_false(base.method == instance.other)
+ call assert_false([base.method] == [instance.other])
+
+ call assert_fails('echo base.method > instance.method')
+endfunc
+
+func Test_version()
+ call assert_true(has('patch-7.4.001'))
+ call assert_true(has('patch-7.4.01'))
+ call assert_true(has('patch-7.4.1'))
+ call assert_true(has('patch-6.9.999'))
+ call assert_true(has('patch-7.1.999'))
+ call assert_true(has('patch-7.4.123'))
+
+ call assert_false(has('patch-7'))
+ call assert_false(has('patch-7.4'))
+ call assert_false(has('patch-7.4.'))
+ call assert_false(has('patch-9.1.0'))
+ call assert_false(has('patch-9.9.1'))
+endfunc
+
+func Test_dict()
+ let d = {'': 'empty', 'a': 'a', 0: 'zero'}
+ call assert_equal('empty', d[''])
+ call assert_equal('a', d['a'])
+ call assert_equal('zero', d[0])
+ call assert_true(has_key(d, ''))
+ call assert_true(has_key(d, 'a'))
+
+ let d[''] = 'none'
+ let d['a'] = 'aaa'
+ call assert_equal('none', d[''])
+ call assert_equal('aaa', d['a'])
+endfunc
+
+func Test_strgetchar()
+ call assert_equal(char2nr('a'), strgetchar('axb', 0))
+ call assert_equal(char2nr('x'), strgetchar('axb', 1))
+ call assert_equal(char2nr('b'), strgetchar('axb', 2))
+
+ call assert_equal(-1, strgetchar('axb', -1))
+ call assert_equal(-1, strgetchar('axb', 3))
+ call assert_equal(-1, strgetchar('', 0))
+endfunc
+
+func Test_strcharpart()
+ call assert_equal('a', strcharpart('axb', 0, 1))
+ call assert_equal('x', strcharpart('axb', 1, 1))
+ call assert_equal('b', strcharpart('axb', 2, 1))
+ call assert_equal('xb', strcharpart('axb', 1))
+
+ call assert_equal('', strcharpart('axb', 1, 0))
+ call assert_equal('', strcharpart('axb', 1, -1))
+ call assert_equal('', strcharpart('axb', -1, 1))
+ call assert_equal('', strcharpart('axb', -2, 2))
+
+ call assert_equal('a', strcharpart('axb', -1, 2))
+endfunc
+
+func Test_loop_over_null_list()
+ let null_list = submatch(1, 1)
+ for i in null_list
+ call assert_report('should not get here')
+ endfor
+endfunc
+
+func Test_compare_null_dict()
+ call assert_fails('let x = v:_null_dict[10]')
+ call assert_equal({}, {})
+ call assert_equal(v:_null_dict, v:_null_dict)
+ call assert_notequal({}, v:_null_dict)
+endfunc
+
+func Test_set_reg_null_list()
+ call setreg('x', v:_null_list)
+endfunc
+
+func Test_special_char()
+ " The failure is only visible using valgrind.
+ call assert_fails('echo "\<C-">')
+endfunc
+
+func Test_option_value()
+ " boolean
+ set bri
+ call assert_equal(1, &bri)
+ set nobri
+ call assert_equal(0, &bri)
+
+ " number
+ set ts=1
+ call assert_equal(1, &ts)
+ set ts=8
+ call assert_equal(8, &ts)
+
+ " string
+ exe "set cedit=\<Esc>"
+ call assert_equal("\<Esc>", &cedit)
+ set cpo=
+ call assert_equal("", &cpo)
+ set cpo=abcdefi
+ call assert_equal("abcdefi", &cpo)
+ set cpo&vim
+endfunc
+
+function Test_printf_64bit()
+ if has('num64')
+ call assert_equal("123456789012345", printf('%d', 123456789012345))
+ endif
+endfunc
+
+func Test_setmatches()
+ hi def link 1 Comment
+ hi def link 2 PreProc
+ let set = [{"group": 1, "pattern": 2, "id": 3, "priority": 4}]
+ let exp = [{"group": '1', "pattern": '2', "id": 3, "priority": 4}]
+ if has('conceal')
+ let set[0]['conceal'] = 5
+ let exp[0]['conceal'] = '5'
+ endif
+ call setmatches(set)
+ call assert_equal(exp, getmatches())
+endfunc
+
+function Test_printf_spec_s()
+ " number
+ call assert_equal("1234567890", printf('%s', 1234567890))
+
+ " string
+ call assert_equal("abcdefgi", printf('%s', "abcdefgi"))
+
+ " float
+ call assert_equal("1.23", printf('%s', 1.23))
+
+ " list
+ let value = [1, 'two', ['three', 4]]
+ call assert_equal(string(value), printf('%s', value))
+
+ " dict
+ let value = {'key1' : 'value1', 'key2' : ['list', 'value'], 'key3' : {'dict' : 'value'}}
+ call assert_equal(string(value), printf('%s', value))
+
+ " funcref
+ call assert_equal('printf', printf('%s', function('printf')))
+
+ " partial
+ call assert_equal(string(function('printf', ['%s'])), printf('%s', function('printf', ['%s'])))
+endfunc
+
+function Test_printf_misc()
+ call assert_equal('123', printf('123'))
+ call assert_fails("call printf('123', 3)", "E767:")
+
+ call assert_equal('123', printf('%d', 123))
+ call assert_equal('123', printf('%i', 123))
+ call assert_equal('123', printf('%D', 123))
+ call assert_equal('123', printf('%U', 123))
+ call assert_equal('173', printf('%o', 123))
+ call assert_equal('173', printf('%O', 123))
+ call assert_equal('7b', printf('%x', 123))
+ call assert_equal('7B', printf('%X', 123))
+
+ call assert_equal('123', printf('%hd', 123))
+ call assert_equal('-123', printf('%hd', -123))
+ call assert_equal('-1', printf('%hd', 0xFFFF))
+ call assert_equal('-1', printf('%hd', 0x1FFFFF))
+
+ call assert_equal('123', printf('%hu', 123))
+ call assert_equal('65413', printf('%hu', -123))
+ call assert_equal('65535', printf('%hu', 0xFFFF))
+ call assert_equal('65535', printf('%hu', 0x1FFFFF))
+
+ call assert_equal('123', printf('%ld', 123))
+ call assert_equal('-123', printf('%ld', -123))
+ call assert_equal('65535', printf('%ld', 0xFFFF))
+ call assert_equal('131071', printf('%ld', 0x1FFFF))
+
+ call assert_equal('{', printf('%c', 123))
+ call assert_equal('abc', printf('%s', 'abc'))
+ call assert_equal('abc', printf('%S', 'abc'))
+
+ call assert_equal('+123', printf('%+d', 123))
+ call assert_equal('-123', printf('%+d', -123))
+ call assert_equal('+123', printf('%+ d', 123))
+ call assert_equal(' 123', printf('% d', 123))
+ call assert_equal(' 123', printf('% d', 123))
+ call assert_equal('-123', printf('% d', -123))
+
+ call assert_equal('123', printf('%2d', 123))
+ call assert_equal(' 123', printf('%6d', 123))
+ call assert_equal('000123', printf('%06d', 123))
+ call assert_equal('+00123', printf('%+06d', 123))
+ call assert_equal(' 00123', printf('% 06d', 123))
+ call assert_equal(' +123', printf('%+6d', 123))
+ call assert_equal(' 123', printf('% 6d', 123))
+ call assert_equal(' -123', printf('% 6d', -123))
+
+ " Test left adjusted.
+ call assert_equal('123 ', printf('%-6d', 123))
+ call assert_equal('+123 ', printf('%-+6d', 123))
+ call assert_equal(' 123 ', printf('%- 6d', 123))
+ call assert_equal('-123 ', printf('%- 6d', -123))
+
+ call assert_equal(' 00123', printf('%7.5d', 123))
+ call assert_equal(' -00123', printf('%7.5d', -123))
+ call assert_equal(' +00123', printf('%+7.5d', 123))
+ " Precision field should not be used when combined with %0
+ call assert_equal(' 00123', printf('%07.5d', 123))
+ call assert_equal(' -00123', printf('%07.5d', -123))
+
+ call assert_equal(' 123', printf('%*d', 5, 123))
+ call assert_equal('123 ', printf('%*d', -5, 123))
+ call assert_equal('00123', printf('%.*d', 5, 123))
+ call assert_equal(' 123', printf('% *d', 5, 123))
+ call assert_equal(' +123', printf('%+ *d', 5, 123))
+
+ call assert_equal('foobar', printf('%.*s', 9, 'foobar'))
+ call assert_equal('foo', printf('%.*s', 3, 'foobar'))
+ call assert_equal('', printf('%.*s', 0, 'foobar'))
+ call assert_equal('foobar', printf('%.*s', -1, 'foobar'))
+
+ " Simple quote (thousand grouping char) is ignored.
+ call assert_equal('+00123456', printf("%+'09d", 123456))
+
+ " Unrecognized format specifier kept as-is.
+ call assert_equal('_123', printf("%_%d", 123))
+
+ " Test alternate forms.
+ call assert_equal('0x7b', printf('%#x', 123))
+ call assert_equal('0X7B', printf('%#X', 123))
+ call assert_equal('0173', printf('%#o', 123))
+ call assert_equal('0173', printf('%#O', 123))
+ call assert_equal('abc', printf('%#s', 'abc'))
+ call assert_equal('abc', printf('%#S', 'abc'))
+ call assert_equal(' 0173', printf('%#6o', 123))
+ call assert_equal(' 00173', printf('%#6.5o', 123))
+ call assert_equal(' 0173', printf('%#6.2o', 123))
+ call assert_equal(' 0173', printf('%#6.2o', 123))
+ call assert_equal('0173', printf('%#2.2o', 123))
+
+ call assert_equal(' 00123', printf('%6.5d', 123))
+ call assert_equal(' 0007b', printf('%6.5x', 123))
+
+ call assert_equal('123', printf('%.2d', 123))
+ call assert_equal('0123', printf('%.4d', 123))
+ call assert_equal('0000000123', printf('%.10d', 123))
+ call assert_equal('123', printf('%.0d', 123))
+
+ call assert_equal('abc', printf('%2s', 'abc'))
+ call assert_equal('abc', printf('%2S', 'abc'))
+ call assert_equal('abc', printf('%.4s', 'abc'))
+ call assert_equal('abc', printf('%.4S', 'abc'))
+ call assert_equal('ab', printf('%.2s', 'abc'))
+ call assert_equal('ab', printf('%.2S', 'abc'))
+ call assert_equal('', printf('%.0s', 'abc'))
+ call assert_equal('', printf('%.s', 'abc'))
+ call assert_equal(' abc', printf('%4s', 'abc'))
+ call assert_equal(' abc', printf('%4S', 'abc'))
+ call assert_equal('0abc', printf('%04s', 'abc'))
+ call assert_equal('0abc', printf('%04S', 'abc'))
+ call assert_equal('abc ', printf('%-4s', 'abc'))
+ call assert_equal('abc ', printf('%-4S', 'abc'))
+
+ call assert_equal('1%', printf('%d%%', 1))
+endfunc
+
+function Test_printf_float()
+ call assert_equal('1.000000', printf('%f', 1))
+ call assert_equal('1.230000', printf('%f', 1.23))
+ call assert_equal('1.230000', printf('%F', 1.23))
+ call assert_equal('9999999.9', printf('%g', 9999999.9))
+ call assert_equal('9999999.9', printf('%G', 9999999.9))
+ call assert_equal('1.00000001e7', printf('%.8g', 10000000.1))
+ call assert_equal('1.00000001E7', printf('%.8G', 10000000.1))
+ call assert_equal('1.230000e+00', printf('%e', 1.23))
+ call assert_equal('1.230000E+00', printf('%E', 1.23))
+ call assert_equal('1.200000e-02', printf('%e', 0.012))
+ call assert_equal('-1.200000e-02', printf('%e', -0.012))
+ call assert_equal('0.33', printf('%.2f', 1.0/3.0))
+ call assert_equal(' 0.33', printf('%6.2f', 1.0/3.0))
+ call assert_equal(' -0.33', printf('%6.2f', -1.0/3.0))
+ call assert_equal('000.33', printf('%06.2f', 1.0/3.0))
+ call assert_equal('-00.33', printf('%06.2f', -1.0/3.0))
+ call assert_equal('-00.33', printf('%+06.2f', -1.0/3.0))
+ call assert_equal('+00.33', printf('%+06.2f', 1.0/3.0))
+ call assert_equal(' 00.33', printf('% 06.2f', 1.0/3.0))
+ call assert_equal('000.33', printf('%06.2g', 1.0/3.0))
+ call assert_equal('-00.33', printf('%06.2g', -1.0/3.0))
+ call assert_equal('0.33', printf('%3.2f', 1.0/3.0))
+ call assert_equal('003.33e-01', printf('%010.2e', 1.0/3.0))
+ call assert_equal(' 03.33e-01', printf('% 010.2e', 1.0/3.0))
+ call assert_equal('+03.33e-01', printf('%+010.2e', 1.0/3.0))
+ call assert_equal('-03.33e-01', printf('%010.2e', -1.0/3.0))
+
+ " When precision is 0, the dot should be omitted.
+ call assert_equal(' 2', printf('%3.f', 7.0/3.0))
+ call assert_equal(' 2', printf('%3.g', 7.0/3.0))
+ call assert_equal(' 2e+00', printf('%7.e', 7.0/3.0))
+
+ " Float zero can be signed.
+ call assert_equal('+0.000000', printf('%+f', 0.0))
+ call assert_equal('0.000000', printf('%f', 1.0/(1.0/0.0)))
+ call assert_equal('-0.000000', printf('%f', 1.0/(-1.0/0.0)))
+ call assert_equal('0.0', printf('%s', 1.0/(1.0/0.0)))
+ call assert_equal('-0.0', printf('%s', 1.0/(-1.0/0.0)))
+ call assert_equal('0.0', printf('%S', 1.0/(1.0/0.0)))
+ call assert_equal('-0.0', printf('%S', 1.0/(-1.0/0.0)))
+
+ " Float infinity can be signed.
+ call assert_equal('inf', printf('%f', 1.0/0.0))
+ call assert_equal('-inf', printf('%f', -1.0/0.0))
+ call assert_equal('inf', printf('%g', 1.0/0.0))
+ call assert_equal('-inf', printf('%g', -1.0/0.0))
+ call assert_equal('inf', printf('%e', 1.0/0.0))
+ call assert_equal('-inf', printf('%e', -1.0/0.0))
+ call assert_equal('INF', printf('%F', 1.0/0.0))
+ call assert_equal('-INF', printf('%F', -1.0/0.0))
+ call assert_equal('INF', printf('%E', 1.0/0.0))
+ call assert_equal('-INF', printf('%E', -1.0/0.0))
+ call assert_equal('INF', printf('%E', 1.0/0.0))
+ call assert_equal('-INF', printf('%G', -1.0/0.0))
+ call assert_equal('+inf', printf('%+f', 1.0/0.0))
+ call assert_equal('-inf', printf('%+f', -1.0/0.0))
+ call assert_equal(' inf', printf('% f', 1.0/0.0))
+ call assert_equal(' inf', printf('%6f', 1.0/0.0))
+ call assert_equal(' -inf', printf('%6f', -1.0/0.0))
+ call assert_equal(' inf', printf('%6g', 1.0/0.0))
+ call assert_equal(' -inf', printf('%6g', -1.0/0.0))
+ call assert_equal(' +inf', printf('%+6f', 1.0/0.0))
+ call assert_equal(' inf', printf('% 6f', 1.0/0.0))
+ call assert_equal(' +inf', printf('%+06f', 1.0/0.0))
+ call assert_equal('inf ', printf('%-6f', 1.0/0.0))
+ call assert_equal('-inf ', printf('%-6f', -1.0/0.0))
+ call assert_equal('+inf ', printf('%-+6f', 1.0/0.0))
+ call assert_equal(' inf ', printf('%- 6f', 1.0/0.0))
+ call assert_equal('-INF ', printf('%-6F', -1.0/0.0))
+ call assert_equal('+INF ', printf('%-+6F', 1.0/0.0))
+ call assert_equal(' INF ', printf('%- 6F', 1.0/0.0))
+ call assert_equal('INF ', printf('%-6G', 1.0/0.0))
+ call assert_equal('-INF ', printf('%-6G', -1.0/0.0))
+ call assert_equal('INF ', printf('%-6E', 1.0/0.0))
+ call assert_equal('-INF ', printf('%-6E', -1.0/0.0))
+ call assert_equal("str2float('inf')", printf('%s', 1.0/0.0))
+ call assert_equal("-str2float('inf')", printf('%s', -1.0/0.0))
+
+ " Test special case where max precision is truncated at 340.
+ call assert_equal('1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', printf('%.330f', 1.0))
+ call assert_equal('1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', printf('%.340f', 1.0))
+ call assert_equal('1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', printf('%.350f', 1.0))
+
+ " Float nan (not a number) has no sign.
+ call assert_equal('nan', printf('%f', sqrt(-1.0)))
+ call assert_equal('nan', printf('%f', 0.0/0.0))
+ call assert_equal('nan', printf('%f', -0.0/0.0))
+ call assert_equal('nan', printf('%g', 0.0/0.0))
+ call assert_equal('nan', printf('%e', 0.0/0.0))
+ call assert_equal('NAN', printf('%F', 0.0/0.0))
+ call assert_equal('NAN', printf('%G', 0.0/0.0))
+ call assert_equal('NAN', printf('%E', 0.0/0.0))
+ call assert_equal('NAN', printf('%F', -0.0/0.0))
+ call assert_equal('NAN', printf('%G', -0.0/0.0))
+ call assert_equal('NAN', printf('%E', -0.0/0.0))
+ call assert_equal(' nan', printf('%6f', 0.0/0.0))
+ call assert_equal(' nan', printf('%06f', 0.0/0.0))
+ call assert_equal('nan ', printf('%-6f', 0.0/0.0))
+ call assert_equal('nan ', printf('%- 6f', 0.0/0.0))
+ call assert_equal("str2float('nan')", printf('%s', 0.0/0.0))
+ call assert_equal("str2float('nan')", printf('%s', -0.0/0.0))
+ call assert_equal("str2float('nan')", printf('%S', 0.0/0.0))
+ call assert_equal("str2float('nan')", printf('%S', -0.0/0.0))
+
+ call assert_fails('echo printf("%f", "a")', 'E807:')
+endfunc
+
+function Test_printf_errors()
+ call assert_fails('echo printf("%d", {})', 'E728:')
+ call assert_fails('echo printf("%d", [])', 'E745:')
+ call assert_fails('echo printf("%d", 1, 2)', 'E767:')
+ call assert_fails('echo printf("%*d", 1)', 'E766:')
+ call assert_fails('echo printf("%d", 1.2)', 'E805:')
+endfunc
+
+function Test_max_min_errors()
+ call assert_fails('call max(v:true)', 'E712:')
+ call assert_fails('call max(v:true)', 'max()')
+ call assert_fails('call min(v:true)', 'E712:')
+ call assert_fails('call min(v:true)', 'min()')
+endfunc
+
+func Test_substitute_expr()
+ let g:val = 'XXX'
+ call assert_equal('XXX', substitute('yyy', 'y*', '\=g:val', ''))
+ call assert_equal('XXX', substitute('yyy', 'y*', {-> g:val}, ''))
+ call assert_equal("-\u1b \uf2-", substitute("-%1b %f2-", '%\(\x\x\)',
+ \ '\=nr2char("0x" . submatch(1))', 'g'))
+ call assert_equal("-\u1b \uf2-", substitute("-%1b %f2-", '%\(\x\x\)',
+ \ {-> nr2char("0x" . submatch(1))}, 'g'))
+
+ call assert_equal('231', substitute('123', '\(.\)\(.\)\(.\)',
+ \ {-> submatch(2) . submatch(3) . submatch(1)}, ''))
+
+ func Recurse()
+ return substitute('yyy', 'y\(.\)y', {-> submatch(1)}, '')
+ endfunc
+ " recursive call works
+ call assert_equal('-y-x-', substitute('xxx', 'x\(.\)x', {-> '-' . Recurse() . '-' . submatch(1) . '-'}, ''))
+endfunc
+
+func Test_invalid_submatch()
+ " This was causing invalid memory access in Vim-7.4.2232 and older
+ call assert_fails("call substitute('x', '.', {-> submatch(10)}, '')", 'E935:')
+endfunc
+
+func Test_substitute_expr_arg()
+ call assert_equal('123456789-123456789=', substitute('123456789',
+ \ '\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
+ \ {m -> m[0] . '-' . m[1] . m[2] . m[3] . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
+
+ call assert_equal('123456-123456=789', substitute('123456789',
+ \ '\(.\)\(.\)\(.\)\(a*\)\(n*\)\(.\)\(.\)\(.\)\(x*\)',
+ \ {m -> m[0] . '-' . m[1] . m[2] . m[3] . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
+
+ call assert_equal('123456789-123456789x=', substitute('123456789',
+ \ '\(.\)\(.\)\(.*\)',
+ \ {m -> m[0] . '-' . m[1] . m[2] . m[3] . 'x' . m[4] . m[5] . m[6] . m[7] . m[8] . m[9] . '='}, ''))
+
+ call assert_fails("call substitute('xxx', '.', {m -> string(add(m, 'x'))}, '')", 'E742:')
+ call assert_fails("call substitute('xxx', '.', {m -> string(insert(m, 'x'))}, '')", 'E742:')
+ call assert_fails("call substitute('xxx', '.', {m -> string(extend(m, ['x']))}, '')", 'E742:')
+ call assert_fails("call substitute('xxx', '.', {m -> string(remove(m, 1))}, '')", 'E742:')
+endfunc
+
+func Test_function_with_funcref()
+ let s:f = function('type')
+ let s:fref = function(s:f)
+ call assert_equal(v:t_string, s:fref('x'))
+ call assert_fails("call function('s:f')", 'E700:')
+
+ call assert_fails("call function('foo()')", 'E475:')
+ call assert_fails("call function('foo()')", 'foo()')
+endfunc
+
+func Test_funcref()
+ func! One()
+ return 1
+ endfunc
+ let OneByName = function('One')
+ let OneByRef = funcref('One')
+ func! One()
+ return 2
+ endfunc
+ call assert_equal(2, OneByName())
+ call assert_equal(1, OneByRef())
+ let OneByRef = funcref('One')
+ call assert_equal(2, OneByRef())
+ call assert_fails('echo funcref("{")', 'E475:')
+endfunc
+
+func Test_empty_concatenate()
+ call assert_equal('b', 'a'[4:0] . 'b')
+ call assert_equal('b', 'b' . 'a'[4:0])
+endfunc
diff --git a/src/nvim/testdir/test_expr_utf8.vim b/src/nvim/testdir/test_expr_utf8.vim
new file mode 100644
index 0000000000..1737a9f745
--- /dev/null
+++ b/src/nvim/testdir/test_expr_utf8.vim
@@ -0,0 +1,37 @@
+" Tests for expressions using utf-8.
+if !has('multi_byte')
+ finish
+endif
+
+func Test_strgetchar()
+ call assert_equal(char2nr('á'), strgetchar('áxb', 0))
+ call assert_equal(char2nr('x'), strgetchar('áxb', 1))
+
+ call assert_equal(char2nr('a'), strgetchar('àxb', 0))
+ call assert_equal(char2nr('̀'), strgetchar('àxb', 1))
+ call assert_equal(char2nr('x'), strgetchar('àxb', 2))
+
+ call assert_equal(char2nr('ã‚'), strgetchar('ã‚aã„', 0))
+ call assert_equal(char2nr('a'), strgetchar('ã‚aã„', 1))
+ call assert_equal(char2nr('ã„'), strgetchar('ã‚aã„', 2))
+endfunc
+
+func Test_strcharpart()
+ call assert_equal('áxb', strcharpart('áxb', 0))
+ call assert_equal('á', strcharpart('áxb', 0, 1))
+ call assert_equal('x', strcharpart('áxb', 1, 1))
+
+ call assert_equal('ã„ã†eãŠ', strcharpart('ã‚ã„ã†eãŠ', 1))
+ call assert_equal('ã„', strcharpart('ã‚ã„ã†eãŠ', 1, 1))
+ call assert_equal('ã„ã†', strcharpart('ã‚ã„ã†eãŠ', 1, 2))
+ call assert_equal('ã„ã†e', strcharpart('ã‚ã„ã†eãŠ', 1, 3))
+ call assert_equal('ã„ã†eãŠ', strcharpart('ã‚ã„ã†eãŠ', 1, 4))
+ call assert_equal('eãŠ', strcharpart('ã‚ã„ã†eãŠ', 3))
+ call assert_equal('e', strcharpart('ã‚ã„ã†eãŠ', 3, 1))
+
+ call assert_equal('ã‚', strcharpart('ã‚ã„ã†eãŠ', -3, 4))
+
+ call assert_equal('a', strcharpart('àxb', 0, 1))
+ call assert_equal('̀', strcharpart('àxb', 1, 1))
+ call assert_equal('x', strcharpart('àxb', 2, 1))
+endfunc
diff --git a/src/nvim/testdir/test_farsi.vim b/src/nvim/testdir/test_farsi.vim
new file mode 100644
index 0000000000..9ff2653af4
--- /dev/null
+++ b/src/nvim/testdir/test_farsi.vim
@@ -0,0 +1,133 @@
+" Simplistic testing of Farsi mode.
+" Note: must be edited with latin1 encoding.
+
+if !has('farsi') || has('nvim') " Not supported in Nvim. #6192
+ finish
+endif
+" Farsi uses a single byte encoding.
+set enc=latin1
+
+func Test_farsi_toggle()
+ new
+
+ set altkeymap
+ call assert_equal(0, &fkmap)
+ call assert_equal(0, &rl)
+ call feedkeys("\<F8>", 'x')
+ call assert_equal(1, &fkmap)
+ call assert_equal(1, &rl)
+ call feedkeys("\<F8>", 'x')
+ call assert_equal(0, &fkmap)
+ call assert_equal(0, &rl)
+
+ set rl
+ " conversion from Farsi 3342 to Farsi VIM.
+ call setline(1, join(map(range(0x80, 0xff), 'nr2char(v:val)'), ''))
+ call feedkeys("\<F9>", 'x')
+ let exp = [0xfc, 0xf8, 0xc1, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ \ 0xc8, 0xc9, 0xca, 0xd0, 0xd1, 0xd2, 0xd3, 0xd6,
+ \ 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd8, 0xd9, 0xda,
+ \ 0xdb, 0xdc, 0xdc, 0xc1, 0xdd, 0xde, 0xe0, 0xe0,
+ \ 0xe1, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ \ 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae,
+ \ 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ \ 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe,
+ \ 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6,
+ \ 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
+ \ 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ \ 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
+ \ 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ \ 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xfb, 0xfb, 0xfe,
+ \ 0xfe, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
+ \ 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xe1,
+ \ ]
+ call assert_equal(join(map(exp, 'nr2char(v:val)'), ''), getline(1))
+
+ " conversion from Farsi VIM to Farsi 3342.
+ call setline(1, join(map(range(0x80, 0xff), 'nr2char(v:val)'), ''))
+ call feedkeys("\<F9>", 'x')
+ let exp = [0xfc, 0xf8, 0xc1, 0x83, 0x84, 0x85, 0x86, 0x87,
+ \ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x90,
+ \ 0x90, 0x90, 0x92, 0x93, 0x93, 0x95, 0x96, 0x97,
+ \ 0x98, 0xdc, 0x9a, 0x9b, 0x9c, 0x9e, 0x9e, 0xff,
+ \ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ \ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ \ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ \ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ \ 0xc0, 0xc1, 0xc2, 0x83, 0x84, 0x85, 0x86, 0x87,
+ \ 0x88, 0x89, 0x8a, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ \ 0x8b, 0x8c, 0x8d, 0x8e, 0xd4, 0xd5, 0x90, 0x93,
+ \ 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0xdf,
+ \ 0x9d, 0xff, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ \ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xec, 0xee, 0xef,
+ \ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ \ 0xf8, 0xf9, 0xfa, 0xec, 0x80, 0xfd, 0xee, 0xff,
+ \ ]
+ call assert_equal(join(map(exp, 'nr2char(v:val)'), ''), getline(1))
+
+ bwipe!
+endfunc
+
+func Test_farsi_map()
+ new
+
+ set altkeymap
+ set rl
+ " RHS of mapping is reversed.
+ imap xyz abc
+ call feedkeys("axyz\<Esc>", 'tx')
+ call assert_equal('cba', getline(1))
+
+ set norl
+ iunmap xyz
+ set noaltkeymap
+ bwipe!
+endfunc
+
+func Test_input_farsi()
+ new
+ setlocal rightleft fkmap
+ " numbers switch input direction
+ call feedkeys("aabc0123456789.+-^%#=xyz\<Esc>", 'tx')
+ call assert_equal("\x8cÌν®¥ª­«¦¹¸·¶µ´³²±°Ô\x93Õ", getline('.'))
+
+ " all non-number special chars with spaces
+ call feedkeys("oB E F H I K L M O P Q R T U W Y ` ! @ # $ % ^ & * () - _ = + \\ | : \" . / < > ? \<Esc>", 'tx')
+ call assert_equal("¡ ô ú À ö æ ç Â [ ] ÷ ó ò ð õ ñ ¢ £  § ® ¤ ¥ ª ¬ è ¨© ­ é ½ « ë ê º » ¦  ¯ ¾ ¼ ¿ ", getline('.'))
+
+ " all non-number special chars without spaces
+ call feedkeys("oBEFHIKLMOPQRTUWY`!@#$%^&*()-_=+\\|:\"./<>?\<Esc>",'tx')
+ call assert_equal("¡ôúÀöæçÂ[]÷óòðõñ¢£§®¤¥ª¬è¨©­é½«ë꺻¦¯¾¼¿", getline('.'))
+
+ " all letter chars with spaces
+ call feedkeys("oa A b c C d D e f g G h i j J k l m n N o p q r s S t u v V w x X y z Z ; \ , [ ] \<Esc>", 'tx')
+ call assert_equal("Ñ ù Ì Î Ï á þ Æ Ã Ü ø Á à Å ü Þ Ý Ä Ë Ë Ê É Ó Ù Ð û Ø Ö Í Í Ò Ô Ô × Õ ý Ú  ß Ç È ", getline('.'))
+
+ " all letter chars without spaces
+ call feedkeys("oaAbcCdDefgGhijJklmnNopqrsStuvVwxXyzZ;\,[]\<Esc>", 'tx')
+ call assert_equal("\x8cùÌÎÏ\x9fî\x86\x83ÜøÁ\x9d\x85\x80\x9c\x9b\x84ËË\x8a\x89\x8e\x96\x8bì\x95\x90ÍÍ\x8dÔÔ\x93Õý\x97ß\x87\x88", getline('.'))
+
+ bwipe!
+endfunc
+
+func Test_command_line_farsi()
+ set allowrevins altkeymap
+
+ " letter characters with spaces
+ call feedkeys(":\"\<C-_>a A b c C d D e f g G h i j J k l m n N o p q r s S t u v V w x X y z Z ; \\ , [ ]\<CR>", 'tx')
+ call assert_equal("\"\x88 Ç ß ë Ú Õ Õ × Ô Ô Ò Í Í Ö Ø û Ð Ù Ó É Ê Ë Ë Ä Ý Þ ü Å à Á ø Ü Ã Æ þ á Ï Î Ì ù Ñ", getreg(':'))
+
+ " letter characters without spaces
+ call feedkeys(":\"\<C-_>aAbcCdDefgGhijJklmnNopqrsStuvVwxXyzZ;\\,[]\<CR>", 'tx')
+ call assert_equal("\"\x88\x87ßëÚÕÕ\x93ÔÔ\x8dÍÍ\x90\x95ì\x8b\x96\x8e\x89\x8aËË\x84\x9b\x9c\x80\x85\x9dÁøÜ\x83\x86î\x9fÏÎÌù\x8c", getreg(':'))
+
+ " other characters with spaces
+ call feedkeys(":\"\<C-_>0 1 2 3 4 5 6 7 8 9 ` . ! \" $ % ^ & / () = \\ ? + - _ * : # ~ @ < > { } | B E F H I K L M O P Q R T U W Y\<CR>", 'tx')
+ call assert_equal("\"ñ õ ð ò ó ÷ ] [ Â ç æ ö À ú ô ¡ ê } { ¼ ¾ § ~ ® º è é ­ «  ¿ ë ½ ©¨ ¯ ¬ ª ¥ ¤ »  £  ¦ ¢ ¹ ¸ · ¶ µ ´ ³ ² ± °", getreg(':'))
+
+ " other characters without spaces
+ call feedkeys(":\"\<C-_>0123456789`.!\"$%^&/()=\\?+-_*:#~@<>{}|BEFHIKLMOPQRTUWY\<CR>", 'tx')
+ call assert_equal("\"ñõðòó÷][ÂçæöÀúô¡ê}{¼¾§~®ºèé­«¿ë½©¨¯¬ª¥¤»£¦¢¹¸·¶µ´³²±°", getreg(':'))
+
+ set noallowrevins noaltkeymap
+endfunc
diff --git a/src/nvim/testdir/test_feedkeys.vim b/src/nvim/testdir/test_feedkeys.vim
new file mode 100644
index 0000000000..70500f2bb5
--- /dev/null
+++ b/src/nvim/testdir/test_feedkeys.vim
@@ -0,0 +1,14 @@
+" Test feedkeys() function.
+
+func Test_feedkeys_x_with_empty_string()
+ new
+ call feedkeys("ifoo\<Esc>")
+ call assert_equal('', getline('.'))
+ call feedkeys('', 'x')
+ call assert_equal('foo', getline('.'))
+
+ " check it goes back to normal mode immediately.
+ call feedkeys('i', 'x')
+ call assert_equal('foo', getline('.'))
+ quit!
+endfunc
diff --git a/src/nvim/testdir/test_file_size.vim b/src/nvim/testdir/test_file_size.vim
new file mode 100644
index 0000000000..3e78a7b23c
--- /dev/null
+++ b/src/nvim/testdir/test_file_size.vim
@@ -0,0 +1,58 @@
+" Inserts 2 million lines with consecutive integers starting from 1
+" (essentially, the output of GNU's seq 1 2000000), writes them to Xtest
+" and writes its cksum to test.out.
+"
+" We need 2 million lines to trigger a call to mf_hash_grow(). If it would mess
+" up the lines the checksum would differ.
+"
+" cksum is part of POSIX and so should be available on most Unixes.
+" If it isn't available then the test will be skipped.
+func Test_File_Size()
+ if !executable('cksum')
+ return
+ endif
+
+ new
+ set fileformat=unix undolevels=-1
+ for i in range(1, 2000000, 100)
+ call append(i, range(i, i + 99))
+ endfor
+
+ 1delete
+ w! Xtest
+ let res = systemlist('cksum Xtest')[0]
+ let res = substitute(res, "\r", "", "")
+ call assert_equal('3678979763 14888896 Xtest', res)
+
+ enew!
+ call delete('Xtest')
+ set fileformat& undolevels&
+endfunc
+
+" Test for writing and reading a file of over 100 Kbyte
+func Test_File_Read_Write()
+ enew!
+
+ " Create a file with the following contents
+ " 1 line: "This is the start"
+ " 3001 lines: "This is the leader"
+ " 1 line: "This is the middle"
+ " 3001 lines: "This is the trailer"
+ " 1 line: "This is the end"
+ call append(0, "This is the start")
+ call append(1, repeat(["This is the leader"], 3001))
+ call append(3002, "This is the middle")
+ call append(3003, repeat(["This is the trailer"], 3001))
+ call append(6004, "This is the end")
+
+ write! Xtest
+ enew!
+ edit! Xtest
+
+ call assert_equal("This is the start", getline(1))
+ call assert_equal("This is the middle", getline(3003))
+ call assert_equal("This is the end", getline(6005))
+
+ enew!
+ call delete("Xtest")
+endfunc
diff --git a/src/nvim/testdir/test_fileformat.vim b/src/nvim/testdir/test_fileformat.vim
new file mode 100644
index 0000000000..8dc25f62b1
--- /dev/null
+++ b/src/nvim/testdir/test_fileformat.vim
@@ -0,0 +1,33 @@
+" Test behavior of fileformat after bwipeout of last buffer
+
+func Test_fileformat_after_bw()
+ bwipeout
+ set fileformat&
+ if &fileformat == 'dos'
+ let test_fileformats = 'unix'
+ elseif &fileformat == 'unix'
+ let test_fileformats = 'mac'
+ else " must be mac
+ let test_fileformats = 'dos'
+ endif
+ exec 'set fileformats='.test_fileformats
+ bwipeout!
+ call assert_equal(test_fileformats, &fileformat)
+ set fileformats&
+endfunc
+
+func Test_fileformat_autocommand()
+ let filecnt = ["", "foobar\<CR>", "eins\<CR>", "\<CR>", "zwei\<CR>", "drei", "vier", "fünf", ""]
+ let ffs = &ffs
+ call writefile(filecnt, 'Xfile', 'b')
+ au BufReadPre Xfile set ffs=dos ff=dos
+ new Xfile
+ call assert_equal('dos', &l:ff)
+ call assert_equal('dos', &ffs)
+
+ " cleanup
+ call delete('Xfile')
+ let &ffs = ffs
+ au! BufReadPre Xfile
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
new file mode 100644
index 0000000000..5d4a0ff3cb
--- /dev/null
+++ b/src/nvim/testdir/test_filetype.vim
@@ -0,0 +1,602 @@
+" Test :setfiletype
+
+func Test_detection()
+ filetype on
+ augroup filetypedetect
+ au BufNewFile,BufRead * call assert_equal(1, did_filetype())
+ augroup END
+ new something.vim
+ call assert_equal('vim', &filetype)
+
+ bwipe!
+ filetype off
+endfunc
+
+func Test_conf_type()
+ filetype on
+ call writefile(['# some comment', 'must be conf'], 'Xfile')
+ augroup filetypedetect
+ au BufNewFile,BufRead * call assert_equal(0, did_filetype())
+ augroup END
+ split Xfile
+ call assert_equal('conf', &filetype)
+
+ bwipe!
+ call delete('Xfile')
+ filetype off
+endfunc
+
+func Test_other_type()
+ filetype on
+ augroup filetypedetect
+ au BufNewFile,BufRead * call assert_equal(0, did_filetype())
+ au BufNewFile,BufRead Xfile setf testfile
+ au BufNewFile,BufRead * call assert_equal(1, did_filetype())
+ augroup END
+ call writefile(['# some comment', 'must be conf'], 'Xfile')
+ split Xfile
+ call assert_equal('testfile', &filetype)
+
+ bwipe!
+ call delete('Xfile')
+ filetype off
+endfunc
+
+" Filetypes detected just from matching the file name.
+let s:filename_checks = {
+ \ 'a2ps': ['/etc/a2ps.cfg', '/etc/a2ps/file.cfg', 'a2psrc', '.a2psrc'],
+ \ 'a65': ['file.a65'],
+ \ 'abap': ['file.abap'],
+ \ 'abc': ['file.abc'],
+ \ 'abel': ['file.abl'],
+ \ 'acedb': ['file.wrm'],
+ \ 'ada': ['file.adb', 'file.ads', 'file.ada', 'file.gpr'],
+ \ 'ahdl': ['file.tdf'],
+ \ 'alsaconf': ['.asoundrc', '/usr/share/alsa/alsa.conf', '/etc/asound.conf'],
+ \ 'aml': ['file.aml'],
+ \ 'ampl': ['file.run'],
+ \ 'ant': ['build.xml'],
+ \ 'apache': ['.htaccess', '/etc/httpd/file.conf'],
+ \ 'applescript': ['file.scpt'],
+ \ 'aptconf': ['apt.conf', '/.aptitude/config'],
+ \ 'arch': ['.arch-inventory'],
+ \ 'arduino': ['file.ino', 'file.pde'],
+ \ 'art': ['file.art'],
+ \ 'asciidoc': ['file.asciidoc', 'file.adoc'],
+ \ 'asn': ['file.asn', 'file.asn1'],
+ \ 'atlas': ['file.atl', 'file.as'],
+ \ 'autohotkey': ['file.ahk'],
+ \ 'autoit': ['file.au3'],
+ \ 'automake': ['GNUmakefile.am'],
+ \ 'ave': ['file.ave'],
+ \ 'awk': ['file.awk'],
+ \ 'b': ['file.mch', 'file.ref', 'file.imp'],
+ \ 'bc': ['file.bc'],
+ \ 'bdf': ['file.bdf'],
+ \ 'bib': ['file.bib'],
+ \ 'bindzone': ['named.root'],
+ \ 'blank': ['file.bl'],
+ \ 'bst': ['file.bst'],
+ \ 'bzr': ['bzr_log.any'],
+ \ 'c': ['enlightenment/file.cfg', 'file.qc', 'file.c'],
+ \ 'cabal': ['file.cabal'],
+ \ 'calendar': ['calendar'],
+ \ 'catalog': ['catalog'],
+ \ 'cdl': ['file.cdl'],
+ \ 'cdrdaoconf': ['/etc/cdrdao.conf', '/etc/defaults/cdrdao', '/etc/default/cdrdao', '.cdrdao'],
+ \ 'cdrtoc': ['file.toc'],
+ \ 'cf': ['file.cfm', 'file.cfi', 'file.cfc'],
+ \ 'cfengine': ['cfengine.conf'],
+ \ 'cfg': ['file.cfg', 'file.hgrc', 'filehgrc'],
+ \ 'ch': ['file.chf'],
+ \ 'chaiscript': ['file.chai'],
+ \ 'chaskell': ['file.chs'],
+ \ 'chill': ['file..ch'],
+ \ 'chordpro': ['file.chopro', 'file.crd', 'file.cho', 'file.crdpro', 'file.chordpro'],
+ \ 'cl': ['file.eni'],
+ \ 'clean': ['file.dcl', 'file.icl'],
+ \ 'clojure': ['file.clj', 'file.cljs', 'file.cljx', 'file.cljc'],
+ \ 'cmake': ['CMakeLists.txt', 'file.cmake', 'file.cmake.in'],
+ \ 'cmusrc': ['any/.cmus/autosave', 'any/.cmus/rc', 'any/.cmus/command-history', 'any/.cmus/file.theme', 'any/cmus/rc', 'any/cmus/file.theme'],
+ \ 'cobol': ['file.cbl', 'file.cob', 'file.lib'],
+ \ 'coco': ['file.atg'],
+ \ 'conaryrecipe': ['file.recipe'],
+ \ 'conf': ['auto.master'],
+ \ 'config': ['configure.in', 'configure.ac'],
+ \ 'context': ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi'],
+ \ 'cpp': ['file.cxx', 'file.c++', 'file.hh', 'file.hxx', 'file.hpp', 'file.ipp', 'file.moc', 'file.tcc', 'file.inl', 'file.tlh'],
+ \ 'crm': ['file.crm'],
+ \ 'cs': ['file.cs'],
+ \ 'csc': ['file.csc'],
+ \ 'csdl': ['file.csdl'],
+ \ 'csp': ['file.csp', 'file.fdr'],
+ \ 'css': ['file.css'],
+ \ 'cterm': ['file.con'],
+ \ 'cucumber': ['file.feature'],
+ \ 'cuda': ['file.cu'],
+ \ 'cupl': ['file.pld'],
+ \ 'cuplsim': ['file.si'],
+ \ 'cvs': ['cvs123'],
+ \ 'cvsrc': ['.cvsrc'],
+ \ 'cynpp': ['file.cyn'],
+ \ 'datascript': ['file.ds'],
+ \ 'dcd': ['file.dcd'],
+ \ 'debcontrol': ['/debian/control'],
+ \ 'debsources': ['/etc/apt/sources.list', '/etc/apt/sources.list.d/file.list'],
+ \ 'def': ['file.def'],
+ \ 'denyhosts': ['denyhosts.conf'],
+ \ 'desc': ['file.desc'],
+ \ 'desktop': ['file.desktop', '.directory'],
+ \ 'dictconf': ['dict.conf', '.dictrc'],
+ \ 'dictdconf': ['dictd.conf'],
+ \ 'diff': ['file.diff', 'file.rej'],
+ \ 'dircolors': ['.dir_colors', '.dircolors', '/etc/DIR_COLORS'],
+ \ 'dnsmasq': ['/etc/dnsmasq.conf'],
+ \ 'dockerfile': ['Dockerfile', 'file.Dockerfile'],
+ \ 'dosbatch': ['file.bat', 'file.sys'],
+ \ 'dosini': ['.editorconfig', '/etc/yum.conf', 'file.ini'],
+ \ 'dot': ['file.dot'],
+ \ 'dracula': ['file.drac', 'file.drc', 'filelvs', 'filelpe'],
+ \ 'dsl': ['file.dsl'],
+ \ 'dtd': ['file.dtd'],
+ \ 'dts': ['file.dts', 'file.dtsi'],
+ \ 'dylan': ['file.dylan'],
+ \ 'dylanintr': ['file.intr'],
+ \ 'dylanlid': ['file.lid'],
+ \ 'ecd': ['file.ecd'],
+ \ 'edif': ['file.edf', 'file.edif', 'file.edo'],
+ \ 'elinks': ['/etc/elinks.conf', '/.elinks/elinks.conf'],
+ \ 'elmfilt': ['filter-rules'],
+ \ 'erlang': ['file.erl', 'file.hrl', 'file.yaws'],
+ \ 'eruby': ['file.erb', 'file.rhtml'],
+ \ 'esmtprc': ['anyesmtprc'],
+ \ 'esqlc': ['file.ec', 'file.EC'],
+ \ 'esterel': ['file.strl'],
+ \ 'eterm': ['anyEterm/file.cfg'],
+ \ 'exim': ['exim.conf'],
+ \ 'expect': ['file.exp'],
+ \ 'exports': ['exports'],
+ \ 'factor': ['file.factor'],
+ \ 'falcon': ['file.fal'],
+ \ 'fan': ['file.fan', 'file.fwt'],
+ \ 'fetchmail': ['.fetchmailrc'],
+ \ 'fgl': ['file.4gl', 'file.4gh', 'file.m4gl'],
+ \ 'focexec': ['file.fex', 'file.focexec'],
+ \ 'forth': ['file.fs', 'file.ft', 'file.fth'],
+ \ 'fortran': ['file.f', 'file.for', 'file.fortran', 'file.fpp', 'file.ftn', 'file.f77', 'file.f90', 'file.f95', 'file.f03', 'file.f08'],
+ \ 'framescript': ['file.fsl'],
+ \ 'freebasic': ['file.fb', 'file.bi'],
+ \ 'fstab': ['fstab', 'mtab'],
+ \ 'gdb': ['.gdbinit'],
+ \ 'gdmo': ['file.mo', 'file.gdmo'],
+ \ 'gedcom': ['file.ged', 'lltxxxxx.txt'],
+ \ 'gitcommit': ['COMMIT_EDITMSG', 'MERGE_MSG', 'TAG_EDITMSG'],
+ \ 'gitconfig': ['file.git/config', '.gitconfig', '.gitmodules', 'file.git/modules//config', '/.config/git/config', '/etc/gitconfig'],
+ \ 'gitolite': ['gitolite.conf'],
+ \ 'gitrebase': ['git-rebase-todo'],
+ \ 'gitsendemail': ['.gitsendemail.msg.xxxxxx'],
+ \ 'gkrellmrc': ['gkrellmrc', 'gkrellmrc_x'],
+ \ 'gnash': ['gnashrc', '.gnashrc', 'gnashpluginrc', '.gnashpluginrc'],
+ \ 'gnuplot': ['file.gpi'],
+ \ 'go': ['file.go'],
+ \ 'gp': ['file.gp', '.gprc'],
+ \ 'gpg': ['/.gnupg/options', '/.gnupg/gpg.conf', '/usr/any/gnupg/options.skel'],
+ \ 'grads': ['file.gs'],
+ \ 'gretl': ['file.gretl'],
+ \ 'groovy': ['file.gradle', 'file.groovy'],
+ \ 'group': ['any/etc/group', 'any/etc/group-', 'any/etc/group.edit', 'any/etc/gshadow', 'any/etc/gshadow-', 'any/etc/gshadow.edit', 'any/var/backups/group.bak', 'any/var/backups/gshadow.bak'],
+ \ 'grub': ['/boot/grub/menu.lst', '/boot/grub/grub.conf', '/etc/grub.conf'],
+ \ 'gsp': ['file.gsp'],
+ \ 'gtkrc': ['.gtkrc', 'gtkrc'],
+ \ 'haml': ['file.haml'],
+ \ 'hamster': ['file.hsc', 'file.hsm'],
+ \ 'haskell': ['file.hs', 'file.hs-boot'],
+ \ 'haste': ['file.ht'],
+ \ 'hastepreproc': ['file.htpp'],
+ \ 'hb': ['file.hb'],
+ \ 'hercules': ['file.vc', 'file.ev', 'file.sum', 'file.errsum'],
+ \ 'hex': ['file.hex', 'file.h32'],
+ \ 'hgcommit': ['hg-editor-file.txt'],
+ \ 'hog': ['file.hog', 'snort.conf', 'vision.conf'],
+ \ 'hostconf': ['/etc/host.conf'],
+ \ 'hostsaccess': ['/etc/hosts.allow', '/etc/hosts.deny'],
+ \ 'htmlcheetah': ['file.tmpl'],
+ \ 'htmlm4': ['file.html.m4'],
+ \ 'httest': ['file.htt', 'file.htb'],
+ \ 'ibasic': ['file.iba', 'file.ibi'],
+ \ 'icemenu': ['/.icewm/menu'],
+ \ 'icon': ['file.icn'],
+ \ 'indent': ['.indent.pro', 'indentrc'],
+ \ 'inform': ['file.inf', 'file.INF'],
+ \ 'initng': ['/etc/initng/any/file.i', 'file.ii'],
+ \ 'inittab': ['inittab'],
+ \ 'ipfilter': ['ipf.conf', 'ipf6.conf', 'ipf.rules'],
+ \ 'iss': ['file.iss'],
+ \ 'ist': ['file.ist', 'file.mst'],
+ \ 'j': ['file.ijs'],
+ \ 'jal': ['file.jal', 'file.JAL'],
+ \ 'jam': ['file.jpl', 'file.jpr'],
+ \ 'java': ['file.java', 'file.jav'],
+ \ 'javacc': ['file.jj', 'file.jjt'],
+ \ 'javascript': ['file.js', 'file.javascript', 'file.es', 'file.jsx', 'file.mjs'],
+ \ 'jess': ['file.clp'],
+ \ 'jgraph': ['file.jgr'],
+ \ 'jovial': ['file.jov', 'file.j73', 'file.jovial'],
+ \ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx'],
+ \ 'json': ['file.json', 'file.jsonp', 'file.webmanifest'],
+ \ 'jsp': ['file.jsp'],
+ \ 'kconfig': ['Kconfig', 'Kconfig.debug'],
+ \ 'kivy': ['file.kv'],
+ \ 'kix': ['file.kix'],
+ \ 'kscript': ['file.ks'],
+ \ 'kwt': ['file.k'],
+ \ 'lace': ['file.ace', 'file.ACE'],
+ \ 'latte': ['file.latte', 'file.lte'],
+ \ 'ld': ['file.ld'],
+ \ 'ldif': ['file.ldif'],
+ \ 'less': ['file.less'],
+ \ 'lex': ['file.lex', 'file.l', 'file.lxx', 'file.l++'],
+ \ 'lftp': ['lftp.conf', '.lftprc', 'anylftp/rc'],
+ \ 'lhaskell': ['file.lhs'],
+ \ 'libao': ['/etc/libao.conf', '/.libao'],
+ \ 'lifelines': ['file.ll'],
+ \ 'lilo': ['lilo.conf'],
+ \ 'limits': ['/etc/limits', '/etc/anylimits.conf', '/etc/anylimits.d/file.conf'],
+ \ 'liquid': ['file.liquid'],
+ \ 'lisp': ['sbclrc', '.sbclrc'],
+ \ 'lite': ['file.lite', 'file.lt'],
+ \ 'litestep': ['/LiteStep/any/file.rc'],
+ \ 'loginaccess': ['/etc/login.access'],
+ \ 'logindefs': ['/etc/login.defs'],
+ \ 'logtalk': ['file.lgt'],
+ \ 'lotos': ['file.lot', 'file.lotos'],
+ \ 'lout': ['file.lou', 'file.lout'],
+ \ 'lprolog': ['file.sig'],
+ \ 'lsl': ['file.lsl'],
+ \ 'lss': ['file.lss'],
+ \ 'lua': ['file.lua', 'file.rockspec', 'file.nse'],
+ \ 'lynx': ['lynx.cfg'],
+ \ 'm4': ['file.at'],
+ \ 'mail': ['snd.123', '.letter', '.letter.123', '.followup', '.article', '.article.123', 'pico.123', 'mutt-xx-xxx', 'muttng-xx-xxx', 'ae123.txt', 'file.eml'],
+ \ 'mailaliases': ['/etc/mail/aliases', '/etc/aliases'],
+ \ 'mailcap': ['.mailcap', 'mailcap'],
+ \ 'make': ['file.mk', 'file.mak', 'file.dsp'],
+ \ 'mallard': ['file.page'],
+ \ 'manconf': ['/etc/man.conf', 'man.config'],
+ \ 'map': ['file.map'],
+ \ 'maple': ['file.mv', 'file.mpl', 'file.mws'],
+ \ 'markdown': ['file.markdown', 'file.mdown', 'file.mkd', 'file.mkdn', 'file.mdwn', 'file.md'],
+ \ 'mason': ['file.mason', 'file.mhtml', 'file.comp'],
+ \ 'master': ['file.mas', 'file.master'],
+ \ 'mel': ['file.mel'],
+ \ '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',
+ \ '/log/auth.err', '/log/cron.err', '/log/daemon.err', '/log/debug.err', '/log/kern.err', '/log/lpr.err', '/log/mail.err', '/log/messages.err', '/log/news/news.err', '/log/syslog.err', '/log/user.err',
+ \ '/log/auth.info', '/log/cron.info', '/log/daemon.info', '/log/debug.info', '/log/kern.info', '/log/lpr.info', '/log/mail.info', '/log/messages.info', '/log/news/news.info', '/log/syslog.info', '/log/user.info',
+ \ '/log/auth.warn', '/log/cron.warn', '/log/daemon.warn', '/log/debug.warn', '/log/kern.warn', '/log/lpr.warn', '/log/mail.warn', '/log/messages.warn', '/log/news/news.warn', '/log/syslog.warn', '/log/user.warn',
+ \ '/log/auth.crit', '/log/cron.crit', '/log/daemon.crit', '/log/debug.crit', '/log/kern.crit', '/log/lpr.crit', '/log/mail.crit', '/log/messages.crit', '/log/news/news.crit', '/log/syslog.crit', '/log/user.crit',
+ \ '/log/auth.notice', '/log/cron.notice', '/log/daemon.notice', '/log/debug.notice', '/log/kern.notice', '/log/lpr.notice', '/log/mail.notice', '/log/messages.notice', '/log/news/news.notice', '/log/syslog.notice', '/log/user.notice'],
+ \ 'mf': ['file.mf'],
+ \ 'mgl': ['file.mgl'],
+ \ 'mgp': ['file.mgp'],
+ \ 'mib': ['file.mib', 'file.my'],
+ \ 'mix': ['file.mix', 'file.mixal'],
+ \ 'mma': ['file.nb'],
+ \ 'mmp': ['file.mmp'],
+ \ 'modconf': ['/etc/modules.conf', '/etc/modules', '/etc/conf.modules'],
+ \ 'modula2': ['file.m2', 'file.mi'],
+ \ 'monk': ['file.isc', 'file.monk', 'file.ssc', 'file.tsc'],
+ \ 'moo': ['file.moo'],
+ \ 'mp': ['file.mp'],
+ \ 'mplayerconf': ['mplayer.conf', '/.mplayer/config'],
+ \ 'mrxvtrc': ['mrxvtrc', '.mrxvtrc'],
+ \ 'msidl': ['file.odl', 'file.mof'],
+ \ 'msql': ['file.msql'],
+ \ 'mupad': ['file.mu'],
+ \ 'mush': ['file.mush'],
+ \ 'muttrc': ['Muttngrc', 'Muttrc'],
+ \ 'mysql': ['file.mysql'],
+ \ 'n1ql': ['file.n1ql', 'file.nql'],
+ \ 'named': ['namedfile.conf', 'rndcfile.conf'],
+ \ 'nanorc': ['/etc/nanorc', 'file.nanorc'],
+ \ 'ncf': ['file.ncf'],
+ \ 'netrc': ['.netrc'],
+ \ 'ninja': ['file.ninja'],
+ \ 'nqc': ['file.nqc'],
+ \ 'nroff': ['file.tr', 'file.nr', 'file.roff', 'file.tmac', 'file.mom'],
+ \ 'nsis': ['file.nsi', 'file.nsh'],
+ \ 'obj': ['file.obj'],
+ \ 'ocaml': ['file.ml', 'file.mli', 'file.mll', 'file.mly', '.ocamlinit'],
+ \ 'occam': ['file.occ'],
+ \ 'omnimark': ['file.xom', 'file.xin'],
+ \ 'openroad': ['file.or'],
+ \ 'ora': ['file.ora'],
+ \ 'pamconf': ['/etc/pam.conf'],
+ \ 'papp': ['file.papp', 'file.pxml', 'file.pxsl'],
+ \ 'pascal': ['file.pas', 'file.dpr'],
+ \ 'passwd': ['any/etc/passwd', 'any/etc/passwd-', 'any/etc/passwd.edit', 'any/etc/shadow', 'any/etc/shadow-', 'any/etc/shadow.edit', 'any/var/backups/passwd.bak', 'any/var/backups/shadow.bak'],
+ \ 'pccts': ['file.g'],
+ \ 'pdf': ['file.pdf'],
+ \ 'perl': ['file.plx', 'file.al', 'file.psgi', 'gitolite.rc', '.gitolite.rc', 'example.gitolite.rc'],
+ \ 'perl6': ['file.p6', 'file.pm6', 'file.pl6'],
+ \ 'pf': ['pf.conf'],
+ \ 'pfmain': ['main.cf'],
+ \ 'php': ['file.php', 'file.php9', 'file.phtml', 'file.ctp'],
+ \ 'lpc': ['file.lpc', 'file.ulpc'],
+ \ 'pike': ['file.pike', 'file.pmod'],
+ \ 'cmod': ['file.cmod'],
+ \ 'pilrc': ['file.rcp'],
+ \ 'pine': ['.pinerc', 'pinerc', '.pinercex', 'pinercex'],
+ \ 'pinfo': ['/etc/pinforc', '/.pinforc'],
+ \ 'pli': ['file.pli', 'file.pl1'],
+ \ 'plm': ['file.plm', 'file.p36', 'file.pac'],
+ \ 'plp': ['file.plp'],
+ \ 'plsql': ['file.pls', 'file.plsql'],
+ \ 'po': ['file.po', 'file.pot'],
+ \ 'pod': ['file.pod'],
+ \ 'pod6': ['file.pod6'],
+ \ 'postscr': ['file.ps', 'file.pfa', 'file.afm', 'file.eps', 'file.epsf', 'file.epsi', 'file.ai'],
+ \ 'pov': ['file.pov'],
+ \ 'povini': ['.povrayrc'],
+ \ 'ppd': ['file.ppd'],
+ \ 'ppwiz': ['file.it', 'file.ih'],
+ \ 'privoxy': ['file.action'],
+ \ 'proc': ['file.pc'],
+ \ 'procmail': ['.procmail', '.procmailrc'],
+ \ 'prolog': ['file.pdb'],
+ \ 'promela': ['file.pml'],
+ \ 'proto': ['file.proto'],
+ \ 'protocols': ['/etc/protocols'],
+ \ 'psf': ['file.psf'],
+ \ 'pyrex': ['file.pyx', 'file.pxd'],
+ \ 'python': ['file.py', 'file.pyw', '.pythonstartup', '.pythonrc', 'file.ptl', 'file.pyi'],
+ \ 'quake': ['anybaseq2/file.cfg', 'anyid1/file.cfg', 'quake3/file.cfg'],
+ \ 'radiance': ['file.rad', 'file.mat'],
+ \ 'ratpoison': ['.ratpoisonrc', 'ratpoisonrc'],
+ \ 'rc': ['file.rc', 'file.rch'],
+ \ 'rcs': ['file,v'],
+ \ 'readline': ['.inputrc', 'inputrc'],
+ \ 'remind': ['.reminders', 'file.remind', 'file.rem'],
+ \ 'resolv': ['resolv.conf'],
+ \ 'reva': ['file.frt'],
+ \ 'rexx': ['file.rex', 'file.orx', 'file.rxo', 'file.rxj', 'file.jrexx', 'file.rexxj', 'file.rexx', 'file.testGroup', 'file.testUnit'],
+ \ 'rib': ['file.rib'],
+ \ 'rnc': ['file.rnc'],
+ \ 'rng': ['file.rng'],
+ \ 'robots': ['robots.txt'],
+ \ 'rpcgen': ['file.x'],
+ \ 'rpl': ['file.rpl'],
+ \ 'rst': ['file.rst'],
+ \ 'rtf': ['file.rtf'],
+ \ 'ruby': ['.irbrc', 'irbrc', 'file.rb', 'file.rbw', 'file.gemspec', 'file.ru', 'Gemfile', 'file.builder', 'file.rxml', 'file.rjs', 'file.rant', 'file.rake'],
+ \ 'rust': ['file.rs'],
+ \ 'samba': ['smb.conf'],
+ \ 'sas': ['file.sas'],
+ \ 'sass': ['file.sass'],
+ \ 'sather': ['file.sa'],
+ \ 'sbt': ['file.sbt'],
+ \ 'scala': ['file.scala'],
+ \ 'scheme': ['file.scm', 'file.ss', 'file.rkt'],
+ \ 'scilab': ['file.sci', 'file.sce'],
+ \ 'screen': ['.screenrc', 'screenrc'],
+ \ 'scss': ['file.scss'],
+ \ 'sd': ['file.sd'],
+ \ 'sdc': ['file.sdc'],
+ \ 'sdl': ['file.sdl', 'file.pr'],
+ \ 'sed': ['file.sed'],
+ \ 'sensors': ['/etc/sensors.conf', '/etc/sensors3.conf'],
+ \ 'services': ['/etc/services'],
+ \ 'setserial': ['/etc/serial.conf'],
+ \ 'sh': ['/etc/udev/cdsymlinks.conf'],
+ \ 'sieve': ['file.siv', 'file.sieve'],
+ \ 'simula': ['file.sim'],
+ \ 'sinda': ['file.sin', 'file.s85'],
+ \ 'sisu': ['file.sst', 'file.ssm', 'file.ssi', 'file.-sst', 'file._sst', 'file.sst.meta', 'file.-sst.meta', 'file._sst.meta'],
+ \ 'skill': ['file.il', 'file.ils', 'file.cdf'],
+ \ 'slang': ['file.sl'],
+ \ 'slice': ['file.ice'],
+ \ 'slpconf': ['/etc/slp.conf'],
+ \ 'slpreg': ['/etc/slp.reg'],
+ \ 'slpspi': ['/etc/slp.spi'],
+ \ 'slrnrc': ['.slrnrc'],
+ \ 'slrnsc': ['file.score'],
+ \ 'sm': ['sendmail.cf'],
+ \ 'smarty': ['file.tpl'],
+ \ 'smcl': ['file.hlp', 'file.ihlp', 'file.smcl'],
+ \ 'smith': ['file.smt', 'file.smith'],
+ \ 'sml': ['file.sml'],
+ \ 'snobol4': ['file.sno', 'file.spt'],
+ \ 'spec': ['file.spec'],
+ \ 'spice': ['file.sp', 'file.spice'],
+ \ 'spup': ['file.speedup', 'file.spdata', 'file.spd'],
+ \ 'spyce': ['file.spy', 'file.spi'],
+ \ 'sql': ['file.tyb', 'file.typ', 'file.tyc', 'file.pkb', 'file.pks'],
+ \ 'sqlj': ['file.sqlj'],
+ \ 'sqr': ['file.sqr', 'file.sqi'],
+ \ 'squid': ['squid.conf'],
+ \ 'srec': ['file.s19', 'file.s28', 'file.s37', 'file.mot', 'file.srec'],
+ \ 'sshconfig': ['ssh_config', '/.ssh/config'],
+ \ 'sshdconfig': ['sshd_config'],
+ \ 'st': ['file.st'],
+ \ 'stata': ['file.ado', 'file.do', 'file.imata', 'file.mata'],
+ \ 'stp': ['file.stp'],
+ \ 'sudoers': ['any/etc/sudoers', 'sudoers.tmp'],
+ \ 'svg': ['file.svg'],
+ \ 'svn': ['svn-commitfile.tmp'],
+ \ 'sysctl': ['/etc/sysctl.conf', '/etc/sysctl.d/file.conf'],
+ \ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.mount', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer'],
+ \ 'systemverilog': ['file.sv', 'file.svh'],
+ \ 'tags': ['tags'],
+ \ 'tak': ['file.tak'],
+ \ 'taskdata': ['pending.data', 'completed.data', 'undo.data'],
+ \ 'taskedit': ['file.task'],
+ \ 'tcl': ['file.tcl', 'file.tk', 'file.itcl', 'file.itk', 'file.jacl'],
+ \ 'teraterm': ['file.ttl'],
+ \ 'terminfo': ['file.ti'],
+ \ 'tex': ['file.latex', 'file.sty', 'file.dtx', 'file.ltx', 'file.bbl'],
+ \ 'texinfo': ['file.texinfo', 'file.texi', 'file.txi'],
+ \ 'texmf': ['texmf.cnf'],
+ \ 'text': ['file.text', 'README'],
+ \ 'tf': ['file.tf', '.tfrc', 'tfrc'],
+ \ 'tidy': ['.tidyrc', 'tidyrc'],
+ \ 'tilde': ['file.t.html'],
+ \ 'tli': ['file.tli'],
+ \ 'tmux': ['tmuxfile.conf', '.tmuxfile.conf'],
+ \ 'tpp': ['file.tpp'],
+ \ 'treetop': ['file.treetop'],
+ \ 'trustees': ['trustees.conf'],
+ \ 'tsalt': ['file.slt'],
+ \ 'tsscl': ['file.tsscl'],
+ \ 'tssgm': ['file.tssgm'],
+ \ 'tssop': ['file.tssop'],
+ \ 'twig': ['file.twig'],
+ \ 'uc': ['file.uc'],
+ \ 'udevconf': ['/etc/udev/udev.conf'],
+ \ 'udevperm': ['/etc/udev/permissions.d/file.permissions'],
+ \ 'uil': ['file.uit', 'file.uil'],
+ \ 'updatedb': ['/etc/updatedb.conf'],
+ \ 'upstart': ['/usr/share/upstart/file.conf', '/usr/share/upstart/file.override', '/etc/init/file.conf', '/etc/init/file.override', '/.init/file.conf', '/.init/file.override', '/.config/upstart/file.conf', '/.config/upstart/file.override'],
+ \ 'upstreamdat': ['upstream.dat', 'UPSTREAM.DAT', 'upstream.file.dat', 'UPSTREAM.FILE.DAT', 'file.upstream.dat', 'FILE.UPSTREAM.DAT'],
+ \ 'upstreaminstalllog': ['upstreaminstall.log', 'UPSTREAMINSTALL.LOG', 'upstreaminstall.file.log', 'UPSTREAMINSTALL.FILE.LOG', 'file.upstreaminstall.log', 'FILE.UPSTREAMINSTALL.LOG'],
+ \ 'upstreamlog': ['fdrupstream.log', 'upstream.log', 'UPSTREAM.LOG', 'upstream.file.log', 'UPSTREAM.FILE.LOG', 'file.upstream.log', 'FILE.UPSTREAM.LOG', 'UPSTREAM-file.log', 'UPSTREAM-FILE.LOG'],
+ \ 'usserverlog': ['usserver.log', 'USSERVER.LOG', 'usserver.file.log', 'USSERVER.FILE.LOG', 'file.usserver.log', 'FILE.USSERVER.LOG'],
+ \ 'usw2kagtlog': ['usw2kagt.log', 'USW2KAGT.LOG', 'usw2kagt.file.log', 'USW2KAGT.FILE.LOG', 'file.usw2kagt.log', 'FILE.USW2KAGT.LOG'],
+ \ 'vb': ['file.sba', 'file.vb', 'file.vbs', 'file.dsm', 'file.ctl'],
+ \ 'vera': ['file.vr', 'file.vri', 'file.vrh'],
+ \ 'verilog': ['file.v'],
+ \ 'verilogams': ['file.va', 'file.vams'],
+ \ 'vgrindefs': ['vgrindefs'],
+ \ 'vhdl': ['file.hdl', 'file.vhd', 'file.vhdl', 'file.vbe', 'file.vst'],
+ \ 'vim': ['file.vim', 'file.vba', '.exrc', '_exrc'],
+ \ 'viminfo': ['.viminfo', '_viminfo'],
+ \ 'vmasm': ['file.mar'],
+ \ 'voscm': ['file.cm'],
+ \ 'vrml': ['file.wrl'],
+ \ 'vroom': ['file.vroom'],
+ \ 'wast': ['file.wast', 'file.wat'],
+ \ 'webmacro': ['file.wm'],
+ \ 'wget': ['.wgetrc', 'wgetrc'],
+ \ 'winbatch': ['file.wbt'],
+ \ 'wml': ['file.wml'],
+ \ 'wsml': ['file.wsml'],
+ \ 'wvdial': ['wvdial.conf', '.wvdialrc'],
+ \ 'xdefaults': ['.Xdefaults', '.Xpdefaults', '.Xresources', 'xdm-config', 'file.ad'],
+ \ 'xhtml': ['file.xhtml', 'file.xht'],
+ \ 'xinetd': ['/etc/xinetd.conf'],
+ \ 'xmath': ['file.msc', 'file.msf'],
+ \ 'xml': ['/etc/blkid.tab', '/etc/blkid.tab.old', 'file.xmi', 'file.csproj', 'file.csproj.user', 'file.ts', 'file.ui', 'file.tpm', '/etc/xdg/menus/file.menu', 'fglrxrc', 'file.xlf', 'file.xliff', 'file.xul', 'file.wsdl'],
+ \ 'xmodmap': ['anyXmodmap'],
+ \ 'xf86conf': ['xorg.conf', 'xorg.conf-4'],
+ \ 'xpm2': ['file.xpm2'],
+ \ 'xquery': ['file.xq', 'file.xql', 'file.xqm', 'file.xquery', 'file.xqy'],
+ \ 'xs': ['file.xs'],
+ \ 'xsd': ['file.xsd'],
+ \ 'xslt': ['file.xsl', 'file.xslt'],
+ \ 'yacc': ['file.yy', 'file.yxx', 'file.y++'],
+ \ 'yaml': ['file.yaml', 'file.yml'],
+ \ 'raml': ['file.raml'],
+ \ 'z8a': ['file.z8a'],
+ \ 'zimbu': ['file.zu'],
+ \ 'zimbutempl': ['file.zut'],
+ \ 'zsh': ['.zprofile', '/etc/zprofile', '.zfbfmarks', 'file.zsh'],
+ \
+ \ 'aap': ['file.aap'],
+ \ 'help': [$VIMRUNTIME . '/doc/help.txt'],
+ \ 'xpm': ['file.xpm'],
+ \ }
+
+let s:filename_case_checks = {
+ \ 'modula2': ['file.DEF', 'file.MOD'],
+ \ }
+
+func CheckItems(checks)
+ for [ft, names] in items(a:checks)
+ for i in range(0, len(names) - 1)
+ new
+ try
+ exe 'edit ' . names[i]
+ catch
+ call assert_report('cannot edit "' . names[i] . '": ' . v:errmsg)
+ endtry
+ call assert_equal(ft, &filetype, 'with file name: ' . names[i])
+ bwipe!
+ endfor
+ endfor
+endfunc
+
+func Test_filetype_detection()
+ filetype on
+ call CheckItems(s:filename_checks)
+ if has('fname_case')
+ call CheckItems(s:filename_case_checks)
+ endif
+ filetype off
+endfunc
+
+" Filetypes detected from the file contents by scripts.vim
+let s:script_checks = {
+ \ 'virata': [['% Virata'],
+ \ ['', '% Virata'],
+ \ ['', '', '% Virata'],
+ \ ['', '', '', '% Virata'],
+ \ ['', '', '', '', '% Virata']],
+ \ 'strace': [['execve("/usr/bin/pstree", ["pstree"], 0x7ff0 /* 63 vars */) = 0'],
+ \ ['15:17:47 execve("/usr/bin/pstree", ["pstree"], ... "_=/usr/bin/strace"]) = 0'],
+ \ ['__libc_start_main and something']],
+ \ 'clojure': [['#!/path/clojure']],
+ \ 'scala': [['#!/path/scala']],
+ \ 'tcsh': [['#!/path/tcsh']],
+ \ 'zsh': [['#!/path/zsh']],
+ \ 'tcl': [['#!/path/tclsh'],
+ \ ['#!/path/wish'],
+ \ ['#!/path/expectk'],
+ \ ['#!/path/itclsh'],
+ \ ['#!/path/itkwish']],
+ \ 'expect': [['#!/path/expect']],
+ \ 'gnuplot': [['#!/path/gnuplot']],
+ \ 'make': [['#!/path/make']],
+ \ 'pike': [['#!/path/pike'],
+ \ ['#!/path/pike0'],
+ \ ['#!/path/pike9']],
+ \ 'lua': [['#!/path/lua']],
+ \ 'perl6': [['#!/path/perl6']],
+ \ 'perl': [['#!/path/perl']],
+ \ 'php': [['#!/path/php']],
+ \ 'python': [['#!/path/python'],
+ \ ['#!/path/python2'],
+ \ ['#!/path/python3']],
+ \ 'groovy': [['#!/path/groovy']],
+ \ 'ruby': [['#!/path/ruby']],
+ \ 'javascript': [['#!/path/node'],
+ \ ['#!/path/js'],
+ \ ['#!/path/nodejs'],
+ \ ['#!/path/rhino']],
+ \ 'bc': [['#!/path/bc']],
+ \ 'sed': [['#!/path/sed']],
+ \ 'ocaml': [['#!/path/ocaml']],
+ \ 'awk': [['#!/path/awk']],
+ \ 'wml': [['#!/path/wml']],
+ \ 'scheme': [['#!/path/scheme']],
+ \ 'cfengine': [['#!/path/cfengine']],
+ \ 'erlang': [['#!/path/escript']],
+ \ 'haskell': [['#!/path/haskell']],
+ \ }
+
+func Test_script_detection()
+ filetype on
+ for [ft, files] in items(s:script_checks)
+ for file in files
+ call writefile(file, 'Xtest')
+ split Xtest
+ call assert_equal(ft, &filetype, 'for text: ' . string(file))
+ bwipe!
+ endfor
+ endfor
+ call delete('Xtest')
+ filetype off
+endfunc
+
+func Test_setfiletype_completion()
+ call feedkeys(":setfiletype java\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"setfiletype java javacc javascript', @:)
+endfunc
diff --git a/src/nvim/testdir/test_filter_cmd.vim b/src/nvim/testdir/test_filter_cmd.vim
new file mode 100644
index 0000000000..86347ab77f
--- /dev/null
+++ b/src/nvim/testdir/test_filter_cmd.vim
@@ -0,0 +1,89 @@
+" Test the :filter command modifier
+
+func Test_filter()
+ edit Xdoesnotmatch
+ edit Xwillmatch
+ call assert_equal('"Xwillmatch"', substitute(execute('filter willma ls'), '[^"]*\(".*"\)[^"]*', '\1', ''))
+ bwipe Xdoesnotmatch
+ bwipe Xwillmatch
+
+ new
+ call setline(1, ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'])
+ call assert_equal("\nfoo2\nfoo4", execute('filter /foo[24]/ 1,$print'))
+ call assert_equal("\n 2 foo2\n 4 foo4", execute('filter /foo[24]/ 1,$number'))
+ call assert_equal("\nfoo2$\nfoo4$", execute('filter /foo[24]/ 1,$list'))
+
+ call assert_equal("\nfoo1$\nfoo3$\nfoo5$", execute('filter! /foo[24]/ 1,$list'))
+ bwipe!
+
+ command XTryThis echo 'this'
+ command XTryThat echo 'that'
+ command XDoThat echo 'that'
+ let lines = split(execute('filter XTry command'), "\n")
+ call assert_equal(3, len(lines))
+ call assert_match("XTryThat", lines[1])
+ call assert_match("XTryThis", lines[2])
+ delcommand XTryThis
+ delcommand XTryThat
+ delcommand XDoThat
+
+ map f1 the first key
+ map f2 the second key
+ map f3 not a key
+ let lines = split(execute('filter the map f'), "\n")
+ call assert_equal(2, len(lines))
+ call assert_match("f2", lines[0])
+ call assert_match("f1", lines[1])
+ unmap f1
+ unmap f2
+ unmap f3
+endfunc
+
+func Test_filter_fails()
+ call assert_fails('filter', 'E471:')
+ call assert_fails('filter pat', 'E476:')
+ call assert_fails('filter /pat', 'E476:')
+ call assert_fails('filter /pat/', 'E476:')
+ call assert_fails('filter /pat/ asdf', 'E492:')
+
+ call assert_fails('filter!', 'E471:')
+ call assert_fails('filter! pat', 'E476:')
+ call assert_fails('filter! /pat', 'E476:')
+ call assert_fails('filter! /pat/', 'E476:')
+ call assert_fails('filter! /pat/ asdf', 'E492:')
+endfunc
+
+function s:complete_filter_cmd(filtcmd)
+ let keystroke = "\<TAB>\<C-R>=execute('let cmdline = getcmdline()')\<CR>\<C-C>"
+ let cmdline = ''
+ call feedkeys(':' . a:filtcmd . keystroke, 'ntx')
+ return cmdline
+endfunction
+
+func Test_filter_cmd_completion()
+ " Do not complete pattern
+ call assert_equal("filter \t", s:complete_filter_cmd('filter '))
+ call assert_equal("filter pat\t", s:complete_filter_cmd('filter pat'))
+ call assert_equal("filter /pat\t", s:complete_filter_cmd('filter /pat'))
+ call assert_equal("filter /pat/\t", s:complete_filter_cmd('filter /pat/'))
+
+ " Complete after string pattern
+ call assert_equal('filter pat print', s:complete_filter_cmd('filter pat pri'))
+
+ " Complete after regexp pattern
+ call assert_equal('filter /pat/ print', s:complete_filter_cmd('filter /pat/ pri'))
+ call assert_equal('filter #pat# print', s:complete_filter_cmd('filter #pat# pri'))
+endfunc
+
+func Test_filter_cmd_with_filter()
+ new
+ set shelltemp
+ %!echo "a|b"
+ let out = getline(1)
+ bw!
+ if has('win32')
+ let out = trim(out, '" ')
+ endif
+ call assert_equal('a|b', out)
+ set shelltemp&
+endfunction
diff --git a/src/nvim/testdir/test_filter_map.vim b/src/nvim/testdir/test_filter_map.vim
new file mode 100644
index 0000000000..c8d64ce0a4
--- /dev/null
+++ b/src/nvim/testdir/test_filter_map.vim
@@ -0,0 +1,81 @@
+" Test filter() and map()
+
+" list with expression string
+func Test_filter_map_list_expr_string()
+ " filter()
+ call assert_equal([2, 3, 4], filter([1, 2, 3, 4], 'v:val > 1'))
+ call assert_equal([3, 4], filter([1, 2, 3, 4], 'v:key > 1'))
+ call assert_equal([], filter([1, 2, 3, 4], 0))
+
+ " map()
+ call assert_equal([2, 4, 6, 8], map([1, 2, 3, 4], 'v:val * 2'))
+ call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], 'v:key * 2'))
+ call assert_equal([9, 9, 9, 9], map([1, 2, 3, 4], 9))
+endfunc
+
+" dict with expression string
+func Test_filter_map_dict_expr_string()
+ let dict = {"foo": 1, "bar": 2, "baz": 3}
+
+ " filter()
+ call assert_equal({"bar": 2, "baz": 3}, filter(copy(dict), 'v:val > 1'))
+ call assert_equal({"foo": 1, "baz": 3}, filter(copy(dict), 'v:key > "bar"'))
+ call assert_equal({}, filter(copy(dict), 0))
+
+ " map()
+ call assert_equal({"foo": 2, "bar": 4, "baz": 6}, map(copy(dict), 'v:val * 2'))
+ call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), 'v:key[0]'))
+ call assert_equal({"foo": 9, "bar": 9, "baz": 9}, map(copy(dict), 9))
+endfunc
+
+" list with funcref
+func Test_filter_map_list_expr_funcref()
+ " filter()
+ func! s:filter1(index, val) abort
+ return a:val > 1
+ endfunc
+ call assert_equal([2, 3, 4], filter([1, 2, 3, 4], function('s:filter1')))
+
+ func! s:filter2(index, val) abort
+ return a:index > 1
+ endfunc
+ call assert_equal([3, 4], filter([1, 2, 3, 4], function('s:filter2')))
+
+ " map()
+ func! s:filter3(index, val) abort
+ return a:val * 2
+ endfunc
+ call assert_equal([2, 4, 6, 8], map([1, 2, 3, 4], function('s:filter3')))
+
+ func! s:filter4(index, val) abort
+ return a:index * 2
+ endfunc
+ call assert_equal([0, 2, 4, 6], map([1, 2, 3, 4], function('s:filter4')))
+endfunc
+
+" dict with funcref
+func Test_filter_map_dict_expr_funcref()
+ let dict = {"foo": 1, "bar": 2, "baz": 3}
+
+ " filter()
+ func! s:filter1(key, val) abort
+ return a:val > 1
+ endfunc
+ call assert_equal({"bar": 2, "baz": 3}, filter(copy(dict), function('s:filter1')))
+
+ func! s:filter2(key, val) abort
+ return a:key > "bar"
+ endfunc
+ call assert_equal({"foo": 1, "baz": 3}, filter(copy(dict), function('s:filter2')))
+
+ " map()
+ func! s:filter3(key, val) abort
+ return a:val * 2
+ endfunc
+ call assert_equal({"foo": 2, "bar": 4, "baz": 6}, map(copy(dict), function('s:filter3')))
+
+ func! s:filter4(key, val) abort
+ return a:key[0]
+ endfunc
+ call assert_equal({"foo": "f", "bar": "b", "baz": "b"}, map(copy(dict), function('s:filter4')))
+endfunc
diff --git a/src/nvim/testdir/test_find_complete.vim b/src/nvim/testdir/test_find_complete.vim
new file mode 100644
index 0000000000..7592b16192
--- /dev/null
+++ b/src/nvim/testdir/test_find_complete.vim
@@ -0,0 +1,166 @@
+" Tests for the 'find' command completion.
+
+" Do all the tests in a separate window to avoid E211 when we recursively
+" delete the Xfind directory during cleanup
+func Test_find_complete()
+ let shellslash = &shellslash
+ set shellslash
+ set belloff=all
+
+ " On windows a stale "Xfind" directory may exist, remove it so that
+ " we start from a clean state.
+ call delete("Xfind", "rf")
+ let cwd = getcwd()
+ let test_out = cwd . '/test.out'
+ call mkdir('Xfind')
+ cd Xfind
+
+ new
+ set path=
+ call assert_fails('call feedkeys(":find\t\n", "xt")', 'E345:')
+ close
+
+ new
+ set path=.
+ call assert_fails('call feedkeys(":find\t\n", "xt")', 'E32:')
+ close
+
+ new
+ set path=.,,
+ call assert_fails('call feedkeys(":find\t\n", "xt")', 'E32:')
+ close
+
+ new
+ set path=./**
+ call assert_fails('call feedkeys(":find\t\n", "xt")', 'E32:')
+ close
+
+ " We shouldn't find any file till this point
+
+ call mkdir('in/path', 'p')
+ exe 'cd ' . cwd
+ call writefile(['Holy Grail'], 'Xfind/file.txt')
+ call writefile(['Jimmy Hoffa'], 'Xfind/in/file.txt')
+ call writefile(['Another Holy Grail'], 'Xfind/in/stuff.txt')
+ call writefile(['E.T.'], 'Xfind/in/path/file.txt')
+
+ new
+ set path=Xfind/**
+ call feedkeys(":find file\t\n", "xt")
+ call assert_equal('Holy Grail', getline(1))
+ call feedkeys(":find file\t\t\n", "xt")
+ call assert_equal('Jimmy Hoffa', getline(1))
+ call feedkeys(":find file\t\t\t\n", "xt")
+ call assert_equal('E.T.', getline(1))
+
+ " Rerun the previous three find completions, using fullpath in 'path'
+ exec "set path=" . cwd . "/Xfind/**"
+
+ call feedkeys(":find file\t\n", "xt")
+ call assert_equal('Holy Grail', getline(1))
+ call feedkeys(":find file\t\t\n", "xt")
+ call assert_equal('Jimmy Hoffa', getline(1))
+ call feedkeys(":find file\t\t\t\n", "xt")
+ call assert_equal('E.T.', getline(1))
+
+ " Same steps again, using relative and fullpath items that point to the same
+ " recursive location.
+ " This is to test that there are no duplicates in the completion list.
+ set path+=Xfind/**
+ call feedkeys(":find file\t\n", "xt")
+ call assert_equal('Holy Grail', getline(1))
+ call feedkeys(":find file\t\t\n", "xt")
+ call assert_equal('Jimmy Hoffa', getline(1))
+ call feedkeys(":find file\t\t\t\n", "xt")
+ call assert_equal('E.T.', getline(1))
+ call feedkeys(":find file\t\t\n", "xt")
+
+ " Test find completion for directory of current buffer, which at this point
+ " is Xfind/in/file.txt.
+ set path=.
+ call feedkeys(":find st\t\n", "xt")
+ call assert_equal('Another Holy Grail', getline(1))
+
+ " Test find completion for empty path item ",," which is the current
+ " directory
+ cd Xfind
+ set path=,,
+ call feedkeys(":find f\t\n", "xt")
+ call assert_equal('Holy Grail', getline(1))
+
+ " Test that find completion on directory appends a slash
+ call feedkeys(":find in/pa\tfile.txt\n", "xt")
+ call assert_equal('E.T.', getline(1))
+ call feedkeys(":find ./i\tstuff.txt\n", "xt")
+ call assert_equal('Another Holy Grail', getline(1))
+
+ " Test shortening of
+ "
+ " foo/x/bar/voyager.txt
+ " foo/y/bar/voyager.txt
+ "
+ " When current directory is above foo/ they should be shortened to (in order
+ " of appearance):
+ "
+ " x/bar/voyager.txt
+ " y/bar/voyager.txt
+ call mkdir('foo/x/bar', 'p')
+ call mkdir('foo/y/bar', 'p')
+ call writefile(['Voyager 1'], 'foo/x/bar/voyager.txt')
+ call writefile(['Voyager 2'], 'foo/y/bar/voyager.txt')
+
+ exec "set path=" . cwd . "/Xfind/**"
+ call feedkeys(":find voyager\t\n", "xt")
+ call assert_equal('Voyager 1', getline(1))
+ call feedkeys(":find voyager\t\t\n", "xt")
+ call assert_equal('Voyager 2', getline(1))
+
+ "
+ " When current directory is .../foo/y/bar they should be shortened to (in
+ " order of appearance):
+ "
+ " ./voyager.txt
+ " x/bar/voyager.txt
+ cd foo/y/bar
+ call feedkeys(":find voyager\t\n", "xt")
+ call assert_equal('Voyager 2', getline(1))
+ call feedkeys(":find voyager\t\t\n", "xt")
+ call assert_equal('Voyager 1', getline(1))
+
+ " Check the opposite too:
+ cd ../../x/bar
+ call feedkeys(":find voyager\t\n", "xt")
+ call assert_equal('Voyager 1', getline(1))
+ call feedkeys(":find voyager\t\t\n", "xt")
+ call assert_equal('Voyager 2', getline(1))
+
+ " Check for correct handling of shorten_fname()'s behavior on windows
+ exec "cd " . cwd . "/Xfind/in"
+ call feedkeys(":find file\t\n", "xt")
+ call assert_equal('Jimmy Hoffa', getline(1))
+
+ " Test for relative to current buffer 'path' item
+ exec "cd " . cwd . "/Xfind/"
+ set path=./path
+ " Open the file where Jimmy Hoffa is found
+ e in/file.txt
+ " Find the file containing 'E.T.' in the Xfind/in/path directory
+ call feedkeys(":find file\t\n", "xt")
+ call assert_equal('E.T.', getline(1))
+
+ " Test that completion works when path=.,,
+ set path=.,,
+ " Open Jimmy Hoffa file
+ e in/file.txt
+ call assert_equal('Jimmy Hoffa', getline(1))
+
+ " Search for the file containing Holy Grail in same directory as in/path.txt
+ call feedkeys(":find stu\t\n", "xt")
+ call assert_equal('Another Holy Grail', getline(1))
+
+ enew | only
+ exe 'cd ' . cwd
+ call delete('Xfind', 'rf')
+ set path&
+ let &shellslash = shellslash
+endfunc
diff --git a/src/nvim/testdir/test_findfile.vim b/src/nvim/testdir/test_findfile.vim
new file mode 100644
index 0000000000..d9a89801ea
--- /dev/null
+++ b/src/nvim/testdir/test_findfile.vim
@@ -0,0 +1,25 @@
+" Test for findfile()
+"
+func Test_findfile()
+ new
+ let cwd=getcwd()
+ cd ..
+
+ " Tests may be run from a shadow directory, so an extra cd needs to be done to
+ " get above src/
+ if fnamemodify(getcwd(), ':t') != 'src'
+ cd ../..
+ else
+ cd ..
+ endif
+ set ssl
+
+ call assert_equal('src/nvim/testdir/test_findfile.vim', findfile('test_findfile.vim','src/nvim/test*'))
+ exe "cd" cwd
+ cd ..
+ call assert_equal('testdir/test_findfile.vim', findfile('test_findfile.vim','test*'))
+ call assert_equal('testdir/test_findfile.vim', findfile('test_findfile.vim','testdir'))
+
+ exe "cd" cwd
+ q!
+endfunc
diff --git a/src/nvim/testdir/test_fixeol.vim b/src/nvim/testdir/test_fixeol.vim
new file mode 100644
index 0000000000..32cb059e26
--- /dev/null
+++ b/src/nvim/testdir/test_fixeol.vim
@@ -0,0 +1,48 @@
+" Tests for 'fixeol' and 'eol'
+func Test_fixeol()
+ " first write two test files – with and without trailing EOL
+ " use Unix fileformat for consistency
+ set ff=unix
+ enew!
+ call setline('.', 'with eol')
+ w! XXEol
+ enew!
+ set noeol nofixeol
+ call setline('.', 'without eol')
+ w! XXNoEol
+ set eol fixeol
+ bwipe XXEol XXNoEol
+
+ " try editing files with 'fixeol' disabled
+ e! XXEol
+ normal ostays eol
+ set nofixeol
+ w! XXTestEol
+ e! XXNoEol
+ normal ostays without
+ set nofixeol
+ w! XXTestNoEol
+ bwipe! XXEol XXNoEol XXTestEol XXTestNoEol
+ set fixeol
+
+ " Append "END" to each file so that we can see what the last written char
+ " was.
+ normal ggdGaEND
+ w >>XXEol
+ w >>XXNoEol
+ w >>XXTestEol
+ w >>XXTestNoEol
+
+ call assert_equal(['with eol', 'END'], readfile('XXEol'))
+ call assert_equal(['without eolEND'], readfile('XXNoEol'))
+ call assert_equal(['with eol', 'stays eol', 'END'], readfile('XXTestEol'))
+ call assert_equal(['without eol', 'stays withoutEND'],
+ \ readfile('XXTestNoEol'))
+
+ call delete('XXEol')
+ call delete('XXNoEol')
+ call delete('XXTestEol')
+ call delete('XXTestNoEol')
+ set ff& fixeol& eol&
+ enew!
+endfunc
diff --git a/src/nvim/testdir/test_float_func.vim b/src/nvim/testdir/test_float_func.vim
new file mode 100644
index 0000000000..5ea5192994
--- /dev/null
+++ b/src/nvim/testdir/test_float_func.vim
@@ -0,0 +1,332 @@
+" test float functions
+
+if !has('float')
+ finish
+end
+
+func Test_abs()
+ call assert_equal('1.23', string(abs(1.23)))
+ call assert_equal('1.23', string(abs(-1.23)))
+ call assert_equal('0.0', string(abs(0.0)))
+ call assert_equal('0.0', string(abs(1.0/(1.0/0.0))))
+ call assert_equal('0.0', string(abs(-1.0/(1.0/0.0))))
+ call assert_equal("str2float('inf')", string(abs(1.0/0.0)))
+ call assert_equal("str2float('inf')", string(abs(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(abs(0.0/0.0)))
+ call assert_equal('12', string(abs('-12abc')))
+ call assert_fails("call abs([])", 'E745:')
+ call assert_fails("call abs({})", 'E728:')
+ call assert_fails("call abs(function('string'))", 'E703:')
+endfunc
+
+func Test_sqrt()
+ call assert_equal('0.0', string(sqrt(0.0)))
+ call assert_equal('1.414214', string(sqrt(2.0)))
+ call assert_equal("str2float('inf')", string(sqrt(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(sqrt(-1.0)))
+ call assert_equal("str2float('nan')", string(sqrt(0.0/0.0)))
+ call assert_fails('call sqrt("")', 'E808:')
+endfunc
+
+func Test_log()
+ call assert_equal('0.0', string(log(1.0)))
+ call assert_equal('-0.693147', string(log(0.5)))
+ call assert_equal("-str2float('inf')", string(log(0.0)))
+ call assert_equal("str2float('nan')", string(log(-1.0)))
+ call assert_equal("str2float('inf')", string(log(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(log(0.0/0.0)))
+ call assert_fails('call log("")', 'E808:')
+endfunc
+
+func Test_log10()
+ call assert_equal('0.0', string(log10(1.0)))
+ call assert_equal('2.0', string(log10(100.0)))
+ call assert_equal('2.079181', string(log10(120.0)))
+ call assert_equal("-str2float('inf')", string(log10(0.0)))
+ call assert_equal("str2float('nan')", string(log10(-1.0)))
+ call assert_equal("str2float('inf')", string(log10(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(log10(0.0/0.0)))
+ call assert_fails('call log10("")', 'E808:')
+endfunc
+
+func Test_exp()
+ call assert_equal('1.0', string(exp(0.0)))
+ call assert_equal('7.389056', string(exp(2.0)))
+ call assert_equal('0.367879', string(exp(-1.0)))
+ call assert_equal("str2float('inf')", string(exp(1.0/0.0)))
+ call assert_equal('0.0', string(exp(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(exp(0.0/0.0)))
+ call assert_fails('call exp("")', 'E808:')
+endfunc
+
+func Test_sin()
+ call assert_equal('0.0', string(sin(0.0)))
+ call assert_equal('0.841471', string(sin(1.0)))
+ call assert_equal('-0.479426', string(sin(-0.5)))
+ call assert_equal("str2float('nan')", string(sin(0.0/0.0)))
+ call assert_equal("str2float('nan')", string(sin(1.0/0.0)))
+ call assert_equal('0.0', string(sin(1.0/(1.0/0.0))))
+ call assert_equal('-0.0', string(sin(-1.0/(1.0/0.0))))
+ call assert_fails('call sin("")', 'E808:')
+endfunc
+
+func Test_asin()
+ call assert_equal('0.0', string(asin(0.0)))
+ call assert_equal('1.570796', string(asin(1.0)))
+ call assert_equal('-0.523599', string(asin(-0.5)))
+ call assert_equal("str2float('nan')", string(asin(1.1)))
+ call assert_equal("str2float('nan')", string(asin(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(asin(0.0/0.0)))
+ call assert_fails('call asin("")', 'E808:')
+endfunc
+
+func Test_sinh()
+ call assert_equal('0.0', string(sinh(0.0)))
+ call assert_equal('0.521095', string(sinh(0.5)))
+ call assert_equal('-1.026517', string(sinh(-0.9)))
+ call assert_equal("str2float('inf')", string(sinh(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(sinh(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(sinh(0.0/0.0)))
+ call assert_fails('call sinh("")', 'E808:')
+endfunc
+
+func Test_cos()
+ call assert_equal('1.0', string(cos(0.0)))
+ call assert_equal('0.540302', string(cos(1.0)))
+ call assert_equal('0.877583', string(cos(-0.5)))
+ call assert_equal("str2float('nan')", string(cos(0.0/0.0)))
+ call assert_equal("str2float('nan')", string(cos(1.0/0.0)))
+ call assert_fails('call cos("")', 'E808:')
+endfunc
+
+func Test_acos()
+ call assert_equal('1.570796', string(acos(0.0)))
+ call assert_equal('0.0', string(acos(1.0)))
+ call assert_equal('3.141593', string(acos(-1.0)))
+ call assert_equal('2.094395', string(acos(-0.5)))
+ call assert_equal("str2float('nan')", string(acos(1.1)))
+ call assert_equal("str2float('nan')", string(acos(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(acos(0.0/0.0)))
+ call assert_fails('call acos("")', 'E808:')
+endfunc
+
+func Test_cosh()
+ call assert_equal('1.0', string(cosh(0.0)))
+ call assert_equal('1.127626', string(cosh(0.5)))
+ call assert_equal("str2float('inf')", string(cosh(1.0/0.0)))
+ call assert_equal("str2float('inf')", string(cosh(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(cosh(0.0/0.0)))
+ call assert_fails('call cosh("")', 'E808:')
+endfunc
+
+func Test_tan()
+ call assert_equal('0.0', string(tan(0.0)))
+ call assert_equal('0.546302', string(tan(0.5)))
+ call assert_equal('-0.546302', string(tan(-0.5)))
+ call assert_equal("str2float('nan')", string(tan(1.0/0.0)))
+ call assert_equal("str2float('nan')", string(cos(0.0/0.0)))
+ call assert_equal('0.0', string(tan(1.0/(1.0/0.0))))
+ call assert_equal('-0.0', string(tan(-1.0/(1.0/0.0))))
+ call assert_fails('call tan("")', 'E808:')
+endfunc
+
+func Test_atan()
+ call assert_equal('0.0', string(atan(0.0)))
+ call assert_equal('0.463648', string(atan(0.5)))
+ call assert_equal('-0.785398', string(atan(-1.0)))
+ call assert_equal('1.570796', string(atan(1.0/0.0)))
+ call assert_equal('-1.570796', string(atan(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(atan(0.0/0.0)))
+ call assert_fails('call atan("")', 'E808:')
+endfunc
+
+func Test_atan2()
+ call assert_equal('-2.356194', string(atan2(-1, -1)))
+ call assert_equal('2.356194', string(atan2(1, -1)))
+ call assert_equal('0.0', string(atan2(1.0, 1.0/0.0)))
+ call assert_equal('1.570796', string(atan2(1.0/0.0, 1.0)))
+ call assert_equal("str2float('nan')", string(atan2(0.0/0.0, 1.0)))
+ call assert_fails('call atan2("", -1)', 'E808:')
+ call assert_fails('call atan2(-1, "")', 'E808:')
+endfunc
+
+func Test_tanh()
+ call assert_equal('0.0', string(tanh(0.0)))
+ call assert_equal('0.462117', string(tanh(0.5)))
+ call assert_equal('-0.761594', string(tanh(-1.0)))
+ call assert_equal('1.0', string(tanh(1.0/0.0)))
+ call assert_equal('-1.0', string(tanh(-1.0/0.0)))
+ call assert_equal("str2float('nan')", string(tanh(0.0/0.0)))
+ call assert_fails('call tanh("")', 'E808:')
+endfunc
+
+func Test_fmod()
+ call assert_equal('0.13', string(fmod(12.33, 1.22)))
+ call assert_equal('-0.13', string(fmod(-12.33, 1.22)))
+ call assert_equal("str2float('nan')", string(fmod(1.0/0.0, 1.0)))
+ " On Windows we get "nan" instead of 1.0, accept both.
+ let res = string(fmod(1.0, 1.0/0.0))
+ if res != "str2float('nan')"
+ call assert_equal('1.0', res)
+ endif
+ call assert_equal("str2float('nan')", string(fmod(1.0, 0.0)))
+ call assert_fails("call fmod('', 1.22)", 'E808:')
+ call assert_fails("call fmod(12.33, '')", 'E808:')
+endfunc
+
+func Test_pow()
+ call assert_equal('1.0', string(pow(0.0, 0.0)))
+ call assert_equal('8.0', string(pow(2.0, 3.0)))
+ call assert_equal("str2float('nan')", string(pow(2.0, 0.0/0.0)))
+ call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0)))
+ call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0)))
+ call assert_equal("str2float('inf')", string(pow(2.0, 1.0/0.0)))
+ call assert_equal("str2float('inf')", string(pow(1.0/0.0, 3.0)))
+ call assert_fails("call pow('', 2.0)", 'E808:')
+ call assert_fails("call pow(2.0, '')", 'E808:')
+endfunc
+
+func Test_str2float()
+ call assert_equal('1.0', string(str2float('1')))
+ call assert_equal('1.0', string(str2float(' 1 ')))
+ call assert_equal('1.0', string(str2float(' 1.0 ')))
+ call assert_equal('1.23', string(str2float('1.23')))
+ call assert_equal('1.23', string(str2float('1.23abc')))
+ call assert_equal('1.0e40', string(str2float('1e40')))
+ call assert_equal('-1.23', string(str2float('-1.23')))
+ call assert_equal('1.23', string(str2float(' + 1.23 ')))
+
+ call assert_equal('1.0', string(str2float('+1')))
+ call assert_equal('1.0', string(str2float('+1')))
+ call assert_equal('1.0', string(str2float(' +1 ')))
+ call assert_equal('1.0', string(str2float(' + 1 ')))
+
+ call assert_equal('-1.0', string(str2float('-1')))
+ call assert_equal('-1.0', string(str2float('-1')))
+ call assert_equal('-1.0', string(str2float(' -1 ')))
+ call assert_equal('-1.0', string(str2float(' - 1 ')))
+
+ call assert_equal('0.0', string(str2float('+0.0')))
+ call assert_equal('-0.0', string(str2float('-0.0')))
+ call assert_equal("str2float('inf')", string(str2float('1e1000')))
+ call assert_equal("str2float('inf')", string(str2float('inf')))
+ call assert_equal("-str2float('inf')", string(str2float('-inf')))
+ call assert_equal("str2float('inf')", string(str2float('+inf')))
+ call assert_equal("str2float('inf')", string(str2float('Inf')))
+ call assert_equal("str2float('inf')", string(str2float(' +inf ')))
+ call assert_equal("str2float('nan')", string(str2float('nan')))
+ call assert_equal("str2float('nan')", string(str2float('NaN')))
+ call assert_equal("str2float('nan')", string(str2float(' nan ')))
+
+ call assert_fails("call str2float(1.2)", 'E806:')
+ call assert_fails("call str2float([])", 'E730:')
+ call assert_fails("call str2float({})", 'E731:')
+ call assert_fails("call str2float(function('string'))", 'E729:')
+endfunc
+
+func Test_float2nr()
+ call assert_equal(1, float2nr(1.234))
+ call assert_equal(123, float2nr(1.234e2))
+ call assert_equal(12, float2nr(123.4e-1))
+ let max_number = 1/0
+ let min_number = -max_number
+ call assert_equal(max_number/2+1, float2nr(pow(2, 62)))
+ call assert_equal(max_number, float2nr(pow(2, 63)))
+ call assert_equal(max_number, float2nr(pow(2, 64)))
+ call assert_equal(min_number/2-1, float2nr(-pow(2, 62)))
+ call assert_equal(min_number, float2nr(-pow(2, 63)))
+ call assert_equal(min_number, float2nr(-pow(2, 64)))
+endfunc
+
+func Test_floor()
+ call assert_equal('2.0', string(floor(2.0)))
+ call assert_equal('2.0', string(floor(2.11)))
+ call assert_equal('2.0', string(floor(2.99)))
+ call assert_equal('-3.0', string(floor(-2.11)))
+ call assert_equal('-3.0', string(floor(-2.99)))
+ call assert_equal("str2float('nan')", string(floor(0.0/0.0)))
+ call assert_equal("str2float('inf')", string(floor(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(floor(-1.0/0.0)))
+ call assert_fails("call floor('')", 'E808:')
+endfunc
+
+func Test_ceil()
+ call assert_equal('2.0', string(ceil(2.0)))
+ call assert_equal('3.0', string(ceil(2.11)))
+ call assert_equal('3.0', string(ceil(2.99)))
+ call assert_equal('-2.0', string(ceil(-2.11)))
+ call assert_equal('-2.0', string(ceil(-2.99)))
+ call assert_equal("str2float('nan')", string(ceil(0.0/0.0)))
+ call assert_equal("str2float('inf')", string(ceil(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(ceil(-1.0/0.0)))
+ call assert_fails("call ceil('')", 'E808:')
+endfunc
+
+func Test_round()
+ call assert_equal('2.0', string(round(2.1)))
+ call assert_equal('3.0', string(round(2.5)))
+ call assert_equal('3.0', string(round(2.9)))
+ call assert_equal('-2.0', string(round(-2.1)))
+ call assert_equal('-3.0', string(round(-2.5)))
+ call assert_equal('-3.0', string(round(-2.9)))
+ call assert_equal("str2float('nan')", string(round(0.0/0.0)))
+ call assert_equal("str2float('inf')", string(round(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(round(-1.0/0.0)))
+ call assert_fails("call round('')", 'E808:')
+endfunc
+
+func Test_trunc()
+ call assert_equal('2.0', string(trunc(2.1)))
+ call assert_equal('2.0', string(trunc(2.5)))
+ call assert_equal('2.0', string(trunc(2.9)))
+ call assert_equal('-2.0', string(trunc(-2.1)))
+ call assert_equal('-2.0', string(trunc(-2.5)))
+ call assert_equal('-2.0', string(trunc(-2.9)))
+ call assert_equal("str2float('nan')", string(trunc(0.0/0.0)))
+ call assert_equal("str2float('inf')", string(trunc(1.0/0.0)))
+ call assert_equal("-str2float('inf')", string(trunc(-1.0/0.0)))
+ call assert_fails("call trunc('')", 'E808:')
+endfunc
+
+func Test_isnan()
+ throw 'skipped: Nvim does not support isnan()'
+ call assert_equal(0, isnan(1.0))
+ call assert_equal(1, isnan(0.0/0.0))
+ call assert_equal(0, isnan(1.0/0.0))
+ call assert_equal(0, isnan('a'))
+ call assert_equal(0, isnan([]))
+ call assert_equal(0, isnan({}))
+endfunc
+
+" This was converted from test65
+func Test_float_misc()
+ call assert_equal('123.456000', printf('%f', 123.456))
+ call assert_equal('1.234560e+02', printf('%e', 123.456))
+ call assert_equal('123.456', printf('%g', 123.456))
+ " +=
+ let v = 1.234
+ let v += 6.543
+ call assert_equal('7.777', printf('%g', v))
+ let v = 1.234
+ let v += 5
+ call assert_equal('6.234', printf('%g', v))
+ let v = 5
+ let v += 3.333
+ call assert_equal('8.333', string(v))
+ " ==
+ let v = 1.234
+ call assert_true(v == 1.234)
+ call assert_false(v == 1.2341)
+ " add-subtract
+ call assert_equal('5.234', printf('%g', 4 + 1.234))
+ call assert_equal('-6.766', printf('%g', 1.234 - 8))
+ " mult-div
+ call assert_equal('4.936', printf('%g', 4 * 1.234))
+ call assert_equal('0.003241', printf('%g', 4.0 / 1234))
+ " dict
+ call assert_equal("{'x': 1.234, 'y': -2.0e20}", string({'x': 1.234, 'y': -2.0e20}))
+ " list
+ call assert_equal('[-123.4, 2.0e-20]', string([-123.4, 2.0e-20]))
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim
new file mode 100644
index 0000000000..cdff0dfbd9
--- /dev/null
+++ b/src/nvim/testdir/test_fnameescape.vim
@@ -0,0 +1,21 @@
+
+" Test if fnameescape is correct for special chars like !
+function! Test_fnameescape()
+ let fname = 'Xspa ce'
+ let status = v:false
+ try
+ exe "w! " . fnameescape(fname)
+ let status = v:true
+ endtry
+ call assert_true(status, "Space")
+ call delete(fname)
+
+ let fname = 'Xemark!'
+ let status = v:false
+ try
+ exe "w! " . fnameescape(fname)
+ let status = v:true
+ endtry
+ call assert_true(status, "ExclamationMark")
+ call delete(fname)
+endfunction
diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim
new file mode 100644
index 0000000000..df3d691d85
--- /dev/null
+++ b/src/nvim/testdir/test_fold.vim
@@ -0,0 +1,742 @@
+" Test for folding
+
+source view_util.vim
+
+func PrepIndent(arg)
+ return [a:arg] + repeat(["\t".a:arg], 5)
+endfu
+
+func Test_address_fold()
+ new
+ call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
+ \ 'after fold 1', 'after fold 2', 'after fold 3'])
+ setl fen fdm=marker
+ " The next commands should all copy the same part of the buffer,
+ " regardless of the addressing type, since the part to be copied
+ " is folded away
+ :1y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :.+y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :.,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :sil .1,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .+,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :,y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+ :,+y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/','after fold 1'], getreg(0,1,1))
+ " using .+3 as second address should copy the whole folded line + the next 3
+ " lines
+ :.,+3y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/',
+ \ 'after fold 1', 'after fold 2', 'after fold 3'], getreg(0,1,1))
+ :sil .,-2y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3', '4', '5', '}/*}}}*/'], getreg(0,1,1))
+
+ " now test again with folding disabled
+ set nofoldenable
+ :1y
+ call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+ :.y
+ call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+ :.+y
+ call assert_equal(['1'], getreg(0,1,1))
+ :.,.y
+ call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .1,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+ " use silent to make E493 go away
+ :sil .+,.y
+ call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+ :,y
+ call assert_equal(['int FuncName() {/*{{{*/'], getreg(0,1,1))
+ :,+y
+ call assert_equal(['int FuncName() {/*{{{*/', '1'], getreg(0,1,1))
+ " using .+3 as second address should copy the whole folded line + the next 3
+ " lines
+ :.,+3y
+ call assert_equal(['int FuncName() {/*{{{*/', '1', '2', '3'], getreg(0,1,1))
+ :7
+ :sil .,-2y
+ call assert_equal(['4', '5', '}/*}}}*/'], getreg(0,1,1))
+
+ quit!
+endfunc
+
+func Test_indent_fold()
+ new
+ call setline(1, ['', 'a', ' b', ' c'])
+ setl fen fdm=indent
+ 2
+ norm! >>
+ let a=map(range(1,4), 'foldclosed(v:val)')
+ call assert_equal([-1,-1,-1,-1], a)
+ bw!
+endfunc
+
+func Test_indent_fold2()
+ new
+ call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
+ setl fen fdm=marker
+ 2
+ norm! >>
+ let a=map(range(1,5), 'foldclosed(v:val)')
+ call assert_equal([-1,-1,-1,4,4], a)
+ bw!
+endfunc
+
+func Test_manual_fold_with_filter()
+ if !executable('cat')
+ return
+ endif
+ for type in ['manual', 'marker']
+ exe 'set foldmethod=' . type
+ new
+ call setline(1, range(1, 20))
+ 4,$fold
+ %foldopen
+ 10,$fold
+ %foldopen
+ " This filter command should not have an effect
+ 1,8! cat
+ call feedkeys('5ggzdzMGdd', 'xt')
+ call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
+
+ bwipe!
+ set foldmethod&
+ endfor
+endfunc
+
+func Test_indent_fold_with_read()
+ new
+ set foldmethod=indent
+ call setline(1, repeat(["\<Tab>a"], 4))
+ for n in range(1, 4)
+ call assert_equal(1, foldlevel(n))
+ endfor
+
+ call writefile(["a", "", "\<Tab>a"], 'Xfile')
+ foldopen
+ 2read Xfile
+ %foldclose
+ call assert_equal(1, foldlevel(1))
+ call assert_equal(2, foldclosedend(1))
+ call assert_equal(0, foldlevel(3))
+ call assert_equal(0, foldlevel(4))
+ call assert_equal(1, foldlevel(5))
+ call assert_equal(7, foldclosedend(5))
+
+ bwipe!
+ set foldmethod&
+ call delete('Xfile')
+endfunc
+
+func Test_combining_folds_indent()
+ new
+ let one = "\<Tab>a"
+ let zero = 'a'
+ call setline(1, [one, one, zero, zero, zero, one, one, one])
+ set foldmethod=indent
+ 3,5d
+ %foldclose
+ call assert_equal(5, foldclosedend(1))
+
+ set foldmethod&
+ bwipe!
+endfunc
+
+func Test_combining_folds_marker()
+ new
+ call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}'])
+ set foldmethod=marker
+ 3,5d
+ %foldclose
+ call assert_equal(2, foldclosedend(1))
+
+ set foldmethod&
+ bwipe!
+endfunc
+
+func Test_folds_marker_in_comment()
+ new
+ call setline(1, ['" foo', 'bar', 'baz'])
+ setl fen fdm=marker
+ setl com=sO:\"\ -,mO:\"\ \ ,eO:\"\",:\" cms=\"%s
+ norm! zf2j
+ setl nofen
+ :1y
+ call assert_equal(['" foo{{{'], getreg(0,1,1))
+ :+2y
+ call assert_equal(['baz"}}}'], getreg(0,1,1))
+
+ set foldmethod&
+ bwipe!
+endfunc
+
+func s:TestFoldExpr(lnum)
+ let thisline = getline(a:lnum)
+ if thisline == 'a'
+ return 1
+ elseif thisline == 'b'
+ return 0
+ elseif thisline == 'c'
+ return '<1'
+ elseif thisline == 'd'
+ return '>1'
+ endif
+ return 0
+endfunction
+
+func Test_update_folds_expr_read()
+ new
+ call setline(1, ['a', 'a', 'a', 'a', 'a', 'a'])
+ set foldmethod=expr
+ set foldexpr=s:TestFoldExpr(v:lnum)
+ 2
+ foldopen
+ call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile')
+ read Xfile
+ %foldclose
+ call assert_equal(2, foldclosedend(1))
+ call assert_equal(0, foldlevel(3))
+ call assert_equal(0, foldlevel(4))
+ call assert_equal(6, foldclosedend(5))
+ call assert_equal(10, foldclosedend(7))
+ call assert_equal(14, foldclosedend(11))
+
+ call delete('Xfile')
+ bwipe!
+ set foldmethod& foldexpr&
+endfunc
+
+func Check_foldlevels(expected)
+ call assert_equal(a:expected, map(range(1, line('$')), 'foldlevel(v:val)'))
+endfunc
+
+func Test_move_folds_around_manual()
+ new
+ let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
+ call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+ let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
+ " all folds closed
+ set foldenable foldlevel=0 fdm=indent
+ " needs a forced redraw
+ redraw!
+ set fdm=manual
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ call assert_equal(input, getline(1, '$'))
+ 7,12m0
+ call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ 10,12m0
+ call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
+ call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+ " moving should not close the folds
+ %d
+ call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+ set fdm=indent
+ redraw!
+ set fdm=manual
+ call cursor(2, 1)
+ %foldopen
+ 7,12m0
+ let folds=repeat([-1], 18)
+ call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ norm! zM
+ " folds are not corrupted and all have been closed
+ call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+ %d
+ call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
+ set fdm=indent
+ redraw!
+ set fdm=manual
+ %foldopen
+ 3m4
+ %foldclose
+ call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
+ call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
+ %d
+ call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
+ set fdm=indent foldlevel=0
+ set fdm=manual
+ %foldopen
+ 3m1
+ %foldclose
+ call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
+ call assert_equal(0, foldlevel(2))
+ call assert_equal(5, foldclosedend(3))
+ call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
+ 2,6m$
+ %foldclose
+ call assert_equal(5, foldclosedend(2))
+ call assert_equal(0, foldlevel(6))
+ call assert_equal(9, foldclosedend(7))
+ call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
+
+ %d
+ " Ensure moving around the edges still works.
+ call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
+ set fdm=indent foldlevel=0
+ set fdm=manual
+ %foldopen
+ 6m$
+ " The first fold has been truncated to the 5'th line.
+ " Second fold has been moved up because the moved line is now below it.
+ call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 0])
+
+ %delete
+ set fdm=indent foldlevel=0
+ call setline(1, [
+ \ "a",
+ \ "\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "a",
+ \ "a"])
+ set fdm=manual
+ %foldopen!
+ 4,5m6
+ call Check_foldlevels([0, 1, 2, 0, 0, 0, 0])
+
+ %delete
+ set fdm=indent
+ call setline(1, [
+ \ "\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "\t\ta",
+ \ "\ta",
+ \ "a"])
+ set fdm=manual
+ %foldopen!
+ 13m7
+ call Check_foldlevels([1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0])
+
+ bw!
+endfunc
+
+func Test_move_folds_around_indent()
+ new
+ let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c")
+ call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+ let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14]
+ " all folds closed
+ set fdm=indent
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ call assert_equal(input, getline(1, '$'))
+ 7,12m0
+ call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ 10,12m0
+ call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$'))
+ call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+ " moving should not close the folds
+ %d
+ call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c"))
+ set fdm=indent
+ call cursor(2, 1)
+ %foldopen
+ 7,12m0
+ let folds=repeat([-1], 18)
+ call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$'))
+ call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)'))
+ norm! zM
+ " folds are not corrupted and all have been closed
+ call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)'))
+ %d
+ call setline(1, ["a", "\tb", "\tc", "\td", "\te"])
+ set fdm=indent
+ %foldopen
+ 3m4
+ %foldclose
+ call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$'))
+ call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)'))
+ %d
+ call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"])
+ set fdm=indent foldlevel=0
+ %foldopen
+ 3m1
+ %foldclose
+ call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$'))
+ call assert_equal(1, foldlevel(2))
+ call assert_equal(5, foldclosedend(3))
+ call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)'))
+ 2,6m$
+ %foldclose
+ call assert_equal(9, foldclosedend(2))
+ call assert_equal(1, foldlevel(6))
+ call assert_equal(9, foldclosedend(7))
+ call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)'))
+ " Ensure moving around the edges still works.
+ %d
+ call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"])
+ set fdm=indent foldlevel=0
+ %foldopen
+ 6m$
+ " The first fold has been truncated to the 5'th line.
+ " Second fold has been moved up because the moved line is now below it.
+ call Check_foldlevels([0, 1, 1, 1, 1, 0, 0, 0, 1, 1])
+ bw!
+endfunc
+
+" test for patch 7.3.637
+" Cannot catch the error caused by a foldopen when there is no fold.
+func Test_foldopen_exception()
+ enew!
+ let a = 'No error caught'
+ try
+ foldopen
+ catch
+ let a = matchstr(v:exception,'^[^ ]*')
+ endtry
+ call assert_equal('Vim(foldopen):E490:', a)
+
+ let a = 'No error caught'
+ try
+ foobar
+ catch
+ let a = matchstr(v:exception,'^[^ ]*')
+ endtry
+ call assert_match('E492:', a)
+endfunc
+
+func Test_folddoopen_folddoclosed()
+ new
+ call setline(1, range(1, 9))
+ set foldmethod=manual
+ 1,3 fold
+ 6,8 fold
+
+ " Test without range.
+ folddoopen s/$/o/
+ folddoclosed s/$/c/
+ call assert_equal(['1c', '2c', '3c',
+ \ '4o', '5o',
+ \ '6c', '7c', '8c',
+ \ '9o'], getline(1, '$'))
+
+ " Test with range.
+ call setline(1, range(1, 9))
+ 1,8 folddoopen s/$/o/
+ 4,$ folddoclosed s/$/c/
+ call assert_equal(['1', '2', '3',
+ \ '4o', '5o',
+ \ '6c', '7c', '8c',
+ \ '9'], getline(1, '$'))
+
+ set foldmethod&
+ bw!
+endfunc
+
+func Test_fold_error()
+ new
+ call setline(1, [1, 2])
+
+ for fm in ['indent', 'expr', 'syntax', 'diff']
+ exe 'set foldmethod=' . fm
+ call assert_fails('norm zf', 'E350:')
+ call assert_fails('norm zd', 'E351:')
+ call assert_fails('norm zE', 'E352:')
+ endfor
+
+ set foldmethod=manual
+ call assert_fails('norm zd', 'E490:')
+ call assert_fails('norm zo', 'E490:')
+ call assert_fails('3fold', 'E16:')
+
+ set foldmethod=marker
+ set nomodifiable
+ call assert_fails('1,2fold', 'E21:')
+
+ set modifiable&
+ set foldmethod&
+ bw!
+endfunc
+
+" Various fold related tests
+
+" Basic test if a fold can be created, opened, moving to the end and closed
+func Test_fold_manual()
+ enew!
+ set fdm=manual
+
+ let content = ['1 aa', '2 bb', '3 cc']
+ call append(0, content)
+ call cursor(1, 1)
+ normal zf2j
+ call assert_equal('1 aa', getline(foldclosed('.')))
+ normal zo
+ call assert_equal(-1, foldclosed('.'))
+ normal ]z
+ call assert_equal('3 cc', getline('.'))
+ normal zc
+ call assert_equal('1 aa', getline(foldclosed('.')))
+
+ set fdm&
+ enew!
+endfunc
+
+" test folding with markers.
+func Test_fold_marker()
+ enew!
+ set fdm=marker fdl=1 fdc=3
+
+ let content = ['4 dd {{{', '5 ee {{{ }}}', '6 ff }}}']
+ call append(0, content)
+ call cursor(2, 1)
+ call assert_equal(2, foldlevel('.'))
+ normal [z
+ call assert_equal(1, foldlevel('.'))
+ exe "normal jo{{ \<Esc>r{jj"
+ call assert_equal(1, foldlevel('.'))
+ normal kYpj
+ call assert_equal(0, foldlevel('.'))
+
+ set fdm& fdl& fdc&
+ enew!
+endfunc
+
+" test create fold markers with C filetype
+func Test_fold_create_marker_in_C()
+ enew!
+ set fdm=marker fdl=9
+ set filetype=c
+
+ let content = [
+ \ '/*',
+ \ ' * comment',
+ \ ' * ',
+ \ ' *',
+ \ ' */',
+ \ 'int f(int* p) {',
+ \ ' *p = 3;',
+ \ ' return 0;',
+ \ '}'
+ \]
+ for c in range(len(content) - 1)
+ bw!
+ call append(0, content)
+ call cursor(c + 1, 1)
+ norm! zfG
+ call assert_equal(content[c] . (c < 4 ? '{{{' : '/*{{{*/'), getline(c + 1))
+ endfor
+
+ set fdm& fdl&
+ enew!
+endfunc
+
+" test folding with indent
+func Test_fold_indent()
+ enew!
+ set fdm=indent sw=2
+
+ let content = ['1 aa', '2 bb', '3 cc']
+ call append(0, content)
+ call cursor(2, 1)
+ exe "normal i \<Esc>jI "
+ call assert_equal(2, foldlevel('.'))
+ normal k
+ call assert_equal(1, foldlevel('.'))
+
+ set fdm& sw&
+ enew!
+endfunc
+
+" test syntax folding
+func Test_fold_syntax()
+ if !has('syntax')
+ return
+ endif
+
+ enew!
+ set fdm=syntax fdl=0
+
+ syn region Hup start="dd" end="ii" fold contains=Fd1,Fd2,Fd3
+ syn region Fd1 start="ee" end="ff" fold contained
+ syn region Fd2 start="gg" end="hh" fold contained
+ syn region Fd3 start="commentstart" end="commentend" fold contained
+ let content = ['3 cc', '4 dd {{{', '5 ee {{{ }}}', '{{{{', '6 ff }}}',
+ \ '6 ff }}}', '7 gg', '8 hh', '9 ii']
+ call append(0, content)
+ normal Gzk
+ call assert_equal('9 ii', getline('.'))
+ normal k
+ call assert_equal('3 cc', getline('.'))
+ exe "normal jAcommentstart \<Esc>Acommentend"
+ set fdl=1
+ normal 3j
+ call assert_equal('7 gg', getline('.'))
+ set fdl=0
+ exe "normal zO\<C-L>j"
+ call assert_equal('8 hh', getline('.'))
+ syn clear Fd1 Fd2 Fd3 Hup
+
+ set fdm& fdl&
+ enew!
+endfunc
+
+func Flvl()
+ let l = getline(v:lnum)
+ if l =~ "bb$"
+ return 2
+ elseif l =~ "gg$"
+ return "s1"
+ elseif l =~ "ii$"
+ return ">2"
+ elseif l =~ "kk$"
+ return "0"
+ endif
+ return "="
+endfun
+
+" test expression folding
+func Test_fold_expr()
+ enew!
+ set fdm=expr fde=Flvl()
+
+ let content = ['1 aa',
+ \ '2 bb',
+ \ '3 cc',
+ \ '4 dd {{{commentstart commentend',
+ \ '5 ee {{{ }}}',
+ \ '{{{',
+ \ '6 ff }}}',
+ \ '6 ff }}}',
+ \ ' 7 gg',
+ \ ' 8 hh',
+ \ '9 ii',
+ \ 'a jj',
+ \ 'b kk']
+ call append(0, content)
+ call cursor(1, 1)
+ exe "normal /bb$\<CR>"
+ call assert_equal(2, foldlevel('.'))
+ exe "normal /hh$\<CR>"
+ call assert_equal(1, foldlevel('.'))
+ exe "normal /ii$\<CR>"
+ call assert_equal(2, foldlevel('.'))
+ exe "normal /kk$\<CR>"
+ call assert_equal(0, foldlevel('.'))
+
+ set fdm& fde&
+ enew!
+endfunc
+
+" Bug with fdm=indent and moving folds
+" Moving a fold a few times, messes up the folds below the moved fold.
+" Fixed by 7.4.700
+func Test_fold_move()
+ enew!
+ set fdm=indent sw=2 fdl=0
+
+ let content = ['', '', 'Line1', ' Line2', ' Line3',
+ \ 'Line4', ' Line5', ' Line6',
+ \ 'Line7', ' Line8', ' Line9']
+ call append(0, content)
+ normal zM
+ call cursor(4, 1)
+ move 2
+ move 1
+ call assert_equal(7, foldclosed(7))
+ call assert_equal(8, foldclosedend(7))
+ call assert_equal(0, foldlevel(9))
+ call assert_equal(10, foldclosed(10))
+ call assert_equal(11, foldclosedend(10))
+ call assert_equal('+-- 2 lines: Line2', foldtextresult(2))
+ call assert_equal('+-- 2 lines: Line8', foldtextresult(10))
+
+ set fdm& sw& fdl&
+ enew!
+endfunc
+
+func Test_foldtext_recursive()
+ new
+ call setline(1, ['{{{', 'some text', '}}}'])
+ setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart)
+ " This was crashing because of endless recursion.
+ 2foldclose
+ redraw
+ call assert_equal(1, foldlevel(2))
+ call assert_equal(1, foldclosed(2))
+ call assert_equal(3, foldclosedend(2))
+ bwipe!
+endfunc
+
+func Test_fold_last_line_with_pagedown()
+ enew!
+ set fdm=manual
+
+ let expect = '+-- 11 lines: 9---'
+ let content = range(1,19)
+ call append(0, content)
+ normal dd9G
+ normal zfG
+ normal zt
+ call assert_equal('9', getline(foldclosed('.')))
+ call assert_equal('19', getline(foldclosedend('.')))
+ call assert_equal(expect, ScreenLines(1, len(expect))[0])
+ call feedkeys("\<C-F>", 'xt')
+ call assert_equal(expect, ScreenLines(1, len(expect))[0])
+ call feedkeys("\<C-F>", 'xt')
+ call assert_equal(expect, ScreenLines(1, len(expect))[0])
+ call feedkeys("\<C-B>\<C-F>\<C-F>", 'xt')
+ call assert_equal(expect, ScreenLines(1, len(expect))[0])
+
+ set fdm&
+ enew!
+endfunc
+
+func Test_folds_with_rnu()
+ if !CanRunVimInTerminal()
+ return
+ endif
+
+ call writefile([
+ \ 'set fdm=marker rnu foldcolumn=2',
+ \ 'call setline(1, ["{{{1", "nline 1", "{{{1", "line 2"])',
+ \ ], 'Xtest_folds_with_rnu')
+ let buf = RunVimInTerminal('-S Xtest_folds_with_rnu', {})
+
+ call VerifyScreenDump(buf, 'Test_folds_with_rnu_01', {})
+ call term_sendkeys(buf, "j")
+ call VerifyScreenDump(buf, 'Test_folds_with_rnu_02', {})
+
+ " clean up
+ call StopVimInTerminal(buf)
+ call delete('Xtest_folds_with_rnu')
+endfunc
+
+func Test_folds_marker_in_comment2()
+ new
+ call setline(1, ['Lorem ipsum dolor sit', 'Lorem ipsum dolor sit', 'Lorem ipsum dolor sit'])
+ setl fen fdm=marker
+ setl commentstring=<!--%s-->
+ setl comments=s:<!--,m:\ \ \ \ ,e:-->
+ norm! zf2j
+ setl nofen
+ :1y
+ call assert_equal(['Lorem ipsum dolor sit<!--{{{-->'], getreg(0,1,1))
+ :+2y
+ call assert_equal(['Lorem ipsum dolor sit<!--}}}-->'], getreg(0,1,1))
+
+ set foldmethod&
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim
new file mode 100644
index 0000000000..7dc9f31ce7
--- /dev/null
+++ b/src/nvim/testdir/test_functions.vim
@@ -0,0 +1,1039 @@
+" Tests for various functions.
+
+" Must be done first, since the alternate buffer must be unset.
+func Test_00_bufexists()
+ call assert_equal(0, bufexists('does_not_exist'))
+ call assert_equal(1, bufexists(bufnr('%')))
+ call assert_equal(0, bufexists(0))
+ new Xfoo
+ let bn = bufnr('%')
+ call assert_equal(1, bufexists(bn))
+ call assert_equal(1, bufexists('Xfoo'))
+ call assert_equal(1, bufexists(getcwd() . '/Xfoo'))
+ call assert_equal(1, bufexists(0))
+ bw
+ call assert_equal(0, bufexists(bn))
+ call assert_equal(0, bufexists('Xfoo'))
+endfunc
+
+func Test_empty()
+ call assert_equal(1, empty(''))
+ call assert_equal(0, empty('a'))
+
+ call assert_equal(1, empty(0))
+ call assert_equal(1, empty(-0))
+ call assert_equal(0, empty(1))
+ call assert_equal(0, empty(-1))
+
+ call assert_equal(1, empty(0.0))
+ call assert_equal(1, empty(-0.0))
+ call assert_equal(0, empty(1.0))
+ call assert_equal(0, empty(-1.0))
+ call assert_equal(0, empty(1.0/0.0))
+ call assert_equal(0, empty(0.0/0.0))
+
+ call assert_equal(1, empty([]))
+ call assert_equal(0, empty(['a']))
+
+ call assert_equal(1, empty({}))
+ call assert_equal(0, empty({'a':1}))
+
+ call assert_equal(1, empty(v:null))
+ " call assert_equal(1, empty(v:none))
+ call assert_equal(1, empty(v:false))
+ call assert_equal(0, empty(v:true))
+
+ if has('channel')
+ call assert_equal(1, empty(test_null_channel()))
+ endif
+ if has('job')
+ call assert_equal(1, empty(test_null_job()))
+ endif
+
+ call assert_equal(0, empty(function('Test_empty')))
+endfunc
+
+func Test_len()
+ call assert_equal(1, len(0))
+ call assert_equal(2, len(12))
+
+ call assert_equal(0, len(''))
+ call assert_equal(2, len('ab'))
+
+ call assert_equal(0, len([]))
+ call assert_equal(2, len([2, 1]))
+
+ call assert_equal(0, len({}))
+ call assert_equal(2, len({'a': 1, 'b': 2}))
+
+ " call assert_fails('call len(v:none)', 'E701:')
+ call assert_fails('call len({-> 0})', 'E701:')
+endfunc
+
+func Test_max()
+ call assert_equal(0, max([]))
+ call assert_equal(2, max([2]))
+ call assert_equal(2, max([1, 2]))
+ call assert_equal(2, max([1, 2, v:null]))
+
+ call assert_equal(0, max({}))
+ call assert_equal(2, max({'a':1, 'b':2}))
+
+ call assert_fails('call max(1)', 'E712:')
+ " call assert_fails('call max(v:none)', 'E712:')
+endfunc
+
+func Test_min()
+ call assert_equal(0, min([]))
+ call assert_equal(2, min([2]))
+ call assert_equal(1, min([1, 2]))
+ call assert_equal(0, min([1, 2, v:null]))
+
+ call assert_equal(0, min({}))
+ call assert_equal(1, min({'a':1, 'b':2}))
+
+ call assert_fails('call min(1)', 'E712:')
+ " call assert_fails('call min(v:none)', 'E712:')
+endfunc
+
+func Test_strwidth()
+ for aw in ['single', 'double']
+ exe 'set ambiwidth=' . aw
+ call assert_equal(0, strwidth(''))
+ call assert_equal(1, strwidth("\t"))
+ call assert_equal(3, strwidth('Vim'))
+ call assert_equal(4, strwidth(1234))
+ call assert_equal(5, strwidth(-1234))
+
+ if has('multi_byte')
+ call assert_equal(2, strwidth('😉'))
+ call assert_equal(17, strwidth('EÄ¥oÅanÄo ĉiuĵaÅ­de'))
+ call assert_equal((aw == 'single') ? 6 : 7, strwidth('Straße'))
+ endif
+
+ call assert_fails('call strwidth({->0})', 'E729:')
+ call assert_fails('call strwidth([])', 'E730:')
+ call assert_fails('call strwidth({})', 'E731:')
+ call assert_fails('call strwidth(1.2)', 'E806:')
+ endfor
+
+ set ambiwidth&
+endfunc
+
+func Test_str2nr()
+ call assert_equal(0, str2nr(''))
+ call assert_equal(1, str2nr('1'))
+ call assert_equal(1, str2nr(' 1 '))
+
+ call assert_equal(1, str2nr('+1'))
+ call assert_equal(1, str2nr('+ 1'))
+ call assert_equal(1, str2nr(' + 1 '))
+
+ call assert_equal(-1, str2nr('-1'))
+ call assert_equal(-1, str2nr('- 1'))
+ call assert_equal(-1, str2nr(' - 1 '))
+
+ call assert_equal(123456789, str2nr('123456789'))
+ call assert_equal(-123456789, str2nr('-123456789'))
+
+ call assert_equal(5, str2nr('101', 2))
+ call assert_equal(5, str2nr('0b101', 2))
+ call assert_equal(5, str2nr('0B101', 2))
+ call assert_equal(-5, str2nr('-101', 2))
+ call assert_equal(-5, str2nr('-0b101', 2))
+ call assert_equal(-5, str2nr('-0B101', 2))
+
+ call assert_equal(65, str2nr('101', 8))
+ call assert_equal(65, str2nr('0101', 8))
+ call assert_equal(-65, str2nr('-101', 8))
+ call assert_equal(-65, str2nr('-0101', 8))
+
+ call assert_equal(11259375, str2nr('abcdef', 16))
+ call assert_equal(11259375, str2nr('ABCDEF', 16))
+ call assert_equal(-11259375, str2nr('-ABCDEF', 16))
+ call assert_equal(11259375, str2nr('0xabcdef', 16))
+ call assert_equal(11259375, str2nr('0Xabcdef', 16))
+ call assert_equal(11259375, str2nr('0XABCDEF', 16))
+ call assert_equal(-11259375, str2nr('-0xABCDEF', 16))
+
+ call assert_equal(0, str2nr('0x10'))
+ call assert_equal(0, str2nr('0b10'))
+ call assert_equal(1, str2nr('12', 2))
+ call assert_equal(1, str2nr('18', 8))
+ call assert_equal(1, str2nr('1g', 16))
+
+ call assert_equal(0, str2nr(v:null))
+ " call assert_equal(0, str2nr(v:none))
+
+ call assert_fails('call str2nr([])', 'E730:')
+ call assert_fails('call str2nr({->2})', 'E729:')
+ call assert_fails('call str2nr(1.2)', 'E806:')
+ call assert_fails('call str2nr(10, [])', 'E474:')
+endfunc
+
+func Test_strftime()
+ if !exists('*strftime')
+ return
+ endif
+ " Format of strftime() depends on system. We assume
+ " that basic formats tested here are available and
+ " identical on all systems which support strftime().
+ "
+ " The 2nd parameter of strftime() is a local time, so the output day
+ " of strftime() can be 17 or 18, depending on timezone.
+ call assert_match('^2017-01-1[78]$', strftime('%Y-%m-%d', 1484695512))
+ "
+ call assert_match('^\d\d\d\d-\(0\d\|1[012]\)-\([012]\d\|3[01]\) \([01]\d\|2[0-3]\):[0-5]\d:\([0-5]\d\|60\)$', strftime('%Y-%m-%d %H:%M:%S'))
+
+ call assert_fails('call strftime([])', 'E730:')
+ call assert_fails('call strftime("%Y", [])', 'E745:')
+endfunc
+
+func Test_resolve()
+ if !has('unix')
+ return
+ endif
+
+ " Xlink1 -> Xlink2
+ " Xlink2 -> Xlink3
+ silent !ln -s -f Xlink2 Xlink1
+ silent !ln -s -f Xlink3 Xlink2
+ call assert_equal('Xlink3', resolve('Xlink1'))
+ call assert_equal('./Xlink3', resolve('./Xlink1'))
+ call assert_equal('Xlink3/', resolve('Xlink2/'))
+ " FIXME: these tests result in things like "Xlink2/" instead of "Xlink3/"?!
+ "call assert_equal('Xlink3/', resolve('Xlink1/'))
+ "call assert_equal('./Xlink3/', resolve('./Xlink1/'))
+ "call assert_equal(getcwd() . '/Xlink3/', resolve(getcwd() . '/Xlink1/'))
+ call assert_equal(getcwd() . '/Xlink3', resolve(getcwd() . '/Xlink1'))
+
+ " Test resolve() with a symlink cycle.
+ " Xlink1 -> Xlink2
+ " Xlink2 -> Xlink3
+ " Xlink3 -> Xlink1
+ silent !ln -s -f Xlink1 Xlink3
+ call assert_fails('call resolve("Xlink1")', 'E655:')
+ call assert_fails('call resolve("./Xlink1")', 'E655:')
+ call assert_fails('call resolve("Xlink2")', 'E655:')
+ call assert_fails('call resolve("Xlink3")', 'E655:')
+ call delete('Xlink1')
+ call delete('Xlink2')
+ call delete('Xlink3')
+
+ silent !ln -s -f Xdir//Xfile Xlink
+ call assert_equal('Xdir/Xfile', resolve('Xlink'))
+ call delete('Xlink')
+
+ silent !ln -s -f Xlink2/ Xlink1
+ call assert_equal('Xlink2', resolve('Xlink1'))
+ call assert_equal('Xlink2/', resolve('Xlink1/'))
+ call delete('Xlink1')
+
+ silent !ln -s -f ./Xlink2 Xlink1
+ call assert_equal('Xlink2', resolve('Xlink1'))
+ call assert_equal('./Xlink2', resolve('./Xlink1'))
+ call delete('Xlink1')
+endfunc
+
+func Test_simplify()
+ call assert_equal('', simplify(''))
+ call assert_equal('/', simplify('/'))
+ call assert_equal('/', simplify('/.'))
+ call assert_equal('/', simplify('/..'))
+ call assert_equal('/...', simplify('/...'))
+ call assert_equal('./dir/file', simplify('./dir/file'))
+ call assert_equal('./dir/file', simplify('.///dir//file'))
+ call assert_equal('./dir/file', simplify('./dir/./file'))
+ call assert_equal('./file', simplify('./dir/../file'))
+ call assert_equal('../dir/file', simplify('dir/../../dir/file'))
+ call assert_equal('./file', simplify('dir/.././file'))
+
+ call assert_fails('call simplify({->0})', 'E729:')
+ call assert_fails('call simplify([])', 'E730:')
+ call assert_fails('call simplify({})', 'E731:')
+ call assert_fails('call simplify(1.2)', 'E806:')
+endfunc
+
+func Test_setbufvar_options()
+ " This tests that aucmd_prepbuf() and aucmd_restbuf() properly restore the
+ " window layout.
+ call assert_equal(1, winnr('$'))
+ split dummy_preview
+ resize 2
+ set winfixheight winfixwidth
+ let prev_id = win_getid()
+
+ wincmd j
+ let wh = winheight('.')
+ let dummy_buf = bufnr('dummy_buf1', v:true)
+ call setbufvar(dummy_buf, '&buftype', 'nofile')
+ execute 'belowright vertical split #' . dummy_buf
+ call assert_equal(wh, winheight('.'))
+ let dum1_id = win_getid()
+
+ wincmd h
+ let wh = winheight('.')
+ let dummy_buf = bufnr('dummy_buf2', v:true)
+ call setbufvar(dummy_buf, '&buftype', 'nofile')
+ execute 'belowright vertical split #' . dummy_buf
+ call assert_equal(wh, winheight('.'))
+
+ bwipe!
+ call win_gotoid(prev_id)
+ bwipe!
+ call win_gotoid(dum1_id)
+ bwipe!
+endfunc
+
+func Test_pathshorten()
+ call assert_equal('', pathshorten(''))
+ call assert_equal('foo', pathshorten('foo'))
+ call assert_equal('/foo', pathshorten('/foo'))
+ call assert_equal('f/', pathshorten('foo/'))
+ call assert_equal('f/bar', pathshorten('foo/bar'))
+ call assert_equal('f/b/foobar', pathshorten('foo/bar/foobar'))
+ call assert_equal('/f/b/foobar', pathshorten('/foo/bar/foobar'))
+ call assert_equal('.f/bar', pathshorten('.foo/bar'))
+ call assert_equal('~f/bar', pathshorten('~foo/bar'))
+ call assert_equal('~.f/bar', pathshorten('~.foo/bar'))
+ call assert_equal('.~f/bar', pathshorten('.~foo/bar'))
+ call assert_equal('~/f/bar', pathshorten('~/foo/bar'))
+endfunc
+
+func Test_strpart()
+ call assert_equal('de', strpart('abcdefg', 3, 2))
+ call assert_equal('ab', strpart('abcdefg', -2, 4))
+ call assert_equal('abcdefg', strpart('abcdefg', -2))
+ call assert_equal('fg', strpart('abcdefg', 5, 4))
+ call assert_equal('defg', strpart('abcdefg', 3))
+
+ if has('multi_byte')
+ call assert_equal('lép', strpart('éléphant', 2, 4))
+ call assert_equal('léphant', strpart('éléphant', 2))
+ endif
+endfunc
+
+func Test_tolower()
+ call assert_equal("", tolower(""))
+
+ " Test with all printable ASCII characters.
+ call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
+ \ tolower(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
+
+ if !has('multi_byte')
+ return
+ endif
+
+ " Test with a few uppercase diacritics.
+ call assert_equal("aàáâãäåÄăąǎǟǡả", tolower("AÀÃÂÃÄÅĀĂĄÇǞǠẢ"))
+ call assert_equal("bḃḇ", tolower("BḂḆ"))
+ call assert_equal("cçćĉċÄ", tolower("CÇĆĈĊČ"))
+ call assert_equal("dÄđḋá¸á¸‘", tolower("DÄŽÄḊḎá¸"))
+ call assert_equal("eèéêëēĕėęěẻẽ", tolower("EÈÉÊËĒĔĖĘĚẺẼ"))
+ call assert_equal("fḟ ", tolower("FḞ "))
+ call assert_equal("gÄğġģǥǧǵḡ", tolower("GĜĞĠĢǤǦǴḠ"))
+ call assert_equal("hĥħḣḧḩ", tolower("HĤĦḢḦḨ"))
+ call assert_equal("iìíîïĩīĭįiÇỉ", tolower("IÃŒÃÃŽÃĨĪĬĮİÇỈ"))
+ call assert_equal("jĵ", tolower("JĴ"))
+ call assert_equal("kķǩḱḵ", tolower("KĶǨḰḴ"))
+ call assert_equal("lĺļľŀłḻ", tolower("LĹĻĽĿÅḺ"))
+ call assert_equal("mḿá¹", tolower("MḾṀ"))
+ call assert_equal("nñńņňṅṉ", tolower("NÑŃŅŇṄṈ"))
+ call assert_equal("oòóôõöøÅÅőơǒǫǭá»", tolower("OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ"))
+ call assert_equal("pṕṗ", tolower("PṔṖ"))
+ call assert_equal("q", tolower("Q"))
+ call assert_equal("rŕŗřṙṟ", tolower("RŔŖŘṘṞ"))
+ call assert_equal("sÅ›Åşšṡ", tolower("SŚŜŞŠṠ"))
+ call assert_equal("tţťŧṫṯ", tolower("TŢŤŦṪṮ"))
+ call assert_equal("uùúûüũūŭůűųưǔủ", tolower("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
+ call assert_equal("vá¹½", tolower("Vá¹¼"))
+ call assert_equal("wŵáºáºƒáº…ẇ", tolower("WŴẀẂẄẆ"))
+ call assert_equal("xẋáº", tolower("XẊẌ"))
+ call assert_equal("yýŷÿáºá»³á»·á»¹", tolower("YÃŶŸẎỲỶỸ"))
+ call assert_equal("zźżžƶẑẕ", tolower("ZŹŻŽƵáºáº”"))
+
+ " Test with a few lowercase diacritics, which should remain unchanged.
+ call assert_equal("aàáâãäåÄăąǎǟǡả", tolower("aàáâãäåÄăąǎǟǡả"))
+ call assert_equal("bḃḇ", tolower("bḃḇ"))
+ call assert_equal("cçćĉċÄ", tolower("cçćĉċÄ"))
+ call assert_equal("dÄđḋá¸á¸‘", tolower("dÄđḋá¸á¸‘"))
+ call assert_equal("eèéêëēĕėęěẻẽ", tolower("eèéêëēĕėęěẻẽ"))
+ call assert_equal("fḟ", tolower("fḟ"))
+ call assert_equal("gÄğġģǥǧǵḡ", tolower("gÄğġģǥǧǵḡ"))
+ call assert_equal("hĥħḣḧḩẖ", tolower("hĥħḣḧḩẖ"))
+ call assert_equal("iìíîïĩīĭįÇỉ", tolower("iìíîïĩīĭįÇỉ"))
+ call assert_equal("jĵǰ", tolower("jĵǰ"))
+ call assert_equal("kķǩḱḵ", tolower("kķǩḱḵ"))
+ call assert_equal("lĺļľŀłḻ", tolower("lĺļľŀłḻ"))
+ call assert_equal("mḿṠ", tolower("mḿṠ"))
+ call assert_equal("nñńņňʼnṅṉ", tolower("nñńņňʼnṅṉ"))
+ call assert_equal("oòóôõöøÅÅőơǒǫǭá»", tolower("oòóôõöøÅÅőơǒǫǭá»"))
+ call assert_equal("pṕṗ", tolower("pṕṗ"))
+ call assert_equal("q", tolower("q"))
+ call assert_equal("rŕŗřṙṟ", tolower("rŕŗřṙṟ"))
+ call assert_equal("sÅ›Åşšṡ", tolower("sÅ›Åşšṡ"))
+ call assert_equal("tţťŧṫṯẗ", tolower("tţťŧṫṯẗ"))
+ call assert_equal("uùúûüũūŭůűųưǔủ", tolower("uùúûüũūŭůűųưǔủ"))
+ call assert_equal("vá¹½", tolower("vá¹½"))
+ call assert_equal("wŵáºáºƒáº…ẇẘ", tolower("wŵáºáºƒáº…ẇẘ"))
+ call assert_equal("ẋáº", tolower("ẋáº"))
+ call assert_equal("yýÿŷáºáº™á»³á»·á»¹", tolower("yýÿŷáºáº™á»³á»·á»¹"))
+ call assert_equal("zźżžƶẑẕ", tolower("zźżžƶẑẕ"))
+
+ " According to https://twitter.com/jifa/status/625776454479970304
+ " Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase
+ " in length (2 to 3 bytes) when lowercased. So let's test them.
+ call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
+
+ " This call to tolower with invalid utf8 sequence used to cause access to
+ " invalid memory.
+ call tolower("\xC0\x80\xC0")
+ call tolower("123\xC0\x80\xC0")
+endfunc
+
+func Test_toupper()
+ call assert_equal("", toupper(""))
+
+ " Test with all printable ASCII characters.
+ call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~',
+ \ toupper(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
+
+ if !has('multi_byte')
+ return
+ endif
+
+ " Test with a few lowercase diacritics.
+ call assert_equal("AÀÃÂÃÄÅĀĂĄÇǞǠẢ", toupper("aàáâãäåÄăąǎǟǡả"))
+ call assert_equal("BḂḆ", toupper("bḃḇ"))
+ call assert_equal("CÇĆĈĊČ", toupper("cçćĉċÄ"))
+ call assert_equal("DÄŽÄḊḎá¸", toupper("dÄđḋá¸á¸‘"))
+ call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("eèéêëēĕėęěẻẽ"))
+ call assert_equal("FḞ", toupper("fḟ"))
+ call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("gÄğġģǥǧǵḡ"))
+ call assert_equal("HĤĦḢḦḨẖ", toupper("hĥħḣḧḩẖ"))
+ call assert_equal("IÃŒÃÃŽÃĨĪĬĮÇỈ", toupper("iìíîïĩīĭįÇỉ"))
+ call assert_equal("JĴǰ", toupper("jĵǰ"))
+ call assert_equal("KĶǨḰḴ", toupper("kķǩḱḵ"))
+ call assert_equal("LĹĻĽĿÅḺ", toupper("lĺļľŀłḻ"))
+ call assert_equal("MḾṀ ", toupper("mḿṠ"))
+ call assert_equal("NÑŃŅŇʼnṄṈ", toupper("nñńņňʼnṅṉ"))
+ call assert_equal("OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ", toupper("oòóôõöøÅÅőơǒǫǭá»"))
+ call assert_equal("PṔṖ", toupper("pṕṗ"))
+ call assert_equal("Q", toupper("q"))
+ call assert_equal("RŔŖŘṘṞ", toupper("rŕŗřṙṟ"))
+ call assert_equal("SŚŜŞŠṠ", toupper("sÅ›Åşšṡ"))
+ call assert_equal("TŢŤŦṪṮẗ", toupper("tţťŧṫṯẗ"))
+ call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("uùúûüũūŭůűųưǔủ"))
+ call assert_equal("Vá¹¼", toupper("vá¹½"))
+ call assert_equal("WŴẀẂẄẆẘ", toupper("wŵáºáºƒáº…ẇẘ"))
+ call assert_equal("ẊẌ", toupper("ẋáº"))
+ call assert_equal("YßŶẎẙỲỶỸ", toupper("yýÿŷáºáº™á»³á»·á»¹"))
+ call assert_equal("ZŹŻŽƵáºáº”", toupper("zźżžƶẑẕ"))
+
+ " Test that uppercase diacritics, which should remain unchanged.
+ call assert_equal("AÀÃÂÃÄÅĀĂĄÇǞǠẢ", toupper("AÀÃÂÃÄÅĀĂĄÇǞǠẢ"))
+ call assert_equal("BḂḆ", toupper("BḂḆ"))
+ call assert_equal("CÇĆĈĊČ", toupper("CÇĆĈĊČ"))
+ call assert_equal("DÄŽÄḊḎá¸", toupper("DÄŽÄḊḎá¸"))
+ call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("EÈÉÊËĒĔĖĘĚẺẼ"))
+ call assert_equal("FḞ ", toupper("FḞ "))
+ call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("GĜĞĠĢǤǦǴḠ"))
+ call assert_equal("HĤĦḢḦḨ", toupper("HĤĦḢḦḨ"))
+ call assert_equal("IÃŒÃÃŽÃĨĪĬĮİÇỈ", toupper("IÃŒÃÃŽÃĨĪĬĮİÇỈ"))
+ call assert_equal("JÄ´", toupper("JÄ´"))
+ call assert_equal("KĶǨḰḴ", toupper("KĶǨḰḴ"))
+ call assert_equal("LĹĻĽĿÅḺ", toupper("LĹĻĽĿÅḺ"))
+ call assert_equal("MḾṀ", toupper("MḾṀ"))
+ call assert_equal("NÑŃŅŇṄṈ", toupper("NÑŃŅŇṄṈ"))
+ call assert_equal("OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ", toupper("OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ"))
+ call assert_equal("PṔṖ", toupper("PṔṖ"))
+ call assert_equal("Q", toupper("Q"))
+ call assert_equal("RŔŖŘṘṞ", toupper("RŔŖŘṘṞ"))
+ call assert_equal("SŚŜŞŠṠ", toupper("SŚŜŞŠṠ"))
+ call assert_equal("TŢŤŦṪṮ", toupper("TŢŤŦṪṮ"))
+ call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
+ call assert_equal("Vá¹¼", toupper("Vá¹¼"))
+ call assert_equal("WŴẀẂẄẆ", toupper("WŴẀẂẄẆ"))
+ call assert_equal("XẊẌ", toupper("XẊẌ"))
+ call assert_equal("YÃŶŸẎỲỶỸ", toupper("YÃŶŸẎỲỶỸ"))
+ call assert_equal("ZŹŻŽƵáºáº”", toupper("ZŹŻŽƵáºáº”"))
+
+ call assert_equal("Ⱥ Ⱦ", toupper("ⱥ ⱦ"))
+
+ " This call to toupper with invalid utf8 sequence used to cause access to
+ " invalid memory.
+ call toupper("\xC0\x80\xC0")
+ call toupper("123\xC0\x80\xC0")
+endfunc
+
+" Tests for the mode() function
+let current_modes = ''
+func Save_mode()
+ let g:current_modes = mode(0) . '-' . mode(1)
+ return ''
+endfunc
+
+func Test_mode()
+ new
+ call append(0, ["Blue Ball Black", "Brown Band Bowl", ""])
+
+ " Only complete from the current buffer.
+ set complete=.
+
+ inoremap <F2> <C-R>=Save_mode()<CR>
+
+ normal! 3G
+ exe "normal i\<F2>\<Esc>"
+ call assert_equal('i-i', g:current_modes)
+ " i_CTRL-P: Multiple matches
+ exe "normal i\<C-G>uBa\<C-P>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-P: Single match
+ exe "normal iBro\<C-P>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X
+ exe "normal iBa\<C-X>\<F2>\<Esc>u"
+ call assert_equal('i-ix', g:current_modes)
+ " i_CTRL-X CTRL-P: Multiple matches
+ exe "normal iBa\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-P: Single match
+ exe "normal iBro\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-P + CTRL-P: Single match
+ exe "normal iBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-L: Multiple matches
+ exe "normal i\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-L: Single match
+ exe "normal iBlu\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-P: No match
+ exe "normal iCom\<C-P>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-P: No match
+ exe "normal iCom\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+ " i_CTRL-X CTRL-L: No match
+ exe "normal iabc\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('i-ic', g:current_modes)
+
+ " R_CTRL-P: Multiple matches
+ exe "normal RBa\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-P: Single match
+ exe "normal RBro\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X
+ exe "normal RBa\<C-X>\<F2>\<Esc>u"
+ call assert_equal('R-Rx', g:current_modes)
+ " R_CTRL-X CTRL-P: Multiple matches
+ exe "normal RBa\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-P: Single match
+ exe "normal RBro\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-P + CTRL-P: Single match
+ exe "normal RBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-L: Multiple matches
+ exe "normal R\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-L: Single match
+ exe "normal RBlu\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-P: No match
+ exe "normal RCom\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-P: No match
+ exe "normal RCom\<C-X>\<C-P>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+ " R_CTRL-X CTRL-L: No match
+ exe "normal Rabc\<C-X>\<C-L>\<F2>\<Esc>u"
+ call assert_equal('R-Rc', g:current_modes)
+
+ call assert_equal('n', mode(0))
+ call assert_equal('n', mode(1))
+
+ " How to test operator-pending mode?
+
+ call feedkeys("v", 'xt')
+ call assert_equal('v', mode())
+ call assert_equal('v', mode(1))
+ call feedkeys("\<Esc>V", 'xt')
+ call assert_equal('V', mode())
+ call assert_equal('V', mode(1))
+ call feedkeys("\<Esc>\<C-V>", 'xt')
+ call assert_equal("\<C-V>", mode())
+ call assert_equal("\<C-V>", mode(1))
+ call feedkeys("\<Esc>", 'xt')
+
+ call feedkeys("gh", 'xt')
+ call assert_equal('s', mode())
+ call assert_equal('s', mode(1))
+ call feedkeys("\<Esc>gH", 'xt')
+ call assert_equal('S', mode())
+ call assert_equal('S', mode(1))
+ call feedkeys("\<Esc>g\<C-H>", 'xt')
+ call assert_equal("\<C-S>", mode())
+ call assert_equal("\<C-S>", mode(1))
+ call feedkeys("\<Esc>", 'xt')
+
+ call feedkeys(":echo \<C-R>=Save_mode()\<C-U>\<CR>", 'xt')
+ call assert_equal('c-c', g:current_modes)
+ call feedkeys("gQecho \<C-R>=Save_mode()\<CR>\<CR>vi\<CR>", 'xt')
+ call assert_equal('c-cv', g:current_modes)
+ " How to test Ex mode?
+
+ bwipe!
+ iunmap <F2>
+ set complete&
+endfunc
+
+func Test_getbufvar()
+ let bnr = bufnr('%')
+ let b:var_num = '1234'
+ let def_num = '5678'
+ call assert_equal('1234', getbufvar(bnr, 'var_num'))
+ call assert_equal('1234', getbufvar(bnr, 'var_num', def_num))
+
+ let bd = getbufvar(bnr, '')
+ call assert_equal('1234', bd['var_num'])
+ call assert_true(exists("bd['changedtick']"))
+ call assert_equal(2, len(bd))
+
+ let bd2 = getbufvar(bnr, '', def_num)
+ call assert_equal(bd, bd2)
+
+ unlet b:var_num
+ call assert_equal(def_num, getbufvar(bnr, 'var_num', def_num))
+ call assert_equal('', getbufvar(bnr, 'var_num'))
+
+ let bd = getbufvar(bnr, '')
+ call assert_equal(1, len(bd))
+ let bd = getbufvar(bnr, '',def_num)
+ call assert_equal(1, len(bd))
+
+ call assert_equal('', getbufvar(9999, ''))
+ call assert_equal(def_num, getbufvar(9999, '', def_num))
+ unlet def_num
+
+ call assert_equal(0, getbufvar(bnr, '&autoindent'))
+ call assert_equal(0, getbufvar(bnr, '&autoindent', 1))
+
+ " Open new window with forced option values
+ set fileformats=unix,dos
+ new ++ff=dos ++bin ++enc=iso-8859-2
+ call assert_equal('dos', getbufvar(bufnr('%'), '&fileformat'))
+ call assert_equal(1, getbufvar(bufnr('%'), '&bin'))
+ call assert_equal('iso-8859-2', getbufvar(bufnr('%'), '&fenc'))
+ close
+
+ set fileformats&
+endfunc
+
+func Test_last_buffer_nr()
+ call assert_equal(bufnr('$'), last_buffer_nr())
+endfunc
+
+func Test_stridx()
+ call assert_equal(-1, stridx('', 'l'))
+ call assert_equal(0, stridx('', ''))
+ call assert_equal(0, stridx('hello', ''))
+ call assert_equal(-1, stridx('hello', 'L'))
+ call assert_equal(2, stridx('hello', 'l', -1))
+ call assert_equal(2, stridx('hello', 'l', 0))
+ call assert_equal(2, stridx('hello', 'l', 1))
+ call assert_equal(3, stridx('hello', 'l', 3))
+ call assert_equal(-1, stridx('hello', 'l', 4))
+ call assert_equal(-1, stridx('hello', 'l', 10))
+ call assert_equal(2, stridx('hello', 'll'))
+ call assert_equal(-1, stridx('hello', 'hello world'))
+endfunc
+
+func Test_strridx()
+ call assert_equal(-1, strridx('', 'l'))
+ call assert_equal(0, strridx('', ''))
+ call assert_equal(5, strridx('hello', ''))
+ call assert_equal(-1, strridx('hello', 'L'))
+ call assert_equal(3, strridx('hello', 'l'))
+ call assert_equal(3, strridx('hello', 'l', 10))
+ call assert_equal(3, strridx('hello', 'l', 3))
+ call assert_equal(2, strridx('hello', 'l', 2))
+ call assert_equal(-1, strridx('hello', 'l', 1))
+ call assert_equal(-1, strridx('hello', 'l', 0))
+ call assert_equal(-1, strridx('hello', 'l', -1))
+ call assert_equal(2, strridx('hello', 'll'))
+ call assert_equal(-1, strridx('hello', 'hello world'))
+endfunc
+
+func Test_match_func()
+ call assert_equal(4, match('testing', 'ing'))
+ call assert_equal(4, match('testing', 'ing', 2))
+ call assert_equal(-1, match('testing', 'ing', 5))
+ call assert_equal(-1, match('testing', 'ing', 8))
+ call assert_equal(1, match(['vim', 'testing', 'execute'], 'ing'))
+ call assert_equal(-1, match(['vim', 'testing', 'execute'], 'img'))
+endfunc
+
+func Test_matchend()
+ call assert_equal(7, matchend('testing', 'ing'))
+ call assert_equal(7, matchend('testing', 'ing', 2))
+ call assert_equal(-1, matchend('testing', 'ing', 5))
+ call assert_equal(-1, matchend('testing', 'ing', 8))
+ call assert_equal(match(['vim', 'testing', 'execute'], 'ing'), matchend(['vim', 'testing', 'execute'], 'ing'))
+ call assert_equal(match(['vim', 'testing', 'execute'], 'img'), matchend(['vim', 'testing', 'execute'], 'img'))
+endfunc
+
+func Test_matchlist()
+ call assert_equal(['acd', 'a', '', 'c', 'd', '', '', '', '', ''], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)'))
+ call assert_equal(['d', '', '', '', 'd', '', '', '', '', ''], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 2))
+ call assert_equal([], matchlist('acd', '\(a\)\?\(b\)\?\(c\)\?\(.*\)', 4))
+endfunc
+
+func Test_matchstr()
+ call assert_equal('ing', matchstr('testing', 'ing'))
+ call assert_equal('ing', matchstr('testing', 'ing', 2))
+ call assert_equal('', matchstr('testing', 'ing', 5))
+ call assert_equal('', matchstr('testing', 'ing', 8))
+ call assert_equal('testing', matchstr(['vim', 'testing', 'execute'], 'ing'))
+ call assert_equal('', matchstr(['vim', 'testing', 'execute'], 'img'))
+endfunc
+
+func Test_matchstrpos()
+ call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing'))
+ call assert_equal(['ing', 4, 7], matchstrpos('testing', 'ing', 2))
+ call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 5))
+ call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8))
+ call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
+ call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img'))
+endfunc
+
+func Test_nextnonblank_prevnonblank()
+ new
+insert
+This
+
+
+is
+
+a
+Test
+.
+ call assert_equal(0, nextnonblank(-1))
+ call assert_equal(0, nextnonblank(0))
+ call assert_equal(1, nextnonblank(1))
+ call assert_equal(4, nextnonblank(2))
+ call assert_equal(4, nextnonblank(3))
+ call assert_equal(4, nextnonblank(4))
+ call assert_equal(6, nextnonblank(5))
+ call assert_equal(6, nextnonblank(6))
+ call assert_equal(7, nextnonblank(7))
+ call assert_equal(0, nextnonblank(8))
+
+ call assert_equal(0, prevnonblank(-1))
+ call assert_equal(0, prevnonblank(0))
+ call assert_equal(1, prevnonblank(1))
+ call assert_equal(1, prevnonblank(2))
+ call assert_equal(1, prevnonblank(3))
+ call assert_equal(4, prevnonblank(4))
+ call assert_equal(4, prevnonblank(5))
+ call assert_equal(6, prevnonblank(6))
+ call assert_equal(7, prevnonblank(7))
+ call assert_equal(0, prevnonblank(8))
+ bw!
+endfunc
+
+func Test_byte2line_line2byte()
+ new
+ set endofline
+ call setline(1, ['a', 'bc', 'd'])
+
+ set fileformat=unix
+ call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
+ \ map(range(-1, 8), 'byte2line(v:val)'))
+ call assert_equal([-1, -1, 1, 3, 6, 8, -1],
+ \ map(range(-1, 5), 'line2byte(v:val)'))
+
+ set fileformat=mac
+ call assert_equal([-1, -1, 1, 1, 2, 2, 2, 3, 3, -1],
+ \ map(range(-1, 8), 'byte2line(v:val)'))
+ call assert_equal([-1, -1, 1, 3, 6, 8, -1],
+ \ map(range(-1, 5), 'line2byte(v:val)'))
+
+ set fileformat=dos
+ call assert_equal([-1, -1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, -1],
+ \ map(range(-1, 11), 'byte2line(v:val)'))
+ call assert_equal([-1, -1, 1, 4, 8, 11, -1],
+ \ map(range(-1, 5), 'line2byte(v:val)'))
+
+ bw!
+ set noendofline nofixendofline
+ normal a-
+ for ff in ["unix", "mac", "dos"]
+ let &fileformat = ff
+ call assert_equal(1, line2byte(1))
+ call assert_equal(2, line2byte(2)) " line2byte(line("$") + 1) is the buffer size plus one (as per :help line2byte).
+ endfor
+
+ set endofline& fixendofline& fileformat&
+ bw!
+endfunc
+
+func Test_count()
+ let l = ['a', 'a', 'A', 'b']
+ call assert_equal(2, count(l, 'a'))
+ call assert_equal(1, count(l, 'A'))
+ call assert_equal(1, count(l, 'b'))
+ call assert_equal(0, count(l, 'B'))
+
+ call assert_equal(2, count(l, 'a', 0))
+ call assert_equal(1, count(l, 'A', 0))
+ call assert_equal(1, count(l, 'b', 0))
+ call assert_equal(0, count(l, 'B', 0))
+
+ call assert_equal(3, count(l, 'a', 1))
+ call assert_equal(3, count(l, 'A', 1))
+ call assert_equal(1, count(l, 'b', 1))
+ call assert_equal(1, count(l, 'B', 1))
+ call assert_equal(0, count(l, 'c', 1))
+
+ call assert_equal(1, count(l, 'a', 0, 1))
+ call assert_equal(2, count(l, 'a', 1, 1))
+ call assert_fails('call count(l, "a", 0, 10)', 'E684:')
+
+ let d = {1: 'a', 2: 'a', 3: 'A', 4: 'b'}
+ call assert_equal(2, count(d, 'a'))
+ call assert_equal(1, count(d, 'A'))
+ call assert_equal(1, count(d, 'b'))
+ call assert_equal(0, count(d, 'B'))
+
+ call assert_equal(2, count(d, 'a', 0))
+ call assert_equal(1, count(d, 'A', 0))
+ call assert_equal(1, count(d, 'b', 0))
+ call assert_equal(0, count(d, 'B', 0))
+
+ call assert_equal(3, count(d, 'a', 1))
+ call assert_equal(3, count(d, 'A', 1))
+ call assert_equal(1, count(d, 'b', 1))
+ call assert_equal(1, count(d, 'B', 1))
+ call assert_equal(0, count(d, 'c', 1))
+
+ call assert_fails('call count(d, "a", 0, 1)', 'E474:')
+
+ call assert_equal(0, count("foo", "bar"))
+ call assert_equal(1, count("foo", "oo"))
+ call assert_equal(2, count("foo", "o"))
+ call assert_equal(0, count("foo", "O"))
+ call assert_equal(2, count("foo", "O", 1))
+ call assert_equal(2, count("fooooo", "oo"))
+ call assert_equal(0, count("foo", ""))
+endfunc
+
+func Test_changenr()
+ new Xchangenr
+ call assert_equal(0, changenr())
+ norm ifoo
+ call assert_equal(1, changenr())
+ set undolevels=10
+ norm Sbar
+ call assert_equal(2, changenr())
+ undo
+ call assert_equal(1, changenr())
+ redo
+ call assert_equal(2, changenr())
+ bw!
+ set undolevels&
+endfunc
+
+func Test_filewritable()
+ new Xfilewritable
+ write!
+ call assert_equal(1, filewritable('Xfilewritable'))
+
+ call assert_notequal(0, setfperm('Xfilewritable', 'r--r-----'))
+ call assert_equal(0, filewritable('Xfilewritable'))
+
+ call assert_notequal(0, setfperm('Xfilewritable', 'rw-r-----'))
+ call assert_equal(1, filewritable('Xfilewritable'))
+
+ call assert_equal(0, filewritable('doesnotexist'))
+
+ call delete('Xfilewritable')
+ bw!
+endfunc
+
+func Test_Executable()
+ if has('win32')
+ call assert_equal(1, executable('notepad'))
+ call assert_equal(1, executable('notepad.exe'))
+ call assert_equal(0, executable('notepad.exe.exe'))
+ call assert_equal(1, executable('shell32.dll'))
+ call assert_equal(1, executable('win.ini'))
+ elseif has('unix')
+ call assert_equal(1, executable('cat'))
+ call assert_equal(0, executable('nodogshere'))
+ endif
+endfunc
+
+func Test_hostname()
+ let hostname_vim = hostname()
+ if has('unix')
+ let hostname_system = systemlist('uname -n')[0]
+ call assert_equal(hostname_vim, hostname_system)
+ endif
+endfunc
+
+func Test_getpid()
+ " getpid() always returns the same value within a vim instance.
+ call assert_equal(getpid(), getpid())
+ if has('unix')
+ call assert_equal(systemlist('echo $PPID')[0], string(getpid()))
+ endif
+endfunc
+
+func Test_hlexists()
+ call assert_equal(0, hlexists('does_not_exist'))
+ " call assert_equal(0, hlexists('Number'))
+ call assert_equal(0, highlight_exists('does_not_exist'))
+ " call assert_equal(0, highlight_exists('Number'))
+ syntax on
+ call assert_equal(0, hlexists('does_not_exist'))
+ " call assert_equal(1, hlexists('Number'))
+ call assert_equal(0, highlight_exists('does_not_exist'))
+ " call assert_equal(1, highlight_exists('Number'))
+ syntax off
+endfunc
+
+func Test_col()
+ new
+ call setline(1, 'abcdef')
+ norm gg4|mx6|mY2|
+ call assert_equal(2, col('.'))
+ call assert_equal(7, col('$'))
+ call assert_equal(4, col("'x"))
+ call assert_equal(6, col("'Y"))
+ call assert_equal(2, col([1, 2]))
+ call assert_equal(7, col([1, '$']))
+
+ call assert_equal(0, col(''))
+ call assert_equal(0, col('x'))
+ call assert_equal(0, col([2, '$']))
+ call assert_equal(0, col([1, 100]))
+ call assert_equal(0, col([1]))
+ bw!
+endfunc
+
+func Test_inputlist()
+ call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>1\<cr>", 'tx')
+ call assert_equal(1, c)
+ call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>2\<cr>", 'tx')
+ call assert_equal(2, c)
+ call feedkeys(":let c = inputlist(['Select color:', '1. red', '2. green', '3. blue'])\<cr>3\<cr>", 'tx')
+ call assert_equal(3, c)
+
+ call assert_fails('call inputlist("")', 'E686:')
+endfunc
+
+func Test_balloon_show()
+ if has('balloon_eval')
+ " This won't do anything but must not crash either.
+ call balloon_show('hi!')
+ endif
+endfunc
+
+func Test_shellescape()
+ let save_shell = &shell
+ set shell=bash
+ call assert_equal("'text'", shellescape('text'))
+ call assert_equal("'te\"xt'", shellescape('te"xt'))
+ call assert_equal("'te'\\''xt'", shellescape("te'xt"))
+
+ call assert_equal("'te%xt'", shellescape("te%xt"))
+ call assert_equal("'te\\%xt'", shellescape("te%xt", 1))
+ call assert_equal("'te#xt'", shellescape("te#xt"))
+ call assert_equal("'te\\#xt'", shellescape("te#xt", 1))
+ call assert_equal("'te!xt'", shellescape("te!xt"))
+ call assert_equal("'te\\!xt'", shellescape("te!xt", 1))
+
+ call assert_equal("'te\nxt'", shellescape("te\nxt"))
+ call assert_equal("'te\\\nxt'", shellescape("te\nxt", 1))
+ set shell=tcsh
+ call assert_equal("'te\\!xt'", shellescape("te!xt"))
+ call assert_equal("'te\\\\!xt'", shellescape("te!xt", 1))
+ call assert_equal("'te\\\nxt'", shellescape("te\nxt"))
+ call assert_equal("'te\\\\\nxt'", shellescape("te\nxt", 1))
+
+ let &shell = save_shell
+endfunc
+
+func Test_redo_in_nested_functions()
+ nnoremap g. :set opfunc=Operator<CR>g@
+ function Operator( type, ... )
+ let @x = 'XXX'
+ execute 'normal! g`[' . (a:type ==# 'line' ? 'V' : 'v') . 'g`]' . '"xp'
+ endfunction
+
+ function! Apply()
+ 5,6normal! .
+ endfunction
+
+ new
+ call setline(1, repeat(['some "quoted" text', 'more "quoted" text'], 3))
+ 1normal g.i"
+ call assert_equal('some "XXX" text', getline(1))
+ 3,4normal .
+ call assert_equal('some "XXX" text', getline(3))
+ call assert_equal('more "XXX" text', getline(4))
+ call Apply()
+ call assert_equal('some "XXX" text', getline(5))
+ call assert_equal('more "XXX" text', getline(6))
+ bwipe!
+
+ nunmap g.
+ delfunc Operator
+ delfunc Apply
+endfunc
+
+func Test_trim()
+ call assert_equal("Testing", trim(" \t\r\r\x0BTesting \t\n\r\n\t\x0B\x0B"))
+ call assert_equal("Testing", trim(" \t \r\r\n\n\x0BTesting \t\n\r\n\t\x0B\x0B"))
+ call assert_equal("RESERVE", trim("xyz \twwRESERVEzyww \t\t", " wxyz\t"))
+ call assert_equal("wRE \tSERVEzyww", trim("wRE \tSERVEzyww"))
+ call assert_equal("abcd\t xxxx tail", trim(" \tabcd\t xxxx tail"))
+ call assert_equal("\tabcd\t xxxx tail", trim(" \tabcd\t xxxx tail", " "))
+ call assert_equal(" \tabcd\t xxxx tail", trim(" \tabcd\t xxxx tail", "abx"))
+ call assert_equal("RESERVE", trim("你RESERVE好", "你好"))
+ call assert_equal("您R E SER V E早", trim("你好您R E SER V E早好你你", "你好"))
+ call assert_equal("你好您R E SER V E早好你你", trim(" \n\r\r 你好您R E SER V E早好你你 \t \x0B", ))
+ call assert_equal("您R E SER V E早好你你 \t \x0B", trim(" 你好您R E SER V E早好你你 \t \x0B", " 你好"))
+ call assert_equal("您R E SER V E早好你你 \t \x0B", trim(" tteesstttt你好您R E SER V E早好你你 \t \x0B ttestt", " 你好tes"))
+ call assert_equal("您R E SER V E早好你你 \t \x0B", trim(" tteesstttt你好您R E SER V E早好你你 \t \x0B ttestt", " 你你你好好好tttsses"))
+ call assert_equal("留下", trim("这些些ä¸è¦è¿™äº›ç•™ä¸‹è¿™äº›", "这些ä¸è¦"))
+ call assert_equal("", trim("", ""))
+ call assert_equal("a", trim("a", ""))
+ call assert_equal("", trim("", "a"))
+
+ let chars = join(map(range(1, 0x20) + [0xa0], {n -> nr2char(n)}), '')
+ call assert_equal("x", trim(chars . "x" . chars))
+endfunc
+
+func EditAnotherFile()
+ let word = expand('<cword>')
+ edit Xfuncrange2
+endfunc
+
+func Test_func_range_with_edit()
+ " Define a function that edits another buffer, then call it with a range that
+ " is invalid in that buffer.
+ call writefile(['just one line'], 'Xfuncrange2')
+ new
+ call setline(1, range(10))
+ write Xfuncrange1
+ call assert_fails('5,8call EditAnotherFile()', 'E16:')
+
+ call delete('Xfuncrange1')
+ call delete('Xfuncrange2')
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_ga.vim b/src/nvim/testdir/test_ga.vim
new file mode 100644
index 0000000000..6a7cba28f0
--- /dev/null
+++ b/src/nvim/testdir/test_ga.vim
@@ -0,0 +1,37 @@
+" Test ga normal command, and :ascii Ex command.
+func Do_ga(c)
+ call setline(1, a:c)
+ let l:a = execute("norm 1goga")
+ let l:b = execute("ascii")
+ call assert_equal(l:a, l:b)
+ return l:a
+endfunc
+
+func Test_ga_command()
+ new
+ set display=uhex
+ call assert_equal("\nNUL", Do_ga(''))
+ call assert_equal("\n<<01>> 1, Hex 01, Oct 001, Digr SH", Do_ga("\x01"))
+ call assert_equal("\n<<09>> 9, Hex 09, Oct 011, Digr HT", Do_ga("\t"))
+
+ set display=
+ call assert_equal("\nNUL", Do_ga(''))
+ call assert_equal("\n<^A> 1, Hex 01, Oct 001, Digr SH", Do_ga("\x01"))
+ call assert_equal("\n<^I> 9, Hex 09, Oct 011, Digr HT", Do_ga("\t"))
+
+ call assert_equal("\n<e> 101, Hex 65, Octal 145", Do_ga('e'))
+
+ if !has('multi_byte')
+ return
+ endif
+
+ " Test a few multi-bytes characters.
+ call assert_equal("\n<é> 233, Hex 00e9, Oct 351, Digr e'", Do_ga('é'))
+ call assert_equal("\n<ẻ> 7867, Hex 1ebb, Oct 17273, Digr e2", Do_ga('ẻ'))
+
+ " Test with combining characters.
+ call assert_equal("\n<e> 101, Hex 65, Octal 145 < Ì> 769, Hex 0301, Octal 1401", Do_ga("e\u0301"))
+ call assert_equal("\n<e> 101, Hex 65, Octal 145 < Ì> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461", Do_ga("e\u0301\u0331"))
+ call assert_equal("\n<e> 101, Hex 65, Octal 145 < Ì> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461 < ̸> 824, Hex 0338, Octal 1470", Do_ga("e\u0301\u0331\u0338"))
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_getcwd.vim b/src/nvim/testdir/test_getcwd.vim
new file mode 100644
index 0000000000..5d97295e9a
--- /dev/null
+++ b/src/nvim/testdir/test_getcwd.vim
@@ -0,0 +1,112 @@
+function! GetCwdInfo(win, tab)
+ let tab_changed = 0
+ let mod = ":t"
+ if a:tab > 0 && a:tab != tabpagenr()
+ let tab_changed = 1
+ exec "tabnext " . a:tab
+ endif
+ let bufname = fnamemodify(bufname(winbufnr(a:win)), mod)
+ if tab_changed
+ tabprevious
+ endif
+ if a:win == 0 && a:tab == 0
+ let dirname = fnamemodify(getcwd(), mod)
+ let lflag = haslocaldir()
+ elseif a:tab == 0
+ let dirname = fnamemodify(getcwd(a:win), mod)
+ let lflag = haslocaldir(a:win)
+ else
+ let dirname = fnamemodify(getcwd(a:win, a:tab), mod)
+ let lflag = haslocaldir(a:win, a:tab)
+ endif
+ return bufname . ' ' . dirname . ' ' . lflag
+endfunction
+
+" Do all test in a separate window to avoid E211 when we recursively
+" delete the Xtopdir directory during cleanup
+function SetUp()
+ set visualbell
+ set nocp viminfo+=nviminfo
+
+ " On windows a swapfile in Xtopdir prevents it from being cleaned up.
+ set noswapfile
+
+ " On windows a stale "Xtopdir" directory may exist, remove it so that
+ " we start from a clean state.
+ call delete("Xtopdir", "rf")
+ new
+ call mkdir('Xtopdir')
+ cd Xtopdir
+ let g:topdir = getcwd()
+ call mkdir('Xdir1')
+ call mkdir('Xdir2')
+ call mkdir('Xdir3')
+endfunction
+
+let g:cwd=getcwd()
+function TearDown()
+ q
+ exec "cd " . g:cwd
+ call delete("Xtopdir", "rf")
+endfunction
+
+function Test_GetCwd()
+ new a
+ new b
+ new c
+ 3wincmd w
+ lcd Xdir1
+ call assert_equal("a Xdir1 1", GetCwdInfo(0, 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ call assert_equal("b Xtopdir 0", GetCwdInfo(0, 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ lcd Xdir3
+ call assert_equal("c Xdir3 1", GetCwdInfo(0, 0))
+ call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), 0))
+ call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), 0))
+ call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ call assert_equal("a Xdir1 1", GetCwdInfo(bufwinnr("a"), tabpagenr()))
+ call assert_equal("b Xtopdir 0", GetCwdInfo(bufwinnr("b"), tabpagenr()))
+ call assert_equal("c Xdir3 1", GetCwdInfo(bufwinnr("c"), tabpagenr()))
+ call assert_equal(g:topdir, getcwd(-1))
+
+ tabnew x
+ new y
+ new z
+ 3wincmd w
+ call assert_equal("x Xtopdir 0", GetCwdInfo(0, 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ lcd Xdir2
+ call assert_equal("y Xdir2 1", GetCwdInfo(0, 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ wincmd W
+ lcd Xdir3
+ call assert_equal("z Xdir3 1", GetCwdInfo(0, 0))
+ call assert_equal("x Xtopdir 0", GetCwdInfo(bufwinnr("x"), 0))
+ call assert_equal("y Xdir2 1", GetCwdInfo(bufwinnr("y"), 0))
+ call assert_equal("z Xdir3 1", GetCwdInfo(bufwinnr("z"), 0))
+ call assert_equal(g:topdir, getcwd(-1))
+ let tp_nr = tabpagenr()
+ tabrewind
+ call assert_equal("x Xtopdir 0", GetCwdInfo(3, tp_nr))
+ call assert_equal("y Xdir2 1", GetCwdInfo(2, tp_nr))
+ call assert_equal("z Xdir3 1", GetCwdInfo(1, tp_nr))
+ call assert_equal(g:topdir, getcwd(-1))
+endfunc
+
+function Test_GetCwd_lcd_shellslash()
+ new
+ let root = fnamemodify('/', ':p')
+ exe 'lcd '.root
+ let cwd = getcwd()
+ if !exists('+shellslash') || &shellslash
+ call assert_equal(cwd[-1:], '/')
+ else
+ call assert_equal(cwd[-1:], '\')
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_getvar.vim b/src/nvim/testdir/test_getvar.vim
new file mode 100644
index 0000000000..d6b6b69aa8
--- /dev/null
+++ b/src/nvim/testdir/test_getvar.vim
@@ -0,0 +1,104 @@
+" Tests for getwinvar(), gettabvar() and gettabwinvar().
+func Test_var()
+ " Use strings to test for memory leaks. First, check that in an empty
+ " window, gettabvar() returns the correct value
+ let t:testvar='abcd'
+ call assert_equal('abcd', gettabvar(1, 'testvar'))
+ call assert_equal('abcd', gettabvar(1, 'testvar'))
+
+ " test for getwinvar()
+ let w:var_str = "Dance"
+ let def_str = "Chance"
+ call assert_equal('Dance', getwinvar(1, 'var_str'))
+ call assert_equal('Dance', getwinvar(1, 'var_str', def_str))
+ call assert_equal({'var_str': 'Dance'}, getwinvar(1, ''))
+ call assert_equal({'var_str': 'Dance'}, getwinvar(1, '', def_str))
+ unlet w:var_str
+ call assert_equal('Chance', getwinvar(1, 'var_str', def_str))
+ call assert_equal({}, getwinvar(1, ''))
+ call assert_equal({}, getwinvar(1, '', def_str))
+ call assert_equal('', getwinvar(9, ''))
+ call assert_equal('Chance', getwinvar(9, '', def_str))
+ call assert_equal(0, getwinvar(1, '&nu'))
+ call assert_equal(0, getwinvar(1, '&nu', 1))
+ unlet def_str
+
+ " test for gettabvar()
+ tabnew
+ tabnew
+ let t:var_list = [1, 2, 3]
+ let t:other = 777
+ let def_list = [4, 5, 6, 7]
+ tabrewind
+ call assert_equal([1, 2, 3], gettabvar(3, 'var_list'))
+ call assert_equal([1, 2, 3], gettabvar(3, 'var_list', def_list))
+ call assert_equal({'var_list': [1, 2, 3], 'other': 777}, gettabvar(3, ''))
+ call assert_equal({'var_list': [1, 2, 3], 'other': 777},
+ \ gettabvar(3, '', def_list))
+
+ tablast
+ unlet t:var_list
+ tabrewind
+ call assert_equal([4, 5, 6, 7], gettabvar(3, 'var_list', def_list))
+ call assert_equal('', gettabvar(9, ''))
+ call assert_equal([4, 5, 6, 7], gettabvar(9, '', def_list))
+ call assert_equal('', gettabvar(3, '&nu'))
+ call assert_equal([4, 5, 6, 7], gettabvar(3, '&nu', def_list))
+ unlet def_list
+ tabonly
+
+ " test for gettabwinvar()
+ tabnew
+ tabnew
+ tabprev
+ split
+ split
+ wincmd w
+ vert split
+ wincmd w
+ let w:var_dict = {'dict': 'tabwin'}
+ let def_dict = {'dict2': 'newval'}
+ wincmd b
+ tabrewind
+ call assert_equal({'dict': 'tabwin'}, gettabwinvar(2, 3, 'var_dict'))
+ call assert_equal({'dict': 'tabwin'},
+ \ gettabwinvar(2, 3, 'var_dict', def_dict))
+ call assert_equal({'var_dict': {'dict': 'tabwin'}}, gettabwinvar(2, 3, ''))
+ call assert_equal({'var_dict': {'dict': 'tabwin'}},
+ \ gettabwinvar(2, 3, '', def_dict))
+
+ tabnext
+ 3wincmd w
+ unlet w:var_dict
+ tabrewind
+ call assert_equal({'dict2': 'newval'},
+ \ gettabwinvar(2, 3, 'var_dict', def_dict))
+ call assert_equal({}, gettabwinvar(2, 3, ''))
+ call assert_equal({}, gettabwinvar(2, 3, '', def_dict))
+ call assert_equal("", gettabwinvar(2, 9, ''))
+ call assert_equal({'dict2': 'newval'}, gettabwinvar(2, 9, '', def_dict))
+ call assert_equal('', gettabwinvar(9, 3, ''))
+ call assert_equal({'dict2': 'newval'}, gettabwinvar(9, 3, '', def_dict))
+
+ unlet def_dict
+
+ call assert_equal('', gettabwinvar(2, 3, '&nux'))
+ call assert_equal(1, gettabwinvar(2, 3, '&nux', 1))
+ tabonly
+endfunc
+
+" It was discovered that "gettabvar()" would fail if called from within the
+" tabline when the user closed a window. This test confirms the fix.
+func Test_gettabvar_in_tabline()
+ let t:var_str = 'value'
+
+ set tabline=%{assert_equal('value',gettabvar(1,'var_str'))}
+ set showtabline=2
+
+ " Simulate the user opening a split (which becomes window #1) and then
+ " closing the split, which triggers the redrawing of the tabline.
+ leftabove split
+ redrawstatus!
+ close
+ redrawstatus!
+endfunc
diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim
new file mode 100644
index 0000000000..c352379697
--- /dev/null
+++ b/src/nvim/testdir/test_gf.vim
@@ -0,0 +1,61 @@
+
+" This is a test if a URL is recognized by "gf", with the cursor before and
+" after the "://". Also test ":\\".
+func Test_gf_url()
+ enew!
+ call append(0, [
+ \ "first test for URL://machine.name/tmp/vimtest2a and other text",
+ \ "second test for URL://machine.name/tmp/vimtest2b. And other text",
+ \ "third test for URL:\\\\machine.name\\vimtest2c and other text",
+ \ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text",
+ \ "fifth test for URL://machine.name/tmp?q=vim&opt=yes and other text",
+ \ ])
+ call cursor(1,1)
+ call search("^first")
+ call search("tmp")
+ call assert_equal("URL://machine.name/tmp/vimtest2a", expand("<cfile>"))
+ call search("^second")
+ call search("URL")
+ call assert_equal("URL://machine.name/tmp/vimtest2b", expand("<cfile>"))
+ if has("ebcdic")
+ set isf=@,240-249,/,.,-,_,+,,,$,:,~,\
+ else
+ set isf=@,48-57,/,.,-,_,+,,,$,:,~,\
+ endif
+ call search("^third")
+ call search("name")
+ call assert_equal("URL:\\\\machine.name\\vimtest2c", expand("<cfile>"))
+ call search("^fourth")
+ call search("URL")
+ call assert_equal("URL:\\\\machine.name\\tmp\\vimtest2d", expand("<cfile>"))
+
+ call search("^fifth")
+ call search("URL")
+ call assert_equal("URL://machine.name/tmp?q=vim&opt=yes", expand("<cfile>"))
+
+ set isf&vim
+ enew!
+endfunc
+
+func Test_gF()
+ new
+ call setline(1, ['111', '222', '333', '444'])
+ w! Xfile
+ close
+ new
+ set isfname-=:
+ call setline(1, ['one', 'Xfile:3', 'three'])
+ 2
+ call assert_fails('normal gF', 'E37:')
+ call assert_equal(2, getcurpos()[1])
+ w! Xfile2
+ normal gF
+ call assert_equal('Xfile', bufname('%'))
+ call assert_equal(3, getcurpos()[1])
+
+ set isfname&
+ call delete('Xfile')
+ call delete('Xfile2')
+ bwipe Xfile
+ bwipe Xfile2
+endfunc
diff --git a/src/nvim/testdir/test_glob2regpat.vim b/src/nvim/testdir/test_glob2regpat.vim
new file mode 100644
index 0000000000..fdf17946b6
--- /dev/null
+++ b/src/nvim/testdir/test_glob2regpat.vim
@@ -0,0 +1,30 @@
+" Test glob2regpat()
+
+func Test_invalid()
+ call assert_fails('call glob2regpat(1.33)', 'E806:')
+ call assert_fails('call glob2regpat("}")', 'E219:')
+ call assert_fails('call glob2regpat("{")', 'E220:')
+endfunc
+
+func Test_valid()
+ call assert_equal('^foo\.', glob2regpat('foo.*'))
+ call assert_equal('^foo.$', glob2regpat('foo?'))
+ call assert_equal('\.vim$', glob2regpat('*.vim'))
+ call assert_equal('^[abc]$', glob2regpat('[abc]'))
+ call assert_equal('^foo bar$', glob2regpat('foo\ bar'))
+ call assert_equal('^foo,bar$', glob2regpat('foo,bar'))
+ call assert_equal('^\(foo\|bar\)$', glob2regpat('{foo,bar}'))
+ call assert_equal('.*', glob2regpat('**'))
+
+ if exists('+shellslash')
+ call assert_equal('^foo[\/].$', glob2regpat('foo\?'))
+ call assert_equal('^\(foo[\/]\|bar\|foobar\)$', glob2regpat('{foo\,bar,foobar}'))
+ call assert_equal('^[\/]\(foo\|bar[\/]\)$', glob2regpat('\{foo,bar\}'))
+ call assert_equal('^[\/][\/]\(foo\|bar[\/][\/]\)$', glob2regpat('\\{foo,bar\\}'))
+ else
+ call assert_equal('^foo?$', glob2regpat('foo\?'))
+ call assert_equal('^\(foo,bar\|foobar\)$', glob2regpat('{foo\,bar,foobar}'))
+ call assert_equal('^{foo,bar}$', glob2regpat('\{foo,bar\}'))
+ call assert_equal('^\\\(foo\|bar\\\)$', glob2regpat('\\{foo,bar\\}'))
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_global.vim b/src/nvim/testdir/test_global.vim
new file mode 100644
index 0000000000..bdeaf8e2cf
--- /dev/null
+++ b/src/nvim/testdir/test_global.vim
@@ -0,0 +1,20 @@
+
+func Test_yank_put_clipboard()
+ new
+ call setline(1, ['a', 'b', 'c'])
+ set clipboard=unnamed
+ g/^/normal yyp
+ call assert_equal(['a', 'a', 'b', 'b', 'c', 'c'], getline(1, 6))
+
+ set clipboard&
+ bwipe!
+endfunc
+
+func Test_nested_global()
+ new
+ call setline(1, ['nothing', 'found', 'found bad', 'bad'])
+ call assert_fails('g/found/3v/bad/s/^/++/', 'E147')
+ g/found/v/bad/s/^/++/
+ call assert_equal(['nothing', '++found', 'found bad', 'bad'], getline(1, 4))
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_gn.vim b/src/nvim/testdir/test_gn.vim
new file mode 100644
index 0000000000..405425a42b
--- /dev/null
+++ b/src/nvim/testdir/test_gn.vim
@@ -0,0 +1,136 @@
+" Test for gn command
+
+func Test_gn_command()
+ set belloff=all
+ noautocmd new
+ " replace a single char by itsself quoted:
+ call setline('.', 'abc x def x ghi x jkl')
+ let @/ = 'x'
+ exe "norm! cgn'x'\<esc>.."
+ call assert_equal("abc 'x' def 'x' ghi 'x' jkl", getline('.'))
+ sil! %d_
+
+ " simple search match
+ call setline('.', 'foobar')
+ let @/ = 'foobar'
+ exe "norm! gncsearchmatch"
+ call assert_equal('searchmatch', getline('.'))
+ sil! %d _
+
+ " replace a multi-line match
+ call setline('.', ['', 'one', 'two'])
+ let @/ = 'one\_s*two\_s'
+ exe "norm! gnceins\<CR>zwei"
+ call assert_equal(['','eins','zwei'], getline(1,'$'))
+ sil! %d _
+
+ " test count argument
+ call setline('.', ['', 'abcdx | abcdx | abcdx'])
+ let @/ = '[a]bcdx'
+ exe "norm! 2gnd"
+ call assert_equal(['','abcdx | | abcdx'], getline(1,'$'))
+ sil! %d _
+
+ " join lines
+ call setline('.', ['join ', 'lines'])
+ let @/ = '$'
+ exe "norm! 0gnd"
+ call assert_equal(['join lines'], getline(1,'$'))
+ sil! %d _
+
+ " zero-width match
+ call setline('.', ['', 'zero width pattern'])
+ let @/ = '\>\zs'
+ exe "norm! 0gnd"
+ call assert_equal(['', 'zerowidth pattern'], getline(1,'$'))
+ sil! %d _
+
+ " delete first and last chars
+ call setline('.', ['delete first and last chars'])
+ let @/ = '^'
+ exe "norm! 0gnd$"
+ let @/ = '\zs'
+ exe "norm! gnd"
+ call assert_equal(['elete first and last char'], getline(1,'$'))
+ sil! %d _
+
+ " using visual mode
+ call setline('.', ['', 'uniquepattern uniquepattern'])
+ exe "norm! /[u]niquepattern/s\<cr>vlgnd"
+ call assert_equal(['', ' uniquepattern'], getline(1,'$'))
+ sil! %d _
+
+ " backwards search
+ call setline('.', ['my very excellent mother just served us nachos'])
+ let @/ = 'mother'
+ exe "norm! $cgNmongoose"
+ call assert_equal(['my very excellent mongoose just served us nachos'], getline(1,'$'))
+ sil! %d _
+
+ " search for single char
+ call setline('.', ['','for (i=0; i<=10; i++)'])
+ let @/ = 'i'
+ exe "norm! cgnj"
+ call assert_equal(['','for (j=0; i<=10; i++)'], getline(1,'$'))
+ sil! %d _
+
+ " search hex char
+ call setline('.', ['','Y'])
+ set noignorecase
+ let @/ = '\%x59'
+ exe "norm! gnd"
+ call assert_equal(['',''], getline(1,'$'))
+ sil! %d _
+
+ " test repeating gdn
+ call setline('.', ['', '1', 'Johnny', '2', 'Johnny', '3'])
+ let @/ = 'Johnny'
+ exe "norm! dgn."
+ call assert_equal(['','1', '', '2', '', '3'], getline(1,'$'))
+ sil! %d _
+
+ " test repeating gUgn
+ call setline('.', ['', '1', 'Depp', '2', 'Depp', '3'])
+ let @/ = 'Depp'
+ exe "norm! gUgn."
+ call assert_equal(['', '1', 'DEPP', '2', 'DEPP', '3'], getline(1,'$'))
+ sil! %d _
+
+ " test using look-ahead assertions
+ call setline('.', ['a:10', '', 'a:1', '', 'a:20'])
+ let @/ = 'a:0\@!\zs\d\+'
+ exe "norm! 2nygno\<esc>p"
+ call assert_equal(['a:10', '', 'a:1', '1', '', 'a:20'], getline(1,'$'))
+ sil! %d _
+
+ " test using nowrapscan
+ set nowrapscan
+ call setline(1, 'foo bar baz')
+ exe "norm! /bar/e\<cr>"
+ exe "norm! gnd"
+ call assert_equal(['foo baz'], getline(1,'$'))
+ sil! %d_
+
+ " search upwards with nowrapscan set
+ call setline('.', ['foo', 'bar', 'foo', 'baz'])
+ set nowrapscan
+ let @/ = 'foo'
+ $
+ norm! dgN
+ call assert_equal(['foo', 'bar', '', 'baz'], getline(1,'$'))
+ sil! %d_
+
+ " search using the \zs atom
+ call setline(1, [' nnoremap', '' , 'nnoremap'])
+ set wrapscan&vim
+ let @/ = '\_s\zsnnoremap'
+ $
+ norm! cgnmatch
+ call assert_equal([' nnoremap', '', 'match'], getline(1,'$'))
+ sil! %d_
+
+ set wrapscan&vim
+ set belloff&vim
+endfu
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_goto.vim b/src/nvim/testdir/test_goto.vim
new file mode 100644
index 0000000000..c0235b1707
--- /dev/null
+++ b/src/nvim/testdir/test_goto.vim
@@ -0,0 +1,373 @@
+" Test commands that jump somewhere.
+
+" Create a new buffer using "lines" and place the cursor on the word after the
+" first occurrence of return and invoke "cmd". The cursor should now be
+" positioned at the given line and col.
+func XTest_goto_decl(cmd, lines, line, col)
+ new
+ call setline(1, a:lines)
+ /return/
+ normal! W
+ execute 'norm! ' . a:cmd
+ call assert_equal(a:line, line('.'))
+ call assert_equal(a:col, col('.'))
+ quit!
+endfunc
+
+func Test_gD()
+ let lines = [
+ \ 'int x;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 1, 5)
+endfunc
+
+func Test_gD_too()
+ let lines = [
+ \ 'Filename x;',
+ \ '',
+ \ 'int Filename',
+ \ 'int func() {',
+ \ ' Filename x;',
+ \ ' return x;',
+ \ ]
+ call XTest_goto_decl('gD', lines, 1, 10)
+endfunc
+
+func Test_gD_comment()
+ let lines = [
+ \ '/* int x; */',
+ \ 'int x;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 2, 5)
+endfunc
+
+func Test_gD_inline_comment()
+ let lines = [
+ \ 'int y /* , x */;',
+ \ 'int x;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 2, 5)
+endfunc
+
+func Test_gD_string()
+ let lines = [
+ \ 'char *s[] = "x";',
+ \ 'int x = 1;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 2, 5)
+endfunc
+
+func Test_gD_string_same_line()
+ let lines = [
+ \ 'char *s[] = "x", int x = 1;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 1, 22)
+endfunc
+
+func Test_gD_char()
+ let lines = [
+ \ "char c = 'x';",
+ \ 'int x = 1;',
+ \ '',
+ \ 'int func(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gD', lines, 2, 5)
+endfunc
+
+func Test_gd()
+ let lines = [
+ \ 'int x;',
+ \ '',
+ \ 'int func(int x)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 3, 14)
+endfunc
+
+func Test_gd_not_local()
+ let lines = [
+ \ 'int func1(void)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ '',
+ \ 'int func2(int x)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 3, 10)
+endfunc
+
+func Test_gd_kr_style()
+ let lines = [
+ \ 'int func(x)',
+ \ ' int x;',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 2, 7)
+endfunc
+
+func Test_gd_missing_braces()
+ let lines = [
+ \ 'def func1(a)',
+ \ ' a + 1',
+ \ 'end',
+ \ '',
+ \ 'a = 1',
+ \ '',
+ \ 'def func2()',
+ \ ' return a',
+ \ 'end',
+ \ ]
+ call XTest_goto_decl('gd', lines, 1, 11)
+endfunc
+
+func Test_gd_comment()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' /* int x; */',
+ \ ' int x;',
+ \ ' return x;',
+ \ '}',
+ \]
+ call XTest_goto_decl('gd', lines, 4, 7)
+endfunc
+
+func Test_gd_comment_in_string()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' char *s ="//"; int x;',
+ \ ' int x;',
+ \ ' return x;',
+ \ '}',
+ \]
+ call XTest_goto_decl('gd', lines, 3, 22)
+endfunc
+
+func Test_gd_string_in_comment()
+ set comments=
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' /* " */ int x;',
+ \ ' int x;',
+ \ ' return x;',
+ \ '}',
+ \]
+ call XTest_goto_decl('gd', lines, 3, 15)
+ set comments&
+endfunc
+
+func Test_gd_inline_comment()
+ let lines = [
+ \ 'int func(/* x is an int */ int x)',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 1, 32)
+endfunc
+
+func Test_gd_inline_comment_only()
+ let lines = [
+ \ 'int func(void) /* one lonely x */',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 3, 10)
+endfunc
+
+func Test_gd_inline_comment_body()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' int y /* , x */;',
+ \ '',
+ \ ' for (/* int x = 0 */; y < 2; y++);',
+ \ '',
+ \ ' int x = 0;',
+ \ '',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 7, 7)
+endfunc
+
+func Test_gd_trailing_multiline_comment()
+ let lines = [
+ \ 'int func(int x) /* x is an int */',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 1, 14)
+endfunc
+
+func Test_gd_trailing_comment()
+ let lines = [
+ \ 'int func(int x) // x is an int',
+ \ '{',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 1, 14)
+endfunc
+
+func Test_gd_string()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' char *s = "x";',
+ \ ' int x = 1;',
+ \ '',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 4, 7)
+endfunc
+
+func Test_gd_string_only()
+ let lines = [
+ \ 'int func(void)',
+ \ '{',
+ \ ' char *s = "x";',
+ \ '',
+ \ ' return x;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('gd', lines, 5, 10)
+endfunc
+
+" Check that setting 'cursorline' does not change curswant
+func Test_cursorline_keep_col()
+ new
+ call setline(1, ['long long long line', 'short line'])
+ normal ggfi
+ let pos = getcurpos()
+ normal j
+ set cursorline
+ normal k
+ call assert_equal(pos, getcurpos())
+ bwipe!
+ set nocursorline
+endfunc
+
+func Test_gd_local_block()
+ let lines = [
+ \ ' int main()',
+ \ '{',
+ \ ' char *a = "NOT NULL";',
+ \ ' if(a)',
+ \ ' {',
+ \ ' char *b = a;',
+ \ ' printf("%s\n", b);',
+ \ ' }',
+ \ ' else',
+ \ ' {',
+ \ ' char *b = "NULL";',
+ \ ' return b;',
+ \ ' }',
+ \ '',
+ \ ' return 0;',
+ \ '}',
+ \ ]
+ call XTest_goto_decl('1gd', lines, 11, 11)
+endfunc
+
+func Test_motion_if_elif_else_endif()
+ new
+ a
+/* Test pressing % on #if, #else #elsif and #endif,
+ * with nested #if
+ */
+#if FOO
+/* ... */
+# if BAR
+/* ... */
+# endif
+#elif BAR
+/* ... */
+#else
+/* ... */
+#endif
+.
+ /#if FOO
+ norm %
+ call assert_equal([9, 1], getpos('.')[1:2])
+ norm %
+ call assert_equal([11, 1], getpos('.')[1:2])
+ norm %
+ call assert_equal([13, 1], getpos('.')[1:2])
+ norm %
+ call assert_equal([4, 1], getpos('.')[1:2])
+ /# if BAR
+ norm $%
+ call assert_equal([8, 1], getpos('.')[1:2])
+ norm $%
+ call assert_equal([6, 1], getpos('.')[1:2])
+
+ bw!
+endfunc
+
+func Test_motion_c_comment()
+ new
+ a
+/*
+ * Test pressing % on beginning/end
+ * of C comments.
+ */
+/* Another comment */
+.
+ norm gg0%
+ call assert_equal([4, 3], getpos('.')[1:2])
+ norm %
+ call assert_equal([1, 1], getpos('.')[1:2])
+ norm gg0l%
+ call assert_equal([4, 3], getpos('.')[1:2])
+ norm h%
+ call assert_equal([1, 1], getpos('.')[1:2])
+
+ norm G^
+ norm %
+ call assert_equal([5, 21], getpos('.')[1:2])
+ norm %
+ call assert_equal([5, 1], getpos('.')[1:2])
+
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_hardcopy.vim b/src/nvim/testdir/test_hardcopy.vim
index 4629d17dd2..ced13b107c 100644
--- a/src/nvim/testdir/test_hardcopy.vim
+++ b/src/nvim/testdir/test_hardcopy.vim
@@ -23,6 +23,10 @@ func Test_printoptions_parsing()
set printoptions=formfeed:y
set printoptions=
set printoptions&
+
+ call assert_fails('set printoptions=paper', 'E550:')
+ call assert_fails('set printoptions=shredder:on', 'E551:')
+ call assert_fails('set printoptions=left:no', 'E552:')
endfunc
func Test_printmbfont_parsing()
@@ -46,6 +50,7 @@ endfunc
" We don't check much of the contents.
func Test_with_syntax()
if has('postscript')
+ edit test_hardcopy.vim
set printoptions=syntax:y
syn on
hardcopy > Xhardcopy
@@ -56,3 +61,29 @@ func Test_with_syntax()
set printoptions&
endif
endfunc
+
+func Test_fname_with_spaces()
+ if !has('postscript')
+ return
+ endif
+ split t\ e\ s\ t.txt
+ call setline(1, ['just', 'some', 'text'])
+ hardcopy > %.ps
+ call assert_true(filereadable('t e s t.txt.ps'))
+ call delete('t e s t.txt.ps')
+ bwipe!
+endfunc
+
+func Test_illegal_byte()
+ if !has('postscript') || &enc != 'utf-8'
+ return
+ endif
+ new
+ " conversion of 0xff will fail, this used to cause a crash
+ call setline(1, "\xff")
+ hardcopy >Xpstest
+
+ bwipe!
+ call delete('Xpstest')
+endfunc
+
diff --git a/src/nvim/testdir/test_help.vim b/src/nvim/testdir/test_help.vim
new file mode 100644
index 0000000000..ed3181564c
--- /dev/null
+++ b/src/nvim/testdir/test_help.vim
@@ -0,0 +1,52 @@
+
+" Tests for :help
+
+func Test_help_restore_snapshot()
+ help
+ set buftype=
+ help
+ edit x
+ help
+ helpclose
+endfunc
+
+func Test_help_errors()
+ call assert_fails('help doesnotexist', 'E149:')
+ call assert_fails('help!', 'E478:')
+
+ new
+ set keywordprg=:help
+ call setline(1, " ")
+ call assert_fails('normal VK', 'E349:')
+ bwipe!
+endfunc
+
+func Test_help_keyword()
+ new
+ set keywordprg=:help
+ call setline(1, " Visual ")
+ normal VK
+ call assert_match('^Visual mode', getline('.'))
+ call assert_equal('help', &ft)
+ close
+ bwipe!
+endfunc
+
+func Test_help_local_additions()
+ call mkdir('Xruntime/doc', 'p')
+ call writefile(['*mydoc.txt* my awesome doc'], 'Xruntime/doc/mydoc.txt')
+ call writefile(['*mydoc-ext.txt* my extended awesome doc'], 'Xruntime/doc/mydoc-ext.txt')
+ let rtp_save = &rtp
+ set rtp+=./Xruntime
+ help
+ 1
+ call search('mydoc.txt')
+ call assert_equal('|mydoc.txt| my awesome doc', getline('.'))
+ 1
+ call search('mydoc-ext.txt')
+ call assert_equal('|mydoc-ext.txt| my extended awesome doc', getline('.'))
+ close
+
+ call delete('Xruntime', 'rf')
+ let &rtp = rtp_save
+endfunc
diff --git a/src/nvim/testdir/test_help_tagjump.vim b/src/nvim/testdir/test_help_tagjump.vim
index 9f9207d27d..c873487b92 100644
--- a/src/nvim/testdir/test_help_tagjump.vim
+++ b/src/nvim/testdir/test_help_tagjump.vim
@@ -18,6 +18,80 @@ func Test_help_tagjump()
call assert_true(getline('.') =~ '\*help.txt\*')
helpclose
+ help |
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*bar\*')
+ helpclose
+
+ help "*
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*quotestar\*')
+ helpclose
+
+ help sp?it
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*'.(has('win32') ? 'split()' : ':split').'\*')
+ helpclose
+
+ help :?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*:?\*')
+ helpclose
+
+ help q?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*q?\*')
+ call assert_true(expand('<cword>') == 'q?')
+ helpclose
+
+ help -?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*-?\*')
+ helpclose
+
+ help v_g?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*v_g?\*')
+ helpclose
+
+ help expr-!=?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*expr-!=?\*')
+ call assert_true(expand('<cword>') == 'expr-!=?')
+ helpclose
+
+ help expr-isnot?
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*expr-isnot?\*')
+ call assert_true(expand('<cword>') == 'expr-isnot?')
+ helpclose
+
+ help FileW*Post
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*FileWritePost\*')
+ helpclose
+
+ help `ls`
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*:ls\*')
+ helpclose
+
+ help ^X
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*CTRL-X\*')
+ helpclose
+
+ help i_^_CTRL-D
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*i_^_CTRL-D\*')
+ helpclose
+
+ exec "help \<C-V>"
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*CTRL-V\*')
+ helpclose
+
+
exec "help! ('textwidth'"
call assert_equal("help", &filetype)
call assert_true(getline('.') =~ "\\*'textwidth'\\*")
@@ -37,4 +111,162 @@ func Test_help_tagjump()
call assert_equal("help", &filetype)
call assert_true(getline('.') =~ '\*arglistid()\*')
helpclose
+
+ exec "help! 'autoindent'."
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ "\\*'autoindent'\\*")
+ helpclose
+
+ exec "help! {address}."
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*{address}\*')
+ helpclose
+
+ exusage
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*:index\*')
+ helpclose
+
+ viusage
+ call assert_equal("help", &filetype)
+ call assert_true(getline('.') =~ '\*normal-index\*')
+ helpclose
+endfunc
+
+let s:langs = ['en', 'ab', 'ja']
+
+func s:doc_config_setup()
+ let s:helpfile_save = &helpfile
+ let &helpfile="Xdir1/doc-en/doc/testdoc.txt"
+ let s:rtp_save = &rtp
+ let &rtp="Xdir1/doc-en"
+ if has('multi_lang')
+ let s:helplang_save=&helplang
+ endif
+
+ call delete('Xdir1', 'rf')
+
+ for lang in s:langs
+ if lang ==# 'en'
+ let tagfname = 'tags'
+ let docfname = 'testdoc.txt'
+ else
+ let tagfname = 'tags-' . lang
+ let docfname = 'testdoc.' . lang . 'x'
+ endif
+ let docdir = "Xdir1/doc-" . lang . "/doc"
+ call mkdir(docdir, "p")
+ call writefile(["\t*test-char*", "\t*test-col*"], docdir . '/' . docfname)
+ call writefile(["test-char\t" . docfname . "\t/*test-char*",
+ \ "test-col\t" . docfname . "\t/*test-col*"],
+ \ docdir . '/' . tagfname)
+ endfor
endfunc
+
+func s:doc_config_teardown()
+ call delete('Xdir1', 'rf')
+
+ let &helpfile = s:helpfile_save
+ let &rtp = s:rtp_save
+ if has('multi_lang')
+ let &helplang = s:helplang_save
+ endif
+endfunc
+
+func s:get_help_compl_list(cmd)
+ return getcompletion(a:cmd, 'help')
+endfunc
+
+func Test_help_complete()
+ try
+ let list = []
+ call s:doc_config_setup()
+
+ " 'helplang=' and help file lang is 'en'
+ if has('multi_lang')
+ set helplang=
+ endif
+ let list = s:get_help_compl_list("test")
+ call assert_equal(['test-col', 'test-char'], list)
+
+ if has('multi_lang')
+ " 'helplang=ab' and help file lang is 'en'
+ set helplang=ab
+ let list = s:get_help_compl_list("test")
+ call assert_equal(['test-col', 'test-char'], list)
+
+ " 'helplang=' and help file lang is 'en' and 'ab'
+ set rtp+=Xdir1/doc-ab
+ set helplang=
+ let list = s:get_help_compl_list("test")
+ call assert_equal(sort(['test-col@en', 'test-col@ab',
+ \ 'test-char@en', 'test-char@ab']), sort(list))
+
+ " 'helplang=ab' and help file lang is 'en' and 'ab'
+ set helplang=ab
+ let list = s:get_help_compl_list("test")
+ call assert_equal(sort(['test-col', 'test-col@en',
+ \ 'test-char', 'test-char@en']), sort(list))
+
+ " 'helplang=' and help file lang is 'en', 'ab' and 'ja'
+ set rtp+=Xdir1/doc-ja
+ set helplang=
+ let list = s:get_help_compl_list("test")
+ call assert_equal(sort(['test-col@en', 'test-col@ab',
+ \ 'test-col@ja', 'test-char@en',
+ \ 'test-char@ab', 'test-char@ja']), sort(list))
+
+ " 'helplang=ab' and help file lang is 'en', 'ab' and 'ja'
+ set helplang=ab
+ let list = s:get_help_compl_list("test")
+ call assert_equal(sort(['test-col', 'test-col@en',
+ \ 'test-col@ja', 'test-char',
+ \ 'test-char@en', 'test-char@ja']), sort(list))
+
+ " 'helplang=ab,ja' and help file lang is 'en', 'ab' and 'ja'
+ set helplang=ab,ja
+ let list = s:get_help_compl_list("test")
+ call assert_equal(sort(['test-col', 'test-col@ja',
+ \ 'test-col@en', 'test-char',
+ \ 'test-char@ja', 'test-char@en']), sort(list))
+ endif
+ catch
+ call assert_exception('X')
+ finally
+ call s:doc_config_teardown()
+ endtry
+endfunc
+
+func Test_help_respect_current_file_lang()
+ try
+ let list = []
+ call s:doc_config_setup()
+
+ if has('multi_lang')
+ function s:check_help_file_ext(help_keyword, ext)
+ exec 'help ' . a:help_keyword
+ call assert_equal(a:ext, expand('%:e'))
+ call feedkeys("\<C-]>", 'tx')
+ call assert_equal(a:ext, expand('%:e'))
+ pop
+ helpclose
+ endfunc
+
+ set rtp+=Xdir1/doc-ab
+ set rtp+=Xdir1/doc-ja
+
+ set helplang=ab
+ call s:check_help_file_ext('test-char', 'abx')
+ call s:check_help_file_ext('test-char@ja', 'jax')
+ set helplang=ab,ja
+ call s:check_help_file_ext('test-char@ja', 'jax')
+ call s:check_help_file_ext('test-char@en', 'txt')
+ endif
+ catch
+ call assert_exception('X')
+ finally
+ call s:doc_config_teardown()
+ endtry
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_hide.vim b/src/nvim/testdir/test_hide.vim
new file mode 100644
index 0000000000..128b8ff945
--- /dev/null
+++ b/src/nvim/testdir/test_hide.vim
@@ -0,0 +1,97 @@
+" Tests for :hide command/modifier and 'hidden' option
+
+function SetUp()
+ let s:save_hidden = &hidden
+ let s:save_bufhidden = &bufhidden
+ let s:save_autowrite = &autowrite
+ set nohidden
+ set bufhidden=
+ set noautowrite
+endfunc
+
+function TearDown()
+ let &hidden = s:save_hidden
+ let &bufhidden = s:save_bufhidden
+ let &autowrite = s:save_autowrite
+endfunc
+
+function Test_hide()
+ let orig_bname = bufname('')
+ let orig_winnr = winnr('$')
+
+ new Xf1
+ set modified
+ call assert_fails('edit Xf2')
+ bwipeout! Xf1
+
+ new Xf1
+ set modified
+ edit! Xf2
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 0], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+ bwipeout! Xf2
+
+ new Xf1
+ set modified
+ " :hide as a command
+ hide
+ call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+
+ new Xf1
+ set modified
+ " :hide as a command with trailing comment
+ hide " comment
+ call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+
+ new Xf1
+ set modified
+ " :hide as a command with bar
+ hide | new Xf2 " comment
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+ bwipeout! Xf2
+
+ new Xf1
+ set modified
+ " :hide as a modifier with trailing comment
+ hide edit Xf2 " comment
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+ bwipeout! Xf2
+
+ new Xf1
+ set modified
+ " To check that the bar is not recognized to separate commands
+ hide echo "one|two"
+ call assert_equal(['Xf1', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+
+ " set hidden
+ new Xf1
+ set hidden
+ set modified
+ edit Xf2 " comment
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf1
+ bwipeout! Xf2
+
+ " set hidden bufhidden=wipe
+ new Xf1
+ set bufhidden=wipe
+ set modified
+ hide edit! Xf2 " comment
+ call assert_equal(['Xf2', 2], [bufname(''), winnr('$')])
+ call assert_equal([0, 0], [buflisted('Xf1'), bufloaded('Xf1')])
+ bwipeout! Xf2
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_highlight.vim b/src/nvim/testdir/test_highlight.vim
new file mode 100644
index 0000000000..33df79581c
--- /dev/null
+++ b/src/nvim/testdir/test_highlight.vim
@@ -0,0 +1,535 @@
+" Tests for ":highlight" and highlighting.
+
+source view_util.vim
+
+func Test_highlight()
+ " basic test if ":highlight" doesn't crash
+ highlight
+ hi Search
+
+ " test setting colors.
+ " test clearing one color and all doesn't generate error or warning
+ silent! hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan
+ silent! hi Group2 term= cterm=
+ hi Group3 term=underline cterm=bold
+
+ let res = split(execute("hi NewGroup"), "\n")[0]
+ " filter ctermfg and ctermbg, the numbers depend on the terminal
+ let res = substitute(res, 'ctermfg=\d*', 'ctermfg=2', '')
+ let res = substitute(res, 'ctermbg=\d*', 'ctermbg=3', '')
+ call assert_equal("NewGroup xxx cterm=italic ctermfg=2 ctermbg=3",
+ \ res)
+ call assert_equal("Group2 xxx cleared",
+ \ split(execute("hi Group2"), "\n")[0])
+ call assert_equal("Group3 xxx cterm=bold",
+ \ split(execute("hi Group3"), "\n")[0])
+
+ hi clear NewGroup
+ call assert_equal("NewGroup xxx cleared",
+ \ split(execute("hi NewGroup"), "\n")[0])
+ call assert_equal("Group2 xxx cleared",
+ \ split(execute("hi Group2"), "\n")[0])
+ hi Group2 NONE
+ call assert_equal("Group2 xxx cleared",
+ \ split(execute("hi Group2"), "\n")[0])
+ hi clear
+ call assert_equal("Group3 xxx cleared",
+ \ split(execute("hi Group3"), "\n")[0])
+ call assert_fails("hi Crash term='asdf", "E475:")
+endfunc
+
+function! HighlightArgs(name)
+ return 'hi ' . substitute(split(execute('hi ' . a:name), '\n')[0], '\<xxx\>', '', '')
+endfunction
+
+function! IsColorable()
+ return has('gui_running') || str2nr(&t_Co) >= 8
+endfunction
+
+function! HiCursorLine()
+ let hiCursorLine = HighlightArgs('CursorLine')
+ if has('gui_running')
+ let guibg = matchstr(hiCursorLine, 'guibg=\w\+')
+ let hi_ul = 'hi CursorLine gui=underline guibg=NONE'
+ let hi_bg = 'hi CursorLine gui=NONE ' . guibg
+ else
+ let hi_ul = 'hi CursorLine cterm=underline ctermbg=NONE'
+ let hi_bg = 'hi CursorLine cterm=NONE ctermbg=Gray'
+ endif
+ return [hiCursorLine, hi_ul, hi_bg]
+endfunction
+
+function! Check_lcs_eol_attrs(attrs, row, col)
+ let save_lcs = &lcs
+ set list
+
+ call assert_equal(a:attrs, ScreenAttrs(a:row, a:col)[0])
+
+ set nolist
+ let &lcs = save_lcs
+endfunction
+
+func Test_highlight_eol_with_cursorline()
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 20)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ " expected:
+ " 'abcd '
+ " ^^^^ ^^^^^ no highlight
+ " ^ 'Search' highlight
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
+ call assert_equal(repeat([attrs0[0]], 5), attrs0[5:9])
+ call assert_notequal(attrs0[0], attrs0[4])
+
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'abcd '
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'abcd '
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
+ call assert_equal(attrs0[4], attrs[4])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[5], attrs[5])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_vertsplit()
+ if !has('vertsplit')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 5)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ let expected = "abcd |abcd "
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ " expected:
+ " 'abcd |abcd '
+ " ^^^^ ^^^^^^^^^ no highlight
+ " ^ 'Search' highlight
+ " ^ 'VertSplit' highlight
+ let attrs0 = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs0[0]], 4), attrs0[0:3])
+ call assert_equal(repeat([attrs0[0]], 9), attrs0[6:14])
+ call assert_notequal(attrs0[0], attrs0[4])
+ call assert_notequal(attrs0[0], attrs0[5])
+ call assert_notequal(attrs0[4], attrs0[5])
+
+ setlocal cursorline
+
+ " expected:
+ " 'abcd |abcd '
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^ 'VertSplit' highlight
+ " ^^^^^^^^^ no highlight
+
+ " underline
+ exe hi_ul
+
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ let attrs = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
+ call assert_equal(attrs0[5:14], attrs[5:14])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[0], attrs[5])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs[5], attrs[6])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 1, 15)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ let actual = ScreenLines(1, 15)[0]
+ call assert_equal(expected, actual)
+
+ let attrs = ScreenAttrs(1, 15)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[6]], 9), attrs[6:14])
+ call assert_equal(attrs0[5:14], attrs[5:14])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[0], attrs[5])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs[5], attrs[6])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_equal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 1, 15)
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_rightleft()
+ if !has('rightleft')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ setlocal rightleft
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " ' dcba'
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
+ call assert_equal(repeat([attrs[4]], 5) + [attrs[5]], attrs[0:5])
+ call assert_notequal(attrs[9], attrs[5])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[9], attrs[9])
+ call assert_notequal(attrs0[5], attrs[5])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " ' dcba'
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[9]], 4), attrs[6:9])
+ call assert_equal(repeat([attrs[4]], 5), attrs[0:4])
+ call assert_equal(attrs0[5], attrs[5])
+ call assert_notequal(attrs[9], attrs[5])
+ call assert_notequal(attrs[5], attrs[4])
+ call assert_notequal(attrs0[9], attrs[9])
+ call assert_notequal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_linewrap()
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ call setline(1, [repeat('a', 51) . 'bcd', ''])
+ call matchadd('Search', '\n')
+
+ setlocal wrap
+ normal! gg$
+ let attrs0 = ScreenAttrs(5, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'abcd '
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^^^ underline
+ let attrs = ScreenAttrs(5, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal([attrs[4]] + repeat([attrs[5]], 5), attrs[4:9])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[4], attrs[4])
+ call Check_lcs_eol_attrs(attrs, 5, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'abcd '
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(5, 10)[0]
+ call assert_equal(repeat([attrs[0]], 4), attrs[0:3])
+ call assert_equal(repeat([attrs[5]], 5), attrs[5:9])
+ call assert_equal(attrs0[4], attrs[4])
+ call assert_notequal(attrs[0], attrs[4])
+ call assert_notequal(attrs[4], attrs[5])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[5], attrs[5])
+ call Check_lcs_eol_attrs(attrs, 5, 10)
+ endif
+
+ setlocal nocursorline nowrap
+ normal! gg$
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " 'aaabcd '
+ " ^^^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[6], attrs[6])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " 'aaabcd '
+ " ^^^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 6), attrs[0:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[0], attrs[0])
+ call assert_notequal(attrs0[7], attrs[7])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+ endif
+
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_sign()
+ if !has('signs')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ call setline(1, 'abcd')
+ call matchadd('Search', '\n')
+
+ sign define Sign text=>>
+ exe 'sign place 1 line=1 name=Sign buffer=' . bufnr('')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " '>>abcd '
+ " ^^ sign
+ " ^^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_notequal(attrs[2], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[6], attrs[6])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " '>>abcd '
+ " ^^ sign
+ " ^^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[2], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[7], attrs[7])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+ endif
+
+ sign unplace 1
+ call CloseWindow()
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_with_cursorline_breakindent()
+ if !has('linebreak')
+ return
+ endif
+
+ let [hiCursorLine, hi_ul, hi_bg] = HiCursorLine()
+
+ call NewWindow('topleft 5', 10)
+ setlocal breakindent breakindentopt=min:0,shift:1 showbreak=>
+ call setline(1, ' ' . repeat('a', 9) . 'bcd')
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(2, 10)[0]
+ setlocal cursorline
+
+ " underline
+ exe hi_ul
+
+ " expected:
+ " ' >bcd '
+ " ^^^ breakindent and showbreak
+ " ^^^ underline
+ " ^ 'Search' highlight with underline
+ " ^^^ underline
+ let attrs = ScreenAttrs(2, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
+ call assert_equal([attrs[6]] + repeat([attrs[7]], 3), attrs[6:9])
+ call assert_equal(attrs0[0], attrs[0])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[2], attrs[3])
+ call assert_notequal(attrs[3], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[3], attrs[3])
+ call assert_notequal(attrs0[6], attrs[6])
+ call Check_lcs_eol_attrs(attrs, 2, 10)
+
+ if IsColorable()
+ " bg-color
+ exe hi_bg
+
+ " expected:
+ " ' >bcd '
+ " ^^^ breakindent and showbreak
+ " ^^^ bg-color of 'CursorLine'
+ " ^ 'Search' highlight
+ " ^^^ bg-color of 'CursorLine'
+ let attrs = ScreenAttrs(2, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[3]], 3), attrs[3:5])
+ call assert_equal(repeat([attrs[7]], 3), attrs[7:9])
+ call assert_equal(attrs0[0], attrs[0])
+ call assert_equal(attrs0[6], attrs[6])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[2], attrs[3])
+ call assert_notequal(attrs[3], attrs[6])
+ call assert_notequal(attrs[6], attrs[7])
+ call assert_notequal(attrs0[2], attrs[2])
+ call assert_notequal(attrs0[3], attrs[3])
+ call assert_notequal(attrs0[7], attrs[7])
+ call Check_lcs_eol_attrs(attrs, 2, 10)
+ endif
+
+ call CloseWindow()
+ set showbreak=
+ exe hiCursorLine
+endfunc
+
+func Test_highlight_eol_on_diff()
+ call setline(1, ['abcd', ''])
+ call matchadd('Search', '\n')
+ let attrs0 = ScreenAttrs(1, 10)[0]
+
+ diffthis
+ botright new
+ diffthis
+
+ " expected:
+ " ' abcd '
+ " ^^ sign
+ " ^^^^ ^^^ 'DiffAdd' highlight
+ " ^ 'Search' highlight
+ let attrs = ScreenAttrs(1, 10)[0]
+ call assert_equal(repeat([attrs[0]], 2), attrs[0:1])
+ call assert_equal(repeat([attrs[2]], 4), attrs[2:5])
+ call assert_equal(repeat([attrs[2]], 3), attrs[7:9])
+ call assert_equal(attrs0[4], attrs[6])
+ call assert_notequal(attrs[0], attrs[2])
+ call assert_notequal(attrs[0], attrs[6])
+ call assert_notequal(attrs[2], attrs[6])
+ call Check_lcs_eol_attrs(attrs, 1, 10)
+
+ bwipe!
+ diffoff
+endfunc
+
+func Test_termguicolors()
+ if !exists('+termguicolors')
+ return
+ endif
+ if has('vtp') && !has('vcon')
+ " Win32: 'guicolors' doesn't work without virtual console.
+ call assert_fails('set termguicolors', 'E954:')
+ return
+ endif
+
+ " Basic test that setting 'termguicolors' works with one color.
+ set termguicolors
+ redraw
+ set t_Co=1
+ redraw
+ set t_Co=0
+ redraw
+endfunc
diff --git a/src/nvim/testdir/test_history.vim b/src/nvim/testdir/test_history.vim
new file mode 100644
index 0000000000..16aad9889e
--- /dev/null
+++ b/src/nvim/testdir/test_history.vim
@@ -0,0 +1,111 @@
+" Tests for the history functions
+
+if !has('cmdline_hist')
+ finish
+endif
+
+set history=7
+
+function History_Tests(hist)
+ " First clear the history
+ call histadd(a:hist, 'dummy')
+ call assert_true(histdel(a:hist))
+ call assert_equal(-1, histnr(a:hist))
+ call assert_equal('', histget(a:hist))
+
+ call assert_true(histadd(a:hist, 'ls'))
+ call assert_true(histadd(a:hist, 'buffers'))
+ call assert_equal('buffers', histget(a:hist))
+ call assert_equal('ls', histget(a:hist, -2))
+ call assert_equal('ls', histget(a:hist, 1))
+ call assert_equal('', histget(a:hist, 5))
+ call assert_equal('', histget(a:hist, -5))
+ call assert_equal(2, histnr(a:hist))
+ call assert_true(histdel(a:hist, 2))
+ call assert_false(histdel(a:hist, 7))
+ call assert_equal(1, histnr(a:hist))
+ call assert_equal('ls', histget(a:hist, -1))
+
+ call assert_true(histadd(a:hist, 'buffers'))
+ call assert_true(histadd(a:hist, 'ls'))
+ call assert_equal('ls', histget(a:hist, -1))
+ call assert_equal(4, histnr(a:hist))
+
+ let a=execute('history ' . a:hist)
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history all')
+ call assert_match("^\n # .* history\n 3 buffers\n> 4 ls", a)
+
+ if len(a:hist) > 0
+ let a=execute('history ' . a:hist . ' 2')
+ call assert_match("^\n # \\S* history$", a)
+ let a=execute('history ' . a:hist . ' 3')
+ call assert_match("^\n # \\S* history\n 3 buffers$", a)
+ let a=execute('history ' . a:hist . ' 4')
+ call assert_match("^\n # \\S* history\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' 3,4')
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -1')
+ call assert_match("^\n # \\S* history\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -2')
+ call assert_match("^\n # \\S* history\n 3 buffers$", a)
+ let a=execute('history ' . a:hist . ' -2,')
+ call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a)
+ let a=execute('history ' . a:hist . ' -3')
+ call assert_match("^\n # \\S* history$", a)
+ endif
+
+ " Test for removing entries matching a pattern
+ for i in range(1, 3)
+ call histadd(a:hist, 'text_' . i)
+ endfor
+ call assert_true(histdel(a:hist, 'text_\d\+'))
+ call assert_equal('ls', histget(a:hist, -1))
+
+ " Test for freeing the entire history list
+ for i in range(1, 7)
+ call histadd(a:hist, 'text_' . i)
+ endfor
+ call histdel(a:hist)
+ for i in range(1, 7)
+ call assert_equal('', histget(a:hist, i))
+ call assert_equal('', histget(a:hist, i - 7 - 1))
+ endfor
+endfunction
+
+function Test_History()
+ for h in ['cmd', ':', '', 'search', '/', '?', 'expr', '=', 'input', '@', 'debug', '>']
+ call History_Tests(h)
+ endfor
+
+ " Negative tests
+ call assert_false(histdel('abc'))
+ call assert_equal('', histget('abc'))
+ call assert_fails('call histdel([])', 'E730:')
+ call assert_equal('', histget(10))
+ call assert_fails('call histget([])', 'E730:')
+ call assert_equal(-1, histnr('abc'))
+ call assert_fails('call histnr([])', 'E730:')
+endfunction
+
+function Test_Search_history_window()
+ new
+ call setline(1, ['a', 'b', 'a', 'b'])
+ 1
+ call feedkeys("/a\<CR>", 'xt')
+ call assert_equal('a', getline('.'))
+ 1
+ call feedkeys("/b\<CR>", 'xt')
+ call assert_equal('b', getline('.'))
+ 1
+ " select the previous /a command
+ call feedkeys("q/kk\<CR>", 'x!')
+ call assert_equal('a', getline('.'))
+ call assert_equal('a', @/)
+ bwipe!
+endfunc
+
+function Test_history_completion()
+ call feedkeys(":history \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"history / : = > ? @ all cmd debug expr input search', @:)
+endfunc
diff --git a/src/nvim/testdir/test_hlsearch.vim b/src/nvim/testdir/test_hlsearch.vim
new file mode 100644
index 0000000000..1fc7b04f88
--- /dev/null
+++ b/src/nvim/testdir/test_hlsearch.vim
@@ -0,0 +1,46 @@
+" Test for v:hlsearch
+
+function! Test_hlsearch()
+ new
+ call setline(1, repeat(['aaa'], 10))
+ set hlsearch nolazyredraw
+ " redraw is needed to make hlsearch highlight the matches
+ exe "normal! /aaa\<CR>" | redraw
+ let r1 = screenattr(1, 1)
+ nohlsearch | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ let v:hlsearch=1 | redraw
+ call assert_equal(r1, screenattr(1,1))
+ let v:hlsearch=0 | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ set hlsearch | redraw
+ call assert_equal(r1, screenattr(1,1))
+ let v:hlsearch=0 | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ exe "normal! n" | redraw
+ call assert_equal(r1, screenattr(1,1))
+ let v:hlsearch=0 | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ exe "normal! /\<CR>" | redraw
+ call assert_equal(r1, screenattr(1,1))
+ set nohls
+ exe "normal! /\<CR>" | redraw
+ call assert_notequal(r1, screenattr(1,1))
+ call assert_fails('let v:hlsearch=[]', 'E745')
+ call garbagecollect(1)
+ call getchar(1)
+ enew!
+endfunction
+
+func Test_hlsearch_eol_highlight()
+ new
+ call append(1, repeat([''], 9))
+ set hlsearch nolazyredraw
+ exe "normal! /$\<CR>" | redraw
+ let attr = screenattr(1, 1)
+ for row in range(2, 10)
+ call assert_equal(attr, screenattr(row, 1), 'in line ' . row)
+ endfor
+ set nohlsearch
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_increment.vim b/src/nvim/testdir/test_increment.vim
new file mode 100644
index 0000000000..ab11d943d9
--- /dev/null
+++ b/src/nvim/testdir/test_increment.vim
@@ -0,0 +1,782 @@
+" Tests for using Ctrl-A/Ctrl-X on visual selections
+
+func SetUp()
+ new dummy
+ set nrformats&vim
+ set nrformats+=octal
+endfunc
+
+func TearDown()
+ bwipe!
+endfunc
+
+" 1) Ctrl-A on visually selected number
+" Text:
+" foobar-10
+" Expected:
+" 1) Ctrl-A on start of line:
+" foobar-9
+" 2) Ctrl-A on visually selected "-10":
+" foobar-9
+" 3) Ctrl-A on visually selected "10":
+" foobar-11
+" 4) Ctrl-X on visually selected "-10"
+" foobar-11
+" 5) Ctrl-X on visually selected "10"
+" foobar-9
+func Test_visual_increment_01()
+ call setline(1, repeat(["foobaar-10"], 5))
+
+ call cursor(1, 1)
+ exec "norm! \<C-A>"
+ call assert_equal("foobaar-9", getline('.'))
+ call assert_equal([0, 1, 9, 0], getpos('.'))
+
+ call cursor(2, 1)
+ exec "norm! f-v$\<C-A>"
+ call assert_equal("foobaar-9", getline('.'))
+ call assert_equal([0, 2, 8, 0], getpos('.'))
+
+ call cursor(3, 1)
+ exec "norm! f1v$\<C-A>"
+ call assert_equal("foobaar-11", getline('.'))
+ call assert_equal([0, 3, 9, 0], getpos('.'))
+
+ call cursor(4, 1)
+ exec "norm! f-v$\<C-X>"
+ call assert_equal("foobaar-11", getline('.'))
+ call assert_equal([0, 4, 8, 0], getpos('.'))
+
+ call cursor(5, 1)
+ exec "norm! f1v$\<C-X>"
+ call assert_equal("foobaar-9", getline('.'))
+ call assert_equal([0, 5, 9, 0], getpos('.'))
+endfunc
+
+" 2) Ctrl-A on visually selected lines
+" Text:
+" 10
+" 20
+" 30
+" 40
+"
+" Expected:
+" 1) Ctrl-A on visually selected lines:
+" 11
+" 21
+" 31
+" 41
+"
+" 2) Ctrl-X on visually selected lines:
+" 9
+" 19
+" 29
+" 39
+func Test_visual_increment_02()
+ call setline(1, ["10", "20", "30", "40"])
+ exec "norm! GV3k$\<C-A>"
+ call assert_equal(["11", "21", "31", "41"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["10", "20", "30", "40"])
+ exec "norm! GV3k$\<C-X>"
+ call assert_equal(["9", "19", "29", "39"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 3) g Ctrl-A on visually selected lines, with non-numbers in between
+" Text:
+" 10
+"
+" 20
+"
+" 30
+"
+" 40
+"
+" Expected:
+" 1) 2 g Ctrl-A on visually selected lines:
+" 12
+"
+" 24
+"
+" 36
+"
+" 48
+" 2) 2 g Ctrl-X on visually selected lines
+" 8
+"
+" 16
+"
+" 24
+"
+" 32
+func Test_visual_increment_03()
+ call setline(1, ["10", "", "20", "", "30", "", "40"])
+ exec "norm! GV6k2g\<C-A>"
+ call assert_equal(["12", "", "24", "", "36", "", "48"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["10", "", "20", "", "30", "", "40"])
+ exec "norm! GV6k2g\<C-X>"
+ call assert_equal(["8", "", "16", "", "24", "", "32"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 4) Ctrl-A on non-number
+" Text:
+" foobar-10
+" Expected:
+" 1) visually select foobar:
+" foobar-10
+func Test_visual_increment_04()
+ call setline(1, ["foobar-10"])
+ exec "norm! vf-\<C-A>"
+ call assert_equal(["foobar-10"], getline(1, '$'))
+ " NOTE: I think this is correct behavior...
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 5) g<Ctrl-A> on letter
+" Test:
+" a
+" a
+" a
+" a
+" Expected:
+" 1) g Ctrl-A on visually selected lines
+" b
+" c
+" d
+" e
+func Test_visual_increment_05()
+ set nrformats+=alpha
+ call setline(1, repeat(["a"], 4))
+ exec "norm! GV3kg\<C-A>"
+ call assert_equal(["b", "c", "d", "e"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 6) g<Ctrl-A> on letter
+" Test:
+" z
+" z
+" z
+" z
+" Expected:
+" 1) g Ctrl-X on visually selected lines
+" y
+" x
+" w
+" v
+func Test_visual_increment_06()
+ set nrformats+=alpha
+ call setline(1, repeat(["z"], 4))
+ exec "norm! GV3kg\<C-X>"
+ call assert_equal(["y", "x", "w", "v"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 7) <Ctrl-A> on letter
+" Test:
+" 2
+" 1
+" 0
+" -1
+" -2
+"
+" Expected:
+" 1) Ctrl-A on visually selected lines
+" 3
+" 2
+" 1
+" 0
+" -1
+"
+" 2) Ctrl-X on visually selected lines
+" 1
+" 0
+" -1
+" -2
+" -3
+func Test_visual_increment_07()
+ call setline(1, ["2", "1", "0", "-1", "-2"])
+ exec "norm! GV4k\<C-A>"
+ call assert_equal(["3", "2", "1", "0", "-1"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["2", "1", "0", "-1", "-2"])
+ exec "norm! GV4k\<C-X>"
+ call assert_equal(["1", "0", "-1", "-2", "-3"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 8) Block increment on 0x9
+" Text:
+" 0x9
+" 0x9
+" Expected:
+" 1) Ctrl-A on visually block selected region (cursor at beginning):
+" 0xa
+" 0xa
+" 2) Ctrl-A on visually block selected region (cursor at end)
+" 0xa
+" 0xa
+func Test_visual_increment_08()
+ call setline(1, repeat(["0x9"], 2))
+ exec "norm! \<C-V>j$\<C-A>"
+ call assert_equal(["0xa", "0xa"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, repeat(["0x9"], 2))
+ exec "norm! gg$\<C-V>+\<C-A>"
+ call assert_equal(["0xa", "0xa"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 9) Increment and redo
+" Text:
+" 2
+" 2
+"
+" 3
+" 3
+"
+" Expected:
+" 1) 2 Ctrl-A on first 2 visually selected lines
+" 4
+" 4
+" 2) redo (.) on 3
+" 5
+" 5
+func Test_visual_increment_09()
+ call setline(1, ["2", "2", "", "3", "3", ""])
+ exec "norm! ggVj2\<C-A>"
+ call assert_equal(["4", "4", "", "3", "3", ""], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ exec "norm! 3j."
+ call assert_equal(["4", "4", "", "5", "5", ""], getline(1, '$'))
+ call assert_equal([0, 4, 1, 0], getpos('.'))
+endfunc
+
+" 10) sequentially decrement 1
+" Text:
+" 1
+" 1
+" 1
+" 1
+" Expected:
+" 1) g Ctrl-X on visually selected lines
+" 0
+" -1
+" -2
+" -3
+func Test_visual_increment_10()
+ call setline(1, repeat(["1"], 4))
+ exec "norm! GV3kg\<C-X>"
+ call assert_equal(["0", "-1", "-2", "-3"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 11) visually block selected indented lines
+" Text:
+" 1
+" 1
+" 1
+" 1
+" Expexted:
+" 1) g Ctrl-A on block selected indented lines
+" 2
+" 1
+" 3
+" 4
+func Test_visual_increment_11()
+ call setline(1, [" 1", "1", " 1", " 1"])
+ exec "norm! f1\<C-V>3jg\<C-A>"
+ call assert_equal([" 2", "1", " 3", " 4"], getline(1, '$'))
+ call assert_equal([0, 1, 5, 0], getpos('.'))
+endfunc
+
+" 12) visually selected several columns
+" Text:
+" 0 0
+" 0 0
+" 0 0
+" Expected:
+" 1) 'v' select last zero and first zeroes
+" 0 1
+" 1 0
+" 1 0
+func Test_visual_increment_12()
+ call setline(1, repeat(["0 0"], 3))
+ exec "norm! $v++\<C-A>"
+ call assert_equal(["0 1", "1 0", "1 0"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+endfunc
+
+" 13) visually selected part of columns
+" Text:
+" max: 100px
+" max: 200px
+" max: 300px
+" max: 400px
+" Expected:
+" 1) 'v' on first two numbers Ctrl-A
+" max: 110px
+" max: 220px
+" max: 330px
+" max: 400px
+" 2) 'v' on first two numbers Ctrl-X
+" max: 90px
+" max: 190px
+" max: 290px
+" max: 400px
+func Test_visual_increment_13()
+ call setline(1, ["max: 100px", "max: 200px", "max: 300px", "max: 400px"])
+ exec "norm! f1\<C-V>l2j\<C-A>"
+ call assert_equal(["max: 110px", "max: 210px", "max: 310px", "max: 400px"], getline(1, '$'))
+ call assert_equal([0, 1, 6, 0], getpos('.'))
+
+ call setline(1, ["max: 100px", "max: 200px", "max: 300px", "max: 400px"])
+ exec "norm! ggf1\<C-V>l2j\<C-X>"
+ call assert_equal(["max: 90px", "max: 190px", "max: 290px", "max: 400px"], getline(1, '$'))
+ call assert_equal([0, 1, 6, 0], getpos('.'))
+endfunc
+
+" 14) redo in block mode
+" Text:
+" 1 1
+" 1 1
+" Expected:
+" 1) Ctrl-a on first column, redo on second column
+" 2 2
+" 2 2
+func Test_visual_increment_14()
+ call setline(1, repeat(["1 1"], 2))
+ exec "norm! G\<C-V>k\<C-A>w."
+ call assert_equal(["2 2", "2 2"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+endfunc
+
+" 15) block select single numbers
+" Text:
+" 101
+" Expected:
+" 1) Ctrl-a on visually selected zero
+" 111
+"
+" Also: 019 with "01" selected increments to "029".
+func Test_visual_increment_15()
+ call setline(1, ["101"])
+ exec "norm! lv\<C-A>"
+ call assert_equal(["111"], getline(1, '$'))
+ call assert_equal([0, 1, 2, 0], getpos('.'))
+
+ call setline(1, ["019"])
+ exec "norm! 0vl\<C-A>"
+ call assert_equal("029", getline(1))
+
+ call setline(1, ["01239"])
+ exec "norm! 0vlll\<C-A>"
+ call assert_equal("01249", getline(1))
+
+ call setline(1, ["01299"])
+ exec "norm! 0vlll\<C-A>"
+ call assert_equal("1309", getline(1))
+endfunc
+
+" 16) increment right aligned numbers
+" Text:
+" 1
+" 19
+" 119
+" Expected:
+" 1) Ctrl-a on line selected region
+" 2
+" 20
+" 120
+func Test_visual_increment_16()
+ call setline(1, [" 1", " 19", " 119"])
+ exec "norm! VG\<C-A>"
+ call assert_equal([" 2", " 20", " 120"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 17) block-wise increment and redo
+" Text:
+" 100
+" 1
+"
+" 100
+" 1
+"
+" Expected:
+" 1) Ctrl-V j $ on first block, afterwards '.' on second
+" 101
+" 2
+"
+" 101
+" 2
+func Test_visual_increment_17()
+ call setline(1, [" 100", " 1", "", " 100", " 1"])
+ exec "norm! \<C-V>j$\<C-A>2j."
+ call assert_equal([" 101", " 2", "", " 101", " 1"], getline(1, '$'))
+ call assert_equal([0, 3, 1, 0], getpos('.'))
+endfunc
+
+" 18) repeat of g<Ctrl-a>
+" Text:
+" 0
+" 0
+" 0
+" 0
+"
+" Expected:
+" 1) V 4j g<ctrl-a>, repeat twice afterwards with .
+" 3
+" 6
+" 9
+" 12
+func Test_visual_increment_18()
+ call setline(1, repeat(["0"], 4))
+ exec "norm! GV3kg\<C-A>"
+ exec "norm! .."
+ call assert_equal(["3", "6", "9", "12"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 19) increment on number with nrformat including alpha
+" Text:
+" 1
+" 1a
+"
+" Expected:
+" 1) <Ctrl-V>j$ <ctrl-a>
+" 2
+" 2a
+func Test_visual_increment_19()
+ set nrformats+=alpha
+ call setline(1, ["1", "1a"])
+ exec "norm! \<C-V>G$\<C-A>"
+ call assert_equal(["2", "2a"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 20) increment a single letter
+" Text:
+" a
+"
+" Expected:
+" 1) <Ctrl-a> and cursor is on a
+" b
+func Test_visual_increment_20()
+ set nrformats+=alpha
+ call setline(1, ["a"])
+ exec "norm! \<C-A>"
+ call assert_equal(["b"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 21) block-wise increment on part of hexadecimal
+" Text:
+" 0x123456
+"
+" Expected:
+" 1) Ctrl-V f3 <ctrl-a>
+" 0x124456
+func Test_visual_increment_21()
+ call setline(1, ["0x123456"])
+ exec "norm! \<C-V>f3\<C-A>"
+ call assert_equal(["0x124456"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 22) Block increment on 0b0
+" Text:
+" 0b1
+" 0b1
+" Expected:
+" 1) Ctrl-A on visually block selected region (cursor at beginning):
+" 0b10
+" 0b10
+" 2) Ctrl-A on visually block selected region (cursor at end)
+" 0b10
+" 0b10
+func Test_visual_increment_22()
+ call setline(1, repeat(["0b1"], 2))
+ exec "norm! \<C-V>j$\<C-A>"
+ call assert_equal(repeat(["0b10"], 2), getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, repeat(["0b1"], 2))
+ exec "norm! $\<C-V>+\<C-A>"
+ call assert_equal(repeat(["0b10"], 2), getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 23) block-wise increment on part of binary
+" Text:
+" 0b1001
+"
+" Expected:
+" 1) Ctrl-V 5l <ctrl-a>
+" 0b1011
+func Test_visual_increment_23()
+ call setline(1, ["0b1001"])
+ exec "norm! \<C-V>4l\<C-A>"
+ call assert_equal(["0b1011"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 24) increment hexadecimal
+" Text:
+" 0x0b1001
+"
+" Expected:
+" 1) <ctrl-a>
+" 0x0b1002
+func Test_visual_increment_24()
+ call setline(1, ["0x0b1001"])
+ exec "norm! \<C-V>$\<C-A>"
+ call assert_equal(["0x0b1002"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 25) increment binary with nrformats including alpha
+" Text:
+" 0b1001a
+"
+" Expected:
+" 1) <ctrl-a>
+" 0b1010a
+func Test_visual_increment_25()
+ set nrformats+=alpha
+ call setline(1, ["0b1001a"])
+ exec "norm! \<C-V>$\<C-A>"
+ call assert_equal(["0b1010a"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" 26) increment binary with 32 bits
+" Text:
+" 0b11111111111111111111111111111110
+"
+" Expected:
+" 1) <ctrl-a>
+" 0b11111111111111111111111111111111
+func Test_visual_increment_26()
+ set nrformats+=alpha
+ call setline(1, ["0b11111111111111111111111111111110"])
+ exec "norm! \<C-V>$\<C-A>"
+ call assert_equal(["0b11111111111111111111111111111111"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+ set nrformats-=alpha
+endfunc
+
+" 27) increment with 'rightreft', if supported
+func Test_visual_increment_27()
+ if exists('+rightleft')
+ set rightleft
+ call setline(1, ["1234 56"])
+
+ exec "norm! $\<C-A>"
+ call assert_equal(["1234 57"], getline(1, '$'))
+ call assert_equal([0, 1, 7, 0], getpos('.'))
+
+ exec "norm! \<C-A>"
+ call assert_equal(["1234 58"], getline(1, '$'))
+ call assert_equal([0, 1, 7, 0], getpos('.'))
+ set norightleft
+ endif
+endfunc
+
+" Tab code and linewise-visual inc/dec
+func Test_visual_increment_28()
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! Vj\<C-A>"
+ call assert_equal(["x\<TAB>11", "\<TAB>0"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! ggVj\<C-X>"
+ call assert_equal(["x\<TAB>9", "\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" Tab code and linewise-visual inc/dec with 'nrformats'+=alpha
+func Test_visual_increment_29()
+ set nrformats+=alpha
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! Vj\<C-A>"
+ call assert_equal(["y\<TAB>10", "\<TAB>0"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! ggVj\<C-X>"
+ call assert_equal(["w\<TAB>10", "\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" Tab code and character-visual inc/dec
+func Test_visual_increment_30()
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! f1vjf1\<C-A>"
+ call assert_equal(["x\<TAB>11", "\<TAB>0"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! ggf1vjf1\<C-X>"
+ call assert_equal(["x\<TAB>9", "\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+endfunc
+
+" Tab code and blockwise-visual inc/dec
+func Test_visual_increment_31()
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! f1\<C-V>jl\<C-A>"
+ call assert_equal(["x\<TAB>11", "\<TAB>0"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+
+ call setline(1, ["x\<TAB>10", "\<TAB>-1"])
+ exec "norm! ggf1\<C-V>jl\<C-X>"
+ call assert_equal(["x\<TAB>9", "\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 3, 0], getpos('.'))
+endfunc
+
+" Tab code and blockwise-visual decrement with 'linebreak' and 'showbreak'
+func Test_visual_increment_32()
+ 28vnew dummy_31
+ set linebreak showbreak=+
+ call setline(1, ["x\<TAB>\<TAB>\<TAB>10", "\<TAB>\<TAB>\<TAB>\<TAB>-1"])
+ exec "norm! ggf0\<C-V>jg_\<C-X>"
+ call assert_equal(["x\<TAB>\<TAB>\<TAB>1-1", "\<TAB>\<TAB>\<TAB>\<TAB>-2"], getline(1, '$'))
+ call assert_equal([0, 1, 6, 0], getpos('.'))
+ bwipe!
+endfunc
+
+" Tab code and blockwise-visual increment with $
+func Test_visual_increment_33()
+ call setline(1, ["\<TAB>123", "456"])
+ exec "norm! gg0\<C-V>j$\<C-A>"
+ call assert_equal(["\<TAB>124", "457"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" Tab code and blockwise-visual increment and redo
+func Test_visual_increment_34()
+ call setline(1, ["\<TAB>123", " 456789"])
+ exec "norm! gg0\<C-V>j\<C-A>"
+ call assert_equal(["\<TAB>123", " 457789"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ exec "norm! .."
+ call assert_equal(["\<TAB>123", " 459789"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" Tab code, spaces and character-visual increment and redo
+func Test_visual_increment_35()
+ call setline(1, ["\<TAB>123", " 123", "\<TAB>123", "\<TAB>123"])
+ exec "norm! ggvjf3\<C-A>..."
+ call assert_equal(["\<TAB>127", " 127", "\<TAB>123", "\<TAB>123"], getline(1, '$'))
+ call assert_equal([0, 1, 2, 0], getpos('.'))
+endfunc
+
+" Tab code, spaces and blockwise-visual increment and redo
+func Test_visual_increment_36()
+ call setline(1, [" 123", "\<TAB>456789"])
+ exec "norm! G0\<C-V>kl\<C-A>"
+ call assert_equal([" 123", "\<TAB>556789"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+
+ exec "norm! ..."
+ call assert_equal([" 123", "\<TAB>856789"], getline(1, '$'))
+ call assert_equal([0, 1, 1, 0], getpos('.'))
+endfunc
+
+" block-wise increment and dot-repeat
+" Text:
+" 1 23
+" 4 56
+"
+" Expected:
+" 1) f2 Ctrl-V jl <ctrl-a>, repeat twice afterwards with .
+" 1 26
+" 4 59
+"
+" Try with and without indent.
+func Test_visual_increment_37()
+ call setline(1, [" 1 23", " 4 56"])
+ exec "norm! ggf2\<C-V>jl\<C-A>.."
+ call assert_equal([" 1 26", " 4 59"], getline(1, 2))
+
+ call setline(1, ["1 23", "4 56"])
+ exec "norm! ggf2\<C-V>jl\<C-A>.."
+ call assert_equal(["1 26", "4 59"], getline(1, 2))
+endfunc
+
+" Check redo after the normal mode increment
+func Test_visual_increment_38()
+ exec "norm! i10\<ESC>5\<C-A>."
+ call assert_equal(["20"], getline(1, '$'))
+ call assert_equal([0, 1, 2, 0], getpos('.'))
+endfunc
+
+" Test what patch 7.3.414 fixed. Ctrl-A on "000" drops the leading zeros.
+func Test_normal_increment_01()
+ call setline(1, "000")
+ exec "norm! gg0\<C-A>"
+ call assert_equal("001", getline(1))
+
+ call setline(1, "000")
+ exec "norm! gg$\<C-A>"
+ call assert_equal("001", getline(1))
+
+ call setline(1, "001")
+ exec "norm! gg0\<C-A>"
+ call assert_equal("002", getline(1))
+
+ call setline(1, "001")
+ exec "norm! gg$\<C-A>"
+ call assert_equal("002", getline(1))
+endfunc
+
+" Test a regression of patch 7.4.1087 fixed.
+func Test_normal_increment_02()
+ call setline(1, ["hello 10", "world"])
+ exec "norm! ggl\<C-A>jx"
+ call assert_equal(["hello 11", "worl"], getline(1, '$'))
+ call assert_equal([0, 2, 4, 0], getpos('.'))
+endfunc
+
+" The test35 unified to this file.
+func Test_normal_increment_03()
+ call setline(1, ["100 0x100 077 0",
+ \ "100 0x100 077 ",
+ \ "100 0x100 077 0xfF 0xFf",
+ \ "100 0x100 077 "])
+ set nrformats=octal,hex
+ exec "norm! gg\<C-A>102\<C-X>\<C-A>l\<C-X>l\<C-A>64\<C-A>128\<C-X>$\<C-X>"
+ set nrformats=octal
+ exec "norm! j0\<C-A>102\<C-X>\<C-A>l\<C-X>2\<C-A>w65\<C-A>129\<C-X>blx6lD"
+ set nrformats=hex
+ exec "norm! j0101\<C-X>l257\<C-X>\<C-A>Txldt \<C-A> \<C-X> \<C-X>"
+ set nrformats=
+ exec "norm! j0200\<C-X>l100\<C-X>w78\<C-X>\<C-A>k"
+ call assert_equal(["0 0x0ff 0000 -1",
+ \ "0 1x100 0777777",
+ \ "-1 0x0 078 0xFE 0xfe",
+ \ "-100 -100x100 000 "], getline(1, '$'))
+ call assert_equal([0, 3, 25, 0], getpos('.'))
+endfunc
+
+func Test_increment_empty_line()
+ new
+ call setline(1, ['0', '0', '0', '0', '0', '0', ''])
+ exe "normal Gvgg\<C-A>"
+ call assert_equal(['1', '1', '1', '1', '1', '1', ''], getline(1, 7))
+ bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_increment_dbcs.vim b/src/nvim/testdir/test_increment_dbcs.vim
new file mode 100644
index 0000000000..474a16feeb
--- /dev/null
+++ b/src/nvim/testdir/test_increment_dbcs.vim
@@ -0,0 +1,29 @@
+" Tests for using Ctrl-A/Ctrl-X using DBCS.
+if !has('multi_byte')
+ finish
+endif
+scriptencoding cp932
+
+func SetUp()
+ new
+ set nrformats&
+endfunc
+
+func TearDown()
+ bwipe!
+endfunc
+
+func Test_increment_dbcs_1()
+ set nrformats+=alpha
+ call setline(1, ["ŽR1"])
+ exec "norm! 0\<C-A>"
+ call assert_equal(["ŽR2"], getline(1, '$'))
+ call assert_equal([0, 1, 4, 0], getpos('.'))
+
+ call setline(1, ["‚`‚a‚b0xDE‚e"])
+ exec "norm! 0\<C-X>"
+ call assert_equal(["‚`‚a‚b0xDD‚e"], getline(1, '$'))
+ call assert_equal([0, 1, 13, 0], getpos('.'))
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim
new file mode 100644
index 0000000000..d3429617d0
--- /dev/null
+++ b/src/nvim/testdir/test_ins_complete.vim
@@ -0,0 +1,251 @@
+
+" Test for insert expansion
+func Test_ins_complete()
+ edit test_ins_complete.vim
+ " The files in the current directory interferes with the files
+ " used by this test. So use a separate directory for the test.
+ call mkdir('Xdir')
+ cd Xdir
+
+ set ff=unix
+ call writefile(["test11\t36Gepeto\t/Tag/",
+ \ "asd\ttest11file\t36G",
+ \ "Makefile\tto\trun"], 'Xtestfile')
+ call writefile(['', 'start of testfile',
+ \ 'ru',
+ \ 'run1',
+ \ 'run2',
+ \ 'STARTTEST',
+ \ 'ENDTEST',
+ \ 'end of testfile'], 'Xtestdata')
+ set ff&
+
+ enew!
+ edit Xtestdata
+ new
+ call append(0, ['#include "Xtestfile"', ''])
+ call cursor(2, 1)
+
+ set cot=
+ set cpt=.,w
+ " add-expands (word from next line) from other window
+ exe "normal iru\<C-N>\<C-N>\<C-X>\<C-N>\<Esc>\<C-A>"
+ call assert_equal('run1 run3', getline('.'))
+ " add-expands (current buffer first)
+ exe "normal o\<C-P>\<C-X>\<C-N>"
+ call assert_equal('run3 run3', getline('.'))
+ " Local expansion, ends in an empty line (unless it becomes a global
+ " expansion)
+ exe "normal o\<C-X>\<C-P>\<C-P>\<C-P>\<C-P>\<C-P>"
+ call assert_equal('', getline('.'))
+ " starts Local and switches to global add-expansion
+ exe "normal o\<C-X>\<C-P>\<C-P>\<C-X>\<C-X>\<C-N>\<C-X>\<C-N>\<C-N>"
+ call assert_equal('run1 run2', getline('.'))
+
+ set cpt=.,w,i
+ " i-add-expands and switches to local
+ exe "normal OM\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-X>\<C-X>\<C-P>"
+ call assert_equal("Makefile\tto\trun3", getline('.'))
+ " add-expands lines (it would end in an empty line if it didn't ignored
+ " itself)
+ exe "normal o\<C-X>\<C-L>\<C-X>\<C-L>\<C-P>\<C-P>"
+ call assert_equal("Makefile\tto\trun3", getline('.'))
+ call assert_equal("Makefile\tto\trun3", getline(line('.') - 1))
+
+ set cpt=kXtestfile
+ " checks k-expansion, and file expansion (use Xtest11 instead of test11,
+ " because TEST11.OUT may match first on DOS)
+ write Xtest11.one
+ write Xtest11.two
+ exe "normal o\<C-N>\<Esc>IX\<Esc>A\<C-X>\<C-F>\<C-N>"
+ call assert_equal('Xtest11.two', getline('.'))
+
+ " use CTRL-X CTRL-F to complete Xtest11.one, remove it and then use CTRL-X
+ " CTRL-F again to verify this doesn't cause trouble.
+ exe "normal oXt\<C-X>\<C-F>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<BS>\<C-X>\<C-F>"
+ call assert_equal('Xtest11.one', getline('.'))
+ normal ddk
+
+ set cpt=w
+ " checks make_cyclic in other window
+ exe "normal oST\<C-N>\<C-P>\<C-P>\<C-P>\<C-P>"
+ call assert_equal('STARTTEST', getline('.'))
+
+ set cpt=u nohid
+ " checks unloaded buffer expansion
+ only
+ exe "normal oEN\<C-N>"
+ call assert_equal('ENDTEST', getline('.'))
+ " checks adding mode abortion
+ exe "normal ounl\<C-N>\<C-X>\<C-X>\<C-P>"
+ call assert_equal('unless', getline('.'))
+
+ set cpt=t,d def=^\\k* tags=Xtestfile notagbsearch
+ " tag expansion, define add-expansion interrupted
+ exe "normal o\<C-X>\<C-]>\<C-X>\<C-D>\<C-X>\<C-D>\<C-X>\<C-X>\<C-D>\<C-X>\<C-D>\<C-X>\<C-D>\<C-X>\<C-D>"
+ call assert_equal('test11file 36Gepeto /Tag/ asd', getline('.'))
+ " t-expansion
+ exe "normal oa\<C-N>\<Esc>"
+ call assert_equal('asd', getline('.'))
+
+ %bw!
+ call delete('Xtestfile')
+ call delete('Xtest11.one')
+ call delete('Xtest11.two')
+ call delete('Xtestdata')
+ set cpt& cot& def& tags& tagbsearch& hidden&
+ cd ..
+ call delete('Xdir', 'rf')
+endfunc
+
+function! s:CompleteDone_CompleteFuncDict( findstart, base )
+ if a:findstart
+ return 0
+ endif
+
+ return {
+ \ 'words': [
+ \ {
+ \ 'word': 'aword',
+ \ 'abbr': 'wrd',
+ \ 'menu': 'extra text',
+ \ 'info': 'words are cool',
+ \ 'kind': 'W',
+ \ 'user_data': 'test'
+ \ }
+ \ ]
+ \ }
+endfunction
+
+function! s:CompleteDone_CheckCompletedItemDict()
+ call assert_equal( 'aword', v:completed_item[ 'word' ] )
+ call assert_equal( 'wrd', v:completed_item[ 'abbr' ] )
+ call assert_equal( 'extra text', v:completed_item[ 'menu' ] )
+ call assert_equal( 'words are cool', v:completed_item[ 'info' ] )
+ call assert_equal( 'W', v:completed_item[ 'kind' ] )
+ call assert_equal( 'test', v:completed_item[ 'user_data' ] )
+
+ let s:called_completedone = 1
+endfunction
+
+function Test_CompleteDoneDict()
+ au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDict()
+
+ set completefunc=<SID>CompleteDone_CompleteFuncDict
+ execute "normal a\<C-X>\<C-U>\<C-Y>"
+ set completefunc&
+
+ call assert_equal( 'test', v:completed_item[ 'user_data' ] )
+ call assert_true( s:called_completedone )
+
+ let s:called_completedone = 0
+ au! CompleteDone
+endfunc
+
+func Test_CompleteDone_undo()
+ au CompleteDone * call append(0, "prepend1")
+ new
+ call setline(1, ["line1", "line2"])
+ call feedkeys("Go\<C-X>\<C-N>\<CR>\<ESC>", "tx")
+ call assert_equal(["prepend1", "line1", "line2", "line1", ""],
+ \ getline(1, '$'))
+ undo
+ call assert_equal(["line1", "line2"], getline(1, '$'))
+ bwipe!
+ au! CompleteDone
+endfunc
+
+function! s:CompleteDone_CompleteFuncDictNoUserData( findstart, base )
+ if a:findstart
+ return 0
+ endif
+
+ return {
+ \ 'words': [
+ \ {
+ \ 'word': 'aword',
+ \ 'abbr': 'wrd',
+ \ 'menu': 'extra text',
+ \ 'info': 'words are cool',
+ \ 'kind': 'W'
+ \ }
+ \ ]
+ \ }
+endfunction
+
+function! s:CompleteDone_CheckCompletedItemDictNoUserData()
+ call assert_equal( 'aword', v:completed_item[ 'word' ] )
+ call assert_equal( 'wrd', v:completed_item[ 'abbr' ] )
+ call assert_equal( 'extra text', v:completed_item[ 'menu' ] )
+ call assert_equal( 'words are cool', v:completed_item[ 'info' ] )
+ call assert_equal( 'W', v:completed_item[ 'kind' ] )
+ call assert_equal( '', v:completed_item[ 'user_data' ] )
+
+ let s:called_completedone = 1
+endfunction
+
+function Test_CompleteDoneDictNoUserData()
+ au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemDictNoUserData()
+
+ set completefunc=<SID>CompleteDone_CompleteFuncDictNoUserData
+ execute "normal a\<C-X>\<C-U>\<C-Y>"
+ set completefunc&
+
+ call assert_equal( '', v:completed_item[ 'user_data' ] )
+ call assert_true( s:called_completedone )
+
+ let s:called_completedone = 0
+ au! CompleteDone
+endfunc
+
+function! s:CompleteDone_CompleteFuncList( findstart, base )
+ if a:findstart
+ return 0
+ endif
+
+ return [ 'aword' ]
+endfunction
+
+function! s:CompleteDone_CheckCompletedItemList()
+ call assert_equal( 'aword', v:completed_item[ 'word' ] )
+ call assert_equal( '', v:completed_item[ 'abbr' ] )
+ call assert_equal( '', v:completed_item[ 'menu' ] )
+ call assert_equal( '', v:completed_item[ 'info' ] )
+ call assert_equal( '', v:completed_item[ 'kind' ] )
+ call assert_equal( '', v:completed_item[ 'user_data' ] )
+
+ let s:called_completedone = 1
+endfunction
+
+function Test_CompleteDoneList()
+ au CompleteDone * :call <SID>CompleteDone_CheckCompletedItemList()
+
+ set completefunc=<SID>CompleteDone_CompleteFuncList
+ execute "normal a\<C-X>\<C-U>\<C-Y>"
+ set completefunc&
+
+ call assert_equal( '', v:completed_item[ 'user_data' ] )
+ call assert_true( s:called_completedone )
+
+ let s:called_completedone = 0
+ au! CompleteDone
+endfunc
+
+func Test_omni_dash()
+ func Omni(findstart, base)
+ if a:findstart
+ return 5
+ else
+ echom a:base
+ return ['-help', '-v']
+ endif
+ endfunc
+ set omnifunc=Omni
+ new
+ exe "normal Gofind -\<C-x>\<C-o>"
+ call assert_equal("\n-\nmatch 1 of 2", execute(':2mess'))
+
+ bwipe!
+ delfunc Omni
+ set omnifunc=
+endfunc
diff --git a/src/nvim/testdir/test_join.vim b/src/nvim/testdir/test_join.vim
new file mode 100644
index 0000000000..1c97414164
--- /dev/null
+++ b/src/nvim/testdir/test_join.vim
@@ -0,0 +1,35 @@
+" Test for joining lines.
+
+func Test_join_with_count()
+ new
+ call setline(1, ['one', 'two', 'three', 'four'])
+ normal J
+ call assert_equal('one two', getline(1))
+ %del
+ call setline(1, ['one', 'two', 'three', 'four'])
+ normal 10J
+ call assert_equal('one two three four', getline(1))
+ quit!
+endfunc
+
+" Tests for setting the '[,'] marks when joining lines.
+func Test_join_marks()
+ enew
+ call append(0, [
+ \ "\t\tO sodales, ludite, vos qui",
+ \ "attamen consulite per voster honur. Tua pulchra " .
+ \ "facies me fay planszer milies",
+ \ "",
+ \ "This line.",
+ \ "Should be joined with the next line",
+ \ "and with this line"])
+
+ normal gg0gqj
+ call assert_equal([0, 1, 1, 0], getpos("'["))
+ call assert_equal([0, 2, 1, 0], getpos("']"))
+
+ /^This line/;'}-join
+ call assert_equal([0, 4, 11, 0], getpos("'["))
+ call assert_equal([0, 4, 67, 0], getpos("']"))
+ enew!
+endfunc
diff --git a/src/nvim/testdir/test_jumps.vim b/src/nvim/testdir/test_jumps.vim
new file mode 100644
index 0000000000..5a3717d165
--- /dev/null
+++ b/src/nvim/testdir/test_jumps.vim
@@ -0,0 +1,11 @@
+func Test_empty_buffer()
+ new
+ insert
+a
+b
+c
+d
+.
+ call assert_equal(1, line("''"))
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_lambda.vim b/src/nvim/testdir/test_lambda.vim
new file mode 100644
index 0000000000..6e07c874b4
--- /dev/null
+++ b/src/nvim/testdir/test_lambda.vim
@@ -0,0 +1,287 @@
+" Test for lambda and closure
+
+function! Test_lambda_feature()
+ call assert_equal(1, has('lambda'))
+endfunction
+
+function! Test_lambda_with_filter()
+ let s:x = 2
+ call assert_equal([2, 3], filter([1, 2, 3], {i, v -> v >= s:x}))
+endfunction
+
+function! Test_lambda_with_map()
+ let s:x = 1
+ call assert_equal([2, 3, 4], map([1, 2, 3], {i, v -> v + s:x}))
+endfunction
+
+function! Test_lambda_with_sort()
+ call assert_equal([1, 2, 3, 4, 7], sort([3,7,2,1,4], {a, b -> a - b}))
+endfunction
+
+function! Test_lambda_with_timer()
+ if !has('timers')
+ return
+ endif
+
+ let s:n = 0
+ let s:timer_id = 0
+ function! s:Foo()
+ "let n = 0
+ let s:timer_id = timer_start(50, {-> execute("let s:n += 1 | echo s:n", "")}, {"repeat": -1})
+ endfunction
+
+ call s:Foo()
+ sleep 210ms
+ " do not collect lambda
+ call test_garbagecollect_now()
+ let m = s:n
+ sleep 230ms
+ call timer_stop(s:timer_id)
+ call assert_true(m > 1)
+ call assert_true(s:n > m + 1)
+ call assert_true(s:n < 9)
+endfunction
+
+function! Test_lambda_with_partial()
+ let l:Cb = function({... -> ['zero', a:1, a:2, a:3]}, ['one', 'two'])
+ call assert_equal(['zero', 'one', 'two', 'three'], l:Cb('three'))
+endfunction
+
+function Test_lambda_fails()
+ call assert_equal(3, {a, b -> a + b}(1, 2))
+ call assert_fails('echo {a, a -> a + a}(1, 2)', 'E15:')
+ call assert_fails('echo {a, b -> a + b)}(1, 2)', 'E15:')
+endfunc
+
+func Test_not_lambda()
+ let x = {'>' : 'foo'}
+ call assert_equal('foo', x['>'])
+endfunc
+
+function! Test_lambda_capture_by_reference()
+ let v = 1
+ let l:F = {x -> x + v}
+ let v = 2
+ call assert_equal(12, l:F(10))
+endfunction
+
+function! Test_lambda_side_effect()
+ function! s:update_and_return(arr)
+ let a:arr[1] = 5
+ return a:arr
+ endfunction
+
+ function! s:foo(arr)
+ return {-> s:update_and_return(a:arr)}
+ endfunction
+
+ let arr = [3,2,1]
+ call assert_equal([3, 5, 1], s:foo(arr)())
+endfunction
+
+function! Test_lambda_refer_local_variable_from_other_scope()
+ function! s:foo(X)
+ return a:X() " refer l:x in s:bar()
+ endfunction
+
+ function! s:bar()
+ let x = 123
+ return s:foo({-> x})
+ endfunction
+
+ call assert_equal(123, s:bar())
+endfunction
+
+function! Test_lambda_do_not_share_local_variable()
+ function! s:define_funcs()
+ let l:One = {-> split(execute("let a = 'abc' | echo a"))[0]}
+ let l:Two = {-> exists("a") ? a : "no"}
+ return [l:One, l:Two]
+ endfunction
+
+ let l:F = s:define_funcs()
+
+ call assert_equal('no', l:F[1]())
+ call assert_equal('abc', l:F[0]())
+ call assert_equal('no', l:F[1]())
+endfunction
+
+function! Test_lambda_closure_counter()
+ function! s:foo()
+ let x = 0
+ return {-> [execute("let x += 1"), x][-1]}
+ endfunction
+
+ let l:F = s:foo()
+ call garbagecollect()
+ call assert_equal(1, l:F())
+ call assert_equal(2, l:F())
+ call assert_equal(3, l:F())
+ call assert_equal(4, l:F())
+endfunction
+
+function! Test_lambda_with_a_var()
+ function! s:foo()
+ let x = 2
+ return {... -> a:000 + [x]}
+ endfunction
+ function! s:bar()
+ return s:foo()(1)
+ endfunction
+
+ call assert_equal([1, 2], s:bar())
+endfunction
+
+function! Test_lambda_call_lambda_from_lambda()
+ function! s:foo(x)
+ let l:F1 = {-> {-> a:x}}
+ return {-> l:F1()}
+ endfunction
+
+ let l:F = s:foo(1)
+ call assert_equal(1, l:F()())
+endfunction
+
+function! Test_lambda_delfunc()
+ function! s:gen()
+ let pl = l:
+ let l:Foo = {-> get(pl, "Foo", get(pl, "Bar", {-> 0}))}
+ let l:Bar = l:Foo
+ delfunction l:Foo
+ return l:Bar
+ endfunction
+
+ let l:F = s:gen()
+ call assert_fails(':call l:F()', 'E933:')
+endfunction
+
+function! Test_lambda_scope()
+ function! s:NewCounter()
+ let c = 0
+ return {-> [execute('let c += 1'), c][-1]}
+ endfunction
+
+ function! s:NewCounter2()
+ return {-> [execute('let c += 100'), c][-1]}
+ endfunction
+
+ let l:C = s:NewCounter()
+ let l:D = s:NewCounter2()
+
+ call assert_equal(1, l:C())
+ call assert_fails(':call l:D()', 'E15:') " E121: then E15:
+ call assert_equal(2, l:C())
+endfunction
+
+function! Test_lambda_share_scope()
+ function! s:New()
+ let c = 0
+ let l:Inc0 = {-> [execute('let c += 1'), c][-1]}
+ let l:Dec0 = {-> [execute('let c -= 1'), c][-1]}
+ return [l:Inc0, l:Dec0]
+ endfunction
+
+ let [l:Inc, l:Dec] = s:New()
+
+ call assert_equal(1, l:Inc())
+ call assert_equal(2, l:Inc())
+ call assert_equal(1, l:Dec())
+endfunction
+
+function! Test_lambda_circular_reference()
+ function! s:Foo()
+ let d = {}
+ let d.f = {-> d}
+ return d.f
+ endfunction
+
+ call s:Foo()
+ call garbagecollect()
+ let i = 0 | while i < 10000 | call s:Foo() | let i+= 1 | endwhile
+ call garbagecollect()
+endfunction
+
+function! Test_lambda_combination()
+ call assert_equal(2, {x -> {x -> x}}(1)(2))
+ call assert_equal(10, {y -> {x -> x(y)(10)}({y -> y})}({z -> z}))
+ call assert_equal(5.0, {x -> {y -> x / y}}(10)(2.0))
+ call assert_equal(6, {x -> {y -> {z -> x + y + z}}}(1)(2)(3))
+
+ call assert_equal(6, {x -> {f -> f(x)}}(3)({x -> x * 2}))
+ call assert_equal(6, {f -> {x -> f(x)}}({x -> x * 2})(3))
+
+ " Z combinator
+ let Z = {f -> {x -> f({y -> x(x)(y)})}({x -> f({y -> x(x)(y)})})}
+ let Fact = {f -> {x -> x == 0 ? 1 : x * f(x - 1)}}
+ call assert_equal(120, Z(Fact)(5))
+endfunction
+
+function! Test_closure_counter()
+ function! s:foo()
+ let x = 0
+ function! s:bar() closure
+ let x += 1
+ return x
+ endfunction
+ return function('s:bar')
+ endfunction
+
+ let l:F = s:foo()
+ call garbagecollect()
+ call assert_equal(1, l:F())
+ call assert_equal(2, l:F())
+ call assert_equal(3, l:F())
+ call assert_equal(4, l:F())
+endfunction
+
+function! Test_closure_unlet()
+ function! s:foo()
+ let x = 1
+ function! s:bar() closure
+ unlet x
+ endfunction
+ call s:bar()
+ return l:
+ endfunction
+
+ call assert_false(has_key(s:foo(), 'x'))
+ call garbagecollect()
+endfunction
+
+function! LambdaFoo()
+ let x = 0
+ function! LambdaBar() closure
+ let x += 1
+ return x
+ endfunction
+ return function('LambdaBar')
+endfunction
+
+func Test_closure_refcount()
+ let g:Count = LambdaFoo()
+ call test_garbagecollect_now()
+ call assert_equal(1, g:Count())
+ let g:Count2 = LambdaFoo()
+ call test_garbagecollect_now()
+ call assert_equal(1, g:Count2())
+ call assert_equal(2, g:Count())
+ call assert_equal(3, g:Count2())
+
+ delfunc LambdaFoo
+ delfunc LambdaBar
+endfunc
+
+" This test is causing a use-after-free on shutdown.
+func Test_named_function_closure()
+ func! Afoo()
+ let x = 14
+ func! s:Abar() closure
+ return x
+ endfunc
+ call assert_equal(14, s:Abar())
+ endfunc
+ call Afoo()
+ call assert_equal(14, s:Abar())
+ call garbagecollect()
+ call assert_equal(14, s:Abar())
+endfunc
diff --git a/src/nvim/testdir/test_largefile.vim b/src/nvim/testdir/test_largefile.vim
new file mode 100644
index 0000000000..3f9c2dc150
--- /dev/null
+++ b/src/nvim/testdir/test_largefile.vim
@@ -0,0 +1,34 @@
+" Tests for large files
+" This is only executed manually: "TEST_FILE=test_largefile.res make oldtest".
+" This is not run as part of "make test".
+
+func Test_largefile()
+ let fname = 'Xlarge.txt'
+
+ call delete(fname)
+ exe "e" fname
+ " Make sure that a line break is 1 byte (LF).
+ set ff=unix
+ set undolevels=-1
+ " Input 99 'A's. The line becomes 100 bytes including a line break.
+ exe "normal 99iA\<Esc>"
+ yank
+ " Put 39,999,999 times. The file becomes 4,000,000,000 bytes.
+ normal 39999999p
+ " Moving around in the file randomly.
+ normal G
+ normal 10%
+ normal 90%
+ normal 50%
+ normal gg
+ w
+ " Check if the file size is 4,000,000,000 bytes.
+ let fsize=getfsize(fname)
+ if has('num64')
+ call assert_true(fsize == 4000000000)
+ else
+ " getfsize() returns -2 if a Number is 32 bits.
+ call assert_true(fsize == -2)
+ endif
+ call delete(fname)
+endfunc
diff --git a/src/nvim/testdir/test_let.vim b/src/nvim/testdir/test_let.vim
new file mode 100644
index 0000000000..24c6ef5e01
--- /dev/null
+++ b/src/nvim/testdir/test_let.vim
@@ -0,0 +1,27 @@
+" Tests for the :let command.
+
+func Test_let()
+ " Test to not autoload when assigning. It causes internal error.
+ set runtimepath+=./sautest
+ let Test104#numvar = function('tr')
+ call assert_equal("function('tr')", string(Test104#numvar))
+
+ let a = 1
+ let b = 2
+
+ let out = execute('let a b')
+ let s = "\na #1\nb #2"
+ call assert_equal(s, out)
+
+ let out = execute('let {0 == 1 ? "a" : "b"}')
+ let s = "\nb #2"
+ call assert_equal(s, out)
+
+ let out = execute('let {0 == 1 ? "a" : "b"} a')
+ let s = "\nb #2\na #1"
+ call assert_equal(s, out)
+
+ let out = execute('let a {0 == 1 ? "a" : "b"}')
+ let s = "\na #1\nb #2"
+ call assert_equal(s, out)
+endfunc
diff --git a/src/nvim/testdir/test_lineending.vim b/src/nvim/testdir/test_lineending.vim
new file mode 100644
index 0000000000..5be3be8db3
--- /dev/null
+++ b/src/nvim/testdir/test_lineending.vim
@@ -0,0 +1,19 @@
+" Tests for saving/loading a file with some lines ending in
+" CTRL-M, some not
+func Test_lineending()
+ let l = ["this line ends in a\<CR>",
+ \ "this one doesn't",
+ \ "this one does\<CR>",
+ \ "and the last one doesn't"]
+ set fileformat=dos
+ enew!
+ call append(0, l)
+ $delete
+ write Xfile1
+ bwipe Xfile1
+ edit Xfile1
+ let t = getline(1, '$')
+ call assert_equal(l, t)
+ new | only
+ call delete('Xfile1')
+endfunc
diff --git a/src/nvim/testdir/test_lispwords.vim b/src/nvim/testdir/test_lispwords.vim
new file mode 100644
index 0000000000..4c05504cf1
--- /dev/null
+++ b/src/nvim/testdir/test_lispwords.vim
@@ -0,0 +1,82 @@
+" Tests for 'lispwords' settings being global-local
+
+set nocompatible viminfo+=nviminfo
+
+func Test_global_local_lispwords()
+ setglobal lispwords=foo,bar,baz
+ setlocal lispwords-=foo | setlocal lispwords+=quux
+ call assert_equal('foo,bar,baz', &g:lispwords)
+ call assert_equal('bar,baz,quux', &l:lispwords)
+ call assert_equal('bar,baz,quux', &lispwords)
+
+ setlocal lispwords<
+ call assert_equal('foo,bar,baz', &g:lispwords)
+ call assert_equal('foo,bar,baz', &l:lispwords)
+ call assert_equal('foo,bar,baz', &lispwords)
+endfunc
+
+func Test_lisp_indent()
+ enew!
+
+ call append(0, [
+ \ '(defun html-file (base)',
+ \ '(format nil "~(~A~).html" base))',
+ \ '',
+ \ '(defmacro page (name title &rest body)',
+ \ '(let ((ti (gensym)))',
+ \ '`(with-open-file (*standard-output*',
+ \ '(html-file ,name)',
+ \ ':direction :output',
+ \ ':if-exists :supersede)',
+ \ '(let ((,ti ,title))',
+ \ '(as title ,ti)',
+ \ '(with center ',
+ \ '(as h2 (string-upcase ,ti)))',
+ \ '(brs 3)',
+ \ ',@body))))',
+ \ '',
+ \ ';;; Utilities for generating links',
+ \ '',
+ \ '(defmacro with-link (dest &rest body)',
+ \ '`(progn',
+ \ '(format t "<a href=\"~A\">" (html-file ,dest))',
+ \ ',@body',
+ \ '(princ "</a>")))'
+ \ ])
+ set lisp
+ set lispwords&
+ let save_copt = &cpoptions
+ set cpoptions+=p
+ normal 1G=G
+
+ call assert_equal([
+ \ '(defun html-file (base)',
+ \ ' (format nil "~(~A~).html" base))',
+ \ '',
+ \ '(defmacro page (name title &rest body)',
+ \ ' (let ((ti (gensym)))',
+ \ ' `(with-open-file (*standard-output*',
+ \ ' (html-file ,name)',
+ \ ' :direction :output',
+ \ ' :if-exists :supersede)',
+ \ ' (let ((,ti ,title))',
+ \ ' (as title ,ti)',
+ \ ' (with center ',
+ \ ' (as h2 (string-upcase ,ti)))',
+ \ ' (brs 3)',
+ \ ' ,@body))))',
+ \ '',
+ \ ';;; Utilities for generating links',
+ \ '',
+ \ '(defmacro with-link (dest &rest body)',
+ \ ' `(progn',
+ \ ' (format t "<a href=\"~A\">" (html-file ,dest))',
+ \ ' ,@body',
+ \ ' (princ "</a>")))',
+ \ ''
+ \ ], getline(1, "$"))
+
+ enew!
+ let &cpoptions=save_copt
+ set nolisp
+endfunc
diff --git a/src/nvim/testdir/test_listchars.vim b/src/nvim/testdir/test_listchars.vim
new file mode 100644
index 0000000000..57ea7ca5a9
--- /dev/null
+++ b/src/nvim/testdir/test_listchars.vim
@@ -0,0 +1,63 @@
+" Tests for 'listchars' display with 'list' and :list
+
+source view_util.vim
+
+func Test_listchars()
+ enew!
+ set ff=unix
+ set list
+
+ set listchars+=tab:>-,space:.,trail:<
+ call append(0, [
+ \ ' aa ',
+ \ ' bb ',
+ \ ' cccc ',
+ \ 'dd ee ',
+ \ ' '
+ \ ])
+ let expected = [
+ \ '>-------aa>-----$',
+ \ '..bb>---<<$',
+ \ '...cccc><$',
+ \ 'dd........ee<<>-$',
+ \ '<$'
+ \ ]
+ redraw!
+ for i in range(1, 5)
+ call cursor(i, 1)
+ call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+ endfor
+
+ set listchars-=trail:<
+ let expected = [
+ \ '>-------aa>-----$',
+ \ '..bb>---..$',
+ \ '...cccc>.$',
+ \ 'dd........ee..>-$',
+ \ '.$'
+ \ ]
+ redraw!
+ for i in range(1, 5)
+ call cursor(i, 1)
+ call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+ endfor
+
+ set listchars+=trail:<
+ set nolist
+ normal ggdG
+ call append(0, [
+ \ ' fff ',
+ \ ' gg ',
+ \ ' h ',
+ \ 'iii ',
+ \ ])
+ let l = split(execute("%list"), "\n")
+ call assert_equal([
+ \ '..fff>--<<$',
+ \ '>-------gg>-----$',
+ \ '.....h>-$',
+ \ 'iii<<<<><<$', '$'], l)
+
+ enew!
+ set listchars& ff&
+endfunc
diff --git a/src/nvim/testdir/test_listdict.vim b/src/nvim/testdir/test_listdict.vim
new file mode 100644
index 0000000000..999d4dbd4a
--- /dev/null
+++ b/src/nvim/testdir/test_listdict.vim
@@ -0,0 +1,651 @@
+" Tests for the List and Dict types
+
+func TearDown()
+ " Run garbage collection after every test
+ call test_garbagecollect_now()
+endfunc
+
+" Tests for List type
+
+" List creation
+func Test_list_create()
+ " Creating List directly with different types
+ let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+ call assert_equal("[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]", string(l))
+ call assert_equal({'a' : 1}, l[-1])
+ call assert_equal(1, l[-4])
+ let x = 10
+ try
+ let x = l[-5]
+ catch
+ call assert_match('E684:', v:exception)
+ endtry
+ call assert_equal(10, x)
+endfunc
+
+" List slices
+func Test_list_slice()
+ let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+ call assert_equal([1, 'as''d', [1, 2, function('strlen')], {'a': 1}], l[:])
+ call assert_equal(['as''d', [1, 2, function('strlen')], {'a': 1}], l[1:])
+ call assert_equal([1, 'as''d', [1, 2, function('strlen')]], l[:-2])
+ call assert_equal([1, 'as''d', [1, 2, function('strlen')], {'a': 1}], l[0:8])
+ call assert_equal([], l[8:-1])
+endfunc
+
+" List identity
+func Test_list_identity()
+ let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+ let ll = l
+ let lx = copy(l)
+ call assert_true(l == ll)
+ call assert_false(l isnot ll)
+ call assert_true(l is ll)
+ call assert_true(l == lx)
+ call assert_false(l is lx)
+ call assert_true(l isnot lx)
+endfunc
+
+" removing items with :unlet
+func Test_list_unlet()
+ let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},]
+ unlet l[2]
+ call assert_equal([1, 'as''d', {'a': 1}], l)
+ let l = range(8)
+ unlet l[:3]
+ unlet l[1:]
+ call assert_equal([4], l)
+
+ " removing items out of range: silently skip items that don't exist
+ let l = [0, 1, 2, 3]
+ call assert_fails('unlet l[2:1]', 'E684')
+ let l = [0, 1, 2, 3]
+ unlet l[2:2]
+ call assert_equal([0, 1, 3], l)
+ let l = [0, 1, 2, 3]
+ unlet l[2:3]
+ call assert_equal([0, 1], l)
+ let l = [0, 1, 2, 3]
+ unlet l[2:4]
+ call assert_equal([0, 1], l)
+ let l = [0, 1, 2, 3]
+ unlet l[2:5]
+ call assert_equal([0, 1], l)
+ let l = [0, 1, 2, 3]
+ call assert_fails('unlet l[-1:2]', 'E684')
+ let l = [0, 1, 2, 3]
+ unlet l[-2:2]
+ call assert_equal([0, 1, 3], l)
+ let l = [0, 1, 2, 3]
+ unlet l[-3:2]
+ call assert_equal([0, 3], l)
+ let l = [0, 1, 2, 3]
+ unlet l[-4:2]
+ call assert_equal([3], l)
+ let l = [0, 1, 2, 3]
+ unlet l[-5:2]
+ call assert_equal([3], l)
+ let l = [0, 1, 2, 3]
+ unlet l[-6:2]
+ call assert_equal([3], l)
+endfunc
+
+" assignment to a list
+func Test_list_assign()
+ let l = [0, 1, 2, 3]
+ let [va, vb] = l[2:3]
+ call assert_equal([2, 3], [va, vb])
+ call assert_fails('let [va, vb] = l', 'E687')
+ call assert_fails('let [va, vb] = l[1:1]', 'E688')
+endfunc
+
+" test for range assign
+func Test_list_range_assign()
+ let l = [0]
+ let l[:] = [1, 2]
+ call assert_equal([1, 2], l)
+endfunc
+
+" Test removing items in list
+func Test_list_func_remove()
+ " Test removing 1 element
+ let l = [1, 2, 3, 4]
+ call assert_equal(1, remove(l, 0))
+ call assert_equal([2, 3, 4], l)
+
+ let l = [1, 2, 3, 4]
+ call assert_equal(2, remove(l, 1))
+ call assert_equal([1, 3, 4], l)
+
+ let l = [1, 2, 3, 4]
+ call assert_equal(4, remove(l, -1))
+ call assert_equal([1, 2, 3], l)
+
+ " Test removing range of element(s)
+ let l = [1, 2, 3, 4]
+ call assert_equal([3], remove(l, 2, 2))
+ call assert_equal([1, 2, 4], l)
+
+ let l = [1, 2, 3, 4]
+ call assert_equal([2, 3], remove(l, 1, 2))
+ call assert_equal([1, 4], l)
+
+ let l = [1, 2, 3, 4]
+ call assert_equal([2, 3], remove(l, -3, -2))
+ call assert_equal([1, 4], l)
+
+ " Test invalid cases
+ let l = [1, 2, 3, 4]
+ call assert_fails("call remove(l, 5)", 'E684:')
+ call assert_fails("call remove(l, 1, 5)", 'E684:')
+ call assert_fails("call remove(l, 3, 2)", 'E16:')
+ call assert_fails("call remove(1, 0)", 'E712:')
+ call assert_fails("call remove(l, l)", 'E745:')
+endfunc
+
+" Tests for Dictionary type
+
+func Test_dict()
+ " Creating Dictionary directly with different types
+ let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},}
+ call assert_equal("{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}", string(d))
+ call assert_equal('asd', d.1)
+ call assert_equal(['-1', '1', 'b'], sort(keys(d)))
+ call assert_equal(['asd', [1, 2, function('strlen')], {'a': 1}], values(d))
+ let v = []
+ for [key, val] in items(d)
+ call extend(v, [key, val])
+ unlet key val
+ endfor
+ call assert_equal(['1','asd','b',[1, 2, function('strlen')],'-1',{'a': 1}], v)
+
+ call extend(d, {3:33, 1:99})
+ call extend(d, {'b':'bbb', 'c':'ccc'}, "keep")
+ call assert_fails("call extend(d, {3:333,4:444}, 'error')", 'E737')
+ call assert_equal({'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}}, d)
+ call filter(d, 'v:key =~ ''[ac391]''')
+ call assert_equal({'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}}, d)
+endfunc
+
+" Dictionary identity
+func Test_dict_identity()
+ let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},}
+ let dd = d
+ let dx = copy(d)
+ call assert_true(d == dd)
+ call assert_false(d isnot dd)
+ call assert_true(d is dd)
+ call assert_true(d == dx)
+ call assert_false(d is dx)
+ call assert_true(d isnot dx)
+endfunc
+
+" removing items with :unlet
+func Test_dict_unlet()
+ let d = {'b':'bbb', '1': 99, '3': 33, '-1': {'a': 1}}
+ unlet d.b
+ unlet d[-1]
+ call assert_equal({'1': 99, '3': 33}, d)
+endfunc
+
+" manipulating a big Dictionary (hashtable.c has a border of 1000 entries)
+func Test_dict_big()
+ let d = {}
+ for i in range(1500)
+ let d[i] = 3000 - i
+ endfor
+ call assert_equal([3000, 2900, 2001, 1600, 1501], [d[0], d[100], d[999], d[1400], d[1499]])
+ let str = ''
+ try
+ let n = d[1500]
+ catch
+ let str=substitute(v:exception, '\v(.{14}).*( \d{4}).*', '\1\2', '')
+ endtry
+ call assert_equal('Vim(let):E716: 1500', str)
+
+ " lookup each items
+ for i in range(1500)
+ call assert_equal(3000 - i, d[i])
+ endfor
+ let i += 1
+
+ " delete even items
+ while i >= 2
+ let i -= 2
+ unlet d[i]
+ endwhile
+ call assert_equal('NONE', get(d, 1500 - 100, 'NONE'))
+ call assert_equal(2999, d[1])
+
+ " delete odd items, checking value, one intentionally wrong
+ let d[33] = 999
+ let i = 1
+ while i < 1500
+ if i != 33
+ call assert_equal(3000 - i, d[i])
+ else
+ call assert_equal(999, d[i])
+ endif
+ unlet d[i]
+ let i += 2
+ endwhile
+ call assert_equal({}, d)
+ unlet d
+endfunc
+
+" Dictionary function
+func Test_dict_func()
+ let d = {}
+ func d.func(a) dict
+ return a:a . len(self.data)
+ endfunc
+ let d.data = [1,2,3]
+ call assert_equal('len: 3', d.func('len: '))
+ let x = d.func('again: ')
+ call assert_equal('again: 3', x)
+ let Fn = d.func
+ call assert_equal('xxx3', Fn('xxx'))
+endfunc
+
+" Function in script-local List or Dict
+func Test_script_local_dict_func()
+ let g:dict = {}
+ function g:dict.func() dict
+ return 'g:dict.func' . self.foo[1] . self.foo[0]('asdf')
+ endfunc
+ let g:dict.foo = ['-', 2, 3]
+ call insert(g:dict.foo, function('strlen'))
+ call assert_equal('g:dict.func-4', g:dict.func())
+ unlet g:dict
+endfunc
+
+" Test removing items in la dictionary
+func Test_dict_func_remove()
+ let d = {1:'a', 2:'b', 3:'c'}
+ call assert_equal('b', remove(d, 2))
+ call assert_equal({1:'a', 3:'c'}, d)
+
+ call assert_fails("call remove(d, 1, 2)", 'E118:')
+ call assert_fails("call remove(d, 'a')", 'E716:')
+ call assert_fails("call remove(d, [])", 'E730:')
+endfunc
+
+" Nasty: remove func from Dict that's being called (works)
+func Test_dict_func_remove_in_use()
+ let d = {1:1}
+ func d.func(a)
+ return "a:" . a:a
+ endfunc
+ let expected = 'a:' . string(get(d, 'func'))
+ call assert_equal(expected, d.func(string(remove(d, 'func'))))
+endfunc
+
+" Nasty: deepcopy() dict that refers to itself (fails when noref used)
+func Test_dict_deepcopy()
+ let d = {1:1, 2:2}
+ let l = [4, d, 6]
+ let d[3] = l
+ let dc = deepcopy(d)
+ call assert_fails('call deepcopy(d, 1)', 'E698')
+ let l2 = [0, l, l, 3]
+ let l[1] = l2
+ let l3 = deepcopy(l2)
+ call assert_true(l3[1] is l3[2])
+endfunc
+
+" Locked variables
+func Test_list_locked_var()
+ let expected = [
+ \ [['0000-000', 'ppppppp'],
+ \ ['0000-000', 'ppppppp'],
+ \ ['0000-000', 'ppppppp']],
+ \ [['1000-000', 'ppppppF'],
+ \ ['0000-000', 'ppppppp'],
+ \ ['0000-000', 'ppppppp']],
+ \ [['1100-100', 'ppFppFF'],
+ \ ['0000-000', 'ppppppp'],
+ \ ['0000-000', 'ppppppp']],
+ \ [['1110-110', 'pFFpFFF'],
+ \ ['0010-010', 'pFppFpp'],
+ \ ['0000-000', 'ppppppp']],
+ \ [['1111-111', 'FFFFFFF'],
+ \ ['0011-011', 'FFpFFpp'],
+ \ ['0000-000', 'ppppppp']]
+ \ ]
+ for depth in range(5)
+ for u in range(3)
+ unlet! l
+ let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}]
+ exe "lockvar " . depth . " l"
+ if u == 1
+ exe "unlockvar l"
+ elseif u == 2
+ exe "unlockvar " . depth . " l"
+ endif
+ let ps = islocked("l").islocked("l[1]").islocked("l[1][1]").islocked("l[1][1][0]").'-'.islocked("l[2]").islocked("l[2]['6']").islocked("l[2]['6'][7]")
+ call assert_equal(expected[depth][u][0], ps)
+ let ps = ''
+ try
+ let l[1][1][0] = 99
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[1][1] = [99]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[1] = [99]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[2]['6'][7] = 99
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[2][6] = {99: 99}
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l[2] = {99: 99}
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ let l = [99]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ call assert_equal(expected[depth][u][1], ps)
+ endfor
+ endfor
+endfunc
+
+" Unletting locked variables
+func Test_list_locked_var_unlet()
+ let expected = [
+ \ [['0000-000', 'ppppppp'],
+ \ ['0000-000', 'ppppppp'],
+ \ ['0000-000', 'ppppppp']],
+ \ [['1000-000', 'ppFppFp'],
+ \ ['0000-000', 'ppppppp'],
+ \ ['0000-000', 'ppppppp']],
+ \ [['1100-100', 'pFFpFFp'],
+ \ ['0000-000', 'ppppppp'],
+ \ ['0000-000', 'ppppppp']],
+ \ [['1110-110', 'FFFFFFp'],
+ \ ['0010-010', 'FppFppp'],
+ \ ['0000-000', 'ppppppp']],
+ \ [['1111-111', 'FFFFFFp'],
+ \ ['0011-011', 'FppFppp'],
+ \ ['0000-000', 'ppppppp']]
+ \ ]
+
+ for depth in range(5)
+ for u in range(3)
+ unlet! l
+ let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}]
+ exe "lockvar " . depth . " l"
+ if u == 1
+ exe "unlockvar l"
+ elseif u == 2
+ exe "unlockvar " . depth . " l"
+ endif
+ let ps = islocked("l").islocked("l[1]").islocked("l[1][1]").islocked("l[1][1][0]").'-'.islocked("l[2]").islocked("l[2]['6']").islocked("l[2]['6'][7]")
+ call assert_equal(expected[depth][u][0], ps)
+ let ps = ''
+ try
+ unlet l[2]['6'][7]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[2][6]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[2]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[1][1][0]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[1][1]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l[1]
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ try
+ unlet l
+ let ps .= 'p'
+ catch
+ let ps .= 'F'
+ endtry
+ call assert_equal(expected[depth][u][1], ps)
+ endfor
+ endfor
+endfunc
+
+" Locked variables and :unlet or list / dict functions
+
+" No :unlet after lock on dict:
+func Test_dict_lock_unlet()
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar 1 d
+ call assert_fails('unlet d.a', 'E741')
+endfunc
+
+" unlet after lock on dict item
+func Test_dict_item_lock_unlet()
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar d.a
+ unlet d.a
+ call assert_equal({'b' : 100}, d)
+endfunc
+
+" filter() after lock on dict item
+func Test_dict_lock_filter()
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar d.a
+ call filter(d, 'v:key != "a"')
+ call assert_equal({'b' : 100}, d)
+endfunc
+
+" map() after lock on dict
+func Test_dict_lock_map()
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar 1 d
+ call map(d, 'v:val + 200')
+ call assert_equal({'a' : 299, 'b' : 300}, d)
+endfunc
+
+" No extend() after lock on dict item
+func Test_dict_lock_extend()
+ unlet! d
+ let d = {'a': 99, 'b': 100}
+ lockvar d.a
+ call assert_fails("call extend(d, {'a' : 123})", 'E741')
+ call assert_equal({'a': 99, 'b': 100}, d)
+endfunc
+
+" No remove() of write-protected scope-level variable
+func! Tfunc(this_is_a_long_parameter_name)
+ call assert_fails("call remove(a:, 'this_is_a_long_parameter_name')", 'E795')
+endfun
+func Test_dict_scope_var_remove()
+ call Tfunc('testval')
+endfunc
+
+" No extend() of write-protected scope-level variable
+func! Tfunc(this_is_a_long_parameter_name)
+ call assert_fails("call extend(a:, {'this_is_a_long_parameter_name': 1234})", 'E742')
+endfunc
+func Test_dict_scope_var_extend()
+ call Tfunc('testval')
+endfunc
+
+" No :unlet of variable in locked scope
+func Test_lock_var_unlet()
+ let b:testvar = 123
+ lockvar 1 b:
+ call assert_fails('unlet b:testvar', 'E741:')
+ unlockvar 1 b:
+ unlet! b:testvar
+endfunc
+
+" No :let += of locked list variable
+func Test_let_lock_list()
+ let l = ['a', 'b', 3]
+ lockvar 1 l
+ call assert_fails("let l += ['x']", 'E741:')
+ call assert_equal(['a', 'b', 3], l)
+
+ unlet l
+ let l = [1, 2, 3, 4]
+ lockvar! l
+ call assert_equal([1, 2, 3, 4], l)
+ unlockvar l[1]
+ call assert_fails('unlet l[0:1]', 'E741:')
+ call assert_equal([1, 2, 3, 4], l)
+ call assert_fails('unlet l[1:2]', 'E741:')
+ call assert_equal([1, 2, 3, 4], l)
+ unlockvar l[1]
+ call assert_fails('let l[0:1] = [0, 1]', 'E741:')
+ call assert_equal([1, 2, 3, 4], l)
+ call assert_fails('let l[1:2] = [0, 1]', 'E741:')
+ call assert_equal([1, 2, 3, 4], l)
+ unlet l
+endfunc
+
+" lockvar/islocked() triggering script autoloading
+func Test_lockvar_script_autoload()
+ let old_rtp = &rtp
+ set rtp+=./sautest
+ lockvar g:footest#x
+ unlockvar g:footest#x
+ call assert_equal(-1, islocked('g:footest#x'))
+ call assert_equal(0, exists('g:footest#x'))
+ call assert_equal(1, g:footest#x)
+ let &rtp = old_rtp
+endfunc
+
+" a:000 function argument test
+func s:arg_list_test(...)
+ call assert_fails('let a:000 = [1, 2]', 'E46:')
+ call assert_fails('let a:000[0] = 9', 'E742:')
+ call assert_fails('let a:000[2] = [9, 10]', 'E742:')
+ call assert_fails('let a:000[3] = {9 : 10}', 'E742:')
+
+ " now the tests that should pass
+ let a:000[2][1] = 9
+ call extend(a:000[2], [5, 6])
+ let a:000[3][5] = 8
+ let a:000[3]['a'] = 12
+ call assert_equal([1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}], a:000)
+endfunc
+
+func Test_func_arg_list()
+ call s:arg_list_test(1, 2, [3, 4], {5: 6})
+endfunc
+
+" Tests for reverse(), sort(), uniq()
+func Test_reverse_sort_uniq()
+ let l = ['-0', 'A11', 2, 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5]
+ call assert_equal(['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5], uniq(copy(l)))
+ call assert_equal([1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'], reverse(l))
+ call assert_equal([1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'], reverse(reverse(l)))
+ call assert_equal(['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]], sort(l))
+ call assert_equal([[0, 1, 2], [0, 1, 2], 4, 2, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'foo', 'A11', '-0'], reverse(sort(l)))
+ call assert_equal(['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]], sort(reverse(sort(l))))
+ call assert_equal(['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]], uniq(sort(l)))
+
+ let l=[7, 9, 'one', 18, 12, 22, 'two', 10.0e-16, -1, 'three', 0xff, 0.22, 'four']
+ call assert_equal([-1, 'one', 'two', 'three', 'four', 1.0e-15, 0.22, 7, 9, 12, 18, 22, 255], sort(copy(l), 'n'))
+
+ let l=[7, 9, 18, 12, 22, 10.0e-16, -1, 0xff, 0, -0, 0.22, 'bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', {}, []]
+ call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1))
+ call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i'))
+ call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l)))
+endfunc
+
+" splitting a string to a List
+func Test_str_split()
+ call assert_equal(['aa', 'bb'], split(' aa bb '))
+ call assert_equal(['aa', 'bb'], split(' aa bb ', '\W\+', 0))
+ call assert_equal(['', 'aa', 'bb', ''], split(' aa bb ', '\W\+', 1))
+ call assert_equal(['', '', 'aa', '', 'bb', '', ''], split(' aa bb ', '\W', 1))
+ call assert_equal(['aa', '', 'bb'], split(':aa::bb:', ':', 0))
+ call assert_equal(['', 'aa', '', 'bb', ''], split(':aa::bb:', ':', 1))
+ call assert_equal(['aa', '', 'bb', 'cc', ''], split('aa,,bb, cc,', ',\s*', 1))
+ call assert_equal(['a', 'b', 'c'], split('abc', '\zs'))
+ call assert_equal(['', 'a', '', 'b', '', 'c', ''], split('abc', '\zs', 1))
+endfunc
+
+" compare recursively linked list and dict
+func Test_listdict_compare()
+ let l = [1, 2, 3, 4]
+ let d = {'1': 1, '2': l, '3': 3}
+ let l[1] = d
+ call assert_true(l == l)
+ call assert_true(d == d)
+ call assert_false(l != deepcopy(l))
+ call assert_false(d != deepcopy(d))
+endfunc
+
+ " compare complex recursively linked list and dict
+func Test_listdict_compare_complex()
+ let l = []
+ call add(l, l)
+ let dict4 = {"l": l}
+ call add(dict4.l, dict4)
+ let lcopy = deepcopy(l)
+ let dict4copy = deepcopy(dict4)
+ call assert_true(l == lcopy)
+ call assert_true(dict4 == dict4copy)
+endfunc
+
+func Test_listdict_extend()
+ " Pass the same List to extend()
+ let l = [1, 2, 3, 4, 5]
+ call extend(l, l)
+ call assert_equal([1, 2, 3, 4, 5, 1, 2, 3, 4, 5], l)
+
+ " Pass the same Dict to extend()
+ let d = { 'a': {'b': 'B'}}
+ call extend(d, d)
+ call assert_equal({'a': {'b': 'B'}}, d)
+
+ " Pass the same Dict to extend() with "error"
+ call assert_fails("call extend(d, d, 'error')", 'E737:')
+ call assert_equal({'a': {'b': 'B'}}, d)
+endfunc
diff --git a/src/nvim/testdir/test_listlbr.vim b/src/nvim/testdir/test_listlbr.vim
new file mode 100644
index 0000000000..d28dbc444c
--- /dev/null
+++ b/src/nvim/testdir/test_listlbr.vim
@@ -0,0 +1,238 @@
+" Test for linebreak and list option (non-utf8)
+
+" Nvim does not allow setting 'encoding', so skip this test.
+finish
+
+set encoding=latin1
+scriptencoding latin1
+
+if !exists("+linebreak") || !has("conceal")
+ finish
+endif
+
+source view_util.vim
+
+function s:screen_lines(lnum, width) abort
+ return ScreenLines(a:lnum, a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+ call assert_equal(join(a:expect, "\n"), join(a:actual, "\n"))
+endfunction
+
+function s:test_windows(...)
+ call NewWindow(10, 20)
+ setl ts=8 sw=4 sts=4 linebreak sbr= wrap
+ exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+ call CloseWindow()
+ exe get(a:000, 0, '')
+endfunction
+
+func Test_set_linebreak()
+ call s:test_windows('setl ts=4 sbr=+')
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ " abcdef ",
+\ "+hijklmn ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_linebreak_with_list()
+ call s:test_windows('setl ts=4 sbr=+ list listchars=')
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "^Iabcdef hijklmn^I ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_linebreak_with_nolist()
+ call s:test_windows('setl ts=4 sbr=+ nolist')
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ")
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ " abcdef ",
+\ "+hijklmn ",
+\ "+pqrstuvwxyz_1060ABC",
+\ "+DEFGHIJKLMNOP ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_should_break()
+ call s:test_windows('setl sbr=+ nolist')
+ call setline(1, "1\t" . repeat('a', winwidth(0)-2))
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "1 ",
+\ "+aaaaaaaaaaaaaaaaaa ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_linebreak_with_conceal()
+ call s:test_windows('setl cpo&vim sbr=+ list conceallevel=2 concealcursor=nv listchars=tab:ab')
+ call setline(1, "_S_\t bla")
+ syn match ConcealVar contained /_/ conceal
+ syn match All /.*/ contains=ConcealVar
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "Sabbbbbb bla ",
+\ "~ ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_virtual_block()
+ call s:test_windows('setl sbr=+')
+ call setline(1, [
+\ "REMOVE: this not",
+\ "REMOVE: aaaaaaaaaaaaa",
+\ ])
+ exe "norm! 1/^REMOVE:"
+ exe "norm! 0\<C-V>jf x"
+ $put
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "this not ",
+\ "aaaaaaaaaaaaa ",
+\ "REMOVE: ",
+\ "REMOVE: ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_virtual_block_and_vbA()
+ call s:test_windows()
+ call setline(1, "long line: " . repeat("foobar ", 40) . "TARGET at end")
+ exe "norm! $3B\<C-v>eAx\<Esc>"
+ let lines = s:screen_lines([1, 10], winwidth(0))
+ let expect = [
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar foobar ",
+\ "foobar TARGETx at ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_virtual_char_and_block()
+ call s:test_windows()
+ call setline(1, "1111-1111-1111-11-1111-1111-1111")
+ exe "norm! 0f-lv3lc2222\<Esc>bgj."
+ let lines = s:screen_lines([1, 2], winwidth(0))
+ let expect = [
+\ "1111-2222-1111-11- ",
+\ "1111-2222-1111 ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_undo_after_block_visual()
+ call s:test_windows()
+ call setline(1, ["aaa", "aaa", "a"])
+ exe "norm! gg\<C-V>2j~e."
+ let lines = s:screen_lines([1, 3], winwidth(0))
+ let expect = [
+\ "AaA ",
+\ "AaA ",
+\ "A ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_norm_after_block_visual()
+ call s:test_windows()
+ call setline(1, ["abcd{ef", "ghijklm", "no}pgrs"])
+ exe "norm! ggf{\<C-V>\<C-V>c%"
+ let lines = s:screen_lines([1, 3], winwidth(0))
+ let expect = [
+\ "abcdpgrs ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_block_replace_after_wrapping()
+ call s:test_windows()
+ call setline(1, repeat("a", 150))
+ exe "norm! 0yypk147|\<C-V>jr0"
+ call assert_equal(repeat("a", 146) . "0aaa", getline(1))
+ call assert_equal(repeat("a", 146) . "0aaa", getline(2))
+ let lines = s:screen_lines([1, 10], winwidth(0))
+ let expect = [
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aaaaaa0aaa ",
+\ "@ ",
+\ "@ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_list_with_listchars()
+ call s:test_windows('setl list listchars=space:_,trail:-,tab:>-,eol:$')
+ call setline(1, "a aaaaaaaaaaaaaaaaaaaaaa\ta ")
+ let lines = s:screen_lines([1, 3], winwidth(0))
+ let expect = [
+\ "a_ ",
+\ "aaaaaaaaaaaaaaaaaaaa",
+\ "aa>-----a-$ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_list_with_tab_and_skipping_first_chars()
+ call s:test_windows('setl list listchars=tab:>- ts=70 nowrap')
+ call setline(1, ["iiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa"])
+ call cursor(4,64)
+ norm! 2zl
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "---------------aaaaa",
+\ "---------------aaaaa",
+\ "---------------aaaaa",
+\ "iiiiiiiii>-----aaaaa",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfu
diff --git a/src/nvim/testdir/test_listlbr_utf8.vim b/src/nvim/testdir/test_listlbr_utf8.vim
new file mode 100644
index 0000000000..b648a3361b
--- /dev/null
+++ b/src/nvim/testdir/test_listlbr_utf8.vim
@@ -0,0 +1,271 @@
+" Test for linebreak and list option in utf-8 mode
+
+set encoding=utf-8
+scriptencoding utf-8
+
+if !exists("+linebreak") || !has("conceal") || !has("signs")
+ finish
+endif
+
+source view_util.vim
+
+function s:screen_lines(lnum, width) abort
+ return ScreenLines(a:lnum, a:width)
+endfunction
+
+function! s:compare_lines(expect, actual)
+ call assert_equal(a:expect, a:actual)
+endfunction
+
+function s:screen_attr(lnum, chars, ...) abort
+ let line = getline(a:lnum)
+ let attr = []
+ let prefix = get(a:000, 0, 0)
+ for i in range(a:chars[0], a:chars[1])
+ let scol = strdisplaywidth(strcharpart(line, 0, i-1)) + 1
+ let attr += [screenattr(a:lnum, scol + prefix)]
+ endfor
+ return attr
+endfunction
+
+function s:test_windows(...)
+ call NewWindow(10, 20)
+ setl ts=4 sw=4 sts=4 linebreak sbr=+ wrap
+ exe get(a:000, 0, '')
+endfunction
+
+function s:close_windows(...)
+ call CloseWindow()
+ exe get(a:000, 0, '')
+endfunction
+
+func Test_linebreak_with_fancy_listchars()
+ call s:test_windows("setl list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
+ redraw!
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "▕———abcdef ",
+\ "+hijklmn▕——— ",
+\ "+pqrstuvwxyzâ£1060ABC",
+\ "+DEFGHIJKLMNOPˑ¶ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_nolinebreak_with_list()
+ call s:test_windows("setl nolinebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+ call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ")
+ redraw!
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ "▕———abcdef hijklmn▕—",
+\ "+pqrstuvwxyzâ£1060ABC",
+\ "+DEFGHIJKLMNOPˑ¶ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_linebreak_with_nolist()
+ call s:test_windows('setl nolist')
+ call setline(1, "\t*mask = nil;")
+ redraw!
+ let lines = s:screen_lines([1, 4], winwidth(0))
+ let expect = [
+\ " *mask = nil; ",
+\ "~ ",
+\ "~ ",
+\ "~ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_list_and_concealing1()
+ call s:test_windows('setl list listchars=tab:>- cole=1')
+ call setline(1, [
+\ "#define ABCDE\t\t1",
+\ "#define ABCDEF\t\t1",
+\ "#define ABCDEFG\t\t1",
+\ "#define ABCDEFGH\t1",
+\ "#define MSG_MODE_FILE\t\t\t1",
+\ "#define MSG_MODE_CONSOLE\t\t2",
+\ "#define MSG_MODE_FILE_AND_CONSOLE\t3",
+\ "#define MSG_MODE_FILE_THEN_CONSOLE\t4",
+\ ])
+ vert resize 40
+ syn match Conceal conceal cchar=>'AB\|MSG_MODE'
+ redraw!
+ let lines = s:screen_lines([1, 7], winwidth(0))
+ let expect = [
+\ "#define ABCDE>-->---1 ",
+\ "#define >CDEF>-->---1 ",
+\ "#define >CDEFG>->---1 ",
+\ "#define >CDEFGH>----1 ",
+\ "#define >_FILE>--------->--->---1 ",
+\ "#define >_CONSOLE>---------->---2 ",
+\ "#define >_FILE_AND_CONSOLE>---------3 ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_list_and_concealing2()
+ call s:test_windows('setl nowrap ts=2 list listchars=tab:>- cole=2 concealcursor=n')
+ call setline(1, "bbeeeeee\t\t;\tsome text")
+ vert resize 40
+ syn clear
+ syn match meaning /;\s*\zs.*/
+ syn match hasword /^\x\{8}/ contains=word
+ syn match word /\<\x\{8}\>/ contains=beginword,endword contained
+ syn match beginword /\<\x\x/ contained conceal
+ syn match endword /\x\{6}\>/ contained
+ hi meaning guibg=blue
+ hi beginword guibg=green
+ hi endword guibg=red
+ redraw!
+ let lines = s:screen_lines([1, 1], winwidth(0))
+ let expect = [
+\ "eeeeee>--->-;>some text ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_screenattr_for_comment()
+ call s:test_windows("setl ft=c ts=7 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+ call setline(1, " /*\t\t and some more */")
+ norm! gg0
+ syntax on
+ hi SpecialKey term=underline ctermfg=red guifg=red
+ redraw!
+ let line = getline(1)
+ let attr = s:screen_attr(1, [1, 6])
+ call assert_notequal(attr[0], attr[1])
+ call assert_notequal(attr[1], attr[3])
+ call assert_notequal(attr[3], attr[5])
+ call s:close_windows()
+endfunc
+
+func Test_visual_block_and_selection_exclusive()
+ call s:test_windows('setl selection=exclusive')
+ call setline(1, "long line: " . repeat("foobar ", 40) . "TARGETÃ' at end")
+ exe "norm! $3B\<C-v>eAx\<Esc>"
+ let lines = s:screen_lines([1, 10], winwidth(0))
+ let expect = [
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar foobar ",
+\ "+foobar TARGETÃx' ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_multibyte_sign_and_colorcolumn()
+ call s:test_windows("setl nolinebreak cc=3 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6")
+ call setline(1, ["", "a b c", "a b c"])
+ exe "sign define foo text=\uff0b"
+ exe "sign place 1 name=foo line=2 buffer=" . bufnr('%')
+ redraw!
+ norm! ggj0
+ let signwidth = strdisplaywidth("\uff0b")
+ let attr1 = s:screen_attr(2, [1, 3], signwidth)
+ let attr2 = s:screen_attr(3, [1, 3], signwidth)
+ call assert_equal(attr1[0], attr2[0])
+ call assert_equal(attr1[1], attr2[1])
+ call assert_equal(attr1[2], attr2[2])
+ let lines = s:screen_lines([1, 3], winwidth(0))
+ let expect = [
+\ " ¶ ",
+\ "+a b c¶ ",
+\ " a b c¶ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_colorcolumn_priority()
+ call s:test_windows('setl cc=4 cuc hls')
+ call setline(1, ["xxyy", ""])
+ norm! gg
+ exe "normal! /xxyy\<CR>"
+ norm! G
+ redraw!
+ let line_attr = s:screen_attr(1, [1, &cc])
+ " Search wins over CursorColumn
+ call assert_equal(line_attr[1], line_attr[0])
+ " Search wins over Colorcolumn
+ call assert_equal(line_attr[2], line_attr[3])
+ call s:close_windows('setl hls&vim')
+endfunc
+
+func Test_illegal_byte_and_breakat()
+ call s:test_windows("setl sbr= brk+=<")
+ vert resize 18
+ call setline(1, repeat("\x80", 6))
+ redraw!
+ let lines = s:screen_lines([1, 2], winwidth(0))
+ let expect = [
+\ "<80><80><80><80><8",
+\ "0><80> ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('setl brk&vim')
+endfunc
+
+func Test_multibyte_wrap_and_breakat()
+ call s:test_windows("setl sbr= brk+=>")
+ call setline(1, repeat('a', 17) . repeat('ã‚', 2))
+ redraw!
+ let lines = s:screen_lines([1, 2], winwidth(0))
+ let expect = [
+\ "aaaaaaaaaaaaaaaaaã‚>",
+\ "ã‚ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows('setl brk&vim')
+endfunc
+
+func Test_chinese_char_on_wrap_column()
+ call s:test_windows("setl nolbr wrap sbr=")
+ syntax off
+ call setline(1, [
+\ 'aaaaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'aaaaaaaaaaaaaaaaa中'.
+\ 'hello'])
+ call cursor(1,1)
+ norm! $
+ redraw!
+ let expect=[
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中aaaaaaaaaaaaaaaaa>',
+\ '中hello ']
+ let lines = s:screen_lines([1, 10], winwidth(0))
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfu
diff --git a/src/nvim/testdir/test_makeencoding.py b/src/nvim/testdir/test_makeencoding.py
new file mode 100644
index 0000000000..041edadc0a
--- /dev/null
+++ b/src/nvim/testdir/test_makeencoding.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Test program for :make, :grep and :cgetfile.
+
+from __future__ import print_function, unicode_literals
+import locale
+import io
+import sys
+
+def set_output_encoding(enc=None):
+ """Set the encoding of stdout and stderr
+
+ arguments:
+ enc -- Encoding name.
+ If omitted, locale.getpreferredencoding() is used.
+ """
+ if enc is None:
+ enc = locale.getpreferredencoding()
+
+ def get_text_writer(fo, **kwargs):
+ kw = dict(kwargs)
+ kw.setdefault('errors', 'backslashreplace') # use \uXXXX style
+ kw.setdefault('closefd', False)
+
+ if sys.version_info[0] < 3:
+ # Work around for Python 2.x
+ # New line conversion isn't needed here. Done in somewhere else.
+ writer = io.open(fo.fileno(), mode='w', newline='', **kw)
+ write = writer.write # save the original write() function
+ enc = locale.getpreferredencoding()
+ def convwrite(s):
+ if isinstance(s, bytes):
+ write(s.decode(enc)) # convert to unistr
+ else:
+ write(s)
+ try:
+ writer.flush() # needed on Windows
+ except IOError:
+ pass
+ writer.write = convwrite
+ else:
+ writer = io.open(fo.fileno(), mode='w', **kw)
+ return writer
+
+ sys.stdout = get_text_writer(sys.stdout, encoding=enc)
+ sys.stderr = get_text_writer(sys.stderr, encoding=enc)
+
+
+def main():
+ enc = 'utf-8'
+ if len(sys.argv) > 1:
+ enc = sys.argv[1]
+ set_output_encoding(enc)
+
+ message_tbl = {
+ 'utf-8': 'ÀÈÌÒÙ ã“ã‚“ã«ã¡ã¯ 你好',
+ 'latin1': 'ÀÈÌÒÙ',
+ 'cp932': 'ã“ã‚“ã«ã¡ã¯',
+ 'cp936': '你好',
+ }
+
+ print('Xfoobar.c(10) : %s (%s)' % (message_tbl[enc], enc))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/nvim/testdir/test_makeencoding.vim b/src/nvim/testdir/test_makeencoding.vim
new file mode 100644
index 0000000000..6e4c7af821
--- /dev/null
+++ b/src/nvim/testdir/test_makeencoding.vim
@@ -0,0 +1,113 @@
+" Tests for 'makeencoding'.
+if !has('multi_byte')
+ finish
+endif
+
+source shared.vim
+
+let s:python = PythonProg()
+if s:python == ''
+ " Can't run this test.
+ finish
+endif
+
+let s:script = 'test_makeencoding.py'
+
+if has('iconv')
+ let s:message_tbl = {
+ \ 'utf-8': 'ÀÈÌÒÙ ã“ã‚“ã«ã¡ã¯ 你好',
+ \ 'latin1': 'ÀÈÌÒÙ',
+ \ 'cp932': 'ã“ã‚“ã«ã¡ã¯',
+ \ 'cp936': '你好',
+ \}
+else
+ let s:message_tbl = {
+ \ 'utf-8': 'ÀÈÌÒÙ ã“ã‚“ã«ã¡ã¯ 你好',
+ \ 'latin1': 'ÀÈÌÒÙ',
+ \}
+endif
+
+
+" Tests for :cgetfile and :lgetfile.
+func Test_getfile()
+ set errorfile=Xerror.txt
+ set errorformat=%f(%l)\ :\ %m
+
+ " :cgetfile
+ for enc in keys(s:message_tbl)
+ let &makeencoding = enc
+ exec "silent !" . s:python . " " . s:script . " " . enc . " > " . &errorfile
+ cgetfile
+ copen
+ call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+ \ getline('.'))
+ cclose
+ endfor
+
+ " :lgetfile
+ for enc in keys(s:message_tbl)
+ let &makeencoding = enc
+ exec "silent !" . s:python . " " . s:script . " " . enc . " > " . &errorfile
+ lgetfile
+ lopen
+ call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+ \ getline('.'))
+ lclose
+ endfor
+
+ call delete(&errorfile)
+endfunc
+
+
+" Tests for :grep and :lgrep.
+func Test_grep()
+ let &grepprg = s:python
+ set grepformat=%f(%l)\ :\ %m
+
+ " :grep
+ for enc in keys(s:message_tbl)
+ let &makeencoding = enc
+ exec "silent grep! " . s:script . " " . enc
+ copen
+ call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+ \ getline('.'))
+ cclose
+ endfor
+
+ " :lgrep
+ for enc in keys(s:message_tbl)
+ let &makeencoding = enc
+ exec "silent lgrep! " . s:script . " " . enc
+ lopen
+ call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+ \ getline('.'))
+ lclose
+ endfor
+endfunc
+
+
+" Tests for :make and :lmake.
+func Test_make()
+ let &makeprg = s:python
+ set errorformat=%f(%l)\ :\ %m
+
+ " :make
+ for enc in keys(s:message_tbl)
+ let &makeencoding = enc
+ exec "silent make! " . s:script . " " . enc
+ copen
+ call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+ \ getline('.'))
+ cclose
+ endfor
+
+ " :lmake
+ for enc in keys(s:message_tbl)
+ let &makeencoding = enc
+ exec "silent lmake! " . s:script . " " . enc
+ lopen
+ call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+ \ getline('.'))
+ lclose
+ endfor
+endfunc
diff --git a/src/nvim/testdir/test_maparg.vim b/src/nvim/testdir/test_maparg.vim
new file mode 100644
index 0000000000..0fb878b04a
--- /dev/null
+++ b/src/nvim/testdir/test_maparg.vim
@@ -0,0 +1,56 @@
+" Tests for maparg().
+" Also test utf8 map with a 0x80 byte.
+if !has("multi_byte")
+ finish
+endif
+
+function s:SID()
+ return str2nr(matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$'))
+endfun
+
+function Test_maparg()
+ new
+ set cpo-=<
+ set encoding=utf8
+ " Test maparg() with a string result
+ map foo<C-V> is<F4>foo
+ vnoremap <script> <buffer> <expr> <silent> bar isbar
+ let sid = s:SID()
+ call assert_equal("is<F4>foo", maparg('foo<C-V>'))
+ call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo<C-V>',
+ \ 'mode': ' ', 'nowait': 0, 'expr': 0, 'sid': sid, 'rhs': 'is<F4>foo',
+ \ 'buffer': 0}, maparg('foo<C-V>', '', 0, 1))
+ call assert_equal({'silent': 1, 'noremap': 1, 'lhs': 'bar', 'mode': 'v',
+ \ 'nowait': 0, 'expr': 1, 'sid': sid, 'rhs': 'isbar', 'buffer': 1},
+ \ maparg('bar', '', 0, 1))
+ map <buffer> <nowait> foo bar
+ call assert_equal({'silent': 0, 'noremap': 0, 'lhs': 'foo', 'mode': ' ',
+ \ 'nowait': 1, 'expr': 0, 'sid': sid, 'rhs': 'bar', 'buffer': 1},
+ \ maparg('foo', '', 0, 1))
+
+ map abc x<char-114>x
+ call assert_equal("xrx", maparg('abc'))
+ map abc y<S-char-114>y
+ call assert_equal("yRy", maparg('abc'))
+
+ map abc <Nop>
+ call assert_equal("<Nop>", maparg('abc'))
+ unmap abc
+endfunction
+
+function Test_range_map()
+ new
+ " Outside of the range, minimum
+ inoremap <Char-0x1040> a
+ execute "normal a\u1040\<Esc>"
+ " Inside of the range, minimum
+ inoremap <Char-0x103f> b
+ execute "normal a\u103f\<Esc>"
+ " Inside of the range, maximum
+ inoremap <Char-0xf03f> c
+ execute "normal a\uf03f\<Esc>"
+ " Outside of the range, maximum
+ inoremap <Char-0xf040> d
+ execute "normal a\uf040\<Esc>"
+ call assert_equal("abcd", getline(1))
+endfunction
diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim
new file mode 100644
index 0000000000..32593a423a
--- /dev/null
+++ b/src/nvim/testdir/test_mapping.vim
@@ -0,0 +1,286 @@
+" Tests for mappings and abbreviations
+
+if !has('multi_byte')
+ finish
+endif
+
+func Test_abbreviation()
+ " abbreviation with 0x80 should work
+ inoreab чкпр vim
+ call feedkeys("Goчкпр \<Esc>", "xt")
+ call assert_equal('vim ', getline('$'))
+ iunab чкпр
+ set nomodified
+endfunc
+
+func Test_map_ctrl_c_insert()
+ " mapping of ctrl-c in Insert mode
+ set cpo-=< cpo-=k
+ inoremap <c-c> <ctrl-c>
+ cnoremap <c-c> dummy
+ cunmap <c-c>
+ call feedkeys("GoTEST2: CTRL-C |\<C-C>A|\<Esc>", "xt")
+ call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$'))
+ unmap! <c-c>
+ set nomodified
+endfunc
+
+func Test_map_ctrl_c_visual()
+ " mapping of ctrl-c in Visual mode
+ vnoremap <c-c> :<C-u>$put ='vmap works'
+ call feedkeys("GV\<C-C>\<CR>", "xt")
+ call assert_equal('vmap works', getline('$'))
+ vunmap <c-c>
+ set nomodified
+endfunc
+
+func Test_map_langmap()
+ if !has('langmap')
+ return
+ endif
+
+ " check langmap applies in normal mode
+ set langmap=+- nolangremap
+ new
+ call setline(1, ['a', 'b', 'c'])
+ 2
+ call assert_equal('b', getline('.'))
+ call feedkeys("+", "xt")
+ call assert_equal('a', getline('.'))
+
+ " check no remapping
+ map x +
+ 2
+ call feedkeys("x", "xt")
+ call assert_equal('c', getline('.'))
+
+ " check with remapping
+ set langremap
+ 2
+ call feedkeys("x", "xt")
+ call assert_equal('a', getline('.'))
+
+ unmap x
+ bwipe!
+
+ " 'langnoremap' follows 'langremap' and vise versa
+ set langremap
+ set langnoremap
+ call assert_equal(0, &langremap)
+ set langremap
+ call assert_equal(0, &langnoremap)
+ set nolangremap
+ call assert_equal(1, &langnoremap)
+
+ " check default values
+ set langnoremap&
+ call assert_equal(1, &langnoremap)
+ call assert_equal(0, &langremap)
+ set langremap&
+ call assert_equal(1, &langnoremap)
+ call assert_equal(0, &langremap)
+
+ " langmap should not apply in insert mode, 'langremap' doesn't matter
+ set langmap=+{ nolangremap
+ call feedkeys("Go+\<Esc>", "xt")
+ call assert_equal('+', getline('$'))
+ set langmap=+{ langremap
+ call feedkeys("Go+\<Esc>", "xt")
+ call assert_equal('+', getline('$'))
+
+ " langmap used for register name in insert mode.
+ call setreg('a', 'aaaa')
+ call setreg('b', 'bbbb')
+ call setreg('c', 'cccc')
+ set langmap=ab langremap
+ call feedkeys("Go\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+ call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+ " mapping does not apply
+ imap c a
+ call feedkeys("Go\<C-R>c\<Esc>", "xt")
+ call assert_equal('cccc', getline('$'))
+ imap a c
+ call feedkeys("Go\<C-R>a\<Esc>", "xt")
+ call assert_equal('bbbb', getline('$'))
+
+ " langmap should not apply in Command-line mode
+ set langmap=+{ nolangremap
+ call feedkeys(":call append(line('$'), '+')\<CR>", "xt")
+ call assert_equal('+', getline('$'))
+
+ iunmap a
+ iunmap c
+ set nomodified
+endfunc
+
+func Test_map_feedkeys()
+ " issue #212 (feedkeys insert mapping at current position)
+ nnoremap . :call feedkeys(".", "in")<cr>
+ call setline('$', ['a b c d', 'a b c d'])
+ $-1
+ call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt")
+ call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$')))
+ nunmap .
+ set nomodified
+endfunc
+
+func Test_map_cursor()
+ " <c-g>U<cursor> works only within a single line
+ imapclear
+ imap ( ()<c-g>U<left>
+ call feedkeys("G2o\<Esc>ki\<CR>Test1: text with a (here some more text\<Esc>k.", "xt")
+ call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 2))
+ call assert_equal('Test1: text with a (here some more text)', getline(line('$') - 1))
+
+ " test undo
+ call feedkeys("G2o\<Esc>ki\<CR>Test2: text wit a (here some more text [und undo]\<C-G>u\<Esc>k.u", "xt")
+ call assert_equal('', getline(line('$') - 2))
+ call assert_equal('Test2: text wit a (here some more text [und undo])', getline(line('$') - 1))
+ set nomodified
+ imapclear
+endfunc
+
+" This isn't actually testing a mapping, but similar use of CTRL-G U as above.
+func Test_break_undo()
+ :set whichwrap=<,>,[,]
+ call feedkeys("G4o2k", "xt")
+ exe ":norm! iTest3: text with a (parenthesis here\<C-G>U\<Right>new line here\<esc>\<up>\<up>."
+ call assert_equal('new line here', getline(line('$') - 3))
+ call assert_equal('Test3: text with a (parenthesis here', getline(line('$') - 2))
+ call assert_equal('new line here', getline(line('$') - 1))
+ set nomodified
+endfunc
+
+func Test_map_meta_quotes()
+ imap <M-"> foo
+ call feedkeys("Go-\<M-\">-\<Esc>", "xt")
+ call assert_equal("-foo-", getline('$'))
+ set nomodified
+ iunmap <M-">
+endfunc
+
+func Test_abbr_after_line_join()
+ new
+ abbr foo bar
+ set backspace=indent,eol,start
+ exe "normal o\<BS>foo "
+ call assert_equal("bar ", getline(1))
+ bwipe!
+ unabbr foo
+ set backspace&
+endfunc
+
+func Test_map_timeout()
+ nnoremap aaaa :let got_aaaa = 1<CR>
+ nnoremap bb :let got_bb = 1<CR>
+ nmap b aaa
+ new
+ func ExitInsert(timer)
+ let g:line = getline(1)
+ call feedkeys("\<Esc>", "t")
+ endfunc
+ set timeout timeoutlen=200
+ call timer_start(300, 'ExitInsert')
+ " After the 'b' Vim waits for another character to see if it matches 'bb'.
+ " When it times out it is expanded to "aaa", but there is no wait for
+ " "aaaa". Can't check that reliably though.
+ call feedkeys("b", "xt!")
+ call assert_equal("aa", g:line)
+ call assert_false(exists('got_aaa'))
+ call assert_false(exists('got_bb'))
+
+ bwipe!
+ nunmap aaaa
+ nunmap bb
+ nunmap b
+ set timeoutlen&
+ delfunc ExitInsert
+endfunc
+
+func Test_cabbr_visual_mode()
+ cabbr s su
+ call feedkeys(":s \<c-B>\"\<CR>", 'itx')
+ call assert_equal('"su ', getreg(':'))
+ call feedkeys(":'<,'>s \<c-B>\"\<CR>", 'itx')
+ let expected = '"'. "'<,'>su "
+ call assert_equal(expected, getreg(':'))
+ call feedkeys(": '<,'>s \<c-B>\"\<CR>", 'itx')
+ let expected = '" '. "'<,'>su "
+ call assert_equal(expected, getreg(':'))
+ call feedkeys(":'a,'bs \<c-B>\"\<CR>", 'itx')
+ let expected = '"'. "'a,'bsu "
+ call assert_equal(expected, getreg(':'))
+ cunabbr s
+endfunc
+
+func Test_abbreviation_CR()
+ new
+ func Eatchar(pat)
+ let c = nr2char(getchar(0))
+ return (c =~ a:pat) ? '' : c
+ endfunc
+ iabbrev <buffer><silent> ~~7 <c-r>=repeat('~', 7)<CR><c-r>=Eatchar('\s')<cr>
+ call feedkeys("GA~~7 \<esc>", 'xt')
+ call assert_equal('~~~~~~~', getline('$'))
+ %d
+ call feedkeys("GA~~7\<cr>\<esc>", 'xt')
+ call assert_equal(['~~~~~~~', ''], getline(1,'$'))
+ delfunc Eatchar
+ bw!
+endfunc
+
+func Test_motionforce_omap()
+ func GetCommand()
+ let g:m=mode(1)
+ let [g:lnum1, g:col1] = searchpos('-', 'Wb')
+ if g:lnum1 == 0
+ return "\<Esc>"
+ endif
+ let [g:lnum2, g:col2] = searchpos('-', 'W')
+ if g:lnum2 == 0
+ return "\<Esc>"
+ endif
+ return ":call Select()\<CR>"
+ endfunc
+ func Select()
+ call cursor([g:lnum1, g:col1])
+ exe "normal! 1 ". (strlen(g:m) == 2 ? 'v' : g:m[2])
+ call cursor([g:lnum2, g:col2])
+ execute "normal! \<BS>"
+ endfunc
+ new
+ onoremap <buffer><expr> i- GetCommand()
+ " 1) default omap mapping
+ %d_
+ call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
+ call cursor(2, 1)
+ norm di-
+ call assert_equal('no', g:m)
+ call assert_equal(['aaa -- eee'], getline(1, '$'))
+ " 2) forced characterwise operation
+ %d_
+ call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
+ call cursor(2, 1)
+ norm dvi-
+ call assert_equal('nov', g:m)
+ call assert_equal(['aaa -- eee'], getline(1, '$'))
+ " 3) forced linewise operation
+ %d_
+ call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
+ call cursor(2, 1)
+ norm dVi-
+ call assert_equal('noV', g:m)
+ call assert_equal([''], getline(1, '$'))
+ " 4) forced blockwise operation
+ %d_
+ call setline(1, ['aaa - bbb', 'x', 'ddd - eee'])
+ call cursor(2, 1)
+ exe "norm d\<C-V>i-"
+ call assert_equal("no\<C-V>", g:m)
+ call assert_equal(['aaabbb', 'x', 'dddeee'], getline(1, '$'))
+ bwipe!
+ delfunc Select
+ delfunc GetCommand
+endfunc
diff --git a/src/nvim/testdir/test_marks.vim b/src/nvim/testdir/test_marks.vim
new file mode 100644
index 0000000000..8858cd22b8
--- /dev/null
+++ b/src/nvim/testdir/test_marks.vim
@@ -0,0 +1,138 @@
+
+" Test that a deleted mark is restored after delete-undo-redo-undo.
+function! Test_Restore_DelMark()
+ enew!
+ call append(0, [" textline A", " textline B", " textline C"])
+ normal! 2gg
+ set nocp viminfo+=nviminfo
+ exe "normal! i\<C-G>u\<Esc>"
+ exe "normal! maddu\<C-R>u"
+ let pos = getpos("'a")
+ call assert_equal(2, pos[1])
+ call assert_equal(1, pos[2])
+ enew!
+endfunction
+
+" Test that CTRL-A and CTRL-X updates last changed mark '[, '].
+function! Test_Incr_Marks()
+ enew!
+ call append(0, ["123 123 123", "123 123 123", "123 123 123"])
+ normal! gg
+ execute "normal! \<C-A>`[v`]rAjwvjw\<C-X>`[v`]rX"
+ call assert_equal("AAA 123 123", getline(1))
+ call assert_equal("123 XXXXXXX", getline(2))
+ call assert_equal("XXX 123 123", getline(3))
+ enew!
+endfunction
+
+func Test_setpos()
+ new one
+ let onebuf = bufnr('%')
+ let onewin = win_getid()
+ call setline(1, ['aaa', 'bbb', 'ccc'])
+ new two
+ let twobuf = bufnr('%')
+ let twowin = win_getid()
+ call setline(1, ['aaa', 'bbb', 'ccc'])
+
+ " for the cursor the buffer number is ignored
+ call setpos(".", [0, 2, 1, 0])
+ call assert_equal([0, 2, 1, 0], getpos("."))
+ call setpos(".", [onebuf, 3, 3, 0])
+ call assert_equal([0, 3, 3, 0], getpos("."))
+
+ call setpos("''", [0, 1, 3, 0])
+ call assert_equal([0, 1, 3, 0], getpos("''"))
+ call setpos("''", [onebuf, 2, 2, 0])
+ call assert_equal([0, 2, 2, 0], getpos("''"))
+
+ " buffer-local marks
+ for mark in ["'a", "'\"", "'[", "']", "'<", "'>"]
+ call win_gotoid(twowin)
+ call setpos(mark, [0, 2, 1, 0])
+ call assert_equal([0, 2, 1, 0], getpos(mark), "for mark " . mark)
+ call setpos(mark, [onebuf, 1, 3, 0])
+ call win_gotoid(onewin)
+ call assert_equal([0, 1, 3, 0], getpos(mark), "for mark " . mark)
+ endfor
+
+ " global marks
+ call win_gotoid(twowin)
+ call setpos("'N", [0, 2, 1, 0])
+ call assert_equal([twobuf, 2, 1, 0], getpos("'N"))
+ call setpos("'N", [onebuf, 1, 3, 0])
+ call assert_equal([onebuf, 1, 3, 0], getpos("'N"))
+
+ call win_gotoid(onewin)
+ bwipe!
+ call win_gotoid(twowin)
+ bwipe!
+endfunc
+
+func Test_marks_cmd()
+ new Xone
+ call setline(1, ['aaa', 'bbb'])
+ norm! maG$mB
+ w!
+ new Xtwo
+ call setline(1, ['ccc', 'ddd'])
+ norm! $mcGmD
+ w!
+
+ b Xone
+ let a = split(execute('marks'), "\n")
+ call assert_equal(9, len(a))
+ call assert_equal('mark line col file/text', a[0])
+ call assert_equal(" ' 2 0 bbb", a[1])
+ call assert_equal(' a 1 0 aaa', a[2])
+ call assert_equal(' B 2 2 bbb', a[3])
+ call assert_equal(' D 2 0 Xtwo', a[4])
+ call assert_equal(' " 1 0 aaa', a[5])
+ call assert_equal(' [ 1 0 aaa', a[6])
+ call assert_equal(' ] 2 0 bbb', a[7])
+ call assert_equal(' . 2 0 bbb', a[8])
+
+ b Xtwo
+ let a = split(execute('marks'), "\n")
+ call assert_equal(9, len(a))
+ call assert_equal('mark line col file/text', a[0])
+ call assert_equal(" ' 1 0 ccc", a[1])
+ call assert_equal(' c 1 2 ccc', a[2])
+ call assert_equal(' B 2 2 Xone', a[3])
+ call assert_equal(' D 2 0 ddd', a[4])
+ call assert_equal(' " 2 0 ddd', a[5])
+ call assert_equal(' [ 1 0 ccc', a[6])
+ call assert_equal(' ] 2 0 ddd', a[7])
+ call assert_equal(' . 2 0 ddd', a[8])
+
+ b Xone
+ delmarks aB
+ let a = split(execute('marks aBcD'), "\n")
+ call assert_equal(2, len(a))
+ call assert_equal('mark line col file/text', a[0])
+ call assert_equal(' D 2 0 Xtwo', a[1])
+
+ b Xtwo
+ delmarks cD
+ call assert_fails('marks aBcD', 'E283:')
+
+ call delete('Xone')
+ call delete('Xtwo')
+ %bwipe
+endfunc
+
+func Test_marks_cmd_multibyte()
+ if !has('multi_byte')
+ return
+ endif
+ new Xone
+ call setline(1, [repeat('á', &columns)])
+ norm! ma
+
+ let a = split(execute('marks a'), "\n")
+ call assert_equal(2, len(a))
+ let expected = ' a 1 0 ' . repeat('á', &columns - 16)
+ call assert_equal(expected, a[1])
+
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim
new file mode 100644
index 0000000000..e608a2e58b
--- /dev/null
+++ b/src/nvim/testdir/test_match.vim
@@ -0,0 +1,232 @@
+" Test for :match, :2match, :3match, clearmatches(), getmatches(), matchadd(),
+" matchaddpos(), matcharg(), matchdelete(), and setmatches().
+
+function Test_match()
+ highlight MyGroup1 term=bold ctermbg=red guibg=red
+ highlight MyGroup2 term=italic ctermbg=green guibg=green
+ highlight MyGroup3 term=underline ctermbg=blue guibg=blue
+
+ " --- Check that "matcharg()" returns the correct group and pattern if a match
+ " --- is defined.
+ match MyGroup1 /TODO/
+ 2match MyGroup2 /FIXME/
+ 3match MyGroup3 /XXX/
+ call assert_equal(['MyGroup1', 'TODO'], matcharg(1))
+ call assert_equal(['MyGroup2', 'FIXME'], matcharg(2))
+ call assert_equal(['MyGroup3', 'XXX'], matcharg(3))
+
+ " --- Check that "matcharg()" returns an empty list if the argument is not 1,
+ " --- 2 or 3 (only 0 and 4 are tested).
+ call assert_equal([], matcharg(0))
+ call assert_equal([], matcharg(4))
+
+ " --- Check that "matcharg()" returns ['', ''] if a match is not defined.
+ match
+ 2match
+ 3match
+ call assert_equal(['', ''], matcharg(1))
+ call assert_equal(['', ''], matcharg(2))
+ call assert_equal(['', ''], matcharg(3))
+
+ " --- Check that "matchadd()" and "getmatches()" agree on added matches and
+ " --- that default values apply.
+ let m1 = matchadd("MyGroup1", "TODO")
+ let m2 = matchadd("MyGroup2", "FIXME", 42)
+ let m3 = matchadd("MyGroup3", "XXX", 60, 17)
+ let ans = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4},
+ \ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5},
+ \ {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
+ call assert_equal(ans, getmatches())
+
+ " --- Check that "matchdelete()" deletes the matches defined in the previous
+ " --- test correctly.
+ call matchdelete(m1)
+ call matchdelete(m2)
+ call matchdelete(m3)
+ call assert_equal([], getmatches())
+
+ " --- Check that "matchdelete()" returns 0 if successful and otherwise -1.
+ let m = matchadd("MyGroup1", "TODO")
+ call assert_equal(0, matchdelete(m))
+ call assert_fails('call matchdelete(42)', 'E803:')
+
+ " --- Check that "clearmatches()" clears all matches defined by ":match" and
+ " --- "matchadd()".
+ let m1 = matchadd("MyGroup1", "TODO")
+ let m2 = matchadd("MyGroup2", "FIXME", 42)
+ let m3 = matchadd("MyGroup3", "XXX", 60, 17)
+ match MyGroup1 /COFFEE/
+ 2match MyGroup2 /HUMPPA/
+ 3match MyGroup3 /VIM/
+ call clearmatches()
+ call assert_equal([], getmatches())
+
+ " --- Check that "setmatches()" restores a list of matches saved by
+ " --- "getmatches()" without changes. (Matches with equal priority must also
+ " --- remain in the same order.)
+ let m1 = matchadd("MyGroup1", "TODO")
+ let m2 = matchadd("MyGroup2", "FIXME", 42)
+ let m3 = matchadd("MyGroup3", "XXX", 60, 17)
+ match MyGroup1 /COFFEE/
+ 2match MyGroup2 /HUMPPA/
+ 3match MyGroup3 /VIM/
+ let ml = getmatches()
+ call clearmatches()
+ call setmatches(ml)
+ call assert_equal(ml, getmatches())
+ call clearmatches()
+
+ " --- Check that "setmatches()" will not add two matches with the same ID. The
+ " --- expected behaviour (for now) is to add the first match but not the
+ " --- second and to return 0 (even though it is a matter of debate whether
+ " --- this can be considered successful behaviour).
+ let data = [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1},
+ \ {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}]
+ call assert_fails('call setmatches(data)', 'E801:')
+ call assert_equal([data[0]], getmatches())
+ call clearmatches()
+
+ " --- Check that "setmatches()" returns 0 if successful and otherwise -1.
+ " --- (A range of valid and invalid input values are tried out to generate the
+ " --- return values.)
+ call assert_equal(0, setmatches([]))
+ call assert_equal(0, setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}]))
+ call clearmatches()
+ call assert_fails('call setmatches(0)', 'E714:')
+ call assert_fails('call setmatches([0])', 'E474:')
+ call assert_fails("call setmatches([{'wrong key': 'wrong value'}])", 'E474:')
+
+ call setline(1, 'abcdefghijklmnopq')
+ call matchaddpos("MyGroup1", [[1, 5], [1, 8, 3]], 10, 3)
+ 1
+ redraw!
+ let v1 = screenattr(1, 1)
+ let v5 = screenattr(1, 5)
+ let v6 = screenattr(1, 6)
+ let v8 = screenattr(1, 8)
+ let v10 = screenattr(1, 10)
+ let v11 = screenattr(1, 11)
+ call assert_notequal(v1, v5)
+ call assert_equal(v6, v1)
+ call assert_equal(v8, v5)
+ call assert_equal(v10, v5)
+ call assert_equal(v11, v1)
+ call assert_equal([{'group': 'MyGroup1', 'id': 3, 'priority': 10, 'pos1': [1, 5, 1], 'pos2': [1, 8, 3]}], getmatches())
+ call clearmatches()
+
+ "
+ if has('multi_byte')
+ call setline(1, 'abcdΣabcdef')
+ call matchaddpos("MyGroup1", [[1, 4, 2], [1, 9, 2]])
+ 1
+ redraw!
+ let v1 = screenattr(1, 1)
+ let v4 = screenattr(1, 4)
+ let v5 = screenattr(1, 5)
+ let v6 = screenattr(1, 6)
+ let v7 = screenattr(1, 7)
+ let v8 = screenattr(1, 8)
+ let v9 = screenattr(1, 9)
+ let v10 = screenattr(1, 10)
+ call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1, 9, 2]}], getmatches())
+ call assert_notequal(v1, v4)
+ call assert_equal(v5, v4)
+ call assert_equal(v6, v1)
+ call assert_equal(v7, v1)
+ call assert_equal(v8, v4)
+ call assert_equal(v9, v4)
+ call assert_equal(v10, v1)
+
+ " Check, that setmatches() can correctly restore the matches from matchaddpos()
+ call matchadd('MyGroup1', '\%2lmatchadd')
+ let m=getmatches()
+ call clearmatches()
+ call setmatches(m)
+ call assert_equal([{'group': 'MyGroup1', 'id': 11, 'priority': 10, 'pos1': [1, 4, 2], 'pos2': [1,9, 2]}, {'group': 'MyGroup1', 'pattern': '\%2lmatchadd', 'priority': 10, 'id': 12}], getmatches())
+ endif
+
+ highlight MyGroup1 NONE
+ highlight MyGroup2 NONE
+ highlight MyGroup3 NONE
+endfunc
+
+func Test_matchaddpos()
+ syntax on
+ set hlsearch
+
+ call setline(1, ['12345', 'NP'])
+ call matchaddpos('Error', [[1,2], [1,6], [2,2]])
+ redraw!
+ call assert_notequal(screenattr(2,2), 0)
+ call assert_equal(screenattr(2,2), screenattr(1,2))
+ call assert_notequal(screenattr(2,2), screenattr(1,6))
+ 1
+ call matchadd('Search', 'N\|\n')
+ redraw!
+ call assert_notequal(screenattr(2,1), 0)
+ call assert_equal(screenattr(2,1), screenattr(1,6))
+ exec "norm! i0\<Esc>"
+ redraw!
+ call assert_equal(screenattr(2,2), screenattr(1,6))
+
+ " Check overlapping pos
+ call clearmatches()
+ call setline(1, ['1234567890', 'NH'])
+ call matchaddpos('Error', [[1,1,5], [1,3,5], [2,2]])
+ redraw!
+ call assert_notequal(screenattr(2,2), 0)
+ call assert_equal(screenattr(2,2), screenattr(1,5))
+ call assert_equal(screenattr(2,2), screenattr(1,7))
+ call assert_notequal(screenattr(2,2), screenattr(1,8))
+
+ call clearmatches()
+ call matchaddpos('Error', [[1], [2,2]])
+ redraw!
+ call assert_equal(screenattr(2,2), screenattr(1,1))
+ call assert_equal(screenattr(2,2), screenattr(1,10))
+ call assert_notequal(screenattr(2,2), screenattr(1,11))
+
+ " Check overlapping pos
+ call clearmatches()
+ call setline(1, ['1234567890', 'NH'])
+ call matchaddpos('Error', [[1,1,5], [1,3,5], [2,2]])
+ redraw!
+ call assert_notequal(screenattr(2,2), 0)
+ call assert_equal(screenattr(2,2), screenattr(1,5))
+ call assert_equal(screenattr(2,2), screenattr(1,7))
+ call assert_notequal(screenattr(2,2), screenattr(1,8))
+
+ nohl
+ call clearmatches()
+ syntax off
+ set hlsearch&
+endfunc
+
+func Test_matchaddpos_using_negative_priority()
+ set hlsearch
+
+ call clearmatches()
+
+ call setline(1, 'x')
+ let @/='x'
+ redraw!
+ let search_attr = screenattr(1,1)
+
+ let @/=''
+ call matchaddpos('Error', [1], 10)
+ redraw!
+ let error_attr = screenattr(1,1)
+
+ call setline(2, '-1 match priority')
+ call matchaddpos('Error', [2], -1)
+ redraw!
+ let negative_match_priority_attr = screenattr(2,1)
+
+ call assert_notequal(negative_match_priority_attr, search_attr, "Match with negative priority is incorrectly highlighted with Search highlight.")
+ call assert_equal(negative_match_priority_attr, error_attr)
+
+ nohl
+ set hlsearch&
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_matchadd_conceal.vim b/src/nvim/testdir/test_matchadd_conceal.vim
new file mode 100644
index 0000000000..b918525dbc
--- /dev/null
+++ b/src/nvim/testdir/test_matchadd_conceal.vim
@@ -0,0 +1,275 @@
+" Test for matchadd() and conceal feature
+if !has('conceal')
+ finish
+endif
+
+source shared.vim
+
+function! Test_simple_matchadd()
+ new
+
+ 1put='# This is a Test'
+ " 1234567890123456
+ let expect = '# This is a Test'
+
+ call cursor(1, 1)
+ call matchadd('Conceal', '\%2l ')
+ redraw!
+ let lnum = 2
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ quit!
+endfunction
+
+function! Test_simple_matchadd_and_conceal()
+ new
+ setlocal concealcursor=n conceallevel=1
+
+ 1put='# This is a Test'
+ " 1234567890123456
+ let expect = '#XThisXisXaXTest'
+
+ call cursor(1, 1)
+ call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
+ redraw!
+ let lnum = 2
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ quit!
+endfunction
+
+function! Test_matchadd_and_conceallevel_3()
+ new
+
+ setlocal conceallevel=3
+ " set filetype and :syntax on to change screenattr()
+ setlocal filetype=conf
+ syntax on
+
+ 1put='# This is a Test'
+ " 1234567890123456
+ let expect = '#ThisisaTest'
+
+ call cursor(1, 1)
+ call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
+ redraw!
+ let lnum = 2
+ call assert_equal(expect, Screenline(lnum))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ " more matchadd()
+ " 1234567890123456
+ let expect = '#Thisisa Test'
+
+ call matchadd('ErrorMsg', '\%2l Test', 20, -1, {'conceal': 'X'})
+ redraw!
+ call assert_equal(expect, Screenline(lnum))
+ call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2) , screenattr(lnum, 7))
+ call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 10), screenattr(lnum, 12))
+ call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 16))
+ call assert_notequal(screenattr(lnum, 10), screenattr(lnum, 16))
+
+ syntax off
+ quit!
+endfunction
+
+function! Test_default_conceal_char()
+ new
+ setlocal concealcursor=n conceallevel=1
+
+ 1put='# This is a Test'
+ " 1234567890123456
+ let expect = '# This is a Test'
+
+ call cursor(1, 1)
+ call matchadd('Conceal', '\%2l ', 10, -1, {})
+ redraw!
+ let lnum = 2
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ " 1234567890123456
+ let expect = '#+This+is+a+Test'
+ let listchars_save = &listchars
+ set listchars=conceal:+
+ redraw!
+
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ let &listchars = listchars_save
+ quit!
+endfunction
+
+function! Test_syn_and_match_conceal()
+ new
+ setlocal concealcursor=n conceallevel=1
+
+ 1put='# This is a Test'
+ " 1234567890123456
+ let expect = '#ZThisZisZaZTest'
+
+ call cursor(1, 1)
+ call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
+ syntax match MyConceal /\%2l / conceal containedin=ALL cchar=*
+ redraw!
+ let lnum = 2
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ " 1234567890123456
+ let expect = '#*This*is*a*Test'
+ call clearmatches()
+ redraw!
+
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ syntax off
+ quit!
+endfunction
+
+function! Test_clearmatches()
+ new
+ setlocal concealcursor=n conceallevel=1
+
+ 1put='# This is a Test'
+ " 1234567890123456
+ let expect = '# This is a Test'
+
+ call cursor(1, 1)
+ call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
+ let a = getmatches()
+ call clearmatches()
+ redraw!
+
+ let lnum = 2
+ call assert_equal(expect, Screenline(lnum))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ " reset match using setmatches()
+ " 1234567890123456
+ let expect = '#ZThisZisZaZTest'
+ call setmatches(a)
+ redraw!
+
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+ call assert_equal({'group': 'Conceal', 'pattern': '\%2l ', 'priority': 10, 'id': a[0].id, 'conceal': 'Z'}, a[0])
+
+ quit!
+endfunction
+
+function! Test_using_matchaddpos()
+ new
+ setlocal concealcursor=n conceallevel=1
+ " set filetype and :syntax on to change screenattr()
+ setlocal filetype=conf
+ syntax on
+
+ 1put='# This is a Test'
+ " 1234567890123456
+ let expect = '#Pis a Test'
+
+ call cursor(1, 1)
+ call matchaddpos('Conceal', [[2,2,6]], 10, -1, {'conceal': 'P'})
+ let a = getmatches()
+ redraw!
+
+ let lnum = 2
+ call assert_equal(expect, Screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 2))
+ call assert_notequal(screenattr(lnum, 2) , screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 10))
+ call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 12))
+ call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 16))
+ call assert_equal(screenattr(lnum, 12), screenattr(lnum, 16))
+ call assert_equal({'group': 'Conceal', 'id': a[0].id, 'priority': 10, 'pos1': [2, 2, 6], 'conceal': 'P'}, a[0])
+
+ syntax off
+ quit!
+endfunction
+
+function! Test_matchadd_repeat_conceal_with_syntax_off()
+ new
+
+ " To test targets in the same line string is replaced with conceal char
+ " correctly, repeat 'TARGET'
+ 1put ='TARGET_TARGETTARGET'
+ call cursor(1, 1)
+ redraw
+ call assert_equal('TARGET_TARGETTARGET', Screenline(2))
+
+ setlocal conceallevel=2
+ call matchadd('Conceal', 'TARGET', 10, -1, {'conceal': 't'})
+
+ redraw
+ call assert_equal('t_tt', Screenline(2))
+
+ quit!
+endfunction
+
+function! Test_matchadd_and_syn_conceal()
+ new
+ let cnt='Inductive bool : Type := | true : bool | false : bool.'
+ let expect = 'Inductive - : Type := | true : - | false : -.'
+ 0put =cnt
+ " set filetype and :syntax on to change screenattr()
+ set cole=1 cocu=nv
+ hi link CheckedByCoq WarningMsg
+ syntax on
+ syntax keyword coqKwd bool conceal cchar=-
+ redraw!
+ call assert_equal(expect, Screenline(1))
+ call assert_notequal(screenattr(1, 10) , screenattr(1, 11))
+ call assert_notequal(screenattr(1, 11) , screenattr(1, 12))
+ call assert_equal(screenattr(1, 11) , screenattr(1, 32))
+ call matchadd('CheckedByCoq', '\%<2l\%>9c\%<16c')
+ redraw!
+ call assert_equal(expect, Screenline(1))
+ call assert_notequal(screenattr(1, 10) , screenattr(1, 11))
+ call assert_notequal(screenattr(1, 11) , screenattr(1, 12))
+ call assert_equal(screenattr(1, 11) , screenattr(1, 32))
+endfunction
diff --git a/src/nvim/testdir/test_matchadd_conceal_utf8.vim b/src/nvim/testdir/test_matchadd_conceal_utf8.vim
new file mode 100644
index 0000000000..24c848a99c
--- /dev/null
+++ b/src/nvim/testdir/test_matchadd_conceal_utf8.vim
@@ -0,0 +1,39 @@
+" Test for matchadd() and conceal feature using utf-8.
+if !has('conceal') || !has('multi_byte')
+ finish
+endif
+
+function! s:screenline(lnum) abort
+ let line = []
+ for c in range(1, winwidth(0))
+ call add(line, nr2char(screenchar(a:lnum, c)))
+ endfor
+ return s:trim(join(line, ''))
+endfunction
+
+function! s:trim(str) abort
+ return matchstr(a:str,'^\s*\zs.\{-}\ze\s*$')
+endfunction
+
+function! Test_match_using_multibyte_conceal_char()
+ new
+ setlocal concealcursor=n conceallevel=1
+
+ 1put='# This is a Test'
+ " 1234567890123456
+ let expect = '#ˑThisˑisˑaˑTest'
+
+ call cursor(1, 1)
+ call matchadd('Conceal', '\%2l ', 20, -1, {'conceal': "\u02d1"})
+ redraw!
+
+ let lnum = 2
+ call assert_equal(expect, s:screenline(lnum))
+ call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
+ call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
+ call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
+
+ quit!
+endfunction
diff --git a/src/nvim/testdir/test_menu.vim b/src/nvim/testdir/test_menu.vim
index be559467c8..af18760065 100644
--- a/src/nvim/testdir/test_menu.vim
+++ b/src/nvim/testdir/test_menu.vim
@@ -4,6 +4,6 @@ func Test_load_menu()
try
source $VIMRUNTIME/menu.vim
catch
- call assert_false(1, 'error while loading menus: ' . v:exception)
+ call assert_report('error while loading menus: ' . v:exception)
endtry
endfunc
diff --git a/src/nvim/testdir/test_messages.vim b/src/nvim/testdir/test_messages.vim
new file mode 100644
index 0000000000..12101ec1f8
--- /dev/null
+++ b/src/nvim/testdir/test_messages.vim
@@ -0,0 +1,45 @@
+" Tests for :messages
+
+function Test_messages()
+ let oldmore = &more
+ try
+ set nomore
+ " Avoid the "message maintainer" line.
+ let $LANG = ''
+
+ let arr = map(range(10), '"hello" . v:val')
+ for s in arr
+ echomsg s | redraw
+ endfor
+ let result = ''
+
+ " get last two messages
+ redir => result
+ 2messages | redraw
+ redir END
+ let msg_list = split(result, "\n")
+ call assert_equal(["hello8", "hello9"], msg_list)
+
+ " clear messages without last one
+ 1messages clear
+ redir => result
+ redraw | messages
+ redir END
+ let msg_list = split(result, "\n")
+ call assert_equal(['hello9'], msg_list)
+
+ " clear all messages
+ messages clear
+ redir => result
+ redraw | messages
+ redir END
+ call assert_equal('', result)
+ finally
+ let &more = oldmore
+ endtry
+endfunction
+
+func Test_message_completion()
+ call feedkeys(":message \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"message clear', @:)
+endfunc
diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim
new file mode 100644
index 0000000000..9ba264deb6
--- /dev/null
+++ b/src/nvim/testdir/test_mksession.vim
@@ -0,0 +1,241 @@
+" Test for :mksession, :mkview and :loadview in latin1 encoding
+
+scriptencoding latin1
+
+if !has('multi_byte') || !has('mksession')
+ finish
+endif
+
+func Test_mksession()
+ tabnew
+ let wrap_save = &wrap
+ set sessionoptions=buffers splitbelow fileencoding=latin1
+ call setline(1, [
+ \ 'start:',
+ \ 'no multibyte chAracter',
+ \ ' one leaDing tab',
+ \ ' four leadinG spaces',
+ \ 'two consecutive tabs',
+ \ 'two tabs in one line',
+ \ 'one ä multibyteCharacter',
+ \ 'aä Ä two multiByte characters',
+ \ 'Aäöü three mulTibyte characters',
+ \ 'short line',
+ \ ])
+ let tmpfile = 'Xtemp'
+ exec 'w! ' . tmpfile
+ /^start:
+ set wrap
+ vsplit
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j8|
+ split
+ norm! j8|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j$
+ wincmd l
+
+ set nowrap
+ /^start:
+ norm! j16|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j08|3zl
+ split
+ norm! j08|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ call wincol()
+ mksession! Xtest_mks.out
+ let li = filter(readfile('Xtest_mks.out'), 'v:val =~# "\\(^ *normal! [0$]\\|^ *exe ''normal!\\)"')
+ let expected = [
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 08|',
+ \ 'normal! 08|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! $',
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+ \ " normal! 08|",
+ \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+ \ " normal! 08|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|"
+ \ ]
+ call assert_equal(expected, li)
+ tabclose!
+
+ call delete('Xtest_mks.out')
+ call delete(tmpfile)
+ let &wrap = wrap_save
+endfunc
+
+func Test_mksession_winheight()
+ new
+ set winheight=10 winminheight=2
+ mksession! Xtest_mks.out
+ source Xtest_mks.out
+
+ call delete('Xtest_mks.out')
+endfunc
+
+" Verify that arglist is stored correctly to the session file.
+func Test_mksession_arglist()
+ argdel *
+ next file1 file2 file3 file4
+ mksession! Xtest_mks.out
+ source Xtest_mks.out
+ call assert_equal(['file1', 'file2', 'file3', 'file4'], argv())
+
+ call delete('Xtest_mks.out')
+ argdel *
+endfunc
+
+
+func Test_mksession_one_buffer_two_windows()
+ edit Xtest1
+ new Xtest2
+ split
+ mksession! Xtest_mks.out
+ let lines = readfile('Xtest_mks.out')
+ let count1 = 0
+ let count2 = 0
+ let count2buf = 0
+ for line in lines
+ if line =~ 'edit \f*Xtest1$'
+ let count1 += 1
+ endif
+ if line =~ 'edit \f\{-}Xtest2'
+ let count2 += 1
+ endif
+ if line =~ 'buffer \f\{-}Xtest2'
+ let count2buf += 1
+ endif
+ endfor
+ call assert_equal(1, count1, 'Xtest1 count')
+ call assert_equal(2, count2, 'Xtest2 count')
+ call assert_equal(2, count2buf, 'Xtest2 buffer count')
+
+ close
+ bwipe!
+ call delete('Xtest_mks.out')
+endfunc
+
+" Test :mkview with a file argument.
+func Test_mkview_file()
+ " Create a view with line number and a fold.
+ help :mkview
+ set number
+ norm! V}zf0
+ let pos = getpos('.')
+ let linefoldclosed1 = foldclosed('.')
+ mkview! Xview
+ set nonumber
+ norm! zrj
+ " We can close the help window, as mkview with a file name should
+ " generate a command to edit the file.
+ helpclose
+
+ source Xview
+ call assert_equal(1, &number)
+ call assert_match('\*:mkview\*$', getline('.'))
+ call assert_equal(pos, getpos('.'))
+ call assert_equal(linefoldclosed1, foldclosed('.'))
+
+ " Creating a view again with the same file name should fail (file
+ " already exists). But with a !, the previous view should be
+ " overwritten without error.
+ help :loadview
+ call assert_fails('mkview Xview', 'E189:')
+ call assert_match('\*:loadview\*$', getline('.'))
+ mkview! Xview
+ call assert_match('\*:loadview\*$', getline('.'))
+
+ call delete('Xview')
+ bwipe
+endfunc
+
+" Test :mkview and :loadview with a custom 'viewdir'.
+func Test_mkview_loadview_with_viewdir()
+ set viewdir=Xviewdir
+
+ help :mkview
+ set number
+ norm! V}zf
+ let pos = getpos('.')
+ let linefoldclosed1 = foldclosed('.')
+ mkview 1
+ set nonumber
+ norm! zrj
+
+ loadview 1
+
+ " The directory Xviewdir/ should have been created and the view
+ " should be stored in that directory.
+ let pathsep = has('win32') ? '\' : '/'
+ call assert_equal('Xviewdir' . pathsep .
+ \ substitute(
+ \ substitute(
+ \ expand('%:p'), pathsep, '=+', 'g'), ':', '=-', 'g') . '=1.vim',
+ \ glob('Xviewdir/*'))
+ call assert_equal(1, &number)
+ call assert_match('\*:mkview\*$', getline('.'))
+ call assert_equal(pos, getpos('.'))
+ call assert_equal(linefoldclosed1, foldclosed('.'))
+
+ call delete('Xviewdir', 'rf')
+ set viewdir&
+ helpclose
+endfunc
+
+func Test_mkview_no_file_name()
+ new
+ " :mkview or :mkview {nr} should fail in a unnamed buffer.
+ call assert_fails('mkview', 'E32:')
+ call assert_fails('mkview 1', 'E32:')
+
+ " :mkview {file} should succeed in a unnamed buffer.
+ mkview Xview
+ help
+ source Xview
+ call assert_equal('', bufname('%'))
+
+ call delete('Xview')
+ %bwipe
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_mksession_utf8.vim b/src/nvim/testdir/test_mksession_utf8.vim
new file mode 100644
index 0000000000..8ffbba2a1c
--- /dev/null
+++ b/src/nvim/testdir/test_mksession_utf8.vim
@@ -0,0 +1,105 @@
+" Test for :mksession, :mkview and :loadview in utf-8 encoding
+
+set encoding=utf-8
+scriptencoding utf-8
+
+if !has('multi_byte') || !has('mksession')
+ finish
+endif
+
+func Test_mksession_utf8()
+ tabnew
+ let wrap_save = &wrap
+ set sessionoptions=buffers splitbelow fileencoding=utf-8
+ call setline(1, [
+ \ 'start:',
+ \ 'no multibyte chAracter',
+ \ ' one leaDing tab',
+ \ ' four leadinG spaces',
+ \ 'two consecutive tabs',
+ \ 'two tabs in one line',
+ \ 'one … multibyteCharacter',
+ \ 'a “b†two multiByte characters',
+ \ '“câ€1€ three mulTibyte characters'
+ \ ])
+ let tmpfile = tempname()
+ exec 'w! ' . tmpfile
+ /^start:
+ set wrap
+ vsplit
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j8|
+ split
+ norm! j8|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ split
+ norm! j16|
+ wincmd l
+
+ set nowrap
+ /^start:
+ norm! j16|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j08|3zl
+ split
+ norm! j08|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ norm! j016|3zl
+ split
+ call wincol()
+ mksession! test_mks.out
+ let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"')
+ let expected = [
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 08|',
+ \ 'normal! 08|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ 'normal! 016|',
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+ \ " normal! 08|",
+ \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'",
+ \ " normal! 08|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|",
+ \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'",
+ \ " normal! 016|"
+ \ ]
+ call assert_equal(expected, li)
+ tabclose!
+
+ call delete('test_mks.out')
+ call delete(tmpfile)
+ let &wrap = wrap_save
+ set sessionoptions& splitbelow& fileencoding&
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_move.vim b/src/nvim/testdir/test_move.vim
new file mode 100644
index 0000000000..d774c93dbd
--- /dev/null
+++ b/src/nvim/testdir/test_move.vim
@@ -0,0 +1,40 @@
+" Test the ":move" command.
+
+func Test_move()
+ enew!
+ call append(0, ['line 1', 'line 2', 'line 3'])
+ g /^$/ delete _
+ set nomodified
+
+ move .
+ call assert_equal(['line 1', 'line 2', 'line 3'], getline(1, 3))
+ call assert_false(&modified)
+
+ 1,2move 0
+ call assert_equal(['line 1', 'line 2', 'line 3'], getline(1, 3))
+ call assert_false(&modified)
+
+ 1,3move 3
+ call assert_equal(['line 1', 'line 2', 'line 3'], getline(1, 3))
+ call assert_false(&modified)
+
+ 1move 2
+ call assert_equal(['line 2', 'line 1', 'line 3'], getline(1, 3))
+ call assert_true(&modified)
+ set nomodified
+
+ 3move 0
+ call assert_equal(['line 3', 'line 2', 'line 1'], getline(1, 3))
+ call assert_true(&modified)
+ set nomodified
+
+ 2,3move 0
+ call assert_equal(['line 2', 'line 1', 'line 3'], getline(1, 3))
+ call assert_true(&modified)
+ set nomodified
+
+ call assert_fails('1,2move 1', 'E134')
+ call assert_fails('2,3move 2', 'E134')
+
+ %bwipeout!
+endfunc
diff --git a/src/nvim/testdir/test_nested_function.vim b/src/nvim/testdir/test_nested_function.vim
new file mode 100644
index 0000000000..afaaea6ceb
--- /dev/null
+++ b/src/nvim/testdir/test_nested_function.vim
@@ -0,0 +1,63 @@
+"Tests for nested functions
+"
+func NestedFunc()
+ func! Func1()
+ let g:text .= 'Func1 '
+ endfunc
+ call Func1()
+ func! s:func2()
+ let g:text .= 's:func2 '
+ endfunc
+ call s:func2()
+ func! s:_func3()
+ let g:text .= 's:_func3 '
+ endfunc
+ call s:_func3()
+ let fn = 'Func4'
+ func! {fn}()
+ let g:text .= 'Func4 '
+ endfunc
+ call {fn}()
+ let fn = 'func5'
+ func! s:{fn}()
+ let g:text .= 's:func5'
+ endfunc
+ call s:{fn}()
+endfunc
+
+func Test_nested_functions()
+ let g:text = ''
+ call NestedFunc()
+ call assert_equal('Func1 s:func2 s:_func3 Func4 s:func5', g:text)
+endfunction
+
+func Test_nested_argument()
+ func g:X()
+ let g:Y = function('sort')
+ endfunc
+ let g:Y = function('sort')
+ echo g:Y([], g:X())
+ delfunc g:X
+ unlet g:Y
+endfunc
+
+func Recurse(count)
+ if a:count > 0
+ call Recurse(a:count - 1)
+ endif
+endfunc
+
+func Test_max_nesting()
+ let call_depth_here = 2
+ let ex_depth_here = 5
+ set mfd&
+
+ call Recurse(99 - call_depth_here)
+ call assert_fails('call Recurse(' . (100 - call_depth_here) . ')', 'E132:')
+
+ set mfd=210
+ call Recurse(209 - ex_depth_here)
+ call assert_fails('call Recurse(' . (210 - ex_depth_here) . ')', 'E169:')
+
+ set mfd&
+endfunc
diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim
new file mode 100644
index 0000000000..d07b3fdbce
--- /dev/null
+++ b/src/nvim/testdir/test_normal.vim
@@ -0,0 +1,2542 @@
+" Test for various Normal mode commands
+
+source shared.vim
+
+func! Setup_NewWindow()
+ 10new
+ call setline(1, range(1,100))
+endfunc
+
+func! MyFormatExpr()
+ " Adds '->$' at lines having numbers followed by trailing whitespace
+ for ln in range(v:lnum, v:lnum+v:count-1)
+ let line = getline(ln)
+ if getline(ln) =~# '\d\s\+$'
+ call setline(ln, substitute(line, '\s\+$', '', '') . '->$')
+ endif
+ endfor
+endfunc
+
+func! CountSpaces(type, ...)
+ " for testing operatorfunc
+ " will count the number of spaces
+ " and return the result in g:a
+ let sel_save = &selection
+ let &selection = "inclusive"
+ let reg_save = @@
+
+ if a:0 " Invoked from Visual mode, use gv command.
+ silent exe "normal! gvy"
+ elseif a:type == 'line'
+ silent exe "normal! '[V']y"
+ else
+ silent exe "normal! `[v`]y"
+ endif
+ let g:a=strlen(substitute(@@, '[^ ]', '', 'g'))
+ let &selection = sel_save
+ let @@ = reg_save
+endfunc
+
+func! OpfuncDummy(type, ...)
+ " for testing operatorfunc
+ let g:opt=&linebreak
+
+ if a:0 " Invoked from Visual mode, use gv command.
+ silent exe "normal! gvy"
+ elseif a:type == 'line'
+ silent exe "normal! '[V']y"
+ else
+ silent exe "normal! `[v`]y"
+ endif
+ " Create a new dummy window
+ new
+ let g:bufnr=bufnr('%')
+endfunc
+
+fun! Test_normal00_optrans()
+ new
+ call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
+ 1
+ exe "norm! Sfoobar\<esc>"
+ call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$'))
+ 2
+ exe "norm! $vbsone"
+ call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$'))
+ norm! VS Second line here
+ call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$'))
+ %d
+ call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line'])
+ call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line'])
+
+ 1
+ norm! 2D
+ call assert_equal(['3 this is the third line', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
+ " Nvim: no "#" flag in 'cpoptions'.
+ " set cpo+=#
+ " norm! 4D
+ " call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$'))
+
+ " clean up
+ set cpo-=#
+ bw!
+endfunc
+
+func! Test_normal01_keymodel()
+ throw "skipped: Nvim regression: 'keymodel'"
+ call Setup_NewWindow()
+ " Test 1: depending on 'keymodel' <s-down> does something different
+ 50
+ call feedkeys("V\<S-Up>y", 'tx')
+ call assert_equal(['47', '48', '49', '50'], getline("'<", "'>"))
+ set keymodel=startsel
+ 50
+ call feedkeys("V\<S-Up>y", 'tx')
+ call assert_equal(['49', '50'], getline("'<", "'>"))
+ " Start visual mode when keymodel = startsel
+ 50
+ call feedkeys("\<S-Up>y", 'tx')
+ call assert_equal(['49', '5'], getreg(0, 0, 1))
+ " Do not start visual mode when keymodel=
+ set keymodel=
+ 50
+ call feedkeys("\<S-Up>y$", 'tx')
+ call assert_equal(['42'], getreg(0, 0, 1))
+ " Stop visual mode when keymodel=stopsel
+ set keymodel=stopsel
+ 50
+ call feedkeys("Vkk\<Up>yy", 'tx')
+ call assert_equal(['47'], getreg(0, 0, 1))
+
+ set keymodel=
+ 50
+ call feedkeys("Vkk\<Up>yy", 'tx')
+ call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal02_selectmode()
+ " some basic select mode tests
+ call Setup_NewWindow()
+ 50
+ norm! gHy
+ call assert_equal('y51', getline('.'))
+ call setline(1, range(1,100))
+ 50
+ exe ":norm! V9jo\<c-g>y"
+ call assert_equal('y60', getline('.'))
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal02_selectmode2()
+ " some basic select mode tests
+ call Setup_NewWindow()
+ 50
+ call feedkeys(":set im\n\<c-o>gHc\<c-o>:set noim\n", 'tx')
+ call assert_equal('c51', getline('.'))
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal03_join()
+ " basic join test
+ call Setup_NewWindow()
+ 50
+ norm! VJ
+ call assert_equal('50 51', getline('.'))
+ $
+ norm! J
+ call assert_equal('100', getline('.'))
+ $
+ norm! V9-gJ
+ call assert_equal('919293949596979899100', getline('.'))
+ call setline(1, range(1,100))
+ $
+ :j 10
+ call assert_equal('100', getline('.'))
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal04_filter()
+ " basic filter test
+ " only test on non windows platform
+ if has('win32')
+ return
+ endif
+ call Setup_NewWindow()
+ 1
+ call feedkeys("!!sed -e 's/^/| /'\n", 'tx')
+ call assert_equal('| 1', getline('.'))
+ 90
+ :sil :!echo one
+ call feedkeys('.', 'tx')
+ call assert_equal('| 90', getline('.'))
+ 95
+ set cpo+=!
+ " 2 <CR>, 1: for executing the command,
+ " 2: clear hit-enter-prompt
+ call feedkeys("!!\n", 'tx')
+ call feedkeys(":!echo one\n\n", 'tx')
+ call feedkeys(".", 'tx')
+ call assert_equal('one', getline('.'))
+ set cpo-=!
+ bw!
+endfunc
+
+func! Test_normal05_formatexpr()
+ " basic formatexpr test
+ call Setup_NewWindow()
+ %d_
+ call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: '])
+ 1
+ set formatexpr=MyFormatExpr()
+ norm! gqG
+ call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$'))
+ set formatexpr=
+ bw!
+endfunc
+
+func Test_normal05_formatexpr_newbuf()
+ " Edit another buffer in the 'formatexpr' function
+ new
+ func! Format()
+ edit another
+ endfunc
+ set formatexpr=Format()
+ norm gqG
+ bw!
+ set formatexpr=
+endfunc
+
+func Test_normal05_formatexpr_setopt()
+ " Change the 'formatexpr' value in the function
+ new
+ func! Format()
+ set formatexpr=
+ endfunc
+ set formatexpr=Format()
+ norm gqG
+ bw!
+ set formatexpr=
+endfunc
+
+func! Test_normal06_formatprg()
+ " basic test for formatprg
+ " only test on non windows platform
+ if has('win32')
+ return
+ endif
+
+ " uses sed to number non-empty lines
+ call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh')
+ call system('chmod +x ./Xsed_format.sh')
+ let text = ['a', '', 'c', '', ' ', 'd', 'e']
+ let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e']
+
+ 10new
+ call setline(1, text)
+ set formatprg=./Xsed_format.sh
+ norm! gggqG
+ call assert_equal(expected, getline(1, '$'))
+ bw!
+
+ 10new
+ call setline(1, text)
+ set formatprg=donothing
+ setlocal formatprg=./Xsed_format.sh
+ norm! gggqG
+ call assert_equal(expected, getline(1, '$'))
+ bw!
+
+ " clean up
+ set formatprg=
+ setlocal formatprg=
+ call delete('Xsed_format.sh')
+endfunc
+
+func! Test_normal07_internalfmt()
+ " basic test for internal formmatter to textwidth of 12
+ let list=range(1,11)
+ call map(list, 'v:val." "')
+ 10new
+ call setline(1, list)
+ set tw=12
+ norm! gggqG
+ call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$'))
+ " clean up
+ set tw=0
+ bw!
+endfunc
+
+func! Test_normal08_fold()
+ " basic tests for foldopen/folddelete
+ if !has("folding")
+ return
+ endif
+ call Setup_NewWindow()
+ 50
+ setl foldenable fdm=marker
+ " First fold
+ norm! V4jzf
+ " check that folds have been created
+ call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54))
+ " Second fold
+ 46
+ norm! V10jzf
+ " check that folds have been created
+ call assert_equal('46/*{{{*/', getline(46))
+ call assert_equal('60/*}}}*/', getline(60))
+ norm! k
+ call assert_equal('45', getline('.'))
+ norm! j
+ call assert_equal('46/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('61', getline('.'))
+ norm! k
+ " open a fold
+ norm! Vzo
+ norm! k
+ call assert_equal('45', getline('.'))
+ norm! j
+ call assert_equal('46/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('47', getline('.'))
+ norm! k
+ norm! zcVzO
+ call assert_equal('46/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('47', getline('.'))
+ norm! j
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51', getline('.'))
+ " delete folds
+ :46
+ " collapse fold
+ norm! V14jzC
+ " delete all folds recursively
+ norm! VzD
+ call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60))
+
+ " clean up
+ setl nofoldenable fdm=marker
+ bw!
+endfunc
+
+func! Test_normal09_operatorfunc()
+ " Test operatorfunc
+ call Setup_NewWindow()
+ " Add some spaces for counting
+ 50,60s/$/ /
+ unlet! g:a
+ let g:a=0
+ nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@
+ vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR>
+ 50
+ norm V2j,,
+ call assert_equal(6, g:a)
+ norm V,,
+ call assert_equal(2, g:a)
+ norm ,,l
+ call assert_equal(0, g:a)
+ 50
+ exe "norm 0\<c-v>10j2l,,"
+ call assert_equal(11, g:a)
+ 50
+ norm V10j,,
+ call assert_equal(22, g:a)
+
+ " clean up
+ unmap <buffer> ,,
+ set opfunc=
+ unlet! g:a
+ bw!
+endfunc
+
+func! Test_normal09a_operatorfunc()
+ " Test operatorfunc
+ call Setup_NewWindow()
+ " Add some spaces for counting
+ 50,60s/$/ /
+ unlet! g:opt
+ set linebreak
+ nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@
+ 50
+ norm ,,j
+ exe "bd!" g:bufnr
+ call assert_true(&linebreak)
+ call assert_equal(g:opt, &linebreak)
+ set nolinebreak
+ norm ,,j
+ exe "bd!" g:bufnr
+ call assert_false(&linebreak)
+ call assert_equal(g:opt, &linebreak)
+
+ " clean up
+ unmap <buffer> ,,
+ set opfunc=
+ bw!
+ unlet! g:opt
+endfunc
+
+func! Test_normal10_expand()
+ " Test for expand()
+ 10new
+ call setline(1, ['1', 'ifooar,,cbar'])
+ 2
+ norm! $
+ call assert_equal('cbar', expand('<cword>'))
+ call assert_equal('ifooar,,cbar', expand('<cWORD>'))
+
+ call setline(1, ['prx = list[idx];'])
+ 1
+ let expected = ['', 'prx', 'prx', 'prx',
+ \ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
+ \ 'idx', 'idx', 'idx', 'idx',
+ \ 'list[idx]',
+ \ '];',
+ \ ]
+ for i in range(1, 16)
+ exe 'norm ' . i . '|'
+ call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
+ endfor
+
+ if executable('echo')
+ " Test expand(`...`) i.e. backticks command expansion.
+ " MS-Windows has a trailing space.
+ call assert_match('^abcde *$', expand('`echo abcde`'))
+ endif
+
+ " Test expand(`=...`) i.e. backticks expression expansion
+ call assert_equal('5', expand('`=2+3`'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal11_showcmd()
+ " test for 'showcmd'
+ 10new
+ exe "norm! ofoobar\<esc>"
+ call assert_equal(2, line('$'))
+ set showcmd
+ exe "norm! ofoobar2\<esc>"
+ call assert_equal(3, line('$'))
+ exe "norm! VAfoobar3\<esc>"
+ call assert_equal(3, line('$'))
+ exe "norm! 0d3\<del>2l"
+ call assert_equal('obar2foobar3', getline('.'))
+ bw!
+endfunc
+
+func! Test_normal12_nv_error()
+ " Test for nv_error
+ 10new
+ call setline(1, range(1,5))
+ " should not do anything, just beep
+ exe "norm! <c-k>"
+ call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$'))
+ bw!
+endfunc
+
+func! Test_normal13_help()
+ " Test for F1
+ call assert_equal(1, winnr())
+ call feedkeys("\<f1>", 'txi')
+ call assert_match('help\.txt', bufname('%'))
+ call assert_equal(2, winnr('$'))
+ bw!
+endfunc
+
+func! Test_normal14_page()
+ " basic test for Ctrl-F and Ctrl-B
+ call Setup_NewWindow()
+ exe "norm! \<c-f>"
+ call assert_equal('9', getline('.'))
+ exe "norm! 2\<c-f>"
+ call assert_equal('25', getline('.'))
+ exe "norm! 2\<c-b>"
+ call assert_equal('18', getline('.'))
+ 1
+ set scrolloff=5
+ exe "norm! 2\<c-f>"
+ call assert_equal('21', getline('.'))
+ exe "norm! \<c-b>"
+ call assert_equal('13', getline('.'))
+ 1
+ set scrolloff=99
+ exe "norm! \<c-f>"
+ call assert_equal('13', getline('.'))
+ set scrolloff=0
+ 100
+ exe "norm! $\<c-b>"
+ call assert_equal('92', getline('.'))
+ call assert_equal([0, 92, 1, 0, 1], getcurpos())
+ 100
+ set nostartofline
+ exe "norm! $\<c-b>"
+ call assert_equal('92', getline('.'))
+ call assert_equal([0, 92, 2, 0, 2147483647], getcurpos())
+ " cleanup
+ set startofline
+ bw!
+endfunc
+
+func! Test_normal14_page_eol()
+ 10new
+ norm oxxxxxxx
+ exe "norm 2\<c-f>"
+ " check with valgrind that cursor is put back in column 1
+ exe "norm 2\<c-b>"
+ bw!
+endfunc
+
+func! Test_normal15_z_scroll_vert()
+ " basic test for z commands that scroll the window
+ call Setup_NewWindow()
+ 100
+ norm! >>
+ " Test for z<cr>
+ exe "norm! z\<cr>"
+ call assert_equal(' 100', getline('.'))
+ call assert_equal(100, winsaveview()['topline'])
+ call assert_equal([0, 100, 2, 0, 9], getcurpos())
+
+ " Test for zt
+ 21
+ norm! >>0zt
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(21, winsaveview()['topline'])
+ call assert_equal([0, 21, 1, 0, 8], getcurpos())
+
+ " Test for zb
+ 30
+ norm! >>$ztzb
+ call assert_equal(' 30', getline('.'))
+ call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
+ call assert_equal([0, 30, 3, 0, 2147483647], getcurpos())
+
+ " Test for z-
+ 1
+ 30
+ norm! 0z-
+ call assert_equal(' 30', getline('.'))
+ call assert_equal(30, winsaveview()['topline']+winheight(0)-1)
+ call assert_equal([0, 30, 2, 0, 9], getcurpos())
+
+ " Test for z{height}<cr>
+ call assert_equal(10, winheight(0))
+ exe "norm! z12\<cr>"
+ call assert_equal(12, winheight(0))
+ exe "norm! z10\<cr>"
+ call assert_equal(10, winheight(0))
+
+ " Test for z.
+ 1
+ 21
+ norm! 0z.
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(17, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " Test for zz
+ 1
+ 21
+ norm! 0zz
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(17, winsaveview()['topline'])
+ call assert_equal([0, 21, 1, 0, 8], getcurpos())
+
+ " Test for z+
+ 11
+ norm! zt
+ norm! z+
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(21, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " Test for [count]z+
+ 1
+ norm! 21z+
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(21, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " Test for z^
+ norm! 22z+0
+ norm! z^
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(12, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " Test for [count]z^
+ 1
+ norm! 30z^
+ call assert_equal(' 21', getline('.'))
+ call assert_equal(12, winsaveview()['topline'])
+ call assert_equal([0, 21, 2, 0, 9], getcurpos())
+
+ " cleanup
+ bw!
+endfunc
+
+func! Test_normal16_z_scroll_hor()
+ " basic test for z commands that scroll the window
+ 10new
+ 15vsp
+ set nowrap listchars=
+ let lineA='abcdefghijklmnopqrstuvwxyz'
+ let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ $put =lineA
+ $put =lineB
+ 1d
+
+ " Test for zl
+ 1
+ norm! 5zl
+ call assert_equal(lineA, getline('.'))
+ call assert_equal(6, col('.'))
+ call assert_equal(5, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('f', @0)
+
+ " Test for zh
+ norm! 2zh
+ call assert_equal(lineA, getline('.'))
+ call assert_equal(6, col('.'))
+ norm! yl
+ call assert_equal('f', @0)
+ call assert_equal(3, winsaveview()['leftcol'])
+
+ " Test for zL
+ norm! zL
+ call assert_equal(11, col('.'))
+ norm! yl
+ call assert_equal('k', @0)
+ call assert_equal(10, winsaveview()['leftcol'])
+ norm! 2zL
+ call assert_equal(25, col('.'))
+ norm! yl
+ call assert_equal('y', @0)
+ call assert_equal(24, winsaveview()['leftcol'])
+
+ " Test for zH
+ norm! 2zH
+ call assert_equal(25, col('.'))
+ call assert_equal(10, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('y', @0)
+
+ " Test for zs
+ norm! $zs
+ call assert_equal(26, col('.'))
+ call assert_equal(25, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('z', @0)
+
+ " Test for ze
+ norm! ze
+ call assert_equal(26, col('.'))
+ call assert_equal(11, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('z', @0)
+
+ " cleanup
+ set wrap listchars=eol:$
+ bw!
+endfunc
+
+func! Test_normal17_z_scroll_hor2()
+ " basic test for z commands that scroll the window
+ " using 'sidescrolloff' setting
+ 10new
+ 20vsp
+ set nowrap listchars= sidescrolloff=5
+ let lineA='abcdefghijklmnopqrstuvwxyz'
+ let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ $put =lineA
+ $put =lineB
+ 1d
+
+ " Test for zl
+ 1
+ norm! 5zl
+ call assert_equal(lineA, getline('.'))
+ call assert_equal(11, col('.'))
+ call assert_equal(5, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('k', @0)
+
+ " Test for zh
+ norm! 2zh
+ call assert_equal(lineA, getline('.'))
+ call assert_equal(11, col('.'))
+ norm! yl
+ call assert_equal('k', @0)
+ call assert_equal(3, winsaveview()['leftcol'])
+
+ " Test for zL
+ norm! 0zL
+ call assert_equal(16, col('.'))
+ norm! yl
+ call assert_equal('p', @0)
+ call assert_equal(10, winsaveview()['leftcol'])
+ norm! 2zL
+ call assert_equal(26, col('.'))
+ norm! yl
+ call assert_equal('z', @0)
+ call assert_equal(15, winsaveview()['leftcol'])
+
+ " Test for zH
+ norm! 2zH
+ call assert_equal(15, col('.'))
+ call assert_equal(0, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('o', @0)
+
+ " Test for zs
+ norm! $zs
+ call assert_equal(26, col('.'))
+ call assert_equal(20, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('z', @0)
+
+ " Test for ze
+ norm! ze
+ call assert_equal(26, col('.'))
+ call assert_equal(11, winsaveview()['leftcol'])
+ norm! yl
+ call assert_equal('z', @0)
+
+ " cleanup
+ set wrap listchars=eol:$ sidescrolloff=0
+ bw!
+endfunc
+
+func! Test_normal18_z_fold()
+ " basic tests for foldopen/folddelete
+ if !has("folding")
+ return
+ endif
+ call Setup_NewWindow()
+ 50
+ setl foldenable fdm=marker foldlevel=5
+
+ " Test for zF
+ " First fold
+ norm! 4zF
+ " check that folds have been created
+ call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53))
+
+ " Test for zd
+ 51
+ norm! 2zF
+ call assert_equal(2, foldlevel('.'))
+ norm! kzd
+ call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53))
+ norm! j
+ call assert_equal(1, foldlevel('.'))
+
+ " Test for zD
+ " also deletes partially selected folds recursively
+ 51
+ norm! zF
+ call assert_equal(2, foldlevel('.'))
+ norm! kV2jzD
+ call assert_equal(['50', '51', '52', '53'], getline(50,53))
+
+ " Test for zE
+ 85
+ norm! 4zF
+ 86
+ norm! 2zF
+ 90
+ norm! 4zF
+ call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93))
+ norm! zE
+ call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93))
+
+ " Test for zn
+ 50
+ set foldlevel=0
+ norm! 2zF
+ norm! zn
+ norm! k
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ call assert_equal(0, &foldenable)
+
+ " Test for zN
+ 49
+ norm! zN
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ call assert_equal(1, &foldenable)
+
+ " Test for zi
+ norm! zi
+ call assert_equal(0, &foldenable)
+ norm! zi
+ call assert_equal(1, &foldenable)
+ norm! zi
+ call assert_equal(0, &foldenable)
+ norm! zi
+ call assert_equal(1, &foldenable)
+
+ " Test for za
+ 50
+ norm! za
+ norm! k
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ 50
+ norm! za
+ norm! k
+ call assert_equal('49', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ 49
+ norm! 5zF
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+ 49
+ norm! za
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ set nofoldenable
+ " close fold and set foldenable
+ norm! za
+ call assert_equal(1, &foldenable)
+
+ 50
+ " have to use {count}za to open all folds and make the cursor visible
+ norm! 2za
+ norm! 2k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ " Test for zA
+ 49
+ set foldlevel=0
+ 50
+ norm! zA
+ norm! 2k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ " zA on a opened fold when foldenable is not set
+ 50
+ set nofoldenable
+ norm! zA
+ call assert_equal(1, &foldenable)
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zc
+ norm! zE
+ 50
+ norm! 2zF
+ 49
+ norm! 5zF
+ set nofoldenable
+ 50
+ " There most likely is a bug somewhere:
+ " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ
+ " TODO: Should this only close the inner most fold or both folds?
+ norm! zc
+ call assert_equal(1, &foldenable)
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+ set nofoldenable
+ 50
+ norm! Vjzc
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zC
+ set nofoldenable
+ 50
+ norm! zCk
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zx
+ " 1) close folds at line 49-54
+ set nofoldenable
+ 48
+ norm! zx
+ call assert_equal(1, &foldenable)
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " 2) do not close fold under cursor
+ 51
+ set nofoldenable
+ norm! zx
+ call assert_equal(1, &foldenable)
+ norm! 3k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ norm! j
+ call assert_equal('53', getline('.'))
+ norm! j
+ call assert_equal('54/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " 3) close one level of folds
+ 48
+ set nofoldenable
+ set foldlevel=1
+ norm! zx
+ call assert_equal(1, &foldenable)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ norm! j
+ call assert_equal('53', getline('.'))
+ norm! j
+ call assert_equal('54/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zX
+ " Close all folds
+ set foldlevel=0 nofoldenable
+ 50
+ norm! zX
+ call assert_equal(1, &foldenable)
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zm
+ 50
+ set nofoldenable foldlevel=2
+ norm! zm
+ call assert_equal(1, &foldenable)
+ call assert_equal(1, &foldlevel)
+ norm! zm
+ call assert_equal(0, &foldlevel)
+ norm! zm
+ call assert_equal(0, &foldlevel)
+ norm! k
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zM
+ 48
+ set nofoldenable foldlevel=99
+ norm! zM
+ call assert_equal(1, &foldenable)
+ call assert_equal(0, &foldlevel)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('55', getline('.'))
+
+ " Test for zr
+ 48
+ set nofoldenable foldlevel=0
+ norm! zr
+ call assert_equal(0, &foldenable)
+ call assert_equal(1, &foldlevel)
+ set foldlevel=0 foldenable
+ norm! zr
+ call assert_equal(1, &foldenable)
+ call assert_equal(1, &foldlevel)
+ norm! zr
+ call assert_equal(2, &foldlevel)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ " Test for zR
+ 48
+ set nofoldenable foldlevel=0
+ norm! zR
+ call assert_equal(0, &foldenable)
+ call assert_equal(2, &foldlevel)
+ set foldenable foldlevel=0
+ norm! zR
+ call assert_equal(1, &foldenable)
+ call assert_equal(2, &foldlevel)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ call append(50, ['a /*{{{*/', 'b /*}}}*/'])
+ 48
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('a /*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+ 48
+ norm! zR
+ call assert_equal(1, &foldenable)
+ call assert_equal(3, &foldlevel)
+ call assert_equal('48', getline('.'))
+ norm! j
+ call assert_equal('49/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('50/*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('a /*{{{*/', getline('.'))
+ norm! j
+ call assert_equal('b /*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('51/*}}}*/', getline('.'))
+ norm! j
+ call assert_equal('52', getline('.'))
+
+ " clean up
+ setl nofoldenable fdm=marker foldlevel=0
+ bw!
+endfunc
+
+func! Test_normal19_z_spell()
+ if !has("spell") || !has('syntax')
+ return
+ endif
+ new
+ call append(0, ['1 good', '2 goood', '3 goood'])
+ set spell spellfile=./Xspellfile.add spelllang=en
+ let oldlang=v:lang
+ lang C
+
+ " Test for zg
+ 1
+ norm! ]s
+ call assert_equal('2 goood', getline('.'))
+ norm! zg
+ 1
+ let a=execute('unsilent :norm! ]s')
+ call assert_equal('1 good', getline('.'))
+ call assert_equal('search hit BOTTOM, continuing at TOP', a[1:])
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('goood', cnt[0])
+
+ " Test for zw
+ 2
+ norm! $zw
+ 1
+ norm! ]s
+ call assert_equal('2 goood', getline('.'))
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('#oood', cnt[0])
+ call assert_equal('goood/!', cnt[1])
+
+ " Test for zg in visual mode
+ let a=execute('unsilent :norm! V$zg')
+ call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
+ 1
+ norm! ]s
+ call assert_equal('3 goood', getline('.'))
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('2 goood', cnt[2])
+ " Remove "2 good" from spellfile
+ 2
+ let a=execute('unsilent norm! V$zw')
+ call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('2 goood/!', cnt[3])
+
+ " Test for zG
+ let a=execute('unsilent norm! V$zG')
+ call assert_match("Word '2 goood' added to .*", a)
+ let fname=matchstr(a, 'to\s\+\zs\f\+$')
+ let fname=Fix_truncated_tmpfile(fname)
+ let cnt=readfile(fname)
+ call assert_equal('2 goood', cnt[0])
+
+ " Test for zW
+ let a=execute('unsilent norm! V$zW')
+ call assert_match("Word '2 goood' added to .*", a)
+ let cnt=readfile(fname)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('2 goood/!', cnt[1])
+
+ " Test for zuW
+ let a=execute('unsilent norm! V$zuW')
+ call assert_match("Word '2 goood' removed from .*", a)
+ let cnt=readfile(fname)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('# goood/!', cnt[1])
+
+ " Test for zuG
+ let a=execute('unsilent norm! $zG')
+ call assert_match("Word 'goood' added to .*", a)
+ let cnt=readfile(fname)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('# goood/!', cnt[1])
+ call assert_equal('goood', cnt[2])
+ let a=execute('unsilent norm! $zuG')
+ let cnt=readfile(fname)
+ call assert_match("Word 'goood' removed from .*", a)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('# goood/!', cnt[1])
+ call assert_equal('#oood', cnt[2])
+ " word not found in wordlist
+ let a=execute('unsilent norm! V$zuG')
+ let cnt=readfile(fname)
+ call assert_match("", a)
+ call assert_equal('# goood', cnt[0])
+ call assert_equal('# goood/!', cnt[1])
+ call assert_equal('#oood', cnt[2])
+
+ " Test for zug
+ call delete('./Xspellfile.add')
+ 2
+ let a=execute('unsilent norm! $zg')
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('goood', cnt[0])
+ let a=execute('unsilent norm! $zug')
+ call assert_match("Word 'goood' removed from \./Xspellfile.add", a)
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('#oood', cnt[0])
+ " word not in wordlist
+ let a=execute('unsilent norm! V$zug')
+ call assert_match('', a)
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('#oood', cnt[0])
+
+ " Test for zuw
+ call delete('./Xspellfile.add')
+ 2
+ let a=execute('unsilent norm! Vzw')
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('2 goood/!', cnt[0])
+ let a=execute('unsilent norm! Vzuw')
+ call assert_match("Word '2 goood' removed from \./Xspellfile.add", a)
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('# goood/!', cnt[0])
+ " word not in wordlist
+ let a=execute('unsilent norm! $zug')
+ call assert_match('', a)
+ let cnt=readfile('./Xspellfile.add')
+ call assert_equal('# goood/!', cnt[0])
+
+ " add second entry to spellfile setting
+ set spellfile=./Xspellfile.add,./Xspellfile2.add
+ call delete('./Xspellfile.add')
+ 2
+ let a=execute('unsilent norm! $2zg')
+ let cnt=readfile('./Xspellfile2.add')
+ call assert_match("Word 'goood' added to ./Xspellfile2.add", a)
+ call assert_equal('goood', cnt[0])
+
+ " Test for :spellgood!
+ let temp = execute(':spe!0/0')
+ call assert_match('Invalid region', temp)
+ let spellfile = matchstr(temp, 'Invalid region nr in \zs.*\ze line \d: 0')
+ call assert_equal(['# goood', '# goood/!', '#oood', '0/0'], readfile(spellfile))
+ call delete(spellfile)
+
+ " clean up
+ exe "lang" oldlang
+ call delete("./Xspellfile.add")
+ call delete("./Xspellfile2.add")
+ call delete("./Xspellfile.add.spl")
+ call delete("./Xspellfile2.add.spl")
+
+ " zux -> no-op
+ 2
+ norm! $zux
+ call assert_equal([], glob('Xspellfile.add',0,1))
+ call assert_equal([], glob('Xspellfile2.add',0,1))
+
+ set spellfile=
+ bw!
+endfunc
+
+func! Test_normal20_exmode()
+ if !has("unix")
+ " Reading from redirected file doesn't work on MS-Windows
+ return
+ endif
+ call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript')
+ call writefile(['1', '2'], 'Xfile')
+ call system(v:progpath .' -e -s < Xscript Xfile')
+ let a=readfile('Xfile2')
+ call assert_equal(['1', 'foo', 'bar', '2'], a)
+
+ " clean up
+ for file in ['Xfile', 'Xfile2', 'Xscript']
+ call delete(file)
+ endfor
+ bw!
+endfunc
+
+func! Test_normal21_nv_hat()
+ set hidden
+ new
+ " to many buffers opened already, will not work
+ "call assert_fails(":b#", 'E23')
+ "call assert_equal('', @#)
+ e Xfoobar
+ e Xfile2
+ call feedkeys("\<c-^>", 't')
+ call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t'))
+ call feedkeys("f\<c-^>", 't')
+ call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t'))
+ " clean up
+ set nohidden
+ bw!
+endfunc
+
+func! Test_normal22_zet()
+ " Test for ZZ
+ " let shell = &shell
+ " let &shell = 'sh'
+
+ " Remove any stale test files from previous run.
+ for file in ['Xfile_Test_normal22_zet']
+ call delete(file)
+ endfor
+
+ call writefile(['1', '2'], 'Xfile_Test_normal22_zet')
+ let args = ' --headless -u NONE -N -U NONE -i NONE --noplugins'
+ call system(v:progpath . args . ' -c "%d" -c ":norm! ZZ" Xfile_Test_normal22_zet')
+ let a = readfile('Xfile_Test_normal22_zet')
+ call assert_equal([], a)
+ " Test for ZQ
+ call writefile(['1', '2'], 'Xfile_Test_normal22_zet')
+ call system(v:progpath . args . ' -c "%d" -c ":norm! ZQ" Xfile_Test_normal22_zet')
+ let a = readfile('Xfile_Test_normal22_zet')
+ call assert_equal(['1', '2'], a)
+
+ " Nvim: This sometimes hangs the TSAN build.
+ " for file in ['Xfile_Test_normal22_zet']
+ " call delete(file)
+ " endfor
+ " let &shell = shell
+endfunc
+
+func! Test_normal23_K()
+ " Test for K command
+ new
+ call append(0, ['helphelp.txt', 'man', 'aa%bb', 'cc|dd'])
+ let k = &keywordprg
+ set keywordprg=:help
+ 1
+ norm! VK
+ call assert_equal('helphelp.txt', fnamemodify(bufname('%'), ':t'))
+ call assert_equal('help', &ft)
+ call assert_match('\*helphelp.txt\*', getline('.'))
+ helpclose
+ norm! 0K
+ call assert_equal('helphelp.txt', fnamemodify(bufname('%'), ':t'))
+ call assert_equal('help', &ft)
+ call assert_match('Help on help files', getline('.'))
+ helpclose
+
+ set keywordprg=:new
+ set iskeyword+=%
+ set iskeyword+=\|
+ 2
+ norm! K
+ call assert_equal('man', fnamemodify(bufname('%'), ':t'))
+ bwipe!
+ 3
+ norm! K
+ call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t'))
+ bwipe!
+ if !has('win32')
+ 4
+ norm! K
+ call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t'))
+ bwipe!
+ endif
+ set iskeyword-=%
+ set iskeyword-=\|
+
+ " Only expect "man" to work on Unix
+ if !has("unix")
+ let &keywordprg = k
+ bw!
+ return
+ endif
+ set keywordprg=man\ --pager=cat
+ " Test for using man
+ 2
+ let a = execute('unsilent norm! K')
+ call assert_match("man --pager=cat 'man'", a)
+
+ " clean up
+ let &keywordprg = k
+ bw!
+endfunc
+
+func! Test_normal24_rot13()
+ " This test uses multi byte characters
+ if !has("multi_byte")
+ return
+ endif
+ " Testing for g?? g?g?
+ new
+ call append(0, 'abcdefghijklmnopqrstuvwxyzäüö')
+ 1
+ norm! g??
+ call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.'))
+ norm! g?g?
+ call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal25_tag()
+ " Testing for CTRL-] g CTRL-] g]
+ " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-]
+ h
+ " Test for CTRL-]
+ call search('\<x\>$')
+ exe "norm! \<c-]>"
+ call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*x*", @0)
+ exe ":norm \<c-o>"
+
+ " Test for g_CTRL-]
+ call search('\<v_u\>$')
+ exe "norm! g\<c-]>"
+ call assert_equal("change.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*v_u*", @0)
+ exe ":norm \<c-o>"
+
+ " Test for g]
+ call search('\<i_<Esc>$')
+ let a = execute(":norm! g]")
+ call assert_match('i_<Esc>.*insert.txt', a)
+
+ if !empty(exepath('cscope')) && has('cscope')
+ " setting cscopetag changes how g] works
+ set cst
+ exe "norm! g]"
+ call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*i_<Esc>*", @0)
+ exe ":norm \<c-o>"
+ " Test for CTRL-W g]
+ exe "norm! \<C-W>g]"
+ call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*i_<Esc>*", @0)
+ call assert_equal(3, winnr('$'))
+ helpclose
+ set nocst
+ endif
+
+ " Test for CTRL-W g]
+ let a = execute("norm! \<C-W>g]")
+ call assert_match('i_<Esc>.*insert.txt', a)
+
+ " Test for CTRL-W CTRL-]
+ exe "norm! \<C-W>\<C-]>"
+ call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*i_<Esc>*", @0)
+ call assert_equal(3, winnr('$'))
+ helpclose
+
+ " Test for CTRL-W g CTRL-]
+ exe "norm! \<C-W>g\<C-]>"
+ call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t'))
+ norm! yiW
+ call assert_equal("*i_<Esc>*", @0)
+ call assert_equal(3, winnr('$'))
+ helpclose
+
+ " clean up
+ helpclose
+endfunc
+
+func! Test_normal26_put()
+ " Test for ]p ]P [p and [P
+ new
+ call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done'])
+ 1
+ /Error/y a
+ 2
+ norm! "a]pj"a[p
+ call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5))
+ 1
+ /^\s\{4}/
+ exe "norm! \"a]P3Eldt'"
+ exe "norm! j\"a[P2Eldt'"
+ call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal27_bracket()
+ " Test for [' [` ]' ]`
+ call Setup_NewWindow()
+ 1,21s/.\+/ & b/
+ 1
+ norm! $ma
+ 5
+ norm! $mb
+ 10
+ norm! $mc
+ 15
+ norm! $md
+ 20
+ norm! $me
+
+ " Test for ['
+ 9
+ norm! 2['
+ call assert_equal(' 1 b', getline('.'))
+ call assert_equal(1, line('.'))
+ call assert_equal(3, col('.'))
+
+ " Test for ]'
+ norm! ]'
+ call assert_equal(' 5 b', getline('.'))
+ call assert_equal(5, line('.'))
+ call assert_equal(3, col('.'))
+
+ " No mark after line 21, cursor moves to first non blank on current line
+ 21
+ norm! $]'
+ call assert_equal(' 21 b', getline('.'))
+ call assert_equal(21, line('.'))
+ call assert_equal(3, col('.'))
+
+ " Test for [`
+ norm! 2[`
+ call assert_equal(' 15 b', getline('.'))
+ call assert_equal(15, line('.'))
+ call assert_equal(8, col('.'))
+
+ " Test for ]`
+ norm! ]`
+ call assert_equal(' 20 b', getline('.'))
+ call assert_equal(20, line('.'))
+ call assert_equal(8, col('.'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal28_parenthesis()
+ " basic testing for ( and )
+ new
+ call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
+
+ $
+ norm! d(
+ call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$'))
+ norm! 2d(
+ call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$'))
+ 1
+ norm! 0d)
+ call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$'))
+
+ call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. '])
+ $
+ norm! $d(
+ call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$'))
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal29_brace()
+ " basic test for { and } movements
+ let text= ['A paragraph begins after each empty line, and also at each of a set of',
+ \ 'paragraph macros, specified by the pairs of characters in the ''paragraphs''',
+ \ 'option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to',
+ \ 'the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in',
+ \ 'the first column). A section boundary is also a paragraph boundary.',
+ \ 'Note that a blank line (only containing white space) is NOT a paragraph',
+ \ 'boundary.',
+ \ '',
+ \ '',
+ \ 'Also note that this does not include a ''{'' or ''}'' in the first column. When',
+ \ 'the ''{'' flag is in ''cpoptions'' then ''{'' in the first column is used as a',
+ \ 'paragraph boundary |posix|.',
+ \ '{',
+ \ 'This is no paragraph',
+ \ 'unless the ''{'' is set',
+ \ 'in ''cpoptions''',
+ \ '}',
+ \ '.IP',
+ \ 'The nroff macros IP separates a paragraph',
+ \ 'That means, it must be a ''.''',
+ \ 'followed by IP',
+ \ '.LPIt does not matter, if afterwards some',
+ \ 'more characters follow.',
+ \ '.SHAlso section boundaries from the nroff',
+ \ 'macros terminate a paragraph. That means',
+ \ 'a character like this:',
+ \ '.NH',
+ \ 'End of text here']
+ new
+ call append(0, text)
+ 1
+ norm! 0d2}
+ call assert_equal(['.IP',
+ \ 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', 'followed by IP',
+ \ '.LPIt does not matter, if afterwards some', 'more characters follow.', '.SHAlso section boundaries from the nroff',
+ \ 'macros terminate a paragraph. That means', 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
+ norm! 0d}
+ call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.',
+ \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
+ \ 'a character like this:', '.NH', 'End of text here', ''], getline(1, '$'))
+ $
+ norm! d{
+ call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.',
+ \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', 'a character like this:', ''], getline(1, '$'))
+ norm! d{
+ call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.', ''], getline(1,'$'))
+ " Test with { in cpooptions
+ %d
+ call append(0, text)
+ " Nvim: no "{" flag in 'cpoptions'.
+ " set cpo+={
+ " 1
+ " norm! 0d2}
+ " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
+ " \ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''',
+ " \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
+ " \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
+ " \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
+ " $
+ " norm! d}
+ " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
+ " \ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''',
+ " \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
+ " \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
+ " \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
+ " norm! gg}
+ " norm! d5}
+ " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$'))
+
+ " clean up
+ set cpo-={
+ bw!
+endfunc
+
+fun! Test_normal30_changecase()
+ " This test uses multi byte characters
+ if !has("multi_byte")
+ return
+ endif
+ new
+ call append(0, 'This is a simple test: äüöß')
+ norm! 1ggVu
+ call assert_equal('this is a simple test: äüöß', getline('.'))
+ norm! VU
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ norm! guu
+ call assert_equal('this is a simple test: äüöss', getline('.'))
+ norm! gUgU
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ norm! gugu
+ call assert_equal('this is a simple test: äüöss', getline('.'))
+ norm! gUU
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ norm! 010~
+ call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
+ norm! V~
+ call assert_equal('THIS IS A simple test: äüöss', getline('.'))
+
+ " Turkish ASCII turns to multi-byte. On some systems Turkish locale
+ " is available but toupper()/tolower() don't do the right thing.
+ try
+ lang tr_TR.UTF-8
+ set casemap=
+ let iupper = toupper('i')
+ if iupper == "\u0130"
+ call setline(1, 'iI')
+ 1normal gUU
+ call assert_equal("\u0130I", getline(1))
+ call assert_equal("\u0130I", toupper("iI"))
+
+ call setline(1, 'iI')
+ 1normal guu
+ call assert_equal("i\u0131", getline(1))
+ call assert_equal("i\u0131", tolower("iI"))
+ elseif iupper == "I"
+ call setline(1, 'iI')
+ 1normal gUU
+ call assert_equal("II", getline(1))
+ call assert_equal("II", toupper("iI"))
+
+ call setline(1, 'iI')
+ 1normal guu
+ call assert_equal("ii", getline(1))
+ call assert_equal("ii", tolower("iI"))
+ else
+ call assert_true(false, "expected toupper('i') to be either 'I' or '\u0131'")
+ endif
+ set casemap&
+ call setline(1, 'iI')
+ 1normal gUU
+ call assert_equal("II", getline(1))
+ call assert_equal("II", toupper("iI"))
+
+ call setline(1, 'iI')
+ 1normal guu
+ call assert_equal("ii", getline(1))
+ call assert_equal("ii", tolower("iI"))
+
+ lang en_US.UTF-8
+ catch /E197:/
+ " can't use Turkish locale
+ throw 'Skipped: Turkish locale not available'
+ endtry
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal31_r_cmd()
+ " Test for r command
+ new
+ call append(0, 'This is a simple test: abcd')
+ exe "norm! 1gg$r\<cr>"
+ call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$'))
+ exe "norm! 1gg2wlr\<cr>"
+ call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$'))
+ exe "norm! 2gg0W5r\<cr>"
+ call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$'))
+ set autoindent
+ call setline(2, ['simple test: abc', ''])
+ exe "norm! 2gg0W5r\<cr>"
+ call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$'))
+ exe "norm! 1ggVr\<cr>"
+ call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1)))
+ call setline(1, 'This is a')
+ exe "norm! 1gg05rf"
+ call assert_equal('fffffis a', getline(1))
+
+ " clean up
+ set noautoindent
+ bw!
+endfunc
+
+func! Test_normal32_g_cmd1()
+ " Test for g*, g#
+ new
+ call append(0, ['abc.x_foo', 'x_foobar.abc'])
+ 1
+ norm! $g*
+ call assert_equal('x_foo', @/)
+ call assert_equal('x_foobar.abc', getline('.'))
+ norm! $g#
+ call assert_equal('abc', @/)
+ call assert_equal('abc.x_foo', getline('.'))
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal33_g_cmd2()
+ if !has("jumplist")
+ return
+ endif
+ " Tests for g cmds
+ call Setup_NewWindow()
+ " Test for g`
+ clearjumps
+ norm! ma10j
+ let a=execute(':jumps')
+ " empty jumplist
+ call assert_equal('>', a[-1:])
+ norm! g`a
+ call assert_equal('>', a[-1:])
+ call assert_equal(1, line('.'))
+ call assert_equal('1', getline('.'))
+
+ " Test for g; and g,
+ norm! g;
+ " there is only one change in the changelist
+ " currently, when we setup the window
+ call assert_equal(2, line('.'))
+ call assert_fails(':norm! g;', 'E662')
+ call assert_fails(':norm! g,', 'E663')
+ let &ul=&ul
+ call append('$', ['a', 'b', 'c', 'd'])
+ let &ul=&ul
+ call append('$', ['Z', 'Y', 'X', 'W'])
+ let a = execute(':changes')
+ call assert_match('2\s\+0\s\+2', a)
+ call assert_match('101\s\+0\s\+a', a)
+ call assert_match('105\s\+0\s\+Z', a)
+ norm! 3g;
+ call assert_equal(2, line('.'))
+ norm! 2g,
+ call assert_equal(105, line('.'))
+
+ " Test for g& - global substitute
+ %d
+ call setline(1, range(1,10))
+ call append('$', ['a', 'b', 'c', 'd'])
+ $s/\w/&&/g
+ exe "norm! /[1-8]\<cr>"
+ norm! g&
+ call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$'))
+
+ " Test for gv
+ %d
+ call append('$', repeat(['abcdefgh'], 8))
+ exe "norm! 2gg02l\<c-v>2j2ly"
+ call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1))
+ " in visual mode, gv swaps current and last selected region
+ exe "norm! G0\<c-v>4k4lgvd"
+ call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$'))
+ exe "norm! G0\<c-v>4k4ly"
+ exe "norm! gvood"
+ call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$'))
+
+ " Test for gk/gj
+ %d
+ 15vsp
+ set wrap listchars= sbr=
+ let lineA='abcdefghijklmnopqrstuvwxyz'
+ let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ $put =lineA
+ $put =lineB
+
+ norm! 3gg0dgk
+ call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$'))
+ set nu
+ norm! 3gg0gjdgj
+ call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+
+ " Test for gJ
+ norm! 2gggJ
+ call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+ call assert_equal(16, col('.'))
+ " shouldn't do anything
+ norm! 10gJ
+ call assert_equal(1, col('.'))
+
+ " Test for g0 g^ gm g$
+ exe "norm! 2gg0gji "
+ call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+ norm! g0yl
+ call assert_equal(12, col('.'))
+ call assert_equal(' ', getreg(0))
+ norm! g$yl
+ call assert_equal(22, col('.'))
+ call assert_equal('3', getreg(0))
+ norm! gmyl
+ call assert_equal(17, col('.'))
+ call assert_equal('n', getreg(0))
+ norm! g^yl
+ call assert_equal(15, col('.'))
+ call assert_equal('l', getreg(0))
+
+ " Test for gI
+ norm! gIfoo
+ call assert_equal(['', 'fooabcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$'))
+
+ " Test for gi
+ wincmd c
+ %d
+ set tw=0
+ call setline(1, ['foobar', 'new line'])
+ norm! A next word
+ $put ='third line'
+ norm! gi another word
+ call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_g_ctrl_g()
+ new
+
+ let a = execute(":norm! g\<c-g>")
+ call assert_equal("\n--No lines in buffer--", a)
+
+ call setline(1, ['first line', 'second line'])
+
+ " Test g CTRL-g with dos, mac and unix file type.
+ norm! gojll
+ set ff=dos
+ let a = execute(":norm! g\<c-g>")
+ call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 15 of 25", a)
+
+ set ff=mac
+ let a = execute(":norm! g\<c-g>")
+ call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
+
+ set ff=unix
+ let a = execute(":norm! g\<c-g>")
+ call assert_equal("\nCol 3 of 11; Line 2 of 2; Word 3 of 4; Byte 14 of 23", a)
+
+ " Test g CTRL-g in visual mode (v)
+ let a = execute(":norm! gojllvlg\<c-g>")
+ call assert_equal("\nSelected 1 of 2 Lines; 1 of 4 Words; 2 of 23 Bytes", a)
+
+ " Test g CTRL-g in visual mode (CTRL-V) with end col > start col
+ let a = execute(":norm! \<Esc>gojll\<C-V>kllg\<c-g>")
+ call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
+
+ " Test g_CTRL-g in visual mode (CTRL-V) with end col < start col
+ let a = execute(":norm! \<Esc>goll\<C-V>jhhg\<c-g>")
+ call assert_equal("\nSelected 3 Cols; 2 of 2 Lines; 2 of 4 Words; 6 of 23 Bytes", a)
+
+ " Test g CTRL-g in visual mode (CTRL-V) with end_vcol being MAXCOL
+ let a = execute(":norm! \<Esc>gojll\<C-V>k$g\<c-g>")
+ call assert_equal("\nSelected 2 of 2 Lines; 4 of 4 Words; 17 of 23 Bytes", a)
+
+ " There should be one byte less with noeol
+ set bin noeol
+ let a = execute(":norm! \<Esc>gog\<c-g>")
+ call assert_equal("\nCol 1 of 10; Line 1 of 2; Word 1 of 4; Char 1 of 23; Byte 1 of 22", a)
+ set bin & eol&
+
+ if has('multi_byte')
+ call setline(1, ['Français', '日本語'])
+
+ let a = execute(":norm! \<Esc>gojlg\<c-g>")
+ call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20", a)
+
+ let a = execute(":norm! \<Esc>gojvlg\<c-g>")
+ call assert_equal("\nSelected 1 of 2 Lines; 1 of 2 Words; 2 of 13 Chars; 6 of 20 Bytes", a)
+
+ let a = execute(":norm! \<Esc>goll\<c-v>jlg\<c-g>")
+ call assert_equal("\nSelected 4 Cols; 2 of 2 Lines; 2 of 2 Words; 6 of 13 Chars; 11 of 20 Bytes", a)
+
+ set fenc=utf8 bomb
+ let a = execute(":norm! \<Esc>gojlg\<c-g>")
+ call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+3 for BOM)", a)
+
+ set fenc=utf16 bomb
+ let a = execute(":norm! g\<c-g>")
+ call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+2 for BOM)", a)
+
+ set fenc=utf32 bomb
+ let a = execute(":norm! g\<c-g>")
+ call assert_equal("\nCol 4-3 of 9-6; Line 2 of 2; Word 2 of 2; Char 11 of 13; Byte 16 of 20(+4 for BOM)", a)
+
+ set fenc& bomb&
+ endif
+
+ set ff&
+ bwipe!
+endfunc
+
+fun! Test_normal34_g_cmd3()
+ if !has("multi_byte")
+ return
+ endif
+
+ " Test for g8
+ new
+ let a=execute(':norm! 1G0g8')
+ call assert_equal("\nNUL", a)
+
+ call setline(1, 'abcdefghijklmnopqrstuvwxyzäüö')
+ let a=execute(':norm! 1G$g8')
+ call assert_equal("\nc3 b6 ", a)
+
+ call setline(1, "a\u0302")
+ let a=execute(':norm! 1G0g8')
+ call assert_equal("\n61 + cc 82 ", a)
+
+ " clean up
+ bw!
+endfunc
+
+func Test_normal_8g8()
+ if !has("multi_byte")
+ return
+ endif
+ new
+
+ " Test 8g8 which finds invalid utf8 at or after the cursor.
+
+ " With invalid byte.
+ call setline(1, "___\xff___")
+ norm! 1G08g8g
+ call assert_equal([0, 1, 4, 0, 1], getcurpos())
+
+ " With invalid byte before the cursor.
+ call setline(1, "___\xff___")
+ norm! 1G$h8g8g
+ call assert_equal([0, 1, 6, 0, 9], getcurpos())
+
+ " With truncated sequence.
+ call setline(1, "___\xE2\x82___")
+ norm! 1G08g8g
+ call assert_equal([0, 1, 4, 0, 1], getcurpos())
+
+ " With overlong sequence.
+ call setline(1, "___\xF0\x82\x82\xAC___")
+ norm! 1G08g8g
+ call assert_equal([0, 1, 4, 0, 1], getcurpos())
+
+ " With valid utf8.
+ call setline(1, "café")
+ norm! 1G08g8
+ call assert_equal([0, 1, 1, 0, 1], getcurpos())
+
+ bw!
+endfunc
+
+fun! Test_normal35_g_cmd4()
+ " Test for g<
+ " Cannot capture its output,
+ " probably a bug, therefore, test disabled:
+ throw "Skipped: output of g< can't be tested currently"
+ echo "a\nb\nc\nd"
+ let b=execute(':norm! g<')
+ call assert_true(!empty(b), 'failed `execute(g<)`')
+endfunc
+
+fun! Test_normal36_g_cmd5()
+ new
+ call append(0, 'abcdefghijklmnopqrstuvwxyz')
+ set ff=unix
+ " Test for gp gP
+ call append(1, range(1,10))
+ 1
+ norm! 1yy
+ 3
+ norm! gp
+ call assert_equal([0, 5, 1, 0, 1], getcurpos())
+ $
+ norm! gP
+ call assert_equal([0, 14, 1, 0, 1], getcurpos())
+
+ " Test for go
+ norm! 26go
+ call assert_equal([0, 1, 26, 0, 26], getcurpos())
+ norm! 27go
+ call assert_equal([0, 1, 26, 0, 26], getcurpos())
+ norm! 28go
+ call assert_equal([0, 2, 1, 0, 1], getcurpos())
+ set ff=dos
+ norm! 29go
+ call assert_equal([0, 2, 1, 0, 1], getcurpos())
+ set ff=unix
+ norm! gg0
+ norm! 101go
+ call assert_equal([0, 13, 26, 0, 26], getcurpos())
+ norm! 103go
+ call assert_equal([0, 14, 1, 0, 1], getcurpos())
+ " count > buffer content
+ norm! 120go
+ call assert_equal([0, 14, 1, 0, 2147483647], getcurpos())
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal37_g_cmd6()
+ " basic test for gt and gT
+ tabnew 1.txt
+ tabnew 2.txt
+ tabnew 3.txt
+ norm! 1gt
+ call assert_equal(1, tabpagenr())
+ norm! 3gt
+ call assert_equal(3, tabpagenr())
+ norm! 1gT
+ " count gT goes not to the absolute tabpagenumber
+ " but, but goes to the count previous tabpagenumber
+ call assert_equal(2, tabpagenr())
+ " wrap around
+ norm! 3gT
+ call assert_equal(3, tabpagenr())
+ " gt does not wrap around
+ norm! 5gt
+ call assert_equal(3, tabpagenr())
+
+ for i in range(3)
+ tabclose
+ endfor
+ " clean up
+ call assert_fails(':tabclose', 'E784')
+endfunc
+
+fun! Test_normal38_nvhome()
+ " Test for <Home> and <C-Home> key
+ new
+ call setline(1, range(10))
+ $
+ setl et sw=2
+ norm! V10>$
+ " count is ignored
+ exe "norm! 10\<home>"
+ call assert_equal(1, col('.'))
+ exe "norm! \<home>"
+ call assert_equal([0, 10, 1, 0, 1], getcurpos())
+ exe "norm! 5\<c-home>"
+ call assert_equal([0, 5, 1, 0, 1], getcurpos())
+ exe "norm! \<c-home>"
+ call assert_equal([0, 1, 1, 0, 1], getcurpos())
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal39_cw()
+ " Test for cw and cW on whitespace
+ " and cpo+=w setting
+ new
+ set tw=0
+ call append(0, 'here are some words')
+ norm! 1gg0elcwZZZ
+ call assert_equal('hereZZZare some words', getline('.'))
+ norm! 1gg0elcWYYY
+ call assert_equal('hereZZZareYYYsome words', getline('.'))
+ " Nvim: no "w" flag in 'cpoptions'.
+ " set cpo+=w
+ " call setline(1, 'here are some words')
+ " norm! 1gg0elcwZZZ
+ " call assert_equal('hereZZZ are some words', getline('.'))
+ " norm! 1gg2elcWYYY
+ " call assert_equal('hereZZZ areYYY some words', getline('.'))
+ set cpo-=w
+ norm! 2gg0cwfoo
+ call assert_equal('foo', getline('.'))
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal40_ctrl_bsl()
+ " Basic test for CTRL-\ commands
+ new
+ call append(0, 'here are some words')
+ exe "norm! 1gg0a\<C-\>\<C-N>"
+ call assert_equal('n', mode())
+ call assert_equal(1, col('.'))
+ call assert_equal('', visualmode())
+ exe "norm! 1gg0viw\<C-\>\<C-N>"
+ call assert_equal('n', mode())
+ call assert_equal(4, col('.'))
+ exe "norm! 1gg0a\<C-\>\<C-G>"
+ call assert_equal('n', mode())
+ call assert_equal(1, col('.'))
+ "imap <buffer> , <c-\><c-n>
+ set im
+ exe ":norm! \<c-\>\<c-n>dw"
+ set noim
+ call assert_equal('are some words', getline(1))
+ call assert_false(&insertmode)
+
+ " clean up
+ bw!
+endfunc
+
+fun! Test_normal41_insert_reg()
+ " Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>=
+ " in insert mode
+ new
+ set sts=2 sw=2 ts=8 tw=0
+ call append(0, ["aaa\tbbb\tccc", '', '', ''])
+ let a=getline(1)
+ norm! 2gg0
+ exe "norm! a\<c-r>=a\<cr>"
+ norm! 3gg0
+ exe "norm! a\<c-r>\<c-r>=a\<cr>"
+ norm! 4gg0
+ exe "norm! a\<c-r>\<c-o>=a\<cr>"
+ call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$'))
+
+ " clean up
+ set sts=0 sw=8 ts=8
+ bw!
+endfunc
+
+func! Test_normal42_halfpage()
+ " basic test for Ctrl-D and Ctrl-U
+ call Setup_NewWindow()
+ call assert_equal(5, &scroll)
+ exe "norm! \<c-d>"
+ call assert_equal('6', getline('.'))
+ exe "norm! 2\<c-d>"
+ call assert_equal('8', getline('.'))
+ call assert_equal(2, &scroll)
+ set scroll=5
+ exe "norm! \<c-u>"
+ call assert_equal('3', getline('.'))
+ 1
+ set scrolloff=5
+ exe "norm! \<c-d>"
+ call assert_equal('10', getline('.'))
+ exe "norm! \<c-u>"
+ call assert_equal('5', getline('.'))
+ 1
+ set scrolloff=99
+ exe "norm! \<c-d>"
+ call assert_equal('10', getline('.'))
+ set scrolloff=0
+ 100
+ exe "norm! $\<c-u>"
+ call assert_equal('95', getline('.'))
+ call assert_equal([0, 95, 1, 0, 1], getcurpos())
+ 100
+ set nostartofline
+ exe "norm! $\<c-u>"
+ call assert_equal('95', getline('.'))
+ call assert_equal([0, 95, 2, 0, 2147483647], getcurpos())
+ " cleanup
+ set startofline
+ bw!
+endfunc
+
+fun! Test_normal43_textobject1()
+ " basic tests for text object aw
+ new
+ call append(0, ['foobar,eins,foobar', 'foo,zwei,foo '])
+ " diw
+ norm! 1gg0diw
+ call assert_equal([',eins,foobar', 'foo,zwei,foo ', ''], getline(1,'$'))
+ " daw
+ norm! 2ggEdaw
+ call assert_equal([',eins,foobar', 'foo,zwei,', ''], getline(1, '$'))
+ %d
+ call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "])
+ " diW
+ norm! 2ggwd2iW
+ call assert_equal(['foo eins foobar', 'foo foo ', ''], getline(1,'$'))
+ " daW
+ norm! 1ggd2aW
+ call assert_equal(['foobar', 'foo foo ', ''], getline(1,'$'))
+
+ %d
+ call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "])
+ " aw in visual line mode switches to characterwise mode
+ norm! 2gg$Vawd
+ call assert_equal(['foo eins foobar', 'foo zwei foo'], getline(1,'$'))
+ norm! 1gg$Viwd
+ call assert_equal(['foo eins ', 'foo zwei foo'], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal44_textobjects2()
+ " basic testing for is and as text objects
+ new
+ call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here'])
+ " Test for dis - does not remove trailing whitespace
+ norm! 1gg0dis
+ call assert_equal([' With some sentences!', '', 'Even with a question? And one more. And no sentence here', ''], getline(1,'$'))
+ " Test for das - removes leading whitespace
+ norm! 3ggf?ldas
+ call assert_equal([' With some sentences!', '', 'Even with a question? And no sentence here', ''], getline(1,'$'))
+ " when used in visual mode, is made characterwise
+ norm! 3gg$Visy
+ call assert_equal('v', visualmode())
+ " reset visualmode()
+ norm! 3ggVy
+ norm! 3gg$Vasy
+ call assert_equal('v', visualmode())
+ " basic testing for textobjects a< and at
+ %d
+ call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' '])
+ " a<
+ norm! 1gg0da<
+ call assert_equal([' ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
+ norm! 1pj
+ call assert_equal([' <div>', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
+ " at
+ norm! d2at
+ call assert_equal([' '], getline(1,'$'))
+ %d
+ call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' '])
+ " i<
+ norm! 1gg0di<
+ call assert_equal(['<> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
+ norm! 1Pj
+ call assert_equal(['<div> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$'))
+ norm! d2it
+ call assert_equal(['<div></div>',' '], getline(1,'$'))
+ " basic testing for a[ and i[ text object
+ %d
+ call setline(1, [' ', '[', 'one [two]', 'thre', ']'])
+ norm! 3gg0di[
+ call assert_equal([' ', '[', ']'], getline(1,'$'))
+ call setline(1, [' ', '[', 'one [two]', 'thre', ']'])
+ norm! 3gg0ftd2a[
+ call assert_equal([' '], getline(1,'$'))
+ %d
+ " Test for i" when cursor is in front of a quoted object
+ call append(0, 'foo "bar"')
+ norm! 1gg0di"
+ call assert_equal(['foo ""', ''], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal45_drop()
+ if !has('dnd')
+ return
+ endif
+
+ " basic test for drag-n-drop
+ " unfortunately, without a gui, we can't really test much here,
+ " so simply test that ~p fails (which uses the drop register)
+ new
+ call assert_fails(':norm! "~p', 'E353')
+ call assert_equal([], getreg('~', 1, 1))
+ " the ~ register is read only
+ call assert_fails(':let @~="1"', 'E354')
+ bw!
+endfunc
+
+func! Test_normal46_ignore()
+ " This test uses multi byte characters
+ if !has("multi_byte")
+ return
+ endif
+
+ new
+ " How to test this?
+ " let's just for now test, that the buffer
+ " does not change
+ call feedkeys("\<c-s>", 't')
+ call assert_equal([''], getline(1,'$'))
+
+ " no valid commands
+ exe "norm! \<char-0x100>"
+ call assert_equal([''], getline(1,'$'))
+
+ exe "norm! ä"
+ call assert_equal([''], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+func! Test_normal47_visual_buf_wipe()
+ " This was causing a crash or ml_get error.
+ enew!
+ call setline(1,'xxx')
+ normal $
+ new
+ call setline(1, range(1,2))
+ 2
+ exe "norm \<C-V>$"
+ bw!
+ norm yp
+ 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"
+ call assert_equal(1, winnr('$'))
+ call assert_fails(":norm! \<c-w>c", "E444")
+endfunc
+
+func! Test_normal49_counts()
+ new
+ call setline(1, 'one two three four five six seven eight nine ten')
+ 1
+ norm! 3d2w
+ call assert_equal('seven eight nine ten', getline(1))
+ bw!
+endfunc
+
+func! Test_normal50_commandline()
+ if !has("timers") || !has("cmdline_hist") || !has("vertsplit")
+ return
+ endif
+ func! DoTimerWork(id)
+ call assert_equal('[Command Line]', bufname(''))
+ " should fail, with E11, but does fail with E23?
+ "call feedkeys("\<c-^>", 'tm')
+
+ " should also fail with E11
+ call assert_fails(":wincmd p", 'E11')
+ " return from commandline window
+ call feedkeys("\<cr>")
+ endfunc
+
+ let oldlang=v:lang
+ lang C
+ set updatetime=20
+ call timer_start(100, 'DoTimerWork')
+ try
+ " throws E23, for whatever reason...
+ call feedkeys('q:', 'x!')
+ catch /E23/
+ " no-op
+ endtry
+ " clean up
+ set updatetime=4000
+ exe "lang" oldlang
+ bw!
+endfunc
+
+func! Test_normal51_FileChangedRO()
+ if !has("autocmd")
+ return
+ endif
+ call writefile(['foo'], 'Xreadonly.log')
+ new Xreadonly.log
+ setl ro
+ au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix')
+ call assert_fails(":norm! Af", 'E788')
+ call assert_equal(['foo'], getline(1,'$'))
+ call assert_equal('Xreadonly.log', bufname(''))
+
+ " cleanup
+ bw!
+ call delete("Xreadonly.log")
+endfunc
+
+func! Test_normal52_rl()
+ if !has("rightleft")
+ return
+ endif
+ new
+ call setline(1, 'abcde fghij klmnopq')
+ norm! 1gg$
+ set rl
+ call assert_equal(19, col('.'))
+ call feedkeys('l', 'tx')
+ call assert_equal(18, col('.'))
+ call feedkeys('h', 'tx')
+ call assert_equal(19, col('.'))
+ call feedkeys("\<right>", 'tx')
+ call assert_equal(18, col('.'))
+ call feedkeys("\<s-right>", 'tx')
+ call assert_equal(13, col('.'))
+ call feedkeys("\<c-right>", 'tx')
+ call assert_equal(7, col('.'))
+ call feedkeys("\<c-left>", 'tx')
+ call assert_equal(13, col('.'))
+ call feedkeys("\<s-left>", 'tx')
+ call assert_equal(19, col('.'))
+ call feedkeys("<<", 'tx')
+ call assert_equal(' abcde fghij klmnopq',getline(1))
+ call feedkeys(">>", 'tx')
+ call assert_equal('abcde fghij klmnopq',getline(1))
+
+ " cleanup
+ set norl
+ bw!
+endfunc
+
+func! Test_normal53_digraph()
+ if !has('digraphs')
+ return
+ endif
+ new
+ call setline(1, 'abcdefgh|')
+ exe "norm! 1gg0f\<c-k>!!"
+ call assert_equal(9, col('.'))
+ set cpo+=D
+ exe "norm! 1gg0f\<c-k>!!"
+ call assert_equal(1, col('.'))
+
+ set cpo-=D
+ bw!
+endfunc
+
+func Test_normal54_Ctrl_bsl()
+ new
+ call setline(1, 'abcdefghijklmn')
+ exe "norm! df\<c-\>\<c-n>"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+ exe "norm! df\<c-\>\<c-g>"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+ exe "norm! df\<c-\>m"
+ call assert_equal(['abcdefghijklmn'], getline(1,'$'))
+ if !has("multi_byte")
+ return
+ endif
+ call setline(2, 'abcdefghijklmnÄf')
+ norm! 2gg0
+ exe "norm! df\<Char-0x101>"
+ call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
+ norm! 1gg0
+ exe "norm! df\<esc>"
+ call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$'))
+
+ " clean up
+ bw!
+endfunc
+
+func Test_normal_large_count()
+ " This may fail with 32bit long, how do we detect that?
+ new
+ normal o
+ normal 6666666666dL
+ bwipe!
+endfunc
+
+" Test for the gr (virtual replace) command
+" Test for the bug fixed by 7.4.387
+func Test_gr_command()
+ enew!
+ let save_cpo = &cpo
+ call append(0, ['First line', 'Second line', 'Third line'])
+ exe "normal i\<C-G>u"
+ call cursor(2, 1)
+ set cpo-=X
+ normal 4gro
+ call assert_equal('oooond line', getline(2))
+ undo
+ set cpo+=X
+ normal 4gro
+ call assert_equal('ooooecond line', getline(2))
+ let &cpo = save_cpo
+ enew!
+endfunc
+
+" When splitting a window the changelist position is wrong.
+" Test the changelist position after splitting a window.
+" Test for the bug fixed by 7.4.386
+func Test_changelist()
+ let save_ul = &ul
+ enew!
+ call append('$', ['1', '2'])
+ exe "normal i\<C-G>u"
+ exe "normal Gkylpa\<C-G>u"
+ set ul=100
+ exe "normal Gylpa\<C-G>u"
+ set ul=100
+ normal gg
+ vsplit
+ normal g;
+ call assert_equal([3, 2], [line('.'), col('.')])
+ normal g;
+ call assert_equal([2, 2], [line('.'), col('.')])
+ call assert_fails('normal g;', 'E662:')
+ %bwipe!
+ let &ul = save_ul
+endfunc
+
+func Test_delete_until_paragraph()
+ if !has('multi_byte')
+ return
+ endif
+ new
+ normal grádv}
+ call assert_equal('á', getline(1))
+ normal grád}
+ call assert_equal('', getline(1))
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_number.vim b/src/nvim/testdir/test_number.vim
new file mode 100644
index 0000000000..59debcea0d
--- /dev/null
+++ b/src/nvim/testdir/test_number.vim
@@ -0,0 +1,254 @@
+" Test for 'number' and 'relativenumber'
+
+source view_util.vim
+
+func! s:screen_lines(start, end) abort
+ return ScreenLines([a:start, a:end], 8)
+endfunc
+
+func! s:compare_lines(expect, actual)
+ call assert_equal(a:expect, a:actual)
+endfunc
+
+func! s:test_windows(h, w) abort
+ call NewWindow(a:h, a:w)
+endfunc
+
+func! s:close_windows() abort
+ call CloseWindow()
+endfunc
+
+func! s:validate_cursor() abort
+ " update skipcol.
+ " wincol():
+ " f_wincol
+ " -> validate_cursor
+ " -> curs_columns
+ call wincol()
+endfunc
+
+func Test_set_options()
+ set nu rnu
+ call assert_equal(1, &nu)
+ call assert_equal(1, &rnu)
+
+ call s:test_windows(10, 20)
+ call assert_equal(1, &nu)
+ call assert_equal(1, &rnu)
+ call s:close_windows()
+
+ set nu& rnu&
+endfunc
+
+func Test_set_global_and_local()
+ " setlocal must NOT reset the other global value
+ set nonu nornu
+ setglobal nu
+ setlocal rnu
+ call assert_equal(1, &g:nu)
+
+ set nonu nornu
+ setglobal rnu
+ setlocal nu
+ call assert_equal(1, &g:rnu)
+
+ " setglobal MUST reset the other global value
+ set nonu nornu
+ setglobal nu
+ setglobal rnu
+ call assert_equal(1, &g:nu)
+
+ set nonu nornu
+ setglobal rnu
+ setglobal nu
+ call assert_equal(1, &g:rnu)
+
+ " set MUST reset the other global value
+ set nonu nornu
+ set nu
+ set rnu
+ call assert_equal(1, &g:nu)
+
+ set nonu nornu
+ set rnu
+ set nu
+ call assert_equal(1, &g:rnu)
+
+ set nu& rnu&
+endfunc
+
+func Test_number()
+ call s:test_windows(10, 20)
+ call setline(1, ["abcdefghij", "klmnopqrst", "uvwxyzABCD", "EFGHIJKLMN", "OPQRSTUVWX", "YZ"])
+ setl number
+ let lines = s:screen_lines(1, 4)
+ let expect = [
+\ " 1 abcd",
+\ " 2 klmn",
+\ " 3 uvwx",
+\ " 4 EFGH",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_relativenumber()
+ call s:test_windows(10, 20)
+ call setline(1, ["abcdefghij", "klmnopqrst", "uvwxyzABCD", "EFGHIJKLMN", "OPQRSTUVWX", "YZ"])
+ 3
+ setl relativenumber
+ let lines = s:screen_lines(1, 6)
+ let expect = [
+\ " 2 abcd",
+\ " 1 klmn",
+\ " 0 uvwx",
+\ " 1 EFGH",
+\ " 2 OPQR",
+\ " 3 YZ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_number_with_relativenumber()
+ call s:test_windows(10, 20)
+ call setline(1, ["abcdefghij", "klmnopqrst", "uvwxyzABCD", "EFGHIJKLMN", "OPQRSTUVWX", "YZ"])
+ 4
+ setl number relativenumber
+ let lines = s:screen_lines(1, 6)
+ let expect = [
+\ " 3 abcd",
+\ " 2 klmn",
+\ " 1 uvwx",
+\ "4 EFGH",
+\ " 1 OPQR",
+\ " 2 YZ ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_number_with_linewrap1()
+ call s:test_windows(3, 20)
+ normal! 61ia
+ setl number wrap
+ call s:validate_cursor()
+ let lines = s:screen_lines(1, 3)
+ let expect = [
+\ "--1 aaaa",
+\ " aaaa",
+\ " aaaa",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+" Pending: https://groups.google.com/forum/#!topic/vim_dev/tzNKP7EDWYI
+func XTest_number_with_linewrap2()
+ call s:test_windows(3, 20)
+ normal! 61ia
+ setl number wrap
+ call s:validate_cursor()
+ 0
+ call s:validate_cursor()
+ let lines = s:screen_lines(1, 3)
+ let expect = [
+\ " 1 aaaa",
+\ " aaaa",
+\ " aaaa",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+" Pending: https://groups.google.com/forum/#!topic/vim_dev/tzNKP7EDWYI
+func XTest_number_with_linewrap3()
+ call s:test_windows(4, 20)
+ normal! 81ia
+ setl number wrap
+ call s:validate_cursor()
+ setl nonumber
+ call s:validate_cursor()
+ let lines = s:screen_lines(1, 4)
+ let expect = [
+\ "aaaaaaaa",
+\ "aaaaaaaa",
+\ "aaaaaaaa",
+\ "a ",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_numberwidth()
+ call s:test_windows(10, 20)
+ call setline(1, repeat(['aaaa'], 10))
+ setl number numberwidth=6
+ let lines = s:screen_lines(1, 3)
+ let expect = [
+\ " 1 aa",
+\ " 2 aa",
+\ " 3 aa",
+\ ]
+ call s:compare_lines(expect, lines)
+
+ set relativenumber
+ let lines = s:screen_lines(1, 3)
+ let expect = [
+\ "1 aa",
+\ " 1 aa",
+\ " 2 aa",
+\ ]
+ call s:compare_lines(expect, lines)
+
+ set nonumber
+ let lines = s:screen_lines(1, 3)
+ let expect = [
+\ " 0 aa",
+\ " 1 aa",
+\ " 2 aa",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
+
+func Test_numberwidth_adjusted()
+ call s:test_windows(10, 20)
+ call setline(1, repeat(['aaaa'], 10000))
+ setl number numberwidth=4
+ let lines = s:screen_lines(1, 3)
+ let expect = [
+\ " 1 aa",
+\ " 2 aa",
+\ " 3 aa",
+\ ]
+ call s:compare_lines(expect, lines)
+
+ $
+ let lines = s:screen_lines(8, 10)
+ let expect = [
+\ " 9998 aa",
+\ " 9999 aa",
+\ "10000 aa",
+\ ]
+ call s:compare_lines(expect, lines)
+
+ setl relativenumber
+ let lines = s:screen_lines(8, 10)
+ let expect = [
+\ " 2 aa",
+\ " 1 aa",
+\ "10000 aa",
+\ ]
+ call s:compare_lines(expect, lines)
+
+ setl nonumber
+ let lines = s:screen_lines(8, 10)
+ let expect = [
+\ " 2 aaaa",
+\ " 1 aaaa",
+\ " 0 aaaa",
+\ ]
+ call s:compare_lines(expect, lines)
+ call s:close_windows()
+endfunc
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
new file mode 100644
index 0000000000..7b640ee2ff
--- /dev/null
+++ b/src/nvim/testdir/test_options.vim
@@ -0,0 +1,412 @@
+" Test for options
+
+function! Test_whichwrap()
+ set whichwrap=b,s
+ call assert_equal('b,s', &whichwrap)
+
+ set whichwrap+=h,l
+ call assert_equal('b,s,h,l', &whichwrap)
+
+ set whichwrap+=h,l
+ call assert_equal('b,s,h,l', &whichwrap)
+
+ set whichwrap+=h,l
+ call assert_equal('b,s,h,l', &whichwrap)
+
+ set whichwrap=h,h
+ call assert_equal('h', &whichwrap)
+
+ set whichwrap=h,h,h
+ call assert_equal('h', &whichwrap)
+
+ set whichwrap&
+endfunction
+
+function! Test_isfname()
+ " This used to cause Vim to access uninitialized memory.
+ set isfname=
+ call assert_equal("~X", expand("~X"))
+ set isfname&
+endfunction
+
+function Test_wildchar()
+ " Empty 'wildchar' used to access invalid memory.
+ call assert_fails('set wildchar=', 'E521:')
+ call assert_fails('set wildchar=abc', 'E521:')
+ set wildchar=<Esc>
+ let a=execute('set wildchar?')
+ call assert_equal("\n wildchar=<Esc>", a)
+ set wildchar=27
+ let a=execute('set wildchar?')
+ call assert_equal("\n wildchar=<Esc>", a)
+ set wildchar&
+endfunction
+
+function! Test_options()
+ let caught = 'ok'
+ try
+ options
+ catch
+ let caught = v:throwpoint . "\n" . v:exception
+ endtry
+ call assert_equal('ok', caught)
+
+ " close option-window
+ close
+endfunction
+
+function! Test_path_keep_commas()
+ " Test that changing 'path' keeps two commas.
+ set path=foo,,bar
+ set path-=bar
+ set path+=bar
+ call assert_equal('foo,,bar', &path)
+
+ set path&
+endfunction
+
+func Test_filetype_valid()
+ if !has('autocmd')
+ return
+ endif
+ set ft=valid_name
+ call assert_equal("valid_name", &filetype)
+ set ft=valid-name
+ call assert_equal("valid-name", &filetype)
+
+ call assert_fails(":set ft=wrong;name", "E474:")
+ call assert_fails(":set ft=wrong\\\\name", "E474:")
+ call assert_fails(":set ft=wrong\\|name", "E474:")
+ call assert_fails(":set ft=wrong/name", "E474:")
+ call assert_fails(":set ft=wrong\\\nname", "E474:")
+ call assert_equal("valid-name", &filetype)
+
+ exe "set ft=trunc\x00name"
+ call assert_equal("trunc", &filetype)
+endfunc
+
+func Test_syntax_valid()
+ if !has('syntax')
+ return
+ endif
+ set syn=valid_name
+ call assert_equal("valid_name", &syntax)
+ set syn=valid-name
+ call assert_equal("valid-name", &syntax)
+
+ call assert_fails(":set syn=wrong;name", "E474:")
+ call assert_fails(":set syn=wrong\\\\name", "E474:")
+ call assert_fails(":set syn=wrong\\|name", "E474:")
+ call assert_fails(":set syn=wrong/name", "E474:")
+ call assert_fails(":set syn=wrong\\\nname", "E474:")
+ call assert_equal("valid-name", &syntax)
+
+ exe "set syn=trunc\x00name"
+ call assert_equal("trunc", &syntax)
+endfunc
+
+func Test_keymap_valid()
+ if !has('keymap')
+ return
+ endif
+ call assert_fails(":set kmp=valid_name", "E544:")
+ call assert_fails(":set kmp=valid_name", "valid_name")
+ call assert_fails(":set kmp=valid-name", "E544:")
+ call assert_fails(":set kmp=valid-name", "valid-name")
+
+ call assert_fails(":set kmp=wrong;name", "E474:")
+ call assert_fails(":set kmp=wrong\\\\name", "E474:")
+ call assert_fails(":set kmp=wrong\\|name", "E474:")
+ call assert_fails(":set kmp=wrong/name", "E474:")
+ call assert_fails(":set kmp=wrong\\\nname", "E474:")
+
+ call assert_fails(":set kmp=trunc\x00name", "E544:")
+ call assert_fails(":set kmp=trunc\x00name", "trunc")
+endfunc
+
+func Check_dir_option(name)
+ " Check that it's possible to set the option.
+ exe 'set ' . a:name . '=/usr/share/dict/words'
+ call assert_equal('/usr/share/dict/words', eval('&' . a:name))
+ exe 'set ' . a:name . '=/usr/share/dict/words,/and/there'
+ call assert_equal('/usr/share/dict/words,/and/there', eval('&' . a:name))
+ exe 'set ' . a:name . '=/usr/share/dict\ words'
+ call assert_equal('/usr/share/dict words', eval('&' . a:name))
+
+ " Check rejecting weird characters.
+ call assert_fails("set " . a:name . "=/not&there", "E474:")
+ call assert_fails("set " . a:name . "=/not>there", "E474:")
+ call assert_fails("set " . a:name . "=/not.*there", "E474:")
+endfunc
+
+func Test_cinkeys()
+ " This used to cause invalid memory access
+ set cindent cinkeys=0
+ norm a
+ set cindent& cinkeys&
+endfunc
+
+func Test_dictionary()
+ call Check_dir_option('dictionary')
+endfunc
+
+func Test_thesaurus()
+ call Check_dir_option('thesaurus')
+endfun
+
+func Test_set_completion()
+ call feedkeys(":set di\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"set dictionary diff diffexpr diffopt digraph directory display', @:)
+
+ " Expand boolan options. When doing :set no<Tab>
+ " vim displays the options names without "no" but completion uses "no...".
+ call feedkeys(":set nodi\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"set nodiff digraph', @:)
+
+ call feedkeys(":set invdi\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"set invdiff digraph', @:)
+
+ " Expand abbreviation of options.
+ call feedkeys(":set ts\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"set tabstop thesaurus', @:)
+
+ " Expand current value
+ call feedkeys(":set fileencodings=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"set fileencodings=ucs-bom,utf-8,default,latin1', @:)
+
+ call feedkeys(":set fileencodings:\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"set fileencodings:ucs-bom,utf-8,default,latin1', @:)
+
+ " Expand directories.
+ let shellslash = &shellslash
+ set shellslash
+ call feedkeys(":set cdpath=./\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('./samples/ ', @:)
+ call assert_notmatch('./small.vim ', @:)
+
+ " Expand files and directories.
+ call feedkeys(":set tags=./\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('./samples/ ./sautest/ ./setup.vim ./shared.vim', @:)
+
+ call feedkeys(":set tags=./\\\\ dif\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"set tags=./\\ diff diffexpr diffopt', @:)
+ let &shellslash = shellslash
+endfunc
+
+func Test_set_errors()
+ call assert_fails('set scroll=-1', 'E49:')
+ call assert_fails('set backupcopy=', 'E474:')
+ call assert_fails('set regexpengine=3', 'E474:')
+ call assert_fails('set history=10001', 'E474:')
+ call assert_fails('set numberwidth=11', 'E474:')
+ call assert_fails('set colorcolumn=-a')
+ call assert_fails('set colorcolumn=a')
+ call assert_fails('set colorcolumn=1,')
+ call assert_fails('set cmdheight=-1', 'E487:')
+ call assert_fails('set cmdwinheight=-1', 'E487:')
+ if has('conceal')
+ call assert_fails('set conceallevel=-1', 'E487:')
+ call assert_fails('set conceallevel=4', 'E474:')
+ endif
+ call assert_fails('set helpheight=-1', 'E487:')
+ call assert_fails('set history=-1', 'E487:')
+ call assert_fails('set report=-1', 'E487:')
+ call assert_fails('set shiftwidth=-1', 'E487:')
+ call assert_fails('set sidescroll=-1', 'E487:')
+ call assert_fails('set tabstop=-1', 'E487:')
+ call assert_fails('set textwidth=-1', 'E487:')
+ call assert_fails('set timeoutlen=-1', 'E487:')
+ call assert_fails('set updatecount=-1', 'E487:')
+ call assert_fails('set updatetime=-1', 'E487:')
+ call assert_fails('set winheight=-1', 'E487:')
+ call assert_fails('set tabstop!', 'E488:')
+ call assert_fails('set xxx', 'E518:')
+ call assert_fails('set beautify?', 'E518:')
+ call assert_fails('set undolevels=x', 'E521:')
+ call assert_fails('set tabstop=', 'E521:')
+ call assert_fails('set comments=-', 'E524:')
+ call assert_fails('set comments=a', 'E525:')
+ call assert_fails('set foldmarker=x', 'E536:')
+ call assert_fails('set commentstring=x', 'E537:')
+ call assert_fails('set complete=x', 'E539:')
+ call assert_fails('set statusline=%{', 'E540:')
+ call assert_fails('set statusline=' . repeat("%p", 81), 'E541:')
+ call assert_fails('set statusline=%(', 'E542:')
+ if has('cursorshape')
+ " This invalid value for 'guicursor' used to cause Vim to crash.
+ call assert_fails('set guicursor=i-ci,r-cr:h', 'E545:')
+ call assert_fails('set guicursor=i-ci', 'E545:')
+ call assert_fails('set guicursor=x', 'E545:')
+ call assert_fails('set guicursor=r-cr:horx', 'E548:')
+ call assert_fails('set guicursor=r-cr:hor0', 'E549:')
+ endif
+ call assert_fails('set backupext=~ patchmode=~', 'E589:')
+ call assert_fails('set winminheight=10 winheight=9', 'E591:')
+ call assert_fails('set winminwidth=10 winwidth=9', 'E592:')
+ call assert_fails("set showbreak=\x01", 'E595:')
+ call assert_fails('set t_foo=', 'E846:')
+endfunc
+
+func Test_set_ttytype()
+ " Nvim does not support 'ttytype'.
+ if !has('nvim') && !has('gui_running') && has('unix')
+ " Setting 'ttytype' used to cause a double-free when exiting vim and
+ " when vim is compiled with -DEXITFREE.
+ set ttytype=ansi
+ call assert_equal('ansi', &ttytype)
+ call assert_equal(&ttytype, &term)
+ set ttytype=xterm
+ call assert_equal('xterm', &ttytype)
+ call assert_equal(&ttytype, &term)
+ " "set ttytype=" gives E522 instead of E529
+ " in travis on some builds. Why? Catch both for now
+ try
+ set ttytype=
+ call assert_report('set ttytype= did not fail')
+ catch /E529\|E522/
+ endtry
+
+ " Some systems accept any terminal name and return dumb settings,
+ " check for failure of finding the entry and for missing 'cm' entry.
+ try
+ set ttytype=xxx
+ call assert_report('set ttytype=xxx did not fail')
+ catch /E522\|E437/
+ endtry
+
+ set ttytype&
+ call assert_equal(&ttytype, &term)
+ endif
+endfunc
+
+func Test_complete()
+ " Trailing single backslash used to cause invalid memory access.
+ set complete=s\
+ new
+ call feedkeys("i\<C-N>\<Esc>", 'xt')
+ bwipe!
+ set complete&
+endfun
+
+func ResetIndentexpr()
+ set indentexpr=
+endfunc
+
+func Test_set_indentexpr()
+ " this was causing usage of freed memory
+ set indentexpr=ResetIndentexpr()
+ new
+ call feedkeys("i\<c-f>", 'x')
+ call assert_equal('', &indentexpr)
+ bwipe!
+endfunc
+
+func Test_copy_winopt()
+ set hidden
+
+ " Test copy option from current buffer in window
+ split
+ enew
+ setlocal numberwidth=5
+ wincmd w
+ call assert_equal(4,&numberwidth)
+ bnext
+ call assert_equal(5,&numberwidth)
+ bw!
+ call assert_equal(4,&numberwidth)
+
+ " Test copy value from window that used to be display the buffer
+ split
+ enew
+ setlocal numberwidth=6
+ bnext
+ wincmd w
+ call assert_equal(4,&numberwidth)
+ bnext
+ call assert_equal(6,&numberwidth)
+ bw!
+
+ " Test that if buffer is current, don't use the stale cached value
+ " from the last time the buffer was displayed.
+ split
+ enew
+ setlocal numberwidth=7
+ bnext
+ bnext
+ setlocal numberwidth=8
+ wincmd w
+ call assert_equal(4,&numberwidth)
+ bnext
+ call assert_equal(8,&numberwidth)
+ bw!
+
+ " Test value is not copied if window already has seen the buffer
+ enew
+ split
+ setlocal numberwidth=9
+ bnext
+ setlocal numberwidth=10
+ wincmd w
+ call assert_equal(4,&numberwidth)
+ bnext
+ call assert_equal(4,&numberwidth)
+ bw!
+
+ set hidden&
+endfunc
+
+func Test_shortmess_F()
+ new
+ call assert_match('\[No Name\]', execute('file'))
+ set shortmess+=F
+ call assert_match('\[No Name\]', execute('file'))
+ call assert_match('^\s*$', execute('file foo'))
+ call assert_match('foo', execute('file'))
+ set shortmess-=F
+ call assert_match('bar', execute('file bar'))
+ call assert_match('bar', execute('file'))
+ set shortmess&
+ bwipe
+endfunc
+
+func Test_set_all()
+ set tw=75
+ set iskeyword=a-z,A-Z
+ set nosplitbelow
+ let out = execute('set all')
+ call assert_match('textwidth=75', out)
+ call assert_match('iskeyword=a-z,A-Z', out)
+ call assert_match('nosplitbelow', out)
+ set tw& iskeyword& splitbelow&
+endfunc
+
+func Test_set_values()
+ " The file is only generated when running "make test" in the src directory.
+ if filereadable('opt_test.vim')
+ source opt_test.vim
+ endif
+endfunc
+
+func Test_shortmess_F2()
+ e file1
+ e file2
+ " Accommodate Nvim default.
+ set shortmess-=F
+ call assert_match('file1', execute('bn', ''))
+ call assert_match('file2', execute('bn', ''))
+ set shortmess+=F
+ call assert_true(empty(execute('bn', '')))
+ call assert_true(empty(execute('bn', '')))
+ set hidden
+ call assert_true(empty(execute('bn', '')))
+ call assert_true(empty(execute('bn', '')))
+ set nohidden
+ call assert_true(empty(execute('bn', '')))
+ call assert_true(empty(execute('bn', '')))
+ " Accommodate Nvim default.
+ set shortmess-=F
+ call assert_match('file1', execute('bn', ''))
+ call assert_match('file2', execute('bn', ''))
+ bwipe
+ bwipe
+endfunc
diff --git a/src/nvim/testdir/test_partial.vim b/src/nvim/testdir/test_partial.vim
new file mode 100644
index 0000000000..de5c26c2dd
--- /dev/null
+++ b/src/nvim/testdir/test_partial.vim
@@ -0,0 +1,351 @@
+" Test binding arguments to a Funcref.
+
+func MyFunc(arg1, arg2, arg3)
+ return a:arg1 . '/' . a:arg2 . '/' . a:arg3
+endfunc
+
+func MySort(up, one, two)
+ if a:one == a:two
+ return 0
+ endif
+ if a:up
+ return a:one > a:two ? 1 : -1
+ endif
+ return a:one < a:two ? 1 : -1
+endfunc
+
+func MyMap(sub, index, val)
+ return a:val - a:sub
+endfunc
+
+func MyFilter(threshold, index, val)
+ return a:val > a:threshold
+endfunc
+
+func Test_partial_args()
+ let Cb = function('MyFunc', ["foo", "bar"])
+
+ call Cb("zzz")
+ call assert_equal("foo/bar/xxx", Cb("xxx"))
+ call assert_equal("foo/bar/yyy", call(Cb, ["yyy"]))
+ let Cb2 = function(Cb)
+ call assert_equal("foo/bar/zzz", Cb2("zzz"))
+ let Cb3 = function(Cb, ["www"])
+ call assert_equal("foo/bar/www", Cb3())
+
+ let Cb = function('MyFunc', [])
+ call assert_equal("a/b/c", Cb("a", "b", "c"))
+ let Cb2 = function(Cb, [])
+ call assert_equal("a/b/d", Cb2("a", "b", "d"))
+ let Cb3 = function(Cb, ["a", "b"])
+ call assert_equal("a/b/e", Cb3("e"))
+
+ let Sort = function('MySort', [1])
+ call assert_equal([1, 2, 3], sort([3, 1, 2], Sort))
+ let Sort = function('MySort', [0])
+ call assert_equal([3, 2, 1], sort([3, 1, 2], Sort))
+
+ let Map = function('MyMap', [2])
+ call assert_equal([-1, 0, 1], map([1, 2, 3], Map))
+ let Map = function('MyMap', [3])
+ call assert_equal([-2, -1, 0], map([1, 2, 3], Map))
+
+ let Filter = function('MyFilter', [1])
+ call assert_equal([2, 3], filter([1, 2, 3], Filter))
+ let Filter = function('MyFilter', [2])
+ call assert_equal([3], filter([1, 2, 3], Filter))
+endfunc
+
+func MyDictFunc(arg1, arg2) dict
+ return self.name . '/' . a:arg1 . '/' . a:arg2
+endfunc
+
+func Test_partial_dict()
+ let dict = {'name': 'hello'}
+ let Cb = function('MyDictFunc', ["foo", "bar"], dict)
+ call assert_equal("hello/foo/bar", Cb())
+ call assert_fails('Cb("xxx")', 'E492:')
+
+ let Cb = function('MyDictFunc', [], dict)
+ call assert_equal("hello/ttt/xxx", Cb("ttt", "xxx"))
+ call assert_fails('Cb("yyy")', 'E492:')
+
+ let Cb = function('MyDictFunc', ["foo"], dict)
+ call assert_equal("hello/foo/xxx", Cb("xxx"))
+ call assert_fails('Cb()', 'E492:')
+ let Cb = function('MyDictFunc', dict)
+ call assert_equal("hello/xxx/yyy", Cb("xxx", "yyy"))
+ call assert_fails('Cb("fff")', 'E492:')
+
+ let Cb = function('MyDictFunc', dict)
+ call assert_equal({"foo": "hello/foo/1", "bar": "hello/bar/2"}, map({"foo": 1, "bar": 2}, Cb))
+
+ let dict = {"tr": function('tr', ['hello', 'h', 'H'])}
+ call assert_equal("Hello", dict.tr())
+endfunc
+
+func Test_partial_implicit()
+ let dict = {'name': 'foo'}
+ func dict.MyFunc(arg) dict
+ return self.name . '/' . a:arg
+ endfunc
+
+ call assert_equal('foo/bar', dict.MyFunc('bar'))
+
+ call assert_fails('let func = dict.MyFunc', 'E704:')
+ let Func = dict.MyFunc
+ call assert_equal('foo/aaa', Func('aaa'))
+
+ let Func = function(dict.MyFunc, ['bbb'])
+ call assert_equal('foo/bbb', Func())
+endfunc
+
+fun InnerCall(funcref)
+ return a:funcref
+endfu
+
+fun OuterCall()
+ let opt = { 'func' : function('sin') }
+ call InnerCall(opt.func)
+endfu
+
+func Test_function_in_dict()
+ call OuterCall()
+endfunc
+
+function! s:cache_clear() dict
+ return self.name
+endfunction
+
+func Test_script_function_in_dict()
+ let s:obj = {'name': 'foo'}
+ let s:obj2 = {'name': 'bar'}
+
+ let s:obj['clear'] = function('s:cache_clear')
+
+ call assert_equal('foo', s:obj.clear())
+ let F = s:obj.clear
+ call assert_equal('foo', F())
+ call assert_equal('foo', call(s:obj.clear, [], s:obj))
+ call assert_equal('bar', call(s:obj.clear, [], s:obj2))
+
+ let s:obj2['clear'] = function('s:cache_clear')
+ call assert_equal('bar', s:obj2.clear())
+ let B = s:obj2.clear
+ call assert_equal('bar', B())
+endfunc
+
+function! s:cache_arg(arg) dict
+ let s:result = self.name . '/' . a:arg
+ return s:result
+endfunction
+
+func Test_script_function_in_dict_arg()
+ let s:obj = {'name': 'foo'}
+ let s:obj['clear'] = function('s:cache_arg')
+
+ call assert_equal('foo/bar', s:obj.clear('bar'))
+ let F = s:obj.clear
+ let s:result = ''
+ call assert_equal('foo/bar', F('bar'))
+ call assert_equal('foo/bar', s:result)
+
+ let s:obj['clear'] = function('s:cache_arg', ['bar'])
+ call assert_equal('foo/bar', s:obj.clear())
+ let s:result = ''
+ call s:obj.clear()
+ call assert_equal('foo/bar', s:result)
+
+ let F = s:obj.clear
+ call assert_equal('foo/bar', F())
+ let s:result = ''
+ call F()
+ call assert_equal('foo/bar', s:result)
+
+ call assert_equal('foo/bar', call(s:obj.clear, [], s:obj))
+endfunc
+
+func Test_partial_exists()
+ let F = function('MyFunc')
+ call assert_true(exists('*F'))
+ let lF = [F]
+ call assert_true(exists('*lF[0]'))
+
+ let F = function('MyFunc', ['arg'])
+ call assert_true(exists('*F'))
+ let lF = [F]
+ call assert_true(exists('*lF[0]'))
+endfunc
+
+func Test_partial_string()
+ let F = function('MyFunc')
+ call assert_equal("function('MyFunc')", string(F))
+ let F = function('MyFunc', ['foo'])
+ call assert_equal("function('MyFunc', ['foo'])", string(F))
+ let F = function('MyFunc', ['foo', 'bar'])
+ call assert_equal("function('MyFunc', ['foo', 'bar'])", string(F))
+ let d = {'one': 1}
+ let F = function('MyFunc', d)
+ call assert_equal("function('MyFunc', {'one': 1})", string(F))
+ let F = function('MyFunc', ['foo'], d)
+ call assert_equal("function('MyFunc', ['foo'], {'one': 1})", string(F))
+endfunc
+
+func Test_func_unref()
+ let obj = {}
+ function! obj.func() abort
+ endfunction
+ let funcnumber = matchstr(string(obj.func), '^function(''\zs.\{-}\ze''')
+ call assert_true(exists('*{' . funcnumber . '}'))
+ unlet obj
+ call assert_false(exists('*{' . funcnumber . '}'))
+endfunc
+
+func Test_redefine_dict_func()
+ let d = {}
+ function d.test4()
+ endfunction
+ let d.test4 = d.test4
+ try
+ function! d.test4(name)
+ endfunction
+ catch
+ call assert_true(v:errmsg, v:exception)
+ endtry
+endfunc
+
+" This caused double free on exit if EXITFREE is defined.
+func Test_cyclic_list_arg()
+ let l = []
+ let Pt = function('string', [l])
+ call add(l, Pt)
+ unlet l
+ unlet Pt
+endfunc
+
+" This caused double free on exit if EXITFREE is defined.
+func Test_cyclic_dict_arg()
+ let d = {}
+ let Pt = function('string', [d])
+ let d.Pt = Pt
+ unlet d
+ unlet Pt
+endfunc
+
+func Ignored(job1, job2, status)
+endfunc
+
+" func Test_cycle_partial_job()
+" let job = job_start('echo')
+" call job_setoptions(job, {'exit_cb': function('Ignored', [job])})
+" unlet job
+" endfunc
+
+" func Test_ref_job_partial_dict()
+" let g:ref_job = job_start('echo')
+" let d = {'a': 'b'}
+" call job_setoptions(g:ref_job, {'exit_cb': function('string', [], d)})
+" endfunc
+
+func Test_auto_partial_rebind()
+ let dict1 = {'name': 'dict1'}
+ func! dict1.f1()
+ return self.name
+ endfunc
+ let dict1.f2 = function(dict1.f1, dict1)
+
+ call assert_equal('dict1', dict1.f1())
+ call assert_equal('dict1', dict1['f1']())
+ call assert_equal('dict1', dict1.f2())
+ call assert_equal('dict1', dict1['f2']())
+
+ let dict2 = {'name': 'dict2'}
+ let dict2.f1 = dict1.f1
+ let dict2.f2 = dict1.f2
+
+ call assert_equal('dict2', dict2.f1())
+ call assert_equal('dict2', dict2['f1']())
+ call assert_equal('dict1', dict2.f2())
+ call assert_equal('dict1', dict2['f2']())
+endfunc
+
+func Test_get_partial_items()
+ let dict = {'name': 'hello'}
+ let args = ["foo", "bar"]
+ let Func = function('MyDictFunc')
+ let Cb = function('MyDictFunc', args, dict)
+
+ call assert_equal(Func, get(Cb, 'func'))
+ call assert_equal('MyDictFunc', get(Cb, 'name'))
+ call assert_equal(args, get(Cb, 'args'))
+ call assert_equal(dict, get(Cb, 'dict'))
+ call assert_fails('call get(Cb, "xxx")', 'E475:')
+
+ call assert_equal(Func, get(Func, 'func'))
+ call assert_equal('MyDictFunc', get(Func, 'name'))
+ call assert_equal([], get(Func, 'args'))
+ call assert_true(empty( get(Func, 'dict')))
+endfunc
+
+func Test_compare_partials()
+ let d1 = {}
+ let d2 = {}
+
+ function d1.f1() dict
+ endfunction
+
+ function d1.f2() dict
+ endfunction
+
+ let F1 = get(d1, 'f1')
+ let F2 = get(d1, 'f2')
+
+ let F1d1 = function(F1, d1)
+ let F2d1 = function(F2, d2)
+ let F1d1a1 = function(F1d1, [1])
+ let F1d1a12 = function(F1d1, [1, 2])
+ let F1a1 = function(F1, [1])
+ let F1a2 = function(F1, [2])
+ let F1d2 = function(F1, d2)
+ let d3 = {'f1': F1, 'f2': F2}
+ let F1d3 = function(F1, d3)
+ let F1ad1 = function(F1, [d1])
+ let F1ad3 = function(F1, [d3])
+
+ call assert_match('^function(''\d\+'')$', string(F1)) " Not a partial
+ call assert_match('^function(''\d\+'')$', string(F2)) " Not a partial
+ call assert_match('^function(''\d\+'', {.*})$', string(F1d1)) " A partial
+ call assert_match('^function(''\d\+'', {.*})$', string(F2d1)) " A partial
+ call assert_match('^function(''\d\+'', \[.*\])$', string(F1a1)) " No dict
+
+ " !=
+ let X = F1
+ call assert_false(F1 != X) " same function
+ let X = F1d1
+ call assert_false(F1d1 != X) " same partial
+ let X = F1d1a1
+ call assert_false(F1d1a1 != X) " same partial
+ let X = F1a1
+ call assert_false(F1a1 != X) " same partial
+
+ call assert_true(F1 != F2) " Different functions
+ call assert_true(F1 != F1d1) " Partial /= non-partial
+ call assert_true(F1d1a1 != F1d1a12) " Different number of arguments
+ call assert_true(F1a1 != F1d1a12) " One has no dict
+ call assert_true(F1a1 != F1a2) " Different arguments
+ call assert_true(F1d2 != F1d1) " Different dictionaries
+ call assert_false(F1d1 != F1d3) " Equal dictionaries, even though d1 isnot d3
+
+ " isnot, option 1
+ call assert_true(F1 isnot# F2) " Different functions
+ call assert_true(F1 isnot# F1d1) " Partial /= non-partial
+ call assert_true(F1d1 isnot# F1d3) " d1 isnot d3, even though d1 == d3
+ call assert_true(F1a1 isnot# F1d1a12) " One has no dict
+ call assert_true(F1a1 isnot# F1a2) " Different number of arguments
+ call assert_true(F1ad1 isnot# F1ad3) " In arguments d1 isnot d3
+
+ " isnot, option 2
+ call assert_true(F1 isnot# F2) " Different functions
+ call assert_true(F1 isnot# F1d1) " Partial /= non-partial
+ call assert_true(d1.f1 isnot# d1.f1) " handle_subscript creates new partial each time
+endfunc
diff --git a/src/nvim/testdir/test_plus_arg_edit.vim b/src/nvim/testdir/test_plus_arg_edit.vim
new file mode 100644
index 0000000000..71dbea1991
--- /dev/null
+++ b/src/nvim/testdir/test_plus_arg_edit.vim
@@ -0,0 +1,10 @@
+" Tests for complicated + argument to :edit command
+function Test_edit()
+ call writefile(["foo|bar"], "Xfile1")
+ call writefile(["foo/bar"], "Xfile2")
+ edit +1|s/|/PIPE/|w Xfile1| e Xfile2|1 | s/\//SLASH/|w
+ call assert_equal(["fooPIPEbar"], readfile("Xfile1"))
+ call assert_equal(["fooSLASHbar"], readfile("Xfile2"))
+ call delete('Xfile1')
+ call delete('Xfile2')
+endfunction
diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim
new file mode 100644
index 0000000000..6c43cbc1dc
--- /dev/null
+++ b/src/nvim/testdir/test_popup.vim
@@ -0,0 +1,715 @@
+" Test for completion menu
+
+source shared.vim
+
+let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
+let g:setting = ''
+
+func! ListMonths()
+ if g:setting != ''
+ exe ":set" g:setting
+ endif
+ let mth = copy(g:months)
+ let entered = strcharpart(getline('.'),0,col('.'))
+ if !empty(entered)
+ let mth = filter(mth, 'v:val=~"^".entered')
+ endif
+ call complete(1, mth)
+ return ''
+endfunc
+
+func! Test_popup_complete2()
+ " Although the popupmenu is not visible, this does not mean completion mode
+ " has ended. After pressing <f5> to complete the currently typed char, Vim
+ " still stays in the first state of the completion (:h ins-completion-menu),
+ " although the popupmenu wasn't shown <c-e> will remove the inserted
+ " completed text (:h complete_CTRL-E), while the following <c-e> will behave
+ " like expected (:h i_CTRL-E)
+ new
+ inoremap <f5> <c-r>=ListMonths()<cr>
+ call append(1, ["December2015"])
+ :1
+ call feedkeys("aD\<f5>\<C-E>\<C-E>\<C-E>\<C-E>\<enter>\<esc>", 'tx')
+ call assert_equal(["Dece", "", "December2015"], getline(1,3))
+ %d
+ bw!
+endfu
+
+func! Test_popup_complete()
+ new
+ inoremap <f5> <c-r>=ListMonths()<cr>
+
+ " <C-E> - select original typed text before the completion started
+ call feedkeys("aJu\<f5>\<down>\<c-e>\<esc>", 'tx')
+ call assert_equal(["Ju"], getline(1,2))
+ %d
+
+ " <C-Y> - accept current match
+ call feedkeys("a\<f5>". repeat("\<down>",7). "\<c-y>\<esc>", 'tx')
+ call assert_equal(["August"], getline(1,2))
+ %d
+
+ " <BS> - Delete one character from the inserted text (state: 1)
+ " TODO: This should not end the completion, but it does.
+ " This should according to the documentation:
+ " January
+ " but instead, this does
+ " Januar
+ " (idea is, C-L inserts the match from the popup menu
+ " but if the menu is closed, it will insert the character <c-l>
+ call feedkeys("aJ\<f5>\<bs>\<c-l>\<esc>", 'tx')
+ call assert_equal(["Januar "], getline(1,2))
+ %d
+
+ " any-non special character: Stop completion without changing the match
+ " and insert the typed character
+ call feedkeys("a\<f5>20", 'tx')
+ call assert_equal(["January20"], getline(1,2))
+ %d
+
+ " any-non printable, non-white character: Add this character and
+ " reduce number of matches
+ call feedkeys("aJu\<f5>\<c-p>l\<c-y>", 'tx')
+ call assert_equal(["Jul"], getline(1,2))
+ %d
+
+ " any-non printable, non-white character: Add this character and
+ " reduce number of matches
+ call feedkeys("aJu\<f5>\<c-p>l\<c-n>\<c-y>", 'tx')
+ call assert_equal(["July"], getline(1,2))
+ %d
+
+ " any-non printable, non-white character: Add this character and
+ " reduce number of matches
+ call feedkeys("aJu\<f5>\<c-p>l\<c-e>", 'tx')
+ call assert_equal(["Jul"], getline(1,2))
+ %d
+
+ " <BS> - Delete one character from the inserted text (state: 2)
+ call feedkeys("a\<f5>\<c-n>\<bs>", 'tx')
+ call assert_equal(["Februar"], getline(1,2))
+ %d
+
+ " <c-l> - Insert one character from the current match
+ call feedkeys("aJ\<f5>".repeat("\<c-n>",3)."\<c-l>\<esc>", 'tx')
+ call assert_equal(["J "], getline(1,2))
+ %d
+
+ " <c-l> - Insert one character from the current match
+ call feedkeys("aJ\<f5>".repeat("\<c-n>",4)."\<c-l>\<esc>", 'tx')
+ call assert_equal(["January "], getline(1,2))
+ %d
+
+ " <c-y> - Accept current selected match
+ call feedkeys("aJ\<f5>\<c-y>\<esc>", 'tx')
+ call assert_equal(["January"], getline(1,2))
+ %d
+
+ " <c-e> - End completion, go back to what was there before selecting a match
+ call feedkeys("aJu\<f5>\<c-e>\<esc>", 'tx')
+ call assert_equal(["Ju"], getline(1,2))
+ %d
+
+ " <PageUp> - Select a match several entries back
+ call feedkeys("a\<f5>\<PageUp>\<c-y>\<esc>", 'tx')
+ call assert_equal([""], getline(1,2))
+ %d
+
+ " <PageUp><PageUp> - Select a match several entries back
+ call feedkeys("a\<f5>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx')
+ call assert_equal(["December"], getline(1,2))
+ %d
+
+ " <PageUp><PageUp><PageUp> - Select a match several entries back
+ call feedkeys("a\<f5>\<PageUp>\<PageUp>\<PageUp>\<c-y>\<esc>", 'tx')
+ call assert_equal(["February"], getline(1,2))
+ %d
+
+ " <PageDown> - Select a match several entries further
+ call feedkeys("a\<f5>\<PageDown>\<c-y>\<esc>", 'tx')
+ call assert_equal(["November"], getline(1,2))
+ %d
+
+ " <PageDown><PageDown> - Select a match several entries further
+ call feedkeys("a\<f5>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx')
+ call assert_equal(["December"], getline(1,2))
+ %d
+
+ " <PageDown><PageDown><PageDown> - Select a match several entries further
+ call feedkeys("a\<f5>\<PageDown>\<PageDown>\<PageDown>\<c-y>\<esc>", 'tx')
+ call assert_equal([""], getline(1,2))
+ %d
+
+ " <PageDown><PageDown><PageDown><PageDown> - Select a match several entries further
+ call feedkeys("a\<f5>".repeat("\<PageDown>",4)."\<c-y>\<esc>", 'tx')
+ call assert_equal(["October"], getline(1,2))
+ %d
+
+ " <Up> - Select a match don't insert yet
+ call feedkeys("a\<f5>\<Up>\<c-y>\<esc>", 'tx')
+ call assert_equal([""], getline(1,2))
+ %d
+
+ " <Up><Up> - Select a match don't insert yet
+ call feedkeys("a\<f5>\<Up>\<Up>\<c-y>\<esc>", 'tx')
+ call assert_equal(["December"], getline(1,2))
+ %d
+
+ " <Up><Up><Up> - Select a match don't insert yet
+ call feedkeys("a\<f5>\<Up>\<Up>\<Up>\<c-y>\<esc>", 'tx')
+ call assert_equal(["November"], getline(1,2))
+ %d
+
+ " <Tab> - Stop completion and insert the match
+ call feedkeys("a\<f5>\<Tab>\<c-y>\<esc>", 'tx')
+ call assert_equal(["January "], getline(1,2))
+ %d
+
+ " <Space> - Stop completion and insert the match
+ call feedkeys("a\<f5>".repeat("\<c-p>",5)." \<esc>", 'tx')
+ call assert_equal(["September "], getline(1,2))
+ %d
+
+ " <Enter> - Use the text and insert line break (state: 1)
+ call feedkeys("a\<f5>\<enter>\<esc>", 'tx')
+ call assert_equal(["January", ''], getline(1,2))
+ %d
+
+ " <Enter> - Insert the current selected text (state: 2)
+ call feedkeys("a\<f5>".repeat("\<Up>",5)."\<enter>\<esc>", 'tx')
+ call assert_equal(["September"], getline(1,2))
+ %d
+
+ " Insert match immediately, if there is only one match
+ " <c-y> selects a character from the line above
+ call append(0, ["December2015"])
+ call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx')
+ call assert_equal(["December2015", "December2015", ""], getline(1,3))
+ %d
+
+ " use menuone for 'completeopt'
+ " Since for the first <c-y> the menu is still shown, will only select
+ " three letters from the line above
+ set completeopt&vim
+ set completeopt+=menuone
+ call append(0, ["December2015"])
+ call feedkeys("aD\<f5>\<C-Y>\<C-Y>\<C-Y>\<C-Y>\<enter>\<esc>", 'tx')
+ call assert_equal(["December2015", "December201", ""], getline(1,3))
+ %d
+
+ " use longest for 'completeopt'
+ set completeopt&vim
+ call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx')
+ set completeopt+=longest
+ call feedkeys("aM\<f5>\<C-N>\<C-P>\<c-e>\<enter>\<esc>", 'tx')
+ call assert_equal(["M", "Ma", ""], getline(1,3))
+ %d
+
+ " use noselect/noinsert for 'completeopt'
+ set completeopt&vim
+ call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
+ set completeopt+=noselect
+ call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
+ set completeopt-=noselect completeopt+=noinsert
+ call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
+ call assert_equal(["March", "M", "March"], getline(1,4))
+ %d
+endfu
+
+
+func! Test_popup_completion_insertmode()
+ new
+ inoremap <F5> <C-R>=ListMonths()<CR>
+
+ call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx')
+ call assert_equal('February', getline(1))
+ %d
+ " Set noinsertmode
+ let g:setting = 'noinsertmode'
+ call feedkeys("a\<f5>\<down>\<enter>\<esc>", 'tx')
+ call assert_equal('February', getline(1))
+ call assert_false(pumvisible())
+ %d
+ " Go through all matches, until none is selected
+ let g:setting = ''
+ call feedkeys("a\<f5>". repeat("\<c-n>",12)."\<enter>\<esc>", 'tx')
+ call assert_equal('', getline(1))
+ %d
+ " select previous entry
+ call feedkeys("a\<f5>\<c-p>\<enter>\<esc>", 'tx')
+ call assert_equal('', getline(1))
+ %d
+ " select last entry
+ call feedkeys("a\<f5>\<c-p>\<c-p>\<enter>\<esc>", 'tx')
+ call assert_equal('December', getline(1))
+
+ iunmap <F5>
+endfunc
+
+" TODO: Fix what breaks after this line.
+" - Do not use "q!", it may exit Vim if there is an error
+finish
+
+func Test_noinsert_complete()
+ function! s:complTest1() abort
+ call complete(1, ['source', 'soundfold'])
+ return ''
+ endfunction
+
+ function! s:complTest2() abort
+ call complete(1, ['source', 'soundfold'])
+ return ''
+ endfunction
+
+ new
+ set completeopt+=noinsert
+ inoremap <F5> <C-R>=s:complTest1()<CR>
+ call feedkeys("i\<F5>soun\<CR>\<CR>\<ESC>.", 'tx')
+ call assert_equal('soundfold', getline(1))
+ call assert_equal('soundfold', getline(2))
+ bwipe!
+
+ new
+ inoremap <F5> <C-R>=s:complTest2()<CR>
+ call feedkeys("i\<F5>\<CR>\<ESC>", 'tx')
+ call assert_equal('source', getline(1))
+ bwipe!
+
+ set completeopt-=noinsert
+ iunmap <F5>
+endfunc
+
+func Test_compl_vim_cmds_after_register_expr()
+ function! s:test_func()
+ return 'autocmd '
+ endfunction
+ augroup AAAAA_Group
+ au!
+ augroup END
+
+ new
+ call feedkeys("i\<c-r>=s:test_func()\<CR>\<C-x>\<C-v>\<Esc>", 'tx')
+ call assert_equal('autocmd AAAAA_Group', getline(1))
+ autocmd! AAAAA_Group
+ augroup! AAAAA_Group
+ bwipe!
+endfunc
+
+func DummyCompleteOne(findstart, base)
+ if a:findstart
+ return 0
+ else
+ wincmd n
+ return ['onedef', 'oneDEF']
+ endif
+endfunc
+
+" Test that nothing happens if the 'completefunc' opens
+" a new window (no completion, no crash)
+func Test_completefunc_opens_new_window_one()
+ new
+ let winid = win_getid()
+ setlocal completefunc=DummyCompleteOne
+ call setline(1, 'one')
+ /^one
+ call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E839:')
+ call assert_notequal(winid, win_getid())
+ q!
+ call assert_equal(winid, win_getid())
+ call assert_equal('', getline(1))
+ q!
+endfunc
+
+" Test that nothing happens if the 'completefunc' opens
+" a new window (no completion, no crash)
+func DummyCompleteTwo(findstart, base)
+ if a:findstart
+ wincmd n
+ return 0
+ else
+ return ['twodef', 'twoDEF']
+ endif
+endfunction
+
+" Test that nothing happens if the 'completefunc' opens
+" a new window (no completion, no crash)
+func Test_completefunc_opens_new_window_two()
+ new
+ let winid = win_getid()
+ setlocal completefunc=DummyCompleteTwo
+ call setline(1, 'two')
+ /^two
+ call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E764:')
+ call assert_notequal(winid, win_getid())
+ q!
+ call assert_equal(winid, win_getid())
+ call assert_equal('two', getline(1))
+ q!
+endfunc
+
+func DummyCompleteThree(findstart, base)
+ if a:findstart
+ return 0
+ else
+ return ['threedef', 'threeDEF']
+ endif
+endfunc
+
+:"Test that 'completefunc' works when it's OK.
+func Test_completefunc_works()
+ new
+ let winid = win_getid()
+ setlocal completefunc=DummyCompleteThree
+ call setline(1, 'three')
+ /^three
+ call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")
+ call assert_equal(winid, win_getid())
+ call assert_equal('threeDEF', getline(1))
+ q!
+endfunc
+
+func DummyCompleteFour(findstart, base)
+ if a:findstart
+ return 0
+ else
+ call complete_add('four1')
+ call complete_add('four2')
+ call complete_check()
+ call complete_add('four3')
+ call complete_add('four4')
+ call complete_check()
+ call complete_add('four5')
+ call complete_add('four6')
+ return []
+ endif
+endfunc
+
+" Test that 'omnifunc' works when it's OK.
+func Test_omnifunc_with_check()
+ new
+ setlocal omnifunc=DummyCompleteFour
+ call setline(1, 'four')
+ /^four
+ call feedkeys("A\<C-X>\<C-O>\<C-N>\<Esc>", "x")
+ call assert_equal('four2', getline(1))
+
+ call setline(1, 'four')
+ /^four
+ call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<Esc>", "x")
+ call assert_equal('four3', getline(1))
+
+ call setline(1, 'four')
+ /^four
+ call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<C-N>\<Esc>", "x")
+ call assert_equal('four5', getline(1))
+
+ q!
+endfunc
+
+function UndoComplete()
+ call complete(1, ['January', 'February', 'March',
+ \ 'April', 'May', 'June', 'July', 'August', 'September',
+ \ 'October', 'November', 'December'])
+ return ''
+endfunc
+
+" Test that no undo item is created when no completion is inserted
+func Test_complete_no_undo()
+ set completeopt=menu,preview,noinsert,noselect
+ inoremap <Right> <C-R>=UndoComplete()<CR>
+ new
+ call feedkeys("ixxx\<CR>\<CR>yyy\<Esc>k", 'xt')
+ call feedkeys("iaaa\<Esc>0", 'xt')
+ call assert_equal('aaa', getline(2))
+ call feedkeys("i\<Right>\<Esc>", 'xt')
+ call assert_equal('aaa', getline(2))
+ call feedkeys("u", 'xt')
+ call assert_equal('', getline(2))
+
+ call feedkeys("ibbb\<Esc>0", 'xt')
+ call assert_equal('bbb', getline(2))
+ call feedkeys("A\<Right>\<Down>\<CR>\<Esc>", 'xt')
+ call assert_equal('January', getline(2))
+ call feedkeys("u", 'xt')
+ call assert_equal('bbb', getline(2))
+
+ call feedkeys("A\<Right>\<C-N>\<Esc>", 'xt')
+ call assert_equal('January', getline(2))
+ call feedkeys("u", 'xt')
+ call assert_equal('bbb', getline(2))
+
+ iunmap <Right>
+ set completeopt&
+ q!
+endfunc
+
+function! DummyCompleteFive(findstart, base)
+ if a:findstart
+ return 0
+ else
+ return [
+ \ { 'word': 'January', 'info': "info1-1\n1-2\n1-3" },
+ \ { 'word': 'February', 'info': "info2-1\n2-2\n2-3" },
+ \ { 'word': 'March', 'info': "info3-1\n3-2\n3-3" },
+ \ { 'word': 'April', 'info': "info4-1\n4-2\n4-3" },
+ \ { 'word': 'May', 'info': "info5-1\n5-2\n5-3" },
+ \ ]
+ endif
+endfunc
+
+" Test that 'completefunc' on Scratch buffer with preview window works when
+" it's OK.
+func Test_completefunc_with_scratch_buffer()
+ new +setlocal\ buftype=nofile\ bufhidden=wipe\ noswapfile
+ set completeopt+=preview
+ setlocal completefunc=DummyCompleteFive
+ call feedkeys("A\<C-X>\<C-U>\<C-N>\<C-N>\<C-N>\<Esc>", "x")
+ call assert_equal(['April'], getline(1, '$'))
+ pclose
+ q!
+ set completeopt&
+endfunc
+
+" <C-E> - select original typed text before the completion started without
+" auto-wrap text.
+func Test_completion_ctrl_e_without_autowrap()
+ new
+ let tw_save = &tw
+ set tw=78
+ let li = [
+ \ '" zzz',
+ \ '" zzzyyyyyyyyyyyyyyyyyyy']
+ call setline(1, li)
+ 0
+ call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx")
+ call assert_equal(li, getline(1, '$'))
+
+ let &tw = tw_save
+ q!
+endfunc
+
+func Test_completion_respect_bs_option()
+ new
+ let li = ["aaa", "aaa12345", "aaaabcdef", "aaaABC"]
+
+ set bs=indent,eol
+ call setline(1, li)
+ 1
+ call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
+ call assert_equal('aaa', getline(1))
+
+ %d
+ set bs=indent,eol,start
+ call setline(1, li)
+ 1
+ call feedkeys("A\<C-X>\<C-N>\<C-P>\<BS>\<BS>\<BS>\<Esc>", "tx")
+ call assert_equal('', getline(1))
+
+ bw!
+endfunc
+
+func CompleteUndo() abort
+ call complete(1, g:months)
+ return ''
+endfunc
+
+func Test_completion_can_undo()
+ inoremap <Right> <c-r>=CompleteUndo()<cr>
+ set completeopt+=noinsert,noselect
+
+ new
+ call feedkeys("a\<Right>a\<Esc>", 'xt')
+ call assert_equal('a', getline(1))
+ undo
+ call assert_equal('', getline(1))
+
+ bwipe!
+ set completeopt&
+ iunmap <Right>
+endfunc
+
+func Test_completion_comment_formatting()
+ new
+ setl formatoptions=tcqro
+ call feedkeys("o/*\<cr>\<cr>/\<esc>", 'tx')
+ call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
+ %d
+ call feedkeys("o/*\<cr>foobar\<cr>/\<esc>", 'tx')
+ call assert_equal(['', '/*', ' * foobar', ' */'], getline(1,4))
+ %d
+ try
+ call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx')
+ call assert_report('completefunc not set, should have failed')
+ catch
+ call assert_exception('E764:')
+ endtry
+ call assert_equal(['', '/*', ' *', ' */'], getline(1,4))
+ bwipe!
+endfunc
+
+function! DummyCompleteSix()
+ call complete(1, ['Hello', 'World'])
+ return ''
+endfunction
+
+" complete() correctly clears the list of autocomplete candidates
+func Test_completion_clear_candidate_list()
+ new
+ %d
+ " select first entry from the completion popup
+ call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx")
+ call assert_equal('Hello', getline(1))
+ %d
+ " select second entry from the completion popup
+ call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx")
+ call assert_equal('World', getline(1))
+ %d
+ " select original text
+ call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx")
+ call assert_equal(' xxx', getline(1))
+ %d
+ " back at first entry from completion list
+ call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx")
+ call assert_equal('Hello', getline(1))
+
+ bw!
+endfunc
+
+func Test_popup_complete_backwards()
+ new
+ call setline(1, ['Post', 'Port', 'Po'])
+ let expected=['Post', 'Port', 'Port']
+ call cursor(3,2)
+ call feedkeys("A\<C-X>". repeat("\<C-P>", 3). "rt\<cr>", 'tx')
+ call assert_equal(expected, getline(1,'$'))
+ bwipe!
+endfunc
+
+func Test_popup_and_preview_autocommand()
+ " This used to crash Vim
+ if !has('python')
+ return
+ endif
+ let h = winheight(0)
+ if h < 15
+ return
+ endif
+ new
+ augroup MyBufAdd
+ au!
+ au BufAdd * nested tab sball
+ augroup END
+ set omnifunc=pythoncomplete#Complete
+ call setline(1, 'import os')
+ " make the line long
+ call setline(2, ' os.')
+ $
+ call feedkeys("A\<C-X>\<C-O>\<C-N>\<C-N>\<C-N>\<enter>\<esc>", 'tx')
+ call assert_equal("import os", getline(1))
+ call assert_match(' os.\(EX_IOERR\|O_CREAT\)$', getline(2))
+ call assert_equal(1, winnr('$'))
+ " previewwindow option is not set
+ call assert_equal(0, &previewwindow)
+ norm! gt
+ call assert_equal(0, &previewwindow)
+ norm! gT
+ call assert_equal(12, tabpagenr('$'))
+ tabonly
+ pclose
+ augroup MyBufAdd
+ au!
+ augroup END
+ augroup! MyBufAdd
+ bw!
+endfunc
+
+fun MessCompleteMonths()
+ for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep")
+ call complete_add(m)
+ if complete_check()
+ break
+ endif
+ endfor
+ return []
+endfun
+
+fun MessCompleteMore()
+ call complete(1, split("Oct Nov Dec"))
+ return []
+endfun
+
+fun MessComplete(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
+ call MessCompleteMonths()
+ call MessCompleteMore()
+ return []
+ endif
+endf
+
+func Test_complete_func_mess()
+ " Calling complete() after complete_add() in 'completefunc' is wrong, but it
+ " should not crash.
+ set completefunc=MessComplete
+ new
+ call setline(1, 'Ju')
+ call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx')
+ call assert_equal('Oct/Oct', getline(1))
+ bwipe!
+ set completefunc=
+endfunc
+
+func Test_complete_CTRLN_startofbuffer()
+ new
+ call setline(1, [ 'organize(cupboard, 3, 2);',
+ \ 'prioritize(bureau, 8, 7);',
+ \ 'realize(bannister, 4, 4);',
+ \ 'moralize(railing, 3,9);'])
+ let expected=['cupboard.organize(3, 2);',
+ \ 'bureau.prioritize(8, 7);',
+ \ 'bannister.realize(4, 4);',
+ \ 'railing.moralize(3,9);']
+ call feedkeys("qai\<c-n>\<c-n>.\<esc>3wdW\<cr>q3@a", 'tx')
+ call assert_equal(expected, getline(1,'$'))
+ bwipe!
+endfunc
+
+func Test_popup_and_window_resize()
+ if !has('terminal') || has('gui_running')
+ return
+ endif
+ let h = winheight(0)
+ if h < 15
+ return
+ endif
+ let g:buf = term_start([$NVIM_PRG, '--clean', '-c', 'set noswapfile'], {'term_rows': h / 3})
+ call term_sendkeys(g:buf, (h / 3 - 1)."o\<esc>G")
+ call term_sendkeys(g:buf, "i\<c-x>")
+ call term_wait(g:buf, 200)
+ call term_sendkeys(g:buf, "\<c-v>")
+ call term_wait(g:buf, 100)
+ " popup first entry "!" must be at the top
+ call WaitFor('term_getline(g:buf, 1) =~ "^!"')
+ call assert_match('^!\s*$', term_getline(g:buf, 1))
+ exe 'resize +' . (h - 1)
+ call term_wait(g:buf, 100)
+ redraw!
+ " popup shifted down, first line is now empty
+ call WaitFor('term_getline(g:buf, 1) == ""')
+ call assert_equal('', term_getline(g:buf, 1))
+ sleep 100m
+ " popup is below cursor line and shows first match "!"
+ call WaitFor('term_getline(g:buf, term_getcursor(g:buf)[0] + 1) =~ "^!"')
+ call assert_match('^!\s*$', term_getline(g:buf, term_getcursor(g:buf)[0] + 1))
+ " cursor line also shows !
+ call assert_match('^!\s*$', term_getline(g:buf, term_getcursor(g:buf)[0]))
+ bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_preview.vim b/src/nvim/testdir/test_preview.vim
new file mode 100644
index 0000000000..91923fb1e9
--- /dev/null
+++ b/src/nvim/testdir/test_preview.vim
@@ -0,0 +1,13 @@
+" Tests for the preview window
+
+func Test_Psearch()
+ " this used to cause ml_get errors
+ help
+ let wincount = winnr('$')
+ 0f
+ ps.
+ call assert_equal(wincount + 1, winnr('$'))
+ pclose
+ call assert_equal(wincount, winnr('$'))
+ bwipe
+endfunc
diff --git a/src/nvim/testdir/test_profile.vim b/src/nvim/testdir/test_profile.vim
new file mode 100644
index 0000000000..4cbd800da5
--- /dev/null
+++ b/src/nvim/testdir/test_profile.vim
@@ -0,0 +1,183 @@
+" Test Vim profiler
+if !has('profile')
+ finish
+endif
+
+func Test_profile_func()
+ let lines = [
+ \ "func! Foo1()",
+ \ "endfunc",
+ \ "func! Foo2()",
+ \ " let l:count = 100",
+ \ " while l:count > 0",
+ \ " let l:count = l:count - 1",
+ \ " endwhile",
+ \ "endfunc",
+ \ "func! Foo3()",
+ \ "endfunc",
+ \ "func! Bar()",
+ \ "endfunc",
+ \ "call Foo1()",
+ \ "call Foo1()",
+ \ "profile pause",
+ \ "call Foo1()",
+ \ "profile continue",
+ \ "call Foo2()",
+ \ "call Foo3()",
+ \ "call Bar()",
+ \ "if !v:profiling",
+ \ " delfunc Foo2",
+ \ "endif",
+ \ "delfunc Foo3",
+ \ ]
+
+ call writefile(lines, 'Xprofile_func.vim')
+ call system(v:progpath
+ \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+ \ . ' -c "profile start Xprofile_func.log"'
+ \ . ' -c "profile func Foo*"'
+ \ . ' -c "so Xprofile_func.vim"'
+ \ . ' -c "qall!"')
+ call assert_equal(0, v:shell_error)
+
+ let lines = readfile('Xprofile_func.log')
+
+ " - Foo1() is called 3 times but should be reported as called twice
+ " since one call is in between "profile pause" .. "profile continue".
+ " - Foo2() should come before Foo1() since Foo1() does much more work.
+ " - Foo3() is not reported because function is deleted.
+ " - Unlike Foo3(), Foo2() should not be deleted since there is a check
+ " for v:profiling.
+ " - Bar() is not reported since it does not match "profile func Foo*".
+ call assert_equal(28, len(lines))
+
+ call assert_equal('FUNCTION Foo1()', lines[0])
+ call assert_equal('Called 2 times', lines[1])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
+ call assert_equal('', lines[4])
+ call assert_equal('count total (s) self (s)', lines[5])
+ call assert_equal('', lines[6])
+ call assert_equal('FUNCTION Foo2()', lines[7])
+ call assert_equal('Called 1 time', lines[8])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[9])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[10])
+ call assert_equal('', lines[11])
+ call assert_equal('count total (s) self (s)', lines[12])
+ call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[13])
+ call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[14])
+ call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[15])
+ call assert_match('^\s*100\s\+.*\sendwhile$', lines[16])
+ call assert_equal('', lines[17])
+ call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[18])
+ call assert_equal('count total (s) self (s) function', lines[19])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[20])
+ call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[21])
+ call assert_equal('', lines[22])
+ call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[23])
+ call assert_equal('count total (s) self (s) function', lines[24])
+ call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[25])
+ call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[26])
+ call assert_equal('', lines[27])
+
+ call delete('Xprofile_func.vim')
+ call delete('Xprofile_func.log')
+endfunc
+
+func Test_profile_file()
+ let lines = [
+ \ 'func! Foo()',
+ \ 'endfunc',
+ \ 'for i in range(10)',
+ \ ' " a comment',
+ \ ' call Foo()',
+ \ 'endfor',
+ \ 'call Foo()',
+ \ ]
+
+ call writefile(lines, 'Xprofile_file.vim')
+ call system(v:progpath
+ \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+ \ . ' -c "profile start Xprofile_file.log"'
+ \ . ' -c "profile file Xprofile_file.vim"'
+ \ . ' -c "so Xprofile_file.vim"'
+ \ . ' -c "so Xprofile_file.vim"'
+ \ . ' -c "qall!"')
+ call assert_equal(0, v:shell_error)
+
+ let lines = readfile('Xprofile_file.log')
+
+ call assert_equal(14, len(lines))
+
+ call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0])
+ call assert_equal('Sourced 2 times', lines[1])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
+ call assert_equal('', lines[4])
+ call assert_equal('count total (s) self (s)', lines[5])
+ call assert_match(' 2 0.\d\+ func! Foo()', lines[6])
+ call assert_equal(' endfunc', lines[7])
+ " Loop iterates 10 times. Since script runs twice, body executes 20 times.
+ " First line of loop executes one more time than body to detect end of loop.
+ call assert_match('^\s*22\s\+\d\+\.\d\+\s\+for i in range(10)$', lines[8])
+ call assert_equal(' " a comment', lines[9])
+ " if self and total are equal we only get one number
+ call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10])
+ call assert_match('^\s*20\s\+\d\+\.\d\+\s\+endfor$', lines[11])
+ " if self and total are equal we only get one number
+ call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12])
+ call assert_equal('', lines[13])
+
+ call delete('Xprofile_file.vim')
+ call delete('Xprofile_file.log')
+endfunc
+
+func Test_profile_file_with_cont()
+ let lines = [
+ \ 'echo "hello',
+ \ ' \ world"',
+ \ 'echo "foo ',
+ \ ' \bar"',
+ \ ]
+
+ call writefile(lines, 'Xprofile_file.vim')
+ call system(v:progpath
+ \ . ' -es -u NONE -U NONE -i NONE --noplugin'
+ \ . ' -c "profile start Xprofile_file.log"'
+ \ . ' -c "profile file Xprofile_file.vim"'
+ \ . ' -c "so Xprofile_file.vim"'
+ \ . ' -c "qall!"')
+ call assert_equal(0, v:shell_error)
+
+ let lines = readfile('Xprofile_file.log')
+ call assert_equal(11, len(lines))
+
+ call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0])
+ call assert_equal('Sourced 1 time', lines[1])
+ call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
+ call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
+ call assert_equal('', lines[4])
+ call assert_equal('count total (s) self (s)', lines[5])
+ call assert_match(' 1 0.\d\+ echo "hello', lines[6])
+ call assert_equal(' \ world"', lines[7])
+ call assert_match(' 1 0.\d\+ echo "foo ', lines[8])
+ call assert_equal(' \bar"', lines[9])
+ call assert_equal('', lines[10])
+
+ call delete('Xprofile_file.vim')
+ call delete('Xprofile_file.log')
+endfunc
+
+func Test_profile_completion()
+ call feedkeys(":profile \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"profile continue dump file func pause start stop', @:)
+
+ call feedkeys(":profile start test_prof\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('^"profile start.* test_profile\.vim', @:)
+endfunc
+
+func Test_profile_errors()
+ call assert_fails("profile func Foo", 'E750:')
+ call assert_fails("profile pause", 'E750:')
+ call assert_fails("profile continue", 'E750:')
+endfunc
diff --git a/src/nvim/testdir/test_put.vim b/src/nvim/testdir/test_put.vim
new file mode 100644
index 0000000000..0b8961c52b
--- /dev/null
+++ b/src/nvim/testdir/test_put.vim
@@ -0,0 +1,49 @@
+
+func Test_put_block()
+ if !has('multi_byte')
+ return
+ endif
+ new
+ call feedkeys("i\<C-V>u2500\<CR>x\<ESC>", 'x')
+ call feedkeys("\<C-V>y", 'x')
+ call feedkeys("gg0p", 'x')
+ call assert_equal("\u2500x", getline(1))
+ bwipe!
+endfunc
+
+func Test_put_char_block()
+ new
+ call setline(1, ['Line 1', 'Line 2'])
+ f Xfile_put
+ " visually select both lines and put the cursor at the top of the visual
+ " selection and then put the buffer name over it
+ exe "norm! G0\<c-v>ke\"%p"
+ call assert_equal(['Xfile_put 1', 'Xfile_put 2'], getline(1,2))
+ bw!
+endfunc
+
+func Test_put_char_block2()
+ new
+ let a = [ getreg('a'), getregtype('a') ]
+ call setreg('a', ' one ', 'v')
+ call setline(1, ['Line 1', '', 'Line 3', ''])
+ " visually select the first 3 lines and put register a over it
+ exe "norm! ggl\<c-v>2j2l\"ap"
+ call assert_equal(['L one 1', '', 'L one 3', ''], getline(1,4))
+ " clean up
+ bw!
+ call setreg('a', a[0], a[1])
+endfunc
+
+func Test_put_expr()
+ new
+ call setline(1, repeat(['A'], 6))
+ exec "1norm! \"=line('.')\<cr>p"
+ norm! j0.
+ norm! j0.
+ exec "4norm! \"=\<cr>P"
+ norm! j0.
+ norm! j0.
+ call assert_equal(['A1','A2','A3','4A','5A','6A'], getline(1,'$'))
+ bw!
+endfunc
diff --git a/src/nvim/testdir/test_python2.vim b/src/nvim/testdir/test_python2.vim
new file mode 100644
index 0000000000..5ba9fd68cf
--- /dev/null
+++ b/src/nvim/testdir/test_python2.vim
@@ -0,0 +1,54 @@
+" Test for python 2 commands.
+" TODO: move tests from test87.in here.
+
+if !has('python')
+ finish
+endif
+
+func Test_pydo()
+ " Check deleting lines does not trigger ml_get error.
+ py import vim
+ new
+ call setline(1, ['one', 'two', 'three'])
+ pydo vim.command("%d_")
+ bwipe!
+
+ " Disabled until neovim/neovim#8554 is resolved
+ if 0
+ " Check switching to another buffer does not trigger ml_get error.
+ new
+ let wincount = winnr('$')
+ call setline(1, ['one', 'two', 'three'])
+ pydo vim.command("new")
+ call assert_equal(wincount + 1, winnr('$'))
+ bwipe!
+ bwipe!
+ endif
+endfunc
+
+func Test_vim_function()
+ " Check creating vim.Function object
+ py import vim
+
+ func s:foo()
+ return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
+ endfunc
+ let name = '<SNR>' . s:foo()
+
+ try
+ py f = vim.bindeval('function("s:foo")')
+ call assert_equal(name, pyeval('f.name'))
+ catch
+ call assert_false(v:exception)
+ endtry
+
+ try
+ py f = vim.Function('\x80\xfdR' + vim.eval('s:foo()'))
+ call assert_equal(name, pyeval('f.name'))
+ catch
+ call assert_false(v:exception)
+ endtry
+
+ py del f
+ delfunc s:foo
+endfunc
diff --git a/src/nvim/testdir/test_python3.vim b/src/nvim/testdir/test_python3.vim
new file mode 100644
index 0000000000..2e3fc93674
--- /dev/null
+++ b/src/nvim/testdir/test_python3.vim
@@ -0,0 +1,54 @@
+" Test for python 2 commands.
+" TODO: move tests from test88.in here.
+
+if !has('python3')
+ finish
+endif
+
+func Test_py3do()
+ " Check deleting lines does not trigger an ml_get error.
+ py3 import vim
+ new
+ call setline(1, ['one', 'two', 'three'])
+ py3do vim.command("%d_")
+ bwipe!
+
+ " Disabled until neovim/neovim#8554 is resolved
+ if 0
+ " Check switching to another buffer does not trigger an ml_get error.
+ new
+ let wincount = winnr('$')
+ call setline(1, ['one', 'two', 'three'])
+ py3do vim.command("new")
+ call assert_equal(wincount + 1, winnr('$'))
+ bwipe!
+ bwipe!
+ endif
+endfunc
+
+func Test_vim_function()
+ " Check creating vim.Function object
+ py3 import vim
+
+ func s:foo()
+ return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
+ endfunc
+ let name = '<SNR>' . s:foo()
+
+ try
+ py3 f = vim.bindeval('function("s:foo")')
+ call assert_equal(name, py3eval('f.name'))
+ catch
+ call assert_false(v:exception)
+ endtry
+
+ try
+ py3 f = vim.Function(b'\x80\xfdR' + vim.eval('s:foo()').encode())
+ call assert_equal(name, py3eval('f.name'))
+ catch
+ call assert_false(v:exception)
+ endtry
+
+ py3 del f
+ delfunc s:foo
+endfunc
diff --git a/src/nvim/testdir/test_pyx2.vim b/src/nvim/testdir/test_pyx2.vim
new file mode 100644
index 0000000000..50e57c3bfb
--- /dev/null
+++ b/src/nvim/testdir/test_pyx2.vim
@@ -0,0 +1,74 @@
+" Test for pyx* commands and functions with Python 2.
+
+set pyx=2
+if !has('python')
+ finish
+endif
+
+let s:py2pattern = '^2\.[0-7]\.\d\+'
+let s:py3pattern = '^3\.\d\+\.\d\+'
+
+
+func Test_has_pythonx()
+ call assert_true(has('pythonx'))
+endfunc
+
+
+func Test_pyx()
+ redir => var
+ pyx << EOF
+import sys
+print(sys.version)
+EOF
+ redir END
+ call assert_match(s:py2pattern, split(var)[0])
+endfunc
+
+
+func Test_pyxdo()
+ pyx import sys
+ enew
+ pyxdo return sys.version.split("\n")[0]
+ call assert_match(s:py2pattern, split(getline('.'))[0])
+endfunc
+
+
+func Test_pyxeval()
+ pyx import sys
+ call assert_match(s:py2pattern, split(pyxeval('sys.version'))[0])
+endfunc
+
+
+func Test_pyxfile()
+ " No special comments nor shebangs
+ redir => var
+ pyxfile pyxfile/pyx.py
+ redir END
+ call assert_match(s:py2pattern, split(var)[0])
+
+ " Python 2 special comment
+ redir => var
+ pyxfile pyxfile/py2_magic.py
+ redir END
+ call assert_match(s:py2pattern, split(var)[0])
+
+ " Python 2 shebang
+ redir => var
+ pyxfile pyxfile/py2_shebang.py
+ redir END
+ call assert_match(s:py2pattern, split(var)[0])
+
+ if has('python3')
+ " Python 3 special comment
+ redir => var
+ pyxfile pyxfile/py3_magic.py
+ redir END
+ call assert_match(s:py3pattern, split(var)[0])
+
+ " Python 3 shebang
+ redir => var
+ pyxfile pyxfile/py3_shebang.py
+ redir END
+ call assert_match(s:py3pattern, split(var)[0])
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_pyx3.vim b/src/nvim/testdir/test_pyx3.vim
new file mode 100644
index 0000000000..64546b4688
--- /dev/null
+++ b/src/nvim/testdir/test_pyx3.vim
@@ -0,0 +1,74 @@
+" Test for pyx* commands and functions with Python 3.
+
+set pyx=3
+if !has('python3')
+ finish
+endif
+
+let s:py2pattern = '^2\.[0-7]\.\d\+'
+let s:py3pattern = '^3\.\d\+\.\d\+'
+
+
+func Test_has_pythonx()
+ call assert_true(has('pythonx'))
+endfunc
+
+
+func Test_pyx()
+ redir => var
+ pyx << EOF
+import sys
+print(sys.version)
+EOF
+ redir END
+ call assert_match(s:py3pattern, split(var)[0])
+endfunc
+
+
+func Test_pyxdo()
+ pyx import sys
+ enew
+ pyxdo return sys.version.split("\n")[0]
+ call assert_match(s:py3pattern, split(getline('.'))[0])
+endfunc
+
+
+func Test_pyxeval()
+ pyx import sys
+ call assert_match(s:py3pattern, split(pyxeval('sys.version'))[0])
+endfunc
+
+
+func Test_pyxfile()
+ " No special comments nor shebangs
+ redir => var
+ pyxfile pyxfile/pyx.py
+ redir END
+ call assert_match(s:py3pattern, split(var)[0])
+
+ " Python 3 special comment
+ redir => var
+ pyxfile pyxfile/py3_magic.py
+ redir END
+ call assert_match(s:py3pattern, split(var)[0])
+
+ " Python 3 shebang
+ redir => var
+ pyxfile pyxfile/py3_shebang.py
+ redir END
+ call assert_match(s:py3pattern, split(var)[0])
+
+ if has('python')
+ " Python 2 special comment
+ redir => var
+ pyxfile pyxfile/py2_magic.py
+ redir END
+ call assert_match(s:py2pattern, split(var)[0])
+
+ " Python 2 shebang
+ redir => var
+ pyxfile pyxfile/py2_shebang.py
+ redir END
+ call assert_match(s:py2pattern, split(var)[0])
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim
new file mode 100644
index 0000000000..cb3e7ca8f6
--- /dev/null
+++ b/src/nvim/testdir/test_quickfix.vim
@@ -0,0 +1,2666 @@
+" Test for the quickfix commands.
+
+if !has('quickfix')
+ finish
+endif
+
+set encoding=utf-8
+
+func s:setup_commands(cchar)
+ if a:cchar == 'c'
+ command! -nargs=* -bang Xlist <mods>clist<bang> <args>
+ command! -nargs=* Xgetexpr <mods>cgetexpr <args>
+ command! -nargs=* Xaddexpr <mods>caddexpr <args>
+ command! -nargs=* -count Xolder <mods><count>colder <args>
+ command! -nargs=* Xnewer <mods>cnewer <args>
+ command! -nargs=* Xopen <mods>copen <args>
+ command! -nargs=* Xwindow <mods>cwindow <args>
+ command! -nargs=* Xbottom <mods>cbottom <args>
+ command! -nargs=* Xclose <mods>cclose <args>
+ command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
+ command! -nargs=* Xgetfile <mods>cgetfile <args>
+ command! -nargs=* Xaddfile <mods>caddfile <args>
+ command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
+ command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
+ command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
+ command! -nargs=* Xrewind <mods>crewind <args>
+ command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
+ command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
+ command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
+ command! -nargs=* -bang Xlast <mods>clast<bang> <args>
+ command! -nargs=* -bang Xnfile <mods>cnfile<bang> <args>
+ command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
+ command! -nargs=* Xexpr <mods>cexpr <args>
+ command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
+ command! -nargs=* Xvimgrepadd <mods>vimgrepadd <args>
+ command! -nargs=* Xgrep <mods> grep <args>
+ command! -nargs=* Xgrepadd <mods> grepadd <args>
+ command! -nargs=* Xhelpgrep helpgrep <args>
+ let g:Xgetlist = function('getqflist')
+ let g:Xsetlist = function('setqflist')
+ call setqflist([], 'f')
+ else
+ command! -nargs=* -bang Xlist <mods>llist<bang> <args>
+ command! -nargs=* Xgetexpr <mods>lgetexpr <args>
+ command! -nargs=* Xaddexpr <mods>laddexpr <args>
+ command! -nargs=* -count Xolder <mods><count>lolder <args>
+ command! -nargs=* Xnewer <mods>lnewer <args>
+ command! -nargs=* Xopen <mods>lopen <args>
+ command! -nargs=* Xwindow <mods>lwindow <args>
+ command! -nargs=* Xbottom <mods>lbottom <args>
+ command! -nargs=* Xclose <mods>lclose <args>
+ command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
+ command! -nargs=* Xgetfile <mods>lgetfile <args>
+ command! -nargs=* Xaddfile <mods>laddfile <args>
+ command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
+ command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
+ command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
+ command! -nargs=* Xrewind <mods>lrewind <args>
+ command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
+ command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
+ command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
+ command! -nargs=* -bang Xlast <mods>llast<bang> <args>
+ command! -nargs=* -bang Xnfile <mods>lnfile<bang> <args>
+ command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
+ command! -nargs=* Xexpr <mods>lexpr <args>
+ command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
+ command! -nargs=* Xvimgrepadd <mods>lvimgrepadd <args>
+ command! -nargs=* Xgrep <mods> lgrep <args>
+ command! -nargs=* Xgrepadd <mods> lgrepadd <args>
+ command! -nargs=* Xhelpgrep lhelpgrep <args>
+ let g:Xgetlist = function('getloclist', [0])
+ let g:Xsetlist = function('setloclist', [0])
+ call setloclist(0, [], 'f')
+ endif
+endfunc
+
+" Tests for the :clist and :llist commands
+func XlistTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ if a:cchar == 'l'
+ call assert_fails('llist', 'E776:')
+ endif
+ " With an empty list, command should return error
+ Xgetexpr []
+ silent! Xlist
+ call assert_true(v:errmsg ==# 'E42: No Errors')
+
+ " Populate the list and then try
+ Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
+ \ 'non-error 2', 'Xtestfile2:2:2:Line2',
+ \ 'non-error 3', 'Xtestfile3:3:1:Line3']
+
+ " List only valid entries
+ let l = split(execute('Xlist', ''), "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ " List all the entries
+ let l = split(execute('Xlist!', ''), "\n")
+ call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ " List a range of errors
+ let l = split(execute('Xlist 3,6', ''), "\n")
+ call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ let l = split(execute('Xlist! 3,4', ''), "\n")
+ call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+
+ let l = split(execute('Xlist -6,-4', ''), "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
+
+ let l = split(execute('Xlist! -5,-3', ''), "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+
+ " Test for '+'
+ let l = split(execute('Xlist! +2', ''), "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+
+ " Different types of errors
+ call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
+ \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
+ \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
+ \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
+ \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
+ let l = split(execute('Xlist', ""), "\n")
+ call assert_equal([' 1:10 col 5 warning 11: Warning',
+ \ ' 2:20 col 10 error 22: Error',
+ \ ' 3:30 col 15 info 33: Info',
+ \ ' 4:40 col 20 x 44: Other',
+ \ ' 5:50 col 25 55: one'], l)
+
+ " Error cases
+ call assert_fails('Xlist abc', 'E488:')
+endfunc
+
+func Test_clist()
+ call XlistTests('c')
+ call XlistTests('l')
+endfunc
+
+" Tests for the :colder, :cnewer, :lolder and :lnewer commands
+" Note that this test assumes that a quickfix/location list is
+" already set by the caller.
+func XageTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
+ call g:Xsetlist(list)
+
+ " Jumping to a non existent list should return error
+ silent! Xolder 99
+ call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
+
+ silent! Xnewer 99
+ call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
+
+ " Add three quickfix/location lists
+ Xgetexpr ['Xtestfile1:1:3:Line1']
+ Xgetexpr ['Xtestfile2:2:2:Line2']
+ Xgetexpr ['Xtestfile3:3:1:Line3']
+
+ " Go back two lists
+ Xolder
+ let l = g:Xgetlist()
+ call assert_equal('Line2', l[0].text)
+
+ " Go forward two lists
+ Xnewer
+ let l = g:Xgetlist()
+ call assert_equal('Line3', l[0].text)
+
+ " Test for the optional count argument
+ Xolder 2
+ let l = g:Xgetlist()
+ call assert_equal('Line1', l[0].text)
+
+ Xnewer 2
+ let l = g:Xgetlist()
+ call assert_equal('Line3', l[0].text)
+endfunc
+
+func Test_cage()
+ call XageTests('c')
+ call XageTests('l')
+endfunc
+
+" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
+" commands
+func XwindowTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ " Opening the location list window without any errors should fail
+ if a:cchar == 'l'
+ call assert_fails('lopen', 'E776:')
+ endif
+
+ " Create a list with no valid entries
+ Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
+
+ " Quickfix/Location window should not open with no valid errors
+ Xwindow
+ call assert_true(winnr('$') == 1)
+
+ " Create a list with valid entries
+ Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
+ \ 'Xtestfile3:3:1:Line3']
+
+ " Open the window
+ Xwindow
+ call assert_true(winnr('$') == 2 && winnr() == 2 &&
+ \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
+ redraw!
+
+ " Close the window
+ Xclose
+ call assert_true(winnr('$') == 1)
+
+ " Create a list with no valid entries
+ Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
+
+ " Open the window
+ Xopen 5
+ call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
+ \ && winheight('.') == 5)
+
+ " Opening the window again, should move the cursor to that window
+ wincmd t
+ Xopen 7
+ call assert_true(winnr('$') == 2 && winnr() == 2 &&
+ \ winheight('.') == 7 &&
+ \ getline('.') ==# '|| non-error 1')
+
+
+ " Calling cwindow should close the quickfix window with no valid errors
+ Xwindow
+ call assert_true(winnr('$') == 1)
+
+ if a:cchar == 'c'
+ " Opening the quickfix window in multiple tab pages should reuse the
+ " quickfix buffer
+ Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
+ \ 'Xtestfile3:3:1:Line3']
+ Xopen
+ let qfbufnum = bufnr('%')
+ tabnew
+ Xopen
+ call assert_equal(qfbufnum, bufnr('%'))
+ new | only | tabonly
+ endif
+endfunc
+
+func Test_cwindow()
+ call XwindowTests('c')
+ call XwindowTests('l')
+endfunc
+
+" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
+" commands.
+func XfileTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ call writefile(['Xtestfile1:700:10:Line 700',
+ \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
+
+ enew!
+ Xfile Xqftestfile1
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
+ \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
+
+ " Test with a non existent file
+ call assert_fails('Xfile non_existent_file', 'E40')
+
+ " Run cfile/lfile from a modified buffer
+ enew!
+ silent! put ='Quickfix'
+ silent! Xfile Xqftestfile1
+ call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
+
+ call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
+ Xaddfile Xqftestfile1
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 3 &&
+ \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
+
+ call writefile(['Xtestfile1:222:77:Line 222',
+ \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
+
+ enew!
+ Xgetfile Xqftestfile1
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
+ \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
+
+ call delete('Xqftestfile1')
+endfunc
+
+func Test_cfile()
+ call XfileTests('c')
+ call XfileTests('l')
+endfunc
+
+" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
+" :lgetbuffer commands.
+func XbufferTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ enew!
+ silent! call setline(1, ['Xtestfile7:700:10:Line 700',
+ \ 'Xtestfile8:800:15:Line 800'])
+ Xbuffer!
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
+ \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
+
+ enew!
+ silent! call setline(1, ['Xtestfile9:900:55:Line 900',
+ \ 'Xtestfile10:950:66:Line 950'])
+ Xgetbuffer
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
+ \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
+
+ enew!
+ silent! call setline(1, ['Xtestfile11:700:20:Line 700',
+ \ 'Xtestfile12:750:25:Line 750'])
+ Xaddbuffer
+ let l = g:Xgetlist()
+ call assert_true(len(l) == 4 &&
+ \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
+ \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
+ \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
+ enew!
+
+ " Check for invalid buffer
+ call assert_fails('Xbuffer 199', 'E474:')
+
+ " Check for unloaded buffer
+ edit Xtestfile1
+ let bnr = bufnr('%')
+ enew!
+ call assert_fails('Xbuffer ' . bnr, 'E681:')
+
+ " Check for invalid range
+ " Using Xbuffer will not run the range check in the cbuffer/lbuffer
+ " commands. So directly call the commands.
+ if (a:cchar == 'c')
+ call assert_fails('900,999cbuffer', 'E16:')
+ else
+ call assert_fails('900,999lbuffer', 'E16:')
+ endif
+endfunc
+
+func Test_cbuffer()
+ call XbufferTests('c')
+ call XbufferTests('l')
+endfunc
+
+func XexprTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ call assert_fails('Xexpr 10', 'E777:')
+endfunc
+
+func Test_cexpr()
+ call XexprTests('c')
+ call XexprTests('l')
+endfunc
+
+" Tests for :cnext, :cprev, :cfirst, :clast commands
+func Xtest_browse(cchar)
+ call s:setup_commands(a:cchar)
+
+ " Jumping to first or next location list entry without any error should
+ " result in failure
+ if a:cchar == 'l'
+ call assert_fails('lfirst', 'E776:')
+ call assert_fails('lnext', 'E776:')
+ endif
+
+ call s:create_test_file('Xqftestfile1')
+ call s:create_test_file('Xqftestfile2')
+
+ Xgetexpr ['Xqftestfile1:5:Line5',
+ \ 'Xqftestfile1:6:Line6',
+ \ 'Xqftestfile2:10:Line10',
+ \ 'Xqftestfile2:11:Line11',
+ \ 'RegularLine1',
+ \ 'RegularLine2']
+
+ Xfirst
+ call assert_fails('Xprev', 'E553')
+ call assert_fails('Xpfile', 'E553')
+ Xnfile
+ call assert_equal('Xqftestfile2', bufname('%'))
+ call assert_equal(10, line('.'))
+ Xpfile
+ call assert_equal('Xqftestfile1', bufname('%'))
+ call assert_equal(6, line('.'))
+ Xlast
+ Xprev
+ call assert_equal('Xqftestfile2', bufname('%'))
+ call assert_equal(11, line('.'))
+ call assert_fails('Xnext', 'E553')
+ call assert_fails('Xnfile', 'E553')
+ Xrewind
+ call assert_equal('Xqftestfile1', bufname('%'))
+ call assert_equal(5, line('.'))
+
+ 10Xnext
+ call assert_equal('Xqftestfile2', bufname('%'))
+ call assert_equal(11, line('.'))
+ 10Xprev
+ call assert_equal('Xqftestfile1', bufname('%'))
+ call assert_equal(5, line('.'))
+
+ Xexpr ""
+ call assert_fails('Xnext', 'E42:')
+
+ call delete('Xqftestfile1')
+ call delete('Xqftestfile2')
+endfunc
+
+func Test_browse()
+ call Xtest_browse('c')
+ call Xtest_browse('l')
+endfunc
+
+func s:test_xhelpgrep(cchar)
+ call s:setup_commands(a:cchar)
+ Xhelpgrep quickfix
+ Xopen
+ if a:cchar == 'c'
+ let title_text = ':helpgrep quickfix'
+ else
+ let title_text = ':lhelpgrep quickfix'
+ endif
+ call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
+
+ " Jumping to a help topic should open the help window
+ only
+ Xnext
+ call assert_true(&buftype == 'help')
+ call assert_true(winnr('$') == 2)
+ " Jumping to the next match should reuse the help window
+ Xnext
+ call assert_true(&buftype == 'help')
+ call assert_true(winnr() == 1)
+ call assert_true(winnr('$') == 2)
+ " Jumping to the next match from the quickfix window should reuse the help
+ " window
+ Xopen
+ Xnext
+ call assert_true(&buftype == 'help')
+ call assert_true(winnr() == 1)
+ call assert_true(winnr('$') == 2)
+
+ " This wipes out the buffer, make sure that doesn't cause trouble.
+ Xclose
+
+ new | only
+
+ " Search for non existing help string
+ call assert_fails('Xhelpgrep a1b2c3', 'E480:')
+endfunc
+
+func Test_helpgrep()
+ call s:test_xhelpgrep('c')
+ helpclose
+ call s:test_xhelpgrep('l')
+endfunc
+
+func Test_errortitle()
+ augroup QfBufWinEnter
+ au!
+ au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
+ augroup END
+ copen
+ let a=[{'lnum': 308, 'bufnr': bufnr(''), 'col': 58, 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'pattern': '', 'text': ' au BufWinEnter * :let g:a=get(w:, ''quickfix_title'', ''NONE'')'}]
+ call setqflist(a)
+ call assert_equal(':setqflist()', g:a)
+ augroup QfBufWinEnter
+ au!
+ augroup END
+ augroup! QfBufWinEnter
+endfunc
+
+func Test_vimgreptitle()
+ augroup QfBufWinEnter
+ au!
+ au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
+ augroup END
+ try
+ vimgrep /pattern/j file
+ catch /E480/
+ endtry
+ copen
+ call assert_equal(': vimgrep /pattern/j file', g:a)
+ augroup QfBufWinEnter
+ au!
+ augroup END
+ augroup! QfBufWinEnter
+endfunc
+
+func XqfTitleTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ Xgetexpr ['file:1:1:message']
+ let l = g:Xgetlist()
+ if a:cchar == 'c'
+ call setqflist(l, 'r')
+ else
+ call setloclist(0, l, 'r')
+ endif
+
+ Xopen
+ if a:cchar == 'c'
+ let title = ':setqflist()'
+ else
+ let title = ':setloclist()'
+ endif
+ call assert_equal(title, w:quickfix_title)
+ Xclose
+endfunc
+
+" Tests for quickfix window's title
+func Test_qf_title()
+ call XqfTitleTests('c')
+ call XqfTitleTests('l')
+endfunc
+
+" Tests for 'errorformat'
+func Test_efm()
+ let save_efm = &efm
+ set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
+ cgetexpr ['WWWW', 'EEEE', 'CCCC']
+ let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
+ call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
+ cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
+ let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
+ call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
+ cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
+ let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
+ call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
+ let &efm = save_efm
+endfunc
+
+" This will test for problems in quickfix:
+" A. incorrectly copying location lists which caused the location list to show
+" a different name than the file that was actually being displayed.
+" B. not reusing the window for which the location list window is opened but
+" instead creating new windows.
+" C. make sure that the location list window is not reused instead of the
+" window it belongs to.
+"
+" Set up the test environment:
+func ReadTestProtocol(name)
+ let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
+ let word = substitute(base, '\v(.*)\..*', '\1', '')
+
+ setl modifiable
+ setl noreadonly
+ setl noswapfile
+ setl bufhidden=delete
+ %del _
+ " For problem 2:
+ " 'buftype' has to be set to reproduce the constant opening of new windows
+ setl buftype=nofile
+
+ call setline(1, word)
+
+ setl nomodified
+ setl nomodifiable
+ setl readonly
+ exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
+endfunc
+
+func Test_locationlist()
+ enew
+
+ augroup testgroup
+ au!
+ autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
+ augroup END
+
+ let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
+
+ let qflist = []
+ for word in words
+ call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
+ " NOTE: problem 1:
+ " intentionally not setting 'lnum' so that the quickfix entries are not
+ " valid
+ call setloclist(0, qflist, ' ')
+ endfor
+
+ " Test A
+ lrewind
+ enew
+ lopen
+ 4lnext
+ vert split
+ wincmd L
+ lopen
+ wincmd p
+ lnext
+ let fileName = expand("%")
+ wincmd p
+ let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
+ let fileName = substitute(fileName, '\\', '/', 'g')
+ let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
+ call assert_equal("test://bar.txt", fileName)
+ call assert_equal("test://bar.txt", locationListFileName)
+
+ wincmd n | only
+
+ " Test B:
+ lrewind
+ lopen
+ 2
+ exe "normal \<CR>"
+ wincmd p
+ 3
+ exe "normal \<CR>"
+ wincmd p
+ 4
+ exe "normal \<CR>"
+ call assert_equal(2, winnr('$'))
+ wincmd n | only
+
+ " Test C:
+ lrewind
+ lopen
+ " Let's move the location list window to the top to check whether it (the
+ " first window found) will be reused when we try to open new windows:
+ wincmd K
+ 2
+ exe "normal \<CR>"
+ wincmd p
+ 3
+ exe "normal \<CR>"
+ wincmd p
+ 4
+ exe "normal \<CR>"
+ 1wincmd w
+ call assert_equal('quickfix', &buftype)
+ 2wincmd w
+ let bufferName = expand("%")
+ let bufferName = substitute(bufferName, '\\', '/', 'g')
+ call assert_equal('test://quux.txt', bufferName)
+
+ wincmd n | only
+
+ augroup! testgroup
+endfunc
+
+func Test_locationlist_curwin_was_closed()
+ augroup testgroup
+ au!
+ autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
+ augroup END
+
+ func! R(n)
+ quit
+ endfunc
+
+ new
+ let q = []
+ call add(q, {'filename': 'test_curwin.txt' })
+ call setloclist(0, q)
+ call assert_fails('lrewind', 'E924:')
+
+ augroup! testgroup
+endfunc
+
+func Test_locationlist_cross_tab_jump()
+ call writefile(['loclistfoo'], 'loclistfoo')
+ call writefile(['loclistbar'], 'loclistbar')
+ set switchbuf=usetab
+
+ edit loclistfoo
+ tabedit loclistbar
+ silent lgrep loclistfoo loclist*
+ call assert_equal(1, tabpagenr())
+
+ enew | only | tabonly
+ set switchbuf&vim
+ call delete('loclistfoo')
+ call delete('loclistbar')
+endfunc
+
+" More tests for 'errorformat'
+func Test_efm1()
+ if !has('unix')
+ " The 'errorformat' setting is different on non-Unix systems.
+ " This test works only on Unix-like systems.
+ return
+ endif
+
+ let l = [
+ \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.',
+ \ '"Xtestfile", line 6 col 19; this is an error',
+ \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c',
+ \ 'Xtestfile:9: parse error before `asd''',
+ \ 'make: *** [vim] Error 1',
+ \ 'in file "Xtestfile" linenr 10: there is an error',
+ \ '',
+ \ '2 returned',
+ \ '"Xtestfile", line 11 col 1; this is an error',
+ \ '"Xtestfile", line 12 col 2; this is another error',
+ \ '"Xtestfile", line 14:10; this is an error in column 10',
+ \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time',
+ \ '"Xtestfile", linenr 16: yet another problem',
+ \ 'Error in "Xtestfile" at line 17:',
+ \ 'x should be a dot',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17',
+ \ ' ^',
+ \ 'Error in "Xtestfile" at line 18:',
+ \ 'x should be a dot',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18',
+ \ '.............^',
+ \ 'Error in "Xtestfile" at line 19:',
+ \ 'x should be a dot',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19',
+ \ '--------------^',
+ \ 'Error in "Xtestfile" at line 20:',
+ \ 'x should be a dot',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20',
+ \ ' ^',
+ \ '',
+ \ 'Does anyone know what is the problem and how to correction it?',
+ \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?',
+ \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?'
+ \ ]
+
+ call writefile(l, 'Xerrorfile1')
+ call writefile(l[:-2], 'Xerrorfile2')
+
+ let m = [
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21',
+ \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22'
+ \ ]
+ call writefile(m, 'Xtestfile')
+
+ let save_efm = &efm
+ set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
+ set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
+
+ exe 'cf Xerrorfile2'
+ clast
+ copen
+ call assert_equal(':cf Xerrorfile2', w:quickfix_title)
+ wincmd p
+
+ exe 'cf Xerrorfile1'
+ call assert_equal([4, 12], [line('.'), col('.')])
+ cn
+ call assert_equal([6, 19], [line('.'), col('.')])
+ cn
+ call assert_equal([9, 2], [line('.'), col('.')])
+ cn
+ call assert_equal([10, 2], [line('.'), col('.')])
+ cn
+ call assert_equal([11, 1], [line('.'), col('.')])
+ cn
+ call assert_equal([12, 2], [line('.'), col('.')])
+ cn
+ call assert_equal([14, 10], [line('.'), col('.')])
+ cn
+ call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
+ cn
+ call assert_equal([16, 2], [line('.'), col('.')])
+ cn
+ call assert_equal([17, 6], [line('.'), col('.')])
+ cn
+ call assert_equal([18, 7], [line('.'), col('.')])
+ cn
+ call assert_equal([19, 8], [line('.'), col('.')])
+ cn
+ call assert_equal([20, 9], [line('.'), col('.')])
+ clast
+ cprev
+ cprev
+ wincmd w
+ call assert_equal(':cf Xerrorfile1', w:quickfix_title)
+ wincmd p
+
+ let &efm = save_efm
+ call delete('Xerrorfile1')
+ call delete('Xerrorfile2')
+ call delete('Xtestfile')
+endfunc
+
+" Test for quickfix directory stack support
+func s:dir_stack_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ let save_efm=&efm
+ set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
+
+ let lines = ["Entering dir 'dir1/a'",
+ \ 'habits2.txt:1:Nine Healthy Habits',
+ \ "Entering dir 'b'",
+ \ 'habits3.txt:2:0 Hours of television',
+ \ 'habits2.txt:7:5 Small meals',
+ \ "Entering dir 'dir1/c'",
+ \ 'habits4.txt:3:1 Hour of exercise',
+ \ "Leaving dir 'dir1/c'",
+ \ "Leaving dir 'dir1/a'",
+ \ 'habits1.txt:4:2 Liters of water',
+ \ "Entering dir 'dir2'",
+ \ 'habits5.txt:5:3 Cups of hot green tea',
+ \ "Leaving dir 'dir2'"
+ \]
+
+ Xexpr ""
+ for l in lines
+ Xaddexpr l
+ endfor
+
+ let qf = g:Xgetlist()
+
+ call assert_equal(expand('dir1/a/habits2.txt'), bufname(qf[1].bufnr))
+ call assert_equal(1, qf[1].lnum)
+ call assert_equal(expand('dir1/a/b/habits3.txt'), bufname(qf[3].bufnr))
+ call assert_equal(2, qf[3].lnum)
+ call assert_equal(expand('dir1/a/habits2.txt'), bufname(qf[4].bufnr))
+ call assert_equal(7, qf[4].lnum)
+ call assert_equal(expand('dir1/c/habits4.txt'), bufname(qf[6].bufnr))
+ call assert_equal(3, qf[6].lnum)
+ call assert_equal('habits1.txt', bufname(qf[9].bufnr))
+ call assert_equal(4, qf[9].lnum)
+ call assert_equal(expand('dir2/habits5.txt'), bufname(qf[11].bufnr))
+ call assert_equal(5, qf[11].lnum)
+
+ let &efm=save_efm
+endfunc
+
+" Tests for %D and %X errorformat options
+func Test_efm_dirstack()
+ " Create the directory stack and files
+ call mkdir('dir1')
+ call mkdir('dir1/a')
+ call mkdir('dir1/a/b')
+ call mkdir('dir1/c')
+ call mkdir('dir2')
+
+ let lines = ["Nine Healthy Habits",
+ \ "0 Hours of television",
+ \ "1 Hour of exercise",
+ \ "2 Liters of water",
+ \ "3 Cups of hot green tea",
+ \ "4 Short mental breaks",
+ \ "5 Small meals",
+ \ "6 AM wake up time",
+ \ "7 Minutes of laughter",
+ \ "8 Hours of sleep (at least)",
+ \ "9 PM end of the day and off to bed"
+ \ ]
+ call writefile(lines, 'habits1.txt')
+ call writefile(lines, 'dir1/a/habits2.txt')
+ call writefile(lines, 'dir1/a/b/habits3.txt')
+ call writefile(lines, 'dir1/c/habits4.txt')
+ call writefile(lines, 'dir2/habits5.txt')
+
+ call s:dir_stack_tests('c')
+ call s:dir_stack_tests('l')
+
+ call delete('dir1', 'rf')
+ call delete('dir2', 'rf')
+ call delete('habits1.txt')
+endfunc
+
+" Test for resync after continuing an ignored message
+func Xefm_ignore_continuations(cchar)
+ call s:setup_commands(a:cchar)
+
+ let save_efm = &efm
+
+ let &efm =
+ \ '%Eerror %m %l,' .
+ \ '%-Wignored %m %l,' .
+ \ '%+Cmore ignored %m %l,' .
+ \ '%Zignored end'
+ Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
+ let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
+ call assert_equal([['resync', 1, 4, 'E']], l)
+
+ let &efm = save_efm
+endfunc
+
+func Test_efm_ignore_continuations()
+ call Xefm_ignore_continuations('c')
+ call Xefm_ignore_continuations('l')
+endfunc
+
+" Tests for invalid error format specifies
+func Xinvalid_efm_Tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ let save_efm = &efm
+
+ set efm=%f:%l:%m,%f:%f:%l:%m
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
+
+ set efm=%f:%l:%m,%f:%l:%r:%m
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
+
+ set efm=%f:%l:%m,%O:%f:%l:%m
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
+
+ set efm=%f:%l:%m,%f:%l:%*[^a-z
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
+
+ set efm=%f:%l:%m,%f:%l:%*c
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
+
+ set efm=%f:%l:%m,%L%M%N
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
+
+ set efm=%f:%l:%m,%f:%l:%m:%R
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
+
+ set efm=
+ call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
+
+ set efm=%DEntering\ dir\ abc,%f:%l:%m
+ call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
+
+ let &efm = save_efm
+endfunc
+
+func Test_invalid_efm()
+ call Xinvalid_efm_Tests('c')
+ call Xinvalid_efm_Tests('l')
+endfunc
+
+" TODO:
+" Add tests for the following formats in 'errorformat'
+" %r %O
+func Test_efm2()
+ let save_efm = &efm
+
+ " Test for %s format in efm
+ set efm=%f:%s
+ cexpr 'Xtestfile:Line search text'
+ let l = getqflist()
+ call assert_equal(l[0].pattern, '^\VLine search text\$')
+ call assert_equal(l[0].lnum, 0)
+
+ let l = split(execute('clist', ''), "\n")
+ call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
+
+ " Test for %P, %Q and %t format specifiers
+ let lines=["[Xtestfile1]",
+ \ "(1,17) error: ';' missing",
+ \ "(21,2) warning: variable 'z' not defined",
+ \ "(67,3) error: end of file found before string ended",
+ \ "--",
+ \ "",
+ \ "[Xtestfile2]",
+ \ "--",
+ \ "",
+ \ "[Xtestfile3]",
+ \ "NEW compiler v1.1",
+ \ "(2,2) warning: variable 'x' not defined",
+ \ "(67,3) warning: 's' already defined",
+ \ "--"
+ \]
+ set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
+ " To exercise the push/pop file functionality in quickfix, the test files
+ " need to be created.
+ call writefile(['Line1'], 'Xtestfile1')
+ call writefile(['Line2'], 'Xtestfile2')
+ call writefile(['Line3'], 'Xtestfile3')
+ cexpr ""
+ for l in lines
+ caddexpr l
+ endfor
+ let l = getqflist()
+ call assert_equal(12, len(l))
+ call assert_equal(21, l[2].lnum)
+ call assert_equal(2, l[2].col)
+ call assert_equal('w', l[2].type)
+ call assert_equal('e', l[3].type)
+ call delete('Xtestfile1')
+ call delete('Xtestfile2')
+ call delete('Xtestfile3')
+
+ " Tests for %E, %C and %Z format specifiers
+ let lines = ["Error 275",
+ \ "line 42",
+ \ "column 3",
+ \ "' ' expected after '--'"
+ \]
+ set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
+ cgetexpr lines
+ let l = getqflist()
+ call assert_equal(275, l[0].nr)
+ call assert_equal(42, l[0].lnum)
+ call assert_equal(3, l[0].col)
+ call assert_equal('E', l[0].type)
+ call assert_equal("\n' ' expected after '--'", l[0].text)
+
+ " Test for %>
+ let lines = ["Error in line 147 of foo.c:",
+ \"unknown variable 'i'"
+ \]
+ set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
+ cgetexpr lines
+ let l = getqflist()
+ call assert_equal(147, l[0].lnum)
+ call assert_equal('E', l[0].type)
+ call assert_equal("\nunknown variable 'i'", l[0].text)
+
+ " Test for %A, %C and other formats
+ let lines = [
+ \"==============================================================",
+ \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
+ \"--------------------------------------------------------------",
+ \"Traceback (most recent call last):",
+ \' File "unittests/dbfacadeTest.py", line 89, in testFoo',
+ \" self.assertEquals(34, dtid)",
+ \' File "/usr/lib/python2.2/unittest.py", line 286, in',
+ \" failUnlessEqual",
+ \" raise self.failureException, \\",
+ \"AssertionError: 34 != 33",
+ \"",
+ \"--------------------------------------------------------------",
+ \"Ran 27 tests in 0.063s"
+ \]
+ set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
+ cgetexpr lines
+ let l = getqflist()
+ call assert_equal(8, len(l))
+ call assert_equal(89, l[4].lnum)
+ call assert_equal(1, l[4].valid)
+ call assert_equal(expand('unittests/dbfacadeTest.py'), bufname(l[4].bufnr))
+
+ " The following sequence of commands used to crash Vim
+ set efm=%W%m
+ cgetexpr ['msg1']
+ let l = getqflist()
+ call assert_equal(1, len(l), string(l))
+ call assert_equal('msg1', l[0].text)
+ set efm=%C%m
+ lexpr 'msg2'
+ let l = getloclist(0)
+ call assert_equal(1, len(l), string(l))
+ call assert_equal('msg2', l[0].text)
+ lopen
+ call setqflist([], 'r')
+ caddbuf
+ let l = getqflist()
+ call assert_equal(1, len(l), string(l))
+ call assert_equal('|| msg2', l[0].text)
+
+ new | only
+ let &efm = save_efm
+endfunc
+
+func XquickfixChangedByAutocmd(cchar)
+ call s:setup_commands(a:cchar)
+ if a:cchar == 'c'
+ let ErrorNr = 'E925'
+ func! ReadFunc()
+ colder
+ cgetexpr []
+ endfunc
+ else
+ let ErrorNr = 'E926'
+ func! ReadFunc()
+ lolder
+ lgetexpr []
+ endfunc
+ endif
+
+ augroup testgroup
+ au!
+ autocmd BufReadCmd test_changed.txt call ReadFunc()
+ augroup END
+
+ new | only
+ let words = [ "a", "b" ]
+ let qflist = []
+ for word in words
+ call add(qflist, {'filename': 'test_changed.txt'})
+ call g:Xsetlist(qflist, ' ')
+ endfor
+ call assert_fails('Xrewind', ErrorNr . ':')
+
+ augroup! testgroup
+endfunc
+
+func Test_quickfix_was_changed_by_autocmd()
+ call XquickfixChangedByAutocmd('c')
+ call XquickfixChangedByAutocmd('l')
+endfunc
+
+func Test_caddbuffer_to_empty()
+ helpgr quickfix
+ call setqflist([], 'r')
+ cad
+ try
+ cn
+ catch
+ " number of matches is unknown
+ call assert_true(v:exception =~ 'E553:')
+ endtry
+ quit!
+endfunc
+
+func Test_cgetexpr_works()
+ " this must not crash Vim
+ cgetexpr [$x]
+ lgetexpr [$x]
+endfunc
+
+" Tests for the setqflist() and setloclist() functions
+func SetXlistTests(cchar, bnum)
+ call s:setup_commands(a:cchar)
+
+ call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
+ \ {'bufnr': a:bnum, 'lnum': 2}])
+ let l = g:Xgetlist()
+ call assert_equal(2, len(l))
+ call assert_equal(2, l[1].lnum)
+
+ Xnext
+ call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
+ let l = g:Xgetlist()
+ call assert_equal(3, len(l))
+ Xnext
+ call assert_equal(3, line('.'))
+
+ " Appending entries to the list should not change the cursor position
+ " in the quickfix window
+ Xwindow
+ 1
+ call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
+ \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
+ call assert_equal(1, line('.'))
+ close
+
+ call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
+ \ {'bufnr': a:bnum, 'lnum': 4},
+ \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
+ let l = g:Xgetlist()
+ call assert_equal(3, len(l))
+ call assert_equal(5, l[2].lnum)
+
+ call g:Xsetlist([])
+ let l = g:Xgetlist()
+ call assert_equal(0, len(l))
+
+ " Tests for setting the 'valid' flag
+ call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
+ Xwindow
+ call assert_equal(1, winnr('$'))
+ let l = g:Xgetlist()
+ call g:Xsetlist(l)
+ call assert_equal(0, g:Xgetlist()[0].valid)
+ call g:Xsetlist([{'text':'Text1', 'valid':1}])
+ Xwindow
+ call assert_equal(2, winnr('$'))
+ Xclose
+ let save_efm = &efm
+ set efm=%m
+ Xgetexpr 'TestMessage'
+ let l = g:Xgetlist()
+ call g:Xsetlist(l)
+ call assert_equal(1, g:Xgetlist()[0].valid)
+ let &efm = save_efm
+
+ " Error cases:
+ " Refer to a non-existing buffer and pass a non-dictionary type
+ call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
+ \ " {'bufnr':999, 'lnum':5}])", 'E92:')
+ call g:Xsetlist([[1, 2,3]])
+ call assert_equal(0, len(g:Xgetlist()))
+endfunc
+
+func Test_setqflist()
+ new Xtestfile | only
+ let bnum = bufnr('%')
+ call setline(1, range(1,5))
+
+ call SetXlistTests('c', bnum)
+ call SetXlistTests('l', bnum)
+
+ enew!
+ call delete('Xtestfile')
+endfunc
+
+func Xlist_empty_middle(cchar)
+ call s:setup_commands(a:cchar)
+
+ " create three quickfix lists
+ let @/ = 'Test_'
+ Xvimgrep // test_quickfix.vim
+ let testlen = len(g:Xgetlist())
+ call assert_true(testlen > 0)
+ Xvimgrep empty test_quickfix.vim
+ call assert_true(len(g:Xgetlist()) > 0)
+ Xvimgrep matches test_quickfix.vim
+ let matchlen = len(g:Xgetlist())
+ call assert_true(matchlen > 0)
+ Xolder
+ " make the middle list empty
+ call g:Xsetlist([], 'r')
+ call assert_true(len(g:Xgetlist()) == 0)
+ Xolder
+ call assert_equal(testlen, len(g:Xgetlist()))
+ Xnewer
+ Xnewer
+ call assert_equal(matchlen, len(g:Xgetlist()))
+endfunc
+
+func Test_setqflist_empty_middle()
+ call Xlist_empty_middle('c')
+ call Xlist_empty_middle('l')
+endfunc
+
+func Xlist_empty_older(cchar)
+ call s:setup_commands(a:cchar)
+
+ " create three quickfix lists
+ Xvimgrep one test_quickfix.vim
+ let onelen = len(g:Xgetlist())
+ call assert_true(onelen > 0)
+ Xvimgrep two test_quickfix.vim
+ let twolen = len(g:Xgetlist())
+ call assert_true(twolen > 0)
+ Xvimgrep three test_quickfix.vim
+ let threelen = len(g:Xgetlist())
+ call assert_true(threelen > 0)
+ Xolder 2
+ " make the first list empty, check the others didn't change
+ call g:Xsetlist([], 'r')
+ call assert_true(len(g:Xgetlist()) == 0)
+ Xnewer
+ call assert_equal(twolen, len(g:Xgetlist()))
+ Xnewer
+ call assert_equal(threelen, len(g:Xgetlist()))
+endfunc
+
+func Test_setqflist_empty_older()
+ call Xlist_empty_older('c')
+ call Xlist_empty_older('l')
+endfunc
+
+func XquickfixSetListWithAct(cchar)
+ call s:setup_commands(a:cchar)
+
+ let list1 = [{'filename': 'fnameA', 'text': 'A'},
+ \ {'filename': 'fnameB', 'text': 'B'}]
+ let list2 = [{'filename': 'fnameC', 'text': 'C'},
+ \ {'filename': 'fnameD', 'text': 'D'},
+ \ {'filename': 'fnameE', 'text': 'E'}]
+
+ " {action} is unspecified. Same as specifing ' '.
+ new | only
+ silent! Xnewer 99
+ call g:Xsetlist(list1)
+ call g:Xsetlist(list2)
+ let li = g:Xgetlist()
+ call assert_equal(3, len(li))
+ call assert_equal('C', li[0]['text'])
+ call assert_equal('D', li[1]['text'])
+ call assert_equal('E', li[2]['text'])
+ silent! Xolder
+ let li = g:Xgetlist()
+ call assert_equal(2, len(li))
+ call assert_equal('A', li[0]['text'])
+ call assert_equal('B', li[1]['text'])
+
+ " {action} is specified ' '.
+ new | only
+ silent! Xnewer 99
+ call g:Xsetlist(list1)
+ call g:Xsetlist(list2, ' ')
+ let li = g:Xgetlist()
+ call assert_equal(3, len(li))
+ call assert_equal('C', li[0]['text'])
+ call assert_equal('D', li[1]['text'])
+ call assert_equal('E', li[2]['text'])
+ silent! Xolder
+ let li = g:Xgetlist()
+ call assert_equal(2, len(li))
+ call assert_equal('A', li[0]['text'])
+ call assert_equal('B', li[1]['text'])
+
+ " {action} is specified 'a'.
+ new | only
+ silent! Xnewer 99
+ call g:Xsetlist(list1)
+ call g:Xsetlist(list2, 'a')
+ let li = g:Xgetlist()
+ call assert_equal(5, len(li))
+ call assert_equal('A', li[0]['text'])
+ call assert_equal('B', li[1]['text'])
+ call assert_equal('C', li[2]['text'])
+ call assert_equal('D', li[3]['text'])
+ call assert_equal('E', li[4]['text'])
+
+ " {action} is specified 'r'.
+ new | only
+ silent! Xnewer 99
+ call g:Xsetlist(list1)
+ call g:Xsetlist(list2, 'r')
+ let li = g:Xgetlist()
+ call assert_equal(3, len(li))
+ call assert_equal('C', li[0]['text'])
+ call assert_equal('D', li[1]['text'])
+ call assert_equal('E', li[2]['text'])
+
+ " Test for wrong value.
+ new | only
+ call assert_fails("call g:Xsetlist(0)", 'E714:')
+ call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
+ call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
+ call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
+ call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
+endfunc
+
+func Test_quickfix_set_list_with_act()
+ call XquickfixSetListWithAct('c')
+ call XquickfixSetListWithAct('l')
+endfunc
+
+func XLongLinesTests(cchar)
+ let l = g:Xgetlist()
+
+ call assert_equal(4, len(l))
+ call assert_equal(1, l[0].lnum)
+ call assert_equal(1, l[0].col)
+ call assert_equal(1975, len(l[0].text))
+ call assert_equal(2, l[1].lnum)
+ call assert_equal(1, l[1].col)
+ call assert_equal(4070, len(l[1].text))
+ call assert_equal(3, l[2].lnum)
+ call assert_equal(1, l[2].col)
+ call assert_equal(4070, len(l[2].text))
+ call assert_equal(4, l[3].lnum)
+ call assert_equal(1, l[3].col)
+ call assert_equal(10, len(l[3].text))
+
+ call g:Xsetlist([], 'r')
+endfunc
+
+func s:long_lines_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ let testfile = 'samples/quickfix.txt'
+
+ " file
+ exe 'Xgetfile' testfile
+ call XLongLinesTests(a:cchar)
+
+ " list
+ Xexpr readfile(testfile)
+ call XLongLinesTests(a:cchar)
+
+ " string
+ Xexpr join(readfile(testfile), "\n")
+ call XLongLinesTests(a:cchar)
+
+ " buffer
+ exe 'edit' testfile
+ exe 'Xbuffer' bufnr('%')
+ call XLongLinesTests(a:cchar)
+endfunc
+
+func Test_long_lines()
+ call s:long_lines_tests('c')
+ call s:long_lines_tests('l')
+endfunc
+
+func s:create_test_file(filename)
+ let l = []
+ for i in range(1, 20)
+ call add(l, 'Line' . i)
+ endfor
+ call writefile(l, a:filename)
+endfunc
+
+func Test_switchbuf()
+ call s:create_test_file('Xqftestfile1')
+ call s:create_test_file('Xqftestfile2')
+ call s:create_test_file('Xqftestfile3')
+
+ new | only
+ edit Xqftestfile1
+ let file1_winid = win_getid()
+ new Xqftestfile2
+ let file2_winid = win_getid()
+ cgetexpr ['Xqftestfile1:5:Line5',
+ \ 'Xqftestfile1:6:Line6',
+ \ 'Xqftestfile2:10:Line10',
+ \ 'Xqftestfile2:11:Line11',
+ \ 'Xqftestfile3:15:Line15',
+ \ 'Xqftestfile3:16:Line16']
+
+ new
+ let winid = win_getid()
+ cfirst | cnext
+ call assert_equal(winid, win_getid())
+ 2cnext
+ call assert_equal(winid, win_getid())
+ 2cnext
+ call assert_equal(winid, win_getid())
+ enew
+
+ set switchbuf=useopen
+ cfirst | cnext
+ call assert_equal(file1_winid, win_getid())
+ 2cnext
+ call assert_equal(file2_winid, win_getid())
+ 2cnext
+ call assert_equal(file2_winid, win_getid())
+
+ enew | only
+ set switchbuf=usetab
+ tabedit Xqftestfile1
+ tabedit Xqftestfile2
+ tabfirst
+ cfirst | cnext
+ call assert_equal(2, tabpagenr())
+ 2cnext
+ call assert_equal(3, tabpagenr())
+ 2cnext
+ call assert_equal(3, tabpagenr())
+ tabfirst | tabonly | enew
+
+ set switchbuf=split
+ cfirst | cnext
+ call assert_equal(1, winnr('$'))
+ cnext | cnext
+ call assert_equal(2, winnr('$'))
+ cnext | cnext
+ call assert_equal(3, winnr('$'))
+ enew | only
+
+ set switchbuf=newtab
+ cfirst | cnext
+ call assert_equal(1, tabpagenr('$'))
+ cnext | cnext
+ call assert_equal(2, tabpagenr('$'))
+ cnext | cnext
+ call assert_equal(3, tabpagenr('$'))
+ tabfirst | enew | tabonly | only
+
+ set switchbuf=
+ edit Xqftestfile1
+ let file1_winid = win_getid()
+ new Xqftestfile2
+ let file2_winid = win_getid()
+ copen
+ exe "normal 1G\<CR>"
+ call assert_equal(file1_winid, win_getid())
+ copen
+ exe "normal 3G\<CR>"
+ call assert_equal(file2_winid, win_getid())
+ copen | only
+ exe "normal 5G\<CR>"
+ call assert_equal(2, winnr('$'))
+ call assert_equal(1, bufwinnr('Xqftestfile3'))
+
+ " If only quickfix window is open in the current tabpage, jumping to an
+ " entry with 'switchubf' set to 'usetab' should search in other tabpages.
+ enew | only
+ set switchbuf=usetab
+ tabedit Xqftestfile1
+ tabedit Xqftestfile2
+ tabedit Xqftestfile3
+ tabfirst
+ copen | only
+ clast
+ call assert_equal(4, tabpagenr())
+ tabfirst | tabonly | enew | only
+
+ call delete('Xqftestfile1')
+ call delete('Xqftestfile2')
+ call delete('Xqftestfile3')
+ set switchbuf&vim
+
+ enew | only
+endfunc
+
+func Xadjust_qflnum(cchar)
+ call s:setup_commands(a:cchar)
+
+ enew | only
+
+ let fname = 'Xqftestfile' . a:cchar
+ call s:create_test_file(fname)
+ exe 'edit ' . fname
+
+ Xgetexpr [fname . ':5:Line5',
+ \ fname . ':10:Line10',
+ \ fname . ':15:Line15',
+ \ fname . ':20:Line20']
+
+ 6,14delete
+ call append(6, ['Buffer', 'Window'])
+
+ let l = g:Xgetlist()
+
+ call assert_equal(5, l[0].lnum)
+ call assert_equal(6, l[2].lnum)
+ call assert_equal(13, l[3].lnum)
+
+ enew!
+ call delete(fname)
+endfunc
+
+func Test_adjust_lnum()
+ call setloclist(0, [])
+ call Xadjust_qflnum('c')
+ call setqflist([])
+ call Xadjust_qflnum('l')
+endfunc
+
+" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
+func s:test_xgrep(cchar)
+ call s:setup_commands(a:cchar)
+
+ " The following lines are used for the grep test. Don't remove.
+ " Grep_Test_Text: Match 1
+ " Grep_Test_Text: Match 2
+ " GrepAdd_Test_Text: Match 1
+ " GrepAdd_Test_Text: Match 2
+ enew! | only
+ set makeef&vim
+ silent Xgrep Grep_Test_Text: test_quickfix.vim
+ call assert_true(len(g:Xgetlist()) == 3)
+ Xopen
+ call assert_true(w:quickfix_title =~ '^:grep')
+ Xclose
+ enew
+ set makeef=Temp_File_##
+ silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
+ call assert_true(len(g:Xgetlist()) == 6)
+endfunc
+
+func Test_grep()
+ if !has('unix')
+ " The grepprg may not be set on non-Unix systems
+ return
+ endif
+
+ call s:test_xgrep('c')
+ call s:test_xgrep('l')
+endfunc
+
+func Test_two_windows()
+ " Use one 'errorformat' for two windows. Add an expression to each of them,
+ " make sure they each keep their own state.
+ set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
+ call mkdir('Xone/a', 'p')
+ call mkdir('Xtwo/a', 'p')
+ let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
+ call writefile(lines, 'Xone/a/one.txt')
+ call writefile(lines, 'Xtwo/a/two.txt')
+
+ new one
+ let one_id = win_getid()
+ lexpr ""
+ new two
+ let two_id = win_getid()
+ lexpr ""
+
+ laddexpr "Entering dir 'Xtwo/a'"
+ call win_gotoid(one_id)
+ laddexpr "Entering dir 'Xone/a'"
+ call win_gotoid(two_id)
+ laddexpr 'two.txt:5:two two two'
+ call win_gotoid(one_id)
+ laddexpr 'one.txt:3:one one one'
+
+ let loc_one = getloclist(one_id)
+ call assert_equal(expand('Xone/a/one.txt'), bufname(loc_one[1].bufnr))
+ call assert_equal(3, loc_one[1].lnum)
+
+ let loc_two = getloclist(two_id)
+ call assert_equal(expand('Xtwo/a/two.txt'), bufname(loc_two[1].bufnr))
+ call assert_equal(5, loc_two[1].lnum)
+
+ call win_gotoid(one_id)
+ bwipe!
+ call win_gotoid(two_id)
+ bwipe!
+ call delete('Xone', 'rf')
+ call delete('Xtwo', 'rf')
+endfunc
+
+func XbottomTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ " Calling lbottom without any errors should fail
+ if a:cchar == 'l'
+ call assert_fails('lbottom', 'E776:')
+ endif
+
+ call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
+ Xopen
+ let wid = win_getid()
+ call assert_equal(1, line('.'))
+ wincmd w
+ call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
+ Xbottom
+ call win_gotoid(wid)
+ call assert_equal(2, line('.'))
+ Xclose
+endfunc
+
+" Tests for the :cbottom and :lbottom commands
+func Test_cbottom()
+ call XbottomTests('c')
+ call XbottomTests('l')
+endfunc
+
+func HistoryTest(cchar)
+ call s:setup_commands(a:cchar)
+
+ " clear all lists after the first one, then replace the first one.
+ call g:Xsetlist([])
+ call assert_fails('Xolder 99', 'E380:')
+ let entry = {'filename': 'foo', 'lnum': 42}
+ call g:Xsetlist([entry], 'r')
+ call g:Xsetlist([entry, entry])
+ call g:Xsetlist([entry, entry, entry])
+ let res = split(execute(a:cchar . 'hist'), "\n")
+ call assert_equal(3, len(res))
+ let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
+ call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
+ call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
+ call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
+endfunc
+
+func Test_history()
+ call HistoryTest('c')
+ call HistoryTest('l')
+endfunc
+
+func Test_duplicate_buf()
+ " make sure we can get the highest buffer number
+ edit DoesNotExist
+ edit DoesNotExist2
+ let last_buffer = bufnr("$")
+
+ " make sure only one buffer is created
+ call writefile(['this one', 'that one'], 'Xgrepthis')
+ vimgrep one Xgrepthis
+ vimgrep one Xgrepthis
+ call assert_equal(last_buffer + 1, bufnr("$"))
+
+ call delete('Xgrepthis')
+endfunc
+
+" Quickfix/Location list set/get properties tests
+func Xproperty_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ " Error cases
+ call assert_fails('call g:Xgetlist(99)', 'E715:')
+ call assert_fails('call g:Xsetlist(99)', 'E714:')
+ call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
+
+ " Set and get the title
+ call g:Xsetlist([])
+ Xopen
+ wincmd p
+ call g:Xsetlist([{'filename':'foo', 'lnum':27}])
+ let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
+ call assert_equal(0, s)
+ let d = g:Xgetlist({"title":1})
+ call assert_equal('Sample', d.title)
+
+ Xopen
+ call assert_equal('Sample', w:quickfix_title)
+ Xclose
+
+ " Tests for action argument
+ silent! Xolder 999
+ let qfnr = g:Xgetlist({'all':1}).nr
+ call g:Xsetlist([], 'r', {'title' : 'N1'})
+ call assert_equal('N1', g:Xgetlist({'all':1}).title)
+ call g:Xsetlist([], ' ', {'title' : 'N2'})
+ call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
+
+ let res = g:Xgetlist({'nr': 0})
+ call assert_equal(qfnr + 1, res.nr)
+ call assert_equal(['nr'], keys(res))
+
+ call g:Xsetlist([], ' ', {'title' : 'N3'})
+ call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
+
+ " Changing the title of an earlier quickfix list
+ call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
+ call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
+
+ " Changing the title of an invalid quickfix list
+ call assert_equal(-1, g:Xsetlist([], ' ',
+ \ {'title' : 'SomeTitle', 'nr' : 99}))
+ call assert_equal(-1, g:Xsetlist([], ' ',
+ \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
+
+ if a:cchar == 'c'
+ copen
+ call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
+ cclose
+ endif
+
+ " Invalid arguments
+ call assert_fails('call g:Xgetlist([])', 'E715')
+ call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
+ let s = g:Xsetlist([], 'a', {'abc':1})
+ call assert_equal(-1, s)
+
+ call assert_equal({}, g:Xgetlist({'abc':1}))
+ call assert_equal({}, g:Xgetlist({'nr':99, 'title':1}))
+ call assert_equal({}, g:Xgetlist({'nr':[], 'title':1}))
+
+ if a:cchar == 'l'
+ call assert_equal({}, getloclist(99, {'title': 1}))
+ endif
+
+ " Context related tests
+ let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
+ call assert_equal(0, s)
+ call test_garbagecollect_now()
+ let d = g:Xgetlist({'context':1})
+ call assert_equal([1,2,3], d.context)
+ call g:Xsetlist([], 'a', {'context':{'color':'green'}})
+ let d = g:Xgetlist({'context':1})
+ call assert_equal({'color':'green'}, d.context)
+ call g:Xsetlist([], 'a', {'context':"Context info"})
+ let d = g:Xgetlist({'context':1})
+ call assert_equal("Context info", d.context)
+ call g:Xsetlist([], 'a', {'context':246})
+ let d = g:Xgetlist({'context':1})
+ call assert_equal(246, d.context)
+ if a:cchar == 'l'
+ " Test for copying context across two different location lists
+ new | only
+ let w1_id = win_getid()
+ let l = [1]
+ call setloclist(0, [], 'a', {'context':l})
+ new
+ let w2_id = win_getid()
+ call add(l, 2)
+ call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
+ call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
+ unlet! l
+ call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
+ only
+ call setloclist(0, [], 'f')
+ call assert_equal({}, getloclist(0, {'context':1}))
+ endif
+
+ " Test for changing the context of previous quickfix lists
+ call g:Xsetlist([], 'f')
+ Xexpr "One"
+ Xexpr "Two"
+ Xexpr "Three"
+ call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
+ call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
+ " Also, check for setting the context using quickfix list number zero.
+ call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
+ call test_garbagecollect_now()
+ let l = g:Xgetlist({'nr' : 1, 'context' : 1})
+ call assert_equal([1], l.context)
+ let l = g:Xgetlist({'nr' : 2, 'context' : 1})
+ call assert_equal([2], l.context)
+ let l = g:Xgetlist({'nr' : 3, 'context' : 1})
+ call assert_equal([3], l.context)
+
+ " Test for changing the context through reference and for garbage
+ " collection of quickfix context
+ let l = ["red"]
+ call g:Xsetlist([], ' ', {'context' : l})
+ call add(l, "blue")
+ let x = g:Xgetlist({'context' : 1})
+ call add(x.context, "green")
+ call assert_equal(["red", "blue", "green"], l)
+ call assert_equal(["red", "blue", "green"], x.context)
+ unlet l
+ call test_garbagecollect_now()
+ let m = g:Xgetlist({'context' : 1})
+ call assert_equal(["red", "blue", "green"], m.context)
+
+ " Test for setting/getting items
+ Xexpr ""
+ let qfprev = g:Xgetlist({'nr':0})
+ let s = g:Xsetlist([], ' ', {'title':'Green',
+ \ 'items' : [{'filename':'F1', 'lnum':10}]})
+ call assert_equal(0, s)
+ let qfcur = g:Xgetlist({'nr':0})
+ call assert_true(qfcur.nr == qfprev.nr + 1)
+ let l = g:Xgetlist({'items':1})
+ call assert_equal('F1', bufname(l.items[0].bufnr))
+ call assert_equal(10, l.items[0].lnum)
+ call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
+ \ {'filename':'F2', 'lnum':30}]})
+ let l = g:Xgetlist({'items':1})
+ call assert_equal('F2', bufname(l.items[2].bufnr))
+ call assert_equal(30, l.items[2].lnum)
+ call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
+ let l = g:Xgetlist({'items':1})
+ call assert_equal('F3', bufname(l.items[0].bufnr))
+ call assert_equal(40, l.items[0].lnum)
+ call g:Xsetlist([], 'r', {'items' : []})
+ let l = g:Xgetlist({'items':1})
+ call assert_equal(0, len(l.items))
+
+ " The following used to crash Vim with address sanitizer
+ call g:Xsetlist([], 'f')
+ call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
+ call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
+
+ " Save and restore the quickfix stack
+ call g:Xsetlist([], 'f')
+ call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
+ Xexpr "File1:10:Line1"
+ Xexpr "File2:20:Line2"
+ Xexpr "File3:30:Line3"
+ let last_qf = g:Xgetlist({'nr':'$'}).nr
+ call assert_equal(3, last_qf)
+ let qstack = []
+ for i in range(1, last_qf)
+ let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
+ endfor
+ call g:Xsetlist([], 'f')
+ for i in range(len(qstack))
+ call g:Xsetlist([], ' ', qstack[i])
+ endfor
+ call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
+ call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
+ call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
+ call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
+ call g:Xsetlist([], 'f')
+
+ " Swap two quickfix lists
+ Xexpr "File1:10:Line10"
+ Xexpr "File2:20:Line20"
+ Xexpr "File3:30:Line30"
+ call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
+ call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
+ let l1=g:Xgetlist({'nr':1,'all':1})
+ let l2=g:Xgetlist({'nr':2,'all':1})
+ let save_id = l1.id
+ let l1.id=l2.id
+ let l2.id=save_id
+ call g:Xsetlist([], 'r', l1)
+ call g:Xsetlist([], 'r', l2)
+ let newl1=g:Xgetlist({'nr':1,'all':1})
+ let newl2=g:Xgetlist({'nr':2,'all':1})
+ call assert_equal(':Fruits', newl1.title)
+ call assert_equal(['Fruits'], newl1.context)
+ call assert_equal('Line20', newl1.items[0].text)
+ call assert_equal(':Colors', newl2.title)
+ call assert_equal(['Colors'], newl2.context)
+ call assert_equal('Line10', newl2.items[0].text)
+ call g:Xsetlist([], 'f')
+endfunc
+
+func Test_qf_property()
+ call Xproperty_tests('c')
+ call Xproperty_tests('l')
+endfunc
+
+" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
+func QfAutoCmdHandler(loc, cmd)
+ call add(g:acmds, a:loc . a:cmd)
+endfunc
+
+func Test_Autocmd()
+ autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
+ autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
+
+ let g:acmds = []
+ cexpr "F1:10:Line 10"
+ caddexpr "F1:20:Line 20"
+ cgetexpr "F1:30:Line 30"
+ enew! | call append(0, "F2:10:Line 10")
+ cbuffer!
+ enew! | call append(0, "F2:20:Line 20")
+ cgetbuffer
+ enew! | call append(0, "F2:30:Line 30")
+ caddbuffer
+
+ let l = ['precexpr',
+ \ 'postcexpr',
+ \ 'precaddexpr',
+ \ 'postcaddexpr',
+ \ 'precgetexpr',
+ \ 'postcgetexpr',
+ \ 'precbuffer',
+ \ 'postcbuffer',
+ \ 'precgetbuffer',
+ \ 'postcgetbuffer',
+ \ 'precaddbuffer',
+ \ 'postcaddbuffer']
+ call assert_equal(l, g:acmds)
+endfunc
+
+func Test_Autocmd_Exception()
+ set efm=%m
+ lgetexpr '?'
+
+ try
+ call DoesNotExit()
+ catch
+ lgetexpr '1'
+ finally
+ lgetexpr '1'
+ endtry
+
+ call assert_equal('1', getloclist(0)[0].text)
+
+ set efm&vim
+endfunc
+
+func Test_caddbuffer_wrong()
+ " This used to cause a memory access in freed memory.
+ let save_efm = &efm
+ set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
+ cgetexpr ['WWWW', 'EEEE', 'CCCC']
+ let &efm = save_efm
+ caddbuffer
+ bwipe!
+endfunc
+
+func Test_caddexpr_wrong()
+ " This used to cause a memory access in freed memory.
+ cbuffer
+ cbuffer
+ copen
+ let save_efm = &efm
+ set efm=%
+ call assert_fails('caddexpr ""', 'E376:')
+ let &efm = save_efm
+endfunc
+
+func Test_dirstack_cleanup()
+ " This used to cause a memory access in freed memory.
+ let save_efm = &efm
+ lexpr '0'
+ lopen
+ fun X(c)
+ let save_efm=&efm
+ set efm=%D%f
+ if a:c == 'c'
+ caddexpr '::'
+ else
+ laddexpr ':0:0'
+ endif
+ let &efm=save_efm
+ endfun
+ call X('c')
+ call X('l')
+ call setqflist([], 'r')
+ caddbuffer
+ let &efm = save_efm
+endfunc
+
+" Tests for jumping to entries from the location list window and quickfix
+" window
+func Test_cwindow_jump()
+ set efm=%f%%%l%%%m
+ lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
+ lopen | only
+ lfirst
+ call assert_true(winnr('$') == 2)
+ call assert_true(winnr() == 1)
+ " Location list for the new window should be set
+ call assert_true(getloclist(0)[2].text == 'Line 30')
+
+ " Open a scratch buffer
+ " Open a new window and create a location list
+ " Open the location list window and close the other window
+ " Jump to an entry.
+ " Should create a new window and jump to the entry. The scrtach buffer
+ " should not be used.
+ enew | only
+ set buftype=nofile
+ below new
+ lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
+ lopen
+ 2wincmd c
+ lnext
+ call assert_true(winnr('$') == 3)
+ call assert_true(winnr() == 2)
+
+ " Open two windows with two different location lists
+ " Open the location list window and close the previous window
+ " Jump to an entry in the location list window
+ " Should open the file in the first window and not set the location list.
+ enew | only
+ lgetexpr ["F1%5%Line 5"]
+ below new
+ lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
+ lopen
+ 2wincmd c
+ lnext
+ call assert_true(winnr() == 1)
+ call assert_true(getloclist(0)[0].text == 'Line 5')
+
+ enew | only
+ cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
+ copen
+ cnext
+ call assert_true(winnr('$') == 2)
+ call assert_true(winnr() == 1)
+
+ enew | only
+ set efm&vim
+endfunc
+
+func XvimgrepTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ call writefile(['Editor:VIM vim',
+ \ 'Editor:Emacs EmAcS',
+ \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
+ call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
+
+ " Error cases
+ call assert_fails('Xvimgrep /abc *', 'E682:')
+
+ let @/=''
+ call assert_fails('Xvimgrep // *', 'E35:')
+
+ call assert_fails('Xvimgrep abc', 'E683:')
+ call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
+ call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
+
+ Xexpr ""
+ Xvimgrepadd Notepad Xtestfile1
+ Xvimgrepadd MacOS Xtestfile2
+ let l = g:Xgetlist()
+ call assert_equal(2, len(l))
+ call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
+
+ Xvimgrep #\cvim#g Xtestfile?
+ let l = g:Xgetlist()
+ call assert_equal(2, len(l))
+ call assert_equal(8, l[0].col)
+ call assert_equal(12, l[1].col)
+
+ 1Xvimgrep ?Editor? Xtestfile*
+ let l = g:Xgetlist()
+ call assert_equal(1, len(l))
+ call assert_equal('Editor:VIM vim', l[0].text)
+
+ edit +3 Xtestfile2
+ Xvimgrep +\cemacs+j Xtestfile1
+ let l = g:Xgetlist()
+ call assert_equal('Xtestfile2', bufname(''))
+ call assert_equal('Editor:Emacs EmAcS', l[0].text)
+
+ call delete('Xtestfile1')
+ call delete('Xtestfile2')
+endfunc
+
+" Tests for the :vimgrep command
+func Test_vimgrep()
+ call XvimgrepTests('c')
+ call XvimgrepTests('l')
+endfunc
+
+func XfreeTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ enew | only
+
+ " Deleting the quickfix stack should work even When the current list is
+ " somewhere in the middle of the stack
+ Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+ Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
+ Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
+ Xolder
+ call g:Xsetlist([], 'f')
+ call assert_equal(0, len(g:Xgetlist()))
+
+ " After deleting the stack, adding a new list should create a stack with a
+ " single list.
+ Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+ call assert_equal(1, g:Xgetlist({'all':1}).nr)
+
+ " Deleting the stack from a quickfix window should update/clear the
+ " quickfix/location list window.
+ Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+ Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
+ Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
+ Xolder
+ Xwindow
+ call g:Xsetlist([], 'f')
+ call assert_equal(2, winnr('$'))
+ call assert_equal(1, line('$'))
+ Xclose
+
+ " Deleting the stack from a non-quickfix window should update/clear the
+ " quickfix/location list window.
+ Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+ Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
+ Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
+ Xolder
+ Xwindow
+ wincmd p
+ call g:Xsetlist([], 'f')
+ call assert_equal(0, len(g:Xgetlist()))
+ wincmd p
+ call assert_equal(2, winnr('$'))
+ call assert_equal(1, line('$'))
+
+ " After deleting the location list stack, if the location list window is
+ " opened, then a new location list should be created. So opening the
+ " location list window again should not create a new window.
+ if a:cchar == 'l'
+ lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
+ wincmd p
+ lopen
+ call assert_equal(2, winnr('$'))
+ endif
+ Xclose
+endfunc
+
+" Tests for the quickifx free functionality
+func Test_qf_free()
+ call XfreeTests('c')
+ call XfreeTests('l')
+endfunc
+
+" Test for buffer overflow when parsing lines and adding new entries to
+" the quickfix list.
+func Test_bufoverflow()
+ set efm=%f:%l:%m
+ cgetexpr ['File1:100:' . repeat('x', 1025)]
+
+ set efm=%+GCompiler:\ %.%#,%f:%l:%m
+ cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
+
+ set efm=%DEntering\ directory\ %f,%f:%l:%m
+ cgetexpr ['Entering directory ' . repeat('a', 1006),
+ \ 'File1:10:Hello World']
+ set efm&vim
+endfunc
+
+" Tests for getting the quickfix stack size
+func XsizeTests(cchar)
+ call s:setup_commands(a:cchar)
+
+ call g:Xsetlist([], 'f')
+ call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
+ call assert_equal(1, len(g:Xgetlist({'nr':'$', 'all':1})))
+ call assert_equal(0, len(g:Xgetlist({'nr':0})))
+
+ Xexpr "File1:10:Line1"
+ Xexpr "File2:20:Line2"
+ Xexpr "File3:30:Line3"
+ Xolder | Xolder
+ call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
+ call g:Xsetlist([], 'f')
+
+ Xexpr "File1:10:Line1"
+ Xexpr "File2:20:Line2"
+ Xexpr "File3:30:Line3"
+ Xolder | Xolder
+ call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
+ call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
+endfunc
+
+func Test_Qf_Size()
+ call XsizeTests('c')
+ call XsizeTests('l')
+endfunc
+
+func Test_cclose_from_copen()
+ augroup QF_Test
+ au!
+ au FileType qf :call assert_fails(':cclose', 'E788')
+ augroup END
+ copen
+ augroup QF_Test
+ au!
+ augroup END
+ augroup! QF_Test
+endfunc
+
+func Test_cclose_in_autocmd()
+ " Problem is only triggered if "starting" is zero, so that the OptionsSet
+ " event will be triggered.
+ " call test_override('starting', 1)
+ augroup QF_Test
+ au!
+ au FileType qf :call assert_fails(':cclose', 'E788')
+ augroup END
+ copen
+ augroup QF_Test
+ au!
+ augroup END
+ augroup! QF_Test
+ " call test_override('starting', 0)
+endfunc
+
+" Check that ":file" without an argument is possible even when "curbuf_lock"
+" is set.
+func Test_file_from_copen()
+ " Works without argument.
+ augroup QF_Test
+ au!
+ au FileType qf file
+ augroup END
+ copen
+
+ augroup QF_Test
+ au!
+ augroup END
+ cclose
+
+ " Fails with argument.
+ augroup QF_Test
+ au!
+ au FileType qf call assert_fails(':file foo', 'E788')
+ augroup END
+ copen
+ augroup QF_Test
+ au!
+ augroup END
+ cclose
+
+ augroup! QF_Test
+endfunction
+
+func Test_resize_from_copen()
+ augroup QF_Test
+ au!
+ au FileType qf resize 5
+ augroup END
+ try
+ " This should succeed without any exception. No other buffers are
+ " involved in the autocmd.
+ copen
+ finally
+ augroup QF_Test
+ au!
+ augroup END
+ augroup! QF_Test
+ endtry
+endfunc
+
+" Tests for the quickfix buffer b:changedtick variable
+func Xchangedtick_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ new | only
+
+ Xexpr "" | Xexpr "" | Xexpr ""
+
+ Xopen
+ Xolder
+ Xolder
+ Xaddexpr "F1:10:Line10"
+ Xaddexpr "F2:20:Line20"
+ call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
+ call g:Xsetlist([], 'f')
+ call assert_equal(8, getbufvar('%', 'changedtick'))
+ Xclose
+endfunc
+
+func Test_changedtick()
+ call Xchangedtick_tests('c')
+ call Xchangedtick_tests('l')
+endfunc
+
+" Tests for parsing an expression using setqflist()
+func Xsetexpr_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ let t = ["File1:10:Line10", "File1:20:Line20"]
+ call g:Xsetlist([], ' ', {'lines' : t})
+ call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
+
+ let l = g:Xgetlist()
+ call assert_equal(3, len(l))
+ call assert_equal(20, l[1].lnum)
+ call assert_equal('Line30', l[2].text)
+ call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
+ let l = g:Xgetlist()
+ call assert_equal(1, len(l))
+ call assert_equal('Line5', l[0].text)
+ call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
+ call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
+
+ call g:Xsetlist([], 'f')
+ " Add entries to multiple lists
+ call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
+ call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
+ call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
+ call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
+ call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
+ call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
+
+ " Adding entries using a custom efm
+ set efm&
+ call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
+ \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
+ call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
+ call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
+ call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
+ call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
+ call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
+ \ 'lines' : ['F1:10:L10']}))
+endfunc
+
+func Test_setexpr()
+ call Xsetexpr_tests('c')
+ call Xsetexpr_tests('l')
+endfunc
+
+" Tests for per quickfix/location list directory stack
+func Xmultidirstack_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ call g:Xsetlist([], 'f')
+ Xexpr "" | Xexpr ""
+
+ call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
+ call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
+ call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
+ call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
+
+ let l1 = g:Xgetlist({'nr':1, 'items':1})
+ let l2 = g:Xgetlist({'nr':2, 'items':1})
+ call assert_equal(expand('Xone/a/one.txt'), bufname(l1.items[1].bufnr))
+ call assert_equal(3, l1.items[1].lnum)
+ call assert_equal(expand('Xtwo/a/two.txt'), bufname(l2.items[1].bufnr))
+ call assert_equal(5, l2.items[1].lnum)
+endfunc
+
+func Test_multidirstack()
+ call mkdir('Xone/a', 'p')
+ call mkdir('Xtwo/a', 'p')
+ let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
+ call writefile(lines, 'Xone/a/one.txt')
+ call writefile(lines, 'Xtwo/a/two.txt')
+ let save_efm = &efm
+ set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
+
+ call Xmultidirstack_tests('c')
+ call Xmultidirstack_tests('l')
+
+ let &efm = save_efm
+ call delete('Xone', 'rf')
+ call delete('Xtwo', 'rf')
+endfunc
+
+" Tests for per quickfix/location list file stack
+func Xmultifilestack_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ call g:Xsetlist([], 'f')
+ Xexpr "" | Xexpr ""
+
+ call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
+ call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
+ call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
+ call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
+
+ let l1 = g:Xgetlist({'nr':1, 'items':1})
+ let l2 = g:Xgetlist({'nr':2, 'items':1})
+ call assert_equal('one.txt', bufname(l1.items[1].bufnr))
+ call assert_equal(3, l1.items[1].lnum)
+ call assert_equal('two.txt', bufname(l2.items[1].bufnr))
+ call assert_equal(5, l2.items[1].lnum)
+endfunc
+
+func Test_multifilestack()
+ let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
+ call writefile(lines, 'one.txt')
+ call writefile(lines, 'two.txt')
+ let save_efm = &efm
+ set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
+
+ call Xmultifilestack_tests('c')
+ call Xmultifilestack_tests('l')
+
+ let &efm = save_efm
+ call delete('one.txt')
+ call delete('two.txt')
+endfunc
+
+" Tests for per buffer 'efm' setting
+func Test_perbuf_efm()
+ call writefile(["File1-10-Line10"], 'one.txt')
+ call writefile(["File2#20#Line20"], 'two.txt')
+ set efm=%f#%l#%m
+ new | only
+ new
+ setlocal efm=%f-%l-%m
+ cfile one.txt
+ wincmd w
+ caddfile two.txt
+
+ let l = getqflist()
+ call assert_equal(10, l[0].lnum)
+ call assert_equal('Line20', l[1].text)
+
+ set efm&
+ new | only
+ call delete('one.txt')
+ call delete('two.txt')
+endfunc
+
+" Open multiple help windows using ":lhelpgrep
+" This test used to crash Vim
+func Test_Multi_LL_Help()
+ new | only
+ lhelpgrep window
+ lopen
+ e#
+ lhelpgrep buffer
+ call assert_equal(3, winnr('$'))
+ call assert_true(len(getloclist(1)) != 0)
+ call assert_true(len(getloclist(2)) != 0)
+ new | only
+endfunc
+
+" Tests for adding new quickfix lists using setqflist()
+func XaddQf_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ " Create a new list using ' ' for action
+ call g:Xsetlist([], 'f')
+ call g:Xsetlist([], ' ', {'title' : 'Test1'})
+ let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+ call assert_equal(1, l.nr)
+ call assert_equal('Test1', l.title)
+
+ " Create a new list using ' ' for action and '$' for 'nr'
+ call g:Xsetlist([], 'f')
+ call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
+ let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+ call assert_equal(1, l.nr)
+ call assert_equal('Test2', l.title)
+
+ " Create a new list using 'a' for action
+ call g:Xsetlist([], 'f')
+ call g:Xsetlist([], 'a', {'title' : 'Test3'})
+ let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+ call assert_equal(1, l.nr)
+ call assert_equal('Test3', l.title)
+
+ " Create a new list using 'a' for action and '$' for 'nr'
+ call g:Xsetlist([], 'f')
+ call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
+ call g:Xsetlist([], 'a', {'title' : 'Test4'})
+ let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+ call assert_equal(1, l.nr)
+ call assert_equal('Test4', l.title)
+
+ " Adding a quickfix list should remove all the lists following the current
+ " list.
+ Xexpr "" | Xexpr "" | Xexpr ""
+ silent! 10Xolder
+ call g:Xsetlist([], ' ', {'title' : 'Test5'})
+ let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+ call assert_equal(2, l.nr)
+ call assert_equal('Test5', l.title)
+
+ " Add a quickfix list using '$' as the list number.
+ let lastqf = g:Xgetlist({'nr':'$'}).nr
+ silent! 99Xolder
+ call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
+ let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+ call assert_equal(lastqf + 1, l.nr)
+ call assert_equal('Test6', l.title)
+
+ " Add a quickfix list using 'nr' set to one more than the quickfix
+ " list size.
+ let lastqf = g:Xgetlist({'nr':'$'}).nr
+ silent! 99Xolder
+ call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
+ let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+ call assert_equal(lastqf + 1, l.nr)
+ call assert_equal('Test7', l.title)
+
+ " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
+ exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
+ silent! 99Xolder
+ call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
+ let l = g:Xgetlist({'nr' : '$', 'all' : 1})
+ call assert_equal(10, l.nr)
+ call assert_equal('Test8', l.title)
+
+ " Add a quickfix list using 'nr' set to a value greater than 10
+ call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
+
+ " Try adding a quickfix list with 'nr' set to a value greater than the
+ " quickfix list size but less than 10.
+ call g:Xsetlist([], 'f')
+ Xexpr "" | Xexpr "" | Xexpr ""
+ silent! 99Xolder
+ call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
+
+ " Add a quickfix list using 'nr' set to a some string or list
+ call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
+endfunc
+
+func Test_add_qf()
+ call XaddQf_tests('c')
+ call XaddQf_tests('l')
+endfunc
+
+" Test for getting the quickfix list items from some text without modifying
+" the quickfix stack
+func XgetListFromLines(cchar)
+ call s:setup_commands(a:cchar)
+ call g:Xsetlist([], 'f')
+
+ let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
+ call assert_equal(2, len(l))
+ call assert_equal(30, l[1].lnum)
+
+ call assert_equal({}, g:Xgetlist({'lines' : 10}))
+ call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
+ call assert_equal([], g:Xgetlist({'lines' : []}).items)
+ call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
+
+ " Parse text using a custom efm
+ set efm&
+ let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
+ call assert_equal('Line30', l[0].text)
+ let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
+ call assert_equal('File3:30:Line30', l[0].text)
+ let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
+ call assert_equal({}, l)
+ call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
+ call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
+
+ " Make sure that the quickfix stack is not modified
+ call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
+endfunc
+
+func Test_get_list_from_lines()
+ call XgetListFromLines('c')
+ call XgetListFromLines('l')
+endfunc
+
+" Tests for the quickfix list id
+func Xqfid_tests(cchar)
+ call s:setup_commands(a:cchar)
+
+ call g:Xsetlist([], 'f')
+ call assert_equal({}, g:Xgetlist({'id':0}))
+ Xexpr ''
+ let start_id = g:Xgetlist({'id' : 0}).id
+ Xexpr '' | Xexpr ''
+ Xolder
+ call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
+ call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
+ call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
+ call assert_equal({}, g:Xgetlist({'id':0, 'nr':99}))
+ call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
+ call assert_equal({}, g:Xgetlist({'id':99, 'nr':0}))
+ call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0}))
+
+ call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
+ call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
+ call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
+ call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
+ call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
+ call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
+
+ let qfid = g:Xgetlist({'id':0, 'nr':0})
+ call g:Xsetlist([], 'f')
+ call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0}))
+endfunc
+
+func Test_qf_id()
+ call Xqfid_tests('c')
+ call Xqfid_tests('l')
+endfunc
+
+" Test for shortening/simplifying the file name when opening the
+" quickfix window or when displaying the quickfix list
+func Test_shorten_fname()
+ if !has('unix')
+ return
+ endif
+ %bwipe
+ " Create a quickfix list with a absolute path filename
+ let fname = getcwd() . '/test_quickfix.vim'
+ call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
+ call assert_equal(fname, bufname('test_quickfix.vim'))
+ " Opening the quickfix window should simplify the file path
+ cwindow
+ call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
+ cclose
+ %bwipe
+ " Create a quickfix list with a absolute path filename
+ call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
+ call assert_equal(fname, bufname('test_quickfix.vim'))
+ " Displaying the quickfix list should simplify the file path
+ silent! clist
+ call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
+endfunc
+
+" Test for the position of the quickfix and location list window
+func Test_qfwin_pos()
+ " Open two windows
+ new | only
+ new
+ cexpr ['F1:10:L10']
+ copen
+ " Quickfix window should be the bottom most window
+ call assert_equal(3, winnr())
+ close
+ " Open at the very top
+ wincmd t
+ topleft copen
+ call assert_equal(1, winnr())
+ close
+ " open left of the current window
+ wincmd t
+ below new
+ leftabove copen
+ call assert_equal(2, winnr())
+ close
+ " open right of the current window
+ rightbelow copen
+ call assert_equal(3, winnr())
+ close
+endfunc
diff --git a/src/nvim/testdir/test_quotestar.vim b/src/nvim/testdir/test_quotestar.vim
new file mode 100644
index 0000000000..3ce1a84281
--- /dev/null
+++ b/src/nvim/testdir/test_quotestar.vim
@@ -0,0 +1,157 @@
+" *-register (quotestar) tests
+
+if !has('clipboard')
+ finish
+endif
+
+source shared.vim
+
+func Do_test_quotestar_for_macunix()
+ if empty(exepath('pbcopy')) || empty(exepath('pbpaste'))
+ return 'Test requires pbcopy(1) and pbpaste(1)'
+ endif
+
+ let @* = ''
+
+ " Test #1: Pasteboard to Vim
+ let test_msg = "text from pasteboard to vim via quotestar"
+ " Write a piece of text to the pasteboard.
+ call system('/bin/echo -n "' . test_msg . '" | pbcopy')
+ " See if the *-register is changed as expected.
+ call assert_equal(test_msg, @*)
+
+ " Test #2: Vim to Pasteboard
+ let test_msg = "text from vim to pasteboard via quotestar"
+ " Write a piece of text to the *-register.
+ let @* = test_msg
+ " See if the pasteboard is changed as expected.
+ call assert_equal(test_msg, system('pbpaste'))
+
+ return ''
+endfunc
+
+func Do_test_quotestar_for_x11()
+ if !has('clientserver') || !has('job')
+ return 'Test requires the client-server and job features'
+ endif
+
+ let cmd = GetVimCommand()
+ if cmd == ''
+ return 'GetVimCommand() failed'
+ endif
+ try
+ call remote_send('xxx', '')
+ catch
+ if v:exception =~ 'E240:'
+ " No connection to the X server, give up.
+ return
+ endif
+ " ignore other errors
+ endtry
+
+ let name = 'XVIMCLIPBOARD'
+
+ " Make sure a previous server has exited
+ try
+ call remote_send(name, ":qa!\<CR>")
+ call WaitFor('serverlist() !~ "' . name . '"')
+ catch /E241:/
+ endtry
+ call assert_notmatch(name, serverlist())
+
+ let cmd .= ' --servername ' . name
+ let g:job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
+ call WaitFor('job_status(g:job) == "run"')
+ if job_status(g:job) != 'run'
+ call assert_report('Cannot run the Vim server')
+ return ''
+ endif
+
+ " Takes a short while for the server to be active.
+ call WaitFor('serverlist() =~ "' . name . '"')
+
+ " Wait for the server to be up and answering requests. One second is not
+ " always sufficient.
+ call WaitFor('remote_expr("' . name . '", "v:version", "", 2) != ""')
+
+ " Clear the *-register of this vim instance and wait for it to be picked up
+ " by the server.
+ let @* = 'no'
+ call remote_foreground(name)
+ call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "no"', 3000)
+
+ " Set the * register on the server.
+ call remote_send(name, ":let @* = 'yes'\<CR>")
+ call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "yes"', 3000)
+
+ " Check that the *-register of this vim instance is changed as expected.
+ call WaitFor('@* == "yes"', 3000)
+
+ " Handle the large selection over 262040 byte.
+ let length = 262044
+ let sample = 'a' . repeat('b', length - 2) . 'c'
+ let @* = sample
+ call WaitFor('remote_expr("' . name . '", "len(@*) >= ' . length . '", "", 1)', 3000)
+ let res = remote_expr(name, "@*", "", 2)
+ call assert_equal(length, len(res))
+ " Check length to prevent a large amount of output at assertion failure.
+ if length == len(res)
+ call assert_equal(sample, res)
+ endif
+
+ if has('unix') && has('gui') && !has('gui_running')
+ let @* = ''
+
+ " Running in a terminal and the GUI is avaiable: Tell the server to open
+ " the GUI and check that the remote command still works.
+ " Need to wait for the GUI to start up, otherwise the send hangs in trying
+ " to send to the terminal window.
+ if has('gui_athena') || has('gui_motif')
+ " For those GUIs, ignore the 'failed to create input context' error.
+ call remote_send(name, ":call test_ignore_error('E285') | gui -f\<CR>")
+ else
+ call remote_send(name, ":gui -f\<CR>")
+ endif
+ " Wait for the server in the GUI to be up and answering requests.
+ call WaitFor('remote_expr("' . name . '", "has(\"gui_running\")", "", 1) =~ "1"')
+
+ call remote_send(name, ":let @* = 'maybe'\<CR>")
+ call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "maybe"')
+ call assert_equal('maybe', remote_expr(name, "@*", "", 2))
+
+ call assert_equal('maybe', @*)
+ endif
+
+ call remote_send(name, ":qa!\<CR>")
+ call WaitFor('job_status(g:job) == "dead"')
+ if job_status(g:job) != 'dead'
+ call assert_report('Server did not exit')
+ call job_stop(g:job, 'kill')
+ endif
+
+ return ''
+endfunc
+
+func Test_quotestar()
+ let skipped = ''
+
+ let quotestar_saved = @*
+
+ if has('macunix')
+ let skipped = Do_test_quotestar_for_macunix()
+ elseif has('x11')
+ if empty($DISPLAY)
+ let skipped = "Test can only run when $DISPLAY is set."
+ else
+ let skipped = Do_test_quotestar_for_x11()
+ endif
+ else
+ let skipped = "Test is not implemented yet for this platform."
+ endif
+
+ let @* = quotestar_saved
+
+ if !empty(skipped)
+ throw 'Skipped: ' . skipped
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_recover.vim b/src/nvim/testdir/test_recover.vim
new file mode 100644
index 0000000000..beecb4cd0d
--- /dev/null
+++ b/src/nvim/testdir/test_recover.vim
@@ -0,0 +1,58 @@
+" Test :recover
+
+func Test_recover_root_dir()
+ " This used to access invalid memory.
+ split Xtest
+ set dir=/
+ call assert_fails('recover', 'E305:')
+ close!
+ call assert_fails('split Xtest', 'E303:')
+ set dir&
+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.
+"
+" We need about 10000 lines of 100 characters to get two levels of pointer
+" blocks.
+func Test_swap_file()
+ set directory=.
+ set fileformat=unix undolevels=-1
+ edit! Xtest
+ let text = "\tabcdefghijklmnoparstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnoparstuvwxyz0123456789"
+ let i = 1
+ let linecount = 10000
+ while i <= linecount
+ call append(i - 1, i . text)
+ 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
+ new
+ only!
+ bwipe! Xtest
+ call rename('Xswap', swname)
+ recover Xtest
+ call delete(swname)
+ let linedollar = line('$')
+ call assert_equal(linecount, linedollar)
+ if linedollar < linecount
+ let linecount = linedollar
+ endif
+ let i = 1
+ while i <= linecount
+ call assert_equal(i . text, getline(i))
+ let i += 1
+ endwhile
+
+ set undolevels&
+ enew! | only
+endfunc
diff --git a/src/nvim/testdir/test_regex_char_classes.vim b/src/nvim/testdir/test_regex_char_classes.vim
new file mode 100644
index 0000000000..2192b5e8fc
--- /dev/null
+++ b/src/nvim/testdir/test_regex_char_classes.vim
@@ -0,0 +1,58 @@
+" Tests for regexp with backslash and other special characters inside []
+" Also test backslash for hex/octal numbered character.
+
+function RunSTest(value, calls, expected)
+ new
+ call feedkeys("i" . a:value, "mx")
+ exec a:calls
+ call assert_equal(a:expected, getline(1), printf("wrong result for %s", a:calls))
+ quit!
+endfunction
+
+function RunXTest(value, search_exp, expected)
+ new
+ call feedkeys("i" . a:value, "mx")
+ call feedkeys("gg" . a:search_exp . "\nx", "mx")
+ call assert_equal(a:expected, getline(1), printf("wrong result for %s", a:search_exp))
+ quit!
+endfunction
+
+
+function Test_x_search()
+ let res = "test text test text"
+ call RunXTest("test \\text test text", "/[\\x]", res)
+ call RunXTest("test \ttext test text", "/[\\t\\]]", res)
+ call RunXTest("test text ]test text", "/[]y]", res)
+ call RunXTest("test ]text test text", "/[\\]]", res)
+ call RunXTest("test text te^st text", "/[y^]", res)
+ call RunXTest("test te$xt test text", "/[$y]", res)
+ call RunXTest("test taext test text", "/[\\x61]", res)
+ call RunXTest("test tbext test text","/[\\x60-\\x64]", res)
+ call RunXTest("test 5text test text","/[\\x785]", res)
+ call RunXTest("testc text test text","/[\\o143]", res)
+ call RunXTest("tesdt text test text","/[\\o140-\\o144]", res)
+ call RunXTest("test7 text test text", "/[\\o417]", res)
+ call RunXTest("test text tBest text", "/\\%x42", res)
+ call RunXTest("test text teCst text", "/\\%o103", res)
+ call RunXTest("test text \<C-V>x00test text", "/[\\x00]", res)
+endfunction
+
+function Test_s_search()
+ let res = "test text test text"
+ call RunSTest("test te\<C-V>x00xt t\<C-V>x04est t\<C-V>x10ext", "s/[\\x00-\\x10]//g", res)
+ call RunSTest("test \\xyztext test text", "s/[\\x-z]\\+//", res)
+ call RunSTest("test text tev\\uyst text", "s/[\\u-z]\\{2,}//", res)
+ call RunSTest("xx aaaaa xx a", "s/\\(a\\)\\+//", "xx xx a")
+ call RunSTest("xx aaaaa xx a", "s/\\(a*\\)\\+//", "xx aaaaa xx a")
+ call RunSTest("xx aaaaa xx a", "s/\\(a*\\)*//", "xx aaaaa xx a")
+ call RunSTest("xx aaaaa xx", "s/\\(a\\)\\{2,3}/A/", "xx Aaa xx")
+ call RunSTest("xx aaaaa xx", "s/\\(a\\)\\{-2,3}/A/", "xx Aaaa xx")
+ call RunSTest("xx aaa12aa xx", "s/\\(a\\)*\\(12\\)\\@>/A/", "xx Aaa xx")
+ call RunSTest("xx foobar xbar xx", "s/\\(foo\\)\\@<!bar/A/", "xx foobar xA xx")
+ call RunSTest("xx an file xx", "s/\\(an\\_s\\+\\)\\@<=file/A/", "xx an A xx")
+ call RunSTest("x= 9;", "s/^\\(\\h\\w*\\%(->\\|\\.\\)\\=\\)\\+=/XX/", "XX 9;")
+ call RunSTest("hh= 77;", "s/^\\(\\h\\w*\\%(->\\|\\.\\)\\=\\)\\+=/YY/", "YY 77;")
+ call RunSTest(" aaa ", "s/aaa/xyz/", " xyz ")
+ call RunSTest(" xyz", "s/~/bcd/", " bcd")
+ call RunSTest(" bcdbcdbcd", "s/~\\+/BB/", " BB")
+endfunction
diff --git a/src/nvim/testdir/test_regexp_latin.vim b/src/nvim/testdir/test_regexp_latin.vim
new file mode 100644
index 0000000000..8528412806
--- /dev/null
+++ b/src/nvim/testdir/test_regexp_latin.vim
@@ -0,0 +1,32 @@
+" Tests for regexp in latin1 encoding
+set encoding=latin1
+scriptencoding latin1
+
+func s:equivalence_test()
+ let str = "AÀÁÂÃÄÅ B C D EÈÉÊË F G H IÌÍÎÏ J K L M NÑ OÒÓÔÕÖØ P Q R S T UÙÚÛÜ V W X YÝ Z aàáâãäå b c d eèéêë f g h iìíîï j k l m nñ oòóôõöø p q r s t uùúûü v w x yýÿ z"
+ let groups = split(str)
+ for group1 in groups
+ for c in split(group1, '\zs')
+ " next statement confirms that equivalence class matches every
+ " character in group
+ call assert_match('^[[=' . c . '=]]*$', group1)
+ for group2 in groups
+ if group2 != group1
+ " next statement converts that equivalence class doesn't match
+ " a character in any other group
+ call assert_equal(-1, match(group2, '[[=' . c . '=]]'))
+ endif
+ endfor
+ endfor
+ endfor
+endfunc
+
+func Test_equivalence_re1()
+ set re=1
+ call s:equivalence_test()
+endfunc
+
+func Test_equivalence_re2()
+ set re=2
+ call s:equivalence_test()
+endfunc
diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim
new file mode 100644
index 0000000000..97638e9aac
--- /dev/null
+++ b/src/nvim/testdir/test_regexp_utf8.vim
@@ -0,0 +1,185 @@
+" Tests for regexp in utf8 encoding
+
+func s:equivalence_test()
+ let str = "AÀÃÂÃÄÅĀĂĄÇǞǠẢ BḂḆ CÇĆĈĊČ DÄŽÄḊḎḠEÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÃŒÃÃŽÃĨĪĬĮİÇỈ JÄ´ KĶǨḰḴ LĹĻĽĿÅḺ MḾṀ NÑŃŅŇṄṈ OÃ’Ã“Ã”Ã•Ã–Ã˜ÅŒÅŽÅÆ Ç‘ǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ Vá¹¼ WŴẀẂẄẆ XẊẌ YÃŶŸẎỲỶỸ ZŹŻŽƵáºáº” aàáâãäåÄăąǎǟǡả bḃḇ cÃ§Ä‡Ä‰Ä‹Ä dÄđḋá¸á¸‘ eèéêëēĕėęěẻẽ fḟ gÄğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįÇỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṠnñńņňʼnṅṉ oòóôõöøÅÅőơǒǫǭỠpṕṗ q rŕŗřṙṟ sÅ›Åşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vá¹½ wŵáºáºƒáº…ẇẘ xẋẠyýÿŷáºáº™á»³á»·á»¹ zźżžƶẑẕ"
+ let groups = split(str)
+ for group1 in groups
+ for c in split(group1, '\zs')
+ " next statement confirms that equivalence class matches every
+ " character in group
+ call assert_match('^[[=' . c . '=]]*$', group1)
+ for group2 in groups
+ if group2 != group1
+ " next statement converts that equivalence class doesn't match
+ " character in any other group
+ call assert_equal(-1, match(group2, '[[=' . c . '=]]'))
+ endif
+ endfor
+ endfor
+ endfor
+endfunc
+
+func Test_equivalence_re1()
+ set re=1
+ call s:equivalence_test()
+ set re=0
+endfunc
+
+func Test_equivalence_re2()
+ set re=2
+ call s:equivalence_test()
+ set re=0
+endfunc
+
+func s:classes_test()
+ set isprint=@,161-255
+ call assert_equal('Motörhead', matchstr('Motörhead', '[[:print:]]\+'))
+
+ let alnumchars = ''
+ let alphachars = ''
+ let backspacechar = ''
+ let blankchars = ''
+ let cntrlchars = ''
+ let digitchars = ''
+ let escapechar = ''
+ let graphchars = ''
+ let lowerchars = ''
+ let printchars = ''
+ let punctchars = ''
+ let returnchar = ''
+ let spacechars = ''
+ let tabchar = ''
+ let upperchars = ''
+ let xdigitchars = ''
+ let i = 1
+ while i <= 255
+ let c = nr2char(i)
+ if c =~ '[[:alpha:]]'
+ let alphachars .= c
+ endif
+ if c =~ '[[:alnum:]]'
+ let alnumchars .= c
+ endif
+ if c =~ '[[:backspace:]]'
+ let backspacechar .= c
+ endif
+ if c =~ '[[:blank:]]'
+ let blankchars .= c
+ endif
+ if c =~ '[[:cntrl:]]'
+ let cntrlchars .= c
+ endif
+ if c =~ '[[:digit:]]'
+ let digitchars .= c
+ endif
+ if c =~ '[[:escape:]]'
+ let escapechar .= c
+ endif
+ if c =~ '[[:graph:]]'
+ let graphchars .= c
+ endif
+ if c =~ '[[:lower:]]'
+ let lowerchars .= c
+ endif
+ if c =~ '[[:print:]]'
+ let printchars .= c
+ endif
+ if c =~ '[[:punct:]]'
+ let punctchars .= c
+ endif
+ if c =~ '[[:return:]]'
+ let returnchar .= c
+ endif
+ if c =~ '[[:space:]]'
+ let spacechars .= c
+ endif
+ if c =~ '[[:tab:]]'
+ let tabchar .= c
+ endif
+ if c =~ '[[:upper:]]'
+ let upperchars .= c
+ endif
+ if c =~ '[[:xdigit:]]'
+ let xdigitchars .= c
+ endif
+ let i += 1
+ endwhile
+
+ call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alphachars)
+ call assert_equal('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alnumchars)
+ call assert_equal("\b", backspacechar)
+ call assert_equal("\t ", blankchars)
+ call assert_equal("\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0b\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f\x7f", cntrlchars)
+ call assert_equal("0123456789", digitchars)
+ call assert_equal("\<Esc>", escapechar)
+ call assert_equal('!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', graphchars)
+ call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars)
+ call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ', printchars)
+ call assert_equal('!"#$%&''()*+,-./:;<=>?@[\]^_`{|}~', punctchars)
+ call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖØÙÚÛÜÃÞ', upperchars)
+ call assert_equal("\r", returnchar)
+ call assert_equal("\t\n\x0b\f\r ", spacechars)
+ call assert_equal("\t", tabchar)
+ call assert_equal('0123456789ABCDEFabcdef', xdigitchars)
+endfunc
+
+func Test_classes_re1()
+ set re=1
+ call s:classes_test()
+ set re=0
+endfunc
+
+func Test_classes_re2()
+ set re=2
+ call s:classes_test()
+ set re=0
+endfunc
+
+func Test_recursive_substitute()
+ new
+ s/^/\=execute("s#^##gn")
+ " check we are now not in the sandbox
+ call setwinvar(1, 'myvar', 1)
+ bwipe!
+endfunc
+
+func Test_nested_backrefs()
+ " Check example in change.txt.
+ new
+ for re in range(0, 2)
+ exe 'set re=' . re
+ call setline(1, 'aa ab x')
+ 1s/\(\(a[a-d] \)*\)\(x\)/-\1- -\2- -\3-/
+ call assert_equal('-aa ab - -ab - -x-', getline(1))
+
+ call assert_equal('-aa ab - -ab - -x-', substitute('aa ab x', '\(\(a[a-d] \)*\)\(x\)', '-\1- -\2- -\3-', ''))
+ endfor
+ bwipe!
+ set re=0
+endfunc
+
+func Test_eow_with_optional()
+ let expected = ['abc def', 'abc', 'def', '', '', '', '', '', '', '']
+ for re in range(0, 2)
+ exe 'set re=' . re
+ let actual = matchlist('abc def', '\(abc\>\)\?\s*\(def\)')
+ call assert_equal(expected, actual)
+ endfor
+endfunc
+
+func Test_reversed_range()
+ for re in range(0, 2)
+ exe 'set re=' . re
+ call assert_fails('call match("abc def", "[c-a]")', 'E944:')
+ endfor
+ set re=0
+endfunc
+
+func Test_large_class()
+ set re=1
+ call assert_fails('call match("abc def", "[\u3000-\u4000]")', 'E945:')
+ set re=2
+ call assert_equal(0, 'abc def' =~# '[\u3000-\u4000]')
+ call assert_equal(1, "\u3042" =~# '[\u3000-\u4000]')
+ set re=0
+endfunc
diff --git a/src/nvim/testdir/test_registers.vim b/src/nvim/testdir/test_registers.vim
new file mode 100644
index 0000000000..d7b6de5652
--- /dev/null
+++ b/src/nvim/testdir/test_registers.vim
@@ -0,0 +1,65 @@
+
+func Test_yank_shows_register()
+ enew
+ set report=0
+ call setline(1, ['foo', 'bar'])
+ " Line-wise
+ exe 'norm! yy'
+ call assert_equal('1 line yanked', v:statusmsg)
+ exe 'norm! "zyy'
+ call assert_equal('1 line yanked into "z', v:statusmsg)
+ exe 'norm! yj'
+ call assert_equal('2 lines yanked', v:statusmsg)
+ exe 'norm! "zyj'
+ call assert_equal('2 lines yanked into "z', v:statusmsg)
+
+ " Block-wise
+ exe "norm! \<C-V>y"
+ call assert_equal('block of 1 line yanked', v:statusmsg)
+ exe "norm! \<C-V>\"zy"
+ call assert_equal('block of 1 line yanked into "z', v:statusmsg)
+ exe "norm! \<C-V>jy"
+ call assert_equal('block of 2 lines yanked', v:statusmsg)
+ exe "norm! \<C-V>j\"zy"
+ call assert_equal('block of 2 lines yanked into "z', v:statusmsg)
+
+ bwipe!
+endfunc
+
+func Test_display_registers()
+ e file1
+ e file2
+ call setline(1, ['foo', 'bar'])
+ /bar
+ exe 'norm! y2l"axx'
+ call feedkeys("i\<C-R>=2*4\n\<esc>")
+ call feedkeys(":ls\n", 'xt')
+
+ let a = execute('display')
+ let b = execute('registers')
+
+ call assert_equal(a, b)
+ call assert_match('^\n--- Registers ---\n'
+ \ . '"" a\n'
+ \ . '"0 ba\n'
+ \ . '"1 b\n'
+ \ . '"a b\n'
+ \ . '.*'
+ \ . '"- a\n'
+ \ . '.*'
+ \ . '": ls\n'
+ \ . '"% file2\n'
+ \ . '"# file1\n'
+ \ . '"/ bar\n'
+ \ . '"= 2\*4', a)
+
+ let a = execute('registers a')
+ call assert_match('^\n--- Registers ---\n'
+ \ . '"a b', a)
+
+ let a = execute('registers :')
+ call assert_match('^\n--- Registers ---\n'
+ \ . '": ls', a)
+
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_retab.vim b/src/nvim/testdir/test_retab.vim
new file mode 100644
index 0000000000..f11a32bade
--- /dev/null
+++ b/src/nvim/testdir/test_retab.vim
@@ -0,0 +1,77 @@
+" Test :retab
+func SetUp()
+ new
+ call setline(1, "\ta \t b c ")
+endfunc
+
+func TearDown()
+ bwipe!
+endfunc
+
+func Retab(bang, n)
+ let l:old_tabstop = &tabstop
+ let l:old_line = getline(1)
+ exe "retab" . a:bang . a:n
+ let l:line = getline(1)
+ call setline(1, l:old_line)
+ if a:n > 0
+ " :retab changes 'tabstop' to n with argument n > 0.
+ call assert_equal(a:n, &tabstop)
+ exe 'set tabstop=' . l:old_tabstop
+ else
+ " :retab does not change 'tabstop' with empty or n <= 0.
+ call assert_equal(l:old_tabstop, &tabstop)
+ endif
+ return l:line
+endfunc
+
+func Test_retab()
+ set tabstop=8 noexpandtab
+ call assert_equal("\ta\t b c ", Retab('', ''))
+ call assert_equal("\ta\t b c ", Retab('', 0))
+ call assert_equal("\ta\t b c ", Retab('', 8))
+ call assert_equal("\ta\t b\t c\t ", Retab('!', ''))
+ call assert_equal("\ta\t b\t c\t ", Retab('!', 0))
+ call assert_equal("\ta\t b\t c\t ", Retab('!', 8))
+
+ call assert_equal("\t\ta\t\t\tb c ", Retab('', 4))
+ call assert_equal("\t\ta\t\t\tb\t\t c\t ", Retab('!', 4))
+
+ call assert_equal(" a\t\tb c ", Retab('', 10))
+ call assert_equal(" a\t\tb c ", Retab('!', 10))
+
+ set tabstop=8 expandtab
+ call assert_equal(" a b c ", Retab('', ''))
+ call assert_equal(" a b c ", Retab('', 0))
+ call assert_equal(" a b c ", Retab('', 8))
+ call assert_equal(" a b c ", Retab('!', ''))
+ call assert_equal(" a b c ", Retab('!', 0))
+ call assert_equal(" a b c ", Retab('!', 8))
+
+ call assert_equal(" a b c ", Retab(' ', 4))
+ call assert_equal(" a b c ", Retab('!', 4))
+
+ call assert_equal(" a b c ", Retab(' ', 10))
+ call assert_equal(" a b c ", Retab('!', 10))
+
+ set tabstop=4 noexpandtab
+ call assert_equal("\ta\t\tb c ", Retab('', ''))
+ call assert_equal("\ta\t\tb\t\t c\t ", Retab('!', ''))
+ call assert_equal("\t a\t\t\tb c ", Retab('', 3))
+ call assert_equal("\t a\t\t\tb\t\t\tc\t ", Retab('!', 3))
+ call assert_equal(" a\t b c ", Retab('', 5))
+ call assert_equal(" a\t b\t\t c\t ", Retab('!', 5))
+
+ set tabstop=4 expandtab
+ call assert_equal(" a b c ", Retab('', ''))
+ call assert_equal(" a b c ", Retab('!', ''))
+ call assert_equal(" a b c ", Retab('', 3))
+ call assert_equal(" a b c ", Retab('!', 3))
+ call assert_equal(" a b c ", Retab('', 5))
+ call assert_equal(" a b c ", Retab('!', 5))
+endfunc
+
+func Test_retab_error()
+ call assert_fails('retab -1', 'E487:')
+ call assert_fails('retab! -1', 'E487:')
+endfunc
diff --git a/src/nvim/testdir/test_scriptnames.vim b/src/nvim/testdir/test_scriptnames.vim
new file mode 100644
index 0000000000..fc6c910bfa
--- /dev/null
+++ b/src/nvim/testdir/test_scriptnames.vim
@@ -0,0 +1,26 @@
+" Test for :scriptnames
+
+func Test_scriptnames()
+ call writefile(['let did_load_script = 123'], 'Xscripting')
+ source Xscripting
+ call assert_equal(123, g:did_load_script)
+
+ let scripts = split(execute('scriptnames'), "\n")
+ let last = scripts[-1]
+ call assert_match('\<Xscripting\>', last)
+ let lastnr = substitute(last, '\D*\(\d\+\):.*', '\1', '')
+ exe 'script ' . lastnr
+ call assert_equal('Xscripting', expand('%:t'))
+
+ call assert_fails('script ' . (lastnr + 1), 'E474:')
+ call assert_fails('script 0', 'E939:')
+
+ new
+ call setline(1, 'nothing')
+ call assert_fails('script ' . lastnr, 'E37:')
+ exe 'script! ' . lastnr
+ call assert_equal('Xscripting', expand('%:t'))
+
+ bwipe
+ call delete('Xscripting')
+endfunc
diff --git a/src/nvim/testdir/test_scroll_opt.vim b/src/nvim/testdir/test_scroll_opt.vim
new file mode 100644
index 0000000000..77920eb8b0
--- /dev/null
+++ b/src/nvim/testdir/test_scroll_opt.vim
@@ -0,0 +1,36 @@
+" Test for reset 'scroll'
+"
+
+func Test_reset_scroll()
+ let scr = &l:scroll
+
+ setlocal scroll=1
+ setlocal scroll&
+ call assert_equal(scr, &l:scroll)
+
+ setlocal scroll=1
+ setlocal scroll=0
+ call assert_equal(scr, &l:scroll)
+
+ try
+ execute 'setlocal scroll=' . (winheight(0) + 1)
+ " not reached
+ call assert_false(1)
+ catch
+ call assert_exception('E49:')
+ endtry
+
+ split
+
+ let scr = &l:scroll
+
+ setlocal scroll=1
+ setlocal scroll&
+ call assert_equal(scr, &l:scroll)
+
+ setlocal scroll=1
+ setlocal scroll=0
+ call assert_equal(scr, &l:scroll)
+
+ quit!
+endfunc
diff --git a/src/nvim/testdir/test_scrollbind.vim b/src/nvim/testdir/test_scrollbind.vim
new file mode 100644
index 0000000000..baa24f1979
--- /dev/null
+++ b/src/nvim/testdir/test_scrollbind.vim
@@ -0,0 +1,32 @@
+" Test for 'scrollbind' causing an unexpected scroll of one of the windows.
+func Test_scrollbind()
+ " We don't want the status line to cause problems:
+ set laststatus=0
+ let totalLines = &lines * 20
+ let middle = totalLines / 2
+ new | only
+ for i in range(1, totalLines)
+ call setline(i, 'LINE ' . i)
+ endfor
+ exe string(middle)
+ normal zt
+ normal M
+ aboveleft vert new
+ for i in range(1, totalLines)
+ call setline(i, 'line ' . i)
+ endfor
+ exe string(middle)
+ normal zt
+ normal M
+ " Execute the following two commands at once to reproduce the problem.
+ setl scb | wincmd p
+ setl scb
+ wincmd w
+ let topLineLeft = line('w0')
+ wincmd p
+ let topLineRight = line('w0')
+ setl noscrollbind
+ wincmd p
+ setl noscrollbind
+ call assert_equal(0, topLineLeft - topLineRight)
+endfunc
diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim
new file mode 100644
index 0000000000..ecd840d40c
--- /dev/null
+++ b/src/nvim/testdir/test_search.vim
@@ -0,0 +1,491 @@
+" Test for the search command
+
+func Test_search_cmdline()
+ " See test/functional/legacy/search_spec.lua
+ throw 'skipped: Nvim does not support test_override()'
+ if !exists('+incsearch')
+ return
+ endif
+ " need to disable char_avail,
+ " so that expansion of commandline works
+ call test_override("char_avail", 1)
+ new
+ call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
+ " Test 1
+ " CTRL-N / CTRL-P skips through the previous search history
+ set noincsearch
+ :1
+ call feedkeys("/foobar\<cr>", 'tx')
+ call feedkeys("/the\<cr>",'tx')
+ call assert_equal('the', @/)
+ call feedkeys("/thes\<C-P>\<C-P>\<cr>",'tx')
+ call assert_equal('foobar', @/)
+
+ " Test 2
+ " Ctrl-G goes from one match to the next
+ " until the end of the buffer
+ set incsearch nowrapscan
+ :1
+ " first match
+ call feedkeys("/the\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ :1
+ " second match
+ call feedkeys("/the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the', getline('.'))
+ call assert_equal([0, 0, 0, 0], getpos('"'))
+ :1
+ " third match
+ call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
+ call assert_equal(' 4 their', getline('.'))
+ :1
+ " fourth match
+ call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
+ call assert_equal(' 5 there', getline('.'))
+ :1
+ " fifth match
+ call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
+ call assert_equal(' 6 their', getline('.'))
+ :1
+ " sixth match
+ call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
+ call assert_equal(' 7 the', getline('.'))
+ :1
+ " seventh match
+ call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
+ call assert_equal(' 8 them', getline('.'))
+ :1
+ " eigth match
+ call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ :1
+ " no further match
+ call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ call assert_equal([0, 0, 0, 0], getpos('"'))
+
+ " Test 3
+ " Ctrl-G goes from one match to the next
+ " and continues back at the top
+ set incsearch wrapscan
+ :1
+ " first match
+ call feedkeys("/the\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ :1
+ " second match
+ call feedkeys("/the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the', getline('.'))
+ :1
+ " third match
+ call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx')
+ call assert_equal(' 4 their', getline('.'))
+ :1
+ " fourth match
+ call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx')
+ call assert_equal(' 5 there', getline('.'))
+ :1
+ " fifth match
+ call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx')
+ call assert_equal(' 6 their', getline('.'))
+ :1
+ " sixth match
+ call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx')
+ call assert_equal(' 7 the', getline('.'))
+ :1
+ " seventh match
+ call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx')
+ call assert_equal(' 8 them', getline('.'))
+ :1
+ " eigth match
+ call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ :1
+ " back at first match
+ call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+
+ " Test 4
+ " CTRL-T goes to the previous match
+ set incsearch nowrapscan
+ $
+ " first match
+ call feedkeys("?the\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ $
+ " first match
+ call feedkeys("?the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ $
+ " second match
+ call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
+ call assert_equal(' 8 them', getline('.'))
+ $
+ " last match
+ call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ $
+ " last match
+ call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+
+ " Test 5
+ " CTRL-T goes to the previous match
+ set incsearch wrapscan
+ $
+ " first match
+ call feedkeys("?the\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ $
+ " first match at the top
+ call feedkeys("?the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ $
+ " second match
+ call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx')
+ call assert_equal(' 8 them', getline('.'))
+ $
+ " last match
+ call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ $
+ " back at the bottom of the buffer
+ call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+
+ " Test 6
+ " CTRL-L adds to the search pattern
+ set incsearch wrapscan
+ 1
+ " first match
+ call feedkeys("/the\<c-l>\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ 1
+ " go to next match of 'thes'
+ call feedkeys("/the\<c-l>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ 1
+ " wrap around
+ call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ 1
+ " wrap around
+ set nowrapscan
+ call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+
+ " Test 7
+ " <bs> remove from match, but stay at current match
+ set incsearch wrapscan
+ 1
+ " first match
+ call feedkeys("/thei\<cr>", 'tx')
+ call assert_equal(' 4 their', getline('.'))
+ 1
+ " delete one char, add another
+ call feedkeys("/thei\<bs>s\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ 1
+ " delete one char, add another, go to previous match, add one char
+ call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx')
+ call assert_equal(' 9 these', getline('.'))
+ 1
+ " delete all chars, start from the beginning again
+ call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx')
+ call assert_equal(' 3 the', getline('.'))
+
+ " clean up
+ call test_override("char_avail", 0)
+ bw!
+endfunc
+
+func Test_search_cmdline2()
+ " See test/functional/legacy/search_spec.lua
+ throw 'skipped: Nvim does not support test_override()'
+ if !exists('+incsearch')
+ return
+ endif
+ " need to disable char_avail,
+ " so that expansion of commandline works
+ call test_override("char_avail", 1)
+ new
+ call setline(1, [' 1', ' 2 these', ' 3 the theother'])
+ " Test 1
+ " Ctrl-T goes correctly back and forth
+ set incsearch
+ 1
+ " first match
+ call feedkeys("/the\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+ 1
+ " go to next match (on next line)
+ call feedkeys("/the\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to next match (still on line 3)
+ call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to next match (still on line 3)
+ call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to previous match (on line 3)
+ call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to previous match (on line 3)
+ call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx')
+ call assert_equal(' 3 the theother', getline('.'))
+ 1
+ " go to previous match (on line 2)
+ call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
+ call assert_equal(' 2 these', getline('.'))
+
+ " Test 2: keep the view,
+ " after deleting a character from the search cmd
+ call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar'])
+ resize 5
+ 1
+ call feedkeys("/foo\<bs>\<cr>", 'tx')
+ redraw
+ call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
+
+ " remove all history entries
+ for i in range(10)
+ call histdel('/')
+ endfor
+
+ " Test 3: reset the view,
+ " after deleting all characters from the search cmd
+ norm! 1gg0
+ " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>",
+ " nor "/foo\<c-u>\<cr>" works to delete the commandline.
+ " In that case Vim should return "E35 no previous regular expression",
+ " but it looks like Vim still sees /foo and therefore the test fails.
+ " Therefore, disableing this test
+ "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35')
+ "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview())
+
+ " clean up
+ set noincsearch
+ call test_override("char_avail", 0)
+ bw!
+endfunc
+
+func Test_use_sub_pat()
+ split
+ let @/ = ''
+ func X()
+ s/^/a/
+ /
+ endfunc
+ call X()
+ bwipe!
+endfunc
+
+func Test_searchpair()
+ new
+ call setline(1, ['other code here', '', '[', '" cursor here', ']'])
+ 4
+ let a=searchpair('\[','',']','bW')
+ call assert_equal(3, a)
+ set nomagic
+ 4
+ let a=searchpair('\[','',']','bW')
+ call assert_equal(3, a)
+ set magic
+ q!
+endfunc
+
+func Test_searchc()
+ " These commands used to cause memory overflow in searchc().
+ new
+ norm ixx
+ exe "norm 0t\u93cf"
+ bw!
+endfunc
+
+func Test_search_cmdline3()
+ throw 'skipped: Nvim does not support test_override()'
+ if !exists('+incsearch')
+ return
+ endif
+ " need to disable char_avail,
+ " so that expansion of commandline works
+ call test_override("char_avail", 1)
+ new
+ call setline(1, [' 1', ' 2 the~e', ' 3 the theother'])
+ set incsearch
+ 1
+ " first match
+ call feedkeys("/the\<c-l>\<cr>", 'tx')
+ call assert_equal(' 2 the~e', getline('.'))
+ " clean up
+ set noincsearch
+ call test_override("char_avail", 0)
+ bw!
+endfunc
+
+func Test_search_cmdline4()
+ " See test/functional/legacy/search_spec.lua
+ throw 'skipped: Nvim does not support test_override()'
+ if !exists('+incsearch')
+ return
+ endif
+ " need to disable char_avail,
+ " so that expansion of commandline works
+ call test_override("char_avail", 1)
+ new
+ call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
+ set incsearch
+ $
+ call feedkeys("?the\<c-g>\<cr>", 'tx')
+ call assert_equal(' 3 the third', getline('.'))
+ $
+ call feedkeys("?the\<c-g>\<c-g>\<cr>", 'tx')
+ call assert_equal(' 1 the first', getline('.'))
+ $
+ call feedkeys("?the\<c-g>\<c-g>\<c-g>\<cr>", 'tx')
+ call assert_equal(' 2 the second', getline('.'))
+ $
+ call feedkeys("?the\<c-t>\<cr>", 'tx')
+ call assert_equal(' 1 the first', getline('.'))
+ $
+ call feedkeys("?the\<c-t>\<c-t>\<cr>", 'tx')
+ call assert_equal(' 3 the third', getline('.'))
+ $
+ call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
+ call assert_equal(' 2 the second', getline('.'))
+ " clean up
+ set noincsearch
+ call test_override("char_avail", 0)
+ bw!
+endfunc
+
+func Test_search_cmdline5()
+ if !exists('+incsearch')
+ return
+ endif
+ " Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
+ " regardless char_avail.
+ new
+ call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
+ set incsearch
+ 1
+ call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
+ call assert_equal(' 3 the third', getline('.'))
+ $
+ call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
+ call assert_equal(' 2 the second', getline('.'))
+ " clean up
+ set noincsearch
+ bw!
+endfunc
+
+" Tests for regexp with various magic settings
+func Test_search_regexp()
+ enew!
+
+ put ='1 a aa abb abbccc'
+ exe 'normal! /a*b\{2}c\+/e' . "\<CR>"
+ call assert_equal([0, 2, 17, 0], getpos('.'))
+
+ put ='2 d dd dee deefff'
+ exe 'normal! /\Md\*e\{2}f\+/e' . "\<CR>"
+ call assert_equal([0, 3, 17, 0], getpos('.'))
+
+ set nomagic
+ put ='3 g gg ghh ghhiii'
+ exe 'normal! /g\*h\{2}i\+/e' . "\<CR>"
+ call assert_equal([0, 4, 17, 0], getpos('.'))
+
+ put ='4 j jj jkk jkklll'
+ exe 'normal! /\mj*k\{2}l\+/e' . "\<CR>"
+ call assert_equal([0, 5, 17, 0], getpos('.'))
+
+ put ='5 m mm mnn mnnooo'
+ exe 'normal! /\vm*n{2}o+/e' . "\<CR>"
+ call assert_equal([0, 6, 17, 0], getpos('.'))
+
+ put ='6 x ^aa$ x'
+ exe 'normal! /\V^aa$' . "\<CR>"
+ call assert_equal([0, 7, 5, 0], getpos('.'))
+
+ set magic
+ put ='7 (a)(b) abbaa'
+ exe 'normal! /\v(a)(b)\2\1\1/e' . "\<CR>"
+ call assert_equal([0, 8, 14, 0], getpos('.'))
+
+ put ='8 axx [ab]xx'
+ exe 'normal! /\V[ab]\(\[xy]\)\1' . "\<CR>"
+ call assert_equal([0, 9, 7, 0], getpos('.'))
+
+ set undolevels=100
+ put ='9 foobar'
+ put =''
+ exe "normal! a\<C-G>u\<Esc>"
+ normal G
+ exe 'normal! dv?bar?' . "\<CR>"
+ call assert_equal('9 foo', getline('.'))
+ call assert_equal([0, 10, 5, 0], getpos('.'))
+ call assert_equal(10, line('$'))
+ normal u
+ call assert_equal('9 foobar', getline('.'))
+ call assert_equal([0, 10, 6, 0], getpos('.'))
+ call assert_equal(11, line('$'))
+
+ set undolevels&
+ enew!
+endfunc
+
+" Test for search('multi-byte char', 'bce')
+func Test_search_multibyte()
+ if !has('multi_byte')
+ return
+ endif
+ let save_enc = &encoding
+ set encoding=utf8
+ enew!
+ call append('$', 'A')
+ call cursor(2, 1)
+ call assert_equal(2, search('A', 'bce', line('.')))
+ enew!
+ let &encoding = save_enc
+endfunc
+
+func Test_search_undefined_behaviour()
+ if !has("terminal")
+ return
+ endif
+ let h = winheight(0)
+ if h < 3
+ return
+ endif
+ " did cause an undefined left shift
+ let g:buf = term_start([GetVimProg(), '--clean', '-e', '-s', '-c', 'call search(getline("."))', 'samples/test000'], {'term_rows': 3})
+ call assert_equal([''], getline(1, '$'))
+ call term_sendkeys(g:buf, ":qa!\<cr>")
+ bwipe!
+endfunc
+
+func Test_search_undefined_behaviour2()
+ call search("\%UC0000000")
+endfunc
+
+" This was causing E874. Also causes an invalid read?
+func Test_look_behind()
+ new
+ call setline(1, '0\|\&\n\@<=')
+ call search(getline("."))
+ bwipe!
+endfunc
+
+func Test_search_sentence()
+ new
+ " this used to cause a crash
+ call assert_fails("/\\%')", 'E486')
+ call assert_fails("/", 'E486')
+ /\%'(
+ /
+endfunc
diff --git a/src/nvim/testdir/test_sha256.vim b/src/nvim/testdir/test_sha256.vim
new file mode 100644
index 0000000000..dd4707977e
--- /dev/null
+++ b/src/nvim/testdir/test_sha256.vim
@@ -0,0 +1,22 @@
+" Tests for the sha256() function.
+
+if !has('cryptv') || !exists('*sha256')
+ finish
+endif
+
+function Test_sha256()
+ " test for empty string:
+ call assert_equal(sha256(""), 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
+
+ "'test for 1 char:
+ call assert_equal(sha256("a"), 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb')
+ "
+ "test for 3 chars:
+ call assert_equal(sha256("abc"), 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad')
+
+ " test for contains meta char:
+ call assert_equal(sha256("foo\nbar"), '807eff6267f3f926a21d234f7b0cf867a86f47e07a532f15e8cc39ed110ca776')
+
+ " test for contains non-ascii char:
+ call assert_equal(sha256("\xde\xad\xbe\xef"), '5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953')
+endfunction
diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim
new file mode 100644
index 0000000000..3960177acd
--- /dev/null
+++ b/src/nvim/testdir/test_signs.vim
@@ -0,0 +1,226 @@
+" Test for signs
+
+if !has('signs')
+ finish
+endif
+
+func Test_sign()
+ new
+ call setline(1, ['a', 'b', 'c', 'd'])
+
+ " Define some signs.
+ " We can specify icons even if not all versions of vim support icons as
+ " icon is ignored when not supported. "(not supported)" is shown after
+ " the icon name when listing signs.
+ sign define Sign1 text=x
+ try
+ sign define Sign2 text=xy texthl=Title linehl=Error numhl=Number icon=../../pixmaps/stock_vim_find_help.png
+ catch /E255:/
+ " ignore error: E255: Couldn't read in sign data!
+ " This error can happen when running in gui.
+ " Some gui like Motif do not support the png icon format.
+ endtry
+
+ " Test listing signs.
+ let a=execute('sign list')
+ call assert_match("^\nsign Sign1 text=x \nsign Sign2 icon=../../pixmaps/stock_vim_find_help.png .*text=xy linehl=Error texthl=Title numhl=Number$", a)
+
+ let a=execute('sign list Sign1')
+ call assert_equal("\nsign Sign1 text=x ", a)
+
+ " Split the window to the bottom to verify sign jump will stay in the current window
+ " if the buffer is displayed there.
+ let bn = bufnr('%')
+ let wn = winnr()
+ exe 'sign place 41 line=3 name=Sign1 buffer=' . bn
+ 1
+ bot split
+ exe 'sign jump 41 buffer=' . bufnr('%')
+ call assert_equal('c', getline('.'))
+ call assert_equal(3, winnr())
+ call assert_equal(bn, bufnr('%'))
+ call assert_notequal(wn, winnr())
+
+ " Create a new buffer and check that ":sign jump" switches to the old buffer.
+ 1
+ new foo
+ call assert_notequal(bn, bufnr('%'))
+ exe 'sign jump 41 buffer=' . bn
+ call assert_equal(bn, bufnr('%'))
+ call assert_equal('c', getline('.'))
+
+ " Redraw to make sure that screen redraw with sign gets exercised,
+ " with and without 'rightleft'.
+ if has('rightleft')
+ set rightleft
+ redraw
+ set norightleft
+ endif
+ redraw
+
+ " Check that we can't change sign.
+ call assert_fails("exe 'sign place 40 name=Sign1 buffer=' . bufnr('%')", 'E885:')
+
+ " Check placed signs
+ let a=execute('sign place')
+ call assert_equal("\n--- Signs ---\nSigns for [NULL]:\n line=3 id=41 name=Sign1\n", a)
+
+ " Unplace the sign and try jumping to it again should fail.
+ sign unplace 41
+ 1
+ call assert_fails("exe 'sign jump 41 buffer=' . bufnr('%')", 'E157:')
+ call assert_equal('a', getline('.'))
+
+ " Unplace sign on current line.
+ exe 'sign place 42 line=4 name=Sign2 buffer=' . bufnr('%')
+ 4
+ sign unplace
+ let a=execute('sign place')
+ call assert_equal("\n--- Signs ---\n", a)
+
+ " Try again to unplace sign on current line, it should fail this time.
+ call assert_fails('sign unplace', 'E159:')
+
+ " Unplace all signs.
+ exe 'sign place 41 line=3 name=Sign1 buffer=' . bufnr('%')
+ sign unplace *
+ let a=execute('sign place')
+ call assert_equal("\n--- Signs ---\n", a)
+
+ " Check :jump with file=...
+ edit foo
+ call setline(1, ['A', 'B', 'C', 'D'])
+
+ try
+ sign define Sign3 text=y texthl=DoesNotExist linehl=DoesNotExist icon=doesnotexist.xpm
+ catch /E255:/
+ " ignore error: E255: it can happens for guis.
+ endtry
+
+ let fn = expand('%:p')
+ exe 'sign place 43 line=2 name=Sign3 file=' . fn
+ edit bar
+ call assert_notequal(fn, expand('%:p'))
+ exe 'sign jump 43 file=' . fn
+ call assert_equal('B', getline('.'))
+
+ " can't define a sign with a non-printable character as text
+ call assert_fails("sign define Sign4 text=\e linehl=Comment", 'E239:')
+ call assert_fails("sign define Sign4 text=a\e linehl=Comment", 'E239:')
+ call assert_fails("sign define Sign4 text=\ea linehl=Comment", 'E239:')
+
+ " Only 1 or 2 character text is allowed
+ call assert_fails("sign define Sign4 text=abc linehl=Comment", 'E239:')
+ call assert_fails("sign define Sign4 text= linehl=Comment", 'E239:')
+ call assert_fails("sign define Sign4 text=\ ab linehl=Comment", 'E239:')
+
+ " define sign with whitespace
+ sign define Sign4 text=\ X linehl=Comment
+ sign undefine Sign4
+ sign define Sign4 linehl=Comment text=\ X
+ sign undefine Sign4
+
+ sign define Sign5 text=X\ linehl=Comment
+ sign undefine Sign5
+ sign define Sign5 linehl=Comment text=X\
+ sign undefine Sign5
+
+ " define sign with backslash
+ sign define Sign4 text=\\\\ linehl=Comment
+ sign undefine Sign4
+ sign define Sign4 text=\\ linehl=Comment
+ sign undefine Sign4
+
+ " After undefining the sign, we should no longer be able to place it.
+ sign undefine Sign1
+ sign undefine Sign2
+ sign undefine Sign3
+ call assert_fails("exe 'sign place 41 line=3 name=Sign1 buffer=' . bufnr('%')", 'E155:')
+endfunc
+
+" Undefining placed sign is not recommended.
+" Quoting :help sign
+"
+" :sign undefine {name}
+" Deletes a previously defined sign. If signs with this {name}
+" are still placed this will cause trouble.
+func Test_sign_undefine_still_placed()
+ new foobar
+ sign define Sign text=x
+ exe 'sign place 41 line=1 name=Sign buffer=' . bufnr('%')
+ sign undefine Sign
+
+ " Listing placed sign should show that sign is deleted.
+ let a=execute('sign place')
+ call assert_equal("\n--- Signs ---\nSigns for foobar:\n line=1 id=41 name=[Deleted]\n", a)
+
+ sign unplace 41
+ let a=execute('sign place')
+ call assert_equal("\n--- Signs ---\n", a)
+endfunc
+
+func Test_sign_completion()
+ sign define Sign1 text=x
+ sign define Sign2 text=y
+
+ call feedkeys(":sign \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign define jump list place undefine unplace', @:)
+
+ call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign define Sign icon= linehl= numhl= text= texthl=', @:)
+
+ call feedkeys(":sign define Sign linehl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign define Sign linehl=SpellBad SpellCap SpellLocal SpellRare', @:)
+
+ call writefile(['foo'], 'XsignOne')
+ call writefile(['bar'], 'XsignTwo')
+ call feedkeys(":sign define Sign icon=Xsig\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign define Sign icon=XsignOne XsignTwo', @:)
+ call delete('XsignOne')
+ call delete('XsignTwo')
+
+ call feedkeys(":sign undefine \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign undefine Sign1 Sign2', @:)
+
+ call feedkeys(":sign place 1 \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign place 1 buffer= file= line= name=', @:)
+
+ call feedkeys(":sign place 1 name=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign place 1 name=Sign1 Sign2', @:)
+
+ call feedkeys(":sign unplace 1 \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign unplace 1 buffer= file=', @:)
+
+ call feedkeys(":sign list \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign list Sign1 Sign2', @:)
+
+ call feedkeys(":sign jump 1 \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"sign jump 1 buffer= file=', @:)
+
+ sign undefine Sign1
+ sign undefine Sign2
+endfunc
+
+func Test_sign_invalid_commands()
+ call assert_fails('sign', 'E471:')
+ call assert_fails('sign jump', 'E471:')
+ call assert_fails('sign xxx', 'E160:')
+ call assert_fails('sign define', 'E156:')
+ call assert_fails('sign define Sign1 xxx', 'E475:')
+ call assert_fails('sign undefine', 'E156:')
+ call assert_fails('sign list xxx', 'E155:')
+ call assert_fails('sign place 1 buffer=999', 'E158:')
+ call assert_fails('sign define Sign2 text=', 'E239:')
+endfunc
+
+func Test_sign_delete_buffer()
+ new
+ sign define Sign text=x
+ let bufnr = bufnr('%')
+ new
+ exe 'bd ' . bufnr
+ exe 'sign place 61 line=3 name=Sign buffer=' . bufnr
+ call assert_fails('sign jump 61 buffer=' . bufnr, 'E934:')
+ sign unplace 61
+ sign undefine Sign
+endfunc
diff --git a/src/nvim/testdir/test_smartindent.vim b/src/nvim/testdir/test_smartindent.vim
new file mode 100644
index 0000000000..9e93a55eb0
--- /dev/null
+++ b/src/nvim/testdir/test_smartindent.vim
@@ -0,0 +1,41 @@
+" Tests for smartindent
+
+" Tests for not doing smart indenting when it isn't set.
+function! Test_nosmartindent()
+ new
+ call append(0, [" some test text",
+ \ " test text",
+ \ "test text",
+ \ " test text"])
+ set nocindent nosmartindent autoindent
+ exe "normal! gg/some\<CR>"
+ exe "normal! 2cc#test\<Esc>"
+ call assert_equal(" #test", getline(1))
+ enew! | close
+endfunction
+
+function MyIndent()
+endfunction
+
+" When 'indentexpr' is set, setting 'si' has no effect.
+function Test_smartindent_has_no_effect()
+ new
+ exe "normal! i\<Tab>one\<Esc>"
+ set noautoindent
+ set smartindent
+ set indentexpr=
+ exe "normal! Gotwo\<Esc>"
+ call assert_equal("\ttwo", getline("$"))
+
+ set indentexpr=MyIndent
+ exe "normal! Gothree\<Esc>"
+ call assert_equal("three", getline("$"))
+
+ delfunction! MyIndent
+ set autoindent&
+ set smartindent&
+ set indentexpr&
+ bwipe!
+endfunction
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_sort.vim b/src/nvim/testdir/test_sort.vim
new file mode 100644
index 0000000000..14d008a17f
--- /dev/null
+++ b/src/nvim/testdir/test_sort.vim
@@ -0,0 +1,1253 @@
+" Tests for the "sort()" function and for the ":sort" command.
+
+func Compare1(a, b) abort
+ call sort(range(3), 'Compare2')
+ return a:a - a:b
+endfunc
+
+func Compare2(a, b) abort
+ return a:a - a:b
+endfunc
+
+func Test_sort_strings()
+ " numbers compared as strings
+ call assert_equal([1, 2, 3], sort([3, 2, 1]))
+ call assert_equal([13, 28, 3], sort([3, 28, 13]))
+endfunc
+
+func Test_sort_numeric()
+ call assert_equal([1, 2, 3], sort([3, 2, 1], 'n'))
+ call assert_equal([3, 13, 28], sort([13, 28, 3], 'n'))
+ " strings are not sorted
+ call assert_equal(['13', '28', '3'], sort(['13', '28', '3'], 'n'))
+endfunc
+
+func Test_sort_numbers()
+ call assert_equal([3, 13, 28], sort([13, 28, 3], 'N'))
+ call assert_equal(['3', '13', '28'], sort(['13', '28', '3'], 'N'))
+endfunc
+
+func Test_sort_float()
+ call assert_equal([0.28, 3, 13.5], sort([13.5, 0.28, 3], 'f'))
+endfunc
+
+func Test_sort_nested()
+ " test ability to call sort() from a compare function
+ call assert_equal([1, 3, 5], sort([3, 1, 5], 'Compare1'))
+endfunc
+
+func Test_sort_default()
+ " docs say omitted, empty or zero argument sorts on string representation.
+ call assert_equal(['2', 'A', 'AA', 'a', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"]))
+ call assert_equal(['2', 'A', 'AA', 'a', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"], ''))
+ call assert_equal(['2', 'A', 'AA', 'a', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"], 0))
+ call assert_equal(['2', 'A', 'a', 'AA', 1, 3.3], sort([3.3, 1, "2", "A", "a", "AA"], 1))
+ call assert_fails('call sort([3.3, 1, "2"], 3)', "E474")
+endfunc
+
+" Tests for the ":sort" command.
+func Test_sort_cmd()
+ let tests = [
+ \ {
+ \ 'name' : 'Alphabetical sort',
+ \ 'cmd' : '%sort',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ ' 123b',
+ \ 'a',
+ \ 'a122',
+ \ 'a123',
+ \ 'a321',
+ \ 'ab',
+ \ 'abc',
+ \ 'b123',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Numeric sort',
+ \ 'cmd' : '%sort n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'a',
+ \ 'x-22',
+ \ 'b321',
+ \ 'b123',
+ \ '',
+ \ 'c123d',
+ \ '-24',
+ \ ' 123b',
+ \ 'c321d',
+ \ '0',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '-24',
+ \ 'x-22',
+ \ '0',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Hexadecimal sort',
+ \ 'cmd' : '%sort x',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'a',
+ \ 'ab',
+ \ 'abc',
+ \ ' 123b',
+ \ 'a122',
+ \ 'a123',
+ \ 'a321',
+ \ 'b123',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Alphabetical unique sort',
+ \ 'cmd' : '%sort u',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ ' 123b',
+ \ 'a',
+ \ 'a122',
+ \ 'a123',
+ \ 'a321',
+ \ 'ab',
+ \ 'abc',
+ \ 'b123',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Alphabetical reverse sort',
+ \ 'cmd' : '%sort!',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'c321d',
+ \ 'c123d',
+ \ 'b322b',
+ \ 'b321b',
+ \ 'b321',
+ \ 'b321',
+ \ 'b123',
+ \ 'abc',
+ \ 'ab',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'a',
+ \ ' 123b',
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Numeric reverse sort',
+ \ 'cmd' : '%sort! n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'b322b',
+ \ 'b321b',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'a321',
+ \ ' 123b',
+ \ 'c123d',
+ \ 'b123',
+ \ 'a123',
+ \ 'a122',
+ \ 'a',
+ \ 'ab',
+ \ 'abc'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Unique reverse sort',
+ \ 'cmd' : 'sort! u',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ],
+ \ 'expected' : [
+ \ 'c321d',
+ \ 'c123d',
+ \ 'b322b',
+ \ 'b321b',
+ \ 'b321',
+ \ 'b123',
+ \ 'abc',
+ \ 'ab',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'a',
+ \ ' 123b',
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Octal sort',
+ \ 'cmd' : 'sort o',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Reverse hexadecimal sort',
+ \ 'cmd' : 'sort! x',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'c321d',
+ \ 'c123d',
+ \ 'b322b',
+ \ 'b321b',
+ \ 'b321',
+ \ 'b321',
+ \ 'b123',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ ' 123b',
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ ''
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Alpha (skip first character) sort',
+ \ 'cmd' : 'sort/./',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'ab',
+ \ 'abc'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'Alpha (skip first 2 characters) sort',
+ \ 'cmd' : 'sort/../',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d',
+ \ 'abc'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, unique, skip first 2 characters',
+ \ 'cmd' : 'sort/../u',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d',
+ \ 'abc'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, skip first character',
+ \ 'cmd' : 'sort/./n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'b322b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, sort on first character',
+ \ 'cmd' : 'sort/./r',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ '',
+ \ '',
+ \ ' 123b',
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, sort on first 2 characters',
+ \ 'cmd' : 'sort/../r',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'a',
+ \ '',
+ \ '',
+ \ ' 123b',
+ \ 'a123',
+ \ 'a122',
+ \ 'a321',
+ \ 'abc',
+ \ 'ab',
+ \ 'b123',
+ \ 'b321',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c123d',
+ \ 'c321d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, sort on first character',
+ \ 'cmd' : 'sort/./rn',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, skip past first digit',
+ \ 'cmd' : 'sort/\d/',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, sort on first digit',
+ \ 'cmd' : 'sort/\d/r',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, skip past first digit',
+ \ 'cmd' : 'sort/\d/n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, sort on first digit',
+ \ 'cmd' : 'sort/\d/rn',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, skip past first 2 digits',
+ \ 'cmd' : 'sort/\d\d/',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ ' 123b',
+ \ 'c123d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, skip past first 2 digits',
+ \ 'cmd' : 'sort/\d\d/n',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b321',
+ \ 'b321b',
+ \ 'a122',
+ \ 'b322b',
+ \ 'a123',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'hexadecimal, skip past first 2 digits',
+ \ 'cmd' : 'sort/\d\d/x',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a321',
+ \ 'b321',
+ \ 'b321',
+ \ 'a122',
+ \ 'a123',
+ \ 'b123',
+ \ 'b321b',
+ \ 'c321d',
+ \ 'b322b',
+ \ ' 123b',
+ \ 'c123d'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alpha, sort on first 2 digits',
+ \ 'cmd' : 'sort/\d\d/r',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'numeric, sort on first 2 digits',
+ \ 'cmd' : 'sort/\d\d/rn',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'hexadecimal, sort on first 2 digits',
+ \ 'cmd' : 'sort/\d\d/rx',
+ \ 'input' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ 'a321',
+ \ 'a123',
+ \ 'a122',
+ \ 'b321',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ 'abc',
+ \ 'ab',
+ \ 'a',
+ \ '',
+ \ '',
+ \ 'a123',
+ \ 'a122',
+ \ 'b123',
+ \ 'c123d',
+ \ ' 123b',
+ \ 'a321',
+ \ 'b321',
+ \ 'c321d',
+ \ 'b322b',
+ \ 'b321',
+ \ 'b321b'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'binary',
+ \ 'cmd' : 'sort b',
+ \ 'input' : [
+ \ '0b111000',
+ \ '0b101100',
+ \ '0b101001',
+ \ '0b101001',
+ \ '0b101000',
+ \ '0b000000',
+ \ '0b001000',
+ \ '0b010000',
+ \ '0b101000',
+ \ '0b100000',
+ \ '0b101010',
+ \ '0b100010',
+ \ '0b100100',
+ \ '0b100010',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ '',
+ \ '',
+ \ '0b000000',
+ \ '0b001000',
+ \ '0b010000',
+ \ '0b100000',
+ \ '0b100010',
+ \ '0b100010',
+ \ '0b100100',
+ \ '0b101000',
+ \ '0b101000',
+ \ '0b101001',
+ \ '0b101001',
+ \ '0b101010',
+ \ '0b101100',
+ \ '0b111000'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'binary with leading characters',
+ \ 'cmd' : 'sort b',
+ \ 'input' : [
+ \ '0b100010',
+ \ '0b010000',
+ \ ' 0b101001',
+ \ 'b0b101100',
+ \ '0b100010',
+ \ ' 0b100100',
+ \ 'a0b001000',
+ \ '0b101000',
+ \ '0b101000',
+ \ 'a0b101001',
+ \ 'ab0b100000',
+ \ '0b101010',
+ \ '0b000000',
+ \ 'b0b111000',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ '',
+ \ '',
+ \ '0b000000',
+ \ 'a0b001000',
+ \ '0b010000',
+ \ 'ab0b100000',
+ \ '0b100010',
+ \ '0b100010',
+ \ ' 0b100100',
+ \ '0b101000',
+ \ '0b101000',
+ \ ' 0b101001',
+ \ 'a0b101001',
+ \ '0b101010',
+ \ 'b0b101100',
+ \ 'b0b111000'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'float',
+ \ 'cmd' : 'sort f',
+ \ 'input' : [
+ \ '1.234',
+ \ '0.88',
+ \ '123.456',
+ \ '1.15e-6',
+ \ '-1.1e3',
+ \ '-1.01e3',
+ \ '',
+ \ ''
+ \ ],
+ \ 'expected' : [
+ \ '',
+ \ '',
+ \ '-1.1e3',
+ \ '-1.01e3',
+ \ '1.15e-6',
+ \ '0.88',
+ \ '1.234',
+ \ '123.456'
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alphabetical, sorted input',
+ \ 'cmd' : 'sort',
+ \ 'input' : [
+ \ 'a',
+ \ 'b',
+ \ 'c',
+ \ ],
+ \ 'expected' : [
+ \ 'a',
+ \ 'b',
+ \ 'c',
+ \ ]
+ \ },
+ \ {
+ \ 'name' : 'alphabetical, sorted input, unique at end',
+ \ 'cmd' : 'sort u',
+ \ 'input' : [
+ \ 'aa',
+ \ 'bb',
+ \ 'cc',
+ \ 'cc',
+ \ ],
+ \ 'expected' : [
+ \ 'aa',
+ \ 'bb',
+ \ 'cc',
+ \ ]
+ \ },
+ \ ]
+
+ for t in tests
+ enew!
+ call append(0, t.input)
+ $delete _
+ setlocal nomodified
+ execute t.cmd
+
+ call assert_equal(t.expected, getline(1, '$'), t.name)
+
+ " Previously, the ":sort" command would set 'modified' even if the buffer
+ " contents did not change. Here, we check that this problem is fixed.
+ if t.input == t.expected
+ call assert_false(&modified, t.name . ': &mod is not correct')
+ else
+ call assert_true(&modified, t.name . ': &mod is not correct')
+ endif
+ endfor
+
+ call assert_fails('sort no', 'E474')
+
+ enew!
+endfunc
+
+func Test_sort_cmd_report()
+ enew!
+ call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3))
+ $delete _
+ setlocal nomodified
+ let res = execute('%sort u')
+
+ call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0'))
+ call assert_match("6 fewer lines", res)
+ enew!
+ call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3))
+ $delete _
+ setlocal nomodified report=10
+ let res = execute('%sort u')
+
+ call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0'))
+ call assert_equal("", res)
+ enew!
+ call append(0, repeat([1], 3) + repeat([2], 3) + repeat([3], 3))
+ $delete _
+ setl report&vim
+ setlocal nomodified
+ let res = execute('1g/^/%sort u')
+
+ call assert_equal([1,2,3], map(getline(1, '$'), 'v:val+0'))
+ " the output comes from the :g command, not from the :sort
+ call assert_match("6 fewer lines", res)
+ enew!
+ endfunc
diff --git a/src/nvim/testdir/test_source_utf8.vim b/src/nvim/testdir/test_source_utf8.vim
new file mode 100644
index 0000000000..c29c2ec1f3
--- /dev/null
+++ b/src/nvim/testdir/test_source_utf8.vim
@@ -0,0 +1,63 @@
+" Test the :source! command
+if !has('multi_byte')
+ finish
+endif
+
+func Test_source_utf8()
+ " check that sourcing a script with 0x80 as second byte works
+ new
+ call setline(1, [':%s/àx/--à1234--/g', ':%s/Àx/--À1234--/g'])
+ write! Xscript
+ bwipe!
+ new
+ call setline(1, [' àx ', ' Àx '])
+ source! Xscript | echo
+ call assert_equal(' --à1234-- ', getline(1))
+ call assert_equal(' --À1234-- ', getline(2))
+ bwipe!
+ call delete('Xscript')
+endfunc
+
+func Test_source_latin()
+ " check that sourcing a latin1 script with a 0xc0 byte works
+ new
+ call setline(1, ["call feedkeys('r')", "call feedkeys('\xc0', 'xt')"])
+ write! Xscript
+ bwipe!
+ new
+ call setline(1, ['xxx'])
+ source Xscript
+ call assert_equal("\u00c0xx", getline(1))
+ bwipe!
+ call delete('Xscript')
+endfunc
+
+" Test for sourcing a file with CTRL-V's at the end of the line
+func Test_source_ctrl_v()
+ call writefile(['map __1 afirst',
+ \ 'map __2 asecond',
+ \ 'map __3 athird',
+ \ 'map __4 afourth',
+ \ 'map __5 afifth',
+ \ "map __1 asd\<C-V>",
+ \ "map __2 asd\<C-V>\<C-V>",
+ \ "map __3 asd\<C-V>\<C-V>",
+ \ "map __4 asd\<C-V>\<C-V>\<C-V>",
+ \ "map __5 asd\<C-V>\<C-V>\<C-V>",
+ \ ], 'Xtestfile')
+ source Xtestfile
+ enew!
+ exe "normal __1\<Esc>\<Esc>__2\<Esc>__3\<Esc>\<Esc>__4\<Esc>__5\<Esc>"
+ exe "%s/\<C-J>/0/g"
+ call assert_equal(['sd',
+ \ "map __2 asd\<Esc>secondsd\<Esc>sd0map __5 asd0fifth"],
+ \ getline(1, 2))
+
+ enew!
+ call delete('Xtestfile')
+ unmap __1
+ unmap __2
+ unmap __3
+ unmap __4
+ unmap __5
+endfunc
diff --git a/src/nvim/testdir/test_spell.vim b/src/nvim/testdir/test_spell.vim
new file mode 100644
index 0000000000..b3438cc649
--- /dev/null
+++ b/src/nvim/testdir/test_spell.vim
@@ -0,0 +1,851 @@
+" Test spell checking
+
+if !has('spell')
+ finish
+endif
+
+func TearDown()
+ set nospell
+ call delete('Xtest.aff')
+ call delete('Xtest.dic')
+ call delete('Xtest.latin1.add')
+ call delete('Xtest.latin1.add.spl')
+ call delete('Xtest.latin1.spl')
+ call delete('Xtest.latin1.sug')
+endfunc
+
+func Test_wrap_search()
+ new
+ call setline(1, ['The', '', 'A plong line with two zpelling mistakes', '', 'End'])
+ set spell wrapscan
+ normal ]s
+ call assert_equal('plong', expand('<cword>'))
+ normal ]s
+ call assert_equal('zpelling', expand('<cword>'))
+ normal ]s
+ call assert_equal('plong', expand('<cword>'))
+ bwipe!
+ set nospell
+endfunc
+
+func Test_curswant()
+ new
+ call setline(1, ['Another plong line', 'abcdefghijklmnopq'])
+ set spell wrapscan
+ normal 0]s
+ call assert_equal('plong', expand('<cword>'))
+ normal j
+ call assert_equal(9, getcurpos()[2])
+ normal 0[s
+ call assert_equal('plong', expand('<cword>'))
+ normal j
+ call assert_equal(9, getcurpos()[2])
+
+ normal 0]S
+ call assert_equal('plong', expand('<cword>'))
+ normal j
+ call assert_equal(9, getcurpos()[2])
+ normal 0[S
+ call assert_equal('plong', expand('<cword>'))
+ normal j
+ call assert_equal(9, getcurpos()[2])
+
+ normal 1G0
+ call assert_equal('plong', spellbadword()[0])
+ normal j
+ call assert_equal(9, getcurpos()[2])
+
+ bwipe!
+ set nospell
+endfunc
+
+func Test_z_equal_on_invalid_utf8_word()
+ split
+ set spell
+ call setline(1, "\xff")
+ norm z=
+ set nospell
+ bwipe!
+endfunc
+
+func Test_spellreall()
+ new
+ set spell
+ call assert_fails('spellrepall', 'E752:')
+ call setline(1, ['A speling mistake. The same speling mistake.',
+ \ 'Another speling mistake.'])
+ call feedkeys(']s1z=', 'tx')
+ call assert_equal('A spelling mistake. The same speling mistake.', getline(1))
+ call assert_equal('Another speling mistake.', getline(2))
+ spellrepall
+ call assert_equal('A spelling mistake. The same spelling mistake.', getline(1))
+ call assert_equal('Another spelling mistake.', getline(2))
+ call assert_fails('spellrepall', 'E753:')
+ set spell&
+ bwipe!
+endfunc
+
+func Test_spellinfo()
+ throw 'skipped: Nvim does not support enc=latin1'
+ new
+
+ set enc=latin1 spell spelllang=en
+ call assert_match("^\nfile: .*/runtime/spell/en.latin1.spl\n$", execute('spellinfo'))
+
+ set enc=cp1250 spell spelllang=en
+ call assert_match("^\nfile: .*/runtime/spell/en.ascii.spl\n$", execute('spellinfo'))
+
+ if has('multi_byte')
+ set enc=utf-8 spell spelllang=en
+ call assert_match("^\nfile: .*/runtime/spell/en.utf-8.spl\n$", execute('spellinfo'))
+ endif
+
+ set enc=latin1 spell spelllang=en_us,en_nz
+ call assert_match("^\n" .
+ \ "file: .*/runtime/spell/en.latin1.spl\n" .
+ \ "file: .*/runtime/spell/en.latin1.spl\n$", execute('spellinfo'))
+
+ set spell spelllang=
+ call assert_fails('spellinfo', 'E756:')
+
+ set nospell spelllang=en
+ call assert_fails('spellinfo', 'E756:')
+
+ set enc& spell& spelllang&
+ bwipe
+endfunc
+
+func Test_zz_basic()
+ call LoadAffAndDic(g:test_data_aff1, g:test_data_dic1)
+ call RunGoodBad("wrong OK puts. Test the end",
+ \ "bad: inputs comment ok Ok. test d\xE9\xF4l end the",
+ \["Comment", "deol", "d\xE9\xF4r", "input", "OK", "output", "outputs", "outtest", "put", "puts",
+ \ "test", "testen", "testn", "the end", "uk", "wrong"],
+ \[
+ \ ["bad", ["put", "uk", "OK"]],
+ \ ["inputs", ["input", "puts", "outputs"]],
+ \ ["comment", ["Comment", "outtest", "the end"]],
+ \ ["ok", ["OK", "uk", "put"]],
+ \ ["Ok", ["OK", "Uk", "Put"]],
+ \ ["test", ["Test", "testn", "testen"]],
+ \ ["d\xE9\xF4l", ["deol", "d\xE9\xF4r", "test"]],
+ \ ["end", ["put", "uk", "test"]],
+ \ ["the", ["put", "uk", "test"]],
+ \ ]
+ \ )
+
+ call assert_equal("gebletegek", soundfold('goobledygoook'))
+ call assert_equal("kepereneven", soundfold('kóopërÿnôven'))
+ call assert_equal("everles gesvets etele", soundfold('oeverloos gezwets edale'))
+endfunc
+
+" Postponed prefixes
+func Test_zz_prefixes()
+ call LoadAffAndDic(g:test_data_aff2, g:test_data_dic1)
+ call RunGoodBad("puts",
+ \ "bad: inputs comment ok Ok end the. test d\xE9\xF4l",
+ \ ["Comment", "deol", "d\xE9\xF4r", "OK", "put", "input", "output", "puts", "outputs", "test", "outtest", "testen", "testn", "the end", "uk", "wrong"],
+ \ [
+ \ ["bad", ["put", "uk", "OK"]],
+ \ ["inputs", ["input", "puts", "outputs"]],
+ \ ["comment", ["Comment"]],
+ \ ["ok", ["OK", "uk", "put"]],
+ \ ["Ok", ["OK", "Uk", "Put"]],
+ \ ["end", ["put", "uk", "deol"]],
+ \ ["the", ["put", "uk", "test"]],
+ \ ["test", ["Test", "testn", "testen"]],
+ \ ["d\xE9\xF4l", ["deol", "d\xE9\xF4r", "test"]],
+ \ ])
+endfunc
+
+"Compound words
+func Test_zz_compound()
+ call LoadAffAndDic(g:test_data_aff3, g:test_data_dic3)
+ call RunGoodBad("foo m\xEF foobar foofoobar barfoo barbarfoo",
+ \ "bad: bar la foom\xEF barm\xEF m\xEFfoo m\xEFbar m\xEFm\xEF lala m\xEFla lam\xEF foola labar",
+ \ ["foo", "m\xEF"],
+ \ [
+ \ ["bad", ["foo", "m\xEF"]],
+ \ ["bar", ["barfoo", "foobar", "foo"]],
+ \ ["la", ["m\xEF", "foo"]],
+ \ ["foom\xEF", ["foo m\xEF", "foo", "foofoo"]],
+ \ ["barm\xEF", ["barfoo", "m\xEF", "barbar"]],
+ \ ["m\xEFfoo", ["m\xEF foo", "foo", "foofoo"]],
+ \ ["m\xEFbar", ["foobar", "barbar", "m\xEF"]],
+ \ ["m\xEFm\xEF", ["m\xEF m\xEF", "m\xEF"]],
+ \ ["lala", []],
+ \ ["m\xEFla", ["m\xEF", "m\xEF m\xEF"]],
+ \ ["lam\xEF", ["m\xEF", "m\xEF m\xEF"]],
+ \ ["foola", ["foo", "foobar", "foofoo"]],
+ \ ["labar", ["barbar", "foobar"]],
+ \ ])
+
+ call LoadAffAndDic(g:test_data_aff4, g:test_data_dic4)
+ call RunGoodBad("word util bork prebork start end wordutil wordutils pro-ok bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork tomato tomatotomato startend startword startwordword startwordend startwordwordend startwordwordwordend prebork preborkbork preborkborkbork nouword",
+ \ "bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato endstart endend startstart wordend wordstart preborkprebork preborkpreborkbork startwordwordwordwordend borkpreborkpreborkbork utilsbork startnouword",
+ \ ["bork", "prebork", "end", "pro-ok", "start", "tomato", "util", "utilize", "utils", "word", "nouword"],
+ \ [
+ \ ["bad", ["end", "bork", "word"]],
+ \ ["wordutilize", ["word utilize", "wordutils", "wordutil"]],
+ \ ["pro", ["bork", "word", "end"]],
+ \ ["borkborkborkborkborkbork", ["bork borkborkborkborkbork", "borkbork borkborkborkbork", "borkborkbork borkborkbork"]],
+ \ ["tomatotomatotomato", ["tomato tomatotomato", "tomatotomato tomato", "tomato tomato tomato"]],
+ \ ["endstart", ["end start", "start"]],
+ \ ["endend", ["end end", "end"]],
+ \ ["startstart", ["start start"]],
+ \ ["wordend", ["word end", "word", "wordword"]],
+ \ ["wordstart", ["word start", "bork start"]],
+ \ ["preborkprebork", ["prebork prebork", "preborkbork", "preborkborkbork"]],
+ \ ["preborkpreborkbork", ["prebork preborkbork", "preborkborkbork", "preborkborkborkbork"]],
+ \ ["startwordwordwordwordend", ["startwordwordwordword end", "startwordwordwordword", "start wordwordwordword end"]],
+ \ ["borkpreborkpreborkbork", ["bork preborkpreborkbork", "bork prebork preborkbork", "bork preborkprebork bork"]],
+ \ ["utilsbork", ["utilbork", "utils bork", "util bork"]],
+ \ ["startnouword", ["start nouword", "startword", "startborkword"]],
+ \ ])
+
+endfunc
+
+"Test affix flags with two characters
+func Test_zz_affix()
+ call LoadAffAndDic(g:test_data_aff5, g:test_data_dic5)
+ call RunGoodBad("fooa1 fooa\xE9 bar prebar barbork prebarbork startprebar start end startend startmiddleend nouend",
+ \ "bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart startprobar startnouend",
+ \ ["bar", "barbork", "end", "fooa1", "fooa\xE9", "nouend", "prebar", "prebarbork", "start"],
+ \ [
+ \ ["bad", ["bar", "end", "fooa1"]],
+ \ ["foo", ["fooa1", "fooa\xE9", "bar"]],
+ \ ["fooa2", ["fooa1", "fooa\xE9", "bar"]],
+ \ ["prabar", ["prebar", "bar", "bar bar"]],
+ \ ["probarbirk", ["prebarbork"]],
+ \ ["middle", []],
+ \ ["startmiddle", ["startmiddleend", "startmiddlebar"]],
+ \ ["middleend", []],
+ \ ["endstart", ["end start", "start"]],
+ \ ["startprobar", ["startprebar", "start prebar", "startbar"]],
+ \ ["startnouend", ["start nouend", "startend"]],
+ \ ])
+
+ call LoadAffAndDic(g:test_data_aff6, g:test_data_dic6)
+ call RunGoodBad("meea1 meea\xE9 bar prebar barbork prebarbork leadprebar lead end leadend leadmiddleend",
+ \ "bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead leadprobar",
+ \ ["bar", "barbork", "end", "lead", "meea1", "meea\xE9", "prebar", "prebarbork"],
+ \ [
+ \ ["bad", ["bar", "end", "lead"]],
+ \ ["mee", ["meea1", "meea\xE9", "bar"]],
+ \ ["meea2", ["meea1", "meea\xE9", "lead"]],
+ \ ["prabar", ["prebar", "bar", "leadbar"]],
+ \ ["probarbirk", ["prebarbork"]],
+ \ ["middle", []],
+ \ ["leadmiddle", ["leadmiddleend", "leadmiddlebar"]],
+ \ ["middleend", []],
+ \ ["endlead", ["end lead", "lead", "end end"]],
+ \ ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
+ \ ])
+
+ call LoadAffAndDic(g:test_data_aff7, g:test_data_dic7)
+ call RunGoodBad("meea1 meea\xE9 bar prebar barmeat prebarmeat leadprebar lead tail leadtail leadmiddletail",
+ \ "bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead leadprobar",
+ \ ["bar", "barmeat", "lead", "meea1", "meea\xE9", "prebar", "prebarmeat", "tail"],
+ \ [
+ \ ["bad", ["bar", "lead", "tail"]],
+ \ ["mee", ["meea1", "meea\xE9", "bar"]],
+ \ ["meea2", ["meea1", "meea\xE9", "lead"]],
+ \ ["prabar", ["prebar", "bar", "leadbar"]],
+ \ ["probarmaat", ["prebarmeat"]],
+ \ ["middle", []],
+ \ ["leadmiddle", ["leadmiddlebar"]],
+ \ ["middletail", []],
+ \ ["taillead", ["tail lead", "tail"]],
+ \ ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
+ \ ])
+endfunc
+
+func Test_zz_NOSLITSUGS()
+ call LoadAffAndDic(g:test_data_aff8, g:test_data_dic8)
+ call RunGoodBad("foo bar faabar", "bad: foobar barfoo",
+ \ ["bar", "faabar", "foo"],
+ \ [
+ \ ["bad", ["bar", "foo"]],
+ \ ["foobar", ["faabar", "foo bar", "bar"]],
+ \ ["barfoo", ["bar foo", "bar", "foo"]],
+ \ ])
+endfunc
+
+" Numbers
+func Test_zz_Numbers()
+ call LoadAffAndDic(g:test_data_aff9, g:test_data_dic9)
+ call RunGoodBad("0b1011 0777 1234 0x01ff", "",
+ \ ["bar", "foo"],
+ \ [
+ \ ])
+endfunc
+
+function FirstSpellWord()
+ call feedkeys("/^start:\n", 'tx')
+ normal ]smm
+ let [str, a] = spellbadword()
+ return str
+endfunc
+
+function SecondSpellWord()
+ normal `m]s
+ let [str, a] = spellbadword()
+ return str
+endfunc
+
+"Test with SAL instead of SOFO items; test automatic reloading
+func Test_zz_sal_and_addition()
+ throw 'skipped: Nvim does not support enc=latin1'
+ set enc=latin1
+ set spellfile=
+ call writefile(g:test_data_dic1, "Xtest.dic")
+ call writefile(g:test_data_aff_sal, "Xtest.aff")
+ mkspell! Xtest Xtest
+ set spl=Xtest.latin1.spl spell
+ call assert_equal('kbltykk', soundfold('goobledygoook'))
+ call assert_equal('kprnfn', soundfold('kóopërÿnôven'))
+ call assert_equal('*fls kswts tl', soundfold('oeverloos gezwets edale'))
+
+ "also use an addition file
+ call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.latin1.add")
+ mkspell! Xtest.latin1.add.spl Xtest.latin1.add
+
+ bwipe!
+ call setline(1, ["start: elequint test elekwint test elekwent asdf"])
+
+ set spellfile=Xtest.latin1.add
+ call assert_equal("elekwent", FirstSpellWord())
+
+ set spl=Xtest_us.latin1.spl
+ call assert_equal("elequint", FirstSpellWord())
+ call assert_equal("elekwint", SecondSpellWord())
+
+ set spl=Xtest_gb.latin1.spl
+ call assert_equal("elekwint", FirstSpellWord())
+ call assert_equal("elekwent", SecondSpellWord())
+
+ set spl=Xtest_nz.latin1.spl
+ call assert_equal("elequint", FirstSpellWord())
+ call assert_equal("elekwent", SecondSpellWord())
+
+ set spl=Xtest_ca.latin1.spl
+ call assert_equal("elequint", FirstSpellWord())
+ call assert_equal("elekwint", SecondSpellWord())
+endfunc
+
+func Test_region_error()
+ messages clear
+ call writefile(["/regions=usgbnz", "elequint/0"], "Xtest.latin1.add")
+ mkspell! Xtest.latin1.add.spl Xtest.latin1.add
+ call assert_match('Invalid region nr in Xtest.latin1.add line 2: 0', execute('messages'))
+ call delete('Xtest.latin1.add')
+ call delete('Xtest.latin1.add.spl')
+endfunc
+
+" Check using z= in new buffer (crash fixed by patch 7.4a.028).
+func Test_zeq_crash()
+ new
+ set spell
+ call feedkeys('iasdz=:\"', 'tx')
+
+ bwipe!
+endfunc
+
+func LoadAffAndDic(aff_contents, dic_contents)
+ throw 'skipped: Nvim does not support enc=latin1'
+ set enc=latin1
+ set spellfile=
+ call writefile(a:aff_contents, "Xtest.aff")
+ call writefile(a:dic_contents, "Xtest.dic")
+ " Generate a .spl file from a .dic and .aff file.
+ mkspell! Xtest Xtest
+ " use that spell file
+ set spl=Xtest.latin1.spl spell
+endfunc
+
+func ListWords()
+ spelldump
+ %yank
+ quit
+ return split(@", "\n")
+endfunc
+
+func TestGoodBadBase()
+ exe '1;/^good:'
+ normal 0f:]s
+ let prevbad = ''
+ let result = []
+ while 1
+ let [bad, a] = spellbadword()
+ if bad == '' || bad == prevbad || bad == 'badend'
+ break
+ endif
+ let prevbad = bad
+ let lst = spellsuggest(bad, 3)
+ normal mm
+
+ call add(result, [bad, lst])
+ normal `m]s
+ endwhile
+ return result
+endfunc
+
+func RunGoodBad(good, bad, expected_words, expected_bad_words)
+ bwipe!
+ call setline(1, ["good: ", a:good, a:bad, " badend "])
+ let words = ListWords()
+ call assert_equal(a:expected_words, words[1:-1])
+ let bad_words = TestGoodBadBase()
+ call assert_equal(a:expected_bad_words, bad_words)
+ bwipe!
+endfunc
+
+let g:test_data_aff1 = [
+ \"SET ISO8859-1",
+ \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
+ \"",
+ \"FOL \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
+ \"LOW \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
+ \"UPP \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
+ \"",
+ \"SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xBF",
+ \"SOFOTO ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?",
+ \"",
+ \"MIDWORD\t'-",
+ \"",
+ \"KEP =",
+ \"RAR ?",
+ \"BAD !",
+ \"",
+ \"PFX I N 1",
+ \"PFX I 0 in .",
+ \"",
+ \"PFX O Y 1",
+ \"PFX O 0 out .",
+ \"",
+ \"SFX S Y 2",
+ \"SFX S 0 s [^s]",
+ \"SFX S 0 es s",
+ \"",
+ \"SFX N N 3",
+ \"SFX N 0 en [^n]",
+ \"SFX N 0 nen n",
+ \"SFX N 0 n .",
+ \"",
+ \"REP 3",
+ \"REP g ch",
+ \"REP ch g",
+ \"REP svp s.v.p.",
+ \"",
+ \"MAP 9",
+ \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
+ \"MAP e\xE8\xE9\xEA\xEB",
+ \"MAP i\xEC\xED\xEE\xEF",
+ \"MAP o\xF2\xF3\xF4\xF5\xF6",
+ \"MAP u\xF9\xFA\xFB\xFC",
+ \"MAP n\xF1",
+ \"MAP c\xE7",
+ \"MAP y\xFF\xFD",
+ \"MAP s\xDF",
+ \ ]
+let g:test_data_dic1 = [
+ \"123456",
+ \"test/NO",
+ \"# comment",
+ \"wrong",
+ \"Comment",
+ \"OK",
+ \"uk",
+ \"put/ISO",
+ \"the end",
+ \"deol",
+ \"d\xE9\xF4r",
+ \ ]
+let g:test_data_aff2 = [
+ \"SET ISO8859-1",
+ \"",
+ \"FOL \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
+ \"LOW \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
+ \"UPP \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
+ \"",
+ \"PFXPOSTPONE",
+ \"",
+ \"MIDWORD\t'-",
+ \"",
+ \"KEP =",
+ \"RAR ?",
+ \"BAD !",
+ \"",
+ \"PFX I N 1",
+ \"PFX I 0 in .",
+ \"",
+ \"PFX O Y 1",
+ \"PFX O 0 out [a-z]",
+ \"",
+ \"SFX S Y 2",
+ \"SFX S 0 s [^s]",
+ \"SFX S 0 es s",
+ \"",
+ \"SFX N N 3",
+ \"SFX N 0 en [^n]",
+ \"SFX N 0 nen n",
+ \"SFX N 0 n .",
+ \"",
+ \"REP 3",
+ \"REP g ch",
+ \"REP ch g",
+ \"REP svp s.v.p.",
+ \"",
+ \"MAP 9",
+ \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
+ \"MAP e\xE8\xE9\xEA\xEB",
+ \"MAP i\xEC\xED\xEE\xEF",
+ \"MAP o\xF2\xF3\xF4\xF5\xF6",
+ \"MAP u\xF9\xFA\xFB\xFC",
+ \"MAP n\xF1",
+ \"MAP c\xE7",
+ \"MAP y\xFF\xFD",
+ \"MAP s\xDF",
+ \ ]
+let g:test_data_aff3 = [
+ \"SET ISO8859-1",
+ \"",
+ \"COMPOUNDMIN 3",
+ \"COMPOUNDRULE m*",
+ \"NEEDCOMPOUND x",
+ \ ]
+let g:test_data_dic3 = [
+ \"1234",
+ \"foo/m",
+ \"bar/mx",
+ \"m\xEF/m",
+ \"la/mx",
+ \ ]
+let g:test_data_aff4 = [
+ \"SET ISO8859-1",
+ \"",
+ \"FOL \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
+ \"LOW \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
+ \"UPP \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
+ \"",
+ \"COMPOUNDRULE m+",
+ \"COMPOUNDRULE sm*e",
+ \"COMPOUNDRULE sm+",
+ \"COMPOUNDMIN 3",
+ \"COMPOUNDWORDMAX 3",
+ \"COMPOUNDFORBIDFLAG t",
+ \"",
+ \"COMPOUNDSYLMAX 5",
+ \"SYLLABLE a\xE1e\xE9i\xEDo\xF3\xF6\xF5u\xFA\xFC\xFBy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui",
+ \"",
+ \"MAP 9",
+ \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
+ \"MAP e\xE8\xE9\xEA\xEB",
+ \"MAP i\xEC\xED\xEE\xEF",
+ \"MAP o\xF2\xF3\xF4\xF5\xF6",
+ \"MAP u\xF9\xFA\xFB\xFC",
+ \"MAP n\xF1",
+ \"MAP c\xE7",
+ \"MAP y\xFF\xFD",
+ \"MAP s\xDF",
+ \"",
+ \"NEEDAFFIX x",
+ \"",
+ \"PFXPOSTPONE",
+ \"",
+ \"MIDWORD '-",
+ \"",
+ \"SFX q N 1",
+ \"SFX q 0 -ok .",
+ \"",
+ \"SFX a Y 2",
+ \"SFX a 0 s .",
+ \"SFX a 0 ize/t .",
+ \"",
+ \"PFX p N 1",
+ \"PFX p 0 pre .",
+ \"",
+ \"PFX P N 1",
+ \"PFX P 0 nou .",
+ \ ]
+let g:test_data_dic4 = [
+ \"1234",
+ \"word/mP",
+ \"util/am",
+ \"pro/xq",
+ \"tomato/m",
+ \"bork/mp",
+ \"start/s",
+ \"end/e",
+ \ ]
+let g:test_data_aff5 = [
+ \"SET ISO8859-1",
+ \"",
+ \"FLAG long",
+ \"",
+ \"NEEDAFFIX !!",
+ \"",
+ \"COMPOUNDRULE ssmm*ee",
+ \"",
+ \"NEEDCOMPOUND xx",
+ \"COMPOUNDPERMITFLAG pp",
+ \"",
+ \"SFX 13 Y 1",
+ \"SFX 13 0 bork .",
+ \"",
+ \"SFX a1 Y 1",
+ \"SFX a1 0 a1 .",
+ \"",
+ \"SFX a\xE9 Y 1",
+ \"SFX a\xE9 0 a\xE9 .",
+ \"",
+ \"PFX zz Y 1",
+ \"PFX zz 0 pre/pp .",
+ \"",
+ \"PFX yy Y 1",
+ \"PFX yy 0 nou .",
+ \ ]
+let g:test_data_dic5 = [
+ \"1234",
+ \"foo/a1a\xE9!!",
+ \"bar/zz13ee",
+ \"start/ss",
+ \"end/eeyy",
+ \"middle/mmxx",
+ \ ]
+let g:test_data_aff6 = [
+ \"SET ISO8859-1",
+ \"",
+ \"FLAG caplong",
+ \"",
+ \"NEEDAFFIX A!",
+ \"",
+ \"COMPOUNDRULE sMm*Ee",
+ \"",
+ \"NEEDCOMPOUND Xx",
+ \"",
+ \"COMPOUNDPERMITFLAG p",
+ \"",
+ \"SFX N3 Y 1",
+ \"SFX N3 0 bork .",
+ \"",
+ \"SFX A1 Y 1",
+ \"SFX A1 0 a1 .",
+ \"",
+ \"SFX A\xE9 Y 1",
+ \"SFX A\xE9 0 a\xE9 .",
+ \"",
+ \"PFX Zz Y 1",
+ \"PFX Zz 0 pre/p .",
+ \ ]
+let g:test_data_dic6 = [
+ \"1234",
+ \"mee/A1A\xE9A!",
+ \"bar/ZzN3Ee",
+ \"lead/s",
+ \"end/Ee",
+ \"middle/MmXx",
+ \ ]
+let g:test_data_aff7 = [
+ \"SET ISO8859-1",
+ \"",
+ \"FLAG num",
+ \"",
+ \"NEEDAFFIX 9999",
+ \"",
+ \"COMPOUNDRULE 2,77*123",
+ \"",
+ \"NEEDCOMPOUND 1",
+ \"COMPOUNDPERMITFLAG 432",
+ \"",
+ \"SFX 61003 Y 1",
+ \"SFX 61003 0 meat .",
+ \"",
+ \"SFX 391 Y 1",
+ \"SFX 391 0 a1 .",
+ \"",
+ \"SFX 111 Y 1",
+ \"SFX 111 0 a\xE9 .",
+ \"",
+ \"PFX 17 Y 1",
+ \"PFX 17 0 pre/432 .",
+ \ ]
+let g:test_data_dic7 = [
+ \"1234",
+ \"mee/391,111,9999",
+ \"bar/17,61003,123",
+ \"lead/2",
+ \"tail/123",
+ \"middle/77,1",
+ \ ]
+let g:test_data_aff8 = [
+ \"SET ISO8859-1",
+ \"",
+ \"NOSPLITSUGS",
+ \ ]
+let g:test_data_dic8 = [
+ \"1234",
+ \"foo",
+ \"bar",
+ \"faabar",
+ \ ]
+let g:test_data_aff9 = [
+ \ ]
+let g:test_data_dic9 = [
+ \"1234",
+ \"foo",
+ \"bar",
+ \ ]
+let g:test_data_aff_sal = [
+ \"SET ISO8859-1",
+ \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
+ \"",
+ \"FOL \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
+ \"LOW \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
+ \"UPP \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
+ \"",
+ \"MIDWORD\t'-",
+ \"",
+ \"KEP =",
+ \"RAR ?",
+ \"BAD !",
+ \"",
+ \"PFX I N 1",
+ \"PFX I 0 in .",
+ \"",
+ \"PFX O Y 1",
+ \"PFX O 0 out .",
+ \"",
+ \"SFX S Y 2",
+ \"SFX S 0 s [^s]",
+ \"SFX S 0 es s",
+ \"",
+ \"SFX N N 3",
+ \"SFX N 0 en [^n]",
+ \"SFX N 0 nen n",
+ \"SFX N 0 n .",
+ \"",
+ \"REP 3",
+ \"REP g ch",
+ \"REP ch g",
+ \"REP svp s.v.p.",
+ \"",
+ \"MAP 9",
+ \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
+ \"MAP e\xE8\xE9\xEA\xEB",
+ \"MAP i\xEC\xED\xEE\xEF",
+ \"MAP o\xF2\xF3\xF4\xF5\xF6",
+ \"MAP u\xF9\xFA\xFB\xFC",
+ \"MAP n\xF1",
+ \"MAP c\xE7",
+ \"MAP y\xFF\xFD",
+ \"MAP s\xDF",
+ \"",
+ \"SAL AH(AEIOUY)-^ *H",
+ \"SAL AR(AEIOUY)-^ *R",
+ \"SAL A(HR)^ *",
+ \"SAL A^ *",
+ \"SAL AH(AEIOUY)- H",
+ \"SAL AR(AEIOUY)- R",
+ \"SAL A(HR) _",
+ \"SAL \xC0^ *",
+ \"SAL \xC5^ *",
+ \"SAL BB- _",
+ \"SAL B B",
+ \"SAL CQ- _",
+ \"SAL CIA X",
+ \"SAL CH X",
+ \"SAL C(EIY)- S",
+ \"SAL CK K",
+ \"SAL COUGH^ KF",
+ \"SAL CC< C",
+ \"SAL C K",
+ \"SAL DG(EIY) K",
+ \"SAL DD- _",
+ \"SAL D T",
+ \"SAL \xC9< E",
+ \"SAL EH(AEIOUY)-^ *H",
+ \"SAL ER(AEIOUY)-^ *R",
+ \"SAL E(HR)^ *",
+ \"SAL ENOUGH^$ *NF",
+ \"SAL E^ *",
+ \"SAL EH(AEIOUY)- H",
+ \"SAL ER(AEIOUY)- R",
+ \"SAL E(HR) _",
+ \"SAL FF- _",
+ \"SAL F F",
+ \"SAL GN^ N",
+ \"SAL GN$ N",
+ \"SAL GNS$ NS",
+ \"SAL GNED$ N",
+ \"SAL GH(AEIOUY)- K",
+ \"SAL GH _",
+ \"SAL GG9 K",
+ \"SAL G K",
+ \"SAL H H",
+ \"SAL IH(AEIOUY)-^ *H",
+ \"SAL IR(AEIOUY)-^ *R",
+ \"SAL I(HR)^ *",
+ \"SAL I^ *",
+ \"SAL ING6 N",
+ \"SAL IH(AEIOUY)- H",
+ \"SAL IR(AEIOUY)- R",
+ \"SAL I(HR) _",
+ \"SAL J K",
+ \"SAL KN^ N",
+ \"SAL KK- _",
+ \"SAL K K",
+ \"SAL LAUGH^ LF",
+ \"SAL LL- _",
+ \"SAL L L",
+ \"SAL MB$ M",
+ \"SAL MM M",
+ \"SAL M M",
+ \"SAL NN- _",
+ \"SAL N N",
+ \"SAL OH(AEIOUY)-^ *H",
+ \"SAL OR(AEIOUY)-^ *R",
+ \"SAL O(HR)^ *",
+ \"SAL O^ *",
+ \"SAL OH(AEIOUY)- H",
+ \"SAL OR(AEIOUY)- R",
+ \"SAL O(HR) _",
+ \"SAL PH F",
+ \"SAL PN^ N",
+ \"SAL PP- _",
+ \"SAL P P",
+ \"SAL Q K",
+ \"SAL RH^ R",
+ \"SAL ROUGH^ RF",
+ \"SAL RR- _",
+ \"SAL R R",
+ \"SAL SCH(EOU)- SK",
+ \"SAL SC(IEY)- S",
+ \"SAL SH X",
+ \"SAL SI(AO)- X",
+ \"SAL SS- _",
+ \"SAL S S",
+ \"SAL TI(AO)- X",
+ \"SAL TH @",
+ \"SAL TCH-- _",
+ \"SAL TOUGH^ TF",
+ \"SAL TT- _",
+ \"SAL T T",
+ \"SAL UH(AEIOUY)-^ *H",
+ \"SAL UR(AEIOUY)-^ *R",
+ \"SAL U(HR)^ *",
+ \"SAL U^ *",
+ \"SAL UH(AEIOUY)- H",
+ \"SAL UR(AEIOUY)- R",
+ \"SAL U(HR) _",
+ \"SAL V^ W",
+ \"SAL V F",
+ \"SAL WR^ R",
+ \"SAL WH^ W",
+ \"SAL W(AEIOU)- W",
+ \"SAL X^ S",
+ \"SAL X KS",
+ \"SAL Y(AEIOU)- Y",
+ \"SAL ZZ- _",
+ \"SAL Z S",
+ \ ]
diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim
new file mode 100644
index 0000000000..3bc9eaf756
--- /dev/null
+++ b/src/nvim/testdir/test_startup.vim
@@ -0,0 +1,367 @@
+" Tests for startup.
+
+source shared.vim
+
+" Check that loading startup.vim works.
+func Test_startup_script()
+ throw 'skipped: Nvim does not need defaults.vim'
+ set compatible
+ source $VIMRUNTIME/defaults.vim
+
+ call assert_equal(0, &compatible)
+endfunc
+
+" Verify the order in which plugins are loaded:
+" 1. plugins in non-after directories
+" 2. packages
+" 3. plugins in after directories
+func Test_after_comes_later()
+ if !has('packages')
+ return
+ endif
+ let before = [
+ \ 'set nocp viminfo+=nviminfo',
+ \ 'set guioptions+=M',
+ \ 'let $HOME = "/does/not/exist"',
+ \ 'set loadplugins',
+ \ 'set rtp=Xhere,Xafter,Xanother',
+ \ 'set packpath=Xhere,Xafter',
+ \ 'set nomore',
+ \ 'let g:sequence = ""',
+ \ ]
+ let after = [
+ \ 'redir! > Xtestout',
+ \ 'scriptnames',
+ \ 'redir END',
+ \ 'redir! > Xsequence',
+ \ 'echo g:sequence',
+ \ 'redir END',
+ \ 'quit',
+ \ ]
+ call mkdir('Xhere/plugin', 'p')
+ call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim')
+ call mkdir('Xanother/plugin', 'p')
+ call writefile(['let g:sequence .= "another "'], 'Xanother/plugin/another.vim')
+ call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p')
+ call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim')
+
+ call mkdir('Xafter/plugin', 'p')
+ call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim')
+
+ if RunVim(before, after, '')
+
+ let lines = readfile('Xtestout')
+ let expected = ['Xbefore.vim', 'here.vim', 'another.vim', 'foo.vim', 'later.vim', 'Xafter.vim']
+ let found = []
+ for line in lines
+ for one in expected
+ if line =~ one
+ call add(found, one)
+ endif
+ endfor
+ endfor
+ call assert_equal(expected, found)
+ endif
+
+ call assert_equal('here another pack after', substitute(join(readfile('Xsequence', 1), ''), '\s\+$', '', ''))
+
+ call delete('Xtestout')
+ call delete('Xsequence')
+ call delete('Xhere', 'rf')
+ call delete('Xanother', 'rf')
+ call delete('Xafter', 'rf')
+endfunc
+
+func Test_pack_in_rtp_when_plugins_run()
+ if !has('packages')
+ return
+ endif
+ let before = [
+ \ 'set nocp viminfo+=nviminfo',
+ \ 'set guioptions+=M',
+ \ 'let $HOME = "/does/not/exist"',
+ \ 'set loadplugins',
+ \ 'set rtp=Xhere',
+ \ 'set packpath=Xhere',
+ \ 'set nomore',
+ \ ]
+ let after = [
+ \ 'quit',
+ \ ]
+ call mkdir('Xhere/plugin', 'p')
+ call writefile(['redir! > Xtestout', 'silent set runtimepath?', 'silent! call foo#Trigger()', 'redir END'], 'Xhere/plugin/here.vim')
+ call mkdir('Xhere/pack/foo/start/foobar/autoload', 'p')
+ call writefile(['function! foo#Trigger()', 'echo "autoloaded foo"', 'endfunction'], 'Xhere/pack/foo/start/foobar/autoload/foo.vim')
+
+ if RunVim(before, after, '')
+
+ let lines = filter(readfile('Xtestout'), '!empty(v:val)')
+ call assert_match('Xhere[/\\]pack[/\\]foo[/\\]start[/\\]foobar', get(lines, 0))
+ call assert_match('autoloaded foo', get(lines, 1))
+ endif
+
+ call delete('Xtestout')
+ call delete('Xhere', 'rf')
+endfunc
+
+func Test_help_arg()
+ if !has('unix') && has('gui')
+ " this doesn't work with gvim on MS-Windows
+ return
+ endif
+ if RunVim([], [], '--help >Xtestout')
+ let lines = readfile('Xtestout')
+ call assert_true(len(lines) > 20)
+ call assert_match('Usage:', lines[0])
+
+ " check if couple of lines are there
+ let found = []
+ for line in lines
+ if line =~ '-R.*Read-only mode'
+ call add(found, 'Readonly mode')
+ endif
+ " Watch out for a second --version line in the Gnome version.
+ if line =~ '--version.*Print version information'
+ call add(found, "--version")
+ endif
+ endfor
+ call assert_equal(['Readonly mode', '--version'], found)
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_compatible_args()
+ throw "skipped: Nvim is always 'nocompatible'"
+ let after = [
+ \ 'call writefile([string(&compatible)], "Xtestout")',
+ \ 'set viminfo+=nviminfo',
+ \ 'quit',
+ \ ]
+ if RunVim([], after, '-C')
+ let lines = readfile('Xtestout')
+ call assert_equal('1', lines[0])
+ endif
+
+ if RunVim([], after, '-N')
+ let lines = readfile('Xtestout')
+ call assert_equal('0', lines[0])
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+" Test the -o[N] and -O[N] arguments to open N windows split
+" horizontally or vertically.
+func Test_o_arg()
+ let after = [
+ \ 'call writefile([winnr("$"),
+ \ winheight(1), winheight(2), &lines,
+ \ winwidth(1), winwidth(2), &columns,
+ \ bufname(winbufnr(1)), bufname(winbufnr(2))],
+ \ "Xtestout")',
+ \ 'qall',
+ \ ]
+ if RunVim([], after, '-o2')
+ " Open 2 windows split horizontally. Expect:
+ " - 2 windows
+ " - both windows should have the same or almost the same height
+ " - sum of both windows height (+ 3 for both statusline and Ex command)
+ " should be equal to the number of lines
+ " - both windows should have the same width which should be equal to the
+ " number of columns
+ " - buffer of both windows should have no name
+ let [wn, wh1, wh2, ln, ww1, ww2, cn, bn1, bn2] = readfile('Xtestout')
+ call assert_equal('2', wn)
+ call assert_inrange(0, 1, wh1 - wh2)
+ call assert_equal(string(wh1 + wh2 + 3), ln)
+ call assert_equal(ww1, ww2)
+ call assert_equal(ww1, cn)
+ call assert_equal('', bn1)
+ call assert_equal('', bn2)
+ endif
+
+ if RunVim([], after, '-o foo bar')
+ " Same expectations as for -o2 but buffer names should be foo and bar
+ let [wn, wh1, wh2, ln, ww1, ww2, cn, bn1, bn2] = readfile('Xtestout')
+ call assert_equal('2', wn)
+ call assert_inrange(0, 1, wh1 - wh2)
+ call assert_equal(string(wh1 + wh2 + 3), ln)
+ call assert_equal(ww1, ww2)
+ call assert_equal(ww1, cn)
+ call assert_equal('foo', bn1)
+ call assert_equal('bar', bn2)
+ endif
+
+ if RunVim([], after, '-O2')
+ " Open 2 windows split vertically. Expect:
+ " - 2 windows
+ " - both windows should have the same or almost the same width
+ " - sum of both windows width (+ 1 separator) should be equal to the
+ " number of columns
+ " - both windows should have the same height
+ " - window height (+ 2 for the statusline and Ex command) should be equal
+ " to the number of lines
+ " - buffer of both windowns should have no name
+ let [wn, wh1, wh2, ln, ww1, ww2, cn, bn1, bn2] = readfile('Xtestout')
+ call assert_equal('2', wn)
+ call assert_inrange(0, 1, ww1 - ww2)
+ call assert_equal(string(ww1 + ww2 + 1), cn)
+ call assert_equal(wh1, wh2)
+ call assert_equal(string(wh1 + 2), ln)
+ call assert_equal('', bn1)
+ call assert_equal('', bn2)
+ endif
+
+ if RunVim([], after, '-O foo bar')
+ " Same expectations as for -O2 but buffer names should be foo and bar
+ let [wn, wh1, wh2, ln, ww1, ww2, cn, bn1, bn2] = readfile('Xtestout')
+ call assert_equal('2', wn)
+ call assert_inrange(0, 1, ww1 - ww2)
+ call assert_equal(string(ww1 + ww2 + 1), cn)
+ call assert_equal(wh1, wh2)
+ call assert_equal(string(wh1 + 2), ln)
+ call assert_equal('foo', bn1)
+ call assert_equal('bar', bn2)
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+func Test_file_args()
+ let after = [
+ \ 'call writefile(argv(), "Xtestout")',
+ \ 'qall',
+ \ ]
+ if RunVim([], after, '')
+ let lines = readfile('Xtestout')
+ call assert_equal(0, len(lines))
+ endif
+
+ if RunVim([], after, 'one')
+ let lines = readfile('Xtestout')
+ call assert_equal(1, len(lines))
+ call assert_equal('one', lines[0])
+ endif
+
+ if RunVim([], after, 'one two three')
+ let lines = readfile('Xtestout')
+ call assert_equal(3, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('two', lines[1])
+ call assert_equal('three', lines[2])
+ endif
+
+ if RunVim([], after, 'one -c echo two')
+ let lines = readfile('Xtestout')
+ call assert_equal(2, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('two', lines[1])
+ endif
+
+ if RunVim([], after, 'one -- -c echo two')
+ let lines = readfile('Xtestout')
+ call assert_equal(4, len(lines))
+ call assert_equal('one', lines[0])
+ call assert_equal('-c', lines[1])
+ call assert_equal('echo', lines[2])
+ call assert_equal('two', lines[3])
+ endif
+
+ call delete('Xtestout')
+endfunc
+
+func Test_startuptime()
+ if !has('startuptime')
+ return
+ endif
+ let after = ['qall']
+ if RunVim([], after, '--startuptime Xtestout one')
+ let lines = readfile('Xtestout')
+ let expected = ['parsing arguments', 'inits 3', 'opening buffers']
+ let found = []
+ for line in lines
+ for exp in expected
+ if line =~ exp
+ call add(found, exp)
+ endif
+ endfor
+ endfor
+ call assert_equal(expected, found)
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_read_stdin()
+ let after = [
+ \ 'write Xtestout',
+ \ 'quit!',
+ \ ]
+ if RunVimPiped([], after, '-', 'echo something | ')
+ let lines = readfile('Xtestout')
+ " MS-Windows adds a space after the word
+ call assert_equal(['something'], split(lines[0]))
+ endif
+ call delete('Xtestout')
+endfunc
+
+func Test_progpath()
+ " Tests normally run with "./vim" or "../vim", these must have been expanded
+ " to a full path.
+ if has('unix')
+ call assert_equal('/', v:progpath[0])
+ elseif has('win32')
+ call assert_equal(':', v:progpath[1])
+ call assert_match('[/\\]', v:progpath[2])
+ endif
+
+ " Only expect "vim" to appear in v:progname.
+ call assert_match('vim\c', v:progname)
+endfunc
+
+func Test_silent_ex_mode()
+ if !has('unix') || has('gui_running')
+ " can't get output of Vim.
+ return
+ endif
+
+ " This caused an ml_get error.
+ let out = system(GetVimCommand() . ' -u NONE -es -c''set verbose=1|h|exe "%norm\<c-y>\<c-d>"'' -c cq')
+ call assert_notmatch('E315:', out)
+endfunc
+
+func Test_default_term()
+ if !has('unix') || has('gui_running')
+ " can't get output of Vim.
+ return
+ endif
+
+ let save_term = $TERM
+ let $TERM = 'unknownxxx'
+ let out = system(GetVimCommand() . ' -c ''echo &term'' -c cq')
+ call assert_match('nvim', out)
+ let $TERM = save_term
+endfunc
+
+func Test_zzz_startinsert()
+ " Test :startinsert
+ call writefile(['123456'], 'Xtestout')
+ let after = [
+ \ ':startinsert',
+ \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")'
+ \ ]
+ if RunVim([], after, 'Xtestout')
+ let lines = readfile('Xtestout')
+ call assert_equal(['foobar123456'], lines)
+ endif
+ " Test :startinsert!
+ call writefile(['123456'], 'Xtestout')
+ let after = [
+ \ ':startinsert!',
+ \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")'
+ \ ]
+ if RunVim([], after, 'Xtestout')
+ let lines = readfile('Xtestout')
+ call assert_equal(['123456foobar'], lines)
+ endif
+ call delete('Xtestout')
+endfunc
diff --git a/src/nvim/testdir/test_startup_utf8.vim b/src/nvim/testdir/test_startup_utf8.vim
new file mode 100644
index 0000000000..d179a4cc79
--- /dev/null
+++ b/src/nvim/testdir/test_startup_utf8.vim
@@ -0,0 +1,64 @@
+" Tests for startup using utf-8.
+if !has('multi_byte')
+ finish
+endif
+
+source shared.vim
+
+func Test_read_stdin_utf8()
+ let linesin = ['テスト', '€ÀÈÌÒÙ']
+ call writefile(linesin, 'Xtestin')
+ let before = [
+ \ 'set enc=utf-8',
+ \ 'set fencs=cp932,utf-8',
+ \ ]
+ let after = [
+ \ 'write ++enc=utf-8 Xtestout',
+ \ 'quit!',
+ \ ]
+ if has('win32')
+ let pipecmd = 'type Xtestin | '
+ else
+ let pipecmd = 'cat Xtestin | '
+ endif
+ if RunVimPiped(before, after, '-', pipecmd)
+ let lines = readfile('Xtestout')
+ call assert_equal(linesin, lines)
+ else
+ call assert_equal('', 'RunVimPiped failed.')
+ endif
+ call delete('Xtestout')
+ call delete('Xtestin')
+endfunc
+
+func Test_read_fifo_utf8()
+ if !has('unix')
+ return
+ endif
+ " Using bash/zsh's process substitution.
+ if executable('bash')
+ set shell=bash
+ elseif executable('zsh')
+ set shell=zsh
+ else
+ return
+ endif
+ let linesin = ['テスト', '€ÀÈÌÒÙ']
+ call writefile(linesin, 'Xtestin')
+ let before = [
+ \ 'set enc=utf-8',
+ \ 'set fencs=cp932,utf-8',
+ \ ]
+ let after = [
+ \ 'write ++enc=utf-8 Xtestout',
+ \ 'quit!',
+ \ ]
+ if RunVim(before, after, '<(cat Xtestin)')
+ let lines = readfile('Xtestout')
+ call assert_equal(linesin, lines)
+ else
+ call assert_equal('', 'RunVim failed.')
+ endif
+ call delete('Xtestout')
+ call delete('Xtestin')
+endfunc
diff --git a/src/nvim/testdir/test_stat.vim b/src/nvim/testdir/test_stat.vim
new file mode 100644
index 0000000000..253f74c2ad
--- /dev/null
+++ b/src/nvim/testdir/test_stat.vim
@@ -0,0 +1,185 @@
+" Tests for stat functions and checktime
+
+func CheckFileTime(doSleep)
+ let fnames = ['Xtest1.tmp', 'Xtest2.tmp', 'Xtest3.tmp']
+ let times = []
+ let result = 0
+
+ " Use three files istead of localtim(), with a network filesystem the file
+ " times may differ at bit
+ let fl = ['Hello World!']
+ for fname in fnames
+ call writefile(fl, fname)
+ call add(times, getftime(fname))
+ if a:doSleep
+ sleep 1
+ endif
+ endfor
+
+ let time_correct = (times[0] <= times[1] && times[1] <= times[2])
+ if a:doSleep || time_correct
+ call assert_true(time_correct, printf('Expected %s <= %s <= %s', times[0], times[1], times[2]))
+ call assert_equal(strlen(fl[0] . "\n"), getfsize(fnames[0]))
+ call assert_equal('file', getftype(fnames[0]))
+ call assert_equal('rw-', getfperm(fnames[0])[0:2])
+ let result = 1
+ endif
+
+ for fname in fnames
+ call delete(fname)
+ endfor
+ return result
+endfunc
+
+func Test_existent_file()
+ " On some systems the file timestamp is rounded to a multiple of 2 seconds.
+ " We need to sleep to handle that, but that makes the test slow. First try
+ " without the sleep, and if it fails try again with the sleep.
+ if CheckFileTime(0) == 0
+ call CheckFileTime(1)
+ endif
+endfunc
+
+func Test_existent_directory()
+ let dname = '.'
+
+ call assert_equal(0, getfsize(dname))
+ call assert_equal('dir', getftype(dname))
+ call assert_equal(has('win32') ? 'rw-' : 'rwx', getfperm(dname)[0:2])
+endfunc
+
+func SleepForTimestamp()
+ " FAT has a granularity of 2 seconds, otherwise it's usually 1 second
+ if has('win32')
+ sleep 2
+ else
+ sleep 2
+ endif
+endfunc
+
+func Test_checktime()
+ let fname = 'Xtest.tmp'
+
+ let fl = ['Hello World!']
+ call writefile(fl, fname)
+ set autoread
+ exec 'e' fname
+ call SleepForTimestamp()
+ let fl = readfile(fname)
+ let fl[0] .= ' - checktime'
+ call writefile(fl, fname)
+ checktime
+ call assert_equal(fl[0], getline(1))
+
+ call delete(fname)
+endfunc
+
+func Test_autoread_file_deleted()
+ new Xautoread
+ set autoread
+ call setline(1, 'original')
+ w!
+
+ call SleepForTimestamp()
+ if has('win32')
+ silent !echo changed > Xautoread
+ else
+ silent !echo 'changed' > Xautoread
+ endif
+ checktime
+ call assert_equal('changed', trim(getline(1)))
+
+ call SleepForTimestamp()
+ messages clear
+ if has('win32')
+ silent !del Xautoread
+ else
+ silent !rm Xautoread
+ endif
+ checktime
+ call assert_match('E211:', execute('messages'))
+ call assert_equal('changed', trim(getline(1)))
+
+ call SleepForTimestamp()
+ if has('win32')
+ silent !echo recreated > Xautoread
+ else
+ silent !echo 'recreated' > Xautoread
+ endif
+ checktime
+ call assert_equal('recreated', trim(getline(1)))
+
+ call delete('Xautoread')
+ bwipe!
+endfunc
+
+
+func Test_nonexistent_file()
+ let fname = 'Xtest.tmp'
+
+ call delete(fname)
+ call assert_equal(-1, getftime(fname))
+ call assert_equal(-1, getfsize(fname))
+ call assert_equal('', getftype(fname))
+ call assert_equal('', getfperm(fname))
+endfunc
+
+func Test_getftype()
+ call assert_equal('file', getftype(v:progpath))
+ call assert_equal('dir', getftype('.'))
+
+ if !has('unix')
+ return
+ endif
+
+ silent !ln -s Xfile Xlink
+ call assert_equal('link', getftype('Xlink'))
+ call delete('Xlink')
+
+ if executable('mkfifo')
+ silent !mkfifo Xfifo
+ call assert_equal('fifo', getftype('Xfifo'))
+ call delete('Xfifo')
+ endif
+
+ for cdevfile in systemlist('find /dev -type c -maxdepth 2 2>/dev/null')
+ let type = getftype(cdevfile)
+ " ignore empty result, can happen if the file disappeared
+ if type != ''
+ call assert_equal('cdev', type)
+ endif
+ endfor
+
+ for bdevfile in systemlist('find /dev -type b -maxdepth 2 2>/dev/null')
+ let type = getftype(bdevfile)
+ " ignore empty result, can happen if the file disappeared
+ if type != ''
+ call assert_equal('bdev', type)
+ endif
+ endfor
+
+ " The /run/ directory typically contains socket files.
+ " If it does not, test won't fail but will not test socket files.
+ for socketfile in systemlist('find /run -type s -maxdepth 2 2>/dev/null')
+ let type = getftype(socketfile)
+ " ignore empty result, can happen if the file disappeared
+ if type != ''
+ call assert_equal('socket', type)
+ endif
+ endfor
+
+ " TODO: file type 'other' is not tested. How can we test it?
+endfunc
+
+func Test_win32_symlink_dir()
+ " On Windows, non-admin users cannot create symlinks.
+ " So we use an existing symlink for this test.
+ if has('win32')
+ " Check if 'C:\Users\All Users' is a symlink to a directory.
+ let res = system('dir C:\Users /a')
+ if match(res, '\C<SYMLINKD> *All Users') >= 0
+ " Get the filetype of the symlink.
+ call assert_equal('link', getftype('C:\Users\All Users'))
+ endif
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_statusline.vim b/src/nvim/testdir/test_statusline.vim
new file mode 100644
index 0000000000..cf85bd58ac
--- /dev/null
+++ b/src/nvim/testdir/test_statusline.vim
@@ -0,0 +1,274 @@
+" Test 'statusline'
+"
+" Not tested yet:
+" %a
+" %N
+" %T
+" %X
+" %*
+
+source view_util.vim
+
+func s:get_statusline()
+ return ScreenLines(&lines - 1, &columns)[0]
+endfunc
+
+func StatuslineWithCaughtError()
+ let s:func_in_statusline_called = 1
+ try
+ call eval('unknown expression')
+ catch
+ endtry
+ return ''
+endfunc
+
+func StatuslineWithError()
+ let s:func_in_statusline_called = 1
+ call eval('unknown expression')
+ return ''
+endfunc
+
+" Function used to display syntax group.
+func SyntaxItem()
+ return synIDattr(synID(line("."),col("."),1),"name")
+endfunc
+
+func Test_caught_error_in_statusline()
+ let s:func_in_statusline_called = 0
+ set laststatus=2
+ let statusline = '%{StatuslineWithCaughtError()}'
+ let &statusline = statusline
+ redrawstatus
+ call assert_true(s:func_in_statusline_called)
+ call assert_equal(statusline, &statusline)
+ set statusline=
+endfunc
+
+func Test_statusline_will_be_disabled_with_error()
+ let s:func_in_statusline_called = 0
+ set laststatus=2
+ let statusline = '%{StatuslineWithError()}'
+ try
+ let &statusline = statusline
+ redrawstatus
+ catch
+ endtry
+ call assert_true(s:func_in_statusline_called)
+ call assert_equal('', &statusline)
+ set statusline=
+endfunc
+
+func Test_statusline()
+ new Xstatusline
+ only
+ set laststatus=2
+ set splitbelow
+ call setline(1, range(1, 200))
+
+ " %b: Value of character under cursor.
+ " %B: As above, in hexadecimal.
+ call cursor(180, 2)
+ set statusline=%b,%B
+ call assert_match('^56,38\s*$', s:get_statusline())
+
+ " %o: Byte number in file of byte under cursor, first byte is 1.
+ " %O: As above, in hexadecimal.
+ set statusline=%o,%O
+ set fileformat=dos
+ call assert_match('^789,315\s*$', s:get_statusline())
+ set fileformat=mac
+ call assert_match('^610,262\s*$', s:get_statusline())
+ set fileformat=unix
+ call assert_match('^610,262\s*$', s:get_statusline())
+ set fileformat&
+
+ " %f: Path to the file in the buffer, as typed or relative to current dir.
+ set statusline=%f
+ call assert_match('^Xstatusline\s*$', s:get_statusline())
+
+ " %F: Full path to the file in the buffer.
+ set statusline=%F
+ call assert_match('/testdir/Xstatusline\s*$', s:get_statusline())
+
+ " %h: Help buffer flag, text is "[help]".
+ " %H: Help buffer flag, text is ",HLP".
+ set statusline=%h,%H
+ call assert_match('^,\s*$', s:get_statusline())
+ help
+ call assert_match('^\[Help\],HLP\s*$', s:get_statusline())
+ helpclose
+
+ " %k: Value of "b:keymap_name" or 'keymap'
+ " when :lmap mappings are being used: <keymap>"
+ set statusline=%k
+ if has('keymap')
+ set keymap=esperanto
+ call assert_match('^<Eo>\s*$', s:get_statusline())
+ set keymap&
+ else
+ call assert_match('^\s*$', s:get_statusline())
+ endif
+
+ " %l: Line number.
+ " %L: Number of line in buffer.
+ " %c: Column number.
+ set statusline=%l/%L,%c
+ call assert_match('^180/200,2\s*$', s:get_statusline())
+
+ " %m: Modified flag, text is "[+]", "[-]" if 'modifiable' is off.
+ " %M: Modified flag, text is ",+" or ",-".
+ set statusline=%m%M
+ call assert_match('^\[+\],+\s*$', s:get_statusline())
+ set nomodifiable
+ call assert_match('^\[+-\],+-\s*$', s:get_statusline())
+ write
+ call assert_match('^\[-\],-\s*$', s:get_statusline())
+ set modifiable&
+ call assert_match('^\s*$', s:get_statusline())
+
+ " %n: Buffer number.
+ set statusline=%n
+ call assert_match('^'.bufnr('%').'\s*$', s:get_statusline())
+
+ " %p: Percentage through file in lines as in CTRL-G.
+ " %P: Percentage through file of displayed window.
+ set statusline=%p,%P
+ 0
+ call assert_match('^0,Top\s*$', s:get_statusline())
+ norm G
+ call assert_match('^100,Bot\s*$', s:get_statusline())
+ 180
+ " Don't check the exact percentage as it depends on the window size
+ call assert_match('^90,\(Top\|Bot\|\d\+%\)\s*$', s:get_statusline())
+
+ " %q: "[Quickfix List]", "[Location List]" or empty.
+ set statusline=%q
+ call assert_match('^\s*$', s:get_statusline())
+ copen
+ call assert_match('^\[Quickfix List\]\s*$', s:get_statusline())
+ cclose
+ lexpr getline(1, 2)
+ lopen
+ call assert_match('^\[Location List\]\s*$', s:get_statusline())
+ lclose
+
+ " %r: Readonly flag, text is "[RO]".
+ " %R: Readonly flag, text is ",RO".
+ set statusline=%r,%R
+ call assert_match('^,\s*$', s:get_statusline())
+ help
+ call assert_match('^\[RO\],RO\s*$', s:get_statusline())
+ helpclose
+
+ " %t: File name (tail) of file in the buffer.
+ set statusline=%t
+ call assert_match('^Xstatusline\s*$', s:get_statusline())
+
+ " %v: Virtual column number.
+ " %V: Virtual column number as -{num}. Not displayed if equal to 'c'.
+ call cursor(180, 2)
+ set statusline=%v,%V
+ call assert_match('^2,\s*$', s:get_statusline())
+ set virtualedit=all
+ norm 10|
+ call assert_match('^10,-10\s*$', s:get_statusline())
+ set virtualedit&
+
+ " %w: Preview window flag, text is "[Preview]".
+ " %W: Preview window flag, text is ",PRV".
+ set statusline=%w%W
+ call assert_match('^\s*$', s:get_statusline())
+ pedit
+ wincmd j
+ call assert_match('^\[Preview\],PRV\s*$', s:get_statusline())
+ pclose
+
+ " %y: Type of file in the buffer, e.g., "[vim]". See 'filetype'.
+ " %Y: Type of file in the buffer, e.g., ",VIM". See 'filetype'.
+ set statusline=%y\ %Y
+ call assert_match('^\s*$', s:get_statusline())
+ setfiletype vim
+ call assert_match('^\[vim\] VIM\s*$', s:get_statusline())
+
+ " %=: Separation point between left and right aligned items.
+ set statusline=foo%=bar
+ call assert_match('^foo\s\+bar\s*$', s:get_statusline())
+
+ " Test min/max width, leading zeroes, left/right justify.
+ set statusline=%04B
+ call cursor(180, 2)
+ call assert_match('^0038\s*$', s:get_statusline())
+ set statusline=#%4B#
+ call assert_match('^# 38#\s*$', s:get_statusline())
+ set statusline=#%-4B#
+ call assert_match('^#38 #\s*$', s:get_statusline())
+ set statusline=%.6f
+ call assert_match('^<sline\s*$', s:get_statusline())
+
+ " %<: Where to truncate.
+ exe 'set statusline=a%<b' . repeat('c', 1000) . 'd'
+ call assert_match('^a<c*d$', s:get_statusline())
+ exe 'set statusline=a' . repeat('b', 1000) . '%<c'
+ call assert_match('^ab*>$', s:get_statusline())
+
+ "%{: Evaluate expression between '%{' and '}' and substitute result.
+ syntax on
+ set statusline=%{SyntaxItem()}
+ call assert_match('^vimNumber\s*$', s:get_statusline())
+ s/^/"/
+ call assert_match('^vimLineComment\s*$', s:get_statusline())
+ syntax off
+
+ "%(: Start of item group.
+ set statusline=ab%(cd%q%)de
+ call assert_match('^abde\s*$', s:get_statusline())
+ copen
+ call assert_match('^abcd\[Quickfix List\1]de\s*$', s:get_statusline())
+ cclose
+
+ " %#: Set highlight group. The name must follow and then a # again.
+ set statusline=ab%#Todo#cd%#Error#ef
+ call assert_match('^abcdef\s*$', s:get_statusline())
+ let sa1=screenattr(&lines - 1, 1)
+ let sa2=screenattr(&lines - 1, 3)
+ let sa3=screenattr(&lines - 1, 5)
+ call assert_notequal(sa1, sa2)
+ call assert_notequal(sa1, sa3)
+ call assert_notequal(sa2, sa3)
+ call assert_equal(sa1, screenattr(&lines - 1, 2))
+ call assert_equal(sa2, screenattr(&lines - 1, 4))
+ call assert_equal(sa3, screenattr(&lines - 1, 6))
+ call assert_equal(sa3, screenattr(&lines - 1, 7))
+
+ " %*: Set highlight group to User{N}
+ set statusline=a%1*b%0*c
+ call assert_match('^abc\s*$', s:get_statusline())
+ let sa1=screenattr(&lines - 1, 1)
+ let sa2=screenattr(&lines - 1, 2)
+ let sa3=screenattr(&lines - 1, 3)
+ call assert_equal(sa1, sa3)
+ call assert_notequal(sa1, sa2)
+
+ " %%: a percent sign.
+ set statusline=10%%
+ call assert_match('^10%\s*$', s:get_statusline())
+
+ " %!: evaluated expression is used as the option value
+ set statusline=%!2*3+1
+ call assert_match('7\s*$', s:get_statusline())
+
+ " Check statusline in current and non-current window
+ " with the 'fillchars' option.
+ set fillchars=stl:^,stlnc:=,vert:\|,fold:-,diff:-
+ vsplit
+ set statusline=x%=y
+ call assert_match('^x^\+y^x=\+y$', s:get_statusline())
+ set fillchars&
+ close
+
+ %bw!
+ call delete('Xstatusline')
+ set statusline&
+ set laststatus&
+ set splitbelow&
+endfunc
diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim
new file mode 100644
index 0000000000..dbd26be089
--- /dev/null
+++ b/src/nvim/testdir/test_substitute.vim
@@ -0,0 +1,503 @@
+" Tests for multi-line regexps with ":s".
+
+function! Test_multiline_subst()
+ enew!
+ call append(0, ["1 aa",
+ \ "bb",
+ \ "cc",
+ \ "2 dd",
+ \ "ee",
+ \ "3 ef",
+ \ "gh",
+ \ "4 ij",
+ \ "5 a8",
+ \ "8b c9",
+ \ "9d",
+ \ "6 e7",
+ \ "77f",
+ \ "xxxxx"])
+
+ 1
+ " test if replacing a line break works with a back reference
+ /^1/,/^2/s/\n\(.\)/ \1/
+ " test if inserting a line break works with a back reference
+ /^3/,/^4/s/\(.\)$/\r\1/
+ " test if replacing a line break with another line break works
+ /^5/,/^6/s/\(\_d\{3}\)/x\1x/
+ call assert_equal('1 aa bb cc 2 dd ee', getline(1))
+ call assert_equal('3 e', getline(2))
+ call assert_equal('f', getline(3))
+ call assert_equal('g', getline(4))
+ call assert_equal('h', getline(5))
+ call assert_equal('4 i', getline(6))
+ call assert_equal('j', getline(7))
+ call assert_equal('5 ax8', getline(8))
+ call assert_equal('8xb cx9', getline(9))
+ call assert_equal('9xd', getline(10))
+ call assert_equal('6 ex7', getline(11))
+ call assert_equal('7x7f', getline(12))
+ call assert_equal('xxxxx', getline(13))
+ enew!
+endfunction
+
+function! Test_substitute_variants()
+ " Validate that all the 2-/3-letter variants which embed the flags into the
+ " command name actually work.
+ enew!
+ let ln = 'Testing string'
+ let variants = [
+ \ { 'cmd': ':s/Test/test/c', 'exp': 'testing string', 'prompt': 'y' },
+ \ { 'cmd': ':s/foo/bar/ce', 'exp': ln },
+ \ { 'cmd': ':s/t/r/cg', 'exp': 'Tesring srring', 'prompt': 'a' },
+ \ { 'cmd': ':s/t/r/ci', 'exp': 'resting string', 'prompt': 'y' },
+ \ { 'cmd': ':s/t/r/cI', 'exp': 'Tesring string', 'prompt': 'y' },
+ \ { 'cmd': ':s/t/r/cn', 'exp': ln },
+ \ { 'cmd': ':s/t/r/cp', 'exp': 'Tesring string', 'prompt': 'y' },
+ \ { 'cmd': ':s/t/r/cl', 'exp': 'Tesring string', 'prompt': 'y' },
+ \ { 'cmd': ':s/t/r/gc', 'exp': 'Tesring srring', 'prompt': 'a' },
+ \ { 'cmd': ':s/foo/bar/ge', 'exp': ln },
+ \ { 'cmd': ':s/t/r/g', 'exp': 'Tesring srring' },
+ \ { 'cmd': ':s/t/r/gi', 'exp': 'resring srring' },
+ \ { 'cmd': ':s/t/r/gI', 'exp': 'Tesring srring' },
+ \ { 'cmd': ':s/t/r/gn', 'exp': ln },
+ \ { 'cmd': ':s/t/r/gp', 'exp': 'Tesring srring' },
+ \ { 'cmd': ':s/t/r/gl', 'exp': 'Tesring srring' },
+ \ { 'cmd': ':s//r/gr', 'exp': 'Testr strr' },
+ \ { 'cmd': ':s/t/r/ic', 'exp': 'resting string', 'prompt': 'y' },
+ \ { 'cmd': ':s/foo/bar/ie', 'exp': ln },
+ \ { 'cmd': ':s/t/r/i', 'exp': 'resting string' },
+ \ { 'cmd': ':s/t/r/iI', 'exp': 'Tesring string' },
+ \ { 'cmd': ':s/t/r/in', 'exp': ln },
+ \ { 'cmd': ':s/t/r/ip', 'exp': 'resting string' },
+ \ { 'cmd': ':s//r/ir', 'exp': 'Testr string' },
+ \ { 'cmd': ':s/t/r/Ic', 'exp': 'Tesring string', 'prompt': 'y' },
+ \ { 'cmd': ':s/foo/bar/Ie', 'exp': ln },
+ \ { 'cmd': ':s/t/r/Ig', 'exp': 'Tesring srring' },
+ \ { 'cmd': ':s/t/r/Ii', 'exp': 'resting string' },
+ \ { 'cmd': ':s/t/r/I', 'exp': 'Tesring string' },
+ \ { 'cmd': ':s/t/r/Ip', 'exp': 'Tesring string' },
+ \ { 'cmd': ':s/t/r/Il', 'exp': 'Tesring string' },
+ \ { 'cmd': ':s//r/Ir', 'exp': 'Testr string' },
+ \ { 'cmd': ':s//r/rc', 'exp': 'Testr string', 'prompt': 'y' },
+ \ { 'cmd': ':s//r/rg', 'exp': 'Testr strr' },
+ \ { 'cmd': ':s//r/ri', 'exp': 'Testr string' },
+ \ { 'cmd': ':s//r/rI', 'exp': 'Testr string' },
+ \ { 'cmd': ':s//r/rn', 'exp': 'Testing string' },
+ \ { 'cmd': ':s//r/rp', 'exp': 'Testr string' },
+ \ { 'cmd': ':s//r/rl', 'exp': 'Testr string' },
+ \ { 'cmd': ':s//r/r', 'exp': 'Testr string' },
+ \]
+
+ for var in variants
+ for run in [1, 2]
+ let cmd = var.cmd
+ if run == 2 && cmd =~ "/.*/.*/."
+ " Change :s/from/to/{flags} to :s{flags}
+ let cmd = substitute(cmd, '/.*/', '', '')
+ endif
+ call setline(1, [ln])
+ let msg = printf('using "%s"', cmd)
+ let @/='ing'
+ let v:errmsg = ''
+ call feedkeys(cmd . "\<CR>" . get(var, 'prompt', ''), 'ntx')
+ " No error should exist (matters for testing e flag)
+ call assert_equal('', v:errmsg, msg)
+ call assert_equal(var.exp, getline('.'), msg)
+ endfor
+ endfor
+endfunction
+
+func Test_substitute_repeat()
+ " This caused an invalid memory access.
+ split Xfile
+ s/^/x
+ call feedkeys("Qsc\<CR>y", 'tx')
+ bwipe!
+endfunc
+
+" Tests for *sub-replace-special* and *sub-replace-expression* on :substitute.
+
+" Execute a list of :substitute command tests
+func Run_SubCmd_Tests(tests)
+ enew!
+ for t in a:tests
+ let start = line('.') + 1
+ let end = start + len(t[2]) - 1
+ exe "normal o" . t[0]
+ call cursor(start, 1)
+ exe t[1]
+ call assert_equal(t[2], getline(start, end), t[1])
+ endfor
+ enew!
+endfunc
+
+func Test_sub_cmd_1()
+ set magic
+ set cpo&
+
+ " List entry format: [input, cmd, output]
+ let tests = [['A', 's/A/&&/', ['AA']],
+ \ ['B', 's/B/\&/', ['&']],
+ \ ['C123456789', 's/C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\0\9\8\7\6\5\4\3\2\1/', ['C123456789987654321']],
+ \ ['D', 's/D/d/', ['d']],
+ \ ['E', 's/E/~/', ['d']],
+ \ ['F', 's/F/\~/', ['~']],
+ \ ['G', 's/G/\ugg/', ['Gg']],
+ \ ['H', 's/H/\Uh\Eh/', ['Hh']],
+ \ ['I', 's/I/\lII/', ['iI']],
+ \ ['J', 's/J/\LJ\EJ/', ['jJ']],
+ \ ['K', 's/K/\Uk\ek/', ['Kk']],
+ \ ['lLl', "s/L/\<C-V>\<C-M>/", ["l\<C-V>", 'l']],
+ \ ['mMm', 's/M/\r/', ['m', 'm']],
+ \ ['nNn', "s/N/\\\<C-V>\<C-M>/", ["n\<C-V>", 'n']],
+ \ ['oOo', 's/O/\n/', ["o\no"]],
+ \ ['pPp', 's/P/\b/', ["p\<C-H>p"]],
+ \ ['qQq', 's/Q/\t/', ["q\tq"]],
+ \ ['rRr', 's/R/\\/', ['r\r']],
+ \ ['sSs', 's/S/\c/', ['scs']],
+ \ ['tTt', "s/T/\<C-V>\<C-J>/", ["t\<C-V>\<C-J>t"]],
+ \ ['U', 's/U/\L\uuUu\l\EU/', ['UuuU']],
+ \ ['V', 's/V/\U\lVvV\u\Ev/', ['vVVv']]
+ \ ]
+ call Run_SubCmd_Tests(tests)
+endfunc
+
+func Test_sub_cmd_2()
+ set nomagic
+ set cpo&
+
+ " List entry format: [input, cmd, output]
+ let tests = [['A', 's/A/&&/', ['&&']],
+ \ ['B', 's/B/\&/', ['B']],
+ \ ['C123456789', 's/\mC\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\0\9\8\7\6\5\4\3\2\1/', ['C123456789987654321']],
+ \ ['D', 's/D/d/', ['d']],
+ \ ['E', 's/E/~/', ['~']],
+ \ ['F', 's/F/\~/', ['~']],
+ \ ['G', 's/G/\ugg/', ['Gg']],
+ \ ['H', 's/H/\Uh\Eh/', ['Hh']],
+ \ ['I', 's/I/\lII/', ['iI']],
+ \ ['J', 's/J/\LJ\EJ/', ['jJ']],
+ \ ['K', 's/K/\Uk\ek/', ['Kk']],
+ \ ['lLl', "s/L/\<C-V>\<C-M>/", ["l\<C-V>", 'l']],
+ \ ['mMm', 's/M/\r/', ['m', 'm']],
+ \ ['nNn', "s/N/\\\<C-V>\<C-M>/", ["n\<C-V>", 'n']],
+ \ ['oOo', 's/O/\n/', ["o\no"]],
+ \ ['pPp', 's/P/\b/', ["p\<C-H>p"]],
+ \ ['qQq', 's/Q/\t/', ["q\tq"]],
+ \ ['rRr', 's/R/\\/', ['r\r']],
+ \ ['sSs', 's/S/\c/', ['scs']],
+ \ ['tTt', "s/T/\<C-V>\<C-J>/", ["t\<C-V>\<C-J>t"]],
+ \ ['U', 's/U/\L\uuUu\l\EU/', ['UuuU']],
+ \ ['V', 's/V/\U\lVvV\u\Ev/', ['vVVv']]
+ \ ]
+ call Run_SubCmd_Tests(tests)
+endfunc
+
+func Test_sub_cmd_3()
+ set nomagic
+ set cpo&
+
+ " List entry format: [input, cmd, output]
+ let tests = [['aAa', "s/A/\\='\\'/", ['a\a']],
+ \ ['bBb', "s/B/\\='\\\\'/", ['b\\b']],
+ \ ['cCc', "s/C/\\='\<C-V>\<C-M>'/", ["c\<C-V>", 'c']],
+ \ ['dDd', "s/D/\\='\\\<C-V>\<C-M>'/", ["d\\\<C-V>", 'd']],
+ \ ['eEe', "s/E/\\='\\\\\<C-V>\<C-M>'/", ["e\\\\\<C-V>", 'e']],
+ \ ['fFf', "s/F/\\='\r'/", ['f', 'f']],
+ \ ['gGg', "s/G/\\='\<C-V>\<C-J>'/", ["g\<C-V>", 'g']],
+ \ ['hHh', "s/H/\\='\\\<C-V>\<C-J>'/", ["h\\\<C-V>", 'h']],
+ \ ['iIi', "s/I/\\='\\\\\<C-V>\<C-J>'/", ["i\\\\\<C-V>", 'i']],
+ \ ['jJj', "s/J/\\='\n'/", ['j', 'j']],
+ \ ['kKk', 's/K/\="\r"/', ['k', 'k']],
+ \ ['lLl', 's/L/\="\n"/', ['l', 'l']]
+ \ ]
+ call Run_SubCmd_Tests(tests)
+endfunc
+
+" Test for submatch() on :substitue.
+func Test_sub_cmd_4()
+ set magic&
+ set cpo&
+
+ " List entry format: [input, cmd, output]
+ let tests = [ ['aAa', "s/A/\\=substitute(submatch(0), '.', '\\', '')/",
+ \ ['a\a']],
+ \ ['bBb', "s/B/\\=substitute(submatch(0), '.', '\\', '')/",
+ \ ['b\b']],
+ \ ['cCc', "s/C/\\=substitute(submatch(0), '.', '\<C-V>\<C-M>', '')/",
+ \ ["c\<C-V>", 'c']],
+ \ ['dDd', "s/D/\\=substitute(submatch(0), '.', '\\\<C-V>\<C-M>', '')/",
+ \ ["d\<C-V>", 'd']],
+ \ ['eEe', "s/E/\\=substitute(submatch(0), '.', '\\\\\<C-V>\<C-M>', '')/",
+ \ ["e\\\<C-V>", 'e']],
+ \ ['fFf', "s/F/\\=substitute(submatch(0), '.', '\\r', '')/",
+ \ ['f', 'f']],
+ \ ['gGg', 's/G/\=substitute(submatch(0), ".", "\<C-V>\<C-J>", "")/',
+ \ ["g\<C-V>", 'g']],
+ \ ['hHh', 's/H/\=substitute(submatch(0), ".", "\\\<C-V>\<C-J>", "")/',
+ \ ["h\<C-V>", 'h']],
+ \ ['iIi', 's/I/\=substitute(submatch(0), ".", "\\\\\<C-V>\<C-J>", "")/',
+ \ ["i\\\<C-V>", 'i']],
+ \ ['jJj', "s/J/\\=substitute(submatch(0), '.', '\\n', '')/",
+ \ ['j', 'j']],
+ \ ['kKk', "s/K/\\=substitute(submatch(0), '.', '\\r', '')/",
+ \ ['k', 'k']],
+ \ ['lLl', "s/L/\\=substitute(submatch(0), '.', '\\n', '')/",
+ \ ['l', 'l']],
+ \ ]
+ call Run_SubCmd_Tests(tests)
+endfunc
+
+func Test_sub_cmd_5()
+ set magic&
+ set cpo&
+
+ " List entry format: [input, cmd, output]
+ let tests = [ ['A123456789', 's/A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . submatch(6) . submatch(5) . submatch(4) . submatch(3) . submatch(2) . submatch(1)/', ['A123456789987654321']],
+ \ ['B123456789', 's/B\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)/\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), submatch(3, 1), submatch(2, 1), submatch(1, 1)])/', ["[['B123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], ['2'], ['1']]"]],
+ \ ]
+ call Run_SubCmd_Tests(tests)
+endfunc
+
+" Test for *:s%* on :substitute.
+func Test_sub_cmd_6()
+ throw "skipped: Nvim removed POSIX-related 'cpoptions' flags"
+ set magic&
+ set cpo+=/
+
+ " List entry format: [input, cmd, output]
+ let tests = [ ['A', 's/A/a/', ['a']],
+ \ ['B', 's/B/%/', ['a']],
+ \ ]
+ call Run_SubCmd_Tests(tests)
+
+ set cpo-=/
+ let tests = [ ['C', 's/C/c/', ['c']],
+ \ ['D', 's/D/%/', ['%']],
+ \ ]
+ call Run_SubCmd_Tests(tests)
+
+ set cpo&
+endfunc
+
+" Test for :s replacing \n with line break.
+func Test_sub_cmd_7()
+ set magic&
+ set cpo&
+
+ " List entry format: [input, cmd, output]
+ let tests = [ ["A\<C-V>\<C-M>A", 's/A./\=submatch(0)/', ['A', 'A']],
+ \ ["B\<C-V>\<C-J>B", 's/B./\=submatch(0)/', ['B', 'B']],
+ \ ["C\<C-V>\<C-J>C", 's/C./\=strtrans(string(submatch(0, 1)))/', [strtrans("['C\<C-J>']C")]],
+ \ ["D\<C-V>\<C-J>\nD", 's/D.\nD/\=strtrans(string(submatch(0, 1)))/', [strtrans("['D\<C-J>', 'D']")]],
+ \ ["E\<C-V>\<C-J>\n\<C-V>\<C-J>\n\<C-V>\<C-J>\n\<C-V>\<C-J>\n\<C-V>\<C-J>E", 's/E\_.\{-}E/\=strtrans(string(submatch(0, 1)))/', [strtrans("['E\<C-J>', '\<C-J>', '\<C-J>', '\<C-J>', '\<C-J>E']")]],
+ \ ]
+ call Run_SubCmd_Tests(tests)
+
+ exe "normal oQ\nQ\<Esc>k"
+ call assert_fails('s/Q[^\n]Q/\=submatch(0)."foobar"/', 'E486')
+ enew!
+endfunc
+
+func TitleString()
+ let check = 'foo' =~ 'bar'
+ return ""
+endfunc
+
+func Test_sub_cmd_8()
+ set titlestring=%{TitleString()}
+
+ enew!
+ call append(0, ['', 'test_one', 'test_two'])
+ call cursor(1,1)
+ /^test_one/s/.*/\="foo\nbar"/
+ call assert_equal('foo', getline(2))
+ call assert_equal('bar', getline(3))
+ call feedkeys(':/^test_two/s/.*/\="foo\nbar"/c', "t")
+ call feedkeys("\<CR>y", "xt")
+ call assert_equal('foo', getline(4))
+ call assert_equal('bar', getline(5))
+
+ enew!
+ set titlestring&
+endfunc
+
+" Test for *sub-replace-special* and *sub-replace-expression* on substitute().
+func Test_sub_replace_1()
+ " Run the tests with 'magic' on
+ set magic
+ set cpo&
+ call assert_equal('AA', substitute('A', 'A', '&&', ''))
+ call assert_equal('&', substitute('B', 'B', '\&', ''))
+ call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
+ call assert_equal('d', substitute('D', 'D', 'd', ''))
+ call assert_equal('~', substitute('E', 'E', '~', ''))
+ call assert_equal('~', substitute('F', 'F', '\~', ''))
+ call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
+ call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
+ call assert_equal('iI', substitute('I', 'I', '\lII', ''))
+ call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
+ call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
+ call assert_equal("l\<C-V>\<C-M>l",
+ \ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
+ call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
+ call assert_equal("n\<C-V>\<C-M>n",
+ \ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
+ call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
+ call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
+ call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
+ call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
+ call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
+ call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
+ call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
+ call assert_equal("w\\w", substitute('wWw', 'W', "\\", ''))
+ call assert_equal("x\<C-M>x", substitute('xXx', 'X', "\r", ''))
+ call assert_equal("YyyY", substitute('Y', 'Y', '\L\uyYy\l\EY', ''))
+ call assert_equal("zZZz", substitute('Z', 'Z', '\U\lZzZ\u\Ez', ''))
+endfunc
+
+func Test_sub_replace_2()
+ " Run the tests with 'magic' off
+ set nomagic
+ set cpo&
+ call assert_equal('AA', substitute('A', 'A', '&&', ''))
+ call assert_equal('&', substitute('B', 'B', '\&', ''))
+ call assert_equal('C123456789987654321', substitute('C123456789', 'C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', '\0\9\8\7\6\5\4\3\2\1', ''))
+ call assert_equal('d', substitute('D', 'D', 'd', ''))
+ call assert_equal('~', substitute('E', 'E', '~', ''))
+ call assert_equal('~', substitute('F', 'F', '\~', ''))
+ call assert_equal('Gg', substitute('G', 'G', '\ugg', ''))
+ call assert_equal('Hh', substitute('H', 'H', '\Uh\Eh', ''))
+ call assert_equal('iI', substitute('I', 'I', '\lII', ''))
+ call assert_equal('jJ', substitute('J', 'J', '\LJ\EJ', ''))
+ call assert_equal('Kk', substitute('K', 'K', '\Uk\ek', ''))
+ call assert_equal("l\<C-V>\<C-M>l",
+ \ substitute('lLl', 'L', "\<C-V>\<C-M>", ''))
+ call assert_equal("m\<C-M>m", substitute('mMm', 'M', '\r', ''))
+ call assert_equal("n\<C-V>\<C-M>n",
+ \ substitute('nNn', 'N', "\\\<C-V>\<C-M>", ''))
+ call assert_equal("o\no", substitute('oOo', 'O', '\n', ''))
+ call assert_equal("p\<C-H>p", substitute('pPp', 'P', '\b', ''))
+ call assert_equal("q\tq", substitute('qQq', 'Q', '\t', ''))
+ call assert_equal('r\r', substitute('rRr', 'R', '\\', ''))
+ call assert_equal('scs', substitute('sSs', 'S', '\c', ''))
+ call assert_equal("t\<C-M>t", substitute('tTt', 'T', "\r", ''))
+ call assert_equal("u\nu", substitute('uUu', 'U', "\n", ''))
+ call assert_equal("v\<C-H>v", substitute('vVv', 'V', "\b", ''))
+ call assert_equal('w\w', substitute('wWw', 'W', "\\", ''))
+ call assert_equal('XxxX', substitute('X', 'X', '\L\uxXx\l\EX', ''))
+ call assert_equal('yYYy', substitute('Y', 'Y', '\U\lYyY\u\Ey', ''))
+endfunc
+
+func Test_sub_replace_3()
+ set magic&
+ set cpo&
+ call assert_equal('a\a', substitute('aAa', 'A', '\="\\"', ''))
+ call assert_equal('b\\b', substitute('bBb', 'B', '\="\\\\"', ''))
+ call assert_equal("c\rc", substitute('cCc', 'C', "\\=\"\r\"", ''))
+ call assert_equal("d\\\rd", substitute('dDd', 'D', "\\=\"\\\\\r\"", ''))
+ call assert_equal("e\\\\\re", substitute('eEe', 'E', "\\=\"\\\\\\\\\r\"", ''))
+ call assert_equal('f\rf', substitute('fFf', 'F', '\="\\r"', ''))
+ call assert_equal('j\nj', substitute('jJj', 'J', '\="\\n"', ''))
+ call assert_equal("k\<C-M>k", substitute('kKk', 'K', '\="\r"', ''))
+ call assert_equal("l\nl", substitute('lLl', 'L', '\="\n"', ''))
+endfunc
+
+" Test for submatch() on substitute().
+func Test_sub_replace_4()
+ set magic&
+ set cpo&
+ call assert_equal('a\a', substitute('aAa', 'A',
+ \ '\=substitute(submatch(0), ".", "\\", "")', ''))
+ call assert_equal('b\b', substitute('bBb', 'B',
+ \ '\=substitute(submatch(0), ".", "\\\\", "")', ''))
+ call assert_equal("c\<C-V>\<C-M>c", substitute('cCc', 'C', '\=substitute(submatch(0), ".", "\<C-V>\<C-M>", "")', ''))
+ call assert_equal("d\<C-V>\<C-M>d", substitute('dDd', 'D', '\=substitute(submatch(0), ".", "\\\<C-V>\<C-M>", "")', ''))
+ call assert_equal("e\\\<C-V>\<C-M>e", substitute('eEe', 'E', '\=substitute(submatch(0), ".", "\\\\\<C-V>\<C-M>", "")', ''))
+ call assert_equal("f\<C-M>f", substitute('fFf', 'F', '\=substitute(submatch(0), ".", "\\r", "")', ''))
+ call assert_equal("j\nj", substitute('jJj', 'J', '\=substitute(submatch(0), ".", "\\n", "")', ''))
+ call assert_equal("k\rk", substitute('kKk', 'K', '\=substitute(submatch(0), ".", "\r", "")', ''))
+ call assert_equal("l\nl", substitute('lLl', 'L', '\=substitute(submatch(0), ".", "\n", "")', ''))
+endfunc
+
+func Test_sub_replace_5()
+ set magic&
+ set cpo&
+ call assert_equal('A123456789987654321', substitute('A123456789',
+ \ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
+ \ '\=submatch(0) . submatch(9) . submatch(8) . ' .
+ \ 'submatch(7) . submatch(6) . submatch(5) . ' .
+ \ 'submatch(4) . submatch(3) . submatch(2) . submatch(1)',
+ \ ''))
+ call assert_equal("[['A123456789'], ['9'], ['8'], ['7'], ['6'], " .
+ \ "['5'], ['4'], ['3'], ['2'], ['1']]",
+ \ substitute('A123456789',
+ \ 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)',
+ \ '\=string([submatch(0, 1), submatch(9, 1), ' .
+ \ 'submatch(8, 1), submatch(7, 1), submatch(6, 1), ' .
+ \ 'submatch(5, 1), submatch(4, 1), submatch(3, 1), ' .
+ \ 'submatch(2, 1), submatch(1, 1)])',
+ \ ''))
+endfunc
+
+func Test_sub_replace_6()
+ set magic&
+ " set cpo+=/
+ call assert_equal('a', substitute('A', 'A', 'a', ''))
+ call assert_equal('%', substitute('B', 'B', '%', ''))
+ " set cpo-=/
+ call assert_equal('c', substitute('C', 'C', 'c', ''))
+ call assert_equal('%', substitute('D', 'D', '%', ''))
+endfunc
+
+func Test_sub_replace_7()
+ set magic&
+ set cpo&
+ call assert_equal('AA', substitute('AA', 'A.', '\=submatch(0)', ''))
+ call assert_equal("B\nB", substitute("B\nB", 'B.', '\=submatch(0)', ''))
+ call assert_equal("['B\n']B", substitute("B\nB", 'B.', '\=string(submatch(0, 1))', ''))
+ call assert_equal('-abab', substitute('-bb', '\zeb', 'a', 'g'))
+ call assert_equal('c-cbcbc', substitute('-bb', '\ze', 'c', 'g'))
+endfunc
+
+" Test for *:s%* on :substitute.
+func Test_sub_replace_8()
+ new
+ set magic&
+ set cpo&
+ $put =',,X'
+ s/\(^\|,\)\ze\(,\|X\)/\1N/g
+ call assert_equal('N,,NX', getline("$"))
+ $put =',,Y'
+ let cmd = ':s/\(^\|,\)\ze\(,\|Y\)/\1N/gc'
+ call feedkeys(cmd . "\<CR>a", "xt")
+ call assert_equal('N,,NY', getline("$"))
+ :$put =',,Z'
+ let cmd = ':s/\(^\|,\)\ze\(,\|Z\)/\1N/gc'
+ call feedkeys(cmd . "\<CR>yy", "xt")
+ call assert_equal('N,,NZ', getline("$"))
+ enew! | close
+endfunc
+
+func Test_sub_replace_9()
+ new
+ set magic&
+ set cpo&
+ $put ='xxx'
+ call feedkeys(":s/x/X/gc\<CR>yyq", "xt")
+ call assert_equal('XXx', getline("$"))
+ enew! | close
+endfunc
+
+func Test_sub_replace_10()
+ set magic&
+ set cpo&
+ call assert_equal('a1a2a3a', substitute('123', '\zs', 'a', 'g'))
+ call assert_equal('aaa', substitute('123', '\zs.', 'a', 'g'))
+ call assert_equal('1a2a3a', substitute('123', '.\zs', 'a', 'g'))
+ call assert_equal('a1a2a3a', substitute('123', '\ze', 'a', 'g'))
+ call assert_equal('a1a2a3', substitute('123', '\ze.', 'a', 'g'))
+ call assert_equal('aaa', substitute('123', '.\ze', 'a', 'g'))
+ call assert_equal('aa2a3a', substitute('123', '1\|\ze', 'a', 'g'))
+ call assert_equal('1aaa', substitute('123', '1\zs\|[23]', 'a', 'g'))
+endfunc
diff --git a/src/nvim/testdir/test_suspend.vim b/src/nvim/testdir/test_suspend.vim
new file mode 100644
index 0000000000..a9964b0400
--- /dev/null
+++ b/src/nvim/testdir/test_suspend.vim
@@ -0,0 +1,51 @@
+" Test :suspend
+
+source shared.vim
+
+func Test_suspend()
+ if !has('terminal') || !executable('/bin/sh')
+ return
+ endif
+
+ let buf = term_start('/bin/sh')
+ " Wait for shell prompt.
+ call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))})
+
+ call term_sendkeys(buf, v:progpath
+ \ . " --clean -X"
+ \ . " -c 'set nu'"
+ \ . " -c 'call setline(1, \"foo\")'"
+ \ . " Xfoo\<CR>")
+ " Cursor in terminal buffer should be on first line in spawned vim.
+ call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))})
+
+ for suspend_cmd in [":suspend\<CR>",
+ \ ":stop\<CR>",
+ \ ":suspend!\<CR>",
+ \ ":stop!\<CR>",
+ \ "\<C-Z>"]
+ " Suspend and wait for shell prompt.
+ call term_sendkeys(buf, suspend_cmd)
+ call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))})
+
+ " Without 'autowrite', buffer should not be written.
+ call assert_equal(0, filereadable('Xfoo'))
+
+ call term_sendkeys(buf, "fg\<CR>")
+ call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))})
+ endfor
+
+ " Test that :suspend! with 'autowrite' writes content of buffers if modified.
+ call term_sendkeys(buf, ":set autowrite\<CR>")
+ call assert_equal(0, filereadable('Xfoo'))
+ call term_sendkeys(buf, ":suspend\<CR>")
+ " Wait for shell prompt.
+ call WaitForAssert({-> assert_match('[$#] $', term_getline(buf, '.'))})
+ call assert_equal(['foo'], readfile('Xfoo'))
+ call term_sendkeys(buf, "fg\<CR>")
+ call WaitForAssert({-> assert_equal(' 1 foo', term_getline(buf, '.'))})
+
+ exe buf . 'bwipe!'
+ call delete('Xfoo')
+ set autowrite&
+endfunc
diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim
new file mode 100644
index 0000000000..bc7b7c00d3
--- /dev/null
+++ b/src/nvim/testdir/test_swap.vim
@@ -0,0 +1,63 @@
+" Tests for the swap feature
+
+" Tests for 'directory' option.
+func Test_swap_directory()
+ if !has("unix")
+ return
+ endif
+ let content = ['start of testfile',
+ \ 'line 2 Abcdefghij',
+ \ 'line 3 Abcdefghij',
+ \ 'end of testfile']
+ call writefile(content, 'Xtest1')
+
+ " '.', swap file in the same directory as file
+ set dir=.,~
+
+ " Verify that the swap file doesn't exist in the current directory
+ call assert_equal([], glob(".Xtest1*.swp", 1, 1, 1))
+ edit Xtest1
+ let swfname = split(execute("swapname"))[0]
+ call assert_equal([swfname], glob(swfname, 1, 1, 1))
+
+ " './dir', swap file in a directory relative to the file
+ set dir=./Xtest2,.,~
+
+ call mkdir("Xtest2")
+ edit Xtest1
+ call assert_equal([], glob(swfname, 1, 1, 1))
+ let swfname = "Xtest2/Xtest1.swp"
+ call assert_equal(swfname, split(execute("swapname"))[0])
+ call assert_equal([swfname], glob("Xtest2/*", 1, 1, 1))
+
+ " 'dir', swap file in directory relative to the current dir
+ set dir=Xtest.je,~
+
+ call mkdir("Xtest.je")
+ call writefile(content, 'Xtest2/Xtest3')
+ edit Xtest2/Xtest3
+ call assert_equal(["Xtest2/Xtest3"], glob("Xtest2/*", 1, 1, 1))
+ let swfname = "Xtest.je/Xtest3.swp"
+ call assert_equal(swfname, split(execute("swapname"))[0])
+ call assert_equal([swfname], glob("Xtest.je/*", 1, 1, 1))
+
+ set dir&
+ call delete("Xtest1")
+ call delete("Xtest2", "rf")
+ call delete("Xtest.je", "rf")
+endfunc
+
+func Test_missing_dir()
+ call mkdir('Xswapdir')
+ exe 'set directory=' . getcwd() . '/Xswapdir'
+
+ call assert_equal('', glob('foo'))
+ call assert_equal('', glob('bar'))
+ edit foo/x.txt
+ " This should not give a warning for an existing swap file.
+ split bar/x.txt
+ only
+
+ set directory&
+ call delete('Xswapdir', 'rf')
+endfunc
diff --git a/src/nvim/testdir/test_syn_attr.vim b/src/nvim/testdir/test_syn_attr.vim
new file mode 100644
index 0000000000..64aab3411d
--- /dev/null
+++ b/src/nvim/testdir/test_syn_attr.vim
@@ -0,0 +1,28 @@
+" Test syntax highlighting functions.
+
+func Test_missing_attr()
+ hi Mine cterm=italic
+ call assert_equal('Mine', synIDattr(hlID("Mine"), "name"))
+ call assert_equal('1', synIDattr(hlID("Mine"), "italic", 'cterm'))
+ hi Mine cterm=inverse
+ call assert_equal('1', synIDattr(hlID("Mine"), "inverse", 'cterm'))
+ hi Mine cterm=standout gui=undercurl
+ call assert_equal('1', synIDattr(hlID("Mine"), "standout", 'cterm'))
+ call assert_equal('1', synIDattr(hlID("Mine"), "undercurl", 'gui'))
+ hi Mine cterm=NONE gui=NONE
+ call assert_equal('', synIDattr(hlID("Mine"), "italic", 'cterm'))
+ call assert_equal('', synIDattr(hlID("Mine"), "inverse", 'cterm'))
+ call assert_equal('', synIDattr(hlID("Mine"), "standout", 'cterm'))
+ call assert_equal('', synIDattr(hlID("Mine"), "undercurl", 'gui'))
+
+ if has('gui')
+ let fontname = getfontname()
+ if fontname == ''
+ let fontname = 'something'
+ endif
+ exe "hi Mine guifg=blue guibg=red font='" . fontname . "'"
+ call assert_equal('blue', synIDattr(hlID("Mine"), "fg", 'gui'))
+ call assert_equal('red', synIDattr(hlID("Mine"), "bg", 'gui'))
+ call assert_equal(fontname, synIDattr(hlID("Mine"), "font", 'gui'))
+ endif
+endfunc
diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim
index 309c0f460b..6978faeb7b 100644
--- a/src/nvim/testdir/test_syntax.vim
+++ b/src/nvim/testdir/test_syntax.vim
@@ -1,5 +1,7 @@
" Test for syntax and syntax iskeyword option
+source view_util.vim
+
func GetSyntaxItem(pat)
let c = ''
let a = ['a', getreg('a'), getregtype('a')]
@@ -50,7 +52,7 @@ func Test_syn_iskeyword()
setlocal isk-=_
call assert_equal('DLTD_BY', GetSyntaxItem('DLTD'))
/\<D\k\+\>/:norm! ygn
- let b2=@0
+ let b2 = @0
call assert_equal('DLTD', @0)
syn iskeyword clear
@@ -61,3 +63,443 @@ func Test_syn_iskeyword()
quit!
endfunc
+
+func Test_syntax_after_reload()
+ split Xsomefile
+ call setline(1, ['hello', 'there'])
+ w!
+ only!
+ setl filetype=hello
+ au FileType hello let g:gotit = 1
+ call assert_false(exists('g:gotit'))
+ edit other
+ buf Xsomefile
+ call assert_equal('hello', &filetype)
+ call assert_true(exists('g:gotit'))
+ call delete('Xsomefile')
+endfunc
+
+func Test_syntime()
+ if !has('profile')
+ return
+ endif
+
+ syntax on
+ syntime on
+ let a = execute('syntime report')
+ call assert_equal("\nNo Syntax items defined for this buffer", a)
+
+ view ../memfile_test.c
+ setfiletype cpp
+ redraw
+ let a = execute('syntime report')
+ call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a)
+ call assert_match(' \d*\.\d* \+[^0]\d* .* cppRawString ', a)
+ call assert_match(' \d*\.\d* \+[^0]\d* .* cppNumber ', a)
+
+ syntime off
+ syntime clear
+ let a = execute('syntime report')
+ call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a)
+ call assert_notmatch('.* cppRawString *', a)
+ call assert_notmatch('.* cppNumber*', a)
+ call assert_notmatch('[1-9]', a)
+
+ call assert_fails('syntime abc', 'E475')
+
+ syntax clear
+ let a = execute('syntime report')
+ call assert_equal("\nNo Syntax items defined for this buffer", a)
+
+ bd
+endfunc
+
+func Test_syntime_completion()
+ if !has('profile')
+ return
+ endif
+
+ call feedkeys(":syntime \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"syntime clear off on report', @:)
+endfunc
+
+func Test_syntax_list()
+ syntax on
+ let a = execute('syntax list')
+ call assert_equal("\nNo Syntax items defined for this buffer", a)
+
+ view ../memfile_test.c
+ setfiletype c
+
+ let a = execute('syntax list')
+ call assert_match('cInclude*', a)
+ call assert_match('cDefine', a)
+
+ let a = execute('syntax list cDefine')
+ call assert_notmatch('cInclude*', a)
+ call assert_match('cDefine', a)
+ call assert_match(' links to Macro$', a)
+
+ call assert_fails('syntax list ABCD', 'E28:')
+ call assert_fails('syntax list @ABCD', 'E392:')
+
+ syntax clear
+ let a = execute('syntax list')
+ call assert_equal("\nNo Syntax items defined for this buffer", a)
+
+ bd
+endfunc
+
+func Test_syntax_completion()
+ call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"syn case clear cluster conceal enable include iskeyword keyword list manual match off on region reset spell sync', @:)
+
+ call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"syn case ignore match', @:)
+
+ call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"syn spell default notoplevel toplevel', @:)
+
+ call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:)
+
+ " Check that clearing "Aap" avoids it showing up before Boolean.
+ hi Aap ctermfg=blue
+ call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('^"syn list Aap Boolean Character ', @:)
+ hi clear Aap
+
+ call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('^"syn list Boolean Character ', @:)
+
+ call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_match('^"syn match Boolean Character ', @:)
+endfunc
+
+func Test_syntax_arg_skipped()
+ syn clear
+ syntax case ignore
+ if 0
+ syntax case match
+ endif
+ call assert_match('case ignore', execute('syntax case'))
+
+ syn keyword Foo foo
+ call assert_match('Foo', execute('syntax'))
+ syn clear
+ call assert_match('case match', execute('syntax case'))
+ call assert_notmatch('Foo', execute('syntax'))
+
+ if has('conceal')
+ syn clear
+ syntax conceal on
+ if 0
+ syntax conceal off
+ endif
+ call assert_match('conceal on', execute('syntax conceal'))
+ syn clear
+ call assert_match('conceal off', execute('syntax conceal'))
+ endif
+
+ syntax conceal on
+ syntax conceal off
+ call assert_match('conceal off', execute('syntax conceal'))
+
+ syntax region Bar start=/</ end=/>/
+ if 0
+ syntax region NotTest start=/</ end=/>/ contains=@Spell
+ endif
+ call assert_match('Bar', execute('syntax'))
+ call assert_notmatch('NotTest', execute('syntax'))
+ call assert_notmatch('Spell', execute('syntax'))
+
+ hi Foo ctermfg=blue
+ let a = execute('hi Foo')
+ if 0
+ syntax rest
+ endif
+ call assert_equal(a, execute('hi Foo'))
+ hi clear Bar
+ hi clear Foo
+
+ set ft=tags
+ syn off
+ if 0
+ syntax enable
+ endif
+ call assert_match('No Syntax items defined', execute('syntax'))
+ syntax enable
+ call assert_match('tagComment', execute('syntax'))
+ set ft=
+
+ syn clear
+ if 0
+ syntax include @Spell nothing
+ endif
+ call assert_notmatch('Spell', execute('syntax'))
+
+ syn clear
+ syn iskeyword 48-57,$,_
+ call assert_match('48-57,$,_', execute('syntax iskeyword'))
+ if 0
+ syn clear
+ syn iskeyword clear
+ endif
+ call assert_match('48-57,$,_', execute('syntax iskeyword'))
+ syn iskeyword clear
+ call assert_match('not set', execute('syntax iskeyword'))
+ syn iskeyword 48-57,$,_
+ syn clear
+ call assert_match('not set', execute('syntax iskeyword'))
+
+ syn clear
+ syn keyword Foo foo
+ if 0
+ syn keyword NotAdded bar
+ endif
+ call assert_match('Foo', execute('syntax'))
+ call assert_notmatch('NotAdded', execute('highlight'))
+
+ syn clear
+ syn keyword Foo foo
+ call assert_match('Foo', execute('syntax'))
+ call assert_match('Foo', execute('syntax list'))
+ call assert_notmatch('Foo', execute('if 0 | syntax | endif'))
+ call assert_notmatch('Foo', execute('if 0 | syntax list | endif'))
+
+ syn clear
+ syn match Fopi /asdf/
+ if 0
+ syn match Fopx /asdf/
+ endif
+ call assert_match('Fopi', execute('syntax'))
+ call assert_notmatch('Fopx', execute('syntax'))
+
+ syn clear
+ syn spell toplevel
+ call assert_match('spell toplevel', execute('syntax spell'))
+ if 0
+ syn spell notoplevel
+ endif
+ call assert_match('spell toplevel', execute('syntax spell'))
+ syn spell notoplevel
+ call assert_match('spell notoplevel', execute('syntax spell'))
+ syn spell default
+ call assert_match('spell default', execute('syntax spell'))
+
+ syn clear
+ if 0
+ syntax cluster Spell
+ endif
+ call assert_notmatch('Spell', execute('syntax'))
+
+ syn clear
+ syn keyword Foo foo
+ syn sync ccomment
+ syn sync maxlines=5
+ if 0
+ syn sync maxlines=11
+ endif
+ call assert_match('on C-style comments', execute('syntax sync'))
+ call assert_match('maximal 5 lines', execute('syntax sync'))
+ syn sync clear
+ if 0
+ syn sync ccomment
+ endif
+ call assert_notmatch('on C-style comments', execute('syntax sync'))
+
+ syn clear
+endfunc
+
+func Test_syntax_invalid_arg()
+ call assert_fails('syntax case asdf', 'E390:')
+ if has('conceal')
+ call assert_fails('syntax conceal asdf', 'E390:')
+ endif
+ call assert_fails('syntax spell asdf', 'E390:')
+ call assert_fails('syntax clear @ABCD', 'E391:')
+ call assert_fails('syntax include @Xxx', 'E397:')
+ call assert_fails('syntax region X start="{"', 'E399:')
+ call assert_fails('syntax sync x', 'E404:')
+ call assert_fails('syntax keyword Abc a[', 'E789:')
+ call assert_fails('syntax keyword Abc a[bc]d', 'E890:')
+endfunc
+
+func Test_syn_sync()
+ syntax region HereGroup start=/this/ end=/that/
+ syntax sync match SyncHere grouphere HereGroup "pattern"
+ call assert_match('SyncHere', execute('syntax sync'))
+ syn sync clear
+ call assert_notmatch('SyncHere', execute('syntax sync'))
+ syn clear
+endfunc
+
+func Test_syn_clear()
+ syntax keyword Foo foo
+ syntax keyword Bar tar
+ call assert_match('Foo', execute('syntax'))
+ call assert_match('Bar', execute('syntax'))
+ call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
+ syn clear Foo
+ call assert_notmatch('Foo', execute('syntax'))
+ call assert_match('Bar', execute('syntax'))
+ call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
+ syn clear Foo Bar
+ call assert_notmatch('Foo', execute('syntax'))
+ call assert_notmatch('Bar', execute('syntax'))
+ hi clear Foo
+ call assert_equal('Foo', synIDattr(hlID("Foo"), "name"))
+ hi clear Bar
+endfunc
+
+func Test_invalid_name()
+ syn clear
+ syn keyword Nop yes
+ call assert_fails("syntax keyword Wr\x17ong bar", 'E669:')
+ syntax keyword @Wrong bar
+ call assert_match('W18:', execute('1messages'))
+ syn clear
+ hi clear Nop
+ hi clear @Wrong
+endfunc
+
+func Test_ownsyntax()
+ new Xfoo
+ call setline(1, '#define FOO')
+ syntax on
+ set filetype=c
+ ownsyntax perl
+ call assert_equal('perlComment', synIDattr(synID(line('.'), col('.'), 1), 'name'))
+ call assert_equal('c', b:current_syntax)
+ call assert_equal('perl', w:current_syntax)
+
+ " A new split window should have the original syntax.
+ split
+ call assert_equal('cDefine', synIDattr(synID(line('.'), col('.'), 1), 'name'))
+ call assert_equal('c', b:current_syntax)
+ call assert_equal(0, exists('w:current_syntax'))
+
+ wincmd x
+ call assert_equal('perlComment', synIDattr(synID(line("."), col("."), 1), "name"))
+
+ syntax off
+ set filetype&
+ %bw!
+endfunc
+
+func Test_ownsyntax_completion()
+ call feedkeys(":ownsyntax java\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"ownsyntax java javacc javascript', @:)
+endfunc
+
+func Test_highlight_invalid_arg()
+ if has('gui_running')
+ call assert_fails('hi XXX guifg=xxx', 'E254:')
+ endif
+ call assert_fails('hi DoesNotExist', 'E411:')
+ call assert_fails('hi link', 'E412:')
+ call assert_fails('hi link a', 'E412:')
+ call assert_fails('hi link a b c', 'E413:')
+ call assert_fails('hi XXX =', 'E415:')
+ call assert_fails('hi XXX cterm', 'E416:')
+ call assert_fails('hi XXX cterm=', 'E417:')
+ call assert_fails('hi XXX cterm=DoesNotExist', 'E418:')
+ call assert_fails('hi XXX ctermfg=DoesNotExist', 'E421:')
+ call assert_fails('hi XXX xxx=White', 'E423:')
+endfunc
+
+func Test_conceal()
+ if !has('conceal')
+ return
+ endif
+
+ new
+ call setline(1, ['', '123456'])
+ syn match test23 "23" conceal cchar=X
+ syn match test45 "45" conceal
+
+ set conceallevel=0
+ call assert_equal('123456 ', ScreenLines(2, 7)[0])
+ call assert_equal([[0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)'))
+
+ set conceallevel=1
+ call assert_equal('1X 6 ', ScreenLines(2, 7)[0])
+ call assert_equal([[0, '', 0], [1, 'X', 1], [1, 'X', 1], [1, ' ', 2], [1, ' ', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)'))
+
+ set conceallevel=1
+ set listchars=conceal:Y
+ call assert_equal([[0, '', 0], [1, 'X', 1], [1, 'X', 1], [1, 'Y', 2], [1, 'Y', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)'))
+ call assert_equal('1XY6 ', ScreenLines(2, 7)[0])
+
+ set conceallevel=2
+ call assert_match('1X6 ', ScreenLines(2, 7)[0])
+ call assert_equal([[0, '', 0], [1, 'X', 1], [1, 'X', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)'))
+
+ set conceallevel=3
+ call assert_match('16 ', ScreenLines(2, 7)[0])
+ call assert_equal([[0, '', 0], [1, '', 1], [1, '', 1], [1, '', 2], [1, '', 2], [0, '', 0]], map(range(1, 6), 'synconcealed(2, v:val)'))
+
+ syn clear
+ set conceallevel&
+ bw!
+endfunc
+
+func Test_bg_detection()
+ if has('gui_running')
+ return
+ endif
+ " auto-detection of &bg, make sure sure it isn't set anywhere before
+ " this test
+ hi Normal ctermbg=0
+ call assert_equal('dark', &bg)
+ hi Normal ctermbg=4
+ call assert_equal('dark', &bg)
+ hi Normal ctermbg=12
+ call assert_equal('light', &bg)
+ hi Normal ctermbg=15
+ call assert_equal('light', &bg)
+
+ " manually-set &bg takes precedence over auto-detection
+ set bg=light
+ hi Normal ctermbg=4
+ call assert_equal('light', &bg)
+ set bg=dark
+ hi Normal ctermbg=12
+ call assert_equal('dark', &bg)
+endfunc
+
+fun Test_synstack_synIDtrans()
+ new
+ setfiletype c
+ syntax on
+ call setline(1, ' /* A comment with a TODO */')
+
+ call assert_equal([], synstack(1, 1))
+
+ norm f/
+ call assert_equal(['cComment', 'cCommentStart'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
+ call assert_equal(['Comment', 'Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")'))
+
+ norm fA
+ call assert_equal(['cComment'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
+ call assert_equal(['Comment'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")'))
+
+ norm fT
+ call assert_equal(['cComment', 'cTodo'], map(synstack(line("."), col(".")), 'synIDattr(v:val, "name")'))
+ call assert_equal(['Comment', 'Todo'], map(synstack(line("."), col(".")), 'synIDattr(synIDtrans(v:val), "name")'))
+
+ syn clear
+ bw!
+endfunc
+
+" Using \z() in a region with NFA failing should not crash.
+func Test_syn_wrong_z_one()
+ new
+ call setline(1, ['just some text', 'with foo and bar to match with'])
+ syn region FooBar start="foo\z(.*\)bar" end="\z1"
+ " call test_override("nfa_fail", 1)
+ redraw!
+ redraw!
+ " call test_override("ALL", 0)
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_system.vim b/src/nvim/testdir/test_system.vim
new file mode 100644
index 0000000000..d3c0594c03
--- /dev/null
+++ b/src/nvim/testdir/test_system.vim
@@ -0,0 +1,90 @@
+" Tests for system() and systemlist()
+
+function! Test_System()
+ if !executable('echo') || !executable('cat') || !executable('wc')
+ return
+ endif
+ let out = system('echo 123')
+ call assert_equal("123\n", out)
+
+ let out = systemlist('echo 123')
+ if &shell =~# 'cmd.exe$'
+ call assert_equal(["123\r"], out)
+ else
+ call assert_equal(['123'], out)
+ endif
+
+ call assert_equal('123', system('cat', '123'))
+ call assert_equal(['123'], systemlist('cat', '123'))
+ call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
+
+ new Xdummy
+ call setline(1, ['asdf', "pw\<NL>er", 'xxxx'])
+ let out = system('wc -l', bufnr('%'))
+ " On OS/X we get leading spaces
+ let out = substitute(out, '^ *', '', '')
+ call assert_equal("3\n", out)
+
+ let out = systemlist('wc -l', bufnr('%'))
+ " On Windows we may get a trailing CR.
+ if out != ["3\r"]
+ " On OS/X we get leading spaces
+ if type(out) == v:t_list
+ let out[0] = substitute(out[0], '^ *', '', '')
+ endif
+ call assert_equal(['3'], out)
+ endif
+
+ let out = systemlist('cat', bufnr('%'))
+ " On Windows we may get a trailing CR.
+ if out != ["asdf\r", "pw\<NL>er\r", "xxxx\r"]
+ call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], out)
+ endif
+ bwipe!
+
+ call assert_fails('call system("wc -l", 99999)', 'E86:')
+endfunction
+
+function! Test_system_exmode()
+ if has('unix') " echo $? only works on Unix
+ let cmd = ' -es --headless -u NONE -c "source Xscript" +q; echo "result=$?"'
+ " Need to put this in a script, "catch" isn't found after an unknown
+ " function.
+ call writefile(['try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript')
+ let a = system(v:progpath . cmd)
+ call assert_match('result=0', a)
+ call assert_equal(0, v:shell_error)
+ endif
+
+ " Error before try does set error flag.
+ call writefile(['call nosuchfunction()', 'try', 'call doesnotexist()', 'catch', 'endtry'], 'Xscript')
+ if has('unix') " echo $? only works on Unix
+ let a = system(v:progpath . cmd)
+ call assert_notequal('0', a[0])
+ endif
+
+ let cmd = ' -es --headless -u NONE -c "source Xscript" +q'
+ let a = system(v:progpath . cmd)
+ call assert_notequal(0, v:shell_error)
+ call delete('Xscript')
+
+ if has('unix') " echo $? only works on Unix
+ let cmd = ' -es --headless -u NONE -c "call doesnotexist()" +q; echo $?'
+ let a = system(v:progpath. cmd)
+ call assert_notequal(0, a[0])
+ endif
+
+ let cmd = ' -es --headless -u NONE -c "call doesnotexist()" +q'
+ let a = system(v:progpath. cmd)
+ call assert_notequal(0, v:shell_error)
+
+ if has('unix') " echo $? only works on Unix
+ let cmd = ' -es --headless -u NONE -c "call doesnotexist()|let a=1" +q; echo $?'
+ let a = system(v:progpath. cmd)
+ call assert_notequal(0, a[0])
+ endif
+
+ let cmd = ' -es --headless -u NONE -c "call doesnotexist()|let a=1" +q'
+ let a = system(v:progpath. cmd)
+ call assert_notequal(0, v:shell_error)
+endfunc
diff --git a/src/nvim/testdir/test_tab.vim b/src/nvim/testdir/test_tab.vim
new file mode 100644
index 0000000000..b847dbd962
--- /dev/null
+++ b/src/nvim/testdir/test_tab.vim
@@ -0,0 +1,45 @@
+
+" Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set.
+" Also test that dv_ works correctly
+func Test_smarttab()
+ enew!
+ set smarttab expandtab ts=8 sw=4
+ " make sure that backspace works, no matter what termcap is used
+ exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
+ call append(0, ['start text',
+ \ "\t\tsome test text",
+ \ 'test text',
+ \ "\t\tother test text",
+ \ ' a cde',
+ \ ' f ghi',
+ \ 'test text',
+ \ ' Second line beginning with whitespace'
+ \ ])
+ call cursor(1, 1)
+ exe "normal /some\<CR>"
+ exe "normal r\t"
+ call assert_equal("\t\t ome test text", getline('.'))
+ set noexpandtab
+ exe "normal /other\<CR>"
+ exe "normal r\t"
+ call assert_equal("\t\t ther test text", getline('.'))
+
+ " Test replacing with Tabs and then backspacing to undo it
+ exe "normal j0wR\t\t\t\<BS>\<BS>\<BS>"
+ call assert_equal(" a cde", getline('.'))
+ " Test replacing with Tabs
+ exe "normal j0wR\t\t\t"
+ call assert_equal(" \t\thi", getline('.'))
+
+ " Test that copyindent works with expandtab set
+ set expandtab smartindent copyindent ts=8 sw=8 sts=8
+ exe "normal jo{\<CR>x"
+ call assert_equal('{', getline(line('.') - 1))
+ call assert_equal(' x', getline('.'))
+ set nosol
+ exe "normal /Second line/\<CR>"
+ exe "normal fwdv_"
+ call assert_equal(' with whitespace', getline('.'))
+ enew!
+ set expandtab& smartindent& copyindent& ts& sw& sts&
+endfunc
diff --git a/src/nvim/testdir/test_tabline.vim b/src/nvim/testdir/test_tabline.vim
new file mode 100644
index 0000000000..6c7a02d650
--- /dev/null
+++ b/src/nvim/testdir/test_tabline.vim
@@ -0,0 +1,43 @@
+function! TablineWithCaughtError()
+ let s:func_in_tabline_called = 1
+ try
+ call eval('unknown expression')
+ catch
+ endtry
+ return ''
+endfunction
+
+function! TablineWithError()
+ let s:func_in_tabline_called = 1
+ call eval('unknown expression')
+ return ''
+endfunction
+
+function! Test_caught_error_in_tabline()
+ let showtabline_save = &showtabline
+ set showtabline=2
+ let s:func_in_tabline_called = 0
+ let tabline = '%{TablineWithCaughtError()}'
+ let &tabline = tabline
+ redraw!
+ call assert_true(s:func_in_tabline_called)
+ call assert_equal(tabline, &tabline)
+ set tabline=
+ let &showtabline = showtabline_save
+endfunction
+
+function! Test_tabline_will_be_disabled_with_error()
+ let showtabline_save = &showtabline
+ set showtabline=2
+ let s:func_in_tabline_called = 0
+ let tabline = '%{TablineWithError()}'
+ try
+ let &tabline = tabline
+ redraw!
+ catch
+ endtry
+ call assert_true(s:func_in_tabline_called)
+ call assert_equal('', &tabline)
+ set tabline=
+ let &showtabline = showtabline_save
+endfunction
diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim
new file mode 100644
index 0000000000..add9b3d7cf
--- /dev/null
+++ b/src/nvim/testdir/test_tabpage.vim
@@ -0,0 +1,550 @@
+" Tests for tabpage
+
+
+function Test_tabpage()
+ bw!
+ " Simple test for opening and closing a tab page
+ tabnew
+ call assert_equal(2, tabpagenr())
+ quit
+
+ " Open three tab pages and use ":tabdo"
+ 0tabnew
+ 1tabnew
+ $tabnew
+ %del
+ tabdo call append(line('$'), tabpagenr())
+ tabclose! 2
+ tabrewind
+ let line1 = getline('$')
+ undo
+ q
+ tablast
+ let line2 = getline('$')
+ q!
+ call append(line('$'), line1)
+ call append(line('$'), line2)
+ unlet line1 line2
+ call assert_equal(['', '3', '1', '4'], getline(1, '$'))
+ "
+ " Test for settabvar() and gettabvar() functions. Open a new tab page and
+ " set 3 variables to a number, string and a list. Verify that the variables
+ " are correctly set.
+ tabnew
+ tabfirst
+ call settabvar(2, 'val_num', 100)
+ call settabvar(2, 'val_str', 'SetTabVar test')
+ call settabvar(2, 'val_list', ['red', 'blue', 'green'])
+ "
+ call assert_true(gettabvar(2, 'val_num') == 100 && gettabvar(2, 'val_str') == 'SetTabVar test' && gettabvar(2, 'val_list') == ['red', 'blue', 'green'])
+
+ tabnext 2
+ call assert_true(t:val_num == 100 && t:val_str == 'SetTabVar test' && t:val_list == ['red', 'blue', 'green'])
+ tabclose
+
+ " Test for ":tab drop exist-file" to keep current window.
+ sp test1
+ tab drop test1
+ call assert_true(tabpagenr('$') == 1 && winnr('$') == 2 && winnr() == 1)
+ close
+ "
+ "
+ " Test for ":tab drop new-file" to keep current window of tabpage 1.
+ split
+ tab drop newfile
+ call assert_true(tabpagenr('$') == 2 && tabpagewinnr(1, '$') == 2 && tabpagewinnr(1) == 1)
+ tabclose
+ q
+ "
+ "
+ " Test for ":tab drop multi-opend-file" to keep current tabpage and window.
+ new test1
+ tabnew
+ new test1
+ tab drop test1
+ call assert_true(tabpagenr() == 2 && tabpagewinnr(2, '$') == 2 && tabpagewinnr(2) == 1)
+ tabclose
+ q
+ "
+ "
+ " Test for ":tab drop vertical-split-window" to jump test1 buffer
+ tabedit test1
+ vnew
+ tabfirst
+ tab drop test1
+ call assert_equal([2, 2, 2, 2], [tabpagenr('$'), tabpagenr(), tabpagewinnr(2, '$'), tabpagewinnr(2)])
+ 1tabonly
+ "
+ "
+ for i in range(9) | tabnew | endfor
+ normal! 1gt
+ call assert_equal(1, tabpagenr())
+ tabmove 5
+ call assert_equal(5, tabpagenr())
+ .tabmove
+ call assert_equal(5, tabpagenr())
+ tabmove -
+ call assert_equal(4, tabpagenr())
+ tabmove +
+ call assert_equal(5, tabpagenr())
+ tabmove -2
+ call assert_equal(3, tabpagenr())
+ tabmove +4
+ call assert_equal(7, tabpagenr())
+ tabmove
+ call assert_equal(10, tabpagenr())
+ 0tabmove
+ call assert_equal(1, tabpagenr())
+ $tabmove
+ call assert_equal(10, tabpagenr())
+ tabmove 0
+ call assert_equal(1, tabpagenr())
+ tabmove $
+ call assert_equal(10, tabpagenr())
+ 3tabmove
+ call assert_equal(4, tabpagenr())
+ 7tabmove 5
+ call assert_equal(5, tabpagenr())
+
+ " The following are a no-op
+ norm! 2gt
+ call assert_equal(2, tabpagenr())
+ tabmove 2
+ call assert_equal(2, tabpagenr())
+ 2tabmove
+ call assert_equal(2, tabpagenr())
+ tabmove 1
+ call assert_equal(2, tabpagenr())
+ 1tabmove
+ call assert_equal(2, tabpagenr())
+
+ call assert_fails("99tabmove", 'E16:')
+ call assert_fails("+99tabmove", 'E16:')
+ call assert_fails("-99tabmove", 'E16:')
+ call assert_fails("tabmove foo", 'E474:')
+ call assert_fails("tabmove 99", 'E474:')
+ call assert_fails("tabmove +99", 'E474:')
+ call assert_fails("tabmove -99", 'E474:')
+ call assert_fails("tabmove -3+", 'E474:')
+ call assert_fails("tabmove $3", 'E474:')
+ 1tabonly!
+endfunc
+
+" Test autocommands
+function Test_tabpage_with_autocmd()
+ if !has('autocmd')
+ return
+ endif
+ command -nargs=1 -bar C :call add(s:li, '=== ' . <q-args> . ' ===')|<args>
+ augroup TestTabpageGroup
+ au!
+ autocmd TabEnter * call add(s:li, 'TabEnter')
+ autocmd WinEnter * call add(s:li, 'WinEnter')
+ autocmd BufEnter * call add(s:li, 'BufEnter')
+ autocmd TabLeave * call add(s:li, 'TabLeave')
+ autocmd WinLeave * call add(s:li, 'WinLeave')
+ autocmd BufLeave * call add(s:li, 'BufLeave')
+ augroup END
+
+ let s:li = []
+ let t:a='a'
+ C tab split
+ call assert_equal(['=== tab split ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter'], s:li)
+ let s:li = []
+ let t:a='b'
+ C tabnew
+ call assert_equal(['=== tabnew ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufLeave', 'BufEnter'], s:li)
+ let t:a='c'
+ let s:li = split(join(map(range(1, tabpagenr('$')), 'gettabvar(v:val, "a")')) , '\s\+')
+ call assert_equal(['a', 'b', 'c'], s:li)
+
+ let s:li = []
+ C call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)')
+ call assert_equal(["=== call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)') ==="], s:li)
+ let s:li = split(join(map(range(1, tabpagenr('$')), 'gettabvar(v:val, "a")')) , '\s\+')
+ call assert_equal(['2', '4', '6'], s:li)
+
+ let s:li = []
+ let w:a='a'
+ C vsplit
+ call assert_equal(['=== vsplit ===', 'WinLeave', 'WinEnter'], s:li)
+ let s:li = []
+ let w:a='a'
+ let tabn=tabpagenr()
+ let winr=range(1, winnr('$'))
+ C tabnext 1
+ call assert_equal(['=== tabnext 1 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter'], s:li)
+ let s:li = split(join(map(copy(winr), 'gettabwinvar('.tabn.', v:val, "a")')), '\s\+')
+ call assert_equal(['a', 'a'], s:li)
+ let s:li = []
+ C call map(copy(winr), 'settabwinvar('.tabn.', v:val, ''a'', v:val*2)')
+ let s:li = split(join(map(copy(winr), 'gettabwinvar('.tabn.', v:val, "a")')), '\s\+')
+ call assert_equal(['2', '4'], s:li)
+
+ augroup TabDestructive
+ autocmd TabEnter * :C tabnext 2 | C tabclose 3
+ augroup END
+ let s:li = []
+ C tabnext 3
+ call assert_equal(['=== tabnext 3 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ==='], s:li)
+ call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')])
+
+ autocmd! TabDestructive TabEnter
+ let s:li = []
+ C tabnew
+ call assert_equal(['=== tabnew ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufLeave', 'BufEnter'], s:li)
+ let s:li = []
+ C tabnext 1
+ call assert_equal(['=== tabnext 1 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', 'BufEnter'], s:li)
+
+ autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3
+ let s:li = []
+ call assert_equal(3, tabpagenr('$'))
+ C tabnext 2
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal(['=== tabnext 2 ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ==='], s:li)
+ call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')])
+
+ delcommand C
+ autocmd! TabDestructive
+ augroup! TabDestructive
+ autocmd! TestTabpageGroup
+ augroup! TestTabpageGroup
+ 1tabonly!
+endfunction
+
+function Test_tabpage_with_tab_modifier()
+ for n in range(4)
+ tabedit
+ endfor
+
+ function s:check_tab(pre_nr, cmd, post_nr)
+ exec 'tabnext ' . a:pre_nr
+ exec a:cmd
+ call assert_equal(a:post_nr, tabpagenr())
+ call assert_equal('help', &buftype)
+ helpclose
+ endfunc
+
+ call s:check_tab(1, 'tab help', 2)
+ call s:check_tab(1, '3tab help', 4)
+ call s:check_tab(1, '.tab help', 2)
+ call s:check_tab(1, '.+1tab help', 3)
+ call s:check_tab(1, '0tab help', 1)
+ call s:check_tab(2, '+tab help', 4)
+ call s:check_tab(2, '+2tab help', 5)
+ call s:check_tab(4, '-tab help', 4)
+ call s:check_tab(4, '-2tab help', 3)
+ call s:check_tab(3, '$tab help', 6)
+ call assert_fails('99tab help', 'E16:')
+ call assert_fails('+99tab help', 'E16:')
+ call assert_fails('-99tab help', 'E16:')
+
+ delfunction s:check_tab
+ 1tabonly!
+endfunction
+
+function Check_tab_count(pre_nr, cmd, post_nr)
+ exec 'tabnext' a:pre_nr
+ normal! G
+ exec a:cmd
+ call assert_equal(a:post_nr, tabpagenr(), a:cmd)
+endfunc
+
+" Test for [count] of tabnext
+function Test_tabpage_with_tabnext()
+ for n in range(4)
+ tabedit
+ call setline(1, ['', '', '3'])
+ endfor
+
+ call Check_tab_count(1, 'tabnext', 2)
+ call Check_tab_count(1, '3tabnext', 3)
+ call Check_tab_count(1, '.tabnext', 1)
+ call Check_tab_count(1, '.+1tabnext', 2)
+ call Check_tab_count(2, '+tabnext', 3)
+ call Check_tab_count(2, '+2tabnext', 4)
+ call Check_tab_count(4, '-tabnext', 3)
+ call Check_tab_count(4, '-2tabnext', 2)
+ call Check_tab_count(3, '$tabnext', 5)
+ call assert_fails('0tabnext', 'E16:')
+ call assert_fails('99tabnext', 'E16:')
+ call assert_fails('+99tabnext', 'E16:')
+ call assert_fails('-99tabnext', 'E16:')
+ call Check_tab_count(1, 'tabnext 3', 3)
+ call Check_tab_count(2, 'tabnext +', 3)
+ call Check_tab_count(2, 'tabnext +2', 4)
+ call Check_tab_count(4, 'tabnext -', 3)
+ call Check_tab_count(4, 'tabnext -2', 2)
+ call Check_tab_count(3, 'tabnext $', 5)
+ call assert_fails('tabnext 0', 'E474:')
+ call assert_fails('tabnext .', 'E474:')
+ call assert_fails('tabnext -+', 'E474:')
+ call assert_fails('tabnext +2-', 'E474:')
+ call assert_fails('tabnext $3', 'E474:')
+ call assert_fails('tabnext 99', 'E474:')
+ call assert_fails('tabnext +99', 'E474:')
+ call assert_fails('tabnext -99', 'E474:')
+
+ 1tabonly!
+endfunction
+
+" Test for [count] of tabprevious
+function Test_tabpage_with_tabprevious()
+ for n in range(5)
+ tabedit
+ call setline(1, ['', '', '3'])
+ endfor
+
+ for cmd in ['tabNext', 'tabprevious']
+ call Check_tab_count(6, cmd, 5)
+ call Check_tab_count(6, '3' . cmd, 3)
+ call Check_tab_count(6, '8' . cmd, 4)
+ call Check_tab_count(6, cmd . ' 3', 3)
+ call Check_tab_count(6, cmd . ' 8', 4)
+ for n in range(2)
+ for c in ['0', '.+3', '+', '+2' , '-', '-2' , '$', '+99', '-99']
+ if n == 0 " pre count
+ let entire_cmd = c . cmd
+ let err_code = 'E16:'
+ else
+ let entire_cmd = cmd . ' ' . c
+ let err_code = 'E474:'
+ endif
+ call assert_fails(entire_cmd, err_code)
+ endfor
+ endfor
+ endfor
+
+ 1tabonly!
+endfunction
+
+function s:reconstruct_tabpage_for_test(nr)
+ let n = (a:nr > 2) ? a:nr - 2 : 1
+ 1tabonly!
+ 0tabedit n0
+ for n in range(1, n)
+ exec '$tabedit n' . n
+ if n == 1
+ call setline(1, ['', '', '3'])
+ endif
+ endfor
+endfunc
+
+func Test_tabpage_ctrl_pgup_pgdown()
+ enew!
+ tabnew tab1
+ tabnew tab2
+
+ call assert_equal(3, tabpagenr())
+ exe "norm! \<C-PageUp>"
+ call assert_equal(2, tabpagenr())
+ exe "norm! \<C-PageDown>"
+ call assert_equal(3, tabpagenr())
+
+ " Check wrapping at last or first page.
+ exe "norm! \<C-PageDown>"
+ call assert_equal(1, tabpagenr())
+ exe "norm! \<C-PageUp>"
+ call assert_equal(3, tabpagenr())
+
+ " With a count, <C-PageUp> and <C-PageDown> are not symmetrical somehow:
+ " - {count}<C-PageUp> goes {count} pages downward (relative count)
+ " - {count}<C-PageDown> goes to page number {count} (absolute count)
+ exe "norm! 2\<C-PageUp>"
+ call assert_equal(1, tabpagenr())
+ exe "norm! 2\<C-PageDown>"
+ call assert_equal(2, tabpagenr())
+
+ 1tabonly!
+endfunc
+
+" Test for [count] of tabclose
+function Test_tabpage_with_tabclose()
+
+ " pre count
+ call s:reconstruct_tabpage_for_test(6)
+ call Check_tab_count(3, 'tabclose!', 3)
+ call Check_tab_count(1, '3tabclose', 1)
+ call Check_tab_count(4, '4tabclose', 3)
+ call Check_tab_count(3, '1tabclose', 2)
+ call Check_tab_count(2, 'tabclose', 1)
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('', bufname(''))
+
+ call s:reconstruct_tabpage_for_test(6)
+ call Check_tab_count(2, '$tabclose', 2)
+ call Check_tab_count(4, '.tabclose', 4)
+ call Check_tab_count(3, '.+tabclose', 3)
+ call Check_tab_count(3, '.-2tabclose', 2)
+ call Check_tab_count(1, '.+1tabclose!', 1)
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('', bufname(''))
+
+ " post count
+ call s:reconstruct_tabpage_for_test(6)
+ call Check_tab_count(3, 'tabclose!', 3)
+ call Check_tab_count(1, 'tabclose 3', 1)
+ call Check_tab_count(4, 'tabclose 4', 3)
+ call Check_tab_count(3, 'tabclose 1', 2)
+ call Check_tab_count(2, 'tabclose', 1)
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('', bufname(''))
+
+ call s:reconstruct_tabpage_for_test(6)
+ call Check_tab_count(2, 'tabclose $', 2)
+ call Check_tab_count(4, 'tabclose', 4)
+ call Check_tab_count(3, 'tabclose +', 3)
+ call Check_tab_count(3, 'tabclose -2', 2)
+ call Check_tab_count(1, 'tabclose! +1', 1)
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal('', bufname(''))
+
+ call s:reconstruct_tabpage_for_test(6)
+ for n in range(2)
+ for c in ['0', '$3', '99', '+99', '-99']
+ if n == 0 " pre count
+ let entire_cmd = c . 'tabclose'
+ let err_code = 'E16:'
+ else
+ let entire_cmd = 'tabclose ' . c
+ let err_code = 'E474:'
+ endif
+ call assert_fails(entire_cmd, err_code)
+ call assert_equal(6, tabpagenr('$'))
+ endfor
+ endfor
+
+ call assert_fails('3tabclose', 'E37:')
+ call assert_fails('tabclose 3', 'E37:')
+ call assert_fails('tabclose -+', 'E474:')
+ call assert_fails('tabclose +2-', 'E474:')
+ call assert_equal(6, tabpagenr('$'))
+
+ 1tabonly!
+endfunction
+
+" Test for [count] of tabonly
+function Test_tabpage_with_tabonly()
+
+ " Test for the normal behavior (pre count only)
+ let tc = [ [4, '.', '!'], [2, '.+', ''], [3, '.-2', '!'], [1, '.+1', '!'] ]
+ for c in tc
+ call s:reconstruct_tabpage_for_test(6)
+ let entire_cmd = c[1] . 'tabonly' . c[2]
+ call Check_tab_count(c[0], entire_cmd, 1)
+ call assert_equal(1, tabpagenr('$'))
+ endfor
+
+ " Test for the normal behavior
+ let tc2 = [ [3, '', ''], [1, '3', ''], [4, '4', '!'], [3, '1', '!'],
+ \ [2, '', '!'],
+ \ [2, '$', '!'], [3, '+', '!'], [3, '-2', '!'], [3, '+1', '!']
+ \ ]
+ for n in range(2)
+ for c in tc2
+ call s:reconstruct_tabpage_for_test(6)
+ if n == 0 " pre count
+ let entire_cmd = c[1] . 'tabonly' . c[2]
+ else
+ let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
+ endif
+ call Check_tab_count(c[0], entire_cmd, 1)
+ call assert_equal(1, tabpagenr('$'))
+ endfor
+ endfor
+
+ " Test for the error behavior
+ for n in range(2)
+ for c in ['0', '$3', '99', '+99', '-99']
+ call s:reconstruct_tabpage_for_test(6)
+ if n == 0 " pre count
+ let entire_cmd = c . 'tabonly'
+ let err_code = 'E16:'
+ else
+ let entire_cmd = 'tabonly ' . c
+ let err_code = 'E474:'
+ endif
+ call assert_fails(entire_cmd, err_code)
+ call assert_equal(6, tabpagenr('$'))
+ endfor
+ endfor
+
+ " Test for the error behavior (post count only)
+ for c in tc
+ call s:reconstruct_tabpage_for_test(6)
+ let entire_cmd = 'tabonly' . c[2] . ' ' . c[1]
+ let err_code = 'E474:'
+ call assert_fails(entire_cmd, err_code)
+ call assert_equal(6, tabpagenr('$'))
+ endfor
+
+ call assert_fails('tabonly -+', 'E474:')
+ call assert_fails('tabonly +2-', 'E474:')
+ call assert_equal(6, tabpagenr('$'))
+
+ 1tabonly!
+ new
+ only!
+endfunction
+
+func Test_tabnext_on_buf_unload1()
+ " This once caused a crash
+ new
+ tabedit
+ tabfirst
+ au BufUnload <buffer> tabnext
+ q
+
+ while tabpagenr('$') > 1
+ bwipe!
+ endwhile
+endfunc
+
+func Test_tabnext_on_buf_unload2()
+ " This once caused a crash
+ tabedit
+ autocmd BufUnload <buffer> tabnext
+ file x
+ edit y
+
+ while tabpagenr('$') > 1
+ bwipe!
+ endwhile
+endfunc
+
+func Test_close_on_quitpre()
+ " This once caused a crash
+ edit Xtest
+ new
+ only
+ set bufhidden=delete
+ au QuitPre <buffer> close
+ tabnew tab1
+ tabnew tab2
+ 1tabn
+ q!
+ call assert_equal(1, tabpagenr())
+ call assert_equal(2, tabpagenr('$'))
+ " clean up
+ while tabpagenr('$') > 1
+ bwipe!
+ endwhile
+ buf Xtest
+endfunc
+
+func Test_tabs()
+ enew!
+ tabnew tab1
+ norm ixxx
+ let a=split(execute(':tabs'), "\n")
+ call assert_equal(['Tab page 1',
+ \ ' [No Name]',
+ \ 'Tab page 2',
+ \ '> + tab1'], a)
+
+ 1tabonly!
+ bw!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_tagcase.vim b/src/nvim/testdir/test_tagcase.vim
new file mode 100644
index 0000000000..833cb9f990
--- /dev/null
+++ b/src/nvim/testdir/test_tagcase.vim
@@ -0,0 +1,73 @@
+" test 'tagcase' option
+
+func Test_tagcase()
+ call writefile(["Bar\tXtext\t3", "Foo\tXtext\t2", "foo\tXtext\t4"], 'Xtags')
+ set tags=Xtags
+ e Xtext
+
+ for &ic in [0, 1]
+ for &scs in [0, 1]
+ for &g:tc in ["followic", "ignore", "match", "followscs", "smart"]
+ for &l:tc in ["", "followic", "ignore", "match", "followscs", "smart"]
+ let smart = 0
+ if &l:tc != ''
+ let tc = &l:tc
+ else
+ let tc = &g:tc
+ endif
+ if tc == 'followic'
+ let ic = &ic
+ elseif tc == 'ignore'
+ let ic = 1
+ elseif tc == 'followscs'
+ let ic = &ic
+ let smart = &scs
+ elseif tc == 'smart'
+ let ic = 1
+ let smart = 1
+ else
+ let ic = 0
+ endif
+ if ic && smart
+ call assert_equal(['foo', 'Foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ elseif ic
+ call assert_equal(['foo', 'Foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo', 'foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ else
+ call assert_equal(['foo'], map(taglist("^foo$"), {i, v -> v.name}))
+ call assert_equal(['Foo'], map(taglist("^Foo$"), {i, v -> v.name}))
+ endif
+ endfor
+ endfor
+ endfor
+ endfor
+
+ call delete('Xtags')
+ set ic&
+ setg tc&
+ setl tc&
+ set scs&
+endfunc
+
+func Test_set_tagcase()
+ " Verify default values.
+ set ic&
+ setg tc&
+ setl tc&
+ call assert_equal(0, &ic)
+ call assert_equal('followic', &g:tc)
+ call assert_equal('followic', &l:tc)
+ call assert_equal('followic', &tc)
+
+ " Verify that the local setting accepts <empty> but that the global setting
+ " does not. The first of these (setting the local value to <empty>) should
+ " succeed; the other two should fail.
+ setl tc=
+ call assert_fails('setg tc=', 'E474:')
+ call assert_fails('set tc=', 'E474:')
+
+ set ic&
+ setg tc&
+ setl tc&
+endfunc
diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim
new file mode 100644
index 0000000000..f9bd8b5246
--- /dev/null
+++ b/src/nvim/testdir/test_tagjump.vim
@@ -0,0 +1,261 @@
+" Tests for tagjump (tags and special searches)
+
+" SEGV occurs in older versions. (At least 7.4.1748 or older)
+func Test_ptag_with_notagstack()
+ set notagstack
+ call assert_fails('ptag does_not_exist_tag_name', 'E426')
+ set tagstack&vim
+endfunc
+
+func Test_cancel_ptjump()
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "word\tfile1\tcmd1",
+ \ "word\tfile2\tcmd2"],
+ \ 'Xtags')
+
+ only!
+ call feedkeys(":ptjump word\<CR>\<CR>", "xt")
+ help
+ call assert_equal(2, winnr('$'))
+
+ call delete('Xtags')
+ quit
+endfunc
+
+func Test_static_tagjump()
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)",
+ \ "word\tXfile2\tcmd2"],
+ \ 'Xtags')
+ new Xfile1
+ call setline(1, ['empty', 'one()', 'empty'])
+ write
+ tag one
+ call assert_equal(2, line('.'))
+
+ bwipe!
+ set tags&
+ call delete('Xtags')
+ call delete('Xfile1')
+endfunc
+
+func Test_duplicate_tagjump()
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "thesame\tXfile1\t1;\"\td\tfile:",
+ \ "thesame\tXfile1\t2;\"\td\tfile:",
+ \ "thesame\tXfile1\t3;\"\td\tfile:",
+ \ ],
+ \ 'Xtags')
+ new Xfile1
+ call setline(1, ['thesame one', 'thesame two', 'thesame three'])
+ write
+ tag thesame
+ call assert_equal(1, line('.'))
+ tnext
+ call assert_equal(2, line('.'))
+ tnext
+ call assert_equal(3, line('.'))
+
+ bwipe!
+ set tags&
+ call delete('Xtags')
+ call delete('Xfile1')
+endfunc
+
+func Test_tagjump_switchbuf()
+ set tags=Xtags
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "second\tXfile1\t2",
+ \ "third\tXfile1\t3",],
+ \ 'Xtags')
+ call writefile(['first', 'second', 'third'], 'Xfile1')
+
+ enew | only
+ set switchbuf=
+ stag second
+ call assert_equal(2, winnr('$'))
+ call assert_equal(2, line('.'))
+ stag third
+ call assert_equal(3, winnr('$'))
+ call assert_equal(3, line('.'))
+
+ enew | only
+ set switchbuf=useopen
+ stag second
+ call assert_equal(2, winnr('$'))
+ call assert_equal(2, line('.'))
+ stag third
+ call assert_equal(2, winnr('$'))
+ call assert_equal(3, line('.'))
+
+ enew | only
+ set switchbuf=usetab
+ tab stag second
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal(2, line('.'))
+ 1tabnext | stag third
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal(3, line('.'))
+
+ tabclose!
+ enew | only
+ call delete('Xfile1')
+ call delete('Xtags')
+ set switchbuf&vim
+endfunc
+
+" Tests for [ CTRL-I and CTRL-W CTRL-I commands
+function Test_keyword_jump()
+ call writefile(["#include Xinclude", "",
+ \ "",
+ \ "/* test text test tex start here",
+ \ " some text",
+ \ " test text",
+ \ " start OK if found this line",
+ \ " start found wrong line",
+ \ "test text"], 'Xtestfile')
+ call writefile(["/* test text test tex start here",
+ \ " some text",
+ \ " test text",
+ \ " start OK if found this line",
+ \ " start found wrong line",
+ \ "test text"], 'Xinclude')
+ new Xtestfile
+ call cursor(1,1)
+ call search("start")
+ exe "normal! 5[\<C-I>"
+ call assert_equal(" start OK if found this line", getline('.'))
+ call cursor(1,1)
+ call search("start")
+ exe "normal! 5\<C-W>\<C-I>"
+ call assert_equal(" start OK if found this line", getline('.'))
+ enew! | only
+ call delete('Xtestfile')
+ call delete('Xinclude')
+endfunction
+
+" Test for jumping to a tag with 'hidden' set, with symbolic link in path of
+" tag. This only works for Unix, because of the symbolic link.
+func Test_tag_symbolic()
+ if !has('unix')
+ return
+ endif
+ set hidden
+ call delete("Xtest.dir", "rf")
+ call system("ln -s . Xtest.dir")
+ " Create a tags file with the current directory name inserted.
+ call writefile([
+ \ "SECTION_OFF " . getcwd() . "/Xtest.dir/Xtest.c /^#define SECTION_OFF 3$/",
+ \ '',
+ \ ], 'Xtags')
+ call writefile(['#define SECTION_OFF 3',
+ \ '#define NUM_SECTIONS 3'], 'Xtest.c')
+
+ " Try jumping to a tag, but with a path that contains a symbolic link. When
+ " wrong, this will give the ATTENTION message. The next space will then be
+ " eaten by hit-return, instead of moving the cursor to 'd'.
+ set tags=Xtags
+ enew!
+ call append(0, 'SECTION_OFF')
+ call cursor(1,1)
+ exe "normal \<C-]> "
+ call assert_equal('Xtest.c', expand('%:t'))
+ call assert_equal(2, col('.'))
+
+ set hidden&
+ set tags&
+ enew!
+ call delete('Xtags')
+ call delete('Xtest.c')
+ call delete("Xtest.dir", "rf")
+ %bwipe!
+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
+ endif
+
+ if !has('iconv') || iconv("\x82\x60", "cp932", "utf-8") != "\uff21"
+ return
+ endif
+
+ let save_enc = &encoding
+ set encoding=utf8
+
+ let content = ['text for tags1', 'abcdefghijklmnopqrs']
+ call writefile(content, 'Xtags1.txt')
+ let content = ['text for tags2', 'ABC']
+ call writefile(content, 'Xtags2.txt')
+ let content = ['text for tags3', 'ABC']
+ call writefile(content, 'Xtags3.txt')
+ let content = ['!_TAG_FILE_ENCODING utf-8 //', 'abcdefghijklmnopqrs Xtags1.txt /abcdefghijklmnopqrs']
+ call writefile(content, 'Xtags1')
+
+ " case1:
+ new
+ set tags=Xtags1
+ tag abcdefghijklmnopqrs
+ call assert_equal('Xtags1.txt', expand('%:t'))
+ call assert_equal('abcdefghijklmnopqrs', getline('.'))
+ close
+
+ " case2:
+ new
+ set tags=test83-tags2
+ tag /.BC
+ call assert_equal('Xtags2.txt', expand('%:t'))
+ call assert_equal('ABC', getline('.'))
+ close
+
+ " case3:
+ new
+ set tags=test83-tags3
+ tag abc50
+ call assert_equal('Xtags3.txt', expand('%:t'))
+ call assert_equal('ABC', getline('.'))
+ close
+
+ set tags&
+ let &encoding = save_enc
+ call delete('Xtags1.txt')
+ call delete('Xtags2.txt')
+ call delete('Xtags3.txt')
+ call delete('Xtags1')
+endfunc
+
+func Test_tagjump_etags()
+ if !has('emacs_tags')
+ return
+ endif
+ call writefile([
+ \ "void foo() {}",
+ \ "int main(int argc, char **argv)",
+ \ "{",
+ \ "\tfoo();",
+ \ "\treturn 0;",
+ \ "}",
+ \ ], 'Xmain.c')
+
+ call writefile([
+ \ "\x0c",
+ \ "Xmain.c,64",
+ \ "void foo() {}\x7ffoo\x011,0",
+ \ "int main(int argc, char **argv)\x7fmain\x012,14",
+ \ ], 'Xtags')
+ set tags=Xtags
+ ta foo
+ call assert_equal('void foo() {}', getline('.'))
+
+ call delete('Xtags')
+ call delete('Xmain.c')
+ bwipe!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim
new file mode 100644
index 0000000000..3ad2025915
--- /dev/null
+++ b/src/nvim/testdir/test_taglist.vim
@@ -0,0 +1,63 @@
+" test 'taglist' function and :tags command
+
+func Test_taglist()
+ call writefile([
+ \ "FFoo\tXfoo\t1",
+ \ "FBar\tXfoo\t2",
+ \ "BFoo\tXbar\t1",
+ \ "BBar\tXbar\t2"
+ \ ], 'Xtags')
+ set tags=Xtags
+ split Xtext
+
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo"), {i, v -> v.name}))
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xtext"), {i, v -> v.name}))
+ call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name}))
+ call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name}))
+
+ call delete('Xtags')
+ bwipe
+endfunc
+
+func Test_taglist_native_etags()
+ if !has('emacs_tags')
+ return
+ endif
+ call writefile([
+ \ "\x0c",
+ \ "src/os_unix.c,13491",
+ \ "set_signals(\x7f1335,32699",
+ \ "reset_signals(\x7f1407,34136",
+ \ ], 'Xtags')
+
+ set tags=Xtags
+
+ call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
+ \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
+
+ call delete('Xtags')
+endfunc
+
+func Test_taglist_ctags_etags()
+ if !has('emacs_tags')
+ return
+ endif
+ call writefile([
+ \ "\x0c",
+ \ "src/os_unix.c,13491",
+ \ "set_signals(void)\x7fset_signals\x011335,32699",
+ \ "reset_signals(void)\x7freset_signals\x011407,34136",
+ \ ], 'Xtags')
+
+ set tags=Xtags
+
+ call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']],
+ \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]}))
+
+ call delete('Xtags')
+endfunc
+
+func Test_tags_too_long()
+ call assert_fails('tag ' . repeat('x', 1020), 'E426')
+ tags
+endfunc
diff --git a/src/nvim/testdir/test_textformat.vim b/src/nvim/testdir/test_textformat.vim
new file mode 100644
index 0000000000..999566c6ac
--- /dev/null
+++ b/src/nvim/testdir/test_textformat.vim
@@ -0,0 +1,168 @@
+" Tests for the various 'formatoptions' settings
+func Test_text_format()
+ enew!
+
+ setl noai tw=2 fo=t
+ call append('$', [
+ \ '{',
+ \ ' ',
+ \ '',
+ \ '}'])
+ exe "normal /^{/+1\n0"
+ normal gRa b
+ let lnum = line('.')
+ call assert_equal([
+ \ 'a',
+ \ 'b'], getline(lnum - 1, lnum))
+
+ normal ggdG
+ setl ai tw=2 fo=tw
+ call append('$', [
+ \ '{',
+ \ 'a b ',
+ \ '',
+ \ 'a ',
+ \ '}'])
+ exe "normal /^{/+1\n0"
+ normal gqgqjjllab
+ let lnum = line('.')
+ call assert_equal([
+ \ 'a ',
+ \ 'b ',
+ \ '',
+ \ 'a ',
+ \ 'b'], getline(lnum - 4, lnum))
+
+ normal ggdG
+ setl tw=3 fo=t
+ call append('$', [
+ \ '{',
+ \ "a \<C-A>",
+ \ '}'])
+ exe "normal /^{/+1\n0"
+ exe "normal gqgqo\na \<C-V>\<C-A>"
+ let lnum = line('.')
+ call assert_equal([
+ \ 'a',
+ \ "\<C-A>",
+ \ '',
+ \ 'a',
+ \ "\<C-A>"], getline(lnum - 4, lnum))
+
+ normal ggdG
+ setl tw=2 fo=tcq1 comments=:#
+ call append('$', [
+ \ '{',
+ \ 'a b',
+ \ '#a b',
+ \ '}'])
+ exe "normal /^{/+1\n0"
+ exe "normal gqgqjgqgqo\na b\n#a b"
+ let lnum = line('.')
+ call assert_equal([
+ \ 'a b',
+ \ '#a b',
+ \ '',
+ \ 'a b',
+ \ '#a b'], getline(lnum - 4, lnum))
+
+ normal ggdG
+ setl tw=5 fo=tcn comments=:#
+ call append('$', [
+ \ '{',
+ \ ' 1 a',
+ \ '# 1 a',
+ \ '}'])
+ exe "normal /^{/+1\n0"
+ exe "normal A b\<Esc>jA b"
+ let lnum = line('.')
+ call assert_equal([
+ \ ' 1 a',
+ \ ' b',
+ \ '# 1 a',
+ \ '# b'], getline(lnum - 3, lnum))
+
+ normal ggdG
+ setl tw=5 fo=t2a si
+ call append('$', [
+ \ '{',
+ \ '',
+ \ ' x a',
+ \ ' b',
+ \ ' c',
+ \ '',
+ \ '}'])
+ exe "normal /^{/+3\n0"
+ exe "normal i \<Esc>A_"
+ let lnum = line('.')
+ call assert_equal([
+ \ '',
+ \ ' x a',
+ \ ' b_',
+ \ ' c',
+ \ ''], getline(lnum - 2, lnum + 2))
+
+ normal ggdG
+ setl tw=5 fo=qn comments=:#
+ call append('$', [
+ \ '{',
+ \ '# 1 a b',
+ \ '}'])
+ exe "normal /^{/+1\n5|"
+ normal gwap
+ call assert_equal(5, col('.'))
+ let lnum = line('.')
+ call assert_equal([
+ \ '# 1 a',
+ \ '# b'], getline(lnum, lnum + 1))
+
+ normal ggdG
+ setl tw=5 fo=q2 comments=:#
+ call append('$', [
+ \ '{',
+ \ '# x',
+ \ '# a b',
+ \ '}'])
+ exe "normal /^{/+1\n0"
+ normal gwap
+ let lnum = line('.')
+ call assert_equal([
+ \ '# x a',
+ \ '# b'], getline(lnum, lnum + 1))
+
+ normal ggdG
+ setl tw& fo=a
+ call append('$', [
+ \ '{',
+ \ ' 1aa',
+ \ ' 2bb',
+ \ '}'])
+ exe "normal /^{/+2\n0"
+ normal I^^
+ call assert_equal('{ 1aa ^^2bb }', getline('.'))
+
+ normal ggdG
+ setl tw=20 fo=an12wcq comments=s1:/*,mb:*,ex:*/
+ call append('$', [
+ \ '/* abc def ghi jkl ',
+ \ ' * mno pqr stu',
+ \ ' */'])
+ exe "normal /mno pqr/\n"
+ normal A vwx yz
+ let lnum = line('.')
+ call assert_equal([
+ \ ' * mno pqr stu ',
+ \ ' * vwx yz',
+ \ ' */'], getline(lnum - 1, lnum + 1))
+
+ normal ggdG
+ setl tw=12 fo=tqnc comments=:#
+ call setline('.', '# 1 xxxxx')
+ normal A foobar
+ call assert_equal([
+ \ '# 1 xxxxx',
+ \ '# foobar'], getline(1, 2))
+
+ setl ai& tw& fo& si& comments&
+ enew!
+endfunc
diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim
new file mode 100644
index 0000000000..6a2f5044cc
--- /dev/null
+++ b/src/nvim/testdir/test_textobjects.vim
@@ -0,0 +1,259 @@
+" Test for textobjects
+
+if !has('textobjects')
+ finish
+endif
+
+func CpoM(line, useM, expected)
+ new
+
+ if a:useM
+ set cpoptions+=M
+ else
+ set cpoptions-=M
+ endif
+
+ call setline(1, a:line)
+
+ call setreg('"', '')
+ normal! ggfrmavi)y
+ call assert_equal(getreg('"'), a:expected[0])
+
+ call setreg('"', '')
+ normal! `afbmavi)y
+ call assert_equal(getreg('"'), a:expected[1])
+
+ call setreg('"', '')
+ normal! `afgmavi)y
+ call assert_equal(getreg('"'), a:expected[2])
+
+ q!
+endfunc
+
+func Test_inner_block_without_cpo_M()
+ call CpoM('(red \(blue) green)', 0, ['red \(blue', 'red \(blue', ''])
+endfunc
+
+func Test_inner_block_with_cpo_M_left_backslash()
+ call CpoM('(red \(blue) green)', 1, ['red \(blue) green', 'blue', 'red \(blue) green'])
+endfunc
+
+func Test_inner_block_with_cpo_M_right_backslash()
+ call CpoM('(red (blue\) green)', 1, ['red (blue\) green', 'blue\', 'red (blue\) green'])
+endfunc
+
+func Test_quote_selection_selection_exclusive()
+ new
+ call setline(1, "a 'bcde' f")
+ set selection=exclusive
+ exe "norm! fdvhi'y"
+ call assert_equal('bcde', @")
+ set selection&vim
+ bw!
+endfunc
+
+" Tests for string and html text objects
+func Test_string_html_objects()
+ enew!
+
+ let t = '"wo\"rd\\" foo'
+ put =t
+ normal! da"
+ call assert_equal('foo', getline('.'))
+
+ let t = "'foo' 'bar' 'piep'"
+ put =t
+ normal! 0va'a'rx
+ call assert_equal("xxxxxxxxxxxx'piep'", getline('.'))
+
+ let t = "bla bla `quote` blah"
+ put =t
+ normal! 02f`da`
+ call assert_equal("bla bla blah", getline('.'))
+
+ let t = 'out " in "noXno"'
+ put =t
+ normal! 0fXdi"
+ call assert_equal('out " in ""', getline('.'))
+
+ let t = "\"'\" 'blah' rep 'buh'"
+ put =t
+ normal! 03f'vi'ry
+ call assert_equal("\"'\" 'blah'yyyyy'buh'", getline('.'))
+
+ set quoteescape=+*-
+ let t = "bla `s*`d-`+++`l**` b`la"
+ put =t
+ normal! di`
+ call assert_equal("bla `` b`la", getline('.'))
+
+ let t = 'voo "nah" sdf " asdf" sdf " sdf" sd'
+ put =t
+ normal! $F"va"oha"i"rz
+ call assert_equal('voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd', getline('.'))
+
+ let t = "-<b>asdf<i>Xasdf</i>asdf</b>-"
+ put =t
+ normal! fXdit
+ call assert_equal('-<b>asdf<i></i>asdf</b>-', getline('.'))
+
+ let t = "-<b>asdX<i>a<i />sdf</i>asdf</b>-"
+ put =t
+ normal! 0fXdit
+ call assert_equal('-<b></b>-', getline('.'))
+
+ let t = "-<b>asdf<i>Xasdf</i>asdf</b>-"
+ put =t
+ normal! fXdat
+ call assert_equal('-<b>asdfasdf</b>-', getline('.'))
+
+ let t = "-<b>asdX<i>as<b />df</i>asdf</b>-"
+ put =t
+ normal! 0fXdat
+ call assert_equal('--', getline('.'))
+
+ let t = "-<b>\ninnertext object\n</b>"
+ put =t
+ normal! dit
+ call assert_equal('-<b></b>', getline('.'))
+
+ set quoteescape&
+ enew!
+endfunc
+
+func Test_empty_html_tag()
+ new
+ call setline(1, '<div></div>')
+ normal 0citxxx
+ call assert_equal('<div>xxx</div>', getline(1))
+
+ call setline(1, '<div></div>')
+ normal 0f<cityyy
+ call assert_equal('<div>yyy</div>', getline(1))
+
+ call setline(1, '<div></div>')
+ normal 0f<vitsaaa
+ call assert_equal('aaa', getline(1))
+
+ bwipe!
+endfunc
+
+" Tests for match() and matchstr()
+func Test_match()
+ call assert_equal("b", matchstr("abcd", ".", 0, 2))
+ call assert_equal("bc", matchstr("abcd", "..", 0, 2))
+ call assert_equal("c", matchstr("abcd", ".", 2, 0))
+ call assert_equal("a", matchstr("abcd", ".", 0, -1))
+ call assert_equal(-1, match("abcd", ".", 0, 5))
+ call assert_equal(0 , match("abcd", ".", 0, -1))
+ call assert_equal(0 , match('abc', '.', 0, 1))
+ call assert_equal(1 , match('abc', '.', 0, 2))
+ call assert_equal(2 , match('abc', '.', 0, 3))
+ call assert_equal(-1, match('abc', '.', 0, 4))
+ call assert_equal(1 , match('abc', '.', 1, 1))
+ call assert_equal(2 , match('abc', '.', 2, 1))
+ call assert_equal(-1, match('abc', '.', 3, 1))
+ call assert_equal(3 , match('abc', '$', 0, 1))
+ call assert_equal(-1, match('abc', '$', 0, 2))
+ call assert_equal(3 , match('abc', '$', 1, 1))
+ call assert_equal(3 , match('abc', '$', 2, 1))
+ call assert_equal(3 , match('abc', '$', 3, 1))
+ call assert_equal(-1, match('abc', '$', 4, 1))
+ call assert_equal(0 , match('abc', '\zs', 0, 1))
+ call assert_equal(1 , match('abc', '\zs', 0, 2))
+ call assert_equal(2 , match('abc', '\zs', 0, 3))
+ call assert_equal(3 , match('abc', '\zs', 0, 4))
+ call assert_equal(-1, match('abc', '\zs', 0, 5))
+ call assert_equal(1 , match('abc', '\zs', 1, 1))
+ call assert_equal(2 , match('abc', '\zs', 2, 1))
+ call assert_equal(3 , match('abc', '\zs', 3, 1))
+ call assert_equal(-1, match('abc', '\zs', 4, 1))
+endfunc
+
+" This was causing an illegal memory access
+func Test_inner_tag()
+ new
+ norm ixxx
+ call feedkeys("v", 'xt')
+ insert
+x
+x
+.
+ norm it
+ q!
+endfunc
+
+func Test_sentence()
+ enew!
+ call setline(1, 'A sentence. A sentence? A sentence!')
+
+ normal yis
+ call assert_equal('A sentence.', @")
+ normal yas
+ call assert_equal('A sentence. ', @")
+
+ normal )
+
+ normal yis
+ call assert_equal('A sentence?', @")
+ normal yas
+ call assert_equal('A sentence? ', @")
+
+ normal )
+
+ normal yis
+ call assert_equal('A sentence!', @")
+ normal yas
+ call assert_equal(' A sentence!', @")
+
+ normal 0
+ normal 2yis
+ call assert_equal('A sentence. ', @")
+ normal 3yis
+ call assert_equal('A sentence. A sentence?', @")
+ normal 2yas
+ call assert_equal('A sentence. A sentence? ', @")
+
+ %delete _
+endfunc
+
+func Test_sentence_with_quotes()
+ enew!
+ call setline(1, 'A "sentence." A sentence.')
+
+ normal yis
+ call assert_equal('A "sentence."', @")
+ normal yas
+ call assert_equal('A "sentence." ', @")
+
+ normal )
+
+ normal yis
+ call assert_equal('A sentence.', @")
+ normal yas
+ call assert_equal(' A sentence.', @")
+
+ %delete _
+endfunc
+
+func! Test_sentence_with_cursor_on_delimiter()
+ enew!
+ call setline(1, "A '([sentence.])' A sentence.")
+
+ normal! 15|yis
+ call assert_equal("A '([sentence.])'", @")
+ normal! 15|yas
+ call assert_equal("A '([sentence.])' ", @")
+
+ normal! 16|yis
+ call assert_equal("A '([sentence.])'", @")
+ normal! 16|yas
+ call assert_equal("A '([sentence.])' ", @")
+
+ normal! 17|yis
+ call assert_equal("A '([sentence.])'", @")
+ normal! 17|yas
+ call assert_equal("A '([sentence.])' ", @")
+
+ %delete _
+endfunc
diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim
index 9f58a35909..cdfdd473b9 100644
--- a/src/nvim/testdir/test_timers.vim
+++ b/src/nvim/testdir/test_timers.vim
@@ -4,29 +4,231 @@ if !has('timers')
finish
endif
+source shared.vim
+
func MyHandler(timer)
- let s:val += 1
+ let g:val += 1
+endfunc
+
+func MyHandlerWithLists(lists, timer)
+ let x = string(a:lists)
endfunc
func Test_oneshot()
- let s:val = 0
+ let g:val = 0
let timer = timer_start(50, 'MyHandler')
- sleep 200m
- call assert_equal(1, s:val)
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ if has('reltime')
+ call assert_inrange(40, 120, slept)
+ else
+ call assert_inrange(20, 120, slept)
+ endif
endfunc
func Test_repeat_three()
- let s:val = 0
+ let g:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': 3})
- sleep 500m
- call assert_equal(3, s:val)
+ let slept = WaitFor('g:val == 3')
+ call assert_equal(3, g:val)
+ if has('reltime')
+ call assert_inrange(120, 250, slept)
+ else
+ call assert_inrange(80, 200, slept)
+ endif
endfunc
func Test_repeat_many()
- let s:val = 0
+ call timer_stopall()
+ let g:val = 0
let timer = timer_start(50, 'MyHandler', {'repeat': -1})
sleep 200m
call timer_stop(timer)
- call assert_true(s:val > 1)
- call assert_true(s:val < 5)
+ call assert_inrange((has('mac') ? 1 : 2), 4, g:val)
+endfunc
+
+func Test_with_partial_callback()
+ let g:val = 0
+ let meow = {'one': 1}
+ function meow.bite(...)
+ let g:val += self.one
+ endfunction
+
+ call timer_start(50, meow.bite)
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ if has('reltime')
+ call assert_inrange(40, 130, slept)
+ else
+ call assert_inrange(20, 100, slept)
+ endif
+endfunc
+
+func Test_retain_partial()
+ call timer_start(50, function('MyHandlerWithLists', [['a']]))
+ call garbagecollect()
+ sleep 100m
+endfunc
+
+func Test_info()
+ let id = timer_start(1000, 'MyHandler')
+ let info = timer_info(id)
+ call assert_equal(id, info[0]['id'])
+ call assert_equal(1000, info[0]['time'])
+ call assert_equal("function('MyHandler')", string(info[0]['callback']))
+
+ let found = 0
+ for info in timer_info()
+ if info['id'] == id
+ let found += 1
+ endif
+ endfor
+ call assert_equal(1, found)
+
+ call timer_stop(id)
+ call assert_equal([], timer_info(id))
+endfunc
+
+func Test_stopall()
+ call timer_stopall()
+ let id1 = timer_start(1000, 'MyHandler')
+ let id2 = timer_start(2000, 'MyHandler')
+ let info = timer_info()
+ call assert_equal(2, len(info))
+
+ call timer_stopall()
+ let info = timer_info()
+ call assert_equal(0, len(info))
+endfunc
+
+func Test_paused()
+ let g:val = 0
+
+ let id = timer_start(50, 'MyHandler')
+ let info = timer_info(id)
+ call assert_equal(0, info[0]['paused'])
+
+ call timer_pause(id, 1)
+ let info = timer_info(id)
+ call assert_equal(1, info[0]['paused'])
+ sleep 200m
+ call assert_equal(0, g:val)
+
+ call timer_pause(id, 0)
+ let info = timer_info(id)
+ call assert_equal(0, info[0]['paused'])
+
+ let slept = WaitFor('g:val == 1')
+ call assert_equal(1, g:val)
+ if has('reltime')
+ call assert_inrange(0, 140, slept)
+ else
+ call assert_inrange(0, 10, slept)
+ endif
+endfunc
+
+func StopMyself(timer)
+ let g:called += 1
+ if g:called == 2
+ call timer_stop(a:timer)
+ endif
+endfunc
+
+func Test_delete_myself()
+ let g:called = 0
+ let t = timer_start(10, 'StopMyself', {'repeat': -1})
+ call WaitFor('g:called == 2')
+ call assert_equal(2, g:called)
+ call assert_equal([], timer_info(t))
endfunc
+
+func StopTimer1(timer)
+ let g:timer2 = timer_start(10, 'StopTimer2')
+ " avoid maxfuncdepth error
+ call timer_pause(g:timer1, 1)
+ sleep 40m
+endfunc
+
+func StopTimer2(timer)
+ call timer_stop(g:timer1)
+endfunc
+
+func Test_stop_in_callback()
+ let g:timer1 = timer_start(10, 'StopTimer1')
+ sleep 40m
+endfunc
+
+func StopTimerAll(timer)
+ call timer_stopall()
+endfunc
+
+func Test_stop_all_in_callback()
+ call timer_stopall()
+ let g:timer1 = timer_start(10, 'StopTimerAll')
+ let info = timer_info()
+ call assert_equal(1, len(info))
+ if has('mac')
+ sleep 100m
+ endif
+ sleep 40m
+ let info = timer_info()
+ call assert_equal(0, len(info))
+endfunc
+
+func FeedkeysCb(timer)
+ call feedkeys("hello\<CR>", 'nt')
+endfunc
+
+func InputCb(timer)
+ call timer_start(10, 'FeedkeysCb')
+ let g:val = input('?')
+ call Resume()
+endfunc
+
+func Test_input_in_timer()
+ let g:val = ''
+ call timer_start(10, 'InputCb')
+ call Standby(1000)
+ call assert_equal('hello', g:val)
+endfunc
+
+func FuncWithCaughtError(timer)
+ let g:call_count += 1
+ try
+ doesnotexist
+ catch
+ " nop
+ endtry
+endfunc
+
+func Test_timer_catch_error()
+ let g:call_count = 0
+ let timer = timer_start(10, 'FuncWithCaughtError', {'repeat': 4})
+ " Timer will not be stopped.
+ call WaitFor('g:call_count == 4')
+ sleep 50m
+ call assert_equal(4, g:call_count)
+endfunc
+
+func FeedAndPeek(timer)
+ call test_feedinput('a')
+ call getchar(1)
+endfunc
+
+func Interrupt(timer)
+ call test_feedinput("\<C-C>")
+endfunc
+
+func Test_peek_and_get_char()
+ throw 'skipped: Nvim does not support test_feedinput()'
+ if !has('unix') && !has('gui_running')
+ return
+ endif
+ call timer_start(0, 'FeedAndPeek')
+ let intr = timer_start(100, 'Interrupt')
+ let c = getchar()
+ call assert_equal(char2nr('a'), c)
+ call timer_stop(intr)
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_true_false.vim b/src/nvim/testdir/test_true_false.vim
new file mode 100644
index 0000000000..84aca737ac
--- /dev/null
+++ b/src/nvim/testdir/test_true_false.vim
@@ -0,0 +1,150 @@
+" Test behavior of boolean-like values.
+
+" Test what is explained at ":help TRUE" and ":help FALSE".
+func Test_if()
+ if v:false
+ call assert_true(false, 'v:false is false')
+ endif
+ if 0
+ call assert_true(false, 'zero is false')
+ endif
+ if "0"
+ call assert_true(false, 'zero string is false')
+ endif
+ if "foo"
+ call assert_true(false, 'foo is false')
+ endif
+ if " "
+ call assert_true(false, 'space is false')
+ endif
+ if empty("foo")
+ call assert_true(false, 'foo is not empty')
+ endif
+
+ if v:true
+ else
+ call assert_true(false, 'v:true is true')
+ endif
+ if 1
+ else
+ call assert_true(false, 'one is true')
+ endif
+ if "1"
+ else
+ call assert_true(false, 'one string is true')
+ endif
+ if "1foo"
+ else
+ call assert_true(false, 'one in string is true')
+ endif
+
+ call assert_fails('if [1]', 'E745')
+ call assert_fails('if {1: 1}', 'E728')
+ call assert_fails('if function("string")', 'E703')
+ call assert_fails('if 1.3")', 'E805')
+endfunc
+
+function Try_arg_true_false(expr, false_val, true_val)
+ for v in ['v:false', '0', '"0"', '"foo"', '" "']
+ let r = eval(substitute(a:expr, '%v%', v, ''))
+ call assert_equal(a:false_val, r, 'result for ' . v . ' is not ' . string(a:false_val) . ' but ' . string(r))
+ endfor
+ for v in ['v:true', '1', '"1"', '"1foo"']
+ let r = eval(substitute(a:expr, '%v%', v, ''))
+ call assert_equal(a:true_val, r, 'result for ' . v . ' is not ' . string(a:true_val) . ' but ' . string(r))
+ endfor
+endfunc
+
+" Test using TRUE or FALSE values for an argument.
+func Test_true_false_arg()
+ call Try_arg_true_false('count(["a", "A"], "a", %v%)', 1, 2)
+
+ set wildignore=*.swp
+ call Try_arg_true_false('expand("foo.swp", %v%)', "", "foo.swp")
+ call Try_arg_true_false('expand("foo.vim", 0, %v%)', "foo.vim", ["foo.vim"])
+
+ call setreg('a', ['x', 'y'])
+ call Try_arg_true_false('getreg("a", 1, %v%)', "x\ny\n", ['x', 'y'])
+
+ set wildignore=*.vim
+ call Try_arg_true_false('glob("runtest.vim", %v%)', "", "runtest.vim")
+ set wildignore=*.swp
+ call Try_arg_true_false('glob("runtest.vim", 0, %v%)', "runtest.vim", ["runtest.vim"])
+ if has('unix')
+ silent !ln -s doesntexit Xlink
+ call Try_arg_true_false('glob("Xlink", 0, 0, %v%)', "", "Xlink")
+ silent !rm Xlink
+ endif
+
+ set wildignore=*.vim
+ call Try_arg_true_false('globpath(".", "runtest.vim", %v%)', "", "./runtest.vim")
+ set wildignore=*.swp
+ call Try_arg_true_false('globpath(".", "runtest.vim", 0, %v%)', "./runtest.vim", ["./runtest.vim"])
+ if has('unix')
+ silent !ln -s doesntexit Xlink
+ call Try_arg_true_false('globpath(".", "Xlink", 0, 0, %v%)', "", "./Xlink")
+ silent !rm Xlink
+ endif
+
+ abbr asdf asdff
+ call Try_arg_true_false('hasmapto("asdff", "i", %v%)', 0, 1)
+
+ call Try_arg_true_false('index(["a", "A"], "A", 0, %v%)', 1, 0)
+
+ function FilterMapArg(d)
+ if type(a:d) == type({})
+ return filter(a:d, 'v:key == "rhs"')
+ endif
+ return a:d
+ endfunction
+ call Try_arg_true_false('maparg("asdf", "i", %v%)', "", "asdff")
+ call Try_arg_true_false('FilterMapArg(maparg("asdf", "i", 1, %v%))', "asdff", {'rhs': 'asdff'})
+
+ call Try_arg_true_false('hasmapto("asdf", "i", %v%)', 0, 1)
+
+ new colored
+ call setline(1, '<here>')
+ syn match brackets "<.*>"
+ syn match here "here" transparent
+ let brackets_id = synID(1, 1, 0)
+ let here_id = synID(1, 3, 0)
+ call Try_arg_true_false('synID(1, 3, %v%)', here_id, brackets_id)
+ bwipe!
+endfunc
+
+function Try_arg_non_zero(expr, false_val, true_val)
+ for v in ['v:false', '0', '[1]', '{2:3}', '3.4']
+ let r = eval(substitute(a:expr, '%v%', v, ''))
+ call assert_equal(a:false_val, r, 'result for ' . v . ' is not ' . a:false_val . ' but ' . r)
+ endfor
+ for v in ['v:true', '1', '" "', '"0"']
+ let r = eval(substitute(a:expr, '%v%', v, ''))
+ call assert_equal(a:true_val, r, 'result for ' . v . ' is not ' . a:true_val . ' but ' . r)
+ endfor
+endfunc
+
+
+" Test using non-zero-arg for an argument.
+func Test_non_zero_arg()
+ " call test_settime(93784)
+ " call Try_arg_non_zero("mode(%v%)", 'x', 'x!')
+ " call test_settime(0)
+
+ call Try_arg_non_zero("shellescape('foo%', %v%)", "'foo%'", "'foo\\%'")
+
+ " visualmode() needs to be called twice to check
+ for v in [v:false, 0, [1], {2:3}, 3.4]
+ normal vv
+ let r = visualmode(v)
+ call assert_equal('v', r, 'result for ' . string(v) . ' is not "v" but ' . r)
+ let r = visualmode(v)
+ call assert_equal('v', r, 'result for ' . string(v) . ' is not "v" but ' . r)
+ endfor
+ for v in [v:true, 1, " ", "0"]
+ normal vv
+ let r = visualmode(v)
+ call assert_equal('v', r, 'result for ' . v . ' is not "v" but ' . r)
+ let r = visualmode(v)
+ call assert_equal('', r, 'result for ' . v . ' is not "" but ' . r)
+ endfor
+endfunc
diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim
new file mode 100644
index 0000000000..9729ca9f57
--- /dev/null
+++ b/src/nvim/testdir/test_undo.vim
@@ -0,0 +1,436 @@
+" Tests for the undo tree.
+" Since this script is sourced we need to explicitly break changes up in
+" undo-able pieces. Do that by setting 'undolevels'.
+" Also tests :earlier and :later.
+
+func Test_undotree()
+ new
+
+ normal! Aabc
+ set ul=100
+ let d = undotree()
+ call assert_equal(1, d.seq_last)
+ call assert_equal(1, d.seq_cur)
+ call assert_equal(0, d.save_last)
+ call assert_equal(0, d.save_cur)
+ call assert_equal(1, len(d.entries))
+ call assert_equal(1, d.entries[0].newhead)
+ call assert_equal(1, d.entries[0].seq)
+ call assert_true(d.entries[0].time <= d.time_cur)
+
+ normal! Adef
+ set ul=100
+ let d = undotree()
+ call assert_equal(2, d.seq_last)
+ call assert_equal(2, d.seq_cur)
+ call assert_equal(0, d.save_last)
+ call assert_equal(0, d.save_cur)
+ call assert_equal(2, len(d.entries))
+ call assert_equal(1, d.entries[0].seq)
+ call assert_equal(1, d.entries[1].newhead)
+ call assert_equal(2, d.entries[1].seq)
+ call assert_true(d.entries[1].time <= d.time_cur)
+
+ undo
+ set ul=100
+ let d = undotree()
+ call assert_equal(2, d.seq_last)
+ call assert_equal(1, d.seq_cur)
+ call assert_equal(0, d.save_last)
+ call assert_equal(0, d.save_cur)
+ call assert_equal(2, len(d.entries))
+ call assert_equal(1, d.entries[0].seq)
+ call assert_equal(1, d.entries[1].curhead)
+ call assert_equal(1, d.entries[1].newhead)
+ call assert_equal(2, d.entries[1].seq)
+ call assert_true(d.entries[1].time == d.time_cur)
+
+ normal! Aghi
+ set ul=100
+ let d = undotree()
+ call assert_equal(3, d.seq_last)
+ call assert_equal(3, d.seq_cur)
+ call assert_equal(0, d.save_last)
+ call assert_equal(0, d.save_cur)
+ call assert_equal(2, len(d.entries))
+ call assert_equal(1, d.entries[0].seq)
+ call assert_equal(2, d.entries[1].alt[0].seq)
+ call assert_equal(1, d.entries[1].newhead)
+ call assert_equal(3, d.entries[1].seq)
+ call assert_true(d.entries[1].time <= d.time_cur)
+
+ undo
+ set ul=100
+ let d = undotree()
+ call assert_equal(3, d.seq_last)
+ call assert_equal(1, d.seq_cur)
+ call assert_equal(0, d.save_last)
+ call assert_equal(0, d.save_cur)
+ call assert_equal(2, len(d.entries))
+ call assert_equal(1, d.entries[0].seq)
+ call assert_equal(2, d.entries[1].alt[0].seq)
+ call assert_equal(1, d.entries[1].curhead)
+ call assert_equal(1, d.entries[1].newhead)
+ call assert_equal(3, d.entries[1].seq)
+ call assert_true(d.entries[1].time == d.time_cur)
+
+ w! Xtest
+ let d = undotree()
+ call assert_equal(1, d.save_cur)
+ call assert_equal(1, d.save_last)
+ call delete('Xtest')
+ bwipe! Xtest
+endfunc
+
+func FillBuffer()
+ for i in range(1,13)
+ put=i
+ " Set 'undolevels' to split undo.
+ exe "setg ul=" . &g:ul
+ endfor
+endfunc
+
+func Test_global_local_undolevels()
+ new one
+ set undolevels=5
+ call FillBuffer()
+ " will only undo the last 5 changes, end up with 13 - (5 + 1) = 7 lines
+ earlier 10
+ call assert_equal(5, &g:undolevels)
+ call assert_equal(-123456, &l:undolevels)
+ call assert_equal('7', getline('$'))
+
+ new two
+ setlocal undolevels=2
+ call FillBuffer()
+ " will only undo the last 2 changes, end up with 13 - (2 + 1) = 10 lines
+ earlier 10
+ call assert_equal(5, &g:undolevels)
+ call assert_equal(2, &l:undolevels)
+ call assert_equal('10', getline('$'))
+
+ setlocal ul=10
+ call assert_equal(5, &g:undolevels)
+ call assert_equal(10, &l:undolevels)
+
+ " Setting local value in "two" must not change local value in "one"
+ wincmd p
+ call assert_equal(5, &g:undolevels)
+ call assert_equal(-123456, &l:undolevels)
+
+ new three
+ setglobal ul=50
+ call assert_equal(50, &g:undolevels)
+ call assert_equal(-123456, &l:undolevels)
+
+ " Drop created windows
+ set ul&
+ new
+ only!
+endfunc
+
+func BackOne(expected)
+ call feedkeys('g-', 'xt')
+ call assert_equal(a:expected, getline(1))
+endfunc
+
+func Test_undo_del_chars()
+ throw 'skipped: Nvim does not support test_settime()'
+
+ " Setup a buffer without creating undo entries
+ new
+ set ul=-1
+ call setline(1, ['123-456'])
+ set ul=100
+ 1
+ call test_settime(100)
+
+ " Delete three characters and undo with g-
+ call feedkeys('x', 'xt')
+ call feedkeys('x', 'xt')
+ call feedkeys('x', 'xt')
+ call assert_equal('-456', getline(1))
+ call BackOne('3-456')
+ call BackOne('23-456')
+ call BackOne('123-456')
+ call assert_fails("BackOne('123-456')")
+
+ :" Delete three other characters and go back in time with g-
+ call feedkeys('$x', 'xt')
+ call feedkeys('x', 'xt')
+ call feedkeys('x', 'xt')
+ call assert_equal('123-', getline(1))
+ call test_settime(101)
+
+ call BackOne('123-4')
+ call BackOne('123-45')
+ " skips '123-456' because it's older
+ call BackOne('-456')
+ call BackOne('3-456')
+ call BackOne('23-456')
+ call BackOne('123-456')
+ call assert_fails("BackOne('123-456')")
+ normal 10g+
+ call assert_equal('123-', getline(1))
+
+ :" Jump two seconds and go some seconds forward and backward
+ call test_settime(103)
+ call feedkeys("Aa\<Esc>", 'xt')
+ call feedkeys("Ab\<Esc>", 'xt')
+ call feedkeys("Ac\<Esc>", 'xt')
+ call assert_equal('123-abc', getline(1))
+ earlier 1s
+ call assert_equal('123-', getline(1))
+ earlier 3s
+ call assert_equal('123-456', getline(1))
+ later 1s
+ call assert_equal('123-', getline(1))
+ later 1h
+ call assert_equal('123-abc', getline(1))
+
+ close!
+endfunc
+
+func Test_undolist()
+ new
+ set ul=100
+
+ let a = execute('undolist')
+ call assert_equal("\nNothing to undo", a)
+
+ " 1 leaf (2 changes).
+ call feedkeys('achange1', 'xt')
+ call feedkeys('achange2', 'xt')
+ let a = execute('undolist')
+ call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a)
+
+ " 2 leaves.
+ call feedkeys('u', 'xt')
+ call feedkeys('achange3\<Esc>', 'xt')
+ let a = execute('undolist')
+ call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a)
+ close!
+endfunc
+
+func Test_U_command()
+ new
+ set ul=100
+ call feedkeys("achange1\<Esc>", 'xt')
+ call feedkeys("achange2\<Esc>", 'xt')
+ norm! U
+ call assert_equal('', getline(1))
+ norm! U
+ call assert_equal('change1change2', getline(1))
+ close!
+endfunc
+
+func Test_undojoin()
+ new
+ call feedkeys("Goaaaa\<Esc>", 'xt')
+ call feedkeys("obbbb\<Esc>", 'xt')
+ call assert_equal(['aaaa', 'bbbb'], getline(2, '$'))
+ call feedkeys("u", 'xt')
+ call assert_equal(['aaaa'], getline(2, '$'))
+ call feedkeys("obbbb\<Esc>", 'xt')
+ undojoin
+ " Note: next change must not be as if typed
+ call feedkeys("occcc\<Esc>", 'x')
+ call assert_equal(['aaaa', 'bbbb', 'cccc'], getline(2, '$'))
+ call feedkeys("u", 'xt')
+ call assert_equal(['aaaa'], getline(2, '$'))
+ close!
+endfunc
+
+func Test_undo_write()
+ split Xtest
+ call feedkeys("ione one one\<Esc>", 'xt')
+ w!
+ call feedkeys("otwo\<Esc>", 'xt')
+ call feedkeys("otwo\<Esc>", 'xt')
+ w
+ call feedkeys("othree\<Esc>", 'xt')
+ call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
+ earlier 1f
+ call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
+ earlier 1f
+ call assert_equal(['one one one'], getline(1, '$'))
+ earlier 1f
+ call assert_equal([''], getline(1, '$'))
+ later 1f
+ call assert_equal(['one one one'], getline(1, '$'))
+ later 1f
+ call assert_equal(['one one one', 'two', 'two'], getline(1, '$'))
+ later 1f
+ call assert_equal(['one one one', 'two', 'two', 'three'], getline(1, '$'))
+
+ close!
+ call delete('Xtest')
+ bwipe! Xtest
+endfunc
+
+func Test_insert_expr()
+ new
+ " calling setline() triggers undo sync
+ call feedkeys("oa\<Esc>", 'xt')
+ call feedkeys("ob\<Esc>", 'xt')
+ set ul=100
+ call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
+ call assert_equal(['a', 'b', '120', '34'], getline(2, '$'))
+ call feedkeys("u", 'x')
+ call assert_equal(['a', 'b', '12'], getline(2, '$'))
+ call feedkeys("u", 'x')
+ call assert_equal(['a', 'b'], getline(2, '$'))
+
+ call feedkeys("oc\<Esc>", 'xt')
+ set ul=100
+ call feedkeys("o1\<Esc>a2\<C-R>=setline('.','1234')\<CR>\<CR>\<Esc>", 'x')
+ call assert_equal(['a', 'b', 'c', '120', '34'], getline(2, '$'))
+ call feedkeys("u", 'x')
+ call assert_equal(['a', 'b', 'c', '12'], getline(2, '$'))
+
+ call feedkeys("od\<Esc>", 'xt')
+ set ul=100
+ call feedkeys("o1\<Esc>a2\<C-R>=string(123)\<CR>\<Esc>", 'x')
+ call assert_equal(['a', 'b', 'c', '12', 'd', '12123'], getline(2, '$'))
+ call feedkeys("u", 'x')
+ call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
+
+ close!
+endfunc
+
+func Test_undofile_earlier()
+ throw 'skipped: Nvim does not support test_settime()'
+
+ let t0 = localtime() - 43200
+ call test_settime(t0)
+ new Xfile
+ call feedkeys("ione\<Esc>", 'xt')
+ set ul=100
+ call test_settime(t0 + 1)
+ call feedkeys("otwo\<Esc>", 'xt')
+ set ul=100
+ call test_settime(t0 + 2)
+ call feedkeys("othree\<Esc>", 'xt')
+ set ul=100
+ w
+ wundo Xundofile
+ bwipe!
+ " restore normal timestamps.
+ call test_settime(0)
+ new Xfile
+ rundo Xundofile
+ earlier 1d
+ call assert_equal('', getline(1))
+ bwipe!
+ call delete('Xfile')
+ call delete('Xundofile')
+endfunc
+
+" Test for undo working properly when executing commands from a register.
+" Also test this in an empty buffer.
+func Test_cmd_in_reg_undo()
+ enew!
+ let @a = "Ox\<Esc>jAy\<Esc>kdd"
+ edit +/^$ test_undo.vim
+ normal @au
+ call assert_equal(0, &modified)
+ return
+ new
+ normal @au
+ call assert_equal(0, &modified)
+ only!
+ let @a = ''
+endfunc
+
+func Test_redo_empty_line()
+ new
+ exe "norm\x16r\x160"
+ exe "norm."
+ bwipe!
+endfunc
+
+" This used to cause an illegal memory access
+func Test_undo_append()
+ new
+ call feedkeys("axx\<Esc>v", 'xt')
+ undo
+ norm o
+ quit
+endfunc
+
+funct Test_undofile()
+ " Test undofile() without setting 'undodir'.
+ if has('persistent_undo')
+ call assert_equal(fnamemodify('.Xundofoo.un~', ':p'), undofile('Xundofoo'))
+ else
+ call assert_equal('', undofile('Xundofoo'))
+ endif
+ call assert_equal('', undofile(''))
+
+ " Test undofile() with 'undodir' set to to an existing directory.
+ call mkdir('Xundodir')
+ set undodir=Xundodir
+ let cwd = getcwd()
+ if has('win32')
+ " Replace windows drive such as C:... into C%...
+ let cwd = substitute(cwd, '^\([a-zA-Z]\):', '\1%', 'g')
+ endif
+ let pathsep = has('win32') ? '\' : '/'
+ let cwd = substitute(cwd . pathsep . 'Xundofoo', pathsep, '%', 'g')
+ if has('persistent_undo')
+ call assert_equal('Xundodir' . pathsep . cwd, undofile('Xundofoo'))
+ else
+ call assert_equal('', undofile('Xundofoo'))
+ endif
+ call assert_equal('', undofile(''))
+ call delete('Xundodir', 'd')
+
+ " Test undofile() with 'undodir' set to a non-existing directory.
+ " call assert_equal('', undofile('Xundofoo'))
+
+ set undodir&
+endfunc
+
+func Test_undo_0()
+ new
+ set ul=100
+ normal i1
+ undo
+ normal i2
+ undo
+ normal i3
+
+ undo 0
+ let d = undotree()
+ call assert_equal('', getline(1))
+ call assert_equal(0, d.seq_cur)
+
+ redo
+ let d = undotree()
+ call assert_equal('3', getline(1))
+ call assert_equal(3, d.seq_cur)
+
+ undo 2
+ undo 0
+ let d = undotree()
+ call assert_equal('', getline(1))
+ call assert_equal(0, d.seq_cur)
+
+ redo
+ let d = undotree()
+ call assert_equal('2', getline(1))
+ call assert_equal(2, d.seq_cur)
+
+ undo 1
+ undo 0
+ let d = undotree()
+ call assert_equal('', getline(1))
+ call assert_equal(0, d.seq_cur)
+
+ redo
+ let d = undotree()
+ call assert_equal('1', getline(1))
+ call assert_equal(1, d.seq_cur)
+
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_unlet.vim b/src/nvim/testdir/test_unlet.vim
index f6705997a9..b02bdaab3b 100644
--- a/src/nvim/testdir/test_unlet.vim
+++ b/src/nvim/testdir/test_unlet.vim
@@ -3,7 +3,7 @@
func Test_read_only()
try
" this caused a crash
- unlet count
+ unlet v:count
catch
call assert_true(v:exception =~ ':E795:')
endtry
@@ -24,3 +24,41 @@ func Test_not_existing()
call assert_true(v:exception =~ ':E108:')
endtry
endfunc
+
+func Test_unlet_fails()
+ call assert_fails('unlet v:["count"]', 'E46:')
+endfunc
+
+func Test_unlet_env()
+ let envcmd = has('win32') ? 'set' : 'env'
+
+ let $FOOBAR = 'test'
+ let found = 0
+ for kv in split(system(envcmd), "\r*\n")
+ if kv == 'FOOBAR=test'
+ let found = 1
+ endif
+ endfor
+ call assert_equal(1, found)
+
+ unlet $FOOBAR
+ let found = 0
+ for kv in split(system(envcmd), "\r*\n")
+ if kv == 'FOOBAR=test'
+ let found = 1
+ endif
+ endfor
+ call assert_equal(0, found)
+
+ unlet $MUST_NOT_BE_AN_ERROR
+endfunc
+
+func Test_unlet_complete()
+ let g:FOOBAR = 1
+ call feedkeys(":unlet g:FOO\t\n", 'tx')
+ call assert_true(!exists('g:FOOBAR'))
+
+ let $FOOBAR = 1
+ call feedkeys(":unlet $FOO\t\n", 'tx')
+ call assert_true(!exists('$FOOBAR') || empty($FOOBAR))
+endfunc
diff --git a/src/nvim/testdir/test_user_func.vim b/src/nvim/testdir/test_user_func.vim
new file mode 100644
index 0000000000..e7a3701386
--- /dev/null
+++ b/src/nvim/testdir/test_user_func.vim
@@ -0,0 +1,96 @@
+" Test for user functions.
+" Also test an <expr> mapping calling a function.
+" Also test that a builtin function cannot be replaced.
+" Also test for regression when calling arbitrary expression.
+
+func Table(title, ...)
+ let ret = a:title
+ let idx = 1
+ while idx <= a:0
+ exe "let ret = ret . a:" . idx
+ let idx = idx + 1
+ endwhile
+ return ret
+endfunc
+
+func Compute(n1, n2, divname)
+ if a:n2 == 0
+ return "fail"
+ endif
+ exe "let g:" . a:divname . " = ". a:n1 / a:n2
+ return "ok"
+endfunc
+
+func Expr1()
+ silent! normal! v
+ return "111"
+endfunc
+
+func Expr2()
+ call search('XX', 'b')
+ return "222"
+endfunc
+
+func ListItem()
+ let g:counter += 1
+ return g:counter . '. '
+endfunc
+
+func ListReset()
+ let g:counter = 0
+ return ''
+endfunc
+
+func FuncWithRef(a)
+ unlet g:FuncRef
+ return a:a
+endfunc
+
+func Test_user_func()
+ let g:FuncRef=function("FuncWithRef")
+ let g:counter = 0
+ inoremap <expr> ( ListItem()
+ inoremap <expr> [ ListReset()
+ imap <expr> + Expr1()
+ imap <expr> * Expr2()
+ let g:retval = "nop"
+
+ call assert_equal('xxx4asdf', Table("xxx", 4, "asdf"))
+ call assert_equal('fail', Compute(45, 0, "retval"))
+ call assert_equal('nop', g:retval)
+ call assert_equal('ok', Compute(45, 5, "retval"))
+ call assert_equal(9, g:retval)
+ call assert_equal(333, g:FuncRef(333))
+
+ enew
+
+ normal oXX+-XX
+ call assert_equal('XX111-XX', getline('.'))
+ normal o---*---
+ call assert_equal('---222---', getline('.'))
+ normal o(one
+ call assert_equal('1. one', getline('.'))
+ normal o(two
+ call assert_equal('2. two', getline('.'))
+ normal o[(one again
+ call assert_equal('1. one again', getline('.'))
+
+ call assert_equal(3, max([1, 2, 3]))
+ call assert_fails("call extend(g:, {'max': function('min')})", 'E704')
+ call assert_equal(3, max([1, 2, 3]))
+
+ " Regression: the first line below used to throw ?E110: Missing ')'?
+ " Second is here just to prove that this line is correct when not skipping
+ " rhs of &&.
+ call assert_equal(0, (0 && (function('tr'))(1, 2, 3)))
+ call assert_equal(1, (1 && (function('tr'))(1, 2, 3)))
+
+ delfunc Table
+ delfunc Compute
+ delfunc Expr1
+ delfunc Expr2
+ delfunc ListItem
+ delfunc ListReset
+ unlet g:retval g:counter
+ enew!
+endfunc
diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim
new file mode 100644
index 0000000000..1520c2f32a
--- /dev/null
+++ b/src/nvim/testdir/test_usercommands.vim
@@ -0,0 +1,220 @@
+" Tests for user defined commands
+
+" Test for <mods> in user defined commands
+function Test_cmdmods()
+ let g:mods = ''
+
+ command! -nargs=* MyCmd let g:mods .= '<mods> '
+
+ MyCmd
+ aboveleft MyCmd
+ abo MyCmd
+ belowright MyCmd
+ bel MyCmd
+ botright MyCmd
+ bo MyCmd
+ browse MyCmd
+ bro MyCmd
+ confirm MyCmd
+ conf MyCmd
+ hide MyCmd
+ hid MyCmd
+ keepalt MyCmd
+ keepa MyCmd
+ keepjumps MyCmd
+ keepj MyCmd
+ keepmarks MyCmd
+ kee MyCmd
+ keeppatterns MyCmd
+ keepp MyCmd
+ leftabove MyCmd " results in :aboveleft
+ lefta MyCmd
+ lockmarks MyCmd
+ loc MyCmd
+ " noautocmd MyCmd
+ noswapfile MyCmd
+ nos MyCmd
+ rightbelow MyCmd " results in :belowright
+ rightb MyCmd
+ " sandbox MyCmd
+ silent MyCmd
+ sil MyCmd
+ tab MyCmd
+ topleft MyCmd
+ to MyCmd
+ " unsilent MyCmd
+ verbose MyCmd
+ verb MyCmd
+ vertical MyCmd
+ vert MyCmd
+
+ aboveleft belowright botright browse confirm hide keepalt keepjumps
+ \ keepmarks keeppatterns lockmarks noswapfile silent tab
+ \ topleft verbose vertical MyCmd
+
+ call assert_equal(' aboveleft aboveleft belowright belowright botright ' .
+ \ 'botright browse browse confirm confirm hide hide ' .
+ \ 'keepalt keepalt keepjumps keepjumps keepmarks keepmarks ' .
+ \ 'keeppatterns keeppatterns aboveleft aboveleft lockmarks lockmarks noswapfile ' .
+ \ 'noswapfile belowright belowright silent silent tab topleft topleft verbose verbose ' .
+ \ 'vertical vertical ' .
+ \ 'aboveleft belowright botright browse confirm hide keepalt keepjumps ' .
+ \ 'keepmarks keeppatterns lockmarks noswapfile silent tab topleft ' .
+ \ 'verbose vertical ', g:mods)
+
+ let g:mods = ''
+ command! -nargs=* MyQCmd let g:mods .= '<q-mods> '
+
+ vertical MyQCmd
+ call assert_equal('"vertical" ', g:mods)
+
+ delcommand MyCmd
+ delcommand MyQCmd
+ unlet g:mods
+endfunction
+
+func Test_Ambiguous()
+ command Doit let g:didit = 'yes'
+ command Dothat let g:didthat = 'also'
+ call assert_fails('Do', 'E464:')
+ Doit
+ call assert_equal('yes', g:didit)
+ Dothat
+ call assert_equal('also', g:didthat)
+ unlet g:didit
+ unlet g:didthat
+
+ delcommand Doit
+ Do
+ call assert_equal('also', g:didthat)
+ delcommand Dothat
+endfunc
+
+func Test_CmdUndefined()
+ call assert_fails('Doit', 'E492:')
+ au CmdUndefined Doit :command Doit let g:didit = 'yes'
+ Doit
+ call assert_equal('yes', g:didit)
+ delcommand Doit
+
+ call assert_fails('Dothat', 'E492:')
+ au CmdUndefined * let g:didnot = 'yes'
+ call assert_fails('Dothat', 'E492:')
+ call assert_equal('yes', g:didnot)
+endfunc
+
+func Test_CmdErrors()
+ call assert_fails('com! docmd :', 'E183:')
+ call assert_fails('com! \<Tab> :', 'E182:')
+ call assert_fails('com! _ :', 'E182:')
+ call assert_fails('com! X :', 'E841:')
+ call assert_fails('com! - DoCmd :', 'E175:')
+ call assert_fails('com! -xxx DoCmd :', 'E181:')
+ call assert_fails('com! -addr DoCmd :', 'E179:')
+ call assert_fails('com! -complete DoCmd :', 'E179:')
+ call assert_fails('com! -complete=xxx DoCmd :', 'E180:')
+ call assert_fails('com! -complete=custom DoCmd :', 'E467:')
+ call assert_fails('com! -complete=customlist DoCmd :', 'E467:')
+ call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:')
+ call assert_fails('com! -nargs=x DoCmd :', 'E176:')
+ call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:')
+ call assert_fails('com! -count=x DoCmd :', 'E178:')
+ call assert_fails('com! -range=x DoCmd :', 'E178:')
+
+ com! -nargs=0 DoCmd :
+ call assert_fails('DoCmd x', 'E488:')
+
+ com! -nargs=1 DoCmd :
+ call assert_fails('DoCmd', 'E471:')
+
+ com! -nargs=+ DoCmd :
+ call assert_fails('DoCmd', 'E471:')
+
+ call assert_fails('com DoCmd :', 'E174:')
+ comclear
+ call assert_fails('delcom DoCmd', 'E184:')
+endfunc
+
+func CustomComplete(A, L, P)
+ return "January\nFebruary\nMars\n"
+endfunc
+
+func CustomCompleteList(A, L, P)
+ return [ "Monday", "Tuesday", "Wednesday" ]
+endfunc
+
+func Test_CmdCompletion()
+ call feedkeys(":com -\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"com -addr bang bar buffer complete count nargs range register', @:)
+
+ call feedkeys(":com -nargs=0 -\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"com -nargs=0 -addr bang bar buffer complete count nargs range register', @:)
+
+ call feedkeys(":com -nargs=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"com -nargs=* + 0 1 ?', @:)
+
+ call feedkeys(":com -addr=\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"com -addr=arguments buffers lines loaded_buffers quickfix tabs windows', @:)
+
+ call feedkeys(":com -complete=co\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"com -complete=color command compiler', @:)
+
+ command! DoCmd1 :
+ command! DoCmd2 :
+ call feedkeys(":com \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"com DoCmd1 DoCmd2', @:)
+
+ call feedkeys(":DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"DoCmd1 DoCmd2', @:)
+
+ call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"delcom DoCmd1 DoCmd2', @:)
+
+ delcom DoCmd1
+ call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"delcom DoCmd2', @:)
+
+ call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"com DoCmd2', @:)
+
+ delcom DoCmd2
+ call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"delcom DoC', @:)
+
+ call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"com DoC', @:)
+
+ com! -complete=behave DoCmd :
+ call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"DoCmd mswin xterm', @:)
+
+ " This does not work. Why?
+ "call feedkeys(":DoCmd x\<C-A>\<C-B>\"\<CR>", 'tx')
+ "call assert_equal('"DoCmd xterm', @:)
+
+ com! -complete=custom,CustomComplete DoCmd :
+ call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"DoCmd January February Mars', @:)
+
+ com! -complete=customlist,CustomCompleteList DoCmd :
+ call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"DoCmd Monday Tuesday Wednesday', @:)
+
+ com! -complete=custom,CustomCompleteList DoCmd :
+ call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:')
+
+ com! -complete=customlist,CustomComp DoCmd :
+ call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:')
+endfunc
+
+func CallExecute(A, L, P)
+ " Drop first '\n'
+ return execute('echo "hi"')[1:]
+endfunc
+
+func Test_use_execute_in_completion()
+ command! -nargs=* -complete=custom,CallExecute DoExec :
+ call feedkeys(":DoExec \<C-A>\<C-B>\"\<CR>", 'tx')
+ call assert_equal('"DoExec hi', @:)
+ delcommand DoExec
+endfunc
diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim
new file mode 100644
index 0000000000..24e3db86fb
--- /dev/null
+++ b/src/nvim/testdir/test_utf8.vim
@@ -0,0 +1,65 @@
+" Tests for Unicode manipulations
+if !has('multi_byte')
+ finish
+endif
+
+
+" Visual block Insert adjusts for multi-byte char
+func Test_visual_block_insert()
+ new
+ call setline(1, ["aaa", "ã‚ã‚ã‚", "bbb"])
+ exe ":norm! gg0l\<C-V>jjIx\<Esc>"
+ call assert_equal(['axaa', 'xã‚ã‚ã‚', 'bxbb'], getline(1, '$'))
+ bwipeout!
+endfunc
+
+" Test for built-in function strchars()
+func Test_strchars()
+ let inp = ["a", "ã‚ã„a", "A\u20dd", "A\u20dd\u20dd", "\u20dd"]
+ let exp = [[1, 1, 1], [3, 3, 3], [2, 2, 1], [3, 3, 1], [1, 1, 1]]
+ for i in range(len(inp))
+ call assert_equal(exp[i][0], strchars(inp[i]))
+ call assert_equal(exp[i][1], strchars(inp[i], 0))
+ call assert_equal(exp[i][2], strchars(inp[i], 1))
+ endfor
+endfunc
+
+" Test for customlist completion
+function! CustomComplete1(lead, line, pos)
+ return ['ã‚', 'ã„']
+endfunction
+
+function! CustomComplete2(lead, line, pos)
+ return ['ã‚ãŸã—', 'ã‚ãŸã¾', 'ã‚ãŸã‚Šã‚']
+endfunction
+
+function! CustomComplete3(lead, line, pos)
+ return ['Nã“', 'Nã‚“', 'Nã¶']
+endfunction
+
+func Test_customlist_completion()
+ command -nargs=1 -complete=customlist,CustomComplete1 Test1 echo
+ call feedkeys(":Test1 \<C-L>\<C-B>\"\<CR>", 'itx')
+ call assert_equal('"Test1 ', getreg(':'))
+
+ command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo
+ call feedkeys(":Test2 \<C-L>\<C-B>\"\<CR>", 'itx')
+ call assert_equal('"Test2 ã‚ãŸ', getreg(':'))
+
+ command -nargs=1 -complete=customlist,CustomComplete3 Test3 echo
+ call feedkeys(":Test3 \<C-L>\<C-B>\"\<CR>", 'itx')
+ call assert_equal('"Test3 N', getreg(':'))
+
+ call garbagecollect(1)
+endfunc
+
+" Yank one 3 byte character and check the mark columns.
+func Test_getvcol()
+ new
+ call setline(1, "x\u2500x")
+ normal 0lvy
+ call assert_equal(2, col("'["))
+ call assert_equal(4, col("']"))
+ call assert_equal(2, virtcol("'["))
+ call assert_equal(2, virtcol("']"))
+endfunc
diff --git a/src/nvim/testdir/test_utf8_comparisons.vim b/src/nvim/testdir/test_utf8_comparisons.vim
new file mode 100644
index 0000000000..576e86142f
--- /dev/null
+++ b/src/nvim/testdir/test_utf8_comparisons.vim
@@ -0,0 +1,95 @@
+" Tests for case-insensitive UTF-8 comparisons (utf_strnicmp() in mbyte.c)
+" Also test "g~ap".
+
+if !has("multi_byte")
+ finish
+endif
+
+function! Ch(a, op, b, expected)
+ call assert_equal(eval(printf('"%s" %s "%s"', a:a, a:op, a:b)), a:expected,
+ \ printf('"%s" %s "%s" should return %d', a:a, a:op, a:b, a:expected))
+endfunction
+
+function! Chk(a, b, result)
+ if a:result == 0
+ call Ch(a:a, '==?', a:b, 1)
+ call Ch(a:a, '!=?', a:b, 0)
+ call Ch(a:a, '<=?', a:b, 1)
+ call Ch(a:a, '>=?', a:b, 1)
+ call Ch(a:a, '<?', a:b, 0)
+ call Ch(a:a, '>?', a:b, 0)
+ elseif a:result > 0
+ call Ch(a:a, '==?', a:b, 0)
+ call Ch(a:a, '!=?', a:b, 1)
+ call Ch(a:a, '<=?', a:b, 0)
+ call Ch(a:a, '>=?', a:b, 1)
+ call Ch(a:a, '<?', a:b, 0)
+ call Ch(a:a, '>?', a:b, 1)
+ else
+ call Ch(a:a, '==?', a:b, 0)
+ call Ch(a:a, '!=?', a:b, 1)
+ call Ch(a:a, '<=?', a:b, 1)
+ call Ch(a:a, '>=?', a:b, 0)
+ call Ch(a:a, '<?', a:b, 1)
+ call Ch(a:a, '>?', a:b, 0)
+ endif
+endfunction
+
+function! Check(a, b, result)
+ call Chk(a:a, a:b, a:result)
+ call Chk(a:b, a:a, -a:result)
+endfunction
+
+function! LT(a, b)
+ call Check(a:a, a:b, -1)
+endfunction
+
+function! GT(a, b)
+ call Check(a:a, a:b, 1)
+endfunction
+
+function! EQ(a, b)
+ call Check(a:a, a:b, 0)
+endfunction
+
+function Test_comparisons()
+ call EQ('', '')
+ call LT('', 'a')
+ call EQ('abc', 'abc')
+ call EQ('Abc', 'abC')
+ call LT('ab', 'abc')
+ call LT('AB', 'abc')
+ call LT('ab', 'aBc')
+ call EQ('\xd0\xb9\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd', '\xd0\xb9\xd0\xa6\xd0\xa3\xd0\xba\xd0\x95\xd0\xbd')
+ call LT('\xd0\xb9\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd', '\xd0\xaf\xd1\x86\xd1\x83\xd0\xba\xd0\xb5\xd0\xbd')
+ call EQ('\xe2\x84\xaa', 'k')
+ call LT('\xe2\x84\xaa', 'kkkkkk')
+ call EQ('\xe2\x84\xaa\xe2\x84\xaa\xe2\x84\xaa', 'kkk')
+ call LT('kk', '\xe2\x84\xaa\xe2\x84\xaa\xe2\x84\xaa')
+ call EQ('\xe2\x84\xaa\xe2\x84\xa6k\xe2\x84\xaak\xcf\x89', 'k\xcf\x89\xe2\x84\xaakk\xe2\x84\xa6')
+ call EQ('Abc\x80', 'AbC\x80')
+ call LT('Abc\x80', 'AbC\x81')
+ call LT('Abc', 'AbC\x80')
+ call LT('abc\x80DEF', 'abc\x80def') " case folding stops at the first bad character
+ call LT('\xc3XYZ', '\xc3xyz')
+ call EQ('\xef\xbc\xba', '\xef\xbd\x9a') " FF3A (upper), FF5A (lower)
+ call GT('\xef\xbc\xba', '\xef\xbc\xff') " first string is ok and equals \xef\xbd\x9a after folding, second string is illegal and was left unchanged, then the strings were bytewise compared
+ call LT('\xc3', '\xc3\x83')
+ call EQ('\xc3\xa3xYz', '\xc3\x83XyZ')
+ for n in range(0x60, 0xFF)
+ call LT(printf('xYz\x%.2X', n-1), printf('XyZ\x%.2X', n))
+ endfor
+ for n in range(0x80, 0xBF)
+ call EQ(printf('xYz\xc2\x%.2XUvW', n), printf('XyZ\xc2\x%.2XuVw', n))
+ endfor
+ for n in range(0xC0, 0xFF)
+ call LT(printf('xYz\xc2\x%.2XUvW', n), printf('XyZ\xc2\x%.2XuVw', n))
+ endfor
+endfunction
+
+" test that g~ap changes one paragraph only.
+function Test_gap()
+ new
+ call feedkeys("iabcd\n\ndefggg0g~ap", "tx")
+ call assert_equal(["ABCD", "", "defg"], getline(1,3))
+endfunction
diff --git a/src/nvim/testdir/test_viml.vim b/src/nvim/testdir/test_vimscript.vim
index 2d989cdad9..5b16f6d205 100644
--- a/src/nvim/testdir/test_viml.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -55,16 +55,26 @@ endfunction
" ExecAsScript - Source a temporary script made from a function. {{{2
"
" Make a temporary script file from the function a:funcname, ":source" it, and
-" delete it afterwards.
+" delete it afterwards. However, if an exception is thrown the file may remain,
+" the caller should call DeleteTheScript() afterwards.
+let s:script_name = ''
function! ExecAsScript(funcname)
" Make a script from the function passed as argument.
- let script = MakeScript(a:funcname)
+ let s:script_name = MakeScript(a:funcname)
" Source and delete the script.
- exec "source" script
- call delete(script)
+ exec "source" s:script_name
+ call delete(s:script_name)
+ let s:script_name = ''
endfunction
+function! DeleteTheScript()
+ if s:script_name
+ call delete(s:script_name)
+ let s:script_name = ''
+ endif
+endfunc
+
com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
@@ -143,6 +153,7 @@ func Test_endwhile_script()
XpathINIT
ExecAsScript T1_F
Xpath 'F'
+ call DeleteTheScript()
try
ExecAsScript T1_G
@@ -152,6 +163,7 @@ func Test_endwhile_script()
Xpath 'x'
endtry
Xpath 'G'
+ call DeleteTheScript()
call assert_equal('abcFhijxG', g:Xpath)
endfunc
@@ -260,6 +272,7 @@ function Test_finish()
XpathINIT
ExecAsScript T4_F
Xpath '5'
+ call DeleteTheScript()
call assert_equal('ab3e3b2c25', g:Xpath)
endfunction
@@ -930,12 +943,21 @@ func Test_type()
call assert_equal(0, type(0))
call assert_equal(1, type(""))
call assert_equal(2, type(function("tr")))
+ call assert_equal(2, type(function("tr", [8])))
call assert_equal(3, type([]))
call assert_equal(4, type({}))
call assert_equal(5, type(0.0))
call assert_equal(6, type(v:false))
call assert_equal(6, type(v:true))
call assert_equal(7, type(v:null))
+ call assert_equal(v:t_number, type(0))
+ call assert_equal(v:t_string, type(""))
+ call assert_equal(v:t_func, type(function("tr")))
+ call assert_equal(v:t_list, type([]))
+ call assert_equal(v:t_dict, type({}))
+ call assert_equal(v:t_float, type(0.0))
+ call assert_equal(v:t_bool, type(v:false))
+ call assert_equal(v:t_bool, type(v:true))
endfunc
"-------------------------------------------------------------------------------
@@ -963,6 +985,316 @@ func Test_skip()
endfunc
"-------------------------------------------------------------------------------
+" Test 93: :echo and string() {{{1
+"-------------------------------------------------------------------------------
+
+func Test_echo_and_string()
+ " String
+ let a = 'foo bar'
+ redir => result
+ echo a
+ echo string(a)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["foo bar",
+ \ "'foo bar'"], l)
+
+ " Float
+ if has('float')
+ let a = -1.2e0
+ redir => result
+ echo a
+ echo string(a)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["-1.2",
+ \ "-1.2"], l)
+ endif
+
+ " Funcref
+ redir => result
+ echo function('string')
+ echo string(function('string'))
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["string",
+ \ "function('string')"], l)
+
+ " Empty dictionaries in a list
+ let a = {}
+ redir => result
+ echo [a, a, a]
+ echo string([a, a, a])
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["[{}, {}, {}]",
+ \ "[{}, {}, {}]"], l)
+
+ " Empty dictionaries in a dictionary
+ let a = {}
+ let b = {"a": a, "b": a}
+ redir => result
+ echo b
+ echo string(b)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["{'a': {}, 'b': {}}",
+ \ "{'a': {}, 'b': {}}"], l)
+
+ " Empty lists in a list
+ let a = []
+ redir => result
+ echo [a, a, a]
+ echo string([a, a, a])
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["[[], [], []]",
+ \ "[[], [], []]"], l)
+
+ " Empty lists in a dictionary
+ let a = []
+ let b = {"a": a, "b": a}
+ redir => result
+ echo b
+ echo string(b)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["{'a': [], 'b': []}",
+ \ "{'a': [], 'b': []}"], l)
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 94: 64-bit Numbers {{{1
+"-------------------------------------------------------------------------------
+
+func Test_num64()
+ if !has('num64')
+ return
+ endif
+
+ call assert_notequal( 4294967296, 0)
+ call assert_notequal(-4294967296, 0)
+ call assert_equal( 4294967296, 0xFFFFffff + 1)
+ call assert_equal(-4294967296, -0xFFFFffff - 1)
+
+ call assert_equal( 9223372036854775807, 1 / 0)
+ call assert_equal(-9223372036854775807, -1 / 0)
+ call assert_equal(-9223372036854775807 - 1, 0 / 0)
+
+ call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
+ call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
+
+ let rng = range(0xFFFFffff, 0x100000001)
+ call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
+ call assert_equal(0x100000001, max(rng))
+ call assert_equal(0xFFFFffff, min(rng))
+ call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 95: lines of :append, :change, :insert {{{1
+"-------------------------------------------------------------------------------
+
+function! DefineFunction(name, body)
+ let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
+ exec func
+endfunction
+
+func Test_script_lines()
+ " :append
+ try
+ call DefineFunction('T_Append', [
+ \ 'append',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_report("Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Append', [
+ \ 'append',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+
+ " :change
+ try
+ call DefineFunction('T_Change', [
+ \ 'change',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_report("Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Change', [
+ \ 'change',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+
+ " :insert
+ try
+ call DefineFunction('T_Insert', [
+ \ 'insert',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_report("Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Insert', [
+ \ 'insert',
+ \ 'abc',
+ \ ])
+ call assert_report("Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 96: line continuation {{{1
+"
+" Undefined behavior was detected by ubsan with line continuation
+" after an empty line.
+"-------------------------------------------------------------------------------
+func Test_script_emty_line_continuation()
+
+ \
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 97: bitwise functions {{{1
+"-------------------------------------------------------------------------------
+func Test_bitwise_functions()
+ " and
+ call assert_equal(127, and(127, 127))
+ call assert_equal(16, and(127, 16))
+ call assert_equal(0, and(127, 128))
+ call assert_fails("call and(1.0, 1)", 'E805:')
+ call assert_fails("call and([], 1)", 'E745:')
+ call assert_fails("call and({}, 1)", 'E728:')
+ call assert_fails("call and(1, 1.0)", 'E805:')
+ call assert_fails("call and(1, [])", 'E745:')
+ call assert_fails("call and(1, {})", 'E728:')
+ " or
+ call assert_equal(23, or(16, 7))
+ call assert_equal(15, or(8, 7))
+ call assert_equal(123, or(0, 123))
+ call assert_fails("call or(1.0, 1)", 'E805:')
+ call assert_fails("call or([], 1)", 'E745:')
+ call assert_fails("call or({}, 1)", 'E728:')
+ call assert_fails("call or(1, 1.0)", 'E805:')
+ call assert_fails("call or(1, [])", 'E745:')
+ call assert_fails("call or(1, {})", 'E728:')
+ " xor
+ call assert_equal(0, xor(127, 127))
+ call assert_equal(111, xor(127, 16))
+ call assert_equal(255, xor(127, 128))
+ call assert_fails("call xor(1.0, 1)", 'E805:')
+ call assert_fails("call xor([], 1)", 'E745:')
+ call assert_fails("call xor({}, 1)", 'E728:')
+ call assert_fails("call xor(1, 1.0)", 'E805:')
+ call assert_fails("call xor(1, [])", 'E745:')
+ call assert_fails("call xor(1, {})", 'E728:')
+ " invert
+ call assert_equal(65408, and(invert(127), 65535))
+ call assert_equal(65519, and(invert(16), 65535))
+ call assert_equal(65407, and(invert(128), 65535))
+ call assert_fails("call invert(1.0)", 'E805:')
+ call assert_fails("call invert([])", 'E745:')
+ call assert_fails("call invert({})", 'E728:')
+endfunc
+
+" Test trailing text after :endfunction {{{1
+func Test_endfunction_trailing()
+ call assert_false(exists('*Xtest'))
+
+ exe "func Xtest()\necho 'hello'\nendfunc\nlet done = 'yes'"
+ call assert_true(exists('*Xtest'))
+ call assert_equal('yes', done)
+ delfunc Xtest
+ unlet done
+
+ exe "func Xtest()\necho 'hello'\nendfunc|let done = 'yes'"
+ call assert_true(exists('*Xtest'))
+ call assert_equal('yes', done)
+ delfunc Xtest
+ unlet done
+
+ " trailing line break
+ exe "func Xtest()\necho 'hello'\nendfunc\n"
+ call assert_true(exists('*Xtest'))
+ delfunc Xtest
+
+ set verbose=1
+ exe "func Xtest()\necho 'hello'\nendfunc \" garbage"
+ call assert_notmatch('W22:', split(execute('1messages'), "\n")[0])
+ call assert_true(exists('*Xtest'))
+ delfunc Xtest
+
+ exe "func Xtest()\necho 'hello'\nendfunc garbage"
+ call assert_match('W22:', split(execute('1messages'), "\n")[0])
+ call assert_true(exists('*Xtest'))
+ delfunc Xtest
+ set verbose=0
+
+ function Foo()
+ echo 'hello'
+ endfunction | echo 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
+ delfunc Foo
+endfunc
+
+func Test_delfunction_force()
+ delfunc! Xtest
+ delfunc! Xtest
+ func Xtest()
+ echo 'nothing'
+ endfunc
+ delfunc! Xtest
+ delfunc! Xtest
+endfunc
+
+" Test using bang after user command {{{1
+func Test_user_command_with_bang()
+ command -bang Nieuw let nieuw = 1
+ Ni!
+ call assert_equal(1, nieuw)
+ unlet nieuw
+ delcommand Nieuw
+endfunc
+
+" Test for script-local function
+func <SID>DoLast()
+ call append(line('$'), "last line")
+endfunc
+
+func s:DoNothing()
+ call append(line('$'), "nothing line")
+endfunc
+
+func Test_script_local_func()
+ set nocp viminfo+=nviminfo
+ new
+ nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr>
+
+ normal _x
+ call assert_equal('nothing line', getline(2))
+ call assert_equal('last line', getline(3))
+ enew! | close
+endfunc
+
+"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker
" vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
diff --git a/src/nvim/testdir/test_virtualedit.vim b/src/nvim/testdir/test_virtualedit.vim
new file mode 100644
index 0000000000..d49025237b
--- /dev/null
+++ b/src/nvim/testdir/test_virtualedit.vim
@@ -0,0 +1,61 @@
+" Tests for 'virtualedit'.
+
+func Test_yank_move_change()
+ new
+ call setline(1, [
+ \ "func foo() error {",
+ \ "\tif n, err := bar();",
+ \ "\terr != nil {",
+ \ "\t\treturn err",
+ \ "\t}",
+ \ "\tn = n * n",
+ \ ])
+ set virtualedit=all
+ set ts=4
+ function! MoveSelectionDown(count) abort
+ normal! m`
+ silent! exe "'<,'>move'>+".a:count
+ norm! ``
+ endfunction
+
+ xmap ]e :<C-U>call MoveSelectionDown(v:count1)<CR>
+ 2
+ normal 2gg
+ normal J
+ normal jVj
+ normal ]e
+ normal ce
+ bwipe!
+ set virtualedit=
+ set ts=8
+endfunc
+
+func Test_paste_end_of_line()
+ new
+ set virtualedit=all
+ call setline(1, ['456', '123'])
+ normal! gg0"ay$
+ exe "normal! 2G$lllA\<C-O>:normal! \"agP\r"
+ call assert_equal('123456', getline(2))
+
+ bwipe!
+ set virtualedit=
+endfunc
+
+func Test_edit_CTRL_G()
+ new
+ set virtualedit=insert
+ call setline(1, ['123', '1', '12'])
+ exe "normal! ggA\<c-g>jx\<c-g>jx"
+ call assert_equal(['123', '1 x', '12 x'], getline(1,'$'))
+
+ set virtualedit=all
+ %d_
+ call setline(1, ['1', '12'])
+ exe "normal! ggllix\<c-g>jx"
+ call assert_equal(['1 x', '12x'], getline(1,'$'))
+
+
+ bwipe!
+ set virtualedit=
+endfunc
diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim
new file mode 100644
index 0000000000..4a143d665d
--- /dev/null
+++ b/src/nvim/testdir/test_visual.vim
@@ -0,0 +1,320 @@
+" Tests for various Visual mode.
+if !has('visual')
+ finish
+endif
+
+
+func Test_block_shift_multibyte()
+ " Uses double-wide character.
+ if !has('multi_byte')
+ return
+ endif
+ split
+ call setline(1, ['xヹxxx', 'ヹxxx'])
+ exe "normal 1G0l\<C-V>jl>"
+ call assert_equal('x ヹxxx', getline(1))
+ call assert_equal(' ヹxxx', getline(2))
+ q!
+endfunc
+
+func Test_block_shift_overflow()
+ " This used to cause a multiplication overflow followed by a crash.
+ new
+ normal ii
+ exe "normal \<C-V>876543210>"
+ q!
+endfunc
+
+func Test_Visual_ctrl_o()
+ new
+ call setline(1, ['one', 'two', 'three'])
+ call cursor(1,2)
+ set noshowmode
+ set tw=0
+ call feedkeys("\<c-v>jjlIa\<c-\>\<c-o>:set tw=88\<cr>\<esc>", 'tx')
+ call assert_equal(['oane', 'tawo', 'tahree'], getline(1, 3))
+ call assert_equal(88, &tw)
+ set tw&
+ bw!
+endfu
+
+func Test_Visual_vapo()
+ new
+ normal oxx
+ normal vapo
+ bwipe!
+endfunc
+
+func Test_dotregister_paste()
+ new
+ exe "norm! ihello world\<esc>"
+ norm! 0ve".p
+ call assert_equal('hello world world', getline(1))
+ q!
+endfunc
+
+func Test_Visual_inner_quote()
+ new
+ normal oxX
+ normal vki'
+ bwipe!
+endfunc
+
+" Test for visual block shift and tab characters.
+func Test_block_shift_tab()
+ enew!
+ call append(0, repeat(['one two three'], 5))
+ call cursor(1,1)
+ exe "normal i\<C-G>u"
+ exe "normal fe\<C-V>4jR\<Esc>ugvr1"
+ call assert_equal('on1 two three', getline(1))
+ call assert_equal('on1 two three', getline(2))
+ call assert_equal('on1 two three', getline(5))
+
+ enew!
+ call append(0, repeat(['abcdefghijklmnopqrstuvwxyz'], 5))
+ call cursor(1,1)
+ exe "normal \<C-V>4jI \<Esc>j<<11|D"
+ exe "normal j7|a\<Tab>\<Tab>"
+ exe "normal j7|a\<Tab>\<Tab> "
+ exe "normal j7|a\<Tab> \<Tab>\<Esc>4k13|\<C-V>4j<"
+ call assert_equal(' abcdefghijklmnopqrstuvwxyz', getline(1))
+ call assert_equal('abcdefghij', getline(2))
+ call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(3))
+ call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(4))
+ call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
+
+ %s/\s\+//g
+ call cursor(1,1)
+ exe "normal \<C-V>4jI \<Esc>j<<"
+ exe "normal j7|a\<Tab>\<Tab>"
+ exe "normal j7|a\<Tab>\<Tab>\<Tab>\<Tab>\<Tab>"
+ exe "normal j7|a\<Tab> \<Tab>\<Tab>\<Esc>4k13|\<C-V>4j3<"
+ call assert_equal(' abcdefghijklmnopqrstuvwxyz', getline(1))
+ call assert_equal('abcdefghij', getline(2))
+ call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(3))
+ call assert_equal(" abc\<Tab>\<Tab>defghijklmnopqrstuvwxyz", getline(4))
+ call assert_equal(" abc\<Tab> defghijklmnopqrstuvwxyz", getline(5))
+
+ enew!
+endfunc
+
+" Tests Blockwise Visual when there are TABs before the text.
+func Test_blockwise_visual()
+ enew!
+ call append(0, ['123456',
+ \ '234567',
+ \ '345678',
+ \ '',
+ \ 'test text test tex start here',
+ \ "\t\tsome text",
+ \ "\t\ttest text",
+ \ 'test text'])
+ call cursor(1,1)
+ exe "normal /start here$\<CR>"
+ exe 'normal "by$' . "\<C-V>jjlld"
+ exe "normal /456$\<CR>"
+ exe "normal \<C-V>jj" . '"bP'
+ call assert_equal(['123start here56',
+ \ '234start here67',
+ \ '345start here78',
+ \ '',
+ \ 'test text test tex rt here',
+ \ "\t\tsomext",
+ \ "\t\ttesext"], getline(1, 7))
+
+ enew!
+endfunc
+
+" Test swapping corners in blockwise visual mode with o and O
+func Test_blockwise_visual_o_O()
+ enew!
+
+ exe "norm! 10i.\<Esc>Y4P3lj\<C-V>4l2jr "
+ exe "norm! gvO\<Esc>ra"
+ exe "norm! gvO\<Esc>rb"
+ exe "norm! gvo\<C-c>rc"
+ exe "norm! gvO\<C-c>rd"
+
+ call assert_equal(['..........',
+ \ '...c d..',
+ \ '... ..',
+ \ '...a b..',
+ \ '..........'], getline(1, '$'))
+
+ enew!
+endfun
+
+" Test Virtual replace mode.
+func Test_virtual_replace()
+ throw 'skipped: TODO: '
+ if exists('&t_kD')
+ let save_t_kD = &t_kD
+ endif
+ if exists('&t_kb')
+ let save_t_kb = &t_kb
+ endif
+ exe "set t_kD=\<C-V>x7f t_kb=\<C-V>x08"
+ enew!
+ exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
+ call cursor(1,1)
+ set ai bs=2
+ exe "normal gR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
+ call assert_equal([' 1',
+ \ ' A',
+ \ ' BCDEFGHIJ',
+ \ ' KL',
+ \ ' MNO',
+ \ ' PQR',
+ \ ], getline(1, 6))
+ normal G
+ mark a
+ inoremap <C-D> <Del>
+ exe "normal o0\<C-D>\nabcdefghi\njk\tlmn\n opq\trst\n\<C-D>uvwxyz\n"
+ exe "normal 'ajgR0\<C-D> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR" . repeat("\<BS>", 29)
+ call assert_equal([' 1',
+ \ 'abcdefghi',
+ \ 'jk lmn',
+ \ ' opq rst',
+ \ 'uvwxyz'], getline(7, 11))
+ normal G
+ exe "normal iab\tcdefghi\tjkl"
+ exe "normal 0gRAB......CDEFGHI.J\<Esc>o"
+ exe "normal iabcdefghijklmnopqrst\<Esc>0gRAB\tIJKLMNO\tQR"
+ call assert_equal(['AB......CDEFGHI.Jkl',
+ \ 'AB IJKLMNO QRst'], getline(12, 13))
+ enew!
+ set noai bs&vim
+ if exists('save_t_kD')
+ let &t_kD = save_t_kD
+ endif
+ if exists('save_t_kb')
+ let &t_kb = save_t_kb
+ endif
+endfunc
+
+" Test Virtual replace mode.
+func Test_virtual_replace2()
+ enew!
+ set bs=2
+ exe "normal a\nabcdefghi\njk\tlmn\n opq rst\n\<C-D>uvwxyz"
+ call cursor(1,1)
+ " Test 1: Test that del deletes the newline
+ exe "normal gR0\<del> 1\nA\nBCDEFGHIJ\n\tKL\nMNO\nPQR"
+ call assert_equal(['0 1',
+ \ 'A',
+ \ 'BCDEFGHIJ',
+ \ ' KL',
+ \ 'MNO',
+ \ 'PQR',
+ \ ], getline(1, 6))
+ " Test 2:
+ " a newline is not deleted, if no newline has been added in virtual replace mode
+ %d_
+ call setline(1, ['abcd', 'efgh', 'ijkl'])
+ call cursor(2,1)
+ exe "norm! gR1234\<cr>5\<bs>\<bs>\<bs>"
+ call assert_equal(['abcd',
+ \ '123h',
+ \ 'ijkl'], getline(1, '$'))
+ " Test 3:
+ " a newline is deleted, if a newline has been inserted before in virtual replace mode
+ %d_
+ call setline(1, ['abcd', 'efgh', 'ijkl'])
+ call cursor(2,1)
+ exe "norm! gR1234\<cr>\<cr>56\<bs>\<bs>\<bs>"
+ call assert_equal(['abcd',
+ \ '1234',
+ \ 'ijkl'], getline(1, '$'))
+ " Test 4:
+ " delete add a newline, delete it, add it again and check undo
+ %d_
+ call setline(1, ['abcd', 'efgh', 'ijkl'])
+ call cursor(2,1)
+ " break undo sequence explicitly
+ let &ul = &ul
+ exe "norm! gR1234\<cr>\<bs>\<del>56\<cr>"
+ let &ul = &ul
+ call assert_equal(['abcd',
+ \ '123456',
+ \ ''], getline(1, '$'))
+ norm! u
+ call assert_equal(['abcd',
+ \ 'efgh',
+ \ 'ijkl'], getline(1, '$'))
+ " clean up
+ %d_
+ set bs&vim
+endfunc
+
+" Test for Visual mode not being reset causing E315 error.
+func TriggerTheProblem()
+ " At this point there is no visual selection because :call reset it.
+ " Let's restore the selection:
+ normal gv
+ '<,'>del _
+ try
+ exe "normal \<Esc>"
+ catch /^Vim\%((\a\+)\)\=:E315/
+ echom 'Snap! E315 error!'
+ let g:msg = 'Snap! E315 error!'
+ endtry
+endfunc
+
+func Test_visual_mode_reset()
+ set belloff=all
+ enew
+ let g:msg = "Everything's fine."
+ enew
+ setl buftype=nofile
+ call append(line('$'), 'Delete this line.')
+
+ " NOTE: this has to be done by a call to a function because executing :del
+ " the ex-way will require the colon operator which resets the visual mode
+ " thus preventing the problem:
+ exe "normal! GV:call TriggerTheProblem()\<CR>"
+ call assert_equal("Everything's fine.", g:msg)
+
+ set belloff&
+endfunc
+
+func Test_Visual_sentence_textobject()
+ new
+ call setline(1, ['First sentence. Second sentence. Third', 'sentence. Fouth sentence'])
+
+ " When start and end of visual area are identical, 'as' or 'is' select
+ " the whole sentence.
+ norm! 1gofdvasy
+ call assert_equal('Second sentence. ', @")
+ norm! 1gofdvisy
+ call assert_equal('Second sentence.', @")
+
+ " When start and end of visual area are not identical, 'as' or 'is'
+ " extend the sentence in direction of the end of the visual area.
+ norm! 1gofdvlasy
+ call assert_equal('d sentence. ', @")
+ norm! gvasy
+ call assert_equal("d sentence. Third\nsentence. ", @")
+
+ norm! 1gofdvlisy
+ call assert_equal('d sentence.', @")
+ norm! gvisy
+ call assert_equal('d sentence. ', @")
+ norm! gvisy
+ call assert_equal("d sentence. Third\nsentence.", @")
+
+ " Extend visual area in opposite direction.
+ norm! 1gofdvhasy
+ call assert_equal(' Second', @")
+ norm! gvasy
+ call assert_equal("First sentence. Second", @")
+
+ norm! 1gofdvhisy
+ call assert_equal('Second', @")
+ norm! gvisy
+ call assert_equal(' Second', @")
+ norm! gvisy
+ call assert_equal('First sentence. Second', @")
+
+ bwipe!
+endfunc
diff --git a/src/nvim/testdir/test_winbuf_close.vim b/src/nvim/testdir/test_winbuf_close.vim
new file mode 100644
index 0000000000..e4618610cd
--- /dev/null
+++ b/src/nvim/testdir/test_winbuf_close.vim
@@ -0,0 +1,160 @@
+" Test for commands that close windows and/or buffers:
+" :quit
+" :close
+" :hide
+" :only
+" :sall
+" :all
+" :ball
+" :buf
+" :edit
+"
+func Test_winbuf_close()
+ enew | only
+
+ call writefile(['testtext 1'], 'Xtest1')
+ call writefile(['testtext 2'], 'Xtest2')
+ call writefile(['testtext 3'], 'Xtest3')
+
+ next! Xtest1 Xtest2
+ call setline(1, 'testtext 1 1')
+
+ " test for working :n when hidden set
+ set hidden
+ next
+ call assert_equal('Xtest2', bufname('%'))
+
+ " test for failing :rew when hidden not set
+ set nohidden
+ call setline(1, 'testtext 2 2')
+ call assert_fails('rewind', 'E37')
+ call assert_equal('Xtest2', bufname('%'))
+ call assert_equal('testtext 2 2', getline(1))
+
+ " test for working :rew when hidden set
+ set hidden
+ rewind
+ call assert_equal('Xtest1', bufname('%'))
+ call assert_equal('testtext 1 1', getline(1))
+
+ " test for :all keeping a buffer when it's modified
+ set nohidden
+ call setline(1, 'testtext 1 1 1')
+ split
+ next Xtest2 Xtest3
+ all
+ 1wincmd w
+ call assert_equal('Xtest1', bufname('%'))
+ call assert_equal('testtext 1 1 1', getline(1))
+
+ " test abandoning changed buffer, should be unloaded even when 'hidden' set
+ set hidden
+ call setline(1, 'testtext 1 1 1 1')
+ quit!
+ call assert_equal('Xtest2', bufname('%'))
+ call assert_equal('testtext 2 2', getline(1))
+ unhide
+ call assert_equal('Xtest2', bufname('%'))
+ call assert_equal('testtext 2 2', getline(1))
+
+ " test ":hide" hides anyway when 'hidden' not set
+ set nohidden
+ call setline(1, 'testtext 2 2 2')
+ hide
+ call assert_equal('Xtest3', bufname('%'))
+ call assert_equal('testtext 3', getline(1))
+
+ " test ":edit" failing in modified buffer when 'hidden' not set
+ call setline(1, 'testtext 3 3')
+ call assert_fails('edit Xtest1', 'E37')
+ call assert_equal('Xtest3', bufname('%'))
+ call assert_equal('testtext 3 3', getline(1))
+
+ " test ":edit" working in modified buffer when 'hidden' set
+ set hidden
+ edit Xtest1
+ call assert_equal('Xtest1', bufname('%'))
+ call assert_equal('testtext 1', getline(1))
+
+ " test ":close" not hiding when 'hidden' not set in modified buffer
+ split Xtest3
+ set nohidden
+ call setline(1, 'testtext 3 3 3')
+ call assert_fails('close', 'E37')
+ call assert_equal('Xtest3', bufname('%'))
+ call assert_equal('testtext 3 3 3', getline(1))
+
+ " test ":close!" does hide when 'hidden' not set in modified buffer;
+ call setline(1, 'testtext 3 3 3 3')
+ close!
+ call assert_equal('Xtest1', bufname('%'))
+ call assert_equal('testtext 1', getline(1))
+
+ set nohidden
+
+ " test ":all!" hides changed buffer
+ split Xtest4
+ call setline(1, 'testtext 4')
+ all!
+ 1wincmd w
+ call assert_equal('Xtest2', bufname('%'))
+ call assert_equal('testtext 2 2 2', getline(1))
+
+ " test ":q!" and hidden buffer.
+ bwipe! Xtest1 Xtest2 Xtest3 Xtest4
+ split Xtest1
+ wincmd w
+ bwipe!
+ set modified
+ bot split Xtest2
+ set modified
+ bot split Xtest3
+ set modified
+ wincmd t
+ hide
+ call assert_equal('Xtest2', bufname('%'))
+ quit!
+ call assert_equal('Xtest3', bufname('%'))
+ call assert_fails('silent! quit!', 'E162')
+ call assert_equal('Xtest1', bufname('%'))
+
+ call delete('Xtest1')
+ call delete('Xtest2')
+ call delete('Xtest3')
+endfunc
+
+" Test that ":close" will respect 'winfixheight' when possible.
+func Test_winfixheight_on_close()
+ set nosplitbelow nosplitright
+
+ split | split | vsplit
+
+ $wincmd w
+ setlocal winfixheight
+ let l:height = winheight(0)
+
+ 3close
+
+ call assert_equal(l:height, winheight(0))
+
+ %bwipeout!
+ setlocal nowinfixheight splitbelow& splitright&
+endfunc
+
+" Test that ":close" will respect 'winfixwidth' when possible.
+func Test_winfixwidth_on_close()
+ set nosplitbelow nosplitright
+
+ vsplit | vsplit | split
+
+ $wincmd w
+ setlocal winfixwidth
+ let l:width = winwidth(0)
+
+ 3close
+
+ call assert_equal(l:width, winwidth(0))
+
+ %bwipeout!
+ setlocal nowinfixwidth splitbelow& splitright&
+endfunction
diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim
new file mode 100644
index 0000000000..b3ab6957dc
--- /dev/null
+++ b/src/nvim/testdir/test_window_cmd.vim
@@ -0,0 +1,521 @@
+" Tests for window cmd (:wincmd, :split, :vsplit, :resize and etc...)
+
+func Test_window_cmd_ls0_with_split()
+ set ls=0
+ set splitbelow
+ split
+ quit
+ call assert_equal(0, &lines - &cmdheight - winheight(0))
+ new | only!
+ "
+ set splitbelow&vim
+ botright split
+ quit
+ call assert_equal(0, &lines - &cmdheight - winheight(0))
+ new | only!
+ set ls&vim
+endfunc
+
+func Test_window_cmd_cmdwin_with_vsp()
+ let efmt = 'Expected 0 but got %d (in ls=%d, %s window)'
+ for v in range(0, 2)
+ exec "set ls=" . v
+ vsplit
+ call feedkeys("q:\<CR>")
+ let ac = &lines - (&cmdheight + winheight(0) + !!v)
+ let emsg = printf(efmt, ac, v, 'left')
+ call assert_equal(0, ac, emsg)
+ wincmd w
+ let ac = &lines - (&cmdheight + winheight(0) + !!v)
+ let emsg = printf(efmt, ac, v, 'right')
+ call assert_equal(0, ac, emsg)
+ new | only!
+ endfor
+ set ls&vim
+endfunc
+
+function Test_window_cmd_wincmd_gf()
+ let fname = 'test_gf.txt'
+ let swp_fname = '.' . fname . '.swp'
+ call writefile([], fname)
+ call writefile([], swp_fname)
+ function s:swap_exists()
+ let v:swapchoice = s:swap_choice
+ endfunc
+ augroup test_window_cmd_wincmd_gf
+ autocmd!
+ exec "autocmd SwapExists " . fname . " call s:swap_exists()"
+ augroup END
+
+ call setline(1, fname)
+ " (E)dit anyway
+ let s:swap_choice = 'e'
+ wincmd gf
+ call assert_equal(2, tabpagenr())
+ call assert_equal(fname, bufname("%"))
+ quit!
+
+ " (Q)uit
+ let s:swap_choice = 'q'
+ wincmd gf
+ call assert_equal(1, tabpagenr())
+ call assert_notequal(fname, bufname("%"))
+ new | only!
+
+ call delete(fname)
+ call delete(swp_fname)
+ augroup! test_window_cmd_wincmd_gf
+endfunc
+
+func Test_next_split_all()
+ " This was causing an illegal memory access.
+ n x
+ norm axxx
+ split
+ split
+ s/x
+ s/x
+ all
+ bwipe!
+endfunc
+
+func Test_window_quit()
+ e Xa
+ split Xb
+ call assert_equal(2, winnr('$'))
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+
+ wincmd q
+ call assert_equal(1, winnr('$'))
+ call assert_equal('Xa', bufname(winbufnr(1)))
+
+ bw Xa Xb
+endfunc
+
+func Test_window_horizontal_split()
+ call assert_equal(1, winnr('$'))
+ 3wincmd s
+ call assert_equal(2, winnr('$'))
+ call assert_equal(3, winheight(0))
+ call assert_equal(winwidth(1), winwidth(2))
+
+ call assert_fails('botright topleft wincmd s', 'E442:')
+ bw
+endfunc
+
+func Test_window_vertical_split()
+ call assert_equal(1, winnr('$'))
+ 3wincmd v
+ call assert_equal(2, winnr('$'))
+ call assert_equal(3, winwidth(0))
+ call assert_equal(winheight(1), winheight(2))
+
+ call assert_fails('botright topleft wincmd v', 'E442:')
+ bw
+endfunc
+
+func Test_window_split_edit_alternate()
+ e Xa
+ e Xb
+
+ wincmd ^
+ call assert_equal('Xa', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+
+ bw Xa Xb
+endfunc
+
+func Test_window_preview()
+ " Open a preview window
+ pedit Xa
+ call assert_equal(2, winnr('$'))
+ call assert_equal(0, &previewwindow)
+
+ " Go to the preview window
+ wincmd P
+ call assert_equal(1, &previewwindow)
+
+ " Close preview window
+ wincmd z
+ call assert_equal(1, winnr('$'))
+ call assert_equal(0, &previewwindow)
+
+ call assert_fails('wincmd P', 'E441:')
+endfunc
+
+func Test_window_exchange()
+ e Xa
+
+ " Nothing happens with window exchange when there is 1 window
+ wincmd x
+ call assert_equal(1, winnr('$'))
+
+ split Xb
+ split Xc
+
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Exchange current window 1 with window 3
+ 3wincmd x
+ call assert_equal('Xa', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the top window
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the middle window
+ wincmd j
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xc', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Exchange window with next when at the bottom window.
+ " When there is no next window, it exchanges with the previous window.
+ wincmd j
+ wincmd x
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_rotate()
+ e Xa
+ split Xb
+ split Xc
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Rotate downwards
+ wincmd r
+ call assert_equal('Xa', bufname(winbufnr(1)))
+ call assert_equal('Xc', bufname(winbufnr(2)))
+ call assert_equal('Xb', bufname(winbufnr(3)))
+
+ 2wincmd r
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ " Rotate upwards
+ wincmd R
+ call assert_equal('Xb', bufname(winbufnr(1)))
+ call assert_equal('Xa', bufname(winbufnr(2)))
+ call assert_equal('Xc', bufname(winbufnr(3)))
+
+ 2wincmd R
+ call assert_equal('Xc', bufname(winbufnr(1)))
+ call assert_equal('Xb', bufname(winbufnr(2)))
+ call assert_equal('Xa', bufname(winbufnr(3)))
+
+ bot vsplit
+ call assert_fails('wincmd R', 'E443:')
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_height()
+ e Xa
+ split Xb
+
+ let [wh1, wh2] = [winheight(1), winheight(2)]
+ " Active window (1) should have the same height or 1 more
+ " than the other window.
+ call assert_inrange(wh2, wh2 + 1, wh1)
+
+ wincmd -
+ call assert_equal(wh1 - 1, winheight(1))
+ call assert_equal(wh2 + 1, winheight(2))
+
+ wincmd +
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh2, winheight(2))
+
+ 2wincmd _
+ call assert_equal(2, winheight(1))
+ call assert_equal(wh1 + wh2 - 2, winheight(2))
+
+ wincmd =
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh2, winheight(2))
+
+ 2wincmd _
+ set winfixheight
+ split Xc
+ let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
+ call assert_equal(2, winheight(2))
+ call assert_inrange(wh3, wh3 + 1, wh1)
+ 3wincmd +
+ call assert_equal(2, winheight(2))
+ call assert_equal(wh1 + 3, winheight(1))
+ call assert_equal(wh3 - 3, winheight(3))
+ wincmd =
+ call assert_equal(2, winheight(2))
+ call assert_equal(wh1, winheight(1))
+ call assert_equal(wh3, winheight(3))
+
+ wincmd j
+ set winfixheight&
+
+ wincmd =
+ let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)]
+ " Current window (2) should have the same height or 1 more
+ " than the other windows.
+ call assert_inrange(wh1, wh1 + 1, wh2)
+ call assert_inrange(wh3, wh3 + 1, wh2)
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_window_width()
+ e Xa
+ vsplit Xb
+
+ let [ww1, ww2] = [winwidth(1), winwidth(2)]
+ " Active window (1) should have the same width or 1 more
+ " than the other window.
+ call assert_inrange(ww2, ww2 + 1, ww1)
+
+ wincmd <
+ call assert_equal(ww1 - 1, winwidth(1))
+ call assert_equal(ww2 + 1, winwidth(2))
+
+ wincmd >
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww2, winwidth(2))
+
+ 2wincmd |
+ call assert_equal(2, winwidth(1))
+ call assert_equal(ww1 + ww2 - 2, winwidth(2))
+
+ wincmd =
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww2, winwidth(2))
+
+ 2wincmd |
+ set winfixwidth
+ vsplit Xc
+ let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
+ call assert_equal(2, winwidth(2))
+ call assert_inrange(ww3, ww3 + 1, ww1)
+ 3wincmd >
+ call assert_equal(2, winwidth(2))
+ call assert_equal(ww1 + 3, winwidth(1))
+ call assert_equal(ww3 - 3, winwidth(3))
+ wincmd =
+ call assert_equal(2, winwidth(2))
+ call assert_equal(ww1, winwidth(1))
+ call assert_equal(ww3, winwidth(3))
+
+ wincmd l
+ set winfixwidth&
+
+ wincmd =
+ let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)]
+ " Current window (2) should have the same width or 1 more
+ " than the other windows.
+ call assert_inrange(ww1, ww1 + 1, ww2)
+ call assert_inrange(ww3, ww3 + 1, ww2)
+
+ bw Xa Xb Xc
+endfunc
+
+func Test_equalalways_on_close()
+ set equalalways
+ vsplit
+ windo split
+ split
+ wincmd J
+ " now we have a frame top-left with two windows, a frame top-right with two
+ " windows and a frame at the bottom, full-width.
+ let height_1 = winheight(1)
+ let height_2 = winheight(2)
+ let height_3 = winheight(3)
+ let height_4 = winheight(4)
+ " closing the bottom window causes all windows to be resized.
+ close
+ call assert_notequal(height_1, winheight(1))
+ call assert_notequal(height_2, winheight(2))
+ call assert_notequal(height_3, winheight(3))
+ call assert_notequal(height_4, winheight(4))
+ call assert_equal(winheight(1), winheight(3))
+ call assert_equal(winheight(2), winheight(4))
+
+ 1wincmd w
+ split
+ 4wincmd w
+ resize + 5
+ " left column has three windows, equalized heights.
+ " right column has two windows, top one a bit higher
+ let height_1 = winheight(1)
+ let height_2 = winheight(2)
+ let height_4 = winheight(4)
+ let height_5 = winheight(5)
+ 3wincmd w
+ " closing window in left column equalizes heights in left column but not in
+ " the right column
+ close
+ call assert_notequal(height_1, winheight(1))
+ call assert_notequal(height_2, winheight(2))
+ call assert_equal(height_4, winheight(3))
+ call assert_equal(height_5, winheight(4))
+
+ only
+ set equalalways&
+endfunc
+
+func Test_win_screenpos()
+ call assert_equal(1, winnr('$'))
+ split
+ vsplit
+ 10wincmd _
+ 30wincmd |
+ call assert_equal([1, 1], win_screenpos(1))
+ call assert_equal([1, 32], win_screenpos(2))
+ call assert_equal([12, 1], win_screenpos(3))
+ call assert_equal([0, 0], win_screenpos(4))
+ only
+endfunc
+
+func Test_window_jump_tag()
+ help
+ /iccf
+ call assert_match('^|iccf|', getline('.'))
+ call assert_equal(2, winnr('$'))
+ 2wincmd }
+ call assert_equal(3, winnr('$'))
+ call assert_match('^|iccf|', getline('.'))
+ wincmd k
+ call assert_match('\*iccf\*', getline('.'))
+ call assert_equal(2, winheight(0))
+
+ wincmd z
+ set previewheight=4
+ help
+ /bugs
+ wincmd }
+ wincmd k
+ call assert_match('\*bugs\*', getline('.'))
+ call assert_equal(4, winheight(0))
+ set previewheight&
+
+ %bw!
+endfunc
+
+func Test_window_newtab()
+ e Xa
+
+ call assert_equal(1, tabpagenr('$'))
+ call assert_equal("\nAlready only one window", execute('wincmd T'))
+
+ split Xb
+ split Xc
+
+ wincmd T
+ call assert_equal(2, tabpagenr('$'))
+ call assert_equal(['Xb', 'Xa'], map(tabpagebuflist(1), 'bufname(v:val)'))
+ call assert_equal(['Xc' ], map(tabpagebuflist(2), 'bufname(v:val)'))
+
+ %bw!
+endfunc
+
+
+" Tests for adjusting window and contents
+func GetScreenStr(row)
+ let str = ""
+ for c in range(1,3)
+ let str .= nr2char(screenchar(a:row, c))
+ endfor
+ return str
+endfunc
+
+func Test_window_contents()
+ enew! | only | new
+ call setline(1, range(1,256))
+
+ exe "norm! \<C-W>t\<C-W>=1Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(1, line("w0"))
+ call assert_equal('1 ', s3)
+
+ exe "norm! \<C-W>t\<C-W>=50Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(50, line("w0"))
+ call assert_equal('50 ', s3)
+
+ exe "norm! \<C-W>t\<C-W>=59Gzt\<C-W>w\<C-W>+"
+ redraw
+ let s3 = GetScreenStr(1)
+ wincmd p
+ call assert_equal(59, line("w0"))
+ call assert_equal('59 ', s3)
+
+ bwipeout!
+ call test_garbagecollect_now()
+endfunc
+
+func Test_access_freed_mem()
+ " This was accessing freed memory
+ au * 0 vs xxx
+ arg 0
+ argadd
+ all
+ all
+ au!
+ bwipe xxx
+endfunc
+
+func Test_visual_cleared_after_window_split()
+ new | only!
+ let smd_save = &showmode
+ set showmode
+ let ls_save = &laststatus
+ set laststatus=1
+ call setline(1, ['a', 'b', 'c', 'd', ''])
+ norm! G
+ exe "norm! kkvk"
+ redraw
+ exe "norm! \<C-W>v"
+ redraw
+ " check if '-- VISUAL --' disappeared from command line
+ let columns = range(1, &columns)
+ let cmdlinechars = map(columns, 'nr2char(screenchar(&lines, v:val))')
+ let cmdline = join(cmdlinechars, '')
+ let cmdline_ltrim = substitute(cmdline, '^\s*', "", "")
+ let mode_shown = substitute(cmdline_ltrim, '\s*$', "", "")
+ call assert_equal('', mode_shown)
+ let &showmode = smd_save
+ let &laststatus = ls_save
+ bwipe!
+endfunc
+
+func Test_winrestcmd()
+ 2split
+ 3vsplit
+ let a = winrestcmd()
+ call assert_equal(2, winheight(0))
+ call assert_equal(3, winwidth(0))
+ wincmd =
+ call assert_notequal(2, winheight(0))
+ call assert_notequal(3, winwidth(0))
+ exe a
+ call assert_equal(2, winheight(0))
+ call assert_equal(3, winwidth(0))
+ only
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test_window_id.vim b/src/nvim/testdir/test_window_id.vim
new file mode 100644
index 0000000000..b3b506d04d
--- /dev/null
+++ b/src/nvim/testdir/test_window_id.vim
@@ -0,0 +1,103 @@
+" Test using the window ID.
+
+func Test_win_getid()
+ edit one
+ let id1 = win_getid()
+ let w:one = 'one'
+ split two
+ let id2 = win_getid()
+ let bufnr2 = bufnr('%')
+ let w:two = 'two'
+ split three
+ let id3 = win_getid()
+ let w:three = 'three'
+ tabnew
+ edit four
+ let id4 = win_getid()
+ let w:four = 'four'
+ split five
+ let id5 = win_getid()
+ let bufnr5 = bufnr('%')
+ let w:five = 'five'
+ tabnext
+
+ wincmd w
+ call assert_equal("two", expand("%"))
+ call assert_equal(id2, win_getid())
+ let nr2 = winnr()
+ wincmd w
+ call assert_equal("one", expand("%"))
+ call assert_equal(id1, win_getid())
+ let nr1 = winnr()
+ wincmd w
+ call assert_equal("three", expand("%"))
+ call assert_equal(id3, win_getid())
+ let nr3 = winnr()
+ call assert_equal('one', getwinvar(id1, 'one'))
+ call assert_equal('two', getwinvar(id2, 'two'))
+ call assert_equal('three', getwinvar(id3, 'three'))
+ tabnext
+ call assert_equal("five", expand("%"))
+ call assert_equal(id5, win_getid())
+ let nr5 = winnr()
+ wincmd w
+ call assert_equal("four", expand("%"))
+ call assert_equal(id4, win_getid())
+ let nr4 = winnr()
+ call assert_equal('four', getwinvar(id4, 'four'))
+ call assert_equal('five', getwinvar(id5, 'five'))
+ call settabwinvar(1, id2, 'two', '2')
+ call setwinvar(id4, 'four', '4')
+ tabnext
+ call assert_equal('4', gettabwinvar(2, id4, 'four'))
+ call assert_equal('five', gettabwinvar(2, id5, 'five'))
+ call assert_equal('2', getwinvar(id2, 'two'))
+
+ exe nr1 . "wincmd w"
+ call assert_equal(id1, win_getid())
+ exe nr2 . "wincmd w"
+ call assert_equal(id2, win_getid())
+ exe nr3 . "wincmd w"
+ call assert_equal(id3, win_getid())
+ tabnext
+ exe nr4 . "wincmd w"
+ call assert_equal(id4, win_getid())
+ exe nr5 . "wincmd w"
+ call assert_equal(id5, win_getid())
+
+ call win_gotoid(id2)
+ call assert_equal("two", expand("%"))
+ call win_gotoid(id4)
+ call assert_equal("four", expand("%"))
+ call win_gotoid(id1)
+ call assert_equal("one", expand("%"))
+ call win_gotoid(id5)
+ call assert_equal("five", expand("%"))
+
+ call assert_equal(0, win_id2win(9999))
+ call assert_equal(nr5, win_id2win(id5))
+ call assert_equal(0, win_id2win(id1))
+ tabnext
+ call assert_equal(nr1, win_id2win(id1))
+
+ call assert_equal([0, 0], win_id2tabwin(9999))
+ call assert_equal([1, nr2], win_id2tabwin(id2))
+ call assert_equal([2, nr4], win_id2tabwin(id4))
+
+ call assert_equal([], win_findbuf(9999))
+ call assert_equal([id2], win_findbuf(bufnr2))
+ call win_gotoid(id5)
+ split
+ call assert_equal(sort([id5, win_getid()]), sort(win_findbuf(bufnr5)))
+
+ only!
+endfunc
+
+func Test_win_getid_curtab()
+ tabedit X
+ tabfirst
+ copen
+ only
+ call assert_equal(win_getid(1), win_getid(1, 1))
+ tabclose!
+endfunc
diff --git a/src/nvim/testdir/test_windows_home.vim b/src/nvim/testdir/test_windows_home.vim
new file mode 100644
index 0000000000..bbcbf96050
--- /dev/null
+++ b/src/nvim/testdir/test_windows_home.vim
@@ -0,0 +1,121 @@
+" Test for $HOME on Windows.
+
+if !has('win32')
+ finish
+endif
+
+let s:env = {}
+
+func s:restore_env()
+ for i in keys(s:env)
+ exe 'let ' . i . '=s:env["' . i . '"]'
+ endfor
+endfunc
+
+func s:save_env(...)
+ for i in a:000
+ exe 'let s:env["' . i . '"]=' . i
+ endfor
+endfunc
+
+func s:unlet_env(...)
+ for i in a:000
+ exe 'let ' . i . '=""'
+ endfor
+endfunc
+
+func CheckHomeIsMissingFromSubprocessEnvironment()
+ silent! let out = system('set')
+ let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
+ call assert_equal(0, len(env))
+endfunc
+
+func CheckHomeIsInSubprocessEnvironment(exp)
+ silent! let out = system('set')
+ let env = filter(split(out, "\n"), 'v:val=~"^HOME="')
+ let home = len(env) == 0 ? "" : substitute(env[0], '[^=]\+=', '', '')
+ call assert_equal(a:exp, home)
+endfunc
+
+func CheckHome(exp, ...)
+ call assert_equal(a:exp, $HOME)
+ call assert_equal(a:exp, expand('~', ':p'))
+ if !a:0
+ call CheckHomeIsMissingFromSubprocessEnvironment()
+ else
+ call CheckHomeIsInSubprocessEnvironment(a:1)
+ endif
+endfunc
+
+func Test_WindowsHome()
+ command! -nargs=* SaveEnv call <SID>save_env(<f-args>)
+ command! -nargs=* RestoreEnv call <SID>restore_env()
+ command! -nargs=* UnletEnv call <SID>unlet_env(<f-args>)
+ set noshellslash
+
+ let save_home = $HOME
+ SaveEnv $USERPROFILE $HOMEDRIVE $HOMEPATH
+ try
+ " Normal behavior: use $HOMEDRIVE and $HOMEPATH, ignore $USERPROFILE
+ let $USERPROFILE = 'unused'
+ let $HOMEDRIVE = 'C:'
+ let $HOMEPATH = '\foobar'
+ let $HOME = '' " Force recomputing "homedir"
+ call CheckHome('C:\foobar')
+
+ " Same, but with $HOMEPATH not set
+ UnletEnv $HOMEPATH
+ let $HOME = '' " Force recomputing "homedir"
+ call CheckHome('C:\')
+
+ " Use $USERPROFILE if $HOMEPATH and $HOMEDRIVE are empty
+ UnletEnv $HOMEDRIVE $HOMEPATH
+ let $USERPROFILE = 'C:\foo'
+ let $HOME = '' " Force recomputing "homedir"
+ call CheckHome('C:\foo')
+
+ " If $HOME is set the others don't matter
+ let $HOME = 'C:\bar'
+ let $USERPROFILE = 'unused'
+ let $HOMEDRIVE = 'unused'
+ let $HOMEPATH = 'unused'
+ call CheckHome('C:\bar', 'C:\bar')
+
+ " If $HOME contains %USERPROFILE% it is expanded
+ let $USERPROFILE = 'C:\foo'
+ let $HOME = '%USERPROFILE%\bar'
+ let $HOMEDRIVE = 'unused'
+ let $HOMEPATH = 'unused'
+ " call CheckHome('C:\foo\bar', '%USERPROFILE%\bar')
+
+ " Invalid $HOME is kept
+ let $USERPROFILE = 'C:\foo'
+ let $HOME = '%USERPROFILE'
+ let $HOMEDRIVE = 'unused'
+ let $HOMEPATH = 'unused'
+ call CheckHome('%USERPROFILE', '%USERPROFILE')
+
+ " %USERPROFILE% not at start of $HOME is not expanded
+ let $USERPROFILE = 'unused'
+ let $HOME = 'C:\%USERPROFILE%'
+ let $HOMEDRIVE = 'unused'
+ let $HOMEPATH = 'unused'
+ call CheckHome('C:\%USERPROFILE%', 'C:\%USERPROFILE%')
+
+ if has('channel')
+ RestoreEnv
+ let $HOME = save_home
+ let env = ''
+ let job = job_start('cmd /c set', {'out_cb': {ch,x->[env,execute('let env=x')]}})
+ sleep 1
+ let env = filter(split(env, "\n"), 'v:val=="HOME"')
+ let home = len(env) == 0 ? "" : env[0]
+ call assert_equal('', home)
+ endif
+ finally
+ RestoreEnv
+ delcommand SaveEnv
+ delcommand RestoreEnv
+ delcommand UnletEnv
+ endtry
+endfunc
diff --git a/src/nvim/testdir/test_wordcount.vim b/src/nvim/testdir/test_wordcount.vim
new file mode 100644
index 0000000000..75c4e4bffa
--- /dev/null
+++ b/src/nvim/testdir/test_wordcount.vim
@@ -0,0 +1,108 @@
+" Test for wordcount() function
+
+if !has('multi_byte')
+ finish
+endif
+
+func Test_wordcount()
+ let save_enc = &enc
+ set encoding=utf-8
+ set selection=inclusive fileformat=unix fileformats=unix
+
+ new
+
+ " Test 1: empty window
+ call assert_equal({'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0,
+ \ 'bytes': 0, 'cursor_bytes': 0}, wordcount())
+
+ " Test 2: some words, cursor at start
+ call append(1, 'one two three')
+ call cursor([1, 1, 0])
+ call assert_equal({'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0,
+ \ 'bytes': 15, 'cursor_bytes': 1}, wordcount())
+
+ " Test 3: some words, cursor at end
+ %d _
+ call append(1, 'one two three')
+ call cursor([2, 99, 0])
+ call assert_equal({'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3,
+ \ 'bytes': 15, 'cursor_bytes': 14}, wordcount())
+
+ " Test 4: some words, cursor at end, ve=all
+ set ve=all
+ %d _
+ call append(1, 'one two three')
+ call cursor([2, 99, 0])
+ call assert_equal({'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3,
+ \ 'bytes': 15, 'cursor_bytes': 15}, wordcount())
+ set ve=
+
+ " Test 5: several lines with words
+ %d _
+ call append(1, ['one two three', 'one two three', 'one two three'])
+ call cursor([4, 99, 0])
+ call assert_equal({'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9,
+ \ 'bytes': 43, 'cursor_bytes': 42}, wordcount())
+
+ " Test 6: one line with BOM set
+ %d _
+ call append(1, 'one two three')
+ set bomb
+ w! Xtest
+ call cursor([2, 99, 0])
+ call assert_equal({'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3,
+ \ 'bytes': 18, 'cursor_bytes': 14}, wordcount())
+ set nobomb
+ w!
+ call delete('Xtest')
+
+ " Test 7: one line with multibyte words
+ %d _
+ call append(1, ['Äne M¤ne Müh'])
+ call cursor([2, 99, 0])
+ call assert_equal({'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3,
+ \ 'bytes': 17, 'cursor_bytes': 16}, wordcount())
+
+ " Test 8: several lines with multibyte words
+ %d _
+ call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
+ call cursor([3, 99, 0])
+ call assert_equal({'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7,
+ \ 'bytes': 36, 'cursor_bytes': 35}, wordcount())
+
+ " Visual map to capture wordcount() in visual mode
+ vnoremap <expr> <F2> execute("let g:visual_stat = wordcount()")
+
+ " Test 9: visual mode, complete buffer
+ let g:visual_stat = {}
+ %d _
+ call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
+ " start visual mode and select the complete buffer
+ 0
+ exe "normal V2j\<F2>y"
+ call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32,
+ \ 'visual_words': 7, 'visual_bytes': 36}, g:visual_stat)
+
+ " Test 10: visual mode (empty)
+ %d _
+ call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
+ " start visual mode and select the complete buffer
+ 0
+ exe "normal v$\<F2>y"
+ call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1,
+ \ 'visual_words': 0, 'visual_bytes': 1}, g:visual_stat)
+
+ " Test 11: visual mode, single line
+ %d _
+ call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
+ " start visual mode and select the complete buffer
+ 2
+ exe "normal 0v$\<F2>y"
+ call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13,
+ \ 'visual_words': 3, 'visual_bytes': 16}, g:visual_stat)
+
+ set selection& fileformat& fileformats&
+ let &enc = save_enc
+ enew!
+ close
+endfunc
diff --git a/src/nvim/testdir/test_writefile.vim b/src/nvim/testdir/test_writefile.vim
new file mode 100644
index 0000000000..1cd5fb306a
--- /dev/null
+++ b/src/nvim/testdir/test_writefile.vim
@@ -0,0 +1,133 @@
+" Tests for the writefile() function.
+
+func Test_writefile()
+ let f = tempname()
+ call writefile(["over","written"], f, "b")
+ call writefile(["hello","world"], f, "b")
+ call writefile(["!", "good"], f, "a")
+ call writefile(["morning"], f, "ab")
+ call writefile(["", "vimmers"], f, "ab")
+ let l = readfile(f)
+ call assert_equal("hello", l[0])
+ call assert_equal("world!", l[1])
+ call assert_equal("good", l[2])
+ call assert_equal("morning", l[3])
+ call assert_equal("vimmers", l[4])
+ call delete(f)
+endfunc
+
+func Test_writefile_fails_gently()
+ call assert_fails('call writefile(["test"], "Xfile", [])', 'E730:')
+ call assert_false(filereadable("Xfile"))
+ call delete("Xfile")
+
+ call assert_fails('call writefile(["test", [], [], [], "tset"], "Xfile")', 'E745:')
+ call assert_false(filereadable("Xfile"))
+ call delete("Xfile")
+
+ call assert_fails('call writefile([], "Xfile", [])', 'E730:')
+ call assert_false(filereadable("Xfile"))
+ call delete("Xfile")
+
+ call assert_fails('call writefile([], [])', 'E730:')
+endfunc
+
+func Test_writefile_fails_conversion()
+ if !has('multi_byte') || !has('iconv')
+ return
+ endif
+ set nobackup nowritebackup
+ new
+ let contents = ["line one", "line two"]
+ call writefile(contents, 'Xfile')
+ edit Xfile
+ call setline(1, ["first line", "cannot convert \u010b", "third line"])
+ call assert_fails('write ++enc=cp932')
+ call assert_equal(contents, readfile('Xfile'))
+
+ call delete('Xfile')
+ bwipe!
+ set backup& writebackup&
+endfunc
+
+func SetFlag(timer)
+ let g:flag = 1
+endfunc
+
+func Test_write_quit_split()
+ " Prevent exiting by splitting window on file write.
+ augroup testgroup
+ autocmd BufWritePre * split
+ augroup END
+ e! Xfile
+ call setline(1, 'nothing')
+ wq
+
+ if has('timers')
+ " timer will not run if "exiting" is still set
+ let g:flag = 0
+ call timer_start(1, 'SetFlag')
+ sleep 50m
+ call assert_equal(1, g:flag)
+ unlet g:flag
+ endif
+ au! testgroup
+ bwipe Xfile
+ call delete('Xfile')
+endfunc
+
+func Test_nowrite_quit_split()
+ " Prevent exiting by opening a help window.
+ e! Xfile
+ help
+ wincmd w
+ exe winnr() . 'q'
+
+ if has('timers')
+ " timer will not run if "exiting" is still set
+ let g:flag = 0
+ call timer_start(1, 'SetFlag')
+ sleep 50m
+ call assert_equal(1, g:flag)
+ unlet g:flag
+ endif
+ bwipe Xfile
+endfunc
+
+func Test_writefile_autowrite()
+ set autowrite
+ new
+ next Xa Xb Xc
+ call setline(1, 'aaa')
+ next
+ call assert_equal(['aaa'], readfile('Xa'))
+ call setline(1, 'bbb')
+ call assert_fails('edit XX')
+ call assert_false(filereadable('Xb'))
+
+ set autowriteall
+ edit XX
+ call assert_equal(['bbb'], readfile('Xb'))
+
+ bwipe!
+ call delete('Xa')
+ call delete('Xb')
+ set noautowrite
+endfunc
+
+func Test_writefile_autowrite_nowrite()
+ set autowrite
+ new
+ next Xa Xb Xc
+ set buftype=nowrite
+ call setline(1, 'aaa')
+ let buf = bufnr('%')
+ " buffer contents silently lost
+ edit XX
+ call assert_false(filereadable('Xa'))
+ rewind
+ call assert_equal('', getline(1))
+
+ bwipe!
+ set noautowrite
+endfunc
diff --git a/src/nvim/testdir/unix.vim b/src/nvim/testdir/unix.vim
index a7daacf8cf..ce2beff7fe 100644
--- a/src/nvim/testdir/unix.vim
+++ b/src/nvim/testdir/unix.vim
@@ -2,6 +2,12 @@
" Always use "sh", don't use the value of "$SHELL".
set shell=sh
+if has('win32')
+ set shellcmdflag=-c shellxquote= shellxescape= shellquote=
+ let &shellredir = '>%s 2>&1'
+ set shellslash
+endif
+
" Don't depend on system locale, always use utf-8
set encoding=utf-8
diff --git a/src/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim
new file mode 100644
index 0000000000..29ea073f97
--- /dev/null
+++ b/src/nvim/testdir/view_util.vim
@@ -0,0 +1,51 @@
+" Functions about view shared by several tests
+
+" Only load this script once.
+if exists('*ScreenLines')
+ finish
+endif
+
+" ScreenLines(lnum, width) or
+" ScreenLines([start, end], width)
+function! ScreenLines(lnum, width) abort
+ redraw!
+ if type(a:lnum) == v:t_list
+ let start = a:lnum[0]
+ let end = a:lnum[1]
+ else
+ let start = a:lnum
+ let end = a:lnum
+ endif
+ let lines = []
+ for l in range(start, end)
+ let lines += [join(map(range(1, a:width), 'nr2char(screenchar(l, v:val))'), '')]
+ endfor
+ return lines
+endfunction
+
+function! ScreenAttrs(lnum, width) abort
+ redraw!
+ if type(a:lnum) == v:t_list
+ let start = a:lnum[0]
+ let end = a:lnum[1]
+ else
+ let start = a:lnum
+ let end = a:lnum
+ endif
+ let attrs = []
+ for l in range(start, end)
+ let attrs += [map(range(1, a:width), 'screenattr(l, v:val)')]
+ endfor
+ return attrs
+endfunction
+
+function! NewWindow(height, width) abort
+ exe a:height . 'new'
+ exe a:width . 'vsp'
+ redraw!
+endfunction
+
+function! CloseWindow() abort
+ bw!
+ redraw!
+endfunction
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index c41107d4d3..e0dd4022ed 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.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 "nvim/tui/input.h"
#include "nvim/vim.h"
@@ -6,15 +9,13 @@
#include "nvim/ascii.h"
#include "nvim/charset.h"
#include "nvim/main.h"
-#include "nvim/misc2.h"
+#include "nvim/aucmd.h"
#include "nvim/option.h"
#include "nvim/os/os.h"
#include "nvim/os/input.h"
#include "nvim/event/rstream.h"
#define PASTETOGGLE_KEY "<Paste>"
-#define FOCUSGAINED_KEY "<FocusGained>"
-#define FOCUSLOST_KEY "<FocusLost>"
#define KEY_BUFFER_SIZE 0xfff
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -34,13 +35,28 @@ void term_input_init(TermInput *input, Loop *loop)
if (!term) {
term = ""; // termkey_new_abstract assumes non-null (#2745)
}
- int enc_flag = enc_utf8 ? TERMKEY_FLAG_UTF8 : TERMKEY_FLAG_RAW;
- input->tk = termkey_new_abstract(term, enc_flag);
+
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+ input->tk = termkey_new_abstract(term,
+ TERMKEY_FLAG_UTF8 | TERMKEY_FLAG_NOSTART);
+ termkey_hook_terminfo_getstr(input->tk, input->tk_ti_hook_fn, NULL);
+ termkey_start(input->tk);
+#else
+ input->tk = termkey_new_abstract(term, TERMKEY_FLAG_UTF8);
+#endif
int curflags = termkey_get_canonflags(input->tk);
termkey_set_canonflags(input->tk, curflags | TERMKEY_CANON_DELBS);
// setup input handle
- rstream_init_fd(loop, &input->read_stream, input->in_fd, 0xfff, input);
+#ifdef WIN32
+ uv_tty_init(&loop->uv, &input->tty_in, 0, 1);
+ uv_tty_set_mode(&input->tty_in, UV_TTY_MODE_RAW);
+ rstream_init_stream(&input->read_stream,
+ (uv_stream_t *)&input->tty_in,
+ 0xfff);
+#else
+ rstream_init_fd(loop, &input->read_stream, input->in_fd, 0xfff);
+#endif
// initialize a timer handle for handling ESC with libtermkey
time_watcher_init(loop, &input->timer_handle, input);
}
@@ -51,13 +67,13 @@ void term_input_destroy(TermInput *input)
uv_mutex_destroy(&input->key_buffer_mutex);
uv_cond_destroy(&input->key_buffer_cond);
time_watcher_close(&input->timer_handle, NULL);
- stream_close(&input->read_stream, NULL);
+ stream_close(&input->read_stream, NULL, NULL);
termkey_destroy(input->tk);
}
void term_input_start(TermInput *input)
{
- rstream_start(&input->read_stream, read_cb);
+ rstream_start(&input->read_stream, read_cb, input);
}
void term_input_stop(TermInput *input)
@@ -95,7 +111,7 @@ static void flush_input(TermInput *input, bool wait_until_empty)
size_t drain_boundary = wait_until_empty ? 0 : 0xff;
do {
uv_mutex_lock(&input->key_buffer_mutex);
- loop_schedule(&main_loop, event_create(1, wait_input_enqueue, 1, input));
+ loop_schedule(&main_loop, event_create(wait_input_enqueue, 1, input));
input->waiting = true;
while (input->waiting) {
uv_cond_wait(&input->key_buffer_cond, &input->key_buffer_mutex);
@@ -156,11 +172,21 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
char buf[64];
size_t len = 0;
int button, row, col;
+ static int last_pressed_button = 0;
TermKeyMouseEvent ev;
termkey_interpret_mouse(input->tk, key, &ev, &button, &row, &col);
- if (ev != TERMKEY_MOUSE_PRESS && ev != TERMKEY_MOUSE_DRAG
- && ev != TERMKEY_MOUSE_RELEASE) {
+ if ((ev == TERMKEY_MOUSE_RELEASE || ev == TERMKEY_MOUSE_DRAG)
+ && button == 0) {
+ // Some terminals (like urxvt) don't report which button was released.
+ // libtermkey reports button 0 in this case.
+ // For drag and release, we can reasonably infer the button to be the last
+ // pressed one.
+ button = last_pressed_button;
+ }
+
+ if (button == 0 || (ev != TERMKEY_MOUSE_PRESS && ev != TERMKEY_MOUSE_DRAG
+ && ev != TERMKEY_MOUSE_RELEASE)) {
return;
}
@@ -187,18 +213,26 @@ static void forward_mouse_event(TermInput *input, TermKeyKey *key)
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Right");
}
- if (ev == TERMKEY_MOUSE_PRESS) {
- if (button == 4) {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp");
- } else if (button == 5) {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelDown");
- } else {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse");
- }
- } else if (ev == TERMKEY_MOUSE_DRAG) {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag");
- } else if (ev == TERMKEY_MOUSE_RELEASE) {
- len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release");
+ switch (ev) {
+ case TERMKEY_MOUSE_PRESS:
+ if (button == 4) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "ScrollWheelUp");
+ } else if (button == 5) {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len,
+ "ScrollWheelDown");
+ } else {
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Mouse");
+ last_pressed_button = button;
+ }
+ break;
+ case TERMKEY_MOUSE_DRAG:
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Drag");
+ break;
+ case TERMKEY_MOUSE_RELEASE:
+ len += (size_t)snprintf(buf + len, sizeof(buf) - len, "Release");
+ break;
+ case TERMKEY_MOUSE_UNKNOWN:
+ assert(false);
}
len += (size_t)snprintf(buf + len, sizeof(buf) - len, "><%d,%d>", col, row);
@@ -216,12 +250,14 @@ static int get_key_code_timeout(void)
{
Integer ms = -1;
// Check 'ttimeout' to determine if we should send ESC after 'ttimeoutlen'.
- // See :help 'ttimeout' for more information
Error err = ERROR_INIT;
- if (vim_get_option(cstr_as_string("ttimeout"), &err).data.boolean) {
- ms = vim_get_option(cstr_as_string("ttimeoutlen"), &err).data.integer;
+ if (nvim_get_option(cstr_as_string("ttimeout"), &err).data.boolean) {
+ Object rv = nvim_get_option(cstr_as_string("ttimeoutlen"), &err);
+ if (!ERROR_SET(&err)) {
+ ms = rv.data.integer;
+ }
}
-
+ api_clear_error(&err);
return (int)ms;
}
@@ -265,9 +301,9 @@ static void timer_cb(TimeWatcher *watcher, void *data)
/// Handle focus events.
///
-/// If the upcoming sequence of bytes in the input stream matches either the
-/// escape code for focus gained `<ESC>[I` or focus lost `<ESC>[O` then consume
-/// that sequence and push the appropriate event into the input queue
+/// If the upcoming sequence of bytes in the input stream matches the termcode
+/// for "focus gained" or "focus lost", consume that sequence and schedule an
+/// event on the main loop.
///
/// @param input the input stream
/// @return true iff handle_focus_event consumed some input
@@ -279,11 +315,7 @@ static bool handle_focus_event(TermInput *input)
// Advance past the sequence
bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I';
rbuffer_consumed(input->read_stream.buffer, 3);
- if (focus_gained) {
- enqueue_input(input, FOCUSGAINED_KEY, sizeof(FOCUSGAINED_KEY) - 1);
- } else {
- enqueue_input(input, FOCUSLOST_KEY, sizeof(FOCUSLOST_KEY) - 1);
- }
+ aucmd_schedule_focusgained(focus_gained);
return true;
}
return false;
@@ -326,8 +358,8 @@ static void set_bg_deferred(void **argv)
{
char *bgvalue = argv[0];
set_string_default("bg", bgvalue, false);
- if (!option_was_set((char_u *)"bg")) {
- set_option_value((char_u *)"bg", 0, (char_u *)bgvalue, 0);
+ if (!option_was_set("bg")) {
+ set_option_value("bg", 0, bgvalue, 0);
}
}
@@ -373,19 +405,17 @@ static bool handle_background_color(TermInput *input)
double r = (double)rgb[0] / (double)rgb_max[0];
double g = (double)rgb[1] / (double)rgb_max[1];
double b = (double)rgb[2] / (double)rgb_max[2];
- double luminance = 0.299*r + 0.587*g + 0.114*b; // CCIR 601
+ double luminance = (0.299 * r) + (0.587 * g) + (0.114 * b); // CCIR 601
char *bgvalue = luminance < 0.5 ? "dark" : "light";
- loop_schedule(&main_loop, event_create(1, set_bg_deferred, 1, bgvalue));
+ loop_schedule(&main_loop, event_create(set_bg_deferred, 1, bgvalue));
}
return true;
}
return false;
}
-static void restart_reading(void **argv);
-
-static void read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
- bool eof)
+static void read_cb(Stream *stream, RBuffer *buf, size_t count_, void *data,
+ bool eof)
{
TermInput *input = data;
@@ -402,10 +432,10 @@ static void read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
//
// ls *.md | xargs nvim
input->in_fd = 2;
- stream_close(&input->read_stream, NULL);
- queue_put(input->loop->fast_events, restart_reading, 1, input);
+ stream_close(&input->read_stream, NULL, NULL);
+ multiqueue_put(input->loop->fast_events, restart_reading, 1, input);
} else {
- loop_schedule(&main_loop, event_create(1, input_done_event, 0));
+ loop_schedule(&main_loop, event_create(input_done_event, 0));
}
return;
}
@@ -454,6 +484,6 @@ static void read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
static void restart_reading(void **argv)
{
TermInput *input = argv[0];
- rstream_init_fd(input->loop, &input->read_stream, input->in_fd, 0xfff, input);
- rstream_start(&input->read_stream, read_cb);
+ rstream_init_fd(input->loop, &input->read_stream, input->in_fd, 0xfff);
+ rstream_start(&input->read_stream, read_cb, input);
}
diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h
index d7ee2b9e52..573cc9d683 100644
--- a/src/nvim/tui/input.h
+++ b/src/nvim/tui/input.h
@@ -12,8 +12,14 @@ typedef struct term_input {
bool paste_enabled;
bool waiting;
TermKey *tk;
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+ TermKey_Terminfo_Getstr_Hook *tk_ti_hook_fn; ///< libtermkey terminfo hook
+#endif
TimeWatcher timer_handle;
Loop *loop;
+#ifdef WIN32
+ uv_tty_t tty_in;
+#endif
Stream read_stream;
RBuffer *key_buffer;
uv_mutex_t key_buffer_mutex;
diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c
new file mode 100644
index 0000000000..14023ce2cb
--- /dev/null
+++ b/src/nvim/tui/terminfo.c
@@ -0,0 +1,225 @@
+// 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
+
+// Built-in fallback terminfo entries.
+
+#include <stdbool.h>
+#include <string.h>
+
+#include <unibilium.h>
+
+#include "nvim/log.h"
+#include "nvim/globals.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
+#include "nvim/option.h"
+#include "nvim/os/os.h"
+#include "nvim/tui/terminfo.h"
+#include "nvim/tui/terminfo_defs.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "tui/terminfo.c.generated.h"
+#endif
+
+bool terminfo_is_term_family(const char *term, const char *family)
+{
+ if (!term) {
+ return false;
+ }
+ size_t tlen = strlen(term);
+ size_t flen = strlen(family);
+ return tlen >= flen
+ && 0 == memcmp(term, family, flen)
+ // Per commentary in terminfo, minus is the only valid suffix separator.
+ && ('\0' == term[flen] || '-' == term[flen]);
+}
+
+bool terminfo_is_bsd_console(const char *term)
+{
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
+ || defined(__DragonFly__)
+ if (strequal(term, "vt220") // OpenBSD
+ || strequal(term, "vt100")) { // NetBSD
+ return true;
+ }
+# if defined(__FreeBSD__)
+ // FreeBSD console sets TERM=xterm, but it does not support xterm features
+ // like cursor-shaping. Assume that TERM=xterm is degraded. #8644
+ return strequal(term, "xterm") && !!os_getenv("XTERM_VERSION");
+# endif
+#else
+ return false;
+#endif
+}
+
+/// Loads a built-in terminfo db when we (unibilium) failed to load a terminfo
+/// record from the environment (termcap systems, unrecognized $TERM, …).
+/// We do not attempt to detect xterm pretenders here.
+///
+/// @param term $TERM value
+/// @param[out,allocated] termname decided builtin 'term' name
+/// @return [allocated] terminfo structure
+static unibi_term *terminfo_builtin(const char *term, char **termname)
+{
+ if (terminfo_is_term_family(term, "xterm")) {
+ *termname = xstrdup("builtin_xterm");
+ return unibi_from_mem((const char *)xterm_256colour_terminfo,
+ sizeof xterm_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "screen")) {
+ *termname = xstrdup("builtin_screen");
+ return unibi_from_mem((const char *)screen_256colour_terminfo,
+ sizeof screen_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "tmux")) {
+ *termname = xstrdup("builtin_tmux");
+ return unibi_from_mem((const char *)tmux_256colour_terminfo,
+ sizeof tmux_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "rxvt")) {
+ *termname = xstrdup("builtin_rxvt");
+ return unibi_from_mem((const char *)rxvt_256colour_terminfo,
+ sizeof rxvt_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "putty")) {
+ *termname = xstrdup("builtin_putty");
+ return unibi_from_mem((const char *)putty_256colour_terminfo,
+ sizeof putty_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "linux")) {
+ *termname = xstrdup("builtin_linux");
+ return unibi_from_mem((const char *)linux_16colour_terminfo,
+ sizeof linux_16colour_terminfo);
+ } else if (terminfo_is_term_family(term, "interix")) {
+ *termname = xstrdup("builtin_interix");
+ return unibi_from_mem((const char *)interix_8colour_terminfo,
+ sizeof interix_8colour_terminfo);
+ } else if (terminfo_is_term_family(term, "iterm")
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app")) {
+ *termname = xstrdup("builtin_iterm");
+ return unibi_from_mem((const char *)iterm_256colour_terminfo,
+ sizeof iterm_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "st")) {
+ *termname = xstrdup("builtin_st");
+ return unibi_from_mem((const char *)st_256colour_terminfo,
+ sizeof st_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "gnome")
+ || terminfo_is_term_family(term, "vte")) {
+ *termname = xstrdup("builtin_vte");
+ return unibi_from_mem((const char *)vte_256colour_terminfo,
+ sizeof vte_256colour_terminfo);
+ } else if (terminfo_is_term_family(term, "cygwin")) {
+ *termname = xstrdup("builtin_cygwin");
+ return unibi_from_mem((const char *)cygwin_terminfo,
+ sizeof cygwin_terminfo);
+ } else if (terminfo_is_term_family(term, "win32con")) {
+ *termname = xstrdup("builtin_win32con");
+ return unibi_from_mem((const char *)win32con_terminfo,
+ sizeof win32con_terminfo);
+ } else if (terminfo_is_term_family(term, "conemu")) {
+ *termname = xstrdup("builtin_conemu");
+ return unibi_from_mem((const char *)conemu_terminfo,
+ sizeof conemu_terminfo);
+ } else if (terminfo_is_term_family(term, "vtpcon")) {
+ *termname = xstrdup("builtin_vtpcon");
+ return unibi_from_mem((const char *)vtpcon_terminfo,
+ sizeof vtpcon_terminfo);
+ } else {
+ *termname = xstrdup("builtin_ansi");
+ return unibi_from_mem((const char *)ansi_terminfo,
+ sizeof ansi_terminfo);
+ }
+}
+
+/// @param term $TERM value
+/// @param[out,allocated] termname decided builtin 'term' name
+/// @return [allocated] terminfo structure
+unibi_term *terminfo_from_builtin(const char *term, char **termname)
+{
+ unibi_term *ut = terminfo_builtin(term, termname);
+ if (*termname == NULL) {
+ *termname = xstrdup("builtin_?");
+ }
+ return ut;
+}
+
+/// Dumps termcap info to the messages area.
+/// Serves a similar purpose as Vim `:set termcap` (removed in Nvim).
+///
+/// @note adapted from unibilium unibi-dump.c
+void terminfo_info_msg(const unibi_term *const ut)
+{
+ if (exiting) {
+ return;
+ }
+ msg_puts_title("\n\n--- Terminal info --- {{{\n");
+
+ char *term;
+ get_tty_option("term", &term);
+ msg_printf_attr(0, "&term: %s\n", term);
+ msg_printf_attr(0, "Description: %s\n", unibi_get_name(ut));
+ const char **a = unibi_get_aliases(ut);
+ if (*a) {
+ msg_puts("Aliases: ");
+ do {
+ msg_printf_attr(0, "%s%s\n", *a, a[1] ? " | " : "");
+ a++;
+ } while (*a);
+ }
+
+ msg_puts("Boolean capabilities:\n");
+ for (enum unibi_boolean i = unibi_boolean_begin_ + 1;
+ i < unibi_boolean_end_; i++) {
+ msg_printf_attr(0, " %-25s %-10s = %s\n", unibi_name_bool(i),
+ unibi_short_name_bool(i),
+ unibi_get_bool(ut, i) ? "true" : "false");
+ }
+
+ msg_puts("Numeric capabilities:\n");
+ for (enum unibi_numeric i = unibi_numeric_begin_ + 1;
+ i < unibi_numeric_end_; i++) {
+ int n = unibi_get_num(ut, i); // -1 means "empty"
+ msg_printf_attr(0, " %-25s %-10s = %d\n", unibi_name_num(i),
+ unibi_short_name_num(i), n);
+ }
+
+ msg_puts("String capabilities:\n");
+ for (enum unibi_string i = unibi_string_begin_ + 1;
+ i < unibi_string_end_; i++) {
+ const char *s = unibi_get_str(ut, i);
+ if (s) {
+ msg_printf_attr(0, " %-25s %-10s = ", unibi_name_str(i),
+ unibi_short_name_str(i));
+ // Most of these strings will contain escape sequences.
+ msg_outtrans_special((char_u *)s, false);
+ msg_putchar('\n');
+ }
+ }
+
+ if (unibi_count_ext_bool(ut)) {
+ msg_puts("Extended boolean capabilities:\n");
+ for (size_t i = 0; i < unibi_count_ext_bool(ut); i++) {
+ msg_printf_attr(0, " %-25s = %s\n",
+ unibi_get_ext_bool_name(ut, i),
+ unibi_get_ext_bool(ut, i) ? "true" : "false");
+ }
+ }
+
+ if (unibi_count_ext_num(ut)) {
+ msg_puts("Extended numeric capabilities:\n");
+ for (size_t i = 0; i < unibi_count_ext_num(ut); i++) {
+ msg_printf_attr(0, " %-25s = %d\n",
+ unibi_get_ext_num_name(ut, i),
+ unibi_get_ext_num(ut, i));
+ }
+ }
+
+ if (unibi_count_ext_str(ut)) {
+ msg_puts("Extended string capabilities:\n");
+ for (size_t i = 0; i < unibi_count_ext_str(ut); i++) {
+ msg_printf_attr(0, " %-25s = ", unibi_get_ext_str_name(ut, i));
+ msg_outtrans_special((char_u *)unibi_get_ext_str(ut, i), false);
+ msg_putchar('\n');
+ }
+ }
+
+ msg_puts("}}}\n");
+ xfree(term);
+}
diff --git a/src/nvim/tui/terminfo.h b/src/nvim/tui/terminfo.h
new file mode 100644
index 0000000000..099df8967f
--- /dev/null
+++ b/src/nvim/tui/terminfo.h
@@ -0,0 +1,10 @@
+#ifndef NVIM_TUI_TERMINFO_H
+#define NVIM_TUI_TERMINFO_H
+
+#include <unibilium.h>
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "tui/terminfo.h.generated.h"
+#endif
+
+#endif // NVIM_TUI_TERMINFO_H
diff --git a/src/nvim/tui/terminfo_defs.h b/src/nvim/tui/terminfo_defs.h
new file mode 100644
index 0000000000..8d77dc7225
--- /dev/null
+++ b/src/nvim/tui/terminfo_defs.h
@@ -0,0 +1,2276 @@
+// 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
+
+//
+// Generated by scripts/update_terminfo.sh and ncurses 6.1.20180127
+//
+
+#ifndef NVIM_TUI_TERMINFO_DEFS_H
+#define NVIM_TUI_TERMINFO_DEFS_H
+
+#include <stdint.h>
+
+// ansi|ansi/pc-term compatible with color,
+// auto_right_margin,
+// backspaces_with_bs,
+// move_insert_mode,
+// move_standout_mode,
+// prtr_silent,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#8,
+// max_pairs#64,
+// no_color_video#3,
+// acs_chars=+^P\054^Q-^X.^Y0\333`^Da\261f\370g\361h\260j\331k\277l\332m\300n\305o~p\304q\304r\304s_t\303u\264v\301w\302x\263y\363z\362{\343|\330}\234~\376,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\E[B,
+// cursor_home=\E[H,
+// cursor_left=\E[D,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// enter_alt_charset_mode=\E[11m,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_pc_charset_mode=\E[11m,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode=\E[8m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// erase_chars=\E[%p1%dX,
+// exit_alt_charset_mode=\E[10m,
+// exit_attribute_mode=\E[0;10m,
+// exit_pc_charset_mode=\E[10m,
+// exit_standout_mode=\E[m,
+// exit_underline_mode=\E[m,
+// insert_line=\E[L,
+// key_backspace=^H,
+// key_btab=\E[Z,
+// key_down=\E[B,
+// key_home=\E[H,
+// key_ic=\E[L,
+// key_left=\E[D,
+// key_right=\E[C,
+// key_up=\E[A,
+// newline=\r\E[S,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_rindex=\E[%p1%dT,
+// parm_up_cursor=\E[%p1%dA,
+// prtr_off=\E[4i,
+// prtr_on=\E[5i,
+// repeat_char=%p1%c\E[%p2%{1}%-%db,
+// row_address=\E[%i%p1%dd,
+// scroll_forward=\n,
+// set0_des_seq=\E(B,
+// set1_des_seq=\E)B,
+// set2_des_seq=\E*B,
+// set3_des_seq=\E+B,
+// set_a_background=\E[4%p1%dm,
+// set_a_foreground=\E[3%p1%dm,
+// set_attributes=\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;%?%p7%t;8%;%?%p9%t;11%;m,
+// set_tab=\EH,
+// tab=\E[I,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?%[;0123456789]c,
+// user9=\E[c,
+static const int8_t ansi_terminfo[] = {
+ 26,1,40,0,38,0,16,0,125,1,68,2,97,110,115,105,124,97,110,115,105,47,112,99,45,116,101,114,109,32,99,111,109,112,97,116,105,98,108,101,32,119,105,116,104,32,99,111,108,111,114,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,80,0,8,0,24,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,0,64,0,3,0,0,0,4,0,6,0,-1,-1,8,0,13,0,20,0,24,0,28,0,-1,-1,39,0,56,0,60,0,-1,-1,64,0,-1,-1,-1,-1,68,0,-1,-1,72,0,-1,-1,76,0,80,0,-1,-1,-1,-1,84,0,90,0,95,0,-1,-1,-1,-1,-1,-1,-1,-1,100,0,-1,-1,105,0,110,0,115,0,120,0,-127,0,-121,0,-1,-1,-1,-1,-1,-1,-113,0,-109,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-105,0,-1,-1,-101,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-99,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-95,0,-91,0,-1,-1,-87,0,-1,-1,-1,-1,-1,-1,-83,0,-1,-1,-1,-1,-1,-1,-79,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-75,0,-1,-1,-70,0,-61,0,-52,0,-43,0,-34,0,-25,0,-16,0,-7,0,2,1,11,1,-1,-1,-1,-1,-1,-1,-1,-1,20,1,25,1,30,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,50,1,-1,-1,61,1,-1,-1,63,1,-107,1,-1,-1,-104,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-100,1,-1,-1,-37,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-33,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-28,1,-17,1,-12,1,7,2,11,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,20,2,30,2,-1,-1,-1,-1,-1,-1,40,2,44,2,48,2,52,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,56,2,62,2,27,91,90,0,7,0,13,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,27,91,66,0,27,91,72,0,27,91,68,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,27,91,49,49,109,0,27,91,53,109,0,27,91,49,109,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,91,49,48,109,0,27,91,48,59,49,48,109,0,27,91,109,0,27,91,109,0,27,91,76,0,8,0,27,91,66,0,27,91,72,0,27,91,76,0,27,91,68,0,27,91,67,0,27,91,65,0,13,27,91,83,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,91,52,105,0,27,91,53,105,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,91,37,105,37,112,49,37,100,100,0,10,0,27,91,48,59,49,48,37,63,37,112,49,37,116,59,55,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,51,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,55,37,116,59,56,37,59,37,63,37,112,57,37,116,59,49,49,37,59,109,0,27,72,0,27,91,73,0,43,16,44,17,45,24,46,25,48,-37,96,4,97,-79,102,-8,103,-15,104,-80,106,-39,107,-65,108,-38,109,-64,110,-59,111,126,112,-60,113,-60,114,-60,115,95,116,-61,117,-76,118,-63,119,-62,120,-77,121,-13,122,-14,123,-29,124,-40,125,-100,126,-2,0,27,91,90,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,91,51,37,112,49,37,100,109,0,27,91,52,37,112,49,37,100,109,0,27,40,66,0,27,41,66,0,27,42,66,0,27,43,66,0,27,91,49,49,109,0,27,91,49,48,109,0,1,0,0,0,0,0,1,0,3,0,1,0,0,0,65,88,0 // NOLINT
+};
+
+// conemu|ANIS X3.64 and Xterm 256 colors for ConEmu with libuv,
+// auto_right_margin,
+// back_color_erase,
+// backspaces_with_bs,
+// has_meta_key,
+// move_insert_mode,
+// move_standout_mode,
+// no_pad_char,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// acs_chars@,
+// back_tab@,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs@,
+// clear_screen=\E[H\E[2J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\E[B,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// cursor_visible@,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// enter_alt_charset_mode@,
+// enter_am_mode@,
+// enter_blink_mode@,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[?1049h,
+// enter_dim_mode@,
+// enter_insert_mode@,
+// enter_italics_mode=\E[3m,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode@,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// erase_chars=\E[%p1%dX,
+// exit_alt_charset_mode@,
+// exit_am_mode@,
+// exit_attribute_mode=\E[0m,
+// exit_ca_mode=\E[?1049l,
+// exit_insert_mode@,
+// exit_italics_mode=\E[23m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen@,
+// init_2string@,
+// initialize_color@,
+// insert_line=\E[L,
+// key_b2=\E[G,
+// key_backspace=^H,
+// key_btab=\E[Z,
+// key_dc=\E[3~,
+// key_down=\E[B,
+// key_end=\E[4~,
+// key_enter=\EOM,
+// key_f1=\E[[A,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[25~,
+// key_f14=\E[26~,
+// key_f15=\E[28~,
+// key_f16=\E[29~,
+// key_f17=\E[31~,
+// key_f18=\E[32~,
+// key_f19=\E[33~,
+// key_f2=\E[[B,
+// key_f20=\E[34~,
+// key_f21=\E[23$,
+// key_f22=\E[24$,
+// key_f23=\E[11\136,
+// key_f24=\E[12\136,
+// key_f25=\E[13\136,
+// key_f26=\E[14\136,
+// key_f27=\E[15\136,
+// key_f28=\E[17\136,
+// key_f29=\E[18\136,
+// key_f3=\E[[C,
+// key_f30=\E[19\136,
+// key_f31=\E[20\136,
+// key_f32=\E[21\136,
+// key_f33=\E[23\136,
+// key_f34=\E[24\136,
+// key_f35=\E[25\136,
+// key_f36=\E[26\136,
+// key_f37=\E[28\136,
+// key_f38=\E[29\136,
+// key_f39=\E[31\136,
+// key_f4=\E[[D,
+// key_f40=\E[1;6S,
+// key_f41=\E[32\136,
+// key_f42=\E[33\136,
+// key_f43=\E[34\136,
+// key_f44=\E[23@,
+// key_f45=\E[24@,
+// key_f46@,
+// key_f47@,
+// key_f48@,
+// key_f49@,
+// key_f5=\E[[E,
+// key_f50@,
+// key_f51@,
+// key_f52@,
+// key_f53@,
+// key_f54@,
+// key_f55@,
+// key_f56@,
+// key_f57@,
+// key_f58@,
+// key_f59@,
+// key_f6=\E[17~,
+// key_f60@,
+// key_f61@,
+// key_f62@,
+// key_f63@,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_left=\E[D,
+// key_mouse@,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\E[C,
+// key_sdc=\E[3;2~,
+// key_send=\E[4;2~,
+// key_sf=\E[1;2B,
+// key_shome=\E[1;2~,
+// key_sic=\E[2;2~,
+// key_sleft=\E[1;2D,
+// key_snext=\E[6;2~,
+// key_sprevious=\E[5;2~,
+// key_sr=\E[1;2A,
+// key_sright=\E[1;2C,
+// key_up=\E[A,
+// keypad_local@,
+// keypad_xmit@,
+// memory_lock@,
+// memory_unlock@,
+// meta_off@,
+// meta_on@,
+// orig_colors@,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_rindex=\E[%p1%dT,
+// parm_up_cursor=\E[%p1%dA,
+// print_screen@,
+// prtr_off@,
+// prtr_on@,
+// repeat_char=%p1%c\E[%p2%{1}%-%db,
+// reset_1string@,
+// reset_2string@,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[48;5;%p1%dm,
+// set_a_foreground=\E[38;5;%p1%dm,
+// set_attributes=\E[0%?%p1%p3%|%t;7%;%?%p2%t;4%;%?%p6%t;1%;m,
+// set_tab@,
+// tab=^I,
+// user6@,
+// user7@,
+// user8@,
+// user9@,
+static const int8_t conemu_terminfo[] = {
+ 30,2,61,0,38,0,15,0,-99,1,31,3,99,111,110,101,109,117,124,65,78,73,83,32,88,51,46,54,52,32,97,110,100,32,88,116,101,114,109,32,50,53,54,32,99,111,108,111,114,115,32,102,111,114,32,67,111,110,69,109,117,32,119,105,116,104,32,108,105,98,117,118,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,-2,-1,0,0,2,0,4,0,-2,-1,21,0,29,0,33,0,37,0,-1,-1,48,0,65,0,69,0,73,0,80,0,-1,-1,82,0,89,0,-1,-1,93,0,-2,-1,97,0,101,0,-1,-1,-1,-1,-2,-1,-2,-1,105,0,110,0,-1,-1,-2,-1,-2,-1,-2,-1,-1,-1,119,0,124,0,-127,0,-122,0,-2,-1,-113,0,-108,0,-1,-1,-2,-1,-99,0,-93,0,-2,-1,-1,-1,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-87,0,-1,-1,-83,0,-1,-1,-1,-1,-1,-1,-81,0,-1,-1,-76,0,-1,-1,-1,-1,-1,-1,-1,-1,-72,0,-67,0,-61,0,-56,0,-51,0,-46,0,-41,0,-35,0,-29,0,-23,0,-17,0,-12,0,-1,-1,-7,0,-1,-1,-3,0,2,1,7,1,11,1,18,1,-1,-1,25,1,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-1,-1,-1,-1,29,1,38,1,47,1,56,1,65,1,74,1,83,1,92,1,101,1,110,1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,119,1,-2,-1,-2,-1,-1,-1,-1,-1,-117,1,-114,1,-103,1,-100,1,-98,1,-95,1,-2,-1,-1,-1,-52,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-50,1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-1,-1,-46,1,-1,-1,-1,-1,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-42,1,-37,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-33,1,-1,-1,-1,-1,-26,1,-1,-1,-1,-1,-1,-1,-1,-1,-19,1,-12,1,-5,1,-1,-1,-1,-1,2,2,-1,-1,9,2,-1,-1,-1,-1,-1,-1,16,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,23,2,29,2,35,2,41,2,47,2,53,2,59,2,65,2,71,2,77,2,83,2,89,2,95,2,101,2,107,2,113,2,119,2,125,2,-125,2,-119,2,-113,2,-107,2,-101,2,-95,2,-89,2,-83,2,-77,2,-71,2,-65,2,-59,2,-52,2,-46,2,-40,2,-34,2,-28,2,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-22,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-17,2,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-8,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-3,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,3,3,17,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,27,91,66,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,27,91,49,109,0,27,91,63,49,48,52,57,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,91,48,109,0,27,91,63,49,48,52,57,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,76,0,8,0,27,91,51,126,0,27,91,66,0,27,91,91,65,0,27,91,50,49,126,0,27,91,91,66,0,27,91,91,67,0,27,91,91,68,0,27,91,91,69,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,91,68,0,27,91,54,126,0,27,91,53,126,0,27,91,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,91,65,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,54,37,116,59,49,37,59,109,0,9,0,27,91,71,0,27,91,90,0,27,91,52,126,0,27,79,77,0,27,91,51,59,50,126,0,27,91,52,59,50,126,0,27,91,49,59,50,126,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,50,51,36,0,27,91,50,52,36,0,27,91,49,49,94,0,27,91,49,50,94,0,27,91,49,51,94,0,27,91,49,52,94,0,27,91,49,53,94,0,27,91,49,55,94,0,27,91,49,56,94,0,27,91,49,57,94,0,27,91,50,48,94,0,27,91,50,49,94,0,27,91,50,51,94,0,27,91,50,52,94,0,27,91,50,53,94,0,27,91,50,54,94,0,27,91,50,56,94,0,27,91,50,57,94,0,27,91,51,49,94,0,27,91,49,59,54,83,0,27,91,51,50,94,0,27,91,51,51,94,0,27,91,51,52,94,0,27,91,50,51,64,0,27,91,50,52,64,0,27,91,49,75,0,27,91,51,57,59,52,57,109,0,27,91,51,109,0,27,91,50,51,109,0,27,91,51,56,59,53,59,37,112,49,37,100,109,0,27,91,52,56,59,53,59,37,112,49,37,100,109,0,0,3,0,1,0,74,0,-104,0,-95,1,1,0,1,0,-1,-1,-1,-1,-2,-1,-2,-1,-1,-1,0,0,-2,-1,-1,-1,5,0,-1,-1,11,0,-1,-1,-2,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,21,0,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,39,0,42,0,45,0,48,0,54,0,60,0,65,0,70,0,75,0,80,0,85,0,89,0,94,0,99,0,104,0,109,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-70,0,-65,0,-60,0,-55,0,-50,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,75,1,79,1,84,1,89,1,94,1,99,1,104,1,108,1,112,1,116,1,120,1,125,1,-126,1,27,91,51,74,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,91,49,59,50,65,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,109,117,108,120,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 // NOLINT
+};
+
+// cygwin|ANSI emulation for Cygwin,
+// auto_right_margin,
+// has_status_line,
+// move_insert_mode,
+// move_standout_mode,
+// xon_xoff,
+// init_tabs#8,
+// max_colors#8,
+// max_pairs#64,
+// acs_chars=+^P\054^Q-^X.^Y0\333`^Da\261f\370g\361h\260j\331k\277l\332m\300n\305o~p\304q\304r\304s_t\303u\264v\301w\302x\263y\363z\362{\343|\330}\234~\376,
+// bell=^G,
+// carriage_return=\r,
+// clear_screen=\E[H\E[J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\E[B,
+// cursor_home=\E[H,
+// cursor_left=^H,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// enter_alt_charset_mode=\E[11m,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E7\E[?47h,
+// enter_insert_mode=\E[4h,
+// enter_pc_charset_mode=\E[11m,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode=\E[8m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// exit_alt_charset_mode=\E[10m,
+// exit_attribute_mode=\E[0;10m,
+// exit_ca_mode=\E[2J\E[?47l\E8,
+// exit_insert_mode=\E[4l,
+// exit_pc_charset_mode=\E[10m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// from_status_line=^G,
+// insert_character=\E[@,
+// insert_line=\E[L,
+// key_b2=\E[G,
+// key_backspace=^H,
+// key_dc=\E[3~,
+// key_down=\E[B,
+// key_end=\E[4~,
+// key_f1=\E[[A,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[25~,
+// key_f14=\E[26~,
+// key_f15=\E[28~,
+// key_f16=\E[29~,
+// key_f17=\E[31~,
+// key_f18=\E[32~,
+// key_f19=\E[33~,
+// key_f2=\E[[B,
+// key_f20=\E[34~,
+// key_f3=\E[[C,
+// key_f4=\E[[D,
+// key_f5=\E[[E,
+// key_f6=\E[17~,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_left=\E[D,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\E[C,
+// key_suspend=^Z,
+// key_up=\E[A,
+// newline=\r\n,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_up_cursor=\E[%p1%dA,
+// reset_1string=\Ec\E]R,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[4%p1%dm,
+// set_a_foreground=\E[3%p1%dm,
+// set_attributes=\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p6%t;1%;%?%p7%t;8%;%?%p9%t;11%;m,
+// tab=^I,
+// to_status_line=\E];,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?6c,
+// user9=\E[c,
+static const int8_t cygwin_terminfo[] = {
+ 26,1,33,0,21,0,15,0,125,1,-108,2,99,121,103,119,105,110,124,65,78,83,73,32,101,109,117,108,97,116,105,111,110,32,102,111,114,32,67,121,103,119,105,110,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,1,-1,-1,8,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,0,64,0,-1,-1,0,0,2,0,-1,-1,-1,-1,4,0,11,0,15,0,19,0,-1,-1,30,0,47,0,51,0,-1,-1,55,0,-1,-1,-1,-1,57,0,-1,-1,61,0,-1,-1,65,0,69,0,-1,-1,-1,-1,73,0,-1,-1,79,0,84,0,-1,-1,-1,-1,93,0,98,0,-1,-1,103,0,108,0,113,0,-1,-1,118,0,124,0,-124,0,-1,-1,-111,0,-106,0,-100,0,-1,-1,-1,-1,-94,0,-1,-1,-1,-1,-1,-1,-1,-1,-92,0,-88,0,-1,-1,-84,0,-1,-1,-1,-1,-1,-1,-82,0,-1,-1,-77,0,-1,-1,-1,-1,-1,-1,-1,-1,-73,0,-68,0,-62,0,-57,0,-52,0,-47,0,-42,0,-36,0,-30,0,-24,0,-18,0,-13,0,-1,-1,-8,0,-1,-1,-4,0,1,1,6,1,-1,-1,-1,-1,-1,-1,10,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,1,-1,-1,17,1,26,1,35,1,44,1,-1,-1,53,1,62,1,71,1,-1,-1,80,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,89,1,-1,-1,-1,-1,-1,-1,95,1,98,1,109,1,112,1,114,1,117,1,-1,-1,-1,-1,-64,1,-62,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-58,1,-1,-1,-1,-1,-1,-1,-1,-1,-54,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,9,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,2,22,2,28,2,34,2,40,2,46,2,52,2,58,2,64,2,70,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,76,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,81,2,92,2,97,2,103,2,107,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,116,2,126,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-120,2,-114,2,7,0,13,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,27,91,66,0,27,91,72,0,8,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,27,91,49,49,109,0,27,91,49,109,0,27,55,27,91,63,52,55,104,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,49,48,109,0,27,91,48,59,49,48,109,0,27,91,50,74,27,91,63,52,55,108,27,56,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,7,0,27,91,64,0,27,91,76,0,8,0,27,91,51,126,0,27,91,66,0,27,91,91,65,0,27,91,50,49,126,0,27,91,91,66,0,27,91,91,67,0,27,91,91,68,0,27,91,91,69,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,91,68,0,27,91,54,126,0,27,91,53,126,0,27,91,67,0,27,91,65,0,13,10,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,99,27,93,82,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,59,49,48,37,63,37,112,49,37,116,59,55,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,51,37,116,59,55,37,59,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,55,37,116,59,56,37,59,37,63,37,112,57,37,116,59,49,49,37,59,109,0,9,0,27,93,59,0,27,91,71,0,43,16,44,17,45,24,46,25,48,-37,96,4,97,-79,102,-8,103,-15,104,-80,106,-39,107,-65,108,-38,109,-64,110,-59,111,126,112,-60,113,-60,114,-60,115,95,116,-61,117,-76,118,-63,119,-62,120,-77,121,-13,122,-14,123,-29,124,-40,125,-100,126,-2,0,27,91,52,126,0,26,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,54,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,91,51,37,112,49,37,100,109,0,27,91,52,37,112,49,37,100,109,0,27,91,49,49,109,0,27,91,49,48,109,0 // NOLINT
+};
+
+// interix|opennt|opennt-25|ntconsole|ntconsole-25|OpenNT-term compatible with color,
+// auto_right_margin,
+// back_color_erase,
+// move_standout_mode,
+// columns#80,
+// init_tabs#8,
+// lines#25,
+// max_colors#8,
+// max_pairs#64,
+// no_color_video#3,
+// acs_chars=+^P\054^Q-^X.^Y0\333`^Da\261f\370g\361h\260j\331k\277l\332m\300n\305o~p\304q\304r\304s_t\303u\264v\301w\302x\263y\363z\362{\343|\330}\234~\376,
+// bell=^G,
+// carriage_return=\r,
+// clear_screen=\E[2J,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_left=\E[D,
+// cursor_right=\E[C,
+// cursor_to_ll=\E[U,
+// cursor_up=\E[A,
+// delete_line=\E[M,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[s\E[1b,
+// enter_reverse_mode=\E[7m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// exit_attribute_mode=\E[0m,
+// exit_ca_mode=\E[2b\E[u\r\E[K,
+// exit_standout_mode=\E[m,
+// exit_underline_mode=\E[m,
+// insert_line=\E[L,
+// key_backspace=^H,
+// key_btab=\E[Z,
+// key_dc=\177,
+// key_down=\E[B,
+// key_end=\E[U,
+// key_f0=\EFA,
+// key_f1=\EF1,
+// key_f10=\EFA,
+// key_f11=\EFB,
+// key_f12=\EFC,
+// key_f13=\EFD,
+// key_f14=\EFE,
+// key_f15=\EFF,
+// key_f16=\EFG,
+// key_f17=\EFH,
+// key_f18=\EFI,
+// key_f19=\EFJ,
+// key_f2=\EF2,
+// key_f20=\EFK,
+// key_f21=\EFL,
+// key_f22=\EFM,
+// key_f23=\EFN,
+// key_f24=\EFO,
+// key_f25=\EFP,
+// key_f26=\EFQ,
+// key_f27=\EFR,
+// key_f28=\EFS,
+// key_f29=\EFT,
+// key_f3=\EF3,
+// key_f30=\EFU,
+// key_f31=\EFV,
+// key_f32=\EFW,
+// key_f33=\EFX,
+// key_f34=\EFY,
+// key_f35=\EFZ,
+// key_f36=\EFa,
+// key_f37=\EFb,
+// key_f38=\EFc,
+// key_f39=\EFd,
+// key_f4=\EF4,
+// key_f40=\EFe,
+// key_f41=\EFf,
+// key_f42=\EFg,
+// key_f43=\EFh,
+// key_f44=\EFi,
+// key_f45=\EFj,
+// key_f46=\EFk,
+// key_f47=\EFm,
+// key_f48=\EFn,
+// key_f49=\EFo,
+// key_f5=\EF5,
+// key_f50=\EFp,
+// key_f51=\EFq,
+// key_f52=\EFr,
+// key_f53=\EFs,
+// key_f54=\EFt,
+// key_f55=\EFu,
+// key_f56=\EFv,
+// key_f57=\EFw,
+// key_f58=\EFx,
+// key_f59=\EFy,
+// key_f6=\EF6,
+// key_f60=\EFz,
+// key_f7=\EF7,
+// key_f8=\EF8,
+// key_f9=\EF9,
+// key_home=\E[H,
+// key_ic=\E[L,
+// key_left=\E[D,
+// key_ll=\E[U,
+// key_npage=\E[T,
+// key_ppage=\E[S,
+// key_right=\E[C,
+// key_sf=\EF+,
+// key_sleft=\EF\136,
+// key_sr=\EF-,
+// key_sright=\EF$,
+// key_up=\E[A,
+// newline=\r\n,
+// orig_pair=\E[m,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_rindex=\E[%p1%dT,
+// parm_up_cursor=\E[%p1%dA,
+// repeat_char=%p1%c\E[%p2%{1}%-%db,
+// reset_1string=\Ec,
+// restore_cursor=\E[u,
+// save_cursor=\E[s,
+// scroll_forward=\E[S,
+// scroll_reverse=\E[T,
+// set_a_background=\E[4%p1%dm,
+// set_a_foreground=\E[3%p1%dm,
+// tab=^I,
+static const int8_t interix_8colour_terminfo[] = {
+ 26,1,82,0,29,0,16,0,105,1,116,2,105,110,116,101,114,105,120,124,111,112,101,110,110,116,124,111,112,101,110,110,116,45,50,53,124,110,116,99,111,110,115,111,108,101,124,110,116,99,111,110,115,111,108,101,45,50,53,124,79,112,101,110,78,84,45,116,101,114,109,32,99,111,109,112,97,116,105,98,108,101,32,119,105,116,104,32,99,111,108,111,114,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,80,0,8,0,25,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,0,64,0,3,0,-1,-1,0,0,2,0,-1,-1,-1,-1,4,0,9,0,13,0,-1,-1,-1,-1,17,0,34,0,36,0,-1,-1,40,0,-1,-1,-1,-1,44,0,48,0,52,0,-1,-1,-1,-1,56,0,-1,-1,-1,-1,-1,-1,-1,-1,60,0,65,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,73,0,78,0,83,0,-1,-1,-1,-1,88,0,93,0,-1,-1,-1,-1,105,0,109,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,113,0,-1,-1,117,0,-1,-1,-1,-1,-1,-1,119,0,-1,-1,121,0,-1,-1,-1,-1,-1,-1,125,0,-127,0,-123,0,-119,0,-115,0,-111,0,-107,0,-103,0,-99,0,-95,0,-91,0,-87,0,-83,0,-1,-1,-79,0,-75,0,-71,0,-67,0,-63,0,-59,0,-55,0,-1,-1,-51,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-47,0,-1,-1,-1,-1,-44,0,-35,0,-1,-1,-26,0,-17,0,-8,0,1,1,10,1,19,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,28,1,48,1,-1,-1,-1,-1,-1,-1,51,1,-1,-1,55,1,59,1,63,1,-1,-1,-1,-1,-1,-1,67,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,69,1,-1,-1,-124,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-120,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-116,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-112,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-108,1,-104,1,-100,1,-96,1,-92,1,-88,1,-84,1,-80,1,-76,1,-72,1,-68,1,-64,1,-60,1,-56,1,-52,1,-48,1,-44,1,-40,1,-36,1,-32,1,-28,1,-24,1,-20,1,-16,1,-12,1,-8,1,-4,1,0,2,4,2,8,2,12,2,16,2,20,2,24,2,28,2,32,2,36,2,40,2,44,2,48,2,52,2,56,2,60,2,64,2,68,2,72,2,76,2,80,2,84,2,88,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,92,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,96,2,106,2,7,0,13,0,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,68,0,27,91,67,0,27,91,85,0,27,91,65,0,27,91,77,0,27,91,49,109,0,27,91,115,27,91,49,98,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,48,109,0,27,91,50,98,27,91,117,13,27,91,75,0,27,91,109,0,27,91,109,0,27,91,76,0,8,0,127,0,27,91,66,0,27,70,65,0,27,70,49,0,27,70,65,0,27,70,50,0,27,70,51,0,27,70,52,0,27,70,53,0,27,70,54,0,27,70,55,0,27,70,56,0,27,70,57,0,27,91,72,0,27,91,76,0,27,91,68,0,27,91,85,0,27,91,84,0,27,91,83,0,27,91,67,0,27,70,43,0,27,70,45,0,27,91,65,0,13,10,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,99,0,27,91,117,0,27,91,115,0,27,91,83,0,27,91,84,0,9,0,43,16,44,17,45,24,46,25,48,-37,96,4,97,-79,102,-8,103,-15,104,-80,106,-39,107,-65,108,-38,109,-64,110,-59,111,126,112,-60,113,-60,114,-60,115,95,116,-61,117,-76,118,-63,119,-62,120,-77,121,-13,122,-14,123,-29,124,-40,125,-100,126,-2,0,27,91,90,0,27,91,85,0,27,70,94,0,27,70,36,0,27,70,66,0,27,70,67,0,27,70,68,0,27,70,69,0,27,70,70,0,27,70,71,0,27,70,72,0,27,70,73,0,27,70,74,0,27,70,75,0,27,70,76,0,27,70,77,0,27,70,78,0,27,70,79,0,27,70,80,0,27,70,81,0,27,70,82,0,27,70,83,0,27,70,84,0,27,70,85,0,27,70,86,0,27,70,87,0,27,70,88,0,27,70,89,0,27,70,90,0,27,70,97,0,27,70,98,0,27,70,99,0,27,70,100,0,27,70,101,0,27,70,102,0,27,70,103,0,27,70,104,0,27,70,105,0,27,70,106,0,27,70,107,0,27,70,109,0,27,70,110,0,27,70,111,0,27,70,112,0,27,70,113,0,27,70,114,0,27,70,115,0,27,70,116,0,27,70,117,0,27,70,118,0,27,70,119,0,27,70,120,0,27,70,121,0,27,70,122,0,27,91,109,0,27,91,51,37,112,49,37,100,109,0,27,91,52,37,112,49,37,100,109,0 // NOLINT
+};
+
+// iTerm2.app|iterm2|terminal emulator for Mac OS X,
+// auto_right_margin,
+// back_color_erase,
+// eat_newline_glitch,
+// has_status_line,
+// move_insert_mode,
+// move_standout_mode,
+// no_pad_char,
+// xon_xoff,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// width_status_line#50,
+// acs_chars=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// dis_status_line=\E]2;^G,
+// ena_acs=\E(B\E)0,
+// enter_alt_charset_mode=^N,
+// enter_am_mode=\E[?7h,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[?1049h\E[22;0;0t,
+// enter_dim_mode=\E[2m,
+// enter_insert_mode=\E[4h,
+// enter_italics_mode=\E[3m,
+// enter_reverse_mode=\E[7m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// exit_alt_charset_mode=^O,
+// exit_am_mode=\E[?7l,
+// exit_attribute_mode=\E[m^O,
+// exit_ca_mode=\E[?1049l\E[23;0;0t,
+// exit_insert_mode=\E[4l,
+// exit_italics_mode=\E[23m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\E[?5h$<200/>\E[?5l,
+// from_status_line=^G,
+// insert_character=\E[@,
+// insert_line=\E[L,
+// key_a1@,
+// key_a3@,
+// key_b2@,
+// key_backspace=\177,
+// key_btab=\E[Z,
+// key_c1@,
+// key_c3@,
+// key_dc=\E[3~,
+// key_down=\EOB,
+// key_end=\EOF,
+// key_enter@,
+// key_f1=\EOP,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[1;2P,
+// key_f14=\E[1;2Q,
+// key_f15=\E[1;2R,
+// key_f16=\E[1;2S,
+// key_f17=\E[15;2~,
+// key_f18=\E[17;2~,
+// key_f19=\E[18;2~,
+// key_f2=\EOQ,
+// key_f20=\E[19;2~,
+// key_f21=\E[20;2~,
+// key_f22=\E[21;2~,
+// key_f23=\E[23;2~,
+// key_f24=\E[24;2~,
+// key_f3=\EOR,
+// key_f4=\EOS,
+// key_f5=\E[15~,
+// key_f6=\E[17~,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\EOH,
+// key_left=\EOD,
+// key_mouse=\E[M,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\EOC,
+// key_send=\E[1;2F,
+// key_sf=\E[1;2B,
+// key_shome=\E[1;2H,
+// key_sleft=\E[1;2D,
+// key_sr=\E[1;2A,
+// key_sright=\E[1;2C,
+// key_up=\EOA,
+// keypad_local=\E[?1l\E>,
+// keypad_xmit=\E[?1h\E=,
+// newline=\EE,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_rindex=\E[%p1%dT,
+// parm_up_cursor=\E[%p1%dA,
+// reset_2string=\E[\041p\E[?3;4l\E[4l\E>\E[?1000l,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p5%t;2%;m%?%p9%t^N%e^O%;,
+// set_tab=\EH,
+// tab=^I,
+// to_status_line=\E]2;,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?%[;0123456789]c,
+// user9=\E[c,
+static const int8_t iterm_256colour_terminfo[] = {
+ 30,2,49,0,29,0,15,0,105,1,-29,3,105,84,101,114,109,50,46,97,112,112,124,105,116,101,114,109,50,124,116,101,114,109,105,110,97,108,32,101,109,117,108,97,116,111,114,32,102,111,114,32,77,97,99,32,79,83,32,88,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,1,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,50,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,37,0,41,0,45,0,-1,-1,56,0,73,0,75,0,79,0,86,0,-1,-1,88,0,95,0,-1,-1,99,0,-1,-1,103,0,107,0,111,0,-1,-1,117,0,119,0,124,0,-127,0,-1,-1,-109,0,-104,0,-1,-1,-1,-1,-99,0,-94,0,-89,0,-1,-1,-84,0,-82,0,-77,0,-1,-1,-59,0,-54,0,-48,0,-42,0,-1,-1,-24,0,-1,-1,-1,-1,-1,-1,-1,-1,-22,0,-18,0,-1,-1,-14,0,-1,-1,-1,-1,-1,-1,-12,0,-1,-1,-7,0,-1,-1,-1,-1,-1,-1,-1,-1,-3,0,1,1,7,1,11,1,15,1,19,1,25,1,31,1,37,1,43,1,49,1,-1,-1,-1,-1,53,1,-1,-1,57,1,62,1,67,1,71,1,78,1,-1,-1,85,1,89,1,97,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,105,1,-1,-1,108,1,117,1,126,1,-121,1,-112,1,-103,1,-94,1,-85,1,-76,1,-67,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-58,1,-1,-1,-1,-1,-32,1,-29,1,-18,1,-15,1,-13,1,-10,1,68,2,-1,-1,71,2,73,2,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-1,-1,-1,-1,78,2,-1,-1,-127,2,-1,-1,-1,-1,-123,2,-117,2,-1,-1,-1,-1,-111,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-104,2,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-100,2,-1,-1,-1,-1,-1,-1,-1,-1,-93,2,-1,-1,-86,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-79,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-72,2,-66,2,-60,2,-53,2,-46,2,-39,2,-32,2,-24,2,-16,2,-8,2,0,3,8,3,16,3,24,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,32,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,37,3,48,3,53,3,72,3,76,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,85,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,90,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,96,3,-1,-1,-1,-1,-1,-1,100,3,-93,3,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,27,93,50,59,7,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,27,91,50,50,59,48,59,48,116,0,27,91,50,109,0,27,91,52,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,15,0,27,91,109,15,0,27,91,63,49,48,52,57,108,27,91,50,51,59,48,59,48,116,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,50,48,48,47,62,27,91,63,53,108,0,7,0,27,91,64,0,27,91,76,0,127,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,79,72,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,69,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,27,91,63,49,48,48,48,108,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,93,50,59,0,96,96,97,97,102,102,103,103,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,40,66,27,41,48,0,27,79,70,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,49,59,50,68,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,91,51,109,0,27,91,50,51,109,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,0,1,0,0,0,33,0,67,0,-37,1,0,0,0,0,5,0,32,0,37,0,45,0,52,0,59,0,66,0,74,0,81,0,88,0,96,0,104,0,111,0,119,0,126,0,-123,0,-115,0,-107,0,-102,0,-94,0,-87,0,-80,0,-74,0,-68,0,-63,0,-55,0,-48,0,-41,0,-36,0,-28,0,-21,0,-14,0,0,0,3,0,6,0,9,0,14,0,19,0,24,0,29,0,35,0,41,0,47,0,53,0,59,0,65,0,71,0,77,0,83,0,89,0,95,0,101,0,107,0,113,0,119,0,125,0,-125,0,-119,0,-113,0,-107,0,-101,0,-95,0,-90,0,-85,0,-80,0,-75,0,27,93,50,59,0,27,91,63,49,48,48,48,37,63,37,112,49,37,123,49,125,37,61,37,116,104,37,101,108,37,59,0,27,27,91,66,0,27,91,49,59,49,48,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,57,70,0,27,91,49,59,49,48,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,49,51,70,0,27,91,49,59,49,52,70,0,27,91,49,59,57,72,0,27,91,49,59,49,48,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,49,51,72,0,27,91,49,59,49,52,72,0,27,27,91,68,0,27,91,49,59,49,48,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,27,91,54,126,0,27,27,91,53,126,0,27,27,91,67,0,27,91,49,59,49,48,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,27,91,65,0,27,91,49,59,49,48,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,77,37,63,37,112,52,37,116,51,37,101,37,112,51,37,39,32,39,37,43,37,99,37,59,37,112,50,37,39,33,39,37,43,37,99,37,112,49,37,39,33,39,37,43,37,99,0,65,88,0,84,83,0,88,77,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,78,88,84,51,0,107,80,82,86,51,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,120,109,0 // NOLINT
+};
+
+// linux|linux console,
+// auto_right_margin,
+// back_color_erase,
+// can_change,
+// eat_newline_glitch,
+// erase_overstrike,
+// move_insert_mode,
+// move_standout_mode,
+// xon_xoff,
+// init_tabs#8,
+// max_colors#8,
+// max_pairs#64,
+// no_color_video#18,
+// acs_chars=++\054\054--..00__``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}c~~,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l\E[?1c,
+// cursor_left=^H,
+// cursor_normal=\E[?25h\E[?0c,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// cursor_visible=\E[?25h\E[?8c,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// ena_acs=\E)0,
+// enter_alt_charset_mode=^N,
+// enter_am_mode=\E[?7h,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_dim_mode=\E[2m,
+// enter_insert_mode=\E[4h,
+// enter_pc_charset_mode=\E[11m,
+// enter_reverse_mode=\E[7m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// erase_chars=\E[%p1%dX,
+// exit_alt_charset_mode=^O,
+// exit_am_mode=\E[?7l,
+// exit_attribute_mode=\E[m^O,
+// exit_insert_mode=\E[4l,
+// exit_pc_charset_mode=\E[10m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\E[?5h$<200/>\E[?5l,
+// initialize_color=\E]P%p1%x%p2%{255}%*%{1000}%/%02x%p3%{255}%*%{1000}%/%02x%p4%{255}%*%{1000}%/%02x,
+// insert_character=\E[@,
+// insert_line=\E[L,
+// key_b2=\E[G,
+// key_backspace=\177,
+// key_btab=\E[Z,
+// key_dc=\E[3~,
+// key_down=\E[B,
+// key_end=\E[4~,
+// key_f1=\E[[A,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[25~,
+// key_f14=\E[26~,
+// key_f15=\E[28~,
+// key_f16=\E[29~,
+// key_f17=\E[31~,
+// key_f18=\E[32~,
+// key_f19=\E[33~,
+// key_f2=\E[[B,
+// key_f20=\E[34~,
+// key_f3=\E[[C,
+// key_f4=\E[[D,
+// key_f5=\E[[E,
+// key_f6=\E[17~,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_left=\E[D,
+// key_mouse=\E[M,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\E[C,
+// key_suspend=^Z,
+// key_up=\E[A,
+// newline=\r\n,
+// orig_colors=\E]R,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_up_cursor=\E[%p1%dA,
+// reset_1string=\Ec\E]R,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[4%p1%dm,
+// set_a_foreground=\E[3%p1%dm,
+// set_attributes=\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p6%t;1%;m%?%p9%t^N%e^O%;,
+// set_tab=\EH,
+// tab=^I,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?6c,
+// user9=\E[c,
+static const int8_t linux_16colour_terminfo[] = {
+ 26,1,20,0,29,0,16,0,125,1,69,3,108,105,110,117,120,124,108,105,110,117,120,32,99,111,110,115,111,108,101,0,0,1,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,-1,-1,8,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,0,64,0,18,0,-1,-1,0,0,2,0,4,0,21,0,26,0,33,0,37,0,41,0,-1,-1,52,0,69,0,71,0,75,0,87,0,-1,-1,89,0,101,0,-1,-1,105,0,109,0,121,0,125,0,-1,-1,-1,-1,-127,0,-125,0,-120,0,-1,-1,-1,-1,-115,0,-110,0,-1,-1,-1,-1,-105,0,-100,0,-95,0,-90,0,-81,0,-79,0,-1,-1,-1,-1,-74,0,-69,0,-63,0,-57,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-39,0,-35,0,-1,-1,-31,0,-1,-1,-1,-1,-1,-1,-29,0,-1,-1,-24,0,-1,-1,-1,-1,-1,-1,-1,-1,-20,0,-15,0,-9,0,-4,0,1,1,6,1,11,1,17,1,23,1,29,1,35,1,40,1,-1,-1,45,1,-1,-1,49,1,54,1,59,1,-1,-1,-1,-1,-1,-1,63,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,67,1,-1,-1,70,1,79,1,88,1,97,1,-1,-1,106,1,115,1,124,1,-1,-1,-123,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-114,1,-1,-1,-1,-1,-1,-1,-108,1,-105,1,-94,1,-91,1,-89,1,-86,1,1,2,-1,-1,4,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,6,2,-1,-1,-1,-1,-1,-1,-1,-1,10,2,-1,-1,77,2,-1,-1,-1,-1,81,2,87,2,-1,-1,-1,-1,93,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,97,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,102,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,104,2,110,2,116,2,122,2,-128,2,-122,2,-116,2,-110,2,-104,2,-98,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-92,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-87,2,-76,2,-71,2,-65,2,-61,2,-52,2,-48,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,33,3,-1,-1,-1,-1,-1,-1,37,3,47,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,57,3,63,3,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,27,91,63,49,99,0,8,0,27,91,63,50,53,104,27,91,63,48,99,0,27,91,67,0,27,91,65,0,27,91,63,50,53,104,27,91,63,56,99,0,27,91,80,0,27,91,77,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,50,109,0,27,91,52,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,15,0,27,91,109,15,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,50,48,48,47,62,27,91,63,53,108,0,27,91,64,0,27,91,76,0,127,0,27,91,51,126,0,27,91,66,0,27,91,91,65,0,27,91,50,49,126,0,27,91,91,66,0,27,91,91,67,0,27,91,91,68,0,27,91,91,69,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,91,68,0,27,91,54,126,0,27,91,53,126,0,27,91,67,0,27,91,65,0,13,10,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,99,27,93,82,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,59,49,48,37,63,37,112,49,37,116,59,55,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,51,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,54,37,116,59,49,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,91,71,0,43,43,44,44,45,45,46,46,48,48,95,95,96,96,97,97,102,102,103,103,104,104,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,99,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,41,48,0,27,91,52,126,0,26,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,54,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,82,0,27,93,80,37,112,49,37,120,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,48,50,120,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,48,50,120,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,48,50,120,0,27,91,77,0,27,91,51,37,112,49,37,100,109,0,27,91,52,37,112,49,37,100,109,0,27,91,49,49,109,0,27,91,49,48,109,0,0,3,0,1,0,12,0,28,0,63,0,1,0,0,0,1,0,-1,-1,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,33,0,39,0,43,0,47,0,51,0,55,0,27,91,51,74,0,65,88,0,71,48,0,88,84,0,85,56,0,69,48,0,69,51,0,83,48,0,84,83,0,88,77,0,107,69,78,68,53,0,107,72,79,77,53,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,120,109,0 // NOLINT
+};
+
+// putty-256color|PuTTY 0.58 with xterm 256-colors,
+// auto_left_margin,
+// auto_right_margin,
+// back_color_erase,
+// eat_newline_glitch,
+// has_status_line,
+// move_insert_mode,
+// move_standout_mode,
+// xon_xoff,
+// init_tabs#8,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// no_color_video#22,
+// acs_chars=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\ED,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\EM,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// dis_status_line=\E]0;^G,
+// display_pc_char=%?%p1%{8}%=%t\E%%G\342\227\230\E%%@%e%p1%{10}%=%t\E%%G\342\227\231\E%%@%e%p1%{12}%=%t\E%%G\342\231\0\E%%@%e%p1%{13}%=%t\E%%G\342\231\252\E%%@%e%p1%{14}%=%t\E%%G\342\231\253\E%%@%e%p1%{15}%=%t\E%%G\342\230\274\E%%@%e%p1%{27}%=%t\E%%G\342\206\220\E%%@%e%p1%{155}%=%t\E%%G\340\202\242\E%%@%e%p1%c%;,
+// ena_acs=\E(B\E)0,
+// enter_alt_charset_mode=^N,
+// enter_am_mode=\E[?7h,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[?47h,
+// enter_insert_mode=\E[4h,
+// enter_pc_charset_mode=\E[11m,
+// enter_reverse_mode=\E[7m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// erase_chars=\E[%p1%dX,
+// exit_alt_charset_mode=^O,
+// exit_am_mode=\E[?7l,
+// exit_attribute_mode=\E[m^O,
+// exit_ca_mode=\E[2J\E[?47l,
+// exit_insert_mode=\E[4l,
+// exit_pc_charset_mode=\E[10m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\E[?5h$<100/>\E[?5l,
+// from_status_line=^G,
+// init_2string=\E7\E[r\E[m\E[?7h\E[?1;4;6l\E[4l\E8\E>\E]R,
+// insert_line=\E[L,
+// key_b2=\E[G,
+// key_backspace=\177,
+// key_btab=\E[Z,
+// key_dc=\E[3~,
+// key_down=\EOB,
+// key_end=\E[4~,
+// key_f1=\E[11~,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[25~,
+// key_f14=\E[26~,
+// key_f15=\E[28~,
+// key_f16=\E[29~,
+// key_f17=\E[31~,
+// key_f18=\E[32~,
+// key_f19=\E[33~,
+// key_f2=\E[12~,
+// key_f20=\E[34~,
+// key_f3=\E[13~,
+// key_f4=\E[14~,
+// key_f5=\E[15~,
+// key_f6=\E[17~,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_left=\EOD,
+// key_mouse=\E[M,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\EOC,
+// key_sf=\E[B,
+// key_sleft=\E[D,
+// key_sr=\E[A,
+// key_sright=\E[C,
+// key_suspend=^Z,
+// key_up=\EOA,
+// keypad_local=\E[?1l\E>,
+// keypad_xmit=\E[?1h\E=,
+// newline=\r\n,
+// orig_colors=\E]R,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_rindex=\E[%p1%dT,
+// parm_up_cursor=\E[%p1%dA,
+// reset_2string=\E<\E["p\E[50;6"p\Ec\E[?3l\E]R\E[?1000l,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set0_des_seq=\E[10m,
+// set1_des_seq=\E[11m,
+// set2_des_seq=\E[12m,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t^N%e^O%;,
+// set_tab=\EH,
+// tab=^I,
+// to_status_line=\E]0;,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?6c,
+// user9=\E[c,
+static const int8_t putty_256colour_terminfo[] = {
+ 30,2,48,0,29,0,16,0,125,1,-106,4,112,117,116,116,121,45,50,53,54,99,111,108,111,114,124,80,117,84,84,89,32,48,46,53,56,32,119,105,116,104,32,120,116,101,114,109,32,50,53,54,45,99,111,108,111,114,115,0,1,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,-1,-1,-1,-1,8,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,22,0,0,0,0,0,4,0,6,0,8,0,25,0,30,0,37,0,41,0,45,0,-1,-1,56,0,73,0,76,0,80,0,87,0,-1,-1,89,0,96,0,-1,-1,100,0,-1,-1,103,0,107,0,111,0,-1,-1,117,0,119,0,124,0,-127,0,-1,-1,-1,-1,-120,0,-1,-1,-1,-1,-115,0,-110,0,-105,0,-100,0,-91,0,-89,0,-84,0,-1,-1,-73,0,-68,0,-62,0,-56,0,-1,-1,-38,0,-1,-1,-36,0,-1,-1,-1,-1,-1,-1,-2,0,-1,-1,2,1,-1,-1,-1,-1,-1,-1,4,1,-1,-1,9,1,-1,-1,-1,-1,-1,-1,-1,-1,13,1,19,1,25,1,31,1,37,1,43,1,49,1,55,1,61,1,67,1,73,1,78,1,-1,-1,83,1,-1,-1,87,1,92,1,97,1,101,1,105,1,-1,-1,109,1,113,1,121,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-127,1,-1,-1,-124,1,-115,1,-106,1,-1,-1,-97,1,-88,1,-79,1,-70,1,-61,1,-52,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-43,1,-1,-1,-1,-1,-10,1,-7,1,4,2,7,2,9,2,12,2,84,2,-1,-1,87,2,89,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,94,2,-1,-1,-1,-1,-1,-1,-1,-1,98,2,-1,-1,-107,2,-1,-1,-1,-1,-103,2,-97,2,-1,-1,-1,-1,-91,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-84,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-79,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-77,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-73,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-69,2,-63,2,-57,2,-51,2,-45,2,-39,2,-33,2,-27,2,-21,2,-15,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-9,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-4,2,7,3,12,3,18,3,22,3,31,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,35,3,-1,-1,-1,-1,-1,-1,39,3,102,3,-1,-1,-1,-1,-1,-1,-90,3,-84,3,-78,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-72,3,-118,4,-112,4,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,27,68,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,77,0,27,91,80,0,27,91,77,0,27,93,48,59,7,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,63,52,55,104,0,27,91,52,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,15,0,27,91,109,15,0,27,91,50,74,27,91,63,52,55,108,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,7,0,27,55,27,91,114,27,91,109,27,91,63,55,104,27,91,63,49,59,52,59,54,108,27,91,52,108,27,56,27,62,27,93,82,0,27,91,76,0,127,0,27,91,51,126,0,27,79,66,0,27,91,49,49,126,0,27,91,50,49,126,0,27,91,49,50,126,0,27,91,49,51,126,0,27,91,49,52,126,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,66,0,27,91,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,13,10,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,60,27,91,34,112,27,91,53,48,59,54,34,112,27,99,27,91,63,51,108,27,93,82,27,91,63,49,48,48,48,108,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,49,37,112,54,37,124,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,93,48,59,0,27,91,71,0,96,96,97,97,102,102,103,103,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,40,66,27,41,48,0,27,91,52,126,0,26,0,27,91,68,0,27,91,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,54,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,82,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,49,48,109,0,27,91,49,49,109,0,27,91,49,50,109,0,37,63,37,112,49,37,123,56,125,37,61,37,116,27,37,37,71,-30,-105,-104,27,37,37,64,37,101,37,112,49,37,123,49,48,125,37,61,37,116,27,37,37,71,-30,-105,-103,27,37,37,64,37,101,37,112,49,37,123,49,50,125,37,61,37,116,27,37,37,71,-30,-103,-128,27,37,37,64,37,101,37,112,49,37,123,49,51,125,37,61,37,116,27,37,37,71,-30,-103,-86,27,37,37,64,37,101,37,112,49,37,123,49,52,125,37,61,37,116,27,37,37,71,-30,-103,-85,27,37,37,64,37,101,37,112,49,37,123,49,53,125,37,61,37,116,27,37,37,71,-30,-104,-68,27,37,37,64,37,101,37,112,49,37,123,50,55,125,37,61,37,116,27,37,37,71,-30,-122,-112,27,37,37,64,37,101,37,112,49,37,123,49,53,53,125,37,61,37,116,27,37,37,71,-32,-126,-94,27,37,37,64,37,101,37,112,49,37,99,37,59,0,27,91,49,49,109,0,27,91,49,48,109,0,3,0,1,0,60,0,124,0,74,1,0,0,1,0,1,0,0,0,-1,-1,0,0,-1,-1,-1,-1,-1,-1,5,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,39,0,45,0,50,0,55,0,60,0,65,0,70,0,74,0,79,0,84,0,89,0,94,0,99,0,105,0,111,0,117,0,123,0,-127,0,-121,0,-115,0,-109,0,-103,0,-97,0,-91,0,-85,0,-80,0,-75,0,-69,0,-63,0,-57,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,25,1,30,1,35,1,40,1,45,1,49,1,53,1,57,1,61,1,27,91,51,74,0,27,93,48,59,0,65,88,0,71,48,0,88,84,0,85,56,0,69,48,0,69,51,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,53,0,107,73,67,54,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,53,0,107,78,88,84,54,0,107,80,82,86,51,0,107,80,82,86,53,0,107,80,82,86,54,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,120,109,0 // NOLINT
+};
+
+// rxvt-256color|rxvt 2.7.9 with xterm 256-colors,
+// auto_right_margin,
+// back_color_erase,
+// backspaces_with_bs,
+// can_change,
+// eat_newline_glitch,
+// erase_overstrike,
+// move_insert_mode,
+// move_standout_mode,
+// xon_xoff,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// acs_chars=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[2J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// delete_line=\E[M,
+// ena_acs=\E(B\E)0,
+// enter_alt_charset_mode=^N,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E7\E[?47h,
+// enter_insert_mode=\E[4h,
+// enter_reverse_mode=\E[7m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// exit_alt_charset_mode=^O,
+// exit_attribute_mode=\E[m^O,
+// exit_ca_mode=\E[2J\E[?47l\E8,
+// exit_insert_mode=\E[4l,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\E[?5h$<100/>\E[?5l,
+// init_1string=\E[?47l\E=\E[?1l,
+// init_2string=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l,
+// initialize_color=\E]4;%p1%d;rgb\072%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\,
+// insert_character=\E[@,
+// insert_line=\E[L,
+// key_a1=\EOw,
+// key_a3=\EOy,
+// key_b2=\EOu,
+// key_backspace=^H,
+// key_btab=\E[Z,
+// key_c1=\EOq,
+// key_c3=\EOs,
+// key_dc=\E[3~,
+// key_down=\E[B,
+// key_end=\E[8~,
+// key_enter=\EOM,
+// key_eol=\E[8\136,
+// key_f0=\E[21~,
+// key_f1=\E[11~,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[25~,
+// key_f14=\E[26~,
+// key_f15=\E[28~,
+// key_f16=\E[29~,
+// key_f17=\E[31~,
+// key_f18=\E[32~,
+// key_f19=\E[33~,
+// key_f2=\E[12~,
+// key_f20=\E[34~,
+// key_f21=\E[23$,
+// key_f22=\E[24$,
+// key_f23=\E[11\136,
+// key_f24=\E[12\136,
+// key_f25=\E[13\136,
+// key_f26=\E[14\136,
+// key_f27=\E[15\136,
+// key_f28=\E[17\136,
+// key_f29=\E[18\136,
+// key_f3=\E[13~,
+// key_f30=\E[19\136,
+// key_f31=\E[20\136,
+// key_f32=\E[21\136,
+// key_f33=\E[23\136,
+// key_f34=\E[24\136,
+// key_f35=\E[25\136,
+// key_f36=\E[26\136,
+// key_f37=\E[28\136,
+// key_f38=\E[29\136,
+// key_f39=\E[31\136,
+// key_f4=\E[14~,
+// key_f40=\E[32\136,
+// key_f41=\E[33\136,
+// key_f42=\E[34\136,
+// key_f43=\E[23@,
+// key_f44=\E[24@,
+// key_f5=\E[15~,
+// key_f6=\E[17~,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_find=\E[1~,
+// key_home=\E[7~,
+// key_ic=\E[2~,
+// key_left=\E[D,
+// key_mouse=\E[M,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\E[C,
+// key_sdc=\E[3$,
+// key_select=\E[4~,
+// key_send=\E[8$,
+// key_sf=\E[a,
+// key_shome=\E[7$,
+// key_sic=\E[2$,
+// key_sleft=\E[d,
+// key_snext=\E[6$,
+// key_sprevious=\E[5$,
+// key_sr=\E[b,
+// key_sright=\E[c,
+// key_up=\E[A,
+// keypad_local=\E>,
+// keypad_xmit=\E=,
+// orig_colors=\E]104^G,
+// orig_pair=\E[39;49m,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_up_cursor=\E[%p1%dA,
+// reset_1string=\E>\E[1;3;4;5;6l\E[?7h\E[m\E[r\E[2J\E[H,
+// reset_2string=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l\E>\E[?1000l\E[?25h,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set0_des_seq=\E(B,
+// set1_des_seq=\E(0,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t^N%e^O%;,
+// set_tab=\EH,
+// tab=^I,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?1;2c,
+// user9=\E[c,
+static const int8_t rxvt_256colour_terminfo[] = {
+ 30,2,47,0,38,0,15,0,110,1,-31,4,114,120,118,116,45,50,53,54,99,111,108,111,114,124,114,120,118,116,32,50,46,55,46,57,32,119,105,116,104,32,120,116,101,114,109,32,50,53,54,45,99,111,108,111,114,115,0,0,1,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,-1,-1,0,0,2,0,4,0,21,0,26,0,34,0,38,0,42,0,-1,-1,53,0,70,0,72,0,76,0,83,0,-1,-1,85,0,92,0,-1,-1,96,0,-1,-1,-1,-1,100,0,-1,-1,-1,-1,104,0,106,0,111,0,116,0,-1,-1,-1,-1,125,0,-1,-1,-1,-1,-126,0,-121,0,-116,0,-1,-1,-111,0,-109,0,-104,0,-1,-1,-91,0,-86,0,-80,0,-74,0,-1,-1,-1,-1,-56,0,-42,0,-1,-1,-1,-1,-8,0,-4,0,-1,-1,0,1,-1,-1,-1,-1,-1,-1,2,1,-1,-1,7,1,-1,-1,11,1,-1,-1,16,1,22,1,28,1,34,1,40,1,46,1,52,1,58,1,64,1,70,1,76,1,82,1,87,1,-1,-1,92,1,-1,-1,96,1,101,1,106,1,110,1,114,1,-1,-1,118,1,122,1,125,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-128,1,-119,1,-110,1,-1,-1,-101,1,-92,1,-83,1,-1,-1,-74,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-65,1,-32,1,-1,-1,-1,-1,18,2,21,2,32,2,35,2,37,2,40,2,107,2,-1,-1,110,2,-1,-1,-1,-1,-1,-1,-1,-1,112,2,116,2,120,2,124,2,-128,2,-1,-1,-1,-1,-124,2,-1,-1,-73,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-69,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-62,2,-57,2,-1,-1,-53,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-48,2,-1,-1,-43,2,-38,2,-1,-1,-1,-1,-1,-1,-1,-1,-33,2,-28,2,-23,2,-1,-1,-1,-1,-19,2,-1,-1,-14,2,-1,-1,-1,-1,-1,-1,-9,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-5,2,1,3,7,3,13,3,19,3,25,3,31,3,37,3,43,3,49,3,55,3,61,3,67,3,73,3,79,3,85,3,91,3,97,3,103,3,109,3,115,3,121,3,127,3,-123,3,-117,3,-111,3,-105,3,-99,3,-93,3,-87,3,-81,3,-75,3,-69,3,-63,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-57,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-52,3,-41,3,-36,3,-28,3,-24,3,-15,3,-8,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,86,4,-1,-1,-1,-1,-1,-1,90,4,-103,4,-1,-1,-1,-1,-1,-1,-39,4,-35,4,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,77,0,14,0,27,91,53,109,0,27,91,49,109,0,27,55,27,91,63,52,55,104,0,27,91,52,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,15,0,27,91,109,15,0,27,91,50,74,27,91,63,52,55,108,27,56,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,27,91,63,52,55,108,27,61,27,91,63,49,108,0,27,91,114,27,91,109,27,91,50,74,27,91,72,27,91,63,55,104,27,91,63,49,59,51,59,52,59,54,108,27,91,52,108,0,27,91,64,0,27,91,76,0,8,0,27,91,51,126,0,27,91,66,0,27,91,56,94,0,27,91,50,49,126,0,27,91,49,49,126,0,27,91,50,49,126,0,27,91,49,50,126,0,27,91,49,51,126,0,27,91,49,52,126,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,55,126,0,27,91,50,126,0,27,91,68,0,27,91,54,126,0,27,91,53,126,0,27,91,67,0,27,91,97,0,27,91,98,0,27,91,65,0,27,62,0,27,61,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,62,27,91,49,59,51,59,52,59,53,59,54,108,27,91,63,55,104,27,91,109,27,91,114,27,91,50,74,27,91,72,0,27,91,114,27,91,109,27,91,50,74,27,91,72,27,91,63,55,104,27,91,63,49,59,51,59,52,59,54,108,27,91,52,108,27,62,27,91,63,49,48,48,48,108,27,91,63,50,53,104,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,79,119,0,27,79,121,0,27,79,117,0,27,79,113,0,27,79,115,0,96,96,97,97,102,102,103,103,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,40,66,27,41,48,0,27,91,56,126,0,27,79,77,0,27,91,49,126,0,27,91,51,36,0,27,91,52,126,0,27,91,56,36,0,27,91,55,36,0,27,91,50,36,0,27,91,100,0,27,91,54,36,0,27,91,53,36,0,27,91,99,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,50,51,36,0,27,91,50,52,36,0,27,91,49,49,94,0,27,91,49,50,94,0,27,91,49,51,94,0,27,91,49,52,94,0,27,91,49,53,94,0,27,91,49,55,94,0,27,91,49,56,94,0,27,91,49,57,94,0,27,91,50,48,94,0,27,91,50,49,94,0,27,91,50,51,94,0,27,91,50,52,94,0,27,91,50,53,94,0,27,91,50,54,94,0,27,91,50,56,94,0,27,91,50,57,94,0,27,91,51,49,94,0,27,91,51,50,94,0,27,91,51,51,94,0,27,91,51,52,94,0,27,91,50,51,64,0,27,91,50,52,64,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,49,59,50,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,49,48,52,7,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,92,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,40,66,0,27,40,48,0,0,2,0,0,0,25,0,52,0,-27,0,1,1,-1,-1,-1,-1,0,0,5,0,10,0,14,0,18,0,23,0,28,0,33,0,38,0,43,0,48,0,52,0,57,0,62,0,67,0,72,0,76,0,80,0,84,0,88,0,92,0,96,0,-1,-1,0,0,3,0,6,0,9,0,12,0,17,0,22,0,26,0,31,0,37,0,43,0,49,0,55,0,60,0,65,0,71,0,77,0,83,0,89,0,95,0,101,0,105,0,110,0,114,0,118,0,122,0,126,0,27,91,51,94,0,27,91,51,64,0,27,91,98,0,27,79,98,0,27,91,56,94,0,27,91,56,64,0,27,91,55,94,0,27,91,55,64,0,27,91,50,94,0,27,91,50,64,0,27,79,100,0,27,91,54,94,0,27,91,54,64,0,27,91,53,94,0,27,91,53,64,0,27,79,99,0,27,91,97,0,27,79,97,0,27,79,120,0,27,79,116,0,27,79,118,0,27,79,114,0,65,88,0,88,84,0,84,83,0,88,77,0,107,68,67,53,0,107,68,67,54,0,107,68,78,0,107,68,78,53,0,107,69,78,68,53,0,107,69,78,68,54,0,107,72,79,77,53,0,107,72,79,77,54,0,107,73,67,53,0,107,73,67,54,0,107,76,70,84,53,0,107,78,88,84,53,0,107,78,88,84,54,0,107,80,82,86,53,0,107,80,82,86,54,0,107,82,73,84,53,0,107,85,80,0,107,85,80,53,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,120,109,0 // NOLINT
+};
+
+// screen-256color|GNU Screen with 256 colors,
+// auto_right_margin,
+// backspaces_with_bs,
+// eat_newline_glitch,
+// has_hardware_tabs,
+// has_meta_key,
+// move_insert_mode,
+// move_standout_mode,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// acs_chars=++\054\054--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[34h\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\EM,
+// cursor_visible=\E[34l,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// ena_acs=\E(B\E)0,
+// enter_alt_charset_mode=^N,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[?1049h,
+// enter_dim_mode=\E[2m,
+// enter_insert_mode=\E[4h,
+// enter_reverse_mode=\E[7m,
+// enter_standout_mode=\E[3m,
+// enter_underline_mode=\E[4m,
+// exit_alt_charset_mode=^O,
+// exit_attribute_mode=\E[m^O,
+// exit_ca_mode=\E[?1049l,
+// exit_insert_mode=\E[4l,
+// exit_standout_mode=\E[23m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\Eg,
+// init_2string=\E)0,
+// insert_line=\E[L,
+// key_backspace=^H,
+// key_btab=\E[Z,
+// key_dc=\E[3~,
+// key_down=\EOB,
+// key_end=\E[4~,
+// key_f1=\EOP,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f2=\EOQ,
+// key_f3=\EOR,
+// key_f4=\EOS,
+// key_f5=\E[15~,
+// key_f6=\E[17~,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_left=\EOD,
+// key_mouse=\E[M,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\EOC,
+// key_up=\EOA,
+// keypad_local=\E[?1l\E>,
+// keypad_xmit=\E[?1h\E=,
+// newline=\EE,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_up_cursor=\E[%p1%dA,
+// reset_2string=\Ec\E[?1000l\E[?25h,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=\E[0%?%p6%t;1%;%?%p1%t;3%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;m%?%p9%t^N%e^O%;,
+// set_tab=\EH,
+// tab=^I,
+static const int8_t screen_256colour_terminfo[] = {
+ 30,2,43,0,43,0,15,0,105,1,4,3,115,99,114,101,101,110,45,50,53,54,99,111,108,111,114,124,71,78,85,32,83,99,114,101,101,110,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,37,0,41,0,45,0,-1,-1,56,0,73,0,75,0,79,0,86,0,-1,-1,88,0,100,0,-1,-1,104,0,107,0,113,0,117,0,-1,-1,-1,-1,121,0,123,0,-128,0,-123,0,-1,-1,-114,0,-109,0,-1,-1,-1,-1,-104,0,-99,0,-94,0,-1,-1,-89,0,-87,0,-82,0,-1,-1,-73,0,-68,0,-62,0,-56,0,-1,-1,-1,-1,-1,-1,-53,0,-1,-1,-1,-1,-1,-1,-49,0,-1,-1,-45,0,-1,-1,-1,-1,-1,-1,-43,0,-1,-1,-38,0,-1,-1,-1,-1,-1,-1,-1,-1,-34,0,-30,0,-24,0,-20,0,-16,0,-12,0,-6,0,0,1,6,1,12,1,18,1,23,1,-1,-1,28,1,-1,-1,32,1,37,1,42,1,-1,-1,-1,-1,-1,-1,46,1,50,1,58,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,66,1,-1,-1,69,1,78,1,87,1,96,1,105,1,114,1,123,1,-124,1,-1,-1,-115,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-106,1,-1,-1,-1,-1,-89,1,-86,1,-75,1,-72,1,-70,1,-67,1,17,2,-1,-1,20,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,22,2,-1,-1,87,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,91,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,98,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,103,2,109,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,115,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,120,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-127,2,-1,-1,-1,-1,-1,-1,-123,2,-60,2,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,51,52,104,27,91,63,50,53,104,0,27,91,67,0,27,77,0,27,91,51,52,108,0,27,91,80,0,27,91,77,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,0,27,91,50,109,0,27,91,52,104,0,27,91,55,109,0,27,91,51,109,0,27,91,52,109,0,15,0,27,91,109,15,0,27,91,63,49,48,52,57,108,0,27,91,52,108,0,27,91,50,51,109,0,27,91,50,52,109,0,27,103,0,27,41,48,0,27,91,76,0,8,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,69,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,99,27,91,63,49,48,48,48,108,27,91,63,50,53,104,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,49,37,116,59,51,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,51,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,43,43,44,44,45,45,46,46,48,48,96,96,97,97,102,102,103,103,104,104,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,40,66,27,41,48,0,27,91,52,126,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,75,0,27,91,51,57,59,52,57,109,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,3,0,1,0,33,0,70,0,-71,0,1,1,0,0,1,0,0,0,0,0,4,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,29,0,34,0,39,0,44,0,49,0,53,0,58,0,63,0,68,0,73,0,78,0,84,0,90,0,96,0,102,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-102,0,-98,0,-94,0,-90,0,-86,0,27,40,66,0,27,40,37,112,49,37,99,0,65,88,0,71,48,0,88,84,0,85,56,0,69,48,0,83,48,0,84,83,0,88,77,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,53,0,107,72,79,77,53,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,120,109,0 // NOLINT
+};
+
+// st-256color|stterm-256color|simpleterm with 256 colors,
+// auto_right_margin,
+// back_color_erase,
+// eat_newline_glitch,
+// has_status_line,
+// move_insert_mode,
+// move_standout_mode,
+// no_pad_char,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// acs_chars=+C\054D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[2J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[?12l\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// cursor_visible=\E[?25h,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// dis_status_line=\E]0;^G,
+// ena_acs=\E)0,
+// enter_alt_charset_mode=\E(0,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[?1049h,
+// enter_dim_mode=\E[2m,
+// enter_insert_mode=\E[4h,
+// enter_italics_mode=\E[3m,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode=\E[8m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// erase_chars=\E[%p1%dX,
+// exit_alt_charset_mode=\E(B,
+// exit_attribute_mode=\E[0m,
+// exit_ca_mode=\E[?1049l,
+// exit_insert_mode=\E[4l,
+// exit_italics_mode=\E[23m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\E[?5h$<100/>\E[?5l,
+// from_status_line=^G,
+// init_2string=\E[4l\E>\E[?1034l,
+// initialize_color@,
+// insert_line=\E[L,
+// key_a1=\E[1~,
+// key_a3=\E[5~,
+// key_b2=\EOu,
+// key_backspace=\177,
+// key_c1=\E[4~,
+// key_c3=\E[6~,
+// key_clear=\E[3;5~,
+// key_dc=\E[3~,
+// key_dl=\E[3;2~,
+// key_down=\EOB,
+// key_eic=\E[2;2~,
+// key_end=\E[4~,
+// key_eol=\E[1;2F,
+// key_eos=\E[1;5F,
+// key_f1=\EOP,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[1;2P,
+// key_f14=\E[1;2Q,
+// key_f15=\E[1;2R,
+// key_f16=\E[1;2S,
+// key_f17=\E[15;2~,
+// key_f18=\E[17;2~,
+// key_f19=\E[18;2~,
+// key_f2=\EOQ,
+// key_f20=\E[19;2~,
+// key_f21=\E[20;2~,
+// key_f22=\E[21;2~,
+// key_f23=\E[23;2~,
+// key_f24=\E[24;2~,
+// key_f25=\E[1;5P,
+// key_f26=\E[1;5Q,
+// key_f27=\E[1;5R,
+// key_f28=\E[1;5S,
+// key_f29=\E[15;5~,
+// key_f3=\EOR,
+// key_f30=\E[17;5~,
+// key_f31=\E[18;5~,
+// key_f32=\E[19;5~,
+// key_f33=\E[20;5~,
+// key_f34=\E[21;5~,
+// key_f35=\E[23;5~,
+// key_f36=\E[24;5~,
+// key_f37=\E[1;6P,
+// key_f38=\E[1;6Q,
+// key_f39=\E[1;6R,
+// key_f4=\EOS,
+// key_f40=\E[1;6S,
+// key_f41=\E[15;6~,
+// key_f42=\E[17;6~,
+// key_f43=\E[18;6~,
+// key_f44=\E[19;6~,
+// key_f45=\E[20;6~,
+// key_f46=\E[21;6~,
+// key_f47=\E[23;6~,
+// key_f48=\E[24;6~,
+// key_f49=\E[1;3P,
+// key_f5=\E[15~,
+// key_f50=\E[1;3Q,
+// key_f51=\E[1;3R,
+// key_f52=\E[1;3S,
+// key_f53=\E[15;3~,
+// key_f54=\E[17;3~,
+// key_f55=\E[18;3~,
+// key_f56=\E[19;3~,
+// key_f57=\E[20;3~,
+// key_f58=\E[21;3~,
+// key_f59=\E[23;3~,
+// key_f6=\E[17~,
+// key_f60=\E[24;3~,
+// key_f61=\E[1;4P,
+// key_f62=\E[1;4Q,
+// key_f63=\E[1;4R,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_il=\E[2;5~,
+// key_left=\EOD,
+// key_mouse=\E[M,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\EOC,
+// key_sdc=\E[3;2~,
+// key_send=\E[1;2F,
+// key_sf=\E[1;2B,
+// key_shome=\E[1;2H,
+// key_sic=\E[2;2~,
+// key_sleft=\E[1;2D,
+// key_snext=\E[6;2~,
+// key_sprevious=\E[5;2~,
+// key_sr=\E[1;2A,
+// key_sright=\E[1;2C,
+// key_up=\EOA,
+// keypad_local=\E[?1l\E>,
+// keypad_xmit=\E[?1h\E=,
+// orig_colors@,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_up_cursor=\E[%p1%dA,
+// print_screen=\E[i,
+// prtr_off=\E[4i,
+// prtr_on=\E[5i,
+// reset_1string=\Ec,
+// reset_2string=\E[4l\E>\E[?1034l,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p7%t;8%;m,
+// set_tab=\EH,
+// tab=^I,
+// to_status_line=\E]0;,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?1;2c,
+// user9=\E[c,
+static const int8_t st_256colour_terminfo[] = {
+ 30,2,55,0,29,0,15,0,105,1,-125,5,115,116,45,50,53,54,99,111,108,111,114,124,115,116,116,101,114,109,45,50,53,54,99,111,108,111,114,124,115,105,109,112,108,101,116,101,114,109,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,38,0,42,0,46,0,-1,-1,57,0,74,0,76,0,80,0,87,0,-1,-1,89,0,102,0,-1,-1,106,0,110,0,117,0,121,0,125,0,-1,-1,-125,0,-121,0,-116,0,-111,0,-1,-1,-102,0,-97,0,-92,0,-1,-1,-87,0,-82,0,-77,0,-72,0,-63,0,-59,0,-54,0,-1,-1,-45,0,-40,0,-34,0,-28,0,-1,-1,-10,0,-1,-1,-8,0,-1,-1,-1,-1,-1,-1,7,1,-1,-1,11,1,-1,-1,13,1,-1,-1,20,1,25,1,32,1,36,1,43,1,50,1,-1,-1,57,1,61,1,67,1,71,1,75,1,79,1,85,1,91,1,97,1,103,1,109,1,114,1,119,1,126,1,-1,-1,-126,1,-121,1,-116,1,-112,1,-105,1,-1,-1,-98,1,-94,1,-86,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-78,1,-69,1,-60,1,-51,1,-42,1,-33,1,-24,1,-15,1,-1,-1,-6,1,-1,-1,-1,-1,-1,-1,3,2,7,2,12,2,-1,-1,17,2,20,2,-1,-1,-1,-1,35,2,38,2,49,2,52,2,54,2,57,2,-106,2,-1,-1,-103,2,-101,2,-1,-1,-1,-1,-1,-1,-96,2,-91,2,-86,2,-82,2,-77,2,-1,-1,-1,-1,-72,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-7,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-3,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,3,-1,-1,-1,-1,9,3,-1,-1,-1,-1,-1,-1,-1,-1,16,3,23,3,30,3,-1,-1,-1,-1,37,3,-1,-1,44,3,-1,-1,-1,-1,-1,-1,51,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,58,3,64,3,70,3,77,3,84,3,91,3,98,3,106,3,114,3,122,3,-126,3,-118,3,-110,3,-102,3,-94,3,-87,3,-80,3,-73,3,-66,3,-58,3,-50,3,-42,3,-34,3,-26,3,-18,3,-10,3,-2,3,5,4,12,4,19,4,26,4,34,4,42,4,50,4,58,4,66,4,74,4,82,4,90,4,97,4,104,4,111,4,118,4,126,4,-122,4,-114,4,-106,4,-98,4,-90,4,-82,4,-74,4,-67,4,-60,4,-53,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-48,4,-37,4,-32,4,-24,4,-20,4,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-11,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-6,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,5,-1,-1,-1,-1,-1,-1,4,5,67,5,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,49,50,108,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,63,50,53,104,0,27,91,80,0,27,91,77,0,27,93,48,59,7,0,27,40,48,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,40,66,0,27,91,48,109,0,27,91,63,49,48,52,57,108,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,7,0,27,91,52,108,27,62,27,91,63,49,48,51,52,108,0,27,91,76,0,127,0,27,91,51,59,53,126,0,27,91,51,126,0,27,91,51,59,50,126,0,27,79,66,0,27,91,50,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,53,70,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,91,50,59,53,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,91,105,0,27,91,52,105,0,27,91,53,105,0,27,99,0,27,91,52,108,27,62,27,91,63,49,48,51,52,108,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,37,63,37,112,57,37,116,27,40,48,37,101,27,40,66,37,59,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,55,37,116,59,56,37,59,109,0,27,72,0,9,0,27,93,48,59,0,27,91,49,126,0,27,91,53,126,0,27,79,117,0,27,91,52,126,0,27,91,54,126,0,43,67,44,68,45,65,46,66,48,69,96,96,97,97,102,102,103,103,104,70,105,71,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,41,48,0,27,91,52,126,0,27,91,51,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,49,59,50,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,91,51,109,0,27,91,50,51,109,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,0,3,0,1,0,71,0,-110,0,-1,1,0,0,1,0,-1,-1,-1,-1,-1,-1,-1,-1,0,0,-1,-1,18,0,24,0,34,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,39,0,-1,-1,46,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,53,0,-1,-1,60,0,-1,-1,-1,-1,67,0,-1,-1,74,0,-1,-1,-1,-1,81,0,-1,-1,88,0,-1,-1,-1,-1,95,0,-1,-1,102,0,-1,-1,-1,-1,-1,-1,109,0,-1,-1,116,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,123,0,-127,0,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,42,0,48,0,53,0,58,0,63,0,68,0,73,0,77,0,82,0,87,0,92,0,97,0,102,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-77,0,-72,0,-67,0,-62,0,-57,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,67,1,72,1,77,1,82,1,87,1,92,1,96,1,100,1,104,1,108,1,113,1,118,1,27,93,53,50,59,37,112,49,37,115,59,37,112,50,37,115,7,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,93,48,59,0,27,91,49,59,51,66,0,27,91,49,59,53,66,0,27,91,49,59,51,68,0,27,91,49,59,53,68,0,27,91,54,59,51,126,0,27,91,54,59,53,126,0,27,91,53,59,51,126,0,27,91,53,59,53,126,0,27,91,49,59,51,67,0,27,91,49,59,53,67,0,27,91,49,59,51,65,0,27,91,49,59,53,65,0,27,91,50,57,109,0,27,91,57,109,0,65,88,0,71,48,0,88,84,0,85,56,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 // NOLINT
+};
+
+// tmux-256color|tmux with 256 colors,
+// auto_right_margin,
+// backspaces_with_bs,
+// eat_newline_glitch,
+// has_hardware_tabs,
+// has_meta_key,
+// has_status_line,
+// move_insert_mode,
+// move_standout_mode,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// acs_chars=++\054\054--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[34h\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\EM,
+// cursor_visible=\E[34l,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// dis_status_line=\E]0;^G,
+// ena_acs=\E(B\E)0,
+// enter_alt_charset_mode=^N,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[?1049h,
+// enter_dim_mode=\E[2m,
+// enter_insert_mode=\E[4h,
+// enter_italics_mode=\E[3m,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode=\E[8m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// exit_alt_charset_mode=^O,
+// exit_attribute_mode=\E[m^O,
+// exit_ca_mode=\E[?1049l,
+// exit_insert_mode=\E[4l,
+// exit_italics_mode=\E[23m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\Eg,
+// from_status_line=^G,
+// init_2string=\E)0,
+// insert_line=\E[L,
+// key_backspace=^H,
+// key_btab=\E[Z,
+// key_dc=\E[3~,
+// key_down=\EOB,
+// key_end=\E[4~,
+// key_f1=\EOP,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[1;2P,
+// key_f14=\E[1;2Q,
+// key_f15=\E[1;2R,
+// key_f16=\E[1;2S,
+// key_f17=\E[15;2~,
+// key_f18=\E[17;2~,
+// key_f19=\E[18;2~,
+// key_f2=\EOQ,
+// key_f20=\E[19;2~,
+// key_f21=\E[20;2~,
+// key_f22=\E[21;2~,
+// key_f23=\E[23;2~,
+// key_f24=\E[24;2~,
+// key_f25=\E[1;5P,
+// key_f26=\E[1;5Q,
+// key_f27=\E[1;5R,
+// key_f28=\E[1;5S,
+// key_f29=\E[15;5~,
+// key_f3=\EOR,
+// key_f30=\E[17;5~,
+// key_f31=\E[18;5~,
+// key_f32=\E[19;5~,
+// key_f33=\E[20;5~,
+// key_f34=\E[21;5~,
+// key_f35=\E[23;5~,
+// key_f36=\E[24;5~,
+// key_f37=\E[1;6P,
+// key_f38=\E[1;6Q,
+// key_f39=\E[1;6R,
+// key_f4=\EOS,
+// key_f40=\E[1;6S,
+// key_f41=\E[15;6~,
+// key_f42=\E[17;6~,
+// key_f43=\E[18;6~,
+// key_f44=\E[19;6~,
+// key_f45=\E[20;6~,
+// key_f46=\E[21;6~,
+// key_f47=\E[23;6~,
+// key_f48=\E[24;6~,
+// key_f49=\E[1;3P,
+// key_f5=\E[15~,
+// key_f50=\E[1;3Q,
+// key_f51=\E[1;3R,
+// key_f52=\E[1;3S,
+// key_f53=\E[15;3~,
+// key_f54=\E[17;3~,
+// key_f55=\E[18;3~,
+// key_f56=\E[19;3~,
+// key_f57=\E[20;3~,
+// key_f58=\E[21;3~,
+// key_f59=\E[23;3~,
+// key_f6=\E[17~,
+// key_f60=\E[24;3~,
+// key_f61=\E[1;4P,
+// key_f62=\E[1;4Q,
+// key_f63=\E[1;4R,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_left=\EOD,
+// key_mouse=\E[M,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\EOC,
+// key_sdc=\E[3;2~,
+// key_send=\E[1;2F,
+// key_sf=\E[1;2B,
+// key_shome=\E[1;2H,
+// key_sic=\E[2;2~,
+// key_sleft=\E[1;2D,
+// key_snext=\E[6;2~,
+// key_sprevious=\E[5;2~,
+// key_sr=\E[1;2A,
+// key_sright=\E[1;2C,
+// key_up=\EOA,
+// keypad_local=\E[?1l\E>,
+// keypad_xmit=\E[?1h\E=,
+// newline=\EE,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_up_cursor=\E[%p1%dA,
+// reset_2string=\Ec\E[?1000l\E[?25h,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p7%t;8%;m%?%p9%t^N%e^O%;,
+// set_tab=\EH,
+// tab=^I,
+// to_status_line=\E]0;,
+static const int8_t tmux_256colour_terminfo[] = {
+ 30,2,35,0,43,0,15,0,105,1,-15,4,116,109,117,120,45,50,53,54,99,111,108,111,114,124,116,109,117,120,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,37,0,41,0,45,0,-1,-1,56,0,73,0,75,0,79,0,86,0,-1,-1,88,0,100,0,-1,-1,104,0,107,0,113,0,117,0,121,0,-1,-1,127,0,-127,0,-122,0,-117,0,-1,-1,-108,0,-103,0,-98,0,-1,-1,-93,0,-88,0,-83,0,-1,-1,-78,0,-76,0,-71,0,-1,-1,-62,0,-57,0,-51,0,-45,0,-1,-1,-42,0,-1,-1,-40,0,-1,-1,-1,-1,-1,-1,-36,0,-1,-1,-32,0,-1,-1,-1,-1,-1,-1,-30,0,-1,-1,-25,0,-1,-1,-1,-1,-1,-1,-1,-1,-21,0,-17,0,-11,0,-7,0,-3,0,1,1,7,1,13,1,19,1,25,1,31,1,36,1,-1,-1,41,1,-1,-1,45,1,50,1,55,1,59,1,66,1,-1,-1,73,1,77,1,85,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,93,1,-1,-1,96,1,105,1,114,1,123,1,-124,1,-115,1,-106,1,-97,1,-1,-1,-88,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-79,1,-1,-1,-1,-1,-62,1,-59,1,-48,1,-45,1,-43,1,-40,1,49,2,-1,-1,52,2,54,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,59,2,-1,-1,124,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-128,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-121,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-116,2,-1,-1,-1,-1,-109,2,-1,-1,-1,-1,-1,-1,-1,-1,-102,2,-95,2,-88,2,-1,-1,-1,-1,-81,2,-1,-1,-74,2,-1,-1,-1,-1,-1,-1,-67,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-60,2,-54,2,-48,2,-41,2,-34,2,-27,2,-20,2,-12,2,-4,2,4,3,12,3,20,3,28,3,36,3,44,3,51,3,58,3,65,3,72,3,80,3,88,3,96,3,104,3,112,3,120,3,-128,3,-120,3,-113,3,-106,3,-99,3,-92,3,-84,3,-76,3,-68,3,-60,3,-52,3,-44,3,-36,3,-28,3,-21,3,-14,3,-7,3,0,4,8,4,16,4,24,4,32,4,40,4,48,4,56,4,64,4,71,4,78,4,85,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,90,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,99,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,104,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,110,4,-1,-1,-1,-1,-1,-1,114,4,-79,4,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,51,52,104,27,91,63,50,53,104,0,27,91,67,0,27,77,0,27,91,51,52,108,0,27,91,80,0,27,91,77,0,27,93,48,59,7,0,14,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,15,0,27,91,109,15,0,27,91,63,49,48,52,57,108,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,103,0,7,0,27,41,48,0,27,91,76,0,8,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,69,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,99,27,91,63,49,48,48,48,108,27,91,63,50,53,104,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,55,37,116,59,56,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,93,48,59,0,43,43,44,44,45,45,46,46,48,48,96,96,97,97,102,102,103,103,104,104,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,40,66,27,41,48,0,27,91,52,126,0,27,91,51,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,51,57,59,52,57,109,0,27,91,51,109,0,27,91,50,51,109,0,27,91,77,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,0,3,0,1,0,73,0,-106,0,65,3,1,1,0,0,1,0,0,0,0,0,7,0,19,0,23,0,28,0,46,0,54,0,60,0,70,0,-1,-1,-1,-1,-1,-1,75,0,82,0,89,0,96,0,103,0,110,0,117,0,124,0,-125,0,-118,0,-111,0,-104,0,-97,0,-90,0,-83,0,-76,0,-1,-1,-69,0,-62,0,-55,0,-48,0,-41,0,-1,-1,-34,0,-27,0,-20,0,-13,0,-6,0,1,1,8,1,15,1,22,1,29,1,36,1,43,1,50,1,57,1,64,1,71,1,78,1,85,1,92,1,99,1,106,1,113,1,120,1,127,1,-122,1,-115,1,-108,1,-101,1,-94,1,-87,1,-80,1,-1,-1,-1,-1,-1,-1,-1,-1,-73,1,-67,1,-1,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,39,0,42,0,48,0,54,0,59,0,64,0,69,0,74,0,79,0,83,0,88,0,93,0,98,0,103,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-71,0,-66,0,-61,0,-56,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,73,1,78,1,83,1,88,1,93,1,98,1,102,1,106,1,110,1,114,1,119,1,124,1,27,93,49,49,50,7,0,27,93,49,50,59,37,112,49,37,115,7,0,27,40,66,0,27,91,51,74,0,27,93,53,50,59,37,112,49,37,115,59,37,112,50,37,115,7,0,27,40,37,112,49,37,99,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,93,48,59,0,27,91,51,59,51,126,0,27,91,51,59,52,126,0,27,91,51,59,53,126,0,27,91,51,59,54,126,0,27,91,51,59,55,126,0,27,91,49,59,50,66,0,27,91,49,59,51,66,0,27,91,49,59,52,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,55,66,0,27,91,49,59,51,70,0,27,91,49,59,52,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,55,70,0,27,91,49,59,51,72,0,27,91,49,59,52,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,55,72,0,27,91,50,59,51,126,0,27,91,50,59,52,126,0,27,91,50,59,53,126,0,27,91,50,59,54,126,0,27,91,50,59,55,126,0,27,91,49,59,51,68,0,27,91,49,59,52,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,91,49,59,55,68,0,27,91,54,59,51,126,0,27,91,54,59,52,126,0,27,91,54,59,53,126,0,27,91,54,59,54,126,0,27,91,54,59,55,126,0,27,91,53,59,51,126,0,27,91,53,59,52,126,0,27,91,53,59,53,126,0,27,91,53,59,54,126,0,27,91,53,59,55,126,0,27,91,49,59,51,67,0,27,91,49,59,52,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,91,49,59,55,67,0,27,91,49,59,50,65,0,27,91,49,59,51,65,0,27,91,49,59,52,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,49,59,55,65,0,27,91,50,57,109,0,27,91,57,109,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 // NOLINT
+};
+
+// vte-256color|VTE with xterm 256-colors,
+// auto_right_margin,
+// back_color_erase,
+// backspaces_with_bs,
+// can_change,
+// eat_newline_glitch,
+// move_insert_mode,
+// move_standout_mode,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// acs_chars=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[2J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// ena_acs=\E)0,
+// enter_alt_charset_mode=^N,
+// enter_am_mode=\E[?7h,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E7\E[?47h,
+// enter_dim_mode=\E[2m,
+// enter_insert_mode=\E[4h,
+// enter_italics_mode=\E[3m,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode=\E[8m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// erase_chars=\E[%p1%dX,
+// exit_alt_charset_mode=^O,
+// exit_am_mode=\E[?7l,
+// exit_attribute_mode=\E[0m^O,
+// exit_ca_mode=\E[2J\E[?47l\E8,
+// exit_insert_mode=\E[4l,
+// exit_italics_mode=\E[23m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\E[?5h$<100/>\E[?5l,
+// init_2string=\E[m\E[?7h\E[4l\E>\E7\E[r\E[?1;3;4;6l\E8,
+// initialize_color=\E]4;%p1%d;rgb\072%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\,
+// insert_line=\E[L,
+// key_b2=\E[E,
+// key_backspace=\177,
+// key_btab=\E[Z,
+// key_dc=\E[3~,
+// key_down=\EOB,
+// key_end=\EOF,
+// key_enter=\EOM,
+// key_f1=\EOP,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[1;2P,
+// key_f14=\E[1;2Q,
+// key_f15=\E[1;2R,
+// key_f16=\E[1;2S,
+// key_f17=\E[15;2~,
+// key_f18=\E[17;2~,
+// key_f19=\E[18;2~,
+// key_f2=\EOQ,
+// key_f20=\E[19;2~,
+// key_f21=\E[20;2~,
+// key_f22=\E[21;2~,
+// key_f23=\E[23;2~,
+// key_f24=\E[24;2~,
+// key_f25=\E[1;5P,
+// key_f26=\E[1;5Q,
+// key_f27=\E[1;5R,
+// key_f28=\E[1;5S,
+// key_f29=\E[15;5~,
+// key_f3=\EOR,
+// key_f30=\E[17;5~,
+// key_f31=\E[18;5~,
+// key_f32=\E[19;5~,
+// key_f33=\E[20;5~,
+// key_f34=\E[21;5~,
+// key_f35=\E[23;5~,
+// key_f36=\E[24;5~,
+// key_f37=\E[1;6P,
+// key_f38=\E[1;6Q,
+// key_f39=\E[1;6R,
+// key_f4=\EOS,
+// key_f40=\E[1;6S,
+// key_f41=\E[15;6~,
+// key_f42=\E[17;6~,
+// key_f43=\E[18;6~,
+// key_f44=\E[19;6~,
+// key_f45=\E[20;6~,
+// key_f46=\E[21;6~,
+// key_f47=\E[23;6~,
+// key_f48=\E[24;6~,
+// key_f49=\E[1;3P,
+// key_f5=\E[15~,
+// key_f50=\E[1;3Q,
+// key_f51=\E[1;3R,
+// key_f52=\E[1;3S,
+// key_f53=\E[15;3~,
+// key_f54=\E[17;3~,
+// key_f55=\E[18;3~,
+// key_f56=\E[19;3~,
+// key_f57=\E[20;3~,
+// key_f58=\E[21;3~,
+// key_f59=\E[23;3~,
+// key_f6=\E[17~,
+// key_f60=\E[24;3~,
+// key_f61=\E[1;4P,
+// key_f62=\E[1;4Q,
+// key_f63=\E[1;4R,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_find=\E[1~,
+// key_home=\EOH,
+// key_ic=\E[2~,
+// key_left=\EOD,
+// key_mouse=\E[<,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\EOC,
+// key_sdc=\E[3;2~,
+// key_select=\E[4~,
+// key_send=\E[1;2F,
+// key_sf=\E[1;2B,
+// key_shome=\E[1;2H,
+// key_sic=\E[2;2~,
+// key_sleft=\E[1;2D,
+// key_snext=\E[6;2~,
+// key_sprevious=\E[5;2~,
+// key_sr=\E[1;2A,
+// key_sright=\E[1;2C,
+// key_up=\EOA,
+// keypad_local=\E[?1l\E>,
+// keypad_xmit=\E[?1h\E=,
+// memory_lock=\El,
+// memory_unlock=\Em,
+// orig_colors=\E]104^G,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_rindex=\E[%p1%dT,
+// parm_up_cursor=\E[%p1%dA,
+// reset_1string=\Ec,
+// reset_2string=\E7\E[r\E8\E[m\E[?7h\E[\041p\E[?1;3;4;6l\E[4l\E>\E[?1000l\E[?25h,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p5%t;2%;%?%p7%t;8%;%?%p1%p3%|%t;7%;m%?%p9%t^N%e^O%;,
+// set_tab=\EH,
+// tab=^I,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?%[;0123456789]c,
+// user9=\E[c,
+static const int8_t vte_256colour_terminfo[] = {
+ 30,2,39,0,38,0,15,0,-99,1,-49,5,118,116,101,45,50,53,54,99,111,108,111,114,124,86,84,69,32,119,105,116,104,32,120,116,101,114,109,32,50,53,54,45,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,38,0,42,0,46,0,-1,-1,57,0,74,0,76,0,80,0,87,0,-1,-1,89,0,96,0,-1,-1,100,0,-1,-1,104,0,108,0,-1,-1,-1,-1,112,0,-1,-1,114,0,119,0,-1,-1,-128,0,-123,0,-118,0,-1,-1,-113,0,-108,0,-103,0,-98,0,-89,0,-87,0,-81,0,-1,-1,-68,0,-63,0,-57,0,-51,0,-1,-1,-1,-1,-1,-1,-33,0,-1,-1,-1,-1,-1,-1,0,1,-1,-1,4,1,-1,-1,-1,-1,-1,-1,6,1,-1,-1,11,1,-1,-1,-1,-1,-1,-1,-1,-1,15,1,19,1,25,1,29,1,33,1,37,1,43,1,49,1,55,1,61,1,67,1,71,1,-1,-1,76,1,-1,-1,80,1,85,1,90,1,94,1,101,1,-1,-1,108,1,112,1,120,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-128,1,-119,1,-110,1,-101,1,-92,1,-83,1,-74,1,-65,1,-56,1,-47,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-38,1,-35,1,-1,-1,-1,-1,16,2,19,2,30,2,33,2,35,2,38,2,116,2,-1,-1,119,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,121,2,-1,-1,-1,-1,-1,-1,-1,-1,125,2,-1,-1,-78,2,-1,-1,-1,-1,-74,2,-68,2,-1,-1,-1,-1,-62,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-58,2,-54,2,-1,-1,-50,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-45,2,-1,-1,-38,2,-33,2,-1,-1,-1,-1,-1,-1,-1,-1,-26,2,-19,2,-12,2,-1,-1,-1,-1,-5,2,-1,-1,2,3,-1,-1,-1,-1,-1,-1,9,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,3,22,3,28,3,35,3,42,3,49,3,56,3,64,3,72,3,80,3,88,3,96,3,104,3,112,3,120,3,127,3,-122,3,-115,3,-108,3,-100,3,-92,3,-84,3,-76,3,-68,3,-60,3,-52,3,-44,3,-37,3,-30,3,-23,3,-16,3,-8,3,0,4,8,4,16,4,24,4,32,4,40,4,48,4,55,4,62,4,69,4,76,4,84,4,92,4,100,4,108,4,116,4,124,4,-124,4,-116,4,-109,4,-102,4,-95,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-90,4,-79,4,-74,4,-55,4,-51,4,-42,4,-35,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,59,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,64,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,70,5,-1,-1,-1,-1,-1,-1,74,5,-119,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-55,5,-52,5,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,14,0,27,91,49,109,0,27,55,27,91,63,52,55,104,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,15,0,27,91,48,109,15,0,27,91,50,74,27,91,63,52,55,108,27,56,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,27,91,109,27,91,63,55,104,27,91,52,108,27,62,27,55,27,91,114,27,91,63,49,59,51,59,52,59,54,108,27,56,0,27,91,76,0,127,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,79,72,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,99,0,27,55,27,91,114,27,56,27,91,109,27,91,63,55,104,27,91,33,112,27,91,63,49,59,51,59,52,59,54,108,27,91,52,108,27,62,27,91,63,49,48,48,48,108,27,91,63,50,53,104,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,55,37,116,59,56,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,109,37,63,37,112,57,37,116,14,37,101,15,37,59,0,27,72,0,9,0,27,91,69,0,96,96,97,97,102,102,103,103,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,41,48,0,27,79,70,0,27,79,77,0,27,91,49,126,0,27,91,51,59,50,126,0,27,91,52,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,49,48,52,7,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,92,0,27,91,51,109,0,27,91,50,51,109,0,27,91,60,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,108,0,27,109,0,0,3,0,1,0,73,0,-106,0,57,3,0,0,1,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,-1,-1,-1,-1,32,0,39,0,46,0,53,0,60,0,67,0,74,0,81,0,88,0,95,0,102,0,109,0,116,0,123,0,-126,0,-119,0,-1,-1,-112,0,-105,0,-98,0,-91,0,-84,0,-1,-1,-77,0,-70,0,-63,0,-56,0,-49,0,-42,0,-35,0,-28,0,-21,0,-14,0,-7,0,0,1,7,1,14,1,21,1,28,1,35,1,42,1,49,1,56,1,63,1,70,1,77,1,84,1,91,1,98,1,105,1,112,1,119,1,126,1,-123,1,-1,-1,-1,-1,-1,-1,-1,-1,-116,1,-110,1,-105,1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,39,0,42,0,48,0,54,0,59,0,64,0,69,0,74,0,79,0,83,0,88,0,93,0,98,0,103,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-71,0,-66,0,-61,0,-56,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,73,1,78,1,83,1,88,1,93,1,98,1,102,1,106,1,110,1,114,1,119,1,124,1,27,91,63,49,48,48,54,59,49,48,48,48,37,63,37,112,49,37,123,49,125,37,61,37,116,104,37,101,108,37,59,0,27,91,51,59,51,126,0,27,91,51,59,52,126,0,27,91,51,59,53,126,0,27,91,51,59,54,126,0,27,91,51,59,55,126,0,27,91,49,59,50,66,0,27,91,49,59,51,66,0,27,91,49,59,52,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,55,66,0,27,91,49,59,51,70,0,27,91,49,59,52,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,55,70,0,27,91,49,59,51,72,0,27,91,49,59,52,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,55,72,0,27,91,50,59,51,126,0,27,91,50,59,52,126,0,27,91,50,59,53,126,0,27,91,50,59,54,126,0,27,91,50,59,55,126,0,27,91,49,59,51,68,0,27,91,49,59,52,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,91,49,59,55,68,0,27,91,54,59,51,126,0,27,91,54,59,52,126,0,27,91,54,59,53,126,0,27,91,54,59,54,126,0,27,91,54,59,55,126,0,27,91,53,59,51,126,0,27,91,53,59,52,126,0,27,91,53,59,53,126,0,27,91,53,59,54,126,0,27,91,53,59,55,126,0,27,91,49,59,51,67,0,27,91,49,59,52,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,91,49,59,55,67,0,27,91,49,59,50,65,0,27,91,49,59,51,65,0,27,91,49,59,52,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,49,59,55,65,0,27,91,50,57,109,0,27,91,57,109,0,27,91,60,37,112,49,37,100,59,37,112,50,37,100,59,37,112,51,37,100,59,37,63,37,112,52,37,116,77,37,101,109,37,59,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 // NOLINT
+};
+
+// vtpcon|ANIS emulation for console virtual terminal sequence with libuv,
+// auto_right_margin,
+// back_color_erase,
+// backspaces_with_bs,
+// has_meta_key,
+// move_insert_mode,
+// move_standout_mode,
+// no_pad_char,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// acs_chars=jjkkllmmnnqqttuuvvwwxx,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs@,
+// clear_screen=\E[H\E[2J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\E[B,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[?12l\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// cursor_visible@,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// enter_alt_charset_mode=\E(0,
+// enter_am_mode@,
+// enter_blink_mode@,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[?1049h,
+// enter_dim_mode@,
+// enter_insert_mode@,
+// enter_italics_mode=\E[3m,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode@,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// erase_chars=\E[%p1%dX,
+// exit_alt_charset_mode=\E(B,
+// exit_am_mode@,
+// exit_attribute_mode=\E[0m,
+// exit_ca_mode=\E[?1049l,
+// exit_insert_mode@,
+// exit_italics_mode=\E[23m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen@,
+// init_2string=\E[\041p\E[?3l,
+// initialize_color=\E]4;%p1%d;rgb\072%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E,
+// insert_line=\E[L,
+// key_b2=\E[G,
+// key_backspace=^H,
+// key_btab=\E[Z,
+// key_dc=\E[3~,
+// key_down=\E[B,
+// key_end=\E[4~,
+// key_enter=\EOM,
+// key_f1=\E[[A,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[25~,
+// key_f14=\E[26~,
+// key_f15=\E[28~,
+// key_f16=\E[29~,
+// key_f17=\E[31~,
+// key_f18=\E[32~,
+// key_f19=\E[33~,
+// key_f2=\E[[B,
+// key_f20=\E[34~,
+// key_f21=\E[23$,
+// key_f22=\E[24$,
+// key_f23=\E[11\136,
+// key_f24=\E[12\136,
+// key_f25=\E[13\136,
+// key_f26=\E[14\136,
+// key_f27=\E[15\136,
+// key_f28=\E[17\136,
+// key_f29=\E[18\136,
+// key_f3=\E[[C,
+// key_f30=\E[19\136,
+// key_f31=\E[20\136,
+// key_f32=\E[21\136,
+// key_f33=\E[23\136,
+// key_f34=\E[24\136,
+// key_f35=\E[25\136,
+// key_f36=\E[26\136,
+// key_f37=\E[28\136,
+// key_f38=\E[29\136,
+// key_f39=\E[31\136,
+// key_f4=\E[[D,
+// key_f40=\E[1;6S,
+// key_f41=\E[32\136,
+// key_f42=\E[33\136,
+// key_f43=\E[34\136,
+// key_f44=\E[23@,
+// key_f45=\E[24@,
+// key_f46@,
+// key_f47@,
+// key_f48@,
+// key_f49@,
+// key_f5=\E[[E,
+// key_f50@,
+// key_f51@,
+// key_f52@,
+// key_f53@,
+// key_f54@,
+// key_f55@,
+// key_f56@,
+// key_f57@,
+// key_f58@,
+// key_f59@,
+// key_f6=\E[17~,
+// key_f60@,
+// key_f61@,
+// key_f62@,
+// key_f63@,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_left=\E[D,
+// key_mouse@,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\E[C,
+// key_sdc=\E[3;2~,
+// key_send=\E[4;2~,
+// key_sf=\E[1;2B,
+// key_shome=\E[1;2~,
+// key_sic=\E[2;2~,
+// key_sleft=\E[1;2D,
+// key_snext=\E[6;2~,
+// key_sprevious=\E[5;2~,
+// key_sr=\E[1;2A,
+// key_sright=\E[1;2C,
+// key_up=\E[A,
+// keypad_local@,
+// keypad_xmit@,
+// memory_lock@,
+// memory_unlock@,
+// meta_off@,
+// meta_on@,
+// orig_colors@,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_rindex=\E[%p1%dT,
+// parm_up_cursor=\E[%p1%dA,
+// print_screen@,
+// prtr_off@,
+// prtr_on@,
+// repeat_char=%p1%c\E[%p2%{1}%-%db,
+// reset_1string@,
+// reset_2string@,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=\E[0%?%p1%p3%|%t;7%;%?%p2%t;4%;%?%p6%t;1%;m,
+// set_tab=\EH,
+// tab=^I,
+// user6@,
+// user7@,
+// user8@,
+// user9@,
+static const int8_t vtpcon_terminfo[] = {
+ 30,2,71,0,38,0,15,0,-99,1,21,4,118,116,112,99,111,110,124,65,78,73,83,32,101,109,117,108,97,116,105,111,110,32,102,111,114,32,99,111,110,115,111,108,101,32,118,105,114,116,117,97,108,32,116,101,114,109,105,110,97,108,32,115,101,113,117,101,110,99,101,32,119,105,116,104,32,108,105,98,117,118,0,0,1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,-2,-1,25,0,33,0,37,0,41,0,-1,-1,52,0,69,0,73,0,77,0,84,0,-1,-1,86,0,99,0,-1,-1,103,0,-2,-1,107,0,111,0,-1,-1,-1,-1,115,0,-2,-1,119,0,124,0,-1,-1,-2,-1,-2,-1,-2,-1,-1,-1,-123,0,-118,0,-113,0,-108,0,-99,0,-95,0,-90,0,-1,-1,-2,-1,-81,0,-75,0,-2,-1,-1,-1,-1,-1,-1,-1,-69,0,-1,-1,-1,-1,-1,-1,-59,0,-1,-1,-55,0,-1,-1,-1,-1,-1,-1,-53,0,-1,-1,-48,0,-1,-1,-1,-1,-1,-1,-1,-1,-44,0,-39,0,-33,0,-28,0,-23,0,-18,0,-13,0,-7,0,-1,0,5,1,11,1,16,1,-1,-1,21,1,-1,-1,25,1,30,1,35,1,39,1,46,1,-1,-1,53,1,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-1,-1,-1,-1,57,1,66,1,75,1,84,1,93,1,102,1,111,1,120,1,-127,1,-118,1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-109,1,-2,-1,-2,-1,-1,-1,-1,-1,-89,1,-86,1,-75,1,-72,1,-70,1,-67,1,-24,1,-1,-1,-21,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-19,1,-1,-1,-1,-1,-1,-1,-1,-1,-15,1,-1,-1,8,2,-1,-1,-1,-1,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,12,2,17,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,2,-1,-1,-1,-1,28,2,-1,-1,-1,-1,-1,-1,-1,-1,35,2,42,2,49,2,-1,-1,-1,-1,56,2,-1,-1,63,2,-1,-1,-1,-1,-1,-1,70,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,77,2,83,2,89,2,95,2,101,2,107,2,113,2,119,2,125,2,-125,2,-119,2,-113,2,-107,2,-101,2,-95,2,-89,2,-83,2,-77,2,-71,2,-65,2,-59,2,-53,2,-47,2,-41,2,-35,2,-29,2,-23,2,-17,2,-11,2,-5,2,2,3,8,3,14,3,20,3,26,3,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,32,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,37,3,-2,-1,46,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-117,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-112,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-106,3,-43,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,27,91,66,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,49,50,108,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,80,0,27,91,77,0,27,40,48,0,27,91,49,109,0,27,91,63,49,48,52,57,104,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,40,66,0,27,91,48,109,0,27,91,63,49,48,52,57,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,33,112,27,91,63,51,108,0,27,91,76,0,8,0,27,91,51,126,0,27,91,66,0,27,91,91,65,0,27,91,50,49,126,0,27,91,91,66,0,27,91,91,67,0,27,91,91,68,0,27,91,91,69,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,91,68,0,27,91,54,126,0,27,91,53,126,0,27,91,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,91,65,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,27,91,48,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,54,37,116,59,49,37,59,109,0,27,72,0,9,0,27,91,71,0,106,106,107,107,108,108,109,109,110,110,113,113,116,116,117,117,118,118,119,119,120,120,0,27,91,90,0,27,91,52,126,0,27,79,77,0,27,91,51,59,50,126,0,27,91,52,59,50,126,0,27,91,49,59,50,126,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,50,51,36,0,27,91,50,52,36,0,27,91,49,49,94,0,27,91,49,50,94,0,27,91,49,51,94,0,27,91,49,52,94,0,27,91,49,53,94,0,27,91,49,55,94,0,27,91,49,56,94,0,27,91,49,57,94,0,27,91,50,48,94,0,27,91,50,49,94,0,27,91,50,51,94,0,27,91,50,52,94,0,27,91,50,53,94,0,27,91,50,54,94,0,27,91,50,56,94,0,27,91,50,57,94,0,27,91,51,49,94,0,27,91,49,59,54,83,0,27,91,51,50,94,0,27,91,51,51,94,0,27,91,51,52,94,0,27,91,50,51,64,0,27,91,50,52,64,0,27,91,49,75,0,27,91,51,57,59,52,57,109,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,0,27,91,51,109,0,27,91,50,51,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,0,3,0,1,0,74,0,-104,0,-95,1,1,0,1,0,-1,-1,-1,-1,-2,-1,-2,-1,-1,-1,0,0,-2,-1,-1,-1,5,0,-1,-1,11,0,-1,-1,-2,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,21,0,-2,-1,-2,-1,-2,-1,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,39,0,42,0,45,0,48,0,54,0,60,0,65,0,70,0,75,0,80,0,85,0,89,0,94,0,99,0,104,0,109,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-70,0,-65,0,-60,0,-55,0,-50,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,75,1,79,1,84,1,89,1,94,1,99,1,104,1,108,1,112,1,116,1,120,1,125,1,-126,1,27,91,51,74,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,91,49,59,50,65,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,109,117,108,120,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 // NOLINT
+};
+
+// win32con|ANSI emulation for libuv on legacy console,
+// auto_right_margin,
+// move_insert_mode,
+// move_standout_mode,
+// init_tabs#8,
+// max_colors#8,
+// max_pairs#64,
+// acs_chars@,
+// bell=^G,
+// carriage_return=\r,
+// clear_screen=\E[H\E[J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\E[B,
+// cursor_home=\E[H,
+// cursor_left=^H,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// delete_character@,
+// delete_line@,
+// enter_alt_charset_mode@,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E7\E[?47h,
+// enter_insert_mode@,
+// enter_pc_charset_mode@,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode@,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode@,
+// exit_alt_charset_mode@,
+// exit_attribute_mode=\E[0m,
+// exit_ca_mode=\E[2J\E[?47l\E8,
+// exit_insert_mode@,
+// exit_pc_charset_mode=\E[10m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode@,
+// from_status_line@,
+// insert_character@,
+// insert_line@,
+// key_b2=\E[G,
+// key_backspace=^H,
+// key_dc=\E[3~,
+// key_down=\E[B,
+// key_end=\E[4~,
+// key_f1=\E[[A,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[25~,
+// key_f14=\E[26~,
+// key_f15=\E[28~,
+// key_f16=\E[29~,
+// key_f17=\E[31~,
+// key_f18=\E[32~,
+// key_f19=\E[33~,
+// key_f2=\E[[B,
+// key_f20=\E[34~,
+// key_f21=\E[23$,
+// key_f22=\E[24$,
+// key_f23=\E[11\136,
+// key_f24=\E[12\136,
+// key_f25=\E[13\136,
+// key_f26=\E[14\136,
+// key_f27=\E[15\136,
+// key_f28=\E[17\136,
+// key_f29=\E[18\136,
+// key_f3=\E[[C,
+// key_f30=\E[19\136,
+// key_f31=\E[20\136,
+// key_f32=\E[21\136,
+// key_f33=\E[23\136,
+// key_f34=\E[24\136,
+// key_f35=\E[25\136,
+// key_f36=\E[26\136,
+// key_f37=\E[28\136,
+// key_f38=\E[29\136,
+// key_f39=\E[31\136,
+// key_f4=\E[[D,
+// key_f41=\E[32\136,
+// key_f42=\E[33\136,
+// key_f43=\E[34\136,
+// key_f44=\E[23@,
+// key_f45=\E[24@,
+// key_f5=\E[[E,
+// key_f6=\E[17~,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\E[1~,
+// key_ic=\E[2~,
+// key_left=\E[D,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\E[C,
+// key_sdc=\E[3;2~,
+// key_send=\E[4;2~,
+// key_shome=\E[1;2~,
+// key_sic=\E[2;2~,
+// key_sleft=\E[1;2D,
+// key_snext=\E[6;2~,
+// key_sprevious=\E[5;2~,
+// key_sright=\E[1;2C,
+// key_suspend=^Z,
+// key_up=\E[A,
+// newline=\r\n,
+// orig_pair=\E[39;49m,
+// parm_dch@,
+// parm_delete_line@,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich@,
+// parm_insert_line@,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_up_cursor=\E[%p1%dA,
+// reset_1string@,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward@,
+// scroll_reverse@,
+// set_a_background=\E[4%p1%dm,
+// set_a_foreground=\E[3%p1%dm,
+// set_attributes=\E[0%?%p1%t;7%;%?%p3%t;7%;%?%p6%t;1%;m,
+// tab=^I,
+// to_status_line@,
+// user6@,
+// user7@,
+// user8@,
+// user9@,
+static const int8_t win32con_terminfo[] = {
+ 26,1,52,0,15,0,15,0,125,1,106,2,119,105,110,51,50,99,111,110,124,65,78,83,73,32,101,109,117,108,97,116,105,111,110,32,102,111,114,32,108,105,98,117,118,32,111,110,32,108,101,103,97,99,121,32,99,111,110,115,111,108,101,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,-1,-1,8,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,8,0,64,0,-1,-1,0,0,2,0,-1,-1,-1,-1,4,0,11,0,15,0,19,0,-1,-1,30,0,47,0,51,0,-1,-1,55,0,-1,-1,-1,-1,57,0,-1,-1,61,0,-1,-1,-2,-1,-2,-1,-1,-1,-1,-1,-2,-1,-1,-1,65,0,70,0,-1,-1,-1,-1,-2,-1,-2,-1,-1,-1,79,0,84,0,-2,-1,-1,-1,-2,-1,89,0,94,0,-1,-1,-2,-1,107,0,-2,-1,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-1,-1,113,0,-1,-1,-1,-1,-1,-1,115,0,-1,-1,120,0,-1,-1,-1,-1,-1,-1,-1,-1,124,0,-127,0,-121,0,-116,0,-111,0,-106,0,-101,0,-95,0,-89,0,-83,0,-77,0,-72,0,-1,-1,-67,0,-1,-1,-63,0,-58,0,-53,0,-1,-1,-1,-1,-1,-1,-49,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-45,0,-1,-1,-2,-1,-2,-1,-42,0,-2,-1,-1,-1,-2,-1,-33,0,-24,0,-1,-1,-15,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-6,0,-3,0,8,1,-2,-1,-2,-1,11,1,-1,-1,-1,-1,49,1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,51,1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,55,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,60,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,1,-1,-1,-1,-1,69,1,-1,-1,-1,-1,-1,-1,-1,-1,76,1,83,1,90,1,-1,-1,-1,-1,97,1,-1,-1,104,1,-1,-1,-1,-1,-1,-1,111,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,118,1,124,1,-126,1,-120,1,-114,1,-108,1,-102,1,-96,1,-90,1,-84,1,-78,1,-72,1,-66,1,-60,1,-54,1,-48,1,-42,1,-36,1,-30,1,-24,1,-18,1,-12,1,-6,1,0,2,6,2,12,2,18,2,24,2,30,2,-1,-1,36,2,42,2,48,2,54,2,60,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,66,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,-2,-1,-2,-1,-2,-1,71,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,80,2,90,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-1,100,2,7,0,13,0,27,91,72,27,91,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,27,91,66,0,27,91,72,0,8,0,27,91,67,0,27,91,65,0,27,91,49,109,0,27,55,27,91,63,52,55,104,0,27,91,55,109,0,27,91,55,109,0,27,91,48,109,0,27,91,50,74,27,91,63,52,55,108,27,56,0,27,91,50,55,109,0,8,0,27,91,51,126,0,27,91,66,0,27,91,91,65,0,27,91,50,49,126,0,27,91,91,66,0,27,91,91,67,0,27,91,91,68,0,27,91,91,69,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,91,49,126,0,27,91,50,126,0,27,91,68,0,27,91,54,126,0,27,91,53,126,0,27,91,67,0,27,91,65,0,13,10,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,65,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,27,91,48,37,63,37,112,49,37,116,59,55,37,59,37,63,37,112,51,37,116,59,55,37,59,37,63,37,112,54,37,116,59,49,37,59,109,0,9,0,27,91,71,0,27,91,52,126,0,26,0,27,91,51,59,50,126,0,27,91,52,59,50,126,0,27,91,49,59,50,126,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,50,53,126,0,27,91,50,54,126,0,27,91,50,56,126,0,27,91,50,57,126,0,27,91,51,49,126,0,27,91,51,50,126,0,27,91,51,51,126,0,27,91,51,52,126,0,27,91,50,51,36,0,27,91,50,52,36,0,27,91,49,49,94,0,27,91,49,50,94,0,27,91,49,51,94,0,27,91,49,52,94,0,27,91,49,53,94,0,27,91,49,55,94,0,27,91,49,56,94,0,27,91,49,57,94,0,27,91,50,48,94,0,27,91,50,49,94,0,27,91,50,51,94,0,27,91,50,52,94,0,27,91,50,53,94,0,27,91,50,54,94,0,27,91,50,56,94,0,27,91,50,57,94,0,27,91,51,49,94,0,27,91,51,50,94,0,27,91,51,51,94,0,27,91,51,52,94,0,27,91,50,51,64,0,27,91,50,52,64,0,27,91,49,75,0,27,91,51,57,59,52,57,109,0,27,91,51,37,112,49,37,100,109,0,27,91,52,37,112,49,37,100,109,0,27,91,49,48,109,0,1,0,0,0,2,0,5,0,25,0,0,0,0,0,6,0,0,0,3,0,6,0,27,91,48,32,113,0,27,91,37,112,49,37,100,32,113,0,65,88,0,83,101,0,83,115,0 // NOLINT
+};
+
+// xterm-256color|xterm with 256 colors,
+// auto_right_margin,
+// back_color_erase,
+// backspaces_with_bs,
+// can_change,
+// eat_newline_glitch,
+// has_meta_key,
+// move_insert_mode,
+// move_standout_mode,
+// no_pad_char,
+// prtr_silent,
+// columns#80,
+// init_tabs#8,
+// lines#24,
+// max_colors#0x100,
+// max_pairs#0x10000,
+// acs_chars=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+// back_tab=\E[Z,
+// bell=^G,
+// carriage_return=\r,
+// change_scroll_region=\E[%i%p1%d;%p2%dr,
+// clear_all_tabs=\E[3g,
+// clear_screen=\E[H\E[2J,
+// clr_bol=\E[1K,
+// clr_eol=\E[K,
+// clr_eos=\E[J,
+// column_address=\E[%i%p1%dG,
+// cursor_address=\E[%i%p1%d;%p2%dH,
+// cursor_down=\n,
+// cursor_home=\E[H,
+// cursor_invisible=\E[?25l,
+// cursor_left=^H,
+// cursor_normal=\E[?12l\E[?25h,
+// cursor_right=\E[C,
+// cursor_up=\E[A,
+// cursor_visible=\E[?12;25h,
+// delete_character=\E[P,
+// delete_line=\E[M,
+// enter_alt_charset_mode=\E(0,
+// enter_am_mode=\E[?7h,
+// enter_blink_mode=\E[5m,
+// enter_bold_mode=\E[1m,
+// enter_ca_mode=\E[?1049h\E[22;0;0t,
+// enter_dim_mode=\E[2m,
+// enter_insert_mode=\E[4h,
+// enter_italics_mode=\E[3m,
+// enter_reverse_mode=\E[7m,
+// enter_secure_mode=\E[8m,
+// enter_standout_mode=\E[7m,
+// enter_underline_mode=\E[4m,
+// erase_chars=\E[%p1%dX,
+// exit_alt_charset_mode=\E(B,
+// exit_am_mode=\E[?7l,
+// exit_attribute_mode=\E(B\E[m,
+// exit_ca_mode=\E[?1049l\E[23;0;0t,
+// exit_insert_mode=\E[4l,
+// exit_italics_mode=\E[23m,
+// exit_standout_mode=\E[27m,
+// exit_underline_mode=\E[24m,
+// flash_screen=\E[?5h$<100/>\E[?5l,
+// init_2string=\E[\041p\E[?3;4l\E[4l\E>,
+// initialize_color=\E]4;%p1%d;rgb\072%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\,
+// insert_line=\E[L,
+// key_b2=\EOE,
+// key_backspace=^H,
+// key_btab=\E[Z,
+// key_dc=\E[3~,
+// key_down=\EOB,
+// key_end=\EOF,
+// key_enter=\EOM,
+// key_f1=\EOP,
+// key_f10=\E[21~,
+// key_f11=\E[23~,
+// key_f12=\E[24~,
+// key_f13=\E[1;2P,
+// key_f14=\E[1;2Q,
+// key_f15=\E[1;2R,
+// key_f16=\E[1;2S,
+// key_f17=\E[15;2~,
+// key_f18=\E[17;2~,
+// key_f19=\E[18;2~,
+// key_f2=\EOQ,
+// key_f20=\E[19;2~,
+// key_f21=\E[20;2~,
+// key_f22=\E[21;2~,
+// key_f23=\E[23;2~,
+// key_f24=\E[24;2~,
+// key_f25=\E[1;5P,
+// key_f26=\E[1;5Q,
+// key_f27=\E[1;5R,
+// key_f28=\E[1;5S,
+// key_f29=\E[15;5~,
+// key_f3=\EOR,
+// key_f30=\E[17;5~,
+// key_f31=\E[18;5~,
+// key_f32=\E[19;5~,
+// key_f33=\E[20;5~,
+// key_f34=\E[21;5~,
+// key_f35=\E[23;5~,
+// key_f36=\E[24;5~,
+// key_f37=\E[1;6P,
+// key_f38=\E[1;6Q,
+// key_f39=\E[1;6R,
+// key_f4=\EOS,
+// key_f40=\E[1;6S,
+// key_f41=\E[15;6~,
+// key_f42=\E[17;6~,
+// key_f43=\E[18;6~,
+// key_f44=\E[19;6~,
+// key_f45=\E[20;6~,
+// key_f46=\E[21;6~,
+// key_f47=\E[23;6~,
+// key_f48=\E[24;6~,
+// key_f49=\E[1;3P,
+// key_f5=\E[15~,
+// key_f50=\E[1;3Q,
+// key_f51=\E[1;3R,
+// key_f52=\E[1;3S,
+// key_f53=\E[15;3~,
+// key_f54=\E[17;3~,
+// key_f55=\E[18;3~,
+// key_f56=\E[19;3~,
+// key_f57=\E[20;3~,
+// key_f58=\E[21;3~,
+// key_f59=\E[23;3~,
+// key_f6=\E[17~,
+// key_f60=\E[24;3~,
+// key_f61=\E[1;4P,
+// key_f62=\E[1;4Q,
+// key_f63=\E[1;4R,
+// key_f7=\E[18~,
+// key_f8=\E[19~,
+// key_f9=\E[20~,
+// key_home=\EOH,
+// key_ic=\E[2~,
+// key_left=\EOD,
+// key_mouse=\E[<,
+// key_npage=\E[6~,
+// key_ppage=\E[5~,
+// key_right=\EOC,
+// key_sdc=\E[3;2~,
+// key_send=\E[1;2F,
+// key_sf=\E[1;2B,
+// key_shome=\E[1;2H,
+// key_sic=\E[2;2~,
+// key_sleft=\E[1;2D,
+// key_snext=\E[6;2~,
+// key_sprevious=\E[5;2~,
+// key_sr=\E[1;2A,
+// key_sright=\E[1;2C,
+// key_up=\EOA,
+// keypad_local=\E[?1l\E>,
+// keypad_xmit=\E[?1h\E=,
+// memory_lock=\El,
+// memory_unlock=\Em,
+// meta_off=\E[?1034l,
+// meta_on=\E[?1034h,
+// orig_colors=\E]104^G,
+// orig_pair=\E[39;49m,
+// parm_dch=\E[%p1%dP,
+// parm_delete_line=\E[%p1%dM,
+// parm_down_cursor=\E[%p1%dB,
+// parm_ich=\E[%p1%d@,
+// parm_index=\E[%p1%dS,
+// parm_insert_line=\E[%p1%dL,
+// parm_left_cursor=\E[%p1%dD,
+// parm_right_cursor=\E[%p1%dC,
+// parm_rindex=\E[%p1%dT,
+// parm_up_cursor=\E[%p1%dA,
+// print_screen=\E[i,
+// prtr_off=\E[4i,
+// prtr_on=\E[5i,
+// repeat_char=%p1%c\E[%p2%{1}%-%db,
+// reset_1string=\Ec\E]104^G,
+// reset_2string=\E[\041p\E[?3;4l\E[4l\E>,
+// restore_cursor=\E8,
+// row_address=\E[%i%p1%dd,
+// save_cursor=\E7,
+// scroll_forward=\n,
+// scroll_reverse=\EM,
+// set_a_background=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
+// set_a_foreground=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
+// set_attributes=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
+// set_tab=\EH,
+// tab=^I,
+// user6=\E[%i%d;%dR,
+// user7=\E[6n,
+// user8=\E[?%[;0123456789]c,
+// user9=\E[c,
+static const int8_t xterm_256colour_terminfo[] = {
+ 30,2,37,0,38,0,15,0,-99,1,2,6,120,116,101,114,109,45,50,53,54,99,111,108,111,114,124,120,116,101,114,109,32,119,105,116,104,32,50,53,54,32,99,111,108,111,114,115,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0,80,0,0,0,8,0,0,0,24,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,0,0,0,0,1,0,0,0,4,0,6,0,8,0,25,0,30,0,38,0,42,0,46,0,-1,-1,57,0,74,0,76,0,80,0,87,0,-1,-1,89,0,102,0,-1,-1,106,0,110,0,120,0,124,0,-1,-1,-1,-1,-128,0,-124,0,-119,0,-114,0,-1,-1,-96,0,-91,0,-86,0,-1,-1,-81,0,-76,0,-71,0,-66,0,-57,0,-53,0,-46,0,-1,-1,-28,0,-23,0,-17,0,-11,0,-1,-1,-1,-1,-1,-1,7,1,-1,-1,-1,-1,-1,-1,25,1,-1,-1,29,1,-1,-1,-1,-1,-1,-1,31,1,-1,-1,36,1,-1,-1,-1,-1,-1,-1,-1,-1,40,1,44,1,50,1,54,1,58,1,62,1,68,1,74,1,80,1,86,1,92,1,96,1,-1,-1,101,1,-1,-1,105,1,110,1,115,1,119,1,126,1,-1,-1,-123,1,-119,1,-111,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-103,1,-94,1,-1,-1,-1,-1,-85,1,-76,1,-67,1,-58,1,-49,1,-40,1,-31,1,-22,1,-13,1,-4,1,-1,-1,-1,-1,-1,-1,5,2,9,2,14,2,19,2,39,2,48,2,-1,-1,-1,-1,66,2,69,2,80,2,83,2,85,2,88,2,-75,2,-1,-1,-72,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-70,2,-1,-1,-1,-1,-1,-1,-1,-1,-66,2,-1,-1,-13,2,-1,-1,-1,-1,-9,2,-3,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,3,7,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,3,-1,-1,-1,-1,18,3,-1,-1,-1,-1,-1,-1,-1,-1,25,3,32,3,39,3,-1,-1,-1,-1,46,3,-1,-1,53,3,-1,-1,-1,-1,-1,-1,60,3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,67,3,73,3,79,3,86,3,93,3,100,3,107,3,115,3,123,3,-125,3,-117,3,-109,3,-101,3,-93,3,-85,3,-78,3,-71,3,-64,3,-57,3,-49,3,-41,3,-33,3,-25,3,-17,3,-9,3,-1,3,7,4,14,4,21,4,28,4,35,4,43,4,51,4,59,4,67,4,75,4,83,4,91,4,99,4,106,4,113,4,120,4,127,4,-121,4,-113,4,-105,4,-97,4,-89,4,-81,4,-73,4,-65,4,-58,4,-51,4,-44,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-39,4,-28,4,-23,4,-4,4,0,5,9,5,16,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,110,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,115,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,121,5,-1,-1,-1,-1,-1,-1,125,5,-68,5,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-4,5,-1,5,27,91,90,0,7,0,13,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,114,0,27,91,51,103,0,27,91,72,27,91,50,74,0,27,91,75,0,27,91,74,0,27,91,37,105,37,112,49,37,100,71,0,27,91,37,105,37,112,49,37,100,59,37,112,50,37,100,72,0,10,0,27,91,72,0,27,91,63,50,53,108,0,8,0,27,91,63,49,50,108,27,91,63,50,53,104,0,27,91,67,0,27,91,65,0,27,91,63,49,50,59,50,53,104,0,27,91,80,0,27,91,77,0,27,40,48,0,27,91,53,109,0,27,91,49,109,0,27,91,63,49,48,52,57,104,27,91,50,50,59,48,59,48,116,0,27,91,50,109,0,27,91,52,104,0,27,91,56,109,0,27,91,55,109,0,27,91,55,109,0,27,91,52,109,0,27,91,37,112,49,37,100,88,0,27,40,66,0,27,40,66,27,91,109,0,27,91,63,49,48,52,57,108,27,91,50,51,59,48,59,48,116,0,27,91,52,108,0,27,91,50,55,109,0,27,91,50,52,109,0,27,91,63,53,104,36,60,49,48,48,47,62,27,91,63,53,108,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,0,27,91,76,0,8,0,27,91,51,126,0,27,79,66,0,27,79,80,0,27,91,50,49,126,0,27,79,81,0,27,79,82,0,27,79,83,0,27,91,49,53,126,0,27,91,49,55,126,0,27,91,49,56,126,0,27,91,49,57,126,0,27,91,50,48,126,0,27,79,72,0,27,91,50,126,0,27,79,68,0,27,91,54,126,0,27,91,53,126,0,27,79,67,0,27,91,49,59,50,66,0,27,91,49,59,50,65,0,27,79,65,0,27,91,63,49,108,27,62,0,27,91,63,49,104,27,61,0,27,91,63,49,48,51,52,108,0,27,91,63,49,48,51,52,104,0,27,91,37,112,49,37,100,80,0,27,91,37,112,49,37,100,77,0,27,91,37,112,49,37,100,66,0,27,91,37,112,49,37,100,64,0,27,91,37,112,49,37,100,83,0,27,91,37,112,49,37,100,76,0,27,91,37,112,49,37,100,68,0,27,91,37,112,49,37,100,67,0,27,91,37,112,49,37,100,84,0,27,91,37,112,49,37,100,65,0,27,91,105,0,27,91,52,105,0,27,91,53,105,0,37,112,49,37,99,27,91,37,112,50,37,123,49,125,37,45,37,100,98,0,27,99,27,93,49,48,52,7,0,27,91,33,112,27,91,63,51,59,52,108,27,91,52,108,27,62,0,27,56,0,27,91,37,105,37,112,49,37,100,100,0,27,55,0,10,0,27,77,0,37,63,37,112,57,37,116,27,40,48,37,101,27,40,66,37,59,27,91,48,37,63,37,112,54,37,116,59,49,37,59,37,63,37,112,53,37,116,59,50,37,59,37,63,37,112,50,37,116,59,52,37,59,37,63,37,112,49,37,112,51,37,124,37,116,59,55,37,59,37,63,37,112,52,37,116,59,53,37,59,37,63,37,112,55,37,116,59,56,37,59,109,0,27,72,0,9,0,27,79,69,0,96,96,97,97,102,102,103,103,105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112,113,113,114,114,115,115,116,116,117,117,118,118,119,119,120,120,121,121,122,122,123,123,124,124,125,125,126,126,0,27,91,90,0,27,91,63,55,104,0,27,91,63,55,108,0,27,79,70,0,27,79,77,0,27,91,51,59,50,126,0,27,91,49,59,50,70,0,27,91,49,59,50,72,0,27,91,50,59,50,126,0,27,91,49,59,50,68,0,27,91,54,59,50,126,0,27,91,53,59,50,126,0,27,91,49,59,50,67,0,27,91,50,51,126,0,27,91,50,52,126,0,27,91,49,59,50,80,0,27,91,49,59,50,81,0,27,91,49,59,50,82,0,27,91,49,59,50,83,0,27,91,49,53,59,50,126,0,27,91,49,55,59,50,126,0,27,91,49,56,59,50,126,0,27,91,49,57,59,50,126,0,27,91,50,48,59,50,126,0,27,91,50,49,59,50,126,0,27,91,50,51,59,50,126,0,27,91,50,52,59,50,126,0,27,91,49,59,53,80,0,27,91,49,59,53,81,0,27,91,49,59,53,82,0,27,91,49,59,53,83,0,27,91,49,53,59,53,126,0,27,91,49,55,59,53,126,0,27,91,49,56,59,53,126,0,27,91,49,57,59,53,126,0,27,91,50,48,59,53,126,0,27,91,50,49,59,53,126,0,27,91,50,51,59,53,126,0,27,91,50,52,59,53,126,0,27,91,49,59,54,80,0,27,91,49,59,54,81,0,27,91,49,59,54,82,0,27,91,49,59,54,83,0,27,91,49,53,59,54,126,0,27,91,49,55,59,54,126,0,27,91,49,56,59,54,126,0,27,91,49,57,59,54,126,0,27,91,50,48,59,54,126,0,27,91,50,49,59,54,126,0,27,91,50,51,59,54,126,0,27,91,50,52,59,54,126,0,27,91,49,59,51,80,0,27,91,49,59,51,81,0,27,91,49,59,51,82,0,27,91,49,59,51,83,0,27,91,49,53,59,51,126,0,27,91,49,55,59,51,126,0,27,91,49,56,59,51,126,0,27,91,49,57,59,51,126,0,27,91,50,48,59,51,126,0,27,91,50,49,59,51,126,0,27,91,50,51,59,51,126,0,27,91,50,52,59,51,126,0,27,91,49,59,52,80,0,27,91,49,59,52,81,0,27,91,49,59,52,82,0,27,91,49,75,0,27,91,37,105,37,100,59,37,100,82,0,27,91,54,110,0,27,91,63,37,91,59,48,49,50,51,52,53,54,55,56,57,93,99,0,27,91,99,0,27,91,51,57,59,52,57,109,0,27,93,49,48,52,7,0,27,93,52,59,37,112,49,37,100,59,114,103,98,58,37,112,50,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,51,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,47,37,112,52,37,123,50,53,53,125,37,42,37,123,49,48,48,48,125,37,47,37,50,46,50,88,27,92,0,27,91,51,109,0,27,91,50,51,109,0,27,91,60,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,51,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,57,37,112,49,37,123,56,125,37,45,37,100,37,101,51,56,59,53,59,37,112,49,37,100,37,59,109,0,27,91,37,63,37,112,49,37,123,56,125,37,60,37,116,52,37,112,49,37,100,37,101,37,112,49,37,123,49,54,125,37,60,37,116,49,48,37,112,49,37,123,56,125,37,45,37,100,37,101,52,56,59,53,59,37,112,49,37,100,37,59,109,0,27,108,0,27,109,0,3,0,1,0,73,0,-106,0,115,3,1,0,1,0,-1,-1,-1,-1,0,0,7,0,-1,-1,19,0,24,0,-1,-1,42,0,48,0,-1,-1,58,0,-1,-1,-1,-1,90,0,97,0,104,0,111,0,118,0,125,0,-124,0,-117,0,-110,0,-103,0,-96,0,-89,0,-82,0,-75,0,-68,0,-61,0,-1,-1,-54,0,-47,0,-40,0,-33,0,-26,0,-1,-1,-19,0,-12,0,-5,0,2,1,9,1,16,1,23,1,30,1,37,1,44,1,51,1,58,1,65,1,72,1,79,1,86,1,93,1,100,1,107,1,114,1,121,1,-128,1,-121,1,-114,1,-107,1,-100,1,-93,1,-86,1,-79,1,-72,1,-65,1,-1,-1,-1,-1,-1,-1,-1,-1,-58,1,-52,1,-47,1,0,0,3,0,6,0,9,0,12,0,15,0,18,0,21,0,24,0,27,0,30,0,33,0,36,0,39,0,42,0,48,0,54,0,59,0,64,0,69,0,74,0,79,0,83,0,88,0,93,0,98,0,103,0,108,0,114,0,120,0,126,0,-124,0,-118,0,-112,0,-106,0,-100,0,-94,0,-88,0,-82,0,-76,0,-71,0,-66,0,-61,0,-56,0,-51,0,-45,0,-39,0,-33,0,-27,0,-21,0,-15,0,-9,0,-3,0,3,1,9,1,15,1,21,1,27,1,33,1,39,1,45,1,51,1,57,1,63,1,69,1,73,1,78,1,83,1,88,1,93,1,98,1,102,1,106,1,110,1,114,1,119,1,124,1,27,93,49,49,50,7,0,27,93,49,50,59,37,112,49,37,115,7,0,27,91,51,74,0,27,93,53,50,59,37,112,49,37,115,59,37,112,50,37,115,7,0,27,91,50,32,113,0,27,91,37,112,49,37,100,32,113,0,27,91,63,49,48,48,54,59,49,48,48,48,37,63,37,112,49,37,123,49,125,37,61,37,116,104,37,101,108,37,59,0,27,91,51,59,51,126,0,27,91,51,59,52,126,0,27,91,51,59,53,126,0,27,91,51,59,54,126,0,27,91,51,59,55,126,0,27,91,49,59,50,66,0,27,91,49,59,51,66,0,27,91,49,59,52,66,0,27,91,49,59,53,66,0,27,91,49,59,54,66,0,27,91,49,59,55,66,0,27,91,49,59,51,70,0,27,91,49,59,52,70,0,27,91,49,59,53,70,0,27,91,49,59,54,70,0,27,91,49,59,55,70,0,27,91,49,59,51,72,0,27,91,49,59,52,72,0,27,91,49,59,53,72,0,27,91,49,59,54,72,0,27,91,49,59,55,72,0,27,91,50,59,51,126,0,27,91,50,59,52,126,0,27,91,50,59,53,126,0,27,91,50,59,54,126,0,27,91,50,59,55,126,0,27,91,49,59,51,68,0,27,91,49,59,52,68,0,27,91,49,59,53,68,0,27,91,49,59,54,68,0,27,91,49,59,55,68,0,27,91,54,59,51,126,0,27,91,54,59,52,126,0,27,91,54,59,53,126,0,27,91,54,59,54,126,0,27,91,54,59,55,126,0,27,91,53,59,51,126,0,27,91,53,59,52,126,0,27,91,53,59,53,126,0,27,91,53,59,54,126,0,27,91,53,59,55,126,0,27,91,49,59,51,67,0,27,91,49,59,52,67,0,27,91,49,59,53,67,0,27,91,49,59,54,67,0,27,91,49,59,55,67,0,27,91,49,59,50,65,0,27,91,49,59,51,65,0,27,91,49,59,52,65,0,27,91,49,59,53,65,0,27,91,49,59,54,65,0,27,91,49,59,55,65,0,27,91,50,57,109,0,27,91,57,109,0,27,91,60,37,112,49,37,100,59,37,112,50,37,100,59,37,112,51,37,100,59,37,63,37,112,52,37,116,77,37,101,109,37,59,0,65,88,0,71,48,0,88,84,0,85,56,0,67,114,0,67,115,0,69,48,0,69,51,0,77,115,0,83,48,0,83,101,0,83,115,0,84,83,0,88,77,0,103,114,98,111,109,0,103,115,98,111,109,0,107,68,67,51,0,107,68,67,52,0,107,68,67,53,0,107,68,67,54,0,107,68,67,55,0,107,68,78,0,107,68,78,51,0,107,68,78,52,0,107,68,78,53,0,107,68,78,54,0,107,68,78,55,0,107,69,78,68,51,0,107,69,78,68,52,0,107,69,78,68,53,0,107,69,78,68,54,0,107,69,78,68,55,0,107,69,78,68,56,0,107,72,79,77,51,0,107,72,79,77,52,0,107,72,79,77,53,0,107,72,79,77,54,0,107,72,79,77,55,0,107,72,79,77,56,0,107,73,67,51,0,107,73,67,52,0,107,73,67,53,0,107,73,67,54,0,107,73,67,55,0,107,76,70,84,51,0,107,76,70,84,52,0,107,76,70,84,53,0,107,76,70,84,54,0,107,76,70,84,55,0,107,78,88,84,51,0,107,78,88,84,52,0,107,78,88,84,53,0,107,78,88,84,54,0,107,78,88,84,55,0,107,80,82,86,51,0,107,80,82,86,52,0,107,80,82,86,53,0,107,80,82,86,54,0,107,80,82,86,55,0,107,82,73,84,51,0,107,82,73,84,52,0,107,82,73,84,53,0,107,82,73,84,54,0,107,82,73,84,55,0,107,85,80,0,107,85,80,51,0,107,85,80,52,0,107,85,80,53,0,107,85,80,54,0,107,85,80,55,0,107,97,50,0,107,98,49,0,107,98,51,0,107,99,50,0,114,109,120,120,0,115,109,120,120,0,120,109,0 // NOLINT
+};
+#endif // NVIM_TUI_TERMINFO_DEFS_H
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index c4efa69c4c..dbffabd707 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1,3 +1,8 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+// Terminal UI functions. Invoked (by ui_bridge.c) on the TUI thread.
+
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
@@ -5,31 +10,60 @@
#include <uv.h>
#include <unibilium.h>
+#if defined(HAVE_TERMIOS_H)
+# include <termios.h>
+#endif
#include "nvim/lib/kvec.h"
+#include "nvim/ascii.h"
#include "nvim/vim.h"
+#include "nvim/log.h"
#include "nvim/ui.h"
+#include "nvim/highlight.h"
#include "nvim/map.h"
#include "nvim/main.h"
#include "nvim/memory.h"
+#include "nvim/option.h"
#include "nvim/api/vim.h"
#include "nvim/api/private/helpers.h"
#include "nvim/event/loop.h"
#include "nvim/event/signal.h"
-#include "nvim/tui/tui.h"
-#include "nvim/tui/input.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
+#include "nvim/os/tty.h"
#include "nvim/strings.h"
-#include "nvim/ugrid.h"
+#include "nvim/syntax.h"
#include "nvim/ui_bridge.h"
+#include "nvim/ugrid.h"
+#include "nvim/tui/input.h"
+#include "nvim/tui/tui.h"
+#include "nvim/tui/terminfo.h"
+#include "nvim/cursor_shape.h"
+#include "nvim/macros.h"
-// Space reserved in the output buffer to restore the cursor to normal when
-// flushing. No existing terminal will require 32 bytes to do that.
+// Space reserved in two output buffers to make the cursor normal or invisible
+// when flushing. No existing terminal will require 32 bytes to do that.
#define CNORM_COMMAND_MAX_SIZE 32
#define OUTBUF_SIZE 0xffff
+#define TOO_MANY_EVENTS 1000000
+#define STARTS_WITH(str, prefix) (strlen(str) >= (sizeof(prefix) - 1) \
+ && 0 == memcmp((str), (prefix), sizeof(prefix) - 1))
+#define TMUX_WRAP(is_tmux, seq) ((is_tmux) \
+ ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
+#define LINUXSET0C "\x1b[?0c"
+#define LINUXSET1C "\x1b[?1c"
+
+#ifdef NVIM_UNIBI_HAS_VAR_FROM
+#define UNIBI_SET_NUM_VAR(var, num) \
+ do { \
+ (var) = unibi_var_from_num((num)); \
+ } while (0)
+#else
+#define UNIBI_SET_NUM_VAR(var, num) (var).i = (num);
+#endif
+
typedef struct {
int top, bot, left, right;
} Rect;
@@ -37,10 +71,12 @@ typedef struct {
typedef struct {
UIBridgeData *bridge;
Loop *loop;
- bool stop;
unibi_var_t params[9];
char buf[OUTBUF_SIZE];
- size_t bufpos, bufsize;
+ size_t bufpos;
+ char norm[CNORM_COMMAND_MAX_SIZE];
+ char invis[CNORM_COMMAND_MAX_SIZE];
+ size_t normlen, invislen;
TermInput input;
uv_loop_t write_loop;
unibi_term *ut;
@@ -51,28 +87,49 @@ typedef struct {
bool out_isatty;
SignalWatcher winch_handle, cont_handle;
bool cont_received;
- // Event scheduled by the ui bridge. Since the main thread suspends until
- // the event is handled, it is fine to use a single field instead of a queue
- Event scheduled_event;
UGrid grid;
kvec_t(Rect) invalid_regions;
+ int row, col;
int out_fd;
- bool can_use_terminal_scroll;
+ bool scroll_region_is_full_screen;
+ bool can_change_scroll_region;
+ bool can_set_lr_margin;
+ bool can_set_left_right_margin;
+ bool can_scroll;
+ bool can_erase_chars;
+ bool immediate_wrap_after_last_column;
+ bool bce;
bool mouse_enabled;
- bool busy;
- HlAttrs print_attrs;
- int showing_mode;
+ bool busy, is_invisible;
+ bool cork, overflow;
+ bool cursor_color_changed;
+ cursorentry_T cursor_shapes[SHAPE_IDX_COUNT];
+ HlAttrs clear_attrs;
+ kvec_t(HlAttrs) attrs;
+ int print_attr_id;
+ bool default_attr;
+ bool can_clear_attr;
+ ModeShape showing_mode;
struct {
int enable_mouse, disable_mouse;
int enable_bracketed_paste, disable_bracketed_paste;
- int enter_insert_mode, enter_replace_mode, exit_insert_mode;
+ int enable_lr_margin, disable_lr_margin;
int set_rgb_foreground, set_rgb_background;
+ int set_cursor_color;
+ int reset_cursor_color;
int enable_focus_reporting, disable_focus_reporting;
+ int resize_screen;
+ int reset_scroll_region;
+ int set_cursor_style, reset_cursor_style;
+ int save_title, restore_title;
+ int enter_undercurl_mode, exit_undercurl_mode, set_underline_color;
int get_bg;
} unibi_ext;
+ char *space_buf;
} TUIData;
static bool volatile got_winch = false;
+static bool cursor_style_enabled = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tui/tui.c.generated.h"
@@ -81,77 +138,162 @@ static bool volatile got_winch = false;
UI *tui_start(void)
{
- UI *ui = xcalloc(1, sizeof(UI));
+ UI *ui = xcalloc(1, sizeof(UI)); // Freed by ui_bridge_stop().
ui->stop = tui_stop;
- ui->rgb = p_tgc;
- ui->resize = tui_resize;
- ui->clear = tui_clear;
- ui->eol_clear = tui_eol_clear;
- ui->cursor_goto = tui_cursor_goto;
+ ui->grid_resize = tui_grid_resize;
+ ui->grid_clear = tui_grid_clear;
+ ui->grid_cursor_goto = tui_grid_cursor_goto;
+ ui->mode_info_set = tui_mode_info_set;
ui->update_menu = tui_update_menu;
ui->busy_start = tui_busy_start;
ui->busy_stop = tui_busy_stop;
ui->mouse_on = tui_mouse_on;
ui->mouse_off = tui_mouse_off;
ui->mode_change = tui_mode_change;
- ui->set_scroll_region = tui_set_scroll_region;
- ui->scroll = tui_scroll;
- ui->highlight_set = tui_highlight_set;
- ui->put = tui_put;
+ ui->grid_scroll = tui_grid_scroll;
+ ui->hl_attr_define = tui_hl_attr_define;
ui->bell = tui_bell;
ui->visual_bell = tui_visual_bell;
- ui->update_fg = tui_update_fg;
- ui->update_bg = tui_update_bg;
- ui->update_sp = tui_update_sp;
+ ui->default_colors_set = tui_default_colors_set;
ui->flush = tui_flush;
ui->suspend = tui_suspend;
ui->set_title = tui_set_title;
ui->set_icon = tui_set_icon;
+ ui->option_set= tui_option_set;
+ ui->raw_line = tui_raw_line;
+
+ memset(ui->ui_ext, 0, sizeof(ui->ui_ext));
+ ui->ui_ext[kUILinegrid] = true;
+
return ui_bridge_attach(ui, tui_main, tui_scheduler);
}
+static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index,
+ char * buf, size_t len)
+{
+ const char *str = unibi_get_str(data->ut, unibi_index);
+ if (!str) {
+ return 0U;
+ }
+ return unibi_run(str, data->params, buf, len);
+}
+
+static void termname_set_event(void **argv)
+{
+ char *termname = argv[0];
+ set_tty_option("term", termname);
+ // Do not free termname, it is freed by set_tty_option.
+}
+
static void terminfo_start(UI *ui)
{
TUIData *data = ui->data;
- data->can_use_terminal_scroll = true;
+ data->scroll_region_is_full_screen = true;
data->bufpos = 0;
- data->bufsize = sizeof(data->buf) - CNORM_COMMAND_MAX_SIZE;
- data->showing_mode = 0;
+ data->default_attr = false;
+ data->can_clear_attr = false;
+ data->is_invisible = true;
+ data->busy = false;
+ data->cork = false;
+ data->overflow = false;
+ data->cursor_color_changed = false;
+ data->showing_mode = SHAPE_IDX_N;
data->unibi_ext.enable_mouse = -1;
data->unibi_ext.disable_mouse = -1;
+ data->unibi_ext.set_cursor_color = -1;
+ data->unibi_ext.reset_cursor_color = -1;
data->unibi_ext.enable_bracketed_paste = -1;
data->unibi_ext.disable_bracketed_paste = -1;
- data->unibi_ext.enter_insert_mode = -1;
- data->unibi_ext.enter_replace_mode = -1;
- data->unibi_ext.exit_insert_mode = -1;
+ data->unibi_ext.enable_lr_margin = -1;
+ data->unibi_ext.disable_lr_margin = -1;
data->unibi_ext.enable_focus_reporting = -1;
data->unibi_ext.disable_focus_reporting = -1;
+ data->unibi_ext.resize_screen = -1;
+ data->unibi_ext.reset_scroll_region = -1;
+ data->unibi_ext.set_cursor_style = -1;
+ data->unibi_ext.reset_cursor_style = -1;
data->unibi_ext.get_bg = -1;
data->out_fd = 1;
data->out_isatty = os_isatty(data->out_fd);
- // setup unibilium
+
+ const char *term = os_getenv("TERM");
+#ifdef WIN32
+ os_tty_guess_term(&term, data->out_fd);
+ os_setenv("TERM", term, 1);
+#endif
+
+ // Set up unibilium/terminfo.
data->ut = unibi_from_env();
- if (!data->ut) {
- // For some reason could not read terminfo file, use a dummy entry that
- // will be populated with common values by fix_terminfo below
- data->ut = unibi_dummy();
+ char *termname = NULL;
+ if (!term || !data->ut) {
+ data->ut = terminfo_from_builtin(term, &termname);
+ } else {
+ termname = xstrdup(term);
}
- fix_terminfo(data);
+ // Update 'term' option.
+ loop_schedule_deferred(&main_loop,
+ event_create(termname_set_event, 1, termname));
+
+ // None of the following work over SSH; see :help TERM .
+ const char *colorterm = os_getenv("COLORTERM");
+ const char *termprg = os_getenv("TERM_PROGRAM");
+ const char *vte_version_env = os_getenv("VTE_VERSION");
+ long vtev = vte_version_env ? strtol(vte_version_env, NULL, 10) : 0;
+ bool iterm_env = termprg && strstr(termprg, "iTerm.app");
+ bool konsole = terminfo_is_term_family(term, "konsole")
+ || os_getenv("KONSOLE_PROFILE_NAME")
+ || os_getenv("KONSOLE_DBUS_SESSION");
+ const char *konsolev_env = os_getenv("KONSOLE_VERSION");
+ long konsolev = konsolev_env ? strtol(konsolev_env, NULL, 10)
+ : (konsole ? 1 : 0);
+
+ patch_terminfo_bugs(data, term, colorterm, vtev, konsolev, iterm_env);
+ augment_terminfo(data, term, colorterm, vtev, konsolev, iterm_env);
+ data->can_change_scroll_region =
+ !!unibi_get_str(data->ut, unibi_change_scroll_region);
+ data->can_set_lr_margin =
+ !!unibi_get_str(data->ut, unibi_set_lr_margin);
+ data->can_set_left_right_margin =
+ !!unibi_get_str(data->ut, unibi_set_left_margin_parm)
+ && !!unibi_get_str(data->ut, unibi_set_right_margin_parm);
+ data->can_scroll =
+ !!unibi_get_str(data->ut, unibi_delete_line)
+ && !!unibi_get_str(data->ut, unibi_parm_delete_line)
+ && !!unibi_get_str(data->ut, unibi_insert_line)
+ && !!unibi_get_str(data->ut, unibi_parm_insert_line);
+ data->can_erase_chars = !!unibi_get_str(data->ut, unibi_erase_chars);
+ data->immediate_wrap_after_last_column =
+ terminfo_is_term_family(term, "conemu")
+ || terminfo_is_term_family(term, "cygwin")
+ || terminfo_is_term_family(term, "win32con")
+ || terminfo_is_term_family(term, "interix");
+ data->bce = unibi_get_bool(data->ut, unibi_back_color_erase);
+ data->normlen = unibi_pre_fmt_str(data, unibi_cursor_normal,
+ data->norm, sizeof data->norm);
+ data->invislen = unibi_pre_fmt_str(data, unibi_cursor_invisible,
+ data->invis, sizeof data->invis);
// Set 't_Co' from the result of unibilium & fix_terminfo.
t_colors = unibi_get_num(data->ut, unibi_max_colors);
- // Enter alternate screen and clear
+ // Enter alternate screen, save title, and clear.
+ // NOTE: Do this *before* changing terminal settings. #6433
unibi_out(ui, unibi_enter_ca_mode);
+ // Save title/icon to the "stack". #4063
+ unibi_out_ext(ui, data->unibi_ext.save_title);
+ unibi_out(ui, unibi_keypad_xmit);
unibi_out(ui, unibi_clear_screen);
- // Ask the terminal to send us the background color
- unibi_out(ui, data->unibi_ext.get_bg);
+ // Ask the terminal to send us the background color.
+ unibi_out_ext(ui, data->unibi_ext.get_bg);
// Enable bracketed paste
- unibi_out(ui, data->unibi_ext.enable_bracketed_paste);
- // Enable focus reporting
- unibi_out(ui, data->unibi_ext.enable_focus_reporting);
+ unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste);
+
uv_loop_init(&data->write_loop);
if (data->out_isatty) {
uv_tty_init(&data->write_loop, &data->output_handle.tty, data->out_fd, 0);
+#ifdef WIN32
uv_tty_set_mode(&data->output_handle.tty, UV_TTY_MODE_RAW);
+#else
+ uv_tty_set_mode(&data->output_handle.tty, UV_TTY_MODE_IO);
+#endif
} else {
uv_pipe_init(&data->write_loop, &data->output_handle.pipe, 0);
uv_pipe_open(&data->output_handle.pipe, data->out_fd);
@@ -162,16 +304,22 @@ static void terminfo_stop(UI *ui)
{
TUIData *data = ui->data;
// Destroy output stuff
- tui_mode_change(ui, NORMAL);
+ tui_mode_change(ui, (String)STRING_INIT, SHAPE_IDX_N);
tui_mouse_off(ui);
unibi_out(ui, unibi_exit_attribute_mode);
- // cursor should be set to normal before exiting alternate screen
+ // Reset cursor to normal before exiting alternate screen.
unibi_out(ui, unibi_cursor_normal);
+ unibi_out(ui, unibi_keypad_local);
unibi_out(ui, unibi_exit_ca_mode);
+ // Restore title/icon from the "stack". #4063
+ unibi_out_ext(ui, data->unibi_ext.restore_title);
+ if (data->cursor_color_changed) {
+ unibi_out_ext(ui, data->unibi_ext.reset_cursor_color);
+ }
// Disable bracketed paste
- unibi_out(ui, data->unibi_ext.disable_bracketed_paste);
+ unibi_out_ext(ui, data->unibi_ext.disable_bracketed_paste);
// Disable focus reporting
- unibi_out(ui, data->unibi_ext.disable_focus_reporting);
+ unibi_out_ext(ui, data->unibi_ext.disable_focus_reporting);
flush_buf(ui);
uv_tty_reset_mode();
uv_close((uv_handle_t *)&data->output_handle, NULL);
@@ -185,7 +333,7 @@ static void terminfo_stop(UI *ui)
static void tui_terminal_start(UI *ui)
{
TUIData *data = ui->data;
- data->print_attrs = EMPTY_ATTRS;
+ data->print_attr_id = -1;
ugrid_init(&data->grid);
terminfo_start(ui);
update_size(ui);
@@ -193,9 +341,25 @@ static void tui_terminal_start(UI *ui)
term_input_start(&data->input);
}
+static void tui_terminal_after_startup(UI *ui)
+ FUNC_ATTR_NONNULL_ALL
+{
+ TUIData *data = ui->data;
+
+ // Emit this after Nvim startup, not during. This works around a tmux
+ // 2.3 bug(?) which caused slow drawing during startup. #7649
+ unibi_out_ext(ui, data->unibi_ext.enable_focus_reporting);
+}
+
static void tui_terminal_stop(UI *ui)
{
TUIData *data = ui->data;
+ if (uv_is_closing(STRUCT_CAST(uv_handle_t, &data->output_handle))) {
+ // Race between SIGCONT (tui.c) and SIGHUP (os/signal.c)? #8075
+ ELOG("TUI already stopped (race?)");
+ ui->data = NULL; // Flag UI as "stopped".
+ return;
+ }
term_input_stop(&data->input);
signal_watcher_stop(&data->winch_handle);
terminfo_stop(ui);
@@ -205,11 +369,16 @@ static void tui_terminal_stop(UI *ui)
static void tui_stop(UI *ui)
{
tui_terminal_stop(ui);
- TUIData *data = ui->data;
- data->stop = true;
+ ui->data = NULL; // Flag UI as "stopped".
}
-// Main function of the TUI thread
+/// Returns true if UI `ui` is stopped.
+static bool tui_is_stopped(UI *ui)
+{
+ return ui->data == NULL;
+}
+
+/// Main function of the TUI thread.
static void tui_main(UIBridgeData *bridge, UI *ui)
{
Loop tui_loop;
@@ -221,17 +390,38 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
kv_init(data->invalid_regions);
signal_watcher_init(data->loop, &data->winch_handle, ui);
signal_watcher_init(data->loop, &data->cont_handle, data);
+#ifdef UNIX
signal_watcher_start(&data->cont_handle, sigcont_cb, SIGCONT);
- // initialize input reading structures
+#endif
+
+ // TODO(bfredl): zero hl is empty, send this explicitly?
+ kv_push(data->attrs, HLATTRS_INIT);
+
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+ data->input.tk_ti_hook_fn = tui_tk_ti_getstr;
+#endif
term_input_init(&data->input, &tui_loop);
tui_terminal_start(ui);
- data->stop = false;
- // allow the main thread to continue, we are ready to start handling UI
- // callbacks
+
+ // Allow main thread to continue, we are ready to handle UI callbacks.
CONTINUE(bridge);
- while (!data->stop) {
- loop_poll_events(&tui_loop, -1);
+ loop_schedule_deferred(&main_loop,
+ event_create(show_termcap_event, 1, data->ut));
+
+ // "Active" loop: first ~100 ms of startup.
+ for (size_t ms = 0; ms < 100 && !tui_is_stopped(ui);) {
+ ms += (loop_poll_events(&tui_loop, 20) ? 20 : 1);
+ }
+ if (!tui_is_stopped(ui)) {
+ tui_terminal_after_startup(ui);
+ // Tickle `main_loop` with a dummy event, else the initial "focus-gained"
+ // terminal response may not get processed until user hits a key.
+ loop_schedule_deferred(&main_loop, event_create(tui_dummy_event, 0));
+ }
+ // "Passive" (I/O-driven) loop: TUI thread "main loop".
+ while (!tui_is_stopped(ui)) {
+ loop_poll_events(&tui_loop, -1); // tui_loop.events is never processed
}
ui_bridge_stopped(bridge);
@@ -239,193 +429,551 @@ static void tui_main(UIBridgeData *bridge, UI *ui)
signal_watcher_stop(&data->cont_handle);
signal_watcher_close(&data->cont_handle, NULL);
signal_watcher_close(&data->winch_handle, NULL);
- loop_close(&tui_loop);
+ loop_close(&tui_loop, false);
kv_destroy(data->invalid_regions);
+ kv_destroy(data->attrs);
+ xfree(data->space_buf);
xfree(data);
- xfree(ui);
}
-static void tui_scheduler(Event event, void *d)
+static void tui_dummy_event(void **argv)
{
- UI *ui = d;
- TUIData *data = ui->data;
- loop_schedule(data->loop, event);
}
-static void refresh_event(void **argv)
+/// Handoff point between the main (ui_bridge) thread and the TUI thread.
+static void tui_scheduler(Event event, void *d)
{
- ui_refresh();
+ UI *ui = d;
+ TUIData *data = ui->data;
+ loop_schedule(data->loop, event); // `tui_loop` local to tui_main().
}
+#ifdef UNIX
static void sigcont_cb(SignalWatcher *watcher, int signum, void *data)
{
((TUIData *)data)->cont_received = true;
}
+#endif
static void sigwinch_cb(SignalWatcher *watcher, int signum, void *data)
{
got_winch = true;
UI *ui = data;
+ if (tui_is_stopped(ui)) {
+ return;
+ }
+
update_size(ui);
- // run refresh_event in nvim main loop
- loop_schedule(&main_loop, event_create(1, refresh_event, 0));
+ ui_schedule_refresh();
}
-static bool attrs_differ(HlAttrs a1, HlAttrs a2)
+static bool attrs_differ(UI *ui, int id1, int id2, bool rgb)
{
- return a1.foreground != a2.foreground || a1.background != a2.background
- || a1.bold != a2.bold || a1.italic != a2.italic
- || a1.undercurl != a2.undercurl || a1.underline != a2.underline
- || a1.reverse != a2.reverse;
+ TUIData *data = ui->data;
+ if (id1 == id2) {
+ return false;
+ } else if (id1 < 0 || id2 < 0) {
+ return true;
+ }
+ HlAttrs a1 = kv_A(data->attrs, (size_t)id1);
+ HlAttrs a2 = kv_A(data->attrs, (size_t)id2);
+
+ if (rgb) {
+ return a1.rgb_fg_color != a2.rgb_fg_color
+ || a1.rgb_bg_color != a2.rgb_bg_color
+ || a1.rgb_ae_attr != a2.rgb_ae_attr
+ || a1.rgb_sp_color != a2.rgb_sp_color;
+ } else {
+ return a1.cterm_fg_color != a2.cterm_fg_color
+ || a1.cterm_bg_color != a2.cterm_bg_color
+ || a1.cterm_ae_attr != a2.cterm_ae_attr
+ || (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)
+ && a1.rgb_sp_color != a2.rgb_sp_color);
+ }
}
-static void update_attrs(UI *ui, HlAttrs attrs)
+static void update_attrs(UI *ui, int attr_id)
{
TUIData *data = ui->data;
- if (!attrs_differ(attrs, data->print_attrs)) {
+ if (!attrs_differ(ui, attr_id, data->print_attr_id, ui->rgb)) {
+ data->print_attr_id = attr_id;
return;
}
+ data->print_attr_id = attr_id;
+ HlAttrs attrs = kv_A(data->attrs, (size_t)attr_id);
- data->print_attrs = attrs;
- unibi_out(ui, unibi_exit_attribute_mode);
- UGrid *grid = &data->grid;
+ int fg = ui->rgb ? attrs.rgb_fg_color : (attrs.cterm_fg_color - 1);
+ if (fg == -1) {
+ fg = ui->rgb ? data->clear_attrs.rgb_fg_color
+ : (data->clear_attrs.cterm_fg_color - 1);
+ }
- int fg = attrs.foreground != -1 ? attrs.foreground : grid->fg;
- int bg = attrs.background != -1 ? attrs.background : grid->bg;
+ int bg = ui->rgb ? attrs.rgb_bg_color : (attrs.cterm_bg_color - 1);
+ if (bg == -1) {
+ bg = ui->rgb ? data->clear_attrs.rgb_bg_color
+ : (data->clear_attrs.cterm_bg_color - 1);
+ }
+
+ int attr = ui->rgb ? attrs.rgb_ae_attr : attrs.cterm_ae_attr;
+ bool bold = attr & HL_BOLD;
+ bool italic = attr & HL_ITALIC;
+ bool reverse = attr & HL_INVERSE;
+ bool standout = attr & HL_STANDOUT;
+
+ bool underline;
+ bool undercurl;
+ if (data->unibi_ext.enter_undercurl_mode) {
+ underline = attr & HL_UNDERLINE;
+ undercurl = attr & HL_UNDERCURL;
+ } else {
+ underline = (attr & HL_UNDERLINE) || (attr & HL_UNDERCURL);
+ undercurl = false;
+ }
+ if (unibi_get_str(data->ut, unibi_set_attributes)) {
+ if (bold || reverse || underline || standout) {
+ UNIBI_SET_NUM_VAR(data->params[0], standout);
+ UNIBI_SET_NUM_VAR(data->params[1], underline);
+ UNIBI_SET_NUM_VAR(data->params[2], reverse);
+ UNIBI_SET_NUM_VAR(data->params[3], 0); // blink
+ UNIBI_SET_NUM_VAR(data->params[4], 0); // dim
+ UNIBI_SET_NUM_VAR(data->params[5], bold);
+ UNIBI_SET_NUM_VAR(data->params[6], 0); // blank
+ UNIBI_SET_NUM_VAR(data->params[7], 0); // protect
+ UNIBI_SET_NUM_VAR(data->params[8], 0); // alternate character set
+ unibi_out(ui, unibi_set_attributes);
+ } else if (!data->default_attr) {
+ unibi_out(ui, unibi_exit_attribute_mode);
+ }
+ } else {
+ if (!data->default_attr) {
+ unibi_out(ui, unibi_exit_attribute_mode);
+ }
+ if (bold) {
+ unibi_out(ui, unibi_enter_bold_mode);
+ }
+ if (underline) {
+ unibi_out(ui, unibi_enter_underline_mode);
+ }
+ if (standout) {
+ unibi_out(ui, unibi_enter_standout_mode);
+ }
+ if (reverse) {
+ unibi_out(ui, unibi_enter_reverse_mode);
+ }
+ }
+ if (italic) {
+ unibi_out(ui, unibi_enter_italics_mode);
+ }
+ if (undercurl && data->unibi_ext.enter_undercurl_mode) {
+ unibi_out_ext(ui, data->unibi_ext.enter_undercurl_mode);
+ }
+ if ((undercurl || underline) && data->unibi_ext.set_underline_color) {
+ int color = attrs.rgb_sp_color;
+ if (color != -1) {
+ UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red
+ UNIBI_SET_NUM_VAR(data->params[1], (color >> 8) & 0xff); // green
+ UNIBI_SET_NUM_VAR(data->params[2], color & 0xff); // blue
+ unibi_out_ext(ui, data->unibi_ext.set_underline_color);
+ }
+ }
if (ui->rgb) {
if (fg != -1) {
- data->params[0].i = (fg >> 16) & 0xff; // red
- data->params[1].i = (fg >> 8) & 0xff; // green
- data->params[2].i = fg & 0xff; // blue
- unibi_out(ui, data->unibi_ext.set_rgb_foreground);
+ UNIBI_SET_NUM_VAR(data->params[0], (fg >> 16) & 0xff); // red
+ UNIBI_SET_NUM_VAR(data->params[1], (fg >> 8) & 0xff); // green
+ UNIBI_SET_NUM_VAR(data->params[2], fg & 0xff); // blue
+ unibi_out_ext(ui, data->unibi_ext.set_rgb_foreground);
}
if (bg != -1) {
- data->params[0].i = (bg >> 16) & 0xff; // red
- data->params[1].i = (bg >> 8) & 0xff; // green
- data->params[2].i = bg & 0xff; // blue
- unibi_out(ui, data->unibi_ext.set_rgb_background);
+ UNIBI_SET_NUM_VAR(data->params[0], (bg >> 16) & 0xff); // red
+ UNIBI_SET_NUM_VAR(data->params[1], (bg >> 8) & 0xff); // green
+ UNIBI_SET_NUM_VAR(data->params[2], bg & 0xff); // blue
+ unibi_out_ext(ui, data->unibi_ext.set_rgb_background);
}
} else {
if (fg != -1) {
- data->params[0].i = fg;
+ UNIBI_SET_NUM_VAR(data->params[0], fg);
unibi_out(ui, unibi_set_a_foreground);
}
if (bg != -1) {
- data->params[0].i = bg;
+ UNIBI_SET_NUM_VAR(data->params[0], bg);
unibi_out(ui, unibi_set_a_background);
}
}
- if (attrs.bold) {
- unibi_out(ui, unibi_enter_bold_mode);
- }
- if (attrs.italic) {
- unibi_out(ui, unibi_enter_italics_mode);
- }
- if (attrs.underline || attrs.undercurl) {
- unibi_out(ui, unibi_enter_underline_mode);
- }
- if (attrs.reverse) {
- unibi_out(ui, unibi_enter_reverse_mode);
+ data->default_attr = fg == -1 && bg == -1
+ && !bold && !italic && !underline && !undercurl && !reverse && !standout;
+
+ // Non-BCE terminals can't clear with non-default background color. Some BCE
+ // terminals don't support attributes either, so don't rely on it. But assume
+ // italic and bold has no effect if there is no text.
+ data->can_clear_attr = !reverse && !standout && !underline && !undercurl
+ && (data->bce || bg == -1);
+}
+
+static void final_column_wrap(UI *ui)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+ if (grid->row != -1 && grid->col == ui->width) {
+ grid->col = 0;
+ if (grid->row < MIN(ui->height, grid->height - 1)) {
+ grid->row++;
+ }
}
}
+/// It is undocumented, but in the majority of terminals and terminal emulators
+/// printing at the right margin does not cause an automatic wrap until the
+/// next character is printed, holding the cursor in place until then.
static void print_cell(UI *ui, UCell *ptr)
{
- update_attrs(ui, ptr->attrs);
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+ if (!data->immediate_wrap_after_last_column) {
+ // Printing the next character finally advances the cursor.
+ final_column_wrap(ui);
+ }
+ update_attrs(ui, ptr->attr);
out(ui, ptr->data, strlen(ptr->data));
+ grid->col++;
+ if (data->immediate_wrap_after_last_column) {
+ // Printing at the right margin immediately advances the cursor.
+ final_column_wrap(ui);
+ }
}
-static void clear_region(UI *ui, int top, int bot, int left, int right)
+static bool cheap_to_print(UI *ui, int row, int col, int next)
{
TUIData *data = ui->data;
UGrid *grid = &data->grid;
+ UCell *cell = grid->cells[row] + col;
+ while (next) {
+ next--;
+ if (attrs_differ(ui, cell->attr,
+ data->print_attr_id, ui->rgb)) {
+ if (data->default_attr) {
+ return false;
+ }
+ }
+ if (strlen(cell->data) > 1) {
+ return false;
+ }
+ cell++;
+ }
+ return true;
+}
- bool cleared = false;
- if (grid->bg == -1 && right == ui->width -1) {
- // Background is set to the default color and the right edge matches the
- // screen end, try to use terminal codes for clearing the requested area.
- HlAttrs clear_attrs = EMPTY_ATTRS;
- clear_attrs.foreground = grid->fg;
- clear_attrs.background = grid->bg;
- update_attrs(ui, clear_attrs);
- if (left == 0) {
- if (bot == ui->height - 1) {
- if (top == 0) {
- unibi_out(ui, unibi_clear_screen);
- } else {
- unibi_goto(ui, top, 0);
- unibi_out(ui, unibi_clr_eos);
+/// This optimizes several cases where it is cheaper to do something other
+/// than send a full cursor positioning control sequence. However, there are
+/// some further optimizations that may seem obvious but that will not work.
+///
+/// We cannot use VT (ASCII 0/11) for moving the cursor up, because VT means
+/// move the cursor down on a DEC terminal. Similarly, on a DEC terminal FF
+/// (ASCII 0/12) means the same thing and does not mean home. VT, CVT, and
+/// TAB also stop at software-defined tabulation stops, not at a fixed set
+/// of row/column positions.
+static void cursor_goto(UI *ui, int row, int col)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+ if (row == grid->row && col == grid->col) {
+ return;
+ }
+ if (0 == row && 0 == col) {
+ unibi_out(ui, unibi_cursor_home);
+ ugrid_goto(grid, row, col);
+ return;
+ }
+ if (grid->row == -1) {
+ goto safe_move;
+ }
+ if (0 == col ? col != grid->col :
+ row != grid->row ? false :
+ 1 == col ? 2 < grid->col && cheap_to_print(ui, grid->row, 0, col) :
+ 2 == col ? 5 < grid->col && cheap_to_print(ui, grid->row, 0, col) :
+ false) {
+ // Motion to left margin from anywhere else, or CR + printing chars is
+ // even less expensive than using BSes or CUB.
+ unibi_out(ui, unibi_carriage_return);
+ ugrid_goto(grid, grid->row, 0);
+ } else if (col > grid->col) {
+ int n = col - grid->col;
+ if (n <= (row == grid->row ? 4 : 2)
+ && cheap_to_print(ui, grid->row, grid->col, n)) {
+ UGRID_FOREACH_CELL(grid, grid->row, grid->col, col, {
+ print_cell(ui, cell);
+ });
+ }
+ }
+ if (row == grid->row) {
+ if (col < grid->col
+ // Deferred right margin wrap terminals have inconsistent ideas about
+ // where the cursor actually is during a deferred wrap. Relative
+ // motion calculations have OBOEs that cannot be compensated for,
+ // because two terminals that claim to be the same will implement
+ // different cursor positioning rules.
+ && (data->immediate_wrap_after_last_column || grid->col < ui->width)) {
+ int n = grid->col - col;
+ if (n <= 4) { // This might be just BS, so it is considered really cheap.
+ while (n--) {
+ unibi_out(ui, unibi_cursor_left);
}
- cleared = true;
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], n);
+ unibi_out(ui, unibi_parm_left_cursor);
}
+ ugrid_goto(grid, row, col);
+ return;
+ } else if (col > grid->col) {
+ int n = col - grid->col;
+ if (n <= 2) {
+ while (n--) {
+ unibi_out(ui, unibi_cursor_right);
+ }
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], n);
+ unibi_out(ui, unibi_parm_right_cursor);
+ }
+ ugrid_goto(grid, row, col);
+ return;
+ }
+ }
+ if (col == grid->col) {
+ if (row > grid->row) {
+ int n = row - grid->row;
+ if (n <= 4) { // This might be just LF, so it is considered really cheap.
+ while (n--) {
+ unibi_out(ui, unibi_cursor_down);
+ }
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], n);
+ unibi_out(ui, unibi_parm_down_cursor);
+ }
+ ugrid_goto(grid, row, col);
+ return;
+ } else if (row < grid->row) {
+ int n = grid->row - row;
+ if (n <= 2) {
+ while (n--) {
+ unibi_out(ui, unibi_cursor_up);
+ }
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], n);
+ unibi_out(ui, unibi_parm_up_cursor);
+ }
+ ugrid_goto(grid, row, col);
+ return;
+ }
+ }
+
+safe_move:
+ unibi_goto(ui, row, col);
+ ugrid_goto(grid, row, col);
+}
+
+static void clear_region(UI *ui, int top, int bot, int left, int right,
+ int attr_id)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ update_attrs(ui, attr_id);
+
+ // Background is set to the default color and the right edge matches the
+ // screen end, try to use terminal codes for clearing the requested area.
+ if (data->can_clear_attr
+ && left == 0 && right == ui->width && bot == ui->height) {
+ if (top == 0) {
+ unibi_out(ui, unibi_clear_screen);
+ ugrid_goto(&data->grid, top, left);
+ } else {
+ cursor_goto(ui, top, 0);
+ unibi_out(ui, unibi_clr_eos);
}
+ } else {
+ int width = right-left;
- if (!cleared) {
- // iterate through each line and clear with clr_eol
- for (int row = top; row <= bot; ++row) {
- unibi_goto(ui, row, left);
+ // iterate through each line and clear
+ for (int row = top; row < bot; row++) {
+ cursor_goto(ui, row, left);
+ if (data->can_clear_attr && right == ui->width) {
unibi_out(ui, unibi_clr_eol);
+ } else if (data->can_erase_chars && data->can_clear_attr && width >= 5) {
+ UNIBI_SET_NUM_VAR(data->params[0], width);
+ unibi_out(ui, unibi_erase_chars);
+ } else {
+ out(ui, data->space_buf, (size_t)width);
+ grid->col += width;
+ if (data->immediate_wrap_after_last_column) {
+ // Printing at the right margin immediately advances the cursor.
+ final_column_wrap(ui);
+ }
}
- cleared = true;
}
}
+}
- if (!cleared) {
- // could not clear using faster terminal codes, refresh the whole region
- int currow = -1;
- UGRID_FOREACH_CELL(grid, top, bot, left, right, {
- if (currow != row) {
- unibi_goto(ui, row, col);
- currow = row;
- }
- print_cell(ui, cell);
- });
+static void set_scroll_region(UI *ui, int top, int bot, int left, int right)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ UNIBI_SET_NUM_VAR(data->params[0], top);
+ UNIBI_SET_NUM_VAR(data->params[1], bot);
+ unibi_out(ui, unibi_change_scroll_region);
+ if (left != 0 || right != ui->width - 1) {
+ unibi_out_ext(ui, data->unibi_ext.enable_lr_margin);
+ if (data->can_set_lr_margin) {
+ UNIBI_SET_NUM_VAR(data->params[0], left);
+ UNIBI_SET_NUM_VAR(data->params[1], right);
+ unibi_out(ui, unibi_set_lr_margin);
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], left);
+ unibi_out(ui, unibi_set_left_margin_parm);
+ UNIBI_SET_NUM_VAR(data->params[0], right);
+ unibi_out(ui, unibi_set_right_margin_parm);
+ }
}
+ grid->row = -1;
+}
- // restore cursor
- unibi_goto(ui, grid->row, grid->col);
+static void reset_scroll_region(UI *ui, bool fullwidth)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+
+ if (0 <= data->unibi_ext.reset_scroll_region) {
+ unibi_out_ext(ui, data->unibi_ext.reset_scroll_region);
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], 0);
+ UNIBI_SET_NUM_VAR(data->params[1], ui->height - 1);
+ unibi_out(ui, unibi_change_scroll_region);
+ }
+ if (!fullwidth) {
+ if (data->can_set_lr_margin) {
+ UNIBI_SET_NUM_VAR(data->params[0], 0);
+ UNIBI_SET_NUM_VAR(data->params[1], ui->width - 1);
+ unibi_out(ui, unibi_set_lr_margin);
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], 0);
+ unibi_out(ui, unibi_set_left_margin_parm);
+ UNIBI_SET_NUM_VAR(data->params[0], ui->width - 1);
+ unibi_out(ui, unibi_set_right_margin_parm);
+ }
+ unibi_out_ext(ui, data->unibi_ext.disable_lr_margin);
+ }
+ grid->row = -1;
}
-static void tui_resize(UI *ui, int width, int height)
+static void tui_grid_resize(UI *ui, Integer g, Integer width, Integer height)
{
TUIData *data = ui->data;
- ugrid_resize(&data->grid, width, height);
+ UGrid *grid = &data->grid;
+ ugrid_resize(grid, (int)width, (int)height);
+
+ xfree(data->space_buf);
+ data->space_buf = xmalloc((size_t)width * sizeof(*data->space_buf));
+ memset(data->space_buf, ' ', (size_t)width);
+
+ // resize might not always be followed by a clear before flush
+ // so clip the invalid region
+ for (size_t i = 0; i < kv_size(data->invalid_regions); i++) {
+ Rect *r = &kv_A(data->invalid_regions, i);
+ r->bot = MIN(r->bot, grid->height);
+ r->right = MIN(r->right, grid->width);
+ }
if (!got_winch) { // Try to resize the terminal window.
- char r[16]; // enough for 9999x9999
- snprintf(r, sizeof(r), "\x1b[8;%d;%dt", height, width);
- out(ui, r, strlen(r));
+ UNIBI_SET_NUM_VAR(data->params[0], (int)height);
+ UNIBI_SET_NUM_VAR(data->params[1], (int)width);
+ unibi_out_ext(ui, data->unibi_ext.resize_screen);
+ // DECSLPP does not reset the scroll region.
+ if (data->scroll_region_is_full_screen) {
+ reset_scroll_region(ui, ui->width == grid->width);
+ }
} else { // Already handled the SIGWINCH signal; avoid double-resize.
got_winch = false;
+ grid->row = -1;
}
}
-static void tui_clear(UI *ui)
+static void tui_grid_clear(UI *ui, Integer g)
{
TUIData *data = ui->data;
UGrid *grid = &data->grid;
ugrid_clear(grid);
- clear_region(ui, grid->top, grid->bot, grid->left, grid->right);
+ kv_size(data->invalid_regions) = 0;
+ clear_region(ui, 0, grid->height, 0, grid->width, 0);
}
-static void tui_eol_clear(UI *ui)
+static void tui_grid_cursor_goto(UI *ui, Integer grid, Integer row, Integer col)
{
TUIData *data = ui->data;
- UGrid *grid = &data->grid;
- ugrid_eol_clear(grid);
- clear_region(ui, grid->row, grid->row, grid->col, grid->right);
+
+ // cursor position is validated in tui_flush
+ data->row = (int)row;
+ data->col = (int)col;
+}
+
+CursorShape tui_cursor_decode_shape(const char *shape_str)
+{
+ CursorShape shape;
+ if (strequal(shape_str, "block")) {
+ shape = SHAPE_BLOCK;
+ } else if (strequal(shape_str, "vertical")) {
+ shape = SHAPE_VER;
+ } else if (strequal(shape_str, "horizontal")) {
+ shape = SHAPE_HOR;
+ } else {
+ WLOG("Unknown shape value '%s'", shape_str);
+ shape = SHAPE_BLOCK;
+ }
+ return shape;
}
-static void tui_cursor_goto(UI *ui, int row, int col)
+static cursorentry_T decode_cursor_entry(Dictionary args)
{
+ cursorentry_T r = shape_table[0];
+
+ for (size_t i = 0; i < args.size; i++) {
+ char *key = args.items[i].key.data;
+ Object value = args.items[i].value;
+
+ if (strequal(key, "cursor_shape")) {
+ r.shape = tui_cursor_decode_shape(args.items[i].value.data.string.data);
+ } else if (strequal(key, "blinkon")) {
+ r.blinkon = (int)value.data.integer;
+ } else if (strequal(key, "blinkoff")) {
+ r.blinkoff = (int)value.data.integer;
+ } else if (strequal(key, "attr_id")) {
+ r.id = (int)value.data.integer;
+ }
+ }
+ return r;
+}
+
+static void tui_mode_info_set(UI *ui, bool guicursor_enabled, Array args)
+{
+ cursor_style_enabled = guicursor_enabled;
+ if (!guicursor_enabled) {
+ return; // Do not send cursor style control codes.
+ }
TUIData *data = ui->data;
- ugrid_goto(&data->grid, row, col);
- unibi_goto(ui, row, col);
+
+ assert(args.size);
+
+ // cursor style entries as defined by `shape_table`.
+ for (size_t i = 0; i < args.size; i++) {
+ assert(args.items[i].type == kObjectTypeDictionary);
+ cursorentry_T r = decode_cursor_entry(args.items[i].data.dictionary);
+ data->cursor_shapes[i] = r;
+ }
+
+ tui_set_mode(ui, data->showing_mode);
}
static void tui_update_menu(UI *ui)
@@ -446,119 +994,130 @@ static void tui_busy_stop(UI *ui)
static void tui_mouse_on(UI *ui)
{
TUIData *data = ui->data;
- unibi_out(ui, data->unibi_ext.enable_mouse);
- data->mouse_enabled = true;
+ if (!data->mouse_enabled) {
+ unibi_out_ext(ui, data->unibi_ext.enable_mouse);
+ data->mouse_enabled = true;
+ }
}
static void tui_mouse_off(UI *ui)
{
TUIData *data = ui->data;
- unibi_out(ui, data->unibi_ext.disable_mouse);
- data->mouse_enabled = false;
+ if (data->mouse_enabled) {
+ unibi_out_ext(ui, data->unibi_ext.disable_mouse);
+ data->mouse_enabled = false;
+ }
}
-static void tui_mode_change(UI *ui, int mode)
+static void tui_set_mode(UI *ui, ModeShape mode)
{
+ if (!cursor_style_enabled) {
+ return;
+ }
TUIData *data = ui->data;
-
- if (mode == INSERT) {
- if (data->showing_mode != INSERT) {
- unibi_out(ui, data->unibi_ext.enter_insert_mode);
- }
- } else if (mode == REPLACE) {
- if (data->showing_mode != REPLACE) {
- unibi_out(ui, data->unibi_ext.enter_replace_mode);
- }
- } else {
- assert(mode == NORMAL);
- if (data->showing_mode != NORMAL) {
- unibi_out(ui, data->unibi_ext.exit_insert_mode);
+ cursorentry_T c = data->cursor_shapes[mode];
+
+ if (c.id != 0 && c.id < (int)kv_size(data->attrs) && ui->rgb) {
+ HlAttrs aep = kv_A(data->attrs, c.id);
+ if (aep.rgb_ae_attr & HL_INVERSE) {
+ // We interpret "inverse" as "default" (no termcode for "inverse"...).
+ // Hopefully the user's default cursor color is inverse.
+ unibi_out_ext(ui, data->unibi_ext.reset_cursor_color);
+ } else {
+ UNIBI_SET_NUM_VAR(data->params[0], aep.rgb_bg_color);
+ unibi_out_ext(ui, data->unibi_ext.set_cursor_color);
+ data->cursor_color_changed = true;
}
+ } else if (c.id == 0) {
+ // No cursor color for this mode; reset to default.
+ unibi_out_ext(ui, data->unibi_ext.reset_cursor_color);
+ }
+
+ int shape;
+ switch (c.shape) {
+ default: abort(); break;
+ case SHAPE_BLOCK: shape = 1; break;
+ case SHAPE_HOR: shape = 3; break;
+ case SHAPE_VER: shape = 5; break;
}
- data->showing_mode = mode;
+ UNIBI_SET_NUM_VAR(data->params[0], shape + (int)(c.blinkon == 0));
+ unibi_out_ext(ui, data->unibi_ext.set_cursor_style);
}
-static void tui_set_scroll_region(UI *ui, int top, int bot, int left,
- int right)
+/// @param mode editor mode
+static void tui_mode_change(UI *ui, String mode, Integer mode_idx)
{
TUIData *data = ui->data;
- ugrid_set_scroll_region(&data->grid, top, bot, left, right);
- data->can_use_terminal_scroll =
- left == 0 && right == ui->width - 1
- && ((top == 0 && bot == ui->height - 1)
- || unibi_get_str(data->ut, unibi_change_scroll_region));
+ tui_set_mode(ui, (ModeShape)mode_idx);
+ data->showing_mode = (ModeShape)mode_idx;
}
-static void tui_scroll(UI *ui, int count)
+static void tui_grid_scroll(UI *ui, Integer g, Integer startrow, Integer endrow,
+ Integer startcol, Integer endcol,
+ Integer rows, Integer cols)
{
+ (void)cols; // unused
TUIData *data = ui->data;
UGrid *grid = &data->grid;
- int clear_top, clear_bot;
- ugrid_scroll(grid, count, &clear_top, &clear_bot);
+ int top = (int)startrow, bot = (int)endrow-1;
+ int left = (int)startcol, right = (int)endcol-1;
- if (data->can_use_terminal_scroll) {
+ bool fullwidth = left == 0 && right == ui->width-1;
+ data->scroll_region_is_full_screen = fullwidth
+ && top == 0 && bot == ui->height-1;
+
+ ugrid_scroll(grid, top, bot, left, right, (int)rows);
+
+ bool can_scroll = data->can_scroll
+ && (data->scroll_region_is_full_screen
+ || (data->can_change_scroll_region
+ && ((left == 0 && right == ui->width - 1)
+ || data->can_set_lr_margin
+ || data->can_set_left_right_margin)));
+
+ if (can_scroll) {
// Change terminal scroll region and move cursor to the top
- data->params[0].i = grid->top;
- data->params[1].i = grid->bot;
- unibi_out(ui, unibi_change_scroll_region);
- unibi_goto(ui, grid->top, grid->left);
- // also set default color attributes or some terminals can become funny
- HlAttrs clear_attrs = EMPTY_ATTRS;
- clear_attrs.foreground = grid->fg;
- clear_attrs.background = grid->bg;
- update_attrs(ui, clear_attrs);
- }
+ if (!data->scroll_region_is_full_screen) {
+ set_scroll_region(ui, top, bot, left, right);
+ }
+ cursor_goto(ui, top, left);
- if (count > 0) {
- if (data->can_use_terminal_scroll) {
- if (count == 1) {
+ if (rows > 0) {
+ if (rows == 1) {
unibi_out(ui, unibi_delete_line);
} else {
- data->params[0].i = count;
+ UNIBI_SET_NUM_VAR(data->params[0], (int)rows);
unibi_out(ui, unibi_parm_delete_line);
}
- }
-
- } else {
- if (data->can_use_terminal_scroll) {
- if (count == -1) {
+ } else {
+ if (rows == -1) {
unibi_out(ui, unibi_insert_line);
} else {
- data->params[0].i = -count;
+ UNIBI_SET_NUM_VAR(data->params[0], -(int)rows);
unibi_out(ui, unibi_parm_insert_line);
}
}
- }
- if (data->can_use_terminal_scroll) {
// Restore terminal scroll region and cursor
- data->params[0].i = 0;
- data->params[1].i = ui->height - 1;
- unibi_out(ui, unibi_change_scroll_region);
- unibi_goto(ui, grid->row, grid->col);
-
- if (grid->bg != -1) {
- // Update the cleared area of the terminal if its builtin scrolling
- // facility was used and the background color is not the default. This is
- // required because scrolling may leave wrong background in the cleared
- // area.
- clear_region(ui, clear_top, clear_bot, grid->left, grid->right);
+ if (!data->scroll_region_is_full_screen) {
+ reset_scroll_region(ui, fullwidth);
}
} else {
- // Mark the entire scroll region as invalid for redrawing later
- invalidate(ui, grid->top, grid->bot, grid->left, grid->right);
+ // Mark the moved region as invalid for redrawing later
+ if (rows > 0) {
+ endrow = endrow - rows;
+ } else {
+ startrow = startrow - rows;
+ }
+ invalidate(ui, (int)startrow, (int)endrow, (int)startcol, (int)endcol);
}
}
-static void tui_highlight_set(UI *ui, HlAttrs attrs)
-{
- ((TUIData *)ui->data)->grid.attrs = attrs;
-}
-
-static void tui_put(UI *ui, uint8_t *text, size_t size)
+static void tui_hl_attr_define(UI *ui, Integer id, HlAttrs attrs,
+ HlAttrs cterm_attrs, Array info)
{
TUIData *data = ui->data;
- print_cell(ui, ugrid_put(&data->grid, text, size));
+ kv_a(data->attrs, (size_t)id) = attrs;
}
static void tui_bell(UI *ui)
@@ -571,19 +1130,20 @@ static void tui_visual_bell(UI *ui)
unibi_out(ui, unibi_flash_screen);
}
-static void tui_update_fg(UI *ui, int fg)
+static void tui_default_colors_set(UI *ui, Integer rgb_fg, Integer rgb_bg,
+ Integer rgb_sp,
+ Integer cterm_fg, Integer cterm_bg)
{
- ((TUIData *)ui->data)->grid.fg = fg;
-}
+ TUIData *data = ui->data;
-static void tui_update_bg(UI *ui, int bg)
-{
- ((TUIData *)ui->data)->grid.bg = bg;
-}
+ data->clear_attrs.rgb_fg_color = (int)rgb_fg;
+ data->clear_attrs.rgb_bg_color = (int)rgb_bg;
+ data->clear_attrs.rgb_sp_color = (int)rgb_sp;
+ data->clear_attrs.cterm_fg_color = (int)cterm_fg;
+ data->clear_attrs.cterm_bg_color = (int)cterm_bg;
-static void tui_update_sp(UI *ui, int sp)
-{
- // Do nothing; 'special' color is for GUI only
+ data->print_attr_id = -1;
+ invalidate(ui, 0, data->grid.height, 0, data->grid.width);
}
static void tui_flush(UI *ui)
@@ -591,23 +1151,67 @@ static void tui_flush(UI *ui)
TUIData *data = ui->data;
UGrid *grid = &data->grid;
+ size_t nrevents = loop_size(data->loop);
+ if (nrevents > TOO_MANY_EVENTS) {
+ WLOG("TUI event-queue flooded (thread_events=%zu); purging", nrevents);
+ // Back-pressure: UI events may accumulate much faster than the terminal
+ // device can serve them. Even if SIGINT/CTRL-C is received, user must still
+ // wait for the TUI event-queue to drain, and if there are ~millions of
+ // events in the queue, it could take hours. Clearing the queue allows the
+ // UI to recover. #1234 #5396
+ loop_purge(data->loop);
+ tui_busy_stop(ui); // avoid hidden cursor
+ }
+
while (kv_size(data->invalid_regions)) {
Rect r = kv_pop(data->invalid_regions);
- int currow = -1;
- UGRID_FOREACH_CELL(grid, r.top, r.bot, r.left, r.right, {
- if (currow != row) {
- unibi_goto(ui, row, col);
- currow = row;
+ assert(r.bot <= grid->height && r.right <= grid->width);
+
+ for (int row = r.top; row < r.bot; row++) {
+ int clear_attr = grid->cells[row][r.right-1].attr;
+ int clear_col;
+ for (clear_col = r.right; clear_col > 0; clear_col--) {
+ UCell *cell = &grid->cells[row][clear_col-1];
+ if (!(cell->data[0] == ' ' && cell->data[1] == NUL
+ && cell->attr == clear_attr)) {
+ break;
+ }
+ }
+
+ UGRID_FOREACH_CELL(grid, row, r.left, clear_col, {
+ cursor_goto(ui, row, curcol);
+ print_cell(ui, cell);
+ });
+ if (clear_col < r.right) {
+ clear_region(ui, row, row+1, clear_col, r.right, clear_attr);
}
- print_cell(ui, cell);
- });
+ }
}
- unibi_goto(ui, grid->row, grid->col);
+ cursor_goto(ui, data->row, data->col);
flush_buf(ui);
}
+/// Dumps termcap info to the messages area, if 'verbose' >= 3.
+static void show_termcap_event(void **argv)
+{
+ if (p_verbose < 3) {
+ return;
+ }
+ const unibi_term *const ut = argv[0];
+ if (!ut) {
+ abort();
+ }
+ verbose_enter();
+ // XXX: (future) if unibi_term is modified (e.g. after a terminal
+ // query-response) this is a race condition.
+ terminfo_info_msg(ut);
+ verbose_leave();
+ verbose_stop(); // flush now
+}
+
+#ifdef UNIX
static void suspend_event(void **argv)
{
UI *ui = argv[0];
@@ -615,70 +1219,118 @@ static void suspend_event(void **argv)
bool enable_mouse = data->mouse_enabled;
tui_terminal_stop(ui);
data->cont_received = false;
+ stream_set_blocking(input_global_fd(), true); // normalize stream (#2598)
kill(0, SIGTSTP);
while (!data->cont_received) {
// poll the event loop until SIGCONT is received
loop_poll_events(data->loop, -1);
}
tui_terminal_start(ui);
+ tui_terminal_after_startup(ui);
if (enable_mouse) {
tui_mouse_on(ui);
}
+ stream_set_blocking(input_global_fd(), false); // libuv expects this
// resume the main thread
CONTINUE(data->bridge);
}
+#endif
static void tui_suspend(UI *ui)
{
+#ifdef UNIX
TUIData *data = ui->data;
// kill(0, SIGTSTP) won't stop the UI thread, so we must poll for SIGCONT
// before continuing. This is done in another callback to avoid
// loop_poll_events recursion
- queue_put_event(data->loop->fast_events,
- event_create(1, suspend_event, 1, ui));
+ multiqueue_put_event(data->loop->fast_events,
+ event_create(suspend_event, 1, ui));
+#endif
}
-static void tui_set_title(UI *ui, char *title)
+static void tui_set_title(UI *ui, String title)
{
TUIData *data = ui->data;
- if (!(title && unibi_get_str(data->ut, unibi_to_status_line)
+ if (!(title.data && unibi_get_str(data->ut, unibi_to_status_line)
&& unibi_get_str(data->ut, unibi_from_status_line))) {
return;
}
unibi_out(ui, unibi_to_status_line);
- out(ui, title, strlen(title));
+ out(ui, title.data, title.size);
unibi_out(ui, unibi_from_status_line);
}
-static void tui_set_icon(UI *ui, char *icon)
+static void tui_set_icon(UI *ui, String icon)
{
}
+static void tui_option_set(UI *ui, String name, Object value)
+{
+ TUIData *data = ui->data;
+ if (strequal(name.data, "termguicolors")) {
+ ui->rgb = value.data.boolean;
+
+ data->print_attr_id = -1;
+ invalidate(ui, 0, data->grid.height, 0, data->grid.width);
+ }
+}
+
+static void tui_raw_line(UI *ui, Integer g, Integer linerow, Integer startcol,
+ Integer endcol, Integer clearcol, Integer clearattr,
+ Boolean wrap, const schar_T *chunk,
+ const sattr_T *attrs)
+{
+ TUIData *data = ui->data;
+ UGrid *grid = &data->grid;
+ for (Integer c = startcol; c < endcol; c++) {
+ memcpy(grid->cells[linerow][c].data, chunk[c-startcol], sizeof(schar_T));
+ assert((size_t)attrs[c-startcol] < kv_size(data->attrs));
+ grid->cells[linerow][c].attr = attrs[c-startcol];
+ }
+ UGRID_FOREACH_CELL(grid, (int)linerow, (int)startcol, (int)endcol, {
+ cursor_goto(ui, (int)linerow, curcol);
+ print_cell(ui, cell);
+ });
+
+ if (clearcol > endcol) {
+ ugrid_clear_chunk(grid, (int)linerow, (int)endcol, (int)clearcol,
+ (sattr_T)clearattr);
+ clear_region(ui, (int)linerow, (int)linerow+1, (int)endcol, (int)clearcol,
+ (int)clearattr);
+ }
+
+ if (wrap && ui->width == grid->width && linerow + 1 < grid->height) {
+ // Only do line wrapping if the grid width is equal to the terminal
+ // width and the line continuation is within the grid.
+
+ if (endcol != grid->width) {
+ // Print the last char of the row, if we haven't already done so.
+ int size = grid->cells[linerow][grid->width - 1].data[0] == NUL ? 2 : 1;
+ cursor_goto(ui, (int)linerow, grid->width - size);
+ print_cell(ui, &grid->cells[linerow][grid->width - size]);
+ }
+
+ // Wrap the cursor over to the next line. The next line will be
+ // printed immediately without an intervening newline.
+ final_column_wrap(ui);
+ }
+}
+
static void invalidate(UI *ui, int top, int bot, int left, int right)
{
TUIData *data = ui->data;
Rect *intersects = NULL;
- // Increase dimensions before comparing to ensure adjacent regions are
- // treated as intersecting
- --top;
- ++bot;
- --left;
- ++right;
for (size_t i = 0; i < kv_size(data->invalid_regions); i++) {
Rect *r = &kv_A(data->invalid_regions, i);
- if (!(top > r->bot || bot < r->top
- || left > r->right || right < r->left)) {
+ // adjacent regions are treated as overlapping
+ if (!(top > r->bot || bot < r->top)
+ && !(left > r->right || right < r->left)) {
intersects = r;
break;
}
}
- ++top;
- --bot;
- ++left;
- --right;
-
if (intersects) {
// If top/bot/left/right intersects with a invalid rect, we replace it
// by the union
@@ -740,39 +1392,61 @@ end:
static void unibi_goto(UI *ui, int row, int col)
{
TUIData *data = ui->data;
- data->params[0].i = row;
- data->params[1].i = col;
+ UNIBI_SET_NUM_VAR(data->params[0], row);
+ UNIBI_SET_NUM_VAR(data->params[1], col);
unibi_out(ui, unibi_cursor_address);
}
+#define UNIBI_OUT(fn) \
+ do { \
+ TUIData *data = ui->data; \
+ const char *str = NULL; \
+ if (unibi_index >= 0) { \
+ str = fn(data->ut, (unsigned)unibi_index); \
+ } \
+ if (str) { \
+ unibi_var_t vars[26 + 26]; \
+ size_t orig_pos = data->bufpos; \
+ \
+ memset(&vars, 0, sizeof(vars)); \
+ data->cork = true; \
+retry: \
+ unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL); \
+ if (data->overflow) { \
+ data->bufpos = orig_pos; \
+ flush_buf(ui); \
+ goto retry; \
+ } \
+ data->cork = false; \
+ } \
+ } while (0)
static void unibi_out(UI *ui, int unibi_index)
{
- TUIData *data = ui->data;
-
- const char *str = NULL;
-
- if (unibi_index >= 0) {
- if (unibi_index < unibi_string_begin_) {
- str = unibi_get_ext_str(data->ut, (unsigned)unibi_index);
- } else {
- str = unibi_get_str(data->ut, (unsigned)unibi_index);
- }
- }
-
- if (str) {
- unibi_var_t vars[26 + 26] = {{0}};
- unibi_format(vars, vars + 26, str, data->params, out, ui, NULL, NULL);
- }
+ UNIBI_OUT(unibi_get_str);
}
+static void unibi_out_ext(UI *ui, int unibi_index)
+{
+ UNIBI_OUT(unibi_get_ext_str);
+}
+#undef UNIBI_OUT
static void out(void *ctx, const char *str, size_t len)
{
UI *ui = ctx;
TUIData *data = ui->data;
- size_t available = data->bufsize - data->bufpos;
+ size_t available = sizeof(data->buf) - data->bufpos;
+
+ if (data->cork && data->overflow) {
+ return;
+ }
if (len > available) {
- flush_buf(ui);
+ if (data->cork) {
+ data->overflow = true;
+ return;
+ } else {
+ flush_buf(ui);
+ }
}
memcpy(data->buf + data->bufpos, str, len);
@@ -787,152 +1461,555 @@ static void unibi_set_if_empty(unibi_term *ut, enum unibi_string str,
}
}
-static void fix_terminfo(TUIData *data)
+static int unibi_find_ext_str(unibi_term *ut, const char *name)
+{
+ size_t max = unibi_count_ext_str(ut);
+ for (size_t i = 0; i < max; i++) {
+ const char * n = unibi_get_ext_str_name(ut, i);
+ if (n && 0 == strcmp(n, name)) {
+ return (int)i;
+ }
+ }
+ return -1;
+}
+
+static int unibi_find_ext_bool(unibi_term *ut, const char *name)
+{
+ size_t max = unibi_count_ext_bool(ut);
+ for (size_t i = 0; i < max; i++) {
+ const char * n = unibi_get_ext_bool_name(ut, i);
+ if (n && 0 == strcmp(n, name)) {
+ return (int)i;
+ }
+ }
+ return -1;
+}
+
+/// Patches the terminfo records after loading from system or built-in db.
+/// Several entries in terminfo are known to be deficient or outright wrong;
+/// and several terminal emulators falsely announce incorrect terminal types.
+static void patch_terminfo_bugs(TUIData *data, const char *term,
+ const char *colorterm, long vte_version,
+ long konsolev, bool iterm_env)
{
unibi_term *ut = data->ut;
+ const char *xterm_version = os_getenv("XTERM_VERSION");
+#if 0 // We don't need to identify this specifically, for now.
+ bool roxterm = !!os_getenv("ROXTERM_ID");
+#endif
+ bool xterm = terminfo_is_term_family(term, "xterm")
+ // Treat Terminal.app as generic xterm-like, for now.
+ || terminfo_is_term_family(term, "nsterm");
+ bool kitty = terminfo_is_term_family(term, "xterm-kitty");
+ bool linuxvt = terminfo_is_term_family(term, "linux");
+ bool bsdvt = terminfo_is_bsd_console(term);
+ bool rxvt = terminfo_is_term_family(term, "rxvt");
+ bool teraterm = terminfo_is_term_family(term, "teraterm");
+ bool putty = terminfo_is_term_family(term, "putty");
+ bool screen = terminfo_is_term_family(term, "screen");
+ bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX");
+ bool st = terminfo_is_term_family(term, "st");
+ bool gnome = terminfo_is_term_family(term, "gnome")
+ || terminfo_is_term_family(term, "vte");
+ bool iterm = terminfo_is_term_family(term, "iterm")
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app");
+ bool alacritty = terminfo_is_term_family(term, "alacritty");
+ // None of the following work over SSH; see :help TERM .
+ bool iterm_pretending_xterm = xterm && iterm_env;
+ bool konsole_pretending_xterm = xterm && konsolev;
+ bool gnome_pretending_xterm = xterm && colorterm
+ && strstr(colorterm, "gnome-terminal");
+ bool mate_pretending_xterm = xterm && colorterm
+ && strstr(colorterm, "mate-terminal");
+ bool true_xterm = xterm && !!xterm_version && !bsdvt;
+ bool cygwin = terminfo_is_term_family(term, "cygwin");
+
+ char *fix_normal = (char *)unibi_get_str(ut, unibi_cursor_normal);
+ if (fix_normal) {
+ if (STARTS_WITH(fix_normal, "\x1b[?12l")) {
+ // terminfo typically includes DECRST 12 as part of setting up the
+ // normal cursor, which interferes with the user's control via
+ // set_cursor_style. When DECRST 12 is present, skip over it, but honor
+ // the rest of the cnorm setting.
+ fix_normal += sizeof "\x1b[?12l" - 1;
+ unibi_set_str(ut, unibi_cursor_normal, fix_normal);
+ }
+ if (linuxvt
+ && strlen(fix_normal) >= (sizeof LINUXSET0C - 1)
+ && !memcmp(strchr(fix_normal, 0) - (sizeof LINUXSET0C - 1),
+ LINUXSET0C, sizeof LINUXSET0C - 1)) {
+ // The Linux terminfo entry similarly includes a Linux-idiosyncractic
+ // cursor shape reset in cnorm, which similarly interferes with
+ // set_cursor_style.
+ fix_normal[strlen(fix_normal) - (sizeof LINUXSET0C - 1)] = 0;
+ }
+ }
+ char *fix_invisible = (char *)unibi_get_str(ut, unibi_cursor_invisible);
+ if (fix_invisible) {
+ if (linuxvt
+ && strlen(fix_invisible) >= (sizeof LINUXSET1C - 1)
+ && !memcmp(strchr(fix_invisible, 0) - (sizeof LINUXSET1C - 1),
+ LINUXSET1C, sizeof LINUXSET1C - 1)) {
+ // The Linux terminfo entry similarly includes a Linux-idiosyncractic
+ // cursor shape reset in cinvis, which similarly interferes with
+ // set_cursor_style.
+ fix_invisible[strlen(fix_invisible) - (sizeof LINUXSET1C - 1)] = 0;
+ }
+ }
- const char *term = os_getenv("TERM");
- const char *colorterm = os_getenv("COLORTERM");
- if (!term) {
- goto end;
+ if (tmux || screen || kitty) {
+ // Disable BCE in some cases we know it is not working. #8806
+ unibi_set_bool(ut, unibi_back_color_erase, false);
}
- bool inside_tmux = os_getenv("TMUX") != NULL;
+ if (xterm) {
+ // Termit, LXTerminal, GTKTerm2, GNOME Terminal, MATE Terminal, roxterm,
+ // and EvilVTE falsely claim to be xterm and do not support important xterm
+ // control sequences that we use. In an ideal world, these would have
+ // their own terminal types and terminfo entries, like PuTTY does, and not
+ // claim to be xterm. Or they would mimic xterm properly enough to be
+ // treatable as xterm.
-#define STARTS_WITH(str, prefix) (!memcmp(str, prefix, sizeof(prefix) - 1))
+ // 2017-04 terminfo.src lacks these. genuine Xterm has them, as have
+ // the false claimants.
+ unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]0;");
+ unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
+ unibi_set_if_empty(ut, unibi_set_tb_margin, "\x1b[%i%p1%d;%p2%dr");
- if (STARTS_WITH(term, "rxvt")) {
- unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b[m\x1b(B");
- unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<20/>\x1b[?5l");
+ if (true_xterm) {
+ // 2017-04 terminfo.src lacks these. genuine Xterm has them.
+ unibi_set_if_empty(ut, unibi_set_lr_margin, "\x1b[%i%p1%d;%p2%ds");
+ unibi_set_if_empty(ut, unibi_set_left_margin_parm, "\x1b[%i%p1%ds");
+ unibi_set_if_empty(ut, unibi_set_right_margin_parm, "\x1b[%i;%p2%ds");
+ }
+ if (true_xterm
+ || iterm_pretending_xterm
+ || gnome_pretending_xterm
+ || konsole_pretending_xterm) {
+ // Apple's outdated copy of terminfo.src for MacOS lacks these.
+ // genuine Xterm and three false claimants have them.
+ unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m");
+ unibi_set_if_empty(ut, unibi_exit_italics_mode, "\x1b[23m");
+ }
+ } else if (rxvt) {
+ // 2017-04 terminfo.src lacks these. Unicode rxvt has them.
unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m");
+ unibi_set_if_empty(ut, unibi_exit_italics_mode, "\x1b[23m");
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]2");
- } else if (STARTS_WITH(term, "xterm")) {
- unibi_set_if_empty(ut, unibi_to_status_line, "\x1b]0;");
- } else if (STARTS_WITH(term, "screen") || STARTS_WITH(term, "tmux")) {
+ unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
+ // 2017-04 terminfo.src has older control sequences.
+ unibi_set_str(ut, unibi_enter_ca_mode, "\x1b[?1049h");
+ unibi_set_str(ut, unibi_exit_ca_mode, "\x1b[?1049l");
+ } else if (screen) {
+ // per the screen manual; 2017-04 terminfo.src lacks these.
unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
+ } else if (tmux) {
+ unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_");
+ unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\");
+ } else if (terminfo_is_term_family(term, "interix")) {
+ // 2017-04 terminfo.src lacks this.
+ unibi_set_if_empty(ut, unibi_carriage_return, "\x0d");
+ } else if (linuxvt) {
+ // Apple's outdated copy of terminfo.src for MacOS lacks these.
+ unibi_set_if_empty(ut, unibi_parm_up_cursor, "\x1b[%p1%dA");
+ unibi_set_if_empty(ut, unibi_parm_down_cursor, "\x1b[%p1%dB");
+ unibi_set_if_empty(ut, unibi_parm_right_cursor, "\x1b[%p1%dC");
+ unibi_set_if_empty(ut, unibi_parm_left_cursor, "\x1b[%p1%dD");
+ } else if (putty) {
+ // No bugs in the vanilla terminfo for our purposes.
+ } else if (iterm) {
+ // 2017-04 terminfo.src has older control sequences.
+ unibi_set_str(ut, unibi_enter_ca_mode, "\x1b[?1049h");
+ unibi_set_str(ut, unibi_exit_ca_mode, "\x1b[?1049l");
+ // 2017-04 terminfo.src lacks these.
+ unibi_set_if_empty(ut, unibi_set_tb_margin, "\x1b[%i%p1%d;%p2%dr");
+ unibi_set_if_empty(ut, unibi_orig_pair, "\x1b[39;49m");
+ unibi_set_if_empty(ut, unibi_enter_dim_mode, "\x1b[2m");
+ unibi_set_if_empty(ut, unibi_enter_italics_mode, "\x1b[3m");
+ unibi_set_if_empty(ut, unibi_exit_italics_mode, "\x1b[23m");
+ unibi_set_if_empty(ut, unibi_exit_underline_mode, "\x1b[24m");
+ unibi_set_if_empty(ut, unibi_exit_standout_mode, "\x1b[27m");
+ } else if (st) {
+ // No bugs in the vanilla terminfo for our purposes.
}
- if (STARTS_WITH(term, "xterm") || STARTS_WITH(term, "rxvt")) {
- unibi_set_if_empty(ut, unibi_cursor_normal, "\x1b[?12l\x1b[?25h");
- unibi_set_if_empty(ut, unibi_cursor_invisible, "\x1b[?25l");
- unibi_set_if_empty(ut, unibi_flash_screen, "\x1b[?5h$<100/>\x1b[?5l");
- unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b(B\x1b[m");
- unibi_set_if_empty(ut, unibi_change_scroll_region, "\x1b[%i%p1%d;%p2%dr");
- unibi_set_if_empty(ut, unibi_clear_screen, "\x1b[H\x1b[2J");
- unibi_set_if_empty(ut, unibi_from_status_line, "\x07");
- }
-
- data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?2004h");
- data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?2004l");
+// At this time (2017-07-12) it seems like all terminals that support 256
+// color codes can use semicolons in the terminal code and be fine.
+// However, this is not correct according to the spec. So to reward those
+// terminals that also support colons, we output the code that way on these
+// specific ones.
- data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?1004h");
- data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?1004l");
+// using colons like ISO 8613-6:1994/ITU T.416:1993 says.
+#define XTERM_SETAF_256_COLON \
+ "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38:5:%p1%d%;m"
+#define XTERM_SETAB_256_COLON \
+ "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48:5:%p1%d%;m"
- data->unibi_ext.get_bg = (int)unibi_add_ext_str(ut, NULL, "\x1b]11;?\x07");
-
-#define XTERM_SETAF \
+#define XTERM_SETAF_256 \
"\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m"
-#define XTERM_SETAB \
+#define XTERM_SETAB_256 \
"\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m"
+#define XTERM_SETAF_16 \
+ "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e39%;m"
+#define XTERM_SETAB_16 \
+ "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e39%;m"
+
+ data->unibi_ext.get_bg = (int)unibi_add_ext_str(ut, "ext.get_bg",
+ "\x1b]11;?\x07");
+
+ // Terminals with 256-colour SGR support despite what terminfo says.
+ if (unibi_get_num(ut, unibi_max_colors) < 256) {
+ // See http://fedoraproject.org/wiki/Features/256_Color_Terminals
+ if (true_xterm || iterm || iterm_pretending_xterm) {
+ unibi_set_num(ut, unibi_max_colors, 256);
+ unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF_256_COLON);
+ unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB_256_COLON);
+ } else if (konsolev || xterm || gnome || rxvt || st || putty
+ || linuxvt // Linux 4.8+ supports 256-colour SGR.
+ || mate_pretending_xterm || gnome_pretending_xterm
+ || tmux
+ || (colorterm && strstr(colorterm, "256"))
+ || (term && strstr(term, "256"))) {
+ unibi_set_num(ut, unibi_max_colors, 256);
+ unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF_256);
+ unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB_256);
+ }
+ }
+ // Terminals with 16-colour SGR support despite what terminfo says.
+ if (unibi_get_num(ut, unibi_max_colors) < 16) {
+ if (colorterm) {
+ unibi_set_num(ut, unibi_max_colors, 16);
+ unibi_set_if_empty(ut, unibi_set_a_foreground, XTERM_SETAF_16);
+ unibi_set_if_empty(ut, unibi_set_a_background, XTERM_SETAB_16);
+ }
+ }
- if ((colorterm && strstr(colorterm, "256"))
- || strstr(term, "256")
- || strstr(term, "xterm")) {
- // Assume TERM~=xterm or COLORTERM~=256 supports 256 colors.
- unibi_set_num(ut, unibi_max_colors, 256);
- unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF);
- unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB);
+ // Blacklist of terminals that cannot be trusted to report DECSCUSR support.
+ if (!(st || (vte_version != 0 && vte_version < 3900) || konsolev)) {
+ data->unibi_ext.reset_cursor_style = unibi_find_ext_str(ut, "Se");
+ data->unibi_ext.set_cursor_style = unibi_find_ext_str(ut, "Ss");
}
- if (os_getenv("NVIM_TUI_ENABLE_CURSOR_SHAPE") == NULL) {
- goto end;
+ // Dickey ncurses terminfo includes Ss/Se capabilities since 2011-07-14. So
+ // adding them to terminal types, that have such control sequences but lack
+ // the correct terminfo entries, is a fixup, not an augmentation.
+ if (-1 == data->unibi_ext.set_cursor_style) {
+ // DECSCUSR (cursor shape) is widely supported.
+ // https://github.com/gnachman/iTerm2/pull/92
+ if ((!bsdvt && (!konsolev || konsolev >= 180770))
+ && ((xterm && !vte_version) // anything claiming xterm compat
+ // per MinTTY 0.4.3-1 release notes from 2009
+ || putty
+ // per https://bugzilla.gnome.org/show_bug.cgi?id=720821
+ || (vte_version >= 3900)
+ || (konsolev >= 180770) // #9364
+ || tmux // per tmux manual page
+ // https://lists.gnu.org/archive/html/screen-devel/2013-03/msg00000.html
+ || screen
+ || st // #7641
+ || rxvt // per command.C
+ // per analysis of VT100Terminal.m
+ || iterm || iterm_pretending_xterm
+ || teraterm // per TeraTerm "Supported Control Functions" doco
+ || alacritty // https://github.com/jwilm/alacritty/pull/608
+ || cygwin
+ // Some linux-type terminals implement the xterm extension.
+ // Example: console-terminal-emulator from the nosh toolset.
+ || (linuxvt
+ && (xterm_version || (vte_version > 0) || colorterm)))) {
+ data->unibi_ext.set_cursor_style =
+ (int)unibi_add_ext_str(ut, "Ss", "\x1b[%p1%d q");
+ if (-1 == data->unibi_ext.reset_cursor_style) {
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
+ }
+ unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
+ "\x1b[ q");
+ } else if (linuxvt) {
+ // Linux uses an idiosyncratic escape code to set the cursor shape and
+ // does not support DECSCUSR.
+ // See http://linuxgazette.net/137/anonymous.html for more info
+ data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
+ "\x1b[?"
+ "%?"
+ // The parameter passed to Ss is the DECSCUSR parameter, so the
+ // terminal capability has to translate into the Linux idiosyncratic
+ // parameter.
+ //
+ // linuxvt only supports block and underline. It is also only
+ // possible to have a steady block (no steady underline)
+ "%p1%{2}%<" "%t%{8}" // blink block
+ "%e%p1%{2}%=" "%t%{112}" // steady block
+ "%e%p1%{3}%=" "%t%{4}" // blink underline (set to half block)
+ "%e%p1%{4}%=" "%t%{4}" // steady underline
+ "%e%p1%{5}%=" "%t%{2}" // blink bar (set to underline)
+ "%e%p1%{6}%=" "%t%{2}" // steady bar
+ "%e%{0}" // anything else
+ "%;" "%dc");
+ if (-1 == data->unibi_ext.reset_cursor_style) {
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
+ }
+ unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
+ "\x1b[?c");
+ } else if (konsolev > 0 && konsolev < 180770) {
+ // Konsole before version 18.07.70: set up a nonce profile. This has
+ // side-effects on temporary font resizing. #6798
+ data->unibi_ext.set_cursor_style = (int)unibi_add_ext_str(ut, "Ss",
+ TMUX_WRAP(tmux, "\x1b]50;CursorShape=%?"
+ "%p1%{3}%<" "%t%{0}" // block
+ "%e%p1%{5}%<" "%t%{2}" // underline
+ "%e%{1}" // everything else is bar
+ "%;%d;BlinkingCursorEnabled=%?"
+ "%p1%{1}%<" "%t%{1}" // Fortunately if we exclude zero as special,
+ "%e%p1%{1}%&" // in all other cases we can treat bit #0 as a flag.
+ "%;%d\x07"));
+ if (-1 == data->unibi_ext.reset_cursor_style) {
+ data->unibi_ext.reset_cursor_style = (int)unibi_add_ext_str(ut, "Se",
+ "");
+ }
+ unibi_set_ext_str(ut, (size_t)data->unibi_ext.reset_cursor_style,
+ "\x1b]50;\x07");
+ }
}
+}
-#define TMUX_WRAP(seq) (inside_tmux ? "\x1bPtmux;\x1b" seq "\x1b\\" : seq)
- // Support changing cursor shape on some popular terminals.
- const char *term_prog = os_getenv("TERM_PROGRAM");
- const char *vte_version = os_getenv("VTE_VERSION");
-
- if ((term_prog && !strcmp(term_prog, "Konsole"))
- || os_getenv("KONSOLE_DBUS_SESSION") != NULL) {
- // Konsole uses a proprietary escape code to set the cursor shape
- // and does not support DECSCUSR.
- data->unibi_ext.enter_insert_mode = (int)unibi_add_ext_str(ut, NULL,
- TMUX_WRAP("\x1b]50;CursorShape=1;BlinkingCursorEnabled=1\x07"));
- data->unibi_ext.enter_replace_mode = (int)unibi_add_ext_str(ut, NULL,
- TMUX_WRAP("\x1b]50;CursorShape=2;BlinkingCursorEnabled=1\x07"));
- data->unibi_ext.exit_insert_mode = (int)unibi_add_ext_str(ut, NULL,
- TMUX_WRAP("\x1b]50;CursorShape=0;BlinkingCursorEnabled=0\x07"));
- } else if (!vte_version || atoi(vte_version) >= 3900) {
- // Assume that the terminal supports DECSCUSR unless it is an
- // old VTE based terminal. This should not get wrapped for tmux,
- // which will handle it via its Ss/Se terminfo extension - usually
- // according to its terminal-overrides.
- data->unibi_ext.enter_insert_mode = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[5 q");
- data->unibi_ext.enter_replace_mode = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[3 q");
- data->unibi_ext.exit_insert_mode = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[2 q");
+/// This adds stuff that is not in standard terminfo as extended unibilium
+/// capabilities.
+static void augment_terminfo(TUIData *data, const char *term,
+ const char *colorterm, long vte_version,
+ long konsolev, bool iterm_env)
+{
+ unibi_term *ut = data->ut;
+ bool xterm = terminfo_is_term_family(term, "xterm")
+ // Treat Terminal.app as generic xterm-like, for now.
+ || terminfo_is_term_family(term, "nsterm");
+ bool bsdvt = terminfo_is_bsd_console(term);
+ bool dtterm = terminfo_is_term_family(term, "dtterm");
+ bool rxvt = terminfo_is_term_family(term, "rxvt");
+ bool teraterm = terminfo_is_term_family(term, "teraterm");
+ bool putty = terminfo_is_term_family(term, "putty");
+ bool screen = terminfo_is_term_family(term, "screen");
+ bool tmux = terminfo_is_term_family(term, "tmux") || !!os_getenv("TMUX");
+ bool iterm = terminfo_is_term_family(term, "iterm")
+ || terminfo_is_term_family(term, "iterm2")
+ || terminfo_is_term_family(term, "iTerm.app")
+ || terminfo_is_term_family(term, "iTerm2.app");
+ bool alacritty = terminfo_is_term_family(term, "alacritty");
+ // None of the following work over SSH; see :help TERM .
+ bool iterm_pretending_xterm = xterm && iterm_env;
+
+ const char *xterm_version = os_getenv("XTERM_VERSION");
+ bool true_xterm = xterm && !!xterm_version && !bsdvt;
+
+ // Only define this capability for terminal types that we know understand it.
+ if (dtterm // originated this extension
+ || xterm // per xterm ctlseqs doco
+ || konsolev // per commentary in VT102Emulation.cpp
+ || teraterm // per TeraTerm "Supported Control Functions" doco
+ || rxvt) { // per command.C
+ data->unibi_ext.resize_screen = (int)unibi_add_ext_str(ut,
+ "ext.resize_screen",
+ "\x1b[8;%p1%d;%p2%dt");
+ }
+ if (putty || xterm || rxvt) {
+ data->unibi_ext.reset_scroll_region = (int)unibi_add_ext_str(ut,
+ "ext.reset_scroll_region",
+ "\x1b[r");
}
-end:
- // Fill some empty slots with common terminal strings
- data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?1002h\x1b[?1006h");
- data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[?1002l\x1b[?1006l");
- data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[38;2;%p1%d;%p2%d;%p3%dm");
- data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, NULL,
- "\x1b[48;2;%p1%d;%p2%d;%p3%dm");
- unibi_set_if_empty(ut, unibi_cursor_address, "\x1b[%i%p1%d;%p2%dH");
- unibi_set_if_empty(ut, unibi_exit_attribute_mode, "\x1b[0;10m");
- unibi_set_if_empty(ut, unibi_set_a_foreground, XTERM_SETAF);
- unibi_set_if_empty(ut, unibi_set_a_background, XTERM_SETAB);
- unibi_set_if_empty(ut, unibi_enter_bold_mode, "\x1b[1m");
- unibi_set_if_empty(ut, unibi_enter_underline_mode, "\x1b[4m");
- unibi_set_if_empty(ut, unibi_enter_reverse_mode, "\x1b[7m");
- unibi_set_if_empty(ut, unibi_bell, "\x07");
- unibi_set_if_empty(data->ut, unibi_enter_ca_mode, "\x1b[?1049h");
- unibi_set_if_empty(data->ut, unibi_exit_ca_mode, "\x1b[?1049l");
- unibi_set_if_empty(ut, unibi_delete_line, "\x1b[M");
- unibi_set_if_empty(ut, unibi_parm_delete_line, "\x1b[%p1%dM");
- unibi_set_if_empty(ut, unibi_insert_line, "\x1b[L");
- unibi_set_if_empty(ut, unibi_parm_insert_line, "\x1b[%p1%dL");
- unibi_set_if_empty(ut, unibi_clear_screen, "\x1b[H\x1b[J");
- unibi_set_if_empty(ut, unibi_clr_eol, "\x1b[K");
- unibi_set_if_empty(ut, unibi_clr_eos, "\x1b[J");
+ // Dickey ncurses terminfo does not include the setrgbf and setrgbb
+ // capabilities, proposed by Rüdiger Sonderfeld on 2013-10-15. Adding
+ // them here when terminfo lacks them is an augmentation, not a fixup.
+ // https://gist.github.com/XVilka/8346728
+
+ // At this time (2017-07-12) it seems like all terminals that support rgb
+ // color codes can use semicolons in the terminal code and be fine.
+ // However, this is not correct according to the spec. So to reward those
+ // terminals that also support colons, we output the code that way on these
+ // specific ones.
+
+ // can use colons like ISO 8613-6:1994/ITU T.416:1993 says.
+ bool has_colon_rgb = !tmux && !screen
+ && !vte_version // VTE colon-support has a big memory leak. #7573
+ && (iterm || iterm_pretending_xterm // per VT100Terminal.m
+ // per http://invisible-island.net/xterm/xterm.log.html#xterm_282
+ || true_xterm);
+
+ data->unibi_ext.set_rgb_foreground = unibi_find_ext_str(ut, "setrgbf");
+ if (-1 == data->unibi_ext.set_rgb_foreground) {
+ if (has_colon_rgb) {
+ data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf",
+ "\x1b[38:2:%p1%d:%p2%d:%p3%dm");
+ } else {
+ data->unibi_ext.set_rgb_foreground = (int)unibi_add_ext_str(ut, "setrgbf",
+ "\x1b[38;2;%p1%d;%p2%d;%p3%dm");
+ }
+ }
+ data->unibi_ext.set_rgb_background = unibi_find_ext_str(ut, "setrgbb");
+ if (-1 == data->unibi_ext.set_rgb_background) {
+ if (has_colon_rgb) {
+ data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb",
+ "\x1b[48:2:%p1%d:%p2%d:%p3%dm");
+ } else {
+ data->unibi_ext.set_rgb_background = (int)unibi_add_ext_str(ut, "setrgbb",
+ "\x1b[48;2;%p1%d;%p2%d;%p3%dm");
+ }
+ }
+
+ if (iterm || iterm_pretending_xterm) {
+ // FIXME: Bypassing tmux like this affects the cursor colour globally, in
+ // all panes, which is not particularly desirable. A better approach
+ // would use a tmux control sequence and an extra if(screen) test.
+ data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
+ ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\"));
+ } else if ((xterm || rxvt || alacritty)
+ && (vte_version == 0 || vte_version >= 3900)) {
+ // Supported in urxvt, newer VTE.
+ data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str(
+ ut, "ext.set_cursor_color", "\033]12;#%p1%06x\007");
+ }
+
+ if (-1 != data->unibi_ext.set_cursor_color) {
+ data->unibi_ext.reset_cursor_color = (int)unibi_add_ext_str(
+ ut, "ext.reset_cursor_color", "\x1b]112\x07");
+ }
+
+ data->unibi_ext.save_title = (int)unibi_add_ext_str(
+ ut, "ext.save_title", "\x1b[22;0;0t");
+ data->unibi_ext.restore_title = (int)unibi_add_ext_str(
+ ut, "ext.restore_title", "\x1b[23;0;0t");
+
+ /// Terminals usually ignore unrecognized private modes, and there is no
+ /// known ambiguity with these. So we just set them unconditionally.
+ data->unibi_ext.enable_lr_margin = (int)unibi_add_ext_str(
+ ut, "ext.enable_lr_margin", "\x1b[?69h");
+ data->unibi_ext.disable_lr_margin = (int)unibi_add_ext_str(
+ ut, "ext.disable_lr_margin", "\x1b[?69l");
+ data->unibi_ext.enable_bracketed_paste = (int)unibi_add_ext_str(
+ ut, "ext.enable_bpaste", "\x1b[?2004h");
+ data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(
+ ut, "ext.disable_bpaste", "\x1b[?2004l");
+ // For urxvt send BOTH xterm and old urxvt sequences. #8695
+ data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(
+ ut, "ext.enable_focus",
+ rxvt ? "\x1b[?1004h\x1b]777;focus;on\x7" : "\x1b[?1004h");
+ data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(
+ ut, "ext.disable_focus",
+ rxvt ? "\x1b[?1004l\x1b]777;focus;off\x7" : "\x1b[?1004l");
+ data->unibi_ext.enable_mouse = (int)unibi_add_ext_str(
+ ut, "ext.enable_mouse", "\x1b[?1002h\x1b[?1006h");
+ data->unibi_ext.disable_mouse = (int)unibi_add_ext_str(
+ ut, "ext.disable_mouse", "\x1b[?1002l\x1b[?1006l");
+
+ int ext_bool_Su = unibi_find_ext_bool(ut, "Su"); // used by kitty
+ if (vte_version >= 5102
+ || (ext_bool_Su != -1 && unibi_get_ext_bool(ut, (size_t)ext_bool_Su))) {
+ data->unibi_ext.enter_undercurl_mode = (int)unibi_add_ext_str(
+ ut, "ext.enter_undercurl_mode", "\x1b[4:3m");
+ data->unibi_ext.exit_undercurl_mode = (int)unibi_add_ext_str(
+ ut, "ext.exit_undercurl_mode", "\x1b[4:0m");
+ // Only support colon syntax. #9270
+ data->unibi_ext.set_underline_color = (int)unibi_add_ext_str(
+ ut, "ext.set_underline_color", "\x1b[58:2::%p1%d:%p2%d:%p3%dm");
+ }
}
static void flush_buf(UI *ui)
{
uv_write_t req;
- uv_buf_t buf;
+ uv_buf_t bufs[3];
+ uv_buf_t *bufp = &bufs[0];
TUIData *data = ui->data;
+ if (data->bufpos <= 0 && data->busy == data->is_invisible) {
+ return;
+ }
+
+ if (!data->is_invisible) {
+ // cursor is visible. Write a "cursor invisible" command before writing the
+ // buffer.
+ bufp->base = data->invis;
+ bufp->len = UV_BUF_LEN(data->invislen);
+ bufp++;
+ data->is_invisible = true;
+ }
+
+ if (data->bufpos > 0) {
+ bufp->base = data->buf;
+ bufp->len = UV_BUF_LEN(data->bufpos);
+ bufp++;
+ }
+
if (!data->busy) {
- // not busy and the cursor is invisible(see below). Append a "cursor
- // normal" command to the end of the buffer.
- data->bufsize += CNORM_COMMAND_MAX_SIZE;
- unibi_out(ui, unibi_cursor_normal);
- data->bufsize -= CNORM_COMMAND_MAX_SIZE;
+ assert(data->is_invisible);
+ // not busy and the cursor is invisible. Write a "cursor normal" command
+ // after writing the buffer.
+ bufp->base = data->norm;
+ bufp->len = UV_BUF_LEN(data->normlen);
+ bufp++;
+ data->is_invisible = data->busy;
}
- buf.base = data->buf;
- buf.len = data->bufpos;
- uv_write(&req, (uv_stream_t *)&data->output_handle, &buf, 1, NULL);
+ uv_write(&req, STRUCT_CAST(uv_stream_t, &data->output_handle),
+ bufs, (unsigned)(bufp - bufs), NULL);
uv_run(&data->write_loop, UV_RUN_DEFAULT);
data->bufpos = 0;
+ data->overflow = false;
+}
- if (!data->busy) {
- // not busy and cursor is visible(see above), append a "cursor invisible"
- // command to the beginning of the buffer for the next flush
- unibi_out(ui, unibi_cursor_invisible);
+#if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18
+/// Try to get "kbs" code from stty because "the terminfo kbs entry is extremely
+/// unreliable." (Vim, Bash, and tmux also do this.)
+///
+/// @see tmux/tty-keys.c fe4e9470bb504357d073320f5d305b22663ee3fd
+/// @see https://bugzilla.redhat.com/show_bug.cgi?id=142659
+static const char *tui_get_stty_erase(void)
+{
+ static char stty_erase[2] = { 0 };
+#if defined(HAVE_TERMIOS_H)
+ struct termios t;
+ if (tcgetattr(input_global_fd(), &t) != -1) {
+ stty_erase[0] = (char)t.c_cc[VERASE];
+ stty_erase[1] = '\0';
+ DLOG("stty/termios:erase=%s", stty_erase);
}
+#endif
+ return stty_erase;
}
+
+/// libtermkey hook to override terminfo entries.
+/// @see TermInput.tk_ti_hook_fn
+static const char *tui_tk_ti_getstr(const char *name, const char *value,
+ void *data)
+{
+ static const char *stty_erase = NULL;
+ if (stty_erase == NULL) {
+ stty_erase = tui_get_stty_erase();
+ }
+
+ if (strequal(name, "key_backspace")) {
+ DLOG("libtermkey:kbs=%s", value);
+ if (stty_erase[0] != 0) {
+ return stty_erase;
+ }
+ } else if (strequal(name, "key_dc")) {
+ DLOG("libtermkey:kdch1=%s", value);
+ // Vim: "If <BS> and <DEL> are now the same, redefine <DEL>."
+ if (value != NULL && strequal(stty_erase, value)) {
+ return stty_erase[0] == DEL ? CTRL_H_STR : DEL_STR;
+ }
+ } else if (strequal(name, "key_mouse")) {
+ DLOG("libtermkey:kmous=%s", value);
+ // If key_mouse is found, libtermkey uses its terminfo driver (driver-ti.c)
+ // for mouse input, which by accident only supports X10 protocol.
+ // Force libtermkey to fallback to its CSI driver (driver-csi.c). #7948
+ return NULL;
+ }
+
+ return value;
+}
+#endif
diff --git a/src/nvim/tui/tui.h b/src/nvim/tui/tui.h
index 07523bc124..996496ee60 100644
--- a/src/nvim/tui/tui.h
+++ b/src/nvim/tui/tui.h
@@ -1,6 +1,9 @@
#ifndef NVIM_TUI_TUI_H
#define NVIM_TUI_TUI_H
+#include "nvim/cursor_shape.h"
+#include "nvim/ui.h"
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tui/tui.h.generated.h"
#endif
diff --git a/src/nvim/types.h b/src/nvim/types.h
index bfe8be2091..f803b45e27 100644
--- a/src/nvim/types.h
+++ b/src/nvim/types.h
@@ -13,4 +13,9 @@ typedef unsigned char char_u;
// Can hold one decoded UTF-8 character.
typedef uint32_t u8char_T;
+// Opaque handle used by API clients to refer to various objects in vim
+typedef int handle_T;
+
+typedef struct expand expand_T;
+
#endif // NVIM_TYPES_H
diff --git a/src/nvim/ugrid.c b/src/nvim/ugrid.c
index 127b18feb6..f5bd35a48e 100644
--- a/src/nvim/ugrid.c
+++ b/src/nvim/ugrid.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 <stdio.h>
@@ -13,8 +16,6 @@
void ugrid_init(UGrid *grid)
{
- grid->attrs = EMPTY_ATTRS;
- grid->fg = grid->bg = -1;
grid->cells = NULL;
}
@@ -31,23 +32,18 @@ void ugrid_resize(UGrid *grid, int width, int height)
grid->cells[i] = xcalloc((size_t)width, sizeof(UCell));
}
- grid->top = 0;
- grid->bot = height - 1;
- grid->left = 0;
- grid->right = width - 1;
- grid->row = grid->col = 0;
grid->width = width;
grid->height = height;
}
void ugrid_clear(UGrid *grid)
{
- clear_region(grid, grid->top, grid->bot, grid->left, grid->right);
+ clear_region(grid, 0, grid->height-1, 0, grid->width-1, 0);
}
-void ugrid_eol_clear(UGrid *grid)
+void ugrid_clear_chunk(UGrid *grid, int row, int col, int endcol, sattr_T attr)
{
- clear_region(grid, grid->row, grid->row, grid->col, grid->right);
+ clear_region(grid, row, row, col, endcol-1, attr);
}
void ugrid_goto(UGrid *grid, int row, int col)
@@ -56,25 +52,17 @@ void ugrid_goto(UGrid *grid, int row, int col)
grid->col = col;
}
-void ugrid_set_scroll_region(UGrid *grid, int top, int bot, int left, int right)
-{
- grid->top = top;
- grid->bot = bot;
- grid->left = left;
- grid->right = right;
-}
-
-void ugrid_scroll(UGrid *grid, int count, int *clear_top, int *clear_bot)
+void ugrid_scroll(UGrid *grid, int top, int bot, int left, int right, int count)
{
// Compute start/stop/step for the loop below
int start, stop, step;
if (count > 0) {
- start = grid->top;
- stop = grid->bot - count + 1;
+ start = top;
+ stop = bot - count + 1;
step = 1;
} else {
- start = grid->bot;
- stop = grid->top - count - 1;
+ start = bot;
+ stop = top - count - 1;
step = -1;
}
@@ -82,47 +70,23 @@ void ugrid_scroll(UGrid *grid, int count, int *clear_top, int *clear_bot)
// Copy cell data
for (i = start; i != stop; i += step) {
- UCell *target_row = grid->cells[i] + grid->left;
- UCell *source_row = grid->cells[i + count] + grid->left;
+ UCell *target_row = grid->cells[i] + left;
+ UCell *source_row = grid->cells[i + count] + left;
memcpy(target_row, source_row,
- sizeof(UCell) * (size_t)(grid->right - grid->left + 1));
+ sizeof(UCell) * (size_t)(right - left + 1));
}
-
- // clear cells in the emptied region,
- if (count > 0) {
- *clear_top = stop;
- *clear_bot = stop + count - 1;
- } else {
- *clear_bot = stop;
- *clear_top = stop + count + 1;
- }
- clear_region(grid, *clear_top, *clear_bot, grid->left, grid->right);
}
-UCell *ugrid_put(UGrid *grid, uint8_t *text, size_t size)
+static void clear_region(UGrid *grid, int top, int bot, int left, int right,
+ sattr_T attr)
{
- UCell *cell = grid->cells[grid->row] + grid->col;
- cell->data[size] = 0;
- cell->attrs = grid->attrs;
-
- if (text) {
- memcpy(cell->data, text, size);
+ for (int row = top; row <= bot; row++) {
+ UGRID_FOREACH_CELL(grid, row, left, right+1, {
+ cell->data[0] = ' ';
+ cell->data[1] = 0;
+ cell->attr = attr;
+ });
}
-
- grid->col += 1;
- return cell;
-}
-
-static void clear_region(UGrid *grid, int top, int bot, int left, int right)
-{
- HlAttrs clear_attrs = EMPTY_ATTRS;
- clear_attrs.foreground = grid->fg;
- clear_attrs.background = grid->bg;
- UGRID_FOREACH_CELL(grid, top, bot, left, right, {
- cell->data[0] = ' ';
- cell->data[1] = 0;
- cell->attrs = clear_attrs;
- });
}
static void destroy_cells(UGrid *grid)
@@ -132,6 +96,7 @@ static void destroy_cells(UGrid *grid)
xfree(grid->cells[i]);
}
xfree(grid->cells);
+ grid->cells = NULL;
}
}
diff --git a/src/nvim/ugrid.h b/src/nvim/ugrid.h
index 268362bf1b..19c2e99ebb 100644
--- a/src/nvim/ugrid.h
+++ b/src/nvim/ugrid.h
@@ -7,31 +7,28 @@
typedef struct ucell UCell;
typedef struct ugrid UGrid;
+#define CELLBYTES (sizeof(schar_T))
+
struct ucell {
- char data[6 * MAX_MCO + 1];
- HlAttrs attrs;
+ char data[CELLBYTES + 1];
+ sattr_T attr;
};
struct ugrid {
- int top, bot, left, right;
int row, col;
- int bg, fg;
int width, height;
- HlAttrs attrs;
UCell **cells;
};
-#define EMPTY_ATTRS ((HlAttrs){ false, false, false, false, false, -1, -1, -1 })
+// -V:UGRID_FOREACH_CELL:625
-#define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \
+#define UGRID_FOREACH_CELL(grid, row, startcol, endcol, code) \
do { \
- for (int row = top; row <= bot; row++) { \
- UCell *row_cells = (grid)->cells[row]; \
- for (int col = left; col <= right; col++) { \
- UCell *cell = row_cells + col; \
- (void)(cell); \
- code; \
- } \
+ UCell *row_cells = (grid)->cells[row]; \
+ for (int curcol = startcol; curcol < endcol; curcol++) { \
+ UCell *cell = row_cells + curcol; \
+ (void)(cell); \
+ code; \
} \
} while (0)
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index d968cbc390..96232ab223 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.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 <inttypes.h>
#include <stdbool.h>
@@ -5,17 +8,17 @@
#include <limits.h>
#include "nvim/vim.h"
+#include "nvim/log.h"
#include "nvim/ui.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
#include "nvim/ex_cmds2.h"
+#include "nvim/ex_getln.h"
#include "nvim/fold.h"
#include "nvim/main.h"
-#include "nvim/mbyte.h"
#include "nvim/ascii.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/mbyte.h"
#include "nvim/garray.h"
#include "nvim/memory.h"
@@ -27,14 +30,17 @@
#include "nvim/os/time.h"
#include "nvim/os/input.h"
#include "nvim/os/signal.h"
+#include "nvim/popupmnu.h"
#include "nvim/screen.h"
-#include "nvim/syntax.h"
+#include "nvim/highlight.h"
#include "nvim/window.h"
+#include "nvim/cursor_shape.h"
#ifdef FEAT_TUI
# include "nvim/tui/tui.h"
#else
# include "nvim/msgpack_rpc/server.h"
#endif
+#include "nvim/api/private/helpers.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui.c.generated.h"
@@ -43,26 +49,45 @@
#define MAX_UI_COUNT 16
static UI *uis[MAX_UI_COUNT];
+static bool ui_ext[kUIExtCount] = { 0 };
static size_t ui_count = 0;
-static int row = 0, col = 0;
-static struct {
- int top, bot, left, right;
-} sr;
-static int current_attr_code = 0;
+static int ui_mode_idx = SHAPE_IDX_N;
+static int cursor_row = 0, cursor_col = 0;
static bool pending_cursor_update = false;
static int busy = 0;
-static int height, width;
+static bool pending_mode_info_update = false;
+static bool pending_mode_update = false;
+static handle_T cursor_grid_handle = DEFAULT_GRID_HANDLE;
-// This set of macros allow us to use UI_CALL to invoke any function on
-// registered UI instances. The functions can have 0-5 arguments(configurable
-// by SELECT_NTH)
+#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
+# define UI_LOG(funname, ...)
+#else
+static size_t uilog_seen = 0;
+static char uilog_last_event[1024] = { 0 };
+# define UI_LOG(funname, ...) \
+ do { \
+ if (strequal(uilog_last_event, STR(funname))) { \
+ uilog_seen++; \
+ } else { \
+ if (uilog_seen > 0) { \
+ logmsg(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, \
+ "%s (+%zu times...)", uilog_last_event, uilog_seen); \
+ } \
+ logmsg(DEBUG_LOG_LEVEL, "UI: ", NULL, -1, true, STR(funname)); \
+ uilog_seen = 0; \
+ xstrlcpy(uilog_last_event, STR(funname), sizeof(uilog_last_event)); \
+ } \
+ } while (0)
+#endif
+
+// UI_CALL invokes a function on all registered UI instances. The functions can
+// have 0-10 arguments (configurable by SELECT_NTH).
//
-// See http://stackoverflow.com/a/11172679 for a better explanation of how it
-// works.
+// See http://stackoverflow.com/a/11172679 for how it works.
#ifdef _MSC_VER
# define UI_CALL(funname, ...) \
do { \
- flush_cursor_update(); \
+ UI_LOG(funname, 0); \
for (size_t i = 0; i < ui_count; i++) { \
UI *ui = uis[i]; \
UI_CALL_MORE(funname, __VA_ARGS__); \
@@ -71,37 +96,42 @@ static int height, width;
#else
# define UI_CALL(...) \
do { \
- flush_cursor_update(); \
+ UI_LOG(__VA_ARGS__, 0); \
for (size_t i = 0; i < ui_count; i++) { \
UI *ui = uis[i]; \
UI_CALL_HELPER(CNT(__VA_ARGS__), __VA_ARGS__); \
} \
} while (0)
#endif
-#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, MORE, ZERO, ignore)
-#define SELECT_NTH(a1, a2, a3, a4, a5, a6, ...) a6
+#define CNT(...) SELECT_NTH(__VA_ARGS__, MORE, MORE, MORE, MORE, MORE, \
+ MORE, MORE, MORE, MORE, ZERO, ignore)
+#define SELECT_NTH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11
#define UI_CALL_HELPER(c, ...) UI_CALL_HELPER2(c, __VA_ARGS__)
+// Resolves to UI_CALL_MORE or UI_CALL_ZERO.
#define UI_CALL_HELPER2(c, ...) UI_CALL_##c(__VA_ARGS__)
#define UI_CALL_MORE(method, ...) if (ui->method) ui->method(ui, __VA_ARGS__)
#define UI_CALL_ZERO(method) if (ui->method) ui->method(ui)
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "ui_events_call.generated.h"
+#endif
+
void ui_builtin_start(void)
{
#ifdef FEAT_TUI
tui_start();
#else
- fprintf(stderr, "Neovim was built without a Terminal UI," \
- "press Ctrl+C to exit\n");
-
+ fprintf(stderr, "Nvim headless-mode started.\n");
size_t len;
char **addrs = server_address_list(&len);
if (addrs != NULL) {
- fprintf(stderr, "currently listening on the following address(es)\n");
+ fprintf(stderr, "Listening on:\n");
for (size_t i = 0; i < len; i++) {
fprintf(stderr, "\t%s\n", addrs[i]);
}
xfree(addrs);
}
+ fprintf(stderr, "Press CTRL+C to exit.\n");
#endif
}
@@ -112,6 +142,9 @@ void ui_builtin_stop(void)
bool ui_rgb_attached(void)
{
+ if (!headless_mode && p_tgc) {
+ return true;
+ }
for (size_t i = 0; i < ui_count; i++) {
if (uis[i]->rgb) {
return true;
@@ -125,29 +158,15 @@ bool ui_active(void)
return ui_count != 0;
}
-void ui_suspend(void)
-{
- UI_CALL(suspend);
- UI_CALL(flush);
-}
-
-void ui_set_title(char *title)
+void ui_event(char *name, Array args)
{
- UI_CALL(set_title, title);
- UI_CALL(flush);
+ bool args_consumed = false;
+ UI_CALL(event, name, args, &args_consumed);
+ if (!args_consumed) {
+ api_free_array(args);
+ }
}
-void ui_set_icon(char *icon)
-{
- UI_CALL(set_icon, icon);
- UI_CALL(flush);
-}
-
-// May update the shape of the cursor.
-void ui_cursor_shape(void)
-{
- ui_mode_change();
-}
void ui_refresh(void)
{
@@ -155,56 +174,82 @@ void ui_refresh(void)
return;
}
+ if (updating_screen) {
+ ui_schedule_refresh();
+ return;
+ }
+
int width = INT_MAX, height = INT_MAX;
+ bool ext_widgets[kUIExtCount];
+ for (UIExtension i = 0; (int)i < kUIExtCount; i++) {
+ ext_widgets[i] = true;
+ }
for (size_t i = 0; i < ui_count; i++) {
UI *ui = uis[i];
- width = ui->width < width ? ui->width : width;
- height = ui->height < height ? ui->height : height;
+ width = MIN(ui->width, width);
+ height = MIN(ui->height, height);
+ for (UIExtension j = 0; (int)j < kUIExtCount; j++) {
+ ext_widgets[j] &= ui->ui_ext[j];
+ }
}
- row = col = 0;
+ cursor_row = cursor_col = 0;
+ pending_cursor_update = true;
+
+ for (UIExtension i = 0; (int)i < kUIExtCount; i++) {
+ ui_ext[i] = ext_widgets[i];
+ if (i < kUIGlobalCount) {
+ ui_call_option_set(cstr_as_string((char *)ui_ext_names[i]),
+ BOOLEAN_OBJ(ext_widgets[i]));
+ }
+ }
+
+ ui_default_colors_set();
+
+ int save_p_lz = p_lz;
+ p_lz = false; // convince redrawing() to return true ...
screen_resize(width, height);
+ p_lz = save_p_lz;
+
+ ui_mode_info_set();
+ pending_mode_update = true;
+ ui_cursor_shape();
}
-void ui_resize(int new_width, int new_height)
+static void ui_refresh_event(void **argv)
{
- width = new_width;
- height = new_height;
-
- UI_CALL(update_fg, (ui->rgb ? normal_fg : cterm_normal_fg_color - 1));
- UI_CALL(update_bg, (ui->rgb ? normal_bg : cterm_normal_bg_color - 1));
- UI_CALL(update_sp, (ui->rgb ? normal_sp : -1));
-
- sr.top = 0;
- sr.bot = height - 1;
- sr.left = 0;
- sr.right = width - 1;
- UI_CALL(resize, width, height);
+ ui_refresh();
}
-void ui_busy_start(void)
+void ui_schedule_refresh(void)
{
- if (!(busy++)) {
- UI_CALL(busy_start);
- }
+ loop_schedule(&main_loop, event_create(ui_refresh_event, 0));
}
-void ui_busy_stop(void)
+void ui_resize(int width, int height)
{
- if (!(--busy)) {
- UI_CALL(busy_stop);
- }
+ ui_call_grid_resize(1, width, height);
}
-void ui_mouse_on(void)
+void ui_default_colors_set(void)
+{
+ ui_call_default_colors_set(normal_fg, normal_bg, normal_sp,
+ cterm_normal_fg_color, cterm_normal_bg_color);
+}
+
+void ui_busy_start(void)
{
- UI_CALL(mouse_on);
+ if (!(busy++)) {
+ ui_call_busy_start();
+ }
}
-void ui_mouse_off(void)
+void ui_busy_stop(void)
{
- UI_CALL(mouse_off);
+ if (!(--busy)) {
+ ui_call_busy_stop();
+ }
}
void ui_attach_impl(UI *ui)
@@ -214,6 +259,19 @@ void ui_attach_impl(UI *ui)
}
uis[ui_count++] = ui;
+ ui_refresh_options();
+
+ for (UIExtension i = kUIGlobalCount; (int)i < kUIExtCount; i++) {
+ ui_set_ext_option(ui, i, ui->ui_ext[i]);
+ }
+
+ bool sent = false;
+ if (ui->ui_ext[kUIHlState]) {
+ sent = highlight_use_hlstate();
+ }
+ if (!sent) {
+ ui_send_all_hls(ui);
+ }
ui_refresh();
}
@@ -239,283 +297,162 @@ void ui_detach_impl(UI *ui)
shift_index++;
}
- if (--ui_count) {
- ui_refresh();
+ if (--ui_count
+ // During teardown/exit the loop was already destroyed, cannot schedule.
+ // https://github.com/neovim/neovim/pull/5119#issuecomment-258667046
+ && !exiting) {
+ ui_schedule_refresh();
}
}
-void ui_clear(void)
-{
- UI_CALL(clear);
-}
-
-// Set scrolling region for window 'wp'.
-// The region starts 'off' lines from the start of the window.
-// Also set the vertical scroll region for a vertically split window. Always
-// the full width of the window, excluding the vertical separator.
-void ui_set_scroll_region(win_T *wp, int off)
-{
- sr.top = wp->w_winrow + off;
- sr.bot = wp->w_winrow + wp->w_height - 1;
-
- if (wp->w_width != Columns) {
- sr.left = wp->w_wincol;
- sr.right = wp->w_wincol + wp->w_width - 1;
- }
-
- UI_CALL(set_scroll_region, sr.top, sr.bot, sr.left, sr.right);
-}
-
-// Reset scrolling region to the whole screen.
-void ui_reset_scroll_region(void)
-{
- sr.top = 0;
- sr.bot = (int)Rows - 1;
- sr.left = 0;
- sr.right = (int)Columns - 1;
- UI_CALL(set_scroll_region, sr.top, sr.bot, sr.left, sr.right);
-}
-
-void ui_append_lines(int count)
-{
- UI_CALL(scroll, -count);
-}
-
-void ui_delete_lines(int count)
+void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
{
- UI_CALL(scroll, count);
-}
-
-void ui_eol_clear(void)
-{
- UI_CALL(eol_clear);
-}
-
-void ui_start_highlight(int attr_code)
-{
- current_attr_code = attr_code;
-
- if (!ui_count) {
+ if (ext < kUIGlobalCount) {
+ ui_refresh();
return;
}
-
- set_highlight_args(current_attr_code);
-}
-
-void ui_stop_highlight(void)
-{
- current_attr_code = HL_NORMAL;
-
- if (!ui_count) {
- return;
+ if (ui->option_set) {
+ ui->option_set(ui, cstr_as_string((char *)ui_ext_names[ext]),
+ BOOLEAN_OBJ(active));
}
-
- set_highlight_args(current_attr_code);
}
-void ui_visual_bell(void)
+void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol,
+ int clearattr, bool wrap)
{
- UI_CALL(visual_bell);
-}
+ size_t off = grid->line_offset[row] + (size_t)startcol;
-void ui_puts(uint8_t *str)
-{
- uint8_t *ptr = str;
- uint8_t c;
-
- while ((c = *ptr)) {
- if (c < 0x20) {
- parse_control_character(c);
- ptr++;
- } else {
- send_output(&ptr);
- }
+ UI_CALL(raw_line, grid->handle, row, startcol, endcol, clearcol, clearattr,
+ wrap, (const schar_T *)grid->chars + off,
+ (const sattr_T *)grid->attrs + off);
+
+ if (p_wd) { // 'writedelay': flush & delay each time.
+ int old_row = cursor_row, old_col = cursor_col;
+ handle_T old_grid = cursor_grid_handle;
+ // If 'writedelay' is active, set the cursor to indicate what was drawn.
+ ui_grid_cursor_goto(grid->handle, row, MIN(clearcol, (int)Columns-1));
+ ui_flush();
+ uint64_t wd = (uint64_t)labs(p_wd);
+ os_microdelay(wd * 1000u, true);
+ ui_grid_cursor_goto(old_grid, old_row, old_col);
}
}
-void ui_putc(uint8_t c)
+void ui_cursor_goto(int new_row, int new_col)
{
- uint8_t buf[2] = {c, 0};
- ui_puts(buf);
+ ui_grid_cursor_goto(DEFAULT_GRID_HANDLE, new_row, new_col);
}
-void ui_cursor_goto(int new_row, int new_col)
+void ui_grid_cursor_goto(handle_T grid_handle, int new_row, int new_col)
{
- if (new_row == row && new_col == col) {
+ if (new_row == cursor_row
+ && new_col == cursor_col
+ && grid_handle == cursor_grid_handle) {
return;
}
- row = new_row;
- col = new_col;
+
+ cursor_row = new_row;
+ cursor_col = new_col;
+ cursor_grid_handle = grid_handle;
pending_cursor_update = true;
}
-void ui_update_menu(void)
+void ui_mode_info_set(void)
{
- UI_CALL(update_menu);
+ pending_mode_info_update = true;
}
int ui_current_row(void)
{
- return row;
+ return cursor_row;
}
int ui_current_col(void)
{
- return col;
+ return cursor_col;
}
void ui_flush(void)
{
- UI_CALL(flush);
-}
-
-static void send_output(uint8_t **ptr)
-{
- uint8_t *p = *ptr;
-
- while (*p >= 0x20) {
- size_t clen = (size_t)mb_ptr2len(p);
- UI_CALL(put, p, (size_t)clen);
- col++;
- if (mb_ptr2cells(p) > 1) {
- // double cell character, blank the next cell
- UI_CALL(put, NULL, 0);
- col++;
- }
- if (col >= width) {
- ui_linefeed();
- }
- p += clen;
- }
-
- *ptr = p;
-}
-
-static void parse_control_character(uint8_t c)
-{
- if (c == '\n') {
- ui_linefeed();
- } else if (c == '\r') {
- ui_carriage_return();
- } else if (c == '\b') {
- ui_cursor_left();
- } else if (c == Ctrl_L) {
- ui_cursor_right();
- } else if (c == Ctrl_G) {
- UI_CALL(bell);
- }
-}
-
-static void set_highlight_args(int attr_code)
-{
- HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1, -1 };
- HlAttrs cterm_attrs = rgb_attrs;
-
- if (attr_code == HL_NORMAL) {
- goto end;
- }
-
- int rgb_mask = 0;
- int cterm_mask = 0;
- attrentry_T *aep = syn_cterm_attr2entry(attr_code);
-
- if (!aep) {
- goto end;
- }
-
- rgb_mask = aep->rgb_ae_attr;
- cterm_mask = aep->cterm_ae_attr;
-
- rgb_attrs.bold = rgb_mask & HL_BOLD;
- rgb_attrs.underline = rgb_mask & HL_UNDERLINE;
- rgb_attrs.undercurl = rgb_mask & HL_UNDERCURL;
- rgb_attrs.italic = rgb_mask & HL_ITALIC;
- rgb_attrs.reverse = rgb_mask & (HL_INVERSE | HL_STANDOUT);
- cterm_attrs.bold = cterm_mask & HL_BOLD;
- cterm_attrs.underline = cterm_mask & HL_UNDERLINE;
- cterm_attrs.undercurl = cterm_mask & HL_UNDERCURL;
- cterm_attrs.italic = cterm_mask & HL_ITALIC;
- cterm_attrs.reverse = cterm_mask & (HL_INVERSE | HL_STANDOUT);
-
- if (aep->rgb_fg_color != normal_fg) {
- rgb_attrs.foreground = aep->rgb_fg_color;
- }
-
- if (aep->rgb_bg_color != normal_bg) {
- rgb_attrs.background = aep->rgb_bg_color;
+ cmdline_ui_flush();
+ win_ui_flush();
+ if (pending_cursor_update) {
+ ui_call_grid_cursor_goto(cursor_grid_handle, cursor_row, cursor_col);
+ pending_cursor_update = false;
}
-
- if (aep->rgb_sp_color != normal_sp) {
- rgb_attrs.special = aep->rgb_sp_color;
+ if (pending_mode_info_update) {
+ Array style = mode_style_array();
+ bool enabled = (*p_guicursor != NUL);
+ ui_call_mode_info_set(enabled, style);
+ api_free_array(style);
+ pending_mode_info_update = false;
}
-
- if (cterm_normal_fg_color != aep->cterm_fg_color) {
- cterm_attrs.foreground = aep->cterm_fg_color - 1;
+ if (pending_mode_update) {
+ char *full_name = shape_table[ui_mode_idx].full_name;
+ ui_call_mode_change(cstr_as_string(full_name), ui_mode_idx);
+ pending_mode_update = false;
}
-
- if (cterm_normal_bg_color != aep->cterm_bg_color) {
- cterm_attrs.background = aep->cterm_bg_color - 1;
- }
-
-end:
- UI_CALL(highlight_set, (ui->rgb ? rgb_attrs : cterm_attrs));
+ ui_call_flush();
}
-static void ui_linefeed(void)
+
+/// Check if current mode has changed.
+/// May update the shape of the cursor.
+void ui_cursor_shape(void)
{
- int new_col = 0;
- int new_row = row;
- if (new_row < sr.bot) {
- new_row++;
- } else {
- UI_CALL(scroll, 1);
+ if (!full_screen) {
+ return;
}
- ui_cursor_goto(new_row, new_col);
-}
+ int new_mode_idx = cursor_get_mode_idx();
-static void ui_carriage_return(void)
-{
- int new_col = 0;
- ui_cursor_goto(row, new_col);
+ if (new_mode_idx != ui_mode_idx) {
+ ui_mode_idx = new_mode_idx;
+ pending_mode_update = true;
+ }
+ conceal_check_cursor_line();
}
-static void ui_cursor_left(void)
+/// Returns true if `widget` is externalized.
+bool ui_is_external(UIExtension widget)
{
- int new_col = col - 1;
- assert(new_col >= 0);
- ui_cursor_goto(row, new_col);
+ return ui_ext[widget];
}
-static void ui_cursor_right(void)
+Array ui_array(void)
{
- int new_col = col + 1;
- assert(new_col < width);
- ui_cursor_goto(row, new_col);
+ Array all_uis = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < ui_count; i++) {
+ UI *ui = uis[i];
+ Dictionary info = ARRAY_DICT_INIT;
+ PUT(info, "width", INTEGER_OBJ(ui->width));
+ PUT(info, "height", INTEGER_OBJ(ui->height));
+ PUT(info, "rgb", BOOLEAN_OBJ(ui->rgb));
+ for (UIExtension j = 0; j < kUIExtCount; j++) {
+ PUT(info, ui_ext_names[j], BOOLEAN_OBJ(ui->ui_ext[j]));
+ }
+ if (ui->inspect) {
+ ui->inspect(ui, &info);
+ }
+ ADD(all_uis, DICTIONARY_OBJ(info));
+ }
+ return all_uis;
}
-static void flush_cursor_update(void)
+void ui_grid_resize(handle_T grid_handle, int width, int height, Error *error)
{
- if (pending_cursor_update) {
- pending_cursor_update = false;
- UI_CALL(cursor_goto, row, col);
+ if (grid_handle == DEFAULT_GRID_HANDLE) {
+ screen_resize(width, height);
+ return;
}
-}
-// Notify that the current mode has changed. Can be used to change cursor
-// shape, for example.
-static void ui_mode_change(void)
-{
- int mode;
- if (!full_screen) {
+ win_T *wp = get_win_by_grid_handle(grid_handle);
+ if (wp == NULL) {
+ api_set_error(error, kErrorTypeValidation,
+ "No window with the given handle");
return;
}
- /* Get a simple UI mode out of State. */
- if ((State & REPLACE) == REPLACE)
- mode = REPLACE;
- else if (State & INSERT)
- mode = INSERT;
- else
- mode = NORMAL;
- UI_CALL(mode_change, mode);
- conceal_check_cursur_line();
+
+ wp->w_grid.requested_rows = (int)height;
+ wp->w_grid.requested_cols = (int)width;
+ redraw_win_later(wp, SOME_VALID);
}
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index 5934d2fee9..16237214cb 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -5,44 +5,58 @@
#include <stdbool.h>
#include <stdint.h>
-typedef struct {
- bool bold, underline, undercurl, italic, reverse;
- int foreground, background, special;
-} HlAttrs;
+#include "nvim/globals.h"
+#include "nvim/api/private/defs.h"
+#include "nvim/highlight_defs.h"
+
+typedef enum {
+ kUICmdline = 0,
+ kUIPopupmenu,
+ kUITabline,
+ kUIWildmenu,
+#define kUIGlobalCount (kUIWildmenu+1)
+ kUILinegrid,
+ kUIMultigrid,
+ kUIHlState,
+ kUIExtCount,
+} UIExtension;
+
+EXTERN const char *ui_ext_names[] INIT(= {
+ "ext_cmdline",
+ "ext_popupmenu",
+ "ext_tabline",
+ "ext_wildmenu",
+ "ext_linegrid",
+ "ext_multigrid",
+ "ext_hlstate",
+});
+
typedef struct ui_t UI;
struct ui_t {
bool rgb;
+ bool ui_ext[kUIExtCount]; ///< Externalized widgets
int width, height;
void *data;
- void (*resize)(UI *ui, int rows, int columns);
- void (*clear)(UI *ui);
- void (*eol_clear)(UI *ui);
- void (*cursor_goto)(UI *ui, int row, int col);
- void (*update_menu)(UI *ui);
- void (*busy_start)(UI *ui);
- void (*busy_stop)(UI *ui);
- void (*mouse_on)(UI *ui);
- void (*mouse_off)(UI *ui);
- void (*mode_change)(UI *ui, int mode);
- void (*set_scroll_region)(UI *ui, int top, int bot, int left, int right);
- void (*scroll)(UI *ui, int count);
- void (*highlight_set)(UI *ui, HlAttrs attrs);
- void (*put)(UI *ui, uint8_t *str, size_t len);
- void (*bell)(UI *ui);
- void (*visual_bell)(UI *ui);
- void (*flush)(UI *ui);
- void (*update_fg)(UI *ui, int fg);
- void (*update_bg)(UI *ui, int bg);
- void (*update_sp)(UI *ui, int sp);
- void (*suspend)(UI *ui);
- void (*set_title)(UI *ui, char *title);
- void (*set_icon)(UI *ui, char *icon);
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "ui_events.generated.h"
+#endif
+
+ // For perfomance and simplicity, we use the dense screen representation
+ // in the bridge and the TUI. The remote_ui module will translate this
+ // in to the public grid_line format.
+ void (*raw_line)(UI *ui, Integer grid, Integer row, Integer startcol,
+ Integer endcol, Integer clearcol, Integer clearattr,
+ Boolean wrap, const schar_T *chunk, const sattr_T *attrs);
+ void (*event)(UI *ui, char *name, Array args, bool *args_consumed);
void (*stop)(UI *ui);
+ void (*inspect)(UI *ui, Dictionary *info);
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui.h.generated.h"
+# include "ui_events_call.h.generated.h"
#endif
#endif // NVIM_UI_H
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 6290fb3d87..bd5d37be73 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -1,16 +1,22 @@
-// FIXME(tarruda): This module is very repetitive. It might be a good idea to
-// automatically generate it with a lua script during build
+// 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
+
+// UI wrapper that sends requests to the UI thread.
+// Used by the built-in TUI and libnvim-based UIs.
+
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <limits.h>
+#include "nvim/log.h"
#include "nvim/main.h"
#include "nvim/vim.h"
#include "nvim/ui.h"
#include "nvim/memory.h"
#include "nvim/ui_bridge.h"
#include "nvim/ugrid.h"
+#include "nvim/api/private/helpers.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ui_bridge.c.generated.h"
@@ -18,13 +24,17 @@
#define UI(b) (((UIBridgeData *)b)->ui)
-// Call a function in the UI thread
-#define UI_CALL(ui, name, argc, ...) \
+// Schedule a function call on the UI bridge thread.
+#define UI_BRIDGE_CALL(ui, name, argc, ...) \
((UIBridgeData *)ui)->scheduler( \
- event_create(1, ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui))
+ event_create(ui_bridge_##name##_event, argc, __VA_ARGS__), UI(ui))
-#define INT2PTR(i) ((void *)(uintptr_t)i)
-#define PTR2INT(p) ((int)(uintptr_t)p)
+#define INT2PTR(i) ((void *)(intptr_t)i)
+#define PTR2INT(p) ((Integer)(intptr_t)p)
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "ui_events_bridge.generated.h"
+#endif
UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
{
@@ -32,31 +42,33 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
rv->ui = ui;
rv->bridge.rgb = ui->rgb;
rv->bridge.stop = ui_bridge_stop;
- rv->bridge.resize = ui_bridge_resize;
- rv->bridge.clear = ui_bridge_clear;
- rv->bridge.eol_clear = ui_bridge_eol_clear;
- rv->bridge.cursor_goto = ui_bridge_cursor_goto;
+ rv->bridge.grid_resize = ui_bridge_grid_resize;
+ rv->bridge.grid_clear = ui_bridge_grid_clear;
+ rv->bridge.grid_cursor_goto = ui_bridge_grid_cursor_goto;
+ rv->bridge.mode_info_set = ui_bridge_mode_info_set;
rv->bridge.update_menu = ui_bridge_update_menu;
rv->bridge.busy_start = ui_bridge_busy_start;
rv->bridge.busy_stop = ui_bridge_busy_stop;
rv->bridge.mouse_on = ui_bridge_mouse_on;
rv->bridge.mouse_off = ui_bridge_mouse_off;
rv->bridge.mode_change = ui_bridge_mode_change;
- rv->bridge.set_scroll_region = ui_bridge_set_scroll_region;
- rv->bridge.scroll = ui_bridge_scroll;
- rv->bridge.highlight_set = ui_bridge_highlight_set;
- rv->bridge.put = ui_bridge_put;
+ rv->bridge.grid_scroll = ui_bridge_grid_scroll;
+ rv->bridge.hl_attr_define = ui_bridge_hl_attr_define;
rv->bridge.bell = ui_bridge_bell;
rv->bridge.visual_bell = ui_bridge_visual_bell;
- rv->bridge.update_fg = ui_bridge_update_fg;
- rv->bridge.update_bg = ui_bridge_update_bg;
- rv->bridge.update_sp = ui_bridge_update_sp;
+ rv->bridge.default_colors_set = ui_bridge_default_colors_set;
rv->bridge.flush = ui_bridge_flush;
rv->bridge.suspend = ui_bridge_suspend;
rv->bridge.set_title = ui_bridge_set_title;
rv->bridge.set_icon = ui_bridge_set_icon;
+ rv->bridge.option_set = ui_bridge_option_set;
+ rv->bridge.raw_line = ui_bridge_raw_line;
rv->scheduler = scheduler;
+ for (UIExtension i = 0; (int)i < kUIExtCount; i++) {
+ rv->bridge.ui_ext[i] = ui->ui_ext[i];
+ }
+
rv->ui_main = ui_main;
uv_mutex_init(&rv->mutex);
uv_cond_init(&rv->cond);
@@ -67,6 +79,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
abort();
}
+ // Suspend the main thread until CONTINUE is called by the UI thread.
while (!rv->ready) {
uv_cond_wait(&rv->cond, &rv->mutex);
}
@@ -91,22 +104,26 @@ static void ui_thread_run(void *data)
static void ui_bridge_stop(UI *b)
{
+ // Detach bridge first, so that "stop" is the last event the TUI loop
+ // receives from the main thread. #8041
+ ui_detach_impl(b);
UIBridgeData *bridge = (UIBridgeData *)b;
bool stopped = bridge->stopped = false;
- UI_CALL(b, stop, 1, b);
+ UI_BRIDGE_CALL(b, stop, 1, b);
for (;;) {
uv_mutex_lock(&bridge->mutex);
stopped = bridge->stopped;
uv_mutex_unlock(&bridge->mutex);
- if (stopped) {
+ if (stopped) { // -V547
break;
}
- loop_poll_events(&main_loop, 10);
+ // TODO(justinmk): Remove this. Use a cond-wait above. #9274
+ loop_poll_events(&main_loop, 10); // Process one event.
}
uv_thread_join(&bridge->ui_thread);
uv_mutex_destroy(&bridge->mutex);
uv_cond_destroy(&bridge->cond);
- ui_detach_impl(b);
+ xfree(bridge->ui); // Threads joined, now safe to free UI container. #7922
xfree(b);
}
static void ui_bridge_stop_event(void **argv)
@@ -115,225 +132,52 @@ static void ui_bridge_stop_event(void **argv)
ui->stop(ui);
}
-static void ui_bridge_resize(UI *b, int width, int height)
-{
- UI_CALL(b, resize, 3, b, INT2PTR(width), INT2PTR(height));
-}
-static void ui_bridge_resize_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->resize(ui, PTR2INT(argv[1]), PTR2INT(argv[2]));
-}
-
-static void ui_bridge_clear(UI *b)
-{
- UI_CALL(b, clear, 1, b);
-}
-static void ui_bridge_clear_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->clear(ui);
-}
-
-static void ui_bridge_eol_clear(UI *b)
-{
- UI_CALL(b, eol_clear, 1, b);
-}
-static void ui_bridge_eol_clear_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->eol_clear(ui);
-}
-
-static void ui_bridge_cursor_goto(UI *b, int row, int col)
-{
- UI_CALL(b, cursor_goto, 3, b, INT2PTR(row), INT2PTR(col));
-}
-static void ui_bridge_cursor_goto_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->cursor_goto(ui, PTR2INT(argv[1]), PTR2INT(argv[2]));
-}
-
-static void ui_bridge_update_menu(UI *b)
-{
- UI_CALL(b, update_menu, 1, b);
-}
-static void ui_bridge_update_menu_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->update_menu(ui);
-}
-
-static void ui_bridge_busy_start(UI *b)
-{
- UI_CALL(b, busy_start, 1, b);
-}
-static void ui_bridge_busy_start_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->busy_start(ui);
-}
-
-static void ui_bridge_busy_stop(UI *b)
-{
- UI_CALL(b, busy_stop, 1, b);
-}
-static void ui_bridge_busy_stop_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->busy_stop(ui);
-}
-
-static void ui_bridge_mouse_on(UI *b)
-{
- UI_CALL(b, mouse_on, 1, b);
-}
-static void ui_bridge_mouse_on_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->mouse_on(ui);
-}
-
-static void ui_bridge_mouse_off(UI *b)
-{
- UI_CALL(b, mouse_off, 1, b);
-}
-static void ui_bridge_mouse_off_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->mouse_off(ui);
-}
-
-static void ui_bridge_mode_change(UI *b, int mode)
-{
- UI_CALL(b, mode_change, 2, b, INT2PTR(mode));
-}
-static void ui_bridge_mode_change_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->mode_change(ui, PTR2INT(argv[1]));
-}
-
-static void ui_bridge_set_scroll_region(UI *b, int top, int bot, int left,
- int right)
-{
- UI_CALL(b, set_scroll_region, 5, b, INT2PTR(top), INT2PTR(bot),
- INT2PTR(left), INT2PTR(right));
-}
-static void ui_bridge_set_scroll_region_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->set_scroll_region(ui, PTR2INT(argv[1]), PTR2INT(argv[2]),
- PTR2INT(argv[3]), PTR2INT(argv[4]));
-}
-
-static void ui_bridge_scroll(UI *b, int count)
-{
- UI_CALL(b, scroll, 2, b, INT2PTR(count));
-}
-static void ui_bridge_scroll_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->scroll(ui, PTR2INT(argv[1]));
-}
-
-static void ui_bridge_highlight_set(UI *b, HlAttrs attrs)
+static void ui_bridge_hl_attr_define(UI *ui, Integer id, HlAttrs attrs,
+ HlAttrs cterm_attrs, Array info)
{
HlAttrs *a = xmalloc(sizeof(HlAttrs));
*a = attrs;
- UI_CALL(b, highlight_set, 2, b, a);
-}
-static void ui_bridge_highlight_set_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->highlight_set(ui, *((HlAttrs *)argv[1]));
- xfree(argv[1]);
-}
-
-static void ui_bridge_put(UI *b, uint8_t *text, size_t size)
-{
- uint8_t *t = NULL;
- if (text) {
- t = xmalloc(sizeof(((UCell *)0)->data));
- memcpy(t, text, size);
- }
- UI_CALL(b, put, 3, b, t, INT2PTR(size));
-}
-static void ui_bridge_put_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->put(ui, (uint8_t *)argv[1], (size_t)(uintptr_t)argv[2]);
- xfree(argv[1]);
-}
-
-static void ui_bridge_bell(UI *b)
-{
- UI_CALL(b, bell, 1, b);
+ UI_BRIDGE_CALL(ui, hl_attr_define, 3, ui, INT2PTR(id), a);
}
-static void ui_bridge_bell_event(void **argv)
+static void ui_bridge_hl_attr_define_event(void **argv)
{
UI *ui = UI(argv[0]);
- ui->bell(ui);
+ Array info = ARRAY_DICT_INIT;
+ ui->hl_attr_define(ui, PTR2INT(argv[1]), *((HlAttrs *)argv[2]),
+ *((HlAttrs *)argv[2]), info);
+ xfree(argv[2]);
}
-static void ui_bridge_visual_bell(UI *b)
-{
- UI_CALL(b, visual_bell, 1, b);
-}
-static void ui_bridge_visual_bell_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->visual_bell(ui);
-}
-
-static void ui_bridge_update_fg(UI *b, int fg)
-{
- UI_CALL(b, update_fg, 2, b, INT2PTR(fg));
-}
-static void ui_bridge_update_fg_event(void **argv)
+static void ui_bridge_raw_line_event(void **argv)
{
UI *ui = UI(argv[0]);
- ui->update_fg(ui, PTR2INT(argv[1]));
+ ui->raw_line(ui, PTR2INT(argv[1]), PTR2INT(argv[2]), PTR2INT(argv[3]),
+ PTR2INT(argv[4]), PTR2INT(argv[5]), PTR2INT(argv[6]),
+ PTR2INT(argv[7]), argv[8], argv[9]);
+ xfree(argv[8]);
+ xfree(argv[9]);
}
-
-static void ui_bridge_update_bg(UI *b, int bg)
-{
- UI_CALL(b, update_bg, 2, b, INT2PTR(bg));
-}
-static void ui_bridge_update_bg_event(void **argv)
+static void ui_bridge_raw_line(UI *ui, Integer grid, Integer row,
+ Integer startcol, Integer endcol,
+ Integer clearcol, Integer clearattr,
+ Boolean wrap, const schar_T *chunk,
+ const sattr_T *attrs)
{
- UI *ui = UI(argv[0]);
- ui->update_bg(ui, PTR2INT(argv[1]));
-}
-
-static void ui_bridge_update_sp(UI *b, int sp)
-{
- UI_CALL(b, update_sp, 2, b, INT2PTR(sp));
-}
-static void ui_bridge_update_sp_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->update_sp(ui, PTR2INT(argv[1]));
-}
-
-static void ui_bridge_flush(UI *b)
-{
- UI_CALL(b, flush, 1, b);
-}
-static void ui_bridge_flush_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->flush(ui);
+ size_t ncol = (size_t)(endcol-startcol);
+ schar_T *c = xmemdup(chunk, ncol * sizeof(schar_T));
+ sattr_T *hl = xmemdup(attrs, ncol * sizeof(sattr_T));
+ UI_BRIDGE_CALL(ui, raw_line, 10, ui, INT2PTR(grid), INT2PTR(row),
+ INT2PTR(startcol), INT2PTR(endcol), INT2PTR(clearcol),
+ INT2PTR(clearattr), INT2PTR(wrap), c, hl);
}
static void ui_bridge_suspend(UI *b)
{
UIBridgeData *data = (UIBridgeData *)b;
uv_mutex_lock(&data->mutex);
- UI_CALL(b, suspend, 1, b);
+ UI_BRIDGE_CALL(b, suspend, 1, b);
data->ready = false;
- // suspend the main thread until CONTINUE is called by the UI thread
+ // Suspend the main thread until CONTINUE is called by the UI thread.
while (!data->ready) {
uv_cond_wait(&data->cond, &data->mutex);
}
@@ -345,24 +189,27 @@ static void ui_bridge_suspend_event(void **argv)
ui->suspend(ui);
}
-static void ui_bridge_set_title(UI *b, char *title)
+static void ui_bridge_option_set(UI *ui, String name, Object value)
{
- UI_CALL(b, set_title, 2, b, title ? xstrdup(title) : NULL);
-}
-static void ui_bridge_set_title_event(void **argv)
-{
- UI *ui = UI(argv[0]);
- ui->set_title(ui, argv[1]);
- xfree(argv[1]);
-}
-
-static void ui_bridge_set_icon(UI *b, char *icon)
-{
- UI_CALL(b, set_icon, 2, b, icon ? xstrdup(icon) : NULL);
+ String copy_name = copy_string(name);
+ Object *copy_value = xmalloc(sizeof(Object));
+ *copy_value = copy_object(value);
+ UI_BRIDGE_CALL(ui, option_set, 4, ui, copy_name.data,
+ INT2PTR(copy_name.size), copy_value);
+ // TODO(bfredl): when/if TUI/bridge teardown is refactored to use events, the
+ // commit that introduced this special case can be reverted.
+ // For now this is needed for nvim_list_uis().
+ if (strequal(name.data, "termguicolors")) {
+ ui->rgb = value.data.boolean;
+ }
}
-static void ui_bridge_set_icon_event(void **argv)
+static void ui_bridge_option_set_event(void **argv)
{
UI *ui = UI(argv[0]);
- ui->set_icon(ui, argv[1]);
- xfree(argv[1]);
+ String name = (String){ .data = argv[1], .size = (size_t)argv[2] };
+ Object value = *(Object *)argv[3];
+ ui->option_set(ui, name, value);
+ api_free_string(name);
+ api_free_object(value);
+ xfree(argv[3]);
}
diff --git a/src/nvim/ui_bridge.h b/src/nvim/ui_bridge.h
index 561ddb6b24..dba461550f 100644
--- a/src/nvim/ui_bridge.h
+++ b/src/nvim/ui_bridge.h
@@ -1,4 +1,5 @@
-// Bridge used for communication between a builtin UI thread and nvim core
+// Bridge for communication between a UI thread and nvim core.
+// Used by the built-in TUI and libnvim-based UIs.
#ifndef NVIM_UI_BRIDGE_H
#define NVIM_UI_BRIDGE_H
@@ -11,7 +12,7 @@ typedef struct ui_bridge_data UIBridgeData;
typedef void(*ui_main_fn)(UIBridgeData *bridge, UI *ui);
struct ui_bridge_data {
UI bridge; // actual UI passed to ui_attach
- UI *ui; // UI pointer that will have it's callback called in
+ UI *ui; // UI pointer that will have its callback called in
// another thread
event_scheduler scheduler;
uv_thread_t ui_thread;
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index fc5d6acaa4..df0507ed41 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.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
+
/*
* undo.c: multi level undo facility
*
@@ -76,17 +79,20 @@
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/undo.h"
+#include "nvim/macros.h"
#include "nvim/cursor.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/buffer_updates.h"
#include "nvim/mark.h"
#include "nvim/memline.h"
#include "nvim/message.h"
@@ -99,6 +105,7 @@
#include "nvim/quickfix.h"
#include "nvim/screen.h"
#include "nvim/sha256.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/types.h"
#include "nvim/os/os.h"
@@ -115,7 +122,7 @@ static long u_newcount, u_oldcount;
* When 'u' flag included in 'cpoptions', we behave like vi. Need to remember
* the action that "u" should do.
*/
-static int undo_undoes = FALSE;
+static bool undo_undoes = false;
static int lastmark = 0;
@@ -304,23 +311,19 @@ bool undo_allowed(void)
return true;
}
-/*
- * Get the undolevle value for the current buffer.
- */
+/// Get the 'undolevels' value for the current buffer.
static long get_undolevel(void)
{
- if (curbuf->terminal) {
- return -1;
- }
- if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL)
+ if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL) {
return p_ul;
+ }
return curbuf->b_p_ul;
}
static inline void zero_fmark_additional_data(fmark_T *fmarks)
{
for (size_t i = 0; i < NMARKS; i++) {
- dict_unref(fmarks[i].additional_data);
+ tv_dict_unref(fmarks[i].additional_data);
fmarks[i].additional_data = NULL;
}
}
@@ -588,7 +591,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload)
uep->ue_next = curbuf->b_u_newhead->uh_entry;
curbuf->b_u_newhead->uh_entry = uep;
curbuf->b_u_synced = false;
- undo_undoes = FALSE;
+ undo_undoes = false;
#ifdef U_DEBUG
u_check(FALSE);
@@ -690,7 +693,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
int ret;
char *failed_dir;
if ((ret = os_mkdir_recurse(dir_name, 0755, &failed_dir)) != 0) {
- EMSG3(_("E926: Unable to create directory \"%s\" for undo file: %s"),
+ EMSG3(_("E5003: Unable to create directory \"%s\" for undo file: %s"),
failed_dir, os_strerror(ret));
xfree(failed_dir);
} else {
@@ -700,7 +703,7 @@ char *u_get_undo_file_name(const char *const buf_ffname, const bool reading)
if (has_directory) {
if (munged_name == NULL) {
munged_name = xstrdup(ffname);
- for (char *p = munged_name; *p != NUL; mb_ptr_adv(p)) {
+ for (char *p = munged_name; *p != NUL; MB_PTR_ADV(p)) {
if (vim_ispathsep(*p)) {
*p = '%';
}
@@ -888,7 +891,7 @@ static u_header_T *unserialize_uhp(bufinfo_T *bi,
for (;; ) {
int len = undo_read_byte(bi);
- if (len == 0) {
+ if (len == 0 || len == EOF) {
break;
}
int what = undo_read_byte(bi);
@@ -968,12 +971,12 @@ static u_entry_T *unserialize_uep(bufinfo_T * bi, bool *error,
uep->ue_lcount = undo_read_4c(bi);
uep->ue_size = undo_read_4c(bi);
- char_u **array;
+ char_u **array = NULL;
if (uep->ue_size > 0) {
- array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size);
- memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size);
- } else {
- array = NULL;
+ if ((size_t)uep->ue_size < SIZE_MAX / sizeof(char_u *)) { // -V547
+ array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size);
+ memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size);
+ }
}
uep->ue_array = array;
@@ -1083,7 +1086,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
*/
perm = 0600;
if (buf->b_ffname != NULL) {
- perm = os_getperm(buf->b_ffname);
+ perm = os_getperm((const char *)buf->b_ffname);
if (perm < 0) {
perm = 0600;
}
@@ -1142,7 +1145,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
EMSG2(_(e_not_open), file_name);
goto theend;
}
- (void)os_setperm((char_u *)file_name, perm);
+ (void)os_setperm(file_name, perm);
if (p_verbose > 0) {
verbose_enter();
smsg(_("Writing undo file: %s"), file_name);
@@ -1167,7 +1170,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
&& os_fileinfo(file_name, &file_info_new)
&& file_info_old.stat.st_gid != file_info_new.stat.st_gid
&& os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) {
- os_setperm((char_u *)file_name, (perm & 0707) | ((perm & 07) << 3));
+ os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
}
# ifdef HAVE_SELINUX
if (buf->b_ffname != NULL)
@@ -1402,7 +1405,9 @@ void u_read_undo(char *name, char_u *hash, char_u *orig_name)
// sequence numbers of the headers.
// When there are no headers uhp_table is NULL.
if (num_head > 0) {
- uhp_table = xmalloc((size_t)num_head * sizeof(u_header_T *));
+ if ((size_t)num_head < SIZE_MAX / sizeof(*uhp_table)) { // -V547
+ uhp_table = xmalloc((size_t)num_head * sizeof(*uhp_table));
+ }
}
long num_read_uhps = 0;
@@ -1630,7 +1635,13 @@ static time_t undo_read_time(bufinfo_T *bi)
static bool undo_read(bufinfo_T *bi, uint8_t *buffer, size_t size)
FUNC_ATTR_NONNULL_ARG(1)
{
- return fread(buffer, size, 1, bi->bi_fp) == 1;
+ const bool retval = fread(buffer, size, 1, bi->bi_fp) == 1;
+ if (!retval) {
+ // Error may be checked for only later. Fill with zeros,
+ // so that the reader won't use garbage.
+ memset(buffer, 0, size);
+ }
+ return retval;
}
/// Reads a string of length "len" from "bi->bi_fd" and appends a zero to it.
@@ -1664,11 +1675,12 @@ void u_undo(int count)
count = 1;
}
- if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
- undo_undoes = TRUE;
- else
+ if (vim_strchr(p_cpo, CPO_UNDO) == NULL) {
+ undo_undoes = true;
+ } else {
undo_undoes = !undo_undoes;
- u_doit(count);
+ }
+ u_doit(count, false, true);
}
/*
@@ -1677,15 +1689,64 @@ void u_undo(int count)
*/
void u_redo(int count)
{
- if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
- undo_undoes = FALSE;
- u_doit(count);
+ if (vim_strchr(p_cpo, CPO_UNDO) == NULL) {
+ undo_undoes = false;
+ }
+
+ u_doit(count, false, true);
}
-/*
- * Undo or redo, depending on 'undo_undoes', 'count' times.
- */
-static void u_doit(int startcount)
+/// Undo and remove the branch from the undo tree.
+/// Also moves the cursor (as a "normal" undo would).
+bool u_undo_and_forget(int count)
+{
+ if (curbuf->b_u_synced == false) {
+ u_sync(true);
+ count = 1;
+ }
+ undo_undoes = true;
+ u_doit(count, true,
+ // Don't send nvim_buf_lines_event for u_undo_and_forget().
+ false);
+
+ if (curbuf->b_u_curhead == NULL) {
+ // nothing was undone.
+ return false;
+ }
+
+ // Delete the current redo header
+ // set the redo header to the next alternative branch (if any)
+ // otherwise we will be in the leaf state
+ u_header_T *to_forget = curbuf->b_u_curhead;
+ curbuf->b_u_newhead = to_forget->uh_next.ptr;
+ curbuf->b_u_curhead = to_forget->uh_alt_next.ptr;
+ if (curbuf->b_u_curhead) {
+ to_forget->uh_alt_next.ptr = NULL;
+ curbuf->b_u_curhead->uh_alt_prev.ptr = to_forget->uh_alt_prev.ptr;
+ curbuf->b_u_seq_cur = curbuf->b_u_curhead->uh_next.ptr ?
+ curbuf->b_u_curhead->uh_next.ptr->uh_seq : 0;
+ } else if (curbuf->b_u_newhead) {
+ curbuf->b_u_seq_cur = curbuf->b_u_newhead->uh_seq;
+ }
+ if (to_forget->uh_alt_prev.ptr) {
+ to_forget->uh_alt_prev.ptr->uh_alt_next.ptr = curbuf->b_u_curhead;
+ }
+ if (curbuf->b_u_newhead) {
+ curbuf->b_u_newhead->uh_prev.ptr = curbuf->b_u_curhead;
+ }
+ if (curbuf->b_u_seq_last == to_forget->uh_seq) {
+ curbuf->b_u_seq_last--;
+ }
+ u_freebranch(curbuf, to_forget, NULL);
+ return true;
+}
+
+/// Undo or redo, depending on `undo_undoes`, `count` times.
+///
+/// @param startcount How often to undo or redo
+/// @param quiet If `true`, don't show messages
+/// @param do_buf_event If `true`, send the changedtick with the buffer updates
+static void u_doit(int startcount, bool quiet, bool do_buf_event)
{
int count = startcount;
@@ -1721,7 +1782,7 @@ static void u_doit(int startcount)
break;
}
- u_undoredo(TRUE);
+ u_undoredo(true, do_buf_event);
} else {
if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0) {
beep_flush(); /* nothing to redo */
@@ -1732,7 +1793,7 @@ static void u_doit(int startcount)
break;
}
- u_undoredo(FALSE);
+ u_undoredo(false, do_buf_event);
/* Advance for next redo. Set "newhead" when at the end of the
* redoable changes. */
@@ -1741,34 +1802,32 @@ static void u_doit(int startcount)
curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev.ptr;
}
}
- u_undo_end(undo_undoes, FALSE);
+ u_undo_end(undo_undoes, false, quiet);
}
-/*
- * Undo or redo over the timeline.
- * When "step" is negative go back in time, otherwise goes forward in time.
- * When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as
- * seconds.
- * When "file" is TRUE use "step" as a number of file writes.
- * When "absolute" is TRUE use "step" as the sequence number to jump to.
- * "sec" must be FALSE then.
- */
-void undo_time(long step, int sec, int file, int absolute)
+// Undo or redo over the timeline.
+// When "step" is negative go back in time, otherwise goes forward in time.
+// When "sec" is false make "step" steps, when "sec" is true use "step" as
+// seconds.
+// When "file" is true use "step" as a number of file writes.
+// When "absolute" is true use "step" as the sequence number to jump to.
+// "sec" must be false then.
+void undo_time(long step, bool sec, bool file, bool absolute)
{
long target;
long closest;
long closest_start;
long closest_seq = 0;
long val;
- u_header_T *uhp;
+ u_header_T *uhp = NULL;
u_header_T *last;
int mark;
int nomark;
int round;
- int dosec = sec;
- int dofile = file;
- int above = FALSE;
- int did_undo = TRUE;
+ bool dosec = sec;
+ bool dofile = file;
+ bool above = false;
+ bool did_undo = true;
/* First make sure the current undoable change is synced. */
if (curbuf->b_u_synced == false)
@@ -1782,20 +1841,12 @@ void undo_time(long step, int sec, int file, int absolute)
/* "target" is the node below which we want to be.
* Init "closest" to a value we can't reach. */
if (absolute) {
- if (step == 0) {
- // target 0 does not exist, got to 1 and above it.
- target = 1;
- above = true;
- } else {
- target = step;
- }
+ target = step;
closest = -1;
} else {
- /* When doing computations with time_t subtract starttime, because
- * time_t converted to a long may result in a wrong number. */
- if (dosec)
- target = (long)(curbuf->b_u_time_cur - starttime) + step;
- else if (dofile) {
+ if (dosec) {
+ target = (long)(curbuf->b_u_time_cur) + step;
+ } else if (dofile) {
if (step < 0) {
/* Going back to a previous write. If there were changes after
* the last write, count that as moving one file-write, so
@@ -1815,7 +1866,7 @@ void undo_time(long step, int sec, int file, int absolute)
if (target <= 0)
/* Go to before first write: before the oldest change. Use
* the sequence number for that. */
- dofile = FALSE;
+ dofile = false;
} else {
/* Moving forward to a newer write. */
target = curbuf->b_u_save_nr_cur + step;
@@ -1823,7 +1874,7 @@ void undo_time(long step, int sec, int file, int absolute)
/* Go to after last write: after the latest change. Use
* the sequence number for that. */
target = curbuf->b_u_seq_last + 1;
- dofile = FALSE;
+ dofile = false;
}
}
} else
@@ -1833,19 +1884,27 @@ void undo_time(long step, int sec, int file, int absolute)
target = 0;
closest = -1;
} else {
- if (dosec)
- closest = (long)(time(NULL) - starttime + 1);
- else if (dofile)
+ if (dosec) {
+ closest = (long)(os_time() + 1);
+ } else if (dofile) {
closest = curbuf->b_u_save_nr_last + 2;
- else
+ } else {
closest = curbuf->b_u_seq_last + 2;
- if (target >= closest)
+ }
+ if (target >= closest) {
target = closest - 1;
+ }
}
}
closest_start = closest;
closest_seq = curbuf->b_u_seq_cur;
+ // When "target" is 0; Back to origin.
+ if (target == 0) {
+ mark = lastmark; // avoid that GCC complains
+ goto target_zero;
+ }
+
/*
* May do this twice:
* 1. Search for "target", update "closest" to the best match found.
@@ -1869,12 +1928,13 @@ void undo_time(long step, int sec, int file, int absolute)
while (uhp != NULL) {
uhp->uh_walk = mark;
- if (dosec)
- val = (long)(uhp->uh_time - starttime);
- else if (dofile)
+ if (dosec) {
+ val = (long)(uhp->uh_time);
+ } else if (dofile) {
val = uhp->uh_save_nr;
- else
+ } else {
val = uhp->uh_seq;
+ }
if (round == 1 && !(dofile && val == 0)) {
/* Remember the header that is closest to the target.
@@ -1954,17 +2014,17 @@ void undo_time(long step, int sec, int file, int absolute)
}
target = closest_seq;
- dosec = FALSE;
- dofile = FALSE;
- if (step < 0)
- above = TRUE; /* stop above the header */
+ dosec = false;
+ dofile = false;
+ if (step < 0) {
+ above = true; // stop above the header
+ }
}
- /* If we found it: Follow the path to go to where we want to be. */
- if (uhp != NULL) {
- /*
- * First go up the tree as much as needed.
- */
+target_zero:
+ // If we found it: Follow the path to go to where we want to be.
+ if (uhp != NULL || target == 0) {
+ // First go up the tree as much as needed.
while (!got_int) {
/* Do the change warning now, for the same reason as above. */
change_warning(0);
@@ -1974,99 +2034,112 @@ void undo_time(long step, int sec, int file, int absolute)
uhp = curbuf->b_u_newhead;
else
uhp = uhp->uh_next.ptr;
- if (uhp == NULL || uhp->uh_walk != mark
- || (uhp->uh_seq == target && !above))
+ if (uhp == NULL
+ || (target > 0 && uhp->uh_walk != mark)
+ || (uhp->uh_seq == target && !above)) {
break;
+ }
curbuf->b_u_curhead = uhp;
- u_undoredo(TRUE);
- uhp->uh_walk = nomark; /* don't go back down here */
+ u_undoredo(true, true);
+ if (target > 0) {
+ uhp->uh_walk = nomark; // don't go back down here
+ }
}
- /*
- * And now go down the tree (redo), branching off where needed.
- */
- while (!got_int) {
- /* Do the change warning now, for the same reason as above. */
- change_warning(0);
+ // When back to origin, redo is not needed.
+ if (target > 0) {
+ // And now go down the tree (redo), branching off where needed.
+ while (!got_int) {
+ // Do the change warning now, for the same reason as above.
+ change_warning(0);
- uhp = curbuf->b_u_curhead;
- if (uhp == NULL)
- break;
-
- /* Go back to the first branch with a mark. */
- while (uhp->uh_alt_prev.ptr != NULL
- && uhp->uh_alt_prev.ptr->uh_walk == mark)
- uhp = uhp->uh_alt_prev.ptr;
+ uhp = curbuf->b_u_curhead;
+ if (uhp == NULL) {
+ break;
+ }
- /* Find the last branch with a mark, that's the one. */
- last = uhp;
- while (last->uh_alt_next.ptr != NULL
- && last->uh_alt_next.ptr->uh_walk == mark)
- last = last->uh_alt_next.ptr;
- if (last != uhp) {
- /* Make the used branch the first entry in the list of
- * alternatives to make "u" and CTRL-R take this branch. */
- while (uhp->uh_alt_prev.ptr != NULL)
+ // Go back to the first branch with a mark.
+ while (uhp->uh_alt_prev.ptr != NULL
+ && uhp->uh_alt_prev.ptr->uh_walk == mark) {
uhp = uhp->uh_alt_prev.ptr;
- if (last->uh_alt_next.ptr != NULL)
- last->uh_alt_next.ptr->uh_alt_prev.ptr =
- last->uh_alt_prev.ptr;
- last->uh_alt_prev.ptr->uh_alt_next.ptr = last->uh_alt_next.ptr;
- last->uh_alt_prev.ptr = NULL;
- last->uh_alt_next.ptr = uhp;
- uhp->uh_alt_prev.ptr = last;
-
- if (curbuf->b_u_oldhead == uhp)
- curbuf->b_u_oldhead = last;
- uhp = last;
- if (uhp->uh_next.ptr != NULL)
- uhp->uh_next.ptr->uh_prev.ptr = uhp;
- }
- curbuf->b_u_curhead = uhp;
+ }
- if (uhp->uh_walk != mark)
- break; /* must have reached the target */
+ // Find the last branch with a mark, that's the one.
+ last = uhp;
+ while (last->uh_alt_next.ptr != NULL
+ && last->uh_alt_next.ptr->uh_walk == mark) {
+ last = last->uh_alt_next.ptr;
+ }
+ if (last != uhp) {
+ // Make the used branch the first entry in the list of
+ // alternatives to make "u" and CTRL-R take this branch.
+ while (uhp->uh_alt_prev.ptr != NULL) {
+ uhp = uhp->uh_alt_prev.ptr;
+ }
+ if (last->uh_alt_next.ptr != NULL) {
+ last->uh_alt_next.ptr->uh_alt_prev.ptr = last->uh_alt_prev.ptr;
+ }
+ last->uh_alt_prev.ptr->uh_alt_next.ptr = last->uh_alt_next.ptr;
+ last->uh_alt_prev.ptr = NULL;
+ last->uh_alt_next.ptr = uhp;
+ uhp->uh_alt_prev.ptr = last;
- /* Stop when going backwards in time and didn't find the exact
- * header we were looking for. */
- if (uhp->uh_seq == target && above) {
- curbuf->b_u_seq_cur = target - 1;
- break;
- }
+ if (curbuf->b_u_oldhead == uhp) {
+ curbuf->b_u_oldhead = last;
+ }
+ uhp = last;
+ if (uhp->uh_next.ptr != NULL) {
+ uhp->uh_next.ptr->uh_prev.ptr = uhp;
+ }
+ }
+ curbuf->b_u_curhead = uhp;
- u_undoredo(FALSE);
+ if (uhp->uh_walk != mark) {
+ break; // must have reached the target
+ }
- /* Advance "curhead" to below the header we last used. If it
- * becomes NULL then we need to set "newhead" to this leaf. */
- if (uhp->uh_prev.ptr == NULL)
- curbuf->b_u_newhead = uhp;
- curbuf->b_u_curhead = uhp->uh_prev.ptr;
- did_undo = FALSE;
+ // Stop when going backwards in time and didn't find the exact
+ // header we were looking for.
+ if (uhp->uh_seq == target && above) {
+ curbuf->b_u_seq_cur = target - 1;
+ break;
+ }
- if (uhp->uh_seq == target) /* found it! */
- break;
+ u_undoredo(false, true);
- uhp = uhp->uh_prev.ptr;
- if (uhp == NULL || uhp->uh_walk != mark) {
- /* Need to redo more but can't find it... */
- EMSG2(_(e_intern2), "undo_time()");
- break;
+ // Advance "curhead" to below the header we last used. If it
+ // becomes NULL then we need to set "newhead" to this leaf.
+ if (uhp->uh_prev.ptr == NULL) {
+ curbuf->b_u_newhead = uhp;
+ }
+ curbuf->b_u_curhead = uhp->uh_prev.ptr;
+ did_undo = false;
+
+ if (uhp->uh_seq == target) { // found it!
+ break;
+ }
+
+ uhp = uhp->uh_prev.ptr;
+ if (uhp == NULL || uhp->uh_walk != mark) {
+ // Need to redo more but can't find it...
+ internal_error("undo_time()");
+ break;
+ }
}
}
}
- u_undo_end(did_undo, absolute);
+ u_undo_end(did_undo, absolute, false);
}
-/*
- * u_undoredo: common code for undo and redo
- *
- * The lines in the file are replaced by the lines in the entry list at
- * curbuf->b_u_curhead. The replaced lines in the file are saved in the entry
- * list for the next undo/redo.
- *
- * When "undo" is TRUE we go up in the tree, when FALSE we go down.
- */
-static void u_undoredo(int undo)
+/// u_undoredo: common code for undo and redo
+///
+/// The lines in the file are replaced by the lines in the entry list at
+/// curbuf->b_u_curhead. The replaced lines in the file are saved in the entry
+/// list for the next undo/redo.
+///
+/// @param undo If `true`, go up the tree. Down if `false`.
+/// @param do_buf_event If `true`, send buffer updates.
+static void u_undoredo(int undo, bool do_buf_event)
{
char_u **newarray = NULL;
linenr_T oldsize;
@@ -2115,8 +2188,8 @@ static void u_undoredo(int undo)
if (top > curbuf->b_ml.ml_line_count || top >= bot
|| bot > curbuf->b_ml.ml_line_count + 1) {
unblock_autocmds();
- EMSG(_("E438: u_undo: line numbers wrong"));
- changed(); /* don't want UNCHANGED now */
+ IEMSG(_("E438: u_undo: line numbers wrong"));
+ changed(); // don't want UNCHANGED now
return;
}
@@ -2173,10 +2246,11 @@ static void u_undoredo(int undo)
* If the file is empty, there is an empty line 1 that we
* should get rid of, by replacing it with the new line
*/
- if (empty_buffer && lnum == 0)
- ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
- else
+ if (empty_buffer && lnum == 0) {
+ ml_replace((linenr_T)1, uep->ue_array[i], true);
+ } else {
ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
+ }
xfree(uep->ue_array[i]);
}
xfree((char_u *)uep->ue_array);
@@ -2185,14 +2259,16 @@ static void u_undoredo(int undo)
/* adjust marks */
if (oldsize != newsize) {
mark_adjust(top + 1, top + oldsize, (long)MAXLNUM,
- (long)newsize - (long)oldsize);
- if (curbuf->b_op_start.lnum > top + oldsize)
+ (long)newsize - (long)oldsize, false);
+ if (curbuf->b_op_start.lnum > top + oldsize) {
curbuf->b_op_start.lnum += newsize - oldsize;
- if (curbuf->b_op_end.lnum > top + oldsize)
+ }
+ if (curbuf->b_op_end.lnum > top + oldsize) {
curbuf->b_op_end.lnum += newsize - oldsize;
+ }
}
- changed_lines(top + 1, 0, bot, newsize - oldsize);
+ changed_lines(top + 1, 0, bot, newsize - oldsize, do_buf_event);
/* set '[ and '] mark */
if (top + 1 < curbuf->b_op_start.lnum)
@@ -2218,12 +2294,21 @@ static void u_undoredo(int undo)
curhead->uh_entry = newlist;
curhead->uh_flags = new_flags;
- if ((old_flags & UH_EMPTYBUF) && bufempty())
+ if ((old_flags & UH_EMPTYBUF) && BUFEMPTY()) {
curbuf->b_ml.ml_flags |= ML_EMPTY;
- if (old_flags & UH_CHANGED)
+ }
+ if (old_flags & UH_CHANGED) {
changed();
- else
+ } else {
unchanged(curbuf, FALSE);
+ }
+
+ // because the calls to changed()/unchanged() above will bump changedtick
+ // again, we need to send a nvim_buf_lines_event with just the new value of
+ // b:changedtick
+ if (do_buf_event && kv_size(curbuf->update_channels)) {
+ buf_updates_changedtick(curbuf);
+ }
/*
* restore marks from before undo/redo
@@ -2278,7 +2363,8 @@ static void u_undoredo(int undo)
if (undo)
/* We are below the previous undo. However, to make ":earlier 1s"
* work we compute this as being just above the just undone change. */
- --curbuf->b_u_seq_cur;
+ curbuf->b_u_seq_cur = curhead->uh_next.ptr ?
+ curhead->uh_next.ptr->uh_seq : 0;
/* Remember where we are for ":earlier 1f" and ":later 1f". */
if (curhead->uh_save_nr != 0) {
@@ -2298,16 +2384,13 @@ static void u_undoredo(int undo)
#endif
}
-/*
- * If we deleted or added lines, report the number of less/more lines.
- * Otherwise, report the number of changes (this may be incorrect
- * in some cases, but it's better than nothing).
- */
-static void
-u_undo_end (
- int did_undo, /* just did an undo */
- int absolute /* used ":undo N" */
-)
+/// If we deleted or added lines, report the number of less/more lines.
+/// Otherwise, report the number of changes (this may be incorrect
+/// in some cases, but it's better than nothing).
+static void u_undo_end(
+ bool did_undo, ///< just did an undo
+ bool absolute, ///< used ":undo N"
+ bool quiet)
{
char *msgstr;
u_header_T *uhp;
@@ -2316,9 +2399,11 @@ u_undo_end (
if ((fdo_flags & FDO_UNDO) && KeyTyped)
foldOpenCursor();
- if (global_busy /* no messages now, wait until global is finished */
- || !messaging()) /* 'lazyredraw' set, don't do messages now */
+ if (quiet
+ || global_busy // no messages until global is finished
+ || !messaging()) { // 'lazyredraw' set, don't do messages now
return;
+ }
if (curbuf->b_ml.ml_flags & ML_EMPTY)
--u_newcount;
@@ -2344,13 +2429,15 @@ u_undo_end (
/* For ":undo N" we prefer a "after #N" message. */
if (absolute && curbuf->b_u_curhead->uh_next.ptr != NULL) {
uhp = curbuf->b_u_curhead->uh_next.ptr;
- did_undo = FALSE;
- } else if (did_undo)
+ did_undo = false;
+ } else if (did_undo) {
uhp = curbuf->b_u_curhead;
- else
+ } else {
uhp = curbuf->b_u_curhead->uh_next.ptr;
- } else
+ }
+ } else {
uhp = curbuf->b_u_newhead;
+ }
if (uhp == NULL)
*msgbuf = NUL;
@@ -2376,9 +2463,9 @@ u_undo_end (
/*
* u_sync: stop adding to the current entry list
*/
-void
-u_sync (
- int force /* Also sync when no_u_sync is set. */
+void
+u_sync(
+ int force // Also sync when no_u_sync is set.
)
{
/* Skip it when already synced or syncing is disabled. */
@@ -2416,8 +2503,8 @@ void ex_undolist(exarg_T *eap)
while (uhp != NULL) {
if (uhp->uh_prev.ptr == NULL && uhp->uh_walk != nomark
&& uhp->uh_walk != mark) {
- vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7ld ",
- uhp->uh_seq, changes);
+ vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7d ",
+ uhp->uh_seq, changes);
u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
uhp->uh_time);
if (uhp->uh_save_nr > 0) {
@@ -2468,13 +2555,14 @@ void ex_undolist(exarg_T *eap)
sort_strings((char_u **)ga.ga_data, ga.ga_len);
msg_start();
- msg_puts_attr((char_u *)_("number changes when saved"),
- hl_attr(HLF_T));
- for (int i = 0; i < ga.ga_len && !got_int; ++i) {
+ msg_puts_attr(_("number changes when saved"),
+ HL_ATTR(HLF_T));
+ for (int i = 0; i < ga.ga_len && !got_int; i++) {
msg_putchar('\n');
- if (got_int)
+ if (got_int) {
break;
- msg_puts(((char_u **)ga.ga_data)[i]);
+ }
+ msg_puts(((const char **)ga.ga_data)[i]);
}
msg_end();
@@ -2507,20 +2595,20 @@ static void u_add_time(char_u *buf, size_t buflen, time_t tt)
*/
void ex_undojoin(exarg_T *eap)
{
- if (curbuf->b_u_newhead == NULL)
- return; /* nothing changed before */
+ if (curbuf->b_u_newhead == NULL) {
+ return; // nothing changed before
+ }
if (curbuf->b_u_curhead != NULL) {
EMSG(_("E790: undojoin is not allowed after undo"));
return;
}
- if (!curbuf->b_u_synced)
- return; /* already unsynced */
- if (get_undolevel() < 0)
- return; /* no entries, nothing to do */
- else {
- /* Go back to the last entry */
- curbuf->b_u_curhead = curbuf->b_u_newhead;
- curbuf->b_u_synced = false; /* no entries, nothing to do */
+ if (!curbuf->b_u_synced) {
+ return; // already unsynced
+ }
+ if (get_undolevel() < 0) {
+ return; // no entries, nothing to do
+ } else {
+ curbuf->b_u_synced = false; // Append next change to last entry
}
}
@@ -2604,7 +2692,7 @@ static void u_unch_branch(u_header_T *uhp)
static u_entry_T *u_get_headentry(void)
{
if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL) {
- EMSG(_("E439: undo list corrupt"));
+ IEMSG(_("E439: undo list corrupt"));
return NULL;
}
return curbuf->b_u_newhead->uh_entry;
@@ -2633,11 +2721,11 @@ static void u_getbot(void)
extra = curbuf->b_ml.ml_line_count - uep->ue_lcount;
uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra;
if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count) {
- EMSG(_("E440: undo line missing"));
- uep->ue_bot = uep->ue_top + 1; /* assume all lines deleted, will
- * get all the old lines back
- * without deleting the current
- * ones */
+ IEMSG(_("E440: undo line missing"));
+ uep->ue_bot = uep->ue_top + 1; // assume all lines deleted, will
+ // get all the old lines back
+ // without deleting the current
+ // ones
}
curbuf->b_u_newhead->uh_getbot_entry = NULL;
@@ -2649,11 +2737,11 @@ static void u_getbot(void)
/*
* Free one header "uhp" and its entry list and adjust the pointers.
*/
-static void
-u_freeheader (
+static void
+u_freeheader(
buf_T *buf,
u_header_T *uhp,
- u_header_T **uhpp /* if not NULL reset when freeing this header */
+ u_header_T **uhpp // if not NULL reset when freeing this header
)
{
u_header_T *uhap;
@@ -2685,11 +2773,11 @@ u_freeheader (
/*
* Free an alternate branch and any following alternate branches.
*/
-static void
-u_freebranch (
+static void
+u_freebranch(
buf_T *buf,
u_header_T *uhp,
- u_header_T **uhpp /* if not NULL reset when freeing this header */
+ u_header_T **uhpp // if not NULL reset when freeing this header
)
{
u_header_T *tofree, *next;
@@ -2719,11 +2807,11 @@ u_freebranch (
* Free all the undo entries for one header and the header itself.
* This means that "uhp" is invalid when returning.
*/
-static void
-u_freeentries (
+static void
+u_freeentries(
buf_T *buf,
u_header_T *uhp,
- u_header_T **uhpp /* if not NULL reset when freeing this header */
+ u_header_T **uhpp // if not NULL reset when freeing this header
)
{
u_entry_T *uep, *nuep;
@@ -2830,7 +2918,7 @@ void u_undoline(void)
curbuf->b_u_line_lnum + 1, (linenr_T)0, FALSE) == FAIL)
return;
oldp = u_save_line(curbuf->b_u_line_lnum);
- ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
+ ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, true);
changed_bytes(curbuf->b_u_line_lnum, 0);
xfree(curbuf->b_u_line_ptr);
curbuf->b_u_line_ptr = oldp;
@@ -2890,35 +2978,39 @@ bool curbufIsChanged(void)
&& (curbuf->b_changed || file_ff_differs(curbuf, true)));
}
-/*
- * For undotree(): Append the list of undo blocks at "first_uhp" to "list".
- * Recursive.
- */
-void u_eval_tree(u_header_T *first_uhp, list_T *list)
+/// Append the list of undo blocks to a newly allocated list
+///
+/// For use in undotree(). Recursive.
+///
+/// @param[in] first_uhp Undo blocks list to start with.
+///
+/// @return [allocated] List with a representation of undo blocks.
+list_T *u_eval_tree(const u_header_T *const first_uhp)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
{
- u_header_T *uhp = first_uhp;
- dict_T *dict;
+ list_T *const list = tv_list_alloc(kListLenMayKnow);
- while (uhp != NULL) {
- dict = dict_alloc();
- dict_add_nr_str(dict, "seq", uhp->uh_seq, NULL);
- dict_add_nr_str(dict, "time", (long)uhp->uh_time, NULL);
- if (uhp == curbuf->b_u_newhead)
- dict_add_nr_str(dict, "newhead", 1, NULL);
- if (uhp == curbuf->b_u_curhead)
- dict_add_nr_str(dict, "curhead", 1, NULL);
- if (uhp->uh_save_nr > 0)
- dict_add_nr_str(dict, "save", uhp->uh_save_nr, NULL);
+ for (const u_header_T *uhp = first_uhp; uhp != NULL; uhp = uhp->uh_prev.ptr) {
+ dict_T *const dict = tv_dict_alloc();
+ tv_dict_add_nr(dict, S_LEN("seq"), (varnumber_T)uhp->uh_seq);
+ tv_dict_add_nr(dict, S_LEN("time"), (varnumber_T)uhp->uh_time);
+ if (uhp == curbuf->b_u_newhead) {
+ tv_dict_add_nr(dict, S_LEN("newhead"), 1);
+ }
+ if (uhp == curbuf->b_u_curhead) {
+ tv_dict_add_nr(dict, S_LEN("curhead"), 1);
+ }
+ if (uhp->uh_save_nr > 0) {
+ tv_dict_add_nr(dict, S_LEN("save"), (varnumber_T)uhp->uh_save_nr);
+ }
if (uhp->uh_alt_next.ptr != NULL) {
- list_T *alt_list = list_alloc();
-
- /* Recursive call to add alternate undo tree. */
- u_eval_tree(uhp->uh_alt_next.ptr, alt_list);
- dict_add_list(dict, "alt", alt_list);
+ // Recursive call to add alternate undo tree.
+ tv_dict_add_list(dict, S_LEN("alt"), u_eval_tree(uhp->uh_alt_next.ptr));
}
- list_append_dict(list, dict);
- uhp = uhp->uh_prev.ptr;
+ tv_list_append_dict(list, dict);
}
+
+ return list;
}
diff --git a/src/nvim/undo.h b/src/nvim/undo.h
index ab8584fbb2..802cdc5583 100644
--- a/src/nvim/undo.h
+++ b/src/nvim/undo.h
@@ -2,6 +2,7 @@
#define NVIM_UNDO_H
#include "nvim/undo_defs.h"
+#include "nvim/ex_cmds_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "undo.h.generated.h"
diff --git a/src/nvim/undo_defs.h b/src/nvim/undo_defs.h
index d841210815..6c7e2bba41 100644
--- a/src/nvim/undo_defs.h
+++ b/src/nvim/undo_defs.h
@@ -4,9 +4,10 @@
#include <time.h> // for time_t
#include "nvim/pos.h"
-#include "nvim/buffer_defs.h"
#include "nvim/mark_defs.h"
+typedef struct u_header u_header_T;
+
/* Structure to store info about the Visual area. */
typedef struct {
pos_T vi_start; /* start pos of last VIsual */
@@ -15,8 +16,9 @@ typedef struct {
colnr_T vi_curswant; /* MAXCOL from w_curswant */
} visualinfo_T;
+#include "nvim/buffer_defs.h"
+
typedef struct u_entry u_entry_T;
-typedef struct u_header u_header_T;
struct u_entry {
u_entry_T *ue_next; /* pointer to next entry in list */
linenr_T ue_top; /* number of line above undo block */
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 8aa3071395..20b71ab724 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.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
+
/// @file version.c
///
/// Nvim was forked from Vim 7.4.160.
@@ -7,28 +10,28 @@
#include <assert.h>
#include <limits.h>
+#include "nvim/api/private/helpers.h"
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/iconv.h"
#include "nvim/version.h"
#include "nvim/charset.h"
+#include "nvim/macros.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/misc2.h"
#include "nvim/screen.h"
#include "nvim/strings.h"
+#include "nvim/lua/executor.h"
// version info generated by the build system
#include "auto/versiondef.h"
-#define STR_(x) #x
-#define STR(x) STR_(x)
-
// for ":version", ":intro", and "nvim --version"
#ifndef NVIM_VERSION_MEDIUM
-#define NVIM_VERSION_MEDIUM STR(NVIM_VERSION_MAJOR) "." STR(NVIM_VERSION_MINOR)\
- "." STR(NVIM_VERSION_PATCH) NVIM_VERSION_PRERELEASE
+#define NVIM_VERSION_MEDIUM "v" STR(NVIM_VERSION_MAJOR)\
+"." STR(NVIM_VERSION_MINOR) "." STR(NVIM_VERSION_PATCH)\
+NVIM_VERSION_PRERELEASE
#endif
#define NVIM_VERSION_LONG "NVIM " NVIM_VERSION_MEDIUM
@@ -44,1055 +47,1280 @@ char *version_cflags = "Compilation: " NVIM_VERSION_CFLAGS;
static char *features[] = {
#ifdef HAVE_ACL
- "+acl",
+"+acl",
#else
- "-acl",
+"-acl",
#endif
#if (defined(HAVE_ICONV_H) && defined(USE_ICONV)) || defined(DYNAMIC_ICONV)
# ifdef DYNAMIC_ICONV
- "+iconv/dyn",
+"+iconv/dyn",
# else
- "+iconv",
+"+iconv",
# endif
#else
- "-iconv",
+"-iconv",
#endif
#ifdef HAVE_JEMALLOC
- "+jemalloc",
+"+jemalloc",
#else
- "-jemalloc",
+"-jemalloc",
#endif
#ifdef FEAT_TUI
- "+tui",
+"+tui",
#else
- "-tui",
+"-tui",
#endif
- NULL
+NULL
};
// clang-format off
-static int included_patches[] = {
- 1973,
- 1960,
+static const int included_patches[] = {
+ 1849,
+ // 1848,
+ 1847,
+ // 1846,
+ // 1845,
+ // 1844,
+ 1843,
+ // 1842,
+ // 1841,
1840,
+ 1839,
+ // 1838,
+ 1837,
+ 1836,
+ // 1835,
+ 1834,
+ 1833,
1832,
- 1831,
+ // 1831,
+ // 1830,
+ 1829,
+ 1828,
+ // 1827,
+ 1826,
+ 1825,
+ // 1824,
+ // 1823,
+ 1822,
+ // 1821,
+ // 1820,
+ 1819,
+ // 1818,
+ // 1817,
+ 1816,
+ // 1815,
+ // 1814,
+ 1813,
+ // 1812,
+ 1811,
+ // 1810,
1809,
1808,
- 1806,
+ 1807,
+ // 1806,
+ // 1805,
+ // 1804,
+ // 1803,
+ // 1802,
+ // 1801,
+ 1800,
1799,
+ // 1798,
+ // 1797,
+ // 1796,
+ // 1795,
+ // 1794,
+ // 1793,
+ 1792,
+ 1791,
+ 1790,
+ // 1789,
+ 1788,
+ 1787,
+ // 1786,
+ 1785,
+ // 1784,
+ // 1783,
+ // 1782,
+ 1781,
+ // 1780,
+ 1779,
+ 1778,
+ 1777,
+ // 1776,
+ // 1775,
+ // 1774,
+ // 1773,
+ // 1772,
+ // 1771,
+ // 1770,
+ // 1769,
+ // 1768,
+ // 1767,
+ 1766,
+ 1765,
+ 1764,
+ // 1763,
+ // 1762,
+ // 1761,
+ 1760,
+ // 1759,
+ 1758,
1757,
+ // 1756,
1755,
- 1753,
- 1728,
- 1716,
- 1712,
- 1695,
- 1654,
- 1652,
+ // 1754,
+ // 1753,
+ // 1752,
+ 1751,
+ // 1750,
+ 1749,
+ 1748,
+ // 1747,
+ // 1746,
+ // 1745,
+ // 1744,
+ // 1743,
+ // 1742,
+ 1741,
+ // 1740,
+ 1739,
+ // 1738,
+ 1737,
+ 1736,
+ // 1735,
+ 1734,
+ // 1733,
+ // 1732,
+ 1731,
+ 1730,
+ // 1729,
+ // 1728,
+ // 1727,
+ // 1726,
+ // 1725,
+ // 1724,
+ // 1723,
+ // 1722,
+ // 1721,
+ // 1720,
+ 1719,
+ // 1718,
+ 1717,
+ // 1716,
+ // 1715,
+ // 1714,
+ // 1713,
+ // 1712,
+ // 1711,
+ 1710,
+ // 1709,
+ // 1708,
+ 1707,
+ // 1706,
+ 1705,
+ // 1704,
+ // 1703,
+ // 1702,
+ 1701,
+ 1700,
+ 1699,
+ 1698,
+ // 1697,
+ 1696,
+ // 1695,
+ // 1694,
+ // 1693,
+ 1692,
+ // 1691,
+ // 1690,
+ // 1689,
+ // 1688,
+ // 1687,
+ 1686,
+ // 1685,
+ // 1684,
+ 1683,
+ 1682,
+ // 1681,
+ // 1680,
+ 1679,
+ // 1678,
+ // 1677,
+ // 1676,
+ 1675,
+ 1674,
+ // 1673,
+ 1672,
+ // 1671,
+ // 1670,
+ // 1669,
+ // 1668,
+ // 1667,
+ // 1666,
+ // 1665,
+ // 1664,
+ 1663,
+ // 1662,
+ // 1661,
+ // 1660,
+ 1659,
+ // 1658,
+ // 1657,
+ // 1656,
+ // 1655,
+ // 1654,
+ // 1653,
+ // 1652,
+ // 1651,
+ 1650,
1649,
- 1643,
- 1641,
- // 1624 NA
-
- // 1600 NA
- // 1599 NA
- // 1598 NA
- // 1597 NA
- 1596,
- // 1595 NA
- // 1594 NA
- // 1593 NA
- 1592,
+ // 1648,
+ // 1647,
+ 1646,
+ // 1645,
+ // 1644,
+ // 1643,
+ // 1642,
+ // 1641,
+ // 1640,
+ 1639,
+ // 1638,
+ // 1637,
+ // 1636,
+ 1635,
+ // 1634,
+ 1633,
+ // 1632,
+ // 1631,
+ 1630,
+ // 1629,
+ // 1628,
+ 1627,
+ // 1626,
+ 1625,
+ // 1624,
+ // 1623,
+ 1622,
+ // 1621,
+ 1620,
+ // 1619,
+ 1618,
+ // 1617,
+ // 1616,
+ // 1615,
+ 1614,
+ 1613,
+ // 1612,
+ // 1611,
+ 1610,
+ // 1609,
+ 1608,
+ // 1607,
+ 1606,
+ // 1605,
+ // 1604,
+ 1603,
+ 1602,
+ 1601,
+ 1600,
+ // 1599,
+ // 1598,
+ 1597,
+ // 1596,
+ 1595,
+ // 1594,
+ // 1593,
+ // 1592,
// 1591,
- // 1590,
+ 1590,
// 1589,
// 1588,
- // 1587 NA
- // 1586,
- // 1585,
- // 1584 NA
- // 1583 NA
+ // 1587,
+ 1586,
+ 1585,
+ 1584,
+ 1583,
// 1582,
-
- // 1581,
- // 1580,
- // 1579 NA
- 1578,
- // 1577,
- 1576,
- // 1575 NA
- 1574,
- // 1573 NA
- // 1572 NA
+ 1581,
+ 1580,
+ 1579,
+ // 1578,
+ 1577,
+ // 1576,
+ 1575,
+ // 1574,
+ 1573,
+ // 1572,
1571,
- 1570,
- 1569,
- 1568,
+ // 1570,
+ // 1569,
+ // 1568,
1567,
- // 1566 NA
- // 1565,
- // 1564,
+ 1566,
+ 1565,
+ 1564,
// 1563,
- // 1562 NA
- // 1561 NA
- // 1560 NA
- // 1559,
+ // 1562,
+ 1561,
+ 1560,
+ 1559,
// 1558,
- // 1557,
- // 1556 NA
- // 1555 NA
- 1554,
+ 1557,
+ 1556,
+ 1555,
+ // 1554,
1553,
- 1552,
- 1551,
- 1550,
+ // 1552,
+ // 1551,
+ // 1550,
// 1549,
- // 1548,
- // 1547,
+ 1548,
+ 1547,
// 1546,
- // 1545 NA
- // 1544 NA
- // 1543 NA
- // 1542 NA
- // 1541 NA
- // 1540 NA
- // 1539 NA
- // 1538 NA
- // 1537 NA
- // 1536 NA
+ // 1545,
+ // 1544,
+ // 1543,
+ // 1542,
+ 1541,
+ // 1540,
+ // 1539,
+ // 1538,
+ // 1537,
+ 1536,
// 1535,
- // 1534 NA
+ // 1534,
// 1533,
- // 1532 NA
- // 1531 NA
- // 1530 NA
- // 1529 NA
- 1528,
- // 1527 NA
- // 1526 NA
- // 1525 NA
- // 1524 NA
- // 1523 NA
- // 1522 NA
- 1521,
- // 1520 NA
- // 1519 NA
- // 1518 NA
- // 1517 NA
- 1516,
- // 1515 NA
- // 1514 NA
- 1513,
- // 1512 NA
- 1511,
- // 1510 NA
- // 1509 NA
- // 1508 NA
- // 1507 NA
- // 1506 NA
- // 1505 NA
- // 1504 NA
- // 1503 NA
- // 1502 NA
- // 1501 NA
- 1500,
- 1499,
- // 1498 NA
- // 1497 NA
- // 1496 NA
- // 1495 NA
- // 1494,
- // 1493 NA
- 1492,
+ 1532,
+ // 1531,
+ 1530,
+ // 1529,
+ // 1528,
+ // 1527,
+ // 1526,
+ // 1525,
+ // 1524,
+ // 1523,
+ // 1522,
+ // 1521,
+ // 1520,
+ // 1519,
+ // 1518,
+ 1517,
+ // 1516,
+ // 1515,
+ // 1514,
+ // 1513,
+ 1512,
+ // 1511,
+ // 1510,
+ 1509,
+ 1508,
+ 1507,
+ 1506,
+ // 1505,
+ 1504,
+ 1503,
+ 1502,
+ // 1501,
+ // 1500,
+ // 1499,
+ // 1498,
+ // 1497,
+ // 1496,
+ // 1495,
+ 1494,
+ 1493,
+ // 1492,
// 1491,
- // 1490 NA
- // 1489 NA
- // 1488 NA
- // 1487 NA
+ 1490,
+ 1489,
+ 1488,
+ 1487,
1486,
- // 1485 NA
- // 1484 NA
- // 1483 NA
- // 1482 NA
- // 1481 NA
- 1480,
- 1479,
+ 1485,
+ // 1484,
+ 1483,
+ // 1482,
+ // 1481,
+ // 1480,
+ // 1479,
1478,
// 1477,
- // 1476 NA
- // 1475 NA
- // 1474 NA
- // 1473 NA
- // 1472 NA
- // 1471 NA
- // 1470 NA
- // 1469 NA
+ // 1476,
+ 1475,
+ 1474,
+ 1473,
+ 1472,
+ 1471,
+ 1470,
+ 1469,
1468,
- // 1467 NA
- // 1466 NA
- // 1465 NA
+ 1467,
+ 1466,
+ 1465,
1464,
- // 1463 NA
- // 1462 NA
- // 1461 NA
- // 1460 NA
- // 1459 NA
- // 1458 NA
- // 1457 NA
- // 1456,
- // 1455 NA
- // 1454 NA
- // 1453 NA
- // 1452 NA
- // 1451 NA
- // 1450 NA
- // 1449 NA
- // 1448 NA
- // 1447 NA
- // 1446 NA
- // 1445 NA
- // 1444 NA
- // 1443 NA
- // 1442 NA
- // 1441 NA
- // 1440 NA
- // 1439 NA
- // 1438 NA
- // 1437 NA
- // 1436 NA
- // 1435 NA
- // 1434 NA
- // 1433 NA
- // 1432 NA
- // 1431 NA
- // 1430 NA
- // 1429 NA
- // 1428 NA
- // 1427 NA
- // 1426 NA
+ // 1463,
+ // 1462,
+ // 1461,
+ // 1460,
+ // 1459,
+ 1458,
+ 1457,
+ 1456,
+ // 1455,
+ // 1454,
+ // 1453,
+ // 1452,
+ // 1451,
+ 1450,
+ // 1449,
+ // 1448,
+ // 1447,
+ 1446,
+ 1445,
+ 1444,
+ 1443,
+ 1442,
+ 1441,
+ // 1440,
+ 1439,
+ 1438,
+ 1437,
+ // 1436,
+ 1435,
+ 1434,
+ 1433,
+ // 1432,
+ 1431,
+ // 1430,
+ // 1429,
+ 1428,
+ 1427,
+ 1426,
1425,
- // 1424 NA
- // 1423 NA
- // 1422 NA
- // 1421 NA
- // 1420 NA
- // 1419 NA
- // 1418 NA
- // 1417 NA
- // 1416 NA
- // 1415 NA
- // 1414 NA
- // 1413 NA
- // 1412 NA
- // 1411 NA
+ 1424,
+ 1423,
+ // 1422,
+ 1421,
+ // 1420,
+ 1419,
+ 1418,
+ 1417,
+ 1416,
+ 1415,
+ // 1414,
+ 1413,
+ // 1412,
+ // 1411,
1410,
- // 1409 NA
- // 1408 NA
- // 1407 NA
- 1406,
- 1405,
- // 1404 NA
- // 1403 NA
- // 1402 NA
+ 1409,
+ // 1408,
+ 1407,
+ // 1406,
+ // 1405,
+ 1404,
+ 1403,
+ 1402,
1401,
- // 1400 NA
- // 1399 NA
- // 1398 NA
+ 1400,
+ 1399,
+ 1398,
1397,
1396,
- // 1395 NA
+ 1395,
1394,
- // 1393 NA
- // 1392 NA
- // 1391 NA
- // 1390 NA
- // 1389 NA
- 1388,
- // 1387 NA
- // 1386 NA
- // 1385 NA
- 1384,
- // 1383 NA
- // 1382 NA
- // 1381 NA
- // 1380 NA
- // 1379 NA
- // 1378 NA
- // 1377 NA
- // 1376 NA
- // 1375 NA
- // 1374 NA
- // 1373 NA
- // 1372 NA
- // 1371 NA
- // 1370 NA
- // 1369 NA
- // 1368 NA
- // 1367 NA
- 1366,
- // 1365,
- // 1364 NA
- // 1363 NA
- // 1362 NA
- // 1361 NA
- // 1360 NA
- // 1359 NA
- // 1358 NA
- // 1357 NA
- // 1356 NA
- // 1355 NA
- // 1354 NA
- // 1353 NA
+ 1393,
+ 1392,
+ 1391,
+ 1390,
+ // 1389,
+ // 1388,
+ 1387,
+ // 1386,
+ 1385,
+ // 1384,
+ 1383,
+ // 1382,
+ // 1381,
+ 1380,
+ 1379,
+ 1378,
+ 1377,
+ // 1376,
+ // 1375,
+ 1374,
+ 1373,
+ // 1372,
+ // 1371,
+ 1370,
+ 1369,
+ // 1368,
+ // 1367,
+ // 1366,
+ 1365,
+ 1364,
+ 1363,
+ // 1362,
+ 1361,
+ // 1360,
+ // 1359,
+ // 1358,
+ 1357,
+ // 1356,
+ // 1355,
+ // 1354,
+ // 1353,
1352,
- // 1351 NA
- // 1350 NA
- // 1349 NA
- // 1348 NA
- 1347,
- 1346,
- // 1345 NA
- // 1344 NA
- // 1343 NA
- // 1342 NA
- // 1341 NA
- // 1340 NA
- // 1339 NA
- // 1338 NA
- // 1337 NA
- // 1336 NA
- // 1335 NA
- // 1334 NA
- // 1333 NA
- // 1332 NA
- // 1331 NA
- // 1330 NA
- // 1329 NA
- // 1328 NA
- // 1327 NA
- // 1326 NA
- // 1325 NA
- // 1324 NA
- // 1323 NA
- // 1322 NA
- // 1321 NA
- // 1320 NA
- // 1319 NA
- // 1318 NA
- // 1317 NA
- // 1316 NA
- // 1315 NA
- // 1314 NA
- // 1313 NA
- // 1312 NA
- // 1311 NA
- // 1310 NA
- 1309,
- // 1308 NA
- // 1307 NA
- // 1306 NA
+ 1351,
+ 1350,
+ // 1349,
+ // 1348,
+ // 1347,
+ // 1346,
+ // 1345,
+ // 1344,
+ 1343,
+ // 1342,
+ // 1341,
+ // 1340,
+ // 1339,
+ 1338,
+ 1337,
+ // 1336,
+ // 1335,
+ // 1334,
+ 1333,
+ // 1332,
+ 1331,
+ // 1330,
+ 1329,
+ // 1328,
+ 1327,
+ 1326,
+ 1325,
+ 1324,
+ // 1323,
+ 1322,
+ // 1321,
+ // 1320,
+ // 1319,
+ // 1318,
+ // 1317,
+ // 1316,
+ // 1315,
+ 1314,
+ 1313,
+ // 1312,
+ 1311,
+ 1310,
+ // 1309,
+ 1308,
+ // 1307,
+ 1306,
// 1305,
1304,
- // 1303 NA
- // 1302 NA
- // 1301 NA
- // 1300 NA
- // 1299 NA
- // 1298 NA
- // 1297 NA
- 1296,
- // 1295 NA
- // 1294 NA
- // 1293 NA
- 1292,
- // 1291 NA
- // 1290 NA
- // 1289 NA
- // 1288 NA
- // 1287 NA
- // 1286 NA
+ 1303,
+ 1302,
+ 1301,
+ // 1300,
+ // 1299,
+ // 1298,
+ // 1297,
+ // 1296,
+ // 1295,
+ 1294,
+ // 1293,
+ // 1292,
+ 1291,
+ 1290,
+ 1289,
+ 1288,
+ // 1287,
+ // 1286,
1285,
1284,
- // 1283 NA
+ 1283,
1282,
1281,
- // 1280 NA
- // 1279 NA
- // 1278 NA
- // 1277 NA
- 1276,
- // 1275 NA
- // 1274 NA
- // 1273,
- // 1272 NA
+ 1280,
+ 1279,
+ // 1278,
+ // 1277,
+ // 1276,
+ 1275,
+ // 1274,
+ 1273,
+ 1272,
1271,
- // 1270 NA
+ // 1270,
1269,
- // 1268 NA
- 1267,
- // 1266
- // 1265 NA
- // 1264 NA
- // 1263 NA
- // 1262 NA
- // 1261 NA
- // 1260 NA
- 1259,
- // 1258 NA
- // 1257 NA
- // 1256 NA
- // 1255 NA
- // 1254 NA
- // 1253 NA
- // 1252 NA
- // 1251 NA
- // 1250 NA
- // 1249 NA
- // 1248 NA
- // 1247 NA
- // 1246 NA
- // 1245 NA
- // 1244 NA
- // 1243 NA
- // 1242 NA
- // 1241 NA
- // 1240 NA
- // 1239 NA
- // 1238 NA
- // 1237,
- 1236,
- // 1235 NA
- // 1234 NA
- // 1233 NA
- // 1232 NA
- // 1231 NA
- // 1230 NA
- // 1229 NA
+ 1268,
+ // 1267,
+ // 1266,
+ // 1265,
+ // 1264,
+ // 1263,
+ 1262,
+ // 1261,
+ // 1260,
+ // 1259,
+ 1258,
+ 1257,
+ 1256,
+ 1255,
+ 1254,
+ 1253,
+ 1252,
+ 1251,
+ 1250,
+ 1249,
+ 1248,
+ 1247,
+ // 1246,
+ // 1245,
+ // 1244,
+ 1243,
+ 1242,
+ // 1241,
+ // 1240,
+ // 1239,
+ 1238,
+ 1237,
+ // 1236,
+ 1235,
+ 1234,
+ 1233,
+ 1232,
+ 1231,
+ 1230,
+ 1229,
1228,
- // 1227 NA
- // 1226 NA
- // 1225 NA
- // 1224 NA
+ 1227,
+ 1226,
+ 1225,
+ 1224,
1223,
- // 1222 NA
- // 1221 NA
- // 1220 NA
- // 1219 NA
- // 1218 NA
- // 1217 NA
- // 1216 NA
- // 1215 NA
- // 1214 NA
- // 1213 NA
- // 1212 NA
- // 1211 NA
- // 1210 NA
- // 1209 NA
- // 1208 NA
- // 1207 NA
- // 1206 NA
- // 1205 NA
- // 1204 NA
- // 1203 NA
- // 1202 NA
- // 1201 NA
- // 1200 NA
- // 1199 NA
- // 1198 NA
- // 1197 NA
- // 1196 NA
- // 1195 NA
- // 1194 NA
- // 1193 NA
- // 1192 NA
- // 1191 NA
- // 1190 NA
- // 1189 NA
- // 1188 NA
- // 1187 NA
- // 1186,
- // 1185 NA
- // 1184 NA
- // 1183 NA
- // 1182 NA
+ 1222,
+ 1221,
+ // 1220,
+ 1219,
+ 1218,
+ // 1217,
+ 1216,
+ 1215,
+ 1214,
+ // 1213,
+ 1212,
+ 1211,
+ 1210,
+ 1209,
+ // 1208,
+ 1207,
+ 1206,
+ 1205,
+ 1204,
+ // 1203,
+ // 1202,
+ 1201,
+ 1200,
+ // 1199,
+ 1198,
+ 1197,
+ 1196,
+ 1195,
+ // 1194,
+ // 1193,
+ 1192,
+ 1191,
+ 1190,
+ 1189,
+ 1188,
+ 1187,
+ 1186,
+ 1185,
+ 1184,
+ 1183,
+ // 1182,
1181,
1180,
// 1179,
1178,
- // 1177 NA
- // 1176 NA
- // 1175 NA
- // 1174 NA
- 1173,
- // 1172 NA
- // 1171 NA
- // 1170 NA
- // 1169 NA
+ // 1177,
+ // 1176,
+ 1175,
+ // 1174,
+ // 1173,
+ 1172,
+ 1171,
+ // 1170,
+ 1169,
1168,
- 1167,
+ // 1167,
1166,
- // 1165 NA
- 1164,
+ 1165,
+ // 1164,
1163,
- // 1162 NA
+ // 1162,
1161,
1160,
- // 1159 NA
- // 1158 NA
+ 1159,
+ 1158,
1157,
- // 1156 NA
- // 1155 NA
- // 1154 NA
- 1153,
- // 1152 NA
+ 1156,
+ 1155,
+ 1154,
+ // 1153,
+ 1152,
1151,
1150,
- 1149,
- // 1148 NA
- // 1147,
- // 1146 NA
- // 1145 NA
- 1144,
- 1143,
- 1142,
+ // 1149,
+ 1148,
+ 1147,
+ // 1146,
+ // 1145,
+ // 1144,
+ // 1143,
+ // 1142,
1141,
- // 1140,
- // 1139 NA
- // 1138 NA
- 1137,
+ 1140,
+ // 1139,
+ // 1138,
+ // 1137,
1136,
- // 1135 NA
- // 1134 NA
- // 1133 NA
- 1132,
- // 1131 NA
- // 1130 NA
- // 1129 NA
- // 1128 NA
- // 1127 NA
- 1126,
- // 1125 NA
- // 1124 NA
- 1123,
- // 1122 NA
+ 1135,
+ // 1134,
+ // 1133,
+ // 1132,
+ // 1131,
+ // 1130,
+ // 1129,
+ // 1128,
+ // 1127,
+ // 1126,
+ // 1125,
+ 1124,
+ // 1123,
+ 1122,
1121,
- 1120,
- 1119,
+ // 1120,
+ // 1119,
1118,
- 1117,
- 1116,
- // 1115 NA
- 1114,
- 1113,
- 1112,
+ // 1117,
+ // 1116,
+ 1115,
+ // 1114,
+ // 1113,
+ // 1112,
1111,
1110,
- // 1109 NA
+ // 1109,
1108,
- 1107,
- // 1106 NA
+ // 1107,
+ // 1106,
1105,
- // 1104 NA
- // 1103 NA
- 1102,
- 1101,
- // 1100 NA
- // 1099 NA
- // 1098 NA
- // 1097 NA
- 1096,
- // 1095 NA
+ // 1104,
+ // 1103,
+ // 1102,
+ // 1101,
+ // 1100,
+ 1099,
+ 1098,
+ // 1097,
+ // 1096,
+ // 1095,
1094,
- 1093,
- 1092,
+ // 1093,
+ // 1092,
1091,
1090,
1089,
1088,
- 1087,
+ // 1087,
1086,
- 1085,
+ // 1085,
1084,
- // 1083 NA
- // 1082 NA
- 1081,
- // 1080 NA
- // 1079 NA
- // 1078 NA
- // 1077 NA
- 1076,
- 1075,
- // 1074 NA,
- // 1073 NA
+ // 1083,
+ // 1082,
+ // 1081,
+ // 1080,
+ // 1079,
+ 1078,
+ // 1077,
+ // 1076,
+ // 1075,
+ // 1074,
+ // 1073,
1072,
1071,
- // 1070 NA
- // 1069 NA
+ // 1070,
+ 1069,
1068,
- // 1067 NA
- // 1066 NA
+ 1067,
+ 1066,
1065,
- 1064,
- // 1063 NA
- // 1062 NA
- 1061,
- // 1060 NA
+ // 1064,
+ // 1063,
+ 1062,
+ // 1061,
+ // 1060,
1059,
- // 1058 NA
- 1057,
+ // 1058,
+ // 1057,
1056,
- 1055,
- 1054,
- 1053,
- 1052,
- 1051,
+ // 1055,
+ // 1054,
+ // 1053,
+ // 1052,
+ // 1051,
1050,
- 1049,
+ // 1049,
1048,
1047,
1046,
- // 1045 NA
- // 1044 NA
- // 1043 NA
+ // 1045,
+ 1044,
+ 1043,
1042,
1041,
- // 1040 NA
- // 1039 NA
- // 1038 NA
+ 1040,
+ // 1039,
+ // 1038,
1037,
- 1036,
- 1035,
- 1034,
- // 1033 NA
+ // 1036,
+ // 1035,
+ // 1034,
+ 1033,
1032,
- // 1031 NA,
+ 1031,
1030,
1029,
- // 1028 NA
+ // 1028,
1027,
- // 1026 NA
- // 1025 NA
- // 1024 NA
- // 1023 NA
- // 1022 NA
- // 1021 NA
- // 1020 NA
- // 1019 NA
- 1018,
+ 1026,
+ 1025,
+ 1024,
+ 1023,
+ 1022,
+ 1021,
+ 1020,
+ 1019,
+ // 1018,
1017,
- // 1016 NA
- 1015,
- // 1014 NA
- 1013,
- // 1012 NA
- // 1011 NA
- // 1010 NA,
- // 1009 NA
- // 1008 NA
+ 1016,
+ // 1015,
+ 1014,
+ // 1013,
+ 1012,
+ // 1011,
+ 1010,
+ // 1009,
+ 1008,
1007,
1006,
- // 1005 NA,
- // 1004 NA,
- // 1003 NA,
- // 1002 NA,
+ // 1005,
+ 1004,
+ // 1003,
+ // 1002,
1001,
- 1000,
- // 999 NA
+ // 1000,
+ 999,
998,
- // 997 NA
- // 996 NA
- // 995 NA
- // 994 NA
- // 993 NA
- // 992 NA
- 991,
- // 990 NA
+ 997,
+ 996,
+ // 995,
+ // 994,
+ 993,
+ // 992,
+ // 991,
+ // 990,
989,
- // 988 NA
- // 987 NA
- // 986 NA
- // 985 NA
- 984,
- // 983 NA
- // 982 NA
- 981,
+ 988,
+ // 987,
+ 986,
+ // 985,
+ // 984,
+ 983,
+ // 982,
+ // 981,
980,
- // 979 NA
- 978,
- 977,
- // 976 NA
+ // 979,
+ // 978,
+ // 977,
+ // 976,
975,
974,
- 973,
+ // 973,
972,
- // 971 NA
- // 970 NA
- // 969 NA
- // 968 NA
- // 967 NA
- // 966 NA
- // 965 NA
- // 964 NA
- 963,
- // 962 NA
+ 971,
+ // 970,
+ // 969,
+ // 968,
+ 967,
+ 966,
+ // 965,
+ // 964,
+ // 963,
+ 962,
961,
- // 960 NA
- // 959 NA
- 958,
- 957,
- // 956 NA
+ // 960,
+ // 959,
+ // 958,
+ // 957,
+ // 956,
955,
- // 954 NA
- 953,
- 952,
- 951,
- 950,
- 949,
- // 948 NA
- // 947 NA
+ 954,
+ // 953,
+ // 952,
+ // 951,
+ // 950,
+ // 949,
+ 948,
+ // 947,
946,
- 945,
+ // 945,
944,
- // 943 NA
- 942,
- 941,
- // 940 NA
- 939,
- // 938 NA
- 937,
- 936,
- // 935 NA
- // 934 NA
- 933,
- 932,
- // 931 NA
- // 930 NA
- 929,
- // 928 NA
- // 927 NA
- 926,
+ // 943,
+ // 942,
+ // 941,
+ // 940,
+ // 939,
+ // 938,
+ // 937,
+ // 936,
+ // 935,
+ // 934,
+ // 933,
+ // 932,
+ // 931,
+ // 930,
+ // 929,
+ // 928,
+ // 927,
+ // 926,
925,
- // 924 NA
- // 923 NA
+ // 924,
+ // 923,
922,
- // 921 NA
- // 920 NA
- // 919 NA
- // 918 NA
- // 917 NA
- 916,
- 915,
- // 914 NA
- // 913 NA
- 912,
- // 911 NA
- // 910 NA
- // 909 NA
- // 908 NA
- // 907 NA
- // 906 NA
- // 905 NA
- // 904 NA
- 903,
- // 902 NA
+ 921,
+ // 920,
+ 919,
+ // 918,
+ // 917,
+ // 916,
+ // 915,
+ // 914,
+ // 913,
+ // 912,
+ // 911,
+ // 910,
+ // 909,
+ // 908,
+ // 907,
+ 906,
+ // 905,
+ 904,
+ // 903,
+ // 902,
901,
- // 900 NA
- // 899 NA
- 898,
- // 897 NA
- 896,
+ 900,
+ // 899,
+ // 898,
+ // 897,
+ // 896,
895,
- // 894 NA
- 893,
- // 892 NA
- 891,
- // 890 NA
- 889,
- 888,
- 887,
- // 886 NA
- 885,
- // 884 NA
+ 894,
+ // 893,
+ // 892,
+ // 891,
+ 890,
+ // 889,
+ // 888,
+ // 887,
+ // 886,
+ // 885,
+ // 884,
883,
- 882,
+ // 882,
881,
- // 880 NA
+ 880,
879,
878,
- 877,
- // 876 NA
- // 875 NA
- // 874 NA
- // 873 NA
- // 872 NA
- 871,
- 870,
- // 869 NA
- 868,
- // 867 NA
- // 866 NA
- // 865 NA
- // 864 NA
- // 863 NA
- // 862 NA
- // 861 NA
- // 860 NA
- 859,
+ // 877,
+ // 876,
+ 875,
+ // 874,
+ // 873,
+ // 872,
+ // 871,
+ // 870,
+ // 869,
+ // 868,
+ // 867,
+ 866,
+ 865,
+ // 864,
+ // 863,
+ 862,
+ 861,
+ // 860,
+ // 859,
858,
- 857,
- 856,
- // 855 NA
- // 854 NA
- 853,
- // 852 NA
- // 851 NA
- // 850 NA
- 849,
- 848,
+ // 857,
+ // 856,
+ // 855,
+ // 854,
+ // 853,
+ // 852,
+ 851,
+ // 850,
+ // 849,
+ // 848,
847,
- // 846 NA
- 845,
- 844,
- 843,
- // 842 NA
- // 841 NA
- // 840 NA
- // 839 NA
- // 838 NA
- // 837 NA
- 836,
+ // 846,
+ // 845,
+ // 844,
+ // 843,
+ // 842,
+ // 841,
+ // 840,
+ // 839,
+ // 838,
+ 837,
+ // 836,
835,
834,
- 833,
- 832,
+ // 833,
+ // 832,
831,
830,
- // 829 NA
+ // 829,
828,
- // 827 NA
- 826,
- 825,
- // 824 NA
- 823,
+ // 827,
+ // 826,
+ // 825,
+ // 824,
+ // 823,
822,
- // 821 NA
- 820,
- 819,
- 818,
- 817,
- 816,
- 815,
+ // 821,
+ // 820,
+ // 819,
+ // 818,
+ // 817,
+ // 816,
+ // 815,
814,
- 813,
- // 812 NA
+ // 813,
+ // 812,
811,
810,
809,
- // 808 NA
- 807,
+ 808,
+ // 807,
806,
805,
- // 804 NA
- 803,
- 802,
- 801,
- 800,
- 799,
- 798,
- // 797 NA
- // 796 NA
+ // 804,
+ // 803,
+ // 802,
+ // 801,
+ // 800,
+ // 799,
+ // 798,
+ // 797,
+ 796,
795,
- // 794 NA
- 793,
+ 794,
+ // 793,
792,
791,
790,
- 789,
- // 788 NA
- 787,
+ // 789,
+ // 788,
+ // 787,
786,
- 785,
- 784,
- // 783 NA
+ // 785,
+ // 784,
+ // 783,
782,
- 781,
+ // 781,
780,
- 779,
- 778,
- // 777 NA
- 776,
- 775,
+ // 779,
+ // 778,
+ // 777,
+ // 776,
+ // 775,
774,
773,
- // 772 NA
- 771,
- // 770 NA
- 769,
- 768,
- // 767 NA
- // 766 NA
+ 772,
+ // 771,
+ 770,
+ // 769,
+ // 768,
+ 767,
+ // 766,
765,
- 764,
- // 763 NA
- // 762 NA
- // 761 NA
- 760,
- // 759 NA
- 758,
- // 757 NA
- // 756 NA
- 755,
- 754,
- 753,
- // 752 NA
- // 751 NA
- // 750 NA
+ // 764,
+ 763,
+ 762,
+ // 761,
+ // 760,
+ // 759,
+ // 758,
+ 757,
+ 756,
+ // 755,
+ // 754,
+ // 753,
+ 752,
+ 751,
+ 750,
749,
- 748,
- 747,
- 746,
- 745,
- // 744 NA
- 743,
- 742,
+ // 748,
+ // 747,
+ // 746,
+ // 745,
+ // 744,
+ // 743,
+ // 742,
741,
- 740,
- 739,
- // 738 NA
+ // 740,
+ // 739,
+ // 738,
737,
736,
- // 735 NA
+ 735,
734,
- // 733 NA
- 732,
- // 731 NA
- // 730 NA
+ 733,
+ // 732,
+ 731,
+ // 730,
729,
- // 728 NA
- // 727 NA
- // 726 NA
- // 725 NA
- // 724 NA
+ // 728,
+ 727,
+ 726,
+ // 725,
+ 724,
723,
722,
721,
- // 720 NA
+ // 720,
719,
- 718,
- 717,
- 716,
- 715,
- 714,
- 713,
- 712,
+ // 718,
+ // 717,
+ // 716,
+ // 715,
+ // 714,
+ // 713,
+ // 712,
711,
710,
- 709,
+ // 709,
708,
707,
706,
- // 705 NA
+ // 705,
704,
- // 703 NA
- 702,
- // 701 NA
+ 703,
+ // 702,
+ 701,
700,
699,
- 698,
+ // 698,
697,
696,
695,
- 694,
- 693,
- // 692 NA
- // 691 NA
+ // 694,
+ // 693,
+ 692,
+ 691,
690,
689,
688,
- // 687 NA
+ 687,
686,
685,
- // 684 NA
- // 683 NA
+ 684,
+ // 683,
682,
- // 681 NA
+ // 681,
680,
- // 679 NA
- // 678 NA
- // 677 NA
- // 676 NA
+ 679,
+ 678,
+ 677,
+ 676,
675,
- // 674 NA
+ 674,
673,
672,
671,
670,
- // 669 NA
+ 669,
668,
667,
- // 666 NA
+ 666,
665,
- // 664 NA
- // 663 NA
+ 664,
+ 663,
662,
- // 661 NA
+ 661,
660,
659,
658,
- // 657 NA
+ 657,
656,
655,
654,
653,
- // 652 NA
+ 652,
651,
- // 650 NA
+ 650,
649,
- // 648 NA
- // 647 NA
- 646,
- 645,
- // 644 NA
- 643,
+ 648,
+ // 647,
+ // 646,
+ // 645,
+ // 644,
+ // 643,
642,
- // 641 NA
+ 641,
640,
639,
- // 638 NA
+ 638,
637,
636,
635,
634,
633,
- // 632 NA
+ 632,
631,
630,
- 629,
- // 628 NA
- // 627 NA
- // 626 NA
- // 625 NA
- // 624 NA
+ // 629,
+ 628,
+ 627,
+ 626,
+ 625,
+ 624,
623,
- // 622 NA
- // 621 NA
- // 620 NA
- // 619 NA
- // 618 NA
+ 622,
+ 621,
+ 620,
+ 619,
+ 618,
617,
616,
615,
614,
613,
612,
- // 611 NA
- // 610 NA
+ 611,
+ 610,
609,
608,
- // 607 NA
+ 607,
606,
605,
604,
@@ -1103,22 +1331,22 @@ static int included_patches[] = {
599,
598,
597,
- // 596 NA
+ 596,
595,
594,
593,
- // 592 NA
- // 591 NA
+ // 592,
+ 591,
590,
- // 589 NA
+ 589,
588,
587,
- // 586 NA
+ 586,
585,
- // 584 NA
- // 583 NA
+ 584,
+ 583,
582,
- // 581 NA
+ 581,
580,
579,
578,
@@ -1127,45 +1355,45 @@ static int included_patches[] = {
575,
574,
573,
- 572,
- // 571 NA
- // 570 NA
+ // 572,
+ 571,
+ 570,
569,
568,
567,
566,
565,
- // 564 NA
+ 564,
563,
562,
561,
- // 560 NA
+ 560,
559,
- // 558 NA
- // 557 NA
- // 556 NA
- // 555 NA
+ 558,
+ 557,
+ 556,
+ 555,
554,
553,
552,
551,
550,
549,
- // 548 NA
+ 548,
547,
546,
545,
- // 544 NA
+ 544,
543,
542,
541,
- // 540 NA
+ 540,
539,
538,
537,
536,
535,
- // 534 NA
+ 534,
533,
532,
531,
@@ -1176,8 +1404,8 @@ static int included_patches[] = {
526,
525,
524,
- // 523 NA
- // 522 NA
+ 523,
+ 522,
521,
520,
519,
@@ -1185,26 +1413,26 @@ static int included_patches[] = {
517,
516,
515,
- 514,
+ // 514,
513,
- // 512 NA
- // 511 NA
- // 510 NA
- // 509 NA
+ 512,
+ 511,
+ 510,
+ 509,
508,
- // 507 NA
- // 506 NA
- // 505 NA
- // 504 NA
+ 507,
+ // 506,
+ 505,
+ // 504,
503,
502,
- // 501 NA
+ 501,
500,
499,
- // 498 NA
+ 498,
497,
- // 496 NA
- // 495 NA
+ 496,
+ 495,
494,
493,
492,
@@ -1215,48 +1443,48 @@ static int included_patches[] = {
487,
486,
485,
- // 484 NA
+ 484,
483,
- // 482 NA
- // 481 NA
- // 480 NA
- // 479 NA
+ 482,
+ 481,
+ 480,
+ 479,
478,
477,
- // 476 NA
- // 475 NA
+ 476,
+ 475,
474,
473,
472,
- // 471 NA
+ 471,
470,
- // 469 NA
+ 469,
468,
467,
466,
- // 465 NA
- // 464 NA
+ 465,
+ 464,
463,
462,
- // 461 NA
- // 460 NA
- // 459 NA
+ 461,
+ 460,
+ 459,
458,
457,
456,
455,
454,
- // 453 NA
+ 453,
452,
- // 451 NA
+ 451,
450,
449,
- // 448 NA
+ 448,
447,
446,
445,
444,
- // 443 NA
+ 443,
442,
441,
440,
@@ -1267,46 +1495,46 @@ static int included_patches[] = {
435,
434,
433,
- // 432 NA
- // 431 NA
- // 430 NA
- // 429 NA
- // 428 NA
+ 432,
+ 431,
+ 430,
+ 429,
+ 428,
427,
- // 426 NA
+ 426,
425,
- // 424 NA
+ 424,
423,
422,
421,
- // 420 NA
+ 420,
419,
418,
417,
416,
415,
414,
- // 413 NA
- // 412 NA
- 411,
+ // 413,
+ // 412,
+ // 411,
410,
- // 409 NA
+ 409,
408,
407,
406,
405,
- // 404 NA
- // 403 NA
- // 402 NA
- // 401 NA
- // 400 NA
- // 399 NA
- // 398 NA
+ 404,
+ 403,
+ 402,
+ 401,
+ 400,
+ 399,
+ 398,
397,
- 396,
+ // 396,
395,
- // 394 NA
- // 393 NA
+ 394,
+ 393,
392,
391,
390,
@@ -1314,12 +1542,12 @@ static int included_patches[] = {
388,
387,
386,
- // 385 NA
- // 384 NA
+ 385,
+ 384,
383,
382,
381,
- // 380 NA
+ 380,
379,
378,
377,
@@ -1333,19 +1561,19 @@ static int included_patches[] = {
369,
368,
367,
- // 366 NA
+ 366,
365,
364,
- // 363 NA
+ 363,
362,
361,
360,
359,
358,
357,
- // 356 NA
+ 356,
355,
- // 354 NA
+ 354,
353,
352,
351,
@@ -1357,33 +1585,33 @@ static int included_patches[] = {
345,
344,
343,
- // 342 NA
+ 342,
341,
- // 340 NA
+ 340,
339,
338,
337,
336,
335,
334,
- // 333 NA
- // 332 NA
+ 333,
+ 332,
331,
330,
329,
328,
327,
- // 326 NA
+ 326,
325,
324,
323,
- // 322 NA
- // 321 NA
+ 322,
+ 321,
320,
- // 319 NA
+ 319,
318,
317,
- // 316 NA
+ 316,
315,
314,
313,
@@ -1392,18 +1620,18 @@ static int included_patches[] = {
310,
309,
308,
- // 307 NA
+ 307,
306,
305,
- // 304 NA
- 303,
+ 304,
+ // 303,
302,
301,
- // 300 NA
- // 299 NA
+ 300,
+ 299,
298,
297,
- 296,
+ // 296,
295,
294,
293,
@@ -1412,11 +1640,11 @@ static int included_patches[] = {
290,
289,
288,
- // 287 NA
+ 287,
286,
285,
284,
- // 283 NA
+ 283,
282,
281,
280,
@@ -1426,119 +1654,119 @@ static int included_patches[] = {
276,
275,
274,
- // 273 NA
+ 273,
272,
- // 271 NA
- // 270 NA
+ 271,
+ 270,
269,
268,
267,
266,
265,
264,
- // 263 NA
+ 263,
262,
261,
260,
- // 259 NA
- // 258 NA
- // 257 NA
+ 259,
+ 258,
+ 257,
256,
- // 255 NA
- // 254 NA
+ 255,
+ 254,
253,
- // 252 NA
+ 252,
251,
- // 250 NA
+ 250,
249,
248,
247,
- // 246 NA
+ 246,
245,
- // 244 NA
+ 244,
243,
242,
241,
240,
239,
- // 238 NA
+ // 238,
237,
236,
235,
234,
- 233,
+ // 233,
232,
- 231,
- 230,
+ // 231,
+ // 230,
229,
- // 228 NA
- // 227 NA
+ // 228,
+ 227,
226,
- // 225 NA
- // 224 NA
- // 223 NA
- // 222 NA
+ 225,
+ 224,
+ 223,
+ 222,
221,
220,
219,
218,
- // 217 NA
- // 216 NA
+ 217,
+ 216,
215,
- // 214 NA
+ 214,
213,
- // 212 NA
+ 212,
211,
- 210,
+ // 210,
209,
- // 208 NA
+ 208,
207,
- // 206 NA
+ 206,
205,
204,
203,
- // 202 NA
+ 202,
201,
- // 200 NA
+ 200,
199,
- // 198 NA
- // 197 NA
- // 196 NA
- // 195 NA
- // 194 NA
+ 198,
+ 197,
+ 196,
+ 195,
+ 194,
193,
192,
191,
- // 190 NA
- // 189 NA
- // 188 NA
+ 190,
+ 189,
+ 188,
187,
186,
- // 185 NA
+ 185,
184,
- // 183 NA
- // 182 NA
+ 183,
+ 182,
181,
- // 180 NA
- // 179 NA
+ 180,
+ 179,
178,
- // 177 NA
- // 176 NA
- // 175 NA
- // 174 NA
+ 177,
+ 176,
+ 175,
+ 174,
173,
172,
171,
170,
169,
- // 168 NA
+ 168,
167,
166,
165,
- // 164 NA
- // 163 NA
- // 162 NA
- // 161 NA
+ 164,
+ 163,
+ 162,
+ 161,
160,
159,
158,
@@ -1699,34 +1927,76 @@ static int included_patches[] = {
3,
2,
1,
- 0
+ 0,
};
// clang-format on
-/// Place to put a short description when adding a feature with a patch.
-/// Keep it short, e.g.,: "relative numbers", "persistent undo".
-/// Also add a comment marker to separate the lines.
-/// See the official Vim patches for the diff format: It must use a context of
-/// one line only. Create it by hand or use "diff -C2" and edit the patch.
-static char *(extra_patches[]) = {
- // Add your patch description below this line
- NULL
-};
+/// Compares a version string to the current Nvim version.
+///
+/// @param version Version string like "1.3.42"
+///
+/// @return true if Nvim is at or above the version.
+bool has_nvim_version(const char *const version_str)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ const char *p = version_str;
+ int major = 0;
+ int minor = 0;
+ int patch = 0;
-/// Checks whether patch `n` has been included.
+ if (!ascii_isdigit(*p)) {
+ return false;
+ }
+ major = atoi(p);
+ p = strchr(p, '.'); // Find the next dot.
+
+ if (p) {
+ p++; // Advance past the dot.
+ if (!ascii_isdigit(*p)) {
+ return false;
+ }
+ minor = atoi(p);
+ p = strchr(p, '.');
+ if (p) {
+ p++;
+ if (!ascii_isdigit(*p)) {
+ return false;
+ }
+ patch = atoi(p);
+ }
+ }
+
+ return (major < NVIM_VERSION_MAJOR
+ || (major == NVIM_VERSION_MAJOR
+ && (minor < NVIM_VERSION_MINOR
+ || (minor == NVIM_VERSION_MINOR
+ && patch <= NVIM_VERSION_PATCH))));
+}
+
+/// Checks whether a Vim patch has been included.
///
-/// @param n The patch number.
+/// @param n Patch number.
///
-/// @return TRUE if patch "n" has been included.
-int has_patch(int n)
+/// @return true if patch `n` has been included.
+bool has_vim_patch(int n)
{
- int i;
- for (i = 0; included_patches[i] != 0; ++i) {
+ for (int i = 0; included_patches[i] != 0; i++) {
if (included_patches[i] == n) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
+}
+
+Dictionary version_dict(void) {
+ Dictionary d = ARRAY_DICT_INIT;
+ PUT(d, "major", INTEGER_OBJ(NVIM_VERSION_MAJOR));
+ PUT(d, "minor", INTEGER_OBJ(NVIM_VERSION_MINOR));
+ PUT(d, "patch", INTEGER_OBJ(NVIM_VERSION_PATCH));
+ PUT(d, "api_level", INTEGER_OBJ(NVIM_API_LEVEL));
+ PUT(d, "api_compatible", INTEGER_OBJ(NVIM_API_LEVEL_COMPAT));
+ PUT(d, "api_prerelease", BOOLEAN_OBJ(NVIM_API_PRERELEASE));
+ return d;
}
void ex_version(exarg_T *eap)
@@ -1778,15 +2048,13 @@ static void list_features(void)
int idx = (i / ncol) + (i % ncol) * nrow;
if (idx < nfeat) {
int last_col = (i + 1) % ncol == 0;
- msg_puts((char_u *)features[idx]);
+ msg_puts(features[idx]);
if (last_col) {
if (msg_col > 0) {
msg_putchar('\n');
}
} else {
- while (msg_col % width) {
- msg_putchar(' ');
- }
+ msg_putchar(' ');
}
} else {
if (msg_col > 0) {
@@ -1794,30 +2062,27 @@ static void list_features(void)
}
}
}
- MSG_PUTS("For differences from Vim, see :help vim-differences\n\n");
+ MSG_PUTS("See \":help feature-compile\"\n\n");
+}
+
+void list_lua_version(void)
+{
+ typval_T luaver_tv;
+ typval_T arg = { .v_type = VAR_UNKNOWN }; // No args.
+ char *luaver_expr = "((jit and jit.version) and jit.version or _VERSION)";
+ executor_eval_lua(cstr_as_string(luaver_expr), &arg, &luaver_tv);
+ assert(luaver_tv.v_type == VAR_STRING);
+ MSG(luaver_tv.vval.v_string);
+ xfree(luaver_tv.vval.v_string);
}
void list_version(void)
{
- // When adding features here, don't forget to update the list of
- // internal variables in eval.c!
MSG(longVersion);
MSG(version_buildtype);
+ list_lua_version();
MSG(version_cflags);
- // Print the list of extra patch descriptions if there is at least one.
- char *s = "";
- if (extra_patches[0] != NULL) {
- MSG_PUTS(_("\nExtra patches: "));
- s = "";
-
- for (int i = 0; extra_patches[i] != NULL; ++i) {
- MSG_PUTS(s);
- s = ", ";
- MSG_PUTS(extra_patches[i]);
- }
- }
-
#ifdef HAVE_PATHDEF
if ((*compiled_user != NUL) || (*compiled_sys != NUL)) {
@@ -1835,7 +2100,7 @@ void list_version(void)
}
#endif // ifdef HAVE_PATHDEF
- version_msg(_("\n\nOptional features included (+) or not (-): "));
+ version_msg(_("\n\nFeatures: "));
list_features();
@@ -1858,6 +2123,8 @@ void list_version(void)
version_msg("\"\n");
}
#endif // ifdef HAVE_PATHDEF
+
+ version_msg("\nRun :checkhealth for more info");
}
/// Output a string for the version message. If it's going to wrap, output a
@@ -1884,7 +2151,7 @@ static void version_msg(char *s)
/// Show the intro message when not editing a file.
void maybe_intro_message(void)
{
- if (bufempty()
+ if (BUFEMPTY()
&& (curbuf->b_fname == NULL)
&& (firstwin->w_next == NULL)
&& (vim_strchr(p_shm, SHM_INTRO) == NULL)) {
@@ -1907,15 +2174,13 @@ void intro_message(int colon)
static char *(lines[]) = {
N_(NVIM_VERSION_LONG),
"",
- N_("by Bram Moolenaar et al."),
- N_("Vim is open source and freely distributable"),
- "",
- N_("Type \":Tutor\" or \":help nvim\" to get started!"),
- "",
- N_("Still have questions? https://neovim.io/community"),
+ N_("Nvim is open source and freely distributable"),
+ N_("https://neovim.io/#chat"),
"",
+ N_("type :help nvim<Enter> if you are new! "),
+ N_("type :checkhealth<Enter> to optimize Nvim"),
N_("type :q<Enter> to exit "),
- N_("type :help<Enter> or <F1> for on-line help"),
+ N_("type :help<Enter> for help "),
"",
N_("Help poor children in Uganda!"),
N_("type :help iccf<Enter> for information "),
@@ -2006,7 +2271,8 @@ static void do_intro_line(long row, char_u *mesg, int attr)
}
}
assert(row <= INT_MAX && col <= INT_MAX);
- screen_puts_len(p, l, (int)row, (int)col, *p == '<' ? hl_attr(HLF_8) : attr);
+ grid_puts_len(&default_grid, p, l, (int)row, (int)col,
+ *p == '<' ? HL_ATTR(HLF_8) : attr);
col += clen;
}
}
diff --git a/src/nvim/version.h b/src/nvim/version.h
index 1de809e539..c10f6fa534 100644
--- a/src/nvim/version.h
+++ b/src/nvim/version.h
@@ -1,6 +1,8 @@
#ifndef NVIM_VERSION_H
#define NVIM_VERSION_H
+#include "nvim/ex_cmds_defs.h"
+
// defined in version.c
extern char* Version;
extern char* longVersion;
@@ -8,14 +10,14 @@ extern char* longVersion;
//
// Vim version number, name, etc. Patchlevel is defined in version.c.
//
-#define VIM_VERSION_MAJOR 7
-#define VIM_VERSION_MINOR 4
+#define VIM_VERSION_MAJOR 8
+#define VIM_VERSION_MINOR 0
#define VIM_VERSION_100 (VIM_VERSION_MAJOR * 100 + VIM_VERSION_MINOR)
// used for the runtime directory name
-#define VIM_VERSION_NODOT "vim74"
+#define VIM_VERSION_NODOT "vim80"
// swap file compatibility (max. length is 6 chars)
-#define VIM_VERSION_SHORT "7.4"
+#define VIM_VERSION_SHORT "8.0"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "version.h.generated.h"
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index 09e9e850a7..767936ecee 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -4,40 +4,27 @@
#include "nvim/types.h"
#include "nvim/pos.h" // for linenr_T, MAXCOL, etc...
-/* Some defines from the old feature.h */
+// Some defines from the old feature.h
#define SESSION_FILE "Session.vim"
#define MAX_MSG_HIST_LEN 200
#define SYS_OPTWIN_FILE "$VIMRUNTIME/optwin.vim"
#define RUNTIME_DIRNAME "runtime"
-/* end */
-/* ============ the header file puzzle (ca. 50-100 pieces) ========= */
-#ifdef HAVE_CONFIG_H /* GNU autoconf (or something else) was here */
-# include "auto/config.h"
-# define HAVE_PATHDEF
+#include "auto/config.h"
+#define HAVE_PATHDEF
-/*
- * Check if configure correctly managed to find sizeof(int). If this failed,
- * it becomes zero. This is likely a problem of not being able to run the
- * test program. Other items from configure may also be wrong then!
- */
-# if (SIZEOF_INT == 0)
-Error: configure did not run properly.Check auto/config.log.
-# endif
+// Check if configure correctly managed to find sizeof(int). If this failed,
+// it becomes zero. This is likely a problem of not being able to run the
+// test program. Other items from configure may also be wrong then!
+#if (SIZEOF_INT == 0)
+# error Configure did not run properly.
#endif
-#include "nvim/os/os_defs.h" /* bring lots of system header files */
+#include "nvim/os/os_defs.h" // bring lots of system header files
/// length of a buffer to store a number in ASCII (64 bits binary + NUL)
-#define NUMBUFLEN 65
-
-// flags for vim_str2nr()
-#define STR2NR_BIN 1
-#define STR2NR_OCT 2
-#define STR2NR_HEX 4
-#define STR2NR_ALL (STR2NR_BIN + STR2NR_OCT + STR2NR_HEX)
-#define STR2NR_FORCE 8 // only when ONE of the above is used
+enum { NUMBUFLEN = 65 };
#define MAX_TYPENR 65535
@@ -46,86 +33,78 @@ Error: configure did not run properly.Check auto/config.log.
#include "nvim/keymap.h"
#include "nvim/macros.h"
+#include "nvim/gettext.h"
+// special attribute addition: Put message in history
+#define MSG_HIST 0x1000
-/* ================ end of the header file puzzle =============== */
+// values for State
+//
+// The lower bits up to 0x20 are used to distinguish normal/visual/op_pending
+// and cmdline/insert+replace mode. This is used for mapping. If none of
+// these bits are set, no mapping is done.
+// The upper bits are used to distinguish between other states.
-#ifdef HAVE_WORKING_LIBINTL
-# include <libintl.h>
-# define _(x) gettext((char *)(x))
-// XXX do we actually need this?
-# ifdef gettext_noop
-# define N_(x) gettext_noop(x)
-# else
-# define N_(x) x
-# endif
-#else
-# define _(x) ((char *)(x))
-# define N_(x) x
-# define bindtextdomain(x, y) /* empty */
-# define bind_textdomain_codeset(x, y) /* empty */
-# define textdomain(x) /* empty */
-#endif
+#define NORMAL 0x01 // Normal mode, command expected
+#define VISUAL 0x02 // Visual mode - use get_real_state()
+#define OP_PENDING 0x04 // Normal mode, operator is pending - use
+ // get_real_state()
+#define CMDLINE 0x08 // Editing command line
+#define INSERT 0x10 // Insert mode
+#define LANGMAP 0x20 // Language mapping, can be combined with
+ // INSERT and CMDLINE
-/* special attribute addition: Put message in history */
-#define MSG_HIST 0x1000
-
-/*
- * values for State
- *
- * The lower bits up to 0x20 are used to distinguish normal/visual/op_pending
- * and cmdline/insert+replace mode. This is used for mapping. If none of
- * these bits are set, no mapping is done.
- * The upper bits are used to distinguish between other states.
- */
-#define NORMAL 0x01 /* Normal mode, command expected */
-#define VISUAL 0x02 /* Visual mode - use get_real_state() */
-#define OP_PENDING 0x04 /* Normal mode, operator is pending - use
- get_real_state() */
-#define CMDLINE 0x08 /* Editing command line */
-#define INSERT 0x10 /* Insert mode */
-#define LANGMAP 0x20 /* Language mapping, can be combined with
- INSERT and CMDLINE */
-
-#define REPLACE_FLAG 0x40 /* Replace mode flag */
+#define REPLACE_FLAG 0x40 // Replace mode flag
#define REPLACE (REPLACE_FLAG + INSERT)
-# define VREPLACE_FLAG 0x80 /* Virtual-replace mode flag */
+# define VREPLACE_FLAG 0x80 // Virtual-replace mode flag
# define VREPLACE (REPLACE_FLAG + VREPLACE_FLAG + INSERT)
#define LREPLACE (REPLACE_FLAG + LANGMAP)
-#define NORMAL_BUSY (0x100 + NORMAL) /* Normal mode, busy with a command */
-#define HITRETURN (0x200 + NORMAL) /* waiting for return or command */
-#define ASKMORE 0x300 /* Asking if you want --more-- */
-#define SETWSIZE 0x400 /* window size has changed */
-#define ABBREV 0x500 /* abbreviation instead of mapping */
-#define EXTERNCMD 0x600 /* executing an external command */
-#define SHOWMATCH (0x700 + INSERT) /* show matching paren */
-#define CONFIRM 0x800 /* ":confirm" prompt */
-#define SELECTMODE 0x1000 /* Select mode, only for mappings */
+#define NORMAL_BUSY (0x100 + NORMAL) // Normal mode, busy with a command
+#define HITRETURN (0x200 + NORMAL) // waiting for return or command
+#define ASKMORE 0x300 // Asking if you want --more--
+#define SETWSIZE 0x400 // window size has changed
+#define ABBREV 0x500 // abbreviation instead of mapping
+#define EXTERNCMD 0x600 // executing an external command
+#define SHOWMATCH (0x700 + INSERT) // show matching paren
+#define CONFIRM 0x800 // ":confirm" prompt
+#define SELECTMODE 0x1000 // Select mode, only for mappings
#define TERM_FOCUS 0x2000 // Terminal focus mode
+#define CMDPREVIEW 0x4000 // Showing 'inccommand' command "live" preview.
// all mode bits used for mapping
#define MAP_ALL_MODES (0x3f | SELECTMODE | TERM_FOCUS)
-/* directions */
-#define FORWARD 1
-#define BACKWARD (-1)
-#define FORWARD_FILE 3
-#define BACKWARD_FILE (-3)
+/// Directions.
+typedef enum {
+ kDirectionNotSet = 0,
+ FORWARD = 1,
+ BACKWARD = (-1),
+ FORWARD_FILE = 3,
+ BACKWARD_FILE = (-3),
+} Direction;
-/* return values for functions */
+// return values for functions
#if !(defined(OK) && (OK == 1))
-/* OK already defined to 1 in MacOS X curses, skip this */
+// OK already defined to 1 in MacOS X curses, skip this
# define OK 1
#endif
#define FAIL 0
-#define NOTDONE 2 /* not OK or FAIL but skipped */
+#define NOTDONE 2 // not OK or FAIL but skipped
+
+// Type values for type().
+#define VAR_TYPE_NUMBER 0
+#define VAR_TYPE_STRING 1
+#define VAR_TYPE_FUNC 2
+#define VAR_TYPE_LIST 3
+#define VAR_TYPE_DICT 4
+#define VAR_TYPE_FLOAT 5
+#define VAR_TYPE_BOOL 6
+
+// values for xp_context when doing command line completion
-/*
- * values for xp_context when doing command line completion
- */
enum {
EXPAND_UNSUCCESSFUL = -2,
EXPAND_OK = -1,
@@ -175,60 +154,63 @@ enum {
EXPAND_SYNTIME,
EXPAND_USER_ADDR_TYPE,
EXPAND_PACKADD,
+ EXPAND_MESSAGES,
+ EXPAND_MAPCLEAR,
+ EXPAND_ARGLIST,
+ EXPAND_CHECKHEALTH,
};
+// Minimal size for block 0 of a swap file.
+// NOTE: This depends on size of struct block0! It's not done with a sizeof(),
+// because struct block0 is defined in memline.c (Sorry).
+// The maximal block size is arbitrary.
-/*
- * Minimal size for block 0 of a swap file.
- * NOTE: This depends on size of struct block0! It's not done with a sizeof(),
- * because struct block0 is defined in memline.c (Sorry).
- * The maximal block size is arbitrary.
- */
#define MIN_SWAP_PAGE_SIZE 1048
#define MAX_SWAP_PAGE_SIZE 50000
-/*
- * Boolean constants
- */
+// Boolean constants
+
#ifndef TRUE
-# define FALSE 0 /* note: this is an int, not a long! */
+# define FALSE 0 // note: this is an int, not a long!
# define TRUE 1
#endif
-#define MAYBE 2 /* sometimes used for a variant on TRUE */
+#define MAYBE 2 // sometimes used for a variant on TRUE
+
+#define STATUS_HEIGHT 1 // height of a status line under a window
+#define QF_WINHEIGHT 10 // default height for quickfix window
-#define STATUS_HEIGHT 1 /* height of a status line under a window */
-#define QF_WINHEIGHT 10 /* default height for quickfix window */
-/*
- * Buffer sizes
- */
+// Buffer sizes
+
#ifndef CMDBUFFSIZE
-# define CMDBUFFSIZE 256 /* size of the command processing buffer */
+# define CMDBUFFSIZE 256 // size of the command processing buffer
#endif
-#define LSIZE 512 /* max. size of a line in the tags file */
+#define LSIZE 512 // max. size of a line in the tags file
+
+#define DIALOG_MSG_SIZE 1000 // buffer size for dialog_msg()
+
+enum { FOLD_TEXT_LEN = 51 }; //!< buffer size for get_foldtext()
-#define DIALOG_MSG_SIZE 1000 /* buffer size for dialog_msg() */
-/*
- * Maximum length of key sequence to be mapped.
- * Must be able to hold an Amiga resize report.
- */
+// Maximum length of key sequence to be mapped.
+// Must be able to hold an Amiga resize report.
+
#define MAXMAPLEN 50
-/* Size in bytes of the hash used in the undo file. */
+// Size in bytes of the hash used in the undo file.
#define UNDO_HASH_SIZE 32
-/*
- * defines to avoid typecasts from (char_u *) to (char *) and back
- * (vim_strchr() and vim_strrchr() are now in alloc.c)
- */
+
+// defines to avoid typecasts from (char_u *) to (char *) and back
+// (vim_strchr() is now in strings.c)
+
#define STRLEN(s) strlen((char *)(s))
#define STRCPY(d, s) strcpy((char *)(d), (char *)(s))
#define STRNCPY(d, s, n) strncpy((char *)(d), (char *)(s), (size_t)(n))
@@ -245,7 +227,7 @@ enum {
# endif
#endif
-/* Like strcpy() but allows overlapped source and destination. */
+// Like strcpy() but allows overlapped source and destination.
#define STRMOVE(d, s) memmove((d), (s), STRLEN(s) + 1)
#ifdef HAVE_STRNCASECMP
@@ -258,8 +240,11 @@ enum {
# endif
#endif
+#define STRRCHR(s, c) (char_u *)strrchr((const char *)(s), (c))
+
#define STRCAT(d, s) strcat((char *)(d), (char *)(s))
#define STRNCAT(d, s, n) strncat((char *)(d), (char *)(s), (size_t)(n))
+#define STRLCAT(d, s, n) xstrlcat((char *)(d), (char *)(s), (size_t)(n))
# define vim_strpbrk(s, cs) (char_u *)strpbrk((char *)(s), (char *)(cs))
@@ -269,41 +254,47 @@ enum {
// destination and mess up the screen.
#define PERROR(msg) (void) emsgf("%s: %s", msg, strerror(errno))
-#define SHOWCMD_COLS 10 /* columns needed by shown command */
-#define STL_MAX_ITEM 80 /* max nr of %<flag> in statusline */
-
-/*
- * fnamecmp() is used to compare file names.
- * On some systems case in a file name does not matter, on others it does.
- * (this does not account for maximum name lengths and things like "../dir",
- * thus it is not 100% accurate!)
- */
-#define fnamecmp(x, y) vim_fnamecmp((char_u *)(x), (char_u *)(y))
-#define fnamencmp(x, y, n) vim_fnamencmp((char_u *)(x), (char_u *)(y), \
- (size_t)(n))
-
-/*
- * Enums need a typecast to be used as array index (for Ultrix).
- */
-#define hl_attr(n) highlight_attr[(int)(n)]
-#define term_str(n) term_strings[(int)(n)]
-
-/* Maximum number of bytes in a multi-byte character. It can be one 32-bit
- * character of up to 6 bytes, or one 16-bit character of up to three bytes
- * plus six following composing characters of three bytes each. */
+#define SHOWCMD_COLS 10 // columns needed by shown command
+#define STL_MAX_ITEM 80 // max nr of %<flag> in statusline
+
+/// Compare file names
+///
+/// On some systems case in a file name does not matter, on others it does.
+///
+/// @note Does not account for maximum name lengths and things like "../dir",
+/// thus it is not 100% accurate. OS may also use different algorythm for
+/// case-insensitive comparison.
+///
+/// @param[in] x First file name to compare.
+/// @param[in] y Second file name to compare.
+///
+/// @return 0 for equal file names, non-zero otherwise.
+#define fnamecmp(x, y) path_fnamecmp((const char *)(x), (const char *)(y))
+#define fnamencmp(x, y, n) path_fnamencmp((const char *)(x), \
+ (const char *)(y), \
+ (size_t)(n))
+
+
+// Enums need a typecast to be used as array index (for Ultrix).
+#define HL_ATTR(n) highlight_attr[(int)(n)]
+#define TERM_STR(n) term_strings[(int)(n)]
+
+/// Maximum number of bytes in a multi-byte character. It can be one 32-bit
+/// character of up to 6 bytes, or one 16-bit character of up to three bytes
+/// plus six following composing characters of three bytes each.
#define MB_MAXBYTES 21
-/* This has to go after the include of proto.h, as proto/gui.pro declares
- * functions of these names. The declarations would break if the defines had
- * been seen at that stage. But it must be before globals.h, where error_ga
- * is declared. */
+// This has to go after the include of proto.h, as proto/gui.pro declares
+// functions of these names. The declarations would break if the defines had
+// been seen at that stage. But it must be before globals.h, where error_ga
+// is declared.
#define mch_errmsg(str) fprintf(stderr, "%s", (str))
#define display_errors() fflush(stderr)
#define mch_msg(str) printf("%s", (str))
-#include "nvim/globals.h" /* global variables and messages */
-#include "nvim/buffer_defs.h" /* buffer and windows */
-#include "nvim/ex_cmds_defs.h" /* Ex command defines */
+#include "nvim/globals.h" // global variables and messages
+#include "nvim/buffer_defs.h" // buffer and windows
+#include "nvim/ex_cmds_defs.h" // Ex command defines
# define SET_NO_HLSEARCH(flag) no_hlsearch = (flag); set_vim_var_nr( \
VV_HLSEARCH, !no_hlsearch && p_hls)
@@ -315,5 +306,19 @@ enum {
#define DIP_START 0x08 // also use "start" directory in 'packpath'
#define DIP_OPT 0x10 // also use "opt" directory in 'packpath'
#define DIP_NORTP 0x20 // do not use 'runtimepath'
+#define DIP_NOAFTER 0x40 // skip "after" directories
+#define DIP_AFTER 0x80 // only use "after" directories
+
+// Lowest number used for window ID. Cannot have this many windows per tab.
+#define LOWEST_WIN_ID 1000
+
+// BSD is supposed to cover FreeBSD and similar systems.
+#if (defined(BSD) || defined(__FreeBSD_kernel__)) && defined(S_ISCHR)
+# define OPEN_CHR_FILES
+#endif
+
+// Replacement for nchar used by nv_replace().
+#define REPLACE_CR_NCHAR -1
+#define REPLACE_NL_NCHAR -2
-#endif /* NVIM_VIM_H */
+#endif // NVIM_VIM_H
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c
new file mode 100644
index 0000000000..dcc64db8a0
--- /dev/null
+++ b/src/nvim/viml/parser/expressions.c
@@ -0,0 +1,3095 @@
+// 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
+
+/// VimL expression parser
+
+// Planned incompatibilities (to be included into vim_diff.txt when this parser
+// will be an actual part of VimL evaluation process):
+//
+// 1. Expressions are first fully parsed and only then executed. This means
+// that while ":echo [system('touch abc')" will create file "abc" in Vim and
+// only then raise syntax error regarding missing comma in list in Neovim
+// trying to execute that will immediately raise syntax error regarding
+// missing list end without actually executing anything.
+// 2. Expressions are first fully parsed, without considering any runtime
+// information. This means things like that "d.a" does not change its
+// meaning depending on type of "d" (or whether Vim is currently executing or
+// skipping). For compatibility reasons the dot thus may either be “concat
+// or subscript†operator or just “concat†operator.
+// 3. Expressions parser is aware whether it is called for :echo or <C-r>=.
+// This means that while "<C-r>=1 | 2<CR>" is equivalent to "<C-r>=1<CR>"
+// because "| 2" part is left to be treated as a command separator and then
+// ignored in Neovim it is an error.
+// 4. Expressions parser has generally better error reporting. But for
+// compatibility reasons most errors have error code E15 while error messages
+// are significantly different from Vim’s E15. Also some error codes were
+// retired because of being harder to emulate or because of them being
+// a result of differences in parsing process: e.g. with ":echo {a, b}" Vim
+// will attempt to parse expression as lambda, fail, check whether it is
+// a curly-braces-name, fail again, and evaluate that as a dictionary, giving
+// error regarding undefined variable "a" (or about missing colon). Neovim
+// will not try to evaluate anything here: comma right after an argument name
+// means that expression may not be anything, but lambda, so the resulting
+// error message will never be about missing variable or colon: it will be
+// about missing arrow (or a continuation of argument list).
+// 5. Failing to parse expression always gives exactly one error message: no
+// more stack of error messages like >
+//
+// :echo [1,
+// E697: Missing end of List ']':
+// E15: Invalid expression: [1,
+//
+// < , just exactly one E697 message.
+// 6. Some expressions involving calling parenthesis which are treated
+// separately by Vim even when not separated by spaces are treated as one
+// expression by Neovim: e.g. ":echo (1)(1)" will yield runtime error after
+// failing to call "1", while Vim will echo "1 1". Reasoning is the same:
+// type of what is in the first expression is generally not known when
+// parsing, so to have separate expressions like this separate them with
+// spaces.
+// 7. 'isident' no longer applies to environment variables, they always include
+// ASCII alphanumeric characters and underscore and nothing except this.
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <assert.h>
+#include <string.h>
+
+#include "nvim/vim.h"
+#include "nvim/memory.h"
+#include "nvim/types.h"
+#include "nvim/charset.h"
+#include "nvim/ascii.h"
+#include "nvim/assert.h"
+#include "nvim/lib/kvec.h"
+#include "nvim/eval/typval.h"
+
+#include "nvim/viml/parser/expressions.h"
+#include "nvim/viml/parser/parser.h"
+
+#define vim_str2nr(s, ...) vim_str2nr((const char_u *)(s), __VA_ARGS__)
+
+typedef kvec_withinit_t(ExprASTNode **, 16) ExprASTStack;
+
+/// Which nodes may be wanted
+typedef enum {
+ /// Operators: function call, subscripts, binary operators, …
+ ///
+ /// For unrestricted expressions.
+ kENodeOperator,
+ /// Values: literals, variables, nested expressions, unary operators.
+ ///
+ /// For unrestricted expressions as well, implies that top item in AST stack
+ /// points to NULL.
+ kENodeValue,
+} ExprASTWantedNode;
+
+/// Parse type: what is being parsed currently
+typedef enum {
+ /// Parsing regular VimL expression
+ kEPTExpr = 0,
+ /// Parsing lambda arguments
+ ///
+ /// Just like parsing function arguments, but it is valid to be ended with an
+ /// arrow only.
+ kEPTLambdaArguments,
+ /// Assignment: parsing for :let
+ kEPTAssignment,
+ /// Single assignment: used when lists are not allowed (i.e. when nesting)
+ kEPTSingleAssignment,
+} ExprASTParseType;
+
+typedef kvec_withinit_t(ExprASTParseType, 4) ExprASTParseTypeStack;
+
+/// Operator priority level
+typedef enum {
+ kEOpLvlInvalid = 0,
+ kEOpLvlComplexIdentifier,
+ kEOpLvlParens,
+ kEOpLvlAssignment,
+ kEOpLvlArrow,
+ kEOpLvlComma,
+ kEOpLvlColon,
+ kEOpLvlTernaryValue,
+ kEOpLvlTernary,
+ kEOpLvlOr,
+ kEOpLvlAnd,
+ kEOpLvlComparison,
+ kEOpLvlAddition, ///< Addition, subtraction and concatenation.
+ kEOpLvlMultiplication, ///< Multiplication, division and modulo.
+ kEOpLvlUnary, ///< Unary operations: not, minus, plus.
+ kEOpLvlSubscript, ///< Subscripts.
+ kEOpLvlValue, ///< Values: literals, variables, nested expressions, …
+} ExprOpLvl;
+
+/// Operator associativity
+typedef enum {
+ kEOpAssNo= 'n', ///< Not associative / not applicable.
+ kEOpAssLeft = 'l', ///< Left associativity.
+ kEOpAssRight = 'r', ///< Right associativity.
+} ExprOpAssociativity;
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "viml/parser/expressions.c.generated.h"
+#endif
+
+/// Character used as a separator in autoload function/variable names.
+#define AUTOLOAD_CHAR '#'
+
+/// Scale number by a given factor
+///
+/// Used to apply exponent to a number. Idea taken from uClibc.
+///
+/// @param[in] num Number to scale. Does not bother doing anything if it is
+/// zero.
+/// @param[in] base Base, should be 10 since non-decimal floating-point
+/// numbers are not supported.
+/// @param[in] exponent Exponent to scale by.
+/// @param[in] exponent_negative True if exponent is negative.
+static inline float_T scale_number(const float_T num,
+ const uint8_t base,
+ const uvarnumber_T exponent,
+ const bool exponent_negative)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST
+{
+ if (num == 0 || exponent == 0) {
+ return num;
+ }
+ assert(base);
+ uvarnumber_T exp = exponent;
+ float_T p_base = (float_T)base;
+ float_T ret = num;
+ while (exp) {
+ if (exp & 1) {
+ if (exponent_negative) {
+ ret /= p_base;
+ } else {
+ ret *= p_base;
+ }
+ }
+ exp >>= 1;
+ p_base *= p_base;
+ }
+ return ret;
+}
+
+/// Get next token for the VimL expression input
+///
+/// @param pstate Parser state.
+/// @param[in] flags Flags, @see LexExprFlags.
+///
+/// @return Next token.
+LexExprToken viml_pexpr_next_token(ParserState *const pstate, const int flags)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ LexExprToken ret = {
+ .type = kExprLexInvalid,
+ .start = pstate->pos,
+ };
+ ParserLine pline;
+ if (!viml_parser_get_remaining_line(pstate, &pline)) {
+ ret.type = kExprLexEOC;
+ return ret;
+ }
+ if (pline.size <= 0) {
+ ret.len = 0;
+ ret.type = kExprLexEOC;
+ goto viml_pexpr_next_token_adv_return;
+ }
+ ret.len = 1;
+ const uint8_t schar = (uint8_t)pline.data[0];
+#define GET_CCS(ret, pline) \
+ do { \
+ if (ret.len < pline.size \
+ && strchr("?#", pline.data[ret.len]) != NULL) { \
+ ret.data.cmp.ccs = \
+ (ExprCaseCompareStrategy)pline.data[ret.len]; \
+ ret.len++; \
+ } else { \
+ ret.data.cmp.ccs = kCCStrategyUseOption; \
+ } \
+ } while (0)
+ switch (schar) {
+ // Paired brackets.
+#define BRACKET(typ, opning, clsing) \
+ case opning: \
+ case clsing: { \
+ ret.type = typ; \
+ ret.data.brc.closing = (schar == clsing); \
+ break; \
+ }
+ BRACKET(kExprLexParenthesis, '(', ')')
+ BRACKET(kExprLexBracket, '[', ']')
+ BRACKET(kExprLexFigureBrace, '{', '}')
+#undef BRACKET
+
+ // Single character tokens without data.
+#define CHAR(typ, ch) \
+ case ch: { \
+ ret.type = typ; \
+ break; \
+ }
+ CHAR(kExprLexQuestion, '?')
+ CHAR(kExprLexColon, ':')
+ CHAR(kExprLexComma, ',')
+#undef CHAR
+
+ // Multiplication/division/modulo.
+#define MUL(mul_type, ch) \
+ case ch: { \
+ ret.type = kExprLexMultiplication; \
+ ret.data.mul.type = mul_type; \
+ break; \
+ }
+ MUL(kExprLexMulMul, '*')
+ MUL(kExprLexMulDiv, '/')
+ MUL(kExprLexMulMod, '%')
+#undef MUL
+
+#define CHARREG(typ, cond) \
+ do { \
+ ret.type = typ; \
+ for (; (ret.len < pline.size \
+ && cond(pline.data[ret.len])) \
+ ; ret.len++) { \
+ } \
+ } while (0)
+
+ // Whitespace.
+ case ' ':
+ case TAB: {
+ CHARREG(kExprLexSpacing, ascii_iswhite);
+ break;
+ }
+
+ // Control character, except for NUL, NL and TAB.
+ case Ctrl_A: case Ctrl_B: case Ctrl_C: case Ctrl_D: case Ctrl_E:
+ case Ctrl_F: case Ctrl_G: case Ctrl_H:
+
+ case Ctrl_K: case Ctrl_L: case Ctrl_M: case Ctrl_N: case Ctrl_O:
+ case Ctrl_P: case Ctrl_Q: case Ctrl_R: case Ctrl_S: case Ctrl_T:
+ case Ctrl_U: case Ctrl_V: case Ctrl_W: case Ctrl_X: case Ctrl_Y:
+ case Ctrl_Z: {
+#define ISCTRL(schar) (schar < ' ')
+ CHARREG(kExprLexInvalid, ISCTRL);
+ ret.data.err.type = kExprLexSpacing;
+ ret.data.err.msg =
+ _("E15: Invalid control character present in input: %.*s");
+ break;
+#undef ISCTRL
+ }
+
+ // Number.
+ case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+ case '7': case '8': case '9': {
+ ret.data.num.is_float = false;
+ ret.data.num.base = 10;
+ size_t frac_start = 0;
+ size_t exp_start = 0;
+ size_t frac_end = 0;
+ bool exp_negative = false;
+ CHARREG(kExprLexNumber, ascii_isdigit);
+ if (flags & kELFlagAllowFloat) {
+ const LexExprToken non_float_ret = ret;
+ if (pline.size > ret.len + 1
+ && pline.data[ret.len] == '.'
+ && ascii_isdigit(pline.data[ret.len + 1])) {
+ ret.len++;
+ frac_start = ret.len;
+ frac_end = ret.len;
+ ret.data.num.is_float = true;
+ for (; ret.len < pline.size && ascii_isdigit(pline.data[ret.len])
+ ; ret.len++) {
+ // A small optimization: trailing zeroes in fractional part do not
+ // add anything to significand, so it is useless to include them in
+ // frac_end.
+ if (pline.data[ret.len] != '0') {
+ frac_end = ret.len + 1;
+ }
+ }
+ if (pline.size > ret.len + 1
+ && (pline.data[ret.len] == 'e'
+ || pline.data[ret.len] == 'E')
+ && ((pline.size > ret.len + 2
+ && (pline.data[ret.len + 1] == '+'
+ || pline.data[ret.len + 1] == '-')
+ && ascii_isdigit(pline.data[ret.len + 2]))
+ || ascii_isdigit(pline.data[ret.len + 1]))) {
+ ret.len++;
+ if (pline.data[ret.len] == '+'
+ || (exp_negative = (pline.data[ret.len] == '-'))) {
+ ret.len++;
+ }
+ exp_start = ret.len;
+ CHARREG(kExprLexNumber, ascii_isdigit);
+ }
+ }
+ if (pline.size > ret.len
+ && (pline.data[ret.len] == '.'
+ || ASCII_ISALPHA(pline.data[ret.len]))) {
+ ret = non_float_ret;
+ }
+ }
+ // TODO(ZyX-I): detect overflows
+ if (ret.data.num.is_float) {
+ // Vim used to use string2float here which in turn uses strtod(). There
+ // are two problems with this approach:
+ // 1. strtod() is locale-dependent. Not sure how it is worked around so
+ // that I do not see relevant bugs, but it still does not look like
+ // a good idea.
+ // 2. strtod() does not accept length argument.
+ //
+ // The below variant of parsing floats was recognized as acceptable
+ // because it is basically how uClibc does the thing: it generates
+ // a number ignoring decimal point (but recording its position), then
+ // uses recorded position to scale number down when processing exponent.
+ float_T significand_part = 0;
+ uvarnumber_T exp_part = 0;
+ const size_t frac_size = (size_t)(frac_end - frac_start);
+ for (size_t i = 0; i < frac_end; i++) {
+ if (i == frac_start - 1) {
+ continue;
+ }
+ significand_part = significand_part * 10 + (pline.data[i] - '0');
+ }
+ if (exp_start) {
+ vim_str2nr(pline.data + exp_start, NULL, NULL, 0, NULL, &exp_part,
+ (int)(ret.len - exp_start));
+ }
+ if (exp_negative) {
+ exp_part += frac_size;
+ } else {
+ if (exp_part < frac_size) {
+ exp_negative = true;
+ exp_part = frac_size - exp_part;
+ } else {
+ exp_part -= frac_size;
+ }
+ }
+ ret.data.num.val.floating = scale_number(significand_part, 10, exp_part,
+ exp_negative);
+ } else {
+ int len;
+ int prep;
+ vim_str2nr(pline.data, &prep, &len, STR2NR_ALL, NULL,
+ &ret.data.num.val.integer, (int)pline.size);
+ ret.len = (size_t)len;
+ const uint8_t bases[] = {
+ [0] = 10,
+ ['0'] = 8,
+ ['x'] = 16, ['X'] = 16,
+ ['b'] = 2, ['B'] = 2,
+ };
+ ret.data.num.base = bases[prep];
+ }
+ break;
+ }
+
+#define ISWORD_OR_AUTOLOAD(x) \
+ (ascii_isident(x) || (x) == AUTOLOAD_CHAR)
+
+ // Environment variable.
+ case '$': {
+ CHARREG(kExprLexEnv, ascii_isident);
+ break;
+ }
+
+ // Normal variable/function name.
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+ case 'v': case 'w': case 'x': case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+ case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+ case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+ case 'V': case 'W': case 'X': case 'Y': case 'Z':
+ case '_': {
+ ret.data.var.scope = 0;
+ ret.data.var.autoload = false;
+ CHARREG(kExprLexPlainIdentifier, ascii_isident);
+ // "is" and "isnot" operators.
+ if (!(flags & kELFlagIsNotCmp)
+ && ((ret.len == 2 && memcmp(pline.data, "is", 2) == 0)
+ || (ret.len == 5 && memcmp(pline.data, "isnot", 5) == 0))) {
+ ret.type = kExprLexComparison;
+ ret.data.cmp.type = kExprCmpIdentical;
+ ret.data.cmp.inv = (ret.len == 5);
+ GET_CCS(ret, pline);
+ // Scope: `s:`, etc.
+ } else if (ret.len == 1
+ && pline.size > 1
+ && memchr(EXPR_VAR_SCOPE_LIST, schar,
+ sizeof(EXPR_VAR_SCOPE_LIST)) != NULL
+ && pline.data[ret.len] == ':'
+ && !(flags & kELFlagForbidScope)) {
+ ret.len++;
+ ret.data.var.scope = (ExprVarScope)schar;
+ CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
+ ret.data.var.autoload = (
+ memchr(pline.data + 2, AUTOLOAD_CHAR, ret.len - 2)
+ != NULL);
+ // Previous CHARREG stopped at autoload character in order to make it
+ // possible to detect `is#`. Continue now with autoload characters
+ // included.
+ //
+ // Warning: there is ambiguity for the lexer: `is#Foo(1)` is a call of
+ // function `is#Foo()`, `1is#Foo(1)` is a comparison `1 is# Foo(1)`. This
+ // needs to be resolved on the higher level where context is available.
+ } else if (pline.size > ret.len
+ && pline.data[ret.len] == AUTOLOAD_CHAR) {
+ ret.data.var.autoload = true;
+ CHARREG(kExprLexPlainIdentifier, ISWORD_OR_AUTOLOAD);
+ }
+ break;
+ }
+
+#undef ISWORD_OR_AUTOLOAD
+#undef CHARREG
+
+ // Option.
+ case '&': {
+#define OPTNAMEMISS(ret) \
+ do { \
+ ret.type = kExprLexInvalid; \
+ ret.data.err.type = kExprLexOption; \
+ ret.data.err.msg = _("E112: Option name missing: %.*s"); \
+ } while (0)
+ if (pline.size > 1 && pline.data[1] == '&') {
+ ret.type = kExprLexAnd;
+ ret.len++;
+ break;
+ }
+ if (pline.size == 1 || !ASCII_ISALPHA(pline.data[1])) {
+ OPTNAMEMISS(ret);
+ break;
+ }
+ ret.type = kExprLexOption;
+ if (pline.size > 2
+ && pline.data[2] == ':'
+ && memchr(EXPR_OPT_SCOPE_LIST, pline.data[1],
+ sizeof(EXPR_OPT_SCOPE_LIST)) != NULL) {
+ ret.len += 2;
+ ret.data.opt.scope = (ExprOptScope)pline.data[1];
+ ret.data.opt.name = pline.data + 3;
+ } else {
+ ret.data.opt.scope = kExprOptScopeUnspecified;
+ ret.data.opt.name = pline.data + 1;
+ }
+ const char *p = ret.data.opt.name;
+ const char *const e = pline.data + pline.size;
+ if (e - p >= 4 && p[0] == 't' && p[1] == '_') {
+ ret.data.opt.len = 4;
+ ret.len += 4;
+ } else {
+ for (; p < e && ASCII_ISALPHA(*p); p++) {
+ }
+ ret.data.opt.len = (size_t)(p - ret.data.opt.name);
+ if (ret.data.opt.len == 0) {
+ OPTNAMEMISS(ret);
+ } else {
+ ret.len += ret.data.opt.len;
+ }
+ }
+ break;
+#undef OPTNAMEMISS
+ }
+
+ // Register.
+ case '@': {
+ ret.type = kExprLexRegister;
+ if (pline.size > 1) {
+ ret.len++;
+ ret.data.reg.name = (uint8_t)pline.data[1];
+ } else {
+ ret.data.reg.name = -1;
+ }
+ break;
+ }
+
+ // Single quoted string.
+ case '\'': {
+ ret.type = kExprLexSingleQuotedString;
+ ret.data.str.closed = false;
+ for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
+ if (pline.data[ret.len] == '\'') {
+ if (ret.len + 1 < pline.size && pline.data[ret.len + 1] == '\'') {
+ ret.len++;
+ } else {
+ ret.data.str.closed = true;
+ }
+ }
+ }
+ break;
+ }
+
+ // Double quoted string.
+ case '"': {
+ ret.type = kExprLexDoubleQuotedString;
+ ret.data.str.closed = false;
+ for (; ret.len < pline.size && !ret.data.str.closed; ret.len++) {
+ if (pline.data[ret.len] == '\\') {
+ if (ret.len + 1 < pline.size) {
+ ret.len++;
+ }
+ } else if (pline.data[ret.len] == '"') {
+ ret.data.str.closed = true;
+ }
+ }
+ break;
+ }
+
+ // Unary not, (un)equality and regex (not) match comparison operators.
+ case '!':
+ case '=': {
+ if (pline.size == 1) {
+ ret.type = (schar == '!' ? kExprLexNot : kExprLexAssignment);
+ ret.data.ass.type = kExprAsgnPlain;
+ break;
+ }
+ ret.type = kExprLexComparison;
+ ret.data.cmp.inv = (schar == '!');
+ if (pline.data[1] == '=') {
+ ret.data.cmp.type = kExprCmpEqual;
+ ret.len++;
+ } else if (pline.data[1] == '~') {
+ ret.data.cmp.type = kExprCmpMatches;
+ ret.len++;
+ } else if (schar == '!') {
+ ret.type = kExprLexNot;
+ } else {
+ ret.type = kExprLexAssignment;
+ ret.data.ass.type = kExprAsgnPlain;
+ }
+ GET_CCS(ret, pline);
+ break;
+ }
+
+ // Less/greater [or equal to] comparison operators.
+ case '>':
+ case '<': {
+ ret.type = kExprLexComparison;
+ const bool haseqsign = (pline.size > 1 && pline.data[1] == '=');
+ if (haseqsign) {
+ ret.len++;
+ }
+ GET_CCS(ret, pline);
+ ret.data.cmp.inv = (schar == '<');
+ ret.data.cmp.type = ((ret.data.cmp.inv ^ haseqsign)
+ ? kExprCmpGreaterOrEqual
+ : kExprCmpGreater);
+ break;
+ }
+
+ // Minus sign, arrow from lambdas or augmented assignment.
+ case '-': {
+ if (pline.size > 1 && pline.data[1] == '>') {
+ ret.len++;
+ ret.type = kExprLexArrow;
+ } else if (pline.size > 1 && pline.data[1] == '=') {
+ ret.len++;
+ ret.type = kExprLexAssignment;
+ ret.data.ass.type = kExprAsgnSubtract;
+ } else {
+ ret.type = kExprLexMinus;
+ }
+ break;
+ }
+
+ // Sign or augmented assignment.
+#define CHAR_OR_ASSIGN(ch, ch_type, ass_type) \
+ case ch: { \
+ if (pline.size > 1 && pline.data[1] == '=') { \
+ ret.len++; \
+ ret.type = kExprLexAssignment; \
+ ret.data.ass.type = ass_type; \
+ } else { \
+ ret.type = ch_type; \
+ } \
+ break; \
+ }
+ CHAR_OR_ASSIGN('+', kExprLexPlus, kExprAsgnAdd)
+ CHAR_OR_ASSIGN('.', kExprLexDot, kExprAsgnConcat)
+#undef CHAR_OR_ASSIGN
+
+ // Expression end because Ex command ended.
+ case NUL:
+ case NL: {
+ if (flags & kELFlagForbidEOC) {
+ ret.type = kExprLexInvalid;
+ ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
+ ret.data.err.type = kExprLexSpacing;
+ } else {
+ ret.type = kExprLexEOC;
+ }
+ break;
+ }
+
+ case '|': {
+ if (pline.size >= 2 && pline.data[ret.len] == '|') {
+ // "||" is or.
+ ret.len++;
+ ret.type = kExprLexOr;
+ } else if (flags & kELFlagForbidEOC) {
+ // Note: `<C-r>=1 | 2<CR>` actually yields 1 in Vim without any
+ // errors. This will be changed here.
+ ret.type = kExprLexInvalid;
+ ret.data.err.msg = _("E15: Unexpected EOC character: %.*s");
+ ret.data.err.type = kExprLexOr;
+ } else {
+ ret.type = kExprLexEOC;
+ }
+ break;
+ }
+
+ // Everything else is not valid.
+ default: {
+ ret.len = (size_t)utfc_ptr2len_len((const char_u *)pline.data,
+ (int)pline.size);
+ ret.type = kExprLexInvalid;
+ ret.data.err.type = kExprLexPlainIdentifier;
+ ret.data.err.msg = _("E15: Unidentified character: %.*s");
+ break;
+ }
+ }
+#undef GET_CCS
+viml_pexpr_next_token_adv_return:
+ if (!(flags & kELFlagPeek)) {
+ viml_parser_advance(pstate, ret.len);
+ }
+ return ret;
+}
+
+static const char *const eltkn_type_tab[] = {
+ [kExprLexInvalid] = "Invalid",
+ [kExprLexMissing] = "Missing",
+ [kExprLexSpacing] = "Spacing",
+ [kExprLexEOC] = "EOC",
+
+ [kExprLexQuestion] = "Question",
+ [kExprLexColon] = "Colon",
+ [kExprLexOr] = "Or",
+ [kExprLexAnd] = "And",
+ [kExprLexComparison] = "Comparison",
+ [kExprLexPlus] = "Plus",
+ [kExprLexMinus] = "Minus",
+ [kExprLexDot] = "Dot",
+ [kExprLexMultiplication] = "Multiplication",
+
+ [kExprLexNot] = "Not",
+
+ [kExprLexNumber] = "Number",
+ [kExprLexSingleQuotedString] = "SingleQuotedString",
+ [kExprLexDoubleQuotedString] = "DoubleQuotedString",
+ [kExprLexOption] = "Option",
+ [kExprLexRegister] = "Register",
+ [kExprLexEnv] = "Env",
+ [kExprLexPlainIdentifier] = "PlainIdentifier",
+
+ [kExprLexBracket] = "Bracket",
+ [kExprLexFigureBrace] = "FigureBrace",
+ [kExprLexParenthesis] = "Parenthesis",
+ [kExprLexComma] = "Comma",
+ [kExprLexArrow] = "Arrow",
+ [kExprLexAssignment] = "Assignment",
+};
+
+const char *const eltkn_cmp_type_tab[] = {
+ [kExprCmpEqual] = "Equal",
+ [kExprCmpMatches] = "Matches",
+ [kExprCmpGreater] = "Greater",
+ [kExprCmpGreaterOrEqual] = "GreaterOrEqual",
+ [kExprCmpIdentical] = "Identical",
+};
+
+const char *const expr_asgn_type_tab[] = {
+ [kExprAsgnPlain] = "Plain",
+ [kExprAsgnAdd] = "Add",
+ [kExprAsgnSubtract] = "Subtract",
+ [kExprAsgnConcat] = "Concat",
+};
+
+const char *const ccs_tab[] = {
+ [kCCStrategyUseOption] = "UseOption",
+ [kCCStrategyMatchCase] = "MatchCase",
+ [kCCStrategyIgnoreCase] = "IgnoreCase",
+};
+
+static const char *const eltkn_mul_type_tab[] = {
+ [kExprLexMulMul] = "Mul",
+ [kExprLexMulDiv] = "Div",
+ [kExprLexMulMod] = "Mod",
+};
+
+static const char *const eltkn_opt_scope_tab[] = {
+ [kExprOptScopeUnspecified] = "Unspecified",
+ [kExprOptScopeGlobal] = "Global",
+ [kExprOptScopeLocal] = "Local",
+};
+
+/// Represent token as a string
+///
+/// Intended for testing and debugging purposes.
+///
+/// @param[in] pstate Parser state, needed to get token string from it. May be
+/// NULL, in which case in place of obtaining part of the
+/// string represented by token only token length is
+/// returned.
+/// @param[in] token Token to represent.
+/// @param[out] ret_size Return string size, for cases like NULs inside
+/// a string. May be NULL.
+///
+/// @return Token represented in a string form, in a static buffer (overwritten
+/// on each call).
+const char *viml_pexpr_repr_token(const ParserState *const pstate,
+ const LexExprToken token,
+ size_t *const ret_size)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static char ret[1024];
+ char *p = ret;
+ const char *const e = &ret[1024] - 1;
+#define ADDSTR(...) \
+ do { \
+ p += snprintf(p, (size_t)(sizeof(ret) - (size_t)(p - ret)), __VA_ARGS__); \
+ if (p >= e) { \
+ goto viml_pexpr_repr_token_end; \
+ } \
+ } while (0)
+ ADDSTR("%zu:%zu:%s", token.start.line, token.start.col,
+ eltkn_type_tab[token.type]);
+ switch (token.type) {
+#define TKNARGS(tkn_type, ...) \
+ case tkn_type: { \
+ ADDSTR(__VA_ARGS__); \
+ break; \
+ }
+ TKNARGS(kExprLexComparison, "(type=%s,ccs=%s,inv=%i)",
+ eltkn_cmp_type_tab[token.data.cmp.type],
+ ccs_tab[token.data.cmp.ccs],
+ (int)token.data.cmp.inv)
+ TKNARGS(kExprLexMultiplication, "(type=%s)",
+ eltkn_mul_type_tab[token.data.mul.type])
+ TKNARGS(kExprLexAssignment, "(type=%s)",
+ expr_asgn_type_tab[token.data.ass.type])
+ TKNARGS(kExprLexRegister, "(name=%s)", intchar2str(token.data.reg.name))
+ case kExprLexDoubleQuotedString:
+ TKNARGS(kExprLexSingleQuotedString, "(closed=%i)",
+ (int)token.data.str.closed)
+ TKNARGS(kExprLexOption, "(scope=%s,name=%.*s)",
+ eltkn_opt_scope_tab[token.data.opt.scope],
+ (int)token.data.opt.len, token.data.opt.name)
+ TKNARGS(kExprLexPlainIdentifier, "(scope=%s,autoload=%i)",
+ intchar2str((int)token.data.var.scope),
+ (int)token.data.var.autoload)
+ TKNARGS(kExprLexNumber, "(is_float=%i,base=%i,val=%lg)",
+ (int)token.data.num.is_float,
+ (int)token.data.num.base,
+ (double)(token.data.num.is_float
+ ? (double)token.data.num.val.floating
+ : (double)token.data.num.val.integer))
+ TKNARGS(kExprLexInvalid, "(msg=%s)", token.data.err.msg)
+ default: {
+ // No additional arguments.
+ break;
+ }
+#undef TKNARGS
+ }
+ if (pstate == NULL) {
+ ADDSTR("::%zu", token.len);
+ } else {
+ *p++ = ':';
+ memmove(
+ p, &pstate->reader.lines.items[token.start.line].data[token.start.col],
+ token.len);
+ p += token.len;
+ *p = NUL;
+ }
+#undef ADDSTR
+viml_pexpr_repr_token_end:
+ if (ret_size != NULL) {
+ *ret_size = (size_t)(p - ret);
+ }
+ return ret;
+}
+
+const char *const east_node_type_tab[] = {
+ [kExprNodeMissing] = "Missing",
+ [kExprNodeOpMissing] = "OpMissing",
+ [kExprNodeTernary] = "Ternary",
+ [kExprNodeTernaryValue] = "TernaryValue",
+ [kExprNodeRegister] = "Register",
+ [kExprNodeSubscript] = "Subscript",
+ [kExprNodeListLiteral] = "ListLiteral",
+ [kExprNodeUnaryPlus] = "UnaryPlus",
+ [kExprNodeBinaryPlus] = "BinaryPlus",
+ [kExprNodeNested] = "Nested",
+ [kExprNodeCall] = "Call",
+ [kExprNodePlainIdentifier] = "PlainIdentifier",
+ [kExprNodePlainKey] = "PlainKey",
+ [kExprNodeComplexIdentifier] = "ComplexIdentifier",
+ [kExprNodeUnknownFigure] = "UnknownFigure",
+ [kExprNodeLambda] = "Lambda",
+ [kExprNodeDictLiteral] = "DictLiteral",
+ [kExprNodeCurlyBracesIdentifier] = "CurlyBracesIdentifier",
+ [kExprNodeComma] = "Comma",
+ [kExprNodeColon] = "Colon",
+ [kExprNodeArrow] = "Arrow",
+ [kExprNodeComparison] = "Comparison",
+ [kExprNodeConcat] = "Concat",
+ [kExprNodeConcatOrSubscript] = "ConcatOrSubscript",
+ [kExprNodeInteger] = "Integer",
+ [kExprNodeFloat] = "Float",
+ [kExprNodeSingleQuotedString] = "SingleQuotedString",
+ [kExprNodeDoubleQuotedString] = "DoubleQuotedString",
+ [kExprNodeOr] = "Or",
+ [kExprNodeAnd] = "And",
+ [kExprNodeUnaryMinus] = "UnaryMinus",
+ [kExprNodeBinaryMinus] = "BinaryMinus",
+ [kExprNodeNot] = "Not",
+ [kExprNodeMultiplication] = "Multiplication",
+ [kExprNodeDivision] = "Division",
+ [kExprNodeMod] = "Mod",
+ [kExprNodeOption] = "Option",
+ [kExprNodeEnvironment] = "Environment",
+ [kExprNodeAssignment] = "Assignment",
+};
+
+/// Represent `int` character as a string
+///
+/// Converts
+/// - ASCII digits into '{digit}'
+/// - ASCII printable characters into a single-character strings
+/// - everything else to numbers.
+///
+/// @param[in] ch Character to convert.
+///
+/// @return Converted string, stored in a static buffer (overriden after each
+/// call).
+static const char *intchar2str(const int ch)
+ FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ static char buf[sizeof(int) * 3 + 1];
+ if (' ' <= ch && ch < 0x7f) {
+ if (ascii_isdigit(ch)) {
+ buf[0] = '\'';
+ buf[1] = (char)ch;
+ buf[2] = '\'';
+ buf[3] = NUL;
+ } else {
+ buf[0] = (char)ch;
+ buf[1] = NUL;
+ }
+ } else {
+ snprintf(buf, sizeof(buf), "%i", ch);
+ }
+ return buf;
+}
+
+#ifdef UNIT_TESTING
+#include <stdio.h>
+
+REAL_FATTR_UNUSED
+static inline void viml_pexpr_debug_print_ast_node(
+ const ExprASTNode *const *const eastnode_p,
+ const char *const prefix)
+{
+ if (*eastnode_p == NULL) {
+ fprintf(stderr, "%s %p : NULL\n", prefix, (void *)eastnode_p);
+ } else {
+ fprintf(stderr, "%s %p : %p : %s : %zu:%zu:%zu\n",
+ prefix, (void *)eastnode_p, (void *)(*eastnode_p),
+ east_node_type_tab[(*eastnode_p)->type], (*eastnode_p)->start.line,
+ (*eastnode_p)->start.col, (*eastnode_p)->len);
+ }
+}
+
+REAL_FATTR_UNUSED
+static inline void viml_pexpr_debug_print_ast_stack(
+ const ExprASTStack *const ast_stack,
+ const char *const msg)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
+{
+ fprintf(stderr, "\n%sstack: %zu:\n", msg, kv_size(*ast_stack));
+ for (size_t i = 0; i < kv_size(*ast_stack); i++) {
+ viml_pexpr_debug_print_ast_node(
+ (const ExprASTNode *const *)kv_A(*ast_stack, i),
+ "-");
+ }
+}
+
+REAL_FATTR_UNUSED
+static inline void viml_pexpr_debug_print_token(
+ const ParserState *const pstate, const LexExprToken token)
+ FUNC_ATTR_ALWAYS_INLINE
+{
+ fprintf(stderr, "\ntkn: %s\n", viml_pexpr_repr_token(pstate, token, NULL));
+}
+#define PSTACK(msg) \
+ viml_pexpr_debug_print_ast_stack(&ast_stack, #msg)
+#define PSTACK_P(msg) \
+ viml_pexpr_debug_print_ast_stack(ast_stack, #msg)
+#define PNODE_P(eastnode_p, msg) \
+ viml_pexpr_debug_print_ast_node((const ExprASTNode *const *)eastnode_p, \
+ (#msg))
+#define PTOKEN(tkn) \
+ viml_pexpr_debug_print_token(pstate, tkn)
+#endif
+
+const uint8_t node_maxchildren[] = {
+ [kExprNodeMissing] = 0,
+ [kExprNodeOpMissing] = 2,
+ [kExprNodeTernary] = 2,
+ [kExprNodeTernaryValue] = 2,
+ [kExprNodeRegister] = 0,
+ [kExprNodeSubscript] = 2,
+ [kExprNodeListLiteral] = 1,
+ [kExprNodeUnaryPlus] = 1,
+ [kExprNodeBinaryPlus] = 2,
+ [kExprNodeNested] = 1,
+ [kExprNodeCall] = 2,
+ [kExprNodePlainIdentifier] = 0,
+ [kExprNodePlainKey] = 0,
+ [kExprNodeComplexIdentifier] = 2,
+ [kExprNodeUnknownFigure] = 1,
+ [kExprNodeLambda] = 2,
+ [kExprNodeDictLiteral] = 1,
+ [kExprNodeCurlyBracesIdentifier] = 1,
+ [kExprNodeComma] = 2,
+ [kExprNodeColon] = 2,
+ [kExprNodeArrow] = 2,
+ [kExprNodeComparison] = 2,
+ [kExprNodeConcat] = 2,
+ [kExprNodeConcatOrSubscript] = 2,
+ [kExprNodeInteger] = 0,
+ [kExprNodeFloat] = 0,
+ [kExprNodeSingleQuotedString] = 0,
+ [kExprNodeDoubleQuotedString] = 0,
+ [kExprNodeOr] = 2,
+ [kExprNodeAnd] = 2,
+ [kExprNodeUnaryMinus] = 1,
+ [kExprNodeBinaryMinus] = 2,
+ [kExprNodeNot] = 1,
+ [kExprNodeMultiplication] = 2,
+ [kExprNodeDivision] = 2,
+ [kExprNodeMod] = 2,
+ [kExprNodeOption] = 0,
+ [kExprNodeEnvironment] = 0,
+ [kExprNodeAssignment] = 2,
+};
+
+/// Free memory occupied by AST
+///
+/// @param ast AST stack to free.
+void viml_pexpr_free_ast(ExprAST ast)
+{
+ ExprASTStack ast_stack;
+ kvi_init(ast_stack);
+ kvi_push(ast_stack, &ast.root);
+ while (kv_size(ast_stack)) {
+ ExprASTNode **const cur_node = kv_last(ast_stack);
+#ifndef NDEBUG
+ // Explicitly check for AST recursiveness.
+ for (size_t i = 0 ; i < kv_size(ast_stack) - 1 ; i++) {
+ assert(*kv_A(ast_stack, i) != *cur_node);
+ }
+#endif
+ if (*cur_node == NULL) {
+ assert(kv_size(ast_stack) == 1);
+ kv_drop(ast_stack, 1);
+ } else if ((*cur_node)->children != NULL) {
+#ifndef NDEBUG
+ const uint8_t maxchildren = node_maxchildren[(*cur_node)->type];
+ assert(maxchildren > 0);
+ assert(maxchildren <= 2);
+ assert(maxchildren == 1
+ ? (*cur_node)->children->next == NULL
+ : ((*cur_node)->children->next == NULL
+ || (*cur_node)->children->next->next == NULL));
+#endif
+ kvi_push(ast_stack, &(*cur_node)->children);
+ } else if ((*cur_node)->next != NULL) {
+ kvi_push(ast_stack, &(*cur_node)->next);
+ } else if (*cur_node != NULL) {
+ kv_drop(ast_stack, 1);
+ switch ((*cur_node)->type) {
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeSingleQuotedString: {
+ xfree((*cur_node)->data.str.value);
+ break;
+ }
+ case kExprNodeMissing:
+ case kExprNodeOpMissing:
+ case kExprNodeTernary:
+ case kExprNodeTernaryValue:
+ case kExprNodeRegister:
+ case kExprNodeSubscript:
+ case kExprNodeListLiteral:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryPlus:
+ case kExprNodeNested:
+ case kExprNodeCall:
+ case kExprNodePlainIdentifier:
+ case kExprNodePlainKey:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeUnknownFigure:
+ case kExprNodeLambda:
+ case kExprNodeDictLiteral:
+ case kExprNodeCurlyBracesIdentifier:
+ case kExprNodeAssignment:
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow:
+ case kExprNodeComparison:
+ case kExprNodeConcat:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeInteger:
+ case kExprNodeFloat:
+ case kExprNodeOr:
+ case kExprNodeAnd:
+ case kExprNodeUnaryMinus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeNot:
+ case kExprNodeMultiplication:
+ case kExprNodeDivision:
+ case kExprNodeMod:
+ case kExprNodeOption:
+ case kExprNodeEnvironment: {
+ break;
+ }
+ }
+ xfree(*cur_node);
+ *cur_node = NULL;
+ }
+ }
+ kvi_destroy(ast_stack);
+}
+
+// Binary operator precedence and associativity:
+//
+// Operator | Precedence | Associativity
+// ---------+------------+-----------------
+// || | 2 | left
+// && | 3 | left
+// cmp* | 4 | not associative
+// + - . | 5 | left
+// * / % | 6 | left
+//
+// * comparison operators:
+//
+// == ==# ==? != !=# !=?
+// =~ =~# =~? !~ !~# !~?
+// > ># >? <= <=# <=?
+// < <# <? >= >=# >=?
+// is is# is? isnot isnot# isnot?
+
+/// Allocate a new node and set some of the values
+///
+/// @param[in] type Node type to allocate.
+/// @param[in] level Node level to allocate
+static inline ExprASTNode *viml_pexpr_new_node(const ExprASTNodeType type)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
+{
+ ExprASTNode *ret = xmalloc(sizeof(*ret));
+ ret->type = type;
+ ret->children = NULL;
+ ret->next = NULL;
+ return ret;
+}
+
+static struct {
+ ExprOpLvl lvl;
+ ExprOpAssociativity ass;
+} node_type_to_node_props[] = {
+ [kExprNodeMissing] = { kEOpLvlInvalid, kEOpAssNo, },
+ [kExprNodeOpMissing] = { kEOpLvlMultiplication, kEOpAssNo },
+
+ [kExprNodeNested] = { kEOpLvlParens, kEOpAssNo },
+ // Note: below nodes are kEOpLvlSubscript for “binary operator†itself, but
+ // kEOpLvlParens when it comes to inside the parenthesis.
+ [kExprNodeCall] = { kEOpLvlParens, kEOpAssNo },
+ [kExprNodeSubscript] = { kEOpLvlParens, kEOpAssNo },
+
+ [kExprNodeUnknownFigure] = { kEOpLvlParens, kEOpAssLeft },
+ [kExprNodeLambda] = { kEOpLvlParens, kEOpAssNo },
+ [kExprNodeDictLiteral] = { kEOpLvlParens, kEOpAssNo },
+ [kExprNodeListLiteral] = { kEOpLvlParens, kEOpAssNo },
+
+ [kExprNodeArrow] = { kEOpLvlArrow, kEOpAssNo },
+
+ // Right associativity for comma because this means easier access to arguments
+ // list, etc: for "[a, b, c, d]" you can access "a" in one step if it is
+ // represented as "list(comma(a, comma(b, comma(c, d))))" then if it is
+ // "list(comma(comma(comma(a, b), c), d))" in which case you will need to
+ // traverse all three comma() structures. And with comma operator (including
+ // actual comma operator from C which is not present in VimL) nobody cares
+ // about associativity, only about order of execution.
+ [kExprNodeComma] = { kEOpLvlComma, kEOpAssRight },
+
+ // Colons are not eligible for chaining, so nobody cares about associativity.
+ [kExprNodeColon] = { kEOpLvlColon, kEOpAssNo },
+
+ [kExprNodeTernary] = { kEOpLvlTernary, kEOpAssRight },
+
+ [kExprNodeOr] = { kEOpLvlOr, kEOpAssLeft },
+
+ [kExprNodeAnd] = { kEOpLvlAnd, kEOpAssLeft },
+
+ [kExprNodeTernaryValue] = { kEOpLvlTernaryValue, kEOpAssRight },
+
+ [kExprNodeComparison] = { kEOpLvlComparison, kEOpAssRight },
+
+ [kExprNodeBinaryPlus] = { kEOpLvlAddition, kEOpAssLeft },
+ [kExprNodeBinaryMinus] = { kEOpLvlAddition, kEOpAssLeft },
+ [kExprNodeConcat] = { kEOpLvlAddition, kEOpAssLeft },
+
+ [kExprNodeMultiplication] = { kEOpLvlMultiplication, kEOpAssLeft },
+ [kExprNodeDivision] = { kEOpLvlMultiplication, kEOpAssLeft },
+ [kExprNodeMod] = { kEOpLvlMultiplication, kEOpAssLeft },
+
+ [kExprNodeUnaryPlus] = { kEOpLvlUnary, kEOpAssNo },
+ [kExprNodeUnaryMinus] = { kEOpLvlUnary, kEOpAssNo },
+ [kExprNodeNot] = { kEOpLvlUnary, kEOpAssNo },
+
+ [kExprNodeConcatOrSubscript] = { kEOpLvlSubscript, kEOpAssLeft },
+
+ [kExprNodeCurlyBracesIdentifier] = { kEOpLvlComplexIdentifier, kEOpAssLeft },
+
+ [kExprNodeAssignment] = { kEOpLvlAssignment, kEOpAssLeft },
+
+ [kExprNodeComplexIdentifier] = { kEOpLvlValue, kEOpAssLeft },
+
+ [kExprNodePlainIdentifier] = { kEOpLvlValue, kEOpAssNo },
+ [kExprNodePlainKey] = { kEOpLvlValue, kEOpAssNo },
+ [kExprNodeRegister] = { kEOpLvlValue, kEOpAssNo },
+ [kExprNodeInteger] = { kEOpLvlValue, kEOpAssNo },
+ [kExprNodeFloat] = { kEOpLvlValue, kEOpAssNo },
+ [kExprNodeDoubleQuotedString] = { kEOpLvlValue, kEOpAssNo },
+ [kExprNodeSingleQuotedString] = { kEOpLvlValue, kEOpAssNo },
+ [kExprNodeOption] = { kEOpLvlValue, kEOpAssNo },
+ [kExprNodeEnvironment] = { kEOpLvlValue, kEOpAssNo },
+};
+
+/// Get AST node priority level
+///
+/// Used primary to reduce line length, so keep the name short.
+///
+/// @param[in] node Node to get priority for.
+///
+/// @return Node priority level.
+static inline ExprOpLvl node_lvl(const ExprASTNode node)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return node_type_to_node_props[node.type].lvl;
+}
+
+/// Get AST node associativity, to be used for operator nodes primary
+///
+/// Used primary to reduce line length, so keep the name short.
+///
+/// @param[in] node Node to get priority for.
+///
+/// @return Node associativity.
+static inline ExprOpAssociativity node_ass(const ExprASTNode node)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return node_type_to_node_props[node.type].ass;
+}
+
+/// Handle binary operator
+///
+/// This function is responsible for handling priority levels as well.
+///
+/// @param[in] pstate Parser state, used for error reporting.
+/// @param ast_stack AST stack. May be popped of some values and will
+/// definitely receive new ones.
+/// @param bop_node New node to handle.
+/// @param[out] want_node_p New value of want_node.
+/// @param[out] ast_err Location where error is saved, if any.
+///
+/// @return True if no errors occurred, false otherwise.
+static bool viml_pexpr_handle_bop(const ParserState *const pstate,
+ ExprASTStack *const ast_stack,
+ ExprASTNode *const bop_node,
+ ExprASTWantedNode *const want_node_p,
+ ExprASTError *const ast_err)
+ FUNC_ATTR_NONNULL_ALL
+{
+ bool ret = true;
+ ExprASTNode **top_node_p = NULL;
+ ExprASTNode *top_node;
+ ExprOpLvl top_node_lvl;
+ ExprOpAssociativity top_node_ass;
+ assert(kv_size(*ast_stack));
+ const ExprOpLvl bop_node_lvl = ((bop_node->type == kExprNodeCall
+ || bop_node->type == kExprNodeSubscript)
+ ? kEOpLvlSubscript
+ : node_lvl(*bop_node));
+#ifndef NDEBUG
+ const ExprOpAssociativity bop_node_ass = (
+ (bop_node->type == kExprNodeCall
+ || bop_node->type == kExprNodeSubscript)
+ ? kEOpAssLeft
+ : node_ass(*bop_node));
+#endif
+ do {
+ ExprASTNode **new_top_node_p = kv_last(*ast_stack);
+ ExprASTNode *new_top_node = *new_top_node_p;
+ assert(new_top_node != NULL);
+ const ExprOpLvl new_top_node_lvl = node_lvl(*new_top_node);
+ const ExprOpAssociativity new_top_node_ass = node_ass(*new_top_node);
+ assert(bop_node_lvl != new_top_node_lvl
+ || bop_node_ass == new_top_node_ass);
+ if (top_node_p != NULL
+ && ((bop_node_lvl > new_top_node_lvl
+ || (bop_node_lvl == new_top_node_lvl
+ && new_top_node_ass == kEOpAssNo)))) {
+ break;
+ }
+ kv_drop(*ast_stack, 1);
+ top_node_p = new_top_node_p;
+ top_node = new_top_node;
+ top_node_lvl = new_top_node_lvl;
+ top_node_ass = new_top_node_ass;
+ if (bop_node_lvl == top_node_lvl && top_node_ass == kEOpAssRight) {
+ break;
+ }
+ } while (kv_size(*ast_stack));
+ if (top_node_ass == kEOpAssLeft || top_node_lvl != bop_node_lvl) {
+ // outer(op(x,y)) -> outer(new_op(op(x,y),*))
+ //
+ // Before: top_node_p = outer(*), points to op(x,y)
+ // Other stack elements unknown
+ //
+ // After: top_node_p = outer(*), points to new_op(op(x,y))
+ // &bop_node->children->next = new_op(op(x,y),*), points to NULL
+ *top_node_p = bop_node;
+ bop_node->children = top_node;
+ assert(bop_node->children->next == NULL);
+ kvi_push(*ast_stack, top_node_p);
+ kvi_push(*ast_stack, &bop_node->children->next);
+ } else {
+ assert(top_node_lvl == bop_node_lvl && top_node_ass == kEOpAssRight);
+ assert(top_node->children != NULL && top_node->children->next != NULL);
+ // outer(op(x,y)) -> outer(op(x,new_op(y,*)))
+ //
+ // Before: top_node_p = outer(*), points to op(x,y)
+ // Other stack elements unknown
+ //
+ // After: top_node_p = outer(*), points to op(x,new_op(y))
+ // &top_node->children->next = op(x,*), points to new_op(y)
+ // &bop_node->children->next = new_op(y,*), points to NULL
+ bop_node->children = top_node->children->next;
+ top_node->children->next = bop_node;
+ assert(bop_node->children->next == NULL);
+ kvi_push(*ast_stack, top_node_p);
+ kvi_push(*ast_stack, &top_node->children->next);
+ kvi_push(*ast_stack, &bop_node->children->next);
+ // TODO(ZyX-I): Make this not error, but treat like Python does
+ if (bop_node->type == kExprNodeComparison) {
+ east_set_error(pstate, ast_err,
+ _("E15: Operator is not associative: %.*s"),
+ bop_node->start);
+ ret = false;
+ }
+ }
+ *want_node_p = kENodeValue;
+ return ret;
+}
+
+/// ParserPosition literal based on ParserPosition pos with columns shifted
+///
+/// Function does not check whether resulting position is valid.
+///
+/// @param[in] pos Position to shift.
+/// @param[in] shift Number of bytes to shift.
+///
+/// @return Shifted position.
+static inline ParserPosition shifted_pos(const ParserPosition pos,
+ const size_t shift)
+ FUNC_ATTR_CONST FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (ParserPosition) { .line = pos.line, .col = pos.col + shift };
+}
+
+/// ParserPosition literal based on ParserPosition pos with specified column
+///
+/// Function does not check whether remaining position is valid.
+///
+/// @param[in] pos Position to adjust.
+/// @param[in] new_col New column.
+///
+/// @return Shifted position.
+static inline ParserPosition recol_pos(const ParserPosition pos,
+ const size_t new_col)
+ FUNC_ATTR_CONST FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (ParserPosition) { .line = pos.line, .col = new_col };
+}
+
+/// Get highlight group name
+#define HL(g) (is_invalid ? "NvimInvalid" #g : "Nvim" #g)
+
+/// Highlight current token with the given group
+#define HL_CUR_TOKEN(g) \
+ viml_parser_highlight(pstate, cur_token.start, cur_token.len, \
+ HL(g))
+
+/// Allocate new node, saving some values
+#define NEW_NODE(type) \
+ viml_pexpr_new_node(type)
+
+/// Set position of the given node to position from the given token
+///
+/// @param cur_node Node to modify.
+/// @param cur_token Token to set position from.
+#define POS_FROM_TOKEN(cur_node, cur_token) \
+ do { \
+ (cur_node)->start = cur_token.start; \
+ (cur_node)->len = cur_token.len; \
+ } while (0)
+
+/// Allocate new node and set its position from the current token
+///
+/// If previous token happened to contain spacing then it will be included.
+///
+/// @param cur_node Variable to save allocated node to.
+/// @param typ Node type.
+#define NEW_NODE_WITH_CUR_POS(cur_node, typ) \
+ do { \
+ (cur_node) = NEW_NODE(typ); \
+ POS_FROM_TOKEN((cur_node), cur_token); \
+ if (prev_token.type == kExprLexSpacing) { \
+ (cur_node)->start = prev_token.start; \
+ (cur_node)->len += prev_token.len; \
+ } \
+ } while (0)
+
+/// Check whether it is possible to have next expression after current
+///
+/// For :echo: `:echo @a @a` is a valid expression. `:echo (@a @a)` is not.
+#define MAY_HAVE_NEXT_EXPR \
+ (kv_size(ast_stack) == 1)
+
+/// Add operator node
+///
+/// @param[in] cur_node Node to add.
+#define ADD_OP_NODE(cur_node) \
+ is_invalid |= !viml_pexpr_handle_bop(pstate, &ast_stack, cur_node, \
+ &want_node, &ast.err)
+
+/// Record missing operator: for things like
+///
+/// :echo @a @a
+///
+/// (allowed) or
+///
+/// :echo (@a @a)
+///
+/// (parsed as OpMissing(@a, @a)).
+#define OP_MISSING \
+ do { \
+ if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) { \
+ /* Multiple expressions allowed, return without calling */ \
+ /* viml_parser_advance(). */ \
+ goto viml_pexpr_parse_end; \
+ } else { \
+ assert(*top_node_p != NULL); \
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, _("E15: Missing operator: %.*s")); \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOpMissing); \
+ cur_node->len = 0; \
+ ADD_OP_NODE(cur_node); \
+ goto viml_pexpr_parse_process_token; \
+ } \
+ } while (0)
+
+/// Record missing value: for things like "* 5"
+///
+/// @param[in] msg Error message.
+#define ADD_VALUE_IF_MISSING(msg) \
+ do { \
+ if (want_node == kENodeValue) { \
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, (msg)); \
+ NEW_NODE_WITH_CUR_POS((*top_node_p), kExprNodeMissing); \
+ (*top_node_p)->len = 0; \
+ want_node = kENodeOperator; \
+ } \
+ } while (0)
+
+/// Set AST error, unless AST already is not correct
+///
+/// @param[out] ret_ast AST to set error in.
+/// @param[in] pstate Parser state, used to get error message argument.
+/// @param[in] msg Error message, assumed to be already translated and
+/// containing a single %token "%.*s".
+/// @param[in] start Position at which error occurred.
+static inline void east_set_error(const ParserState *const pstate,
+ ExprASTError *const ret_ast_err,
+ const char *const msg,
+ const ParserPosition start)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_ALWAYS_INLINE
+{
+ if (ret_ast_err->msg != NULL) {
+ return;
+ }
+ const ParserLine pline = pstate->reader.lines.items[start.line];
+ ret_ast_err->msg = msg;
+ ret_ast_err->arg_len = (int)(pline.size - start.col);
+ ret_ast_err->arg = pline.data + start.col;
+}
+
+/// Set error from the given token and given message
+#define ERROR_FROM_TOKEN_AND_MSG(cur_token, msg) \
+ do { \
+ is_invalid = true; \
+ east_set_error(pstate, &ast.err, msg, cur_token.start); \
+ } while (0)
+
+/// Like #ERROR_FROM_TOKEN_AND_MSG, but gets position from a node
+#define ERROR_FROM_NODE_AND_MSG(node, msg) \
+ do { \
+ is_invalid = true; \
+ east_set_error(pstate, &ast.err, msg, node->start); \
+ } while (0)
+
+/// Set error from the given kExprLexInvalid token
+#define ERROR_FROM_TOKEN(cur_token) \
+ ERROR_FROM_TOKEN_AND_MSG(cur_token, cur_token.data.err.msg)
+
+/// Select figure brace type, altering highlighting as well if needed
+///
+/// @param[out] node Node to modify type.
+/// @param[in] new_type New type, one of ExprASTNodeType values without
+/// kExprNode prefix.
+/// @param[in] hl Corresponding highlighting, passed as an argument to #HL.
+#define SELECT_FIGURE_BRACE_TYPE(node, new_type, hl) \
+ do { \
+ ExprASTNode *const node_ = (node); \
+ assert(node_->type == kExprNodeUnknownFigure \
+ || node_->type == kExprNode##new_type); \
+ node_->type = kExprNode##new_type; \
+ if (pstate->colors) { \
+ kv_A(*pstate->colors, node_->data.fig.opening_hl_idx).group = \
+ HL(hl); \
+ } \
+ } while (0)
+
+/// Add identifier which should constitute complex identifier node
+///
+/// This one is to be called only in case want_node is kENodeOperator.
+///
+/// @param new_ident_node_code Code used to create a new identifier node and
+/// update want_node and ast_stack, without
+/// a trailing semicolon.
+/// @param hl Highlighting name to use, passed as an argument to #HL.
+#define ADD_IDENT(new_ident_node_code, hl) \
+ do { \
+ assert(want_node == kENodeOperator); \
+ /* Operator: may only be curly braces name, but only under certain */ \
+ /* conditions. */ \
+\
+ /* First condition is that there is no space before a part of complex */ \
+ /* identifier. */ \
+ if (prev_token.type == kExprLexSpacing) { \
+ OP_MISSING; \
+ } \
+ switch ((*top_node_p)->type) { \
+ /* Second is that previous node is one of the identifiers: */ \
+ /* complex, plain, curly braces. */ \
+\
+ /* TODO(ZyX-I): Extend syntax to allow ${expr}. This is needed to */ \
+ /* handle environment variables like those bash uses for */ \
+ /* `export -f`: their names consist not only of alphanumeric */ \
+ /* characetrs. */ \
+ case kExprNodeComplexIdentifier: \
+ case kExprNodePlainIdentifier: \
+ case kExprNodeCurlyBracesIdentifier: { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComplexIdentifier); \
+ cur_node->len = 0; \
+ cur_node->children = *top_node_p; \
+ *top_node_p = cur_node; \
+ kvi_push(ast_stack, &cur_node->children->next); \
+ ExprASTNode **const new_top_node_p = kv_last(ast_stack); \
+ assert(*new_top_node_p == NULL); \
+ new_ident_node_code; \
+ *new_top_node_p = cur_node; \
+ HL_CUR_TOKEN(hl); \
+ break; \
+ } \
+ default: { \
+ OP_MISSING; \
+ break; \
+ } \
+ } \
+ } while (0)
+
+/// Determine whether given parse type is an assignment
+///
+/// @param[in] pt Checked parse type.
+///
+/// @return true if parsing an assignment, false otherwise.
+static inline bool pt_is_assignment(const ExprASTParseType pt)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ return (pt == kEPTAssignment || pt == kEPTSingleAssignment);
+}
+
+/// Structure used to define “string shifts†necessary to map string
+/// highlighting to actual strings.
+typedef struct {
+ size_t start; ///< Where special character starts in original string.
+ size_t orig_len; ///< Length of orininal string (e.g. 4 for "\x80").
+ size_t act_len; ///< Length of resulting character(s) (e.g. 1 for "\x80").
+ bool escape_not_known; ///< True if escape sequence in original is not known.
+} StringShift;
+
+/// Parse and highlight single- or double-quoted string
+///
+/// Function is supposed to detect and highlight regular expressions (but does
+/// not do now).
+///
+/// @param[out] pstate Parser state which also contains a place where
+/// highlighting is saved.
+/// @param[out] node Node where string parsing results are saved.
+/// @param[in] token Token to highlight.
+/// @param[in] ast_stack Parser AST stack, used to detect whether current
+/// string is a regex.
+/// @param[in] is_invalid Whether currently processed token is not valid.
+static void parse_quoted_string(ParserState *const pstate,
+ ExprASTNode *const node,
+ const LexExprToken token,
+ const ExprASTStack ast_stack,
+ const bool is_invalid)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const ParserLine pline = pstate->reader.lines.items[token.start.line];
+ const char *const s = pline.data + token.start.col;
+ const char *const e = s + token.len - token.data.str.closed;
+ const char *p = s + 1;
+ const bool is_double = (token.type == kExprLexDoubleQuotedString);
+ size_t size = token.len - token.data.str.closed - 1;
+ kvec_withinit_t(StringShift, 16) shifts;
+ kvi_init(shifts);
+ if (!is_double) {
+ viml_parser_highlight(pstate, token.start, 1, HL(SingleQuote));
+ while (p < e) {
+ const char *const chunk_e = memchr(p, '\'', (size_t)(e - p));
+ if (chunk_e == NULL) {
+ break;
+ }
+ size--;
+ p = chunk_e + 2;
+ if (pstate->colors) {
+ kvi_push(shifts, ((StringShift) {
+ .start = token.start.col + (size_t)(chunk_e - s),
+ .orig_len = 2,
+ .act_len = 1,
+ .escape_not_known = false,
+ }));
+ }
+ }
+ node->data.str.size = size;
+ if (size == 0) {
+ node->data.str.value = NULL;
+ } else {
+ char *v_p;
+ v_p = node->data.str.value = xmallocz(size);
+ p = s + 1;
+ while (p < e) {
+ const char *const chunk_e = memchr(p, '\'', (size_t)(e - p));
+ if (chunk_e == NULL) {
+ memcpy(v_p, p, (size_t)(e - p));
+ break;
+ }
+ memcpy(v_p, p, (size_t)(chunk_e - p));
+ v_p += (size_t)(chunk_e - p) + 1;
+ v_p[-1] = '\'';
+ p = chunk_e + 2;
+ }
+ }
+ } else {
+ viml_parser_highlight(pstate, token.start, 1, HL(DoubleQuote));
+ for (p = s + 1; p < e; p++) {
+ if (*p == '\\' && p + 1 < e) {
+ p++;
+ if (p + 1 == e) {
+ size--;
+ break;
+ }
+ switch (*p) {
+ // A "\<x>" form occupies at least 4 characters, and produces up to
+ // 6 characters: reserve space for 2 extra, but do not compute actual
+ // length just now, it would be costy.
+ case '<': {
+ size += 2;
+ break;
+ }
+ // Hexadecimal, always single byte, but at least three bytes each.
+ case 'x': case 'X': {
+ size--;
+ if (ascii_isxdigit(p[1])) {
+ size--;
+ if (p + 2 < e && ascii_isxdigit(p[2])) {
+ size--;
+ }
+ }
+ break;
+ }
+ // Unicode
+ //
+ // \uF takes 1 byte which is 2 bytes less then escape sequence.
+ // \uFF: 2 bytes, 2 bytes less.
+ // \uFFF: 3 bytes, 2 bytes less.
+ // \uFFFF: 3 bytes, 3 bytes less.
+ // \UFFFFF: 4 bytes, 3 bytes less.
+ // \UFFFFFF: 5 bytes, 3 bytes less.
+ // \UFFFFFFF: 6 bytes, 3 bytes less.
+ // \U7FFFFFFF: 6 bytes, 4 bytes less.
+ case 'u': case 'U': {
+ const char *const esc_start = p;
+ size_t n = (*p == 'u' ? 4 : 8);
+ int nr = 0;
+ p++;
+ while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
+ p++;
+ nr = (nr << 4) + hex2nr(*p);
+ }
+ // Escape length: (esc_start - 1) points to "\\", esc_start to "u"
+ // or "U", p to the byte after last byte. So escape sequence
+ // occupies p - (esc_start - 1), but it stands for a utf_char2len
+ // bytes.
+ size -= (size_t)((p - (esc_start - 1)) - utf_char2len(nr));
+ p--;
+ break;
+ }
+ // Octal, always single byte, but at least two bytes each.
+ case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+ case '7': {
+ size--;
+ p++;
+ if (*p >= '0' && *p <= '7') {
+ size--;
+ p++;
+ if (p < e && *p >= '0' && *p <= '7') {
+ size--;
+ p++;
+ }
+ }
+ break;
+ }
+ default: {
+ size--;
+ break;
+ }
+ }
+ }
+ }
+ if (size == 0) {
+ node->data.str.value = NULL;
+ node->data.str.size = 0;
+ } else {
+ char *v_p;
+ v_p = node->data.str.value = xmalloc(size);
+ p = s + 1;
+ while (p < e) {
+ const char *const chunk_e = memchr(p, '\\', (size_t)(e - p));
+ if (chunk_e == NULL) {
+ memcpy(v_p, p, (size_t)(e - p));
+ v_p += e - p;
+ break;
+ }
+ memcpy(v_p, p, (size_t)(chunk_e - p));
+ v_p += (size_t)(chunk_e - p);
+ p = chunk_e + 1;
+ if (p == e) {
+ *v_p++ = '\\';
+ break;
+ }
+ bool is_unknown = false;
+ const char *const v_p_start = v_p;
+ switch (*p) {
+#define SINGLE_CHAR_ESC(ch, real_ch) \
+ case ch: { \
+ *v_p++ = real_ch; \
+ p++; \
+ break; \
+ }
+ SINGLE_CHAR_ESC('b', BS)
+ SINGLE_CHAR_ESC('e', ESC)
+ SINGLE_CHAR_ESC('f', FF)
+ SINGLE_CHAR_ESC('n', NL)
+ SINGLE_CHAR_ESC('r', CAR)
+ SINGLE_CHAR_ESC('t', TAB)
+ SINGLE_CHAR_ESC('"', '"')
+ SINGLE_CHAR_ESC('\\', '\\')
+#undef SINGLE_CHAR_ESC
+
+ // Hexadecimal or unicode.
+ case 'X': case 'x': case 'u': case 'U': {
+ if (p + 1 < e && ascii_isxdigit(p[1])) {
+ size_t n;
+ int nr;
+ bool is_hex = (*p == 'x' || *p == 'X');
+
+ if (is_hex) {
+ n = 2;
+ } else if (*p == 'u') {
+ n = 4;
+ } else {
+ n = 8;
+ }
+ nr = 0;
+ while (p + 1 < e && n-- && ascii_isxdigit(p[1])) {
+ p++;
+ nr = (nr << 4) + hex2nr(*p);
+ }
+ p++;
+ if (is_hex) {
+ *v_p++ = (char)nr;
+ } else {
+ v_p += utf_char2bytes(nr, (char_u *)v_p);
+ }
+ } else {
+ is_unknown = true;
+ *v_p++ = *p;
+ p++;
+ }
+ break;
+ }
+ // Octal: "\1", "\12", "\123".
+ case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+ case '7': {
+ uint8_t ch = (uint8_t)(*p++ - '0');
+ if (p < e && *p >= '0' && *p <= '7') {
+ ch = (uint8_t)((ch << 3) + *p++ - '0');
+ if (p < e && *p >= '0' && *p <= '7') {
+ ch = (uint8_t)((ch << 3) + *p++ - '0');
+ }
+ }
+ *v_p++ = (char)ch;
+ break;
+ }
+ // Special key, e.g.: "\<C-W>"
+ case '<': {
+ const size_t special_len = (
+ trans_special((const char_u **)&p, (size_t)(e - p),
+ (char_u *)v_p, true, true));
+ if (special_len != 0) {
+ v_p += special_len;
+ } else {
+ is_unknown = true;
+ mb_copy_char((const char_u **)&p, (char_u **)&v_p);
+ }
+ break;
+ }
+ default: {
+ is_unknown = true;
+ mb_copy_char((const char_u **)&p, (char_u **)&v_p);
+ break;
+ }
+ }
+ if (pstate->colors) {
+ kvi_push(shifts, ((StringShift) {
+ .start = token.start.col + (size_t)(chunk_e - s),
+ .orig_len = (size_t)(p - chunk_e),
+ .act_len = (size_t)(v_p - (char *)v_p_start),
+ .escape_not_known = is_unknown,
+ }));
+ }
+ }
+ node->data.str.size = (size_t)(v_p - node->data.str.value);
+ }
+ }
+ if (pstate->colors) {
+ // TODO(ZyX-I): use ast_stack to determine and highlight regular expressions
+ // TODO(ZyX-I): use ast_stack to determine and highlight printf format str
+ // TODO(ZyX-I): use ast_stack to determine and highlight expression strings
+ size_t next_col = token.start.col + 1;
+ const char *const body_str = (is_double
+ ? HL(DoubleQuotedBody)
+ : HL(SingleQuotedBody));
+ const char *const esc_str = (is_double
+ ? HL(DoubleQuotedEscape)
+ : HL(SingleQuotedQuote));
+ const char *const ukn_esc_str = (is_double
+ ? HL(DoubleQuotedUnknownEscape)
+ : HL(SingleQuotedUnknownEscape));
+ for (size_t i = 0; i < kv_size(shifts); i++) {
+ const StringShift cur_shift = kv_A(shifts, i);
+ if (cur_shift.start > next_col) {
+ viml_parser_highlight(pstate, recol_pos(token.start, next_col),
+ cur_shift.start - next_col,
+ body_str);
+ }
+ viml_parser_highlight(pstate, recol_pos(token.start, cur_shift.start),
+ cur_shift.orig_len,
+ (cur_shift.escape_not_known
+ ? ukn_esc_str
+ : esc_str));
+ next_col = cur_shift.start + cur_shift.orig_len;
+ }
+ if (next_col - token.start.col < token.len - token.data.str.closed) {
+ viml_parser_highlight(pstate, recol_pos(token.start, next_col),
+ (token.start.col
+ + token.len
+ - token.data.str.closed
+ - next_col),
+ body_str);
+ }
+ }
+ if (token.data.str.closed) {
+ if (is_double) {
+ viml_parser_highlight(pstate, shifted_pos(token.start, token.len - 1),
+ 1, HL(DoubleQuote));
+ } else {
+ viml_parser_highlight(pstate, shifted_pos(token.start, token.len - 1),
+ 1, HL(SingleQuote));
+ }
+ }
+ kvi_destroy(shifts);
+}
+
+/// Additional flags to pass to lexer depending on want_node
+static const int want_node_to_lexer_flags[] = {
+ [kENodeValue] = kELFlagIsNotCmp,
+ [kENodeOperator] = kELFlagForbidScope,
+};
+
+/// Number of characters to highlight as NumberPrefix depending on the base
+static const uint8_t base_to_prefix_length[] = {
+ [2] = 2,
+ [8] = 1,
+ [10] = 0,
+ [16] = 2,
+};
+
+/// Parse one VimL expression
+///
+/// @param pstate Parser state.
+/// @param[in] flags Additional flags, see ExprParserFlags
+///
+/// @return Parsed AST.
+ExprAST viml_pexpr_parse(ParserState *const pstate, const int flags)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
+{
+ ExprAST ast = {
+ .err = {
+ .msg = NULL,
+ .arg_len = 0,
+ .arg = NULL,
+ },
+ .root = NULL,
+ };
+ // Expression stack contains current branch in AST tree: that is
+ // - Stack item 0 contains root of the tree, i.e. &ast->root.
+ // - Stack item i points to the previous stack items’ last child.
+ //
+ // When parser expects “value†node that is something like identifier or "["
+ // (list start) last stack item contains NULL. Otherwise last stack item is
+ // supposed to contain last “finished†value: e.g. "1" or "+(1, 1)" (node
+ // representing "1+1").
+ ExprASTStack ast_stack;
+ kvi_init(ast_stack);
+ kvi_push(ast_stack, &ast.root);
+ ExprASTWantedNode want_node = kENodeValue;
+ ExprASTParseTypeStack pt_stack;
+ kvi_init(pt_stack);
+ kvi_push(pt_stack, kEPTExpr);
+ if (flags & kExprFlagsParseLet) {
+ kvi_push(pt_stack, kEPTAssignment);
+ }
+ LexExprToken prev_token = { .type = kExprLexMissing };
+ bool highlighted_prev_spacing = false;
+ // Lambda node, valid when parsing lambda arguments only.
+ ExprASTNode *lambda_node = NULL;
+ size_t asgn_level = 0;
+ do {
+ const bool is_concat_or_subscript = (
+ want_node == kENodeValue
+ && kv_size(ast_stack) > 1
+ && (*kv_Z(ast_stack, 1))->type == kExprNodeConcatOrSubscript);
+ const int lexer_additional_flags = (
+ kELFlagPeek
+ | ((flags & kExprFlagsDisallowEOC) ? kELFlagForbidEOC : 0)
+ | ((want_node == kENodeValue
+ && (kv_size(ast_stack) == 1
+ || ((*kv_Z(ast_stack, 1))->type != kExprNodeConcat
+ && ((*kv_Z(ast_stack, 1))->type
+ != kExprNodeConcatOrSubscript))))
+ ? kELFlagAllowFloat
+ : 0));
+ LexExprToken cur_token = viml_pexpr_next_token(
+ pstate, want_node_to_lexer_flags[want_node] | lexer_additional_flags);
+ if (cur_token.type == kExprLexEOC) {
+ break;
+ }
+ LexExprTokenType tok_type = cur_token.type;
+ const bool token_invalid = (tok_type == kExprLexInvalid);
+ bool is_invalid = token_invalid;
+viml_pexpr_parse_process_token:
+ // May use different flags this time.
+ cur_token = viml_pexpr_next_token(
+ pstate, want_node_to_lexer_flags[want_node] | lexer_additional_flags);
+ if (tok_type == kExprLexSpacing) {
+ if (is_invalid) {
+ HL_CUR_TOKEN(Spacing);
+ } else {
+ // Do not do anything: let regular spacing be highlighted as normal.
+ // This also allows later to highlight spacing as invalid.
+ }
+ goto viml_pexpr_parse_cycle_end;
+ } else if (is_invalid && prev_token.type == kExprLexSpacing
+ && !highlighted_prev_spacing) {
+ viml_parser_highlight(pstate, prev_token.start, prev_token.len,
+ HL(Spacing));
+ is_invalid = false;
+ highlighted_prev_spacing = true;
+ }
+ const ParserLine pline = pstate->reader.lines.items[cur_token.start.line];
+ ExprASTNode **const top_node_p = kv_last(ast_stack);
+ assert(kv_size(ast_stack) >= 1);
+ ExprASTNode *cur_node = NULL;
+#ifndef NDEBUG
+ const bool want_value = (want_node == kENodeValue);
+ assert(want_value == (*top_node_p == NULL));
+ assert(kv_A(ast_stack, 0) == &ast.root);
+ // Check that stack item i + 1 points to stack items’ i *last* child.
+ for (size_t i = 0; i + 1 < kv_size(ast_stack); i++) {
+ const bool item_null = (want_value && i + 2 == kv_size(ast_stack));
+ assert((&(*kv_A(ast_stack, i))->children == kv_A(ast_stack, i + 1)
+ && (item_null
+ ? (*kv_A(ast_stack, i))->children == NULL
+ : (*kv_A(ast_stack, i))->children->next == NULL))
+ || ((&(*kv_A(ast_stack, i))->children->next
+ == kv_A(ast_stack, i + 1))
+ && (item_null
+ ? (*kv_A(ast_stack, i))->children->next == NULL
+ : (*kv_A(ast_stack, i))->children->next->next == NULL)));
+ }
+#endif
+ // Note: in Vim whether expression "cond?d.a:2" is valid depends both on
+ // "cond" and whether "d" is a dictionary: expression is valid if condition
+ // is true and "d" is a dictionary (with "a" key or it will complain about
+ // missing one, but this is not relevant); if any of the requirements is
+ // broken then this thing is parsed as "d . a:2" yielding missing colon
+ // error. This parser does not allow such ambiguity, especially because it
+ // simply can’t: whether "d" is a dictionary is not known at the parsing
+ // time.
+ //
+ // Here example will always contain a concat with "a:2" sucking colon,
+ // making expression invalid both because there is no longer a spare colon
+ // for ternary and because concatenating dictionary with anything is not
+ // valid. There are more cases when this will make a difference though.
+ const bool node_is_key = (
+ is_concat_or_subscript
+ && (cur_token.type == kExprLexPlainIdentifier
+ ? (!cur_token.data.var.autoload
+ && cur_token.data.var.scope == kExprVarScopeMissing)
+ : (cur_token.type == kExprLexNumber))
+ && prev_token.type != kExprLexSpacing);
+ if (is_concat_or_subscript && !node_is_key) {
+ // Note: in Vim "d. a" (this is the reason behind `prev_token.type !=
+ // kExprLexSpacing` part of the condition) as well as any other "d.{expr}"
+ // where "{expr}" does not look like a key is invalid whenever "d" happens
+ // to be a dictionary. Since parser has no idea whether preceding
+ // expression is actually a dictionary it can’t outright reject anything,
+ // so it turns kExprNodeConcatOrSubscript into kExprNodeConcat instead,
+ // which will yield different errors then Vim does in a number of
+ // circumstances, and in any case runtime and not parse time errors.
+ (*kv_Z(ast_stack, 1))->type = kExprNodeConcat;
+ }
+ // Pop some stack pt_stack items in case of misplaced nodes.
+ const bool is_single_assignment = kv_last(pt_stack) == kEPTSingleAssignment;
+ switch (kv_last(pt_stack)) {
+ case kEPTExpr: {
+ break;
+ }
+ case kEPTLambdaArguments: {
+ if ((want_node == kENodeOperator
+ && tok_type != kExprLexComma
+ && tok_type != kExprLexArrow)
+ || (want_node == kENodeValue
+ && !(cur_token.type == kExprLexPlainIdentifier
+ && cur_token.data.var.scope == kExprVarScopeMissing
+ && !cur_token.data.var.autoload)
+ && tok_type != kExprLexArrow)) {
+ lambda_node->data.fig.type_guesses.allow_lambda = false;
+ if (lambda_node->children != NULL
+ && lambda_node->children->type == kExprNodeComma) {
+ // If lambda has comma child this means that parser has already seen
+ // at least "{arg1,", so node cannot possibly be anything, but
+ // lambda.
+
+ // Vim may give E121 or E720 in this case, but it does not look
+ // right to have either because both are results of reevaluation
+ // possibly-lambda node as a dictionary and here this is not going
+ // to happen.
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E15: Expected lambda arguments list or arrow: %.*s"));
+ } else {
+ // Else it may appear that possibly-lambda node is actually
+ // a dictionary or curly-braces-name identifier.
+ lambda_node = NULL;
+ kv_drop(pt_stack, 1);
+ }
+ }
+ break;
+ }
+ case kEPTSingleAssignment:
+ case kEPTAssignment: {
+ if (want_node == kENodeValue
+ && tok_type != kExprLexBracket
+ && tok_type != kExprLexPlainIdentifier
+ && (tok_type != kExprLexFigureBrace || cur_token.data.brc.closing)
+ && !(node_is_key && tok_type == kExprLexNumber)
+ && tok_type != kExprLexEnv
+ && tok_type != kExprLexOption
+ && tok_type != kExprLexRegister) {
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E15: Expected value part of assignment lvalue: %.*s"));
+ kv_drop(pt_stack, 1);
+ } else if (want_node == kENodeOperator
+ && tok_type != kExprLexBracket
+ && (tok_type != kExprLexFigureBrace
+ || cur_token.data.brc.closing)
+ && tok_type != kExprLexDot
+ && (tok_type != kExprLexComma || !is_single_assignment)
+ && tok_type != kExprLexAssignment
+ // Curly brace identifiers: will contain plain identifier or
+ // another curly brace in position where operator is wanted.
+ && !((tok_type == kExprLexPlainIdentifier
+ || (tok_type == kExprLexFigureBrace
+ && !cur_token.data.brc.closing))
+ && prev_token.type != kExprLexSpacing)) {
+ if (flags & kExprFlagsMulti && MAY_HAVE_NEXT_EXPR) {
+ goto viml_pexpr_parse_end;
+ }
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E15: Expected assignment operator or subscript: %.*s"));
+ kv_drop(pt_stack, 1);
+ }
+ assert(kv_size(pt_stack));
+ break;
+ }
+ }
+ assert(kv_size(pt_stack));
+ const ExprASTParseType cur_pt = kv_last(pt_stack);
+ assert(lambda_node == NULL || cur_pt == kEPTLambdaArguments);
+ switch (tok_type) {
+ case kExprLexMissing:
+ case kExprLexSpacing:
+ case kExprLexEOC: {
+ assert(false);
+ }
+ case kExprLexInvalid: {
+ ERROR_FROM_TOKEN(cur_token);
+ tok_type = cur_token.data.err.type;
+ goto viml_pexpr_parse_process_token;
+ }
+ case kExprLexRegister: {
+ if (want_node == kENodeOperator) {
+ // Register in operator position: e.g. @a @a
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeRegister);
+ cur_node->data.reg.name = cur_token.data.reg.name;
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ HL_CUR_TOKEN(Register);
+ break;
+ }
+#define SIMPLE_UB_OP(op) \
+ case kExprLex##op: { \
+ if (want_node == kENodeValue) { \
+ /* Value level: assume unary operator. */ \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnary##op); \
+ *top_node_p = cur_node; \
+ kvi_push(ast_stack, &cur_node->children); \
+ HL_CUR_TOKEN(Unary##op); \
+ } else { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeBinary##op); \
+ ADD_OP_NODE(cur_node); \
+ HL_CUR_TOKEN(Binary##op); \
+ } \
+ want_node = kENodeValue; \
+ break; \
+ }
+ SIMPLE_UB_OP(Plus)
+ SIMPLE_UB_OP(Minus)
+#undef SIMPLE_UB_OP
+#define SIMPLE_B_OP(op, msg) \
+ case kExprLex##op: { \
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected " msg ": %.*s")); \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##op); \
+ HL_CUR_TOKEN(op); \
+ ADD_OP_NODE(cur_node); \
+ break; \
+ }
+ SIMPLE_B_OP(Or, "or operator")
+ SIMPLE_B_OP(And, "and operator")
+#undef SIMPLE_B_OP
+ case kExprLexMultiplication: {
+ ADD_VALUE_IF_MISSING(
+ _("E15: Unexpected multiplication-like operator: %.*s"));
+ switch (cur_token.data.mul.type) {
+#define MUL_OP(lex_op_tail, node_op_tail) \
+ case kExprLexMul##lex_op_tail: { \
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNode##node_op_tail); \
+ HL_CUR_TOKEN(node_op_tail); \
+ break; \
+ }
+ MUL_OP(Mul, Multiplication)
+ MUL_OP(Div, Division)
+ MUL_OP(Mod, Mod)
+#undef MUL_OP
+ }
+ ADD_OP_NODE(cur_node);
+ break;
+ }
+ case kExprLexOption: {
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeOption);
+ if (cur_token.type == kExprLexInvalid) {
+ assert(cur_token.len == 1
+ || (cur_token.len == 3
+ && pline.data[cur_token.start.col + 2] == ':'));
+ cur_node->data.opt.ident = (
+ pline.data + cur_token.start.col + cur_token.len);
+ cur_node->data.opt.ident_len = 0;
+ cur_node->data.opt.scope = (
+ cur_token.len == 3
+ ? (ExprOptScope)pline.data[cur_token.start.col + 1]
+ : kExprOptScopeUnspecified);
+ } else {
+ cur_node->data.opt.ident = cur_token.data.opt.name;
+ cur_node->data.opt.ident_len = cur_token.data.opt.len;
+ cur_node->data.opt.scope = cur_token.data.opt.scope;
+ }
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ viml_parser_highlight(pstate, cur_token.start, 1, HL(OptionSigil));
+ const size_t scope_shift = (
+ cur_token.data.opt.scope == kExprOptScopeUnspecified ? 0 : 2);
+ if (scope_shift) {
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
+ HL(OptionScope));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 2), 1,
+ HL(OptionScopeDelimiter));
+ }
+ viml_parser_highlight(
+ pstate, shifted_pos(cur_token.start, scope_shift + 1),
+ cur_token.len - (scope_shift + 1), HL(OptionName));
+ break;
+ }
+ case kExprLexEnv: {
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeEnvironment);
+ cur_node->data.env.ident = pline.data + cur_token.start.col + 1;
+ cur_node->data.env.ident_len = cur_token.len - 1;
+ if (cur_node->data.env.ident_len == 0) {
+ ERROR_FROM_TOKEN_AND_MSG(cur_token,
+ _("E15: Environment variable name missing"));
+ }
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ viml_parser_highlight(pstate, cur_token.start, 1, HL(EnvironmentSigil));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1),
+ cur_token.len - 1, HL(EnvironmentName));
+ break;
+ }
+ case kExprLexNot: {
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNot);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ HL_CUR_TOKEN(Not);
+ break;
+ }
+ case kExprLexComparison: {
+ ADD_VALUE_IF_MISSING(
+ _("E15: Expected value, got comparison operator: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComparison);
+ if (cur_token.type == kExprLexInvalid) {
+ cur_node->data.cmp.ccs = kCCStrategyUseOption;
+ cur_node->data.cmp.type = kExprCmpEqual;
+ cur_node->data.cmp.inv = false;
+ } else {
+ cur_node->data.cmp.ccs = cur_token.data.cmp.ccs;
+ cur_node->data.cmp.type = cur_token.data.cmp.type;
+ cur_node->data.cmp.inv = cur_token.data.cmp.inv;
+ }
+ ADD_OP_NODE(cur_node);
+ if (cur_token.data.cmp.ccs != kCCStrategyUseOption) {
+ viml_parser_highlight(pstate, cur_token.start, cur_token.len - 1,
+ HL(Comparison));
+ viml_parser_highlight(
+ pstate, shifted_pos(cur_token.start, cur_token.len - 1), 1,
+ HL(ComparisonModifier));
+ } else {
+ HL_CUR_TOKEN(Comparison);
+ }
+ want_node = kENodeValue;
+ break;
+ }
+ case kExprLexComma: {
+ assert(!(want_node == kENodeValue && cur_pt == kEPTLambdaArguments));
+ if (want_node == kENodeValue) {
+ // Value level: comma appearing here is not valid.
+ // Note: in Vim string(,x) will give E116, this is not the case here.
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E15: Expected value, got comma: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
+ cur_node->len = 0;
+ *top_node_p = cur_node;
+ want_node = kENodeOperator;
+ }
+ if (cur_pt == kEPTLambdaArguments) {
+ assert(lambda_node != NULL);
+ assert(lambda_node->data.fig.type_guesses.allow_lambda);
+ SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
+ }
+ if (kv_size(ast_stack) < 2) {
+ goto viml_pexpr_parse_invalid_comma;
+ }
+ for (size_t i = 1; i < kv_size(ast_stack); i++) {
+ ExprASTNode *const *const eastnode_p =
+ (ExprASTNode *const *)kv_Z(ast_stack, i);
+ const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
+ const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
+ if (eastnode_type == kExprNodeLambda) {
+ assert(cur_pt == kEPTLambdaArguments
+ && want_node == kENodeOperator);
+ break;
+ } else if (eastnode_type == kExprNodeDictLiteral
+ || eastnode_type == kExprNodeListLiteral
+ || eastnode_type == kExprNodeCall) {
+ break;
+ } else if (eastnode_type == kExprNodeComma
+ || eastnode_type == kExprNodeColon
+ || eastnode_lvl > kEOpLvlComma) {
+ // Do nothing
+ } else {
+viml_pexpr_parse_invalid_comma:
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E15: Comma outside of call, lambda or literal: %.*s"));
+ break;
+ }
+ if (i == kv_size(ast_stack) - 1) {
+ goto viml_pexpr_parse_invalid_comma;
+ }
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeComma);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Comma);
+ break;
+ }
+#define EXP_VAL_COLON "E15: Expected value, got colon: %.*s"
+ case kExprLexColon: {
+ bool is_ternary = false;
+ if (kv_size(ast_stack) < 2) {
+ goto viml_pexpr_parse_invalid_colon;
+ }
+ bool can_be_ternary = true;
+ bool is_subscript = false;
+ for (size_t i = 1; i < kv_size(ast_stack); i++) {
+ ExprASTNode *const *const eastnode_p =
+ (ExprASTNode *const *)kv_Z(ast_stack, i);
+ const ExprASTNodeType eastnode_type = (*eastnode_p)->type;
+ const ExprOpLvl eastnode_lvl = node_lvl(**eastnode_p);
+ STATIC_ASSERT(kEOpLvlTernary > kEOpLvlComma,
+ "Unexpected operator priorities");
+ if (can_be_ternary && eastnode_type == kExprNodeTernaryValue
+ && !(*eastnode_p)->data.ter.got_colon) {
+ kv_drop(ast_stack, i);
+ (*eastnode_p)->start = cur_token.start;
+ (*eastnode_p)->len = cur_token.len;
+ if (prev_token.type == kExprLexSpacing) {
+ (*eastnode_p)->start = prev_token.start;
+ (*eastnode_p)->len += prev_token.len;
+ }
+ is_ternary = true;
+ (*eastnode_p)->data.ter.got_colon = true;
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ assert((*eastnode_p)->children != NULL);
+ assert((*eastnode_p)->children->next == NULL);
+ kvi_push(ast_stack, &(*eastnode_p)->children->next);
+ break;
+ } else if (eastnode_type == kExprNodeUnknownFigure) {
+ SELECT_FIGURE_BRACE_TYPE(*eastnode_p, DictLiteral, Dict);
+ break;
+ } else if (eastnode_type == kExprNodeDictLiteral) {
+ break;
+ } else if (eastnode_type == kExprNodeSubscript) {
+ is_subscript = true;
+ can_be_ternary = false;
+ assert(!is_ternary);
+ break;
+ } else if (eastnode_type == kExprNodeColon) {
+ goto viml_pexpr_parse_invalid_colon;
+ } else if (eastnode_lvl >= kEOpLvlTernaryValue) {
+ // Do nothing
+ } else if (eastnode_lvl >= kEOpLvlComma) {
+ can_be_ternary = false;
+ } else {
+ goto viml_pexpr_parse_invalid_colon;
+ }
+ if (i == kv_size(ast_stack) - 1) {
+ goto viml_pexpr_parse_invalid_colon;
+ }
+ }
+ if (is_subscript) {
+ assert(kv_size(ast_stack) > 1);
+ // Colon immediately following subscript start: it is empty subscript
+ // part like a[:2].
+ if (want_node == kENodeValue
+ && (*kv_Z(ast_stack, 1))->type == kExprNodeSubscript) {
+ NEW_NODE_WITH_CUR_POS(*top_node_p, kExprNodeMissing);
+ (*top_node_p)->len = 0;
+ want_node = kENodeOperator;
+ } else {
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(SubscriptColon);
+ } else {
+ goto viml_pexpr_parse_valid_colon;
+viml_pexpr_parse_invalid_colon:
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E15: Colon outside of dictionary or ternary operator: %.*s"));
+viml_pexpr_parse_valid_colon:
+ ADD_VALUE_IF_MISSING(_(EXP_VAL_COLON));
+ if (is_ternary) {
+ HL_CUR_TOKEN(TernaryColon);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeColon);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Colon);
+ }
+ }
+ want_node = kENodeValue;
+ break;
+ }
+#undef EXP_VAL_COLON
+ case kExprLexBracket: {
+ if (cur_token.data.brc.closing) {
+ ExprASTNode **new_top_node_p = NULL;
+ // Always drop the topmost value:
+ //
+ // 1. When want_node != kENodeValue topmost item on stack is
+ // a *finished* left operand, which may as well be "{@a}" which
+ // needs not be finished again.
+ // 2. Otherwise it is pointing to NULL what nobody wants.
+ kv_drop(ast_stack, 1);
+ if (!kv_size(ast_stack)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
+ cur_node->len = 0;
+ if (want_node != kENodeValue) {
+ cur_node->children = *top_node_p;
+ }
+ *top_node_p = cur_node;
+ goto viml_pexpr_parse_bracket_closing_error;
+ }
+ if (want_node == kENodeValue) {
+ // It is OK to want value if
+ //
+ // 1. It is empty list literal, in which case top node will be
+ // ListLiteral.
+ // 2. It is list literal with trailing comma, in which case top node
+ // will be that comma.
+ // 3. It is subscript with colon, but without one of the values:
+ // e.g. "a[:]", "a[1:]", top node will be colon in this case.
+ if ((*kv_last(ast_stack))->type != kExprNodeListLiteral
+ && (*kv_last(ast_stack))->type != kExprNodeComma
+ && (*kv_last(ast_stack))->type != kExprNodeColon) {
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E15: Expected value, got closing bracket: %.*s"));
+ }
+ }
+ do {
+ new_top_node_p = kv_pop(ast_stack);
+ } while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeListLiteral
+ && (*new_top_node_p)->type != kExprNodeSubscript)));
+ ExprASTNode *new_top_node = *new_top_node_p;
+ switch (new_top_node->type) {
+ case kExprNodeListLiteral: {
+ if (pt_is_assignment(cur_pt) && new_top_node->children == NULL) {
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E475: Unable to assign to empty list: %.*s"));
+ }
+ HL_CUR_TOKEN(List);
+ break;
+ }
+ case kExprNodeSubscript: {
+ HL_CUR_TOKEN(SubscriptBracket);
+ break;
+ }
+ default: {
+viml_pexpr_parse_bracket_closing_error:
+ assert(!kv_size(ast_stack));
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E15: Unexpected closing figure brace: %.*s"));
+ HL_CUR_TOKEN(List);
+ break;
+ }
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ if (kv_size(ast_stack) <= asgn_level) {
+ assert(kv_size(ast_stack) == asgn_level);
+ asgn_level = 0;
+ if (cur_pt == kEPTAssignment) {
+ assert(ast.err.msg);
+ } else if (cur_pt == kEPTExpr
+ && kv_size(pt_stack) > 1
+ && pt_is_assignment(kv_Z(pt_stack, 1))) {
+ kv_drop(pt_stack, 1);
+ }
+ }
+ if (cur_pt == kEPTSingleAssignment && kv_size(ast_stack) == 1) {
+ kv_drop(pt_stack, 1);
+ }
+ } else {
+ if (want_node == kENodeValue) {
+ // Value means list literal or list assignment.
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeListLiteral);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ want_node = kENodeValue;
+ if (cur_pt == kEPTAssignment) {
+ // Additional assignment parse type allows to easily forbid nested
+ // lists.
+ kvi_push(pt_stack, kEPTSingleAssignment);
+ } else if (cur_pt == kEPTSingleAssignment) {
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E475: Nested lists not allowed when assigning: %.*s"));
+ }
+ HL_CUR_TOKEN(List);
+ } else {
+ // Operator means subscript, also in assignment. But in assignment
+ // subscript may be pretty much any expression, so need to push
+ // kEPTExpr.
+ if (prev_token.type == kExprLexSpacing) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeSubscript);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(SubscriptBracket);
+ if (pt_is_assignment(cur_pt)) {
+ assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
+ asgn_level = kv_size(ast_stack) - 1;
+ kvi_push(pt_stack, kEPTExpr);
+ }
+ }
+ }
+ break;
+ }
+ case kExprLexFigureBrace: {
+ if (cur_token.data.brc.closing) {
+ ExprASTNode **new_top_node_p = NULL;
+ // Always drop the topmost value:
+ //
+ // 1. When want_node != kENodeValue topmost item on stack is
+ // a *finished* left operand, which may as well be "{@a}" which
+ // needs not be finished again.
+ // 2. Otherwise it is pointing to NULL what nobody wants.
+ kv_drop(ast_stack, 1);
+ if (!kv_size(ast_stack)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
+ cur_node->data.fig.type_guesses.allow_lambda = false;
+ cur_node->data.fig.type_guesses.allow_dict = false;
+ cur_node->data.fig.type_guesses.allow_ident = false;
+ cur_node->len = 0;
+ if (want_node != kENodeValue) {
+ cur_node->children = *top_node_p;
+ }
+ *top_node_p = cur_node;
+ new_top_node_p = top_node_p;
+ goto viml_pexpr_parse_figure_brace_closing_error;
+ }
+ if (want_node == kENodeValue) {
+ if ((*kv_last(ast_stack))->type != kExprNodeUnknownFigure
+ && (*kv_last(ast_stack))->type != kExprNodeComma) {
+ // kv_last being UnknownFigure may occur for empty dictionary
+ // literal, while Comma is expected in case of non-empty one.
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E15: Expected value, got closing figure brace: %.*s"));
+ }
+ }
+ do {
+ new_top_node_p = kv_pop(ast_stack);
+ } while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeUnknownFigure
+ && (*new_top_node_p)->type != kExprNodeDictLiteral
+ && ((*new_top_node_p)->type
+ != kExprNodeCurlyBracesIdentifier)
+ && (*new_top_node_p)->type != kExprNodeLambda)));
+ ExprASTNode *new_top_node = *new_top_node_p;
+ switch (new_top_node->type) {
+ case kExprNodeUnknownFigure: {
+ if (new_top_node->children == NULL) {
+ // No children of curly braces node indicates empty dictionary.
+ assert(want_node == kENodeValue);
+ assert(new_top_node->data.fig.type_guesses.allow_dict);
+ SELECT_FIGURE_BRACE_TYPE(new_top_node, DictLiteral, Dict);
+ HL_CUR_TOKEN(Dict);
+ } else if (new_top_node->data.fig.type_guesses.allow_ident) {
+ SELECT_FIGURE_BRACE_TYPE(new_top_node, CurlyBracesIdentifier,
+ Curly);
+ HL_CUR_TOKEN(Curly);
+ } else {
+ // If by this time type of the node has not already been
+ // guessed, but it definitely is not a curly braces name then
+ // it is invalid for sure.
+ ERROR_FROM_NODE_AND_MSG(
+ new_top_node,
+ _("E15: Don't know what figure brace means: %.*s"));
+ if (pstate->colors) {
+ // Will reset to NvimInvalidFigureBrace.
+ kv_A(*pstate->colors,
+ new_top_node->data.fig.opening_hl_idx).group = (
+ HL(FigureBrace));
+ }
+ HL_CUR_TOKEN(FigureBrace);
+ }
+ break;
+ }
+ case kExprNodeDictLiteral: {
+ HL_CUR_TOKEN(Dict);
+ break;
+ }
+ case kExprNodeCurlyBracesIdentifier: {
+ HL_CUR_TOKEN(Curly);
+ break;
+ }
+ case kExprNodeLambda: {
+ HL_CUR_TOKEN(Lambda);
+ break;
+ }
+ default: {
+viml_pexpr_parse_figure_brace_closing_error:
+ assert(!kv_size(ast_stack));
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E15: Unexpected closing figure brace: %.*s"));
+ HL_CUR_TOKEN(FigureBrace);
+ break;
+ }
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ if (kv_size(ast_stack) <= asgn_level) {
+ assert(kv_size(ast_stack) == asgn_level);
+ if (cur_pt == kEPTExpr
+ && kv_size(pt_stack) > 1
+ && pt_is_assignment(kv_Z(pt_stack, 1))) {
+ kv_drop(pt_stack, 1);
+ asgn_level = 0;
+ }
+ }
+ } else {
+ if (want_node == kENodeValue) {
+ HL_CUR_TOKEN(FigureBrace);
+ // Value: may be any of lambda, dictionary literal and curly braces
+ // name.
+
+ // Though if we are in an assignment this may only be a curly braces
+ // name.
+ if (pt_is_assignment(cur_pt)) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCurlyBracesIdentifier);
+ cur_node->data.fig.type_guesses.allow_lambda = false;
+ cur_node->data.fig.type_guesses.allow_dict = false;
+ cur_node->data.fig.type_guesses.allow_ident = true;
+ kvi_push(pt_stack, kEPTExpr);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeUnknownFigure);
+ cur_node->data.fig.type_guesses.allow_lambda = true;
+ cur_node->data.fig.type_guesses.allow_dict = true;
+ cur_node->data.fig.type_guesses.allow_ident = true;
+ }
+ if (pstate->colors) {
+ cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors) - 1;
+ }
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ kvi_push(pt_stack, kEPTLambdaArguments);
+ lambda_node = cur_node;
+ } else {
+ ADD_IDENT(
+ do {
+ NEW_NODE_WITH_CUR_POS(cur_node,
+ kExprNodeCurlyBracesIdentifier);
+ cur_node->data.fig.opening_hl_idx = kv_size(*pstate->colors);
+ cur_node->data.fig.type_guesses.allow_lambda = false;
+ cur_node->data.fig.type_guesses.allow_dict = false;
+ cur_node->data.fig.type_guesses.allow_ident = true;
+ kvi_push(ast_stack, &cur_node->children);
+ if (pt_is_assignment(cur_pt)) {
+ kvi_push(pt_stack, kEPTExpr);
+ }
+ want_node = kENodeValue;
+ } while (0),
+ Curly);
+ }
+ if (pt_is_assignment(cur_pt)
+ && !pt_is_assignment(kv_last(pt_stack))) {
+ assert(want_node == kENodeValue); // Subtract 1 for NULL at top.
+ asgn_level = kv_size(ast_stack) - 1;
+ }
+ }
+ break;
+ }
+ case kExprLexArrow: {
+ if (cur_pt == kEPTLambdaArguments) {
+ kv_drop(pt_stack, 1);
+ assert(kv_size(pt_stack));
+ if (want_node == kENodeValue) {
+ // Wanting value means trailing comma and NULL at the top of the
+ // stack.
+ kv_drop(ast_stack, 1);
+ }
+ assert(kv_size(ast_stack) >= 1);
+ while ((*kv_last(ast_stack))->type != kExprNodeLambda
+ && (*kv_last(ast_stack))->type != kExprNodeUnknownFigure) {
+ kv_drop(ast_stack, 1);
+ }
+ assert((*kv_last(ast_stack)) == lambda_node);
+ SELECT_FIGURE_BRACE_TYPE(lambda_node, Lambda, Lambda);
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
+ if (lambda_node->children == NULL) {
+ assert(want_node == kENodeValue);
+ lambda_node->children = cur_node;
+ kvi_push(ast_stack, &lambda_node->children);
+ } else {
+ assert(lambda_node->children->next == NULL);
+ lambda_node->children->next = cur_node;
+ kvi_push(ast_stack, &lambda_node->children->next);
+ }
+ kvi_push(ast_stack, &cur_node->children);
+ lambda_node = NULL;
+ } else {
+ // Only first branch is valid.
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected arrow: %.*s"));
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E15: Arrow outside of lambda: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeArrow);
+ ADD_OP_NODE(cur_node);
+ }
+ want_node = kENodeValue;
+ HL_CUR_TOKEN(Arrow);
+ break;
+ }
+ case kExprLexPlainIdentifier: {
+ const ExprVarScope scope = (cur_token.type == kExprLexInvalid
+ ? kExprVarScopeMissing
+ : cur_token.data.var.scope);
+ if (want_node == kENodeValue) {
+ want_node = kENodeOperator;
+ NEW_NODE_WITH_CUR_POS(cur_node,
+ (node_is_key
+ ? kExprNodePlainKey
+ : kExprNodePlainIdentifier));
+ cur_node->data.var.scope = scope;
+ const size_t scope_shift = (scope == kExprVarScopeMissing ? 0 : 2);
+ cur_node->data.var.ident = (pline.data + cur_token.start.col
+ + scope_shift);
+ cur_node->data.var.ident_len = cur_token.len - scope_shift;
+ *top_node_p = cur_node;
+ if (scope_shift) {
+ assert(!node_is_key);
+ viml_parser_highlight(pstate, cur_token.start, 1,
+ HL(IdentifierScope));
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start, 1), 1,
+ HL(IdentifierScopeDelimiter));
+ }
+ viml_parser_highlight(pstate, shifted_pos(cur_token.start,
+ scope_shift),
+ cur_token.len - scope_shift,
+ (node_is_key
+ ? HL(IdentifierKey)
+ : HL(IdentifierName)));
+ } else {
+ if (scope == kExprVarScopeMissing) {
+ ADD_IDENT(
+ do {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainIdentifier);
+ cur_node->data.var.scope = scope;
+ cur_node->data.var.ident = pline.data + cur_token.start.col;
+ cur_node->data.var.ident_len = cur_token.len;
+ want_node = kENodeOperator;
+ } while (0),
+ IdentifierName);
+ } else {
+ OP_MISSING;
+ }
+ }
+ break;
+ }
+ case kExprLexNumber: {
+ if (want_node != kENodeValue) {
+ OP_MISSING;
+ }
+ if (node_is_key) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodePlainKey);
+ cur_node->data.var.ident = pline.data + cur_token.start.col;
+ cur_node->data.var.ident_len = cur_token.len;
+ HL_CUR_TOKEN(IdentifierKey);
+ } else if (cur_token.data.num.is_float) {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeFloat);
+ cur_node->data.flt.value = cur_token.data.num.val.floating;
+ HL_CUR_TOKEN(Float);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeInteger);
+ cur_node->data.num.value = cur_token.data.num.val.integer;
+ const uint8_t prefix_length = base_to_prefix_length[
+ cur_token.data.num.base];
+ viml_parser_highlight(pstate, cur_token.start, prefix_length,
+ HL(NumberPrefix));
+ viml_parser_highlight(
+ pstate, shifted_pos(cur_token.start, prefix_length),
+ cur_token.len - prefix_length, HL(Number));
+ }
+ want_node = kENodeOperator;
+ *top_node_p = cur_node;
+ break;
+ }
+ case kExprLexDot: {
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected dot: %.*s"));
+ if (prev_token.type == kExprLexSpacing) {
+ if (cur_pt == kEPTAssignment) {
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E15: Cannot concatenate in assignments: %.*s"));
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcat);
+ HL_CUR_TOKEN(Concat);
+ } else {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeConcatOrSubscript);
+ HL_CUR_TOKEN(ConcatOrSubscript);
+ }
+ ADD_OP_NODE(cur_node);
+ break;
+ }
+ case kExprLexParenthesis: {
+ if (cur_token.data.brc.closing) {
+ if (want_node == kENodeValue) {
+ if (kv_size(ast_stack) > 1) {
+ const ExprASTNode *const prev_top_node = *kv_Z(ast_stack, 1);
+ if (prev_top_node->type == kExprNodeCall) {
+ // Function call without arguments, this is not an error.
+ // But further code does not expect NULL nodes.
+ kv_drop(ast_stack, 1);
+ goto viml_pexpr_parse_no_paren_closing_error;
+ }
+ }
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E15: Expected value, got parenthesis: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeMissing);
+ cur_node->len = 0;
+ *top_node_p = cur_node;
+ } else {
+ // Always drop the topmost value: when want_node != kENodeValue
+ // topmost item on stack is a *finished* left operand, which may as
+ // well be "(@a)" which needs not be finished again.
+ kv_drop(ast_stack, 1);
+ }
+viml_pexpr_parse_no_paren_closing_error: {}
+ ExprASTNode **new_top_node_p = NULL;
+ while (kv_size(ast_stack)
+ && (new_top_node_p == NULL
+ || ((*new_top_node_p)->type != kExprNodeNested
+ && (*new_top_node_p)->type != kExprNodeCall))) {
+ new_top_node_p = kv_pop(ast_stack);
+ }
+ if (new_top_node_p != NULL
+ && ((*new_top_node_p)->type == kExprNodeNested
+ || (*new_top_node_p)->type == kExprNodeCall)) {
+ if ((*new_top_node_p)->type == kExprNodeNested) {
+ HL_CUR_TOKEN(NestingParenthesis);
+ } else {
+ HL_CUR_TOKEN(CallingParenthesis);
+ }
+ } else {
+ // “Always drop the topmost value†branch has got rid of the single
+ // value stack had, so there is nothing known to enclose. Correct
+ // this.
+ if (new_top_node_p == NULL) {
+ new_top_node_p = top_node_p;
+ }
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E15: Unexpected closing parenthesis: %.*s"));
+ HL_CUR_TOKEN(NestingParenthesis);
+ cur_node = NEW_NODE(kExprNodeNested);
+ cur_node->start = cur_token.start;
+ cur_node->len = 0;
+ // Unexpected closing parenthesis, assume that it was wanted to
+ // enclose everything in ().
+ cur_node->children = *new_top_node_p;
+ *new_top_node_p = cur_node;
+ assert(cur_node->next == NULL);
+ }
+ kvi_push(ast_stack, new_top_node_p);
+ want_node = kENodeOperator;
+ } else {
+ switch (want_node) {
+ case kENodeValue: {
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeNested);
+ *top_node_p = cur_node;
+ kvi_push(ast_stack, &cur_node->children);
+ HL_CUR_TOKEN(NestingParenthesis);
+ break;
+ }
+ case kENodeOperator: {
+ if (prev_token.type == kExprLexSpacing) {
+ // For some reason "function (args)" is a function call, but
+ // "(funcref) (args)" is not. AFAIR this somehow involves
+ // compatibility and Bram was commenting that this is
+ // intentionally inconsistent and he is not very happy with the
+ // situation himself.
+ if ((*top_node_p)->type != kExprNodePlainIdentifier
+ && (*top_node_p)->type != kExprNodeComplexIdentifier
+ && (*top_node_p)->type != kExprNodeCurlyBracesIdentifier) {
+ OP_MISSING;
+ }
+ }
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeCall);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(CallingParenthesis);
+ break;
+ }
+ }
+ want_node = kENodeValue;
+ }
+ break;
+ }
+ case kExprLexQuestion: {
+ ADD_VALUE_IF_MISSING(_("E15: Expected value, got question mark: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeTernary);
+ ADD_OP_NODE(cur_node);
+ HL_CUR_TOKEN(Ternary);
+ ExprASTNode *ter_val_node;
+ NEW_NODE_WITH_CUR_POS(ter_val_node, kExprNodeTernaryValue);
+ ter_val_node->data.ter.got_colon = false;
+ assert(cur_node->children != NULL);
+ assert(cur_node->children->next == NULL);
+ assert(kv_last(ast_stack) == &cur_node->children->next);
+ *kv_last(ast_stack) = ter_val_node;
+ kvi_push(ast_stack, &ter_val_node->children);
+ break;
+ }
+ case kExprLexDoubleQuotedString:
+ case kExprLexSingleQuotedString: {
+ const bool is_double = (tok_type == kExprLexDoubleQuotedString);
+ if (!cur_token.data.str.closed) {
+ // It is weird, but Vim has two identical errors messages with
+ // different error numbers: "E114: Missing quote" and
+ // "E115: Missing quote".
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, (is_double
+ ? _("E114: Missing double quote: %.*s")
+ : _("E115: Missing single quote: %.*s")));
+ }
+ if (want_node == kENodeOperator) {
+ OP_MISSING;
+ }
+ NEW_NODE_WITH_CUR_POS(
+ cur_node, (is_double
+ ? kExprNodeDoubleQuotedString
+ : kExprNodeSingleQuotedString));
+ *top_node_p = cur_node;
+ parse_quoted_string(pstate, cur_node, cur_token, ast_stack, is_invalid);
+ want_node = kENodeOperator;
+ break;
+ }
+ case kExprLexAssignment: {
+ if (cur_pt == kEPTAssignment) {
+ kv_drop(pt_stack, 1);
+ } else if (cur_pt == kEPTSingleAssignment) {
+ kv_drop(pt_stack, 2);
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token,
+ _("E475: Expected closing bracket to end list assignment "
+ "lvalue: %.*s"));
+ } else {
+ ERROR_FROM_TOKEN_AND_MSG(
+ cur_token, _("E15: Misplaced assignment: %.*s"));
+ }
+ assert(kv_size(pt_stack));
+ assert(kv_last(pt_stack) == kEPTExpr);
+ ADD_VALUE_IF_MISSING(_("E15: Unexpected assignment: %.*s"));
+ NEW_NODE_WITH_CUR_POS(cur_node, kExprNodeAssignment);
+ cur_node->data.ass.type = cur_token.data.ass.type;
+ switch (cur_token.data.ass.type) {
+#define HL_ASGN(asgn, hl) \
+ case kExprAsgn##asgn: { HL_CUR_TOKEN(hl); break; }
+ HL_ASGN(Plain, PlainAssignment)
+ HL_ASGN(Add, AssignmentWithAddition)
+ HL_ASGN(Subtract, AssignmentWithSubtraction)
+ HL_ASGN(Concat, AssignmentWithConcatenation)
+#undef HL_ASGN
+ }
+ ADD_OP_NODE(cur_node);
+ break;
+ }
+ }
+viml_pexpr_parse_cycle_end:
+ prev_token = cur_token;
+ highlighted_prev_spacing = false;
+ viml_parser_advance(pstate, cur_token.len);
+ } while (true);
+viml_pexpr_parse_end:
+ assert(kv_size(pt_stack));
+ assert(kv_size(ast_stack));
+ if (want_node == kENodeValue
+ // Blacklist some parse type entries as their presence means better error
+ // message in the other branch.
+ && kv_last(pt_stack) != kEPTLambdaArguments) {
+ east_set_error(pstate, &ast.err, _("E15: Expected value, got EOC: %.*s"),
+ pstate->pos);
+ } else if (kv_size(ast_stack) != 1) {
+ // Something may be wrong, check whether it really is.
+
+ // Pointer to ast.root must never be dropped, so “!= 1†is expected to be
+ // the same as “> 1â€.
+ assert(kv_size(ast_stack));
+ // Topmost stack item must be a *finished* value, so it must not be
+ // analyzed. E.g. it may contain an already finished nested expression.
+ kv_drop(ast_stack, 1);
+ while (ast.err.msg == NULL && kv_size(ast_stack)) {
+ const ExprASTNode *const cur_node = (*kv_pop(ast_stack));
+ // This should only happen when want_node == kENodeValue.
+ assert(cur_node != NULL);
+ // TODO(ZyX-I): Rehighlight as invalid?
+ switch (cur_node->type) {
+ case kExprNodeOpMissing:
+ case kExprNodeMissing: {
+ // Error should’ve been already reported.
+ break;
+ }
+ case kExprNodeCall: {
+ east_set_error(
+ pstate, &ast.err,
+ _("E116: Missing closing parenthesis for function call: %.*s"),
+ cur_node->start);
+ break;
+ }
+ case kExprNodeNested: {
+ east_set_error(
+ pstate, &ast.err,
+ _("E110: Missing closing parenthesis for nested expression"
+ ": %.*s"),
+ cur_node->start);
+ break;
+ }
+ case kExprNodeListLiteral: {
+ // For whatever reason "[1" yields "E696: Missing comma in list" error
+ // in Vim while "[1," yields E697.
+ east_set_error(
+ pstate, &ast.err,
+ _("E697: Missing end of List ']': %.*s"),
+ cur_node->start);
+ break;
+ }
+ case kExprNodeDictLiteral: {
+ // Same problem like with list literal with E722 (missing comma) vs
+ // E723, but additionally just "{" yields only E15.
+ east_set_error(
+ pstate, &ast.err,
+ _("E723: Missing end of Dictionary '}': %.*s"),
+ cur_node->start);
+ break;
+ }
+ case kExprNodeUnknownFigure: {
+ east_set_error(
+ pstate, &ast.err,
+ _("E15: Missing closing figure brace: %.*s"),
+ cur_node->start);
+ break;
+ }
+ case kExprNodeLambda: {
+ east_set_error(
+ pstate, &ast.err,
+ _("E15: Missing closing figure brace for lambda: %.*s"),
+ cur_node->start);
+ break;
+ }
+ case kExprNodeCurlyBracesIdentifier: {
+ // Until trailing "}" it is impossible to distinguish curly braces
+ // identifier and dictionary, so it must not appear in the stack like
+ // this.
+ assert(false);
+ }
+ case kExprNodeInteger:
+ case kExprNodeFloat:
+ case kExprNodeSingleQuotedString:
+ case kExprNodeDoubleQuotedString:
+ case kExprNodeOption:
+ case kExprNodeEnvironment:
+ case kExprNodeRegister:
+ case kExprNodePlainIdentifier:
+ case kExprNodePlainKey: {
+ // These are plain values and not containers, for them it should only
+ // be possible to show up in the topmost stack element, but it was
+ // unconditionally popped at the start.
+ assert(false);
+ }
+ case kExprNodeComma:
+ case kExprNodeColon:
+ case kExprNodeArrow: {
+ // It is actually only valid inside something else, but everything
+ // where one of the above is valid requires to be closed and thus is
+ // to be caught later.
+ break;
+ }
+ case kExprNodeSubscript:
+ case kExprNodeConcatOrSubscript:
+ case kExprNodeComplexIdentifier:
+ case kExprNodeAssignment:
+ case kExprNodeMod:
+ case kExprNodeDivision:
+ case kExprNodeMultiplication:
+ case kExprNodeNot:
+ case kExprNodeAnd:
+ case kExprNodeOr:
+ case kExprNodeConcat:
+ case kExprNodeComparison:
+ case kExprNodeUnaryMinus:
+ case kExprNodeUnaryPlus:
+ case kExprNodeBinaryMinus:
+ case kExprNodeTernary:
+ case kExprNodeBinaryPlus: {
+ // It is OK to see these in the stack.
+ break;
+ }
+ case kExprNodeTernaryValue: {
+ if (!cur_node->data.ter.got_colon) {
+ // Actually Vim throws E109 in more cases.
+ east_set_error(
+ pstate, &ast.err, _("E109: Missing ':' after '?': %.*s"),
+ cur_node->start);
+ }
+ break;
+ }
+ }
+ }
+ }
+ kvi_destroy(ast_stack);
+ return ast;
+} // NOLINT(readability/fn_size)
+
+#undef NEW_NODE
+#undef HL
diff --git a/src/nvim/viml/parser/expressions.h b/src/nvim/viml/parser/expressions.h
new file mode 100644
index 0000000000..23e172da75
--- /dev/null
+++ b/src/nvim/viml/parser/expressions.h
@@ -0,0 +1,389 @@
+#ifndef NVIM_VIML_PARSER_EXPRESSIONS_H
+#define NVIM_VIML_PARSER_EXPRESSIONS_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nvim/types.h"
+#include "nvim/viml/parser/parser.h"
+#include "nvim/eval/typval.h"
+
+// Defines whether to ignore case:
+// == kCCStrategyUseOption
+// ==# kCCStrategyMatchCase
+// ==? kCCStrategyIgnoreCase
+typedef enum {
+ kCCStrategyUseOption = 0, // 0 for xcalloc
+ kCCStrategyMatchCase = '#',
+ kCCStrategyIgnoreCase = '?',
+} ExprCaseCompareStrategy;
+
+/// Lexer token type
+typedef enum {
+ kExprLexInvalid = 0, ///< Invalid token, indicaten an error.
+ kExprLexMissing, ///< Missing token, for use in parser.
+ kExprLexSpacing, ///< Spaces, tabs, newlines, etc.
+ kExprLexEOC, ///< End of command character: NL, |, just end of stream.
+
+ kExprLexQuestion, ///< Question mark, for use in ternary.
+ kExprLexColon, ///< Colon, for use in ternary.
+ kExprLexOr, ///< Logical or operator.
+ kExprLexAnd, ///< Logical and operator.
+ kExprLexComparison, ///< One of the comparison operators.
+ kExprLexPlus, ///< Plus sign.
+ kExprLexMinus, ///< Minus sign.
+ kExprLexDot, ///< Dot: either concat or subscript, also part of the float.
+ kExprLexMultiplication, ///< Multiplication, division or modulo operator.
+
+ kExprLexNot, ///< Not: !.
+
+ kExprLexNumber, ///< Integer number literal, or part of a float.
+ kExprLexSingleQuotedString, ///< Single quoted string literal.
+ kExprLexDoubleQuotedString, ///< Double quoted string literal.
+ kExprLexOption, ///< &optionname option value.
+ kExprLexRegister, ///< @r register value.
+ kExprLexEnv, ///< Environment $variable value.
+ kExprLexPlainIdentifier, ///< Identifier without scope: `abc`, `foo#bar`.
+
+ kExprLexBracket, ///< Bracket, either opening or closing.
+ kExprLexFigureBrace, ///< Figure brace, either opening or closing.
+ kExprLexParenthesis, ///< Parenthesis, either opening or closing.
+ kExprLexComma, ///< Comma.
+ kExprLexArrow, ///< Arrow, like from lambda expressions.
+ kExprLexAssignment, ///< Assignment: `=` or `{op}=`.
+ // XXX When modifying this enum you need to also modify eltkn_type_tab in
+ // expressions.c and tests and, possibly, viml_pexpr_repr_token.
+} LexExprTokenType;
+
+typedef enum {
+ kExprCmpEqual, ///< Equality, unequality.
+ kExprCmpMatches, ///< Matches regex, not matches regex.
+ kExprCmpGreater, ///< `>` or `<=`
+ kExprCmpGreaterOrEqual, ///< `>=` or `<`.
+ kExprCmpIdentical, ///< `is` or `isnot`
+} ExprComparisonType;
+
+/// All possible option scopes
+typedef enum {
+ kExprOptScopeUnspecified = 0,
+ kExprOptScopeGlobal = 'g',
+ kExprOptScopeLocal = 'l',
+} ExprOptScope;
+
+/// All possible assignment types: `=` and `{op}=`.
+typedef enum {
+ kExprAsgnPlain = 0, ///< Plain assignment: `=`.
+ kExprAsgnAdd, ///< Assignment augmented with addition: `+=`.
+ kExprAsgnSubtract, ///< Assignment augmented with subtraction: `-=`.
+ kExprAsgnConcat, ///< Assignment augmented with concatenation: `.=`.
+} ExprAssignmentType;
+
+#define EXPR_OPT_SCOPE_LIST \
+ ((char[]){ kExprOptScopeGlobal, kExprOptScopeLocal })
+
+/// All possible variable scopes
+typedef enum {
+ kExprVarScopeMissing = 0,
+ kExprVarScopeScript = 's',
+ kExprVarScopeGlobal = 'g',
+ kExprVarScopeVim = 'v',
+ kExprVarScopeBuffer = 'b',
+ kExprVarScopeWindow = 'w',
+ kExprVarScopeTabpage = 't',
+ kExprVarScopeLocal = 'l',
+ kExprVarScopeArguments = 'a',
+} ExprVarScope;
+
+#define EXPR_VAR_SCOPE_LIST \
+ ((char[]) { \
+ kExprVarScopeScript, kExprVarScopeGlobal, kExprVarScopeVim, \
+ kExprVarScopeBuffer, kExprVarScopeWindow, kExprVarScopeTabpage, \
+ kExprVarScopeLocal, kExprVarScopeBuffer, kExprVarScopeArguments, \
+ })
+
+/// Lexer token
+typedef struct {
+ ParserPosition start;
+ size_t len;
+ LexExprTokenType type;
+ union {
+ struct {
+ ExprComparisonType type; ///< Comparison type.
+ ExprCaseCompareStrategy ccs; ///< Case comparison strategy.
+ bool inv; ///< True if comparison is to be inverted.
+ } cmp; ///< For kExprLexComparison.
+
+ struct {
+ enum {
+ kExprLexMulMul, ///< Real multiplication.
+ kExprLexMulDiv, ///< Division.
+ kExprLexMulMod, ///< Modulo.
+ } type; ///< Multiplication type.
+ } mul; ///< For kExprLexMultiplication.
+
+ struct {
+ bool closing; ///< True if bracket/etc is a closing one.
+ } brc; ///< For brackets/braces/parenthesis.
+
+ struct {
+ int name; ///< Register name, may be -1 if name not present.
+ } reg; ///< For kExprLexRegister.
+
+ struct {
+ bool closed; ///< True if quote was closed.
+ } str; ///< For kExprLexSingleQuotedString and kExprLexDoubleQuotedString.
+
+ struct {
+ const char *name; ///< Option name start.
+ size_t len; ///< Option name length.
+ ExprOptScope scope; ///< Option scope: &l:, &g: or not specified.
+ } opt; ///< Option properties.
+
+ struct {
+ ExprVarScope scope; ///< Scope character or 0 if not present.
+ bool autoload; ///< Has autoload characters.
+ } var; ///< For kExprLexPlainIdentifier
+
+ struct {
+ LexExprTokenType type; ///< Suggested type for parsing incorrect code.
+ const char *msg; ///< Error message.
+ } err; ///< For kExprLexInvalid
+
+ struct {
+ union {
+ float_T floating;
+ uvarnumber_T integer;
+ } val; ///< Number value.
+ uint8_t base; ///< Base: 2, 8, 10 or 16.
+ bool is_float; ///< True if number is a floating-point.
+ } num; ///< For kExprLexNumber
+
+ struct {
+ ExprAssignmentType type;
+ } ass; ///< For kExprLexAssignment
+ } data; ///< Additional data, if needed.
+} LexExprToken;
+
+typedef enum {
+ /// If set, “pointer†to the current byte in pstate will not be shifted
+ kELFlagPeek = (1 << 0),
+ /// Determines whether scope is allowed to come before the identifier
+ kELFlagForbidScope = (1 << 1),
+ /// Determines whether floating-point numbers are allowed
+ ///
+ /// I.e. whether dot is a decimal point separator or is not a part of
+ /// a number at all.
+ kELFlagAllowFloat = (1 << 2),
+ /// Determines whether `is` and `isnot` are seen as comparison operators
+ ///
+ /// If set they are supposed to be just regular identifiers.
+ kELFlagIsNotCmp = (1 << 3),
+ /// Determines whether EOC tokens are allowed
+ ///
+ /// If set then it will yield Invalid token with E15 in place of EOC one if
+ /// “EOC†is something like "|". It is fine with emitting EOC at the end of
+ /// string still, with or without this flag set.
+ kELFlagForbidEOC = (1 << 4),
+ // XXX Whenever you add a new flag, alter klee_assume() statement in
+ // viml_expressions_lexer.c.
+} LexExprFlags;
+
+/// Expression AST node type
+typedef enum {
+ kExprNodeMissing = 0,
+ kExprNodeOpMissing,
+ kExprNodeTernary, ///< Ternary operator.
+ kExprNodeTernaryValue, ///< Ternary operator, colon.
+ kExprNodeRegister, ///< Register.
+ kExprNodeSubscript, ///< Subscript.
+ kExprNodeListLiteral, ///< List literal.
+ kExprNodeUnaryPlus,
+ kExprNodeBinaryPlus,
+ kExprNodeNested, ///< Nested parenthesised expression.
+ kExprNodeCall, ///< Function call.
+ /// Plain identifier: simple variable/function name
+ ///
+ /// Looks like "string", "g:Foo", etc: consists from a single
+ /// kExprLexPlainIdentifier token.
+ kExprNodePlainIdentifier,
+ /// Plain dictionary key, for use with kExprNodeConcatOrSubscript
+ kExprNodePlainKey,
+ /// Complex identifier: variable/function name with curly braces
+ kExprNodeComplexIdentifier,
+ /// Figure brace expression which is not yet known
+ ///
+ /// May resolve to any of kExprNodeDictLiteral, kExprNodeLambda or
+ /// kExprNodeCurlyBracesIdentifier.
+ kExprNodeUnknownFigure,
+ kExprNodeLambda, ///< Lambda.
+ kExprNodeDictLiteral, ///< Dictionary literal.
+ kExprNodeCurlyBracesIdentifier, ///< Part of the curly braces name.
+ kExprNodeComma, ///< Comma “operatorâ€.
+ kExprNodeColon, ///< Colon “operatorâ€.
+ kExprNodeArrow, ///< Arrow “operatorâ€.
+ kExprNodeComparison, ///< Various comparison operators.
+ /// Concat operator
+ ///
+ /// To be only used in cases when it is known for sure it is not a subscript.
+ kExprNodeConcat,
+ /// Concat or subscript operator
+ ///
+ /// For cases when it is not obvious whether expression is a concat or
+ /// a subscript. May only have either number or plain identifier as the second
+ /// child. To make it easier to avoid curly braces in place of
+ /// kExprNodePlainIdentifier node kExprNodePlainKey is used.
+ kExprNodeConcatOrSubscript,
+ kExprNodeInteger, ///< Integral number.
+ kExprNodeFloat, ///< Floating-point number.
+ kExprNodeSingleQuotedString,
+ kExprNodeDoubleQuotedString,
+ kExprNodeOr,
+ kExprNodeAnd,
+ kExprNodeUnaryMinus,
+ kExprNodeBinaryMinus,
+ kExprNodeNot,
+ kExprNodeMultiplication,
+ kExprNodeDivision,
+ kExprNodeMod,
+ kExprNodeOption,
+ kExprNodeEnvironment,
+ kExprNodeAssignment,
+ // XXX When modifying this list also modify east_node_type_tab both in parser
+ // and in tests, and you most likely will also have to alter list of
+ // highlight groups stored in highlight_init_cmdline variable.
+} ExprASTNodeType;
+
+typedef struct expr_ast_node ExprASTNode;
+
+/// Structure representing one AST node
+struct expr_ast_node {
+ ExprASTNodeType type; ///< Node type.
+ /// Node children: e.g. for 1 + 2 nodes 1 and 2 will be children of +.
+ ExprASTNode *children;
+ /// Next node: e.g. for 1 + 2 child nodes 1 and 2 are put into a single-linked
+ /// list: `(+)->children` references only node 1, node 2 is in
+ /// `(+)->children->next`.
+ ExprASTNode *next;
+ ParserPosition start;
+ size_t len;
+ union {
+ struct {
+ int name; ///< Register name, may be -1 if name not present.
+ } reg; ///< For kExprNodeRegister.
+ struct {
+ /// Which nodes UnknownFigure can’t possibly represent.
+ struct {
+ /// True if UnknownFigure may actually represent dictionary literal.
+ bool allow_dict;
+ /// True if UnknownFigure may actually represent lambda.
+ bool allow_lambda;
+ /// True if UnknownFigure may actually be part of curly braces name.
+ bool allow_ident;
+ } type_guesses;
+ /// Highlight chunk index, used for rehighlighting if needed
+ size_t opening_hl_idx;
+ } fig; ///< For kExprNodeUnknownFigure.
+ struct {
+ ExprVarScope scope; ///< Scope character or 0 if not present.
+ /// Actual identifier without scope.
+ ///
+ /// Points to inside parser reader state.
+ const char *ident;
+ size_t ident_len; ///< Actual identifier length.
+ } var; ///< For kExprNodePlainIdentifier and kExprNodePlainKey.
+ struct {
+ bool got_colon; ///< True if colon was seen.
+ } ter; ///< For kExprNodeTernaryValue.
+ struct {
+ ExprComparisonType type; ///< Comparison type.
+ ExprCaseCompareStrategy ccs; ///< Case comparison strategy.
+ bool inv; ///< True if comparison is to be inverted.
+ } cmp; ///< For kExprNodeComparison.
+ struct {
+ uvarnumber_T value;
+ } num; ///< For kExprNodeInteger.
+ struct {
+ float_T value;
+ } flt; ///< For kExprNodeFloat.
+ struct {
+ char *value;
+ size_t size;
+ } str; ///< For kExprNodeSingleQuotedString and
+ ///< kExprNodeDoubleQuotedString.
+ struct {
+ const char *ident; ///< Option name start.
+ size_t ident_len; ///< Option name length.
+ ExprOptScope scope; ///< Option scope: &l:, &g: or not specified.
+ } opt; ///< For kExprNodeOption.
+ struct {
+ const char *ident; ///< Environment variable name start.
+ size_t ident_len; ///< Environment variable name length.
+ } env; ///< For kExprNodeEnvironment.
+ struct {
+ ExprAssignmentType type;
+ } ass; ///< For kExprNodeAssignment
+ } data;
+};
+
+enum {
+ /// Allow multiple expressions in a row: e.g. for :echo
+ ///
+ /// Parser will still parse only one of them though.
+ kExprFlagsMulti = (1 << 0),
+ /// Allow NL, NUL and bar to be EOC
+ ///
+ /// When parsing expressions input by user bar is assumed to be a binary
+ /// operator and other two are spacings.
+ kExprFlagsDisallowEOC = (1 << 1),
+ /// Parse :let argument
+ ///
+ /// That mean that top level node must be an assignment and first nodes
+ /// belong to lvalues.
+ kExprFlagsParseLet = (1 << 2),
+ // XXX whenever you add a new flag, alter klee_assume() statement in
+ // viml_expressions_parser.c, nvim_parse_expression() flags parsing
+ // alongside with its documentation and flag sets in check_parsing()
+ // function in expressions parser functional and unit tests.
+} ExprParserFlags;
+
+/// AST error definition
+typedef struct {
+ /// Error message. Must contain a single printf format atom: %.*s.
+ const char *msg;
+ /// Error message argument: points to the location of the error.
+ const char *arg;
+ /// Message argument length: length till the end of string.
+ int arg_len;
+} ExprASTError;
+
+/// Structure representing complety AST for one expression
+typedef struct {
+ /// When AST is not correct this message will be printed.
+ ///
+ /// Uses `emsgf(msg, arg_len, arg);`, `msg` is assumed to contain only `%.*s`.
+ ExprASTError err;
+ /// Root node of the AST.
+ ExprASTNode *root;
+} ExprAST;
+
+/// Array mapping ExprASTNodeType to maximum amount of children node may have
+extern const uint8_t node_maxchildren[];
+
+/// Array mapping ExprASTNodeType values to their stringified versions
+extern const char *const east_node_type_tab[];
+
+/// Array mapping ExprComparisonType values to their stringified versions
+extern const char *const eltkn_cmp_type_tab[];
+
+/// Array mapping ExprCaseCompareStrategy values to their stringified versions
+extern const char *const ccs_tab[];
+
+/// Array mapping ExprAssignmentType values to their stringified versions
+extern const char *const expr_asgn_type_tab[];
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "viml/parser/expressions.h.generated.h"
+#endif
+
+#endif // NVIM_VIML_PARSER_EXPRESSIONS_H
diff --git a/src/nvim/viml/parser/parser.c b/src/nvim/viml/parser/parser.c
new file mode 100644
index 0000000000..8d26d08ea7
--- /dev/null
+++ b/src/nvim/viml/parser/parser.c
@@ -0,0 +1,16 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+
+#include "nvim/viml/parser/parser.h"
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "viml/parser/parser.c.generated.h"
+#endif
+
+
+void parser_simple_get_line(void *cookie, ParserLine *ret_pline)
+{
+ ParserLine **plines_p = (ParserLine **)cookie;
+ *ret_pline = **plines_p;
+ (*plines_p)++;
+}
diff --git a/src/nvim/viml/parser/parser.h b/src/nvim/viml/parser/parser.h
new file mode 100644
index 0000000000..7ac49709d8
--- /dev/null
+++ b/src/nvim/viml/parser/parser.h
@@ -0,0 +1,244 @@
+#ifndef NVIM_VIML_PARSER_PARSER_H
+#define NVIM_VIML_PARSER_PARSER_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <assert.h>
+
+#include "nvim/lib/kvec.h"
+#include "nvim/func_attr.h"
+#include "nvim/mbyte.h"
+#include "nvim/memory.h"
+
+/// One parsed line
+typedef struct {
+ const char *data; ///< Parsed line pointer
+ size_t size; ///< Parsed line size
+ bool allocated; ///< True if line may be freed.
+} ParserLine;
+
+/// Line getter type for parser
+///
+/// Line getter must return {NULL, 0} for EOF.
+typedef void (*ParserLineGetter)(void *cookie, ParserLine *ret_pline);
+
+/// Parser position in the input
+typedef struct {
+ size_t line; ///< Line index in ParserInputReader.lines.
+ size_t col; ///< Byte index in the line.
+} ParserPosition;
+
+/// Parser state item.
+typedef struct {
+ enum {
+ kPTopStateParsingCommand = 0,
+ kPTopStateParsingExpression,
+ } type;
+ union {
+ struct {
+ enum {
+ kExprUnknown = 0,
+ } type;
+ } expr;
+ } data;
+} ParserStateItem;
+
+/// Structure defining input reader
+typedef struct {
+ /// Function used to get next line.
+ ParserLineGetter get_line;
+ /// Data for get_line function.
+ void *cookie;
+ /// All lines obtained by get_line.
+ kvec_withinit_t(ParserLine, 4) lines;
+ /// Conversion, for :scriptencoding.
+ vimconv_T conv;
+} ParserInputReader;
+
+/// Highlighted region definition
+///
+/// Note: one chunk may highlight only one line.
+typedef struct {
+ ParserPosition start; ///< Start of the highlight: line and column.
+ size_t end_col; ///< End column, points to the start of the next character.
+ const char *group; ///< Highlight group.
+} ParserHighlightChunk;
+
+/// Highlighting defined by a parser
+typedef kvec_withinit_t(ParserHighlightChunk, 16) ParserHighlight;
+
+/// Structure defining parser state
+typedef struct {
+ /// Line reader.
+ ParserInputReader reader;
+ /// Position up to which input was parsed.
+ ParserPosition pos;
+ /// Parser state stack.
+ kvec_withinit_t(ParserStateItem, 16) stack;
+ /// Highlighting support.
+ ParserHighlight *colors;
+ /// True if line continuation can be used.
+ bool can_continuate;
+} ParserState;
+
+static inline void viml_parser_init(
+ ParserState *const ret_pstate,
+ const ParserLineGetter get_line, void *const cookie,
+ ParserHighlight *const colors)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1, 2);
+
+/// Initialize a new parser state instance
+///
+/// @param[out] ret_pstate Parser state to initialize.
+/// @param[in] get_line Line getter function.
+/// @param[in] cookie Argument for the get_line function.
+/// @param[in] colors Where to save highlighting. May be NULL if it is not
+/// needed.
+static inline void viml_parser_init(
+ ParserState *const ret_pstate,
+ const ParserLineGetter get_line, void *const cookie,
+ ParserHighlight *const colors)
+{
+ *ret_pstate = (ParserState) {
+ .reader = {
+ .get_line = get_line,
+ .cookie = cookie,
+ .conv = MBYTE_NONE_CONV,
+ },
+ .pos = { 0, 0 },
+ .colors = colors,
+ .can_continuate = false,
+ };
+ kvi_init(ret_pstate->reader.lines);
+ kvi_init(ret_pstate->stack);
+}
+
+static inline void viml_parser_destroy(ParserState *const pstate)
+ REAL_FATTR_NONNULL_ALL REAL_FATTR_ALWAYS_INLINE;
+
+/// Free all memory allocated by the parser on heap
+///
+/// @param pstate Parser state to free.
+static inline void viml_parser_destroy(ParserState *const pstate)
+{
+ for (size_t i = 0; i < kv_size(pstate->reader.lines); i++) {
+ ParserLine pline = kv_A(pstate->reader.lines, i);
+ if (pline.allocated) {
+ xfree((void *)pline.data);
+ }
+ }
+ kvi_destroy(pstate->reader.lines);
+ kvi_destroy(pstate->stack);
+}
+
+static inline void viml_preader_get_line(ParserInputReader *const preader,
+ ParserLine *const ret_pline)
+ REAL_FATTR_NONNULL_ALL;
+
+/// Get one line from ParserInputReader
+static inline void viml_preader_get_line(ParserInputReader *const preader,
+ ParserLine *const ret_pline)
+{
+ ParserLine pline;
+ preader->get_line(preader->cookie, &pline);
+ if (preader->conv.vc_type != CONV_NONE && pline.size) {
+ ParserLine cpline = {
+ .allocated = true,
+ .size = pline.size,
+ };
+ cpline.data = (char *)string_convert(&preader->conv,
+ (char_u *)pline.data,
+ &cpline.size);
+ if (pline.allocated) {
+ xfree((void *)pline.data);
+ }
+ pline = cpline;
+ }
+ kvi_push(preader->lines, pline);
+ *ret_pline = pline;
+}
+
+static inline bool viml_parser_get_remaining_line(ParserState *const pstate,
+ ParserLine *const ret_pline)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_NONNULL_ALL;
+
+/// Get currently parsed line, shifted to pstate->pos.col
+///
+/// @param pstate Parser state to operate on.
+///
+/// @return True if there is a line, false in case of EOF.
+static inline bool viml_parser_get_remaining_line(ParserState *const pstate,
+ ParserLine *const ret_pline)
+{
+ const size_t num_lines = kv_size(pstate->reader.lines);
+ if (pstate->pos.line == num_lines) {
+ viml_preader_get_line(&pstate->reader, ret_pline);
+ } else {
+ *ret_pline = kv_last(pstate->reader.lines);
+ }
+ assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1);
+ if (ret_pline->data != NULL) {
+ ret_pline->data += pstate->pos.col;
+ ret_pline->size -= pstate->pos.col;
+ }
+ return ret_pline->data != NULL;
+}
+
+static inline void viml_parser_advance(ParserState *const pstate,
+ const size_t len)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL;
+
+/// Advance position by a given number of bytes
+///
+/// At maximum advances to the next line.
+///
+/// @param pstate Parser state to advance.
+/// @param[in] len Number of bytes to advance.
+static inline void viml_parser_advance(ParserState *const pstate,
+ const size_t len)
+{
+ assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1);
+ const ParserLine pline = kv_last(pstate->reader.lines);
+ if (pstate->pos.col + len >= pline.size) {
+ pstate->pos.line++;
+ pstate->pos.col = 0;
+ } else {
+ pstate->pos.col += len;
+ }
+}
+
+static inline void viml_parser_highlight(ParserState *const pstate,
+ const ParserPosition start,
+ const size_t end_col,
+ const char *const group)
+ REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL;
+
+/// Record highlighting of some region of text
+///
+/// @param pstate Parser state to work with.
+/// @param[in] start Start position of the highlight.
+/// @param[in] len Highlighting chunk length.
+/// @param[in] group Highlight group.
+static inline void viml_parser_highlight(ParserState *const pstate,
+ const ParserPosition start,
+ const size_t len,
+ const char *const group)
+{
+ if (pstate->colors == NULL || len == 0) {
+ return;
+ }
+ assert(kv_size(*pstate->colors) == 0
+ || kv_Z(*pstate->colors, 0).start.line < start.line
+ || kv_Z(*pstate->colors, 0).end_col <= start.col);
+ kvi_push(*pstate->colors, ((ParserHighlightChunk) {
+ .start = start,
+ .end_col = start.col + len,
+ .group = group,
+ }));
+}
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "viml/parser/parser.h.generated.h"
+#endif
+
+#endif // NVIM_VIML_PARSER_PARSER_H
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 1298248f1e..3cadfe612a 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.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 <inttypes.h>
#include <stdbool.h>
@@ -28,7 +31,6 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/misc1.h"
-#include "nvim/misc2.h"
#include "nvim/file_search.h"
#include "nvim/garray.h"
#include "nvim/move.h"
@@ -41,10 +43,12 @@
#include "nvim/regexp.h"
#include "nvim/screen.h"
#include "nvim/search.h"
+#include "nvim/state.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/terminal.h"
#include "nvim/undo.h"
+#include "nvim/ui.h"
#include "nvim/os/os.h"
@@ -129,9 +133,10 @@ newwindow:
vim_snprintf(cbuf, sizeof(cbuf) - 5, "%" PRId64, (int64_t)Prenum);
else
cbuf[0] = NUL;
- if (nchar == 'v' || nchar == Ctrl_V)
- strcat(cbuf, "v");
- strcat(cbuf, "new");
+ if (nchar == 'v' || nchar == Ctrl_V) {
+ xstrlcat(cbuf, "v", sizeof(cbuf));
+ }
+ xstrlcat(cbuf, "new", sizeof(cbuf));
do_cmdline_cmd(cbuf);
break;
@@ -160,13 +165,18 @@ newwindow:
/* cursor to preview window */
case 'P':
- for (wp = firstwin; wp != NULL; wp = wp->w_next)
- if (wp->w_p_pvw)
+ wp = NULL;
+ FOR_ALL_WINDOWS_IN_TAB(wp2, curtab) {
+ if (wp2->w_p_pvw) {
+ wp = wp2;
break;
- if (wp == NULL)
+ }
+ }
+ if (wp == NULL) {
EMSG(_("E441: There is no preview window"));
- else
+ } else {
win_goto(wp);
+ }
break;
/* close all but current window */
@@ -183,7 +193,7 @@ newwindow:
/* cursor to previous window with wrap around */
case 'W':
CHECK_CMDWIN
- if (firstwin == lastwin && Prenum != 1) /* just one window */
+ if (ONE_WINDOW && Prenum != 1) /* just one window */
beep_flush();
else {
if (Prenum) { /* go to specified window */
@@ -278,10 +288,11 @@ newwindow:
/* cursor to last accessed (previous) window */
case 'p':
case Ctrl_P:
- if (prevwin == NULL)
+ if (!win_valid(prevwin)) {
beep_flush();
- else
+ } else {
win_goto(prevwin);
+ }
break;
/* exchange current and next window */
@@ -356,7 +367,7 @@ newwindow:
g_do_tagpreview = Prenum;
else
g_do_tagpreview = p_pvh;
- /*FALLTHROUGH*/
+ FALLTHROUGH;
case ']':
case Ctrl_RSB:
CHECK_CMDWIN
@@ -384,12 +395,16 @@ wingotofile:
ptr = grab_file_name(Prenum1, &lnum);
if (ptr != NULL) {
+ tabpage_T *oldtab = curtab;
+ win_T *oldwin = curwin;
setpcmark();
if (win_split(0, 0) == OK) {
RESET_BINDING(curwin);
- (void)do_ecmd(0, ptr, NULL, NULL, ECMD_LASTL,
- ECMD_HIDE, NULL);
- if (nchar == 'F' && lnum >= 0) {
+ if (do_ecmd(0, ptr, NULL, NULL, ECMD_LASTL, ECMD_HIDE, NULL) == FAIL) {
+ // Failed to open the file, close the window opened for it.
+ win_close(curwin, false);
+ goto_tabpage_win(oldtab, oldwin);
+ } else if (nchar == 'F' && lnum >= 0) {
curwin->w_cursor.lnum = lnum;
check_cursor_lnum();
beginline(BL_SOL | BL_FIX);
@@ -405,8 +420,8 @@ wingotofile:
case 'i': /* Go to any match */
case Ctrl_I:
type = FIND_ANY;
- /* FALLTHROUGH */
- case 'd': /* Go to definition, using 'define' */
+ FALLTHROUGH;
+ case 'd': // Go to definition, using 'define'
case Ctrl_D:
CHECK_CMDWIN
if ((len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0)
@@ -436,13 +451,12 @@ wingotofile:
case 'g':
case Ctrl_G:
CHECK_CMDWIN
- ++ no_mapping;
- ++allow_keys; /* no mapping for xchar, but allow key codes */
- if (xchar == NUL)
+ no_mapping++;
+ if (xchar == NUL) {
xchar = plain_vgetc();
- LANGMAP_ADJUST(xchar, TRUE);
- --no_mapping;
- --allow_keys;
+ }
+ LANGMAP_ADJUST(xchar, true);
+ no_mapping--;
(void)add_to_showcmd(xchar);
switch (xchar) {
case '}':
@@ -451,7 +465,7 @@ wingotofile:
g_do_tagpreview = Prenum;
else
g_do_tagpreview = p_pvh;
- /*FALLTHROUGH*/
+ FALLTHROUGH;
case ']':
case Ctrl_RSB:
// Keep visual mode, can select words to use as a tag.
@@ -482,7 +496,7 @@ wingotofile:
}
static void cmd_with_count(char *cmd, char_u *bufp, size_t bufsize,
- long Prenum)
+ int64_t Prenum)
{
size_t len = xstrlcpy((char *)bufp, cmd, bufsize);
@@ -551,6 +565,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
int before;
int minheight;
int wmh1;
+ bool did_set_fraction = false;
if (flags & WSP_TOP)
oldwin = firstwin;
@@ -560,7 +575,7 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
oldwin = curwin;
/* add a status line when p_ls == 1 and splitting the first window */
- if (lastwin == firstwin && p_ls == 1 && oldwin->w_status_height == 0) {
+ if (ONE_WINDOW && p_ls == 1 && oldwin->w_status_height == 0) {
if (oldwin->w_height <= p_wmh && new_wp == NULL) {
EMSG(_(e_noroom));
return FAIL;
@@ -627,11 +642,12 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
if (oldwin->w_width - new_size - 1 < p_wmw)
do_equal = TRUE;
- /* We don't like to take lines for the new window from a
- * 'winfixwidth' window. Take them from a window to the left or right
- * instead, if possible. */
- if (oldwin->w_p_wfw)
- win_setwidth_win(oldwin->w_width + new_size, oldwin);
+ // We don't like to take lines for the new window from a
+ // 'winfixwidth' window. Take them from a window to the left or right
+ // instead, if possible. Add one for the separator.
+ if (oldwin->w_p_wfw) {
+ win_setwidth_win(oldwin->w_width + new_size + 1, oldwin);
+ }
/* Only make all windows the same width if one of them (except oldwin)
* is wider than one of the split windows. */
@@ -714,6 +730,11 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
* 'winfixheight' window. Take them from a window above or below
* instead, if possible. */
if (oldwin->w_p_wfh) {
+ // Set w_fraction now so that the cursor keeps the same relative
+ // vertical position using the old height.
+ set_fraction(oldwin);
+ did_set_fraction = true;
+
win_setheight_win(oldwin->w_height + new_size + STATUS_HEIGHT,
oldwin);
oldwin_height = oldwin->w_height;
@@ -828,8 +849,9 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
/* Set w_fraction now so that the cursor keeps the same relative
* vertical position. */
- if (oldwin->w_height > 0)
+ if (!did_set_fraction) {
set_fraction(oldwin);
+ }
wp->w_fraction = oldwin->w_fraction;
if (flags & WSP_VERT) {
@@ -893,31 +915,31 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
/* "new_size" of the current window goes to the new window, use
* one row for the status line */
win_new_height(wp, new_size);
- if (flags & (WSP_TOP | WSP_BOT))
- frame_new_height(curfrp, curfrp->fr_height
- - (new_size + STATUS_HEIGHT), flags & WSP_TOP, FALSE);
- else
+ if (flags & (WSP_TOP | WSP_BOT)) {
+ int new_fr_height = curfrp->fr_height - new_size;
+
+ if (!((flags & WSP_BOT) && p_ls == 0)) {
+ new_fr_height -= STATUS_HEIGHT;
+ }
+ frame_new_height(curfrp, new_fr_height, flags & WSP_TOP, false);
+ } else {
win_new_height(oldwin, oldwin_height - (new_size + STATUS_HEIGHT));
- if (before) { /* new window above current one */
+ }
+ if (before) { // new window above current one
wp->w_winrow = oldwin->w_winrow;
wp->w_status_height = STATUS_HEIGHT;
oldwin->w_winrow += wp->w_height + STATUS_HEIGHT;
} else { /* new window below current one */
wp->w_winrow = oldwin->w_winrow + oldwin->w_height + STATUS_HEIGHT;
wp->w_status_height = oldwin->w_status_height;
- // Don't set the status_height for oldwin yet, this might break
- // frame_fix_height(oldwin), therefore will be set below.
+ if (!(flags & WSP_BOT)) {
+ oldwin->w_status_height = STATUS_HEIGHT;
+ }
}
if (flags & WSP_BOT)
frame_add_statusline(curfrp);
frame_fix_height(wp);
frame_fix_height(oldwin);
-
- if (!before) {
- // New window above current one, set the status_height after
- // frame_fix_height(oldwin)
- oldwin->w_status_height = STATUS_HEIGHT;
- }
}
if (flags & (WSP_TOP | WSP_BOT))
@@ -968,11 +990,15 @@ int win_split_ins(int size, int flags, win_T *new_wp, int dir)
/*
* make the new window the current window
*/
- win_enter(wp, false);
- if (flags & WSP_VERT)
+ win_enter_ext(wp, false, false, true, true, true);
+ if (flags & WSP_VERT) {
p_wiw = i;
- else
+ } else {
p_wh = i;
+ }
+
+ // Send the window positions to the UI
+ oldwin->w_pos_changed = true;
return OK;
}
@@ -1028,7 +1054,7 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
win_init_some(newp, oldp);
- check_colorcolumn(newp);
+ didset_window_options(newp);
}
/*
@@ -1064,6 +1090,23 @@ bool win_valid(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
return false;
}
+/// Check if "win" is a pointer to an existing window in any tabpage.
+///
+/// @param win window to check
+bool win_valid_any_tab(win_T *win) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ if (win == NULL) {
+ return false;
+ }
+
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ if (wp == win) {
+ return true;
+ }
+ }
+ return false;
+}
+
/*
* Return the number of windows.
*/
@@ -1150,7 +1193,7 @@ static void win_exchange(long Prenum)
win_T *wp2;
int temp;
- if (lastwin == firstwin) { /* just one window */
+ if (ONE_WINDOW) { /* just one window */
beep_flush();
return;
}
@@ -1225,7 +1268,8 @@ static void win_exchange(long Prenum)
(void)win_comp_pos(); /* recompute window positions */
win_enter(wp, true);
- redraw_later(CLEAR);
+ redraw_later(NOT_VALID);
+ redraw_win_later(wp, NOT_VALID);
}
/*
@@ -1239,7 +1283,7 @@ static void win_rotate(int upwards, int count)
frame_T *frp;
int n;
- if (firstwin == lastwin) { /* nothing to do */
+ if (ONE_WINDOW) { /* nothing to do */
beep_flush();
return;
}
@@ -1300,7 +1344,10 @@ static void win_rotate(int upwards, int count)
(void)win_comp_pos();
}
- redraw_later(CLEAR);
+ wp1->w_pos_changed = true;
+ wp2->w_pos_changed = true;
+
+ redraw_all_later(NOT_VALID);
}
/*
@@ -1311,7 +1358,7 @@ static void win_totop(int size, int flags)
int dir;
int height = curwin->w_height;
- if (lastwin == firstwin) {
+ if (ONE_WINDOW) {
beep_flush();
return;
}
@@ -1382,6 +1429,9 @@ void win_move_after(win_T *win1, win_T *win2)
redraw_later(NOT_VALID);
}
win_enter(win1, false);
+
+ win1->w_pos_changed = true;
+ win2->w_pos_changed = true;
}
/*
@@ -1437,10 +1487,10 @@ static void win_equal_rec(
|| topfr->fr_width != width || topfr->fr_win->w_wincol != col
) {
topfr->fr_win->w_winrow = row;
- frame_new_height(topfr, height, FALSE, FALSE);
+ frame_new_height(topfr, height, false, false);
topfr->fr_win->w_wincol = col;
- frame_new_width(topfr, width, FALSE, FALSE);
- redraw_all_later(CLEAR);
+ frame_new_width(topfr, width, false, false);
+ redraw_all_later(NOT_VALID);
}
} else if (topfr->fr_layout == FR_ROW) {
topfr->fr_width = width;
@@ -1685,25 +1735,23 @@ static void win_equal_rec(
}
}
-/*
- * close all windows for buffer 'buf'
- */
-void
-close_windows (
- buf_T *buf,
- int keep_curwin /* don't close "curwin" */
-)
+/// Closes all windows for buffer `buf`.
+///
+/// @param keep_curwin don't close `curwin`
+void close_windows(buf_T *buf, int keep_curwin)
{
tabpage_T *tp, *nexttp;
int h = tabline_height();
++RedrawingDisabled;
- for (win_T *wp = firstwin; wp != NULL && lastwin != firstwin; ) {
+ for (win_T *wp = firstwin; wp != NULL && !ONE_WINDOW; ) {
if (wp->w_buffer == buf && (!keep_curwin || wp != curwin)
- && !(wp->w_closing || wp->w_buffer->b_closing)
- ) {
- win_close(wp, FALSE);
+ && !(wp->w_closing || wp->w_buffer->b_locked > 0)) {
+ if (win_close(wp, false) == FAIL) {
+ // If closing the window fails give up, to avoid looping forever.
+ break;
+ }
/* Start all over, autocommands may change the window layout. */
wp = firstwin;
@@ -1717,9 +1765,8 @@ close_windows (
if (tp != curtab) {
FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
if (wp->w_buffer == buf
- && !(wp->w_closing || wp->w_buffer->b_closing)
- ) {
- win_close_othertab(wp, FALSE, tp);
+ && !(wp->w_closing || wp->w_buffer->b_locked > 0)) {
+ win_close_othertab(wp, false, tp);
/* Start all over, the tab page may be closed and
* autocommands may change the window layout. */
@@ -1732,9 +1779,10 @@ close_windows (
--RedrawingDisabled;
- redraw_tabline = TRUE;
- if (h != tabline_height())
+ redraw_tabline = true;
+ if (h != tabline_height()) {
shell_new_rows();
+ }
}
/// Check that current window is the last one.
@@ -1775,7 +1823,7 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf,
tabpage_T *prev_curtab)
FUNC_ATTR_NONNULL_ARG(1)
{
- if (firstwin != lastwin) {
+ if (!ONE_WINDOW) {
return false;
}
buf_T *old_curbuf = curbuf;
@@ -1811,15 +1859,8 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf,
shell_new_rows();
}
- if (term) {
- // When a window containing a terminal buffer is closed, recalculate its
- // size
- terminal_resize(term, 0, 0);
- }
-
// Since goto_tabpage_tp above did not trigger *Enter autocommands, do
// that now.
- apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, curbuf);
apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf);
apply_autocmds(EVENT_TABENTER, NULL, NULL, false, curbuf);
if (old_curbuf != curbuf) {
@@ -1828,29 +1869,30 @@ static bool close_last_window_tabpage(win_T *win, bool free_buf,
return true;
}
-/*
- * Close window "win". Only works for the current tab page.
- * If "free_buf" is TRUE related buffer may be unloaded.
- *
- * Called by :quit, :close, :xit, :wq and findtag().
- * Returns FAIL when the window was not closed.
- */
-int win_close(win_T *win, int free_buf)
+// Close window "win". Only works for the current tab page.
+// If "free_buf" is true related buffer may be unloaded.
+//
+// Called by :quit, :close, :xit, :wq and findtag().
+// Returns FAIL when the window was not closed.
+int win_close(win_T *win, bool free_buf)
{
win_T *wp;
int other_buffer = FALSE;
int close_curwin = FALSE;
int dir;
- int help_window = FALSE;
+ bool help_window = false;
tabpage_T *prev_curtab = curtab;
+ frame_T *win_frame = win->w_frame->fr_parent;
if (last_window()) {
EMSG(_("E444: Cannot close last window"));
return FAIL;
}
- if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_closing))
- return FAIL; /* window is already being closed */
+ if (win->w_closing
+ || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) {
+ return FAIL; // window is already being closed
+ }
if (win == aucmd_win) {
EMSG(_("E813: Cannot close autocmd window"));
return FAIL;
@@ -1868,10 +1910,11 @@ int win_close(win_T *win, int free_buf)
/* When closing the help window, try restoring a snapshot after closing
* the window. Otherwise clear the snapshot, it's now invalid. */
- if (win->w_buffer != NULL && win->w_buffer->b_help)
- help_window = TRUE;
- else
+ if (bt_help(win->w_buffer)) {
+ help_window = true;
+ } else {
clear_snapshot(curtab, SNAP_HELP_IDX);
+ }
if (win == curwin) {
/*
@@ -1915,15 +1958,17 @@ int win_close(win_T *win, int free_buf)
* Close the link to the buffer.
*/
if (win->w_buffer != NULL) {
+ bufref_T bufref;
+ set_bufref(&bufref, curbuf);
win->w_closing = true;
close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, true);
- if (win_valid(win)) {
+ if (win_valid_any_tab(win)) {
win->w_closing = false;
}
// Make sure curbuf is valid. It can become invalid if 'bufhidden' is
// "wipe".
- if (!buf_valid(curbuf)) {
+ if (!bufref_valid(&bufref)) {
curbuf = firstbuf;
}
}
@@ -1931,17 +1976,26 @@ int win_close(win_T *win, int free_buf)
if (only_one_window() && win_valid(win) && win->w_buffer == NULL
&& (last_window() || curtab != prev_curtab
|| close_last_window_tabpage(win, free_buf, prev_curtab))) {
- /* Autocommands have close all windows, quit now. Restore
- * curwin->w_buffer, otherwise writing ShaDa file may fail. */
- if (curwin->w_buffer == NULL)
+ // Autocommands have closed all windows, quit now. Restore
+ // curwin->w_buffer, otherwise writing ShaDa file may fail.
+ if (curwin->w_buffer == NULL) {
curwin->w_buffer = curbuf;
+ }
getout(0);
}
- /* Autocommands may have closed the window already, or closed the only
- * other window or moved to another tab page. */
- else if (!win_valid(win) || last_window() || curtab != prev_curtab
- || close_last_window_tabpage(win, free_buf, prev_curtab))
+ // Autocommands may have moved to another tab page.
+ if (curtab != prev_curtab && win_valid_any_tab(win)
+ && win->w_buffer == NULL) {
+ // Need to close the window anyway, since the buffer is NULL.
+ win_close_othertab(win, false, prev_curtab);
+ return FAIL;
+ }
+ // Autocommands may have closed the window already, or closed the only
+ // other window or moved to another tab page.
+ if (!win_valid(win) || last_window()
+ || close_last_window_tabpage(win, free_buf, prev_curtab)) {
return FAIL;
+ }
// let terminal buffers know that this window dimensions may be ignored
win->w_closing = true;
@@ -1949,6 +2003,14 @@ int win_close(win_T *win, int free_buf)
* the screen space. */
wp = win_free_mem(win, &dir, NULL);
+ if (help_window) {
+ // Closing the help window moves the cursor back to the original window.
+ win_T *tmpwp = get_snapshot_focus(SNAP_HELP_IDX);
+ if (tmpwp != NULL) {
+ wp = tmpwp;
+ }
+ }
+
/* Make sure curwin isn't invalid. It can cause severe trouble when
* printing an error message. For win_equal() curbuf needs to be valid
* too. */
@@ -1974,20 +2036,25 @@ int win_close(win_T *win, int free_buf)
}
curbuf = curwin->w_buffer;
close_curwin = TRUE;
+
+ // The cursor position may be invalid if the buffer changed after last
+ // using the window.
+ check_cursor();
}
- if (p_ea
- && (*p_ead == 'b' || *p_ead == dir)
- ) {
- win_equal(curwin, true, dir);
+ if (p_ea && (*p_ead == 'b' || *p_ead == dir)) {
+ // If the frame of the closed window contains the new current window,
+ // only resize that frame. Otherwise resize all windows.
+ win_equal(curwin, curwin->w_frame->fr_parent == win_frame, dir);
} else {
win_comp_pos();
}
if (close_curwin) {
- win_enter_ext(wp, false, TRUE, TRUE, TRUE);
- if (other_buffer)
- /* careful: after this wp and win may be invalid! */
- apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
+ win_enter_ext(wp, false, true, false, true, true);
+ if (other_buffer) {
+ // careful: after this wp and win may be invalid!
+ apply_autocmds(EVENT_BUFENTER, NULL, NULL, false, curbuf);
+ }
}
/*
@@ -2001,6 +2068,7 @@ int win_close(win_T *win, int free_buf)
if (help_window)
restore_snapshot(SNAP_HELP_IDX, close_curwin);
+ curwin->w_pos_changed = true;
redraw_all_later(NOT_VALID);
return OK;
}
@@ -2018,12 +2086,17 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
tabpage_T *ptp = NULL;
int free_tp = FALSE;
- assert(win->w_buffer); // to avoid np dereference warning in next line
- if (win->w_closing || win->w_buffer->b_closing)
- return; /* window is already being closed */
+ // Get here with win->w_buffer == NULL when win_close() detects the tab page
+ // changed.
+ if (win->w_closing
+ || (win->w_buffer != NULL && win->w_buffer->b_locked > 0)) {
+ return; // window is already being closed
+ }
- /* Close the link to the buffer. */
- close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, FALSE);
+ if (win->w_buffer != NULL) {
+ // Close the link to the buffer.
+ close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, false);
+ }
/* Careful: Autocommands may have closed the tab page or made it the
* current tab page. */
@@ -2048,19 +2121,29 @@ void win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
/* When closing the last window in a tab page remove the tab page. */
if (tp->tp_firstwin == tp->tp_lastwin) {
- if (tp == first_tabpage)
+ char_u prev_idx[NUMBUFLEN];
+ if (has_event(EVENT_TABCLOSED)) {
+ vim_snprintf((char *)prev_idx, NUMBUFLEN, "%i", tabpage_index(tp));
+ }
+
+ if (tp == first_tabpage) {
first_tabpage = tp->tp_next;
- else {
+ } else {
for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tp;
- ptp = ptp->tp_next)
- ;
+ ptp = ptp->tp_next) {
+ // loop
+ }
if (ptp == NULL) {
- EMSG2(_(e_intern2), "win_close_othertab()");
+ internal_error("win_close_othertab()");
return;
}
ptp->tp_next = tp->tp_next;
}
- free_tp = TRUE;
+ free_tp = true;
+
+ if (has_event(EVENT_TABCLOSED)) {
+ apply_autocmds(EVENT_TABCLOSED, prev_idx, prev_idx, false, win->w_buffer);
+ }
}
/* Free the memory used for the window. */
@@ -2139,7 +2222,7 @@ winframe_remove (
/*
* If there is only one window there is nothing to remove.
*/
- if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
+ if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin)
return NULL;
/*
@@ -2231,6 +2314,9 @@ winframe_remove (
if (frp2->fr_win != NULL)
frp2->fr_win->w_frame = frp2->fr_parent;
frp = frp2->fr_parent;
+ if (topframe->fr_child == frp2) {
+ topframe->fr_child = frp;
+ }
xfree(frp2);
frp2 = frp->fr_parent;
@@ -2252,6 +2338,9 @@ winframe_remove (
break;
}
}
+ if (topframe->fr_child == frp) {
+ topframe->fr_child = frp2;
+ }
xfree(frp);
}
}
@@ -2259,14 +2348,14 @@ winframe_remove (
return wp;
}
-/*
- * Find out which frame is going to get the freed up space when "win" is
- * closed.
- * if 'splitbelow'/'splitleft' the space goes to the window above/left.
- * if 'nosplitbelow'/'nosplitleft' the space goes to the window below/right.
- * This makes opening a window and closing it immediately keep the same window
- * layout.
- */
+// Return a pointer to the frame that will receive the empty screen space that
+// is left over after "win" is closed.
+//
+// If 'splitbelow' or 'splitright' is set, the space goes above or to the left
+// by default. Otherwise, the free space goes below or to the right. The
+// result is that opening a window and then immediately closing it will
+// preserve the initial window layout. The 'wfh' and 'wfw' settings are
+// respected when possible.
static frame_T *
win_altframe (
win_T *win,
@@ -2274,20 +2363,40 @@ win_altframe (
)
{
frame_T *frp;
- int b;
- if (tp == NULL ? firstwin == lastwin : tp->tp_firstwin == tp->tp_lastwin)
- /* Last window in this tab page, will go to next tab page. */
+ if (tp == NULL ? ONE_WINDOW : tp->tp_firstwin == tp->tp_lastwin) {
return alt_tabpage()->tp_curwin->w_frame;
+ }
frp = win->w_frame;
- if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW)
- b = p_spr;
- else
- b = p_sb;
- if ((!b && frp->fr_next != NULL) || frp->fr_prev == NULL)
+
+ if (frp->fr_prev == NULL) {
return frp->fr_next;
- return frp->fr_prev;
+ }
+ if (frp->fr_next == NULL) {
+ return frp->fr_prev;
+ }
+
+ frame_T *target_fr = frp->fr_next;
+ frame_T *other_fr = frp->fr_prev;
+ if (p_spr || p_sb) {
+ target_fr = frp->fr_prev;
+ other_fr = frp->fr_next;
+ }
+
+ // If 'wfh' or 'wfw' is set for the target and not for the alternate
+ // window, reverse the selection.
+ if (frp->fr_parent != NULL && frp->fr_parent->fr_layout == FR_ROW) {
+ if (frame_fixed_width(target_fr) && !frame_fixed_width(other_fr)) {
+ target_fr = other_fr;
+ }
+ } else {
+ if (frame_fixed_height(target_fr) && !frame_fixed_height(other_fr)) {
+ target_fr = other_fr;
+ }
+ }
+
+ return target_fr;
}
/*
@@ -2784,8 +2893,8 @@ close_others (
}
if (!r) {
if (message && (p_confirm || cmdmod.confirm) && p_write) {
- dialog_changed(wp->w_buffer, FALSE);
- if (!win_valid(wp)) { /* autocommands messed wp up */
+ dialog_changed(wp->w_buffer, false);
+ if (!win_valid(wp)) { // autocommands messed wp up
nextwp = firstwin;
continue;
}
@@ -2793,10 +2902,10 @@ close_others (
if (bufIsChanged(wp->w_buffer))
continue;
}
- win_close(wp, !P_HID(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
+ win_close(wp, !buf_hide(wp->w_buffer) && !bufIsChanged(wp->w_buffer));
}
- if (message && lastwin != firstwin)
+ if (message && !ONE_WINDOW)
EMSG(_("E445: Other window contains changes"));
}
@@ -2874,8 +2983,9 @@ static int win_alloc_firstwin(win_T *oldwin)
/* Very first window, need to create an empty buffer for it and
* initialize from scratch. */
curbuf = buflist_new(NULL, NULL, 1L, BLN_LISTED);
- if (curbuf == NULL)
+ if (curbuf == NULL) {
return FAIL;
+ }
curwin->w_buffer = curbuf;
curwin->w_s = &(curbuf->b_s);
curbuf->b_nwindows = 1; /* there is one window */
@@ -2893,7 +3003,6 @@ static int win_alloc_firstwin(win_T *oldwin)
topframe = curwin->w_frame;
topframe->fr_width = Columns;
topframe->fr_height = Rows - p_ch;
- topframe->fr_win = curwin;
return OK;
}
@@ -2926,11 +3035,13 @@ void win_init_size(void)
*/
static tabpage_T *alloc_tabpage(void)
{
+ static int last_tp_handle = 0;
tabpage_T *tp = xcalloc(1, sizeof(tabpage_T));
+ tp->handle = ++last_tp_handle;
handle_register_tabpage(tp);
- /* init t: variables */
- tp->tp_vars = dict_alloc();
+ // Init t: variables.
+ tp->tp_vars = tv_dict_alloc();
init_var_dict(tp->tp_vars, &tp->tp_winvar, VAR_SCOPE);
tp->tp_diff_invalid = TRUE;
tp->tp_ch_used = p_ch;
@@ -2950,8 +3061,7 @@ void free_tabpage(tabpage_T *tp)
hash_init(&tp->tp_vars->dv_hashtab);
unref_var_dict(tp->tp_vars);
-
- xfree(tp->localdir); // Free tab-local working directory
+ xfree(tp->tp_localdir);
xfree(tp);
}
@@ -2976,6 +3086,9 @@ int win_new_tabpage(int after, char_u *filename)
xfree(newtp);
return FAIL;
}
+
+ newtp->tp_localdir = tp->tp_localdir ? vim_strsave(tp->tp_localdir) : NULL;
+
curtab = newtp;
/* Create a new empty window. */
@@ -3003,10 +3116,15 @@ int win_new_tabpage(int after, char_u *filename)
newtp->tp_topframe = topframe;
last_status(FALSE);
- redraw_all_later(CLEAR);
+ redraw_all_later(NOT_VALID);
- apply_autocmds(EVENT_TABNEW, filename, filename, false, curbuf);
+ if (ui_is_external(kUIMultigrid)) {
+ tabpage_check_windows(tp);
+ }
+
+ apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);
apply_autocmds(EVENT_WINENTER, NULL, NULL, false, curbuf);
+ apply_autocmds(EVENT_TABNEW, filename, filename, false, curbuf);
apply_autocmds(EVENT_TABENTER, NULL, NULL, false, curbuf);
return OK;
@@ -3078,6 +3196,45 @@ bool valid_tabpage(tabpage_T *tpc) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
return false;
}
+/// Returns true when `tpc` is valid and at least one window is valid.
+int valid_tabpage_win(tabpage_T *tpc)
+{
+ FOR_ALL_TABS(tp) {
+ if (tp == tpc) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
+ if (win_valid_any_tab(wp)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ // shouldn't happen
+ return false;
+}
+
+/// Close tabpage `tab`, assuming it has no windows in it.
+/// There must be another tabpage or this will crash.
+void close_tabpage(tabpage_T *tab)
+{
+ tabpage_T *ptp;
+
+ if (tab == first_tabpage) {
+ first_tabpage = tab->tp_next;
+ ptp = first_tabpage;
+ } else {
+ for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tab;
+ ptp = ptp->tp_next) {
+ // do nothing
+ }
+ assert(ptp != NULL);
+ ptp->tp_next = tab->tp_next;
+ }
+
+ goto_tabpage_tp(ptp, false, false);
+ free_tabpage(tab);
+}
+
/*
* Find tab page "n" (first one is 1). Returns NULL when not found.
*/
@@ -3156,22 +3313,26 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au
int old_off = tp->tp_firstwin->w_winrow;
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;
+ if (old_curtab != curtab && ui_is_external(kUIMultigrid)) {
+ tabpage_check_windows(old_curtab);
+ }
+
/* We would like doing the TabEnter event first, but we don't have a
* valid current window yet, which may break some commands.
* This triggers autocommands, thus may make "tp" invalid. */
- win_enter_ext(tp->tp_curwin, false, TRUE,
- trigger_enter_autocmds, trigger_leave_autocmds);
+ win_enter_ext(tp->tp_curwin, false, true, false,
+ trigger_enter_autocmds, trigger_leave_autocmds);
prevwin = next_prevwin;
- last_status(FALSE); /* status line may appear or disappear */
- (void)win_comp_pos(); /* recompute w_winrow for all windows */
- must_redraw = CLEAR; /* need to redraw everything */
- diff_need_scrollbind = TRUE;
+ last_status(false); // status line may appear or disappear
+ (void)win_comp_pos(); // recompute w_winrow for all windows
+ diff_need_scrollbind = true;
/* The tabpage line may have appeared or disappeared, may need to resize
* the frames for that. When the Vim window was resized need to update
@@ -3193,7 +3354,21 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, int trigger_enter_au
apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
}
- redraw_all_later(CLEAR);
+ redraw_all_later(NOT_VALID);
+}
+
+/// called when changing current tabpage from old_curtab to curtab
+static void tabpage_check_windows(tabpage_T *old_curtab)
+{
+ win_T *next_wp;
+ for (win_T *wp = old_curtab->tp_firstwin; wp; wp = next_wp) {
+ next_wp = wp->w_next;
+ wp->w_pos_changed = true;
+ }
+
+ for (win_T *wp = firstwin; wp; wp = wp->w_next) {
+ wp->w_pos_changed = true;
+ }
}
/*
@@ -3207,11 +3382,8 @@ void goto_tabpage(int n)
int i;
if (text_locked()) {
- /* Not allowed when editing the command line. */
- if (cmdwin_type != 0)
- EMSG(_(e_cmdwin));
- else
- EMSG(_(e_secure));
+ // Not allowed when editing the command line.
+ text_locked_msg();
return;
}
@@ -3296,8 +3468,11 @@ void tabpage_move(int nr)
tabpage_T *tp;
tabpage_T *tp_dst;
- if (first_tabpage->tp_next == NULL)
+ assert(curtab != NULL);
+
+ if (first_tabpage->tp_next == NULL) {
return;
+ }
for (tp = first_tabpage; tp->tp_next != NULL && n < nr; tp = tp->tp_next) {
++n;
@@ -3310,15 +3485,20 @@ void tabpage_move(int nr)
tp_dst = tp;
- /* Remove the current tab page from the list of tab pages. */
- if (curtab == first_tabpage)
+ // Remove the current tab page from the list of tab pages.
+ if (curtab == first_tabpage) {
first_tabpage = curtab->tp_next;
- else {
- for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
- if (tp->tp_next == curtab)
+ } else {
+ tp = NULL;
+ FOR_ALL_TABS(tp2) {
+ if (tp2->tp_next == curtab) {
+ tp = tp2;
break;
- if (tp == NULL) /* "cannot happen" */
+ }
+ }
+ if (tp == NULL) { // "cannot happen"
return;
+ }
tp->tp_next = curtab->tp_next;
}
@@ -3362,11 +3542,13 @@ void win_goto(win_T *wp)
win_enter(wp, true);
- /* Conceal cursor line in previous window, unconceal in current window. */
- if (win_valid(owp) && owp->w_p_cole > 0 && !msg_scrolled)
- update_single_line(owp, owp->w_cursor.lnum);
- if (curwin->w_p_cole > 0 && !msg_scrolled)
- need_cursor_line_redraw = TRUE;
+ // Conceal cursor line in previous window, unconceal in current window.
+ if (win_valid(owp) && owp->w_p_cole > 0 && !msg_scrolled) {
+ redrawWinline(owp, owp->w_cursor.lnum);
+ }
+ if (curwin->w_p_cole > 0 && !msg_scrolled) {
+ redrawWinline(curwin, curwin->w_cursor.lnum);
+ }
}
@@ -3506,7 +3688,7 @@ end:
*/
void win_enter(win_T *wp, bool undo_sync)
{
- win_enter_ext(wp, undo_sync, FALSE, TRUE, TRUE);
+ win_enter_ext(wp, undo_sync, false, false, true, true);
}
/*
@@ -3514,7 +3696,9 @@ void win_enter(win_T *wp, bool undo_sync)
* Can be called with "curwin_invalid" TRUE, which means that curwin has just
* been closed and isn't valid.
*/
-static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, int trigger_enter_autocmds, int trigger_leave_autocmds)
+static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid,
+ int trigger_new_autocmds, int trigger_enter_autocmds,
+ int trigger_leave_autocmds)
{
int other_buffer = FALSE;
@@ -3563,33 +3747,46 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, int tri
curwin->w_cursor.coladd = 0;
changed_line_abv_curs(); /* assume cursor position needs updating */
- // The new directory is either the local directory of the window, of the tab
- // or NULL.
- char_u *new_dir = curwin->w_localdir ? curwin->w_localdir : curtab->localdir;
+ // New directory is either the local directory of the window, tab or NULL.
+ char *new_dir = (char *)(curwin->w_localdir
+ ? curwin->w_localdir : curtab->tp_localdir);
+
+ char cwd[MAXPATHL];
+ if (os_dirname((char_u *)cwd, MAXPATHL) != OK) {
+ cwd[0] = NUL;
+ }
if (new_dir) {
// Window/tab has a local directory: Save current directory as global
- // directory (unless that was done already) and change to the local
- // directory.
+ // (unless that was done already) and change to the local directory.
if (globaldir == NULL) {
- char_u cwd[MAXPATHL];
-
- if (os_dirname(cwd, MAXPATHL) == OK) {
- globaldir = vim_strsave(cwd);
+ if (cwd[0] != NUL) {
+ globaldir = (char_u *)xstrdup(cwd);
}
}
- if (os_chdir((char *)new_dir) == 0) {
+ if (os_chdir(new_dir) == 0) {
+ if (!p_acd && !strequal(new_dir, cwd)) {
+ do_autocmd_dirchanged(new_dir, curwin->w_localdir
+ ? kCdScopeWindow : kCdScopeTab);
+ }
shorten_fnames(true);
}
} else if (globaldir != NULL) {
- /* Window doesn't have a local directory and we are not in the global
- * directory: Change to the global directory. */
- ignored = os_chdir((char *)globaldir);
+ // Window doesn't have a local directory and we are not in the global
+ // directory: Change to the global directory.
+ if (os_chdir((char *)globaldir) == 0) {
+ if (!p_acd && !strequal((char *)globaldir, cwd)) {
+ do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal);
+ }
+ }
xfree(globaldir);
globaldir = NULL;
shorten_fnames(TRUE);
}
+ if (trigger_new_autocmds) {
+ apply_autocmds(EVENT_WINNEW, NULL, NULL, false, curbuf);
+ }
if (trigger_enter_autocmds) {
apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
if (other_buffer)
@@ -3602,6 +3799,12 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, int tri
if (restart_edit)
redraw_later(VALID); /* causes status line redraw */
+ if (HL_ATTR(HLF_INACTIVE)
+ || (prevwin && prevwin->w_hl_ids[HLF_INACTIVE])
+ || curwin->w_hl_ids[HLF_INACTIVE]) {
+ redraw_all_later(NOT_VALID);
+ }
+
/* set window height to desired minimal value */
if (curwin->w_height < p_wh && !curwin->w_p_wfh)
win_setheight((int)p_wh);
@@ -3616,10 +3819,6 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, int tri
/* Change directories when the 'acd' option is set. */
do_autochdir();
-
- if (curbuf->terminal) {
- terminal_resize(curbuf->terminal, curwin->w_width, curwin->w_height);
- }
}
@@ -3686,15 +3885,19 @@ win_T *buf_jump_open_tab(buf_T *buf)
*/
static win_T *win_alloc(win_T *after, int hidden)
{
- /*
- * allocate window structure and linesizes arrays
- */
+ static int last_win_id = LOWEST_WIN_ID - 1;
+
+ // allocate window structure and linesizes arrays
win_T *new_wp = xcalloc(1, sizeof(win_T));
- handle_register_window(new_wp);
win_alloc_lines(new_wp);
- /* init w: variables */
- new_wp->w_vars = dict_alloc();
+ new_wp->handle = ++last_win_id;
+ handle_register_window(new_wp);
+
+ grid_assign_handle(&new_wp->w_grid);
+
+ // Init w: variables.
+ new_wp->w_vars = tv_dict_alloc();
init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE);
/* Don't execute autocommands while the window is not properly
@@ -3758,8 +3961,15 @@ win_free (
hash_init(&wp->w_vars->dv_hashtab);
unref_var_dict(wp->w_vars);
- if (prevwin == wp)
+ if (prevwin == wp) {
prevwin = NULL;
+ }
+ FOR_ALL_TABS(ttp) {
+ if (ttp->tp_prevwin == wp) {
+ ttp->tp_prevwin = NULL;
+ }
+ }
+
win_free_lsize(wp);
for (i = 0; i < wp->w_tagstacklen; ++i)
@@ -3784,6 +3994,8 @@ win_free (
xfree(wp->w_p_cc_cols);
+ win_free_grid(wp, false);
+
if (wp != aucmd_win)
win_remove(wp, tp);
if (autocmd_busy) {
@@ -3796,6 +4008,20 @@ win_free (
unblock_autocmds();
}
+void win_free_grid(win_T *wp, bool reinit)
+{
+ if (wp->w_grid.handle != 0 && ui_is_external(kUIMultigrid)) {
+ ui_call_grid_destroy(wp->w_grid.handle);
+ wp->w_grid.handle = 0;
+ }
+ grid_free(&wp->w_grid);
+ if (reinit) {
+ // if a float is turned into a split and back into a float, the grid
+ // data structure will be reused
+ memset(&wp->w_grid, 0, sizeof(wp->w_grid));
+ }
+}
+
/*
* Append window "wp" in the window list after window "after".
*/
@@ -3829,18 +4055,20 @@ win_remove (
tabpage_T *tp /* tab page "win" is in, NULL for current */
)
{
- if (wp->w_prev != NULL)
+ if (wp->w_prev != NULL) {
wp->w_prev->w_next = wp->w_next;
- else if (tp == NULL)
- firstwin = wp->w_next;
- else
+ } else if (tp == NULL) {
+ firstwin = curtab->tp_firstwin = wp->w_next;
+ } else {
tp->tp_firstwin = wp->w_next;
- if (wp->w_next != NULL)
+ }
+ if (wp->w_next != NULL) {
wp->w_next->w_prev = wp->w_prev;
- else if (tp == NULL)
- lastwin = wp->w_prev;
- else
+ } else if (tp == NULL) {
+ lastwin = curtab->tp_lastwin = wp->w_prev;
+ } else {
tp->tp_lastwin = wp->w_prev;
+ }
}
/*
@@ -3874,12 +4102,18 @@ static void frame_insert(frame_T *before, frame_T *frp)
*/
static void frame_remove(frame_T *frp)
{
- if (frp->fr_prev != NULL)
+ if (frp->fr_prev != NULL) {
frp->fr_prev->fr_next = frp->fr_next;
- else
+ } else {
frp->fr_parent->fr_child = frp->fr_next;
- if (frp->fr_next != NULL)
+ // special case: topframe->fr_child == frp
+ if (topframe->fr_child == frp) {
+ topframe->fr_child = frp->fr_next;
+ }
+ }
+ if (frp->fr_next != NULL) {
frp->fr_next->fr_prev = frp->fr_prev;
+ }
}
@@ -3889,8 +4123,8 @@ static void frame_remove(frame_T *frp)
void win_alloc_lines(win_T *wp)
{
wp->w_lines_valid = 0;
- assert(Rows >= 0);
- wp->w_lines = xcalloc(Rows, sizeof(wline_T));
+ assert(wp->w_grid.Rows >= 0);
+ wp->w_lines = xcalloc(MAX(wp->w_grid.Rows + 1, Rows), sizeof(wline_T));
}
/*
@@ -4020,7 +4254,8 @@ static void frame_comp_pos(frame_T *topfrp, int *row, int *col)
wp->w_winrow = *row;
wp->w_wincol = *col;
redraw_win_later(wp, NOT_VALID);
- wp->w_redr_status = TRUE;
+ wp->w_redr_status = true;
+ wp->w_pos_changed = true;
}
*row += wp->w_height + wp->w_status_height;
*col += wp->w_width + wp->w_vsep_width;
@@ -4073,8 +4308,9 @@ void win_setheight_win(int height, win_T *win)
* If there is extra space created between the last window and the command
* line, clear it.
*/
- if (full_screen && msg_scrolled == 0 && row < cmdline_row)
- screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
+ if (full_screen && msg_scrolled == 0 && row < cmdline_row) {
+ grid_fill(&default_grid, row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
+ }
cmdline_row = row;
msg_row = row;
msg_col = 0;
@@ -4157,11 +4393,11 @@ static void frame_setheight(frame_T *curfrp, int height)
room_cmdline = 0;
}
- if (height <= room + room_cmdline)
+ if (height <= room + room_cmdline) {
break;
+ }
if (run == 2 || curfrp->fr_width == Columns) {
- if (height > room + room_cmdline)
- height = room + room_cmdline;
+ height = room + room_cmdline;
break;
}
frame_setheight(curfrp->fr_parent, height
@@ -4325,8 +4561,7 @@ static void frame_setwidth(frame_T *curfrp, int width)
if (width <= room)
break;
if (run == 2 || curfrp->fr_height >= ROWS_AVAIL) {
- if (width > room)
- width = room;
+ width = room;
break;
}
frame_setwidth(curfrp->fr_parent, width
@@ -4525,7 +4760,7 @@ void win_drag_status_line(win_T *dragwin, int offset)
fr = fr->fr_next;
}
row = win_comp_pos();
- screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
+ grid_fill(&default_grid, row, cmdline_row, 0, (int)Columns, ' ', ' ', 0);
cmdline_row = row;
p_ch = Rows - cmdline_row;
if (p_ch < 1)
@@ -4638,10 +4873,13 @@ void win_drag_vsep_line(win_T *dragwin, int offset)
#define FRACTION_MULT 16384L
// Set wp->w_fraction for the current w_wrow and w_height.
+// Has no effect when the window is less than two lines.
void set_fraction(win_T *wp)
{
- wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height / 2)
+ if (wp->w_height > 1) {
+ wp->w_fraction = ((long)wp->w_wrow * FRACTION_MULT + wp->w_height / 2)
/ (long)wp->w_height;
+ }
}
/*
@@ -4651,8 +4889,6 @@ void set_fraction(win_T *wp)
*/
void win_new_height(win_T *wp, int height)
{
- linenr_T lnum;
- int sline, line_size;
int prev_height = wp->w_height;
/* Don't want a negative height. Happens when splitting a tiny window.
@@ -4668,7 +4904,7 @@ void win_new_height(win_T *wp, int height)
// call win_new_height() recursively.
validate_cursor();
}
- if (wp->w_height != prev_height) {
+ if (wp->w_height != prev_height) { // -V547
return; // Recursive call already changed the size, bail out.
}
if (wp->w_wrow != wp->w_prev_fraction_row) {
@@ -4679,6 +4915,21 @@ void win_new_height(win_T *wp, int height)
wp->w_height = height;
wp->w_skipcol = 0;
+ // There is no point in adjusting the scroll position when exiting. Some
+ // values might be invalid.
+ if (!exiting) {
+ scroll_to_fraction(wp, prev_height);
+ }
+
+ wp->w_pos_changed = true;
+}
+
+void scroll_to_fraction(win_T *wp, int prev_height)
+{
+ linenr_T lnum;
+ int sline, line_size;
+ int height = wp->w_height;
+
/* Don't change w_topline when height is zero. Don't set w_topline when
* 'scrollbind' is set and this isn't the current window. */
if (height > 0
@@ -4697,8 +4948,8 @@ void win_new_height(win_T *wp, int height)
sline = wp->w_wrow - line_size;
if (sline >= 0) {
- /* Make sure the whole cursor line is visible, if possible. */
- int rows = plines_win(wp, lnum, FALSE);
+ // Make sure the whole cursor line is visible, if possible.
+ const int rows = plines_win(wp, lnum, false);
if (sline > wp->w_height - rows) {
sline = wp->w_height - rows;
@@ -4733,12 +4984,13 @@ void win_new_height(win_T *wp, int height)
--sline;
break;
}
- --lnum;
- if (lnum == wp->w_topline)
- line_size = plines_win_nofill(wp, lnum, TRUE)
+ lnum--;
+ if (lnum == wp->w_topline) {
+ line_size = plines_win_nofill(wp, lnum, true)
+ wp->w_topfill;
- else
- line_size = plines_win(wp, lnum, TRUE);
+ } else {
+ line_size = plines_win(wp, lnum, true);
+ }
sline -= line_size;
}
@@ -4775,13 +5027,11 @@ void win_new_height(win_T *wp, int height)
if (wp->w_buffer->terminal) {
terminal_resize(wp->w_buffer->terminal, 0, wp->w_height);
- redraw_win_later(wp, CLEAR);
+ redraw_win_later(wp, NOT_VALID);
}
}
-/*
- * Set the width of a window.
- */
+/// Set the width of a window.
void win_new_width(win_T *wp, int width)
{
wp->w_width = width;
@@ -4797,10 +5047,12 @@ void win_new_width(win_T *wp, int width)
if (wp->w_buffer->terminal) {
if (wp->w_height != 0) {
- terminal_resize(wp->w_buffer->terminal, wp->w_width, 0);
+ terminal_resize(wp->w_buffer->terminal,
+ (uint16_t)(MAX(0, wp->w_width - win_col_off(wp))),
+ 0);
}
- redraw_win_later(wp, CLEAR);
}
+ wp->w_pos_changed = true;
}
void win_comp_scroll(win_T *wp)
@@ -4857,10 +5109,11 @@ void command_height(void)
/* Recompute window positions. */
(void)win_comp_pos();
- /* clear the lines added to cmdline */
- if (full_screen)
- screen_fill(cmdline_row, (int)Rows, 0,
- (int)Columns, ' ', ' ', 0);
+ // clear the lines added to cmdline
+ if (full_screen) {
+ grid_fill(&default_grid, cmdline_row, (int)Rows, 0, (int)Columns, ' ',
+ ' ', 0);
+ }
msg_row = cmdline_row;
redraw_cmdline = TRUE;
return;
@@ -4946,16 +5199,20 @@ file_name_in_line (
{
char_u *ptr;
size_t len;
+ bool in_type = true;
+ bool is_url = false;
/*
* search forward for what could be the start of a file name
*/
ptr = line + col;
- while (*ptr != NUL && !vim_isfilec(*ptr))
- mb_ptr_adv(ptr);
- if (*ptr == NUL) { /* nothing found */
- if (options & FNAME_MESS)
+ while (*ptr != NUL && !vim_isfilec(*ptr)) {
+ MB_PTR_ADV(ptr);
+ }
+ if (*ptr == NUL) { // nothing found
+ if (options & FNAME_MESS) {
EMSG(_("E446: No file name under cursor"));
+ }
return NULL;
}
@@ -4964,13 +5221,14 @@ file_name_in_line (
* Go one char back to ":" before "//" even when ':' is not in 'isfname'.
*/
while (ptr > line) {
- if (has_mbyte && (len = (size_t)((*mb_head_off)(line, ptr - 1))) > 0)
+ if ((len = (size_t)(utf_head_off(line, ptr - 1))) > 0) {
ptr -= len + 1;
- else if (vim_isfilec(ptr[-1])
- || ((options & FNAME_HYP) && path_is_url((char *)ptr - 1)))
- --ptr;
- else
+ } else if (vim_isfilec(ptr[-1])
+ || ((options & FNAME_HYP) && path_is_url((char *)ptr - 1))) {
+ ptr--;
+ } else {
break;
+ }
}
/*
@@ -4979,7 +5237,19 @@ file_name_in_line (
*/
len = 0;
while (vim_isfilec(ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ')
- || ((options & FNAME_HYP) && path_is_url((char *)ptr + len))) {
+ || ((options & FNAME_HYP) && path_is_url((char *)ptr + len))
+ || (is_url && vim_strchr((char_u *)"?&=", ptr[len]) != NULL)) {
+ // After type:// we also include ?, & and = as valid characters, so that
+ // http://google.com?q=this&that=ok works.
+ if ((ptr[len] >= 'A' && ptr[len] <= 'Z')
+ || (ptr[len] >= 'a' && ptr[len] <= 'z')) {
+ if (in_type && path_is_url((char *)ptr + len + 1)) {
+ is_url = true;
+ }
+ } else {
+ in_type = false;
+ }
+
if (ptr[len] == '\\' && ptr[len + 1] == ' ') {
// Skip over the "\" in "\ ".
++len;
@@ -5028,7 +5298,7 @@ last_status (
{
/* Don't make a difference between horizontal or vertical split. */
last_status_rec(topframe, (p_ls == 2
- || (p_ls == 1 && (morewin || lastwin != firstwin))));
+ || (p_ls == 1 && (morewin || !ONE_WINDOW))));
}
static void last_status_rec(frame_T *fr, int statusline)
@@ -5085,6 +5355,9 @@ static void last_status_rec(frame_T *fr, int statusline)
*/
int tabline_height(void)
{
+ if (ui_is_external(kUITabline)) {
+ return 0;
+ }
assert(first_tabpage);
switch (p_stal) {
case 0: return 0;
@@ -5127,7 +5400,7 @@ bool only_one_window(void) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
int count = 0;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_buffer != NULL
- && (!((wp->w_buffer->b_help && !curbuf->b_help)
+ && (!((bt_help(wp->w_buffer) && !bt_help(curbuf))
|| wp->w_p_pvw) || wp == curwin) && wp != aucmd_win) {
count++;
}
@@ -5229,15 +5502,13 @@ restore_snapshot (
win_comp_pos();
if (wp != NULL && close_curwin)
win_goto(wp);
- redraw_all_later(CLEAR);
+ redraw_all_later(NOT_VALID);
}
clear_snapshot(curtab, idx);
}
-/*
- * Check if frames "sn" and "fr" have the same layout, same following frames
- * and same children.
- */
+/// Check if frames "sn" and "fr" have the same layout, same following frames
+/// and same children. And the window pointer is valid.
static int check_snapshot_rec(frame_T *sn, frame_T *fr)
{
if (sn->fr_layout != fr->fr_layout
@@ -5246,7 +5517,8 @@ static int check_snapshot_rec(frame_T *sn, frame_T *fr)
|| (sn->fr_next != NULL
&& check_snapshot_rec(sn->fr_next, fr->fr_next) == FAIL)
|| (sn->fr_child != NULL
- && check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL))
+ && check_snapshot_rec(sn->fr_child, fr->fr_child) == FAIL)
+ || (sn->fr_win != NULL && !win_valid(sn->fr_win)))
return FAIL;
return OK;
}
@@ -5281,6 +5553,27 @@ static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr)
return wp;
}
+/// Gets the focused window (the one holding the cursor) of the snapshot.
+static win_T *get_snapshot_focus(int idx)
+{
+ if (curtab->tp_snapshot[idx] == NULL) {
+ return NULL;
+ }
+
+ frame_T *sn = curtab->tp_snapshot[idx];
+ // This should be equivalent to the recursive algorithm found in
+ // restore_snapshot as far as traveling nodes go.
+ while (sn->fr_child != NULL || sn->fr_next != NULL) {
+ while (sn->fr_child != NULL) {
+ sn = sn->fr_child;
+ }
+ if (sn->fr_next != NULL) {
+ sn = sn->fr_next;
+ }
+ }
+
+ return sn->fr_win;
+}
/*
* Set "win" to be the curwin and "tp" to be the current tab page.
@@ -5313,12 +5606,10 @@ int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage
return OK;
}
-/*
- * Restore current tabpage and window saved by switch_win(), if still valid.
- * When "no_display" is TRUE the display won't be affected, no redraw is
- * triggered.
- */
-void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display)
+// Restore current tabpage and window saved by switch_win(), if still valid.
+// When "no_display" is true the display won't be affected, no redraw is
+// triggered.
+void restore_win(win_T *save_curwin, tabpage_T *save_curtab, bool no_display)
{
if (save_curtab != NULL && valid_tabpage(save_curtab)) {
if (no_display) {
@@ -5337,44 +5628,45 @@ void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display)
unblock_autocmds();
}
-/*
- * Make "buf" the current buffer. restore_buffer() MUST be called to undo.
- * No autocommands will be executed. Use aucmd_prepbuf() if there are any.
- */
-void switch_buffer(buf_T **save_curbuf, buf_T *buf)
+/// Make "buf" the current buffer.
+///
+/// restore_buffer() MUST be called to undo.
+/// No autocommands will be executed. Use aucmd_prepbuf() if there are any.
+void switch_buffer(bufref_T *save_curbuf, buf_T *buf)
{
block_autocmds();
- *save_curbuf = curbuf;
- --curbuf->b_nwindows;
+ set_bufref(save_curbuf, curbuf);
+ curbuf->b_nwindows--;
curbuf = buf;
curwin->w_buffer = buf;
- ++curbuf->b_nwindows;
+ curbuf->b_nwindows++;
}
-/*
- * Restore the current buffer after using switch_buffer().
- */
-void restore_buffer(buf_T *save_curbuf)
+/// Restore the current buffer after using switch_buffer().
+void restore_buffer(bufref_T *save_curbuf)
{
unblock_autocmds();
- /* Check for valid buffer, just in case. */
- if (buf_valid(save_curbuf)) {
- --curbuf->b_nwindows;
- curwin->w_buffer = save_curbuf;
- curbuf = save_curbuf;
- ++curbuf->b_nwindows;
+ // Check for valid buffer, just in case.
+ if (bufref_valid(save_curbuf)) {
+ curbuf->b_nwindows--;
+ curwin->w_buffer = save_curbuf->br_buf;
+ curbuf = save_curbuf->br_buf;
+ curbuf->b_nwindows++;
}
}
-// Add match to the match list of window 'wp'. The pattern 'pat' will be
-// highlighted with the group 'grp' with priority 'prio'.
-// Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
-// If no particular ID is desired, -1 must be specified for 'id'.
-// Return ID of added match, -1 on failure.
-int match_add(win_T *wp, char_u *grp, char_u *pat,
+/// Add match to the match list of window 'wp'. The pattern 'pat' will be
+/// highlighted with the group 'grp' with priority 'prio'.
+/// Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
+///
+/// @param[in] id a desired ID 'id' can be specified
+/// (greater than or equal to 1). -1 must be specified if no
+/// particular ID is desired
+/// @return ID of added match, -1 on failure.
+int match_add(win_T *wp, const char *const grp, const char *const pat,
int prio, int id, list_T *pos_list,
- char_u *conceal_char)
+ const char *const conceal_char)
{
matchitem_T *cur;
matchitem_T *prev;
@@ -5387,8 +5679,8 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
return -1;
}
if (id < -1 || id == 0) {
- EMSGN("E799: Invalid ID: %" PRId64
- " (must be greater than or equal to 1)",
+ EMSGN(_("E799: Invalid ID: %" PRId64
+ " (must be greater than or equal to 1)"),
id);
return -1;
}
@@ -5396,17 +5688,17 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
cur = wp->w_match_head;
while (cur != NULL) {
if (cur->id == id) {
- EMSGN("E801: ID already taken: %" PRId64, id);
+ EMSGN(_("E801: ID already taken: %" PRId64), id);
return -1;
}
cur = cur->next;
}
}
- if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0) {
+ if ((hlg_id = syn_name2id((const char_u *)grp)) == 0) {
EMSG2(_(e_nogroup), grp);
return -1;
}
- if (pat != NULL && (regprog = vim_regcomp(pat, RE_MAGIC)) == NULL) {
+ if (pat != NULL && (regprog = vim_regcomp((char_u *)pat, RE_MAGIC)) == NULL) {
EMSG2(_(e_invarg2), pat);
return -1;
}
@@ -5425,76 +5717,76 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
m = xcalloc(1, sizeof(matchitem_T));
m->id = id;
m->priority = prio;
- m->pattern = pat == NULL ? NULL: vim_strsave(pat);
+ m->pattern = pat == NULL ? NULL: (char_u *)xstrdup(pat);
m->hlg_id = hlg_id;
m->match.regprog = regprog;
m->match.rmm_ic = FALSE;
m->match.rmm_maxcol = 0;
m->conceal_char = 0;
if (conceal_char != NULL) {
- m->conceal_char = (*mb_ptr2char)(conceal_char);
+ m->conceal_char = utf_ptr2char((const char_u *)conceal_char);
}
// Set up position matches
- if (pos_list != NULL)
- {
- linenr_T toplnum = 0;
- linenr_T botlnum = 0;
- listitem_T *li;
- int i;
-
- for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH;
- i++, li = li->li_next) {
- linenr_T lnum = 0;
- colnr_T col = 0;
- int len = 1;
- list_T *subl;
- listitem_T *subli;
- int error = false;
-
- if (li->li_tv.v_type == VAR_LIST) {
- subl = li->li_tv.vval.v_list;
- if (subl == NULL) {
- goto fail;
- }
- subli = subl->lv_first;
+ if (pos_list != NULL) {
+ linenr_T toplnum = 0;
+ linenr_T botlnum = 0;
+
+ int i = 0;
+ TV_LIST_ITER(pos_list, li, {
+ linenr_T lnum = 0;
+ colnr_T col = 0;
+ int len = 1;
+ bool error = false;
+
+ if (TV_LIST_ITEM_TV(li)->v_type == VAR_LIST) {
+ const list_T *const subl = TV_LIST_ITEM_TV(li)->vval.v_list;
+ const listitem_T *subli = tv_list_first(subl);
if (subli == NULL) {
+ emsgf(_("E5030: Empty list at position %d"),
+ (int)tv_list_idx_of_item(pos_list, li));
goto fail;
}
- lnum = get_tv_number_chk(&subli->li_tv, &error);
- if (error == true) {
+ lnum = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error);
+ if (error) {
goto fail;
}
- if (lnum == 0) {
- --i;
+ if (lnum <= 0) {
continue;
}
m->pos.pos[i].lnum = lnum;
- subli = subli->li_next;
+ subli = TV_LIST_ITEM_NEXT(subl, subli);
if (subli != NULL) {
- col = get_tv_number_chk(&subli->li_tv, &error);
- if (error == true)
+ col = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error);
+ if (error) {
goto fail;
- subli = subli->li_next;
+ }
+ if (col < 0) {
+ continue;
+ }
+ subli = TV_LIST_ITEM_NEXT(subl, subli);
if (subli != NULL) {
- len = get_tv_number_chk(&subli->li_tv, &error);
- if (error == true) {
+ len = tv_get_number_chk(TV_LIST_ITEM_TV(subli), &error);
+ if (len < 0) {
+ continue;
+ }
+ if (error) {
goto fail;
}
}
}
m->pos.pos[i].col = col;
m->pos.pos[i].len = len;
- } else if (li->li_tv.v_type == VAR_NUMBER) {
- if (li->li_tv.vval.v_number == 0) {
- --i;
+ } else if (TV_LIST_ITEM_TV(li)->v_type == VAR_NUMBER) {
+ if (TV_LIST_ITEM_TV(li)->vval.v_number <= 0) {
continue;
}
- m->pos.pos[i].lnum = li->li_tv.vval.v_number;
+ m->pos.pos[i].lnum = TV_LIST_ITEM_TV(li)->vval.v_number;
m->pos.pos[i].col = 0;
m->pos.pos[i].len = 0;
} else {
- EMSG(_("List or number required"));
+ emsgf(_("E5031: List or number required at position %d"),
+ (int)tv_list_idx_of_item(pos_list, li));
goto fail;
}
if (toplnum == 0 || lnum < toplnum) {
@@ -5503,7 +5795,11 @@ int match_add(win_T *wp, char_u *grp, char_u *pat,
if (botlnum == 0 || lnum >= botlnum) {
botlnum = lnum + 1;
}
- }
+ i++;
+ if (i >= MAXPOSMATCH) {
+ break;
+ }
+ });
// Calculate top and bottom lines for redrawing area
if (toplnum != 0){
@@ -5548,10 +5844,9 @@ fail:
return -1;
}
-/*
- * Delete match with ID 'id' in the match list of window 'wp'.
- * Print error messages if 'perr' is TRUE.
- */
+
+/// Delete match with ID 'id' in the match list of window 'wp'.
+/// Print error messages if 'perr' is TRUE.
int match_delete(win_T *wp, int id, int perr)
{
matchitem_T *cur = wp->w_match_head;
@@ -5559,10 +5854,11 @@ int match_delete(win_T *wp, int id, int perr)
int rtype = SOME_VALID;
if (id < 1) {
- if (perr == TRUE)
- EMSGN("E802: Invalid ID: %" PRId64
- " (must be greater than or equal to 1)",
+ if (perr) {
+ EMSGN(_("E802: Invalid ID: %" PRId64
+ " (must be greater than or equal to 1)"),
id);
+ }
return -1;
}
while (cur != NULL && cur->id != id) {
@@ -5570,8 +5866,9 @@ int match_delete(win_T *wp, int id, int perr)
cur = cur->next;
}
if (cur == NULL) {
- if (perr == TRUE)
- EMSGN("E803: ID not found: %" PRId64, id);
+ if (perr) {
+ EMSGN(_("E803: ID not found: %" PRId64), id);
+ }
return -1;
}
if (cur == prev)
@@ -5671,3 +5968,144 @@ static bool frame_check_width(frame_T *topfrp, int width)
}
return true;
}
+
+int win_getid(typval_T *argvars)
+{
+ if (argvars[0].v_type == VAR_UNKNOWN) {
+ return curwin->handle;
+ }
+ int winnr = tv_get_number(&argvars[0]);
+ win_T *wp;
+ if (winnr > 0) {
+ if (argvars[1].v_type == VAR_UNKNOWN) {
+ wp = firstwin;
+ } else {
+ tabpage_T *tp = NULL;
+ int tabnr = tv_get_number(&argvars[1]);
+ FOR_ALL_TABS(tp2) {
+ if (--tabnr == 0) {
+ tp = tp2;
+ break;
+ }
+ }
+ if (tp == NULL) {
+ return -1;
+ }
+ if (tp == curtab) {
+ wp = firstwin;
+ } else {
+ wp = tp->tp_firstwin;
+ }
+ }
+ for ( ; wp != NULL; wp = wp->w_next) {
+ if (--winnr == 0) {
+ return wp->handle;
+ }
+ }
+ }
+ return 0;
+}
+
+int win_gotoid(typval_T *argvars)
+{
+ int id = tv_get_number(&argvars[0]);
+
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ if (wp->handle == id) {
+ goto_tabpage_win(tp, wp);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void win_get_tabwin(handle_T id, int *tabnr, int *winnr)
+{
+ *tabnr = 0;
+ *winnr = 0;
+
+ int tnum = 1, wnum = 1;
+ FOR_ALL_TABS(tp) {
+ FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
+ if (wp->handle == id) {
+ *winnr = wnum;
+ *tabnr = tnum;
+ return;
+ }
+ wnum++;
+ }
+ tnum++;
+ wnum = 1;
+ }
+}
+
+void win_id2tabwin(typval_T *const argvars, typval_T *const rettv)
+{
+ int winnr = 1;
+ int tabnr = 1;
+ handle_T id = (handle_T)tv_get_number(&argvars[0]);
+
+ win_get_tabwin(id, &tabnr, &winnr);
+
+ list_T *const list = tv_list_alloc_ret(rettv, 2);
+ tv_list_append_number(list, tabnr);
+ tv_list_append_number(list, winnr);
+}
+
+win_T * win_id2wp(typval_T *argvars)
+{
+ int id = tv_get_number(&argvars[0]);
+
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ if (wp->handle == id) {
+ return wp;
+ }
+ }
+
+ return NULL;
+}
+
+int win_id2win(typval_T *argvars)
+{
+ int nr = 1;
+ int id = tv_get_number(&argvars[0]);
+
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->handle == id) {
+ return nr;
+ }
+ nr++;
+ }
+ return 0;
+}
+
+void win_findbuf(typval_T *argvars, list_T *list)
+{
+ int bufnr = tv_get_number(&argvars[0]);
+
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ if (wp->w_buffer->b_fnum == bufnr) {
+ tv_list_append_number(list, wp->handle);
+ }
+ }
+}
+
+void win_ui_flush(void)
+{
+ if (!ui_is_external(kUIMultigrid)) {
+ return;
+ }
+
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ if (wp->w_pos_changed && wp->w_grid.chars != NULL) {
+ if (tp == curtab) {
+ ui_call_win_pos(wp->w_grid.handle, wp->handle, wp->w_winrow,
+ wp->w_wincol, wp->w_width, wp->w_height);
+ } else {
+ ui_call_win_hide(wp->w_grid.handle);
+ }
+ wp->w_pos_changed = false;
+ }
+ }
+
+}
diff --git a/src/nvim/window.h b/src/nvim/window.h
index 2ac4c00c28..82b3fe5e88 100644
--- a/src/nvim/window.h
+++ b/src/nvim/window.h
@@ -3,6 +3,8 @@
#include <stdbool.h>
+#include "nvim/buffer_defs.h"
+
/* Values for file_name_in_line() */
#define FNAME_MESS 1 /* give error message */
#define FNAME_EXP 2 /* expand to path */
diff --git a/src/nvim/xdiff/COPYING b/src/nvim/xdiff/COPYING
new file mode 100644
index 0000000000..f3f1b3b65e
--- /dev/null
+++ b/src/nvim/xdiff/COPYING
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/src/nvim/xdiff/README.txt b/src/nvim/xdiff/README.txt
new file mode 100644
index 0000000000..1afe74095b
--- /dev/null
+++ b/src/nvim/xdiff/README.txt
@@ -0,0 +1,16 @@
+The files in this directory come from the xdiff implementation in git.
+You can find it here: https://github.com/git/git/tree/master/xdiff
+The files were last updated 2018 September 10.
+
+This is originally based on libxdiff, which can be found here:
+http://www.xmailserver.org/xdiff-lib.html
+
+The git version was used because it has been maintained and improved.
+And since it's part of git it is expected to be reliable.
+
+The code is distributed under the GNU LGPL license. It is included in the
+COPYING file.
+
+Changes in these files were made to avoid compiler warnings.
+
+The first work for including xdiff in Vim was done by Christian Brabandt.
diff --git a/src/nvim/xdiff/xdiff.h b/src/nvim/xdiff/xdiff.h
new file mode 100644
index 0000000000..bc26fb64fd
--- /dev/null
+++ b/src/nvim/xdiff/xdiff.h
@@ -0,0 +1,143 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#if !defined(XDIFF_H)
+#define XDIFF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* #ifdef __cplusplus */
+
+/* xpparm_t.flags */
+#define XDF_NEED_MINIMAL (1 << 0)
+
+#define XDF_IGNORE_WHITESPACE (1 << 1)
+#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 2)
+#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 3)
+#define XDF_IGNORE_CR_AT_EOL (1 << 4)
+#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | \
+ XDF_IGNORE_WHITESPACE_CHANGE | \
+ XDF_IGNORE_WHITESPACE_AT_EOL | \
+ XDF_IGNORE_CR_AT_EOL)
+
+#define XDF_IGNORE_BLANK_LINES (1 << 7)
+
+#define XDF_PATIENCE_DIFF (1 << 14)
+#define XDF_HISTOGRAM_DIFF (1 << 15)
+#define XDF_DIFF_ALGORITHM_MASK (XDF_PATIENCE_DIFF | XDF_HISTOGRAM_DIFF)
+#define XDF_DIFF_ALG(x) ((x) & XDF_DIFF_ALGORITHM_MASK)
+
+#define XDF_INDENT_HEURISTIC (1 << 23)
+
+/* xdemitconf_t.flags */
+#define XDL_EMIT_FUNCNAMES (1 << 0)
+#define XDL_EMIT_FUNCCONTEXT (1 << 2)
+
+/* merge simplification levels */
+#define XDL_MERGE_MINIMAL 0
+#define XDL_MERGE_EAGER 1
+#define XDL_MERGE_ZEALOUS 2
+#define XDL_MERGE_ZEALOUS_ALNUM 3
+
+/* merge favor modes */
+#define XDL_MERGE_FAVOR_OURS 1
+#define XDL_MERGE_FAVOR_THEIRS 2
+#define XDL_MERGE_FAVOR_UNION 3
+
+/* merge output styles */
+#define XDL_MERGE_DIFF3 1
+
+typedef struct s_mmfile {
+ char *ptr;
+ long size;
+} mmfile_t;
+
+typedef struct s_mmbuffer {
+ char *ptr;
+ long size;
+} mmbuffer_t;
+
+typedef struct s_xpparam {
+ unsigned long flags;
+
+ /* See Documentation/diff-options.txt. */
+ char **anchors;
+ size_t anchors_nr;
+} xpparam_t;
+
+typedef struct s_xdemitcb {
+ void *priv;
+ int (*outf)(void *, mmbuffer_t *, int);
+} xdemitcb_t;
+
+typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv);
+
+typedef int (*xdl_emit_hunk_consume_func_t)(long start_a, long count_a,
+ long start_b, long count_b,
+ void *cb_data);
+
+typedef struct s_xdemitconf {
+ long ctxlen;
+ long interhunkctxlen;
+ unsigned long flags;
+ find_func_t find_func;
+ void *find_func_priv;
+ xdl_emit_hunk_consume_func_t hunk_func;
+} xdemitconf_t;
+
+typedef struct s_bdiffparam {
+ long bsize;
+} bdiffparam_t;
+
+#include "../memory.h"
+
+#define xdl_malloc(x) xmalloc((x))
+#define xdl_free(ptr) xfree(ptr)
+#define xdl_realloc(ptr,x) xrealloc((ptr),(x))
+
+void *xdl_mmfile_first(mmfile_t *mmf, long *size);
+long xdl_mmfile_size(mmfile_t *mmf);
+
+int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdemitconf_t const *xecfg, xdemitcb_t *ecb);
+
+typedef struct s_xmparam {
+ xpparam_t xpp;
+ int marker_size;
+ int level;
+ int favor;
+ int style;
+ const char *ancestor; /* label for orig */
+ const char *file1; /* label for mf1 */
+ const char *file2; /* label for mf2 */
+} xmparam_t;
+
+#define DEFAULT_CONFLICT_MARKER_SIZE 7
+
+int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
+ xmparam_t const *xmp, mmbuffer_t *result);
+
+#ifdef __cplusplus
+}
+#endif /* #ifdef __cplusplus */
+
+#endif /* #if !defined(XDIFF_H) */
diff --git a/src/nvim/xdiff/xdiffi.c b/src/nvim/xdiff/xdiffi.c
new file mode 100644
index 0000000000..96d5277027
--- /dev/null
+++ b/src/nvim/xdiff/xdiffi.c
@@ -0,0 +1,1043 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#include "xinclude.h"
+
+#define XDL_MAX_COST_MIN 256
+#define XDL_HEUR_MIN_COST 256
+#define XDL_LINE_MAX (long)((1UL << (CHAR_BIT * sizeof(long) - 1)) - 1)
+#define XDL_SNAKE_CNT 20
+#define XDL_K_HEUR 4
+
+typedef struct s_xdpsplit {
+ long i1, i2;
+ int min_lo, min_hi;
+} xdpsplit_t;
+
+/*
+ * See "An O(ND) Difference Algorithm and its Variations", by Eugene Myers.
+ * Basically considers a "box" (off1, off2, lim1, lim2) and scan from both
+ * the forward diagonal starting from (off1, off2) and the backward diagonal
+ * starting from (lim1, lim2). If the K values on the same diagonal crosses
+ * returns the furthest point of reach. We might end up having to expensive
+ * cases using this algorithm is full, so a little bit of heuristic is needed
+ * to cut the search and to return a suboptimal point.
+ */
+static long xdl_split(unsigned long const *ha1, long off1, long lim1,
+ unsigned long const *ha2, long off2, long lim2,
+ long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
+ xdalgoenv_t *xenv) {
+ long dmin = off1 - lim2, dmax = lim1 - off2;
+ long fmid = off1 - off2, bmid = lim1 - lim2;
+ long odd = (fmid - bmid) & 1;
+ long fmin = fmid, fmax = fmid;
+ long bmin = bmid, bmax = bmid;
+ long ec, d, i1, i2, prev1, best, dd, v, k;
+
+ /*
+ * Set initial diagonal values for both forward and backward path.
+ */
+ kvdf[fmid] = off1;
+ kvdb[bmid] = lim1;
+
+ for (ec = 1;; ec++) {
+ int got_snake = 0;
+
+ /*
+ * We need to extent the diagonal "domain" by one. If the next
+ * values exits the box boundaries we need to change it in the
+ * opposite direction because (max - min) must be a power of two.
+ * Also we initialize the external K value to -1 so that we can
+ * avoid extra conditions check inside the core loop.
+ */
+ if (fmin > dmin)
+ kvdf[--fmin - 1] = -1;
+ else
+ ++fmin;
+ if (fmax < dmax)
+ kvdf[++fmax + 1] = -1;
+ else
+ --fmax;
+
+ for (d = fmax; d >= fmin; d -= 2) {
+ if (kvdf[d - 1] >= kvdf[d + 1])
+ i1 = kvdf[d - 1] + 1;
+ else
+ i1 = kvdf[d + 1];
+ prev1 = i1;
+ i2 = i1 - d;
+ for (; i1 < lim1 && i2 < lim2 && ha1[i1] == ha2[i2]; i1++, i2++);
+ if (i1 - prev1 > xenv->snake_cnt)
+ got_snake = 1;
+ kvdf[d] = i1;
+ if (odd && bmin <= d && d <= bmax && kvdb[d] <= i1) {
+ spl->i1 = i1;
+ spl->i2 = i2;
+ spl->min_lo = spl->min_hi = 1;
+ return ec;
+ }
+ }
+
+ /*
+ * We need to extent the diagonal "domain" by one. If the next
+ * values exits the box boundaries we need to change it in the
+ * opposite direction because (max - min) must be a power of two.
+ * Also we initialize the external K value to -1 so that we can
+ * avoid extra conditions check inside the core loop.
+ */
+ if (bmin > dmin)
+ kvdb[--bmin - 1] = XDL_LINE_MAX;
+ else
+ ++bmin;
+ if (bmax < dmax)
+ kvdb[++bmax + 1] = XDL_LINE_MAX;
+ else
+ --bmax;
+
+ for (d = bmax; d >= bmin; d -= 2) {
+ if (kvdb[d - 1] < kvdb[d + 1])
+ i1 = kvdb[d - 1];
+ else
+ i1 = kvdb[d + 1] - 1;
+ prev1 = i1;
+ i2 = i1 - d;
+ for (; i1 > off1 && i2 > off2 && ha1[i1 - 1] == ha2[i2 - 1]; i1--, i2--);
+ if (prev1 - i1 > xenv->snake_cnt)
+ got_snake = 1;
+ kvdb[d] = i1;
+ if (!odd && fmin <= d && d <= fmax && i1 <= kvdf[d]) {
+ spl->i1 = i1;
+ spl->i2 = i2;
+ spl->min_lo = spl->min_hi = 1;
+ return ec;
+ }
+ }
+
+ if (need_min)
+ continue;
+
+ /*
+ * If the edit cost is above the heuristic trigger and if
+ * we got a good snake, we sample current diagonals to see
+ * if some of the, have reached an "interesting" path. Our
+ * measure is a function of the distance from the diagonal
+ * corner (i1 + i2) penalized with the distance from the
+ * mid diagonal itself. If this value is above the current
+ * edit cost times a magic factor (XDL_K_HEUR) we consider
+ * it interesting.
+ */
+ if (got_snake && ec > xenv->heur_min) {
+ for (best = 0, d = fmax; d >= fmin; d -= 2) {
+ dd = d > fmid ? d - fmid: fmid - d;
+ i1 = kvdf[d];
+ i2 = i1 - d;
+ v = (i1 - off1) + (i2 - off2) - dd;
+
+ if (v > XDL_K_HEUR * ec && v > best &&
+ off1 + xenv->snake_cnt <= i1 && i1 < lim1 &&
+ off2 + xenv->snake_cnt <= i2 && i2 < lim2) {
+ for (k = 1; ha1[i1 - k] == ha2[i2 - k]; k++)
+ if (k == xenv->snake_cnt) {
+ best = v;
+ spl->i1 = i1;
+ spl->i2 = i2;
+ break;
+ }
+ }
+ }
+ if (best > 0) {
+ spl->min_lo = 1;
+ spl->min_hi = 0;
+ return ec;
+ }
+
+ for (best = 0, d = bmax; d >= bmin; d -= 2) {
+ dd = d > bmid ? d - bmid: bmid - d;
+ i1 = kvdb[d];
+ i2 = i1 - d;
+ v = (lim1 - i1) + (lim2 - i2) - dd;
+
+ if (v > XDL_K_HEUR * ec && v > best &&
+ off1 < i1 && i1 <= lim1 - xenv->snake_cnt &&
+ off2 < i2 && i2 <= lim2 - xenv->snake_cnt) {
+ for (k = 0; ha1[i1 + k] == ha2[i2 + k]; k++)
+ if (k == xenv->snake_cnt - 1) {
+ best = v;
+ spl->i1 = i1;
+ spl->i2 = i2;
+ break;
+ }
+ }
+ }
+ if (best > 0) {
+ spl->min_lo = 0;
+ spl->min_hi = 1;
+ return ec;
+ }
+ }
+
+ /*
+ * Enough is enough. We spent too much time here and now we collect
+ * the furthest reaching path using the (i1 + i2) measure.
+ */
+ if (ec >= xenv->mxcost) {
+ long fbest, fbest1, bbest, bbest1;
+
+ fbest = fbest1 = -1;
+ for (d = fmax; d >= fmin; d -= 2) {
+ i1 = XDL_MIN(kvdf[d], lim1);
+ i2 = i1 - d;
+ if (lim2 < i2)
+ i1 = lim2 + d, i2 = lim2;
+ if (fbest < i1 + i2) {
+ fbest = i1 + i2;
+ fbest1 = i1;
+ }
+ }
+
+ bbest = bbest1 = XDL_LINE_MAX;
+ for (d = bmax; d >= bmin; d -= 2) {
+ i1 = XDL_MAX(off1, kvdb[d]);
+ i2 = i1 - d;
+ if (i2 < off2)
+ i1 = off2 + d, i2 = off2;
+ if (i1 + i2 < bbest) {
+ bbest = i1 + i2;
+ bbest1 = i1;
+ }
+ }
+
+ if ((lim1 + lim2) - bbest < fbest - (off1 + off2)) {
+ spl->i1 = fbest1;
+ spl->i2 = fbest - fbest1;
+ spl->min_lo = 1;
+ spl->min_hi = 0;
+ } else {
+ spl->i1 = bbest1;
+ spl->i2 = bbest - bbest1;
+ spl->min_lo = 0;
+ spl->min_hi = 1;
+ }
+ return ec;
+ }
+ }
+}
+
+
+/*
+ * Rule: "Divide et Impera". Recursively split the box in sub-boxes by calling
+ * the box splitting function. Note that the real job (marking changed lines)
+ * is done in the two boundary reaching checks.
+ */
+int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
+ diffdata_t *dd2, long off2, long lim2,
+ long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv) {
+ unsigned long const *ha1 = dd1->ha, *ha2 = dd2->ha;
+
+ /*
+ * Shrink the box by walking through each diagonal snake (SW and NE).
+ */
+ for (; off1 < lim1 && off2 < lim2 && ha1[off1] == ha2[off2]; off1++, off2++);
+ for (; off1 < lim1 && off2 < lim2 && ha1[lim1 - 1] == ha2[lim2 - 1]; lim1--, lim2--);
+
+ /*
+ * If one dimension is empty, then all records on the other one must
+ * be obviously changed.
+ */
+ if (off1 == lim1) {
+ char *rchg2 = dd2->rchg;
+ long *rindex2 = dd2->rindex;
+
+ for (; off2 < lim2; off2++)
+ rchg2[rindex2[off2]] = 1;
+ } else if (off2 == lim2) {
+ char *rchg1 = dd1->rchg;
+ long *rindex1 = dd1->rindex;
+
+ for (; off1 < lim1; off1++)
+ rchg1[rindex1[off1]] = 1;
+ } else {
+ xdpsplit_t spl;
+ spl.i1 = spl.i2 = 0;
+
+ /*
+ * Divide ...
+ */
+ if (xdl_split(ha1, off1, lim1, ha2, off2, lim2, kvdf, kvdb,
+ need_min, &spl, xenv) < 0) {
+
+ return -1;
+ }
+
+ /*
+ * ... et Impera.
+ */
+ if (xdl_recs_cmp(dd1, off1, spl.i1, dd2, off2, spl.i2,
+ kvdf, kvdb, spl.min_lo, xenv) < 0 ||
+ xdl_recs_cmp(dd1, spl.i1, lim1, dd2, spl.i2, lim2,
+ kvdf, kvdb, spl.min_hi, xenv) < 0) {
+
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdfenv_t *xe) {
+ long ndiags;
+ long *kvd, *kvdf, *kvdb;
+ xdalgoenv_t xenv;
+ diffdata_t dd1, dd2;
+
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
+ return xdl_do_patience_diff(mf1, mf2, xpp, xe);
+
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
+ return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
+
+ if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
+
+ return -1;
+ }
+
+ /*
+ * Allocate and setup K vectors to be used by the differential algorithm.
+ * One is to store the forward path and one to store the backward path.
+ */
+ ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
+ if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
+
+ xdl_free_env(xe);
+ return -1;
+ }
+ kvdf = kvd;
+ kvdb = kvdf + ndiags;
+ kvdf += xe->xdf2.nreff + 1;
+ kvdb += xe->xdf2.nreff + 1;
+
+ xenv.mxcost = xdl_bogosqrt(ndiags);
+ if (xenv.mxcost < XDL_MAX_COST_MIN)
+ xenv.mxcost = XDL_MAX_COST_MIN;
+ xenv.snake_cnt = XDL_SNAKE_CNT;
+ xenv.heur_min = XDL_HEUR_MIN_COST;
+
+ dd1.nrec = xe->xdf1.nreff;
+ dd1.ha = xe->xdf1.ha;
+ dd1.rchg = xe->xdf1.rchg;
+ dd1.rindex = xe->xdf1.rindex;
+ dd2.nrec = xe->xdf2.nreff;
+ dd2.ha = xe->xdf2.ha;
+ dd2.rchg = xe->xdf2.rchg;
+ dd2.rindex = xe->xdf2.rindex;
+
+ if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
+ kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {
+
+ xdl_free(kvd);
+ xdl_free_env(xe);
+ return -1;
+ }
+
+ xdl_free(kvd);
+
+ return 0;
+}
+
+
+static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2) {
+ xdchange_t *xch;
+
+ if (!(xch = (xdchange_t *) xdl_malloc(sizeof(xdchange_t))))
+ return NULL;
+
+ xch->next = xscr;
+ xch->i1 = i1;
+ xch->i2 = i2;
+ xch->chg1 = chg1;
+ xch->chg2 = chg2;
+ xch->ignore = 0;
+
+ return xch;
+}
+
+
+static int recs_match(xrecord_t *rec1, xrecord_t *rec2, long flags)
+{
+ return (rec1->ha == rec2->ha &&
+ xdl_recmatch(rec1->ptr, rec1->size,
+ rec2->ptr, rec2->size,
+ flags));
+}
+
+/*
+ * If a line is indented more than this, xget_indent() just returns this value.
+ * This avoids having to do absurd amounts of work for data that are not
+ * human-readable text, and also ensures that the output of xget_indent fits within
+ * an int.
+ */
+#define MAX_INDENT 200
+
+/*
+ * Return the amount of indentation of the specified line, treating TAB as 8
+ * columns. Return -1 if line is empty or contains only whitespace. Clamp the
+ * output value at MAX_INDENT.
+ */
+static int xget_indent(xrecord_t *rec)
+{
+ long i;
+ int ret = 0;
+
+ for (i = 0; i < rec->size; i++) {
+ char c = rec->ptr[i];
+
+ if (!XDL_ISSPACE(c))
+ return ret;
+ else if (c == ' ')
+ ret += 1;
+ else if (c == '\t')
+ ret += 8 - ret % 8;
+ /* ignore other whitespace characters */
+
+ if (ret >= MAX_INDENT)
+ return MAX_INDENT;
+ }
+
+ /* The line contains only whitespace. */
+ return -1;
+}
+
+/*
+ * If more than this number of consecutive blank rows are found, just return this
+ * value. This avoids requiring O(N^2) work for pathological cases, and also
+ * ensures that the output of score_split fits in an int.
+ */
+#define MAX_BLANKS 20
+
+/* Characteristics measured about a hypothetical split position. */
+struct split_measurement {
+ /*
+ * Is the split at the end of the file (aside from any blank lines)?
+ */
+ int end_of_file;
+
+ /*
+ * How much is the line immediately following the split indented (or -1 if
+ * the line is blank):
+ */
+ int indent;
+
+ /*
+ * How many consecutive lines above the split are blank?
+ */
+ int pre_blank;
+
+ /*
+ * How much is the nearest non-blank line above the split indented (or -1
+ * if there is no such line)?
+ */
+ int pre_indent;
+
+ /*
+ * How many lines after the line following the split are blank?
+ */
+ int post_blank;
+
+ /*
+ * How much is the nearest non-blank line after the line following the
+ * split indented (or -1 if there is no such line)?
+ */
+ int post_indent;
+};
+
+struct split_score {
+ /* The effective indent of this split (smaller is preferred). */
+ int effective_indent;
+
+ /* Penalty for this split (smaller is preferred). */
+ int penalty;
+};
+
+/*
+ * Fill m with information about a hypothetical split of xdf above line split.
+ */
+static void measure_split(const xdfile_t *xdf, long split,
+ struct split_measurement *m)
+{
+ long i;
+
+ if (split >= xdf->nrec) {
+ m->end_of_file = 1;
+ m->indent = -1;
+ } else {
+ m->end_of_file = 0;
+ m->indent = xget_indent(xdf->recs[split]);
+ }
+
+ m->pre_blank = 0;
+ m->pre_indent = -1;
+ for (i = split - 1; i >= 0; i--) {
+ m->pre_indent = xget_indent(xdf->recs[i]);
+ if (m->pre_indent != -1)
+ break;
+ m->pre_blank += 1;
+ if (m->pre_blank == MAX_BLANKS) {
+ m->pre_indent = 0;
+ break;
+ }
+ }
+
+ m->post_blank = 0;
+ m->post_indent = -1;
+ for (i = split + 1; i < xdf->nrec; i++) {
+ m->post_indent = xget_indent(xdf->recs[i]);
+ if (m->post_indent != -1)
+ break;
+ m->post_blank += 1;
+ if (m->post_blank == MAX_BLANKS) {
+ m->post_indent = 0;
+ break;
+ }
+ }
+}
+
+/*
+ * The empirically-determined weight factors used by score_split() below.
+ * Larger values means that the position is a less favorable place to split.
+ *
+ * Note that scores are only ever compared against each other, so multiplying
+ * all of these weight/penalty values by the same factor wouldn't change the
+ * heuristic's behavior. Still, we need to set that arbitrary scale *somehow*.
+ * In practice, these numbers are chosen to be large enough that they can be
+ * adjusted relative to each other with sufficient precision despite using
+ * integer math.
+ */
+
+/* Penalty if there are no non-blank lines before the split */
+#define START_OF_FILE_PENALTY 1
+
+/* Penalty if there are no non-blank lines after the split */
+#define END_OF_FILE_PENALTY 21
+
+/* Multiplier for the number of blank lines around the split */
+#define TOTAL_BLANK_WEIGHT (-30)
+
+/* Multiplier for the number of blank lines after the split */
+#define POST_BLANK_WEIGHT 6
+
+/*
+ * Penalties applied if the line is indented more than its predecessor
+ */
+#define RELATIVE_INDENT_PENALTY (-4)
+#define RELATIVE_INDENT_WITH_BLANK_PENALTY 10
+
+/*
+ * Penalties applied if the line is indented less than both its predecessor and
+ * its successor
+ */
+#define RELATIVE_OUTDENT_PENALTY 24
+#define RELATIVE_OUTDENT_WITH_BLANK_PENALTY 17
+
+/*
+ * Penalties applied if the line is indented less than its predecessor but not
+ * less than its successor
+ */
+#define RELATIVE_DEDENT_PENALTY 23
+#define RELATIVE_DEDENT_WITH_BLANK_PENALTY 17
+
+/*
+ * We only consider whether the sum of the effective indents for splits are
+ * less than (-1), equal to (0), or greater than (+1) each other. The resulting
+ * value is multiplied by the following weight and combined with the penalty to
+ * determine the better of two scores.
+ */
+#define INDENT_WEIGHT 60
+
+/*
+ * How far do we slide a hunk at most?
+ */
+#define INDENT_HEURISTIC_MAX_SLIDING 100
+
+/*
+ * Compute a badness score for the hypothetical split whose measurements are
+ * stored in m. The weight factors were determined empirically using the tools and
+ * corpus described in
+ *
+ * https://github.com/mhagger/diff-slider-tools
+ *
+ * Also see that project if you want to improve the weights based on, for example,
+ * a larger or more diverse corpus.
+ */
+static void score_add_split(const struct split_measurement *m, struct split_score *s)
+{
+ /*
+ * A place to accumulate penalty factors (positive makes this index more
+ * favored):
+ */
+ int post_blank, total_blank, indent, any_blanks;
+
+ if (m->pre_indent == -1 && m->pre_blank == 0)
+ s->penalty += START_OF_FILE_PENALTY;
+
+ if (m->end_of_file)
+ s->penalty += END_OF_FILE_PENALTY;
+
+ /*
+ * Set post_blank to the number of blank lines following the split,
+ * including the line immediately after the split:
+ */
+ post_blank = (m->indent == -1) ? 1 + m->post_blank : 0;
+ total_blank = m->pre_blank + post_blank;
+
+ /* Penalties based on nearby blank lines: */
+ s->penalty += TOTAL_BLANK_WEIGHT * total_blank;
+ s->penalty += POST_BLANK_WEIGHT * post_blank;
+
+ if (m->indent != -1)
+ indent = m->indent;
+ else
+ indent = m->post_indent;
+
+ any_blanks = (total_blank != 0);
+
+ /* Note that the effective indent is -1 at the end of the file: */
+ s->effective_indent += indent;
+
+ if (indent == -1) {
+ /* No additional adjustments needed. */
+ } else if (m->pre_indent == -1) {
+ /* No additional adjustments needed. */
+ } else if (indent > m->pre_indent) {
+ /*
+ * The line is indented more than its predecessor.
+ */
+ s->penalty += any_blanks ?
+ RELATIVE_INDENT_WITH_BLANK_PENALTY :
+ RELATIVE_INDENT_PENALTY;
+ } else if (indent == m->pre_indent) {
+ /*
+ * The line has the same indentation level as its predecessor.
+ * No additional adjustments needed.
+ */
+ } else {
+ /*
+ * The line is indented less than its predecessor. It could be
+ * the block terminator of the previous block, but it could
+ * also be the start of a new block (e.g., an "else" block, or
+ * maybe the previous block didn't have a block terminator).
+ * Try to distinguish those cases based on what comes next:
+ */
+ if (m->post_indent != -1 && m->post_indent > indent) {
+ /*
+ * The following line is indented more. So it is likely
+ * that this line is the start of a block.
+ */
+ s->penalty += any_blanks ?
+ RELATIVE_OUTDENT_WITH_BLANK_PENALTY :
+ RELATIVE_OUTDENT_PENALTY;
+ } else {
+ /*
+ * That was probably the end of a block.
+ */
+ s->penalty += any_blanks ?
+ RELATIVE_DEDENT_WITH_BLANK_PENALTY :
+ RELATIVE_DEDENT_PENALTY;
+ }
+ }
+}
+
+static int score_cmp(struct split_score *s1, struct split_score *s2)
+{
+ /* -1 if s1.effective_indent < s2->effective_indent, etc. */
+ int cmp_indents = ((s1->effective_indent > s2->effective_indent) -
+ (s1->effective_indent < s2->effective_indent));
+
+ return INDENT_WEIGHT * cmp_indents + (s1->penalty - s2->penalty);
+}
+
+/*
+ * Represent a group of changed lines in an xdfile_t (i.e., a contiguous group
+ * of lines that was inserted or deleted from the corresponding version of the
+ * file). We consider there to be such a group at the beginning of the file, at
+ * the end of the file, and between any two unchanged lines, though most such
+ * groups will usually be empty.
+ *
+ * If the first line in a group is equal to the line following the group, then
+ * the group can be slid down. Similarly, if the last line in a group is equal
+ * to the line preceding the group, then the group can be slid up. See
+ * group_slide_down() and group_slide_up().
+ *
+ * Note that loops that are testing for changed lines in xdf->rchg do not need
+ * index bounding since the array is prepared with a zero at position -1 and N.
+ */
+struct xdlgroup {
+ /*
+ * The index of the first changed line in the group, or the index of
+ * the unchanged line above which the (empty) group is located.
+ */
+ long start;
+
+ /*
+ * The index of the first unchanged line after the group. For an empty
+ * group, end is equal to start.
+ */
+ long end;
+};
+
+/*
+ * Initialize g to point at the first group in xdf.
+ */
+static void group_init(xdfile_t *xdf, struct xdlgroup *g)
+{
+ g->start = g->end = 0;
+ while (xdf->rchg[g->end])
+ g->end++;
+}
+
+/*
+ * Move g to describe the next (possibly empty) group in xdf and return 0. If g
+ * is already at the end of the file, do nothing and return -1.
+ */
+static inline int group_next(xdfile_t *xdf, struct xdlgroup *g)
+{
+ if (g->end == xdf->nrec)
+ return -1;
+
+ g->start = g->end + 1;
+ for (g->end = g->start; xdf->rchg[g->end]; g->end++)
+ ;
+
+ return 0;
+}
+
+/*
+ * Move g to describe the previous (possibly empty) group in xdf and return 0.
+ * If g is already at the beginning of the file, do nothing and return -1.
+ */
+static inline int group_previous(xdfile_t *xdf, struct xdlgroup *g)
+{
+ if (g->start == 0)
+ return -1;
+
+ g->end = g->start - 1;
+ for (g->start = g->end; xdf->rchg[g->start - 1]; g->start--)
+ ;
+
+ return 0;
+}
+
+/*
+ * If g can be slid toward the end of the file, do so, and if it bumps into a
+ * following group, expand this group to include it. Return 0 on success or -1
+ * if g cannot be slid down.
+ */
+static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g, long flags)
+{
+ if (g->end < xdf->nrec &&
+ recs_match(xdf->recs[g->start], xdf->recs[g->end], flags)) {
+ xdf->rchg[g->start++] = 0;
+ xdf->rchg[g->end++] = 1;
+
+ while (xdf->rchg[g->end])
+ g->end++;
+
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/*
+ * If g can be slid toward the beginning of the file, do so, and if it bumps
+ * into a previous group, expand this group to include it. Return 0 on success
+ * or -1 if g cannot be slid up.
+ */
+static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g, long flags)
+{
+ if (g->start > 0 &&
+ recs_match(xdf->recs[g->start - 1], xdf->recs[g->end - 1], flags)) {
+ xdf->rchg[--g->start] = 1;
+ xdf->rchg[--g->end] = 0;
+
+ while (xdf->rchg[g->start - 1])
+ g->start--;
+
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+static void xdl_bug(const char *msg)
+{
+ fprintf(stderr, "BUG: %s\n", msg);
+ exit(1);
+}
+
+/*
+ * Move back and forward change groups for a consistent and pretty diff output.
+ * This also helps in finding joinable change groups and reducing the diff
+ * size.
+ */
+int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
+ struct xdlgroup g, go;
+ long earliest_end, end_matching_other;
+ long groupsize;
+
+ group_init(xdf, &g);
+ group_init(xdfo, &go);
+
+ while (1) {
+ /* If the group is empty in the to-be-compacted file, skip it: */
+ if (g.end == g.start)
+ goto next;
+
+ /*
+ * Now shift the change up and then down as far as possible in
+ * each direction. If it bumps into any other changes, merge them.
+ */
+ do {
+ groupsize = g.end - g.start;
+
+ /*
+ * Keep track of the last "end" index that causes this
+ * group to align with a group of changed lines in the
+ * other file. -1 indicates that we haven't found such
+ * a match yet:
+ */
+ end_matching_other = -1;
+
+ /* Shift the group backward as much as possible: */
+ while (!group_slide_up(xdf, &g, flags))
+ if (group_previous(xdfo, &go))
+ xdl_bug("group sync broken sliding up");
+
+ /*
+ * This is this highest that this group can be shifted.
+ * Record its end index:
+ */
+ earliest_end = g.end;
+
+ if (go.end > go.start)
+ end_matching_other = g.end;
+
+ /* Now shift the group forward as far as possible: */
+ while (1) {
+ if (group_slide_down(xdf, &g, flags))
+ break;
+ if (group_next(xdfo, &go))
+ xdl_bug("group sync broken sliding down");
+
+ if (go.end > go.start)
+ end_matching_other = g.end;
+ }
+ } while (groupsize != g.end - g.start);
+
+ /*
+ * If the group can be shifted, then we can possibly use this
+ * freedom to produce a more intuitive diff.
+ *
+ * The group is currently shifted as far down as possible, so the
+ * heuristics below only have to handle upwards shifts.
+ */
+
+ if (g.end == earliest_end) {
+ /* no shifting was possible */
+ } else if (end_matching_other != -1) {
+ /*
+ * Move the possibly merged group of changes back to line
+ * up with the last group of changes from the other file
+ * that it can align with.
+ */
+ while (go.end == go.start) {
+ if (group_slide_up(xdf, &g, flags))
+ xdl_bug("match disappeared");
+ if (group_previous(xdfo, &go))
+ xdl_bug("group sync broken sliding to match");
+ }
+ } else if (flags & XDF_INDENT_HEURISTIC) {
+ /*
+ * Indent heuristic: a group of pure add/delete lines
+ * implies two splits, one between the end of the "before"
+ * context and the start of the group, and another between
+ * the end of the group and the beginning of the "after"
+ * context. Some splits are aesthetically better and some
+ * are worse. We compute a badness "score" for each split,
+ * and add the scores for the two splits to define a
+ * "score" for each position that the group can be shifted
+ * to. Then we pick the shift with the lowest score.
+ */
+ long shift, best_shift = -1;
+ struct split_score best_score;
+
+ shift = earliest_end;
+ if (g.end - groupsize - 1 > shift)
+ shift = g.end - groupsize - 1;
+ if (g.end - INDENT_HEURISTIC_MAX_SLIDING > shift)
+ shift = g.end - INDENT_HEURISTIC_MAX_SLIDING;
+ for (; shift <= g.end; shift++) {
+ struct split_measurement m;
+ struct split_score score = {0, 0};
+
+ measure_split(xdf, shift, &m);
+ score_add_split(&m, &score);
+ measure_split(xdf, shift - groupsize, &m);
+ score_add_split(&m, &score);
+ if (best_shift == -1 ||
+ score_cmp(&score, &best_score) <= 0) {
+ best_score.effective_indent = score.effective_indent;
+ best_score.penalty = score.penalty;
+ best_shift = shift;
+ }
+ }
+
+ while (g.end > best_shift) {
+ if (group_slide_up(xdf, &g, flags))
+ xdl_bug("best shift unreached");
+ if (group_previous(xdfo, &go))
+ xdl_bug("group sync broken sliding to blank line");
+ }
+ }
+
+ next:
+ /* Move past the just-processed group: */
+ if (group_next(xdf, &g))
+ break;
+ if (group_next(xdfo, &go))
+ xdl_bug("group sync broken moving to next group");
+ }
+
+ if (!group_next(xdfo, &go))
+ xdl_bug("group sync broken at end of file");
+
+ return 0;
+}
+
+
+int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr) {
+ xdchange_t *cscr = NULL, *xch;
+ char *rchg1 = xe->xdf1.rchg, *rchg2 = xe->xdf2.rchg;
+ long i1, i2, l1, l2;
+
+ /*
+ * Trivial. Collects "groups" of changes and creates an edit script.
+ */
+ for (i1 = xe->xdf1.nrec, i2 = xe->xdf2.nrec; i1 >= 0 || i2 >= 0; i1--, i2--)
+ if (rchg1[i1 - 1] || rchg2[i2 - 1]) {
+ for (l1 = i1; rchg1[i1 - 1]; i1--);
+ for (l2 = i2; rchg2[i2 - 1]; i2--);
+
+ if (!(xch = xdl_add_change(cscr, i1, i2, l1 - i1, l2 - i2))) {
+ xdl_free_script(cscr);
+ return -1;
+ }
+ cscr = xch;
+ }
+
+ *xscr = cscr;
+
+ return 0;
+}
+
+
+void xdl_free_script(xdchange_t *xscr) {
+ xdchange_t *xch;
+
+ while ((xch = xscr) != NULL) {
+ xscr = xscr->next;
+ xdl_free(xch);
+ }
+}
+
+static int xdl_call_hunk_func(xdfenv_t *xe UNUSED, xdchange_t *xscr, xdemitcb_t *ecb,
+ xdemitconf_t const *xecfg)
+{
+ xdchange_t *xch, *xche;
+
+ for (xch = xscr; xch; xch = xche->next) {
+ xche = xdl_get_hunk(&xch, xecfg);
+ if (!xch)
+ break;
+ if (xecfg->hunk_func(xch->i1, xche->i1 + xche->chg1 - xch->i1,
+ xch->i2, xche->i2 + xche->chg2 - xch->i2,
+ ecb->priv) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+static void xdl_mark_ignorable(xdchange_t *xscr, xdfenv_t *xe, long flags)
+{
+ xdchange_t *xch;
+
+ for (xch = xscr; xch; xch = xch->next) {
+ int ignore = 1;
+ xrecord_t **rec;
+ long i;
+
+ rec = &xe->xdf1.recs[xch->i1];
+ for (i = 0; i < xch->chg1 && ignore; i++)
+ ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags);
+
+ rec = &xe->xdf2.recs[xch->i2];
+ for (i = 0; i < xch->chg2 && ignore; i++)
+ ignore = xdl_blankline(rec[i]->ptr, rec[i]->size, flags);
+
+ xch->ignore = ignore;
+ }
+}
+
+int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdemitconf_t const *xecfg, xdemitcb_t *ecb) {
+ xdchange_t *xscr;
+ xdfenv_t xe;
+ emit_func_t ef = xecfg->hunk_func ? xdl_call_hunk_func : xdl_emit_diff;
+
+ if (xdl_do_diff(mf1, mf2, xpp, &xe) < 0) {
+
+ return -1;
+ }
+ if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 ||
+ xdl_change_compact(&xe.xdf2, &xe.xdf1, xpp->flags) < 0 ||
+ xdl_build_script(&xe, &xscr) < 0) {
+
+ xdl_free_env(&xe);
+ return -1;
+ }
+ if (xscr) {
+ if (xpp->flags & XDF_IGNORE_BLANK_LINES)
+ xdl_mark_ignorable(xscr, &xe, xpp->flags);
+
+ if (ef(&xe, xscr, ecb, xecfg) < 0) {
+
+ xdl_free_script(xscr);
+ xdl_free_env(&xe);
+ return -1;
+ }
+ xdl_free_script(xscr);
+ }
+ xdl_free_env(&xe);
+
+ return 0;
+}
diff --git a/src/nvim/xdiff/xdiffi.h b/src/nvim/xdiff/xdiffi.h
new file mode 100644
index 0000000000..8f1c7c8b04
--- /dev/null
+++ b/src/nvim/xdiff/xdiffi.h
@@ -0,0 +1,64 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#if !defined(XDIFFI_H)
+#define XDIFFI_H
+
+
+typedef struct s_diffdata {
+ long nrec;
+ unsigned long const *ha;
+ long *rindex;
+ char *rchg;
+} diffdata_t;
+
+typedef struct s_xdalgoenv {
+ long mxcost;
+ long snake_cnt;
+ long heur_min;
+} xdalgoenv_t;
+
+typedef struct s_xdchange {
+ struct s_xdchange *next;
+ long i1, i2;
+ long chg1, chg2;
+ int ignore;
+} xdchange_t;
+
+
+
+int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
+ diffdata_t *dd2, long off2, long lim2,
+ long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv);
+int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdfenv_t *xe);
+int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags);
+int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
+void xdl_free_script(xdchange_t *xscr);
+int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+ xdemitconf_t const *xecfg);
+int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdfenv_t *env);
+int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdfenv_t *env);
+
+#endif /* #if !defined(XDIFFI_H) */
diff --git a/src/nvim/xdiff/xemit.c b/src/nvim/xdiff/xemit.c
new file mode 100644
index 0000000000..d8a6f1ed38
--- /dev/null
+++ b/src/nvim/xdiff/xemit.c
@@ -0,0 +1,332 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#include "xinclude.h"
+
+static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) {
+
+ *rec = xdf->recs[ri]->ptr;
+
+ return xdf->recs[ri]->size;
+}
+
+
+static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) {
+ long size, psize = (long)strlen(pre);
+ char const *rec;
+
+ size = xdl_get_rec(xdf, ri, &rec);
+ if (xdl_emit_diffrec(rec, size, pre, psize, ecb) < 0) {
+
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Starting at the passed change atom, find the latest change atom to be included
+ * inside the differential hunk according to the specified configuration.
+ * Also advance xscr if the first changes must be discarded.
+ */
+xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
+{
+ xdchange_t *xch, *xchp, *lxch;
+ long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;
+ long max_ignorable = xecfg->ctxlen;
+ unsigned long ignored = 0; /* number of ignored blank lines */
+
+ /* remove ignorable changes that are too far before other changes */
+ for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
+ xch = xchp->next;
+
+ if (xch == NULL ||
+ xch->i1 - (xchp->i1 + xchp->chg1) >= max_ignorable)
+ *xscr = xch;
+ }
+
+ if (*xscr == NULL)
+ return NULL;
+
+ lxch = *xscr;
+
+ for (xchp = *xscr, xch = xchp->next; xch; xchp = xch, xch = xch->next) {
+ long distance = xch->i1 - (xchp->i1 + xchp->chg1);
+ if (distance > max_common)
+ break;
+
+ if (distance < max_ignorable && (!xch->ignore || lxch == xchp)) {
+ lxch = xch;
+ ignored = 0;
+ } else if (distance < max_ignorable && xch->ignore) {
+ ignored += xch->chg2;
+ } else if (lxch != xchp &&
+ xch->i1 + (long)ignored - (lxch->i1 + lxch->chg1) > max_common) {
+ break;
+ } else if (!xch->ignore) {
+ lxch = xch;
+ ignored = 0;
+ } else {
+ ignored += xch->chg2;
+ }
+ }
+
+ return lxch;
+}
+
+
+#if 0
+static long def_ff(const char *rec, long len, char *buf, long sz, void *priv UNUSED)
+{
+ if (len > 0 &&
+ (isalpha((unsigned char)*rec) || /* identifier? */
+ *rec == '_' || /* also identifier? */
+ *rec == '$')) { /* identifiers from VMS and other esoterico */
+ if (len > sz)
+ len = sz;
+ while (0 < len && isspace((unsigned char)rec[len - 1]))
+ len--;
+ memcpy(buf, rec, len);
+ return len;
+ }
+ return -1;
+}
+#endif
+
+#if 0
+static long match_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri,
+ char *buf, long sz)
+{
+ const char *rec;
+ long len = xdl_get_rec(xdf, ri, &rec);
+ if (!xecfg->find_func)
+ return def_ff(rec, len, buf, sz, xecfg->find_func_priv);
+ return xecfg->find_func(rec, len, buf, sz, xecfg->find_func_priv);
+}
+#endif
+
+#if 0
+static int is_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri)
+{
+ char dummy[1];
+ return match_func_rec(xdf, xecfg, ri, dummy, sizeof(dummy)) >= 0;
+}
+#endif
+
+struct func_line {
+ long len;
+ char buf[80];
+};
+
+#if 0
+static long get_func_line(xdfenv_t *xe, xdemitconf_t const *xecfg,
+ struct func_line *func_line, long start, long limit)
+{
+ long l, size, step = (start > limit) ? -1 : 1;
+ char *buf, dummy[1];
+
+ buf = func_line ? func_line->buf : dummy;
+ size = func_line ? sizeof(func_line->buf) : sizeof(dummy);
+
+ for (l = start; l != limit && 0 <= l && l < xe->xdf1.nrec; l += step) {
+ long len = match_func_rec(&xe->xdf1, xecfg, l, buf, size);
+ if (len >= 0) {
+ if (func_line)
+ func_line->len = len;
+ return l;
+ }
+ }
+ return -1;
+}
+#endif
+
+#if 0
+static int is_empty_rec(xdfile_t *xdf, long ri)
+{
+ const char *rec;
+ long len = xdl_get_rec(xdf, ri, &rec);
+
+ while (len > 0 && XDL_ISSPACE(*rec)) {
+ rec++;
+ len--;
+ }
+ return !len;
+}
+#endif
+
+int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+ xdemitconf_t const *xecfg) {
+ long s1, s2, e1, e2, lctx;
+ xdchange_t *xch, *xche;
+#if 0
+ long funclineprev = -1;
+#endif
+ struct func_line func_line;
+
+ func_line.len = 0;
+
+ for (xch = xscr; xch; xch = xche->next) {
+ xche = xdl_get_hunk(&xch, xecfg);
+ if (!xch)
+ break;
+
+ s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0);
+ s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);
+
+#if 0
+ if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
+ long fs1, i1 = xch->i1;
+
+ /* Appended chunk? */
+ if (i1 >= xe->xdf1.nrec) {
+ long i2 = xch->i2;
+
+ /*
+ * We don't need additional context if
+ * a whole function was added.
+ */
+ while (i2 < xe->xdf2.nrec) {
+ if (is_func_rec(&xe->xdf2, xecfg, i2))
+ goto post_context_calculation;
+ i2++;
+ }
+
+ /*
+ * Otherwise get more context from the
+ * pre-image.
+ */
+ i1 = xe->xdf1.nrec - 1;
+ }
+
+ fs1 = get_func_line(xe, xecfg, NULL, i1, -1);
+ while (fs1 > 0 && !is_empty_rec(&xe->xdf1, fs1 - 1) &&
+ !is_func_rec(&xe->xdf1, xecfg, fs1 - 1))
+ fs1--;
+ if (fs1 < 0)
+ fs1 = 0;
+ if (fs1 < s1) {
+ s2 -= s1 - fs1;
+ s1 = fs1;
+ }
+ }
+
+ post_context_calculation:
+#endif
+ lctx = xecfg->ctxlen;
+ lctx = XDL_MIN(lctx, xe->xdf1.nrec - (xche->i1 + xche->chg1));
+ lctx = XDL_MIN(lctx, xe->xdf2.nrec - (xche->i2 + xche->chg2));
+
+ e1 = xche->i1 + xche->chg1 + lctx;
+ e2 = xche->i2 + xche->chg2 + lctx;
+
+#if 0
+ if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
+ long fe1 = get_func_line(xe, xecfg, NULL,
+ xche->i1 + xche->chg1,
+ xe->xdf1.nrec);
+ while (fe1 > 0 && is_empty_rec(&xe->xdf1, fe1 - 1))
+ fe1--;
+ if (fe1 < 0)
+ fe1 = xe->xdf1.nrec;
+ if (fe1 > e1) {
+ e2 += fe1 - e1;
+ e1 = fe1;
+ }
+
+ /*
+ * Overlap with next change? Then include it
+ * in the current hunk and start over to find
+ * its new end.
+ */
+ if (xche->next) {
+ long l = XDL_MIN(xche->next->i1,
+ xe->xdf1.nrec - 1);
+ if (l - xecfg->ctxlen <= e1 ||
+ get_func_line(xe, xecfg, NULL, l, e1) < 0) {
+ xche = xche->next;
+ goto post_context_calculation;
+ }
+ }
+ }
+#endif
+
+ /*
+ * Emit current hunk header.
+ */
+
+#if 0
+ if (xecfg->flags & XDL_EMIT_FUNCNAMES) {
+ get_func_line(xe, xecfg, &func_line,
+ s1 - 1, funclineprev);
+ funclineprev = s1 - 1;
+ }
+#endif
+ if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
+ func_line.buf, func_line.len, ecb) < 0)
+ return -1;
+
+ /*
+ * Emit pre-context.
+ */
+ for (; s2 < xch->i2; s2++)
+ if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
+ return -1;
+
+ for (s1 = xch->i1, s2 = xch->i2;; xch = xch->next) {
+ /*
+ * Merge previous with current change atom.
+ */
+ for (; s1 < xch->i1 && s2 < xch->i2; s1++, s2++)
+ if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
+ return -1;
+
+ /*
+ * Removes lines from the first file.
+ */
+ for (s1 = xch->i1; s1 < xch->i1 + xch->chg1; s1++)
+ if (xdl_emit_record(&xe->xdf1, s1, "-", ecb) < 0)
+ return -1;
+
+ /*
+ * Adds lines from the second file.
+ */
+ for (s2 = xch->i2; s2 < xch->i2 + xch->chg2; s2++)
+ if (xdl_emit_record(&xe->xdf2, s2, "+", ecb) < 0)
+ return -1;
+
+ if (xch == xche)
+ break;
+ s1 = xch->i1 + xch->chg1;
+ s2 = xch->i2 + xch->chg2;
+ }
+
+ /*
+ * Emit post-context.
+ */
+ for (s2 = xche->i2 + xche->chg2; s2 < e2; s2++)
+ if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/nvim/xdiff/xemit.h b/src/nvim/xdiff/xemit.h
new file mode 100644
index 0000000000..1b9887e670
--- /dev/null
+++ b/src/nvim/xdiff/xemit.h
@@ -0,0 +1,36 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#if !defined(XEMIT_H)
+#define XEMIT_H
+
+
+typedef int (*emit_func_t)(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+ xdemitconf_t const *xecfg);
+
+xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg);
+int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
+ xdemitconf_t const *xecfg);
+
+
+
+#endif /* #if !defined(XEMIT_H) */
diff --git a/src/nvim/xdiff/xhistogram.c b/src/nvim/xdiff/xhistogram.c
new file mode 100644
index 0000000000..3fb8974dd4
--- /dev/null
+++ b/src/nvim/xdiff/xhistogram.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2010, Google Inc.
+ * and other copyright owners as documented in JGit's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "xinclude.h"
+#include "xtypes.h"
+#include "xdiff.h"
+
+#define MAX_PTR INT_MAX
+#define MAX_CNT INT_MAX
+
+#define LINE_END(n) (line##n + count##n - 1)
+#define LINE_END_PTR(n) (*line##n + *count##n - 1)
+
+struct histindex {
+ struct record {
+ unsigned int ptr, cnt;
+ struct record *next;
+ } **records, /* an occurrence */
+ **line_map; /* map of line to record chain */
+ chastore_t rcha;
+ unsigned int *next_ptrs;
+ unsigned int table_bits,
+ records_size,
+ line_map_size;
+
+ unsigned int max_chain_length,
+ key_shift,
+ ptr_shift;
+
+ unsigned int cnt,
+ has_common;
+
+ xdfenv_t *env;
+ xpparam_t const *xpp;
+};
+
+struct region {
+ unsigned int begin1, end1;
+ unsigned int begin2, end2;
+};
+
+#define LINE_MAP(i, a) (i->line_map[(a) - i->ptr_shift])
+
+#define NEXT_PTR(index, ptr) \
+ (index->next_ptrs[(ptr) - index->ptr_shift])
+
+#define CNT(index, ptr) \
+ ((LINE_MAP(index, ptr))->cnt)
+
+#define REC(env, s, l) \
+ (env->xdf##s.recs[l - 1])
+
+static int cmp_recs(xpparam_t const *xpp,
+ xrecord_t *r1, xrecord_t *r2)
+{
+ return r1->ha == r2->ha &&
+ xdl_recmatch(r1->ptr, r1->size, r2->ptr, r2->size,
+ xpp->flags);
+}
+
+#define CMP_ENV(xpp, env, s1, l1, s2, l2) \
+ (cmp_recs(xpp, REC(env, s1, l1), REC(env, s2, l2)))
+
+#define CMP(i, s1, l1, s2, l2) \
+ (cmp_recs(i->xpp, REC(i->env, s1, l1), REC(i->env, s2, l2)))
+
+#define TABLE_HASH(index, side, line) \
+ XDL_HASHLONG((REC(index->env, side, line))->ha, index->table_bits)
+
+static int scanA(struct histindex *index, int line1, int count1)
+{
+ int ptr, tbl_idx;
+ unsigned int chain_len;
+ struct record **rec_chain, *rec;
+
+ for (ptr = LINE_END(1); line1 <= ptr; ptr--) {
+ tbl_idx = TABLE_HASH(index, 1, ptr);
+ rec_chain = index->records + tbl_idx;
+ rec = *rec_chain;
+
+ chain_len = 0;
+ while (rec) {
+ if (CMP(index, 1, rec->ptr, 1, ptr)) {
+ /*
+ * ptr is identical to another element. Insert
+ * it onto the front of the existing element
+ * chain.
+ */
+ NEXT_PTR(index, ptr) = rec->ptr;
+ rec->ptr = ptr;
+ /* cap rec->cnt at MAX_CNT */
+ rec->cnt = XDL_MIN(MAX_CNT, rec->cnt + 1);
+ LINE_MAP(index, ptr) = rec;
+ goto continue_scan;
+ }
+
+ rec = rec->next;
+ chain_len++;
+ }
+
+ if (chain_len == index->max_chain_length)
+ return -1;
+
+ /*
+ * This is the first time we have ever seen this particular
+ * element in the sequence. Construct a new chain for it.
+ */
+ if (!(rec = xdl_cha_alloc(&index->rcha)))
+ return -1;
+ rec->ptr = ptr;
+ rec->cnt = 1;
+ rec->next = *rec_chain;
+ *rec_chain = rec;
+ LINE_MAP(index, ptr) = rec;
+
+continue_scan:
+ ; /* no op */
+ }
+
+ return 0;
+}
+
+static int try_lcs(struct histindex *index, struct region *lcs, int b_ptr,
+ int line1, int count1, int line2, int count2)
+{
+ unsigned int b_next = b_ptr + 1;
+ struct record *rec = index->records[TABLE_HASH(index, 2, b_ptr)];
+ unsigned int as, ae, bs, be, np, rc;
+ int should_break;
+
+ for (; rec; rec = rec->next) {
+ if (rec->cnt > index->cnt) {
+ if (!index->has_common)
+ index->has_common = CMP(index, 1, rec->ptr, 2, b_ptr);
+ continue;
+ }
+
+ as = rec->ptr;
+ if (!CMP(index, 1, as, 2, b_ptr))
+ continue;
+
+ index->has_common = 1;
+ for (;;) {
+ should_break = 0;
+ np = NEXT_PTR(index, as);
+ bs = b_ptr;
+ ae = as;
+ be = bs;
+ rc = rec->cnt;
+
+ while (line1 < (int)as && line2 < (int)bs
+ && CMP(index, 1, as - 1, 2, bs - 1)) {
+ as--;
+ bs--;
+ if (1 < rc)
+ rc = XDL_MIN(rc, CNT(index, as));
+ }
+ while ((int)ae < LINE_END(1) && (int)be < LINE_END(2)
+ && CMP(index, 1, ae + 1, 2, be + 1)) {
+ ae++;
+ be++;
+ if (1 < rc)
+ rc = XDL_MIN(rc, CNT(index, ae));
+ }
+
+ if (b_next <= be)
+ b_next = be + 1;
+ if (lcs->end1 - lcs->begin1 < ae - as || rc < index->cnt) {
+ lcs->begin1 = as;
+ lcs->begin2 = bs;
+ lcs->end1 = ae;
+ lcs->end2 = be;
+ index->cnt = rc;
+ }
+
+ if (np == 0)
+ break;
+
+ while (np <= ae) {
+ np = NEXT_PTR(index, np);
+ if (np == 0) {
+ should_break = 1;
+ break;
+ }
+ }
+
+ if (should_break)
+ break;
+
+ as = np;
+ }
+ }
+ return b_next;
+}
+
+static int fall_back_to_classic_diff(xpparam_t const *xpp, xdfenv_t *env,
+ int line1, int count1, int line2, int count2)
+{
+ xpparam_t xpparam;
+ xpparam.flags = xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
+
+ return xdl_fall_back_diff(env, &xpparam,
+ line1, count1, line2, count2);
+}
+
+static inline void free_index(struct histindex *index)
+{
+ xdl_free(index->records);
+ xdl_free(index->line_map);
+ xdl_free(index->next_ptrs);
+ xdl_cha_free(&index->rcha);
+}
+
+static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
+ struct region *lcs,
+ int line1, int count1, int line2, int count2)
+{
+ int b_ptr;
+ int sz, ret = -1;
+ struct histindex index;
+
+ memset(&index, 0, sizeof(index));
+
+ index.env = env;
+ index.xpp = xpp;
+
+ index.records = NULL;
+ index.line_map = NULL;
+ /* in case of early xdl_cha_free() */
+ index.rcha.head = NULL;
+
+ index.table_bits = xdl_hashbits(count1);
+ sz = index.records_size = 1 << index.table_bits;
+ sz *= sizeof(struct record *);
+ if (!(index.records = (struct record **) xdl_malloc(sz)))
+ goto cleanup;
+ memset(index.records, 0, sz);
+
+ sz = index.line_map_size = count1;
+ sz *= sizeof(struct record *);
+ if (!(index.line_map = (struct record **) xdl_malloc(sz)))
+ goto cleanup;
+ memset(index.line_map, 0, sz);
+
+ sz = index.line_map_size;
+ sz *= sizeof(unsigned int);
+ if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
+ goto cleanup;
+ memset(index.next_ptrs, 0, sz);
+
+ /* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
+ if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
+ goto cleanup;
+
+ index.ptr_shift = line1;
+ index.max_chain_length = 64;
+
+ if (scanA(&index, line1, count1))
+ goto cleanup;
+
+ index.cnt = index.max_chain_length + 1;
+
+ for (b_ptr = line2; b_ptr <= LINE_END(2); )
+ b_ptr = try_lcs(&index, lcs, b_ptr, line1, count1, line2, count2);
+
+ if (index.has_common && index.max_chain_length < index.cnt)
+ ret = 1;
+ else
+ ret = 0;
+
+cleanup:
+ free_index(&index);
+ return ret;
+}
+
+static int histogram_diff(xpparam_t const *xpp, xdfenv_t *env,
+ int line1, int count1, int line2, int count2)
+{
+ struct region lcs;
+ int lcs_found;
+ int result;
+redo:
+ result = -1;
+
+ if (count1 <= 0 && count2 <= 0)
+ return 0;
+
+ if (LINE_END(1) >= MAX_PTR)
+ return -1;
+
+ if (!count1) {
+ while(count2--)
+ env->xdf2.rchg[line2++ - 1] = 1;
+ return 0;
+ } else if (!count2) {
+ while(count1--)
+ env->xdf1.rchg[line1++ - 1] = 1;
+ return 0;
+ }
+
+ memset(&lcs, 0, sizeof(lcs));
+ lcs_found = find_lcs(xpp, env, &lcs, line1, count1, line2, count2);
+ if (lcs_found < 0)
+ goto out;
+ else if (lcs_found)
+ result = fall_back_to_classic_diff(xpp, env, line1, count1, line2, count2);
+ else {
+ if (lcs.begin1 == 0 && lcs.begin2 == 0) {
+ while (count1--)
+ env->xdf1.rchg[line1++ - 1] = 1;
+ while (count2--)
+ env->xdf2.rchg[line2++ - 1] = 1;
+ result = 0;
+ } else {
+ result = histogram_diff(xpp, env,
+ line1, lcs.begin1 - line1,
+ line2, lcs.begin2 - line2);
+ if (result)
+ goto out;
+ /*
+ * result = histogram_diff(xpp, env,
+ * lcs.end1 + 1, LINE_END(1) - lcs.end1,
+ * lcs.end2 + 1, LINE_END(2) - lcs.end2);
+ * but let's optimize tail recursion ourself:
+ */
+ count1 = LINE_END(1) - lcs.end1;
+ line1 = lcs.end1 + 1;
+ count2 = LINE_END(2) - lcs.end2;
+ line2 = lcs.end2 + 1;
+ goto redo;
+ }
+ }
+out:
+ return result;
+}
+
+int xdl_do_histogram_diff(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env)
+{
+ if (xdl_prepare_env(file1, file2, xpp, env) < 0)
+ return -1;
+
+ return histogram_diff(xpp, env,
+ env->xdf1.dstart + 1, env->xdf1.dend - env->xdf1.dstart + 1,
+ env->xdf2.dstart + 1, env->xdf2.dend - env->xdf2.dstart + 1);
+}
diff --git a/src/nvim/xdiff/xinclude.h b/src/nvim/xdiff/xinclude.h
new file mode 100644
index 0000000000..46b8608314
--- /dev/null
+++ b/src/nvim/xdiff/xinclude.h
@@ -0,0 +1,61 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+/* defines HAVE_ATTRIBUTE_UNUSED */
+#ifdef HAVE_CONFIG_H
+# include "../auto/config.h"
+#endif
+
+/* Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter
+ * can be used to check for mistakes. */
+#ifdef HAVE_ATTRIBUTE_UNUSED
+# define UNUSED __attribute__((unused))
+#else
+# define UNUSED
+#endif
+
+#if defined(_MSC_VER)
+# define inline __inline
+#endif
+
+#if !defined(XINCLUDE_H)
+#define XINCLUDE_H
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if !defined(_WIN32)
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <limits.h>
+
+#include "xmacros.h"
+#include "xdiff.h"
+#include "xtypes.h"
+#include "xutils.h"
+#include "xprepare.h"
+#include "xdiffi.h"
+#include "xemit.h"
+
+
+#endif /* #if !defined(XINCLUDE_H) */
diff --git a/src/nvim/xdiff/xmacros.h b/src/nvim/xdiff/xmacros.h
new file mode 100644
index 0000000000..2809a28ca9
--- /dev/null
+++ b/src/nvim/xdiff/xmacros.h
@@ -0,0 +1,54 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#if !defined(XMACROS_H)
+#define XMACROS_H
+
+
+
+
+#define XDL_MIN(a, b) ((a) < (b) ? (a): (b))
+#define XDL_MAX(a, b) ((a) > (b) ? (a): (b))
+#define XDL_ABS(v) ((v) >= 0 ? (v): -(v))
+#define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
+#define XDL_ISSPACE(c) (isspace((unsigned char)(c)))
+#define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
+#define XDL_MASKBITS(b) ((1UL << (b)) - 1)
+#define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
+#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
+#define XDL_LE32_PUT(p, v) \
+do { \
+ unsigned char *__p = (unsigned char *) (p); \
+ *__p++ = (unsigned char) (v); \
+ *__p++ = (unsigned char) ((v) >> 8); \
+ *__p++ = (unsigned char) ((v) >> 16); \
+ *__p = (unsigned char) ((v) >> 24); \
+} while (0)
+#define XDL_LE32_GET(p, v) \
+do { \
+ unsigned char const *__p = (unsigned char const *) (p); \
+ (v) = (unsigned long) __p[0] | ((unsigned long) __p[1]) << 8 | \
+ ((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
+} while (0)
+
+
+#endif /* #if !defined(XMACROS_H) */
diff --git a/src/nvim/xdiff/xpatience.c b/src/nvim/xdiff/xpatience.c
new file mode 100644
index 0000000000..2c65aac386
--- /dev/null
+++ b/src/nvim/xdiff/xpatience.c
@@ -0,0 +1,393 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003-2016 Davide Libenzi, Johannes E. Schindelin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+#include "xinclude.h"
+#include "xtypes.h"
+#include "xdiff.h"
+
+/*
+ * The basic idea of patience diff is to find lines that are unique in
+ * both files. These are intuitively the ones that we want to see as
+ * common lines.
+ *
+ * The maximal ordered sequence of such line pairs (where ordered means
+ * that the order in the sequence agrees with the order of the lines in
+ * both files) naturally defines an initial set of common lines.
+ *
+ * Now, the algorithm tries to extend the set of common lines by growing
+ * the line ranges where the files have identical lines.
+ *
+ * Between those common lines, the patience diff algorithm is applied
+ * recursively, until no unique line pairs can be found; these line ranges
+ * are handled by the well-known Myers algorithm.
+ */
+
+#define NON_UNIQUE ULONG_MAX
+
+/*
+ * This is a hash mapping from line hash to line numbers in the first and
+ * second file.
+ */
+struct hashmap {
+ int nr, alloc;
+ struct entry {
+ unsigned long hash;
+ /*
+ * 0 = unused entry, 1 = first line, 2 = second, etc.
+ * line2 is NON_UNIQUE if the line is not unique
+ * in either the first or the second file.
+ */
+ unsigned long line1, line2;
+ /*
+ * "next" & "previous" are used for the longest common
+ * sequence;
+ * initially, "next" reflects only the order in file1.
+ */
+ struct entry *next, *previous;
+
+ /*
+ * If 1, this entry can serve as an anchor. See
+ * Documentation/diff-options.txt for more information.
+ */
+ unsigned anchor : 1;
+ } *entries, *first, *last;
+ /* were common records found? */
+ unsigned long has_matches;
+ mmfile_t *file1, *file2;
+ xdfenv_t *env;
+ xpparam_t const *xpp;
+};
+
+static int is_anchor(xpparam_t const *xpp, const char *line)
+{
+ size_t i;
+ for (i = 0; i < xpp->anchors_nr; i++) {
+ if (!strncmp(line, xpp->anchors[i], strlen(xpp->anchors[i])))
+ return 1;
+ }
+ return 0;
+}
+
+/* The argument "pass" is 1 for the first file, 2 for the second. */
+static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
+ int pass)
+{
+ xrecord_t **records = pass == 1 ?
+ map->env->xdf1.recs : map->env->xdf2.recs;
+ xrecord_t *record = records[line - 1], *other;
+ /*
+ * After xdl_prepare_env() (or more precisely, due to
+ * xdl_classify_record()), the "ha" member of the records (AKA lines)
+ * is _not_ the hash anymore, but a linearized version of it. In
+ * other words, the "ha" member is guaranteed to start with 0 and
+ * the second record's ha can only be 0 or 1, etc.
+ *
+ * So we multiply ha by 2 in the hope that the hashing was
+ * "unique enough".
+ */
+ int index = (int)((record->ha << 1) % map->alloc);
+
+ while (map->entries[index].line1) {
+ other = map->env->xdf1.recs[map->entries[index].line1 - 1];
+ if (map->entries[index].hash != record->ha ||
+ !xdl_recmatch(record->ptr, record->size,
+ other->ptr, other->size,
+ map->xpp->flags)) {
+ if (++index >= map->alloc)
+ index = 0;
+ continue;
+ }
+ if (pass == 2)
+ map->has_matches = 1;
+ if (pass == 1 || map->entries[index].line2)
+ map->entries[index].line2 = NON_UNIQUE;
+ else
+ map->entries[index].line2 = line;
+ return;
+ }
+ if (pass == 2)
+ return;
+ map->entries[index].line1 = line;
+ map->entries[index].hash = record->ha;
+ map->entries[index].anchor = is_anchor(xpp, map->env->xdf1.recs[line - 1]->ptr);
+ if (!map->first)
+ map->first = map->entries + index;
+ if (map->last) {
+ map->last->next = map->entries + index;
+ map->entries[index].previous = map->last;
+ }
+ map->last = map->entries + index;
+ map->nr++;
+}
+
+/*
+ * This function has to be called for each recursion into the inter-hunk
+ * parts, as previously non-unique lines can become unique when being
+ * restricted to a smaller part of the files.
+ *
+ * It is assumed that env has been prepared using xdl_prepare().
+ */
+static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env,
+ struct hashmap *result,
+ int line1, int count1, int line2, int count2)
+{
+ result->file1 = file1;
+ result->file2 = file2;
+ result->xpp = xpp;
+ result->env = env;
+
+ /* We know exactly how large we want the hash map */
+ result->alloc = count1 * 2;
+ result->entries = (struct entry *)
+ xdl_malloc(result->alloc * sizeof(struct entry));
+ if (!result->entries)
+ return -1;
+ memset(result->entries, 0, result->alloc * sizeof(struct entry));
+
+ /* First, fill with entries from the first file */
+ while (count1--)
+ insert_record(xpp, line1++, result, 1);
+
+ /* Then search for matches in the second file */
+ while (count2--)
+ insert_record(xpp, line2++, result, 2);
+
+ return 0;
+}
+
+/*
+ * Find the longest sequence with a smaller last element (meaning a smaller
+ * line2, as we construct the sequence with entries ordered by line1).
+ */
+static int binary_search(struct entry **sequence, int longest,
+ struct entry *entry)
+{
+ int left = -1, right = longest;
+
+ while (left + 1 < right) {
+ int middle = left + (right - left) / 2;
+ /* by construction, no two entries can be equal */
+ if (sequence[middle]->line2 > entry->line2)
+ right = middle;
+ else
+ left = middle;
+ }
+ /* return the index in "sequence", _not_ the sequence length */
+ return left;
+}
+
+/*
+ * The idea is to start with the list of common unique lines sorted by
+ * the order in file1. For each of these pairs, the longest (partial)
+ * sequence whose last element's line2 is smaller is determined.
+ *
+ * For efficiency, the sequences are kept in a list containing exactly one
+ * item per sequence length: the sequence with the smallest last
+ * element (in terms of line2).
+ */
+static struct entry *find_longest_common_sequence(struct hashmap *map)
+{
+ struct entry **sequence = (struct entry **)xdl_malloc(map->nr * sizeof(struct entry *));
+ int longest = 0, i;
+ struct entry *entry;
+ /*
+ * If not -1, this entry in sequence must never be overridden.
+ * Therefore, overriding entries before this has no effect, so
+ * do not do that either.
+ */
+ int anchor_i = -1;
+
+ /* Added to silence Coverity. */
+ if (sequence == NULL)
+ return map->first;
+
+ for (entry = map->first; entry; entry = entry->next) {
+ if (!entry->line2 || entry->line2 == NON_UNIQUE)
+ continue;
+ i = binary_search(sequence, longest, entry);
+ entry->previous = i < 0 ? NULL : sequence[i];
+ ++i;
+ if (i <= anchor_i)
+ continue;
+ sequence[i] = entry;
+ if (entry->anchor) {
+ anchor_i = i;
+ longest = anchor_i + 1;
+ } else if (i == longest) {
+ longest++;
+ }
+ }
+
+ /* No common unique lines were found */
+ if (!longest) {
+ xdl_free(sequence);
+ return NULL;
+ }
+
+ /* Iterate starting at the last element, adjusting the "next" members */
+ entry = sequence[longest - 1];
+ entry->next = NULL;
+ while (entry->previous) {
+ entry->previous->next = entry;
+ entry = entry->previous;
+ }
+ xdl_free(sequence);
+ return entry;
+}
+
+static int match(struct hashmap *map, int line1, int line2)
+{
+ xrecord_t *record1 = map->env->xdf1.recs[line1 - 1];
+ xrecord_t *record2 = map->env->xdf2.recs[line2 - 1];
+ return xdl_recmatch(record1->ptr, record1->size,
+ record2->ptr, record2->size, map->xpp->flags);
+}
+
+static int patience_diff(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env,
+ int line1, int count1, int line2, int count2);
+
+static int walk_common_sequence(struct hashmap *map, struct entry *first,
+ int line1, int count1, int line2, int count2)
+{
+ int end1 = line1 + count1, end2 = line2 + count2;
+ int next1, next2;
+
+ for (;;) {
+ /* Try to grow the line ranges of common lines */
+ if (first) {
+ next1 = first->line1;
+ next2 = first->line2;
+ while (next1 > line1 && next2 > line2 &&
+ match(map, next1 - 1, next2 - 1)) {
+ next1--;
+ next2--;
+ }
+ } else {
+ next1 = end1;
+ next2 = end2;
+ }
+ while (line1 < next1 && line2 < next2 &&
+ match(map, line1, line2)) {
+ line1++;
+ line2++;
+ }
+
+ /* Recurse */
+ if (next1 > line1 || next2 > line2) {
+ struct hashmap submap;
+
+ memset(&submap, 0, sizeof(submap));
+ if (patience_diff(map->file1, map->file2,
+ map->xpp, map->env,
+ line1, next1 - line1,
+ line2, next2 - line2))
+ return -1;
+ }
+
+ if (!first)
+ return 0;
+
+ while (first->next &&
+ first->next->line1 == first->line1 + 1 &&
+ first->next->line2 == first->line2 + 1)
+ first = first->next;
+
+ line1 = first->line1 + 1;
+ line2 = first->line2 + 1;
+
+ first = first->next;
+ }
+}
+
+static int fall_back_to_classic_diff(struct hashmap *map,
+ int line1, int count1, int line2, int count2)
+{
+ xpparam_t xpp;
+ xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
+
+ return xdl_fall_back_diff(map->env, &xpp,
+ line1, count1, line2, count2);
+}
+
+/*
+ * Recursively find the longest common sequence of unique lines,
+ * and if none was found, ask xdl_do_diff() to do the job.
+ *
+ * This function assumes that env was prepared with xdl_prepare_env().
+ */
+static int patience_diff(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env,
+ int line1, int count1, int line2, int count2)
+{
+ struct hashmap map;
+ struct entry *first;
+ int result = 0;
+
+ /* trivial case: one side is empty */
+ if (!count1) {
+ while(count2--)
+ env->xdf2.rchg[line2++ - 1] = 1;
+ return 0;
+ } else if (!count2) {
+ while(count1--)
+ env->xdf1.rchg[line1++ - 1] = 1;
+ return 0;
+ }
+
+ memset(&map, 0, sizeof(map));
+ if (fill_hashmap(file1, file2, xpp, env, &map,
+ line1, count1, line2, count2))
+ return -1;
+
+ /* are there any matching lines at all? */
+ if (!map.has_matches) {
+ while(count1--)
+ env->xdf1.rchg[line1++ - 1] = 1;
+ while(count2--)
+ env->xdf2.rchg[line2++ - 1] = 1;
+ xdl_free(map.entries);
+ return 0;
+ }
+
+ first = find_longest_common_sequence(&map);
+ if (first)
+ result = walk_common_sequence(&map, first,
+ line1, count1, line2, count2);
+ else
+ result = fall_back_to_classic_diff(&map,
+ line1, count1, line2, count2);
+
+ xdl_free(map.entries);
+ return result;
+}
+
+int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
+ xpparam_t const *xpp, xdfenv_t *env)
+{
+ if (xdl_prepare_env(file1, file2, xpp, env) < 0)
+ return -1;
+
+ /* environment is cleaned up in xdl_diff() */
+ return patience_diff(file1, file2, xpp, env,
+ 1, env->xdf1.nrec, 1, env->xdf2.nrec);
+}
diff --git a/src/nvim/xdiff/xprepare.c b/src/nvim/xdiff/xprepare.c
new file mode 100644
index 0000000000..abeb8fb84e
--- /dev/null
+++ b/src/nvim/xdiff/xprepare.c
@@ -0,0 +1,483 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#include "xinclude.h"
+
+
+#define XDL_KPDIS_RUN 4
+#define XDL_MAX_EQLIMIT 1024
+#define XDL_SIMSCAN_WINDOW 100
+#define XDL_GUESS_NLINES1 256
+#define XDL_GUESS_NLINES2 20
+
+
+typedef struct s_xdlclass {
+ struct s_xdlclass *next;
+ unsigned long ha;
+ char const *line;
+ long size;
+ long idx;
+ long len1, len2;
+} xdlclass_t;
+
+typedef struct s_xdlclassifier {
+ unsigned int hbits;
+ long hsize;
+ xdlclass_t **rchash;
+ chastore_t ncha;
+ xdlclass_t **rcrecs;
+ long alloc;
+ long count;
+ long flags;
+} xdlclassifier_t;
+
+
+
+
+static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags);
+static void xdl_free_classifier(xdlclassifier_t *cf);
+static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t **rhash,
+ unsigned int hbits, xrecord_t *rec);
+static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
+ xdlclassifier_t *cf, xdfile_t *xdf);
+static void xdl_free_ctx(xdfile_t *xdf);
+static int xdl_clean_mmatch(char const *dis, long i, long s, long e);
+static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2);
+static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2);
+static int xdl_optimize_ctxs(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2);
+
+
+
+
+static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
+ cf->flags = flags;
+
+ cf->hbits = xdl_hashbits((unsigned int) size);
+ cf->hsize = 1 << cf->hbits;
+
+ if (xdl_cha_init(&cf->ncha, sizeof(xdlclass_t), size / 4 + 1) < 0) {
+
+ return -1;
+ }
+ if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {
+
+ xdl_cha_free(&cf->ncha);
+ return -1;
+ }
+ memset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));
+
+ cf->alloc = size;
+ if (!(cf->rcrecs = (xdlclass_t **) xdl_malloc(cf->alloc * sizeof(xdlclass_t *)))) {
+
+ xdl_free(cf->rchash);
+ xdl_cha_free(&cf->ncha);
+ return -1;
+ }
+
+ cf->count = 0;
+
+ return 0;
+}
+
+
+static void xdl_free_classifier(xdlclassifier_t *cf) {
+
+ xdl_free(cf->rcrecs);
+ xdl_free(cf->rchash);
+ xdl_cha_free(&cf->ncha);
+}
+
+
+static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t **rhash,
+ unsigned int hbits, xrecord_t *rec) {
+ long hi;
+ char const *line;
+ xdlclass_t *rcrec;
+ xdlclass_t **rcrecs;
+
+ line = rec->ptr;
+ hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
+ for (rcrec = cf->rchash[hi]; rcrec; rcrec = rcrec->next)
+ if (rcrec->ha == rec->ha &&
+ xdl_recmatch(rcrec->line, rcrec->size,
+ rec->ptr, rec->size, cf->flags))
+ break;
+
+ if (!rcrec) {
+ if (!(rcrec = xdl_cha_alloc(&cf->ncha))) {
+
+ return -1;
+ }
+ rcrec->idx = cf->count++;
+ if (cf->count > cf->alloc) {
+ cf->alloc *= 2;
+ if (!(rcrecs = (xdlclass_t **) xdl_realloc(cf->rcrecs, cf->alloc * sizeof(xdlclass_t *)))) {
+
+ return -1;
+ }
+ cf->rcrecs = rcrecs;
+ }
+ cf->rcrecs[rcrec->idx] = rcrec;
+ rcrec->line = line;
+ rcrec->size = rec->size;
+ rcrec->ha = rec->ha;
+ rcrec->len1 = rcrec->len2 = 0;
+ rcrec->next = cf->rchash[hi];
+ cf->rchash[hi] = rcrec;
+ }
+
+ (pass == 1) ? rcrec->len1++ : rcrec->len2++;
+
+ rec->ha = (unsigned long) rcrec->idx;
+
+ hi = (long) XDL_HASHLONG(rec->ha, hbits);
+ rec->next = rhash[hi];
+ rhash[hi] = rec;
+
+ return 0;
+}
+
+
+static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
+ xdlclassifier_t *cf, xdfile_t *xdf) {
+ unsigned int hbits;
+ long nrec, hsize, bsize;
+ unsigned long hav;
+ char const *blk, *cur, *top, *prev;
+ xrecord_t *crec;
+ xrecord_t **recs, **rrecs;
+ xrecord_t **rhash;
+ unsigned long *ha;
+ char *rchg;
+ long *rindex;
+
+ ha = NULL;
+ rindex = NULL;
+ rchg = NULL;
+ rhash = NULL;
+ recs = NULL;
+
+ if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
+ goto abort;
+ if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
+ goto abort;
+
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
+ hbits = hsize = 0;
+ else {
+ hbits = xdl_hashbits((unsigned int) narec);
+ hsize = 1 << hbits;
+ if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))
+ goto abort;
+ memset(rhash, 0, hsize * sizeof(xrecord_t *));
+ }
+
+ nrec = 0;
+ if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
+ for (top = blk + bsize; cur < top; ) {
+ prev = cur;
+ hav = xdl_hash_record(&cur, top, xpp->flags);
+ if (nrec >= narec) {
+ narec *= 2;
+ if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
+ goto abort;
+ recs = rrecs;
+ }
+ if (!(crec = xdl_cha_alloc(&xdf->rcha)))
+ goto abort;
+ crec->ptr = prev;
+ crec->size = (long) (cur - prev);
+ crec->ha = hav;
+ recs[nrec++] = crec;
+
+ if ((XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+ xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
+ goto abort;
+ }
+ }
+
+ if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))
+ goto abort;
+ memset(rchg, 0, (nrec + 2) * sizeof(char));
+
+ if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long))))
+ goto abort;
+ if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long))))
+ goto abort;
+
+ xdf->nrec = nrec;
+ xdf->recs = recs;
+ xdf->hbits = hbits;
+ xdf->rhash = rhash;
+ xdf->rchg = rchg + 1;
+ xdf->rindex = rindex;
+ xdf->nreff = 0;
+ xdf->ha = ha;
+ xdf->dstart = 0;
+ xdf->dend = nrec - 1;
+
+ return 0;
+
+abort:
+ xdl_free(ha);
+ xdl_free(rindex);
+ xdl_free(rchg);
+ xdl_free(rhash);
+ xdl_free(recs);
+ xdl_cha_free(&xdf->rcha);
+ return -1;
+}
+
+
+static void xdl_free_ctx(xdfile_t *xdf) {
+
+ xdl_free(xdf->rhash);
+ xdl_free(xdf->rindex);
+ xdl_free(xdf->rchg - 1);
+ xdl_free(xdf->ha);
+ xdl_free(xdf->recs);
+ xdl_cha_free(&xdf->rcha);
+}
+
+
+int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdfenv_t *xe) {
+ long enl1, enl2, sample;
+ xdlclassifier_t cf;
+
+ memset(&cf, 0, sizeof(cf));
+
+ /*
+ * For histogram diff, we can afford a smaller sample size and
+ * thus a poorer estimate of the number of lines, as the hash
+ * table (rhash) won't be filled up/grown. The number of lines
+ * (nrecs) will be updated correctly anyway by
+ * xdl_prepare_ctx().
+ */
+ sample = (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF
+ ? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1);
+
+ enl1 = xdl_guess_lines(mf1, sample) + 1;
+ enl2 = xdl_guess_lines(mf2, sample) + 1;
+
+ if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF &&
+ xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0)
+ return -1;
+
+ if (xdl_prepare_ctx(1, mf1, enl1, xpp, &cf, &xe->xdf1) < 0) {
+
+ xdl_free_classifier(&cf);
+ return -1;
+ }
+ if (xdl_prepare_ctx(2, mf2, enl2, xpp, &cf, &xe->xdf2) < 0) {
+
+ xdl_free_ctx(&xe->xdf1);
+ xdl_free_classifier(&cf);
+ return -1;
+ }
+
+ if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
+ (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+ xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
+
+ xdl_free_ctx(&xe->xdf2);
+ xdl_free_ctx(&xe->xdf1);
+ xdl_free_classifier(&cf);
+ return -1;
+ }
+
+ if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)
+ xdl_free_classifier(&cf);
+
+ return 0;
+}
+
+
+void xdl_free_env(xdfenv_t *xe) {
+
+ xdl_free_ctx(&xe->xdf2);
+ xdl_free_ctx(&xe->xdf1);
+}
+
+
+static int xdl_clean_mmatch(char const *dis, long i, long s, long e) {
+ long r, rdis0, rpdis0, rdis1, rpdis1;
+
+ /*
+ * Limits the window the is examined during the similar-lines
+ * scan. The loops below stops when dis[i - r] == 1 (line that
+ * has no match), but there are corner cases where the loop
+ * proceed all the way to the extremities by causing huge
+ * performance penalties in case of big files.
+ */
+ if (i - s > XDL_SIMSCAN_WINDOW)
+ s = i - XDL_SIMSCAN_WINDOW;
+ if (e - i > XDL_SIMSCAN_WINDOW)
+ e = i + XDL_SIMSCAN_WINDOW;
+
+ /*
+ * Scans the lines before 'i' to find a run of lines that either
+ * have no match (dis[j] == 0) or have multiple matches (dis[j] > 1).
+ * Note that we always call this function with dis[i] > 1, so the
+ * current line (i) is already a multimatch line.
+ */
+ for (r = 1, rdis0 = 0, rpdis0 = 1; (i - r) >= s; r++) {
+ if (!dis[i - r])
+ rdis0++;
+ else if (dis[i - r] == 2)
+ rpdis0++;
+ else
+ break;
+ }
+ /*
+ * If the run before the line 'i' found only multimatch lines, we
+ * return 0 and hence we don't make the current line (i) discarded.
+ * We want to discard multimatch lines only when they appear in the
+ * middle of runs with nomatch lines (dis[j] == 0).
+ */
+ if (rdis0 == 0)
+ return 0;
+ for (r = 1, rdis1 = 0, rpdis1 = 1; (i + r) <= e; r++) {
+ if (!dis[i + r])
+ rdis1++;
+ else if (dis[i + r] == 2)
+ rpdis1++;
+ else
+ break;
+ }
+ /*
+ * If the run after the line 'i' found only multimatch lines, we
+ * return 0 and hence we don't make the current line (i) discarded.
+ */
+ if (rdis1 == 0)
+ return 0;
+ rdis1 += rdis0;
+ rpdis1 += rpdis0;
+
+ return rpdis1 * XDL_KPDIS_RUN < (rpdis1 + rdis1);
+}
+
+
+/*
+ * Try to reduce the problem complexity, discard records that have no
+ * matches on the other file. Also, lines that have multiple matches
+ * might be potentially discarded if they happear in a run of discardable.
+ */
+static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2) {
+ long i, nm, nreff, mlim;
+ xrecord_t **recs;
+ xdlclass_t *rcrec;
+ char *dis, *dis1, *dis2;
+
+ if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {
+
+ return -1;
+ }
+ memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
+ dis1 = dis;
+ dis2 = dis1 + xdf1->nrec + 1;
+
+ if ((mlim = xdl_bogosqrt(xdf1->nrec)) > XDL_MAX_EQLIMIT)
+ mlim = XDL_MAX_EQLIMIT;
+ for (i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; i <= xdf1->dend; i++, recs++) {
+ rcrec = cf->rcrecs[(*recs)->ha];
+ nm = rcrec ? rcrec->len2 : 0;
+ dis1[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
+ }
+
+ if ((mlim = xdl_bogosqrt(xdf2->nrec)) > XDL_MAX_EQLIMIT)
+ mlim = XDL_MAX_EQLIMIT;
+ for (i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart]; i <= xdf2->dend; i++, recs++) {
+ rcrec = cf->rcrecs[(*recs)->ha];
+ nm = rcrec ? rcrec->len1 : 0;
+ dis2[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
+ }
+
+ for (nreff = 0, i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart];
+ i <= xdf1->dend; i++, recs++) {
+ if (dis1[i] == 1 ||
+ (dis1[i] == 2 && !xdl_clean_mmatch(dis1, i, xdf1->dstart, xdf1->dend))) {
+ xdf1->rindex[nreff] = i;
+ xdf1->ha[nreff] = (*recs)->ha;
+ nreff++;
+ } else
+ xdf1->rchg[i] = 1;
+ }
+ xdf1->nreff = nreff;
+
+ for (nreff = 0, i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart];
+ i <= xdf2->dend; i++, recs++) {
+ if (dis2[i] == 1 ||
+ (dis2[i] == 2 && !xdl_clean_mmatch(dis2, i, xdf2->dstart, xdf2->dend))) {
+ xdf2->rindex[nreff] = i;
+ xdf2->ha[nreff] = (*recs)->ha;
+ nreff++;
+ } else
+ xdf2->rchg[i] = 1;
+ }
+ xdf2->nreff = nreff;
+
+ xdl_free(dis);
+
+ return 0;
+}
+
+
+/*
+ * Early trim initial and terminal matching records.
+ */
+static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2) {
+ long i, lim;
+ xrecord_t **recs1, **recs2;
+
+ recs1 = xdf1->recs;
+ recs2 = xdf2->recs;
+ for (i = 0, lim = XDL_MIN(xdf1->nrec, xdf2->nrec); i < lim;
+ i++, recs1++, recs2++)
+ if ((*recs1)->ha != (*recs2)->ha)
+ break;
+
+ xdf1->dstart = xdf2->dstart = i;
+
+ recs1 = xdf1->recs + xdf1->nrec - 1;
+ recs2 = xdf2->recs + xdf2->nrec - 1;
+ for (lim -= i, i = 0; i < lim; i++, recs1--, recs2--)
+ if ((*recs1)->ha != (*recs2)->ha)
+ break;
+
+ xdf1->dend = xdf1->nrec - i - 1;
+ xdf2->dend = xdf2->nrec - i - 1;
+
+ return 0;
+}
+
+
+static int xdl_optimize_ctxs(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2) {
+
+ if (xdl_trim_ends(xdf1, xdf2) < 0 ||
+ xdl_cleanup_records(cf, xdf1, xdf2) < 0) {
+
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/nvim/xdiff/xprepare.h b/src/nvim/xdiff/xprepare.h
new file mode 100644
index 0000000000..947d9fc1bb
--- /dev/null
+++ b/src/nvim/xdiff/xprepare.h
@@ -0,0 +1,34 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#if !defined(XPREPARE_H)
+#define XPREPARE_H
+
+
+
+int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
+ xdfenv_t *xe);
+void xdl_free_env(xdfenv_t *xe);
+
+
+
+#endif /* #if !defined(XPREPARE_H) */
diff --git a/src/nvim/xdiff/xtypes.h b/src/nvim/xdiff/xtypes.h
new file mode 100644
index 0000000000..8442bd436e
--- /dev/null
+++ b/src/nvim/xdiff/xtypes.h
@@ -0,0 +1,67 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#if !defined(XTYPES_H)
+#define XTYPES_H
+
+
+
+typedef struct s_chanode {
+ struct s_chanode *next;
+ long icurr;
+} chanode_t;
+
+typedef struct s_chastore {
+ chanode_t *head, *tail;
+ long isize, nsize;
+ chanode_t *ancur;
+ chanode_t *sncur;
+ long scurr;
+} chastore_t;
+
+typedef struct s_xrecord {
+ struct s_xrecord *next;
+ char const *ptr;
+ long size;
+ unsigned long ha;
+} xrecord_t;
+
+typedef struct s_xdfile {
+ chastore_t rcha;
+ long nrec;
+ unsigned int hbits;
+ xrecord_t **rhash;
+ long dstart, dend;
+ xrecord_t **recs;
+ char *rchg;
+ long *rindex;
+ long nreff;
+ unsigned long *ha;
+} xdfile_t;
+
+typedef struct s_xdfenv {
+ xdfile_t xdf1, xdf2;
+} xdfenv_t;
+
+
+
+#endif /* #if !defined(XTYPES_H) */
diff --git a/src/nvim/xdiff/xutils.c b/src/nvim/xdiff/xutils.c
new file mode 100644
index 0000000000..25a090fb73
--- /dev/null
+++ b/src/nvim/xdiff/xutils.c
@@ -0,0 +1,425 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#include <limits.h>
+#include <assert.h>
+#include "xinclude.h"
+
+
+
+
+long xdl_bogosqrt(long n) {
+ long i;
+
+ /*
+ * Classical integer square root approximation using shifts.
+ */
+ for (i = 1; n > 0; n >>= 2)
+ i <<= 1;
+
+ return i;
+}
+
+
+int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
+ xdemitcb_t *ecb) {
+ int i = 2;
+ mmbuffer_t mb[3];
+
+ mb[0].ptr = (char *) pre;
+ mb[0].size = psize;
+ mb[1].ptr = (char *) rec;
+ mb[1].size = size;
+ if (size > 0 && rec[size - 1] != '\n') {
+ mb[2].ptr = (char *) "\n\\ No newline at end of file\n";
+ mb[2].size = (long)strlen(mb[2].ptr);
+ i++;
+ }
+ if (ecb->outf(ecb->priv, mb, i) < 0) {
+
+ return -1;
+ }
+
+ return 0;
+}
+
+void *xdl_mmfile_first(mmfile_t *mmf, long *size)
+{
+ *size = mmf->size;
+ return mmf->ptr;
+}
+
+
+long xdl_mmfile_size(mmfile_t *mmf)
+{
+ return mmf->size;
+}
+
+
+int xdl_cha_init(chastore_t *cha, long isize, long icount) {
+
+ cha->head = cha->tail = NULL;
+ cha->isize = isize;
+ cha->nsize = icount * isize;
+ cha->ancur = cha->sncur = NULL;
+ cha->scurr = 0;
+
+ return 0;
+}
+
+
+void xdl_cha_free(chastore_t *cha) {
+ chanode_t *cur, *tmp;
+
+ for (cur = cha->head; (tmp = cur) != NULL;) {
+ cur = cur->next;
+ xdl_free(tmp);
+ }
+}
+
+
+void *xdl_cha_alloc(chastore_t *cha) {
+ chanode_t *ancur;
+ void *data;
+
+ if (!(ancur = cha->ancur) || ancur->icurr == cha->nsize) {
+ if (!(ancur = (chanode_t *) xdl_malloc(sizeof(chanode_t) + cha->nsize))) {
+
+ return NULL;
+ }
+ ancur->icurr = 0;
+ ancur->next = NULL;
+ if (cha->tail)
+ cha->tail->next = ancur;
+ if (!cha->head)
+ cha->head = ancur;
+ cha->tail = ancur;
+ cha->ancur = ancur;
+ }
+
+ data = (char *) ancur + sizeof(chanode_t) + ancur->icurr;
+ ancur->icurr += cha->isize;
+
+ return data;
+}
+
+long xdl_guess_lines(mmfile_t *mf, long sample) {
+ long nl = 0, size, tsize = 0;
+ char const *data, *cur, *top;
+
+ if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
+ for (top = data + size; nl < sample && cur < top; ) {
+ nl++;
+ if (!(cur = memchr(cur, '\n', top - cur)))
+ cur = top;
+ else
+ cur++;
+ }
+ tsize += (long) (cur - data);
+ }
+
+ if (nl && tsize)
+ nl = xdl_mmfile_size(mf) / (tsize / nl);
+
+ return nl + 1;
+}
+
+int xdl_blankline(const char *line, long size, long flags)
+{
+ long i;
+
+ if (!(flags & XDF_WHITESPACE_FLAGS))
+ return (size <= 1);
+
+ for (i = 0; i < size && XDL_ISSPACE(line[i]); i++)
+ ;
+
+ return (i == size);
+}
+
+/*
+ * Have we eaten everything on the line, except for an optional
+ * CR at the very end?
+ */
+static int ends_with_optional_cr(const char *l, long s, long i)
+{
+ int complete = s && l[s-1] == '\n';
+
+ if (complete)
+ s--;
+ if (s == i)
+ return 1;
+ /* do not ignore CR at the end of an incomplete line */
+ if (complete && s == i + 1 && l[i] == '\r')
+ return 1;
+ return 0;
+}
+
+int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
+{
+ int i1, i2;
+
+ if (s1 == s2 && !memcmp(l1, l2, s1))
+ return 1;
+ if (!(flags & XDF_WHITESPACE_FLAGS))
+ return 0;
+
+ i1 = 0;
+ i2 = 0;
+
+ /*
+ * -w matches everything that matches with -b, and -b in turn
+ * matches everything that matches with --ignore-space-at-eol,
+ * which in turn matches everything that matches with --ignore-cr-at-eol.
+ *
+ * Each flavor of ignoring needs different logic to skip whitespaces
+ * while we have both sides to compare.
+ */
+ if (flags & XDF_IGNORE_WHITESPACE) {
+ goto skip_ws;
+ while (i1 < s1 && i2 < s2) {
+ if (l1[i1++] != l2[i2++])
+ return 0;
+ skip_ws:
+ while (i1 < s1 && XDL_ISSPACE(l1[i1]))
+ i1++;
+ while (i2 < s2 && XDL_ISSPACE(l2[i2]))
+ i2++;
+ }
+ } else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
+ while (i1 < s1 && i2 < s2) {
+ if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {
+ /* Skip matching spaces and try again */
+ while (i1 < s1 && XDL_ISSPACE(l1[i1]))
+ i1++;
+ while (i2 < s2 && XDL_ISSPACE(l2[i2]))
+ i2++;
+ continue;
+ }
+ if (l1[i1++] != l2[i2++])
+ return 0;
+ }
+ } else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL) {
+ while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) {
+ i1++;
+ i2++;
+ }
+ } else if (flags & XDF_IGNORE_CR_AT_EOL) {
+ /* Find the first difference and see how the line ends */
+ while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) {
+ i1++;
+ i2++;
+ }
+ return (ends_with_optional_cr(l1, s1, i1) &&
+ ends_with_optional_cr(l2, s2, i2));
+ }
+
+ /*
+ * After running out of one side, the remaining side must have
+ * nothing but whitespace for the lines to match. Note that
+ * ignore-whitespace-at-eol case may break out of the loop
+ * while there still are characters remaining on both lines.
+ */
+ if (i1 < s1) {
+ while (i1 < s1 && XDL_ISSPACE(l1[i1]))
+ i1++;
+ if (s1 != i1)
+ return 0;
+ }
+ if (i2 < s2) {
+ while (i2 < s2 && XDL_ISSPACE(l2[i2]))
+ i2++;
+ return (s2 == i2);
+ }
+ return 1;
+}
+
+static unsigned long xdl_hash_record_with_whitespace(char const **data,
+ char const *top, long flags) {
+ unsigned long ha = 5381;
+ char const *ptr = *data;
+ int cr_at_eol_only = (flags & XDF_WHITESPACE_FLAGS) == XDF_IGNORE_CR_AT_EOL;
+
+ for (; ptr < top && *ptr != '\n'; ptr++) {
+ if (cr_at_eol_only) {
+ /* do not ignore CR at the end of an incomplete line */
+ if (*ptr == '\r' &&
+ (ptr + 1 < top && ptr[1] == '\n'))
+ continue;
+ }
+ else if (XDL_ISSPACE(*ptr)) {
+ const char *ptr2 = ptr;
+ int at_eol;
+ while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
+ && ptr[1] != '\n')
+ ptr++;
+ at_eol = (top <= ptr + 1 || ptr[1] == '\n');
+ if (flags & XDF_IGNORE_WHITESPACE)
+ ; /* already handled */
+ else if (flags & XDF_IGNORE_WHITESPACE_CHANGE
+ && !at_eol) {
+ ha += (ha << 5);
+ ha ^= (unsigned long) ' ';
+ }
+ else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL
+ && !at_eol) {
+ while (ptr2 != ptr + 1) {
+ ha += (ha << 5);
+ ha ^= (unsigned long) *ptr2;
+ ptr2++;
+ }
+ }
+ continue;
+ }
+ ha += (ha << 5);
+ ha ^= (unsigned long) *ptr;
+ }
+ *data = ptr < top ? ptr + 1: ptr;
+
+ return ha;
+}
+
+unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
+ unsigned long ha = 5381;
+ char const *ptr = *data;
+
+ if (flags & XDF_WHITESPACE_FLAGS)
+ return xdl_hash_record_with_whitespace(data, top, flags);
+
+ for (; ptr < top && *ptr != '\n'; ptr++) {
+ ha += (ha << 5);
+ ha ^= (unsigned long) *ptr;
+ }
+ *data = ptr < top ? ptr + 1: ptr;
+
+ return ha;
+}
+
+unsigned int xdl_hashbits(unsigned int size) {
+ unsigned int val = 1, bits = 0;
+
+ for (; val < size && bits < CHAR_BIT * sizeof(unsigned int); val <<= 1, bits++);
+ return bits ? bits: 1;
+}
+
+
+int xdl_num_out(char *out, long val) {
+ char *ptr, *str = out;
+ char buf[32];
+
+ ptr = buf + sizeof(buf) - 1;
+ *ptr = '\0';
+ if (val < 0) {
+ *--ptr = '-';
+ val = -val;
+ }
+ for (; val && ptr > buf; val /= 10)
+ *--ptr = "0123456789"[val % 10];
+ if (*ptr)
+ for (; *ptr; ptr++, str++)
+ *str = *ptr;
+ else
+ *str++ = '0';
+ *str = '\0';
+
+ return str - out;
+}
+
+int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
+ const char *func, long funclen, xdemitcb_t *ecb) {
+ int nb = 0;
+ mmbuffer_t mb;
+ char buf[128];
+
+ memcpy(buf, "@@ -", 4);
+ nb += 4;
+
+ nb += xdl_num_out(buf + nb, c1 ? s1: s1 - 1);
+
+ if (c1 != 1) {
+ memcpy(buf + nb, ",", 1);
+ nb += 1;
+
+ nb += xdl_num_out(buf + nb, c1);
+ }
+
+ memcpy(buf + nb, " +", 2);
+ nb += 2;
+
+ nb += xdl_num_out(buf + nb, c2 ? s2: s2 - 1);
+
+ if (c2 != 1) {
+ memcpy(buf + nb, ",", 1);
+ nb += 1;
+
+ nb += xdl_num_out(buf + nb, c2);
+ }
+
+ memcpy(buf + nb, " @@", 3);
+ nb += 3;
+ if (func && funclen) {
+ buf[nb++] = ' ';
+ if (funclen > (long)sizeof(buf) - nb - 1)
+ funclen = sizeof(buf) - nb - 1;
+ memcpy(buf + nb, func, funclen);
+ nb += funclen;
+ }
+ buf[nb++] = '\n';
+
+ mb.ptr = buf;
+ mb.size = nb;
+ if (ecb->outf(ecb->priv, &mb, 1) < 0)
+ return -1;
+
+ return 0;
+}
+
+int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
+ int line1, int count1, int line2, int count2)
+{
+ /*
+ * This probably does not work outside Git, since
+ * we have a very simple mmfile structure.
+ *
+ * Note: ideally, we would reuse the prepared environment, but
+ * the libxdiff interface does not (yet) allow for diffing only
+ * ranges of lines instead of the whole files.
+ */
+ mmfile_t subfile1, subfile2;
+ xdfenv_t env;
+
+ subfile1.ptr = (char *)diff_env->xdf1.recs[line1 - 1]->ptr;
+ subfile1.size = diff_env->xdf1.recs[line1 + count1 - 2]->ptr +
+ diff_env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;
+ subfile2.ptr = (char *)diff_env->xdf2.recs[line2 - 1]->ptr;
+ subfile2.size = diff_env->xdf2.recs[line2 + count2 - 2]->ptr +
+ diff_env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;
+ if (xdl_do_diff(&subfile1, &subfile2, xpp, &env) < 0)
+ return -1;
+
+ memcpy(diff_env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);
+ memcpy(diff_env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);
+
+ xdl_free_env(&env);
+
+ return 0;
+}
diff --git a/src/nvim/xdiff/xutils.h b/src/nvim/xdiff/xutils.h
new file mode 100644
index 0000000000..fba7bae03c
--- /dev/null
+++ b/src/nvim/xdiff/xutils.h
@@ -0,0 +1,47 @@
+/*
+ * LibXDiff by Davide Libenzi ( File Differential Library )
+ * Copyright (C) 2003 Davide Libenzi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Davide Libenzi <davidel@xmailserver.org>
+ *
+ */
+
+#if !defined(XUTILS_H)
+#define XUTILS_H
+
+
+
+long xdl_bogosqrt(long n);
+int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
+ xdemitcb_t *ecb);
+int xdl_cha_init(chastore_t *cha, long isize, long icount);
+void xdl_cha_free(chastore_t *cha);
+void *xdl_cha_alloc(chastore_t *cha);
+long xdl_guess_lines(mmfile_t *mf, long sample);
+int xdl_blankline(const char *line, long size, long flags);
+int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
+unsigned long xdl_hash_record(char const **data, char const *top, long flags);
+unsigned int xdl_hashbits(unsigned int size);
+int xdl_num_out(char *out, long val);
+int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
+ const char *func, long funclen, xdemitcb_t *ecb);
+int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
+ int line1, int count1, int line2, int count2);
+
+
+
+#endif /* #if !defined(XUTILS_H) */